[
  {
    "path": ".ci/apt-internal.gitlab-ci.yml",
    "content": ".register_inputs: &register_inputs\n  stage: release-internal\n  runOnBranches: \"^master$\"\n  COMPONENT: \"common\"\n\n.register_inputs_stable_bookworm: &register_inputs_stable_bookworm\n  <<: *register_inputs\n  runOnChangesTo: ['RELEASE_NOTES']\n  FLAVOR: \"bookworm\"\n  SERIES: \"stable\"\n\n.register_inputs_stable_trixie: &register_inputs_stable_trixie\n  <<: *register_inputs\n  runOnChangesTo: ['RELEASE_NOTES']\n  FLAVOR: \"trixie\"\n  SERIES: \"stable\"\n\n.register_inputs_next_bookworm: &register_inputs_next_bookworm\n  <<: *register_inputs\n  FLAVOR: \"bookworm\"\n  SERIES: next\n\n.register_inputs_next_trixie: &register_inputs_next_trixie\n  <<: *register_inputs\n  FLAVOR: \"trixie\"\n  SERIES: next\n\n################################################\n### Generate Debian Package for Internal APT ###\n################################################\n.cloudflared-apt-build: &cloudflared_apt_build\n  stage: package\n  needs:\n    - ci-image-get-image-ref\n    - linux-packaging # For consistency, we only run this job after we knew we could build the packages for external delivery\n  image: $BUILD_IMAGE\n  cache: {}\n  script:\n    - make cloudflared-deb\n  artifacts:\n    paths:\n      - cloudflared*.deb\n\n##############\n### Stable ###\n##############\ncloudflared-amd64-stable:\n  <<: *cloudflared_apt_build\n  rules:\n    - !reference [.default-rules, run-on-release]\n  variables: &amd64-stable-vars\n    GOOS: linux\n    GOARCH: amd64\n    FIPS: true\n    ORIGINAL_NAME: true\n    CGO_ENABLED: 1\n\ncloudflared-arm64-stable:\n  <<: *cloudflared_apt_build\n  rules:\n    - !reference [.default-rules, run-on-release]\n  variables: &arm64-stable-vars\n    GOOS: linux\n    GOARCH: arm64\n    FIPS: false # TUN-7595\n    ORIGINAL_NAME: true\n    CGO_ENABLED: 1\n\n############\n### Next ###\n############\ncloudflared-amd64-next:\n  <<: *cloudflared_apt_build\n  rules:\n    - !reference [.default-rules, run-on-master]\n  variables:\n    <<: *amd64-stable-vars\n    NIGHTLY: true\n\ncloudflared-arm64-next:\n  <<: *cloudflared_apt_build\n  rules:\n    - !reference [.default-rules, run-on-master]\n  variables:\n    <<: *arm64-stable-vars\n    NIGHTLY: true\n\ninclude:\n  - local: .ci/commons.gitlab-ci.yml\n\n  ##########################################\n  ### Publish Packages to Internal Repos ###\n  ##########################################\n  # Bookworm AMD64\n  - component: $CI_SERVER_FQDN/cloudflare/ci/apt-register/register@~latest\n    inputs:\n      <<: *register_inputs_stable_bookworm\n      jobPrefix: cloudflared-bookworm-amd64\n      needs: &amd64-stable [\"cloudflared-amd64-stable\"]\n\n  # Bookworm ARM64\n  - component: $CI_SERVER_FQDN/cloudflare/ci/apt-register/register@~latest\n    inputs:\n      <<: *register_inputs_stable_bookworm\n      jobPrefix: cloudflared-bookworm-arm64\n      needs: &arm64-stable [\"cloudflared-arm64-stable\"]\n\n  # Trixie AMD64\n  - component: $CI_SERVER_FQDN/cloudflare/ci/apt-register/register@~latest\n    inputs:\n      <<: *register_inputs_stable_trixie\n      jobPrefix: cloudflared-trixie-amd64\n      needs: *amd64-stable\n\n  # Trixie ARM64\n  - component: $CI_SERVER_FQDN/cloudflare/ci/apt-register/register@~latest\n    inputs:\n      <<: *register_inputs_stable_trixie\n      jobPrefix: cloudflared-trixie-arm64\n      needs: *arm64-stable\n\n  ##################################################\n  ### Publish Nightly Packages to Internal Repos ###\n  ##################################################\n  # Bookworm AMD64\n  - component: $CI_SERVER_FQDN/cloudflare/ci/apt-register/register@~latest\n    inputs:\n      <<: *register_inputs_next_bookworm\n      jobPrefix: cloudflared-nightly-bookworm-amd64\n      needs: &amd64-next ['cloudflared-amd64-next']\n\n  # Bookworm ARM64\n  - component: $CI_SERVER_FQDN/cloudflare/ci/apt-register/register@~latest\n    inputs:\n      <<: *register_inputs_next_bookworm\n      jobPrefix: cloudflared-nightly-bookworm-arm64\n      needs: &arm64-next ['cloudflared-arm64-next']\n\n  # Trixie AMD64\n  - component: $CI_SERVER_FQDN/cloudflare/ci/apt-register/register@~latest\n    inputs:\n      <<: *register_inputs_next_trixie\n      jobPrefix: cloudflared-nightly-trixie-amd64\n      needs: *amd64-next\n\n  # Trixie ARM64\n  - component: $CI_SERVER_FQDN/cloudflare/ci/apt-register/register@~latest\n    inputs:\n      <<: *register_inputs_next_trixie\n      jobPrefix: cloudflared-nightly-trixie-arm64\n      needs: *arm64-next\n"
  },
  {
    "path": ".ci/ci-image.gitlab-ci.yml",
    "content": "# Builds a custom CI Image when necessary\n\ninclude:\n  #####################################################\n  ############## Build and Push CI Image ##############\n  #####################################################\n  - component: $CI_SERVER_FQDN/cloudflare/ci/docker-image/build-push-image@~latest\n    inputs:\n      stage: pre-build\n      jobPrefix: ci-image\n      runOnChangesTo: [\".ci/image/**\"]\n      runOnMR: true\n      runOnBranches: '^master$'\n      commentImageRefs: false\n      runner: vm-linux-x86-4cpu-8gb\n      EXTRA_DIB_ARGS: \"--manifest=.ci/image/.docker-images\"\n\n  #####################################################\n  ## Resolve the image reference for downstream jobs ##\n  #####################################################\n  - component: $CI_SERVER_FQDN/cloudflare/ci/docker-image/get-image-ref@~latest\n    inputs:\n      stage: pre-build\n      jobPrefix: ci-image\n      runOnMR: true\n      runOnBranches: '^master$'\n      IMAGE_PATH: \"$REGISTRY_HOST/stash/tun/cloudflared/ci-image/master\"\n      VARIABLE_NAME: BUILD_IMAGE\n      needs:\n        - job: ci-image-build-push-image\n          optional: true\n"
  },
  {
    "path": ".ci/commons.gitlab-ci.yml",
    "content": "## A set of predefined rules to use on the different jobs\n.default-rules:\n  # Rules to run the job only on the master branch\n  run-on-master:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n      when: on_success\n    - when: never\n  # Rules to run the job only on merge requests\n  run-on-mr:\n    - if: $CI_COMMIT_TAG\n      when: never\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n      when: on_success\n    - when: never\n  # Rules to run the job on merge_requests and master branch\n  run-always:\n    - if: $CI_COMMIT_TAG\n      when: never\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n    - if: $CI_COMMIT_BRANCH != null && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n      when: on_success\n    - when: never\n  # Rules to run the job only when a release happens\n  run-on-release:\n    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH\n      changes:\n          - 'RELEASE_NOTES'\n      when: on_success\n    - when: never\n\n.component-tests:\n  image: $BUILD_IMAGE\n  rules:\n    - !reference [.default-rules, run-always]\n  variables:\n    COMPONENT_TESTS_CONFIG: component-test-config.yaml\n    COMPONENT_TESTS_CONFIG_CONTENT: Y2xvdWRmbGFyZWRfYmluYXJ5OiBjbG91ZGZsYXJlZC5leGUKY3JlZGVudGlhbHNfZmlsZTogY3JlZC5qc29uCm9yaWdpbmNlcnQ6IGNlcnQucGVtCnpvbmVfZG9tYWluOiBhcmdvdHVubmVsdGVzdC5jb20Kem9uZV90YWc6IDQ4Nzk2ZjFlNzBiYjc2NjljMjliYjUxYmEyODJiZjY1\n  secrets:\n    DNS_API_TOKEN:\n      vault: gitlab/cloudflare/tun/cloudflared/_dev/_terraform_atlantis/component_tests_token/data@kv\n      file: false\n    COMPONENT_TESTS_ORIGINCERT:\n      vault: gitlab/cloudflare/tun/cloudflared/_dev/component_tests_cert_pem/data@kv\n      file: false\n  cache: {}\n"
  },
  {
    "path": ".ci/github.gitlab-ci.yml",
    "content": "include:\n  - local: .ci/commons.gitlab-ci.yml\n\n######################################\n### Sync master branch with Github ###\n######################################\npush-github:\n  stage: sync\n  rules:\n    - !reference [.default-rules, run-on-master]\n  script:\n    - ./.ci/scripts/github-push.sh\n  secrets:\n    CLOUDFLARED_DEPLOY_SSH_KEY:\n      vault: gitlab/cloudflare/tun/cloudflared/_branch/master/cloudflared_github_ssh/data@kv\n      file: false\n  cache: {}\n"
  },
  {
    "path": ".ci/image/.docker-images",
    "content": "images:\n  - name: ci-image\n"
  },
  {
    "path": ".ci/image/Dockerfile",
    "content": "ARG CLOUDFLARE_DOCKER_REGISTRY_HOST\n\nFROM ${CLOUDFLARE_DOCKER_REGISTRY_HOST:-registry.cfdata.org}/stash/cf/debian-images/trixie/main:2026.1.0@sha256:e32092fd01520f5ae7de1fa6bb5a721720900ebeaa48e98f36f6f86168833cd7\nRUN apt-get update && \\\n  apt-get upgrade -y && \\\n  apt-get install --no-install-recommends --allow-downgrades -y \\\n  build-essential \\\n  git \\\n  go-boring=1.24.13-1 \\\n  libffi-dev \\\n  procps \\\n  python3-dev \\\n  python3-pip \\\n  python3-setuptools \\\n  python3-venv \\\n  # tool to create msi packages\n  wixl \\\n  # install ruby and rpm which are required to install fpm package builder\n  rpm \\\n  ruby \\\n  ruby-dev \\\n  rubygems \\\n  # create deb and rpm repository files\n  reprepro \\\n  createrepo-c \\\n  # gcc for cross architecture compilation in arm\n  gcc-aarch64-linux-gnu \\\n  libc6-dev-arm64-cross && \\\n  rm -rf /var/lib/apt/lists/* && \\\n  # Install fpm gem\n  gem install fpm --no-document && \\\n  # Initialize rpm repository, SQL Lite DB\n  mkdir -p /var/lib/rpm && \\\n  rpm --initdb && \\\n  chmod -R 777 /var/lib/rpm && \\\n  # Create work directory\n  mkdir -p opt\n\nWORKDIR /opt\n"
  },
  {
    "path": ".ci/linux.gitlab-ci.yml",
    "content": ".golang-inputs: &golang_inputs\n  runOnMR: true\n  runOnBranches: \"^master$\"\n  outputDir: artifacts\n  runner: linux-x86-8cpu-16gb\n  stage: build\n  golangVersion: \"boring-1.24\"\n  imageVersion: \"3462-0b23466e0715@sha256:42e8533370666a2463041572293a79e1449001ef803a993e6a860be00858c806\"\n  CGO_ENABLED: 1\n\n.default-packaging-job: &packaging-job-defaults\n  stage: package\n  needs:\n    - ci-image-get-image-ref\n  rules:\n    - !reference [.default-rules, run-on-master]\n  image: $BUILD_IMAGE\n  cache: {}\n  artifacts:\n    paths:\n      - artifacts/*\n\ninclude:\n  ###################\n  ### Linux Build ###\n  ###################\n  - component: $CI_SERVER_FQDN/cloudflare/ci/golang/boring-make@~latest\n    inputs:\n      <<: *golang_inputs\n      jobPrefix: linux-build\n      GOLANG_MAKE_TARGET: ci-build\n\n  ########################\n  ### Linux FIPS Build ###\n  ########################\n  - component: $CI_SERVER_FQDN/cloudflare/ci/golang/boring-make@~latest\n    inputs:\n      <<: *golang_inputs\n      jobPrefix: linux-fips-build\n      GOLANG_MAKE_TARGET: ci-fips-build\n\n  #################\n  ### Unit Tests ##\n  #################\n  - component: $CI_SERVER_FQDN/cloudflare/ci/golang/boring-make@~latest\n    inputs:\n      <<: *golang_inputs\n      stage: test\n      jobPrefix: test\n      GOLANG_MAKE_TARGET: ci-test\n\n  ######################\n  ### Unit Tests FIPS ##\n  ######################\n  - component: $CI_SERVER_FQDN/cloudflare/ci/golang/boring-make@~latest\n    inputs:\n      <<: *golang_inputs\n      stage: test\n      jobPrefix: test-fips\n      GOLANG_MAKE_TARGET: ci-fips-test\n\n  #################\n  ### Vuln Check ##\n  #################\n  - component: $CI_SERVER_FQDN/cloudflare/ci/golang/boring-make@~latest\n    inputs:\n      <<: *golang_inputs\n      runOnBranches: \"^$\"\n      stage: validate\n      jobPrefix: vulncheck\n      GOLANG_MAKE_TARGET: vulncheck\n\n#################################\n### Run Linux Component Tests ###\n#################################\nlinux-component-tests: &linux-component-tests\n  stage: test\n  extends: .component-tests\n  needs:\n    - ci-image-get-image-ref\n    - linux-build-boring-make\n  script:\n    - ./.ci/scripts/component-tests.sh\n  variables: &component-tests-variables\n    CI: 1\n    COMPONENT_TESTS_CONFIG_CONTENT: Y2xvdWRmbGFyZWRfYmluYXJ5OiAuL2Nsb3VkZmxhcmVkCmNyZWRlbnRpYWxzX2ZpbGU6IGNyZWQuanNvbgpvcmlnaW5jZXJ0OiBjZXJ0LnBlbQp6b25lX2RvbWFpbjogYXJnb3R1bm5lbHRlc3QuY29tCnpvbmVfdGFnOiA0ODc5NmYxZTcwYmI3NjY5YzI5YmI1MWJhMjgyYmY2NQ==\n  tags:\n    - linux-x86-8cpu-16gb\n  artifacts:\n    reports:\n      junit: report.xml\n\n######################################\n### Run Linux FIPS Component Tests ###\n######################################\nlinux-component-tests-fips:\n  <<: *linux-component-tests\n  needs:\n    - ci-image-get-image-ref\n    - linux-fips-build-boring-make\n  variables:\n    <<: *component-tests-variables\n    COMPONENT_TESTS_FIPS: 1\n\n################################\n####### Linux Packaging ########\n################################\nlinux-packaging:\n  <<: *packaging-job-defaults\n  parallel:\n    matrix:\n      - ARCH: [\"386\", \"amd64\", \"arm\", \"armhf\", \"arm64\"]\n  script:\n    - ./.ci/scripts/linux/build-packages.sh ${ARCH}\n\n################################\n##### Linux FIPS Packaging #####\n################################\nlinux-packaging-fips:\n  <<: *packaging-job-defaults\n  script:\n    - ./.ci/scripts/linux/build-packages-fips.sh\n"
  },
  {
    "path": ".ci/mac.gitlab-ci.yml",
    "content": "include:\n  - local: .ci/commons.gitlab-ci.yml\n\n###############################\n### Defaults for Mac Builds ###\n###############################\n.mac-build-defaults: &mac-build-defaults\n  rules:\n    - !reference [.default-rules, run-on-mr]\n  tags:\n    - \"macstadium-${RUNNER_ARCH}\"\n  parallel:\n    matrix:\n      - RUNNER_ARCH: [arm, intel]\n  cache: {}\n\n######################################\n### Build Cloudflared Mac Binaries ###\n######################################\nmacos-build-cloudflared: &mac-build\n  <<: *mac-build-defaults\n  stage: build\n  artifacts:\n    paths:\n      - artifacts/*\n  script:\n    - '[ \"${RUNNER_ARCH}\" = \"arm\" ] && export TARGET_ARCH=arm64'\n    - '[ \"${RUNNER_ARCH}\" = \"intel\" ] && export TARGET_ARCH=amd64'\n    - ARCH=$(uname -m)\n    - echo ARCH=$ARCH - TARGET_ARCH=$TARGET_ARCH\n    - ./.ci/scripts/mac/install-go.sh \"$MAC_GO_VERSION\"\n    - BUILD_SCRIPT=.ci/scripts/mac/build.sh\n    - if [[ ! -x ${BUILD_SCRIPT} ]] ; then exit ; fi\n    - set -euo pipefail\n    - echo \"Executing ${BUILD_SCRIPT}\"\n    - exec ${BUILD_SCRIPT}\n\n###############################################\n### Build and Sign Cloudflared Mac Binaries ###\n###############################################\nmacos-build-and-sign-cloudflared:\n  <<: *mac-build\n  rules:\n    - !reference [.default-rules, run-on-master]\n  secrets:\n    APPLE_DEV_CA_CERT:\n      vault: gitlab/cloudflare/tun/cloudflared/_branch/master/apple_dev_ca_cert_v2/data@kv\n      file: false\n    CFD_CODE_SIGN_CERT:\n      vault: gitlab/cloudflare/tun/cloudflared/_branch/master/cfd_code_sign_cert_v2/data@kv\n      file: false\n    CFD_CODE_SIGN_KEY:\n      vault: gitlab/cloudflare/tun/cloudflared/_branch/master/cfd_code_sign_key_v2/data@kv\n      file: false\n    CFD_CODE_SIGN_PASS:\n      vault: gitlab/cloudflare/tun/cloudflared/_branch/master/cfd_code_sign_pass_v2/data@kv\n      file: false\n    CFD_INSTALLER_CERT:\n      vault: gitlab/cloudflare/tun/cloudflared/_branch/master/cfd_installer_cert_v2/data@kv\n      file: false\n    CFD_INSTALLER_KEY:\n      vault: gitlab/cloudflare/tun/cloudflared/_branch/master/cfd_installer_key_v2/data@kv\n      file: false\n    CFD_INSTALLER_PASS:\n      vault: gitlab/cloudflare/tun/cloudflared/_branch/master/cfd_installer_pass_v2/data@kv\n      file: false\n"
  },
  {
    "path": ".ci/release.gitlab-ci.yml",
    "content": "include:\n  - local: .ci/commons.gitlab-ci.yml\n\n  ######################################\n  ### Build and Push DockerHub Image ###\n  ######################################\n  - component: $CI_SERVER_FQDN/cloudflare/ci/docker-image/build-push-image@~latest\n    inputs:\n      stage: release\n      jobPrefix: docker-hub\n      runOnMR: false\n      runOnBranches: '^master$'\n      runOnChangesTo: ['RELEASE_NOTES']\n      needs:\n        - generate-version-file\n        - release-cloudflared-to-r2\n      commentImageRefs: false\n      runner: vm-linux-x86-4cpu-8gb\n      # Based on if the CI reference is protected or not the CI component will\n      # either use _BRANCH or _PROD, therefore, to prevent the pipelines from failing\n      # we simply set both to the same value.\n      DOCKER_USER_BRANCH: &docker-hub-user svcgithubdockerhubcloudflar045\n      DOCKER_PASSWORD_BRANCH: &docker-hub-password gitlab/cloudflare/tun/cloudflared/_dev/dockerhub/svc_password/data\n      DOCKER_USER_PROD: *docker-hub-user\n      DOCKER_PASSWORD_PROD: *docker-hub-password\n      EXTRA_DIB_ARGS: --overwrite\n\n.default-release-job: &release-job-defaults\n  stage: release\n  image: $BUILD_IMAGE\n  cache:\n    paths:\n      - .cache/pip\n  variables: &release-job-variables\n    PIP_CACHE_DIR: \"$CI_PROJECT_DIR/.cache/pip\"\n    # KV Vars\n    KV_NAMESPACE: 380e19aa04314648949b6ad841417ebe\n    KV_ACCOUNT: &cf-account 5ab4e9dfbd435d24068829fda0077963\n    # R2 Vars\n    R2_BUCKET: cloudflared-pkgs\n    R2_ACCOUNT_ID: *cf-account\n    # APT and RPM Repository Vars\n    GPG_PUBLIC_KEY_URL: \"https://pkg.cloudflare.com/cloudflare-ascii-pubkey.gpg\"\n    PKG_URL: \"https://pkg.cloudflare.com/cloudflared\"\n    BINARY_NAME: cloudflared\n  secrets:\n    KV_API_TOKEN:\n      vault: gitlab/cloudflare/tun/cloudflared/_dev/cfd_kv_api_token/data@kv\n      file: false\n    API_KEY:\n      vault: gitlab/cloudflare/tun/cloudflared/_dev/cfd_github_api_key/data@kv\n      file: false\n    R2_CLIENT_ID:\n      vault: gitlab/cloudflare/tun/cloudflared/_dev/_terraform_atlantis/r2_api_token/client_id@kv\n      file: false\n    R2_CLIENT_SECRET:\n      vault: gitlab/cloudflare/tun/cloudflared/_dev/_terraform_atlantis/r2_api_token/client_secret@kv\n      file: false\n    LINUX_SIGNING_PUBLIC_KEY:\n      vault: gitlab/cloudflare/tun/cloudflared/_dev/gpg_v1/public_key@kv\n      file: false\n    LINUX_SIGNING_PRIVATE_KEY:\n      vault: gitlab/cloudflare/tun/cloudflared/_dev/gpg_v1/private_key@kv\n      file: false\n    LINUX_SIGNING_PUBLIC_KEY_2:\n      vault: gitlab/cloudflare/tun/cloudflared/_dev/gpg_v2/public_key@kv\n      file: false\n    LINUX_SIGNING_PRIVATE_KEY_2:\n      vault: gitlab/cloudflare/tun/cloudflared/_dev/gpg_v2/private_key@kv\n      file: false\n\n###########################################\n### Push Cloudflared Binaries to Github ###\n###########################################\nrelease-cloudflared-to-github:\n  <<: *release-job-defaults\n  rules:\n    - !reference [.default-rules, run-on-release]\n  needs:\n    - ci-image-get-image-ref\n    - linux-packaging\n    - linux-packaging-fips\n    - macos-build-and-sign-cloudflared\n    - windows-package-sign\n  script:\n    - ./.ci/scripts/release-target.sh github-release\n\n#########################################\n### Upload Cloudflared Binaries to R2 ###\n#########################################\nrelease-cloudflared-to-r2:\n  <<: *release-job-defaults\n  rules:\n    - !reference [.default-rules, run-on-release]\n  needs:\n    - ci-image-get-image-ref\n    - linux-packaging # We only release non-FIPS binaries to R2\n    - release-cloudflared-to-github\n  script:\n    - ./.ci/scripts/release-target.sh r2-linux-release\n\n#################################################\n### Upload Cloudflared Nightly Binaries to R2 ###\n#################################################\nrelease-cloudflared-nightly-to-r2:\n  <<: *release-job-defaults\n  rules:\n    - !reference [.default-rules, run-on-master]\n  variables:\n    <<: *release-job-variables\n    R2_BUCKET: cloudflared-pkgs-next\n    GPG_PUBLIC_KEY_URL: \"https://next.pkg.cloudflare.com/cloudflare-ascii-pubkey.gpg\"\n    PKG_URL: \"https://next.pkg.cloudflare.com/cloudflared\"\n  needs:\n    - ci-image-get-image-ref\n    - linux-packaging # We only release non-FIPS binaries to R2\n  script:\n    - ./.ci/scripts/release-target.sh r2-linux-release\n\n#############################\n### Generate Version File ###\n#############################\ngenerate-version-file:\n  <<: *release-job-defaults\n  rules:\n    - !reference [.default-rules, run-on-release]\n  needs:\n    - ci-image-get-image-ref\n  script:\n    - make generate-docker-version\n  artifacts:\n    paths:\n      - versions\n"
  },
  {
    "path": ".ci/scripts/component-tests.sh",
    "content": "#!/bin/bash\nset -e -u -o pipefail\n\n# Fetch cloudflared from the artifacts folder\nmv ./artifacts/cloudflared ./cloudflared\n\npython3 -m venv env\n. env/bin/activate\n\npip install --upgrade -r component-tests/requirements.txt\n\n# Creates and routes a Named Tunnel for this build. Also constructs\n# config file from env vars.\npython3 component-tests/setup.py --type create\n\n# Define the cleanup function\ncleanup() {\n    # The Named Tunnel is deleted and its route unprovisioned here.\n    python3 component-tests/setup.py --type cleanup\n}\n\n# The trap will call the cleanup function on script exit\ntrap cleanup EXIT\n\npytest component-tests -o log_cli=true --log-cli-level=INFO --junit-xml=report.xml\n"
  },
  {
    "path": ".ci/scripts/fmt-check.sh",
    "content": "#!/bin/bash\nset -e -u -o pipefail\n\nOUTPUT=$(go run -mod=readonly golang.org/x/tools/cmd/goimports@v0.30.0 -l -d -local github.com/cloudflare/cloudflared $(go list -mod=vendor -f '{{.Dir}}' -a ./... | fgrep -v tunnelrpc))\n\nif [ -n \"$OUTPUT\" ] ; then\n  PAGER=$(which colordiff || echo cat)\n  echo\n  echo \"Code formatting issues found, use 'make fmt' to correct them\"\n  echo\n  echo \"$OUTPUT\" | $PAGER\n  exit 1\nfi\n"
  },
  {
    "path": ".ci/scripts/github-push.sh",
    "content": "#!/bin/bash\nset -e -u -o pipefail\n\nBRANCH=\"master\"\nTMP_PATH=\"$PWD/tmp\"\nPRIVATE_KEY_PATH=\"$TMP_PATH/github-deploy-key\"\nPUBLIC_KEY_GITHUB_PATH=\"$TMP_PATH/github.pub\"\n\nmkdir -p $TMP_PATH\n\n# Setup Private Key\necho \"$CLOUDFLARED_DEPLOY_SSH_KEY\" > $PRIVATE_KEY_PATH\nchmod 400 $PRIVATE_KEY_PATH\n\n# Download GitHub Public Key for KnownHostsFile\nssh-keyscan -t ed25519 github.com > $PUBLIC_KEY_GITHUB_PATH\n\n# Setup git ssh command with the right configurations\nexport GIT_SSH_COMMAND=\"ssh -o UserKnownHostsFile=$PUBLIC_KEY_GITHUB_PATH -o IdentitiesOnly=yes -i $PRIVATE_KEY_PATH\"\n\n# Add GitHub as a new remote\ngit remote add github git@github.com:cloudflare/cloudflared.git || true\n\n# GitLab doesn't pull branch references, instead it creates a new one on each pipeline.\n# Therefore, we need to manually fetch the reference to then push it to GitHub.\ngit fetch origin $BRANCH:$BRANCH\ngit push -u github $BRANCH\n\nif TAG=\"$(git describe --tags --exact-match 2>/dev/null)\"; then\n  git push -u github \"$TAG\"\nfi\n"
  },
  {
    "path": ".ci/scripts/linux/build-packages-fips.sh",
    "content": "#!/bin/bash\nset -e -u -o pipefail\nVERSION=$(git describe --tags --always --match \"[0-9][0-9][0-9][0-9].*.*\")\necho $VERSION\n\n# This controls the directory the built artifacts go into\nexport ARTIFACT_DIR=artifacts/\nmkdir -p $ARTIFACT_DIR\n\narch=(\"amd64\")\nexport TARGET_ARCH=$arch\nexport TARGET_OS=linux\nexport FIPS=true\n# For BoringCrypto to link, we need CGO enabled. Otherwise compilation fails.\nexport CGO_ENABLED=1\n\nmake cloudflared-deb\nmv cloudflared-fips\\_$VERSION\\_$arch.deb $ARTIFACT_DIR/cloudflared-fips-linux-$arch.deb\n\n# rpm packages invert the - and _ and use x86_64 instead of amd64.\nRPMVERSION=$(echo $VERSION | sed -r 's/-/_/g')\nRPMARCH=\"x86_64\"\nmake cloudflared-rpm\nmv cloudflared-fips-$RPMVERSION-1.$RPMARCH.rpm $ARTIFACT_DIR/cloudflared-fips-linux-$RPMARCH.rpm\n\n# finally move the linux binary as well.\nmv ./cloudflared $ARTIFACT_DIR/cloudflared-fips-linux-$arch\n"
  },
  {
    "path": ".ci/scripts/linux/build-packages.sh",
    "content": "#!/bin/bash\nset -e -u -o pipefail\n\n# Check if architecture argument is provided\nif [ $# -eq 0 ]; then\n    echo \"Error: Architecture argument is required\"\n    echo \"Usage: $0 <architecture>\"\n    exit 1\nfi\n\n# Parameters\narch=$1\n\n# Get Version\nVERSION=$(git describe --tags --always --match \"[0-9][0-9][0-9][0-9].*.*\")\necho $VERSION\n\n# Disable FIPS module in go-boring\nexport GOEXPERIMENT=noboringcrypto\nexport CGO_ENABLED=0\n\n# This controls the directory the built artifacts go into\nexport ARTIFACT_DIR=artifacts/\nmkdir -p $ARTIFACT_DIR\n\nexport TARGET_OS=linux\n\nunset TARGET_ARM\nexport TARGET_ARCH=$arch\n\n## Support for arm platforms without hardware FPU enabled\nif [[ $arch == arm ]] ; then\n    export TARGET_ARCH=arm\n    export TARGET_ARM=5\nfi\n\n## Support for armhf builds\nif [[ $arch == armhf ]] ; then\n    export TARGET_ARCH=arm\n    export TARGET_ARM=7\nfi\n\nmake cloudflared-deb\nmv cloudflared\\_$VERSION\\_$arch.deb $ARTIFACT_DIR/cloudflared-linux-$arch.deb\n\n# rpm packages invert the - and _ and use x86_64 instead of amd64.\nRPMVERSION=$(echo $VERSION|sed -r 's/-/_/g')\nRPMARCH=$arch\nif [ $arch == \"amd64\" ];then\n    RPMARCH=\"x86_64\"\nfi\nif [ $arch == \"arm64\" ]; then\n    RPMARCH=\"aarch64\"\nfi\nmake cloudflared-rpm\nmv cloudflared-$RPMVERSION-1.$RPMARCH.rpm $ARTIFACT_DIR/cloudflared-linux-$RPMARCH.rpm\n\n# finally move the linux binary as well.\nmv ./cloudflared $ARTIFACT_DIR/cloudflared-linux-$arch\n\n"
  },
  {
    "path": ".ci/scripts/mac/build.sh",
    "content": "#!/bin/bash\n\nset -exo pipefail\n\nif [[ \"$(uname)\" != \"Darwin\" ]] ; then\n    echo \"This should be run on macOS\"\n    exit 1\nfi\n\nif [[ \"amd64\" != \"${TARGET_ARCH}\" && \"arm64\" != \"${TARGET_ARCH}\" ]]\nthen\n  echo \"TARGET_ARCH must be amd64 or arm64\"\n  exit 1\nfi\n\ngo version\nexport GO111MODULE=on\n\n# build 'cloudflared-darwin-amd64.tgz'\nmkdir -p artifacts\nTARGET_DIRECTORY=\".build\"\nBINARY_NAME=\"cloudflared\"\nVERSION=$(git describe --tags --always --dirty=\"-dev\")\nPRODUCT=\"cloudflared\"\nAPPLE_CA_CERT=\"apple_dev_ca.cert\"\nCODE_SIGN_PRIV=\"code_sign.p12\"\nCODE_SIGN_CERT=\"code_sign.cer\"\nINSTALLER_PRIV=\"installer.p12\"\nINSTALLER_CERT=\"installer.cer\"\nBUNDLE_ID=\"com.cloudflare.cloudflared\"\nSEC_DUP_MSG=\"security: SecKeychainItemImport: The specified item already exists in the keychain.\"\nexport PATH=\"$PATH:/usr/local/bin\"\nFILENAME=\"$(pwd)/artifacts/cloudflared-darwin-$TARGET_ARCH.tgz\"\nPKGNAME=\"$(pwd)/artifacts/cloudflared-$TARGET_ARCH.pkg\"\nmkdir -p ../src/github.com/cloudflare/    \ncp -r . ../src/github.com/cloudflare/cloudflared\ncd ../src/github.com/cloudflare/cloudflared \n\n# Imports certificates to the Apple KeyChain\nimport_certificate() {\n    local CERTIFICATE_NAME=$1\n    local CERTIFICATE_ENV_VAR=$2\n    local CERTIFICATE_FILE_NAME=$3\n\n    echo \"Importing $CERTIFICATE_NAME\"\n\n    if [[ ! -z \"$CERTIFICATE_ENV_VAR\" ]]; then\n      # write certificate to disk and then import it keychain\n      echo -n -e ${CERTIFICATE_ENV_VAR} | base64 -D > ${CERTIFICATE_FILE_NAME}\n      # we set || true  here and for every `security import invoke` because the  \"duplicate SecKeychainItemImport\" error\n      # will cause set -e to exit 1. It is okay we do this because we deliberately handle this error in the lines below.\n      local out=$(security import ${CERTIFICATE_FILE_NAME} -T /usr/bin/pkgbuild -A 2>&1) || true\n      local exitcode=$?\n      # delete the certificate from disk\n      rm -rf ${CERTIFICATE_FILE_NAME}\n      if [ -n \"$out\" ]; then\n        if [ $exitcode -eq 0 ]; then\n            echo \"$out\"\n        else\n            if [ \"$out\" != \"${SEC_DUP_MSG}\" ]; then\n                echo \"$out\" >&2\n                exit $exitcode\n            else\n                echo \"already imported code signing certificate\"\n            fi\n        fi\n      fi\n    fi\n}\n\ncreate_cloudflared_build_keychain() {\n  # Reusing the private key password as the keychain key\n  local PRIVATE_KEY_PASS=$1\n\n  # Create keychain only if it doesn't already exist\n  if [ ! -f \"$HOME/Library/Keychains/cloudflared_build_keychain.keychain-db\" ]; then\n    security create-keychain -p \"$PRIVATE_KEY_PASS\" cloudflared_build_keychain\n  else\n    echo \"Keychain already exists: cloudflared_build_keychain\"\n  fi\n\n  # Append temp keychain to the user domain\n  security list-keychains -d user -s cloudflared_build_keychain $(security list-keychains -d user | sed s/\\\"//g)\n\n  # Remove relock timeout\n  security set-keychain-settings cloudflared_build_keychain\n\n  # Unlock keychain so it doesn't require password\n  security unlock-keychain -p \"$PRIVATE_KEY_PASS\" cloudflared_build_keychain\n\n}\n\n# Imports private keys to the Apple KeyChain\nimport_private_keys() {\n    local PRIVATE_KEY_NAME=$1\n    local PRIVATE_KEY_ENV_VAR=$2\n    local PRIVATE_KEY_FILE_NAME=$3\n    local PRIVATE_KEY_PASS=$4\n\n    echo \"Importing $PRIVATE_KEY_NAME\"\n\n    if [[ ! -z \"$PRIVATE_KEY_ENV_VAR\" ]]; then\n      if [[ ! -z \"$PRIVATE_KEY_PASS\" ]]; then\n        # write private key to disk and then import it keychain\n        echo -n -e ${PRIVATE_KEY_ENV_VAR} | base64 -D > ${PRIVATE_KEY_FILE_NAME}\n        # we set || true  here and for every `security import invoke` because the  \"duplicate SecKeychainItemImport\" error\n        # will cause set -e to exit 1. It is okay we do this because we deliberately handle this error in the lines below.\n        local out=$(security import ${PRIVATE_KEY_FILE_NAME} -k cloudflared_build_keychain -P \"$PRIVATE_KEY_PASS\" -T /usr/bin/pkgbuild -A -P \"${PRIVATE_KEY_PASS}\" 2>&1) || true\n        local exitcode=$?\n        rm -rf ${PRIVATE_KEY_FILE_NAME}\n        if [ -n \"$out\" ]; then\n          if [ $exitcode -eq 0 ]; then\n              echo \"$out\"\n          else\n              if [ \"$out\" != \"${SEC_DUP_MSG}\" ]; then\n                  echo \"$out\" >&2\n                  exit $exitcode\n              fi\n          fi\n        fi\n      fi\n    fi\n}\n\n# Create temp keychain only for this build\ncreate_cloudflared_build_keychain \"${CFD_CODE_SIGN_PASS}\"\n\n# Add Apple Root Developer certificate to the key chain\nimport_certificate \"Apple Developer CA\" \"${APPLE_DEV_CA_CERT}\" \"${APPLE_CA_CERT}\"\n\n# Add code signing private key to the key chain\nimport_private_keys \"Developer ID Application\" \"${CFD_CODE_SIGN_KEY}\" \"${CODE_SIGN_PRIV}\" \"${CFD_CODE_SIGN_PASS}\"\n\n# Add code signing certificate to the key chain\nimport_certificate \"Developer ID Application\" \"${CFD_CODE_SIGN_CERT}\" \"${CODE_SIGN_CERT}\"\n\n# Add package signing private key to the key chain\nimport_private_keys \"Developer ID Installer\" \"${CFD_INSTALLER_KEY}\" \"${INSTALLER_PRIV}\" \"${CFD_INSTALLER_PASS}\"\n\n# Add package signing certificate to the key chain\nimport_certificate \"Developer ID Installer\" \"${CFD_INSTALLER_CERT}\" \"${INSTALLER_CERT}\"\n\n# get the code signing certificate name\nif [[ ! -z \"$CFD_CODE_SIGN_NAME\" ]]; then\n  CODE_SIGN_NAME=\"${CFD_CODE_SIGN_NAME}\"\nelse\n  if [[ -n \"$(security find-certificate -c \"Developer ID Application\" cloudflared_build_keychain | cut -d'\"' -f 4 -s | grep \"Developer ID Application:\" | head -1)\" ]]; then\n    CODE_SIGN_NAME=$(security find-certificate -c \"Developer ID Application\" cloudflared_build_keychain | cut -d'\"' -f 4 -s | grep \"Developer ID Application:\" | head -1)\n  else\n    CODE_SIGN_NAME=\"\"\n  fi\nfi\n\n# get the package signing certificate name\nif [[ ! -z \"$CFD_INSTALLER_NAME\" ]]; then\n  PKG_SIGN_NAME=\"${CFD_INSTALLER_NAME}\"\nelse\n  if [[ -n \"$(security find-certificate -c \"Developer ID Installer\" cloudflared_build_keychain | cut -d'\"' -f 4 -s | grep \"Developer ID Installer:\" | head -1)\" ]]; then\n    PKG_SIGN_NAME=$(security find-certificate -c \"Developer ID Installer\" cloudflared_build_keychain | cut -d'\"' -f 4 -s | grep \"Developer ID Installer:\" | head -1)\n  else\n    PKG_SIGN_NAME=\"\"\n  fi\nfi\n\n# cleanup the build directory because the previous execution might have failed without cleaning up.\nrm -rf \"${TARGET_DIRECTORY}\"\nexport TARGET_OS=\"darwin\"\nGOCACHE=\"$PWD/../../../../\" GOPATH=\"$PWD/../../../../\" CGO_ENABLED=1 make cloudflared\n\n\n# This allows apple tools to use the certificates in the keychain without requiring password input.\n# This command always needs to run after the certificates have been loaded into the keychain\nif [[ ! -z \"$CFD_CODE_SIGN_PASS\" ]]; then\n  security set-key-partition-list -S apple-tool:,apple: -s -k \"${CFD_CODE_SIGN_PASS}\" cloudflared_build_keychain\nfi\n\n# sign the cloudflared binary\nif [[ ! -z \"$CODE_SIGN_NAME\" ]]; then\n  codesign --keychain $HOME/Library/Keychains/cloudflared_build_keychain.keychain-db -s \"${CODE_SIGN_NAME}\" -fv --options runtime --timestamp ${BINARY_NAME}\n\n # notarize the binary\n # TODO: TUN-5789\nfi\n\nARCH_TARGET_DIRECTORY=\"${TARGET_DIRECTORY}/${TARGET_ARCH}-build\"\n# creating build directory\nrm -rf $ARCH_TARGET_DIRECTORY\nmkdir -p \"${ARCH_TARGET_DIRECTORY}\"\nmkdir -p \"${ARCH_TARGET_DIRECTORY}/contents\"\ncp -r \".mac_resources/scripts\" \"${ARCH_TARGET_DIRECTORY}/scripts\"\n\n# copy cloudflared into the build directory\ncp ${BINARY_NAME} \"${ARCH_TARGET_DIRECTORY}/contents/${PRODUCT}\"\n\n# compress cloudflared into a tar and gzipped file\ntar czf \"$FILENAME\" \"${BINARY_NAME}\"\n\n# build the installer package\nif [[ ! -z \"$PKG_SIGN_NAME\" ]]; then\n\n  pkgbuild --identifier com.cloudflare.${PRODUCT} \\\n      --version ${VERSION} \\\n      --scripts ${ARCH_TARGET_DIRECTORY}/scripts \\\n      --root ${ARCH_TARGET_DIRECTORY}/contents \\\n      --install-location /usr/local/bin \\\n      --keychain cloudflared_build_keychain \\\n      --sign \"${PKG_SIGN_NAME}\" \\\n      ${PKGNAME}\n\n      # notarize the package\n      # TODO: TUN-5789\nelse\n    pkgbuild --identifier com.cloudflare.${PRODUCT} \\\n      --version ${VERSION} \\\n      --scripts ${ARCH_TARGET_DIRECTORY}/scripts \\\n      --root ${ARCH_TARGET_DIRECTORY}/contents \\\n      --install-location /usr/local/bin \\\n      ${PKGNAME}\nfi\n\n# cleanup build directory because this script is not ran within containers,\n# which might lead to future issues in subsequent runs.\nrm -rf \"${TARGET_DIRECTORY}\"\n\n# cleanup the keychain\nsecurity default-keychain -d user -s login.keychain-db\nsecurity list-keychains -d user -s login.keychain-db\nsecurity delete-keychain cloudflared_build_keychain\n"
  },
  {
    "path": ".ci/scripts/mac/install-go.sh",
    "content": "rm -rf /tmp/go\nexport GOCACHE=/tmp/gocache\nrm -rf $GOCACHE\n\nif [ -z \"$1\" ]\n  then\n    echo \"No go version supplied\"\nfi\n\nbrew install \"$1\"\n\ngo version\nwhich go\ngo env\n"
  },
  {
    "path": ".ci/scripts/package-windows.sh",
    "content": "#!/bin/bash\nset -e -u -o pipefail\n\npython3 -m venv env\n. env/bin/activate\npip install pynacl==1.4.0 pygithub==1.55\n\nVERSION=$(git describe --tags --always --match \"[0-9][0-9][0-9][0-9].*.*\")\necho $VERSION\n\nexport TARGET_OS=windows\n# This controls the directory the built artifacts go into\nexport BUILT_ARTIFACT_DIR=artifacts/\nexport FINAL_ARTIFACT_DIR=artifacts/\nmkdir -p $BUILT_ARTIFACT_DIR\nmkdir -p $FINAL_ARTIFACT_DIR\nwindowsArchs=(\"amd64\" \"386\")\nfor arch in ${windowsArchs[@]}; do\n    export TARGET_ARCH=$arch\n    # Copy .exe from artifacts directory\n    cp $BUILT_ARTIFACT_DIR/cloudflared-windows-$arch.exe ./cloudflared.exe\n    make cloudflared-msi\n    # Copy msi into final directory\n    mv cloudflared-$VERSION-$arch.msi $FINAL_ARTIFACT_DIR/cloudflared-windows-$arch.msi\ndone\n"
  },
  {
    "path": ".ci/scripts/release-target.sh",
    "content": "#!/bin/bash\nset -e -u -o pipefail\n\n# Check if a make target is provided as an argument\nif [ $# -eq 0 ]; then\n    echo \"Error: Make target argument is required\"\n    echo \"Usage: $0 <make-target>\"\n    exit 1\nfi\n\nMAKE_TARGET=$1\n\npython3 -m venv venv\nsource venv/bin/activate\n\n# Our release scripts are written in python, so we should install their dependecies here.\npip install pynacl==1.4.0 pygithub==1.55 boto3==1.42.30 python-gnupg==0.4.9\nmake $MAKE_TARGET\n"
  },
  {
    "path": ".ci/scripts/vuln-check.sh",
    "content": "#!/bin/bash\nset -e -u\n\n# Define the file to store the list of vulnerabilities to ignore.\nIGNORE_FILE=\".vulnignore\"\n\ngo version\n# Check if the ignored vulnerabilities file exists. If not, create an empty one.\nif [ ! -f \"$IGNORE_FILE\" ]; then\n  touch \"$IGNORE_FILE\"\n  echo \"Created an empty file to store ignored vulnerabilities: $IGNORE_FILE\"\n  echo \"# Add vulnerability IDs (e.g., GO-2022-0450) to ignore, one per line.\" >>\"$IGNORE_FILE\"\n  echo \"# You can also add comments on the same line after the ID.\" >>\"$IGNORE_FILE\"\n  echo \"\" >>\"$IGNORE_FILE\"\nfi\n\n# Run govulncheck and capture its output.\nVULN_OUTPUT=$(go run -mod=readonly golang.org/x/vuln/cmd/govulncheck@latest ./... || true)\n\n# Print the govuln output\necho \"=====================================\"\necho \"Full Output of govulncheck:\"\necho \"=====================================\"\necho \"$VULN_OUTPUT\"\necho \"=====================================\"\necho \"End of govulncheck Output\"\necho \"=====================================\"\n\n# Process the ignore file to remove comments and empty lines.\n# The 'cut' command gets the vulnerability ID and removes anything after the '#'.\n# The 'grep' command filters out empty lines and lines starting with '#'.\nCLEAN_IGNORES=$(grep -v '^\\s*#' \"$IGNORE_FILE\" | cut -d'#' -f1 | sed 's/ //g' | sort -u || true)\n\n# Filter out the ignored vulnerabilities.\nUNIGNORED_VULNS=$(echo \"$VULN_OUTPUT\" | grep 'Vulnerability' || true)\n\n# If the list of ignored vulnerabilities is not empty, filter them out.\nif [ -n \"$CLEAN_IGNORES\" ]; then\n  UNIGNORED_VULNS=$(echo \"$UNIGNORED_VULNS\" | grep -vFf <(echo \"$CLEAN_IGNORES\") || true)\nfi\n\n# If there are any vulnerabilities that were not in our ignore list, print them and exit with an error.\nif [ -n \"$UNIGNORED_VULNS\" ]; then\n  echo \"🚨 Found new, unignored vulnerabilities:\"\n  echo \"-------------------------------------\"\n  echo \"$UNIGNORED_VULNS\"\n  echo \"-------------------------------------\"\n  echo \"Exiting with an error. ❌\"\n  exit 1\nelse\n  echo \"🎉 No new vulnerabilities found. All clear! ✨\"\n  exit 0\nfi\n"
  },
  {
    "path": ".ci/scripts/windows/builds.ps1",
    "content": "Set-StrictMode -Version Latest\n$ErrorActionPreference = \"Stop\"\n$ProgressPreference = \"SilentlyContinue\"\n\n$env:TARGET_OS = \"windows\"\n$env:LOCAL_OS = \"windows\"\n$TIMESTAMP_RFC3161 = \"http://timestamp.digicert.com\"\n\nNew-Item -Path \".\\artifacts\" -ItemType Directory\n\nWrite-Output \"Building for amd64\"\n$env:TARGET_ARCH = \"amd64\"\n$env:LOCAL_ARCH = \"amd64\"\n$env:CGO_ENABLED = 1\n& make cloudflared\nif ($LASTEXITCODE -ne 0) { throw \"Failed to build cloudflared for amd64\" }\n# Sign build\nazuresigntool.exe sign -kvu $env:KEY_VAULT_URL -kvi \"$env:KEY_VAULT_CLIENT_ID\" -kvs \"$env:KEY_VAULT_SECRET\" -kvc \"$env:KEY_VAULT_CERTIFICATE\" -kvt \"$env:KEY_VAULT_TENANT_ID\" -tr \"$TIMESTAMP_RFC3161\" -d \"Cloudflare Tunnel Daemon\" .\\cloudflared.exe\ncopy .\\cloudflared.exe .\\artifacts\\cloudflared-windows-amd64.exe\n\nWrite-Output \"Building for 386\"\n$env:TARGET_ARCH = \"386\"\n$env:LOCAL_ARCH = \"386\"\n$env:CGO_ENABLED = 0\n& make cloudflared\nif ($LASTEXITCODE -ne 0) { throw \"Failed to build cloudflared for 386\" }\n## Sign build\nazuresigntool.exe sign -kvu $env:KEY_VAULT_URL -kvi \"$env:KEY_VAULT_CLIENT_ID\" -kvs \"$env:KEY_VAULT_SECRET\" -kvc \"$env:KEY_VAULT_CERTIFICATE\" -kvt \"$env:KEY_VAULT_TENANT_ID\" -tr \"$TIMESTAMP_RFC3161\" -d \"Cloudflare Tunnel Daemon\" .\\cloudflared.exe\ncopy .\\cloudflared.exe .\\artifacts\\cloudflared-windows-386.exe\n"
  },
  {
    "path": ".ci/scripts/windows/component-test.ps1",
    "content": "Set-StrictMode -Version Latest\n$ErrorActionPreference = \"Stop\"\n$ProgressPreference = \"SilentlyContinue\"\n\n$env:TARGET_OS = \"windows\"\n$env:LOCAL_OS = \"windows\"\n$env:TARGET_ARCH = \"amd64\"\n$env:LOCAL_ARCH = \"amd64\"\n$env:CGO_ENABLED = 1\n\npython --version\npython -m pip --version\n\n\nWrite-Host \"Building cloudflared\"\n& make cloudflared\nif ($LASTEXITCODE -ne 0) { throw \"Failed to build cloudflared\" }\n\n\nWrite-Host \"Running unit tests\"\n# Not testing with race detector because of https://github.com/golang/go/issues/61058\n# We already test it on other platforms\ngo test -failfast -v -mod=vendor ./...\nif ($LASTEXITCODE -ne 0) { throw \"Failed unit tests\" }\n\n\n# On Gitlab runners we need to add all of this addresses to the NO_PROXY list in order for the tests to run.\n$env:NO_PROXY = \"pypi.org,files.pythonhosted.org,api.cloudflare.com,argotunneltest.com,argotunnel.com,trycloudflare.com,${env:NO_PROXY}\"\nWrite-Host \"No Proxy: ${env:NO_PROXY}\"\nWrite-Host \"Running component tests\"\ntry {\n    python -m pip --disable-pip-version-check install --upgrade -r component-tests/requirements.txt --use-pep517\n    python component-tests/setup.py --type create\n    python -m pytest component-tests -o log_cli=true --log-cli-level=INFO --junit-xml=report.xml\n    if ($LASTEXITCODE -ne 0) {\n        throw \"Failed component tests\"\n    }\n} finally {\n    python component-tests/setup.py --type cleanup\n}\n"
  },
  {
    "path": ".ci/scripts/windows/go-wrapper.ps1",
    "content": "Param(\n    [string]$GoVersion,\n    [string]$ScriptToExecute\n)\n\n# The script is a wrapper that downloads a specific version\n# of go, adds it to the PATH and executes a script with that go\n# version in the path.\n\nSet-StrictMode -Version Latest\n$ErrorActionPreference = \"Stop\"\n$ProgressPreference = \"SilentlyContinue\"\n\n# Get the path to the system's temporary directory.\n$tempPath = [System.IO.Path]::GetTempPath()\n\n# Create a unique name for the new temporary folder.\n$folderName = \"go_\" + (Get-Random)\n\n# Join the temp path and the new folder name to create the full path.\n$fullPath = Join-Path -Path $tempPath -ChildPath $folderName\n\n# Store the current value of PATH environment variable.\n$oldPath = $env:Path\n\n# Use a try...finally block to ensure the temporrary folder and PATH are cleaned up.\ntry {\n    # Create the temporary folder.\n    Write-Host \"Creating temporary folder at: $fullPath\"\n    $newTempFolder = New-Item -ItemType Directory -Path $fullPath -Force\n\n    # Download go\n    $url = \"https://go.dev/dl/$GoVersion.windows-amd64.zip\"\n    $destinationFile = Join-Path -Path $newTempFolder.FullName -ChildPath \"go$GoVersion.windows-amd64.zip\"\n    Write-Host \"Downloading go from: $url\"\n    Invoke-WebRequest -Uri $url -OutFile $destinationFile\n    Write-Host \"File downloaded to: $destinationFile\"\n\n    # Unzip the downloaded file.\n    Write-Host \"Unzipping the file...\"\n    Expand-Archive -Path $destinationFile -DestinationPath $newTempFolder.FullName -Force\n    Write-Host \"File unzipped successfully.\"\n\n    # Define the go/bin path wich is inside the temporary folder\n    $goBinPath = Join-Path -Path $fullPath -ChildPath \"go\\bin\"\n\n    # Add the go/bin path to the PATH environment variable.\n    $env:Path = \"$goBinPath;$($env:Path)\"\n    Write-Host \"Added $goBinPath to the environment PATH.\"\n\n    go env\n    go version\n\n    & $ScriptToExecute\n} finally {\n    # Cleanup: Remove the path from the environment variable and then the temporary folder.\n    Write-Host \"Starting cleanup...\"\n\n    $env:Path = $oldPath\n    Write-Host \"Reverted changes in the environment PATH.\"\n\n    # Remove the temporary folder and its contents.\n    if (Test-Path -Path $fullPath) {\n        Remove-Item -Path $fullPath -Recurse -Force\n        Write-Host \"Temporary folder and its contents have been removed.\"\n    } else {\n        Write-Host \"Temporary folder does not exist, no cleanup needed.\"\n    }\n}\n"
  },
  {
    "path": ".ci/scripts/windows/sign-msi.ps1",
    "content": "# Sign Windows artifacts using azuretool\n# This script processes MSI files from the artifacts directory\n\n$ErrorActionPreference = \"Stop\"\n\n# Define paths\n$ARTIFACT_DIR = \"artifacts\"\n$TIMESTAMP_RFC3161 = \"http://timestamp.digicert.com\"\n\nWrite-Host \"Looking for Windows artifacts to sign in $ARTIFACT_DIR...\"\n\n# Find all Windows MSI files\n$msiFiles = Get-ChildItem -Path $ARTIFACT_DIR -Filter \"cloudflared-windows-*.msi\" -ErrorAction SilentlyContinue\n\nif ($msiFiles.Count -eq 0) {\n    Write-Host \"No Windows MSI files found in $ARTIFACT_DIR\"\n    exit 1\n}\n\nWrite-Host \"Found $($msiFiles.Count) file(s) to sign:\"\nforeach ($file in $msiFiles) {\n    Write-Host \"Running azuretool sign for $($file.Name)\"\n    azuresigntool.exe sign -kvu $env:KEY_VAULT_URL -kvi \"$env:KEY_VAULT_CLIENT_ID\" -kvs \"$env:KEY_VAULT_SECRET\" -kvc \"$env:KEY_VAULT_CERTIFICATE\" -kvt \"$env:KEY_VAULT_TENANT_ID\" -tr \"$TIMESTAMP_RFC3161\" -d \"Cloudflare Tunnel Daemon\" .\\\\$ARTIFACT_DIR\\\\$($file.Name)\n}\n\nWrite-Host \"Signing process completed\"\n"
  },
  {
    "path": ".ci/windows.gitlab-ci.yml",
    "content": "include:\n  - local: .ci/commons.gitlab-ci.yml\n\n###################################\n### Defaults for Windows Builds ###\n###################################\n.windows-build-defaults: &windows-build-defaults\n  rules:\n    - !reference [.default-rules, run-always]\n  tags:\n    - windows-x86\n  cache: {}\n\n##########################################\n### Build Cloudflared Windows Binaries ###\n##########################################\nwindows-build-cloudflared:\n  <<: *windows-build-defaults\n  stage: build\n  script:\n    - powershell -ExecutionPolicy Bypass -File \".\\.ci\\scripts\\windows\\go-wrapper.ps1\" \"${WIN_GO_VERSION}\" \".\\.ci\\scripts\\windows\\builds.ps1\"\n  artifacts:\n    paths:\n      - artifacts/*\n\n######################################################\n### Load Environment Variables for Component Tests ###\n######################################################\nwindows-load-env-variables:\n  stage: pre-build\n  extends: .component-tests\n  script:\n    - echo \"COMPONENT_TESTS_CONFIG=$COMPONENT_TESTS_CONFIG\" >> windows.env\n    - echo \"COMPONENT_TESTS_CONFIG_CONTENT=$COMPONENT_TESTS_CONFIG_CONTENT\" >> windows.env\n    - echo \"DNS_API_TOKEN=$DNS_API_TOKEN\" >> windows.env\n    # We have to encode the `COMPONENT_TESTS_ORIGINCERT` secret, because it content is a file, otherwise we can't export it using gitlab\n    - echo \"COMPONENT_TESTS_ORIGINCERT=$(echo \"$COMPONENT_TESTS_ORIGINCERT\" | base64 -w0)\" >> windows.env\n    - echo \"KEY_VAULT_URL=$KEY_VAULT_URL\" >> windows.env\n    - echo \"KEY_VAULT_CLIENT_ID=$KEY_VAULT_CLIENT_ID\" >> windows.env\n    - echo \"KEY_VAULT_TENANT_ID=$KEY_VAULT_TENANT_ID\" >> windows.env\n    - echo \"KEY_VAULT_SECRET=$KEY_VAULT_SECRET\" >> windows.env\n    - echo \"KEY_VAULT_CERTIFICATE=$KEY_VAULT_CERTIFICATE\" >> windows.env\n  variables:\n    COMPONENT_TESTS_CONFIG_CONTENT: Y2xvdWRmbGFyZWRfYmluYXJ5OiAuL2Nsb3VkZmxhcmVkLmV4ZQpjcmVkZW50aWFsc19maWxlOiBjcmVkLmpzb24Kb3JpZ2luY2VydDogY2VydC5wZW0Kem9uZV9kb21haW46IGFyZ290dW5uZWx0ZXN0LmNvbQp6b25lX3RhZzogNDg3OTZmMWU3MGJiNzY2OWMyOWJiNTFiYTI4MmJmNjU=\n  secrets:\n    KEY_VAULT_URL:\n      vault: gitlab/cloudflare/tun/cloudflared/_dev/azure_vault/app_info/key_vault_url@kv\n      file: false\n    KEY_VAULT_CLIENT_ID:\n      vault: gitlab/cloudflare/tun/cloudflared/_dev/azure_vault/app_info/key_vault_client_id@kv\n      file: false\n    KEY_VAULT_TENANT_ID:\n      vault: gitlab/cloudflare/tun/cloudflared/_dev/azure_vault/app_info/key_vault_tenant_id@kv\n      file: false\n    KEY_VAULT_SECRET:\n      vault: gitlab/cloudflare/tun/cloudflared/_dev/azure_vault/secret/key_vault_secret@kv\n      file: false\n    KEY_VAULT_CERTIFICATE:\n      vault: gitlab/cloudflare/tun/cloudflared/_dev/azure_vault/certificate/key_vault_certificate@kv\n      file: false\n  artifacts:\n    access: 'none'\n    reports:\n      dotenv: windows.env\n\n###################################\n### Run Windows Component Tests ###\n###################################\nwindows-component-tests-cloudflared:\n  <<: *windows-build-defaults\n  stage: test\n  needs: [\"windows-load-env-variables\"]\n  script:\n    # We have to decode the secret we encoded on the `windows-load-env-variables` job\n    - $env:COMPONENT_TESTS_ORIGINCERT = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($env:COMPONENT_TESTS_ORIGINCERT))\n    - powershell -ExecutionPolicy Bypass -File \".\\.ci\\scripts\\windows\\go-wrapper.ps1\" \"${WIN_GO_VERSION}\" \".\\.ci\\scripts\\windows\\component-test.ps1\"\n  artifacts:\n    reports:\n      junit: report.xml\n\n################################\n### Package Windows Binaries ###\n################################\nwindows-package:\n  rules:\n    - !reference [.default-rules, run-on-master]\n  stage: package\n  needs:\n    - ci-image-get-image-ref\n    - windows-build-cloudflared\n  image: $BUILD_IMAGE\n  script:\n    - .ci/scripts/package-windows.sh\n  cache: {}\n  artifacts:\n    paths:\n      - artifacts/*\n\n#############################\n### Sign Windows Binaries ###\n#############################\nwindows-package-sign:\n  <<: *windows-build-defaults\n  rules:\n    - !reference [.default-rules, run-on-master]\n  stage: package\n  needs:\n    - windows-package\n    - windows-load-env-variables\n  script:\n    - powershell -ExecutionPolicy Bypass -File \".\\.ci\\scripts\\windows\\sign-msi.ps1\"\n  artifacts:\n    paths:\n      - artifacts/*\n"
  },
  {
    "path": ".docker-images",
    "content": "images:\n  - name: cloudflared\n    dockerfile: Dockerfile.$ARCH\n    context: .\n    version_file: versions\n    registries:\n    - name: docker.io/cloudflare\n      user: env:DOCKER_USER\n      password: env:DOCKER_PASSWORD\n    architectures:\n    - amd64\n    - arm64\n"
  },
  {
    "path": ".dockerignore",
    "content": ""
  },
  {
    "path": ".github/ISSUE_TEMPLATE/---bug-report.md",
    "content": "---\nname: \"\\U0001F41B Bug report\"\nabout: Create a report to help us improve cloudflared\ntitle: \"\\U0001F41B\"\nlabels: 'Priority: Normal, Type: Bug'\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n1. Configure '...'\n2. Run '....'\n3. See error\n\nIf it's an issue with Cloudflare Tunnel:\n4. Tunnel ID : \n5. cloudflared config: \n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Environment and versions**\n - OS: [e.g. MacOS]\n - Architecture: [e.g. AMD, ARM]\n - Version: [e.g. 2022.02.0]\n\n**Logs and errors**\nIf applicable, add logs or errors to help explain your problem.\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/---documentation.md",
    "content": "---\nname: \"\\U0001F4DD Documentation\"\nabout: Request new or updated documentation for cloudflared\ntitle: \"\\U0001F4DD\"\nlabels: 'Priority: Normal, Type: Documentation'\n\n---\n\n**Available Documentation**\nA link to the documentation that is available today and the areas which could be improved. \n\n**Suggested Documentation**\nA clear and concise description of the documentation, tutorial, or guide that should be added. \n\n**Additional context**\nAdd any other context or screenshots about the documentation request here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/---feature-request.md",
    "content": "---\nname: \"\\U0001F4A1 Feature request\"\nabout: Suggest a feature or enhancement for cloudflared\ntitle: \"\\U0001F4A1\"\nlabels: 'Priority: Normal, Type: Feature Request'\n\n---\n\n**Describe the feature you'd like**\nA clear and concise description of the feature. What problem does it solve for you?\n\n**Describe alternatives you've considered**\nAre there any alternatives to solving this problem? If so, what was your experience with them?\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/workflows/check.yaml",
    "content": "on: [push, pull_request]\nname: Check\njobs:\n  check:\n    strategy:\n      matrix:\n        go-version: [1.22.x]\n        os: [ubuntu-latest, macos-latest, windows-latest]\n    runs-on: ${{ matrix.os }}\n    steps:\n    - name: Install Go\n      uses: actions/setup-go@v5\n      with:\n        go-version: ${{ matrix.go-version }}\n    - name: Checkout code\n      uses: actions/checkout@v4\n    - name: Test\n      run: make test\n"
  },
  {
    "path": ".github/workflows/semgrep.yml",
    "content": "on:\n  pull_request: {}\n  workflow_dispatch: {}\n  push: \n    branches:\n      - main\n      - master\n  schedule:\n    - cron: '0 0 * * *'\nname: Semgrep config\njobs:\n  semgrep:\n    name: semgrep/ci\n    runs-on: ubuntu-latest\n    env:\n      SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}\n      SEMGREP_URL: https://cloudflare.semgrep.dev\n      SEMGREP_APP_URL: https://cloudflare.semgrep.dev\n      SEMGREP_VERSION_CHECK_URL: https://cloudflare.semgrep.dev/api/check-version\n    container:\n      image: semgrep/semgrep\n    steps:\n      - uses: actions/checkout@v4\n      - run: semgrep ci\n"
  },
  {
    "path": ".gitignore",
    "content": "/tmp\n/bin\n.idea\n.build\n.vscode\n\\#*\\#\ncscope.*\n/cloudflared\n/cloudflared.pkg\n/cloudflared.exe\n/cloudflared.msi\n/cloudflared-x86-64*\n/cloudflared.1\n/packaging\n.DS_Store\n*-session.log\nssh_server_tests/.env\n/.cover\nbuilt_artifacts/\ncomponent-tests/.venv\n/artifacts\n"
  },
  {
    "path": ".gitlab-ci.yml",
    "content": "variables:\n  GO_VERSION: \"1.24.13\"\n  MAC_GO_VERSION: \"go@$GO_VERSION\"\n  WIN_GO_VERSION: \"go$GO_VERSION\"\n  GIT_DEPTH: \"0\"\n\ndefault:\n  id_tokens:\n    VAULT_ID_TOKEN:\n      aud: https://vault.cfdata.org\n\nstages:\n  [\n    sync,\n    pre-build,\n    build,\n    validate,\n    test,\n    package,\n    release,\n    release-internal,\n    review,\n  ]\n\ninclude:\n  #####################################################\n  ########## Import Commons Configurations ############\n  #####################################################\n  - local: .ci/commons.gitlab-ci.yml\n\n  #####################################################\n  ########### Sync Repository with Github #############\n  #####################################################\n  - local: .ci/github.gitlab-ci.yml\n\n  #####################################################\n  ############# Build or Fetch CI Image ###############\n  #####################################################\n  - local: .ci/ci-image.gitlab-ci.yml\n\n  #####################################################\n  ################## Linux Builds ###################\n  #####################################################\n  - local: .ci/linux.gitlab-ci.yml\n\n  #####################################################\n  ################## Windows Builds ###################\n  #####################################################\n  - local: .ci/windows.gitlab-ci.yml\n\n  #####################################################\n  ################### macOS Builds ####################\n  #####################################################\n  - local: .ci/mac.gitlab-ci.yml\n\n  #####################################################\n  ################# Release Packages ##################\n  #####################################################\n  - local: .ci/release.gitlab-ci.yml\n\n  #####################################################\n  ########## Release Packages Internally ##############\n  #####################################################\n  - local: .ci/apt-internal.gitlab-ci.yml\n\n  #####################################################\n  ############## Manual Claude Review #################\n  #####################################################\n  - component: $CI_SERVER_FQDN/cloudflare/ci/ai/review@~latest\n"
  },
  {
    "path": ".golangci.yaml",
    "content": "linters:\n  enable:\n    # Some of the linters below are commented out. We should uncomment and start running them, but they return\n    # too many problems to fix in one commit. Something for later.\n    - asasalint        # Check for pass []any as any in variadic func(...any).\n    - asciicheck       # Checks that all code identifiers does not have non-ASCII symbols in the name.\n    - bidichk          # Checks for dangerous unicode character sequences.\n    - bodyclose        # Checks whether HTTP response body is closed successfully.\n    - decorder         # Check declaration order and count of types, constants, variables and functions.\n    - dogsled          # Checks assignments with too many blank identifiers (e.g. x, , , _, := f()).\n    - dupl             # Tool for code clone detection.\n    - dupword          # Checks for duplicate words in the source code.\n    - durationcheck    # Check for two durations multiplied together.\n    - errcheck         # Errcheck is a program for checking for unchecked errors in Go code. These unchecked errors can be critical bugs in some cases.\n    - errname          # Checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error.\n    - exhaustive       # Check exhaustiveness of enum switch statements.\n    - gofmt            # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification.\n    - goimports        # Check import statements are formatted according to the 'goimport' command. Reformat imports in autofix mode.\n    - gosec            # Inspects source code for security problems.\n    - gosimple         # Linter for Go source code that specializes in simplifying code.\n    - govet            # Vet examines Go source code and reports suspicious constructs. It is roughly the same as 'go vet' and uses its passes.\n    - ineffassign      # Detects when assignments to existing variables are not used.\n    - importas         # Enforces consistent import aliases.\n    - misspell         # Finds commonly misspelled English words.\n    - prealloc         # Finds slice declarations that could potentially be pre-allocated.\n    - promlinter       # Check Prometheus metrics naming via promlint.\n    - sloglint         # Ensure consistent code style when using log/slog.\n    - sqlclosecheck    # Checks that sql.Rows, sql.Stmt, sqlx.NamedStmt, pgx.Query are closed.\n    - staticcheck      # It's a set of rules from staticcheck. It's not the same thing as the staticcheck binary.\n    - usetesting       # Reports uses of functions with replacement inside the testing package.\n    - testableexamples # Linter checks if examples are testable (have an expected output).\n    - testifylint      # Checks usage of github.com/stretchr/testify.\n    - tparallel        # Tparallel detects inappropriate usage of t.Parallel() method in your Go test codes.\n    - unconvert        # Remove unnecessary type conversions.\n    - unused           # Checks Go code for unused constants, variables, functions and types.\n    - wastedassign     # Finds wasted assignment statements.\n    - whitespace       # Whitespace is a linter that checks for unnecessary newlines at the start and end of functions, if, for, etc.\n    - zerologlint      # Detects the wrong usage of zerolog that a user forgets to dispatch with Send or Msg.\n  # Other linters are disabled, list of all is here: https://golangci-lint.run/usage/linters/\nrun:\n  timeout: 5m\n  modules-download-mode: vendor\n\n# output configuration options\noutput:\n  formats:\n    - format: 'colored-line-number'\n  print-issued-lines: true\n  print-linter-name: true\n\nissues:\n  # Maximum issues count per one linter.\n  # Set to 0 to disable.\n  # Default: 50\n  max-issues-per-linter: 50\n  # Maximum count of issues with the same text.\n  # Set to 0 to disable.\n  # Default: 3\n  max-same-issues: 15\n  # Show only new issues: if there are unstaged changes or untracked files,\n  # only those changes are analyzed, else only changes in HEAD~ are analyzed.\n  # It's a super-useful option for integration of golangci-lint into existing large codebase.\n  # It's not practical to fix all existing issues at the moment of integration:\n  # much better don't allow issues in new code.\n  #\n  # Default: false\n  new: true\n  # Show only new issues created after git revision `REV`.\n  # Default: \"\"\n  new-from-rev: ac34f94d423273c8fa8fdbb5f2ac60e55f2c77d5\n  # Show issues in any part of update files (requires new-from-rev or new-from-patch).\n  # Default: false\n  whole-files: true\n  # Which dirs to exclude: issues from them won't be reported.\n  # Can use regexp here: `generated.*`, regexp is applied on full path,\n  # including the path prefix if one is set.\n  # Default dirs are skipped independently of this option's value (see exclude-dirs-use-default).\n  # \"/\" will be replaced by current OS file path separator to properly work on Windows.\n  # Default: []\n  exclude-dirs:\n    - vendor\n\nlinters-settings:\n  # Check exhaustiveness of enum switch statements.\n  exhaustive:\n    # Presence of \"default\" case in switch statements satisfies exhaustiveness,\n    # even if all enum members are not listed.\n    # Default: false\n    default-signifies-exhaustive: true\n"
  },
  {
    "path": ".mac_resources/scripts/postinstall",
    "content": "#!/bin/bash\n\n# uninstall first in case this is an upgrade\n/usr/local/bin/cloudflared service uninstall\n\n# install the new service using launchctl\n/usr/local/bin/cloudflared service install"
  },
  {
    "path": ".mac_resources/uninstall.sh",
    "content": "#!/bin/bash\n\n/usr/local/bin/cloudflared service uninstall\nrm /usr/local/bin/cloudflared\npkgutil --forget com.cloudflare.cloudflared"
  },
  {
    "path": ".vulnignore",
    "content": "# Add vulnerability IDs (e.g., GO-2022-0450) to ignore, one per line.\n# You can also add comments on the same line after the ID.\n"
  },
  {
    "path": "AGENTS.md",
    "content": "# Cloudflared\n\nCloudflare's command-line tool and networking daemon written in Go.\nProduction-grade tunneling and network connectivity services used by millions of\ndevelopers and organizations worldwide.\n\n## Essential Commands\n\n### Build & Test (Always run before commits)\n\n```bash\n# Full development check (run before any commit)\nmake test lint\n\n# Build for current platform\nmake cloudflared\n\n# Run all unit tests with coverage\nmake test\nmake cover\n\n# Run specific test\ngo test -run TestFunctionName ./path/to/package\n\n# Run tests with race detection\ngo test -race ./...\n```\n\n### Platform-Specific Builds\n\n```bash\n# Linux\nTARGET_OS=linux TARGET_ARCH=amd64 make cloudflared\n\n# Windows\nTARGET_OS=windows TARGET_ARCH=amd64 make cloudflared\n\n# macOS ARM64\nTARGET_OS=darwin TARGET_ARCH=arm64 make cloudflared\n\n# FIPS compliant build\nFIPS=true make cloudflared\n```\n\n### Code Quality & Formatting\n\n```bash\n# Run linter (38+ enabled linters)\nmake lint\n\n# Auto-fix formatting\nmake fmt\ngofmt -w .\ngoimports -w .\n\n# Security scanning\nmake vet\n\n# Component tests (Python integration tests)\ncd component-tests && python -m pytest test_file.py::test_function_name\n```\n\n## Project Knowledge\n\n### Package Structure\n\n- Use meaningful package names that reflect functionality\n- Package names should be lowercase, single words when possible\n- Avoid generic names like `util`, `common`, `helper`\n\n### Function and Method Guidelines\n\n```go\n// Good: Clear purpose, proper error handling\nfunc (c *Connection) HandleRequest(ctx context.Context, req *http.Request) error {\n    if req == nil {\n        return errors.New(\"request cannot be nil\")\n    }\n    // Implementation...\n    return nil\n}\n```\n\n### Error Handling\n\n- Always handle errors explicitly, never ignore them\n- Use `fmt.Errorf` for error wrapping\n- Create meaningful error messages with context\n- Use error variables for common errors\n\n```go\n// Good error handling patterns\nif err != nil {\n    return fmt.Errorf(\"failed to process connection: %w\", err)\n}\n```\n\n### Logging Standards\n\n- Use `github.com/rs/zerolog` for structured logging\n- Include relevant context fields\n- Use appropriate log levels (Debug, Info, Warn, Error)\n\n```go\nlogger.Info().\n    Str(\"tunnelID\", tunnel.ID).\n    Int(\"connIndex\", connIndex).\n    Msg(\"Connection established\")\n```\n\n### Testing Patterns\n\n- Use `github.com/stretchr/testify` for assertions\n- Test files end with `_test.go`\n- Use table-driven tests for multiple scenarios\n- Always use `t.Parallel()` for parallel-safe tests\n- Use meaningful test names that describe behavior\n\n```go\nfunc TestMetricsListenerCreation(t *testing.T) {\n    t.Parallel()\n    // Test implementation\n    assert.Equal(t, expected, actual)\n    require.NoError(t, err)\n}\n```\n\n### Constants and Variables\n\n```go\nconst (\n    MaxGracePeriod       = time.Minute * 3\n    MaxConcurrentStreams = math.MaxUint32\n    LogFieldConnIndex    = \"connIndex\"\n)\n\nvar (\n    // Group related variables\n    switchingProtocolText = fmt.Sprintf(\"%d %s\", http.StatusSwitchingProtocols, http.StatusText(http.StatusSwitchingProtocols))\n    flushableContentTypes = []string{sseContentType, grpcContentType, sseJsonContentType}\n)\n```\n\n### Type Definitions\n\n- Define interfaces close to their usage\n- Keep interfaces small and focused\n- Use descriptive names for complex types\n\n```go\ntype TunnelConnection interface {\n    Serve(ctx context.Context) error\n}\n\ntype TunnelProperties struct {\n    Credentials    Credentials\n    QuickTunnelUrl string\n}\n```\n\n## Key Architectural Patterns\n\n### Context Usage\n\n- Always accept `context.Context` as first parameter for long-running operations\n- Respect context cancellation in loops and blocking operations\n- Pass context through call chains\n\n### Concurrency\n\n- Use channels for goroutine communication\n- Protect shared state with mutexes\n- Prefer `sync.RWMutex` for read-heavy workloads\n\n### Configuration\n\n- Use structured configuration with validation\n- Support both file-based and CLI flag configuration\n- Provide sensible defaults\n\n### Metrics and Observability\n\n- Instrument code with Prometheus metrics\n- Use OpenTelemetry for distributed tracing\n- Include structured logging with relevant context\n\n## Boundaries\n\n### ✅ Always Do\n\n- Run `make test lint` before any commit\n- Handle all errors explicitly with proper context\n- Use `github.com/rs/zerolog` for all logging\n- Add `t.Parallel()` to all parallel-safe tests\n- Follow the import grouping conventions\n- Use meaningful variable and function names\n- Include context.Context for long-running operations\n- Close resources in defer statements\n\n### ⚠️ Ask First Before\n\n- Adding new dependencies to go.mod\n- Modifying CI/CD configuration files\n- Changing build system or Makefile\n- Modifying component test infrastructure\n- Adding new linter rules or changing golangci-lint config\n- Making breaking changes to public APIs\n- Changing logging levels or structured logging fields\n\n### 🚫 Never Do\n\n- Ignore errors without explicit handling (`_ = err`)\n- Use generic package names (`util`, `helper`, `common`)\n- Commit code that fails `make test lint`\n- Use `fmt.Print*` instead of structured logging\n- Modify vendor dependencies directly\n- Commit secrets, credentials, or sensitive data\n- Use deprecated or unsafe Go patterns\n- Skip testing for new functionality\n- Remove existing tests unless they're genuinely invalid\n\n## Dependencies Management\n\n- Use Go modules (`go.mod`) exclusively\n- Vendor dependencies for reproducible builds\n- Keep dependencies up-to-date and secure\n- Prefer standard library when possible\n- Cloudflared uses a fork of quic-go always check release notes before bumping\n  this dependency.\n\n## Security Considerations\n\n- FIPS compliance support available\n- Vulnerability scanning integrated in CI\n- Credential handling follows security best practices\n- Network security with TLS/QUIC protocols\n- Regular security audits and updates\n- Post quantum encryption\n\n## Common Patterns to Follow\n\n1. **Graceful shutdown**: Always implement proper cleanup\n2. **Resource management**: Close resources in defer statements\n3. **Error propagation**: Wrap errors with meaningful context\n4. **Configuration validation**: Validate inputs early\n5. **Logging consistency**: Use structured logging throughout\n6. **Testing coverage**: Aim for comprehensive test coverage\n7. **Documentation**: Comment exported functions and types\n\nRemember: This is a mission-critical networking tool used in production by many\norganizations. Code quality, security, and reliability are paramount.\n"
  },
  {
    "path": "CHANGES.md",
    "content": "## 2026.2.0\n### Breaking Change\n- Removes the `proxy-dns` feature from cloudflared. This feature allowed running a local DNS over HTTPS (DoH) proxy.\n  Users who relied on this functionality should migrate to alternative solutions.\n  \n  Removed commands and flags:\n  - `cloudflared proxy-dns`\n  - `cloudflared tunnel proxy-dns` \n  - `--proxy-dns`, `--proxy-dns-port`, `--proxy-dns-address`, `--proxy-dns-upstream`, `--proxy-dns-max-upstream-conns`, `--proxy-dns-bootstrap`\n  - `resolver` section in configuration file\n\n## 2025.7.1\n### Notices\n- `cloudflared` will no longer officially support Debian and Ubuntu distros that reached end-of-life: `buster`, `bullseye`, `impish`, `trusty`.\n\n## 2025.1.1\n### New Features\n- This release introduces the use of new Post Quantum curves and the ability to use Post Quantum curves when running tunnels with the QUIC protocol this applies to non-FIPS and FIPS builds.\n\n## 2024.12.2\n### New Features\n- This release introduces the ability to collect troubleshooting information from one instance of cloudflared running on the local machine. The command can be executed as `cloudflared tunnel diag`.\n\n## 2024.12.1\n### Notices\n- The use of the `--metrics` is still honoured meaning that if this flag is set the metrics server will try to bind it, however, this version includes a change that makes the metrics server bind to a port with a semi-deterministic approach. If the metrics flag is not present the server will bind to the first available port of the range 20241 to 20245. In case of all ports being unavailable then the fallback is to bind to a random port.\n\n## 2024.10.0\n### Bug Fixes\n- We fixed a bug related to `--grace-period`. Tunnels that use QUIC as transport weren't abiding by this waiting period before forcefully closing the connections to the edge. From now on, both QUIC and HTTP2 tunnels will wait for either the grace period to end (defaults to 30 seconds) or until the last in-flight request is handled. Users that wish to maintain the previous behavior should set `--grace-period` to 0 if `--protocol` is set to `quic`. This will force `cloudflared` to shutdown as soon as either SIGTERM or SIGINT is received.\n\n## 2024.2.1\n### Notices\n- Starting from this version, tunnel diagnostics will be enabled by default. This will allow the engineering team to remotely get diagnostics from cloudflared during debug activities. Users still have the capability to opt-out of this feature by defining `--management-diagnostics=false` (or env `TUNNEL_MANAGEMENT_DIAGNOSTICS`).\n\n## 2023.9.0\n### Notices\n- The `warp-routing` `enabled: boolean` flag is no longer supported in the configuration file. Warp Routing traffic (eg TCP, UDP, ICMP) traffic is proxied to cloudflared if routes to the target tunnel are configured. This change does not affect remotely managed tunnels, but for locally managed tunnels, users that might be relying on this feature flag to block traffic should instead guarantee that tunnel has no Private Routes configured for the tunnel.\n## 2023.7.0\n### New Features\n- You can now enable additional diagnostics over the management.argotunnel.com service for your active cloudflared connectors via a new runtime flag `--management-diagnostics` (or env `TUNNEL_MANAGEMENT_DIAGNOSTICS`). This feature is provided as opt-in and requires the flag to enable. Endpoints such as /metrics provides your prometheus metrics endpoint another mechanism to be reached. Additionally /debug/pprof/(goroutine|heap) are also introduced to allow for remotely retrieving active pprof information from a running cloudflared connector.\n\n## 2023.4.1\n### New Features\n- You can now stream your logs from your remote cloudflared to your local terminal with `cloudflared tail <TUNNEL-ID>`. This new feature requires the remote cloudflared to be version 2023.4.1 or higher.\n\n## 2023.3.2\n### Notices\n- Due to the nature of QuickTunnels (https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/do-more-with-tunnels/trycloudflare/) and its intended usage for testing and experiment of Cloudflare Tunnels, starting from 2023.3.2, QuickTunnels only make a single connection to the edge. If users want to use Tunnels in a production environment, they should move to Named Tunnels instead. (https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/tunnel-guide/remote/#set-up-a-tunnel-remotely-dashboard-setup)\n\n## 2023.3.1\n### Breaking Change\n- Running a tunnel without ingress rules defined in configuration file nor from the CLI flags will no longer provide a default ingress rule to localhost:8080 and instead will return HTTP response code 503 for all incoming HTTP requests.\n\n### Security Fixes\n- Windows 32 bit machines MSI now defaults to Program Files to install cloudflared. (See CVE-2023-1314). The cloudflared client itself is unaffected. This just changes how the installer works on 32 bit windows machines.\n\n### Bug Fixes\n- Fixed a bug that would cause running tunnel on Bastion mode and without ingress rules to crash.\n\n## 2023.2.2\n### Notices\n- Legacy tunnels were officially deprecated on December 1, 2022. Starting with this version, cloudflared no longer supports connecting legacy tunnels.\n- h2mux tunnel connection protocol is no longer supported. Any tunnels still configured to use this protocol will alert and use http2 tunnel protocol instead. We recommend using quic protocol for all tunnels going forward.\n\n## 2023.2.1\n### Bug fixes\n- Fixed a bug in TCP connection proxy that could result in the connection being closed before all data was written.\n- cloudflared now correctly aborts body write if connection to origin service fails after response headers were sent already.\n- Fixed a bug introduced in the previous release where debug endpoints were removed.\n\n## 2022.12.0\n### Improvements\n- cloudflared now attempts to try other edge addresses before falling back to a lower protocol.\n- cloudflared tunnel no longer spins up a quick tunnel. The call has to be explicit and provide a --url flag.\n- cloudflared will now randomly pick the first or second region to connect to instead of always connecting to region2 first.\n\n## 2022.9.0\n### New Features\n- cloudflared now rejects ingress rules with invalid http status codes for http_status.\n\n## 2022.8.1\n### New Features\n- cloudflared now remembers if it connected to a certain protocol successfully. If it did, it does not fall back to a lower\n  protocol on connection failures.\n\n## 2022.7.1\n### New Features\n- It is now possible to connect cloudflared tunnel to Cloudflare Global Network with IPv6. See `cloudflared tunnel --help` and look for `edge-ip-version` for more information. For now, the default behavior is to still connect with IPv4 only.\n\n### Bug Fixes\n- Several bug fixes related with QUIC transport (used between cloudflared tunnel and Cloudflare Global Network). Updating to this version is highly recommended.\n\n## 2022.4.0\n### Bug Fixes\n- `cloudflared tunnel run` no longer logs the Tunnel token or JSON credentials in clear text as those are the secret\nthat allows to run the Tunnel.\n\n## 2022.3.4\n### New Features\n- It is now possible to retrieve the credentials that allow to run a Tunnel in case you forgot/lost them. This is\nachievable with: `cloudflared tunnel token --cred-file /path/to/file.json TUNNEL`. This new feature only works for\nTunnels created with cloudflared version 2022.3.0 or more recent.\n\n### Bug Fixes\n- `cloudflared service install` now starts the underlying agent service on Linux operating system (similarly to the\nbehaviour in Windows and MacOS).\n\n## 2022.3.3\n### Bug Fixes\n- `cloudflared service install` now starts the underlying agent service on Windows operating system (similarly to the\nbehaviour in MacOS).\n\n## 2022.3.1\n### Bug Fixes\n- Various fixes to the reliability of `quic` protocol, including an edge case that could lead to cloudflared crashing.\n\n## 2022.3.0\n### New Features\n- It is now possible to configure Ingress Rules to point to an origin served by unix socket with either HTTP or HTTPS.\nIf the origin starts with `unix:/` then we assume HTTP (existing behavior). Otherwise, the origin can start with\n`unix+tls:/` for HTTPS.\n\n## 2022.2.1\n### New Features\n- This project now has a new LICENSE that is more compliant with open source purposes.\n\n### Bug Fixes\n- Various fixes to the reliability of `quic` protocol.\n\n## 2022.1.3\n### New Features\n- New `cloudflared tunnel vnet` commands to allow for private routing to be virtualized. This means that the same CIDR\ncan now be used to point to two different Tunnels with `cloudflared tunnel route ip` command. More information will be\nmade available on blog.cloudflare.com and developers.cloudflare.com/cloudflare-one once the feature is globally available.\n\n### Bug Fixes\n- Correctly handle proxying UDP datagrams with no payload.\n- Bug fix for origins that use Server-Sent Events (SSE).\n\n## 2022.1.0\n### Improvements\n- If a specific `protocol` property is defined (e.g. for `quic`), cloudflared no longer falls back to an older protocol\n(such as `http2`) in face of connectivity errors. This is important because some features are only supported in a specific\nprotocol (e.g. UDP proxying only works for `quic`). Hence, if a user chooses a protocol, cloudflared now adheres to it\nno matter what.\n\n### Bug Fixes\n- Stopping cloudflared running with `quic` protocol now respects graceful shutdown.\n\n## 2021.12.2\n### Bug Fixes\n- Fix logging when `quic` transport is used and UDP traffic is proxied.\n- FIPS compliant cloudflared binaries will now be released as separate artifacts. Recall that these are only for linux\nand amd64.\n\n## 2021.12.1\n### Bug Fixes\n - Fixes Github issue #530 where cloudflared 2021.12.0 could not reach origins that were HTTPS and using certain encryption\nmethods forbidden by FIPS compliance (such as Let's Encrypt certificates). To address this fix we have temporarily reverted\nFIPS compliance from amd64 linux binaries that was recently introduced (or fixed actually as it was never working before).\n\n## 2021.12.0\n### New Features\n- Cloudflared binary released for amd64 linux is now FIPS compliant.\n\n### Improvements\n- Logging about connectivity to Cloudflare edge now only yields `ERR` level logging if there are no connections to\nCloudflare edge that are active. Otherwise it logs `WARN` level.\n \n### Bug Fixes\n- Fixes Github issue #501.\n\n## 2021.11.0\n### Improvements\n- Fallback from `protocol:quic` to `protocol:http2` immediately if UDP connectivity isn't available. This could be because of a firewall or \negress rule.\n\n## 2021.10.4\n### Improvements\n- Collect quic transport metrics on RTT, packets and bytes transferred.\n\n### Bug Fixes\n- Fix race condition that was writing to the connection after the http2 handler returns.\n\n## 2021.9.2\n\n### New features\n- `cloudflared` can now run with `quic` as the underlying tunnel transport protocol. To try it, change or add \"protocol: quic\" to your config.yml file or\nrun cloudflared with the `--protocol quic` flag. e.g:\n    `cloudflared tunnel --protocol quic run <tunnel-name>`\n\n### Bug Fixes\n- Fixed some generic transport bugs in `quic` mode. It's advised to upgrade to at least this version (2021.9.2) when running `cloudflared`\nwith `quic` protocol.\n- `cloudflared` docker images will now show version.\n\n\n## 2021.8.4\n### Improvements\n- Temporary tunnels (those hosted on trycloudflare.com that do not require a Cloudflare login) now run as Named Tunnels\nunderneath. We recall that these tunnels should not be relied upon for production usage as they come with no guarantee\nof uptime. Previous cloudflared versions will soon be unable to run legacy temporary tunnels and will require an update\n(to this version or more recent).\n\n## 2021.8.2\n### Improvements\n- Because Equinox os shutting down, all cloudflared releases are now present [here](https://github.com/cloudflare/cloudflared/releases).\n[Equinox](https://dl.equinox.io/cloudflare/cloudflared/stable) will no longer receive updates. \n\n## 2021.8.0\n### Bug fixes\n- Prevents tunnel from accidentally running when only proxy-dns should run. \n\n### Improvements\n- If auto protocol transport lookup fails, we now default to a transport instead of not connecting.\n\n## 2021.6.0\n### Bug Fixes\n- Fixes a http2 transport (the new default for Named Tunnels) to work with unix socket origins.\n\n\n## 2021.5.10\n### Bug Fixes\n- Fixes a memory leak in h2mux transport that connects cloudflared to Cloudflare edge.\n\n\n## 2021.5.9\n### New Features\n- Uses new Worker based login helper service to facilitate token exchange in cloudflared flows.\n\n### Bug Fixes\n- Fixes Centos-7 builds.\n\n## 2021.5.8\n### New Features\n- When creating a DNS record to point a hostname at a tunnel, you can now use --overwrite-dns to overwrite any existing\n  DNS records with that hostname. This works both when using the CLI to provision DNS, as well as when starting an adhoc\n  named tunnel, e.g.:\n  - `cloudflared tunnel route dns --overwrite-dns foo-tunnel foo.example.com`\n  - `cloudflared tunnel --overwrite-dns --name foo-tunnel --hostname foo.example.com`\n\n## 2021.5.7\n### New Features\n- Named Tunnels will automatically select the protocol to connect to Cloudflare's edge network.\n\n## 2021.5.0\n\n### New Features\n- It is now possible to run the same tunnel using more than one `cloudflared` instance. This is a server-side change and\n  is compatible with any client version that uses Named Tunnels.\n\n  To get started, visit our [developer documentation](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/run-tunnel/deploy-cloudflared-replicas).\n- `cloudflared tunnel ingress validate` will now warn about unused keys in your config file. This is helpful for\n  detecting typos in your config.\n- If `cloudflared` detects it is running inside a Linux container, it will limit itself to use only the number of CPUs\n  the pod has been granted, instead of trying to use every CPU available.\n\n## 2021.4.0\n\n### Bug Fixes\n\n- Fixed proxying of websocket requests to avoid possibility of losing initial frames that were sent in the same TCP\n  packet as response headers [#345](https://github.com/cloudflare/cloudflared/issues/345).\n- `proxy-dns` option now works in conjunction with running a named tunnel [#346](https://github.com/cloudflare/cloudflared/issues/346).\n\n## 2021.3.6\n\n### Bug Fixes\n\n- Reverted 2021.3.5 improvement to use HTTP/2 in a best-effort manner between cloudflared and origin services because\n  it was found to break in some cases.\n\n## 2021.3.5\n\n### Improvements\n\n - HTTP/2 transport is now always chosen if origin server supports it and the service url scheme is HTTPS.\n   This was previously done in a best attempt manner.\n\n### Bug Fixes\n\n - The MacOS binaries were not successfully released in 2021.3.3 and 2021.3.4. This release is aimed at addressing that.\n\n## 2021.3.3\n\n### Improvements\n\n- Tunnel create command, as well as, running ad-hoc tunnels using `cloudflared tunnel -name NAME`, will not overwrite\n  existing files when writing tunnel credentials.\n\n### Bug Fixes\n\n- Tunnel create and delete commands no longer use path to credentials from the configuration file.\n  If you need to place tunnel credentials file at a specific location, you must use `--credentials-file` flag.\n- Access ssh-gen creates properly named keys for SSH short lived certs.\n\n\n## 2021.3.2\n\n### New Features\n\n- It is now possible to obtain more detailed information about the cloudflared connectors to Cloudflare Edge via\n  `cloudflared tunnel info <name/uuid>`. It is possible to sort the output as well as output in different formats,\n  such as: `cloudflared tunnel info --sort-by version --invert-sort --output json <name/uuid>`.\n  You can obtain more information via `cloudflared tunnel info --help`.\n\n### Bug Fixes\n\n- Don't look for configuration file in default paths when `--config FILE` flag is present after `tunnel` subcommand.\n- cloudflared access token command now functions correctly with the new token-per-app change from 2021.3.0.\n\n\n## 2021.3.0\n\n### New Features\n\n- [Cloudflare One Routing](https://developers.cloudflare.com/cloudflare-one/tutorials/warp-to-tunnel) specific commands\n  now show up in the `cloudflared tunnel route --help` output.\n- There is a new ingress type that allows cloudflared to proxy SOCKS5 as a bastion. You can use it with an ingress\n  rule by adding `service: socks-proxy`. Traffic is routed to any destination specified by the SOCKS5 packet but only\n  if allowed by a rule. In the following example we allow proxying to a certain CIDR but explicitly forbid one address\n  within it:\n```\ningress:\n  - hostname: socks.example.com\n    service: socks-proxy\n    originRequest:\n      ipRules:\n        - prefix: 192.168.1.8/32\n          allow: false\n        - prefix: 192.168.1.0/24\n          ports: [80, 443]\n          allow: true\n```\n\n\n### Improvements\n\n- Nested commands, such as `cloudflared tunnel run`, now consider CLI arguments even if they appear earlier on the\n  command. For instance, `cloudflared --config config.yaml tunnel run` will now behave the same as\n  `cloudflared tunnel --config config.yaml run`\n- Warnings are now shown in the output logs whenever cloudflared is running without the most recent version and\n  `no-autoupdate` is `true`.\n- Access tokens are now stored per Access App instead of per request path. This decreases the number of times that the\n  user is required to authenticate with an Access policy redundantly.\n\n### Bug Fixes\n\n- GitHub [PR #317](https://github.com/cloudflare/cloudflared/issues/317) was broken in 2021.2.5 and is now fixed again.\n\n## 2021.2.5\n\n### New Features\n\n- We introduce [Cloudflare One Routing](https://developers.cloudflare.com/cloudflare-one/tutorials/warp-to-tunnel) in\n  beta mode. Cloudflare customer can now connect users and private networks with RFC 1918 IP addresses via the\n  Cloudflare edge network. Users running Cloudflare WARP client in the same organization can connect to the services\n  made available by Argo Tunnel IP routes. Please share your feedback in the GitHub issue tracker.\n\n## 2021.2.4\n\n### Bug Fixes\n\n- Reverts the Improvement released in 2021.2.3 for CLI arguments as it introduced a regression where cloudflared failed\n  to read URLs in configuration files.\n- cloudflared now logs the reason for failed connections if the error is recoverable.\n\n## 2021.2.3\n\n### Backward Incompatible Changes\n\n- Removes db-connect. The Cloudflare Workers product will continue to support db-connect implementations with versions\n  of cloudflared that predate this release and include support for db-connect.\n\n### New Features\n\n- Introduces support for proxy configurations with websockets in arbitrary TCP connections (#318).\n\n### Improvements\n\n- (reverted) Nested command line argument handling.\n\n### Bug Fixes\n\n- The maximum number of upstream connections is now limited by default which should fix reported issues of cloudflared\n  exhausting CPU usage when faced with connectivity issues.\n"
  },
  {
    "path": "Dockerfile",
    "content": "# use a builder image for building cloudflare\nARG TARGET_GOOS\nARG TARGET_GOARCH\nFROM golang:1.24.13 AS builder\nENV GO111MODULE=on \\\n  CGO_ENABLED=0 \\\n  TARGET_GOOS=${TARGET_GOOS} \\\n  TARGET_GOARCH=${TARGET_GOARCH} \\\n  # the CONTAINER_BUILD envvar is used set github.com/cloudflare/cloudflared/metrics.Runtime=virtual\n  # which changes how cloudflared binds the metrics server\n  CONTAINER_BUILD=1\n\n\nWORKDIR /go/src/github.com/cloudflare/cloudflared/\n\n# copy our sources into the builder image\nCOPY . .\n\n# compile cloudflared\nRUN make cloudflared\n\n# use a distroless base image with glibc\nFROM gcr.io/distroless/base-debian13:nonroot\n\nLABEL org.opencontainers.image.source=\"https://github.com/cloudflare/cloudflared\"\n\n# copy our compiled binary\nCOPY --from=builder --chown=nonroot /go/src/github.com/cloudflare/cloudflared/cloudflared /usr/local/bin/\n\n# run as nonroot user\n# We need to use numeric user id's because Kubernetes doesn't support strings:\n# https://github.com/kubernetes/kubernetes/blob/v1.33.2/pkg/kubelet/kuberuntime/security_context_others.go#L49\n# The `nonroot` user maps to `65532`, from: https://github.com/GoogleContainerTools/distroless/blob/main/common/variables.bzl#L18\nUSER 65532:65532\n\n# command / entrypoint of container\nENTRYPOINT [\"cloudflared\", \"--no-autoupdate\"]\nCMD [\"version\"]\n"
  },
  {
    "path": "Dockerfile.amd64",
    "content": "# use a builder image for building cloudflare\nFROM golang:1.24.13 AS builder\nENV GO111MODULE=on \\\n  CGO_ENABLED=0 \\\n  # the CONTAINER_BUILD envvar is used set github.com/cloudflare/cloudflared/metrics.Runtime=virtual\n  # which changes how cloudflared binds the metrics server\n  CONTAINER_BUILD=1 \n\nWORKDIR /go/src/github.com/cloudflare/cloudflared/\n\n# copy our sources into the builder image\nCOPY . .\n\n# compile cloudflared\nRUN GOOS=linux GOARCH=amd64 make cloudflared\n\n# use a distroless base image with glibc\nFROM gcr.io/distroless/base-debian13:nonroot\n\nLABEL org.opencontainers.image.source=\"https://github.com/cloudflare/cloudflared\"\n\n# copy our compiled binary\nCOPY --from=builder --chown=nonroot /go/src/github.com/cloudflare/cloudflared/cloudflared /usr/local/bin/\n\n# run as nonroot user\n# We need to use numeric user id's because Kubernetes doesn't support strings:\n# https://github.com/kubernetes/kubernetes/blob/v1.33.2/pkg/kubelet/kuberuntime/security_context_others.go#L49\n# The `nonroot` user maps to `65532`, from: https://github.com/GoogleContainerTools/distroless/blob/main/common/variables.bzl#L18\nUSER 65532:65532\n\n# command / entrypoint of container\nENTRYPOINT [\"cloudflared\", \"--no-autoupdate\"]\nCMD [\"version\"]\n"
  },
  {
    "path": "Dockerfile.arm64",
    "content": "# use a builder image for building cloudflare\nFROM golang:1.24.13 AS builder\nENV GO111MODULE=on \\\n  CGO_ENABLED=0 \\\n  # the CONTAINER_BUILD envvar is used set github.com/cloudflare/cloudflared/metrics.Runtime=virtual\n  # which changes how cloudflared binds the metrics server\n  CONTAINER_BUILD=1\n\nWORKDIR /go/src/github.com/cloudflare/cloudflared/\n\n# copy our sources into the builder image\nCOPY . .\n\n# compile cloudflared\nRUN GOOS=linux GOARCH=arm64 make cloudflared\n\n# use a distroless base image with glibc\nFROM gcr.io/distroless/base-debian13:nonroot-arm64\n\nLABEL org.opencontainers.image.source=\"https://github.com/cloudflare/cloudflared\"\n\n# copy our compiled binary\nCOPY --from=builder --chown=nonroot /go/src/github.com/cloudflare/cloudflared/cloudflared /usr/local/bin/\n\n# run as nonroot user\n# We need to use numeric user id's because Kubernetes doesn't support strings:\n# https://github.com/kubernetes/kubernetes/blob/v1.33.2/pkg/kubelet/kuberuntime/security_context_others.go#L49\n# The `nonroot` user maps to `65532`, from: https://github.com/GoogleContainerTools/distroless/blob/main/common/variables.bzl#L18\nUSER 65532:65532\n\n# command / entrypoint of container\nENTRYPOINT [\"cloudflared\", \"--no-autoupdate\"]\nCMD [\"version\"]\n"
  },
  {
    "path": "LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "Makefile",
    "content": "# The targets cannot be run in parallel\n.NOTPARALLEL:\n\nVERSION       := $(shell git describe --tags --always --match \"[0-9][0-9][0-9][0-9].*.*\")\nMSI_VERSION   := $(shell git tag -l --sort=v:refname | grep \"w\" | tail -1 | cut -c2-)\n#MSI_VERSION expects the format of the tag to be: (wX.X.X). Starts with the w character to not break cfsetup.\n#e.g. w3.0.1 or w4.2.10. It trims off the w character when creating the MSI.\n\nifeq ($(ORIGINAL_NAME), true)\n\t# Used for builds that want FIPS compilation but want the artifacts generated to still have the original name.\n\tBINARY_NAME := cloudflared\nelse ifeq ($(FIPS), true)\n\t# Used for FIPS compliant builds that do not match the case above.\n\tBINARY_NAME := cloudflared-fips\nelse\n\t# Used for all other (non-FIPS) builds.\n\tBINARY_NAME := cloudflared\nendif\n\nifeq ($(NIGHTLY), true)\n\tDEB_PACKAGE_NAME := $(BINARY_NAME)-nightly\n\tNIGHTLY_FLAGS := --conflicts cloudflared --replaces cloudflared\nelse\n\tDEB_PACKAGE_NAME := $(BINARY_NAME)\nendif\n\n# Use git in windows since we don't have access to the `date` tool\nifeq ($(TARGET_OS), windows)\n\tDATE := $(shell git log -1 --format=\"%ad\" --date=format-local:'%Y-%m-%dT%H:%M UTC' -- RELEASE_NOTES)\nelse\n\tDATE := $(shell date -u -r RELEASE_NOTES '+%Y-%m-%d-%H:%M UTC')\nendif\n\nVERSION_FLAGS := -X \"main.Version=$(VERSION)\" -X \"main.BuildTime=$(DATE)\"\nifdef PACKAGE_MANAGER\n\tVERSION_FLAGS := $(VERSION_FLAGS) -X \"github.com/cloudflare/cloudflared/cmd/cloudflared/updater.BuiltForPackageManager=$(PACKAGE_MANAGER)\"\nendif\n\nifdef CONTAINER_BUILD\n\tVERSION_FLAGS := $(VERSION_FLAGS) -X \"github.com/cloudflare/cloudflared/metrics.Runtime=virtual\"\nendif\n\nLINK_FLAGS :=\nifeq ($(FIPS), true)\n\tLINK_FLAGS := -linkmode=external -extldflags=-static $(LINK_FLAGS)\n\t# Prevent linking with libc regardless of CGO enabled or not.\n\tGO_BUILD_TAGS := $(GO_BUILD_TAGS) osusergo netgo fips\n\tVERSION_FLAGS := $(VERSION_FLAGS) -X \"main.BuildType=FIPS\"\nendif\n\nLDFLAGS := -ldflags='$(VERSION_FLAGS) $(LINK_FLAGS)'\nifneq ($(GO_BUILD_TAGS),)\n\tGO_BUILD_TAGS := -tags \"$(GO_BUILD_TAGS)\"\nendif\n\nifeq ($(debug), 1)\n\tGO_BUILD_TAGS += -gcflags=\"all=-N -l\"\nendif\n\nIMPORT_PATH    := github.com/cloudflare/cloudflared\nPACKAGE_DIR    := $(CURDIR)/packaging\nPREFIX         := /usr\nINSTALL_BINDIR := $(PREFIX)/bin/\nINSTALL_MANDIR := $(PREFIX)/share/man/man1/\n\nLOCAL_ARCH ?= $(shell uname -m)\nifneq ($(GOARCH),)\n    TARGET_ARCH ?= $(GOARCH)\nelse ifeq ($(LOCAL_ARCH),x86_64)\n    TARGET_ARCH ?= amd64\nelse ifeq ($(LOCAL_ARCH),amd64)\n    TARGET_ARCH ?= amd64\nelse ifeq ($(LOCAL_ARCH),386)\n    TARGET_ARCH ?= 386\nelse ifeq ($(LOCAL_ARCH),i686)\n    TARGET_ARCH ?= amd64\nelse ifeq ($(shell echo $(LOCAL_ARCH) | head -c 5),armv8)\n    TARGET_ARCH ?= arm64\nelse ifeq ($(LOCAL_ARCH),aarch64)\n    TARGET_ARCH ?= arm64\nelse ifeq ($(LOCAL_ARCH),arm64)\n    TARGET_ARCH ?= arm64\nelse ifeq ($(shell echo $(LOCAL_ARCH) | head -c 4),armv)\n    TARGET_ARCH ?= arm\nelse ifeq ($(LOCAL_ARCH),s390x)\n    TARGET_ARCH ?= s390x\nelse\n    $(error This system's architecture $(LOCAL_ARCH) isn't supported)\nendif\n\nLOCAL_OS ?= $(shell go env GOOS)\nifeq ($(LOCAL_OS),linux)\n    TARGET_OS ?= linux\nelse ifeq ($(LOCAL_OS),darwin)\n    TARGET_OS ?= darwin\nelse ifeq ($(LOCAL_OS),windows)\n    TARGET_OS ?= windows\nelse ifeq ($(LOCAL_OS),freebsd)\n    TARGET_OS ?= freebsd\nelse ifeq ($(LOCAL_OS),openbsd)\n    TARGET_OS ?= openbsd\nelse\n    $(error This system's OS $(LOCAL_OS) isn't supported)\nendif\n\nifeq ($(TARGET_OS), windows)\n\tEXECUTABLE_PATH=./$(BINARY_NAME).exe\nelse\n\tEXECUTABLE_PATH=./$(BINARY_NAME)\nendif\n\nifeq ($(FLAVOR), centos-7)\n\tTARGET_PUBLIC_REPO ?= el7\nelse\n\tTARGET_PUBLIC_REPO ?= $(FLAVOR)\nendif\n\nifneq ($(TARGET_ARM), )\n\tARM_COMMAND := GOARM=$(TARGET_ARM)\nendif\n\nifeq ($(TARGET_ARM), 7)\n\tPACKAGE_ARCH := armhf\nelse\n\tPACKAGE_ARCH := $(TARGET_ARCH)\nendif\n\n#for FIPS compliance, FPM defaults to MD5.\nRPM_DIGEST := --rpm-digest sha256\n\nGO_TEST_LOG_OUTPUT = /tmp/gotest.log\n\n.PHONY: all\nall: cloudflared test\n\n.PHONY: clean\nclean:\n\tgo clean\n\n.PHONY: vulncheck\nvulncheck:\n\t@./.ci/scripts/vuln-check.sh\n\n.PHONY: cloudflared\ncloudflared:\nifeq ($(FIPS), true)\n\t$(info Building cloudflared with go-fips)\nendif\n\tGOOS=$(TARGET_OS) GOARCH=$(TARGET_ARCH) $(ARM_COMMAND) go build -mod=vendor $(GO_BUILD_TAGS) $(LDFLAGS) $(IMPORT_PATH)/cmd/cloudflared\nifeq ($(FIPS), true)\n\t./check-fips.sh cloudflared\nendif\n\n.PHONY: container\ncontainer:\n\tdocker build --build-arg=TARGET_ARCH=$(TARGET_ARCH) --build-arg=TARGET_OS=$(TARGET_OS) -t cloudflare/cloudflared-$(TARGET_OS)-$(TARGET_ARCH):\"$(VERSION)\" .\n\n.PHONY: generate-docker-version\ngenerate-docker-version:\n\techo latest $(VERSION) > versions\n\n\n.PHONY: test\ntest: vet\n\t$Q go test -json -v -mod=vendor -race $(LDFLAGS) ./... 2>&1 | tee $(GO_TEST_LOG_OUTPUT)\nifneq ($(FIPS), true)\n\t@go run -mod=readonly github.com/gotesttools/gotestfmt/v2/cmd/gotestfmt@latest -input $(GO_TEST_LOG_OUTPUT)\nendif\n\n.PHONY: cover\ncover:\n\t@echo \"\"\n\t@echo \"=====> Total test coverage: <=====\"\n\t@echo \"\"\n\t# Print the overall coverage here for quick access.\n\t$Q go tool cover -func \".cover/c.out\" | grep \"total:\" | awk '{print $$3}'\n\t# Generate the HTML report that can be viewed from the browser in CI.\n\t$Q go tool cover -html \".cover/c.out\" -o .cover/all.html\n\n.PHONY: fuzz\nfuzz:\n\t@go test -fuzz=FuzzIPDecoder -fuzztime=600s ./packet\n\t@go test -fuzz=FuzzICMPDecoder -fuzztime=600s ./packet\n\t@go test -fuzz=FuzzSessionWrite -fuzztime=600s ./quic/v3\n\t@go test -fuzz=FuzzSessionRead -fuzztime=600s ./quic/v3\n\t@go test -fuzz=FuzzRegistrationDatagram -fuzztime=600s ./quic/v3\n\t@go test -fuzz=FuzzPayloadDatagram -fuzztime=600s ./quic/v3\n\t@go test -fuzz=FuzzRegistrationResponseDatagram -fuzztime=600s ./quic/v3\n\t@go test -fuzz=FuzzNewIdentity -fuzztime=600s ./tracing\n\t@go test -fuzz=FuzzNewAccessValidator -fuzztime=600s ./validation\n\ncloudflared.1: cloudflared_man_template\n\tsed -e 's/\\$${VERSION}/$(VERSION)/; s/\\$${DATE}/$(DATE)/' cloudflared_man_template > cloudflared.1\n\ninstall: cloudflared cloudflared.1\n\tmkdir -p $(DESTDIR)$(INSTALL_BINDIR) $(DESTDIR)$(INSTALL_MANDIR)\n\tinstall -m755 cloudflared $(DESTDIR)$(INSTALL_BINDIR)/cloudflared\n\tinstall -m644 cloudflared.1 $(DESTDIR)$(INSTALL_MANDIR)/cloudflared.1\n\n# When we build packages, the package name will be FIPS-aware.\n# But we keep the binary installed by it to be named \"cloudflared\" regardless.\ndefine build_package\n\tmkdir -p $(PACKAGE_DIR)\n\tcp cloudflared $(PACKAGE_DIR)/cloudflared\n\tcp cloudflared.1 $(PACKAGE_DIR)/cloudflared.1\n\tfpm -C $(PACKAGE_DIR) -s dir -t $(1) \\\n\t\t--description 'Cloudflare Tunnel daemon' \\\n\t\t--vendor 'Cloudflare' \\\n\t\t--license 'Apache License Version 2.0' \\\n\t\t--url 'https://github.com/cloudflare/cloudflared' \\\n\t\t-m 'Cloudflare <support@cloudflare.com>' \\\n\t    -a $(PACKAGE_ARCH) -v $(VERSION) -n $(DEB_PACKAGE_NAME) $(RPM_DIGEST) $(NIGHTLY_FLAGS) --after-install postinst.sh --after-remove postrm.sh \\\n\t\tcloudflared=$(INSTALL_BINDIR) cloudflared.1=$(INSTALL_MANDIR)\nendef\n\n.PHONY: cloudflared-deb\ncloudflared-deb: cloudflared cloudflared.1\n\t$(call build_package,deb)\n\n.PHONY: cloudflared-rpm\ncloudflared-rpm: cloudflared cloudflared.1\n\t$(call build_package,rpm)\n\n.PHONY: cloudflared-msi\ncloudflared-msi:\n\twixl --define Version=$(VERSION) --define Path=$(EXECUTABLE_PATH) --output cloudflared-$(VERSION)-$(TARGET_ARCH).msi cloudflared.wxs\n\n.PHONY: github-release-dryrun\ngithub-release-dryrun:\n\tpython3 github_release.py --path $(PWD)/built_artifacts --release-version $(VERSION) --dry-run\n\n.PHONY: github-release\ngithub-release:\n\tpython3 github_release.py --path $(PWD)/artifacts/ --release-version $(VERSION)\n\tpython3 github_message.py --release-version $(VERSION)\n\n.PHONY: r2-linux-release\nr2-linux-release:\n\tpython3 ./release_pkgs.py\n\n.PHONY: r2-next-linux-release\n# Publishes to a separate R2 repository during GPG key rollover, using dual-key signing.\nr2-next-linux-release:\n\tpython3 ./release_pkgs.py --upload-repo-file\n\n.PHONY: capnp\ncapnp:\n\twhich capnp  # https://capnproto.org/install.html\n\twhich capnpc-go  # go install zombiezen.com/go/capnproto2/capnpc-go@latest\n\tcapnp compile -ogo tunnelrpc/proto/tunnelrpc.capnp tunnelrpc/proto/quic_metadata_protocol.capnp\n\n.PHONY: vet\nvet:\n\t$Q go vet -mod=vendor github.com/cloudflare/cloudflared/...\n\n.PHONY: fmt\nfmt:\n\t@goimports -l -w -local github.com/cloudflare/cloudflared $$(go list -mod=vendor -f '{{.Dir}}' -a ./... | fgrep -v tunnelrpc/proto)\n\t@go fmt $$(go list -mod=vendor -f '{{.Dir}}' -a ./... | fgrep -v tunnelrpc/proto)\n\n.PHONY: fmt-check\nfmt-check:\n\t@./.ci/scripts/fmt-check.sh\n\n.PHONY: lint\nlint:\n\t@golangci-lint run\n\n.PHONY: mocks\nmocks:\n\tgo generate mocks/mockgen.go\n\n.PHONY: ci-build\nci-build:\n\t@GOOS=linux GOARCH=amd64 $(MAKE) cloudflared\n\t@mkdir -p artifacts\n\t@mv cloudflared artifacts/cloudflared\n\n.PHONY: ci-fips-build\nci-fips-build:\n\t@FIPS=true GOOS=linux GOARCH=amd64 $(MAKE) cloudflared\n\t@mkdir -p artifacts\n\t@mv cloudflared artifacts/cloudflared\n\n.PHONY: ci-test\nci-test: fmt-check lint test\n\t@go run -mod=readonly github.com/jstemmer/go-junit-report/v2@latest -in $(GO_TEST_LOG_OUTPUT) -parser gojson -out report.xml -set-exit-code\n\n.PHONY: ci-fips-test\nci-fips-test:\n\t@FIPS=true $(MAKE) ci-test\n"
  },
  {
    "path": "README.md",
    "content": "# Cloudflare Tunnel client\n\nContains the command-line client for Cloudflare Tunnel, a tunneling daemon that proxies traffic from the Cloudflare network to your origins.\nThis daemon sits between Cloudflare network and your origin (e.g. a webserver). Cloudflare attracts client requests and sends them to you\nvia this daemon, without requiring you to poke holes on your firewall --- your origin can remain as closed as possible.\nExtensive documentation can be found in the [Cloudflare Tunnel section](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel) of the Cloudflare Docs.\nAll usages related with proxying to your origins are available under `cloudflared tunnel help`.\n\nYou can also use `cloudflared` to access Tunnel origins (that are protected with `cloudflared tunnel`) for TCP traffic\nat Layer 4 (i.e., not HTTP/websocket), which is relevant for use cases such as SSH, RDP, etc.\nSuch usages are available under `cloudflared access help`.\n\nYou can instead use [WARP client](https://developers.cloudflare.com/warp-client/)\nto access private origins behind Tunnels for Layer 4 traffic without requiring `cloudflared access` commands on the client side.\n\n\n## Before you get started\n\nBefore you use Cloudflare Tunnel, you'll need to complete a few steps in the Cloudflare dashboard: you need to add a\nwebsite to your Cloudflare account. Note that today it is possible to use Tunnel without a website (e.g. for private\nrouting), but for legacy reasons this requirement is still necessary:\n1. [Add a website to Cloudflare](https://developers.cloudflare.com/fundamentals/manage-domains/add-site/)\n2. [Change your domain nameservers to Cloudflare](https://developers.cloudflare.com/dns/zone-setups/full-setup/setup/)\n\n\n## Installing `cloudflared`\n\nDownloads are available as standalone binaries, a Docker image, and Debian, RPM, and Homebrew packages. You can also find releases [here](https://github.com/cloudflare/cloudflared/releases) on the `cloudflared` GitHub repository.\n\n* You can [install on macOS](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/downloads/#macos) via Homebrew or by downloading the [latest Darwin amd64 release](https://github.com/cloudflare/cloudflared/releases)\n* Binaries, Debian, and RPM packages for Linux [can be found here](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/downloads/#linux)\n* A Docker image of `cloudflared` is [available on DockerHub](https://hub.docker.com/r/cloudflare/cloudflared)\n* You can install on Windows machines with the [steps here](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/downloads/#windows)\n* To build from source, install the required version of go, mentioned in the [Development](#development) section below. Then you can run `make cloudflared`.\n\nUser documentation for Cloudflare Tunnel can be found at https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/\n\n\n## Creating Tunnels and routing traffic\n\nOnce installed, you can authenticate `cloudflared` into your Cloudflare account and begin creating Tunnels to serve traffic to your origins.\n\n* Create a Tunnel with [these instructions](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/get-started/create-remote-tunnel/)\n* Route traffic to that Tunnel:\n  * Via public [DNS records in Cloudflare](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/routing-to-tunnel/dns/)\n  * Or via a public hostname guided by a [Cloudflare Load Balancer](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/routing-to-tunnel/public-load-balancers/)\n  * Or from [WARP client private traffic](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/private-net/)\n\n\n## TryCloudflare\n\nWant to test Cloudflare Tunnel before adding a website to Cloudflare? You can do so with TryCloudflare using the documentation [available here](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/do-more-with-tunnels/trycloudflare/).\n\n## Deprecated versions\n\nCloudflare currently supports versions of cloudflared that are **within one year** of the most recent release. Breaking changes unrelated to feature availability may be introduced that will impact versions released more than one year ago. You can read more about upgrading cloudflared in our [developer documentation](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/downloads/update-cloudflared/).\n\nFor example, as of January 2023 Cloudflare will support cloudflared version 2023.1.1 to cloudflared 2022.1.1.\n\n## Development\n\n### Requirements\n- [GNU Make](https://www.gnu.org/software/make/)\n- [capnp](https://capnproto.org/install.html)\n- [go >= 1.24](https://go.dev/doc/install)\n- Optional tools:\n  - [capnpc-go](https://pkg.go.dev/zombiezen.com/go/capnproto2/capnpc-go)\n  - [goimports](https://pkg.go.dev/golang.org/x/tools/cmd/goimports)\n  - [golangci-lint](https://github.com/golangci/golangci-lint)\n  - [gomocks](https://pkg.go.dev/go.uber.org/mock)\n\n### Build\nTo build cloudflared locally run `make cloudflared`\n\n### Test\nTo locally run the tests run `make test`\n\n### Linting\nTo format the code and keep a good code quality use `make fmt` and `make lint`\n\n### Mocks\nAfter changes on interfaces you might need to regenerate the mocks, so run `make mock`\n"
  },
  {
    "path": "RELEASE_NOTES",
    "content": "2026.3.0\n- 2026-03-05 TUN-10292: Add cloudflared management token command\n- 2026-03-03 chore: Addressing small fixes and typos\n- 2026-03-03 fix: Update go-sentry and go-oidc to address CVE's\n- 2026-02-24 TUN-10258: add agents.md\n- 2026-02-23 TUN-10267: Update mods to fix CVE GO-2026-4394\n- 2026-02-20 TUN-10247: Update tail command to use /management/logs endpoint\n- 2026-02-11 TUN-9858: Add more information to proxy-dns removal message\n\n2026.2.0\n- 2026-02-06 TUN-10216: TUN fix cloudflare vulnerabilities GO-2026-4340 and GO-2026-4341\n- 2026-02-02 TUN-9858: Remove proxy-dns feature from cloudflared\n\n2026.1.2\n- 2026-01-23 Revert \"TUN-9863: Update pipelines to use cloudflared EV Certificate\"\n- 2026-01-21 Revert \"TUN-9886 notarize cloudflared\"\n- 2025-12-12 TUN-9886 notarize cloudflared\n\n2026.1.1\n- 2026-01-19 fix: Update boto3 to run on trixie\n- 2026-01-19 fix: Fix wixl bundling tool for windows msi packages\n- 2026-01-19 fix: rpm bundling and rpm key import\n\n2026.1.0\n- 2026-01-13 TUN-10162: Update go to 1.24.11 and Debian distroless to debian13\n- 2025-11-21 Replace jira.cfops.it with jira.cfdata.org in connection/http2_test.go\n- 2025-11-19 TUN-9863: Update pipelines to use cloudflared EV Certificate\n- 2025-11-07 TUN-9800: Migrate apt internal builds to Gitlab\n- 2025-11-04 TUN-9998: Don't need to read origin cert to determine if the endpoint is fedramp\n- 2025-10-13 TUN-9910: Make the metadata key to carry HTTP status over QUIC transport a constant\n\n2025.11.1\n- 2025-11-07 TUN-9800: Fix docker hub push step\n\n2025.11.0\n- 2025-11-06 TUN-9863: Introduce Code Signing for Windows Builds\n- 2025-11-06 TUN-9800: Prefix gitlab steps with operating system\n- 2025-11-04 chore: Update cloudflared signing key name in index.html\n- 2025-10-31 chore: add claude review\n- 2025-10-31 Chore: Update documentation links in README\n- 2025-10-31 TUN-9800: Add pipelines for linux packaging\n\n2025.10.1\n- 2025-10-30 chore: Update ci image to use goboring 1.24.9\n- 2025-10-28 TUN-9849: Add cf-proxy-* to control response headers\n- 2025-10-24 TUN-9961: Add pkg.cloudflared.com index.html to git repo\n- 2025-10-23 TUN-9954: Update from go1.24.6 to go1.24.9\n- 2025-10-23 Fix systemd service installation hanging\n- 2025-10-21 TUN-9941: Use new GPG key for RPM builds\n- 2025-10-21 TUN-9941: Fix typo causing r2-release-next deployment to fail\n- 2025-10-21 TUN-9941: Lookup correct key for RPM signature\n- 2025-10-15 TUN-9919: Make RPM postinstall scriplet idempotent\n- 2025-10-14 TUN-9916: Fix the cloudflared binary path used in the component test\n\n2025.10.0\n- 2025-10-14 chore: Fix upload of RPM repo file during double signing\n- 2025-10-13 TUN-9882: Bump datagram v3 write channel capacity\n- 2025-10-10 chore: Fix import of GPG keys when two keys are provided\n- 2025-10-10 chore: Fix parameter order when uploading RPM .repo file to R2\n- 2025-10-10 TUN-9883: Add new datagram v3 feature flag\n- 2025-10-09 chore: Force usage of go-boring 1.24\n- 2025-10-08 TUN-9882: Improve metrics for datagram v3\n- 2025-10-07 GRC-16749: Add fedramp tags to catalog\n- 2025-10-07 TUN-9882: Add buffers for UDP and ICMP datagrams in datagram v3\n- 2025-10-07 TUN-9882: Add write deadline for UDP origin writes\n- 2025-09-29 TUN-9776: Support signing Debian packages with two keys for rollover\n- 2025-09-22 TUN-9800: Add pipeline to sync between gitlab and github repos\n\n2025.9.1\n- 2025-09-22 TUN-9855: Create script to ignore vulnerabilities from govuln check\n- 2025-09-19 TUN-9852: Remove fmt.Println from cloudflared access command\n\n2025.9.0\n- 2025-09-15 TUN-9820: Add support for FedRAMP in originRequest Access config\n- 2025-09-11 TUN-9800: Migrate cloudflared-ci pipelines to Gitlab CI\n- 2025-09-04 TUN-9803: Add windows builds to gitlab-ci\n- 2025-08-27 TUN-9755: Set endpoint in tunnel credentials when generating locally managed tunnel with a Fed token\n\n2025.8.1\n- 2025-08-19 AUTH-7480 update fed callback url for login helper\n- 2025-08-19 CUSTESC-53681: Correct QUIC connection management for datagram handlers\n- 2025-08-12 AUTH-7260: Add support for login interstitial auto closure\n\n2025.8.0\n- 2025-08-07 vuln: Fix GO-2025-3770 vulnerability\n- 2025-07-23 TUN-9583: set proper url and hostname for cloudflared tail command\n- 2025-07-07 TUN-9542: Remove unsupported Debian-based releases\n\n2025.7.0\n- 2025-07-03 TUN-9540: Use numeric user id for Dockerfiles\n- 2025-07-01 TUN-9161: Remove P256Kyber768Draft00PQKex curve from nonFips curve preferences\n- 2025-07-01 TUN-9531: Bump go-boring from 1.24.2 to 1.24.4\n- 2025-07-01 TUN-9511: Add metrics for virtual DNS origin\n- 2025-06-30 TUN-9470: Add OriginDialerService to include TCP\n- 2025-06-30 TUN-9473: Add --dns-resolver-addrs flag\n- 2025-06-27 TUN-9472: Add virtual DNS service\n- 2025-06-23 TUN-9469: Centralize UDP origin proxy dialing as ingress service\n\n2025.6.1\n- 2025-06-16 TUN-9467: add vulncheck to cloudflared\n- 2025-06-16 TUN-9495: Remove references to cloudflare-go\n- 2025-06-16 TUN-9371: Add logging format as JSON\n- 2025-06-12 TUN-9467: bump coredns to solve CVE\n\n2025.6.0\n- 2025-06-06 TUN-9016: update go to 1.24\n- 2025-06-05 TUN-9171: Use `is_default_network` instead of `is_default` to create vnet's\n\n2025.5.0\n- 2025-05-14 TUN-9319: Add dynamic loading of features to connections via ConnectionOptionsSnapshot\n- 2025-05-13 TUN-9322: Add metric for unsupported RPC commands for datagram v3\n- 2025-05-07 TUN-9291: Remove dynamic reloading of features for datagram v3\n\n2025.4.2\n- 2025-04-30 chore: Do not use gitlab merge request pipelines\n- 2025-04-30 DEVTOOLS-16383: Create GitlabCI pipeline to release Mac builds\n- 2025-04-24 TUN-9255: Improve flush on write conditions in http2 tunnel type to match what is done on the edge\n- 2025-04-10 SDLC-3727 - Adding FIPS status to backstage\n\n2025.4.0\n- 2025-04-02 Fix broken links in `cmd/cloudflared/*.go` related to running tunnel as a service\n- 2025-04-02 chore: remove repetitive words\n- 2025-04-01 Fix messages to point to one.dash.cloudflare.com\n- 2025-04-01 feat: emit explicit errors for the `service` command on unsupported OSes\n- 2025-04-01 Use RELEASE_NOTES date instead of build date\n- 2025-04-01 chore: Update tunnel configuration link in the readme\n- 2025-04-01 fix: expand home directory for credentials file\n- 2025-04-01 fix: Use path and filepath operation appropriately\n- 2025-04-01 feat: Adds a new command line for tunnel run for token file\n- 2025-04-01 chore: fix linter rules\n- 2025-03-17 TUN-9101: Don't ignore errors on `cloudflared access ssh`\n- 2025-03-06 TUN-9089: Pin go import to v0.30.0, v0.31.0 requires go 1.23\n\n2025.2.1\n- 2025-02-26 TUN-9016: update base-debian to v12\n- 2025-02-25 TUN-8960: Connect to FED API GW based on the OriginCert's endpoint\n- 2025-02-25 TUN-9007: modify logic to resolve region when the tunnel token has an endpoint field\n- 2025-02-13 SDLC-3762: Remove backstage.io/source-location from catalog-info.yaml\n- 2025-02-06 TUN-8914: Create a flags module to group all cloudflared cli flags\n\n2025.2.0\n- 2025-02-03 TUN-8914: Add a new configuration to locally override the max-active-flows\n- 2025-02-03 Bump x/crypto to 0.31.0\n\n2025.1.1\n- 2025-01-30 TUN-8858: update go to 1.22.10 and include quic-go FIPS changes\n- 2025-01-30 TUN-8855: fix lint issues\n- 2025-01-30 TUN-8855: Update PQ curve preferences\n- 2025-01-30 TUN-8857: remove restriction for using FIPS and PQ\n- 2025-01-30 TUN-8894: report FIPS+PQ error to Sentry when dialling to the edge\n- 2025-01-22 TUN-8904: Rename Connect Response Flow Rate Limited metadata\n- 2025-01-21 AUTH-6633 Fix cloudflared access login + warp as auth\n- 2025-01-20 TUN-8861: Add session limiter to UDP session manager\n- 2025-01-20 TUN-8861: Rename Session Limiter to Flow Limiter\n- 2025-01-17 TUN-8900: Add import of Apple Developer Certificate Authority to macOS Pipeline\n- 2025-01-17 TUN-8871: Accept login flag to authenticate with Fedramp environment\n- 2025-01-16 TUN-8866: Add linter to cloudflared repository\n- 2025-01-14 TUN-8861: Add session limiter to TCP session manager\n- 2025-01-13 TUN-8861: Add configuration for active sessions limiter\n- 2025-01-09 TUN-8848: Don't treat connection shutdown as an error condition when RPC server is done\n\n2025.1.0\n- 2025-01-06 TUN-8842: Add Ubuntu Noble and 'any' debian distributions to release script\n- 2025-01-06 TUN-8807: Add support_datagram_v3 to remote feature rollout\n- 2024-12-20 TUN-8829: add CONTAINER_BUILD to dockerfiles\n\n2024.12.2\n- 2024-12-19 TUN-8822: Prevent concurrent usage of ICMPDecoder\n- 2024-12-18 TUN-8818: update changes document to reflect newly added diag subcommand\n- 2024-12-17 TUN-8817: Increase close session channel by one since there are two writers\n- 2024-12-13 TUN-8797: update CHANGES.md with note about semi-deterministic approach used to bind metrics server\n- 2024-12-13 TUN-8724: Add CLI command for diagnostic procedure\n- 2024-12-11 TUN-8786: calculate cli flags once for the diagnostic procedure\n- 2024-12-11 TUN-8792: Make diag/system endpoint always return a JSON\n- 2024-12-10 TUN-8783: fix log collectors for the diagnostic procedure\n- 2024-12-10 TUN-8785: include the icmp sources in the diag's tunnel state\n- 2024-12-10 TUN-8784: Set JSON encoder options to print formatted JSON when writing diag files\n\n2024.12.1\n- 2024-12-10 TUN-8795: update createrepo to createrepo_c to fix the release_pkgs.py script\n\n2024.12.0\n- 2024-12-09 TUN-8640: Add ICMP support for datagram V3\n- 2024-12-09 TUN-8789: make python package installation consistent\n- 2024-12-06 TUN-8781: Add Trixie, drop Buster. Default to Bookworm\n- 2024-12-05 TUN-8775: Make sure the session Close can only be called once\n- 2024-12-04 TUN-8725: implement diagnostic procedure\n- 2024-12-04 TUN-8767: include raw output from network collector in diagnostic zipfile\n- 2024-12-04 TUN-8770: add cli configuration and tunnel configuration to diagnostic zipfile\n- 2024-12-04 TUN-8768: add job report to diagnostic zipfile\n- 2024-12-03 TUN-8726: implement compression routine to be used in diagnostic procedure\n- 2024-12-03 TUN-8732: implement port selection algorithm\n- 2024-12-03 TUN-8762: fix argument order when invoking tracert and modify network info output parsing.\n- 2024-12-03 TUN-8769: fix k8s log collector arguments\n- 2024-12-03 TUN-8727: extend client to include function to get cli configuration and tunnel configuration\n- 2024-11-29 TUN-8729: implement network collection for diagnostic procedure\n- 2024-11-29 TUN-8727: implement metrics, runtime, system, and tunnelstate in diagnostic http client\n- 2024-11-27 TUN-8733: add log collection for docker\n- 2024-11-27 TUN-8734: add log collection for kubernetes\n- 2024-11-27 TUN-8640: Refactor ICMPRouter to support new ICMPResponders\n- 2024-11-26 TUN-8735: add managed/local log collection\n- 2024-11-25 TUN-8728: implement diag/tunnel endpoint\n- 2024-11-25 TUN-8730: implement diag/configuration\n- 2024-11-22 TUN-8737: update metrics server port selection\n- 2024-11-22 TUN-8731: Implement diag/system endpoint\n- 2024-11-21 TUN-8748: Migrated datagram V3 flows to use migrated context\n\n2024.11.1\n- 2024-11-18 Add cloudflared tunnel ready command\n- 2024-11-14 Make metrics a requirement for tunnel ready command\n- 2024-11-12 TUN-8701:  Simplify flow registration logs for datagram v3\n- 2024-11-11 add: new go-fuzz targets\n- 2024-11-07 TUN-8701: Add metrics and adjust logs for datagram v3\n- 2024-11-06 TUN-8709: Add session migration for datagram v3\n- 2024-11-04 Fixed 404 in README.md to TryCloudflare\n- 2024-09-24 Update semgrep.yml\n\n2024.11.0\n- 2024-11-05 VULN-66059: remove ssh server tests\n- 2024-11-04 TUN-8700: Add datagram v3 muxer\n- 2024-11-04 TUN-8646: Allow experimental feature support for datagram v3\n- 2024-11-04 TUN-8641: Expose methods to simplify V3 Datagram parsing on the edge\n- 2024-10-31 TUN-8708: Bump python min version to 3.10\n- 2024-10-31 TUN-8667: Add datagram v3 session manager\n- 2024-10-25 TUN-8692: remove dashes from session id\n- 2024-10-24 TUN-8694: Rework release script\n- 2024-10-24 TUN-8661: Refactor connection methods to support future different datagram muxing methods\n- 2024-07-22 TUN-8553: Bump go to 1.22.5 and go-boring 1.22.5-1\n\n2024.10.1\n- 2024-10-23 TUN-8694: Fix github release script\n- 2024-10-21 Revert \"TUN-8592: Use metadata from the edge to determine if request body is empty for QUIC transport\"\n- 2024-10-18 TUN-8688: Correct UDP bind for IPv6 edge connectivity on macOS\n- 2024-10-17 TUN-8685: Bump coredns dependency\n- 2024-10-16 TUN-8638: Add datagram v3 serializers and deserializers\n- 2024-10-15 chore: Remove h2mux code\n- 2024-10-11 TUN-8631: Abort release on version mismatch\n\n2024.10.0\n- 2024-10-01 TUN-8646: Add datagram v3 support feature flag\n- 2024-09-30 TUN-8621: Fix cloudflared version in change notes to account for release date\n- 2024-09-19 Adding semgrep yaml file\n- 2024-09-12 TUN-8632: Delay checking auto-update by the provided frequency\n- 2024-09-11 TUN-8630: Check checksum of downloaded binary to compare to current for auto-updating\n- 2024-09-09 TUN-8629: Cloudflared update on Windows requires running it twice to update\n- 2024-09-06 PPIP-2310: Update quick tunnel disclaimer\n- 2024-08-30 TUN-8621: Prevent QUIC connection from closing before grace period after unregistering\n- 2024-08-09 TUN-8592: Use metadata from the edge to determine if request body is empty for QUIC transport\n- 2024-06-26 TUN-8484: Print response when QuickTunnel can't be unmarshalled\n\n2024.9.1\n- 2024-09-10 Revert Release 2024.9.0\n\n2024.9.0\n- 2024-09-10 TUN-8621: Fix cloudflared version in change notes.\n- 2024-09-06 PPIP-2310: Update quick tunnel disclaimer\n- 2024-08-30 TUN-8621: Prevent QUIC connection from closing before grace period after unregistering\n- 2024-08-09 TUN-8592: Use metadata from the edge to determine if request body is empty for QUIC transport\n- 2024-06-26 TUN-8484: Print response when QuickTunnel can't be unmarshalled\n\n2024.8.3\n- 2024-08-15 TUN-8591 login command without extra text\n- 2024-03-25 remove code that will not be executed\n- 2024-03-25 remove code that will not be executed\n\n2024.8.2\n- 2024-08-05 TUN-8583: change final directory of artifacts\n- 2024-08-05 TUN-8585: Avoid creating GH client when dry-run is true\n\n2024.7.3\n- 2024-07-31 TUN-8546: Fix final artifacts paths\n\n2024.7.2\n- 2024-07-17 TUN-8546: rework MacOS build script\n\n2024.7.1\n- 2024-07-16 TUN-8543: use -p flag to create intermediate directories\n\n2024.7.0\n- 2024-07-05 TUN-8520: add macos arm64 build\n- 2024-07-05 TUN-8523: refactor makefile and cfsetup\n- 2024-07-02 TUN-8504: Use pre-installed python version instead of downloading it on Windows builds\n- 2024-06-26 TUN-8489: Add default noop logger for capnprpc\n- 2024-06-25 TUN-8487: Add user-agent for quick-tunnel requests\n- 2023-12-12 TUN-8057: cloudflared uses new PQ curve ID\n\n2024.6.1\n- 2024-06-12 TUN-8461: Don't log Failed to send session payload if the error is EOF\n- 2024-06-07 TUN-8456: Update quic-go to 0.45 and collect mtu and congestion control metrics\n- 2024-06-06 TUN-8452: Add flag to control QUIC stream-level flow control limit\n- 2024-06-06 TUN-8451: Log QUIC flow control frames and transport parameters received\n- 2024-06-05 TUN-8449: Add flag to control QUIC connection-level flow control limit and increase default to 30MB\n\n2024.6.0\n- 2024-05-30 TUN-8441: Correct UDP total sessions metric to a counter and add new ICMP metrics\n- 2024-05-28 TUN-8422: Add metrics for capnp method calls\n- 2024-05-24 TUN-8424: Refactor capnp registration server\n- 2024-05-23 TUN-8427: Fix BackoffHandler's internally shared clock structure\n- 2024-05-21 TUN-8425: Remove ICMP binding for quick tunnels\n- 2024-05-20 TUN-8423: Deprecate older legacy tunnel capnp interfaces\n- 2024-05-15 TUN-8419: Add capnp safe transport\n- 2024-05-13 TUN-8415: Refactor capnp rpc into a single module\n\n2024.5.0\n- 2024-05-07 TUN-8407: Upgrade go to version 1.22.2\n\n2024.4.1\n- 2024-04-22 TUN-8380: Add sleep before requesting quick tunnel as temporary fix for component tests\n- 2024-04-19 TUN-8374: Close UDP socket if registration fails\n- 2024-04-18 TUN-8371: Bump quic-go to v0.42.0\n- 2024-04-03 TUN-8333: Bump go-jose dependency to v4\n- 2024-04-02 TUN-8331: Add unit testing for AccessJWTValidator middleware\n\n2024.4.0\n- 2024-04-02 feat: provide short version (#1206)\n- 2024-04-02 Format code\n- 2024-01-18 feat: auto tls sni\n- 2023-12-24 fix checkInPingGroup bugs\n- 2023-12-15 Add environment variables for TCP tunnel hostname / destination / URL.\n\n2024.3.0\n- 2024-03-14 TUN-8281: Run cloudflared query list tunnels/routes endpoint in a paginated way\n- 2024-03-13 TUN-8297: Improve write timeout logging on safe_stream.go\n- 2024-03-07 TUN-8290: Remove `|| true` from postrm.sh\n- 2024-03-05 TUN-8275: Skip write timeout log on \"no network activity\"\n- 2024-01-23 Update postrm.sh to fix incomplete uninstall\n- 2024-01-05 fix typo in errcheck for response parsing logic in CreateTunnel routine\n- 2023-12-23 Update linux_service.go\n- 2023-12-07 ci: bump actions/checkout to v4\n- 2023-12-07 ci/check: bump actions/setup-go to v5\n- 2023-04-28 check.yaml: bump actions/setup-go to v4\n\n2024.2.1\n- 2024-02-20 TUN-8242: Update Changes.md file with new remote diagnostics behaviour\n- 2024-02-19 TUN-8238: Fix type mismatch introduced by fast-forward\n- 2024-02-16 TUN-8243: Collect metrics on the number of QUIC frames sent/received\n- 2024-02-15 TUN-8238: Refactor proxy logging\n- 2024-02-14 TUN-8242: Enable remote diagnostics by default\n- 2024-02-12 TUN-8236: Add write timeout to quic and tcp connections\n- 2024-02-09 TUN-8224: Fix safety of TCP stream logging, separate connect and ack log messages\n\n2024.2.0\n- 2024-02-07 TUN-8224: Count and collect metrics on stream connect successes/errors\n\n2024.1.5\n- 2024-01-22 TUN-8176: Support ARM platforms that don't have an FPU or have it enabled in kernel\n- 2024-01-15 TUN-8158: Bring back commit e6537418859afcac29e56a39daa08bcabc09e048 and fixes infinite loop on linux when the socket is closed\n\n2024.1.4\n- 2024-01-19 Revert \"TUN-8158: Add logging to confirm when ICMP reply is returned to the edge\"\n\n2024.1.3\n- 2024-01-15 TUN-8161: Fix broken ARM build for armv6\n- 2024-01-15 TUN-8158: Add logging to confirm when ICMP reply is returned to the edge\n\n2024.1.2\n- 2024-01-11 TUN-8147: Disable ECN usage due to bugs in detecting if supported\n- 2024-01-11 TUN-8146: Fix export path for install-go command\n- 2024-01-11 TUN-8146: Fix Makefile targets should not be run in parallel and install-go script was missing shebang\n- 2024-01-10 TUN-8140: Remove homebrew scripts\n\n2024.1.1\n- 2024-01-10 TUN-8134: Revert installed prefix to /usr\n- 2024-01-09 TUN-8130: Fix path to install go for mac build\n- 2024-01-09 TUN-8129: Use the same build command between branch and release builds\n- 2024-01-09 TUN-8130: Install go tool chain in /tmp on build agents\n- 2024-01-09 TUN-8134: Install cloudflare go as part of make install\n- 2024-01-08 TUN-8118: Disable FIPS module to build with go-boring without CGO_ENABLED\n\n2024.1.0\n- 2024-01-01 TUN-7934: Update quic-go to a version that queues datagrams for better throughput and drops large datagram\n- 2023-12-20 TUN-8072: Need to set GOCACHE in mac go installation script\n- 2023-12-17 TUN-8072: Add script to download cloudflare go for Mac build agents\n- 2023-12-15 Fix nil pointer dereference segfault when passing \"null\" config json to cloudflared tunnel ingress validate (#1070)\n- 2023-12-15 configuration.go: fix developerPortal link (#960)\n- 2023-12-14 tunnelrpc/pogs: fix dropped test errors (#1106)\n- 2023-12-14 cmd/cloudflared/updater: fix dropped error (#1055)\n- 2023-12-14 use os.Executable to discover the path to cloudflared (#1040)\n- 2023-12-14 Remove extraneous `period` from Path Environment Variable (#1009)\n- 2023-12-14 Use CLI context when running tunnel (#597)\n- 2023-12-14 TUN-8066: Define scripts to build on Windows agents\n- 2023-12-11 TUN-8052: Update go to 1.21.5\n- 2023-12-07 TUN-7970: Default to enable post quantum encryption for quic transport\n- 2023-12-04 TUN-8006: Update quic-go to latest upstream\n- 2023-11-15 VULN-44842 Add a flag that allows users to not send the Access JWT to stdout\n- 2023-11-13 TUN-7965: Remove legacy incident status page check\n- 2023-11-13 AUTH-5682 Org token flow in Access logins should pass CF_AppSession cookie\n\n2023.10.0\n- 2023-10-06 TUN-7864: Document cloudflared versions support\n- 2023-10-03 CUSTESC-33731: Make rule match test report rule in 0-index base\n- 2023-09-22 TUN-7824: Fix usage of systemctl status to detect which services are installed\n- 2023-09-20 TUN-7813: Improve tunnel delete command to use cascade delete\n- 2023-09-20 TUN-7787: cloudflared only list ip routes targeted for cfd_tunnel\n- 2023-09-15 TUN-7787: Refactor cloudflared to use new route endpoints based on route IDs\n- 2023-09-08 TUN-7776: Remove warp-routing flag from cloudflared\n- 2023-09-05 TUN-7756: Clarify that QUIC is mandatory to support ICMP proxying\n\n2023.8.2\n- 2023-08-25 TUN-7700: Implement feature selector to determine if connections will prefer post quantum cryptography\n- 2023-08-22 TUN-7707: Use X25519Kyber768Draft00 curve when post-quantum feature is enabled\n\n2023.8.1\n- 2023-08-23 TUN-7718: Update R2 Token to no longer encode secret\n\n2023.8.0\n- 2023-07-26 TUN-7584: Bump go 1.20.6\n\n2023.7.3\n- 2023-07-25 TUN-7628: Correct Host parsing for Access\n- 2023-07-24 TUN-7624: Fix flaky TestBackoffGracePeriod test in cloudflared\n\n2023.7.2\n- 2023-07-19 TUN-7599: Onboard cloudflared to Software Dashboard\n- 2023-07-19 TUN-7587: Remove junos builds\n- 2023-07-18 TUN-7597: Add flag to disable auto-update services to be installed\n- 2023-07-17 TUN-7594: Add nightly arm64 cloudflared internal deb publishes\n- 2023-07-14 TUN-7586: Upgrade go-jose/go-jose/v3 and core-os/go-oidc/v3\n- 2023-07-14 TUN-7589: Remove legacy golang.org/x/crypto/ssh/terminal package usage\n- 2023-07-14 TUN-7590: Remove usages of ioutil\n- 2023-07-14 TUN-7585: Remove h2mux compression\n- 2023-07-14 TUN-7588: Update package coreos/go-systemd\n\n2023.7.1\n- 2023-07-13 TUN-7582: Correct changelog wording for --management-diagnostics\n- 2023-07-12 TUN-7575: Add option to disable PTMU discovery over QUIC\n\n2023.7.0\n- 2023-07-06 TUN-7558: Flush on Writes for StreamBasedOriginProxy\n- 2023-07-05 TUN-7553: Add flag to enable management diagnostic services\n- 2023-07-05 TUN-7564: Support cf-trace-id for cloudflared access\n- 2023-07-05 TUN-7477: Decrement UDP sessions on shutdown\n- 2023-07-03 TUN-7545: Add support for full bidirectionally streaming with close signal propagation\n- 2023-06-30 TUN-7549: Add metrics route to management service\n- 2023-06-30 TUN-7551: Complete removal of raven-go to sentry-go\n- 2023-06-30 TUN-7550: Add pprof endpoint to management service\n- 2023-06-29 TUN-7543: Add --debug-stream flag to cloudflared access ssh\n- 2023-06-26 TUN-6011: Remove docker networks from ICMP Proxy test\n- 2023-06-20 AUTH-5328 Pass cloudflared_token_check param when running cloudflared access login\n\n2023.6.1\n- 2023-06-19 TUN-7480: Added a timeout for unregisterUDP.\n- 2023-06-16 TUN-7477: Add UDP/TCP session metrics\n- 2023-06-14 TUN-7468: Increase the limit of incoming streams\n\n2023.6.0\n- 2023-06-15 TUN-7471: Fixes cloudflared not closing the quic stream on unregister UDP session\n- 2023-06-09 TUN-7463: Add default ingress rule if no ingress rules are provided when updating the configuration\n- 2023-05-31 TUN-7447: Add a cover build to report code coverage\n\n2023.5.1\n- 2023-05-16 TUN-7424: Add CORS headers to host_details responses\n- 2023-05-11 TUN-7421: Add *.cloudflare.com to permitted Origins for management WebSocket requests\n- 2023-05-05 TUN-7404: Default configuration version set to -1\n- 2023-05-05 TUN-7227: Migrate to devincarr/quic-go\n\n2023.5.0\n- 2023-04-27 TUN-7398: Add support for quic safe stream to set deadline\n- 2023-04-26 TUN-7394: Retry StartFirstTunnel on quic.ApplicationErrors\n- 2023-04-26 TUN-7392: Ignore release checksum upload if asset already uploaded\n- 2023-04-25 TUN-7392: Ignore duplicate artifact uploads for github release\n- 2023-04-25 TUN-7393: Add json output for cloudflared tail\n- 2023-04-24 TUN-7390: Remove Debian stretch builds\n\n2023.4.2\n- 2023-04-24 TUN-7133: Add sampling support for streaming logs\n- 2023-04-21 TUN-7141: Add component tests for streaming logs\n- 2023-04-21 TUN-7373: Streaming logs override for same actor\n- 2023-04-20 TUN-7383: Bump requirements.txt\n- 2023-04-19 TUN-7361: Add a label to override hostname\n- 2023-04-19 TUN-7378: Remove RPC debug logs\n- 2023-04-18 TUN-7360: Add Get Host Details handler in management service\n- 2023-04-17 AUTH-3122 Verify that Access tokens are still valid in curl command\n- 2023-04-17 TUN-7129: Categorize TCP logs for streaming logs\n- 2023-04-17 TUN-7130: Categorize UDP logs for streaming logs\n- 2023-04-10 AUTH-4887 Add aud parameter to token transfer url\n\n2023.4.1\n- 2023-04-13 TUN-7368: Report destination address for TCP requests in logs\n- 2023-04-12 TUN-7134: Acquire token for cloudflared tail\n- 2023-04-12 TUN-7131: Add cloudflared log event to connection messages and enable streaming logs\n- 2023-04-11 TUN-7132 TUN-7136: Add filter support for streaming logs\n- 2023-04-06 TUN-7354: Don't warn for empty ingress rules when using --token\n- 2023-04-06 TUN-7128: Categorize logs from public hostname locations\n- 2023-04-06 TUN-7351: Add streaming logs session ping and timeout\n- 2023-04-06 TUN-7335: Fix cloudflared update not working in windows\n\n2023.4.0\n- 2023-04-07 TUN-7356: Bump golang.org/x/net package to 0.7.0\n- 2023-04-07 TUN-7357: Bump to go 1.19.6\n- 2023-04-06 TUN-7127: Disconnect logger level requirement for management\n- 2023-04-05 TUN-7332: Remove legacy tunnel force flag\n- 2023-04-05 TUN-7135: Add cloudflared tail\n- 2023-04-04 Add suport for OpenBSD (#916)\n- 2023-04-04 Fix typo (#918)\n- 2023-04-04 TUN-7125: Add management streaming logs WebSocket protocol\n- 2023-03-30 TUN-9999: Remove classic tunnel component tests\n- 2023-03-30 TUN-7126: Add Management logger io.Writer\n- 2023-03-29 TUN-7324: Add http.Hijacker to connection.ResponseWriter\n- 2023-03-29 TUN-7333: Default features checkable at runtime across all packages\n- 2023-03-21 TUN-7124: Add intercept ingress rule for management requests\n\n2023.3.1\n- 2023-03-13 TUN-7271: Return 503 status code when no ingress rules configured\n- 2023-03-10 TUN-7272: Fix cloudflared returning non supported status service which breaks configuration migration\n- 2023-03-09 TUN-7259: Add warning for missing ingress rules\n- 2023-03-09 TUN-7268: Default to Program Files as location for win32\n- 2023-03-07 TUN-7252: Remove h2mux connection\n- 2023-03-07 TUN-7253: Adopt http.ResponseWriter for connection.ResponseWriter\n- 2023-03-06 TUN-7245: Add bastion flag to origin service check\n- 2023-03-06 EDGESTORE-108: Remove deprecated s3v2 signature\n- 2023-03-02 TUN-7226: Fixed a missed rename\n\n2023.3.0\n- 2023-03-01 GH-352: Add Tunnel CLI option \"edge-bind-address\" (#870)\n- 2023-03-01 Fixed WIX template to allow MSI upgrades (#838)\n- 2023-02-28 TUN-7213: Decode Base64 encoded key before writing it\n- 2023-02-28 check.yaml: update actions to v3 (#876)\n- 2023-02-27 TUN-7213: Debug homebrew-cloudflare  build\n- 2023-02-15 RTG-2476 Add qtls override for Go 1.20\n\n2023.2.2\n- 2023-02-22 TUN-7197: Add connIndex tag to debug messages of incoming requests\n- 2023-02-08 TUN-7167: Respect protocol overrides with --token\n- 2023-02-06 TUN-7065: Remove classic tunnel creation\n- 2023-02-06 TUN-6938: Force h2mux protocol to http2 for named tunnels\n- 2023-02-06 TUN-6938: Provide QUIC as first in protocol list\n- 2023-02-03 TUN-7158: Correct TCP tracing propagation\n- 2023-02-01 TUN-7151: Update changes file with latest release notices\n\n2023.2.1\n- 2023-02-01 TUN-7065: Revert Ingress Rule check for named tunnel configurations\n- 2023-02-01 Revert \"TUN-7065: Revert Ingress Rule check for named tunnel configurations\"\n- 2023-02-01 Revert \"TUN-7065: Remove classic tunnel creation\"\n2023.1.0\n- 2023-01-10 TUN-7064: RPM digests are now sha256 instead of md5sum\n- 2023-01-04 RTG-2418 Update qtls\n- 2022-12-24 TUN-7057: Remove dependency github.com/gorilla/mux\n- 2022-12-24 TUN-6724: Migrate to sentry-go from raven-go\n\n2022.12.1\n- 2022-12-20 TUN-7021: Fix proxy-dns not starting when cloudflared tunnel is run\n- 2022-12-15 TUN-7010: Changelog for release 2022.12.0\n\n2022.12.0\n- 2022-12-14 TUN-6999: cloudflared should attempt other edge addresses before falling back on protocol\n- 2022-12-13 TUN-7004: Dont show local config dirs for remotely configured tuns\n- 2022-12-12 TUN-7003: Tempoarily disable erroneous notarize-app\n- 2022-12-12 TUN-7003: Add back a missing fi\n- 2022-12-07 TUN-7000: Reduce metric cardinality of closedConnections metric by removing error as tag\n- 2022-12-07 TUN-6994: Improve logging config file not found\n- 2022-12-07 TUN-7002: Randomise first region selection\n- 2022-12-07 TUN-6995: Disable quick-tunnels spin up by default\n- 2022-12-05 TUN-6984: Add bash set x to improve visibility during builds\n- 2022-12-05 TUN-6984: [CI] Ignore security import errors for code_sigining\n- 2022-12-05 TUN-6984: [CI] Don't fail on unset.\n- 2022-11-30 TUN-6984: Set euo pipefile for homebrew builds\n\n2022.11.1\n- 2022-11-29 TUN-6981: We should close UDP socket if failed to connecto to edge\n- 2022-11-25 CUSTESC-23757: Fix a bug where a wildcard ingress rule would match an host without starting with a dot\n- 2022-11-24 TUN-6970: Print newline when printing tunnel token\n- 2022-11-22 TUN-6963: Refactor Metrics service setup\n2022.11.0\n- 2022-11-16 Revert \"TUN-6935: Cloudflared should use APIToken instead of serviceKey\"\n- 2022-11-16 TUN-6929: Use same protocol for other connections as first one\n- 2022-11-14 TUN-6941: Reduce log level to debug when failing to proxy ICMP reply\n- 2022-11-14 TUN-6935: Cloudflared should use APIToken instead of serviceKey\n- 2022-11-14 TUN-6935: Cloudflared should use APIToken instead of serviceKey\n- 2022-11-11 TUN-6937: Bump golang.org/x/* packages to new release tags\n- 2022-11-10 ZTC-234: macOS tests\n- 2022-11-09 TUN-6927: Refactor validate access configuration to allow empty audTags only\n- 2022-11-08 ZTC-234: Replace ICMP funnels when ingress connection changes\n- 2022-11-04 TUN-6917: Bump go to 1.19.3\n- 2022-11-02 Issue #574: Better ssh config for short-lived cert (#763)\n- 2022-10-28 TUN-6898: Fix bug handling IPv6 based ingresses with missing port\n- 2022-10-28 TUN-6898: Refactor addPortIfMissing\n2022.10.3\n- 2022-10-24 TUN-6871: Add default feature to cloudflared to support EOF on QUIC connections\n- 2022-10-19 TUN-6876: Fix flaky TestTraceICMPRouterEcho by taking account request span can return before reply\n- 2022-10-18 TUN-6867: Clear spans right after they are serialized to avoid returning duplicate spans\n2022.10.2\n- 2022-10-18 TUN-6869: Fix Makefile complaining about missing GO packages\n- 2022-10-18 TUN-6864: Don't reuse port in quic unit tests\n- 2022-10-18 TUN-6868: Return left padded tracing ID when tracing identity is converted to string\n\n2022.10.1\n- 2022-10-16 TUN-6861: Trace ICMP on Windows\n- 2022-10-15 TUN-6860: Send access configuration keys to the edge\n- 2022-10-14 TUN-6858: Trace ICMP reply\n- 2022-10-13 TUN-6855: Add DatagramV2Type for IP packet with trace and tracing spans\n- 2022-10-13 TUN-6856: Refactor to lay foundation for tracing ICMP\n- 2022-10-13 TUN-6604: Trace icmp echo request on Linux and Darwin\n- 2022-10-12 Fix log message (#591)\n- 2022-10-12 TUN-6853: Reuse source port when connecting to the edge for quic connections\n- 2022-10-11 TUN-6829: Allow user of datagramsession to control logging level of errors\n- 2022-10-10 RTG-2276 Update qtls and go mod tidy\n- 2022-10-05 Add post-quantum flag to quick tunnel\n- 2022-10-05 TUN-6823: Update github release message to pull from KV\n- 2022-10-04 TUN-6825: Fix cloudflared:version images require arch hyphens\n- 2022-10-03 TUN-6806: Add ingress rule number to log when filtering due to middlware handler\n- 2022-08-17 Label correct container\n- 2022-08-16 Fix typo in help text for `cloudflared tunnel route lb`\n- 2022-07-18 drop usage of cat when sed is invoked to generate the manpage\n- 2021-03-15 update-build-readme\n- 2021-03-15 fix link\n\n2022.10.0\n- 2022-09-30 TUN-6755: Remove unused publish functions\n- 2022-09-30 TUN-6813: Only proxy ICMP packets when warp-routing is enabled\n- 2022-09-29 TUN-6811: Ping group range should be parsed as int32\n- 2022-09-29 TUN-6812: Drop IP packets if ICMP proxy is not initialized\n- 2022-09-28 TUN-6716: Document limitation of Windows ICMP proxy\n- 2022-09-28 TUN-6810: Add component test for post-quantum\n- 2022-09-27 TUN-6715: Provide suggestion to add cloudflared to ping_group_range if it failed to open ICMP socket\n- 2022-09-22 TUN-6792: Fix brew core release by not auditing the formula\n- 2022-09-22 TUN-6774: Validate OriginRequest.Access to add Ingress.Middleware\n- 2022-09-22 TUN-6775: Add middleware.Handler verification to ProxyHTTP\n- 2022-09-22 TUN-6791: Calculate ICMPv6 checksum\n- 2022-09-22 TUN-6801: Add punycode alternatives for ingress rules\n- 2022-09-21 TUN-6772: Add a JWT Validator as an ingress verifier\n- 2022-09-21 TUN-6772: Add a JWT Validator as an ingress verifier\n- 2022-09-21 TUN-6774: Validate OriginRequest.Access to add Ingress.Middleware\n- 2022-09-21 TUN-6772: Add a JWT Validator as an ingress verifier\n- 2022-09-20 TUN-6741: ICMP proxy tries to listen on specific IPv4 & IPv6 when possible\n2022.9.1\n- 2022-09-20 TUN-6777: Fix race condition in TestFunnelIdleTimeout\n- 2022-09-20 TUN-6595: Enable datagramv2 and icmp proxy by default\n- 2022-09-20 TUN-6773: Add access based configuration to ingress.OriginRequestConfig\n- 2022-09-19 TUN-6778: Cleanup logs about ICMP\n- 2022-09-19 TUN-6779: cloudflared should also use the root CAs from system pool to validate edge certificate\n- 2022-09-19 TUN-6780: Add support for certReload to also include support for client certificates\n- 2022-09-16 TUN-6767: Build ICMP proxy for Windows only when CGO is enabled\n- 2022-09-15 TUN-6590: Use Windows Teamcity agent to build binary\n- 2022-09-13 TUN-6592: Decrement TTL and return ICMP time exceed if it's 0\n- 2022-09-09 TUN-6749: Fix icmp_generic build\n- 2022-09-09 TUN-6744: On posix platforms, assign unique echo ID per (src, dst, echo ID)\n- 2022-09-08 TUN-6743: Support ICMPv6 echo on Windows\n- 2022-09-08 TUN-6689: Utilize new RegisterUDPSession to begin tracing\n- 2022-09-07 TUN-6688: Update RegisterUdpSession capnproto to include trace context\n- 2022-09-06 TUN-6740: Detect no UDP packets allowed and fallback from QUIC in that case\n- 2022-09-06 TUN-6654: Support ICMPv6 on Linux and Darwin\n- 2022-09-02 TUN-6696: Refactor flow into funnel and close idle funnels\n- 2022-09-02 TUN-6718: Bump go and go-boring 1.18.6\n- 2022-08-29 TUN-6531: Implement ICMP proxy for Windows using IcmpSendEcho\n- 2022-08-24 RTG-1339 Support post-quantum hybrid key exchange\n\n2022.9.0\n- 2022-09-05 TUN-6737: Fix datagramV2Type should be declared in its own block so it starts at 0\n- 2022-09-01 TUN-6725: Fix testProxySSEAllData\n- 2022-09-01 TUN-6726: Fix maxDatagramPayloadSize for Windows QUIC datagrams\n- 2022-09-01 TUN-6729: Fix flaky TestClosePreviousProxies\n- 2022-09-01 TUN-6728: Verify http status code ingress rule\n- 2022-08-25 TUN-6695: Implement ICMP proxy for linux\n\n2022.8.4\n- 2022-08-31 TUN-6717: Update Github action to run with Go 1.19\n- 2022-08-31 TUN-6720: Remove forcibly closing connection during reconnect signal\n- 2022-08-29 Release 2022.8.3\n\n2022.8.3\n- 2022-08-26 TUN-6708: Fix replace flow logic\n- 2022-08-25 TUN-6705: Tunnel should retry connections forever\n- 2022-08-25 TUN-6704: Honor protocol flag when edge discovery is unreachable\n- 2022-08-25 TUN-6699: Add metric for packet too big dropped\n- 2022-08-24 TUN-6691: Properly error check for net.ErrClosed\n- 2022-08-22 TUN-6679: Allow client side of quic request to close body\n- 2022-08-22 TUN-6586: Change ICMP proxy to only build for Darwin and use echo ID to track flows\n- 2022-08-18 TUN-6530: Implement ICMPv4 proxy\n- 2022-08-17 TUN-6666: Define packet package\n- 2022-08-17 TUN-6667: DatagramMuxerV2 provides a method to receive RawPacket\n- 2022-08-16 TUN-6657: Ask for Tunnel ID and Configuration on Bug Report\n- 2022-08-16 TUN-6676: Add suport for trailers in http2 connections\n- 2022-08-11 TUN-6575: Consume cf-trace-id from incoming http2 TCP requests\n\n2022.8.2\n- 2022-08-16 TUN-6656: Docker for arm64 should not be deployed in an amd64 container\n\n2022.8.1\n- 2022-08-15 TUN-6617: Updated CHANGES.md for protocol stickiness\n- 2022-08-12 EDGEPLAT-3918: bump go and go-boring to 1.18.5\n- 2022-08-12 TUN-6652: Publish dockerfile for both amd64 and arm64\n- 2022-08-11 TUN-6617: Dont fallback to http2 if QUIC conn was successful.\n- 2022-08-11 TUN-6617: Dont fallback to http2 if QUIC conn was successful.\n- 2022-08-11 Revert \"TUN-6617: Dont fallback to http2 if QUIC conn was successful.\"\n- 2022-08-11 TUN-6617: Dont fallback to http2 if QUIC conn was successful.\n- 2022-08-01 TUN-6584: Define QUIC datagram v2 format to support proxying IP packets\n\n2022.8.0\n- 2022-08-10 TUN-6637: Upgrade quic-go\n- 2022-08-10 TUN-6646: Add support to SafeStreamCloser to close only write side of stream\n- 2022-08-09 TUN-6642: Fix unexpected close of quic stream triggered by upstream origin close\n- 2022-08-09 TUN-6639: Validate cyclic ingress configuration\n- 2022-08-08 TUN-6637: Upgrade go version and quic-go\n- 2022-08-08 TUN-6639: Validate cyclic ingress configuration\n- 2022-08-04 EDGEPLAT-3918: build cloudflared for Bookworm\n- 2022-08-02 Revert \"TUN-6576: Consume cf-trace-id from incoming TCP requests to create root span\"\n- 2022-07-27 TUN-6601: Update gopkg.in/yaml.v3 references in modules\n- 2022-07-26 TUN-6576: Consume cf-trace-id from incoming TCP requests to create root span\n- 2022-07-26 TUN-6576: Consume cf-trace-id from incoming TCP requests to create root span\n- 2022-07-25 TUN-6598: Remove auto assignees on github issues\n- 2022-07-20 TUN-6583: Remove legacy --ui flag\n- 2022-07-20 cURL supports stdin and uses os pipes directly without copying\n- 2022-07-07 TUN-6517: Use QUIC stream context while proxying HTTP requests and TCP connections\n2022.7.1\n- 2022-07-06 TUN-6503: Fix transport fallback from QUIC in face of dial error \"no network activity\"\n\n2022.7.0\n- 2022-07-05 TUN-6499: Remove log that is per datagram\n- 2022-06-24 TUN-6460: Rename metric label location to edge_location\n- 2022-06-24 TUN-6459: Add cloudflared user-agent to access calls\n- 2022-06-17 TUN-6427: Differentiate between upstream request closed/canceled and failed origin requests\n- 2022-06-17 TUN-6388: Fix first tunnel connection not retrying\n- 2022-06-13 TUN-6384: Correct duplicate connection error to fetch new IP first\n- 2022-06-13 TUN-6373: Add edge-ip-version to remotely pushed configuration\n- 2022-06-07 TUN-6010: Add component tests for --edge-ip-version\n- 2022-05-20 TUN-6007: Implement new edge discovery algorithm\n- 2022-02-18 Ensure service install directories are created before writing file\n\n2022.6.3\n- 2022-06-20 TUN-6362: Add armhf support to cloudflare packaging\n\n2022.6.2\n- 2022-06-13 TUN-6381: Write error data on QUIC stream when we fail to talk to the origin; separate logging for protocol errors vs. origin errors.\n- 2022-06-17 TUN-6414: Remove go-sumtype from cloudflared build process\n- 2022-06-01 Add Http2Origin option to force HTTP/2 origin connections\n- 2022-06-02 fix ingress rules unit test\n- 2022-06-09 Update remaining OriginRequestConfig functions for Http2Origins\n- 2022-05-31 Add image source label to docker container.\n- 2022-05-10 Warp Private Network link updated\n\n2022.6.1\n- 2022-06-14 TUN-6395: Fix writing RPM repo data\n\n2022.6.0\n- 2022-06-14 Revert \"TUN-6010: Add component tests for --edge-ip-version\"\n- 2022-06-14 Revert \"TUN-6373: Add edge-ip-version to remotely pushed configuration\"\n- 2022-06-14 Revert \"TUN-6384: Correct duplicate connection error to fetch new IP first\"\n- 2022-06-14 Revert \"TUN-6007: Implement new edge discovery algorithm\"\n- 2022-06-13 TUN-6385: Don't share err between acceptStream loop and per-stream goroutines\n- 2022-06-13 TUN-6384: Correct duplicate connection error to fetch new IP first\n- 2022-06-13 TUN-6373: Add edge-ip-version to remotely pushed configuration\n- 2022-06-13 TUN-6380: Enforce connect and keep-alive timeouts for TCP connections in both WARP routing and websocket based TCP proxy.\n- 2022-06-11 Update issue templates\n- 2022-06-11 Amendment to previous PR\n- 2022-06-09 TUN-6347: Add TCP stream logs with FlowID\n- 2022-06-08 TUN-6361: Add cloudflared arm builds to pkging as well\n- 2022-06-07 TUN-6357: Add connector id to ready check endpoint\n- 2022-06-07 TUN-6010: Add component tests for --edge-ip-version\n- 2022-06-06 TUN-6191: Update quic-go to v0.27.1 and with custom patch to allow keep alive period to be configurable\n- 2022-06-03 TUN-6343: Fix QUIC->HTTP2 fallback\n- 2022-06-02 TUN-6339: Add config for IPv6 support\n- 2022-06-02 TUN-6341: Fix default config value for edge-ip-version\n- 2022-06-01 TUN-6323: Add Xenial and Trusty for Ubuntu pkging\n- 2022-05-31 TUN-6210: Add cloudflared.repo to make it easy for yum installs\n- 2022-05-30 TUN-6293: Update yaml v3 to latest hotfix\n- 2022-05-20 TUN-6007: Implement new edge discovery algorithm\n2022.5.3\n- 2022-05-30 TUN-6308: Add debug logs to see if packets are sent/received from edge\n- 2022-05-30 TUN-6301: Allow to update logger used by UDP session manager\n\n2022.5.2\n- 2022-05-23 TUN-6270: Import gpg keys from environment variables\n- 2022-05-24 TUN-6209: Improve feedback process if release_pkgs to deb and rpm fail\n- 2022-05-24 TUN-6280: Don't wrap qlog connection tracer for gatethering QUIC metrics since we're not writing qlog files.\n- 2022-05-25 TUN-6209: Sign RPM packages\n- 2022-05-25 TUN-6285: Upload pkg assets to repos when cloudflared is released.\n- 2022-05-24 TUN-6282: Upgrade golang to 1.17.10, go-boring to 1.17.9\n- 2022-05-26 TUN-6292: Debug builds for cloudflared\n- 2022-05-28 TUN-6304: Fixed some file permission issues\n- 2022-05-11 TUN-6197: Publish to brew core should not try to open the browser\n- 2022-05-12 TUN-5943: Add RPM support\n- 2022-05-18 TUN-6248: Fix panic in cloudflared during tracing when origin doesn't provide header map\n- 2022-05-18 TUN-6250: Add upstream response status code to tracing span attributes\n\n2022.5.1\n- 2022-05-06 TUN-6146: Release_pkgs is now a generic command line script\n- 2022-05-06 TUN-6185: Fix tcpOverWSOriginService not using original scheme for String representation\n- 2022-05-05 TUN-6175: Simply debian packaging by structural upload\n- 2022-05-05 TUN-5945: Added support for Ubuntu releases\n- 2022-05-04 TUN-6054: Create and upload deb packages to R2\n- 2022-05-03 TUN-6161: Set git user/email for brew core release\n- 2022-05-03 TUN-6166: Fix mocked QUIC transport for UDP proxy manager to return expected error\n- 2022-04-27 TUN-6016: Push local managed tunnels configuration to the edge\n2022.5.0\n- 2022-05-02 TUN-6158: Update golang.org/x/crypto\n- 2022-04-20 VULN-8383 Bump yaml.v2 to yaml.v3\n- 2022-04-21 TUN-6123: For a given connection with edge, close all datagram sessions through this connection when it's closed\n- 2022-04-20 TUN-6015: Add RPC method for pushing local config\n- 2022-04-21 TUN-6130: Fix vendoring due to case sensitive typo in package\n- 2022-04-27 TUN-6142: Add tunnel details support to RPC\n- 2022-04-28 TUN-6014: Add remote config flag as default feature\n- 2022-04-12 TUN-6000: Another fix for publishing to brew core\n- 2022-04-11 TUN-5990: Add otlp span export to response header\n- 2022-04-19 TUN-6070: First connection retries other edge IPs if the error is quic timeout(likely due to firewall blocking UDP)\n- 2022-04-11 TUN-6030: Add ttfb span for origin http request\n\n2022.4.1\n- 2022-04-11 TUN-6035: Reduce buffer size when proxying data\n- 2022-04-11 TUN-6038: Reduce buffer size used for proxying data\n- 2022-04-11 TUN-6043: Allow UI-managed Tunnels to fallback from QUIC but warn about that\n- 2022-04-07 TUN-6000 add version argument to bump-formula-pr\n- 2022-04-06 TUN-5989: Add in-memory otlp exporter\n\n2022.4.0\n- 2022-04-01 TUN-5973: Add backoff for non-recoverable errors as well\n- 2022-04-05 TUN-5992: Use QUIC protocol for remotely managed tunnels when protocol is unspecified\n- 2022-04-06 Update Makefile\n- 2022-04-06 TUN-5995: Update prometheus to 1.12.1 to avoid vulnerabilities\n- 2022-04-07 TUN-5995: Force prometheus v1.12.1 usage\n- 2022-04-07 TUN-4130: cloudflared docker images now have a latest tag\n- 2022-03-30 TUN-5842: Fix flaky TestConcurrentUpdateAndRead by making sure resources are released\n- 2022-03-30 carrier: fix dropped errors\n- 2022-03-25 TUN-5959: tidy go.mod\n- 2022-03-25 TUN-5958: Fix release to homebrew core\n- 2022-03-28 TUN-5960: Do not log the tunnel token or json credentials\n- 2022-03-28 TUN-5956: Add timeout to session manager APIs\n\n2022.3.4\n- 2022-03-22 TUN-5918: Clean up text in cloudflared tunnel --help\n- 2022-03-22 TUN-5895 run brew bump-formula-pr on release\n- 2022-03-22 TUN-5915: New cloudflared command to allow to retrieve the token credentials for a Tunnel\n- 2022-03-24 TUN-5933: Better messaging to help user when installing service if it is already installed\n- 2022-03-25 TUN-5954: Start cloudflared service in Linux too similarly to other OSs\n- 2022-03-14 TUN-5869: Add configuration endpoint in metrics server\n\n2022.3.3\n- 2022-03-17 TUN-5893: Start windows service on install, stop on uninstall. Previously user had to manually start the service after running 'cloudflared tunnel install' and stop the service before running uninstall command.\n- 2022-03-17 Revert \"CC-796: Remove dependency on unsupported version of go-oidc\"\n- 2022-03-18 TUN-5881: Clarify success (or lack thereof) of (un)installing cloudflared service\n- 2022-03-18 CC-796: Remove dependency on unsupported version of go-oidc\n- 2022-03-18 TUN-5907: Change notes for 2022.3.3\n\n2022.3.2\n- 2022-03-10 TUN-5833: Create constant for allow-remote-config\n- 2022-03-15 TUN-5867: Return error if service was already installed\n- 2022-03-16 TUN-5833: Send feature `allow_remote_config` if Tunnel is run with --token\n- 2022-03-08 TUN-5849: Remove configuration debug log\n- 2022-03-08 TUN-5850: Update CHANGES.md with latest releases\n- 2022-03-08 TUN-5851: Update all references to point to Apache License 2.0\n- 2022-03-07 TUN-5853 Add \"install\" make target and build package manager info into executable\n- 2022-03-08 TUN-5801: Add custom wrapper for OriginConfig for JSON serde\n- 2022-03-09 TUN-5703: Add prometheus metric for current configuration version\n- 2022-02-05 CC-796: Remove dependency on unsupported version of go-oidc\n\n2022.3.1\n- 2022-03-04 TUN-5837: Log panic recovery in http2 logic with debug level log\n- 2022-03-04  TUN-5696: HTTP/2 Configuration Update\n- 2022-03-04 TUN-5836: Avoid websocket#Stream function from crashing cloudflared with unexpected memory access\n- 2022-03-05 TUN-5836: QUIC transport no longer sets body to nil in any condition\n\n2022.3.0\n- 2022-03-02 TUN-5680: Adapt component tests for new service install based on token\n- 2022-02-21 TUN-5682: Remove name field from credentials\n- 2022-02-21 TUN-5681: Add support for running tunnel using Token\n- 2022-02-28 TUN-5824: Update updater no-update-in-shell link\n- 2022-02-28 TUN-5823: Warn about legacy flags that are ignored when ingress rules are used\n- 2022-02-28 TUN-5737: Support https protocol over unix socket origin\n- 2022-02-23 TUN-5679: Add support for service install using Tunnel Token\n\n2022.2.2\n- 2022-02-22 TUN-5754: Allow ingress validate to take plaintext option\n- 2022-02-17 TUN-5678: Cloudflared uses typed tunnel API\n\n2022.2.1\n- 2022-02-10 TUN-5184: Handle errors in bidrectional streaming (websocket#Stream) gracefully when 1 side has ended\n- 2022-02-14 Update issue templates\n- 2022-02-14 Update issue templates\n- 2022-02-11 TUN-5768: Update cloudflared license file\n- 2022-02-11 TUN-5698: Make ingress rules and warp routing dynamically configurable\n- 2022-02-14 TUN-5678: Adapt cloudflared to use new typed APIs\n- 2022-02-17 Revert \"TUN-5678: Adapt cloudflared to use new typed APIs\"\n- 2022-02-11 TUN-5697: Listen for UpdateConfiguration RPC in quic transport\n- 2022-02-04 TUN-5744: Add a test to make sure cloudflared uses scheme defined in ingress rule, not X-Forwarded-Proto header\n- 2022-02-07 TUN-5749: Refactor cloudflared to pave way for reconfigurable ingress - Split origin into supervisor and proxy packages - Create configManager to handle dynamic config\n- 2021-10-19 TUN-5184: Make sure outstanding websocket write is finished, and no more writes after shutdown\n\n2022.2.0\n- 2022-02-02 TUN-4947: Use http when talking to Unix sockets origins\n- 2022-02-02 TUN-5695: Define RPC method to update configuration\n- 2022-01-27 TUN-5621: Correctly manage QUIC stream closing\n- 2022-01-28 TUN-5702: Allow to deserialize config from JSON\n\n2022.1.3\n- 2022-01-21 TUN-5477: Unhide vnet commands\n- 2022-01-24 TUN-5669: Change network command to vnet\n- 2022-01-25 TUN-5675: Remove github.com/dgrijalva/jwt-go dependency by upgrading coredns version\n- 2022-01-27 TUN-5719: Re-attempt connection to edge with QUIC despite network error when there is no fallback\n- 2022-01-28 TUN-5724: Fix SSE streaming by guaranteeing we write everything we read\n- 2022-01-17 TUN-5547: Bump golang x/net package to fix http2 transport bugs\n- 2022-01-19 TUN-5659: Proxy UDP with zero-byte payload\n- 2021-10-22 Add X-Forwarded-Host for http proxy\n\n2022.1.2\n- 2022-01-13 TUN-5650: Fix pynacl version to 1.4.0 and pygithub version to 1.55 so release doesn't break unexpectedly\n\n2022.1.1\n- 2022-01-10 TUN-5631: Build everything with go 1.17.5\n- 2022-01-06 TUN-5623: Configure quic max datagram frame size to 1350 bytes for none Windows platforms\n\n2022.1.0\n- 2022-01-03 TUN-5612: Add support for specifying TLS min/max version\n- 2022-01-03 TUN-5612: Make tls min/max version public visible\n- 2022-01-03 TUN-5551: Internally published debian artifacts are now named just cloudflared even though they are FIPS compliant\n- 2022-01-04 TUN-5600: Close QUIC transports as soon as possible while respecting graceful shutdown\n- 2022-01-05 TUN-5616: Never fallback transport if user chooses it on purpose\n- 2022-01-05 TUN-5204: Unregister QUIC transports on disconnect\n- 2022-01-04 TUN-5600: Add coverage to component tests for various transports\n\n2021.12.4\n- 2021-12-27 TUN-5482: Refactor tunnelstore client related packages for more coherent package\n- 2021-12-27 TUN-5551: Change internally published debian package to be FIPS compliant\n- 2021-12-27 TUN-5551: Show whether the binary was built for FIPS compliance\n\n2021.12.3\n- 2021-12-22 TUN-5584: Changes for release 2021.12.2\n- 2021-12-22 TUN-5590: QUIC datagram max user payload is 1217 bytes\n- 2021-12-22 TUN-5593: Read full packet from UDP connection, even if it exceeds MTU of the transport. When packet length is greater than the MTU of the transport, we will silently drop packets (for now).\n- 2021-12-23 TUN-5597: Log session ID when session is terminated by edge\n\n2021.12.2\n- 2021-12-20 TUN-5571: Remove redundant session manager log, it's already logged in origin/tunnel.ServeQUIC\n- 2021-12-20 TUN-5570: Only log RPC server events at error level to reduce noise\n- 2021-12-14 TUN-5494: Send a RPC with terminate reason to edge if the session is closed locally\n- 2021-11-09 TUN-5551: Reintroduce FIPS compliance for linux amd64 now as separate binaries\n\n2021.12.1\n- 2021-12-16 TUN-5549: Revert \"TUN-5277: Ensure cloudflared binary is FIPS compliant on linux amd64\"\n\n2021.12.0\n- 2021-12-13 TUN-5530: Get current time from ticker\n- 2021-12-15 TUN-5544: Update CHANGES.md for next release\n- 2021-12-07 TUN-5519: Adjust URL for virtual_networks endpoint to match what we will publish\n- 2021-12-02 TUN-5488: Close session after it's idle for a period defined by registerUdpSession RPC\n- 2021-12-09 TUN-5504: Fix upload of packages to public repo\n- 2021-11-30 TUN-5481: Create abstraction for Origin UDP Connection\n- 2021-11-30 TUN-5422: Define RPC to unregister session\n- 2021-11-26 TUN-5361: Commands for managing virtual networks\n- 2021-11-29 TUN-5362: Adjust route ip commands to be aware of virtual networks\n- 2021-11-23 TUN-5301: Separate datagram multiplex and session management logic from quic connection logic\n- 2021-11-10 TUN-5405: Update net package to v0.0.0-20211109214657-ef0fda0de508\n- 2021-11-10 TUN-5408: Update quic package to v0.24.0\n- 2021-11-12 Fix typos\n- 2021-11-13 Fix for Issue #501: Unexpected User-agent insertion when tunneling http request\n- 2021-11-16 TUN-5129: Remove `-dev` suffix when computing version and Git has uncommitted changes\n- 2021-11-18 TUN-5441: Fix message about available protocols\n- 2021-11-12 TUN-5300: Define RPC to register UDP sessions\n- 2021-11-14 TUN-5299: Send/receive QUIC datagram from edge and proxy to origin as UDP\n- 2021-11-04 TUN-5387: Updated CHANGES.md for 2021.11.0\n- 2021-11-08 TUN-5368: Log connection issues with LogLevel that depends on tunnel state\n- 2021-11-09 TUN-5397: Log cloudflared output when it fails to connect tunnel\n- 2021-11-09 TUN-5277: Ensure cloudflared binary is FIPS compliant on linux amd64\n- 2021-11-08 TUN-5393: Content-length is no longer a control header for non-h2mux transports\n\n2021.11.0\n- 2021-11-03 TUN-5285: Fallback to HTTP2 immediately if connection times out with no network activity\n- 2021-09-29 Add flag to 'tunnel create' subcommand to specify a base64-encoded secret\n\n2021.10.5\n- 2021-10-25 Update change log for release 2021.10.4\n- 2021-10-25 Revert \"TUN-5184: Make sure outstanding websocket write is finished, and no more writes after shutdown\"\n\n2021.10.4\n- 2021-10-21 TUN-5287: Fix misuse of wait group in TestQUICServer that caused the test to exit immediately\n- 2021-10-21 TUN-5286: Upgrade crypto/ssh package to fix CVE-2020-29652\n- 2021-10-18 TUN-5262: Allow to configure max fetch size for listing queries\n- 2021-10-19 TUN-5262: Improvements to `max-fetch-size` that allow to deal with large number of tunnels in account\n- 2021-10-15 TUN-5261: Collect QUIC metrics about RTT, packets and bytes transfered and log events at tracing level\n- 2021-10-19 TUN-5184: Make sure outstanding websocket write is finished, and no more writes after shutdown\n\n2021.10.3\n- 2021-10-14 TUN-5255: Fix potential panic if Cloudflare API fails to respond to GetTunnel(id) during delete command\n- 2021-10-14 TUN-5257: Fix more cfsetup targets that were broken by recent package changes\n\n2021.10.2\n- 2021-10-11 TUN-5138: Switch to QUIC on auto protocol based on threshold\n- 2021-10-14 TUN-5250: Add missing packages for cfsetup to succeed in github release pkgs target\n\n2021.10.1\n- 2021-10-12 TUN-5246: Use protocol: quic for Quick tunnels if one is not already set\n- 2021-10-13 TUN-5249: Revert \"TUN-5138: Switch to QUIC on auto protocol based on threshold\"\n\n2021.10.0\n- 2021-10-11 TUN-5138: Switch to QUIC on auto protocol based on threshold\n- 2021-10-07 TUN-5195: Do not set empty body if not applicable\n- 2021-10-08 UN-5213: Increase MaxStreams value for QUIC transport\n- 2021-09-28 TUN-5169: Release 2021.9.2 CHANGES.md\n- 2021-09-28 TUN-5164: Update README and clean up references to Argo Tunnel (using Cloudflare Tunnel instead)\n\n2021.9.2\n- 2021-09-21 TUN-5129: Use go 1.17 and copy .git folder to docker build to compute version\n- 2021-09-21 TUN-5128: Enforce maximum grace period\n- 2021-09-22 TUN-5141: Make sure websocket pinger returns before streaming returns\n- 2021-09-24 TUN-5142: Add asynchronous servecontrolstream for QUIC\n- 2021-09-24 TUN-5142: defer close rpcconn inside unregister instead of ServeControlStream\n- 2021-09-27 TUN-5160: Set request.ContentLength when this value is in request header\n\n2021.9.1\n- 2021-09-21 TUN-5118: Quic connection now detects duplicate connections similar to http2\n- 2021-09-15 Fix TryCloudflare link\n\n2021.9.0\n- 2021-09-02 Fix broken TryCloudflare link\n- 2021-09-03 Add support for taking named tunnel credentials from an environment variable\n- 2021-08-30 TUN-5012: Use patched go-sumtype\n- 2021-08-31 TUN-5011: Use the region parameter in fallback SRV lookup\n- 2021-08-31 TUN-5029: Do not strip cf- prefixed headers\n- 2021-08-29 TUN-5009: Updated github action to use go 1.17.x for checks\n- 2021-08-28 TUN-5010: --region should be a string flag\n- 2021-08-10 Allow building on arm64 platforms\n- 2021-06-09 Update README.md\n- 2021-05-31 🖌️ Allow providing TokenID and TokenSecret as env vars when calling cloudflared access\n- 2021-05-31 🎨 Prefix env var parameters with TUNNEL\n\n2021.8.7\n- 2021-08-28 Revert \"TUN-4926: Implement --region configuration option\"\n\n2021.8.6\n- 2021-08-27 TUN-5000: De-flake logging to dir component test in Windows by increasing to buffer to cope with more logging\n- 2021-08-27 TUN-5003: Fix cfsetup for non-FIPS golang version\n\n2021.8.5\n- 2021-08-27 TUN-4961: Update quic-go to latest\n- 2021-08-27 Release 2021.8.4\n\n2021.8.4\n- 2021-08-26 TUN-4974: Fix regression where we were debug logging by accident\n- 2021-08-26 TUN-4970: Only default to http2 for warp-routing if protocol is h2mux\n- 2021-08-26 TUN-4981: Improve readability of prepareTunnelConfig method\n- 2021-08-26 TUN-4926: Implement --region configuration option\n- 2021-07-09 TUN-4821: Make quick tunnels the default in cloudflared\n\n2021.8.3\n- 2021-08-23 TUN-4889: Add back appendtagheaders function\n- 2021-08-21 TUN-4940: Fix cloudflared not picking up correct NextProtos for quic\n- 2021-08-21 TUN-4613: Add a no-op protocol version slot\n- 2021-08-13 TUN-4922: Downgrade quic-go library to 0.20.0\n- 2021-08-17 TUN-4866: Add Control Stream for QUIC\n- 2021-08-17 TUN-4927: Parameterize region in edge discovery code\n- 2021-08-06 TUN-4602: Added UDP resolves to Edge discovery\n\n2021.8.2\n- 2021-08-03 TUN-4597: Added HTTPProxy for QUIC\n- 2021-08-04 TUN-4795: Remove Equinox releases\n- 2021-08-09 TUN-4911: Append Environment variable to Path instead of overwriting it\n\n2021.8.1\n- 2021-08-02 TUN-4855: Added CHANGES.md for release 2021.8.0\n- 2021-08-03 TUN-4597: Add a QUIC server skeleton\n- 2021-08-03 TUN-4873: Disable unix domain socket test for windows unit tests\n- 2021-08-04 TUN-4875: Added amd64-linux builds back to releases\n\n2021.8.0\n- 2021-07-30 TUN-4847: Allow to list tunnels by prefix name or exclusion prefix name\n- 2021-07-30 TUN-4772: Release built executables with packages\n- 2021-07-30 TUN-4851: Component tests to smoke test that Proxy DNS and Tunnel are only run when expected\n- 2021-07-28 TUN-4811: Publish quick tunnels' hostname in /metrics under `userHostname` for backwards-compatibility\n- 2021-07-29 TUN-4832: Prevent tunnel from running accidentally when only proxy-dns should run\n- 2021-07-28 TUN-4819: Tolerate protocol TXT record lookup failing\n\n2021.7.4\n- 2021-07-28 TUN-4814: Revert \"TUN-4699: Make quick tunnels the default in cloudflared\"\n- 2021-07-28 TUN-4812: Disable CGO for cloudflared builds\n\n2021.7.3\n- 2021-07-27 TUN-4799: Build deb, msi and rpm packages with fips\n\n2021.7.2\n- 2021-07-27 Fixed a syntax error with python logging.\n\n2021.7.1\n- 2021-07-21 TUN-4755: Add a windows msi release option to Make\n- 2021-07-22 TUN-4761: Added a build-all-packages target to cfsetup\n- 2021-07-26 TUN-4771: Upload deb, rpm and msi packages to github\n- 2021-07-14 TUN-4714: Name nightly package cloudflared-nightly to avoid apt conflict\n- 2021-07-16 TUN-4701: Split Proxy into ProxyHTTP and ProxyTCP\n- 2021-07-08 TUN-4596: Add QUIC application protocol for QUIC stream handshake\n- 2021-07-09 TUN-4699: Make quick tunnels the default in cloudflared\n\n2021.7.0\n- 2021-07-01 TUN-4626: Proxy non-stream based origin websockets with http Roundtrip.\n- 2021-07-01 TUN-4655: ingress.StreamBasedProxy.EstablishConnection takes dest input\n- 2021-07-09 TUN-4698: Add cloudflared metrics endpoint to serve quick tunnel hostname\n- 2021-06-21 TUN-4521: Modify cloudflared to use zoneless-tunnels-worker for free tunnels\n- 2021-04-05 AUTH-3475: Updated GetAppInfo error message\n\n2021.6.0\n- 2021-06-21 TUN-4571: Changelog for 2021.6.0\n- 2021-06-18 TUN-4571: Fix proxying to unix sockets when using HTTP2 transport to Cloudflare Edge\n- 2021-06-07 TUN-4502: Make `cloudflared tunnel route` subcommands described consistently\n- 2021-06-08 TUN-4504: Fix component tests in windows\n- 2021-05-27 TUN-4461: Log resulting DNS hostname if one is received from Cloudflare API\n\n2021.5.10\n- 2021-05-25 TUN-4456: Replaced instances of Tick() with Ticker() in h2mux paths\n\n2021.5.9\n- 2021-05-20 TUN-4426: Fix centos builds\n- 2021-05-20 Update changelog\n- 2021-04-30 AUTH-3426: Point to new transfer service URL and eliminate PUT /ok\n\n2021.5.8\n- 2021-05-14 TUN-4419: Improve error message when cloudflared cannot reach origin\n- 2021-05-19 TUN-4425: --overwrite-dns flag for in adhoc and route dns cmds\n\n2021.5.7\n- 2021-05-17 Fix typo in Changes.md\n- 2021-05-17 TUN-4421: Named Tunnels will automatically select the protocol to connect to Cloudflare's edge network\n\n2021.5.6\n- 2021-05-14 TUN-4418: Downgrade to Go 1.16.3\n\n2021.5.5\n\n\n2021.5.4\n- Fix release pipeline\n\n2021.5.1\n- 2021-05-10 TUN-4342: Fix false positive warning about unused hostname property\n- 2021-05-10 Release 2021.5.0\n\n2021.5.0\n- 2021-05-10 TUN-4384: Silence log from automaxprocs\n- 2021-05-10 AUTH-3537: AUDs in JWTs are now always arrays\n- 2021-05-10 Update changelog for 2021.5.0\n- 2021-05-03 TUN-4343: Fix broken build by setting debug field correctly\n- 2021-05-06 TUN-4356: Set AUTOMAXPROCS to the CPU limit when running in a Linux container\n- 2021-05-06 TUN-4357: Bump Go to 1.16\n- 2021-05-06 TUN-4359: Warn about unused keys in 'tunnel ingress validate'\n- 2021-04-30 debug: log host / path\n- 2021-04-20 AUTH-3513: Checks header for app info in case response is a 403/401 from the edge\n- 2021-04-29 TUN-4000: Release notes for cloudflared replica model\n- 2021-04-09 TUN-2853: rename STDIN-CONTROL env var to STDIN_CONTROL\n- 2021-04-09 TUN-4206: Better error message when user is only using one ingress rule\n\n2021.4.0\n- 2021-04-05 TUN-4178: Fix component test for running as a service in MacOS to not assume a named tunnel\n- 2021-04-05 TUN-4177: Running with proxy-dns should not prevent running Named Tunnels\n- 2021-04-02 TUN-4168: Transparently proxy websocket connections using stdlib HTTP client instead of gorilla/websocket; move websocket client code into carrier package since it's only used by access subcommands now (#345).\n- 2021-04-07 Publish change log for 2021.4.0\n\n2021.3.6\n- 2021-03-30 TUN-4150: Only show the connector table in 'tunnel info' if there are connectors. Don't show rows with zero connections.\n- 2021-03-31 TUN-4153: Revert best-effort HTTP2 usage when talking to origins\n- 2021-03-26 TUN-4141: Better error messages for tunnel info subcommand.\n- 2021-03-29 TUN-4146: Unhide and document grace-period\n- 2021-03-25 TUN-3863: Consolidate header handling logic in the connection package; move headers definitions from h2mux to packages that manage them; cleanup header conversions\n\n2021.3.5\n- 2021-03-26 TUN-3896: http-service and tunnelstore client use http2 transport.\n- 2021-03-25 TUN-4125: Change component tests to run in CI with its own dedicated resources\n- 2021-03-26 Publish change log for 2021.3.5\n\n2021.3.4\n\n\n2021.3.3\n- 2021-03-23 TUN-4111: Warn the user if both properties \"tunnel\" and \"hostname\" are used\n- 2021-03-23 TUN-4082: Test logging when running as a service\n- 2021-03-23 TUN-4112: Skip testing graceful shutdown with SIGINT on Windows\n- 2021-03-23 TUN-4116: Ingore credentials-file setting in configuration file during tunnel create and delete opeations.\n- 2021-03-23 TUN-4118: Don't overwrite existing file with tunnel credentials. For ad-hoc tunnels, this means tunnel won't start if there's a file in the way.\n- 2021-03-24 TUN-4123: Don't capture output in reconnect componet test\n- 2021-03-23 TUN-4067: Reformat code for consistent import order, grouping, and fix formatting. Added goimports target to the Makefile to make this easier in the future.\n- 2021-03-24 AUTH-3455: Generate short-lived ssh cert per hostname\n- 2021-03-25 Update changelog 2021.3.3\n\n2021.3.2\n- 2021-03-23 TUN-4042: Capture cloudflared output to debug component tests\n- 2021-03-23 Publish changelog for 2021.3.2\n- 2021-03-16 TUN-4089: Address flakiness in component tests for termination\n- 2021-03-16 TUN-4060: Fix Go Vet warnings (new with go 1.16) where t.Fatalf is called from a test goroutine\n- 2021-03-16 TUN-4091: Use flaky decorator to rerun reconnect component tests when they fail\n- 2021-03-12 TUN-4081: Update log severities to use Zerolog's levels\n- 2021-03-16 TUN-4094: Don't read configuration file for access commands\n- 2021-03-15 TUN-3993: New `cloudflared tunnel info` to obtain details about the active connectors for a tunnel\n- 2021-03-17 TUN-3715: Apply input source to the correct context\n- 2021-03-17 AUTH-3394: Ensure scheme on token command\n- 2021-03-18 TUN-4096: Reduce tunnel not connected assertion backoff to address flaky termination tests\n- 2021-03-19 TUN-3998: Allow to cleanup the connections of a tunnel limited to a single client\n- 2021-02-04 TUN-3715: Only read config file once, right before invoking the command\n\n2021.3.1\n- 2021-03-11 TUN-4051: Add component-tests to test graceful shutdown\n- 2021-03-12 TUN-4052: Add component tests to assert service mode behavior\n\n2021.3.0\n- 2021-03-10 TUN-4075: Dedup test should not compare order of list\n- 2021-03-10 Revert \"AUTH-3394: Creates a token per app instead of per path\"\n- 2021-03-11 TUN-4066: Remove unnecessary chmod during package publish to CF_PKG_HOSTS\n- 2021-03-11 TUN-4066: Set permissions in build agent before 'scp'-ing to machine hosting package repo\n- 2021-03-11 TUN-4050: Add component tests to assert reconnect behavior\n- 2021-03-10 AUTH-3394: Creates a token per app instead of per path - with fix for free tunnels\n- 2021-03-15 Publish change log for 2021.3.0\n- 2021-03-01 Issue #285 - Makefile does not detect TARGET_ARCH correctly on FreeBSD  (#325)\n- 2021-03-01 TUN-3988: Log why it cannot check if origin cert exists\n- 2021-03-02 TUN-3995: Optional --features flag for tunnel run.\n- 2021-03-02 TUN-3994: Log client_id when running a named tunnel\n- 2021-03-04 TUN-4026: Fix regression where HTTP2 edge transport was no longer propagating control plane errors\n- 2021-03-05 TUN-4055: Skeleton for component tests\n- 2021-03-08 TUN-4047: Add cfsetup target to run component test\n- 2021-03-08 TUN-4016: Delegate decision to update for Worker service\n- 2021-03-02 TUN-3905: Cannot run go mod vendor in cloudflared due to fips\n- 2021-03-08 TUN-4063: Cleanup dependencies between packages.\n- 2021-03-09 Allow partial reads from a GorillaConn; add SetDeadline (from net.Conn) (#330)\n- 2021-03-09 TUN-4069: Fix regression on support for websocket over proxy\n- 2021-03-02 AUTH-3394: Creates a token per app instead of per path\n- 2021-03-01 TUN-4017: Add support for using cloudflared as a full socks proxy.\n- 2021-03-08 TUN-4062: Read component tests config from yaml file\n- 2021-03-08 TUN-4049: Add component tests to assert logging behavior when running from terminal\n- 2021-02-23 TUN-3963: Repoint urfave/cli/v2 library at patched branch at github.com/ipostelnik/cli/v2@fixed which correctly handles reading flags declared at multiple levels of subcommands.\n- 2021-02-25 TUN-3970: Route ip show has alias route ip list\n- 2021-02-26 TUN-3978: Unhide teamnet commands and improve their help\n- 2021-02-26 TUN-3983: Renew CA certs in cloudflared\n- 2021-02-28 TUN-3989: Check in with Updater service in more situations and convey messages to user\n- 2021-02-11 TUN-3819: Remove client-side check that deleted tunnels have no connections\n\n2021.2.5\n- 2021-02-23 Publish change notes for 2021.2.5\n- 2021-02-11 TUN-3838: ResponseWriter no longer reads and origin error tests\n- 2021-02-10 TUN-3895: Tests for socks stream handler\n- 2021-02-19 TUN-3939: Add logging that shows that Warp-routing is enabled\n- 2021-02-02 TUN-3817: Adds tests for websocket based streaming regression\n- 2021-02-04 TUN-3799: extended the Stream interface to take a logger and added debug logs for io.Copy errors\n- 2021-02-03 TUN-3855: Add ability to override target of 'access ssh' command to a different host for testing\n- 2021-02-04 TUN-3853: Respond with ws headers from the origin service rather than generating our own\n- 2021-02-08 TUN-3889: Move host header override logic to httpService\n- 2021-02-05 TUN-3868: Refactor singleTCPService and bridgeService to tcpOverWSService and rawTCPService\n- 2021-01-21 TUN-3753: Select http2 protocol when warp routing is enabled\n- 2021-01-26 TUN-3809: Allow routes ip show to output as JSON or YAML\n- 2021-01-11 TUN-3615: added support to  proxy tcp streams\n- 2021-01-17 TUN-3725: Warp-routing is independent of ingress\n- 2021-01-15 TUN-3764: Actively flush data for TCP streams\n- 2020-12-09 TUN-3617: Separate service from client, and implement different client for http vs. tcp origins\n\n2021.2.4\n- 2021-02-22 TUN-3948: Log error when retrying connection\n- 2021-02-23 TUN-3964: Revert \"TUN-3922: Repoint urfave/cli/v2 library at patched branch at github.com/ipostelnik/cli/v2@fixed which correctly handles reading flags declared at multiple levels of subcommands.\"\n- 2021-02-23 Publish release notes for 2021.2.4\n\n2021.2.3\n- 2021-02-23 Publish release notes for 2021.2.3\n- 2021-02-10 TUN-3902: Add jitter to backoffhandler\n- 2021-02-11 TUN-3913: Help gives wrong exit code for autoupdate\n- 2021-02-12 Add max upstream connections dns-proxy option (#290)\n- 2021-02-16 TUN-3924: Removed db-connect command. Added a placeholder handler for this command that informs users that command is no longer supported.\n- 2021-02-12 TUN-3922: Repoint urfave/cli/v2 library at patched branch at github.com/ipostelnik/cli/v2@fixed which correctly handles reading flags declared at multiple levels of subcommands.\n- 2021-02-19 Added support for proxy (#318)\n- 2021-02-19 TUN-3945: Fix runApp signature for generic service\n- 2021-02-09 Update README.md\n- 2021-02-09 Update the TryCloudflare link\n\n2021.2.2\n- 2021-02-04 TUN-3864: Users can choose where credentials file is written after creating a tunnel\n- 2021-02-04 TUN-3869: Improve reliability of graceful shutdown.\n- 2021-02-07 TUN-3878: Do not supply -tags when none are specified\n- 2021-02-04 TUN-3635: Send event when unregistering tunnel for gracful shutdown so /ready endpoint reports down status befoe connections finish handling pending requests.\n- 2021-02-08 TUN-3890: Code coverage for cloudflared in CI\n- 2021-02-09 AUTH-3375 exchangeOrgToken deleted cookie fix\n- 2020-11-18 Update error message to use login command\n\n2021.2.1\n- 2021-02-04 TUN-3858: Do not suffix cloudflared version with -fips\n\n2021.2.0\n- 2021-02-01 TUN-3837: Remove automation_email from cloudflared status page test\n- 2021-02-03 TUN-3848: Use transport logger for h2mux\n- 2021-02-03 TUN-3854: cloudflared tunnel list flags to sort output\n- 2021-01-21 TUN-3195: Don't colorize console logs when stderr is not a terminal\n- 2021-01-20 Fixed connection error handling by removing duplicated errors, standardizing on non-pointer error types\n- 2021-01-20 TUN-3118: Changed graceful shutdown to immediately unregister tunnel from the edge, keep the connection open until the edge drops it or grace period expires\n- 2021-01-25 TUN-3165: Add reference to Argo Tunnel documentation in the help output\n- 2021-01-25 TUN-3806: Use a .dockerignore\n- 2021-01-21 TUN-3795: Use RFC-3339 style date format for logs, produce timestamp in UTC\n- 2021-01-26 TUN-3795: Removed errant test\n- 2021-01-25 TUN-3792: Handle graceful shutdown correctly when running as a windows service. Only expose one shutdown channel globally, which now triggers the graceful shutdown sequence across all modes. Removed separate handling of zero-duration grace period, instead it's checked only when we need to wait for exit.\n- 2021-01-27 TUN-3811: Better error reporting on http2 connection termination. Registration errors from control loop are now propagated out of the connection server code. Unified error handling between h2mux and http2 connections so we log and retry errors the same way, regardless of underlying transport.\n- 2021-01-28 TUN-3830: Use Go 1.15.7\n- 2021-01-28 TUN-3826: Use go-fips when building cloudflared for linux/amd64\n- 2021-01-19 TUN-3777: Fix /ready endpoint for classic tunnels\n- 2021-01-19 TUN-3773: Add back pprof endpoints\n\n2021.1.5\n- 2021-01-15 TUN-3594: Log ingress response at debug level\n- 2021-01-15 TUN-3765: Fix doubly nested log output by `logfile` option\n- 2021-01-16 TUN-3767: Tolerate logging errors\n- 2021-01-17 TUN-3768: Reuse file loggers\n- 2021-01-14 TUN-3738: Refactor observer to avoid potential of blocking on tunnel notifications\n- 2021-01-15 TUN-3766: Print flags defined at all levels of command hierarchy, not just locally defined flags for a command. This fixes output of overriden settings for  subcommand.\n\n2021.1.4\n- 2021-01-14 TUN-3759: Single file logging output should always append\n\n2021.1.3\n- 2021-01-14 TUN-3756: File logging output must consider the directory\n- 2021-01-14 TUN-3757: Fix legacy Uint flags that are incorrectly handled by ufarve library\n\n2021.1.2\n- 2021-01-13 TUN-3747: Fix logging in Windows\n\n2021.1.1\n- 2021-01-13 TUN-3744: Fix compilation error in windows service\n\n2021.1.0\n- 2021-01-11 TUN-3670: Update Teamnet API gateway prefixes\n- 2021-01-13 TUN-3738: Consume UI events even when UI is disabled\n- 2021-01-06 TUN-3722: Teamnet API paths include /network\n- 2021-01-05 TUN-3688: Subcommand for users to check which route an IP proxies through\n- 2021-01-08 TUN-3691: Edit Teamnet help text\n- 2020-12-30 TUN-3706: Quit if any origin service fails to start\n- 2020-12-31 TUN-3708: Better info message about system root certpool on Windows\n- 2020-12-21 TUN-3669: Teamnet commands to add/show Teamnet routes.\n- 2020-12-29 TUN-3689: Delete routes via cloudflared CLI\n- 2020-12-28 TUN-3471: Add structured log context to logs\n- 2020-12-15 TUN-3650: Remove unused awsuploader package\n- 2020-12-03 Update to add deprecated version note (#271)\n- 2020-12-02 TUN-3472: Set up rolling logger with zerolog and lumberjack\n- 2020-12-08 TUN-3607: Set up single-file logger with zerolog\n- 2020-12-03 Update to add deprecated version note (#271)\n- 2020-11-25 TUN-3470: Replace in-house logger calls with zerolog\n\n2020.12.0\n- 2020-12-04 TUN-3599: improved delete if credentials isnt found.\n- 2020-12-04 TUN-3612: Upgrade to Go 1.15.6\n- 2020-11-30 TUN-3593: /ready endpoint for k8s readiness. Move tunnel events out of UI package, into connection package.\n- 2020-11-27 TUN-3594: Log response status at debug level\n\n2020.11.11\n- 2020-11-20 TUN-3578: cloudflared tunnel route dns should allow wildcard subdomains\n- 2020-11-21 EDGEPLAT-2958 remove deb-compression, defaulting to gzip\n- 2020-11-23 TUN-3581: Tunnels can be run by name using only --credentials-file, no origin cert necessary.\n- 2020-11-15 TUN-3561: Unified logger configuration\n- 2020-11-08 AUTH-3221: Saves org token to disk and uses it to refresh the app token\n\n2020.11.10\n- 2020-11-20 TUN-3562: Fix panic when using bastion mode ingress rule\n- 2020-11-20 EDGEPLAT-2958 build cloudflared for Bullseye\n\n2020.11.9\n- 2020-11-18 TUN-3557: Detect SSE if content-type starts with text/event-stream\n- 2020-11-18 TUN-3559: Share response meta header with other packages\n- 2020-11-18 DEVTOOLS-7936: Remove redundant chgrp from publish\n- 2020-11-18 TUN-3558: cloudflared allows empty config files\n- 2020-11-18 TUN-3544: Upgrade to Go 1.15.5\n\n2020.11.8\n- 2020-11-17 TUN-3555: Single origin service should default to localhost:8080\n\n2020.11.7\n- 2020-11-13 TUN-3514: Stop setting --is-autoupdated flag after autoupdate because it can break named tunnel running in k8s\n- 2020-11-15 TUN-3548, TUN-3547: Bastion mode can be specified as a service, doesn't require URL.\n- 2020-11-16 TUN-3549: Use a separate handler for each websocket proxy\n\n2020.11.6\n- 2020-11-14 TUN-3546: Fix panic in tlsconfig.LoadOriginCA\n\n2020.11.5\n- 2020-11-12 TUN-3540: Better copy in ingress rules error messages\n- 2020-11-12 DEVTOOLS-7936: Set permissions on public packages\n- 2020-11-13 TUN-3543: ProxyAddress not using default in single-origin mode\n\n2020.11.4\n- 2020-11-11 TUN-3534: Specific error message when credentials file is a .pem not .json\n- 2020-11-02 TUN-3500: Integrate replace h2mux by http2 work with multiple origin support\n- 2020-11-09 TUN-3514: Transport logger write to UI when UI is enabled\n- 2020-10-30 TUN-3490: Make sure OriginClient implementation doesn't write after Proxy return\n- 2020-10-20 TUN-3403: Unit test for origin/proxy to test serving HTTP and Websocket\n- 2020-10-23 TUN-3480: Support SSE with http2 connection, and add SSE handler to hello-world server\n- 2020-10-27 TUN-3489: Add unit tests to cover proxy logic in connection package of cloudflared\n- 2020-10-16 TUN-3467: Serialize cf-cloudflared-response-meta during package initialization using jsoniter\n- 2020-10-14 TUN-3456: New protocol option auto to automatically select between http2 and h2mux\n- 2020-10-14 TUN-3458: Upgrade to http2 when available, fallback to h2mux when we reach max retries\n- 2020-10-08 TUN-3449: Use flag to select transport protocol implementation\n- 2020-10-08 TUN-3462: Refactor cloudflared to separate origin from connection\n- 2020-09-21 TUN-3406: Proxy websocket requests over Go http2\n- 2020-09-25 TUN-3420: Establish control plane and send RPC over control plane\n- 2020-09-11 TUN-3400: Use Go HTTP2 library as transport to connect with the edge\n\n2020.11.3\n- 2020-11-11 TUN-3533: Set config for single origin ingress\n\n2020.11.2\n\n\n2020.11.1\n- 2020-11-10 TUN-3527: More specific error for invalid YAML/JSON\n- 2020-11-06 Update README.md (#256)\n\n2020.11.0\n- 2020-11-04 TUN-3484: OriginService that responds with configured HTTP status\n- 2020-11-05 TUN-3505: Response body for status code origin returns EOF on Read\n- 2020-11-04 TUN-3503: Matching ingress rule should not take port into account\n- 2020-11-05 TUN-3506: OriginService needs to set request host and scheme for websocket requests\n- 2020-11-09 TUN-3516: Better error message when parsing invalid YAML config\n- 2020-11-09 TUN-3522: ingress validate checks that the config file exists\n- 2020-11-09 TUN-3524: Don't ignore errors from app-level action handler (#248)\n- 2020-11-09 TUN-3461: Show all origin services in the UI\n- 2020-10-30 TUN-3494: Proceed to create tunnel if at least one edge address can be resolved\n- 2020-10-30 TUN-3492: Refactor OriginService, shrink its interface\n- 2020-10-22 TUN-3478: Increase download timeout to 60s\n- 2020-10-15 TUN-2640: Users can configure per-origin config. Unify single-rule CLI flow with multi-rule config file code.\n\n2020.10.2\n- 2020-10-21 Release 2020.10.1\n- 2020-10-21 AUTH-3185 fixed indention error\n- 2020-10-19 TUN-3459: Make service install on linux use named tunnels\n\n2020.10.1\n- 2020-10-20 Split out typed config from legacy command-line switches; refactor ingress commands and fix tests\n- 2020-10-20 Move raw ingress rules to config package\n- 2020-10-21 TUN-3476: Fix conversion to string and int slice\n- 2020-10-12 TUN-3441:  Multiple-origin routing via ingress rules\n- 2020-10-15 TUN-3464: Newtype to wrap []ingress.Rule\n- 2020-10-15 TUN-3465: Use Go 1.15.3\n- 2020-10-15 TUN-3463: Let users run a named tunnel via config file setting\n- 2020-10-19 TUN-3475: Unify config file handling with typed config for new fields\n- 2020-10-19 TUN-3459: Make service install on linux use named tunnels\n- 2020-10-06 AUTH-3148 fixed cloudflared copy and match all the files in the checksum upload\n- 2020-10-06 TUN-3436, TUN-3437: Parse ingress from YAML, ensure last rule catches everything\n- 2020-10-06 TUN-3446: Use go 1.15.2 and add a step to build cloudflared in the dev Dockerfile\n- 2020-10-07 TUN-3439: 'tunnel validate' command to check ingress rules\n- 2020-10-07 TUN-3440: 'tunnel rule' command to test ingress rules\n- 2020-10-08 TUN-3451: Cloudflared tunnel ingress command\n- 2020-10-09 TUN-3452: Fix loading of flags from config file for tunnel run subcommand. This change also cleans up building of tunnel subcommand list, hides deprecated subcommands and improves help.\n- 2020-10-08 TUN-3438: move ingress into own package, read into TunnelConfig\n\n2020.10.0\n- 2020-10-02 AUTH-2993 cleaned up worker service tests\n- 2020-10-02 TUN-3443: Decode as v4api response on non-200 status\n- 2020-09-24 TRAFFIC-448: allow the user to specify the proxy address and port to bind to, falling back to 127.0.0.1 and random port if not specified\n- 2020-09-28 TUN-3427: Define a struct that only implements RegistrationServer in tunnelpogs\n- 2020-09-29 TUN-3430: Copy flags to configure proxy to run subcommand, print relevant tunnel flags in help\n- 2020-08-12 AUTH-2993 added workers updater logic\n\n2020.9.3\n- 2020-09-22 TRAFFIC-448: build cloudflare for junos and publish to s3\n- 2020-09-22 TUN-3410: Request the v1 Tunnelstore API\n- 2020-09-23 Release 2020.9.2\n- 2020-09-17 updater service exit code should be 11\n- 2020-09-18 AUTH-3109 upload the checksum to workers kv on github releases\n\n2020.9.2\n- 2020-09-22 TRAFFIC-448: build cloudflare for junos and publish to s3\n- 2020-09-22 TUN-3410: Request the v1 Tunnelstore API\n- 2020-09-17 AUTH-3103 CI build fixes\n- 2020-09-18 AUTH-3110-use-cfsetup-precache\n- 2020-09-17 TUN-3295: Show route command results\n- 2020-09-16 TUN-3291: cloudflared tunnel run -h explains how to use flags from parent command\n- 2020-09-18 AUTH-3109 upload the checksum to workers kv on github releases\n- 2020-09-17 updater service exit code should be 11\n- 2020-09-01 TUN-3216: UI improvements\n- 2020-08-25 Rebased and passed TunnelEventChan to LogServerInfo in new ReconnectTunnel function\n- 2020-08-25 TUN-3321: Add box around logs on UI\n- 2020-08-26 TUN-3328: Filter out free tunnel has started log from UI\n- 2020-08-27 TUN-3333: Add text to UI explaining how to exit\n- 2020-08-27 TUN-3335: Dynamically set connection table size for UI\n- 2020-08-10 TUN-3238: Update UI when connection re-connects\n- 2020-08-17 TUN-3261: Display connections on UI for free classic tunnels\n- 2020-07-24 TUN-3201: Create base cloudflared UI structure\n- 2020-07-29 TUN-3200: Add connection information to UI\n- 2020-07-24 TUN-3255: Update UI to display URL instead of hostname\n- 2020-07-29 TUN-3198: Handle errors while running tunnel UI\n\n2020.9.1\n- 2020-09-14 TUN-3395: Unhide named tunnel subcommands, tweak help\n- 2020-09-15 TUN-3395: Improve help for list command\n- 2020-09-14 TUN-3294: Perform basic validation on arguments of route command; remove default pool name which wasn't valid\n- 2020-09-15 TUN-3395: Improve help for list command\n- 2020-09-16 Use Go 1.15.2\n\n2020.9.0\n- 2020-09-11 TUN-3293: Try to use error information from the body of a failed tunnelstore reresponse if available\n- 2020-09-04 AUTH-2653 renabled signing\n- 2020-09-04 TUN-3377: Tunnel route should check dns/lb before checking tunnel ID\n- 2020-09-04 AUTH-2653 changed to proper file extension\n- 2020-09-04 AUTH-2653 handle duplicate key import errors\n- 2020-09-04 TUN-3345: tunnel run accepts name of tunnel as argument\n- 2020-09-08 AUTH-2653 disble error pipe to see what is failing\n- 2020-09-08 AUTH-2653 search for the certificate and not the identity\n- 2020-09-09 TUN-3284: Use cloudflared/<version> as user agent of tunnelstore client\n- 2020-09-09 TUN-3375: Upgrade x/text and gorilla websocket deps\n- 2020-09-09 TUN-3375: Upgrade coredns and prometheus dependencies\n- 2020-09-09 AUTH-2653 add notarization to mac build\n- 2020-09-08 TUN-3292: Mention cleanup in tunnel run help.\n- 2020-08-20 AUTH-2016 fixed variable fail\n- 2020-08-12 TUN-3352 extra debug logging for websockets\n\n2020.8.2\n- 2020-08-20 AUTH-3021 fixed the git version call by using the older flag\n- 2020-08-18 TUN-3268: Each connection has its own event digest to reconnect\n\n2020.8.1\n- 2020-08-14 AUTH-2975 don't check /etc on windows\n- 2020-08-14 AUTH-2977 log file protection\n- 2020-08-18 TUN-3286: Use either ID or name in Named Tunnel subcommands.\n- 2020-08-18 AUTH-2712 fixed the mac build script\n- 2020-08-19 AUTH-2653 disabling signing until we can get the keys\n- 2020-08-05 TUN-3233: List tunnels support filtering by deleted, name, existed at and id\n- 2020-08-05 TUN-3237: By default, don't show connections that are pending reconnect\n- 2020-08-06 TUN-3242: Build with go 1.14\n- 2020-08-07 TUN-3243: Refactor tunnel subcommands to allow commands to compose better\n- 2020-08-07 AUTH-2864 - add macos build to github release\n- 2020-07-31 AUTH-2857 update homebrew script to use new url\n- 2020-07-30 TUN-3213: Create, route and run named tunnels in one command\n- 2020-07-07 AUTH-2712 added MSI build for a windows agent\n\n2020.8.0\n- 2020-07-30 TUN-3220: tunnel route reports created route\n- 2020-07-31 TUN-3221: ConnectionOptions tracks numPreviousAttempts.\n- 2020-07-20 TUN-3190: Initialize logger using command line flags in tunnels subcommands\n- 2020-07-21 TUN-3192: Use zone ID in tunnelstore request path; improve debug logging\n- 2020-07-23 TUN-3194: Don't render log output when level is not enabled\n- 2020-07-22 AUTH-2016 adds sha256 hashes to releases\n- 2020-07-27 Removes centos 6 build\n- 2020-07-27 TUN-3209: Add benchmark for header serialization\n- 2020-07-24 TUN-3209: improve performance and reduce allocations during user header serialization from h1 to h2\n- 2020-07-26 TUN-3208: Add benchmark for large response write\n- 2020-07-27 TUN-3208: Reduce copies and allocations on h2mux write path. Pre-allocate 16KB write buffer on the first write if possible. Use explicit byte array for chunks on write thread to avoid copying through intermediate buffer due to io.CopyN.\n- 2020-07-28 AUTH-2714: Adds arm64 cloudflared build\n- 2020-07-29 AUTH-2927 run message update after all github builds are done\n- 2020-07-17 AUTH-2902 redirect with just the root host on curl commands\n\n2020.7.4\n- 2020-07-20 Build cloudflared for arm64 on native agents\n- 2020-07-10 TUN-3048: Handle error when user tries to delete active tunnel\n- 2020-07-14 AUTH-2890: adds error handler to cli actions\n- 2020-07-06 TUN-3156: Add route subcommand under tunnel\n\n2020.7.3\n- 2020-07-13 Change scp command to use file glob that matches both cloudflared rpms and debs\n\n2020.7.2\n- 2020-07-02 AUTH-2644: Change install location and add man page\n- 2020-07-02 TUN-3131: Allow user to specify tunnel credentials path, and remove it in tunnel delete command\n- 2020-07-03 TUN-3008: Implement cloudflared tunnel cleanup command\n- 2020-07-02 TUN-3150: cloudflared tunnel list's table should use intelligent column width\n- 2020-07-07 TUN-3169: Move on to the next address when edge returns duplicate connection. There's no point in trying to connect to the same address since it will be hashed to the same metal. Improve logging of errors from serve tunnel loop, hide useless context cancelled error.\n- 2020-07-08 beautify package meta information generated by fpm (#218)\n- 2020-07-06 AUTH-2871: fix rpm builds\n- 2020-07-08 AUTH-2858: Set file to disable autoupdate\n- 2020-07-09 AUTH-2872: Adds centos-6 build\n\n2020.7.1\n- 2020-07-02 DEVTOOLS-7321: Push GitHub homebrew updates to master\n- 2020-07-06 TUN-3161: Upgrade golang.org/x/ deps\n- 2020-06-30 AUTH-2854: Create cloudflared RPMs\n- 2020-06-26 AUTH-2850 log config file path\n\n2020.7.0\n- 2020-06-30 TUN-3140: Add timestamps to terminal log entries\n- 2020-06-30 AUTH-2860: Fix builds\n- 2020-06-25 TUN-3007: Implement named tunnel connection registration and unregistration.\n\n2020.6.6\n- 2020-06-23 AUTH-2685: Adds script to create release\n- 2020-06-25 AUTH-2652: Update cloudflare repo\n- 2020-06-26 AUTH-2718: Add target for publishing deb to pkg.cloudflare repo\n- 2020-06-26 AUTH-2849 all log output to stderr\n- 2020-06-17 TUN-3106: Pass NamedTunnel config to StartServer\n- 2020-06-18 TUN-3107: UnregisterConnection shouldn't wrap nil error as RPC error\n- 2020-06-17 AUTH-2652: Adds .docker-images to push images to docker hub\n- 2020-06-18 AUTH-2712 mac package build script and better config file handling when started as a service\n\n2020.6.5\n- 2020-06-16 DEVTOOLS-7321: Don't skip macOS builds based on tag\n- 2020-06-16 fix for a flaky test\n- 2020-06-16 AUTH-2815 flag check was wrong. stupid oversight\n- 2020-06-16 TUN-3101: Tunnel list command should only show non-deleted, by default\n- 2020-06-16 TUN-3066: Command line action for tunnel run\n- 2020-06-16 TUN-3100 make updater report the right text\n\n2020.6.4\n- 2020-06-11 TUN-3085: Pass connection authentication information using TunnelAuth struct\n- 2020-06-15 TUN-3084: Generate and store tunnel_secret value during tunnel creation\n- 2020-06-16 AUTH-2815 add the log file to support the config.yaml file\n- 2020-06-02 TUN-3015: Add a new cap'n'proto RPC interface for connection registration as well as matching client and server implementations. The old interface extends the new one for backward compatibility.\n\n2020.6.3\n- 2020-06-15 DEVTOOLS-7321: Add openssh-client pkg for missing ssh-keyscan\n- 2020-06-15 AUTH-2813 adds back a single file support a cloudflared log file\n\n2020.6.2\n- 2020-06-11 AUTH-2648 updated usage text\n- 2020-06-11 AUTH-2763 don't redirect from curl command\n- 2020-06-12 TUN-3090: Upgrade crypto dep\n- 2020-06-11 TUN-3038: Add connections to tunnel list table\n- 2020-06-12 AUTH-2810 added warn for backwards compatibility sake\n\n2020.6.1\n- 2020-06-09 AUTH-2796 fixed windows build\n\n2020.6.0\n- 2020-06-05 AUTH-2645 protect against user mistaken flag input\n- 2020-06-05 AUTH-2687 don't copy config unnecessarily\n- 2020-06-05 AUTH-2169 make access login page more generic\n- 2020-06-05 AUTH-2729 added log file and level to cmd flags to match config file settings\n- 2020-06-08 AUTH-2785 service token flag fix and logger fix\n- 2020-05-20 AUTH-2682: Create buster build\n- 2020-05-21 TUN-2928, TUN-2929, TUN-2930: Add tunnel subcommands to interact with tunnel store service\n- 2020-05-29 Adding support for multi-architecture images and binaries (#184)\n- 2020-05-29 TUN-3019: Remove declarative tunnel entry code\n- 2020-05-29 TUN-3020: Remove declarative tunnel related RPC code\n- 2020-05-13 AUTH-2505 added aliases\n- 2020-05-14 AUTH-2529 added deprecation text to db-connect command\n- 2020-05-18 AUTH-2686: Added error handling to tunnel subcommand\n- 2020-05-04 AUTH-2369: RDP Bastion prototype\n- 2020-04-29 AUTH-2596 added new logger package and replaced logrus\n- 2020-04-25 DEVTOOLS-7321: Use SSH key from env for pushing to GitHub\n- 2020-04-25 DEVTOOLS-7321: Push to a test branch instead of to master\n- 2020-03-30 DEVTOOLS-7321: Add scripts for macOS builds and homebrew uploads\n\n2020.5.1\n- 2020-05-07 TUN-2860: Enable quick reconnect feature by default\n- 2020-05-07 AUTH-2564: error handling and minor fixes\n- 2020-05-01 AUTH-2588 add DoH to service mode\n\n2020.5.0\n- 2020-05-01 TUN-2943: Copy certutil from edge into cloudflared\n- 2020-05-05 TUN-2955: Fix connection and goroutine leaks when tunnel conection is terminated on error. Only unregister tunnels that had connected successfully. Close edge connection used to unregister the tunnel. Use buffered channels for error channels where receiver may quit early on context cancellation.\n- 2020-04-30 TUN-2940: Added delay parameter to stdin reconnect command.\n- 2020-04-27 TUN-2921: Rework address selection logic to avoid corner cases\n- 2020-04-28 TUN-2872: Exit with non-0 status code when the binary is updated so launchd will restart the service\n- 2020-04-13 AUTH-2587 add config watcher and reload logic for access client forwarder\n\n2020.4.0\n- 2020-04-10 TUN-2881: Parameterize response meta information header name in the generating function\n- 2020-04-11 TUN-2894: ResponseMetaHeader should be public\n- 2020-04-09 TUN-2880: Return metadata about source of the response from cloudflared\n- 2020-04-04 ARES-899: Fixes DoH client as system resolver. Fixes #91\n- 2020-03-31 AUTH-2394 added socks5 proxy\n- 2020-02-24 AUTH-2235 GetTokenIfExists now parses JWT payload for json expiry field to detect if the cached access token is expired\n\n2020.3.2\n- 2020-03-31 TUN-2854: Quick Reconnects should be an optional supported feature\n- 2020-03-30 TUN-2850: Tunnel stripping Cloudflare headers\n\n2020.3.1\n- 2020-03-27 TUN-2846: Trigger debug reconnects from stdin commands, not SIGUSR1\n\n2020.3.0\n- 2020-03-23 AUTH-2394 fixed header for websockets. Added TCP alias\n- 2020-03-10 TUN-2797: Fix panic in SetConnDigest by making mutexes values.\n- 2020-03-13 TUN-2807: cloudflared hello-world shouldn't assume it's my first tunnel\n- 2020-03-13 TUN-2756: Set connection digest after reconnect.\n- 2020-03-16 TUN-2812: Tunnel proxies and RPCs can share an edge address\n- 2020-03-18 TUN-2816: cloudflared metrics server should be more discoverable\n- 2020-03-19 TUN-2820: Serialized headers for Websockets\n- 2020-03-19 TUN-2819: cloudflared should close its connections when a signal is sent\n- 2020-03-19 TUN-2823: Bugfix. cloudflared would hang forever if error occurred.\n- 2020-03-10 TUN-2796: Implement HTTP2 CONTINUATION headers correctly\n- 2020-03-02 TUN-2779: update sample HTML pages\n- 2020-03-04 TUN-2785: Use reconnect token by default\n- 2020-03-05 TUN-2754: Add ConnDigest to cloudflared and its RPCs\n- 2020-03-06 TUN-2755: ReconnectTunnel RPC now transmits ConnectionDigest\n- 2020-03-06 TUN-2761: Use the new header management functions in cloudflared\n- 2020-03-06 TUN-2788: cloudflared should store one ConnDigest per HA connection\n- 2020-02-26 TUN-2767: Test for large headers\n- 2020-02-28 do not terminate tunnel if origin is not reachable on start-up (#177)\n- 2020-02-28 TUN-2776: Add header serialization feature in cloudflared\n- 2020-02-21 TUN-2748: Insecure randomness vulnerability in github.com/miekg/dns\n\n2020.2.1\n- 2020-02-20 TUN-2745: Rename existing header management functions\n- 2020-02-21 TUN-2746: Add the new header management functions\n- 2020-02-25 perf(cloudflared): reuse memory from buffer pool to get better throughput (#161)\n- 2020-02-25 Tweak HTTP host header. Fixes #107 (#168)\n- 2020-02-25 TUN-2765: Add list of features to tunnelrpc\n- 2020-02-19 TUN-2725: Specify in code that --edge is for internal testing only\n- 2020-02-19 TUN-2703: Muxer.Serve terminates when its context is Done\n- 2020-02-09 TUN-2717: Function to serialize/deserialize HTTP headers\n- 2020-02-05 TUN-2714: New edge discovery. Connections try to reconnect to the same edge IP.\n\n2020.2.0\n- 2020-01-30 TUN-2651: Fix panic in h2mux reader when a stream error is encountered\n- 2020-01-27 TUN-2645: Revert \"TUN-2645: Turn on reconnect tokens\"\n- 2020-01-28 TUN-2693: Metrics for ReconnectTunnel\n- 2020-01-28 TUN-2696: Add unknown registerRPCName\n- 2020-01-28 TUN-2699: Metrics for Authenticate RPCs\n- 2020-01-28 TUN-2690: cloudflared reconnect uses wrong context\n- 2020-01-29 TUN-2707: Inconsistent cardinality in tunnel error metrics\n- 2020-01-13 TUN-2645: Turn on reconnect tokens\n- 2019-12-23 TUN-2646: Make --edge flag work again for local development\n\n2019.12.0\n- 2019-12-11 TUN-2631: only notify that activeStreamMap is closed if ignoreNewStreams=true\n- 2019-12-17 bug(cloudflared): Set the MaxIdleConnsPerHost of http.Transport to proxy-keepalive-connections (#155)\n- 2019-12-17 refactor(docker): optimize Dockerfile (#126)\n- 2019-12-19 Fix timer scheduling for systemd update service (#159)\n- 2019-12-13 TUN-2637: Manage edge IPs in a region-aware manner\n- 2019-12-03 bug(cloudflared): nil pointer deference on h2DictWriter Close() (#154)\n- 2019-12-03 TUN-2608: h2mux.Muxer.Shutdown always returns a non-nil channel\n- 2019-12-04 TUN-2555: origin/supervisor.go calls Authenticate\n- 2019-12-06 TUN-2554: cloudflared calls ReconnectTunnel\n- 2019-11-20 TUN-2575: Constructors + simpler conversions for AuthOutcome\n- 2019-11-22 Fix Docker build failure (#149)\n- 2019-11-21 TUN-2573: Refactor TunnelRegistration into PermanentRegistrationError, RetryableRegistrationError and SuccessfulTunnelRegistration\n- 2019-11-22 TUN-2582: EventDigest field in tunnelrpc\n- 2019-11-22 Fix \"happy eyeballs\" not being disabled since Golang 1.12 upgrade * The Dialer.DualStack setting is now ignored and deprecated; RFC 6555 Fast Fallback (\"Happy Eyeballs\") is now enabled by default. To disable, set Dialer.FallbackDelay to a negative value.\n- 2019-11-25 TUN-2591: ReconnectTunnel now sends EventDigest\n- 2019-11-21 TUN-2606: add DialEdge helpers\n- 2019-11-21 TUN-2607: add RPC stream helpers\n\n2019.11.3\n- 2019-11-20 TUN-2562: Update Cloudflare Origin CA RSA root\n\n2019.11.2\n- 2019-11-18 TUN-2567: AuthOutcome can be turned back into AuthResponse\n- 2019-11-18 TUN-2563: Exposes config_version metrics\n\n2019.11.1\n- 2019-11-12 Add db-connect, a SQL over HTTPS server\n- 2019-11-12 TUN-2053: Add a /healthcheck endpoint to the metrics server\n- 2019-11-13 TUN-2178: public API to create new h2mux.MuxedStreamRequest\n- 2019-11-13 TUN-2490: respect original representation of HTTP request path\n- 2019-11-18 TUN-2547: TunnelRPC definitions for Authenticate flow\n- 2019-11-18 TUN-2551: TunnelRPC definitions for ReconnectTunnel flow\n- 2019-11-05 TUN-2506: Expose active streams metrics\n\n2019.11.0\n- 2019-11-04 TUN-2502: Switch to go modules\n- 2019-11-04 TUN-2500: Don't send client registration errors to Sentry\n- 2019-11-04 TUN-2489: Delete stream from activestreammap when read and write are both closed\n- 2019-11-05 TUN-2505: Terminate stream on receipt of RST_STREAM; MuxedStream.CloseWrite() should terminate the MuxedStream.Write() loop\n- 2019-10-30 TUN-2451: Log inavlid path\n- 2019-10-22 TUN-2425: Enable cloudflared to serve multiple Hello World servers by having each of them create its own ServeMux\n- 2019-10-22 AUTH-2173: Prepends access login url with scheme if one doesnt exist\n- 2019-10-23 TUN-2460: Configure according to the ClientConfig recevied from a successful Connect\n- 2019-10-23 AUTH-2177: Reads and writes error streams\n\n2019.10.4\n- 2019-10-21 TUN-2450: Remove Brew publishing formula\n\n2019.10.3\n- 2019-10-18 Fix #129: Excessive memory usage streaming large files (#142)\n\n2019.10.2\n- 2019-10-17 AUTH-2167: Adds CLI option for host key directory\n\n2019.10.1\n- 2019-10-17 Adds variable to fix windows build\n\n2019.10.0\n- 2019-10-11 AUTH-2105: Dont require --destination arg\n- 2019-10-14 TUN-2344: log more details: http2.Framer.ErrorDetail() if available, connectionID\n- 2019-10-16 AUTH-2159: Moves shutdownC close into error handling AUTH-2161: Lowers size of preamble length AUTH-2160: Fixes url parsing logic\n- 2019-10-16 AUTH-2135: Adds support for IPv6 and tests\n- 2019-10-02 AUTH-2105: Adds support for local forwarding. Refactor auditlogger creation. AUTH-2088: Adds dynamic destination routing\n- 2019-10-09 AUTH-2114: Uses short lived cert auth for outgoing client connection\n- 2019-09-30 AUTH-2089: Revise ssh server to function as a proxy\n\n2019.9.2\n- 2019-09-26 TUN-2355: Roll back TUN-2276\n\n2019.9.1\n- 2019-09-23 TUN-2334: remove tlsConfig.ServerName special case\n- 2019-09-23 AUTH-2077: Quotes open browser command in windows\n- 2019-09-11 AUTH-2050: Adds time.sleep to temporarily avoid hitting tunnel muxer dealock issue\n- 2019-09-10 AUTH-2056: Writes stderr to its own stream for non-pty connections\n- 2019-09-16 TUN-2307: Capnp is the only serialization format used in tunnelpogs\n- 2019-09-18 TUN-2315: Replace Scope with IntentLabel\n- 2019-09-17 TUN-2309: Split ConnectResult into ConnectError and ConnectSuccess, each implementing its own capnp serialization logic\n- 2019-09-18 AUTH-2052: Adds tests for SSH server\n- 2019-09-18 AUTH-2067: Log commands correctly\n- 2019-09-19 AUTH-2055: Verifies token at edge on access login\n- 2019-09-04 TUN-2201: change SRV records used by cloudflared\n- 2019-09-06 TUN-2280: Revert \"TUN-2260: add name/group to CapnpConnectParameters, remove Scope\"\n- 2019-09-03 AUTH-1943 hooked up uploader to logger, added timestamp to session logs, add tests\n- 2019-09-04 AUTH-2036: Refactor user retrieval, shutdown after ssh server stops, add custom version string\n- 2019-09-06 AUTH-1942 added event log to ssh server\n- 2019-09-04 AUTH-2037: Adds support for ssh port forwarding\n- 2019-09-05 TUN-2276: Path encoding broken\n\n2019.9.0\n- 2019-09-05 TUN-2279: Revert path encoding fix\n- 2019-08-30 AUTH-2021 - check error for failing tests\n- 2019-08-29 AUTH-2030: Support both authorized_key and short lived cert authentication simultaniously without specifiying at start time\n- 2019-08-29 AUTH-2026: Adds support for non-pty sessions and inline command exec\n- 2019-08-26 AUTH-1943: Adds session logging\n- 2019-08-26 TUN-2162: Decomplect OpenStream to allow finer-grained timeouts\n- 2019-08-29 TUN-2260: add name/group to CapnpConnectParameters, remove Scope\n\n2019.8.4\n- 2019-08-30 Fix #111: Add support for specifying a specific HTTP Host: header on the origin. (#114)\n- 2019-08-22 TUN-2165: Add ClientConfig to tunnelrpc.ConnectResult\n- 2019-08-20 AUTH-2014: Checks users login shell\n- 2019-08-26 TUN-2243: Revert \"STOR-519: Add db-connect, a SQL over HTTPS server\"\n- 2019-08-27 TUN-2244: Add NO_AUTOUPDATE env var\n- 2019-08-22 AUTH-2018: Adds support for authorized keys and short lived certs\n- 2019-08-28 AUTH-2022: Adds ssh timeout configuration\n- 2019-08-28 TUN-1968: Gracefully diff StreamHandler.UpdateConfig\n- 2019-08-26 AUTH-2021 - s3 bucket uploading for SSH logs\n- 2019-08-19 AUTH-2004: Adds static host key support\n- 2019-07-18 AUTH-1941: Adds initial SSH server implementation\n\n2019.8.3\n- 2019-08-20 STOR-519: Add db-connect, a SQL over HTTPS server\n- 2019-08-20 Release 2019.8.2\n- 2019-08-20 Revert \"AUTH-1941: Adds initial SSH server implementation\"\n- 2019-08-11 TUN-2163: Add GrapQLType method to Scope interface\n- 2019-08-06 TUN-2152: Requests with a query in the URL are erroneously escaped\n- 2019-07-18 AUTH-1941: Adds initial SSH server implementation\n\n2019.8.1\n- 2019-08-05 TUN-2111: Implement custom serialization logic for FallibleConfig and OriginConfig\n- 2019-08-06 Revert \"TUN-1736: Missing headers when passing an invalid path\"\n\n2019.8.0\n- 2019-07-11 TUN-1956: Go 1.12 update\n- 2019-07-24 TUN-1736: Missing headers when passing an invalid path\n- 2019-07-30 TUN-2117: read group/system-name from CLI, send it to edge\n- 2019-08-02 TUN-2125: Add PostgresType() to Scope\n- 2019-08-05 TUN-2147: Implemented ScopeUnmarshaler\n- 2019-07-31 TUN-2110: Implement custom deserialization logic for OriginConfig\n- 2019-07-31 AUTH-1972: Deletes token lock file if backoff retry attempts exceeded and intercepts signals until lock is released\n\n2019.7.0\n- 2019-05-28 TUN-1913: Define OriginService for each type of origin\n- 2019-04-29 Build a docker container\n- 2019-06-12 TUN-1952: Group ClientConfig fields by the component that uses the config, and return the part of the config that failed to be applied\n- 2019-06-05 TUN-1893: Proxy requests to the origin based on tunnel hostname\n- 2019-06-17 TUN-1961: Create EdgeConnectionManager to maintain outbound connections to the edge\n- 2019-06-18 TUN-1885: Reconfigure cloudflared on receiving new ClientConfig\n- 2019-06-19 TUN-1976: Pass tunnel hostname through header\n- 2019-06-20 TUN-1982: Load custom origin CA when OriginCAPool is specified\n- 2019-06-26 TUN-2005: Upgrade logrus\n- 2019-06-20 TUN-1981: Write response header & body on proxy error to notify eyeballs of failure category\n- 2019-06-20 TUN-1977: Validate OriginConfig has valid URL, and use scheme to determine if a HTTPOriginService is expecting HTTP or Unix\n- 2019-06-13 DoH: change the media type to application/dns-message\n- 2019-06-26 AUTH-1736: Better handling of token revocation\n\n2019.6.0\n- 2019-05-17 TUN-1828: Update declarative tunnel config struct\n- 2019-05-29 Handle exit code on err\n- 2019-05-29 AUTH-1802: Fixed ssh-config templating\n- 2019-05-30 TUN-1914: Conflate HTTP and Unix OriginConfig, and add TLS config to WebSocketOriginConfig\n- 2019-06-03 AUTH-1811: ssh-gen config fixes\n\n2019.5.0\n- 2019-04-25 TUN-1781: ServeStream should return early on error\n- 2019-04-30 TUN-1786: Remove low-level Windows service logging\n- 2019-05-03 TUN-1807: Send cloudflared version in Connect RPC\n- 2019-01-23 AUTH-1557: Short Lived Certs\n- 2019-05-13 TUN-1847: Log a distinct message when OpenStream fails while waiting for response headers\n- 2019-05-13 AUTH-1706: fixes and testing\n- 2019-05-22 TUN-1880: Save debug and warn level log to logfile\n- 2019-05-22 AUTH-1781: fixed race condition for short lived certs, doc required config\n\n2019.4.1\n- 2019-03-18 TUN-1626: Create new supervisor to establish connection with origintunneld\n- 2019-04-04 TUN-1619: Add flag to test declarative tunnels.\n- 2019-04-05 TUN-1577: decompose carrier.StartServer to make TestStartServer less flappy\n- 2019-03-29 TUN-1606: Define CloudflaredConfig RPC structure, interface for cloudflared's RPC server\n- 2019-04-02 TUN-1682: Add context to OpenStream to prevent it from blocking indefinitely.\n- 2019-04-16 TUN-1732: cloudflared metrics should track userHostnames\n- 2019-04-17 TUN-1734: Pin packages at exact versions\n- 2019-04-18 TUN-1669: Update license message in help text. Also fix test\n\n2019.4.0\n- 2019-03-28 TUN-1648: ConnectionID is now a UUID\n- 2019-04-01 TUN-1673: Conflate Hello and Connect RPCs\n\n2019.3.2\n- 2019-03-22 TUN-1637: Free tunnels shouldn't require cert.pem\n- 2019-03-18 TUN-1604: Define Connect RPC call\n\n2019.3.1\n- 2019-03-09 Add rdp as a supported protocol in URL validation (#76)\n- 2019-03-15 TUN-1613: improved cloudflared RegisterTunnel fail metrics\n- 2019-03-17 TUN-1615: revert miekg/dns to last known working revision\n\n2019.3.0\n- 2018-12-28 make http transport aware of proxy from envvar\n- 2019-02-28 TUN-1559: fix nil dereference in TunnelConfig.CloseConnOnce\n- 2019-03-04 TUN-1451: Make non-interactive, non-service execution possible on Windows\n- 2019-03-04 TUN-1562: Refactor connectedSignal to be safe to close multiple times\n- 2019-02-27 TUN-1550: Add validation timeout for non-responsive origins\n- 2019-03-06 AUTH-1531: Named flags for ssh service tokens\n- 2019-02-14 Support unix sockets.\n- 2019-03-08 TUN-1389: Non-scalar flags in a cloudflared config.yml don't get logged\n- 2019-03-07 TUN-1522: If we can't get SRV from default resolver, get them from 1.1.1.1 DoT\n\n2019.2.1\n- 2019-02-14 TUN-1381:  should tell you if you're on the latest version rather than just exiting silently\n- 2019-02-15 TUN-1467: build with Go 1.11\n- 2019-02-15 AUTH-1519: Added logging\n- 2019-02-19 TUN-1525: cloudflared metrics for registration success/fail\n- 2019-02-19 TUN-1510: Wrap the close() in sync.Once.Do\n\n2019.2.0\n- 2019-01-24 AUTH-1462: better curl arg parsing\n- 2019-02-01 TUN-1456: Only make one UUID\n- 2019-01-30 cloudflared/linux_service: Add missing /etc/init.d shebang\n- 2019-02-07 AUTH-1511: Add custom headers for ssh command\n- 2019-02-01 AUTH-1503: Added RDP support\n- 2019-02-01 AUTH-1403: Print the paths in the ssh-config instructions\n\n2019.1.0\n- 2018-12-10 TUN-1231: Horizontal overflow wrapping on the Hello page\n- 2018-12-17 TUN-1140: Show usage if invoked with no args or config\n- 2018-11-06 TUN-632 Filter out common network exceptions from going to Sentry on StartServer\n- 2019-01-07 TUN-1138: Install cloudflared service directory with 755 permissions\n- 2019-01-07 TUN-1265: Silent exit when failing to parse config\n- 2019-01-10 TUN-1350: Enhance error messages with cloudflarestatus.com link, if relevant\n- 2019-01-16 TUN-1358: Close readyList after Muxer.Serve() has stopped running\n- 2019-01-24 AUTH-1423: move from stdout to stderr\n- 2019-01-24 AUTH-1404: reauth if the token is about to expire within 15 minutes\n- 2019-01-24 AUTH-1459: improved ssh streaming error message\n- 2019-01-24 AUTH-1211: print all the versions\n- 2019-01-24 AUTH-1337: fix url path\n- 2019-01-28 TUN-1418: Rename ProtocolLogger to TransportLogger, and use TransportLogger to log RPC events.\n- 2019-01-28 TUN-1419: Identify request/response headers/content length with ray ID\n\n2018.12.1\n- 2018-12-11 TUN-1270: cloudflared panic (HA metrics missing label)\n\n2018.12.0\n- 2018-11-15 TUN-1196: Allow TLS config client CA and root CA to be constructed from multiple certificates\n- 2018-11-20 TUN-1209: TLS Config Certificates and GetCertificate can both be set\n- 2018-11-26 TUN-1212: Expose tunnel_id in metrics\n- 2018-11-30 TUN-1204: remove 'cloudflared hello' command\n- 2018-12-04 Fix license URL typo\n- 2018-12-07 TUN-1250: ValidateHTTPService shouldn't follow 302s\n\n2018.11.0\n- 2018-10-31 AUTH-1282: Fixed an issue where we were receiving as opposed sending on the channel.\n- 2018-11-06 TUN-1179: Fix log message in cmd/cloudflared/transfer.Run\n- 2018-11-13 AUTH-1308: get jwt even when you are already logged in\n- 2018-11-12 TUN-1190: check URL parse error when starting SSH proxy server\n- 2018-11-15 AUTH-1320: Fixed request issue and unhide the ssh command\n\n2018.10.5\n- 2018-10-18 TUN-968: Flow control for large requests/responses\n- 2018-10-26 TUN-1158: Windows: use process arguments rather than trivial service arguments\n- 2018-10-20 #30: Fix the Content-Length header for HTTP2->HTTP1\n- 2018-10-29 TUN-1160: pass Host header during origin url validation\n\n2018.10.4\n- 2018-09-21 AUTH-1070: added SSH/protocol forwarding\n- 2018-10-19 AUTH-1235: fixed packaging of deb dev file\n- 2018-10-19 TUN-1097: Host missing from WebSocket request\n- 2018-10-19 AUTH-1188: UX Review and Changes for CLI SSH Access\n\n2018.10.3\n- 2018-10-08 TUN-1099: Bring back changes in 2018.10.1\n- 2018-10-08 TUN-1098: removed deprecation error\n- 2018-10-08 TUN-1101: False negatives in Cloudflared error reporting\n\n2018.10.2\n- 2018-10-06 TUN-1093: Revert cloudflared to 2018.8.0\n\n2018.10.1\n- 2018-10-03 TUN-1012: Normalize config filename for Linux services\n- 2018-10-05 TUN-1081: cloudflared now generates UUIDs\n- 2018-10-05 TUN-1083: fixed incorrect help menu\n- 2018-10-05 TUN-1086: fixed config option\n\n2018.10.0\n- 2018-08-15 AUTH-910, AUTH-1049, AUTH-1068, AUTH-1056: Generate and store Access tokens with E2EE option, curl/cmd wrapper\n- 2018-09-11 TUN-890: To support free tunnels, hostname can now be \"\"\n- 2018-09-12 TUN-810: Cloudflared should open dash/argotunnel not dash/warp\n- 2018-09-12 TUN-985: Don't display tunnel ID if it's empty string\n- 2018-09-11 TUN-881: Display trial zone URL upon successful registration\n- 2018-09-11 TUN-868: HTTP/HTTPS mismatch should have a better error message\n- 2018-09-19 TUN-1028: Unhide cloudflared compression flag\n- 2018-09-20 AUTH-1139: refactored cloudflared help menu\n- 2018-09-20 TUN-1035: New text for cloudflared tunnel --help\n- 2018-09-18 AUTH-1136: addressing beta feedback\n- 2018-09-26 AUTH-1165: hide access command\n- 2018-09-26 TUN-1046: Document that delta compression is a beta feature\n- 2018-09-28 TUN-1056: Lint error broke build\n- 2018-09-27 TUN-1052: Origintunneld can send back an Origincert to Cloudflared\n- 2018-09-28 TUN-1052: Changing type of OriginCert to :Data\n- 2018-10-01 TUN-1062: Makefile target for regenerating Capn Proto definitions\n- 2018-10-02 TUN-1064: Revert OriginCert capnp changes in Cloudflared. Reverts commits a1ee2342e97 and 8c756c45785.\n- 2018-10-03 TUN-1076: Pin capnproto2 to version 2.17.1\n- 2018-10-03 AUTH-1199: unhide access command, added beta label\n\n2018.8.0\n- 2018-05-01 Initial commit\n- 2018-05-03 TUN-595: Add License/Readme files to cloudflared\n- 2018-05-01 TUN-528: Move cloudflared into a separate repo\n- 2018-07-24 TUN-813: Clean up cloudflared dependencies\n- 2018-07-25 TUN-814: Handle error in CreateTLSListener before closing listener\n- 2018-07-24 TUN-804: create Makefile recipe to build cloudflared and run tests\n- 2018-07-26 TUN-817: Increase the log time precision\n- 2018-07-30 TUN-828: Added Connection: keep-alive header\n- 2018-07-30 TUN-829: prefer p256 curve\n- 2018-07-31 TUN-834: Enable tracing on cloudflared\n- 2018-08-07 TUN-820: Fix caddyfile gitignore\n- 2018-07-25 TUN-804: create make recipe for building deb package\n- 2018-08-07 TUN-861: Disable cloudflared tracing by default; preserve the latest tracefile\n- 2018-08-07 TUN-857: Pull the brotli-go dependency from Github\n- 2018-08-14 TUN-897: Bring back missing Brotli files\n- 2018-07-26 TUN-804: create makefile recipe to release cloudflared using equinox\n- 2018-08-15 TUN-901: makefile target for homebrew release\n- 2018-07-30 TUN-801: Rapid SQL Proxy\n- 2018-08-27 TUN-833: Don't log system root certificate loading failure on Windows\n\n"
  },
  {
    "path": "carrier/carrier.go",
    "content": "// Package carrier provides a WebSocket proxy to carry or proxy a connection\n// from the local client to the edge. See it as a wrapper around any protocol\n// that it packages up in a WebSocket connection to the edge.\npackage carrier\n\nimport (\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/token\"\n)\n\nconst (\n\tLogFieldOriginURL       = \"originURL\"\n\tCFAccessTokenHeader     = \"Cf-Access-Token\"\n\tcfJumpDestinationHeader = \"Cf-Access-Jump-Destination\"\n)\n\ntype StartOptions struct {\n\tAppInfo               *token.AppInfo\n\tOriginURL             string\n\tHeaders               http.Header\n\tHost                  string\n\tTLSClientConfig       *tls.Config\n\tAutoCloseInterstitial bool\n\tIsFedramp             bool\n}\n\n// Connection wraps up all the needed functions to forward over the tunnel\ntype Connection interface {\n\t// ServeStream is used to forward data from the client to the edge\n\tServeStream(*StartOptions, io.ReadWriter) error\n}\n\n// StdinoutStream is empty struct for wrapping stdin/stdout\n// into a single ReadWriter\ntype StdinoutStream struct{}\n\n// Read will read from Stdin\nfunc (c *StdinoutStream) Read(p []byte) (int, error) {\n\treturn os.Stdin.Read(p)\n}\n\n// Write will write to Stdout\nfunc (c *StdinoutStream) Write(p []byte) (int, error) {\n\treturn os.Stdout.Write(p)\n}\n\n// Helper to allow deferring the response close with a check that the resp is not nil\nfunc closeRespBody(resp *http.Response) {\n\tif resp != nil {\n\t\t_ = resp.Body.Close()\n\t}\n}\n\n// StartForwarder will setup a listener on a specified address/port and then\n// forward connections to the origin by calling `Serve()`.\nfunc StartForwarder(conn Connection, address string, shutdownC <-chan struct{}, options *StartOptions) error {\n\tlistener, err := net.Listen(\"tcp\", address)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to start forwarding server\")\n\t}\n\treturn Serve(conn, listener, shutdownC, options)\n}\n\n// StartClient will copy the data from stdin/stdout over a WebSocket connection\n// to the edge (originURL)\nfunc StartClient(conn Connection, stream io.ReadWriter, options *StartOptions) error {\n\treturn conn.ServeStream(options, stream)\n}\n\n// Serve accepts incoming connections on the specified net.Listener.\n// Each connection is handled in a new goroutine: its data is copied over a\n// WebSocket connection to the edge (originURL).\n// `Serve` always closes `listener`.\nfunc Serve(remoteConn Connection, listener net.Listener, shutdownC <-chan struct{}, options *StartOptions) error {\n\tdefer listener.Close()\n\terrChan := make(chan error)\n\n\tgo func() {\n\t\tfor {\n\t\t\tconn, err := listener.Accept()\n\t\t\tif err != nil {\n\t\t\t\t// don't block if parent goroutine quit early\n\t\t\t\tselect {\n\t\t\t\tcase errChan <- err:\n\t\t\t\tdefault:\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\tgo serveConnection(remoteConn, conn, options)\n\t\t}\n\t}()\n\n\tselect {\n\tcase <-shutdownC:\n\t\treturn nil\n\tcase err := <-errChan:\n\t\treturn err\n\t}\n}\n\n// serveConnection handles connections for the Serve() call\nfunc serveConnection(remoteConn Connection, c net.Conn, options *StartOptions) {\n\tdefer c.Close()\n\t_ = remoteConn.ServeStream(options, c)\n}\n\n// IsAccessResponse checks the http Response to see if the url location\n// contains the Access structure.\nfunc IsAccessResponse(resp *http.Response) bool {\n\tif resp == nil || resp.StatusCode != http.StatusFound {\n\t\treturn false\n\t}\n\n\tlocation, err := resp.Location()\n\tif err != nil || location == nil {\n\t\treturn false\n\t}\n\tif strings.HasPrefix(location.Path, token.AccessLoginWorkerPath) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// BuildAccessRequest builds an HTTP request with the Access token set\nfunc BuildAccessRequest(options *StartOptions, log *zerolog.Logger) (*http.Request, error) {\n\treq, err := http.NewRequest(http.MethodGet, options.OriginURL, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttoken, err := token.FetchTokenWithRedirect(req.URL, options.AppInfo, options.AutoCloseInterstitial, options.IsFedramp, log)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// We need to create a new request as FetchToken will modify req (boo mutable)\n\t// as it has to follow redirect on the API and such, so here we init a new one\n\toriginRequest, err := http.NewRequest(http.MethodGet, options.OriginURL, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\toriginRequest.Header.Set(CFAccessTokenHeader, token)\n\n\tfor k, v := range options.Headers {\n\t\tif len(v) >= 1 {\n\t\t\toriginRequest.Header.Set(k, v[0])\n\t\t}\n\t}\n\n\treturn originRequest, nil\n}\n\nfunc SetBastionDest(header http.Header, destination string) {\n\tif destination != \"\" {\n\t\theader.Set(cfJumpDestinationHeader, destination)\n\t}\n}\n\nfunc ResolveBastionDest(r *http.Request) (string, error) {\n\tjumpDestination := r.Header.Get(cfJumpDestinationHeader)\n\tif jumpDestination == \"\" {\n\t\treturn \"\", fmt.Errorf(\"Did not receive final destination from client. The --destination flag is likely not set on the client side\")\n\t}\n\t// Strip scheme and path set by client. Without a scheme\n\t// Parsing a hostname and path without scheme might not return an error due to parsing ambiguities\n\tif jumpURL, err := url.Parse(jumpDestination); err == nil && jumpURL.Host != \"\" {\n\t\treturn removePath(jumpURL.Host), nil\n\t}\n\treturn removePath(jumpDestination), nil\n}\n\nfunc removePath(dest string) string {\n\treturn strings.SplitN(dest, \"/\", 2)[0]\n}\n"
  },
  {
    "path": "carrier/carrier_test.go",
    "content": "package carrier\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"sync\"\n\t\"testing\"\n\n\tws \"github.com/gorilla/websocket\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nconst (\n\t// example in Sec-Websocket-Key in rfc6455\n\ttestSecWebsocketKey = \"dGhlIHNhbXBsZSBub25jZQ==\"\n)\n\ntype testStreamer struct {\n\tbuf *bytes.Buffer\n\tl   sync.RWMutex\n}\n\nfunc newTestStream() *testStreamer {\n\treturn &testStreamer{buf: new(bytes.Buffer)}\n}\n\nfunc (s *testStreamer) Read(p []byte) (int, error) {\n\ts.l.RLock()\n\tdefer s.l.RUnlock()\n\treturn s.buf.Read(p)\n\n}\n\nfunc (s *testStreamer) Write(p []byte) (int, error) {\n\ts.l.Lock()\n\tdefer s.l.Unlock()\n\treturn s.buf.Write(p)\n}\n\nfunc TestStartClient(t *testing.T) {\n\tmessage := \"Good morning Austin! Time for another sunny day in the great state of Texas.\"\n\tlog := zerolog.Nop()\n\twsConn := NewWSConnection(&log)\n\tts := newTestWebSocketServer()\n\tdefer ts.Close()\n\n\tbuf := newTestStream()\n\toptions := &StartOptions{\n\t\tOriginURL: \"http://\" + ts.Listener.Addr().String(),\n\t\tHeaders:   nil,\n\t}\n\terr := StartClient(wsConn, buf, options)\n\tassert.NoError(t, err)\n\t_, _ = buf.Write([]byte(message))\n\n\treadBuffer := make([]byte, len(message))\n\t_, _ = buf.Read(readBuffer)\n\tassert.Equal(t, message, string(readBuffer))\n}\n\nfunc TestStartServer(t *testing.T) {\n\tlistener, err := net.Listen(\"tcp\", \"localhost:\")\n\tif err != nil {\n\t\tt.Fatalf(\"Error starting listener: %v\", err)\n\t}\n\tmessage := \"Good morning Austin! Time for another sunny day in the great state of Texas.\"\n\tlog := zerolog.Nop()\n\tshutdownC := make(chan struct{})\n\twsConn := NewWSConnection(&log)\n\tts := newTestWebSocketServer()\n\tdefer ts.Close()\n\toptions := &StartOptions{\n\t\tOriginURL: \"http://\" + ts.Listener.Addr().String(),\n\t\tHeaders:   nil,\n\t}\n\n\tgo func() {\n\t\terr := Serve(wsConn, listener, shutdownC, options)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Error running server: %v\", err)\n\t\t\treturn\n\t\t}\n\t}()\n\n\tconn, err := net.Dial(\"tcp\", listener.Addr().String())\n\t_, _ = conn.Write([]byte(message))\n\n\treadBuffer := make([]byte, len(message))\n\t_, _ = conn.Read(readBuffer)\n\tassert.Equal(t, string(readBuffer), message)\n}\n\nfunc TestIsAccessResponse(t *testing.T) {\n\tvalidLocationHeader := http.Header{}\n\tvalidLocationHeader.Add(\"location\", \"https://test.cloudflareaccess.com/cdn-cgi/access/login/blahblah\")\n\tinvalidLocationHeader := http.Header{}\n\tinvalidLocationHeader.Add(\"location\", \"https://google.com\")\n\ttestCases := []struct {\n\t\tDescription string\n\t\tIn          *http.Response\n\t\tExpectedOut bool\n\t}{\n\t\t{\"nil response\", nil, false},\n\t\t{\"redirect with no location\", &http.Response{StatusCode: http.StatusFound}, false},\n\t\t{\"200 ok\", &http.Response{StatusCode: http.StatusOK}, false},\n\t\t{\"redirect with location\", &http.Response{StatusCode: http.StatusFound, Header: validLocationHeader}, true},\n\t\t{\"redirect with invalid location\", &http.Response{StatusCode: http.StatusFound, Header: invalidLocationHeader}, false},\n\t}\n\n\tfor i, tc := range testCases {\n\t\tif IsAccessResponse(tc.In) != tc.ExpectedOut {\n\t\t\tt.Fatalf(\"Failed case %d -- %s\", i, tc.Description)\n\t\t}\n\t}\n\n}\n\nfunc newTestWebSocketServer() *httptest.Server {\n\tupgrader := ws.Upgrader{\n\t\tReadBufferSize:  1024,\n\t\tWriteBufferSize: 1024,\n\t}\n\n\treturn httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tconn, _ := upgrader.Upgrade(w, r, nil)\n\t\tdefer conn.Close()\n\t\tfor {\n\t\t\tmt, message, err := conn.ReadMessage()\n\t\t\tif err != nil {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif err := conn.WriteMessage(mt, []byte(message)); err != nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}))\n}\n\nfunc testRequest(t *testing.T, url string, stream io.ReadWriter) *http.Request {\n\treq, err := http.NewRequest(\"GET\", url, stream)\n\tif err != nil {\n\t\tt.Fatalf(\"testRequestHeader error\")\n\t}\n\n\treq.Header.Add(\"Connection\", \"Upgrade\")\n\treq.Header.Add(\"Upgrade\", \"WebSocket\")\n\treq.Header.Add(\"Sec-Websocket-Key\", testSecWebsocketKey)\n\treq.Header.Add(\"Sec-Websocket-Protocol\", \"tunnel-protocol\")\n\treq.Header.Add(\"Sec-Websocket-Version\", \"13\")\n\treq.Header.Add(\"User-Agent\", \"curl/7.59.0\")\n\n\treturn req\n}\n\nfunc TestBastionDestination(t *testing.T) {\n\ttests := []struct {\n\t\tname         string\n\t\theader       http.Header\n\t\texpectedDest string\n\t\twantErr      bool\n\t}{\n\t\t{\n\t\t\tname: \"hostname destination\",\n\t\t\theader: http.Header{\n\t\t\t\tcfJumpDestinationHeader: []string{\"localhost\"},\n\t\t\t},\n\t\t\texpectedDest: \"localhost\",\n\t\t},\n\t\t{\n\t\t\tname: \"hostname destination with port\",\n\t\t\theader: http.Header{\n\t\t\t\tcfJumpDestinationHeader: []string{\"localhost:9000\"},\n\t\t\t},\n\t\t\texpectedDest: \"localhost:9000\",\n\t\t},\n\t\t{\n\t\t\tname: \"hostname destination with scheme and port\",\n\t\t\theader: http.Header{\n\t\t\t\tcfJumpDestinationHeader: []string{\"ssh://localhost:9000\"},\n\t\t\t},\n\t\t\texpectedDest: \"localhost:9000\",\n\t\t},\n\t\t{\n\t\t\tname: \"full hostname url\",\n\t\t\theader: http.Header{\n\t\t\t\tcfJumpDestinationHeader: []string{\"ssh://localhost:9000/metrics\"},\n\t\t\t},\n\t\t\texpectedDest: \"localhost:9000\",\n\t\t},\n\t\t{\n\t\t\tname: \"hostname destination with port and path\",\n\t\t\theader: http.Header{\n\t\t\t\tcfJumpDestinationHeader: []string{\"localhost:9000/metrics\"},\n\t\t\t},\n\t\t\texpectedDest: \"localhost:9000\",\n\t\t},\n\t\t{\n\t\t\tname: \"ip destination\",\n\t\t\theader: http.Header{\n\t\t\t\tcfJumpDestinationHeader: []string{\"127.0.0.1\"},\n\t\t\t},\n\t\t\texpectedDest: \"127.0.0.1\",\n\t\t},\n\t\t{\n\t\t\tname: \"ip destination with port\",\n\t\t\theader: http.Header{\n\t\t\t\tcfJumpDestinationHeader: []string{\"127.0.0.1:9000\"},\n\t\t\t},\n\t\t\texpectedDest: \"127.0.0.1:9000\",\n\t\t},\n\t\t{\n\t\t\tname: \"ip destination with port and path\",\n\t\t\theader: http.Header{\n\t\t\t\tcfJumpDestinationHeader: []string{\"127.0.0.1:9000/metrics\"},\n\t\t\t},\n\t\t\texpectedDest: \"127.0.0.1:9000\",\n\t\t},\n\t\t{\n\t\t\tname: \"ip destination with schem and port\",\n\t\t\theader: http.Header{\n\t\t\t\tcfJumpDestinationHeader: []string{\"tcp://127.0.0.1:9000\"},\n\t\t\t},\n\t\t\texpectedDest: \"127.0.0.1:9000\",\n\t\t},\n\t\t{\n\t\t\tname: \"full ip url\",\n\t\t\theader: http.Header{\n\t\t\t\tcfJumpDestinationHeader: []string{\"ssh://127.0.0.1:9000/metrics\"},\n\t\t\t},\n\t\t\texpectedDest: \"127.0.0.1:9000\",\n\t\t},\n\t\t{\n\t\t\tname:    \"no destination\",\n\t\t\twantErr: true,\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\tr := &http.Request{\n\t\t\tHeader: test.header,\n\t\t}\n\t\tdest, err := ResolveBastionDest(r)\n\t\tif test.wantErr {\n\t\t\tassert.Error(t, err, \"Test %s expects error\", test.name)\n\t\t} else {\n\t\t\tassert.NoError(t, err, \"Test %s expects no error, got error %v\", test.name, err)\n\t\t\tassert.Equal(t, test.expectedDest, dest, \"Test %s expect dest %s, got %s\", test.name, test.expectedDest, dest)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "carrier/websocket.go",
    "content": "package carrier\n\nimport (\n\t\"io\"\n\t\"net/http\"\n\t\"net/http/httputil\"\n\t\"net/url\"\n\n\t\"github.com/gorilla/websocket\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/stream\"\n\t\"github.com/cloudflare/cloudflared/token\"\n\tcfwebsocket \"github.com/cloudflare/cloudflared/websocket\"\n)\n\n// Websocket is used to carry data via WS binary frames over the tunnel from client to the origin\n// This implements the functions for glider proxy (sock5) and the carrier interface\ntype Websocket struct {\n\tlog     *zerolog.Logger\n\tisSocks bool\n}\n\n// NewWSConnection returns a new connection object\nfunc NewWSConnection(log *zerolog.Logger) Connection {\n\treturn &Websocket{\n\t\tlog: log,\n\t}\n}\n\n// ServeStream will create a Websocket client stream connection to the edge\n// it blocks and writes the raw data from conn over the tunnel\nfunc (ws *Websocket) ServeStream(options *StartOptions, conn io.ReadWriter) error {\n\twsConn, err := createWebsocketStream(options, ws.log)\n\tif err != nil {\n\t\tws.log.Err(err).Str(LogFieldOriginURL, options.OriginURL).Msg(\"failed to connect to origin\")\n\t\treturn err\n\t}\n\tdefer wsConn.Close()\n\n\tstream.Pipe(wsConn, conn, ws.log)\n\treturn nil\n}\n\n// createWebsocketStream will create a WebSocket connection to stream data over\n// It also handles redirects from Access and will present that flow if\n// the token is not present on the request\nfunc createWebsocketStream(options *StartOptions, log *zerolog.Logger) (*cfwebsocket.GorillaConn, error) {\n\treq, err := http.NewRequest(http.MethodGet, options.OriginURL, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq.Header = options.Headers\n\tif options.Host != \"\" {\n\t\treq.Host = options.Host\n\t}\n\n\tdump, err := httputil.DumpRequest(req, false)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tlog.Debug().Msgf(\"Websocket request: %s\", string(dump))\n\n\tdialer := &websocket.Dialer{\n\t\tTLSClientConfig: options.TLSClientConfig,\n\t\tProxy:           http.ProxyFromEnvironment,\n\t}\n\twsConn, resp, err := clientConnect(req, dialer)\n\tdefer closeRespBody(resp)\n\n\tif err != nil && IsAccessResponse(resp) {\n\t\t// Only get Access app info if we know the origin is protected by Access\n\t\toriginReq, err := http.NewRequest(http.MethodGet, options.OriginURL, nil)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tappInfo, err := token.GetAppInfo(originReq.URL)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\toptions.AppInfo = appInfo\n\n\t\twsConn, err = createAccessAuthenticatedStream(options, log)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else if err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &cfwebsocket.GorillaConn{Conn: wsConn}, nil\n}\n\nvar stripWebsocketHeaders = []string{\n\t\"Upgrade\",\n\t\"Connection\",\n\t\"Sec-Websocket-Key\",\n\t\"Sec-Websocket-Version\",\n\t\"Sec-Websocket-Extensions\",\n}\n\n// the gorilla websocket library sets its own Upgrade, Connection, Sec-WebSocket-Key,\n// Sec-WebSocket-Version and Sec-Websocket-Extensions headers.\n// https://github.com/gorilla/websocket/blob/master/client.go#L189-L194.\nfunc websocketHeaders(req *http.Request) http.Header {\n\twsHeaders := make(http.Header)\n\tfor key, val := range req.Header {\n\t\twsHeaders[key] = val\n\t}\n\t// Assume the header keys are in canonical format.\n\tfor _, header := range stripWebsocketHeaders {\n\t\twsHeaders.Del(header)\n\t}\n\twsHeaders.Set(\"Host\", req.Host) // See TUN-1097\n\treturn wsHeaders\n}\n\n// clientConnect creates a WebSocket client connection for provided request. Caller is responsible for closing\n// the connection. The response body may not contain the entire response and does\n// not need to be closed by the application.\nfunc clientConnect(req *http.Request, dialler *websocket.Dialer) (*websocket.Conn, *http.Response, error) {\n\treq.URL.Scheme = changeRequestScheme(req.URL)\n\twsHeaders := websocketHeaders(req)\n\tif dialler == nil {\n\t\tdialler = &websocket.Dialer{\n\t\t\tProxy: http.ProxyFromEnvironment,\n\t\t}\n\t}\n\tconn, response, err := dialler.Dial(req.URL.String(), wsHeaders)\n\tif err != nil {\n\t\treturn nil, response, err\n\t}\n\treturn conn, response, nil\n}\n\n// changeRequestScheme is needed as the gorilla websocket library requires the ws scheme.\n// (even though it changes it back to http/https, but ¯\\_(ツ)_/¯.)\nfunc changeRequestScheme(reqURL *url.URL) string {\n\tswitch reqURL.Scheme {\n\tcase \"https\":\n\t\treturn \"wss\"\n\tcase \"http\":\n\t\treturn \"ws\"\n\tcase \"\":\n\t\treturn \"ws\"\n\tdefault:\n\t\treturn reqURL.Scheme\n\t}\n}\n\n// createAccessAuthenticatedStream will try load a token from storage and make\n// a connection with the token set on the request. If it still get redirect,\n// this probably means the token in storage is invalid (expired/revoked). If that\n// happens it deletes the token and runs the connection again, so the user can\n// login again and generate a new one.\nfunc createAccessAuthenticatedStream(options *StartOptions, log *zerolog.Logger) (*websocket.Conn, error) {\n\twsConn, resp, err := createAccessWebSocketStream(options, log)\n\tdefer closeRespBody(resp)\n\tif err == nil {\n\t\treturn wsConn, nil\n\t}\n\n\tif !IsAccessResponse(resp) {\n\t\treturn nil, err\n\t}\n\n\t// Access Token is invalid for some reason. Go through regen flow\n\tif err := token.RemoveTokenIfExists(options.AppInfo); err != nil {\n\t\treturn nil, err\n\t}\n\twsConn, resp, err = createAccessWebSocketStream(options, log)\n\tdefer closeRespBody(resp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn wsConn, nil\n}\n\n// createAccessWebSocketStream builds an Access request and makes a connection\nfunc createAccessWebSocketStream(options *StartOptions, log *zerolog.Logger) (*websocket.Conn, *http.Response, error) {\n\treq, err := BuildAccessRequest(options, log)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tdump, err := httputil.DumpRequest(req, false)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tlog.Debug().Msgf(\"Access Websocket request: %s\", string(dump))\n\n\tconn, resp, err := clientConnect(req, nil)\n\n\tif resp != nil {\n\t\tr, err := httputil.DumpResponse(resp, true)\n\t\tif r != nil {\n\t\t\tlog.Debug().Msgf(\"Websocket response: %q\", r)\n\t\t} else if err != nil {\n\t\t\tlog.Debug().Msgf(\"Websocket response error: %v\", err)\n\t\t}\n\t}\n\n\treturn conn, resp, err\n}\n"
  },
  {
    "path": "carrier/websocket_test.go",
    "content": "package carrier\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"testing\"\n\t\"time\"\n\n\tgws \"github.com/gorilla/websocket\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"golang.org/x/net/websocket\"\n\n\t\"github.com/cloudflare/cloudflared/hello\"\n\t\"github.com/cloudflare/cloudflared/tlsconfig\"\n\tcfwebsocket \"github.com/cloudflare/cloudflared/websocket\"\n)\n\nfunc websocketClientTLSConfig(t *testing.T) *tls.Config {\n\tcertPool := x509.NewCertPool()\n\thelloCert, err := tlsconfig.GetHelloCertificateX509()\n\tassert.NoError(t, err)\n\tcertPool.AddCert(helloCert)\n\tassert.NotNil(t, certPool)\n\treturn &tls.Config{RootCAs: certPool}\n}\n\nfunc TestWebsocketHeaders(t *testing.T) {\n\treq := testRequest(t, \"http://example.com\", nil)\n\twsHeaders := websocketHeaders(req)\n\tfor _, header := range stripWebsocketHeaders {\n\t\tassert.Empty(t, wsHeaders[header])\n\t}\n\tassert.Equal(t, \"curl/7.59.0\", wsHeaders.Get(\"User-Agent\"))\n}\n\nfunc TestServe(t *testing.T) {\n\tlog := zerolog.Nop()\n\tshutdownC := make(chan struct{})\n\terrC := make(chan error)\n\tlistener, err := hello.CreateTLSListener(\"localhost:1111\")\n\tassert.NoError(t, err)\n\tdefer listener.Close()\n\n\tgo func() {\n\t\terrC <- hello.StartHelloWorldServer(&log, listener, shutdownC)\n\t}()\n\n\treq := testRequest(t, \"https://localhost:1111/ws\", nil)\n\n\ttlsConfig := websocketClientTLSConfig(t)\n\tassert.NotNil(t, tlsConfig)\n\td := gws.Dialer{TLSClientConfig: tlsConfig}\n\tconn, resp, err := clientConnect(req, &d)\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"websocket\", resp.Header.Get(\"Upgrade\"))\n\n\tfor i := 0; i < 1000; i++ {\n\t\tmessageSize := rand.Int()%2048 + 1\n\t\tclientMessage := make([]byte, messageSize)\n\t\t// rand.Read always returns len(clientMessage) and a nil error\n\t\trand.Read(clientMessage)\n\t\terr = conn.WriteMessage(websocket.BinaryFrame, clientMessage)\n\t\tassert.NoError(t, err)\n\n\t\tmessageType, message, err := conn.ReadMessage()\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, websocket.BinaryFrame, messageType)\n\t\tassert.Equal(t, clientMessage, message)\n\t}\n\n\t_ = conn.Close()\n\tclose(shutdownC)\n\t<-errC\n}\n\nfunc TestWebsocketWrapper(t *testing.T) {\n\tlistener, err := hello.CreateTLSListener(\"localhost:0\")\n\trequire.NoError(t, err)\n\n\tserverErrorChan := make(chan error)\n\thelloSvrCtx, cancelHelloSvr := context.WithCancel(context.Background())\n\tdefer func() { <-serverErrorChan }()\n\tdefer cancelHelloSvr()\n\tgo func() {\n\t\tlog := zerolog.Nop()\n\t\tserverErrorChan <- hello.StartHelloWorldServer(&log, listener, helloSvrCtx.Done())\n\t}()\n\n\ttlsConfig := websocketClientTLSConfig(t)\n\td := gws.Dialer{TLSClientConfig: tlsConfig, HandshakeTimeout: time.Minute}\n\ttestAddr := fmt.Sprintf(\"https://%s/ws\", listener.Addr().String())\n\treq := testRequest(t, testAddr, nil)\n\tconn, resp, err := clientConnect(req, &d)\n\trequire.NoError(t, err)\n\tassert.Equal(t, \"websocket\", resp.Header.Get(\"Upgrade\"))\n\n\t// Websocket now connected to test server so lets check our wrapper\n\twrapper := cfwebsocket.GorillaConn{Conn: conn}\n\tbuf := make([]byte, 100)\n\twrapper.Write([]byte(\"abc\"))\n\tn, err := wrapper.Read(buf)\n\trequire.NoError(t, err)\n\trequire.Equal(t, n, 3)\n\trequire.Equal(t, \"abc\", string(buf[:n]))\n\n\t// Test partial read, read 1 of 3 bytes in one read and the other 2 in another read\n\twrapper.Write([]byte(\"abc\"))\n\tbuf = buf[:1]\n\tn, err = wrapper.Read(buf)\n\trequire.NoError(t, err)\n\trequire.Equal(t, n, 1)\n\trequire.Equal(t, \"a\", string(buf[:n]))\n\tbuf = buf[:cap(buf)]\n\tn, err = wrapper.Read(buf)\n\trequire.NoError(t, err)\n\trequire.Equal(t, n, 2)\n\trequire.Equal(t, \"bc\", string(buf[:n]))\n}\n"
  },
  {
    "path": "catalog-info.yaml",
    "content": "apiVersion: backstage.io/v1alpha1\nkind: Component\nmetadata:\n  name: cloudflared\n  description: Client for Cloudflare Tunnels\n  annotations:\n    cloudflare.com/software-excellence-opt-in: \"true\"\n    cloudflare.com/jira-project-key: \"TUN\"\n    cloudflare.com/jira-project-component: \"Cloudflare Tunnel\"\n  tags:\n    - internal\nspec:\n  type: \"service\"\n  lifecycle: \"Active\"\n  owner: \"teams/tunnel-teams-routing\"\n  cf:\n    compliance:\n      fedramp-high: \"pending\"\n      fedramp-moderate: \"yes\"\n    FIPS: \"required\"\n"
  },
  {
    "path": "cfapi/base_client.go",
    "content": "package cfapi\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\t\"golang.org/x/net/http2\"\n)\n\nconst (\n\tdefaultTimeout  = 15 * time.Second\n\tjsonContentType = \"application/json\"\n)\n\nvar (\n\tErrUnauthorized = errors.New(\"unauthorized\")\n\tErrBadRequest   = errors.New(\"incorrect request parameters\")\n\tErrNotFound     = errors.New(\"not found\")\n\tErrAPINoSuccess = errors.New(\"API call failed\")\n)\n\ntype RESTClient struct {\n\tbaseEndpoints *baseEndpoints\n\tauthToken     string\n\tuserAgent     string\n\tclient        http.Client\n\tlog           *zerolog.Logger\n}\n\ntype baseEndpoints struct {\n\taccountLevel  url.URL\n\tzoneLevel     url.URL\n\taccountRoutes url.URL\n\taccountVnets  url.URL\n}\n\nvar _ Client = (*RESTClient)(nil)\n\nfunc NewRESTClient(baseURL, accountTag, zoneTag, authToken, userAgent string, log *zerolog.Logger) (*RESTClient, error) {\n\tbaseURL = strings.TrimSuffix(baseURL, \"/\")\n\taccountLevelEndpoint, err := url.Parse(fmt.Sprintf(\"%s/accounts/%s/cfd_tunnel\", baseURL, accountTag))\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to create account level endpoint\")\n\t}\n\taccountRoutesEndpoint, err := url.Parse(fmt.Sprintf(\"%s/accounts/%s/teamnet/routes\", baseURL, accountTag))\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to create route account-level endpoint\")\n\t}\n\taccountVnetsEndpoint, err := url.Parse(fmt.Sprintf(\"%s/accounts/%s/teamnet/virtual_networks\", baseURL, accountTag))\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to create virtual network account-level endpoint\")\n\t}\n\tzoneLevelEndpoint, err := url.Parse(fmt.Sprintf(\"%s/zones/%s/tunnels\", baseURL, zoneTag))\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to create account level endpoint\")\n\t}\n\thttpTransport := http.Transport{\n\t\tTLSHandshakeTimeout:   defaultTimeout,\n\t\tResponseHeaderTimeout: defaultTimeout,\n\t}\n\t_ = http2.ConfigureTransport(&httpTransport)\n\treturn &RESTClient{\n\t\tbaseEndpoints: &baseEndpoints{\n\t\t\taccountLevel:  *accountLevelEndpoint,\n\t\t\tzoneLevel:     *zoneLevelEndpoint,\n\t\t\taccountRoutes: *accountRoutesEndpoint,\n\t\t\taccountVnets:  *accountVnetsEndpoint,\n\t\t},\n\t\tauthToken: authToken,\n\t\tuserAgent: userAgent,\n\t\tclient: http.Client{\n\t\t\tTransport: &httpTransport,\n\t\t\tTimeout:   defaultTimeout,\n\t\t},\n\t\tlog: log,\n\t}, nil\n}\n\nfunc (r *RESTClient) sendRequest(method string, url url.URL, body interface{}) (*http.Response, error) {\n\tvar bodyReader io.Reader\n\tif body != nil {\n\t\tif bodyBytes, err := json.Marshal(body); err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"failed to serialize json body\")\n\t\t} else {\n\t\t\tbodyReader = bytes.NewBuffer(bodyBytes)\n\t\t}\n\t}\n\n\treq, err := http.NewRequest(method, url.String(), bodyReader)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"can't create %s request\", method)\n\t}\n\treq.Header.Set(\"User-Agent\", r.userAgent)\n\tif bodyReader != nil {\n\t\treq.Header.Set(\"Content-Type\", jsonContentType)\n\t}\n\treq.Header.Add(\"Authorization\", fmt.Sprintf(\"Bearer %s\", r.authToken))\n\treq.Header.Add(\"Accept\", \"application/json;version=1\")\n\treturn r.client.Do(req)\n}\n\nfunc parseResponseEnvelope(reader io.Reader) (*response, error) {\n\t// Schema for Tunnelstore responses in the v1 API.\n\t// Roughly, it's a wrapper around a particular result that adds failures/errors/etc\n\tvar result response\n\t// First, parse the wrapper and check the API call succeeded\n\tif err := json.NewDecoder(reader).Decode(&result); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to decode response\")\n\t}\n\tif err := result.checkErrors(); err != nil {\n\t\treturn nil, err\n\t}\n\tif !result.Success {\n\t\treturn nil, ErrAPINoSuccess\n\t}\n\n\treturn &result, nil\n}\n\nfunc parseResponse(reader io.Reader, data interface{}) error {\n\tresult, err := parseResponseEnvelope(reader)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn parseResponseBody(result, data)\n}\n\nfunc parseResponseBody(result *response, data interface{}) error {\n\t// At this point we know the API call succeeded, so, parse out the inner\n\t// result into the datatype provided as a parameter.\n\tif err := json.Unmarshal(result.Result, &data); err != nil {\n\t\treturn errors.Wrap(err, \"the Cloudflare API response was an unexpected type\")\n\t}\n\treturn nil\n}\n\nfunc fetchExhaustively[T any](requestFn func(int) (*http.Response, error)) ([]*T, error) {\n\tpage := 0\n\tvar fullResponse []*T\n\n\tfor {\n\t\tpage += 1\n\t\tenvelope, parsedBody, err := fetchPage[T](requestFn, page)\n\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, fmt.Sprintf(\"Error Parsing page %d\", page))\n\t\t}\n\n\t\tfullResponse = append(fullResponse, parsedBody...)\n\t\tif envelope.Pagination.Count < envelope.Pagination.PerPage || len(fullResponse) >= envelope.Pagination.TotalCount {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn fullResponse, nil\n}\n\nfunc fetchPage[T any](requestFn func(int) (*http.Response, error), page int) (*response, []*T, error) {\n\tpageResp, err := requestFn(page)\n\tif err != nil {\n\t\treturn nil, nil, errors.Wrap(err, \"REST request failed\")\n\t}\n\tdefer pageResp.Body.Close()\n\tif pageResp.StatusCode == http.StatusOK {\n\t\tenvelope, err := parseResponseEnvelope(pageResp.Body)\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t\tvar parsedRspBody []*T\n\t\treturn envelope, parsedRspBody, parseResponseBody(envelope, &parsedRspBody)\n\t}\n\treturn nil, nil, errors.New(fmt.Sprintf(\"Failed to fetch page. Server returned: %d\", pageResp.StatusCode))\n}\n\ntype response struct {\n\tSuccess    bool            `json:\"success,omitempty\"`\n\tErrors     []apiError      `json:\"errors,omitempty\"`\n\tMessages   []string        `json:\"messages,omitempty\"`\n\tResult     json.RawMessage `json:\"result,omitempty\"`\n\tPagination Pagination      `json:\"result_info,omitempty\"`\n}\n\ntype Pagination struct {\n\tCount      int `json:\"count,omitempty\"`\n\tPage       int `json:\"page,omitempty\"`\n\tPerPage    int `json:\"per_page,omitempty\"`\n\tTotalCount int `json:\"total_count,omitempty\"`\n}\n\nfunc (r *response) checkErrors() error {\n\tif len(r.Errors) == 0 {\n\t\treturn nil\n\t}\n\tif len(r.Errors) == 1 {\n\t\treturn r.Errors[0]\n\t}\n\tvar messagesBuilder strings.Builder\n\tfor _, e := range r.Errors {\n\t\tmessagesBuilder.WriteString(fmt.Sprintf(\"%s; \", e))\n\t}\n\treturn fmt.Errorf(\"API errors: %s\", messagesBuilder.String())\n}\n\ntype apiError struct {\n\tCode    json.Number `json:\"code,omitempty\"`\n\tMessage string      `json:\"message,omitempty\"`\n}\n\nfunc (e apiError) Error() string {\n\treturn fmt.Sprintf(\"code: %v, reason: %s\", e.Code, e.Message)\n}\n\nfunc (r *RESTClient) statusCodeToError(op string, resp *http.Response) error {\n\tif resp.Header.Get(\"Content-Type\") == \"application/json\" {\n\t\tvar errorsResp response\n\t\tif json.NewDecoder(resp.Body).Decode(&errorsResp) == nil {\n\t\t\tif err := errorsResp.checkErrors(); err != nil {\n\t\t\t\treturn errors.Errorf(\"Failed to %s: %s\", op, err)\n\t\t\t}\n\t\t}\n\t}\n\n\tswitch resp.StatusCode {\n\tcase http.StatusOK:\n\t\treturn nil\n\tcase http.StatusBadRequest:\n\t\treturn ErrBadRequest\n\tcase http.StatusUnauthorized, http.StatusForbidden:\n\t\treturn ErrUnauthorized\n\tcase http.StatusNotFound:\n\t\treturn ErrNotFound\n\t}\n\treturn errors.Errorf(\"API call to %s failed with status %d: %s\", op,\n\t\tresp.StatusCode, http.StatusText(resp.StatusCode))\n}\n"
  },
  {
    "path": "cfapi/client.go",
    "content": "package cfapi\n\nimport (\n\t\"github.com/google/uuid\"\n)\n\ntype TunnelClient interface {\n\tCreateTunnel(name string, tunnelSecret []byte) (*TunnelWithToken, error)\n\tGetTunnel(tunnelID uuid.UUID) (*Tunnel, error)\n\tGetTunnelToken(tunnelID uuid.UUID) (string, error)\n\tGetManagementToken(tunnelID uuid.UUID, resource ManagementResource) (string, error)\n\tDeleteTunnel(tunnelID uuid.UUID, cascade bool) error\n\tListTunnels(filter *TunnelFilter) ([]*Tunnel, error)\n\tListActiveClients(tunnelID uuid.UUID) ([]*ActiveClient, error)\n\tCleanupConnections(tunnelID uuid.UUID, params *CleanupParams) error\n}\n\ntype HostnameClient interface {\n\tRouteTunnel(tunnelID uuid.UUID, route HostnameRoute) (HostnameRouteResult, error)\n}\n\ntype IPRouteClient interface {\n\tListRoutes(filter *IpRouteFilter) ([]*DetailedRoute, error)\n\tAddRoute(newRoute NewRoute) (Route, error)\n\tDeleteRoute(id uuid.UUID) error\n\tGetByIP(params GetRouteByIpParams) (DetailedRoute, error)\n}\n\ntype VnetClient interface {\n\tCreateVirtualNetwork(newVnet NewVirtualNetwork) (VirtualNetwork, error)\n\tListVirtualNetworks(filter *VnetFilter) ([]*VirtualNetwork, error)\n\tDeleteVirtualNetwork(id uuid.UUID, force bool) error\n\tUpdateVirtualNetwork(id uuid.UUID, updates UpdateVirtualNetwork) error\n}\n\ntype Client interface {\n\tTunnelClient\n\tHostnameClient\n\tIPRouteClient\n\tVnetClient\n}\n"
  },
  {
    "path": "cfapi/hostname.go",
    "content": "package cfapi\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"path\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/pkg/errors\"\n)\n\ntype Change = string\n\nconst (\n\tChangeNew       = \"new\"\n\tChangeUpdated   = \"updated\"\n\tChangeUnchanged = \"unchanged\"\n)\n\n// HostnameRoute represents a record type that can route to a tunnel\ntype HostnameRoute interface {\n\tjson.Marshaler\n\tRecordType() string\n\tUnmarshalResult(body io.Reader) (HostnameRouteResult, error)\n\tString() string\n}\n\ntype HostnameRouteResult interface {\n\t// SuccessSummary explains what will route to this tunnel when it's provisioned successfully\n\tSuccessSummary() string\n}\n\ntype DNSRoute struct {\n\tuserHostname      string\n\toverwriteExisting bool\n}\n\ntype DNSRouteResult struct {\n\troute *DNSRoute\n\tCName Change `json:\"cname\"`\n\tName  string `json:\"name\"`\n}\n\nfunc NewDNSRoute(userHostname string, overwriteExisting bool) HostnameRoute {\n\treturn &DNSRoute{\n\t\tuserHostname:      userHostname,\n\t\toverwriteExisting: overwriteExisting,\n\t}\n}\n\nfunc (dr *DNSRoute) MarshalJSON() ([]byte, error) {\n\ts := struct {\n\t\tType              string `json:\"type\"`\n\t\tUserHostname      string `json:\"user_hostname\"`\n\t\tOverwriteExisting bool   `json:\"overwrite_existing\"`\n\t}{\n\t\tType:              dr.RecordType(),\n\t\tUserHostname:      dr.userHostname,\n\t\tOverwriteExisting: dr.overwriteExisting,\n\t}\n\treturn json.Marshal(&s)\n}\n\nfunc (dr *DNSRoute) UnmarshalResult(body io.Reader) (HostnameRouteResult, error) {\n\tvar result DNSRouteResult\n\terr := parseResponse(body, &result)\n\tresult.route = dr\n\treturn &result, err\n}\n\nfunc (dr *DNSRoute) RecordType() string {\n\treturn \"dns\"\n}\n\nfunc (dr *DNSRoute) String() string {\n\treturn fmt.Sprintf(\"%s %s\", dr.RecordType(), dr.userHostname)\n}\n\nfunc (res *DNSRouteResult) SuccessSummary() string {\n\tvar msgFmt string\n\tswitch res.CName {\n\tcase ChangeNew:\n\t\tmsgFmt = \"Added CNAME %s which will route to this tunnel\"\n\tcase ChangeUpdated: // this is not currently returned by tunnelsore\n\t\tmsgFmt = \"%s updated to route to your tunnel\"\n\tcase ChangeUnchanged:\n\t\tmsgFmt = \"%s is already configured to route to your tunnel\"\n\t}\n\treturn fmt.Sprintf(msgFmt, res.hostname())\n}\n\n// hostname yields the resulting name for the DNS route; if that is not available from Cloudflare API, then the\n// requested name is returned instead (should not be the common path, it is just a fall-back).\nfunc (res *DNSRouteResult) hostname() string {\n\tif res.Name != \"\" {\n\t\treturn res.Name\n\t}\n\treturn res.route.userHostname\n}\n\ntype LBRoute struct {\n\tlbName string\n\tlbPool string\n}\n\ntype LBRouteResult struct {\n\troute        *LBRoute\n\tLoadBalancer Change `json:\"load_balancer\"`\n\tPool         Change `json:\"pool\"`\n}\n\nfunc NewLBRoute(lbName, lbPool string) HostnameRoute {\n\treturn &LBRoute{\n\t\tlbName: lbName,\n\t\tlbPool: lbPool,\n\t}\n}\n\nfunc (lr *LBRoute) MarshalJSON() ([]byte, error) {\n\ts := struct {\n\t\tType   string `json:\"type\"`\n\t\tLBName string `json:\"lb_name\"`\n\t\tLBPool string `json:\"lb_pool\"`\n\t}{\n\t\tType:   lr.RecordType(),\n\t\tLBName: lr.lbName,\n\t\tLBPool: lr.lbPool,\n\t}\n\treturn json.Marshal(&s)\n}\n\nfunc (lr *LBRoute) RecordType() string {\n\treturn \"lb\"\n}\n\nfunc (lb *LBRoute) String() string {\n\treturn fmt.Sprintf(\"%s %s %s\", lb.RecordType(), lb.lbName, lb.lbPool)\n}\n\nfunc (lr *LBRoute) UnmarshalResult(body io.Reader) (HostnameRouteResult, error) {\n\tvar result LBRouteResult\n\terr := parseResponse(body, &result)\n\tresult.route = lr\n\treturn &result, err\n}\n\nfunc (res *LBRouteResult) SuccessSummary() string {\n\tvar msg string\n\tswitch res.LoadBalancer + \",\" + res.Pool {\n\tcase \"new,new\":\n\t\tmsg = \"Created load balancer %s and added a new pool %s with this tunnel as an origin\"\n\tcase \"new,updated\":\n\t\tmsg = \"Created load balancer %s with an existing pool %s which was updated to use this tunnel as an origin\"\n\tcase \"new,unchanged\":\n\t\tmsg = \"Created load balancer %s with an existing pool %s which already has this tunnel as an origin\"\n\tcase \"updated,new\":\n\t\tmsg = \"Added new pool %[2]s with this tunnel as an origin to load balancer %[1]s\"\n\tcase \"updated,updated\":\n\t\tmsg = \"Updated pool %[2]s to use this tunnel as an origin and added it to load balancer %[1]s\"\n\tcase \"updated,unchanged\":\n\t\tmsg = \"Added pool %[2]s, which already has this tunnel as an origin, to load balancer %[1]s\"\n\tcase \"unchanged,updated\":\n\t\tmsg = \"Added this tunnel as an origin in pool %[2]s which is already used by load balancer %[1]s\"\n\tcase \"unchanged,unchanged\":\n\t\tmsg = \"Load balancer %s already uses pool %s which has this tunnel as an origin\"\n\tcase \"unchanged,new\":\n\t\t// this state is not possible\n\t\tfallthrough\n\tdefault:\n\t\tmsg = \"Something went wrong: failed to modify load balancer %s with pool %s; please check traffic manager configuration in the dashboard\"\n\t}\n\n\treturn fmt.Sprintf(msg, res.route.lbName, res.route.lbPool)\n}\n\nfunc (r *RESTClient) RouteTunnel(tunnelID uuid.UUID, route HostnameRoute) (HostnameRouteResult, error) {\n\tendpoint := r.baseEndpoints.zoneLevel\n\tendpoint.Path = path.Join(endpoint.Path, fmt.Sprintf(\"%v/routes\", tunnelID))\n\tresp, err := r.sendRequest(\"PUT\", endpoint, route)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"REST request failed\")\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode == http.StatusOK {\n\t\treturn route.UnmarshalResult(resp.Body)\n\t}\n\n\treturn nil, r.statusCodeToError(\"add route\", resp)\n}\n"
  },
  {
    "path": "cfapi/hostname_test.go",
    "content": "package cfapi\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestDNSRouteUnmarshalResult(t *testing.T) {\n\troute := &DNSRoute{\n\t\tuserHostname: \"example.com\",\n\t}\n\n\tresult, err := route.UnmarshalResult(strings.NewReader(`{\"success\": true, \"result\": {\"cname\": \"new\"}}`))\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, &DNSRouteResult{\n\t\troute: route,\n\t\tCName: ChangeNew,\n\t}, result)\n\n\tbadJSON := []string{\n\t\t`abc`,\n\t\t`{\"success\": false, \"result\": {\"cname\": \"new\"}}`,\n\t\t`{\"errors\": [{\"code\": 1003, \"message\":\"An A, AAAA or CNAME record already exists with that host\"}], \"result\": {\"cname\": \"new\"}}`,\n\t\t`{\"errors\": [{\"code\": 1003, \"message\":\"An A, AAAA or CNAME record already exists with that host\"}, {\"code\": 1004, \"message\":\"Cannot use tunnel as origin for non-proxied load balancer\"}], \"result\": {\"cname\": \"new\"}}`,\n\t\t`{\"result\": {\"cname\": \"new\"}}`,\n\t\t`{\"result\": {\"cname\": \"new\"}}`,\n\t}\n\n\tfor _, j := range badJSON {\n\t\t_, err = route.UnmarshalResult(strings.NewReader(j))\n\t\tassert.NotNil(t, err)\n\t}\n}\n\nfunc TestLBRouteUnmarshalResult(t *testing.T) {\n\troute := &LBRoute{\n\t\tlbName: \"lb.example.com\",\n\t\tlbPool: \"pool\",\n\t}\n\n\tresult, err := route.UnmarshalResult(strings.NewReader(`{\"success\": true, \"result\": {\"pool\": \"unchanged\", \"load_balancer\": \"updated\"}}`))\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, &LBRouteResult{\n\t\troute:        route,\n\t\tLoadBalancer: ChangeUpdated,\n\t\tPool:         ChangeUnchanged,\n\t}, result)\n\n\tbadJSON := []string{\n\t\t`abc`,\n\t\t`{\"success\": false, \"result\": {\"pool\": \"unchanged\", \"load_balancer\": \"updated\"}}`,\n\t\t`{\"errors\": [{\"code\": 1003, \"message\":\"An A, AAAA or CNAME record already exists with that host\"}], \"result\": {\"pool\": \"unchanged\", \"load_balancer\": \"updated\"}}`,\n\t\t`{\"errors\": [{\"code\": 1003, \"message\":\"An A, AAAA or CNAME record already exists with that host\"}, {\"code\": 1004, \"message\":\"Cannot use tunnel as origin for non-proxied load balancer\"}], \"result\": {\"pool\": \"unchanged\", \"load_balancer\": \"updated\"}}`,\n\t\t`{\"result\": {\"pool\": \"unchanged\", \"load_balancer\": \"updated\"}}`,\n\t}\n\n\tfor _, j := range badJSON {\n\t\t_, err = route.UnmarshalResult(strings.NewReader(j))\n\t\tassert.NotNil(t, err)\n\t}\n}\n\nfunc TestLBRouteResultSuccessSummary(t *testing.T) {\n\troute := &LBRoute{\n\t\tlbName: \"lb.example.com\",\n\t\tlbPool: \"POOL\",\n\t}\n\n\ttests := []struct {\n\t\tlb       Change\n\t\tpool     Change\n\t\texpected string\n\t}{\n\t\t{ChangeNew, ChangeNew, \"Created load balancer lb.example.com and added a new pool POOL with this tunnel as an origin\"},\n\t\t{ChangeNew, ChangeUpdated, \"Created load balancer lb.example.com with an existing pool POOL which was updated to use this tunnel as an origin\"},\n\t\t{ChangeNew, ChangeUnchanged, \"Created load balancer lb.example.com with an existing pool POOL which already has this tunnel as an origin\"},\n\t\t{ChangeUpdated, ChangeNew, \"Added new pool POOL with this tunnel as an origin to load balancer lb.example.com\"},\n\t\t{ChangeUpdated, ChangeUpdated, \"Updated pool POOL to use this tunnel as an origin and added it to load balancer lb.example.com\"},\n\t\t{ChangeUpdated, ChangeUnchanged, \"Added pool POOL, which already has this tunnel as an origin, to load balancer lb.example.com\"},\n\t\t{ChangeUnchanged, ChangeNew, \"Something went wrong: failed to modify load balancer lb.example.com with pool POOL; please check traffic manager configuration in the dashboard\"},\n\t\t{ChangeUnchanged, ChangeUpdated, \"Added this tunnel as an origin in pool POOL which is already used by load balancer lb.example.com\"},\n\t\t{ChangeUnchanged, ChangeUnchanged, \"Load balancer lb.example.com already uses pool POOL which has this tunnel as an origin\"},\n\t\t{\"\", \"\", \"Something went wrong: failed to modify load balancer lb.example.com with pool POOL; please check traffic manager configuration in the dashboard\"},\n\t\t{\"a\", \"b\", \"Something went wrong: failed to modify load balancer lb.example.com with pool POOL; please check traffic manager configuration in the dashboard\"},\n\t}\n\tfor i, tt := range tests {\n\t\tres := &LBRouteResult{\n\t\t\troute:        route,\n\t\t\tLoadBalancer: tt.lb,\n\t\t\tPool:         tt.pool,\n\t\t}\n\t\tactual := res.SuccessSummary()\n\t\tassert.Equal(t, tt.expected, actual, \"case %d\", i+1)\n\t}\n}\n"
  },
  {
    "path": "cfapi/ip_route.go",
    "content": "package cfapi\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"path\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/pkg/errors\"\n)\n\n// Route is a mapping from customer's IP space to a tunnel.\n// Each route allows the customer to route eyeballs in their corporate network\n// to certain private IP ranges. Each Route represents an IP range in their\n// network, and says that eyeballs can reach that route using the corresponding\n// tunnel.\ntype Route struct {\n\tNetwork  CIDR      `json:\"network\"`\n\tTunnelID uuid.UUID `json:\"tunnel_id\"`\n\t// Optional field. When unset, it means the Route belongs to the default virtual network.\n\tVNetID    *uuid.UUID `json:\"virtual_network_id,omitempty\"`\n\tComment   string     `json:\"comment\"`\n\tCreatedAt time.Time  `json:\"created_at\"`\n\tDeletedAt time.Time  `json:\"deleted_at\"`\n}\n\n// CIDR is just a newtype wrapper around net.IPNet. It adds JSON unmarshalling.\ntype CIDR net.IPNet\n\nfunc (c CIDR) String() string {\n\tn := net.IPNet(c)\n\treturn n.String()\n}\n\nfunc (c CIDR) MarshalJSON() ([]byte, error) {\n\tstr := c.String()\n\tjson, err := json.Marshal(str)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"error serializing CIDR into JSON\")\n\t}\n\treturn json, nil\n}\n\n// UnmarshalJSON parses a JSON string into net.IPNet\nfunc (c *CIDR) UnmarshalJSON(data []byte) error {\n\tvar s string\n\tif err := json.Unmarshal(data, &s); err != nil {\n\t\treturn errors.Wrap(err, \"error parsing cidr string\")\n\t}\n\t_, network, err := net.ParseCIDR(s)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"error parsing invalid network from backend\")\n\t}\n\tif network == nil {\n\t\treturn fmt.Errorf(\"backend returned invalid network %s\", s)\n\t}\n\t*c = CIDR(*network)\n\treturn nil\n}\n\n// NewRoute has all the parameters necessary to add a new route to the table.\ntype NewRoute struct {\n\tNetwork  net.IPNet\n\tTunnelID uuid.UUID\n\tComment  string\n\t// Optional field. If unset, backend will assume the default vnet for the account.\n\tVNetID *uuid.UUID\n}\n\n// MarshalJSON handles fields with non-JSON types (e.g. net.IPNet).\nfunc (r NewRoute) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(&struct {\n\t\tNetwork  string     `json:\"network\"`\n\t\tTunnelID uuid.UUID  `json:\"tunnel_id\"`\n\t\tComment  string     `json:\"comment\"`\n\t\tVNetID   *uuid.UUID `json:\"virtual_network_id,omitempty\"`\n\t}{\n\t\tNetwork:  r.Network.String(),\n\t\tTunnelID: r.TunnelID,\n\t\tComment:  r.Comment,\n\t\tVNetID:   r.VNetID,\n\t})\n}\n\n// DetailedRoute is just a Route with some extra fields, e.g. TunnelName.\ntype DetailedRoute struct {\n\tID       uuid.UUID `json:\"id\"`\n\tNetwork  CIDR      `json:\"network\"`\n\tTunnelID uuid.UUID `json:\"tunnel_id\"`\n\t// Optional field. When unset, it means the DetailedRoute belongs to the default virtual network.\n\tVNetID     *uuid.UUID `json:\"virtual_network_id,omitempty\"`\n\tComment    string     `json:\"comment\"`\n\tCreatedAt  time.Time  `json:\"created_at\"`\n\tDeletedAt  time.Time  `json:\"deleted_at\"`\n\tTunnelName string     `json:\"tunnel_name\"`\n}\n\n// IsZero checks if DetailedRoute is the zero value.\nfunc (r *DetailedRoute) IsZero() bool {\n\treturn r.TunnelID == uuid.Nil\n}\n\n// TableString outputs a table row summarizing the route, to be used\n// when showing the user their routing table.\nfunc (r DetailedRoute) TableString() string {\n\tdeletedColumn := \"-\"\n\tif !r.DeletedAt.IsZero() {\n\t\tdeletedColumn = r.DeletedAt.Format(time.RFC3339)\n\t}\n\tvnetColumn := \"default\"\n\tif r.VNetID != nil {\n\t\tvnetColumn = r.VNetID.String()\n\t}\n\n\treturn fmt.Sprintf(\n\t\t\"%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t\",\n\t\tr.ID,\n\t\tr.Network.String(),\n\t\tvnetColumn,\n\t\tr.Comment,\n\t\tr.TunnelID,\n\t\tr.TunnelName,\n\t\tr.CreatedAt.Format(time.RFC3339),\n\t\tdeletedColumn,\n\t)\n}\n\ntype GetRouteByIpParams struct {\n\tIp net.IP\n\t// Optional field. If unset, backend will assume the default vnet for the account.\n\tVNetID *uuid.UUID\n}\n\n// ListRoutes calls the Tunnelstore GET endpoint for all routes under an account.\n// Due to pagination on the server side it will call the endpoint multiple times if needed.\nfunc (r *RESTClient) ListRoutes(filter *IpRouteFilter) ([]*DetailedRoute, error) {\n\tfetchFn := func(page int) (*http.Response, error) {\n\t\tendpoint := r.baseEndpoints.accountRoutes\n\t\tfilter.Page(page)\n\t\tendpoint.RawQuery = filter.Encode()\n\t\trsp, err := r.sendRequest(\"GET\", endpoint, nil)\n\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"REST request failed\")\n\t\t}\n\t\tif rsp.StatusCode != http.StatusOK {\n\t\t\trsp.Body.Close()\n\t\t\treturn nil, r.statusCodeToError(\"list routes\", rsp)\n\t\t}\n\t\treturn rsp, nil\n\t}\n\treturn fetchExhaustively[DetailedRoute](fetchFn)\n}\n\n// AddRoute calls the Tunnelstore POST endpoint for a given route.\nfunc (r *RESTClient) AddRoute(newRoute NewRoute) (Route, error) {\n\tendpoint := r.baseEndpoints.accountRoutes\n\tendpoint.Path = path.Join(endpoint.Path)\n\tresp, err := r.sendRequest(\"POST\", endpoint, newRoute)\n\tif err != nil {\n\t\treturn Route{}, errors.Wrap(err, \"REST request failed\")\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode == http.StatusOK {\n\t\treturn parseRoute(resp.Body)\n\t}\n\n\treturn Route{}, r.statusCodeToError(\"add route\", resp)\n}\n\n// DeleteRoute calls the Tunnelstore DELETE endpoint for a given route.\nfunc (r *RESTClient) DeleteRoute(id uuid.UUID) error {\n\tendpoint := r.baseEndpoints.accountRoutes\n\tendpoint.Path = path.Join(endpoint.Path, url.PathEscape(id.String()))\n\n\tresp, err := r.sendRequest(\"DELETE\", endpoint, nil)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"REST request failed\")\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode == http.StatusOK {\n\t\t_, err := parseRoute(resp.Body)\n\t\treturn err\n\t}\n\n\treturn r.statusCodeToError(\"delete route\", resp)\n}\n\n// GetByIP checks which route will proxy a given IP.\nfunc (r *RESTClient) GetByIP(params GetRouteByIpParams) (DetailedRoute, error) {\n\tendpoint := r.baseEndpoints.accountRoutes\n\tendpoint.Path = path.Join(endpoint.Path, \"ip\", url.PathEscape(params.Ip.String()))\n\tsetVnetParam(&endpoint, params.VNetID)\n\n\tresp, err := r.sendRequest(\"GET\", endpoint, nil)\n\tif err != nil {\n\t\treturn DetailedRoute{}, errors.Wrap(err, \"REST request failed\")\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode == http.StatusOK {\n\t\treturn parseDetailedRoute(resp.Body)\n\t}\n\n\treturn DetailedRoute{}, r.statusCodeToError(\"get route by IP\", resp)\n}\n\nfunc parseRoute(body io.ReadCloser) (Route, error) {\n\tvar route Route\n\terr := parseResponse(body, &route)\n\treturn route, err\n}\n\nfunc parseDetailedRoute(body io.ReadCloser) (DetailedRoute, error) {\n\tvar route DetailedRoute\n\terr := parseResponse(body, &route)\n\treturn route, err\n}\n\n// setVnetParam overwrites the URL's query parameters with a query param to scope the HostnameRoute action to a certain\n// virtual network (if one is provided).\nfunc setVnetParam(endpoint *url.URL, vnetID *uuid.UUID) {\n\tqueryParams := url.Values{}\n\tif vnetID != nil {\n\t\tqueryParams.Set(\"virtual_network_id\", vnetID.String())\n\t}\n\tendpoint.RawQuery = queryParams.Encode()\n}\n"
  },
  {
    "path": "cfapi/ip_route_filter.go",
    "content": "package cfapi\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"net/url\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/urfave/cli/v2\"\n)\n\nvar (\n\tfilterIpRouteDeleted = cli.BoolFlag{\n\t\tName:  \"filter-is-deleted\",\n\t\tUsage: \"If false (default), only show non-deleted routes. If true, only show deleted routes.\",\n\t}\n\tfilterIpRouteTunnelID = cli.StringFlag{\n\t\tName:  \"filter-tunnel-id\",\n\t\tUsage: \"Show only routes with the given tunnel ID.\",\n\t}\n\tfilterSubsetIpRoute = cli.StringFlag{\n\t\tName:    \"filter-network-is-subset-of\",\n\t\tAliases: []string{\"nsub\"},\n\t\tUsage:   \"Show only routes whose network is a subset of the given network.\",\n\t}\n\tfilterSupersetIpRoute = cli.StringFlag{\n\t\tName:    \"filter-network-is-superset-of\",\n\t\tAliases: []string{\"nsup\"},\n\t\tUsage:   \"Show only routes whose network is a superset of the given network.\",\n\t}\n\tfilterIpRouteComment = cli.StringFlag{\n\t\tName:  \"filter-comment-is\",\n\t\tUsage: \"Show only routes with this comment.\",\n\t}\n\tfilterIpRouteByVnet = cli.StringFlag{\n\t\tName:  \"filter-vnet-id\",\n\t\tUsage: \"Show only routes that are attached to the given virtual network ID.\",\n\t}\n\n\t// Flags contains all filter flags.\n\tIpRouteFilterFlags = []cli.Flag{\n\t\t&filterIpRouteDeleted,\n\t\t&filterIpRouteTunnelID,\n\t\t&filterSubsetIpRoute,\n\t\t&filterSupersetIpRoute,\n\t\t&filterIpRouteComment,\n\t\t&filterIpRouteByVnet,\n\t}\n)\n\n// IpRouteFilter which routes get queried.\ntype IpRouteFilter struct {\n\tqueryParams url.Values\n}\n\n// NewIpRouteFilterFromCLI parses CLI flags to discover which filters should get applied.\nfunc NewIpRouteFilterFromCLI(c *cli.Context) (*IpRouteFilter, error) {\n\tf := NewIPRouteFilter()\n\n\t// Set deletion filter\n\tif flag := filterIpRouteDeleted.Name; c.IsSet(flag) && c.Bool(flag) {\n\t\tf.Deleted()\n\t} else {\n\t\tf.NotDeleted()\n\t}\n\n\tif subset, err := cidrFromFlag(c, filterSubsetIpRoute); err != nil {\n\t\treturn nil, err\n\t} else if subset != nil {\n\t\tf.NetworkIsSupersetOf(*subset)\n\t}\n\n\tif superset, err := cidrFromFlag(c, filterSupersetIpRoute); err != nil {\n\t\treturn nil, err\n\t} else if superset != nil {\n\t\tf.NetworkIsSupersetOf(*superset)\n\t}\n\n\tif comment := c.String(filterIpRouteComment.Name); comment != \"\" {\n\t\tf.CommentIs(comment)\n\t}\n\n\tif tunnelID := c.String(filterIpRouteTunnelID.Name); tunnelID != \"\" {\n\t\tu, err := uuid.Parse(tunnelID)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrapf(err, \"Couldn't parse UUID from %s\", filterIpRouteTunnelID.Name)\n\t\t}\n\t\tf.TunnelID(u)\n\t}\n\n\tif vnetId := c.String(filterIpRouteByVnet.Name); vnetId != \"\" {\n\t\tu, err := uuid.Parse(vnetId)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrapf(err, \"Couldn't parse UUID from %s\", filterIpRouteByVnet.Name)\n\t\t}\n\t\tf.VNetID(u)\n\t}\n\n\tif maxFetch := c.Int(\"max-fetch-size\"); maxFetch > 0 {\n\t\tf.MaxFetchSize(uint(maxFetch))\n\t}\n\n\treturn f, nil\n}\n\n// Parses a CIDR from the flag. If the flag was unset, returns (nil, nil).\nfunc cidrFromFlag(c *cli.Context, flag cli.StringFlag) (*net.IPNet, error) {\n\tif !c.IsSet(flag.Name) {\n\t\treturn nil, nil\n\t}\n\n\t_, subset, err := net.ParseCIDR(c.String(flag.Name))\n\tif err != nil {\n\t\treturn nil, err\n\t} else if subset == nil {\n\t\treturn nil, fmt.Errorf(\"Invalid CIDR supplied for %s\", flag.Name)\n\t}\n\n\treturn subset, nil\n}\n\nfunc NewIPRouteFilter() *IpRouteFilter {\n\tvalues := &IpRouteFilter{queryParams: url.Values{}}\n\n\t// always list cfd_tunnel routes only\n\tvalues.queryParams.Set(\"tun_types\", \"cfd_tunnel\")\n\n\treturn values\n}\n\nfunc (f *IpRouteFilter) CommentIs(comment string) {\n\tf.queryParams.Set(\"comment\", comment)\n}\n\nfunc (f *IpRouteFilter) NotDeleted() {\n\tf.queryParams.Set(\"is_deleted\", \"false\")\n}\n\nfunc (f *IpRouteFilter) Deleted() {\n\tf.queryParams.Set(\"is_deleted\", \"true\")\n}\n\nfunc (f *IpRouteFilter) NetworkIsSubsetOf(superset net.IPNet) {\n\tf.queryParams.Set(\"network_subset\", superset.String())\n}\n\nfunc (f *IpRouteFilter) NetworkIsSupersetOf(subset net.IPNet) {\n\tf.queryParams.Set(\"network_superset\", subset.String())\n}\n\nfunc (f *IpRouteFilter) ExistedAt(existedAt time.Time) {\n\tf.queryParams.Set(\"existed_at\", existedAt.Format(time.RFC3339))\n}\n\nfunc (f *IpRouteFilter) TunnelID(id uuid.UUID) {\n\tf.queryParams.Set(\"tunnel_id\", id.String())\n}\n\nfunc (f *IpRouteFilter) VNetID(id uuid.UUID) {\n\tf.queryParams.Set(\"virtual_network_id\", id.String())\n}\n\nfunc (f *IpRouteFilter) MaxFetchSize(max uint) {\n\tf.queryParams.Set(\"per_page\", strconv.Itoa(int(max)))\n}\n\nfunc (f *IpRouteFilter) Page(page int) {\n\tf.queryParams.Set(\"page\", strconv.Itoa(page))\n}\n\nfunc (f IpRouteFilter) Encode() string {\n\treturn f.queryParams.Encode()\n}\n"
  },
  {
    "path": "cfapi/ip_route_test.go",
    "content": "package cfapi\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestUnmarshalRoute(t *testing.T) {\n\ttestCases := []struct {\n\t\tJson    string\n\t\tHasVnet bool\n\t}{\n\t\t{\n\t\t\t`{\n\t\t\t\t\"network\":\"10.1.2.40/29\",\n\t\t\t\t\"tunnel_id\":\"fba6ffea-807f-4e7a-a740-4184ee1b82c8\",\n\t\t\t\t\"comment\":\"test\",\n\t\t\t\t\"created_at\":\"2020-12-22T02:00:15.587008Z\",\n\t\t\t\t\"deleted_at\":null\n\t\t\t}`,\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\t`{\n\t\t\t\t\"network\":\"10.1.2.40/29\",\n\t\t\t\t\"tunnel_id\":\"fba6ffea-807f-4e7a-a740-4184ee1b82c8\",\n\t\t\t\t\"comment\":\"test\",\n\t\t\t\t\"created_at\":\"2020-12-22T02:00:15.587008Z\",\n\t\t\t\t\"deleted_at\":null,\n\t\t\t\t\"virtual_network_id\":\"38c95083-8191-4110-8339-3f438d44fdb9\"\n\t\t\t}`,\n\t\t\ttrue,\n\t\t},\n\t}\n\n\tfor _, testCase := range testCases {\n\t\tdata := testCase.Json\n\n\t\tvar r Route\n\t\terr := json.Unmarshal([]byte(data), &r)\n\n\t\t// Check everything worked\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, uuid.MustParse(\"fba6ffea-807f-4e7a-a740-4184ee1b82c8\"), r.TunnelID)\n\t\trequire.Equal(t, \"test\", r.Comment)\n\t\t_, cidr, err := net.ParseCIDR(\"10.1.2.40/29\")\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, CIDR(*cidr), r.Network)\n\t\trequire.Equal(t, \"test\", r.Comment)\n\n\t\tif testCase.HasVnet {\n\t\t\trequire.Equal(t, uuid.MustParse(\"38c95083-8191-4110-8339-3f438d44fdb9\"), *r.VNetID)\n\t\t} else {\n\t\t\trequire.Nil(t, r.VNetID)\n\t\t}\n\t}\n}\n\nfunc TestDetailedRouteJsonRoundtrip(t *testing.T) {\n\ttestCases := []struct {\n\t\tJson    string\n\t\tHasVnet bool\n\t}{\n\t\t{\n\t\t\t`{\n\t\t\t\t\"id\":\"91ebc578-cc99-4641-9937-0fb630505fa0\",\n\t\t\t\t\"network\":\"10.1.2.40/29\",\n\t\t\t\t\"tunnel_id\":\"fba6ffea-807f-4e7a-a740-4184ee1b82c8\",\n\t\t\t\t\"comment\":\"test\",\n\t\t\t\t\"created_at\":\"2020-12-22T02:00:15.587008Z\",\n\t\t\t\t\"deleted_at\":\"2021-01-14T05:01:42.183002Z\",\n\t\t\t\t\"tunnel_name\":\"Mr. Tun\"\n\t\t\t}`,\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\t`{\n\t\t\t\t\"id\":\"91ebc578-cc99-4641-9937-0fb630505fa0\",\n\t\t\t\t\"network\":\"10.1.2.40/29\",\n\t\t\t\t\"tunnel_id\":\"fba6ffea-807f-4e7a-a740-4184ee1b82c8\",\n\t\t\t\t\"virtual_network_id\":\"38c95083-8191-4110-8339-3f438d44fdb9\",\n\t\t\t\t\"comment\":\"test\",\n\t\t\t\t\"created_at\":\"2020-12-22T02:00:15.587008Z\",\n\t\t\t\t\"deleted_at\":\"2021-01-14T05:01:42.183002Z\",\n\t\t\t\t\"tunnel_name\":\"Mr. Tun\"\n\t\t\t}`,\n\t\t\ttrue,\n\t\t},\n\t}\n\n\tfor _, testCase := range testCases {\n\t\tdata := testCase.Json\n\n\t\tvar r DetailedRoute\n\t\terr := json.Unmarshal([]byte(data), &r)\n\n\t\t// Check everything worked\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, uuid.MustParse(\"fba6ffea-807f-4e7a-a740-4184ee1b82c8\"), r.TunnelID)\n\t\trequire.Equal(t, \"test\", r.Comment)\n\t\t_, cidr, err := net.ParseCIDR(\"10.1.2.40/29\")\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, CIDR(*cidr), r.Network)\n\t\trequire.Equal(t, \"test\", r.Comment)\n\t\trequire.Equal(t, \"Mr. Tun\", r.TunnelName)\n\n\t\tif testCase.HasVnet {\n\t\t\trequire.Equal(t, uuid.MustParse(\"38c95083-8191-4110-8339-3f438d44fdb9\"), *r.VNetID)\n\t\t} else {\n\t\t\trequire.Nil(t, r.VNetID)\n\t\t}\n\n\t\tbytes, err := json.Marshal(r)\n\t\trequire.NoError(t, err)\n\t\tobtainedJson := string(bytes)\n\t\tdata = strings.Replace(data, \"\\t\", \"\", -1)\n\t\tdata = strings.Replace(data, \"\\n\", \"\", -1)\n\t\trequire.Equal(t, data, obtainedJson)\n\t}\n}\n\nfunc TestMarshalNewRoute(t *testing.T) {\n\t_, network, err := net.ParseCIDR(\"1.2.3.4/32\")\n\trequire.NoError(t, err)\n\trequire.NotNil(t, network)\n\tvnetId := uuid.New()\n\n\tnewRoutes := []NewRoute{\n\t\t{\n\t\t\tNetwork:  *network,\n\t\t\tTunnelID: uuid.New(),\n\t\t\tComment:  \"hi\",\n\t\t},\n\t\t{\n\t\t\tNetwork:  *network,\n\t\t\tTunnelID: uuid.New(),\n\t\t\tComment:  \"hi\",\n\t\t\tVNetID:   &vnetId,\n\t\t},\n\t}\n\n\tfor _, newRoute := range newRoutes {\n\t\t// Test where receiver is struct\n\t\tserialized, err := json.Marshal(newRoute)\n\t\trequire.NoError(t, err)\n\t\trequire.True(t, strings.Contains(string(serialized), \"tunnel_id\"))\n\n\t\t// Test where receiver is pointer to struct\n\t\tserialized, err = json.Marshal(&newRoute)\n\t\trequire.NoError(t, err)\n\t\trequire.True(t, strings.Contains(string(serialized), \"tunnel_id\"))\n\n\t\tif newRoute.VNetID == nil {\n\t\t\trequire.False(t, strings.Contains(string(serialized), \"virtual_network_id\"))\n\t\t} else {\n\t\t\trequire.True(t, strings.Contains(string(serialized), \"virtual_network_id\"))\n\t\t}\n\t}\n}\n\nfunc TestRouteTableString(t *testing.T) {\n\t_, network, err := net.ParseCIDR(\"1.2.3.4/32\")\n\trequire.NoError(t, err)\n\trequire.NotNil(t, network)\n\tr := DetailedRoute{\n\t\tID:      uuid.Nil,\n\t\tNetwork: CIDR(*network),\n\t}\n\trow := r.TableString()\n\tfmt.Println(row)\n\trequire.True(t, strings.HasPrefix(row, \"00000000-0000-0000-0000-000000000000\\t1.2.3.4/32\"))\n}\n"
  },
  {
    "path": "cfapi/tunnel.go",
    "content": "package cfapi\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"path\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/pkg/errors\"\n)\n\nvar ErrTunnelNameConflict = errors.New(\"tunnel with name already exists\")\n\ntype ManagementResource int\n\nconst (\n\tLogs ManagementResource = iota\n\tAdmin\n\tHostDetails\n)\n\nfunc (r ManagementResource) String() string {\n\tswitch r {\n\tcase Logs:\n\t\treturn \"logs\"\n\tcase Admin:\n\t\treturn \"admin\"\n\tcase HostDetails:\n\t\treturn \"host_details\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\ntype Tunnel struct {\n\tID          uuid.UUID    `json:\"id\"`\n\tName        string       `json:\"name\"`\n\tCreatedAt   time.Time    `json:\"created_at\"`\n\tDeletedAt   time.Time    `json:\"deleted_at\"`\n\tConnections []Connection `json:\"connections\"`\n}\n\ntype TunnelWithToken struct {\n\tTunnel\n\tToken string `json:\"token\"`\n}\n\ntype Connection struct {\n\tColoName           string    `json:\"colo_name\"`\n\tID                 uuid.UUID `json:\"id\"`\n\tIsPendingReconnect bool      `json:\"is_pending_reconnect\"`\n\tOriginIP           net.IP    `json:\"origin_ip\"`\n\tOpenedAt           time.Time `json:\"opened_at\"`\n}\n\ntype ActiveClient struct {\n\tID          uuid.UUID    `json:\"id\"`\n\tFeatures    []string     `json:\"features\"`\n\tVersion     string       `json:\"version\"`\n\tArch        string       `json:\"arch\"`\n\tRunAt       time.Time    `json:\"run_at\"`\n\tConnections []Connection `json:\"conns\"`\n}\n\ntype newTunnel struct {\n\tName         string `json:\"name\"`\n\tTunnelSecret []byte `json:\"tunnel_secret\"`\n}\n\ntype CleanupParams struct {\n\tqueryParams url.Values\n}\n\nfunc NewCleanupParams() *CleanupParams {\n\treturn &CleanupParams{\n\t\tqueryParams: url.Values{},\n\t}\n}\n\nfunc (cp *CleanupParams) ForClient(clientID uuid.UUID) {\n\tcp.queryParams.Set(\"client_id\", clientID.String())\n}\n\nfunc (cp CleanupParams) encode() string {\n\treturn cp.queryParams.Encode()\n}\n\nfunc (r *RESTClient) CreateTunnel(name string, tunnelSecret []byte) (*TunnelWithToken, error) {\n\tif name == \"\" {\n\t\treturn nil, errors.New(\"tunnel name required\")\n\t}\n\tif _, err := uuid.Parse(name); err == nil {\n\t\treturn nil, errors.New(\"you cannot use UUIDs as tunnel names\")\n\t}\n\tbody := &newTunnel{\n\t\tName:         name,\n\t\tTunnelSecret: tunnelSecret,\n\t}\n\n\tresp, err := r.sendRequest(\"POST\", r.baseEndpoints.accountLevel, body)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"REST request failed\")\n\t}\n\tdefer resp.Body.Close()\n\n\tswitch resp.StatusCode {\n\tcase http.StatusOK:\n\t\tvar tunnel TunnelWithToken\n\t\tif serdeErr := parseResponse(resp.Body, &tunnel); serdeErr != nil {\n\t\t\treturn nil, serdeErr\n\t\t}\n\t\treturn &tunnel, nil\n\tcase http.StatusConflict:\n\t\treturn nil, ErrTunnelNameConflict\n\t}\n\n\treturn nil, r.statusCodeToError(\"create tunnel\", resp)\n}\n\nfunc (r *RESTClient) GetTunnel(tunnelID uuid.UUID) (*Tunnel, error) {\n\tendpoint := r.baseEndpoints.accountLevel\n\tendpoint.Path = path.Join(endpoint.Path, fmt.Sprintf(\"%v\", tunnelID))\n\tresp, err := r.sendRequest(\"GET\", endpoint, nil)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"REST request failed\")\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode == http.StatusOK {\n\t\treturn unmarshalTunnel(resp.Body)\n\t}\n\n\treturn nil, r.statusCodeToError(\"get tunnel\", resp)\n}\n\nfunc (r *RESTClient) GetTunnelToken(tunnelID uuid.UUID) (token string, err error) {\n\tendpoint := r.baseEndpoints.accountLevel\n\tendpoint.Path = path.Join(endpoint.Path, fmt.Sprintf(\"%v/token\", tunnelID))\n\tresp, err := r.sendRequest(\"GET\", endpoint, nil)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"REST request failed\")\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode == http.StatusOK {\n\t\terr = parseResponse(resp.Body, &token)\n\t\treturn token, err\n\t}\n\n\treturn \"\", r.statusCodeToError(\"get tunnel token\", resp)\n}\n\n// managementEndpointPath returns the path segment for a management resource endpoint\nfunc managementEndpointPath(tunnelID uuid.UUID, res ManagementResource) string {\n\treturn fmt.Sprintf(\"%v/management/%s\", tunnelID, res.String())\n}\n\nfunc (r *RESTClient) GetManagementToken(tunnelID uuid.UUID, res ManagementResource) (token string, err error) {\n\tendpoint := r.baseEndpoints.accountLevel\n\tendpoint.Path = path.Join(endpoint.Path, managementEndpointPath(tunnelID, res))\n\n\tresp, err := r.sendRequest(\"POST\", endpoint, nil)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"REST request failed\")\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode == http.StatusOK {\n\t\terr = parseResponse(resp.Body, &token)\n\t\treturn token, err\n\t}\n\n\treturn \"\", r.statusCodeToError(\"get tunnel token\", resp)\n}\n\nfunc (r *RESTClient) DeleteTunnel(tunnelID uuid.UUID, cascade bool) error {\n\tendpoint := r.baseEndpoints.accountLevel\n\tendpoint.Path = path.Join(endpoint.Path, fmt.Sprintf(\"%v\", tunnelID))\n\t// Cascade will delete all tunnel dependencies (connections, routes, etc.) that\n\t// are linked to the deleted tunnel.\n\tif cascade {\n\t\tendpoint.RawQuery = \"cascade=true\"\n\t}\n\tresp, err := r.sendRequest(\"DELETE\", endpoint, nil)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"REST request failed\")\n\t}\n\tdefer resp.Body.Close()\n\n\treturn r.statusCodeToError(\"delete tunnel\", resp)\n}\n\nfunc (r *RESTClient) ListTunnels(filter *TunnelFilter) ([]*Tunnel, error) {\n\tfetchFn := func(page int) (*http.Response, error) {\n\t\tendpoint := r.baseEndpoints.accountLevel\n\t\tfilter.Page(page)\n\t\tendpoint.RawQuery = filter.encode()\n\t\trsp, err := r.sendRequest(\"GET\", endpoint, nil)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"REST request failed\")\n\t\t}\n\t\tif rsp.StatusCode != http.StatusOK {\n\t\t\trsp.Body.Close()\n\t\t\treturn nil, r.statusCodeToError(\"list tunnels\", rsp)\n\t\t}\n\t\treturn rsp, nil\n\t}\n\n\treturn fetchExhaustively[Tunnel](fetchFn)\n}\n\nfunc (r *RESTClient) ListActiveClients(tunnelID uuid.UUID) ([]*ActiveClient, error) {\n\tendpoint := r.baseEndpoints.accountLevel\n\tendpoint.Path = path.Join(endpoint.Path, fmt.Sprintf(\"%v/connections\", tunnelID))\n\tresp, err := r.sendRequest(\"GET\", endpoint, nil)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"REST request failed\")\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode == http.StatusOK {\n\t\treturn parseConnectionsDetails(resp.Body)\n\t}\n\n\treturn nil, r.statusCodeToError(\"list connection details\", resp)\n}\n\nfunc parseConnectionsDetails(reader io.Reader) ([]*ActiveClient, error) {\n\tvar clients []*ActiveClient\n\terr := parseResponse(reader, &clients)\n\treturn clients, err\n}\n\nfunc (r *RESTClient) CleanupConnections(tunnelID uuid.UUID, params *CleanupParams) error {\n\tendpoint := r.baseEndpoints.accountLevel\n\tendpoint.RawQuery = params.encode()\n\tendpoint.Path = path.Join(endpoint.Path, fmt.Sprintf(\"%v/connections\", tunnelID))\n\tresp, err := r.sendRequest(\"DELETE\", endpoint, nil)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"REST request failed\")\n\t}\n\tdefer resp.Body.Close()\n\n\treturn r.statusCodeToError(\"cleanup connections\", resp)\n}\n\nfunc unmarshalTunnel(reader io.Reader) (*Tunnel, error) {\n\tvar tunnel Tunnel\n\terr := parseResponse(reader, &tunnel)\n\treturn &tunnel, err\n}\n"
  },
  {
    "path": "cfapi/tunnel_filter.go",
    "content": "package cfapi\n\nimport (\n\t\"net/url\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n)\n\nconst (\n\tTimeLayout = time.RFC3339\n)\n\ntype TunnelFilter struct {\n\tqueryParams url.Values\n}\n\nfunc NewTunnelFilter() *TunnelFilter {\n\treturn &TunnelFilter{\n\t\tqueryParams: url.Values{},\n\t}\n}\n\nfunc (f *TunnelFilter) ByName(name string) {\n\tf.queryParams.Set(\"name\", name)\n}\n\nfunc (f *TunnelFilter) ByNamePrefix(namePrefix string) {\n\tf.queryParams.Set(\"name_prefix\", namePrefix)\n}\n\nfunc (f *TunnelFilter) ExcludeNameWithPrefix(excludePrefix string) {\n\tf.queryParams.Set(\"exclude_prefix\", excludePrefix)\n}\n\nfunc (f *TunnelFilter) NoDeleted() {\n\tf.queryParams.Set(\"is_deleted\", \"false\")\n}\n\nfunc (f *TunnelFilter) ByExistedAt(existedAt time.Time) {\n\tf.queryParams.Set(\"existed_at\", existedAt.Format(TimeLayout))\n}\n\nfunc (f *TunnelFilter) ByTunnelID(tunnelID uuid.UUID) {\n\tf.queryParams.Set(\"uuid\", tunnelID.String())\n}\n\nfunc (f *TunnelFilter) MaxFetchSize(max uint) {\n\tf.queryParams.Set(\"per_page\", strconv.Itoa(int(max)))\n}\n\nfunc (f *TunnelFilter) Page(page int) {\n\tf.queryParams.Set(\"page\", strconv.Itoa(page))\n}\n\nfunc (f TunnelFilter) encode() string {\n\treturn f.queryParams.Encode()\n}\n"
  },
  {
    "path": "cfapi/tunnel_test.go",
    "content": "package cfapi\n\nimport (\n\t\"bytes\"\n\t\"net\"\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nvar loc, _ = time.LoadLocation(\"UTC\")\n\nfunc Test_unmarshalTunnel(t *testing.T) {\n\ttype args struct {\n\t\tbody string\n\t}\n\ttests := []struct {\n\t\tname    string\n\t\targs    args\n\t\twant    *Tunnel\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname: \"empty list\",\n\t\t\targs: args{body: `{\"success\": true, \"result\": {\"id\":\"b34cc7ce-925b-46ee-bc23-4cb5c18d8292\",\"created_at\":\"2021-07-29T13:46:14.090955Z\",\"deleted_at\":\"2021-07-29T14:07:27.559047Z\",\"name\":\"qt-bIWWN7D662ogh61pCPfu5s2XgqFY1OyV\",\"account_id\":6946212,\"account_tag\":\"5ab4e9dfbd435d24068829fda0077963\",\"conns_active_at\":null,\"conns_inactive_at\":\"2021-07-29T13:47:22.548482Z\",\"tun_type\":\"cfd_tunnel\",\"metadata\":{\"qtid\":\"a6fJROgkXutNruBGaJjD\"}}}`},\n\t\t\twant: &Tunnel{\n\t\t\t\tID:          uuid.MustParse(\"b34cc7ce-925b-46ee-bc23-4cb5c18d8292\"),\n\t\t\t\tName:        \"qt-bIWWN7D662ogh61pCPfu5s2XgqFY1OyV\",\n\t\t\t\tCreatedAt:   time.Date(2021, 07, 29, 13, 46, 14, 90955000, loc),\n\t\t\t\tDeletedAt:   time.Date(2021, 07, 29, 14, 7, 27, 559047000, loc),\n\t\t\t\tConnections: nil,\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\tgot, err := unmarshalTunnel(strings.NewReader(tt.args.body))\n\t\t\tif (err != nil) != tt.wantErr {\n\t\t\t\tt.Errorf(\"unmarshalTunnel() error = %v, wantErr %v\", err, tt.wantErr)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"unmarshalTunnel() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestUnmarshalTunnelOk(t *testing.T) {\n\tjsonBody := `{\"success\": true, \"result\": {\"id\": \"00000000-0000-0000-0000-000000000000\",\"name\":\"test\",\"created_at\":\"0001-01-01T00:00:00Z\",\"connections\":[]}}`\n\texpected := Tunnel{\n\t\tID:          uuid.Nil,\n\t\tName:        \"test\",\n\t\tCreatedAt:   time.Time{},\n\t\tConnections: []Connection{},\n\t}\n\tactual, err := unmarshalTunnel(bytes.NewReader([]byte(jsonBody)))\n\trequire.NoError(t, err)\n\trequire.Equal(t, &expected, actual)\n}\n\nfunc TestUnmarshalTunnelErr(t *testing.T) {\n\ttests := []string{\n\t\t`abc`,\n\t\t`{\"success\": true, \"result\": abc}`,\n\t\t`{\"success\": false, \"result\": {\"id\": \"00000000-0000-0000-0000-000000000000\",\"name\":\"test\",\"created_at\":\"0001-01-01T00:00:00Z\",\"connections\":[]}}}`,\n\t\t`{\"errors\": [{\"code\": 1003, \"message\":\"An A, AAAA or CNAME record already exists with that host\"}], \"result\": {\"id\": \"00000000-0000-0000-0000-000000000000\",\"name\":\"test\",\"created_at\":\"0001-01-01T00:00:00Z\",\"connections\":[]}}}`,\n\t}\n\n\tfor i, test := range tests {\n\t\t_, err := unmarshalTunnel(bytes.NewReader([]byte(test)))\n\t\tassert.Error(t, err, \"Test #%v failed\", i)\n\t}\n}\n\nfunc TestManagementResource_String(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\tresource ManagementResource\n\t\twant     string\n\t}{\n\t\t{\n\t\t\tname:     \"Logs\",\n\t\t\tresource: Logs,\n\t\t\twant:     \"logs\",\n\t\t},\n\t\t{\n\t\t\tname:     \"Admin\",\n\t\t\tresource: Admin,\n\t\t\twant:     \"admin\",\n\t\t},\n\t\t{\n\t\t\tname:     \"HostDetails\",\n\t\t\tresource: HostDetails,\n\t\t\twant:     \"host_details\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tassert.Equal(t, tt.want, tt.resource.String())\n\t\t})\n\t}\n}\n\nfunc TestManagementResource_String_Unknown(t *testing.T) {\n\tunknown := ManagementResource(999)\n\tassert.Equal(t, \"\", unknown.String())\n}\n\nfunc TestManagementEndpointPath(t *testing.T) {\n\ttunnelID := uuid.MustParse(\"b34cc7ce-925b-46ee-bc23-4cb5c18d8292\")\n\n\ttests := []struct {\n\t\tname     string\n\t\tresource ManagementResource\n\t\twant     string\n\t}{\n\t\t{\n\t\t\tname:     \"Logs resource\",\n\t\t\tresource: Logs,\n\t\t\twant:     \"b34cc7ce-925b-46ee-bc23-4cb5c18d8292/management/logs\",\n\t\t},\n\t\t{\n\t\t\tname:     \"Admin resource\",\n\t\t\tresource: Admin,\n\t\t\twant:     \"b34cc7ce-925b-46ee-bc23-4cb5c18d8292/management/admin\",\n\t\t},\n\t\t{\n\t\t\tname:     \"HostDetails resource\",\n\t\t\tresource: HostDetails,\n\t\t\twant:     \"b34cc7ce-925b-46ee-bc23-4cb5c18d8292/management/host_details\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot := managementEndpointPath(tunnelID, tt.resource)\n\t\t\tassert.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n\nfunc TestUnmarshalConnections(t *testing.T) {\n\tjsonBody := `{\"success\":true,\"messages\":[],\"errors\":[],\"result\":[{\"id\":\"d4041254-91e3-4deb-bd94-b46e11680b1e\",\"features\":[\"ha-origin\"],\"version\":\"2021.2.5\",\"arch\":\"darwin_amd64\",\"conns\":[{\"colo_name\":\"LIS\",\"id\":\"ac2286e5-c708-4588-a6a0-ba6b51940019\",\"is_pending_reconnect\":false,\"origin_ip\":\"148.38.28.2\",\"opened_at\":\"0001-01-01T00:00:00Z\"}],\"run_at\":\"0001-01-01T00:00:00Z\"}]}`\n\texpected := ActiveClient{\n\t\tID:       uuid.MustParse(\"d4041254-91e3-4deb-bd94-b46e11680b1e\"),\n\t\tFeatures: []string{\"ha-origin\"},\n\t\tVersion:  \"2021.2.5\",\n\t\tArch:     \"darwin_amd64\",\n\t\tRunAt:    time.Time{},\n\t\tConnections: []Connection{{\n\t\t\tID:                 uuid.MustParse(\"ac2286e5-c708-4588-a6a0-ba6b51940019\"),\n\t\t\tColoName:           \"LIS\",\n\t\t\tIsPendingReconnect: false,\n\t\t\tOriginIP:           net.ParseIP(\"148.38.28.2\"),\n\t\t\tOpenedAt:           time.Time{},\n\t\t}},\n\t}\n\tactual, err := parseConnectionsDetails(bytes.NewReader([]byte(jsonBody)))\n\trequire.NoError(t, err)\n\tassert.Equal(t, []*ActiveClient{&expected}, actual)\n}\n"
  },
  {
    "path": "cfapi/virtual_network.go",
    "content": "package cfapi\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"path\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/pkg/errors\"\n)\n\ntype NewVirtualNetwork struct {\n\tName      string `json:\"name\"`\n\tComment   string `json:\"comment\"`\n\tIsDefault bool   `json:\"is_default_network\"`\n}\n\ntype VirtualNetwork struct {\n\tID        uuid.UUID `json:\"id\"`\n\tComment   string    `json:\"comment\"`\n\tName      string    `json:\"name\"`\n\tIsDefault bool      `json:\"is_default_network\"`\n\tCreatedAt time.Time `json:\"created_at\"`\n\tDeletedAt time.Time `json:\"deleted_at\"`\n}\n\ntype UpdateVirtualNetwork struct {\n\tName      *string `json:\"name,omitempty\"`\n\tComment   *string `json:\"comment,omitempty\"`\n\tIsDefault *bool   `json:\"is_default_network,omitempty\"`\n}\n\nfunc (virtualNetwork VirtualNetwork) TableString() string {\n\tdeletedColumn := \"-\"\n\tif !virtualNetwork.DeletedAt.IsZero() {\n\t\tdeletedColumn = virtualNetwork.DeletedAt.Format(time.RFC3339)\n\t}\n\treturn fmt.Sprintf(\n\t\t\"%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t\",\n\t\tvirtualNetwork.ID,\n\t\tvirtualNetwork.Name,\n\t\tstrconv.FormatBool(virtualNetwork.IsDefault),\n\t\tvirtualNetwork.Comment,\n\t\tvirtualNetwork.CreatedAt.Format(time.RFC3339),\n\t\tdeletedColumn,\n\t)\n}\n\nfunc (r *RESTClient) CreateVirtualNetwork(newVnet NewVirtualNetwork) (VirtualNetwork, error) {\n\tresp, err := r.sendRequest(\"POST\", r.baseEndpoints.accountVnets, newVnet)\n\tif err != nil {\n\t\treturn VirtualNetwork{}, errors.Wrap(err, \"REST request failed\")\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode == http.StatusOK {\n\t\treturn parseVnet(resp.Body)\n\t}\n\n\treturn VirtualNetwork{}, r.statusCodeToError(\"add virtual network\", resp)\n}\n\nfunc (r *RESTClient) ListVirtualNetworks(filter *VnetFilter) ([]*VirtualNetwork, error) {\n\tendpoint := r.baseEndpoints.accountVnets\n\tendpoint.RawQuery = filter.Encode()\n\tresp, err := r.sendRequest(\"GET\", endpoint, nil)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"REST request failed\")\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode == http.StatusOK {\n\t\treturn parseListVnets(resp.Body)\n\t}\n\n\treturn nil, r.statusCodeToError(\"list virtual networks\", resp)\n}\n\nfunc (r *RESTClient) DeleteVirtualNetwork(id uuid.UUID, force bool) error {\n\tendpoint := r.baseEndpoints.accountVnets\n\tendpoint.Path = path.Join(endpoint.Path, url.PathEscape(id.String()))\n\n\tqueryParams := url.Values{}\n\tif force {\n\t\tqueryParams.Set(\"force\", strconv.FormatBool(force))\n\t}\n\tendpoint.RawQuery = queryParams.Encode()\n\n\tresp, err := r.sendRequest(\"DELETE\", endpoint, nil)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"REST request failed\")\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode == http.StatusOK {\n\t\t_, err := parseVnet(resp.Body)\n\t\treturn err\n\t}\n\n\treturn r.statusCodeToError(\"delete virtual network\", resp)\n}\n\nfunc (r *RESTClient) UpdateVirtualNetwork(id uuid.UUID, updates UpdateVirtualNetwork) error {\n\tendpoint := r.baseEndpoints.accountVnets\n\tendpoint.Path = path.Join(endpoint.Path, url.PathEscape(id.String()))\n\tresp, err := r.sendRequest(\"PATCH\", endpoint, updates)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"REST request failed\")\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode == http.StatusOK {\n\t\t_, err := parseVnet(resp.Body)\n\t\treturn err\n\t}\n\n\treturn r.statusCodeToError(\"update virtual network\", resp)\n}\n\nfunc parseListVnets(body io.ReadCloser) ([]*VirtualNetwork, error) {\n\tvar vnets []*VirtualNetwork\n\terr := parseResponse(body, &vnets)\n\treturn vnets, err\n}\n\nfunc parseVnet(body io.ReadCloser) (VirtualNetwork, error) {\n\tvar vnet VirtualNetwork\n\terr := parseResponse(body, &vnet)\n\treturn vnet, err\n}\n"
  },
  {
    "path": "cfapi/virtual_network_filter.go",
    "content": "package cfapi\n\nimport (\n\t\"net/url\"\n\t\"strconv\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/urfave/cli/v2\"\n)\n\nvar (\n\tfilterVnetId = cli.StringFlag{\n\t\tName:  \"id\",\n\t\tUsage: \"List virtual networks with the given `ID`\",\n\t}\n\tfilterVnetByName = cli.StringFlag{\n\t\tName:  \"name\",\n\t\tUsage: \"List virtual networks with the given `NAME`\",\n\t}\n\tfilterDefaultVnet = cli.BoolFlag{\n\t\tName:  \"is-default\",\n\t\tUsage: \"If true, lists the virtual network that is the default one. If false, lists all non-default virtual networks for the account. If absent, all are included in the results regardless of their default status.\",\n\t}\n\tfilterDeletedVnet = cli.BoolFlag{\n\t\tName:  \"show-deleted\",\n\t\tUsage: \"If false (default), only show non-deleted virtual networks. If true, only show deleted virtual networks.\",\n\t}\n\tVnetFilterFlags = []cli.Flag{\n\t\t&filterVnetId,\n\t\t&filterVnetByName,\n\t\t&filterDefaultVnet,\n\t\t&filterDeletedVnet,\n\t}\n)\n\n// VnetFilter which virtual networks get queried.\ntype VnetFilter struct {\n\tqueryParams url.Values\n}\n\nfunc NewVnetFilter() *VnetFilter {\n\treturn &VnetFilter{\n\t\tqueryParams: url.Values{},\n\t}\n}\n\nfunc (f *VnetFilter) ById(vnetId uuid.UUID) {\n\tf.queryParams.Set(\"id\", vnetId.String())\n}\n\nfunc (f *VnetFilter) ByName(name string) {\n\tf.queryParams.Set(\"name\", name)\n}\n\nfunc (f *VnetFilter) ByDefaultStatus(isDefault bool) {\n\tf.queryParams.Set(\"is_default\", strconv.FormatBool(isDefault))\n}\n\nfunc (f *VnetFilter) WithDeleted(isDeleted bool) {\n\tf.queryParams.Set(\"is_deleted\", strconv.FormatBool(isDeleted))\n}\n\nfunc (f *VnetFilter) MaxFetchSize(max uint) {\n\tf.queryParams.Set(\"per_page\", strconv.Itoa(int(max)))\n}\n\nfunc (f VnetFilter) Encode() string {\n\treturn f.queryParams.Encode()\n}\n\n// NewFromCLI parses CLI flags to discover which filters should get applied to list virtual networks.\nfunc NewFromCLI(c *cli.Context) (*VnetFilter, error) {\n\tf := NewVnetFilter()\n\n\tif id := c.String(\"id\"); id != \"\" {\n\t\tvnetId, err := uuid.Parse(id)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrapf(err, \"%s is not a valid virtual network ID\", id)\n\t\t}\n\t\tf.ById(vnetId)\n\t}\n\n\tif name := c.String(\"name\"); name != \"\" {\n\t\tf.ByName(name)\n\t}\n\n\tif c.IsSet(\"is-default\") {\n\t\tf.ByDefaultStatus(c.Bool(\"is-default\"))\n\t}\n\n\tf.WithDeleted(c.Bool(\"show-deleted\"))\n\n\tif maxFetch := c.Int(\"max-fetch-size\"); maxFetch > 0 {\n\t\tf.MaxFetchSize(uint(maxFetch))\n\t}\n\n\treturn f, nil\n}\n"
  },
  {
    "path": "cfapi/virtual_network_test.go",
    "content": "package cfapi\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestVirtualNetworkJsonRoundtrip(t *testing.T) {\n\tdata := `{\n\t\t\"id\":\"74fce949-351b-4752-b261-81a56cfd3130\",\n\t\t\"comment\":\"New York DC1\",\n\t\t\"name\":\"us-east-1\",\n\t\t\"is_default_network\":true,\n\t\t\"created_at\":\"2021-11-26T14:40:02.600673Z\",\n\t\t\"deleted_at\":\"2021-12-01T10:23:13.102645Z\"\n\t}`\n\tvar v VirtualNetwork\n\terr := json.Unmarshal([]byte(data), &v)\n\n\trequire.NoError(t, err)\n\trequire.Equal(t, uuid.MustParse(\"74fce949-351b-4752-b261-81a56cfd3130\"), v.ID)\n\trequire.Equal(t, \"us-east-1\", v.Name)\n\trequire.Equal(t, \"New York DC1\", v.Comment)\n\trequire.Equal(t, true, v.IsDefault)\n\n\tbytes, err := json.Marshal(v)\n\trequire.NoError(t, err)\n\tobtainedJson := string(bytes)\n\tdata = strings.Replace(data, \"\\t\", \"\", -1)\n\tdata = strings.Replace(data, \"\\n\", \"\", -1)\n\trequire.Equal(t, data, obtainedJson)\n}\n\nfunc TestMarshalNewVnet(t *testing.T) {\n\tnewVnet := NewVirtualNetwork{\n\t\tName:      \"eu-west-1\",\n\t\tComment:   \"London office\",\n\t\tIsDefault: true,\n\t}\n\n\tserialized, err := json.Marshal(newVnet)\n\trequire.NoError(t, err)\n\trequire.True(t, strings.Contains(string(serialized), newVnet.Name))\n}\n\nfunc TestMarshalUpdateVnet(t *testing.T) {\n\tnewName := \"bulgaria-1\"\n\tupdates := UpdateVirtualNetwork{\n\t\tName: &newName,\n\t}\n\n\t// Test where receiver is struct\n\tserialized, err := json.Marshal(updates)\n\trequire.NoError(t, err)\n\trequire.True(t, strings.Contains(string(serialized), newName))\n}\n\nfunc TestVnetTableString(t *testing.T) {\n\tvirtualNet := VirtualNetwork{\n\t\tID:        uuid.New(),\n\t\tName:      \"us-east-1\",\n\t\tComment:   \"New York DC1\",\n\t\tIsDefault: true,\n\t\tCreatedAt: time.Now(),\n\t\tDeletedAt: time.Time{},\n\t}\n\n\trow := virtualNet.TableString()\n\trequire.True(t, strings.HasPrefix(row, virtualNet.ID.String()))\n\trequire.True(t, strings.Contains(row, virtualNet.Name))\n\trequire.True(t, strings.Contains(row, virtualNet.Comment))\n\trequire.True(t, strings.Contains(row, \"true\"))\n\trequire.True(t, strings.HasSuffix(row, \"-\\t\"))\n}\n"
  },
  {
    "path": "cfio/copy.go",
    "content": "package cfio\n\nimport (\n\t\"io\"\n\t\"sync\"\n)\n\nconst defaultBufferSize = 16 * 1024\n\nvar bufferPool = sync.Pool{\n\tNew: func() interface{} {\n\t\treturn make([]byte, defaultBufferSize)\n\t},\n}\n\nfunc Copy(dst io.Writer, src io.Reader) (written int64, err error) {\n\t_, okWriteTo := src.(io.WriterTo)\n\t_, okReadFrom := dst.(io.ReaderFrom)\n\tvar buffer []byte = nil\n\n\tif !(okWriteTo || okReadFrom) {\n\t\tbuffer = bufferPool.Get().([]byte)\n\t\tdefer bufferPool.Put(buffer)\n\t}\n\n\treturn io.CopyBuffer(dst, src, buffer)\n}\n"
  },
  {
    "path": "cfsetup.yaml",
    "content": "# A valid cfsetup.yaml is required but we dont have any real config to specify\ndummy_key: true\n"
  },
  {
    "path": "check-fips.sh",
    "content": "# Pass the path to the executable to check for FIPS compliance\nexe=$1\n\nif [ \"$(go tool nm \"${exe}\" | grep -c '_Cfunc__goboringcrypto_')\" -eq 0 ]; then\n    # Asserts that executable is using FIPS-compliant boringcrypto\n    echo \"${exe}: missing goboring symbols\" >&2\n    exit 1\nfi\nif [ \"$(go tool nm \"${exe}\" | grep -c 'crypto/internal/boring/sig.FIPSOnly')\" -eq 0 ]; then\n    # Asserts that executable is using FIPS-only schemes\n    echo \"${exe}: missing fipsonly symbols\" >&2\n    exit 1\nfi\n\necho \"${exe} is FIPS-compliant\"\n"
  },
  {
    "path": "client/config.go",
    "content": "package client\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/features\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\n// Config captures the local client runtime configuration.\ntype Config struct {\n\tConnectorID uuid.UUID\n\tVersion     string\n\tArch        string\n\n\tfeatureSelector features.FeatureSelector\n}\n\nfunc NewConfig(version string, arch string, featureSelector features.FeatureSelector) (*Config, error) {\n\tconnectorID, err := uuid.NewRandom()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to generate a connector UUID: %w\", err)\n\t}\n\treturn &Config{\n\t\tConnectorID:     connectorID,\n\t\tVersion:         version,\n\t\tArch:            arch,\n\t\tfeatureSelector: featureSelector,\n\t}, nil\n}\n\n// ConnectionOptionsSnapshot is a snapshot of the current client information used to initialize a connection.\n//\n// The FeatureSnapshot is the features that are available for this connection. At the client level they may\n// change, but they will not change within the scope of this struct.\ntype ConnectionOptionsSnapshot struct {\n\tclient              pogs.ClientInfo\n\toriginLocalIP       net.IP\n\tnumPreviousAttempts uint8\n\tFeatureSnapshot     features.FeatureSnapshot\n}\n\nfunc (c *Config) ConnectionOptionsSnapshot(originIP net.IP, previousAttempts uint8) *ConnectionOptionsSnapshot {\n\tsnapshot := c.featureSelector.Snapshot()\n\treturn &ConnectionOptionsSnapshot{\n\t\tclient: pogs.ClientInfo{\n\t\t\tClientID: c.ConnectorID[:],\n\t\t\tVersion:  c.Version,\n\t\t\tArch:     c.Arch,\n\t\t\tFeatures: snapshot.FeaturesList,\n\t\t},\n\t\toriginLocalIP:       originIP,\n\t\tnumPreviousAttempts: previousAttempts,\n\t\tFeatureSnapshot:     snapshot,\n\t}\n}\n\nfunc (c ConnectionOptionsSnapshot) ConnectionOptions() *pogs.ConnectionOptions {\n\treturn &pogs.ConnectionOptions{\n\t\tClient:              c.client,\n\t\tOriginLocalIP:       c.originLocalIP,\n\t\tReplaceExisting:     false,\n\t\tCompressionQuality:  0,\n\t\tNumPreviousAttempts: c.numPreviousAttempts,\n\t}\n}\n\nfunc (c ConnectionOptionsSnapshot) LogFields(event *zerolog.Event) *zerolog.Event {\n\treturn event.Strs(\"features\", c.client.Features)\n}\n"
  },
  {
    "path": "client/config_test.go",
    "content": "package client\n\nimport (\n\t\"net\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/cloudflare/cloudflared/features\"\n)\n\nfunc TestGenerateConnectionOptions(t *testing.T) {\n\tversion := \"1234\"\n\tarch := \"linux_amd64\"\n\toriginIP := net.ParseIP(\"192.168.1.1\")\n\tvar previousAttempts uint8 = 4\n\n\tconfig, err := NewConfig(version, arch, &mockFeatureSelector{})\n\trequire.NoError(t, err)\n\trequire.Equal(t, version, config.Version)\n\trequire.Equal(t, arch, config.Arch)\n\n\t// Validate ConnectionOptionsSnapshot fields\n\tconnOptions := config.ConnectionOptionsSnapshot(originIP, previousAttempts)\n\trequire.Equal(t, version, connOptions.client.Version)\n\trequire.Equal(t, arch, connOptions.client.Arch)\n\trequire.Equal(t, config.ConnectorID[:], connOptions.client.ClientID)\n\n\t// Vaidate snapshot feature fields against the connOptions generated\n\tsnapshot := config.featureSelector.Snapshot()\n\trequire.Equal(t, features.DatagramV3, snapshot.DatagramVersion)\n\trequire.Equal(t, features.DatagramV3, connOptions.FeatureSnapshot.DatagramVersion)\n\n\tpogsConnOptions := connOptions.ConnectionOptions()\n\trequire.Equal(t, connOptions.client, pogsConnOptions.Client)\n\trequire.Equal(t, originIP, pogsConnOptions.OriginLocalIP)\n\trequire.False(t, pogsConnOptions.ReplaceExisting)\n\trequire.Equal(t, uint8(0), pogsConnOptions.CompressionQuality)\n\trequire.Equal(t, previousAttempts, pogsConnOptions.NumPreviousAttempts)\n}\n\ntype mockFeatureSelector struct{}\n\nfunc (m *mockFeatureSelector) Snapshot() features.FeatureSnapshot {\n\treturn features.FeatureSnapshot{\n\t\tPostQuantum:     features.PostQuantumPrefer,\n\t\tDatagramVersion: features.DatagramV3,\n\t\tFeaturesList:    []string{features.FeaturePostQuantum, features.FeatureDatagramV3_2},\n\t}\n}\n"
  },
  {
    "path": "cloudflared.wxs",
    "content": "<?xml version=\"1.0\"?>\n\n<?if $(var.Platform)=\"x64\" ?>\n    <?define Program_Files=\"ProgramFiles64Folder\"?>\n<?else ?>\n    <?define Program_Files=\"ProgramFilesFolder\"?>\n<?endif ?>\n<?ifndef var.Version?>\n    <?error Undefined Version variable?>\n<?endif ?>\n<?ifndef var.Path?>\n    <?error Undefined Path variable?>\n<?endif ?>\n\n<Wix xmlns=\"http://schemas.microsoft.com/wix/2006/wi\">\n    <Product Id=\"*\"\n        UpgradeCode=\"23f90fdd-9328-47ea-ab52-5380855a4b12\"\n        Name=\"cloudflared\"\n        Version=\"$(var.Version)\"\n        Manufacturer=\"cloudflare\"\n        Language=\"1033\">\n\n        <Package InstallerVersion=\"200\" Compressed=\"yes\" Comments=\"Windows Installer Package\" InstallScope=\"perMachine\" />\n\n        <Media Id=\"1\" Cabinet=\"product.cab\" EmbedCab=\"yes\" />\n\n        <MajorUpgrade DowngradeErrorMessage=\"A later version of [ProductName] is already installed. Setup will now exit.\" />\n\n        <Upgrade Id=\"23f90fdd-9328-47ea-ab52-5380855a4b12\">\n            <UpgradeVersion Minimum=\"$(var.Version)\" OnlyDetect=\"yes\" Property=\"NEWERVERSIONDETECTED\" />\n            <UpgradeVersion Minimum=\"2020.8.0\" Maximum=\"$(var.Version)\" IncludeMinimum=\"yes\" IncludeMaximum=\"no\"\n                Property=\"OLDERVERSIONBEINGUPGRADED\" />\n        </Upgrade>\n        <Condition Message=\"A newer version of this software is already installed.\">NOT NEWERVERSIONDETECTED</Condition>\n\n        <Directory Id=\"TARGETDIR\" Name=\"SourceDir\">\n            <!--This specifies where the cloudflared.exe is moved to in the windows Operation System-->\n            <Directory Id=\"$(var.Program_Files)\">\n                <Directory Id=\"INSTALLDIR\" Name=\"cloudflared\">\n                    <Component Id=\"ApplicationFiles\" Guid=\"35e5e858-9372-4449-bf73-1cd6f7267128\">\n                        <File Id=\"ApplicationFile0\" Source=\"$(var.Path)\" />\n                    </Component>\n                </Directory>\n            </Directory>\n            <Component Id=\"ENVS\" Guid=\"6bb74449-d10d-4f4a-933e-6fc9fa006eae\">\n                <!--Set the cloudflared bin location to the Path Environment Variable-->\n                <Environment Id=\"ENV0\"\n                    Name=\"PATH\"\n                    Value=\"[INSTALLDIR]\"\n                    Permanent=\"no\"\n                    Part=\"last\"\n                    Action=\"create\"\n                    System=\"yes\" />\n            </Component>\n        </Directory>\n\n\n        <Feature Id='Complete' Level='1'>\n            <ComponentRef Id=\"ENVS\" />\n            <ComponentRef Id='ApplicationFiles' />\n        </Feature>\n\n    </Product>\n</Wix>\n"
  },
  {
    "path": "cloudflared_man_template",
    "content": ".\\\" Manpage for cloudflared.\n.TH man 1 ${DATE} \"${VERSION}\" \"cloudflared man page\"\n.SH NAME\ncloudflared \\- creates a connection to the cloudflare edge network\n.SH DESCRIPTION\ncloudflared creates a persistent connection between a local service and the Cloudflare network. Once the daemon is running and the Tunnel has been configured, the local service can be locked down to only allow connections from Cloudflare.\n"
  },
  {
    "path": "cmd/cloudflared/access/carrier.go",
    "content": "package access\n\nimport (\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/cloudflare/cloudflared/carrier\"\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/logger\"\n\t\"github.com/cloudflare/cloudflared/stream\"\n\t\"github.com/cloudflare/cloudflared/validation\"\n)\n\nconst (\n\tLogFieldHost               = \"host\"\n\tcfAccessClientIDHeader     = \"Cf-Access-Client-Id\"\n\tcfAccessClientSecretHeader = \"Cf-Access-Client-Secret\"\n)\n\n// StartForwarder starts a client side websocket forward\nfunc StartForwarder(forwarder config.Forwarder, shutdown <-chan struct{}, log *zerolog.Logger) error {\n\tvalidURL, err := validation.ValidateUrl(forwarder.Listener)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"error validating origin URL\")\n\t}\n\n\t// get the headers from the config file and add to the request\n\theaders := make(http.Header)\n\tif forwarder.TokenClientID != \"\" {\n\t\theaders.Set(cfAccessClientIDHeader, forwarder.TokenClientID)\n\t}\n\n\tif forwarder.TokenSecret != \"\" {\n\t\theaders.Set(cfAccessClientSecretHeader, forwarder.TokenSecret)\n\t}\n\theaders.Set(\"User-Agent\", userAgent)\n\n\tcarrier.SetBastionDest(headers, forwarder.Destination)\n\n\toptions := &carrier.StartOptions{\n\t\tOriginURL: forwarder.URL,\n\t\tHeaders:   headers, //TODO: TUN-2688 support custom headers from config file\n\t\tIsFedramp: forwarder.IsFedramp,\n\t}\n\n\t// we could add a cmd line variable for this bool if we want the SOCK5 server to be on the client side\n\twsConn := carrier.NewWSConnection(log)\n\n\tlog.Info().Str(LogFieldHost, validURL.Host).Msg(\"Start Websocket listener\")\n\treturn carrier.StartForwarder(wsConn, validURL.Host, shutdown, options)\n}\n\n// ssh will start a WS proxy server for server mode\n// or copy from stdin/stdout for client mode\n// useful for proxying other protocols (like ssh) over websockets\n// (which you can put Access in front of)\nfunc ssh(c *cli.Context) error {\n\t// If not running as a forwarder, disable terminal logs as it collides with the stdin/stdout of the parent process\n\toutputTerminal := logger.DisableTerminalLog\n\tif c.IsSet(sshURLFlag) {\n\t\toutputTerminal = logger.EnableTerminalLog\n\t}\n\tlog := logger.CreateSSHLoggerFromContext(c, outputTerminal)\n\n\t// get the hostname from the cmdline and error out if its not provided\n\trawHostName := c.String(sshHostnameFlag)\n\turl, err := parseURL(rawHostName)\n\tif err != nil {\n\t\tlog.Err(err).Send()\n\t\treturn cli.ShowCommandHelp(c, \"ssh\")\n\t}\n\n\t// get the headers from the cmdline and add them\n\theaders := parseRequestHeaders(c.StringSlice(sshHeaderFlag))\n\tif c.IsSet(sshTokenIDFlag) {\n\t\theaders.Set(cfAccessClientIDHeader, c.String(sshTokenIDFlag))\n\t}\n\tif c.IsSet(sshTokenSecretFlag) {\n\t\theaders.Set(cfAccessClientSecretHeader, c.String(sshTokenSecretFlag))\n\t}\n\theaders.Set(\"User-Agent\", userAgent)\n\n\tcarrier.SetBastionDest(headers, c.String(sshDestinationFlag))\n\n\toptions := &carrier.StartOptions{\n\t\tOriginURL: url.String(),\n\t\tHeaders:   headers,\n\t\tHost:      url.Host,\n\t\tIsFedramp: c.Bool(fedrampFlag),\n\t}\n\n\tif connectTo := c.String(sshConnectTo); connectTo != \"\" {\n\t\tparts := strings.Split(connectTo, \":\")\n\t\tswitch len(parts) {\n\t\tcase 1:\n\t\t\toptions.OriginURL = fmt.Sprintf(\"https://%s\", parts[0])\n\t\tcase 2:\n\t\t\toptions.OriginURL = fmt.Sprintf(\"https://%s:%s\", parts[0], parts[1])\n\t\tcase 3:\n\t\t\toptions.OriginURL = fmt.Sprintf(\"https://%s:%s\", parts[2], parts[1])\n\t\t\toptions.TLSClientConfig = &tls.Config{\n\t\t\t\tInsecureSkipVerify: true, // #nosec G402\n\t\t\t\tServerName:         parts[0],\n\t\t\t}\n\t\t\tlog.Warn().Msgf(\"Using insecure SSL connection because SNI overridden to %s\", parts[0])\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"invalid connection override: %s\", connectTo)\n\t\t}\n\t}\n\n\t// we could add a cmd line variable for this bool if we want the SOCK5 server to be on the client side\n\twsConn := carrier.NewWSConnection(log)\n\n\tif c.NArg() > 0 || c.IsSet(sshURLFlag) {\n\t\tforwarder, err := config.ValidateUrl(c, true)\n\t\tif err != nil {\n\t\t\tlog.Err(err).Msg(\"Error validating origin URL\")\n\t\t\treturn errors.Wrap(err, \"error validating origin URL\")\n\t\t}\n\t\tlog.Info().Str(LogFieldHost, forwarder.Host).Msg(\"Start Websocket listener\")\n\t\terr = carrier.StartForwarder(wsConn, forwarder.Host, shutdownC, options)\n\t\tif err != nil {\n\t\t\tlog.Err(err).Msg(\"Error on Websocket listener\")\n\t\t}\n\t\treturn err\n\t}\n\n\tvar s io.ReadWriter\n\ts = &carrier.StdinoutStream{}\n\tif c.IsSet(sshDebugStream) {\n\t\tmaxMessages := c.Uint64(sshDebugStream)\n\t\tif maxMessages == 0 {\n\t\t\t// default to 10 if provided but unset\n\t\t\tmaxMessages = 10\n\t\t}\n\t\tlogger := log.With().Str(\"host\", url.Host).Logger()\n\t\ts = stream.NewDebugStream(s, &logger, maxMessages)\n\t}\n\treturn carrier.StartClient(wsConn, s, options)\n}\n"
  },
  {
    "path": "cmd/cloudflared/access/cmd.go",
    "content": "package access\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n\t\"text/template\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/urfave/cli/v2\"\n\t\"golang.org/x/net/idna\"\n\n\t\"github.com/cloudflare/cloudflared/carrier\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n\tcfdflags \"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n\t\"github.com/cloudflare/cloudflared/logger\"\n\t\"github.com/cloudflare/cloudflared/sshgen\"\n\t\"github.com/cloudflare/cloudflared/token\"\n\t\"github.com/cloudflare/cloudflared/validation\"\n)\n\nconst (\n\tappURLFlag         = \"app\"\n\tloginQuietFlag     = \"quiet\"\n\tsshHostnameFlag    = \"hostname\"\n\tsshDestinationFlag = \"destination\"\n\tsshURLFlag         = \"url\"\n\tsshHeaderFlag      = \"header\"\n\tsshTokenIDFlag     = \"service-token-id\"\n\tsshTokenSecretFlag = \"service-token-secret\"\n\tsshGenCertFlag     = \"short-lived-cert\"\n\tsshConnectTo       = \"connect-to\"\n\tsshDebugStream     = \"debug-stream\"\n\tsshConfigTemplate  = `\nAdd to your {{.Home}}/.ssh/config:\n\n{{- if .ShortLivedCerts}}\nMatch host {{.Hostname}} exec \"{{.Cloudflared}} access ssh-gen --hostname %h\"\n  ProxyCommand {{.Cloudflared}} access ssh --hostname %h\n  IdentityFile ~/.cloudflared/%h-cf_key\n  CertificateFile ~/.cloudflared/%h-cf_key-cert.pub\n{{- else}}\nHost {{.Hostname}}\n  ProxyCommand {{.Cloudflared}} access ssh --hostname %h\n{{end}}\n`\n\tfedrampFlag = \"fedramp\"\n)\n\nconst sentryDSN = \"https://56a9c9fa5c364ab28f34b14f35ea0f1b@sentry.io/189878\"\n\nvar (\n\tshutdownC chan struct{}\n\tuserAgent = \"DEV\"\n)\n\n// Init will initialize and store vars from the main program\nfunc Init(shutdown chan struct{}, version string) {\n\tshutdownC = shutdown\n\tuserAgent = fmt.Sprintf(\"cloudflared/%s\", version)\n}\n\n// Flags return the global flags for Access related commands (hopefully none)\nfunc Flags() []cli.Flag {\n\treturn []cli.Flag{} // no flags yet.\n}\n\n// Commands returns all the Access related subcommands\nfunc Commands() []*cli.Command {\n\treturn []*cli.Command{\n\t\t{\n\t\t\tName:     \"access\",\n\t\t\tAliases:  []string{\"forward\"},\n\t\t\tCategory: \"Access\",\n\t\t\tUsage:    \"access <subcommand>\",\n\t\t\tFlags: []cli.Flag{&cli.BoolFlag{\n\t\t\t\tName:  fedrampFlag,\n\t\t\t\tUsage: \"use when performing operations in fedramp account\",\n\t\t\t}},\n\t\t\tDescription: `Cloudflare Access protects internal resources by securing, authenticating and monitoring access\n\t\t\tper-user and by application. With Cloudflare Access, only authenticated users with the required permissions are\n\t\t\table to reach sensitive resources. The commands provided here allow you to interact with Access protected\n\t\t\tapplications from the command line.`,\n\t\t\tSubcommands: []*cli.Command{\n\t\t\t\t{\n\t\t\t\t\tName:      \"login\",\n\t\t\t\t\tAction:    cliutil.Action(login),\n\t\t\t\t\tUsage:     \"login <url of access application>\",\n\t\t\t\t\tArgsUsage: \"url of Access application\",\n\t\t\t\t\tDescription: `The login subcommand initiates an authentication flow with your identity provider.\n\t\t\t\t\tThe subcommand will launch a browser. For headless systems, a url is provided.\n\t\t\t\t\tOnce authenticated with your identity provider, the login command will generate a JSON Web Token (JWT)\n\t\t\t\t\tscoped to your identity, the application you intend to reach, and valid for a session duration set by your\n\t\t\t\t\tadministrator. cloudflared stores the token in local storage.`,\n\t\t\t\t\tFlags: []cli.Flag{\n\t\t\t\t\t\t&cli.BoolFlag{\n\t\t\t\t\t\t\tName:    loginQuietFlag,\n\t\t\t\t\t\t\tAliases: []string{\"q\"},\n\t\t\t\t\t\t\tUsage:   \"do not print the jwt to the command line\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t&cli.BoolFlag{\n\t\t\t\t\t\t\tName:  \"no-verbose\",\n\t\t\t\t\t\t\tUsage: \"print only the jwt to stdout\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t&cli.BoolFlag{\n\t\t\t\t\t\t\tName:  \"auto-close\",\n\t\t\t\t\t\t\tUsage: \"automatically close the auth interstitial after action\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t&cli.StringFlag{\n\t\t\t\t\t\t\tName: appURLFlag,\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\tName:   \"curl\",\n\t\t\t\t\tAction: cliutil.Action(curl),\n\t\t\t\t\tUsage:  \"curl [--allow-request, -ar] <url> [<curl args>...]\",\n\t\t\t\t\tDescription: `The curl subcommand wraps curl and automatically injects the JWT into a cf-access-token\n\t\t\t\t\theader when using curl to reach an application behind Access.`,\n\t\t\t\t\tArgsUsage:       \"allow-request will allow the curl request to continue even if the jwt is not present.\",\n\t\t\t\t\tSkipFlagParsing: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:        \"token\",\n\t\t\t\t\tAction:      cliutil.Action(generateToken),\n\t\t\t\t\tUsage:       \"token <url of access application>\",\n\t\t\t\t\tArgsUsage:   \"url of Access application\",\n\t\t\t\t\tDescription: `The token subcommand produces a JWT which can be used to authenticate requests.`,\n\t\t\t\t\tFlags: []cli.Flag{\n\t\t\t\t\t\t&cli.StringFlag{\n\t\t\t\t\t\t\tName: appURLFlag,\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\tName:        \"tcp\",\n\t\t\t\t\tAction:      cliutil.Action(ssh),\n\t\t\t\t\tAliases:     []string{\"rdp\", \"ssh\", \"smb\"},\n\t\t\t\t\tUsage:       \"\",\n\t\t\t\t\tArgsUsage:   \"\",\n\t\t\t\t\tDescription: `The tcp subcommand sends data over a proxy to the Cloudflare edge.`,\n\t\t\t\t\tFlags: []cli.Flag{\n\t\t\t\t\t\t&cli.StringFlag{\n\t\t\t\t\t\t\tName:    sshHostnameFlag,\n\t\t\t\t\t\t\tAliases: []string{\"tunnel-host\", \"T\"},\n\t\t\t\t\t\t\tUsage:   \"specify the hostname of your application.\",\n\t\t\t\t\t\t\tEnvVars: []string{\"TUNNEL_SERVICE_HOSTNAME\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t&cli.StringFlag{\n\t\t\t\t\t\t\tName:    sshDestinationFlag,\n\t\t\t\t\t\t\tUsage:   \"specify the destination address of your SSH server.\",\n\t\t\t\t\t\t\tEnvVars: []string{\"TUNNEL_SERVICE_DESTINATION\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t&cli.StringFlag{\n\t\t\t\t\t\t\tName:    sshURLFlag,\n\t\t\t\t\t\t\tAliases: []string{\"listener\", \"L\"},\n\t\t\t\t\t\t\tUsage:   \"specify the host:port to forward data to Cloudflare edge.\",\n\t\t\t\t\t\t\tEnvVars: []string{\"TUNNEL_SERVICE_URL\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t&cli.StringSliceFlag{\n\t\t\t\t\t\t\tName:    sshHeaderFlag,\n\t\t\t\t\t\t\tAliases: []string{\"H\"},\n\t\t\t\t\t\t\tUsage:   \"specify additional headers you wish to send.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t&cli.StringFlag{\n\t\t\t\t\t\t\tName:    sshTokenIDFlag,\n\t\t\t\t\t\t\tAliases: []string{\"id\"},\n\t\t\t\t\t\t\tUsage:   \"specify an Access service token ID you wish to use.\",\n\t\t\t\t\t\t\tEnvVars: []string{\"TUNNEL_SERVICE_TOKEN_ID\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t&cli.StringFlag{\n\t\t\t\t\t\t\tName:    sshTokenSecretFlag,\n\t\t\t\t\t\t\tAliases: []string{\"secret\"},\n\t\t\t\t\t\t\tUsage:   \"specify an Access service token secret you wish to use.\",\n\t\t\t\t\t\t\tEnvVars: []string{\"TUNNEL_SERVICE_TOKEN_SECRET\"},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t&cli.StringFlag{\n\t\t\t\t\t\t\tName:  cfdflags.LogFile,\n\t\t\t\t\t\t\tUsage: \"Save application log to this file for reporting issues.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t&cli.StringFlag{\n\t\t\t\t\t\t\tName:  cfdflags.LogDirectory,\n\t\t\t\t\t\t\tUsage: \"Save application log to this directory for reporting issues.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t&cli.StringFlag{\n\t\t\t\t\t\t\tName:    cfdflags.LogLevelSSH,\n\t\t\t\t\t\t\tAliases: []string{\"loglevel\"}, //added to match the tunnel side\n\t\t\t\t\t\t\tUsage:   \"Application logging level {debug, info, warn, error, fatal}. \",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t&cli.StringFlag{\n\t\t\t\t\t\t\tName:   sshConnectTo,\n\t\t\t\t\t\t\tHidden: true,\n\t\t\t\t\t\t\tUsage:  \"Connect to alternate location for testing, value is host, host:port, or sni:port:host\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t&cli.Uint64Flag{\n\t\t\t\t\t\t\tName:   sshDebugStream,\n\t\t\t\t\t\t\tHidden: true,\n\t\t\t\t\t\t\tUsage:  \"Writes up-to the max provided stream payloads to the logger as debug statements.\",\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\tName:        \"ssh-config\",\n\t\t\t\t\tAction:      cliutil.Action(sshConfig),\n\t\t\t\t\tUsage:       \"\",\n\t\t\t\t\tDescription: `Prints an example configuration ~/.ssh/config`,\n\t\t\t\t\tFlags: []cli.Flag{\n\t\t\t\t\t\t&cli.StringFlag{\n\t\t\t\t\t\t\tName:  sshHostnameFlag,\n\t\t\t\t\t\t\tUsage: \"specify the hostname of your application.\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t&cli.BoolFlag{\n\t\t\t\t\t\t\tName:  sshGenCertFlag,\n\t\t\t\t\t\t\tUsage: \"specify if you wish to generate short lived certs.\",\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\tName:        \"ssh-gen\",\n\t\t\t\t\tAction:      cliutil.Action(sshGen),\n\t\t\t\t\tUsage:       \"\",\n\t\t\t\t\tDescription: `Generates a short lived certificate for given hostname`,\n\t\t\t\t\tFlags: []cli.Flag{\n\t\t\t\t\t\t&cli.StringFlag{\n\t\t\t\t\t\t\tName:  sshHostnameFlag,\n\t\t\t\t\t\t\tUsage: \"specify the hostname of your application.\",\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\n// login pops up the browser window to do the actual login and JWT generation\nfunc login(c *cli.Context) error {\n\terr := sentry.Init(sentry.ClientOptions{\n\t\tDsn:     sentryDSN,\n\t\tRelease: c.App.Version,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tlog := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog)\n\n\tappURL, err := getAppURLFromArgs(c)\n\tif err != nil {\n\t\tlog.Error().Msg(\"Please provide the url of the Access application\")\n\t\treturn err\n\t}\n\n\tappInfo, err := token.GetAppInfo(appURL)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := verifyTokenAtEdge(appURL, appInfo, c, log); err != nil {\n\t\tlog.Err(err).Msg(\"Could not verify token\")\n\t\treturn err\n\t}\n\n\tcfdToken, err := token.GetAppTokenIfExists(appInfo)\n\tif err != nil {\n\t\tfmt.Fprintln(os.Stderr, \"Unable to find token for provided application.\")\n\t\treturn err\n\t} else if cfdToken == \"\" {\n\t\tfmt.Fprintln(os.Stderr, \"token for provided application was empty.\")\n\t\treturn errors.New(\"empty application token\")\n\t}\n\n\tif c.Bool(loginQuietFlag) {\n\t\treturn nil\n\t}\n\n\t// Chatty by default for backward compat. The new --app flag\n\t// is an implicit opt-out of the backwards-compatible chatty output.\n\tif c.Bool(\"no-verbose\") || c.IsSet(appURLFlag) {\n\t\tfmt.Fprint(os.Stdout, cfdToken)\n\t} else {\n\t\tfmt.Fprintf(os.Stdout, \"Successfully fetched your token:\\n\\n%s\\n\\n\", cfdToken)\n\t}\n\n\treturn nil\n}\n\n// curl provides a wrapper around curl, passing Access JWT along in request\nfunc curl(c *cli.Context) error {\n\terr := sentry.Init(sentry.ClientOptions{\n\t\tDsn:     sentryDSN,\n\t\tRelease: c.App.Version,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\tlog := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog)\n\n\targs := c.Args()\n\tif args.Len() < 1 {\n\t\tlog.Error().Msg(\"Please provide the access app and command you wish to run.\")\n\t\treturn errors.New(\"incorrect args\")\n\t}\n\n\tcmdArgs, allowRequest := parseAllowRequest(args.Slice())\n\tappURL, err := getAppURL(cmdArgs, log)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tappInfo, err := token.GetAppInfo(appURL)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Verify that the existing token is still good; if not fetch a new one\n\tif err := verifyTokenAtEdge(appURL, appInfo, c, log); err != nil {\n\t\tlog.Err(err).Msg(\"Could not verify token\")\n\t\treturn err\n\t}\n\n\ttok, err := token.GetAppTokenIfExists(appInfo)\n\tif err != nil || tok == \"\" {\n\t\tif allowRequest {\n\t\t\tlog.Info().Msg(\"You don't have an Access token set. Please run access token <access application> to fetch one.\")\n\t\t\treturn run(\"curl\", cmdArgs...)\n\t\t}\n\t\ttok, err = token.FetchToken(appURL, appInfo, c.Bool(cfdflags.AutoCloseInterstitial), c.Bool(fedrampFlag), log)\n\t\tif err != nil {\n\t\t\tlog.Err(err).Msg(\"Failed to refresh token\")\n\t\t\treturn err\n\t\t}\n\t}\n\n\tcmdArgs = append(cmdArgs, \"-H\")\n\tcmdArgs = append(cmdArgs, fmt.Sprintf(\"%s: %s\", carrier.CFAccessTokenHeader, tok))\n\treturn run(\"curl\", cmdArgs...)\n}\n\n// run kicks off a shell task and pipe the results to the respective std pipes\nfunc run(cmd string, args ...string) error {\n\tc := exec.Command(cmd, args...)\n\tc.Stdin = os.Stdin\n\tstderr, err := c.StderrPipe()\n\tif err != nil {\n\t\treturn err\n\t}\n\tgo func() {\n\t\t_, _ = io.Copy(os.Stderr, stderr)\n\t}()\n\n\tstdout, err := c.StdoutPipe()\n\tif err != nil {\n\t\treturn err\n\t}\n\tgo func() {\n\t\t_, _ = io.Copy(os.Stdout, stdout)\n\t}()\n\treturn c.Run()\n}\n\nfunc getAppURLFromArgs(c *cli.Context) (*url.URL, error) {\n\tvar appURLStr string\n\targs := c.Args()\n\tif args.Len() < 1 {\n\t\tappURLStr = c.String(appURLFlag)\n\t} else {\n\t\tappURLStr = args.First()\n\t}\n\treturn parseURL(appURLStr)\n}\n\n// token dumps provided token to stdout\nfunc generateToken(c *cli.Context) error {\n\terr := sentry.Init(sentry.ClientOptions{\n\t\tDsn:     sentryDSN,\n\t\tRelease: c.App.Version,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\tappURL, err := getAppURLFromArgs(c)\n\tif err != nil {\n\t\tfmt.Fprintln(os.Stderr, \"Please provide a url.\")\n\t\treturn err\n\t}\n\n\tappInfo, err := token.GetAppInfo(appURL)\n\tif err != nil {\n\t\treturn err\n\t}\n\ttok, err := token.GetAppTokenIfExists(appInfo)\n\tif err != nil || tok == \"\" {\n\t\tfmt.Fprintln(os.Stderr, \"Unable to find token for provided application. Please run login command to generate token.\")\n\t\treturn err\n\t}\n\n\tif _, err := fmt.Fprint(os.Stdout, tok); err != nil {\n\t\tfmt.Fprintln(os.Stderr, \"Failed to write token to stdout.\")\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// sshConfig prints an example SSH config to stdout\nfunc sshConfig(c *cli.Context) error {\n\tgenCertBool := c.Bool(sshGenCertFlag)\n\thostname := c.String(sshHostnameFlag)\n\tif hostname == \"\" {\n\t\thostname = \"[your hostname]\"\n\t}\n\n\ttype config struct {\n\t\tHome            string\n\t\tShortLivedCerts bool\n\t\tHostname        string\n\t\tCloudflared     string\n\t}\n\n\tt := template.Must(template.New(\"sshConfig\").Parse(sshConfigTemplate))\n\treturn t.Execute(os.Stdout, config{Home: os.Getenv(\"HOME\"), ShortLivedCerts: genCertBool, Hostname: hostname, Cloudflared: cloudflaredPath()})\n}\n\n// sshGen generates a short lived certificate for provided hostname\nfunc sshGen(c *cli.Context) error {\n\tlog := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog)\n\n\t// get the hostname from the cmdline and error out if its not provided\n\trawHostName := c.String(sshHostnameFlag)\n\thostname, err := validation.ValidateHostname(rawHostName)\n\tif err != nil || rawHostName == \"\" {\n\t\treturn cli.ShowCommandHelp(c, \"ssh-gen\")\n\t}\n\n\toriginURL, err := parseURL(hostname)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// this fetchToken function mutates the appURL param. We should refactor that\n\tfetchTokenURL := &url.URL{}\n\t*fetchTokenURL = *originURL\n\n\tappInfo, err := token.GetAppInfo(fetchTokenURL)\n\tif err != nil {\n\t\treturn err\n\t}\n\tcfdToken, err := token.FetchTokenWithRedirect(fetchTokenURL, appInfo, c.Bool(cfdflags.AutoCloseInterstitial), c.Bool(fedrampFlag), log)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := sshgen.GenerateShortLivedCertificate(originURL, cfdToken); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// getAppURL will pull the request URL needed for fetching a user's Access token\nfunc getAppURL(cmdArgs []string, log *zerolog.Logger) (*url.URL, error) {\n\tif len(cmdArgs) < 1 {\n\t\tlog.Error().Msg(\"Please provide a valid URL as the first argument to curl.\")\n\t\treturn nil, errors.New(\"not a valid url\")\n\t}\n\n\tu, err := processURL(cmdArgs[0])\n\tif err != nil {\n\t\tlog.Error().Msg(\"Please provide a valid URL as the first argument to curl.\")\n\t\treturn nil, err\n\t}\n\n\treturn u, err\n}\n\n// parseAllowRequest will parse cmdArgs and return a copy of the args and result\n// of the allow request was present\nfunc parseAllowRequest(cmdArgs []string) ([]string, bool) {\n\tif len(cmdArgs) > 1 {\n\t\tif cmdArgs[0] == \"--allow-request\" || cmdArgs[0] == \"-ar\" {\n\t\t\treturn cmdArgs[1:], true\n\t\t}\n\t}\n\n\treturn cmdArgs, false\n}\n\n// processURL will preprocess the string (parse to a url, convert to punycode, etc).\nfunc processURL(s string) (*url.URL, error) {\n\tu, err := url.ParseRequestURI(s)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif u.Host == \"\" {\n\t\treturn nil, errors.New(\"not a valid host\")\n\t}\n\n\thost, err := idna.ToASCII(u.Hostname())\n\tif err != nil { // we fail to convert to punycode, just return the url we parsed.\n\t\treturn u, nil\n\t}\n\tif u.Port() != \"\" {\n\t\tu.Host = fmt.Sprintf(\"%s:%s\", host, u.Port())\n\t} else {\n\t\tu.Host = host\n\t}\n\n\treturn u, nil\n}\n\n// cloudflaredPath pulls the full path of cloudflared on disk\nfunc cloudflaredPath() string {\n\tpath, err := os.Executable()\n\tif err == nil && isFileThere(path) {\n\t\treturn path\n\t}\n\n\tfor _, p := range strings.Split(os.Getenv(\"PATH\"), \":\") {\n\t\tpath := fmt.Sprintf(\"%s/%s\", p, \"cloudflared\")\n\t\tif isFileThere(path) {\n\t\t\treturn path\n\t\t}\n\t}\n\treturn \"cloudflared\"\n}\n\n// isFileThere will check for the presence of candidate path\nfunc isFileThere(candidate string) bool {\n\tfi, err := os.Stat(candidate)\n\tif err != nil || fi.IsDir() || !fi.Mode().IsRegular() {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// verifyTokenAtEdge checks for a token on disk, or generates a new one.\n// Then makes a request to the origin with the token to ensure it is valid.\n// Returns nil if token is valid.\nfunc verifyTokenAtEdge(appUrl *url.URL, appInfo *token.AppInfo, c *cli.Context, log *zerolog.Logger) error {\n\theaders := parseRequestHeaders(c.StringSlice(sshHeaderFlag))\n\tif c.IsSet(sshTokenIDFlag) {\n\t\theaders.Add(cfAccessClientIDHeader, c.String(sshTokenIDFlag))\n\t}\n\tif c.IsSet(sshTokenSecretFlag) {\n\t\theaders.Add(cfAccessClientSecretHeader, c.String(sshTokenSecretFlag))\n\t}\n\toptions := &carrier.StartOptions{AppInfo: appInfo, OriginURL: appUrl.String(), Headers: headers, AutoCloseInterstitial: c.Bool(cfdflags.AutoCloseInterstitial), IsFedramp: c.Bool(fedrampFlag)}\n\n\tif valid, err := isTokenValid(options, log); err != nil {\n\t\treturn err\n\t} else if valid {\n\t\treturn nil\n\t}\n\n\tif err := token.RemoveTokenIfExists(appInfo); err != nil {\n\t\treturn err\n\t}\n\n\tif valid, err := isTokenValid(options, log); err != nil {\n\t\treturn err\n\t} else if !valid {\n\t\treturn errors.New(\"failed to verify token\")\n\t}\n\n\treturn nil\n}\n\n// isTokenValid makes a request to the origin and returns true if the response was not a 302.\nfunc isTokenValid(options *carrier.StartOptions, log *zerolog.Logger) (bool, error) {\n\treq, err := carrier.BuildAccessRequest(options, log)\n\tif err != nil {\n\t\treturn false, errors.Wrap(err, \"Could not create access request\")\n\t}\n\treq.Header.Set(\"User-Agent\", userAgent)\n\n\tquery := req.URL.Query()\n\tquery.Set(\"cloudflared_token_check\", \"true\")\n\treq.URL.RawQuery = query.Encode()\n\n\t// Do not follow redirects\n\tclient := &http.Client{\n\t\tCheckRedirect: func(req *http.Request, via []*http.Request) error {\n\t\t\treturn http.ErrUseLastResponse\n\t\t},\n\t\tTimeout: time.Second * 5,\n\t}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tdefer resp.Body.Close()\n\n\t// A redirect to login means the token was invalid.\n\treturn !carrier.IsAccessResponse(resp), nil\n}\n"
  },
  {
    "path": "cmd/cloudflared/access/validation.go",
    "content": "package access\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\n\t\"golang.org/x/net/http/httpguts\"\n)\n\n// parseRequestHeaders will take user-provided header values as strings \"Content-Type: application/json\" and create\n// a http.Header object.\nfunc parseRequestHeaders(values []string) http.Header {\n\theaders := make(http.Header)\n\tfor _, valuePair := range values {\n\t\theader, value, found := strings.Cut(valuePair, \":\")\n\t\tif found {\n\t\t\theaders.Add(strings.TrimSpace(header), strings.TrimSpace(value))\n\t\t}\n\t}\n\treturn headers\n}\n\n// parseHostname will attempt to convert a user provided URL string into a string with some light error checking on\n// certain expectations from the URL.\n// Will convert all HTTP URLs to HTTPS\nfunc parseURL(input string) (*url.URL, error) {\n\tif input == \"\" {\n\t\treturn nil, errors.New(\"no input provided\")\n\t}\n\tif !strings.HasPrefix(input, \"https://\") && !strings.HasPrefix(input, \"http://\") {\n\t\tinput = fmt.Sprintf(\"https://%s\", input)\n\t}\n\turl, err := url.ParseRequestURI(input)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse as URL: %w\", err)\n\t}\n\tif url.Scheme != \"https\" {\n\t\turl.Scheme = \"https\"\n\t}\n\tif url.Host == \"\" {\n\t\treturn nil, errors.New(\"failed to parse Host\")\n\t}\n\thost, err := httpguts.PunycodeHostPort(url.Host)\n\tif err != nil || host == \"\" {\n\t\treturn nil, err\n\t}\n\tif !httpguts.ValidHostHeader(host) {\n\t\treturn nil, errors.New(\"invalid Host provided\")\n\t}\n\turl.Host = host\n\treturn url, nil\n}\n"
  },
  {
    "path": "cmd/cloudflared/access/validation_test.go",
    "content": "package access\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestParseRequestHeaders(t *testing.T) {\n\tvalues := parseRequestHeaders([]string{\"client: value\", \"secret: safe-value\", \"trash\", \"cf-trace-id: 000:000:0:1:asd\"})\n\tassert.Len(t, values, 3)\n\tassert.Equal(t, \"value\", values.Get(\"client\"))\n\tassert.Equal(t, \"safe-value\", values.Get(\"secret\"))\n\tassert.Equal(t, \"000:000:0:1:asd\", values.Get(\"cf-trace-id\"))\n}\n\nfunc TestParseURL(t *testing.T) {\n\tschemes := []string{\n\t\t\"http://\",\n\t\t\"https://\",\n\t\t\"\",\n\t}\n\thosts := []struct {\n\t\tinput    string\n\t\texpected string\n\t}{\n\t\t{\"localhost\", \"localhost\"},\n\t\t{\"127.0.0.1\", \"127.0.0.1\"},\n\t\t{\"127.0.0.1:9090\", \"127.0.0.1:9090\"},\n\t\t{\"::1\", \"::1\"},\n\t\t{\"::1:8080\", \"::1:8080\"},\n\t\t{\"[::1]\", \"[::1]\"},\n\t\t{\"[::1]:8080\", \"[::1]:8080\"},\n\t\t{\":8080\", \":8080\"},\n\t\t{\"example.com\", \"example.com\"},\n\t\t{\"hello.example.com\", \"hello.example.com\"},\n\t\t{\"bücher.example.com\", \"xn--bcher-kva.example.com\"},\n\t}\n\tpaths := []string{\n\t\t\"\",\n\t\t\"/test\",\n\t\t\"/example.com?qwe=123\",\n\t}\n\tfor i, scheme := range schemes {\n\t\tfor j, host := range hosts {\n\t\t\tfor k, path := range paths {\n\t\t\t\tt.Run(fmt.Sprintf(\"%d_%d_%d\", i, j, k), func(t *testing.T) {\n\t\t\t\t\tinput := fmt.Sprintf(\"%s%s%s\", scheme, host.input, path)\n\t\t\t\t\texpected := fmt.Sprintf(\"%s%s%s\", \"https://\", host.expected, path)\n\t\t\t\t\turl, err := parseURL(input)\n\t\t\t\t\tassert.NoError(t, err, \"input: %s\\texpected: %s\", input, expected)\n\t\t\t\t\tassert.Equal(t, expected, url.String())\n\t\t\t\t\tassert.Equal(t, host.expected, url.Host)\n\t\t\t\t\tassert.Equal(t, \"https\", url.Scheme)\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\tt.Run(\"no input\", func(t *testing.T) {\n\t\t_, err := parseURL(\"\")\n\t\tassert.ErrorContains(t, err, \"no input provided\")\n\t})\n\n\tt.Run(\"missing host\", func(t *testing.T) {\n\t\t_, err := parseURL(\"https:///host\")\n\t\tassert.ErrorContains(t, err, \"failed to parse Host\")\n\t})\n\n\tt.Run(\"invalid path only\", func(t *testing.T) {\n\t\t_, err := parseURL(\"/host\")\n\t\tassert.ErrorContains(t, err, \"failed to parse Host\")\n\t})\n\n\tt.Run(\"invalid parse URL\", func(t *testing.T) {\n\t\t_, err := parseURL(\"https://host\\\\host\")\n\t\tassert.ErrorContains(t, err, \"failed to parse as URL\")\n\t})\n}\n"
  },
  {
    "path": "cmd/cloudflared/app_forward_service.go",
    "content": "package main\n\nimport (\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/access\"\n\t\"github.com/cloudflare/cloudflared/config\"\n)\n\n// ForwardServiceType is used to identify what kind of overwatch service this is\nconst ForwardServiceType = \"forward\"\n\n// ForwarderService is used to wrap the access package websocket forwarders\n// into a service model for the overwatch package.\n// it also holds a reference to the config object that represents its state\ntype ForwarderService struct {\n\tforwarder config.Forwarder\n\tshutdown  chan struct{}\n\tlog       *zerolog.Logger\n}\n\n// NewForwardService creates a new forwarder service\nfunc NewForwardService(f config.Forwarder, log *zerolog.Logger) *ForwarderService {\n\treturn &ForwarderService{forwarder: f, shutdown: make(chan struct{}, 1), log: log}\n}\n\n// Name is used to figure out this service is related to the others (normally the addr it binds to)\n// e.g. localhost:78641 or 127.0.0.1:2222 since this is a websocket forwarder\nfunc (s *ForwarderService) Name() string {\n\treturn s.forwarder.Listener\n}\n\n// Type is used to identify what kind of overwatch service this is\nfunc (s *ForwarderService) Type() string {\n\treturn ForwardServiceType\n}\n\n// Hash is used to figure out if this forwarder is the unchanged or not from the config file updates\nfunc (s *ForwarderService) Hash() string {\n\treturn s.forwarder.Hash()\n}\n\n// Shutdown stops the websocket listener\nfunc (s *ForwarderService) Shutdown() {\n\ts.shutdown <- struct{}{}\n}\n\n// Run is the run loop that is started by the overwatch service\nfunc (s *ForwarderService) Run() error {\n\treturn access.StartForwarder(s.forwarder, s.shutdown, s.log)\n}\n"
  },
  {
    "path": "cmd/cloudflared/app_service.go",
    "content": "package main\n\nimport (\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/overwatch\"\n)\n\n// AppService is the main service that runs when no command lines flags are passed to cloudflared\n// it manages all the running services such as tunnels, forwarders, etc\ntype AppService struct {\n\tconfigManager    config.Manager\n\tserviceManager   overwatch.Manager\n\tshutdownC        chan struct{}\n\tconfigUpdateChan chan config.Root\n\tlog              *zerolog.Logger\n}\n\n// NewAppService creates a new AppService with needed supporting services\nfunc NewAppService(configManager config.Manager, serviceManager overwatch.Manager, shutdownC chan struct{}, log *zerolog.Logger) *AppService {\n\treturn &AppService{\n\t\tconfigManager:    configManager,\n\t\tserviceManager:   serviceManager,\n\t\tshutdownC:        shutdownC,\n\t\tconfigUpdateChan: make(chan config.Root),\n\t\tlog:              log,\n\t}\n}\n\n// Run starts the run loop to handle config updates and run forwarders, tunnels, etc\nfunc (s *AppService) Run() error {\n\tgo s.actionLoop()\n\treturn s.configManager.Start(s)\n}\n\n// Shutdown kills all the running services\nfunc (s *AppService) Shutdown() error {\n\ts.configManager.Shutdown()\n\ts.shutdownC <- struct{}{}\n\n\treturn nil\n}\n\n// ConfigDidUpdate is a delegate notification from the config manager\n// it is trigger when the config file has been updated and now the service needs\n// to update its services accordingly\nfunc (s *AppService) ConfigDidUpdate(c config.Root) {\n\ts.configUpdateChan <- c\n}\n\n// actionLoop handles the actions from running processes\nfunc (s *AppService) actionLoop() {\n\tfor {\n\t\tselect {\n\t\tcase c := <-s.configUpdateChan:\n\t\t\ts.handleConfigUpdate(c)\n\t\tcase <-s.shutdownC:\n\t\t\tfor _, service := range s.serviceManager.Services() {\n\t\t\t\tservice.Shutdown()\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (s *AppService) handleConfigUpdate(c config.Root) {\n\t// handle the client forward listeners\n\tactiveServices := map[string]struct{}{}\n\tfor _, f := range c.Forwarders {\n\t\tservice := NewForwardService(f, s.log)\n\t\ts.serviceManager.Add(service)\n\t\tactiveServices[service.Name()] = struct{}{}\n\t}\n\n\t// TODO: TUN-1451 - tunnels\n\n\t// remove any services that are no longer active\n\tfor _, service := range s.serviceManager.Services() {\n\t\tif _, ok := activeServices[service.Name()]; !ok {\n\t\t\ts.serviceManager.Remove(service.Name())\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "cmd/cloudflared/cliutil/build_info.go",
    "content": "package cliutil\n\nimport (\n\t\"crypto/sha256\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"runtime\"\n\n\t\"github.com/rs/zerolog\"\n)\n\ntype BuildInfo struct {\n\tGoOS               string `json:\"go_os\"`\n\tGoVersion          string `json:\"go_version\"`\n\tGoArch             string `json:\"go_arch\"`\n\tBuildType          string `json:\"build_type\"`\n\tCloudflaredVersion string `json:\"cloudflared_version\"`\n\tChecksum           string `json:\"checksum\"`\n}\n\nfunc GetBuildInfo(buildType, version string) *BuildInfo {\n\treturn &BuildInfo{\n\t\tGoOS:               runtime.GOOS,\n\t\tGoVersion:          runtime.Version(),\n\t\tGoArch:             runtime.GOARCH,\n\t\tBuildType:          buildType,\n\t\tCloudflaredVersion: version,\n\t\tChecksum:           currentBinaryChecksum(),\n\t}\n}\n\nfunc (bi *BuildInfo) Log(log *zerolog.Logger) {\n\tlog.Info().Msgf(\"Version %s (Checksum %s)\", bi.CloudflaredVersion, bi.Checksum)\n\tif bi.BuildType != \"\" {\n\t\tlog.Info().Msgf(\"Built%s\", bi.GetBuildTypeMsg())\n\t}\n\tlog.Info().Msgf(\"GOOS: %s, GOVersion: %s, GoArch: %s\", bi.GoOS, bi.GoVersion, bi.GoArch)\n}\n\nfunc (bi *BuildInfo) OSArch() string {\n\treturn fmt.Sprintf(\"%s_%s\", bi.GoOS, bi.GoArch)\n}\n\nfunc (bi *BuildInfo) Version() string {\n\treturn bi.CloudflaredVersion\n}\n\nfunc (bi *BuildInfo) GetBuildTypeMsg() string {\n\tif bi.BuildType == \"\" {\n\t\treturn \"\"\n\t}\n\treturn fmt.Sprintf(\" with %s\", bi.BuildType)\n}\n\nfunc (bi *BuildInfo) UserAgent() string {\n\treturn fmt.Sprintf(\"cloudflared/%s\", bi.CloudflaredVersion)\n}\n\n// FileChecksum opens a file and returns the SHA256 checksum.\nfunc FileChecksum(filePath string) (string, error) {\n\tf, err := os.Open(filePath)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer f.Close()\n\n\th := sha256.New()\n\tif _, err := io.Copy(h, f); err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn fmt.Sprintf(\"%x\", h.Sum(nil)), nil\n}\n\nfunc currentBinaryChecksum() string {\n\tcurrentPath, err := os.Executable()\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\tsum, _ := FileChecksum(currentPath)\n\treturn sum\n}\n"
  },
  {
    "path": "cmd/cloudflared/cliutil/deprecated.go",
    "content": "package cliutil\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/urfave/cli/v2\"\n)\n\nfunc RemovedCommand(name string) *cli.Command {\n\treturn &cli.Command{\n\t\tName: name,\n\t\tAction: func(context *cli.Context) error {\n\t\t\treturn cli.Exit(\n\t\t\t\tfmt.Sprintf(\"%s command is no longer supported by cloudflared. Consult Cloudflare Tunnel documentation for possible alternative solutions.\", name),\n\t\t\t\t-1,\n\t\t\t)\n\t\t},\n\t\tDescription: fmt.Sprintf(\"%s is deprecated\", name),\n\t\tHidden:      true,\n\t}\n}\n"
  },
  {
    "path": "cmd/cloudflared/cliutil/errors.go",
    "content": "package cliutil\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/urfave/cli/v2\"\n)\n\ntype usageError string\n\nfunc (ue usageError) Error() string {\n\treturn string(ue)\n}\n\nfunc UsageError(format string, args ...interface{}) error {\n\tif len(args) == 0 {\n\t\treturn usageError(format)\n\t} else {\n\t\tmsg := fmt.Sprintf(format, args...)\n\t\treturn usageError(msg)\n\t}\n}\n\n// Ensures exit with error code if actionFunc returns an error\nfunc WithErrorHandler(actionFunc cli.ActionFunc) cli.ActionFunc {\n\treturn func(ctx *cli.Context) error {\n\t\terr := actionFunc(ctx)\n\t\tif err != nil {\n\t\t\tif _, ok := err.(usageError); ok {\n\t\t\t\tmsg := fmt.Sprintf(\"%s\\nSee 'cloudflared %s --help'.\", err.Error(), ctx.Command.FullName())\n\t\t\t\terr = cli.Exit(msg, -1)\n\t\t\t} else if _, ok := err.(cli.ExitCoder); !ok {\n\t\t\t\terr = cli.Exit(err.Error(), 1)\n\t\t\t}\n\t\t}\n\t\treturn err\n\t}\n}\n"
  },
  {
    "path": "cmd/cloudflared/cliutil/handler.go",
    "content": "package cliutil\n\nimport (\n\t\"github.com/urfave/cli/v2\"\n\t\"github.com/urfave/cli/v2/altsrc\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/logger\"\n)\n\nfunc Action(actionFunc cli.ActionFunc) cli.ActionFunc {\n\treturn WithErrorHandler(actionFunc)\n}\n\nfunc ConfiguredAction(actionFunc cli.ActionFunc) cli.ActionFunc {\n\t// Adapt actionFunc to the type signature required by ConfiguredActionWithWarnings\n\tf := func(context *cli.Context, _ string) error {\n\t\treturn actionFunc(context)\n\t}\n\n\treturn ConfiguredActionWithWarnings(f)\n}\n\n// Just like ConfiguredAction, but accepts a second parameter with configuration warnings.\nfunc ConfiguredActionWithWarnings(actionFunc func(*cli.Context, string) error) cli.ActionFunc {\n\treturn WithErrorHandler(func(c *cli.Context) error {\n\t\twarnings, err := setFlagsFromConfigFile(c)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn actionFunc(c, warnings)\n\t})\n}\n\nfunc setFlagsFromConfigFile(c *cli.Context) (configWarnings string, err error) {\n\tconst errorExitCode = 1\n\tlog := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog)\n\tinputSource, warnings, err := config.ReadConfigFile(c, log)\n\tif err != nil {\n\t\tif err == config.ErrNoConfigFile {\n\t\t\treturn \"\", nil\n\t\t}\n\t\treturn \"\", cli.Exit(err, errorExitCode)\n\t}\n\n\tif err := altsrc.ApplyInputSource(c, inputSource); err != nil {\n\t\treturn \"\", cli.Exit(err, errorExitCode)\n\t}\n\treturn warnings, nil\n}\n"
  },
  {
    "path": "cmd/cloudflared/cliutil/logger.go",
    "content": "package cliutil\n\nimport (\n\t\"github.com/urfave/cli/v2\"\n\t\"github.com/urfave/cli/v2/altsrc\"\n\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n)\n\nvar (\n\tdebugLevelWarning = \"At debug level cloudflared will log request URL, method, protocol, content length, as well as, all request and response headers. \" +\n\t\t\"This can expose sensitive information in your logs.\"\n\n\tFlagLogOutput = &cli.StringFlag{\n\t\tName:    flags.LogFormatOutput,\n\t\tUsage:   \"Output format for the logs (default, json)\",\n\t\tValue:   flags.LogFormatOutputValueDefault,\n\t\tEnvVars: []string{\"TUNNEL_MANAGEMENT_OUTPUT\", \"TUNNEL_LOG_OUTPUT\"},\n\t}\n)\n\nfunc ConfigureLoggingFlags(shouldHide bool) []cli.Flag {\n\treturn []cli.Flag{\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    flags.LogLevel,\n\t\t\tValue:   \"info\",\n\t\t\tUsage:   \"Application logging level {debug, info, warn, error, fatal}. \" + debugLevelWarning,\n\t\t\tEnvVars: []string{\"TUNNEL_LOGLEVEL\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    flags.TransportLogLevel,\n\t\t\tAliases: []string{\"proto-loglevel\"}, // This flag used to be called proto-loglevel\n\t\t\tValue:   \"info\",\n\t\t\tUsage:   \"Transport logging level(previously called protocol logging level) {debug, info, warn, error, fatal}\",\n\t\t\tEnvVars: []string{\"TUNNEL_PROTO_LOGLEVEL\", \"TUNNEL_TRANSPORT_LOGLEVEL\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    flags.LogFile,\n\t\t\tUsage:   \"Save application log to this file for reporting issues.\",\n\t\t\tEnvVars: []string{\"TUNNEL_LOGFILE\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    flags.LogDirectory,\n\t\t\tUsage:   \"Save application log to this directory for reporting issues.\",\n\t\t\tEnvVars: []string{\"TUNNEL_LOGDIRECTORY\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    flags.TraceOutput,\n\t\t\tUsage:   \"Name of trace output file, generated when cloudflared stops.\",\n\t\t\tEnvVars: []string{\"TUNNEL_TRACE_OUTPUT\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\tFlagLogOutput,\n\t}\n}\n"
  },
  {
    "path": "cmd/cloudflared/cliutil/management.go",
    "content": "package cliutil\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/mattn/go-colorable\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/cloudflare/cloudflared/cfapi\"\n\tcfdflags \"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n\t\"github.com/cloudflare/cloudflared/credentials\"\n)\n\n// Error definitions for management token operations\nvar (\n\tErrNoTunnelID      = errors.New(\"no tunnel ID provided\")\n\tErrInvalidTunnelID = errors.New(\"unable to parse provided tunnel id as a valid UUID\")\n)\n\n// GetManagementToken acquires a management token from Cloudflare API for the specified resource\nfunc GetManagementToken(c *cli.Context, log *zerolog.Logger, res cfapi.ManagementResource, buildInfo *BuildInfo) (string, error) {\n\tuserCreds, err := credentials.Read(c.String(cfdflags.OriginCert), log)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tvar apiURL string\n\tif userCreds.IsFEDEndpoint() {\n\t\tapiURL = credentials.FedRampBaseApiURL\n\t} else {\n\t\tapiURL = c.String(cfdflags.ApiURL)\n\t}\n\n\tclient, err := userCreds.Client(apiURL, buildInfo.UserAgent(), log)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\ttunnelIDString := c.Args().First()\n\tif tunnelIDString == \"\" {\n\t\treturn \"\", ErrNoTunnelID\n\t}\n\ttunnelID, err := uuid.Parse(tunnelIDString)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"%w: %v\", ErrInvalidTunnelID, err)\n\t}\n\n\ttoken, err := client.GetManagementToken(tunnelID, res)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn token, nil\n}\n\n// CreateStderrLogger creates a logger that outputs to stderr to avoid interfering with stdout\nfunc CreateStderrLogger(c *cli.Context) *zerolog.Logger {\n\tlevel, levelErr := zerolog.ParseLevel(c.String(cfdflags.LogLevel))\n\tif levelErr != nil {\n\t\tlevel = zerolog.InfoLevel\n\t}\n\tvar writer io.Writer\n\tswitch c.String(cfdflags.LogFormatOutput) {\n\tcase cfdflags.LogFormatOutputValueJSON:\n\t\t// zerolog by default outputs as JSON\n\t\twriter = os.Stderr\n\tcase cfdflags.LogFormatOutputValueDefault:\n\t\t// \"default\" and unset use the same logger output format\n\t\tfallthrough\n\tdefault:\n\t\twriter = zerolog.ConsoleWriter{\n\t\t\tOut:        colorable.NewColorable(os.Stderr),\n\t\t\tTimeFormat: time.RFC3339,\n\t\t}\n\t}\n\tlog := zerolog.New(writer).With().Timestamp().Logger().Level(level)\n\treturn &log\n}\n"
  },
  {
    "path": "cmd/cloudflared/common_service.go",
    "content": "package main\n\nimport (\n\t\"github.com/rs/zerolog\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/tunnel\"\n)\n\nfunc buildArgsForToken(c *cli.Context, log *zerolog.Logger) ([]string, error) {\n\ttoken := c.Args().First()\n\tif _, err := tunnel.ParseToken(token); err != nil {\n\t\treturn nil, cliutil.UsageError(\"Provided tunnel token is not valid (%s).\", err)\n\t}\n\n\treturn []string{\n\t\t\"tunnel\", \"run\", \"--token\", token,\n\t}, nil\n}\n\nfunc getServiceExtraArgsFromCliArgs(c *cli.Context, log *zerolog.Logger) ([]string, error) {\n\tif c.NArg() > 0 {\n\t\t// currently, we only support extra args for token\n\t\treturn buildArgsForToken(c, log)\n\t} else {\n\t\t// empty extra args\n\t\treturn make([]string, 0), nil\n\t}\n}\n"
  },
  {
    "path": "cmd/cloudflared/flags/flags.go",
    "content": "package flags\n\nconst (\n\t// HaConnections specifies how many connections to make to the edge\n\tHaConnections = \"ha-connections\"\n\n\t// SshPort is the port on localhost the cloudflared ssh server will run on\n\tSshPort = \"local-ssh-port\"\n\n\t// SshIdleTimeout defines the duration a SSH session can remain idle before being closed\n\tSshIdleTimeout = \"ssh-idle-timeout\"\n\n\t// SshMaxTimeout defines the max duration a SSH session can remain open for\n\tSshMaxTimeout = \"ssh-max-timeout\"\n\n\t// SshLogUploaderBucketName is the bucket name to use for the SSH log uploader\n\tSshLogUploaderBucketName = \"bucket-name\"\n\n\t// SshLogUploaderRegionName is the AWS region name to use for the SSH log uploader\n\tSshLogUploaderRegionName = \"region-name\"\n\n\t// SshLogUploaderSecretID is the Secret id of SSH log uploader\n\tSshLogUploaderSecretID = \"secret-id\"\n\n\t// SshLogUploaderAccessKeyID is the Access key id of SSH log uploader\n\tSshLogUploaderAccessKeyID = \"access-key-id\"\n\n\t// SshLogUploaderSessionTokenID is the Session token of SSH log uploader\n\tSshLogUploaderSessionTokenID = \"session-token\"\n\n\t// SshLogUploaderS3URL is the S3 URL of SSH log uploader (e.g. don't use AWS s3 and use google storage bucket instead)\n\tSshLogUploaderS3URL = \"s3-url-host\"\n\n\t// HostKeyPath is the path of the dir to save SSH host keys too\n\tHostKeyPath = \"host-key-path\"\n\n\t// RpcTimeout is how long to wait for a Capnp RPC request to the edge\n\tRpcTimeout = \"rpc-timeout\"\n\n\t// WriteStreamTimeout sets if we should have a timeout when writing data to a stream towards the destination (edge/origin).\n\tWriteStreamTimeout = \"write-stream-timeout\"\n\n\t// QuicDisablePathMTUDiscovery sets if QUIC should not perform PTMU discovery and use a smaller (safe) packet size.\n\t// Packets will then be at most 1252 (IPv4) / 1232 (IPv6) bytes in size.\n\t// Note that this may result in packet drops for UDP proxying, since we expect being able to send at least 1280 bytes of inner packets.\n\tQuicDisablePathMTUDiscovery = \"quic-disable-pmtu-discovery\"\n\n\t// QuicConnLevelFlowControlLimit controls the max flow control limit allocated for a QUIC connection. This controls how much data is the\n\t// receiver willing to buffer. Once the limit is reached, the sender will send a DATA_BLOCKED frame to indicate it has more data to write,\n\t// but it's blocked by flow control\n\tQuicConnLevelFlowControlLimit = \"quic-connection-level-flow-control-limit\"\n\n\t// QuicStreamLevelFlowControlLimit is similar to quicConnLevelFlowControlLimit but for each QUIC stream. When the sender is blocked,\n\t// it will send a STREAM_DATA_BLOCKED frame\n\tQuicStreamLevelFlowControlLimit = \"quic-stream-level-flow-control-limit\"\n\n\t// Ui is to enable launching cloudflared in interactive UI mode\n\tUi = \"ui\"\n\n\t// ConnectorLabel is the command line flag to give a meaningful label to a specific connector\n\tConnectorLabel = \"label\"\n\n\t// MaxActiveFlows is the command line flag to set the maximum number of flows that cloudflared can be processing at the same time\n\tMaxActiveFlows = \"max-active-flows\"\n\n\t// Tag is the command line flag to set custom tags used to identify this tunnel via added HTTP request headers to the origin\n\tTag = \"tag\"\n\n\t// Protocol is the command line flag to set the protocol to use to connect to the Cloudflare Edge\n\tProtocol = \"protocol\"\n\n\t// PostQuantum is the command line flag to force the connection to Cloudflare Edge to use Post Quantum cryptography\n\tPostQuantum = \"post-quantum\"\n\n\t// Features is the command line flag to opt into various features that are still being developed or tested\n\tFeatures = \"features\"\n\n\t// EdgeIpVersion is the command line flag to set the Cloudflare Edge IP address version to connect with\n\tEdgeIpVersion = \"edge-ip-version\"\n\n\t// EdgeBindAddress is the command line flag to bind to IP address for outgoing connections to Cloudflare Edge\n\tEdgeBindAddress = \"edge-bind-address\"\n\n\t// Force is the command line flag to specify if you wish to force an action\n\tForce = \"force\"\n\n\t// Edge is the command line flag to set the address of the Cloudflare tunnel server. Only works in Cloudflare's internal testing environment\n\tEdge = \"edge\"\n\n\t// Region is the command line flag to set the Cloudflare Edge region to connect to\n\tRegion = \"region\"\n\n\t// IsAutoUpdated is the command line flag to signal the new process that cloudflared has been autoupdated\n\tIsAutoUpdated = \"is-autoupdated\"\n\n\t// LBPool is the command line flag to set the name of the load balancing pool to add this origin to\n\tLBPool = \"lb-pool\"\n\n\t// Retries is the command line flag to set the maximum number of retries for connection/protocol errors\n\tRetries = \"retries\"\n\n\t// MaxEdgeAddrRetries is the command line flag to set the maximum number of times to retry on edge addrs before falling back to a lower protocol\n\tMaxEdgeAddrRetries = \"max-edge-addr-retries\"\n\n\t// GracePeriod is the command line flag to set the maximum amount of time that cloudflared waits to shut down if it is still serving requests\n\tGracePeriod = \"grace-period\"\n\n\t// ICMPV4Src is the command line flag to set the source address and the interface name to send/receive ICMPv4 messages\n\tICMPV4Src = \"icmpv4-src\"\n\n\t// ICMPV6Src is the command line flag to set the source address and the interface name to send/receive ICMPv6 messages\n\tICMPV6Src = \"icmpv6-src\"\n\n\t// Name is the command line to set the name of the tunnel\n\tName = \"name\"\n\n\t// AutoUpdateFreq is the command line for setting the frequency that cloudflared checks for updates\n\tAutoUpdateFreq = \"autoupdate-freq\"\n\n\t// NoAutoUpdate is the command line flag to disable cloudflared from checking for updates\n\tNoAutoUpdate = \"no-autoupdate\"\n\n\t// LogLevel is the command line flag for the cloudflared logging level\n\tLogLevel = \"loglevel\"\n\n\t// LogLevelSSH is the command line flag for the cloudflared ssh logging level\n\tLogLevelSSH = \"log-level\"\n\n\t// TransportLogLevel is the command line flag for the transport logging level\n\tTransportLogLevel = \"transport-loglevel\"\n\n\t// LogFile is the command line flag to define the file where application logs will be stored\n\tLogFile = \"logfile\"\n\n\t// LogDirectory is the command line flag to define the directory where application logs will be stored.\n\tLogDirectory = \"log-directory\"\n\n\t// LogFormatOutput allows the command line logs to be output as JSON.\n\tLogFormatOutput             = \"output\"\n\tLogFormatOutputValueDefault = \"default\"\n\tLogFormatOutputValueJSON    = \"json\"\n\n\t// TraceOutput is the command line flag to set the name of trace output file\n\tTraceOutput = \"trace-output\"\n\n\t// OriginCert is the command line flag to define the path for the origin certificate used by cloudflared\n\tOriginCert = \"origincert\"\n\n\t// Metrics is the command line flag to define the address of the metrics server\n\tMetrics = \"metrics\"\n\n\t// MetricsUpdateFreq is the command line flag to define how frequently tunnel metrics are updated\n\tMetricsUpdateFreq = \"metrics-update-freq\"\n\n\t// ApiURL is the command line flag used to define the base URL of the API\n\tApiURL = \"api-url\"\n\n\t// Virtual DNS resolver service resolver addresses to use instead of dynamically fetching them from the OS.\n\tVirtualDNSServiceResolverAddresses = \"dns-resolver-addrs\"\n\n\t// Management hostname to signify incoming management requests\n\tManagementHostname = \"management-hostname\"\n\n\t// Automatically close the login interstitial browser window after the user makes a decision.\n\tAutoCloseInterstitial = \"auto-close\"\n)\n"
  },
  {
    "path": "cmd/cloudflared/generic_service.go",
    "content": "//go:build !windows && !darwin && !linux\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\tcli \"github.com/urfave/cli/v2\"\n\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n)\n\nfunc runApp(app *cli.App, graceShutdownC chan struct{}) {\n\tapp.Commands = append(app.Commands, &cli.Command{\n\t\tName:  \"service\",\n\t\tUsage: \"Manages the cloudflared system service (not supported on this operating system)\",\n\t\tSubcommands: []*cli.Command{\n\t\t\t{\n\t\t\t\tName:   \"install\",\n\t\t\t\tUsage:  \"Install cloudflared as a system service (not supported on this operating system)\",\n\t\t\t\tAction: cliutil.ConfiguredAction(installGenericService),\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:   \"uninstall\",\n\t\t\t\tUsage:  \"Uninstall the cloudflared service (not supported on this operating system)\",\n\t\t\t\tAction: cliutil.ConfiguredAction(uninstallGenericService),\n\t\t\t},\n\t\t},\n\t})\n\tapp.Run(os.Args)\n}\n\nfunc installGenericService(c *cli.Context) error {\n\treturn fmt.Errorf(\"service installation is not supported on this operating system\")\n}\n\nfunc uninstallGenericService(c *cli.Context) error {\n\treturn fmt.Errorf(\"service uninstallation is not supported on this operating system\")\n}\n"
  },
  {
    "path": "cmd/cloudflared/linux_service.go",
    "content": "//go:build linux\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\n\t\"github.com/rs/zerolog\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/tunnel\"\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/logger\"\n)\n\nfunc runApp(app *cli.App, _ chan struct{}) {\n\tapp.Commands = append(app.Commands, &cli.Command{\n\t\tName:  \"service\",\n\t\tUsage: \"Manages the cloudflared system service\",\n\t\tSubcommands: []*cli.Command{\n\t\t\t{\n\t\t\t\tName:   \"install\",\n\t\t\t\tUsage:  \"Install cloudflared as a system service\",\n\t\t\t\tAction: cliutil.ConfiguredAction(installLinuxService),\n\t\t\t\tFlags: []cli.Flag{\n\t\t\t\t\tnoUpdateServiceFlag,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:   \"uninstall\",\n\t\t\t\tUsage:  \"Uninstall the cloudflared service\",\n\t\t\t\tAction: cliutil.ConfiguredAction(uninstallLinuxService),\n\t\t\t},\n\t\t},\n\t})\n\t_ = app.Run(os.Args)\n}\n\n// The directory and files that are used by the service.\n// These are hard-coded in the templates below.\nconst (\n\tserviceConfigDir         = \"/etc/cloudflared\"\n\tserviceConfigFile        = \"config.yml\"\n\tserviceCredentialFile    = \"cert.pem\"\n\tserviceConfigPath        = serviceConfigDir + \"/\" + serviceConfigFile\n\tcloudflaredService       = \"cloudflared.service\"\n\tcloudflaredUpdateService = \"cloudflared-update.service\"\n\tcloudflaredUpdateTimer   = \"cloudflared-update.timer\"\n)\n\nvar systemdAllTemplates = map[string]ServiceTemplate{\n\tcloudflaredService: {\n\t\tPath: fmt.Sprintf(\"/etc/systemd/system/%s\", cloudflaredService),\n\t\tContent: `[Unit]\nDescription=cloudflared\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nTimeoutStartSec=15\nType=notify\nExecStart={{ .Path }} --no-autoupdate{{ range .ExtraArgs }} {{ . }}{{ end }}\nRestart=on-failure\nRestartSec=5s\n\n[Install]\nWantedBy=multi-user.target\n`,\n\t},\n\tcloudflaredUpdateService: {\n\t\tPath: fmt.Sprintf(\"/etc/systemd/system/%s\", cloudflaredUpdateService),\n\t\tContent: `[Unit]\nDescription=Update cloudflared\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nExecStart=/bin/bash -c '{{ .Path }} update; code=$?; if [ $code -eq 11 ]; then systemctl restart cloudflared; exit 0; fi; exit $code'\n`,\n\t},\n\tcloudflaredUpdateTimer: {\n\t\tPath: fmt.Sprintf(\"/etc/systemd/system/%s\", cloudflaredUpdateTimer),\n\t\tContent: `[Unit]\nDescription=Update cloudflared\n\n[Timer]\nOnCalendar=daily\n\n[Install]\nWantedBy=timers.target\n`,\n\t},\n}\n\nvar sysvTemplate = ServiceTemplate{\n\tPath:     \"/etc/init.d/cloudflared\",\n\tFileMode: 0755,\n\t// nolint: dupword\n\tContent: `#!/bin/sh\n# For RedHat and cousins:\n# chkconfig: 2345 99 01\n# description: cloudflared\n# processname: {{.Path}}\n### BEGIN INIT INFO\n# Provides:          {{.Path}}\n# Required-Start:\n# Required-Stop:\n# Default-Start:     2 3 4 5\n# Default-Stop:      0 1 6\n# Short-Description: cloudflared\n# Description:       cloudflared agent\n### END INIT INFO\nname=$(basename $(readlink -f $0))\ncmd=\"{{.Path}} --pidfile /var/run/$name.pid {{ range .ExtraArgs }} {{ . }}{{ end }}\"\npid_file=\"/var/run/$name.pid\"\nstdout_log=\"/var/log/$name.log\"\nstderr_log=\"/var/log/$name.err\"\n[ -e /etc/sysconfig/$name ] && . /etc/sysconfig/$name\nget_pid() {\n    cat \"$pid_file\"\n}\nis_running() {\n    [ -f \"$pid_file\" ] && ps $(get_pid) > /dev/null 2>&1\n}\ncase \"$1\" in\n    start)\n        if is_running; then\n            echo \"Already started\"\n        else\n            echo \"Starting $name\"\n            $cmd >> \"$stdout_log\" 2>> \"$stderr_log\" &\n            echo $! > \"$pid_file\"\n        fi\n    ;;\n    stop)\n        if is_running; then\n            echo -n \"Stopping $name..\"\n            kill $(get_pid)\n            for i in {1..10}\n            do\n                if ! is_running; then\n                    break\n                fi\n                echo -n \".\"\n                sleep 1\n            done\n            echo\n            if is_running; then\n                echo \"Not stopped; may still be shutting down or shutdown may have failed\"\n                exit 1\n            else\n                echo \"Stopped\"\n                if [ -f \"$pid_file\" ]; then\n                    rm \"$pid_file\"\n                fi\n            fi\n        else\n            echo \"Not running\"\n        fi\n    ;;\n    restart)\n        $0 stop\n        if is_running; then\n            echo \"Unable to stop, will not attempt to start\"\n            exit 1\n        fi\n        $0 start\n    ;;\n    status)\n        if is_running; then\n            echo \"Running\"\n        else\n            echo \"Stopped\"\n            exit 1\n        fi\n    ;;\n    *)\n    echo \"Usage: $0 {start|stop|restart|status}\"\n    exit 1\n    ;;\nesac\nexit 0\n`,\n}\n\nvar noUpdateServiceFlag = &cli.BoolFlag{\n\tName:  \"no-update-service\",\n\tUsage: \"Disable auto-update of the cloudflared linux service, which restarts the server to upgrade for new versions.\",\n\tValue: false,\n}\n\nfunc isSystemd() bool {\n\tif _, err := os.Stat(\"/run/systemd/system\"); err == nil {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc installLinuxService(c *cli.Context) error {\n\tlog := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog)\n\n\tetPath, err := os.Executable()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error determining executable path: %v\", err)\n\t}\n\ttemplateArgs := ServiceTemplateArgs{\n\t\tPath: etPath,\n\t}\n\n\t// Check if the \"no update flag\" is set\n\tautoUpdate := !c.IsSet(noUpdateServiceFlag.Name)\n\n\tvar extraArgsFunc func(c *cli.Context, log *zerolog.Logger) ([]string, error)\n\tif c.NArg() == 0 {\n\t\textraArgsFunc = buildArgsForConfig\n\t} else {\n\t\textraArgsFunc = buildArgsForToken\n\t}\n\n\textraArgs, err := extraArgsFunc(c, log)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ttemplateArgs.ExtraArgs = extraArgs\n\n\tswitch {\n\tcase isSystemd():\n\t\tlog.Info().Msgf(\"Using Systemd\")\n\t\terr = installSystemd(&templateArgs, autoUpdate, log)\n\tdefault:\n\t\tlog.Info().Msgf(\"Using SysV\")\n\t\terr = installSysv(&templateArgs, autoUpdate, log)\n\t}\n\n\tif err == nil {\n\t\tlog.Info().Msg(\"Linux service for cloudflared installed successfully\")\n\t}\n\treturn err\n}\n\nfunc buildArgsForConfig(c *cli.Context, log *zerolog.Logger) ([]string, error) {\n\tif err := ensureConfigDirExists(serviceConfigDir); err != nil {\n\t\treturn nil, err\n\t}\n\n\tsrc, _, err := config.ReadConfigFile(c, log)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// can't use context because this command doesn't define \"credentials-file\" flag\n\tconfigPresent := func(s string) bool {\n\t\tval, err := src.String(s)\n\t\treturn err == nil && val != \"\"\n\t}\n\tif src.TunnelID == \"\" || !configPresent(tunnel.CredFileFlag) {\n\t\treturn nil, fmt.Errorf(`Configuration file %s must contain entries for the tunnel to run and its associated credentials:\ntunnel: TUNNEL-UUID\ncredentials-file: CREDENTIALS-FILE\n`, src.Source())\n\t}\n\tif src.Source() != serviceConfigPath {\n\t\tif exists, err := config.FileExists(serviceConfigPath); err != nil || exists {\n\t\t\treturn nil, fmt.Errorf(\"Possible conflicting configuration in %[1]s and %[2]s. Either remove %[2]s or run `cloudflared --config %[2]s service install`\", src.Source(), serviceConfigPath)\n\t\t}\n\n\t\tif err := copyFile(src.Source(), serviceConfigPath); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to copy %s to %s: %w\", src.Source(), serviceConfigPath, err)\n\t\t}\n\t}\n\n\treturn []string{\n\t\t\"--config\", \"/etc/cloudflared/config.yml\", \"tunnel\", \"run\",\n\t}, nil\n}\n\nfunc installSystemd(templateArgs *ServiceTemplateArgs, autoUpdate bool, log *zerolog.Logger) error {\n\tvar systemdTemplates []ServiceTemplate\n\tif autoUpdate {\n\t\tsystemdTemplates = []ServiceTemplate{\n\t\t\tsystemdAllTemplates[cloudflaredService],\n\t\t\tsystemdAllTemplates[cloudflaredUpdateService],\n\t\t\tsystemdAllTemplates[cloudflaredUpdateTimer],\n\t\t}\n\t} else {\n\t\tsystemdTemplates = []ServiceTemplate{\n\t\t\tsystemdAllTemplates[cloudflaredService],\n\t\t}\n\t}\n\n\tfor _, serviceTemplate := range systemdTemplates {\n\t\terr := serviceTemplate.Generate(templateArgs)\n\t\tif err != nil {\n\t\t\tlog.Err(err).Msg(\"error generating service template\")\n\t\t\treturn err\n\t\t}\n\t}\n\tif err := runCommand(\"systemctl\", \"enable\", cloudflaredService); err != nil {\n\t\tlog.Err(err).Msgf(\"systemctl enable %s error\", cloudflaredService)\n\t\treturn err\n\t}\n\n\tif autoUpdate {\n\t\tif err := runCommand(\"systemctl\", \"start\", cloudflaredUpdateTimer); err != nil {\n\t\t\tlog.Err(err).Msgf(\"systemctl start %s error\", cloudflaredUpdateTimer)\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif err := runCommand(\"systemctl\", \"daemon-reload\"); err != nil {\n\t\tlog.Err(err).Msg(\"systemctl daemon-reload error\")\n\t\treturn err\n\t}\n\treturn runCommand(\"systemctl\", \"start\", cloudflaredService)\n}\n\nfunc installSysv(templateArgs *ServiceTemplateArgs, autoUpdate bool, log *zerolog.Logger) error {\n\tconfPath, err := sysvTemplate.ResolvePath()\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"error resolving system path\")\n\t\treturn err\n\t}\n\n\tif autoUpdate {\n\t\ttemplateArgs.ExtraArgs = append([]string{\"--autoupdate-freq 24h0m0s\"}, templateArgs.ExtraArgs...)\n\t} else {\n\t\ttemplateArgs.ExtraArgs = append([]string{\"--no-autoupdate\"}, templateArgs.ExtraArgs...)\n\t}\n\n\tif err := sysvTemplate.Generate(templateArgs); err != nil {\n\t\tlog.Err(err).Msg(\"error generating system template\")\n\t\treturn err\n\t}\n\tfor _, i := range [...]string{\"2\", \"3\", \"4\", \"5\"} {\n\t\tif err := os.Symlink(confPath, \"/etc/rc\"+i+\".d/S50et\"); err != nil {\n\t\t\tcontinue\n\t\t}\n\t}\n\tfor _, i := range [...]string{\"0\", \"1\", \"6\"} {\n\t\tif err := os.Symlink(confPath, \"/etc/rc\"+i+\".d/K02et\"); err != nil {\n\t\t\tcontinue\n\t\t}\n\t}\n\treturn runCommand(\"service\", \"cloudflared\", \"start\")\n}\n\nfunc uninstallLinuxService(c *cli.Context) error {\n\tlog := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog)\n\n\tvar err error\n\tswitch {\n\tcase isSystemd():\n\t\tlog.Info().Msg(\"Using Systemd\")\n\t\terr = uninstallSystemd(log)\n\tdefault:\n\t\tlog.Info().Msg(\"Using SysV\")\n\t\terr = uninstallSysv(log)\n\t}\n\n\tif err == nil {\n\t\tlog.Info().Msg(\"Linux service for cloudflared uninstalled successfully\")\n\t}\n\treturn err\n}\n\nfunc uninstallSystemd(log *zerolog.Logger) error {\n\t// Get only the installed services\n\tinstalledServices := make(map[string]ServiceTemplate)\n\tfor serviceName, serviceTemplate := range systemdAllTemplates {\n\t\tif err := runCommand(\"systemctl\", \"list-units\", \"--all\", \"|\", \"grep\", serviceName); err == nil {\n\t\t\tinstalledServices[serviceName] = serviceTemplate\n\t\t} else {\n\t\t\tlog.Info().Msgf(\"Service '%s' not installed, skipping its uninstall\", serviceName)\n\t\t}\n\t}\n\n\tif _, exists := installedServices[cloudflaredService]; exists {\n\t\tif err := runCommand(\"systemctl\", \"disable\", cloudflaredService); err != nil {\n\t\t\tlog.Err(err).Msgf(\"systemctl disable %s error\", cloudflaredService)\n\t\t\treturn err\n\t\t}\n\t\tif err := runCommand(\"systemctl\", \"stop\", cloudflaredService); err != nil {\n\t\t\tlog.Err(err).Msgf(\"systemctl stop %s error\", cloudflaredService)\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif _, exists := installedServices[cloudflaredUpdateTimer]; exists {\n\t\tif err := runCommand(\"systemctl\", \"stop\", cloudflaredUpdateTimer); err != nil {\n\t\t\tlog.Err(err).Msgf(\"systemctl stop %s error\", cloudflaredUpdateTimer)\n\t\t\treturn err\n\t\t}\n\t}\n\n\tfor _, serviceTemplate := range installedServices {\n\t\tif err := serviceTemplate.Remove(); err != nil {\n\t\t\tlog.Err(err).Msg(\"error removing service template\")\n\t\t\treturn err\n\t\t}\n\t}\n\tif err := runCommand(\"systemctl\", \"daemon-reload\"); err != nil {\n\t\tlog.Err(err).Msg(\"systemctl daemon-reload error\")\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc uninstallSysv(log *zerolog.Logger) error {\n\tif err := runCommand(\"service\", \"cloudflared\", \"stop\"); err != nil {\n\t\tlog.Err(err).Msg(\"service cloudflared stop error\")\n\t\treturn err\n\t}\n\tif err := sysvTemplate.Remove(); err != nil {\n\t\tlog.Err(err).Msg(\"error removing service template\")\n\t\treturn err\n\t}\n\tfor _, i := range [...]string{\"2\", \"3\", \"4\", \"5\"} {\n\t\tif err := os.Remove(\"/etc/rc\" + i + \".d/S50et\"); err != nil {\n\t\t\tcontinue\n\t\t}\n\t}\n\tfor _, i := range [...]string{\"0\", \"1\", \"6\"} {\n\t\tif err := os.Remove(\"/etc/rc\" + i + \".d/K02et\"); err != nil {\n\t\t\tcontinue\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc ensureConfigDirExists(configDir string) error {\n\tok, err := config.FileExists(configDir)\n\tif !ok && err == nil {\n\t\terr = os.Mkdir(configDir, 0755)\n\t}\n\treturn err\n}\n\nfunc copyFile(src, dest string) error {\n\tsrcFile, err := os.Open(src)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer srcFile.Close()\n\n\tdestFile, err := os.Create(dest)\n\tif err != nil {\n\t\treturn err\n\t}\n\tok := false\n\tdefer func() {\n\t\tdestFile.Close()\n\t\tif !ok {\n\t\t\t_ = os.Remove(dest)\n\t\t}\n\t}()\n\n\tif _, err := io.Copy(destFile, srcFile); err != nil {\n\t\treturn err\n\t}\n\n\tok = true\n\treturn nil\n}\n"
  },
  {
    "path": "cmd/cloudflared/macos_service.go",
    "content": "//go:build darwin\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\thomedir \"github.com/mitchellh/go-homedir\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n\t\"github.com/cloudflare/cloudflared/logger\"\n)\n\nconst (\n\tlaunchdIdentifier = \"com.cloudflare.cloudflared\"\n)\n\nfunc runApp(app *cli.App, _ chan struct{}) {\n\tapp.Commands = append(app.Commands, &cli.Command{\n\t\tName:  \"service\",\n\t\tUsage: \"Manages the cloudflared launch agent\",\n\t\tSubcommands: []*cli.Command{\n\t\t\t{\n\t\t\t\tName:   \"install\",\n\t\t\t\tUsage:  \"Install cloudflared as an user launch agent\",\n\t\t\t\tAction: cliutil.ConfiguredAction(installLaunchd),\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:   \"uninstall\",\n\t\t\t\tUsage:  \"Uninstall the cloudflared launch agent\",\n\t\t\t\tAction: cliutil.ConfiguredAction(uninstallLaunchd),\n\t\t\t},\n\t\t},\n\t})\n\t_ = app.Run(os.Args)\n}\n\nfunc newLaunchdTemplate(installPath, stdoutPath, stderrPath string) *ServiceTemplate {\n\treturn &ServiceTemplate{\n\t\tPath: installPath,\n\t\tContent: fmt.Sprintf(`<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n\t<dict>\n\t\t<key>Label</key>\n\t\t<string>%s</string>\n\t\t<key>ProgramArguments</key>\n\t\t<array>\n\t\t\t<string>{{ .Path }}</string>\n\t\t\t{{- range $i, $item := .ExtraArgs}}\n\t\t\t<string>{{ $item }}</string>\n\t\t\t{{- end}}\n\t\t</array>\n\t\t<key>RunAtLoad</key>\n\t\t<true/>\n\t\t<key>StandardOutPath</key>\n\t\t<string>%s</string>\n\t\t<key>StandardErrorPath</key>\n\t\t<string>%s</string>\n\t\t<key>KeepAlive</key>\n\t\t<dict>\n\t\t\t<key>SuccessfulExit</key>\n\t\t\t<false/>\n\t\t</dict>\n\t\t<key>ThrottleInterval</key>\n\t\t<integer>5</integer>\n\t</dict>\n</plist>`, launchdIdentifier, stdoutPath, stderrPath),\n\t}\n}\n\nfunc isRootUser() bool {\n\treturn os.Geteuid() == 0\n}\n\nfunc installPath() (string, error) {\n\t// User is root, use /Library/LaunchDaemons instead of home directory\n\tif isRootUser() {\n\t\treturn fmt.Sprintf(\"/Library/LaunchDaemons/%s.plist\", launchdIdentifier), nil\n\t}\n\tuserHomeDir, err := userHomeDir()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn fmt.Sprintf(\"%s/Library/LaunchAgents/%s.plist\", userHomeDir, launchdIdentifier), nil\n}\n\nfunc stdoutPath() (string, error) {\n\tif isRootUser() {\n\t\treturn fmt.Sprintf(\"/Library/Logs/%s.out.log\", launchdIdentifier), nil\n\t}\n\tuserHomeDir, err := userHomeDir()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn fmt.Sprintf(\"%s/Library/Logs/%s.out.log\", userHomeDir, launchdIdentifier), nil\n}\n\nfunc stderrPath() (string, error) {\n\tif isRootUser() {\n\t\treturn fmt.Sprintf(\"/Library/Logs/%s.err.log\", launchdIdentifier), nil\n\t}\n\tuserHomeDir, err := userHomeDir()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn fmt.Sprintf(\"%s/Library/Logs/%s.err.log\", userHomeDir, launchdIdentifier), nil\n}\n\nfunc installLaunchd(c *cli.Context) error {\n\tlog := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog)\n\n\tif isRootUser() {\n\t\tlog.Info().Msg(\"Installing cloudflared client as a system launch daemon. \" +\n\t\t\t\"cloudflared client will run at boot\")\n\t} else {\n\t\tlog.Info().Msg(\"Installing cloudflared client as an user launch agent. \" +\n\t\t\t\"Note that cloudflared client will only run when the user is logged in. \" +\n\t\t\t\"If you want to run cloudflared client at boot, install with root permission. \" +\n\t\t\t\"For more information, visit https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/configure-tunnels/local-management/as-a-service/macos/\")\n\t}\n\tetPath, err := os.Executable()\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"Error determining executable path\")\n\t\treturn fmt.Errorf(\"Error determining executable path: %v\", err)\n\t}\n\tinstallPath, err := installPath()\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"Error determining install path\")\n\t\treturn errors.Wrap(err, \"Error determining install path\")\n\t}\n\textraArgs, err := getServiceExtraArgsFromCliArgs(c, log)\n\tif err != nil {\n\t\terrMsg := \"Unable to determine extra arguments for launch daemon\"\n\t\tlog.Err(err).Msg(errMsg)\n\t\treturn errors.Wrap(err, errMsg)\n\t}\n\n\tstdoutPath, err := stdoutPath()\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"error determining stdout path\")\n\t\treturn errors.Wrap(err, \"error determining stdout path\")\n\t}\n\tstderrPath, err := stderrPath()\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"error determining stderr path\")\n\t\treturn errors.Wrap(err, \"error determining stderr path\")\n\t}\n\tlaunchdTemplate := newLaunchdTemplate(installPath, stdoutPath, stderrPath)\n\ttemplateArgs := ServiceTemplateArgs{Path: etPath, ExtraArgs: extraArgs}\n\terr = launchdTemplate.Generate(&templateArgs)\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"error generating launchd template\")\n\t\treturn err\n\t}\n\tplistPath, err := launchdTemplate.ResolvePath()\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"error resolving launchd template path\")\n\t\treturn err\n\t}\n\n\tlog.Info().Msgf(\"Outputs are logged to %s and %s\", stderrPath, stdoutPath)\n\terr = runCommand(\"launchctl\", \"load\", plistPath)\n\tif err == nil {\n\t\tlog.Info().Msg(\"MacOS service for cloudflared installed successfully\")\n\t}\n\treturn err\n}\n\nfunc uninstallLaunchd(c *cli.Context) error {\n\tlog := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog)\n\n\tif isRootUser() {\n\t\tlog.Info().Msg(\"Uninstalling cloudflared as a system launch daemon\")\n\t} else {\n\t\tlog.Info().Msg(\"Uninstalling cloudflared as a user launch agent\")\n\t}\n\tinstallPath, err := installPath()\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"error determining install path\")\n\t}\n\tstdoutPath, err := stdoutPath()\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"error determining stdout path\")\n\t}\n\tstderrPath, err := stderrPath()\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"error determining stderr path\")\n\t}\n\tlaunchdTemplate := newLaunchdTemplate(installPath, stdoutPath, stderrPath)\n\tplistPath, err := launchdTemplate.ResolvePath()\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"error resolving launchd template path\")\n\t\treturn err\n\t}\n\terr = runCommand(\"launchctl\", \"unload\", plistPath)\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"error unloading launchd\")\n\t\treturn err\n\t}\n\n\terr = launchdTemplate.Remove()\n\tif err == nil {\n\t\tlog.Info().Msg(\"Launchd for cloudflared was uninstalled successfully\")\n\t}\n\treturn err\n}\n\nfunc userHomeDir() (string, error) {\n\t// This returns the home dir of the executing user using OS-specific method\n\t// for discovering the home dir. It's not recommended to call this function\n\t// when the user has root permission as $HOME depends on what options the user\n\t// use with sudo.\n\thomeDir, err := homedir.Dir()\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"Cannot determine home directory for the user\")\n\t}\n\treturn homeDir, nil\n}\n"
  },
  {
    "path": "cmd/cloudflared/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go\"\n\t\"github.com/urfave/cli/v2\"\n\t\"go.uber.org/automaxprocs/maxprocs\"\n\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/access\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n\tcfdflags \"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/management\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/proxydns\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/tail\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/tunnel\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/updater\"\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/logger\"\n\t\"github.com/cloudflare/cloudflared/metrics\"\n\t\"github.com/cloudflare/cloudflared/overwatch\"\n\t\"github.com/cloudflare/cloudflared/token\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n\t\"github.com/cloudflare/cloudflared/watcher\"\n)\n\nconst (\n\tversionText = \"Print the version\"\n)\n\nvar (\n\tVersion   = \"DEV\"\n\tBuildTime = \"unknown\"\n\tBuildType = \"\"\n\t// Mostly network errors that we don't want reported back to Sentry, this is done by substring match.\n\tignoredErrors = []string{\n\t\t\"connection reset by peer\",\n\t\t\"An existing connection was forcibly closed by the remote host.\",\n\t\t\"use of closed connection\",\n\t\t\"You need to enable Argo Smart Routing\",\n\t\t\"3001 connection closed\",\n\t\t\"3002 connection dropped\",\n\t\t\"rpc exception: dial tcp\",\n\t\t\"rpc exception: EOF\",\n\t}\n)\n\nfunc main() {\n\t// FIXME: TUN-8148: Disable QUIC_GO ECN due to bugs in proper detection if supported\n\tos.Setenv(\"QUIC_GO_DISABLE_ECN\", \"1\")\n\tmetrics.RegisterBuildInfo(BuildType, BuildTime, Version)\n\t_, _ = maxprocs.Set()\n\tbInfo := cliutil.GetBuildInfo(BuildType, Version)\n\n\t// Graceful shutdown channel used by the app. When closed, app must terminate gracefully.\n\t// Windows service manager closes this channel when it receives stop command.\n\tgraceShutdownC := make(chan struct{})\n\n\tcli.VersionFlag = &cli.BoolFlag{\n\t\tName:    \"version\",\n\t\tAliases: []string{\"v\", \"V\"},\n\t\tUsage:   versionText,\n\t}\n\n\tapp := &cli.App{}\n\tapp.Name = \"cloudflared\"\n\tapp.Usage = \"Cloudflare's command-line tool and agent\"\n\tapp.UsageText = \"cloudflared [global options] [command] [command options]\"\n\tapp.Copyright = fmt.Sprintf(\n\t\t`(c) %d Cloudflare Inc.\n   Your installation of cloudflared software constitutes a symbol of your signature indicating that you accept\n   the terms of the Apache License Version 2.0 (https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/license),\n   Terms (https://www.cloudflare.com/terms/) and Privacy Policy (https://www.cloudflare.com/privacypolicy/).`,\n\t\ttime.Now().Year(),\n\t)\n\tapp.Version = fmt.Sprintf(\"%s (built %s%s)\", Version, BuildTime, bInfo.GetBuildTypeMsg())\n\tapp.Description = `cloudflared connects your machine or user identity to Cloudflare's global network.\n\tYou can use it to authenticate a session to reach an API behind Access, route web traffic to this machine,\n\tand configure access control.\n\n\tSee https://developers.cloudflare.com/cloudflare-one/connections/connect-apps for more in-depth documentation.`\n\tapp.Flags = flags()\n\tapp.Action = action(graceShutdownC)\n\tapp.Commands = commands(cli.ShowVersion)\n\n\ttunnel.Init(bInfo, graceShutdownC) // we need this to support the tunnel sub command...\n\taccess.Init(graceShutdownC, Version)\n\tupdater.Init(bInfo)\n\ttracing.Init(Version)\n\ttoken.Init(Version)\n\ttail.Init(bInfo)\n\tmanagement.Init(bInfo)\n\trunApp(app, graceShutdownC)\n}\n\nfunc commands(version func(c *cli.Context)) []*cli.Command {\n\tcmds := []*cli.Command{\n\t\t{\n\t\t\tName:   \"update\",\n\t\t\tAction: cliutil.ConfiguredAction(updater.Update),\n\t\t\tUsage:  \"Update the agent if a new version exists\",\n\t\t\tFlags: []cli.Flag{\n\t\t\t\t&cli.BoolFlag{\n\t\t\t\t\tName:  \"beta\",\n\t\t\t\t\tUsage: \"specify if you wish to update to the latest beta version\",\n\t\t\t\t},\n\t\t\t\t&cli.BoolFlag{\n\t\t\t\t\tName:   cfdflags.Force,\n\t\t\t\t\tUsage:  \"specify if you wish to force an upgrade to the latest version regardless of the current version\",\n\t\t\t\t\tHidden: true,\n\t\t\t\t},\n\t\t\t\t&cli.BoolFlag{\n\t\t\t\t\tName:   \"staging\",\n\t\t\t\t\tUsage:  \"specify if you wish to use the staging url for updating\",\n\t\t\t\t\tHidden: true,\n\t\t\t\t},\n\t\t\t\t&cli.StringFlag{\n\t\t\t\t\tName:   \"version\",\n\t\t\t\t\tUsage:  \"specify a version you wish to upgrade or downgrade to\",\n\t\t\t\t\tHidden: false,\n\t\t\t\t},\n\t\t\t},\n\t\t\tDescription: `Looks for a new version on the official download server.\nIf a new version exists, updates the agent binary and quits.\nOtherwise, does nothing.\n\nTo determine if an update happened in a script, check for error code 11.`,\n\t\t},\n\t\t{\n\t\t\tName: \"version\",\n\t\t\tAction: func(c *cli.Context) (err error) {\n\t\t\t\tif c.Bool(\"short\") {\n\t\t\t\t\tfmt.Println(strings.Split(c.App.Version, \" \")[0])\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\tversion(c)\n\t\t\t\treturn nil\n\t\t\t},\n\t\t\tUsage:       versionText,\n\t\t\tDescription: versionText,\n\t\t\tFlags: []cli.Flag{\n\t\t\t\t&cli.BoolFlag{\n\t\t\t\t\tName:    \"short\",\n\t\t\t\t\tAliases: []string{\"s\"},\n\t\t\t\t\tUsage:   \"print just the version number\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tcmds = append(cmds, tunnel.Commands()...)\n\tcmds = append(cmds, proxydns.Command()) // removed feature, only here for error message\n\tcmds = append(cmds, access.Commands()...)\n\tcmds = append(cmds, tail.Command())\n\tcmds = append(cmds, management.Command())\n\treturn cmds\n}\n\nfunc flags() []cli.Flag {\n\tflags := tunnel.Flags()\n\treturn append(flags, access.Flags()...)\n}\n\nfunc isEmptyInvocation(c *cli.Context) bool {\n\treturn c.NArg() == 0 && c.NumFlags() == 0\n}\n\nfunc action(graceShutdownC chan struct{}) cli.ActionFunc {\n\treturn cliutil.ConfiguredAction(func(c *cli.Context) (err error) {\n\t\tif isEmptyInvocation(c) {\n\t\t\treturn handleServiceMode(c, graceShutdownC)\n\t\t}\n\t\tfunc() {\n\t\t\tdefer sentry.Recover()\n\t\t\terr = tunnel.TunnelCommand(c)\n\t\t}()\n\t\tif err != nil {\n\t\t\tcaptureError(err)\n\t\t}\n\t\treturn err\n\t})\n}\n\n// In order to keep the amount of noise sent to Sentry low, typical network errors can be filtered out here by a substring match.\nfunc captureError(err error) {\n\terrorMessage := err.Error()\n\tfor _, ignoredErrorMessage := range ignoredErrors {\n\t\tif strings.Contains(errorMessage, ignoredErrorMessage) {\n\t\t\treturn\n\t\t}\n\t}\n\tsentry.CaptureException(err)\n}\n\n// cloudflared was started without any flags\nfunc handleServiceMode(c *cli.Context, shutdownC chan struct{}) error {\n\tlog := logger.CreateLoggerFromContext(c, logger.DisableTerminalLog)\n\n\t// start the main run loop that reads from the config file\n\tf, err := watcher.NewFile()\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"Cannot load config file\")\n\t\treturn err\n\t}\n\n\tconfigPath := config.FindOrCreateConfigPath()\n\tconfigManager, err := config.NewFileManager(f, configPath, log)\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"Cannot setup config file for monitoring\")\n\t\treturn err\n\t}\n\tlog.Info().Msgf(\"monitoring config file at: %s\", configPath)\n\n\tserviceCallback := func(t string, name string, err error) {\n\t\tif err != nil {\n\t\t\tlog.Err(err).Msgf(\"%s service: %s encountered an error\", t, name)\n\t\t}\n\t}\n\tserviceManager := overwatch.NewAppManager(serviceCallback)\n\n\tappService := NewAppService(configManager, serviceManager, shutdownC, log)\n\tif err := appService.Run(); err != nil {\n\t\tlog.Err(err).Msg(\"Failed to start app service\")\n\t\treturn err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "cmd/cloudflared/management/cmd.go",
    "content": "package management\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/cloudflare/cloudflared/cfapi\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n\tcfdflags \"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n\t\"github.com/cloudflare/cloudflared/credentials\"\n)\n\nvar buildInfo *cliutil.BuildInfo\n\n// Init initializes the management package with build info\nfunc Init(bi *cliutil.BuildInfo) {\n\tbuildInfo = bi\n}\n\n// Command returns the management command with its subcommands\nfunc Command() *cli.Command {\n\treturn &cli.Command{\n\t\tName:     \"management\",\n\t\tUsage:    \"Monitor cloudflared tunnels via management API\",\n\t\tCategory: \"Management\",\n\t\tHidden:   true,\n\t\tSubcommands: []*cli.Command{\n\t\t\tbuildTokenSubcommand(),\n\t\t},\n\t}\n}\n\n// buildTokenSubcommand creates the token subcommand\nfunc buildTokenSubcommand() *cli.Command {\n\treturn &cli.Command{\n\t\tName:        \"token\",\n\t\tAction:      cliutil.ConfiguredAction(tokenCommand),\n\t\tUsage:       \"Get management access jwt for a specific resource\",\n\t\tUsageText:   \"cloudflared management token --resource <resource> TUNNEL_ID\",\n\t\tDescription: \"Get management access jwt for a tunnel with specified resource permissions (logs, admin, host_details)\",\n\t\tHidden:      true,\n\t\tFlags: []cli.Flag{\n\t\t\t&cli.StringFlag{\n\t\t\t\tName:     \"resource\",\n\t\t\t\tUsage:    \"Resource type for token permissions: logs, admin, or host_details\",\n\t\t\t\tRequired: true,\n\t\t\t},\n\t\t\t&cli.StringFlag{\n\t\t\t\tName:    cfdflags.OriginCert,\n\t\t\t\tUsage:   \"Path to the certificate generated for your origin when you run cloudflared login.\",\n\t\t\t\tEnvVars: []string{\"TUNNEL_ORIGIN_CERT\"},\n\t\t\t\tValue:   credentials.FindDefaultOriginCertPath(),\n\t\t\t},\n\t\t\t&cli.StringFlag{\n\t\t\t\tName:    cfdflags.LogLevel,\n\t\t\t\tValue:   \"info\",\n\t\t\t\tUsage:   \"Application logging level {debug, info, warn, error, fatal}\",\n\t\t\t\tEnvVars: []string{\"TUNNEL_LOGLEVEL\"},\n\t\t\t},\n\t\t\tcliutil.FlagLogOutput,\n\t\t},\n\t}\n}\n\n// tokenCommand handles the token subcommand execution\nfunc tokenCommand(c *cli.Context) error {\n\tlog := cliutil.CreateStderrLogger(c)\n\n\t// Parse and validate resource flag\n\tresourceStr := c.String(\"resource\")\n\tresource, err := parseResource(resourceStr)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"invalid resource '%s': %w\", resourceStr, err)\n\t}\n\n\t// Get management token\n\ttoken, err := cliutil.GetManagementToken(c, log, resource, buildInfo)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Output JSON to stdout\n\ttokenResponse := struct {\n\t\tToken string `json:\"token\"`\n\t}{Token: token}\n\n\treturn json.NewEncoder(os.Stdout).Encode(tokenResponse)\n}\n\n// parseResource converts resource string to ManagementResource enum\nfunc parseResource(resource string) (cfapi.ManagementResource, error) {\n\tswitch resource {\n\tcase \"logs\":\n\t\treturn cfapi.Logs, nil\n\tcase \"admin\":\n\t\treturn cfapi.Admin, nil\n\tcase \"host_details\":\n\t\treturn cfapi.HostDetails, nil\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"must be one of: logs, admin, host_details\")\n\t}\n}\n"
  },
  {
    "path": "cmd/cloudflared/management/cmd_test.go",
    "content": "package management\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/cloudflare/cloudflared/cfapi\"\n)\n\nfunc TestParseResource_ValidResources(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tinput    string\n\t\texpected cfapi.ManagementResource\n\t}{\n\t\t{\"logs\", cfapi.Logs},\n\t\t{\"admin\", cfapi.Admin},\n\t\t{\"host_details\", cfapi.HostDetails},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.input, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult, err := parseResource(tt.input)\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, tt.expected, result)\n\t\t})\n\t}\n}\n\nfunc TestParseResource_InvalidResource(t *testing.T) {\n\tt.Parallel()\n\n\tinvalid := []string{\"invalid\", \"LOGS\", \"Admin\", \"\", \"metrics\", \"host-details\"}\n\n\tfor _, input := range invalid {\n\t\tt.Run(input, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\t_, err := parseResource(input)\n\t\t\trequire.Error(t, err)\n\t\t\tassert.Contains(t, err.Error(), \"must be one of\")\n\t\t})\n\t}\n}\n\nfunc TestCommandStructure(t *testing.T) {\n\tt.Parallel()\n\n\tcmd := Command()\n\n\tassert.Equal(t, \"management\", cmd.Name)\n\tassert.True(t, cmd.Hidden)\n\tassert.Len(t, cmd.Subcommands, 1)\n\n\ttokenCmd := cmd.Subcommands[0]\n\tassert.Equal(t, \"token\", tokenCmd.Name)\n\tassert.True(t, tokenCmd.Hidden)\n\n\t// Verify required flags exist\n\tvar hasResourceFlag bool\n\tfor _, flag := range tokenCmd.Flags {\n\t\tif flag.Names()[0] == \"resource\" {\n\t\t\thasResourceFlag = true\n\t\t\tbreak\n\t\t}\n\t}\n\tassert.True(t, hasResourceFlag, \"token command should have --resource flag\")\n}\n"
  },
  {
    "path": "cmd/cloudflared/proxydns/cmd.go",
    "content": "package proxydns\n\nimport (\n\t\"errors\"\n\n\t\"github.com/urfave/cli/v2\"\n\t\"github.com/urfave/cli/v2/altsrc\"\n\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n\t\"github.com/cloudflare/cloudflared/logger\"\n)\n\nconst removedMessage = \"dns-proxy feature is no longer supported\"\n\nfunc Command() *cli.Command {\n\treturn &cli.Command{\n\t\tName:            \"proxy-dns\",\n\t\tAction:          cliutil.ConfiguredAction(Run),\n\t\tUsage:           removedMessage,\n\t\tSkipFlagParsing: true,\n\t}\n}\n\nfunc Run(c *cli.Context) error {\n\tlog := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog)\n\terr := errors.New(removedMessage)\n\tlog.Error().Msg(\"DNS Proxy is no longer supported since version 2026.2.0 (https://developers.cloudflare.com/changelog/2025-11-11-cloudflared-proxy-dns/). As an alternative consider using https://developers.cloudflare.com/1.1.1.1/encryption/dns-over-https/dns-over-https-client/\")\n\n\treturn err\n}\n\n// Old flags used by the proxy-dns command, only kept to not break any script that might be setting these flags\nfunc ConfigureProxyDNSFlags(shouldHide bool) []cli.Flag {\n\treturn []cli.Flag{\n\t\taltsrc.NewBoolFlag(&cli.BoolFlag{\n\t\t\tName: \"proxy-dns\",\n\t\t}),\n\t\taltsrc.NewIntFlag(&cli.IntFlag{\n\t\t\tName: \"proxy-dns-port\",\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName: \"proxy-dns-address\",\n\t\t}),\n\t\taltsrc.NewStringSliceFlag(&cli.StringSliceFlag{\n\t\t\tName: \"proxy-dns-upstream\",\n\t\t}),\n\t\taltsrc.NewIntFlag(&cli.IntFlag{\n\t\t\tName: \"proxy-dns-max-upstream-conns\",\n\t\t}),\n\t\taltsrc.NewStringSliceFlag(&cli.StringSliceFlag{\n\t\t\tName: \"proxy-dns-bootstrap\",\n\t\t}),\n\t}\n}\n"
  },
  {
    "path": "cmd/cloudflared/service_template.go",
    "content": "package main\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"text/template\"\n\n\thomedir \"github.com/mitchellh/go-homedir\"\n)\n\ntype ServiceTemplate struct {\n\tPath     string\n\tContent  string\n\tFileMode os.FileMode\n}\n\ntype ServiceTemplateArgs struct {\n\tPath      string\n\tExtraArgs []string\n}\n\nfunc (st *ServiceTemplate) ResolvePath() (string, error) {\n\tresolvedPath, err := homedir.Expand(st.Path)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error resolving path %s: %v\", st.Path, err)\n\t}\n\treturn resolvedPath, nil\n}\n\nfunc (st *ServiceTemplate) Generate(args *ServiceTemplateArgs) error {\n\ttmpl, err := template.New(st.Path).Parse(st.Content)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error generating %s template: %v\", st.Path, err)\n\t}\n\tresolvedPath, err := st.ResolvePath()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif _, err = os.Stat(resolvedPath); err == nil {\n\t\treturn errors.New(serviceAlreadyExistsWarn(resolvedPath))\n\t}\n\n\tvar buffer bytes.Buffer\n\terr = tmpl.Execute(&buffer, args)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error generating %s: %v\", st.Path, err)\n\t}\n\tfileMode := os.FileMode(0o644)\n\tif st.FileMode != 0 {\n\t\tfileMode = st.FileMode\n\t}\n\n\tplistFolder := filepath.Dir(resolvedPath)\n\terr = os.MkdirAll(plistFolder, 0o755)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error creating %s: %v\", plistFolder, err)\n\t}\n\n\terr = os.WriteFile(resolvedPath, buffer.Bytes(), fileMode)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error writing %s: %v\", resolvedPath, err)\n\t}\n\treturn nil\n}\n\nfunc (st *ServiceTemplate) Remove() error {\n\tresolvedPath, err := st.ResolvePath()\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = os.Remove(resolvedPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error deleting %s: %v\", resolvedPath, err)\n\t}\n\treturn nil\n}\n\nfunc serviceAlreadyExistsWarn(service string) string {\n\treturn fmt.Sprintf(\"cloudflared service is already installed at %s; if you are running a cloudflared tunnel, you \"+\n\t\t\"can point it to multiple origins, avoiding the need to run more than one cloudflared service in the \"+\n\t\t\"same machine; otherwise if you are really sure, you can do `cloudflared service uninstall` to clean \"+\n\t\t\"up the existing service and then try again this command\",\n\t\tservice,\n\t)\n}\n\nfunc runCommand(command string, args ...string) error {\n\tcmd := exec.Command(command, args...)\n\tstderr, err := cmd.StderrPipe()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error getting stderr pipe: %v\", err)\n\t}\n\terr = cmd.Start()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error starting %s: %v\", command, err)\n\t}\n\n\toutput, _ := io.ReadAll(stderr)\n\terr = cmd.Wait()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"%s %v returned with error code %v due to: %v\", command, args, err, string(output))\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "cmd/cloudflared/tail/cmd.go",
    "content": "package tail\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/urfave/cli/v2\"\n\t\"nhooyr.io/websocket\"\n\n\t\"github.com/cloudflare/cloudflared/cfapi\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n\tcfdflags \"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n\t\"github.com/cloudflare/cloudflared/credentials\"\n\t\"github.com/cloudflare/cloudflared/management\"\n)\n\nvar buildInfo *cliutil.BuildInfo\n\nfunc Init(bi *cliutil.BuildInfo) {\n\tbuildInfo = bi\n}\n\nfunc Command() *cli.Command {\n\tsubcommands := []*cli.Command{\n\t\tbuildTailManagementTokenSubcommand(),\n\t}\n\n\treturn buildTailCommand(subcommands)\n}\n\nfunc buildTailManagementTokenSubcommand() *cli.Command {\n\treturn &cli.Command{\n\t\tName:        \"token\",\n\t\tAction:      cliutil.ConfiguredAction(managementTokenCommand),\n\t\tUsage:       \"Get management access jwt\",\n\t\tUsageText:   \"cloudflared tail token TUNNEL_ID\",\n\t\tDescription: `Get management access jwt for a tunnel`,\n\t\tHidden:      true,\n\t}\n}\n\nfunc managementTokenCommand(c *cli.Context) error {\n\tlog := cliutil.CreateStderrLogger(c)\n\n\ttoken, err := cliutil.GetManagementToken(c, log, cfapi.Logs, buildInfo)\n\tif err != nil {\n\t\treturn err\n\t}\n\ttokenResponse := struct {\n\t\tToken string `json:\"token\"`\n\t}{Token: token}\n\n\treturn json.NewEncoder(os.Stdout).Encode(tokenResponse)\n}\n\nfunc buildTailCommand(subcommands []*cli.Command) *cli.Command {\n\treturn &cli.Command{\n\t\tName:      \"tail\",\n\t\tAction:    Run,\n\t\tUsage:     \"Stream logs from a remote cloudflared\",\n\t\tUsageText: \"cloudflared tail [tail command options] [TUNNEL-ID]\",\n\t\tFlags: []cli.Flag{\n\t\t\t&cli.StringFlag{\n\t\t\t\tName:    \"connector-id\",\n\t\t\t\tUsage:   \"Access a specific cloudflared instance by connector id (for when a tunnel has multiple cloudflared's)\",\n\t\t\t\tValue:   \"\",\n\t\t\t\tEnvVars: []string{\"TUNNEL_MANAGEMENT_CONNECTOR\"},\n\t\t\t},\n\t\t\t&cli.StringSliceFlag{\n\t\t\t\tName:    \"event\",\n\t\t\t\tUsage:   \"Filter by specific Events (cloudflared, http, tcp, udp) otherwise, defaults to send all events\",\n\t\t\t\tEnvVars: []string{\"TUNNEL_MANAGEMENT_FILTER_EVENTS\"},\n\t\t\t},\n\t\t\t&cli.StringFlag{\n\t\t\t\tName:    \"level\",\n\t\t\t\tUsage:   \"Filter by specific log levels (debug, info, warn, error). Filters by debug log level by default.\",\n\t\t\t\tEnvVars: []string{\"TUNNEL_MANAGEMENT_FILTER_LEVEL\"},\n\t\t\t\tValue:   \"debug\",\n\t\t\t},\n\t\t\t&cli.Float64Flag{\n\t\t\t\tName:    \"sample\",\n\t\t\t\tUsage:   \"Sample log events by percentage (0.0 .. 1.0). No sampling by default.\",\n\t\t\t\tEnvVars: []string{\"TUNNEL_MANAGEMENT_FILTER_SAMPLE\"},\n\t\t\t\tValue:   1.0,\n\t\t\t},\n\t\t\t&cli.StringFlag{\n\t\t\t\tName:    \"token\",\n\t\t\t\tUsage:   \"Access token for a specific tunnel\",\n\t\t\t\tValue:   \"\",\n\t\t\t\tEnvVars: []string{\"TUNNEL_MANAGEMENT_TOKEN\"},\n\t\t\t},\n\t\t\t&cli.StringFlag{\n\t\t\t\tName:    cfdflags.ManagementHostname,\n\t\t\t\tUsage:   \"Management hostname to signify incoming management requests\",\n\t\t\t\tEnvVars: []string{\"TUNNEL_MANAGEMENT_HOSTNAME\"},\n\t\t\t\tHidden:  true,\n\t\t\t\tValue:   \"management.argotunnel.com\",\n\t\t\t},\n\t\t\t&cli.StringFlag{\n\t\t\t\tName:   \"trace\",\n\t\t\t\tUsage:  \"Set a cf-trace-id for the request\",\n\t\t\t\tHidden: true,\n\t\t\t\tValue:  \"\",\n\t\t\t},\n\t\t\t&cli.StringFlag{\n\t\t\t\tName:    cfdflags.LogLevel,\n\t\t\t\tValue:   \"info\",\n\t\t\t\tUsage:   \"Application logging level {debug, info, warn, error, fatal}\",\n\t\t\t\tEnvVars: []string{\"TUNNEL_LOGLEVEL\"},\n\t\t\t},\n\t\t\t&cli.StringFlag{\n\t\t\t\tName:    cfdflags.OriginCert,\n\t\t\t\tUsage:   \"Path to the certificate generated for your origin when you run cloudflared login.\",\n\t\t\t\tEnvVars: []string{\"TUNNEL_ORIGIN_CERT\"},\n\t\t\t\tValue:   credentials.FindDefaultOriginCertPath(),\n\t\t\t},\n\t\t\tcliutil.FlagLogOutput,\n\t\t},\n\t\tSubcommands: subcommands,\n\t}\n}\n\n// Middleware validation error struct for returning to the eyeball\ntype managementError struct {\n\tCode    int    `json:\"code,omitempty\"`\n\tMessage string `json:\"message,omitempty\"`\n}\n\n// Middleware validation error HTTP response JSON for returning to the eyeball\ntype managementErrorResponse struct {\n\tSuccess bool              `json:\"success,omitempty\"`\n\tErrors  []managementError `json:\"errors,omitempty\"`\n}\n\nfunc handleValidationError(resp *http.Response, log *zerolog.Logger) {\n\tif resp.StatusCode == 530 {\n\t\tlog.Error().Msgf(\"no cloudflared connector available or reachable via management request (a recent version of cloudflared is required to use streaming logs)\")\n\t}\n\tvar managementErr managementErrorResponse\n\terr := json.NewDecoder(resp.Body).Decode(&managementErr)\n\tif err != nil {\n\t\tlog.Error().Msgf(\"unable to start management log streaming session: http response code returned %d\", resp.StatusCode)\n\t\treturn\n\t}\n\tif managementErr.Success || len(managementErr.Errors) == 0 {\n\t\tlog.Error().Msgf(\"management tunnel validation returned success with invalid HTTP response code to convert to a WebSocket request\")\n\t\treturn\n\t}\n\tfor _, e := range managementErr.Errors {\n\t\tlog.Error().Msgf(\"management request failed validation: (%d) %s\", e.Code, e.Message)\n\t}\n}\n\n// parseFilters will attempt to parse provided filters to send to with the EventStartStreaming\nfunc parseFilters(c *cli.Context) (*management.StreamingFilters, error) {\n\tvar level *management.LogLevel\n\tvar sample float64\n\n\tevents := make([]management.LogEventType, 0)\n\n\targLevel := c.String(\"level\")\n\targEvents := c.StringSlice(\"event\")\n\targSample := c.Float64(\"sample\")\n\n\tif argLevel != \"\" {\n\t\tl, ok := management.ParseLogLevel(argLevel)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"invalid --level filter provided, please use one of the following Log Levels: debug, info, warn, error\")\n\t\t}\n\t\tlevel = &l\n\t}\n\n\tfor _, v := range argEvents {\n\t\tt, ok := management.ParseLogEventType(v)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"invalid --event filter provided, please use one of the following EventTypes: cloudflared, http, tcp, udp\")\n\t\t}\n\t\tevents = append(events, t)\n\t}\n\n\tif argSample <= 0.0 || argSample > 1.0 {\n\t\treturn nil, fmt.Errorf(\"invalid --sample value provided, please make sure it is in the range (0.0 .. 1.0)\")\n\t}\n\tsample = argSample\n\n\tif level == nil && len(events) == 0 && argSample != 1.0 {\n\t\t// When no filters are provided, do not return a StreamingFilters struct\n\t\treturn nil, nil\n\t}\n\n\treturn &management.StreamingFilters{\n\t\tLevel:    level,\n\t\tEvents:   events,\n\t\tSampling: sample,\n\t}, nil\n}\n\n// buildURL will build the management url to contain the required query parameters to authenticate the request.\nfunc buildURL(c *cli.Context, log *zerolog.Logger, res cfapi.ManagementResource) (url.URL, error) {\n\tvar err error\n\n\ttoken := c.String(\"token\")\n\tif token == \"\" {\n\t\ttoken, err = cliutil.GetManagementToken(c, log, res, buildInfo)\n\t\tif err != nil {\n\t\t\treturn url.URL{}, fmt.Errorf(\"unable to acquire management token for requested tunnel id: %w\", err)\n\t\t}\n\t}\n\n\tclaims, err := management.ParseToken(token)\n\tif err != nil {\n\t\treturn url.URL{}, fmt.Errorf(\"failed to determine if token is FED: %w\", err)\n\t}\n\n\tvar managementHostname string\n\tif claims.IsFed() {\n\t\tmanagementHostname = credentials.FedRampHostname\n\t} else {\n\t\tmanagementHostname = c.String(cfdflags.ManagementHostname)\n\t}\n\n\tquery := url.Values{}\n\tquery.Add(\"access_token\", token)\n\tconnector := c.String(\"connector-id\")\n\tif connector != \"\" {\n\t\tconnectorID, err := uuid.Parse(connector)\n\t\tif err != nil {\n\t\t\treturn url.URL{}, fmt.Errorf(\"unabled to parse 'connector-id' flag into a valid UUID: %w\", err)\n\t\t}\n\t\tquery.Add(\"connector_id\", connectorID.String())\n\t}\n\treturn url.URL{Scheme: \"wss\", Host: managementHostname, Path: \"/logs\", RawQuery: query.Encode()}, nil\n}\n\nfunc printLine(log *management.Log, logger *zerolog.Logger) {\n\tfields, err := json.Marshal(log.Fields)\n\tif err != nil {\n\t\tfields = []byte(\"unable to parse fields\")\n\t\tlogger.Debug().Msgf(\"unable to parse fields from event %+v\", log)\n\t}\n\tfmt.Printf(\"%s %s %s %s %s\\n\", log.Time, log.Level, log.Event, log.Message, fields)\n}\n\nfunc printJSON(log *management.Log, logger *zerolog.Logger) {\n\toutput, err := json.Marshal(log)\n\tif err != nil {\n\t\tlogger.Debug().Msgf(\"unable to parse event to json %+v\", log)\n\t} else {\n\t\tfmt.Println(string(output))\n\t}\n}\n\n// Run implements a foreground runner\nfunc Run(c *cli.Context) error {\n\tlog := cliutil.CreateStderrLogger(c)\n\n\tsignals := make(chan os.Signal, 10)\n\tsignal.Notify(signals, syscall.SIGTERM, syscall.SIGINT)\n\tdefer signal.Stop(signals)\n\n\toutput := \"default\"\n\tswitch c.String(\"output\") {\n\tcase \"default\", \"\":\n\t\toutput = \"default\"\n\tcase \"json\":\n\t\toutput = \"json\"\n\tdefault:\n\t\tlog.Err(errors.New(\"invalid --output value provided, please make sure it is one of: default, json\")).Send()\n\t}\n\n\tfilters, err := parseFilters(c)\n\tif err != nil {\n\t\tlog.Error().Err(err).Msgf(\"invalid filters provided\")\n\t\treturn nil\n\t}\n\n\tu, err := buildURL(c, log, cfapi.Logs)\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"unable to construct management request URL\")\n\t\treturn nil\n\t}\n\n\theader := make(http.Header)\n\theader.Add(\"User-Agent\", buildInfo.UserAgent())\n\ttrace := c.String(\"trace\")\n\tif trace != \"\" {\n\t\theader[\"cf-trace-id\"] = []string{trace}\n\t}\n\tctx := c.Context\n\t// nolint: bodyclose\n\tconn, resp, err := websocket.Dial(ctx, u.String(), &websocket.DialOptions{\n\t\tHTTPHeader: header,\n\t})\n\tif err != nil {\n\t\tif resp != nil && resp.StatusCode != http.StatusSwitchingProtocols {\n\t\t\thandleValidationError(resp, log)\n\t\t\treturn nil\n\t\t}\n\t\tlog.Error().Err(err).Msgf(\"unable to start management log streaming session\")\n\t\treturn nil\n\t}\n\tdefer conn.Close(websocket.StatusInternalError, \"management connection was closed abruptly\")\n\n\t// Once connection is established, send start_streaming event to begin receiving logs\n\terr = management.WriteEvent(conn, ctx, &management.EventStartStreaming{\n\t\tClientEvent: management.ClientEvent{Type: management.StartStreaming},\n\t\tFilters:     filters,\n\t})\n\tif err != nil {\n\t\tlog.Error().Err(err).Msg(\"unable to request logs from management tunnel\")\n\t\treturn nil\n\t}\n\tlog.Debug().\n\t\tStr(\"tunnel-id\", c.Args().First()).\n\t\tStr(\"connector-id\", c.String(\"connector-id\")).\n\t\tInterface(\"filters\", filters).\n\t\tMsg(\"connected\")\n\n\treaderDone := make(chan struct{})\n\n\tgo func() {\n\t\tdefer close(readerDone)\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t\tevent, err := management.ReadServerEvent(conn, ctx)\n\t\t\t\tif err != nil {\n\t\t\t\t\tif closeErr := management.AsClosed(err); closeErr != nil {\n\t\t\t\t\t\t// If the client (or the server) already closed the connection, don't continue to\n\t\t\t\t\t\t// attempt to read from the client.\n\t\t\t\t\t\tif closeErr.Code == websocket.StatusNormalClosure {\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Only log abnormal closures\n\t\t\t\t\t\tlog.Error().Msgf(\"received remote closure: (%d) %s\", closeErr.Code, closeErr.Reason)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tlog.Err(err).Msg(\"unable to read event from server\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tswitch event.Type {\n\t\t\t\tcase management.Logs:\n\t\t\t\t\tlogs, ok := management.IntoServerEvent(event, management.Logs)\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\tlog.Error().Msgf(\"invalid logs event\")\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\t// Output all the logs received to stdout\n\t\t\t\t\tfor _, l := range logs.Logs {\n\t\t\t\t\t\tif output == \"json\" {\n\t\t\t\t\t\t\tprintJSON(l, log)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tprintLine(l, log)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\tcase management.UnknownServerEventType:\n\t\t\t\t\tfallthrough\n\t\t\t\tdefault:\n\t\t\t\t\tlog.Debug().Msgf(\"unexpected log event type: %s\", event.Type)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn nil\n\t\tcase <-readerDone:\n\t\t\treturn nil\n\t\tcase <-signals:\n\t\t\tlog.Debug().Msg(\"closing management connection\")\n\t\t\t// Cleanly close the connection by sending a close message and then\n\t\t\t// waiting (with timeout) for the server to close the connection.\n\t\t\tconn.Close(websocket.StatusNormalClosure, \"\")\n\t\t\tselect {\n\t\t\tcase <-readerDone:\n\t\t\tcase <-time.After(time.Second):\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/cmd.go",
    "content": "package tunnel\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime/trace\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/coreos/go-systemd/v22/daemon\"\n\t\"github.com/facebookgo/grace/gracenet\"\n\t\"github.com/getsentry/sentry-go\"\n\t\"github.com/mitchellh/go-homedir\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/urfave/cli/v2\"\n\t\"github.com/urfave/cli/v2/altsrc\"\n\n\t\"github.com/cloudflare/cloudflared/cfapi\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n\tcfdflags \"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/proxydns\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/updater\"\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/connection\"\n\t\"github.com/cloudflare/cloudflared/credentials\"\n\t\"github.com/cloudflare/cloudflared/diagnostic\"\n\t\"github.com/cloudflare/cloudflared/edgediscovery\"\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\t\"github.com/cloudflare/cloudflared/logger\"\n\t\"github.com/cloudflare/cloudflared/management\"\n\t\"github.com/cloudflare/cloudflared/metrics\"\n\t\"github.com/cloudflare/cloudflared/orchestration\"\n\t\"github.com/cloudflare/cloudflared/signal\"\n\t\"github.com/cloudflare/cloudflared/supervisor\"\n\t\"github.com/cloudflare/cloudflared/tlsconfig\"\n\t\"github.com/cloudflare/cloudflared/tunnelstate\"\n\t\"github.com/cloudflare/cloudflared/validation\"\n)\n\nconst (\n\tsentryDSN = \"https://56a9c9fa5c364ab28f34b14f35ea0f1b:3e8827f6f9f740738eb11138f7bebb68@sentry.io/189878\"\n\n\tLogFieldCommand             = \"command\"\n\tLogFieldExpandedPath        = \"expandedPath\"\n\tLogFieldPIDPathname         = \"pidPathname\"\n\tLogFieldTmpTraceFilename    = \"tmpTraceFilename\"\n\tLogFieldTraceOutputFilepath = \"traceOutputFilepath\"\n\n\ttunnelCmdErrorMessage = `You did not specify any valid additional argument to the cloudflared tunnel command.\n\nIf you are trying to run a Quick Tunnel then you need to explicitly pass the --url flag.\nEg. cloudflared tunnel --url localhost:8080/.\n\nPlease note that Quick Tunnels are meant to be ephemeral and should only be used for testing purposes.\nFor production usage, we recommend creating Named Tunnels. (https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/tunnel-guide/)\n`\n)\n\nvar (\n\tgraceShutdownC chan struct{}\n\tbuildInfo      *cliutil.BuildInfo\n\n\trouteFailMsg = fmt.Sprintf(\"failed to provision routing, please create it manually via Cloudflare dashboard or UI; \"+\n\t\t\"most likely you already have a conflicting record there. You can also rerun this command with --%s to overwrite \"+\n\t\t\"any existing DNS records for this hostname.\", overwriteDNSFlag)\n\terrDeprecatedClassicTunnel = errors.New(\"Classic tunnels have been deprecated, please use Named Tunnels. (https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/tunnel-guide/)\")\n\t// TODO: TUN-8756 the list below denotes the flags that do not possess any kind of sensitive information\n\t// however this approach is not maintainble in the long-term.\n\tnonSecretFlagsList = []string{\n\t\t\"config\",\n\t\tcfdflags.AutoUpdateFreq,\n\t\tcfdflags.NoAutoUpdate,\n\t\tcfdflags.Metrics,\n\t\t\"pidfile\",\n\t\t\"url\",\n\t\t\"hello-world\",\n\t\t\"socks5\",\n\t\t\"proxy-connect-timeout\",\n\t\t\"proxy-tls-timeout\",\n\t\t\"proxy-tcp-keepalive\",\n\t\t\"proxy-no-happy-eyeballs\",\n\t\t\"proxy-keepalive-connections\",\n\t\t\"proxy-keepalive-timeout\",\n\t\t\"proxy-connection-timeout\",\n\t\t\"proxy-expect-continue-timeout\",\n\t\t\"http-host-header\",\n\t\t\"origin-server-name\",\n\t\t\"unix-socket\",\n\t\t\"origin-ca-pool\",\n\t\t\"no-tls-verify\",\n\t\t\"no-chunked-encoding\",\n\t\t\"http2-origin\",\n\t\tcfdflags.ManagementHostname,\n\t\t\"service-op-ip\",\n\t\t\"local-ssh-port\",\n\t\t\"ssh-idle-timeout\",\n\t\t\"ssh-max-timeout\",\n\t\t\"bucket-name\",\n\t\t\"region-name\",\n\t\t\"s3-url-host\",\n\t\t\"host-key-path\",\n\t\t\"ssh-server\",\n\t\t\"bastion\",\n\t\t\"proxy-address\",\n\t\t\"proxy-port\",\n\t\tcfdflags.LogLevel,\n\t\tcfdflags.TransportLogLevel,\n\t\tcfdflags.LogFile,\n\t\tcfdflags.LogDirectory,\n\t\tcfdflags.TraceOutput,\n\t\tcfdflags.IsAutoUpdated,\n\t\tcfdflags.Edge,\n\t\tcfdflags.Region,\n\t\tcfdflags.EdgeIpVersion,\n\t\tcfdflags.EdgeBindAddress,\n\t\t\"cacert\",\n\t\t\"hostname\",\n\t\t\"id\",\n\t\tcfdflags.LBPool,\n\t\tcfdflags.ApiURL,\n\t\tcfdflags.MetricsUpdateFreq,\n\t\tcfdflags.Tag,\n\t\t\"heartbeat-interval\",\n\t\t\"heartbeat-count\",\n\t\tcfdflags.MaxEdgeAddrRetries,\n\t\tcfdflags.Retries,\n\t\t\"ha-connections\",\n\t\t\"rpc-timeout\",\n\t\t\"write-stream-timeout\",\n\t\t\"quic-disable-pmtu-discovery\",\n\t\t\"quic-connection-level-flow-control-limit\",\n\t\t\"quic-stream-level-flow-control-limit\",\n\t\tcfdflags.ConnectorLabel,\n\t\tcfdflags.GracePeriod,\n\t\t\"compression-quality\",\n\t\t\"use-reconnect-token\",\n\t\t\"dial-edge-timeout\",\n\t\t\"stdin-control\",\n\t\tcfdflags.Name,\n\t\tcfdflags.Ui,\n\t\t\"quick-service\",\n\t\t\"max-fetch-size\",\n\t\tcfdflags.PostQuantum,\n\t\t\"management-diagnostics\",\n\t\tcfdflags.Protocol,\n\t\t\"overwrite-dns\",\n\t\t\"help\",\n\t\tcfdflags.MaxActiveFlows,\n\t}\n)\n\nfunc Flags() []cli.Flag {\n\treturn tunnelFlags(true)\n}\n\nfunc Commands() []*cli.Command {\n\tsubcommands := []*cli.Command{\n\t\tbuildLoginSubcommand(false),\n\t\tbuildCreateCommand(),\n\t\tbuildRouteCommand(),\n\t\tbuildVirtualNetworkSubcommand(false),\n\t\tbuildRunCommand(),\n\t\tbuildListCommand(),\n\t\tbuildReadyCommand(),\n\t\tbuildInfoCommand(),\n\t\tbuildIngressSubcommand(),\n\t\tbuildDeleteCommand(),\n\t\tbuildCleanupCommand(),\n\t\tbuildTokenCommand(),\n\t\tbuildDiagCommand(),\n\t\tproxydns.Command(), // removed feature, only here for error message\n\t\tcliutil.RemovedCommand(\"db-connect\"),\n\t}\n\n\treturn []*cli.Command{\n\t\tbuildTunnelCommand(subcommands),\n\t\t// for compatibility, allow following as top-level subcommands\n\t\tbuildLoginSubcommand(true),\n\t\tcliutil.RemovedCommand(\"db-connect\"),\n\t}\n}\n\nfunc buildTunnelCommand(subcommands []*cli.Command) *cli.Command {\n\treturn &cli.Command{\n\t\tName:      \"tunnel\",\n\t\tAction:    cliutil.ConfiguredAction(TunnelCommand),\n\t\tCategory:  \"Tunnel\",\n\t\tUsage:     \"Use Cloudflare Tunnel to expose private services to the Internet or to Cloudflare connected private users.\",\n\t\tArgsUsage: \" \",\n\t\tDescription: `    Cloudflare Tunnel allows to expose private services without opening any ingress port on this machine. It can expose:\n  A) Locally reachable HTTP-based private services to the Internet on DNS with Cloudflare as authority (which you can\nthen protect with Cloudflare Access).\n  B) Locally reachable TCP/UDP-based private services to Cloudflare connected private users in the same account, e.g.,\nthose enrolled to a Zero Trust WARP Client.\n\nYou can manage your Tunnels via one.dash.cloudflare.com. This approach will only require you to run a single command\nlater in each machine where you wish to run a Tunnel.\n\nAlternatively, you can manage your Tunnels via the command line. Begin by obtaining a certificate to be able to do so:\n\n\t$ cloudflared tunnel login\n\nWith your certificate installed you can then get started with Tunnels:\n\n\t$ cloudflared tunnel create my-first-tunnel\n\t$ cloudflared tunnel route dns my-first-tunnel my-first-tunnel.mydomain.com\n\t$ cloudflared tunnel run --hello-world my-first-tunnel\n\nYou can now access my-first-tunnel.mydomain.com and be served an example page by your local cloudflared process.\n\nFor exposing local TCP/UDP services by IP to your privately connected users, check out:\n\n\t$ cloudflared tunnel route ip --help\n\nSee https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/tunnel-guide/ for more info.`,\n\t\tSubcommands: subcommands,\n\t\tFlags:       tunnelFlags(false),\n\t}\n}\n\nfunc TunnelCommand(c *cli.Context) error {\n\tsc, err := newSubcommandContext(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Run a adhoc named tunnel\n\t// Allows for the creation, routing (optional), and startup of a tunnel in one command\n\t// --name required\n\t// --url or --hello-world required\n\t// --hostname optional\n\tif name := c.String(cfdflags.Name); name != \"\" {\n\t\thostname, err := validation.ValidateHostname(c.String(\"hostname\"))\n\t\tif err != nil {\n\t\t\treturn errors.Wrap(err, \"Invalid hostname provided\")\n\t\t}\n\t\turl := c.String(\"url\")\n\t\tif url == hostname && url != \"\" && hostname != \"\" {\n\t\t\treturn fmt.Errorf(\"hostname and url shouldn't match. See --help for more information\")\n\t\t}\n\n\t\treturn runAdhocNamedTunnel(sc, name, c.String(CredFileFlag))\n\t}\n\n\t// Run a quick tunnel\n\t// A unauthenticated named tunnel hosted on <random>.<quick-tunnels-service>.com\n\tshouldRunQuickTunnel := c.IsSet(\"url\") || c.IsSet(ingress.HelloWorldFlag)\n\tif c.String(\"quick-service\") != \"\" && shouldRunQuickTunnel {\n\t\treturn RunQuickTunnel(sc)\n\t}\n\n\t// If user provides a config, check to see if they meant to use `tunnel run` instead\n\tif ref := config.GetConfiguration().TunnelID; ref != \"\" {\n\t\treturn fmt.Errorf(\"Use `cloudflared tunnel run` to start tunnel %s\", ref)\n\t}\n\n\t// Classic tunnel usage is no longer supported\n\tif c.String(\"hostname\") != \"\" {\n\t\treturn errDeprecatedClassicTunnel\n\t}\n\n\treturn errors.New(tunnelCmdErrorMessage)\n}\n\nfunc Init(info *cliutil.BuildInfo, gracefulShutdown chan struct{}) {\n\tbuildInfo, graceShutdownC = info, gracefulShutdown\n}\n\n// runAdhocNamedTunnel create, route and run a named tunnel in one command\nfunc runAdhocNamedTunnel(sc *subcommandContext, name, credentialsOutputPath string) error {\n\ttunnel, ok, err := sc.tunnelActive(name)\n\tif err != nil || !ok {\n\t\t// pass empty string as secret to generate one\n\t\ttunnel, err = sc.create(name, credentialsOutputPath, \"\")\n\t\tif err != nil {\n\t\t\treturn errors.Wrap(err, \"failed to create tunnel\")\n\t\t}\n\t} else {\n\t\tsc.log.Info().Str(LogFieldTunnelID, tunnel.ID.String()).Msg(\"Reusing existing tunnel with this name\")\n\t}\n\n\tif r, ok := routeFromFlag(sc.c); ok {\n\t\tif res, err := sc.route(tunnel.ID, r); err != nil {\n\t\t\tsc.log.Err(err).Str(\"route\", r.String()).Msg(routeFailMsg)\n\t\t} else {\n\t\t\tsc.log.Info().Msg(res.SuccessSummary())\n\t\t}\n\t}\n\n\tif err := sc.run(tunnel.ID); err != nil {\n\t\treturn errors.Wrap(err, \"error running tunnel\")\n\t}\n\n\treturn nil\n}\n\nfunc routeFromFlag(c *cli.Context) (route cfapi.HostnameRoute, ok bool) {\n\tif hostname := c.String(\"hostname\"); hostname != \"\" {\n\t\tif lbPool := c.String(cfdflags.LBPool); lbPool != \"\" {\n\t\t\treturn cfapi.NewLBRoute(hostname, lbPool), true\n\t\t}\n\t\treturn cfapi.NewDNSRoute(hostname, c.Bool(overwriteDNSFlagName)), true\n\t}\n\treturn nil, false\n}\n\nfunc StartServer(\n\tc *cli.Context,\n\tinfo *cliutil.BuildInfo,\n\tnamedTunnel *connection.TunnelProperties,\n\tlog *zerolog.Logger,\n) error {\n\terr := sentry.Init(sentry.ClientOptions{\n\t\tDsn:     sentryDSN,\n\t\tRelease: c.App.Version,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar wg sync.WaitGroup\n\tlisteners := gracenet.Net{}\n\terrC := make(chan error)\n\n\t// Only log for locally configured tunnels (Token is blank).\n\tif config.GetConfiguration().Source() == \"\" && c.String(TunnelTokenFlag) == \"\" {\n\t\tlog.Info().Msg(config.ErrNoConfigFile.Error())\n\t}\n\n\tif c.IsSet(cfdflags.TraceOutput) {\n\t\ttmpTraceFile, err := os.CreateTemp(\"\", \"trace\")\n\t\tif err != nil {\n\t\t\tlog.Err(err).Msg(\"Failed to create new temporary file to save trace output\")\n\t\t}\n\n\t\ttraceLog := log.With().Str(LogFieldTmpTraceFilename, tmpTraceFile.Name()).Logger()\n\n\t\tdefer func() {\n\t\t\tif err := tmpTraceFile.Close(); err != nil {\n\t\t\t\ttraceLog.Err(err).Msg(\"Failed to close temporary trace output file\")\n\t\t\t}\n\t\t\ttraceOutputFilepath := c.String(cfdflags.TraceOutput)\n\t\t\tif err := os.Rename(tmpTraceFile.Name(), traceOutputFilepath); err != nil {\n\t\t\t\ttraceLog.\n\t\t\t\t\tErr(err).\n\t\t\t\t\tStr(LogFieldTraceOutputFilepath, traceOutputFilepath).\n\t\t\t\t\tMsg(\"Failed to rename temporary trace output file\")\n\t\t\t} else {\n\t\t\t\terr := os.Remove(tmpTraceFile.Name())\n\t\t\t\tif err != nil {\n\t\t\t\t\ttraceLog.Err(err).Msg(\"Failed to remove the temporary trace file\")\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\n\t\tif err := trace.Start(tmpTraceFile); err != nil {\n\t\t\ttraceLog.Err(err).Msg(\"Failed to start trace\")\n\t\t\treturn errors.Wrap(err, \"Error starting tracing\")\n\t\t}\n\t\tdefer trace.Stop()\n\t}\n\n\tinfo.Log(log)\n\tlogClientOptions(c, log)\n\n\t// this context drives the server, when it's cancelled tunnel and all other components (origins, dns, etc...) should stop\n\tctx, cancel := context.WithCancel(c.Context)\n\tdefer cancel()\n\n\tgo waitForSignal(graceShutdownC, log)\n\n\tconnectedSignal := signal.New(make(chan struct{}))\n\tgo notifySystemd(connectedSignal)\n\tif c.IsSet(\"pidfile\") {\n\t\tgo writePidFile(connectedSignal, c.String(\"pidfile\"), log)\n\t}\n\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tautoupdater := updater.NewAutoUpdater(\n\t\t\tc.Bool(cfdflags.NoAutoUpdate), c.Duration(cfdflags.AutoUpdateFreq), &listeners, log,\n\t\t)\n\t\terrC <- autoupdater.Run(ctx)\n\t}()\n\n\tif namedTunnel == nil {\n\t\treturn fmt.Errorf(\"namedTunnel is nil\")\n\t}\n\n\tlogTransport := logger.CreateTransportLoggerFromContext(c, logger.EnableTerminalLog)\n\n\tobserver := connection.NewObserver(log, logTransport)\n\n\t// Send Quick Tunnel URL to UI if applicable\n\tquickTunnelURL := namedTunnel.QuickTunnelUrl\n\tif quickTunnelURL != \"\" {\n\t\tobserver.SendURL(quickTunnelURL)\n\t}\n\n\ttunnelConfig, orchestratorConfig, err := prepareTunnelConfig(ctx, c, info, log, logTransport, observer, namedTunnel)\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"Couldn't start tunnel\")\n\t\treturn err\n\t}\n\tconnectorID := tunnelConfig.ClientConfig.ConnectorID\n\n\t// Disable ICMP packet routing for quick tunnels\n\tif quickTunnelURL != \"\" {\n\t\ttunnelConfig.ICMPRouterServer = nil\n\t}\n\n\tserviceIP := c.String(\"service-op-ip\")\n\tif edgeAddrs, err := edgediscovery.ResolveEdge(log, tunnelConfig.Region, tunnelConfig.EdgeIPVersion); err == nil {\n\t\tif serviceAddr, err := edgeAddrs.GetAddrForRPC(); err == nil {\n\t\t\tserviceIP = serviceAddr.TCP.String()\n\t\t}\n\t}\n\n\tisFEDEndpoint := namedTunnel.Credentials.Endpoint == credentials.FedEndpoint\n\tvar managementHostname string\n\tif isFEDEndpoint {\n\t\tmanagementHostname = credentials.FedRampHostname\n\t} else {\n\t\tmanagementHostname = c.String(cfdflags.ManagementHostname)\n\t}\n\n\tmgmt := management.New(\n\t\tmanagementHostname,\n\t\tc.Bool(\"management-diagnostics\"),\n\t\tserviceIP,\n\t\tconnectorID,\n\t\tc.String(cfdflags.ConnectorLabel),\n\t\tlogger.ManagementLogger.Log,\n\t\tlogger.ManagementLogger,\n\t)\n\tinternalRules := []ingress.Rule{ingress.NewManagementRule(mgmt)}\n\torchestrator, err := orchestration.NewOrchestrator(ctx, orchestratorConfig, tunnelConfig.Tags, internalRules, tunnelConfig.Log)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tmetricsListener, err := metrics.CreateMetricsListener(&listeners, c.String(\"metrics\"))\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"Error opening metrics server listener\")\n\t\treturn errors.Wrap(err, \"Error opening metrics server listener\")\n\t}\n\n\tdefer metricsListener.Close()\n\twg.Add(1)\n\n\tgo func() {\n\t\tdefer wg.Done()\n\t\ttracker := tunnelstate.NewConnTracker(log)\n\t\tobserver.RegisterSink(tracker)\n\n\t\tipv4, ipv6, err := determineICMPSources(c, log)\n\t\tsources := make([]string, 0)\n\t\tif err == nil {\n\t\t\tsources = append(sources, ipv4.String())\n\t\t\tsources = append(sources, ipv6.String())\n\t\t}\n\n\t\treadinessServer := metrics.NewReadyServer(connectorID, tracker)\n\t\tcliFlags := nonSecretCliFlags(log, c, nonSecretFlagsList)\n\t\tdiagnosticHandler := diagnostic.NewDiagnosticHandler(\n\t\t\tlog,\n\t\t\t0,\n\t\t\tdiagnostic.NewSystemCollectorImpl(buildInfo.CloudflaredVersion),\n\t\t\ttunnelConfig.NamedTunnel.Credentials.TunnelID,\n\t\t\tconnectorID,\n\t\t\ttracker,\n\t\t\tcliFlags,\n\t\t\tsources,\n\t\t)\n\t\tmetricsConfig := metrics.Config{\n\t\t\tReadyServer:         readinessServer,\n\t\t\tDiagnosticHandler:   diagnosticHandler,\n\t\t\tQuickTunnelHostname: quickTunnelURL,\n\t\t\tOrchestrator:        orchestrator,\n\t\t}\n\t\terrC <- metrics.ServeMetrics(metricsListener, ctx, metricsConfig, log)\n\t}()\n\n\treconnectCh := make(chan supervisor.ReconnectSignal, c.Int(cfdflags.HaConnections))\n\tif c.IsSet(\"stdin-control\") {\n\t\tlog.Info().Msg(\"Enabling control through stdin\")\n\t\tgo stdinControl(reconnectCh, log)\n\t}\n\n\twg.Add(1)\n\tgo func() {\n\t\tdefer func() {\n\t\t\twg.Done()\n\t\t\tlog.Info().Msg(\"Tunnel server stopped\")\n\t\t}()\n\t\terrC <- supervisor.StartTunnelDaemon(ctx, tunnelConfig, orchestrator, connectedSignal, reconnectCh, graceShutdownC)\n\t}()\n\n\tgracePeriod, err := gracePeriod(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn waitToShutdown(&wg, cancel, errC, graceShutdownC, gracePeriod, log)\n}\n\nfunc waitToShutdown(wg *sync.WaitGroup,\n\tcancelServerContext func(),\n\terrC <-chan error,\n\tgraceShutdownC <-chan struct{},\n\tgracePeriod time.Duration,\n\tlog *zerolog.Logger,\n) error {\n\tvar err error\n\tselect {\n\tcase err = <-errC:\n\t\tlog.Error().Err(err).Msg(\"Initiating shutdown\")\n\tcase <-graceShutdownC:\n\t\tlog.Debug().Msg(\"Graceful shutdown signalled\")\n\t\tif gracePeriod > 0 {\n\t\t\t// wait for either grace period or service termination\n\t\t\tticker := time.NewTicker(gracePeriod)\n\t\t\tdefer ticker.Stop()\n\t\t\tselect {\n\t\t\tcase <-ticker.C:\n\t\t\tcase <-errC:\n\t\t\t}\n\t\t}\n\t}\n\n\t// stop server context\n\tcancelServerContext()\n\n\t// Wait for clean exit, discarding all errors while we wait\n\tstopDiscarding := make(chan struct{})\n\tgo func() {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-errC: // ignore\n\t\t\tcase <-stopDiscarding:\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\twg.Wait()\n\tclose(stopDiscarding)\n\n\treturn err\n}\n\nfunc notifySystemd(waitForSignal *signal.Signal) {\n\t<-waitForSignal.Wait()\n\t_, _ = daemon.SdNotify(false, \"READY=1\")\n}\n\nfunc writePidFile(waitForSignal *signal.Signal, pidPathname string, log *zerolog.Logger) {\n\t<-waitForSignal.Wait()\n\texpandedPath, err := homedir.Expand(pidPathname)\n\tif err != nil {\n\t\tlog.Err(err).Str(LogFieldPIDPathname, pidPathname).Msg(\"Unable to expand the path, try to use absolute path in --pidfile\")\n\t\treturn\n\t}\n\tfile, err := os.Create(expandedPath)\n\tif err != nil {\n\t\tlog.Err(err).Str(LogFieldExpandedPath, expandedPath).Msg(\"Unable to write pid\")\n\t\treturn\n\t}\n\tdefer file.Close()\n\tfmt.Fprintf(file, \"%d\", os.Getpid())\n}\n\nfunc hostnameFromURI(uri string) string {\n\tu, err := url.Parse(uri)\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\tswitch u.Scheme {\n\tcase \"ssh\":\n\t\treturn addPortIfMissing(u, 22)\n\tcase \"rdp\":\n\t\treturn addPortIfMissing(u, 3389)\n\tcase \"smb\":\n\t\treturn addPortIfMissing(u, 445)\n\tcase \"tcp\":\n\t\treturn addPortIfMissing(u, 7864) // just a random port since there isn't a default in this case\n\t}\n\treturn \"\"\n}\n\nfunc addPortIfMissing(uri *url.URL, port int) string {\n\tif uri.Port() != \"\" {\n\t\treturn uri.Host\n\t}\n\treturn fmt.Sprintf(\"%s:%d\", uri.Hostname(), port)\n}\n\nfunc tunnelFlags(shouldHide bool) []cli.Flag {\n\tflags := configureCloudflaredFlags(shouldHide)\n\tflags = append(flags, configureProxyFlags(shouldHide)...)\n\tflags = append(flags, cliutil.ConfigureLoggingFlags(shouldHide)...)\n\tflags = append(flags, proxydns.ConfigureProxyDNSFlags(shouldHide)...) // removed feature, only kept to not break any script that might be setting these flags\n\tflags = append(flags, []cli.Flag{\n\t\tcredentialsFileFlag,\n\t\taltsrc.NewBoolFlag(&cli.BoolFlag{\n\t\t\tName:   cfdflags.IsAutoUpdated,\n\t\t\tUsage:  \"Signal the new process that Cloudflare Tunnel connector has been autoupdated\",\n\t\t\tValue:  false,\n\t\t\tHidden: true,\n\t\t}),\n\t\taltsrc.NewStringSliceFlag(&cli.StringSliceFlag{\n\t\t\tName:    cfdflags.Edge,\n\t\t\tUsage:   \"Address of the Cloudflare tunnel server. Only works in Cloudflare's internal testing environment.\",\n\t\t\tEnvVars: []string{\"TUNNEL_EDGE\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    cfdflags.Region,\n\t\t\tUsage:   \"Cloudflare Edge region to connect to. Omit or set to empty to connect to the global region.\",\n\t\t\tEnvVars: []string{\"TUNNEL_REGION\"},\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    cfdflags.EdgeIpVersion,\n\t\t\tUsage:   \"Cloudflare Edge IP address version to connect with. {4, 6, auto}\",\n\t\t\tEnvVars: []string{\"TUNNEL_EDGE_IP_VERSION\"},\n\t\t\tValue:   \"4\",\n\t\t\tHidden:  false,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    cfdflags.EdgeBindAddress,\n\t\t\tUsage:   \"Bind to IP address for outgoing connections to Cloudflare Edge.\",\n\t\t\tEnvVars: []string{\"TUNNEL_EDGE_BIND_ADDRESS\"},\n\t\t\tHidden:  false,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    tlsconfig.CaCertFlag,\n\t\t\tUsage:   \"Certificate Authority authenticating connections with Cloudflare's edge network.\",\n\t\t\tEnvVars: []string{\"TUNNEL_CACERT\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    \"hostname\",\n\t\t\tUsage:   \"Set a hostname on a Cloudflare zone to route traffic through this tunnel.\",\n\t\t\tEnvVars: []string{\"TUNNEL_HOSTNAME\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    \"id\",\n\t\t\tUsage:   \"A unique identifier used to tie connections to this tunnel instance.\",\n\t\t\tEnvVars: []string{\"TUNNEL_ID\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    cfdflags.LBPool,\n\t\t\tUsage:   \"The name of a (new/existing) load balancing pool to add this origin to.\",\n\t\t\tEnvVars: []string{\"TUNNEL_LB_POOL\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    \"api-key\",\n\t\t\tUsage:   \"This parameter has been deprecated since version 2017.10.1.\",\n\t\t\tEnvVars: []string{\"TUNNEL_API_KEY\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    \"api-email\",\n\t\t\tUsage:   \"This parameter has been deprecated since version 2017.10.1.\",\n\t\t\tEnvVars: []string{\"TUNNEL_API_EMAIL\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    \"api-ca-key\",\n\t\t\tUsage:   \"This parameter has been deprecated since version 2017.10.1.\",\n\t\t\tEnvVars: []string{\"TUNNEL_API_CA_KEY\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    cfdflags.ApiURL,\n\t\t\tUsage:   \"Base URL for Cloudflare API v4\",\n\t\t\tEnvVars: []string{\"TUNNEL_API_URL\"},\n\t\t\tValue:   \"https://api.cloudflare.com/client/v4\",\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewDurationFlag(&cli.DurationFlag{\n\t\t\tName:    cfdflags.MetricsUpdateFreq,\n\t\t\tUsage:   \"Frequency to update tunnel metrics\",\n\t\t\tValue:   time.Second * 5,\n\t\t\tEnvVars: []string{\"TUNNEL_METRICS_UPDATE_FREQ\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewStringSliceFlag(&cli.StringSliceFlag{\n\t\t\tName:    cfdflags.Tag,\n\t\t\tUsage:   \"Custom tags used to identify this tunnel via added HTTP request headers to the origin, in format `KEY=VALUE`. Multiple tags may be specified.\",\n\t\t\tEnvVars: []string{\"TUNNEL_TAG\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewDurationFlag(&cli.DurationFlag{\n\t\t\tName:   \"heartbeat-interval\",\n\t\t\tUsage:  \"Minimum idle time before sending a heartbeat.\",\n\t\t\tValue:  time.Second * 5,\n\t\t\tHidden: true,\n\t\t}),\n\t\t// Note TUN-3758 , we use Int because UInt is not supported with altsrc\n\t\taltsrc.NewIntFlag(&cli.IntFlag{\n\t\t\tName:   \"heartbeat-count\",\n\t\t\tUsage:  \"Minimum number of unacked heartbeats to send before closing the connection.\",\n\t\t\tValue:  5,\n\t\t\tHidden: true,\n\t\t}),\n\t\taltsrc.NewIntFlag(&cli.IntFlag{\n\t\t\tName:   cfdflags.MaxEdgeAddrRetries,\n\t\t\tUsage:  \"Maximum number of times to retry on edge addrs before falling back to a lower protocol\",\n\t\t\tValue:  8,\n\t\t\tHidden: true,\n\t\t}),\n\t\t// Note TUN-3758 , we use Int because UInt is not supported with altsrc\n\t\taltsrc.NewIntFlag(&cli.IntFlag{\n\t\t\tName:    cfdflags.Retries,\n\t\t\tValue:   5,\n\t\t\tUsage:   \"Maximum number of retries for connection/protocol errors.\",\n\t\t\tEnvVars: []string{\"TUNNEL_RETRIES\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewIntFlag(&cli.IntFlag{\n\t\t\tName:   cfdflags.HaConnections,\n\t\t\tValue:  4,\n\t\t\tHidden: true,\n\t\t}),\n\t\taltsrc.NewDurationFlag(&cli.DurationFlag{\n\t\t\tName:   cfdflags.RpcTimeout,\n\t\t\tValue:  5 * time.Second,\n\t\t\tHidden: true,\n\t\t}),\n\t\taltsrc.NewDurationFlag(&cli.DurationFlag{\n\t\t\tName:    cfdflags.WriteStreamTimeout,\n\t\t\tEnvVars: []string{\"TUNNEL_STREAM_WRITE_TIMEOUT\"},\n\t\t\tUsage:   \"Use this option to add a stream write timeout for connections when writing towards the origin or edge. Default is 0 which disables the write timeout.\",\n\t\t\tValue:   0 * time.Second,\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewBoolFlag(&cli.BoolFlag{\n\t\t\tName:    cfdflags.QuicDisablePathMTUDiscovery,\n\t\t\tEnvVars: []string{\"TUNNEL_DISABLE_QUIC_PMTU\"},\n\t\t\tUsage:   \"Use this option to disable PTMU discovery for QUIC connections. This will result in lower packet sizes. Not however, that this may cause instability for UDP proxying.\",\n\t\t\tValue:   false,\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewIntFlag(&cli.IntFlag{\n\t\t\tName:    cfdflags.QuicConnLevelFlowControlLimit,\n\t\t\tEnvVars: []string{\"TUNNEL_QUIC_CONN_LEVEL_FLOW_CONTROL_LIMIT\"},\n\t\t\tUsage:   \"Use this option to change the connection-level flow control limit for QUIC transport.\",\n\t\t\tValue:   30 * (1 << 20), // 30 MB\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewIntFlag(&cli.IntFlag{\n\t\t\tName:    cfdflags.QuicStreamLevelFlowControlLimit,\n\t\t\tEnvVars: []string{\"TUNNEL_QUIC_STREAM_LEVEL_FLOW_CONTROL_LIMIT\"},\n\t\t\tUsage:   \"Use this option to change the connection-level flow control limit for QUIC transport.\",\n\t\t\tValue:   6 * (1 << 20), // 6 MB\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:  cfdflags.ConnectorLabel,\n\t\t\tUsage: \"Use this option to give a meaningful label to a specific connector. When a tunnel starts up, a connector id unique to the tunnel is generated. This is a uuid. To make it easier to identify a connector, we will use the hostname of the machine the tunnel is running on along with the connector ID. This option exists if one wants to have more control over what their individual connectors are called.\",\n\t\t\tValue: \"\",\n\t\t}),\n\t\taltsrc.NewDurationFlag(&cli.DurationFlag{\n\t\t\tName:    cfdflags.GracePeriod,\n\t\t\tUsage:   \"When cloudflared receives SIGINT/SIGTERM it will stop accepting new requests, wait for in-progress requests to terminate, then shutdown. Waiting for in-progress requests will timeout after this grace period, or when a second SIGTERM/SIGINT is received.\",\n\t\t\tValue:   time.Second * 30,\n\t\t\tEnvVars: []string{\"TUNNEL_GRACE_PERIOD\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\t// Note TUN-3758 , we use Int because UInt is not supported with altsrc\n\t\taltsrc.NewIntFlag(&cli.IntFlag{\n\t\t\tName:    \"compression-quality\",\n\t\t\tValue:   0,\n\t\t\tUsage:   \"(beta) Use cross-stream compression instead HTTP compression. 0-off, 1-low, 2-medium, >=3-high.\",\n\t\t\tEnvVars: []string{\"TUNNEL_COMPRESSION_LEVEL\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewBoolFlag(&cli.BoolFlag{\n\t\t\tName:    \"use-reconnect-token\",\n\t\t\tUsage:   \"Test reestablishing connections with the new 'reconnect token' flow.\",\n\t\t\tValue:   true,\n\t\t\tEnvVars: []string{\"TUNNEL_USE_RECONNECT_TOKEN\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewDurationFlag(&cli.DurationFlag{\n\t\t\tName:    \"dial-edge-timeout\",\n\t\t\tUsage:   \"Maximum wait time to set up a connection with the edge\",\n\t\t\tValue:   time.Second * 15,\n\t\t\tEnvVars: []string{\"DIAL_EDGE_TIMEOUT\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewBoolFlag(&cli.BoolFlag{\n\t\t\tName:    \"stdin-control\",\n\t\t\tUsage:   \"Control the process using commands sent through stdin\",\n\t\t\tEnvVars: []string{\"STDIN_CONTROL\"},\n\t\t\tHidden:  true,\n\t\t\tValue:   false,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    cfdflags.Name,\n\t\t\tAliases: []string{\"n\"},\n\t\t\tEnvVars: []string{\"TUNNEL_NAME\"},\n\t\t\tUsage:   \"Stable name to identify the tunnel. Using this flag will create, route and run a tunnel. For production usage, execute each command separately\",\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewBoolFlag(&cli.BoolFlag{\n\t\t\tName:   cfdflags.Ui,\n\t\t\tUsage:  \"(depreciated) Launch tunnel UI. Tunnel logs are scrollable via 'j', 'k', or arrow keys.\",\n\t\t\tValue:  false,\n\t\t\tHidden: true,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:   \"quick-service\",\n\t\t\tUsage:  \"URL for a service which manages unauthenticated 'quick' tunnels.\",\n\t\t\tValue:  \"https://api.trycloudflare.com\",\n\t\t\tHidden: true,\n\t\t}),\n\t\taltsrc.NewIntFlag(&cli.IntFlag{\n\t\t\tName:    \"max-fetch-size\",\n\t\t\tUsage:   `The maximum number of results that cloudflared can fetch from Cloudflare API for any listing operations needed`,\n\t\t\tEnvVars: []string{\"TUNNEL_MAX_FETCH_SIZE\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewBoolFlag(&cli.BoolFlag{\n\t\t\tName:    cfdflags.PostQuantum,\n\t\t\tUsage:   \"When given creates an experimental post-quantum secure tunnel\",\n\t\t\tAliases: []string{\"pq\"},\n\t\t\tEnvVars: []string{\"TUNNEL_POST_QUANTUM\"},\n\t\t}),\n\t\taltsrc.NewBoolFlag(&cli.BoolFlag{\n\t\t\tName:    \"management-diagnostics\",\n\t\t\tUsage:   \"Enables the in-depth diagnostic routes to be made available over the management service (/debug/pprof, /metrics, etc.)\",\n\t\t\tEnvVars: []string{\"TUNNEL_MANAGEMENT_DIAGNOSTICS\"},\n\t\t\tValue:   true,\n\t\t}),\n\t\tselectProtocolFlag,\n\t\toverwriteDNSFlag,\n\t}...)\n\n\treturn flags\n}\n\n// Flags in tunnel command that is relevant to run subcommand\nfunc configureCloudflaredFlags(shouldHide bool) []cli.Flag {\n\treturn []cli.Flag{\n\t\t&cli.StringFlag{\n\t\t\tName:   \"config\",\n\t\t\tUsage:  \"Specifies a config file in YAML format.\",\n\t\t\tValue:  config.FindDefaultConfigPath(),\n\t\t\tHidden: shouldHide,\n\t\t},\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    cfdflags.OriginCert,\n\t\t\tUsage:   \"Path to the certificate generated for your origin when you run cloudflared login.\",\n\t\t\tEnvVars: []string{\"TUNNEL_ORIGIN_CERT\"},\n\t\t\tValue:   credentials.FindDefaultOriginCertPath(),\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewDurationFlag(&cli.DurationFlag{\n\t\t\tName:   cfdflags.AutoUpdateFreq,\n\t\t\tUsage:  fmt.Sprintf(\"Autoupdate frequency. Default is %v.\", updater.DefaultCheckUpdateFreq),\n\t\t\tValue:  updater.DefaultCheckUpdateFreq,\n\t\t\tHidden: shouldHide,\n\t\t}),\n\t\taltsrc.NewBoolFlag(&cli.BoolFlag{\n\t\t\tName:    cfdflags.NoAutoUpdate,\n\t\t\tUsage:   \"Disable periodic check for updates, restarting the server with the new version.\",\n\t\t\tEnvVars: []string{\"NO_AUTOUPDATE\"},\n\t\t\tValue:   false,\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:  cfdflags.Metrics,\n\t\t\tValue: metrics.GetMetricsDefaultAddress(metrics.Runtime),\n\t\t\tUsage: fmt.Sprintf(\n\t\t\t\t`Listen address for metrics reporting. If no address is passed cloudflared will try to bind to %v.\nIf all are unavailable, a random port will be used. Note that when running cloudflared from an virtual\nenvironment the default address binds to all interfaces, hence, it is important to isolate the host\nand virtualized host network stacks from each other`,\n\t\t\t\tmetrics.GetMetricsKnownAddresses(metrics.Runtime),\n\t\t\t),\n\t\t\tEnvVars: []string{\"TUNNEL_METRICS\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    \"pidfile\",\n\t\t\tUsage:   \"Write the application's PID to this file after first successful connection.\",\n\t\t\tEnvVars: []string{\"TUNNEL_PIDFILE\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t}\n}\n\nfunc configureProxyFlags(shouldHide bool) []cli.Flag {\n\tflags := []cli.Flag{\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    \"url\",\n\t\t\tValue:   \"http://localhost:8080\",\n\t\t\tUsage:   \"Connect to the local webserver at `URL`.\",\n\t\t\tEnvVars: []string{\"TUNNEL_URL\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewBoolFlag(&cli.BoolFlag{\n\t\t\tName:    ingress.HelloWorldFlag,\n\t\t\tValue:   false,\n\t\t\tUsage:   \"Run Hello World Server\",\n\t\t\tEnvVars: []string{\"TUNNEL_HELLO_WORLD\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewBoolFlag(&cli.BoolFlag{\n\t\t\tName:    ingress.Socks5Flag,\n\t\t\tUsage:   legacyTunnelFlag(\"specify if this tunnel is running as a SOCK5 Server\"),\n\t\t\tEnvVars: []string{\"TUNNEL_SOCKS\"},\n\t\t\tValue:   false,\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewDurationFlag(&cli.DurationFlag{\n\t\t\tName:   ingress.ProxyConnectTimeoutFlag,\n\t\t\tUsage:  legacyTunnelFlag(\"HTTP proxy timeout for establishing a new connection\"),\n\t\t\tValue:  time.Second * 30,\n\t\t\tHidden: shouldHide,\n\t\t}),\n\t\taltsrc.NewDurationFlag(&cli.DurationFlag{\n\t\t\tName:   ingress.ProxyTLSTimeoutFlag,\n\t\t\tUsage:  legacyTunnelFlag(\"HTTP proxy timeout for completing a TLS handshake\"),\n\t\t\tValue:  time.Second * 10,\n\t\t\tHidden: shouldHide,\n\t\t}),\n\t\taltsrc.NewDurationFlag(&cli.DurationFlag{\n\t\t\tName:   ingress.ProxyTCPKeepAliveFlag,\n\t\t\tUsage:  legacyTunnelFlag(\"HTTP proxy TCP keepalive duration\"),\n\t\t\tValue:  time.Second * 30,\n\t\t\tHidden: shouldHide,\n\t\t}),\n\t\taltsrc.NewBoolFlag(&cli.BoolFlag{\n\t\t\tName:   ingress.ProxyNoHappyEyeballsFlag,\n\t\t\tUsage:  legacyTunnelFlag(\"HTTP proxy should disable \\\"happy eyeballs\\\" for IPv4/v6 fallback\"),\n\t\t\tHidden: shouldHide,\n\t\t}),\n\t\taltsrc.NewIntFlag(&cli.IntFlag{\n\t\t\tName:   ingress.ProxyKeepAliveConnectionsFlag,\n\t\t\tUsage:  legacyTunnelFlag(\"HTTP proxy maximum keepalive connection pool size\"),\n\t\t\tValue:  100,\n\t\t\tHidden: shouldHide,\n\t\t}),\n\t\taltsrc.NewDurationFlag(&cli.DurationFlag{\n\t\t\tName:   ingress.ProxyKeepAliveTimeoutFlag,\n\t\t\tUsage:  legacyTunnelFlag(\"HTTP proxy timeout for closing an idle connection\"),\n\t\t\tValue:  time.Second * 90,\n\t\t\tHidden: shouldHide,\n\t\t}),\n\t\taltsrc.NewDurationFlag(&cli.DurationFlag{\n\t\t\tName:   \"proxy-connection-timeout\",\n\t\t\tUsage:  \"DEPRECATED. No longer has any effect.\",\n\t\t\tValue:  time.Second * 90,\n\t\t\tHidden: shouldHide,\n\t\t}),\n\t\taltsrc.NewDurationFlag(&cli.DurationFlag{\n\t\t\tName:   \"proxy-expect-continue-timeout\",\n\t\t\tUsage:  \"DEPRECATED. No longer has any effect.\",\n\t\t\tValue:  time.Second * 90,\n\t\t\tHidden: shouldHide,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    ingress.HTTPHostHeaderFlag,\n\t\t\tUsage:   legacyTunnelFlag(\"Sets the HTTP Host header for the local webserver.\"),\n\t\t\tEnvVars: []string{\"TUNNEL_HTTP_HOST_HEADER\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    ingress.OriginServerNameFlag,\n\t\t\tUsage:   legacyTunnelFlag(\"Hostname on the origin server certificate.\"),\n\t\t\tEnvVars: []string{\"TUNNEL_ORIGIN_SERVER_NAME\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    \"unix-socket\",\n\t\t\tUsage:   \"Path to unix socket to use instead of --url\",\n\t\t\tEnvVars: []string{\"TUNNEL_UNIX_SOCKET\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    tlsconfig.OriginCAPoolFlag,\n\t\t\tUsage:   legacyTunnelFlag(\"Path to the CA for the certificate of your origin. This option should be used only if your certificate is not signed by Cloudflare.\"),\n\t\t\tEnvVars: []string{\"TUNNEL_ORIGIN_CA_POOL\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewBoolFlag(&cli.BoolFlag{\n\t\t\tName:    ingress.NoTLSVerifyFlag,\n\t\t\tUsage:   legacyTunnelFlag(\"Disables TLS verification of the certificate presented by your origin. Will allow any certificate from the origin to be accepted. Note: The connection from your machine to Cloudflare's Edge is still encrypted.\"),\n\t\t\tEnvVars: []string{\"NO_TLS_VERIFY\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewBoolFlag(&cli.BoolFlag{\n\t\t\tName:    ingress.NoChunkedEncodingFlag,\n\t\t\tUsage:   legacyTunnelFlag(\"Disables chunked transfer encoding; useful if you are running a WSGI server.\"),\n\t\t\tEnvVars: []string{\"TUNNEL_NO_CHUNKED_ENCODING\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewBoolFlag(&cli.BoolFlag{\n\t\t\tName:    ingress.Http2OriginFlag,\n\t\t\tUsage:   \"Enables HTTP/2 origin servers.\",\n\t\t\tEnvVars: []string{\"TUNNEL_ORIGIN_ENABLE_HTTP2\"},\n\t\t\tHidden:  shouldHide,\n\t\t\tValue:   false,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    cfdflags.ManagementHostname,\n\t\t\tUsage:   \"Management hostname to signify incoming management requests\",\n\t\t\tEnvVars: []string{\"TUNNEL_MANAGEMENT_HOSTNAME\"},\n\t\t\tHidden:  true,\n\t\t\tValue:   \"management.argotunnel.com\",\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    \"service-op-ip\",\n\t\t\tUsage:   \"Fallback IP for service operations run by the management service.\",\n\t\t\tEnvVars: []string{\"TUNNEL_SERVICE_OP_IP\"},\n\t\t\tHidden:  true,\n\t\t\tValue:   \"198.41.200.113:80\",\n\t\t}),\n\t}\n\treturn append(flags, sshFlags(shouldHide)...)\n}\n\nfunc legacyTunnelFlag(msg string) string {\n\treturn fmt.Sprintf(\n\t\t\"%s This flag only takes effect if you define your origin with `--url` and if you do not use ingress rules.\"+\n\t\t\t\" The recommended way is to rely on ingress rules and define this property under `originRequest` as per\"+\n\t\t\t\" https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/configuration/configuration-file/ingress\",\n\t\tmsg,\n\t)\n}\n\nfunc sshFlags(shouldHide bool) []cli.Flag {\n\treturn []cli.Flag{\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    cfdflags.SshPort,\n\t\t\tUsage:   \"Localhost port that cloudflared SSH server will run on\",\n\t\t\tValue:   \"2222\",\n\t\t\tEnvVars: []string{\"LOCAL_SSH_PORT\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewDurationFlag(&cli.DurationFlag{\n\t\t\tName:    cfdflags.SshIdleTimeout,\n\t\t\tUsage:   \"Connection timeout after no activity\",\n\t\t\tEnvVars: []string{\"SSH_IDLE_TIMEOUT\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewDurationFlag(&cli.DurationFlag{\n\t\t\tName:    cfdflags.SshMaxTimeout,\n\t\t\tUsage:   \"Absolute connection timeout\",\n\t\t\tEnvVars: []string{\"SSH_MAX_TIMEOUT\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    cfdflags.SshLogUploaderBucketName,\n\t\t\tUsage:   \"Bucket name of where to upload SSH logs\",\n\t\t\tEnvVars: []string{\"BUCKET_ID\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    cfdflags.SshLogUploaderRegionName,\n\t\t\tUsage:   \"Region name of where to upload SSH logs\",\n\t\t\tEnvVars: []string{\"REGION_ID\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    cfdflags.SshLogUploaderSecretID,\n\t\t\tUsage:   \"Secret ID of where to upload SSH logs\",\n\t\t\tEnvVars: []string{\"SECRET_ID\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    cfdflags.SshLogUploaderAccessKeyID,\n\t\t\tUsage:   \"Access Key ID of where to upload SSH logs\",\n\t\t\tEnvVars: []string{\"ACCESS_CLIENT_ID\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    cfdflags.SshLogUploaderSessionTokenID,\n\t\t\tUsage:   \"Session Token to use in the configuration of SSH logs uploading\",\n\t\t\tEnvVars: []string{\"SESSION_TOKEN_ID\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    cfdflags.SshLogUploaderS3URL,\n\t\t\tUsage:   \"S3 url of where to upload SSH logs\",\n\t\t\tEnvVars: []string{\"S3_URL\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewPathFlag(&cli.PathFlag{\n\t\t\tName:    cfdflags.HostKeyPath,\n\t\t\tUsage:   \"Absolute path of directory to save SSH host keys in\",\n\t\t\tEnvVars: []string{\"HOST_KEY_PATH\"},\n\t\t\tHidden:  true,\n\t\t}),\n\t\taltsrc.NewBoolFlag(&cli.BoolFlag{\n\t\t\tName:    ingress.SSHServerFlag,\n\t\t\tValue:   false,\n\t\t\tUsage:   \"Run an SSH Server\",\n\t\t\tEnvVars: []string{\"TUNNEL_SSH_SERVER\"},\n\t\t\tHidden:  true, // TODO: remove when feature is complete\n\t\t}),\n\t\taltsrc.NewBoolFlag(&cli.BoolFlag{\n\t\t\tName:    config.BastionFlag,\n\t\t\tValue:   false,\n\t\t\tUsage:   \"Runs as jump host\",\n\t\t\tEnvVars: []string{\"TUNNEL_BASTION\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\taltsrc.NewStringFlag(&cli.StringFlag{\n\t\t\tName:    ingress.ProxyAddressFlag,\n\t\t\tUsage:   \"Listen address for the proxy.\",\n\t\t\tValue:   \"127.0.0.1\",\n\t\t\tEnvVars: []string{\"TUNNEL_PROXY_ADDRESS\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t\t// Note TUN-3758 , we use Int because UInt is not supported with altsrc\n\t\taltsrc.NewIntFlag(&cli.IntFlag{\n\t\t\tName:    ingress.ProxyPortFlag,\n\t\t\tUsage:   \"Listen port for the proxy.\",\n\t\t\tValue:   0,\n\t\t\tEnvVars: []string{\"TUNNEL_PROXY_PORT\"},\n\t\t\tHidden:  shouldHide,\n\t\t}),\n\t}\n}\n\nfunc stdinControl(reconnectCh chan supervisor.ReconnectSignal, log *zerolog.Logger) {\n\tfor {\n\t\tscanner := bufio.NewScanner(os.Stdin)\n\t\tfor scanner.Scan() {\n\t\t\tcommand := scanner.Text()\n\t\t\tparts := strings.SplitN(command, \" \", 2)\n\n\t\t\tswitch parts[0] {\n\t\t\tcase \"\":\n\t\t\t\tbreak\n\t\t\tcase \"reconnect\":\n\t\t\t\tvar reconnect supervisor.ReconnectSignal\n\t\t\t\tif len(parts) > 1 {\n\t\t\t\t\tvar err error\n\t\t\t\t\tif reconnect.Delay, err = time.ParseDuration(parts[1]); err != nil {\n\t\t\t\t\t\tlog.Error().Msg(err.Error())\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlog.Info().Msgf(\"Sending %+v\", reconnect)\n\t\t\t\treconnectCh <- reconnect\n\t\t\tdefault:\n\t\t\t\tlog.Info().Str(LogFieldCommand, command).Msg(\"Unknown command\")\n\t\t\t\tfallthrough\n\t\t\tcase \"help\":\n\t\t\t\tlog.Info().Msg(`Supported command:\nreconnect [delay]\n- restarts one randomly chosen connection with optional delay before reconnect`)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc nonSecretCliFlags(log *zerolog.Logger, cli *cli.Context, flagInclusionList []string) map[string]string {\n\tflagsNames := cli.FlagNames()\n\tflags := make(map[string]string, len(flagsNames))\n\n\tfor _, flag := range flagsNames {\n\t\tvalue := cli.String(flag)\n\n\t\tif value == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tisIncluded := isFlagIncluded(flagInclusionList, flag)\n\t\tif !isIncluded {\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch flag {\n\t\tcase cfdflags.LogDirectory, cfdflags.LogFile:\n\t\t\t{\n\t\t\t\tabsolute, err := filepath.Abs(value)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Error().Err(err).Msgf(\"could not convert %s path to absolute\", flag)\n\t\t\t\t} else {\n\t\t\t\t\tflags[flag] = absolute\n\t\t\t\t}\n\t\t\t}\n\t\tdefault:\n\t\t\tflags[flag] = value\n\t\t}\n\t}\n\treturn flags\n}\n\nfunc isFlagIncluded(flagInclusionList []string, flag string) bool {\n\tfor _, include := range flagInclusionList {\n\t\tif include == flag {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/cmd_test.go",
    "content": "package tunnel\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestHostnameFromURI(t *testing.T) {\n\tassert.Equal(t, \"awesome.warptunnels.horse:22\", hostnameFromURI(\"ssh://awesome.warptunnels.horse:22\"))\n\tassert.Equal(t, \"awesome.warptunnels.horse:22\", hostnameFromURI(\"ssh://awesome.warptunnels.horse\"))\n\tassert.Equal(t, \"awesome.warptunnels.horse:2222\", hostnameFromURI(\"ssh://awesome.warptunnels.horse:2222\"))\n\tassert.Equal(t, \"localhost:3389\", hostnameFromURI(\"rdp://localhost\"))\n\tassert.Equal(t, \"localhost:3390\", hostnameFromURI(\"rdp://localhost:3390\"))\n\tassert.Equal(t, \"\", hostnameFromURI(\"trash\"))\n\tassert.Equal(t, \"\", hostnameFromURI(\"https://awesomesauce.com\"))\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/configuration.go",
    "content": "package tunnel\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/netip\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/urfave/cli/v2\"\n\t\"github.com/urfave/cli/v2/altsrc\"\n\t\"golang.org/x/term\"\n\n\t\"github.com/cloudflare/cloudflared/client\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/connection\"\n\t\"github.com/cloudflare/cloudflared/edgediscovery\"\n\t\"github.com/cloudflare/cloudflared/edgediscovery/allregions\"\n\t\"github.com/cloudflare/cloudflared/features\"\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\t\"github.com/cloudflare/cloudflared/ingress/origins\"\n\t\"github.com/cloudflare/cloudflared/orchestration\"\n\t\"github.com/cloudflare/cloudflared/supervisor\"\n\t\"github.com/cloudflare/cloudflared/tlsconfig\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\nconst (\n\tsecretValue       = \"*****\"\n\ticmpFunnelTimeout = time.Second * 10\n)\n\nvar (\n\tsecretFlags = [2]*altsrc.StringFlag{credentialsContentsFlag, tunnelTokenFlag}\n\n\tconfigFlags = []string{\n\t\tflags.AutoUpdateFreq,\n\t\tflags.NoAutoUpdate,\n\t\tflags.Retries,\n\t\tflags.Protocol,\n\t\tflags.LogLevel,\n\t\tflags.TransportLogLevel,\n\t\tflags.OriginCert,\n\t\tflags.Metrics,\n\t\tflags.MetricsUpdateFreq,\n\t\tflags.EdgeIpVersion,\n\t\tflags.EdgeBindAddress,\n\t\tflags.MaxActiveFlows,\n\t}\n)\n\nfunc logClientOptions(c *cli.Context, log *zerolog.Logger) {\n\tflags := make(map[string]interface{})\n\tfor _, flag := range c.FlagNames() {\n\t\tif isSecretFlag(flag) {\n\t\t\tflags[flag] = secretValue\n\t\t} else {\n\t\t\tflags[flag] = c.Generic(flag)\n\t\t}\n\t}\n\n\tif len(flags) > 0 {\n\t\tlog.Info().Msgf(\"Settings: %v\", flags)\n\t}\n\n\tenvs := make(map[string]string)\n\t// Find env variables for Argo Tunnel\n\tfor _, env := range os.Environ() {\n\t\t// All Argo Tunnel env variables start with TUNNEL_\n\t\tif strings.Contains(env, \"TUNNEL_\") {\n\t\t\tvars := strings.Split(env, \"=\")\n\t\t\tif len(vars) == 2 {\n\t\t\t\tif isSecretEnvVar(vars[0]) {\n\t\t\t\t\tenvs[vars[0]] = secretValue\n\t\t\t\t} else {\n\t\t\t\t\tenvs[vars[0]] = vars[1]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif len(envs) > 0 {\n\t\tlog.Info().Msgf(\"Environmental variables %v\", envs)\n\t}\n}\n\nfunc isSecretFlag(key string) bool {\n\tfor _, flag := range secretFlags {\n\t\tif flag.Name == key {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc isSecretEnvVar(key string) bool {\n\tfor _, flag := range secretFlags {\n\t\tfor _, secretEnvVar := range flag.EnvVars {\n\t\t\tif secretEnvVar == key {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc prepareTunnelConfig(\n\tctx context.Context,\n\tc *cli.Context,\n\tinfo *cliutil.BuildInfo,\n\tlog, logTransport *zerolog.Logger,\n\tobserver *connection.Observer,\n\tnamedTunnel *connection.TunnelProperties,\n) (*supervisor.TunnelConfig, *orchestration.Config, error) {\n\ttransportProtocol := c.String(flags.Protocol)\n\tisPostQuantumEnforced := c.Bool(flags.PostQuantum)\n\tfeatureSelector, err := features.NewFeatureSelector(ctx, namedTunnel.Credentials.AccountTag, c.StringSlice(flags.Features), isPostQuantumEnforced, log)\n\tif err != nil {\n\t\treturn nil, nil, errors.Wrap(err, \"Failed to create feature selector\")\n\t}\n\n\tclientConfig, err := client.NewConfig(info.Version(), info.OSArch(), featureSelector)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tlog.Info().Msgf(\"Generated Connector ID: %s\", clientConfig.ConnectorID)\n\n\ttags, err := NewTagSliceFromCLI(c.StringSlice(flags.Tag))\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"Tag parse failure\")\n\t\treturn nil, nil, errors.Wrap(err, \"Tag parse failure\")\n\t}\n\ttags = append(tags, pogs.Tag{Name: \"ID\", Value: clientConfig.ConnectorID.String()})\n\n\tclientFeatures := featureSelector.Snapshot()\n\tpqMode := clientFeatures.PostQuantum\n\tif pqMode == features.PostQuantumStrict {\n\t\t// Error if the user tries to force a non-quic transport protocol\n\t\tif transportProtocol != connection.AutoSelectFlag && transportProtocol != connection.QUIC.String() {\n\t\t\treturn nil, nil, fmt.Errorf(\"post-quantum is only supported with the quic transport\")\n\t\t}\n\t\ttransportProtocol = connection.QUIC.String()\n\t}\n\n\tcfg := config.GetConfiguration()\n\tingressRules, err := ingress.ParseIngressFromConfigAndCLI(cfg, c, log)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tprotocolSelector, err := connection.NewProtocolSelector(transportProtocol, namedTunnel.Credentials.AccountTag, c.IsSet(TunnelTokenFlag), isPostQuantumEnforced, edgediscovery.ProtocolPercentage, connection.ResolveTTL, log)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tlog.Info().Msgf(\"Initial protocol %s\", protocolSelector.Current())\n\n\tedgeTLSConfigs := make(map[connection.Protocol]*tls.Config, len(connection.ProtocolList))\n\tfor _, p := range connection.ProtocolList {\n\t\ttlsSettings := p.TLSSettings()\n\t\tif tlsSettings == nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"%s has unknown TLS settings\", p)\n\t\t}\n\t\tedgeTLSConfig, err := tlsconfig.CreateTunnelConfig(c, tlsSettings.ServerName)\n\t\tif err != nil {\n\t\t\treturn nil, nil, errors.Wrap(err, \"unable to create TLS config to connect with edge\")\n\t\t}\n\t\tif len(tlsSettings.NextProtos) > 0 {\n\t\t\tedgeTLSConfig.NextProtos = tlsSettings.NextProtos\n\t\t}\n\t\tedgeTLSConfigs[p] = edgeTLSConfig\n\t}\n\n\tgracePeriod, err := gracePeriod(c)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tedgeIPVersion, err := parseConfigIPVersion(c.String(flags.EdgeIpVersion))\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tedgeBindAddr, err := parseConfigBindAddress(c.String(flags.EdgeBindAddress))\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tif err := testIPBindable(edgeBindAddr); err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"invalid edge-bind-address %s: %v\", edgeBindAddr, err)\n\t}\n\tedgeIPVersion, err = adjustIPVersionByBindAddress(edgeIPVersion, edgeBindAddr)\n\tif err != nil {\n\t\t// This is not a fatal error, we just overrode edgeIPVersion\n\t\tlog.Warn().Str(\"edgeIPVersion\", edgeIPVersion.String()).Err(err).Msg(\"Overriding edge-ip-version\")\n\t}\n\n\tregion := c.String(flags.Region)\n\tendpoint := namedTunnel.Credentials.Endpoint\n\tvar resolvedRegion string\n\t// set resolvedRegion to either the region passed as argument\n\t// or to the endpoint in the credentials.\n\t// Region and endpoint are interchangeable\n\tif region != \"\" && endpoint != \"\" {\n\t\treturn nil, nil, fmt.Errorf(\"region provided with a token that has an endpoint\")\n\t} else if region != \"\" {\n\t\tresolvedRegion = region\n\t} else if endpoint != \"\" {\n\t\tresolvedRegion = endpoint\n\t}\n\n\twarpRoutingConfig := ingress.NewWarpRoutingConfig(&cfg.WarpRouting)\n\n\t// Setup origin dialer service and virtual services\n\toriginDialerService := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   ingress.NewDialer(warpRoutingConfig),\n\t\tTCPWriteTimeout: c.Duration(flags.WriteStreamTimeout),\n\t}, log)\n\n\t// Setup DNS Resolver Service\n\toriginMetrics := origins.NewMetrics(prometheus.DefaultRegisterer)\n\tdnsResolverAddrs := c.StringSlice(flags.VirtualDNSServiceResolverAddresses)\n\tdnsService := origins.NewDNSResolverService(origins.NewDNSDialer(), log, originMetrics)\n\tif len(dnsResolverAddrs) > 0 {\n\t\taddrs, err := parseResolverAddrPorts(dnsResolverAddrs)\n\t\tif err != nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"invalid %s provided: %w\", flags.VirtualDNSServiceResolverAddresses, err)\n\t\t}\n\t\tdnsService = origins.NewStaticDNSResolverService(addrs, origins.NewDNSDialer(), log, originMetrics)\n\t}\n\toriginDialerService.AddReservedService(dnsService, []netip.AddrPort{origins.VirtualDNSServiceAddr})\n\n\ttunnelConfig := &supervisor.TunnelConfig{\n\t\tClientConfig:    clientConfig,\n\t\tGracePeriod:     gracePeriod,\n\t\tEdgeAddrs:       c.StringSlice(flags.Edge),\n\t\tRegion:          resolvedRegion,\n\t\tEdgeIPVersion:   edgeIPVersion,\n\t\tEdgeBindAddr:    edgeBindAddr,\n\t\tHAConnections:   c.Int(flags.HaConnections),\n\t\tIsAutoupdated:   c.Bool(flags.IsAutoUpdated),\n\t\tLBPool:          c.String(flags.LBPool),\n\t\tTags:            tags,\n\t\tLog:             log,\n\t\tLogTransport:    logTransport,\n\t\tObserver:        observer,\n\t\tReportedVersion: info.Version(),\n\t\t// Note TUN-3758 , we use Int because UInt is not supported with altsrc\n\t\tRetries:                             uint(c.Int(flags.Retries)), // nolint: gosec\n\t\tRunFromTerminal:                     isRunningFromTerminal(),\n\t\tNamedTunnel:                         namedTunnel,\n\t\tProtocolSelector:                    protocolSelector,\n\t\tEdgeTLSConfigs:                      edgeTLSConfigs,\n\t\tMaxEdgeAddrRetries:                  uint8(c.Int(flags.MaxEdgeAddrRetries)), // nolint: gosec\n\t\tRPCTimeout:                          c.Duration(flags.RpcTimeout),\n\t\tWriteStreamTimeout:                  c.Duration(flags.WriteStreamTimeout),\n\t\tDisableQUICPathMTUDiscovery:         c.Bool(flags.QuicDisablePathMTUDiscovery),\n\t\tQUICConnectionLevelFlowControlLimit: c.Uint64(flags.QuicConnLevelFlowControlLimit),\n\t\tQUICStreamLevelFlowControlLimit:     c.Uint64(flags.QuicStreamLevelFlowControlLimit),\n\t\tOriginDNSService:                    dnsService,\n\t\tOriginDialerService:                 originDialerService,\n\t}\n\ticmpRouter, err := newICMPRouter(c, log)\n\tif err != nil {\n\t\tlog.Warn().Err(err).Msg(\"ICMP proxy feature is disabled\")\n\t} else {\n\t\ttunnelConfig.ICMPRouterServer = icmpRouter\n\t}\n\torchestratorConfig := &orchestration.Config{\n\t\tIngress:             &ingressRules,\n\t\tWarpRouting:         warpRoutingConfig,\n\t\tOriginDialerService: originDialerService,\n\t\tConfigurationFlags:  parseConfigFlags(c),\n\t}\n\treturn tunnelConfig, orchestratorConfig, nil\n}\n\nfunc parseConfigFlags(c *cli.Context) map[string]string {\n\tresult := make(map[string]string)\n\n\tfor _, flag := range configFlags {\n\t\tif v := c.String(flag); c.IsSet(flag) && v != \"\" {\n\t\t\tresult[flag] = v\n\t\t}\n\t}\n\n\treturn result\n}\n\nfunc gracePeriod(c *cli.Context) (time.Duration, error) {\n\tperiod := c.Duration(flags.GracePeriod)\n\tif period > connection.MaxGracePeriod {\n\t\treturn time.Duration(0), fmt.Errorf(\"%s must be equal or less than %v\", flags.GracePeriod, connection.MaxGracePeriod)\n\t}\n\treturn period, nil\n}\n\nfunc isRunningFromTerminal() bool {\n\treturn term.IsTerminal(int(os.Stdout.Fd()))\n}\n\n// ParseConfigIPVersion returns the IP version from possible expected values from config\nfunc parseConfigIPVersion(version string) (v allregions.ConfigIPVersion, err error) {\n\tswitch version {\n\tcase \"4\":\n\t\tv = allregions.IPv4Only\n\tcase \"6\":\n\t\tv = allregions.IPv6Only\n\tcase \"auto\":\n\t\tv = allregions.Auto\n\tdefault: // unspecified or invalid\n\t\terr = fmt.Errorf(\"invalid value for edge-ip-version: %s\", version)\n\t}\n\treturn\n}\n\nfunc parseConfigBindAddress(ipstr string) (net.IP, error) {\n\t// Unspecified - it's fine\n\tif ipstr == \"\" {\n\t\treturn nil, nil\n\t}\n\tip := net.ParseIP(ipstr)\n\tif ip == nil {\n\t\treturn nil, fmt.Errorf(\"invalid value for edge-bind-address: %s\", ipstr)\n\t}\n\treturn ip, nil\n}\n\nfunc testIPBindable(ip net.IP) error {\n\t// \"Unspecified\" = let OS choose, so always bindable\n\tif ip == nil {\n\t\treturn nil\n\t}\n\n\taddr := &net.UDPAddr{IP: ip, Port: 0}\n\tlistener, err := net.ListenUDP(\"udp\", addr)\n\tif err != nil {\n\t\treturn err\n\t}\n\tlistener.Close()\n\treturn nil\n}\n\nfunc adjustIPVersionByBindAddress(ipVersion allregions.ConfigIPVersion, ip net.IP) (allregions.ConfigIPVersion, error) {\n\tif ip == nil {\n\t\treturn ipVersion, nil\n\t}\n\t// https://pkg.go.dev/net#IP.To4: \"If ip is not an IPv4 address, To4 returns nil.\"\n\tif ip.To4() != nil {\n\t\tif ipVersion == allregions.IPv6Only {\n\t\t\treturn allregions.IPv4Only, fmt.Errorf(\"IPv4 bind address is specified, but edge-ip-version is IPv6\")\n\t\t}\n\t\treturn allregions.IPv4Only, nil\n\t} else {\n\t\tif ipVersion == allregions.IPv4Only {\n\t\t\treturn allregions.IPv6Only, fmt.Errorf(\"IPv6 bind address is specified, but edge-ip-version is IPv4\")\n\t\t}\n\t\treturn allregions.IPv6Only, nil\n\t}\n}\n\nfunc newICMPRouter(c *cli.Context, logger *zerolog.Logger) (ingress.ICMPRouterServer, error) {\n\tipv4Src, ipv6Src, err := determineICMPSources(c, logger)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ticmpRouter, err := ingress.NewICMPRouter(ipv4Src, ipv6Src, logger, icmpFunnelTimeout)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn icmpRouter, nil\n}\n\nfunc determineICMPSources(c *cli.Context, logger *zerolog.Logger) (netip.Addr, netip.Addr, error) {\n\tipv4Src, err := determineICMPv4Src(c.String(flags.ICMPV4Src), logger)\n\tif err != nil {\n\t\treturn netip.Addr{}, netip.Addr{}, errors.Wrap(err, \"failed to determine IPv4 source address for ICMP proxy\")\n\t}\n\n\tlogger.Info().Msgf(\"ICMP proxy will use %s as source for IPv4\", ipv4Src)\n\n\tipv6Src, zone, err := determineICMPv6Src(c.String(flags.ICMPV6Src), logger, ipv4Src)\n\tif err != nil {\n\t\treturn netip.Addr{}, netip.Addr{}, errors.Wrap(err, \"failed to determine IPv6 source address for ICMP proxy\")\n\t}\n\n\tif zone != \"\" {\n\t\tlogger.Info().Msgf(\"ICMP proxy will use %s in zone %s as source for IPv6\", ipv6Src, zone)\n\t} else {\n\t\tlogger.Info().Msgf(\"ICMP proxy will use %s as source for IPv6\", ipv6Src)\n\t}\n\n\treturn ipv4Src, ipv6Src, nil\n}\n\nfunc determineICMPv4Src(userDefinedSrc string, logger *zerolog.Logger) (netip.Addr, error) {\n\tif userDefinedSrc != \"\" {\n\t\taddr, err := netip.ParseAddr(userDefinedSrc)\n\t\tif err != nil {\n\t\t\treturn netip.Addr{}, err\n\t\t}\n\t\tif addr.Is4() {\n\t\t\treturn addr, nil\n\t\t}\n\t\treturn netip.Addr{}, fmt.Errorf(\"expect IPv4, but %s is IPv6\", userDefinedSrc)\n\t}\n\n\taddr, err := findLocalAddr(net.ParseIP(\"192.168.0.1\"), 53)\n\tif err != nil {\n\t\taddr = netip.IPv4Unspecified()\n\t\tlogger.Debug().Err(err).Msgf(\"Failed to determine the IPv4 for this machine. It will use %s to send/listen for ICMPv4 echo\", addr)\n\t}\n\treturn addr, nil\n}\n\ntype interfaceIP struct {\n\tname string\n\tip   net.IP\n}\n\nfunc determineICMPv6Src(userDefinedSrc string, logger *zerolog.Logger, ipv4Src netip.Addr) (addr netip.Addr, zone string, err error) {\n\tif userDefinedSrc != \"\" {\n\t\taddr, err := netip.ParseAddr(userDefinedSrc)\n\t\tif err != nil {\n\t\t\treturn netip.Addr{}, \"\", err\n\t\t}\n\t\tif addr.Is6() {\n\t\t\treturn addr, addr.Zone(), nil\n\t\t}\n\t\treturn netip.Addr{}, \"\", fmt.Errorf(\"expect IPv6, but %s is IPv4\", userDefinedSrc)\n\t}\n\n\t// Loop through all the interfaces, the preference is\n\t// 1. The interface where ipv4Src is in\n\t// 2. Interface with IPv6 address\n\t// 3. Unspecified interface\n\n\tinterfaces, err := net.Interfaces()\n\tif err != nil {\n\t\treturn netip.IPv6Unspecified(), \"\", nil\n\t}\n\n\tinterfacesWithIPv6 := make([]interfaceIP, 0)\n\tfor _, interf := range interfaces {\n\t\tinterfaceAddrs, err := interf.Addrs()\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tfoundIPv4SrcInterface := false\n\t\tfor _, interfaceAddr := range interfaceAddrs {\n\t\t\tif ipnet, ok := interfaceAddr.(*net.IPNet); ok {\n\t\t\t\tip := ipnet.IP\n\t\t\t\tif ip.Equal(ipv4Src.AsSlice()) {\n\t\t\t\t\tfoundIPv4SrcInterface = true\n\t\t\t\t}\n\t\t\t\tif ip.To4() == nil {\n\t\t\t\t\tinterfacesWithIPv6 = append(interfacesWithIPv6, interfaceIP{\n\t\t\t\t\t\tname: interf.Name,\n\t\t\t\t\t\tip:   ip,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Found the interface of ipv4Src. Loop through the addresses to see if there is an IPv6\n\t\tif foundIPv4SrcInterface {\n\t\t\tfor _, interfaceAddr := range interfaceAddrs {\n\t\t\t\tif ipnet, ok := interfaceAddr.(*net.IPNet); ok {\n\t\t\t\t\tip := ipnet.IP\n\t\t\t\t\tif ip.To4() == nil {\n\t\t\t\t\t\taddr, err := netip.ParseAddr(ip.String())\n\t\t\t\t\t\tif err == nil {\n\t\t\t\t\t\t\treturn addr, interf.Name, nil\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 _, interf := range interfacesWithIPv6 {\n\t\taddr, err := netip.ParseAddr(interf.ip.String())\n\t\tif err == nil {\n\t\t\treturn addr, interf.name, nil\n\t\t}\n\t}\n\tlogger.Debug().Err(err).Msgf(\"Failed to determine the IPv6 for this machine. It will use %s to send/listen for ICMPv6 echo\", netip.IPv6Unspecified())\n\n\treturn netip.IPv6Unspecified(), \"\", nil\n}\n\n// FindLocalAddr tries to dial UDP and returns the local address picked by the OS\nfunc findLocalAddr(dst net.IP, port int) (netip.Addr, error) {\n\tudpConn, err := net.DialUDP(\"udp\", nil, &net.UDPAddr{\n\t\tIP:   dst,\n\t\tPort: port,\n\t})\n\tif err != nil {\n\t\treturn netip.Addr{}, err\n\t}\n\tdefer udpConn.Close()\n\tlocalAddrPort, err := netip.ParseAddrPort(udpConn.LocalAddr().String())\n\tif err != nil {\n\t\treturn netip.Addr{}, err\n\t}\n\tlocalAddr := localAddrPort.Addr()\n\treturn localAddr, nil\n}\n\nfunc parseResolverAddrPorts(input []string) ([]netip.AddrPort, error) {\n\t// We don't allow more than 10 resolvers to be provided statically for the resolver service.\n\tif len(input) > 10 {\n\t\treturn nil, errors.New(\"too many addresses provided, max: 10\")\n\t}\n\taddrs := make([]netip.AddrPort, 0, len(input))\n\tfor _, val := range input {\n\t\taddr, err := netip.ParseAddrPort(val)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\taddrs = append(addrs, addr)\n\t}\n\treturn addrs, nil\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/configuration_test.go",
    "content": "//go:build ignore\n\n// TODO: Remove the above build tag and include this test when we start compiling with Golang 1.10.0+\n\npackage tunnel\n\nimport (\n\t\"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"encoding/asn1\"\n\t\"net\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\n// Generated using `openssl req -newkey rsa:512 -nodes -x509 -days 3650`\nvar samplePEM = []byte(`\n-----BEGIN CERTIFICATE-----\nMIIB4DCCAYoCCQCb/H0EUrdXEjANBgkqhkiG9w0BAQsFADB3MQswCQYDVQQGEwJV\nUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkF1c3RpbjEZMBcGA1UECgwQQ2xv\ndWRmbGFyZSwgSW5jLjEZMBcGA1UECwwQUHJvZHVjdCBTdHJhdGVneTERMA8GA1UE\nAwwIVGVzdCBPbmUwHhcNMTgwNDI2MTYxMDUxWhcNMjgwNDIzMTYxMDUxWjB3MQsw\nCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkF1c3RpbjEZMBcG\nA1UECgwQQ2xvdWRmbGFyZSwgSW5jLjEZMBcGA1UECwwQUHJvZHVjdCBTdHJhdGVn\neTERMA8GA1UEAwwIVGVzdCBPbmUwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAwVQD\nK0SJ25UFLznm2pU3zhzMEvpDEofHVNnCjk4mlDrtVop7PkKZ8pDEmuQANltUrxC8\nyHBE2wXMv+GlH+bDtwIDAQABMA0GCSqGSIb3DQEBCwUAA0EAjVYQzozIFPkt/HRY\nuUoZ8zEHIDICb0syFf5VAjm9AgTwIPzUmD+c5vl6LWDnxq7L45nLCzhhQ6YmiwDz\nX7Wcyg==\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIB4DCCAYoCCQDZfCdAJ+mwzDANBgkqhkiG9w0BAQsFADB3MQswCQYDVQQGEwJV\nUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkF1c3RpbjEZMBcGA1UECgwQQ2xv\ndWRmbGFyZSwgSW5jLjEZMBcGA1UECwwQUHJvZHVjdCBTdHJhdGVneTERMA8GA1UE\nAwwIVGVzdCBUd28wHhcNMTgwNDI2MTYxMTIwWhcNMjgwNDIzMTYxMTIwWjB3MQsw\nCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkF1c3RpbjEZMBcG\nA1UECgwQQ2xvdWRmbGFyZSwgSW5jLjEZMBcGA1UECwwQUHJvZHVjdCBTdHJhdGVn\neTERMA8GA1UEAwwIVGVzdCBUd28wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAoHKp\nROVK3zCSsH7ocYeyRAML4V7SFAbZcb4WIwDnE08oMBVRkQVcW5tqEkvG3RiClfzV\nwZIJ3CfqKIeSNSDU9wIDAQABMA0GCSqGSIb3DQEBCwUAA0EAJw2gUbnPiq4C2p5b\niWzlA9Q7aKo+VQ4H7IZS7tTccr59nVjvH/TG3eWujpnocr4TOqW9M3CK1DF9mUGP\n3pQ3Jg==\n-----END CERTIFICATE-----\n`)\n\nvar systemCertPoolSubjects []*pkix.Name\n\ntype certificateFixture struct {\n\tou string\n\tcn string\n}\n\nfunc TestMain(m *testing.M) {\n\tsystemCertPool, err := x509.SystemCertPool()\n\tif isUnrecoverableError(err) {\n\t\tos.Exit(1)\n\t}\n\n\tif systemCertPool == nil {\n\t\t// On Windows, let's just assume the system cert pool was empty\n\t\tsystemCertPool = x509.NewCertPool()\n\t}\n\n\tsystemCertPoolSubjects, err = getCertPoolSubjects(systemCertPool)\n\tif err != nil {\n\t\tos.Exit(1)\n\t}\n\n\tos.Exit(m.Run())\n}\n\nfunc TestLoadOriginCertPoolJustSystemPool(t *testing.T) {\n\tcertPoolSubjects := loadCertPoolSubjects(t, nil)\n\textraSubjects := subjectSubtract(systemCertPoolSubjects, certPoolSubjects)\n\n\t// Remove extra subjects from the cert pool\n\tvar filteredSystemCertPoolSubjects []*pkix.Name\n\n\tt.Log(extraSubjects)\n\nOUTER:\n\tfor _, subject := range certPoolSubjects {\n\t\tfor _, extraSubject := range extraSubjects {\n\t\t\tif subject == extraSubject {\n\t\t\t\tt.Log(extraSubject)\n\t\t\t\tcontinue OUTER\n\t\t\t}\n\t\t}\n\n\t\tfilteredSystemCertPoolSubjects = append(filteredSystemCertPoolSubjects, subject)\n\t}\n\n\tassert.Equal(t, len(filteredSystemCertPoolSubjects), len(systemCertPoolSubjects))\n\n\tdifference := subjectSubtract(systemCertPoolSubjects, filteredSystemCertPoolSubjects)\n\tassert.Equal(t, 0, len(difference))\n}\n\nfunc TestLoadOriginCertPoolCFCertificates(t *testing.T) {\n\tcertPoolSubjects := loadCertPoolSubjects(t, nil)\n\n\textraSubjects := subjectSubtract(systemCertPoolSubjects, certPoolSubjects)\n\n\texpected := []*certificateFixture{\n\t\t{ou: \"CloudFlare Origin SSL ECC Certificate Authority\"},\n\t\t{ou: \"CloudFlare Origin SSL Certificate Authority\"},\n\t\t{cn: \"origin-pull.cloudflare.net\"},\n\t\t{cn: \"Argo Tunnel Sample Hello Server Certificate\"},\n\t}\n\n\tassertFixturesMatchSubjects(t, expected, extraSubjects)\n}\n\nfunc TestLoadOriginCertPoolWithExtraPEMs(t *testing.T) {\n\tcertPoolWithoutPEMSubjects := loadCertPoolSubjects(t, nil)\n\tcertPoolWithPEMSubjects := loadCertPoolSubjects(t, samplePEM)\n\n\tdifference := subjectSubtract(certPoolWithoutPEMSubjects, certPoolWithPEMSubjects)\n\n\tassert.Equal(t, 2, len(difference))\n\n\texpected := []*certificateFixture{\n\t\t{cn: \"Test One\"},\n\t\t{cn: \"Test Two\"},\n\t}\n\n\tassertFixturesMatchSubjects(t, expected, difference)\n}\n\nfunc loadCertPoolSubjects(t *testing.T, originCAPoolPEM []byte) []*pkix.Name {\n\tcertPool, err := loadOriginCertPool(originCAPoolPEM)\n\tif isUnrecoverableError(err) {\n\t\tt.Fatal(err)\n\t}\n\tassert.NotEmpty(t, certPool.Subjects())\n\tcertPoolSubjects, err := getCertPoolSubjects(certPool)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\treturn certPoolSubjects\n}\n\nfunc assertFixturesMatchSubjects(t *testing.T, fixtures []*certificateFixture, subjects []*pkix.Name) {\n\tassert.Equal(t, len(fixtures), len(subjects))\n\n\tfor _, fixture := range fixtures {\n\t\tfound := false\n\t\tfor _, subject := range subjects {\n\t\t\tfound = found || fixtureMatchesSubjectPredicate(fixture, subject)\n\t\t}\n\n\t\tif !found {\n\t\t\tt.Fail()\n\t\t}\n\t}\n}\n\nfunc fixtureMatchesSubjectPredicate(fixture *certificateFixture, subject *pkix.Name) bool {\n\tcnMatch := true\n\tif fixture.cn != \"\" {\n\t\tcnMatch = fixture.cn == subject.CommonName\n\t}\n\n\touMatch := true\n\tif fixture.ou != \"\" {\n\t\touMatch = len(subject.OrganizationalUnit) > 0 && fixture.ou == subject.OrganizationalUnit[0]\n\t}\n\n\treturn cnMatch && ouMatch\n}\n\nfunc subjectSubtract(left []*pkix.Name, right []*pkix.Name) []*pkix.Name {\n\tvar difference []*pkix.Name\n\n\tvar found bool\n\tfor _, r := range right {\n\t\tfound = false\n\t\tfor _, l := range left {\n\t\t\tif (*l).String() == (*r).String() {\n\t\t\t\tfound = true\n\t\t\t}\n\t\t}\n\n\t\tif !found {\n\t\t\tdifference = append(difference, r)\n\t\t}\n\t}\n\n\treturn difference\n}\n\nfunc getCertPoolSubjects(certPool *x509.CertPool) ([]*pkix.Name, error) {\n\tvar subjects []*pkix.Name\n\n\tfor _, subject := range certPool.Subjects() {\n\t\tvar sequence pkix.RDNSequence\n\t\t_, err := asn1.Unmarshal(subject, &sequence)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tname := pkix.Name{}\n\t\tname.FillFromRDNSequence(&sequence)\n\n\t\tsubjects = append(subjects, &name)\n\t}\n\n\treturn subjects, nil\n}\n\nfunc isUnrecoverableError(err error) bool {\n\treturn err != nil && err.Error() != \"crypto/x509: system root pool is not available on Windows\"\n}\n\nfunc TestTestIPBindable(t *testing.T) {\n\tassert.Nil(t, testIPBindable(nil))\n\n\t// Public services - if one of these IPs is on the machine, the test environment is too weird\n\tassert.NotNil(t, testIPBindable(net.ParseIP(\"8.8.8.8\")))\n\tassert.NotNil(t, testIPBindable(net.ParseIP(\"1.1.1.1\")))\n\n\taddrs, err := net.InterfaceAddrs()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tfor i, addr := range addrs {\n\t\tif i >= 3 {\n\t\t\tbreak\n\t\t}\n\t\tip := addr.(*net.IPNet).IP\n\t\tassert.Nil(t, testIPBindable(ip))\n\t}\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/credential_finder.go",
    "content": "package tunnel\n\nimport (\n\t\"fmt\"\n\t\"path/filepath\"\n\n\tcfdflags \"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/credentials\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/urfave/cli/v2\"\n)\n\n// CredFinder can find the tunnel credentials file.\ntype CredFinder interface {\n\tPath() (string, error)\n}\n\n// Implements CredFinder and looks for the credentials file at the given\n// filepath.\ntype staticPath struct {\n\tfilePath string\n\tfs       fileSystem\n}\n\nfunc newStaticPath(filePath string, fs fileSystem) CredFinder {\n\treturn staticPath{\n\t\tfilePath: filePath,\n\t\tfs:       fs,\n\t}\n}\n\nfunc (a staticPath) Path() (string, error) {\n\tif a.filePath != \"\" && a.fs.validFilePath(a.filePath) {\n\t\treturn a.filePath, nil\n\t}\n\treturn \"\", fmt.Errorf(\"Tunnel credentials file '%s' doesn't exist or is not a file\", a.filePath)\n}\n\n// Implements CredFinder and looks for the credentials file in several directories\n// searching for a file named <id>.json\ntype searchByID struct {\n\tid  uuid.UUID\n\tc   *cli.Context\n\tlog *zerolog.Logger\n\tfs  fileSystem\n}\n\nfunc newSearchByID(id uuid.UUID, c *cli.Context, log *zerolog.Logger, fs fileSystem) CredFinder {\n\treturn searchByID{\n\t\tid:  id,\n\t\tc:   c,\n\t\tlog: log,\n\t\tfs:  fs,\n\t}\n}\n\nfunc (s searchByID) Path() (string, error) {\n\toriginCertPath := s.c.String(cfdflags.OriginCert)\n\toriginCertLog := s.log.With().\n\t\tStr(\"originCertPath\", originCertPath).\n\t\tLogger()\n\n\tif originCertPath != \"\" {\n\t\t// Look for tunnel credentials in the origin cert directory if the flag is provided\n\t\tif originCertPath, err := credentials.FindOriginCert(originCertPath, &originCertLog); err == nil {\n\t\t\toriginCertDir := filepath.Dir(originCertPath)\n\t\t\tif filePath, err := tunnelFilePath(s.id, originCertDir); err == nil {\n\t\t\t\tif s.fs.validFilePath(filePath) {\n\t\t\t\t\treturn filePath, nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Last resort look under default config directories\n\tfor _, configDir := range config.DefaultConfigSearchDirectories() {\n\t\tif filePath, err := tunnelFilePath(s.id, configDir); err == nil {\n\t\t\tif s.fs.validFilePath(filePath) {\n\t\t\t\treturn filePath, nil\n\t\t\t}\n\t\t}\n\t}\n\treturn \"\", fmt.Errorf(\"tunnel credentials file not found\")\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/filesystem.go",
    "content": "package tunnel\n\nimport (\n\t\"os\"\n)\n\n// Abstract away details of reading files, so that SubcommandContext can read\n// from either the real filesystem, or a mock (when running unit tests).\ntype fileSystem interface {\n\treadFile(filePath string) ([]byte, error)\n\tvalidFilePath(path string) bool\n}\n\ntype realFileSystem struct{}\n\nfunc (fs realFileSystem) validFilePath(path string) bool {\n\tfileStat, err := os.Stat(path)\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn !fileStat.IsDir()\n}\n\nfunc (fs realFileSystem) readFile(filePath string) ([]byte, error) {\n\treturn os.ReadFile(filePath)\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/info.go",
    "content": "package tunnel\n\nimport (\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\n\t\"github.com/cloudflare/cloudflared/cfapi\"\n)\n\ntype Info struct {\n\tID         uuid.UUID             `json:\"id\"`\n\tName       string                `json:\"name\"`\n\tCreatedAt  time.Time             `json:\"createdAt\"`\n\tConnectors []*cfapi.ActiveClient `json:\"conns\"`\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/ingress_subcommands.go",
    "content": "package tunnel\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/url\"\n\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/urfave/cli/v2\"\n)\n\nconst ingressDataJSONFlagName = \"json\"\n\nvar ingressDataJSON = &cli.StringFlag{\n\tName:    ingressDataJSONFlagName,\n\tAliases: []string{\"j\"},\n\tUsage:   `Accepts data in the form of json as an input rather than read from a file`,\n\tEnvVars: []string{\"TUNNEL_INGRESS_VALIDATE_JSON\"},\n}\n\nfunc buildIngressSubcommand() *cli.Command {\n\treturn &cli.Command{\n\t\tName:      \"ingress\",\n\t\tCategory:  \"Tunnel\",\n\t\tUsage:     \"Validate and test cloudflared tunnel's ingress configuration\",\n\t\tUsageText: \"cloudflared tunnel [--config FILEPATH] ingress COMMAND [arguments...]\",\n\t\tHidden:    true,\n\t\tDescription: ` Cloudflared lets you route traffic from the internet to multiple different addresses on your\n\t\torigin. Multiple-origin routing is configured by a set of rules. Each rule matches traffic\n\t\tby its hostname or path, and routes it to an address. These rules are configured under the\n\t\t'ingress' key of your config.yaml, for example:\n\n\t\tingress:\n\t\t  - hostname: www.example.com\n\t\t    service: https://localhost:8000\n\t\t  - hostname: *.example.xyz\n\t\t    path: /[a-zA-Z]+.html\n\t\t    service: https://localhost:8001\n\t\t  - hostname: *\n\t\t    service: https://localhost:8002\n\n\t\tTo ensure cloudflared can route all incoming requests, the last rule must be a catch-all\n\t\trule that matches all traffic. You can validate these rules with the 'ingress validate'\n\t\tcommand, and test which rule matches a particular URL with 'ingress rule <URL>'.\n\n\t\tMultiple-origin routing is incompatible with the --url flag.`,\n\t\tSubcommands: []*cli.Command{buildValidateIngressCommand(), buildTestURLCommand()},\n\t}\n}\n\nfunc buildValidateIngressCommand() *cli.Command {\n\treturn &cli.Command{\n\t\tName:        \"validate\",\n\t\tAction:      cliutil.ConfiguredActionWithWarnings(validateIngressCommand),\n\t\tUsage:       \"Validate the ingress configuration \",\n\t\tUsageText:   \"cloudflared tunnel [--config FILEPATH] ingress validate\",\n\t\tDescription: \"Validates the configuration file, ensuring your ingress rules are OK.\",\n\t\tFlags:       []cli.Flag{ingressDataJSON},\n\t}\n}\n\nfunc buildTestURLCommand() *cli.Command {\n\treturn &cli.Command{\n\t\tName:      \"rule\",\n\t\tAction:    cliutil.ConfiguredAction(testURLCommand),\n\t\tUsage:     \"Check which ingress rule matches a given request URL\",\n\t\tUsageText: \"cloudflared tunnel [--config FILEPATH] ingress rule URL\",\n\t\tArgsUsage: \"URL\",\n\t\tDescription: \"Check which ingress rule matches a given request URL. \" +\n\t\t\t\"Ingress rules match a request's hostname and path. Hostname is \" +\n\t\t\t\"optional and is either a full hostname like `www.example.com` or a \" +\n\t\t\t\"hostname with a `*` for its subdomains, e.g. `*.example.com`. Path \" +\n\t\t\t\"is optional and matches a regular expression, like `/[a-zA-Z0-9_]+.html`\",\n\t}\n}\n\n// validateIngressCommand check the syntax of the ingress rules in the cloudflared config file\nfunc validateIngressCommand(c *cli.Context, warnings string) error {\n\tconf, err := getConfiguration(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif _, err := ingress.ParseIngress(conf); err != nil {\n\t\treturn errors.Wrap(err, \"Validation failed\")\n\t}\n\tif c.IsSet(\"url\") {\n\t\treturn ingress.ErrURLIncompatibleWithIngress\n\t}\n\tif warnings != \"\" {\n\t\tfmt.Println(\"Warning: unused keys detected in your config file. Here is a list of unused keys:\")\n\t\tfmt.Println(warnings)\n\t\treturn nil\n\t}\n\tfmt.Println(\"OK\")\n\treturn nil\n}\n\nfunc getConfiguration(c *cli.Context) (*config.Configuration, error) {\n\tvar conf *config.Configuration\n\tif c.IsSet(ingressDataJSONFlagName) {\n\t\tingressJSON := c.String(ingressDataJSONFlagName)\n\t\tfmt.Println(\"Validating rules from cmdline flag --json\")\n\t\terr := json.Unmarshal([]byte(ingressJSON), &conf)\n\t\treturn conf, err\n\t}\n\tconf = config.GetConfiguration()\n\tif conf.Source() == \"\" {\n\t\treturn nil, errors.New(\"No configuration file was found. Please create one, or use the --config flag to specify its filepath. You can use the help command to learn more about configuration files\")\n\t}\n\tfmt.Println(\"Validating rules from\", conf.Source())\n\treturn conf, nil\n}\n\n// testURLCommand checks which ingress rule matches the given URL.\nfunc testURLCommand(c *cli.Context) error {\n\trequestArg := c.Args().First()\n\tif requestArg == \"\" {\n\t\treturn errors.New(\"cloudflared tunnel rule expects a single argument, the URL to test\")\n\t}\n\n\trequestURL, err := url.Parse(requestArg)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"%s is not a valid URL\", requestArg)\n\t}\n\tif requestURL.Hostname() == \"\" && requestURL.Scheme == \"\" {\n\t\treturn fmt.Errorf(\"%s doesn't have a hostname, consider adding a scheme\", requestArg)\n\t}\n\n\tconf := config.GetConfiguration()\n\tfmt.Println(\"Using rules from\", conf.Source())\n\ting, err := ingress.ParseIngress(conf)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Validation failed\")\n\t}\n\n\t_, i := ing.FindMatchingRule(requestURL.Hostname(), requestURL.Path)\n\tfmt.Printf(\"Matched rule #%d\\n\", i)\n\tfmt.Println(ing.Rules[i].MultiLineString())\n\treturn nil\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/login.go",
    "content": "package tunnel\n\nimport (\n\t\"fmt\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"syscall\"\n\n\thomedir \"github.com/mitchellh/go-homedir\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n\tcfdflags \"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/credentials\"\n\t\"github.com/cloudflare/cloudflared/logger\"\n\t\"github.com/cloudflare/cloudflared/token\"\n)\n\nconst (\n\tbaseLoginURL         = \"https://dash.cloudflare.com/argotunnel\"\n\tcallbackURL          = \"https://login.cloudflareaccess.org/\"\n\tfedBaseLoginURL      = \"https://dash.fed.cloudflare.com/argotunnel\"\n\tfedCallbackStoreURL  = \"https://login.fed.cloudflareaccess.org/\"\n\tfedRAMPParamName     = \"fedramp\"\n\tloginURLParamName    = \"loginURL\"\n\tcallbackURLParamName = \"callbackURL\"\n)\n\nvar (\n\tloginURL = &cli.StringFlag{\n\t\tName:  loginURLParamName,\n\t\tValue: baseLoginURL,\n\t\tUsage: \"The URL used to login (default is https://dash.cloudflare.com/argotunnel)\",\n\t}\n\tcallbackStore = &cli.StringFlag{\n\t\tName:  callbackURLParamName,\n\t\tValue: callbackURL,\n\t\tUsage: \"The URL used for the callback (default is https://login.cloudflareaccess.org/)\",\n\t}\n\tfedramp = &cli.BoolFlag{\n\t\tName:    fedRAMPParamName,\n\t\tAliases: []string{\"f\"},\n\t\tUsage:   \"Login with FedRAMP High environment.\",\n\t}\n)\n\nfunc buildLoginSubcommand(hidden bool) *cli.Command {\n\treturn &cli.Command{\n\t\tName:      \"login\",\n\t\tAction:    cliutil.ConfiguredAction(login),\n\t\tUsage:     \"Generate a configuration file with your login details\",\n\t\tArgsUsage: \" \",\n\t\tHidden:    hidden,\n\t\tFlags: []cli.Flag{\n\t\t\tloginURL,\n\t\t\tcallbackStore,\n\t\t\tfedramp,\n\t\t},\n\t}\n}\n\nfunc login(c *cli.Context) error {\n\tlog := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog)\n\n\tpath, ok, err := checkForExistingCert()\n\tif ok {\n\t\tlog.Error().Err(err).Msgf(\"You have an existing certificate at %s which login would overwrite.\\nIf this is intentional, please move or delete that file then run this command again.\\n\", path)\n\t\treturn nil\n\t} else if err != nil {\n\t\treturn err\n\t}\n\n\tvar (\n\t\tbaseloginURL     = c.String(loginURLParamName)\n\t\tcallbackStoreURL = c.String(callbackURLParamName)\n\t)\n\n\tisFEDRamp := c.Bool(fedRAMPParamName)\n\tif isFEDRamp {\n\t\tbaseloginURL = fedBaseLoginURL\n\t\tcallbackStoreURL = fedCallbackStoreURL\n\t}\n\n\tloginURL, err := url.Parse(baseloginURL)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tresourceData, err := token.RunTransfer(\n\t\tloginURL,\n\t\t\"\",\n\t\t\"cert\",\n\t\t\"callback\",\n\t\tcallbackStoreURL,\n\t\tfalse,\n\t\tfalse,\n\t\tc.Bool(cfdflags.AutoCloseInterstitial),\n\t\tisFEDRamp,\n\t\tlog,\n\t)\n\tif err != nil {\n\t\tlog.Error().Err(err).Msgf(\"Failed to write the certificate.\\n\\nYour browser will download the certificate instead. You will have to manually\\ncopy it to the following path:\\n\\n%s\\n\", path)\n\t\treturn err\n\t}\n\n\tcert, err := credentials.DecodeOriginCert(resourceData)\n\tif err != nil {\n\t\tlog.Error().Err(err).Msg(\"failed to decode origin certificate\")\n\t\treturn err\n\t}\n\n\tif isFEDRamp {\n\t\tcert.Endpoint = credentials.FedEndpoint\n\t}\n\n\tresourceData, err = cert.EncodeOriginCert()\n\tif err != nil {\n\t\tlog.Error().Err(err).Msg(\"failed to encode origin certificate\")\n\t\treturn err\n\t}\n\n\tif err := os.WriteFile(path, resourceData, 0600); err != nil {\n\t\treturn errors.Wrap(err, fmt.Sprintf(\"error writing cert to %s\", path))\n\t}\n\n\tlog.Info().Msgf(\"You have successfully logged in.\\nIf you wish to copy your credentials to a server, they have been saved to:\\n%s\\n\", path)\n\treturn nil\n}\n\nfunc checkForExistingCert() (string, bool, error) {\n\tconfigPath, err := homedir.Expand(config.DefaultConfigSearchDirectories()[0])\n\tif err != nil {\n\t\treturn \"\", false, err\n\t}\n\tok, err := config.FileExists(configPath)\n\tif !ok && err == nil {\n\t\t// create config directory if doesn't already exist\n\t\terr = os.Mkdir(configPath, 0700)\n\t}\n\tif err != nil {\n\t\treturn \"\", false, err\n\t}\n\tpath := filepath.Join(configPath, credentials.DefaultCredentialFile)\n\tfileInfo, err := os.Stat(path)\n\tif err == nil && fileInfo.Size() > 0 {\n\t\treturn path, true, nil\n\t}\n\tif err != nil && err.(*os.PathError).Err != syscall.ENOENT {\n\t\treturn path, false, err\n\t}\n\n\treturn path, false, nil\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/quick_tunnel.go",
    "content": "package tunnel\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/pkg/errors\"\n\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n\t\"github.com/cloudflare/cloudflared/connection\"\n)\n\nconst httpTimeout = 15 * time.Second\n\nconst disclaimer = \"Thank you for trying Cloudflare Tunnel. Doing so, without a Cloudflare account, is a quick way to experiment and try it out. However, be aware that these account-less Tunnels have no uptime guarantee, are subject to the Cloudflare Online Services Terms of Use (https://www.cloudflare.com/website-terms/), and Cloudflare reserves the right to investigate your use of Tunnels for violations of such terms. If you intend to use Tunnels in production you should use a pre-created named tunnel by following: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps\"\n\n// RunQuickTunnel requests a tunnel from the specified service.\n// We use this to power quick tunnels on trycloudflare.com, but the\n// service is open-source and could be used by anyone.\nfunc RunQuickTunnel(sc *subcommandContext) error {\n\tsc.log.Info().Msg(disclaimer)\n\tsc.log.Info().Msg(\"Requesting new quick Tunnel on trycloudflare.com...\")\n\n\tclient := http.Client{\n\t\tTransport: &http.Transport{\n\t\t\tTLSHandshakeTimeout:   httpTimeout,\n\t\t\tResponseHeaderTimeout: httpTimeout,\n\t\t},\n\t\tTimeout: httpTimeout,\n\t}\n\n\treq, err := http.NewRequest(http.MethodPost, fmt.Sprintf(\"%s/tunnel\", sc.c.String(\"quick-service\")), nil)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to build quick tunnel request\")\n\t}\n\treq.Header.Add(\"Content-Type\", \"application/json\")\n\treq.Header.Add(\"User-Agent\", buildInfo.UserAgent())\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to request quick Tunnel\")\n\t}\n\tdefer resp.Body.Close()\n\n\t// This will read the entire response into memory so we can print it in case of error\n\trsp_body, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to read quick-tunnel response\")\n\t}\n\n\tvar data QuickTunnelResponse\n\tif err := json.Unmarshal(rsp_body, &data); err != nil {\n\t\trsp_string := string(rsp_body)\n\t\tfields := map[string]interface{}{\"status_code\": resp.Status}\n\t\tsc.log.Err(err).Fields(fields).Msgf(\"Error unmarshaling QuickTunnel response: %s\", rsp_string)\n\t\treturn errors.Wrap(err, \"failed to unmarshal quick Tunnel\")\n\t}\n\n\ttunnelID, err := uuid.Parse(data.Result.ID)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to parse quick Tunnel ID\")\n\t}\n\n\tcredentials := connection.Credentials{\n\t\tAccountTag:   data.Result.AccountTag,\n\t\tTunnelSecret: data.Result.Secret,\n\t\tTunnelID:     tunnelID,\n\t}\n\n\turl := data.Result.Hostname\n\tif !strings.HasPrefix(url, \"https://\") {\n\t\turl = \"https://\" + url\n\t}\n\n\tfor _, line := range AsciiBox([]string{\n\t\t\"Your quick Tunnel has been created! Visit it at (it may take some time to be reachable):\",\n\t\turl,\n\t}, 2) {\n\t\tsc.log.Info().Msg(line)\n\t}\n\n\tif !sc.c.IsSet(flags.Protocol) {\n\t\t_ = sc.c.Set(flags.Protocol, \"quic\")\n\t}\n\n\t// Override the number of connections used. Quick tunnels shouldn't be used for production usage,\n\t// so, use a single connection instead.\n\t_ = sc.c.Set(flags.HaConnections, \"1\")\n\treturn StartServer(\n\t\tsc.c,\n\t\tbuildInfo,\n\t\t&connection.TunnelProperties{Credentials: credentials, QuickTunnelUrl: data.Result.Hostname},\n\t\tsc.log,\n\t)\n}\n\ntype QuickTunnelResponse struct {\n\tSuccess bool\n\tResult  QuickTunnel\n\tErrors  []QuickTunnelError\n}\n\ntype QuickTunnelError struct {\n\tCode    int\n\tMessage string\n}\n\ntype QuickTunnel struct {\n\tID         string `json:\"id\"`\n\tName       string `json:\"name\"`\n\tHostname   string `json:\"hostname\"`\n\tAccountTag string `json:\"account_tag\"`\n\tSecret     []byte `json:\"secret\"`\n}\n\n// Print out the given lines in a nice ASCII box.\nfunc AsciiBox(lines []string, padding int) (box []string) {\n\tmaxLen := maxLen(lines)\n\tspacer := strings.Repeat(\" \", padding)\n\tborder := \"+\" + strings.Repeat(\"-\", maxLen+(padding*2)) + \"+\"\n\tbox = append(box, border)\n\tfor _, line := range lines {\n\t\tbox = append(box, \"|\"+spacer+line+strings.Repeat(\" \", maxLen-len(line))+spacer+\"|\")\n\t}\n\tbox = append(box, border)\n\treturn\n}\n\nfunc maxLen(lines []string) int {\n\tmax := 0\n\tfor _, line := range lines {\n\t\tif len(line) > max {\n\t\t\tmax = len(line)\n\t\t}\n\t}\n\treturn max\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/signal.go",
    "content": "package tunnel\n\nimport (\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\n\t\"github.com/rs/zerolog\"\n)\n\n// waitForSignal closes graceShutdownC to indicate that we should start graceful shutdown sequence\nfunc waitForSignal(graceShutdownC chan struct{}, logger *zerolog.Logger) {\n\tsignals := make(chan os.Signal, 10)\n\tsignal.Notify(signals, syscall.SIGTERM, syscall.SIGINT)\n\tdefer signal.Stop(signals)\n\n\tselect {\n\tcase s := <-signals:\n\t\tlogger.Info().Msgf(\"Initiating graceful shutdown due to signal %s ...\", s)\n\t\tclose(graceShutdownC)\n\tcase <-graceShutdownC:\n\t}\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/signal_test.go",
    "content": "//go:build !windows\n\npackage tunnel\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"syscall\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nconst tick = 100 * time.Millisecond\n\nvar (\n\tserverErr        = fmt.Errorf(\"server error\")\n\tshutdownErr      = fmt.Errorf(\"receive shutdown\")\n\tgraceShutdownErr = fmt.Errorf(\"receive grace shutdown\")\n)\n\nfunc channelClosed(c chan struct{}) bool {\n\tselect {\n\tcase <-c:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc TestSignalShutdown(t *testing.T) {\n\tlog := zerolog.Nop()\n\n\t// Test handling SIGTERM & SIGINT\n\tfor _, sig := range []syscall.Signal{syscall.SIGTERM, syscall.SIGINT} {\n\t\tgraceShutdownC := make(chan struct{})\n\n\t\tgo func(sig syscall.Signal) {\n\t\t\t// sleep for a tick to prevent sending signal before calling waitForSignal\n\t\t\ttime.Sleep(tick)\n\t\t\t_ = syscall.Kill(syscall.Getpid(), sig)\n\t\t}(sig)\n\n\t\ttime.AfterFunc(time.Second, func() {\n\t\t\tselect {\n\t\t\tcase <-graceShutdownC:\n\t\t\tdefault:\n\t\t\t\tclose(graceShutdownC)\n\t\t\t\tt.Fatal(\"waitForSignal timed out\")\n\t\t\t}\n\t\t})\n\n\t\twaitForSignal(graceShutdownC, &log)\n\t\tassert.True(t, channelClosed(graceShutdownC))\n\t}\n}\n\nfunc TestWaitForShutdown(t *testing.T) {\n\tlog := zerolog.Nop()\n\n\terrC := make(chan error)\n\tgraceShutdownC := make(chan struct{})\n\tconst gracePeriod = 5 * time.Second\n\n\tcontextCancelled := false\n\tcancel := func() {\n\t\tcontextCancelled = true\n\t}\n\tvar wg sync.WaitGroup\n\n\t// on, error stop immediately\n\tcontextCancelled = false\n\tstartTime := time.Now()\n\tgo func() {\n\t\terrC <- serverErr\n\t}()\n\terr := waitToShutdown(&wg, cancel, errC, graceShutdownC, gracePeriod, &log)\n\tassert.Equal(t, serverErr, err)\n\tassert.True(t, contextCancelled)\n\tassert.False(t, channelClosed(graceShutdownC))\n\tassert.True(t, time.Now().Sub(startTime) < time.Second) // check that wait ended early\n\n\t// on graceful shutdown, ignore error but stop as soon as an error arrives\n\tcontextCancelled = false\n\tstartTime = time.Now()\n\tgo func() {\n\t\tclose(graceShutdownC)\n\t\ttime.Sleep(tick)\n\t\terrC <- serverErr\n\t}()\n\terr = waitToShutdown(&wg, cancel, errC, graceShutdownC, gracePeriod, &log)\n\tassert.Nil(t, err)\n\tassert.True(t, contextCancelled)\n\tassert.True(t, time.Now().Sub(startTime) < time.Second) // check that wait ended early\n\n\t// with graceShutdownC closed stop right away without grace period\n\tcontextCancelled = false\n\tstartTime = time.Now()\n\terr = waitToShutdown(&wg, cancel, errC, graceShutdownC, 0, &log)\n\tassert.Nil(t, err)\n\tassert.True(t, contextCancelled)\n\tassert.True(t, time.Now().Sub(startTime) < time.Second) // check that wait ended early\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/subcommand_context.go",
    "content": "package tunnel\n\nimport (\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/mitchellh/go-homedir\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/cloudflare/cloudflared/cfapi\"\n\tcfdflags \"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n\t\"github.com/cloudflare/cloudflared/connection\"\n\t\"github.com/cloudflare/cloudflared/credentials\"\n\t\"github.com/cloudflare/cloudflared/logger\"\n)\n\nconst fedRampBaseApiURL = \"https://api.fed.cloudflare.com/client/v4\"\n\ntype invalidJSONCredentialError struct {\n\terr  error\n\tpath string\n}\n\nfunc (e invalidJSONCredentialError) Error() string {\n\treturn \"Invalid JSON when parsing tunnel credentials file\"\n}\n\n// subcommandContext carries structs shared between subcommands, to reduce number of arguments needed to\n// pass between subcommands, and make sure they are only initialized once\ntype subcommandContext struct {\n\tc   *cli.Context\n\tlog *zerolog.Logger\n\tfs  fileSystem\n\n\t// These fields should be accessed using their respective Getter\n\ttunnelstoreClient cfapi.Client\n\tuserCredential    *credentials.User\n}\n\nfunc newSubcommandContext(c *cli.Context) (*subcommandContext, error) {\n\treturn &subcommandContext{\n\t\tc:   c,\n\t\tlog: logger.CreateLoggerFromContext(c, logger.EnableTerminalLog),\n\t\tfs:  realFileSystem{},\n\t}, nil\n}\n\n// Returns something that can find the given tunnel's credentials file.\nfunc (sc *subcommandContext) credentialFinder(tunnelID uuid.UUID) CredFinder {\n\tif path := sc.c.String(CredFileFlag); path != \"\" {\n\t\t// Expand path if CredFileFlag contains `~`\n\t\tabsPath, err := homedir.Expand(path)\n\t\tif err != nil {\n\t\t\treturn newStaticPath(path, sc.fs)\n\t\t}\n\t\treturn newStaticPath(absPath, sc.fs)\n\t}\n\treturn newSearchByID(tunnelID, sc.c, sc.log, sc.fs)\n}\n\nfunc (sc *subcommandContext) client() (cfapi.Client, error) {\n\tif sc.tunnelstoreClient != nil {\n\t\treturn sc.tunnelstoreClient, nil\n\t}\n\tcred, err := sc.credential()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar apiURL string\n\tif cred.IsFEDEndpoint() {\n\t\tsc.log.Info().Str(\"api-url\", fedRampBaseApiURL).Msg(\"using fedramp base api\")\n\t\tapiURL = fedRampBaseApiURL\n\t} else {\n\t\tapiURL = sc.c.String(cfdflags.ApiURL)\n\t}\n\n\tsc.tunnelstoreClient, err = cred.Client(apiURL, buildInfo.UserAgent(), sc.log)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn sc.tunnelstoreClient, nil\n}\n\nfunc (sc *subcommandContext) credential() (*credentials.User, error) {\n\tif sc.userCredential == nil {\n\t\tuc, err := credentials.Read(sc.c.String(cfdflags.OriginCert), sc.log)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tsc.userCredential = uc\n\t}\n\treturn sc.userCredential, nil\n}\n\nfunc (sc *subcommandContext) readTunnelCredentials(credFinder CredFinder) (connection.Credentials, error) {\n\tfilePath, err := credFinder.Path()\n\tif err != nil {\n\t\treturn connection.Credentials{}, err\n\t}\n\tbody, err := sc.fs.readFile(filePath)\n\tif err != nil {\n\t\treturn connection.Credentials{}, errors.Wrapf(err, \"couldn't read tunnel credentials from %v\", filePath)\n\t}\n\n\tvar credentials connection.Credentials\n\tif err = json.Unmarshal(body, &credentials); err != nil {\n\t\tif filepath.Ext(filePath) == \".pem\" {\n\t\t\treturn connection.Credentials{}, fmt.Errorf(\"The tunnel credentials file should be .json but you gave a .pem. \" +\n\t\t\t\t\"The tunnel credentials file was originally created by `cloudflared tunnel create`. \" +\n\t\t\t\t\"You may have accidentally used the filepath to cert.pem, which is generated by `cloudflared tunnel \" +\n\t\t\t\t\"login`.\")\n\t\t}\n\t\treturn connection.Credentials{}, invalidJSONCredentialError{path: filePath, err: err}\n\t}\n\treturn credentials, nil\n}\n\nfunc (sc *subcommandContext) create(name string, credentialsFilePath string, secret string) (*cfapi.Tunnel, error) {\n\tclient, err := sc.client()\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"couldn't create client to talk to Cloudflare Tunnel backend\")\n\t}\n\n\tvar tunnelSecret []byte\n\tif secret == \"\" {\n\t\ttunnelSecret, err = generateTunnelSecret()\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"couldn't generate the secret for your new tunnel\")\n\t\t}\n\t} else {\n\t\tdecodedSecret, err := base64.StdEncoding.DecodeString(secret)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"Couldn't decode tunnel secret from base64\")\n\t\t}\n\t\ttunnelSecret = decodedSecret\n\t\tif len(tunnelSecret) < 32 {\n\t\t\treturn nil, errors.New(\"Decoded tunnel secret must be at least 32 bytes long\")\n\t\t}\n\t}\n\n\ttunnel, err := client.CreateTunnel(name, tunnelSecret)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"Create Tunnel API call failed\")\n\t}\n\n\tcredential, err := sc.credential()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttunnelCredentials := connection.Credentials{\n\t\tAccountTag:   credential.AccountID(),\n\t\tTunnelSecret: tunnelSecret,\n\t\tTunnelID:     tunnel.ID,\n\t\tEndpoint:     credential.Endpoint(),\n\t}\n\tusedCertPath := false\n\tif credentialsFilePath == \"\" {\n\t\toriginCertDir := filepath.Dir(credential.CertPath())\n\t\tcredentialsFilePath, err = tunnelFilePath(tunnelCredentials.TunnelID, originCertDir)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tusedCertPath = true\n\t}\n\twriteFileErr := writeTunnelCredentials(credentialsFilePath, &tunnelCredentials)\n\tif writeFileErr != nil {\n\t\tvar errorLines []string\n\t\terrorLines = append(errorLines, fmt.Sprintf(\"Your tunnel '%v' was created with ID %v. However, cloudflared couldn't write tunnel credentials to %s.\", tunnel.Name, tunnel.ID, credentialsFilePath))\n\t\terrorLines = append(errorLines, fmt.Sprintf(\"The file-writing error is: %v\", writeFileErr))\n\t\tif deleteErr := client.DeleteTunnel(tunnel.ID, true); deleteErr != nil {\n\t\t\terrorLines = append(errorLines, fmt.Sprintf(\"Cloudflared tried to delete the tunnel for you, but encountered an error. You should use `cloudflared tunnel delete %v` to delete the tunnel yourself, because the tunnel can't be run without the tunnelfile.\", tunnel.ID))\n\t\t\terrorLines = append(errorLines, fmt.Sprintf(\"The delete tunnel error is: %v\", deleteErr))\n\t\t} else {\n\t\t\terrorLines = append(errorLines, \"The tunnel was deleted, because the tunnel can't be run without the credentials file\")\n\t\t}\n\t\terrorMsg := strings.Join(errorLines, \"\\n\")\n\t\treturn nil, errors.New(errorMsg)\n\t}\n\n\tif outputFormat := sc.c.String(outputFormatFlag.Name); outputFormat != \"\" {\n\t\treturn nil, renderOutput(outputFormat, &tunnel)\n\t}\n\n\tfmt.Printf(\"Tunnel credentials written to %v.\", credentialsFilePath)\n\tif usedCertPath {\n\t\tfmt.Print(\" cloudflared chose this file based on where your origin certificate was found.\")\n\t}\n\tfmt.Println(\" Keep this file secret. To revoke these credentials, delete the tunnel.\")\n\tfmt.Printf(\"\\nCreated tunnel %s with id %s\\n\", tunnel.Name, tunnel.ID)\n\n\treturn &tunnel.Tunnel, nil\n}\n\nfunc (sc *subcommandContext) list(filter *cfapi.TunnelFilter) ([]*cfapi.Tunnel, error) {\n\tclient, err := sc.client()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn client.ListTunnels(filter)\n}\n\nfunc (sc *subcommandContext) delete(tunnelIDs []uuid.UUID) error {\n\tforceFlagSet := sc.c.Bool(cfdflags.Force)\n\n\tclient, err := sc.client()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor _, id := range tunnelIDs {\n\t\ttunnel, err := client.GetTunnel(id)\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"Can't get tunnel information. Please check tunnel id: %s\", id)\n\t\t}\n\n\t\t// Check if tunnel DeletedAt field has already been set\n\t\tif !tunnel.DeletedAt.IsZero() {\n\t\t\treturn fmt.Errorf(\"Tunnel %s has already been deleted\", tunnel.ID)\n\t\t}\n\n\t\tif err := client.DeleteTunnel(tunnel.ID, forceFlagSet); err != nil {\n\t\t\treturn errors.Wrapf(err, \"Error deleting tunnel %s\", tunnel.ID)\n\t\t}\n\n\t\tcredFinder := sc.credentialFinder(id)\n\t\tif tunnelCredentialsPath, err := credFinder.Path(); err == nil {\n\t\t\tif err = os.Remove(tunnelCredentialsPath); err != nil {\n\t\t\t\tsc.log.Info().Msgf(\"Tunnel %v was deleted, but we could not remove its credentials file  %s: %s. Consider deleting this file manually.\", id, tunnelCredentialsPath, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// findCredentials will choose the right way to find the credentials file, find it,\n// and add the TunnelID into any old credentials (generated before TUN-3581 added the `TunnelID`\n// field to credentials files)\nfunc (sc *subcommandContext) findCredentials(tunnelID uuid.UUID) (connection.Credentials, error) {\n\tvar credentials connection.Credentials\n\tvar err error\n\tif credentialsContents := sc.c.String(CredContentsFlag); credentialsContents != \"\" {\n\t\tif err = json.Unmarshal([]byte(credentialsContents), &credentials); err != nil {\n\t\t\terr = invalidJSONCredentialError{path: \"TUNNEL_CRED_CONTENTS\", err: err}\n\t\t}\n\t} else {\n\t\tcredFinder := sc.credentialFinder(tunnelID)\n\t\tcredentials, err = sc.readTunnelCredentials(credFinder)\n\t}\n\t// This line ensures backwards compatibility with credentials files generated before\n\t// TUN-3581. Those old credentials files don't have a TunnelID field, so we enrich the struct\n\t// with the ID, which we have already resolved from the user input.\n\tcredentials.TunnelID = tunnelID\n\treturn credentials, err\n}\n\nfunc (sc *subcommandContext) run(tunnelID uuid.UUID) error {\n\tcredentials, err := sc.findCredentials(tunnelID)\n\tif err != nil {\n\t\tif e, ok := err.(invalidJSONCredentialError); ok {\n\t\t\tsc.log.Error().Msgf(\"The credentials file at %s contained invalid JSON. This is probably caused by passing the wrong filepath. Reminder: the credentials file is a .json file created via `cloudflared tunnel create`.\", e.path)\n\t\t\tsc.log.Error().Msgf(\"Invalid JSON when parsing credentials file: %s\", e.err.Error())\n\t\t}\n\t\treturn err\n\t}\n\n\treturn sc.runWithCredentials(credentials)\n}\n\nfunc (sc *subcommandContext) runWithCredentials(credentials connection.Credentials) error {\n\tsc.log.Info().Str(LogFieldTunnelID, credentials.TunnelID.String()).Msg(\"Starting tunnel\")\n\n\treturn StartServer(\n\t\tsc.c,\n\t\tbuildInfo,\n\t\t&connection.TunnelProperties{Credentials: credentials},\n\t\tsc.log,\n\t)\n}\n\nfunc (sc *subcommandContext) cleanupConnections(tunnelIDs []uuid.UUID) error {\n\tparams := cfapi.NewCleanupParams()\n\textraLog := \"\"\n\tif connector := sc.c.String(\"connector-id\"); connector != \"\" {\n\t\tconnectorID, err := uuid.Parse(connector)\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"%s is not a valid client ID (must be a UUID)\", connector)\n\t\t}\n\t\tparams.ForClient(connectorID)\n\t\textraLog = fmt.Sprintf(\" for connector-id %s\", connectorID.String())\n\t}\n\n\tclient, err := sc.client()\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor _, tunnelID := range tunnelIDs {\n\t\tsc.log.Info().Msgf(\"Cleanup connection for tunnel %s%s\", tunnelID, extraLog)\n\t\tif err := client.CleanupConnections(tunnelID, params); err != nil {\n\t\t\tsc.log.Error().Msgf(\"Error cleaning up connections for tunnel %v, error :%v\", tunnelID, err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (sc *subcommandContext) getTunnelTokenCredentials(tunnelID uuid.UUID) (*connection.TunnelToken, error) {\n\tclient, err := sc.client()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttoken, err := client.GetTunnelToken(tunnelID)\n\tif err != nil {\n\t\tsc.log.Err(err).Msgf(\"Could not get the Token for the given Tunnel %v\", tunnelID)\n\t\treturn nil, err\n\t}\n\n\treturn ParseToken(token)\n}\n\nfunc (sc *subcommandContext) route(tunnelID uuid.UUID, r cfapi.HostnameRoute) (cfapi.HostnameRouteResult, error) {\n\tclient, err := sc.client()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn client.RouteTunnel(tunnelID, r)\n}\n\n// Query Tunnelstore to find the active tunnel with the given name.\nfunc (sc *subcommandContext) tunnelActive(name string) (*cfapi.Tunnel, bool, error) {\n\tfilter := cfapi.NewTunnelFilter()\n\tfilter.NoDeleted()\n\tfilter.ByName(name)\n\ttunnels, err := sc.list(filter)\n\tif err != nil {\n\t\treturn nil, false, err\n\t}\n\tif len(tunnels) == 0 {\n\t\treturn nil, false, nil\n\t}\n\t// There should only be 1 active tunnel for a given name\n\treturn tunnels[0], true, nil\n}\n\n// findID parses the input. If it's a UUID, return the UUID.\n// Otherwise, assume it's a name, and look up the ID of that tunnel.\nfunc (sc *subcommandContext) findID(input string) (uuid.UUID, error) {\n\tif u, err := uuid.Parse(input); err == nil {\n\t\treturn u, nil\n\t}\n\n\t// Look up name in the credentials file.\n\tcredFinder := newStaticPath(sc.c.String(CredFileFlag), sc.fs)\n\tif credentials, err := sc.readTunnelCredentials(credFinder); err == nil {\n\t\tif credentials.TunnelID != uuid.Nil {\n\t\t\treturn credentials.TunnelID, nil\n\t\t}\n\t}\n\n\t// Fall back to querying Tunnelstore.\n\tif tunnel, found, err := sc.tunnelActive(input); err != nil {\n\t\treturn uuid.Nil, err\n\t} else if found {\n\t\treturn tunnel.ID, nil\n\t}\n\n\treturn uuid.Nil, fmt.Errorf(\"%s is neither the ID nor the name of any of your tunnels\", input)\n}\n\n// findIDs is just like mapping `findID` over a slice, but it only uses\n// one Tunnelstore API call per non-UUID input provided.\nfunc (sc *subcommandContext) findIDs(inputs []string) ([]uuid.UUID, error) {\n\tuuids, names := splitUuids(inputs)\n\n\tfor _, name := range names {\n\t\tfilter := cfapi.NewTunnelFilter()\n\t\tfilter.NoDeleted()\n\t\tfilter.ByName(name)\n\n\t\ttunnels, err := sc.list(filter)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif len(tunnels) != 1 {\n\t\t\treturn nil, fmt.Errorf(\"there should only be 1 non-deleted Tunnel named %s\", name)\n\t\t}\n\n\t\tuuids = append(uuids, tunnels[0].ID)\n\t}\n\n\treturn uuids, nil\n}\n\nfunc splitUuids(inputs []string) ([]uuid.UUID, []string) {\n\tuuids := make([]uuid.UUID, 0)\n\tnames := make([]string, 0)\n\n\tfor _, input := range inputs {\n\t\tid, err := uuid.Parse(input)\n\t\tif err != nil {\n\t\t\tnames = append(names, input)\n\t\t} else {\n\t\t\tuuids = append(uuids, id)\n\t\t}\n\t}\n\n\treturn uuids, names\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/subcommand_context_teamnet.go",
    "content": "package tunnel\n\nimport (\n\t\"net\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/pkg/errors\"\n\n\t\"github.com/cloudflare/cloudflared/cfapi\"\n)\n\nconst noClientMsg = \"error while creating backend client\"\n\nfunc (sc *subcommandContext) listRoutes(filter *cfapi.IpRouteFilter) ([]*cfapi.DetailedRoute, error) {\n\tclient, err := sc.client()\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, noClientMsg)\n\t}\n\treturn client.ListRoutes(filter)\n}\n\nfunc (sc *subcommandContext) addRoute(newRoute cfapi.NewRoute) (cfapi.Route, error) {\n\tclient, err := sc.client()\n\tif err != nil {\n\t\treturn cfapi.Route{}, errors.Wrap(err, noClientMsg)\n\t}\n\treturn client.AddRoute(newRoute)\n}\n\nfunc (sc *subcommandContext) deleteRoute(id uuid.UUID) error {\n\tclient, err := sc.client()\n\tif err != nil {\n\t\treturn errors.Wrap(err, noClientMsg)\n\t}\n\treturn client.DeleteRoute(id)\n}\n\nfunc (sc *subcommandContext) getRouteByIP(params cfapi.GetRouteByIpParams) (cfapi.DetailedRoute, error) {\n\tclient, err := sc.client()\n\tif err != nil {\n\t\treturn cfapi.DetailedRoute{}, errors.Wrap(err, noClientMsg)\n\t}\n\treturn client.GetByIP(params)\n}\n\nfunc (sc *subcommandContext) getRouteId(network net.IPNet, vnetId *uuid.UUID) (uuid.UUID, error) {\n\tfilters := cfapi.NewIPRouteFilter()\n\tfilters.NotDeleted()\n\tfilters.NetworkIsSubsetOf(network)\n\tfilters.NetworkIsSupersetOf(network)\n\n\tif vnetId != nil {\n\t\tfilters.VNetID(*vnetId)\n\t}\n\n\tresult, err := sc.listRoutes(filters)\n\tif err != nil {\n\t\treturn uuid.Nil, err\n\t}\n\n\tif len(result) != 1 {\n\t\treturn uuid.Nil, errors.New(\"unable to find route for provided network and vnet\")\n\t}\n\n\treturn result[0].ID, nil\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/subcommand_context_test.go",
    "content": "package tunnel\n\nimport (\n\t\"encoding/base64\"\n\t\"flag\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/cloudflare/cloudflared/cfapi\"\n\t\"github.com/cloudflare/cloudflared/connection\"\n\t\"github.com/cloudflare/cloudflared/credentials\"\n)\n\ntype mockFileSystem struct {\n\trf  func(string) ([]byte, error)\n\tvfp func(string) bool\n}\n\nfunc (fs mockFileSystem) validFilePath(path string) bool {\n\treturn fs.vfp(path)\n}\n\nfunc (fs mockFileSystem) readFile(filePath string) ([]byte, error) {\n\treturn fs.rf(filePath)\n}\n\nfunc Test_subcommandContext_findCredentials(t *testing.T) {\n\ttype fields struct {\n\t\tc                 *cli.Context\n\t\tlog               *zerolog.Logger\n\t\tfs                fileSystem\n\t\ttunnelstoreClient cfapi.Client\n\t\tuserCredential    *credentials.User\n\t}\n\ttype args struct {\n\t\ttunnelID uuid.UUID\n\t}\n\toldCertPath := \"old_cert.json\"\n\tnewCertPath := \"new_cert.json\"\n\taccountTag := \"0000d4d14e84bd4ae5a6a02e0000ac63\"\n\tsecret := []byte{211, 79, 177, 245, 179, 194, 152, 127, 140, 71, 18, 46, 183, 209, 10, 24, 192, 150, 55, 249, 211, 16, 167, 30, 113, 51, 152, 168, 72, 100, 205, 144}\n\tsecretB64 := base64.StdEncoding.EncodeToString(secret)\n\ttunnelID := uuid.MustParse(\"df5ed608-b8b4-4109-89f3-9f2cf199df64\")\n\tname := \"mytunnel\"\n\n\tfs := mockFileSystem{\n\t\trf: func(filePath string) ([]byte, error) {\n\t\t\tif filePath == oldCertPath {\n\t\t\t\t// An old credentials file created before TUN-3581 added the new fields\n\t\t\t\treturn []byte(fmt.Sprintf(`{\"AccountTag\":\"%s\",\"TunnelSecret\":\"%s\"}`, accountTag, secretB64)), nil\n\t\t\t}\n\t\t\tif filePath == newCertPath {\n\t\t\t\t// A new credentials file created after TUN-3581 with its new fields.\n\t\t\t\treturn []byte(fmt.Sprintf(`{\"AccountTag\":\"%s\",\"TunnelSecret\":\"%s\",\"TunnelID\":\"%s\",\"TunnelName\":\"%s\"}`, accountTag, secretB64, tunnelID, name)), nil\n\t\t\t}\n\t\t\treturn nil, errors.New(\"file not found\")\n\t\t},\n\t\tvfp: func(string) bool { return true },\n\t}\n\tlog := zerolog.Nop()\n\n\ttests := []struct {\n\t\tname    string\n\t\tfields  fields\n\t\targs    args\n\t\twant    connection.Credentials\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname: \"Filepath given leads to old credentials file\",\n\t\t\tfields: fields{\n\t\t\t\tlog: &log,\n\t\t\t\tfs:  fs,\n\t\t\t\tc: func() *cli.Context {\n\t\t\t\t\tflagSet := flag.NewFlagSet(\"test0\", flag.PanicOnError)\n\t\t\t\t\tflagSet.String(CredFileFlag, oldCertPath, \"\")\n\t\t\t\t\tc := cli.NewContext(cli.NewApp(), flagSet, nil)\n\t\t\t\t\t_ = c.Set(CredFileFlag, oldCertPath)\n\t\t\t\t\treturn c\n\t\t\t\t}(),\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\ttunnelID: tunnelID,\n\t\t\t},\n\t\t\twant: connection.Credentials{\n\t\t\t\tAccountTag:   accountTag,\n\t\t\t\tTunnelID:     tunnelID,\n\t\t\t\tTunnelSecret: secret,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Filepath given leads to new credentials file\",\n\t\t\tfields: fields{\n\t\t\t\tlog: &log,\n\t\t\t\tfs:  fs,\n\t\t\t\tc: func() *cli.Context {\n\t\t\t\t\tflagSet := flag.NewFlagSet(\"test0\", flag.PanicOnError)\n\t\t\t\t\tflagSet.String(CredFileFlag, newCertPath, \"\")\n\t\t\t\t\tc := cli.NewContext(cli.NewApp(), flagSet, nil)\n\t\t\t\t\t_ = c.Set(CredFileFlag, newCertPath)\n\t\t\t\t\treturn c\n\t\t\t\t}(),\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\ttunnelID: tunnelID,\n\t\t\t},\n\t\t\twant: connection.Credentials{\n\t\t\t\tAccountTag:   accountTag,\n\t\t\t\tTunnelID:     tunnelID,\n\t\t\t\tTunnelSecret: secret,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"TUNNEL_CRED_CONTENTS given contains old credentials contents\",\n\t\t\tfields: fields{\n\t\t\t\tlog: &log,\n\t\t\t\tfs:  fs,\n\t\t\t\tc: func() *cli.Context {\n\t\t\t\t\tflagSet := flag.NewFlagSet(\"test0\", flag.PanicOnError)\n\t\t\t\t\tflagSet.String(CredContentsFlag, \"\", \"\")\n\t\t\t\t\tc := cli.NewContext(cli.NewApp(), flagSet, nil)\n\t\t\t\t\t_ = c.Set(CredContentsFlag, fmt.Sprintf(`{\"AccountTag\":\"%s\",\"TunnelSecret\":\"%s\"}`, accountTag, secretB64))\n\t\t\t\t\treturn c\n\t\t\t\t}(),\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\ttunnelID: tunnelID,\n\t\t\t},\n\t\t\twant: connection.Credentials{\n\t\t\t\tAccountTag:   accountTag,\n\t\t\t\tTunnelID:     tunnelID,\n\t\t\t\tTunnelSecret: secret,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"TUNNEL_CRED_CONTENTS given contains new credentials contents\",\n\t\t\tfields: fields{\n\t\t\t\tlog: &log,\n\t\t\t\tfs:  fs,\n\t\t\t\tc: func() *cli.Context {\n\t\t\t\t\tflagSet := flag.NewFlagSet(\"test0\", flag.PanicOnError)\n\t\t\t\t\tflagSet.String(CredContentsFlag, \"\", \"\")\n\t\t\t\t\tc := cli.NewContext(cli.NewApp(), flagSet, nil)\n\t\t\t\t\t_ = c.Set(CredContentsFlag, fmt.Sprintf(`{\"AccountTag\":\"%s\",\"TunnelSecret\":\"%s\",\"TunnelID\":\"%s\",\"TunnelName\":\"%s\"}`, accountTag, secretB64, tunnelID, name))\n\t\t\t\t\treturn c\n\t\t\t\t}(),\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\ttunnelID: tunnelID,\n\t\t\t},\n\t\t\twant: connection.Credentials{\n\t\t\t\tAccountTag:   accountTag,\n\t\t\t\tTunnelID:     tunnelID,\n\t\t\t\tTunnelSecret: secret,\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\tsc := &subcommandContext{\n\t\t\t\tc:                 tt.fields.c,\n\t\t\t\tlog:               tt.fields.log,\n\t\t\t\tfs:                tt.fields.fs,\n\t\t\t\ttunnelstoreClient: tt.fields.tunnelstoreClient,\n\t\t\t\tuserCredential:    tt.fields.userCredential,\n\t\t\t}\n\t\t\tgot, err := sc.findCredentials(tt.args.tunnelID)\n\t\t\tif (err != nil) != tt.wantErr {\n\t\t\t\tt.Errorf(\"subcommandContext.findCredentials() error = %v, wantErr %v\", err, tt.wantErr)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"subcommandContext.findCredentials() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\ntype deleteMockTunnelStore struct {\n\tcfapi.Client\n\tmockTunnels      map[uuid.UUID]mockTunnelBehaviour\n\tdeletedTunnelIDs []uuid.UUID\n}\n\ntype mockTunnelBehaviour struct {\n\ttunnel     cfapi.Tunnel\n\tdeleteErr  error\n\tcleanupErr error\n}\n\nfunc newDeleteMockTunnelStore(tunnels ...mockTunnelBehaviour) *deleteMockTunnelStore {\n\tmockTunnels := make(map[uuid.UUID]mockTunnelBehaviour)\n\tfor _, tunnel := range tunnels {\n\t\tmockTunnels[tunnel.tunnel.ID] = tunnel\n\t}\n\treturn &deleteMockTunnelStore{\n\t\tmockTunnels:      mockTunnels,\n\t\tdeletedTunnelIDs: make([]uuid.UUID, 0),\n\t}\n}\n\nfunc (d *deleteMockTunnelStore) GetTunnel(tunnelID uuid.UUID) (*cfapi.Tunnel, error) {\n\ttunnel, ok := d.mockTunnels[tunnelID]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"Couldn't find tunnel: %v\", tunnelID)\n\t}\n\treturn &tunnel.tunnel, nil\n}\n\nfunc (d *deleteMockTunnelStore) GetTunnelToken(tunnelID uuid.UUID) (string, error) {\n\treturn \"token\", nil\n}\n\nfunc (d *deleteMockTunnelStore) DeleteTunnel(tunnelID uuid.UUID, cascade bool) error {\n\ttunnel, ok := d.mockTunnels[tunnelID]\n\tif !ok {\n\t\treturn fmt.Errorf(\"Couldn't find tunnel: %v\", tunnelID)\n\t}\n\n\tif tunnel.deleteErr != nil {\n\t\treturn tunnel.deleteErr\n\t}\n\n\td.deletedTunnelIDs = append(d.deletedTunnelIDs, tunnelID)\n\ttunnel.tunnel.DeletedAt = time.Now()\n\tdelete(d.mockTunnels, tunnelID)\n\treturn nil\n}\n\nfunc (d *deleteMockTunnelStore) CleanupConnections(tunnelID uuid.UUID, _ *cfapi.CleanupParams) error {\n\ttunnel, ok := d.mockTunnels[tunnelID]\n\tif !ok {\n\t\treturn fmt.Errorf(\"Couldn't find tunnel: %v\", tunnelID)\n\t}\n\treturn tunnel.cleanupErr\n}\n\nfunc Test_subcommandContext_Delete(t *testing.T) {\n\ttype fields struct {\n\t\tc                 *cli.Context\n\t\tlog               *zerolog.Logger\n\t\tisUIEnabled       bool\n\t\tfs                fileSystem\n\t\ttunnelstoreClient *deleteMockTunnelStore\n\t\tuserCredential    *credentials.User\n\t}\n\ttype args struct {\n\t\ttunnelIDs []uuid.UUID\n\t}\n\tnewCertPath := \"new_cert.json\"\n\ttunnelID1 := uuid.MustParse(\"df5ed608-b8b4-4109-89f3-9f2cf199df64\")\n\ttunnelID2 := uuid.MustParse(\"af5ed608-b8b4-4109-89f3-9f2cf199df64\")\n\tlog := zerolog.Nop()\n\n\tvar tests = []struct {\n\t\tname    string\n\t\tfields  fields\n\t\targs    args\n\t\twant    []uuid.UUID\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname: \"clean up continues if credentials are not found\",\n\t\t\tfields: fields{\n\t\t\t\tlog: &log,\n\t\t\t\tfs: mockFileSystem{\n\t\t\t\t\trf: func(filePath string) ([]byte, error) {\n\t\t\t\t\t\treturn nil, errors.New(\"file not found\")\n\t\t\t\t\t},\n\t\t\t\t\tvfp: func(string) bool { return true },\n\t\t\t\t},\n\t\t\t\tc: func() *cli.Context {\n\t\t\t\t\tflagSet := flag.NewFlagSet(\"test0\", flag.PanicOnError)\n\t\t\t\t\tflagSet.String(CredFileFlag, newCertPath, \"\")\n\t\t\t\t\tc := cli.NewContext(cli.NewApp(), flagSet, nil)\n\t\t\t\t\t_ = c.Set(CredFileFlag, newCertPath)\n\t\t\t\t\treturn c\n\t\t\t\t}(),\n\t\t\t\ttunnelstoreClient: newDeleteMockTunnelStore(\n\t\t\t\t\tmockTunnelBehaviour{\n\t\t\t\t\t\ttunnel: cfapi.Tunnel{ID: tunnelID1},\n\t\t\t\t\t},\n\t\t\t\t\tmockTunnelBehaviour{\n\t\t\t\t\t\ttunnel: cfapi.Tunnel{ID: tunnelID2},\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t},\n\n\t\t\targs: args{\n\t\t\t\ttunnelIDs: []uuid.UUID{tunnelID1, tunnelID2},\n\t\t\t},\n\t\t\twant: []uuid.UUID{tunnelID1, tunnelID2},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tsc := &subcommandContext{\n\t\t\t\tc:                 tt.fields.c,\n\t\t\t\tlog:               tt.fields.log,\n\t\t\t\tfs:                tt.fields.fs,\n\t\t\t\ttunnelstoreClient: tt.fields.tunnelstoreClient,\n\t\t\t\tuserCredential:    tt.fields.userCredential,\n\t\t\t}\n\t\t\terr := sc.delete(tt.args.tunnelIDs)\n\t\t\tif (err != nil) != tt.wantErr {\n\t\t\t\tt.Errorf(\"subcommandContext.findCredentials() error = %v, wantErr %v\", err, tt.wantErr)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tgot := tt.fields.tunnelstoreClient.deletedTunnelIDs\n\t\t\tif !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"subcommandContext.findCredentials() = %v, want %v\", got, tt.want)\n\t\t\t\treturn\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc Test_subcommandContext_ValidateIngressCommand(t *testing.T) {\n\tvar tests = []struct {\n\t\tname        string\n\t\tc           *cli.Context\n\t\twantErr     bool\n\t\texpectedErr error\n\t}{\n\t\t{\n\t\t\tname: \"read a valid configuration from data\",\n\t\t\tc: func() *cli.Context {\n\t\t\t\tdata := `{ \"warp-routing\": {\"enabled\": true},  \"originRequest\" : {\"connectTimeout\": 10}, \"ingress\" : [ {\"hostname\": \"test\", \"service\": \"https://localhost:8000\" } , {\"service\": \"http_status:404\"} ]}`\n\t\t\t\tflagSet := flag.NewFlagSet(\"json\", flag.PanicOnError)\n\t\t\t\tflagSet.String(ingressDataJSONFlagName, data, \"\")\n\t\t\t\tc := cli.NewContext(cli.NewApp(), flagSet, nil)\n\t\t\t\t_ = c.Set(ingressDataJSONFlagName, data)\n\t\t\t\treturn c\n\t\t\t}(),\n\t\t},\n\t\t{\n\t\t\tname: \"read an invalid configuration with multiple mistakes\",\n\t\t\tc: func() *cli.Context {\n\t\t\t\tdata := `{ \"ingress\" : [ {\"hostname\": \"test\", \"service\": \"localhost:8000\" } , {\"service\": \"http_status:invalid_status\"} ]}`\n\t\t\t\tflagSet := flag.NewFlagSet(\"json\", flag.PanicOnError)\n\t\t\t\tflagSet.String(ingressDataJSONFlagName, data, \"\")\n\t\t\t\tc := cli.NewContext(cli.NewApp(), flagSet, nil)\n\t\t\t\t_ = c.Set(ingressDataJSONFlagName, data)\n\t\t\t\treturn c\n\t\t\t}(),\n\t\t\twantErr:     true,\n\t\t\texpectedErr: errors.New(\"Validation failed: localhost:8000 is an invalid address, please make sure it has a scheme and a hostname\"),\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 := validateIngressCommand(tt.c, \"\")\n\t\t\tif tt.wantErr {\n\t\t\t\tassert.Equal(t, tt.expectedErr.Error(), err.Error())\n\t\t\t} else {\n\t\t\t\tassert.Nil(t, err)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/subcommand_context_vnets.go",
    "content": "package tunnel\n\nimport (\n\t\"github.com/google/uuid\"\n\t\"github.com/pkg/errors\"\n\n\t\"github.com/cloudflare/cloudflared/cfapi\"\n)\n\nfunc (sc *subcommandContext) addVirtualNetwork(newVnet cfapi.NewVirtualNetwork) (cfapi.VirtualNetwork, error) {\n\tclient, err := sc.client()\n\tif err != nil {\n\t\treturn cfapi.VirtualNetwork{}, errors.Wrap(err, noClientMsg)\n\t}\n\treturn client.CreateVirtualNetwork(newVnet)\n}\n\nfunc (sc *subcommandContext) listVirtualNetworks(filter *cfapi.VnetFilter) ([]*cfapi.VirtualNetwork, error) {\n\tclient, err := sc.client()\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, noClientMsg)\n\t}\n\treturn client.ListVirtualNetworks(filter)\n}\n\nfunc (sc *subcommandContext) deleteVirtualNetwork(vnetId uuid.UUID, force bool) error {\n\tclient, err := sc.client()\n\tif err != nil {\n\t\treturn errors.Wrap(err, noClientMsg)\n\t}\n\treturn client.DeleteVirtualNetwork(vnetId, force)\n}\n\nfunc (sc *subcommandContext) updateVirtualNetwork(vnetId uuid.UUID, updates cfapi.UpdateVirtualNetwork) error {\n\tclient, err := sc.client()\n\tif err != nil {\n\t\treturn errors.Wrap(err, noClientMsg)\n\t}\n\treturn client.UpdateVirtualNetwork(vnetId, updates)\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/subcommands.go",
    "content": "package tunnel\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strings\"\n\t\"text/tabwriter\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/mitchellh/go-homedir\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/urfave/cli/v2\"\n\t\"github.com/urfave/cli/v2/altsrc\"\n\t\"golang.org/x/net/idna\"\n\t\"gopkg.in/yaml.v3\"\n\n\t\"github.com/cloudflare/cloudflared/cfapi\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/updater\"\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/connection\"\n\t\"github.com/cloudflare/cloudflared/diagnostic\"\n\t\"github.com/cloudflare/cloudflared/fips\"\n\t\"github.com/cloudflare/cloudflared/metrics\"\n)\n\nconst (\n\tallSortByOptions        = \"name, id, createdAt, deletedAt, numConnections\"\n\tconnsSortByOptions      = \"id, startedAt, numConnections, version\"\n\tCredFileFlagAlias       = \"cred-file\"\n\tCredFileFlag            = \"credentials-file\"\n\tCredContentsFlag        = \"credentials-contents\"\n\tTunnelTokenFlag         = \"token\"\n\tTunnelTokenFileFlag     = \"token-file\"\n\toverwriteDNSFlagName    = \"overwrite-dns\"\n\tnoDiagLogsFlagName      = \"no-diag-logs\"\n\tnoDiagMetricsFlagName   = \"no-diag-metrics\"\n\tnoDiagSystemFlagName    = \"no-diag-system\"\n\tnoDiagRuntimeFlagName   = \"no-diag-runtime\"\n\tnoDiagNetworkFlagName   = \"no-diag-network\"\n\tdiagContainerIDFlagName = \"diag-container-id\"\n\tdiagPodFlagName         = \"diag-pod-id\"\n\n\tLogFieldTunnelID = \"tunnelID\"\n)\n\nvar (\n\tshowDeletedFlag = &cli.BoolFlag{\n\t\tName:    \"show-deleted\",\n\t\tAliases: []string{\"d\"},\n\t\tUsage:   \"Include deleted tunnels in the list\",\n\t}\n\tlistNameFlag = &cli.StringFlag{\n\t\tName:    flags.Name,\n\t\tAliases: []string{\"n\"},\n\t\tUsage:   \"List tunnels with the given `NAME`\",\n\t}\n\tlistNamePrefixFlag = &cli.StringFlag{\n\t\tName:    \"name-prefix\",\n\t\tAliases: []string{\"np\"},\n\t\tUsage:   \"List tunnels that start with the give `NAME` prefix\",\n\t}\n\tlistExcludeNamePrefixFlag = &cli.StringFlag{\n\t\tName:    \"exclude-name-prefix\",\n\t\tAliases: []string{\"enp\"},\n\t\tUsage:   \"List tunnels whose `NAME` does not start with the given prefix\",\n\t}\n\tlistExistedAtFlag = &cli.TimestampFlag{\n\t\tName:        \"when\",\n\t\tAliases:     []string{\"w\"},\n\t\tUsage:       \"List tunnels that are active at the given `TIME` in RFC3339 format\",\n\t\tLayout:      cfapi.TimeLayout,\n\t\tDefaultText: fmt.Sprintf(\"current time, %s\", time.Now().Format(cfapi.TimeLayout)),\n\t}\n\tlistIDFlag = &cli.StringFlag{\n\t\tName:    \"id\",\n\t\tAliases: []string{\"i\"},\n\t\tUsage:   \"List tunnel by `ID`\",\n\t}\n\tshowRecentlyDisconnected = &cli.BoolFlag{\n\t\tName:    \"show-recently-disconnected\",\n\t\tAliases: []string{\"rd\"},\n\t\tUsage:   \"Include connections that have recently disconnected in the list\",\n\t}\n\toutputFormatFlag = &cli.StringFlag{\n\t\tName:    \"output\",\n\t\tAliases: []string{\"o\"},\n\t\tUsage:   \"Render output using given `FORMAT`. Valid options are 'json' or 'yaml'\",\n\t}\n\tsortByFlag = &cli.StringFlag{\n\t\tName:    \"sort-by\",\n\t\tValue:   \"name\",\n\t\tUsage:   fmt.Sprintf(\"Sorts the list of tunnels by the given field. Valid options are {%s}\", allSortByOptions),\n\t\tEnvVars: []string{\"TUNNEL_LIST_SORT_BY\"},\n\t}\n\tinvertSortFlag = &cli.BoolFlag{\n\t\tName:    \"invert-sort\",\n\t\tUsage:   \"Inverts the sort order of the tunnel list.\",\n\t\tEnvVars: []string{\"TUNNEL_LIST_INVERT_SORT\"},\n\t}\n\tfeaturesFlag = altsrc.NewStringSliceFlag(&cli.StringSliceFlag{\n\t\tName:    flags.Features,\n\t\tAliases: []string{\"F\"},\n\t\tUsage:   \"Opt into various features that are still being developed or tested.\",\n\t})\n\tcredentialsFileFlagCLIOnly = &cli.StringFlag{\n\t\tName:    CredFileFlag,\n\t\tAliases: []string{CredFileFlagAlias},\n\t\tUsage:   \"Filepath at which to read/write the tunnel credentials\",\n\t\tEnvVars: []string{\"TUNNEL_CRED_FILE\"},\n\t}\n\tcredentialsFileFlag     = altsrc.NewStringFlag(credentialsFileFlagCLIOnly)\n\tcredentialsContentsFlag = altsrc.NewStringFlag(&cli.StringFlag{\n\t\tName:    CredContentsFlag,\n\t\tUsage:   \"Contents of the tunnel credentials JSON file to use. When provided along with credentials-file, this will take precedence.\",\n\t\tEnvVars: []string{\"TUNNEL_CRED_CONTENTS\"},\n\t})\n\ttunnelTokenFlag = altsrc.NewStringFlag(&cli.StringFlag{\n\t\tName:    TunnelTokenFlag,\n\t\tUsage:   \"The Tunnel token. When provided along with credentials, this will take precedence. Also takes precedence over token-file\",\n\t\tEnvVars: []string{\"TUNNEL_TOKEN\"},\n\t})\n\ttunnelTokenFileFlag = altsrc.NewStringFlag(&cli.StringFlag{\n\t\tName:    TunnelTokenFileFlag,\n\t\tUsage:   \"Filepath at which to read the tunnel token. When provided along with credentials, this will take precedence.\",\n\t\tEnvVars: []string{\"TUNNEL_TOKEN_FILE\"},\n\t})\n\tforceDeleteFlag = &cli.BoolFlag{\n\t\tName:    flags.Force,\n\t\tAliases: []string{\"f\"},\n\t\tUsage: \"Deletes a tunnel even if tunnel is connected and it has dependencies associated to it. (eg. IP routes).\" +\n\t\t\t\" It is not possible to delete tunnels that have connections or non-deleted dependencies, without this flag.\",\n\t\tEnvVars: []string{\"TUNNEL_RUN_FORCE_OVERWRITE\"},\n\t}\n\tselectProtocolFlag = altsrc.NewStringFlag(&cli.StringFlag{\n\t\tName:    flags.Protocol,\n\t\tValue:   connection.AutoSelectFlag,\n\t\tAliases: []string{\"p\"},\n\t\tUsage:   fmt.Sprintf(\"Protocol implementation to connect with Cloudflare's edge network. %s\", connection.AvailableProtocolFlagMessage),\n\t\tEnvVars: []string{\"TUNNEL_TRANSPORT_PROTOCOL\"},\n\t\tHidden:  true,\n\t})\n\tpostQuantumFlag = altsrc.NewBoolFlag(&cli.BoolFlag{\n\t\tName:    flags.PostQuantum,\n\t\tUsage:   \"When given creates an experimental post-quantum secure tunnel\",\n\t\tAliases: []string{\"pq\"},\n\t\tEnvVars: []string{\"TUNNEL_POST_QUANTUM\"},\n\t\tHidden:  fips.IsFipsEnabled(),\n\t})\n\tsortInfoByFlag = &cli.StringFlag{\n\t\tName:    \"sort-by\",\n\t\tValue:   \"createdAt\",\n\t\tUsage:   fmt.Sprintf(\"Sorts the list of connections of a tunnel by the given field. Valid options are {%s}\", connsSortByOptions),\n\t\tEnvVars: []string{\"TUNNEL_INFO_SORT_BY\"},\n\t}\n\tinvertInfoSortFlag = &cli.BoolFlag{\n\t\tName:    \"invert-sort\",\n\t\tUsage:   \"Inverts the sort order of the tunnel info.\",\n\t\tEnvVars: []string{\"TUNNEL_INFO_INVERT_SORT\"},\n\t}\n\tcleanupClientFlag = &cli.StringFlag{\n\t\tName:    \"connector-id\",\n\t\tAliases: []string{\"c\"},\n\t\tUsage:   `Constraints the cleanup to stop the connections of a single Connector (by its ID). You can find the various Connectors (and their IDs) currently connected to your tunnel via 'cloudflared tunnel info <name>'.`,\n\t\tEnvVars: []string{\"TUNNEL_CLEANUP_CONNECTOR\"},\n\t}\n\toverwriteDNSFlag = &cli.BoolFlag{\n\t\tName:    overwriteDNSFlagName,\n\t\tAliases: []string{\"f\"},\n\t\tUsage:   `Overwrites existing DNS records with this hostname`,\n\t\tEnvVars: []string{\"TUNNEL_FORCE_PROVISIONING_DNS\"},\n\t}\n\tcreateSecretFlag = &cli.StringFlag{\n\t\tName:    \"secret\",\n\t\tAliases: []string{\"s\"},\n\t\tUsage:   \"Base64 encoded secret to set for the tunnel. The decoded secret must be at least 32 bytes long. If not specified, a random 32-byte secret will be generated.\",\n\t\tEnvVars: []string{\"TUNNEL_CREATE_SECRET\"},\n\t}\n\ticmpv4SrcFlag = &cli.StringFlag{\n\t\tName:    flags.ICMPV4Src,\n\t\tUsage:   \"Source address to send/receive ICMPv4 messages. If not provided cloudflared will dial a local address to determine the source IP or fallback to 0.0.0.0.\",\n\t\tEnvVars: []string{\"TUNNEL_ICMPV4_SRC\"},\n\t}\n\ticmpv6SrcFlag = &cli.StringFlag{\n\t\tName:    flags.ICMPV6Src,\n\t\tUsage:   \"Source address and the interface name to send/receive ICMPv6 messages. If not provided cloudflared will dial a local address to determine the source IP or fallback to ::.\",\n\t\tEnvVars: []string{\"TUNNEL_ICMPV6_SRC\"},\n\t}\n\tmetricsFlag = &cli.StringFlag{\n\t\tName:  flags.Metrics,\n\t\tUsage: \"The metrics server address i.e.: 127.0.0.1:12345. If your instance is running in a Docker/Kubernetes environment you need to setup port forwarding for your application.\",\n\t\tValue: \"\",\n\t}\n\tdiagContainerFlag = &cli.StringFlag{\n\t\tName:  diagContainerIDFlagName,\n\t\tUsage: \"Container ID or Name to collect logs from\",\n\t\tValue: \"\",\n\t}\n\tdiagPodFlag = &cli.StringFlag{\n\t\tName:  diagPodFlagName,\n\t\tUsage: \"Kubernetes POD to collect logs from\",\n\t\tValue: \"\",\n\t}\n\tnoDiagLogsFlag = &cli.BoolFlag{\n\t\tName:  noDiagLogsFlagName,\n\t\tUsage: \"Log collection will not be performed\",\n\t\tValue: false,\n\t}\n\tnoDiagMetricsFlag = &cli.BoolFlag{\n\t\tName:  noDiagMetricsFlagName,\n\t\tUsage: \"Metric collection will not be performed\",\n\t\tValue: false,\n\t}\n\tnoDiagSystemFlag = &cli.BoolFlag{\n\t\tName:  noDiagSystemFlagName,\n\t\tUsage: \"System information collection will not be performed\",\n\t\tValue: false,\n\t}\n\tnoDiagRuntimeFlag = &cli.BoolFlag{\n\t\tName:  noDiagRuntimeFlagName,\n\t\tUsage: \"Runtime information collection will not be performed\",\n\t\tValue: false,\n\t}\n\tnoDiagNetworkFlag = &cli.BoolFlag{\n\t\tName:  noDiagNetworkFlagName,\n\t\tUsage: \"Network diagnostics won't be performed\",\n\t\tValue: false,\n\t}\n\tmaxActiveFlowsFlag = &cli.Uint64Flag{\n\t\tName:    flags.MaxActiveFlows,\n\t\tUsage:   \"Overrides the remote configuration for max active private network flows (TCP/UDP) that this cloudflared instance supports\",\n\t\tEnvVars: []string{\"TUNNEL_MAX_ACTIVE_FLOWS\"},\n\t}\n\tdnsResolverAddrsFlag = &cli.StringSliceFlag{\n\t\tName:    flags.VirtualDNSServiceResolverAddresses,\n\t\tUsage:   \"Overrides the dynamic DNS resolver resolution to use these address:port's instead.\",\n\t\tEnvVars: []string{\"TUNNEL_DNS_RESOLVER_ADDRS\"},\n\t}\n)\n\nfunc buildCreateCommand() *cli.Command {\n\treturn &cli.Command{\n\t\tName:      \"create\",\n\t\tAction:    cliutil.ConfiguredAction(createCommand),\n\t\tUsage:     \"Create a new tunnel with given name\",\n\t\tUsageText: \"cloudflared tunnel [tunnel command options] create [subcommand options] NAME\",\n\t\tDescription: `Creates a tunnel, registers it with Cloudflare edge and generates credential file used to run this tunnel.\n  Use \"cloudflared tunnel route\" subcommand to map a DNS name to this tunnel and \"cloudflared tunnel run\" to start the connection.\n\n  For example, to create a tunnel named 'my-tunnel' run:\n\n  $ cloudflared tunnel create my-tunnel`,\n\t\tFlags:              []cli.Flag{outputFormatFlag, credentialsFileFlagCLIOnly, createSecretFlag},\n\t\tCustomHelpTemplate: commandHelpTemplate(),\n\t}\n}\n\n// generateTunnelSecret as an array of 32 bytes using secure random number generator\nfunc generateTunnelSecret() ([]byte, error) {\n\trandomBytes := make([]byte, 32)\n\t_, err := rand.Read(randomBytes)\n\treturn randomBytes, err\n}\n\nfunc createCommand(c *cli.Context) error {\n\tsc, err := newSubcommandContext(c)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"error setting up logger\")\n\t}\n\n\tif c.NArg() != 1 {\n\t\treturn cliutil.UsageError(`\"cloudflared tunnel create\" requires exactly 1 argument, the name of tunnel to create.`)\n\t}\n\tname := c.Args().First()\n\n\twarningChecker := updater.StartWarningCheck(c)\n\tdefer warningChecker.LogWarningIfAny(sc.log)\n\n\t_, err = sc.create(name, c.String(CredFileFlag), c.String(createSecretFlag.Name))\n\treturn errors.Wrap(err, \"failed to create tunnel\")\n}\n\nfunc tunnelFilePath(tunnelID uuid.UUID, directory string) (string, error) {\n\tfileName := fmt.Sprintf(\"%v.json\", tunnelID)\n\tfilePath := filepath.Clean(fmt.Sprintf(\"%s/%s\", directory, fileName))\n\treturn homedir.Expand(filePath)\n}\n\n// writeTunnelCredentials saves `credentials` as a JSON into `filePath`, only if\n// the file does not exist already\nfunc writeTunnelCredentials(filePath string, credentials *connection.Credentials) error {\n\tif _, err := os.Stat(filePath); !os.IsNotExist(err) {\n\t\tif err == nil {\n\t\t\treturn fmt.Errorf(\"%s already exists\", filePath)\n\t\t}\n\t\treturn err\n\t}\n\tbody, err := json.Marshal(credentials)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Unable to marshal tunnel credentials to JSON\")\n\t}\n\treturn os.WriteFile(filePath, body, 0400)\n}\n\nfunc buildListCommand() *cli.Command {\n\treturn &cli.Command{\n\t\tName:        \"list\",\n\t\tAction:      cliutil.ConfiguredAction(listCommand),\n\t\tUsage:       \"List existing tunnels\",\n\t\tUsageText:   \"cloudflared tunnel [tunnel command options] list [subcommand options]\",\n\t\tDescription: \"cloudflared tunnel list will display all active tunnels, their created time and associated connections. Use -d flag to include deleted tunnels. See the list of options to filter the list\",\n\t\tFlags: []cli.Flag{\n\t\t\toutputFormatFlag,\n\t\t\tshowDeletedFlag,\n\t\t\tlistNameFlag,\n\t\t\tlistNamePrefixFlag,\n\t\t\tlistExcludeNamePrefixFlag,\n\t\t\tlistExistedAtFlag,\n\t\t\tlistIDFlag,\n\t\t\tshowRecentlyDisconnected,\n\t\t\tsortByFlag,\n\t\t\tinvertSortFlag,\n\t\t},\n\t\tCustomHelpTemplate: commandHelpTemplate(),\n\t}\n}\n\nfunc listCommand(c *cli.Context) error {\n\tsc, err := newSubcommandContext(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\twarningChecker := updater.StartWarningCheck(c)\n\tdefer warningChecker.LogWarningIfAny(sc.log)\n\n\tfilter := cfapi.NewTunnelFilter()\n\tif !c.Bool(\"show-deleted\") {\n\t\tfilter.NoDeleted()\n\t}\n\tif name := c.String(flags.Name); name != \"\" {\n\t\tfilter.ByName(name)\n\t}\n\tif namePrefix := c.String(\"name-prefix\"); namePrefix != \"\" {\n\t\tfilter.ByNamePrefix(namePrefix)\n\t}\n\tif excludePrefix := c.String(\"exclude-name-prefix\"); excludePrefix != \"\" {\n\t\tfilter.ExcludeNameWithPrefix(excludePrefix)\n\t}\n\tif existedAt := c.Timestamp(\"time\"); existedAt != nil {\n\t\tfilter.ByExistedAt(*existedAt)\n\t}\n\tif id := c.String(\"id\"); id != \"\" {\n\t\ttunnelID, err := uuid.Parse(id)\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"%s is not a valid tunnel ID\", id)\n\t\t}\n\t\tfilter.ByTunnelID(tunnelID)\n\t}\n\tif maxFetch := c.Int(\"max-fetch-size\"); maxFetch > 0 {\n\t\tfilter.MaxFetchSize(uint(maxFetch))\n\t}\n\n\ttunnels, err := sc.list(filter)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Sort the tunnels\n\tsortBy := c.String(\"sort-by\")\n\tinvalidSortField := false\n\tsort.Slice(tunnels, func(i, j int) bool {\n\t\tcmp := func() bool {\n\t\t\tswitch sortBy {\n\t\t\tcase \"name\":\n\t\t\t\treturn tunnels[i].Name < tunnels[j].Name\n\t\t\tcase \"id\":\n\t\t\t\treturn tunnels[i].ID.String() < tunnels[j].ID.String()\n\t\t\tcase \"createdAt\":\n\t\t\t\treturn tunnels[i].CreatedAt.Unix() < tunnels[j].CreatedAt.Unix()\n\t\t\tcase \"deletedAt\":\n\t\t\t\treturn tunnels[i].DeletedAt.Unix() < tunnels[j].DeletedAt.Unix()\n\t\t\tcase \"numConnections\":\n\t\t\t\treturn len(tunnels[i].Connections) < len(tunnels[j].Connections)\n\t\t\tdefault:\n\t\t\t\tinvalidSortField = true\n\t\t\t\treturn tunnels[i].Name < tunnels[j].Name\n\t\t\t}\n\t\t}()\n\t\tif c.Bool(\"invert-sort\") {\n\t\t\treturn !cmp\n\t\t}\n\t\treturn cmp\n\t})\n\tif invalidSortField {\n\t\tsc.log.Error().Msgf(\"%s is not a valid sort field. Valid sort fields are %s. Defaulting to 'name'.\", sortBy, allSortByOptions)\n\t}\n\n\tif outputFormat := c.String(outputFormatFlag.Name); outputFormat != \"\" {\n\t\treturn renderOutput(outputFormat, tunnels)\n\t}\n\n\tif len(tunnels) > 0 {\n\t\tformatAndPrintTunnelList(tunnels, c.Bool(\"show-recently-disconnected\"))\n\t} else {\n\t\tfmt.Println(\"No tunnels were found for the given filter flags. You can use 'cloudflared tunnel create' to create a tunnel.\")\n\t}\n\n\treturn nil\n}\n\nfunc formatAndPrintTunnelList(tunnels []*cfapi.Tunnel, showRecentlyDisconnected bool) {\n\twriter := tabWriter()\n\tdefer writer.Flush()\n\n\t_, _ = fmt.Fprintln(writer, \"You can obtain more detailed information for each tunnel with `cloudflared tunnel info <name/uuid>`\")\n\n\t// Print column headers with tabbed columns\n\t_, _ = fmt.Fprintln(writer, \"ID\\tNAME\\tCREATED\\tCONNECTIONS\\t\")\n\n\t// Loop through tunnels, create formatted string for each, and print using tabwriter\n\tfor _, t := range tunnels {\n\t\tformattedStr := fmt.Sprintf(\n\t\t\t\"%s\\t%s\\t%s\\t%s\\t\",\n\t\t\tt.ID,\n\t\t\tt.Name,\n\t\t\tt.CreatedAt.Format(time.RFC3339),\n\t\t\tfmtConnections(t.Connections, showRecentlyDisconnected),\n\t\t)\n\t\t_, _ = fmt.Fprintln(writer, formattedStr)\n\t}\n}\n\nfunc fmtConnections(connections []cfapi.Connection, showRecentlyDisconnected bool) string {\n\t// Count connections per colo\n\tnumConnsPerColo := make(map[string]uint, len(connections))\n\tfor _, connection := range connections {\n\t\tif !connection.IsPendingReconnect || showRecentlyDisconnected {\n\t\t\tnumConnsPerColo[connection.ColoName]++\n\t\t}\n\t}\n\n\t// Get sorted list of colos\n\tsortedColos := []string{}\n\tfor coloName := range numConnsPerColo {\n\t\tsortedColos = append(sortedColos, coloName)\n\t}\n\tsort.Strings(sortedColos)\n\n\t// Map each colo to its frequency, combine into output string.\n\toutput := make([]string, 0, len(sortedColos))\n\tfor _, coloName := range sortedColos {\n\t\toutput = append(output, fmt.Sprintf(\"%dx%s\", numConnsPerColo[coloName], coloName))\n\t}\n\treturn strings.Join(output, \", \")\n}\n\nfunc buildReadyCommand() *cli.Command {\n\treturn &cli.Command{\n\t\tName:               \"ready\",\n\t\tAction:             cliutil.ConfiguredAction(readyCommand),\n\t\tUsage:              \"Call /ready endpoint and return proper exit code\",\n\t\tUsageText:          \"cloudflared tunnel [tunnel command options] ready [subcommand options]\",\n\t\tDescription:        \"cloudflared tunnel ready will return proper exit code based on the /ready endpoint\",\n\t\tFlags:              []cli.Flag{},\n\t\tCustomHelpTemplate: commandHelpTemplate(),\n\t}\n}\n\nfunc readyCommand(c *cli.Context) error {\n\tmetricsOpts := c.String(flags.Metrics)\n\tif !c.IsSet(flags.Metrics) {\n\t\treturn errors.New(\"--metrics has to be provided\")\n\t}\n\n\trequestURL := fmt.Sprintf(\"http://%s/ready\", metricsOpts)\n\treq, err := http.NewRequest(http.MethodGet, requestURL, nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer res.Body.Close()\n\tif res.StatusCode != 200 {\n\t\tbody, err := io.ReadAll(res.Body)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn fmt.Errorf(\"http://%s/ready endpoint returned status code %d\\n%s\", metricsOpts, res.StatusCode, body)\n\t}\n\treturn nil\n}\n\nfunc buildInfoCommand() *cli.Command {\n\treturn &cli.Command{\n\t\tName:        \"info\",\n\t\tAction:      cliutil.ConfiguredAction(tunnelInfo),\n\t\tUsage:       \"List details about the active connectors for a tunnel\",\n\t\tUsageText:   \"cloudflared tunnel [tunnel command options] info [subcommand options] [TUNNEL]\",\n\t\tDescription: \"cloudflared tunnel info displays details about the active connectors for a given tunnel (identified by name or uuid).\",\n\t\tFlags: []cli.Flag{\n\t\t\toutputFormatFlag,\n\t\t\tshowRecentlyDisconnected,\n\t\t\tsortInfoByFlag,\n\t\t\tinvertInfoSortFlag,\n\t\t},\n\t\tCustomHelpTemplate: commandHelpTemplate(),\n\t}\n}\n\nfunc tunnelInfo(c *cli.Context) error {\n\tsc, err := newSubcommandContext(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\twarningChecker := updater.StartWarningCheck(c)\n\tdefer warningChecker.LogWarningIfAny(sc.log)\n\n\tif c.NArg() != 1 {\n\t\treturn cliutil.UsageError(`\"cloudflared tunnel info\" accepts exactly one argument, the ID or name of the tunnel to get info about.`)\n\t}\n\ttunnelID, err := sc.findID(c.Args().First())\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"error parsing tunnel ID\")\n\t}\n\n\tclient, err := sc.client()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tclients, err := client.ListActiveClients(tunnelID)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tsortBy := c.String(\"sort-by\")\n\tinvalidSortField := false\n\tsort.Slice(clients, func(i, j int) bool {\n\t\tcmp := func() bool {\n\t\t\tswitch sortBy {\n\t\t\tcase \"id\":\n\t\t\t\treturn clients[i].ID.String() < clients[j].ID.String()\n\t\t\tcase \"createdAt\":\n\t\t\t\treturn clients[i].RunAt.Unix() < clients[j].RunAt.Unix()\n\t\t\tcase \"numConnections\":\n\t\t\t\treturn len(clients[i].Connections) < len(clients[j].Connections)\n\t\t\tcase \"version\":\n\t\t\t\treturn clients[i].Version < clients[j].Version\n\t\t\tdefault:\n\t\t\t\tinvalidSortField = true\n\t\t\t\treturn clients[i].RunAt.Unix() < clients[j].RunAt.Unix()\n\t\t\t}\n\t\t}()\n\t\tif c.Bool(\"invert-sort\") {\n\t\t\treturn !cmp\n\t\t}\n\t\treturn cmp\n\t})\n\tif invalidSortField {\n\t\tsc.log.Error().Msgf(\"%s is not a valid sort field. Valid sort fields are %s. Defaulting to 'name'.\", sortBy, connsSortByOptions)\n\t}\n\n\ttunnel, err := getTunnel(sc, tunnelID)\n\tif err != nil {\n\t\treturn err\n\t}\n\tinfo := Info{\n\t\ttunnel.ID,\n\t\ttunnel.Name,\n\t\ttunnel.CreatedAt,\n\t\tclients,\n\t}\n\n\tif outputFormat := c.String(outputFormatFlag.Name); outputFormat != \"\" {\n\t\treturn renderOutput(outputFormat, info)\n\t}\n\n\tif len(clients) > 0 {\n\t\tformatAndPrintConnectionsList(info, c.Bool(\"show-recently-disconnected\"))\n\t} else {\n\t\tfmt.Printf(\"Your tunnel %s does not have any active connection.\\n\", tunnelID)\n\t}\n\n\treturn nil\n}\n\nfunc getTunnel(sc *subcommandContext, tunnelID uuid.UUID) (*cfapi.Tunnel, error) {\n\tfilter := cfapi.NewTunnelFilter()\n\tfilter.ByTunnelID(tunnelID)\n\ttunnels, err := sc.list(filter)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(tunnels) != 1 {\n\t\treturn nil, errors.Errorf(\"Expected to find a single tunnel with uuid %v but found %d tunnels.\", tunnelID, len(tunnels))\n\t}\n\treturn tunnels[0], nil\n}\n\nfunc formatAndPrintConnectionsList(tunnelInfo Info, showRecentlyDisconnected bool) {\n\twriter := tabWriter()\n\tdefer writer.Flush()\n\n\t// Print the general tunnel info table\n\t_, _ = fmt.Fprintf(writer, \"NAME:     %s\\nID:       %s\\nCREATED:  %s\\n\\n\", tunnelInfo.Name, tunnelInfo.ID, tunnelInfo.CreatedAt)\n\n\t// Determine whether to print the connector table\n\tshouldDisplayTable := false\n\tfor _, c := range tunnelInfo.Connectors {\n\t\tconns := fmtConnections(c.Connections, showRecentlyDisconnected)\n\t\tif len(conns) > 0 {\n\t\t\tshouldDisplayTable = true\n\t\t}\n\t}\n\tif !shouldDisplayTable {\n\t\tfmt.Println(\"This tunnel has no active connectors.\")\n\t\treturn\n\t}\n\n\t// Print the connector table\n\t_, _ = fmt.Fprintln(writer, \"CONNECTOR ID\\tCREATED\\tARCHITECTURE\\tVERSION\\tORIGIN IP\\tEDGE\\t\")\n\tfor _, c := range tunnelInfo.Connectors {\n\t\tconns := fmtConnections(c.Connections, showRecentlyDisconnected)\n\t\tif len(conns) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\toriginIp := c.Connections[0].OriginIP.String()\n\t\tformattedStr := fmt.Sprintf(\n\t\t\t\"%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t\",\n\t\t\tc.ID,\n\t\t\tc.RunAt.Format(time.RFC3339),\n\t\t\tc.Arch,\n\t\t\tc.Version,\n\t\t\toriginIp,\n\t\t\tconns,\n\t\t)\n\t\t_, _ = fmt.Fprintln(writer, formattedStr)\n\t}\n}\n\nfunc tabWriter() *tabwriter.Writer {\n\tconst (\n\t\tminWidth = 0\n\t\ttabWidth = 8\n\t\tpadding  = 1\n\t\tpadChar  = ' '\n\t\tflags    = 0\n\t)\n\n\twriter := tabwriter.NewWriter(os.Stdout, minWidth, tabWidth, padding, padChar, flags)\n\treturn writer\n}\n\nfunc buildDeleteCommand() *cli.Command {\n\treturn &cli.Command{\n\t\tName:               \"delete\",\n\t\tAction:             cliutil.ConfiguredAction(deleteCommand),\n\t\tUsage:              \"Delete existing tunnel by UUID or name\",\n\t\tUsageText:          \"cloudflared tunnel [tunnel command options] delete [subcommand options] TUNNEL\",\n\t\tDescription:        \"cloudflared tunnel delete will delete tunnels with the given tunnel UUIDs or names. A tunnel cannot be deleted if it has active connections. To delete the tunnel unconditionally, use -f flag.\",\n\t\tFlags:              []cli.Flag{credentialsFileFlagCLIOnly, forceDeleteFlag},\n\t\tCustomHelpTemplate: commandHelpTemplate(),\n\t}\n}\n\nfunc deleteCommand(c *cli.Context) error {\n\tsc, err := newSubcommandContext(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif c.NArg() < 1 {\n\t\treturn cliutil.UsageError(`\"cloudflared tunnel delete\" requires at least 1 argument, the ID or name of the tunnel to delete.`)\n\t}\n\n\twarningChecker := updater.StartWarningCheck(c)\n\tdefer warningChecker.LogWarningIfAny(sc.log)\n\n\ttunnelIDs, err := sc.findIDs(c.Args().Slice())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn sc.delete(tunnelIDs)\n}\n\nfunc renderOutput(format string, v interface{}) error {\n\tswitch format {\n\tcase \"json\":\n\t\tencoder := json.NewEncoder(os.Stdout)\n\t\tencoder.SetIndent(\"\", \"  \")\n\t\treturn encoder.Encode(v)\n\tcase \"yaml\":\n\t\treturn yaml.NewEncoder(os.Stdout).Encode(v)\n\tdefault:\n\t\treturn errors.Errorf(\"Unknown output format '%s'\", format)\n\t}\n}\n\nfunc buildRunCommand() *cli.Command {\n\tflags := []cli.Flag{\n\t\tcredentialsFileFlag,\n\t\tcredentialsContentsFlag,\n\t\tpostQuantumFlag,\n\t\tselectProtocolFlag,\n\t\tfeaturesFlag,\n\t\ttunnelTokenFlag,\n\t\ttunnelTokenFileFlag,\n\t\ticmpv4SrcFlag,\n\t\ticmpv6SrcFlag,\n\t\tmaxActiveFlowsFlag,\n\t\tdnsResolverAddrsFlag,\n\t}\n\tflags = append(flags, configureProxyFlags(false)...)\n\treturn &cli.Command{\n\t\tName:      \"run\",\n\t\tAction:    cliutil.ConfiguredAction(runCommand),\n\t\tUsage:     \"Proxy a local web server by running the given tunnel\",\n\t\tUsageText: \"cloudflared tunnel [tunnel command options] run [subcommand options] [TUNNEL]\",\n\t\tDescription: `Runs the tunnel identified by name or UUID, creating highly available connections\n  between your server and the Cloudflare edge. You can provide name or UUID of tunnel to run either as the\n  last command line argument or in the configuration file using \"tunnel: TUNNEL\".\n\n  This command requires the tunnel credentials file created when \"cloudflared tunnel create\" was run,\n  however it does not need access to cert.pem from \"cloudflared login\" if you identify the tunnel by UUID.\n  If you experience other problems running the tunnel, \"cloudflared tunnel cleanup\" may help by removing\n  any old connection records.\n`,\n\t\tFlags:              flags,\n\t\tCustomHelpTemplate: commandHelpTemplate(),\n\t}\n}\n\nfunc runCommand(c *cli.Context) error {\n\tsc, err := newSubcommandContext(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif c.NArg() > 1 {\n\t\treturn cliutil.UsageError(`\"cloudflared tunnel run\" accepts only one argument, the ID or name of the tunnel to run.`)\n\t}\n\n\tif c.String(\"hostname\") != \"\" {\n\t\tsc.log.Warn().Msg(\"The property `hostname` in your configuration is ignored because you configured a Named Tunnel \" +\n\t\t\t\"in the property `tunnel` to run. Make sure to provision the routing (e.g. via `cloudflared tunnel route dns/lb`) or else \" +\n\t\t\t\"your origin will not be reachable. You should remove the `hostname` property to avoid this warning.\")\n\t}\n\n\ttokenStr := c.String(TunnelTokenFlag)\n\t// Check if tokenStr is blank before checking for tokenFile\n\tif tokenStr == \"\" {\n\t\tif tokenFile := c.String(TunnelTokenFileFlag); tokenFile != \"\" {\n\t\t\tdata, err := os.ReadFile(tokenFile)\n\t\t\tif err != nil {\n\t\t\t\treturn cliutil.UsageError(\"Failed to read token file: %s\", err.Error())\n\t\t\t}\n\t\t\ttokenStr = strings.TrimSpace(string(data))\n\t\t}\n\t}\n\t// Check if token is provided and if not use default tunnelID flag method\n\tif tokenStr != \"\" {\n\t\tif token, err := ParseToken(tokenStr); err == nil {\n\t\t\treturn sc.runWithCredentials(token.Credentials())\n\t\t}\n\t\treturn cliutil.UsageError(\"Provided Tunnel token is not valid.\")\n\t} else {\n\t\ttunnelRef := c.Args().First()\n\t\tif tunnelRef == \"\" {\n\t\t\t// see if tunnel id was in the config file\n\t\t\ttunnelRef = config.GetConfiguration().TunnelID\n\t\t\tif tunnelRef == \"\" {\n\t\t\t\treturn cliutil.UsageError(`\"cloudflared tunnel run\" requires the ID or name of the tunnel to run as the last command line argument or in the configuration file.`)\n\t\t\t}\n\t\t}\n\n\t\treturn runNamedTunnel(sc, tunnelRef)\n\t}\n}\n\nfunc ParseToken(tokenStr string) (*connection.TunnelToken, error) {\n\tcontent, err := base64.StdEncoding.DecodeString(tokenStr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar token connection.TunnelToken\n\tif err := json.Unmarshal(content, &token); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &token, nil\n}\n\nfunc runNamedTunnel(sc *subcommandContext, tunnelRef string) error {\n\ttunnelID, err := sc.findID(tunnelRef)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"error parsing tunnel ID\")\n\t}\n\treturn sc.run(tunnelID)\n}\n\nfunc buildCleanupCommand() *cli.Command {\n\treturn &cli.Command{\n\t\tName:               \"cleanup\",\n\t\tAction:             cliutil.ConfiguredAction(cleanupCommand),\n\t\tUsage:              \"Cleanup tunnel connections\",\n\t\tUsageText:          \"cloudflared tunnel [tunnel command options] cleanup [subcommand options] TUNNEL\",\n\t\tDescription:        \"Delete connections for tunnels with the given UUIDs or names.\",\n\t\tFlags:              []cli.Flag{cleanupClientFlag},\n\t\tCustomHelpTemplate: commandHelpTemplate(),\n\t}\n}\n\nfunc cleanupCommand(c *cli.Context) error {\n\tif c.NArg() < 1 {\n\t\treturn cliutil.UsageError(`\"cloudflared tunnel cleanup\" requires at least 1 argument, the IDs of the tunnels to cleanup connections.`)\n\t}\n\n\tsc, err := newSubcommandContext(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ttunnelIDs, err := sc.findIDs(c.Args().Slice())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn sc.cleanupConnections(tunnelIDs)\n}\n\nfunc buildTokenCommand() *cli.Command {\n\treturn &cli.Command{\n\t\tName:               \"token\",\n\t\tAction:             cliutil.ConfiguredAction(tokenCommand),\n\t\tUsage:              \"Fetch the credentials token for an existing tunnel (by name or UUID) that allows to run it\",\n\t\tUsageText:          \"cloudflared tunnel [tunnel command options] token [subcommand options] TUNNEL\",\n\t\tDescription:        \"cloudflared tunnel token will fetch the credentials token for a given tunnel (by its name or UUID), which is then used to run the tunnel. This command fails if the tunnel does not exist or has been deleted. Use the flag `cloudflared tunnel token --cred-file /my/path/file.json TUNNEL` to output the token to the credentials JSON file. Note: this command only works for Tunnels created since cloudflared version 2022.3.0\",\n\t\tFlags:              []cli.Flag{credentialsFileFlagCLIOnly},\n\t\tCustomHelpTemplate: commandHelpTemplate(),\n\t}\n}\n\nfunc tokenCommand(c *cli.Context) error {\n\tsc, err := newSubcommandContext(c)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"error setting up logger\")\n\t}\n\n\twarningChecker := updater.StartWarningCheck(c)\n\tdefer warningChecker.LogWarningIfAny(sc.log)\n\n\tif c.NArg() != 1 {\n\t\treturn cliutil.UsageError(`\"cloudflared tunnel token\" requires exactly 1 argument, the name or UUID of tunnel to fetch the credentials token for.`)\n\t}\n\ttunnelID, err := sc.findID(c.Args().First())\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"error parsing tunnel ID\")\n\t}\n\n\ttoken, err := sc.getTunnelTokenCredentials(tunnelID)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif path := c.String(CredFileFlag); path != \"\" {\n\t\tcredentials := token.Credentials()\n\t\terr := writeTunnelCredentials(path, &credentials)\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"error writing token credentials to JSON file in path %s\", path)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tencodedToken, err := token.Encode()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Println(encodedToken)\n\treturn nil\n}\n\nfunc buildRouteCommand() *cli.Command {\n\treturn &cli.Command{\n\t\tName:      \"route\",\n\t\tUsage:     \"Define which traffic routed from Cloudflare edge to this tunnel: requests to a DNS hostname, to a Cloudflare Load Balancer, or traffic originating from Cloudflare WARP clients\",\n\t\tUsageText: \"cloudflared tunnel [tunnel command options] route [subcommand options] [dns TUNNEL HOSTNAME]|[lb TUNNEL HOSTNAME LB-POOL]|[ip NETWORK TUNNEL]\",\n\t\tDescription: `The route command defines how Cloudflare will proxy requests to this tunnel.\n\nTo route a hostname by creating a DNS CNAME record to a tunnel:\n   cloudflared tunnel route dns <tunnel ID or name> <hostname>\nYou can read more at: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/routing-to-tunnel/dns\n\nTo use this tunnel as a load balancer origin, creating pool and load balancer if necessary:\n   cloudflared tunnel route lb <tunnel ID or name> <hostname> <load balancer pool>\nYou can read more at: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/routing-to-tunnel/lb\n\nFor Cloudflare WARP traffic to be routed to your private network, reachable from this tunnel as origins, use:\n   cloudflared tunnel route ip <network CIDR> <tunnel ID or name>\nFurther information about managing Cloudflare WARP traffic to your tunnel is available at:\n   cloudflared tunnel route ip --help\n`,\n\t\tCustomHelpTemplate: commandHelpTemplate(),\n\t\tSubcommands: []*cli.Command{\n\t\t\t{\n\t\t\t\tName:        \"dns\",\n\t\t\t\tAction:      cliutil.ConfiguredAction(routeDnsCommand),\n\t\t\t\tUsage:       \"HostnameRoute a hostname by creating a DNS CNAME record to a tunnel\",\n\t\t\t\tUsageText:   \"cloudflared tunnel route dns [TUNNEL] [HOSTNAME]\",\n\t\t\t\tDescription: `Creates a DNS CNAME record hostname that points to the tunnel.`,\n\t\t\t\tFlags:       []cli.Flag{overwriteDNSFlag},\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:        \"lb\",\n\t\t\t\tAction:      cliutil.ConfiguredAction(routeLbCommand),\n\t\t\t\tUsage:       \"Use this tunnel as a load balancer origin, creating pool and load balancer if necessary\",\n\t\t\t\tUsageText:   \"cloudflared tunnel route lb [TUNNEL] [HOSTNAME] [LB-POOL-NAME]\",\n\t\t\t\tDescription: `Creates Load Balancer with an origin pool that points to the tunnel.`,\n\t\t\t},\n\t\t\tbuildRouteIPSubcommand(),\n\t\t},\n\t}\n}\n\nfunc dnsRouteFromArg(c *cli.Context, overwriteExisting bool) (cfapi.HostnameRoute, error) {\n\tconst (\n\t\tuserHostnameIndex = 1\n\t\texpectedNArgs     = 2\n\t)\n\tif c.NArg() != expectedNArgs {\n\t\treturn nil, cliutil.UsageError(\"Expected %d arguments, got %d\", expectedNArgs, c.NArg())\n\t}\n\tuserHostname := c.Args().Get(userHostnameIndex)\n\tif userHostname == \"\" {\n\t\treturn nil, cliutil.UsageError(\"The third argument should be the hostname\")\n\t} else if !validateHostname(userHostname, true) {\n\t\treturn nil, errors.Errorf(\"%s is not a valid hostname\", userHostname)\n\t}\n\treturn cfapi.NewDNSRoute(userHostname, overwriteExisting), nil\n}\n\nfunc lbRouteFromArg(c *cli.Context) (cfapi.HostnameRoute, error) {\n\tconst (\n\t\tlbNameIndex   = 1\n\t\tlbPoolIndex   = 2\n\t\texpectedNArgs = 3\n\t)\n\tif c.NArg() != expectedNArgs {\n\t\treturn nil, cliutil.UsageError(\"Expected %d arguments, got %d\", expectedNArgs, c.NArg())\n\t}\n\tlbName := c.Args().Get(lbNameIndex)\n\tif lbName == \"\" {\n\t\treturn nil, cliutil.UsageError(\"The third argument should be the load balancer name\")\n\t} else if !validateHostname(lbName, true) {\n\t\treturn nil, errors.Errorf(\"%s is not a valid load balancer name\", lbName)\n\t}\n\n\tlbPool := c.Args().Get(lbPoolIndex)\n\tif lbPool == \"\" {\n\t\treturn nil, cliutil.UsageError(\"The fourth argument should be the pool name\")\n\t} else if !validateName(lbPool, false) {\n\t\treturn nil, errors.Errorf(\"%s is not a valid pool name\", lbPool)\n\t}\n\n\treturn cfapi.NewLBRoute(lbName, lbPool), nil\n}\n\nvar (\n\tnameRegex     = regexp.MustCompile(\"^[_a-zA-Z0-9][-_.a-zA-Z0-9]*$\")\n\thostNameRegex = regexp.MustCompile(\"^[*_a-zA-Z0-9][-_.a-zA-Z0-9]*$\")\n)\n\nfunc validateName(s string, allowWildcardSubdomain bool) bool {\n\tif allowWildcardSubdomain {\n\t\treturn hostNameRegex.MatchString(s)\n\t}\n\treturn nameRegex.MatchString(s)\n}\n\nfunc validateHostname(s string, allowWildcardSubdomain bool) bool {\n\t// Slightly stricter than PunyCodeProfile\n\tidnaProfile := idna.New(\n\t\tidna.ValidateLabels(true),\n\t\tidna.VerifyDNSLength(true))\n\n\tpuny, err := idnaProfile.ToASCII(s)\n\treturn err == nil && validateName(puny, allowWildcardSubdomain)\n}\n\nfunc routeDnsCommand(c *cli.Context) error {\n\tif c.NArg() != 2 {\n\t\treturn cliutil.UsageError(`This command expects the format \"cloudflared tunnel route dns <tunnel name/id> <hostname>\"`)\n\t}\n\treturn routeCommand(c, \"dns\")\n}\n\nfunc routeLbCommand(c *cli.Context) error {\n\tif c.NArg() != 3 {\n\t\treturn cliutil.UsageError(`This command expects the format \"cloudflared tunnel route lb <tunnel name/id> <hostname> <load balancer pool>\"`)\n\t}\n\treturn routeCommand(c, \"lb\")\n}\n\nfunc routeCommand(c *cli.Context, routeType string) error {\n\tsc, err := newSubcommandContext(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ttunnelID, err := sc.findID(c.Args().Get(0))\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar route cfapi.HostnameRoute\n\tswitch routeType {\n\tcase \"dns\":\n\t\troute, err = dnsRouteFromArg(c, c.Bool(overwriteDNSFlagName))\n\tcase \"lb\":\n\t\troute, err = lbRouteFromArg(c)\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tres, err := sc.route(tunnelID, route)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tsc.log.Info().Str(LogFieldTunnelID, tunnelID.String()).Msg(res.SuccessSummary())\n\treturn nil\n}\n\nfunc commandHelpTemplate() string {\n\tvar parentFlagsHelp string\n\tfor _, f := range configureCloudflaredFlags(false) {\n\t\tparentFlagsHelp += fmt.Sprintf(\" %s\\n\\t\", f)\n\t}\n\tfor _, f := range cliutil.ConfigureLoggingFlags(false) {\n\t\tparentFlagsHelp += fmt.Sprintf(\" %s\\n\\t\", f)\n\t}\n\tconst template = `NAME:\n\t{{.HelpName}} - {{.Usage}}\n\nUSAGE:\n\t{{.UsageText}}\n\nDESCRIPTION:\n\t{{.Description}}\n\nTUNNEL COMMAND OPTIONS:\n\t%s\nSUBCOMMAND OPTIONS:\n\t{{range .VisibleFlags}}{{.}}\n\t{{end}}\n`\n\treturn fmt.Sprintf(template, parentFlagsHelp)\n}\n\nfunc buildDiagCommand() *cli.Command {\n\treturn &cli.Command{\n\t\tName:        \"diag\",\n\t\tAction:      cliutil.ConfiguredAction(diagCommand),\n\t\tUsage:       \"Creates a diagnostic report from a local cloudflared instance\",\n\t\tUsageText:   \"cloudflared tunnel [tunnel command options] diag [subcommand options]\",\n\t\tDescription: \"cloudflared tunnel diag will create a diagnostic report of a local cloudflared instance. The diagnostic procedure collects: logs, metrics, system information, traceroute to Cloudflare Edge, and runtime information. Since there may be multiple instances of cloudflared running the --metrics option may be provided to target a specific instance.\",\n\t\tFlags: []cli.Flag{\n\t\t\tmetricsFlag,\n\t\t\tdiagContainerFlag,\n\t\t\tdiagPodFlag,\n\t\t\tnoDiagLogsFlag,\n\t\t\tnoDiagMetricsFlag,\n\t\t\tnoDiagSystemFlag,\n\t\t\tnoDiagRuntimeFlag,\n\t\t\tnoDiagNetworkFlag,\n\t\t},\n\t\tCustomHelpTemplate: commandHelpTemplate(),\n\t}\n}\n\nfunc diagCommand(ctx *cli.Context) error {\n\tsctx, err := newSubcommandContext(ctx)\n\tif err != nil {\n\t\treturn err\n\t}\n\tlog := sctx.log\n\toptions := diagnostic.Options{\n\t\tKnownAddresses: metrics.GetMetricsKnownAddresses(metrics.Runtime),\n\t\tAddress:        sctx.c.String(flags.Metrics),\n\t\tContainerID:    sctx.c.String(diagContainerIDFlagName),\n\t\tPodID:          sctx.c.String(diagPodFlagName),\n\t\tToggles: diagnostic.Toggles{\n\t\t\tNoDiagLogs:    sctx.c.Bool(noDiagLogsFlagName),\n\t\t\tNoDiagMetrics: sctx.c.Bool(noDiagMetricsFlagName),\n\t\t\tNoDiagSystem:  sctx.c.Bool(noDiagSystemFlagName),\n\t\t\tNoDiagRuntime: sctx.c.Bool(noDiagRuntimeFlagName),\n\t\t\tNoDiagNetwork: sctx.c.Bool(noDiagNetworkFlagName),\n\t\t},\n\t}\n\n\tif options.Address == \"\" {\n\t\tlog.Info().Msg(\"If your instance is running in a Docker/Kubernetes environment you need to setup port forwarding for your application.\")\n\t}\n\n\tstates, err := diagnostic.RunDiagnostic(log, options)\n\n\tif errors.Is(err, diagnostic.ErrMetricsServerNotFound) {\n\t\tlog.Warn().Msg(\"No instances found\")\n\t\treturn nil\n\t}\n\tif errors.Is(err, diagnostic.ErrMultipleMetricsServerFound) {\n\t\tif states != nil {\n\t\t\tlog.Info().Msgf(\"Found multiple instances running:\")\n\t\t\tfor _, state := range states {\n\t\t\t\tlog.Info().Msgf(\"Instance: tunnel-id=%s connector-id=%s metrics-address=%s\", state.TunnelID, state.ConnectorID, state.URL.String())\n\t\t\t}\n\t\t\tlog.Info().Msgf(\"To select one instance use the option --metrics\")\n\t\t}\n\t\treturn nil\n\t}\n\n\tif errors.Is(err, diagnostic.ErrLogConfigurationIsInvalid) {\n\t\tlog.Info().Msg(\"Couldn't extract logs from the instance. If the instance is running in a containerized environment use the option --diag-container-id or --diag-pod-id. If there is no logging configuration use --no-diag-logs.\")\n\t}\n\n\tif err != nil {\n\t\tlog.Warn().Msg(\"Diagnostic completed with one or more errors\")\n\t} else {\n\t\tlog.Info().Msg(\"Diagnostic completed\")\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/subcommands_test.go",
    "content": "package tunnel\n\nimport (\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/google/uuid\"\n\thomedir \"github.com/mitchellh/go-homedir\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/cloudflare/cloudflared/cfapi\"\n\t\"github.com/cloudflare/cloudflared/connection\"\n)\n\nfunc Test_fmtConnections(t *testing.T) {\n\ttype args struct {\n\t\tconnections []cfapi.Connection\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"empty\",\n\t\t\targs: args{\n\t\t\t\tconnections: []cfapi.Connection{},\n\t\t\t},\n\t\t\twant: \"\",\n\t\t},\n\t\t{\n\t\t\tname: \"trivial\",\n\t\t\targs: args{\n\t\t\t\tconnections: []cfapi.Connection{\n\t\t\t\t\t{\n\t\t\t\t\t\tColoName: \"DFW\",\n\t\t\t\t\t\tID:       uuid.MustParse(\"ea550130-57fd-4463-aab1-752822231ddd\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: \"1xDFW\",\n\t\t},\n\t\t{\n\t\t\tname: \"with a pending reconnect\",\n\t\t\targs: args{\n\t\t\t\tconnections: []cfapi.Connection{\n\t\t\t\t\t{\n\t\t\t\t\t\tColoName:           \"DFW\",\n\t\t\t\t\t\tID:                 uuid.MustParse(\"ea550130-57fd-4463-aab1-752822231ddd\"),\n\t\t\t\t\t\tIsPendingReconnect: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: \"\",\n\t\t},\n\t\t{\n\t\t\tname: \"many colos\",\n\t\t\targs: args{\n\t\t\t\tconnections: []cfapi.Connection{\n\t\t\t\t\t{\n\t\t\t\t\t\tColoName: \"YRV\",\n\t\t\t\t\t\tID:       uuid.MustParse(\"ea550130-57fd-4463-aab1-752822231ddd\"),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tColoName: \"DFW\",\n\t\t\t\t\t\tID:       uuid.MustParse(\"c13c0b3b-0fbf-453c-8169-a1990fced6d0\"),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tColoName: \"ATL\",\n\t\t\t\t\t\tID:       uuid.MustParse(\"70c90639-e386-4e8d-9a4e-7f046d70e63f\"),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tColoName: \"DFW\",\n\t\t\t\t\t\tID:       uuid.MustParse(\"30ad6251-0305-4635-a670-d3994f474981\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: \"1xATL, 2xDFW, 1xYRV\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := fmtConnections(tt.args.connections, false); got != tt.want {\n\t\t\t\tt.Errorf(\"fmtConnections() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestTunnelfilePath(t *testing.T) {\n\ttunnelID, err := uuid.Parse(\"f48d8918-bc23-4647-9d48-082c5b76de65\")\n\tassert.NoError(t, err)\n\toriginCertDir := filepath.Dir(\"~/.cloudflared/cert.pem\")\n\tactual, err := tunnelFilePath(tunnelID, originCertDir)\n\tassert.NoError(t, err)\n\thomeDir, err := homedir.Dir()\n\tassert.NoError(t, err)\n\texpected := filepath.Join(homeDir, \".cloudflared\", tunnelID.String()+\".json\")\n\tassert.Equal(t, expected, actual)\n}\n\nfunc TestValidateName(t *testing.T) {\n\ttests := []struct {\n\t\tname string\n\t\twant bool\n\t}{\n\t\t{name: \"\", want: false},\n\t\t{name: \"-\", want: false},\n\t\t{name: \".\", want: false},\n\t\t{name: \"a b\", want: false},\n\t\t{name: \"a+b\", want: false},\n\t\t{name: \"-ab\", want: false},\n\n\t\t{name: \"ab\", want: true},\n\t\t{name: \"ab-c\", want: true},\n\t\t{name: \"abc.def\", want: true},\n\t\t{name: \"_ab_c.-d-ef\", want: true},\n\t}\n\tfor _, tt := range tests {\n\t\tif got := validateName(tt.name, false); got != tt.want {\n\t\t\tt.Errorf(\"validateName() = %v, want %v\", got, tt.want)\n\t\t}\n\t}\n}\n\nfunc Test_validateHostname(t *testing.T) {\n\ttype args struct {\n\t\ts                      string\n\t\tallowWildcardSubdomain bool\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant bool\n\t}{\n\t\t{\n\t\t\tname: \"Normal\",\n\t\t\targs: args{\n\t\t\t\ts:                      \"example.com\",\n\t\t\t\tallowWildcardSubdomain: true,\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"wildcard subdomain for TUN-358\",\n\t\t\targs: args{\n\t\t\t\ts:                      \"*.ehrig.io\",\n\t\t\t\tallowWildcardSubdomain: true,\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Misplaced wildcard\",\n\t\t\targs: args{\n\t\t\t\ts:                      \"subdomain.*.ehrig.io\",\n\t\t\t\tallowWildcardSubdomain: true,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Invalid domain\",\n\t\t\targs: args{\n\t\t\t\ts:                      \"..\",\n\t\t\t\tallowWildcardSubdomain: true,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Invalid domain\",\n\t\t\targs: args{\n\t\t\t\ts: \"..\",\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\tif got := validateHostname(tt.args.s, tt.args.allowWildcardSubdomain); got != tt.want {\n\t\t\t\tt.Errorf(\"validateHostname() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc Test_TunnelToken(t *testing.T) {\n\ttoken, err := ParseToken(\"aabc\")\n\trequire.Error(t, err)\n\trequire.Nil(t, token)\n\n\texpectedToken := &connection.TunnelToken{\n\t\tAccountTag:   \"abc\",\n\t\tTunnelSecret: []byte(\"secret\"),\n\t\tTunnelID:     uuid.New(),\n\t}\n\n\ttokenJsonStr, err := json.Marshal(expectedToken)\n\trequire.NoError(t, err)\n\n\ttoken64 := base64.StdEncoding.EncodeToString(tokenJsonStr)\n\n\ttoken, err = ParseToken(token64)\n\trequire.NoError(t, err)\n\trequire.Equal(t, token, expectedToken)\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/tag.go",
    "content": "package tunnel\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\n// Restrict key names to characters allowed in an HTTP header name.\n// Restrict key values to printable characters (what is recognised as data in an HTTP header value).\nvar tagRegexp = regexp.MustCompile(\"^([a-zA-Z0-9!#$%&'*+\\\\-.^_`|~]+)=([[:print:]]+)$\")\n\nfunc NewTagFromCLI(compoundTag string) (pogs.Tag, bool) {\n\tmatches := tagRegexp.FindStringSubmatch(compoundTag)\n\tif len(matches) == 0 {\n\t\treturn pogs.Tag{}, false\n\t}\n\treturn pogs.Tag{Name: matches[1], Value: matches[2]}, true\n}\n\nfunc NewTagSliceFromCLI(tags []string) ([]pogs.Tag, error) {\n\tvar tagSlice []pogs.Tag\n\tfor _, compoundTag := range tags {\n\t\tif tag, ok := NewTagFromCLI(compoundTag); ok {\n\t\t\ttagSlice = append(tagSlice, tag)\n\t\t} else {\n\t\t\treturn nil, fmt.Errorf(\"Cannot parse tag value %s\", compoundTag)\n\t\t}\n\t}\n\treturn tagSlice, nil\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/tag_test.go",
    "content": "package tunnel\n\nimport (\n\t\"testing\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestSingleTag(t *testing.T) {\n\ttestCases := []struct {\n\t\tInput  string\n\t\tOutput pogs.Tag\n\t\tFail   bool\n\t}{\n\t\t{Input: \"x=y\", Output: pogs.Tag{Name: \"x\", Value: \"y\"}},\n\t\t{Input: \"More-Complex=Tag Values\", Output: pogs.Tag{Name: \"More-Complex\", Value: \"Tag Values\"}},\n\t\t{Input: \"First=Equals=Wins\", Output: pogs.Tag{Name: \"First\", Value: \"Equals=Wins\"}},\n\t\t{Input: \"x=\", Fail: true},\n\t\t{Input: \"=y\", Fail: true},\n\t\t{Input: \"=\", Fail: true},\n\t\t{Input: \"No spaces allowed=in key names\", Fail: true},\n\t\t{Input: \"omg\\nwtf=bbq\", Fail: true},\n\t}\n\tfor i, testCase := range testCases {\n\t\ttag, ok := NewTagFromCLI(testCase.Input)\n\t\tassert.Equalf(t, !testCase.Fail, ok, \"mismatched success for test case %d\", i)\n\t\tassert.Equalf(t, testCase.Output, tag, \"mismatched output for test case %d\", i)\n\t}\n}\n\nfunc TestTagSlice(t *testing.T) {\n\ttagSlice, err := NewTagSliceFromCLI([]string{\"a=b\", \"c=d\", \"e=f\"})\n\tassert.NoError(t, err)\n\tassert.Len(t, tagSlice, 3)\n\tassert.Equal(t, \"a\", tagSlice[0].Name)\n\tassert.Equal(t, \"b\", tagSlice[0].Value)\n\tassert.Equal(t, \"c\", tagSlice[1].Name)\n\tassert.Equal(t, \"d\", tagSlice[1].Value)\n\tassert.Equal(t, \"e\", tagSlice[2].Name)\n\tassert.Equal(t, \"f\", tagSlice[2].Value)\n\n\ttagSlice, err = NewTagSliceFromCLI([]string{\"a=b\", \"=\", \"e=f\"})\n\tassert.Error(t, err)\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/teamnet_subcommands.go",
    "content": "package tunnel\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"text/tabwriter\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/cloudflare/cloudflared/cfapi\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/updater\"\n)\n\nvar (\n\tvnetFlag = &cli.StringFlag{\n\t\tName:    \"vnet\",\n\t\tAliases: []string{\"vn\"},\n\t\tUsage:   \"The ID or name of the virtual network to which the route is associated to.\",\n\t}\n\n\terrAddRoute = errors.New(\"You must supply exactly one argument, the ID or CIDR of the route you want to delete\")\n)\n\nfunc buildRouteIPSubcommand() *cli.Command {\n\treturn &cli.Command{\n\t\tName:      \"ip\",\n\t\tUsage:     \"Configure and query Cloudflare WARP routing to private IP networks made available through Cloudflare Tunnels.\",\n\t\tUsageText: \"cloudflared tunnel [--config FILEPATH] route COMMAND [arguments...]\",\n\t\tDescription: `cloudflared can provision routes for any IP space in your corporate network. Users enrolled in\nyour Cloudflare for Teams organization can reach those IPs through the Cloudflare WARP\nclient. You can then configure L7/L4 filtering on https://one.dash.cloudflare.com to\ndetermine who can reach certain routes.\nBy default IP routes all exist within a single virtual network. If you use the same IP\nspace(s) in different physical private networks, all meant to be reachable via IP routes,\nthen you have to manage the ambiguous IP routes by associating them to virtual networks.\nSee \"cloudflared tunnel vnet --help\" for more information.`,\n\t\tSubcommands: []*cli.Command{\n\t\t\t{\n\t\t\t\tName:      \"add\",\n\t\t\t\tAction:    cliutil.ConfiguredAction(addRouteCommand),\n\t\t\t\tUsage:     \"Add a new network to the routing table reachable via a Tunnel\",\n\t\t\t\tUsageText: \"cloudflared tunnel [--config FILEPATH] route ip add [flags] [CIDR] [TUNNEL] [COMMENT?]\",\n\t\t\t\tDescription: `Adds a network IP route space (represented as a CIDR) to your routing table.\nThat network IP space becomes reachable for requests egressing from a user's machine\nas long as it is using Cloudflare WARP client and is enrolled in the same account\nthat is running the Tunnel chosen here. Further, those requests will be proxied to\nthe specified Tunnel, and reach an IP in the given CIDR, as long as that IP is\nreachable from cloudflared.\nIf the CIDR exists in more than one private network, to be connected with Cloudflare\nTunnels, then you have to manage those IP routes with virtual networks (see\n\"cloudflared tunnel vnet --help)\". In those cases, you then have to tell\nwhich virtual network's routing table you want to add the route to with:\n\"cloudflared tunnel route ip add --vnet [ID/name] [CIDR] [TUNNEL]\".`,\n\t\t\t\tFlags: []cli.Flag{vnetFlag},\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:        \"show\",\n\t\t\t\tAliases:     []string{\"list\"},\n\t\t\t\tAction:      cliutil.ConfiguredAction(showRoutesCommand),\n\t\t\t\tUsage:       \"Show the routing table\",\n\t\t\t\tUsageText:   \"cloudflared tunnel [--config FILEPATH] route ip show [flags]\",\n\t\t\t\tDescription: `Shows your organization private routing table. You can use flags to filter the results.`,\n\t\t\t\tFlags:       showRoutesFlags(),\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:      \"delete\",\n\t\t\t\tAction:    cliutil.ConfiguredAction(deleteRouteCommand),\n\t\t\t\tUsage:     \"Delete a row from your organization's private routing table\",\n\t\t\t\tUsageText: \"cloudflared tunnel [--config FILEPATH] route ip delete [flags] [Route ID or CIDR]\",\n\t\t\t\tDescription: `Deletes the row for the given route ID from your routing table. That portion of your network\nwill no longer be reachable.`,\n\t\t\t\tFlags: []cli.Flag{vnetFlag},\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:      \"get\",\n\t\t\t\tAction:    cliutil.ConfiguredAction(getRouteByIPCommand),\n\t\t\t\tUsage:     \"Check which row of the routing table matches a given IP.\",\n\t\t\t\tUsageText: \"cloudflared tunnel [--config FILEPATH] route ip get [flags] [IP]\",\n\t\t\t\tDescription: `Checks which row of the routing table will be used to proxy a given IP. This helps check\nand validate your config. Note that if you use virtual networks, then you have\nto tell which virtual network whose routing table you want to use.`,\n\t\t\t\tFlags: []cli.Flag{vnetFlag},\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc showRoutesFlags() []cli.Flag {\n\tflags := make([]cli.Flag, 0)\n\tflags = append(flags, cfapi.IpRouteFilterFlags...)\n\tflags = append(flags, outputFormatFlag)\n\treturn flags\n}\n\nfunc showRoutesCommand(c *cli.Context) error {\n\tsc, err := newSubcommandContext(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfilter, err := cfapi.NewIpRouteFilterFromCLI(c)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"invalid config for routing filters\")\n\t}\n\n\twarningChecker := updater.StartWarningCheck(c)\n\tdefer warningChecker.LogWarningIfAny(sc.log)\n\n\troutes, err := sc.listRoutes(filter)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif outputFormat := c.String(outputFormatFlag.Name); outputFormat != \"\" {\n\t\treturn renderOutput(outputFormat, routes)\n\t}\n\n\tif len(routes) > 0 {\n\t\tformatAndPrintRouteList(routes)\n\t} else {\n\t\tfmt.Println(\"No routes were found for the given filter flags. You can use 'cloudflared tunnel route ip add' to add a route.\")\n\t}\n\n\treturn nil\n}\n\nfunc addRouteCommand(c *cli.Context) error {\n\tsc, err := newSubcommandContext(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif c.NArg() < 2 {\n\t\treturn errors.New(\"You must supply at least 2 arguments, first the network you wish to route (in CIDR form e.g. 1.2.3.4/32) and then the tunnel ID to proxy with\")\n\t}\n\n\targs := c.Args()\n\n\t_, network, err := net.ParseCIDR(args.Get(0))\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Invalid network CIDR\")\n\t}\n\tif network == nil {\n\t\treturn errors.New(\"Invalid network CIDR\")\n\t}\n\n\ttunnelRef := args.Get(1)\n\ttunnelID, err := sc.findID(tunnelRef)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Invalid tunnel\")\n\t}\n\n\tcomment := \"\"\n\tif c.NArg() >= 3 {\n\t\tcomment = args.Get(2)\n\t}\n\n\tvar vnetId *uuid.UUID\n\tif c.IsSet(vnetFlag.Name) {\n\t\tid, err := getVnetId(sc, c.String(vnetFlag.Name))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tvnetId = &id\n\t}\n\n\t_, err = sc.addRoute(cfapi.NewRoute{\n\t\tComment:  comment,\n\t\tNetwork:  *network,\n\t\tTunnelID: tunnelID,\n\t\tVNetID:   vnetId,\n\t})\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"API error\")\n\t}\n\tfmt.Printf(\"Successfully added route for %s over tunnel %s\\n\", network, tunnelID)\n\treturn nil\n}\n\nfunc deleteRouteCommand(c *cli.Context) error {\n\tsc, err := newSubcommandContext(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif c.NArg() != 1 {\n\t\treturn errAddRoute\n\t}\n\n\tvar routeId uuid.UUID\n\trouteId, err = uuid.Parse(c.Args().First())\n\tif err != nil {\n\t\t_, network, err := net.ParseCIDR(c.Args().First())\n\t\tif err != nil || network == nil {\n\t\t\treturn errAddRoute\n\t\t}\n\n\t\tvar vnetId *uuid.UUID\n\t\tif c.IsSet(vnetFlag.Name) {\n\t\t\tid, err := getVnetId(sc, c.String(vnetFlag.Name))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tvnetId = &id\n\t\t}\n\n\t\trouteId, err = sc.getRouteId(*network, vnetId)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif err := sc.deleteRoute(routeId); err != nil {\n\t\treturn errors.Wrap(err, \"API error\")\n\t}\n\tfmt.Printf(\"Successfully deleted route with ID %s\\n\", routeId)\n\treturn nil\n}\n\nfunc getRouteByIPCommand(c *cli.Context) error {\n\tsc, err := newSubcommandContext(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif c.NArg() != 1 {\n\t\treturn errors.New(\"You must supply exactly one argument, an IP whose route will be queried (e.g. 1.2.3.4 or 2001:0db8:::7334)\")\n\t}\n\n\tipInput := c.Args().First()\n\tip := net.ParseIP(ipInput)\n\tif ip == nil {\n\t\treturn fmt.Errorf(\"Invalid IP %s\", ipInput)\n\t}\n\n\tparams := cfapi.GetRouteByIpParams{\n\t\tIp: ip,\n\t}\n\n\tif c.IsSet(vnetFlag.Name) {\n\t\tvnetId, err := getVnetId(sc, c.String(vnetFlag.Name))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tparams.VNetID = &vnetId\n\t}\n\n\troute, err := sc.getRouteByIP(params)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"API error\")\n\t}\n\tif route.IsZero() {\n\t\tfmt.Printf(\"No route matches the IP %s\\n\", ip)\n\t} else {\n\t\tformatAndPrintRouteList([]*cfapi.DetailedRoute{&route})\n\t}\n\treturn nil\n}\n\nfunc formatAndPrintRouteList(routes []*cfapi.DetailedRoute) {\n\tconst (\n\t\tminWidth = 0\n\t\ttabWidth = 8\n\t\tpadding  = 1\n\t\tpadChar  = ' '\n\t\tflags    = 0\n\t)\n\n\twriter := tabwriter.NewWriter(os.Stdout, minWidth, tabWidth, padding, padChar, flags)\n\tdefer writer.Flush()\n\n\t// Print column headers with tabbed columns\n\t_, _ = fmt.Fprintln(writer, \"ID\\tNETWORK\\tVIRTUAL NET ID\\tCOMMENT\\tTUNNEL ID\\tTUNNEL NAME\\tCREATED\\tDELETED\\t\")\n\n\t// Loop through routes, create formatted string for each, and print using tabwriter\n\tfor _, route := range routes {\n\t\tformattedStr := route.TableString()\n\t\t_, _ = fmt.Fprintln(writer, formattedStr)\n\t}\n}\n"
  },
  {
    "path": "cmd/cloudflared/tunnel/vnets_subcommands.go",
    "content": "package tunnel\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"text/tabwriter\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/cloudflare/cloudflared/cfapi\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/updater\"\n)\n\nvar (\n\tmakeDefaultFlag = &cli.BoolFlag{\n\t\tName:    \"default\",\n\t\tAliases: []string{\"d\"},\n\t\tUsage: \"The virtual network becomes the default one for the account. This means that all operations that \" +\n\t\t\t\"omit a virtual network will now implicitly be using this virtual network (i.e., the default one) such \" +\n\t\t\t\"as new IP routes that are created. When this flag is not set, the virtual network will not become the \" +\n\t\t\t\"default one in the account.\",\n\t}\n\tnewNameFlag = &cli.StringFlag{\n\t\tName:    \"name\",\n\t\tAliases: []string{\"n\"},\n\t\tUsage:   \"The new name for the virtual network.\",\n\t}\n\tnewCommentFlag = &cli.StringFlag{\n\t\tName:    \"comment\",\n\t\tAliases: []string{\"c\"},\n\t\tUsage:   \"A new comment describing the purpose of the virtual network.\",\n\t}\n\tvnetForceDeleteFlag = &cli.BoolFlag{\n\t\tName:    \"force\",\n\t\tAliases: []string{\"f\"},\n\t\tUsage: \"Force the deletion of the virtual network even if it is being relied upon by other resources. Those\" +\n\t\t\t\"resources will either be deleted (e.g. IP Routes) or moved to the current default virutal network.\",\n\t}\n)\n\nfunc buildVirtualNetworkSubcommand(hidden bool) *cli.Command {\n\treturn &cli.Command{\n\t\tName:      \"vnet\",\n\t\tUsage:     \"Configure and query virtual networks to manage private IP routes with overlapping IPs.\",\n\t\tUsageText: \"cloudflared tunnel [--config FILEPATH] network COMMAND [arguments...]\",\n\t\tDescription: `cloudflared allows to manage IP routes that expose origins in your private network space via their IP directly\nto clients outside (e.g. using WARP client) --- those are configurable via \"cloudflared tunnel route ip\" commands.\nBy default, all those IP routes live in the same virtual network. Managing virtual networks (e.g. by creating a\nnew one) becomes relevant when you have different private networks that have overlapping IPs. E.g.: if you have\na private network A running Tunnel 1, and private network B running Tunnel 2, it is possible that both Tunnels\nexpose the same IP space (say 10.0.0.0/8); to handle that, you have to add each IP Route (one that points to\nTunnel 1 and another that points to Tunnel 2) in different Virtual Networks. That way, if your clients are on\nVirtual Network X, they will see Tunnel 1 (via Route A) and not see Tunnel 2 (since its Route B is associated\nto another Virtual Network Y).`,\n\t\tHidden: hidden,\n\t\tSubcommands: []*cli.Command{\n\t\t\t{\n\t\t\t\tName:      \"add\",\n\t\t\t\tAction:    cliutil.ConfiguredAction(addVirtualNetworkCommand),\n\t\t\t\tUsage:     \"Add a new virtual network to which IP routes can be attached\",\n\t\t\t\tUsageText: \"cloudflared tunnel [--config FILEPATH] network add [flags] NAME [\\\"comment\\\"]\",\n\t\t\t\tDescription: `Adds a new virtual network. You can then attach IP routes to this virtual network with \"cloudflared tunnel route ip\"\ncommands. By doing so, such route(s) become segregated from route(s) in another virtual networks. Note that all\nroutes exist within some virtual network. If you do not specify any, then the system pre-creates a default virtual\nnetwork to which all routes belong. That is fine if you do not have overlapping IPs within different physical\nprivate networks in your infrastructure exposed via Cloudflare Tunnel. Note: if a virtual network is added as\nthe new default, then the previous existing default virtual network will be automatically modified to no longer\nbe the current default.`,\n\t\t\t\tFlags:  []cli.Flag{makeDefaultFlag},\n\t\t\t\tHidden: hidden,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:        \"list\",\n\t\t\t\tAction:      cliutil.ConfiguredAction(listVirtualNetworksCommand),\n\t\t\t\tUsage:       \"Lists the virtual networks\",\n\t\t\t\tUsageText:   \"cloudflared tunnel [--config FILEPATH] network list [flags]\",\n\t\t\t\tDescription: \"Lists the virtual networks based on the given filter flags.\",\n\t\t\t\tFlags:       listVirtualNetworksFlags(),\n\t\t\t\tHidden:      hidden,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:      \"delete\",\n\t\t\t\tAction:    cliutil.ConfiguredAction(deleteVirtualNetworkCommand),\n\t\t\t\tUsage:     \"Delete a virtual network\",\n\t\t\t\tUsageText: \"cloudflared tunnel [--config FILEPATH] network delete VIRTUAL_NETWORK\",\n\t\t\t\tDescription: `Deletes the virtual network (given its ID or name). This is only possible if that virtual network is unused. \nA virtual network may be used by IP routes or by WARP devices.`,\n\t\t\t\tFlags:  []cli.Flag{vnetForceDeleteFlag},\n\t\t\t\tHidden: hidden,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:      \"update\",\n\t\t\t\tAction:    cliutil.ConfiguredAction(updateVirtualNetworkCommand),\n\t\t\t\tUsage:     \"Update a virtual network\",\n\t\t\t\tUsageText: \"cloudflared tunnel [--config FILEPATH] network update [flags] VIRTUAL_NETWORK\",\n\t\t\t\tDescription: `Updates the virtual network (given its ID or name). If this virtual network is updated to become the new\ndefault, then the previously existing default virtual network will also be modified to no longer be the default.\nYou cannot update a virtual network to not be the default anymore directly. Instead, you should create a new\ndefault or update an existing one to become the default.`,\n\t\t\t\tFlags:  []cli.Flag{newNameFlag, newCommentFlag, makeDefaultFlag},\n\t\t\t\tHidden: hidden,\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc listVirtualNetworksFlags() []cli.Flag {\n\tflags := make([]cli.Flag, 0)\n\tflags = append(flags, cfapi.VnetFilterFlags...)\n\tflags = append(flags, outputFormatFlag)\n\treturn flags\n}\n\nfunc addVirtualNetworkCommand(c *cli.Context) error {\n\tsc, err := newSubcommandContext(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif c.NArg() < 1 {\n\t\treturn errors.New(\"You must supply at least 1 argument, the name of the virtual network you wish to add.\")\n\t}\n\n\twarningChecker := updater.StartWarningCheck(c)\n\tdefer warningChecker.LogWarningIfAny(sc.log)\n\n\targs := c.Args()\n\n\tname := args.Get(0)\n\n\tcomment := \"\"\n\tif c.NArg() >= 2 {\n\t\tcomment = args.Get(1)\n\t}\n\n\tnewVnet := cfapi.NewVirtualNetwork{\n\t\tName:      name,\n\t\tComment:   comment,\n\t\tIsDefault: c.Bool(makeDefaultFlag.Name),\n\t}\n\tcreatedVnet, err := sc.addVirtualNetwork(newVnet)\n\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Could not add virtual network\")\n\t}\n\n\textraMsg := \"\"\n\tif createdVnet.IsDefault {\n\t\textraMsg = \" (as the new default for this account) \"\n\t}\n\tfmt.Printf(\n\t\t\"Successfully added virtual 'network' %s with ID: %s%s\\n\"+\n\t\t\t\"You can now add IP routes attached to this virtual network. See `cloudflared tunnel route ip add -help`\\n\",\n\t\tname, createdVnet.ID, extraMsg,\n\t)\n\treturn nil\n}\n\nfunc listVirtualNetworksCommand(c *cli.Context) error {\n\tsc, err := newSubcommandContext(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\twarningChecker := updater.StartWarningCheck(c)\n\tdefer warningChecker.LogWarningIfAny(sc.log)\n\n\tfilter, err := cfapi.NewFromCLI(c)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"invalid flags for filtering virtual networks\")\n\t}\n\n\tvnets, err := sc.listVirtualNetworks(filter)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif outputFormat := c.String(outputFormatFlag.Name); outputFormat != \"\" {\n\t\treturn renderOutput(outputFormat, vnets)\n\t}\n\n\tif len(vnets) > 0 {\n\t\tformatAndPrintVnetsList(vnets)\n\t} else {\n\t\tfmt.Println(\"No virtual networks were found for the given filter flags. You can use 'cloudflared tunnel vnet add' to add a virtual network.\")\n\t}\n\n\treturn nil\n}\n\nfunc deleteVirtualNetworkCommand(c *cli.Context) error {\n\tsc, err := newSubcommandContext(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif c.NArg() < 1 {\n\t\treturn errors.New(\"You must supply exactly one argument, either the ID or name of the virtual network to delete\")\n\t}\n\n\tinput := c.Args().Get(0)\n\tvnetId, err := getVnetId(sc, input)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tforceDelete := false\n\tif c.IsSet(vnetForceDeleteFlag.Name) {\n\t\tforceDelete = c.Bool(vnetForceDeleteFlag.Name)\n\t}\n\n\tif err := sc.deleteVirtualNetwork(vnetId, forceDelete); err != nil {\n\t\treturn errors.Wrap(err, \"API error\")\n\t}\n\tfmt.Printf(\"Successfully deleted virtual network '%s'\\n\", input)\n\treturn nil\n}\n\nfunc updateVirtualNetworkCommand(c *cli.Context) error {\n\tsc, err := newSubcommandContext(c)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif c.NArg() != 1 {\n\t\treturn errors.New(\" You must supply exactly one argument, either the ID or (current) name of the virtual network to update\")\n\t}\n\n\tinput := c.Args().Get(0)\n\tvnetId, err := getVnetId(sc, input)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tupdates := cfapi.UpdateVirtualNetwork{}\n\n\tif c.IsSet(newNameFlag.Name) {\n\t\tnewName := c.String(newNameFlag.Name)\n\t\tupdates.Name = &newName\n\t}\n\tif c.IsSet(newCommentFlag.Name) {\n\t\tnewComment := c.String(newCommentFlag.Name)\n\t\tupdates.Comment = &newComment\n\t}\n\tif c.IsSet(makeDefaultFlag.Name) {\n\t\tisDefault := c.Bool(makeDefaultFlag.Name)\n\t\tupdates.IsDefault = &isDefault\n\t}\n\n\tif err := sc.updateVirtualNetwork(vnetId, updates); err != nil {\n\t\treturn errors.Wrap(err, \"API error\")\n\t}\n\tfmt.Printf(\"Successfully updated virtual network '%s'\\n\", input)\n\treturn nil\n}\n\nfunc getVnetId(sc *subcommandContext, input string) (uuid.UUID, error) {\n\tval, err := uuid.Parse(input)\n\tif err == nil {\n\t\treturn val, nil\n\t}\n\n\tfilter := cfapi.NewVnetFilter()\n\tfilter.WithDeleted(false)\n\tfilter.ByName(input)\n\n\tvnets, err := sc.listVirtualNetworks(filter)\n\tif err != nil {\n\t\treturn uuid.Nil, err\n\t}\n\n\tif len(vnets) != 1 {\n\t\treturn uuid.Nil, fmt.Errorf(\"there should only be 1 non-deleted virtual network named %s\", input)\n\t}\n\n\treturn vnets[0].ID, nil\n}\n\nfunc formatAndPrintVnetsList(vnets []*cfapi.VirtualNetwork) {\n\tconst (\n\t\tminWidth = 0\n\t\ttabWidth = 8\n\t\tpadding  = 1\n\t\tpadChar  = ' '\n\t\tflags    = 0\n\t)\n\n\twriter := tabwriter.NewWriter(os.Stdout, minWidth, tabWidth, padding, padChar, flags)\n\tdefer writer.Flush()\n\n\t_, _ = fmt.Fprintln(writer, \"ID\\tNAME\\tIS DEFAULT\\tCOMMENT\\tCREATED\\tDELETED\\t\")\n\n\tfor _, virtualNetwork := range vnets {\n\t\tformattedStr := virtualNetwork.TableString()\n\t\t_, _ = fmt.Fprintln(writer, formattedStr)\n\t}\n}\n"
  },
  {
    "path": "cmd/cloudflared/updater/check.go",
    "content": "package updater\n\nimport (\n\t\"github.com/rs/zerolog\"\n\t\"github.com/urfave/cli/v2\"\n)\n\ntype VersionWarningChecker struct {\n\twarningChan chan string\n}\n\nfunc StartWarningCheck(c *cli.Context) VersionWarningChecker {\n\tchecker := VersionWarningChecker{\n\t\twarningChan: make(chan string),\n\t}\n\n\tgo func() {\n\t\toptions := updateOptions{\n\t\t\tupdateDisabled:  true,\n\t\t\tisBeta:          c.Bool(\"beta\"),\n\t\t\tisStaging:       c.Bool(\"staging\"),\n\t\t\tisForced:        false,\n\t\t\tintendedVersion: \"\",\n\t\t}\n\t\tcheckResult, err := CheckForUpdate(options)\n\t\tif err == nil {\n\t\t\tchecker.warningChan <- checkResult.UserMessage()\n\t\t}\n\t\tclose(checker.warningChan)\n\t}()\n\n\treturn checker\n}\n\nfunc (checker VersionWarningChecker) getWarning() string {\n\tselect {\n\tcase message := <-checker.warningChan:\n\t\treturn message\n\tdefault:\n\t\t// No feedback on time, we don't wait for it, since this is best-effort.\n\t\treturn \"\"\n\t}\n}\n\nfunc (checker VersionWarningChecker) LogWarningIfAny(log *zerolog.Logger) {\n\tif warning := checker.getWarning(); warning != \"\" {\n\t\tlog.Warn().Msg(warning)\n\t}\n}\n"
  },
  {
    "path": "cmd/cloudflared/updater/service.go",
    "content": "package updater\n\n// CheckResult is the behaviour resulting from checking in with the Update Service\ntype CheckResult interface {\n\tApply() error\n\tVersion() string\n\tUserMessage() string\n}\n\n// Service is the functions to get check for new updates\ntype Service interface {\n\tCheck() (CheckResult, error)\n}\n\nconst (\n\t// OSKeyName is the url parameter key to send to the checkin API for the operating system of the local cloudflared (e.g. windows, darwin, linux)\n\tOSKeyName = \"os\"\n\n\t// ArchitectureKeyName is the url parameter key to send to the checkin API for the architecture of the local cloudflared (e.g. amd64, x86)\n\tArchitectureKeyName = \"arch\"\n\n\t// BetaKeyName is the url parameter key to send to the checkin API to signal if the update should be a beta version or not\n\tBetaKeyName = \"beta\"\n\n\t// VersionKeyName is the url parameter key to send to the checkin API to specific what version to upgrade or downgrade to\n\tVersionKeyName = \"version\"\n\n\t// ClientVersionName is the url parameter key to send the version that this cloudflared is currently running with\n\tClientVersionName = \"clientVersion\"\n)\n"
  },
  {
    "path": "cmd/cloudflared/updater/update.go",
    "content": "package updater\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/facebookgo/grace/gracenet\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/urfave/cli/v2\"\n\t\"golang.org/x/term\"\n\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n\tcfdflags \"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/logger\"\n)\n\nconst (\n\tDefaultCheckUpdateFreq        = time.Hour * 24\n\tnoUpdateInShellMessage        = \"cloudflared will not automatically update when run from the shell. To enable auto-updates, run cloudflared as a service: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/configure-tunnels/local-management/as-a-service/\"\n\tnoUpdateOnWindowsMessage      = \"cloudflared will not automatically update on Windows systems.\"\n\tnoUpdateManagedPackageMessage = \"cloudflared will not automatically update if installed by a package manager.\"\n\tisManagedInstallFile          = \".installedFromPackageManager\"\n\tUpdateURL                     = \"https://update.argotunnel.com\"\n\tStagingUpdateURL              = \"https://staging-update.argotunnel.com\"\n\n\tLogFieldVersion = \"version\"\n)\n\nvar (\n\tbuildInfo              *cliutil.BuildInfo\n\tBuiltForPackageManager = \"\"\n)\n\n// BinaryUpdated implements ExitCoder interface, the app will exit with status code 11\n// https://pkg.go.dev/github.com/urfave/cli/v2?tab=doc#ExitCoder\n// nolint: errname\ntype statusSuccess struct {\n\tnewVersion string\n}\n\nfunc (u *statusSuccess) Error() string {\n\treturn fmt.Sprintf(\"cloudflared has been updated to version %s\", u.newVersion)\n}\n\nfunc (u *statusSuccess) ExitCode() int {\n\treturn 11\n}\n\n// statusError implements ExitCoder interface, the app will exit with status code 10\ntype statusError struct {\n\terr error\n}\n\nfunc (e *statusError) Error() string {\n\treturn fmt.Sprintf(\"failed to update cloudflared: %v\", e.err)\n}\n\nfunc (e *statusError) ExitCode() int {\n\treturn 10\n}\n\ntype updateOptions struct {\n\tupdateDisabled  bool\n\tisBeta          bool\n\tisStaging       bool\n\tisForced        bool\n\tintendedVersion string\n}\n\ntype UpdateOutcome struct {\n\tUpdated     bool\n\tVersion     string\n\tUserMessage string\n\tError       error\n}\n\nfunc (uo *UpdateOutcome) noUpdate() bool {\n\treturn uo.Error == nil && !uo.Updated\n}\n\nfunc Init(info *cliutil.BuildInfo) {\n\tbuildInfo = info\n}\n\nfunc CheckForUpdate(options updateOptions) (CheckResult, error) {\n\tcfdPath, err := os.Executable()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\turl := UpdateURL\n\tif options.isStaging {\n\t\turl = StagingUpdateURL\n\t}\n\n\tif runtime.GOOS == \"windows\" {\n\t\tcfdPath = encodeWindowsPath(cfdPath)\n\t}\n\n\ts := NewWorkersService(buildInfo.CloudflaredVersion, url, cfdPath, Options{IsBeta: options.isBeta,\n\t\tIsForced: options.isForced, RequestedVersion: options.intendedVersion})\n\n\treturn s.Check()\n}\n\nfunc encodeWindowsPath(path string) string {\n\t// We do this because Windows allows spaces in directories such as\n\t// Program Files but does not allow these directories to be spaced in batch files.\n\ttargetPath := strings.Replace(path, \"Program Files (x86)\", \"PROGRA~2\", -1)\n\t// This is to do the same in 32 bit systems. We do this second so that the first\n\t// replace is for x86 dirs.\n\ttargetPath = strings.Replace(targetPath, \"Program Files\", \"PROGRA~1\", -1)\n\treturn targetPath\n}\n\nfunc applyUpdate(options updateOptions, update CheckResult) UpdateOutcome {\n\tif update.Version() == \"\" || options.updateDisabled {\n\t\treturn UpdateOutcome{UserMessage: update.UserMessage()}\n\t}\n\n\terr := update.Apply()\n\tif err != nil {\n\t\treturn UpdateOutcome{Error: err}\n\t}\n\n\treturn UpdateOutcome{Updated: true, Version: update.Version(), UserMessage: update.UserMessage()}\n}\n\n// Update is the handler for the update command from the command line\nfunc Update(c *cli.Context) error {\n\tlog := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog)\n\n\tif wasInstalledFromPackageManager() {\n\t\tpackageManagerName := \"a package manager\"\n\t\tif BuiltForPackageManager != \"\" {\n\t\t\tpackageManagerName = BuiltForPackageManager\n\t\t}\n\t\tlog.Error().Msg(fmt.Sprintf(\"cloudflared was installed by %s. Please update using the same method.\", packageManagerName))\n\t\treturn nil\n\t}\n\n\tisBeta := c.Bool(\"beta\")\n\tif isBeta {\n\t\tlog.Info().Msg(\"cloudflared is set to update to the latest beta version\")\n\t}\n\n\tisStaging := c.Bool(\"staging\")\n\tif isStaging {\n\t\tlog.Info().Msg(\"cloudflared is set to update from staging\")\n\t}\n\n\tisForced := c.Bool(cfdflags.Force)\n\tif isForced {\n\t\tlog.Info().Msg(\"cloudflared is set to upgrade to the latest publish version regardless of the current version\")\n\t}\n\n\tupdateOutcome := loggedUpdate(log, updateOptions{\n\t\tupdateDisabled:  false,\n\t\tisBeta:          isBeta,\n\t\tisStaging:       isStaging,\n\t\tisForced:        isForced,\n\t\tintendedVersion: c.String(\"version\"),\n\t})\n\tif updateOutcome.Error != nil {\n\t\treturn &statusError{updateOutcome.Error}\n\t}\n\n\tif updateOutcome.noUpdate() {\n\t\tlog.Info().Str(LogFieldVersion, updateOutcome.Version).Msg(\"cloudflared is up to date\")\n\t\treturn nil\n\t}\n\n\treturn &statusSuccess{newVersion: updateOutcome.Version}\n}\n\n// Checks for an update and applies it if one is available\nfunc loggedUpdate(log *zerolog.Logger, options updateOptions) UpdateOutcome {\n\tcheckResult, err := CheckForUpdate(options)\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"update check failed\")\n\t\treturn UpdateOutcome{Error: err}\n\t}\n\n\tupdateOutcome := applyUpdate(options, checkResult)\n\tif updateOutcome.Updated {\n\t\tlog.Info().Str(LogFieldVersion, updateOutcome.Version).Msg(\"cloudflared has been updated\")\n\t}\n\tif updateOutcome.Error != nil {\n\t\tlog.Err(updateOutcome.Error).Msg(\"update failed to apply\")\n\t}\n\n\treturn updateOutcome\n}\n\n// AutoUpdater periodically checks for new version of cloudflared.\ntype AutoUpdater struct {\n\tconfigurable *configurable\n\tlisteners    *gracenet.Net\n\tlog          *zerolog.Logger\n}\n\n// AutoUpdaterConfigurable is the attributes of AutoUpdater that can be reconfigured during runtime\ntype configurable struct {\n\tenabled bool\n\tfreq    time.Duration\n}\n\nfunc NewAutoUpdater(updateDisabled bool, freq time.Duration, listeners *gracenet.Net, log *zerolog.Logger) *AutoUpdater {\n\treturn &AutoUpdater{\n\t\tconfigurable: createUpdateConfig(updateDisabled, freq, log),\n\t\tlisteners:    listeners,\n\t\tlog:          log,\n\t}\n}\n\nfunc createUpdateConfig(updateDisabled bool, freq time.Duration, log *zerolog.Logger) *configurable {\n\tif isAutoupdateEnabled(log, updateDisabled, freq) {\n\t\tlog.Info().Dur(\"autoupdateFreq\", freq).Msg(\"Autoupdate frequency is set\")\n\t\treturn &configurable{\n\t\t\tenabled: true,\n\t\t\tfreq:    freq,\n\t\t}\n\t} else {\n\t\treturn &configurable{\n\t\t\tenabled: false,\n\t\t\tfreq:    DefaultCheckUpdateFreq,\n\t\t}\n\t}\n}\n\n// Run will perodically check for cloudflared updates, download them, and then restart the current cloudflared process\n// to use the new version. It delays the first update check by the configured frequency as to not attempt a\n// download immediately and restart after starting (in the case that there is an upgrade available).\nfunc (a *AutoUpdater) Run(ctx context.Context) error {\n\tticker := time.NewTicker(a.configurable.freq)\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tcase <-ticker.C:\n\t\t}\n\t\tupdateOutcome := loggedUpdate(a.log, updateOptions{updateDisabled: !a.configurable.enabled})\n\t\tif updateOutcome.Updated {\n\t\t\tbuildInfo.CloudflaredVersion = updateOutcome.Version\n\t\t\tif IsSysV() {\n\t\t\t\t// SysV doesn't have a mechanism to keep service alive, we have to restart the process\n\t\t\t\ta.log.Info().Msg(\"Restarting service managed by SysV...\")\n\t\t\t\tpid, err := a.listeners.StartProcess()\n\t\t\t\tif err != nil {\n\t\t\t\t\ta.log.Err(err).Msg(\"Unable to restart server automatically\")\n\t\t\t\t\treturn &statusError{err: err}\n\t\t\t\t}\n\t\t\t\t// stop old process after autoupdate. Otherwise we create a new process\n\t\t\t\t// after each update\n\t\t\t\ta.log.Info().Msgf(\"PID of the new process is %d\", pid)\n\t\t\t}\n\t\t\treturn &statusSuccess{newVersion: updateOutcome.Version}\n\t\t} else if updateOutcome.UserMessage != \"\" {\n\t\t\ta.log.Warn().Msg(updateOutcome.UserMessage)\n\t\t}\n\t}\n}\n\nfunc isAutoupdateEnabled(log *zerolog.Logger, updateDisabled bool, updateFreq time.Duration) bool {\n\tif !supportAutoUpdate(log) {\n\t\treturn false\n\t}\n\treturn !updateDisabled && updateFreq != 0\n}\n\nfunc supportAutoUpdate(log *zerolog.Logger) bool {\n\tif runtime.GOOS == \"windows\" {\n\t\tlog.Info().Msg(noUpdateOnWindowsMessage)\n\t\treturn false\n\t}\n\n\tif wasInstalledFromPackageManager() {\n\t\tlog.Info().Msg(noUpdateManagedPackageMessage)\n\t\treturn false\n\t}\n\n\tif isRunningFromTerminal() {\n\t\tlog.Info().Msg(noUpdateInShellMessage)\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc wasInstalledFromPackageManager() bool {\n\tok, _ := config.FileExists(filepath.Join(config.DefaultUnixConfigLocation, isManagedInstallFile))\n\treturn len(BuiltForPackageManager) != 0 || ok\n}\n\nfunc isRunningFromTerminal() bool {\n\treturn term.IsTerminal(int(os.Stdout.Fd()))\n}\n\nfunc IsSysV() bool {\n\tif runtime.GOOS != \"linux\" {\n\t\treturn false\n\t}\n\n\tif _, err := os.Stat(\"/run/systemd/system\"); err == nil {\n\t\treturn false\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "cmd/cloudflared/updater/update_test.go",
    "content": "package updater\n\nimport (\n\t\"context\"\n\t\"flag\"\n\t\"testing\"\n\n\t\"github.com/facebookgo/grace/gracenet\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n)\n\nfunc init() {\n\tInit(cliutil.GetBuildInfo(\"TEST\", \"TEST\"))\n}\n\nfunc TestDisabledAutoUpdater(t *testing.T) {\n\tlisteners := &gracenet.Net{}\n\tlog := zerolog.Nop()\n\tautoupdater := NewAutoUpdater(false, 0, listeners, &log)\n\tctx, cancel := context.WithCancel(context.Background())\n\terrC := make(chan error)\n\tgo func() {\n\t\terrC <- autoupdater.Run(ctx)\n\t}()\n\n\tassert.False(t, autoupdater.configurable.enabled)\n\tassert.Equal(t, DefaultCheckUpdateFreq, autoupdater.configurable.freq)\n\n\tcancel()\n\t// Make sure that autoupdater terminates after canceling the context\n\tassert.Equal(t, context.Canceled, <-errC)\n}\n\nfunc TestCheckInWithUpdater(t *testing.T) {\n\tflagSet := flag.NewFlagSet(t.Name(), flag.PanicOnError)\n\tcliCtx := cli.NewContext(cli.NewApp(), flagSet, nil)\n\n\twarningChecker := StartWarningCheck(cliCtx)\n\twarning := warningChecker.getWarning()\n\t// Assuming this runs either on a release or development version, then the Worker will never have anything to tell us.\n\tassert.Empty(t, warning)\n}\n"
  },
  {
    "path": "cmd/cloudflared/updater/workers_service.go",
    "content": "package updater\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"runtime\"\n)\n\n// Options are the update options supported by the\ntype Options struct {\n\t// IsBeta is for beta updates to be installed if available\n\tIsBeta bool\n\n\t// IsForced is to forcibly download the latest version regardless of the current version\n\tIsForced bool\n\n\t// RequestedVersion is the specific version to upgrade or downgrade to\n\tRequestedVersion string\n}\n\n// VersionResponse is the JSON response from the Workers API endpoint\ntype VersionResponse struct {\n\tURL          string `json:\"url\"`\n\tVersion      string `json:\"version\"`\n\tChecksum     string `json:\"checksum\"`\n\tIsCompressed bool   `json:\"compressed\"`\n\tUserMessage  string `json:\"userMessage\"`\n\tShouldUpdate bool   `json:\"shouldUpdate\"`\n\tError        string `json:\"error\"`\n}\n\n// WorkersService implements Service.\n// It contains everything needed to check in with the WorkersAPI and download and apply the updates\ntype WorkersService struct {\n\tcurrentVersion string\n\turl            string\n\ttargetPath     string\n\topts           Options\n}\n\n// NewWorkersService creates a new updater Service object.\nfunc NewWorkersService(currentVersion, url, targetPath string, opts Options) Service {\n\treturn &WorkersService{\n\t\tcurrentVersion: currentVersion,\n\t\turl:            url,\n\t\ttargetPath:     targetPath,\n\t\topts:           opts,\n\t}\n}\n\n// Check does a check in with the Workers API to get a new version update\nfunc (s *WorkersService) Check() (CheckResult, error) {\n\tclient := &http.Client{\n\t\tTimeout: clientTimeout,\n\t}\n\n\treq, err := http.NewRequest(http.MethodGet, s.url, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tq := req.URL.Query()\n\tq.Add(OSKeyName, runtime.GOOS)\n\tq.Add(ArchitectureKeyName, runtime.GOARCH)\n\tq.Add(ClientVersionName, s.currentVersion)\n\n\tif s.opts.IsBeta {\n\t\tq.Add(BetaKeyName, \"true\")\n\t}\n\n\tif s.opts.RequestedVersion != \"\" {\n\t\tq.Add(VersionKeyName, s.opts.RequestedVersion)\n\t}\n\n\treq.URL.RawQuery = q.Encode()\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"unable to check for update: %d\", resp.StatusCode)\n\t}\n\n\tvar v VersionResponse\n\tif err := json.NewDecoder(resp.Body).Decode(&v); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif v.Error != \"\" {\n\t\treturn nil, errors.New(v.Error)\n\t}\n\n\tversionToUpdate := \"\"\n\tif v.ShouldUpdate {\n\t\tversionToUpdate = v.Version\n\t}\n\n\treturn NewWorkersVersion(v.URL, versionToUpdate, v.Checksum, s.targetPath, v.UserMessage, v.IsCompressed), nil\n}\n"
  },
  {
    "path": "cmd/cloudflared/updater/workers_service_test.go",
    "content": "//go:build !windows\n\npackage updater\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"crypto/sha256\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nvar testFilePath = filepath.Join(os.TempDir(), \"test\")\n\nfunc respondWithJSON(w http.ResponseWriter, v interface{}, status int) {\n\tdata, _ := json.Marshal(v)\n\n\tw.Header().Set(\"Content-Type\", \"application/json\")\n\tw.WriteHeader(status)\n\tw.Write(data)\n}\n\nfunc respondWithData(w http.ResponseWriter, b []byte, status int) {\n\tw.Header().Set(\"Content-Type\", \"application/octet-stream\")\n\tw.WriteHeader(status)\n\tw.Write(b)\n}\n\nconst mostRecentVersion = \"2021.2.5\"\nconst mostRecentBetaVersion = \"2021.3.0\"\nconst knownBuggyVersion = \"2020.12.0\"\nconst expectedUserMsg = \"This message is expected when running a known buggy version\"\n\nfunc updateHandler(w http.ResponseWriter, r *http.Request) {\n\tversion := mostRecentVersion\n\thost := fmt.Sprintf(\"http://%s\", r.Host)\n\turl := host + \"/download\"\n\n\tquery := r.URL.Query()\n\n\tif query.Get(BetaKeyName) == \"true\" {\n\t\tversion = mostRecentBetaVersion\n\t\turl = host + \"/beta\"\n\t}\n\n\trequestedVersion := query.Get(VersionKeyName)\n\tif requestedVersion != \"\" {\n\t\tversion = requestedVersion\n\t\turl = fmt.Sprintf(\"%s?version=%s\", url, requestedVersion)\n\t}\n\n\tif query.Get(ArchitectureKeyName) != runtime.GOARCH || query.Get(OSKeyName) != runtime.GOOS {\n\t\trespondWithJSON(w, VersionResponse{Error: \"unsupported os and architecture\"}, http.StatusBadRequest)\n\t\treturn\n\t}\n\n\th := sha256.New()\n\tfmt.Fprint(h, version)\n\tchecksum := fmt.Sprintf(\"%x\", h.Sum(nil))\n\n\tvar userMessage = \"\"\n\tif query.Get(ClientVersionName) == knownBuggyVersion {\n\t\tuserMessage = expectedUserMsg\n\t}\n\tshouldUpdate := requestedVersion != \"\" || IsNewerVersion(query.Get(ClientVersionName), version)\n\n\tv := VersionResponse{\n\t\tURL: url, Version: version, Checksum: checksum, UserMessage: userMessage, ShouldUpdate: shouldUpdate,\n\t}\n\trespondWithJSON(w, v, http.StatusOK)\n}\n\nfunc gzipUpdateHandler(w http.ResponseWriter, r *http.Request) {\n\tlog.Println(\"got a request!\")\n\tversion := \"2020.09.02\"\n\th := sha256.New()\n\tfmt.Fprint(h, version)\n\tchecksum := fmt.Sprintf(\"%x\", h.Sum(nil))\n\n\turl := fmt.Sprintf(\"http://%s/gzip-download.tgz\", r.Host)\n\tv := VersionResponse{URL: url, Version: version, Checksum: checksum, ShouldUpdate: true}\n\trespondWithJSON(w, v, http.StatusOK)\n}\n\nfunc compressedDownloadHandler(w http.ResponseWriter, r *http.Request) {\n\tversion := \"2020.09.02\"\n\tbuf := new(bytes.Buffer)\n\n\tgw := gzip.NewWriter(buf)\n\ttw := tar.NewWriter(gw)\n\n\theader := &tar.Header{\n\t\tSize: int64(len(version)),\n\t\tName: \"download\",\n\t}\n\ttw.WriteHeader(header)\n\ttw.Write([]byte(version))\n\n\ttw.Close()\n\tgw.Close()\n\n\trespondWithData(w, buf.Bytes(), http.StatusOK)\n}\n\nfunc downloadHandler(w http.ResponseWriter, r *http.Request) {\n\tversion := mostRecentVersion\n\trequestedVersion := r.URL.Query().Get(VersionKeyName)\n\tif requestedVersion != \"\" {\n\t\tversion = requestedVersion\n\t}\n\trespondWithData(w, []byte(version), http.StatusOK)\n}\n\nfunc betaHandler(w http.ResponseWriter, r *http.Request) {\n\trespondWithData(w, []byte(mostRecentBetaVersion), http.StatusOK)\n}\n\nfunc failureHandler(w http.ResponseWriter, r *http.Request) {\n\trespondWithJSON(w, VersionResponse{Error: \"unsupported os and architecture\"}, http.StatusBadRequest)\n}\n\nfunc IsNewerVersion(current string, check string) bool {\n\tif current == \"\" || check == \"\" {\n\t\treturn false\n\t}\n\tif strings.Contains(strings.ToLower(current), \"dev\") {\n\t\treturn false // dev builds shouldn't update\n\t}\n\n\tcMajor, cMinor, cPatch, err := SemanticParts(current)\n\tif err != nil {\n\t\treturn false\n\t}\n\n\tnMajor, nMinor, nPatch, err := SemanticParts(check)\n\tif err != nil {\n\t\treturn false\n\t}\n\n\tif nMajor > cMajor {\n\t\treturn true\n\t}\n\n\tif nMajor == cMajor && nMinor > cMinor {\n\t\treturn true\n\t}\n\n\tif nMajor == cMajor && nMinor == cMinor && nPatch > cPatch {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc SemanticParts(version string) (major int, minor int, patch int, err error) {\n\tmajor = 0\n\tminor = 0\n\tpatch = 0\n\tparts := strings.Split(version, \".\")\n\tif len(parts) != 3 {\n\t\terr = errors.New(\"invalid version\")\n\t\treturn\n\t}\n\tmajor, err = strconv.Atoi(parts[0])\n\tif err != nil {\n\t\treturn\n\t}\n\n\tminor, err = strconv.Atoi(parts[1])\n\tif err != nil {\n\t\treturn\n\t}\n\n\tpatch, err = strconv.Atoi(parts[2])\n\tif err != nil {\n\t\treturn\n\t}\n\treturn\n}\n\nfunc createServer() *httptest.Server {\n\tmux := http.NewServeMux()\n\tmux.HandleFunc(\"/updater\", updateHandler)\n\tmux.HandleFunc(\"/download\", downloadHandler)\n\tmux.HandleFunc(\"/beta\", betaHandler)\n\tmux.HandleFunc(\"/fail\", failureHandler)\n\tmux.HandleFunc(\"/compressed\", gzipUpdateHandler)\n\tmux.HandleFunc(\"/gzip-download.tgz\", compressedDownloadHandler)\n\treturn httptest.NewServer(mux)\n}\n\nfunc createTestFile(t *testing.T, path string) {\n\tf, err := os.Create(path)\n\trequire.NoError(t, err)\n\tfmt.Fprint(f, \"2020.08.04\")\n\tf.Close()\n}\n\nfunc TestUpdateService(t *testing.T) {\n\tts := createServer()\n\tdefer ts.Close()\n\n\tcreateTestFile(t, testFilePath)\n\tdefer os.Remove(testFilePath)\n\tlog.Println(\"server url: \", ts.URL)\n\n\ts := NewWorkersService(\"2020.8.2\", fmt.Sprintf(\"%s/updater\", ts.URL), testFilePath, Options{})\n\tv, err := s.Check()\n\trequire.NoError(t, err)\n\trequire.Equal(t, v.Version(), mostRecentVersion)\n\n\trequire.NoError(t, v.Apply())\n\tdat, err := os.ReadFile(testFilePath)\n\trequire.NoError(t, err)\n\n\trequire.Equal(t, string(dat), mostRecentVersion)\n}\n\nfunc TestBetaUpdateService(t *testing.T) {\n\tts := createServer()\n\tdefer ts.Close()\n\n\tcreateTestFile(t, testFilePath)\n\tdefer os.Remove(testFilePath)\n\n\ts := NewWorkersService(\"2020.8.2\", fmt.Sprintf(\"%s/updater\", ts.URL), testFilePath, Options{IsBeta: true})\n\tv, err := s.Check()\n\trequire.NoError(t, err)\n\trequire.Equal(t, v.Version(), mostRecentBetaVersion)\n\n\trequire.NoError(t, v.Apply())\n\tdat, err := os.ReadFile(testFilePath)\n\trequire.NoError(t, err)\n\n\trequire.Equal(t, string(dat), mostRecentBetaVersion)\n}\n\nfunc TestFailUpdateService(t *testing.T) {\n\tts := createServer()\n\tdefer ts.Close()\n\n\tcreateTestFile(t, testFilePath)\n\tdefer os.Remove(testFilePath)\n\n\ts := NewWorkersService(\"2020.8.2\", fmt.Sprintf(\"%s/fail\", ts.URL), testFilePath, Options{})\n\tv, err := s.Check()\n\trequire.Error(t, err)\n\trequire.Nil(t, v)\n}\n\nfunc TestNoUpdateService(t *testing.T) {\n\tts := createServer()\n\tdefer ts.Close()\n\n\tcreateTestFile(t, testFilePath)\n\tdefer os.Remove(testFilePath)\n\n\ts := NewWorkersService(mostRecentVersion, fmt.Sprintf(\"%s/updater\", ts.URL), testFilePath, Options{})\n\tv, err := s.Check()\n\trequire.NoError(t, err)\n\trequire.NotNil(t, v)\n\trequire.Empty(t, v.Version())\n}\n\nfunc TestForcedUpdateService(t *testing.T) {\n\tts := createServer()\n\tdefer ts.Close()\n\n\tcreateTestFile(t, testFilePath)\n\tdefer os.Remove(testFilePath)\n\n\ts := NewWorkersService(\"2020.8.5\", fmt.Sprintf(\"%s/updater\", ts.URL), testFilePath, Options{IsForced: true})\n\tv, err := s.Check()\n\trequire.NoError(t, err)\n\trequire.Equal(t, v.Version(), mostRecentVersion)\n\n\trequire.NoError(t, v.Apply())\n\tdat, err := os.ReadFile(testFilePath)\n\trequire.NoError(t, err)\n\n\trequire.Equal(t, string(dat), mostRecentVersion)\n}\n\nfunc TestUpdateSpecificVersionService(t *testing.T) {\n\tts := createServer()\n\tdefer ts.Close()\n\n\tcreateTestFile(t, testFilePath)\n\tdefer os.Remove(testFilePath)\n\treqVersion := \"2020.9.1\"\n\n\ts := NewWorkersService(\"2020.8.2\", fmt.Sprintf(\"%s/updater\", ts.URL), testFilePath, Options{RequestedVersion: reqVersion})\n\tv, err := s.Check()\n\trequire.NoError(t, err)\n\trequire.Equal(t, reqVersion, v.Version())\n\n\trequire.NoError(t, v.Apply())\n\tdat, err := os.ReadFile(testFilePath)\n\trequire.NoError(t, err)\n\n\trequire.Equal(t, reqVersion, string(dat))\n}\n\nfunc TestCompressedUpdateService(t *testing.T) {\n\tts := createServer()\n\tdefer ts.Close()\n\n\tcreateTestFile(t, testFilePath)\n\tdefer os.Remove(testFilePath)\n\n\ts := NewWorkersService(\"2020.8.2\", fmt.Sprintf(\"%s/compressed\", ts.URL), testFilePath, Options{})\n\tv, err := s.Check()\n\trequire.NoError(t, err)\n\trequire.Equal(t, \"2020.09.02\", v.Version())\n\n\trequire.NoError(t, v.Apply())\n\tdat, err := os.ReadFile(testFilePath)\n\trequire.NoError(t, err)\n\n\trequire.Equal(t, \"2020.09.02\", string(dat))\n}\n\nfunc TestUpdateWhenRunningKnownBuggyVersion(t *testing.T) {\n\tts := createServer()\n\tdefer ts.Close()\n\n\tcreateTestFile(t, testFilePath)\n\tdefer os.Remove(testFilePath)\n\n\ts := NewWorkersService(knownBuggyVersion, fmt.Sprintf(\"%s/updater\", ts.URL), testFilePath, Options{})\n\tv, err := s.Check()\n\trequire.NoError(t, err)\n\trequire.Equal(t, v.Version(), mostRecentVersion)\n\trequire.Equal(t, v.UserMessage(), expectedUserMsg)\n}\n"
  },
  {
    "path": "cmd/cloudflared/updater/workers_update.go",
    "content": "package updater\n\nimport (\n\t\"archive/tar\"\n\t\"compress/gzip\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"text/template\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go\"\n\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n)\n\nconst (\n\tclientTimeout = time.Second * 60\n\t// stop the service\n\t// rename cloudflared.exe to cloudflared.exe.old\n\t// rename cloudflared.exe.new to cloudflared.exe\n\t// delete cloudflared.exe.old\n\t// start the service\n\t// exit with code 0 if we've reached this point indicating success.\n\twindowsUpdateCommandTemplate = `sc stop cloudflared >nul 2>&1\ndel \"{{.OldPath}}\"\nrename \"{{.TargetPath}}\" {{.OldName}}\nrename \"{{.NewPath}}\" {{.BinaryName}}\nsc start cloudflared >nul 2>&1\nexit /b 0`\n\tbatchFileName = \"cfd_update.bat\"\n)\n\n// Prepare some data to insert into the template.\ntype batchData struct {\n\tTargetPath string\n\tOldName    string\n\tNewPath    string\n\tOldPath    string\n\tBinaryName string\n\tBatchName  string\n}\n\n// WorkersVersion implements the Version interface.\n// It contains everything needed to perform a version upgrade\ntype WorkersVersion struct {\n\tdownloadURL  string\n\tchecksum     string\n\tversion      string\n\ttargetPath   string\n\tisCompressed bool\n\tuserMessage  string\n}\n\n// NewWorkersVersion creates a new Version object. This is normally created by a WorkersService JSON checkin response\n// url is where to download the file\n// version is the version of this update\n// checksum is the expected checksum of the downloaded file\n// target path is where the file should be replace. Normally this the running cloudflared's path\n// userMessage is a possible message to convey back to the user after having checked in with the Updater Service\n// isCompressed tells whether the asset to update cloudflared is compressed or not\nfunc NewWorkersVersion(url, version, checksum, targetPath, userMessage string, isCompressed bool) CheckResult {\n\treturn &WorkersVersion{\n\t\tdownloadURL:  url,\n\t\tversion:      version,\n\t\tchecksum:     checksum,\n\t\ttargetPath:   targetPath,\n\t\tisCompressed: isCompressed,\n\t\tuserMessage:  userMessage,\n\t}\n}\n\n// Apply does the actual verification and update logic.\n// This includes signature and checksum validation,\n// replacing the binary, etc\nfunc (v *WorkersVersion) Apply() error {\n\tnewFilePath := fmt.Sprintf(\"%s.new\", v.targetPath)\n\tos.Remove(newFilePath) //remove any failed updates before download\n\n\t// download the file\n\tif err := download(v.downloadURL, newFilePath, v.isCompressed); err != nil {\n\t\treturn err\n\t}\n\n\tdownloadSum, err := cliutil.FileChecksum(newFilePath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Check that the file downloaded matches what is expected.\n\tif v.checksum != downloadSum {\n\t\treturn errors.New(\"checksum validation failed\")\n\t}\n\n\t// Check if the currently running version has the same checksum\n\tif downloadSum == buildInfo.Checksum {\n\t\t// Currently running binary matches the downloaded binary so we have no reason to update. This is\n\t\t// typically unexpected, as such we emit a sentry event.\n\t\tlocalHub := sentry.CurrentHub().Clone()\n\t\terr := errors.New(\"checksum validation matches currently running process\")\n\t\tlocalHub.CaptureException(err)\n\t\t// Make sure to cleanup the new downloaded file since we aren't upgrading versions.\n\t\tos.Remove(newFilePath)\n\t\treturn err\n\t}\n\n\toldFilePath := fmt.Sprintf(\"%s.old\", v.targetPath)\n\t// Windows requires more effort to self update, especially when it is running as a service:\n\t// you have to stop the service (if running as one) in order to move/rename the binary\n\t// but now the binary isn't running though, so an external process\n\t// has to move the old binary out and the new one in then start the service\n\t// the easiest way to do this is with a batch file (or with a DLL, but that gets ugly for a cross compiled binary like cloudflared)\n\t// a batch file isn't ideal, but it is the simplest path forward for the constraints Windows creates\n\tif runtime.GOOS == \"windows\" {\n\t\tif err := writeBatchFile(v.targetPath, newFilePath, oldFilePath); err != nil {\n\t\t\treturn err\n\t\t}\n\t\trootDir := filepath.Dir(v.targetPath)\n\t\tbatchPath := filepath.Join(rootDir, batchFileName)\n\t\treturn runWindowsBatch(batchPath)\n\t}\n\n\t// now move the current file out, move the new file in and delete the old file\n\tif err := os.Rename(v.targetPath, oldFilePath); err != nil {\n\t\treturn err\n\t}\n\n\tif err := os.Rename(newFilePath, v.targetPath); err != nil {\n\t\t//attempt rollback\n\t\t_ = os.Rename(oldFilePath, v.targetPath)\n\t\treturn err\n\t}\n\tos.Remove(oldFilePath)\n\n\treturn nil\n}\n\n// String returns the version number of this update/release (e.g. 2020.08.05)\nfunc (v *WorkersVersion) Version() string {\n\treturn v.version\n}\n\n// String returns a possible message to convey back to user after having checked in with the Updater Service. E.g.\n// it can warn about the need to update the version currently running.\nfunc (v *WorkersVersion) UserMessage() string {\n\treturn v.userMessage\n}\n\n// download the file from the link in the json\nfunc download(url, filepath string, isCompressed bool) error {\n\tclient := &http.Client{\n\t\tTimeout: clientTimeout,\n\t}\n\tresp, err := client.Get(url)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\n\tvar r io.Reader\n\tr = resp.Body\n\n\t// compressed macos binary, need to decompress\n\tif isCompressed || isCompressedFile(url) {\n\t\t// first the gzip reader\n\t\tgr, err := gzip.NewReader(resp.Body)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer gr.Close()\n\n\t\t// now the tar\n\t\ttr := tar.NewReader(gr)\n\n\t\t// advance the reader pass the header, which will be the single binary file\n\t\t_, _ = tr.Next()\n\n\t\tr = tr\n\t}\n\n\tout, err := os.OpenFile(filepath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer out.Close()\n\n\t_, err = io.Copy(out, r)\n\treturn err\n}\n\n// isCompressedFile is a really simple file extension check to see if this is a macos tar and gzipped\nfunc isCompressedFile(urlstring string) bool {\n\tif path.Ext(urlstring) == \".tgz\" {\n\t\treturn true\n\t}\n\n\tu, err := url.Parse(urlstring)\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn path.Ext(u.Path) == \".tgz\"\n}\n\n// writeBatchFile writes a batch file out to disk\n// see the dicussion on why it has to be done this way\nfunc writeBatchFile(targetPath string, newPath string, oldPath string) error {\n\tbatchFilePath := filepath.Join(filepath.Dir(targetPath), batchFileName)\n\tos.Remove(batchFilePath) //remove any failed updates before download\n\tf, err := os.Create(batchFilePath)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer f.Close()\n\tcfdName := filepath.Base(targetPath)\n\toldName := filepath.Base(oldPath)\n\n\tdata := batchData{\n\t\tTargetPath: targetPath,\n\t\tOldName:    oldName,\n\t\tNewPath:    newPath,\n\t\tOldPath:    oldPath,\n\t\tBinaryName: cfdName,\n\t\tBatchName:  batchFileName,\n\t}\n\n\tt, err := template.New(\"batch\").Parse(windowsUpdateCommandTemplate)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn t.Execute(f, data)\n}\n\n// run each OS command for windows\nfunc runWindowsBatch(batchFile string) error {\n\tdefer os.Remove(batchFile)\n\tcmd := exec.Command(\"cmd\", \"/C\", batchFile)\n\t_, err := cmd.Output()\n\t// Remove the batch file we created. Don't let this interfere with the error\n\t// we report.\n\tif err != nil {\n\t\tif exitError, ok := err.(*exec.ExitError); ok {\n\t\t\treturn fmt.Errorf(\"Error during update : %s;\", string(exitError.Stderr))\n\t\t}\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "cmd/cloudflared/windows_service.go",
    "content": "//go:build windows\n\npackage main\n\n// Copypasta from the example files:\n// https://github.com/golang/sys/blob/master/windows/svc/example\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"syscall\"\n\t\"time\"\n\t\"unsafe\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/urfave/cli/v2\"\n\t\"golang.org/x/sys/windows\"\n\t\"golang.org/x/sys/windows/svc\"\n\t\"golang.org/x/sys/windows/svc/eventlog\"\n\t\"golang.org/x/sys/windows/svc/mgr\"\n\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil\"\n\t\"github.com/cloudflare/cloudflared/logger\"\n)\n\nconst (\n\twindowsServiceName        = \"Cloudflared\"\n\twindowsServiceDescription = \"Cloudflared agent\"\n\twindowsServiceUrl         = \"https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/configure-tunnels/local-management/as-a-service/windows/\"\n\n\trecoverActionDelay      = time.Second * 20\n\tfailureCountResetPeriod = time.Hour * 24\n\n\t// not defined in golang.org/x/sys/windows package\n\t// https://msdn.microsoft.com/en-us/library/windows/desktop/ms681988(v=vs.85).aspx\n\tserviceConfigFailureActionsFlag = 4\n\n\t// ERROR_FAILED_SERVICE_CONTROLLER_CONNECT\n\t// https://docs.microsoft.com/en-us/windows/desktop/debug/system-error-codes--1000-1299-\n\tserviceControllerConnectionFailure = 1063\n\n\tLogFieldWindowsServiceName = \"windowsServiceName\"\n)\n\nfunc runApp(app *cli.App, graceShutdownC chan struct{}) {\n\tapp.Commands = append(app.Commands, &cli.Command{\n\t\tName:  \"service\",\n\t\tUsage: \"Manages the cloudflared Windows service\",\n\t\tSubcommands: []*cli.Command{\n\t\t\t{\n\t\t\t\tName:   \"install\",\n\t\t\t\tUsage:  \"Install cloudflared as a Windows service\",\n\t\t\t\tAction: cliutil.ConfiguredAction(installWindowsService),\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:   \"uninstall\",\n\t\t\t\tUsage:  \"Uninstall the cloudflared service\",\n\t\t\t\tAction: cliutil.ConfiguredAction(uninstallWindowsService),\n\t\t\t},\n\t\t},\n\t})\n\n\t// `IsAnInteractiveSession()` isn't exactly equivalent to \"should the\n\t// process run as a normal EXE?\" There are legitimate non-service cases,\n\t// like running cloudflared in a GCP startup script, for which\n\t// `IsAnInteractiveSession()` returns false. For more context, see:\n\t//     https://github.com/judwhite/go-svc/issues/6\n\t// It seems that the \"correct way\" to check \"is this a normal EXE?\" is:\n\t//     1. attempt to connect to the Service Control Manager\n\t//     2. get ERROR_FAILED_SERVICE_CONTROLLER_CONNECT\n\t// This involves actually trying to start the service.\n\n\tlog := logger.Create(nil)\n\n\tisIntSess, err := svc.IsAnInteractiveSession()\n\tif err != nil {\n\t\tlog.Fatal().Err(err).Msg(\"failed to determine if we are running in an interactive session\")\n\t}\n\tif isIntSess {\n\t\tapp.Run(os.Args)\n\t\treturn\n\t}\n\n\t// Run executes service name by calling windowsService which is a Handler\n\t// interface that implements Execute method.\n\t// It will set service status to stop after Execute returns\n\terr = svc.Run(windowsServiceName, &windowsService{app: app, graceShutdownC: graceShutdownC})\n\tif err != nil {\n\t\tif errno, ok := err.(syscall.Errno); ok && int(errno) == serviceControllerConnectionFailure {\n\t\t\t// Hack: assume this is a false negative from the IsAnInteractiveSession() check above.\n\t\t\t// Run the app in \"interactive\" mode anyway.\n\t\t\tapp.Run(os.Args)\n\t\t\treturn\n\t\t}\n\t\tlog.Fatal().Err(err).Msgf(\"%s service failed\", windowsServiceName)\n\t}\n}\n\ntype windowsService struct {\n\tapp            *cli.App\n\tgraceShutdownC chan struct{}\n}\n\n// Execute is called by the service manager when service starts, the state\n// of the service will be set to Stopped when this function returns.\nfunc (s *windowsService) Execute(serviceArgs []string, r <-chan svc.ChangeRequest, statusChan chan<- svc.Status) (ssec bool, errno uint32) {\n\tlog := logger.Create(nil)\n\telog, err := eventlog.Open(windowsServiceName)\n\tif err != nil {\n\t\tlog.Err(err).Msgf(\"Cannot open event log for %s\", windowsServiceName)\n\t\treturn\n\t}\n\tdefer elog.Close()\n\n\telog.Info(1, fmt.Sprintf(\"%s service starting\", windowsServiceName))\n\tdefer func() {\n\t\telog.Info(1, fmt.Sprintf(\"%s service stopped\", windowsServiceName))\n\t}()\n\n\t// the arguments passed here are only meaningful if they were manually\n\t// specified by the user, e.g. using the Services console or `sc start`.\n\t// https://docs.microsoft.com/en-us/windows/desktop/services/service-entry-point\n\t// https://stackoverflow.com/a/6235139\n\tvar args []string\n\tif len(serviceArgs) > 1 {\n\t\targs = serviceArgs\n\t} else {\n\t\t// fall back to the arguments from ImagePath (or, as sc calls it, binPath)\n\t\targs = os.Args\n\t}\n\telog.Info(1, fmt.Sprintf(\"%s service arguments: %v\", windowsServiceName, args))\n\n\tstatusChan <- svc.Status{State: svc.StartPending}\n\terrC := make(chan error)\n\tgo func() {\n\t\terrC <- s.app.Run(args)\n\t}()\n\tstatusChan <- svc.Status{State: svc.Running, Accepts: svc.AcceptStop | svc.AcceptShutdown}\n\n\tfor {\n\t\tselect {\n\t\tcase c := <-r:\n\t\t\tswitch c.Cmd {\n\t\t\tcase svc.Interrogate:\n\t\t\t\tstatusChan <- c.CurrentStatus\n\t\t\tcase svc.Stop, svc.Shutdown:\n\t\t\t\tif s.graceShutdownC != nil {\n\t\t\t\t\t// start graceful shutdown\n\t\t\t\t\telog.Info(1, \"cloudflared starting graceful shutdown\")\n\t\t\t\t\tclose(s.graceShutdownC)\n\t\t\t\t\ts.graceShutdownC = nil\n\t\t\t\t\tstatusChan <- svc.Status{State: svc.StopPending}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\t// repeated attempts at graceful shutdown forces immediate stop\n\t\t\t\telog.Info(1, \"cloudflared terminating immediately\")\n\t\t\t\tstatusChan <- svc.Status{State: svc.StopPending}\n\t\t\t\treturn false, 0\n\t\t\tdefault:\n\t\t\t\telog.Error(1, fmt.Sprintf(\"unexpected control request #%d\", c))\n\t\t\t}\n\t\tcase err := <-errC:\n\t\t\tif err != nil {\n\t\t\t\telog.Error(1, fmt.Sprintf(\"cloudflared terminated with error %v\", err))\n\t\t\t\tssec = true\n\t\t\t\terrno = 1\n\t\t\t} else {\n\t\t\t\telog.Info(1, \"cloudflared terminated without error\")\n\t\t\t\terrno = 0\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc installWindowsService(c *cli.Context) error {\n\tzeroLogger := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog)\n\n\tzeroLogger.Info().Msg(\"Installing cloudflared Windows service\")\n\texepath, err := os.Executable()\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Cannot find path name that start the process\")\n\t}\n\tm, err := mgr.Connect()\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Cannot establish a connection to the service control manager\")\n\t}\n\tdefer m.Disconnect()\n\ts, err := m.OpenService(windowsServiceName)\n\tlog := zeroLogger.With().Str(LogFieldWindowsServiceName, windowsServiceName).Logger()\n\tif err == nil {\n\t\ts.Close()\n\t\treturn errors.New(serviceAlreadyExistsWarn(windowsServiceName))\n\t}\n\textraArgs, err := getServiceExtraArgsFromCliArgs(c, &log)\n\tif err != nil {\n\t\terrMsg := \"Unable to determine extra arguments for windows service\"\n\t\tlog.Err(err).Msg(errMsg)\n\t\treturn errors.Wrap(err, errMsg)\n\t}\n\n\tconfig := mgr.Config{StartType: mgr.StartAutomatic, DisplayName: windowsServiceDescription}\n\ts, err = m.CreateService(windowsServiceName, exepath, config, extraArgs...)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Cannot install service\")\n\t}\n\tdefer s.Close()\n\tlog.Info().Msg(\"cloudflared agent service is installed\")\n\terr = eventlog.InstallAsEventCreate(windowsServiceName, eventlog.Error|eventlog.Warning|eventlog.Info)\n\tif err != nil {\n\t\ts.Delete()\n\t\treturn errors.Wrap(err, \"Cannot install event logger\")\n\t}\n\n\terr = configRecoveryOption(s.Handle)\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"Cannot set service recovery actions\")\n\t\tlog.Info().Msgf(\"See %s to manually configure service recovery actions\", windowsServiceUrl)\n\t}\n\n\terr = s.Start()\n\tif err == nil {\n\t\tlog.Info().Msg(\"Agent service for cloudflared installed successfully\")\n\t}\n\treturn err\n}\n\nfunc uninstallWindowsService(c *cli.Context) error {\n\tlog := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog).\n\t\tWith().\n\t\tStr(LogFieldWindowsServiceName, windowsServiceName).Logger()\n\n\tlog.Info().Msg(\"Uninstalling cloudflared agent service\")\n\tm, err := mgr.Connect()\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Cannot establish a connection to the service control manager\")\n\t}\n\tdefer m.Disconnect()\n\ts, err := m.OpenService(windowsServiceName)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"agent service %s is not installed, so it could not be uninstalled\", windowsServiceName)\n\t}\n\tdefer s.Close()\n\n\tif status, err := s.Query(); err == nil && status.State == svc.Running {\n\t\tlog.Info().Msg(\"Stopping cloudflared agent service\")\n\t\tif _, err := s.Control(svc.Stop); err != nil {\n\t\t\tlog.Info().Err(err).Msg(\"Failed to stop cloudflared agent service, you may need to stop it manually to complete uninstall.\")\n\t\t}\n\t}\n\n\terr = s.Delete()\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Cannot delete agent service\")\n\t}\n\tlog.Info().Msg(\"Agent service for cloudflared was uninstalled successfully\")\n\terr = eventlog.Remove(windowsServiceName)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Cannot remove event logger\")\n\t}\n\treturn nil\n}\n\n// defined in https://msdn.microsoft.com/en-us/library/windows/desktop/ms685126(v=vs.85).aspx\ntype scAction int\n\n// https://msdn.microsoft.com/en-us/library/windows/desktop/ms685126(v=vs.85).aspx\nconst (\n\tscActionNone scAction = iota\n\tscActionRestart\n\tscActionReboot\n\tscActionRunCommand\n)\n\n// defined in https://msdn.microsoft.com/en-us/library/windows/desktop/ms685939(v=vs.85).aspx\ntype serviceFailureActions struct {\n\t// time to wait to reset the failure count to zero if there are no failures in seconds\n\tresetPeriod uint32\n\trebootMsg   *uint16\n\tcommand     *uint16\n\t// If failure count is greater than actionCount, the service controller repeats\n\t// the last action in actions\n\tactionCount uint32\n\tactions     uintptr\n}\n\n// https://msdn.microsoft.com/en-us/library/windows/desktop/ms685937(v=vs.85).aspx\n// Not supported in Windows Server 2003 and Windows XP\ntype serviceFailureActionsFlag struct {\n\t// enableActionsForStopsWithErr is of type BOOL, which is declared as\n\t// typedef int BOOL in C\n\tenableActionsForStopsWithErr int\n}\n\ntype recoveryAction struct {\n\trecoveryType uint32\n\t// The time to wait before performing the specified action, in milliseconds\n\tdelay uint32\n}\n\n// until https://github.com/golang/go/issues/23239 is release, we will need to\n// configure through ChangeServiceConfig2\nfunc configRecoveryOption(handle windows.Handle) error {\n\tactions := []recoveryAction{\n\t\t{recoveryType: uint32(scActionRestart), delay: uint32(recoverActionDelay / time.Millisecond)},\n\t}\n\tserviceRecoveryActions := serviceFailureActions{\n\t\tresetPeriod: uint32(failureCountResetPeriod / time.Second),\n\t\tactionCount: uint32(len(actions)),\n\t\tactions:     uintptr(unsafe.Pointer(&actions[0])),\n\t}\n\tif err := windows.ChangeServiceConfig2(handle, windows.SERVICE_CONFIG_FAILURE_ACTIONS, (*byte)(unsafe.Pointer(&serviceRecoveryActions))); err != nil {\n\t\treturn err\n\t}\n\tserviceFailureActionsFlag := serviceFailureActionsFlag{enableActionsForStopsWithErr: 1}\n\treturn windows.ChangeServiceConfig2(handle, serviceConfigFailureActionsFlag, (*byte)(unsafe.Pointer(&serviceFailureActionsFlag)))\n}\n"
  },
  {
    "path": "component-tests/.gitignore",
    "content": "__pycache__\n.pytest_cache\n"
  },
  {
    "path": "component-tests/README.md",
    "content": "# Requirements\n1. Python 3.10 or later with packages in the given `requirements.txt`\n   - E.g. with venv:\n   - `python3 -m venv ./.venv`  \n   - `source ./.venv/bin/activate`\n   - `python3 -m pip install -r requirements.txt`\n\n2. Create a config yaml file, for example:\n```\ncloudflared_binary: \"cloudflared\"\ntunnel: \"3d539f97-cd3a-4d8e-c33b-65e9099c7a8d\"\ncredentials_file: \"/Users/tunnel/.cloudflared/3d539f97-cd3a-4d8e-c33b-65e9099c7a8d.json\"\norigincert: \"/Users/tunnel/.cloudflared/cert.pem\"\ningress:\n- hostname: named-tunnel-component-tests.example.com\n  service: hello_world\n- service: http_status:404\n```\n\n3. Route hostname to the tunnel. For the example config above, we can do that via\n```\n   cloudflared tunnel route dns 3d539f97-cd3a-4d8e-c33b-65e9099c7a8d named-tunnel-component-tests.example.com\n```\n\n4. Turn on linter\nIf you are using Visual Studio, follow https://code.visualstudio.com/docs/python/linting to turn on linter.\n\n5. Turn on formatter\nIf you are using Visual Studio, follow https://code.visualstudio.com/docs/python/editing#_formatting\nto turn on formatter and https://marketplace.visualstudio.com/items?itemName=cbrevik.toggle-format-on-save\nto turn on format on save.\n\n6. If you have cloudflared running as a service on your machine, you can either stop the service or ignore the service tests\nvia `--ignore test_service.py`\n\n# How to run\nSpecify path to config file via env var `COMPONENT_TESTS_CONFIG`. This is required.\n## All tests\nRun `pytest` inside this(component-tests) folder\n\n## Specific files\nRun `pytest <file 1 name>.py <file 2 name>.py`\n\n## Specific tests\nRun `pytest file.py -k <test 1 name> -k <test 2 name>`\n\n## Live Logging\nRunning with `-o log_cli=true` outputs logging to CLI as the tests are. By default the log level is WARN.\n`--log-cli-level` control logging level.\nFor example, to log at info level, run `pytest -o log_cli=true --log-cli-level=INFO`.\nSee https://docs.pytest.org/en/latest/logging.html#live-logs for more documentation on logging."
  },
  {
    "path": "component-tests/cli.py",
    "content": "import json\nimport subprocess\nfrom time import sleep\n\nfrom constants import MANAGEMENT_HOST_NAME\nfrom setup import get_config_from_file\nfrom util import get_tunnel_connector_id\n\nSINGLE_CASE_TIMEOUT = 600\n\nclass CloudflaredCli:\n    def __init__(self, config, config_path, logger):\n        self.basecmd = [config.cloudflared_binary, \"tunnel\"]\n        if config_path is not None:\n            self.basecmd += [\"--config\", str(config_path)]\n        origincert = get_config_from_file()[\"origincert\"]\n        if origincert:\n            self.basecmd += [\"--origincert\", origincert]\n        self.logger = logger\n\n    def _run_command(self, subcmd, subcmd_name, needs_to_pass=True):\n        cmd = self.basecmd + subcmd\n        # timeout limits the time a subprocess can run. This is useful to guard against running a tunnel when\n        # command/args are in wrong order.\n        result = run_subprocess(cmd, subcmd_name, self.logger, check=needs_to_pass, capture_output=True, timeout=15)\n        return result\n\n    def list_tunnels(self):\n        cmd_args = [\"list\", \"--output\", \"json\"]\n        listed = self._run_command(cmd_args, \"list\")\n        return json.loads(listed.stdout)\n\n    def get_management_token(self, config, config_path, resource):\n        basecmd = [config.cloudflared_binary]\n        if config_path is not None:\n            basecmd += [\"--config\", str(config_path)]\n        origincert = get_config_from_file()[\"origincert\"]\n        if origincert:\n            basecmd += [\"--origincert\", origincert]\n\n        cmd_args = [\"management\", \"token\", \"--resource\", resource, config.get_tunnel_id()]\n        cmd = basecmd + cmd_args\n        result = run_subprocess(cmd, \"token\", self.logger, check=True, capture_output=True, timeout=15)\n        return json.loads(result.stdout.decode(\"utf-8\").strip())[\"token\"]\n    \n    def get_tail_token(self, config, config_path):\n        \"\"\"\n        Get management token using the 'tail token' command.\n        Returns a token scoped for 'logs' resource.\n        \"\"\"\n        basecmd = [config.cloudflared_binary]\n        if config_path is not None:\n            basecmd += [\"--config\", str(config_path)]\n        origincert = get_config_from_file()[\"origincert\"]\n        if origincert:\n            basecmd += [\"--origincert\", origincert]\n        \n        cmd_args = [\"tail\", \"token\", config.get_tunnel_id()]\n        cmd = basecmd + cmd_args\n        result = run_subprocess(cmd, \"tail-token\", self.logger, check=True, capture_output=True, timeout=15)\n        return json.loads(result.stdout.decode(\"utf-8\").strip())[\"token\"]\n    \n    def get_management_url(self, path, config, config_path, resource):\n        access_jwt = self.get_management_token(config, config_path, resource)\n        connector_id = get_tunnel_connector_id()\n        return f\"https://{MANAGEMENT_HOST_NAME}/{path}?connector_id={connector_id}&access_token={access_jwt}\"\n    \n    def get_management_wsurl(self, path, config, config_path, resource):\n        access_jwt = self.get_management_token(config, config_path, resource)\n        connector_id = get_tunnel_connector_id()\n        return f\"wss://{MANAGEMENT_HOST_NAME}/{path}?connector_id={connector_id}&access_token={access_jwt}\"\n\n    def get_connector_id(self, config): \n        op = self.get_tunnel_info(config.get_tunnel_id())\n        connectors = []\n        for conn in op[\"conns\"]:\n            connectors.append(conn[\"id\"])\n        return connectors\n\n    def get_tunnel_info(self, tunnel_id):\n        info = self._run_command([\"info\", \"--output\", \"json\", tunnel_id], \"info\")\n        return json.loads(info.stdout)\n\n    def __enter__(self):\n        self.basecmd += [\"run\"]\n        self.process = subprocess.Popen(self.basecmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n        self.logger.info(f\"Run cmd {self.basecmd}\")\n        return self.process\n\n    def __exit__(self, exc_type, exc_value, exc_traceback):\n        terminate_gracefully(self.process, self.logger, self.basecmd)\n        self.logger.debug(f\"{self.basecmd} logs: {self.process.stderr.read()}\")\n\n\ndef terminate_gracefully(process, logger, cmd):\n    process.terminate()\n    process_terminated = wait_for_terminate(process)\n    if not process_terminated:\n        process.kill()\n        logger.warning(f\"{cmd}: cloudflared did not terminate within wait period. Killing process. logs: \\\n                stdout: {process.stdout.read()}, stderr: {process.stderr.read()}\")\n\n\ndef wait_for_terminate(opened_subprocess, attempts=10, poll_interval=1):\n    \"\"\"\n        wait_for_terminate polls the opened_subprocess every x seconds for a given number of attempts.\n        It returns true if the subprocess was terminated and false if it didn't.\n    \"\"\"\n    for _ in range(attempts):\n        if _is_process_stopped(opened_subprocess):\n            return True\n        sleep(poll_interval)\n    return False\n\n\ndef _is_process_stopped(process):\n    return process.poll() is not None\n\n\ndef cert_path():\n    return get_config_from_file()[\"origincert\"]\n\n\nclass SubprocessError(Exception):\n    def __init__(self, program, exit_code, cause):\n        self.program = program\n        self.exit_code = exit_code\n        self.cause = cause\n\n\ndef run_subprocess(cmd, cmd_name, logger, timeout=SINGLE_CASE_TIMEOUT, **kargs):\n    kargs[\"timeout\"] = timeout\n    try:\n        result = subprocess.run(cmd, **kargs)\n        logger.debug(f\"{cmd} log: {result.stdout}\", extra={\"cmd\": cmd_name})\n        return result\n    except subprocess.CalledProcessError as e:\n        err = f\"{cmd} return exit code {e.returncode}, stderr\" + e.stderr.decode(\"utf-8\")\n        logger.error(err, extra={\"cmd\": cmd_name, \"return_code\": e.returncode})\n        raise SubprocessError(cmd[0], e.returncode, e)\n    except subprocess.TimeoutExpired as e:\n        err = f\"{cmd} timeout after {e.timeout} seconds, stdout: {e.stdout}, stderr: {e.stderr}\"\n        logger.error(err, extra={\"cmd\": cmd_name, \"return_code\": \"timeout\"})\n        raise e"
  },
  {
    "path": "component-tests/config.py",
    "content": "#!/usr/bin/env python\nimport copy\nimport json\nimport base64\n\nfrom dataclasses import dataclass, InitVar\n\nfrom constants import METRICS_PORT\n\n# frozen=True raises exception when assigning to fields. This emulates immutability\n\n\n@dataclass(frozen=True)\nclass BaseConfig:\n    cloudflared_binary: str\n    no_autoupdate: bool = True\n    metrics: str = f'localhost:{METRICS_PORT}'\n\n    def merge_config(self, additional):\n        config = copy.copy(additional)\n        config['no-autoupdate'] = self.no_autoupdate\n        config['metrics'] = self.metrics\n        return config\n\n\n@dataclass(frozen=True)\nclass NamedTunnelBaseConfig(BaseConfig):\n    # The attributes of the parent class are ordered before attributes in this class,\n    # so we have to use default values here and check if they are set in __post_init__\n    tunnel: str = None\n    credentials_file: str = None\n    ingress: list = None\n    hostname: str = None\n\n    def __post_init__(self):\n        if self.tunnel is None:\n            raise TypeError(\"Field tunnel is not set\")\n        if self.credentials_file is None:\n            raise TypeError(\"Field credentials_file is not set\")\n        if self.ingress is None:\n            raise TypeError(\"Field ingress is not set\")\n\n    def merge_config(self, additional):\n        config = super(NamedTunnelBaseConfig, self).merge_config(additional)\n        if 'tunnel' not in config:\n            config['tunnel'] = self.tunnel\n        if 'credentials-file' not in config:\n            config['credentials-file'] = self.credentials_file\n        # In some cases we want to override default ingress, such as in config tests\n        if 'ingress' not in config:\n            config['ingress'] = self.ingress\n        return config\n\n\n@dataclass(frozen=True)\nclass NamedTunnelConfig(NamedTunnelBaseConfig):\n    full_config: dict = None\n    additional_config: InitVar[dict] = {}\n\n    def __post_init__(self, additional_config):\n        # Cannot call set self.full_config because the class is frozen, instead, we can use __setattr__\n        # https://docs.python.org/3/library/dataclasses.html#frozen-instances\n        object.__setattr__(self, 'full_config',\n                           self.merge_config(additional_config))\n\n    def get_url(self):\n        return \"https://\" + self.hostname\n\n    def base_config(self):\n        config = self.full_config.copy()\n\n        # removes the tunnel reference\n        del(config[\"tunnel\"])\n        del(config[\"credentials-file\"])\n\n        return config\n\n    def get_tunnel_id(self):\n        return self.full_config[\"tunnel\"]\n\n    def get_token(self):\n        creds = self.get_credentials_json()\n        token_dict = {\"a\": creds[\"AccountTag\"], \"t\": creds[\"TunnelID\"], \"s\": creds[\"TunnelSecret\"]}\n        token_json_str = json.dumps(token_dict)\n        return base64.b64encode(token_json_str.encode('utf-8'))\n\n    def get_credentials_json(self):\n        with open(self.credentials_file) as json_file:\n            return json.load(json_file)\n        \n@dataclass(frozen=True)\nclass QuickTunnelConfig(BaseConfig):\n    full_config: dict = None\n    additional_config: InitVar[dict] = {}\n\n    def __post_init__(self, additional_config):\n        # Cannot call set self.full_config because the class is frozen, instead, we can use __setattr__\n        # https://docs.python.org/3/library/dataclasses.html#frozen-instances\n        object.__setattr__(self, 'full_config',\n                           self.merge_config(additional_config))\n\n"
  },
  {
    "path": "component-tests/config.yaml",
    "content": "cloudflared_binary: \"cloudflared\"\ntunnel: \"ae21a96c-24d1-4ce8-a6ba-962cba5976d3\"\ncredentials_file: \"/Users/sudarsan/.cloudflared/ae21a96c-24d1-4ce8-a6ba-962cba5976d3.json\"\norigincert: \"/Users/sudarsan/.cloudflared/cert.pem\"\ningress:\n- hostname: named-tunnel-component-tests.example.com\n  service: hello_world\n- service: http_status:404\n"
  },
  {
    "path": "component-tests/conftest.py",
    "content": "import os\nfrom enum import Enum, auto\nfrom time import sleep\n\nimport pytest\nimport yaml\n\nfrom config import NamedTunnelConfig, QuickTunnelConfig\nfrom constants import BACKOFF_SECS\nfrom util import LOGGER\n\n\nclass CfdModes(Enum):\n    NAMED = auto()\n    QUICK = auto()\n\n\n@pytest.fixture(scope=\"session\")\ndef component_tests_config():\n    config_file = os.getenv(\"COMPONENT_TESTS_CONFIG\")\n    if config_file is None:\n        raise Exception(\n            \"Need to provide path to config file in COMPONENT_TESTS_CONFIG\")\n    with open(config_file, 'r') as stream:\n        config = yaml.safe_load(stream)\n        LOGGER.info(f\"component tests base config {config}\")\n\n        def _component_tests_config(additional_config={}, cfd_mode=CfdModes.NAMED, provide_ingress=True):\n            # Allows the ingress rules to be omitted from the provided config\n            ingress = []\n            if provide_ingress:\n                ingress = config['ingress']\n\n            # Provide the hostname to allow routing to the tunnel even if the ingress rule isn't defined in the config\n            hostname = config['ingress'][0]['hostname']\n\n            if cfd_mode is CfdModes.NAMED:\n                return NamedTunnelConfig(additional_config=additional_config,\n                                         cloudflared_binary=config['cloudflared_binary'],\n                                         tunnel=config['tunnel'],\n                                         credentials_file=config['credentials_file'],\n                                         ingress=ingress,\n                                         hostname=hostname)\n            elif cfd_mode is CfdModes.QUICK:\n                return QuickTunnelConfig(additional_config=additional_config, cloudflared_binary=config['cloudflared_binary'])\n            else:\n                raise Exception(f\"Unknown cloudflared mode {cfd_mode}\")\n\n        return _component_tests_config\n\n\n# This fixture is automatically called before each tests to make sure the previous cloudflared has been shutdown\n@pytest.fixture(autouse=True)\ndef wait_previous_cloudflared():\n    sleep(BACKOFF_SECS)\n"
  },
  {
    "path": "component-tests/constants.py",
    "content": "METRICS_PORT = 51000\nMAX_RETRIES = 5\nBACKOFF_SECS = 7\nMAX_LOG_LINES = 50\n\nMANAGEMENT_HOST_NAME = \"management.argotunnel.com\"\n\n\ndef protocols():\n    return [\"http2\", \"quic\"]\n"
  },
  {
    "path": "component-tests/requirements.txt",
    "content": "cloudflare==2.14.3\nflaky==3.7.0\npytest==7.3.1\npytest-asyncio==0.21.0\npyyaml==6.0.1\nrequests==2.28.2\nretrying==1.3.4\nwebsockets==11.0.1\n"
  },
  {
    "path": "component-tests/setup.py",
    "content": "#!/usr/bin/env python\nimport argparse\nimport base64\nimport json\nimport os\nimport subprocess\nimport uuid\n\nimport CloudFlare\nimport yaml\nfrom retrying import retry\n\nfrom constants import MAX_RETRIES, BACKOFF_SECS\nfrom util import LOGGER\n\n\ndef get_config_from_env():\n    config_content = base64.b64decode(get_env(\"COMPONENT_TESTS_CONFIG_CONTENT\")).decode('utf-8')\n    return yaml.safe_load(config_content)\n\n\ndef get_config_from_file():\n    config_path = get_env(\"COMPONENT_TESTS_CONFIG\")\n    with open(config_path, 'r') as infile:\n        return yaml.safe_load(infile)\n\n\ndef persist_config(config):\n    config_path = get_env(\"COMPONENT_TESTS_CONFIG\")\n    with open(config_path, 'w') as outfile:\n        yaml.safe_dump(config, outfile)\n\n\ndef persist_origin_cert(config):\n    origincert = get_env(\"COMPONENT_TESTS_ORIGINCERT\")\n    path = config[\"origincert\"]\n    with open(path, 'w') as outfile:\n        outfile.write(origincert)\n    return path\n\n\n@retry(stop_max_attempt_number=MAX_RETRIES, wait_fixed=BACKOFF_SECS * 1000)\ndef create_tunnel(config, origincert_path, random_uuid):\n    # Delete any previous existing credentials file. If the agent keeps files around (that's the case in Windows) then\n    # cloudflared tunnel create will refuse to create the tunnel because it does not want to overwrite credentials\n    # files.\n    credentials_path = config[\"credentials_file\"]\n    try:\n        os.remove(credentials_path)\n    except OSError:\n        pass\n\n    tunnel_name = \"cfd_component_test-\" + random_uuid\n    create_cmd = [config[\"cloudflared_binary\"], \"tunnel\", \"--origincert\", origincert_path, \"create\",\n                  \"--credentials-file\", credentials_path, tunnel_name]\n    LOGGER.info(f\"Creating tunnel with {create_cmd}\")\n    subprocess.run(create_cmd, check=True)\n\n    list_cmd = [config[\"cloudflared_binary\"], \"tunnel\", \"--origincert\", origincert_path, \"list\", \"--name\",\n                tunnel_name, \"--output\", \"json\"]\n    LOGGER.info(f\"Listing tunnel with {list_cmd}\")\n    cloudflared = subprocess.run(list_cmd, check=True, capture_output=True)\n    return json.loads(cloudflared.stdout)[0][\"id\"]\n\n\n@retry(stop_max_attempt_number=MAX_RETRIES, wait_fixed=BACKOFF_SECS * 1000)\ndef delete_tunnel(config):\n    credentials_path = config[\"credentials_file\"]\n    delete_cmd = [config[\"cloudflared_binary\"], \"tunnel\", \"--origincert\", config[\"origincert\"], \"delete\",\n                  \"--credentials-file\", credentials_path, \"-f\", config[\"tunnel\"]]\n    LOGGER.info(f\"Deleting tunnel with {delete_cmd}\")\n    subprocess.run(delete_cmd, check=True)\n\n\n@retry(stop_max_attempt_number=MAX_RETRIES, wait_fixed=BACKOFF_SECS * 1000)\ndef create_dns(config, hostname, type, content):\n    cf = CloudFlare.CloudFlare(debug=False, token=get_env(\"DNS_API_TOKEN\"))\n    cf.zones.dns_records.post(\n        config[\"zone_tag\"],\n        data={'name': hostname, 'type': type, 'content': content, 'proxied': True}\n    )\n\n\ndef create_named_dns(config, random_uuid):\n    hostname = \"named-\" + random_uuid + \".\" + config[\"zone_domain\"]\n    create_dns(config, hostname, \"CNAME\", config[\"tunnel\"] + \".cfargotunnel.com\")\n    return hostname\n\n\n@retry(stop_max_attempt_number=MAX_RETRIES, wait_fixed=BACKOFF_SECS * 1000)\ndef delete_dns(config, hostname):\n    cf = CloudFlare.CloudFlare(debug=False, token=get_env(\"DNS_API_TOKEN\"))\n    zone_tag = config[\"zone_tag\"]\n    dns_records = cf.zones.dns_records.get(zone_tag, params={'name': hostname})\n    if len(dns_records) > 0:\n        cf.zones.dns_records.delete(zone_tag, dns_records[0]['id'])\n\n\ndef write_file(content, path):\n    with open(path, 'w') as outfile:\n        outfile.write(content)\n\n\ndef get_env(env_name):\n    val = os.getenv(env_name)\n    if val is None:\n        raise Exception(f\"{env_name} is not set\")\n    return val\n\n\ndef create():\n    \"\"\"\n    Creates the necessary resources for the components test to run.\n     - Creates a named tunnel with a random name.\n     - Creates a random CNAME DNS entry for that tunnel.\n\n    Those created resources are added to the config (obtained from an environment variable).\n    The resulting configuration is persisted for the tests to use.\n    \"\"\"\n    config = get_config_from_env()\n    origincert_path = persist_origin_cert(config)\n\n    random_uuid = str(uuid.uuid4())\n    config[\"tunnel\"] = create_tunnel(config, origincert_path, random_uuid)\n    config[\"ingress\"] = [\n        {\n            \"hostname\": create_named_dns(config, random_uuid),\n            \"service\": \"hello_world\"\n        },\n        {\n            \"service\": \"http_status:404\"\n        }\n    ]\n\n    persist_config(config)\n\n\ndef cleanup():\n    \"\"\"\n    Reads the persisted configuration that was created previously.\n    Deletes the resources that were created there.\n    \"\"\"\n    config = get_config_from_file()\n    delete_tunnel(config)\n    delete_dns(config, config[\"ingress\"][0][\"hostname\"])\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser(description='setup component tests')\n    parser.add_argument('--type', choices=['create', 'cleanup'], default='create')\n    args = parser.parse_args()\n\n    if args.type == 'create':\n        create()\n    else:\n        cleanup()\n"
  },
  {
    "path": "component-tests/test_config.py",
    "content": "#!/usr/bin/env python\nfrom util import start_cloudflared\n\n\nclass TestConfig:\n    # tmp_path is a fixture provides a temporary directory unique to the test invocation\n    def test_validate_ingress_rules(self, tmp_path, component_tests_config):\n        extra_config = {\n            'ingress': [\n                {\n                    \"hostname\": \"example.com\",\n                    \"service\": \"https://localhost:8000\",\n                    \"originRequest\": {\n                        \"originServerName\": \"test.example.com\",\n                        \"caPool\": \"/etc/certs/ca.pem\"\n                    },\n                },\n                {\n                    \"hostname\": \"api.example.com\",\n                    \"path\": \"login\",\n                    \"service\": \"https://localhost:9000\",\n                },\n                {\n                    \"hostname\": \"wss.example.com\",\n                    \"service\": \"wss://localhost:8000\",\n                },\n                {\n                    \"hostname\": \"ssh.example.com\",\n                    \"service\": \"ssh://localhost:8000\",\n                },\n                {\"service\": \"http_status:404\"}\n            ],\n        }\n        config = component_tests_config(extra_config)\n        validate_args = [\"ingress\", \"validate\"]\n        _ = start_cloudflared(tmp_path, config, validate_args)\n\n        self.match_rule(tmp_path, config,\n                        \"http://example.com/index.html\", 0)\n        self.match_rule(tmp_path, config,\n                        \"https://example.com/index.html\", 0)\n        self.match_rule(tmp_path, config,\n                        \"https://api.example.com/login\", 1)\n        self.match_rule(tmp_path, config,\n                        \"https://wss.example.com\", 2)\n        self.match_rule(tmp_path, config,\n                        \"https://ssh.example.com\", 3)\n        self.match_rule(tmp_path, config,\n                        \"https://api.example.com\", 4)\n\n    # This is used to check that the command tunnel ingress url <url> matches rule number <rule_num>. Note that rule number uses 1-based indexing\n\n    def match_rule(self, tmp_path, config, url, rule_num):\n        args = [\"ingress\", \"rule\", url]\n        match_rule = start_cloudflared(tmp_path, config, args)\n\n        assert f\"Matched rule #{rule_num}\" .encode() in match_rule.stdout\n"
  },
  {
    "path": "component-tests/test_edge_discovery.py",
    "content": "import ipaddress\nimport socket\n\nimport pytest\n\nfrom constants import protocols\nfrom cli import CloudflaredCli\nfrom util import get_tunnel_connector_id, LOGGER, wait_tunnel_ready, write_config\n\n\nclass TestEdgeDiscovery:\n    def _extra_config(self, protocol, edge_ip_version):\n        config = {\n            \"protocol\": protocol,\n        }\n        if edge_ip_version:\n            config[\"edge-ip-version\"] = edge_ip_version\n        return config\n\n    @pytest.mark.parametrize(\"protocol\", protocols())\n    def test_default_only(self, tmp_path, component_tests_config, protocol):\n        \"\"\"\n        This test runs a tunnel to connect via IPv4-only edge addresses (default is unset \"--edge-ip-version 4\")\n        \"\"\"\n        if self.has_ipv6_only():\n            pytest.skip(\"Host has IPv6 only support and current default is IPv4 only\")\n        self.expect_address_connections(\n            tmp_path, component_tests_config, protocol, None, self.expect_ipv4_address)\n\n    @pytest.mark.parametrize(\"protocol\", protocols())\n    def test_ipv4_only(self, tmp_path, component_tests_config, protocol):\n        \"\"\"\n        This test runs a tunnel to connect via IPv4-only edge addresses\n        \"\"\"\n        if self.has_ipv6_only():\n            pytest.skip(\"Host has IPv6 only support\")\n        self.expect_address_connections(\n            tmp_path, component_tests_config, protocol, \"4\", self.expect_ipv4_address)\n\n    @pytest.mark.parametrize(\"protocol\", protocols())\n    def test_ipv6_only(self, tmp_path, component_tests_config, protocol):\n        \"\"\"\n        This test runs a tunnel to connect via IPv6-only edge addresses\n        \"\"\"\n        if self.has_ipv4_only():\n            pytest.skip(\"Host has IPv4 only support\")\n        self.expect_address_connections(\n            tmp_path, component_tests_config, protocol, \"6\", self.expect_ipv6_address)\n\n    @pytest.mark.parametrize(\"protocol\", protocols())\n    def test_auto_ip64(self, tmp_path, component_tests_config, protocol):\n        \"\"\"\n        This test runs a tunnel to connect via auto with a preference of IPv6 then IPv4 addresses for a dual stack host\n\n        This test also assumes that the host has IPv6 preference.\n        \"\"\"\n        if not self.has_dual_stack(address_family_preference=socket.AddressFamily.AF_INET6):\n            pytest.skip(\"Host does not support dual stack with IPv6 preference\")\n        self.expect_address_connections(\n            tmp_path, component_tests_config, protocol, \"auto\", self.expect_ipv6_address)\n\n    @pytest.mark.parametrize(\"protocol\", protocols())\n    def test_auto_ip46(self, tmp_path, component_tests_config, protocol):\n        \"\"\"\n        This test runs a tunnel to connect via auto with a preference of IPv4 then IPv6 addresses for a dual stack host\n\n        This test also assumes that the host has IPv4 preference.\n        \"\"\"\n        if not self.has_dual_stack(address_family_preference=socket.AddressFamily.AF_INET):\n            pytest.skip(\"Host does not support dual stack with IPv4 preference\")\n        self.expect_address_connections(\n            tmp_path, component_tests_config, protocol, \"auto\", self.expect_ipv4_address)\n\n    def expect_address_connections(self, tmp_path, component_tests_config, protocol, edge_ip_version, assert_address_type):\n        config = component_tests_config(\n            self._extra_config(protocol, edge_ip_version))\n        config_path = write_config(tmp_path, config.full_config)\n        LOGGER.debug(config)\n        with CloudflaredCli(config, config_path, LOGGER):\n            wait_tunnel_ready(tunnel_url=config.get_url(),\n                              require_min_connections=4)\n            cfd_cli = CloudflaredCli(config, config_path, LOGGER)\n            tunnel_id = config.get_tunnel_id()\n            info = cfd_cli.get_tunnel_info(tunnel_id)\n            connector_id = get_tunnel_connector_id()\n            connector = next(\n                (c for c in info[\"conns\"] if c[\"id\"] == connector_id), None)\n            assert connector, f\"Expected connection info from get tunnel info for the connected instance: {info}\"\n            conns = connector[\"conns\"]\n            assert conns == None or len(\n                conns) == 4, f\"There should be 4 connections registered: {conns}\"\n            for conn in conns:\n                origin_ip = conn[\"origin_ip\"]\n                assert origin_ip, f\"No available origin_ip for this connection: {conn}\"\n                assert_address_type(origin_ip)\n\n    def expect_ipv4_address(self, address):\n        assert type(ipaddress.ip_address(\n            address)) is ipaddress.IPv4Address, f\"Expected connection from origin to be a valid IPv4 address: {address}\"\n\n    def expect_ipv6_address(self, address):\n        assert type(ipaddress.ip_address(\n            address)) is ipaddress.IPv6Address, f\"Expected connection from origin to be a valid IPv6 address: {address}\"\n\n    def get_addresses(self):\n        \"\"\"\n        Returns a list of addresses for the host.\n        \"\"\"\n        host_addresses = socket.getaddrinfo(\n            \"region1.v2.argotunnel.com\", 7844, socket.AF_UNSPEC, socket.SOCK_STREAM)\n        assert len(\n            host_addresses) > 0, \"No addresses returned from getaddrinfo\"\n        return host_addresses\n\n    def has_dual_stack(self, address_family_preference=None):\n        \"\"\"\n        Returns true if the host has dual stack support and can optionally check \n        the provided IP family preference.\n        \"\"\"\n        dual_stack = not self.has_ipv6_only() and not self.has_ipv4_only()\n        if address_family_preference:\n            address = self.get_addresses()[0]\n            return dual_stack and address[0] == address_family_preference\n\n        return dual_stack\n\n    def has_ipv6_only(self):\n        \"\"\"\n        Returns True if the host has only IPv6 address support.\n        \"\"\"\n        return self.attempt_connection(socket.AddressFamily.AF_INET6) and not self.attempt_connection(socket.AddressFamily.AF_INET)\n\n    def has_ipv4_only(self):\n        \"\"\"\n        Returns True if the host has only IPv4 address support.\n        \"\"\"\n        return self.attempt_connection(socket.AddressFamily.AF_INET) and not self.attempt_connection(socket.AddressFamily.AF_INET6)\n\n    def attempt_connection(self, address_family):\n        \"\"\"\n        Returns True if a successful socket connection can be made to the \n        remote host with the provided address family to validate host support \n        for the provided address family.\n        \"\"\"\n        address = None\n        for a in self.get_addresses():\n            if a[0] == address_family:\n                address = a\n                break\n        if address is None:\n            # Couldn't even lookup the address family so we can't connect\n            return False\n        af, socktype, proto, canonname, sockaddr = address\n        s = None\n        try:\n            s = socket.socket(af, socktype, proto)\n        except OSError:\n            return False\n        try:\n            s.connect(sockaddr)\n        except OSError:\n            s.close()\n            return False\n        s.close()\n        return True\n"
  },
  {
    "path": "component-tests/test_logging.py",
    "content": "#!/usr/bin/env python\nimport json\nimport os\n\nfrom constants import MAX_LOG_LINES\nfrom util import start_cloudflared, wait_tunnel_ready, send_requests\n\n# Rolling logger rotate log files after 1 MB\nrotate_after_size = 1000 * 1000\ndefault_log_file = \"cloudflared.log\"\nexpect_message = \"Starting Hello\"\n\n\ndef assert_log_to_terminal(cloudflared):\n    for _ in range(0, MAX_LOG_LINES):\n        line = cloudflared.stderr.readline()\n        if not line:\n            break\n        if expect_message.encode() in line:\n            return\n    raise Exception(f\"terminal log doesn't contain {expect_message}\")\n\n\ndef assert_log_in_file(file):\n    with open(file, \"r\") as f:\n        for _ in range(0, MAX_LOG_LINES):\n            line = f.readline()\n            if not line:\n                break\n            if expect_message in line:\n                return\n    raise Exception(f\"log file doesn't contain {expect_message}\")\n\n\ndef assert_json_log(file):\n    def assert_in_json(j, key):\n        assert key in j, f\"{key} is not in j\"\n\n    with open(file, \"r\") as f:\n        line = f.readline()\n        json_log = json.loads(line)\n        assert_in_json(json_log, \"level\")\n        assert_in_json(json_log, \"time\")\n        assert_in_json(json_log, \"message\")\n\n\ndef assert_log_to_dir(config, log_dir):\n    max_batches = 3\n    batch_requests = 1000\n    for _ in range(max_batches):\n        send_requests(config.get_url(),\n                      batch_requests, require_ok=False)\n        files = os.listdir(log_dir)\n        if len(files) == 2:\n            current_log_file_index = files.index(default_log_file)\n            current_file = log_dir / files[current_log_file_index]\n            stats = os.stat(current_file)\n            assert stats.st_size > 0\n            assert_json_log(current_file)\n\n            # One file is the current log file, the other is the rotated log file\n            rotated_log_file_index = 0 if current_log_file_index == 1 else 1\n            rotated_file = log_dir / files[rotated_log_file_index]\n            stats = os.stat(rotated_file)\n            assert stats.st_size > rotate_after_size\n            assert_log_in_file(rotated_file)\n            assert_json_log(current_file)\n            return\n\n    raise Exception(\n        f\"Log file isn't rotated after sending {max_batches * batch_requests} requests\")\n\n\nclass TestLogging:\n    def test_logging_to_terminal(self, tmp_path, component_tests_config):\n        config = component_tests_config()\n        with start_cloudflared(tmp_path, config, cfd_pre_args=[\"tunnel\", \"--ha-connections\", \"1\"], new_process=True) as cloudflared:\n            wait_tunnel_ready(tunnel_url=config.get_url())\n            assert_log_to_terminal(cloudflared)\n\n    def test_logging_to_file(self, tmp_path, component_tests_config):\n        log_file = tmp_path / default_log_file\n        extra_config = {\n            # Convert from pathlib.Path to str\n            \"logfile\": str(log_file),\n        }\n        config = component_tests_config(extra_config)\n        with start_cloudflared(tmp_path, config, cfd_pre_args=[\"tunnel\", \"--ha-connections\", \"1\"], new_process=True, capture_output=False):\n            wait_tunnel_ready(tunnel_url=config.get_url(), cfd_logs=str(log_file))\n            assert_log_in_file(log_file)\n            assert_json_log(log_file)\n\n    def test_logging_to_dir(self, tmp_path, component_tests_config):\n        log_dir = tmp_path / \"logs\"\n        extra_config = {\n            \"loglevel\": \"debug\",\n            # Convert from pathlib.Path to str\n            \"log-directory\": str(log_dir),\n        }\n        config = component_tests_config(extra_config)\n        with start_cloudflared(tmp_path, config, cfd_pre_args=[\"tunnel\", \"--ha-connections\", \"1\"], new_process=True, capture_output=False):\n            wait_tunnel_ready(tunnel_url=config.get_url(), cfd_logs=str(log_dir))\n            assert_log_to_dir(config, log_dir)\n"
  },
  {
    "path": "component-tests/test_management.py",
    "content": "#!/usr/bin/env python\nimport json\nimport requests\nfrom conftest import CfdModes\nfrom constants import METRICS_PORT, MAX_RETRIES, BACKOFF_SECS\nfrom retrying import retry\nfrom cli import CloudflaredCli\nfrom util import LOGGER, write_config, start_cloudflared, wait_tunnel_ready, send_requests, decode_jwt_payload\nimport platform\n\n\"\"\"\nEach test in TestManagement will:\n1. Acquire a management token from Cloudflare public API\n2. Make a request against the management service for the running tunnel\n\"\"\"\nclass TestManagement:\n    \"\"\"\n        test_get_host_details does the following:\n        1. It gets a management token from Tunnelstore using cloudflared tail token <tunnel_id>\n        2. It gets the connector_id after starting a cloudflare tunnel\n        3. It sends a request to the management host with the connector_id and management token\n        4. Asserts that the response has a hostname and ip.\n    \"\"\"\n    def test_get_host_details(self, tmp_path, component_tests_config):\n        # TUN-7377 : wait_tunnel_ready does not work properly in windows.\n        # Skipping this test for windows for now and will address it as part of tun-7377\n        if platform.system() == \"Windows\":\n            return\n        config = component_tests_config(cfd_mode=CfdModes.NAMED, provide_ingress=False)\n        LOGGER.debug(config)\n        headers = {}\n        headers[\"Content-Type\"] = \"application/json\"\n        config_path = write_config(tmp_path, config.full_config)\n        with start_cloudflared(tmp_path, config, cfd_pre_args=[\"tunnel\", \"--ha-connections\", \"1\", \"--label\" , \"test\"], cfd_args=[\"run\", \"--hello-world\"], new_process=True):\n            wait_tunnel_ready(tunnel_url=config.get_url(),\n                              require_min_connections=1)\n            cfd_cli = CloudflaredCli(config, config_path, LOGGER)\n            connector_id = cfd_cli.get_connector_id(config)[0]\n            url = cfd_cli.get_management_url(\"host_details\", config, config_path, resource=\"host_details\")\n            resp = send_request(url, headers=headers)\n            \n            # Assert response json.\n            assert resp.status_code == 200, \"Expected cloudflared to return 200 for host details\"\n            assert resp.json()[\"hostname\"] == \"custom:test\", \"Expected cloudflared to return hostname\"\n            assert resp.json()[\"ip\"] != \"\", \"Expected cloudflared to return ip\"\n            assert resp.json()[\"connector_id\"] == connector_id, \"Expected cloudflared to return connector_id\"\n    \n    \"\"\"\n        test_get_metrics will verify that the /metrics endpoint returns the prometheus metrics dump\n    \"\"\"\n    def test_get_metrics(self, tmp_path, component_tests_config):\n        # TUN-7377 : wait_tunnel_ready does not work properly in windows.\n        # Skipping this test for windows for now and will address it as part of tun-7377\n        if platform.system() == \"Windows\":\n            return\n        config = component_tests_config(cfd_mode=CfdModes.NAMED, provide_ingress=False)\n        LOGGER.debug(config)\n        config_path = write_config(tmp_path, config.full_config)\n        with start_cloudflared(tmp_path, config, cfd_pre_args=[\"tunnel\", \"--ha-connections\", \"1\"], new_process=True):\n            wait_tunnel_ready(require_min_connections=1)\n            cfd_cli = CloudflaredCli(config, config_path, LOGGER)\n            url = cfd_cli.get_management_url(\"metrics\", config, config_path, resource=\"admin\")\n            resp = send_request(url)\n            \n            # Assert response.\n            assert resp.status_code == 200, \"Expected cloudflared to return 200 for /metrics\"\n            assert \"# HELP build_info Build and version information\" in resp.text, \"Expected /metrics to have with the build_info details\"\n\n    \"\"\"\n        test_get_pprof_heap will verify that the /debug/pprof/heap endpoint returns a pprof/heap dump response\n    \"\"\"\n    def test_get_pprof_heap(self, tmp_path, component_tests_config):\n        # TUN-7377 : wait_tunnel_ready does not work properly in windows.\n        # Skipping this test for windows for now and will address it as part of tun-7377\n        if platform.system() == \"Windows\":\n            return\n        config = component_tests_config(cfd_mode=CfdModes.NAMED, provide_ingress=False)\n        LOGGER.debug(config)\n        config_path = write_config(tmp_path, config.full_config)\n        with start_cloudflared(tmp_path, config, cfd_pre_args=[\"tunnel\", \"--ha-connections\", \"1\"], new_process=True):\n            wait_tunnel_ready(require_min_connections=1)\n            cfd_cli = CloudflaredCli(config, config_path, LOGGER)\n            url = cfd_cli.get_management_url(\"debug/pprof/heap\", config, config_path, resource=\"admin\")\n            resp = send_request(url)\n            \n            # Assert response.\n            assert resp.status_code == 200, \"Expected cloudflared to return 200 for /debug/pprof/heap\"\n            assert resp.headers[\"Content-Type\"] == \"application/octet-stream\", \"Expected /debug/pprof/heap to have return a binary response\"\n    \n    \"\"\"\n        test_get_metrics_when_disabled will verify that diagnostic endpoints (such as /metrics) return 404 and are unmounted. \n    \"\"\"\n    def test_get_metrics_when_disabled(self, tmp_path, component_tests_config):\n        # TUN-7377 : wait_tunnel_ready does not work properly in windows.\n        # Skipping this test for windows for now and will address it as part of tun-7377\n        if platform.system() == \"Windows\":\n            return\n        config = component_tests_config(cfd_mode=CfdModes.NAMED, provide_ingress=False)\n        LOGGER.debug(config)\n        config_path = write_config(tmp_path, config.full_config)\n        with start_cloudflared(tmp_path, config, cfd_pre_args=[\"tunnel\", \"--ha-connections\", \"1\", \"--management-diagnostics=false\"], new_process=True):\n            wait_tunnel_ready(require_min_connections=1)\n            cfd_cli = CloudflaredCli(config, config_path, LOGGER)\n            url = cfd_cli.get_management_url(\"metrics\", config, config_path, resource=\"admin\")\n            resp = send_request(url)\n            \n            # Assert response.\n            assert resp.status_code == 404, \"Expected cloudflared to return 404 for /metrics\"\n\n    def test_tail_token_command(self, tmp_path, component_tests_config):\n        \"\"\"\n        Validates that 'cloudflared tail token' command returns a token \n        scoped for 'logs' and 'ping' resources.\n        \"\"\"\n        # TUN-7377: wait_tunnel_ready does not work properly in windows\n        if platform.system() == \"Windows\":\n            return\n        \n        config = component_tests_config(cfd_mode=CfdModes.NAMED, provide_ingress=False)\n        LOGGER.debug(config)\n        config_path = write_config(tmp_path, config.full_config)\n        \n        cfd_cli = CloudflaredCli(config, config_path, LOGGER)\n        token = cfd_cli.get_tail_token(config, config_path)\n        \n        # Verify token was returned\n        assert token, \"Expected non-empty token to be returned\"\n        \n        # Decode JWT payload to verify resource claims\n        claims = decode_jwt_payload(token)\n\n        resource_tag = 'res'\n        # Verify the token has 'logs' and 'ping' in resource array\n        assert resource_tag in claims, f\"Expected {resource_tag} claim in token\"\n        assert isinstance(claims['res'], list), f\"Expected {resource_tag} to be an array\"\n        assert 'logs' in claims[resource_tag], \\\n            f\"Expected 'logs' in resource array, got: {claims[resource_tag]}\"\n        assert 'ping' in claims[resource_tag], \\\n            f\"Expected 'ping' in resource array, got: {claims[resource_tag]}\"\n        \n        LOGGER.info(f\"Tail token successfully verified with resources: {claims[resource_tag]}\")\n\n\n\n\n@retry(stop_max_attempt_number=MAX_RETRIES, wait_fixed=BACKOFF_SECS * 1000)\ndef send_request(url, headers={}):\n    with requests.Session() as s:\n        resp = s.get(url, timeout=BACKOFF_SECS, headers=headers)\n        if resp.status_code == 530:\n            LOGGER.debug(f\"Received 530 status, retrying request to {url}\")\n            raise Exception(f\"Received 530 status code from {url}\")\n        return resp\n"
  },
  {
    "path": "component-tests/test_pq.py",
    "content": "from util import LOGGER, start_cloudflared, wait_tunnel_ready\n\n\nclass TestPostQuantum:\n    def _extra_config(self):\n        config = {\n            \"protocol\": \"quic\",\n        }\n        return config\n\n    def test_post_quantum(self, tmp_path, component_tests_config):\n        config = component_tests_config(self._extra_config())\n        LOGGER.debug(config)\n        with start_cloudflared(\n            tmp_path,\n            config,\n            cfd_pre_args=[\"tunnel\", \"--ha-connections\", \"1\"],\n            cfd_args=[\"run\", \"--post-quantum\"],\n            new_process=True,\n        ):\n            wait_tunnel_ready(tunnel_url=config.get_url(), require_min_connections=1)\n"
  },
  {
    "path": "component-tests/test_quicktunnels.py",
    "content": "#!/usr/bin/env python\nfrom conftest import CfdModes\nfrom constants import METRICS_PORT\nimport time\nfrom util import LOGGER, start_cloudflared, wait_tunnel_ready, get_quicktunnel_url, send_requests\n\nclass TestQuickTunnels:\n    def test_quick_tunnel(self, tmp_path, component_tests_config):\n        config = component_tests_config(cfd_mode=CfdModes.QUICK)\n        LOGGER.debug(config)\n        with start_cloudflared(tmp_path, config, cfd_pre_args=[\"tunnel\", \"--ha-connections\", \"1\"], cfd_args=[\"--hello-world\"], new_process=True):\n            wait_tunnel_ready(require_min_connections=1)\n            time.sleep(10)\n            url = get_quicktunnel_url()\n            send_requests(url, 3, True)\n    \n    def test_quick_tunnel_url(self, tmp_path, component_tests_config):\n        config = component_tests_config(cfd_mode=CfdModes.QUICK)\n        LOGGER.debug(config)\n        with start_cloudflared(tmp_path, config, cfd_pre_args=[\"tunnel\", \"--ha-connections\", \"1\"], cfd_args=[\"--url\", f\"http://localhost:{METRICS_PORT}/\"], new_process=True):\n            wait_tunnel_ready(require_min_connections=1)\n            time.sleep(10)\n            url = get_quicktunnel_url()\n            send_requests(url+\"/ready\", 3, True)\n"
  },
  {
    "path": "component-tests/test_reconnect.py",
    "content": "#!/usr/bin/env python\nimport copy\nimport platform\nfrom time import sleep\n\nimport pytest\nfrom flaky import flaky\n\nfrom conftest import CfdModes\nfrom constants import protocols\nfrom util import start_cloudflared, wait_tunnel_ready, check_tunnel_not_connected\n\n\n@flaky(max_runs=3, min_passes=1)\nclass TestReconnect:\n    default_ha_conns = 1\n    default_reconnect_secs = 15\n    extra_config = {\n        \"stdin-control\": True,\n    }\n\n    def _extra_config(self, protocol):\n        return {\n            \"stdin-control\": True,\n            \"protocol\": protocol,\n        }\n\n    @pytest.mark.skipif(platform.system() == \"Windows\", reason=f\"Currently buggy on Windows TUN-4584\")\n    @pytest.mark.parametrize(\"protocol\", protocols())\n    def test_named_reconnect(self, tmp_path, component_tests_config, protocol):\n        config = component_tests_config(self._extra_config(protocol))\n        with start_cloudflared(tmp_path, config, cfd_pre_args=[\"tunnel\", \"--ha-connections\", \"1\"], new_process=True, allow_input=True, capture_output=False) as cloudflared:\n            # Repeat the test multiple times because some issues only occur after multiple reconnects\n            self.assert_reconnect(config, cloudflared, 5)\n\n    def send_reconnect(self, cloudflared, secs):\n        # Although it is recommended to use the Popen.communicate method, we cannot\n        # use it because it blocks on reading stdout and stderr until EOF is reached\n        cloudflared.stdin.write(f\"reconnect {secs}s\\n\".encode())\n        cloudflared.stdin.flush()\n\n    def assert_reconnect(self, config, cloudflared, repeat):\n        wait_tunnel_ready(tunnel_url=config.get_url(),\n                          require_min_connections=self.default_ha_conns)\n        for _ in range(repeat):\n            for _ in range(self.default_ha_conns):\n                self.send_reconnect(cloudflared, self.default_reconnect_secs)\n            check_tunnel_not_connected()\n            sleep(self.default_reconnect_secs * 2)\n            wait_tunnel_ready(tunnel_url=config.get_url(),\n                              require_min_connections=self.default_ha_conns)\n"
  },
  {
    "path": "component-tests/test_service.py",
    "content": "#!/usr/bin/env python\nimport os\nimport pathlib\nimport subprocess\nfrom contextlib import contextmanager\nfrom pathlib import Path\n\nimport pytest\n\nimport test_logging\nfrom conftest import CfdModes\nfrom util import select_platform, skip_on_ci, start_cloudflared, wait_tunnel_ready, write_config\n\n\ndef default_config_dir():\n    return os.path.join(Path.home(), \".cloudflared\")\n\n\ndef default_config_file():\n    return os.path.join(default_config_dir(), \"config.yml\")\n\n\nclass TestServiceMode:\n    @select_platform(\"Darwin\")\n    @pytest.mark.skipif(os.path.exists(default_config_file()), reason=f\"There is already a config file in default path\")\n    def test_launchd_service_log_to_file(self, tmp_path, component_tests_config):\n        log_file = tmp_path / test_logging.default_log_file\n        additional_config = {\n            # On Darwin cloudflared service defaults to run classic tunnel command\n            \"hello-world\": True,\n            \"logfile\": str(log_file),\n        }\n        config = component_tests_config(additional_config=additional_config, cfd_mode=CfdModes.CLASSIC)\n\n        def assert_log_file():\n            test_logging.assert_log_in_file(log_file)\n            test_logging.assert_json_log(log_file)\n\n        self.launchd_service_scenario(config, assert_log_file)\n\n    @select_platform(\"Darwin\")\n    @pytest.mark.skipif(os.path.exists(default_config_file()), reason=f\"There is already a config file in default path\")\n    def test_launchd_service_with_token(self, tmp_path, component_tests_config):\n        log_file = tmp_path / test_logging.default_log_file\n        additional_config = {\n            \"logfile\": str(log_file),\n        }\n        config = component_tests_config(additional_config=additional_config)\n\n        # service install doesn't install the config file but in this case we want to use some default settings\n        # so we write the base config without the tunnel credentials and ID\n        write_config(pathlib.Path(default_config_dir()), config.base_config())\n\n        self.launchd_service_scenario(config, use_token=True)\n\n    @select_platform(\"Darwin\")\n    @pytest.mark.skipif(os.path.exists(default_config_file()), reason=f\"There is already a config file in default path\")\n    def test_launchd_service_rotating_log(self, tmp_path, component_tests_config):\n        log_dir = tmp_path / \"logs\"\n        additional_config = {\n            # On Darwin cloudflared service defaults to run classic tunnel command\n            \"hello-world\": True,\n            \"loglevel\": \"debug\",\n            \"log-directory\": str(log_dir),\n        }\n        config = component_tests_config(additional_config=additional_config, cfd_mode=CfdModes.CLASSIC)\n\n        def assert_rotating_log():\n            test_logging.assert_log_to_dir(config, log_dir)\n\n        self.launchd_service_scenario(config, assert_rotating_log)\n\n    def launchd_service_scenario(self, config, extra_assertions=None, use_token=False):\n        with self.run_service(Path(default_config_dir()), config, use_token=use_token):\n            self.launchctl_cmd(\"list\")\n            self.launchctl_cmd(\"start\")\n            wait_tunnel_ready(tunnel_url=config.get_url())\n            if extra_assertions is not None:\n                extra_assertions()\n            self.launchctl_cmd(\"stop\")\n\n        os.remove(default_config_file())\n        self.launchctl_cmd(\"list\", success=False)\n\n    @skip_on_ci(\"we can't run sudo command on CI\")\n    @select_platform(\"Linux\")\n    @pytest.mark.skipif(os.path.exists(\"/etc/cloudflared/config.yml\"),\n                        reason=f\"There is already a config file in default path\")\n    def test_sysv_service_log_to_file(self, tmp_path, component_tests_config):\n        log_file = tmp_path / test_logging.default_log_file\n        additional_config = {\n            \"logfile\": str(log_file),\n        }\n        config = component_tests_config(additional_config=additional_config)\n\n        def assert_log_file():\n            test_logging.assert_log_in_file(log_file)\n            test_logging.assert_json_log(log_file)\n\n        self.sysv_service_scenario(config, tmp_path, assert_log_file)\n\n    @skip_on_ci(\"we can't run sudo command on CI\")\n    @select_platform(\"Linux\")\n    @pytest.mark.skipif(os.path.exists(\"/etc/cloudflared/config.yml\"),\n                        reason=f\"There is already a config file in default path\")\n    def test_sysv_service_rotating_log(self, tmp_path, component_tests_config):\n        log_dir = tmp_path / \"logs\"\n        additional_config = {\n            \"loglevel\": \"debug\",\n            \"log-directory\": str(log_dir),\n        }\n        config = component_tests_config(additional_config=additional_config)\n\n        def assert_rotating_log():\n            # We need the folder to have executable permissions for the \"stat\" command in the assertions to work.\n            subprocess.check_call(['sudo', 'chmod', 'o+x', log_dir])\n            test_logging.assert_log_to_dir(config, log_dir)\n\n        self.sysv_service_scenario(config, tmp_path, assert_rotating_log)\n\n    @skip_on_ci(\"we can't run sudo command on CI\")\n    @select_platform(\"Linux\")\n    @pytest.mark.skipif(os.path.exists(\"/etc/cloudflared/config.yml\"),\n                        reason=f\"There is already a config file in default path\")\n    def test_sysv_service_with_token(self, tmp_path, component_tests_config):\n        additional_config = {\n            \"loglevel\": \"debug\",\n        }\n\n        config = component_tests_config(additional_config=additional_config)\n\n        # service install doesn't install the config file but in this case we want to use some default settings\n        # so we write the base config without the tunnel credentials and ID\n        config_path = write_config(tmp_path, config.base_config())\n        subprocess.run([\"sudo\", \"cp\", config_path, \"/etc/cloudflared/config.yml\"], check=True)\n\n        self.sysv_service_scenario(config, tmp_path, use_token=True)\n\n    def sysv_service_scenario(self, config, tmp_path, extra_assertions=None, use_token=False):\n        with self.run_service(tmp_path, config, root=True, use_token=use_token):\n            self.sysv_cmd(\"status\")\n            wait_tunnel_ready(tunnel_url=config.get_url())\n            if extra_assertions is not None:\n                extra_assertions()\n\n        # Service install copies config file to /etc/cloudflared/config.yml\n        subprocess.run([\"sudo\", \"rm\", \"/etc/cloudflared/config.yml\"])\n        self.sysv_cmd(\"status\", success=False)\n\n    @contextmanager\n    def run_service(self, tmp_path, config, root=False, use_token=False):\n        args = [\"service\", \"install\"]\n\n        if use_token:\n            args.append(config.get_token())\n\n        try:\n            service = start_cloudflared(\n                tmp_path, config, cfd_args=args, cfd_pre_args=[], capture_output=False, root=root, skip_config_flag=use_token)\n            yield service\n        finally:\n            start_cloudflared(\n                tmp_path, config, cfd_args=[\"service\", \"uninstall\"], cfd_pre_args=[], capture_output=False, root=root, skip_config_flag=use_token)\n\n    def launchctl_cmd(self, action, success=True):\n        cmd = subprocess.run(\n            [\"launchctl\", action, \"com.cloudflare.cloudflared\"], check=success)\n        if not success:\n            assert cmd.returncode != 0, f\"Expect {cmd.args} to fail, but it succeed\"\n\n    def sysv_cmd(self, action, success=True):\n        cmd = subprocess.run(\n            [\"sudo\", \"service\", \"cloudflared\", action], check=success)\n        if not success:\n            assert cmd.returncode != 0, f\"Expect {cmd.args} to fail, but it succeed\"\n"
  },
  {
    "path": "component-tests/test_tail.py",
    "content": "#!/usr/bin/env python\nimport asyncio\nimport json\nimport pytest\nimport requests\nimport websockets\nfrom websockets.client import connect, WebSocketClientProtocol\nfrom conftest import CfdModes\nfrom constants import MAX_RETRIES, BACKOFF_SECS\nfrom retrying import retry\nfrom cli import CloudflaredCli\nfrom util import LOGGER, start_cloudflared, write_config, wait_tunnel_ready\n\nclass TestTail:\n    @pytest.mark.asyncio\n    async def test_start_stop_streaming(self, tmp_path, component_tests_config):\n        \"\"\"\n        Validates that a websocket connection to management.argotunnel.com/logs can be opened\n        with the access token and start and stop streaming on-demand.\n        \"\"\"\n        print(\"test_start_stop_streaming\")\n        config = component_tests_config(cfd_mode=CfdModes.NAMED, provide_ingress=False)\n        LOGGER.debug(config)\n        config_path = write_config(tmp_path, config.full_config)\n        with start_cloudflared(tmp_path, config, cfd_args=[\"run\", \"--hello-world\"], new_process=True):\n            wait_tunnel_ready(tunnel_url=config.get_url(), require_min_connections=1)\n            cfd_cli = CloudflaredCli(config, config_path, LOGGER)\n            url = cfd_cli.get_management_wsurl(\"logs\", config, config_path, resource=\"logs\")\n            async with connect(url, open_timeout=5, close_timeout=3) as websocket:\n                await websocket.send('{\"type\": \"start_streaming\"}')\n                await websocket.send('{\"type\": \"stop_streaming\"}')\n                await websocket.send('{\"type\": \"start_streaming\"}')\n                await websocket.send('{\"type\": \"stop_streaming\"}')\n\n    @pytest.mark.asyncio\n    async def test_streaming_logs(self, tmp_path, component_tests_config):\n        \"\"\"\n        Validates that a streaming logs connection will stream logs\n        \"\"\"\n        print(\"test_streaming_logs\")\n        config = component_tests_config(cfd_mode=CfdModes.NAMED, provide_ingress=False)\n        LOGGER.debug(config)\n        config_path = write_config(tmp_path, config.full_config)\n        with start_cloudflared(tmp_path, config, cfd_args=[\"run\", \"--hello-world\"], new_process=True):\n            wait_tunnel_ready(tunnel_url=config.get_url(), require_min_connections=1)\n            cfd_cli = CloudflaredCli(config, config_path, LOGGER)\n            url = cfd_cli.get_management_wsurl(\"logs\", config, config_path, resource=\"logs\")\n            async with connect(url, open_timeout=5, close_timeout=5) as websocket:\n                # send start_streaming\n                await websocket.send(json.dumps({\n                    \"type\": \"start_streaming\",\n                    \"filters\": {\n                        \"events\": [\"http\"]\n                    }\n                }))\n                # send some http requests to the tunnel to trigger some logs\n                await generate_and_validate_http_events(websocket, config.get_url(), 10)\n                # send stop_streaming\n                await websocket.send('{\"type\": \"stop_streaming\"}')\n\n    @pytest.mark.asyncio\n    async def test_streaming_logs_filters(self, tmp_path, component_tests_config):\n        \"\"\"\n        Validates that a streaming logs connection will stream logs \n        but not http when filters applied.\n        \"\"\"\n        print(\"test_streaming_logs_filters\")\n        config = component_tests_config(cfd_mode=CfdModes.NAMED, provide_ingress=False)\n        LOGGER.debug(config)\n        config_path = write_config(tmp_path, config.full_config)\n        with start_cloudflared(tmp_path, config, cfd_args=[\"run\", \"--hello-world\"], new_process=True):\n            wait_tunnel_ready(tunnel_url=config.get_url(), require_min_connections=1)\n            cfd_cli = CloudflaredCli(config, config_path, LOGGER)\n            url = cfd_cli.get_management_wsurl(\"logs\", config, config_path, resource=\"logs\")\n            async with connect(url, open_timeout=5, close_timeout=5) as websocket:\n                # send start_streaming with tcp logs only\n                await websocket.send(json.dumps({\n                    \"type\": \"start_streaming\",\n                    \"filters\": {\n                        \"events\": [\"tcp\"],\n                        \"level\": \"debug\"\n                    }\n                }))\n                # don't expect any http logs\n                await generate_and_validate_no_log_event(websocket, config.get_url())\n                # send stop_streaming\n                await websocket.send('{\"type\": \"stop_streaming\"}')\n    \n    @pytest.mark.asyncio\n    async def test_streaming_logs_sampling(self, tmp_path, component_tests_config):\n        \"\"\"\n        Validates that a streaming logs connection will stream logs with sampling.\n        \"\"\"\n        print(\"test_streaming_logs_sampling\")\n        config = component_tests_config(cfd_mode=CfdModes.NAMED, provide_ingress=False)\n        LOGGER.debug(config)\n        config_path = write_config(tmp_path, config.full_config)\n        with start_cloudflared(tmp_path, config, cfd_args=[\"run\", \"--hello-world\"], new_process=True):\n            wait_tunnel_ready(tunnel_url=config.get_url(), require_min_connections=1)\n            cfd_cli = CloudflaredCli(config, config_path, LOGGER)\n            url = cfd_cli.get_management_wsurl(\"logs\", config, config_path, resource=\"logs\")\n            async with connect(url, open_timeout=5, close_timeout=5) as websocket:\n                # send start_streaming with info logs only\n                await websocket.send(json.dumps({\n                    \"type\": \"start_streaming\",\n                    \"filters\": {\n                        \"sampling\": 0.5,\n                        \"events\": [\"http\"]\n                    }\n                }))\n                # don't expect any http logs\n                count = await generate_and_validate_http_events(websocket, config.get_url(), 10)\n                assert count < (10 * 2) # There are typically always two log lines for http requests (request and response)\n                # send stop_streaming\n                await websocket.send('{\"type\": \"stop_streaming\"}')\n\n    @pytest.mark.asyncio\n    async def test_streaming_logs_actor_override(self, tmp_path, component_tests_config):\n        \"\"\"\n        Validates that a streaming logs session can be overriden by the same actor \n        \"\"\"\n        print(\"test_streaming_logs_actor_override\")\n        config = component_tests_config(cfd_mode=CfdModes.NAMED, provide_ingress=False)\n        LOGGER.debug(config)\n        config_path = write_config(tmp_path, config.full_config)\n        with start_cloudflared(tmp_path, config, cfd_args=[\"run\", \"--hello-world\"], new_process=True):\n            wait_tunnel_ready(tunnel_url=config.get_url(), require_min_connections=1)\n            cfd_cli = CloudflaredCli(config, config_path, LOGGER)\n            url = cfd_cli.get_management_wsurl(\"logs\", config, config_path, resource=\"logs\")\n            task = asyncio.ensure_future(start_streaming_to_be_remotely_closed(url))\n            override_task = asyncio.ensure_future(start_streaming_override(url))\n            await asyncio.wait([task, override_task])\n            assert task.exception() == None, task.exception()\n            assert override_task.exception() == None, override_task.exception()\n\nasync def start_streaming_to_be_remotely_closed(url):\n    async with connect(url, open_timeout=5, close_timeout=5) as websocket:\n        try:\n            await websocket.send(json.dumps({\"type\": \"start_streaming\"}))\n            await asyncio.sleep(10)\n            assert websocket.closed, \"expected this request to be forcibly closed by the override\"\n        except websockets.ConnectionClosed:\n            # we expect the request to be closed\n            pass\n\nasync def start_streaming_override(url):\n    # wait for the first connection to be established\n    await asyncio.sleep(1)\n    async with connect(url, open_timeout=5, close_timeout=5) as websocket:\n        await websocket.send(json.dumps({\"type\": \"start_streaming\"}))\n        await asyncio.sleep(1)\n        await websocket.send(json.dumps({\"type\": \"stop_streaming\"}))\n        await asyncio.sleep(1)\n\n# Every http request has two log lines sent\nasync def generate_and_validate_http_events(websocket: WebSocketClientProtocol, url: str, count_send: int):\n    for i in range(count_send):\n        send_request(url)\n    # There are typically always two log lines for http requests (request and response)\n    count = 0\n    while True:\n        try:\n            req_line = await asyncio.wait_for(websocket.recv(), 2)\n            log_line = json.loads(req_line)\n            assert log_line[\"type\"] == \"logs\"\n            assert log_line[\"logs\"][0][\"event\"] == \"http\"\n            count += 1\n        except asyncio.TimeoutError:\n            # ignore timeout from waiting for recv\n            break\n    return count\n\n# Every http request has two log lines sent\nasync def generate_and_validate_no_log_event(websocket: WebSocketClientProtocol, url: str):\n    send_request(url)\n    try:\n        # wait for 5 seconds and make sure we hit the timeout and not recv any events\n        req_line = await asyncio.wait_for(websocket.recv(), 5)\n        assert req_line == None, \"expected no logs for the specified filters\"\n    except asyncio.TimeoutError:\n        pass\n\n@retry(stop_max_attempt_number=MAX_RETRIES, wait_fixed=BACKOFF_SECS * 1000)\ndef send_request(url, headers={}):\n    with requests.Session() as s:\n        resp = s.get(url, timeout=BACKOFF_SECS, headers=headers)\n        assert resp.status_code == 200, f\"{url} returned {resp}\"\n        return resp.status_code == 200"
  },
  {
    "path": "component-tests/test_termination.py",
    "content": "#!/usr/bin/env python\nfrom contextlib import contextmanager\nimport platform\nimport signal\nimport threading\nimport time\n\nimport pytest\nimport requests\n\nfrom constants import protocols\nfrom util import start_cloudflared, wait_tunnel_ready, check_tunnel_not_connected\n\n\ndef supported_signals():\n    if platform.system() == \"Windows\":\n        return [signal.SIGTERM]\n    return [signal.SIGTERM, signal.SIGINT]\n\n\nclass TestTermination:\n    grace_period = 5\n    timeout = 10\n    sse_endpoint = \"/sse?freq=1s\"\n\n    def _extra_config(self, protocol):\n        return {\n            \"grace-period\": f\"{self.grace_period}s\",\n            \"protocol\": protocol,\n        }\n\n    @pytest.mark.parametrize(\"signal\", supported_signals())\n    @pytest.mark.parametrize(\"protocol\", protocols())\n    def test_graceful_shutdown(self, tmp_path, component_tests_config, signal, protocol):\n        config = component_tests_config(self._extra_config(protocol))\n        with start_cloudflared(\n                tmp_path, config, cfd_pre_args=[\"tunnel\", \"--ha-connections\", \"1\"],  new_process=True, capture_output=False) as cloudflared:\n            wait_tunnel_ready(tunnel_url=config.get_url())\n\n            connected = threading.Condition()\n            in_flight_req = threading.Thread(\n                target=self.stream_request, args=(config, connected, False, ))\n            in_flight_req.start()\n\n            with connected:\n                connected.wait(self.timeout)\n            # Send signal after the SSE connection is established\n            with self.within_grace_period():\n                self.terminate_by_signal(cloudflared, signal)\n                self.wait_eyeball_thread(\n                    in_flight_req, self.grace_period + self.timeout)\n\n    # test cloudflared terminates before grace period expires when all eyeball\n    # connections are drained\n    @pytest.mark.parametrize(\"signal\", supported_signals())\n    @pytest.mark.parametrize(\"protocol\", protocols())\n    def test_shutdown_once_no_connection(self, tmp_path, component_tests_config, signal, protocol):\n        config = component_tests_config(self._extra_config(protocol))\n        with start_cloudflared(\n                tmp_path, config, cfd_pre_args=[\"tunnel\", \"--ha-connections\", \"1\"], new_process=True, capture_output=False) as cloudflared:\n            wait_tunnel_ready(tunnel_url=config.get_url())\n\n            connected = threading.Condition()\n            in_flight_req = threading.Thread(\n                target=self.stream_request, args=(config, connected, True, ))\n            in_flight_req.start()\n\n            with connected:\n                connected.wait(self.timeout)\n            with self.within_grace_period(has_connection=False):\n                # Send signal after the SSE connection is established\n                self.terminate_by_signal(cloudflared, signal)\n                self.wait_eyeball_thread(in_flight_req, self.grace_period)\n\n    @pytest.mark.parametrize(\"signal\", supported_signals())\n    @pytest.mark.parametrize(\"protocol\", protocols())\n    def test_no_connection_shutdown(self, tmp_path, component_tests_config, signal, protocol):\n        config = component_tests_config(self._extra_config(protocol))\n        with start_cloudflared(\n                tmp_path, config, cfd_pre_args=[\"tunnel\", \"--ha-connections\", \"1\"], new_process=True, capture_output=False) as cloudflared:\n            wait_tunnel_ready(tunnel_url=config.get_url())\n            with self.within_grace_period(has_connection=False):\n                self.terminate_by_signal(cloudflared, signal)\n\n    def terminate_by_signal(self, cloudflared, sig):\n        cloudflared.send_signal(sig)\n        check_tunnel_not_connected()\n        cloudflared.wait()\n\n    def wait_eyeball_thread(self, thread, timeout):\n        thread.join(timeout)\n        assert thread.is_alive() == False, \"eyeball thread is still alive\"\n\n    # Using this context asserts logic within the context is executed within grace period\n    @contextmanager\n    def within_grace_period(self, has_connection=True):\n        try:\n            start = time.time()\n            yield\n        finally:\n\n            # If the request takes longer than the grace period then we need to wait at most the grace period.\n            # If the request fell within the grace period cloudflared can close earlier, but to ensure that it doesn't\n            # close immediately we add a minimum boundary. If cloudflared shutdown in less than 1s it's likely that\n            # it shutdown as soon as it received SIGINT. The only way cloudflared can close immediately is if it has no\n            # in-flight requests\n            minimum = 1 if has_connection else 0\n            duration = time.time() - start\n            # Here we truncate to ensure that we don't fail on minute differences like 10.1 instead of 10\n            assert minimum <= int(duration) <= self.grace_period\n\n    def stream_request(self, config, connected, early_terminate):\n        expected_terminate_message = \"502 Bad Gateway\"\n        url = config.get_url() + self.sse_endpoint\n\n        with requests.get(url, timeout=5, stream=True) as resp:\n            with connected:\n                connected.notifyAll()\n            lines = 0\n            for line in resp.iter_lines():\n                if expected_terminate_message.encode() == line:\n                    break\n                lines += 1\n                if early_terminate and lines == 2:\n                    return\n            # /sse returns count followed by 2 new lines\n            assert lines >= (self.grace_period * 2)\n"
  },
  {
    "path": "component-tests/test_token.py",
    "content": "import base64\nimport json\n\nfrom setup import get_config_from_file\nfrom util import start_cloudflared\n\n\nclass TestToken:\n    def test_get_token(self, tmp_path, component_tests_config):\n        config = component_tests_config()\n        tunnel_id = config.get_tunnel_id()\n\n        token_args = [\"--origincert\", cert_path(), \"token\", tunnel_id]\n        output = start_cloudflared(tmp_path, config, token_args)\n\n        assert parse_token(config.get_token()) == parse_token(output.stdout)\n\n    def test_get_credentials_file(self, tmp_path, component_tests_config):\n        config = component_tests_config()\n        tunnel_id = config.get_tunnel_id()\n\n        cred_file = tmp_path / \"test_get_credentials_file.json\"\n        token_args = [\"--origincert\", cert_path(), \"token\", \"--cred-file\", cred_file, tunnel_id]\n        start_cloudflared(tmp_path, config, token_args)\n\n        with open(cred_file) as json_file:\n            assert config.get_credentials_json() == json.load(json_file)\n\n\ndef cert_path():\n    return get_config_from_file()[\"origincert\"]\n\n\ndef parse_token(token):\n    return json.loads(base64.b64decode(token))\n"
  },
  {
    "path": "component-tests/test_tunnel.py",
    "content": "#!/usr/bin/env python\nimport requests\nfrom conftest import CfdModes\nfrom constants import METRICS_PORT, MAX_RETRIES, BACKOFF_SECS\nfrom retrying import retry\nfrom cli import CloudflaredCli\nfrom util import LOGGER, write_config, start_cloudflared, wait_tunnel_ready, send_requests\nimport platform\n\nclass TestTunnel:\n    '''Test tunnels with no ingress rules from config.yaml but ingress rules from CLI only'''\n\n    def test_tunnel_hello_world(self, tmp_path, component_tests_config):\n        config = component_tests_config(cfd_mode=CfdModes.NAMED, provide_ingress=False)\n        LOGGER.debug(config)\n        with start_cloudflared(tmp_path, config, cfd_pre_args=[\"tunnel\", \"--ha-connections\", \"1\"],  cfd_args=[\"run\", \"--hello-world\"], new_process=True):\n            wait_tunnel_ready(tunnel_url=config.get_url(),\n                              require_min_connections=1)\n    \n    def test_tunnel_url(self, tmp_path, component_tests_config):\n        config = component_tests_config(cfd_mode=CfdModes.NAMED, provide_ingress=False)\n        LOGGER.debug(config)\n        with start_cloudflared(tmp_path, config, cfd_pre_args=[\"tunnel\", \"--ha-connections\", \"1\"],  cfd_args=[\"run\", \"--url\", f\"http://localhost:{METRICS_PORT}/\"], new_process=True):\n            wait_tunnel_ready(require_min_connections=1)\n            send_requests(config.get_url()+\"/ready\", 3, True)\n\n    def test_tunnel_no_ingress(self, tmp_path, component_tests_config):\n        '''\n        Running a tunnel with no ingress rules provided from either config.yaml or CLI will still work but return 503\n        for all incoming requests.\n        '''\n        config = component_tests_config(cfd_mode=CfdModes.NAMED, provide_ingress=False)\n        LOGGER.debug(config)\n        with start_cloudflared(tmp_path, config, cfd_pre_args=[\"tunnel\", \"--ha-connections\", \"1\"],  cfd_args=[\"run\"], new_process=True):\n            wait_tunnel_ready(require_min_connections=1)\n            expected_status_code = 503\n            resp = send_request(config.get_url()+\"/\", expected_status_code)\n            assert resp.status_code == expected_status_code, \"Expected cloudflared to return 503 for all requests with no ingress defined\"\n            resp = send_request(config.get_url()+\"/test\", expected_status_code)\n            assert resp.status_code == expected_status_code, \"Expected cloudflared to return 503 for all requests with no ingress defined\"\n\ndef retry_if_result_none(result):\n    '''\n    Returns True if the result is None, indicating that the function should be retried.\n    '''\n    return result is None\n\n@retry(retry_on_result=retry_if_result_none, stop_max_attempt_number=MAX_RETRIES, wait_fixed=BACKOFF_SECS * 1000)\ndef send_request(url, expected_status_code=200):\n    with requests.Session() as s:\n        resp = s.get(url, timeout=BACKOFF_SECS)\n        return resp if resp.status_code == expected_status_code else None\n"
  },
  {
    "path": "component-tests/util.py",
    "content": "import logging\nimport os\nimport platform\nimport subprocess\nfrom contextlib import contextmanager\nfrom time import sleep\nimport sys\n\nimport pytest\n\nimport requests\nimport yaml\nfrom retrying import retry\n\nfrom constants import METRICS_PORT, MAX_RETRIES, BACKOFF_SECS\n\ndef configure_logger():\n    logger = logging.getLogger(__name__)\n    logger.setLevel(logging.DEBUG)\n    handler = logging.StreamHandler(sys.stdout)\n    logger.addHandler(handler)\n    return logger\n\nLOGGER = configure_logger()\n\ndef select_platform(plat):\n    return pytest.mark.skipif(\n        platform.system() != plat, reason=f\"Only runs on {plat}\")\n\ndef fips_enabled():\n    env_fips = os.getenv(\"COMPONENT_TESTS_FIPS\")\n    return env_fips is not None and env_fips != \"0\"\n\nnofips = pytest.mark.skipif(\n        fips_enabled(), reason=f\"Only runs without FIPS (COMPONENT_TESTS_FIPS=0)\")\n\ndef skip_on_ci(reason):\n    env_ci = os.getenv(\"CI\")\n    running_in_ci = env_ci is not None and env_ci != \"0\"\n    return pytest.mark.skipif(\n        running_in_ci, reason=f\"This test can't run on CI due to: {reason}\")\n\ndef write_config(directory, config):\n    config_path = directory / \"config.yml\"\n    with open(config_path, 'w') as outfile:\n        yaml.dump(config, outfile)\n    return config_path\n\n\ndef start_cloudflared(directory, config, cfd_args=[\"run\"], cfd_pre_args=[\"tunnel\"], new_process=False,\n                      allow_input=False, capture_output=True, root=False, skip_config_flag=False, expect_success=True):\n\n    config_path = None\n    if not skip_config_flag:\n        config_path = write_config(directory, config.full_config)\n\n    cmd = cloudflared_cmd(config, config_path, cfd_args, cfd_pre_args, root)\n\n    if new_process:\n        return run_cloudflared_background(cmd, allow_input, capture_output)\n    # By setting check=True, it will raise an exception if the process exits with non-zero exit code\n    return subprocess.run(cmd, check=expect_success, capture_output=capture_output)\n\ndef cloudflared_cmd(config, config_path, cfd_args, cfd_pre_args, root):\n    cmd = []\n    if root:\n        cmd += [\"sudo\"]\n    cmd += [config.cloudflared_binary]\n    cmd += cfd_pre_args\n\n    if config_path is not None:\n        cmd += [\"--config\", str(config_path)]\n\n    cmd += cfd_args\n    LOGGER.info(f\"Run cmd {cmd} with config {config}\")\n    return cmd\n\n\n@contextmanager\ndef run_cloudflared_background(cmd, allow_input, capture_output):\n    output = subprocess.PIPE if capture_output else subprocess.DEVNULL\n    stdin = subprocess.PIPE if allow_input else None\n    cfd = None\n    try:\n        cfd = subprocess.Popen(cmd, stdin=stdin, stdout=output, stderr=output)\n        yield cfd\n    finally:\n        if cfd:\n            cfd.terminate()\n            if capture_output:\n                LOGGER.info(f\"cloudflared log: {cfd.stderr.read()}\")\n    \n\ndef get_quicktunnel_url():\n    quicktunnel_url = f'http://localhost:{METRICS_PORT}/quicktunnel'\n    with requests.Session() as s:\n        resp = send_request(s, quicktunnel_url, True)\n\n        hostname = resp.json()[\"hostname\"]\n        assert hostname, \\\n            f\"Quicktunnel endpoint returned {hostname} but we expected a url\"\n\n        return f\"https://{hostname}\"\n\ndef wait_tunnel_ready(tunnel_url=None, require_min_connections=1, cfd_logs=None):\n    try:\n        inner_wait_tunnel_ready(tunnel_url, require_min_connections)\n    except Exception as e:\n        if cfd_logs is not None:\n            _log_cloudflared_logs(cfd_logs)\n        raise e\n\n\n@retry(stop_max_attempt_number=MAX_RETRIES, wait_fixed=BACKOFF_SECS * 1000)\ndef inner_wait_tunnel_ready(tunnel_url=None, require_min_connections=1):\n    metrics_url = f'http://localhost:{METRICS_PORT}/ready'\n\n    with requests.Session() as s:\n        LOGGER.debug(\"Waiting for tunnel to be ready...\")\n        resp = send_request(s, metrics_url, True)\n\n        ready_connections = resp.json()[\"readyConnections\"]\n\n        assert ready_connections >= require_min_connections, \\\n            f\"Ready endpoint returned {resp.json()} but we expect at least {require_min_connections} connections\"\n\n        if tunnel_url is not None:\n            send_request(s, tunnel_url, True)\n\ndef _log_cloudflared_logs(cfd_logs):\n    log_file = cfd_logs\n    if os.path.isdir(cfd_logs):\n        files = os.listdir(cfd_logs)\n        if len(files) == 0:\n            return\n        log_file = os.path.join(cfd_logs, files[0])\n    with open(log_file, \"r\") as f:\n        LOGGER.warning(\"Cloudflared Tunnel was not ready:\")\n        for line in f.readlines():\n            LOGGER.warning(line)\n\n\n@retry(stop_max_attempt_number=MAX_RETRIES, wait_fixed=BACKOFF_SECS * 1000)\ndef check_tunnel_not_connected():\n    url = f'http://localhost:{METRICS_PORT}/ready'\n\n    try:\n        resp = requests.get(url, timeout=BACKOFF_SECS)\n        assert resp.status_code == 503, f\"Expect {url} returns 503, got {resp.status_code}\"\n        assert resp.json()[\n            \"readyConnections\"] == 0, \"Expected all connections to be terminated (pending reconnect)\"\n    # cloudflared might already terminate\n    except requests.exceptions.ConnectionError as e:\n        LOGGER.warning(f\"Failed to connect to {url}, error: {e}\")\n\n\ndef get_tunnel_connector_id():\n    url = f'http://localhost:{METRICS_PORT}/ready'\n\n    try:\n        resp = requests.get(url, timeout=1)\n        return resp.json()[\"connectorId\"]\n    # cloudflared might already terminated\n    except requests.exceptions.ConnectionError as e:\n        LOGGER.warning(f\"Failed to connect to {url}, error: {e}\")\n\n\n# In some cases we don't need to check response status, such as when sending batch requests to generate logs\ndef send_requests(url, count, require_ok=True):\n    errors = 0\n    with requests.Session() as s:\n        for _ in range(count):\n            resp = send_request(s, url, require_ok)\n            if resp is None:\n                errors += 1\n            sleep(0.01)\n    if errors > 0:\n        LOGGER.warning(\n            f\"{errors} out of {count} requests to {url} return non-200 status\")\n\n\n@retry(stop_max_attempt_number=MAX_RETRIES, wait_fixed=BACKOFF_SECS * 1000)\ndef send_request(session, url, require_ok):\n    resp = session.get(url, timeout=BACKOFF_SECS)\n    if require_ok:\n        assert resp.status_code == 200, f\"{url} returned {resp}\"\n    return resp if resp.status_code == 200 else None\n\n\ndef decode_jwt_payload(token):\n    \"\"\"\n    Decode the payload section of a JWT token without signature verification.\n    \n    JWT Structure:\n    ==============\n    A JWT consists of three Base64URL-encoded parts separated by dots:\n        HEADER.PAYLOAD.SIGNATURE\n    \n    The payload contains the JWT claims (the actual data/permissions).\n    \n    Args:\n        token (str): The complete JWT token string\n        \n    Returns:\n        dict: The decoded payload as a dictionary containing JWT claims\n        \n    Raises:\n        ValueError: If the token doesn't have exactly 3 parts\n        \n    Note:\n        This function does NOT verify the signature - it only decodes the payload.\n        Use this only when you trust the token source (e.g., tokens you just generated).\n    \"\"\"\n    import base64\n    import json\n    \n    # Split JWT into its three components\n    parts = token.split('.')\n    if len(parts) != 3:\n        raise ValueError(f\"Invalid JWT format: expected 3 parts, got {len(parts)}\")\n    \n    # Extract and decode the payload (middle section)\n    # Base64 requires padding to be a multiple of 4 characters\n    payload_encoded = parts[1]\n    remainder = len(payload_encoded) % 4\n    if remainder != 0:\n        payload_padded = payload_encoded + '=' * (4 - remainder)\n    else:\n        payload_padded = payload_encoded\n    \n    # Decode from Base64URL format and parse JSON\n    decoded_payload = base64.urlsafe_b64decode(payload_padded)\n    return json.loads(decoded_payload)\n"
  },
  {
    "path": "config/configuration.go",
    "content": "package config\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"time\"\n\n\thomedir \"github.com/mitchellh/go-homedir\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/urfave/cli/v2\"\n\tyaml \"gopkg.in/yaml.v3\"\n\n\t\"github.com/cloudflare/cloudflared/validation\"\n)\n\nvar (\n\t// DefaultConfigFiles is the file names from which we attempt to read configuration.\n\tDefaultConfigFiles = []string{\"config.yml\", \"config.yaml\"}\n\n\t// DefaultUnixConfigLocation is the primary location to find a config file\n\tDefaultUnixConfigLocation = \"/usr/local/etc/cloudflared\"\n\n\t// DefaultUnixLogLocation is the primary location to find log files\n\tDefaultUnixLogLocation = \"/var/log/cloudflared\"\n\n\t// Launchd doesn't set root env variables, so there is default\n\t// Windows default config dir was ~/cloudflare-warp in documentation; let's keep it compatible\n\tdefaultUserConfigDirs = []string{\"~/.cloudflared\", \"~/.cloudflare-warp\", \"~/cloudflare-warp\"}\n\tdefaultNixConfigDirs  = []string{\"/etc/cloudflared\", DefaultUnixConfigLocation}\n\n\tErrNoConfigFile = fmt.Errorf(\"Cannot determine default configuration path. No file %v in %v\", DefaultConfigFiles, DefaultConfigSearchDirectories())\n)\n\nconst (\n\t// BastionFlag is to enable bastion, or jump host, operation\n\tBastionFlag = \"bastion\"\n)\n\n// DefaultConfigDirectory returns the default directory of the config file\nfunc DefaultConfigDirectory() string {\n\tif runtime.GOOS == \"windows\" {\n\t\tpath := os.Getenv(\"CFDPATH\")\n\t\tif path == \"\" {\n\t\t\tpath = filepath.Join(os.Getenv(\"ProgramFiles(x86)\"), \"cloudflared\")\n\t\t\tif _, err := os.Stat(path); os.IsNotExist(err) { // doesn't exist, so return an empty failure string\n\t\t\t\treturn \"\"\n\t\t\t}\n\t\t}\n\t\treturn path\n\t}\n\treturn DefaultUnixConfigLocation\n}\n\n// DefaultLogDirectory returns the default directory for log files\nfunc DefaultLogDirectory() string {\n\tif runtime.GOOS == \"windows\" {\n\t\treturn DefaultConfigDirectory()\n\t}\n\treturn DefaultUnixLogLocation\n}\n\n// DefaultConfigPath returns the default location of a config file\nfunc DefaultConfigPath() string {\n\tdir := DefaultConfigDirectory()\n\tif dir == \"\" {\n\t\treturn DefaultConfigFiles[0]\n\t}\n\treturn filepath.Join(dir, DefaultConfigFiles[0])\n}\n\n// DefaultConfigSearchDirectories returns the default folder locations of the config\nfunc DefaultConfigSearchDirectories() []string {\n\tdirs := make([]string, len(defaultUserConfigDirs))\n\tcopy(dirs, defaultUserConfigDirs)\n\tif runtime.GOOS != \"windows\" {\n\t\tdirs = append(dirs, defaultNixConfigDirs...)\n\t}\n\treturn dirs\n}\n\n// FileExists checks to see if a file exist at the provided path.\nfunc FileExists(path string) (bool, error) {\n\tf, err := os.Open(path)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\t// ignore missing files\n\t\t\treturn false, nil\n\t\t}\n\t\treturn false, err\n\t}\n\t_ = f.Close()\n\treturn true, nil\n}\n\n// FindDefaultConfigPath returns the first path that contains a config file.\n// If none of the combination of DefaultConfigSearchDirectories() and DefaultConfigFiles\n// contains a config file, return empty string.\nfunc FindDefaultConfigPath() string {\n\tfor _, configDir := range DefaultConfigSearchDirectories() {\n\t\tfor _, configFile := range DefaultConfigFiles {\n\t\t\tdirPath, err := homedir.Expand(configDir)\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tpath := filepath.Join(dirPath, configFile)\n\t\t\tif ok, _ := FileExists(path); ok {\n\t\t\t\treturn path\n\t\t\t}\n\t\t}\n\t}\n\treturn \"\"\n}\n\n// FindOrCreateConfigPath returns the first path that contains a config file\n// or creates one in the primary default path if it doesn't exist\nfunc FindOrCreateConfigPath() string {\n\tpath := FindDefaultConfigPath()\n\n\tif path == \"\" {\n\t\t// create the default directory if it doesn't exist\n\t\tpath = DefaultConfigPath()\n\t\tif err := os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil {\n\t\t\treturn \"\"\n\t\t}\n\n\t\t// write a new config file out\n\t\tfile, err := os.Create(path)\n\t\tif err != nil {\n\t\t\treturn \"\"\n\t\t}\n\t\tdefer file.Close()\n\n\t\tlogDir := DefaultLogDirectory()\n\t\t_ = os.MkdirAll(logDir, os.ModePerm) // try and create it. Doesn't matter if it succeed or not, only byproduct will be no logs\n\n\t\tc := Root{\n\t\t\tLogDirectory: logDir,\n\t\t}\n\t\tif err := yaml.NewEncoder(file).Encode(&c); err != nil {\n\t\t\treturn \"\"\n\t\t}\n\t}\n\n\treturn path\n}\n\n// ValidateUnixSocket ensures --unix-socket param is used exclusively\n// i.e. it fails if a user specifies both --url and --unix-socket\nfunc ValidateUnixSocket(c *cli.Context) (string, error) {\n\tif c.IsSet(\"unix-socket\") && (c.IsSet(\"url\") || c.NArg() > 0) {\n\t\treturn \"\", errors.New(\"--unix-socket must be used exclusively.\")\n\t}\n\treturn c.String(\"unix-socket\"), nil\n}\n\n// ValidateUrl will validate url flag correctness. It can be either from --url or argument\n// Notice ValidateUnixSocket, it will enforce --unix-socket is not used with --url or argument\nfunc ValidateUrl(c *cli.Context, allowURLFromArgs bool) (*url.URL, error) {\n\tvar url = c.String(\"url\")\n\tif allowURLFromArgs && c.NArg() > 0 {\n\t\tif c.IsSet(\"url\") {\n\t\t\treturn nil, errors.New(\"Specified origin urls using both --url and argument. Decide which one you want, I can only support one.\")\n\t\t}\n\t\turl = c.Args().Get(0)\n\t}\n\tvalidUrl, err := validation.ValidateUrl(url)\n\treturn validUrl, err\n}\n\ntype UnvalidatedIngressRule struct {\n\tHostname      string              `json:\"hostname,omitempty\"`\n\tPath          string              `json:\"path,omitempty\"`\n\tService       string              `json:\"service,omitempty\"`\n\tOriginRequest OriginRequestConfig `yaml:\"originRequest\" json:\"originRequest\"`\n}\n\n// OriginRequestConfig is a set of optional fields that users may set to\n// customize how cloudflared sends requests to origin services. It is used to set\n// up general config that apply to all rules, and also, specific per-rule\n// config.\n// Note:\n// - To specify a time.Duration in go-yaml, use e.g. \"3s\" or \"24h\".\n// - To specify a time.Duration in json, use int64 of the nanoseconds\ntype OriginRequestConfig struct {\n\t// HTTP proxy timeout for establishing a new connection\n\tConnectTimeout *CustomDuration `yaml:\"connectTimeout\" json:\"connectTimeout,omitempty\"`\n\t// HTTP proxy timeout for completing a TLS handshake\n\tTLSTimeout *CustomDuration `yaml:\"tlsTimeout\" json:\"tlsTimeout,omitempty\"`\n\t// HTTP proxy TCP keepalive duration\n\tTCPKeepAlive *CustomDuration `yaml:\"tcpKeepAlive\" json:\"tcpKeepAlive,omitempty\"`\n\t// HTTP proxy should disable \"happy eyeballs\" for IPv4/v6 fallback\n\tNoHappyEyeballs *bool `yaml:\"noHappyEyeballs\" json:\"noHappyEyeballs,omitempty\"`\n\t// HTTP proxy maximum keepalive connection pool size\n\tKeepAliveConnections *int `yaml:\"keepAliveConnections\" json:\"keepAliveConnections,omitempty\"`\n\t// HTTP proxy timeout for closing an idle connection\n\tKeepAliveTimeout *CustomDuration `yaml:\"keepAliveTimeout\" json:\"keepAliveTimeout,omitempty\"`\n\t// Sets the HTTP Host header for the local webserver.\n\tHTTPHostHeader *string `yaml:\"httpHostHeader\" json:\"httpHostHeader,omitempty\"`\n\t// Hostname on the origin server certificate.\n\tOriginServerName *string `yaml:\"originServerName\" json:\"originServerName,omitempty\"`\n\t// Auto configure the Hostname on the origin server certificate.\n\tMatchSNIToHost *bool `yaml:\"matchSNItoHost\" json:\"matchSNItoHost,omitempty\"`\n\t// Path to the CA for the certificate of your origin.\n\t// This option should be used only if your certificate is not signed by Cloudflare.\n\tCAPool *string `yaml:\"caPool\" json:\"caPool,omitempty\"`\n\t// Disables TLS verification of the certificate presented by your origin.\n\t// Will allow any certificate from the origin to be accepted.\n\t// Note: The connection from your machine to Cloudflare's Edge is still encrypted.\n\tNoTLSVerify *bool `yaml:\"noTLSVerify\" json:\"noTLSVerify,omitempty\"`\n\t// Disables chunked transfer encoding.\n\t// Useful if you are running a WSGI server.\n\tDisableChunkedEncoding *bool `yaml:\"disableChunkedEncoding\" json:\"disableChunkedEncoding,omitempty\"`\n\t// Runs as jump host\n\tBastionMode *bool `yaml:\"bastionMode\" json:\"bastionMode,omitempty\"`\n\t// Listen address for the proxy.\n\tProxyAddress *string `yaml:\"proxyAddress\" json:\"proxyAddress,omitempty\"`\n\t// Listen port for the proxy.\n\tProxyPort *uint `yaml:\"proxyPort\" json:\"proxyPort,omitempty\"`\n\t// Valid options are 'socks' or empty.\n\tProxyType *string `yaml:\"proxyType\" json:\"proxyType,omitempty\"`\n\t// IP rules for the proxy service\n\tIPRules []IngressIPRule `yaml:\"ipRules\" json:\"ipRules,omitempty\"`\n\t// Attempt to connect to origin with HTTP/2\n\tHttp2Origin *bool `yaml:\"http2Origin\" json:\"http2Origin,omitempty\"`\n\t// Access holds all access related configs\n\tAccess *AccessConfig `yaml:\"access\" json:\"access,omitempty\"`\n}\n\ntype AccessConfig struct {\n\t// Required when set to true will fail every request that does not arrive through an access authenticated endpoint.\n\tRequired bool `yaml:\"required\" json:\"required,omitempty\"`\n\n\t// TeamName is the organization team name to get the public key certificates for.\n\tTeamName string `yaml:\"teamName\" json:\"teamName\"`\n\n\t// AudTag is the AudTag to verify access JWT against.\n\tAudTag []string `yaml:\"audTag\" json:\"audTag\"`\n\n\tEnvironment string `yaml:\"environment\" json:\"environment,omitempty\"`\n}\n\ntype IngressIPRule struct {\n\tPrefix *string `yaml:\"prefix\" json:\"prefix\"`\n\tPorts  []int   `yaml:\"ports\" json:\"ports\"`\n\tAllow  bool    `yaml:\"allow\" json:\"allow\"`\n}\n\ntype Configuration struct {\n\tTunnelID      string `yaml:\"tunnel\"`\n\tIngress       []UnvalidatedIngressRule\n\tWarpRouting   WarpRoutingConfig   `yaml:\"warp-routing\"`\n\tOriginRequest OriginRequestConfig `yaml:\"originRequest\"`\n\tsourceFile    string\n}\n\ntype WarpRoutingConfig struct {\n\tConnectTimeout *CustomDuration `yaml:\"connectTimeout\" json:\"connectTimeout,omitempty\"`\n\tMaxActiveFlows *uint64         `yaml:\"maxActiveFlows\" json:\"maxActiveFlows,omitempty\"`\n\tTCPKeepAlive   *CustomDuration `yaml:\"tcpKeepAlive\" json:\"tcpKeepAlive,omitempty\"`\n}\n\ntype configFileSettings struct {\n\tConfiguration `yaml:\",inline\"`\n\t// older settings will be aggregated into the generic map, should be read via cli.Context\n\tSettings map[string]interface{} `yaml:\",inline\"`\n}\n\nfunc (c *Configuration) Source() string {\n\treturn c.sourceFile\n}\n\nfunc (c *configFileSettings) Int(name string) (int, error) {\n\tif raw, ok := c.Settings[name]; ok {\n\t\tif v, ok := raw.(int); ok {\n\t\t\treturn v, nil\n\t\t}\n\t\treturn 0, fmt.Errorf(\"expected int found %T for %s\", raw, name)\n\t}\n\treturn 0, nil\n}\n\nfunc (c *configFileSettings) Duration(name string) (time.Duration, error) {\n\tif raw, ok := c.Settings[name]; ok {\n\t\tswitch v := raw.(type) {\n\t\tcase time.Duration:\n\t\t\treturn v, nil\n\t\tcase string:\n\t\t\treturn time.ParseDuration(v)\n\t\t}\n\t\treturn 0, fmt.Errorf(\"expected duration found %T for %s\", raw, name)\n\t}\n\treturn 0, nil\n}\n\nfunc (c *configFileSettings) Float64(name string) (float64, error) {\n\tif raw, ok := c.Settings[name]; ok {\n\t\tif v, ok := raw.(float64); ok {\n\t\t\treturn v, nil\n\t\t}\n\t\treturn 0, fmt.Errorf(\"expected float found %T for %s\", raw, name)\n\t}\n\treturn 0, nil\n}\n\nfunc (c *configFileSettings) String(name string) (string, error) {\n\tif raw, ok := c.Settings[name]; ok {\n\t\tif v, ok := raw.(string); ok {\n\t\t\treturn v, nil\n\t\t}\n\t\treturn \"\", fmt.Errorf(\"expected string found %T for %s\", raw, name)\n\t}\n\treturn \"\", nil\n}\n\nfunc (c *configFileSettings) StringSlice(name string) ([]string, error) {\n\tif raw, ok := c.Settings[name]; ok {\n\t\tif slice, ok := raw.([]interface{}); ok {\n\t\t\tstrSlice := make([]string, len(slice))\n\t\t\tfor i, v := range slice {\n\t\t\t\tstr, ok := v.(string)\n\t\t\t\tif !ok {\n\t\t\t\t\treturn nil, fmt.Errorf(\"expected string, found %T for %v\", i, v)\n\t\t\t\t}\n\t\t\t\tstrSlice[i] = str\n\t\t\t}\n\t\t\treturn strSlice, nil\n\t\t}\n\t\treturn nil, fmt.Errorf(\"expected string slice found %T for %s\", raw, name)\n\t}\n\treturn nil, nil\n}\n\nfunc (c *configFileSettings) IntSlice(name string) ([]int, error) {\n\tif raw, ok := c.Settings[name]; ok {\n\t\tif slice, ok := raw.([]interface{}); ok {\n\t\t\tintSlice := make([]int, len(slice))\n\t\t\tfor i, v := range slice {\n\t\t\t\tstr, ok := v.(int)\n\t\t\t\tif !ok {\n\t\t\t\t\treturn nil, fmt.Errorf(\"expected int, found %T for %v \", v, v)\n\t\t\t\t}\n\t\t\t\tintSlice[i] = str\n\t\t\t}\n\t\t\treturn intSlice, nil\n\t\t}\n\t\tif v, ok := raw.([]int); ok {\n\t\t\treturn v, nil\n\t\t}\n\t\treturn nil, fmt.Errorf(\"expected int slice found %T for %s\", raw, name)\n\t}\n\treturn nil, nil\n}\n\nfunc (c *configFileSettings) Generic(name string) (cli.Generic, error) {\n\treturn nil, errors.New(\"option type Generic not supported\")\n}\n\nfunc (c *configFileSettings) Bool(name string) (bool, error) {\n\tif raw, ok := c.Settings[name]; ok {\n\t\tif v, ok := raw.(bool); ok {\n\t\t\treturn v, nil\n\t\t}\n\t\treturn false, fmt.Errorf(\"expected boolean found %T for %s\", raw, name)\n\t}\n\treturn false, nil\n}\n\nvar configuration configFileSettings\n\nfunc GetConfiguration() *Configuration {\n\treturn &configuration.Configuration\n}\n\n// ReadConfigFile returns InputSourceContext initialized from the configuration file.\n// On repeat calls returns with the same file, returns without reading the file again; however,\n// if value of \"config\" flag changes, will read the new config file\nfunc ReadConfigFile(c *cli.Context, log *zerolog.Logger) (settings *configFileSettings, warnings string, err error) {\n\tconfigFile := c.String(\"config\")\n\tif configuration.Source() == configFile || configFile == \"\" {\n\t\tif configuration.Source() == \"\" {\n\t\t\treturn nil, \"\", ErrNoConfigFile\n\t\t}\n\t\treturn &configuration, \"\", nil\n\t}\n\n\tlog.Debug().Msgf(\"Loading configuration from %s\", configFile)\n\tfile, err := os.Open(configFile)\n\tif err != nil {\n\t\t// If does not exist and config file was not specificly specified then return ErrNoConfigFile found.\n\t\tif os.IsNotExist(err) && !c.IsSet(\"config\") {\n\t\t\terr = ErrNoConfigFile\n\t\t}\n\t\treturn nil, \"\", err\n\t}\n\tdefer file.Close()\n\tif err := yaml.NewDecoder(file).Decode(&configuration); err != nil {\n\t\tif err == io.EOF {\n\t\t\tlog.Error().Msgf(\"Configuration file %s was empty\", configFile)\n\t\t\treturn &configuration, \"\", nil\n\t\t}\n\t\treturn nil, \"\", errors.Wrap(err, \"error parsing YAML in config file at \"+configFile)\n\t}\n\tconfiguration.sourceFile = configFile\n\n\t// Parse it again, with strict mode, to find warnings.\n\tif file, err := os.Open(configFile); err == nil {\n\t\tdecoder := yaml.NewDecoder(file)\n\t\tdecoder.KnownFields(true)\n\t\tvar unusedConfig configFileSettings\n\t\tif err := decoder.Decode(&unusedConfig); err != nil {\n\t\t\twarnings = err.Error()\n\t\t}\n\t}\n\n\treturn &configuration, warnings, nil\n}\n\n// A CustomDuration is a Duration that has custom serialization for JSON.\n// JSON in Javascript assumes that int fields are 32 bits and Duration fields are deserialized assuming that numbers\n// are in nanoseconds, which in 32bit integers limits to just 2 seconds.\n// This type assumes that when serializing/deserializing from JSON, that the number is in seconds, while it maintains\n// the YAML serde assumptions.\ntype CustomDuration struct {\n\ttime.Duration\n}\n\nfunc (s CustomDuration) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(s.Duration.Seconds())\n}\n\nfunc (s *CustomDuration) UnmarshalJSON(data []byte) error {\n\tseconds, err := strconv.ParseInt(string(data), 10, 64)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ts.Duration = time.Duration(seconds * int64(time.Second))\n\treturn nil\n}\n\nfunc (s *CustomDuration) MarshalYAML() (interface{}, error) {\n\treturn s.Duration.String(), nil\n}\n\nfunc (s *CustomDuration) UnmarshalYAML(unmarshal func(interface{}) error) error {\n\treturn unmarshal(&s.Duration)\n}\n"
  },
  {
    "path": "config/configuration_test.go",
    "content": "package config\n\nimport (\n\t\"encoding/json\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\tyaml \"gopkg.in/yaml.v3\"\n)\n\nfunc TestConfigFileSettings(t *testing.T) {\n\tvar (\n\t\tfirstIngress = UnvalidatedIngressRule{\n\t\t\tHostname: \"tunnel1.example.com\",\n\t\t\tPath:     \"/id\",\n\t\t\tService:  \"https://localhost:8000\",\n\t\t}\n\t\tsecondIngress = UnvalidatedIngressRule{\n\t\t\tHostname: \"*\",\n\t\t\tPath:     \"\",\n\t\t\tService:  \"https://localhost:8001\",\n\t\t}\n\t\twarpRouting = WarpRoutingConfig{\n\t\t\tConnectTimeout: &CustomDuration{Duration: 2 * time.Second},\n\t\t\tTCPKeepAlive:   &CustomDuration{Duration: 10 * time.Second},\n\t\t}\n\t)\n\trawYAML := `\ntunnel: config-file-test\noriginRequest:\n  ipRules:\n  - prefix: \"10.0.0.0/8\"\n    ports:\n    - 80\n    - 8080\n    allow: false\n  - prefix: \"fc00::/7\"\n    ports:\n    - 443\n    - 4443\n    allow: true\ningress:\n - hostname: tunnel1.example.com\n   path: /id\n   service: https://localhost:8000\n - hostname: \"*\"\n   service: https://localhost:8001\nwarp-routing: \n  enabled: true\n  connectTimeout: 2s\n  tcpKeepAlive: 10s\n\nretries: 5\ngrace-period: 30s\npercentage: 3.14\nhostname: example.com\ntag:\n - test\n - central-1\ncounters:\n - 123\n - 456\n`\n\tvar config configFileSettings\n\terr := yaml.Unmarshal([]byte(rawYAML), &config)\n\tassert.NoError(t, err)\n\n\tassert.Equal(t, \"config-file-test\", config.TunnelID)\n\tassert.Equal(t, firstIngress, config.Ingress[0])\n\tassert.Equal(t, secondIngress, config.Ingress[1])\n\tassert.Equal(t, warpRouting, config.WarpRouting)\n\tprivateV4 := \"10.0.0.0/8\"\n\tprivateV6 := \"fc00::/7\"\n\tipRules := []IngressIPRule{\n\t\t{\n\t\t\tPrefix: &privateV4,\n\t\t\tPorts:  []int{80, 8080},\n\t\t\tAllow:  false,\n\t\t},\n\t\t{\n\t\t\tPrefix: &privateV6,\n\t\t\tPorts:  []int{443, 4443},\n\t\t\tAllow:  true,\n\t\t},\n\t}\n\tassert.Equal(t, ipRules, config.OriginRequest.IPRules)\n\n\tretries, err := config.Int(\"retries\")\n\tassert.NoError(t, err)\n\tassert.Equal(t, 5, retries)\n\n\tgracePeriod, err := config.Duration(\"grace-period\")\n\tassert.NoError(t, err)\n\tassert.Equal(t, time.Second*30, gracePeriod)\n\n\tpercentage, err := config.Float64(\"percentage\")\n\tassert.NoError(t, err)\n\tassert.Equal(t, 3.14, percentage)\n\n\thostname, err := config.String(\"hostname\")\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"example.com\", hostname)\n\n\ttags, err := config.StringSlice(\"tag\")\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"test\", tags[0])\n\tassert.Equal(t, \"central-1\", tags[1])\n\n\tcounters, err := config.IntSlice(\"counters\")\n\tassert.NoError(t, err)\n\tassert.Equal(t, 123, counters[0])\n\tassert.Equal(t, 456, counters[1])\n\n}\n\nvar rawJsonConfig = []byte(`\n{\n\t\"connectTimeout\": 10,\n\t\"tlsTimeout\": 30,\n\t\"tcpKeepAlive\": 30,\n\t\"noHappyEyeballs\": true,\n\t\"keepAliveTimeout\": 60,\n\t\"keepAliveConnections\": 10,\n\t\"httpHostHeader\": \"app.tunnel.com\",\n\t\"originServerName\": \"app.tunnel.com\",\n\t\"caPool\": \"/etc/capool\",\n\t\"noTLSVerify\": true,\n\t\"disableChunkedEncoding\": true,\n\t\"bastionMode\": true,\n\t\"proxyAddress\": \"127.0.0.3\",\n\t\"proxyPort\": 9000,\n\t\"proxyType\": \"socks\",\n\t\"ipRules\": [\n\t\t{\n\t\t\t\"prefix\": \"10.0.0.0/8\",\n\t\t\t\"ports\": [80, 8080],\n\t\t\t\"allow\": false\n\t\t},\n\t\t{\n\t\t\t\"prefix\": \"fc00::/7\",\n\t\t\t\"ports\": [443, 4443],\n\t\t\t\"allow\": true\n\t\t}\n\t],\n\t\"http2Origin\": true\n}\n`)\n\nfunc TestMarshalUnmarshalOriginRequest(t *testing.T) {\n\ttestCases := []struct {\n\t\tname          string\n\t\tmarshalFunc   func(in interface{}) (out []byte, err error)\n\t\tunMarshalFunc func(in []byte, out interface{}) (err error)\n\t}{\n\t\t{\"json\", json.Marshal, json.Unmarshal},\n\t\t{\"yaml\", yaml.Marshal, yaml.Unmarshal},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tassertConfig(t, tc.marshalFunc, tc.unMarshalFunc)\n\t\t})\n\t}\n}\n\nfunc assertConfig(\n\tt *testing.T,\n\tmarshalFunc func(in interface{}) (out []byte, err error),\n\tunMarshalFunc func(in []byte, out interface{}) (err error),\n) {\n\tvar config OriginRequestConfig\n\tvar config2 OriginRequestConfig\n\n\tassert.NoError(t, json.Unmarshal(rawJsonConfig, &config))\n\n\tassert.Equal(t, time.Second*10, config.ConnectTimeout.Duration)\n\tassert.Equal(t, time.Second*30, config.TLSTimeout.Duration)\n\tassert.Equal(t, time.Second*30, config.TCPKeepAlive.Duration)\n\tassert.Equal(t, true, *config.NoHappyEyeballs)\n\tassert.Equal(t, time.Second*60, config.KeepAliveTimeout.Duration)\n\tassert.Equal(t, 10, *config.KeepAliveConnections)\n\tassert.Equal(t, \"app.tunnel.com\", *config.HTTPHostHeader)\n\tassert.Equal(t, \"app.tunnel.com\", *config.OriginServerName)\n\tassert.Equal(t, \"/etc/capool\", *config.CAPool)\n\tassert.Equal(t, true, *config.NoTLSVerify)\n\tassert.Equal(t, true, *config.DisableChunkedEncoding)\n\tassert.Equal(t, true, *config.BastionMode)\n\tassert.Equal(t, \"127.0.0.3\", *config.ProxyAddress)\n\tassert.Equal(t, true, *config.NoTLSVerify)\n\tassert.Equal(t, uint(9000), *config.ProxyPort)\n\tassert.Equal(t, \"socks\", *config.ProxyType)\n\tassert.Equal(t, true, *config.Http2Origin)\n\n\tprivateV4 := \"10.0.0.0/8\"\n\tprivateV6 := \"fc00::/7\"\n\tipRules := []IngressIPRule{\n\t\t{\n\t\t\tPrefix: &privateV4,\n\t\t\tPorts:  []int{80, 8080},\n\t\t\tAllow:  false,\n\t\t},\n\t\t{\n\t\t\tPrefix: &privateV6,\n\t\t\tPorts:  []int{443, 4443},\n\t\t\tAllow:  true,\n\t\t},\n\t}\n\tassert.Equal(t, ipRules, config.IPRules)\n\n\t// validate that serializing and deserializing again matches the deserialization from raw string\n\tresult, err := marshalFunc(config)\n\trequire.NoError(t, err)\n\terr = unMarshalFunc(result, &config2)\n\trequire.NoError(t, err)\n\n\trequire.Equal(t, config2, config)\n}\n"
  },
  {
    "path": "config/manager.go",
    "content": "package config\n\nimport (\n\t\"io\"\n\t\"os\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\tyaml \"gopkg.in/yaml.v3\"\n\n\t\"github.com/cloudflare/cloudflared/watcher\"\n)\n\n// Notifier sends out config updates\ntype Notifier interface {\n\tConfigDidUpdate(Root)\n}\n\n// Manager is the base functions of the config manager\ntype Manager interface {\n\tStart(Notifier) error\n\tShutdown()\n}\n\n// FileManager watches the yaml config for changes\n// sends updates to the service to reconfigure to match the updated config\ntype FileManager struct {\n\twatcher    watcher.Notifier\n\tnotifier   Notifier\n\tconfigPath string\n\tlog        *zerolog.Logger\n\tReadConfig func(string, *zerolog.Logger) (Root, error)\n}\n\n// NewFileManager creates a config manager\nfunc NewFileManager(watcher watcher.Notifier, configPath string, log *zerolog.Logger) (*FileManager, error) {\n\tm := &FileManager{\n\t\twatcher:    watcher,\n\t\tconfigPath: configPath,\n\t\tlog:        log,\n\t\tReadConfig: readConfigFromPath,\n\t}\n\terr := watcher.Add(configPath)\n\treturn m, err\n}\n\n// Start starts the runloop to watch for config changes\nfunc (m *FileManager) Start(notifier Notifier) error {\n\tm.notifier = notifier\n\n\t// update the notifier with a fresh config on start\n\tconfig, err := m.GetConfig()\n\tif err != nil {\n\t\treturn err\n\t}\n\tnotifier.ConfigDidUpdate(config)\n\n\tm.watcher.Start(m)\n\treturn nil\n}\n\n// GetConfig reads the yaml file from the disk\nfunc (m *FileManager) GetConfig() (Root, error) {\n\treturn m.ReadConfig(m.configPath, m.log)\n}\n\n// Shutdown stops the watcher\nfunc (m *FileManager) Shutdown() {\n\tm.watcher.Shutdown()\n}\n\nfunc readConfigFromPath(configPath string, log *zerolog.Logger) (Root, error) {\n\tif configPath == \"\" {\n\t\treturn Root{}, errors.New(\"unable to find config file\")\n\t}\n\n\tfile, err := os.Open(configPath)\n\tif err != nil {\n\t\treturn Root{}, err\n\t}\n\tdefer file.Close()\n\n\tvar config Root\n\tif err := yaml.NewDecoder(file).Decode(&config); err != nil {\n\t\tif err == io.EOF {\n\t\t\tlog.Error().Msgf(\"Configuration file %s was empty\", configPath)\n\t\t\treturn Root{}, nil\n\t\t}\n\t\treturn Root{}, errors.Wrap(err, \"error parsing YAML in config file at \"+configPath)\n\t}\n\n\treturn config, nil\n}\n\n// File change notifications from the watcher\n\n// WatcherItemDidChange triggers when the yaml config is updated\n// sends the updated config to the service to reload its state\nfunc (m *FileManager) WatcherItemDidChange(filepath string) {\n\tconfig, err := m.GetConfig()\n\tif err != nil {\n\t\tm.log.Err(err).Msg(\"Failed to read new config\")\n\t\treturn\n\t}\n\tm.log.Info().Msg(\"Config file has been updated\")\n\tm.notifier.ConfigDidUpdate(config)\n}\n\n// WatcherDidError notifies of errors with the file watcher\nfunc (m *FileManager) WatcherDidError(err error) {\n\tm.log.Err(err).Msg(\"Config watcher encountered an error\")\n}\n"
  },
  {
    "path": "config/manager_test.go",
    "content": "package config\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/cloudflare/cloudflared/watcher\"\n)\n\ntype mockNotifier struct {\n\tconfigs []Root\n}\n\nfunc (n *mockNotifier) ConfigDidUpdate(c Root) {\n\tn.configs = append(n.configs, c)\n}\n\ntype mockFileWatcher struct {\n\tpath     string\n\tnotifier watcher.Notification\n\tready    chan struct{}\n}\n\nfunc (w *mockFileWatcher) Start(n watcher.Notification) {\n\tw.notifier = n\n\tw.ready <- struct{}{}\n}\n\nfunc (w *mockFileWatcher) Add(string) error {\n\treturn nil\n}\n\nfunc (w *mockFileWatcher) Shutdown() {\n\n}\n\nfunc (w *mockFileWatcher) TriggerChange() {\n\tw.notifier.WatcherItemDidChange(w.path)\n}\n\nfunc TestConfigChanged(t *testing.T) {\n\tfilePath := \"config.yaml\"\n\tf, err := os.Create(filePath)\n\tassert.NoError(t, err)\n\tdefer func() {\n\t\t_ = f.Close()\n\t\t_ = os.Remove(filePath)\n\t}()\n\tc := &Root{\n\t\tForwarders: []Forwarder{\n\t\t\t{\n\t\t\t\tURL:      \"test.daltoniam.com\",\n\t\t\t\tListener: \"127.0.0.1:8080\",\n\t\t\t},\n\t\t},\n\t}\n\tconfigRead := func(configPath string, log *zerolog.Logger) (Root, error) {\n\t\treturn *c, nil\n\t}\n\twait := make(chan struct{})\n\tw := &mockFileWatcher{path: filePath, ready: wait}\n\n\tlog := zerolog.Nop()\n\n\tservice, err := NewFileManager(w, filePath, &log)\n\tservice.ReadConfig = configRead\n\tassert.NoError(t, err)\n\n\tn := &mockNotifier{}\n\tgo service.Start(n)\n\n\t<-wait\n\tc.Forwarders = append(c.Forwarders, Forwarder{URL: \"add.daltoniam.com\", Listener: \"127.0.0.1:8081\"})\n\tw.TriggerChange()\n\n\tservice.Shutdown()\n\n\tassert.Len(t, n.configs, 2, \"did not get 2 config updates as expected\")\n\tassert.Len(t, n.configs[0].Forwarders, 1, \"not the amount of forwarders expected\")\n\tassert.Len(t, n.configs[1].Forwarders, 2, \"not the amount of forwarders expected\")\n\n\tassert.Equal(t, n.configs[0].Forwarders[0].Hash(), c.Forwarders[0].Hash(), \"forwarder hashes don't match\")\n\tassert.Equal(t, n.configs[1].Forwarders[0].Hash(), c.Forwarders[0].Hash(), \"forwarder hashes don't match\")\n\tassert.Equal(t, n.configs[1].Forwarders[1].Hash(), c.Forwarders[1].Hash(), \"forwarder hashes don't match\")\n}\n"
  },
  {
    "path": "config/model.go",
    "content": "package config\n\nimport (\n\t\"crypto/sha256\"\n\t\"fmt\"\n\t\"io\"\n)\n\n// Forwarder represents a client side listener to forward traffic to the edge\ntype Forwarder struct {\n\tURL           string `json:\"url\"`\n\tListener      string `json:\"listener\"`\n\tTokenClientID string `json:\"service_token_id\" yaml:\"serviceTokenID\"`\n\tTokenSecret   string `json:\"secret_token_id\" yaml:\"serviceTokenSecret\"`\n\tDestination   string `json:\"destination\"`\n\tIsFedramp     bool   `json:\"is_fedramp\" yaml:\"isFedramp\"`\n}\n\n// Tunnel represents a tunnel that should be started\ntype Tunnel struct {\n\tURL          string `json:\"url\"`\n\tOrigin       string `json:\"origin\"`\n\tProtocolType string `json:\"type\"`\n}\n\n// Root is the base options to configure the service.\ntype Root struct {\n\tLogDirectory string      `json:\"log_directory\" yaml:\"logDirectory,omitempty\"`\n\tLogLevel     string      `json:\"log_level\" yaml:\"logLevel,omitempty\"`\n\tForwarders   []Forwarder `json:\"forwarders,omitempty\" yaml:\"forwarders,omitempty\"`\n\tTunnels      []Tunnel    `json:\"tunnels,omitempty\" yaml:\"tunnels,omitempty\"`\n\t// `resolver` key is reserved for a removed feature (proxy-dns) and should not be used.\n}\n\n// Hash returns the computed values to see if the forwarder values change\nfunc (f *Forwarder) Hash() string {\n\th := sha256.New()\n\t_, _ = io.WriteString(h, f.URL)\n\t_, _ = io.WriteString(h, f.Listener)\n\t_, _ = io.WriteString(h, f.TokenClientID)\n\t_, _ = io.WriteString(h, f.TokenSecret)\n\t_, _ = io.WriteString(h, f.Destination)\n\treturn fmt.Sprintf(\"%x\", h.Sum(nil))\n}\n"
  },
  {
    "path": "connection/connection.go",
    "content": "package connection\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"net\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/pkg/errors\"\n\n\t\"github.com/cloudflare/cloudflared/tracing\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n\t\"github.com/cloudflare/cloudflared/websocket\"\n)\n\nconst (\n\tlbProbeUserAgentPrefix = \"Mozilla/5.0 (compatible; Cloudflare-Traffic-Manager/1.0; +https://www.cloudflare.com/traffic-manager/;\"\n\tLogFieldConnIndex      = \"connIndex\"\n\tMaxGracePeriod         = time.Minute * 3\n\tMaxConcurrentStreams   = math.MaxUint32\n\n\tcontentTypeHeader      = \"content-type\"\n\tcontentLengthHeader    = \"content-length\"\n\ttransferEncodingHeader = \"transfer-encoding\"\n\n\tsseContentType     = \"text/event-stream\"\n\tgrpcContentType    = \"application/grpc\"\n\tsseJsonContentType = \"application/x-ndjson\"\n\n\tchunkTransferEncoding = \"chunked\"\n)\n\nvar (\n\tswitchingProtocolText = fmt.Sprintf(\"%d %s\", http.StatusSwitchingProtocols, http.StatusText(http.StatusSwitchingProtocols))\n\tflushableContentTypes = []string{sseContentType, grpcContentType, sseJsonContentType}\n)\n\n// TunnelConnection represents the connection to the edge.\n// The Serve method is provided to allow clients to handle any errors from the connection encountered during\n// processing of the connection. Cancelling of the context provided to Serve will close the connection.\ntype TunnelConnection interface {\n\tServe(ctx context.Context) error\n}\n\ntype Orchestrator interface {\n\tUpdateConfig(version int32, config []byte) *pogs.UpdateConfigurationResponse\n\tGetConfigJSON() ([]byte, error)\n\tGetOriginProxy() (OriginProxy, error)\n}\n\ntype TunnelProperties struct {\n\tCredentials    Credentials\n\tQuickTunnelUrl string\n}\n\n// Credentials are stored in the credentials file and contain all info needed to run a tunnel.\ntype Credentials struct {\n\tAccountTag   string\n\tTunnelSecret []byte\n\tTunnelID     uuid.UUID\n\tEndpoint     string\n}\n\nfunc (c *Credentials) Auth() pogs.TunnelAuth {\n\treturn pogs.TunnelAuth{\n\t\tAccountTag:   c.AccountTag,\n\t\tTunnelSecret: c.TunnelSecret,\n\t}\n}\n\n// TunnelToken are Credentials but encoded with custom fields namings.\ntype TunnelToken struct {\n\tAccountTag   string    `json:\"a\"`\n\tTunnelSecret []byte    `json:\"s\"`\n\tTunnelID     uuid.UUID `json:\"t\"`\n\tEndpoint     string    `json:\"e,omitempty\"`\n}\n\nfunc (t TunnelToken) Credentials() Credentials {\n\t// nolint: gosimple\n\treturn Credentials{\n\t\tAccountTag:   t.AccountTag,\n\t\tTunnelSecret: t.TunnelSecret,\n\t\tTunnelID:     t.TunnelID,\n\t\tEndpoint:     t.Endpoint,\n\t}\n}\n\nfunc (t TunnelToken) Encode() (string, error) {\n\tval, err := json.Marshal(t)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"could not JSON encode token\")\n\t}\n\n\treturn base64.StdEncoding.EncodeToString(val), nil\n}\n\ntype ClassicTunnelProperties struct {\n\tHostname   string\n\tOriginCert []byte\n\t// feature-flag to use new edge reconnect tokens\n\tUseReconnectToken bool\n}\n\n// Type indicates the connection type of the  connection.\ntype Type int\n\nconst (\n\tTypeWebsocket Type = iota\n\tTypeTCP\n\tTypeControlStream\n\tTypeHTTP\n\tTypeConfiguration\n)\n\n// ShouldFlush returns whether this kind of connection should actively flush data\nfunc (t Type) shouldFlush() bool {\n\tswitch t {\n\tcase TypeWebsocket, TypeTCP, TypeControlStream:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc (t Type) String() string {\n\tswitch t {\n\tcase TypeWebsocket:\n\t\treturn \"websocket\"\n\tcase TypeTCP:\n\t\treturn \"tcp\"\n\tcase TypeControlStream:\n\t\treturn \"control stream\"\n\tcase TypeHTTP:\n\t\treturn \"http\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"Unknown Type %d\", t)\n\t}\n}\n\n// OriginProxy is how data flows from cloudflared to the origin services running behind it.\ntype OriginProxy interface {\n\tProxyHTTP(w ResponseWriter, tr *tracing.TracedHTTPRequest, isWebsocket bool) error\n\tProxyTCP(ctx context.Context, rwa ReadWriteAcker, req *TCPRequest) error\n}\n\n// TCPRequest defines the input format needed to perform a TCP proxy.\ntype TCPRequest struct {\n\tDest      string\n\tCFRay     string\n\tLBProbe   bool\n\tFlowID    string\n\tCfTraceID string\n\tConnIndex uint8\n}\n\n// ReadWriteAcker is a readwriter with the ability to Acknowledge to the downstream (edge) that the origin has\n// accepted the connection.\ntype ReadWriteAcker interface {\n\tio.ReadWriter\n\tAckConnection(tracePropagation string) error\n}\n\n// HTTPResponseReadWriteAcker is an HTTP implementation of ReadWriteAcker.\ntype HTTPResponseReadWriteAcker struct {\n\tr   io.Reader\n\tw   ResponseWriter\n\tf   http.Flusher\n\treq *http.Request\n}\n\n// NewHTTPResponseReadWriterAcker returns a new instance of HTTPResponseReadWriteAcker.\nfunc NewHTTPResponseReadWriterAcker(w ResponseWriter, flusher http.Flusher, req *http.Request) *HTTPResponseReadWriteAcker {\n\treturn &HTTPResponseReadWriteAcker{\n\t\tr:   req.Body,\n\t\tw:   w,\n\t\tf:   flusher,\n\t\treq: req,\n\t}\n}\n\nfunc (h *HTTPResponseReadWriteAcker) Read(p []byte) (int, error) {\n\treturn h.r.Read(p)\n}\n\nfunc (h *HTTPResponseReadWriteAcker) Write(p []byte) (int, error) {\n\tn, err := h.w.Write(p)\n\tif n > 0 {\n\t\th.f.Flush()\n\t}\n\treturn n, err\n}\n\n// AckConnection acks an HTTP connection by sending a switch protocols status code that enables the caller to\n// upgrade to streams.\nfunc (h *HTTPResponseReadWriteAcker) AckConnection(tracePropagation string) error {\n\tresp := &http.Response{\n\t\tStatus:        switchingProtocolText,\n\t\tStatusCode:    http.StatusSwitchingProtocols,\n\t\tContentLength: -1,\n\t\tHeader:        http.Header{},\n\t}\n\n\tif secWebsocketKey := h.req.Header.Get(\"Sec-WebSocket-Key\"); secWebsocketKey != \"\" {\n\t\tresp.Header = websocket.NewResponseHeader(h.req)\n\t}\n\n\tif tracePropagation != \"\" {\n\t\tresp.Header.Add(tracing.CanonicalCloudflaredTracingHeader, tracePropagation)\n\t}\n\n\treturn h.w.WriteRespHeaders(resp.StatusCode, resp.Header)\n}\n\n// localProxyConnection emulates an incoming connection to cloudflared as a net.Conn.\n// Used when handling a \"hijacked\" connection from connection.ResponseWriter\ntype localProxyConnection struct {\n\tio.ReadWriteCloser\n}\n\nfunc (c *localProxyConnection) Read(b []byte) (int, error) {\n\treturn c.ReadWriteCloser.Read(b)\n}\n\nfunc (c *localProxyConnection) Write(b []byte) (int, error) {\n\treturn c.ReadWriteCloser.Write(b)\n}\n\nfunc (c *localProxyConnection) Close() error {\n\treturn c.ReadWriteCloser.Close()\n}\n\nfunc (c *localProxyConnection) LocalAddr() net.Addr {\n\t// Unused LocalAddr\n\treturn &net.TCPAddr{IP: net.IPv6loopback, Port: 0, Zone: \"\"}\n}\n\nfunc (c *localProxyConnection) RemoteAddr() net.Addr {\n\t// Unused RemoteAddr\n\treturn &net.TCPAddr{IP: net.IPv6loopback, Port: 0, Zone: \"\"}\n}\n\nfunc (c *localProxyConnection) SetDeadline(t time.Time) error {\n\t// ignored since we can't set the read/write Deadlines for the tunnel back to origintunneld\n\treturn nil\n}\n\nfunc (c *localProxyConnection) SetReadDeadline(t time.Time) error {\n\t// ignored since we can't set the read/write Deadlines for the tunnel back to origintunneld\n\treturn nil\n}\n\nfunc (c *localProxyConnection) SetWriteDeadline(t time.Time) error {\n\t// ignored since we can't set the read/write Deadlines for the tunnel back to origintunneld\n\treturn nil\n}\n\n// ResponseWriter is the response path for a request back through cloudflared's tunnel.\ntype ResponseWriter interface {\n\tWriteRespHeaders(status int, header http.Header) error\n\tAddTrailer(trailerName, trailerValue string)\n\thttp.ResponseWriter\n\thttp.Hijacker\n\tio.Writer\n}\n\ntype ConnectedFuse interface {\n\tConnected()\n\tIsConnected() bool\n}\n\n// Helper method to let the caller know what content-types should require a flush on every\n// write to a ResponseWriter.\nfunc shouldFlush(headers http.Header) bool {\n\t// When doing Server Side Events (SSE), some frameworks don't respect the `Content-Type` header.\n\t// Therefore, we need to rely on other ways to know whether we should flush on write or not. A good\n\t// approach is to assume that responses without `Content-Length` or with `Transfer-Encoding: chunked`\n\t// are streams, and therefore, should be flushed right away to the eyeball.\n\t// References:\n\t// - https://datatracker.ietf.org/doc/html/rfc7230#section-4.1\n\t// - https://datatracker.ietf.org/doc/html/rfc9112#section-6.1\n\tif contentLength := headers.Get(contentLengthHeader); contentLength == \"\" {\n\t\treturn true\n\t}\n\tif transferEncoding := headers.Get(transferEncodingHeader); transferEncoding != \"\" {\n\t\ttransferEncoding = strings.ToLower(transferEncoding)\n\t\tif strings.Contains(transferEncoding, chunkTransferEncoding) {\n\t\t\treturn true\n\t\t}\n\t}\n\tif contentType := headers.Get(contentTypeHeader); contentType != \"\" {\n\t\tcontentType = strings.ToLower(contentType)\n\t\tfor _, c := range flushableContentTypes {\n\t\t\tif strings.HasPrefix(contentType, c) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc uint8ToString(input uint8) string {\n\treturn strconv.FormatUint(uint64(input), 10)\n}\n\nfunc FindCfRayHeader(req *http.Request) string {\n\treturn req.Header.Get(\"Cf-Ray\")\n}\n\nfunc IsLBProbeRequest(req *http.Request) bool {\n\treturn strings.HasPrefix(req.UserAgent(), lbProbeUserAgentPrefix)\n}\n"
  },
  {
    "path": "connection/connection_test.go",
    "content": "package connection\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/big\"\n\t\"net/http\"\n\t\"testing\"\n\t\"time\"\n\n\tpkgerrors \"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/require\"\n\n\tcfdflow \"github.com/cloudflare/cloudflared/flow\"\n\n\t\"github.com/cloudflare/cloudflared/stream\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n\ttunnelpogs \"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n\t\"github.com/cloudflare/cloudflared/websocket\"\n)\n\nconst (\n\tlargeFileSize   = 2 * 1024 * 1024\n\ttestGracePeriod = time.Millisecond * 100\n)\n\nvar (\n\ttestOrchestrator = &mockOrchestrator{\n\t\toriginProxy: &mockOriginProxy{},\n\t}\n\tlog           = zerolog.Nop()\n\ttestLargeResp = make([]byte, largeFileSize)\n)\n\nvar _ ReadWriteAcker = (*HTTPResponseReadWriteAcker)(nil)\n\ntype testRequest struct {\n\tname           string\n\tendpoint       string\n\texpectedStatus int\n\texpectedBody   []byte\n\tisProxyError   bool\n}\n\ntype mockOrchestrator struct {\n\toriginProxy OriginProxy\n}\n\nfunc (mcr *mockOrchestrator) GetConfigJSON() ([]byte, error) {\n\treturn nil, fmt.Errorf(\"not implemented\")\n}\n\nfunc (*mockOrchestrator) UpdateConfig(version int32, config []byte) *tunnelpogs.UpdateConfigurationResponse {\n\treturn &tunnelpogs.UpdateConfigurationResponse{\n\t\tLastAppliedVersion: version,\n\t}\n}\n\nfunc (mcr *mockOrchestrator) GetOriginProxy() (OriginProxy, error) {\n\treturn mcr.originProxy, nil\n}\n\nfunc (mcr *mockOrchestrator) WarpRoutingEnabled() (enabled bool) {\n\treturn true\n}\n\ntype mockOriginProxy struct{}\n\nfunc (moc *mockOriginProxy) ProxyHTTP(\n\tw ResponseWriter,\n\ttr *tracing.TracedHTTPRequest,\n\tisWebsocket bool,\n) error {\n\treq := tr.Request\n\tif isWebsocket {\n\t\tswitch req.URL.Path {\n\t\tcase \"/ws/echo\":\n\t\t\treturn wsEchoEndpoint(w, req)\n\t\tcase \"/ws/flaky\":\n\t\t\treturn wsFlakyEndpoint(w, req)\n\t\tdefault:\n\t\t\toriginRespEndpoint(w, http.StatusNotFound, []byte(\"ws endpoint not found\"))\n\t\t\treturn fmt.Errorf(\"unknown websocket endpoint %s\", req.URL.Path)\n\t\t}\n\t}\n\tswitch req.URL.Path {\n\tcase \"/ok\":\n\t\toriginRespEndpoint(w, http.StatusOK, []byte(http.StatusText(http.StatusOK)))\n\tcase \"/large_file\":\n\t\toriginRespEndpoint(w, http.StatusOK, testLargeResp)\n\tcase \"/400\":\n\t\toriginRespEndpoint(w, http.StatusBadRequest, []byte(http.StatusText(http.StatusBadRequest)))\n\tcase \"/500\":\n\t\toriginRespEndpoint(w, http.StatusInternalServerError, []byte(http.StatusText(http.StatusInternalServerError)))\n\tcase \"/error\":\n\t\treturn fmt.Errorf(\"Failed to proxy to origin\")\n\tdefault:\n\t\toriginRespEndpoint(w, http.StatusNotFound, []byte(\"page not found\"))\n\t}\n\treturn nil\n}\n\nfunc (moc *mockOriginProxy) ProxyTCP(\n\tctx context.Context,\n\trwa ReadWriteAcker,\n\tr *TCPRequest,\n) error {\n\tif r.CfTraceID == \"flow-rate-limited\" {\n\t\treturn pkgerrors.Wrap(cfdflow.ErrTooManyActiveFlows, \"tcp flow rate limited\")\n\t}\n\n\treturn nil\n}\n\ntype echoPipe struct {\n\treader *io.PipeReader\n\twriter *io.PipeWriter\n}\n\nfunc (ep *echoPipe) Read(p []byte) (int, error) {\n\treturn ep.reader.Read(p)\n}\n\nfunc (ep *echoPipe) Write(p []byte) (int, error) {\n\treturn ep.writer.Write(p)\n}\n\n// A mock origin that echos data by streaming like a tcpOverWSConnection\n// https://github.com/cloudflare/cloudflared/blob/master/ingress/origin_connection.go\nfunc wsEchoEndpoint(w ResponseWriter, r *http.Request) error {\n\tresp := &http.Response{\n\t\tStatusCode: http.StatusSwitchingProtocols,\n\t}\n\tif err := w.WriteRespHeaders(resp.StatusCode, resp.Header); err != nil {\n\t\treturn err\n\t}\n\twsCtx, cancel := context.WithCancel(r.Context())\n\treadPipe, writePipe := io.Pipe()\n\n\twsConn := websocket.NewConn(wsCtx, NewHTTPResponseReadWriterAcker(w, w.(http.Flusher), r), &log)\n\tgo func() {\n\t\tselect {\n\t\tcase <-wsCtx.Done():\n\t\tcase <-r.Context().Done():\n\t\t}\n\t\treadPipe.Close()\n\t\twritePipe.Close()\n\t}()\n\n\toriginConn := &echoPipe{reader: readPipe, writer: writePipe}\n\tstream.Pipe(wsConn, originConn, &log)\n\tcancel()\n\twsConn.Close()\n\treturn nil\n}\n\ntype flakyConn struct {\n\tcloseAt time.Time\n}\n\nfunc (fc *flakyConn) Read(p []byte) (int, error) {\n\tif time.Now().After(fc.closeAt) {\n\t\treturn 0, io.EOF\n\t}\n\tn := copy(p, \"Read from flaky connection\")\n\treturn n, nil\n}\n\nfunc (fc *flakyConn) Write(p []byte) (int, error) {\n\tif time.Now().After(fc.closeAt) {\n\t\treturn 0, fmt.Errorf(\"flaky connection closed\")\n\t}\n\treturn len(p), nil\n}\n\nfunc wsFlakyEndpoint(w ResponseWriter, r *http.Request) error {\n\tresp := &http.Response{\n\t\tStatusCode: http.StatusSwitchingProtocols,\n\t}\n\tif err := w.WriteRespHeaders(resp.StatusCode, resp.Header); err != nil {\n\t\treturn err\n\t}\n\twsCtx, cancel := context.WithCancel(r.Context())\n\n\twsConn := websocket.NewConn(wsCtx, NewHTTPResponseReadWriterAcker(w, w.(http.Flusher), r), &log)\n\n\trInt, _ := rand.Int(rand.Reader, big.NewInt(50))\n\tclosedAfter := time.Millisecond * time.Duration(rInt.Int64())\n\toriginConn := &flakyConn{closeAt: time.Now().Add(closedAfter)}\n\tstream.Pipe(wsConn, originConn, &log)\n\tcancel()\n\twsConn.Close()\n\treturn nil\n}\n\nfunc originRespEndpoint(w ResponseWriter, status int, data []byte) {\n\tresp := &http.Response{\n\t\tStatusCode: status,\n\t}\n\t_ = w.WriteRespHeaders(resp.StatusCode, resp.Header)\n\t_, _ = w.Write(data)\n}\n\ntype mockConnectedFuse struct{}\n\nfunc (mcf mockConnectedFuse) Connected() {}\n\nfunc (mcf mockConnectedFuse) IsConnected() bool {\n\treturn true\n}\n\nfunc TestShouldFlushHeaders(t *testing.T) {\n\ttests := []struct {\n\t\theaders     map[string]string\n\t\tshouldFlush bool\n\t}{\n\t\t{\n\t\t\theaders:     map[string]string{contentTypeHeader: \"application/json\", contentLengthHeader: \"1\"},\n\t\t\tshouldFlush: false,\n\t\t},\n\t\t{\n\t\t\theaders:     map[string]string{contentTypeHeader: \"text/html\", contentLengthHeader: \"1\"},\n\t\t\tshouldFlush: false,\n\t\t},\n\t\t{\n\t\t\theaders:     map[string]string{contentTypeHeader: \"text/event-stream\", contentLengthHeader: \"1\"},\n\t\t\tshouldFlush: true,\n\t\t},\n\t\t{\n\t\t\theaders:     map[string]string{contentTypeHeader: \"application/grpc\", contentLengthHeader: \"1\"},\n\t\t\tshouldFlush: true,\n\t\t},\n\t\t{\n\t\t\theaders:     map[string]string{contentTypeHeader: \"application/x-ndjson\", contentLengthHeader: \"1\"},\n\t\t\tshouldFlush: true,\n\t\t},\n\t\t{\n\t\t\theaders:     map[string]string{contentTypeHeader: \"application/json\"},\n\t\t\tshouldFlush: true,\n\t\t},\n\t\t{\n\t\t\theaders:     map[string]string{contentTypeHeader: \"application/json\", contentLengthHeader: \"-1\", transferEncodingHeader: \"chunked\"},\n\t\t\tshouldFlush: true,\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\theaders := http.Header{}\n\t\tfor k, v := range test.headers {\n\t\t\theaders.Add(k, v)\n\t\t}\n\n\t\trequire.Equal(t, test.shouldFlush, shouldFlush(headers))\n\t}\n}\n"
  },
  {
    "path": "connection/control.go",
    "content": "package connection\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/pkg/errors\"\n\n\t\"github.com/cloudflare/cloudflared/management\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\n// registerClient derives a named tunnel rpc client that can then be used to register and unregister connections.\ntype registerClientFunc func(context.Context, io.ReadWriteCloser, time.Duration) tunnelrpc.RegistrationClient\n\ntype controlStream struct {\n\tobserver *Observer\n\n\tconnectedFuse    ConnectedFuse\n\ttunnelProperties *TunnelProperties\n\tconnIndex        uint8\n\tedgeAddress      net.IP\n\tprotocol         Protocol\n\n\tregisterClientFunc registerClientFunc\n\tregisterTimeout    time.Duration\n\n\tgracefulShutdownC <-chan struct{}\n\tgracePeriod       time.Duration\n\tstoppedGracefully bool\n}\n\n// ControlStreamHandler registers connections with origintunneld and initiates graceful shutdown.\ntype ControlStreamHandler interface {\n\t// ServeControlStream handles the control plane of the transport in the current goroutine calling this\n\tServeControlStream(ctx context.Context, rw io.ReadWriteCloser, connOptions *pogs.ConnectionOptions, tunnelConfigGetter TunnelConfigJSONGetter) error\n\t// IsStopped tells whether the method above has finished\n\tIsStopped() bool\n}\n\ntype TunnelConfigJSONGetter interface {\n\tGetConfigJSON() ([]byte, error)\n}\n\n// NewControlStream returns a new instance of ControlStreamHandler\nfunc NewControlStream(\n\tobserver *Observer,\n\tconnectedFuse ConnectedFuse,\n\ttunnelProperties *TunnelProperties,\n\tconnIndex uint8,\n\tedgeAddress net.IP,\n\tregisterClientFunc registerClientFunc,\n\tregisterTimeout time.Duration,\n\tgracefulShutdownC <-chan struct{},\n\tgracePeriod time.Duration,\n\tprotocol Protocol,\n) ControlStreamHandler {\n\tif registerClientFunc == nil {\n\t\tregisterClientFunc = tunnelrpc.NewRegistrationClient\n\t}\n\treturn &controlStream{\n\t\tobserver:           observer,\n\t\tconnectedFuse:      connectedFuse,\n\t\ttunnelProperties:   tunnelProperties,\n\t\tregisterClientFunc: registerClientFunc,\n\t\tregisterTimeout:    registerTimeout,\n\t\tconnIndex:          connIndex,\n\t\tedgeAddress:        edgeAddress,\n\t\tgracefulShutdownC:  gracefulShutdownC,\n\t\tgracePeriod:        gracePeriod,\n\t\tprotocol:           protocol,\n\t}\n}\n\nfunc (c *controlStream) ServeControlStream(\n\tctx context.Context,\n\trw io.ReadWriteCloser,\n\tconnOptions *pogs.ConnectionOptions,\n\ttunnelConfigGetter TunnelConfigJSONGetter,\n) error {\n\tregistrationClient := c.registerClientFunc(ctx, rw, c.registerTimeout)\n\tc.observer.logConnecting(c.connIndex, c.edgeAddress, c.protocol)\n\tregistrationDetails, err := registrationClient.RegisterConnection(\n\t\tctx,\n\t\tc.tunnelProperties.Credentials.Auth(),\n\t\tc.tunnelProperties.Credentials.TunnelID,\n\t\tconnOptions,\n\t\tc.connIndex,\n\t\tc.edgeAddress)\n\tif err != nil {\n\t\tdefer registrationClient.Close()\n\t\tif err.Error() == DuplicateConnectionError {\n\t\t\tc.observer.metrics.regFail.WithLabelValues(\"dup_edge_conn\", \"registerConnection\").Inc()\n\t\t\treturn errDuplicationConnection\n\t\t}\n\t\tc.observer.metrics.regFail.WithLabelValues(\"server_error\", \"registerConnection\").Inc()\n\t\treturn serverRegistrationErrorFromRPC(err)\n\t}\n\tc.observer.metrics.regSuccess.WithLabelValues(\"registerConnection\").Inc()\n\n\tc.observer.logConnected(registrationDetails.UUID, c.connIndex, registrationDetails.Location, c.edgeAddress, c.protocol)\n\tc.observer.sendConnectedEvent(c.connIndex, c.protocol, registrationDetails.Location, c.edgeAddress)\n\tc.connectedFuse.Connected()\n\n\t// if conn index is 0 and tunnel is not remotely managed, then send local ingress rules configuration\n\tif c.connIndex == 0 && !registrationDetails.TunnelIsRemotelyManaged {\n\t\tif tunnelConfig, err := tunnelConfigGetter.GetConfigJSON(); err == nil {\n\t\t\tif err := registrationClient.SendLocalConfiguration(ctx, tunnelConfig); err != nil {\n\t\t\t\tc.observer.metrics.localConfigMetrics.pushesErrors.Inc()\n\t\t\t\tc.observer.log.Err(err).Msg(\"unable to send local configuration\")\n\t\t\t}\n\t\t\tc.observer.metrics.localConfigMetrics.pushes.Inc()\n\t\t} else {\n\t\t\tc.observer.log.Err(err).Msg(\"failed to obtain current configuration\")\n\t\t}\n\t}\n\n\treturn c.waitForUnregister(ctx, registrationClient)\n}\n\nfunc (c *controlStream) waitForUnregister(ctx context.Context, registrationClient tunnelrpc.RegistrationClient) error {\n\t// wait for connection termination or start of graceful shutdown\n\tdefer registrationClient.Close()\n\tvar shutdownError error\n\tselect {\n\tcase <-ctx.Done():\n\t\tshutdownError = ctx.Err()\n\t\tbreak\n\tcase <-c.gracefulShutdownC:\n\t\tc.stoppedGracefully = true\n\t}\n\n\tc.observer.sendUnregisteringEvent(c.connIndex)\n\terr := registrationClient.GracefulShutdown(ctx, c.gracePeriod)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Error shutting down control stream\")\n\t}\n\tc.observer.log.Info().\n\t\tInt(management.EventTypeKey, int(management.Cloudflared)).\n\t\tUint8(LogFieldConnIndex, c.connIndex).\n\t\tIPAddr(LogFieldIPAddress, c.edgeAddress).\n\t\tMsg(\"Unregistered tunnel connection\")\n\treturn shutdownError\n}\n\nfunc (c *controlStream) IsStopped() bool {\n\treturn c.stoppedGracefully\n}\n"
  },
  {
    "path": "connection/errors.go",
    "content": "package connection\n\nimport (\n\ttunnelpogs \"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\nconst (\n\tDuplicateConnectionError = \"EDUPCONN\"\n)\n\ntype DupConnRegisterTunnelError struct{}\n\nvar errDuplicationConnection = DupConnRegisterTunnelError{}\n\nfunc (e DupConnRegisterTunnelError) Error() string {\n\treturn \"already connected to this server, trying another address\"\n}\n\n// Dial to edge server with quic failed\ntype EdgeQuicDialError struct {\n\tCause error\n}\n\nfunc (e *EdgeQuicDialError) Error() string {\n\treturn \"failed to dial to edge with quic: \" + e.Cause.Error()\n}\n\nfunc (e *EdgeQuicDialError) Unwrap() error {\n\treturn e.Cause\n}\n\n// RegisterTunnel error from server\ntype ServerRegisterTunnelError struct {\n\tCause     error\n\tPermanent bool\n}\n\nfunc (e ServerRegisterTunnelError) Error() string {\n\treturn e.Cause.Error()\n}\n\nfunc serverRegistrationErrorFromRPC(err error) ServerRegisterTunnelError {\n\tif retryable, ok := err.(*tunnelpogs.RetryableError); ok {\n\t\treturn ServerRegisterTunnelError{\n\t\t\tCause:     retryable.Unwrap(),\n\t\t\tPermanent: false,\n\t\t}\n\t}\n\treturn ServerRegisterTunnelError{\n\t\tCause:     err,\n\t\tPermanent: true,\n\t}\n}\n\ntype ControlStreamError struct{}\n\nvar _ error = &ControlStreamError{}\n\nfunc (e *ControlStreamError) Error() string {\n\treturn \"control stream encountered a failure while serving\"\n}\n\ntype StreamListenerError struct{}\n\nvar _ error = &StreamListenerError{}\n\nfunc (e *StreamListenerError) Error() string {\n\treturn \"accept stream listener encountered a failure while serving\"\n}\n\ntype DatagramManagerError struct{}\n\nvar _ error = &DatagramManagerError{}\n\nfunc (e *DatagramManagerError) Error() string {\n\treturn \"datagram manager encountered a failure while serving\"\n}\n"
  },
  {
    "path": "connection/event.go",
    "content": "package connection\n\nimport \"net\"\n\n// Event is something that happened to a connection, e.g. disconnection or registration.\ntype Event struct {\n\tIndex       uint8\n\tEventType   Status\n\tLocation    string\n\tProtocol    Protocol\n\tURL         string\n\tEdgeAddress net.IP\n}\n\n// Status is the status of a connection.\ntype Status int\n\nconst (\n\t// Disconnected means the connection to the edge was broken.\n\tDisconnected Status = iota\n\t// Connected means the connection to the edge was successfully established.\n\tConnected\n\t// Reconnecting means the connection to the edge is being re-established.\n\tReconnecting\n\t// SetURL means this connection's tunnel was given a URL by the edge. Used for quick tunnels.\n\tSetURL\n\t// RegisteringTunnel means the non-named tunnel is registering its connection.\n\tRegisteringTunnel\n\t// We're unregistering tunnel from the edge in preparation for a disconnect\n\tUnregistering\n)\n"
  },
  {
    "path": "connection/header.go",
    "content": "package connection\n\nimport (\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/pkg/errors\"\n)\n\nvar (\n\t// internal special headers\n\tRequestUserHeaders  = \"cf-cloudflared-request-headers\"\n\tResponseUserHeaders = \"cf-cloudflared-response-headers\"\n\tResponseMetaHeader  = \"cf-cloudflared-response-meta\"\n\n\t// internal special headers\n\tCanonicalResponseUserHeaders = http.CanonicalHeaderKey(ResponseUserHeaders)\n\tCanonicalResponseMetaHeader  = http.CanonicalHeaderKey(ResponseMetaHeader)\n)\n\nvar (\n\t// pre-generate possible values for res\n\tresponseMetaHeaderCfd                = mustInitRespMetaHeader(\"cloudflared\", false)\n\tresponseMetaHeaderCfdFlowRateLimited = mustInitRespMetaHeader(\"cloudflared\", true)\n\tresponseMetaHeaderOrigin             = mustInitRespMetaHeader(\"origin\", false)\n)\n\n// HTTPHeader is a custom header struct that expects only ever one value for the header.\n// This structure is used to serialize the headers and attach them to the HTTP2 request when proxying.\ntype HTTPHeader struct {\n\tName  string\n\tValue string\n}\n\ntype responseMetaHeader struct {\n\tSource          string `json:\"src\"`\n\tFlowRateLimited bool   `json:\"flow_rate_limited,omitempty\"`\n}\n\nfunc mustInitRespMetaHeader(src string, flowRateLimited bool) string {\n\theader, err := json.Marshal(responseMetaHeader{Source: src, FlowRateLimited: flowRateLimited})\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"Failed to serialize response meta header = %s, err: %v\", src, err))\n\t}\n\treturn string(header)\n}\n\nvar headerEncoding = base64.RawStdEncoding\n\n// IsControlResponseHeader is called in the direction of eyeball <- origin.\nfunc IsControlResponseHeader(headerName string) bool {\n\treturn strings.HasPrefix(headerName, \":\") ||\n\t\tstrings.HasPrefix(headerName, \"cf-int-\") ||\n\t\tstrings.HasPrefix(headerName, \"cf-cloudflared-\") ||\n\t\tstrings.HasPrefix(headerName, \"cf-proxy-\")\n}\n\n// isWebsocketClientHeader returns true if the header name is required by the client to upgrade properly\nfunc IsWebsocketClientHeader(headerName string) bool {\n\treturn headerName == \"sec-websocket-accept\" ||\n\t\theaderName == \"connection\" ||\n\t\theaderName == \"upgrade\"\n}\n\n// Serialize HTTP1.x headers by base64-encoding each header name and value,\n// and then joining them in the format of [key:value;]\nfunc SerializeHeaders(h1Headers http.Header) string {\n\t// compute size of the fully serialized value and largest temp buffer we will need\n\tserializedLen := 0\n\tmaxTempLen := 0\n\tfor headerName, headerValues := range h1Headers {\n\t\tfor _, headerValue := range headerValues {\n\t\t\tnameLen := headerEncoding.EncodedLen(len(headerName))\n\t\t\tvalueLen := headerEncoding.EncodedLen(len(headerValue))\n\t\t\tconst delims = 2\n\t\t\tserializedLen += delims + nameLen + valueLen\n\t\t\tif nameLen > maxTempLen {\n\t\t\t\tmaxTempLen = nameLen\n\t\t\t}\n\t\t\tif valueLen > maxTempLen {\n\t\t\t\tmaxTempLen = valueLen\n\t\t\t}\n\t\t}\n\t}\n\tvar buf strings.Builder\n\tbuf.Grow(serializedLen)\n\n\ttemp := make([]byte, maxTempLen)\n\twriteB64 := func(s string) {\n\t\tn := headerEncoding.EncodedLen(len(s))\n\t\tif n > len(temp) {\n\t\t\ttemp = make([]byte, n)\n\t\t}\n\t\theaderEncoding.Encode(temp[:n], []byte(s))\n\t\tbuf.Write(temp[:n])\n\t}\n\n\tfor headerName, headerValues := range h1Headers {\n\t\tfor _, headerValue := range headerValues {\n\t\t\tif buf.Len() > 0 {\n\t\t\t\tbuf.WriteByte(';')\n\t\t\t}\n\t\t\twriteB64(headerName)\n\t\t\tbuf.WriteByte(':')\n\t\t\twriteB64(headerValue)\n\t\t}\n\t}\n\n\treturn buf.String()\n}\n\n// Deserialize headers serialized by `SerializeHeader`\nfunc DeserializeHeaders(serializedHeaders string) ([]HTTPHeader, error) {\n\tconst unableToDeserializeErr = \"Unable to deserialize headers\"\n\n\tdeserialized := make([]HTTPHeader, 0)\n\tfor _, serializedPair := range strings.Split(serializedHeaders, \";\") {\n\t\tif len(serializedPair) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tserializedHeaderParts := strings.Split(serializedPair, \":\")\n\t\tif len(serializedHeaderParts) != 2 {\n\t\t\treturn nil, errors.New(unableToDeserializeErr)\n\t\t}\n\n\t\tserializedName := serializedHeaderParts[0]\n\t\tserializedValue := serializedHeaderParts[1]\n\t\tdeserializedName := make([]byte, headerEncoding.DecodedLen(len(serializedName)))\n\t\tdeserializedValue := make([]byte, headerEncoding.DecodedLen(len(serializedValue)))\n\n\t\tif _, err := headerEncoding.Decode(deserializedName, []byte(serializedName)); err != nil {\n\t\t\treturn nil, errors.Wrap(err, unableToDeserializeErr)\n\t\t}\n\t\tif _, err := headerEncoding.Decode(deserializedValue, []byte(serializedValue)); err != nil {\n\t\t\treturn nil, errors.Wrap(err, unableToDeserializeErr)\n\t\t}\n\n\t\tdeserialized = append(deserialized, HTTPHeader{\n\t\t\tName:  string(deserializedName),\n\t\t\tValue: string(deserializedValue),\n\t\t})\n\t}\n\n\treturn deserialized, nil\n}\n"
  },
  {
    "path": "connection/header_test.go",
    "content": "package connection\n\nimport (\n\t\"net/http\"\n\t\"reflect\"\n\t\"sort\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestSerializeHeaders(t *testing.T) {\n\trequest, err := http.NewRequest(http.MethodGet, \"http://example.com\", nil)\n\trequire.NoError(t, err)\n\n\tmockHeaders := http.Header{\n\t\t\"Mock-Header-One\":        {\"Mock header one value\", \"three\"},\n\t\t\"Mock-Header-Two-Long\":   {\"Mock header two value\\nlong\"},\n\t\t\":;\":                     {\":;\", \";:\"},\n\t\t\":\":                      {\":\"},\n\t\t\";\":                      {\";\"},\n\t\t\";;\":                     {\";;\"},\n\t\t\"Empty values\":           {\"\", \"\"},\n\t\t\"\":                       {\"Empty key\"},\n\t\t\"control\\tcharacter\\b\\n\": {\"value\\n\\b\\t\"},\n\t\t\";\\v:\":                   {\":\\v;\"},\n\t}\n\n\tfor header, values := range mockHeaders {\n\t\tfor _, value := range values {\n\t\t\t// Note that Golang's http library is opinionated;\n\t\t\t// at this point every header name will be title-cased in order to comply with the HTTP RFC\n\t\t\t// This means our proxy is not completely transparent when it comes to proxying headers\n\t\t\trequest.Header.Add(header, value)\n\t\t}\n\t}\n\n\tserializedHeaders := SerializeHeaders(request.Header)\n\n\t// Sanity check: the headers serialized to something that's not an empty string\n\trequire.NotEqual(t, \"\", serializedHeaders)\n\n\t// Deserialize back, and ensure we get the same set of headers\n\tdeserializedHeaders, err := DeserializeHeaders(serializedHeaders)\n\trequire.NoError(t, err)\n\n\trequire.Len(t, deserializedHeaders, 13)\n\texpectedHeaders := headerToReqHeader(mockHeaders)\n\n\tsort.Sort(ByName(deserializedHeaders))\n\tsort.Sort(ByName(expectedHeaders))\n\n\trequire.True(\n\t\tt,\n\t\treflect.DeepEqual(expectedHeaders, deserializedHeaders),\n\t\t\"got = %#v, want = %#v\\n\", deserializedHeaders, expectedHeaders,\n\t)\n}\n\ntype ByName []HTTPHeader\n\nfunc (a ByName) Len() int      { return len(a) }\nfunc (a ByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }\nfunc (a ByName) Less(i, j int) bool {\n\tif a[i].Name == a[j].Name {\n\t\treturn a[i].Value < a[j].Value\n\t}\n\n\treturn a[i].Name < a[j].Name\n}\n\nfunc headerToReqHeader(headers http.Header) (reqHeaders []HTTPHeader) {\n\tfor name, values := range headers {\n\t\tfor _, value := range values {\n\t\t\treqHeaders = append(reqHeaders, HTTPHeader{Name: name, Value: value})\n\t\t}\n\t}\n\n\treturn reqHeaders\n}\n\nfunc TestSerializeNoHeaders(t *testing.T) {\n\trequest, err := http.NewRequest(http.MethodGet, \"http://example.com\", nil)\n\trequire.NoError(t, err)\n\n\tserializedHeaders := SerializeHeaders(request.Header)\n\tdeserializedHeaders, err := DeserializeHeaders(serializedHeaders)\n\trequire.NoError(t, err)\n\trequire.Empty(t, deserializedHeaders)\n}\n\nfunc TestDeserializeMalformed(t *testing.T) {\n\tvar err error\n\n\tmalformedData := []string{\n\t\t\"malformed data\",\n\t\t\"bW9jawo=\",                   // \"mock\"\n\t\t\"bW9jawo=:ZGF0YQo=:bW9jawo=\", // \"mock:data:mock\"\n\t\t\"::\",\n\t}\n\n\tfor _, malformedValue := range malformedData {\n\t\t_, err = DeserializeHeaders(malformedValue)\n\t\trequire.Error(t, err)\n\t}\n}\n\nfunc TestIsControlResponseHeader(t *testing.T) {\n\tcontrolResponseHeaders := []string{\n\t\t// Anything that begins with cf-int-, cf-cloudflared- or cf-proxy-\n\t\t\"cf-int-sample-header\",\n\t\t\"cf-cloudflared-sample-header\",\n\t\t\"cf-proxy-sample-header\",\n\t\t// Any http2 pseudoheader\n\t\t\":sample-pseudo-header\",\n\t}\n\n\tfor _, header := range controlResponseHeaders {\n\t\trequire.True(t, IsControlResponseHeader(header))\n\t}\n}\n\nfunc TestIsNotControlResponseHeader(t *testing.T) {\n\tnotControlResponseHeaders := []string{\n\t\t\"mock-header\",\n\t\t\"another-sample-header\",\n\t\t\"upgrade\",\n\t\t\"connection\",\n\t\t\"cf-whatever\", // On the response path, we only want to filter cf-int- and cf-cloudflared-\n\t}\n\n\tfor _, header := range notControlResponseHeaders {\n\t\trequire.False(t, IsControlResponseHeader(header))\n\t}\n}\n"
  },
  {
    "path": "connection/http2.go",
    "content": "package connection\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\tgojson \"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\t\"golang.org/x/net/http2\"\n\n\t\"github.com/cloudflare/cloudflared/client\"\n\tcfdflow \"github.com/cloudflare/cloudflared/flow\"\n\n\t\"github.com/cloudflare/cloudflared/tracing\"\n)\n\n// note: these constants are exported so we can reuse them in the edge-side code\nconst (\n\tInternalUpgradeHeader     = \"Cf-Cloudflared-Proxy-Connection-Upgrade\"\n\tInternalTCPProxySrcHeader = \"Cf-Cloudflared-Proxy-Src\"\n\tWebsocketUpgrade          = \"websocket\"\n\tControlStreamUpgrade      = \"control-stream\"\n\tConfigurationUpdate       = \"update-configuration\"\n)\n\nvar errEdgeConnectionClosed = fmt.Errorf(\"connection with edge closed\")\n\n// HTTP2Connection represents a net.Conn that uses HTTP2 frames to proxy traffic from the edge to cloudflared on the\n// origin.\ntype HTTP2Connection struct {\n\tconn         net.Conn\n\tserver       *http2.Server\n\torchestrator Orchestrator\n\tconnOptions  *client.ConnectionOptionsSnapshot\n\tobserver     *Observer\n\tconnIndex    uint8\n\n\tlog                  *zerolog.Logger\n\tactiveRequestsWG     sync.WaitGroup\n\tcontrolStreamHandler ControlStreamHandler\n\tstoppedGracefully    bool\n\tcontrolStreamErr     error // result of running control stream handler\n}\n\n// NewHTTP2Connection returns a new instance of HTTP2Connection.\nfunc NewHTTP2Connection(\n\tconn net.Conn,\n\torchestrator Orchestrator,\n\tconnOptions *client.ConnectionOptionsSnapshot,\n\tobserver *Observer,\n\tconnIndex uint8,\n\tcontrolStreamHandler ControlStreamHandler,\n\tlog *zerolog.Logger,\n) *HTTP2Connection {\n\treturn &HTTP2Connection{\n\t\tconn: conn,\n\t\tserver: &http2.Server{\n\t\t\tMaxConcurrentStreams: MaxConcurrentStreams,\n\t\t},\n\t\torchestrator:         orchestrator,\n\t\tconnOptions:          connOptions,\n\t\tobserver:             observer,\n\t\tconnIndex:            connIndex,\n\t\tcontrolStreamHandler: controlStreamHandler,\n\t\tlog:                  log,\n\t}\n}\n\n// Serve serves an HTTP2 server that the edge can talk to.\nfunc (c *HTTP2Connection) Serve(ctx context.Context) error {\n\tgo func() {\n\t\t<-ctx.Done()\n\t\tc.close()\n\t}()\n\tc.server.ServeConn(c.conn, &http2.ServeConnOpts{\n\t\tContext: ctx,\n\t\tHandler: c,\n\t})\n\n\tswitch {\n\tcase c.controlStreamHandler.IsStopped():\n\t\treturn nil\n\tcase c.controlStreamErr != nil:\n\t\treturn c.controlStreamErr\n\tdefault:\n\t\tc.observer.log.Info().Uint8(LogFieldConnIndex, c.connIndex).Msg(\"Lost connection with the edge\")\n\t\treturn errEdgeConnectionClosed\n\t}\n}\n\nfunc (c *HTTP2Connection) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tc.activeRequestsWG.Add(1)\n\tdefer c.activeRequestsWG.Done()\n\n\tconnType := determineHTTP2Type(r)\n\thandleMissingRequestParts(connType, r)\n\n\trespWriter, err := NewHTTP2RespWriter(r, w, connType, c.log)\n\tif err != nil {\n\t\tc.observer.log.Error().Msg(err.Error())\n\t\treturn\n\t}\n\n\toriginProxy, err := c.orchestrator.GetOriginProxy()\n\tif err != nil {\n\t\tc.observer.log.Error().Msg(err.Error())\n\t\treturn\n\t}\n\n\tvar requestErr error\n\tswitch connType {\n\tcase TypeControlStream:\n\t\trequestErr = c.controlStreamHandler.ServeControlStream(r.Context(), respWriter, c.connOptions.ConnectionOptions(), c.orchestrator)\n\t\tif requestErr != nil {\n\t\t\tc.controlStreamErr = requestErr\n\t\t}\n\n\tcase TypeConfiguration:\n\t\trequestErr = c.handleConfigurationUpdate(respWriter, r)\n\n\tcase TypeWebsocket, TypeHTTP:\n\t\tstripWebsocketUpgradeHeader(r)\n\t\t// Check for tracing on request\n\t\ttr := tracing.NewTracedHTTPRequest(r, c.connIndex, c.log)\n\t\tif err := originProxy.ProxyHTTP(respWriter, tr, connType == TypeWebsocket); err != nil {\n\t\t\trequestErr = fmt.Errorf(\"Failed to proxy HTTP: %w\", err)\n\t\t}\n\n\tcase TypeTCP:\n\t\thost, err := getRequestHost(r)\n\t\tif err != nil {\n\t\t\trequestErr = fmt.Errorf(`cloudflared received a warp-routing request with an empty host value: %w`, err)\n\t\t\tbreak\n\t\t}\n\n\t\trws := NewHTTPResponseReadWriterAcker(respWriter, respWriter, r)\n\t\trequestErr = originProxy.ProxyTCP(r.Context(), rws, &TCPRequest{\n\t\t\tDest:      host,\n\t\t\tCFRay:     FindCfRayHeader(r),\n\t\t\tLBProbe:   IsLBProbeRequest(r),\n\t\t\tCfTraceID: r.Header.Get(tracing.TracerContextName),\n\t\t\tConnIndex: c.connIndex,\n\t\t})\n\n\tdefault:\n\t\trequestErr = fmt.Errorf(\"Received unknown connection type: %s\", connType)\n\t}\n\n\tif requestErr != nil {\n\t\tc.log.Error().Err(requestErr).Msg(\"failed to serve incoming request\")\n\n\t\t// WriteErrorResponse will return false if status was already written. we need to abort handler.\n\t\tif !respWriter.WriteErrorResponse(requestErr) {\n\t\t\tc.log.Debug().Msg(\"Handler aborted due to failure to write error response after status already sent\")\n\t\t\tpanic(http.ErrAbortHandler)\n\t\t}\n\t}\n}\n\n// ConfigurationUpdateBody is the representation followed by the edge to send updates to cloudflared.\ntype ConfigurationUpdateBody struct {\n\tVersion int32             `json:\"version\"`\n\tConfig  gojson.RawMessage `json:\"config\"`\n}\n\nfunc (c *HTTP2Connection) handleConfigurationUpdate(respWriter *http2RespWriter, r *http.Request) error {\n\tvar configBody ConfigurationUpdateBody\n\tif err := json.NewDecoder(r.Body).Decode(&configBody); err != nil {\n\t\treturn err\n\t}\n\tresp := c.orchestrator.UpdateConfig(configBody.Version, configBody.Config)\n\tbdy, err := json.Marshal(resp)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = respWriter.Write(bdy)\n\treturn err\n}\n\nfunc (c *HTTP2Connection) close() {\n\t// Wait for all serve HTTP handlers to return\n\tc.activeRequestsWG.Wait()\n\tc.conn.Close()\n}\n\ntype http2RespWriter struct {\n\tr             io.Reader\n\tw             http.ResponseWriter\n\tflusher       http.Flusher\n\tshouldFlush   bool\n\tstatusWritten bool\n\trespHeaders   http.Header\n\thijackedMutex sync.Mutex\n\thijackedv     bool\n\tlog           *zerolog.Logger\n}\n\nfunc NewHTTP2RespWriter(r *http.Request, w http.ResponseWriter, connType Type, log *zerolog.Logger) (*http2RespWriter, error) {\n\tflusher, isFlusher := w.(http.Flusher)\n\tif !isFlusher {\n\t\trespWriter := &http2RespWriter{\n\t\t\tr:   r.Body,\n\t\t\tw:   w,\n\t\t\tlog: log,\n\t\t}\n\t\terr := fmt.Errorf(\"%T doesn't implement http.Flusher\", w)\n\t\trespWriter.WriteErrorResponse(err)\n\t\treturn nil, err\n\t}\n\n\treturn &http2RespWriter{\n\t\tr:           r.Body,\n\t\tw:           w,\n\t\tflusher:     flusher,\n\t\tshouldFlush: connType.shouldFlush(),\n\t\trespHeaders: make(http.Header),\n\t\tlog:         log,\n\t}, nil\n}\n\nfunc (rp *http2RespWriter) AddTrailer(trailerName, trailerValue string) {\n\tif !rp.statusWritten {\n\t\trp.log.Warn().Msg(\"Tried to add Trailer to response before status written. Ignoring...\")\n\t\treturn\n\t}\n\n\trp.w.Header().Add(http2.TrailerPrefix+trailerName, trailerValue)\n}\n\nfunc (rp *http2RespWriter) WriteRespHeaders(status int, header http.Header) error {\n\tif rp.hijacked() {\n\t\trp.log.Warn().Msg(\"WriteRespHeaders after hijack\")\n\t\treturn nil\n\t}\n\tdest := rp.w.Header()\n\tuserHeaders := make(http.Header, len(header))\n\tfor name, values := range header {\n\t\t// lowercase headers for simplicity check\n\t\th2name := strings.ToLower(name)\n\n\t\tif h2name == \"content-length\" {\n\t\t\t// This header has meaning in HTTP/2 and will be used by the edge,\n\t\t\t// so it should be sent *also* as an HTTP/2 response header.\n\t\t\tdest[name] = values\n\t\t}\n\n\t\tif h2name == tracing.IntCloudflaredTracingHeader {\n\t\t\t// Add cf-int-cloudflared-tracing header outside of serialized userHeaders\n\t\t\tdest[tracing.CanonicalCloudflaredTracingHeader] = values\n\t\t\tcontinue\n\t\t}\n\n\t\tif !IsControlResponseHeader(h2name) || IsWebsocketClientHeader(h2name) {\n\t\t\t// User headers, on the other hand, must all be serialized so that\n\t\t\t// HTTP/2 header validation won't be applied to HTTP/1 header values\n\t\t\tuserHeaders[name] = values\n\t\t}\n\t}\n\n\t// Perform user header serialization and set them in the single header\n\tdest.Set(CanonicalResponseUserHeaders, SerializeHeaders(userHeaders))\n\n\trp.setResponseMetaHeader(responseMetaHeaderOrigin)\n\t// HTTP2 removes support for 101 Switching Protocols https://tools.ietf.org/html/rfc7540#section-8.1.1\n\tif status == http.StatusSwitchingProtocols {\n\t\tstatus = http.StatusOK\n\t}\n\trp.w.WriteHeader(status)\n\tif shouldFlush(header) {\n\t\trp.shouldFlush = true\n\t}\n\tif rp.shouldFlush {\n\t\trp.flusher.Flush()\n\t}\n\n\trp.statusWritten = true\n\treturn nil\n}\n\nfunc (rp *http2RespWriter) Header() http.Header {\n\treturn rp.respHeaders\n}\n\nfunc (rp *http2RespWriter) Flush() {\n\trp.flusher.Flush()\n}\n\nfunc (rp *http2RespWriter) WriteHeader(status int) {\n\tif rp.hijacked() {\n\t\trp.log.Warn().Msg(\"WriteHeader after hijack\")\n\t\treturn\n\t}\n\t_ = rp.WriteRespHeaders(status, rp.respHeaders)\n}\n\nfunc (rp *http2RespWriter) hijacked() bool {\n\trp.hijackedMutex.Lock()\n\tdefer rp.hijackedMutex.Unlock()\n\treturn rp.hijackedv\n}\n\nfunc (rp *http2RespWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {\n\tif !rp.statusWritten {\n\t\treturn nil, nil, fmt.Errorf(\"status not yet written before attempting to hijack connection\")\n\t}\n\t// Make sure to flush anything left in the buffer before hijacking\n\tif rp.shouldFlush {\n\t\trp.flusher.Flush()\n\t}\n\trp.hijackedMutex.Lock()\n\tdefer rp.hijackedMutex.Unlock()\n\tif rp.hijackedv {\n\t\treturn nil, nil, http.ErrHijacked\n\t}\n\trp.hijackedv = true\n\tconn := &localProxyConnection{rp}\n\t// We return the http2RespWriter here because we want to make sure that we flush after every write\n\t// otherwise the HTTP2 write buffer waits a few seconds before sending.\n\treadWriter := bufio.NewReadWriter(\n\t\tbufio.NewReader(rp),\n\t\tbufio.NewWriter(rp),\n\t)\n\treturn conn, readWriter, nil\n}\n\nfunc (rp *http2RespWriter) WriteErrorResponse(err error) bool {\n\tif rp.statusWritten {\n\t\treturn false\n\t}\n\n\tif errors.Is(err, cfdflow.ErrTooManyActiveFlows) {\n\t\trp.setResponseMetaHeader(responseMetaHeaderCfdFlowRateLimited)\n\t} else {\n\t\trp.setResponseMetaHeader(responseMetaHeaderCfd)\n\t}\n\trp.w.WriteHeader(http.StatusBadGateway)\n\trp.statusWritten = true\n\n\treturn true\n}\n\nfunc (rp *http2RespWriter) setResponseMetaHeader(value string) {\n\trp.w.Header().Set(CanonicalResponseMetaHeader, value)\n}\n\nfunc (rp *http2RespWriter) Read(p []byte) (n int, err error) {\n\treturn rp.r.Read(p)\n}\n\nfunc (rp *http2RespWriter) Write(p []byte) (n int, err error) {\n\tdefer func() {\n\t\t// Implementer of OriginClient should make sure it doesn't write to the connection after Proxy returns\n\t\t// Register a recover routine just in case.\n\t\tif r := recover(); r != nil {\n\t\t\trp.log.Debug().Msgf(\"Recover from http2 response writer panic, error %s\", debug.Stack())\n\t\t}\n\t}()\n\tn, err = rp.w.Write(p)\n\tif err == nil && rp.shouldFlush {\n\t\trp.flusher.Flush()\n\t}\n\treturn n, err\n}\n\nfunc (rp *http2RespWriter) Close() error {\n\treturn nil\n}\n\nfunc determineHTTP2Type(r *http.Request) Type {\n\tswitch {\n\tcase isConfigurationUpdate(r):\n\t\treturn TypeConfiguration\n\tcase isWebsocketUpgrade(r):\n\t\treturn TypeWebsocket\n\tcase IsTCPStream(r):\n\t\treturn TypeTCP\n\tcase isControlStreamUpgrade(r):\n\t\treturn TypeControlStream\n\tdefault:\n\t\treturn TypeHTTP\n\t}\n}\n\nfunc handleMissingRequestParts(connType Type, r *http.Request) {\n\tif connType == TypeHTTP {\n\t\t// http library has no guarantees that we receive a filled URL. If not, then we fill it, as we reuse the request\n\t\t// for proxying. For proxying they should not matter since we control the dialer on every egress proxied.\n\t\tif len(r.URL.Scheme) == 0 {\n\t\t\tr.URL.Scheme = \"http\"\n\t\t}\n\t\tif len(r.URL.Host) == 0 {\n\t\t\tr.URL.Host = \"localhost:8080\"\n\t\t}\n\t}\n}\n\nfunc isControlStreamUpgrade(r *http.Request) bool {\n\treturn r.Header.Get(InternalUpgradeHeader) == ControlStreamUpgrade\n}\n\nfunc isWebsocketUpgrade(r *http.Request) bool {\n\treturn r.Header.Get(InternalUpgradeHeader) == WebsocketUpgrade\n}\n\nfunc isConfigurationUpdate(r *http.Request) bool {\n\treturn r.Header.Get(InternalUpgradeHeader) == ConfigurationUpdate\n}\n\n// IsTCPStream discerns if the connection request needs a tcp stream proxy.\nfunc IsTCPStream(r *http.Request) bool {\n\treturn r.Header.Get(InternalTCPProxySrcHeader) != \"\"\n}\n\nfunc stripWebsocketUpgradeHeader(r *http.Request) {\n\tr.Header.Del(InternalUpgradeHeader)\n}\n\n// getRequestHost returns the host of the http.Request.\nfunc getRequestHost(r *http.Request) (string, error) {\n\tif r.Host != \"\" {\n\t\treturn r.Host, nil\n\t}\n\tif r.URL != nil {\n\t\treturn r.URL.Host, nil\n\t}\n\treturn \"\", errors.New(\"host not set in incoming request\")\n}\n"
  },
  {
    "path": "connection/http2_test.go",
    "content": "package connection\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/gobwas/ws/wsutil\"\n\t\"github.com/google/uuid\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"golang.org/x/net/http2\"\n\n\t\"github.com/cloudflare/cloudflared/client\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\nvar testTransport = http2.Transport{}\n\nfunc newTestHTTP2Connection() (*HTTP2Connection, net.Conn) {\n\tedgeConn, cfdConn := net.Pipe()\n\tconnIndex := uint8(0)\n\tlog := zerolog.Nop()\n\tobs := NewObserver(&log, &log)\n\tcontrolStream := NewControlStream(\n\t\tobs,\n\t\tmockConnectedFuse{},\n\t\t&TunnelProperties{},\n\t\tconnIndex,\n\t\tnil,\n\t\tnil,\n\t\t1*time.Second,\n\t\tnil,\n\t\t1*time.Second,\n\t\tHTTP2,\n\t)\n\treturn NewHTTP2Connection(\n\t\tcfdConn,\n\t\t// OriginProxy is set in testConfigManager\n\t\ttestOrchestrator,\n\t\t&client.ConnectionOptionsSnapshot{},\n\t\tobs,\n\t\tconnIndex,\n\t\tcontrolStream,\n\t\t&log,\n\t), edgeConn\n}\n\nfunc TestHTTP2ConfigurationSet(t *testing.T) {\n\thttp2Conn, edgeConn := newTestHTTP2Connection()\n\n\tctx, cancel := context.WithCancel(t.Context())\n\tvar wg sync.WaitGroup\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\t_ = http2Conn.Serve(ctx)\n\t}()\n\n\tedgeHTTP2Conn, err := testTransport.NewClientConn(edgeConn)\n\trequire.NoError(t, err)\n\n\treqBody := []byte(`{\n\"version\": 2,\n\"config\": {\"warp-routing\": {\"enabled\": true},  \"originRequest\" : {\"connectTimeout\": 10}, \"ingress\" : [ {\"hostname\": \"test\", \"service\": \"https://localhost:8000\" } , {\"service\": \"http_status:404\"} ]}}\n`)\n\treader := bytes.NewReader(reqBody)\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPut, \"http://localhost:8080/ok\", reader)\n\trequire.NoError(t, err)\n\treq.Header.Set(InternalUpgradeHeader, ConfigurationUpdate)\n\n\tresp, err := edgeHTTP2Conn.RoundTrip(req)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusOK, resp.StatusCode)\n\tbdy, err := io.ReadAll(resp.Body)\n\tdefer resp.Body.Close()\n\trequire.NoError(t, err)\n\tassert.Equal(t, `{\"lastAppliedVersion\":2,\"err\":null}`, string(bdy))\n\tcancel()\n\twg.Wait()\n}\n\nfunc TestServeHTTP(t *testing.T) {\n\ttests := []testRequest{\n\t\t{\n\t\t\tname:           \"ok\",\n\t\t\tendpoint:       \"ok\",\n\t\t\texpectedStatus: http.StatusOK,\n\t\t\texpectedBody:   []byte(http.StatusText(http.StatusOK)),\n\t\t},\n\t\t{\n\t\t\tname:           \"large_file\",\n\t\t\tendpoint:       \"large_file\",\n\t\t\texpectedStatus: http.StatusOK,\n\t\t\texpectedBody:   testLargeResp,\n\t\t},\n\t\t{\n\t\t\tname:           \"Bad request\",\n\t\t\tendpoint:       \"400\",\n\t\t\texpectedStatus: http.StatusBadRequest,\n\t\t\texpectedBody:   []byte(http.StatusText(http.StatusBadRequest)),\n\t\t},\n\t\t{\n\t\t\tname:           \"Internal server error\",\n\t\t\tendpoint:       \"500\",\n\t\t\texpectedStatus: http.StatusInternalServerError,\n\t\t\texpectedBody:   []byte(http.StatusText(http.StatusInternalServerError)),\n\t\t},\n\t\t{\n\t\t\tname:           \"Proxy error\",\n\t\t\tendpoint:       \"error\",\n\t\t\texpectedStatus: http.StatusBadGateway,\n\t\t\texpectedBody:   nil,\n\t\t\tisProxyError:   true,\n\t\t},\n\t}\n\n\thttp2Conn, edgeConn := newTestHTTP2Connection()\n\n\tctx, cancel := context.WithCancel(t.Context())\n\tvar wg sync.WaitGroup\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\t_ = http2Conn.Serve(ctx)\n\t}()\n\n\tedgeHTTP2Conn, err := testTransport.NewClientConn(edgeConn)\n\trequire.NoError(t, err)\n\n\tfor _, test := range tests {\n\t\tendpoint := fmt.Sprintf(\"http://localhost:8080/%s\", test.endpoint)\n\t\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)\n\t\trequire.NoError(t, err)\n\n\t\tresp, err := edgeHTTP2Conn.RoundTrip(req)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, test.expectedStatus, resp.StatusCode)\n\t\tif test.expectedBody != nil {\n\t\t\trespBody, err := io.ReadAll(resp.Body)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, test.expectedBody, respBody)\n\t\t}\n\t\t_ = resp.Body.Close()\n\t\tif test.isProxyError {\n\t\t\trequire.Equal(t, responseMetaHeaderCfd, resp.Header.Get(ResponseMetaHeader))\n\t\t} else {\n\t\t\trequire.Equal(t, responseMetaHeaderOrigin, resp.Header.Get(ResponseMetaHeader))\n\t\t}\n\t}\n\tcancel()\n\twg.Wait()\n}\n\ntype mockNamedTunnelRPCClient struct {\n\tshouldFail   error\n\tregistered   chan struct{}\n\tunregistered chan struct{}\n}\n\nfunc (mc mockNamedTunnelRPCClient) SendLocalConfiguration(c context.Context, config []byte) error {\n\treturn nil\n}\n\nfunc (mc mockNamedTunnelRPCClient) RegisterConnection(\n\tctx context.Context,\n\tauth pogs.TunnelAuth,\n\ttunnelID uuid.UUID,\n\toptions *pogs.ConnectionOptions,\n\tconnIndex uint8,\n\tedgeAddress net.IP,\n) (*pogs.ConnectionDetails, error) {\n\tif mc.shouldFail != nil {\n\t\treturn nil, mc.shouldFail\n\t}\n\tclose(mc.registered)\n\treturn &pogs.ConnectionDetails{\n\t\tLocation:                \"LIS\",\n\t\tUUID:                    uuid.New(),\n\t\tTunnelIsRemotelyManaged: false,\n\t}, nil\n}\n\nfunc (mc mockNamedTunnelRPCClient) GracefulShutdown(ctx context.Context, gracePeriod time.Duration) error {\n\tclose(mc.unregistered)\n\treturn nil\n}\n\nfunc (mockNamedTunnelRPCClient) Close() {}\n\ntype mockRPCClientFactory struct {\n\tshouldFail   error\n\tregistered   chan struct{}\n\tunregistered chan struct{}\n}\n\nfunc (mf *mockRPCClientFactory) newMockRPCClient(context.Context, io.ReadWriteCloser, time.Duration) tunnelrpc.RegistrationClient {\n\treturn &mockNamedTunnelRPCClient{\n\t\tshouldFail:   mf.shouldFail,\n\t\tregistered:   mf.registered,\n\t\tunregistered: mf.unregistered,\n\t}\n}\n\ntype wsRespWriter struct {\n\t*httptest.ResponseRecorder\n\treadPipe  *io.PipeReader\n\twritePipe *io.PipeWriter\n\tclosed    bool\n\tpanicked  bool\n}\n\nfunc newWSRespWriter() *wsRespWriter {\n\treadPipe, writePipe := io.Pipe()\n\treturn &wsRespWriter{\n\t\thttptest.NewRecorder(),\n\t\treadPipe,\n\t\twritePipe,\n\t\tfalse,\n\t\tfalse,\n\t}\n}\n\ntype nowriter struct {\n\tio.Reader\n}\n\nfunc (nowriter) Write(_ []byte) (int, error) {\n\treturn 0, fmt.Errorf(\"writer not implemented\")\n}\n\nfunc (w *wsRespWriter) RespBody() io.ReadWriter {\n\treturn nowriter{w.readPipe}\n}\n\nfunc (w *wsRespWriter) Write(data []byte) (n int, err error) {\n\tif w.closed {\n\t\tw.panicked = true\n\t\treturn 0, errors.New(\"wsRespWriter panicked\")\n\t}\n\treturn w.writePipe.Write(data)\n}\n\nfunc (w *wsRespWriter) close() {\n\tw.closed = true\n}\n\nfunc TestServeWS(t *testing.T) {\n\thttp2Conn, _ := newTestHTTP2Connection()\n\n\tctx, cancel := context.WithCancel(t.Context())\n\n\trespWriter := newWSRespWriter()\n\treadPipe, writePipe := io.Pipe()\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, \"http://localhost:8080/ws/echo\", readPipe)\n\trequire.NoError(t, err)\n\treq.Header.Set(InternalUpgradeHeader, WebsocketUpgrade)\n\n\tserveDone := make(chan struct{})\n\tgo func() {\n\t\tdefer close(serveDone)\n\t\thttp2Conn.ServeHTTP(respWriter, req)\n\t\trespWriter.close()\n\t}()\n\n\tdata := []byte(\"test websocket\")\n\terr = wsutil.WriteClientBinary(writePipe, data)\n\trequire.NoError(t, err)\n\n\trespBody, err := wsutil.ReadServerBinary(respWriter.RespBody())\n\trequire.NoError(t, err)\n\trequire.Equal(t, data, respBody, \"expect %s, got %s\", string(data), string(respBody))\n\n\tcancel()\n\tresp := respWriter.Result()\n\tdefer resp.Body.Close()\n\t// http2RespWriter should rewrite status 101 to 200\n\trequire.Equal(t, http.StatusOK, resp.StatusCode)\n\trequire.Equal(t, responseMetaHeaderOrigin, resp.Header.Get(ResponseMetaHeader))\n\n\t<-serveDone\n\trequire.False(t, respWriter.panicked)\n}\n\n// TestNoWriteAfterServeHTTPReturns is a regression test of https://jira.cfdata.org/browse/TUN-5184\n// to make sure we don't write to the ResponseWriter after the ServeHTTP method returns\nfunc TestNoWriteAfterServeHTTPReturns(t *testing.T) {\n\tcfdHTTP2Conn, edgeTCPConn := newTestHTTP2Connection()\n\n\tctx, cancel := context.WithCancel(t.Context())\n\tvar wg sync.WaitGroup\n\n\tserverDone := make(chan struct{})\n\tgo func() {\n\t\tdefer close(serverDone)\n\t\t_ = cfdHTTP2Conn.Serve(ctx)\n\t}()\n\n\tedgeTransport := http2.Transport{}\n\tedgeHTTP2Conn, err := edgeTransport.NewClientConn(edgeTCPConn)\n\trequire.NoError(t, err)\n\tmessage := []byte(t.Name())\n\n\tfor i := 0; i < 100; i++ {\n\t\twg.Add(1)\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\treadPipe, writePipe := io.Pipe()\n\t\t\treqCtx, reqCancel := context.WithCancel(ctx)\n\t\t\treq, err := http.NewRequestWithContext(reqCtx, http.MethodGet, \"http://localhost:8080/ws/flaky\", readPipe)\n\t\t\tassert.NoError(t, err)\n\n\t\t\treq.Header.Set(InternalUpgradeHeader, WebsocketUpgrade)\n\n\t\t\tresp, err := edgeHTTP2Conn.RoundTrip(req)\n\t\t\tassert.NoError(t, err)\n\t\t\t_ = resp.Body.Close()\n\n\t\t\t// http2RespWriter should rewrite status 101 to 200\n\t\t\tassert.Equal(t, http.StatusOK, resp.StatusCode)\n\n\t\t\twg.Add(1)\n\t\t\tgo func() {\n\t\t\t\tdefer wg.Done()\n\t\t\t\tfor {\n\t\t\t\t\tselect {\n\t\t\t\t\tcase <-reqCtx.Done():\n\t\t\t\t\t\treturn\n\t\t\t\t\tdefault:\n\t\t\t\t\t}\n\t\t\t\t\t_ = wsutil.WriteClientBinary(writePipe, message)\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\ttime.Sleep(time.Millisecond * 100)\n\t\t\treqCancel()\n\t\t}()\n\t}\n\n\twg.Wait()\n\tcancel()\n\t<-serverDone\n}\n\nfunc TestServeControlStream(t *testing.T) {\n\thttp2Conn, edgeConn := newTestHTTP2Connection()\n\n\trpcClientFactory := mockRPCClientFactory{\n\t\tregistered:   make(chan struct{}),\n\t\tunregistered: make(chan struct{}),\n\t}\n\n\tobs := NewObserver(&log, &log)\n\tcontrolStream := NewControlStream(\n\t\tobs,\n\t\tmockConnectedFuse{},\n\t\t&TunnelProperties{},\n\t\t1,\n\t\tnil,\n\t\trpcClientFactory.newMockRPCClient,\n\t\t1*time.Second,\n\t\tnil,\n\t\t1*time.Second,\n\t\tHTTP2,\n\t)\n\thttp2Conn.controlStreamHandler = controlStream\n\n\tctx, cancel := context.WithCancel(t.Context())\n\tvar wg sync.WaitGroup\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\t_ = http2Conn.Serve(ctx)\n\t}()\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, \"http://localhost:8080/\", nil)\n\trequire.NoError(t, err)\n\treq.Header.Set(InternalUpgradeHeader, ControlStreamUpgrade)\n\n\tedgeHTTP2Conn, err := testTransport.NewClientConn(edgeConn)\n\trequire.NoError(t, err)\n\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\t// nolint: bodyclose\n\t\t_, _ = edgeHTTP2Conn.RoundTrip(req)\n\t}()\n\n\t<-rpcClientFactory.registered\n\tcancel()\n\t<-rpcClientFactory.unregistered\n\tassert.False(t, http2Conn.stoppedGracefully)\n\n\twg.Wait()\n}\n\nfunc TestFailRegistration(t *testing.T) {\n\thttp2Conn, edgeConn := newTestHTTP2Connection()\n\n\trpcClientFactory := mockRPCClientFactory{\n\t\tshouldFail:   errDuplicationConnection,\n\t\tregistered:   make(chan struct{}),\n\t\tunregistered: make(chan struct{}),\n\t}\n\n\tobs := NewObserver(&log, &log)\n\tcontrolStream := NewControlStream(\n\t\tobs,\n\t\tmockConnectedFuse{},\n\t\t&TunnelProperties{},\n\t\thttp2Conn.connIndex,\n\t\tnil,\n\t\trpcClientFactory.newMockRPCClient,\n\t\t1*time.Second,\n\t\tnil,\n\t\t1*time.Second,\n\t\tHTTP2,\n\t)\n\thttp2Conn.controlStreamHandler = controlStream\n\n\tctx, cancel := context.WithCancel(t.Context())\n\tvar wg sync.WaitGroup\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\t_ = http2Conn.Serve(ctx)\n\t}()\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, \"http://localhost:8080/\", nil)\n\trequire.NoError(t, err)\n\treq.Header.Set(InternalUpgradeHeader, ControlStreamUpgrade)\n\n\tedgeHTTP2Conn, err := testTransport.NewClientConn(edgeConn)\n\trequire.NoError(t, err)\n\tresp, err := edgeHTTP2Conn.RoundTrip(req)\n\trequire.NoError(t, err)\n\tdefer resp.Body.Close()\n\trequire.Equal(t, http.StatusBadGateway, resp.StatusCode)\n\n\trequire.Error(t, http2Conn.controlStreamErr)\n\tcancel()\n\twg.Wait()\n}\n\nfunc TestGracefulShutdownHTTP2(t *testing.T) {\n\thttp2Conn, edgeConn := newTestHTTP2Connection()\n\n\trpcClientFactory := mockRPCClientFactory{\n\t\tregistered:   make(chan struct{}),\n\t\tunregistered: make(chan struct{}),\n\t}\n\tevents := &eventCollectorSink{}\n\n\tshutdownC := make(chan struct{})\n\tobs := NewObserver(&log, &log)\n\tobs.RegisterSink(events)\n\tcontrolStream := NewControlStream(\n\t\tobs,\n\t\tmockConnectedFuse{},\n\t\t&TunnelProperties{},\n\t\thttp2Conn.connIndex,\n\t\tnil,\n\t\trpcClientFactory.newMockRPCClient,\n\t\t1*time.Second,\n\t\tshutdownC,\n\t\t1*time.Second,\n\t\tHTTP2,\n\t)\n\n\thttp2Conn.controlStreamHandler = controlStream\n\n\tctx, cancel := context.WithCancel(t.Context())\n\tvar wg sync.WaitGroup\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\t_ = http2Conn.Serve(ctx)\n\t}()\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, \"http://localhost:8080/\", nil)\n\trequire.NoError(t, err)\n\treq.Header.Set(InternalUpgradeHeader, ControlStreamUpgrade)\n\n\tedgeHTTP2Conn, err := testTransport.NewClientConn(edgeConn)\n\trequire.NoError(t, err)\n\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\t// nolint: bodyclose\n\t\t_, _ = edgeHTTP2Conn.RoundTrip(req)\n\t}()\n\n\tselect {\n\tcase <-rpcClientFactory.registered:\n\t\tbreak // ok\n\tcase <-time.Tick(time.Second):\n\t\tt.Fatal(\"timeout out waiting for registration\")\n\t}\n\n\t// signal graceful shutdown\n\tclose(shutdownC)\n\n\tselect {\n\tcase <-rpcClientFactory.unregistered:\n\t\tbreak // ok\n\tcase <-time.Tick(time.Second):\n\t\tt.Fatal(\"timeout out waiting for unregistered signal\")\n\t}\n\tassert.True(t, controlStream.IsStopped())\n\n\tcancel()\n\twg.Wait()\n\n\tevents.assertSawEvent(t, Event{\n\t\tIndex:     http2Conn.connIndex,\n\t\tEventType: Unregistering,\n\t})\n}\n\nfunc TestServeTCP_RateLimited(t *testing.T) {\n\tctx, cancel := context.WithCancel(t.Context())\n\thttp2Conn, edgeConn := newTestHTTP2Connection()\n\n\tvar wg sync.WaitGroup\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\t_ = http2Conn.Serve(ctx)\n\t}()\n\n\tedgeHTTP2Conn, err := testTransport.NewClientConn(edgeConn)\n\trequire.NoError(t, err)\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, \"http://localhost:8080\", nil)\n\trequire.NoError(t, err)\n\treq.Header.Set(InternalTCPProxySrcHeader, \"tcp\")\n\treq.Header.Set(tracing.TracerContextName, \"flow-rate-limited\")\n\n\tresp, err := edgeHTTP2Conn.RoundTrip(req)\n\trequire.NoError(t, err)\n\tdefer resp.Body.Close()\n\n\trequire.Equal(t, http.StatusBadGateway, resp.StatusCode)\n\trequire.Equal(t, responseMetaHeaderCfdFlowRateLimited, resp.Header.Get(ResponseMetaHeader))\n\n\tcancel()\n\twg.Wait()\n}\n\nfunc benchmarkServeHTTP(b *testing.B, test testRequest) {\n\thttp2Conn, edgeConn := newTestHTTP2Connection()\n\n\tctx, cancel := context.WithCancel(b.Context())\n\tvar wg sync.WaitGroup\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\t_ = http2Conn.Serve(ctx)\n\t}()\n\n\tendpoint := fmt.Sprintf(\"http://localhost:8080/%s\", test.endpoint)\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)\n\trequire.NoError(b, err)\n\n\tedgeHTTP2Conn, err := testTransport.NewClientConn(edgeConn)\n\trequire.NoError(b, err)\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tb.StartTimer()\n\t\tresp, err := edgeHTTP2Conn.RoundTrip(req)\n\t\tb.StopTimer()\n\t\trequire.NoError(b, err)\n\t\trequire.Equal(b, test.expectedStatus, resp.StatusCode)\n\t\tif test.expectedBody != nil {\n\t\t\trespBody, err := io.ReadAll(resp.Body)\n\t\t\trequire.NoError(b, err)\n\t\t\trequire.Equal(b, test.expectedBody, respBody)\n\t\t}\n\t\tresp.Body.Close()\n\t}\n\n\tcancel()\n\twg.Wait()\n}\n\nfunc BenchmarkServeHTTPSimple(b *testing.B) {\n\ttest := testRequest{\n\t\tname:           \"ok\",\n\t\tendpoint:       \"ok\",\n\t\texpectedStatus: http.StatusOK,\n\t\texpectedBody:   []byte(http.StatusText(http.StatusOK)),\n\t}\n\n\tbenchmarkServeHTTP(b, test)\n}\n\nfunc BenchmarkServeHTTPLargeFile(b *testing.B) {\n\ttest := testRequest{\n\t\tname:           \"large_file\",\n\t\tendpoint:       \"large_file\",\n\t\texpectedStatus: http.StatusOK,\n\t\texpectedBody:   testLargeResp,\n\t}\n\n\tbenchmarkServeHTTP(b, test)\n}\n"
  },
  {
    "path": "connection/json.go",
    "content": "package connection\n\nimport (\n\tjsoniter \"github.com/json-iterator/go\"\n)\n\nvar json = jsoniter.ConfigFastest\n"
  },
  {
    "path": "connection/metrics.go",
    "content": "package connection\n\nimport (\n\t\"sync\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n)\n\nconst (\n\tMetricsNamespace = \"cloudflared\"\n\tTunnelSubsystem  = \"tunnel\"\n\tmuxerSubsystem   = \"muxer\"\n\tconfigSubsystem  = \"config\"\n)\n\ntype localConfigMetrics struct {\n\tpushes       prometheus.Counter\n\tpushesErrors prometheus.Counter\n}\n\ntype tunnelMetrics struct {\n\tserverLocations *prometheus.GaugeVec\n\t// locationLock is a mutex for oldServerLocations\n\tlocationLock sync.Mutex\n\t// oldServerLocations stores the last server the tunnel was connected to\n\toldServerLocations map[string]string\n\n\tregSuccess *prometheus.CounterVec\n\tregFail    *prometheus.CounterVec\n\trpcFail    *prometheus.CounterVec\n\n\ttunnelsHA           tunnelsForHA\n\tuserHostnamesCounts *prometheus.CounterVec\n\n\tlocalConfigMetrics *localConfigMetrics\n}\n\nfunc newLocalConfigMetrics() *localConfigMetrics {\n\n\tpushesMetric := prometheus.NewCounter(\n\t\tprometheus.CounterOpts{\n\t\t\tNamespace: MetricsNamespace,\n\t\t\tSubsystem: configSubsystem,\n\t\t\tName:      \"local_config_pushes\",\n\t\t\tHelp:      \"Number of local configuration pushes to the edge\",\n\t\t},\n\t)\n\n\tpushesErrorsMetric := prometheus.NewCounter(\n\t\tprometheus.CounterOpts{\n\t\t\tNamespace: MetricsNamespace,\n\t\t\tSubsystem: configSubsystem,\n\t\t\tName:      \"local_config_pushes_errors\",\n\t\t\tHelp:      \"Number of errors occurred during local configuration pushes\",\n\t\t},\n\t)\n\n\tprometheus.MustRegister(\n\t\tpushesMetric,\n\t\tpushesErrorsMetric,\n\t)\n\n\treturn &localConfigMetrics{\n\t\tpushes:       pushesMetric,\n\t\tpushesErrors: pushesErrorsMetric,\n\t}\n}\n\n// Metrics that can be collected without asking the edge\nfunc initTunnelMetrics() *tunnelMetrics {\n\tmaxConcurrentRequestsPerTunnel := prometheus.NewGaugeVec(\n\t\tprometheus.GaugeOpts{\n\t\t\tNamespace: MetricsNamespace,\n\t\t\tSubsystem: TunnelSubsystem,\n\t\t\tName:      \"max_concurrent_requests_per_tunnel\",\n\t\t\tHelp:      \"Largest number of concurrent requests proxied through each tunnel so far\",\n\t\t},\n\t\t[]string{\"connection_id\"},\n\t)\n\tprometheus.MustRegister(maxConcurrentRequestsPerTunnel)\n\n\tserverLocations := prometheus.NewGaugeVec(\n\t\tprometheus.GaugeOpts{\n\t\t\tNamespace: MetricsNamespace,\n\t\t\tSubsystem: TunnelSubsystem,\n\t\t\tName:      \"server_locations\",\n\t\t\tHelp:      \"Where each tunnel is connected to. 1 means current location, 0 means previous locations.\",\n\t\t},\n\t\t[]string{\"connection_id\", \"edge_location\"},\n\t)\n\tprometheus.MustRegister(serverLocations)\n\n\trpcFail := prometheus.NewCounterVec(\n\t\tprometheus.CounterOpts{\n\t\t\tNamespace: MetricsNamespace,\n\t\t\tSubsystem: TunnelSubsystem,\n\t\t\tName:      \"tunnel_rpc_fail\",\n\t\t\tHelp:      \"Count of RPC connection errors by type\",\n\t\t},\n\t\t[]string{\"error\", \"rpcName\"},\n\t)\n\tprometheus.MustRegister(rpcFail)\n\n\tregisterFail := prometheus.NewCounterVec(\n\t\tprometheus.CounterOpts{\n\t\t\tNamespace: MetricsNamespace,\n\t\t\tSubsystem: TunnelSubsystem,\n\t\t\tName:      \"tunnel_register_fail\",\n\t\t\tHelp:      \"Count of tunnel registration errors by type\",\n\t\t},\n\t\t[]string{\"error\", \"rpcName\"},\n\t)\n\tprometheus.MustRegister(registerFail)\n\n\tuserHostnamesCounts := prometheus.NewCounterVec(\n\t\tprometheus.CounterOpts{\n\t\t\tNamespace: MetricsNamespace,\n\t\t\tSubsystem: TunnelSubsystem,\n\t\t\tName:      \"user_hostnames_counts\",\n\t\t\tHelp:      \"Which user hostnames cloudflared is serving\",\n\t\t},\n\t\t[]string{\"userHostname\"},\n\t)\n\tprometheus.MustRegister(userHostnamesCounts)\n\n\tregisterSuccess := prometheus.NewCounterVec(\n\t\tprometheus.CounterOpts{\n\t\t\tNamespace: MetricsNamespace,\n\t\t\tSubsystem: TunnelSubsystem,\n\t\t\tName:      \"tunnel_register_success\",\n\t\t\tHelp:      \"Count of successful tunnel registrations\",\n\t\t},\n\t\t[]string{\"rpcName\"},\n\t)\n\tprometheus.MustRegister(registerSuccess)\n\n\treturn &tunnelMetrics{\n\t\tserverLocations:     serverLocations,\n\t\toldServerLocations:  make(map[string]string),\n\t\ttunnelsHA:           newTunnelsForHA(),\n\t\tregSuccess:          registerSuccess,\n\t\tregFail:             registerFail,\n\t\trpcFail:             rpcFail,\n\t\tuserHostnamesCounts: userHostnamesCounts,\n\t\tlocalConfigMetrics:  newLocalConfigMetrics(),\n\t}\n}\n\nfunc (t *tunnelMetrics) registerServerLocation(connectionID, loc string) {\n\tt.locationLock.Lock()\n\tdefer t.locationLock.Unlock()\n\tif oldLoc, ok := t.oldServerLocations[connectionID]; ok && oldLoc == loc {\n\t\treturn\n\t} else if ok {\n\t\tt.serverLocations.WithLabelValues(connectionID, oldLoc).Dec()\n\t}\n\tt.serverLocations.WithLabelValues(connectionID, loc).Inc()\n\tt.oldServerLocations[connectionID] = loc\n}\n\nvar tunnelMetricsInternal struct {\n\tsync.Once\n\tmetrics *tunnelMetrics\n}\n\nfunc newTunnelMetrics() *tunnelMetrics {\n\ttunnelMetricsInternal.Do(func() {\n\t\ttunnelMetricsInternal.metrics = initTunnelMetrics()\n\t})\n\treturn tunnelMetricsInternal.metrics\n}\n"
  },
  {
    "path": "connection/observer.go",
    "content": "package connection\n\nimport (\n\t\"net\"\n\t\"strings\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/management\"\n)\n\nconst (\n\tLogFieldConnectionID      = \"connection\"\n\tLogFieldLocation          = \"location\"\n\tLogFieldIPAddress         = \"ip\"\n\tLogFieldProtocol          = \"protocol\"\n\tobserverChannelBufferSize = 16\n)\n\ntype Observer struct {\n\tlog             *zerolog.Logger\n\tlogTransport    *zerolog.Logger\n\tmetrics         *tunnelMetrics\n\ttunnelEventChan chan Event\n\taddSinkChan     chan EventSink\n}\n\ntype EventSink interface {\n\tOnTunnelEvent(event Event)\n}\n\nfunc NewObserver(log, logTransport *zerolog.Logger) *Observer {\n\to := &Observer{\n\t\tlog:             log,\n\t\tlogTransport:    logTransport,\n\t\tmetrics:         newTunnelMetrics(),\n\t\ttunnelEventChan: make(chan Event, observerChannelBufferSize),\n\t\taddSinkChan:     make(chan EventSink, observerChannelBufferSize),\n\t}\n\tgo o.dispatchEvents()\n\treturn o\n}\n\nfunc (o *Observer) RegisterSink(sink EventSink) {\n\to.addSinkChan <- sink\n}\n\nfunc (o *Observer) logConnecting(connIndex uint8, address net.IP, protocol Protocol) {\n\to.log.Debug().\n\t\tInt(management.EventTypeKey, int(management.Cloudflared)).\n\t\tUint8(LogFieldConnIndex, connIndex).\n\t\tIPAddr(LogFieldIPAddress, address).\n\t\tStr(LogFieldProtocol, protocol.String()).\n\t\tMsg(\"Registering tunnel connection\")\n}\n\nfunc (o *Observer) logConnected(connectionID uuid.UUID, connIndex uint8, location string, address net.IP, protocol Protocol) {\n\to.log.Info().\n\t\tInt(management.EventTypeKey, int(management.Cloudflared)).\n\t\tStr(LogFieldConnectionID, connectionID.String()).\n\t\tUint8(LogFieldConnIndex, connIndex).\n\t\tStr(LogFieldLocation, location).\n\t\tIPAddr(LogFieldIPAddress, address).\n\t\tStr(LogFieldProtocol, protocol.String()).\n\t\tMsg(\"Registered tunnel connection\")\n\to.metrics.registerServerLocation(uint8ToString(connIndex), location)\n}\n\nfunc (o *Observer) sendRegisteringEvent(connIndex uint8) {\n\to.sendEvent(Event{Index: connIndex, EventType: RegisteringTunnel})\n}\n\nfunc (o *Observer) sendConnectedEvent(connIndex uint8, protocol Protocol, location string, edgeAddress net.IP) {\n\to.sendEvent(Event{Index: connIndex, EventType: Connected, Protocol: protocol, Location: location, EdgeAddress: edgeAddress})\n}\n\nfunc (o *Observer) SendURL(url string) {\n\to.sendEvent(Event{EventType: SetURL, URL: url})\n\n\tif !strings.HasPrefix(url, \"https://\") {\n\t\t// We add https:// in the prefix for backwards compatibility as we used to do that with the old free tunnels\n\t\t// and some tools (like `wrangler tail`) are regexp-ing for that specifically.\n\t\turl = \"https://\" + url\n\t}\n\to.metrics.userHostnamesCounts.WithLabelValues(url).Inc()\n}\n\nfunc (o *Observer) SendReconnect(connIndex uint8) {\n\to.sendEvent(Event{Index: connIndex, EventType: Reconnecting})\n}\n\nfunc (o *Observer) sendUnregisteringEvent(connIndex uint8) {\n\to.sendEvent(Event{Index: connIndex, EventType: Unregistering})\n}\n\nfunc (o *Observer) SendDisconnect(connIndex uint8) {\n\to.sendEvent(Event{Index: connIndex, EventType: Disconnected})\n}\n\nfunc (o *Observer) sendEvent(e Event) {\n\tselect {\n\tcase o.tunnelEventChan <- e:\n\t\tbreak\n\tdefault:\n\t\to.log.Warn().Msg(\"observer channel buffer is full\")\n\t}\n}\n\nfunc (o *Observer) dispatchEvents() {\n\tvar sinks []EventSink\n\tfor {\n\t\tselect {\n\t\tcase sink := <-o.addSinkChan:\n\t\t\tsinks = append(sinks, sink)\n\t\tcase evt := <-o.tunnelEventChan:\n\t\t\tfor _, sink := range sinks {\n\t\t\t\tsink.OnTunnelEvent(evt)\n\t\t\t}\n\t\t}\n\t}\n}\n\ntype EventSinkFunc func(event Event)\n\nfunc (f EventSinkFunc) OnTunnelEvent(event Event) {\n\tf(event)\n}\n"
  },
  {
    "path": "connection/observer_test.go",
    "content": "package connection\n\nimport (\n\t\"strconv\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n\tdto \"github.com/prometheus/client_model/go\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestSendUrl(t *testing.T) {\n\tobserver := NewObserver(&log, &log)\n\n\tobserver.SendURL(\"my-url.com\")\n\tassert.Equal(t, 1.0, getCounterValue(t, observer.metrics.userHostnamesCounts, \"https://my-url.com\"))\n\n\tobserver.SendURL(\"https://another-long-one.com\")\n\tassert.Equal(t, 1.0, getCounterValue(t, observer.metrics.userHostnamesCounts, \"https://another-long-one.com\"))\n}\n\nfunc getCounterValue(t *testing.T, metric *prometheus.CounterVec, val string) float64 {\n\tvar m = &dto.Metric{}\n\terr := metric.WithLabelValues(val).Write(m)\n\tassert.NoError(t, err)\n\treturn m.Counter.GetValue()\n}\n\nfunc TestRegisterServerLocation(t *testing.T) {\n\tm := newTunnelMetrics()\n\ttunnels := 20\n\tvar wg sync.WaitGroup\n\twg.Add(tunnels)\n\tfor i := 0; i < tunnels; i++ {\n\t\tgo func(i int) {\n\t\t\tid := strconv.Itoa(i)\n\t\t\tm.registerServerLocation(id, \"LHR\")\n\t\t\twg.Done()\n\t\t}(i)\n\t}\n\twg.Wait()\n\tfor i := 0; i < tunnels; i++ {\n\t\tid := strconv.Itoa(i)\n\t\tassert.Equal(t, \"LHR\", m.oldServerLocations[id])\n\t}\n\n\twg.Add(tunnels)\n\tfor i := 0; i < tunnels; i++ {\n\t\tgo func(i int) {\n\t\t\tid := strconv.Itoa(i)\n\t\t\tm.registerServerLocation(id, \"AUS\")\n\t\t\twg.Done()\n\t\t}(i)\n\t}\n\twg.Wait()\n\tfor i := 0; i < tunnels; i++ {\n\t\tid := strconv.Itoa(i)\n\t\tassert.Equal(t, \"AUS\", m.oldServerLocations[id])\n\t}\n\n}\n\nfunc TestObserverEventsDontBlock(t *testing.T) {\n\tobserver := NewObserver(&log, &log)\n\tvar mu sync.Mutex\n\tobserver.RegisterSink(EventSinkFunc(func(_ Event) {\n\t\t// callback will block if lock is already held\n\t\tmu.Lock()\n\t\tmu.Unlock()\n\t}))\n\n\ttimeout := time.AfterFunc(5*time.Second, func() {\n\t\tmu.Unlock() // release the callback on timer expiration\n\t\tt.Fatal(\"observer is blocked\")\n\t})\n\n\tmu.Lock() // block the callback\n\tfor i := 0; i < 2*observerChannelBufferSize; i++ {\n\t\tobserver.sendRegisteringEvent(0)\n\t}\n\tif pending := timeout.Stop(); pending {\n\t\t// release the callback if timer hasn't expired yet\n\t\tmu.Unlock()\n\t}\n}\n\ntype eventCollectorSink struct {\n\tobservedEvents []Event\n\tmu             sync.Mutex\n}\n\nfunc (s *eventCollectorSink) OnTunnelEvent(event Event) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.observedEvents = append(s.observedEvents, event)\n}\n\nfunc (s *eventCollectorSink) assertSawEvent(t *testing.T, event Event) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\tassert.Contains(t, s.observedEvents, event)\n}\n"
  },
  {
    "path": "connection/protocol.go",
    "content": "package connection\n\nimport (\n\t\"fmt\"\n\t\"hash/fnv\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/edgediscovery\"\n)\n\nconst (\n\tAvailableProtocolFlagMessage = \"Available protocols: 'auto' - automatically chooses the best protocol over time (the default; and also the recommended one); 'quic' - based on QUIC, relying on UDP egress to Cloudflare edge; 'http2' - using Go's HTTP2 library, relying on TCP egress to Cloudflare edge\"\n\t// edgeH2muxTLSServerName is the server name to establish h2mux connection with edge (unused, but kept for legacy reference).\n\t_ = \"cftunnel.com\"\n\t// edgeH2TLSServerName is the server name to establish http2 connection with edge\n\tedgeH2TLSServerName = \"h2.cftunnel.com\"\n\t// edgeQUICServerName is the server name to establish quic connection with edge.\n\tedgeQUICServerName = \"quic.cftunnel.com\"\n\tAutoSelectFlag     = \"auto\"\n\t// SRV and TXT record resolution TTL\n\tResolveTTL = time.Hour\n)\n\n// ProtocolList represents a list of supported protocols for communication with the edge\n// in order of precedence for remote percentage fetcher.\nvar ProtocolList = []Protocol{QUIC, HTTP2}\n\ntype Protocol int64\n\nconst (\n\t// HTTP2 using golang HTTP2 library for edge connections.\n\tHTTP2 Protocol = iota\n\t// QUIC using quic-go for edge connections.\n\tQUIC\n)\n\n// Fallback returns the fallback protocol and whether the protocol has a fallback\nfunc (p Protocol) fallback() (Protocol, bool) {\n\tswitch p {\n\tcase HTTP2:\n\t\treturn 0, false\n\tcase QUIC:\n\t\treturn HTTP2, true\n\tdefault:\n\t\treturn 0, false\n\t}\n}\n\nfunc (p Protocol) String() string {\n\tswitch p {\n\tcase HTTP2:\n\t\treturn \"http2\"\n\tcase QUIC:\n\t\treturn \"quic\"\n\tdefault:\n\t\treturn \"unknown protocol\"\n\t}\n}\n\nfunc (p Protocol) TLSSettings() *TLSSettings {\n\tswitch p {\n\tcase HTTP2:\n\t\treturn &TLSSettings{\n\t\t\tServerName: edgeH2TLSServerName,\n\t\t}\n\tcase QUIC:\n\t\treturn &TLSSettings{\n\t\t\tServerName: edgeQUICServerName,\n\t\t\tNextProtos: []string{\"argotunnel\"},\n\t\t}\n\tdefault:\n\t\treturn nil\n\t}\n}\n\ntype TLSSettings struct {\n\tServerName string\n\tNextProtos []string\n}\n\ntype ProtocolSelector interface {\n\tCurrent() Protocol\n\tFallback() (Protocol, bool)\n}\n\n// staticProtocolSelector will not provide a different protocol for Fallback\ntype staticProtocolSelector struct {\n\tcurrent Protocol\n}\n\nfunc (s *staticProtocolSelector) Current() Protocol {\n\treturn s.current\n}\n\nfunc (s *staticProtocolSelector) Fallback() (Protocol, bool) {\n\treturn s.current, false\n}\n\n// remoteProtocolSelector will fetch a list of remote protocols to provide for edge discovery\ntype remoteProtocolSelector struct {\n\tlock sync.RWMutex\n\n\tcurrent Protocol\n\n\t// protocolPool is desired protocols in the order of priority they should be picked in.\n\tprotocolPool []Protocol\n\n\tswitchThreshold int32\n\tfetchFunc       edgediscovery.PercentageFetcher\n\trefreshAfter    time.Time\n\tttl             time.Duration\n\tlog             *zerolog.Logger\n}\n\nfunc newRemoteProtocolSelector(\n\tcurrent Protocol,\n\tprotocolPool []Protocol,\n\tswitchThreshold int32,\n\tfetchFunc edgediscovery.PercentageFetcher,\n\tttl time.Duration,\n\tlog *zerolog.Logger,\n) *remoteProtocolSelector {\n\treturn &remoteProtocolSelector{\n\t\tcurrent:         current,\n\t\tprotocolPool:    protocolPool,\n\t\tswitchThreshold: switchThreshold,\n\t\tfetchFunc:       fetchFunc,\n\t\trefreshAfter:    time.Now().Add(ttl),\n\t\tttl:             ttl,\n\t\tlog:             log,\n\t}\n}\n\nfunc (s *remoteProtocolSelector) Current() Protocol {\n\ts.lock.Lock()\n\tdefer s.lock.Unlock()\n\tif time.Now().Before(s.refreshAfter) {\n\t\treturn s.current\n\t}\n\n\tprotocol, err := getProtocol(s.protocolPool, s.fetchFunc, s.switchThreshold)\n\tif err != nil {\n\t\ts.log.Err(err).Msg(\"Failed to refresh protocol\")\n\t\treturn s.current\n\t}\n\ts.current = protocol\n\n\ts.refreshAfter = time.Now().Add(s.ttl)\n\treturn s.current\n}\n\nfunc (s *remoteProtocolSelector) Fallback() (Protocol, bool) {\n\ts.lock.RLock()\n\tdefer s.lock.RUnlock()\n\treturn s.current.fallback()\n}\n\nfunc getProtocol(protocolPool []Protocol, fetchFunc edgediscovery.PercentageFetcher, switchThreshold int32) (Protocol, error) {\n\tprotocolPercentages, err := fetchFunc()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tfor _, protocol := range protocolPool {\n\t\tprotocolPercentage := protocolPercentages.GetPercentage(protocol.String())\n\t\tif protocolPercentage > switchThreshold {\n\t\t\treturn protocol, nil\n\t\t}\n\t}\n\n\t// Default to first index in protocolPool list\n\treturn protocolPool[0], nil\n}\n\n// defaultProtocolSelector will allow for a protocol to have a fallback\ntype defaultProtocolSelector struct {\n\tlock    sync.RWMutex\n\tcurrent Protocol\n}\n\nfunc newDefaultProtocolSelector(\n\tcurrent Protocol,\n) *defaultProtocolSelector {\n\treturn &defaultProtocolSelector{\n\t\tcurrent: current,\n\t}\n}\n\nfunc (s *defaultProtocolSelector) Current() Protocol {\n\ts.lock.Lock()\n\tdefer s.lock.Unlock()\n\treturn s.current\n}\n\nfunc (s *defaultProtocolSelector) Fallback() (Protocol, bool) {\n\ts.lock.RLock()\n\tdefer s.lock.RUnlock()\n\treturn s.current.fallback()\n}\n\nfunc NewProtocolSelector(\n\tprotocolFlag string,\n\taccountTag string,\n\ttunnelTokenProvided bool,\n\tneedPQ bool,\n\tprotocolFetcher edgediscovery.PercentageFetcher,\n\tresolveTTL time.Duration,\n\tlog *zerolog.Logger,\n) (ProtocolSelector, error) {\n\t// With --post-quantum, we force quic\n\tif needPQ {\n\t\treturn &staticProtocolSelector{\n\t\t\tcurrent: QUIC,\n\t\t}, nil\n\t}\n\n\tthreshold := switchThreshold(accountTag)\n\tfetchedProtocol, err := getProtocol(ProtocolList, protocolFetcher, threshold)\n\tlog.Debug().Msgf(\"Fetched protocol: %s\", fetchedProtocol)\n\tif err != nil {\n\t\tlog.Warn().Msg(\"Unable to lookup protocol percentage.\")\n\t\t// Falling through here since 'auto' is handled in the switch and failing\n\t\t// to do the protocol lookup isn't a failure since it can be triggered again\n\t\t// after the TTL.\n\t}\n\n\t// If the user picks a protocol, then we stick to it no matter what.\n\tswitch protocolFlag {\n\tcase \"h2mux\":\n\t\t// Any users still requesting h2mux will be upgraded to http2 instead\n\t\tlog.Warn().Msg(\"h2mux is no longer a supported protocol: upgrading edge connection to http2. Please remove '--protocol h2mux' from runtime arguments to remove this warning.\")\n\t\treturn &staticProtocolSelector{current: HTTP2}, nil\n\tcase QUIC.String():\n\t\treturn &staticProtocolSelector{current: QUIC}, nil\n\tcase HTTP2.String():\n\t\treturn &staticProtocolSelector{current: HTTP2}, nil\n\tcase AutoSelectFlag:\n\t\t// When a --token is provided, we want to start with QUIC but have fallback to HTTP2\n\t\tif tunnelTokenProvided {\n\t\t\treturn newDefaultProtocolSelector(QUIC), nil\n\t\t}\n\t\treturn newRemoteProtocolSelector(fetchedProtocol, ProtocolList, threshold, protocolFetcher, resolveTTL, log), nil\n\t}\n\n\treturn nil, fmt.Errorf(\"unknown protocol %s, %s\", protocolFlag, AvailableProtocolFlagMessage)\n}\n\nfunc switchThreshold(accountTag string) int32 {\n\th := fnv.New32a()\n\t_, _ = h.Write([]byte(accountTag))\n\treturn int32(h.Sum32() % 100) // nolint: gosec\n}\n"
  },
  {
    "path": "connection/protocol_test.go",
    "content": "package connection\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/cloudflare/cloudflared/edgediscovery\"\n)\n\nconst (\n\ttestNoTTL      = 0\n\ttestAccountTag = \"testAccountTag\"\n)\n\nfunc mockFetcher(getError bool, protocolPercent ...edgediscovery.ProtocolPercent) edgediscovery.PercentageFetcher {\n\treturn func() (edgediscovery.ProtocolPercents, error) {\n\t\tif getError {\n\t\t\treturn nil, fmt.Errorf(\"failed to fetch percentage\")\n\t\t}\n\t\treturn protocolPercent, nil\n\t}\n}\n\ntype dynamicMockFetcher struct {\n\tprotocolPercents edgediscovery.ProtocolPercents\n\terr              error\n}\n\nfunc (dmf *dynamicMockFetcher) fetch() edgediscovery.PercentageFetcher {\n\treturn func() (edgediscovery.ProtocolPercents, error) {\n\t\treturn dmf.protocolPercents, dmf.err\n\t}\n}\n\nfunc TestNewProtocolSelector(t *testing.T) {\n\ttests := []struct {\n\t\tname                string\n\t\tprotocol            string\n\t\ttunnelTokenProvided bool\n\t\tneedPQ              bool\n\t\texpectedProtocol    Protocol\n\t\thasFallback         bool\n\t\texpectedFallback    Protocol\n\t\twantErr             bool\n\t}{\n\t\t{\n\t\t\tname:     \"named tunnel with unknown protocol\",\n\t\t\tprotocol: \"unknown\",\n\t\t\twantErr:  true,\n\t\t},\n\t\t{\n\t\t\tname:             \"named tunnel with h2mux: force to http2\",\n\t\t\tprotocol:         \"h2mux\",\n\t\t\texpectedProtocol: HTTP2,\n\t\t},\n\t\t{\n\t\t\tname:             \"named tunnel with http2: no fallback\",\n\t\t\tprotocol:         \"http2\",\n\t\t\texpectedProtocol: HTTP2,\n\t\t},\n\t\t{\n\t\t\tname:             \"named tunnel with auto: quic\",\n\t\t\tprotocol:         AutoSelectFlag,\n\t\t\texpectedProtocol: QUIC,\n\t\t\thasFallback:      true,\n\t\t\texpectedFallback: HTTP2,\n\t\t},\n\t\t{\n\t\t\tname:             \"named tunnel (post quantum)\",\n\t\t\tprotocol:         AutoSelectFlag,\n\t\t\tneedPQ:           true,\n\t\t\texpectedProtocol: QUIC,\n\t\t},\n\t\t{\n\t\t\tname:             \"named tunnel (post quantum) w/http2\",\n\t\t\tprotocol:         \"http2\",\n\t\t\tneedPQ:           true,\n\t\t\texpectedProtocol: QUIC,\n\t\t},\n\t}\n\n\tfetcher := dynamicMockFetcher{\n\t\tprotocolPercents: edgediscovery.ProtocolPercents{},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tselector, err := NewProtocolSelector(test.protocol, testAccountTag, test.tunnelTokenProvided, test.needPQ, fetcher.fetch(), ResolveTTL, &log)\n\t\t\tif test.wantErr {\n\t\t\t\tassert.Error(t, err, fmt.Sprintf(\"test %s failed\", test.name))\n\t\t\t} else {\n\t\t\t\tassert.NoError(t, err, fmt.Sprintf(\"test %s failed\", test.name))\n\t\t\t\tassert.Equal(t, test.expectedProtocol, selector.Current(), fmt.Sprintf(\"test %s failed\", test.name))\n\t\t\t\tfallback, ok := selector.Fallback()\n\t\t\t\tassert.Equal(t, test.hasFallback, ok, fmt.Sprintf(\"test %s failed\", test.name))\n\t\t\t\tif test.hasFallback {\n\t\t\t\t\tassert.Equal(t, test.expectedFallback, fallback, fmt.Sprintf(\"test %s failed\", test.name))\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestAutoProtocolSelectorRefresh(t *testing.T) {\n\tfetcher := dynamicMockFetcher{}\n\tselector, err := NewProtocolSelector(AutoSelectFlag, testAccountTag, false, false, fetcher.fetch(), testNoTTL, &log)\n\tassert.NoError(t, err)\n\tassert.Equal(t, QUIC, selector.Current())\n\n\tfetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: \"http2\", Percentage: 100}}\n\tassert.Equal(t, HTTP2, selector.Current())\n\n\tfetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: \"http2\", Percentage: 0}}\n\tassert.Equal(t, QUIC, selector.Current())\n\n\tfetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: \"http2\", Percentage: 100}}\n\tassert.Equal(t, HTTP2, selector.Current())\n\n\tfetcher.err = fmt.Errorf(\"failed to fetch\")\n\tassert.Equal(t, HTTP2, selector.Current())\n\n\tfetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: \"http2\", Percentage: -1}}\n\tfetcher.err = nil\n\tassert.Equal(t, QUIC, selector.Current())\n\n\tfetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: \"http2\", Percentage: 0}}\n\tassert.Equal(t, QUIC, selector.Current())\n\n\tfetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: \"quic\", Percentage: 100}}\n\tassert.Equal(t, QUIC, selector.Current())\n}\n\nfunc TestHTTP2ProtocolSelectorRefresh(t *testing.T) {\n\tfetcher := dynamicMockFetcher{}\n\t// Since the user chooses http2 on purpose, we always stick to it.\n\tselector, err := NewProtocolSelector(HTTP2.String(), testAccountTag, false, false, fetcher.fetch(), testNoTTL, &log)\n\tassert.NoError(t, err)\n\tassert.Equal(t, HTTP2, selector.Current())\n\n\tfetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: \"http2\", Percentage: 100}}\n\tassert.Equal(t, HTTP2, selector.Current())\n\n\tfetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: \"http2\", Percentage: 0}}\n\tassert.Equal(t, HTTP2, selector.Current())\n\n\tfetcher.err = fmt.Errorf(\"failed to fetch\")\n\tassert.Equal(t, HTTP2, selector.Current())\n\n\tfetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: \"http2\", Percentage: -1}}\n\tfetcher.err = nil\n\tassert.Equal(t, HTTP2, selector.Current())\n\n\tfetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: \"http2\", Percentage: 0}}\n\tassert.Equal(t, HTTP2, selector.Current())\n\n\tfetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: \"http2\", Percentage: 100}}\n\tassert.Equal(t, HTTP2, selector.Current())\n\n\tfetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: \"http2\", Percentage: -1}}\n\tassert.Equal(t, HTTP2, selector.Current())\n}\n\nfunc TestAutoProtocolSelectorNoRefreshWithToken(t *testing.T) {\n\tfetcher := dynamicMockFetcher{}\n\tselector, err := NewProtocolSelector(AutoSelectFlag, testAccountTag, true, false, fetcher.fetch(), testNoTTL, &log)\n\tassert.NoError(t, err)\n\tassert.Equal(t, QUIC, selector.Current())\n\n\tfetcher.protocolPercents = edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: \"http2\", Percentage: 100}}\n\tassert.Equal(t, QUIC, selector.Current())\n}\n"
  },
  {
    "path": "connection/quic.go",
    "content": "package connection\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/netip\"\n\t\"runtime\"\n\t\"sync\"\n\n\t\"github.com/quic-go/quic-go\"\n\t\"github.com/rs/zerolog\"\n)\n\nvar (\n\tportForConnIndex = make(map[uint8]int, 0)\n\tportMapMutex     sync.Mutex\n)\n\nfunc DialQuic(\n\tctx context.Context,\n\tquicConfig *quic.Config,\n\ttlsConfig *tls.Config,\n\tedgeAddr netip.AddrPort,\n\tlocalAddr net.IP,\n\tconnIndex uint8,\n\tlogger *zerolog.Logger,\n) (quic.Connection, error) {\n\tudpConn, err := createUDPConnForConnIndex(connIndex, localAddr, edgeAddr, logger)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tconn, err := quic.Dial(ctx, udpConn, net.UDPAddrFromAddrPort(edgeAddr), tlsConfig, quicConfig)\n\tif err != nil {\n\t\t// close the udp server socket in case of error connecting to the edge\n\t\tudpConn.Close()\n\t\treturn nil, &EdgeQuicDialError{Cause: err}\n\t}\n\n\t// wrap the session, so that the UDPConn is closed after session is closed.\n\tconn = &wrapCloseableConnQuicConnection{\n\t\tconn,\n\t\tudpConn,\n\t}\n\treturn conn, nil\n}\n\nfunc createUDPConnForConnIndex(connIndex uint8, localIP net.IP, edgeIP netip.AddrPort, logger *zerolog.Logger) (*net.UDPConn, error) {\n\tportMapMutex.Lock()\n\tdefer portMapMutex.Unlock()\n\n\tlistenNetwork := \"udp\"\n\t// https://github.com/quic-go/quic-go/issues/3793 DF bit cannot be set for dual stack listener (\"udp\") on macOS,\n\t// to set the DF bit properly, the network string needs to be specific to the IP family.\n\tif runtime.GOOS == \"darwin\" {\n\t\tif edgeIP.Addr().Is4() {\n\t\t\tlistenNetwork = \"udp4\"\n\t\t} else {\n\t\t\tlistenNetwork = \"udp6\"\n\t\t}\n\t}\n\n\t// if port was not set yet, it will be zero, so bind will randomly allocate one.\n\tif port, ok := portForConnIndex[connIndex]; ok {\n\t\tudpConn, err := net.ListenUDP(listenNetwork, &net.UDPAddr{IP: localIP, Port: port})\n\t\t// if there wasn't an error, or if port was 0 (independently of error or not, just return)\n\t\tif err == nil {\n\t\t\treturn udpConn, nil\n\t\t} else {\n\t\t\tlogger.Debug().Err(err).Msgf(\"Unable to reuse port %d for connIndex %d. Falling back to random allocation.\", port, connIndex)\n\t\t}\n\t}\n\n\t// if we reached here, then there was an error or port as not been allocated it.\n\tudpConn, err := net.ListenUDP(listenNetwork, &net.UDPAddr{IP: localIP, Port: 0})\n\tif err == nil {\n\t\tudpAddr, ok := (udpConn.LocalAddr()).(*net.UDPAddr)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"unable to cast to udpConn\")\n\t\t}\n\t\tportForConnIndex[connIndex] = udpAddr.Port\n\t} else {\n\t\tdelete(portForConnIndex, connIndex)\n\t}\n\n\treturn udpConn, err\n}\n\ntype wrapCloseableConnQuicConnection struct {\n\tquic.Connection\n\tudpConn *net.UDPConn\n}\n\nfunc (w *wrapCloseableConnQuicConnection) CloseWithError(errorCode quic.ApplicationErrorCode, reason string) error {\n\terr := w.Connection.CloseWithError(errorCode, reason)\n\tw.udpConn.Close()\n\n\treturn err\n}\n"
  },
  {
    "path": "connection/quic_connection.go",
    "content": "package connection\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go\"\n\t\"github.com/rs/zerolog\"\n\t\"golang.org/x/sync/errgroup\"\n\n\t\"github.com/cloudflare/cloudflared/client\"\n\tcfdflow \"github.com/cloudflare/cloudflared/flow\"\n\n\tcfdquic \"github.com/cloudflare/cloudflared/quic\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n\trpcquic \"github.com/cloudflare/cloudflared/tunnelrpc/quic\"\n)\n\nconst (\n\t// HTTPHeaderKey is used to get or set http headers in QUIC ALPN if the underlying proxy connection type is HTTP.\n\tHTTPHeaderKey = \"HttpHeader\"\n\t// HTTPMethodKey is used to get or set http method in QUIC ALPN if the underlying proxy connection type is HTTP.\n\tHTTPMethodKey = \"HttpMethod\"\n\t// HTTPHostKey is used to get or set http host in QUIC ALPN if the underlying proxy connection type is HTTP.\n\tHTTPHostKey = \"HttpHost\"\n\t// HTTPStatus is used to return http status code in QUIC ALPN if the underlying proxy connection type is HTTP.\n\tHTTPStatus = \"HttpStatus\"\n\n\tQUICMetadataFlowID = \"FlowID\"\n)\n\n// quicConnection represents the type that facilitates Proxying via QUIC streams.\ntype quicConnection struct {\n\tconn                 quic.Connection\n\tlogger               *zerolog.Logger\n\torchestrator         Orchestrator\n\tdatagramHandler      DatagramSessionHandler\n\tcontrolStreamHandler ControlStreamHandler\n\tconnOptions          *client.ConnectionOptionsSnapshot\n\tconnIndex            uint8\n\n\trpcTimeout         time.Duration\n\tstreamWriteTimeout time.Duration\n\tgracePeriod        time.Duration\n}\n\n// NewTunnelConnection takes a [quic.Connection] to wrap it for use with cloudflared application logic.\nfunc NewTunnelConnection(\n\tctx context.Context,\n\tconn quic.Connection,\n\tconnIndex uint8,\n\torchestrator Orchestrator,\n\tdatagramSessionHandler DatagramSessionHandler,\n\tcontrolStreamHandler ControlStreamHandler,\n\tconnOptions *client.ConnectionOptionsSnapshot,\n\trpcTimeout time.Duration,\n\tstreamWriteTimeout time.Duration,\n\tgracePeriod time.Duration,\n\tlogger *zerolog.Logger,\n) TunnelConnection {\n\treturn &quicConnection{\n\t\tconn:                 conn,\n\t\tlogger:               logger,\n\t\torchestrator:         orchestrator,\n\t\tdatagramHandler:      datagramSessionHandler,\n\t\tcontrolStreamHandler: controlStreamHandler,\n\t\tconnOptions:          connOptions,\n\t\tconnIndex:            connIndex,\n\t\trpcTimeout:           rpcTimeout,\n\t\tstreamWriteTimeout:   streamWriteTimeout,\n\t\tgracePeriod:          gracePeriod,\n\t}\n}\n\n// Serve starts a QUIC connection that begins accepting streams.\n// Returning a nil error means cloudflared will exit for good and will not attempt to reconnect.\nfunc (q *quicConnection) Serve(ctx context.Context) error {\n\t// The edge assumes the first stream is used for the control plane\n\tcontrolStream, err := q.conn.OpenStream()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to open a registration control stream: %w\", err)\n\t}\n\n\t// If either goroutine returns a non nil error, then the error group cancels the context, thus also canceling the\n\t// other goroutines. We enforce returning a not-nil error for each function started in the errgroup by logging\n\t// the error returned and returning a custom error type instead.\n\terrGroup, ctx := errgroup.WithContext(ctx)\n\n\t// Close the quic connection if any of the following routines return from the errgroup (regardless of their error)\n\t// because they are no longer processing requests for the connection.\n\tdefer q.Close()\n\n\t// Start the control stream routine\n\terrGroup.Go(func() error {\n\t\t// err is equal to nil if we exit due to unregistration. If that happens we want to wait the full\n\t\t// amount of the grace period, allowing requests to finish before we cancel the context, which will\n\t\t// make cloudflared exit.\n\t\tif err := q.serveControlStream(ctx, controlStream); err == nil {\n\t\t\tif q.gracePeriod > 0 {\n\t\t\t\t// In Go1.23 this can be removed and replaced with time.Ticker\n\t\t\t\t// see https://pkg.go.dev/time#Tick\n\t\t\t\tticker := time.NewTicker(q.gracePeriod)\n\t\t\t\tdefer ticker.Stop()\n\t\t\t\tselect {\n\t\t\t\tcase <-ctx.Done():\n\t\t\t\tcase <-ticker.C:\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif err != nil {\n\t\t\tq.logger.Error().Err(err).Msg(\"failed to serve the control stream\")\n\t\t}\n\t\treturn &ControlStreamError{}\n\t})\n\t// Start the accept stream loop routine\n\terrGroup.Go(func() error {\n\t\terr := q.acceptStream(ctx)\n\t\tif err != nil {\n\t\t\tq.logger.Error().Err(err).Msg(\"failed to accept incoming stream requests\")\n\t\t}\n\t\treturn &StreamListenerError{}\n\t})\n\t// Start the datagram handler routine\n\terrGroup.Go(func() error {\n\t\terr := q.datagramHandler.Serve(ctx)\n\t\tif err != nil {\n\t\t\tq.logger.Error().Err(err).Msg(\"failed to run the datagram handler\")\n\t\t}\n\t\treturn &DatagramManagerError{}\n\t})\n\n\treturn errGroup.Wait()\n}\n\n// serveControlStream will serve the RPC; blocking until the control plane is done.\nfunc (q *quicConnection) serveControlStream(ctx context.Context, controlStream quic.Stream) error {\n\treturn q.controlStreamHandler.ServeControlStream(ctx, controlStream, q.connOptions.ConnectionOptions(), q.orchestrator)\n}\n\n// Close the connection with no errors specified.\nfunc (q *quicConnection) Close() {\n\t_ = q.conn.CloseWithError(0, \"\")\n}\n\nfunc (q *quicConnection) acceptStream(ctx context.Context) error {\n\tfor {\n\t\tquicStream, err := q.conn.AcceptStream(ctx)\n\t\tif err != nil {\n\t\t\t// context.Canceled is usually a user ctrl+c. We don't want to log an error here as it's intentional.\n\t\t\tif errors.Is(err, context.Canceled) || q.controlStreamHandler.IsStopped() {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"failed to accept QUIC stream: %w\", err)\n\t\t}\n\t\tgo q.runStream(quicStream)\n\t}\n}\n\nfunc (q *quicConnection) runStream(quicStream quic.Stream) {\n\tctx := quicStream.Context()\n\tstream := cfdquic.NewSafeStreamCloser(quicStream, q.streamWriteTimeout, q.logger)\n\tdefer stream.Close()\n\n\t// we are going to fuse readers/writers from stream <- cloudflared -> origin, and we want to guarantee that\n\t// code executed in the code path of handleStream don't trigger an earlier close to the downstream write stream.\n\t// So, we wrap the stream with a no-op write closer and only this method can actually close write side of the stream.\n\t// A call to close will simulate a close to the read-side, which will fail subsequent reads.\n\tnoCloseStream := &nopCloserReadWriter{ReadWriteCloser: stream}\n\tss := rpcquic.NewCloudflaredServer(q.handleDataStream, q.datagramHandler, q, q.rpcTimeout)\n\tif err := ss.Serve(ctx, noCloseStream); err != nil {\n\t\tq.logger.Debug().Err(err).Msg(\"Failed to handle QUIC stream\")\n\n\t\t// if we received an error at this level, then close write side of stream with an error, which will result in\n\t\t// RST_STREAM frame.\n\t\tquicStream.CancelWrite(0)\n\t}\n}\n\nfunc (q *quicConnection) handleDataStream(ctx context.Context, stream *rpcquic.RequestServerStream) error {\n\trequest, err := stream.ReadConnectRequestData()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err, connectResponseSent := q.dispatchRequest(ctx, stream, request); err != nil {\n\t\tq.logger.Err(err).Str(\"type\", request.Type.String()).Str(\"dest\", request.Dest).Msg(\"Request failed\")\n\n\t\t// if the connectResponse was already sent and we had an error, we need to propagate it up, so that the stream is\n\t\t// closed with an RST_STREAM frame\n\t\tif connectResponseSent {\n\t\t\treturn err\n\t\t}\n\n\t\tvar metadata []pogs.Metadata\n\t\t// Check the type of error that was throw and add metadata that will help identify it on OTD.\n\t\tif errors.Is(err, cfdflow.ErrTooManyActiveFlows) {\n\t\t\tmetadata = append(metadata, pogs.ErrorFlowConnectRateLimitedMetadata)\n\t\t}\n\n\t\tif writeRespErr := stream.WriteConnectResponseData(err, metadata...); writeRespErr != nil {\n\t\t\treturn writeRespErr\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// dispatchRequest will dispatch the request to the origin depending on the type and returns an error if it occurs.\n// Also returns if the connect response was sent to the downstream during processing of the origin request.\nfunc (q *quicConnection) dispatchRequest(ctx context.Context, stream *rpcquic.RequestServerStream, request *pogs.ConnectRequest) (err error, connectResponseSent bool) {\n\toriginProxy, err := q.orchestrator.GetOriginProxy()\n\tif err != nil {\n\t\treturn err, false\n\t}\n\n\tswitch request.Type {\n\tcase pogs.ConnectionTypeHTTP, pogs.ConnectionTypeWebsocket:\n\t\ttracedReq, err := buildHTTPRequest(ctx, request, stream, q.connIndex, q.logger)\n\t\tif err != nil {\n\t\t\treturn err, false\n\t\t}\n\t\tw := newHTTPResponseAdapter(stream)\n\t\treturn originProxy.ProxyHTTP(&w, tracedReq, request.Type == pogs.ConnectionTypeWebsocket), w.connectResponseSent\n\n\tcase pogs.ConnectionTypeTCP:\n\t\trwa := &streamReadWriteAcker{RequestServerStream: stream}\n\t\tmetadata := request.MetadataMap()\n\t\treturn originProxy.ProxyTCP(ctx, rwa, &TCPRequest{\n\t\t\tDest:      request.Dest,\n\t\t\tFlowID:    metadata[QUICMetadataFlowID],\n\t\t\tCfTraceID: metadata[tracing.TracerContextName],\n\t\t\tConnIndex: q.connIndex,\n\t\t}), rwa.connectResponseSent\n\tdefault:\n\t\treturn fmt.Errorf(\"unsupported error type: %s\", request.Type), false\n\t}\n}\n\n// UpdateConfiguration is the RPC method invoked by edge when there is a new configuration\nfunc (q *quicConnection) UpdateConfiguration(ctx context.Context, version int32, config []byte) *pogs.UpdateConfigurationResponse {\n\treturn q.orchestrator.UpdateConfig(version, config)\n}\n\n// streamReadWriteAcker is a light wrapper over QUIC streams with a callback to send response back to\n// the client.\ntype streamReadWriteAcker struct {\n\t*rpcquic.RequestServerStream\n\tconnectResponseSent bool\n}\n\n// AckConnection acks response back to the proxy.\nfunc (s *streamReadWriteAcker) AckConnection(tracePropagation string) error {\n\tmetadata := []pogs.Metadata{}\n\t// Only add tracing if provided by the edge request\n\tif tracePropagation != \"\" {\n\t\tmetadata = append(metadata, pogs.Metadata{\n\t\t\tKey: tracing.CanonicalCloudflaredTracingHeader,\n\t\t\tVal: tracePropagation,\n\t\t})\n\t}\n\ts.connectResponseSent = true\n\treturn s.WriteConnectResponseData(nil, metadata...)\n}\n\n// httpResponseAdapter translates responses written by the HTTP Proxy into ones that can be used in QUIC.\ntype httpResponseAdapter struct {\n\t*rpcquic.RequestServerStream\n\theaders             http.Header\n\tconnectResponseSent bool\n}\n\nfunc newHTTPResponseAdapter(s *rpcquic.RequestServerStream) httpResponseAdapter {\n\treturn httpResponseAdapter{RequestServerStream: s, headers: make(http.Header)}\n}\n\nfunc (hrw *httpResponseAdapter) AddTrailer(trailerName, trailerValue string) {\n\t// we do not support trailers over QUIC\n}\n\nfunc (hrw *httpResponseAdapter) WriteRespHeaders(status int, header http.Header) error {\n\tmetadata := make([]pogs.Metadata, 0)\n\tmetadata = append(metadata, pogs.Metadata{Key: HTTPStatus, Val: strconv.Itoa(status)})\n\tfor k, vv := range header {\n\t\tfor _, v := range vv {\n\t\t\thttpHeaderKey := fmt.Sprintf(\"%s:%s\", HTTPHeaderKey, k)\n\t\t\tmetadata = append(metadata, pogs.Metadata{Key: httpHeaderKey, Val: v})\n\t\t}\n\t}\n\n\treturn hrw.WriteConnectResponseData(nil, metadata...)\n}\n\nfunc (hrw *httpResponseAdapter) Write(p []byte) (int, error) {\n\t// Make sure to send WriteHeader response if not called yet\n\tif !hrw.connectResponseSent {\n\t\t_ = hrw.WriteRespHeaders(http.StatusOK, hrw.headers)\n\t}\n\treturn hrw.RequestServerStream.Write(p)\n}\n\nfunc (hrw *httpResponseAdapter) Header() http.Header {\n\treturn hrw.headers\n}\n\n// This is a no-op Flush because this adapter is over a quic.Stream and we don't need Flush here.\nfunc (hrw *httpResponseAdapter) Flush() {}\n\nfunc (hrw *httpResponseAdapter) WriteHeader(status int) {\n\t_ = hrw.WriteRespHeaders(status, hrw.headers)\n}\n\nfunc (hrw *httpResponseAdapter) Hijack() (net.Conn, *bufio.ReadWriter, error) {\n\tconn := &localProxyConnection{hrw.ReadWriteCloser}\n\treadWriter := bufio.NewReadWriter(\n\t\tbufio.NewReader(hrw.ReadWriteCloser),\n\t\tbufio.NewWriter(hrw.ReadWriteCloser),\n\t)\n\treturn conn, readWriter, nil\n}\n\nfunc (hrw *httpResponseAdapter) WriteErrorResponse(err error) {\n\t_ = hrw.WriteConnectResponseData(err, pogs.Metadata{Key: HTTPStatus, Val: strconv.Itoa(http.StatusBadGateway)})\n}\n\nfunc (hrw *httpResponseAdapter) WriteConnectResponseData(respErr error, metadata ...pogs.Metadata) error {\n\thrw.connectResponseSent = true\n\treturn hrw.RequestServerStream.WriteConnectResponseData(respErr, metadata...)\n}\n\nfunc buildHTTPRequest(\n\tctx context.Context,\n\tconnectRequest *pogs.ConnectRequest,\n\tbody io.ReadCloser,\n\tconnIndex uint8,\n\tlog *zerolog.Logger,\n) (*tracing.TracedHTTPRequest, error) {\n\tmetadata := connectRequest.MetadataMap()\n\tdest := connectRequest.Dest\n\tmethod := metadata[HTTPMethodKey]\n\thost := metadata[HTTPHostKey]\n\tisWebsocket := connectRequest.Type == pogs.ConnectionTypeWebsocket\n\n\treq, err := http.NewRequestWithContext(ctx, method, dest, body)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treq.Host = host\n\tfor _, metadata := range connectRequest.Metadata {\n\t\tif strings.Contains(metadata.Key, HTTPHeaderKey) {\n\t\t\t// metadata.Key is off the format httpHeaderKey:<HTTPHeader>\n\t\t\thttpHeaderKey := strings.Split(metadata.Key, \":\")\n\t\t\tif len(httpHeaderKey) != 2 {\n\t\t\t\treturn nil, fmt.Errorf(\"header Key: %s malformed\", metadata.Key)\n\t\t\t}\n\t\t\treq.Header.Add(httpHeaderKey[1], metadata.Val)\n\t\t}\n\t}\n\t// Go's http.Client automatically sends chunked request body if this value is not set on the\n\t// *http.Request struct regardless of header:\n\t// https://go.googlesource.com/go/+/go1.8rc2/src/net/http/transfer.go#154.\n\tif err := setContentLength(req); err != nil {\n\t\treturn nil, fmt.Errorf(\"Error setting content-length: %w\", err)\n\t}\n\n\t// Go's client defaults to chunked encoding after a 200ms delay if the following cases are true:\n\t//   * the request body blocks\n\t//   * the content length is not set (or set to -1)\n\t//   * the method doesn't usually have a body (GET, HEAD, DELETE, ...)\n\t//   * there is no transfer-encoding=chunked already set.\n\t// So, if transfer cannot be chunked and content length is 0, we dont set a request body.\n\tif !isWebsocket && !isTransferEncodingChunked(req) && req.ContentLength == 0 {\n\t\treq.Body = http.NoBody\n\t}\n\tstripWebsocketUpgradeHeader(req)\n\n\t// Check for tracing on request\n\ttracedReq := tracing.NewTracedHTTPRequest(req, connIndex, log)\n\treturn tracedReq, err\n}\n\nfunc setContentLength(req *http.Request) error {\n\tvar err error\n\tif contentLengthStr := req.Header.Get(\"Content-Length\"); contentLengthStr != \"\" {\n\t\treq.ContentLength, err = strconv.ParseInt(contentLengthStr, 10, 64)\n\t}\n\treturn err\n}\n\nfunc isTransferEncodingChunked(req *http.Request) bool {\n\ttransferEncodingVal := req.Header.Get(\"Transfer-Encoding\")\n\t// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding suggests that this can be a comma\n\t// separated value as well.\n\treturn strings.Contains(strings.ToLower(transferEncodingVal), \"chunked\")\n}\n\n// A helper struct that guarantees a call to close only affects read side, but not write side.\ntype nopCloserReadWriter struct {\n\tio.ReadWriteCloser\n\n\t// for use by Read only\n\t// we don't need a memory barrier here because there is an implicit assumption that\n\t// Read calls can't happen concurrently by different go-routines.\n\tsawEOF bool\n\t// should be updated and read using atomic primitives.\n\t// value is read in Read method and written in Close method, which could be done by different\n\t// go-routines.\n\tclosed uint32\n}\n\nfunc (np *nopCloserReadWriter) Read(p []byte) (n int, err error) {\n\tif np.sawEOF {\n\t\treturn 0, io.EOF\n\t}\n\n\tif atomic.LoadUint32(&np.closed) > 0 {\n\t\treturn 0, fmt.Errorf(\"closed by handler\")\n\t}\n\n\tn, err = np.ReadWriteCloser.Read(p)\n\tif err == io.EOF {\n\t\tnp.sawEOF = true\n\t}\n\n\treturn\n}\n\nfunc (np *nopCloserReadWriter) Close() error {\n\tatomic.StoreUint32(&np.closed, 1)\n\n\treturn nil\n}\n"
  },
  {
    "path": "connection/quic_connection_test.go",
    "content": "package connection\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"encoding/pem\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/big\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/netip\"\n\t\"net/url\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/gobwas/ws/wsutil\"\n\t\"github.com/google/uuid\"\n\tpkgerrors \"github.com/pkg/errors\"\n\t\"github.com/quic-go/quic-go\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"golang.org/x/net/nettest\"\n\n\t\"github.com/cloudflare/cloudflared/client\"\n\t\"github.com/cloudflare/cloudflared/config\"\n\tcfdflow \"github.com/cloudflare/cloudflared/flow\"\n\n\t\"github.com/cloudflare/cloudflared/datagramsession\"\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\t\"github.com/cloudflare/cloudflared/packet\"\n\tcfdquic \"github.com/cloudflare/cloudflared/quic\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n\trpcquic \"github.com/cloudflare/cloudflared/tunnelrpc/quic\"\n)\n\nvar (\n\ttestTLSServerConfig = GenerateTLSConfig()\n\ttestQUICConfig      = &quic.Config{\n\t\tKeepAlivePeriod: 5 * time.Second,\n\t\tEnableDatagrams: true,\n\t}\n\tdefaultQUICTimeout = 30 * time.Second\n)\n\nvar _ ReadWriteAcker = (*streamReadWriteAcker)(nil)\n\n// TestQUICServer tests if a quic server accepts and responds to a quic client with the acceptance protocol.\n// It also serves as a demonstration for communication with the QUIC connection started by a cloudflared.\nfunc TestQUICServer(t *testing.T) {\n\t// This is simply a sample websocket frame message.\n\twsBuf := &bytes.Buffer{}\n\terr := wsutil.WriteClientBinary(wsBuf, []byte(\"Hello\"))\n\trequire.NoError(t, err)\n\n\ttests := []struct {\n\t\tdesc             string\n\t\tdest             string\n\t\tconnectionType   pogs.ConnectionType\n\t\tmetadata         []pogs.Metadata\n\t\tmessage          []byte\n\t\texpectedResponse []byte\n\t}{\n\t\t{\n\t\t\tdesc:           \"test http proxy\",\n\t\t\tdest:           \"/ok\",\n\t\t\tconnectionType: pogs.ConnectionTypeHTTP,\n\t\t\tmetadata: []pogs.Metadata{\n\t\t\t\t{\n\t\t\t\t\tKey: \"HttpHeader:Cf-Ray\",\n\t\t\t\t\tVal: \"123123123\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tKey: \"HttpHost\",\n\t\t\t\t\tVal: \"cf.host\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tKey: \"HttpMethod\",\n\t\t\t\t\tVal: \"GET\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpectedResponse: []byte(\"OK\"),\n\t\t},\n\t\t{\n\t\t\tdesc:           \"test http body request streaming\",\n\t\t\tdest:           \"/slow_echo_body\",\n\t\t\tconnectionType: pogs.ConnectionTypeHTTP,\n\t\t\tmetadata: []pogs.Metadata{\n\t\t\t\t{\n\t\t\t\t\tKey: \"HttpHeader:Cf-Ray\",\n\t\t\t\t\tVal: \"123123123\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tKey: \"HttpHost\",\n\t\t\t\t\tVal: \"cf.host\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tKey: \"HttpMethod\",\n\t\t\t\t\tVal: \"POST\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tKey: \"HttpHeader:Content-Length\",\n\t\t\t\t\tVal: \"24\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tmessage:          []byte(\"This is the message body\"),\n\t\t\texpectedResponse: []byte(\"This is the message body\"),\n\t\t},\n\t\t{\n\t\t\tdesc:           \"test ws proxy\",\n\t\t\tdest:           \"/ws/echo\",\n\t\t\tconnectionType: pogs.ConnectionTypeWebsocket,\n\t\t\tmetadata: []pogs.Metadata{\n\t\t\t\t{\n\t\t\t\t\tKey: \"HttpHeader:Cf-Cloudflared-Proxy-Connection-Upgrade\",\n\t\t\t\t\tVal: \"Websocket\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tKey: \"HttpHeader:Another-Header\",\n\t\t\t\t\tVal: \"Misc\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tKey: \"HttpHost\",\n\t\t\t\t\tVal: \"cf.host\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tKey: \"HttpMethod\",\n\t\t\t\t\tVal: \"get\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tmessage:          wsBuf.Bytes(),\n\t\t\texpectedResponse: []byte{0x82, 0x5, 0x48, 0x65, 0x6c, 0x6c, 0x6f},\n\t\t},\n\t\t{\n\t\t\tdesc:             \"test tcp proxy\",\n\t\t\tconnectionType:   pogs.ConnectionTypeTCP,\n\t\t\tmetadata:         []pogs.Metadata{},\n\t\t\tmessage:          []byte(\"Here is some tcp data\"),\n\t\t\texpectedResponse: []byte(\"Here is some tcp data\"),\n\t\t},\n\t}\n\n\tfor i, test := range tests {\n\t\tt.Run(test.desc, func(t *testing.T) {\n\t\t\tctx, cancel := context.WithCancel(t.Context())\n\t\t\t// Start a UDP Listener for QUIC.\n\t\t\tudpAddr, err := net.ResolveUDPAddr(\"udp\", \"127.0.0.1:0\")\n\t\t\trequire.NoError(t, err)\n\t\t\tudpListener, err := net.ListenUDP(udpAddr.Network(), udpAddr)\n\t\t\trequire.NoError(t, err)\n\t\t\tdefer udpListener.Close()\n\t\t\tquicTransport := &quic.Transport{Conn: udpListener, ConnectionIDLength: 16}\n\t\t\tquicListener, err := quicTransport.Listen(testTLSServerConfig, testQUICConfig)\n\t\t\trequire.NoError(t, err)\n\n\t\t\tserverDone := make(chan struct{})\n\t\t\tgo func() {\n\t\t\t\t// nolint: testifylint\n\t\t\t\tquicServer(\n\t\t\t\t\tctx, t, quicListener, test.dest, test.connectionType, test.metadata, test.message, test.expectedResponse,\n\t\t\t\t)\n\t\t\t\tclose(serverDone)\n\t\t\t}()\n\n\t\t\t// nolint: gosec\n\t\t\ttunnelConn, _ := testTunnelConnection(t, netip.MustParseAddrPort(udpListener.LocalAddr().String()), uint8(i))\n\n\t\t\tconnDone := make(chan struct{})\n\t\t\tgo func() {\n\t\t\t\t_ = tunnelConn.Serve(ctx)\n\t\t\t\tclose(connDone)\n\t\t\t}()\n\n\t\t\t<-serverDone\n\t\t\tcancel()\n\t\t\t<-connDone\n\t\t})\n\t}\n}\n\ntype fakeControlStream struct {\n\tControlStreamHandler\n}\n\nfunc (fakeControlStream) ServeControlStream(ctx context.Context, rw io.ReadWriteCloser, connOptions *pogs.ConnectionOptions, tunnelConfigGetter TunnelConfigJSONGetter) error {\n\t<-ctx.Done()\n\treturn nil\n}\n\nfunc (fakeControlStream) IsStopped() bool {\n\treturn true\n}\n\nfunc quicServer(\n\tctx context.Context,\n\tt *testing.T,\n\tlistener *quic.Listener,\n\tdest string,\n\tconnectionType pogs.ConnectionType,\n\tmetadata []pogs.Metadata,\n\tmessage []byte,\n\texpectedResponse []byte,\n) {\n\tsession, err := listener.Accept(ctx)\n\trequire.NoError(t, err)\n\n\tquicStream, err := session.OpenStreamSync(t.Context())\n\trequire.NoError(t, err)\n\tstream := cfdquic.NewSafeStreamCloser(quicStream, defaultQUICTimeout, &log)\n\n\treqClientStream := rpcquic.RequestClientStream{ReadWriteCloser: stream}\n\terr = reqClientStream.WriteConnectRequestData(dest, connectionType, metadata...)\n\trequire.NoError(t, err)\n\n\t_, err = reqClientStream.ReadConnectResponseData()\n\trequire.NoError(t, err)\n\n\tif message != nil {\n\t\t// ALPN successful. Write data.\n\t\t_, err := stream.Write(message)\n\t\trequire.NoError(t, err)\n\t}\n\n\tresponse := make([]byte, len(expectedResponse))\n\t_, err = stream.Read(response)\n\tif err != io.EOF {\n\t\trequire.NoError(t, err)\n\t}\n\n\t// For now it is an echo server. Verify if the same data is returned.\n\tassert.Equal(t, expectedResponse, response)\n}\n\ntype mockOriginProxyWithRequest struct{}\n\nfunc (moc *mockOriginProxyWithRequest) ProxyHTTP(w ResponseWriter, tr *tracing.TracedHTTPRequest, isWebsocket bool) error {\n\t// These are a series of crude tests to ensure the headers and http related data is transferred from\n\t// metadata.\n\tr := tr.Request\n\tif r.Method == \"\" {\n\t\treturn errors.New(\"method not sent\")\n\t}\n\tif r.Host == \"\" {\n\t\treturn errors.New(\"host not sent\")\n\t}\n\tif len(r.Header) == 0 {\n\t\treturn errors.New(\"headers not set\")\n\t}\n\n\tif isWebsocket {\n\t\treturn wsEchoEndpoint(w, r)\n\t}\n\tswitch r.URL.Path {\n\tcase \"/ok\":\n\t\toriginRespEndpoint(w, http.StatusOK, []byte(http.StatusText(http.StatusOK)))\n\tcase \"/slow_echo_body\":\n\t\ttime.Sleep(5 * time.Nanosecond)\n\t\tfallthrough\n\tcase \"/echo_body\":\n\t\tresp := &http.Response{\n\t\t\tStatusCode: http.StatusOK,\n\t\t}\n\t\t_ = w.WriteRespHeaders(resp.StatusCode, resp.Header)\n\t\t_, _ = io.Copy(w, r.Body)\n\tcase \"/error\":\n\t\treturn fmt.Errorf(\"Failed to proxy to origin\")\n\tdefault:\n\t\toriginRespEndpoint(w, http.StatusNotFound, []byte(\"page not found\"))\n\t}\n\treturn nil\n}\n\nfunc TestBuildHTTPRequest(t *testing.T) {\n\ttests := []struct {\n\t\tname           string\n\t\tconnectRequest *pogs.ConnectRequest\n\t\tbody           io.ReadCloser\n\t\treq            *http.Request\n\t}{\n\t\t{\n\t\t\tname: \"check if http.Request is built correctly with content length\",\n\t\t\tconnectRequest: &pogs.ConnectRequest{\n\t\t\t\tDest: \"http://test.com\",\n\t\t\t\tMetadata: []pogs.Metadata{\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpHeader:Cf-Cloudflared-Proxy-Connection-Upgrade\",\n\t\t\t\t\t\tVal: \"Websocket\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpHeader:Content-Length\",\n\t\t\t\t\t\tVal: \"514\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpHeader:Another-Header\",\n\t\t\t\t\t\tVal: \"Misc\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpHost\",\n\t\t\t\t\t\tVal: \"cf.host\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpMethod\",\n\t\t\t\t\t\tVal: \"get\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\treq: &http.Request{\n\t\t\t\tMethod: \"get\",\n\t\t\t\tURL: &url.URL{\n\t\t\t\t\tScheme: \"http\",\n\t\t\t\t\tHost:   \"test.com\",\n\t\t\t\t},\n\t\t\t\tProto:      \"HTTP/1.1\",\n\t\t\t\tProtoMajor: 1,\n\t\t\t\tProtoMinor: 1,\n\t\t\t\tHeader: http.Header{\n\t\t\t\t\t\"Another-Header\": []string{\"Misc\"},\n\t\t\t\t\t\"Content-Length\": []string{\"514\"},\n\t\t\t\t},\n\t\t\t\tContentLength: 514,\n\t\t\t\tHost:          \"cf.host\",\n\t\t\t\tBody:          io.NopCloser(&bytes.Buffer{}),\n\t\t\t},\n\t\t\tbody: io.NopCloser(&bytes.Buffer{}),\n\t\t},\n\t\t{\n\t\t\tname: \"if content length isn't part of request headers, then it's not set\",\n\t\t\tconnectRequest: &pogs.ConnectRequest{\n\t\t\t\tDest: \"http://test.com\",\n\t\t\t\tMetadata: []pogs.Metadata{\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpHeader:Cf-Cloudflared-Proxy-Connection-Upgrade\",\n\t\t\t\t\t\tVal: \"Websocket\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpHeader:Another-Header\",\n\t\t\t\t\t\tVal: \"Misc\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpHost\",\n\t\t\t\t\t\tVal: \"cf.host\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpMethod\",\n\t\t\t\t\t\tVal: \"get\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\treq: &http.Request{\n\t\t\t\tMethod: \"get\",\n\t\t\t\tURL: &url.URL{\n\t\t\t\t\tScheme: \"http\",\n\t\t\t\t\tHost:   \"test.com\",\n\t\t\t\t},\n\t\t\t\tProto:      \"HTTP/1.1\",\n\t\t\t\tProtoMajor: 1,\n\t\t\t\tProtoMinor: 1,\n\t\t\t\tHeader: http.Header{\n\t\t\t\t\t\"Another-Header\": []string{\"Misc\"},\n\t\t\t\t},\n\t\t\t\tContentLength: 0,\n\t\t\t\tHost:          \"cf.host\",\n\t\t\t\tBody:          http.NoBody,\n\t\t\t},\n\t\t\tbody: io.NopCloser(&bytes.Buffer{}),\n\t\t},\n\t\t{\n\t\t\tname: \"if content length is 0, but transfer-encoding is chunked, body is not nil\",\n\t\t\tconnectRequest: &pogs.ConnectRequest{\n\t\t\t\tDest: \"http://test.com\",\n\t\t\t\tMetadata: []pogs.Metadata{\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpHeader:Another-Header\",\n\t\t\t\t\t\tVal: \"Misc\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpHeader:Transfer-Encoding\",\n\t\t\t\t\t\tVal: \"chunked\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpHost\",\n\t\t\t\t\t\tVal: \"cf.host\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpMethod\",\n\t\t\t\t\t\tVal: \"get\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\treq: &http.Request{\n\t\t\t\tMethod: \"get\",\n\t\t\t\tURL: &url.URL{\n\t\t\t\t\tScheme: \"http\",\n\t\t\t\t\tHost:   \"test.com\",\n\t\t\t\t},\n\t\t\t\tProto:      \"HTTP/1.1\",\n\t\t\t\tProtoMajor: 1,\n\t\t\t\tProtoMinor: 1,\n\t\t\t\tHeader: http.Header{\n\t\t\t\t\t\"Another-Header\":    []string{\"Misc\"},\n\t\t\t\t\t\"Transfer-Encoding\": []string{\"chunked\"},\n\t\t\t\t},\n\t\t\t\tContentLength: 0,\n\t\t\t\tHost:          \"cf.host\",\n\t\t\t\tBody:          io.NopCloser(&bytes.Buffer{}),\n\t\t\t},\n\t\t\tbody: io.NopCloser(&bytes.Buffer{}),\n\t\t},\n\t\t{\n\t\t\tname: \"if content length is 0, but transfer-encoding is gzip,chunked, body is not nil\",\n\t\t\tconnectRequest: &pogs.ConnectRequest{\n\t\t\t\tDest: \"http://test.com\",\n\t\t\t\tMetadata: []pogs.Metadata{\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpHeader:Another-Header\",\n\t\t\t\t\t\tVal: \"Misc\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpHeader:Transfer-Encoding\",\n\t\t\t\t\t\tVal: \"gzip,chunked\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpHost\",\n\t\t\t\t\t\tVal: \"cf.host\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpMethod\",\n\t\t\t\t\t\tVal: \"get\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\treq: &http.Request{\n\t\t\t\tMethod: \"get\",\n\t\t\t\tURL: &url.URL{\n\t\t\t\t\tScheme: \"http\",\n\t\t\t\t\tHost:   \"test.com\",\n\t\t\t\t},\n\t\t\t\tProto:      \"HTTP/1.1\",\n\t\t\t\tProtoMajor: 1,\n\t\t\t\tProtoMinor: 1,\n\t\t\t\tHeader: http.Header{\n\t\t\t\t\t\"Another-Header\":    []string{\"Misc\"},\n\t\t\t\t\t\"Transfer-Encoding\": []string{\"gzip,chunked\"},\n\t\t\t\t},\n\t\t\t\tContentLength: 0,\n\t\t\t\tHost:          \"cf.host\",\n\t\t\t\tBody:          io.NopCloser(&bytes.Buffer{}),\n\t\t\t},\n\t\t\tbody: io.NopCloser(&bytes.Buffer{}),\n\t\t},\n\t\t{\n\t\t\tname: \"if content length is 0, and connect request is a websocket, body is not nil\",\n\t\t\tconnectRequest: &pogs.ConnectRequest{\n\t\t\t\tType: pogs.ConnectionTypeWebsocket,\n\t\t\t\tDest: \"http://test.com\",\n\t\t\t\tMetadata: []pogs.Metadata{\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpHeader:Another-Header\",\n\t\t\t\t\t\tVal: \"Misc\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpHost\",\n\t\t\t\t\t\tVal: \"cf.host\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tKey: \"HttpMethod\",\n\t\t\t\t\t\tVal: \"get\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\treq: &http.Request{\n\t\t\t\tMethod: \"get\",\n\t\t\t\tURL: &url.URL{\n\t\t\t\t\tScheme: \"http\",\n\t\t\t\t\tHost:   \"test.com\",\n\t\t\t\t},\n\t\t\t\tProto:      \"HTTP/1.1\",\n\t\t\t\tProtoMajor: 1,\n\t\t\t\tProtoMinor: 1,\n\t\t\t\tHeader: http.Header{\n\t\t\t\t\t\"Another-Header\": []string{\"Misc\"},\n\t\t\t\t},\n\t\t\t\tContentLength: 0,\n\t\t\t\tHost:          \"cf.host\",\n\t\t\t\tBody:          io.NopCloser(&bytes.Buffer{}),\n\t\t\t},\n\t\t\tbody: io.NopCloser(&bytes.Buffer{}),\n\t\t},\n\t}\n\n\tlog := zerolog.Nop()\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\treq, err := buildHTTPRequest(t.Context(), test.connectRequest, test.body, 0, &log)\n\t\t\trequire.NoError(t, err)\n\t\t\ttest.req = test.req.WithContext(req.Context())\n\t\t\trequire.Equal(t, test.req, req.Request)\n\t\t})\n\t}\n}\n\nfunc (moc *mockOriginProxyWithRequest) ProxyTCP(ctx context.Context, rwa ReadWriteAcker, tcpRequest *TCPRequest) error {\n\tif tcpRequest.Dest == \"rate-limit-me\" {\n\t\treturn pkgerrors.Wrap(cfdflow.ErrTooManyActiveFlows, \"failed tcp stream\")\n\t}\n\n\t_ = rwa.AckConnection(\"\")\n\t_, _ = io.Copy(rwa, rwa)\n\treturn nil\n}\n\nfunc TestServeUDPSession(t *testing.T) {\n\t// Start a UDP Listener for QUIC.\n\tudpAddr, err := net.ResolveUDPAddr(\"udp\", \"127.0.0.1:0\")\n\trequire.NoError(t, err)\n\tudpListener, err := net.ListenUDP(udpAddr.Network(), udpAddr)\n\trequire.NoError(t, err)\n\tdefer udpListener.Close()\n\n\tctx, cancel := context.WithCancel(t.Context())\n\n\t// Establish QUIC connection with edge\n\tedgeQUICSessionChan := make(chan quic.Connection)\n\tgo func() {\n\t\tearlyListener, err := quic.Listen(udpListener, testTLSServerConfig, testQUICConfig)\n\t\tassert.NoError(t, err)\n\n\t\tedgeQUICSession, err := earlyListener.Accept(ctx)\n\t\tassert.NoError(t, err)\n\n\t\tedgeQUICSessionChan <- edgeQUICSession\n\t}()\n\n\t// Random index to avoid reusing port\n\ttunnelConn, datagramConn := testTunnelConnection(t, netip.MustParseAddrPort(udpListener.LocalAddr().String()), 28)\n\tgo func() {\n\t\t_ = tunnelConn.Serve(ctx)\n\t}()\n\n\tedgeQUICSession := <-edgeQUICSessionChan\n\n\tserveSession(ctx, datagramConn, edgeQUICSession, closedByOrigin, io.EOF.Error(), t)\n\tserveSession(ctx, datagramConn, edgeQUICSession, closedByTimeout, datagramsession.SessionIdleErr(time.Millisecond*50).Error(), t)\n\tserveSession(ctx, datagramConn, edgeQUICSession, closedByRemote, \"eyeball closed connection\", t)\n\tcancel()\n}\n\nfunc TestNopCloserReadWriterCloseBeforeEOF(t *testing.T) {\n\treaderWriter := nopCloserReadWriter{ReadWriteCloser: &mockReaderNoopWriter{Reader: strings.NewReader(\"123456789\")}}\n\tbuffer := make([]byte, 5)\n\n\tn, err := readerWriter.Read(buffer)\n\trequire.NoError(t, err)\n\trequire.Equal(t, 5, n)\n\n\t// close\n\trequire.NoError(t, readerWriter.Close())\n\n\t// read should get error\n\tn, err = readerWriter.Read(buffer)\n\trequire.Equal(t, 0, n)\n\trequire.Equal(t, err, fmt.Errorf(\"closed by handler\"))\n}\n\nfunc TestNopCloserReadWriterCloseAfterEOF(t *testing.T) {\n\treaderWriter := nopCloserReadWriter{ReadWriteCloser: &mockReaderNoopWriter{Reader: strings.NewReader(\"123456789\")}}\n\tbuffer := make([]byte, 20)\n\n\tn, err := readerWriter.Read(buffer)\n\trequire.NoError(t, err)\n\trequire.Equal(t, 9, n)\n\n\t// force another read to read eof\n\t_, err = readerWriter.Read(buffer)\n\trequire.Equal(t, err, io.EOF)\n\n\t// close\n\trequire.NoError(t, readerWriter.Close())\n\n\t// read should get EOF still\n\tn, err = readerWriter.Read(buffer)\n\trequire.Equal(t, 0, n)\n\trequire.Equal(t, err, io.EOF)\n}\n\nfunc TestCreateUDPConnReuseSourcePort(t *testing.T) {\n\tedgeIPv4 := netip.MustParseAddrPort(\"0.0.0.0:0\")\n\tedgeIPv6 := netip.MustParseAddrPort(\"[::]:0\")\n\n\t// We assume the test environment has access to an IPv4 interface\n\ttestCreateUDPConnReuseSourcePortForEdgeIP(t, edgeIPv4)\n\n\tif nettest.SupportsIPv6() {\n\t\ttestCreateUDPConnReuseSourcePortForEdgeIP(t, edgeIPv6)\n\t}\n}\n\n// TestTCPProxy_FlowRateLimited tests if the pogs.ConnectResponse returns the expected error and metadata, when a\n// new flow is rate limited.\nfunc TestTCPProxy_FlowRateLimited(t *testing.T) {\n\tctx, cancel := context.WithCancel(t.Context())\n\n\t// Start a UDP Listener for QUIC.\n\tudpAddr, err := net.ResolveUDPAddr(\"udp\", \"127.0.0.1:0\")\n\trequire.NoError(t, err)\n\n\tudpListener, err := net.ListenUDP(udpAddr.Network(), udpAddr)\n\trequire.NoError(t, err)\n\tdefer udpListener.Close()\n\n\tquicTransport := &quic.Transport{Conn: udpListener, ConnectionIDLength: 16}\n\tquicListener, err := quicTransport.Listen(testTLSServerConfig, testQUICConfig)\n\trequire.NoError(t, err)\n\n\tserverDone := make(chan struct{})\n\tgo func() {\n\t\tdefer close(serverDone)\n\n\t\tsession, err := quicListener.Accept(ctx)\n\t\tassert.NoError(t, err)\n\n\t\tquicStream, err := session.OpenStreamSync(t.Context())\n\t\tassert.NoError(t, err)\n\t\tstream := cfdquic.NewSafeStreamCloser(quicStream, defaultQUICTimeout, &log)\n\n\t\treqClientStream := rpcquic.RequestClientStream{ReadWriteCloser: stream}\n\t\terr = reqClientStream.WriteConnectRequestData(\"rate-limit-me\", pogs.ConnectionTypeTCP)\n\t\tassert.NoError(t, err)\n\n\t\tresponse, err := reqClientStream.ReadConnectResponseData()\n\t\tassert.NoError(t, err)\n\n\t\t// Got Rate Limited\n\t\tassert.NotEmpty(t, response.Error)\n\t\tassert.Contains(t, response.Metadata, pogs.ErrorFlowConnectRateLimitedMetadata)\n\t}()\n\n\ttunnelConn, _ := testTunnelConnection(t, netip.MustParseAddrPort(udpListener.LocalAddr().String()), uint8(0))\n\n\tconnDone := make(chan struct{})\n\tgo func() {\n\t\tdefer close(connDone)\n\t\t_ = tunnelConn.Serve(ctx)\n\t}()\n\n\t<-serverDone\n\tcancel()\n\t<-connDone\n}\n\nfunc testCreateUDPConnReuseSourcePortForEdgeIP(t *testing.T, edgeIP netip.AddrPort) {\n\tlogger := zerolog.Nop()\n\tconn, err := createUDPConnForConnIndex(0, nil, edgeIP, &logger)\n\trequire.NoError(t, err)\n\n\tgetPortFunc := func(conn *net.UDPConn) int {\n\t\taddr := conn.LocalAddr().(*net.UDPAddr)\n\t\treturn addr.Port\n\t}\n\n\tinitialPort := getPortFunc(conn)\n\n\t// close conn\n\tconn.Close()\n\n\t// should get the same port as before.\n\tconn, err = createUDPConnForConnIndex(0, nil, edgeIP, &logger)\n\trequire.NoError(t, err)\n\trequire.Equal(t, initialPort, getPortFunc(conn))\n\n\t// new index, should get a different port\n\tconn1, err := createUDPConnForConnIndex(1, nil, edgeIP, &logger)\n\trequire.NoError(t, err)\n\trequire.NotEqual(t, initialPort, getPortFunc(conn1))\n\n\t// not closing the conn and trying to obtain a new conn for same index should give a different random port\n\tconn, err = createUDPConnForConnIndex(0, nil, edgeIP, &logger)\n\trequire.NoError(t, err)\n\trequire.NotEqual(t, initialPort, getPortFunc(conn))\n}\n\nfunc serveSession(ctx context.Context, datagramConn *datagramV2Connection, edgeQUICSession quic.Connection, closeType closeReason, expectedReason string, t *testing.T) {\n\tpayload := []byte(t.Name())\n\tsessionID := uuid.New()\n\tcfdConn, originConn := net.Pipe()\n\t// Registers and run a new session\n\tsession, err := datagramConn.sessionManager.RegisterSession(ctx, sessionID, cfdConn)\n\trequire.NoError(t, err)\n\n\tsessionDone := make(chan struct{})\n\tgo func() {\n\t\tdatagramConn.serveUDPSession(session, time.Millisecond*50)\n\t\tclose(sessionDone)\n\t}()\n\n\t// Send a message to the quic session on edge side, it should be deumx to this datagram v2 session\n\tmuxedPayload, err := cfdquic.SuffixSessionID(sessionID, payload)\n\trequire.NoError(t, err)\n\tmuxedPayload, err = cfdquic.SuffixType(muxedPayload, cfdquic.DatagramTypeUDP)\n\trequire.NoError(t, err)\n\n\terr = edgeQUICSession.SendDatagram(muxedPayload)\n\trequire.NoError(t, err)\n\n\treadBuffer := make([]byte, len(payload)+1)\n\tn, err := originConn.Read(readBuffer)\n\trequire.NoError(t, err)\n\trequire.Equal(t, len(payload), n)\n\trequire.True(t, bytes.Equal(payload, readBuffer[:n]))\n\n\t// Close connection to terminate session\n\tswitch closeType {\n\tcase closedByOrigin:\n\t\toriginConn.Close()\n\tcase closedByRemote:\n\t\terr = datagramConn.UnregisterUdpSession(ctx, sessionID, expectedReason)\n\t\trequire.NoError(t, err)\n\tcase closedByTimeout:\n\t}\n\n\tif closeType != closedByRemote {\n\t\t// Session was not closed by remote, so closeUDPSession should be invoked to unregister from remote\n\t\tunregisterFromEdgeChan := make(chan struct{})\n\t\tsessionRPCServer := &mockSessionRPCServer{\n\t\t\tsessionID:            sessionID,\n\t\t\tunregisterReason:     expectedReason,\n\t\t\tcalledUnregisterChan: unregisterFromEdgeChan,\n\t\t}\n\t\t// nolint: testifylint\n\t\tgo runRPCServer(ctx, edgeQUICSession, sessionRPCServer, nil, t)\n\n\t\t<-unregisterFromEdgeChan\n\t}\n\n\t<-sessionDone\n}\n\ntype closeReason uint8\n\nconst (\n\tclosedByOrigin closeReason = iota\n\tclosedByRemote\n\tclosedByTimeout\n)\n\nfunc runRPCServer(ctx context.Context, session quic.Connection, sessionRPCServer pogs.SessionManager, configRPCServer pogs.ConfigurationManager, t *testing.T) {\n\tstream, err := session.AcceptStream(ctx)\n\trequire.NoError(t, err)\n\n\tif stream.StreamID() == 0 {\n\t\t// Skip the first stream, it's the control stream of the QUIC connection\n\t\tstream, err = session.AcceptStream(ctx)\n\t\trequire.NoError(t, err)\n\t}\n\tss := rpcquic.NewCloudflaredServer(\n\t\tfunc(_ context.Context, _ *rpcquic.RequestServerStream) error {\n\t\t\treturn nil\n\t\t},\n\t\tsessionRPCServer,\n\t\tconfigRPCServer,\n\t\t10*time.Second,\n\t)\n\terr = ss.Serve(ctx, stream)\n\tassert.NoError(t, err)\n}\n\ntype mockSessionRPCServer struct {\n\tsessionID            uuid.UUID\n\tunregisterReason     string\n\tcalledUnregisterChan chan struct{}\n}\n\nfunc (s mockSessionRPCServer) RegisterUdpSession(ctx context.Context, sessionID uuid.UUID, dstIP net.IP, dstPort uint16, closeIdleAfter time.Duration, traceContext string) (*pogs.RegisterUdpSessionResponse, error) {\n\treturn nil, fmt.Errorf(\"mockSessionRPCServer doesn't implement RegisterUdpSession\")\n}\n\nfunc (s mockSessionRPCServer) UnregisterUdpSession(ctx context.Context, sessionID uuid.UUID, reason string) error {\n\tif s.sessionID != sessionID {\n\t\treturn fmt.Errorf(\"expect session ID %s, got %s\", s.sessionID, sessionID)\n\t}\n\tif s.unregisterReason != reason {\n\t\treturn fmt.Errorf(\"expect unregister reason %s, got %s\", s.unregisterReason, reason)\n\t}\n\tclose(s.calledUnregisterChan)\n\treturn nil\n}\n\nfunc testTunnelConnection(t *testing.T, serverAddr netip.AddrPort, index uint8) (TunnelConnection, *datagramV2Connection) {\n\ttlsClientConfig := &tls.Config{\n\t\t// nolint: gosec\n\t\tInsecureSkipVerify: true,\n\t\tNextProtos:         []string{\"argotunnel\"},\n\t}\n\t// Start a mock httpProxy\n\tlog := zerolog.New(io.Discard)\n\tctx, cancel := context.WithCancel(t.Context())\n\tdefer cancel()\n\n\t// Dial the QUIC connection to the edge\n\tconn, err := DialQuic(\n\t\tctx,\n\t\ttestQUICConfig,\n\t\ttlsClientConfig,\n\t\tserverAddr,\n\t\tnil, // connect on a random port\n\t\tindex,\n\t\t&log,\n\t)\n\trequire.NoError(t, err)\n\n\t// Start a session manager for the connection\n\tsessionDemuxChan := make(chan *packet.Session, 4)\n\tdatagramMuxer := cfdquic.NewDatagramMuxerV2(conn, &log, sessionDemuxChan)\n\tsessionManager := datagramsession.NewManager(&log, datagramMuxer.SendToSession, sessionDemuxChan)\n\tvar connIndex uint8 = 0\n\tpacketRouter := ingress.NewPacketRouter(nil, datagramMuxer, connIndex, &log)\n\ttestDefaultDialer := ingress.NewDialer(ingress.WarpRoutingConfig{\n\t\tConnectTimeout: config.CustomDuration{Duration: 1 * time.Second},\n\t\tTCPKeepAlive:   config.CustomDuration{Duration: 15 * time.Second},\n\t\tMaxActiveFlows: 0,\n\t})\n\toriginDialer := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 1 * time.Second,\n\t}, &log)\n\n\tdatagramConn := &datagramV2Connection{\n\t\tconn,\n\t\tindex,\n\t\tsessionManager,\n\t\tcfdflow.NewLimiter(0),\n\t\tdatagramMuxer,\n\t\toriginDialer,\n\t\tpacketRouter,\n\t\t15 * time.Second,\n\t\t0 * time.Second,\n\t\t&log,\n\t}\n\n\ttunnelConn := NewTunnelConnection(\n\t\tctx,\n\t\tconn,\n\t\tindex,\n\t\t&mockOrchestrator{originProxy: &mockOriginProxyWithRequest{}},\n\t\tdatagramConn,\n\t\tfakeControlStream{},\n\t\t&client.ConnectionOptionsSnapshot{},\n\t\t15*time.Second,\n\t\t0*time.Second,\n\t\t0*time.Second,\n\t\t&log,\n\t)\n\treturn tunnelConn, datagramConn\n}\n\ntype mockReaderNoopWriter struct {\n\tio.Reader\n}\n\nfunc (m *mockReaderNoopWriter) Write(p []byte) (n int, err error) {\n\treturn len(p), nil\n}\n\nfunc (m *mockReaderNoopWriter) Close() error {\n\treturn nil\n}\n\n// GenerateTLSConfig sets up a bare-bones TLS config for a QUIC server\nfunc GenerateTLSConfig() *tls.Config {\n\t// nolint: gosec\n\tkey, err := rsa.GenerateKey(rand.Reader, 1024)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\ttemplate := x509.Certificate{SerialNumber: big.NewInt(1)}\n\tcertDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tkeyPEM := pem.EncodeToMemory(&pem.Block{Type: \"RSA PRIVATE KEY\", Bytes: x509.MarshalPKCS1PrivateKey(key)})\n\tcertPEM := pem.EncodeToMemory(&pem.Block{Type: \"CERTIFICATE\", Bytes: certDER})\n\n\ttlsCert, err := tls.X509KeyPair(certPEM, keyPEM)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\t// nolint: gosec\n\treturn &tls.Config{\n\t\tCertificates: []tls.Certificate{tlsCert},\n\t\tNextProtos:   []string{\"argotunnel\"},\n\t}\n}\n"
  },
  {
    "path": "connection/quic_datagram_v2.go",
    "content": "package connection\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/netip\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/pkg/errors\"\n\tpkgerrors \"github.com/pkg/errors\"\n\t\"github.com/quic-go/quic-go\"\n\t\"github.com/rs/zerolog\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/trace\"\n\t\"golang.org/x/sync/errgroup\"\n\n\tcfdflow \"github.com/cloudflare/cloudflared/flow\"\n\n\t\"github.com/cloudflare/cloudflared/datagramsession\"\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\t\"github.com/cloudflare/cloudflared/management\"\n\t\"github.com/cloudflare/cloudflared/packet\"\n\tcfdquic \"github.com/cloudflare/cloudflared/quic\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n\ttunnelpogs \"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n\trpcquic \"github.com/cloudflare/cloudflared/tunnelrpc/quic\"\n)\n\nconst (\n\t// emperically this capacity has been working well\n\tdemuxChanCapacity = 16\n)\n\nvar (\n\terrInvalidDestinationIP = errors.New(\"unable to parse destination IP\")\n)\n\n// DatagramSessionHandler is a service that can serve datagrams for a connection and handle sessions from incoming\n// connection streams.\ntype DatagramSessionHandler interface {\n\tServe(context.Context) error\n\n\tpogs.SessionManager\n}\n\ntype datagramV2Connection struct {\n\tconn  quic.Connection\n\tindex uint8\n\n\t// sessionManager tracks active sessions. It receives datagrams from quic connection via datagramMuxer\n\tsessionManager datagramsession.Manager\n\t// flowLimiter tracks active sessions across the tunnel and limits new sessions if they are above the limit.\n\tflowLimiter cfdflow.Limiter\n\n\t// datagramMuxer mux/demux datagrams from quic connection\n\tdatagramMuxer *cfdquic.DatagramMuxerV2\n\t// originDialer is the origin dialer for UDP requests\n\toriginDialer ingress.OriginUDPDialer\n\t// packetRouter acts as the origin router for ICMP requests\n\tpacketRouter *ingress.PacketRouter\n\n\trpcTimeout         time.Duration\n\tstreamWriteTimeout time.Duration\n\n\tlogger *zerolog.Logger\n}\n\nfunc NewDatagramV2Connection(ctx context.Context,\n\tconn quic.Connection,\n\toriginDialer ingress.OriginUDPDialer,\n\ticmpRouter ingress.ICMPRouter,\n\tindex uint8,\n\trpcTimeout time.Duration,\n\tstreamWriteTimeout time.Duration,\n\tflowLimiter cfdflow.Limiter,\n\tlogger *zerolog.Logger,\n) DatagramSessionHandler {\n\tsessionDemuxChan := make(chan *packet.Session, demuxChanCapacity)\n\tdatagramMuxer := cfdquic.NewDatagramMuxerV2(conn, logger, sessionDemuxChan)\n\tsessionManager := datagramsession.NewManager(logger, datagramMuxer.SendToSession, sessionDemuxChan)\n\tpacketRouter := ingress.NewPacketRouter(icmpRouter, datagramMuxer, index, logger)\n\n\treturn &datagramV2Connection{\n\t\tconn:               conn,\n\t\tindex:              index,\n\t\tsessionManager:     sessionManager,\n\t\tflowLimiter:        flowLimiter,\n\t\tdatagramMuxer:      datagramMuxer,\n\t\toriginDialer:       originDialer,\n\t\tpacketRouter:       packetRouter,\n\t\trpcTimeout:         rpcTimeout,\n\t\tstreamWriteTimeout: streamWriteTimeout,\n\t\tlogger:             logger,\n\t}\n}\n\nfunc (d *datagramV2Connection) Serve(ctx context.Context) error {\n\t// If either goroutine from the errgroup returns at all (error or nil), we rely on its cancellation to make sure\n\t// the other goroutines as well.\n\terrGroup, ctx := errgroup.WithContext(ctx)\n\n\terrGroup.Go(func() error {\n\t\treturn d.sessionManager.Serve(ctx)\n\t})\n\terrGroup.Go(func() error {\n\t\treturn d.datagramMuxer.ServeReceive(ctx)\n\t})\n\terrGroup.Go(func() error {\n\t\treturn d.packetRouter.Serve(ctx)\n\t})\n\n\treturn errGroup.Wait()\n}\n\n// RegisterUdpSession is the RPC method invoked by edge to register and run a session\nfunc (q *datagramV2Connection) RegisterUdpSession(ctx context.Context, sessionID uuid.UUID, dstIP net.IP, dstPort uint16, closeAfterIdleHint time.Duration, traceContext string) (*tunnelpogs.RegisterUdpSessionResponse, error) {\n\ttraceCtx := tracing.NewTracedContext(ctx, traceContext, q.logger)\n\tctx, registerSpan := traceCtx.Tracer().Start(traceCtx, \"register-session\", trace.WithAttributes(\n\t\tattribute.String(\"session-id\", sessionID.String()),\n\t\tattribute.String(\"dst\", fmt.Sprintf(\"%s:%d\", dstIP, dstPort)),\n\t))\n\tlog := q.logger.With().Int(management.EventTypeKey, int(management.UDP)).Logger()\n\n\t// Try to start a new session\n\tif err := q.flowLimiter.Acquire(management.UDP.String()); err != nil {\n\t\tlog.Warn().Msgf(\"Too many concurrent sessions being handled, rejecting udp proxy to %s:%d\", dstIP, dstPort)\n\n\t\terr := pkgerrors.Wrap(err, \"failed to start udp session due to rate limiting\")\n\t\ttracing.EndWithErrorStatus(registerSpan, err)\n\t\treturn nil, err\n\t}\n\t// We need to force the net.IP to IPv4 (if it's an IPv4 address) otherwise the net.IP conversion from capnp\n\t// will be a IPv4-mapped-IPv6 address.\n\t// In the case that the address is IPv6 we leave it untouched and parse it as normal.\n\tip := dstIP.To4()\n\tif ip == nil {\n\t\tip = dstIP\n\t}\n\t// Parse the dstIP and dstPort into a netip.AddrPort\n\t// This should never fail because the IP was already parsed as a valid net.IP\n\tdestAddr, ok := netip.AddrFromSlice(ip)\n\tif !ok {\n\t\tlog.Err(errInvalidDestinationIP).Msgf(\"Failed to parse destination proxy IP: %s\", ip)\n\t\ttracing.EndWithErrorStatus(registerSpan, errInvalidDestinationIP)\n\t\tq.flowLimiter.Release()\n\t\treturn nil, errInvalidDestinationIP\n\t}\n\tdstAddrPort := netip.AddrPortFrom(destAddr, dstPort)\n\n\t// Each session is a series of datagram from an eyeball to a dstIP:dstPort.\n\t// (src port, dst IP, dst port) uniquely identifies a session, so it needs a dedicated connected socket.\n\toriginProxy, err := q.originDialer.DialUDP(dstAddrPort)\n\tif err != nil {\n\t\tlog.Err(err).Msgf(\"Failed to create udp proxy to %s\", dstAddrPort)\n\t\ttracing.EndWithErrorStatus(registerSpan, err)\n\t\tq.flowLimiter.Release()\n\t\treturn nil, err\n\t}\n\tregisterSpan.SetAttributes(\n\t\tattribute.Bool(\"socket-bind-success\", true),\n\t\tattribute.String(\"src\", originProxy.LocalAddr().String()),\n\t)\n\n\tsession, err := q.sessionManager.RegisterSession(ctx, sessionID, originProxy)\n\tif err != nil {\n\t\toriginProxy.Close()\n\t\tlog.Err(err).Str(datagramsession.LogFieldSessionID, datagramsession.FormatSessionID(sessionID)).Msgf(\"Failed to register udp session\")\n\t\ttracing.EndWithErrorStatus(registerSpan, err)\n\t\tq.flowLimiter.Release()\n\t\treturn nil, err\n\t}\n\n\tgo func() {\n\t\tdefer q.flowLimiter.Release() // we do the release here, instead of inside the `serveUDPSession` just to keep all acquire/release calls in the same method.\n\t\tq.serveUDPSession(session, closeAfterIdleHint)\n\t}()\n\n\tlog.Debug().\n\t\tStr(datagramsession.LogFieldSessionID, datagramsession.FormatSessionID(sessionID)).\n\t\tStr(\"src\", originProxy.LocalAddr().String()).\n\t\tStr(\"dst\", fmt.Sprintf(\"%s:%d\", dstIP, dstPort)).\n\t\tMsgf(\"Registered session\")\n\ttracing.End(registerSpan)\n\n\tresp := tunnelpogs.RegisterUdpSessionResponse{\n\t\tSpans: traceCtx.GetProtoSpans(),\n\t}\n\n\treturn &resp, nil\n}\n\n// UnregisterUdpSession is the RPC method invoked by edge to unregister and terminate a sesssion\nfunc (q *datagramV2Connection) UnregisterUdpSession(ctx context.Context, sessionID uuid.UUID, message string) error {\n\treturn q.sessionManager.UnregisterSession(ctx, sessionID, message, true)\n}\n\nfunc (q *datagramV2Connection) serveUDPSession(session *datagramsession.Session, closeAfterIdleHint time.Duration) {\n\tctx := q.conn.Context()\n\tclosedByRemote, err := session.Serve(ctx, closeAfterIdleHint)\n\t// If session is terminated by remote, then we know it has been unregistered from session manager and edge\n\tif !closedByRemote {\n\t\tif err != nil {\n\t\t\tq.closeUDPSession(ctx, session.ID, err.Error())\n\t\t} else {\n\t\t\tq.closeUDPSession(ctx, session.ID, \"terminated without error\")\n\t\t}\n\t}\n\tq.logger.Debug().Err(err).\n\t\tInt(management.EventTypeKey, int(management.UDP)).\n\t\tStr(datagramsession.LogFieldSessionID, datagramsession.FormatSessionID(session.ID)).\n\t\tMsg(\"Session terminated\")\n}\n\n// closeUDPSession first unregisters the session from session manager, then it tries to unregister from edge\nfunc (q *datagramV2Connection) closeUDPSession(ctx context.Context, sessionID uuid.UUID, message string) {\n\t_ = q.sessionManager.UnregisterSession(ctx, sessionID, message, false)\n\tquicStream, err := q.conn.OpenStream()\n\tif err != nil {\n\t\t// Log this at debug because this is not an error if session was closed due to lost connection\n\t\t// with edge\n\t\tq.logger.Debug().Err(err).\n\t\t\tInt(management.EventTypeKey, int(management.UDP)).\n\t\t\tStr(datagramsession.LogFieldSessionID, datagramsession.FormatSessionID(sessionID)).\n\t\t\tMsgf(\"Failed to open quic stream to unregister udp session with edge\")\n\t\treturn\n\t}\n\n\tstream := cfdquic.NewSafeStreamCloser(quicStream, q.streamWriteTimeout, q.logger)\n\tdefer stream.Close()\n\trpcClientStream, err := rpcquic.NewSessionClient(ctx, stream, q.rpcTimeout)\n\tif err != nil {\n\t\t// Log this at debug because this is not an error if session was closed due to lost connection\n\t\t// with edge\n\t\tq.logger.Err(err).Str(datagramsession.LogFieldSessionID, datagramsession.FormatSessionID(sessionID)).\n\t\t\tMsgf(\"Failed to open rpc stream to unregister udp session with edge\")\n\t\treturn\n\t}\n\tdefer rpcClientStream.Close()\n\n\tif err := rpcClientStream.UnregisterUdpSession(ctx, sessionID, message); err != nil {\n\t\tq.logger.Err(err).Str(datagramsession.LogFieldSessionID, datagramsession.FormatSessionID(sessionID)).\n\t\t\tMsgf(\"Failed to unregister udp session with edge\")\n\t}\n}\n"
  },
  {
    "path": "connection/quic_datagram_v2_test.go",
    "content": "package connection\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/quic-go/quic-go\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/require\"\n\t\"go.uber.org/mock/gomock\"\n\n\tcfdflow \"github.com/cloudflare/cloudflared/flow\"\n\t\"github.com/cloudflare/cloudflared/mocks\"\n)\n\ntype mockQuicConnection struct{}\n\nfunc (m *mockQuicConnection) AcceptStream(_ context.Context) (quic.Stream, error) {\n\treturn nil, nil\n}\n\nfunc (m *mockQuicConnection) AcceptUniStream(_ context.Context) (quic.ReceiveStream, error) {\n\treturn nil, nil\n}\n\nfunc (m *mockQuicConnection) OpenStream() (quic.Stream, error) {\n\treturn nil, nil\n}\n\nfunc (m *mockQuicConnection) OpenStreamSync(_ context.Context) (quic.Stream, error) {\n\treturn nil, nil\n}\n\nfunc (m *mockQuicConnection) OpenUniStream() (quic.SendStream, error) {\n\treturn nil, nil\n}\n\nfunc (m *mockQuicConnection) OpenUniStreamSync(_ context.Context) (quic.SendStream, error) {\n\treturn nil, nil\n}\n\nfunc (m *mockQuicConnection) LocalAddr() net.Addr {\n\treturn nil\n}\n\nfunc (m *mockQuicConnection) RemoteAddr() net.Addr {\n\treturn nil\n}\n\nfunc (m *mockQuicConnection) CloseWithError(_ quic.ApplicationErrorCode, s string) error {\n\treturn nil\n}\n\nfunc (m *mockQuicConnection) Context() context.Context {\n\treturn nil\n}\n\nfunc (m *mockQuicConnection) ConnectionState() quic.ConnectionState {\n\tpanic(\"not meant to be called\")\n}\n\nfunc (m *mockQuicConnection) SendDatagram(_ []byte) error {\n\treturn nil\n}\n\nfunc (m *mockQuicConnection) ReceiveDatagram(_ context.Context) ([]byte, error) {\n\treturn nil, nil\n}\n\nfunc (m *mockQuicConnection) AddPath(*quic.Transport) (*quic.Path, error) {\n\treturn nil, nil\n}\n\nfunc TestRateLimitOnNewDatagramV2UDPSession(t *testing.T) {\n\tlog := zerolog.Nop()\n\tconn := &mockQuicConnection{}\n\tctrl := gomock.NewController(t)\n\tflowLimiterMock := mocks.NewMockLimiter(ctrl)\n\n\tdatagramConn := NewDatagramV2Connection(\n\t\tt.Context(),\n\t\tconn,\n\t\tnil,\n\t\tnil,\n\t\t0,\n\t\t0*time.Second,\n\t\t0*time.Second,\n\t\tflowLimiterMock,\n\t\t&log,\n\t)\n\n\tflowLimiterMock.EXPECT().Acquire(\"udp\").Return(cfdflow.ErrTooManyActiveFlows)\n\tflowLimiterMock.EXPECT().Release().Times(0)\n\n\t_, err := datagramConn.RegisterUdpSession(t.Context(), uuid.New(), net.IPv4(0, 0, 0, 0), 1000, 1*time.Second, \"\")\n\trequire.ErrorIs(t, err, cfdflow.ErrTooManyActiveFlows)\n}\n"
  },
  {
    "path": "connection/quic_datagram_v3.go",
    "content": "package connection\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/quic-go/quic-go\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\t\"github.com/cloudflare/cloudflared/management\"\n\tcfdquic \"github.com/cloudflare/cloudflared/quic/v3\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\nvar (\n\tErrUnsupportedRPCUDPRegistration   = errors.New(\"datagram v3 does not support RegisterUdpSession RPC\")\n\tErrUnsupportedRPCUDPUnregistration = errors.New(\"datagram v3 does not support UnregisterUdpSession RPC\")\n)\n\ntype datagramV3Connection struct {\n\tconn  quic.Connection\n\tindex uint8\n\t// datagramMuxer mux/demux datagrams from quic connection\n\tdatagramMuxer cfdquic.DatagramConn\n\tmetrics       cfdquic.Metrics\n\tlogger        *zerolog.Logger\n}\n\nfunc NewDatagramV3Connection(ctx context.Context,\n\tconn quic.Connection,\n\tsessionManager cfdquic.SessionManager,\n\ticmpRouter ingress.ICMPRouter,\n\tindex uint8,\n\tmetrics cfdquic.Metrics,\n\tlogger *zerolog.Logger,\n) DatagramSessionHandler {\n\tlog := logger.\n\t\tWith().\n\t\tInt(management.EventTypeKey, int(management.UDP)).\n\t\tUint8(LogFieldConnIndex, index).\n\t\tLogger()\n\tdatagramMuxer := cfdquic.NewDatagramConn(conn, sessionManager, icmpRouter, index, metrics, &log)\n\n\treturn &datagramV3Connection{\n\t\tconn,\n\t\tindex,\n\t\tdatagramMuxer,\n\t\tmetrics,\n\t\tlogger,\n\t}\n}\n\nfunc (d *datagramV3Connection) Serve(ctx context.Context) error {\n\treturn d.datagramMuxer.Serve(ctx)\n}\n\nfunc (d *datagramV3Connection) RegisterUdpSession(ctx context.Context, sessionID uuid.UUID, dstIP net.IP, dstPort uint16, closeAfterIdleHint time.Duration, traceContext string) (*pogs.RegisterUdpSessionResponse, error) {\n\td.metrics.UnsupportedRemoteCommand(d.index, \"register_udp_session\")\n\treturn nil, ErrUnsupportedRPCUDPRegistration\n}\n\nfunc (d *datagramV3Connection) UnregisterUdpSession(ctx context.Context, sessionID uuid.UUID, message string) error {\n\td.metrics.UnsupportedRemoteCommand(d.index, \"unregister_udp_session\")\n\treturn ErrUnsupportedRPCUDPUnregistration\n}\n"
  },
  {
    "path": "connection/tunnelsforha.go",
    "content": "package connection\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n)\n\n// tunnelsForHA maps this cloudflared instance's HA connections to the tunnel IDs they serve.\ntype tunnelsForHA struct {\n\tsync.Mutex\n\tmetrics *prometheus.GaugeVec\n\tentries map[uint8]string\n}\n\n// NewTunnelsForHA initializes the Prometheus metrics etc for a tunnelsForHA.\nfunc newTunnelsForHA() tunnelsForHA {\n\tmetrics := prometheus.NewGaugeVec(\n\t\tprometheus.GaugeOpts{\n\t\t\tName: \"tunnel_ids\",\n\t\t\tHelp: \"The ID of all tunnels (and their corresponding HA connection ID) running in this instance of cloudflared.\",\n\t\t},\n\t\t[]string{\"tunnel_id\", \"ha_conn_id\"},\n\t)\n\tprometheus.MustRegister(metrics)\n\n\treturn tunnelsForHA{\n\t\tmetrics: metrics,\n\t\tentries: make(map[uint8]string),\n\t}\n}\n\n// Track a new tunnel ID, removing the disconnected tunnel (if any) and update metrics.\nfunc (t *tunnelsForHA) AddTunnelID(haConn uint8, tunnelID string) {\n\tt.Lock()\n\tdefer t.Unlock()\n\thaStr := fmt.Sprintf(\"%v\", haConn)\n\tif oldTunnelID, ok := t.entries[haConn]; ok {\n\t\tt.metrics.WithLabelValues(oldTunnelID, haStr).Dec()\n\t}\n\tt.entries[haConn] = tunnelID\n\tt.metrics.WithLabelValues(tunnelID, haStr).Inc()\n}\n\nfunc (t *tunnelsForHA) String() string {\n\tt.Lock()\n\tdefer t.Unlock()\n\treturn fmt.Sprintf(\"%v\", t.entries)\n}\n"
  },
  {
    "path": "credentials/credentials.go",
    "content": "package credentials\n\nimport (\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/cfapi\"\n)\n\nconst (\n\tlogFieldOriginCertPath = \"originCertPath\"\n\tFedEndpoint            = \"fed\"\n\tFedRampBaseApiURL      = \"https://api.fed.cloudflare.com/client/v4\"\n\tFedRampHostname        = \"management.fed.argotunnel.com\"\n)\n\ntype User struct {\n\tcert     *OriginCert\n\tcertPath string\n}\n\nfunc (c User) AccountID() string {\n\treturn c.cert.AccountID\n}\n\nfunc (c User) Endpoint() string {\n\treturn c.cert.Endpoint\n}\n\nfunc (c User) ZoneID() string {\n\treturn c.cert.ZoneID\n}\n\nfunc (c User) APIToken() string {\n\treturn c.cert.APIToken\n}\n\nfunc (c User) CertPath() string {\n\treturn c.certPath\n}\n\nfunc (c User) IsFEDEndpoint() bool {\n\treturn c.cert.Endpoint == FedEndpoint\n}\n\n// Client uses the user credentials to create a Cloudflare API client\nfunc (c *User) Client(apiURL string, userAgent string, log *zerolog.Logger) (cfapi.Client, error) {\n\tif apiURL == \"\" {\n\t\treturn nil, errors.New(\"An api-url was not provided for the Cloudflare API client\")\n\t}\n\tclient, err := cfapi.NewRESTClient(\n\t\tapiURL,\n\t\tc.cert.AccountID,\n\t\tc.cert.ZoneID,\n\t\tc.cert.APIToken,\n\t\tuserAgent,\n\t\tlog,\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn client, nil\n}\n\n// Read will load and read the origin cert.pem to load the user credentials\nfunc Read(originCertPath string, log *zerolog.Logger) (*User, error) {\n\toriginCertLog := log.With().\n\t\tStr(logFieldOriginCertPath, originCertPath).\n\t\tLogger()\n\n\toriginCertPath, err := FindOriginCert(originCertPath, &originCertLog)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"Error locating origin cert\")\n\t}\n\tblocks, err := readOriginCert(originCertPath)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"Can't read origin cert from %s\", originCertPath)\n\t}\n\n\tcert, err := decodeOriginCert(blocks)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"Error decoding origin cert\")\n\t}\n\n\tif cert.AccountID == \"\" {\n\t\treturn nil, errors.Errorf(`Origin certificate needs to be refreshed before creating new tunnels.\\nDelete %s and run \"cloudflared login\" to obtain a new cert.`, originCertPath)\n\t}\n\n\treturn &User{\n\t\tcert:     cert,\n\t\tcertPath: originCertPath,\n\t}, nil\n}\n"
  },
  {
    "path": "credentials/credentials_test.go",
    "content": "package credentials\n\nimport (\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestCredentialsRead(t *testing.T) {\n\tfile, err := os.ReadFile(\"test-cloudflare-tunnel-cert-json.pem\")\n\trequire.NoError(t, err)\n\tdir := t.TempDir()\n\tcertPath := filepath.Join(dir, originCertFile)\n\t_ = os.WriteFile(certPath, file, fs.ModePerm)\n\tuser, err := Read(certPath, &nopLog)\n\trequire.NoError(t, err)\n\trequire.Equal(t, certPath, user.CertPath())\n\trequire.Equal(t, \"test-service-key\", user.APIToken())\n\trequire.Equal(t, \"7b0a4d77dfb881c1a3b7d61ea9443e19\", user.ZoneID())\n\trequire.Equal(t, \"abcdabcdabcdabcd1234567890abcdef\", user.AccountID())\n}\n\nfunc TestCredentialsClient(t *testing.T) {\n\tuser := User{\n\t\tcertPath: \"/tmp/cert.pem\",\n\t\tcert: &OriginCert{\n\t\t\tZoneID:    \"7b0a4d77dfb881c1a3b7d61ea9443e19\",\n\t\t\tAccountID: \"abcdabcdabcdabcd1234567890abcdef\",\n\t\t\tAPIToken:  \"test-service-key\",\n\t\t},\n\t}\n\tclient, err := user.Client(\"example.com\", \"cloudflared/test\", &nopLog)\n\trequire.NoError(t, err)\n\trequire.NotNil(t, client)\n}\n"
  },
  {
    "path": "credentials/origin_cert.go",
    "content": "package credentials\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"encoding/pem\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/mitchellh/go-homedir\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n)\n\nconst (\n\tDefaultCredentialFile = \"cert.pem\"\n)\n\ntype OriginCert struct {\n\tZoneID    string `json:\"zoneID\"`\n\tAccountID string `json:\"accountID\"`\n\tAPIToken  string `json:\"apiToken\"`\n\tEndpoint  string `json:\"endpoint,omitempty\"`\n}\n\nfunc (oc *OriginCert) UnmarshalJSON(data []byte) error {\n\tvar aux struct {\n\t\tZoneID    string `json:\"zoneID\"`\n\t\tAccountID string `json:\"accountID\"`\n\t\tAPIToken  string `json:\"apiToken\"`\n\t\tEndpoint  string `json:\"endpoint,omitempty\"`\n\t}\n\tif err := json.Unmarshal(data, &aux); err != nil {\n\t\treturn fmt.Errorf(\"error parsing OriginCert: %v\", err)\n\t}\n\toc.ZoneID = aux.ZoneID\n\toc.AccountID = aux.AccountID\n\toc.APIToken = aux.APIToken\n\toc.Endpoint = strings.ToLower(aux.Endpoint)\n\treturn nil\n}\n\n// FindDefaultOriginCertPath returns the first path that contains a cert.pem file. If none of the\n// DefaultConfigSearchDirectories contains a cert.pem file, return empty string\nfunc FindDefaultOriginCertPath() string {\n\tfor _, defaultConfigDir := range config.DefaultConfigSearchDirectories() {\n\t\toriginCertPath, _ := homedir.Expand(filepath.Join(defaultConfigDir, DefaultCredentialFile))\n\t\tif ok := fileExists(originCertPath); ok {\n\t\t\treturn originCertPath\n\t\t}\n\t}\n\treturn \"\"\n}\n\nfunc DecodeOriginCert(blocks []byte) (*OriginCert, error) {\n\treturn decodeOriginCert(blocks)\n}\n\nfunc (cert *OriginCert) EncodeOriginCert() ([]byte, error) {\n\tif cert == nil {\n\t\treturn nil, fmt.Errorf(\"originCert cannot be nil\")\n\t}\n\tbuffer, err := json.Marshal(cert)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"originCert marshal failed: %v\", err)\n\t}\n\tblock := pem.Block{\n\t\tType:    \"ARGO TUNNEL TOKEN\",\n\t\tHeaders: map[string]string{},\n\t\tBytes:   buffer,\n\t}\n\tvar out bytes.Buffer\n\terr = pem.Encode(&out, &block)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"pem encoding failed: %v\", err)\n\t}\n\treturn out.Bytes(), nil\n}\n\nfunc decodeOriginCert(blocks []byte) (*OriginCert, error) {\n\tif len(blocks) == 0 {\n\t\treturn nil, fmt.Errorf(\"cannot decode empty certificate\")\n\t}\n\toriginCert := OriginCert{}\n\tblock, rest := pem.Decode(blocks)\n\tfor block != nil {\n\t\tswitch block.Type {\n\t\tcase \"PRIVATE KEY\", \"CERTIFICATE\":\n\t\t\t// this is for legacy purposes.\n\t\tcase \"ARGO TUNNEL TOKEN\":\n\t\t\tif originCert.ZoneID != \"\" || originCert.APIToken != \"\" {\n\t\t\t\treturn nil, fmt.Errorf(\"found multiple tokens in the certificate\")\n\t\t\t}\n\t\t\t// The token is a string,\n\t\t\t// Try the newer JSON format\n\t\t\t_ = json.Unmarshal(block.Bytes, &originCert)\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"unknown block %s in the certificate\", block.Type)\n\t\t}\n\t\tblock, rest = pem.Decode(rest)\n\t}\n\n\tif originCert.ZoneID == \"\" || originCert.APIToken == \"\" {\n\t\treturn nil, fmt.Errorf(\"missing token in the certificate\")\n\t}\n\n\treturn &originCert, nil\n}\n\nfunc readOriginCert(originCertPath string) ([]byte, error) {\n\toriginCert, err := os.ReadFile(originCertPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot read %s to load origin certificate\", originCertPath)\n\t}\n\n\treturn originCert, nil\n}\n\n// FindOriginCert will check to make sure that the certificate exists at the specified file path.\nfunc FindOriginCert(originCertPath string, log *zerolog.Logger) (string, error) {\n\tif originCertPath == \"\" {\n\t\tlog.Error().Msgf(\"Cannot determine default origin certificate path. No file %s in %v. You need to specify the origin certificate path by specifying the origincert option in the configuration file, or set TUNNEL_ORIGIN_CERT environment variable\", DefaultCredentialFile, config.DefaultConfigSearchDirectories())\n\t\treturn \"\", fmt.Errorf(\"client didn't specify origincert path\")\n\t}\n\tvar err error\n\toriginCertPath, err = homedir.Expand(originCertPath)\n\tif err != nil {\n\t\tlog.Err(err).Msgf(\"Cannot resolve origin certificate path\")\n\t\treturn \"\", fmt.Errorf(\"cannot resolve path %s\", originCertPath)\n\t}\n\t// Check that the user has acquired a certificate using the login command\n\tok := fileExists(originCertPath)\n\tif !ok {\n\t\tlog.Error().Msgf(`Cannot find a valid certificate for your origin at the path:\n\n    %s\n\nIf the path above is wrong, specify the path with the -origincert option.\nIf you don't have a certificate signed by Cloudflare, run the command:\n\n\tcloudflared login\n`, originCertPath)\n\t\treturn \"\", fmt.Errorf(\"cannot find a valid certificate at the path %s\", originCertPath)\n\t}\n\n\treturn originCertPath, nil\n}\n\n// FileExists checks to see if a file exist at the provided path.\nfunc fileExists(path string) bool {\n\tfileStat, err := os.Stat(path)\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn !fileStat.IsDir()\n}\n"
  },
  {
    "path": "credentials/origin_cert_test.go",
    "content": "package credentials\n\nimport (\n\t\"fmt\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nconst (\n\toriginCertFile = \"cert.pem\"\n)\n\nvar nopLog = zerolog.Nop().With().Logger()\n\nfunc TestLoadOriginCert(t *testing.T) {\n\tcert, err := decodeOriginCert([]byte{})\n\tassert.Equal(t, fmt.Errorf(\"cannot decode empty certificate\"), err)\n\tassert.Nil(t, cert)\n\n\tblocks, err := os.ReadFile(\"test-cert-unknown-block.pem\")\n\trequire.NoError(t, err)\n\tcert, err = decodeOriginCert(blocks)\n\tassert.Equal(t, fmt.Errorf(\"unknown block RSA PRIVATE KEY in the certificate\"), err)\n\tassert.Nil(t, cert)\n}\n\nfunc TestJSONArgoTunnelTokenEmpty(t *testing.T) {\n\tblocks, err := os.ReadFile(\"test-cert-no-token.pem\")\n\trequire.NoError(t, err)\n\tcert, err := decodeOriginCert(blocks)\n\tassert.Equal(t, fmt.Errorf(\"missing token in the certificate\"), err)\n\tassert.Nil(t, cert)\n}\n\nfunc TestJSONArgoTunnelToken(t *testing.T) {\n\t// The given cert's Argo Tunnel Token was generated by base64 encoding this JSON:\n\t// {\n\t// \"zoneID\": \"7b0a4d77dfb881c1a3b7d61ea9443e19\",\n\t// \"apiToken\": \"test-service-key\",\n\t// \"accountID\": \"abcdabcdabcdabcd1234567890abcdef\"\n\t// }\n\tCloudflareTunnelTokenTest(t, \"test-cloudflare-tunnel-cert-json.pem\")\n}\n\nfunc CloudflareTunnelTokenTest(t *testing.T, path string) {\n\tblocks, err := os.ReadFile(path)\n\trequire.NoError(t, err)\n\tcert, err := decodeOriginCert(blocks)\n\trequire.NoError(t, err)\n\tassert.NotNil(t, cert)\n\tassert.Equal(t, \"7b0a4d77dfb881c1a3b7d61ea9443e19\", cert.ZoneID)\n\tkey := \"test-service-key\"\n\tassert.Equal(t, key, cert.APIToken)\n}\n\nfunc TestFindOriginCert_Valid(t *testing.T) {\n\tfile, err := os.ReadFile(\"test-cloudflare-tunnel-cert-json.pem\")\n\trequire.NoError(t, err)\n\tdir := t.TempDir()\n\tcertPath := filepath.Join(dir, originCertFile)\n\t_ = os.WriteFile(certPath, file, fs.ModePerm)\n\tpath, err := FindOriginCert(certPath, &nopLog)\n\trequire.NoError(t, err)\n\trequire.Equal(t, certPath, path)\n}\n\nfunc TestFindOriginCert_Missing(t *testing.T) {\n\tdir := t.TempDir()\n\tcertPath := filepath.Join(dir, originCertFile)\n\t_, err := FindOriginCert(certPath, &nopLog)\n\trequire.Error(t, err)\n}\n\nfunc TestEncodeDecodeOriginCert(t *testing.T) {\n\tcert := OriginCert{\n\t\tZoneID:    \"zone\",\n\t\tAccountID: \"account\",\n\t\tAPIToken:  \"token\",\n\t\tEndpoint:  \"FED\",\n\t}\n\tblocks, err := cert.EncodeOriginCert()\n\trequire.NoError(t, err)\n\tdecodedCert, err := DecodeOriginCert(blocks)\n\trequire.NoError(t, err)\n\tassert.NotNil(t, cert)\n\tassert.Equal(t, \"zone\", decodedCert.ZoneID)\n\tassert.Equal(t, \"account\", decodedCert.AccountID)\n\tassert.Equal(t, \"token\", decodedCert.APIToken)\n\tassert.Equal(t, FedEndpoint, decodedCert.Endpoint)\n}\n\nfunc TestEncodeDecodeNilOriginCert(t *testing.T) {\n\tvar cert *OriginCert\n\tblocks, err := cert.EncodeOriginCert()\n\tassert.Equal(t, fmt.Errorf(\"originCert cannot be nil\"), err)\n\trequire.Nil(t, blocks)\n}\n"
  },
  {
    "path": "credentials/test-cert-no-token.pem",
    "content": "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCfGswL16Fz9Ei3\nsAg5AmBizoN2nZdyXHP8T57UxUMcrlJXEEXCVS5RR4m9l+EmK0ng6yHR1H5oX1Lg\n1WKyXgWwr0whwmdTD+qWFJW2M8HyefyBKLrsGPuxw4CVYT0h72bxtG0uyrXYh7Mt\nz0lHjGV90qrFpq5o0jx0sLbDlDvpFPbIO58uYzKG4Sn2VTC4rOyXPE6SuDvMHIeX\n6Ekw4wSVQ9eTbksLQqTyxSqM3zp2ygc56SjGjy1nGQT8ZBGFzSbZAzNOxVKrUsyS\nx7LzZVl+zCGCPlQwaYLKObKXadZJmrqSFmErC5jcbVgBz7oJQOglHJ2n0sMcZ+Ja\n1Y649mPVAgMBAAECggEAEbPF0ah9fH0IzTU/CPbIeh3flyY8GDuMpR1HvwUurSWB\nIFI9bLyVAXKb8vYP1TMaTnXi5qmFof+/JShgyZc3+1tZtWTfoaiC8Y1bRfE2yk+D\nxmwddhDmijYGG7i8uEaeddSdFEh2GKAqkbV/QgBvN2Nl4EVmIOAJXXNe9l5LFyjy\nsR10aNVJRYV1FahrCTwZ3SovHP4d4AUvHh/3FFZDukHc37CFA0+CcR4uehp5yedi\n2UdqaszXqunFo/3h+Tn9dW2C7gTTZx4+mfyaws3p3YOmdYArXvpejxHIc0FGwLBm\nsb9K7wGVUiF0Bt0ch+C1mdYrCaFNHnPuDswjmm3FwQKBgQDYtxOwwSLA6ZyppozX\nDoyx9a7PhiMHCFKSdVB4l8rpK545a+AmpG6LRScTtBsMTHBhT3IQ3QPWlVm1AhjF\nAvXMa1rOeaGbCbDn1xqEoEVPtj4tys8eTfyWmtU73jWTFauOt4/xpf/urEpg91xj\nm+Gl/8qgBrpm5rQxV5Y4MysRlQKBgQC78jzzlhocXGNvw0wT/K2NsknyeoZXqpIE\nQYL60FMl4geZn6w9hwxaL1r+g/tUjTnpBPQtS1r2Ed2gXby5zspN1g/PW8U3t3to\nP7zHIJ/sLBXrCh5RJko3hUgGhDNOOCIQj4IaKUfvHYvEIbIxlyI0vdsXsgXgMuQ8\npb9Yifn5QQKBgQCmGu0EtYQlyOlDP10EGSrN3Dm45l9CrKZdi326cN4eCkikSoLs\nG2x/YumouItiydP5QiNzuXOPrbmse4bwumwb2s0nJSMw6iSmDsFMlmuJxW2zO5e0\n6qGH7fUyhgcaTanJIfk6hrm7/mKkH/S4hGpYCc8NCRsmc/35M+D4AoAoYQKBgQC0\nLWpZaxDlF30MbAHHN3l6We2iU+vup0sMYXGb2ZOcwa/fir+ozIr++l8VmJmdWTan\nOWSM96zgMghx8Os4hhJTxF+rvqK242OfcVsc2x31X94zUaP2z+peh5uhA6Pb3Nxr\nW+iyA9k+Vujiwhr+h5D3VvtvH++aG6/KpGtoCf5nAQKBgQDXX2+d7bd5CLNLLFNd\nM2i4QoOFcSKIG+v4SuvgEJHgG8vGvxh2qlSxnMWuPV+7/1P5ATLqDj1PlKms+BNR\ny7sc5AT9PclkL3Y9MNzOu0LXyBkGYcl8M0EQfLv9VPbWT+NXiMg/O2CHiT02pAAz\nuQicoQq3yzeQh20wtrtaXzTNmA==\n-----END PRIVATE KEY-----\n-----BEGIN CERTIFICATE-----\nMIID+jCCA6CgAwIBAgIUJhFxUKEGvTRc3CjCok6dbPGH/P4wCgYIKoZIzj0EAwIw\ngagxCzAJBgNVBAYTAlVTMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMTgwNgYD\nVQQLEy9DbG91ZEZsYXJlIE9yaWdpbiBTU0wgRUNDIENlcnRpZmljYXRlIEF1dGhv\ncml0eTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZvcm5p\nYTEXMBUGA1UEAxMOKGRldiB1c2Ugb25seSkwHhcNMTcxMDEzMTM1OTAwWhcNMzIx\nMDA5MTM1OTAwWjBiMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMR0wGwYDVQQL\nExRDbG91ZEZsYXJlIE9yaWdpbiBDQTEmMCQGA1UEAxMdQ2xvdWRGbGFyZSBPcmln\naW4gQ2VydGlmaWNhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCf\nGswL16Fz9Ei3sAg5AmBizoN2nZdyXHP8T57UxUMcrlJXEEXCVS5RR4m9l+EmK0ng\n6yHR1H5oX1Lg1WKyXgWwr0whwmdTD+qWFJW2M8HyefyBKLrsGPuxw4CVYT0h72bx\ntG0uyrXYh7Mtz0lHjGV90qrFpq5o0jx0sLbDlDvpFPbIO58uYzKG4Sn2VTC4rOyX\nPE6SuDvMHIeX6Ekw4wSVQ9eTbksLQqTyxSqM3zp2ygc56SjGjy1nGQT8ZBGFzSbZ\nAzNOxVKrUsySx7LzZVl+zCGCPlQwaYLKObKXadZJmrqSFmErC5jcbVgBz7oJQOgl\nHJ2n0sMcZ+Ja1Y649mPVAgMBAAGjggEgMIIBHDAOBgNVHQ8BAf8EBAMCBaAwEwYD\nVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUzA6f2Ajq\nzhX67c6piY2a1uTiUkwwHwYDVR0jBBgwFoAU2qfBlqxKMZnf0QeTeYiMelfqJfgw\nRAYIKwYBBQUHAQEEODA2MDQGCCsGAQUFBzABhihodHRwOi8vb2NzcC5jbG91ZGZs\nYXJlLmNvbS9vcmlnaW5fZWNjX2NhMCMGA1UdEQQcMBqCDCouYXJub2xkLmNvbYIK\nYXJub2xkLmNvbTA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vY3JsLmNsb3VkZmxh\ncmUuY29tL29yaWdpbl9lY2NfY2EuY3JsMAoGCCqGSM49BAMCA0gAMEUCIDV7HoMj\nK5rShE/l+90YAOzHC89OH/wUz3I5KYOFuehoAiEA8e92aIf9XBkr0K6EvFCiSsD+\nx+Yo/cL8fGfVpPt4UM8=\n-----END CERTIFICATE-----\n-----BEGIN ARGO TUNNEL TOKEN-----\neyJ6b25lSUQiOiAiN2IwYTRkNzdkZmI4ODFjMWEzYjdkNjFlYTk0NDNlMTkiLCAiYWNjb3VudElE\nIjogImFiY2RhYmNkYWJjZGFiY2QxMjM0NTY3ODkwYWJjZGVmIn0=\n-----END ARGO TUNNEL TOKEN-----\n"
  },
  {
    "path": "credentials/test-cert-unknown-block.pem",
    "content": "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCfGswL16Fz9Ei3\nsAg5AmBizoN2nZdyXHP8T57UxUMcrlJXEEXCVS5RR4m9l+EmK0ng6yHR1H5oX1Lg\n1WKyXgWwr0whwmdTD+qWFJW2M8HyefyBKLrsGPuxw4CVYT0h72bxtG0uyrXYh7Mt\nz0lHjGV90qrFpq5o0jx0sLbDlDvpFPbIO58uYzKG4Sn2VTC4rOyXPE6SuDvMHIeX\n6Ekw4wSVQ9eTbksLQqTyxSqM3zp2ygc56SjGjy1nGQT8ZBGFzSbZAzNOxVKrUsyS\nx7LzZVl+zCGCPlQwaYLKObKXadZJmrqSFmErC5jcbVgBz7oJQOglHJ2n0sMcZ+Ja\n1Y649mPVAgMBAAECggEAEbPF0ah9fH0IzTU/CPbIeh3flyY8GDuMpR1HvwUurSWB\nIFI9bLyVAXKb8vYP1TMaTnXi5qmFof+/JShgyZc3+1tZtWTfoaiC8Y1bRfE2yk+D\nxmwddhDmijYGG7i8uEaeddSdFEh2GKAqkbV/QgBvN2Nl4EVmIOAJXXNe9l5LFyjy\nsR10aNVJRYV1FahrCTwZ3SovHP4d4AUvHh/3FFZDukHc37CFA0+CcR4uehp5yedi\n2UdqaszXqunFo/3h+Tn9dW2C7gTTZx4+mfyaws3p3YOmdYArXvpejxHIc0FGwLBm\nsb9K7wGVUiF0Bt0ch+C1mdYrCaFNHnPuDswjmm3FwQKBgQDYtxOwwSLA6ZyppozX\nDoyx9a7PhiMHCFKSdVB4l8rpK545a+AmpG6LRScTtBsMTHBhT3IQ3QPWlVm1AhjF\nAvXMa1rOeaGbCbDn1xqEoEVPtj4tys8eTfyWmtU73jWTFauOt4/xpf/urEpg91xj\nm+Gl/8qgBrpm5rQxV5Y4MysRlQKBgQC78jzzlhocXGNvw0wT/K2NsknyeoZXqpIE\nQYL60FMl4geZn6w9hwxaL1r+g/tUjTnpBPQtS1r2Ed2gXby5zspN1g/PW8U3t3to\nP7zHIJ/sLBXrCh5RJko3hUgGhDNOOCIQj4IaKUfvHYvEIbIxlyI0vdsXsgXgMuQ8\npb9Yifn5QQKBgQCmGu0EtYQlyOlDP10EGSrN3Dm45l9CrKZdi326cN4eCkikSoLs\nG2x/YumouItiydP5QiNzuXOPrbmse4bwumwb2s0nJSMw6iSmDsFMlmuJxW2zO5e0\n6qGH7fUyhgcaTanJIfk6hrm7/mKkH/S4hGpYCc8NCRsmc/35M+D4AoAoYQKBgQC0\nLWpZaxDlF30MbAHHN3l6We2iU+vup0sMYXGb2ZOcwa/fir+ozIr++l8VmJmdWTan\nOWSM96zgMghx8Os4hhJTxF+rvqK242OfcVsc2x31X94zUaP2z+peh5uhA6Pb3Nxr\nW+iyA9k+Vujiwhr+h5D3VvtvH++aG6/KpGtoCf5nAQKBgQDXX2+d7bd5CLNLLFNd\nM2i4QoOFcSKIG+v4SuvgEJHgG8vGvxh2qlSxnMWuPV+7/1P5ATLqDj1PlKms+BNR\ny7sc5AT9PclkL3Y9MNzOu0LXyBkGYcl8M0EQfLv9VPbWT+NXiMg/O2CHiT02pAAz\nuQicoQq3yzeQh20wtrtaXzTNmA==\n-----END PRIVATE KEY-----\n-----BEGIN CERTIFICATE-----\nMIID+jCCA6CgAwIBAgIUJhFxUKEGvTRc3CjCok6dbPGH/P4wCgYIKoZIzj0EAwIw\ngagxCzAJBgNVBAYTAlVTMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMTgwNgYD\nVQQLEy9DbG91ZEZsYXJlIE9yaWdpbiBTU0wgRUNDIENlcnRpZmljYXRlIEF1dGhv\ncml0eTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZvcm5p\nYTEXMBUGA1UEAxMOKGRldiB1c2Ugb25seSkwHhcNMTcxMDEzMTM1OTAwWhcNMzIx\nMDA5MTM1OTAwWjBiMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMR0wGwYDVQQL\nExRDbG91ZEZsYXJlIE9yaWdpbiBDQTEmMCQGA1UEAxMdQ2xvdWRGbGFyZSBPcmln\naW4gQ2VydGlmaWNhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCf\nGswL16Fz9Ei3sAg5AmBizoN2nZdyXHP8T57UxUMcrlJXEEXCVS5RR4m9l+EmK0ng\n6yHR1H5oX1Lg1WKyXgWwr0whwmdTD+qWFJW2M8HyefyBKLrsGPuxw4CVYT0h72bx\ntG0uyrXYh7Mtz0lHjGV90qrFpq5o0jx0sLbDlDvpFPbIO58uYzKG4Sn2VTC4rOyX\nPE6SuDvMHIeX6Ekw4wSVQ9eTbksLQqTyxSqM3zp2ygc56SjGjy1nGQT8ZBGFzSbZ\nAzNOxVKrUsySx7LzZVl+zCGCPlQwaYLKObKXadZJmrqSFmErC5jcbVgBz7oJQOgl\nHJ2n0sMcZ+Ja1Y649mPVAgMBAAGjggEgMIIBHDAOBgNVHQ8BAf8EBAMCBaAwEwYD\nVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUzA6f2Ajq\nzhX67c6piY2a1uTiUkwwHwYDVR0jBBgwFoAU2qfBlqxKMZnf0QeTeYiMelfqJfgw\nRAYIKwYBBQUHAQEEODA2MDQGCCsGAQUFBzABhihodHRwOi8vb2NzcC5jbG91ZGZs\nYXJlLmNvbS9vcmlnaW5fZWNjX2NhMCMGA1UdEQQcMBqCDCouYXJub2xkLmNvbYIK\nYXJub2xkLmNvbTA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vY3JsLmNsb3VkZmxh\ncmUuY29tL29yaWdpbl9lY2NfY2EuY3JsMAoGCCqGSM49BAMCA0gAMEUCIDV7HoMj\nK5rShE/l+90YAOzHC89OH/wUz3I5KYOFuehoAiEA8e92aIf9XBkr0K6EvFCiSsD+\nx+Yo/cL8fGfVpPt4UM8=\n-----END CERTIFICATE-----\n-----BEGIN ARGO TUNNEL TOKEN-----\nN2IwYTRkNzdkZmI4ODFjMWEzYjdkNjFlYTk0NDNlMTkKdjEuMC01OGJkNGY5ZTI4\nZjdiM2MyOGUwNWEzNWZmM2U4MGFiNGZkOTY0NGVmM2ZlY2U1MzdlYjBkMTJlMmU5\nMjU4MjE3LTE4MzQ0MmZiYjBiYmRiM2U1NzE1NThmZWM5YjU1ODllYmQ3N2FhZmM4\nNzQ5OGVlM2YwOWY2NGE0YWQ3OWZmZTg3OTFlZGJhZTA4YjM2YzFkOGYxZDcwYTg2\nNzBkZTU2OTIyZGZmOTJiMTVkMjE0YTUyNGY0ZWJmYTE5NTg4NTllLTdjZTgwZjc5\nOTIxMzEyYTYwMjJjNWQyNWUyZDM4MGY4MmNlYWVmZTNmYmRjNDNkZDEzYjA4MGUz\nZWYxZTI2Zjc=\n-----END ARGO TUNNEL TOKEN-----\n-----BEGIN RSA PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCfGswL16Fz9Ei3\nsAg5AmBizoN2nZdyXHP8T57UxUMcrlJXEEXCVS5RR4m9l+EmK0ng6yHR1H5oX1Lg\n1WKyXgWwr0whwmdTD+qWFJW2M8HyefyBKLrsGPuxw4CVYT0h72bxtG0uyrXYh7Mt\nz0lHjGV90qrFpq5o0jx0sLbDlDvpFPbIO58uYzKG4Sn2VTC4rOyXPE6SuDvMHIeX\n6Ekw4wSVQ9eTbksLQqTyxSqM3zp2ygc56SjGjy1nGQT8ZBGFzSbZAzNOxVKrUsyS\nx7LzZVl+zCGCPlQwaYLKObKXadZJmrqSFmErC5jcbVgBz7oJQOglHJ2n0sMcZ+Ja\n1Y649mPVAgMBAAECggEAEbPF0ah9fH0IzTU/CPbIeh3flyY8GDuMpR1HvwUurSWB\nIFI9bLyVAXKb8vYP1TMaTnXi5qmFof+/JShgyZc3+1tZtWTfoaiC8Y1bRfE2yk+D\nxmwddhDmijYGG7i8uEaeddSdFEh2GKAqkbV/QgBvN2Nl4EVmIOAJXXNe9l5LFyjy\nsR10aNVJRYV1FahrCTwZ3SovHP4d4AUvHh/3FFZDukHc37CFA0+CcR4uehp5yedi\n2UdqaszXqunFo/3h+Tn9dW2C7gTTZx4+mfyaws3p3YOmdYArXvpejxHIc0FGwLBm\nsb9K7wGVUiF0Bt0ch+C1mdYrCaFNHnPuDswjmm3FwQKBgQDYtxOwwSLA6ZyppozX\nDoyx9a7PhiMHCFKSdVB4l8rpK545a+AmpG6LRScTtBsMTHBhT3IQ3QPWlVm1AhjF\nAvXMa1rOeaGbCbDn1xqEoEVPtj4tys8eTfyWmtU73jWTFauOt4/xpf/urEpg91xj\nm+Gl/8qgBrpm5rQxV5Y4MysRlQKBgQC78jzzlhocXGNvw0wT/K2NsknyeoZXqpIE\nQYL60FMl4geZn6w9hwxaL1r+g/tUjTnpBPQtS1r2Ed2gXby5zspN1g/PW8U3t3to\nP7zHIJ/sLBXrCh5RJko3hUgGhDNOOCIQj4IaKUfvHYvEIbIxlyI0vdsXsgXgMuQ8\npb9Yifn5QQKBgQCmGu0EtYQlyOlDP10EGSrN3Dm45l9CrKZdi326cN4eCkikSoLs\nG2x/YumouItiydP5QiNzuXOPrbmse4bwumwb2s0nJSMw6iSmDsFMlmuJxW2zO5e0\n6qGH7fUyhgcaTanJIfk6hrm7/mKkH/S4hGpYCc8NCRsmc/35M+D4AoAoYQKBgQC0\nLWpZaxDlF30MbAHHN3l6We2iU+vup0sMYXGb2ZOcwa/fir+ozIr++l8VmJmdWTan\nOWSM96zgMghx8Os4hhJTxF+rvqK242OfcVsc2x31X94zUaP2z+peh5uhA6Pb3Nxr\nW+iyA9k+Vujiwhr+h5D3VvtvH++aG6/KpGtoCf5nAQKBgQDXX2+d7bd5CLNLLFNd\nM2i4QoOFcSKIG+v4SuvgEJHgG8vGvxh2qlSxnMWuPV+7/1P5ATLqDj1PlKms+BNR\ny7sc5AT9PclkL3Y9MNzOu0LXyBkGYcl8M0EQfLv9VPbWT+NXiMg/O2CHiT02pAAz\nuQicoQq3yzeQh20wtrtaXzTNmA==\n-----END RSA PRIVATE KEY-----\n\n"
  },
  {
    "path": "credentials/test-cloudflare-tunnel-cert-json.pem",
    "content": "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCfGswL16Fz9Ei3\nsAg5AmBizoN2nZdyXHP8T57UxUMcrlJXEEXCVS5RR4m9l+EmK0ng6yHR1H5oX1Lg\n1WKyXgWwr0whwmdTD+qWFJW2M8HyefyBKLrsGPuxw4CVYT0h72bxtG0uyrXYh7Mt\nz0lHjGV90qrFpq5o0jx0sLbDlDvpFPbIO58uYzKG4Sn2VTC4rOyXPE6SuDvMHIeX\n6Ekw4wSVQ9eTbksLQqTyxSqM3zp2ygc56SjGjy1nGQT8ZBGFzSbZAzNOxVKrUsyS\nx7LzZVl+zCGCPlQwaYLKObKXadZJmrqSFmErC5jcbVgBz7oJQOglHJ2n0sMcZ+Ja\n1Y649mPVAgMBAAECggEAEbPF0ah9fH0IzTU/CPbIeh3flyY8GDuMpR1HvwUurSWB\nIFI9bLyVAXKb8vYP1TMaTnXi5qmFof+/JShgyZc3+1tZtWTfoaiC8Y1bRfE2yk+D\nxmwddhDmijYGG7i8uEaeddSdFEh2GKAqkbV/QgBvN2Nl4EVmIOAJXXNe9l5LFyjy\nsR10aNVJRYV1FahrCTwZ3SovHP4d4AUvHh/3FFZDukHc37CFA0+CcR4uehp5yedi\n2UdqaszXqunFo/3h+Tn9dW2C7gTTZx4+mfyaws3p3YOmdYArXvpejxHIc0FGwLBm\nsb9K7wGVUiF0Bt0ch+C1mdYrCaFNHnPuDswjmm3FwQKBgQDYtxOwwSLA6ZyppozX\nDoyx9a7PhiMHCFKSdVB4l8rpK545a+AmpG6LRScTtBsMTHBhT3IQ3QPWlVm1AhjF\nAvXMa1rOeaGbCbDn1xqEoEVPtj4tys8eTfyWmtU73jWTFauOt4/xpf/urEpg91xj\nm+Gl/8qgBrpm5rQxV5Y4MysRlQKBgQC78jzzlhocXGNvw0wT/K2NsknyeoZXqpIE\nQYL60FMl4geZn6w9hwxaL1r+g/tUjTnpBPQtS1r2Ed2gXby5zspN1g/PW8U3t3to\nP7zHIJ/sLBXrCh5RJko3hUgGhDNOOCIQj4IaKUfvHYvEIbIxlyI0vdsXsgXgMuQ8\npb9Yifn5QQKBgQCmGu0EtYQlyOlDP10EGSrN3Dm45l9CrKZdi326cN4eCkikSoLs\nG2x/YumouItiydP5QiNzuXOPrbmse4bwumwb2s0nJSMw6iSmDsFMlmuJxW2zO5e0\n6qGH7fUyhgcaTanJIfk6hrm7/mKkH/S4hGpYCc8NCRsmc/35M+D4AoAoYQKBgQC0\nLWpZaxDlF30MbAHHN3l6We2iU+vup0sMYXGb2ZOcwa/fir+ozIr++l8VmJmdWTan\nOWSM96zgMghx8Os4hhJTxF+rvqK242OfcVsc2x31X94zUaP2z+peh5uhA6Pb3Nxr\nW+iyA9k+Vujiwhr+h5D3VvtvH++aG6/KpGtoCf5nAQKBgQDXX2+d7bd5CLNLLFNd\nM2i4QoOFcSKIG+v4SuvgEJHgG8vGvxh2qlSxnMWuPV+7/1P5ATLqDj1PlKms+BNR\ny7sc5AT9PclkL3Y9MNzOu0LXyBkGYcl8M0EQfLv9VPbWT+NXiMg/O2CHiT02pAAz\nuQicoQq3yzeQh20wtrtaXzTNmA==\n-----END PRIVATE KEY-----\n-----BEGIN CERTIFICATE-----\nMIID+jCCA6CgAwIBAgIUJhFxUKEGvTRc3CjCok6dbPGH/P4wCgYIKoZIzj0EAwIw\ngagxCzAJBgNVBAYTAlVTMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMTgwNgYD\nVQQLEy9DbG91ZEZsYXJlIE9yaWdpbiBTU0wgRUNDIENlcnRpZmljYXRlIEF1dGhv\ncml0eTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZvcm5p\nYTEXMBUGA1UEAxMOKGRldiB1c2Ugb25seSkwHhcNMTcxMDEzMTM1OTAwWhcNMzIx\nMDA5MTM1OTAwWjBiMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMR0wGwYDVQQL\nExRDbG91ZEZsYXJlIE9yaWdpbiBDQTEmMCQGA1UEAxMdQ2xvdWRGbGFyZSBPcmln\naW4gQ2VydGlmaWNhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCf\nGswL16Fz9Ei3sAg5AmBizoN2nZdyXHP8T57UxUMcrlJXEEXCVS5RR4m9l+EmK0ng\n6yHR1H5oX1Lg1WKyXgWwr0whwmdTD+qWFJW2M8HyefyBKLrsGPuxw4CVYT0h72bx\ntG0uyrXYh7Mtz0lHjGV90qrFpq5o0jx0sLbDlDvpFPbIO58uYzKG4Sn2VTC4rOyX\nPE6SuDvMHIeX6Ekw4wSVQ9eTbksLQqTyxSqM3zp2ygc56SjGjy1nGQT8ZBGFzSbZ\nAzNOxVKrUsySx7LzZVl+zCGCPlQwaYLKObKXadZJmrqSFmErC5jcbVgBz7oJQOgl\nHJ2n0sMcZ+Ja1Y649mPVAgMBAAGjggEgMIIBHDAOBgNVHQ8BAf8EBAMCBaAwEwYD\nVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUzA6f2Ajq\nzhX67c6piY2a1uTiUkwwHwYDVR0jBBgwFoAU2qfBlqxKMZnf0QeTeYiMelfqJfgw\nRAYIKwYBBQUHAQEEODA2MDQGCCsGAQUFBzABhihodHRwOi8vb2NzcC5jbG91ZGZs\nYXJlLmNvbS9vcmlnaW5fZWNjX2NhMCMGA1UdEQQcMBqCDCouYXJub2xkLmNvbYIK\nYXJub2xkLmNvbTA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vY3JsLmNsb3VkZmxh\ncmUuY29tL29yaWdpbl9lY2NfY2EuY3JsMAoGCCqGSM49BAMCA0gAMEUCIDV7HoMj\nK5rShE/l+90YAOzHC89OH/wUz3I5KYOFuehoAiEA8e92aIf9XBkr0K6EvFCiSsD+\nx+Yo/cL8fGfVpPt4UM8=\n-----END CERTIFICATE-----\n-----BEGIN ARGO TUNNEL TOKEN-----\neyJ6b25lSUQiOiAiN2IwYTRkNzdkZmI4ODFjMWEzYjdkNjFlYTk0NDNlMTkiLCAiYXBpVG9rZW4i\nOiAidGVzdC1zZXJ2aWNlLWtleSIsICJhY2NvdW50SUQiOiAiYWJjZGFiY2RhYmNkYWJjZDEyMzQ1\nNjc4OTBhYmNkZWYifQ==\n-----END ARGO TUNNEL TOKEN-----\n"
  },
  {
    "path": "datagramsession/event.go",
    "content": "package datagramsession\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/google/uuid\"\n)\n\n// registerSessionEvent is an event to start tracking a new session\ntype registerSessionEvent struct {\n\tsessionID   uuid.UUID\n\toriginProxy io.ReadWriteCloser\n\tresultChan  chan *Session\n}\n\nfunc newRegisterSessionEvent(sessionID uuid.UUID, originProxy io.ReadWriteCloser) *registerSessionEvent {\n\treturn &registerSessionEvent{\n\t\tsessionID:   sessionID,\n\t\toriginProxy: originProxy,\n\t\tresultChan:  make(chan *Session, 1),\n\t}\n}\n\n// unregisterSessionEvent is an event to stop tracking and terminate the session.\ntype unregisterSessionEvent struct {\n\tsessionID uuid.UUID\n\terr       *errClosedSession\n}\n\n// ClosedSessionError represent a condition that closes the session other than I/O\n// I/O error is not included, because the side that closes the session is ambiguous.\ntype errClosedSession struct {\n\tmessage  string\n\tbyRemote bool\n}\n\nfunc (sc *errClosedSession) Error() string {\n\tif sc.byRemote {\n\t\treturn fmt.Sprintf(\"session closed by remote due to %s\", sc.message)\n\t} else {\n\t\treturn fmt.Sprintf(\"session closed by local due to %s\", sc.message)\n\t}\n}\n"
  },
  {
    "path": "datagramsession/manager.go",
    "content": "package datagramsession\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/management\"\n\t\"github.com/cloudflare/cloudflared/packet\"\n)\n\nconst (\n\trequestChanCapacity = 16\n\tdefaultReqTimeout   = time.Second * 5\n)\n\nvar (\n\terrSessionManagerClosed = fmt.Errorf(\"session manager closed\")\n\tLogFieldSessionID       = \"sessionID\"\n)\n\nfunc FormatSessionID(sessionID uuid.UUID) string {\n\tsessionIDStr := sessionID.String()\n\tsessionIDStr = strings.ReplaceAll(sessionIDStr, \"-\", \"\")\n\treturn sessionIDStr\n}\n\n// Manager defines the APIs to manage sessions from the same transport.\ntype Manager interface {\n\t// Serve starts the event loop\n\tServe(ctx context.Context) error\n\t// RegisterSession starts tracking a session. Caller is responsible for starting the session\n\tRegisterSession(ctx context.Context, sessionID uuid.UUID, dstConn io.ReadWriteCloser) (*Session, error)\n\t// UnregisterSession stops tracking the session and terminates it\n\tUnregisterSession(ctx context.Context, sessionID uuid.UUID, message string, byRemote bool) error\n\t// UpdateLogger updates the logger used by the Manager\n\tUpdateLogger(log *zerolog.Logger)\n}\n\ntype manager struct {\n\tregistrationChan   chan *registerSessionEvent\n\tunregistrationChan chan *unregisterSessionEvent\n\tsendFunc           transportSender\n\treceiveChan        <-chan *packet.Session\n\tclosedChan         <-chan struct{}\n\tsessions           map[uuid.UUID]*Session\n\tlog                *zerolog.Logger\n\t// timeout waiting for an API to finish. This can be overriden in test\n\ttimeout time.Duration\n}\n\nfunc NewManager(log *zerolog.Logger, sendF transportSender, receiveChan <-chan *packet.Session) *manager {\n\treturn &manager{\n\t\tregistrationChan:   make(chan *registerSessionEvent),\n\t\tunregistrationChan: make(chan *unregisterSessionEvent),\n\t\tsendFunc:           sendF,\n\t\treceiveChan:        receiveChan,\n\t\tclosedChan:         make(chan struct{}),\n\t\tsessions:           make(map[uuid.UUID]*Session),\n\t\tlog:                log,\n\t\ttimeout:            defaultReqTimeout,\n\t}\n}\n\nfunc (m *manager) UpdateLogger(log *zerolog.Logger) {\n\t// Benign data race, no problem if the old pointer is read or not concurrently.\n\tm.log = log\n}\n\nfunc (m *manager) Serve(ctx context.Context) error {\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\tm.shutdownSessions(ctx.Err())\n\t\t\treturn ctx.Err()\n\t\t// receiveChan is buffered, so the transport can read more datagrams from transport while the event loop is\n\t\t// processing other events\n\t\tcase datagram := <-m.receiveChan:\n\t\t\tm.sendToSession(datagram)\n\t\tcase registration := <-m.registrationChan:\n\t\t\tm.registerSession(ctx, registration)\n\t\tcase unregistration := <-m.unregistrationChan:\n\t\t\tm.unregisterSession(unregistration)\n\t\t}\n\t}\n}\n\nfunc (m *manager) shutdownSessions(err error) {\n\tif err == nil {\n\t\terr = errSessionManagerClosed\n\t}\n\tcloseSessionErr := &errClosedSession{\n\t\tmessage: err.Error(),\n\t\t// Usually connection with remote has been closed, so set this to true to skip unregistering from remote\n\t\tbyRemote: true,\n\t}\n\tfor _, s := range m.sessions {\n\t\tm.unregisterSession(&unregisterSessionEvent{\n\t\t\tsessionID: s.ID,\n\t\t\terr:       closeSessionErr,\n\t\t})\n\t}\n}\n\nfunc (m *manager) RegisterSession(ctx context.Context, sessionID uuid.UUID, originProxy io.ReadWriteCloser) (*Session, error) {\n\tctx, cancel := context.WithTimeout(ctx, m.timeout)\n\tdefer cancel()\n\tevent := newRegisterSessionEvent(sessionID, originProxy)\n\tselect {\n\tcase <-ctx.Done():\n\t\tm.log.Error().Msg(\"Datagram session registration timeout\")\n\t\treturn nil, ctx.Err()\n\tcase m.registrationChan <- event:\n\t\tsession := <-event.resultChan\n\t\treturn session, nil\n\t// Once closedChan is closed, manager won't accept more registration because nothing is\n\t// reading from registrationChan and it's an unbuffered channel\n\tcase <-m.closedChan:\n\t\treturn nil, errSessionManagerClosed\n\t}\n}\n\nfunc (m *manager) registerSession(ctx context.Context, registration *registerSessionEvent) {\n\tsession := m.newSession(registration.sessionID, registration.originProxy)\n\tm.sessions[registration.sessionID] = session\n\tregistration.resultChan <- session\n\tincrementUDPSessions()\n}\n\nfunc (m *manager) newSession(id uuid.UUID, dstConn io.ReadWriteCloser) *Session {\n\tlogger := m.log.With().\n\t\tInt(management.EventTypeKey, int(management.UDP)).\n\t\tStr(LogFieldSessionID, FormatSessionID(id)).Logger()\n\treturn &Session{\n\t\tID:       id,\n\t\tsendFunc: m.sendFunc,\n\t\tdstConn:  dstConn,\n\t\t// activeAtChan has low capacity. It can be full when there are many concurrent read/write. markActive() will\n\t\t// drop instead of blocking because last active time only needs to be an approximation\n\t\tactiveAtChan: make(chan time.Time, 2),\n\t\t// capacity is 2 because close() and dstToTransport routine in Serve() can write to this channel\n\t\tcloseChan: make(chan error, 2),\n\t\tlog:       &logger,\n\t}\n}\n\nfunc (m *manager) UnregisterSession(ctx context.Context, sessionID uuid.UUID, message string, byRemote bool) error {\n\tctx, cancel := context.WithTimeout(ctx, m.timeout)\n\tdefer cancel()\n\tevent := &unregisterSessionEvent{\n\t\tsessionID: sessionID,\n\t\terr: &errClosedSession{\n\t\t\tmessage:  message,\n\t\t\tbyRemote: byRemote,\n\t\t},\n\t}\n\tselect {\n\tcase <-ctx.Done():\n\t\tm.log.Error().Msg(\"Datagram session unregistration timeout\")\n\t\treturn ctx.Err()\n\tcase m.unregistrationChan <- event:\n\t\treturn nil\n\tcase <-m.closedChan:\n\t\treturn errSessionManagerClosed\n\t}\n}\n\nfunc (m *manager) unregisterSession(unregistration *unregisterSessionEvent) {\n\tsession, ok := m.sessions[unregistration.sessionID]\n\tif ok {\n\t\tdelete(m.sessions, unregistration.sessionID)\n\t\tsession.close(unregistration.err)\n\t\tdecrementUDPActiveSessions()\n\t}\n}\n\nfunc (m *manager) sendToSession(datagram *packet.Session) {\n\tsession, ok := m.sessions[datagram.ID]\n\tif !ok {\n\t\tm.log.Error().Str(LogFieldSessionID, FormatSessionID(datagram.ID)).Msg(\"session not found\")\n\t\treturn\n\t}\n\t// session writes to destination over a connected UDP socket, which should not be blocking, so this call doesn't\n\t// need to run in another go routine\n\tsession.transportToDst(datagram.Payload)\n}\n"
  },
  {
    "path": "datagramsession/manager_test.go",
    "content": "package datagramsession\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/require\"\n\t\"golang.org/x/sync/errgroup\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n)\n\nvar (\n\tnopLogger = zerolog.Nop()\n)\n\nfunc TestManagerServe(t *testing.T) {\n\tconst (\n\t\tsessions            = 2\n\t\tmsgs                = 5\n\t\tremoteUnregisterMsg = \"eyeball closed connection\"\n\t)\n\n\trequestChan := make(chan *packet.Session)\n\ttransport := mockQUICTransport{\n\t\tsessions: make(map[uuid.UUID]chan []byte),\n\t}\n\tfor i := 0; i < sessions; i++ {\n\t\ttransport.sessions[uuid.New()] = make(chan []byte)\n\t}\n\n\tmg := NewManager(&nopLogger, transport.MuxSession, requestChan)\n\n\tctx, cancel := context.WithCancel(context.Background())\n\tserveDone := make(chan struct{})\n\tgo func(ctx context.Context) {\n\t\tmg.Serve(ctx)\n\t\tclose(serveDone)\n\t}(ctx)\n\n\terrGroup, ctx := errgroup.WithContext(ctx)\n\tfor sessionID, eyeballRespChan := range transport.sessions {\n\t\t// Assign loop variables to local variables\n\t\tsID := sessionID\n\t\tpayload := testPayload(sID)\n\t\texpectResp := testResponse(payload)\n\n\t\tcfdConn, originConn := net.Pipe()\n\n\t\torigin := mockOrigin{\n\t\t\texpectMsgCount: msgs,\n\t\t\texpectedMsg:    payload,\n\t\t\texpectedResp:   expectResp,\n\t\t\tconn:           originConn,\n\t\t}\n\n\t\teyeball := mockEyeballSession{\n\t\t\tid:               sID,\n\t\t\texpectedMsgCount: msgs,\n\t\t\texpectedMsg:      payload,\n\t\t\texpectedResponse: expectResp,\n\t\t\trespReceiver:     eyeballRespChan,\n\t\t}\n\n\t\t// Assign loop variables to local variables\n\t\terrGroup.Go(func() error {\n\t\t\tsession, err := mg.RegisterSession(ctx, sID, cfdConn)\n\t\t\trequire.NoError(t, err)\n\t\t\treqErrGroup, reqCtx := errgroup.WithContext(ctx)\n\t\t\treqErrGroup.Go(func() error {\n\t\t\t\treturn origin.serve()\n\t\t\t})\n\t\t\treqErrGroup.Go(func() error {\n\t\t\t\treturn eyeball.serve(reqCtx, requestChan)\n\t\t\t})\n\n\t\t\tsessionDone := make(chan struct{})\n\t\t\tgo func() {\n\t\t\t\tclosedByRemote, err := session.Serve(ctx, time.Minute*2)\n\t\t\t\tcloseSession := &errClosedSession{\n\t\t\t\t\tmessage:  remoteUnregisterMsg,\n\t\t\t\t\tbyRemote: true,\n\t\t\t\t}\n\t\t\t\trequire.Equal(t, closeSession, err)\n\t\t\t\trequire.True(t, closedByRemote)\n\t\t\t\tclose(sessionDone)\n\t\t\t}()\n\n\t\t\t// Make sure eyeball and origin have received all messages before unregistering the session\n\t\t\trequire.NoError(t, reqErrGroup.Wait())\n\n\t\t\trequire.NoError(t, mg.UnregisterSession(ctx, sID, remoteUnregisterMsg, true))\n\t\t\t<-sessionDone\n\t\t\treturn nil\n\t\t})\n\t}\n\n\trequire.NoError(t, errGroup.Wait())\n\tcancel()\n\t<-serveDone\n}\n\nfunc TestTimeout(t *testing.T) {\n\tconst (\n\t\ttestTimeout = time.Millisecond * 50\n\t)\n\n\tmg := NewManager(&nopLogger, nil, nil)\n\tmg.timeout = testTimeout\n\tctx := context.Background()\n\tsessionID := uuid.New()\n\t// session manager is not running, so event loop is not running and therefore calling the APIs should timeout\n\tsession, err := mg.RegisterSession(ctx, sessionID, nil)\n\trequire.ErrorIs(t, err, context.DeadlineExceeded)\n\trequire.Nil(t, session)\n\n\terr = mg.UnregisterSession(ctx, sessionID, \"session gone\", true)\n\trequire.ErrorIs(t, err, context.DeadlineExceeded)\n}\n\nfunc TestUnregisterSessionCloseSession(t *testing.T) {\n\tsessionID := uuid.New()\n\tpayload := []byte(t.Name())\n\tsender := newMockTransportSender(sessionID, payload)\n\tmg := NewManager(&nopLogger, sender.muxSession, nil)\n\tctx, cancel := context.WithCancel(context.Background())\n\n\tmanagerDone := make(chan struct{})\n\tgo func() {\n\t\terr := mg.Serve(ctx)\n\t\trequire.Error(t, err)\n\t\tclose(managerDone)\n\t}()\n\n\tcfdConn, originConn := net.Pipe()\n\tsession, err := mg.RegisterSession(ctx, sessionID, cfdConn)\n\trequire.NoError(t, err)\n\trequire.NotNil(t, session)\n\n\tunregisteredChan := make(chan struct{})\n\tgo func() {\n\t\t_, err := originConn.Write(payload)\n\t\trequire.NoError(t, err)\n\n\t\terr = mg.UnregisterSession(ctx, sessionID, \"eyeball closed session\", true)\n\t\trequire.NoError(t, err)\n\n\t\tclose(unregisteredChan)\n\t}()\n\n\tclosedByRemote, err := session.Serve(ctx, time.Minute)\n\trequire.True(t, closedByRemote)\n\trequire.Error(t, err)\n\n\t<-unregisteredChan\n\tcancel()\n\t<-managerDone\n}\n\nfunc TestManagerCtxDoneCloseSessions(t *testing.T) {\n\tsessionID := uuid.New()\n\tpayload := []byte(t.Name())\n\tsender := newMockTransportSender(sessionID, payload)\n\tmg := NewManager(&nopLogger, sender.muxSession, nil)\n\tctx, cancel := context.WithCancel(context.Background())\n\n\tvar wg sync.WaitGroup\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\terr := mg.Serve(ctx)\n\t\trequire.Error(t, err)\n\t}()\n\n\tcfdConn, originConn := net.Pipe()\n\tsession, err := mg.RegisterSession(ctx, sessionID, cfdConn)\n\trequire.NoError(t, err)\n\trequire.NotNil(t, session)\n\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\t_, err := originConn.Write(payload)\n\t\trequire.NoError(t, err)\n\t\tcancel()\n\t}()\n\n\tclosedByRemote, err := session.Serve(ctx, time.Minute)\n\trequire.False(t, closedByRemote)\n\trequire.Error(t, err)\n\n\twg.Wait()\n}\n\ntype mockOrigin struct {\n\texpectMsgCount int\n\texpectedMsg    []byte\n\texpectedResp   []byte\n\tconn           io.ReadWriteCloser\n}\n\nfunc (mo *mockOrigin) serve() error {\n\texpectedMsgLen := len(mo.expectedMsg)\n\treadBuffer := make([]byte, expectedMsgLen+1)\n\tfor i := 0; i < mo.expectMsgCount; i++ {\n\t\tn, err := mo.conn.Read(readBuffer)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif n != expectedMsgLen {\n\t\t\treturn fmt.Errorf(\"Expect to read %d bytes, read %d\", expectedMsgLen, n)\n\t\t}\n\t\tif !bytes.Equal(readBuffer[:n], mo.expectedMsg) {\n\t\t\treturn fmt.Errorf(\"Expect %v, read %v\", mo.expectedMsg, readBuffer[:n])\n\t\t}\n\t\t_, err = mo.conn.Write(mo.expectedResp)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc testPayload(sessionID uuid.UUID) []byte {\n\treturn []byte(fmt.Sprintf(\"Message from %s\", sessionID))\n}\n\nfunc testResponse(msg []byte) []byte {\n\treturn []byte(fmt.Sprintf(\"Response to %v\", msg))\n}\n\ntype mockQUICTransport struct {\n\tsessions map[uuid.UUID]chan []byte\n}\n\nfunc (me *mockQUICTransport) MuxSession(session *packet.Session) error {\n\ts := me.sessions[session.ID]\n\ts <- session.Payload\n\treturn nil\n}\n\ntype mockEyeballSession struct {\n\tid               uuid.UUID\n\texpectedMsgCount int\n\texpectedMsg      []byte\n\texpectedResponse []byte\n\trespReceiver     <-chan []byte\n}\n\nfunc (me *mockEyeballSession) serve(ctx context.Context, requestChan chan *packet.Session) error {\n\tfor i := 0; i < me.expectedMsgCount; i++ {\n\t\trequestChan <- &packet.Session{\n\t\t\tID:      me.id,\n\t\t\tPayload: me.expectedMsg,\n\t\t}\n\t\tresp := <-me.respReceiver\n\t\tif !bytes.Equal(resp, me.expectedResponse) {\n\t\t\treturn fmt.Errorf(\"Expect %v, read %v\", me.expectedResponse, resp)\n\t\t}\n\t\tfmt.Println(\"Resp\", resp)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "datagramsession/metrics.go",
    "content": "package datagramsession\n\nimport (\n\t\"github.com/prometheus/client_golang/prometheus\"\n)\n\nconst (\n\tnamespace = \"cloudflared\"\n)\n\nvar (\n\tactiveUDPSessions = prometheus.NewGauge(prometheus.GaugeOpts{\n\t\tNamespace: namespace,\n\t\tSubsystem: \"udp\",\n\t\tName:      \"active_sessions\",\n\t\tHelp:      \"Concurrent count of UDP sessions that are being proxied to any origin\",\n\t})\n\ttotalUDPSessions = prometheus.NewCounter(prometheus.CounterOpts{\n\t\tNamespace: namespace,\n\t\tSubsystem: \"udp\",\n\t\tName:      \"total_sessions\",\n\t\tHelp:      \"Total count of UDP sessions that have been proxied to any origin\",\n\t})\n)\n\nfunc init() {\n\tprometheus.MustRegister(\n\t\tactiveUDPSessions,\n\t\ttotalUDPSessions,\n\t)\n}\n\nfunc incrementUDPSessions() {\n\ttotalUDPSessions.Inc()\n\tactiveUDPSessions.Inc()\n}\n\nfunc decrementUDPActiveSessions() {\n\tactiveUDPSessions.Dec()\n}\n"
  },
  {
    "path": "datagramsession/session.go",
    "content": "package datagramsession\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n)\n\nconst (\n\tdefaultCloseIdleAfter = time.Second * 210\n)\n\nfunc SessionIdleErr(timeout time.Duration) error {\n\treturn fmt.Errorf(\"session idle for %v\", timeout)\n}\n\ntype transportSender func(session *packet.Session) error\n\n// ErrVithVariableSeverity are errors that have variable severity\ntype ErrVithVariableSeverity interface {\n\terror\n\t// LogLevel return the severity of this error\n\tLogLevel() zerolog.Level\n}\n\n// Session is a bidirectional pipe of datagrams between transport and dstConn\n// Destination can be a connection with origin or with eyeball\n// When the destination is origin:\n// - Manager receives datagrams from receiveChan and calls the transportToDst method of the Session to send to origin\n// - Datagrams from origin are read from conn and Send to transport using the transportSender callback. Transport will return them to eyeball\n// When the destination is eyeball:\n// - Datagrams from eyeball are read from conn and Send to transport. Transport will send them to cloudflared using the transportSender callback.\n// - Manager receives datagrams from receiveChan and calls the transportToDst method of the Session to send to the eyeball\ntype Session struct {\n\tID       uuid.UUID\n\tsendFunc transportSender\n\tdstConn  io.ReadWriteCloser\n\t// activeAtChan is used to communicate the last read/write time\n\tactiveAtChan chan time.Time\n\tcloseChan    chan error\n\tlog          *zerolog.Logger\n}\n\nfunc (s *Session) Serve(ctx context.Context, closeAfterIdle time.Duration) (closedByRemote bool, err error) {\n\tgo func() {\n\t\t// QUIC implementation copies data to another buffer before returning https://github.com/quic-go/quic-go/blob/v0.24.0/session.go#L1967-L1975\n\t\t// This makes it safe to share readBuffer between iterations\n\t\tconst maxPacketSize = 1500\n\t\treadBuffer := make([]byte, maxPacketSize)\n\t\tfor {\n\t\t\tif closeSession, err := s.dstToTransport(readBuffer); err != nil {\n\t\t\t\tif errors.Is(err, net.ErrClosed) || errors.Is(err, io.EOF) {\n\t\t\t\t\ts.log.Debug().Msg(\"Destination connection closed\")\n\t\t\t\t} else {\n\t\t\t\t\tlevel := zerolog.ErrorLevel\n\t\t\t\t\tif variableErr, ok := err.(ErrVithVariableSeverity); ok {\n\t\t\t\t\t\tlevel = variableErr.LogLevel()\n\t\t\t\t\t}\n\t\t\t\t\ts.log.WithLevel(level).Err(err).Msg(\"Failed to send session payload from destination to transport\")\n\t\t\t\t}\n\t\t\t\tif closeSession {\n\t\t\t\t\ts.closeChan <- err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n\terr = s.waitForCloseCondition(ctx, closeAfterIdle)\n\tif closeSession, ok := err.(*errClosedSession); ok {\n\t\tclosedByRemote = closeSession.byRemote\n\t}\n\treturn closedByRemote, err\n}\n\nfunc (s *Session) waitForCloseCondition(ctx context.Context, closeAfterIdle time.Duration) error {\n\t// Closing dstConn cancels read so dstToTransport routine in Serve() can return\n\tdefer s.dstConn.Close()\n\tif closeAfterIdle == 0 {\n\t\t// provide default is caller doesn't specify one\n\t\tcloseAfterIdle = defaultCloseIdleAfter\n\t}\n\n\tcheckIdleFreq := closeAfterIdle / 8\n\tcheckIdleTicker := time.NewTicker(checkIdleFreq)\n\tdefer checkIdleTicker.Stop()\n\n\tactiveAt := time.Now()\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tcase reason := <-s.closeChan:\n\t\t\treturn reason\n\t\t// TODO: TUN-5423 evaluate if using atomic is more efficient\n\t\tcase now := <-checkIdleTicker.C:\n\t\t\t// The session is considered inactive if current time is after (last active time + allowed idle time)\n\t\t\tif now.After(activeAt.Add(closeAfterIdle)) {\n\t\t\t\treturn SessionIdleErr(closeAfterIdle)\n\t\t\t}\n\t\tcase activeAt = <-s.activeAtChan: // Update last active time\n\t\t}\n\t}\n}\n\nfunc (s *Session) dstToTransport(buffer []byte) (closeSession bool, err error) {\n\tn, err := s.dstConn.Read(buffer)\n\ts.markActive()\n\t// https://pkg.go.dev/io#Reader suggests caller should always process n > 0 bytes\n\tif n > 0 || err == nil {\n\t\tsession := packet.Session{\n\t\t\tID:      s.ID,\n\t\t\tPayload: buffer[:n],\n\t\t}\n\t\tif sendErr := s.sendFunc(&session); sendErr != nil {\n\t\t\treturn false, sendErr\n\t\t}\n\t}\n\treturn err != nil, err\n}\n\nfunc (s *Session) transportToDst(payload []byte) (int, error) {\n\ts.markActive()\n\tn, err := s.dstConn.Write(payload)\n\tif err != nil {\n\t\ts.log.Err(err).Msg(\"Failed to write payload to session\")\n\t}\n\treturn n, err\n}\n\n// Sends the last active time to the idle checker loop without blocking. activeAtChan will only be full when there\n// are many concurrent read/write. It is fine to lose some precision\nfunc (s *Session) markActive() {\n\tselect {\n\tcase s.activeAtChan <- time.Now():\n\tdefault:\n\t}\n}\n\nfunc (s *Session) close(err *errClosedSession) {\n\ts.closeChan <- err\n}\n"
  },
  {
    "path": "datagramsession/session_test.go",
    "content": "package datagramsession\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"golang.org/x/sync/errgroup\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n)\n\n// TestCloseSession makes sure a session will stop after context is done\nfunc TestSessionCtxDone(t *testing.T) {\n\ttestSessionReturns(t, closeByContext, time.Minute*2)\n}\n\n// TestCloseSession makes sure a session will stop after close method is called\nfunc TestCloseSession(t *testing.T) {\n\ttestSessionReturns(t, closeByCallingClose, time.Minute*2)\n}\n\n// TestCloseIdle makess sure a session will stop after there is no read/write for a period defined by closeAfterIdle\nfunc TestCloseIdle(t *testing.T) {\n\ttestSessionReturns(t, closeByTimeout, time.Millisecond*100)\n}\n\nfunc testSessionReturns(t *testing.T, closeBy closeMethod, closeAfterIdle time.Duration) {\n\tlocalCloseReason := &errClosedSession{\n\t\tmessage:  \"connection closed by origin\",\n\t\tbyRemote: false,\n\t}\n\tsessionID := uuid.New()\n\tcfdConn, originConn := net.Pipe()\n\tpayload := testPayload(sessionID)\n\n\tlog := zerolog.Nop()\n\tmg := NewManager(&log, nil, nil)\n\tsession := mg.newSession(sessionID, cfdConn)\n\n\tctx, cancel := context.WithCancel(t.Context())\n\tsessionDone := make(chan struct{})\n\tgo func() {\n\t\tclosedByRemote, err := session.Serve(ctx, closeAfterIdle)\n\t\tswitch closeBy {\n\t\tcase closeByContext:\n\t\t\tassert.Equal(t, context.Canceled, err)\n\t\t\tassert.False(t, closedByRemote)\n\t\tcase closeByCallingClose:\n\t\t\tassert.Equal(t, localCloseReason, err)\n\t\t\tassert.Equal(t, localCloseReason.byRemote, closedByRemote)\n\t\tcase closeByTimeout:\n\t\t\tassert.Equal(t, SessionIdleErr(closeAfterIdle), err)\n\t\t\tassert.False(t, closedByRemote)\n\t\t}\n\t\tclose(sessionDone)\n\t}()\n\n\tgo func() {\n\t\tn, err := session.transportToDst(payload)\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, len(payload), n)\n\t}()\n\n\treadBuffer := make([]byte, len(payload)+1)\n\tn, err := originConn.Read(readBuffer)\n\trequire.NoError(t, err)\n\trequire.Equal(t, len(payload), n)\n\n\tlastRead := time.Now()\n\n\tswitch closeBy {\n\tcase closeByContext:\n\t\tcancel()\n\tcase closeByCallingClose:\n\t\tsession.close(localCloseReason)\n\tdefault:\n\t\t// ignore\n\t}\n\n\t<-sessionDone\n\tif closeBy == closeByTimeout {\n\t\trequire.True(t, time.Now().After(lastRead.Add(closeAfterIdle)))\n\t}\n\t// call cancelled again otherwise the linter will warn about possible context leak\n\tcancel()\n}\n\ntype closeMethod int\n\nconst (\n\tcloseByContext closeMethod = iota\n\tcloseByCallingClose\n\tcloseByTimeout\n)\n\nfunc TestWriteToDstSessionPreventClosed(t *testing.T) {\n\ttestActiveSessionNotClosed(t, false, true)\n}\n\nfunc TestReadFromDstSessionPreventClosed(t *testing.T) {\n\ttestActiveSessionNotClosed(t, true, false)\n}\n\nfunc testActiveSessionNotClosed(t *testing.T, readFromDst bool, writeToDst bool) {\n\tconst closeAfterIdle = time.Millisecond * 100\n\tconst activeTime = time.Millisecond * 500\n\n\tsessionID := uuid.New()\n\tcfdConn, originConn := net.Pipe()\n\tpayload := testPayload(sessionID)\n\n\trespChan := make(chan *packet.Session)\n\tsender := newMockTransportSender(sessionID, payload)\n\tmg := NewManager(&nopLogger, sender.muxSession, respChan)\n\tsession := mg.newSession(sessionID, cfdConn)\n\n\tstartTime := time.Now()\n\tactiveUntil := startTime.Add(activeTime)\n\tctx, cancel := context.WithCancel(t.Context())\n\terrGroup, ctx := errgroup.WithContext(ctx)\n\terrGroup.Go(func() error {\n\t\t_, _ = session.Serve(ctx, closeAfterIdle)\n\t\tif time.Now().Before(startTime.Add(activeTime)) {\n\t\t\treturn fmt.Errorf(\"session closed while it's still active\")\n\t\t}\n\t\treturn nil\n\t})\n\n\tif readFromDst {\n\t\terrGroup.Go(func() error {\n\t\t\tfor {\n\t\t\t\tif time.Now().After(activeUntil) {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\tif _, err := originConn.Write(payload); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\ttime.Sleep(closeAfterIdle / 2)\n\t\t\t}\n\t\t})\n\t}\n\tif writeToDst {\n\t\terrGroup.Go(func() error {\n\t\t\treadBuffer := make([]byte, len(payload))\n\t\t\tfor {\n\t\t\t\tn, err := originConn.Read(readBuffer)\n\t\t\t\tif err != nil {\n\t\t\t\t\tif err == io.EOF || err == io.ErrClosedPipe {\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif !bytes.Equal(payload, readBuffer[:n]) {\n\t\t\t\t\treturn fmt.Errorf(\"payload %v is not equal to %v\", readBuffer[:n], payload)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t\terrGroup.Go(func() error {\n\t\t\tfor {\n\t\t\t\tif time.Now().After(activeUntil) {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\tif _, err := session.transportToDst(payload); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\ttime.Sleep(closeAfterIdle / 2)\n\t\t\t}\n\t\t})\n\t}\n\n\trequire.NoError(t, errGroup.Wait())\n\tcancel()\n}\n\nfunc TestMarkActiveNotBlocking(t *testing.T) {\n\tconst concurrentCalls = 50\n\tmg := NewManager(&nopLogger, nil, nil)\n\tsession := mg.newSession(uuid.New(), nil)\n\tvar wg sync.WaitGroup\n\twg.Add(concurrentCalls)\n\tfor i := 0; i < concurrentCalls; i++ {\n\t\tgo func() {\n\t\t\tsession.markActive()\n\t\t\twg.Done()\n\t\t}()\n\t}\n\twg.Wait()\n}\n\n// Some UDP application might send 0-size payload.\nfunc TestZeroBytePayload(t *testing.T) {\n\tsessionID := uuid.New()\n\tcfdConn, originConn := net.Pipe()\n\n\tsender := sendOnceTransportSender{\n\t\tbaseSender: newMockTransportSender(sessionID, make([]byte, 0)),\n\t\tsentChan:   make(chan struct{}),\n\t}\n\tmg := NewManager(&nopLogger, sender.muxSession, nil)\n\tsession := mg.newSession(sessionID, cfdConn)\n\n\tctx, cancel := context.WithCancel(t.Context())\n\terrGroup, ctx := errgroup.WithContext(ctx)\n\terrGroup.Go(func() error {\n\t\t// Read from underlying conn and send to transport\n\t\tclosedByRemote, err := session.Serve(ctx, time.Minute*2)\n\t\trequire.Equal(t, context.Canceled, err)\n\t\trequire.False(t, closedByRemote)\n\t\treturn nil\n\t})\n\n\terrGroup.Go(func() error {\n\t\t// Write to underlying connection\n\t\tn, err := originConn.Write([]byte{})\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, 0, n)\n\t\treturn nil\n\t})\n\n\t<-sender.sentChan\n\tcancel()\n\trequire.NoError(t, errGroup.Wait())\n}\n\ntype mockTransportSender struct {\n\texpectedSessionID uuid.UUID\n\texpectedPayload   []byte\n}\n\nfunc newMockTransportSender(expectedSessionID uuid.UUID, expectedPayload []byte) *mockTransportSender {\n\treturn &mockTransportSender{\n\t\texpectedSessionID: expectedSessionID,\n\t\texpectedPayload:   expectedPayload,\n\t}\n}\n\nfunc (mts *mockTransportSender) muxSession(session *packet.Session) error {\n\tif session.ID != mts.expectedSessionID {\n\t\treturn fmt.Errorf(\"Expect session %s, got %s\", mts.expectedSessionID, session.ID)\n\t}\n\tif !bytes.Equal(session.Payload, mts.expectedPayload) {\n\t\treturn fmt.Errorf(\"Expect %v, read %v\", mts.expectedPayload, session.Payload)\n\t}\n\treturn nil\n}\n\ntype sendOnceTransportSender struct {\n\tbaseSender *mockTransportSender\n\tsentChan   chan struct{}\n}\n\nfunc (sots *sendOnceTransportSender) muxSession(session *packet.Session) error {\n\tdefer close(sots.sentChan)\n\treturn sots.baseSender.muxSession(session)\n}\n"
  },
  {
    "path": "diagnostic/client.go",
    "content": "package diagnostic\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n\n\tcfdflags \"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n)\n\ntype httpClient struct {\n\thttp.Client\n\tbaseURL *url.URL\n}\n\nfunc NewHTTPClient() *httpClient {\n\thttpTransport := http.Transport{\n\t\tTLSHandshakeTimeout:   defaultTimeout,\n\t\tResponseHeaderTimeout: defaultTimeout,\n\t}\n\n\treturn &httpClient{\n\t\thttp.Client{\n\t\t\tTransport: &httpTransport,\n\t\t\tTimeout:   defaultTimeout,\n\t\t},\n\t\tnil,\n\t}\n}\n\nfunc (client *httpClient) SetBaseURL(baseURL *url.URL) {\n\tclient.baseURL = baseURL\n}\n\nfunc (client *httpClient) GET(ctx context.Context, endpoint string) (*http.Response, error) {\n\tif client.baseURL == nil {\n\t\treturn nil, ErrNoBaseURL\n\t}\n\turl := client.baseURL.JoinPath(endpoint)\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, url.String(), nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error creating GET request: %w\", err)\n\t}\n\n\treq.Header.Add(\"Accept\", \"application/json;version=1\")\n\n\tresponse, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error GET request: %w\", err)\n\t}\n\n\treturn response, nil\n}\n\ntype LogConfiguration struct {\n\tlogFile      string\n\tlogDirectory string\n\tuid          int // the uid of the user that started cloudflared\n}\n\nfunc (client *httpClient) GetLogConfiguration(ctx context.Context) (*LogConfiguration, error) {\n\tresponse, err := client.GET(ctx, cliConfigurationEndpoint)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdefer response.Body.Close()\n\n\tvar data map[string]string\n\tif err := json.NewDecoder(response.Body).Decode(&data); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode body: %w\", err)\n\t}\n\n\tuidStr, exists := data[configurationKeyUID]\n\tif !exists {\n\t\treturn nil, ErrKeyNotFound\n\t}\n\n\tuid, err := strconv.Atoi(uidStr)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error convertin pid to int: %w\", err)\n\t}\n\n\tlogFile, exists := data[cfdflags.LogFile]\n\tif exists {\n\t\treturn &LogConfiguration{logFile, \"\", uid}, nil\n\t}\n\n\tlogDirectory, exists := data[cfdflags.LogDirectory]\n\tif exists {\n\t\treturn &LogConfiguration{\"\", logDirectory, uid}, nil\n\t}\n\n\t// No log configured may happen when cloudflared is executed as a managed service or\n\t// when containerized\n\treturn &LogConfiguration{\"\", \"\", uid}, nil\n}\n\nfunc (client *httpClient) GetMemoryDump(ctx context.Context, writer io.Writer) error {\n\tresponse, err := client.GET(ctx, memoryDumpEndpoint)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn copyToWriter(response, writer)\n}\n\nfunc (client *httpClient) GetGoroutineDump(ctx context.Context, writer io.Writer) error {\n\tresponse, err := client.GET(ctx, goroutineDumpEndpoint)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn copyToWriter(response, writer)\n}\n\nfunc (client *httpClient) GetTunnelState(ctx context.Context) (*TunnelState, error) {\n\tresponse, err := client.GET(ctx, tunnelStateEndpoint)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdefer response.Body.Close()\n\n\tvar state TunnelState\n\tif err := json.NewDecoder(response.Body).Decode(&state); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode body: %w\", err)\n\t}\n\n\treturn &state, nil\n}\n\nfunc (client *httpClient) GetSystemInformation(ctx context.Context, writer io.Writer) error {\n\tresponse, err := client.GET(ctx, systemInformationEndpoint)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn copyJSONToWriter(response, writer)\n}\n\nfunc (client *httpClient) GetMetrics(ctx context.Context, writer io.Writer) error {\n\tresponse, err := client.GET(ctx, metricsEndpoint)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn copyToWriter(response, writer)\n}\n\nfunc (client *httpClient) GetTunnelConfiguration(ctx context.Context, writer io.Writer) error {\n\tresponse, err := client.GET(ctx, tunnelConfigurationEndpoint)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn copyJSONToWriter(response, writer)\n}\n\nfunc (client *httpClient) GetCliConfiguration(ctx context.Context, writer io.Writer) error {\n\tresponse, err := client.GET(ctx, cliConfigurationEndpoint)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn copyJSONToWriter(response, writer)\n}\n\nfunc copyToWriter(response *http.Response, writer io.Writer) error {\n\tdefer response.Body.Close()\n\n\t_, err := io.Copy(writer, response.Body)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error writing response: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc copyJSONToWriter(response *http.Response, writer io.Writer) error {\n\tdefer response.Body.Close()\n\n\tvar data interface{}\n\n\tdecoder := json.NewDecoder(response.Body)\n\n\terr := decoder.Decode(&data)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"diagnostic client error whilst reading response: %w\", err)\n\t}\n\n\tencoder := newFormattedEncoder(writer)\n\n\terr = encoder.Encode(data)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"diagnostic client error whilst writing json: %w\", err)\n\t}\n\n\treturn nil\n}\n\ntype HTTPClient interface {\n\tGetLogConfiguration(ctx context.Context) (*LogConfiguration, error)\n\tGetMemoryDump(ctx context.Context, writer io.Writer) error\n\tGetGoroutineDump(ctx context.Context, writer io.Writer) error\n\tGetTunnelState(ctx context.Context) (*TunnelState, error)\n\tGetSystemInformation(ctx context.Context, writer io.Writer) error\n\tGetMetrics(ctx context.Context, writer io.Writer) error\n\tGetCliConfiguration(ctx context.Context, writer io.Writer) error\n\tGetTunnelConfiguration(ctx context.Context, writer io.Writer) error\n}\n"
  },
  {
    "path": "diagnostic/consts.go",
    "content": "package diagnostic\n\nimport \"time\"\n\nconst (\n\tdefaultCollectorTimeout    = time.Second * 10       // This const define the timeout value of a collector operation.\n\tcollectorField             = \"collector\"            // used for logging purposes\n\tsystemCollectorName        = \"system\"               // used for logging purposes\n\ttunnelStateCollectorName   = \"tunnelState\"          // used for logging purposes\n\tconfigurationCollectorName = \"configuration\"        // used for logging purposes\n\tdefaultTimeout             = 15 * time.Second       // timeout for the collectors\n\ttwoWeeksOffset             = -14 * 24 * time.Hour   // maximum offset for the logs\n\tlogFilename                = \"cloudflared_logs.txt\" // name of the output log file\n\tconfigurationKeyUID        = \"uid\"                  // Key used to set and get the UID value from the configuration map\n\ttailMaxNumberOfLines       = \"10000\"                // maximum number of log lines from a virtual runtime (docker or kubernetes)\n\n\t// Endpoints used by the diagnostic HTTP Client.\n\tcliConfigurationEndpoint    = \"/diag/configuration\"\n\ttunnelStateEndpoint         = \"/diag/tunnel\"\n\tsystemInformationEndpoint   = \"/diag/system\"\n\tmemoryDumpEndpoint          = \"debug/pprof/heap\"\n\tgoroutineDumpEndpoint       = \"debug/pprof/goroutine\"\n\tmetricsEndpoint             = \"metrics\"\n\ttunnelConfigurationEndpoint = \"/config\"\n\t// Base for filenames of the diagnostic procedure\n\tsystemInformationBaseName = \"systeminformation.json\"\n\tmetricsBaseName           = \"metrics.txt\"\n\tzipName                   = \"cloudflared-diag\"\n\theapPprofBaseName         = \"heap.pprof\"\n\tgoroutinePprofBaseName    = \"goroutine.pprof\"\n\tnetworkBaseName           = \"network.json\"\n\trawNetworkBaseName        = \"raw-network.txt\"\n\ttunnelStateBaseName       = \"tunnelstate.json\"\n\tcliConfigurationBaseName  = \"cli-configuration.json\"\n\tconfigurationBaseName     = \"configuration.json\"\n\ttaskResultBaseName        = \"task-result.json\"\n)\n"
  },
  {
    "path": "diagnostic/diagnostic.go",
    "content": "package diagnostic\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/rs/zerolog\"\n\n\tnetwork \"github.com/cloudflare/cloudflared/diagnostic/network\"\n)\n\nconst (\n\ttaskSuccess                  = \"success\"\n\ttaskFailure                  = \"failure\"\n\tjobReportName                = \"job report\"\n\ttunnelStateJobName           = \"tunnel state\"\n\tsystemInformationJobName     = \"system information\"\n\tgoroutineJobName             = \"goroutine profile\"\n\theapJobName                  = \"heap profile\"\n\tmetricsJobName               = \"metrics\"\n\tlogInformationJobName        = \"log information\"\n\trawNetworkInformationJobName = \"raw network information\"\n\tnetworkInformationJobName    = \"network information\"\n\tcliConfigurationJobName      = \"cli configuration\"\n\tconfigurationJobName         = \"configuration\"\n)\n\n// Struct used to hold the results of different routines executing the network collection.\ntype taskResult struct {\n\tResult string `json:\"result,omitempty\"`\n\tErr    error  `json:\"error,omitempty\"`\n\tpath   string\n}\n\nfunc (result taskResult) MarshalJSON() ([]byte, error) {\n\ts := map[string]string{\n\t\t\"result\": result.Result,\n\t}\n\tif result.Err != nil {\n\t\ts[\"error\"] = result.Err.Error()\n\t}\n\n\treturn json.Marshal(s)\n}\n\n// Struct used to hold the results of different routines executing the network collection.\ntype networkCollectionResult struct {\n\tname string\n\tinfo []*network.Hop\n\traw  string\n\terr  error\n}\n\n// This type represents the most common functions from the diagnostic http client\n// functions.\ntype collectToWriterFunc func(ctx context.Context, writer io.Writer) error\n\n// This type represents the common denominator among all the collection procedures.\ntype collectFunc func(ctx context.Context) (string, error)\n\n// collectJob is an internal struct that denotes holds the information necessary\n// to run a collection job.\ntype collectJob struct {\n\tjobName string\n\tfn      collectFunc\n\tbypass  bool\n}\n\n// The Toggles structure denotes the available toggles for the diagnostic procedure.\n// Each toggle enables/disables tasks from the diagnostic.\ntype Toggles struct {\n\tNoDiagLogs    bool\n\tNoDiagMetrics bool\n\tNoDiagSystem  bool\n\tNoDiagRuntime bool\n\tNoDiagNetwork bool\n}\n\n// The Options structure holds every option necessary for\n// the diagnostic procedure to work.\ntype Options struct {\n\tKnownAddresses []string\n\tAddress        string\n\tContainerID    string\n\tPodID          string\n\tToggles        Toggles\n}\n\nfunc collectLogs(\n\tctx context.Context,\n\tclient HTTPClient,\n\tdiagContainer, diagPod string,\n) (string, error) {\n\tvar collector LogCollector\n\tif diagPod != \"\" {\n\t\tcollector = NewKubernetesLogCollector(diagContainer, diagPod)\n\t} else if diagContainer != \"\" {\n\t\tcollector = NewDockerLogCollector(diagContainer)\n\t} else {\n\t\tcollector = NewHostLogCollector(client)\n\t}\n\n\tlogInformation, err := collector.Collect(ctx)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error collecting logs: %w\", err)\n\t}\n\n\tif logInformation.isDirectory {\n\t\treturn CopyFilesFromDirectory(logInformation.path)\n\t}\n\n\tif logInformation.wasCreated {\n\t\treturn logInformation.path, nil\n\t}\n\n\tlogHandle, err := os.Open(logInformation.path)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error opening log file while collecting logs: %w\", err)\n\t}\n\tdefer logHandle.Close()\n\n\toutputLogHandle, err := os.Create(filepath.Join(os.TempDir(), logFilename))\n\tif err != nil {\n\t\treturn \"\", ErrCreatingTemporaryFile\n\t}\n\tdefer outputLogHandle.Close()\n\n\t_, err = io.Copy(outputLogHandle, logHandle)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error copying logs while collecting logs: %w\", err)\n\t}\n\n\treturn outputLogHandle.Name(), err\n}\n\nfunc collectNetworkResultRoutine(\n\tctx context.Context,\n\tcollector network.NetworkCollector,\n\thostname string,\n\tuseIPv4 bool,\n\tresults chan networkCollectionResult,\n) {\n\tconst (\n\t\thopsNo  = 5\n\t\ttimeout = time.Second * 5\n\t)\n\n\tname := hostname\n\n\tif useIPv4 {\n\t\tname += \"-v4\"\n\t} else {\n\t\tname += \"-v6\"\n\t}\n\n\thops, raw, err := collector.Collect(ctx, network.NewTraceOptions(hopsNo, timeout, hostname, useIPv4))\n\tresults <- networkCollectionResult{name, hops, raw, err}\n}\n\nfunc gatherNetworkInformation(ctx context.Context) map[string]networkCollectionResult {\n\tnetworkCollector := network.NetworkCollectorImpl{}\n\n\thostAndIPversionPairs := []struct {\n\t\thost  string\n\t\tuseV4 bool\n\t}{\n\t\t{\"region1.v2.argotunnel.com\", true},\n\t\t{\"region1.v2.argotunnel.com\", false},\n\t\t{\"region2.v2.argotunnel.com\", true},\n\t\t{\"region2.v2.argotunnel.com\", false},\n\t}\n\n\t// the number of results is known thus use len to avoid footguns\n\tresults := make(chan networkCollectionResult, len(hostAndIPversionPairs))\n\n\tvar wgroup sync.WaitGroup\n\n\tfor _, item := range hostAndIPversionPairs {\n\t\twgroup.Add(1)\n\n\t\tgo func() {\n\t\t\tdefer wgroup.Done()\n\t\t\tcollectNetworkResultRoutine(ctx, &networkCollector, item.host, item.useV4, results)\n\t\t}()\n\t}\n\n\t// Wait for routines to end.\n\twgroup.Wait()\n\n\tresultMap := make(map[string]networkCollectionResult)\n\n\tfor range len(hostAndIPversionPairs) {\n\t\tresult := <-results\n\t\tresultMap[result.name] = result\n\t}\n\n\treturn resultMap\n}\n\nfunc networkInformationCollectors() (rawNetworkCollector, jsonNetworkCollector collectFunc) {\n\t// The network collector is an operation that takes most of the diagnostic time, thus,\n\t// the sync.Once is used to memoize the result of the collector and then create different\n\t// outputs.\n\tvar once sync.Once\n\n\tvar resultMap map[string]networkCollectionResult\n\n\trawNetworkCollector = func(ctx context.Context) (string, error) {\n\t\tonce.Do(func() { resultMap = gatherNetworkInformation(ctx) })\n\n\t\treturn rawNetworkInformationWriter(resultMap)\n\t}\n\tjsonNetworkCollector = func(ctx context.Context) (string, error) {\n\t\tonce.Do(func() { resultMap = gatherNetworkInformation(ctx) })\n\n\t\treturn jsonNetworkInformationWriter(resultMap)\n\t}\n\n\treturn rawNetworkCollector, jsonNetworkCollector\n}\n\nfunc rawNetworkInformationWriter(resultMap map[string]networkCollectionResult) (string, error) {\n\tnetworkDumpHandle, err := os.Create(filepath.Join(os.TempDir(), rawNetworkBaseName))\n\tif err != nil {\n\t\treturn \"\", ErrCreatingTemporaryFile\n\t}\n\n\tdefer networkDumpHandle.Close()\n\n\tvar exitErr error\n\n\tfor k, v := range resultMap {\n\t\tif v.err != nil {\n\t\t\tif exitErr == nil {\n\t\t\t\texitErr = v.err\n\t\t\t}\n\n\t\t\t_, err := networkDumpHandle.WriteString(k + \"\\nno content\\n\")\n\t\t\tif err != nil {\n\t\t\t\treturn networkDumpHandle.Name(), fmt.Errorf(\"error writing 'no content' to raw network file: %w\", err)\n\t\t\t}\n\t\t} else {\n\t\t\t_, err := networkDumpHandle.WriteString(k + \"\\n\" + v.raw + \"\\n\")\n\t\t\tif err != nil {\n\t\t\t\treturn networkDumpHandle.Name(), fmt.Errorf(\"error writing raw network information: %w\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn networkDumpHandle.Name(), exitErr\n}\n\nfunc jsonNetworkInformationWriter(resultMap map[string]networkCollectionResult) (string, error) {\n\tnetworkDumpHandle, err := os.Create(filepath.Join(os.TempDir(), networkBaseName))\n\tif err != nil {\n\t\treturn \"\", ErrCreatingTemporaryFile\n\t}\n\n\tdefer networkDumpHandle.Close()\n\n\tencoder := newFormattedEncoder(networkDumpHandle)\n\n\tvar exitErr error\n\n\tjsonMap := make(map[string][]*network.Hop, len(resultMap))\n\tfor k, v := range resultMap {\n\t\tjsonMap[k] = v.info\n\n\t\tif exitErr == nil && v.err != nil {\n\t\t\texitErr = v.err\n\t\t}\n\t}\n\n\terr = encoder.Encode(jsonMap)\n\tif err != nil {\n\t\treturn networkDumpHandle.Name(), fmt.Errorf(\"error encoding network information results: %w\", err)\n\t}\n\n\treturn networkDumpHandle.Name(), exitErr\n}\n\nfunc collectFromEndpointAdapter(collect collectToWriterFunc, fileName string) collectFunc {\n\treturn func(ctx context.Context) (string, error) {\n\t\tdumpHandle, err := os.Create(filepath.Join(os.TempDir(), fileName))\n\t\tif err != nil {\n\t\t\treturn \"\", ErrCreatingTemporaryFile\n\t\t}\n\t\tdefer dumpHandle.Close()\n\n\t\terr = collect(ctx, dumpHandle)\n\t\tif err != nil {\n\t\t\treturn dumpHandle.Name(), fmt.Errorf(\"error running collector: %w\", err)\n\t\t}\n\n\t\treturn dumpHandle.Name(), nil\n\t}\n}\n\nfunc tunnelStateCollectEndpointAdapter(client HTTPClient, tunnel *TunnelState, fileName string) collectFunc {\n\tendpointFunc := func(ctx context.Context, writer io.Writer) error {\n\t\tif tunnel == nil {\n\t\t\t// When the metrics server is not passed the diagnostic will query all known hosts\n\t\t\t// and get the tunnel state, however, when the metrics server is passed that won't\n\t\t\t// happen hence the check for nil in this function.\n\t\t\ttunnelResponse, err := client.GetTunnelState(ctx)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"error retrieving tunnel state: %w\", err)\n\t\t\t}\n\n\t\t\ttunnel = tunnelResponse\n\t\t}\n\n\t\tencoder := newFormattedEncoder(writer)\n\n\t\terr := encoder.Encode(tunnel)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error encoding tunnel state: %w\", err)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\treturn collectFromEndpointAdapter(endpointFunc, fileName)\n}\n\n// resolveInstanceBaseURL is responsible to\n// resolve the base URL of the instance that should be diagnosed.\n// To resolve the instance it may be necessary to query the\n// /diag/tunnel endpoint of the known instances, thus, if a single\n// instance is found its state is also returned; if multiple instances\n// are found then their states are returned in an array along with an\n// error.\nfunc resolveInstanceBaseURL(\n\tmetricsServerAddress string,\n\tlog *zerolog.Logger,\n\tclient *httpClient,\n\taddresses []string,\n) (*url.URL, *TunnelState, []*AddressableTunnelState, error) {\n\tif metricsServerAddress != \"\" {\n\t\tif !strings.HasPrefix(metricsServerAddress, \"http://\") {\n\t\t\tmetricsServerAddress = \"http://\" + metricsServerAddress\n\t\t}\n\t\turl, err := url.Parse(metricsServerAddress)\n\t\tif err != nil {\n\t\t\treturn nil, nil, nil, fmt.Errorf(\"provided address is not valid: %w\", err)\n\t\t}\n\n\t\treturn url, nil, nil, nil\n\t}\n\n\ttunnelState, foundTunnelStates, err := FindMetricsServer(log, client, addresses)\n\tif err != nil {\n\t\treturn nil, nil, foundTunnelStates, err\n\t}\n\n\treturn tunnelState.URL, tunnelState.TunnelState, nil, nil\n}\n\nfunc createJobs(\n\tclient *httpClient,\n\ttunnel *TunnelState,\n\tdiagContainer string,\n\tdiagPod string,\n\tnoDiagSystem bool,\n\tnoDiagRuntime bool,\n\tnoDiagMetrics bool,\n\tnoDiagLogs bool,\n\tnoDiagNetwork bool,\n) []collectJob {\n\trawNetworkCollectorFunc, jsonNetworkCollectorFunc := networkInformationCollectors()\n\tjobs := []collectJob{\n\t\t{\n\t\t\tjobName: tunnelStateJobName,\n\t\t\tfn:      tunnelStateCollectEndpointAdapter(client, tunnel, tunnelStateBaseName),\n\t\t\tbypass:  false,\n\t\t},\n\t\t{\n\t\t\tjobName: systemInformationJobName,\n\t\t\tfn:      collectFromEndpointAdapter(client.GetSystemInformation, systemInformationBaseName),\n\t\t\tbypass:  noDiagSystem,\n\t\t},\n\t\t{\n\t\t\tjobName: goroutineJobName,\n\t\t\tfn:      collectFromEndpointAdapter(client.GetGoroutineDump, goroutinePprofBaseName),\n\t\t\tbypass:  noDiagRuntime,\n\t\t},\n\t\t{\n\t\t\tjobName: heapJobName,\n\t\t\tfn:      collectFromEndpointAdapter(client.GetMemoryDump, heapPprofBaseName),\n\t\t\tbypass:  noDiagRuntime,\n\t\t},\n\t\t{\n\t\t\tjobName: metricsJobName,\n\t\t\tfn:      collectFromEndpointAdapter(client.GetMetrics, metricsBaseName),\n\t\t\tbypass:  noDiagMetrics,\n\t\t},\n\t\t{\n\t\t\tjobName: logInformationJobName,\n\t\t\tfn: func(ctx context.Context) (string, error) {\n\t\t\t\treturn collectLogs(ctx, client, diagContainer, diagPod)\n\t\t\t},\n\t\t\tbypass: noDiagLogs,\n\t\t},\n\t\t{\n\t\t\tjobName: rawNetworkInformationJobName,\n\t\t\tfn:      rawNetworkCollectorFunc,\n\t\t\tbypass:  noDiagNetwork,\n\t\t},\n\t\t{\n\t\t\tjobName: networkInformationJobName,\n\t\t\tfn:      jsonNetworkCollectorFunc,\n\t\t\tbypass:  noDiagNetwork,\n\t\t},\n\t\t{\n\t\t\tjobName: cliConfigurationJobName,\n\t\t\tfn:      collectFromEndpointAdapter(client.GetCliConfiguration, cliConfigurationBaseName),\n\t\t\tbypass:  false,\n\t\t},\n\t\t{\n\t\t\tjobName: configurationJobName,\n\t\t\tfn:      collectFromEndpointAdapter(client.GetTunnelConfiguration, configurationBaseName),\n\t\t\tbypass:  false,\n\t\t},\n\t}\n\n\treturn jobs\n}\n\nfunc createTaskReport(taskReport map[string]taskResult) (string, error) {\n\tdumpHandle, err := os.Create(filepath.Join(os.TempDir(), taskResultBaseName))\n\tif err != nil {\n\t\treturn \"\", ErrCreatingTemporaryFile\n\t}\n\tdefer dumpHandle.Close()\n\n\tencoder := newFormattedEncoder(dumpHandle)\n\n\terr = encoder.Encode(taskReport)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error encoding task results: %w\", err)\n\t}\n\n\treturn dumpHandle.Name(), nil\n}\n\nfunc runJobs(ctx context.Context, jobs []collectJob, log *zerolog.Logger) map[string]taskResult {\n\tjobReport := make(map[string]taskResult, len(jobs))\n\n\tfor _, job := range jobs {\n\t\tif job.bypass {\n\t\t\tcontinue\n\t\t}\n\n\t\tlog.Info().Msgf(\"Collecting %s...\", job.jobName)\n\t\tpath, err := job.fn(ctx)\n\n\t\tvar result taskResult\n\t\tif err != nil {\n\t\t\tresult = taskResult{Result: taskFailure, Err: err, path: path}\n\n\t\t\tlog.Error().Err(err).Msgf(\"Job: %s finished with error.\", job.jobName)\n\t\t} else {\n\t\t\tresult = taskResult{Result: taskSuccess, Err: nil, path: path}\n\n\t\t\tlog.Info().Msgf(\"Collected %s.\", job.jobName)\n\t\t}\n\n\t\tjobReport[job.jobName] = result\n\t}\n\n\ttaskReportName, err := createTaskReport(jobReport)\n\n\tvar result taskResult\n\n\tif err != nil {\n\t\tresult = taskResult{\n\t\t\tResult: taskFailure,\n\t\t\tpath:   taskReportName,\n\t\t\tErr:    err,\n\t\t}\n\t} else {\n\t\tresult = taskResult{\n\t\t\tResult: taskSuccess,\n\t\t\tpath:   taskReportName,\n\t\t\tErr:    nil,\n\t\t}\n\t}\n\n\tjobReport[jobReportName] = result\n\n\treturn jobReport\n}\n\nfunc RunDiagnostic(\n\tlog *zerolog.Logger,\n\toptions Options,\n) ([]*AddressableTunnelState, error) {\n\tclient := NewHTTPClient()\n\n\tbaseURL, tunnel, foundTunnels, err := resolveInstanceBaseURL(options.Address, log, client, options.KnownAddresses)\n\tif err != nil {\n\t\treturn foundTunnels, err\n\t}\n\n\tlog.Info().Msgf(\"Selected server %s starting diagnostic...\", baseURL.String())\n\tclient.SetBaseURL(baseURL)\n\n\tconst timeout = 45 * time.Second\n\tctx, cancel := context.WithTimeout(context.Background(), timeout)\n\n\tdefer cancel()\n\n\tjobs := createJobs(\n\t\tclient,\n\t\ttunnel,\n\t\toptions.ContainerID,\n\t\toptions.PodID,\n\t\toptions.Toggles.NoDiagSystem,\n\t\toptions.Toggles.NoDiagRuntime,\n\t\toptions.Toggles.NoDiagMetrics,\n\t\toptions.Toggles.NoDiagLogs,\n\t\toptions.Toggles.NoDiagNetwork,\n\t)\n\n\tjobsReport := runJobs(ctx, jobs, log)\n\tpaths := make([]string, 0)\n\n\tvar gerr error\n\n\tfor _, v := range jobsReport {\n\t\tpaths = append(paths, v.path)\n\n\t\tif gerr == nil && v.Err != nil {\n\t\t\tgerr = v.Err\n\t\t}\n\n\t\tdefer func() {\n\t\t\tif !errors.Is(v.Err, ErrCreatingTemporaryFile) {\n\t\t\t\tos.Remove(v.path)\n\t\t\t}\n\t\t}()\n\t}\n\n\tzipfile, err := CreateDiagnosticZipFile(zipName, paths)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlog.Info().Msgf(\"Diagnostic file written: %v\", zipfile)\n\n\treturn nil, gerr\n}\n"
  },
  {
    "path": "diagnostic/diagnostic_utils.go",
    "content": "package diagnostic\n\nimport (\n\t\"archive/zip\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/rs/zerolog\"\n)\n\n// CreateDiagnosticZipFile create a zip file with the contents from the all\n// files paths. The files will be written in the root of the zip file.\n// In case of an error occurs after whilst writing to the zip file\n// this will be removed.\nfunc CreateDiagnosticZipFile(base string, paths []string) (zipFileName string, err error) {\n\t// Create a zip file with all files from paths added to the root\n\tsuffix := time.Now().Format(time.RFC3339)\n\tzipFileName = base + \"-\" + suffix + \".zip\"\n\tzipFileName = strings.ReplaceAll(zipFileName, \":\", \"-\")\n\n\tarchive, cerr := os.Create(zipFileName)\n\tif cerr != nil {\n\t\treturn \"\", fmt.Errorf(\"error creating file %s: %w\", zipFileName, cerr)\n\t}\n\n\tarchiveWriter := zip.NewWriter(archive)\n\n\tdefer func() {\n\t\tarchiveWriter.Close()\n\t\tarchive.Close()\n\n\t\tif err != nil {\n\t\t\tos.Remove(zipFileName)\n\t\t}\n\t}()\n\n\tfor _, file := range paths {\n\t\tif file == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tvar handle *os.File\n\n\t\thandle, err = os.Open(file)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"error opening file %s: %w\", zipFileName, err)\n\t\t}\n\n\t\tdefer handle.Close()\n\n\t\t// Keep the base only to not create sub directories in the\n\t\t// zip file.\n\t\tvar writer io.Writer\n\n\t\twriter, err = archiveWriter.Create(filepath.Base(file))\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"error creating archive writer from %s: %w\", file, err)\n\t\t}\n\n\t\tif _, err = io.Copy(writer, handle); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"error copying file %s: %w\", file, err)\n\t\t}\n\t}\n\n\tzipFileName = archive.Name()\n\treturn zipFileName, nil\n}\n\ntype AddressableTunnelState struct {\n\t*TunnelState\n\tURL *url.URL\n}\n\nfunc findMetricsServerPredicate(tunnelID, connectorID uuid.UUID) func(state *TunnelState) bool {\n\tif tunnelID != uuid.Nil && connectorID != uuid.Nil {\n\t\treturn func(state *TunnelState) bool {\n\t\t\treturn state.ConnectorID == connectorID && state.TunnelID == tunnelID\n\t\t}\n\t} else if tunnelID == uuid.Nil && connectorID != uuid.Nil {\n\t\treturn func(state *TunnelState) bool {\n\t\t\treturn state.ConnectorID == connectorID\n\t\t}\n\t} else if tunnelID != uuid.Nil && connectorID == uuid.Nil {\n\t\treturn func(state *TunnelState) bool {\n\t\t\treturn state.TunnelID == tunnelID\n\t\t}\n\t}\n\n\treturn func(*TunnelState) bool {\n\t\treturn true\n\t}\n}\n\n// The FindMetricsServer will try to find the metrics server url.\n// There are two possible error scenarios:\n// 1. No instance is found which will only return ErrMetricsServerNotFound\n// 2. Multiple instances are found which will return an array of state and ErrMultipleMetricsServerFound\n// In case of success, only the state for the instance is returned.\nfunc FindMetricsServer(\n\tlog *zerolog.Logger,\n\tclient *httpClient,\n\taddresses []string,\n) (*AddressableTunnelState, []*AddressableTunnelState, error) {\n\tinstances := make([]*AddressableTunnelState, 0)\n\n\tfor _, address := range addresses {\n\t\turl, err := url.Parse(\"http://\" + address)\n\t\tif err != nil {\n\t\t\tlog.Debug().Err(err).Msgf(\"error parsing address %s\", address)\n\n\t\t\tcontinue\n\t\t}\n\n\t\tclient.SetBaseURL(url)\n\n\t\tstate, err := client.GetTunnelState(context.Background())\n\t\tif err == nil {\n\t\t\tinstances = append(instances, &AddressableTunnelState{state, url})\n\t\t} else {\n\t\t\tlog.Debug().Err(err).Msgf(\"error getting tunnel state from address %s\", address)\n\t\t}\n\t}\n\n\tif len(instances) == 0 {\n\t\treturn nil, nil, ErrMetricsServerNotFound\n\t}\n\n\tif len(instances) == 1 {\n\t\treturn instances[0], nil, nil\n\t}\n\n\treturn nil, instances, ErrMultipleMetricsServerFound\n}\n\n// newFormattedEncoder return a JSON encoder with identation\nfunc newFormattedEncoder(w io.Writer) *json.Encoder {\n\tencoder := json.NewEncoder(w)\n\tencoder.SetIndent(\"\", \"  \")\n\treturn encoder\n}\n"
  },
  {
    "path": "diagnostic/diagnostic_utils_test.go",
    "content": "package diagnostic_test\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/facebookgo/grace/gracenet\"\n\t\"github.com/google/uuid\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/cloudflare/cloudflared/diagnostic\"\n\t\"github.com/cloudflare/cloudflared/metrics\"\n\t\"github.com/cloudflare/cloudflared/tunnelstate\"\n)\n\nfunc helperCreateServer(t *testing.T, listeners *gracenet.Net, tunnelID uuid.UUID, connectorID uuid.UUID) func() {\n\tt.Helper()\n\tlistener, err := metrics.CreateMetricsListener(listeners, \"localhost:0\")\n\trequire.NoError(t, err)\n\tlog := zerolog.Nop()\n\ttracker := tunnelstate.NewConnTracker(&log)\n\thandler := diagnostic.NewDiagnosticHandler(&log, 0, nil, tunnelID, connectorID, tracker, map[string]string{}, []string{})\n\trouter := http.NewServeMux()\n\trouter.HandleFunc(\"/diag/tunnel\", handler.TunnelStateHandler)\n\tserver := &http.Server{\n\t\tReadTimeout:  10 * time.Second,\n\t\tWriteTimeout: 10 * time.Second,\n\t\tHandler:      router,\n\t}\n\n\tvar wgroup sync.WaitGroup\n\n\twgroup.Add(1)\n\n\tgo func() {\n\t\tdefer wgroup.Done()\n\n\t\t_ = server.Serve(listener)\n\t}()\n\n\tctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)\n\n\tcleanUp := func() {\n\t\t_ = server.Shutdown(ctx)\n\n\t\tcancel()\n\t\twgroup.Wait()\n\t}\n\n\treturn cleanUp\n}\n\nfunc TestFindMetricsServer_WhenSingleServerIsRunning_ReturnState(t *testing.T) {\n\tlisteners := gracenet.Net{}\n\ttid1 := uuid.New()\n\tcid1 := uuid.New()\n\n\tcleanUp := helperCreateServer(t, &listeners, tid1, cid1)\n\tdefer cleanUp()\n\n\tlog := zerolog.Nop()\n\tclient := diagnostic.NewHTTPClient()\n\taddresses := metrics.GetMetricsKnownAddresses(\"host\")\n\turl1, err := url.Parse(\"http://localhost:20241\")\n\trequire.NoError(t, err)\n\n\ttunnel1 := &diagnostic.AddressableTunnelState{\n\t\tTunnelState: &diagnostic.TunnelState{\n\t\t\tTunnelID:    tid1,\n\t\t\tConnectorID: cid1,\n\t\t\tConnections: nil,\n\t\t},\n\t\tURL: url1,\n\t}\n\n\tstate, tunnels, err := diagnostic.FindMetricsServer(&log, client, addresses[:])\n\tif err != nil {\n\t\trequire.ErrorIs(t, err, diagnostic.ErrMultipleMetricsServerFound)\n\t}\n\n\tassert.Equal(t, tunnel1, state)\n\tassert.Nil(t, tunnels)\n}\n\nfunc TestFindMetricsServer_WhenMultipleServerAreRunning_ReturnError(t *testing.T) {\n\tlisteners := gracenet.Net{}\n\ttid1 := uuid.New()\n\tcid1 := uuid.New()\n\tcid2 := uuid.New()\n\n\tcleanUp := helperCreateServer(t, &listeners, tid1, cid1)\n\tdefer cleanUp()\n\n\tcleanUp = helperCreateServer(t, &listeners, tid1, cid2)\n\tdefer cleanUp()\n\n\tlog := zerolog.Nop()\n\tclient := diagnostic.NewHTTPClient()\n\taddresses := metrics.GetMetricsKnownAddresses(\"host\")\n\turl1, err := url.Parse(\"http://localhost:20241\")\n\trequire.NoError(t, err)\n\turl2, err := url.Parse(\"http://localhost:20242\")\n\trequire.NoError(t, err)\n\n\ttunnel1 := &diagnostic.AddressableTunnelState{\n\t\tTunnelState: &diagnostic.TunnelState{\n\t\t\tTunnelID:    tid1,\n\t\t\tConnectorID: cid1,\n\t\t\tConnections: nil,\n\t\t},\n\t\tURL: url1,\n\t}\n\ttunnel2 := &diagnostic.AddressableTunnelState{\n\t\tTunnelState: &diagnostic.TunnelState{\n\t\t\tTunnelID:    tid1,\n\t\t\tConnectorID: cid2,\n\t\t\tConnections: nil,\n\t\t},\n\t\tURL: url2,\n\t}\n\n\tstate, tunnels, err := diagnostic.FindMetricsServer(&log, client, addresses[:])\n\tif err != nil {\n\t\trequire.ErrorIs(t, err, diagnostic.ErrMultipleMetricsServerFound)\n\t}\n\n\tassert.Nil(t, state)\n\tassert.Equal(t, []*diagnostic.AddressableTunnelState{tunnel1, tunnel2}, tunnels)\n}\n\nfunc TestFindMetricsServer_WhenNoInstanceIsRuning_ReturnError(t *testing.T) {\n\tlog := zerolog.Nop()\n\tclient := diagnostic.NewHTTPClient()\n\taddresses := metrics.GetMetricsKnownAddresses(\"host\")\n\n\tstate, tunnels, err := diagnostic.FindMetricsServer(&log, client, addresses[:])\n\trequire.ErrorIs(t, err, diagnostic.ErrMetricsServerNotFound)\n\n\tassert.Nil(t, state)\n\tassert.Nil(t, tunnels)\n}\n"
  },
  {
    "path": "diagnostic/error.go",
    "content": "package diagnostic\n\nimport (\n\t\"errors\"\n)\n\nvar (\n\t// Error used when there is no log directory available.\n\tErrManagedLogNotFound = errors.New(\"managed log directory not found\")\n\t// Error used when it is not possible to collect logs using the log configuration.\n\tErrLogConfigurationIsInvalid = errors.New(\"provided log configuration is invalid\")\n\t// Error used when parsing the fields of the output of collector.\n\tErrInsufficientLines = errors.New(\"insufficient lines\")\n\t// Error used when parsing the lines of the output of collector.\n\tErrInsuficientFields = errors.New(\"insufficient fields\")\n\t// Error used when given key is not found while parsing KV.\n\tErrKeyNotFound = errors.New(\"key not found\")\n\t// Error used when there is no disk volume information available.\n\tErrNoVolumeFound = errors.New(\"no disk volume information found\")\n\t// Error user when the base url of the diagnostic client is not provided.\n\tErrNoBaseURL = errors.New(\"no base url\")\n\t// Error used when no metrics server is found listening to the known addresses list (check [metrics.GetMetricsKnownAddresses]).\n\tErrMetricsServerNotFound = errors.New(\"metrics server not found\")\n\t// Error used when multiple metrics server are found listening to the known addresses list (check [metrics.GetMetricsKnownAddresses]).\n\tErrMultipleMetricsServerFound = errors.New(\"multiple metrics server found\")\n\t// Error used when a temporary file creation fails within the diagnostic procedure\n\tErrCreatingTemporaryFile = errors.New(\"temporary file creation failed\")\n)\n"
  },
  {
    "path": "diagnostic/handlers.go",
    "content": "package diagnostic\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"os\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelstate\"\n)\n\ntype Handler struct {\n\tlog             *zerolog.Logger\n\ttimeout         time.Duration\n\tsystemCollector SystemCollector\n\ttunnelID        uuid.UUID\n\tconnectorID     uuid.UUID\n\ttracker         *tunnelstate.ConnTracker\n\tcliFlags        map[string]string\n\ticmpSources     []string\n}\n\nfunc NewDiagnosticHandler(\n\tlog *zerolog.Logger,\n\ttimeout time.Duration,\n\tsystemCollector SystemCollector,\n\ttunnelID uuid.UUID,\n\tconnectorID uuid.UUID,\n\ttracker *tunnelstate.ConnTracker,\n\tcliFlags map[string]string,\n\ticmpSources []string,\n) *Handler {\n\tlogger := log.With().Logger()\n\tif timeout == 0 {\n\t\ttimeout = defaultCollectorTimeout\n\t}\n\n\tcliFlags[configurationKeyUID] = strconv.Itoa(os.Getuid())\n\treturn &Handler{\n\t\tlog:             &logger,\n\t\ttimeout:         timeout,\n\t\tsystemCollector: systemCollector,\n\t\ttunnelID:        tunnelID,\n\t\tconnectorID:     connectorID,\n\t\ttracker:         tracker,\n\t\tcliFlags:        cliFlags,\n\t\ticmpSources:     icmpSources,\n\t}\n}\n\nfunc (handler *Handler) InstallEndpoints(router *http.ServeMux) {\n\trouter.HandleFunc(cliConfigurationEndpoint, handler.ConfigurationHandler)\n\trouter.HandleFunc(tunnelStateEndpoint, handler.TunnelStateHandler)\n\trouter.HandleFunc(systemInformationEndpoint, handler.SystemHandler)\n}\n\ntype SystemInformationResponse struct {\n\tInfo *SystemInformation `json:\"info\"`\n\tErr  error              `json:\"errors\"`\n}\n\nfunc (handler *Handler) SystemHandler(writer http.ResponseWriter, request *http.Request) {\n\tlogger := handler.log.With().Str(collectorField, systemCollectorName).Logger()\n\tlogger.Info().Msg(\"Collection started\")\n\n\tdefer logger.Info().Msg(\"Collection finished\")\n\n\tctx, cancel := context.WithTimeout(request.Context(), handler.timeout)\n\n\tdefer cancel()\n\n\tinfo, err := handler.systemCollector.Collect(ctx)\n\n\tresponse := SystemInformationResponse{\n\t\tInfo: info,\n\t\tErr:  err,\n\t}\n\n\tencoder := json.NewEncoder(writer)\n\terr = encoder.Encode(response)\n\tif err != nil {\n\t\tlogger.Error().Err(err).Msgf(\"error occurred whilst serializing information\")\n\t\twriter.WriteHeader(http.StatusInternalServerError)\n\t}\n}\n\ntype TunnelState struct {\n\tTunnelID    uuid.UUID                           `json:\"tunnelID,omitempty\"`\n\tConnectorID uuid.UUID                           `json:\"connectorID,omitempty\"`\n\tConnections []tunnelstate.IndexedConnectionInfo `json:\"connections,omitempty\"`\n\tICMPSources []string                            `json:\"icmp_sources,omitempty\"`\n}\n\nfunc (handler *Handler) TunnelStateHandler(writer http.ResponseWriter, _ *http.Request) {\n\tlog := handler.log.With().Str(collectorField, tunnelStateCollectorName).Logger()\n\tlog.Info().Msg(\"Collection started\")\n\n\tdefer log.Info().Msg(\"Collection finished\")\n\n\tbody := TunnelState{\n\t\thandler.tunnelID,\n\t\thandler.connectorID,\n\t\thandler.tracker.GetActiveConnections(),\n\t\thandler.icmpSources,\n\t}\n\tencoder := json.NewEncoder(writer)\n\n\terr := encoder.Encode(body)\n\tif err != nil {\n\t\thandler.log.Error().Err(err).Msgf(\"error occurred whilst serializing information\")\n\t\twriter.WriteHeader(http.StatusInternalServerError)\n\t}\n}\n\nfunc (handler *Handler) ConfigurationHandler(writer http.ResponseWriter, _ *http.Request) {\n\tlog := handler.log.With().Str(collectorField, configurationCollectorName).Logger()\n\tlog.Info().Msg(\"Collection started\")\n\n\tdefer func() {\n\t\tlog.Info().Msg(\"Collection finished\")\n\t}()\n\n\tencoder := json.NewEncoder(writer)\n\n\terr := encoder.Encode(handler.cliFlags)\n\tif err != nil {\n\t\thandler.log.Error().Err(err).Msgf(\"error occurred whilst serializing response\")\n\t\twriter.WriteHeader(http.StatusInternalServerError)\n\t}\n}\n\nfunc writeResponse(w http.ResponseWriter, bytes []byte, logger *zerolog.Logger) {\n\tbytesWritten, err := w.Write(bytes)\n\tif err != nil {\n\t\tlogger.Error().Err(err).Msg(\"error occurred writing response\")\n\t} else if bytesWritten != len(bytes) {\n\t\tlogger.Error().Msgf(\"error incomplete write response %d/%d\", bytesWritten, len(bytes))\n\t}\n}\n"
  },
  {
    "path": "diagnostic/handlers_test.go",
    "content": "package diagnostic_test\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"runtime\"\n\t\"testing\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/cloudflare/cloudflared/connection\"\n\t\"github.com/cloudflare/cloudflared/diagnostic\"\n\t\"github.com/cloudflare/cloudflared/tunnelstate\"\n)\n\ntype SystemCollectorMock struct {\n\tsystemInfo *diagnostic.SystemInformation\n\terr        error\n}\n\nconst (\n\tsystemInformationKey = \"sikey\"\n\terrorKey             = \"errkey\"\n)\n\nfunc newTrackerFromConns(t *testing.T, connections []tunnelstate.IndexedConnectionInfo) *tunnelstate.ConnTracker {\n\tt.Helper()\n\n\tlog := zerolog.Nop()\n\ttracker := tunnelstate.NewConnTracker(&log)\n\n\tfor _, conn := range connections {\n\t\ttracker.OnTunnelEvent(connection.Event{\n\t\t\tIndex:       conn.Index,\n\t\t\tEventType:   connection.Connected,\n\t\t\tProtocol:    conn.Protocol,\n\t\t\tEdgeAddress: conn.EdgeAddress,\n\t\t})\n\t}\n\n\treturn tracker\n}\n\nfunc (collector *SystemCollectorMock) Collect(context.Context) (*diagnostic.SystemInformation, error) {\n\treturn collector.systemInfo, collector.err\n}\n\nfunc TestSystemHandler(t *testing.T) {\n\tt.Parallel()\n\n\tlog := zerolog.Nop()\n\ttests := []struct {\n\t\tname       string\n\t\tsystemInfo *diagnostic.SystemInformation\n\t\terr        error\n\t\tstatusCode int\n\t}{\n\t\t{\n\t\t\tname: \"happy path\",\n\t\t\tsystemInfo: diagnostic.NewSystemInformation(\n\t\t\t\t0, 0, 0, 0,\n\t\t\t\t\"string\", \"string\", \"string\", \"string\",\n\t\t\t\t\"string\", \"string\",\n\t\t\t\truntime.Version(), runtime.GOARCH, nil,\n\t\t\t),\n\n\t\t\terr:        nil,\n\t\t\tstatusCode: http.StatusOK,\n\t\t},\n\t\t{\n\t\t\tname: \"on error and no raw info\", systemInfo: nil,\n\t\t\terr: errors.New(\"an error\"), statusCode: http.StatusOK,\n\t\t},\n\t}\n\n\tfor _, tCase := range tests {\n\t\tt.Run(tCase.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\thandler := diagnostic.NewDiagnosticHandler(&log, 0, &SystemCollectorMock{\n\t\t\t\tsystemInfo: tCase.systemInfo,\n\t\t\t\terr:        tCase.err,\n\t\t\t}, uuid.New(), uuid.New(), nil, map[string]string{}, nil)\n\t\t\trecorder := httptest.NewRecorder()\n\t\t\tctx := context.Background()\n\t\t\trequest, err := http.NewRequestWithContext(ctx, http.MethodGet, \"/diag/system\", nil)\n\t\t\trequire.NoError(t, err)\n\t\t\thandler.SystemHandler(recorder, request)\n\n\t\t\tassert.Equal(t, tCase.statusCode, recorder.Code)\n\t\t\tif tCase.statusCode == http.StatusOK && tCase.systemInfo != nil {\n\t\t\t\tvar response diagnostic.SystemInformationResponse\n\t\t\t\tdecoder := json.NewDecoder(recorder.Body)\n\t\t\t\terr := decoder.Decode(&response)\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tassert.Equal(t, tCase.systemInfo, response.Info)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestTunnelStateHandler(t *testing.T) {\n\tt.Parallel()\n\n\tlog := zerolog.Nop()\n\ttests := []struct {\n\t\tname        string\n\t\ttunnelID    uuid.UUID\n\t\tclientID    uuid.UUID\n\t\tconnections []tunnelstate.IndexedConnectionInfo\n\t\ticmpSources []string\n\t}{\n\t\t{\n\t\t\tname:     \"case1\",\n\t\t\ttunnelID: uuid.New(),\n\t\t\tclientID: uuid.New(),\n\t\t},\n\t\t{\n\t\t\tname:        \"case2\",\n\t\t\ttunnelID:    uuid.New(),\n\t\t\tclientID:    uuid.New(),\n\t\t\ticmpSources: []string{\"172.17.0.3\", \"::1\"},\n\t\t\tconnections: []tunnelstate.IndexedConnectionInfo{{\n\t\t\t\tConnectionInfo: tunnelstate.ConnectionInfo{\n\t\t\t\t\tIsConnected: true,\n\t\t\t\t\tProtocol:    connection.QUIC,\n\t\t\t\t\tEdgeAddress: net.IPv4(100, 100, 100, 100),\n\t\t\t\t},\n\t\t\t\tIndex: 0,\n\t\t\t}},\n\t\t},\n\t}\n\n\tfor _, tCase := range tests {\n\t\tt.Run(tCase.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\ttracker := newTrackerFromConns(t, tCase.connections)\n\t\t\thandler := diagnostic.NewDiagnosticHandler(\n\t\t\t\t&log,\n\t\t\t\t0,\n\t\t\t\tnil,\n\t\t\t\ttCase.tunnelID,\n\t\t\t\ttCase.clientID,\n\t\t\t\ttracker,\n\t\t\t\tmap[string]string{},\n\t\t\t\ttCase.icmpSources,\n\t\t\t)\n\t\t\trecorder := httptest.NewRecorder()\n\t\t\thandler.TunnelStateHandler(recorder, nil)\n\t\t\tdecoder := json.NewDecoder(recorder.Body)\n\n\t\t\tvar response diagnostic.TunnelState\n\t\t\terr := decoder.Decode(&response)\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, http.StatusOK, recorder.Code)\n\t\t\tassert.Equal(t, tCase.tunnelID, response.TunnelID)\n\t\t\tassert.Equal(t, tCase.clientID, response.ConnectorID)\n\t\t\tassert.Equal(t, tCase.connections, response.Connections)\n\t\t\tassert.Equal(t, tCase.icmpSources, response.ICMPSources)\n\t\t})\n\t}\n}\n\nfunc TestConfigurationHandler(t *testing.T) {\n\tt.Parallel()\n\n\tlog := zerolog.Nop()\n\n\ttests := []struct {\n\t\tname     string\n\t\tflags    map[string]string\n\t\texpected map[string]string\n\t}{\n\t\t{\n\t\t\tname:  \"empty cli\",\n\t\t\tflags: make(map[string]string),\n\t\t\texpected: map[string]string{\n\t\t\t\t\"uid\": \"0\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"cli with flags\",\n\t\t\tflags: map[string]string{\n\t\t\t\t\"b\":   \"a\",\n\t\t\t\t\"c\":   \"a\",\n\t\t\t\t\"d\":   \"a\",\n\t\t\t\t\"uid\": \"0\",\n\t\t\t},\n\t\t\texpected: map[string]string{\n\t\t\t\t\"b\":   \"a\",\n\t\t\t\t\"c\":   \"a\",\n\t\t\t\t\"d\":   \"a\",\n\t\t\t\t\"uid\": \"0\",\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tCase := range tests {\n\t\tt.Run(tCase.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tvar response map[string]string\n\n\t\t\thandler := diagnostic.NewDiagnosticHandler(&log, 0, nil, uuid.New(), uuid.New(), nil, tCase.flags, nil)\n\t\t\trecorder := httptest.NewRecorder()\n\t\t\thandler.ConfigurationHandler(recorder, nil)\n\t\t\tdecoder := json.NewDecoder(recorder.Body)\n\t\t\terr := decoder.Decode(&response)\n\t\t\trequire.NoError(t, err)\n\t\t\t_, ok := response[\"uid\"]\n\t\t\tassert.True(t, ok)\n\t\t\tdelete(tCase.expected, \"uid\")\n\t\t\tdelete(response, \"uid\")\n\t\t\tassert.Equal(t, http.StatusOK, recorder.Code)\n\t\t\tassert.Equal(t, tCase.expected, response)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "diagnostic/log_collector.go",
    "content": "package diagnostic\n\nimport (\n\t\"context\"\n)\n\n// Represents the path of the log file or log directory.\n// This struct is meant to give some ergonimics regarding\n// the logging information.\ntype LogInformation struct {\n\tpath        string // path to a file or directory\n\twasCreated  bool   // denotes if `path` was created\n\tisDirectory bool   // denotes if `path` is a directory\n}\n\nfunc NewLogInformation(\n\tpath string,\n\twasCreated bool,\n\tisDirectory bool,\n) *LogInformation {\n\treturn &LogInformation{\n\t\tpath,\n\t\twasCreated,\n\t\tisDirectory,\n\t}\n}\n\ntype LogCollector interface {\n\t// This function is responsible for returning a path to a single file\n\t// whose contents are the logs of a cloudflared instance.\n\t// A new file may be create by a LogCollector, thus, its the caller\n\t// responsibility to remove the newly create file.\n\tCollect(ctx context.Context) (*LogInformation, error)\n}\n"
  },
  {
    "path": "diagnostic/log_collector_docker.go",
    "content": "package diagnostic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"time\"\n)\n\ntype DockerLogCollector struct {\n\tcontainerID string // This member identifies the container by identifier or name\n}\n\nfunc NewDockerLogCollector(containerID string) *DockerLogCollector {\n\treturn &DockerLogCollector{\n\t\tcontainerID,\n\t}\n}\n\nfunc (collector *DockerLogCollector) Collect(ctx context.Context) (*LogInformation, error) {\n\ttmp := os.TempDir()\n\n\toutputHandle, err := os.Create(filepath.Join(tmp, logFilename))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error opening output file: %w\", err)\n\t}\n\n\tdefer outputHandle.Close()\n\n\t// Calculate 2 weeks ago\n\tsince := time.Now().Add(twoWeeksOffset).Format(time.RFC3339)\n\n\tcommand := exec.CommandContext(\n\t\tctx,\n\t\t\"docker\",\n\t\t\"logs\",\n\t\t\"--tail\",\n\t\ttailMaxNumberOfLines,\n\t\t\"--since\",\n\t\tsince,\n\t\tcollector.containerID,\n\t)\n\n\treturn PipeCommandOutputToFile(command, outputHandle)\n}\n"
  },
  {
    "path": "diagnostic/log_collector_host.go",
    "content": "package diagnostic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"runtime\"\n)\n\nconst (\n\tlinuxManagedLogsPath          = \"/var/log/cloudflared.err\"\n\tdarwinManagedLogsPath         = \"/Library/Logs/com.cloudflare.cloudflared.err.log\"\n\tlinuxServiceConfigurationPath = \"/etc/systemd/system/cloudflared.service\"\n\tlinuxSystemdPath              = \"/run/systemd/system\"\n)\n\ntype HostLogCollector struct {\n\tclient HTTPClient\n}\n\nfunc NewHostLogCollector(client HTTPClient) *HostLogCollector {\n\treturn &HostLogCollector{\n\t\tclient,\n\t}\n}\n\nfunc extractLogsFromJournalCtl(ctx context.Context) (*LogInformation, error) {\n\ttmp := os.TempDir()\n\n\toutputHandle, err := os.Create(filepath.Join(tmp, logFilename))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error opening output file: %w\", err)\n\t}\n\n\tdefer outputHandle.Close()\n\n\tcommand := exec.CommandContext(\n\t\tctx,\n\t\t\"journalctl\",\n\t\t\"--since\",\n\t\t\"2 weeks ago\",\n\t\t\"-u\",\n\t\t\"cloudflared.service\",\n\t)\n\n\treturn PipeCommandOutputToFile(command, outputHandle)\n}\n\nfunc getServiceLogPath() (string, error) {\n\tswitch runtime.GOOS {\n\tcase \"darwin\":\n\t\t{\n\t\t\tpath := darwinManagedLogsPath\n\t\t\tif _, err := os.Stat(path); err == nil {\n\t\t\t\treturn path, nil\n\t\t\t}\n\n\t\t\tuserHomeDir, err := os.UserHomeDir()\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", fmt.Errorf(\"error getting user home: %w\", err)\n\t\t\t}\n\n\t\t\treturn filepath.Join(userHomeDir, darwinManagedLogsPath), nil\n\t\t}\n\tcase \"linux\":\n\t\t{\n\t\t\treturn linuxManagedLogsPath, nil\n\t\t}\n\tdefault:\n\t\treturn \"\", ErrManagedLogNotFound\n\t}\n}\n\nfunc (collector *HostLogCollector) Collect(ctx context.Context) (*LogInformation, error) {\n\tlogConfiguration, err := collector.client.GetLogConfiguration(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting log configuration: %w\", err)\n\t}\n\n\tif logConfiguration.uid == 0 {\n\t\t_, statSystemdErr := os.Stat(linuxServiceConfigurationPath)\n\n\t\t_, statServiceConfigurationErr := os.Stat(linuxServiceConfigurationPath)\n\t\tif statSystemdErr == nil && statServiceConfigurationErr == nil && runtime.GOOS == \"linux\" {\n\t\t\treturn extractLogsFromJournalCtl(ctx)\n\t\t}\n\n\t\tpath, err := getServiceLogPath()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\treturn NewLogInformation(path, false, false), nil\n\t}\n\n\tif logConfiguration.logFile != \"\" {\n\t\treturn NewLogInformation(logConfiguration.logFile, false, false), nil\n\t} else if logConfiguration.logDirectory != \"\" {\n\t\treturn NewLogInformation(logConfiguration.logDirectory, false, true), nil\n\t}\n\n\treturn nil, ErrLogConfigurationIsInvalid\n}\n"
  },
  {
    "path": "diagnostic/log_collector_kubernetes.go",
    "content": "package diagnostic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"time\"\n)\n\ntype KubernetesLogCollector struct {\n\tcontainerID string // This member identifies the container by identifier or name\n\tpod         string // This member identifies the pod where the container is deployed\n}\n\nfunc NewKubernetesLogCollector(containerID, pod string) *KubernetesLogCollector {\n\treturn &KubernetesLogCollector{\n\t\tcontainerID,\n\t\tpod,\n\t}\n}\n\nfunc (collector *KubernetesLogCollector) Collect(ctx context.Context) (*LogInformation, error) {\n\ttmp := os.TempDir()\n\toutputHandle, err := os.Create(filepath.Join(tmp, logFilename))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error opening output file: %w\", err)\n\t}\n\n\tdefer outputHandle.Close()\n\n\tvar command *exec.Cmd\n\t// Calculate 2 weeks ago\n\tsince := time.Now().Add(twoWeeksOffset).Format(time.RFC3339)\n\tif collector.containerID != \"\" {\n\t\tcommand = exec.CommandContext(\n\t\t\tctx,\n\t\t\t\"kubectl\",\n\t\t\t\"logs\",\n\t\t\tcollector.pod,\n\t\t\t\"--since-time\",\n\t\t\tsince,\n\t\t\t\"--tail\",\n\t\t\ttailMaxNumberOfLines,\n\t\t\t\"-c\",\n\t\t\tcollector.containerID,\n\t\t)\n\t} else {\n\t\tcommand = exec.CommandContext(\n\t\t\tctx,\n\t\t\t\"kubectl\",\n\t\t\t\"logs\",\n\t\t\tcollector.pod,\n\t\t\t\"--since-time\",\n\t\t\tsince,\n\t\t\t\"--tail\",\n\t\t\ttailMaxNumberOfLines,\n\t\t)\n\t}\n\n\treturn PipeCommandOutputToFile(command, outputHandle)\n}\n"
  },
  {
    "path": "diagnostic/log_collector_utils.go",
    "content": "package diagnostic\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n)\n\nfunc PipeCommandOutputToFile(command *exec.Cmd, outputHandle *os.File) (*LogInformation, error) {\n\tstdoutReader, err := command.StdoutPipe()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"error retrieving stdout from command '%s': %w\",\n\t\t\tcommand.String(),\n\t\t\terr,\n\t\t)\n\t}\n\n\tstderrReader, err := command.StderrPipe()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"error retrieving stderr from command '%s': %w\",\n\t\t\tcommand.String(),\n\t\t\terr,\n\t\t)\n\t}\n\n\tif err := command.Start(); err != nil {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"error running command '%s': %w\",\n\t\t\tcommand.String(),\n\t\t\terr,\n\t\t)\n\t}\n\n\t_, err = io.Copy(outputHandle, stdoutReader)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"error copying stdout from %s to file %s: %w\",\n\t\t\tcommand.String(),\n\t\t\toutputHandle.Name(),\n\t\t\terr,\n\t\t)\n\t}\n\n\t_, err = io.Copy(outputHandle, stderrReader)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"error copying stderr from %s to file %s: %w\",\n\t\t\tcommand.String(),\n\t\t\toutputHandle.Name(),\n\t\t\terr,\n\t\t)\n\t}\n\n\tif err := command.Wait(); err != nil {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"error waiting from command '%s': %w\",\n\t\t\tcommand.String(),\n\t\t\terr,\n\t\t)\n\t}\n\n\treturn NewLogInformation(outputHandle.Name(), true, false), nil\n}\n\nfunc CopyFilesFromDirectory(path string) (string, error) {\n\t// rolling logs have as suffix the current date thus\n\t// when iterating the path files they are already in\n\t// chronological order\n\tfiles, err := os.ReadDir(path)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error reading directory %s: %w\", path, err)\n\t}\n\n\toutputHandle, err := os.Create(filepath.Join(os.TempDir(), logFilename))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"creating file %s: %w\", outputHandle.Name(), err)\n\t}\n\tdefer outputHandle.Close()\n\n\tfor _, file := range files {\n\t\tlogHandle, err := os.Open(filepath.Join(path, file.Name()))\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"error opening file %s:%w\", file.Name(), err)\n\t\t}\n\t\tdefer logHandle.Close()\n\n\t\t_, err = io.Copy(outputHandle, logHandle)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"error copying file %s:%w\", logHandle.Name(), err)\n\t\t}\n\t}\n\n\tlogHandle, err := os.Open(filepath.Join(path, \"cloudflared.log\"))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error opening file %s:%w\", logHandle.Name(), err)\n\t}\n\tdefer logHandle.Close()\n\n\t_, err = io.Copy(outputHandle, logHandle)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error copying file %s:%w\", logHandle.Name(), err)\n\t}\n\n\treturn outputHandle.Name(), nil\n}\n"
  },
  {
    "path": "diagnostic/network/collector.go",
    "content": "package diagnostic\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"time\"\n)\n\nconst MicrosecondsFactor = 1000.0\n\nvar ErrEmptyDomain = errors.New(\"domain must not be empty\")\n\n// For now only support ICMP is provided.\ntype IPVersion int\n\nconst (\n\tV4 IPVersion = iota\n\tV6 IPVersion = iota\n)\n\ntype Hop struct {\n\tHop    uint8           `json:\"hop,omitempty\"`    // hop number along the route\n\tDomain string          `json:\"domain,omitempty\"` // domain and/or ip of the hop, this field will be '*' if the hop is a timeout\n\tRtts   []time.Duration `json:\"rtts,omitempty\"`   // RTT measurements in microseconds\n}\n\ntype TraceOptions struct {\n\tttl     uint64        // number of hops to perform\n\ttimeout time.Duration // wait timeout for each response\n\taddress string        // address to trace\n\tuseV4   bool\n}\n\nfunc NewTimeoutHop(\n\thop uint8,\n) *Hop {\n\t// Whenever there is a hop in the format of 'N * * *'\n\t// it means that the hop in the path didn't answer to\n\t// any probe.\n\treturn NewHop(\n\t\thop,\n\t\t\"*\",\n\t\tnil,\n\t)\n}\n\nfunc NewHop(hop uint8, domain string, rtts []time.Duration) *Hop {\n\treturn &Hop{\n\t\thop,\n\t\tdomain,\n\t\trtts,\n\t}\n}\n\nfunc NewTraceOptions(\n\tttl uint64,\n\ttimeout time.Duration,\n\taddress string,\n\tuseV4 bool,\n) TraceOptions {\n\treturn TraceOptions{\n\t\tttl,\n\t\ttimeout,\n\t\taddress,\n\t\tuseV4,\n\t}\n}\n\ntype NetworkCollector interface {\n\t// Performs a trace route operation with the specified options.\n\t// In case the trace fails, it will return a non-nil error and\n\t// it may return a string which represents the raw information\n\t// obtained.\n\t// In case it is successful it will only return an array of Hops\n\t// an empty string and a nil error.\n\tCollect(ctx context.Context, options TraceOptions) ([]*Hop, string, error)\n}\n"
  },
  {
    "path": "diagnostic/network/collector_unix.go",
    "content": "//go:build darwin || linux\n\npackage diagnostic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os/exec\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\ntype NetworkCollectorImpl struct{}\n\nfunc (tracer *NetworkCollectorImpl) Collect(ctx context.Context, options TraceOptions) ([]*Hop, string, error) {\n\targs := []string{\n\t\t\"-I\",\n\t\t\"-w\",\n\t\tstrconv.FormatInt(int64(options.timeout.Seconds()), 10),\n\t\t\"-m\",\n\t\tstrconv.FormatUint(options.ttl, 10),\n\t\toptions.address,\n\t}\n\n\tvar command string\n\n\tswitch options.useV4 {\n\tcase false:\n\t\tcommand = \"traceroute6\"\n\tdefault:\n\t\tcommand = \"traceroute\"\n\t}\n\n\tprocess := exec.CommandContext(ctx, command, args...)\n\n\treturn decodeNetworkOutputToFile(process, DecodeLine)\n}\n\nfunc DecodeLine(text string) (*Hop, error) {\n\tfields := strings.Fields(text)\n\tparts := []string{}\n\tfilter := func(s string) bool { return s != \"*\" && s != \"ms\" }\n\n\tfor _, field := range fields {\n\t\tif filter(field) {\n\t\t\tparts = append(parts, field)\n\t\t}\n\t}\n\n\tindex, err := strconv.ParseUint(parts[0], 10, 8)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"couldn't parse index from timeout hop: %w\", err)\n\t}\n\n\tif len(parts) == 1 {\n\t\treturn NewTimeoutHop(uint8(index)), nil\n\t}\n\n\tdomain := \"\"\n\trtts := []time.Duration{}\n\n\tfor _, part := range parts[1:] {\n\t\trtt, err := strconv.ParseFloat(part, 64)\n\t\tif err != nil {\n\t\t\tdomain += part + \" \"\n\t\t} else {\n\t\t\trtts = append(rtts, time.Duration(rtt*MicrosecondsFactor))\n\t\t}\n\t}\n\n\tdomain, _ = strings.CutSuffix(domain, \" \")\n\tif domain == \"\" {\n\t\treturn nil, ErrEmptyDomain\n\t}\n\n\treturn NewHop(uint8(index), domain, rtts), nil\n}\n"
  },
  {
    "path": "diagnostic/network/collector_unix_test.go",
    "content": "//go:build darwin || linux\n\npackage diagnostic_test\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\tdiagnostic \"github.com/cloudflare/cloudflared/diagnostic/network\"\n)\n\nfunc TestDecode(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname         string\n\t\ttext         string\n\t\texpectedHops []*diagnostic.Hop\n\t}{\n\t\t{\n\t\t\t\"repeated hop index parse failure\",\n\t\t\t`1  172.68.101.121 (172.68.101.121)  12.874 ms  15.517 ms  15.311 ms\n2  172.68.101.121 (172.68.101.121)  12.874 ms  15.517 ms  15.311 ms\nsomeletters * * *\n4  172.68.101.121 (172.68.101.121)  12.874 ms  15.517 ms  15.311 ms `,\n\t\t\t[]*diagnostic.Hop{\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(1),\n\t\t\t\t\t\"172.68.101.121 (172.68.101.121)\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(12874),\n\t\t\t\t\t\ttime.Duration(15517),\n\t\t\t\t\t\ttime.Duration(15311),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(2),\n\t\t\t\t\t\"172.68.101.121 (172.68.101.121)\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(12874),\n\t\t\t\t\t\ttime.Duration(15517),\n\t\t\t\t\t\ttime.Duration(15311),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(4),\n\t\t\t\t\t\"172.68.101.121 (172.68.101.121)\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(12874),\n\t\t\t\t\t\ttime.Duration(15517),\n\t\t\t\t\t\ttime.Duration(15311),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t\"hop index parse failure\",\n\t\t\t`1  172.68.101.121 (172.68.101.121)  12.874 ms  15.517 ms  15.311 ms\n2  172.68.101.121 (172.68.101.121)  12.874 ms  15.517 ms  15.311 ms\nsomeletters 8.8.8.8 8.8.8.9 abc ms 0.456 ms 0.789 ms`,\n\t\t\t[]*diagnostic.Hop{\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(1),\n\t\t\t\t\t\"172.68.101.121 (172.68.101.121)\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(12874),\n\t\t\t\t\t\ttime.Duration(15517),\n\t\t\t\t\t\ttime.Duration(15311),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(2),\n\t\t\t\t\t\"172.68.101.121 (172.68.101.121)\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(12874),\n\t\t\t\t\t\ttime.Duration(15517),\n\t\t\t\t\t\ttime.Duration(15311),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t\"missing rtt\",\n\t\t\t`1  172.68.101.121 (172.68.101.121)  12.874 ms  15.517 ms  15.311 ms\n2 * 8.8.8.8 8.8.8.9 0.456 ms 0.789 ms`,\n\t\t\t[]*diagnostic.Hop{\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(1),\n\t\t\t\t\t\"172.68.101.121 (172.68.101.121)\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(12874),\n\t\t\t\t\t\ttime.Duration(15517),\n\t\t\t\t\t\ttime.Duration(15311),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(2),\n\t\t\t\t\t\"8.8.8.8 8.8.8.9\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(456),\n\t\t\t\t\t\ttime.Duration(789),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t\"simple example ipv4\",\n\t\t\t`1  172.68.101.121 (172.68.101.121)  12.874 ms  15.517 ms  15.311 ms\n2  172.68.101.121 (172.68.101.121)  12.874 ms  15.517 ms  15.311 ms\n3  * * *`,\n\t\t\t[]*diagnostic.Hop{\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(1),\n\t\t\t\t\t\"172.68.101.121 (172.68.101.121)\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(12874),\n\t\t\t\t\t\ttime.Duration(15517),\n\t\t\t\t\t\ttime.Duration(15311),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(2),\n\t\t\t\t\t\"172.68.101.121 (172.68.101.121)\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(12874),\n\t\t\t\t\t\ttime.Duration(15517),\n\t\t\t\t\t\ttime.Duration(15311),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tdiagnostic.NewTimeoutHop(uint8(3)),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t\"simple example ipv6\",\n\t\t\t` 1  2400:cb00:107:1024::ac44:6550  12.780 ms  9.118 ms  10.046 ms\n 2  2a09:bac1::  9.945 ms  10.033 ms  11.562 ms`,\n\t\t\t[]*diagnostic.Hop{\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(1),\n\t\t\t\t\t\"2400:cb00:107:1024::ac44:6550\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(12780),\n\t\t\t\t\t\ttime.Duration(9118),\n\t\t\t\t\t\ttime.Duration(10046),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(2),\n\t\t\t\t\t\"2a09:bac1::\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(9945),\n\t\t\t\t\t\ttime.Duration(10033),\n\t\t\t\t\t\ttime.Duration(11562),\n\t\t\t\t\t},\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\n\t\t\thops, err := diagnostic.Decode(strings.NewReader(test.text), diagnostic.DecodeLine)\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, test.expectedHops, hops)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "diagnostic/network/collector_utils.go",
    "content": "package diagnostic\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os/exec\"\n)\n\ntype DecodeLineFunc func(text string) (*Hop, error)\n\nfunc decodeNetworkOutputToFile(command *exec.Cmd, decodeLine DecodeLineFunc) ([]*Hop, string, error) {\n\tstdout, err := command.StdoutPipe()\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"error piping traceroute's output: %w\", err)\n\t}\n\n\tif err := command.Start(); err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"error starting traceroute: %w\", err)\n\t}\n\n\t// Tee the output to a string to have the raw information\n\t// in case the decode call fails\n\t// This error is handled only after the Wait call below returns\n\t// otherwise the process can become a zombie\n\tbuf := bytes.NewBuffer([]byte{})\n\ttee := io.TeeReader(stdout, buf)\n\thops, err := Decode(tee, decodeLine)\n\t// regardless of success of the decoding\n\t// consume all output to have available in buf\n\t_, _ = io.ReadAll(tee)\n\n\tif werr := command.Wait(); werr != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"error finishing traceroute: %w\", werr)\n\t}\n\n\tif err != nil {\n\t\treturn nil, buf.String(), err\n\t}\n\n\treturn hops, buf.String(), nil\n}\n\nfunc Decode(reader io.Reader, decodeLine DecodeLineFunc) ([]*Hop, error) {\n\tscanner := bufio.NewScanner(reader)\n\tscanner.Split(bufio.ScanLines)\n\n\tvar hops []*Hop\n\n\tfor scanner.Scan() {\n\t\ttext := scanner.Text()\n\t\tif text == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\thop, err := decodeLine(text)\n\t\tif err != nil {\n\t\t\t// This continue is here on the error case because there are lines at the start and end\n\t\t\t// that may not be parsable. (check windows tracert output)\n\t\t\t// The skip is here because aside from the start and end lines the other lines should\n\t\t\t// always be parsable without errors.\n\t\t\tcontinue\n\t\t}\n\n\t\thops = append(hops, hop)\n\t}\n\n\tif scanner.Err() != nil {\n\t\treturn nil, fmt.Errorf(\"scanner reported an error: %w\", scanner.Err())\n\t}\n\n\treturn hops, nil\n}\n"
  },
  {
    "path": "diagnostic/network/collector_windows.go",
    "content": "//go:build windows\n\npackage diagnostic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os/exec\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\ntype NetworkCollectorImpl struct{}\n\nfunc (tracer *NetworkCollectorImpl) Collect(ctx context.Context, options TraceOptions) ([]*Hop, string, error) {\n\tipversion := \"-4\"\n\tif !options.useV4 {\n\t\tipversion = \"-6\"\n\t}\n\n\targs := []string{\n\t\tipversion,\n\t\t\"-w\",\n\t\tstrconv.FormatInt(int64(options.timeout.Seconds()), 10),\n\t\t\"-h\",\n\t\tstrconv.FormatUint(options.ttl, 10),\n\t\t// Do not resolve host names (can add 30+ seconds to run time)\n\t\t\"-d\",\n\t\toptions.address,\n\t}\n\tcommand := exec.CommandContext(ctx, \"tracert.exe\", args...)\n\n\treturn decodeNetworkOutputToFile(command, DecodeLine)\n}\n\nfunc DecodeLine(text string) (*Hop, error) {\n\tconst requestTimedOut = \"Request timed out.\"\n\n\tfields := strings.Fields(text)\n\tparts := []string{}\n\tfilter := func(s string) bool { return s != \"*\" && s != \"ms\" }\n\n\tfor _, field := range fields {\n\t\tif filter(field) {\n\t\t\tparts = append(parts, field)\n\t\t}\n\t}\n\n\tindex, err := strconv.ParseUint(parts[0], 10, 8)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"couldn't parse index from timeout hop: %w\", err)\n\t}\n\n\tdomain := \"\"\n\trtts := []time.Duration{}\n\n\tfor _, part := range parts[1:] {\n\n\t\trtt, err := strconv.ParseFloat(strings.TrimLeft(part, \"<\"), 64)\n\n\t\tif err != nil {\n\t\t\tdomain += part + \" \"\n\t\t} else {\n\t\t\trtts = append(rtts, time.Duration(rtt*MicrosecondsFactor))\n\t\t}\n\t}\n\n\tdomain, _ = strings.CutSuffix(domain, \" \")\n\t// If the domain is equal to \"Request timed out.\" then we build a\n\t// timeout hop.\n\tif domain == requestTimedOut {\n\t\treturn NewTimeoutHop(uint8(index)), nil\n\t}\n\n\tif domain == \"\" {\n\t\treturn nil, ErrEmptyDomain\n\t}\n\n\treturn NewHop(uint8(index), domain, rtts), nil\n}\n"
  },
  {
    "path": "diagnostic/network/collector_windows_test.go",
    "content": "//go:build windows\n\npackage diagnostic_test\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\tdiagnostic \"github.com/cloudflare/cloudflared/diagnostic/network\"\n)\n\nfunc TestDecode(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname         string\n\t\ttext         string\n\t\texpectedHops []*diagnostic.Hop\n\t}{\n\n\t\t{\n\t\t\t\"tracert output\",\n\t\t\t`\nTracing route to region2.v2.argotunnel.com [198.41.200.73]\nover a maximum of 5 hops:\n\n  1    10 ms    <1 ms     1 ms  192.168.64.1\n  2    27 ms    14 ms     5 ms  192.168.1.254\n  3     *        *        *     Request timed out.\n  4     *        *        *     Request timed out.\n  5    27 ms     5 ms     5 ms  195.8.30.245\n\nTrace complete.\n`,\n\t\t\t[]*diagnostic.Hop{\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(1),\n\t\t\t\t\t\"192.168.64.1\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(10000),\n\t\t\t\t\t\ttime.Duration(1000),\n\t\t\t\t\t\ttime.Duration(1000),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(2),\n\t\t\t\t\t\"192.168.1.254\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(27000),\n\t\t\t\t\t\ttime.Duration(14000),\n\t\t\t\t\t\ttime.Duration(5000),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tdiagnostic.NewTimeoutHop(uint8(3)),\n\t\t\t\tdiagnostic.NewTimeoutHop(uint8(4)),\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(5),\n\t\t\t\t\t\"195.8.30.245\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(27000),\n\t\t\t\t\t\ttime.Duration(5000),\n\t\t\t\t\t\ttime.Duration(5000),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t\"repeated hop index parse failure\",\n\t\t\t`1\t12.874 ms\t15.517 ms\t15.311 ms\t172.68.101.121 (172.68.101.121)  \n2\t12.874 ms\t15.517 ms\t15.311 ms\t172.68.101.121 (172.68.101.121)  \nsomeletters * * *`,\n\t\t\t[]*diagnostic.Hop{\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(1),\n\t\t\t\t\t\"172.68.101.121 (172.68.101.121)\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(12874),\n\t\t\t\t\t\ttime.Duration(15517),\n\t\t\t\t\t\ttime.Duration(15311),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(2),\n\t\t\t\t\t\"172.68.101.121 (172.68.101.121)\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(12874),\n\t\t\t\t\t\ttime.Duration(15517),\n\t\t\t\t\t\ttime.Duration(15311),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t\"hop index parse failure\",\n\t\t\t`1\t12.874 ms\t15.517 ms\t15.311 ms\t172.68.101.121 (172.68.101.121)  \n2\t12.874 ms\t15.517 ms\t15.311 ms\t172.68.101.121 (172.68.101.121)  \nsomeletters abc ms 0.456 ms 0.789 ms 8.8.8.8 8.8.8.9`,\n\t\t\t[]*diagnostic.Hop{\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(1),\n\t\t\t\t\t\"172.68.101.121 (172.68.101.121)\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(12874),\n\t\t\t\t\t\ttime.Duration(15517),\n\t\t\t\t\t\ttime.Duration(15311),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(2),\n\t\t\t\t\t\"172.68.101.121 (172.68.101.121)\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(12874),\n\t\t\t\t\t\ttime.Duration(15517),\n\t\t\t\t\t\ttime.Duration(15311),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t\"missing rtt\",\n\t\t\t`1\t<12.874 ms\t<15.517 ms\t<15.311 ms\t172.68.101.121 (172.68.101.121)  \n2 * 0.456 ms 0.789 ms 8.8.8.8 8.8.8.9`,\n\t\t\t[]*diagnostic.Hop{\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(1),\n\t\t\t\t\t\"172.68.101.121 (172.68.101.121)\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(12874),\n\t\t\t\t\t\ttime.Duration(15517),\n\t\t\t\t\t\ttime.Duration(15311),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(2),\n\t\t\t\t\t\"8.8.8.8 8.8.8.9\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(456),\n\t\t\t\t\t\ttime.Duration(789),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t\"simple example ipv4\",\n\t\t\t`1\t12.874 ms\t15.517 ms\t15.311 ms\t172.68.101.121 (172.68.101.121)  \n2\t12.874 ms\t15.517 ms\t15.311 ms\t172.68.101.121 (172.68.101.121)  \n3  * * * Request timed out.`,\n\t\t\t[]*diagnostic.Hop{\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(1),\n\t\t\t\t\t\"172.68.101.121 (172.68.101.121)\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(12874),\n\t\t\t\t\t\ttime.Duration(15517),\n\t\t\t\t\t\ttime.Duration(15311),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(2),\n\t\t\t\t\t\"172.68.101.121 (172.68.101.121)\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(12874),\n\t\t\t\t\t\ttime.Duration(15517),\n\t\t\t\t\t\ttime.Duration(15311),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tdiagnostic.NewTimeoutHop(uint8(3)),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t\"simple example ipv6\",\n\t\t\t` 1 12.780 ms  9.118 ms  10.046 ms 2400:cb00:107:1024::ac44:6550\n 2   9.945 ms  10.033 ms  11.562 ms 2a09:bac1::`,\n\t\t\t[]*diagnostic.Hop{\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(1),\n\t\t\t\t\t\"2400:cb00:107:1024::ac44:6550\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(12780),\n\t\t\t\t\t\ttime.Duration(9118),\n\t\t\t\t\t\ttime.Duration(10046),\n\t\t\t\t\t},\n\t\t\t\t),\n\t\t\t\tdiagnostic.NewHop(\n\t\t\t\t\tuint8(2),\n\t\t\t\t\t\"2a09:bac1::\",\n\t\t\t\t\t[]time.Duration{\n\t\t\t\t\t\ttime.Duration(9945),\n\t\t\t\t\t\ttime.Duration(10033),\n\t\t\t\t\t\ttime.Duration(11562),\n\t\t\t\t\t},\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\n\t\t\thops, err := diagnostic.Decode(strings.NewReader(test.text), diagnostic.DecodeLine)\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, test.expectedHops, hops)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "diagnostic/system_collector.go",
    "content": "package diagnostic\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"strings\"\n)\n\ntype SystemInformationError struct {\n\tErr     error  `json:\"error\"`\n\tRawInfo string `json:\"rawInfo\"`\n}\n\nfunc (err SystemInformationError) Error() string {\n\treturn err.Err.Error()\n}\n\nfunc (err SystemInformationError) MarshalJSON() ([]byte, error) {\n\ts := map[string]string{\n\t\t\"error\":   err.Err.Error(),\n\t\t\"rawInfo\": err.RawInfo,\n\t}\n\n\treturn json.Marshal(s)\n}\n\ntype SystemInformationGeneralError struct {\n\tOperatingSystemInformationError error\n\tMemoryInformationError          error\n\tFileDescriptorsInformationError error\n\tDiskVolumeInformationError      error\n}\n\nfunc (err SystemInformationGeneralError) Error() string {\n\tbuilder := &strings.Builder{}\n\tbuilder.WriteString(\"errors found:\")\n\n\tif err.OperatingSystemInformationError != nil {\n\t\tbuilder.WriteString(err.OperatingSystemInformationError.Error() + \", \")\n\t}\n\n\tif err.MemoryInformationError != nil {\n\t\tbuilder.WriteString(err.MemoryInformationError.Error() + \", \")\n\t}\n\n\tif err.FileDescriptorsInformationError != nil {\n\t\tbuilder.WriteString(err.FileDescriptorsInformationError.Error() + \", \")\n\t}\n\n\tif err.DiskVolumeInformationError != nil {\n\t\tbuilder.WriteString(err.DiskVolumeInformationError.Error() + \", \")\n\t}\n\n\treturn builder.String()\n}\n\nfunc (err SystemInformationGeneralError) MarshalJSON() ([]byte, error) {\n\tdata := map[string]SystemInformationError{}\n\n\tvar sysErr SystemInformationError\n\tif errors.As(err.OperatingSystemInformationError, &sysErr) {\n\t\tdata[\"operatingSystemInformationError\"] = sysErr\n\t}\n\n\tif errors.As(err.MemoryInformationError, &sysErr) {\n\t\tdata[\"memoryInformationError\"] = sysErr\n\t}\n\n\tif errors.As(err.FileDescriptorsInformationError, &sysErr) {\n\t\tdata[\"fileDescriptorsInformationError\"] = sysErr\n\t}\n\n\tif errors.As(err.DiskVolumeInformationError, &sysErr) {\n\t\tdata[\"diskVolumeInformationError\"] = sysErr\n\t}\n\n\treturn json.Marshal(data)\n}\n\ntype DiskVolumeInformation struct {\n\tName        string `json:\"name\"`        // represents the filesystem in linux/macos or device name in windows\n\tSizeMaximum uint64 `json:\"sizeMaximum\"` // represents the maximum size of the disk in kilobytes\n\tSizeCurrent uint64 `json:\"sizeCurrent\"` // represents the current size of the disk in kilobytes\n}\n\nfunc NewDiskVolumeInformation(name string, maximum, current uint64) *DiskVolumeInformation {\n\treturn &DiskVolumeInformation{\n\t\tname,\n\t\tmaximum,\n\t\tcurrent,\n\t}\n}\n\ntype SystemInformation struct {\n\tMemoryMaximum         uint64                   `json:\"memoryMaximum,omitempty\"`         // represents the maximum memory of the system in kilobytes\n\tMemoryCurrent         uint64                   `json:\"memoryCurrent,omitempty\"`         // represents the system's memory in use in kilobytes\n\tFileDescriptorMaximum uint64                   `json:\"fileDescriptorMaximum,omitempty\"` // represents the maximum number of file descriptors of the system\n\tFileDescriptorCurrent uint64                   `json:\"fileDescriptorCurrent,omitempty\"` // represents the system's file descriptors in use\n\tOsSystem              string                   `json:\"osSystem,omitempty\"`              // represents the operating system name i.e.: linux, windows, darwin\n\tHostName              string                   `json:\"hostName,omitempty\"`              // represents the system host name\n\tOsVersion             string                   `json:\"osVersion,omitempty\"`             // detailed information about the system's release version level\n\tOsRelease             string                   `json:\"osRelease,omitempty\"`             // detailed information about the system's release\n\tArchitecture          string                   `json:\"architecture,omitempty\"`          // represents the system's hardware platform i.e: arm64/amd64\n\tCloudflaredVersion    string                   `json:\"cloudflaredVersion,omitempty\"`    // the runtime version of cloudflared\n\tGoVersion             string                   `json:\"goVersion,omitempty\"`\n\tGoArch                string                   `json:\"goArch,omitempty\"`\n\tDisk                  []*DiskVolumeInformation `json:\"disk,omitempty\"`\n}\n\nfunc NewSystemInformation(\n\tmemoryMaximum,\n\tmemoryCurrent,\n\tfilesMaximum,\n\tfilesCurrent uint64,\n\tosystem,\n\tname,\n\tosVersion,\n\tosRelease,\n\tarchitecture,\n\tcloudflaredVersion,\n\tgoVersion,\n\tgoArchitecture string,\n\tdisk []*DiskVolumeInformation,\n) *SystemInformation {\n\treturn &SystemInformation{\n\t\tmemoryMaximum,\n\t\tmemoryCurrent,\n\t\tfilesMaximum,\n\t\tfilesCurrent,\n\t\tosystem,\n\t\tname,\n\t\tosVersion,\n\t\tosRelease,\n\t\tarchitecture,\n\t\tcloudflaredVersion,\n\t\tgoVersion,\n\t\tgoArchitecture,\n\t\tdisk,\n\t}\n}\n\ntype SystemCollector interface {\n\t// If the collection is successful it will return `SystemInformation` struct,\n\t// and a nil error.\n\t//\n\t// This function expects that the caller sets the context timeout to prevent\n\t// long-lived collectors.\n\tCollect(ctx context.Context) (*SystemInformation, error)\n}\n"
  },
  {
    "path": "diagnostic/system_collector_linux.go",
    "content": "//go:build linux\n\npackage diagnostic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os/exec\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype SystemCollectorImpl struct {\n\tversion string\n}\n\nfunc NewSystemCollectorImpl(\n\tversion string,\n) *SystemCollectorImpl {\n\treturn &SystemCollectorImpl{\n\t\tversion,\n\t}\n}\n\nfunc (collector *SystemCollectorImpl) Collect(ctx context.Context) (*SystemInformation, error) {\n\tmemoryInfo, memoryInfoRaw, memoryInfoErr := collectMemoryInformation(ctx)\n\tfdInfo, fdInfoRaw, fdInfoErr := collectFileDescriptorInformation(ctx)\n\tdisks, disksRaw, diskErr := collectDiskVolumeInformationUnix(ctx)\n\tosInfo, osInfoRaw, osInfoErr := collectOSInformationUnix(ctx)\n\n\tvar memoryMaximum, memoryCurrent, fileDescriptorMaximum, fileDescriptorCurrent uint64\n\tvar osSystem, name, osVersion, osRelease, architecture string\n\tgerror := SystemInformationGeneralError{}\n\n\tif memoryInfoErr != nil {\n\t\tgerror.MemoryInformationError = SystemInformationError{\n\t\t\tErr:     memoryInfoErr,\n\t\t\tRawInfo: memoryInfoRaw,\n\t\t}\n\t} else {\n\t\tmemoryMaximum = memoryInfo.MemoryMaximum\n\t\tmemoryCurrent = memoryInfo.MemoryCurrent\n\t}\n\n\tif fdInfoErr != nil {\n\t\tgerror.FileDescriptorsInformationError = SystemInformationError{\n\t\t\tErr:     fdInfoErr,\n\t\t\tRawInfo: fdInfoRaw,\n\t\t}\n\t} else {\n\t\tfileDescriptorMaximum = fdInfo.FileDescriptorMaximum\n\t\tfileDescriptorCurrent = fdInfo.FileDescriptorCurrent\n\t}\n\n\tif diskErr != nil {\n\t\tgerror.DiskVolumeInformationError = SystemInformationError{\n\t\t\tErr:     diskErr,\n\t\t\tRawInfo: disksRaw,\n\t\t}\n\t}\n\n\tif osInfoErr != nil {\n\t\tgerror.OperatingSystemInformationError = SystemInformationError{\n\t\t\tErr:     osInfoErr,\n\t\t\tRawInfo: osInfoRaw,\n\t\t}\n\t} else {\n\t\tosSystem = osInfo.OsSystem\n\t\tname = osInfo.Name\n\t\tosVersion = osInfo.OsVersion\n\t\tosRelease = osInfo.OsRelease\n\t\tarchitecture = osInfo.Architecture\n\t}\n\n\tcloudflaredVersion := collector.version\n\tinfo := NewSystemInformation(\n\t\tmemoryMaximum,\n\t\tmemoryCurrent,\n\t\tfileDescriptorMaximum,\n\t\tfileDescriptorCurrent,\n\t\tosSystem,\n\t\tname,\n\t\tosVersion,\n\t\tosRelease,\n\t\tarchitecture,\n\t\tcloudflaredVersion,\n\t\truntime.Version(),\n\t\truntime.GOARCH,\n\t\tdisks,\n\t)\n\n\treturn info, gerror\n}\n\nfunc collectMemoryInformation(ctx context.Context) (*MemoryInformation, string, error) {\n\t// This function relies on the output of `cat /proc/meminfo` to retrieve\n\t// memoryMax and  memoryCurrent.\n\t// The expected output is in the format of `KEY VALUE UNIT`.\n\tconst (\n\t\tmemTotalPrefix     = \"MemTotal\"\n\t\tmemAvailablePrefix = \"MemAvailable\"\n\t)\n\n\tcommand := exec.CommandContext(ctx, \"cat\", \"/proc/meminfo\")\n\n\tstdout, err := command.Output()\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"error retrieving output from command '%s': %w\", command.String(), err)\n\t}\n\n\toutput := string(stdout)\n\n\tmapper := func(field string) (uint64, error) {\n\t\tfield = strings.TrimRight(field, \" kB\")\n\n\t\treturn strconv.ParseUint(field, 10, 64)\n\t}\n\n\tmemoryInfo, err := ParseMemoryInformationFromKV(output, memTotalPrefix, memAvailablePrefix, mapper)\n\tif err != nil {\n\t\treturn nil, output, err\n\t}\n\n\t// returning raw output in case other collected information\n\t// resulted in errors\n\treturn memoryInfo, output, nil\n}\n\nfunc collectFileDescriptorInformation(ctx context.Context) (*FileDescriptorInformation, string, error) {\n\t// Command retrieved from https://docs.kernel.org/admin-guide/sysctl/fs.html#file-max-file-nr.\n\t// If the sysctl is not available the command with fail.\n\tcommand := exec.CommandContext(ctx, \"sysctl\", \"-n\", \"fs.file-nr\")\n\n\tstdout, err := command.Output()\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"error retrieving output from command '%s': %w\", command.String(), err)\n\t}\n\n\toutput := string(stdout)\n\n\tfileDescriptorInfo, err := ParseSysctlFileDescriptorInformation(output)\n\tif err != nil {\n\t\treturn nil, output, err\n\t}\n\n\t// returning raw output in case other collected information\n\t// resulted in errors\n\treturn fileDescriptorInfo, output, nil\n}\n"
  },
  {
    "path": "diagnostic/system_collector_macos.go",
    "content": "//go:build darwin\n\npackage diagnostic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os/exec\"\n\t\"runtime\"\n\t\"strconv\"\n)\n\ntype SystemCollectorImpl struct {\n\tversion string\n}\n\nfunc NewSystemCollectorImpl(\n\tversion string,\n) *SystemCollectorImpl {\n\treturn &SystemCollectorImpl{\n\t\tversion,\n\t}\n}\n\nfunc (collector *SystemCollectorImpl) Collect(ctx context.Context) (*SystemInformation, error) {\n\tmemoryInfo, memoryInfoRaw, memoryInfoErr := collectMemoryInformation(ctx)\n\tfdInfo, fdInfoRaw, fdInfoErr := collectFileDescriptorInformation(ctx)\n\tdisks, disksRaw, diskErr := collectDiskVolumeInformationUnix(ctx)\n\tosInfo, osInfoRaw, osInfoErr := collectOSInformationUnix(ctx)\n\n\tvar memoryMaximum, memoryCurrent, fileDescriptorMaximum, fileDescriptorCurrent uint64\n\tvar osSystem, name, osVersion, osRelease, architecture string\n\n\terr := SystemInformationGeneralError{\n\t\tOperatingSystemInformationError: nil,\n\t\tMemoryInformationError:          nil,\n\t\tFileDescriptorsInformationError: nil,\n\t\tDiskVolumeInformationError:      nil,\n\t}\n\n\tif memoryInfoErr != nil {\n\t\terr.MemoryInformationError = SystemInformationError{\n\t\t\tErr:     memoryInfoErr,\n\t\t\tRawInfo: memoryInfoRaw,\n\t\t}\n\t} else {\n\t\tmemoryMaximum = memoryInfo.MemoryMaximum\n\t\tmemoryCurrent = memoryInfo.MemoryCurrent\n\t}\n\n\tif fdInfoErr != nil {\n\t\terr.FileDescriptorsInformationError = SystemInformationError{\n\t\t\tErr:     fdInfoErr,\n\t\t\tRawInfo: fdInfoRaw,\n\t\t}\n\t} else {\n\t\tfileDescriptorMaximum = fdInfo.FileDescriptorMaximum\n\t\tfileDescriptorCurrent = fdInfo.FileDescriptorCurrent\n\t}\n\n\tif diskErr != nil {\n\t\terr.DiskVolumeInformationError = SystemInformationError{\n\t\t\tErr:     diskErr,\n\t\t\tRawInfo: disksRaw,\n\t\t}\n\t}\n\n\tif osInfoErr != nil {\n\t\terr.OperatingSystemInformationError = SystemInformationError{\n\t\t\tErr:     osInfoErr,\n\t\t\tRawInfo: osInfoRaw,\n\t\t}\n\t} else {\n\t\tosSystem = osInfo.OsSystem\n\t\tname = osInfo.Name\n\t\tosVersion = osInfo.OsVersion\n\t\tosRelease = osInfo.OsRelease\n\t\tarchitecture = osInfo.Architecture\n\t}\n\n\tcloudflaredVersion := collector.version\n\tinfo := NewSystemInformation(\n\t\tmemoryMaximum,\n\t\tmemoryCurrent,\n\t\tfileDescriptorMaximum,\n\t\tfileDescriptorCurrent,\n\t\tosSystem,\n\t\tname,\n\t\tosVersion,\n\t\tosRelease,\n\t\tarchitecture,\n\t\tcloudflaredVersion,\n\t\truntime.Version(),\n\t\truntime.GOARCH,\n\t\tdisks,\n\t)\n\n\treturn info, err\n}\n\nfunc collectFileDescriptorInformation(ctx context.Context) (\n\t*FileDescriptorInformation,\n\tstring,\n\terror,\n) {\n\tconst (\n\t\tfileDescriptorMaximumKey = \"kern.maxfiles\"\n\t\tfileDescriptorCurrentKey = \"kern.num_files\"\n\t)\n\n\tcommand := exec.CommandContext(ctx, \"sysctl\", fileDescriptorMaximumKey, fileDescriptorCurrentKey)\n\n\tstdout, err := command.Output()\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"error retrieving output from command '%s': %w\", command.String(), err)\n\t}\n\n\toutput := string(stdout)\n\n\tfileDescriptorInfo, err := ParseFileDescriptorInformationFromKV(\n\t\toutput,\n\t\tfileDescriptorMaximumKey,\n\t\tfileDescriptorCurrentKey,\n\t)\n\tif err != nil {\n\t\treturn nil, output, err\n\t}\n\n\t// returning raw output in case other collected information\n\t// resulted in errors\n\treturn fileDescriptorInfo, output, nil\n}\n\nfunc collectMemoryInformation(ctx context.Context) (\n\t*MemoryInformation,\n\tstring,\n\terror,\n) {\n\tconst (\n\t\tmemoryMaximumKey   = \"hw.memsize\"\n\t\tmemoryAvailableKey = \"hw.memsize_usable\"\n\t)\n\n\tcommand := exec.CommandContext(\n\t\tctx,\n\t\t\"sysctl\",\n\t\tmemoryMaximumKey,\n\t\tmemoryAvailableKey,\n\t)\n\n\tstdout, err := command.Output()\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"error retrieving output from command '%s': %w\", command.String(), err)\n\t}\n\n\toutput := string(stdout)\n\n\tmapper := func(field string) (uint64, error) {\n\t\tconst kiloBytes = 1024\n\t\tvalue, err := strconv.ParseUint(field, 10, 64)\n\t\treturn value / kiloBytes, err\n\t}\n\n\tmemoryInfo, err := ParseMemoryInformationFromKV(output, memoryMaximumKey, memoryAvailableKey, mapper)\n\tif err != nil {\n\t\treturn nil, output, err\n\t}\n\n\t// returning raw output in case other collected information\n\t// resulted in errors\n\treturn memoryInfo, output, nil\n}\n"
  },
  {
    "path": "diagnostic/system_collector_test.go",
    "content": "package diagnostic_test\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/cloudflare/cloudflared/diagnostic\"\n)\n\nfunc TestParseMemoryInformationFromKV(t *testing.T) {\n\tt.Parallel()\n\n\tmapper := func(field string) (uint64, error) {\n\t\tvalue, err := strconv.ParseUint(field, 10, 64)\n\t\treturn value, err\n\t}\n\n\tlinuxMapper := func(field string) (uint64, error) {\n\t\tfield = strings.TrimRight(field, \" kB\")\n\t\treturn strconv.ParseUint(field, 10, 64)\n\t}\n\n\twindowsMemoryOutput := `\n\nFreeVirtualMemory      : 5350472\nTotalVirtualMemorySize : 8903424\n\n\n`\n\tmacosMemoryOutput := `hw.memsize: 38654705664\nhw.memsize_usable: 38009012224`\n\tmemoryOutputWithMissingKey := `hw.memsize: 38654705664`\n\n\tlinuxMemoryOutput := `MemTotal:        8028860 kB\nMemFree:          731396 kB\nMemAvailable:    4678844 kB\nBuffers:          472632 kB\nCached:          3186492 kB\nSwapCached:         4196 kB\nActive:          3088988 kB\nInactive:        3468560 kB`\n\n\ttests := []struct {\n\t\tname               string\n\t\toutput             string\n\t\tmemoryMaximumKey   string\n\t\tmemoryAvailableKey string\n\t\texpected           *diagnostic.MemoryInformation\n\t\texpectedErr        bool\n\t\tmapper             func(string) (uint64, error)\n\t}{\n\t\t{\n\t\t\tname:               \"parse linux memory values\",\n\t\t\toutput:             linuxMemoryOutput,\n\t\t\tmemoryMaximumKey:   \"MemTotal\",\n\t\t\tmemoryAvailableKey: \"MemAvailable\",\n\t\t\texpected: &diagnostic.MemoryInformation{\n\t\t\t\t8028860,\n\t\t\t\t8028860 - 4678844,\n\t\t\t},\n\t\t\texpectedErr: false,\n\t\t\tmapper:      linuxMapper,\n\t\t},\n\t\t{\n\t\t\tname:               \"parse memory values with missing key\",\n\t\t\toutput:             memoryOutputWithMissingKey,\n\t\t\tmemoryMaximumKey:   \"hw.memsize\",\n\t\t\tmemoryAvailableKey: \"hw.memsize_usable\",\n\t\t\texpected:           nil,\n\t\t\texpectedErr:        true,\n\t\t\tmapper:             mapper,\n\t\t},\n\t\t{\n\t\t\tname:               \"parse macos memory values\",\n\t\t\toutput:             macosMemoryOutput,\n\t\t\tmemoryMaximumKey:   \"hw.memsize\",\n\t\t\tmemoryAvailableKey: \"hw.memsize_usable\",\n\t\t\texpected: &diagnostic.MemoryInformation{\n\t\t\t\t38654705664,\n\t\t\t\t38654705664 - 38009012224,\n\t\t\t},\n\t\t\texpectedErr: false,\n\t\t\tmapper:      mapper,\n\t\t},\n\t\t{\n\t\t\tname:               \"parse windows memory values\",\n\t\t\toutput:             windowsMemoryOutput,\n\t\t\tmemoryMaximumKey:   \"TotalVirtualMemorySize\",\n\t\t\tmemoryAvailableKey: \"FreeVirtualMemory\",\n\t\t\texpected: &diagnostic.MemoryInformation{\n\t\t\t\t8903424,\n\t\t\t\t8903424 - 5350472,\n\t\t\t},\n\t\t\texpectedErr: false,\n\t\t\tmapper:      mapper,\n\t\t},\n\t}\n\n\tfor _, tCase := range tests {\n\t\tt.Run(tCase.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tmemoryInfo, err := diagnostic.ParseMemoryInformationFromKV(\n\t\t\t\ttCase.output,\n\t\t\t\ttCase.memoryMaximumKey,\n\t\t\t\ttCase.memoryAvailableKey,\n\t\t\t\ttCase.mapper,\n\t\t\t)\n\n\t\t\tif tCase.expectedErr {\n\t\t\t\tassert.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tassert.Equal(t, tCase.expected, memoryInfo)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestParseUnameOutput(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname        string\n\t\toutput      string\n\t\tos          string\n\t\texpected    *diagnostic.OsInfo\n\t\texpectedErr bool\n\t}{\n\t\t{\n\t\t\tname:   \"darwin machine\",\n\t\t\toutput: \"Darwin APC 23.6.0 Darwin Kernel Version 99.6.0: Wed Jul 31 20:48:04 PDT 1997; root:xnu-66666.666.6.666.6~1/RELEASE_ARM64_T6666 arm64\",\n\t\t\tos:     \"darwin\",\n\t\t\texpected: &diagnostic.OsInfo{\n\t\t\t\tArchitecture: \"arm64\",\n\t\t\t\tName:         \"APC\",\n\t\t\t\tOsSystem:     \"Darwin\",\n\t\t\t\tOsRelease:    \"Darwin Kernel Version 99.6.0: Wed Jul 31 20:48:04 PDT 1997; root:xnu-66666.666.6.666.6~1/RELEASE_ARM64_T6666\",\n\t\t\t\tOsVersion:    \"23.6.0\",\n\t\t\t},\n\t\t\texpectedErr: false,\n\t\t},\n\t\t{\n\t\t\tname:   \"linux machine\",\n\t\t\toutput: \"Linux dab00d565591 6.6.31-linuxkit #1 SMP Thu May 23 08:36:57 UTC 2024 aarch64 GNU/Linux\",\n\t\t\tos:     \"linux\",\n\t\t\texpected: &diagnostic.OsInfo{\n\t\t\t\tArchitecture: \"aarch64\",\n\t\t\t\tName:         \"dab00d565591\",\n\t\t\t\tOsSystem:     \"Linux\",\n\t\t\t\tOsRelease:    \"#1 SMP Thu May 23 08:36:57 UTC 2024\",\n\t\t\t\tOsVersion:    \"6.6.31-linuxkit\",\n\t\t\t},\n\t\t\texpectedErr: false,\n\t\t},\n\t\t{\n\t\t\tname:        \"not enough fields\",\n\t\t\toutput:      \"Linux \",\n\t\t\tos:          \"linux\",\n\t\t\texpected:    nil,\n\t\t\texpectedErr: true,\n\t\t},\n\t}\n\n\tfor _, tCase := range tests {\n\t\tt.Run(tCase.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tmemoryInfo, err := diagnostic.ParseUnameOutput(\n\t\t\t\ttCase.output,\n\t\t\t\ttCase.os,\n\t\t\t)\n\n\t\t\tif tCase.expectedErr {\n\t\t\t\tassert.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tassert.Equal(t, tCase.expected, memoryInfo)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestParseFileDescriptorInformationFromKV(t *testing.T) {\n\tconst (\n\t\tfileDescriptorMaximumKey = \"kern.maxfiles\"\n\t\tfileDescriptorCurrentKey = \"kern.num_files\"\n\t)\n\n\tt.Parallel()\n\n\tmemoryOutput := `kern.maxfiles: 276480\nkern.num_files: 11787`\n\tmemoryOutputWithMissingKey := `kern.maxfiles: 276480`\n\n\ttests := []struct {\n\t\tname        string\n\t\toutput      string\n\t\texpected    *diagnostic.FileDescriptorInformation\n\t\texpectedErr bool\n\t}{\n\t\t{\n\t\t\tname:        \"parse memory values with missing key\",\n\t\t\toutput:      memoryOutputWithMissingKey,\n\t\t\texpected:    nil,\n\t\t\texpectedErr: true,\n\t\t},\n\t\t{\n\t\t\tname:   \"parse macos memory values\",\n\t\t\toutput: memoryOutput,\n\t\t\texpected: &diagnostic.FileDescriptorInformation{\n\t\t\t\t276480,\n\t\t\t\t11787,\n\t\t\t},\n\t\t\texpectedErr: false,\n\t\t},\n\t}\n\n\tfor _, tCase := range tests {\n\t\tt.Run(tCase.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tfdInfo, err := diagnostic.ParseFileDescriptorInformationFromKV(\n\t\t\t\ttCase.output,\n\t\t\t\tfileDescriptorMaximumKey,\n\t\t\t\tfileDescriptorCurrentKey,\n\t\t\t)\n\n\t\t\tif tCase.expectedErr {\n\t\t\t\tassert.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tassert.Equal(t, tCase.expected, fdInfo)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestParseSysctlFileDescriptorInformation(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname        string\n\t\toutput      string\n\t\texpected    *diagnostic.FileDescriptorInformation\n\t\texpectedErr bool\n\t}{\n\t\t{\n\t\t\tname:   \"expected output\",\n\t\t\toutput: \"111 0 1111111\",\n\t\t\texpected: &diagnostic.FileDescriptorInformation{\n\t\t\t\tFileDescriptorMaximum: 1111111,\n\t\t\t\tFileDescriptorCurrent: 111,\n\t\t\t},\n\t\t\texpectedErr: false,\n\t\t},\n\t\t{\n\t\t\tname:        \"not enough fields\",\n\t\t\toutput:      \"111 111 \",\n\t\t\texpected:    nil,\n\t\t\texpectedErr: true,\n\t\t},\n\t}\n\n\tfor _, tCase := range tests {\n\t\tt.Run(tCase.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tfdsInfo, err := diagnostic.ParseSysctlFileDescriptorInformation(\n\t\t\t\ttCase.output,\n\t\t\t)\n\n\t\t\tif tCase.expectedErr {\n\t\t\t\tassert.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tassert.Equal(t, tCase.expected, fdsInfo)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestParseWinOperatingSystemInfo(t *testing.T) {\n\tconst (\n\t\tarchitecturePrefix = \"OSArchitecture\"\n\t\tosSystemPrefix     = \"Caption\"\n\t\tosVersionPrefix    = \"Version\"\n\t\tosReleasePrefix    = \"BuildNumber\"\n\t\tnamePrefix         = \"CSName\"\n\t)\n\n\tt.Parallel()\n\n\twindowsIncompleteOsInfo := `\nOSArchitecture         : ARM 64 bits\nCaption                : Microsoft Windows 11 Home\nMorekeys : 121314\nCSName                 : UTILIZA-QO859QP\n`\n\twindowsCompleteOsInfo := `\nOSArchitecture         : ARM 64 bits\nCaption                : Microsoft Windows 11 Home\nVersion                : 10.0.22631\nBuildNumber            : 22631\nMorekeys : 121314\nCSName                 : UTILIZA-QO859QP\n`\n\n\ttests := []struct {\n\t\tname        string\n\t\toutput      string\n\t\texpected    *diagnostic.OsInfo\n\t\texpectedErr bool\n\t}{\n\t\t{\n\t\t\tname:   \"expected output\",\n\t\t\toutput: windowsCompleteOsInfo,\n\t\t\texpected: &diagnostic.OsInfo{\n\t\t\t\tArchitecture: \"ARM 64 bits\",\n\t\t\t\tName:         \"UTILIZA-QO859QP\",\n\t\t\t\tOsSystem:     \"Microsoft Windows 11 Home\",\n\t\t\t\tOsRelease:    \"22631\",\n\t\t\t\tOsVersion:    \"10.0.22631\",\n\t\t\t},\n\t\t\texpectedErr: false,\n\t\t},\n\t\t{\n\t\t\tname:        \"missing keys\",\n\t\t\toutput:      windowsIncompleteOsInfo,\n\t\t\texpected:    nil,\n\t\t\texpectedErr: true,\n\t\t},\n\t}\n\n\tfor _, tCase := range tests {\n\t\tt.Run(tCase.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tosInfo, err := diagnostic.ParseWinOperatingSystemInfo(\n\t\t\t\ttCase.output,\n\t\t\t\tarchitecturePrefix,\n\t\t\t\tosSystemPrefix,\n\t\t\t\tosVersionPrefix,\n\t\t\t\tosReleasePrefix,\n\t\t\t\tnamePrefix,\n\t\t\t)\n\n\t\t\tif tCase.expectedErr {\n\t\t\t\tassert.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tassert.Equal(t, tCase.expected, osInfo)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestParseDiskVolumeInformationOutput(t *testing.T) {\n\tt.Parallel()\n\n\tinvalidUnixDiskVolumeInfo := `Filesystem            Size  Used Avail Use% Mounted on\noverlay                59G   19G   38G  33% /\ntmpfs                  64M     0   64M   0% /dev\nshm                    64M     0   64M   0% /dev/shm\n/run/host_mark/Users  461G  266G  195G  58% /tmp/cloudflared\n/dev/vda1              59G   19G   38G  33% /etc/hosts\ntmpfs                 3.9G     0  3.9G   0% /sys/firmware\n`\n\n\tunixDiskVolumeInfo := `Filesystem            Size  Used Avail Use% Mounted on\noverlay               61202244  18881444  39179476  33% /\ntmpfs                    65536         0     65536   0% /dev\nshm                      65536         0     65536   0% /dev/shm\n/run/host_mark/Users 482797652 278648468 204149184  58% /tmp/cloudflared\n/dev/vda1             61202244  18881444  39179476  33% /etc/hosts\ntmpfs                  4014428         0   4014428   0% /sys/firmware`\n\tmissingFields := ` DeviceID        Size\n--------        ----\nC:       size\nE:         235563008\nZ:       67754782720\n`\n\tinvalidTypeField := ` DeviceID        Size   FreeSpace\n--------        ----   ---------\nC:       size 31318736896\nD:\nE:         235563008           0\nZ:       67754782720 31318732800\n`\n\n\twindowsDiskVolumeInfo := `\n\nDeviceID        Size   FreeSpace\n--------        ----   ---------\nC:       67754782720 31318736896\nE:         235563008           0\nZ:       67754782720 31318732800`\n\n\ttests := []struct {\n\t\tname        string\n\t\toutput      string\n\t\texpected    []*diagnostic.DiskVolumeInformation\n\t\tskipLines   int\n\t\texpectedErr bool\n\t}{\n\t\t{\n\t\t\tname:        \"invalid unix disk volume information (numbers have units)\",\n\t\t\toutput:      invalidUnixDiskVolumeInfo,\n\t\t\texpected:    []*diagnostic.DiskVolumeInformation{},\n\t\t\tskipLines:   1,\n\t\t\texpectedErr: true,\n\t\t},\n\t\t{\n\t\t\tname:      \"unix disk volume information\",\n\t\t\toutput:    unixDiskVolumeInfo,\n\t\t\tskipLines: 1,\n\t\t\texpected: []*diagnostic.DiskVolumeInformation{\n\t\t\t\tdiagnostic.NewDiskVolumeInformation(\"overlay\", 61202244, 18881444),\n\t\t\t\tdiagnostic.NewDiskVolumeInformation(\"tmpfs\", 65536, 0),\n\t\t\t\tdiagnostic.NewDiskVolumeInformation(\"shm\", 65536, 0),\n\t\t\t\tdiagnostic.NewDiskVolumeInformation(\"/run/host_mark/Users\", 482797652, 278648468),\n\t\t\t\tdiagnostic.NewDiskVolumeInformation(\"/dev/vda1\", 61202244, 18881444),\n\t\t\t\tdiagnostic.NewDiskVolumeInformation(\"tmpfs\", 4014428, 0),\n\t\t\t},\n\t\t\texpectedErr: false,\n\t\t},\n\t\t{\n\t\t\tname:   \"windows disk volume information\",\n\t\t\toutput: windowsDiskVolumeInfo,\n\t\t\texpected: []*diagnostic.DiskVolumeInformation{\n\t\t\t\tdiagnostic.NewDiskVolumeInformation(\"C:\", 67754782720, 31318736896),\n\t\t\t\tdiagnostic.NewDiskVolumeInformation(\"E:\", 235563008, 0),\n\t\t\t\tdiagnostic.NewDiskVolumeInformation(\"Z:\", 67754782720, 31318732800),\n\t\t\t},\n\t\t\tskipLines:   4,\n\t\t\texpectedErr: false,\n\t\t},\n\t\t{\n\t\t\tname:        \"insuficient fields\",\n\t\t\toutput:      missingFields,\n\t\t\texpected:    nil,\n\t\t\tskipLines:   2,\n\t\t\texpectedErr: true,\n\t\t},\n\t\t{\n\t\t\tname:        \"invalid field\",\n\t\t\toutput:      invalidTypeField,\n\t\t\texpected:    nil,\n\t\t\tskipLines:   2,\n\t\t\texpectedErr: true,\n\t\t},\n\t}\n\n\tfor _, tCase := range tests {\n\t\tt.Run(tCase.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tdisks, err := diagnostic.ParseDiskVolumeInformationOutput(tCase.output, tCase.skipLines, 1)\n\n\t\t\tif tCase.expectedErr {\n\t\t\t\tassert.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tassert.Equal(t, tCase.expected, disks)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "diagnostic/system_collector_utils.go",
    "content": "package diagnostic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os/exec\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc findColonSeparatedPairs[V any](output string, keys []string, mapper func(string) (V, error)) map[string]V {\n\tconst (\n\t\tmemoryField             = 1\n\t\tmemoryInformationFields = 2\n\t)\n\n\tlines := strings.Split(output, \"\\n\")\n\tpairs := make(map[string]V, 0)\n\n\t// sort keys and lines to allow incremental search\n\tsort.Strings(lines)\n\tsort.Strings(keys)\n\n\t// keeps track of the last key found\n\tlastIndex := 0\n\n\tfor _, line := range lines {\n\t\tif lastIndex == len(keys) {\n\t\t\t// already found all keys no need to continue iterating\n\t\t\t// over the other values\n\t\t\tbreak\n\t\t}\n\n\t\tfor index, key := range keys[lastIndex:] {\n\t\t\tline = strings.TrimSpace(line)\n\t\t\tif strings.HasPrefix(line, key) {\n\t\t\t\tfields := strings.Split(line, \":\")\n\t\t\t\tif len(fields) < memoryInformationFields {\n\t\t\t\t\tlastIndex = index + 1\n\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tfield, err := mapper(strings.TrimSpace(fields[memoryField]))\n\t\t\t\tif err != nil {\n\t\t\t\t\tlastIndex = lastIndex + index + 1\n\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tpairs[key] = field\n\t\t\t\tlastIndex = lastIndex + index + 1\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\treturn pairs\n}\n\nfunc ParseDiskVolumeInformationOutput(output string, skipLines int, scale float64) ([]*DiskVolumeInformation, error) {\n\tconst (\n\t\tdiskFieldsMinimum = 3\n\t\tnameField         = 0\n\t\tsizeMaximumField  = 1\n\t\tsizeCurrentField  = 2\n\t)\n\n\tdisksRaw := strings.Split(output, \"\\n\")\n\tdisks := make([]*DiskVolumeInformation, 0)\n\n\tif skipLines > len(disksRaw) || skipLines < 0 {\n\t\tskipLines = 0\n\t}\n\n\tfor _, disk := range disksRaw[skipLines:] {\n\t\tif disk == \"\" {\n\t\t\t// skip empty line\n\t\t\tcontinue\n\t\t}\n\n\t\tfields := strings.Fields(disk)\n\t\tif len(fields) < diskFieldsMinimum {\n\t\t\treturn nil, fmt.Errorf(\"expected disk volume to have %d fields got %d: %w\",\n\t\t\t\tdiskFieldsMinimum, len(fields), ErrInsuficientFields,\n\t\t\t)\n\t\t}\n\n\t\tname := fields[nameField]\n\n\t\tsizeMaximum, err := strconv.ParseUint(fields[sizeMaximumField], 10, 64)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tsizeCurrent, err := strconv.ParseUint(fields[sizeCurrentField], 10, 64)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tdiskInfo := NewDiskVolumeInformation(\n\t\t\tname, uint64(float64(sizeMaximum)*scale), uint64(float64(sizeCurrent)*scale),\n\t\t)\n\t\tdisks = append(disks, diskInfo)\n\t}\n\n\tif len(disks) == 0 {\n\t\treturn nil, ErrNoVolumeFound\n\t}\n\n\treturn disks, nil\n}\n\ntype OsInfo struct {\n\tOsSystem     string\n\tName         string\n\tOsVersion    string\n\tOsRelease    string\n\tArchitecture string\n}\n\nfunc ParseUnameOutput(output string, system string) (*OsInfo, error) {\n\tconst (\n\t\tosystemField               = 0\n\t\tnameField                  = 1\n\t\tosVersionField             = 2\n\t\tosReleaseStartField        = 3\n\t\tosInformationFieldsMinimum = 6\n\t\tdarwin                     = \"darwin\"\n\t)\n\n\tarchitectureOffset := 2\n\tif system == darwin {\n\t\tarchitectureOffset = 1\n\t}\n\n\tfields := strings.Fields(output)\n\tif len(fields) < osInformationFieldsMinimum {\n\t\treturn nil, fmt.Errorf(\"expected system information to have %d fields got %d: %w\",\n\t\t\tosInformationFieldsMinimum, len(fields), ErrInsuficientFields,\n\t\t)\n\t}\n\n\tarchitectureField := len(fields) - architectureOffset\n\tosystem := fields[osystemField]\n\tname := fields[nameField]\n\tosVersion := fields[osVersionField]\n\tosRelease := strings.Join(fields[osReleaseStartField:architectureField], \" \")\n\tarchitecture := fields[architectureField]\n\n\treturn &OsInfo{\n\t\tosystem,\n\t\tname,\n\t\tosVersion,\n\t\tosRelease,\n\t\tarchitecture,\n\t}, nil\n}\n\nfunc ParseWinOperatingSystemInfo(\n\toutput string,\n\tarchitectureKey string,\n\tosSystemKey string,\n\tosVersionKey string,\n\tosReleaseKey string,\n\tnameKey string,\n) (*OsInfo, error) {\n\tidentity := func(s string) (string, error) { return s, nil }\n\n\tkeys := []string{architectureKey, osSystemKey, osVersionKey, osReleaseKey, nameKey}\n\tpairs := findColonSeparatedPairs(\n\t\toutput,\n\t\tkeys,\n\t\tidentity,\n\t)\n\n\tarchitecture, exists := pairs[architectureKey]\n\tif !exists {\n\t\treturn nil, fmt.Errorf(\"parsing os information: %w, key=%s\", ErrKeyNotFound, architectureKey)\n\t}\n\n\tosSystem, exists := pairs[osSystemKey]\n\tif !exists {\n\t\treturn nil, fmt.Errorf(\"parsing os information: %w, key=%s\", ErrKeyNotFound, osSystemKey)\n\t}\n\n\tosVersion, exists := pairs[osVersionKey]\n\tif !exists {\n\t\treturn nil, fmt.Errorf(\"parsing os information: %w, key=%s\", ErrKeyNotFound, osVersionKey)\n\t}\n\n\tosRelease, exists := pairs[osReleaseKey]\n\tif !exists {\n\t\treturn nil, fmt.Errorf(\"parsing os information: %w, key=%s\", ErrKeyNotFound, osReleaseKey)\n\t}\n\n\tname, exists := pairs[nameKey]\n\tif !exists {\n\t\treturn nil, fmt.Errorf(\"parsing os information: %w, key=%s\", ErrKeyNotFound, nameKey)\n\t}\n\n\treturn &OsInfo{osSystem, name, osVersion, osRelease, architecture}, nil\n}\n\ntype FileDescriptorInformation struct {\n\tFileDescriptorMaximum uint64\n\tFileDescriptorCurrent uint64\n}\n\nfunc ParseSysctlFileDescriptorInformation(output string) (*FileDescriptorInformation, error) {\n\tconst (\n\t\topenFilesField             = 0\n\t\tmaxFilesField              = 2\n\t\tfileDescriptorLimitsFields = 3\n\t)\n\n\tfields := strings.Fields(output)\n\n\tif len(fields) != fileDescriptorLimitsFields {\n\t\treturn nil,\n\t\t\tfmt.Errorf(\n\t\t\t\t\"expected file descriptor information to have %d fields got %d: %w\",\n\t\t\t\tfileDescriptorLimitsFields,\n\t\t\t\tlen(fields),\n\t\t\t\tErrInsuficientFields,\n\t\t\t)\n\t}\n\n\tfileDescriptorCurrent, err := strconv.ParseUint(fields[openFilesField], 10, 64)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"error parsing files current field '%s': %w\",\n\t\t\tfields[openFilesField],\n\t\t\terr,\n\t\t)\n\t}\n\n\tfileDescriptorMaximum, err := strconv.ParseUint(fields[maxFilesField], 10, 64)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing files max field '%s': %w\", fields[maxFilesField], err)\n\t}\n\n\treturn &FileDescriptorInformation{fileDescriptorMaximum, fileDescriptorCurrent}, nil\n}\n\nfunc ParseFileDescriptorInformationFromKV(\n\toutput string,\n\tfileDescriptorMaximumKey string,\n\tfileDescriptorCurrentKey string,\n) (*FileDescriptorInformation, error) {\n\tmapper := func(field string) (uint64, error) {\n\t\treturn strconv.ParseUint(field, 10, 64)\n\t}\n\n\tpairs := findColonSeparatedPairs(output, []string{fileDescriptorMaximumKey, fileDescriptorCurrentKey}, mapper)\n\n\tfileDescriptorMaximum, exists := pairs[fileDescriptorMaximumKey]\n\tif !exists {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"parsing file descriptor information: %w, key=%s\",\n\t\t\tErrKeyNotFound,\n\t\t\tfileDescriptorMaximumKey,\n\t\t)\n\t}\n\n\tfileDescriptorCurrent, exists := pairs[fileDescriptorCurrentKey]\n\tif !exists {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"parsing file descriptor information: %w, key=%s\",\n\t\t\tErrKeyNotFound,\n\t\t\tfileDescriptorCurrentKey,\n\t\t)\n\t}\n\n\treturn &FileDescriptorInformation{fileDescriptorMaximum, fileDescriptorCurrent}, nil\n}\n\ntype MemoryInformation struct {\n\tMemoryMaximum uint64 // size in KB\n\tMemoryCurrent uint64 // size in KB\n}\n\nfunc ParseMemoryInformationFromKV(\n\toutput string,\n\tmemoryMaximumKey string,\n\tmemoryAvailableKey string,\n\tmapper func(field string) (uint64, error),\n) (*MemoryInformation, error) {\n\tpairs := findColonSeparatedPairs(output, []string{memoryMaximumKey, memoryAvailableKey}, mapper)\n\n\tmemoryMaximum, exists := pairs[memoryMaximumKey]\n\tif !exists {\n\t\treturn nil, fmt.Errorf(\"parsing memory information: %w, key=%s\", ErrKeyNotFound, memoryMaximumKey)\n\t}\n\n\tmemoryAvailable, exists := pairs[memoryAvailableKey]\n\tif !exists {\n\t\treturn nil, fmt.Errorf(\"parsing memory information: %w, key=%s\", ErrKeyNotFound, memoryAvailableKey)\n\t}\n\n\tmemoryCurrent := memoryMaximum - memoryAvailable\n\n\treturn &MemoryInformation{memoryMaximum, memoryCurrent}, nil\n}\n\nfunc RawSystemInformation(osInfoRaw string, memoryInfoRaw string, fdInfoRaw string, disksRaw string) string {\n\tvar builder strings.Builder\n\n\tformatInfo := func(info string, builder *strings.Builder) {\n\t\tif info == \"\" {\n\t\t\tbuilder.WriteString(\"No information\\n\")\n\t\t} else {\n\t\t\tbuilder.WriteString(info)\n\t\t\tbuilder.WriteString(\"\\n\")\n\t\t}\n\t}\n\n\tbuilder.WriteString(\"---BEGIN Operating system information\\n\")\n\tformatInfo(osInfoRaw, &builder)\n\tbuilder.WriteString(\"---END Operating system information\\n\")\n\tbuilder.WriteString(\"---BEGIN Memory information\\n\")\n\tformatInfo(memoryInfoRaw, &builder)\n\tbuilder.WriteString(\"---END Memory information\\n\")\n\tbuilder.WriteString(\"---BEGIN File descriptors information\\n\")\n\tformatInfo(fdInfoRaw, &builder)\n\tbuilder.WriteString(\"---END File descriptors information\\n\")\n\tbuilder.WriteString(\"---BEGIN Disks information\\n\")\n\tformatInfo(disksRaw, &builder)\n\tbuilder.WriteString(\"---END Disks information\\n\")\n\n\trawInformation := builder.String()\n\n\treturn rawInformation\n}\n\nfunc collectDiskVolumeInformationUnix(ctx context.Context) ([]*DiskVolumeInformation, string, error) {\n\tcommand := exec.CommandContext(ctx, \"df\", \"-k\")\n\n\tstdout, err := command.Output()\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"error retrieving output from command '%s': %w\", command.String(), err)\n\t}\n\n\toutput := string(stdout)\n\n\tdisks, err := ParseDiskVolumeInformationOutput(output, 1, 1)\n\tif err != nil {\n\t\treturn nil, output, err\n\t}\n\n\t// returning raw output in case other collected information\n\t// resulted in errors\n\treturn disks, output, nil\n}\n\nfunc collectOSInformationUnix(ctx context.Context) (*OsInfo, string, error) {\n\tcommand := exec.CommandContext(ctx, \"uname\", \"-a\")\n\n\tstdout, err := command.Output()\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"error retrieving output from command '%s': %w\", command.String(), err)\n\t}\n\n\toutput := string(stdout)\n\n\tosInfo, err := ParseUnameOutput(output, runtime.GOOS)\n\tif err != nil {\n\t\treturn nil, output, err\n\t}\n\n\t// returning raw output in case other collected information\n\t// resulted in errors\n\treturn osInfo, output, nil\n}\n"
  },
  {
    "path": "diagnostic/system_collector_windows.go",
    "content": "//go:build windows\n\npackage diagnostic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os/exec\"\n\t\"runtime\"\n\t\"strconv\"\n)\n\nconst kiloBytesScale = 1.0 / 1024\n\ntype SystemCollectorImpl struct {\n\tversion string\n}\n\nfunc NewSystemCollectorImpl(\n\tversion string,\n) *SystemCollectorImpl {\n\treturn &SystemCollectorImpl{\n\t\tversion,\n\t}\n}\n\nfunc (collector *SystemCollectorImpl) Collect(ctx context.Context) (*SystemInformation, error) {\n\tmemoryInfo, memoryInfoRaw, memoryInfoErr := collectMemoryInformation(ctx)\n\tdisks, disksRaw, diskErr := collectDiskVolumeInformation(ctx)\n\tosInfo, osInfoRaw, osInfoErr := collectOSInformation(ctx)\n\n\tvar memoryMaximum, memoryCurrent, fileDescriptorMaximum, fileDescriptorCurrent uint64\n\tvar osSystem, name, osVersion, osRelease, architecture string\n\n\terr := SystemInformationGeneralError{\n\t\tOperatingSystemInformationError: nil,\n\t\tMemoryInformationError:          nil,\n\t\tFileDescriptorsInformationError: nil,\n\t\tDiskVolumeInformationError:      nil,\n\t}\n\n\tif memoryInfoErr != nil {\n\t\terr.MemoryInformationError = SystemInformationError{\n\t\t\tErr:     memoryInfoErr,\n\t\t\tRawInfo: memoryInfoRaw,\n\t\t}\n\t} else {\n\t\tmemoryMaximum = memoryInfo.MemoryMaximum\n\t\tmemoryCurrent = memoryInfo.MemoryCurrent\n\t}\n\n\tif diskErr != nil {\n\t\terr.DiskVolumeInformationError = SystemInformationError{\n\t\t\tErr:     diskErr,\n\t\t\tRawInfo: disksRaw,\n\t\t}\n\t}\n\n\tif osInfoErr != nil {\n\t\terr.OperatingSystemInformationError = SystemInformationError{\n\t\t\tErr:     osInfoErr,\n\t\t\tRawInfo: osInfoRaw,\n\t\t}\n\t} else {\n\t\tosSystem = osInfo.OsSystem\n\t\tname = osInfo.Name\n\t\tosVersion = osInfo.OsVersion\n\t\tosRelease = osInfo.OsRelease\n\t\tarchitecture = osInfo.Architecture\n\t}\n\n\tcloudflaredVersion := collector.version\n\tinfo := NewSystemInformation(\n\t\tmemoryMaximum,\n\t\tmemoryCurrent,\n\t\tfileDescriptorMaximum,\n\t\tfileDescriptorCurrent,\n\t\tosSystem,\n\t\tname,\n\t\tosVersion,\n\t\tosRelease,\n\t\tarchitecture,\n\t\tcloudflaredVersion,\n\t\truntime.Version(),\n\t\truntime.GOARCH,\n\t\tdisks,\n\t)\n\n\treturn info, err\n}\n\nfunc collectMemoryInformation(ctx context.Context) (*MemoryInformation, string, error) {\n\tconst (\n\t\tmemoryTotalPrefix     = \"TotalVirtualMemorySize\"\n\t\tmemoryAvailablePrefix = \"FreeVirtualMemory\"\n\t)\n\n\tcommand := exec.CommandContext(\n\t\tctx,\n\t\t\"powershell\",\n\t\t\"-Command\",\n\t\t\"Get-CimInstance -Class Win32_OperatingSystem | Select-Object FreeVirtualMemory, TotalVirtualMemorySize | Format-List\",\n\t)\n\n\tstdout, err := command.Output()\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"error retrieving output from command '%s': %w\", command.String(), err)\n\t}\n\n\toutput := string(stdout)\n\n\t// the result of the command above will return values in bytes hence\n\t// they need to be converted to kilobytes\n\tmapper := func(field string) (uint64, error) {\n\t\tvalue, err := strconv.ParseUint(field, 10, 64)\n\t\treturn uint64(float64(value) * kiloBytesScale), err\n\t}\n\n\tmemoryInfo, err := ParseMemoryInformationFromKV(output, memoryTotalPrefix, memoryAvailablePrefix, mapper)\n\tif err != nil {\n\t\treturn nil, output, err\n\t}\n\n\t// returning raw output in case other collected information\n\t// resulted in errors\n\treturn memoryInfo, output, nil\n}\n\nfunc collectDiskVolumeInformation(ctx context.Context) ([]*DiskVolumeInformation, string, error) {\n\n\tcommand := exec.CommandContext(\n\t\tctx,\n\t\t\"powershell\", \"-Command\", \"Get-CimInstance -Class Win32_LogicalDisk | Select-Object DeviceID, Size, FreeSpace\")\n\n\tstdout, err := command.Output()\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"error retrieving output from command '%s': %w\", command.String(), err)\n\t}\n\n\toutput := string(stdout)\n\n\tdisks, err := ParseDiskVolumeInformationOutput(output, 2, kiloBytesScale)\n\tif err != nil {\n\t\treturn nil, output, err\n\t}\n\n\t// returning raw output in case other collected information\n\t// resulted in errors\n\treturn disks, output, nil\n}\n\nfunc collectOSInformation(ctx context.Context) (*OsInfo, string, error) {\n\tconst (\n\t\tarchitecturePrefix = \"OSArchitecture\"\n\t\tosSystemPrefix     = \"Caption\"\n\t\tosVersionPrefix    = \"Version\"\n\t\tosReleasePrefix    = \"BuildNumber\"\n\t\tnamePrefix         = \"CSName\"\n\t)\n\n\tcommand := exec.CommandContext(\n\t\tctx,\n\t\t\"powershell\",\n\t\t\"-Command\",\n\t\t\"Get-CimInstance -Class Win32_OperatingSystem | Select-Object OSArchitecture, Caption, Version, BuildNumber, CSName | Format-List\",\n\t)\n\n\tstdout, err := command.Output()\n\tif err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"error retrieving output from command '%s': %w\", command.String(), err)\n\t}\n\n\toutput := string(stdout)\n\n\tosInfo, err := ParseWinOperatingSystemInfo(output, architecturePrefix, osSystemPrefix, osVersionPrefix, osReleasePrefix, namePrefix)\n\tif err != nil {\n\t\treturn nil, output, err\n\t}\n\n\t// returning raw output in case other collected information\n\t// resulted in errors\n\treturn osInfo, output, nil\n}\n"
  },
  {
    "path": "edgediscovery/allregions/address.go",
    "content": "package allregions\n\n// Region contains cloudflared edge addresses. The edge is partitioned into several regions for\n// redundancy purposes.\ntype AddrSet map[*EdgeAddr]UsedBy\n\n// AddrUsedBy finds the address used by the given connection in this region.\n// Returns nil if the connection isn't using any IP.\nfunc (a AddrSet) AddrUsedBy(connID int) *EdgeAddr {\n\tfor addr, used := range a {\n\t\tif used.Used && used.ConnID == connID {\n\t\t\treturn addr\n\t\t}\n\t}\n\treturn nil\n}\n\n// AvailableAddrs counts how many unused addresses this region contains.\nfunc (a AddrSet) AvailableAddrs() int {\n\tn := 0\n\tfor _, usedby := range a {\n\t\tif !usedby.Used {\n\t\t\tn++\n\t\t}\n\t}\n\treturn n\n}\n\n// GetUnusedIP returns a random unused address in this region.\n// Returns nil if all addresses are in use.\nfunc (a AddrSet) GetUnusedIP(excluding *EdgeAddr) *EdgeAddr {\n\tfor addr, usedby := range a {\n\t\tif !usedby.Used && addr != excluding {\n\t\t\treturn addr\n\t\t}\n\t}\n\treturn nil\n}\n\n// Use the address, assigning it to a proxy connection.\nfunc (a AddrSet) Use(addr *EdgeAddr, connID int) {\n\tif addr == nil {\n\t\treturn\n\t}\n\ta[addr] = InUse(connID)\n}\n\n// GetAnyAddress returns an arbitrary address from the region.\nfunc (a AddrSet) GetAnyAddress() *EdgeAddr {\n\tfor addr := range a {\n\t\treturn addr\n\t}\n\treturn nil\n}\n\n// GiveBack the address, ensuring it is no longer assigned to an IP.\n// Returns true if the address is in this region.\nfunc (a AddrSet) GiveBack(addr *EdgeAddr) (ok bool) {\n\tif _, ok := a[addr]; !ok {\n\t\treturn false\n\t}\n\ta[addr] = Unused()\n\treturn true\n}\n"
  },
  {
    "path": "edgediscovery/allregions/address_test.go",
    "content": "package allregions\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n)\n\nfunc TestAddrSet_AddrUsedBy(t *testing.T) {\n\ttype args struct {\n\t\tconnID int\n\t}\n\ttests := []struct {\n\t\tname    string\n\t\taddrSet AddrSet\n\t\targs    args\n\t\twant    *EdgeAddr\n\t}{\n\t\t{\n\t\t\tname: \"happy trivial test\",\n\t\t\taddrSet: AddrSet{\n\t\t\t\t&addr0: InUse(0),\n\t\t\t},\n\t\t\targs: args{connID: 0},\n\t\t\twant: &addr0,\n\t\t},\n\t\t{\n\t\t\tname: \"sad trivial test\",\n\t\t\taddrSet: AddrSet{\n\t\t\t\t&addr0: InUse(0),\n\t\t\t},\n\t\t\targs: args{connID: 1},\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"sad test\",\n\t\t\taddrSet: AddrSet{\n\t\t\t\t&addr0: InUse(0),\n\t\t\t\t&addr1: InUse(1),\n\t\t\t\t&addr2: InUse(2),\n\t\t\t},\n\t\t\targs: args{connID: 3},\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"happy test\",\n\t\t\taddrSet: AddrSet{\n\t\t\t\t&addr0: InUse(0),\n\t\t\t\t&addr1: InUse(1),\n\t\t\t\t&addr2: InUse(2),\n\t\t\t},\n\t\t\targs: args{connID: 1},\n\t\t\twant: &addr1,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := tt.addrSet.AddrUsedBy(tt.args.connID); !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"Region.AddrUsedBy() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestAddrSet_AvailableAddrs(t *testing.T) {\n\ttests := []struct {\n\t\tname    string\n\t\taddrSet AddrSet\n\t\twant    int\n\t}{\n\t\t{\n\t\t\tname: \"contains addresses\",\n\t\t\taddrSet: AddrSet{\n\t\t\t\t&addr0: InUse(0),\n\t\t\t\t&addr1: Unused(),\n\t\t\t\t&addr2: InUse(2),\n\t\t\t},\n\t\t\twant: 1,\n\t\t},\n\t\t{\n\t\t\tname: \"all free\",\n\t\t\taddrSet: AddrSet{\n\t\t\t\t&addr0: Unused(),\n\t\t\t\t&addr1: Unused(),\n\t\t\t\t&addr2: Unused(),\n\t\t\t},\n\t\t\twant: 3,\n\t\t},\n\t\t{\n\t\t\tname: \"all used\",\n\t\t\taddrSet: AddrSet{\n\t\t\t\t&addr0: InUse(0),\n\t\t\t\t&addr1: InUse(1),\n\t\t\t\t&addr2: InUse(2),\n\t\t\t},\n\t\t\twant: 0,\n\t\t},\n\t\t{\n\t\t\tname:    \"empty\",\n\t\t\taddrSet: AddrSet{},\n\t\t\twant:    0,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := tt.addrSet.AvailableAddrs(); got != tt.want {\n\t\t\t\tt.Errorf(\"Region.AvailableAddrs() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestAddrSet_GetUnusedIP(t *testing.T) {\n\ttype args struct {\n\t\texcluding *EdgeAddr\n\t}\n\ttests := []struct {\n\t\tname    string\n\t\taddrSet AddrSet\n\t\targs    args\n\t\twant    *EdgeAddr\n\t}{\n\t\t{\n\t\t\tname: \"happy test with excluding set\",\n\t\t\taddrSet: AddrSet{\n\t\t\t\t&addr0: Unused(),\n\t\t\t\t&addr1: Unused(),\n\t\t\t\t&addr2: InUse(2),\n\t\t\t},\n\t\t\targs: args{excluding: &addr0},\n\t\t\twant: &addr1,\n\t\t},\n\t\t{\n\t\t\tname: \"happy test with no excluding\",\n\t\t\taddrSet: AddrSet{\n\t\t\t\t&addr0: InUse(0),\n\t\t\t\t&addr1: Unused(),\n\t\t\t\t&addr2: InUse(2),\n\t\t\t},\n\t\t\targs: args{excluding: nil},\n\t\t\twant: &addr1,\n\t\t},\n\t\t{\n\t\t\tname: \"sad test with no excluding\",\n\t\t\taddrSet: AddrSet{\n\t\t\t\t&addr0: InUse(0),\n\t\t\t\t&addr1: InUse(1),\n\t\t\t\t&addr2: InUse(2),\n\t\t\t},\n\t\t\targs: args{excluding: nil},\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"sad test with excluding\",\n\t\t\taddrSet: AddrSet{\n\t\t\t\t&addr0: Unused(),\n\t\t\t\t&addr1: InUse(1),\n\t\t\t\t&addr2: InUse(2),\n\t\t\t},\n\t\t\targs: args{excluding: &addr0},\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\tif got := tt.addrSet.GetUnusedIP(tt.args.excluding); !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"Region.GetUnusedIP() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestAddrSet_GiveBack(t *testing.T) {\n\ttype args struct {\n\t\taddr *EdgeAddr\n\t}\n\ttests := []struct {\n\t\tname           string\n\t\taddrSet        AddrSet\n\t\targs           args\n\t\twantOk         bool\n\t\tavailableAfter int\n\t}{\n\t\t{\n\t\t\tname: \"sad test with excluding\",\n\t\t\taddrSet: AddrSet{\n\t\t\t\t&addr1: InUse(1),\n\t\t\t},\n\t\t\targs:           args{addr: &addr1},\n\t\t\twantOk:         true,\n\t\t\tavailableAfter: 1,\n\t\t},\n\t\t{\n\t\t\tname: \"sad test with excluding\",\n\t\t\taddrSet: AddrSet{\n\t\t\t\t&addr1: InUse(1),\n\t\t\t},\n\t\t\targs:           args{addr: &addr2},\n\t\t\twantOk:         false,\n\t\t\tavailableAfter: 0,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif gotOk := tt.addrSet.GiveBack(tt.args.addr); gotOk != tt.wantOk {\n\t\t\t\tt.Errorf(\"Region.GiveBack() = %v, want %v\", gotOk, tt.wantOk)\n\t\t\t}\n\t\t\tif tt.availableAfter != tt.addrSet.AvailableAddrs() {\n\t\t\t\tt.Errorf(\"Region.AvailableAddrs() = %v, want %v\", tt.addrSet.AvailableAddrs(), tt.availableAfter)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestAddrSet_GetAnyAddress(t *testing.T) {\n\ttests := []struct {\n\t\tname    string\n\t\taddrSet AddrSet\n\t\twantNil bool\n\t}{\n\t\t{\n\t\t\tname:    \"Sad test -- GetAnyAddress should only fail if the region is empty\",\n\t\t\taddrSet: AddrSet{},\n\t\t\twantNil: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Happy test (all addresses unused)\",\n\t\t\taddrSet: AddrSet{\n\t\t\t\t&addr0: Unused(),\n\t\t\t},\n\t\t\twantNil: false,\n\t\t},\n\t\t{\n\t\t\tname: \"Happy test (GetAnyAddress can still return addresses used by proxy conns)\",\n\t\t\taddrSet: AddrSet{\n\t\t\t\t&addr0: InUse(2),\n\t\t\t},\n\t\t\twantNil: false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := tt.addrSet.GetAnyAddress(); tt.wantNil != (got == nil) {\n\t\t\t\tt.Errorf(\"Region.GetAnyAddress() = %v, but should it return nil? %v\", got, tt.wantNil)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "edgediscovery/allregions/discovery.go",
    "content": "package allregions\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/management\"\n)\n\nconst (\n\t// Used to discover HA origintunneld servers\n\tsrvService = \"v2-origintunneld\"\n\tsrvProto   = \"tcp\"\n\tsrvName    = \"argotunnel.com\"\n\n\t// Used to fallback to DoT when we can't use the default resolver to\n\t// discover HA origintunneld servers (GitHub issue #75).\n\tdotServerName = \"cloudflare-dns.com\"\n\tdotServerAddr = \"1.1.1.1:853\"\n\tdotTimeout    = 15 * time.Second\n\n\tlogFieldAddress = \"address\"\n)\n\n// Redeclare network functions so they can be overridden in tests.\nvar (\n\tnetLookupSRV = net.LookupSRV\n\tnetLookupIP  = net.LookupIP\n)\n\n// ConfigIPVersion is the selection of IP versions from config\ntype ConfigIPVersion int8\n\nconst (\n\tAuto     ConfigIPVersion = 2\n\tIPv4Only ConfigIPVersion = 4\n\tIPv6Only ConfigIPVersion = 6\n)\n\nfunc (c ConfigIPVersion) String() string {\n\tswitch c {\n\tcase Auto:\n\t\treturn \"auto\"\n\tcase IPv4Only:\n\t\treturn \"4\"\n\tcase IPv6Only:\n\t\treturn \"6\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\n// IPVersion is the IP version of an EdgeAddr\ntype EdgeIPVersion int8\n\nconst (\n\tV4 EdgeIPVersion = 4\n\tV6 EdgeIPVersion = 6\n)\n\n// String returns the enum's constant name.\nfunc (c EdgeIPVersion) String() string {\n\tswitch c {\n\tcase V4:\n\t\treturn \"4\"\n\tcase V6:\n\t\treturn \"6\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\n// EdgeAddr is a representation of possible ways to refer an edge location.\ntype EdgeAddr struct {\n\tTCP       *net.TCPAddr\n\tUDP       *net.UDPAddr\n\tIPVersion EdgeIPVersion\n}\n\n// If the call to net.LookupSRV fails, try to fall back to DoT from Cloudflare directly.\n//\n// Note: Instead of DoT, we could also have used DoH. Either of these:\n//   - directly via the JSON API (https://1.1.1.1/dns-query?ct=application/dns-json&name=_origintunneld._tcp.argotunnel.com&type=srv)\n//   - indirectly via `tunneldns.NewUpstreamHTTPS()`\n//\n// But both of these cases miss out on a key feature from the stdlib:\n//\n//\t\"The returned records are sorted by priority and randomized by weight within a priority.\"\n//\t(https://golang.org/pkg/net/#Resolver.LookupSRV)\n//\n// Does this matter? I don't know. It may someday. Let's use DoT so we don't need to worry about it.\n// See also: Go feature request for stdlib-supported DoH: https://github.com/golang/go/issues/27552\nvar fallbackLookupSRV = lookupSRVWithDOT\n\nvar friendlyDNSErrorLines = []string{\n\t`Please try the following things to diagnose this issue:`,\n\t`  1. ensure that argotunnel.com is returning \"origintunneld\" service records.`,\n\t`     Run your system's equivalent of: dig srv _origintunneld._tcp.argotunnel.com`,\n\t`  2. ensure that your DNS resolver is not returning compressed SRV records.`,\n\t`     See GitHub issue https://github.com/golang/go/issues/27546`,\n\t`     For example, you could use Cloudflare's 1.1.1.1 as your resolver:`,\n\t`     https://developers.cloudflare.com/1.1.1.1/setting-up-1.1.1.1/`,\n}\n\n// EdgeDiscovery implements HA service discovery lookup.\nfunc edgeDiscovery(log *zerolog.Logger, srvService string) ([][]*EdgeAddr, error) {\n\tlogger := log.With().Int(management.EventTypeKey, int(management.Cloudflared)).Logger()\n\tlogger.Debug().\n\t\tInt(management.EventTypeKey, int(management.Cloudflared)).\n\t\tStr(\"domain\", \"_\"+srvService+\"._\"+srvProto+\".\"+srvName).\n\t\tMsg(\"edge discovery: looking up edge SRV record\")\n\n\t_, addrs, err := netLookupSRV(srvService, srvProto, srvName)\n\tif err != nil {\n\t\t_, fallbackAddrs, fallbackErr := fallbackLookupSRV(srvService, srvProto, srvName)\n\t\tif fallbackErr != nil || len(fallbackAddrs) == 0 {\n\t\t\t// use the original DNS error `err` in messages, not `fallbackErr`\n\t\t\tlogger.Err(err).Msg(\"edge discovery: error looking up Cloudflare edge IPs: the DNS query failed\")\n\t\t\tfor _, s := range friendlyDNSErrorLines {\n\t\t\t\tlogger.Error().Msg(s)\n\t\t\t}\n\t\t\treturn nil, errors.Wrapf(err, \"Could not lookup srv records on _%v._%v.%v\", srvService, srvProto, srvName)\n\t\t}\n\t\t// Accept the fallback results and keep going\n\t\taddrs = fallbackAddrs\n\t}\n\n\tvar resolvedAddrPerCNAME [][]*EdgeAddr\n\tfor _, addr := range addrs {\n\t\tedgeAddrs, err := resolveSRV(addr)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tlogAddrs := make([]string, len(edgeAddrs))\n\t\tfor i, e := range edgeAddrs {\n\t\t\tlogAddrs[i] = e.UDP.IP.String()\n\t\t}\n\t\tlogger.Debug().\n\t\t\tStrs(\"addresses\", logAddrs).\n\t\t\tMsg(\"edge discovery: resolved edge addresses\")\n\t\tresolvedAddrPerCNAME = append(resolvedAddrPerCNAME, edgeAddrs)\n\t}\n\n\treturn resolvedAddrPerCNAME, nil\n}\n\nfunc lookupSRVWithDOT(srvService string, srvProto string, srvName string) (cname string, addrs []*net.SRV, err error) {\n\t// Inspiration: https://github.com/artyom/dot/blob/master/dot.go\n\tr := &net.Resolver{\n\t\tPreferGo: true,\n\t\tDial: func(ctx context.Context, _ string, _ string) (net.Conn, error) {\n\t\t\tvar dialer net.Dialer\n\t\t\tconn, err := dialer.DialContext(ctx, \"tcp\", dotServerAddr)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\ttlsConfig := &tls.Config{ServerName: dotServerName}\n\t\t\treturn tls.Client(conn, tlsConfig), nil\n\t\t},\n\t}\n\tctx, cancel := context.WithTimeout(context.Background(), dotTimeout)\n\tdefer cancel()\n\treturn r.LookupSRV(ctx, srvService, srvProto, srvName)\n}\n\nfunc resolveSRV(srv *net.SRV) ([]*EdgeAddr, error) {\n\tips, err := netLookupIP(srv.Target)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"Couldn't resolve SRV record %v\", srv)\n\t}\n\tif len(ips) == 0 {\n\t\treturn nil, fmt.Errorf(\"SRV record %v had no IPs\", srv)\n\t}\n\taddrs := make([]*EdgeAddr, len(ips))\n\tfor i, ip := range ips {\n\t\tversion := V6\n\t\tif ip.To4() != nil {\n\t\t\tversion = V4\n\t\t}\n\t\taddrs[i] = &EdgeAddr{\n\t\t\tTCP:       &net.TCPAddr{IP: ip, Port: int(srv.Port)},\n\t\t\tUDP:       &net.UDPAddr{IP: ip, Port: int(srv.Port)},\n\t\t\tIPVersion: version,\n\t\t}\n\t}\n\treturn addrs, nil\n}\n\n// ResolveAddrs resolves TCP address given a list of addresses. Address can be a hostname, however, it will return at most one\n// of the hostname's IP addresses.\nfunc ResolveAddrs(addrs []string, log *zerolog.Logger) (resolved []*EdgeAddr) {\n\tfor _, addr := range addrs {\n\t\ttcpAddr, err := net.ResolveTCPAddr(\"tcp\", addr)\n\t\tif err != nil {\n\t\t\tlog.Error().Int(management.EventTypeKey, int(management.Cloudflared)).\n\t\t\t\tStr(logFieldAddress, addr).Err(err).Msg(\"edge discovery: failed to resolve to TCP address\")\n\t\t\tcontinue\n\t\t}\n\n\t\tudpAddr, err := net.ResolveUDPAddr(\"udp\", addr)\n\t\tif err != nil {\n\t\t\tlog.Error().Int(management.EventTypeKey, int(management.Cloudflared)).\n\t\t\t\tStr(logFieldAddress, addr).Err(err).Msg(\"edge discovery: failed to resolve to UDP address\")\n\t\t\tcontinue\n\t\t}\n\t\tversion := V6\n\t\tif udpAddr.IP.To4() != nil {\n\t\t\tversion = V4\n\t\t}\n\t\tresolved = append(resolved, &EdgeAddr{\n\t\t\tTCP:       tcpAddr,\n\t\t\tUDP:       udpAddr,\n\t\t\tIPVersion: version,\n\t\t})\n\t}\n\treturn\n}\n"
  },
  {
    "path": "edgediscovery/allregions/discovery_test.go",
    "content": "package allregions\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc (ea *EdgeAddr) String() string {\n\treturn fmt.Sprintf(\"%s-%s\", ea.TCP, ea.UDP)\n}\n\nfunc TestEdgeDiscovery(t *testing.T) {\n\tmockAddrs := newMockAddrs(19, 2, 5)\n\tnetLookupSRV = mockNetLookupSRV(mockAddrs)\n\tnetLookupIP = mockNetLookupIP(mockAddrs)\n\n\texpectedAddrSet := map[string]bool{}\n\tfor _, addrs := range mockAddrs.addrMap {\n\t\tfor _, addr := range addrs {\n\t\t\texpectedAddrSet[addr.String()] = true\n\t\t}\n\t}\n\n\tl := zerolog.Nop()\n\taddrLists, err := edgeDiscovery(&l, \"\")\n\tassert.NoError(t, err)\n\tactualAddrSet := map[string]bool{}\n\tfor _, addrs := range addrLists {\n\t\tfor _, addr := range addrs {\n\t\t\tactualAddrSet[addr.String()] = true\n\t\t}\n\t}\n\n\tassert.Equal(t, expectedAddrSet, actualAddrSet)\n}\n"
  },
  {
    "path": "edgediscovery/allregions/mocks_for_test.go",
    "content": "package allregions\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"math/rand\"\n\t\"net\"\n\t\"reflect\"\n\t\"testing/quick\"\n)\n\nvar (\n\tv4Addrs = []*EdgeAddr{&addr0, &addr1, &addr2, &addr3}\n\tv6Addrs = []*EdgeAddr{&addr4, &addr5, &addr6, &addr7}\n\taddr0   = EdgeAddr{\n\t\tTCP: &net.TCPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.0\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tUDP: &net.UDPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.0\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tIPVersion: V4,\n\t}\n\taddr1 = EdgeAddr{\n\t\tTCP: &net.TCPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.1\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tUDP: &net.UDPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.1\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tIPVersion: V4,\n\t}\n\taddr2 = EdgeAddr{\n\t\tTCP: &net.TCPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.2\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tUDP: &net.UDPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.2\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tIPVersion: V4,\n\t}\n\taddr3 = EdgeAddr{\n\t\tTCP: &net.TCPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.3\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tUDP: &net.UDPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.3\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tIPVersion: V4,\n\t}\n\taddr4 = EdgeAddr{\n\t\tTCP: &net.TCPAddr{\n\t\t\tIP:   net.ParseIP(\"2606:4700:a0::1\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tUDP: &net.UDPAddr{\n\t\t\tIP:   net.ParseIP(\"2606:4700:a0::1\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tIPVersion: V6,\n\t}\n\taddr5 = EdgeAddr{\n\t\tTCP: &net.TCPAddr{\n\t\t\tIP:   net.ParseIP(\"2606:4700:a0::2\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tUDP: &net.UDPAddr{\n\t\t\tIP:   net.ParseIP(\"2606:4700:a0::2\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tIPVersion: V6,\n\t}\n\taddr6 = EdgeAddr{\n\t\tTCP: &net.TCPAddr{\n\t\t\tIP:   net.ParseIP(\"2606:4700:a0::3\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tUDP: &net.UDPAddr{\n\t\t\tIP:   net.ParseIP(\"2606:4700:a0::3\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tIPVersion: V6,\n\t}\n\taddr7 = EdgeAddr{\n\t\tTCP: &net.TCPAddr{\n\t\t\tIP:   net.ParseIP(\"2606:4700:a0::4\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tUDP: &net.UDPAddr{\n\t\t\tIP:   net.ParseIP(\"2606:4700:a0::4\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tIPVersion: V6,\n\t}\n)\n\ntype mockAddrs struct {\n\t// a set of synthetic SRV records\n\taddrMap map[net.SRV][]*EdgeAddr\n\t// the total number of addresses, aggregated across addrMap.\n\t// For the convenience of test code that would otherwise have to compute\n\t// this by hand every time.\n\tnumAddrs int\n}\n\nfunc newMockAddrs(port uint16, numRegions uint8, numAddrsPerRegion uint8) mockAddrs {\n\taddrMap := make(map[net.SRV][]*EdgeAddr)\n\tnumAddrs := 0\n\n\tfor r := uint8(0); r < numRegions; r++ {\n\t\tvar (\n\t\t\tsrv   = net.SRV{Target: fmt.Sprintf(\"test-region-%v.example.com\", r), Port: port}\n\t\t\taddrs []*EdgeAddr\n\t\t)\n\t\tfor a := uint8(0); a < numAddrsPerRegion; a++ {\n\t\t\ttcpAddr := &net.TCPAddr{\n\t\t\t\tIP:   net.ParseIP(fmt.Sprintf(\"10.0.%v.%v\", r, a)),\n\t\t\t\tPort: int(port),\n\t\t\t}\n\t\t\tudpAddr := &net.UDPAddr{\n\t\t\t\tIP:   net.ParseIP(fmt.Sprintf(\"10.0.%v.%v\", r, a)),\n\t\t\t\tPort: int(port),\n\t\t\t}\n\t\t\taddrs = append(addrs, &EdgeAddr{tcpAddr, udpAddr, V4})\n\t\t}\n\t\taddrMap[srv] = addrs\n\t\tnumAddrs += len(addrs)\n\t}\n\treturn mockAddrs{addrMap: addrMap, numAddrs: numAddrs}\n}\n\nvar _ quick.Generator = mockAddrs{}\n\nfunc (mockAddrs) Generate(rand *rand.Rand, size int) reflect.Value {\n\tport := uint16(rand.Intn(math.MaxUint16))\n\tnumRegions := uint8(1 + rand.Intn(10))\n\tnumAddrsPerRegion := uint8(1 + rand.Intn(32))\n\tresult := newMockAddrs(port, numRegions, numAddrsPerRegion)\n\treturn reflect.ValueOf(result)\n}\n\n// Returns a function compatible with net.LookupSRV that will return the SRV\n// records from mockAddrs.\nfunc mockNetLookupSRV(\n\tm mockAddrs,\n) func(service, proto, name string) (cname string, addrs []*net.SRV, err error) {\n\tvar addrs []*net.SRV\n\tfor k := range m.addrMap {\n\t\taddr := k\n\t\taddrs = append(addrs, &addr)\n\t\t// We can't just do\n\t\t//   addrs = append(addrs, &k)\n\t\t// `k` will be reused by subsequent loop iterations,\n\t\t// so all the copies of `&k` would point to the same location.\n\t}\n\treturn func(_, _, _ string) (string, []*net.SRV, error) {\n\t\treturn \"\", addrs, nil\n\t}\n}\n\n// Returns a function compatible with net.LookupIP that translates the SRV records\n// from mockAddrs into IP addresses, based on the TCP addresses in mockAddrs.\nfunc mockNetLookupIP(\n\tm mockAddrs,\n) func(host string) ([]net.IP, error) {\n\treturn func(host string) ([]net.IP, error) {\n\t\tfor srv, addrs := range m.addrMap {\n\t\t\tif srv.Target != host {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tresult := make([]net.IP, len(addrs))\n\t\t\tfor i, addr := range addrs {\n\t\t\t\tresult[i] = addr.TCP.IP\n\t\t\t}\n\t\t\treturn result, nil\n\t\t}\n\t\treturn nil, fmt.Errorf(\"No IPs for %v\", host)\n\t}\n}\n"
  },
  {
    "path": "edgediscovery/allregions/region.go",
    "content": "package allregions\n\nimport \"time\"\n\nconst (\n\ttimeoutDuration = 10 * time.Minute\n)\n\n// Region contains cloudflared edge addresses. The edge is partitioned into several regions for\n// redundancy purposes.\ntype Region struct {\n\tprimaryIsActive bool\n\tactive          AddrSet\n\tprimary         AddrSet\n\tsecondary       AddrSet\n\tprimaryTimeout  time.Time\n\ttimeoutDuration time.Duration\n}\n\n// NewRegion creates a region with the given addresses, which are all unused.\nfunc NewRegion(addrs []*EdgeAddr, overrideIPVersion ConfigIPVersion) Region {\n\t// The zero value of UsedBy is Unused(), so we can just initialize the map's values with their\n\t// zero values.\n\tconnForv4 := make(AddrSet)\n\tconnForv6 := make(AddrSet)\n\tsystemPreference := V6\n\tfor i, addr := range addrs {\n\t\tif i == 0 {\n\t\t\t// First family of IPs returned is system preference of IP\n\t\t\tsystemPreference = addr.IPVersion\n\t\t}\n\t\tswitch addr.IPVersion {\n\t\tcase V4:\n\t\t\tconnForv4[addr] = Unused()\n\t\tcase V6:\n\t\t\tconnForv6[addr] = Unused()\n\t\t}\n\t}\n\n\t// Process as system preference\n\tvar primary AddrSet\n\tvar secondary AddrSet\n\tswitch systemPreference {\n\tcase V4:\n\t\tprimary = connForv4\n\t\tsecondary = connForv6\n\tcase V6:\n\t\tprimary = connForv6\n\t\tsecondary = connForv4\n\t}\n\n\t// Override with provided preference\n\tswitch overrideIPVersion {\n\tcase IPv4Only:\n\t\tprimary = connForv4\n\t\tsecondary = make(AddrSet) // empty\n\tcase IPv6Only:\n\t\tprimary = connForv6\n\t\tsecondary = make(AddrSet) // empty\n\tcase Auto:\n\t\t// no change\n\tdefault:\n\t\t// no change\n\t}\n\n\treturn Region{\n\t\tprimaryIsActive: true,\n\t\tactive:          primary,\n\t\tprimary:         primary,\n\t\tsecondary:       secondary,\n\t\ttimeoutDuration: timeoutDuration,\n\t}\n}\n\n// AddrUsedBy finds the address used by the given connection in this region.\n// Returns nil if the connection isn't using any IP.\nfunc (r *Region) AddrUsedBy(connID int) *EdgeAddr {\n\tedgeAddr := r.primary.AddrUsedBy(connID)\n\tif edgeAddr == nil {\n\t\tedgeAddr = r.secondary.AddrUsedBy(connID)\n\t}\n\treturn edgeAddr\n}\n\n// AvailableAddrs counts how many unused addresses this region contains.\nfunc (r Region) AvailableAddrs() int {\n\treturn r.active.AvailableAddrs()\n}\n\n// AssignAnyAddress returns a random unused address in this region now\n// assigned to the connID excluding the provided EdgeAddr.\n// Returns nil if all addresses are in use for the region.\nfunc (r Region) AssignAnyAddress(connID int, excluding *EdgeAddr) *EdgeAddr {\n\tif addr := r.active.GetUnusedIP(excluding); addr != nil {\n\t\tr.active.Use(addr, connID)\n\t\treturn addr\n\t}\n\treturn nil\n}\n\n// GetAnyAddress returns an arbitrary address from the region.\nfunc (r Region) GetAnyAddress() *EdgeAddr {\n\treturn r.active.GetAnyAddress()\n}\n\n// GiveBack the address, ensuring it is no longer assigned to an IP.\n// Returns true if the address is in this region.\nfunc (r *Region) GiveBack(addr *EdgeAddr, hasConnectivityError bool) (ok bool) {\n\tif ok = r.primary.GiveBack(addr); !ok {\n\t\t// Attempt to give back the address in the secondary set\n\t\tif ok = r.secondary.GiveBack(addr); !ok {\n\t\t\t// Address is not in this region\n\t\t\treturn\n\t\t}\n\t}\n\n\t// No connectivity error: no worry\n\tif !hasConnectivityError {\n\t\treturn\n\t}\n\n\t// If using primary and returned address is IPv6 and secondary is available\n\tif r.primaryIsActive && addr.IPVersion == V6 && len(r.secondary) > 0 {\n\t\tr.active = r.secondary\n\t\tr.primaryIsActive = false\n\t\tr.primaryTimeout = time.Now().Add(r.timeoutDuration)\n\t\treturn\n\t}\n\n\t// Do nothing for IPv4 or if secondary is empty\n\tif r.primaryIsActive {\n\t\treturn\n\t}\n\n\t// Immediately return to primary pool, regardless of current primary timeout\n\tif addr.IPVersion == V4 {\n\t\tactivatePrimary(r)\n\t\treturn\n\t}\n\n\t// Timeout exceeded and can be reset to primary pool\n\tif r.primaryTimeout.Before(time.Now()) {\n\t\tactivatePrimary(r)\n\t\treturn\n\t}\n\n\treturn\n}\n\n// activatePrimary sets the primary set to the active set and resets the timeout.\nfunc activatePrimary(r *Region) {\n\tr.active = r.primary\n\tr.primaryIsActive = true\n\tr.primaryTimeout = time.Now() // reset timeout\n}\n"
  },
  {
    "path": "edgediscovery/allregions/region_test.go",
    "content": "package allregions\n\nimport (\n\t\"net\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc makeAddrSet(addrs []*EdgeAddr) AddrSet {\n\taddrSet := make(AddrSet, len(addrs))\n\tfor _, addr := range addrs {\n\t\taddrSet[addr] = Unused()\n\t}\n\treturn addrSet\n}\n\nfunc TestRegion_New(t *testing.T) {\n\ttests := []struct {\n\t\tname          string\n\t\taddrs         []*EdgeAddr\n\t\tmode          ConfigIPVersion\n\t\texpectedAddrs int\n\t\tprimary       AddrSet\n\t\tsecondary     AddrSet\n\t}{\n\t\t{\n\t\t\tname:          \"IPv4 addresses with IPv4Only\",\n\t\t\taddrs:         v4Addrs,\n\t\t\tmode:          IPv4Only,\n\t\t\texpectedAddrs: len(v4Addrs),\n\t\t\tprimary:       makeAddrSet(v4Addrs),\n\t\t\tsecondary:     AddrSet{},\n\t\t},\n\t\t{\n\t\t\tname:          \"IPv6 addresses with IPv4Only\",\n\t\t\taddrs:         v6Addrs,\n\t\t\tmode:          IPv4Only,\n\t\t\texpectedAddrs: 0,\n\t\t\tprimary:       AddrSet{},\n\t\t\tsecondary:     AddrSet{},\n\t\t},\n\t\t{\n\t\t\tname:          \"IPv6 addresses with IPv6Only\",\n\t\t\taddrs:         v6Addrs,\n\t\t\tmode:          IPv6Only,\n\t\t\texpectedAddrs: len(v6Addrs),\n\t\t\tprimary:       makeAddrSet(v6Addrs),\n\t\t\tsecondary:     AddrSet{},\n\t\t},\n\t\t{\n\t\t\tname:          \"IPv6 addresses with IPv4Only\",\n\t\t\taddrs:         v6Addrs,\n\t\t\tmode:          IPv4Only,\n\t\t\texpectedAddrs: 0,\n\t\t\tprimary:       AddrSet{},\n\t\t\tsecondary:     AddrSet{},\n\t\t},\n\t\t{\n\t\t\tname:          \"IPv4 (first) and IPv6 addresses with Auto\",\n\t\t\taddrs:         append(v4Addrs, v6Addrs...),\n\t\t\tmode:          Auto,\n\t\t\texpectedAddrs: len(v4Addrs),\n\t\t\tprimary:       makeAddrSet(v4Addrs),\n\t\t\tsecondary:     makeAddrSet(v6Addrs),\n\t\t},\n\t\t{\n\t\t\tname:          \"IPv6 (first) and IPv4 addresses with Auto\",\n\t\t\taddrs:         append(v6Addrs, v4Addrs...),\n\t\t\tmode:          Auto,\n\t\t\texpectedAddrs: len(v6Addrs),\n\t\t\tprimary:       makeAddrSet(v6Addrs),\n\t\t\tsecondary:     makeAddrSet(v4Addrs),\n\t\t},\n\t\t{\n\t\t\tname:          \"IPv4 addresses with Auto\",\n\t\t\taddrs:         v4Addrs,\n\t\t\tmode:          Auto,\n\t\t\texpectedAddrs: len(v4Addrs),\n\t\t\tprimary:       makeAddrSet(v4Addrs),\n\t\t\tsecondary:     AddrSet{},\n\t\t},\n\t\t{\n\t\t\tname:          \"IPv6 addresses with Auto\",\n\t\t\taddrs:         v6Addrs,\n\t\t\tmode:          Auto,\n\t\t\texpectedAddrs: len(v6Addrs),\n\t\t\tprimary:       makeAddrSet(v6Addrs),\n\t\t\tsecondary:     AddrSet{},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tr := NewRegion(tt.addrs, tt.mode)\n\t\t\tassert.Equal(t, tt.expectedAddrs, r.AvailableAddrs())\n\t\t\tassert.Equal(t, tt.primary, r.primary)\n\t\t\tassert.Equal(t, tt.secondary, r.secondary)\n\t\t})\n\t}\n}\n\nfunc TestRegion_AnyAddress_EmptyActiveSet(t *testing.T) {\n\ttests := []struct {\n\t\tname  string\n\t\taddrs []*EdgeAddr\n\t\tmode  ConfigIPVersion\n\t}{\n\t\t{\n\t\t\tname:  \"IPv6 addresses with IPv4Only\",\n\t\t\taddrs: v6Addrs,\n\t\t\tmode:  IPv4Only,\n\t\t},\n\t\t{\n\t\t\tname:  \"IPv4 addresses with IPv6Only\",\n\t\t\taddrs: v4Addrs,\n\t\t\tmode:  IPv6Only,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tr := NewRegion(tt.addrs, tt.mode)\n\t\t\taddr := r.GetAnyAddress()\n\t\t\tassert.Nil(t, addr)\n\t\t\taddr = r.AssignAnyAddress(0, nil)\n\t\t\tassert.Nil(t, addr)\n\t\t})\n\t}\n}\n\nfunc TestRegion_AssignAnyAddress_FullyUsedActiveSet(t *testing.T) {\n\ttests := []struct {\n\t\tname  string\n\t\taddrs []*EdgeAddr\n\t\tmode  ConfigIPVersion\n\t}{\n\t\t{\n\t\t\tname:  \"IPv6 addresses with IPv6Only\",\n\t\t\taddrs: v6Addrs,\n\t\t\tmode:  IPv6Only,\n\t\t},\n\t\t{\n\t\t\tname:  \"IPv4 addresses with IPv4Only\",\n\t\t\taddrs: v4Addrs,\n\t\t\tmode:  IPv4Only,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tr := NewRegion(tt.addrs, tt.mode)\n\t\t\ttotal := r.active.AvailableAddrs()\n\t\t\tfor i := 0; i < total; i++ {\n\t\t\t\taddr := r.AssignAnyAddress(i, nil)\n\t\t\t\tassert.NotNil(t, addr)\n\t\t\t}\n\t\t\taddr := r.AssignAnyAddress(9, nil)\n\t\t\tassert.Nil(t, addr)\n\t\t})\n\t}\n}\n\nvar giveBackTests = []struct {\n\tname          string\n\taddrs         []*EdgeAddr\n\tmode          ConfigIPVersion\n\texpectedAddrs int\n\tprimary       AddrSet\n\tsecondary     AddrSet\n\tprimarySwap   bool\n}{\n\t{\n\t\tname:          \"IPv4 addresses with IPv4Only\",\n\t\taddrs:         v4Addrs,\n\t\tmode:          IPv4Only,\n\t\texpectedAddrs: len(v4Addrs),\n\t\tprimary:       makeAddrSet(v4Addrs),\n\t\tsecondary:     AddrSet{},\n\t\tprimarySwap:   false,\n\t},\n\t{\n\t\tname:          \"IPv6 addresses with IPv6Only\",\n\t\taddrs:         v6Addrs,\n\t\tmode:          IPv6Only,\n\t\texpectedAddrs: len(v6Addrs),\n\t\tprimary:       makeAddrSet(v6Addrs),\n\t\tsecondary:     AddrSet{},\n\t\tprimarySwap:   false,\n\t},\n\t{\n\t\tname:          \"IPv4 (first) and IPv6 addresses with Auto\",\n\t\taddrs:         append(v4Addrs, v6Addrs...),\n\t\tmode:          Auto,\n\t\texpectedAddrs: len(v4Addrs),\n\t\tprimary:       makeAddrSet(v4Addrs),\n\t\tsecondary:     makeAddrSet(v6Addrs),\n\t\tprimarySwap:   false,\n\t},\n\t{\n\t\tname:          \"IPv6 (first) and IPv4 addresses with Auto\",\n\t\taddrs:         append(v6Addrs, v4Addrs...),\n\t\tmode:          Auto,\n\t\texpectedAddrs: len(v6Addrs),\n\t\tprimary:       makeAddrSet(v6Addrs),\n\t\tsecondary:     makeAddrSet(v4Addrs),\n\t\tprimarySwap:   true,\n\t},\n\t{\n\t\tname:          \"IPv4 addresses with Auto\",\n\t\taddrs:         v4Addrs,\n\t\tmode:          Auto,\n\t\texpectedAddrs: len(v4Addrs),\n\t\tprimary:       makeAddrSet(v4Addrs),\n\t\tsecondary:     AddrSet{},\n\t\tprimarySwap:   false,\n\t},\n\t{\n\t\tname:          \"IPv6 addresses with Auto\",\n\t\taddrs:         v6Addrs,\n\t\tmode:          Auto,\n\t\texpectedAddrs: len(v6Addrs),\n\t\tprimary:       makeAddrSet(v6Addrs),\n\t\tsecondary:     AddrSet{},\n\t\tprimarySwap:   false,\n\t},\n}\n\nfunc TestRegion_GiveBack_NoConnectivityError(t *testing.T) {\n\tfor _, tt := range giveBackTests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tr := NewRegion(tt.addrs, tt.mode)\n\t\t\taddr := r.AssignAnyAddress(0, nil)\n\t\t\tassert.NotNil(t, addr)\n\t\t\tassert.True(t, r.GiveBack(addr, false))\n\t\t})\n\t}\n}\n\nfunc TestRegion_GiveBack_ForeignAddr(t *testing.T) {\n\tinvalid := EdgeAddr{\n\t\tTCP: &net.TCPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.0\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tUDP: &net.UDPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.0\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tIPVersion: V4,\n\t}\n\tfor _, tt := range giveBackTests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tr := NewRegion(tt.addrs, tt.mode)\n\t\t\tassert.False(t, r.GiveBack(&invalid, false))\n\t\t\tassert.False(t, r.GiveBack(&invalid, true))\n\t\t})\n\t}\n}\n\nfunc TestRegion_GiveBack_SwapPrimary(t *testing.T) {\n\tfor _, tt := range giveBackTests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tr := NewRegion(tt.addrs, tt.mode)\n\t\t\taddr := r.AssignAnyAddress(0, nil)\n\t\t\tassert.NotNil(t, addr)\n\t\t\tassert.True(t, r.GiveBack(addr, true))\n\t\t\tassert.Equal(t, tt.primarySwap, !r.primaryIsActive)\n\t\t\tif tt.primarySwap {\n\t\t\t\tassert.Equal(t, r.secondary, r.active)\n\t\t\t\tassert.False(t, r.primaryTimeout.IsZero())\n\t\t\t} else {\n\t\t\t\tassert.Equal(t, r.primary, r.active)\n\t\t\t\tassert.True(t, r.primaryTimeout.IsZero())\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestRegion_GiveBack_IPv4_ResetPrimary(t *testing.T) {\n\tr := NewRegion(append(v6Addrs, v4Addrs...), Auto)\n\t// Exhaust all IPv6 addresses\n\ta0 := r.AssignAnyAddress(0, nil)\n\ta1 := r.AssignAnyAddress(1, nil)\n\ta2 := r.AssignAnyAddress(2, nil)\n\ta3 := r.AssignAnyAddress(3, nil)\n\tassert.NotNil(t, a0)\n\tassert.NotNil(t, a1)\n\tassert.NotNil(t, a2)\n\tassert.NotNil(t, a3)\n\t// Give back the first IPv6 address to fallback to secondary IPv4 address set\n\tassert.True(t, r.GiveBack(a0, true))\n\tassert.False(t, r.primaryIsActive)\n\t// Give back another IPv6 address\n\tassert.True(t, r.GiveBack(a1, true))\n\t// Primary shouldn't change\n\tassert.False(t, r.primaryIsActive)\n\t// Request an address (should be IPv4 from secondary)\n\ta4_v4 := r.AssignAnyAddress(4, nil)\n\tassert.NotNil(t, a4_v4)\n\tassert.Equal(t, V4, a4_v4.IPVersion)\n\ta5_v4 := r.AssignAnyAddress(5, nil)\n\tassert.NotNil(t, a5_v4)\n\tassert.Equal(t, V4, a5_v4.IPVersion)\n\ta6_v4 := r.AssignAnyAddress(6, nil)\n\tassert.NotNil(t, a6_v4)\n\tassert.Equal(t, V4, a6_v4.IPVersion)\n\t// Return IPv4 address (without failure)\n\t// Primary shouldn't change because it is not a connectivity failure\n\tassert.True(t, r.GiveBack(a4_v4, false))\n\tassert.False(t, r.primaryIsActive)\n\t// Return IPv4 address (with failure)\n\t// Primary should change because it is a connectivity failure\n\tassert.True(t, r.GiveBack(a5_v4, true))\n\tassert.True(t, r.primaryIsActive)\n\t// Return IPv4 address (with failure)\n\t// Primary shouldn't change because the address is returned to the inactive\n\t// secondary address set\n\tassert.True(t, r.GiveBack(a6_v4, true))\n\tassert.True(t, r.primaryIsActive)\n\t// Return IPv6 address (without failure)\n\t// Primary shoudn't change because it is not a connectivity failure\n\tassert.True(t, r.GiveBack(a2, false))\n\tassert.True(t, r.primaryIsActive)\n}\n\nfunc TestRegion_GiveBack_Timeout(t *testing.T) {\n\tr := NewRegion(append(v6Addrs, v4Addrs...), Auto)\n\ta0 := r.AssignAnyAddress(0, nil)\n\ta1 := r.AssignAnyAddress(1, nil)\n\ta2 := r.AssignAnyAddress(2, nil)\n\tassert.NotNil(t, a0)\n\tassert.NotNil(t, a1)\n\tassert.NotNil(t, a2)\n\t// Give back IPv6 address to set timeout\n\tassert.True(t, r.GiveBack(a0, true))\n\tassert.False(t, r.primaryIsActive)\n\tassert.False(t, r.primaryTimeout.IsZero())\n\t// Request an address (should be IPv4 from secondary)\n\ta3_v4 := r.AssignAnyAddress(3, nil)\n\tassert.NotNil(t, a3_v4)\n\tassert.Equal(t, V4, a3_v4.IPVersion)\n\tassert.False(t, r.primaryIsActive)\n\t// Give back IPv6 address inside timeout (no change)\n\tassert.True(t, r.GiveBack(a2, true))\n\tassert.False(t, r.primaryIsActive)\n\tassert.False(t, r.primaryTimeout.IsZero())\n\t// Accelerate timeout\n\tr.primaryTimeout = time.Now().Add(-time.Minute)\n\t// Return IPv6 address\n\tassert.True(t, r.GiveBack(a1, true))\n\tassert.True(t, r.primaryIsActive)\n\t// Returning an IPv4 address after primary is active shouldn't change primary\n\t// even with a connectivity error\n\tassert.True(t, r.GiveBack(a3_v4, true))\n\tassert.True(t, r.primaryIsActive)\n}\n"
  },
  {
    "path": "edgediscovery/allregions/regions.go",
    "content": "package allregions\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\n\t\"github.com/rs/zerolog\"\n)\n\n// Regions stores Cloudflare edge network IPs, partitioned into two regions.\n// This is NOT thread-safe. Users of this package should use it with a lock.\ntype Regions struct {\n\tregion1 Region\n\tregion2 Region\n}\n\n// ------------------------------------\n// Constructors\n// ------------------------------------\n\n// ResolveEdge resolves the Cloudflare edge, returning all regions discovered.\nfunc ResolveEdge(log *zerolog.Logger, region string, overrideIPVersion ConfigIPVersion) (*Regions, error) {\n\tedgeAddrs, err := edgeDiscovery(log, getRegionalServiceName(region))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(edgeAddrs) < 2 {\n\t\treturn nil, fmt.Errorf(\"expected at least 2 Cloudflare Regions regions, but SRV only returned %v\", len(edgeAddrs))\n\t}\n\treturn &Regions{\n\t\tregion1: NewRegion(edgeAddrs[0], overrideIPVersion),\n\t\tregion2: NewRegion(edgeAddrs[1], overrideIPVersion),\n\t}, nil\n}\n\n// StaticEdge creates a list of edge addresses from the list of hostnames.\n// Mainly used for testing connectivity.\nfunc StaticEdge(hostnames []string, log *zerolog.Logger) (*Regions, error) {\n\tresolved := ResolveAddrs(hostnames, log)\n\tif len(resolved) == 0 {\n\t\treturn nil, fmt.Errorf(\"failed to resolve any edge address\")\n\t}\n\treturn NewNoResolve(resolved), nil\n}\n\n// NewNoResolve doesn't resolve the edge. Instead it just uses the given addresses.\n// You probably only need this for testing.\nfunc NewNoResolve(addrs []*EdgeAddr) *Regions {\n\tregion1 := make([]*EdgeAddr, 0)\n\tregion2 := make([]*EdgeAddr, 0)\n\tfor i, v := range addrs {\n\t\tif i%2 == 0 {\n\t\t\tregion1 = append(region1, v)\n\t\t} else {\n\t\t\tregion2 = append(region2, v)\n\t\t}\n\t}\n\n\treturn &Regions{\n\t\tregion1: NewRegion(region1, Auto),\n\t\tregion2: NewRegion(region2, Auto),\n\t}\n}\n\n// ------------------------------------\n// Methods\n// ------------------------------------\n\n// GetAnyAddress returns an arbitrary address from the larger region.\nfunc (rs *Regions) GetAnyAddress() *EdgeAddr {\n\tif addr := rs.region1.GetAnyAddress(); addr != nil {\n\t\treturn addr\n\t}\n\treturn rs.region2.GetAnyAddress()\n}\n\n// AddrUsedBy finds the address used by the given connection.\n// Returns nil if the connection isn't using an address.\nfunc (rs *Regions) AddrUsedBy(connID int) *EdgeAddr {\n\tif addr := rs.region1.AddrUsedBy(connID); addr != nil {\n\t\treturn addr\n\t}\n\treturn rs.region2.AddrUsedBy(connID)\n}\n\n// GetUnusedAddr gets an unused addr from the edge, excluding the given addr. Prefer to use addresses\n// evenly across both regions.\nfunc (rs *Regions) GetUnusedAddr(excluding *EdgeAddr, connID int) *EdgeAddr {\n\t// If both regions have the same number of available addrs, lets randomise which one\n\t// we pick. The rest of this algorithm will continue to make sure we always use addresses\n\t// evenly across both regions.\n\tif rs.region1.AvailableAddrs() == rs.region2.AvailableAddrs() {\n\t\tregions := []Region{rs.region1, rs.region2}\n\t\tfirstChoice := rand.Intn(2)\n\t\treturn getAddrs(excluding, connID, &regions[firstChoice], &regions[1-firstChoice])\n\t}\n\n\tif rs.region1.AvailableAddrs() > rs.region2.AvailableAddrs() {\n\t\treturn getAddrs(excluding, connID, &rs.region1, &rs.region2)\n\t}\n\n\treturn getAddrs(excluding, connID, &rs.region2, &rs.region1)\n}\n\n// getAddrs tries to grab address form `first` region, then `second` region\n// this is an unrolled loop over 2 element array\nfunc getAddrs(excluding *EdgeAddr, connID int, first *Region, second *Region) *EdgeAddr {\n\taddr := first.AssignAnyAddress(connID, excluding)\n\tif addr != nil {\n\t\treturn addr\n\t}\n\taddr = second.AssignAnyAddress(connID, excluding)\n\tif addr != nil {\n\t\treturn addr\n\t}\n\n\treturn nil\n}\n\n// AvailableAddrs returns how many edge addresses aren't used.\nfunc (rs *Regions) AvailableAddrs() int {\n\treturn rs.region1.AvailableAddrs() + rs.region2.AvailableAddrs()\n}\n\n// GiveBack the address so that other connections can use it.\n// Returns true if the address is in this edge.\nfunc (rs *Regions) GiveBack(addr *EdgeAddr, hasConnectivityError bool) bool {\n\tif found := rs.region1.GiveBack(addr, hasConnectivityError); found {\n\t\treturn found\n\t}\n\treturn rs.region2.GiveBack(addr, hasConnectivityError)\n}\n\n// Return regionalized service name if `region` isn't empty, otherwise return the global service name for origintunneld\nfunc getRegionalServiceName(region string) string {\n\tif region != \"\" {\n\t\treturn region + \"-\" + srvService // Example: `us-v2-origintunneld`\n\t}\n\n\treturn srvService // Global service is just `v2-origintunneld`\n}\n"
  },
  {
    "path": "edgediscovery/allregions/regions_test.go",
    "content": "package allregions\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc makeRegions(addrs []*EdgeAddr, mode ConfigIPVersion) Regions {\n\tr1addrs := make([]*EdgeAddr, 0)\n\tr2addrs := make([]*EdgeAddr, 0)\n\tfor i, addr := range addrs {\n\t\tif i%2 == 0 {\n\t\t\tr1addrs = append(r1addrs, addr)\n\t\t} else {\n\t\t\tr2addrs = append(r2addrs, addr)\n\t\t}\n\t}\n\tr1 := NewRegion(r1addrs, mode)\n\tr2 := NewRegion(r2addrs, mode)\n\treturn Regions{region1: r1, region2: r2}\n}\n\nfunc TestRegions_AddrUsedBy(t *testing.T) {\n\ttests := []struct {\n\t\tname  string\n\t\taddrs []*EdgeAddr\n\t\tmode  ConfigIPVersion\n\t}{\n\t\t{\n\t\t\tname:  \"IPv4 addresses with IPv4Only\",\n\t\t\taddrs: v4Addrs,\n\t\t\tmode:  IPv4Only,\n\t\t},\n\t\t{\n\t\t\tname:  \"IPv6 addresses with IPv6Only\",\n\t\t\taddrs: v6Addrs,\n\t\t\tmode:  IPv6Only,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\trs := makeRegions(tt.addrs, tt.mode)\n\t\t\taddr1 := rs.GetUnusedAddr(nil, 1)\n\t\t\tassert.Equal(t, addr1, rs.AddrUsedBy(1))\n\t\t\taddr2 := rs.GetUnusedAddr(nil, 2)\n\t\t\tassert.Equal(t, addr2, rs.AddrUsedBy(2))\n\t\t\taddr3 := rs.GetUnusedAddr(nil, 3)\n\t\t\tassert.Equal(t, addr3, rs.AddrUsedBy(3))\n\t\t})\n\t}\n}\n\nfunc TestRegions_Giveback_Region1(t *testing.T) {\n\ttests := []struct {\n\t\tname  string\n\t\taddrs []*EdgeAddr\n\t\tmode  ConfigIPVersion\n\t}{\n\t\t{\n\t\t\tname:  \"IPv4 addresses with IPv4Only\",\n\t\t\taddrs: v4Addrs,\n\t\t\tmode:  IPv4Only,\n\t\t},\n\t\t{\n\t\t\tname:  \"IPv6 addresses with IPv6Only\",\n\t\t\taddrs: v6Addrs,\n\t\t\tmode:  IPv6Only,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\trs := makeRegions(tt.addrs, tt.mode)\n\t\t\taddr := rs.region1.AssignAnyAddress(0, nil)\n\t\t\trs.region1.AssignAnyAddress(1, nil)\n\t\t\trs.region2.AssignAnyAddress(2, nil)\n\t\t\trs.region2.AssignAnyAddress(3, nil)\n\n\t\t\tassert.Equal(t, 0, rs.AvailableAddrs())\n\n\t\t\trs.GiveBack(addr, false)\n\t\t\tassert.Equal(t, addr, rs.GetUnusedAddr(nil, 0))\n\t\t})\n\t}\n}\n\nfunc TestRegions_Giveback_Region2(t *testing.T) {\n\ttests := []struct {\n\t\tname  string\n\t\taddrs []*EdgeAddr\n\t\tmode  ConfigIPVersion\n\t}{\n\t\t{\n\t\t\tname:  \"IPv4 addresses with IPv4Only\",\n\t\t\taddrs: v4Addrs,\n\t\t\tmode:  IPv4Only,\n\t\t},\n\t\t{\n\t\t\tname:  \"IPv6 addresses with IPv6Only\",\n\t\t\taddrs: v6Addrs,\n\t\t\tmode:  IPv6Only,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\trs := makeRegions(tt.addrs, tt.mode)\n\t\t\trs.region1.AssignAnyAddress(0, nil)\n\t\t\trs.region1.AssignAnyAddress(1, nil)\n\t\t\taddr := rs.region2.AssignAnyAddress(2, nil)\n\t\t\trs.region2.AssignAnyAddress(3, nil)\n\n\t\t\tassert.Equal(t, 0, rs.AvailableAddrs())\n\n\t\t\trs.GiveBack(addr, false)\n\t\t\tassert.Equal(t, addr, rs.GetUnusedAddr(nil, 2))\n\t\t})\n\t}\n}\n\nfunc TestRegions_GetUnusedAddr_OneAddrLeft(t *testing.T) {\n\ttests := []struct {\n\t\tname  string\n\t\taddrs []*EdgeAddr\n\t\tmode  ConfigIPVersion\n\t}{\n\t\t{\n\t\t\tname:  \"IPv4 addresses with IPv4Only\",\n\t\t\taddrs: v4Addrs,\n\t\t\tmode:  IPv4Only,\n\t\t},\n\t\t{\n\t\t\tname:  \"IPv6 addresses with IPv6Only\",\n\t\t\taddrs: v6Addrs,\n\t\t\tmode:  IPv6Only,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\trs := makeRegions(tt.addrs, tt.mode)\n\t\t\trs.region1.AssignAnyAddress(0, nil)\n\t\t\trs.region1.AssignAnyAddress(1, nil)\n\t\t\trs.region2.AssignAnyAddress(2, nil)\n\t\t\taddr := rs.region2.active.GetUnusedIP(nil)\n\n\t\t\tassert.Equal(t, 1, rs.AvailableAddrs())\n\t\t\tassert.Equal(t, addr, rs.GetUnusedAddr(nil, 3))\n\t\t})\n\t}\n}\n\nfunc TestRegions_GetUnusedAddr_Excluding_Region1(t *testing.T) {\n\ttests := []struct {\n\t\tname  string\n\t\taddrs []*EdgeAddr\n\t\tmode  ConfigIPVersion\n\t}{\n\t\t{\n\t\t\tname:  \"IPv4 addresses with IPv4Only\",\n\t\t\taddrs: v4Addrs,\n\t\t\tmode:  IPv4Only,\n\t\t},\n\t\t{\n\t\t\tname:  \"IPv6 addresses with IPv6Only\",\n\t\t\taddrs: v6Addrs,\n\t\t\tmode:  IPv6Only,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\trs := makeRegions(tt.addrs, tt.mode)\n\n\t\t\trs.region1.AssignAnyAddress(0, nil)\n\t\t\trs.region1.AssignAnyAddress(1, nil)\n\t\t\taddr := rs.region2.active.GetUnusedIP(nil)\n\t\t\ta2 := rs.region2.active.GetUnusedIP(addr)\n\n\t\t\tassert.Equal(t, 2, rs.AvailableAddrs())\n\t\t\tassert.Equal(t, addr, rs.GetUnusedAddr(a2, 3))\n\t\t})\n\t}\n}\n\nfunc TestRegions_GetUnusedAddr_Excluding_Region2(t *testing.T) {\n\ttests := []struct {\n\t\tname  string\n\t\taddrs []*EdgeAddr\n\t\tmode  ConfigIPVersion\n\t}{\n\t\t{\n\t\t\tname:  \"IPv4 addresses with IPv4Only\",\n\t\t\taddrs: v4Addrs,\n\t\t\tmode:  IPv4Only,\n\t\t},\n\t\t{\n\t\t\tname:  \"IPv6 addresses with IPv6Only\",\n\t\t\taddrs: v6Addrs,\n\t\t\tmode:  IPv6Only,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\trs := makeRegions(tt.addrs, tt.mode)\n\n\t\t\trs.region2.AssignAnyAddress(0, nil)\n\t\t\trs.region2.AssignAnyAddress(1, nil)\n\t\t\taddr := rs.region1.active.GetUnusedIP(nil)\n\t\t\ta2 := rs.region1.active.GetUnusedIP(addr)\n\n\t\t\tassert.Equal(t, 2, rs.AvailableAddrs())\n\t\t\tassert.Equal(t, addr, rs.GetUnusedAddr(a2, 1))\n\t\t})\n\t}\n}\n\nfunc TestNewNoResolveBalancesRegions(t *testing.T) {\n\ttype args struct {\n\t\taddrs []*EdgeAddr\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t}{\n\t\t{\n\t\t\tname: \"one address\",\n\t\t\targs: args{addrs: []*EdgeAddr{&addr0}},\n\t\t},\n\t\t{\n\t\t\tname: \"two addresses\",\n\t\t\targs: args{addrs: []*EdgeAddr{&addr0, &addr1}},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tregions := NewNoResolve(tt.args.addrs)\n\t\t\tRegionsIsBalanced(t, regions)\n\t\t})\n\t}\n}\n\nfunc TestGetRegionalServiceName(t *testing.T) {\n\t// Empty region should just go to origintunneld\n\tglobalServiceName := getRegionalServiceName(\"\")\n\tassert.Equal(t, srvService, globalServiceName)\n\n\t// Non-empty region should go to the regional origintunneld variant\n\tfor _, region := range []string{\"us\", \"pt\", \"am\"} {\n\t\tregionalServiceName := getRegionalServiceName(region)\n\t\tassert.Equal(t, region+\"-\"+srvService, regionalServiceName)\n\t}\n}\n\nfunc RegionsIsBalanced(t *testing.T, rs *Regions) {\n\tdelta := rs.region1.AvailableAddrs() - rs.region2.AvailableAddrs()\n\tassert.True(t, abs(delta) <= 1)\n}\n\nfunc abs(x int) int {\n\tif x >= 0 {\n\t\treturn x\n\t}\n\treturn -x\n}\n"
  },
  {
    "path": "edgediscovery/allregions/usedby.go",
    "content": "package allregions\n\ntype UsedBy struct {\n\tConnID int\n\tUsed   bool\n}\n\nfunc InUse(connID int) UsedBy {\n\treturn UsedBy{ConnID: connID, Used: true}\n}\n\nfunc Unused() UsedBy {\n\treturn UsedBy{}\n}\n"
  },
  {
    "path": "edgediscovery/dial.go",
    "content": "package edgediscovery\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/pkg/errors\"\n)\n\n// DialEdge makes a TLS connection to a Cloudflare edge node\nfunc DialEdge(\n\tctx context.Context,\n\ttimeout time.Duration,\n\ttlsConfig *tls.Config,\n\tedgeTCPAddr *net.TCPAddr,\n\tlocalIP net.IP,\n) (net.Conn, error) {\n\t// Inherit from parent context so we can cancel (Ctrl-C) while dialing\n\tdialCtx, dialCancel := context.WithTimeout(ctx, timeout)\n\tdefer dialCancel()\n\n\tdialer := net.Dialer{}\n\tif localIP != nil {\n\t\tdialer.LocalAddr = &net.TCPAddr{IP: localIP, Port: 0}\n\t}\n\tedgeConn, err := dialer.DialContext(dialCtx, \"tcp\", edgeTCPAddr.String())\n\tif err != nil {\n\t\treturn nil, newDialError(err, \"DialContext error\")\n\t}\n\n\ttlsEdgeConn := tls.Client(edgeConn, tlsConfig)\n\ttlsEdgeConn.SetDeadline(time.Now().Add(timeout))\n\n\tif err = tlsEdgeConn.Handshake(); err != nil {\n\t\treturn nil, newDialError(err, \"TLS handshake with edge error\")\n\t}\n\t// clear the deadline on the conn; http2 has its own timeouts\n\ttlsEdgeConn.SetDeadline(time.Time{})\n\treturn tlsEdgeConn, nil\n}\n\n// DialError is an error returned from DialEdge\ntype DialError struct {\n\tcause error\n}\n\nfunc newDialError(err error, message string) error {\n\treturn DialError{cause: errors.Wrap(err, message)}\n}\n\nfunc (e DialError) Error() string {\n\treturn e.cause.Error()\n}\n\nfunc (e DialError) Cause() error {\n\treturn e.cause\n}\n"
  },
  {
    "path": "edgediscovery/edgediscovery.go",
    "content": "package edgediscovery\n\nimport (\n\t\"sync\"\n\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/edgediscovery/allregions\"\n\t\"github.com/cloudflare/cloudflared/management\"\n)\n\nconst (\n\tLogFieldConnIndex = \"connIndex\"\n\tLogFieldIPAddress = \"ip\"\n)\n\nvar errNoAddressesLeft = ErrNoAddressesLeft{}\n\ntype ErrNoAddressesLeft struct{}\n\nfunc (e ErrNoAddressesLeft) Error() string {\n\treturn \"there are no free edge addresses left to resolve to\"\n}\n\n// Edge finds addresses on the Cloudflare edge and hands them out to connections.\ntype Edge struct {\n\tregions *allregions.Regions\n\tsync.Mutex\n\tlog *zerolog.Logger\n}\n\n// ------------------------------------\n// Constructors\n// ------------------------------------\n\n// ResolveEdge runs the initial discovery of the Cloudflare edge, finding Addrs that can be allocated\n// to connections.\nfunc ResolveEdge(log *zerolog.Logger, region string, edgeIpVersion allregions.ConfigIPVersion) (*Edge, error) {\n\tregions, err := allregions.ResolveEdge(log, region, edgeIpVersion)\n\tif err != nil {\n\t\treturn new(Edge), err\n\t}\n\treturn &Edge{\n\t\tlog:     log,\n\t\tregions: regions,\n\t}, nil\n}\n\n// StaticEdge creates a list of edge addresses from the list of hostnames. Mainly used for testing connectivity.\nfunc StaticEdge(log *zerolog.Logger, hostnames []string) (*Edge, error) {\n\tregions, err := allregions.StaticEdge(hostnames, log)\n\tif err != nil {\n\t\treturn new(Edge), err\n\t}\n\treturn &Edge{\n\t\tlog:     log,\n\t\tregions: regions,\n\t}, nil\n}\n\n// ------------------------------------\n// Methods\n// ------------------------------------\n\n// GetAddrForRPC gives this connection an edge Addr.\nfunc (ed *Edge) GetAddrForRPC() (*allregions.EdgeAddr, error) {\n\ted.Lock()\n\tdefer ed.Unlock()\n\taddr := ed.regions.GetAnyAddress()\n\tif addr == nil {\n\t\treturn nil, errNoAddressesLeft\n\t}\n\treturn addr, nil\n}\n\n// GetAddr gives this proxy connection an edge Addr. Prefer Addrs this connection has already used.\nfunc (ed *Edge) GetAddr(connIndex int) (*allregions.EdgeAddr, error) {\n\tlog := ed.log.With().\n\t\tInt(LogFieldConnIndex, connIndex).\n\t\tInt(management.EventTypeKey, int(management.Cloudflared)).\n\t\tLogger()\n\ted.Lock()\n\tdefer ed.Unlock()\n\n\t// If this connection has already used an edge addr, return it.\n\tif addr := ed.regions.AddrUsedBy(connIndex); addr != nil {\n\t\tlog.Debug().IPAddr(LogFieldIPAddress, addr.UDP.IP).Msg(\"edge discovery: returning same edge address back to pool\")\n\t\treturn addr, nil\n\t}\n\n\t// Otherwise, give it an unused one\n\taddr := ed.regions.GetUnusedAddr(nil, connIndex)\n\tif addr == nil {\n\t\tlog.Debug().Msg(\"edge discovery: no addresses left in pool to give proxy connection\")\n\t\treturn nil, errNoAddressesLeft\n\t}\n\tlog.Debug().IPAddr(LogFieldIPAddress, addr.UDP.IP).Msg(\"edge discovery: giving new address to connection\")\n\treturn addr, nil\n}\n\n// GetDifferentAddr gives back the proxy connection's edge Addr and uses a new one.\nfunc (ed *Edge) GetDifferentAddr(connIndex int, hasConnectivityError bool) (*allregions.EdgeAddr, error) {\n\tlog := ed.log.With().\n\t\tInt(LogFieldConnIndex, connIndex).\n\t\tInt(management.EventTypeKey, int(management.Cloudflared)).\n\t\tLogger()\n\ted.Lock()\n\tdefer ed.Unlock()\n\n\toldAddr := ed.regions.AddrUsedBy(connIndex)\n\tif oldAddr != nil {\n\t\ted.regions.GiveBack(oldAddr, hasConnectivityError)\n\t}\n\taddr := ed.regions.GetUnusedAddr(oldAddr, connIndex)\n\tif addr == nil {\n\t\tlog.Debug().Msg(\"edge discovery: no addresses left in pool to give proxy connection\")\n\t\t// note: if oldAddr were not nil, it will become available on the next iteration\n\t\treturn nil, errNoAddressesLeft\n\t}\n\tlog.Debug().\n\t\tIPAddr(LogFieldIPAddress, addr.UDP.IP).\n\t\tInt(\"available\", ed.regions.AvailableAddrs()).\n\t\tMsg(\"edge discovery: giving new address to connection\")\n\treturn addr, nil\n}\n\n// AvailableAddrs returns how many unused addresses there are left.\nfunc (ed *Edge) AvailableAddrs() int {\n\ted.Lock()\n\tdefer ed.Unlock()\n\treturn ed.regions.AvailableAddrs()\n}\n\n// GiveBack the address so that other connections can use it.\n// Returns true if the address is in this edge.\nfunc (ed *Edge) GiveBack(addr *allregions.EdgeAddr, hasConnectivityError bool) bool {\n\ted.Lock()\n\tdefer ed.Unlock()\n\ted.log.Debug().\n\t\tInt(management.EventTypeKey, int(management.Cloudflared)).\n\t\tIPAddr(LogFieldIPAddress, addr.UDP.IP).\n\t\tMsg(\"edge discovery: gave back address to the pool\")\n\treturn ed.regions.GiveBack(addr, hasConnectivityError)\n}\n"
  },
  {
    "path": "edgediscovery/edgediscovery_test.go",
    "content": "package edgediscovery\n\nimport (\n\t\"net\"\n\t\"testing\"\n\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/cloudflare/cloudflared/edgediscovery/allregions\"\n)\n\nvar (\n\ttestLogger = zerolog.Nop()\n\tv4Addrs    = []*allregions.EdgeAddr{&addr0, &addr1, &addr2, &addr3}\n\tv6Addrs    = []*allregions.EdgeAddr{&addr4, &addr5, &addr6, &addr7}\n\taddr0      = allregions.EdgeAddr{\n\t\tTCP: &net.TCPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.0\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tUDP: &net.UDPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.0\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tIPVersion: allregions.V4,\n\t}\n\taddr1 = allregions.EdgeAddr{\n\t\tTCP: &net.TCPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.1\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tUDP: &net.UDPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.1\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tIPVersion: allregions.V4,\n\t}\n\taddr2 = allregions.EdgeAddr{\n\t\tTCP: &net.TCPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.2\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tUDP: &net.UDPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.2\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tIPVersion: allregions.V4,\n\t}\n\taddr3 = allregions.EdgeAddr{\n\t\tTCP: &net.TCPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.3\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tUDP: &net.UDPAddr{\n\t\t\tIP:   net.ParseIP(\"123.4.5.3\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tIPVersion: allregions.V4,\n\t}\n\taddr4 = allregions.EdgeAddr{\n\t\tTCP: &net.TCPAddr{\n\t\t\tIP:   net.ParseIP(\"2606:4700:a0::1\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tUDP: &net.UDPAddr{\n\t\t\tIP:   net.ParseIP(\"2606:4700:a0::1\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tIPVersion: allregions.V6,\n\t}\n\taddr5 = allregions.EdgeAddr{\n\t\tTCP: &net.TCPAddr{\n\t\t\tIP:   net.ParseIP(\"2606:4700:a0::2\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tUDP: &net.UDPAddr{\n\t\t\tIP:   net.ParseIP(\"2606:4700:a0::2\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tIPVersion: allregions.V6,\n\t}\n\taddr6 = allregions.EdgeAddr{\n\t\tTCP: &net.TCPAddr{\n\t\t\tIP:   net.ParseIP(\"2606:4700:a0::3\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tUDP: &net.UDPAddr{\n\t\t\tIP:   net.ParseIP(\"2606:4700:a0::3\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tIPVersion: allregions.V6,\n\t}\n\taddr7 = allregions.EdgeAddr{\n\t\tTCP: &net.TCPAddr{\n\t\t\tIP:   net.ParseIP(\"2606:4700:a0::4\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tUDP: &net.UDPAddr{\n\t\t\tIP:   net.ParseIP(\"2606:4700:a0::4\"),\n\t\t\tPort: 8000,\n\t\t\tZone: \"\",\n\t\t},\n\t\tIPVersion: allregions.V6,\n\t}\n)\n\nfunc TestGiveBack(t *testing.T) {\n\tedge := MockEdge(&testLogger, []*allregions.EdgeAddr{&addr0, &addr1, &addr2, &addr3})\n\n\t// Give this connection an address\n\tassert.Equal(t, 4, edge.AvailableAddrs())\n\tconst connID = 0\n\taddr, err := edge.GetAddr(connID)\n\tassert.NoError(t, err)\n\tassert.NotNil(t, addr)\n\tassert.Equal(t, 3, edge.AvailableAddrs())\n\n\t// Get it back\n\tedge.GiveBack(addr, false)\n\tassert.Equal(t, 4, edge.AvailableAddrs())\n}\n\nfunc TestRPCAndProxyShareSingleEdgeIP(t *testing.T) {\n\t// Make an edge with a single IP\n\tedge := MockEdge(&testLogger, []*allregions.EdgeAddr{&addr0})\n\ttunnelConnID := 0\n\n\t// Use the IP for a tunnel\n\taddrTunnel, err := edge.GetAddr(tunnelConnID)\n\tassert.NoError(t, err)\n\n\t// Ensure the IP can be used for RPC too\n\taddrRPC, err := edge.GetAddrForRPC()\n\tassert.NoError(t, err)\n\tassert.Equal(t, addrTunnel, addrRPC)\n}\n\nfunc TestGetAddrForRPC(t *testing.T) {\n\tedge := MockEdge(&testLogger, []*allregions.EdgeAddr{&addr0, &addr1, &addr2, &addr3})\n\n\t// Get a connection\n\tassert.Equal(t, 4, edge.AvailableAddrs())\n\taddr, err := edge.GetAddrForRPC()\n\tassert.NoError(t, err)\n\tassert.NotNil(t, addr)\n\n\t// Using an address for RPC shouldn't consume it\n\tassert.Equal(t, 4, edge.AvailableAddrs())\n\n\t// Get it back\n\tedge.GiveBack(addr, false)\n\tassert.Equal(t, 4, edge.AvailableAddrs())\n}\n\nfunc TestOnePerRegion(t *testing.T) {\n\t// Make an edge with only one address\n\tedge := MockEdge(&testLogger, []*allregions.EdgeAddr{&addr0, &addr1})\n\n\t// Use the only address\n\tconst connID = 0\n\ta1, err := edge.GetAddr(connID)\n\tassert.NoError(t, err)\n\tassert.NotNil(t, a1)\n\n\t// if the first address is bad, get the second one\n\ta2, err := edge.GetDifferentAddr(connID, false)\n\tassert.NoError(t, err)\n\tassert.NotNil(t, a2)\n\tassert.NotEqual(t, a1, a2)\n\n\t// now that second one is bad, get the first one again\n\ta3, err := edge.GetDifferentAddr(connID, false)\n\tassert.NoError(t, err)\n\tassert.Equal(t, a1, a3)\n}\n\nfunc TestOnlyOneAddrLeft(t *testing.T) {\n\t// Make an edge with only one address\n\tedge := MockEdge(&testLogger, []*allregions.EdgeAddr{&addr0})\n\n\t// Use the only address\n\tconst connID = 0\n\taddr, err := edge.GetAddr(connID)\n\tassert.NoError(t, err)\n\tassert.NotNil(t, addr)\n\n\t// If that edge address is \"bad\", there's no alternative address.\n\t_, err = edge.GetDifferentAddr(connID, false)\n\tassert.Error(t, err)\n\n\t// previously bad address should become available again on next iteration.\n\taddr, err = edge.GetDifferentAddr(connID, false)\n\tassert.NoError(t, err)\n\tassert.NotNil(t, addr)\n}\n\nfunc TestNoAddrsLeft(t *testing.T) {\n\t// Make an edge with no addresses\n\tedge := MockEdge(&testLogger, []*allregions.EdgeAddr{})\n\n\t_, err := edge.GetAddr(2)\n\tassert.Error(t, err)\n\t_, err = edge.GetAddrForRPC()\n\tassert.Error(t, err)\n}\n\nfunc TestGetAddr(t *testing.T) {\n\tedge := MockEdge(&testLogger, []*allregions.EdgeAddr{&addr0, &addr1, &addr2, &addr3})\n\n\t// Give this connection an address\n\tconst connID = 0\n\taddr, err := edge.GetAddr(connID)\n\tassert.NoError(t, err)\n\tassert.NotNil(t, addr)\n\n\t// If the same connection requests another address, it should get the same one.\n\taddr2, err := edge.GetAddr(connID)\n\tassert.NoError(t, err)\n\tassert.Equal(t, addr, addr2)\n}\n\nfunc TestGetDifferentAddr(t *testing.T) {\n\tedge := MockEdge(&testLogger, []*allregions.EdgeAddr{&addr0, &addr1, &addr2, &addr3})\n\n\t// Give this connection an address\n\tassert.Equal(t, 4, edge.AvailableAddrs())\n\tconst connID = 0\n\taddr, err := edge.GetAddr(connID)\n\tassert.NoError(t, err)\n\tassert.NotNil(t, addr)\n\tassert.Equal(t, 3, edge.AvailableAddrs())\n\n\t// If the same connection requests another address, it should get the same one.\n\taddr2, err := edge.GetDifferentAddr(connID, false)\n\tassert.NoError(t, err)\n\tassert.NotEqual(t, addr, addr2)\n\tassert.Equal(t, 3, edge.AvailableAddrs())\n}\n\n// MockEdge creates a Cloudflare Edge from arbitrary TCP addresses. Used for testing.\nfunc MockEdge(log *zerolog.Logger, addrs []*allregions.EdgeAddr) *Edge {\n\tregions := allregions.NewNoResolve(addrs)\n\treturn &Edge{\n\t\tlog:     log,\n\t\tregions: regions,\n\t}\n}\n"
  },
  {
    "path": "edgediscovery/mocks_for_test.go",
    "content": "package edgediscovery\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"math/rand\"\n\t\"net\"\n\t\"reflect\"\n\t\"testing/quick\"\n)\n\ntype mockAddrs struct {\n\t// a set of synthetic SRV records\n\taddrMap map[net.SRV][]*net.TCPAddr\n\t// the total number of addresses, aggregated across addrMap.\n\t// For the convenience of test code that would otherwise have to compute\n\t// this by hand every time.\n\tnumAddrs int\n}\n\nfunc newMockAddrs(port uint16, numRegions uint8, numAddrsPerRegion uint8) mockAddrs {\n\taddrMap := make(map[net.SRV][]*net.TCPAddr)\n\tnumAddrs := 0\n\n\tfor r := uint8(0); r < numRegions; r++ {\n\t\tvar (\n\t\t\tsrv   = net.SRV{Target: fmt.Sprintf(\"test-region-%v.example.com\", r), Port: port}\n\t\t\taddrs []*net.TCPAddr\n\t\t)\n\t\tfor a := uint8(0); a < numAddrsPerRegion; a++ {\n\t\t\taddrs = append(addrs, &net.TCPAddr{\n\t\t\t\tIP:   net.ParseIP(fmt.Sprintf(\"10.0.%v.%v\", r, a)),\n\t\t\t\tPort: int(port),\n\t\t\t})\n\t\t}\n\t\taddrMap[srv] = addrs\n\t\tnumAddrs += len(addrs)\n\t}\n\treturn mockAddrs{addrMap: addrMap, numAddrs: numAddrs}\n}\n\nvar _ quick.Generator = mockAddrs{}\n\nfunc (mockAddrs) Generate(rand *rand.Rand, size int) reflect.Value {\n\tport := uint16(rand.Intn(math.MaxUint16))\n\tnumRegions := uint8(1 + rand.Intn(10))\n\tnumAddrsPerRegion := uint8(1 + rand.Intn(32))\n\tresult := newMockAddrs(port, numRegions, numAddrsPerRegion)\n\treturn reflect.ValueOf(result)\n}\n\n// Returns a function compatible with net.LookupSRV that will return the SRV\n// records from mockAddrs.\nfunc mockNetLookupSRV(\n\tm mockAddrs,\n) func(service, proto, name string) (cname string, addrs []*net.SRV, err error) {\n\tvar addrs []*net.SRV\n\tfor k := range m.addrMap {\n\t\taddr := k\n\t\taddrs = append(addrs, &addr)\n\t\t// We can't just do\n\t\t//   addrs = append(addrs, &k)\n\t\t// `k` will be reused by subsequent loop iterations,\n\t\t// so all the copies of `&k` would point to the same location.\n\t}\n\treturn func(_, _, _ string) (string, []*net.SRV, error) {\n\t\treturn \"\", addrs, nil\n\t}\n}\n\n// Returns a function compatible with net.LookupIP that translates the SRV records\n// from mockAddrs into IP addresses, based on the TCP addresses in mockAddrs.\nfunc mockNetLookupIP(\n\tm mockAddrs,\n) func(host string) ([]net.IP, error) {\n\treturn func(host string) ([]net.IP, error) {\n\t\tfor srv, tcpAddrs := range m.addrMap {\n\t\t\tif srv.Target != host {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tresult := make([]net.IP, len(tcpAddrs))\n\t\t\tfor i, tcpAddr := range tcpAddrs {\n\t\t\t\tresult[i] = tcpAddr.IP\n\t\t\t}\n\t\t\treturn result, nil\n\t\t}\n\t\treturn nil, fmt.Errorf(\"No IPs for %v\", host)\n\t}\n}\n\ntype mockEdgeServiceDiscoverer struct {\n}\n\nfunc (mr *mockEdgeServiceDiscoverer) Addr() (*net.TCPAddr, error) {\n\treturn &net.TCPAddr{\n\t\tIP:   net.ParseIP(\"127.0.0.1\"),\n\t\tPort: 63102,\n\t}, nil\n}\n\nfunc (mr *mockEdgeServiceDiscoverer) AnyAddr() (*net.TCPAddr, error) {\n\treturn &net.TCPAddr{\n\t\tIP:   net.ParseIP(\"127.0.0.1\"),\n\t\tPort: 63102,\n\t}, nil\n}\n\nfunc (mr *mockEdgeServiceDiscoverer) ReplaceAddr(addr *net.TCPAddr) {}\n\nfunc (mr *mockEdgeServiceDiscoverer) MarkAddrBad(addr *net.TCPAddr) {}\n\nfunc (mr *mockEdgeServiceDiscoverer) AvailableAddrs() int {\n\treturn 1\n}\n\nfunc (mr *mockEdgeServiceDiscoverer) Refresh() error {\n\treturn nil\n}\n"
  },
  {
    "path": "edgediscovery/protocol.go",
    "content": "package edgediscovery\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net\"\n\t\"strings\"\n)\n\nconst (\n\tprotocolRecord = \"protocol-v2.argotunnel.com\"\n)\n\nvar (\n\terrNoProtocolRecord = fmt.Errorf(\"No TXT record found for %s to determine connection protocol\", protocolRecord)\n)\n\ntype PercentageFetcher func() (ProtocolPercents, error)\n\n// ProtocolPercent represents a single Protocol Percentage combination.\ntype ProtocolPercent struct {\n\tProtocol   string `json:\"protocol\"`\n\tPercentage int32  `json:\"percentage\"`\n}\n\n// ProtocolPercents represents the preferred distribution ratio of protocols when protocol isn't specified.\ntype ProtocolPercents []ProtocolPercent\n\n// GetPercentage returns the threshold percentage of a single protocol.\nfunc (p ProtocolPercents) GetPercentage(protocol string) int32 {\n\tfor _, protocolPercent := range p {\n\t\tif strings.ToLower(protocolPercent.Protocol) == strings.ToLower(protocol) {\n\t\t\treturn protocolPercent.Percentage\n\t\t}\n\t}\n\treturn 0\n}\n\n// ProtocolPercentage returns the ratio of protocols and a specification ratio for their selection.\nfunc ProtocolPercentage() (ProtocolPercents, error) {\n\trecords, err := net.LookupTXT(protocolRecord)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(records) == 0 {\n\t\treturn nil, errNoProtocolRecord\n\t}\n\n\tvar protocolsWithPercent ProtocolPercents\n\terr = json.Unmarshal([]byte(records[0]), &protocolsWithPercent)\n\treturn protocolsWithPercent, err\n}\n"
  },
  {
    "path": "edgediscovery/protocol_test.go",
    "content": "package edgediscovery\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestProtocolPercentage(t *testing.T) {\n\t_, err := ProtocolPercentage()\n\tassert.NoError(t, err)\n}\n"
  },
  {
    "path": "features/features.go",
    "content": "package features\n\nimport \"slices\"\n\nconst (\n\tFeatureSerializedHeaders = \"serialized_headers\"\n\tFeatureQuickReconnects   = \"quick_reconnects\"\n\tFeatureAllowRemoteConfig = \"allow_remote_config\"\n\tFeatureDatagramV2        = \"support_datagram_v2\"\n\tFeaturePostQuantum       = \"postquantum\"\n\tFeatureQUICSupportEOF    = \"support_quic_eof\"\n\tFeatureManagementLogs    = \"management_logs\"\n\tFeatureDatagramV3_2      = \"support_datagram_v3_2\"\n\n\tDeprecatedFeatureDatagramV3   = \"support_datagram_v3\"   // Deprecated: TUN-9291\n\tDeprecatedFeatureDatagramV3_1 = \"support_datagram_v3_1\" // Deprecated: TUN-9883\n)\n\nvar defaultFeatures = []string{\n\tFeatureAllowRemoteConfig,\n\tFeatureSerializedHeaders,\n\tFeatureDatagramV2,\n\tFeatureQUICSupportEOF,\n\tFeatureManagementLogs,\n}\n\n// List of features that are no longer in-use.\nvar deprecatedFeatures = []string{\n\tDeprecatedFeatureDatagramV3,\n\tDeprecatedFeatureDatagramV3_1,\n}\n\n// Features set by user provided flags\ntype staticFeatures struct {\n\tPostQuantumMode *PostQuantumMode\n}\n\ntype FeatureSnapshot struct {\n\tPostQuantum     PostQuantumMode\n\tDatagramVersion DatagramVersion\n\n\t// We provide the list of features since we need it to send in the ConnectionOptions during connection\n\t// registrations.\n\tFeaturesList []string\n}\n\ntype PostQuantumMode uint8\n\nconst (\n\t// Prefer post quantum, but fallback if connection cannot be established\n\tPostQuantumPrefer PostQuantumMode = iota\n\t// If the user passes the --post-quantum flag, we override\n\t// CurvePreferences to only support hybrid post-quantum key agreements.\n\tPostQuantumStrict\n)\n\ntype DatagramVersion string\n\nconst (\n\t// DatagramV2 is the currently supported datagram protocol for UDP and ICMP packets\n\tDatagramV2 DatagramVersion = FeatureDatagramV2\n\t// DatagramV3 is a new datagram protocol for UDP and ICMP packets. It is not backwards compatible with datagram v2.\n\tDatagramV3 DatagramVersion = FeatureDatagramV3_2\n)\n\n// Remove any duplicate features from the list and remove deprecated features\nfunc dedupAndRemoveFeatures(features []string) []string {\n\t// Convert the slice into a set\n\tset := map[string]bool{}\n\tfor _, feature := range features {\n\t\t// Remove deprecated features from the provided list\n\t\tif slices.Contains(deprecatedFeatures, feature) {\n\t\t\tcontinue\n\t\t}\n\t\tset[feature] = true\n\t}\n\n\t// Convert the set back into a slice\n\tkeys := make([]string, len(set))\n\ti := 0\n\tfor str := range set {\n\t\tkeys[i] = str\n\t\ti++\n\t}\n\treturn keys\n}\n"
  },
  {
    "path": "features/selector.go",
    "content": "package features\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"hash/fnv\"\n\t\"net\"\n\t\"slices\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/rs/zerolog\"\n)\n\nconst (\n\tfeatureSelectorHostname = \"cfd-features.argotunnel.com\"\n\tlookupTimeout           = time.Second * 10\n\tdefaultLookupFreq       = time.Hour\n)\n\n// If the TXT record adds other fields, the umarshal logic will ignore those keys\n// If the TXT record is missing a key, the field will unmarshal to the default Go value\n\ntype featuresRecord struct {\n\tDatagramV3Percentage uint32 `json:\"dv3_2\"`\n\n\t// DatagramV3Percentage int32 `json:\"dv3\"` // Removed in TUN-9291\n\t// DatagramV3Percentage uint32 `json:\"dv3_1\"` // Removed in TUN-9883\n\t// PostQuantumPercentage int32 `json:\"pq\"` // Removed in TUN-7970\n}\n\nfunc NewFeatureSelector(ctx context.Context, accountTag string, cliFeatures []string, pq bool, logger *zerolog.Logger) (FeatureSelector, error) {\n\treturn newFeatureSelector(ctx, accountTag, logger, newDNSResolver(), cliFeatures, pq, defaultLookupFreq)\n}\n\ntype FeatureSelector interface {\n\tSnapshot() FeatureSnapshot\n}\n\n// FeatureSelector determines if this account will try new features; loaded once during startup.\ntype featureSelector struct {\n\taccountHash uint32\n\tlogger      *zerolog.Logger\n\tresolver    resolver\n\n\tstaticFeatures staticFeatures\n\tcliFeatures    []string\n\n\t// lock protects concurrent access to dynamic features\n\tlock           sync.RWMutex\n\tremoteFeatures featuresRecord\n}\n\nfunc newFeatureSelector(ctx context.Context, accountTag string, logger *zerolog.Logger, resolver resolver, cliFeatures []string, pq bool, refreshFreq time.Duration) (*featureSelector, error) {\n\t// Combine default features and user-provided features\n\tvar pqMode *PostQuantumMode\n\tif pq {\n\t\tmode := PostQuantumStrict\n\t\tpqMode = &mode\n\t\tcliFeatures = append(cliFeatures, FeaturePostQuantum)\n\t}\n\tstaticFeatures := staticFeatures{\n\t\tPostQuantumMode: pqMode,\n\t}\n\tselector := &featureSelector{\n\t\taccountHash:    switchThreshold(accountTag),\n\t\tlogger:         logger,\n\t\tresolver:       resolver,\n\t\tstaticFeatures: staticFeatures,\n\t\tcliFeatures:    dedupAndRemoveFeatures(cliFeatures),\n\t}\n\n\t// Load the remote features\n\tif err := selector.refresh(ctx); err != nil {\n\t\tlogger.Err(err).Msg(\"Failed to fetch features, default to disable\")\n\t}\n\n\t// Spin off reloading routine\n\tgo selector.refreshLoop(ctx, refreshFreq)\n\n\treturn selector, nil\n}\n\nfunc (fs *featureSelector) Snapshot() FeatureSnapshot {\n\tfs.lock.RLock()\n\tdefer fs.lock.RUnlock()\n\treturn FeatureSnapshot{\n\t\tPostQuantum:     fs.postQuantumMode(),\n\t\tDatagramVersion: fs.datagramVersion(),\n\t\tFeaturesList:    fs.clientFeatures(),\n\t}\n}\n\nfunc (fs *featureSelector) accountEnabled(percentage uint32) bool {\n\treturn percentage > fs.accountHash\n}\n\nfunc (fs *featureSelector) postQuantumMode() PostQuantumMode {\n\tif fs.staticFeatures.PostQuantumMode != nil {\n\t\treturn *fs.staticFeatures.PostQuantumMode\n\t}\n\n\treturn PostQuantumPrefer\n}\n\nfunc (fs *featureSelector) datagramVersion() DatagramVersion {\n\t// If user provides the feature via the cli, we take it as priority over remote feature evaluation\n\tif slices.Contains(fs.cliFeatures, FeatureDatagramV3_2) {\n\t\treturn DatagramV3\n\t}\n\t// If the user specifies DatagramV2, we also take that over remote\n\tif slices.Contains(fs.cliFeatures, FeatureDatagramV2) {\n\t\treturn DatagramV2\n\t}\n\n\tif fs.accountEnabled(fs.remoteFeatures.DatagramV3Percentage) {\n\t\treturn DatagramV3\n\t}\n\n\treturn DatagramV2\n}\n\n// clientFeatures will return the list of currently available features that cloudflared should provide to the edge.\nfunc (fs *featureSelector) clientFeatures() []string {\n\t// Evaluate any remote features along with static feature list to construct the list of features\n\treturn dedupAndRemoveFeatures(slices.Concat(defaultFeatures, fs.cliFeatures, []string{string(fs.datagramVersion())}))\n}\n\nfunc (fs *featureSelector) refresh(ctx context.Context) error {\n\trecord, err := fs.resolver.lookupRecord(ctx)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar features featuresRecord\n\tif err := json.Unmarshal(record, &features); err != nil {\n\t\treturn err\n\t}\n\n\tfs.lock.Lock()\n\tdefer fs.lock.Unlock()\n\n\tfs.remoteFeatures = features\n\n\treturn nil\n}\n\nfunc (fs *featureSelector) refreshLoop(ctx context.Context, refreshFreq time.Duration) {\n\tticker := time.NewTicker(refreshFreq)\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\tcase <-ticker.C:\n\t\t\terr := fs.refresh(ctx)\n\t\t\tif err != nil {\n\t\t\t\tfs.logger.Err(err).Msg(\"Failed to refresh feature selector\")\n\t\t\t}\n\t\t}\n\t}\n}\n\n// resolver represents an object that can look up featuresRecord\ntype resolver interface {\n\tlookupRecord(ctx context.Context) ([]byte, error)\n}\n\ntype dnsResolver struct {\n\tresolver *net.Resolver\n}\n\nfunc newDNSResolver() *dnsResolver {\n\treturn &dnsResolver{\n\t\tresolver: net.DefaultResolver,\n\t}\n}\n\nfunc (dr *dnsResolver) lookupRecord(ctx context.Context) ([]byte, error) {\n\tctx, cancel := context.WithTimeout(ctx, lookupTimeout)\n\tdefer cancel()\n\n\trecords, err := dr.resolver.LookupTXT(ctx, featureSelectorHostname)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif len(records) == 0 {\n\t\treturn nil, fmt.Errorf(\"No TXT record found for %s to determine which features to opt-in\", featureSelectorHostname)\n\t}\n\n\treturn []byte(records[0]), nil\n}\n\nfunc switchThreshold(accountTag string) uint32 {\n\th := fnv.New32a()\n\t_, _ = h.Write([]byte(accountTag))\n\treturn h.Sum32() % 100\n}\n"
  },
  {
    "path": "features/selector_test.go",
    "content": "package features\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nconst (\n\ttestAccountTag  = \"123456\"\n\ttestAccountHash = 74 // switchThreshold of `accountTag`\n)\n\nfunc TestUnmarshalFeaturesRecord(t *testing.T) {\n\ttests := []struct {\n\t\trecord             []byte\n\t\texpectedPercentage uint32\n\t}{\n\t\t{\n\t\t\trecord:             []byte(`{\"dv3_2\":0}`),\n\t\t\texpectedPercentage: 0,\n\t\t},\n\t\t{\n\t\t\trecord:             []byte(`{\"dv3_2\":39}`),\n\t\t\texpectedPercentage: 39,\n\t\t},\n\t\t{\n\t\t\trecord:             []byte(`{\"dv3_2\":100}`),\n\t\t\texpectedPercentage: 100,\n\t\t},\n\t\t{\n\t\t\trecord: []byte(`{}`), // Unmarshal to default struct if key is not present\n\t\t},\n\t\t{\n\t\t\trecord: []byte(`{\"kyber\":768}`), // Unmarshal to default struct if key is not present\n\t\t},\n\t\t{\n\t\t\trecord: []byte(`{\"pq\": 101,\"dv3\":100,\"dv3_1\":100}`), // Expired keys don't unmarshal to anything\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tvar features featuresRecord\n\t\terr := json.Unmarshal(test.record, &features)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, test.expectedPercentage, features.DatagramV3Percentage, test)\n\t}\n}\n\nfunc TestFeaturePrecedenceEvaluationPostQuantum(t *testing.T) {\n\tlogger := zerolog.Nop()\n\ttests := []struct {\n\t\tname             string\n\t\tcli              bool\n\t\texpectedFeatures []string\n\t\texpectedVersion  PostQuantumMode\n\t}{\n\t\t{\n\t\t\tname:             \"default\",\n\t\t\tcli:              false,\n\t\t\texpectedFeatures: defaultFeatures,\n\t\t\texpectedVersion:  PostQuantumPrefer,\n\t\t},\n\t\t{\n\t\t\tname:             \"user_specified\",\n\t\t\tcli:              true,\n\t\t\texpectedFeatures: dedupAndRemoveFeatures(append(defaultFeatures, FeaturePostQuantum)),\n\t\t\texpectedVersion:  PostQuantumStrict,\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tresolver := &staticResolver{record: featuresRecord{}}\n\t\t\tselector, err := newFeatureSelector(t.Context(), test.name, &logger, resolver, []string{}, test.cli, time.Second)\n\t\t\trequire.NoError(t, err)\n\t\t\tsnapshot := selector.Snapshot()\n\t\t\trequire.ElementsMatch(t, test.expectedFeatures, snapshot.FeaturesList)\n\t\t\trequire.Equal(t, test.expectedVersion, snapshot.PostQuantum)\n\t\t})\n\t}\n}\n\nfunc TestFeaturePrecedenceEvaluationDatagramVersion(t *testing.T) {\n\tlogger := zerolog.Nop()\n\ttests := []struct {\n\t\tname             string\n\t\tcli              []string\n\t\tremote           featuresRecord\n\t\texpectedFeatures []string\n\t\texpectedVersion  DatagramVersion\n\t}{\n\t\t{\n\t\t\tname:             \"default\",\n\t\t\tcli:              []string{},\n\t\t\tremote:           featuresRecord{},\n\t\t\texpectedFeatures: defaultFeatures,\n\t\t\texpectedVersion:  DatagramV2,\n\t\t},\n\t\t{\n\t\t\tname:             \"user_specified_v2\",\n\t\t\tcli:              []string{FeatureDatagramV2},\n\t\t\tremote:           featuresRecord{},\n\t\t\texpectedFeatures: defaultFeatures,\n\t\t\texpectedVersion:  DatagramV2,\n\t\t},\n\t\t{\n\t\t\tname:             \"user_specified_v3\",\n\t\t\tcli:              []string{FeatureDatagramV3_2},\n\t\t\tremote:           featuresRecord{},\n\t\t\texpectedFeatures: dedupAndRemoveFeatures(append(defaultFeatures, FeatureDatagramV3_2)),\n\t\t\texpectedVersion:  FeatureDatagramV3_2,\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tresolver := &staticResolver{record: test.remote}\n\t\t\tselector, err := newFeatureSelector(t.Context(), test.name, &logger, resolver, test.cli, false, time.Second)\n\t\t\trequire.NoError(t, err)\n\t\t\tsnapshot := selector.Snapshot()\n\t\t\trequire.ElementsMatch(t, test.expectedFeatures, snapshot.FeaturesList)\n\t\t\trequire.Equal(t, test.expectedVersion, snapshot.DatagramVersion)\n\t\t})\n\t}\n}\n\nfunc TestDeprecatedFeaturesRemoved(t *testing.T) {\n\tlogger := zerolog.Nop()\n\ttests := []struct {\n\t\tname             string\n\t\tcli              []string\n\t\tremote           featuresRecord\n\t\texpectedFeatures []string\n\t}{\n\t\t{\n\t\t\tname:             \"no_removals\",\n\t\t\tcli:              []string{},\n\t\t\tremote:           featuresRecord{},\n\t\t\texpectedFeatures: defaultFeatures,\n\t\t},\n\t\t{\n\t\t\tname:             \"support_datagram_v3\",\n\t\t\tcli:              []string{DeprecatedFeatureDatagramV3},\n\t\t\tremote:           featuresRecord{},\n\t\t\texpectedFeatures: defaultFeatures,\n\t\t},\n\t\t{\n\t\t\tname:             \"support_datagram_v3_1\",\n\t\t\tcli:              []string{DeprecatedFeatureDatagramV3_1},\n\t\t\tremote:           featuresRecord{},\n\t\t\texpectedFeatures: defaultFeatures,\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tresolver := &staticResolver{record: test.remote}\n\t\t\tselector, err := newFeatureSelector(t.Context(), test.name, &logger, resolver, test.cli, false, time.Second)\n\t\t\trequire.NoError(t, err)\n\t\t\tsnapshot := selector.Snapshot()\n\t\t\trequire.ElementsMatch(t, test.expectedFeatures, snapshot.FeaturesList)\n\t\t})\n\t}\n}\n\nfunc TestRefreshFeaturesRecord(t *testing.T) {\n\tpercentages := []uint32{0, 10, testAccountHash - 1, testAccountHash, testAccountHash + 1, 100, 101, 1000}\n\tselector := newTestSelector(t, percentages, false, time.Minute)\n\n\t// Starting out should default to DatagramV2\n\tsnapshot := selector.Snapshot()\n\trequire.Equal(t, DatagramV2, snapshot.DatagramVersion)\n\n\tfor _, percentage := range percentages {\n\t\tsnapshot = selector.Snapshot()\n\t\tif percentage > testAccountHash {\n\t\t\trequire.Equal(t, DatagramV3, snapshot.DatagramVersion)\n\t\t} else {\n\t\t\trequire.Equal(t, DatagramV2, snapshot.DatagramVersion)\n\t\t}\n\n\t\t// Manually progress the next refresh\n\t\t_ = selector.refresh(t.Context())\n\t}\n\n\t// Make sure a resolver error doesn't override the last fetched features\n\tsnapshot = selector.Snapshot()\n\trequire.Equal(t, DatagramV3, snapshot.DatagramVersion)\n}\n\nfunc TestSnapshotIsolation(t *testing.T) {\n\tpercentages := []uint32{testAccountHash, testAccountHash + 1}\n\tselector := newTestSelector(t, percentages, false, time.Minute)\n\n\t// Starting out should default to DatagramV2\n\tsnapshot := selector.Snapshot()\n\trequire.Equal(t, DatagramV2, snapshot.DatagramVersion)\n\n\t// Manually progress the next refresh\n\t_ = selector.refresh(t.Context())\n\n\tsnapshot2 := selector.Snapshot()\n\trequire.Equal(t, DatagramV3, snapshot2.DatagramVersion)\n\trequire.NotEqual(t, snapshot.DatagramVersion, snapshot2.DatagramVersion)\n}\n\nfunc TestStaticFeatures(t *testing.T) {\n\tpercentages := []uint32{0}\n\t// PostQuantum Enabled from user flag\n\tselector := newTestSelector(t, percentages, true, time.Second)\n\tsnapshot := selector.Snapshot()\n\trequire.Equal(t, PostQuantumStrict, snapshot.PostQuantum)\n\n\t// PostQuantum Disabled (or not set)\n\tselector = newTestSelector(t, percentages, false, time.Second)\n\tsnapshot = selector.Snapshot()\n\trequire.Equal(t, PostQuantumPrefer, snapshot.PostQuantum)\n}\n\nfunc newTestSelector(t *testing.T, percentages []uint32, pq bool, refreshFreq time.Duration) *featureSelector {\n\tlogger := zerolog.Nop()\n\n\tresolver := &mockResolver{\n\t\tpercentages: percentages,\n\t}\n\n\tselector, err := newFeatureSelector(t.Context(), testAccountTag, &logger, resolver, []string{}, pq, refreshFreq)\n\trequire.NoError(t, err)\n\n\treturn selector\n}\n\ntype mockResolver struct {\n\tnextIndex   int\n\tpercentages []uint32\n}\n\nfunc (mr *mockResolver) lookupRecord(ctx context.Context) ([]byte, error) {\n\tif mr.nextIndex >= len(mr.percentages) {\n\t\treturn nil, fmt.Errorf(\"no more record to lookup\")\n\t}\n\n\trecord, err := json.Marshal(featuresRecord{\n\t\tDatagramV3Percentage: mr.percentages[mr.nextIndex],\n\t})\n\tmr.nextIndex++\n\n\treturn record, err\n}\n\ntype staticResolver struct {\n\trecord featuresRecord\n}\n\nfunc (r *staticResolver) lookupRecord(ctx context.Context) ([]byte, error) {\n\treturn json.Marshal(r.record)\n}\n"
  },
  {
    "path": "fips/fips.go",
    "content": "//go:build fips\n\npackage fips\n\nimport (\n\t_ \"crypto/tls/fipsonly\"\n)\n\nfunc IsFipsEnabled() bool {\n\treturn true\n}\n"
  },
  {
    "path": "fips/nofips.go",
    "content": "//go:build !fips\n\npackage fips\n\nfunc IsFipsEnabled() bool {\n\treturn false\n}\n"
  },
  {
    "path": "flow/limiter.go",
    "content": "package flow\n\nimport (\n\t\"errors\"\n\t\"sync\"\n)\n\nconst (\n\tunlimitedActiveFlows = 0\n)\n\nvar (\n\tErrTooManyActiveFlows = errors.New(\"too many active flows\")\n)\n\ntype Limiter interface {\n\t// Acquire tries to acquire a free slot for a flow, if the value of flows is already above\n\t// the maximum it returns ErrTooManyActiveFlows.\n\tAcquire(flowType string) error\n\t// Release releases a slot for a flow.\n\tRelease()\n\t// SetLimit allows to hot swap the limit value of the limiter.\n\tSetLimit(uint64)\n}\n\ntype flowLimiter struct {\n\tlimiterLock        sync.Mutex\n\tactiveFlowsCounter uint64\n\tmaxActiveFlows     uint64\n\tunlimited          bool\n}\n\nfunc NewLimiter(maxActiveFlows uint64) Limiter {\n\tflowLimiter := &flowLimiter{\n\t\tmaxActiveFlows: maxActiveFlows,\n\t\tunlimited:      isUnlimited(maxActiveFlows),\n\t}\n\n\treturn flowLimiter\n}\n\nfunc (s *flowLimiter) Acquire(flowType string) error {\n\ts.limiterLock.Lock()\n\tdefer s.limiterLock.Unlock()\n\n\tif !s.unlimited && s.activeFlowsCounter >= s.maxActiveFlows {\n\t\tflowRegistrationsDropped.WithLabelValues(flowType).Inc()\n\t\treturn ErrTooManyActiveFlows\n\t}\n\n\ts.activeFlowsCounter++\n\treturn nil\n}\n\nfunc (s *flowLimiter) Release() {\n\ts.limiterLock.Lock()\n\tdefer s.limiterLock.Unlock()\n\n\tif s.activeFlowsCounter <= 0 {\n\t\treturn\n\t}\n\n\ts.activeFlowsCounter--\n}\n\nfunc (s *flowLimiter) SetLimit(newMaxActiveFlows uint64) {\n\ts.limiterLock.Lock()\n\tdefer s.limiterLock.Unlock()\n\n\ts.maxActiveFlows = newMaxActiveFlows\n\ts.unlimited = isUnlimited(newMaxActiveFlows)\n}\n\n// isUnlimited checks if the value received matches the configuration for the unlimited flow limiter.\nfunc isUnlimited(value uint64) bool {\n\treturn value == unlimitedActiveFlows\n}\n"
  },
  {
    "path": "flow/limiter_test.go",
    "content": "package flow_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/cloudflare/cloudflared/flow\"\n)\n\nfunc TestFlowLimiter_Unlimited(t *testing.T) {\n\tunlimitedLimiter := flow.NewLimiter(0)\n\n\tfor i := 0; i < 1000; i++ {\n\t\terr := unlimitedLimiter.Acquire(\"test\")\n\t\trequire.NoError(t, err)\n\t}\n}\n\nfunc TestFlowLimiter_Limited(t *testing.T) {\n\tmaxFlows := uint64(5)\n\tlimiter := flow.NewLimiter(maxFlows)\n\n\tfor i := uint64(0); i < maxFlows; i++ {\n\t\terr := limiter.Acquire(\"test\")\n\t\trequire.NoError(t, err)\n\t}\n\n\terr := limiter.Acquire(\"should fail\")\n\trequire.ErrorIs(t, err, flow.ErrTooManyActiveFlows)\n}\n\nfunc TestFlowLimiter_AcquireAndReleaseFlow(t *testing.T) {\n\tmaxFlows := uint64(5)\n\tlimiter := flow.NewLimiter(maxFlows)\n\n\t// Acquire the maximum number of flows\n\tfor i := uint64(0); i < maxFlows; i++ {\n\t\terr := limiter.Acquire(\"test\")\n\t\trequire.NoError(t, err)\n\t}\n\n\t// Validate acquire 1 more flows fails\n\terr := limiter.Acquire(\"should fail\")\n\trequire.ErrorIs(t, err, flow.ErrTooManyActiveFlows)\n\n\t// Release the maximum number of flows\n\tfor i := uint64(0); i < maxFlows; i++ {\n\t\tlimiter.Release()\n\t}\n\n\t// Validate acquire 1 more flows works\n\terr = limiter.Acquire(\"shouldn't fail\")\n\trequire.NoError(t, err)\n\n\t// Release a 10x the number of max flows\n\tfor i := uint64(0); i < 10*maxFlows; i++ {\n\t\tlimiter.Release()\n\t}\n\n\t// Validate it still can only acquire a value = number max flows.\n\tfor i := uint64(0); i < maxFlows; i++ {\n\t\terr := limiter.Acquire(\"test\")\n\t\trequire.NoError(t, err)\n\t}\n\terr = limiter.Acquire(\"should fail\")\n\trequire.ErrorIs(t, err, flow.ErrTooManyActiveFlows)\n}\n\nfunc TestFlowLimiter_SetLimit(t *testing.T) {\n\tmaxFlows := uint64(5)\n\tlimiter := flow.NewLimiter(maxFlows)\n\n\t// Acquire the maximum number of flows\n\tfor i := uint64(0); i < maxFlows; i++ {\n\t\terr := limiter.Acquire(\"test\")\n\t\trequire.NoError(t, err)\n\t}\n\n\t// Validate acquire 1 more flows fails\n\terr := limiter.Acquire(\"should fail\")\n\trequire.ErrorIs(t, err, flow.ErrTooManyActiveFlows)\n\n\t// Set the flow limiter to support one more request\n\tlimiter.SetLimit(maxFlows + 1)\n\n\t// Validate acquire 1 more flows now works\n\terr = limiter.Acquire(\"shouldn't fail\")\n\trequire.NoError(t, err)\n\n\t// Validate acquire 1 more flows doesn't work because we already reached the limit\n\terr = limiter.Acquire(\"should fail\")\n\trequire.ErrorIs(t, err, flow.ErrTooManyActiveFlows)\n\n\t// Release all flows\n\tfor i := uint64(0); i < maxFlows+1; i++ {\n\t\tlimiter.Release()\n\t}\n\n\t// Validate 1 flow works again\n\terr = limiter.Acquire(\"shouldn't fail\")\n\trequire.NoError(t, err)\n\n\t// Set the flow limit to 1\n\tlimiter.SetLimit(1)\n\n\t// Validate acquire 1 more flows doesn't work\n\terr = limiter.Acquire(\"should fail\")\n\trequire.ErrorIs(t, err, flow.ErrTooManyActiveFlows)\n\n\t// Set the flow limit to unlimited\n\tlimiter.SetLimit(0)\n\n\t// Validate it can acquire a lot of flows because it is now unlimited.\n\tfor i := uint64(0); i < 10*maxFlows; i++ {\n\t\terr := limiter.Acquire(\"shouldn't fail\")\n\t\trequire.NoError(t, err)\n\t}\n}\n"
  },
  {
    "path": "flow/metrics.go",
    "content": "package flow\n\nimport (\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"github.com/prometheus/client_golang/prometheus/promauto\"\n)\n\nconst (\n\tnamespace = \"flow\"\n)\n\nvar (\n\tlabels = []string{\"flow_type\"}\n\n\tflowRegistrationsDropped = promauto.NewCounterVec(prometheus.CounterOpts{\n\t\tNamespace: namespace,\n\t\tSubsystem: \"client\",\n\t\tName:      \"registrations_rate_limited_total\",\n\t\tHelp:      \"Count registrations dropped due to high number of concurrent flows being handled\",\n\t},\n\t\tlabels,\n\t)\n)\n"
  },
  {
    "path": "github_message.py",
    "content": "#!/usr/bin/python3\n\"\"\"\nCreate Github Releases Notes with binary checksums from Workers KV\n\"\"\"\n\nimport argparse\nimport logging\nimport os\nimport requests\n\nfrom github import Github, UnknownObjectException\n\nFORMAT = \"%(levelname)s - %(asctime)s: %(message)s\"\nlogging.basicConfig(format=FORMAT, level=logging.INFO)\n\nCLOUDFLARED_REPO = os.environ.get(\"GITHUB_REPO\", \"cloudflare/cloudflared\")\nGITHUB_CONFLICT_CODE = \"already_exists\"\nBASE_KV_URL = 'https://api.cloudflare.com/client/v4/accounts/'\n\n\ndef kv_get_keys(prefix, account, namespace, api_token):\n    \"\"\" get the KV keys for a given prefix \"\"\"\n    response = requests.get(\n        BASE_KV_URL + account + \"/storage/kv/namespaces/\" +\n        namespace + \"/keys\" + \"?prefix=\" + prefix,\n        headers={\n            \"Content-Type\": \"application/json\",\n            \"Authorization\": \"Bearer \" + api_token,\n        },\n    )\n    if response.status_code != 200:\n        jsonResponse = response.json()\n        errors = jsonResponse[\"errors\"]\n        if len(errors) > 0:\n            raise Exception(\"failed to get checksums: {0}\", errors[0])\n    return response.json()[\"result\"]\n\n\ndef kv_get_value(key, account, namespace, api_token):\n    \"\"\" get the KV value for a provided key \"\"\"\n    response = requests.get(\n        BASE_KV_URL + account + \"/storage/kv/namespaces/\" + namespace + \"/values/\" + key,\n        headers={\n            \"Content-Type\": \"application/json\",\n            \"Authorization\": \"Bearer \" + api_token,\n        },\n    )\n    if response.status_code != 200:\n        jsonResponse = response.json()\n        errors = jsonResponse[\"errors\"]\n        if len(errors) > 0:\n            raise Exception(\"failed to get checksums: {0}\", errors[0])\n    return response.text\n\n\ndef update_or_add_message(msg, name, sha):\n    \"\"\" \n    updates or builds the github version message for each new asset's sha256. \n    Searches the existing message string to update or create. \n    \"\"\"\n    new_text = '{0}: {1}\\n'.format(name, sha)\n    start = msg.find(name)\n    if (start != -1):\n        end = msg.find(\"\\n\", start)\n        if (end != -1):\n            return msg.replace(msg[start:end+1], new_text)\n    back = msg.rfind(\"```\")\n    if (back != -1):\n        return '{0}{1}```'.format(msg[:back], new_text)\n    return '{0} \\n### SHA256 Checksums:\\n```\\n{1}```'.format(msg, new_text)\n\n\ndef get_release(repo, version):\n    \"\"\" Get a Github Release matching the version tag. \"\"\"\n    try:\n        release = repo.get_release(version)\n        logging.info(\"Release %s found\", version)\n        return release\n    except UnknownObjectException:\n        logging.info(\"Release %s not found\", version)\n\n\ndef parse_args():\n    \"\"\" Parse and validate args \"\"\"\n    parser = argparse.ArgumentParser(\n        description=\"Updates a Github Release with checksums from KV\"\n    )\n    parser.add_argument(\n        \"--api-key\", default=os.environ.get(\"API_KEY\"), help=\"Github API key\"\n    )\n    parser.add_argument(\n        \"--kv-namespace-id\", default=os.environ.get(\"KV_NAMESPACE\"), help=\"workers KV namespace id\"\n    )\n    parser.add_argument(\n        \"--kv-account-id\", default=os.environ.get(\"KV_ACCOUNT\"), help=\"workers KV account id\"\n    )\n    parser.add_argument(\n        \"--kv-api-token\", default=os.environ.get(\"KV_API_TOKEN\"), help=\"workers KV API Token\"\n    )\n    parser.add_argument(\n        \"--release-version\",\n        metavar=\"version\",\n        default=os.environ.get(\"VERSION\"),\n        help=\"Release version\",\n    )\n    parser.add_argument(\n        \"--dry-run\", action=\"store_true\", help=\"Do not modify the release message\"\n    )\n\n    args = parser.parse_args()\n    is_valid = True\n    if not args.release_version:\n        logging.error(\"Missing release version\")\n        is_valid = False\n\n    if not args.api_key:\n        logging.error(\"Missing API key\")\n        is_valid = False\n\n    if not args.kv_namespace_id:\n        logging.error(\"Missing KV namespace id\")\n        is_valid = False\n\n    if not args.kv_account_id:\n        logging.error(\"Missing KV account id\")\n        is_valid = False\n\n    if not args.kv_api_token:\n        logging.error(\"Missing KV API token\")\n        is_valid = False\n\n    if is_valid:\n        return args\n\n    parser.print_usage()\n    exit(1)\n\n\ndef main():\n    \"\"\" Attempts to update the Github Release message with the github asset's checksums \"\"\"\n    try:\n        args = parse_args()\n        client = Github(args.api_key)\n        repo = client.get_repo(CLOUDFLARED_REPO)\n        release = get_release(repo, args.release_version)\n\n        msg = \"\"\n\n        prefix = f\"update_{args.release_version}_\"\n        keys = kv_get_keys(prefix, args.kv_account_id,\n                           args.kv_namespace_id, args.kv_api_token)\n        for key in [k[\"name\"] for k in keys]:\n            checksum = kv_get_value(\n                key, args.kv_account_id, args.kv_namespace_id, args.kv_api_token)\n            binary_name = key[len(prefix):]\n            msg = update_or_add_message(msg, binary_name, checksum)\n\n        if args.dry_run:\n            logging.info(\"Skipping release message update because of dry-run\")\n            logging.info(f\"Github message:\\n{msg}\")\n            return\n\n        # update the release body text\n        release.update_release(args.release_version, msg)\n\n    except Exception as e:\n        logging.exception(e)\n        exit(1)\n\n\nmain()\n"
  },
  {
    "path": "github_release.py",
    "content": "#!/usr/bin/python3\n\"\"\"\nCreates Github Releases and uploads assets\n\"\"\"\n\nimport argparse\nimport logging\nimport os\nimport shutil\nimport hashlib\nimport requests\nimport tarfile\nfrom os import listdir\nfrom os.path import isfile, join, splitext\nimport re\nimport subprocess\n\nfrom github import Github, GithubException, UnknownObjectException\n\nFORMAT = \"%(levelname)s - %(asctime)s: %(message)s\"\nlogging.basicConfig(format=FORMAT, level=logging.INFO)\n\nCLOUDFLARED_REPO = os.environ.get(\"GITHUB_REPO\", \"cloudflare/cloudflared\")\nGITHUB_CONFLICT_CODE = \"already_exists\"\nBASE_KV_URL = 'https://api.cloudflare.com/client/v4/accounts/'\nUPDATER_PREFIX = 'update'\n\ndef get_sha256(filename):\n    \"\"\" get the sha256 of a file \"\"\"\n    sha256_hash = hashlib.sha256()\n    with open(filename,\"rb\") as f:\n        for byte_block in iter(lambda: f.read(4096),b\"\"):\n            sha256_hash.update(byte_block)\n        return sha256_hash.hexdigest()\n\ndef send_hash(pkg_hash, name, version, account, namespace, api_token):\n    \"\"\" send the checksum of a file to workers kv \"\"\"\n    key = '{0}_{1}_{2}'.format(UPDATER_PREFIX, version, name)\n    headers = {\n        \"Content-Type\": \"application/json\",\n        \"Authorization\": \"Bearer \" + api_token,\n    }\n    response = requests.put(\n            BASE_KV_URL + account + \"/storage/kv/namespaces/\" + namespace + \"/values/\" + key,\n            headers=headers,\n            data=pkg_hash\n    )\n\n    if response.status_code != 200:\n        jsonResponse = response.json()\n        errors = jsonResponse[\"errors\"]\n        if len(errors) > 0:\n            raise Exception(\"failed to upload checksum: {0}\", errors[0])\n\n\n\ndef assert_tag_exists(repo, version):\n    \"\"\" Raise exception if repo does not contain a tag matching version \"\"\"\n    tags = repo.get_tags()\n    if not tags or tags[0].name != version:\n        raise Exception(\"Tag {} not found\".format(version))\n\n\ndef get_or_create_release(repo, version, dry_run=False, is_draft=False):\n    \"\"\"\n    Get a Github Release matching the version tag or create a new one.\n    If a conflict occurs on creation, attempt to fetch the Release on last time\n    \"\"\"\n    try:\n        release = repo.get_release(version)\n        logging.info(\"Release %s found\", version)\n        return release\n    except UnknownObjectException:\n        logging.info(\"Release %s not found\", version)\n\n    # We don't want to create a new release tag if one doesn't already exist\n    assert_tag_exists(repo, version)\n\n    if dry_run:\n        logging.info(\"Skipping Release creation because of dry-run\")\n        return\n\n    try:\n        if is_draft:\n            logging.info(\"Drafting release %s\", version)\n        else:\n            logging.info(\"Creating release %s\", version)\n        return repo.create_git_release(version, version, \"\", is_draft)\n    except GithubException as e:\n        errors = e.data.get(\"errors\", [])\n        if e.status == 422 and any(\n            [err.get(\"code\") == GITHUB_CONFLICT_CODE for err in errors]\n        ):\n            logging.warning(\n                \"Conflict: Release was likely just made by a different build: %s\",\n                e.data,\n            )\n            return repo.get_release(version)\n        raise e\n\n\ndef parse_args():\n    \"\"\" Parse and validate args \"\"\"\n    parser = argparse.ArgumentParser(\n        description=\"Creates Github Releases and uploads assets.\"\n    )\n    parser.add_argument(\n        \"--api-key\", default=os.environ.get(\"API_KEY\"), help=\"Github API key\"\n    )\n    parser.add_argument(\n        \"--release-version\",\n        metavar=\"version\",\n        default=os.environ.get(\"VERSION\"),\n        help=\"Release version\",\n    )\n    parser.add_argument(\n        \"--path\", default=os.environ.get(\"ASSET_PATH\"), help=\"Asset path\"\n    )\n    parser.add_argument(\n        \"--name\", default=os.environ.get(\"ASSET_NAME\"), help=\"Asset Name\"\n    )\n    parser.add_argument(\n        \"--namespace-id\", default=os.environ.get(\"KV_NAMESPACE\"), help=\"workersKV namespace id\"\n    )\n    parser.add_argument(\n        \"--kv-account-id\", default=os.environ.get(\"KV_ACCOUNT\"), help=\"workersKV account id\"\n    )\n    parser.add_argument(\n        \"--kv-api-token\", default=os.environ.get(\"KV_API_TOKEN\"), help=\"workersKV API Token\"\n    )\n    parser.add_argument(\n        \"--dry-run\", action=\"store_true\", help=\"Do not create release or upload asset\"\n    )\n\n    parser.add_argument(\n        \"--draft\", action=\"store_true\", help=\"Create a draft release\"\n    )\n\n    args = parser.parse_args()\n    is_valid = True\n    if not args.release_version:\n        logging.error(\"Missing release version\")\n        is_valid = False\n\n    if not args.path:\n        logging.error(\"Missing asset path\")\n        is_valid = False\n\n    if not args.name and not os.path.isdir(args.path):\n        logging.error(\"Missing asset name\")\n        is_valid = False\n\n    if not args.api_key:\n        logging.error(\"Missing API key\")\n        is_valid = False\n    \n    if not args.namespace_id:\n        logging.error(\"Missing KV namespace id\")\n        is_valid = False\n\n    if not args.kv_account_id:\n        logging.error(\"Missing KV account id\")\n        is_valid = False\n\n    if not args.kv_api_token:\n        logging.error(\"Missing KV API token\")\n        is_valid = False\n\n    if is_valid:\n        return args\n\n    parser.print_usage()\n    exit(1)\n\ndef upload_asset(release, filepath, filename, release_version, kv_account_id, namespace_id, kv_api_token):\n    logging.info(\"Uploading asset: %s\", filename)\n    assets = release.get_assets()\n    uploaded = False\n    for asset in assets:\n        if asset.name == filename:\n            uploaded = True\n            break\n    \n    if uploaded:\n        logging.info(\"asset already uploaded, skipping upload\")\n        return\n    \n    release.upload_asset(filepath, name=filename)\n\n    # check and extract if the file is a tar and gzipped file (as is the case with the macos builds)\n    binary_path = filepath\n    if binary_path.endswith(\"tgz\"):\n        try:\n            shutil.rmtree('cfd')\n        except OSError:\n            pass\n        zipfile = tarfile.open(binary_path, \"r:gz\")\n        zipfile.extractall('cfd') # specify which folder to extract to\n        zipfile.close()\n\n        binary_path = os.path.join(os.getcwd(), 'cfd', 'cloudflared')\n\n    # send the sha256 (the checksum) to workers kv\n    logging.info(\"Uploading sha256 checksum for: %s\", filename)\n    pkg_hash = get_sha256(binary_path)\n    send_hash(pkg_hash, filename, release_version, kv_account_id, namespace_id, kv_api_token)\n\ndef move_asset(filepath, filename):\n    # create the artifacts directory if it doesn't exist\n    artifact_path = os.path.join(os.getcwd(), 'artifacts')\n    if not os.path.isdir(artifact_path):\n        os.mkdir(artifact_path)\n\n    # copy the binary to the path\n    copy_path = os.path.join(artifact_path, filename)\n    try:\n        shutil.copy(filepath, copy_path)\n    except shutil.SameFileError:\n        pass # the macOS release copy fails with being the same file (already in the artifacts directory)\n\ndef get_binary_version(binary_path):\n    \"\"\"\n    Sample output from go version -m <binary>:\n    ...\n    build\t-compiler=gc\n\tbuild\t-ldflags=\"-X \\\"main.Version=2024.8.3-6-gec072691\\\" -X \\\"main.BuildTime=2024-09-10-1027 UTC\\\" \"\n\tbuild\tCGO_ENABLED=1\n    ...\n\n    This function parses the above output to retrieve the following substring 2024.8.3-6-gec072691.\n    To do this a start and end indexes are computed and the a slice is extracted from the output using them.\n    \"\"\"\n    needle = \"main.Version=\"\n    cmd = ['go','version', '-m', binary_path]\n    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n    output, _ = process.communicate()\n    version_info = output.decode()\n\n    # Find start of needle\n    needle_index = version_info.find(needle)\n    # Find backward slash relative to the beggining of the needle\n    relative_end_index = version_info[needle_index:].find(\"\\\\\")\n    # Calculate needle position plus needle length to find version beggining\n    start_index = needle_index + len(needle)\n    # Calculate needle position plus relative position of the backward slash\n    end_index = needle_index + relative_end_index\n    return version_info[start_index:end_index]\n\ndef assert_asset_version(binary_path, release_version):\n    \"\"\"\n    Asserts that the artifacts have the correct release_version.\n    The artifacts that are checked must not have an extension expecting .exe and .tgz.\n    In the occurrence of any other extension the function exits early.\n    \"\"\"\n    try:\n        shutil.rmtree('tmp')\n    except OSError:\n        pass\n    _, ext = os.path.splitext(binary_path)\n    if ext == '.exe' or ext == '':\n        binary_version = get_binary_version(binary_path)\n    elif ext == '.tgz':\n        tar = tarfile.open(binary_path, \"r:gz\")\n        tar.extractall(\"tmp\")\n        tar.close()\n        binary_path = os.path.join(os.getcwd(), 'tmp', 'cloudflared')\n        binary_version = get_binary_version(binary_path)\n    else:\n        return\n\n    if binary_version != release_version:\n        logging.error(f\"Version mismatch {binary_path}, binary_version {binary_version} release_version {release_version}\")\n        exit(1)\n\n\ndef main():\n    \"\"\" Attempts to upload Asset to Github Release. Creates Release if it doesn't exist \"\"\"\n    try:\n        args = parse_args()\n\n        if args.dry_run:\n            if os.path.isdir(args.path):\n                onlyfiles = [f for f in listdir(args.path) if isfile(join(args.path, f))]\n                for filename in onlyfiles:\n                    binary_path = os.path.join(args.path, filename)\n                    logging.info(\"binary: \" + binary_path)\n                    assert_asset_version(binary_path, args.release_version)\n            elif os.path.isfile(args.path):\n                logging.info(\"binary: \" + binary_path)\n            else:\n                logging.error(\"dryrun failed\")\n            return\n        else:\n            client = Github(args.api_key)\n            repo = client.get_repo(CLOUDFLARED_REPO)\n\n            if os.path.isdir(args.path):\n                onlyfiles = [f for f in listdir(args.path) if isfile(join(args.path, f))]\n                for filename in onlyfiles:\n                    binary_path = os.path.join(args.path, filename)\n                    assert_asset_version(binary_path, args.release_version)\n                release = get_or_create_release(repo, args.release_version, args.dry_run, args.draft)\n                for filename in onlyfiles:\n                    binary_path = os.path.join(args.path, filename)\n                    upload_asset(release, binary_path, filename, args.release_version, args.kv_account_id, args.namespace_id,\n                    args.kv_api_token)\n                    move_asset(binary_path, filename)\n            else:\n                raise Exception(\"the argument path must be a directory\")\n\n    except Exception as e:\n        logging.exception(e)\n        exit(1)\n\nmain()\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/cloudflare/cloudflared\n\ngo 1.24.0\n\nrequire (\n\tgithub.com/coreos/go-oidc/v3 v3.17.0\n\tgithub.com/coreos/go-systemd/v22 v22.5.0\n\tgithub.com/facebookgo/grace v0.0.0-20180706040059-75cf19382434\n\tgithub.com/fortytw2/leaktest v1.3.0\n\tgithub.com/fsnotify/fsnotify v1.4.9\n\tgithub.com/getsentry/sentry-go v0.43.0\n\tgithub.com/go-chi/chi/v5 v5.2.2\n\tgithub.com/go-chi/cors v1.2.1\n\tgithub.com/go-jose/go-jose/v4 v4.1.3\n\tgithub.com/gobwas/ws v1.2.1\n\tgithub.com/google/gopacket v1.1.19\n\tgithub.com/google/uuid v1.6.0\n\tgithub.com/gorilla/websocket v1.5.0\n\tgithub.com/json-iterator/go v1.1.12\n\tgithub.com/mattn/go-colorable v0.1.13\n\tgithub.com/mitchellh/go-homedir v1.1.0\n\tgithub.com/pkg/errors v0.9.1\n\tgithub.com/prometheus/client_golang v1.22.0\n\tgithub.com/prometheus/client_model v0.6.2\n\tgithub.com/quic-go/quic-go v0.52.0\n\tgithub.com/rs/zerolog v1.20.0\n\tgithub.com/stretchr/testify v1.11.1\n\tgithub.com/urfave/cli/v2 v2.3.0\n\tgo.opentelemetry.io/contrib/propagators v0.22.0\n\tgo.opentelemetry.io/otel v1.40.0\n\tgo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0\n\tgo.opentelemetry.io/otel/sdk v1.40.0\n\tgo.opentelemetry.io/otel/trace v1.40.0\n\tgo.opentelemetry.io/proto/otlp v1.2.0\n\tgo.uber.org/automaxprocs v1.6.0\n\tgo.uber.org/mock v0.5.1\n\tgolang.org/x/crypto v0.38.0\n\tgolang.org/x/net v0.40.0\n\tgolang.org/x/sync v0.14.0\n\tgolang.org/x/sys v0.40.0\n\tgolang.org/x/term v0.32.0\n\tgoogle.golang.org/protobuf v1.36.6\n\tgopkg.in/natefinch/lumberjack.v2 v2.0.0\n\tgopkg.in/yaml.v3 v3.0.1\n\tnhooyr.io/websocket v1.8.7\n\tzombiezen.com/go/capnproto2 v2.18.0+incompatible\n)\n\nrequire (\n\tgithub.com/BurntSushi/toml v1.2.0 // indirect\n\tgithub.com/beorn7/perks v1.0.1 // indirect\n\tgithub.com/bytedance/sonic v1.12.0 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.3.0 // indirect\n\tgithub.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect\n\tgithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect\n\tgithub.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 // indirect\n\tgithub.com/facebookgo/freeport v0.0.0-20150612182905-d4adf43b75b9 // indirect\n\tgithub.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect\n\tgithub.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 // indirect\n\tgithub.com/gin-gonic/gin v1.9.1 // indirect\n\tgithub.com/go-logr/logr v1.4.3 // indirect\n\tgithub.com/go-logr/stdr v1.2.2 // indirect\n\tgithub.com/go-playground/validator/v10 v10.15.1 // indirect\n\tgithub.com/go-task/slim-sprig/v3 v3.0.0 // indirect\n\tgithub.com/gobwas/httphead v0.1.0 // indirect\n\tgithub.com/gobwas/pool v0.2.1 // indirect\n\tgithub.com/google/pprof v0.0.0-20250418163039-24c5476c6587 // indirect\n\tgithub.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect\n\tgithub.com/klauspost/compress v1.18.0 // indirect\n\tgithub.com/klauspost/cpuid/v2 v2.2.5 // 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/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect\n\tgithub.com/onsi/ginkgo/v2 v2.23.4 // indirect\n\tgithub.com/pelletier/go-toml/v2 v2.0.9 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect\n\tgithub.com/prometheus/common v0.64.0 // indirect\n\tgithub.com/prometheus/procfs v0.15.1 // indirect\n\tgithub.com/russross/blackfriday/v2 v2.1.0 // indirect\n\tgithub.com/tinylib/msgp v1.6.3 // indirect\n\tgo.opentelemetry.io/auto/sdk v1.2.1 // indirect\n\tgo.opentelemetry.io/otel/metric v1.40.0 // indirect\n\tgolang.org/x/arch v0.4.0 // indirect\n\tgolang.org/x/mod v0.24.0 // indirect\n\tgolang.org/x/oauth2 v0.30.0 // indirect\n\tgolang.org/x/text v0.25.0 // indirect\n\tgolang.org/x/tools v0.32.0 // indirect\n\tgoogle.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250512202823-5a2f75b736a9 // indirect\n\tgoogle.golang.org/grpc v1.72.2 // indirect\n\tgopkg.in/yaml.v2 v2.4.0 // indirect\n)\n\nreplace github.com/urfave/cli/v2 => github.com/ipostelnik/cli/v2 v2.3.1-0.20210324024421-b6ea8234fe3d\n\n// Avoid 'CVE-2022-21698'\nreplace github.com/prometheus/golang_client => github.com/prometheus/golang_client v1.12.1\n\nreplace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1\n\n// This fork is based on quic-go v0.45\nreplace github.com/quic-go/quic-go => github.com/chungthuang/quic-go v0.45.1-0.20250428085412-43229ad201fd\n"
  },
  {
    "path": "go.sum",
    "content": "github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0=\ngithub.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=\ngithub.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/bytedance/sonic v1.12.0 h1:YGPgxF9xzaCNvd/ZKdQ28yRovhfMFZQjuk6fKBzZ3ls=\ngithub.com/bytedance/sonic v1.12.0/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=\ngithub.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM=\ngithub.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/chungthuang/quic-go v0.45.1-0.20250428085412-43229ad201fd h1:VdYI5zFQ2h1/qzoC6rhyPx479bkF8i177Qpg4Q2n1vk=\ngithub.com/chungthuang/quic-go v0.45.1-0.20250428085412-43229ad201fd/go.mod h1:MFlGGpcpJqRAfmYi6NC2cptDPSxRWTOGNuP4wqrWmzQ=\ngithub.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=\ngithub.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=\ngithub.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=\ngithub.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=\ngithub.com/coreos/go-oidc/v3 v3.17.0 h1:hWBGaQfbi0iVviX4ibC7bk8OKT5qNr4klBaCHVNvehc=\ngithub.com/coreos/go-oidc/v3 v3.17.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8=\ngithub.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=\ngithub.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=\ngithub.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=\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 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=\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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ=\ngithub.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=\ngithub.com/facebookgo/freeport v0.0.0-20150612182905-d4adf43b75b9 h1:wWke/RUCl7VRjQhwPlR/v0glZXNYzBHdNUzf/Am2Nmg=\ngithub.com/facebookgo/freeport v0.0.0-20150612182905-d4adf43b75b9/go.mod h1:uPmAp6Sws4L7+Q/OokbWDAK1ibXYhB3PXFP1kol5hPg=\ngithub.com/facebookgo/grace v0.0.0-20180706040059-75cf19382434 h1:mOp33BLbcbJ8fvTAmZacbBiOASfxN+MLcLxymZCIrGE=\ngithub.com/facebookgo/grace v0.0.0-20180706040059-75cf19382434/go.mod h1:KigFdumBXUPSwzLDbeuzyt0elrL7+CP7TKuhrhT4bcU=\ngithub.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=\ngithub.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=\ngithub.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y=\ngithub.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=\ngithub.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=\ngithub.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=\ngithub.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=\ngithub.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=\ngithub.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=\ngithub.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=\ngithub.com/getsentry/sentry-go v0.43.0 h1:XbXLpFicpo8HmBDaInk7dum18G9KSLcjZiyUKS+hLW4=\ngithub.com/getsentry/sentry-go v0.43.0/go.mod h1:XDotiNZbgf5U8bPDUAfvcFmOnMQQceESxyKaObSssW0=\ngithub.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=\ngithub.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=\ngithub.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=\ngithub.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=\ngithub.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=\ngithub.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/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=\ngithub.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=\ngithub.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=\ngithub.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=\ngithub.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=\ngithub.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=\ngithub.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=\ngithub.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=\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.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=\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.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=\ngithub.com/go-playground/validator/v10 v10.15.1 h1:BSe8uhN+xQ4r5guV/ywQI4gO59C2raYcGffYWZEjZzM=\ngithub.com/go-playground/validator/v10 v10.15.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=\ngithub.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=\ngithub.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=\ngithub.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=\ngithub.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=\ngithub.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=\ngithub.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=\ngithub.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=\ngithub.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=\ngithub.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=\ngithub.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk=\ngithub.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=\ngithub.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=\ngithub.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=\ngithub.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=\ngithub.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\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/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=\ngithub.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=\ngithub.com/google/pprof v0.0.0-20250418163039-24c5476c6587 h1:b/8HpQhvKLSNzH5oTXN2WkNcMl6YB5K3FRbb+i+Ml34=\ngithub.com/google/pprof v0.0.0-20250418163039-24c5476c6587/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=\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/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=\ngithub.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=\ngithub.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=\ngithub.com/ipostelnik/cli/v2 v2.3.1-0.20210324024421-b6ea8234fe3d h1:PRDnysJ9dF1vUMmEzBu6aHQeUluSQy4eWH3RsSSy/vI=\ngithub.com/ipostelnik/cli/v2 v2.3.1-0.20210324024421-b6ea8234fe3d/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=\ngithub.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\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/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=\ngithub.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=\ngithub.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=\ngithub.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=\ngithub.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=\ngithub.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=\ngithub.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=\ngithub.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=\ngithub.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=\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.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=\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/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=\ngithub.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=\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 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\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/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=\ngithub.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=\ngithub.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=\ngithub.com/onsi/gomega v1.36.3 h1:hID7cr8t3Wp26+cYnfcjR6HpJ00fdogN6dqZ1t6IylU=\ngithub.com/onsi/gomega v1.36.3/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=\ngithub.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=\ngithub.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=\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/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=\ngithub.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=\ngithub.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=\ngithub.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=\ngithub.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=\ngithub.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=\ngithub.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=\ngithub.com/prometheus/common v0.64.0 h1:pdZeA+g617P7oGv1CzdTzyeShxAGrTBsolKNOLQPGO4=\ngithub.com/prometheus/common v0.64.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=\ngithub.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=\ngithub.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=\ngithub.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=\ngithub.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=\ngithub.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=\ngithub.com/rs/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs=\ngithub.com/rs/zerolog v1.20.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo=\ngithub.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=\ngithub.com/russross/blackfriday/v2 v2.1.0/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/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/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\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.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.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/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 v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=\ngithub.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=\ngithub.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=\ngithub.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=\ngithub.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=\ngo.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=\ngo.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=\ngo.opentelemetry.io/contrib/propagators v0.22.0 h1:KGdv58M2//veiYLIhb31mofaI2LgkIPXXAZVeYVyfd8=\ngo.opentelemetry.io/contrib/propagators v0.22.0/go.mod h1:xGOuXr6lLIF9BXipA4pm6UuOSI0M98U6tsI3khbOiwU=\ngo.opentelemetry.io/otel v1.0.0-RC2/go.mod h1:w1thVQ7qbAy8MHb0IFj8a5Q2QU0l2ksf8u/CN8m3NOM=\ngo.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms=\ngo.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs=\ngo.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g=\ngo.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc=\ngo.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8=\ngo.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE=\ngo.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw=\ngo.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg=\ngo.opentelemetry.io/otel/trace v1.0.0-RC2/go.mod h1:JPQ+z6nNw9mqEGT8o3eoPTdnNI+Aj5JcxEsVGREIAy4=\ngo.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw=\ngo.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA=\ngo.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94=\ngo.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A=\ngo.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=\ngo.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=\ngo.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=\ngo.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=\ngo.uber.org/mock v0.5.1 h1:ASgazW/qBmR+A32MYFDB6E2POoTgOwT509VP0CT/fjs=\ngo.uber.org/mock v0.5.1/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=\ngolang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc=\ngolang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=\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/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=\ngolang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=\ngolang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=\ngolang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=\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/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=\ngolang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=\ngolang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=\ngolang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=\ngolang.org/x/sync v0.14.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-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=\ngolang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=\ngolang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=\ngolang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=\ngolang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU=\ngolang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 h1:vPV0tzlsK6EzEDHNNH5sa7Hs9bd7iXR7B1tSiPepkV0=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:pKLAc5OolXC3ViWGI62vvC0n10CpwAtRcTNCFwTKBEw=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250512202823-5a2f75b736a9 h1:IkAfh6J/yllPtpYFU0zZN1hUPYdT0ogkBT/9hMxHjvg=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20250512202823-5a2f75b736a9/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=\ngoogle.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8=\ngoogle.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=\ngoogle.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=\ngoogle.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=\ngopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\nnhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=\nnhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=\nzombiezen.com/go/capnproto2 v2.18.0+incompatible h1:mwfXZniffG5mXokQGHUJWGnqIBggoPfT/CEwon9Yess=\nzombiezen.com/go/capnproto2 v2.18.0+incompatible/go.mod h1:XO5Pr2SbXgqZwn0m0Ru54QBqpOf4K5AYBO+8LAOBQEQ=\n"
  },
  {
    "path": "hello/hello.go",
    "content": "package hello\n\nimport (\n\t\"bytes\"\n\t\"crypto/tls\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"html/template\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/gorilla/websocket\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/tlsconfig\"\n)\n\nconst (\n\tUptimeRoute    = \"/uptime\"\n\tWSRoute        = \"/ws\"\n\tSSERoute       = \"/sse\"\n\tHealthRoute    = \"/_health\"\n\tdefaultSSEFreq = time.Second * 10\n)\n\ntype templateData struct {\n\tServerName string\n\tRequest    *http.Request\n\tBody       string\n}\n\ntype OriginUpTime struct {\n\tStartTime time.Time `json:\"startTime\"`\n\tUpTime    string    `json:\"uptime\"`\n}\n\nconst defaultServerName = \"the Cloudflare Tunnel test server\"\nconst indexTemplate = `\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\">\n    <title>\n      Cloudflare Tunnel Connection\n    </title>\n    <meta name=\"author\" content=\"\">\n    <meta name=\"description\" content=\"Cloudflare Tunnel Connection\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <style>\n      html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}section{display:block}h1{font-size:2em;margin:.67em 0}a{background-color:transparent;-webkit-text-decoration-skip:objects}/* 1 */::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}/* 1 */a,body,dd,div,dl,dt,h1,h4,html,p,section{box-sizing:border-box}.bt{border-top-style:solid;border-top-width:1px}.bl{border-left-style:solid;border-left-width:1px}.b--orange{border-color:#f38020}.br1{border-radius:.125rem}.bw2{border-width:.25rem}.dib{display:inline-block}.sans-serif{font-family:open sans,-apple-system,BlinkMacSystemFont,avenir next,avenir,helvetica neue,helvetica,ubuntu,roboto,noto,segoe ui,arial,sans-serif}.overflow-x-auto{overflow-x:auto}.code{font-family:Consolas,monaco,monospace}.b{font-weight:700}.fw3{font-weight:300}.fw4{font-weight:400}.fw5{font-weight:500}.fw6{font-weight:600}.lh-copy{line-height:1.5}.link{text-decoration:none}.link,.link:active,.link:focus,.link:hover,.link:link,.link:visited{transition:color .15s ease-in}.link:focus{outline:1px dotted currentColor}.mw-100{max-width:100%}.mw4{max-width:8rem}.mw7{max-width:48rem}.bg-light-gray{background-color:#f7f7f7}.link-hover:hover{background-color:#1f679e}.white{color:#fff}.bg-white{background-color:#fff}.bg-blue{background-color:#408bc9}.pb2{padding-bottom:.5rem}.pb6{padding-bottom:8rem}.pt3{padding-top:1rem}.pt5{padding-top:4rem}.pv2{padding-top:.5rem;padding-bottom:.5rem}.ph3{padding-left:1rem;padding-right:1rem}.ph4{padding-left:2rem;padding-right:2rem}.ml0{margin-left:0}.mb1{margin-bottom:.25rem}.mb2{margin-bottom:.5rem}.mb3{margin-bottom:1rem}.mt5{margin-top:4rem}.ttu{text-transform:uppercase}.f4{font-size:1.25rem}.f5{font-size:1rem}.f6{font-size:.875rem}.f7{font-size:.75rem}.measure{max-width:30em}.center{margin-left:auto}.center{margin-right:auto}@media screen and (min-width:30em){.f2-ns{font-size:2.25rem}}@media screen and (min-width:30em) and (max-width:60em){.f5-m{font-size:1rem}}@media screen and (min-width:60em){.f4-l{font-size:1.25rem}}\n    .st0{fill:#FFF}.st1{fill:#f48120}.st2{fill:#faad3f}.st3{fill:#404041}\n    </style>\n  </head>\n  <body class=\"sans-serif black\">\n    <div class=\"bt bw2 b--orange bg-white pb6\">\n      <div class=\"mw7 center ph4 pt3\">\n        <svg id=\"Layer_2\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 109 40.5\" class=\"mw4\">\n          <path class=\"st0\" d=\"M98.6 14.2L93 12.9l-1-.4-25.7.2v12.4l32.3.1z\"/>\n          <path class=\"st1\" d=\"M88.1 24c.3-1 .2-2-.3-2.6-.5-.6-1.2-1-2.1-1.1l-17.4-.2c-.1 0-.2-.1-.3-.1-.1-.1-.1-.2 0-.3.1-.2.2-.3.4-.3l17.5-.2c2.1-.1 4.3-1.8 5.1-3.8l1-2.6c0-.1.1-.2 0-.3-1.1-5.1-5.7-8.9-11.1-8.9-5 0-9.3 3.2-10.8 7.7-1-.7-2.2-1.1-3.6-1-2.4.2-4.3 2.2-4.6 4.6-.1.6 0 1.2.1 1.8-3.9.1-7.1 3.3-7.1 7.3 0 .4 0 .7.1 1.1 0 .2.2.3.3.3h32.1c.2 0 .4-.1.4-.3l.3-1.1z\"/>\n          <path class=\"st2\" d=\"M93.6 12.8h-.5c-.1 0-.2.1-.3.2l-.7 2.4c-.3 1-.2 2 .3 2.6.5.6 1.2 1 2.1 1.1l3.7.2c.1 0 .2.1.3.1.1.1.1.2 0 .3-.1.2-.2.3-.4.3l-3.8.2c-2.1.1-4.3 1.8-5.1 3.8l-.2.9c-.1.1 0 .3.2.3h13.2c.2 0 .3-.1.3-.3.2-.8.4-1.7.4-2.6 0-5.2-4.3-9.5-9.5-9.5\"/>\n          <path class=\"st3\" d=\"M104.4 30.8c-.5 0-.9-.4-.9-.9s.4-.9.9-.9.9.4.9.9-.4.9-.9.9m0-1.6c-.4 0-.7.3-.7.7 0 .4.3.7.7.7.4 0 .7-.3.7-.7 0-.4-.3-.7-.7-.7m.4 1.2h-.2l-.2-.3h-.2v.3h-.2v-.9h.5c.2 0 .3.1.3.3 0 .1-.1.2-.2.3l.2.3zm-.3-.5c.1 0 .1 0 .1-.1s-.1-.1-.1-.1h-.3v.3h.3zM14.8 29H17v6h3.8v1.9h-6zM23.1 32.9c0-2.3 1.8-4.1 4.3-4.1s4.2 1.8 4.2 4.1-1.8 4.1-4.3 4.1c-2.4 0-4.2-1.8-4.2-4.1m6.3 0c0-1.2-.8-2.2-2-2.2s-2 1-2 2.1.8 2.1 2 2.1c1.2.2 2-.8 2-2M34.3 33.4V29h2.2v4.4c0 1.1.6 1.7 1.5 1.7s1.5-.5 1.5-1.6V29h2.2v4.4c0 2.6-1.5 3.7-3.7 3.7-2.3-.1-3.7-1.2-3.7-3.7M45 29h3.1c2.8 0 4.5 1.6 4.5 3.9s-1.7 4-4.5 4h-3V29zm3.1 5.9c1.3 0 2.2-.7 2.2-2s-.9-2-2.2-2h-.9v4h.9zM55.7 29H62v1.9h-4.1v1.3h3.7V34h-3.7v2.9h-2.2zM65.1 29h2.2v6h3.8v1.9h-6zM76.8 28.9H79l3.4 8H80l-.6-1.4h-3.1l-.6 1.4h-2.3l3.4-8zm2 4.9l-.9-2.2-.9 2.2h1.8zM85.2 29h3.7c1.2 0 2 .3 2.6.9.5.5.7 1.1.7 1.8 0 1.2-.6 2-1.6 2.4l1.9 2.8H90l-1.6-2.4h-1v2.4h-2.2V29zm3.6 3.8c.7 0 1.2-.4 1.2-.9 0-.6-.5-.9-1.2-.9h-1.4v1.9h1.4zM95.3 29h6.4v1.8h-4.2V32h3.8v1.8h-3.8V35h4.3v1.9h-6.5zM10 33.9c-.3.7-1 1.2-1.8 1.2-1.2 0-2-1-2-2.1s.8-2.1 2-2.1c.9 0 1.6.6 1.9 1.3h2.3c-.4-1.9-2-3.3-4.2-3.3-2.4 0-4.3 1.8-4.3 4.1s1.8 4.1 4.2 4.1c2.1 0 3.7-1.4 4.2-3.2H10z\"/>\n        </svg>\n        <h1 class=\"f4 f2-ns mt5 fw5\">Congrats! You created a tunnel!</h1>\n        <p class=\"f6 f5-m f4-l measure lh-copy fw3\">\n          Cloudflare Tunnel exposes locally running applications to the internet by\n          running an encrypted, virtual tunnel from your laptop or server to\n          Cloudflare's edge network.\n        </p>\n        <p class=\"b f5 mt5 fw6\">Ready for the next step?</p>\n        <a\n          class=\"fw6 link white bg-blue ph4 pv2 br1 dib f5 link-hover\"\n          style=\"border-bottom: 1px solid #1f679e\"\n          href=\"https://developers.cloudflare.com/cloudflare-one/connections/connect-apps\">\n          Get started here\n        </a>\n       <section>\n          <h4 class=\"f6 fw4 pt5 mb2\">Request</h4>\n          <dl class=\"bl bw2 b--orange ph3 pt3 pb2 bg-light-gray f7 code overflow-x-auto mw-100\">\n\t\t\t\t\t\t<dd class=\"ml0 mb3 f5\">Method: {{.Request.Method}}</dd>\n\t\t\t\t\t\t<dd class=\"ml0 mb3 f5\">Protocol: {{.Request.Proto}}</dd>\n\t\t\t\t\t\t<dd class=\"ml0 mb3 f5\">Request URL: {{.Request.URL}}</dd>\n\t\t\t\t\t\t<dd class=\"ml0 mb3 f5\">Transfer encoding: {{.Request.TransferEncoding}}</dd>\n\t\t\t\t\t\t<dd class=\"ml0 mb3 f5\">Host: {{.Request.Host}}</dd>\n\t\t\t\t\t\t<dd class=\"ml0 mb3 f5\">Remote address: {{.Request.RemoteAddr}}</dd>\n\t\t\t\t\t\t<dd class=\"ml0 mb3 f5\">Request URI: {{.Request.RequestURI}}</dd>\n{{range $key, $value := .Request.Header}}\n\t\t\t\t\t\t<dd class=\"ml0 mb3 f5\">Header: {{$key}}, Value: {{$value}}</dd>\n{{end}}\n\t\t\t\t\t\t<dd class=\"ml0 mb3 f5\">Body: {{.Body}}</dd>\n\t\t\t\t\t</dl>\n        </section>\n     </div>\n    </div>\n  </body>\n</html>\n`\n\nfunc StartHelloWorldServer(log *zerolog.Logger, listener net.Listener, shutdownC <-chan struct{}) error {\n\tlog.Info().Msgf(\"Starting Hello World server at %s\", listener.Addr())\n\tserverName := defaultServerName\n\tif hostname, err := os.Hostname(); err == nil {\n\t\tserverName = hostname\n\t}\n\n\tupgrader := websocket.Upgrader{\n\t\tReadBufferSize:  1024,\n\t\tWriteBufferSize: 1024,\n\t}\n\n\tmuxer := http.NewServeMux()\n\tmuxer.HandleFunc(UptimeRoute, uptimeHandler(time.Now()))\n\tmuxer.HandleFunc(WSRoute, websocketHandler(log, upgrader))\n\tmuxer.HandleFunc(SSERoute, sseHandler(log))\n\tmuxer.HandleFunc(HealthRoute, healthHandler())\n\tmuxer.HandleFunc(\"/\", rootHandler(serverName))\n\thttpServer := &http.Server{Addr: listener.Addr().String(), Handler: muxer}\n\tgo func() {\n\t\t<-shutdownC\n\t\t_ = httpServer.Close()\n\t}()\n\n\terr := httpServer.Serve(listener)\n\treturn err\n}\n\nfunc CreateTLSListener(address string) (net.Listener, error) {\n\tcertificate, err := tlsconfig.GetHelloCertificate()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// If the port in address is empty, a port number is automatically chosen\n\tlistener, err := tls.Listen(\n\t\t\"tcp\",\n\t\taddress,\n\t\t&tls.Config{Certificates: []tls.Certificate{certificate}})\n\n\treturn listener, err\n}\n\nfunc uptimeHandler(startTime time.Time) http.HandlerFunc {\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\t// Note that if autoupdate is enabled, the uptime is reset when a new client\n\t\t// release is available\n\t\tresp := &OriginUpTime{StartTime: startTime, UpTime: time.Now().Sub(startTime).String()}\n\t\trespJson, err := json.Marshal(resp)\n\t\tif err != nil {\n\t\t\tw.WriteHeader(http.StatusInternalServerError)\n\t\t} else {\n\t\t\tw.Header().Set(\"Content-Type\", \"application/json\")\n\t\t\t_, _ = w.Write(respJson)\n\t\t}\n\t}\n}\n\n// This handler will echo message\nfunc websocketHandler(log *zerolog.Logger, upgrader websocket.Upgrader) http.HandlerFunc {\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\t// This addresses the issue of r.Host includes port but origin header doesn't\n\t\thost, _, err := net.SplitHostPort(r.Host)\n\t\tif err == nil {\n\t\t\tr.Host = host\n\t\t}\n\n\t\tconn, err := upgrader.Upgrade(w, r, nil)\n\t\tif err != nil {\n\t\t\tlog.Err(err).Msg(\"failed to upgrade to websocket connection\")\n\t\t\treturn\n\t\t}\n\t\tdefer conn.Close()\n\t\tfor {\n\t\t\tmt, message, err := conn.ReadMessage()\n\t\t\tif err != nil {\n\t\t\t\tlog.Err(err).Msg(\"websocket read message error\")\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif err := conn.WriteMessage(mt, message); err != nil {\n\t\t\t\tlog.Err(err).Msg(\"websocket write message error\")\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc sseHandler(log *zerolog.Logger) http.HandlerFunc {\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\tw.Header().Set(\"Content-Type\", \"text/event-stream; charset=utf-8\")\n\t\tflusher, ok := w.(http.Flusher)\n\t\tif !ok {\n\t\t\tw.WriteHeader(http.StatusInternalServerError)\n\t\t\tlog.Error().Msgf(\"Can't support SSE. ResponseWriter %T doesn't implement http.Flusher interface\", w)\n\t\t\treturn\n\t\t}\n\n\t\tfreq := defaultSSEFreq\n\t\tif requestedFreq := r.URL.Query()[\"freq\"]; len(requestedFreq) > 0 {\n\t\t\tparsedFreq, err := time.ParseDuration(requestedFreq[0])\n\t\t\tif err == nil {\n\t\t\t\tfreq = parsedFreq\n\t\t\t}\n\t\t}\n\t\tlog.Info().Msgf(\"Server Sent Events every %s\", freq)\n\t\tticker := time.NewTicker(freq)\n\t\tcounter := 0\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-r.Context().Done():\n\t\t\t\treturn\n\t\t\tcase <-ticker.C:\n\t\t\t}\n\t\t\t_, err := fmt.Fprintf(w, \"%d\\n\\n\", counter)\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tflusher.Flush()\n\t\t\tcounter++\n\t\t}\n\t}\n}\n\nfunc healthHandler() http.HandlerFunc {\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\tw.Write([]byte(\"ok\"))\n\t}\n}\n\nfunc rootHandler(serverName string) http.HandlerFunc {\n\tresponseTemplate := template.Must(template.New(\"index\").Parse(indexTemplate))\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\tvar buffer bytes.Buffer\n\t\tvar body string\n\t\trawBody, err := io.ReadAll(r.Body)\n\t\tif err == nil {\n\t\t\tbody = string(rawBody)\n\t\t} else {\n\t\t\tbody = \"\"\n\t\t}\n\t\terr = responseTemplate.Execute(&buffer, &templateData{\n\t\t\tServerName: serverName,\n\t\t\tRequest:    r,\n\t\t\tBody:       body,\n\t\t})\n\t\tif err != nil {\n\t\t\tw.WriteHeader(http.StatusInternalServerError)\n\t\t\t_, _ = fmt.Fprintf(w, \"error: %v\", err)\n\t\t} else {\n\t\t\t_, _ = buffer.WriteTo(w)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "hello/hello_test.go",
    "content": "package hello\n\nimport (\n\t\"testing\"\n)\n\nfunc TestCreateTLSListenerHostAndPortSuccess(t *testing.T) {\n\tlistener, err := CreateTLSListener(\"localhost:1234\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer listener.Close()\n\tif listener.Addr().String() == \"\" {\n\t\tt.Fatal(\"Fail to find available port\")\n\t}\n}\n\nfunc TestCreateTLSListenerOnlyHostSuccess(t *testing.T) {\n\tlistener, err := CreateTLSListener(\"localhost:\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer listener.Close()\n\tif listener.Addr().String() == \"\" {\n\t\tt.Fatal(\"Fail to find available port\")\n\t}\n}\n\nfunc TestCreateTLSListenerOnlyPortSuccess(t *testing.T) {\n\tlistener, err := CreateTLSListener(\"localhost:8888\")\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer listener.Close()\n\tif listener.Addr().String() == \"\" {\n\t\tt.Fatal(\"Fail to find available port\")\n\t}\n}\n"
  },
  {
    "path": "ingress/config.go",
    "content": "package ingress\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/ipaccess\"\n\t\"github.com/cloudflare/cloudflared/tlsconfig\"\n)\n\nvar (\n\tdefaultHTTPConnectTimeout        = config.CustomDuration{Duration: 30 * time.Second}\n\tdefaultWarpRoutingConnectTimeout = config.CustomDuration{Duration: 5 * time.Second}\n\tdefaultTLSTimeout                = config.CustomDuration{Duration: 10 * time.Second}\n\tdefaultTCPKeepAlive              = config.CustomDuration{Duration: 30 * time.Second}\n\tdefaultKeepAliveTimeout          = config.CustomDuration{Duration: 90 * time.Second}\n)\n\nconst (\n\tdefaultProxyAddress           = \"127.0.0.1\"\n\tdefaultKeepAliveConnections   = 100\n\tdefaultMaxActiveFlows         = 0 // unlimited\n\tSSHServerFlag                 = \"ssh-server\"\n\tSocks5Flag                    = \"socks5\"\n\tProxyConnectTimeoutFlag       = \"proxy-connect-timeout\"\n\tProxyTLSTimeoutFlag           = \"proxy-tls-timeout\"\n\tProxyTCPKeepAliveFlag         = \"proxy-tcp-keepalive\"\n\tProxyNoHappyEyeballsFlag      = \"proxy-no-happy-eyeballs\"\n\tProxyKeepAliveConnectionsFlag = \"proxy-keepalive-connections\"\n\tProxyKeepAliveTimeoutFlag     = \"proxy-keepalive-timeout\"\n\tHTTPHostHeaderFlag            = \"http-host-header\"\n\tOriginServerNameFlag          = \"origin-server-name\"\n\tMatchSNIToHostFlag            = \"match-sni-to-host\"\n\tNoTLSVerifyFlag               = \"no-tls-verify\"\n\tNoChunkedEncodingFlag         = \"no-chunked-encoding\"\n\tProxyAddressFlag              = \"proxy-address\"\n\tProxyPortFlag                 = \"proxy-port\"\n\tHttp2OriginFlag               = \"http2-origin\"\n)\n\nconst (\n\tsocksProxy = \"socks\"\n)\n\ntype WarpRoutingConfig struct {\n\tConnectTimeout config.CustomDuration `yaml:\"connectTimeout\" json:\"connectTimeout,omitempty\"`\n\tMaxActiveFlows uint64                `yaml:\"maxActiveFlows\" json:\"MaxActiveFlows,omitempty\"`\n\tTCPKeepAlive   config.CustomDuration `yaml:\"tcpKeepAlive\" json:\"tcpKeepAlive,omitempty\"`\n}\n\nfunc NewWarpRoutingConfig(raw *config.WarpRoutingConfig) WarpRoutingConfig {\n\tcfg := WarpRoutingConfig{\n\t\tConnectTimeout: defaultWarpRoutingConnectTimeout,\n\t\tMaxActiveFlows: defaultMaxActiveFlows,\n\t\tTCPKeepAlive:   defaultTCPKeepAlive,\n\t}\n\tif raw.ConnectTimeout != nil {\n\t\tcfg.ConnectTimeout = *raw.ConnectTimeout\n\t}\n\tif raw.MaxActiveFlows != nil {\n\t\tcfg.MaxActiveFlows = *raw.MaxActiveFlows\n\t}\n\tif raw.TCPKeepAlive != nil {\n\t\tcfg.TCPKeepAlive = *raw.TCPKeepAlive\n\t}\n\treturn cfg\n}\n\nfunc (c *WarpRoutingConfig) RawConfig() config.WarpRoutingConfig {\n\traw := config.WarpRoutingConfig{}\n\tif c.ConnectTimeout.Duration != defaultWarpRoutingConnectTimeout.Duration {\n\t\traw.ConnectTimeout = &c.ConnectTimeout\n\t}\n\tif c.MaxActiveFlows != defaultMaxActiveFlows {\n\t\traw.MaxActiveFlows = &c.MaxActiveFlows\n\t}\n\tif c.TCPKeepAlive.Duration != defaultTCPKeepAlive.Duration {\n\t\traw.TCPKeepAlive = &c.TCPKeepAlive\n\t}\n\treturn raw\n}\n\n// RemoteConfig models ingress settings that can be managed remotely, for example through the dashboard.\ntype RemoteConfig struct {\n\tIngress     Ingress\n\tWarpRouting WarpRoutingConfig\n}\n\ntype RemoteConfigJSON struct {\n\tGlobalOriginRequest *config.OriginRequestConfig     `json:\"originRequest,omitempty\"`\n\tIngressRules        []config.UnvalidatedIngressRule `json:\"ingress\"`\n\tWarpRouting         config.WarpRoutingConfig        `json:\"warp-routing\"`\n}\n\nfunc (rc *RemoteConfig) UnmarshalJSON(b []byte) error {\n\tvar rawConfig RemoteConfigJSON\n\n\tif err := json.Unmarshal(b, &rawConfig); err != nil {\n\t\treturn err\n\t}\n\n\t// if nil, just assume the default values.\n\tglobalOriginRequestConfig := rawConfig.GlobalOriginRequest\n\tif globalOriginRequestConfig == nil {\n\t\tglobalOriginRequestConfig = &config.OriginRequestConfig{}\n\t}\n\n\tingress, err := validateIngress(rawConfig.IngressRules, originRequestFromConfig(*globalOriginRequestConfig))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\trc.Ingress = ingress\n\trc.WarpRouting = NewWarpRoutingConfig(&rawConfig.WarpRouting)\n\n\treturn nil\n}\n\nfunc originRequestFromSingleRule(c *cli.Context) OriginRequestConfig {\n\tvar connectTimeout = defaultHTTPConnectTimeout\n\tvar tlsTimeout = defaultTLSTimeout\n\tvar tcpKeepAlive = defaultTCPKeepAlive\n\tvar noHappyEyeballs bool\n\tvar keepAliveConnections = defaultKeepAliveConnections\n\tvar keepAliveTimeout = defaultKeepAliveTimeout\n\tvar httpHostHeader string\n\tvar originServerName string\n\tvar matchSNItoHost bool\n\tvar caPool string\n\tvar noTLSVerify bool\n\tvar disableChunkedEncoding bool\n\tvar bastionMode bool\n\tvar proxyAddress = defaultProxyAddress\n\tvar proxyPort uint\n\tvar proxyType string\n\tvar http2Origin bool\n\tif flag := ProxyConnectTimeoutFlag; c.IsSet(flag) {\n\t\tconnectTimeout = config.CustomDuration{Duration: c.Duration(flag)}\n\t}\n\tif flag := ProxyTLSTimeoutFlag; c.IsSet(flag) {\n\t\ttlsTimeout = config.CustomDuration{Duration: c.Duration(flag)}\n\t}\n\tif flag := ProxyTCPKeepAliveFlag; c.IsSet(flag) {\n\t\ttcpKeepAlive = config.CustomDuration{Duration: c.Duration(flag)}\n\t}\n\tif flag := ProxyNoHappyEyeballsFlag; c.IsSet(flag) {\n\t\tnoHappyEyeballs = c.Bool(flag)\n\t}\n\tif flag := ProxyKeepAliveConnectionsFlag; c.IsSet(flag) {\n\t\tkeepAliveConnections = c.Int(flag)\n\t}\n\tif flag := ProxyKeepAliveTimeoutFlag; c.IsSet(flag) {\n\t\tkeepAliveTimeout = config.CustomDuration{Duration: c.Duration(flag)}\n\t}\n\tif flag := HTTPHostHeaderFlag; c.IsSet(flag) {\n\t\thttpHostHeader = c.String(flag)\n\t}\n\tif flag := OriginServerNameFlag; c.IsSet(flag) {\n\t\toriginServerName = c.String(flag)\n\t}\n\tif flag := MatchSNIToHostFlag; c.IsSet(flag) {\n\t\tmatchSNItoHost = c.Bool(flag)\n\t}\n\tif flag := tlsconfig.OriginCAPoolFlag; c.IsSet(flag) {\n\t\tcaPool = c.String(flag)\n\t}\n\tif flag := NoTLSVerifyFlag; c.IsSet(flag) {\n\t\tnoTLSVerify = c.Bool(flag)\n\t}\n\tif flag := NoChunkedEncodingFlag; c.IsSet(flag) {\n\t\tdisableChunkedEncoding = c.Bool(flag)\n\t}\n\tif flag := config.BastionFlag; c.IsSet(flag) {\n\t\tbastionMode = c.Bool(flag)\n\t}\n\tif flag := ProxyAddressFlag; c.IsSet(flag) {\n\t\tproxyAddress = c.String(flag)\n\t}\n\tif flag := ProxyPortFlag; c.IsSet(flag) {\n\t\t// Note TUN-3758 , we use Int because UInt is not supported with altsrc\n\t\t// nolint: gosec\n\t\tproxyPort = uint(c.Int(flag))\n\t}\n\tif flag := Http2OriginFlag; c.IsSet(flag) {\n\t\thttp2Origin = c.Bool(flag)\n\t}\n\tif c.IsSet(Socks5Flag) {\n\t\tproxyType = socksProxy\n\t}\n\n\treturn OriginRequestConfig{\n\t\tConnectTimeout:         connectTimeout,\n\t\tTLSTimeout:             tlsTimeout,\n\t\tTCPKeepAlive:           tcpKeepAlive,\n\t\tNoHappyEyeballs:        noHappyEyeballs,\n\t\tKeepAliveConnections:   keepAliveConnections,\n\t\tKeepAliveTimeout:       keepAliveTimeout,\n\t\tHTTPHostHeader:         httpHostHeader,\n\t\tOriginServerName:       originServerName,\n\t\tMatchSNIToHost:         matchSNItoHost,\n\t\tCAPool:                 caPool,\n\t\tNoTLSVerify:            noTLSVerify,\n\t\tDisableChunkedEncoding: disableChunkedEncoding,\n\t\tBastionMode:            bastionMode,\n\t\tProxyAddress:           proxyAddress,\n\t\tProxyPort:              proxyPort,\n\t\tProxyType:              proxyType,\n\t\tHttp2Origin:            http2Origin,\n\t}\n}\n\nfunc originRequestFromConfig(c config.OriginRequestConfig) OriginRequestConfig {\n\tout := OriginRequestConfig{\n\t\tConnectTimeout:       defaultHTTPConnectTimeout,\n\t\tTLSTimeout:           defaultTLSTimeout,\n\t\tTCPKeepAlive:         defaultTCPKeepAlive,\n\t\tKeepAliveConnections: defaultKeepAliveConnections,\n\t\tKeepAliveTimeout:     defaultKeepAliveTimeout,\n\t\tProxyAddress:         defaultProxyAddress,\n\t}\n\tif c.ConnectTimeout != nil {\n\t\tout.ConnectTimeout = *c.ConnectTimeout\n\t}\n\tif c.TLSTimeout != nil {\n\t\tout.TLSTimeout = *c.TLSTimeout\n\t}\n\tif c.TCPKeepAlive != nil {\n\t\tout.TCPKeepAlive = *c.TCPKeepAlive\n\t}\n\tif c.NoHappyEyeballs != nil {\n\t\tout.NoHappyEyeballs = *c.NoHappyEyeballs\n\t}\n\tif c.KeepAliveConnections != nil {\n\t\tout.KeepAliveConnections = *c.KeepAliveConnections\n\t}\n\tif c.KeepAliveTimeout != nil {\n\t\tout.KeepAliveTimeout = *c.KeepAliveTimeout\n\t}\n\tif c.HTTPHostHeader != nil {\n\t\tout.HTTPHostHeader = *c.HTTPHostHeader\n\t}\n\tif c.OriginServerName != nil {\n\t\tout.OriginServerName = *c.OriginServerName\n\t}\n\tif c.MatchSNIToHost != nil {\n\t\tout.MatchSNIToHost = *c.MatchSNIToHost\n\t}\n\tif c.CAPool != nil {\n\t\tout.CAPool = *c.CAPool\n\t}\n\tif c.NoTLSVerify != nil {\n\t\tout.NoTLSVerify = *c.NoTLSVerify\n\t}\n\tif c.DisableChunkedEncoding != nil {\n\t\tout.DisableChunkedEncoding = *c.DisableChunkedEncoding\n\t}\n\tif c.BastionMode != nil {\n\t\tout.BastionMode = *c.BastionMode\n\t}\n\tif c.ProxyAddress != nil {\n\t\tout.ProxyAddress = *c.ProxyAddress\n\t}\n\tif c.ProxyPort != nil {\n\t\tout.ProxyPort = *c.ProxyPort\n\t}\n\tif c.ProxyType != nil {\n\t\tout.ProxyType = *c.ProxyType\n\t}\n\tif len(c.IPRules) > 0 {\n\t\tfor _, r := range c.IPRules {\n\t\t\trule, err := ipaccess.NewRuleByCIDR(r.Prefix, r.Ports, r.Allow)\n\t\t\tif err == nil {\n\t\t\t\tout.IPRules = append(out.IPRules, rule)\n\t\t\t}\n\t\t}\n\t}\n\tif c.Http2Origin != nil {\n\t\tout.Http2Origin = *c.Http2Origin\n\t}\n\tif c.Access != nil {\n\t\tout.Access = *c.Access\n\t}\n\treturn out\n}\n\n// OriginRequestConfig configures how Cloudflared sends requests to origin\n// services.\n// Note: To specify a time.Duration in go-yaml, use e.g. \"3s\" or \"24h\".\ntype OriginRequestConfig struct {\n\t// HTTP proxy timeout for establishing a new connection\n\tConnectTimeout config.CustomDuration `yaml:\"connectTimeout\" json:\"connectTimeout\"`\n\t// HTTP proxy timeout for completing a TLS handshake\n\tTLSTimeout config.CustomDuration `yaml:\"tlsTimeout\" json:\"tlsTimeout\"`\n\t// HTTP proxy TCP keepalive duration\n\tTCPKeepAlive config.CustomDuration `yaml:\"tcpKeepAlive\" json:\"tcpKeepAlive\"`\n\t// HTTP proxy should disable \"happy eyeballs\" for IPv4/v6 fallback\n\tNoHappyEyeballs bool `yaml:\"noHappyEyeballs\" json:\"noHappyEyeballs\"`\n\t// HTTP proxy timeout for closing an idle connection\n\tKeepAliveTimeout config.CustomDuration `yaml:\"keepAliveTimeout\" json:\"keepAliveTimeout\"`\n\t// HTTP proxy maximum keepalive connection pool size\n\tKeepAliveConnections int `yaml:\"keepAliveConnections\" json:\"keepAliveConnections\"`\n\t// Sets the HTTP Host header for the local webserver.\n\tHTTPHostHeader string `yaml:\"httpHostHeader\" json:\"httpHostHeader\"`\n\t// Hostname on the origin server certificate.\n\tOriginServerName string `yaml:\"originServerName\" json:\"originServerName\"`\n\t// Auto configure the Hostname on the origin server certificate.\n\tMatchSNIToHost bool `yaml:\"matchSNItoHost\" json:\"matchSNItoHost\"`\n\t// Path to the CA for the certificate of your origin.\n\t// This option should be used only if your certificate is not signed by Cloudflare.\n\tCAPool string `yaml:\"caPool\" json:\"caPool\"`\n\t// Disables TLS verification of the certificate presented by your origin.\n\t// Will allow any certificate from the origin to be accepted.\n\t// Note: The connection from your machine to Cloudflare's Edge is still encrypted.\n\tNoTLSVerify bool `yaml:\"noTLSVerify\" json:\"noTLSVerify\"`\n\t// Disables chunked transfer encoding.\n\t// Useful if you are running a WSGI server.\n\tDisableChunkedEncoding bool `yaml:\"disableChunkedEncoding\" json:\"disableChunkedEncoding\"`\n\t// Runs as jump host\n\tBastionMode bool `yaml:\"bastionMode\" json:\"bastionMode\"`\n\t// Listen address for the proxy.\n\tProxyAddress string `yaml:\"proxyAddress\" json:\"proxyAddress\"`\n\t// Listen port for the proxy.\n\tProxyPort uint `yaml:\"proxyPort\" json:\"proxyPort\"`\n\t// What sort of proxy should be started\n\tProxyType string `yaml:\"proxyType\" json:\"proxyType\"`\n\t// IP rules for the proxy service\n\tIPRules []ipaccess.Rule `yaml:\"ipRules\" json:\"ipRules\"`\n\t// Attempt to connect to origin with HTTP/2\n\tHttp2Origin bool `yaml:\"http2Origin\" json:\"http2Origin\"`\n\n\t// Access holds all access related configs\n\tAccess config.AccessConfig `yaml:\"access\" json:\"access,omitempty\"`\n}\n\nfunc (defaults *OriginRequestConfig) setConnectTimeout(overrides config.OriginRequestConfig) {\n\tif val := overrides.ConnectTimeout; val != nil {\n\t\tdefaults.ConnectTimeout = *val\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setTLSTimeout(overrides config.OriginRequestConfig) {\n\tif val := overrides.TLSTimeout; val != nil {\n\t\tdefaults.TLSTimeout = *val\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setNoHappyEyeballs(overrides config.OriginRequestConfig) {\n\tif val := overrides.NoHappyEyeballs; val != nil {\n\t\tdefaults.NoHappyEyeballs = *val\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setKeepAliveConnections(overrides config.OriginRequestConfig) {\n\tif val := overrides.KeepAliveConnections; val != nil {\n\t\tdefaults.KeepAliveConnections = *val\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setKeepAliveTimeout(overrides config.OriginRequestConfig) {\n\tif val := overrides.KeepAliveTimeout; val != nil {\n\t\tdefaults.KeepAliveTimeout = *val\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setTCPKeepAlive(overrides config.OriginRequestConfig) {\n\tif val := overrides.TCPKeepAlive; val != nil {\n\t\tdefaults.TCPKeepAlive = *val\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setHTTPHostHeader(overrides config.OriginRequestConfig) {\n\tif val := overrides.HTTPHostHeader; val != nil {\n\t\tdefaults.HTTPHostHeader = *val\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setOriginServerName(overrides config.OriginRequestConfig) {\n\tif val := overrides.OriginServerName; val != nil {\n\t\tdefaults.OriginServerName = *val\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setMatchSNIToHost(overrides config.OriginRequestConfig) {\n\tif val := overrides.MatchSNIToHost; val != nil {\n\t\tdefaults.MatchSNIToHost = *val\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setCAPool(overrides config.OriginRequestConfig) {\n\tif val := overrides.CAPool; val != nil {\n\t\tdefaults.CAPool = *val\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setNoTLSVerify(overrides config.OriginRequestConfig) {\n\tif val := overrides.NoTLSVerify; val != nil {\n\t\tdefaults.NoTLSVerify = *val\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setDisableChunkedEncoding(overrides config.OriginRequestConfig) {\n\tif val := overrides.DisableChunkedEncoding; val != nil {\n\t\tdefaults.DisableChunkedEncoding = *val\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setBastionMode(overrides config.OriginRequestConfig) {\n\tif val := overrides.BastionMode; val != nil {\n\t\tdefaults.BastionMode = *val\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setProxyPort(overrides config.OriginRequestConfig) {\n\tif val := overrides.ProxyPort; val != nil {\n\t\tdefaults.ProxyPort = *val\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setProxyAddress(overrides config.OriginRequestConfig) {\n\tif val := overrides.ProxyAddress; val != nil {\n\t\tdefaults.ProxyAddress = *val\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setProxyType(overrides config.OriginRequestConfig) {\n\tif val := overrides.ProxyType; val != nil {\n\t\tdefaults.ProxyType = *val\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setIPRules(overrides config.OriginRequestConfig) {\n\tif val := overrides.IPRules; len(val) > 0 {\n\t\tipAccessRule := make([]ipaccess.Rule, len(overrides.IPRules))\n\t\tfor i, r := range overrides.IPRules {\n\t\t\trule, err := ipaccess.NewRuleByCIDR(r.Prefix, r.Ports, r.Allow)\n\t\t\tif err == nil {\n\t\t\t\tipAccessRule[i] = rule\n\t\t\t}\n\t\t}\n\t\tdefaults.IPRules = ipAccessRule\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setHttp2Origin(overrides config.OriginRequestConfig) {\n\tif val := overrides.Http2Origin; val != nil {\n\t\tdefaults.Http2Origin = *val\n\t}\n}\n\nfunc (defaults *OriginRequestConfig) setAccess(overrides config.OriginRequestConfig) {\n\tif val := overrides.Access; val != nil {\n\t\tdefaults.Access = *val\n\t}\n}\n\n// SetConfig gets config for the requests that cloudflared sends to origins.\n// Each field has a setter method which sets a value for the field by trying to find:\n//  1. The user config for this rule\n//  2. The user config for the overall ingress config\n//  3. Defaults chosen by the cloudflared team\n//  4. Golang zero values for that type\n//\n// If an earlier option isn't set, it will try the next option down.\nfunc setConfig(defaults OriginRequestConfig, overrides config.OriginRequestConfig) OriginRequestConfig {\n\tcfg := defaults\n\tcfg.setConnectTimeout(overrides)\n\tcfg.setTLSTimeout(overrides)\n\tcfg.setNoHappyEyeballs(overrides)\n\tcfg.setKeepAliveConnections(overrides)\n\tcfg.setKeepAliveTimeout(overrides)\n\tcfg.setTCPKeepAlive(overrides)\n\tcfg.setHTTPHostHeader(overrides)\n\tcfg.setOriginServerName(overrides)\n\tcfg.setMatchSNIToHost(overrides)\n\tcfg.setCAPool(overrides)\n\tcfg.setNoTLSVerify(overrides)\n\tcfg.setDisableChunkedEncoding(overrides)\n\tcfg.setBastionMode(overrides)\n\tcfg.setProxyPort(overrides)\n\tcfg.setProxyAddress(overrides)\n\tcfg.setProxyType(overrides)\n\tcfg.setIPRules(overrides)\n\tcfg.setHttp2Origin(overrides)\n\tcfg.setAccess(overrides)\n\n\treturn cfg\n}\n\nfunc ConvertToRawOriginConfig(c OriginRequestConfig) config.OriginRequestConfig {\n\tvar connectTimeout *config.CustomDuration\n\tvar tlsTimeout *config.CustomDuration\n\tvar tcpKeepAlive *config.CustomDuration\n\tvar keepAliveConnections *int\n\tvar keepAliveTimeout *config.CustomDuration\n\tvar proxyAddress *string\n\tvar access *config.AccessConfig\n\n\tif c.ConnectTimeout != defaultHTTPConnectTimeout {\n\t\tconnectTimeout = &c.ConnectTimeout\n\t}\n\tif c.TLSTimeout != defaultTLSTimeout {\n\t\ttlsTimeout = &c.TLSTimeout\n\t}\n\tif c.TCPKeepAlive != defaultTCPKeepAlive {\n\t\ttcpKeepAlive = &c.TCPKeepAlive\n\t}\n\tif c.KeepAliveConnections != defaultKeepAliveConnections {\n\t\tkeepAliveConnections = &c.KeepAliveConnections\n\t}\n\tif c.KeepAliveTimeout != defaultKeepAliveTimeout {\n\t\tkeepAliveTimeout = &c.KeepAliveTimeout\n\t}\n\tif c.ProxyAddress != defaultProxyAddress {\n\t\tproxyAddress = &c.ProxyAddress\n\t}\n\tif c.Access.Required {\n\t\taccess = &c.Access\n\t}\n\n\treturn config.OriginRequestConfig{\n\t\tConnectTimeout:         connectTimeout,\n\t\tTLSTimeout:             tlsTimeout,\n\t\tTCPKeepAlive:           tcpKeepAlive,\n\t\tNoHappyEyeballs:        defaultBoolToNil(c.NoHappyEyeballs),\n\t\tKeepAliveConnections:   keepAliveConnections,\n\t\tKeepAliveTimeout:       keepAliveTimeout,\n\t\tHTTPHostHeader:         emptyStringToNil(c.HTTPHostHeader),\n\t\tOriginServerName:       emptyStringToNil(c.OriginServerName),\n\t\tMatchSNIToHost:         defaultBoolToNil(c.MatchSNIToHost),\n\t\tCAPool:                 emptyStringToNil(c.CAPool),\n\t\tNoTLSVerify:            defaultBoolToNil(c.NoTLSVerify),\n\t\tDisableChunkedEncoding: defaultBoolToNil(c.DisableChunkedEncoding),\n\t\tBastionMode:            defaultBoolToNil(c.BastionMode),\n\t\tProxyAddress:           proxyAddress,\n\t\tProxyPort:              zeroUIntToNil(c.ProxyPort),\n\t\tProxyType:              emptyStringToNil(c.ProxyType),\n\t\tIPRules:                convertToRawIPRules(c.IPRules),\n\t\tHttp2Origin:            defaultBoolToNil(c.Http2Origin),\n\t\tAccess:                 access,\n\t}\n}\n\nfunc convertToRawIPRules(ipRules []ipaccess.Rule) []config.IngressIPRule {\n\tresult := make([]config.IngressIPRule, 0)\n\tfor _, r := range ipRules {\n\t\tcidr := r.StringCIDR()\n\n\t\tnewRule := config.IngressIPRule{\n\t\t\tPrefix: &cidr,\n\t\t\tPorts:  r.Ports(),\n\t\t\tAllow:  r.RulePolicy(),\n\t\t}\n\n\t\tresult = append(result, newRule)\n\t}\n\n\treturn result\n}\n\nfunc defaultBoolToNil(b bool) *bool {\n\tif !b {\n\t\treturn nil\n\t}\n\n\treturn &b\n}\n\nfunc emptyStringToNil(s string) *string {\n\tif s == \"\" {\n\t\treturn nil\n\t}\n\n\treturn &s\n}\n\nfunc zeroUIntToNil(v uint) *uint {\n\tif v == 0 {\n\t\treturn nil\n\t}\n\n\treturn &v\n}\n"
  },
  {
    "path": "ingress/config_test.go",
    "content": "package ingress\n\nimport (\n\t\"encoding/json\"\n\t\"flag\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/require\"\n\t\"github.com/urfave/cli/v2\"\n\tyaml \"gopkg.in/yaml.v3\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/ipaccess\"\n)\n\n// Ensure that the nullable config from `config` package and the\n// non-nullable config from `ingress` package have the same number of\n// fields.\n// This test ensures that programmers didn't add a new field to\n// one struct and forget to add it to the other ;)\nfunc TestCorrespondingFields(t *testing.T) {\n\trequire.Equal(\n\t\tt,\n\t\tCountFields(t, config.OriginRequestConfig{}),\n\t\tCountFields(t, OriginRequestConfig{}),\n\t)\n}\n\nfunc CountFields(t *testing.T, val interface{}) int {\n\tb, err := yaml.Marshal(val)\n\trequire.NoError(t, err)\n\tm := make(map[string]interface{}, 0)\n\terr = yaml.Unmarshal(b, &m)\n\trequire.NoError(t, err)\n\treturn len(m)\n}\n\nfunc TestUnmarshalRemoteConfigOverridesGlobal(t *testing.T) {\n\trawConfig := []byte(`\n{\n    \"originRequest\": {\n        \"connectTimeout\": 90,\n\t\t\"noHappyEyeballs\": true\n    },\n    \"ingress\": [\n        {\n            \"hostname\": \"jira.cfops.com\",\n            \"service\": \"http://192.16.19.1:80\",\n            \"originRequest\": {\n                \"noTLSVerify\": true,\n                \"connectTimeout\": 10\n            }\n        },\n        {\n            \"service\": \"http_status:404\"\n        }\n    ],\n    \"warp-routing\": {\n        \"enabled\": true\n    }\n}\t\n`)\n\tvar remoteConfig RemoteConfig\n\terr := json.Unmarshal(rawConfig, &remoteConfig)\n\trequire.NoError(t, err)\n\trequire.True(t, remoteConfig.Ingress.Rules[0].Config.NoTLSVerify)\n\trequire.True(t, remoteConfig.Ingress.Defaults.NoHappyEyeballs)\n}\n\nfunc TestOriginRequestConfigOverrides(t *testing.T) {\n\tvalidate := func(ing Ingress) {\n\t\t// Rule 0 didn't override anything, so it inherits the user-specified\n\t\t// root-level configuration.\n\t\tactual0 := ing.Rules[0].Config\n\t\texpected0 := OriginRequestConfig{\n\t\t\tConnectTimeout:         config.CustomDuration{Duration: 1 * time.Minute},\n\t\t\tTLSTimeout:             config.CustomDuration{Duration: 1 * time.Second},\n\t\t\tTCPKeepAlive:           config.CustomDuration{Duration: 1 * time.Second},\n\t\t\tNoHappyEyeballs:        true,\n\t\t\tKeepAliveTimeout:       config.CustomDuration{Duration: 1 * time.Second},\n\t\t\tKeepAliveConnections:   1,\n\t\t\tHTTPHostHeader:         \"abc\",\n\t\t\tOriginServerName:       \"a1\",\n\t\t\tCAPool:                 \"/tmp/path0\",\n\t\t\tNoTLSVerify:            true,\n\t\t\tDisableChunkedEncoding: true,\n\t\t\tBastionMode:            true,\n\t\t\tProxyAddress:           \"127.1.2.3\",\n\t\t\tProxyPort:              uint(100),\n\t\t\tProxyType:              \"socks5\",\n\t\t\tIPRules: []ipaccess.Rule{\n\t\t\t\tnewIPRule(t, \"10.0.0.0/8\", []int{80, 8080}, false),\n\t\t\t\tnewIPRule(t, \"fc00::/7\", []int{443, 4443}, true),\n\t\t\t},\n\t\t}\n\t\trequire.Equal(t, expected0, actual0)\n\n\t\t// Rule 1 overrode all the root-level config.\n\t\tactual1 := ing.Rules[1].Config\n\t\texpected1 := OriginRequestConfig{\n\t\t\tConnectTimeout:         config.CustomDuration{Duration: 2 * time.Minute},\n\t\t\tTLSTimeout:             config.CustomDuration{Duration: 2 * time.Second},\n\t\t\tTCPKeepAlive:           config.CustomDuration{Duration: 2 * time.Second},\n\t\t\tNoHappyEyeballs:        false,\n\t\t\tKeepAliveTimeout:       config.CustomDuration{Duration: 2 * time.Second},\n\t\t\tKeepAliveConnections:   2,\n\t\t\tHTTPHostHeader:         \"def\",\n\t\t\tOriginServerName:       \"b2\",\n\t\t\tCAPool:                 \"/tmp/path1\",\n\t\t\tNoTLSVerify:            false,\n\t\t\tDisableChunkedEncoding: false,\n\t\t\tBastionMode:            false,\n\t\t\tProxyAddress:           \"interface\",\n\t\t\tProxyPort:              uint(200),\n\t\t\tProxyType:              \"\",\n\t\t\tIPRules: []ipaccess.Rule{\n\t\t\t\tnewIPRule(t, \"10.0.0.0/16\", []int{3000, 3030}, false),\n\t\t\t\tnewIPRule(t, \"192.16.0.0/24\", []int{5000, 5050}, true),\n\t\t\t},\n\t\t}\n\t\trequire.Equal(t, expected1, actual1)\n\t}\n\n\trulesYAML := `\noriginRequest:\n  connectTimeout: 1m\n  tlsTimeout: 1s\n  noHappyEyeballs: true\n  tcpKeepAlive: 1s\n  keepAliveConnections: 1\n  keepAliveTimeout: 1s\n  httpHostHeader: abc\n  originServerName: a1\n  caPool: /tmp/path0\n  noTLSVerify: true\n  disableChunkedEncoding: true\n  bastionMode: True\n  proxyAddress: 127.1.2.3\n  proxyPort: 100\n  proxyType: socks5\n  ipRules:\n  - prefix: \"10.0.0.0/8\"\n    ports:\n    - 80\n    - 8080\n    allow: false\n  - prefix: \"fc00::/7\"\n    ports:\n    - 443\n    - 4443\n    allow: true\ningress:\n- hostname: tun.example.com\n  service: https://localhost:8000\n- hostname: \"*\"\n  service: https://localhost:8001\n  originRequest:\n    connectTimeout: 2m\n    tlsTimeout: 2s\n    noHappyEyeballs: false\n    tcpKeepAlive: 2s\n    keepAliveConnections: 2\n    keepAliveTimeout: 2s\n    httpHostHeader: def\n    originServerName: b2\n    caPool: /tmp/path1\n    noTLSVerify: false\n    disableChunkedEncoding: false\n    bastionMode: false\n    proxyAddress: interface\n    proxyPort: 200\n    proxyType: \"\"\n    ipRules:\n    - prefix: \"10.0.0.0/16\"\n      ports:\n      - 3000\n      - 3030\n      allow: false\n    - prefix: \"192.16.0.0/24\"\n      ports:\n      - 5000\n      - 5050\n      allow: true\n`\n\n\ting, err := ParseIngress(MustReadIngress(rulesYAML))\n\trequire.NoError(t, err)\n\tvalidate(ing)\n\n\trawConfig := []byte(`\n{\n    \"originRequest\": {\n        \"connectTimeout\": 60,\n\t\t\"tlsTimeout\": 1,\n\t\t\"noHappyEyeballs\": true,\n\t\t\"tcpKeepAlive\": 1,\n\t\t\"keepAliveConnections\": 1,\n\t\t\"keepAliveTimeout\": 1,\n\t\t\"httpHostHeader\": \"abc\",\n\t\t\"originServerName\": \"a1\",\n\t\t\"caPool\": \"/tmp/path0\",\n\t\t\"noTLSVerify\": true,\n\t\t\"disableChunkedEncoding\": true,\n\t\t\"bastionMode\": true,\n\t\t\"proxyAddress\": \"127.1.2.3\",\n\t\t\"proxyPort\": 100,\n\t\t\"proxyType\": \"socks5\",\n\t\t\"ipRules\": [\n\t\t\t{\n\t\t\t\t\"prefix\": \"10.0.0.0/8\",\n\t\t\t\t\"ports\": [80, 8080],\n\t\t\t\t\"allow\": false\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"prefix\": \"fc00::/7\",\n\t\t\t\t\"ports\": [443, 4443],\n\t\t\t\t\"allow\": true\n\t\t\t}\n\t\t]\n    },\n    \"ingress\": [\n        {\n            \"hostname\": \"tun.example.com\",\n            \"service\": \"https://localhost:8000\"\n        },\n        {\n\t\t\t\"hostname\": \"*\",\n            \"service\": \"https://localhost:8001\",\n\t\t\t\"originRequest\": {\n\t\t\t\t\"connectTimeout\": 120,\n\t\t\t\t\"tlsTimeout\": 2,\n\t\t\t\t\"noHappyEyeballs\": false,\n\t\t\t\t\"tcpKeepAlive\": 2,\n\t\t\t\t\"keepAliveConnections\": 2,\n\t\t\t\t\"keepAliveTimeout\": 2,\n\t\t\t\t\"httpHostHeader\": \"def\",\n\t\t\t\t\"originServerName\": \"b2\",\n\t\t\t\t\"caPool\": \"/tmp/path1\",\n\t\t\t\t\"noTLSVerify\": false,\n\t\t\t\t\"disableChunkedEncoding\": false,\n\t\t\t\t\"bastionMode\": false,\n\t\t\t\t\"proxyAddress\": \"interface\",\n\t\t\t\t\"proxyPort\": 200,\n\t\t\t\t\"proxyType\": \"\",\n\t\t\t\t\"ipRules\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"prefix\": \"10.0.0.0/16\",\n\t\t\t\t\t\t\"ports\": [3000, 3030],\n\t\t\t\t\t\t\"allow\": false\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"prefix\": \"192.16.0.0/24\",\n\t\t\t\t\t\t\"ports\": [5000, 5050],\n\t\t\t\t\t\t\"allow\": true\n\t\t\t\t\t}\n\t\t\t\t]\n    \t\t}\n        }\n    ],\n    \"warp-routing\": {\n        \"enabled\": true\n    }\n}\t\n`)\n\tvar remoteConfig RemoteConfig\n\terr = json.Unmarshal(rawConfig, &remoteConfig)\n\trequire.NoError(t, err)\n\tvalidate(remoteConfig.Ingress)\n}\n\nfunc TestOriginRequestConfigDefaults(t *testing.T) {\n\tvalidate := func(ing Ingress) {\n\t\t// Rule 0 didn't override anything, so it inherits the cloudflared defaults\n\t\tactual0 := ing.Rules[0].Config\n\t\texpected0 := OriginRequestConfig{\n\t\t\tConnectTimeout:       defaultHTTPConnectTimeout,\n\t\t\tTLSTimeout:           defaultTLSTimeout,\n\t\t\tTCPKeepAlive:         defaultTCPKeepAlive,\n\t\t\tKeepAliveConnections: defaultKeepAliveConnections,\n\t\t\tKeepAliveTimeout:     defaultKeepAliveTimeout,\n\t\t\tProxyAddress:         defaultProxyAddress,\n\t\t}\n\t\trequire.Equal(t, expected0, actual0)\n\n\t\t// Rule 1 overrode all defaults.\n\t\tactual1 := ing.Rules[1].Config\n\t\texpected1 := OriginRequestConfig{\n\t\t\tConnectTimeout:         config.CustomDuration{Duration: 2 * time.Minute},\n\t\t\tTLSTimeout:             config.CustomDuration{Duration: 2 * time.Second},\n\t\t\tTCPKeepAlive:           config.CustomDuration{Duration: 2 * time.Second},\n\t\t\tNoHappyEyeballs:        false,\n\t\t\tKeepAliveTimeout:       config.CustomDuration{Duration: 2 * time.Second},\n\t\t\tKeepAliveConnections:   2,\n\t\t\tHTTPHostHeader:         \"def\",\n\t\t\tOriginServerName:       \"b2\",\n\t\t\tCAPool:                 \"/tmp/path1\",\n\t\t\tNoTLSVerify:            false,\n\t\t\tDisableChunkedEncoding: false,\n\t\t\tBastionMode:            false,\n\t\t\tProxyAddress:           \"interface\",\n\t\t\tProxyPort:              uint(200),\n\t\t\tProxyType:              \"\",\n\t\t\tIPRules: []ipaccess.Rule{\n\t\t\t\tnewIPRule(t, \"10.0.0.0/16\", []int{3000, 3030}, false),\n\t\t\t\tnewIPRule(t, \"192.16.0.0/24\", []int{5000, 5050}, true),\n\t\t\t},\n\t\t}\n\t\trequire.Equal(t, expected1, actual1)\n\t}\n\n\trulesYAML := `\ningress:\n- hostname: tun.example.com\n  service: https://localhost:8000\n- hostname: \"*\"\n  service: https://localhost:8001\n  originRequest:\n    connectTimeout: 2m\n    tlsTimeout: 2s\n    noHappyEyeballs: false\n    tcpKeepAlive: 2s\n    keepAliveConnections: 2\n    keepAliveTimeout: 2s\n    httpHostHeader: def\n    originServerName: b2\n    caPool: /tmp/path1\n    noTLSVerify: false\n    disableChunkedEncoding: false\n    bastionMode: false\n    proxyAddress: interface\n    proxyPort: 200\n    proxyType: \"\"\n    ipRules:\n    - prefix: \"10.0.0.0/16\"\n      ports:\n      - 3000\n      - 3030\n      allow: false\n    - prefix: \"192.16.0.0/24\"\n      ports:\n      - 5000\n      - 5050\n      allow: true\n`\n\ting, err := ParseIngress(MustReadIngress(rulesYAML))\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\tvalidate(ing)\n\n\trawConfig := []byte(`\n{\n\t\"ingress\": [\n        {\n            \"hostname\": \"tun.example.com\",\n            \"service\": \"https://localhost:8000\"\n        },\n        {\n\t\t\t\"hostname\": \"*\",\n            \"service\": \"https://localhost:8001\",\n\t\t\t\"originRequest\": {\n\t\t\t\t\"connectTimeout\": 120,\n\t\t\t\t\"tlsTimeout\": 2,\n\t\t\t\t\"noHappyEyeballs\": false,\n\t\t\t\t\"tcpKeepAlive\": 2,\n\t\t\t\t\"keepAliveConnections\": 2,\n\t\t\t\t\"keepAliveTimeout\": 2,\n\t\t\t\t\"httpHostHeader\": \"def\",\n\t\t\t\t\"originServerName\": \"b2\",\n\t\t\t\t\"caPool\": \"/tmp/path1\",\n\t\t\t\t\"noTLSVerify\": false,\n\t\t\t\t\"disableChunkedEncoding\": false,\n\t\t\t\t\"bastionMode\": false,\n\t\t\t\t\"proxyAddress\": \"interface\",\n\t\t\t\t\"proxyPort\": 200,\n\t\t\t\t\"proxyType\": \"\",\n\t\t\t\t\"ipRules\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"prefix\": \"10.0.0.0/16\",\n\t\t\t\t\t\t\"ports\": [3000, 3030],\n\t\t\t\t\t\t\"allow\": false\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"prefix\": \"192.16.0.0/24\",\n\t\t\t\t\t\t\"ports\": [5000, 5050],\n\t\t\t\t\t\t\"allow\": true\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t]\n}\n`)\n\n\tvar remoteConfig RemoteConfig\n\terr = json.Unmarshal(rawConfig, &remoteConfig)\n\trequire.NoError(t, err)\n\tvalidate(remoteConfig.Ingress)\n}\n\nfunc TestDefaultConfigFromCLI(t *testing.T) {\n\tset := flag.NewFlagSet(\"contrive\", 0)\n\tc := cli.NewContext(nil, set, nil)\n\n\texpected := OriginRequestConfig{\n\t\tConnectTimeout:       defaultHTTPConnectTimeout,\n\t\tTLSTimeout:           defaultTLSTimeout,\n\t\tTCPKeepAlive:         defaultTCPKeepAlive,\n\t\tKeepAliveConnections: defaultKeepAliveConnections,\n\t\tKeepAliveTimeout:     defaultKeepAliveTimeout,\n\t\tProxyAddress:         defaultProxyAddress,\n\t}\n\tactual := originRequestFromSingleRule(c)\n\trequire.Equal(t, expected, actual)\n}\n\nfunc newIPRule(t *testing.T, prefix string, ports []int, allow bool) ipaccess.Rule {\n\trule, err := ipaccess.NewRuleByCIDR(&prefix, ports, allow)\n\trequire.NoError(t, err)\n\treturn rule\n}\n"
  },
  {
    "path": "ingress/constants_test.go",
    "content": "package ingress\n\nimport \"github.com/cloudflare/cloudflared/logger\"\n\nvar (\n\tTestLogger = logger.Create(nil)\n)\n"
  },
  {
    "path": "ingress/icmp_darwin.go",
    "content": "//go:build darwin\n\npackage ingress\n\n// This file implements ICMPProxy for Darwin. It uses a non-privileged ICMP socket to send echo requests and listen for\n// echo replies. The source IP of the requests are rewritten to the bind IP of the socket and the socket reads all\n// messages, so we use echo ID to distinguish the replies. Each (source IP, destination IP, echo ID) is assigned a\n// unique echo ID.\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"math\"\n\t\"net/netip\"\n\t\"strconv\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/rs/zerolog\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"golang.org/x/net/icmp\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n)\n\ntype icmpProxy struct {\n\tsrcFunnelTracker *packet.FunnelTracker\n\techoIDTracker    *echoIDTracker\n\tconn             *icmp.PacketConn\n\tlogger           *zerolog.Logger\n\tidleTimeout      time.Duration\n}\n\n// echoIDTracker tracks which ID has been assigned. It first loops through assignment from lastAssignment to then end,\n// then from the beginning to lastAssignment.\n// ICMP echo are short lived. By the time an ID is revisited, it should have been released.\ntype echoIDTracker struct {\n\tlock sync.Mutex\n\t// maps the source IP, destination IP and original echo ID to a unique echo ID obtained from assignment\n\tmapping map[flow3Tuple]uint16\n\t// assignment tracks if an ID is assigned using index as the ID\n\t// The size of the array is math.MaxUint16 because echo ID is 2 bytes\n\tassignment [math.MaxUint16]bool\n\t// nextAssignment is the next number to check for assigment\n\tnextAssignment uint16\n}\n\nfunc newEchoIDTracker() *echoIDTracker {\n\treturn &echoIDTracker{\n\t\tmapping: make(map[flow3Tuple]uint16),\n\t}\n}\n\n// Get assignment or assign a new ID.\nfunc (eit *echoIDTracker) getOrAssign(key flow3Tuple) (id uint16, success bool) {\n\teit.lock.Lock()\n\tdefer eit.lock.Unlock()\n\tid, exists := eit.mapping[key]\n\tif exists {\n\t\treturn id, true\n\t}\n\n\tif eit.nextAssignment == math.MaxUint16 {\n\t\teit.nextAssignment = 0\n\t}\n\n\tfor i, assigned := range eit.assignment[eit.nextAssignment:] {\n\t\tif !assigned {\n\t\t\techoID := uint16(i) + eit.nextAssignment\n\t\t\teit.set(key, echoID)\n\t\t\treturn echoID, true\n\t\t}\n\t}\n\tfor i, assigned := range eit.assignment[0:eit.nextAssignment] {\n\t\tif !assigned {\n\t\t\techoID := uint16(i)\n\t\t\teit.set(key, echoID)\n\t\t\treturn echoID, true\n\t\t}\n\t}\n\treturn 0, false\n}\n\n// Caller should hold the lock\nfunc (eit *echoIDTracker) set(key flow3Tuple, assignedEchoID uint16) {\n\teit.assignment[assignedEchoID] = true\n\teit.mapping[key] = assignedEchoID\n\teit.nextAssignment = assignedEchoID + 1\n}\n\nfunc (eit *echoIDTracker) release(key flow3Tuple, assigned uint16) bool {\n\teit.lock.Lock()\n\tdefer eit.lock.Unlock()\n\n\tcurrentEchoID, exists := eit.mapping[key]\n\tif exists && assigned == currentEchoID {\n\t\tdelete(eit.mapping, key)\n\t\teit.assignment[assigned] = false\n\t\treturn true\n\t}\n\treturn false\n}\n\ntype echoFunnelID uint16\n\nfunc (snf echoFunnelID) Type() string {\n\treturn \"echoID\"\n}\n\nfunc (snf echoFunnelID) String() string {\n\treturn strconv.FormatUint(uint64(snf), 10)\n}\n\nfunc newICMPProxy(listenIP netip.Addr, logger *zerolog.Logger, idleTimeout time.Duration) (*icmpProxy, error) {\n\tconn, err := newICMPConn(listenIP)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tlogger.Info().Msgf(\"Created ICMP proxy listening on %s\", conn.LocalAddr())\n\treturn &icmpProxy{\n\t\tsrcFunnelTracker: packet.NewFunnelTracker(),\n\t\techoIDTracker:    newEchoIDTracker(),\n\t\tconn:             conn,\n\t\tlogger:           logger,\n\t\tidleTimeout:      idleTimeout,\n\t}, nil\n}\n\nfunc (ip *icmpProxy) Request(ctx context.Context, pk *packet.ICMP, responder ICMPResponder) error {\n\t_, span := responder.RequestSpan(ctx, pk)\n\tdefer responder.ExportSpan()\n\n\toriginalEcho, err := getICMPEcho(pk.Message)\n\tif err != nil {\n\t\ttracing.EndWithErrorStatus(span, err)\n\t\treturn err\n\t}\n\tobserveICMPRequest(ip.logger, span, pk.Src.String(), pk.Dst.String(), originalEcho.ID, originalEcho.Seq)\n\n\techoIDTrackerKey := flow3Tuple{\n\t\tsrcIP:          pk.Src,\n\t\tdstIP:          pk.Dst,\n\t\toriginalEchoID: originalEcho.ID,\n\t}\n\tassignedEchoID, success := ip.echoIDTracker.getOrAssign(echoIDTrackerKey)\n\tif !success {\n\t\terr := fmt.Errorf(\"failed to assign unique echo ID\")\n\t\ttracing.EndWithErrorStatus(span, err)\n\t\treturn err\n\t}\n\tspan.SetAttributes(attribute.Int(\"assignedEchoID\", int(assignedEchoID)))\n\n\tshouldReplaceFunnelFunc := createShouldReplaceFunnelFunc(ip.logger, responder, pk, originalEcho.ID)\n\tnewFunnelFunc := func() (packet.Funnel, error) {\n\t\toriginalEcho, err := getICMPEcho(pk.Message)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcloseCallback := func() error {\n\t\t\tip.echoIDTracker.release(echoIDTrackerKey, assignedEchoID)\n\t\t\treturn nil\n\t\t}\n\t\ticmpFlow := newICMPEchoFlow(pk.Src, closeCallback, ip.conn, responder, int(assignedEchoID), originalEcho.ID)\n\t\treturn icmpFlow, nil\n\t}\n\tfunnelID := echoFunnelID(assignedEchoID)\n\tfunnel, isNew, err := ip.srcFunnelTracker.GetOrRegister(funnelID, shouldReplaceFunnelFunc, newFunnelFunc)\n\tif err != nil {\n\t\ttracing.EndWithErrorStatus(span, err)\n\t\treturn err\n\t}\n\tif isNew {\n\t\tspan.SetAttributes(attribute.Bool(\"newFlow\", true))\n\t\tip.logger.Debug().\n\t\t\tStr(\"src\", pk.Src.String()).\n\t\t\tStr(\"dst\", pk.Dst.String()).\n\t\t\tInt(\"originalEchoID\", originalEcho.ID).\n\t\t\tInt(\"assignedEchoID\", int(assignedEchoID)).\n\t\t\tMsg(\"New flow\")\n\t}\n\ticmpFlow, err := toICMPEchoFlow(funnel)\n\tif err != nil {\n\t\ttracing.EndWithErrorStatus(span, err)\n\t\treturn err\n\t}\n\n\terr = icmpFlow.sendToDst(pk.Dst, pk.Message)\n\tif err != nil {\n\t\ttracing.EndWithErrorStatus(span, err)\n\t\treturn err\n\t}\n\ttracing.End(span)\n\treturn nil\n}\n\n// Serve listens for responses to the requests until context is done\nfunc (ip *icmpProxy) Serve(ctx context.Context) error {\n\tgo func() {\n\t\t<-ctx.Done()\n\t\tip.conn.Close()\n\t}()\n\tgo func() {\n\t\tip.srcFunnelTracker.ScheduleCleanup(ctx, ip.idleTimeout)\n\t}()\n\tbuf := make([]byte, mtu)\n\ticmpDecoder := packet.NewICMPDecoder()\n\tfor {\n\t\tn, from, err := ip.conn.ReadFrom(buf)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treply, err := parseReply(from, buf[:n])\n\t\tif err != nil {\n\t\t\tip.logger.Debug().Err(err).Str(\"dst\", from.String()).Msg(\"Failed to parse ICMP reply, continue to parse as full packet\")\n\t\t\t// In unit test, we found out when the listener listens on 0.0.0.0, the socket reads the full packet after\n\t\t\t// the second reply\n\t\t\tif err := ip.handleFullPacket(ctx, icmpDecoder, buf[:n]); err != nil {\n\t\t\t\tip.logger.Debug().Err(err).Str(\"dst\", from.String()).Msg(\"Failed to parse ICMP reply as full packet\")\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif !isEchoReply(reply.msg) {\n\t\t\tip.logger.Debug().Str(\"dst\", from.String()).Msgf(\"Drop ICMP %s from reply\", reply.msg.Type)\n\t\t\tcontinue\n\t\t}\n\t\tif err := ip.sendReply(ctx, reply); err != nil {\n\t\t\tip.logger.Debug().Err(err).Str(\"dst\", from.String()).Msg(\"Failed to send ICMP reply\")\n\t\t\tcontinue\n\t\t}\n\t}\n}\n\nfunc (ip *icmpProxy) handleFullPacket(ctx context.Context, decoder *packet.ICMPDecoder, rawPacket []byte) error {\n\ticmpPacket, err := decoder.Decode(packet.RawPacket{Data: rawPacket})\n\tif err != nil {\n\t\treturn err\n\t}\n\techo, err := getICMPEcho(icmpPacket.Message)\n\tif err != nil {\n\t\treturn err\n\t}\n\treply := echoReply{\n\t\tfrom: icmpPacket.Src,\n\t\tmsg:  icmpPacket.Message,\n\t\techo: echo,\n\t}\n\tif ip.sendReply(ctx, &reply); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (ip *icmpProxy) sendReply(ctx context.Context, reply *echoReply) error {\n\tfunnelID := echoFunnelID(reply.echo.ID)\n\tfunnel, ok := ip.srcFunnelTracker.Get(funnelID)\n\tif !ok {\n\t\treturn packet.ErrFunnelNotFound\n\t}\n\ticmpFlow, err := toICMPEchoFlow(funnel)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_, span := icmpFlow.responder.ReplySpan(ctx, ip.logger)\n\tdefer icmpFlow.responder.ExportSpan()\n\n\tif err := icmpFlow.returnToSrc(reply); err != nil {\n\t\ttracing.EndWithErrorStatus(span, err)\n\t\treturn err\n\t}\n\tobserveICMPReply(ip.logger, span, reply.from.String(), reply.echo.ID, reply.echo.Seq)\n\tspan.SetAttributes(attribute.Int(\"originalEchoID\", icmpFlow.originalEchoID))\n\ttracing.End(span)\n\treturn nil\n}\n"
  },
  {
    "path": "ingress/icmp_darwin_test.go",
    "content": "//go:build darwin\n\npackage ingress\n\nimport (\n\t\"math\"\n\t\"net/netip\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n)\n\nfunc TestSingleEchoIDTracker(t *testing.T) {\n\ttracker := newEchoIDTracker()\n\tkey := flow3Tuple{\n\t\tsrcIP:          netip.MustParseAddr(\"172.16.0.1\"),\n\t\tdstIP:          netip.MustParseAddr(\"172.16.0.2\"),\n\t\toriginalEchoID: 5182,\n\t}\n\n\t// not assigned yet, so nothing to release\n\trequire.False(t, tracker.release(key, 0))\n\n\techoID, ok := tracker.getOrAssign(key)\n\trequire.True(t, ok)\n\trequire.Equal(t, uint16(0), echoID)\n\n\t//  Second time should return the same echo ID\n\techoID, ok = tracker.getOrAssign(key)\n\trequire.True(t, ok)\n\trequire.Equal(t, uint16(0), echoID)\n\n\t// releasing a different ID returns false\n\trequire.False(t, tracker.release(key, 1999))\n\trequire.True(t, tracker.release(key, echoID))\n\t// releasing the second time returns false\n\trequire.False(t, tracker.release(key, echoID))\n\n\t// Move to the next IP\n\techoID, ok = tracker.getOrAssign(key)\n\trequire.True(t, ok)\n\trequire.Equal(t, uint16(1), echoID)\n}\n\nfunc TestFullEchoIDTracker(t *testing.T) {\n\tvar (\n\t\tdstIP          = netip.MustParseAddr(\"192.168.0.1\")\n\t\toriginalEchoID = 41820\n\t)\n\ttracker := newEchoIDTracker()\n\tfirstSrcIP := netip.MustParseAddr(\"172.16.0.1\")\n\tsrcIP := firstSrcIP\n\n\tfor i := uint16(0); i < math.MaxUint16; i++ {\n\t\tkey := flow3Tuple{\n\t\t\tsrcIP:          srcIP,\n\t\t\tdstIP:          dstIP,\n\t\t\toriginalEchoID: originalEchoID,\n\t\t}\n\t\techoID, ok := tracker.getOrAssign(key)\n\t\trequire.True(t, ok)\n\t\trequire.Equal(t, i, echoID)\n\n\t\techoID, ok = tracker.get(key)\n\t\trequire.True(t, ok)\n\t\trequire.Equal(t, i, echoID)\n\n\t\tsrcIP = srcIP.Next()\n\t}\n\n\tkey := flow3Tuple{\n\t\tsrcIP:          srcIP.Next(),\n\t\tdstIP:          dstIP,\n\t\toriginalEchoID: originalEchoID,\n\t}\n\t// All echo IDs are assigned\n\techoID, ok := tracker.getOrAssign(key)\n\trequire.False(t, ok)\n\trequire.Equal(t, uint16(0), echoID)\n\n\tsrcIP = firstSrcIP\n\tfor i := uint16(0); i < math.MaxUint16; i++ {\n\t\tkey := flow3Tuple{\n\t\t\tsrcIP:          srcIP,\n\t\t\tdstIP:          dstIP,\n\t\t\toriginalEchoID: originalEchoID,\n\t\t}\n\t\tok := tracker.release(key, i)\n\t\trequire.True(t, ok)\n\n\t\techoID, ok = tracker.get(key)\n\t\trequire.False(t, ok)\n\t\trequire.Equal(t, uint16(0), echoID)\n\t\tsrcIP = srcIP.Next()\n\t}\n\n\t// The IDs are assignable again\n\tsrcIP = firstSrcIP\n\tfor i := uint16(0); i < math.MaxUint16; i++ {\n\t\tkey := flow3Tuple{\n\t\t\tsrcIP:          srcIP,\n\t\t\tdstIP:          dstIP,\n\t\t\toriginalEchoID: originalEchoID,\n\t\t}\n\t\techoID, ok := tracker.getOrAssign(key)\n\t\trequire.True(t, ok)\n\t\trequire.Equal(t, i, echoID)\n\n\t\techoID, ok = tracker.get(key)\n\t\trequire.True(t, ok)\n\t\trequire.Equal(t, i, echoID)\n\t\tsrcIP = srcIP.Next()\n\t}\n}\n\nfunc (eit *echoIDTracker) get(key flow3Tuple) (id uint16, exist bool) {\n\teit.lock.Lock()\n\tdefer eit.lock.Unlock()\n\tid, exists := eit.mapping[key]\n\treturn id, exists\n}\n\nfunc getFunnel(t *testing.T, proxy *icmpProxy, tuple flow3Tuple) (packet.Funnel, bool) {\n\tassignedEchoID, success := proxy.echoIDTracker.getOrAssign(tuple)\n\trequire.True(t, success)\n\treturn proxy.srcFunnelTracker.Get(echoFunnelID(assignedEchoID))\n}\n"
  },
  {
    "path": "ingress/icmp_generic.go",
    "content": "//go:build !darwin && !linux && (!windows || !cgo)\n\npackage ingress\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/netip\"\n\t\"runtime\"\n\t\"time\"\n\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n)\n\nvar errICMPProxyNotImplemented = fmt.Errorf(\"ICMP proxy is not implemented on %s %s\", runtime.GOOS, runtime.GOARCH)\n\ntype icmpProxy struct{}\n\nfunc (ip icmpProxy) Request(ctx context.Context, pk *packet.ICMP, responder ICMPResponder) error {\n\treturn errICMPProxyNotImplemented\n}\n\nfunc (ip *icmpProxy) Serve(ctx context.Context) error {\n\treturn errICMPProxyNotImplemented\n}\n\nfunc newICMPProxy(listenIP netip.Addr, logger *zerolog.Logger, idleTimeout time.Duration) (*icmpProxy, error) {\n\treturn nil, errICMPProxyNotImplemented\n}\n"
  },
  {
    "path": "ingress/icmp_linux.go",
    "content": "//go:build linux\n\npackage ingress\n\n// This file implements ICMPProxy for Linux. Each (source IP, destination IP, echo ID) opens a non-privileged ICMP socket.\n// The source IP of the requests are rewritten to the bind IP of the socket and echo ID rewritten to the port number of\n// the socket. The kernel ensures the socket only reads replies whose echo ID matches the port number.\n// For more information about the socket, see https://man7.org/linux/man-pages/man7/icmp.7.html and https://lwn.net/Articles/422330/\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/netip\"\n\t\"os\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n)\n\nconst (\n\t// https://lwn.net/Articles/550551/ IPv4 and IPv6 share the same path\n\tpingGroupPath = \"/proc/sys/net/ipv4/ping_group_range\"\n)\n\nvar (\n\tfindGroupIDRegex = regexp.MustCompile(`\\d+`)\n)\n\ntype icmpProxy struct {\n\tsrcFunnelTracker *packet.FunnelTracker\n\tlistenIP         netip.Addr\n\tlogger           *zerolog.Logger\n\tidleTimeout      time.Duration\n}\n\nfunc newICMPProxy(listenIP netip.Addr, logger *zerolog.Logger, idleTimeout time.Duration) (*icmpProxy, error) {\n\tif err := testPermission(listenIP, logger); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &icmpProxy{\n\t\tsrcFunnelTracker: packet.NewFunnelTracker(),\n\t\tlistenIP:         listenIP,\n\t\tlogger:           logger,\n\t\tidleTimeout:      idleTimeout,\n\t}, nil\n}\n\nfunc testPermission(listenIP netip.Addr, logger *zerolog.Logger) error {\n\t// Opens a non-privileged ICMP socket. On Linux the group ID of the process needs to be in ping_group_range\n\t// Only check ping_group_range once for IPv4\n\tif listenIP.Is4() {\n\t\tif err := checkInPingGroup(); err != nil {\n\t\t\tlogger.Warn().Err(err).Msgf(\"The user running cloudflared process has a GID (group ID) that is not within ping_group_range. You might need to add that user to a group within that range, or instead update the range to encompass a group the user is already in by modifying %s. Otherwise cloudflared will not be able to ping this network\", pingGroupPath)\n\t\t\treturn err\n\t\t}\n\t}\n\tconn, err := newICMPConn(listenIP)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// This conn is only to test if cloudflared has permission to open this type of socket\n\tconn.Close()\n\treturn nil\n}\n\nfunc checkInPingGroup() error {\n\tfile, err := os.ReadFile(pingGroupPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\tgroupID := uint64(os.Getegid())\n\t// Example content: 999\t   59999\n\tfound := findGroupIDRegex.FindAll(file, 2)\n\tif len(found) == 2 {\n\t\tgroupMin, err := strconv.ParseUint(string(found[0]), 10, 32)\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"failed to determine minimum ping group ID\")\n\t\t}\n\t\tgroupMax, err := strconv.ParseUint(string(found[1]), 10, 32)\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"failed to determine maximum ping group ID\")\n\t\t}\n\t\tif groupID < groupMin || groupID > groupMax {\n\t\t\treturn fmt.Errorf(\"Group ID %d is not between ping group %d to %d\", groupID, groupMin, groupMax)\n\t\t}\n\t\treturn nil\n\t}\n\treturn fmt.Errorf(\"did not find group range in %s\", pingGroupPath)\n}\n\nfunc (ip *icmpProxy) Request(ctx context.Context, pk *packet.ICMP, responder ICMPResponder) error {\n\tctx, span := responder.RequestSpan(ctx, pk)\n\tdefer responder.ExportSpan()\n\n\toriginalEcho, err := getICMPEcho(pk.Message)\n\tif err != nil {\n\t\ttracing.EndWithErrorStatus(span, err)\n\t\treturn err\n\t}\n\tobserveICMPRequest(ip.logger, span, pk.Src.String(), pk.Dst.String(), originalEcho.ID, originalEcho.Seq)\n\n\tshouldReplaceFunnelFunc := createShouldReplaceFunnelFunc(ip.logger, responder, pk, originalEcho.ID)\n\tnewFunnelFunc := func() (packet.Funnel, error) {\n\t\tconn, err := newICMPConn(ip.listenIP)\n\t\tif err != nil {\n\t\t\ttracing.EndWithErrorStatus(span, err)\n\t\t\treturn nil, errors.Wrap(err, \"failed to open ICMP socket\")\n\t\t}\n\t\tip.logger.Debug().Msgf(\"Opened ICMP socket listen on %s\", conn.LocalAddr())\n\t\tcloseCallback := func() error {\n\t\t\treturn conn.Close()\n\t\t}\n\t\tlocalUDPAddr, ok := conn.LocalAddr().(*net.UDPAddr)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"ICMP listener address %s is not net.UDPAddr\", conn.LocalAddr())\n\t\t}\n\t\tspan.SetAttributes(attribute.Int(\"port\", localUDPAddr.Port))\n\n\t\techoID := localUDPAddr.Port\n\t\ticmpFlow := newICMPEchoFlow(pk.Src, closeCallback, conn, responder, echoID, originalEcho.ID)\n\t\treturn icmpFlow, nil\n\t}\n\tfunnelID := flow3Tuple{\n\t\tsrcIP:          pk.Src,\n\t\tdstIP:          pk.Dst,\n\t\toriginalEchoID: originalEcho.ID,\n\t}\n\tfunnel, isNew, err := ip.srcFunnelTracker.GetOrRegister(funnelID, shouldReplaceFunnelFunc, newFunnelFunc)\n\tif err != nil {\n\t\ttracing.EndWithErrorStatus(span, err)\n\t\treturn err\n\t}\n\ticmpFlow, err := toICMPEchoFlow(funnel)\n\tif err != nil {\n\t\ttracing.EndWithErrorStatus(span, err)\n\t\treturn err\n\t}\n\tif isNew {\n\t\tspan.SetAttributes(attribute.Bool(\"newFlow\", true))\n\t\tip.logger.Debug().\n\t\t\tStr(\"src\", pk.Src.String()).\n\t\t\tStr(\"dst\", pk.Dst.String()).\n\t\t\tInt(\"originalEchoID\", originalEcho.ID).\n\t\t\tMsg(\"New flow\")\n\t\tgo func() {\n\t\t\tip.listenResponse(ctx, icmpFlow)\n\t\t\tip.srcFunnelTracker.Unregister(funnelID, icmpFlow)\n\t\t}()\n\t}\n\tif err := icmpFlow.sendToDst(pk.Dst, pk.Message); err != nil {\n\t\ttracing.EndWithErrorStatus(span, err)\n\t\treturn errors.Wrap(err, \"failed to send ICMP echo request\")\n\t}\n\ttracing.End(span)\n\treturn nil\n}\n\nfunc (ip *icmpProxy) Serve(ctx context.Context) error {\n\tip.srcFunnelTracker.ScheduleCleanup(ctx, ip.idleTimeout)\n\treturn ctx.Err()\n}\n\nfunc (ip *icmpProxy) listenResponse(ctx context.Context, flow *icmpEchoFlow) {\n\tbuf := make([]byte, mtu)\n\tfor {\n\t\tif done := ip.handleResponse(ctx, flow, buf); done {\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// Listens for ICMP response and handles error logging\nfunc (ip *icmpProxy) handleResponse(ctx context.Context, flow *icmpEchoFlow, buf []byte) (done bool) {\n\t_, span := flow.responder.ReplySpan(ctx, ip.logger)\n\tdefer flow.responder.ExportSpan()\n\n\tspan.SetAttributes(\n\t\tattribute.Int(\"originalEchoID\", flow.originalEchoID),\n\t)\n\n\tn, from, err := flow.originConn.ReadFrom(buf)\n\tif err != nil {\n\t\tif flow.IsClosed() {\n\t\t\ttracing.EndWithErrorStatus(span, fmt.Errorf(\"flow was closed\"))\n\t\t\treturn true\n\t\t}\n\t\tip.logger.Error().Err(err).Str(\"socket\", flow.originConn.LocalAddr().String()).Msg(\"Failed to read from ICMP socket\")\n\t\ttracing.EndWithErrorStatus(span, err)\n\t\treturn true\n\t}\n\treply, err := parseReply(from, buf[:n])\n\tif err != nil {\n\t\tip.logger.Error().Err(err).Str(\"dst\", from.String()).Msg(\"Failed to parse ICMP reply\")\n\t\ttracing.EndWithErrorStatus(span, err)\n\t\treturn false\n\t}\n\tif !isEchoReply(reply.msg) {\n\t\terr := fmt.Errorf(\"Expect ICMP echo reply, got %s\", reply.msg.Type)\n\t\tip.logger.Debug().Str(\"dst\", from.String()).Msgf(\"Drop ICMP %s from reply\", reply.msg.Type)\n\t\ttracing.EndWithErrorStatus(span, err)\n\t\treturn false\n\t}\n\n\tif err := flow.returnToSrc(reply); err != nil {\n\t\tip.logger.Error().Err(err).Str(\"dst\", from.String()).Msg(\"Failed to send ICMP reply\")\n\t\ttracing.EndWithErrorStatus(span, err)\n\t\treturn false\n\t}\n\n\tobserveICMPReply(ip.logger, span, from.String(), reply.echo.ID, reply.echo.Seq)\n\ttracing.End(span)\n\treturn false\n}\n\n// Only linux uses flow3Tuple as FunnelID\nfunc (ft flow3Tuple) Type() string {\n\treturn \"srcIP_dstIP_echoID\"\n}\n\nfunc (ft flow3Tuple) String() string {\n\treturn fmt.Sprintf(\"%s:%s:%d\", ft.srcIP, ft.dstIP, ft.originalEchoID)\n}\n"
  },
  {
    "path": "ingress/icmp_linux_test.go",
    "content": "//go:build linux\n\npackage ingress\n\nimport (\n\t\"testing\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n)\n\nfunc getFunnel(t *testing.T, proxy *icmpProxy, tuple flow3Tuple) (packet.Funnel, bool) {\n\treturn proxy.srcFunnelTracker.Get(tuple)\n}\n"
  },
  {
    "path": "ingress/icmp_metrics.go",
    "content": "package ingress\n\nimport (\n\t\"github.com/prometheus/client_golang/prometheus\"\n)\n\nconst (\n\tnamespace = \"cloudflared\"\n)\n\nvar (\n\ticmpRequests = prometheus.NewCounter(prometheus.CounterOpts{\n\t\tNamespace: namespace,\n\t\tSubsystem: \"icmp\",\n\t\tName:      \"total_requests\",\n\t\tHelp:      \"Total count of ICMP requests that have been proxied to any origin\",\n\t})\n\ticmpReplies = prometheus.NewCounter(prometheus.CounterOpts{\n\t\tNamespace: namespace,\n\t\tSubsystem: \"icmp\",\n\t\tName:      \"total_replies\",\n\t\tHelp:      \"Total count of ICMP replies that have been proxied from any origin\",\n\t})\n)\n\nfunc init() {\n\tprometheus.MustRegister(\n\t\ticmpRequests,\n\t\ticmpReplies,\n\t)\n}\n\nfunc incrementICMPRequest() {\n\ticmpRequests.Inc()\n}\n\nfunc incrementICMPReply() {\n\ticmpReplies.Inc()\n}\n"
  },
  {
    "path": "ingress/icmp_posix.go",
    "content": "//go:build darwin || linux\n\npackage ingress\n\n// This file extracts logic shared by Linux and Darwin implementation if ICMPProxy.\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"net/netip\"\n\t\"sync/atomic\"\n\n\t\"github.com/google/gopacket/layers\"\n\t\"github.com/rs/zerolog\"\n\t\"golang.org/x/net/icmp\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n)\n\n// Opens a non-privileged ICMP socket on Linux and Darwin\nfunc newICMPConn(listenIP netip.Addr) (*icmp.PacketConn, error) {\n\tif listenIP.Is4() {\n\t\treturn icmp.ListenPacket(\"udp4\", listenIP.String())\n\t}\n\treturn icmp.ListenPacket(\"udp6\", listenIP.String())\n}\n\nfunc netipAddr(addr net.Addr) (netip.Addr, bool) {\n\tudpAddr, ok := addr.(*net.UDPAddr)\n\tif !ok {\n\t\treturn netip.Addr{}, false\n\t}\n\n\treturn udpAddr.AddrPort().Addr(), true\n}\n\ntype flow3Tuple struct {\n\tsrcIP          netip.Addr\n\tdstIP          netip.Addr\n\toriginalEchoID int\n}\n\n// icmpEchoFlow implements the packet.Funnel interface.\ntype icmpEchoFlow struct {\n\t*packet.ActivityTracker\n\tcloseCallback  func() error\n\tclosed         *atomic.Bool\n\tsrc            netip.Addr\n\toriginConn     *icmp.PacketConn\n\tresponder      ICMPResponder\n\tassignedEchoID int\n\toriginalEchoID int\n}\n\nfunc newICMPEchoFlow(src netip.Addr, closeCallback func() error, originConn *icmp.PacketConn, responder ICMPResponder, assignedEchoID, originalEchoID int) *icmpEchoFlow {\n\treturn &icmpEchoFlow{\n\t\tActivityTracker: packet.NewActivityTracker(),\n\t\tcloseCallback:   closeCallback,\n\t\tclosed:          &atomic.Bool{},\n\t\tsrc:             src,\n\t\toriginConn:      originConn,\n\t\tresponder:       responder,\n\t\tassignedEchoID:  assignedEchoID,\n\t\toriginalEchoID:  originalEchoID,\n\t}\n}\n\nfunc (ief *icmpEchoFlow) Equal(other packet.Funnel) bool {\n\totherICMPFlow, ok := other.(*icmpEchoFlow)\n\tif !ok {\n\t\treturn false\n\t}\n\tif otherICMPFlow.src != ief.src {\n\t\treturn false\n\t}\n\tif otherICMPFlow.originalEchoID != ief.originalEchoID {\n\t\treturn false\n\t}\n\tif otherICMPFlow.assignedEchoID != ief.assignedEchoID {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (ief *icmpEchoFlow) Close() error {\n\tief.closed.Store(true)\n\treturn ief.closeCallback()\n}\n\nfunc (ief *icmpEchoFlow) IsClosed() bool {\n\treturn ief.closed.Load()\n}\n\n// sendToDst rewrites the echo ID to the one assigned to this flow\nfunc (ief *icmpEchoFlow) sendToDst(dst netip.Addr, msg *icmp.Message) error {\n\tief.UpdateLastActive()\n\toriginalEcho, err := getICMPEcho(msg)\n\tif err != nil {\n\t\treturn err\n\t}\n\tsendMsg := icmp.Message{\n\t\tType: msg.Type,\n\t\tCode: msg.Code,\n\t\tBody: &icmp.Echo{\n\t\t\tID:   ief.assignedEchoID,\n\t\t\tSeq:  originalEcho.Seq,\n\t\t\tData: originalEcho.Data,\n\t\t},\n\t}\n\t// For IPv4, the pseudoHeader is not used because the checksum is always calculated\n\tvar pseudoHeader []byte = nil\n\tserializedPacket, err := sendMsg.Marshal(pseudoHeader)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = ief.originConn.WriteTo(serializedPacket, &net.UDPAddr{\n\t\tIP: dst.AsSlice(),\n\t})\n\treturn err\n}\n\n// returnToSrc rewrites the echo ID to the original echo ID from the eyeball\nfunc (ief *icmpEchoFlow) returnToSrc(reply *echoReply) error {\n\tief.UpdateLastActive()\n\treply.echo.ID = ief.originalEchoID\n\treply.msg.Body = reply.echo\n\tpk := packet.ICMP{\n\t\tIP: &packet.IP{\n\t\t\tSrc:      reply.from,\n\t\t\tDst:      ief.src,\n\t\t\tProtocol: layers.IPProtocol(reply.msg.Type.Protocol()),\n\t\t\tTTL:      packet.DefaultTTL,\n\t\t},\n\t\tMessage: reply.msg,\n\t}\n\treturn ief.responder.ReturnPacket(&pk)\n}\n\ntype echoReply struct {\n\tfrom netip.Addr\n\tmsg  *icmp.Message\n\techo *icmp.Echo\n}\n\nfunc parseReply(from net.Addr, rawMsg []byte) (*echoReply, error) {\n\tfromAddr, ok := netipAddr(from)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"cannot convert %s to netip.Addr\", from)\n\t}\n\tproto := layers.IPProtocolICMPv4\n\tif fromAddr.Is6() {\n\t\tproto = layers.IPProtocolICMPv6\n\t}\n\tmsg, err := icmp.ParseMessage(int(proto), rawMsg)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\techo, err := getICMPEcho(msg)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &echoReply{\n\t\tfrom: fromAddr,\n\t\tmsg:  msg,\n\t\techo: echo,\n\t}, nil\n}\n\nfunc toICMPEchoFlow(funnel packet.Funnel) (*icmpEchoFlow, error) {\n\ticmpFlow, ok := funnel.(*icmpEchoFlow)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"%v is not *ICMPEchoFunnel\", funnel)\n\t}\n\treturn icmpFlow, nil\n}\n\nfunc createShouldReplaceFunnelFunc(logger *zerolog.Logger, responder ICMPResponder, pk *packet.ICMP, originalEchoID int) func(packet.Funnel) bool {\n\treturn func(existing packet.Funnel) bool {\n\t\texistingFlow, err := toICMPEchoFlow(existing)\n\t\tif err != nil {\n\t\t\tlogger.Err(err).\n\t\t\t\tStr(\"src\", pk.Src.String()).\n\t\t\t\tStr(\"dst\", pk.Dst.String()).\n\t\t\t\tInt(\"originalEchoID\", originalEchoID).\n\t\t\t\tMsg(\"Funnel of wrong type found\")\n\t\t\treturn true\n\t\t}\n\t\t// Each quic connection should have a unique muxer.\n\t\t// If the existing flow has a different muxer, there's a new quic connection where return packets should be\n\t\t// routed. Otherwise, return packets will be send to the first observed incoming connection, rather than the\n\t\t// most recently observed connection.\n\t\tif existingFlow.responder.ConnectionIndex() != responder.ConnectionIndex() {\n\t\t\tlogger.Debug().\n\t\t\t\tStr(\"src\", pk.Src.String()).\n\t\t\t\tStr(\"dst\", pk.Dst.String()).\n\t\t\t\tInt(\"originalEchoID\", originalEchoID).\n\t\t\t\tMsg(\"Replacing funnel with new responder\")\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n}\n"
  },
  {
    "path": "ingress/icmp_posix_test.go",
    "content": "//go:build darwin || linux\n\npackage ingress\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/fortytw2/leaktest\"\n\t\"github.com/google/gopacket/layers\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/require\"\n\t\"golang.org/x/net/icmp\"\n\t\"golang.org/x/net/ipv4\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n)\n\nfunc TestFunnelIdleTimeout(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\n\tconst (\n\t\tidleTimeout = time.Second\n\t\techoID      = 42573\n\t\tstartSeq    = 8129\n\t)\n\tlogger := zerolog.New(os.Stderr)\n\tproxy, err := newICMPProxy(localhostIP, &logger, idleTimeout)\n\trequire.NoError(t, err)\n\n\tctx, cancel := context.WithCancel(context.Background())\n\n\tproxyDone := make(chan struct{})\n\tgo func() {\n\t\tproxy.Serve(ctx)\n\t\tclose(proxyDone)\n\t}()\n\n\t// Send a packet to register the flow\n\tpk := packet.ICMP{\n\t\tIP: &packet.IP{\n\t\t\tSrc:      localhostIP,\n\t\t\tDst:      localhostIP,\n\t\t\tProtocol: layers.IPProtocolICMPv4,\n\t\t},\n\t\tMessage: &icmp.Message{\n\t\t\tType: ipv4.ICMPTypeEcho,\n\t\t\tCode: 0,\n\t\t\tBody: &icmp.Echo{\n\t\t\t\tID:   echoID,\n\t\t\t\tSeq:  startSeq,\n\t\t\t\tData: []byte(t.Name()),\n\t\t\t},\n\t\t},\n\t}\n\tmuxer := newMockMuxer(0)\n\tresponder := newPacketResponder(muxer, 0, packet.NewEncoder())\n\trequire.NoError(t, proxy.Request(ctx, &pk, responder))\n\tvalidateEchoFlow(t, <-muxer.cfdToEdge, &pk)\n\n\t// Send second request, should reuse the funnel\n\trequire.NoError(t, proxy.Request(ctx, &pk, responder))\n\tvalidateEchoFlow(t, <-muxer.cfdToEdge, &pk)\n\n\t// New muxer on a different connection should use a new flow\n\ttime.Sleep(idleTimeout * 2)\n\tnewMuxer := newMockMuxer(0)\n\tnewResponder := newPacketResponder(newMuxer, 1, packet.NewEncoder())\n\trequire.NoError(t, proxy.Request(ctx, &pk, newResponder))\n\tvalidateEchoFlow(t, <-newMuxer.cfdToEdge, &pk)\n\n\ttime.Sleep(idleTimeout * 2)\n\tcancel()\n\t<-proxyDone\n}\n\nfunc TestReuseFunnel(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\n\tconst (\n\t\tidleTimeout = time.Millisecond * 100\n\t\techoID      = 42573\n\t\tstartSeq    = 8129\n\t)\n\tlogger := zerolog.New(os.Stderr)\n\tproxy, err := newICMPProxy(localhostIP, &logger, idleTimeout)\n\trequire.NoError(t, err)\n\n\tctx, cancel := context.WithCancel(context.Background())\n\n\tproxyDone := make(chan struct{})\n\tgo func() {\n\t\tproxy.Serve(ctx)\n\t\tclose(proxyDone)\n\t}()\n\n\t// Send a packet to register the flow\n\tpk := packet.ICMP{\n\t\tIP: &packet.IP{\n\t\t\tSrc:      localhostIP,\n\t\t\tDst:      localhostIP,\n\t\t\tProtocol: layers.IPProtocolICMPv4,\n\t\t},\n\t\tMessage: &icmp.Message{\n\t\t\tType: ipv4.ICMPTypeEcho,\n\t\t\tCode: 0,\n\t\t\tBody: &icmp.Echo{\n\t\t\t\tID:   echoID,\n\t\t\t\tSeq:  startSeq,\n\t\t\t\tData: []byte(t.Name()),\n\t\t\t},\n\t\t},\n\t}\n\ttuple := flow3Tuple{\n\t\tsrcIP:          pk.Src,\n\t\tdstIP:          pk.Dst,\n\t\toriginalEchoID: echoID,\n\t}\n\tmuxer := newMockMuxer(0)\n\tresponder := newPacketResponder(muxer, 0, packet.NewEncoder())\n\trequire.NoError(t, proxy.Request(ctx, &pk, responder))\n\tvalidateEchoFlow(t, <-muxer.cfdToEdge, &pk)\n\tfunnel1, found := getFunnel(t, proxy, tuple)\n\trequire.True(t, found)\n\n\t// Send second request, should reuse the funnel\n\trequire.NoError(t, proxy.Request(ctx, &pk, responder))\n\tvalidateEchoFlow(t, <-muxer.cfdToEdge, &pk)\n\tfunnel2, found := getFunnel(t, proxy, tuple)\n\trequire.True(t, found)\n\trequire.Equal(t, funnel1, funnel2)\n\n\ttime.Sleep(idleTimeout * 2)\n\n\tcancel()\n\t<-proxyDone\n}\n"
  },
  {
    "path": "ingress/icmp_windows.go",
    "content": "//go:build windows && cgo\n\npackage ingress\n\n/*\n#include <iphlpapi.h>\n#include <icmpapi.h>\n*/\nimport \"C\"\nimport (\n\t\"context\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"net/netip\"\n\t\"runtime/debug\"\n\t\"syscall\"\n\t\"time\"\n\t\"unsafe\"\n\n\t\"github.com/google/gopacket/layers\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"golang.org/x/net/icmp\"\n\t\"golang.org/x/net/ipv4\"\n\t\"golang.org/x/net/ipv6\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n)\n\nconst (\n\t// Value defined in https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasocketw\n\tAF_INET6          = 23\n\ticmpEchoReplyCode = 0\n\tnullParameter     = uintptr(0)\n)\n\nvar (\n\tIphlpapi             = syscall.NewLazyDLL(\"Iphlpapi.dll\")\n\tIcmpCreateFile_proc  = Iphlpapi.NewProc(\"IcmpCreateFile\")\n\tIcmp6CreateFile_proc = Iphlpapi.NewProc(\"Icmp6CreateFile\")\n\tIcmpSendEcho_proc    = Iphlpapi.NewProc(\"IcmpSendEcho\")\n\tIcmp6SendEcho_proc   = Iphlpapi.NewProc(\"Icmp6SendEcho2\")\n\techoReplySize        = unsafe.Sizeof(echoReply{})\n\techoV6ReplySize      = unsafe.Sizeof(echoV6Reply{})\n\ticmpv6ErrMessageSize = 8\n\tioStatusBlockSize    = unsafe.Sizeof(ioStatusBlock{})\n\tendian               = binary.LittleEndian\n)\n\n// IP_STATUS code, see https://docs.microsoft.com/en-us/windows/win32/api/ipexport/ns-ipexport-icmp_echo_reply32#members\n// for possible values\ntype ipStatus uint32\n\nconst (\n\tsuccess     ipStatus = 0\n\tbufTooSmall          = iota + 11000\n\tdestNetUnreachable\n\tdestHostUnreachable\n\tdestProtocolUnreachable\n\tdestPortUnreachable\n\tnoResources\n\tbadOption\n\thwError\n\tpacketTooBig\n\treqTimedOut\n\tbadReq\n\tbadRoute\n\tttlExpiredTransit\n\tttlExpiredReassembly\n\tparamProblem\n\tsourceQuench\n\toptionTooBig\n\tbadDestination\n\t// Can be returned for malformed ICMP packets\n\tgeneralFailure = 11050\n)\n\n// Additional IP_STATUS codes for ICMPv6  https://docs.microsoft.com/en-us/windows/win32/api/ipexport/ns-ipexport-icmpv6_echo_reply_lh#members\nconst (\n\tipv6DestUnreachable ipStatus = iota + 11040\n\tipv6TimeExceeded\n\tipv6BadHeader\n\tipv6UnrecognizedNextHeader\n\tipv6ICMPError\n\tipv6DestScopeMismatch\n)\n\nfunc (is ipStatus) String() string {\n\tswitch is {\n\tcase success:\n\t\treturn \"Success\"\n\tcase bufTooSmall:\n\t\treturn \"The reply buffer too small\"\n\tcase destNetUnreachable:\n\t\treturn \"The destination network was unreachable\"\n\tcase destHostUnreachable:\n\t\treturn \"The destination host was unreachable\"\n\tcase destProtocolUnreachable:\n\t\treturn \"The destination protocol was unreachable\"\n\tcase destPortUnreachable:\n\t\treturn \"The destination port was unreachable\"\n\tcase noResources:\n\t\treturn \"Insufficient IP resources were available\"\n\tcase badOption:\n\t\treturn \"A bad IP option was specified\"\n\tcase hwError:\n\t\treturn \"A hardware error occurred\"\n\tcase packetTooBig:\n\t\treturn \"The packet was too big\"\n\tcase reqTimedOut:\n\t\treturn \"The request timed out\"\n\tcase badReq:\n\t\treturn \"Bad request\"\n\tcase badRoute:\n\t\treturn \"Bad route\"\n\tcase ttlExpiredTransit:\n\t\treturn \"The TTL expired in transit\"\n\tcase ttlExpiredReassembly:\n\t\treturn \"The TTL expired during fragment reassembly\"\n\tcase paramProblem:\n\t\treturn \"A parameter problem\"\n\tcase sourceQuench:\n\t\treturn \"Datagrams are arriving too fast to be processed and datagrams may have been discarded\"\n\tcase optionTooBig:\n\t\treturn \"The IP option was too big\"\n\tcase badDestination:\n\t\treturn \"Bad destination\"\n\tcase ipv6DestUnreachable:\n\t\treturn \"IPv6 destination unreachable\"\n\tcase ipv6TimeExceeded:\n\t\treturn \"IPv6 time exceeded\"\n\tcase ipv6BadHeader:\n\t\treturn \"IPv6 bad IP header\"\n\tcase ipv6UnrecognizedNextHeader:\n\t\treturn \"IPv6 unrecognized next header\"\n\tcase ipv6ICMPError:\n\t\treturn \"IPv6 ICMP error\"\n\tcase ipv6DestScopeMismatch:\n\t\treturn \"IPv6 destination scope ID mismatch\"\n\tcase generalFailure:\n\t\treturn \"The ICMP packet might be malformed\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"Unknown ip status %d\", is)\n\t}\n}\n\n// https://docs.microsoft.com/en-us/windows/win32/api/ipexport/ns-ipexport-ip_option_information\ntype ipOption struct {\n\tTTL         uint8\n\tTos         uint8\n\tFlags       uint8\n\tOptionsSize uint8\n\tOptionsData uintptr\n}\n\n// https://docs.microsoft.com/en-us/windows/win32/api/ipexport/ns-ipexport-icmp_echo_reply\ntype echoReply struct {\n\tAddress       uint32\n\tStatus        ipStatus\n\tRoundTripTime uint32\n\tDataSize      uint16\n\tReserved      uint16\n\t// The pointer size defers between 32-bit and 64-bit platforms\n\tDataPointer *byte\n\tOptions     ipOption\n}\n\ntype echoV6Reply struct {\n\tAddress       ipv6AddrEx\n\tStatus        ipStatus\n\tRoundTripTime uint32\n}\n\n// https://docs.microsoft.com/en-us/windows/win32/api/ipexport/ns-ipexport-ipv6_address_ex\n// All the fields are in network byte order. The memory alignment is 4 bytes\ntype ipv6AddrEx struct {\n\tport uint16\n\t// flowInfo is uint32. Because of field alignment, when we cast reply buffer to ipv6AddrEx, it starts at the 5th byte\n\t// But looking at the raw bytes, flowInfo starts at the 3rd byte. We device flowInfo into 2 uint16 so it's aligned\n\tflowInfoUpper uint16\n\tflowInfoLower uint16\n\taddr          [8]uint16\n\tscopeID       uint32\n}\n\n// https://docs.microsoft.com/en-us/windows/win32/winsock/sockaddr-2\ntype sockAddrIn6 struct {\n\tfamily int16\n\t// Can't embed ipv6AddrEx, that changes the memory alignment\n\tport     uint16\n\tflowInfo uint32\n\taddr     [16]byte\n\tscopeID  uint32\n}\n\nfunc newSockAddrIn6(addr netip.Addr) (*sockAddrIn6, error) {\n\tif !addr.Is6() {\n\t\treturn nil, fmt.Errorf(\"%s is not IPv6\", addr)\n\t}\n\treturn &sockAddrIn6{\n\t\tfamily: AF_INET6,\n\t\tport:   10,\n\t\taddr:   addr.As16(),\n\t}, nil\n}\n\n// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_io_status_block#syntax\ntype ioStatusBlock struct {\n\t// The first field is an union of NTSTATUS and PVOID. NTSTATUS is int32 while PVOID depends on the platform.\n\t// We model it as uintptr whose size depends on if the platform is 32-bit or 64-bit\n\t// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55\n\tstatusOrPointer uintptr\n\tinformation     uintptr\n}\n\ntype icmpProxy struct {\n\t// An open handle that can send ICMP requests https://docs.microsoft.com/en-us/windows/win32/api/icmpapi/nf-icmpapi-icmpcreatefile\n\thandle uintptr\n\t// This is a ICMPv6 if srcSocketAddr is not nil\n\tsrcSocketAddr *sockAddrIn6\n\tlogger        *zerolog.Logger\n}\n\nfunc newICMPProxy(listenIP netip.Addr, logger *zerolog.Logger, idleTimeout time.Duration) (*icmpProxy, error) {\n\tvar (\n\t\tsrcSocketAddr *sockAddrIn6\n\t\thandle        uintptr\n\t\terr           error\n\t)\n\tif listenIP.Is4() {\n\t\thandle, _, err = IcmpCreateFile_proc.Call()\n\t} else {\n\t\tsrcSocketAddr, err = newSockAddrIn6(listenIP)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\thandle, _, err = Icmp6CreateFile_proc.Call()\n\t}\n\t// Windows procedure calls always return non-nil error constructed from the result of GetLastError.\n\t// Caller need to inspect the primary returned value\n\tif syscall.Handle(handle) == syscall.InvalidHandle {\n\t\treturn nil, errors.Wrap(err, \"invalid ICMP handle\")\n\t}\n\treturn &icmpProxy{\n\t\thandle:        handle,\n\t\tsrcSocketAddr: srcSocketAddr,\n\t\tlogger:        logger,\n\t}, nil\n}\n\nfunc (ip *icmpProxy) Serve(ctx context.Context) error {\n\t<-ctx.Done()\n\tsyscall.CloseHandle(syscall.Handle(ip.handle))\n\treturn ctx.Err()\n}\n\n// Request sends an ICMP echo request and wait for a reply or timeout.\n// The async version of Win32 APIs take a callback whose memory is not garbage collected, so we use the synchronous version.\n// It's possible that a slow request will block other requests, so we set the timeout to only 1s.\nfunc (ip *icmpProxy) Request(ctx context.Context, pk *packet.ICMP, responder ICMPResponder) error {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tip.logger.Error().Interface(\"error\", r).Msgf(\"Recover panic from sending icmp request/response, error %s\", debug.Stack())\n\t\t}\n\t}()\n\n\t_, requestSpan := responder.RequestSpan(ctx, pk)\n\tdefer responder.ExportSpan()\n\n\techo, err := getICMPEcho(pk.Message)\n\tif err != nil {\n\t\treturn err\n\t}\n\tobserveICMPRequest(ip.logger, requestSpan, pk.Src.String(), pk.Dst.String(), echo.ID, echo.Seq)\n\n\tresp, err := ip.icmpEchoRoundtrip(pk.Dst, echo)\n\tif err != nil {\n\t\tip.logger.Err(err).Msg(\"ICMP echo roundtrip failed\")\n\t\ttracing.EndWithErrorStatus(requestSpan, err)\n\t\treturn err\n\t}\n\ttracing.End(requestSpan)\n\tresponder.ExportSpan()\n\n\t_, replySpan := responder.ReplySpan(ctx, ip.logger)\n\terr = ip.handleEchoReply(pk, echo, resp, responder)\n\tif err != nil {\n\t\tip.logger.Err(err).Msg(\"Failed to send ICMP reply\")\n\t\ttracing.EndWithErrorStatus(replySpan, err)\n\t\treturn errors.Wrap(err, \"failed to handle ICMP echo reply\")\n\t}\n\tobserveICMPReply(ip.logger, replySpan, pk.Dst.String(), echo.ID, echo.Seq)\n\treplySpan.SetAttributes(\n\t\tattribute.Int64(\"rtt\", int64(resp.rtt())),\n\t\tattribute.String(\"status\", resp.status().String()),\n\t)\n\ttracing.End(replySpan)\n\treturn nil\n}\n\nfunc (ip *icmpProxy) handleEchoReply(request *packet.ICMP, echoReq *icmp.Echo, resp echoResp, responder ICMPResponder) error {\n\tvar replyType icmp.Type\n\tif request.Dst.Is4() {\n\t\treplyType = ipv4.ICMPTypeEchoReply\n\t} else {\n\t\treplyType = ipv6.ICMPTypeEchoReply\n\t}\n\n\tpk := packet.ICMP{\n\t\tIP: &packet.IP{\n\t\t\tSrc:      request.Dst,\n\t\t\tDst:      request.Src,\n\t\t\tProtocol: layers.IPProtocol(request.Type.Protocol()),\n\t\t\tTTL:      packet.DefaultTTL,\n\t\t},\n\t\tMessage: &icmp.Message{\n\t\t\tType: replyType,\n\t\t\tCode: icmpEchoReplyCode,\n\t\t\tBody: &icmp.Echo{\n\t\t\t\tID:   echoReq.ID,\n\t\t\t\tSeq:  echoReq.Seq,\n\t\t\t\tData: resp.payload(),\n\t\t\t},\n\t\t},\n\t}\n\treturn responder.ReturnPacket(&pk)\n}\n\nfunc (ip *icmpProxy) icmpEchoRoundtrip(dst netip.Addr, echo *icmp.Echo) (echoResp, error) {\n\tif dst.Is6() {\n\t\tif ip.srcSocketAddr == nil {\n\t\t\treturn nil, fmt.Errorf(\"cannot send ICMPv6 using ICMPv4 proxy\")\n\t\t}\n\t\tresp, err := ip.icmp6SendEcho(dst, echo)\n\t\tif err != nil {\n\n\t\t\treturn nil, errors.Wrap(err, \"failed to send/receive ICMPv6 echo\")\n\t\t}\n\t\treturn resp, nil\n\t}\n\tif ip.srcSocketAddr != nil {\n\t\treturn nil, fmt.Errorf(\"cannot send ICMPv4 using ICMPv6 proxy\")\n\t}\n\tresp, err := ip.icmpSendEcho(dst, echo)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to send/receive ICMPv4 echo\")\n\t}\n\treturn resp, nil\n}\n\n/*\nWrapper to call https://docs.microsoft.com/en-us/windows/win32/api/icmpapi/nf-icmpapi-icmpsendecho\nParameters:\n- IcmpHandle: Handle created by IcmpCreateFile\n- DestinationAddress: IPv4 in the form of https://docs.microsoft.com/en-us/windows/win32/api/inaddr/ns-inaddr-in_addr#syntax\n- RequestData: A pointer to echo data\n- RequestSize: Number of bytes in buffer pointed by echo data\n- RequestOptions: IP header options\n- ReplyBuffer: A pointer to the buffer for echoReply, options and data\n- ReplySize: Number of bytes allocated for ReplyBuffer\n- Timeout: Timeout in milliseconds to wait for a reply\nReturns:\n- the number of replies in uint32 https://docs.microsoft.com/en-us/windows/win32/api/icmpapi/nf-icmpapi-icmpsendecho#return-value\nTo retain the reference allocated objects, conversion from pointer to uintptr must happen as arguments to the\nsyscall function\n*/\nfunc (ip *icmpProxy) icmpSendEcho(dst netip.Addr, echo *icmp.Echo) (*echoV4Resp, error) {\n\tdataSize := len(echo.Data)\n\treplySize := echoReplySize + uintptr(dataSize)\n\treplyBuf := make([]byte, replySize)\n\tnoIPHeaderOption := nullParameter\n\tinAddr, err := inAddrV4(dst)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treplyCount, _, err := IcmpSendEcho_proc.Call(\n\t\tip.handle,\n\t\tuintptr(inAddr),\n\t\tuintptr(unsafe.Pointer(&echo.Data[0])),\n\t\tuintptr(dataSize),\n\t\tnoIPHeaderOption,\n\t\tuintptr(unsafe.Pointer(&replyBuf[0])),\n\t\treplySize,\n\t\ticmpRequestTimeoutMs,\n\t)\n\tif replyCount == 0 {\n\t\t// status is returned in 5th to 8th byte of reply buffer\n\t\tif status, parseErr := unmarshalIPStatus(replyBuf[4:8]); parseErr == nil && status != success {\n\t\t\treturn nil, errors.Wrapf(err, \"received ip status: %s\", status)\n\t\t}\n\t\treturn nil, errors.Wrap(err, \"did not receive ICMP echo reply\")\n\t} else if replyCount > 1 {\n\t\tip.logger.Warn().Msgf(\"Received %d ICMP echo replies, only sending 1 back\", replyCount)\n\t}\n\treturn newEchoV4Resp(replyBuf)\n}\n\n// Third definition of https://docs.microsoft.com/en-us/windows/win32/api/inaddr/ns-inaddr-in_addr#syntax is address in uint32\nfunc inAddrV4(ip netip.Addr) (uint32, error) {\n\tif !ip.Is4() {\n\t\treturn 0, fmt.Errorf(\"%s is not IPv4\", ip)\n\t}\n\tv4 := ip.As4()\n\treturn endian.Uint32(v4[:]), nil\n}\n\ntype echoResp interface {\n\tstatus() ipStatus\n\trtt() uint32\n\tpayload() []byte\n}\n\ntype echoV4Resp struct {\n\treply *echoReply\n\tdata  []byte\n}\n\nfunc (r *echoV4Resp) status() ipStatus {\n\treturn r.reply.Status\n}\n\nfunc (r *echoV4Resp) rtt() uint32 {\n\treturn r.reply.RoundTripTime\n}\n\nfunc (r *echoV4Resp) payload() []byte {\n\treturn r.data\n}\n\nfunc newEchoV4Resp(replyBuf []byte) (*echoV4Resp, error) {\n\tif len(replyBuf) == 0 {\n\t\treturn nil, fmt.Errorf(\"reply buffer is empty\")\n\t}\n\t// This is pattern 1 of https://pkg.go.dev/unsafe@master#Pointer, conversion of *replyBuf to *echoReply\n\t// replyBuf size is larger than echoReply\n\treply := *(*echoReply)(unsafe.Pointer(&replyBuf[0]))\n\tif reply.Status != success {\n\t\treturn nil, fmt.Errorf(\"status %d\", reply.Status)\n\t}\n\tdataBufStart := len(replyBuf) - int(reply.DataSize)\n\tif dataBufStart < int(echoReplySize) {\n\t\treturn nil, fmt.Errorf(\"reply buffer size %d is too small to hold data of size %d\", len(replyBuf), int(reply.DataSize))\n\t}\n\treturn &echoV4Resp{\n\t\treply: &reply,\n\t\tdata:  replyBuf[dataBufStart:],\n\t}, nil\n}\n\n/*\n\tWrapper to call https://docs.microsoft.com/en-us/windows/win32/api/icmpapi/nf-icmpapi-icmp6sendecho2\n\tParameters:\n\t- IcmpHandle: Handle created by Icmp6CreateFile\n\t- Event (optional): Event object to be signaled when a reply arrives\n\t- ApcRoutine (optional): Routine to call when the calling thread is in an alertable thread and a reply arrives\n\t- ApcContext (optional): Optional parameter to ApcRoutine\n\t- SourceAddress: Source address of the request\n\t- DestinationAddress: Destination address of the request\n\t- RequestData: A pointer to echo data\n\t- RequestSize: Number of bytes in buffer pointed by echo data\n\t- RequestOptions (optional): A pointer to the IPv6 header options\n\t- ReplyBuffer: A pointer to the buffer for echoReply, options and data\n\t- ReplySize: Number of bytes allocated for ReplyBuffer\n\t- Timeout: Timeout in milliseconds to wait for a reply\n\tReturns:\n\t- the number of replies in uint32\n\tTo retain the reference allocated objects, conversion from pointer to uintptr must happen as arguments to the\n\tsyscall function\n*/\n\nfunc (ip *icmpProxy) icmp6SendEcho(dst netip.Addr, echo *icmp.Echo) (*echoV6Resp, error) {\n\tdstAddr, err := newSockAddrIn6(dst)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdataSize := len(echo.Data)\n\t// Reply buffer needs to be big enough to hold an echoV6Reply, echo data, 8 bytes for ICMP error message\n\t// and ioStatusBlock\n\treplySize := echoV6ReplySize + uintptr(dataSize) + uintptr(icmpv6ErrMessageSize) + ioStatusBlockSize\n\treplyBuf := make([]byte, replySize)\n\tnoEvent := nullParameter\n\tnoApcRoutine := nullParameter\n\tnoAppCtx := nullParameter\n\tnoIPHeaderOption := nullParameter\n\treplyCount, _, err := Icmp6SendEcho_proc.Call(\n\t\tip.handle,\n\t\tnoEvent,\n\t\tnoApcRoutine,\n\t\tnoAppCtx,\n\t\tuintptr(unsafe.Pointer(ip.srcSocketAddr)),\n\t\tuintptr(unsafe.Pointer(dstAddr)),\n\t\tuintptr(unsafe.Pointer(&echo.Data[0])),\n\t\tuintptr(dataSize),\n\t\tnoIPHeaderOption,\n\t\tuintptr(unsafe.Pointer(&replyBuf[0])),\n\t\treplySize,\n\t\ticmpRequestTimeoutMs,\n\t)\n\tif replyCount == 0 {\n\t\t// status is in the 4 bytes after ipv6AddrEx. The reply buffer size is at least size of ipv6AddrEx + 4\n\t\tif status, parseErr := unmarshalIPStatus(replyBuf[unsafe.Sizeof(ipv6AddrEx{}) : unsafe.Sizeof(ipv6AddrEx{})+4]); parseErr == nil && status != success {\n\t\t\treturn nil, fmt.Errorf(\"received ip status: %s\", status)\n\t\t}\n\t\treturn nil, errors.Wrap(err, \"did not receive ICMP echo reply\")\n\t} else if replyCount > 1 {\n\t\tip.logger.Warn().Msgf(\"Received %d ICMP echo replies, only sending 1 back\", replyCount)\n\t}\n\treturn newEchoV6Resp(replyBuf, dataSize)\n}\n\ntype echoV6Resp struct {\n\treply *echoV6Reply\n\tdata  []byte\n}\n\nfunc (r *echoV6Resp) status() ipStatus {\n\treturn r.reply.Status\n}\n\nfunc (r *echoV6Resp) rtt() uint32 {\n\treturn r.reply.RoundTripTime\n}\n\nfunc (r *echoV6Resp) payload() []byte {\n\treturn r.data\n}\n\nfunc newEchoV6Resp(replyBuf []byte, dataSize int) (*echoV6Resp, error) {\n\tif len(replyBuf) == 0 {\n\t\treturn nil, fmt.Errorf(\"reply buffer is empty\")\n\t}\n\treply := *(*echoV6Reply)(unsafe.Pointer(&replyBuf[0]))\n\tif reply.Status != success {\n\t\treturn nil, fmt.Errorf(\"status %d\", reply.Status)\n\t}\n\tif uintptr(len(replyBuf)) < unsafe.Sizeof(reply)+uintptr(dataSize) {\n\t\treturn nil, fmt.Errorf(\"reply buffer size %d is too small to hold reply size %d + data size %d\", len(replyBuf), echoV6ReplySize, dataSize)\n\t}\n\treturn &echoV6Resp{\n\t\treply: &reply,\n\t\tdata:  replyBuf[echoV6ReplySize : echoV6ReplySize+uintptr(dataSize)],\n\t}, nil\n}\n\nfunc unmarshalIPStatus(replyBuf []byte) (ipStatus, error) {\n\tif len(replyBuf) != 4 {\n\t\treturn 0, fmt.Errorf(\"ipStatus needs to be 4 bytes, got %d\", len(replyBuf))\n\t}\n\treturn ipStatus(endian.Uint32(replyBuf)), nil\n}\n"
  },
  {
    "path": "ingress/icmp_windows_test.go",
    "content": "//go:build windows && cgo\n\npackage ingress\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/netip\"\n\t\"testing\"\n\t\"time\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/icmp\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\n// TestParseEchoReply tests parsing raw bytes from icmpSendEcho into echoResp\nfunc TestParseEchoReply(t *testing.T) {\n\tdst, err := inAddrV4(netip.MustParseAddr(\"192.168.10.20\"))\n\trequire.NoError(t, err)\n\n\tvalidReplyData := []byte(t.Name())\n\tvalidReply := echoReply{\n\t\tAddress:       dst,\n\t\tStatus:        success,\n\t\tRoundTripTime: uint32(20),\n\t\tDataSize:      uint16(len(validReplyData)),\n\t\tDataPointer:   &validReplyData[0],\n\t\tOptions: ipOption{\n\t\t\tTTL: 59,\n\t\t},\n\t}\n\n\tdestHostUnreachableReply := validReply\n\tdestHostUnreachableReply.Status = destHostUnreachable\n\n\ttests := []struct {\n\t\ttestCase      string\n\t\treplyBuf      []byte\n\t\texpectedReply *echoReply\n\t\texpectedData  []byte\n\t}{\n\t\t{\n\t\t\ttestCase: \"empty buffer\",\n\t\t},\n\t\t{\n\t\t\ttestCase: \"status not success\",\n\t\t\treplyBuf: destHostUnreachableReply.marshal(t, []byte{}),\n\t\t},\n\t\t{\n\t\t\ttestCase:      \"valid reply\",\n\t\t\treplyBuf:      validReply.marshal(t, validReplyData),\n\t\t\texpectedReply: &validReply,\n\t\t\texpectedData:  validReplyData,\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tresp, err := newEchoV4Resp(test.replyBuf)\n\t\tif test.expectedReply == nil {\n\t\t\trequire.Error(t, err)\n\t\t\trequire.Nil(t, resp)\n\t\t} else {\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, resp.reply, test.expectedReply)\n\t\t\trequire.True(t, bytes.Equal(resp.data, test.expectedData))\n\t\t}\n\t}\n}\n\n// TestParseEchoV6Reply tests parsing raw bytes from icmp6SendEcho into echoV6Resp\nfunc TestParseEchoV6Reply(t *testing.T) {\n\tdst := netip.MustParseAddr(\"2606:3600:4500::3333\").As16()\n\tvar addr [8]uint16\n\tfor i := 0; i < 8; i++ {\n\t\taddr[i] = binary.BigEndian.Uint16(dst[i*2 : i*2+2])\n\t}\n\n\tvalidReplyData := []byte(t.Name())\n\tvalidReply := echoV6Reply{\n\t\tAddress: ipv6AddrEx{\n\t\t\taddr: addr,\n\t\t},\n\t\tStatus:        success,\n\t\tRoundTripTime: 25,\n\t}\n\n\tdestHostUnreachableReply := validReply\n\tdestHostUnreachableReply.Status = ipv6DestUnreachable\n\n\ttests := []struct {\n\t\ttestCase      string\n\t\treplyBuf      []byte\n\t\texpectedReply *echoV6Reply\n\t\texpectedData  []byte\n\t}{\n\t\t{\n\t\t\ttestCase: \"empty buffer\",\n\t\t},\n\t\t{\n\t\t\ttestCase: \"status not success\",\n\t\t\treplyBuf: destHostUnreachableReply.marshal(t, []byte{}),\n\t\t},\n\t\t{\n\t\t\ttestCase:      \"valid reply\",\n\t\t\treplyBuf:      validReply.marshal(t, validReplyData),\n\t\t\texpectedReply: &validReply,\n\t\t\texpectedData:  validReplyData,\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tresp, err := newEchoV6Resp(test.replyBuf, len(test.expectedData))\n\t\tif test.expectedReply == nil {\n\t\t\trequire.Error(t, err)\n\t\t\trequire.Nil(t, resp)\n\t\t} else {\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, resp.reply, test.expectedReply)\n\t\t\trequire.True(t, bytes.Equal(resp.data, test.expectedData))\n\t\t}\n\t}\n}\n\n// TestSendEchoErrors makes sure icmpSendEcho handles error cases\nfunc TestSendEchoErrors(t *testing.T) {\n\ttestSendEchoErrors(t, netip.IPv4Unspecified())\n\ttestSendEchoErrors(t, netip.IPv6Unspecified())\n}\n\nfunc testSendEchoErrors(t *testing.T, listenIP netip.Addr) {\n\tproxy, err := newICMPProxy(listenIP, &noopLogger, time.Second)\n\trequire.NoError(t, err)\n\n\techo := icmp.Echo{\n\t\tID:   6193,\n\t\tSeq:  25712,\n\t\tData: []byte(t.Name()),\n\t}\n\tdocumentIP := netip.MustParseAddr(\"192.0.2.200\")\n\tif listenIP.Is6() {\n\t\tdocumentIP = netip.MustParseAddr(\"2001:db8::1\")\n\t}\n\tresp, err := proxy.icmpEchoRoundtrip(documentIP, &echo)\n\trequire.Error(t, err)\n\trequire.Nil(t, resp)\n}\n\nfunc (er *echoReply) marshal(t *testing.T, data []byte) []byte {\n\tbuf := new(bytes.Buffer)\n\n\tfor _, field := range []any{\n\t\ter.Address,\n\t\ter.Status,\n\t\ter.RoundTripTime,\n\t\ter.DataSize,\n\t\ter.Reserved,\n\t} {\n\t\trequire.NoError(t, binary.Write(buf, endian, field))\n\t}\n\n\trequire.NoError(t, marshalPointer(buf, uintptr(unsafe.Pointer(er.DataPointer))))\n\n\tfor _, field := range []any{\n\t\ter.Options.TTL,\n\t\ter.Options.Tos,\n\t\ter.Options.Flags,\n\t\ter.Options.OptionsSize,\n\t} {\n\t\trequire.NoError(t, binary.Write(buf, endian, field))\n\t}\n\n\trequire.NoError(t, marshalPointer(buf, er.Options.OptionsData))\n\n\tpadSize := buf.Len() % int(unsafe.Alignof(er))\n\tpadding := make([]byte, padSize)\n\tn, err := buf.Write(padding)\n\trequire.NoError(t, err)\n\trequire.Equal(t, padSize, n)\n\n\tn, err = buf.Write(data)\n\trequire.NoError(t, err)\n\trequire.Equal(t, len(data), n)\n\n\treturn buf.Bytes()\n}\n\nfunc marshalPointer(buf io.Writer, ptr uintptr) error {\n\tsize := unsafe.Sizeof(ptr)\n\tswitch size {\n\tcase 4:\n\t\treturn binary.Write(buf, endian, uint32(ptr))\n\tcase 8:\n\t\treturn binary.Write(buf, endian, uint64(ptr))\n\tdefault:\n\t\treturn fmt.Errorf(\"unexpected pointer size %d\", size)\n\t}\n}\n\nfunc (er *echoV6Reply) marshal(t *testing.T, data []byte) []byte {\n\tbuf := new(bytes.Buffer)\n\n\tfor _, field := range []any{\n\t\ter.Address.port,\n\t\ter.Address.flowInfoUpper,\n\t\ter.Address.flowInfoLower,\n\t\ter.Address.addr,\n\t\ter.Address.scopeID,\n\t} {\n\t\trequire.NoError(t, binary.Write(buf, endian, field))\n\t}\n\n\tpadSize := buf.Len() % int(unsafe.Alignof(er))\n\tpadding := make([]byte, padSize)\n\tn, err := buf.Write(padding)\n\trequire.NoError(t, err)\n\trequire.Equal(t, padSize, n)\n\n\tfor _, field := range []any{\n\t\ter.Status,\n\t\ter.RoundTripTime,\n\t} {\n\t\trequire.NoError(t, binary.Write(buf, endian, field))\n\t}\n\n\tn, err = buf.Write(data)\n\trequire.NoError(t, err)\n\trequire.Equal(t, len(data), n)\n\n\treturn buf.Bytes()\n}\n"
  },
  {
    "path": "ingress/ingress.go",
    "content": "package ingress\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"net/url\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/urfave/cli/v2\"\n\t\"golang.org/x/net/idna\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/ingress/middleware\"\n\t\"github.com/cloudflare/cloudflared/ipaccess\"\n)\n\nvar (\n\tErrNoIngressRules             = errors.New(\"The config file doesn't contain any ingress rules\")\n\tErrNoIngressRulesCLI          = errors.New(\"No ingress rules were defined in provided config (if any) nor from the cli, cloudflared will return 503 for all incoming HTTP requests\")\n\terrLastRuleNotCatchAll        = errors.New(\"The last ingress rule must match all URLs (i.e. it should not have a hostname or path filter)\")\n\terrBadWildcard                = errors.New(\"Hostname patterns can have at most one wildcard character (\\\"*\\\") and it can only be used for subdomains, e.g. \\\"*.example.com\\\"\")\n\terrHostnameContainsPort       = errors.New(\"Hostname cannot contain a port\")\n\tErrURLIncompatibleWithIngress = errors.New(\"You can't set the --url flag (or $TUNNEL_URL) when using multiple-origin ingress rules\")\n)\n\nconst (\n\tServiceBastion     = \"bastion\"\n\tServiceSocksProxy  = \"socks-proxy\"\n\tServiceWarpRouting = \"warp-routing\"\n)\n\n// FindMatchingRule returns the index of the Ingress Rule which matches the given\n// hostname and path. This function assumes the last rule matches everything,\n// which is the case if the rules were instantiated via the ingress#Validate method.\n//\n// Negative index rule signifies local cloudflared rules (not-user defined).\nfunc (ing Ingress) FindMatchingRule(hostname, path string) (*Rule, int) {\n\t// The hostname might contain port. We only want to compare the host part with the rule\n\thost, _, err := net.SplitHostPort(hostname)\n\tif err == nil {\n\t\thostname = host\n\t}\n\tfor i, rule := range ing.InternalRules {\n\t\tif rule.Matches(hostname, path) {\n\t\t\t// Local rule matches return a negative rule index to distiguish local rules from user-defined rules in logs\n\t\t\t// Full range would be [-1 .. )\n\t\t\treturn &rule, -1 - i\n\t\t}\n\t}\n\tfor i, rule := range ing.Rules {\n\t\tif rule.Matches(hostname, path) {\n\t\t\treturn &rule, i\n\t\t}\n\t}\n\n\ti := len(ing.Rules) - 1\n\treturn &ing.Rules[i], i\n}\n\nfunc matchHost(ruleHost, reqHost string) bool {\n\tif ruleHost == reqHost {\n\t\treturn true\n\t}\n\n\t// Validate hostnames that use wildcards at the start\n\tif strings.HasPrefix(ruleHost, \"*.\") {\n\t\ttoMatch := strings.TrimPrefix(ruleHost, \"*\")\n\t\treturn strings.HasSuffix(reqHost, toMatch)\n\t}\n\treturn false\n}\n\n// Ingress maps eyeball requests to origins.\ntype Ingress struct {\n\t// Set of ingress rules that are not added to remote config, e.g. management\n\tInternalRules []Rule\n\t// Rules that are provided by the user from remote or local configuration\n\tRules    []Rule              `json:\"ingress\"`\n\tDefaults OriginRequestConfig `json:\"originRequest\"`\n}\n\n// ParseIngress parses ingress rules, but does not send HTTP requests to the origins.\nfunc ParseIngress(conf *config.Configuration) (Ingress, error) {\n\tif conf == nil || len(conf.Ingress) == 0 {\n\t\treturn Ingress{}, ErrNoIngressRules\n\t}\n\treturn validateIngress(conf.Ingress, originRequestFromConfig(conf.OriginRequest))\n}\n\n// ParseIngressFromConfigAndCLI will parse the configuration rules from config files for ingress\n// rules and then attempt to parse CLI for ingress rules.\n// Will always return at least one valid ingress rule. If none are provided by the user, the default\n// will be to return 503 status code for all incoming requests.\nfunc ParseIngressFromConfigAndCLI(conf *config.Configuration, c *cli.Context, log *zerolog.Logger) (Ingress, error) {\n\t// Attempt to parse ingress rules from configuration\n\tingressRules, err := ParseIngress(conf)\n\tif err == nil && !ingressRules.IsEmpty() {\n\t\treturn ingressRules, nil\n\t}\n\tif err != ErrNoIngressRules {\n\t\treturn Ingress{}, err\n\t}\n\t// Attempt to parse ingress rules from CLI:\n\t//   --url or --unix-socket flag for a tunnel HTTP ingress\n\t//   --hello-world for a basic HTTP ingress self-served\n\t//   --bastion for ssh bastion service\n\tingressRules, err = parseCLIIngress(c, false)\n\tif errors.Is(err, ErrNoIngressRulesCLI) {\n\t\t// If no token is provided, the probability of NOT being a remotely managed tunnel is higher.\n\t\t// So, we should warn the user that no ingress rules were found, because remote configuration will most likely not exist.\n\t\tif !c.IsSet(\"token\") {\n\t\t\tlog.Warn().Msg(ErrNoIngressRulesCLI.Error())\n\t\t}\n\t\treturn newDefaultOrigin(c, log), nil\n\t}\n\n\tif err != nil {\n\t\treturn Ingress{}, err\n\t}\n\n\treturn ingressRules, nil\n}\n\n// parseCLIIngress constructs an Ingress set with only one rule constructed from\n// CLI parameters: --url, --hello-world, --bastion, or --unix-socket\nfunc parseCLIIngress(c *cli.Context, allowURLFromArgs bool) (Ingress, error) {\n\tservice, err := parseSingleOriginService(c, allowURLFromArgs)\n\tif err != nil {\n\t\treturn Ingress{}, err\n\t}\n\n\t// Construct an Ingress with the single rule.\n\tdefaults := originRequestFromSingleRule(c)\n\ting := Ingress{\n\t\tRules: []Rule{\n\t\t\t{\n\t\t\t\tService: service,\n\t\t\t\tConfig:  setConfig(defaults, config.OriginRequestConfig{}),\n\t\t\t},\n\t\t},\n\t\tDefaults: defaults,\n\t}\n\treturn ing, err\n}\n\n// newDefaultOrigin always returns a 503 response code to help indicate that there are no ingress\n// rules setup, but the tunnel is reachable.\nfunc newDefaultOrigin(c *cli.Context, log *zerolog.Logger) Ingress {\n\tdefaultRule := GetDefaultIngressRules(log)\n\tdefaults := originRequestFromSingleRule(c)\n\tingress := Ingress{\n\t\tRules:    defaultRule,\n\t\tDefaults: defaults,\n\t}\n\treturn ingress\n}\n\n// Get a single origin service from the CLI/config.\nfunc parseSingleOriginService(c *cli.Context, allowURLFromArgs bool) (OriginService, error) {\n\tif c.IsSet(HelloWorldFlag) {\n\t\treturn new(helloWorld), nil\n\t}\n\tif c.IsSet(config.BastionFlag) {\n\t\treturn newBastionService(), nil\n\t}\n\tif c.IsSet(\"url\") {\n\t\toriginURL, err := config.ValidateUrl(c, allowURLFromArgs)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"Error validating origin URL\")\n\t\t}\n\t\tif isHTTPService(originURL) {\n\t\t\treturn &httpService{\n\t\t\t\turl: originURL,\n\t\t\t}, nil\n\t\t}\n\t\treturn newTCPOverWSService(originURL), nil\n\t}\n\tif c.IsSet(\"unix-socket\") {\n\t\tpath, err := config.ValidateUnixSocket(c)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"Error validating --unix-socket\")\n\t\t}\n\t\treturn &unixSocketPath{path: path, scheme: \"http\"}, nil\n\t}\n\treturn nil, ErrNoIngressRulesCLI\n}\n\n// IsEmpty checks if there are any ingress rules.\nfunc (ing Ingress) IsEmpty() bool {\n\treturn len(ing.Rules) == 0\n}\n\n// IsSingleRule checks if the user only specified a single ingress rule.\nfunc (ing Ingress) IsSingleRule() bool {\n\treturn len(ing.Rules) == 1\n}\n\n// StartOrigins will start any origin services managed by cloudflared, e.g. proxy servers or Hello World.\nfunc (ing Ingress) StartOrigins(\n\tlog *zerolog.Logger,\n\tshutdownC <-chan struct{},\n) error {\n\tfor _, rule := range ing.Rules {\n\t\tif err := rule.Service.start(log, shutdownC, rule.Config); err != nil {\n\t\t\treturn errors.Wrapf(err, \"Error starting local service %s\", rule.Service)\n\t\t}\n\t}\n\treturn nil\n}\n\n// CatchAll returns the catch-all rule (i.e. the last rule)\nfunc (ing Ingress) CatchAll() *Rule {\n\treturn &ing.Rules[len(ing.Rules)-1]\n}\n\n// Gets the default ingress rule that will be return 503 status\n// code for all incoming requests.\nfunc GetDefaultIngressRules(log *zerolog.Logger) []Rule {\n\tnoRulesService := newDefaultStatusCode(log)\n\treturn []Rule{\n\t\t{\n\t\t\tService: &noRulesService,\n\t\t},\n\t}\n}\n\nfunc validateAccessConfiguration(cfg *config.AccessConfig) error {\n\tif !cfg.Required {\n\t\treturn nil\n\t}\n\n\t// we allow for an initial setup where user can force Access but not configure the rest of the keys.\n\t// however, if the user specified audTags but forgot teamName, we should alert it.\n\tif cfg.TeamName == \"\" && len(cfg.AudTag) > 0 {\n\t\treturn errors.New(\"access.TeamName cannot be blank when access.audTags are present\")\n\t}\n\n\treturn nil\n}\n\nfunc validateIngress(ingress []config.UnvalidatedIngressRule, defaults OriginRequestConfig) (Ingress, error) {\n\trules := make([]Rule, len(ingress))\n\tfor i, r := range ingress {\n\t\tcfg := setConfig(defaults, r.OriginRequest)\n\t\tvar service OriginService\n\n\t\tif prefix := \"unix:\"; strings.HasPrefix(r.Service, prefix) {\n\t\t\t// No validation necessary for unix socket filepath services\n\t\t\tpath := strings.TrimPrefix(r.Service, prefix)\n\t\t\tservice = &unixSocketPath{path: path, scheme: \"http\"}\n\t\t} else if prefix := \"unix+tls:\"; strings.HasPrefix(r.Service, prefix) {\n\t\t\tpath := strings.TrimPrefix(r.Service, prefix)\n\t\t\tservice = &unixSocketPath{path: path, scheme: \"https\"}\n\t\t} else if prefix := \"http_status:\"; strings.HasPrefix(r.Service, prefix) {\n\t\t\tstatusCode, err := strconv.Atoi(strings.TrimPrefix(r.Service, prefix))\n\t\t\tif err != nil {\n\t\t\t\treturn Ingress{}, errors.Wrap(err, \"invalid HTTP status code\")\n\t\t\t}\n\t\t\tif statusCode < 100 || statusCode > 999 {\n\t\t\t\treturn Ingress{}, fmt.Errorf(\"invalid HTTP status code: %d\", statusCode)\n\t\t\t}\n\t\t\tsrv := newStatusCode(statusCode)\n\t\t\tservice = &srv\n\t\t} else if r.Service == HelloWorldFlag || r.Service == HelloWorldService {\n\t\t\tservice = new(helloWorld)\n\t\t} else if r.Service == ServiceSocksProxy {\n\t\t\trules := make([]ipaccess.Rule, len(r.OriginRequest.IPRules))\n\n\t\t\tfor i, ipRule := range r.OriginRequest.IPRules {\n\t\t\t\trule, err := ipaccess.NewRuleByCIDR(ipRule.Prefix, ipRule.Ports, ipRule.Allow)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn Ingress{}, fmt.Errorf(\"unable to create ip rule for %s: %s\", r.Service, err)\n\t\t\t\t}\n\t\t\t\trules[i] = rule\n\t\t\t}\n\n\t\t\taccessPolicy, err := ipaccess.NewPolicy(false, rules)\n\t\t\tif err != nil {\n\t\t\t\treturn Ingress{}, fmt.Errorf(\"unable to create ip access policy for %s: %s\", r.Service, err)\n\t\t\t}\n\n\t\t\tservice = newSocksProxyOverWSService(accessPolicy)\n\t\t} else if r.Service == ServiceBastion || cfg.BastionMode {\n\t\t\t// Bastion mode will always start a Websocket proxy server, which will\n\t\t\t// overwrite the localService.URL field when `start` is called. So,\n\t\t\t// leave the URL field empty for now.\n\t\t\tcfg.BastionMode = true\n\t\t\tservice = newBastionService()\n\t\t} else {\n\t\t\t// Validate URL services\n\t\t\tu, err := url.Parse(r.Service)\n\t\t\tif err != nil {\n\t\t\t\treturn Ingress{}, err\n\t\t\t}\n\n\t\t\tif u.Scheme == \"\" || u.Hostname() == \"\" {\n\t\t\t\treturn Ingress{}, fmt.Errorf(\"%s is an invalid address, please make sure it has a scheme and a hostname\", r.Service)\n\t\t\t}\n\n\t\t\tif u.Path != \"\" {\n\t\t\t\treturn Ingress{}, fmt.Errorf(\"%s is an invalid address, ingress rules don't support proxying to a different path on the origin service. The path will be the same as the eyeball request's path\", r.Service)\n\t\t\t}\n\t\t\tif isHTTPService(u) {\n\t\t\t\tservice = &httpService{url: u}\n\t\t\t} else {\n\t\t\t\tservice = newTCPOverWSService(u)\n\t\t\t}\n\t\t}\n\n\t\tvar handlers []middleware.Handler\n\t\tif access := r.OriginRequest.Access; access != nil {\n\t\t\tif err := validateAccessConfiguration(access); err != nil {\n\t\t\t\treturn Ingress{}, err\n\t\t\t}\n\t\t\tif access.Required {\n\t\t\t\tverifier := middleware.NewJWTValidator(access.TeamName, access.Environment, access.AudTag)\n\t\t\t\thandlers = append(handlers, verifier)\n\t\t\t}\n\t\t}\n\n\t\tif err := validateHostname(r, i, len(ingress)); err != nil {\n\t\t\treturn Ingress{}, err\n\t\t}\n\n\t\tisCatchAllRule := (r.Hostname == \"\" || r.Hostname == \"*\") && r.Path == \"\"\n\t\tpunycodeHostname := \"\"\n\t\tif !isCatchAllRule {\n\t\t\tpunycode, err := idna.Lookup.ToASCII(r.Hostname)\n\t\t\t// Don't provide the punycode hostname if it is the same as the original hostname\n\t\t\tif err == nil && punycode != r.Hostname {\n\t\t\t\tpunycodeHostname = punycode\n\t\t\t}\n\t\t}\n\n\t\tvar pathRegexp *Regexp\n\t\tif r.Path != \"\" {\n\t\t\tvar err error\n\t\t\tregex, err := regexp.Compile(r.Path)\n\t\t\tif err != nil {\n\t\t\t\treturn Ingress{}, errors.Wrapf(err, \"Rule #%d has an invalid regex\", i+1)\n\t\t\t}\n\t\t\tpathRegexp = &Regexp{Regexp: regex}\n\t\t}\n\n\t\trules[i] = Rule{\n\t\t\tHostname:         r.Hostname,\n\t\t\tpunycodeHostname: punycodeHostname,\n\t\t\tService:          service,\n\t\t\tPath:             pathRegexp,\n\t\t\tHandlers:         handlers,\n\t\t\tConfig:           cfg,\n\t\t}\n\t}\n\treturn Ingress{Rules: rules, Defaults: defaults}, nil\n}\n\nfunc validateHostname(r config.UnvalidatedIngressRule, ruleIndex, totalRules int) error {\n\t// Ensure that the hostname doesn't contain port\n\t_, _, err := net.SplitHostPort(r.Hostname)\n\tif err == nil {\n\t\treturn errHostnameContainsPort\n\t}\n\t// Ensure that there are no wildcards anywhere except the first character\n\t// of the hostname.\n\tif strings.LastIndex(r.Hostname, \"*\") > 0 {\n\t\treturn errBadWildcard\n\t}\n\n\t// The last rule should catch all hostnames.\n\tisCatchAllRule := (r.Hostname == \"\" || r.Hostname == \"*\") && r.Path == \"\"\n\tisLastRule := ruleIndex == totalRules-1\n\tif isLastRule && !isCatchAllRule {\n\t\treturn errLastRuleNotCatchAll\n\t}\n\t// ONLY the last rule should catch all hostnames.\n\tif !isLastRule && isCatchAllRule {\n\t\treturn ruleShouldNotBeCatchAllError{index: ruleIndex, hostname: r.Hostname}\n\t}\n\treturn nil\n}\n\ntype ruleShouldNotBeCatchAllError struct {\n\tindex    int\n\thostname string\n}\n\nfunc (e ruleShouldNotBeCatchAllError) Error() string {\n\treturn fmt.Sprintf(\"Rule #%d is matching the hostname '%s', but \"+\n\t\t\"this will match every hostname, meaning the rules which follow it \"+\n\t\t\"will never be triggered.\", e.index+1, e.hostname)\n}\n\nfunc isHTTPService(url *url.URL) bool {\n\treturn url.Scheme == \"http\" || url.Scheme == \"https\" || url.Scheme == \"ws\" || url.Scheme == \"wss\"\n}\n"
  },
  {
    "path": "ingress/ingress_test.go",
    "content": "package ingress\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"regexp\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"github.com/urfave/cli/v2\"\n\tyaml \"gopkg.in/yaml.v3\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/ipaccess\"\n\t\"github.com/cloudflare/cloudflared/tlsconfig\"\n)\n\nfunc TestParseUnixSocket(t *testing.T) {\n\trawYAML := `\ningress:\n- service: unix:/tmp/echo.sock\n`\n\ting, err := ParseIngress(MustReadIngress(rawYAML))\n\trequire.NoError(t, err)\n\ts, ok := ing.Rules[0].Service.(*unixSocketPath)\n\trequire.True(t, ok)\n\trequire.Equal(t, \"http\", s.scheme)\n}\n\nfunc TestParseUnixSocketTLS(t *testing.T) {\n\trawYAML := `\ningress:\n- service: unix+tls:/tmp/echo.sock\n`\n\ting, err := ParseIngress(MustReadIngress(rawYAML))\n\trequire.NoError(t, err)\n\ts, ok := ing.Rules[0].Service.(*unixSocketPath)\n\trequire.True(t, ok)\n\trequire.Equal(t, \"https\", s.scheme)\n}\n\nfunc TestParseIngressNilConfig(t *testing.T) {\n\t_, err := ParseIngress(nil)\n\trequire.Error(t, err)\n}\n\nfunc TestParseIngress(t *testing.T) {\n\tlocalhost8000 := MustParseURL(t, \"https://localhost:8000\")\n\tlocalhost8001 := MustParseURL(t, \"https://localhost:8001\")\n\tfourOhFour := newStatusCode(404)\n\tdefaultConfig := setConfig(originRequestFromConfig(config.OriginRequestConfig{}), config.OriginRequestConfig{})\n\trequire.Equal(t, defaultKeepAliveConnections, defaultConfig.KeepAliveConnections)\n\ttr := true\n\ttype args struct {\n\t\trawYAML string\n\t}\n\ttests := []struct {\n\t\tname    string\n\t\targs    args\n\t\twant    []Rule\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname:    \"Empty file\",\n\t\t\targs:    args{rawYAML: \"\"},\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Multiple rules\",\n\t\t\targs: args{rawYAML: `\ningress:\n - hostname: tunnel1.example.com\n   service: https://localhost:8000\n - hostname: \"*\"\n   service: https://localhost:8001\n`},\n\t\t\twant: []Rule{\n\t\t\t\t{\n\t\t\t\t\tHostname: \"tunnel1.example.com\",\n\t\t\t\t\tService:  &httpService{url: localhost8000},\n\t\t\t\t\tConfig:   defaultConfig,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tHostname: \"*\",\n\t\t\t\t\tService:  &httpService{url: localhost8001},\n\t\t\t\t\tConfig:   defaultConfig,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Extra keys\",\n\t\t\targs: args{rawYAML: `\ningress:\n - hostname: \"*\"\n   service: https://localhost:8000\nextraKey: extraValue\n`},\n\t\t\twant: []Rule{\n\t\t\t\t{\n\t\t\t\t\tHostname: \"*\",\n\t\t\t\t\tService:  &httpService{url: localhost8000},\n\t\t\t\t\tConfig:   defaultConfig,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"ws service\",\n\t\t\targs: args{rawYAML: `\ningress:\n - hostname: \"*\"\n   service: wss://localhost:8000\n`},\n\t\t\twant: []Rule{\n\t\t\t\t{\n\t\t\t\t\tHostname: \"*\",\n\t\t\t\t\tService:  &httpService{url: MustParseURL(t, \"wss://localhost:8000\")},\n\t\t\t\t\tConfig:   defaultConfig,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Hostname can be omitted\",\n\t\t\targs: args{rawYAML: `\ningress:\n - service: https://localhost:8000\n`},\n\t\t\twant: []Rule{\n\t\t\t\t{\n\t\t\t\t\tService: &httpService{url: localhost8000},\n\t\t\t\t\tConfig:  defaultConfig,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Unicode domain\",\n\t\t\targs: args{rawYAML: `\ningress:\n - hostname: môô.cloudflare.com\n   service: https://localhost:8000\n - service: https://localhost:8001\n`},\n\t\t\twant: []Rule{\n\t\t\t\t{\n\t\t\t\t\tHostname:         \"môô.cloudflare.com\",\n\t\t\t\t\tpunycodeHostname: \"xn--m-xgaa.cloudflare.com\",\n\t\t\t\t\tService:          &httpService{url: localhost8000},\n\t\t\t\t\tConfig:           defaultConfig,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tService: &httpService{url: localhost8001},\n\t\t\t\t\tConfig:  defaultConfig,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Invalid unicode domain\",\n\t\t\targs: args{rawYAML: fmt.Sprintf(`\ningress:\n - hostname: %s\n   service: https://localhost:8000\n`, string(rune(0xd8f3))+\".cloudflare.com\")},\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Invalid service\",\n\t\t\targs: args{rawYAML: `\ningress:\n - hostname: \"*\"\n   service: https://local host:8000\n`},\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Last rule isn't catchall\",\n\t\t\targs: args{rawYAML: `\ningress:\n - hostname: example.com\n   service: https://localhost:8000\n`},\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname: \"First rule is catchall\",\n\t\t\targs: args{rawYAML: `\ningress:\n - service: https://localhost:8000\n - hostname: example.com\n   service: https://localhost:8000\n`},\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Catch-all rule can't have a path\",\n\t\t\targs: args{rawYAML: `\ningress:\n - service: https://localhost:8001\n   path: /subpath1/(.*)/subpath2\n`},\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Invalid regex\",\n\t\t\targs: args{rawYAML: `\ningress:\n - hostname: example.com\n   service: https://localhost:8000\n   path: \"*/subpath2\"\n - service: https://localhost:8001\n`},\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Service must have a scheme\",\n\t\t\targs: args{rawYAML: `\ningress:\n - service: localhost:8000\n`},\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Wildcard not at start\",\n\t\t\targs: args{rawYAML: `\ningress:\n - hostname: \"test.*.example.com\"\n   service: https://localhost:8000\n`},\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Service can't have a path\",\n\t\t\targs: args{rawYAML: `\ningress:\n - service: https://localhost:8000/static/\n`},\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Invalid HTTP status\",\n\t\t\targs: args{rawYAML: `\ningress:\n - service: http_status:asdf\n`},\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Invalid HTTP status code\",\n\t\t\targs: args{rawYAML: `\ningress:\n - service: http_status:8080\n`},\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Valid HTTP status\",\n\t\t\targs: args{rawYAML: `\ningress:\n - service: http_status:404\n`},\n\t\t\twant: []Rule{\n\t\t\t\t{\n\t\t\t\t\tHostname: \"\",\n\t\t\t\t\tService:  &fourOhFour,\n\t\t\t\t\tConfig:   defaultConfig,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Valid hello world service\",\n\t\t\targs: args{rawYAML: `\ningress:\n - service: hello_world\n`},\n\t\t\twant: []Rule{\n\t\t\t\t{\n\t\t\t\t\tHostname: \"\",\n\t\t\t\t\tService:  new(helloWorld),\n\t\t\t\t\tConfig:   defaultConfig,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"TCP services\",\n\t\t\targs: args{rawYAML: `\ningress:\n- hostname: tcp.foo.com\n  service: tcp://127.0.0.1\n- hostname: tcp2.foo.com\n  service: tcp://localhost:8000\n- service: http_status:404\n`},\n\t\t\twant: []Rule{\n\t\t\t\t{\n\t\t\t\t\tHostname: \"tcp.foo.com\",\n\t\t\t\t\tService:  newTCPOverWSService(MustParseURL(t, \"tcp://127.0.0.1:7864\")),\n\t\t\t\t\tConfig:   defaultConfig,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tHostname: \"tcp2.foo.com\",\n\t\t\t\t\tService:  newTCPOverWSService(MustParseURL(t, \"tcp://localhost:8000\")),\n\t\t\t\t\tConfig:   defaultConfig,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tService: &fourOhFour,\n\t\t\t\t\tConfig:  defaultConfig,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"SSH services\",\n\t\t\targs: args{rawYAML: `\ningress:\n- service: ssh://127.0.0.1\n`},\n\t\t\twant: []Rule{\n\t\t\t\t{\n\t\t\t\t\tService: newTCPOverWSService(MustParseURL(t, \"ssh://127.0.0.1:22\")),\n\t\t\t\t\tConfig:  defaultConfig,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"RDP services\",\n\t\t\targs: args{rawYAML: `\ningress:\n- service: rdp://127.0.0.1\n`},\n\t\t\twant: []Rule{\n\t\t\t\t{\n\t\t\t\t\tService: newTCPOverWSService(MustParseURL(t, \"rdp://127.0.0.1:3389\")),\n\t\t\t\t\tConfig:  defaultConfig,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"SMB services\",\n\t\t\targs: args{rawYAML: `\ningress:\n- service: smb://127.0.0.1\n`},\n\t\t\twant: []Rule{\n\t\t\t\t{\n\t\t\t\t\tService: newTCPOverWSService(MustParseURL(t, \"smb://127.0.0.1:445\")),\n\t\t\t\t\tConfig:  defaultConfig,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Other TCP services\",\n\t\t\targs: args{rawYAML: `\ningress:\n- service: ftp://127.0.0.1\n`},\n\t\t\twant: []Rule{\n\t\t\t\t{\n\t\t\t\t\tService: newTCPOverWSService(MustParseURL(t, \"ftp://127.0.0.1\")),\n\t\t\t\t\tConfig:  defaultConfig,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"SOCKS services\",\n\t\t\targs: args{rawYAML: `\ningress:\n- hostname: socks.foo.com\n  service: socks-proxy\n  originRequest:\n    ipRules:\n      - prefix: 1.1.1.0/24\n        ports: [80, 443]\n        allow: true\n      - prefix: 0.0.0.0/0\n        allow: false\n- service: http_status:404\n`},\n\t\t\twant: []Rule{\n\t\t\t\t{\n\t\t\t\t\tHostname: \"socks.foo.com\",\n\t\t\t\t\tService:  newSocksProxyOverWSService(accessPolicy()),\n\t\t\t\t\tConfig: setConfig(originRequestFromConfig(config.OriginRequestConfig{}), config.OriginRequestConfig{IPRules: []config.IngressIPRule{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPrefix: ipRulePrefix(\"1.1.1.0/24\"),\n\t\t\t\t\t\t\tPorts:  []int{80, 443},\n\t\t\t\t\t\t\tAllow:  true,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tPrefix: ipRulePrefix(\"0.0.0.0/0\"),\n\t\t\t\t\t\t\tAllow:  false,\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\tService: &fourOhFour,\n\t\t\t\t\tConfig:  defaultConfig,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"URL isn't necessary if using bastion\",\n\t\t\targs: args{rawYAML: `\ningress:\n- hostname: bastion.foo.com\n  originRequest:\n    bastionMode: true\n- service: http_status:404\n`},\n\t\t\twant: []Rule{\n\t\t\t\t{\n\t\t\t\t\tHostname: \"bastion.foo.com\",\n\t\t\t\t\tService:  newBastionService(),\n\t\t\t\t\tConfig:   setConfig(originRequestFromConfig(config.OriginRequestConfig{}), config.OriginRequestConfig{BastionMode: &tr}),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tService: &fourOhFour,\n\t\t\t\t\tConfig:  defaultConfig,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Bastion service\",\n\t\t\targs: args{rawYAML: `\ningress:\n- hostname: bastion.foo.com\n  service: bastion\n- service: http_status:404\n`},\n\t\t\twant: []Rule{\n\t\t\t\t{\n\t\t\t\t\tHostname: \"bastion.foo.com\",\n\t\t\t\t\tService:  newBastionService(),\n\t\t\t\t\tConfig:   setConfig(originRequestFromConfig(config.OriginRequestConfig{}), config.OriginRequestConfig{BastionMode: &tr}),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tService: &fourOhFour,\n\t\t\t\t\tConfig:  defaultConfig,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Hostname contains port\",\n\t\t\targs: args{rawYAML: `\ningress:\n - hostname: \"test.example.com:443\"\n   service: https://localhost:8000\n - hostname: \"*\"\n   service: https://localhost:8001\n`},\n\t\t\twantErr: true,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot, err := ParseIngress(MustReadIngress(tt.args.rawYAML))\n\t\t\tif (err != nil) != tt.wantErr {\n\t\t\t\tt.Errorf(\"ParseIngress() error = %v, wantErr %v\", err, tt.wantErr)\n\t\t\t\treturn\n\t\t\t}\n\t\t\trequire.Equal(t, tt.want, got.Rules)\n\t\t})\n\t}\n}\n\nfunc ipRulePrefix(s string) *string {\n\treturn &s\n}\n\nfunc TestSingleOriginSetsConfig(t *testing.T) {\n\tflagSet := flag.NewFlagSet(t.Name(), flag.PanicOnError)\n\tflagSet.Bool(\"hello-world\", true, \"\")\n\tflagSet.Duration(ProxyConnectTimeoutFlag, time.Second, \"\")\n\tflagSet.Duration(ProxyTLSTimeoutFlag, time.Second, \"\")\n\tflagSet.Duration(ProxyTCPKeepAliveFlag, time.Second, \"\")\n\tflagSet.Bool(ProxyNoHappyEyeballsFlag, true, \"\")\n\tflagSet.Int(ProxyKeepAliveConnectionsFlag, 10, \"\")\n\tflagSet.Duration(ProxyKeepAliveTimeoutFlag, time.Second, \"\")\n\tflagSet.String(HTTPHostHeaderFlag, \"example.com:8080\", \"\")\n\tflagSet.String(OriginServerNameFlag, \"example.com\", \"\")\n\tflagSet.String(tlsconfig.OriginCAPoolFlag, \"/etc/certs/ca.pem\", \"\")\n\tflagSet.Bool(NoTLSVerifyFlag, true, \"\")\n\tflagSet.Bool(NoChunkedEncodingFlag, true, \"\")\n\tflagSet.Bool(config.BastionFlag, true, \"\")\n\tflagSet.String(ProxyAddressFlag, \"localhost:8080\", \"\")\n\tflagSet.Uint(ProxyPortFlag, 8080, \"\")\n\tflagSet.Bool(Socks5Flag, true, \"\")\n\n\tcliCtx := cli.NewContext(cli.NewApp(), flagSet, nil)\n\terr := cliCtx.Set(\"hello-world\", \"true\")\n\trequire.NoError(t, err)\n\terr = cliCtx.Set(ProxyConnectTimeoutFlag, \"1s\")\n\trequire.NoError(t, err)\n\terr = cliCtx.Set(ProxyTLSTimeoutFlag, \"1s\")\n\trequire.NoError(t, err)\n\terr = cliCtx.Set(ProxyTCPKeepAliveFlag, \"1s\")\n\trequire.NoError(t, err)\n\terr = cliCtx.Set(ProxyNoHappyEyeballsFlag, \"true\")\n\trequire.NoError(t, err)\n\terr = cliCtx.Set(ProxyKeepAliveConnectionsFlag, \"10\")\n\trequire.NoError(t, err)\n\terr = cliCtx.Set(ProxyKeepAliveTimeoutFlag, \"1s\")\n\trequire.NoError(t, err)\n\terr = cliCtx.Set(HTTPHostHeaderFlag, \"example.com:8080\")\n\trequire.NoError(t, err)\n\terr = cliCtx.Set(OriginServerNameFlag, \"example.com\")\n\trequire.NoError(t, err)\n\terr = cliCtx.Set(tlsconfig.OriginCAPoolFlag, \"/etc/certs/ca.pem\")\n\trequire.NoError(t, err)\n\terr = cliCtx.Set(NoTLSVerifyFlag, \"true\")\n\trequire.NoError(t, err)\n\terr = cliCtx.Set(NoChunkedEncodingFlag, \"true\")\n\trequire.NoError(t, err)\n\terr = cliCtx.Set(config.BastionFlag, \"true\")\n\trequire.NoError(t, err)\n\terr = cliCtx.Set(ProxyAddressFlag, \"localhost:8080\")\n\trequire.NoError(t, err)\n\terr = cliCtx.Set(ProxyPortFlag, \"8080\")\n\trequire.NoError(t, err)\n\terr = cliCtx.Set(Socks5Flag, \"true\")\n\trequire.NoError(t, err)\n\n\tallowURLFromArgs := false\n\trequire.NoError(t, err)\n\tingress, err := parseCLIIngress(cliCtx, allowURLFromArgs)\n\trequire.NoError(t, err)\n\n\tassert.Equal(t, config.CustomDuration{Duration: time.Second}, ingress.Rules[0].Config.ConnectTimeout)\n\tassert.Equal(t, config.CustomDuration{Duration: time.Second}, ingress.Rules[0].Config.TLSTimeout)\n\tassert.Equal(t, config.CustomDuration{Duration: time.Second}, ingress.Rules[0].Config.TCPKeepAlive)\n\tassert.True(t, ingress.Rules[0].Config.NoHappyEyeballs)\n\tassert.Equal(t, 10, ingress.Rules[0].Config.KeepAliveConnections)\n\tassert.Equal(t, config.CustomDuration{Duration: time.Second}, ingress.Rules[0].Config.KeepAliveTimeout)\n\tassert.Equal(t, \"example.com:8080\", ingress.Rules[0].Config.HTTPHostHeader)\n\tassert.Equal(t, \"example.com\", ingress.Rules[0].Config.OriginServerName)\n\tassert.Equal(t, \"/etc/certs/ca.pem\", ingress.Rules[0].Config.CAPool)\n\tassert.True(t, ingress.Rules[0].Config.NoTLSVerify)\n\tassert.True(t, ingress.Rules[0].Config.DisableChunkedEncoding)\n\tassert.True(t, ingress.Rules[0].Config.BastionMode)\n\tassert.Equal(t, \"localhost:8080\", ingress.Rules[0].Config.ProxyAddress)\n\tassert.Equal(t, uint(8080), ingress.Rules[0].Config.ProxyPort)\n\tassert.Equal(t, socksProxy, ingress.Rules[0].Config.ProxyType)\n}\n\nfunc TestSingleOriginServices(t *testing.T) {\n\thost := \"://localhost:8080\"\n\thttpURL := urlMustParse(\"http\" + host)\n\ttcpURL := urlMustParse(\"tcp\" + host)\n\tunix := \"unix://service\"\n\tnewCli := func(params ...string) *cli.Context {\n\t\tflagSet := flag.NewFlagSet(t.Name(), flag.PanicOnError)\n\t\tflagSet.Bool(\"hello-world\", false, \"\")\n\t\tflagSet.Bool(\"bastion\", false, \"\")\n\t\tflagSet.String(\"url\", \"\", \"\")\n\t\tflagSet.String(\"unix-socket\", \"\", \"\")\n\t\tcliCtx := cli.NewContext(cli.NewApp(), flagSet, nil)\n\t\tfor i := 0; i < len(params); i += 2 {\n\t\t\tcliCtx.Set(params[i], params[i+1])\n\t\t}\n\n\t\treturn cliCtx\n\t}\n\n\ttests := []struct {\n\t\tname            string\n\t\tcli             *cli.Context\n\t\texpectedService OriginService\n\t\terr             error\n\t}{\n\t\t{\n\t\t\tname:            \"Valid hello-world\",\n\t\t\tcli:             newCli(\"hello-world\", \"true\"),\n\t\t\texpectedService: &helloWorld{},\n\t\t},\n\t\t{\n\t\t\tname:            \"Valid bastion\",\n\t\t\tcli:             newCli(\"bastion\", \"true\"),\n\t\t\texpectedService: newBastionService(),\n\t\t},\n\t\t{\n\t\t\tname:            \"Valid http url\",\n\t\t\tcli:             newCli(\"url\", httpURL.String()),\n\t\t\texpectedService: &httpService{url: httpURL},\n\t\t},\n\t\t{\n\t\t\tname:            \"Valid tcp url\",\n\t\t\tcli:             newCli(\"url\", tcpURL.String()),\n\t\t\texpectedService: newTCPOverWSService(tcpURL),\n\t\t},\n\t\t{\n\t\t\tname:            \"Valid unix-socket\",\n\t\t\tcli:             newCli(\"unix-socket\", unix),\n\t\t\texpectedService: &unixSocketPath{path: unix, scheme: \"http\"},\n\t\t},\n\t\t{\n\t\t\tname: \"No origins defined\",\n\t\t\tcli:  newCli(),\n\t\t\terr:  ErrNoIngressRulesCLI,\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tingress, err := parseCLIIngress(test.cli, false)\n\t\t\trequire.Equal(t, err, test.err)\n\t\t\tif test.err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\trequire.Equal(t, 1, len(ingress.Rules))\n\t\t\trule := ingress.Rules[0]\n\t\t\trequire.Equal(t, test.expectedService, rule.Service)\n\t\t})\n\t}\n}\n\nfunc urlMustParse(s string) *url.URL {\n\tu, err := url.Parse(s)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn u\n}\n\nfunc TestSingleOriginServices_URL(t *testing.T) {\n\thost := \"://localhost:8080\"\n\tnewCli := func(param string, value string) *cli.Context {\n\t\tflagSet := flag.NewFlagSet(t.Name(), flag.PanicOnError)\n\t\tflagSet.String(\"url\", \"\", \"\")\n\t\tcliCtx := cli.NewContext(cli.NewApp(), flagSet, nil)\n\t\tcliCtx.Set(param, value)\n\t\treturn cliCtx\n\t}\n\n\thttpTests := []string{\"http\", \"https\"}\n\tfor _, test := range httpTests {\n\t\tt.Run(test, func(t *testing.T) {\n\t\t\turl := urlMustParse(test + host)\n\t\t\tingress, err := parseCLIIngress(newCli(\"url\", url.String()), false)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, 1, len(ingress.Rules))\n\t\t\trule := ingress.Rules[0]\n\t\t\trequire.Equal(t, &httpService{url: url}, rule.Service)\n\t\t})\n\t}\n\n\ttcpTests := []string{\"ssh\", \"rdp\", \"smb\", \"tcp\"}\n\tfor _, test := range tcpTests {\n\t\tt.Run(test, func(t *testing.T) {\n\t\t\turl := urlMustParse(test + host)\n\t\t\tingress, err := parseCLIIngress(newCli(\"url\", url.String()), false)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, 1, len(ingress.Rules))\n\t\t\trule := ingress.Rules[0]\n\t\t\trequire.Equal(t, newTCPOverWSService(url), rule.Service)\n\t\t})\n\t}\n}\n\nfunc TestFindMatchingRule(t *testing.T) {\n\tingress := Ingress{\n\t\tRules: []Rule{\n\t\t\t{\n\t\t\t\tHostname: \"tunnel-a.example.com\",\n\t\t\t\tPath:     nil,\n\t\t\t},\n\t\t\t{\n\t\t\t\tHostname: \"tunnel-b.example.com\",\n\t\t\t\tPath:     MustParsePath(t, \"/health\"),\n\t\t\t},\n\t\t\t{\n\t\t\t\tHostname: \"*\",\n\t\t\t},\n\t\t},\n\t}\n\n\ttests := []struct {\n\t\thost          string\n\t\tpath          string\n\t\treq           *http.Request\n\t\twantRuleIndex int\n\t}{\n\t\t{\n\t\t\thost:          \"tunnel-a.example.com\",\n\t\t\tpath:          \"/\",\n\t\t\twantRuleIndex: 0,\n\t\t},\n\t\t{\n\t\t\thost:          \"tunnel-a.example.com\",\n\t\t\tpath:          \"/pages/about\",\n\t\t\twantRuleIndex: 0,\n\t\t},\n\t\t{\n\t\t\thost:          \"tunnel-a.example.com:443\",\n\t\t\tpath:          \"/pages/about\",\n\t\t\twantRuleIndex: 0,\n\t\t},\n\t\t{\n\t\t\thost:          \"tunnel-b.example.com\",\n\t\t\tpath:          \"/health\",\n\t\t\twantRuleIndex: 1,\n\t\t},\n\t\t{\n\t\t\thost:          \"tunnel-b.example.com\",\n\t\t\tpath:          \"/index.html\",\n\t\t\twantRuleIndex: 2,\n\t\t},\n\t\t{\n\t\t\thost:          \"tunnel-c.example.com\",\n\t\t\tpath:          \"/\",\n\t\t\twantRuleIndex: 2,\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\t_, ruleIndex := ingress.FindMatchingRule(test.host, test.path)\n\t\tassert.Equal(t, test.wantRuleIndex, ruleIndex, fmt.Sprintf(\"Expect host=%s, path=%s to match rule %d, got %d\", test.host, test.path, test.wantRuleIndex, ruleIndex))\n\t}\n}\n\nfunc TestIsHTTPService(t *testing.T) {\n\ttests := []struct {\n\t\turl    *url.URL\n\t\tisHTTP bool\n\t}{\n\t\t{\n\t\t\turl:    MustParseURL(t, \"http://localhost\"),\n\t\t\tisHTTP: true,\n\t\t},\n\t\t{\n\t\t\turl:    MustParseURL(t, \"https://127.0.0.1:8000\"),\n\t\t\tisHTTP: true,\n\t\t},\n\t\t{\n\t\t\turl:    MustParseURL(t, \"ws://localhost\"),\n\t\t\tisHTTP: true,\n\t\t},\n\t\t{\n\t\t\turl:    MustParseURL(t, \"wss://localhost:8000\"),\n\t\t\tisHTTP: true,\n\t\t},\n\t\t{\n\t\t\turl:    MustParseURL(t, \"tcp://localhost:9000\"),\n\t\t\tisHTTP: false,\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\tassert.Equal(t, test.isHTTP, isHTTPService(test.url))\n\t}\n}\n\nfunc MustParsePath(t *testing.T, path string) *Regexp {\n\tregexp, err := regexp.Compile(path)\n\tassert.NoError(t, err)\n\treturn &Regexp{Regexp: regexp}\n}\n\nfunc MustParseURL(t *testing.T, rawURL string) *url.URL {\n\tu, err := url.Parse(rawURL)\n\trequire.NoError(t, err)\n\treturn u\n}\n\nfunc accessPolicy() *ipaccess.Policy {\n\tcidr1 := \"1.1.1.0/24\"\n\tcidr2 := \"0.0.0.0/0\"\n\trule1, _ := ipaccess.NewRuleByCIDR(&cidr1, []int{80, 443}, true)\n\trule2, _ := ipaccess.NewRuleByCIDR(&cidr2, nil, false)\n\trules := []ipaccess.Rule{rule1, rule2}\n\taccessPolicy, _ := ipaccess.NewPolicy(false, rules)\n\treturn accessPolicy\n}\n\nfunc BenchmarkFindMatch(b *testing.B) {\n\trulesYAML := `\ningress:\n - hostname: tunnel1.example.com\n   service: https://localhost:8000\n - hostname: tunnel2.example.com\n   service: https://localhost:8001\n - hostname: \"*\"\n   service: https://localhost:8002\n`\n\n\ting, err := ParseIngress(MustReadIngress(rulesYAML))\n\tif err != nil {\n\t\tb.Error(err)\n\t}\n\n\tfor n := 0; n < b.N; n++ {\n\t\ting.FindMatchingRule(\"tunnel1.example.com\", \"\")\n\t\ting.FindMatchingRule(\"tunnel2.example.com\", \"\")\n\t\ting.FindMatchingRule(\"tunnel3.example.com\", \"\")\n\t}\n}\n\nfunc TestParseAccessConfig(t *testing.T) {\n\ttests := []struct {\n\t\tname        string\n\t\tcfg         config.AccessConfig\n\t\texpectError bool\n\t}{\n\t\t{\n\t\t\tname:        \"Config required with teamName only\",\n\t\t\tcfg:         config.AccessConfig{Required: true, TeamName: \"team\"},\n\t\t\texpectError: false,\n\t\t},\n\t\t{\n\t\t\tname:        \"required false\",\n\t\t\tcfg:         config.AccessConfig{Required: false},\n\t\t\texpectError: false,\n\t\t},\n\t\t{\n\t\t\tname:        \"required true but empty config\",\n\t\t\tcfg:         config.AccessConfig{Required: true},\n\t\t\texpectError: false,\n\t\t},\n\t\t{\n\t\t\tname:        \"complete config\",\n\t\t\tcfg:         config.AccessConfig{Required: true, TeamName: \"team\", AudTag: []string{\"a\"}},\n\t\t\texpectError: false,\n\t\t},\n\t\t{\n\t\t\tname:        \"required true with audTags but no teamName\",\n\t\t\tcfg:         config.AccessConfig{Required: true, AudTag: []string{\"a\"}},\n\t\t\texpectError: true,\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\terr := validateAccessConfiguration(&test.cfg)\n\t\t\trequire.Equal(t, err != nil, test.expectError)\n\t\t})\n\t}\n}\n\nfunc MustReadIngress(s string) *config.Configuration {\n\tvar conf config.Configuration\n\terr := yaml.Unmarshal([]byte(s), &conf)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn &conf\n}\n"
  },
  {
    "path": "ingress/middleware/jwtvalidator.go",
    "content": "package middleware\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/coreos/go-oidc/v3/oidc\"\n\n\t\"github.com/cloudflare/cloudflared/credentials\"\n)\n\nconst (\n\theaderKeyAccessJWTAssertion = \"Cf-Access-Jwt-Assertion\"\n)\n\nvar (\n\tcloudflareAccessCertsURL    = \"https://%s.cloudflareaccess.com\"\n\tcloudflareAccessFedCertsURL = \"https://%s.fed.cloudflareaccess.com\"\n)\n\n// JWTValidator is an implementation of Verifier that validates access based JWT tokens.\ntype JWTValidator struct {\n\t*oidc.IDTokenVerifier\n\taudTags []string\n}\n\nfunc NewJWTValidator(teamName string, environment string, audTags []string) *JWTValidator {\n\tvar certsURL string\n\tif environment == credentials.FedEndpoint {\n\t\tcertsURL = fmt.Sprintf(cloudflareAccessFedCertsURL, teamName)\n\t} else {\n\t\tcertsURL = fmt.Sprintf(cloudflareAccessCertsURL, teamName)\n\t}\n\n\tcertsEndpoint := fmt.Sprintf(\"%s/cdn-cgi/access/certs\", certsURL)\n\n\tconfig := &oidc.Config{\n\t\tSkipClientIDCheck: true,\n\t}\n\n\tctx := context.Background()\n\tkeySet := oidc.NewRemoteKeySet(ctx, certsEndpoint)\n\tverifier := oidc.NewVerifier(certsURL, keySet, config)\n\treturn &JWTValidator{\n\t\tIDTokenVerifier: verifier,\n\t\taudTags:         audTags,\n\t}\n}\n\nfunc (v *JWTValidator) Name() string {\n\treturn \"AccessJWTValidator\"\n}\n\nfunc (v *JWTValidator) Handle(ctx context.Context, r *http.Request) (*HandleResult, error) {\n\taccessJWT := r.Header.Get(headerKeyAccessJWTAssertion)\n\tif accessJWT == \"\" {\n\t\t// log the exact error message here. the message is specific to the handler implementation logic, we don't gain anything\n\t\t// in passing it upstream. and each handler impl know what logging level to use for each.\n\t\treturn &HandleResult{\n\t\t\tShouldFilterRequest: true,\n\t\t\tStatusCode:          http.StatusForbidden,\n\t\t\tReason:              \"no access token in request\",\n\t\t}, nil\n\t}\n\n\ttoken, err := v.IDTokenVerifier.Verify(ctx, accessJWT)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// We want at least one audTag to match\n\tfor _, jwtAudTag := range token.Audience {\n\t\tfor _, acceptedAudTag := range v.audTags {\n\t\t\tif acceptedAudTag == jwtAudTag {\n\t\t\t\treturn &HandleResult{ShouldFilterRequest: false}, nil\n\t\t\t}\n\t\t}\n\t}\n\n\treturn &HandleResult{\n\t\tShouldFilterRequest: true,\n\t\tStatusCode:          http.StatusForbidden,\n\t\tReason:              fmt.Sprintf(\"Invalid token in jwt: %v\", token.Audience),\n\t}, nil\n}\n"
  },
  {
    "path": "ingress/middleware/jwtvalidator_test.go",
    "content": "package middleware\n\nimport (\n\t\"context\"\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/coreos/go-oidc/v3/oidc\"\n\t\"github.com/go-jose/go-jose/v4\"\n\t\"github.com/go-jose/go-jose/v4/jwt\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nvar (\n\tissuer = fmt.Sprintf(cloudflareAccessCertsURL, \"testteam\")\n)\n\ntype accessTokenClaims struct {\n\tEmail string `json:\"email\"`\n\tType  string `json:\"type\"`\n\tjwt.Claims\n}\n\nfunc TestJWTValidator(t *testing.T) {\n\treq := httptest.NewRequest(\"GET\", \"http://example.com\", nil)\n\n\tkey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)\n\trequire.NoError(t, err)\n\tissued := time.Now()\n\tclaims := accessTokenClaims{\n\t\tEmail: \"test@example.com\",\n\t\tType:  \"app\",\n\t\tClaims: jwt.Claims{\n\t\t\tIssuer:   issuer,\n\t\t\tSubject:  \"ee239b7a-e3e6-4173-972a-8fbe9d99c04f\",\n\t\t\tAudience: []string{\"\"},\n\t\t\tExpiry:   jwt.NewNumericDate(issued.Add(time.Hour)),\n\t\t\tIssuedAt: jwt.NewNumericDate(issued),\n\t\t},\n\t}\n\ttoken := signToken(t, claims, key)\n\treq.Header.Add(headerKeyAccessJWTAssertion, token)\n\n\tkeySet := oidc.StaticKeySet{PublicKeys: []crypto.PublicKey{key.Public()}}\n\tconfig := &oidc.Config{\n\t\tSkipClientIDCheck:    true,\n\t\tSupportedSigningAlgs: []string{string(jose.ES256)},\n\t}\n\tverifier := oidc.NewVerifier(issuer, &keySet, config)\n\n\ttests := []struct {\n\t\tname    string\n\t\taudTags []string\n\t\taud     jwt.Audience\n\t\terror   bool\n\t}{\n\t\t{\n\t\t\tname: \"valid\",\n\t\t\taudTags: []string{\n\t\t\t\t\"0bc545634b1732494b3f9472794a549c883fabd48de9dfe0e0413e59c3f96c38\",\n\t\t\t\t\"d7ec5b7fda23ffa8f8c8559fb37c66a2278208a78dbe376a3394b5ffec6911ba\",\n\t\t\t},\n\t\t\taud:   jwt.Audience{\"d7ec5b7fda23ffa8f8c8559fb37c66a2278208a78dbe376a3394b5ffec6911ba\"},\n\t\t\terror: false,\n\t\t},\n\t\t{\n\t\t\tname: \"invalid no match\",\n\t\t\taudTags: []string{\n\t\t\t\t\"0bc545634b1732494b3f9472794a549c883fabd48de9dfe0e0413e59c3f96c38\",\n\t\t\t\t\"d7ec5b7fda23ffa8f8c8559fb37c66a2278208a78dbe376a3394b5ffec6911ba\",\n\t\t\t},\n\t\t\taud:   jwt.Audience{\"09dc377143841843ecca28b196bdb1ec1675af38c8b7b60c7def5876c8877157\"},\n\t\t\terror: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid empty check\",\n\t\t\taudTags: []string{},\n\t\t\taud:     jwt.Audience{\"09dc377143841843ecca28b196bdb1ec1675af38c8b7b60c7def5876c8877157\"},\n\t\t\terror:   true,\n\t\t},\n\t\t{\n\t\t\tname: \"invalid absent aud\",\n\t\t\taudTags: []string{\n\t\t\t\t\"0bc545634b1732494b3f9472794a549c883fabd48de9dfe0e0413e59c3f96c38\",\n\t\t\t\t\"d7ec5b7fda23ffa8f8c8559fb37c66a2278208a78dbe376a3394b5ffec6911ba\",\n\t\t\t},\n\t\t\taud:   jwt.Audience{\"\"},\n\t\t\terror: true,\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tvalidator := JWTValidator{\n\t\t\t\tIDTokenVerifier: verifier,\n\t\t\t\taudTags:         test.audTags,\n\t\t\t}\n\t\t\tclaims.Audience = test.aud\n\t\t\ttoken := signToken(t, claims, key)\n\t\t\treq.Header.Set(headerKeyAccessJWTAssertion, token)\n\n\t\t\tresult, err := validator.Handle(context.Background(), req)\n\t\t\tassert.NoError(t, err)\n\t\t\tassert.Equal(t, test.error, result.ShouldFilterRequest)\n\t\t})\n\t}\n}\n\nfunc signToken(t *testing.T, token accessTokenClaims, key *ecdsa.PrivateKey) string {\n\tsigner, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.ES256, Key: key}, &jose.SignerOptions{})\n\trequire.NoError(t, err)\n\tpayload, err := json.Marshal(token)\n\trequire.NoError(t, err)\n\tjws, err := signer.Sign(payload)\n\trequire.NoError(t, err)\n\tjwt, err := jws.CompactSerialize()\n\trequire.NoError(t, err)\n\treturn jwt\n}\n"
  },
  {
    "path": "ingress/middleware/middleware.go",
    "content": "package middleware\n\nimport (\n\t\"context\"\n\t\"net/http\"\n)\n\ntype HandleResult struct {\n\t// Tells that the request didn't passed the handler and should be filtered\n\tShouldFilterRequest bool\n\t// The status code to return in case ShouldFilterRequest is true.\n\tStatusCode int\n\tReason     string\n}\n\ntype Handler interface {\n\tName() string\n\tHandle(ctx context.Context, r *http.Request) (result *HandleResult, err error)\n}\n"
  },
  {
    "path": "ingress/origin_connection.go",
    "content": "package ingress\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/ipaccess\"\n\t\"github.com/cloudflare/cloudflared/socks\"\n\t\"github.com/cloudflare/cloudflared/stream\"\n\t\"github.com/cloudflare/cloudflared/websocket\"\n)\n\n// OriginConnection is a way to stream to a service running on the user's origin.\n// Different concrete implementations will stream different protocols as long as they are io.ReadWriters.\ntype OriginConnection interface {\n\t// Stream should generally be implemented as a bidirectional io.Copy.\n\tStream(ctx context.Context, tunnelConn io.ReadWriter, log *zerolog.Logger)\n\tClose() error\n}\n\ntype streamHandlerFunc func(originConn io.ReadWriter, remoteConn net.Conn, log *zerolog.Logger)\n\n// DefaultStreamHandler is an implementation of streamHandlerFunc that\n// performs a two way io.Copy between originConn and remoteConn.\nfunc DefaultStreamHandler(originConn io.ReadWriter, remoteConn net.Conn, log *zerolog.Logger) {\n\tstream.Pipe(originConn, remoteConn, log)\n}\n\n// tcpConnection is an OriginConnection that directly streams to raw TCP.\ntype tcpConnection struct {\n\tnet.Conn\n\twriteTimeout time.Duration\n\tlogger       *zerolog.Logger\n}\n\nfunc (tc *tcpConnection) Stream(_ context.Context, tunnelConn io.ReadWriter, _ *zerolog.Logger) {\n\tstream.Pipe(tunnelConn, tc, tc.logger)\n}\n\nfunc (tc *tcpConnection) Write(b []byte) (int, error) {\n\tif tc.writeTimeout > 0 {\n\t\tif err := tc.Conn.SetWriteDeadline(time.Now().Add(tc.writeTimeout)); err != nil {\n\t\t\ttc.logger.Err(err).Msg(\"Error setting write deadline for TCP connection\")\n\t\t}\n\t}\n\n\treturn tc.Conn.Write(b)\n}\n\n// tcpOverWSConnection is an OriginConnection that streams to TCP over WS.\ntype tcpOverWSConnection struct {\n\tconn          net.Conn\n\tstreamHandler streamHandlerFunc\n}\n\nfunc (wc *tcpOverWSConnection) Stream(ctx context.Context, tunnelConn io.ReadWriter, log *zerolog.Logger) {\n\twsCtx, cancel := context.WithCancel(ctx)\n\twsConn := websocket.NewConn(wsCtx, tunnelConn, log)\n\twc.streamHandler(wsConn, wc.conn, log)\n\tcancel()\n\t// Makes sure wsConn stops sending ping before terminating the stream\n\twsConn.Close()\n}\n\nfunc (wc *tcpOverWSConnection) Close() error {\n\treturn wc.conn.Close()\n}\n\n// socksProxyOverWSConnection is an OriginConnection that streams SOCKS connections over WS.\n// The connection to the origin happens inside the SOCKS code as the client specifies the origin\n// details in the packet.\ntype socksProxyOverWSConnection struct {\n\taccessPolicy *ipaccess.Policy\n}\n\nfunc (sp *socksProxyOverWSConnection) Stream(ctx context.Context, tunnelConn io.ReadWriter, log *zerolog.Logger) {\n\twsCtx, cancel := context.WithCancel(ctx)\n\twsConn := websocket.NewConn(wsCtx, tunnelConn, log)\n\tsocks.StreamNetHandler(wsConn, sp.accessPolicy, log)\n\tcancel()\n\t// Makes sure wsConn stops sending ping before terminating the stream\n\twsConn.Close()\n}\n\nfunc (sp *socksProxyOverWSConnection) Close() error {\n\treturn nil\n}\n"
  },
  {
    "path": "ingress/origin_connection_test.go",
    "content": "package ingress\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"net/url\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/gobwas/ws/wsutil\"\n\tgorillaWS \"github.com/gorilla/websocket\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"golang.org/x/net/proxy\"\n\t\"golang.org/x/sync/errgroup\"\n\n\t\"github.com/cloudflare/cloudflared/socks\"\n\t\"github.com/cloudflare/cloudflared/stream\"\n\t\"github.com/cloudflare/cloudflared/websocket\"\n)\n\nconst (\n\ttestStreamTimeout = time.Second * 3\n\techoHeaderName    = \"Test-Cloudflared-Echo\"\n)\n\nvar (\n\ttestMessage  = []byte(\"TestStreamOriginConnection\")\n\ttestResponse = []byte(fmt.Sprintf(\"echo-%s\", testMessage))\n)\n\nfunc TestStreamTCPConnection(t *testing.T) {\n\tcfdConn, originConn := net.Pipe()\n\ttcpConn := tcpConnection{\n\t\tConn:         cfdConn,\n\t\twriteTimeout: 30 * time.Second,\n\t}\n\n\teyeballConn, edgeConn := net.Pipe()\n\n\tctx, cancel := context.WithTimeout(context.Background(), testStreamTimeout)\n\tdefer cancel()\n\n\terrGroup, ctx := errgroup.WithContext(ctx)\n\terrGroup.Go(func() error {\n\t\t_, err := eyeballConn.Write(testMessage)\n\t\trequire.NoError(t, err)\n\n\t\treadBuffer := make([]byte, len(testResponse))\n\t\t_, err = eyeballConn.Read(readBuffer)\n\t\trequire.NoError(t, err)\n\n\t\trequire.Equal(t, testResponse, readBuffer)\n\n\t\treturn nil\n\t})\n\terrGroup.Go(func() error {\n\t\techoTCPOrigin(t, originConn)\n\t\toriginConn.Close()\n\t\treturn nil\n\t})\n\n\ttcpConn.Stream(ctx, edgeConn, TestLogger)\n\trequire.NoError(t, errGroup.Wait())\n}\n\nfunc TestDefaultStreamWSOverTCPConnection(t *testing.T) {\n\tcfdConn, originConn := net.Pipe()\n\ttcpOverWSConn := tcpOverWSConnection{\n\t\tconn:          cfdConn,\n\t\tstreamHandler: DefaultStreamHandler,\n\t}\n\n\teyeballConn, edgeConn := net.Pipe()\n\n\tctx, cancel := context.WithTimeout(context.Background(), testStreamTimeout)\n\tdefer cancel()\n\n\terrGroup, ctx := errgroup.WithContext(ctx)\n\terrGroup.Go(func() error {\n\t\techoWSEyeball(t, eyeballConn)\n\t\treturn nil\n\t})\n\terrGroup.Go(func() error {\n\t\techoTCPOrigin(t, originConn)\n\t\toriginConn.Close()\n\t\treturn nil\n\t})\n\n\ttcpOverWSConn.Stream(ctx, edgeConn, TestLogger)\n\trequire.NoError(t, errGroup.Wait())\n}\n\n// TestSocksStreamWSOverTCPConnection simulates proxying in socks mode.\n// Eyeball side runs cloudflared access tcp with --url flag to start a websocket forwarder which\n// wraps SOCKS5 traffic in websocket\n// Origin side runs a tcpOverWSConnection with socks.StreamHandler\nfunc TestSocksStreamWSOverTCPConnection(t *testing.T) {\n\tvar (\n\t\tsendMessage             = t.Name()\n\t\techoHeaderIncomingValue = fmt.Sprintf(\"header-%s\", sendMessage)\n\t\techoMessage             = fmt.Sprintf(\"echo-%s\", sendMessage)\n\t\techoHeaderReturnValue   = fmt.Sprintf(\"echo-%s\", echoHeaderIncomingValue)\n\t)\n\n\tstatusCodes := []int{\n\t\thttp.StatusOK,\n\t\thttp.StatusTemporaryRedirect,\n\t\thttp.StatusBadRequest,\n\t\thttp.StatusInternalServerError,\n\t}\n\tfor _, status := range statusCodes {\n\t\thandler := func(w http.ResponseWriter, r *http.Request) {\n\t\t\tbody, err := io.ReadAll(r.Body)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, []byte(sendMessage), body)\n\n\t\t\trequire.Equal(t, echoHeaderIncomingValue, r.Header.Get(echoHeaderName))\n\t\t\tw.Header().Set(echoHeaderName, echoHeaderReturnValue)\n\n\t\t\tw.WriteHeader(status)\n\t\t\tw.Write([]byte(echoMessage))\n\t\t}\n\t\torigin := httptest.NewServer(http.HandlerFunc(handler))\n\t\tdefer origin.Close()\n\n\t\toriginURL, err := url.Parse(origin.URL)\n\t\trequire.NoError(t, err)\n\n\t\toriginConn, err := net.Dial(\"tcp\", originURL.Host)\n\t\trequire.NoError(t, err)\n\n\t\ttcpOverWSConn := tcpOverWSConnection{\n\t\t\tconn:          originConn,\n\t\t\tstreamHandler: socks.StreamHandler,\n\t\t}\n\n\t\twsForwarderOutConn, edgeConn := net.Pipe()\n\t\tctx, cancel := context.WithTimeout(context.Background(), testStreamTimeout)\n\t\tdefer cancel()\n\n\t\terrGroup, ctx := errgroup.WithContext(ctx)\n\t\terrGroup.Go(func() error {\n\t\t\ttcpOverWSConn.Stream(ctx, edgeConn, TestLogger)\n\t\t\treturn nil\n\t\t})\n\n\t\twsForwarderListener, err := net.Listen(\"tcp\", \"127.0.0.1:0\")\n\t\trequire.NoError(t, err)\n\n\t\terrGroup.Go(func() error {\n\t\t\twsForwarderInConn, err := wsForwarderListener.Accept()\n\t\t\trequire.NoError(t, err)\n\t\t\tdefer wsForwarderInConn.Close()\n\n\t\t\tstream.Pipe(wsForwarderInConn, &wsEyeball{wsForwarderOutConn}, TestLogger)\n\t\t\treturn nil\n\t\t})\n\n\t\teyeballDialer, err := proxy.SOCKS5(\"tcp\", wsForwarderListener.Addr().String(), nil, proxy.Direct)\n\t\trequire.NoError(t, err)\n\n\t\ttransport := &http.Transport{\n\t\t\tDial: eyeballDialer.Dial,\n\t\t}\n\n\t\t// Request URL doesn't matter because the transport is using eyeballDialer to connectq\n\t\treq, err := http.NewRequestWithContext(ctx, \"GET\", \"http://test-socks-stream.com\", bytes.NewBuffer([]byte(sendMessage)))\n\t\tassert.NoError(t, err)\n\t\treq.Header.Set(echoHeaderName, echoHeaderIncomingValue)\n\n\t\tresp, err := transport.RoundTrip(req)\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, status, resp.StatusCode)\n\t\trequire.Equal(t, echoHeaderReturnValue, resp.Header.Get(echoHeaderName))\n\t\tbody, err := io.ReadAll(resp.Body)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, []byte(echoMessage), body)\n\n\t\twsForwarderOutConn.Close()\n\t\tedgeConn.Close()\n\t\ttcpOverWSConn.Close()\n\n\t\trequire.NoError(t, errGroup.Wait())\n\t}\n}\n\nfunc TestWsConnReturnsBeforeStreamReturns(t *testing.T) {\n\thandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\teyeballConn := &readWriter{\n\t\t\tw: w,\n\t\t\tr: r.Body,\n\t\t}\n\n\t\tcfdConn, originConn := net.Pipe()\n\t\ttcpOverWSConn := tcpOverWSConnection{\n\t\t\tconn:          cfdConn,\n\t\t\tstreamHandler: DefaultStreamHandler,\n\t\t}\n\t\tgo func() {\n\t\t\ttime.Sleep(time.Millisecond * 10)\n\t\t\t// Simulate losing connection to origin\n\t\t\toriginConn.Close()\n\t\t}()\n\t\tctx := context.WithValue(r.Context(), websocket.PingPeriodContextKey, time.Microsecond)\n\t\ttcpOverWSConn.Stream(ctx, eyeballConn, TestLogger)\n\t})\n\tserver := httptest.NewServer(handler)\n\tdefer server.Close()\n\tclient := server.Client()\n\n\tctx, cancel := context.WithTimeout(context.Background(), time.Second*10)\n\tdefer cancel()\n\n\terrGroup, ctx := errgroup.WithContext(ctx)\n\tfor i := 0; i < 50; i++ {\n\t\teyeballConn, edgeConn := net.Pipe()\n\t\treq, err := http.NewRequestWithContext(ctx, http.MethodConnect, server.URL, edgeConn)\n\t\tassert.NoError(t, err)\n\n\t\tresp, err := client.Transport.RoundTrip(req)\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, resp.StatusCode, http.StatusOK)\n\n\t\terrGroup.Go(func() error {\n\t\t\tfor {\n\t\t\t\tif err := wsutil.WriteClientBinary(eyeballConn, testMessage); err != nil {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n\n\tassert.NoError(t, errGroup.Wait())\n}\n\ntype wsEyeball struct {\n\tconn net.Conn\n}\n\nfunc (wse *wsEyeball) Read(p []byte) (int, error) {\n\tdata, err := wsutil.ReadServerBinary(wse.conn)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn copy(p, data), nil\n}\n\nfunc (wse *wsEyeball) Write(p []byte) (int, error) {\n\terr := wsutil.WriteClientBinary(wse.conn, p)\n\treturn len(p), err\n}\n\nfunc echoWSEyeball(t *testing.T, conn net.Conn) {\n\tdefer func() {\n\t\tassert.NoError(t, conn.Close())\n\t}()\n\n\tif !assert.NoError(t, wsutil.WriteClientBinary(conn, testMessage)) {\n\t\treturn\n\t}\n\n\treadMsg, err := wsutil.ReadServerBinary(conn)\n\tif !assert.NoError(t, err) {\n\t\treturn\n\t}\n\n\tassert.Equal(t, testResponse, readMsg)\n}\n\nfunc echoWSOrigin(t *testing.T, expectMessages bool) *httptest.Server {\n\tvar upgrader = gorillaWS.Upgrader{\n\t\tReadBufferSize:  10,\n\t\tWriteBufferSize: 10,\n\t}\n\n\tws := func(w http.ResponseWriter, r *http.Request) {\n\t\theader := make(http.Header)\n\t\tfor k, vs := range r.Header {\n\t\t\tif k == \"Test-Cloudflared-Echo\" {\n\t\t\t\theader[k] = vs\n\t\t\t}\n\t\t}\n\t\tconn, err := upgrader.Upgrade(w, r, header)\n\t\trequire.NoError(t, err)\n\t\tdefer conn.Close()\n\n\t\tsawMessage := false\n\t\tfor {\n\t\t\tmessageType, p, err := conn.ReadMessage()\n\t\t\tif err != nil {\n\t\t\t\tif expectMessages && !sawMessage {\n\t\t\t\t\tt.Errorf(\"unexpected error: %v\", err)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\tassert.Equal(t, testMessage, p)\n\t\t\tsawMessage = true\n\t\t\tif err := conn.WriteMessage(messageType, testResponse); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// NewTLSServer starts the server in another thread\n\treturn httptest.NewTLSServer(http.HandlerFunc(ws))\n}\n\nfunc echoTCPOrigin(t *testing.T, conn net.Conn) {\n\treadBuffer := make([]byte, len(testMessage))\n\t_, err := conn.Read(readBuffer)\n\tassert.NoError(t, err)\n\n\tassert.Equal(t, testMessage, readBuffer)\n\n\t_, err = conn.Write(testResponse)\n\tassert.NoError(t, err)\n}\n\ntype readWriter struct {\n\tw io.Writer\n\tr io.Reader\n}\n\nfunc (r *readWriter) Read(p []byte) (n int, err error) {\n\treturn r.r.Read(p)\n}\n\nfunc (r *readWriter) Write(p []byte) (n int, err error) {\n\treturn r.w.Write(p)\n}\n"
  },
  {
    "path": "ingress/origin_dialer.go",
    "content": "package ingress\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/netip\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/rs/zerolog\"\n)\n\nconst writeDeadlineUDP = 200 * time.Millisecond\n\n// OriginTCPDialer provides a TCP dial operation to a requested address.\ntype OriginTCPDialer interface {\n\tDialTCP(ctx context.Context, addr netip.AddrPort) (net.Conn, error)\n}\n\n// OriginUDPDialer provides a UDP dial operation to a requested address.\ntype OriginUDPDialer interface {\n\tDialUDP(addr netip.AddrPort) (net.Conn, error)\n}\n\n// OriginDialer provides both TCP and UDP dial operations to an address.\ntype OriginDialer interface {\n\tOriginTCPDialer\n\tOriginUDPDialer\n}\n\ntype OriginConfig struct {\n\t// The default Dialer used if no reserved services are found for an origin request.\n\tDefaultDialer OriginDialer\n\t// Timeout on write operations for TCP connections to the origin.\n\tTCPWriteTimeout time.Duration\n}\n\n// OriginDialerService provides a proxy TCP and UDP dialer to origin services while allowing reserved\n// services to be provided. These reserved services are assigned to specific [netip.AddrPort]s\n// and provide their own [OriginDialer]'s to handle origin dialing per protocol.\ntype OriginDialerService struct {\n\t// Reserved TCP services for reserved AddrPort values\n\treservedTCPServices map[netip.AddrPort]OriginTCPDialer\n\t// Reserved UDP services for reserved AddrPort values\n\treservedUDPServices map[netip.AddrPort]OriginUDPDialer\n\t// The default Dialer used if no reserved services are found for an origin request\n\tdefaultDialer  OriginDialer\n\tdefaultDialerM sync.RWMutex\n\t// Write timeout for TCP connections\n\twriteTimeout time.Duration\n\n\tlogger *zerolog.Logger\n}\n\nfunc NewOriginDialer(config OriginConfig, logger *zerolog.Logger) *OriginDialerService {\n\treturn &OriginDialerService{\n\t\treservedTCPServices: map[netip.AddrPort]OriginTCPDialer{},\n\t\treservedUDPServices: map[netip.AddrPort]OriginUDPDialer{},\n\t\tdefaultDialer:       config.DefaultDialer,\n\t\twriteTimeout:        config.TCPWriteTimeout,\n\t\tlogger:              logger,\n\t}\n}\n\n// AddReservedService adds a reserved virtual service to dial to.\n// Not locked and expected to be initialized before calling first dial and not afterwards.\nfunc (d *OriginDialerService) AddReservedService(service OriginDialer, addrs []netip.AddrPort) {\n\tfor _, addr := range addrs {\n\t\td.reservedTCPServices[addr] = service\n\t\td.reservedUDPServices[addr] = service\n\t}\n}\n\n// UpdateDefaultDialer updates the default dialer.\nfunc (d *OriginDialerService) UpdateDefaultDialer(dialer *Dialer) {\n\td.defaultDialerM.Lock()\n\tdefer d.defaultDialerM.Unlock()\n\td.defaultDialer = dialer\n}\n\n// DialTCP will perform a dial TCP to the requested addr.\nfunc (d *OriginDialerService) DialTCP(ctx context.Context, addr netip.AddrPort) (net.Conn, error) {\n\tconn, err := d.dialTCP(ctx, addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// Assign the write timeout for the TCP operations\n\treturn &tcpConnection{\n\t\tConn:         conn,\n\t\twriteTimeout: d.writeTimeout,\n\t\tlogger:       d.logger,\n\t}, nil\n}\n\nfunc (d *OriginDialerService) dialTCP(ctx context.Context, addr netip.AddrPort) (net.Conn, error) {\n\t// Check to see if any reserved services are available for this addr and call their dialer instead.\n\tif dialer, ok := d.reservedTCPServices[addr]; ok {\n\t\treturn dialer.DialTCP(ctx, addr)\n\t}\n\td.defaultDialerM.RLock()\n\tdialer := d.defaultDialer\n\td.defaultDialerM.RUnlock()\n\treturn dialer.DialTCP(ctx, addr)\n}\n\n// DialUDP will perform a dial UDP to the requested addr.\nfunc (d *OriginDialerService) DialUDP(addr netip.AddrPort) (net.Conn, error) {\n\t// Check to see if any reserved services are available for this addr and call their dialer instead.\n\tif dialer, ok := d.reservedUDPServices[addr]; ok {\n\t\treturn dialer.DialUDP(addr)\n\t}\n\td.defaultDialerM.RLock()\n\tdialer := d.defaultDialer\n\td.defaultDialerM.RUnlock()\n\treturn dialer.DialUDP(addr)\n}\n\ntype Dialer struct {\n\tDialer net.Dialer\n}\n\nfunc NewDialer(config WarpRoutingConfig) *Dialer {\n\treturn &Dialer{\n\t\tDialer: net.Dialer{\n\t\t\tTimeout:   config.ConnectTimeout.Duration,\n\t\t\tKeepAlive: config.TCPKeepAlive.Duration,\n\t\t},\n\t}\n}\n\nfunc (d *Dialer) DialTCP(ctx context.Context, dest netip.AddrPort) (net.Conn, error) {\n\tconn, err := d.Dialer.DialContext(ctx, \"tcp\", dest.String())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to dial tcp to origin %s: %w\", dest, err)\n\t}\n\n\treturn conn, nil\n}\n\nfunc (d *Dialer) DialUDP(dest netip.AddrPort) (net.Conn, error) {\n\tconn, err := d.Dialer.Dial(\"udp\", dest.String())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to dial udp to origin %s: %w\", dest, err)\n\t}\n\treturn &writeDeadlineConn{\n\t\tConn: conn,\n\t}, nil\n}\n\n// writeDeadlineConn is a wrapper around a net.Conn that sets a write deadline of 200ms.\n// This is to prevent the socket from blocking on the write operation if it were to occur. However,\n// we typically never expect this to occur except under high load or kernel issues.\ntype writeDeadlineConn struct {\n\tnet.Conn\n}\n\nfunc (w *writeDeadlineConn) Write(b []byte) (int, error) {\n\tif err := w.SetWriteDeadline(time.Now().Add(writeDeadlineUDP)); err != nil {\n\t\treturn 0, err\n\t}\n\treturn w.Conn.Write(b)\n}\n"
  },
  {
    "path": "ingress/origin_icmp_proxy.go",
    "content": "package ingress\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/netip\"\n\t\"time\"\n\n\t\"github.com/rs/zerolog\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/trace\"\n\t\"golang.org/x/net/icmp\"\n\t\"golang.org/x/net/ipv4\"\n\t\"golang.org/x/net/ipv6\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n)\n\nconst (\n\tmtu = 1500\n\t// icmpRequestTimeoutMs controls how long to wait for a reply\n\ticmpRequestTimeoutMs = 1000\n)\n\nvar (\n\terrPacketNil = fmt.Errorf(\"packet is nil\")\n)\n\n// ICMPRouterServer is a parent interface over-top of ICMPRouter that allows for the operation of the proxy origin listeners.\ntype ICMPRouterServer interface {\n\tICMPRouter\n\t// Serve runs the ICMPRouter proxy origin listeners for any of the IPv4 or IPv6 interfaces configured.\n\tServe(ctx context.Context) error\n}\n\n// ICMPRouter manages out-going ICMP requests towards the origin.\ntype ICMPRouter interface {\n\t// Request will send an ICMP packet towards the origin with an ICMPResponder to attach to the ICMP flow for the\n\t// response to utilize.\n\tRequest(ctx context.Context, pk *packet.ICMP, responder ICMPResponder) error\n\t// ConvertToTTLExceeded will take an ICMP packet and create a ICMP TTL Exceeded response origininating from the\n\t// ICMPRouter's IP interface.\n\tConvertToTTLExceeded(pk *packet.ICMP, rawPacket packet.RawPacket) *packet.ICMP\n}\n\n// ICMPResponder manages how to handle incoming ICMP messages coming from the origin to the edge.\ntype ICMPResponder interface {\n\tConnectionIndex() uint8\n\tReturnPacket(pk *packet.ICMP) error\n\tAddTraceContext(tracedCtx *tracing.TracedContext, serializedIdentity []byte)\n\tRequestSpan(ctx context.Context, pk *packet.ICMP) (context.Context, trace.Span)\n\tReplySpan(ctx context.Context, logger *zerolog.Logger) (context.Context, trace.Span)\n\tExportSpan()\n}\n\ntype icmpRouter struct {\n\tipv4Proxy *icmpProxy\n\tipv4Src   netip.Addr\n\tipv6Proxy *icmpProxy\n\tipv6Src   netip.Addr\n}\n\n// NewICMPRouter doesn't return an error if either ipv4 proxy or ipv6 proxy can be created. The machine might only\n// support one of them.\n// funnelIdleTimeout controls how long to wait to close a funnel without send/return\nfunc NewICMPRouter(ipv4Addr, ipv6Addr netip.Addr, logger *zerolog.Logger, funnelIdleTimeout time.Duration) (ICMPRouterServer, error) {\n\tipv4Proxy, ipv4Err := newICMPProxy(ipv4Addr, logger, funnelIdleTimeout)\n\tipv6Proxy, ipv6Err := newICMPProxy(ipv6Addr, logger, funnelIdleTimeout)\n\tif ipv4Err != nil && ipv6Err != nil {\n\t\terr := fmt.Errorf(\"cannot create ICMPv4 proxy: %v nor ICMPv6 proxy: %v\", ipv4Err, ipv6Err)\n\t\tlogger.Debug().Err(err).Msg(\"ICMP proxy feature is disabled\")\n\t\treturn nil, err\n\t}\n\tif ipv4Err != nil {\n\t\tlogger.Debug().Err(ipv4Err).Msg(\"failed to create ICMPv4 proxy, only ICMPv6 proxy is created\")\n\t\tipv4Proxy = nil\n\t}\n\tif ipv6Err != nil {\n\t\tlogger.Debug().Err(ipv6Err).Msg(\"failed to create ICMPv6 proxy, only ICMPv4 proxy is created\")\n\t\tipv6Proxy = nil\n\t}\n\treturn &icmpRouter{\n\t\tipv4Proxy: ipv4Proxy,\n\t\tipv4Src:   ipv4Addr,\n\t\tipv6Proxy: ipv6Proxy,\n\t\tipv6Src:   ipv6Addr,\n\t}, nil\n}\n\nfunc (ir *icmpRouter) Serve(ctx context.Context) error {\n\tif ir.ipv4Proxy != nil && ir.ipv6Proxy != nil {\n\t\terrC := make(chan error, 2)\n\t\tgo func() {\n\t\t\terrC <- ir.ipv4Proxy.Serve(ctx)\n\t\t}()\n\t\tgo func() {\n\t\t\terrC <- ir.ipv6Proxy.Serve(ctx)\n\t\t}()\n\t\treturn <-errC\n\t}\n\tif ir.ipv4Proxy != nil {\n\t\treturn ir.ipv4Proxy.Serve(ctx)\n\t}\n\tif ir.ipv6Proxy != nil {\n\t\treturn ir.ipv6Proxy.Serve(ctx)\n\t}\n\treturn fmt.Errorf(\"ICMPv4 proxy and ICMPv6 proxy are both nil\")\n}\n\nfunc (ir *icmpRouter) Request(ctx context.Context, pk *packet.ICMP, responder ICMPResponder) error {\n\tif pk == nil {\n\t\treturn errPacketNil\n\t}\n\tif pk.Dst.Is4() {\n\t\tif ir.ipv4Proxy != nil {\n\t\t\treturn ir.ipv4Proxy.Request(ctx, pk, responder)\n\t\t}\n\t\treturn fmt.Errorf(\"ICMPv4 proxy was not instantiated\")\n\t}\n\tif ir.ipv6Proxy != nil {\n\t\treturn ir.ipv6Proxy.Request(ctx, pk, responder)\n\t}\n\treturn fmt.Errorf(\"ICMPv6 proxy was not instantiated\")\n}\n\nfunc (ir *icmpRouter) ConvertToTTLExceeded(pk *packet.ICMP, rawPacket packet.RawPacket) *packet.ICMP {\n\tvar srcIP netip.Addr\n\tif pk.Dst.Is4() {\n\t\tsrcIP = ir.ipv4Src\n\t} else {\n\t\tsrcIP = ir.ipv6Src\n\t}\n\treturn packet.NewICMPTTLExceedPacket(pk.IP, rawPacket, srcIP)\n}\n\nfunc getICMPEcho(msg *icmp.Message) (*icmp.Echo, error) {\n\techo, ok := msg.Body.(*icmp.Echo)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"expect ICMP echo, got %s\", msg.Type)\n\t}\n\treturn echo, nil\n}\n\nfunc isEchoReply(msg *icmp.Message) bool {\n\treturn msg.Type == ipv4.ICMPTypeEchoReply || msg.Type == ipv6.ICMPTypeEchoReply\n}\n\nfunc observeICMPRequest(logger *zerolog.Logger, span trace.Span, src string, dst string, echoID int, seq int) {\n\tincrementICMPRequest()\n\tlogger.Debug().\n\t\tStr(\"src\", src).\n\t\tStr(\"dst\", dst).\n\t\tInt(\"originalEchoID\", echoID).\n\t\tInt(\"originalEchoSeq\", seq).\n\t\tMsg(\"Received ICMP request\")\n\tspan.SetAttributes(\n\t\tattribute.Int(\"originalEchoID\", echoID),\n\t\tattribute.Int(\"seq\", seq),\n\t)\n}\n\nfunc observeICMPReply(logger *zerolog.Logger, span trace.Span, dst string, echoID int, seq int) {\n\tincrementICMPReply()\n\tlogger.Debug().Str(\"dst\", dst).Int(\"echoID\", echoID).Int(\"seq\", seq).Msg(\"Sent ICMP reply to edge\")\n\tspan.SetAttributes(\n\t\tattribute.String(\"dst\", dst),\n\t\tattribute.Int(\"echoID\", echoID),\n\t\tattribute.Int(\"seq\", seq),\n\t)\n}\n"
  },
  {
    "path": "ingress/origin_icmp_proxy_test.go",
    "content": "package ingress\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/netip\"\n\t\"strings\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/fortytw2/leaktest\"\n\t\"github.com/google/gopacket/layers\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/require\"\n\t\"golang.org/x/net/icmp\"\n\t\"golang.org/x/net/ipv4\"\n\t\"golang.org/x/net/ipv6\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n\tquicpogs \"github.com/cloudflare/cloudflared/quic\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n)\n\nvar (\n\tnoopLogger            = zerolog.Nop()\n\tlocalhostIP           = netip.MustParseAddr(\"127.0.0.1\")\n\tlocalhostIPv6         = netip.MustParseAddr(\"::1\")\n\ttestFunnelIdleTimeout = time.Millisecond * 10\n)\n\n// TestICMPProxyEcho makes sure we can send ICMP echo via the Request method and receives response via the\n// ListenResponse method\n//\n// Note: if this test fails on your device under Linux, then most likely you need to make sure that your user\n// is allowed in ping_group_range. See the following gist for how to do that:\n// https://github.com/ValentinBELYN/icmplib/blob/main/docs/6-use-icmplib-without-privileges.md\nfunc TestICMPRouterEcho(t *testing.T) {\n\ttestICMPRouterEcho(t, true)\n\ttestICMPRouterEcho(t, false)\n}\n\nfunc testICMPRouterEcho(t *testing.T, sendIPv4 bool) {\n\tdefer leaktest.Check(t)()\n\n\tconst (\n\t\techoID = 36571\n\t\tendSeq = 20\n\t)\n\n\trouter, err := NewICMPRouter(localhostIP, localhostIPv6, &noopLogger, testFunnelIdleTimeout)\n\trequire.NoError(t, err)\n\n\tproxyDone := make(chan struct{})\n\tctx, cancel := context.WithCancel(context.Background())\n\tgo func() {\n\t\trouter.Serve(ctx)\n\t\tclose(proxyDone)\n\t}()\n\n\tmuxer := newMockMuxer(1)\n\tresponder := newPacketResponder(muxer, 0, packet.NewEncoder())\n\n\tprotocol := layers.IPProtocolICMPv6\n\tif sendIPv4 {\n\t\tprotocol = layers.IPProtocolICMPv4\n\t}\n\tlocalIPs := getLocalIPs(t, sendIPv4)\n\tips := make([]*packet.IP, len(localIPs))\n\tfor i, localIP := range localIPs {\n\t\tips[i] = &packet.IP{\n\t\t\tSrc:      localIP,\n\t\t\tDst:      localIP,\n\t\t\tProtocol: protocol,\n\t\t\tTTL:      packet.DefaultTTL,\n\t\t}\n\t}\n\n\tvar icmpType icmp.Type = ipv6.ICMPTypeEchoRequest\n\tif sendIPv4 {\n\t\ticmpType = ipv4.ICMPTypeEcho\n\t}\n\tfor seq := 0; seq < endSeq; seq++ {\n\t\tfor i, ip := range ips {\n\t\t\tpk := packet.ICMP{\n\t\t\t\tIP: ip,\n\t\t\t\tMessage: &icmp.Message{\n\t\t\t\t\tType: icmpType,\n\t\t\t\t\tCode: 0,\n\t\t\t\t\tBody: &icmp.Echo{\n\t\t\t\t\t\tID:   echoID + i,\n\t\t\t\t\t\tSeq:  seq,\n\t\t\t\t\t\tData: []byte(fmt.Sprintf(\"icmp echo seq %d\", seq)),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}\n\t\t\trequire.NoError(t, router.Request(ctx, &pk, responder))\n\t\t\tvalidateEchoFlow(t, <-muxer.cfdToEdge, &pk)\n\t\t}\n\t}\n\n\t// Make sure funnel cleanup kicks in\n\ttime.Sleep(testFunnelIdleTimeout * 2)\n\tcancel()\n\t<-proxyDone\n}\n\nfunc TestTraceICMPRouterEcho(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\n\ttracingCtx := \"ec31ad8a01fde11fdcabe2efdce36873:52726f6cabc144f5:0:1\"\n\n\trouter, err := NewICMPRouter(localhostIP, localhostIPv6, &noopLogger, testFunnelIdleTimeout)\n\trequire.NoError(t, err)\n\n\tproxyDone := make(chan struct{})\n\tctx, cancel := context.WithCancel(context.Background())\n\tgo func() {\n\t\trouter.Serve(ctx)\n\t\tclose(proxyDone)\n\t}()\n\n\t// Buffer 3 packets, request span, reply span and reply\n\tmuxer := newMockMuxer(3)\n\ttracingIdentity, err := tracing.NewIdentity(tracingCtx)\n\trequire.NoError(t, err)\n\tserializedIdentity, err := tracingIdentity.MarshalBinary()\n\trequire.NoError(t, err)\n\n\tresponder := newPacketResponder(muxer, 0, packet.NewEncoder())\n\tresponder.AddTraceContext(tracing.NewTracedContext(ctx, tracingIdentity.String(), &noopLogger), serializedIdentity)\n\n\techo := &icmp.Echo{\n\t\tID:   12910,\n\t\tSeq:  182,\n\t\tData: []byte(t.Name()),\n\t}\n\tpk := packet.ICMP{\n\t\tIP: &packet.IP{\n\t\t\tSrc:      localhostIP,\n\t\t\tDst:      localhostIP,\n\t\t\tProtocol: layers.IPProtocolICMPv4,\n\t\t\tTTL:      packet.DefaultTTL,\n\t\t},\n\t\tMessage: &icmp.Message{\n\t\t\tType: ipv4.ICMPTypeEcho,\n\t\t\tCode: 0,\n\t\t\tBody: echo,\n\t\t},\n\t}\n\n\trequire.NoError(t, router.Request(ctx, &pk, responder))\n\tfirstPK := <-muxer.cfdToEdge\n\tvar requestSpan *quicpogs.TracingSpanPacket\n\t// The order of receiving reply or request span is not deterministic\n\tswitch firstPK.Type() {\n\tcase quicpogs.DatagramTypeIP:\n\t\t// reply packet\n\t\tvalidateEchoFlow(t, firstPK, &pk)\n\tcase quicpogs.DatagramTypeTracingSpan:\n\t\t// Request span\n\t\trequestSpan = firstPK.(*quicpogs.TracingSpanPacket)\n\t\trequire.NotEmpty(t, requestSpan.Spans)\n\t\trequire.True(t, bytes.Equal(serializedIdentity, requestSpan.TracingIdentity))\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"received unexpected packet type %d\", firstPK.Type()))\n\t}\n\n\tsecondPK := <-muxer.cfdToEdge\n\tif requestSpan != nil {\n\t\t// If first packet is request span, second packet should be the reply\n\t\tvalidateEchoFlow(t, secondPK, &pk)\n\t} else {\n\t\trequestSpan = secondPK.(*quicpogs.TracingSpanPacket)\n\t\trequire.NotEmpty(t, requestSpan.Spans)\n\t\trequire.True(t, bytes.Equal(serializedIdentity, requestSpan.TracingIdentity))\n\t}\n\n\t// Reply span\n\tthirdPacket := <-muxer.cfdToEdge\n\treplySpan, ok := thirdPacket.(*quicpogs.TracingSpanPacket)\n\trequire.True(t, ok)\n\trequire.NotEmpty(t, replySpan.Spans)\n\trequire.True(t, bytes.Equal(serializedIdentity, replySpan.TracingIdentity))\n\trequire.False(t, bytes.Equal(requestSpan.Spans, replySpan.Spans))\n\n\techo.Seq++\n\tpk.Body = echo\n\t// Only first request for a flow is traced. The edge will not send tracing context for the second request\n\tnewResponder := newPacketResponder(muxer, 0, packet.NewEncoder())\n\trequire.NoError(t, router.Request(ctx, &pk, newResponder))\n\tvalidateEchoFlow(t, <-muxer.cfdToEdge, &pk)\n\n\tselect {\n\tcase receivedPacket := <-muxer.cfdToEdge:\n\t\tpanic(fmt.Sprintf(\"Receive unexpected packet %+v\", receivedPacket))\n\tdefault:\n\t}\n\n\ttime.Sleep(testFunnelIdleTimeout * 2)\n\tcancel()\n\t<-proxyDone\n}\n\n// TestConcurrentRequests makes sure icmpRouter can send concurrent requests to the same destination with different\n// echo ID. This simulates concurrent ping to the same destination.\nfunc TestConcurrentRequestsToSameDst(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\n\tconst (\n\t\tconcurrentPings = 5\n\t\tendSeq          = 5\n\t)\n\n\trouter, err := NewICMPRouter(localhostIP, localhostIPv6, &noopLogger, testFunnelIdleTimeout)\n\trequire.NoError(t, err)\n\n\tproxyDone := make(chan struct{})\n\tctx, cancel := context.WithCancel(context.Background())\n\tgo func() {\n\t\trouter.Serve(ctx)\n\t\tclose(proxyDone)\n\t}()\n\n\tvar wg sync.WaitGroup\n\t// icmpv4 and icmpv6 each has concurrentPings\n\twg.Add(concurrentPings * 2)\n\tfor i := 0; i < concurrentPings; i++ {\n\t\techoID := 38451 + i\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\n\t\t\tmuxer := newMockMuxer(1)\n\t\t\tresponder := newPacketResponder(muxer, 0, packet.NewEncoder())\n\t\t\tfor seq := 0; seq < endSeq; seq++ {\n\t\t\t\tpk := &packet.ICMP{\n\t\t\t\t\tIP: &packet.IP{\n\t\t\t\t\t\tSrc:      localhostIP,\n\t\t\t\t\t\tDst:      localhostIP,\n\t\t\t\t\t\tProtocol: layers.IPProtocolICMPv4,\n\t\t\t\t\t\tTTL:      packet.DefaultTTL,\n\t\t\t\t\t},\n\t\t\t\t\tMessage: &icmp.Message{\n\t\t\t\t\t\tType: ipv4.ICMPTypeEcho,\n\t\t\t\t\t\tCode: 0,\n\t\t\t\t\t\tBody: &icmp.Echo{\n\t\t\t\t\t\t\tID:   echoID,\n\t\t\t\t\t\t\tSeq:  seq,\n\t\t\t\t\t\t\tData: []byte(fmt.Sprintf(\"icmpv4 echo id %d, seq %d\", echoID, seq)),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\trequire.NoError(t, router.Request(ctx, pk, responder))\n\t\t\t\tvalidateEchoFlow(t, <-muxer.cfdToEdge, pk)\n\t\t\t}\n\t\t}()\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\tmuxer := newMockMuxer(1)\n\t\t\tresponder := newPacketResponder(muxer, 0, packet.NewEncoder())\n\t\t\tfor seq := 0; seq < endSeq; seq++ {\n\t\t\t\tpk := &packet.ICMP{\n\t\t\t\t\tIP: &packet.IP{\n\t\t\t\t\t\tSrc:      localhostIPv6,\n\t\t\t\t\t\tDst:      localhostIPv6,\n\t\t\t\t\t\tProtocol: layers.IPProtocolICMPv6,\n\t\t\t\t\t\tTTL:      packet.DefaultTTL,\n\t\t\t\t\t},\n\t\t\t\t\tMessage: &icmp.Message{\n\t\t\t\t\t\tType: ipv6.ICMPTypeEchoRequest,\n\t\t\t\t\t\tCode: 0,\n\t\t\t\t\t\tBody: &icmp.Echo{\n\t\t\t\t\t\t\tID:   echoID,\n\t\t\t\t\t\t\tSeq:  seq,\n\t\t\t\t\t\t\tData: []byte(fmt.Sprintf(\"icmpv6 echo id %d, seq %d\", echoID, seq)),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\trequire.NoError(t, router.Request(ctx, pk, responder))\n\t\t\t\tvalidateEchoFlow(t, <-muxer.cfdToEdge, pk)\n\t\t\t}\n\t\t}()\n\t}\n\twg.Wait()\n\n\ttime.Sleep(testFunnelIdleTimeout * 2)\n\tcancel()\n\t<-proxyDone\n}\n\n// TestICMPProxyRejectNotEcho makes sure it rejects messages other than echo\nfunc TestICMPRouterRejectNotEcho(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\n\tmsgs := []icmp.Message{\n\t\t{\n\t\t\tType: ipv4.ICMPTypeDestinationUnreachable,\n\t\t\tCode: 1,\n\t\t\tBody: &icmp.DstUnreach{\n\t\t\t\tData: []byte(\"original packet\"),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tType: ipv4.ICMPTypeTimeExceeded,\n\t\t\tCode: 1,\n\t\t\tBody: &icmp.TimeExceeded{\n\t\t\t\tData: []byte(\"original packet\"),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tType: ipv4.ICMPType(2),\n\t\t\tCode: 0,\n\t\t\tBody: &icmp.PacketTooBig{\n\t\t\t\tMTU:  1280,\n\t\t\t\tData: []byte(\"original packet\"),\n\t\t\t},\n\t\t},\n\t}\n\ttestICMPRouterRejectNotEcho(t, localhostIP, msgs)\n\tmsgsV6 := []icmp.Message{\n\t\t{\n\t\t\tType: ipv6.ICMPTypeDestinationUnreachable,\n\t\t\tCode: 3,\n\t\t\tBody: &icmp.DstUnreach{\n\t\t\t\tData: []byte(\"original packet\"),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tType: ipv6.ICMPTypeTimeExceeded,\n\t\t\tCode: 0,\n\t\t\tBody: &icmp.TimeExceeded{\n\t\t\t\tData: []byte(\"original packet\"),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tType: ipv6.ICMPTypePacketTooBig,\n\t\t\tCode: 0,\n\t\t\tBody: &icmp.PacketTooBig{\n\t\t\t\tMTU:  1280,\n\t\t\t\tData: []byte(\"original packet\"),\n\t\t\t},\n\t\t},\n\t}\n\ttestICMPRouterRejectNotEcho(t, localhostIPv6, msgsV6)\n}\n\nfunc testICMPRouterRejectNotEcho(t *testing.T, srcDstIP netip.Addr, msgs []icmp.Message) {\n\trouter, err := NewICMPRouter(localhostIP, localhostIPv6, &noopLogger, testFunnelIdleTimeout)\n\trequire.NoError(t, err)\n\n\tmuxer := newMockMuxer(1)\n\tresponder := newPacketResponder(muxer, 0, packet.NewEncoder())\n\tprotocol := layers.IPProtocolICMPv4\n\tif srcDstIP.Is6() {\n\t\tprotocol = layers.IPProtocolICMPv6\n\t}\n\tfor _, m := range msgs {\n\t\tpk := packet.ICMP{\n\t\t\tIP: &packet.IP{\n\t\t\t\tSrc:      srcDstIP,\n\t\t\t\tDst:      srcDstIP,\n\t\t\t\tProtocol: protocol,\n\t\t\t\tTTL:      packet.DefaultTTL,\n\t\t\t},\n\t\t\tMessage: &m,\n\t\t}\n\t\trequire.Error(t, router.Request(context.Background(), &pk, responder))\n\t}\n}\n\nfunc validateEchoFlow(t *testing.T, pk quicpogs.Packet, echoReq *packet.ICMP) {\n\tdecoder := packet.NewICMPDecoder()\n\tdecoded, err := decoder.Decode(packet.RawPacket{Data: pk.Payload()})\n\trequire.NoError(t, err, pk)\n\trequire.Equal(t, decoded.Src, echoReq.Dst)\n\trequire.Equal(t, decoded.Dst, echoReq.Src)\n\trequire.Equal(t, echoReq.Protocol, decoded.Protocol)\n\n\tif echoReq.Type == ipv4.ICMPTypeEcho {\n\t\trequire.Equal(t, ipv4.ICMPTypeEchoReply, decoded.Type)\n\t} else {\n\t\trequire.Equal(t, ipv6.ICMPTypeEchoReply, decoded.Type)\n\t}\n\trequire.Equal(t, 0, decoded.Code)\n\trequire.NotZero(t, decoded.Checksum)\n\n\trequire.Equal(t, echoReq.Body, decoded.Body)\n}\n\nfunc getLocalIPs(t *testing.T, ipv4 bool) []netip.Addr {\n\tinterfaces, err := net.Interfaces()\n\trequire.NoError(t, err)\n\tlocalIPs := []netip.Addr{}\n\tfor _, i := range interfaces {\n\t\t// Skip TUN devices, and Docker Networks\n\t\tif strings.Contains(i.Name, \"tun\") || strings.Contains(i.Name, \"docker\") || strings.HasPrefix(i.Name, \"br-\") {\n\t\t\tcontinue\n\t\t}\n\t\taddrs, err := i.Addrs()\n\t\trequire.NoError(t, err)\n\t\tfor _, addr := range addrs {\n\t\t\tif ipnet, ok := addr.(*net.IPNet); ok && (ipnet.IP.IsPrivate() || ipnet.IP.IsLoopback()) {\n\t\t\t\t// TODO DEVTOOLS-12514: We only run the IPv6 against the loopback interface due to issues on the CI runners.\n\t\t\t\tif (ipv4 && ipnet.IP.To4() != nil) || (!ipv4 && ipnet.IP.To4() == nil && ipnet.IP.IsLoopback()) {\n\t\t\t\t\tlocalIPs = append(localIPs, netip.MustParseAddr(ipnet.IP.String()))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn localIPs\n}\n"
  },
  {
    "path": "ingress/origin_proxy.go",
    "content": "package ingress\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\n\t\"github.com/rs/zerolog\"\n)\n\n// HTTPOriginProxy can be implemented by origin services that want to proxy http requests.\ntype HTTPOriginProxy interface {\n\t// RoundTripper is how cloudflared proxies eyeball requests to the actual origin services\n\thttp.RoundTripper\n}\n\n// StreamBasedOriginProxy can be implemented by origin services that want to proxy ws/TCP.\ntype StreamBasedOriginProxy interface {\n\tEstablishConnection(ctx context.Context, dest string, log *zerolog.Logger) (OriginConnection, error)\n}\n\n// HTTPLocalProxy can be implemented by cloudflared services that want to handle incoming http requests.\ntype HTTPLocalProxy interface {\n\t// Handler is how cloudflared proxies eyeball requests to the local cloudflared services\n\thttp.Handler\n}\n\nfunc (o *unixSocketPath) RoundTrip(req *http.Request) (*http.Response, error) {\n\treq.URL.Scheme = o.scheme\n\treturn o.transport.RoundTrip(req)\n}\n\nfunc (o *httpService) RoundTrip(req *http.Request) (*http.Response, error) {\n\t// Rewrite the request URL so that it goes to the origin service.\n\treq.URL.Host = o.url.Host\n\tswitch o.url.Scheme {\n\tcase \"ws\":\n\t\treq.URL.Scheme = \"http\"\n\tcase \"wss\":\n\t\treq.URL.Scheme = \"https\"\n\tdefault:\n\t\treq.URL.Scheme = o.url.Scheme\n\t}\n\n\tif o.hostHeader != \"\" {\n\t\t// For incoming requests, the Host header is promoted to the Request.Host field and removed from the Header map.\n\t\t// Pass the original Host header as X-Forwarded-Host.\n\t\treq.Header.Set(\"X-Forwarded-Host\", req.Host)\n\t\treq.Host = o.hostHeader\n\t}\n\n\tif o.matchSNIToHost {\n\t\to.SetOriginServerName(req)\n\t}\n\n\treturn o.transport.RoundTrip(req)\n}\n\nfunc (o *httpService) SetOriginServerName(req *http.Request) {\n\to.transport.DialTLSContext = func(ctx context.Context, network, addr string) (net.Conn, error) {\n\t\tconn, err := o.transport.DialContext(ctx, network, addr)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn tls.Client(conn, &tls.Config{\n\t\t\tRootCAs:            o.transport.TLSClientConfig.RootCAs,\n\t\t\tInsecureSkipVerify: o.transport.TLSClientConfig.InsecureSkipVerify, // nolint: gosec\n\t\t\tServerName:         req.Host,\n\t\t}), nil\n\t}\n}\n\nfunc (o *statusCode) RoundTrip(_ *http.Request) (*http.Response, error) {\n\tif o.defaultResp {\n\t\to.log.Warn().Msg(ErrNoIngressRulesCLI.Error())\n\t}\n\tresp := &http.Response{\n\t\tStatusCode: o.code,\n\t\tStatus:     fmt.Sprintf(\"%d %s\", o.code, http.StatusText(o.code)),\n\t\tBody:       new(NopReadCloser),\n\t}\n\n\treturn resp, nil\n}\n\nfunc (o *rawTCPService) EstablishConnection(ctx context.Context, dest string, logger *zerolog.Logger) (OriginConnection, error) {\n\tconn, err := o.dialer.DialContext(ctx, \"tcp\", dest)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\toriginConn := &tcpConnection{\n\t\tConn:         conn,\n\t\twriteTimeout: o.writeTimeout,\n\t\tlogger:       logger,\n\t}\n\treturn originConn, nil\n}\n\nfunc (o *tcpOverWSService) EstablishConnection(ctx context.Context, dest string, _ *zerolog.Logger) (OriginConnection, error) {\n\tvar err error\n\tif !o.isBastion {\n\t\tdest = o.dest\n\t}\n\n\tconn, err := o.dialer.DialContext(ctx, \"tcp\", dest)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\toriginConn := &tcpOverWSConnection{\n\t\tconn:          conn,\n\t\tstreamHandler: o.streamHandler,\n\t}\n\treturn originConn, nil\n}\n\nfunc (o *socksProxyOverWSService) EstablishConnection(_ context.Context, _ string, _ *zerolog.Logger) (OriginConnection, error) {\n\treturn o.conn, nil\n}\n"
  },
  {
    "path": "ingress/origin_proxy_test.go",
    "content": "package ingress\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"net/url\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/cloudflare/cloudflared/carrier\"\n\t\"github.com/cloudflare/cloudflared/websocket\"\n)\n\nfunc TestRawTCPServiceEstablishConnection(t *testing.T) {\n\toriginListener, err := net.Listen(\"tcp\", \"127.0.0.1:0\")\n\trequire.NoError(t, err)\n\n\tlistenerClosed := make(chan struct{})\n\ttcpListenRoutine(originListener, listenerClosed)\n\n\trawTCPService := &rawTCPService{name: ServiceWarpRouting}\n\n\treq, err := http.NewRequest(http.MethodGet, fmt.Sprintf(\"http://%s\", originListener.Addr()), nil)\n\trequire.NoError(t, err)\n\n\toriginListener.Close()\n\t<-listenerClosed\n\n\treq, err = http.NewRequest(http.MethodGet, fmt.Sprintf(\"http://%s\", originListener.Addr()), nil)\n\trequire.NoError(t, err)\n\n\t// Origin not listening for new connection, should return an error\n\t_, err = rawTCPService.EstablishConnection(context.Background(), req.URL.String(), TestLogger)\n\trequire.Error(t, err)\n}\n\nfunc TestTCPOverWSServiceEstablishConnection(t *testing.T) {\n\toriginListener, err := net.Listen(\"tcp\", \"127.0.0.1:0\")\n\trequire.NoError(t, err)\n\n\tlistenerClosed := make(chan struct{})\n\ttcpListenRoutine(originListener, listenerClosed)\n\n\toriginURL := &url.URL{\n\t\tScheme: \"tcp\",\n\t\tHost:   originListener.Addr().String(),\n\t}\n\n\tbaseReq, err := http.NewRequest(http.MethodGet, \"https://place-holder\", nil)\n\trequire.NoError(t, err)\n\tbaseReq.Header.Set(\"Sec-Websocket-Key\", \"dGhlIHNhbXBsZSBub25jZQ==\")\n\n\tbastionReq := baseReq.Clone(context.Background())\n\tcarrier.SetBastionDest(bastionReq.Header, originListener.Addr().String())\n\n\ttests := []struct {\n\t\ttestCase  string\n\t\tservice   *tcpOverWSService\n\t\treq       *http.Request\n\t\texpectErr bool\n\t}{\n\t\t{\n\t\t\ttestCase: \"specific TCP service\",\n\t\t\tservice:  newTCPOverWSService(originURL),\n\t\t\treq:      baseReq,\n\t\t},\n\t\t{\n\t\t\ttestCase: \"bastion service\",\n\t\t\tservice:  newBastionService(),\n\t\t\treq:      bastionReq,\n\t\t},\n\t\t{\n\t\t\ttestCase:  \"invalid bastion request\",\n\t\t\tservice:   newBastionService(),\n\t\t\treq:       baseReq,\n\t\t\texpectErr: true,\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.testCase, func(t *testing.T) {\n\t\t\tif test.expectErr {\n\t\t\t\tbastionHost, _ := carrier.ResolveBastionDest(test.req)\n\t\t\t\t_, err := test.service.EstablishConnection(context.Background(), bastionHost, TestLogger)\n\t\t\t\tassert.Error(t, err)\n\t\t\t}\n\t\t})\n\t}\n\n\toriginListener.Close()\n\t<-listenerClosed\n\n\tfor _, service := range []*tcpOverWSService{newTCPOverWSService(originURL), newBastionService()} {\n\t\t// Origin not listening for new connection, should return an error\n\t\tbastionHost, _ := carrier.ResolveBastionDest(bastionReq)\n\t\t_, err := service.EstablishConnection(context.Background(), bastionHost, TestLogger)\n\t\tassert.Error(t, err)\n\t}\n}\n\nfunc TestHTTPServiceHostHeaderOverride(t *testing.T) {\n\tcfg := OriginRequestConfig{\n\t\tHTTPHostHeader: t.Name(),\n\t}\n\thandler := func(w http.ResponseWriter, r *http.Request) {\n\t\trequire.Equal(t, r.Host, t.Name())\n\t\tif websocket.IsWebSocketUpgrade(r) {\n\t\t\trespHeaders := websocket.NewResponseHeader(r)\n\t\t\tfor k, v := range respHeaders {\n\t\t\t\tw.Header().Set(k, v[0])\n\t\t\t}\n\t\t\tw.WriteHeader(http.StatusSwitchingProtocols)\n\t\t\treturn\n\t\t}\n\t\t// return the X-Forwarded-Host header for assertions\n\t\t// as the httptest Server URL isn't available here yet\n\t\tw.Write([]byte(r.Header.Get(\"X-Forwarded-Host\")))\n\t}\n\torigin := httptest.NewServer(http.HandlerFunc(handler))\n\tdefer origin.Close()\n\n\toriginURL, err := url.Parse(origin.URL)\n\trequire.NoError(t, err)\n\n\thttpService := &httpService{\n\t\turl: originURL,\n\t}\n\tshutdownC := make(chan struct{})\n\trequire.NoError(t, httpService.start(TestLogger, shutdownC, cfg))\n\n\treq, err := http.NewRequest(http.MethodGet, originURL.String(), nil)\n\trequire.NoError(t, err)\n\n\tresp, err := httpService.RoundTrip(req)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusOK, resp.StatusCode)\n\n\trespBody, err := io.ReadAll(resp.Body)\n\trequire.NoError(t, err)\n\trequire.Equal(t, respBody, []byte(originURL.Host))\n}\n\n// TestHTTPServiceUsesIngressRuleScheme makes sure httpService uses scheme defined in ingress rule and not by eyeball request\nfunc TestHTTPServiceUsesIngressRuleScheme(t *testing.T) {\n\thandler := func(w http.ResponseWriter, r *http.Request) {\n\t\trequire.NotNil(t, r.TLS)\n\t\t// Echo the X-Forwarded-Proto header for assertions\n\t\tw.Write([]byte(r.Header.Get(\"X-Forwarded-Proto\")))\n\t}\n\torigin := httptest.NewTLSServer(http.HandlerFunc(handler))\n\tdefer origin.Close()\n\n\toriginURL, err := url.Parse(origin.URL)\n\trequire.NoError(t, err)\n\trequire.Equal(t, \"https\", originURL.Scheme)\n\n\tcfg := OriginRequestConfig{\n\t\tNoTLSVerify: true,\n\t}\n\thttpService := &httpService{\n\t\turl: originURL,\n\t}\n\tshutdownC := make(chan struct{})\n\trequire.NoError(t, httpService.start(TestLogger, shutdownC, cfg))\n\n\t// Tunnel uses scheme defined in the service field of the ingress rule, independent of the X-Forwarded-Proto header\n\tprotos := []string{\"https\", \"http\", \"dne\"}\n\tfor _, p := range protos {\n\t\treq, err := http.NewRequest(http.MethodGet, originURL.String(), nil)\n\t\trequire.NoError(t, err)\n\t\treq.Header.Add(\"X-Forwarded-Proto\", p)\n\n\t\tresp, err := httpService.RoundTrip(req)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, http.StatusOK, resp.StatusCode)\n\n\t\trespBody, err := io.ReadAll(resp.Body)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, respBody, []byte(p))\n\t}\n}\n\nfunc tcpListenRoutine(listener net.Listener, closeChan chan struct{}) {\n\tgo func() {\n\t\tfor {\n\t\t\tconn, err := listener.Accept()\n\t\t\tif err != nil {\n\t\t\t\tclose(closeChan)\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// Close immediately, this test is not about testing read/write on connection\n\t\t\tconn.Close()\n\t\t}\n\t}()\n}\n"
  },
  {
    "path": "ingress/origin_service.go",
    "content": "package ingress\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/hello\"\n\t\"github.com/cloudflare/cloudflared/ipaccess\"\n\t\"github.com/cloudflare/cloudflared/management\"\n\t\"github.com/cloudflare/cloudflared/socks\"\n\t\"github.com/cloudflare/cloudflared/tlsconfig\"\n)\n\nconst (\n\tHelloWorldService = \"hello_world\"\n\tHelloWorldFlag    = \"hello-world\"\n\tHttpStatusService = \"http_status\"\n)\n\n// OriginService is something a tunnel can proxy traffic to.\ntype OriginService interface {\n\tString() string\n\t// Start the origin service if it's managed by cloudflared, e.g. proxy servers or Hello World.\n\t// If it's not managed by cloudflared, this is a no-op because the user is responsible for\n\t// starting the origin service.\n\t// Implementor of services managed by cloudflared should terminate the service if shutdownC is closed\n\tstart(log *zerolog.Logger, shutdownC <-chan struct{}, cfg OriginRequestConfig) error\n\tMarshalJSON() ([]byte, error)\n}\n\n// unixSocketPath is an OriginService representing a unix socket (which accepts HTTP or HTTPS)\ntype unixSocketPath struct {\n\tpath      string\n\tscheme    string\n\ttransport *http.Transport\n}\n\nfunc (o *unixSocketPath) String() string {\n\tscheme := \"\"\n\tif o.scheme == \"https\" {\n\t\tscheme = \"+tls\"\n\t}\n\treturn fmt.Sprintf(\"unix%s:%s\", scheme, o.path)\n}\n\nfunc (o *unixSocketPath) start(log *zerolog.Logger, _ <-chan struct{}, cfg OriginRequestConfig) error {\n\ttransport, err := newHTTPTransport(o, cfg, log)\n\tif err != nil {\n\t\treturn err\n\t}\n\to.transport = transport\n\treturn nil\n}\n\nfunc (o unixSocketPath) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(o.String())\n}\n\ntype httpService struct {\n\turl            *url.URL\n\thostHeader     string\n\ttransport      *http.Transport\n\tmatchSNIToHost bool\n}\n\nfunc (o *httpService) start(log *zerolog.Logger, _ <-chan struct{}, cfg OriginRequestConfig) error {\n\ttransport, err := newHTTPTransport(o, cfg, log)\n\tif err != nil {\n\t\treturn err\n\t}\n\to.hostHeader = cfg.HTTPHostHeader\n\to.transport = transport\n\to.matchSNIToHost = cfg.MatchSNIToHost\n\treturn nil\n}\n\nfunc (o *httpService) String() string {\n\treturn o.url.String()\n}\n\nfunc (o httpService) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(o.String())\n}\n\n// rawTCPService dials TCP to the destination specified by the client\n// It's used by warp routing\ntype rawTCPService struct {\n\tname         string\n\tdialer       net.Dialer\n\twriteTimeout time.Duration\n\tlogger       *zerolog.Logger\n}\n\nfunc (o *rawTCPService) String() string {\n\treturn o.name\n}\n\nfunc (o *rawTCPService) start(_ *zerolog.Logger, _ <-chan struct{}, _ OriginRequestConfig) error {\n\treturn nil\n}\n\nfunc (o rawTCPService) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(o.String())\n}\n\n// tcpOverWSService models TCP origins serving eyeballs connecting over websocket, such as\n// cloudflared access commands.\ntype tcpOverWSService struct {\n\tscheme        string\n\tdest          string\n\tisBastion     bool\n\tstreamHandler streamHandlerFunc\n\tdialer        net.Dialer\n}\n\ntype socksProxyOverWSService struct {\n\tconn *socksProxyOverWSConnection\n}\n\nfunc newTCPOverWSService(url *url.URL) *tcpOverWSService {\n\tswitch url.Scheme {\n\tcase \"ssh\":\n\t\taddPortIfMissing(url, 22)\n\tcase \"rdp\":\n\t\taddPortIfMissing(url, 3389)\n\tcase \"smb\":\n\t\taddPortIfMissing(url, 445)\n\tcase \"tcp\":\n\t\taddPortIfMissing(url, 7864) // just a random port since there isn't a default in this case\n\t}\n\treturn &tcpOverWSService{\n\t\tscheme: url.Scheme,\n\t\tdest:   url.Host,\n\t}\n}\n\nfunc newBastionService() *tcpOverWSService {\n\treturn &tcpOverWSService{\n\t\tisBastion: true,\n\t}\n}\n\nfunc newSocksProxyOverWSService(accessPolicy *ipaccess.Policy) *socksProxyOverWSService {\n\tproxy := socksProxyOverWSService{\n\t\tconn: &socksProxyOverWSConnection{\n\t\t\taccessPolicy: accessPolicy,\n\t\t},\n\t}\n\n\treturn &proxy\n}\n\nfunc addPortIfMissing(uri *url.URL, port int) {\n\thostname := uri.Hostname()\n\n\tif uri.Port() == \"\" {\n\t\turi.Host = net.JoinHostPort(hostname, strconv.FormatInt(int64(port), 10))\n\t}\n}\n\nfunc (o *tcpOverWSService) String() string {\n\tif o.isBastion {\n\t\treturn ServiceBastion\n\t}\n\n\tif o.scheme != \"\" {\n\t\treturn fmt.Sprintf(\"%s://%s\", o.scheme, o.dest)\n\t} else {\n\t\treturn o.dest\n\t}\n}\n\nfunc (o *tcpOverWSService) start(log *zerolog.Logger, _ <-chan struct{}, cfg OriginRequestConfig) error {\n\tif cfg.ProxyType == socksProxy {\n\t\to.streamHandler = socks.StreamHandler\n\t} else {\n\t\to.streamHandler = DefaultStreamHandler\n\t}\n\to.dialer.Timeout = cfg.ConnectTimeout.Duration\n\to.dialer.KeepAlive = cfg.TCPKeepAlive.Duration\n\treturn nil\n}\n\nfunc (o tcpOverWSService) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(o.String())\n}\n\nfunc (o *socksProxyOverWSService) start(log *zerolog.Logger, _ <-chan struct{}, cfg OriginRequestConfig) error {\n\treturn nil\n}\n\nfunc (o *socksProxyOverWSService) String() string {\n\treturn ServiceSocksProxy\n}\n\nfunc (o socksProxyOverWSService) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(o.String())\n}\n\n// HelloWorld is an OriginService for the built-in Hello World server.\n// Users only use this for testing and experimenting with cloudflared.\ntype helloWorld struct {\n\thttpService\n\tserver net.Listener\n}\n\nfunc (o *helloWorld) String() string {\n\treturn HelloWorldService\n}\n\n// Start starts a HelloWorld server and stores its address in the Service receiver.\nfunc (o *helloWorld) start(\n\tlog *zerolog.Logger,\n\tshutdownC <-chan struct{},\n\tcfg OriginRequestConfig,\n) error {\n\tif err := o.httpService.start(log, shutdownC, cfg); err != nil {\n\t\treturn err\n\t}\n\n\thelloListener, err := hello.CreateTLSListener(\"127.0.0.1:\")\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Cannot start Hello World Server\")\n\t}\n\tgo hello.StartHelloWorldServer(log, helloListener, shutdownC)\n\to.server = helloListener\n\n\to.httpService.url = &url.URL{\n\t\tScheme: \"https\",\n\t\tHost:   o.server.Addr().String(),\n\t}\n\n\treturn nil\n}\n\nfunc (o helloWorld) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(o.String())\n}\n\n// statusCode is an OriginService that just responds with a given HTTP status.\n// Typical use-case is \"user wants the catch-all rule to just respond 404\".\ntype statusCode struct {\n\tcode int\n\n\t// Set only when the user has not defined any ingress rules\n\tdefaultResp bool\n\tlog         *zerolog.Logger\n}\n\nfunc newStatusCode(status int) statusCode {\n\treturn statusCode{code: status}\n}\n\n// default status code (503) that is returned for requests to cloudflared that don't have any ingress rules setup\nfunc newDefaultStatusCode(log *zerolog.Logger) statusCode {\n\treturn statusCode{code: 503, defaultResp: true, log: log}\n}\n\nfunc (o *statusCode) String() string {\n\treturn fmt.Sprintf(\"http_status:%d\", o.code)\n}\n\nfunc (o *statusCode) start(\n\tlog *zerolog.Logger,\n\t_ <-chan struct{},\n\tcfg OriginRequestConfig,\n) error {\n\treturn nil\n}\n\nfunc (o statusCode) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(o.String())\n}\n\n// WarpRoutingService starts a tcp stream between the origin and requests from\n// warp clients.\ntype WarpRoutingService struct {\n\tProxy StreamBasedOriginProxy\n}\n\nfunc NewWarpRoutingService(config WarpRoutingConfig, writeTimeout time.Duration) *WarpRoutingService {\n\tsvc := &rawTCPService{\n\t\tname: ServiceWarpRouting,\n\t\tdialer: net.Dialer{\n\t\t\tTimeout:   config.ConnectTimeout.Duration,\n\t\t\tKeepAlive: config.TCPKeepAlive.Duration,\n\t\t},\n\t\twriteTimeout: writeTimeout,\n\t}\n\n\treturn &WarpRoutingService{Proxy: svc}\n}\n\n// ManagementService starts a local HTTP server to handle incoming management requests.\ntype ManagementService struct {\n\tHTTPLocalProxy\n}\n\nfunc newManagementService(managementProxy HTTPLocalProxy) *ManagementService {\n\treturn &ManagementService{\n\t\tHTTPLocalProxy: managementProxy,\n\t}\n}\n\nfunc (o *ManagementService) start(log *zerolog.Logger, _ <-chan struct{}, cfg OriginRequestConfig) error {\n\treturn nil\n}\n\nfunc (o *ManagementService) String() string {\n\treturn \"management\"\n}\n\nfunc (o ManagementService) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(o.String())\n}\n\nfunc NewManagementRule(management *management.ManagementService) Rule {\n\treturn Rule{\n\t\tHostname: management.Hostname,\n\t\tService:  newManagementService(management),\n\t}\n}\n\ntype NopReadCloser struct{}\n\n// Read always returns EOF to signal end of input\nfunc (nrc *NopReadCloser) Read(buf []byte) (int, error) {\n\treturn 0, io.EOF\n}\n\nfunc (nrc *NopReadCloser) Close() error {\n\treturn nil\n}\n\nfunc newHTTPTransport(service OriginService, cfg OriginRequestConfig, log *zerolog.Logger) (*http.Transport, error) {\n\toriginCertPool, err := tlsconfig.LoadOriginCA(cfg.CAPool, log)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"Error loading cert pool\")\n\t}\n\n\thttpTransport := http.Transport{\n\t\tProxy:                 http.ProxyFromEnvironment,\n\t\tMaxIdleConns:          cfg.KeepAliveConnections,\n\t\tMaxIdleConnsPerHost:   cfg.KeepAliveConnections,\n\t\tIdleConnTimeout:       cfg.KeepAliveTimeout.Duration,\n\t\tTLSHandshakeTimeout:   cfg.TLSTimeout.Duration,\n\t\tExpectContinueTimeout: 1 * time.Second,\n\t\tTLSClientConfig:       &tls.Config{RootCAs: originCertPool, InsecureSkipVerify: cfg.NoTLSVerify},\n\t\tForceAttemptHTTP2:     cfg.Http2Origin,\n\t}\n\tif _, isHelloWorld := service.(*helloWorld); !isHelloWorld && cfg.OriginServerName != \"\" {\n\t\thttpTransport.TLSClientConfig.ServerName = cfg.OriginServerName\n\t}\n\n\tdialer := &net.Dialer{\n\t\tTimeout:   cfg.ConnectTimeout.Duration,\n\t\tKeepAlive: cfg.TCPKeepAlive.Duration,\n\t}\n\tif cfg.NoHappyEyeballs {\n\t\tdialer.FallbackDelay = -1 // As of Golang 1.12, a negative delay disables \"happy eyeballs\"\n\t}\n\n\t// DialContext depends on which kind of origin is being used.\n\tdialContext := dialer.DialContext\n\tswitch service := service.(type) {\n\n\t// If this origin is a unix socket, enforce network type \"unix\".\n\tcase *unixSocketPath:\n\t\thttpTransport.DialContext = func(ctx context.Context, _, _ string) (net.Conn, error) {\n\t\t\treturn dialContext(ctx, \"unix\", service.path)\n\t\t}\n\n\t// Otherwise, use the regular network config.\n\tdefault:\n\t\thttpTransport.DialContext = dialContext\n\t}\n\n\treturn &httpTransport, nil\n}\n\n// MockOriginHTTPService should only be used by other packages to mock OriginService. Set Transport to configure desired RoundTripper behavior.\ntype MockOriginHTTPService struct {\n\tTransport http.RoundTripper\n}\n\nfunc (mos MockOriginHTTPService) RoundTrip(req *http.Request) (*http.Response, error) {\n\treturn mos.Transport.RoundTrip(req)\n}\n\nfunc (mos MockOriginHTTPService) String() string {\n\treturn \"MockOriginService\"\n}\n\nfunc (mos MockOriginHTTPService) start(log *zerolog.Logger, _ <-chan struct{}, cfg OriginRequestConfig) error {\n\treturn nil\n}\n\nfunc (mos MockOriginHTTPService) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(mos.String())\n}\n"
  },
  {
    "path": "ingress/origin_service_test.go",
    "content": "package ingress\n\nimport (\n\t\"net/url\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestAddPortIfMissing(t *testing.T) {\n\ttestCases := []struct {\n\t\tinput    string\n\t\texpected string\n\t}{\n\t\t{\"ssh://[::1]\", \"[::1]:22\"},\n\t\t{\"ssh://[::1]:38\", \"[::1]:38\"},\n\t\t{\"ssh://abc:38\", \"abc:38\"},\n\t\t{\"ssh://127.0.0.1:38\", \"127.0.0.1:38\"},\n\t\t{\"ssh://127.0.0.1\", \"127.0.0.1:22\"},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.input, func(t *testing.T) {\n\t\t\turl1, _ := url.Parse(tc.input)\n\t\t\taddPortIfMissing(url1, 22)\n\t\t\trequire.Equal(t, tc.expected, url1.Host)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "ingress/origins/dns.go",
    "content": "package origins\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"math/big\"\n\t\"net\"\n\t\"net/netip\"\n\t\"slices\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/ingress\"\n)\n\nconst (\n\t// We need a DNS record:\n\t// 1. That will be around for as long as cloudflared is\n\t// 2. That Cloudflare controls: to allow us to make changes if needed\n\t// 3. That is an external record to a typical customer's network: enforcing that the DNS request go to the\n\t//    local DNS resolver over any local /etc/host configurations setup.\n\t// 4. That cloudflared would normally query: ensuring that users with a positive security model for DNS queries\n\t//    don't need to adjust anything.\n\t//\n\t// This hostname is one that used during the edge discovery process and as such satisfies the above constraints.\n\tdefaultLookupHost          = \"region1.v2.argotunnel.com\"\n\tdefaultResolverPort uint16 = 53\n\n\t// We want the refresh time to be short to accommodate DNS resolver changes locally, but not too frequent as to\n\t// shuffle the resolver if multiple are configured.\n\trefreshFreq    = 5 * time.Minute\n\trefreshTimeout = 5 * time.Second\n)\n\nvar (\n\t// Virtual DNS service address\n\tVirtualDNSServiceAddr = netip.AddrPortFrom(netip.MustParseAddr(\"2606:4700:0cf1:2000:0000:0000:0000:0001\"), 53)\n\n\tdefaultResolverAddr = netip.AddrPortFrom(netip.MustParseAddr(\"127.0.0.1\"), defaultResolverPort)\n)\n\ntype netDial func(network string, address string) (net.Conn, error)\n\n// DNSResolverService will make DNS requests to the local DNS resolver via the Dial method.\ntype DNSResolverService struct {\n\taddresses  []netip.AddrPort\n\taddressesM sync.RWMutex\n\tstatic     bool\n\tdialer     ingress.OriginDialer\n\tresolver   peekResolver\n\tlogger     *zerolog.Logger\n\tmetrics    Metrics\n}\n\nfunc NewDNSResolverService(dialer ingress.OriginDialer, logger *zerolog.Logger, metrics Metrics) *DNSResolverService {\n\treturn &DNSResolverService{\n\t\taddresses: []netip.AddrPort{defaultResolverAddr},\n\t\tdialer:    dialer,\n\t\tresolver:  &resolver{dialFunc: net.Dial},\n\t\tlogger:    logger,\n\t\tmetrics:   metrics,\n\t}\n}\n\nfunc NewStaticDNSResolverService(resolverAddrs []netip.AddrPort, dialer ingress.OriginDialer, logger *zerolog.Logger, metrics Metrics) *DNSResolverService {\n\ts := NewDNSResolverService(dialer, logger, metrics)\n\ts.addresses = resolverAddrs\n\ts.static = true\n\treturn s\n}\n\nfunc (s *DNSResolverService) DialTCP(ctx context.Context, _ netip.AddrPort) (net.Conn, error) {\n\ts.metrics.IncrementDNSTCPRequests()\n\tdest := s.getAddress()\n\t// The dialer ignores the provided address because the request will instead go to the local DNS resolver.\n\treturn s.dialer.DialTCP(ctx, dest)\n}\n\nfunc (s *DNSResolverService) DialUDP(_ netip.AddrPort) (net.Conn, error) {\n\ts.metrics.IncrementDNSUDPRequests()\n\tdest := s.getAddress()\n\t// The dialer ignores the provided address because the request will instead go to the local DNS resolver.\n\treturn s.dialer.DialUDP(dest)\n}\n\n// StartRefreshLoop is a routine that is expected to run in the background to update the DNS local resolver if\n// adjusted while the cloudflared process is running.\n// Does not run when the resolver was provided with external resolver addresses via CLI.\nfunc (s *DNSResolverService) StartRefreshLoop(ctx context.Context) {\n\tif s.static {\n\t\ts.logger.Debug().Msgf(\"Canceled DNS local resolver refresh loop because static resolver addresses were provided: %s\", s.addresses)\n\t\treturn\n\t}\n\t// Call update first to load an address before handling traffic\n\terr := s.update(ctx)\n\tif err != nil {\n\t\ts.logger.Err(err).Msg(\"Failed to initialize DNS local resolver\")\n\t}\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\tcase <-time.Tick(refreshFreq):\n\t\t\terr := s.update(ctx)\n\t\t\tif err != nil {\n\t\t\t\ts.logger.Err(err).Msg(\"Failed to refresh DNS local resolver\")\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (s *DNSResolverService) update(ctx context.Context) error {\n\tctx, cancel := context.WithTimeout(ctx, refreshTimeout)\n\tdefer cancel()\n\t// Make a standard DNS request to a well-known DNS record that will last a long time\n\t_, err := s.resolver.lookupNetIP(ctx, defaultLookupHost)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Validate the address before updating internal reference\n\t_, address := s.resolver.addr()\n\tpeekAddrPort, err := netip.ParseAddrPort(address)\n\tif err == nil {\n\t\ts.setAddress(peekAddrPort)\n\t\treturn nil\n\t}\n\t// It's possible that the address didn't have an attached port, attempt to parse just the address and use\n\t// the default port 53\n\tpeekAddr, err := netip.ParseAddr(address)\n\tif err != nil {\n\t\treturn err\n\t}\n\ts.setAddress(netip.AddrPortFrom(peekAddr, defaultResolverPort))\n\treturn nil\n}\n\n// returns the address from the peekResolver or from the static addresses if provided.\n// If multiple addresses are provided in the static addresses pick one randomly.\nfunc (s *DNSResolverService) getAddress() netip.AddrPort {\n\ts.addressesM.RLock()\n\tdefer s.addressesM.RUnlock()\n\tl := len(s.addresses)\n\tif l <= 0 {\n\t\treturn defaultResolverAddr\n\t}\n\tif l == 1 {\n\t\treturn s.addresses[0]\n\t}\n\t// Only initialize the random selection if there is more than one element in the list.\n\tvar i int64 = 0\n\tr, err := rand.Int(rand.Reader, big.NewInt(int64(l)))\n\t// We ignore errors from crypto rand and use index 0; this should be extremely unlikely and the\n\t// list index doesn't need to be cryptographically secure, but linters insist.\n\tif err == nil {\n\t\ti = r.Int64()\n\t}\n\treturn s.addresses[i]\n}\n\n// lock and update the address used for the local DNS resolver\nfunc (s *DNSResolverService) setAddress(addr netip.AddrPort) {\n\ts.addressesM.Lock()\n\tdefer s.addressesM.Unlock()\n\tif !slices.Contains(s.addresses, addr) {\n\t\ts.logger.Debug().Msgf(\"Updating DNS local resolver: %s\", addr)\n\t}\n\t// We only store one address when reading the peekResolver, so we just replace the whole list.\n\ts.addresses = []netip.AddrPort{addr}\n}\n\ntype peekResolver interface {\n\taddr() (network string, address string)\n\tlookupNetIP(ctx context.Context, host string) ([]netip.Addr, error)\n}\n\n// resolver is a shim that inspects the go runtime's DNS resolution process to capture the DNS resolver\n// address used to complete a DNS request.\ntype resolver struct {\n\tnetwork  string\n\taddress  string\n\tdialFunc netDial\n}\n\nfunc (r *resolver) addr() (network string, address string) {\n\treturn r.network, r.address\n}\n\nfunc (r *resolver) lookupNetIP(ctx context.Context, host string) ([]netip.Addr, error) {\n\tresolver := &net.Resolver{\n\t\tPreferGo: true,\n\t\t// Use the peekDial to inspect the results of the DNS resolver used during the LookupIPAddr call.\n\t\tDial: r.peekDial,\n\t}\n\treturn resolver.LookupNetIP(ctx, \"ip\", host)\n}\n\nfunc (r *resolver) peekDial(ctx context.Context, network, address string) (net.Conn, error) {\n\tr.network = network\n\tr.address = address\n\treturn r.dialFunc(network, address)\n}\n\n// NewDNSDialer creates a custom dialer for the DNS resolver service to utilize.\nfunc NewDNSDialer() *ingress.Dialer {\n\treturn &ingress.Dialer{\n\t\tDialer: net.Dialer{\n\t\t\t// We want short timeouts for the DNS requests\n\t\t\tTimeout: 5 * time.Second,\n\t\t\t// We do not want keep alive since the edge will not reuse TCP connections per request\n\t\t\tKeepAlive: -1,\n\t\t\tKeepAliveConfig: net.KeepAliveConfig{\n\t\t\t\tEnable: false,\n\t\t\t},\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "ingress/origins/dns_test.go",
    "content": "package origins\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net\"\n\t\"net/netip\"\n\t\"slices\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/rs/zerolog\"\n)\n\nfunc TestDNSResolver_DefaultResolver(t *testing.T) {\n\tlog := zerolog.Nop()\n\tservice := NewDNSResolverService(NewDNSDialer(), &log, &noopMetrics{})\n\tmockResolver := &mockPeekResolver{\n\t\taddress: \"127.0.0.2:53\",\n\t}\n\tservice.resolver = mockResolver\n\tvalidateAddrs(t, []netip.AddrPort{defaultResolverAddr}, service.addresses)\n}\n\nfunc TestStaticDNSResolver_DefaultResolver(t *testing.T) {\n\tlog := zerolog.Nop()\n\taddresses := []netip.AddrPort{netip.MustParseAddrPort(\"1.1.1.1:53\"), netip.MustParseAddrPort(\"1.0.0.1:53\")}\n\tservice := NewStaticDNSResolverService(addresses, NewDNSDialer(), &log, &noopMetrics{})\n\tmockResolver := &mockPeekResolver{\n\t\taddress: \"127.0.0.2:53\",\n\t}\n\tservice.resolver = mockResolver\n\tvalidateAddrs(t, addresses, service.addresses)\n}\n\nfunc TestDNSResolver_UpdateResolverAddress(t *testing.T) {\n\tlog := zerolog.Nop()\n\tservice := NewDNSResolverService(NewDNSDialer(), &log, &noopMetrics{})\n\n\tmockResolver := &mockPeekResolver{}\n\tservice.resolver = mockResolver\n\n\ttests := []struct {\n\t\taddr     string\n\t\texpected netip.AddrPort\n\t}{\n\t\t{\"127.0.0.2:53\", netip.MustParseAddrPort(\"127.0.0.2:53\")},\n\t\t// missing port should be added (even though this is unlikely to happen)\n\t\t{\"127.0.0.3\", netip.MustParseAddrPort(\"127.0.0.3:53\")},\n\t}\n\n\tfor _, test := range tests {\n\t\tmockResolver.address = test.addr\n\t\t// Update the resolver address\n\t\terr := service.update(t.Context())\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\t// Validate expected\n\t\tvalidateAddrs(t, []netip.AddrPort{test.expected}, service.addresses)\n\t}\n}\n\nfunc TestStaticDNSResolver_RefreshLoopExits(t *testing.T) {\n\tlog := zerolog.Nop()\n\taddresses := []netip.AddrPort{netip.MustParseAddrPort(\"1.1.1.1:53\"), netip.MustParseAddrPort(\"1.0.0.1:53\")}\n\tservice := NewStaticDNSResolverService(addresses, NewDNSDialer(), &log, &noopMetrics{})\n\n\tmockResolver := &mockPeekResolver{\n\t\taddress: \"127.0.0.2:53\",\n\t}\n\tservice.resolver = mockResolver\n\n\tctx, cancel := context.WithCancel(t.Context())\n\tdefer cancel()\n\n\tgo service.StartRefreshLoop(ctx)\n\n\t// Wait for the refresh loop to end _and_ not update the addresses\n\ttime.Sleep(10 * time.Millisecond)\n\n\t// Validate expected\n\tvalidateAddrs(t, addresses, service.addresses)\n}\n\nfunc TestDNSResolver_UpdateResolverAddressInvalid(t *testing.T) {\n\tlog := zerolog.Nop()\n\tservice := NewDNSResolverService(NewDNSDialer(), &log, &noopMetrics{})\n\tmockResolver := &mockPeekResolver{}\n\tservice.resolver = mockResolver\n\n\tinvalidAddresses := []string{\n\t\t\"999.999.999.999\",\n\t\t\"localhost\",\n\t\t\"255.255.255\",\n\t}\n\n\tfor _, addr := range invalidAddresses {\n\t\tmockResolver.address = addr\n\t\t// Update the resolver address should not update for these invalid addresses\n\t\terr := service.update(t.Context())\n\t\tif err == nil {\n\t\t\tt.Error(\"service update should throw an error\")\n\t\t}\n\t\t// Validate expected\n\t\tvalidateAddrs(t, []netip.AddrPort{defaultResolverAddr}, service.addresses)\n\t}\n}\n\nfunc TestDNSResolver_UpdateResolverErrorIgnored(t *testing.T) {\n\tlog := zerolog.Nop()\n\tservice := NewDNSResolverService(NewDNSDialer(), &log, &noopMetrics{})\n\tresolverErr := errors.New(\"test resolver error\")\n\tmockResolver := &mockPeekResolver{err: resolverErr}\n\tservice.resolver = mockResolver\n\n\t// Update the resolver address should not update when the resolver cannot complete the lookup\n\terr := service.update(t.Context())\n\tif err != resolverErr {\n\t\tt.Error(\"service update should throw an error\")\n\t}\n\t// Validate expected\n\tvalidateAddrs(t, []netip.AddrPort{defaultResolverAddr}, service.addresses)\n}\n\nfunc TestDNSResolver_DialUDPUsesResolvedAddress(t *testing.T) {\n\tlog := zerolog.Nop()\n\tmockDialer := &mockDialer{expected: defaultResolverAddr}\n\tservice := NewDNSResolverService(mockDialer, &log, &noopMetrics{})\n\tmockResolver := &mockPeekResolver{}\n\tservice.resolver = mockResolver\n\n\t// Attempt a dial to 127.0.0.2:53 which should be ignored and instead resolve to 127.0.0.1:53\n\t_, err := service.DialUDP(netip.MustParseAddrPort(\"127.0.0.2:53\"))\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n}\n\nfunc TestDNSResolver_DialTCPUsesResolvedAddress(t *testing.T) {\n\tlog := zerolog.Nop()\n\tmockDialer := &mockDialer{expected: defaultResolverAddr}\n\tservice := NewDNSResolverService(mockDialer, &log, &noopMetrics{})\n\tmockResolver := &mockPeekResolver{}\n\tservice.resolver = mockResolver\n\n\t// Attempt a dial to 127.0.0.2:53 which should be ignored and instead resolve to 127.0.0.1:53\n\t_, err := service.DialTCP(t.Context(), netip.MustParseAddrPort(\"127.0.0.2:53\"))\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n}\n\ntype mockPeekResolver struct {\n\terr     error\n\taddress string\n}\n\nfunc (r *mockPeekResolver) addr() (network, address string) {\n\treturn \"udp\", r.address\n}\n\nfunc (r *mockPeekResolver) lookupNetIP(ctx context.Context, host string) ([]netip.Addr, error) {\n\t// We can return an empty result as it doesn't matter as long as the lookup doesn't fail\n\treturn []netip.Addr{}, r.err\n}\n\ntype mockDialer struct {\n\texpected netip.AddrPort\n}\n\nfunc (d *mockDialer) DialTCP(ctx context.Context, addr netip.AddrPort) (net.Conn, error) {\n\tif d.expected != addr {\n\t\treturn nil, errors.New(\"unexpected address dialed\")\n\t}\n\treturn nil, nil\n}\n\nfunc (d *mockDialer) DialUDP(addr netip.AddrPort) (net.Conn, error) {\n\tif d.expected != addr {\n\t\treturn nil, errors.New(\"unexpected address dialed\")\n\t}\n\treturn nil, nil\n}\n\nfunc validateAddrs(t *testing.T, expected []netip.AddrPort, actual []netip.AddrPort) {\n\tif len(actual) != len(expected) {\n\t\tt.Errorf(\"addresses should only contain one element: %s\", actual)\n\t}\n\tfor _, e := range expected {\n\t\tif !slices.Contains(actual, e) {\n\t\t\tt.Errorf(\"missing address: %s in %s\", e, actual)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "ingress/origins/metrics.go",
    "content": "package origins\n\nimport (\n\t\"github.com/prometheus/client_golang/prometheus\"\n)\n\nconst (\n\tnamespace = \"cloudflared\"\n\tsubsystem = \"virtual_origins\"\n)\n\ntype Metrics interface {\n\tIncrementDNSUDPRequests()\n\tIncrementDNSTCPRequests()\n}\n\ntype metrics struct {\n\tdnsResolverRequests *prometheus.CounterVec\n}\n\nfunc (m *metrics) IncrementDNSUDPRequests() {\n\tm.dnsResolverRequests.WithLabelValues(\"udp\").Inc()\n}\n\nfunc (m *metrics) IncrementDNSTCPRequests() {\n\tm.dnsResolverRequests.WithLabelValues(\"tcp\").Inc()\n}\n\nfunc NewMetrics(registerer prometheus.Registerer) Metrics {\n\tm := &metrics{\n\t\tdnsResolverRequests: prometheus.NewCounterVec(prometheus.CounterOpts{\n\t\t\tNamespace: namespace,\n\t\t\tSubsystem: subsystem,\n\t\t\tName:      \"dns_requests_total\",\n\t\t\tHelp:      \"Total count of DNS requests that have been proxied to the virtual DNS resolver origin\",\n\t\t}, []string{\"protocol\"}),\n\t}\n\tregisterer.MustRegister(m.dnsResolverRequests)\n\treturn m\n}\n"
  },
  {
    "path": "ingress/origins/metrics_test.go",
    "content": "package origins\n\ntype noopMetrics struct{}\n\nfunc (noopMetrics) IncrementDNSUDPRequests() {}\nfunc (noopMetrics) IncrementDNSTCPRequests() {}\n"
  },
  {
    "path": "ingress/packet_router.go",
    "content": "package ingress\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/rs/zerolog\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/trace\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n\tquicpogs \"github.com/cloudflare/cloudflared/quic\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n)\n\n// Upstream of raw packets\ntype muxer interface {\n\tSendPacket(pk quicpogs.Packet) error\n\t// ReceivePacket waits for the next raw packet from upstream\n\tReceivePacket(ctx context.Context) (quicpogs.Packet, error)\n}\n\n// PacketRouter routes packets between Upstream and ICMPRouter. Currently it rejects all other type of ICMP packets\ntype PacketRouter struct {\n\ticmpRouter ICMPRouter\n\tmuxer      muxer\n\tconnIndex  uint8\n\tlogger     *zerolog.Logger\n\tencoder    *packet.Encoder\n\tdecoder    *packet.ICMPDecoder\n}\n\n// NewPacketRouter creates a PacketRouter that handles ICMP packets. Packets are read from muxer but dropped if globalConfig is nil.\nfunc NewPacketRouter(icmpRouter ICMPRouter, muxer muxer, connIndex uint8, logger *zerolog.Logger) *PacketRouter {\n\treturn &PacketRouter{\n\t\ticmpRouter: icmpRouter,\n\t\tmuxer:      muxer,\n\t\tconnIndex:  connIndex,\n\t\tlogger:     logger,\n\t\tencoder:    packet.NewEncoder(),\n\t\tdecoder:    packet.NewICMPDecoder(),\n\t}\n}\n\nfunc (r *PacketRouter) Serve(ctx context.Context) error {\n\tfor {\n\t\trawPacket, responder, err := r.nextPacket(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tr.handlePacket(ctx, rawPacket, responder)\n\t}\n}\n\nfunc (r *PacketRouter) nextPacket(ctx context.Context) (packet.RawPacket, ICMPResponder, error) {\n\tpk, err := r.muxer.ReceivePacket(ctx)\n\tif err != nil {\n\t\treturn packet.RawPacket{}, nil, err\n\t}\n\tresponder := newPacketResponder(r.muxer, r.connIndex, packet.NewEncoder())\n\n\tswitch pk.Type() {\n\tcase quicpogs.DatagramTypeIP:\n\t\treturn packet.RawPacket{Data: pk.Payload()}, responder, nil\n\tcase quicpogs.DatagramTypeIPWithTrace:\n\t\tvar identity tracing.Identity\n\t\tif err := identity.UnmarshalBinary(pk.Metadata()); err != nil {\n\t\t\tr.logger.Err(err).Bytes(\"tracingIdentity\", pk.Metadata()).Msg(\"Failed to unmarshal tracing identity\")\n\t\t} else {\n\t\t\ttracedCtx := tracing.NewTracedContext(ctx, identity.String(), r.logger)\n\t\t\tresponder.AddTraceContext(tracedCtx, pk.Metadata())\n\t\t}\n\t\treturn packet.RawPacket{Data: pk.Payload()}, responder, nil\n\tdefault:\n\t\treturn packet.RawPacket{}, nil, fmt.Errorf(\"unexpected datagram type %d\", pk.Type())\n\t}\n}\n\nfunc (r *PacketRouter) handlePacket(ctx context.Context, rawPacket packet.RawPacket, responder ICMPResponder) {\n\t// ICMP Proxy feature is disabled, drop packets\n\tif r.icmpRouter == nil {\n\t\treturn\n\t}\n\n\ticmpPacket, err := r.decoder.Decode(rawPacket)\n\tif err != nil {\n\t\tr.logger.Err(err).Msg(\"Failed to decode ICMP packet from quic datagram\")\n\t\treturn\n\t}\n\n\tif icmpPacket.TTL <= 1 {\n\t\tif err := r.sendTTLExceedMsg(icmpPacket, rawPacket); err != nil {\n\t\t\tr.logger.Err(err).Msg(\"Failed to return ICMP TTL exceed error\")\n\t\t}\n\t\treturn\n\t}\n\ticmpPacket.TTL--\n\n\tif err := r.icmpRouter.Request(ctx, icmpPacket, responder); err != nil {\n\t\tr.logger.Err(err).\n\t\t\tStr(\"src\", icmpPacket.Src.String()).\n\t\t\tStr(\"dst\", icmpPacket.Dst.String()).\n\t\t\tInterface(\"type\", icmpPacket.Type).\n\t\t\tMsg(\"Failed to send ICMP packet\")\n\t}\n}\n\nfunc (r *PacketRouter) sendTTLExceedMsg(pk *packet.ICMP, rawPacket packet.RawPacket) error {\n\ticmpTTLPacket := r.icmpRouter.ConvertToTTLExceeded(pk, rawPacket)\n\tencodedTTLExceed, err := r.encoder.Encode(icmpTTLPacket)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn r.muxer.SendPacket(quicpogs.RawPacket(encodedTTLExceed))\n}\n\n// packetResponder should not be used concurrently. This assumption is upheld because reply packets are ready one-by-one\ntype packetResponder struct {\n\tdatagramMuxer      muxer\n\tconnIndex          uint8\n\tencoder            *packet.Encoder\n\ttracedCtx          *tracing.TracedContext\n\tserializedIdentity []byte\n\t// hadReply tracks if there has been any reply for this flow\n\thadReply bool\n}\n\nfunc newPacketResponder(datagramMuxer muxer, connIndex uint8, encoder *packet.Encoder) ICMPResponder {\n\treturn &packetResponder{\n\t\tdatagramMuxer: datagramMuxer,\n\t\tconnIndex:     connIndex,\n\t\tencoder:       encoder,\n\t}\n}\n\nfunc (pr *packetResponder) tracingEnabled() bool {\n\treturn pr.tracedCtx != nil\n}\n\nfunc (pr *packetResponder) ConnectionIndex() uint8 {\n\treturn pr.connIndex\n}\n\nfunc (pr *packetResponder) ReturnPacket(pk *packet.ICMP) error {\n\trawPacket, err := pr.encoder.Encode(pk)\n\tif err != nil {\n\t\treturn err\n\t}\n\tpr.hadReply = true\n\treturn pr.datagramMuxer.SendPacket(quicpogs.RawPacket(rawPacket))\n}\n\nfunc (pr *packetResponder) AddTraceContext(tracedCtx *tracing.TracedContext, serializedIdentity []byte) {\n\tpr.tracedCtx = tracedCtx\n\tpr.serializedIdentity = serializedIdentity\n}\n\nfunc (pr *packetResponder) RequestSpan(ctx context.Context, pk *packet.ICMP) (context.Context, trace.Span) {\n\tif !pr.tracingEnabled() {\n\t\treturn ctx, tracing.NewNoopSpan()\n\t}\n\treturn pr.tracedCtx.Tracer().Start(pr.tracedCtx, \"icmp-echo-request\", trace.WithAttributes(\n\t\tattribute.String(\"src\", pk.Src.String()),\n\t\tattribute.String(\"dst\", pk.Dst.String()),\n\t))\n}\n\nfunc (pr *packetResponder) ReplySpan(ctx context.Context, logger *zerolog.Logger) (context.Context, trace.Span) {\n\tif !pr.tracingEnabled() || pr.hadReply {\n\t\treturn ctx, tracing.NewNoopSpan()\n\t}\n\treturn pr.tracedCtx.Tracer().Start(pr.tracedCtx, \"icmp-echo-reply\")\n}\n\nfunc (pr *packetResponder) ExportSpan() {\n\tif !pr.tracingEnabled() {\n\t\treturn\n\t}\n\tspans := pr.tracedCtx.GetProtoSpans()\n\tif len(spans) > 0 {\n\t\tpr.datagramMuxer.SendPacket(&quicpogs.TracingSpanPacket{\n\t\t\tSpans:           spans,\n\t\t\tTracingIdentity: pr.serializedIdentity,\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "ingress/packet_router_test.go",
    "content": "package ingress\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"net/netip\"\n\t\"sync/atomic\"\n\t\"testing\"\n\n\t\"github.com/google/gopacket/layers\"\n\t\"github.com/stretchr/testify/require\"\n\t\"golang.org/x/net/icmp\"\n\t\"golang.org/x/net/ipv4\"\n\t\"golang.org/x/net/ipv6\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n\tquicpogs \"github.com/cloudflare/cloudflared/quic\"\n)\n\nvar (\n\tdefaultRouter = &icmpRouter{\n\t\tipv4Proxy: nil,\n\t\tipv4Src:   netip.MustParseAddr(\"172.16.0.1\"),\n\t\tipv6Proxy: nil,\n\t\tipv6Src:   netip.MustParseAddr(\"fd51:2391:523:f4ee::1\"),\n\t}\n)\n\nfunc TestRouterReturnTTLExceed(t *testing.T) {\n\tmuxer := newMockMuxer(0)\n\trouter := NewPacketRouter(defaultRouter, muxer, 0, &noopLogger)\n\tctx, cancel := context.WithCancel(context.Background())\n\trouterStopped := make(chan struct{})\n\tgo func() {\n\t\trouter.Serve(ctx)\n\t\tclose(routerStopped)\n\t}()\n\n\tpk := packet.ICMP{\n\t\tIP: &packet.IP{\n\t\t\tSrc:      netip.MustParseAddr(\"192.168.1.1\"),\n\t\t\tDst:      netip.MustParseAddr(\"10.0.0.1\"),\n\t\t\tProtocol: layers.IPProtocolICMPv4,\n\t\t\tTTL:      1,\n\t\t},\n\t\tMessage: &icmp.Message{\n\t\t\tType: ipv4.ICMPTypeEcho,\n\t\t\tCode: 0,\n\t\t\tBody: &icmp.Echo{\n\t\t\t\tID:   12481,\n\t\t\t\tSeq:  8036,\n\t\t\t\tData: []byte(\"TTL exceed\"),\n\t\t\t},\n\t\t},\n\t}\n\tassertTTLExceed(t, &pk, defaultRouter.ipv4Src, muxer)\n\tpk = packet.ICMP{\n\t\tIP: &packet.IP{\n\t\t\tSrc:      netip.MustParseAddr(\"fd51:2391:523:f4ee::1\"),\n\t\t\tDst:      netip.MustParseAddr(\"fd51:2391:697:f4ee::2\"),\n\t\t\tProtocol: layers.IPProtocolICMPv6,\n\t\t\tTTL:      1,\n\t\t},\n\t\tMessage: &icmp.Message{\n\t\t\tType: ipv6.ICMPTypeEchoRequest,\n\t\t\tCode: 0,\n\t\t\tBody: &icmp.Echo{\n\t\t\t\tID:   42583,\n\t\t\t\tSeq:  7039,\n\t\t\t\tData: []byte(\"TTL exceed\"),\n\t\t\t},\n\t\t},\n\t}\n\tassertTTLExceed(t, &pk, defaultRouter.ipv6Src, muxer)\n\n\tcancel()\n\t<-routerStopped\n}\n\nfunc assertTTLExceed(t *testing.T, originalPacket *packet.ICMP, expectedSrc netip.Addr, muxer *mockMuxer) {\n\tencoder := packet.NewEncoder()\n\trawPacket, err := encoder.Encode(originalPacket)\n\trequire.NoError(t, err)\n\tmuxer.edgeToCfd <- quicpogs.RawPacket(rawPacket)\n\n\tresp := <-muxer.cfdToEdge\n\tdecoder := packet.NewICMPDecoder()\n\tdecoded, err := decoder.Decode(packet.RawPacket(resp.(quicpogs.RawPacket)))\n\trequire.NoError(t, err)\n\n\trequire.Equal(t, expectedSrc, decoded.Src)\n\trequire.Equal(t, originalPacket.Src, decoded.Dst)\n\trequire.Equal(t, originalPacket.Protocol, decoded.Protocol)\n\trequire.Equal(t, packet.DefaultTTL, decoded.TTL)\n\tif originalPacket.Dst.Is4() {\n\t\trequire.Equal(t, ipv4.ICMPTypeTimeExceeded, decoded.Type)\n\t} else {\n\t\trequire.Equal(t, ipv6.ICMPTypeTimeExceeded, decoded.Type)\n\t}\n\trequire.Equal(t, 0, decoded.Code)\n\ttimeExceed, ok := decoded.Body.(*icmp.TimeExceeded)\n\trequire.True(t, ok)\n\trequire.True(t, bytes.Equal(rawPacket.Data, timeExceed.Data))\n}\n\ntype mockMuxer struct {\n\tcfdToEdge chan quicpogs.Packet\n\tedgeToCfd chan quicpogs.Packet\n}\n\nfunc newMockMuxer(capacity int) *mockMuxer {\n\treturn &mockMuxer{\n\t\tcfdToEdge: make(chan quicpogs.Packet, capacity),\n\t\tedgeToCfd: make(chan quicpogs.Packet, capacity),\n\t}\n}\n\n// Copy packet, because icmpProxy expects the encoder buffer to be reusable after the packet is sent\nfunc (mm *mockMuxer) SendPacket(pk quicpogs.Packet) error {\n\tpayload := pk.Payload()\n\tcopiedPayload := make([]byte, len(payload))\n\tcopy(copiedPayload, payload)\n\n\tmetadata := pk.Metadata()\n\tcopiedMetadata := make([]byte, len(metadata))\n\tcopy(copiedMetadata, metadata)\n\n\tvar copiedPacket quicpogs.Packet\n\tswitch pk.Type() {\n\tcase quicpogs.DatagramTypeIP:\n\t\tcopiedPacket = quicpogs.RawPacket(packet.RawPacket{\n\t\t\tData: copiedPayload,\n\t\t})\n\tcase quicpogs.DatagramTypeIPWithTrace:\n\t\tcopiedPacket = &quicpogs.TracedPacket{\n\t\t\tPacket: packet.RawPacket{\n\t\t\t\tData: copiedPayload,\n\t\t\t},\n\t\t\tTracingIdentity: copiedMetadata,\n\t\t}\n\tcase quicpogs.DatagramTypeTracingSpan:\n\t\tcopiedPacket = &quicpogs.TracingSpanPacket{\n\t\t\tSpans:           copiedPayload,\n\t\t\tTracingIdentity: copiedMetadata,\n\t\t}\n\tdefault:\n\t\treturn fmt.Errorf(\"unexpected metadata type %d\", pk.Type())\n\t}\n\tmm.cfdToEdge <- copiedPacket\n\treturn nil\n}\n\nfunc (mm *mockMuxer) ReceivePacket(ctx context.Context) (quicpogs.Packet, error) {\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn nil, ctx.Err()\n\tcase pk := <-mm.edgeToCfd:\n\t\treturn pk, nil\n\t}\n}\n\ntype routerEnabledChecker struct {\n\tenabled uint32\n}\n\nfunc (rec *routerEnabledChecker) isEnabled() bool {\n\tif atomic.LoadUint32(&rec.enabled) == 0 {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (rec *routerEnabledChecker) set(enabled bool) {\n\tif enabled {\n\t\tatomic.StoreUint32(&rec.enabled, 1)\n\t} else {\n\t\tatomic.StoreUint32(&rec.enabled, 0)\n\t}\n}\n"
  },
  {
    "path": "ingress/rule.go",
    "content": "package ingress\n\nimport (\n\t\"encoding/json\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/cloudflare/cloudflared/ingress/middleware\"\n)\n\n// Rule routes traffic from a hostname/path on the public internet to the\n// service running on the given URL.\ntype Rule struct {\n\t// Requests for this hostname will be proxied to this rule's service.\n\tHostname string `json:\"hostname\"`\n\n\t// punycodeHostname is an additional optional hostname converted to punycode.\n\tpunycodeHostname string\n\n\t// Path is an optional regex that can specify path-driven ingress rules.\n\tPath *Regexp `json:\"path\"`\n\n\t// A (probably local) address. Requests for a hostname which matches this\n\t// rule's hostname pattern will be proxied to the service running on this\n\t// address.\n\tService OriginService `json:\"service\"`\n\n\t// Handlers is a list of functions that acts as a middleware during ProxyHTTP\n\tHandlers []middleware.Handler\n\n\t// Configure the request cloudflared sends to this specific origin.\n\tConfig OriginRequestConfig `json:\"originRequest\"`\n}\n\n// MultiLineString is for outputting rules in a human-friendly way when Cloudflared\n// is used as a CLI tool (not as a daemon).\nfunc (r Rule) MultiLineString() string {\n\tvar out strings.Builder\n\tif r.Hostname != \"\" {\n\t\tout.WriteString(\"\\thostname: \")\n\t\tout.WriteString(r.Hostname)\n\t\tout.WriteRune('\\n')\n\t}\n\tif r.Path != nil && r.Path.Regexp != nil {\n\t\tout.WriteString(\"\\tpath: \")\n\t\tout.WriteString(r.Path.Regexp.String())\n\t\tout.WriteRune('\\n')\n\t}\n\tout.WriteString(\"\\tservice: \")\n\tout.WriteString(r.Service.String())\n\treturn out.String()\n}\n\n// Matches checks if the rule matches a given hostname/path combination.\nfunc (r *Rule) Matches(hostname, path string) bool {\n\thostMatch := false\n\tif r.Hostname == \"\" || r.Hostname == \"*\" {\n\t\thostMatch = true\n\t} else {\n\t\thostMatch = matchHost(r.Hostname, hostname)\n\t}\n\tpunycodeHostMatch := false\n\tif r.punycodeHostname != \"\" {\n\t\tpunycodeHostMatch = matchHost(r.punycodeHostname, hostname)\n\t}\n\tpathMatch := r.Path == nil || r.Path.Regexp == nil || r.Path.Regexp.MatchString(path)\n\treturn (hostMatch || punycodeHostMatch) && pathMatch\n}\n\n// Regexp adds unmarshalling from json for regexp.Regexp\ntype Regexp struct {\n\t*regexp.Regexp\n}\n\nfunc (r *Regexp) MarshalJSON() ([]byte, error) {\n\tif r.Regexp == nil {\n\t\treturn json.Marshal(nil)\n\t}\n\treturn json.Marshal(r.Regexp.String())\n}\n"
  },
  {
    "path": "ingress/rule_test.go",
    "content": "package ingress\n\nimport (\n\t\"encoding/json\"\n\t\"io\"\n\t\"net/http/httptest\"\n\t\"net/url\"\n\t\"regexp\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n)\n\nfunc Test_rule_matches(t *testing.T) {\n\ttype args struct {\n\t\trequestURL *url.URL\n\t}\n\ttests := []struct {\n\t\tname string\n\t\trule Rule\n\t\targs args\n\t\twant bool\n\t}{\n\t\t{\n\t\t\tname: \"Just hostname, pass\",\n\t\t\trule: Rule{\n\t\t\t\tHostname: \"example.com\",\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\trequestURL: MustParseURL(t, \"https://example.com\"),\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Unicode hostname with unicode request, pass\",\n\t\t\trule: Rule{\n\t\t\t\tHostname:         \"môô.cloudflare.com\",\n\t\t\t\tpunycodeHostname: \"xn--m-xgaa.cloudflare.com\",\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\trequestURL: MustParseURL(t, \"https://môô.cloudflare.com\"),\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Unicode hostname with punycode request, pass\",\n\t\t\trule: Rule{\n\t\t\t\tHostname:         \"môô.cloudflare.com\",\n\t\t\t\tpunycodeHostname: \"xn--m-xgaa.cloudflare.com\",\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\trequestURL: MustParseURL(t, \"https://xn--m-xgaa.cloudflare.com\"),\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Entire hostname is wildcard, should match everything\",\n\t\t\trule: Rule{\n\t\t\t\tHostname: \"*\",\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\trequestURL: MustParseURL(t, \"https://example.com\"),\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Just hostname, fail\",\n\t\t\trule: Rule{\n\t\t\t\tHostname: \"example.com\",\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\trequestURL: MustParseURL(t, \"https://foo.bar\"),\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname: \"Just wildcard hostname, pass\",\n\t\t\trule: Rule{\n\t\t\t\tHostname: \"*.example.com\",\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\trequestURL: MustParseURL(t, \"https://adam.example.com\"),\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Just wildcard hostname, fail\",\n\t\t\trule: Rule{\n\t\t\t\tHostname: \"*.example.com\",\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\trequestURL: MustParseURL(t, \"https://tunnel.com\"),\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname: \"Just wildcard outside of subdomain in hostname, fail\",\n\t\t\trule: Rule{\n\t\t\t\tHostname: \"*example.com\",\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\trequestURL: MustParseURL(t, \"https://www.example.com\"),\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname: \"Wildcard over multiple subdomains\",\n\t\t\trule: Rule{\n\t\t\t\tHostname: \"*.example.com\",\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\trequestURL: MustParseURL(t, \"https://adam.chalmers.example.com\"),\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Hostname and path\",\n\t\t\trule: Rule{\n\t\t\t\tHostname: \"*.example.com\",\n\t\t\t\tPath:     &Regexp{Regexp: regexp.MustCompile(\"/static/.*\\\\.html\")},\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\trequestURL: MustParseURL(t, \"https://www.example.com/static/index.html\"),\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Hostname and empty Regex\",\n\t\t\trule: Rule{\n\t\t\t\tHostname: \"example.com\",\n\t\t\t\tPath:     &Regexp{},\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\trequestURL: MustParseURL(t, \"https://example.com/\"),\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Hostname and nil path\",\n\t\t\trule: Rule{\n\t\t\t\tHostname: \"example.com\",\n\t\t\t\tPath:     nil,\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\trequestURL: MustParseURL(t, \"https://example.com/\"),\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Hostname with wildcard should not match if no dot present\",\n\t\t\trule: Rule{\n\t\t\t\tHostname: \"*.api.abc.cloud\",\n\t\t\t},\n\t\t\targs: args{\n\t\t\t\trequestURL: MustParseURL(t, \"https://testing-api.abc.cloud\"),\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tu := tt.args.requestURL\n\t\t\tif got := tt.rule.Matches(u.Hostname(), u.Path); got != tt.want {\n\t\t\t\tt.Errorf(\"rule.matches() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestStaticHTTPStatus(t *testing.T) {\n\to := newStatusCode(404)\n\tbuf := make([]byte, 100)\n\n\tsendReq := func() {\n\t\tresp, err := o.RoundTrip(nil)\n\t\trequire.NoError(t, err)\n\t\t_, err = resp.Body.Read(buf)\n\t\trequire.Equal(t, io.EOF, err)\n\t\trequire.NoError(t, resp.Body.Close())\n\t\trequire.Equal(t, 404, resp.StatusCode)\n\n\t\tresp, err = o.RoundTrip(nil)\n\t\trequire.NoError(t, err)\n\t\tw := httptest.NewRecorder()\n\t\tn, err := io.Copy(w, resp.Body)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, int64(0), n)\n\t}\n\tsendReq()\n\tsendReq()\n}\n\nfunc TestMarshalJSON(t *testing.T) {\n\tlocalhost8000 := MustParseURL(t, \"https://localhost:8000\")\n\tdefaultConfig := setConfig(originRequestFromConfig(config.OriginRequestConfig{}), config.OriginRequestConfig{})\n\ttests := []struct {\n\t\tname     string\n\t\tpath     *Regexp\n\t\texpected string\n\t\twant     bool\n\t}{\n\t\t{\n\t\t\tname:     \"Nil\",\n\t\t\tpath:     nil,\n\t\t\texpected: `{\"hostname\":\"example.com\",\"path\":null,\"service\":\"https://localhost:8000\",\"Handlers\":null,\"originRequest\":{\"connectTimeout\":30,\"tlsTimeout\":10,\"tcpKeepAlive\":30,\"noHappyEyeballs\":false,\"keepAliveTimeout\":90,\"keepAliveConnections\":100,\"httpHostHeader\":\"\",\"originServerName\":\"\",\"matchSNItoHost\":false,\"caPool\":\"\",\"noTLSVerify\":false,\"disableChunkedEncoding\":false,\"bastionMode\":false,\"proxyAddress\":\"127.0.0.1\",\"proxyPort\":0,\"proxyType\":\"\",\"ipRules\":null,\"http2Origin\":false,\"access\":{\"teamName\":\"\",\"audTag\":null}}}`,\n\t\t\twant:     true,\n\t\t},\n\t\t{\n\t\t\tname:     \"Nil regex\",\n\t\t\tpath:     &Regexp{Regexp: nil},\n\t\t\texpected: `{\"hostname\":\"example.com\",\"path\":null,\"service\":\"https://localhost:8000\",\"Handlers\":null,\"originRequest\":{\"connectTimeout\":30,\"tlsTimeout\":10,\"tcpKeepAlive\":30,\"noHappyEyeballs\":false,\"keepAliveTimeout\":90,\"keepAliveConnections\":100,\"httpHostHeader\":\"\",\"originServerName\":\"\",\"matchSNItoHost\":false,\"caPool\":\"\",\"noTLSVerify\":false,\"disableChunkedEncoding\":false,\"bastionMode\":false,\"proxyAddress\":\"127.0.0.1\",\"proxyPort\":0,\"proxyType\":\"\",\"ipRules\":null,\"http2Origin\":false,\"access\":{\"teamName\":\"\",\"audTag\":null}}}`,\n\t\t\twant:     true,\n\t\t},\n\t\t{\n\t\t\tname:     \"Empty\",\n\t\t\tpath:     &Regexp{Regexp: regexp.MustCompile(\"\")},\n\t\t\texpected: `{\"hostname\":\"example.com\",\"path\":\"\",\"service\":\"https://localhost:8000\",\"Handlers\":null,\"originRequest\":{\"connectTimeout\":30,\"tlsTimeout\":10,\"tcpKeepAlive\":30,\"noHappyEyeballs\":false,\"keepAliveTimeout\":90,\"keepAliveConnections\":100,\"httpHostHeader\":\"\",\"originServerName\":\"\",\"matchSNItoHost\":false,\"caPool\":\"\",\"noTLSVerify\":false,\"disableChunkedEncoding\":false,\"bastionMode\":false,\"proxyAddress\":\"127.0.0.1\",\"proxyPort\":0,\"proxyType\":\"\",\"ipRules\":null,\"http2Origin\":false,\"access\":{\"teamName\":\"\",\"audTag\":null}}}`,\n\t\t\twant:     true,\n\t\t},\n\t\t{\n\t\t\tname:     \"Basic\",\n\t\t\tpath:     &Regexp{Regexp: regexp.MustCompile(\"/echo\")},\n\t\t\texpected: `{\"hostname\":\"example.com\",\"path\":\"/echo\",\"service\":\"https://localhost:8000\",\"Handlers\":null,\"originRequest\":{\"connectTimeout\":30,\"tlsTimeout\":10,\"tcpKeepAlive\":30,\"noHappyEyeballs\":false,\"keepAliveTimeout\":90,\"keepAliveConnections\":100,\"httpHostHeader\":\"\",\"originServerName\":\"\",\"matchSNItoHost\":false,\"caPool\":\"\",\"noTLSVerify\":false,\"disableChunkedEncoding\":false,\"bastionMode\":false,\"proxyAddress\":\"127.0.0.1\",\"proxyPort\":0,\"proxyType\":\"\",\"ipRules\":null,\"http2Origin\":false,\"access\":{\"teamName\":\"\",\"audTag\":null}}}`,\n\t\t\twant:     true,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tr := Rule{\n\t\t\t\tHostname: \"example.com\",\n\t\t\t\tService:  &httpService{url: localhost8000},\n\t\t\t\tPath:     tt.path,\n\t\t\t\tConfig:   defaultConfig,\n\t\t\t}\n\t\t\tbytes, err := json.Marshal(r)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.expected, string(bytes))\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/test/wstest.go",
    "content": "package test\n\n// copied from https://github.com/nhooyr/websocket/blob/master/internal/test/wstest/pipe.go\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\n\t\"nhooyr.io/websocket\"\n)\n\n// Pipe is used to create an in memory connection\n// between two websockets analogous to net.Pipe.\nfunc WSPipe(dialOpts *websocket.DialOptions, acceptOpts *websocket.AcceptOptions) (clientConn, serverConn *websocket.Conn) {\n\ttt := fakeTransport{\n\t\th: func(w http.ResponseWriter, r *http.Request) {\n\t\t\tserverConn, _ = websocket.Accept(w, r, acceptOpts)\n\t\t},\n\t}\n\n\tif dialOpts == nil {\n\t\tdialOpts = &websocket.DialOptions{}\n\t}\n\tdialOpts = &*dialOpts\n\tdialOpts.HTTPClient = &http.Client{\n\t\tTransport: tt,\n\t}\n\n\tclientConn, _, _ = websocket.Dial(context.Background(), \"ws://example.com\", dialOpts)\n\treturn clientConn, serverConn\n}\n\ntype fakeTransport struct {\n\th http.HandlerFunc\n}\n\nfunc (t fakeTransport) RoundTrip(r *http.Request) (*http.Response, error) {\n\tclientConn, serverConn := net.Pipe()\n\n\thj := testHijacker{\n\t\tResponseRecorder: httptest.NewRecorder(),\n\t\tserverConn:       serverConn,\n\t}\n\n\tt.h.ServeHTTP(hj, r)\n\n\tresp := hj.ResponseRecorder.Result()\n\tif resp.StatusCode == http.StatusSwitchingProtocols {\n\t\tresp.Body = clientConn\n\t}\n\treturn resp, nil\n}\n\ntype testHijacker struct {\n\t*httptest.ResponseRecorder\n\tserverConn net.Conn\n}\n\nvar _ http.Hijacker = testHijacker{}\n\nfunc (hj testHijacker) Hijack() (net.Conn, *bufio.ReadWriter, error) {\n\treturn hj.serverConn, bufio.NewReadWriter(bufio.NewReader(hj.serverConn), bufio.NewWriter(hj.serverConn)), nil\n}\n"
  },
  {
    "path": "ipaccess/access.go",
    "content": "package ipaccess\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"sort\"\n)\n\ntype Policy struct {\n\tdefaultAllow bool\n\trules        []Rule\n}\n\ntype Rule struct {\n\tipNet *net.IPNet\n\tports []int\n\tallow bool\n}\n\nfunc NewPolicy(defaultAllow bool, rules []Rule) (*Policy, error) {\n\tfor _, rule := range rules {\n\t\tif err := rule.Validate(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tpolicy := Policy{\n\t\tdefaultAllow: defaultAllow,\n\t\trules:        rules,\n\t}\n\n\treturn &policy, nil\n}\n\nfunc NewRuleByCIDR(prefix *string, ports []int, allow bool) (Rule, error) {\n\tif prefix == nil || len(*prefix) == 0 {\n\t\treturn Rule{}, fmt.Errorf(\"no prefix provided\")\n\t}\n\n\t_, ipnet, err := net.ParseCIDR(*prefix)\n\tif err != nil {\n\t\treturn Rule{}, fmt.Errorf(\"unable to parse cidr: %s\", *prefix)\n\t}\n\n\treturn NewRule(ipnet, ports, allow)\n}\n\nfunc NewRule(ipnet *net.IPNet, ports []int, allow bool) (Rule, error) {\n\trule := Rule{\n\t\tipNet: ipnet,\n\t\tports: ports,\n\t\tallow: allow,\n\t}\n\treturn rule, rule.Validate()\n}\n\nfunc (r *Rule) Validate() error {\n\tif r.ipNet == nil {\n\t\treturn fmt.Errorf(\"no ipnet set on the rule\")\n\t}\n\n\tif len(r.ports) > 0 {\n\t\tsort.Ints(r.ports)\n\t\tfor _, port := range r.ports {\n\t\t\tif port < 1 || port > 65535 {\n\t\t\t\treturn fmt.Errorf(\"invalid port %d, needs to be between 1 and 65535\", port)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (h *Policy) Allowed(ip net.IP, port int) (bool, *Rule) {\n\tif len(h.rules) == 0 {\n\t\treturn h.defaultAllow, nil\n\t}\n\n\tfor _, rule := range h.rules {\n\t\tif rule.ipNet.Contains(ip) {\n\t\t\tif len(rule.ports) == 0 {\n\t\t\t\treturn rule.allow, &rule\n\t\t\t} else if pos := sort.SearchInts(rule.ports, port); pos < len(rule.ports) && rule.ports[pos] == port {\n\t\t\t\treturn rule.allow, &rule\n\t\t\t}\n\t\t}\n\t}\n\n\treturn h.defaultAllow, nil\n}\n\nfunc (ipr *Rule) String() string {\n\treturn fmt.Sprintf(\"prefix:%s/port:%s/allow:%t\", ipr.ipNet, ipr.PortsString(), ipr.allow)\n}\n\nfunc (ipr *Rule) PortsString() string {\n\tif len(ipr.ports) > 0 {\n\t\treturn fmt.Sprint(ipr.ports)\n\t}\n\treturn \"all\"\n}\n\nfunc (ipr *Rule) Ports() []int {\n\treturn ipr.ports\n}\n\nfunc (ipr *Rule) RulePolicy() bool {\n\treturn ipr.allow\n}\n\nfunc (ipr *Rule) StringCIDR() string {\n\treturn ipr.ipNet.String()\n}\n"
  },
  {
    "path": "ipaccess/access_test.go",
    "content": "package ipaccess\n\nimport (\n\t\"bytes\"\n\t\"net\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestRuleCreation(t *testing.T) {\n\t_, ipnet, _ := net.ParseCIDR(\"1.1.1.1/24\")\n\n\t_, err := NewRule(nil, []int{80}, false)\n\tassert.Error(t, err, \"expected error as no ipnet provided\")\n\n\t_, err = NewRule(ipnet, []int{65536, 80}, false)\n\tassert.Error(t, err, \"expected error as port higher than 65535\")\n\n\t_, err = NewRule(ipnet, []int{80, -1}, false)\n\tassert.Error(t, err, \"expected error as port less than 0\")\n\n\trule, err := NewRule(ipnet, []int{443, 80}, false)\n\tassert.NoError(t, err)\n\tassert.True(t, ipnet.IP.Equal(rule.ipNet.IP) && bytes.Compare(ipnet.Mask, rule.ipNet.Mask) == 0, \"ipnet expected to be %+v, got: %+v\", ipnet, rule.ipNet)\n\tassert.True(t, len(rule.ports) == 2 && rule.ports[0] == 80 && rule.ports[1] == 443, \"expected ports to be sorted\")\n}\n\nfunc TestRuleCreationByCIDR(t *testing.T) {\n\tvar cidr *string\n\t_, err := NewRuleByCIDR(cidr, []int{80}, false)\n\tassert.Error(t, err, \"expected error as cidr is nil\")\n\n\tbadCidr := \"1.1.1.1\"\n\tcidr = &badCidr\n\t_, err = NewRuleByCIDR(cidr, []int{80}, false)\n\tassert.Error(t, err, \"expected error as the cidr is bad\")\n\n\tgoodCidr := \"1.1.1.1/24\"\n\t_, ipnet, _ := net.ParseCIDR(\"1.1.1.0/24\")\n\tcidr = &goodCidr\n\trule, err := NewRuleByCIDR(cidr, []int{80}, false)\n\tassert.NoError(t, err)\n\tassert.True(t, ipnet.IP.Equal(rule.ipNet.IP) && bytes.Compare(ipnet.Mask, rule.ipNet.Mask) == 0, \"ipnet expected to be %+v, got: %+v\", ipnet, rule.ipNet)\n}\n\nfunc TestRulesNoRules(t *testing.T) {\n\tip, _, _ := net.ParseCIDR(\"1.2.3.4/24\")\n\n\tpolicy, _ := NewPolicy(true, []Rule{})\n\n\tallowed, rule := policy.Allowed(ip, 80)\n\tassert.True(t, allowed, \"expected to be allowed as no rules and default allow\")\n\tassert.Nil(t, rule, \"expected to be nil as no rules\")\n\n\tpolicy, _ = NewPolicy(false, []Rule{})\n\n\tallowed, rule = policy.Allowed(ip, 80)\n\tassert.False(t, allowed, \"expected to be denied as no rules and default deny\")\n\tassert.Nil(t, rule, \"expected to be nil as no rules\")\n}\n\nfunc TestRulesMatchIPAndPort(t *testing.T) {\n\tip1, ipnet1, _ := net.ParseCIDR(\"1.2.3.4/24\")\n\tip2, _, _ := net.ParseCIDR(\"2.3.4.5/24\")\n\n\trule1, _ := NewRule(ipnet1, []int{80, 443}, true)\n\trules := []Rule{\n\t\trule1,\n\t}\n\n\tpolicy, _ := NewPolicy(false, rules)\n\n\tallowed, rule := policy.Allowed(ip1, 80)\n\tassert.True(t, allowed, \"expected to be allowed as matching rule\")\n\tassert.True(t, rule.ipNet == ipnet1, \"expected to match ipnet1\")\n\n\tallowed, rule = policy.Allowed(ip2, 80)\n\tassert.False(t, allowed, \"expected to be denied as no matching rule\")\n\tassert.Nil(t, rule, \"expected to be nil\")\n}\n\nfunc TestRulesMatchIPAndPort2(t *testing.T) {\n\tip1, ipnet1, _ := net.ParseCIDR(\"1.2.3.4/24\")\n\tip2, ipnet2, _ := net.ParseCIDR(\"2.3.4.5/24\")\n\n\trule1, _ := NewRule(ipnet1, []int{53, 80}, false)\n\trule2, _ := NewRule(ipnet2, []int{53, 80}, true)\n\trules := []Rule{\n\t\trule1,\n\t\trule2,\n\t}\n\n\tpolicy, _ := NewPolicy(false, rules)\n\n\tallowed, rule := policy.Allowed(ip1, 80)\n\tassert.False(t, allowed, \"expected to be denied as matching rule\")\n\tassert.True(t, rule.ipNet == ipnet1, \"expected to match ipnet1\")\n\n\tallowed, rule = policy.Allowed(ip2, 80)\n\tassert.True(t, allowed, \"expected to be allowed as matching rule\")\n\tassert.True(t, rule.ipNet == ipnet2, \"expected to match ipnet1\")\n\n\tallowed, rule = policy.Allowed(ip2, 81)\n\tassert.False(t, allowed, \"expected to be denied as no matching rule\")\n\tassert.Nil(t, rule, \"expected to be nil\")\n}\n"
  },
  {
    "path": "logger/configuration.go",
    "content": "package logger\n\nimport (\n\t\"path/filepath\"\n)\n\nvar defaultConfig = createDefaultConfig()\n\n// Logging configuration\ntype Config struct {\n\tConsoleConfig *ConsoleConfig // If nil, the logger will not log into the console\n\tFileConfig    *FileConfig    // If nil, the logger will not use an individual log file\n\tRollingConfig *RollingConfig // If nil, the logger will not use a rolling log\n\n\tMinLevel string // debug | info | error | fatal\n}\n\ntype ConsoleConfig struct {\n\tnoColor bool\n\tasJSON  bool\n}\n\ntype FileConfig struct {\n\tDirname  string\n\tFilename string\n}\n\nfunc (fc *FileConfig) Fullpath() string {\n\treturn filepath.Join(fc.Dirname, fc.Filename)\n}\n\ntype RollingConfig struct {\n\tDirname  string\n\tFilename string\n\n\tmaxSize    int // megabytes\n\tmaxBackups int // files\n\tmaxAge     int // days\n}\n\nfunc createDefaultConfig() Config {\n\tconst minLevel = \"info\"\n\n\tconst RollingMaxSize = 1    // Mb\n\tconst RollingMaxBackups = 5 // files\n\tconst RollingMaxAge = 0     // Keep forever\n\tconst defaultLogFilename = \"cloudflared.log\"\n\n\treturn Config{\n\t\tConsoleConfig: &ConsoleConfig{\n\t\t\tnoColor: false,\n\t\t\tasJSON:  false,\n\t\t},\n\t\tFileConfig: &FileConfig{\n\t\t\tDirname:  \"\",\n\t\t\tFilename: defaultLogFilename,\n\t\t},\n\t\tRollingConfig: &RollingConfig{\n\t\t\tDirname:    \"\",\n\t\t\tFilename:   defaultLogFilename,\n\t\t\tmaxSize:    RollingMaxSize,\n\t\t\tmaxBackups: RollingMaxBackups,\n\t\t\tmaxAge:     RollingMaxAge,\n\t\t},\n\t\tMinLevel: minLevel,\n\t}\n}\n\nfunc CreateConfig(\n\tminLevel string,\n\tdisableTerminal bool,\n\tformatJSON bool,\n\trollingLogPath, nonRollingLogFilePath string,\n) *Config {\n\tvar console *ConsoleConfig\n\tif !disableTerminal {\n\t\tconsole = createConsoleConfig(formatJSON)\n\t}\n\n\tvar file *FileConfig\n\tvar rolling *RollingConfig\n\tif nonRollingLogFilePath != \"\" {\n\t\tfile = createFileConfig(nonRollingLogFilePath)\n\t} else if rollingLogPath != \"\" {\n\t\trolling = createRollingConfig(rollingLogPath)\n\t}\n\n\tif minLevel == \"\" {\n\t\tminLevel = defaultConfig.MinLevel\n\t}\n\n\treturn &Config{\n\t\tConsoleConfig: console,\n\t\tFileConfig:    file,\n\t\tRollingConfig: rolling,\n\n\t\tMinLevel: minLevel,\n\t}\n}\n\nfunc createConsoleConfig(formatJSON bool) *ConsoleConfig {\n\treturn &ConsoleConfig{\n\t\tnoColor: false,\n\t\tasJSON:  formatJSON,\n\t}\n}\n\nfunc createFileConfig(fullpath string) *FileConfig {\n\tif fullpath == \"\" {\n\t\treturn defaultConfig.FileConfig\n\t}\n\n\tdirname, filename := filepath.Split(fullpath)\n\n\treturn &FileConfig{\n\t\tDirname:  dirname,\n\t\tFilename: filename,\n\t}\n}\n\nfunc createRollingConfig(directory string) *RollingConfig {\n\tif directory == \"\" {\n\t\tdirectory = defaultConfig.RollingConfig.Dirname\n\t}\n\n\treturn &RollingConfig{\n\t\tDirname:    directory,\n\t\tFilename:   defaultConfig.RollingConfig.Filename,\n\t\tmaxSize:    defaultConfig.RollingConfig.maxSize,\n\t\tmaxBackups: defaultConfig.RollingConfig.maxBackups,\n\t\tmaxAge:     defaultConfig.RollingConfig.maxAge,\n\t}\n}\n"
  },
  {
    "path": "logger/console.go",
    "content": "package logger\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\n\tjsoniter \"github.com/json-iterator/go\"\n)\n\nvar json = jsoniter.ConfigCompatibleWithStandardLibrary\n\n// consoleWriter allows us the simplicity to prevent duplicate json keys in the logger events reported.\n//\n// By default zerolog constructs the json event in parts by appending each additional key after the first. It\n// doesn't have any internal state or struct of the json message representation so duplicate keys can be\n// inserted without notice and no pruning will occur before writing the log event out to the io.Writer.\n//\n// To help prevent these duplicate keys, we will decode the json log event and then immediately re-encode it\n// again as writing it to the output io.Writer. Since we encode it to a map[string]any, duplicate keys\n// are pruned. We pay the cost of decoding and encoding the log event for each time, but helps prevent\n// us from needing to worry about adding duplicate keys in the log event from different areas of code.\ntype consoleWriter struct {\n\tout io.Writer\n}\n\nfunc (c *consoleWriter) Write(p []byte) (n int, err error) {\n\tvar evt map[string]any\n\td := json.NewDecoder(bytes.NewReader(p))\n\td.UseNumber()\n\terr = d.Decode(&evt)\n\tif err != nil {\n\t\treturn n, fmt.Errorf(\"cannot decode event: %s\", err)\n\t}\n\te := json.NewEncoder(c.out)\n\treturn len(p), e.Encode(evt)\n}\n"
  },
  {
    "path": "logger/console_test.go",
    "content": "package logger\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/rs/zerolog\"\n)\n\nfunc TestConsoleLoggerDuplicateKeys(t *testing.T) {\n\tr := bytes.NewBuffer(make([]byte, 500))\n\tlogger := zerolog.New(&consoleWriter{out: r}).With().Timestamp().Logger()\n\tlogger.Debug().Str(\"test\", \"1234\").Int(\"number\", 45).Str(\"test\", \"5678\").Msg(\"log message\")\n\n\tevent, err := r.ReadString('\\n')\n\tif err != nil {\n\t\tt.Error(err)\n\t}\n\n\tif !strings.Contains(event, \"\\\"test\\\":\\\"5678\\\"\") {\n\t\tt.Errorf(\"log event missing key 'test': %s\", event)\n\t}\n\tif !strings.Contains(event, \"\\\"number\\\":45\") {\n\t\tt.Errorf(\"log event missing key 'number': %s\", event)\n\t}\n\tif !strings.Contains(event, \"\\\"time\\\":\") {\n\t\tt.Errorf(\"log event missing key 'time': %s\", event)\n\t}\n\tif !strings.Contains(event, \"\\\"level\\\":\\\"debug\\\"\") {\n\t\tt.Errorf(\"log event missing key 'level': %s\", event)\n\t}\n}\n"
  },
  {
    "path": "logger/create.go",
    "content": "package logger\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/mattn/go-colorable\"\n\t\"github.com/rs/zerolog\"\n\tfallbacklog \"github.com/rs/zerolog/log\"\n\t\"github.com/urfave/cli/v2\"\n\t\"golang.org/x/term\"\n\t\"gopkg.in/natefinch/lumberjack.v2\"\n\n\tcfdflags \"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n\t\"github.com/cloudflare/cloudflared/management\"\n)\n\nconst (\n\tEnableTerminalLog  = false\n\tDisableTerminalLog = true\n\n\tdirPermMode  = 0744 // rwxr--r--\n\tfilePermMode = 0644 // rw-r--r--\n\n\tconsoleTimeFormat = time.RFC3339\n)\n\nvar (\n\tManagementLogger *management.Logger\n)\n\nfunc init() {\n\tzerolog.TimeFieldFormat = time.RFC3339\n\tzerolog.TimestampFunc = utcNow\n\n\tManagementLogger = management.NewLogger()\n}\n\nfunc utcNow() time.Time {\n\treturn time.Now().UTC()\n}\n\nfunc fallbackLogger(err error) *zerolog.Logger {\n\tfailLog := fallbacklog.With().Logger()\n\tfallbacklog.Error().Msgf(\"Falling back to a default logger due to logger setup failure: %s\", err)\n\n\treturn &failLog\n}\n\n// resilientMultiWriter is an alternative to zerolog's so that we can make it resilient to individual\n// writer's errors. E.g., when running as a Windows service, the console writer fails, but we don't want to\n// allow that to prevent all logging to fail due to breaking the for loop upon an error.\ntype resilientMultiWriter struct {\n\tlevel            zerolog.Level\n\twriters          []io.Writer\n\tmanagementWriter zerolog.LevelWriter\n}\n\nfunc (t resilientMultiWriter) Write(p []byte) (n int, err error) {\n\tfor _, w := range t.writers {\n\t\t_, _ = w.Write(p)\n\t}\n\tif t.managementWriter != nil {\n\t\t_, _ = t.managementWriter.Write(p)\n\t}\n\treturn len(p), nil\n}\n\nfunc (t resilientMultiWriter) WriteLevel(level zerolog.Level, p []byte) (n int, err error) {\n\t// Only write the event to normal writers if it exceeds the level, but always write to the\n\t// management logger and let it decided with the provided level of the log event.\n\tif t.level <= level {\n\t\tfor _, w := range t.writers {\n\t\t\t_, _ = w.Write(p)\n\t\t}\n\t}\n\tif t.managementWriter != nil {\n\t\t_, _ = t.managementWriter.WriteLevel(level, p)\n\t}\n\treturn len(p), nil\n}\n\nvar levelErrorLogged = false\n\nfunc newZerolog(loggerConfig *Config) *zerolog.Logger {\n\tvar writers []io.Writer\n\n\tif loggerConfig.ConsoleConfig != nil {\n\t\twriters = append(writers, createConsoleLogger(*loggerConfig.ConsoleConfig))\n\t}\n\n\tif loggerConfig.FileConfig != nil {\n\t\tfileLogger, err := createFileWriter(*loggerConfig.FileConfig)\n\t\tif err != nil {\n\t\t\treturn fallbackLogger(err)\n\t\t}\n\n\t\twriters = append(writers, fileLogger)\n\t}\n\n\tif loggerConfig.RollingConfig != nil {\n\t\trollingLogger, err := createRollingLogger(*loggerConfig.RollingConfig)\n\t\tif err != nil {\n\t\t\treturn fallbackLogger(err)\n\t\t}\n\n\t\twriters = append(writers, rollingLogger)\n\t}\n\n\tmanagementWriter := ManagementLogger\n\n\tlevel, levelErr := zerolog.ParseLevel(loggerConfig.MinLevel)\n\tif levelErr != nil {\n\t\tlevel = zerolog.InfoLevel\n\t}\n\n\tmulti := resilientMultiWriter{level, writers, managementWriter}\n\tlog := zerolog.New(multi).With().Timestamp().Logger()\n\tif !levelErrorLogged && levelErr != nil {\n\t\tlog.Error().Msgf(\"Failed to parse log level %q, using %q instead\", loggerConfig.MinLevel, level)\n\t\tlevelErrorLogged = true\n\t}\n\n\treturn &log\n}\n\nfunc CreateTransportLoggerFromContext(c *cli.Context, disableTerminal bool) *zerolog.Logger {\n\treturn createFromContext(c, cfdflags.TransportLogLevel, cfdflags.LogDirectory, disableTerminal)\n}\n\nfunc CreateLoggerFromContext(c *cli.Context, disableTerminal bool) *zerolog.Logger {\n\treturn createFromContext(c, cfdflags.LogLevel, cfdflags.LogDirectory, disableTerminal)\n}\n\nfunc CreateSSHLoggerFromContext(c *cli.Context, disableTerminal bool) *zerolog.Logger {\n\treturn createFromContext(c, cfdflags.LogLevelSSH, cfdflags.LogDirectory, disableTerminal)\n}\n\nfunc createFromContext(\n\tc *cli.Context,\n\tlogLevelFlagName,\n\tlogDirectoryFlagName string,\n\tdisableTerminal bool,\n) *zerolog.Logger {\n\tlogLevel := c.String(logLevelFlagName)\n\tlogFile := c.String(cfdflags.LogFile)\n\tlogDirectory := c.String(logDirectoryFlagName)\n\tvar logFormatJSON bool\n\tswitch c.String(cfdflags.LogFormatOutput) {\n\tcase cfdflags.LogFormatOutputValueJSON:\n\t\tlogFormatJSON = true\n\tcase cfdflags.LogFormatOutputValueDefault:\n\t\t// \"default\" and unset use the same logger output format\n\t\tfallthrough\n\tdefault:\n\t\tlogFormatJSON = false\n\t}\n\n\tloggerConfig := CreateConfig(\n\t\tlogLevel,\n\t\tdisableTerminal,\n\t\tlogFormatJSON,\n\t\tlogDirectory,\n\t\tlogFile,\n\t)\n\n\tlog := newZerolog(loggerConfig)\n\tif incompatibleFlagsSet := logFile != \"\" && logDirectory != \"\"; incompatibleFlagsSet {\n\t\tlog.Error().Msgf(\"Your config includes values for both %s (%s) and %s (%s), but they are incompatible. %s takes precedence.\", cfdflags.LogFile, logFile, logDirectoryFlagName, logDirectory, cfdflags.LogFile)\n\t}\n\treturn log\n}\n\nfunc Create(loggerConfig *Config) *zerolog.Logger {\n\tif loggerConfig == nil {\n\t\tloggerConfig = &Config{\n\t\t\tdefaultConfig.ConsoleConfig,\n\t\t\tnil,\n\t\t\tnil,\n\t\t\tdefaultConfig.MinLevel,\n\t\t}\n\t}\n\treturn newZerolog(loggerConfig)\n}\n\nfunc createConsoleLogger(config ConsoleConfig) io.Writer {\n\tif config.asJSON {\n\t\treturn &consoleWriter{out: os.Stderr}\n\t}\n\tconsoleOut := os.Stderr\n\treturn zerolog.ConsoleWriter{\n\t\tOut:        colorable.NewColorable(consoleOut),\n\t\tNoColor:    config.noColor || !term.IsTerminal(int(consoleOut.Fd())),\n\t\tTimeFormat: consoleTimeFormat,\n\t}\n}\n\ntype fileInitializer struct {\n\tonce          sync.Once\n\twriter        io.Writer\n\tcreationError error\n}\n\nvar (\n\tsingleFileInit   fileInitializer\n\trotatingFileInit fileInitializer\n)\n\nfunc createFileWriter(config FileConfig) (io.Writer, error) {\n\tsingleFileInit.once.Do(func() {\n\t\tvar logFile io.Writer\n\t\tfullpath := config.Fullpath()\n\n\t\t// Try to open the existing file\n\t\tlogFile, err := os.OpenFile(fullpath, os.O_APPEND|os.O_WRONLY, filePermMode)\n\t\tif err != nil {\n\t\t\t// If the existing file wasn't found, or couldn't be opened, just ignore\n\t\t\t// it and recreate a new one.\n\t\t\tlogFile, err = createDirFile(config)\n\t\t\t// If creating a new logfile fails, then we have no choice but to error out.\n\t\t\tif err != nil {\n\t\t\t\tsingleFileInit.creationError = err\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tsingleFileInit.writer = logFile\n\t})\n\n\treturn singleFileInit.writer, singleFileInit.creationError\n}\n\nfunc createDirFile(config FileConfig) (io.Writer, error) {\n\tif config.Dirname != \"\" {\n\t\terr := os.MkdirAll(config.Dirname, dirPermMode)\n\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to create directories for new logfile: %s\", err)\n\t\t}\n\t}\n\n\tmode := os.FileMode(filePermMode)\n\n\tfullPath := filepath.Join(config.Dirname, config.Filename)\n\tlogFile, err := os.OpenFile(fullPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, mode)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to create a new logfile: %s\", err)\n\t}\n\n\treturn logFile, nil\n}\n\nfunc createRollingLogger(config RollingConfig) (io.Writer, error) {\n\trotatingFileInit.once.Do(func() {\n\t\tif err := os.MkdirAll(config.Dirname, dirPermMode); err != nil {\n\t\t\trotatingFileInit.creationError = err\n\t\t\treturn\n\t\t}\n\n\t\trotatingFileInit.writer = &lumberjack.Logger{\n\t\t\tFilename:   filepath.Join(config.Dirname, config.Filename),\n\t\t\tMaxBackups: config.maxBackups,\n\t\t\tMaxSize:    config.maxSize,\n\t\t\tMaxAge:     config.maxAge,\n\t\t}\n\t})\n\n\treturn rotatingFileInit.writer, rotatingFileInit.creationError\n}\n"
  },
  {
    "path": "logger/create_test.go",
    "content": "package logger\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\ntype mockedWriter struct {\n\twantErr    bool\n\twriteCalls int\n}\n\nfunc (c *mockedWriter) Write(p []byte) (int, error) {\n\tc.writeCalls++\n\n\tif c.wantErr {\n\t\treturn -1, errors.New(\"Expected error\")\n\t}\n\n\treturn len(p), nil\n}\n\n// Tests that a new writer is only used if it actually works.\nfunc TestResilientMultiWriter_Errors(t *testing.T) {\n\ttests := []struct {\n\t\tname    string\n\t\twriters []*mockedWriter\n\t}{\n\t\t{\n\t\t\tname: \"All valid writers\",\n\t\t\twriters: []*mockedWriter{\n\t\t\t\t{\n\t\t\t\t\twantErr: false,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\twantErr: false,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"All invalid writers\",\n\t\t\twriters: []*mockedWriter{\n\t\t\t\t{\n\t\t\t\t\twantErr: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\twantErr: true,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"First invalid writer\",\n\t\t\twriters: []*mockedWriter{\n\t\t\t\t{\n\t\t\t\t\twantErr: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\twantErr: false,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"First valid writer\",\n\t\t\twriters: []*mockedWriter{\n\t\t\t\t{\n\t\t\t\t\twantErr: false,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\twantErr: true,\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\twriters := []io.Writer{}\n\t\t\tfor _, w := range test.writers {\n\t\t\t\twriters = append(writers, w)\n\t\t\t}\n\t\t\tmultiWriter := resilientMultiWriter{zerolog.InfoLevel, writers, nil}\n\n\t\t\tlogger := zerolog.New(multiWriter).With().Timestamp().Logger()\n\t\t\tlogger.Info().Msg(\"Test msg\")\n\n\t\t\tfor _, w := range test.writers {\n\t\t\t\t// Expect each writer to be written to regardless of the previous writers returning an error\n\t\t\t\tassert.Equal(t, 1, w.writeCalls)\n\t\t\t}\n\t\t})\n\t}\n}\n\ntype mockedManagementWriter struct {\n\tWriteCalls int\n}\n\nfunc (c *mockedManagementWriter) Write(p []byte) (int, error) {\n\treturn len(p), nil\n}\n\nfunc (c *mockedManagementWriter) WriteLevel(level zerolog.Level, p []byte) (int, error) {\n\tc.WriteCalls++\n\treturn len(p), nil\n}\n\n// Tests that management writer receives write calls of all levels except Disabled\nfunc TestResilientMultiWriter_Management(t *testing.T) {\n\tfor _, level := range []zerolog.Level{\n\t\tzerolog.DebugLevel,\n\t\tzerolog.InfoLevel,\n\t\tzerolog.WarnLevel,\n\t\tzerolog.ErrorLevel,\n\t\tzerolog.FatalLevel,\n\t\tzerolog.PanicLevel,\n\t} {\n\t\tt.Run(level.String(), func(t *testing.T) {\n\t\t\tmanagementWriter := mockedManagementWriter{}\n\t\t\tmultiWriter := resilientMultiWriter{level, []io.Writer{&mockedWriter{}}, &managementWriter}\n\n\t\t\tlogger := zerolog.New(multiWriter).With().Timestamp().Logger()\n\t\t\tlogger.Info().Msg(\"Test msg\")\n\n\t\t\t// Always write to management\n\t\t\tassert.Equal(t, 1, managementWriter.WriteCalls)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "management/events.go",
    "content": "package management\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\n\tjsoniter \"github.com/json-iterator/go\"\n\t\"github.com/rs/zerolog\"\n\t\"nhooyr.io/websocket\"\n)\n\nvar (\n\terrInvalidMessageType = fmt.Errorf(\"invalid message type was provided\")\n)\n\n// ServerEventType represents the event types that can come from the server\ntype ServerEventType string\n\n// ClientEventType represents the event types that can come from the client\ntype ClientEventType string\n\nconst (\n\tUnknownClientEventType ClientEventType = \"\"\n\tStartStreaming         ClientEventType = \"start_streaming\"\n\tStopStreaming          ClientEventType = \"stop_streaming\"\n\n\tUnknownServerEventType ServerEventType = \"\"\n\tLogs                   ServerEventType = \"logs\"\n)\n\n// ServerEvent is the base struct that informs, based of the Type field, which Event type was provided from the server.\ntype ServerEvent struct {\n\tType ServerEventType `json:\"type,omitempty\"`\n\t// The raw json message is provided to allow better deserialization once the type is known\n\tevent jsoniter.RawMessage\n}\n\n// ClientEvent is the base struct that informs, based of the Type field, which Event type was provided from the client.\ntype ClientEvent struct {\n\tType ClientEventType `json:\"type,omitempty\"`\n\t// The raw json message is provided to allow better deserialization once the type is known\n\tevent jsoniter.RawMessage\n}\n\n// EventStartStreaming signifies that the client wishes to start receiving log events.\n// Additional filters can be provided to augment the log events requested.\ntype EventStartStreaming struct {\n\tClientEvent\n\tFilters *StreamingFilters `json:\"filters,omitempty\"`\n}\n\ntype StreamingFilters struct {\n\tEvents   []LogEventType `json:\"events,omitempty\"`\n\tLevel    *LogLevel      `json:\"level,omitempty\"`\n\tSampling float64        `json:\"sampling,omitempty\"`\n}\n\n// EventStopStreaming signifies that the client wishes to halt receiving log events.\ntype EventStopStreaming struct {\n\tClientEvent\n}\n\n// EventLog is the event that the server sends to the client with the log events.\ntype EventLog struct {\n\tServerEvent\n\tLogs []*Log `json:\"logs\"`\n}\n\n// LogEventType is the way that logging messages are able to be filtered.\n// Example: assigning LogEventType.Cloudflared to a zerolog event will allow the client to filter for only\n// the Cloudflared-related events.\ntype LogEventType int8\n\nconst (\n\t// Cloudflared events are significant to cloudflared operations like connection state changes.\n\t// Cloudflared is also the default event type for any events that haven't been separated into a proper event type.\n\tCloudflared LogEventType = iota\n\tHTTP\n\tTCP\n\tUDP\n)\n\nfunc ParseLogEventType(s string) (LogEventType, bool) {\n\tswitch s {\n\tcase \"cloudflared\":\n\t\treturn Cloudflared, true\n\tcase \"http\":\n\t\treturn HTTP, true\n\tcase \"tcp\":\n\t\treturn TCP, true\n\tcase \"udp\":\n\t\treturn UDP, true\n\t}\n\treturn -1, false\n}\n\nfunc (l LogEventType) String() string {\n\tswitch l {\n\tcase Cloudflared:\n\t\treturn \"cloudflared\"\n\tcase HTTP:\n\t\treturn \"http\"\n\tcase TCP:\n\t\treturn \"tcp\"\n\tcase UDP:\n\t\treturn \"udp\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\nfunc (l LogEventType) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(l.String())\n}\n\nfunc (e *LogEventType) UnmarshalJSON(data []byte) error {\n\tvar s string\n\tif err := json.Unmarshal(data, &s); err != nil {\n\t\treturn errors.New(\"unable to unmarshal LogEventType string\")\n\t}\n\tif event, ok := ParseLogEventType(s); ok {\n\t\t*e = event\n\t\treturn nil\n\t}\n\treturn errors.New(\"unable to unmarshal LogEventType\")\n}\n\n// LogLevel corresponds to the zerolog logging levels\n// \"panic\", \"fatal\", and \"trace\" are exempt from this list as they are rarely used and, at least\n// the first two are limited to failure conditions that lead to cloudflared shutting down.\ntype LogLevel int8\n\nconst (\n\tDebug LogLevel = 0\n\tInfo  LogLevel = 1\n\tWarn  LogLevel = 2\n\tError LogLevel = 3\n)\n\nfunc ParseLogLevel(l string) (LogLevel, bool) {\n\tswitch l {\n\tcase \"debug\":\n\t\treturn Debug, true\n\tcase \"info\":\n\t\treturn Info, true\n\tcase \"warn\":\n\t\treturn Warn, true\n\tcase \"error\":\n\t\treturn Error, true\n\t}\n\treturn -1, false\n}\n\nfunc (l LogLevel) String() string {\n\tswitch l {\n\tcase Debug:\n\t\treturn \"debug\"\n\tcase Info:\n\t\treturn \"info\"\n\tcase Warn:\n\t\treturn \"warn\"\n\tcase Error:\n\t\treturn \"error\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\nfunc (l LogLevel) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(l.String())\n}\n\nfunc (l *LogLevel) UnmarshalJSON(data []byte) error {\n\tvar s string\n\tif err := json.Unmarshal(data, &s); err != nil {\n\t\treturn errors.New(\"unable to unmarshal LogLevel string\")\n\t}\n\tif level, ok := ParseLogLevel(s); ok {\n\t\t*l = level\n\t\treturn nil\n\t}\n\treturn fmt.Errorf(\"unable to unmarshal LogLevel\")\n}\n\nconst (\n\t// TimeKey aligns with the zerolog.TimeFieldName\n\tTimeKey = \"time\"\n\t// LevelKey aligns with the zerolog.LevelFieldName\n\tLevelKey = \"level\"\n\t// LevelKey aligns with the zerolog.MessageFieldName\n\tMessageKey = \"message\"\n\t// EventTypeKey is the custom JSON key of the LogEventType in ZeroLogEvent\n\tEventTypeKey = \"event\"\n\t// FieldsKey is a custom JSON key to match and store every other key for a zerolog event\n\tFieldsKey = \"fields\"\n)\n\n// Log is the basic structure of the events that are sent to the client.\ntype Log struct {\n\tTime    string                 `json:\"time,omitempty\"`\n\tLevel   LogLevel               `json:\"level,omitempty\"`\n\tMessage string                 `json:\"message,omitempty\"`\n\tEvent   LogEventType           `json:\"event,omitempty\"`\n\tFields  map[string]interface{} `json:\"fields,omitempty\"`\n}\n\n// IntoClientEvent unmarshals the provided ClientEvent into the proper type.\nfunc IntoClientEvent[T EventStartStreaming | EventStopStreaming](e *ClientEvent, eventType ClientEventType) (*T, bool) {\n\tif e.Type != eventType {\n\t\treturn nil, false\n\t}\n\tevent := new(T)\n\terr := json.Unmarshal(e.event, event)\n\tif err != nil {\n\t\treturn nil, false\n\t}\n\treturn event, true\n}\n\n// IntoServerEvent unmarshals the provided ServerEvent into the proper type.\nfunc IntoServerEvent[T EventLog](e *ServerEvent, eventType ServerEventType) (*T, bool) {\n\tif e.Type != eventType {\n\t\treturn nil, false\n\t}\n\tevent := new(T)\n\terr := json.Unmarshal(e.event, event)\n\tif err != nil {\n\t\treturn nil, false\n\t}\n\treturn event, true\n}\n\n// ReadEvent will read a message from the websocket connection and parse it into a valid ServerEvent.\nfunc ReadServerEvent(c *websocket.Conn, ctx context.Context) (*ServerEvent, error) {\n\tmessage, err := readMessage(c, ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tevent := ServerEvent{}\n\tif err := json.Unmarshal(message, &event); err != nil {\n\t\treturn nil, err\n\t}\n\tswitch event.Type {\n\tcase Logs:\n\t\tevent.event = message\n\t\treturn &event, nil\n\tcase UnknownServerEventType:\n\t\treturn nil, errInvalidMessageType\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"invalid server message type was provided: %s\", event.Type)\n\t}\n}\n\n// ReadEvent will read a message from the websocket connection and parse it into a valid ClientEvent.\nfunc ReadClientEvent(c *websocket.Conn, ctx context.Context) (*ClientEvent, error) {\n\tmessage, err := readMessage(c, ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tevent := ClientEvent{}\n\tif err := json.Unmarshal(message, &event); err != nil {\n\t\treturn nil, err\n\t}\n\tswitch event.Type {\n\tcase StartStreaming, StopStreaming:\n\t\tevent.event = message\n\t\treturn &event, nil\n\tcase UnknownClientEventType:\n\t\treturn nil, errInvalidMessageType\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"invalid client message type was provided: %s\", event.Type)\n\t}\n}\n\n// readMessage will read a message from the websocket connection and return the payload.\nfunc readMessage(c *websocket.Conn, ctx context.Context) ([]byte, error) {\n\tmessageType, reader, err := c.Reader(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif messageType != websocket.MessageText {\n\t\treturn nil, errInvalidMessageType\n\t}\n\treturn io.ReadAll(reader)\n}\n\n// WriteEvent will write a Event type message to the websocket connection.\nfunc WriteEvent(c *websocket.Conn, ctx context.Context, event any) error {\n\tpayload, err := json.Marshal(event)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn c.Write(ctx, websocket.MessageText, payload)\n}\n\n// IsClosed returns true if the websocket error is a websocket.CloseError; returns false if not a\n// websocket.CloseError\nfunc IsClosed(err error, log *zerolog.Logger) bool {\n\tvar closeErr websocket.CloseError\n\tif errors.As(err, &closeErr) {\n\t\tif closeErr.Code != websocket.StatusNormalClosure {\n\t\t\tlog.Debug().Msgf(\"connection is already closed: (%d) %s\", closeErr.Code, closeErr.Reason)\n\t\t}\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc AsClosed(err error) *websocket.CloseError {\n\tvar closeErr websocket.CloseError\n\tif errors.As(err, &closeErr) {\n\t\treturn &closeErr\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "management/events_test.go",
    "content": "package management\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/require\"\n\t\"nhooyr.io/websocket\"\n\n\t\"github.com/cloudflare/cloudflared/internal/test\"\n)\n\nvar (\n\tdebugLevel *LogLevel\n\tinfoLevel  *LogLevel\n\twarnLevel  *LogLevel\n\terrorLevel *LogLevel\n)\n\nfunc init() {\n\t// created here because we can't do a reference to a const enum, i.e. &Info\n\tdebugLevel := new(LogLevel)\n\t*debugLevel = Debug\n\tinfoLevel := new(LogLevel)\n\t*infoLevel = Info\n\twarnLevel := new(LogLevel)\n\t*warnLevel = Warn\n\terrorLevel := new(LogLevel)\n\t*errorLevel = Error\n}\n\nfunc TestIntoClientEvent_StartStreaming(t *testing.T) {\n\tfor _, test := range []struct {\n\t\tname     string\n\t\texpected EventStartStreaming\n\t}{\n\t\t{\n\t\t\tname:     \"no filters\",\n\t\t\texpected: EventStartStreaming{ClientEvent: ClientEvent{Type: StartStreaming}},\n\t\t},\n\t\t{\n\t\t\tname: \"level filter\",\n\t\t\texpected: EventStartStreaming{\n\t\t\t\tClientEvent: ClientEvent{Type: StartStreaming},\n\t\t\t\tFilters: &StreamingFilters{\n\t\t\t\t\tLevel: infoLevel,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"events filter\",\n\t\t\texpected: EventStartStreaming{\n\t\t\t\tClientEvent: ClientEvent{Type: StartStreaming},\n\t\t\t\tFilters: &StreamingFilters{\n\t\t\t\t\tEvents: []LogEventType{Cloudflared, HTTP},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"sampling filter\",\n\t\t\texpected: EventStartStreaming{\n\t\t\t\tClientEvent: ClientEvent{Type: StartStreaming},\n\t\t\t\tFilters: &StreamingFilters{\n\t\t\t\t\tSampling: 0.5,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"level and events filters\",\n\t\t\texpected: EventStartStreaming{\n\t\t\t\tClientEvent: ClientEvent{Type: StartStreaming},\n\t\t\t\tFilters: &StreamingFilters{\n\t\t\t\t\tLevel:    infoLevel,\n\t\t\t\t\tEvents:   []LogEventType{Cloudflared},\n\t\t\t\t\tSampling: 0.5,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t} {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tdata, err := json.Marshal(test.expected)\n\t\t\trequire.NoError(t, err)\n\t\t\tevent := ClientEvent{}\n\t\t\terr = json.Unmarshal(data, &event)\n\t\t\trequire.NoError(t, err)\n\t\t\tevent.event = data\n\t\t\tce, ok := IntoClientEvent[EventStartStreaming](&event, StartStreaming)\n\t\t\trequire.True(t, ok)\n\t\t\trequire.Equal(t, test.expected.ClientEvent, ce.ClientEvent)\n\t\t\tif test.expected.Filters != nil {\n\t\t\t\tf := ce.Filters\n\t\t\t\tef := test.expected.Filters\n\t\t\t\tif ef.Level != nil {\n\t\t\t\t\trequire.Equal(t, *ef.Level, *f.Level)\n\t\t\t\t}\n\t\t\t\trequire.ElementsMatch(t, ef.Events, f.Events)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestIntoClientEvent_StopStreaming(t *testing.T) {\n\tevent := ClientEvent{\n\t\tType:  StopStreaming,\n\t\tevent: []byte(`{\"type\": \"stop_streaming\"}`),\n\t}\n\tce, ok := IntoClientEvent[EventStopStreaming](&event, StopStreaming)\n\trequire.True(t, ok)\n\trequire.Equal(t, EventStopStreaming{ClientEvent: ClientEvent{Type: StopStreaming}}, *ce)\n}\n\nfunc TestIntoClientEvent_Invalid(t *testing.T) {\n\tevent := ClientEvent{\n\t\tType:  UnknownClientEventType,\n\t\tevent: []byte(`{\"type\": \"invalid\"}`),\n\t}\n\t_, ok := IntoClientEvent[EventStartStreaming](&event, StartStreaming)\n\trequire.False(t, ok)\n}\n\nfunc TestIntoServerEvent_Logs(t *testing.T) {\n\tevent := ServerEvent{\n\t\tType:  Logs,\n\t\tevent: []byte(`{\"type\": \"logs\"}`),\n\t}\n\tce, ok := IntoServerEvent(&event, Logs)\n\trequire.True(t, ok)\n\trequire.Equal(t, EventLog{ServerEvent: ServerEvent{Type: Logs}}, *ce)\n}\n\nfunc TestIntoServerEvent_Invalid(t *testing.T) {\n\tevent := ServerEvent{\n\t\tType:  UnknownServerEventType,\n\t\tevent: []byte(`{\"type\": \"invalid\"}`),\n\t}\n\t_, ok := IntoServerEvent(&event, Logs)\n\trequire.False(t, ok)\n}\n\nfunc TestReadServerEvent(t *testing.T) {\n\tsentEvent := EventLog{\n\t\tServerEvent: ServerEvent{Type: Logs},\n\t\tLogs: []*Log{\n\t\t\t{\n\t\t\t\tTime:    time.Now().UTC().Format(time.RFC3339),\n\t\t\t\tEvent:   HTTP,\n\t\t\t\tLevel:   Info,\n\t\t\t\tMessage: \"test\",\n\t\t\t},\n\t\t},\n\t}\n\tclient, server := test.WSPipe(nil, nil)\n\tserver.CloseRead(context.Background())\n\tdefer func() {\n\t\tserver.Close(websocket.StatusInternalError, \"\")\n\t}()\n\tgo func() {\n\t\terr := WriteEvent(server, context.Background(), &sentEvent)\n\t\trequire.NoError(t, err)\n\t}()\n\tevent, err := ReadServerEvent(client, context.Background())\n\trequire.NoError(t, err)\n\trequire.Equal(t, sentEvent.Type, event.Type)\n\tclient.Close(websocket.StatusInternalError, \"\")\n}\n\nfunc TestReadServerEvent_InvalidWebSocketMessageType(t *testing.T) {\n\tclient, server := test.WSPipe(nil, nil)\n\tserver.CloseRead(context.Background())\n\tdefer func() {\n\t\tserver.Close(websocket.StatusInternalError, \"\")\n\t}()\n\tgo func() {\n\t\terr := server.Write(context.Background(), websocket.MessageBinary, []byte(\"test1234\"))\n\t\trequire.NoError(t, err)\n\t}()\n\t_, err := ReadServerEvent(client, context.Background())\n\trequire.Error(t, err)\n\tclient.Close(websocket.StatusInternalError, \"\")\n}\n\nfunc TestReadServerEvent_InvalidMessageType(t *testing.T) {\n\tsentEvent := ClientEvent{Type: ClientEventType(UnknownServerEventType)}\n\tclient, server := test.WSPipe(nil, nil)\n\tserver.CloseRead(context.Background())\n\tdefer func() {\n\t\tserver.Close(websocket.StatusInternalError, \"\")\n\t}()\n\tgo func() {\n\t\terr := WriteEvent(server, context.Background(), &sentEvent)\n\t\trequire.NoError(t, err)\n\t}()\n\t_, err := ReadServerEvent(client, context.Background())\n\trequire.ErrorIs(t, err, errInvalidMessageType)\n\tclient.Close(websocket.StatusInternalError, \"\")\n}\n\nfunc TestReadClientEvent(t *testing.T) {\n\tsentEvent := EventStartStreaming{\n\t\tClientEvent: ClientEvent{Type: StartStreaming},\n\t}\n\tclient, server := test.WSPipe(nil, nil)\n\tclient.CloseRead(context.Background())\n\tdefer func() {\n\t\tclient.Close(websocket.StatusInternalError, \"\")\n\t}()\n\tgo func() {\n\t\terr := WriteEvent(client, context.Background(), &sentEvent)\n\t\trequire.NoError(t, err)\n\t}()\n\tevent, err := ReadClientEvent(server, context.Background())\n\trequire.NoError(t, err)\n\trequire.Equal(t, sentEvent.Type, event.Type)\n\tserver.Close(websocket.StatusInternalError, \"\")\n}\n\nfunc TestReadClientEvent_InvalidWebSocketMessageType(t *testing.T) {\n\tclient, server := test.WSPipe(nil, nil)\n\tclient.CloseRead(context.Background())\n\tdefer func() {\n\t\tclient.Close(websocket.StatusInternalError, \"\")\n\t}()\n\tgo func() {\n\t\terr := client.Write(context.Background(), websocket.MessageBinary, []byte(\"test1234\"))\n\t\trequire.NoError(t, err)\n\t}()\n\t_, err := ReadClientEvent(server, context.Background())\n\trequire.Error(t, err)\n\tserver.Close(websocket.StatusInternalError, \"\")\n}\n\nfunc TestReadClientEvent_InvalidMessageType(t *testing.T) {\n\tsentEvent := ClientEvent{Type: UnknownClientEventType}\n\tclient, server := test.WSPipe(nil, nil)\n\tclient.CloseRead(context.Background())\n\tdefer func() {\n\t\tclient.Close(websocket.StatusInternalError, \"\")\n\t}()\n\tgo func() {\n\t\terr := WriteEvent(client, context.Background(), &sentEvent)\n\t\trequire.NoError(t, err)\n\t}()\n\t_, err := ReadClientEvent(server, context.Background())\n\trequire.ErrorIs(t, err, errInvalidMessageType)\n\tserver.Close(websocket.StatusInternalError, \"\")\n}\n"
  },
  {
    "path": "management/logger.go",
    "content": "package management\n\nimport (\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\tjsoniter \"github.com/json-iterator/go\"\n\t\"github.com/rs/zerolog\"\n)\n\nvar json = jsoniter.ConfigFastest\n\n// Logger manages the number of management streaming log sessions\ntype Logger struct {\n\tsessions []*session\n\tmu       sync.RWMutex\n\n\t// Unique logger that isn't a io.Writer of the list of zerolog writers. This helps prevent management log\n\t// statements from creating infinite recursion to export messages to a session and allows basic debugging and\n\t// error statements to be issued in the management code itself.\n\tLog *zerolog.Logger\n}\n\nfunc NewLogger() *Logger {\n\tlog := zerolog.New(zerolog.ConsoleWriter{\n\t\tOut:        os.Stdout,\n\t\tTimeFormat: time.RFC3339,\n\t}).With().Timestamp().Logger().Level(zerolog.InfoLevel)\n\treturn &Logger{\n\t\tLog: &log,\n\t}\n}\n\ntype LoggerListener interface {\n\t// ActiveSession returns the first active session for the requested actor.\n\tActiveSession(actor) *session\n\t// ActiveSession returns the count of active sessions.\n\tActiveSessions() int\n\t// Listen appends the session to the list of sessions that receive log events.\n\tListen(*session)\n\t// Remove a session from the available sessions that were receiving log events.\n\tRemove(*session)\n}\n\nfunc (l *Logger) ActiveSession(actor actor) *session {\n\tl.mu.RLock()\n\tdefer l.mu.RUnlock()\n\tfor _, session := range l.sessions {\n\t\tif session.actor.ID == actor.ID && session.active.Load() {\n\t\t\treturn session\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (l *Logger) ActiveSessions() int {\n\tl.mu.RLock()\n\tdefer l.mu.RUnlock()\n\tcount := 0\n\tfor _, session := range l.sessions {\n\t\tif session.active.Load() {\n\t\t\tcount += 1\n\t\t}\n\t}\n\treturn count\n}\n\nfunc (l *Logger) Listen(session *session) {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tsession.active.Store(true)\n\tl.sessions = append(l.sessions, session)\n}\n\nfunc (l *Logger) Remove(session *session) {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tindex := -1\n\tfor i, v := range l.sessions {\n\t\tif v == session {\n\t\t\tindex = i\n\t\t\tbreak\n\t\t}\n\t}\n\tif index == -1 {\n\t\t// Not found\n\t\treturn\n\t}\n\tcopy(l.sessions[index:], l.sessions[index+1:])\n\tl.sessions = l.sessions[:len(l.sessions)-1]\n}\n\n// Write will write the log event to all sessions that have available capacity. For those that are full, the message\n// will be dropped.\n// This function is the interface that zerolog expects to call when a log event is to be written out.\nfunc (l *Logger) Write(p []byte) (int, error) {\n\tl.mu.RLock()\n\tdefer l.mu.RUnlock()\n\t// return early if no active sessions\n\tif len(l.sessions) == 0 {\n\t\treturn len(p), nil\n\t}\n\tevent, err := parseZerologEvent(p)\n\t// drop event if unable to parse properly\n\tif err != nil {\n\t\tl.Log.Debug().Msg(\"unable to parse log event\")\n\t\treturn len(p), nil\n\t}\n\tfor _, session := range l.sessions {\n\t\tsession.Insert(event)\n\t}\n\treturn len(p), nil\n}\n\nfunc (l *Logger) WriteLevel(level zerolog.Level, p []byte) (n int, err error) {\n\treturn l.Write(p)\n}\n\nfunc parseZerologEvent(p []byte) (*Log, error) {\n\tvar fields map[string]interface{}\n\titer := json.BorrowIterator(p)\n\tdefer json.ReturnIterator(iter)\n\titer.ReadVal(&fields)\n\tif iter.Error != nil {\n\t\treturn nil, iter.Error\n\t}\n\tlogTime := time.Now().UTC().Format(zerolog.TimeFieldFormat)\n\tif t, ok := fields[TimeKey]; ok {\n\t\tif t, ok := t.(string); ok {\n\t\t\tlogTime = t\n\t\t}\n\t}\n\tlogLevel := Debug\n\t// A zerolog Debug event can be created and then an error can be added\n\t// via .Err(error), if so, we upgrade the level to error.\n\tif _, hasError := fields[\"error\"]; hasError {\n\t\tlogLevel = Error\n\t} else {\n\t\tif level, ok := fields[LevelKey]; ok {\n\t\t\tif level, ok := level.(string); ok {\n\t\t\t\tif logLevel, ok = ParseLogLevel(level); !ok {\n\t\t\t\t\tlogLevel = Debug\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// Assume the event type is Cloudflared if unable to parse/find. This could be from log events that haven't\n\t// yet been tagged with the appropriate EventType yet.\n\tlogEvent := Cloudflared\n\te := fields[EventTypeKey]\n\tif e != nil {\n\t\tif eventNumber, ok := e.(float64); ok {\n\t\t\tlogEvent = LogEventType(eventNumber)\n\t\t}\n\t}\n\tlogMessage := \"\"\n\tif m, ok := fields[MessageKey]; ok {\n\t\tif m, ok := m.(string); ok {\n\t\t\tlogMessage = m\n\t\t}\n\t}\n\tevent := Log{\n\t\tTime:    logTime,\n\t\tLevel:   logLevel,\n\t\tEvent:   logEvent,\n\t\tMessage: logMessage,\n\t}\n\t// Remove the keys that have top level keys on Log\n\tdelete(fields, TimeKey)\n\tdelete(fields, LevelKey)\n\tdelete(fields, EventTypeKey)\n\tdelete(fields, MessageKey)\n\t// The rest of the keys go into the Fields\n\tevent.Fields = fields\n\treturn &event, nil\n}\n"
  },
  {
    "path": "management/logger_test.go",
    "content": "package management\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// No listening sessions will not write to the channel\nfunc TestLoggerWrite_NoSessions(t *testing.T) {\n\tlogger := NewLogger()\n\tzlog := zerolog.New(logger).With().Timestamp().Logger().Level(zerolog.InfoLevel)\n\n\tzlog.Info().Msg(\"hello\")\n}\n\n// Validate that the session receives the event\nfunc TestLoggerWrite_OneSession(t *testing.T) {\n\tlogger := NewLogger()\n\tzlog := zerolog.New(logger).With().Timestamp().Logger().Level(zerolog.InfoLevel)\n\t_, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\n\tsession := newSession(logWindow, actor{ID: actorID}, cancel)\n\tlogger.Listen(session)\n\tdefer logger.Remove(session)\n\tassert.Equal(t, 1, logger.ActiveSessions())\n\tassert.Equal(t, session, logger.ActiveSession(actor{ID: actorID}))\n\tzlog.Info().Int(EventTypeKey, int(HTTP)).Msg(\"hello\")\n\tselect {\n\tcase event := <-session.listener:\n\t\tassert.NotEmpty(t, event.Time)\n\t\tassert.Equal(t, \"hello\", event.Message)\n\t\tassert.Equal(t, Info, event.Level)\n\t\tassert.Equal(t, HTTP, event.Event)\n\tdefault:\n\t\tassert.Fail(t, \"expected an event to be in the listener\")\n\t}\n}\n\n// Validate all sessions receive the same event\nfunc TestLoggerWrite_MultipleSessions(t *testing.T) {\n\tlogger := NewLogger()\n\tzlog := zerolog.New(logger).With().Timestamp().Logger().Level(zerolog.InfoLevel)\n\t_, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\n\tsession1 := newSession(logWindow, actor{}, cancel)\n\tlogger.Listen(session1)\n\tdefer logger.Remove(session1)\n\tassert.Equal(t, 1, logger.ActiveSessions())\n\n\tsession2 := newSession(logWindow, actor{}, cancel)\n\tlogger.Listen(session2)\n\tassert.Equal(t, 2, logger.ActiveSessions())\n\n\tzlog.Info().Int(EventTypeKey, int(HTTP)).Msg(\"hello\")\n\tfor _, session := range []*session{session1, session2} {\n\t\tselect {\n\t\tcase event := <-session.listener:\n\t\t\tassert.NotEmpty(t, event.Time)\n\t\t\tassert.Equal(t, \"hello\", event.Message)\n\t\t\tassert.Equal(t, Info, event.Level)\n\t\t\tassert.Equal(t, HTTP, event.Event)\n\t\tdefault:\n\t\t\tassert.Fail(t, \"expected an event to be in the listener\")\n\t\t}\n\t}\n\n\t// Close session2 and make sure session1 still receives events\n\tlogger.Remove(session2)\n\tzlog.Info().Int(EventTypeKey, int(HTTP)).Msg(\"hello2\")\n\tselect {\n\tcase event := <-session1.listener:\n\t\tassert.NotEmpty(t, event.Time)\n\t\tassert.Equal(t, \"hello2\", event.Message)\n\t\tassert.Equal(t, Info, event.Level)\n\t\tassert.Equal(t, HTTP, event.Event)\n\tdefault:\n\t\tassert.Fail(t, \"expected an event to be in the listener\")\n\t}\n\n\t// Make sure a held reference to session2 doesn't receive events after being closed\n\tselect {\n\tcase <-session2.listener:\n\t\tassert.Fail(t, \"An event was not expected to be in the session listener\")\n\tdefault:\n\t\t// pass\n\t}\n}\n\ntype mockWriter struct {\n\tevent *Log\n\terr   error\n}\n\nfunc (m *mockWriter) Write(p []byte) (int, error) {\n\tm.event, m.err = parseZerologEvent(p)\n\treturn len(p), nil\n}\n\n// Validate all event types are set properly\nfunc TestParseZerologEvent_EventTypes(t *testing.T) {\n\twriter := mockWriter{}\n\tzlog := zerolog.New(&writer).With().Timestamp().Logger().Level(zerolog.InfoLevel)\n\n\tfor _, test := range []LogEventType{\n\t\tCloudflared,\n\t\tHTTP,\n\t\tTCP,\n\t\tUDP,\n\t} {\n\t\tt.Run(test.String(), func(t *testing.T) {\n\t\t\tdefer func() { writer.err = nil }()\n\t\t\tzlog.Info().Int(EventTypeKey, int(test)).Msg(\"test\")\n\t\t\trequire.NoError(t, writer.err)\n\t\t\trequire.Equal(t, test, writer.event.Event)\n\t\t})\n\t}\n\n\t// Invalid defaults to Cloudflared LogEventType\n\tt.Run(\"invalid\", func(t *testing.T) {\n\t\tdefer func() { writer.err = nil }()\n\t\tzlog.Info().Str(EventTypeKey, \"unknown\").Msg(\"test\")\n\t\trequire.NoError(t, writer.err)\n\t\trequire.Equal(t, Cloudflared, writer.event.Event)\n\t})\n}\n\n// Validate top-level keys are removed from Fields\nfunc TestParseZerologEvent_Fields(t *testing.T) {\n\twriter := mockWriter{}\n\tzlog := zerolog.New(&writer).With().Timestamp().Logger().Level(zerolog.InfoLevel)\n\tzlog.Info().Int(EventTypeKey, int(Cloudflared)).Str(\"test\", \"test\").Msg(\"test message\")\n\trequire.NoError(t, writer.err)\n\tevent := writer.event\n\trequire.NotEmpty(t, event.Time)\n\trequire.Equal(t, Cloudflared, event.Event)\n\trequire.Equal(t, Info, event.Level)\n\trequire.Equal(t, \"test message\", event.Message)\n\n\t// Make sure Fields doesn't have other set keys used in the Log struct\n\trequire.NotEmpty(t, event.Fields)\n\trequire.Equal(t, \"test\", event.Fields[\"test\"])\n\trequire.NotContains(t, event.Fields, EventTypeKey)\n\trequire.NotContains(t, event.Fields, LevelKey)\n\trequire.NotContains(t, event.Fields, MessageKey)\n\trequire.NotContains(t, event.Fields, TimeKey)\n}\n"
  },
  {
    "path": "management/middleware.go",
    "content": "package management\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n)\n\ntype ctxKey int\n\nconst (\n\taccessClaimsCtxKey ctxKey = iota\n)\n\nvar errMissingAccessToken = managementError{Code: 1001, Message: \"missing access_token query parameter\"}\n\n// HTTP middleware setting the parsed access_token claims in the request context\nfunc ValidateAccessTokenQueryMiddleware(next http.Handler) http.Handler {\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\t// Validate access token\n\t\taccessToken := r.URL.Query().Get(\"access_token\")\n\t\tif accessToken == \"\" {\n\t\t\twriteHTTPErrorResponse(w, errMissingAccessToken)\n\t\t\treturn\n\t\t}\n\t\ttoken, err := ParseToken(accessToken)\n\t\tif err != nil {\n\t\t\twriteHTTPErrorResponse(w, errMissingAccessToken)\n\t\t\treturn\n\t\t}\n\t\tr = r.WithContext(context.WithValue(r.Context(), accessClaimsCtxKey, token))\n\t\tnext.ServeHTTP(w, r)\n\t})\n}\n\n// Middleware validation error struct for returning to the eyeball\ntype managementError struct {\n\tCode    int    `json:\"code,omitempty\"`\n\tMessage string `json:\"message,omitempty\"`\n}\n\nfunc (m *managementError) Error() string {\n\treturn m.Message\n}\n\n// Middleware validation error HTTP response JSON for returning to the eyeball\ntype managementErrorResponse struct {\n\tSuccess bool              `json:\"success,omitempty\"`\n\tErrors  []managementError `json:\"errors,omitempty\"`\n}\n\n// writeErrorResponse will respond to the eyeball with basic HTTP JSON payloads with validation failure information\nfunc writeHTTPErrorResponse(w http.ResponseWriter, errResp managementError) {\n\tw.Header().Set(\"Content-Type\", \"application/json\")\n\tw.WriteHeader(http.StatusBadRequest)\n\terr := json.NewEncoder(w).Encode(managementErrorResponse{\n\t\tSuccess: false,\n\t\tErrors:  []managementError{errResp},\n\t})\n\t// we have already written the header, so write a basic error response if unable to encode the error\n\tif err != nil {\n\t\t// fallback to text message\n\t\thttp.Error(w, fmt.Sprintf(\n\t\t\t\"%d %s\",\n\t\t\thttp.StatusBadRequest,\n\t\t\thttp.StatusText(http.StatusBadRequest),\n\t\t), http.StatusBadRequest)\n\t}\n}\n"
  },
  {
    "path": "management/middleware_test.go",
    "content": "package management\n\nimport (\n\t\"io\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"github.com/go-chi/chi/v5\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestValidateAccessTokenQueryMiddleware(t *testing.T) {\n\tr := chi.NewRouter()\n\tr.Use(ValidateAccessTokenQueryMiddleware)\n\tr.Get(\"/valid\", func(w http.ResponseWriter, r *http.Request) {\n\t\tclaims, ok := r.Context().Value(accessClaimsCtxKey).(*managementTokenClaims)\n\t\tassert.True(t, ok)\n\t\tassert.True(t, claims.verify())\n\t\tw.WriteHeader(http.StatusOK)\n\t})\n\tr.Get(\"/invalid\", func(w http.ResponseWriter, r *http.Request) {\n\t\t_, ok := r.Context().Value(accessClaimsCtxKey).(*managementTokenClaims)\n\t\tassert.False(t, ok)\n\t\tw.WriteHeader(http.StatusOK)\n\t})\n\n\tts := httptest.NewServer(r)\n\tdefer ts.Close()\n\n\t// valid: with access_token query param\n\tpath := \"/valid?access_token=\" + validToken\n\tresp, _ := testRequest(t, ts, \"GET\", path, nil)\n\tassert.Equal(t, http.StatusOK, resp.StatusCode)\n\n\t// invalid: unset token\n\tpath = \"/invalid\"\n\tresp, err := testRequest(t, ts, \"GET\", path, nil)\n\tassert.Equal(t, http.StatusBadRequest, resp.StatusCode)\n\tassert.NotNil(t, err)\n\tassert.Equal(t, errMissingAccessToken, err.Errors[0])\n\n\t// invalid: invalid token\n\tpath = \"/invalid?access_token=eyJ\"\n\tresp, err = testRequest(t, ts, \"GET\", path, nil)\n\tassert.Equal(t, http.StatusBadRequest, resp.StatusCode)\n\tassert.NotNil(t, err)\n\tassert.Equal(t, errMissingAccessToken, err.Errors[0])\n}\n\nfunc testRequest(t *testing.T, ts *httptest.Server, method, path string, body io.Reader) (*http.Response, *managementErrorResponse) {\n\treq, err := http.NewRequest(method, ts.URL+path, body)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tresp, err := ts.Client().Do(req)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tvar claims managementErrorResponse\n\terr = json.NewDecoder(resp.Body).Decode(&claims)\n\tif err != nil {\n\t\treturn resp, nil\n\t}\n\tdefer resp.Body.Close()\n\n\treturn resp, &claims\n}\n"
  },
  {
    "path": "management/service.go",
    "content": "package management\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/pprof\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/go-chi/chi/v5\"\n\t\"github.com/go-chi/cors\"\n\t\"github.com/google/uuid\"\n\t\"github.com/prometheus/client_golang/prometheus/promhttp\"\n\t\"github.com/rs/zerolog\"\n\t\"nhooyr.io/websocket\"\n)\n\nconst (\n\t// In the current state, an invalid command was provided by the client\n\tStatusInvalidCommand websocket.StatusCode = 4001\n\treasonInvalidCommand                      = \"expected start streaming as first event\"\n\t// There are a limited number of available streaming log sessions that cloudflared will service, exceeding this\n\t// value will return this error to incoming requests.\n\tStatusSessionLimitExceeded websocket.StatusCode = 4002\n\treasonSessionLimitExceeded                      = \"limit exceeded for streaming sessions\"\n\t// There is a limited idle time while not actively serving a session for a request before dropping the connection.\n\tStatusIdleLimitExceeded websocket.StatusCode = 4003\n\treasonIdleLimitExceeded                      = \"session was idle for too long\"\n)\n\nvar (\n\t// CORS middleware required to allow dash to access management.argotunnel.com requests\n\tcorsHandler = cors.Handler(cors.Options{\n\t\t// Allows for any subdomain of cloudflare.com\n\t\tAllowedOrigins: []string{\"https://*.cloudflare.com\"},\n\t\t// Required to present cookies or other authentication across origin boundries\n\t\tAllowCredentials: true,\n\t\tMaxAge:           300, // Maximum value not ignored by any of major browsers\n\t})\n)\n\ntype ManagementService struct {\n\t// The management tunnel hostname\n\tHostname string\n\n\t// Host details related configurations\n\tserviceIP string\n\tclientID  uuid.UUID\n\tlabel     string\n\n\t// Additional Handlers\n\tmetricsHandler http.Handler\n\n\tlog    *zerolog.Logger\n\trouter chi.Router\n\n\t// streamingMut is a lock to prevent concurrent requests to start streaming. Utilizing the atomic.Bool is not\n\t// sufficient to complete this operation since many other checks during an incoming new request are needed\n\t// to validate this before setting streaming to true.\n\tstreamingMut sync.Mutex\n\tlogger       LoggerListener\n}\n\nfunc New(managementHostname string,\n\tenableDiagServices bool,\n\tserviceIP string,\n\tclientID uuid.UUID,\n\tlabel string,\n\tlog *zerolog.Logger,\n\tlogger LoggerListener,\n) *ManagementService {\n\ts := &ManagementService{\n\t\tHostname:       managementHostname,\n\t\tlog:            log,\n\t\tlogger:         logger,\n\t\tserviceIP:      serviceIP,\n\t\tclientID:       clientID,\n\t\tlabel:          label,\n\t\tmetricsHandler: promhttp.Handler(),\n\t}\n\tr := chi.NewRouter()\n\tr.Use(ValidateAccessTokenQueryMiddleware)\n\n\t// Default management services\n\tr.With(corsHandler).Get(\"/ping\", ping)\n\tr.With(corsHandler).Head(\"/ping\", ping)\n\tr.Get(\"/logs\", s.logs)\n\tr.With(corsHandler).Get(\"/host_details\", s.getHostDetails)\n\n\t// Diagnostic management services\n\tif enableDiagServices {\n\t\t// Prometheus endpoint\n\t\tr.With(corsHandler).Get(\"/metrics\", s.metricsHandler.ServeHTTP)\n\t\t// Supports only heap and goroutine\n\t\tr.With(corsHandler).Get(\"/debug/pprof/{profile:heap|goroutine}\", pprof.Index)\n\t}\n\n\ts.router = r\n\treturn s\n}\n\nfunc (m *ManagementService) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tm.router.ServeHTTP(w, r)\n}\n\n// Management Ping handler\nfunc ping(w http.ResponseWriter, r *http.Request) {\n\tw.WriteHeader(200)\n}\n\n// The response provided by the /host_details endpoint\ntype getHostDetailsResponse struct {\n\tClientID string `json:\"connector_id\"`\n\tIP       string `json:\"ip,omitempty\"`\n\tHostName string `json:\"hostname,omitempty\"`\n}\n\nfunc (m *ManagementService) getHostDetails(w http.ResponseWriter, r *http.Request) {\n\tvar getHostDetailsResponse = getHostDetailsResponse{\n\t\tClientID: m.clientID.String(),\n\t}\n\tif ip, err := getPrivateIP(m.serviceIP); err == nil {\n\t\tgetHostDetailsResponse.IP = ip\n\t}\n\tgetHostDetailsResponse.HostName = m.getLabel()\n\n\tw.Header().Set(\"Content-Type\", \"application/json\")\n\tw.WriteHeader(200)\n\tjson.NewEncoder(w).Encode(getHostDetailsResponse)\n}\n\nfunc (m *ManagementService) getLabel() string {\n\tif m.label != \"\" {\n\t\treturn fmt.Sprintf(\"custom:%s\", m.label)\n\t}\n\n\t// If no label is provided we return the system hostname. This is not\n\t// a fqdn hostname.\n\thostname, err := os.Hostname()\n\tif err != nil {\n\t\treturn \"unknown\"\n\t}\n\treturn hostname\n}\n\n// Get preferred private ip of this machine\nfunc getPrivateIP(addr string) (string, error) {\n\tconn, err := net.DialTimeout(\"tcp\", addr, 1*time.Second)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer conn.Close()\n\tlocalAddr := conn.LocalAddr().String()\n\thost, _, err := net.SplitHostPort(localAddr)\n\treturn host, err\n}\n\n// readEvents will loop through all incoming websocket messages from a client and marshal them into the\n// proper Event structure and pass through to the events channel. Any invalid messages sent will automatically\n// terminate the connection.\nfunc (m *ManagementService) readEvents(c *websocket.Conn, ctx context.Context, events chan<- *ClientEvent) {\n\tfor {\n\t\tevent, err := ReadClientEvent(c, ctx)\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\tdefault:\n\t\t\tif err != nil {\n\t\t\t\t// If the client (or the server) already closed the connection, don't attempt to close it again\n\t\t\t\tif !IsClosed(err, m.log) {\n\t\t\t\t\tm.log.Err(err).Send()\n\t\t\t\t\tm.log.Err(c.Close(websocket.StatusUnsupportedData, err.Error())).Send()\n\t\t\t\t}\n\t\t\t\t// Any errors when reading the messages from the client will close the connection\n\t\t\t\treturn\n\t\t\t}\n\t\t\tevents <- event\n\t\t}\n\t}\n}\n\n// streamLogs will begin the process of reading from the Session listener and write the log events to the client.\nfunc (m *ManagementService) streamLogs(c *websocket.Conn, ctx context.Context, session *session) {\n\tfor session.Active() {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\tsession.Stop()\n\t\t\treturn\n\t\tcase event := <-session.listener:\n\t\t\terr := WriteEvent(c, ctx, &EventLog{\n\t\t\t\tServerEvent: ServerEvent{Type: Logs},\n\t\t\t\tLogs:        []*Log{event},\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\t// If the client (or the server) already closed the connection, don't attempt to close it again\n\t\t\t\tif !IsClosed(err, m.log) {\n\t\t\t\t\tm.log.Err(err).Send()\n\t\t\t\t\tm.log.Err(c.Close(websocket.StatusInternalError, err.Error())).Send()\n\t\t\t\t}\n\t\t\t\t// Any errors when writing the messages to the client will stop streaming and close the connection\n\t\t\t\tsession.Stop()\n\t\t\t\treturn\n\t\t\t}\n\t\tdefault:\n\t\t\t// No messages to send\n\t\t}\n\t}\n}\n\n// canStartStream will check the conditions of the request and return if the session can begin streaming.\nfunc (m *ManagementService) canStartStream(session *session) bool {\n\tm.streamingMut.Lock()\n\tdefer m.streamingMut.Unlock()\n\t// Limits to one actor for streaming logs\n\tif m.logger.ActiveSessions() > 0 {\n\t\t// Allow the same user to preempt their existing session to disconnect their old session and start streaming\n\t\t// with this new session instead.\n\t\tif existingSession := m.logger.ActiveSession(session.actor); existingSession != nil {\n\t\t\tm.log.Info().\n\t\t\t\tMsgf(\"Another management session request for the same actor was requested; the other session will be disconnected to handle the new request.\")\n\t\t\texistingSession.Stop()\n\t\t\tm.logger.Remove(existingSession)\n\t\t\texistingSession.cancel()\n\t\t} else {\n\t\t\tm.log.Warn().\n\t\t\t\tMsgf(\"Another management session request was attempted but one session already being served; there is a limit of streaming log sessions to reduce overall performance impact.\")\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// parseFilters will check the ClientEvent for start_streaming and assign filters if provided to the session\nfunc (m *ManagementService) parseFilters(c *websocket.Conn, event *ClientEvent, session *session) bool {\n\t// Expect the first incoming request\n\tstartEvent, ok := IntoClientEvent[EventStartStreaming](event, StartStreaming)\n\tif !ok {\n\t\treturn false\n\t}\n\tsession.Filters(startEvent.Filters)\n\treturn true\n}\n\n// Management Streaming Logs accept handler\nfunc (m *ManagementService) logs(w http.ResponseWriter, r *http.Request) {\n\tc, err := websocket.Accept(w, r, &websocket.AcceptOptions{\n\t\tOriginPatterns: []string{\n\t\t\t\"*.cloudflare.com\",\n\t\t},\n\t})\n\tif err != nil {\n\t\tm.log.Debug().Msgf(\"management handshake: %s\", err.Error())\n\t\treturn\n\t}\n\t// Make sure the connection is closed if other go routines fail to close the connection after completing.\n\tdefer c.Close(websocket.StatusInternalError, \"\")\n\tctx, cancel := context.WithCancel(r.Context())\n\tdefer cancel()\n\tevents := make(chan *ClientEvent)\n\tgo m.readEvents(c, ctx, events)\n\n\t// Send a heartbeat ping to hold the connection open even if not streaming.\n\tping := time.NewTicker(15 * time.Second)\n\tdefer ping.Stop()\n\n\t// Close the connection if no operation has occurred after the idle timeout. The timeout is halted\n\t// when streaming logs is active.\n\tidleTimeout := 5 * time.Minute\n\tidle := time.NewTimer(idleTimeout)\n\tdefer idle.Stop()\n\n\t// Fetch the claims from the request context to acquire the actor\n\tclaims, ok := ctx.Value(accessClaimsCtxKey).(*managementTokenClaims)\n\tif !ok || claims == nil {\n\t\t// Typically should never happen as it is provided in the context from the middleware\n\t\tm.log.Err(c.Close(websocket.StatusInternalError, \"missing access_token\")).Send()\n\t\treturn\n\t}\n\n\tsession := newSession(logWindow, claims.Actor, cancel)\n\tdefer m.logger.Remove(session)\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\tm.log.Debug().Msgf(\"management logs: context cancelled\")\n\t\t\tc.Close(websocket.StatusNormalClosure, \"context closed\")\n\t\t\treturn\n\t\tcase event := <-events:\n\t\t\tswitch event.Type {\n\t\t\tcase StartStreaming:\n\t\t\t\tidle.Stop()\n\t\t\t\t// Expect the first incoming request\n\t\t\t\tstartEvent, ok := IntoClientEvent[EventStartStreaming](event, StartStreaming)\n\t\t\t\tif !ok {\n\t\t\t\t\tm.log.Warn().Msgf(\"expected start_streaming as first recieved event\")\n\t\t\t\t\tm.log.Err(c.Close(StatusInvalidCommand, reasonInvalidCommand)).Send()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t// Make sure the session can start\n\t\t\t\tif !m.canStartStream(session) {\n\t\t\t\t\tm.log.Err(c.Close(StatusSessionLimitExceeded, reasonSessionLimitExceeded)).Send()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tsession.Filters(startEvent.Filters)\n\t\t\t\tm.logger.Listen(session)\n\t\t\t\tm.log.Debug().Msgf(\"Streaming logs\")\n\t\t\t\tgo m.streamLogs(c, ctx, session)\n\t\t\t\tcontinue\n\t\t\tcase StopStreaming:\n\t\t\t\tidle.Reset(idleTimeout)\n\t\t\t\t// Stop the current session for the current actor who requested it\n\t\t\t\tsession.Stop()\n\t\t\t\tm.logger.Remove(session)\n\t\t\tcase UnknownClientEventType:\n\t\t\t\tfallthrough\n\t\t\tdefault:\n\t\t\t\t// Drop unknown events and close connection\n\t\t\t\tm.log.Debug().Msgf(\"unexpected management message received: %s\", event.Type)\n\t\t\t\t// If the client (or the server) already closed the connection, don't attempt to close it again\n\t\t\t\tif !IsClosed(err, m.log) {\n\t\t\t\t\tm.log.Err(err).Err(c.Close(websocket.StatusUnsupportedData, err.Error())).Send()\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\tcase <-ping.C:\n\t\t\tgo c.Ping(ctx)\n\t\tcase <-idle.C:\n\t\t\tc.Close(StatusIdleLimitExceeded, reasonIdleLimitExceeded)\n\t\t\treturn\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "management/service_test.go",
    "content": "package management\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"nhooyr.io/websocket\"\n\n\t\"github.com/cloudflare/cloudflared/internal/test\"\n)\n\nvar (\n\tnoopLogger         = zerolog.New(io.Discard)\n\tmanagementHostname = \"https://management.argotunnel.com\"\n)\n\nfunc TestDisableDiagnosticRoutes(t *testing.T) {\n\tmgmt := New(\"management.argotunnel.com\", false, \"1.1.1.1:80\", uuid.Nil, \"\", &noopLogger, nil)\n\tfor _, path := range []string{\"/metrics\", \"/debug/pprof/goroutine\", \"/debug/pprof/heap\"} {\n\t\tt.Run(strings.Replace(path, \"/\", \"_\", -1), func(t *testing.T) {\n\t\t\treq := httptest.NewRequest(\"GET\", managementHostname+path+\"?access_token=\"+validToken, nil)\n\t\t\trecorder := httptest.NewRecorder()\n\t\t\tmgmt.ServeHTTP(recorder, req)\n\t\t\tresp := recorder.Result()\n\t\t\trequire.Equal(t, http.StatusNotFound, resp.StatusCode)\n\t\t})\n\t}\n}\n\nfunc TestReadEventsLoop(t *testing.T) {\n\tsentEvent := EventStartStreaming{\n\t\tClientEvent: ClientEvent{Type: StartStreaming},\n\t}\n\tclient, server := test.WSPipe(nil, nil)\n\tclient.CloseRead(context.Background())\n\tdefer func() {\n\t\tclient.Close(websocket.StatusInternalError, \"\")\n\t}()\n\tgo func() {\n\t\terr := WriteEvent(client, context.Background(), &sentEvent)\n\t\trequire.NoError(t, err)\n\t}()\n\tm := ManagementService{\n\t\tlog: &noopLogger,\n\t}\n\tevents := make(chan *ClientEvent)\n\tgo m.readEvents(server, context.Background(), events)\n\tevent := <-events\n\trequire.Equal(t, sentEvent.Type, event.Type)\n\tserver.Close(websocket.StatusInternalError, \"\")\n}\n\nfunc TestReadEventsLoop_ContextCancelled(t *testing.T) {\n\tclient, server := test.WSPipe(nil, nil)\n\tctx, cancel := context.WithCancel(context.Background())\n\tclient.CloseRead(ctx)\n\tdefer func() {\n\t\tclient.Close(websocket.StatusInternalError, \"\")\n\t}()\n\tm := ManagementService{\n\t\tlog: &noopLogger,\n\t}\n\tevents := make(chan *ClientEvent)\n\tgo func() {\n\t\ttime.Sleep(time.Second)\n\t\tcancel()\n\t}()\n\t// Want to make sure this function returns when context is cancelled\n\tm.readEvents(server, ctx, events)\n\tserver.Close(websocket.StatusInternalError, \"\")\n}\n\nfunc TestCanStartStream_NoSessions(t *testing.T) {\n\tm := ManagementService{\n\t\tlog: &noopLogger,\n\t\tlogger: &Logger{\n\t\t\tLog: &noopLogger,\n\t\t},\n\t}\n\t_, cancel := context.WithCancel(context.Background())\n\tsession := newSession(0, actor{}, cancel)\n\tassert.True(t, m.canStartStream(session))\n}\n\nfunc TestCanStartStream_ExistingSessionDifferentActor(t *testing.T) {\n\tm := ManagementService{\n\t\tlog: &noopLogger,\n\t\tlogger: &Logger{\n\t\t\tLog: &noopLogger,\n\t\t},\n\t}\n\t_, cancel := context.WithCancel(context.Background())\n\tsession1 := newSession(0, actor{ID: \"test\"}, cancel)\n\tassert.True(t, m.canStartStream(session1))\n\tm.logger.Listen(session1)\n\tassert.True(t, session1.Active())\n\n\t// Try another session\n\tsession2 := newSession(0, actor{ID: \"test2\"}, cancel)\n\tassert.Equal(t, 1, m.logger.ActiveSessions())\n\tassert.False(t, m.canStartStream(session2))\n\n\t// Close session1\n\tm.logger.Remove(session1)\n\tassert.True(t, session1.Active()) // Remove doesn't stop a session\n\tsession1.Stop()\n\tassert.False(t, session1.Active())\n\tassert.Equal(t, 0, m.logger.ActiveSessions())\n\n\t// Try session2 again\n\tassert.True(t, m.canStartStream(session2))\n}\n\nfunc TestCanStartStream_ExistingSessionSameActor(t *testing.T) {\n\tm := ManagementService{\n\t\tlog: &noopLogger,\n\t\tlogger: &Logger{\n\t\t\tLog: &noopLogger,\n\t\t},\n\t}\n\tactor := actor{ID: \"test\"}\n\t_, cancel := context.WithCancel(context.Background())\n\tsession1 := newSession(0, actor, cancel)\n\tassert.True(t, m.canStartStream(session1))\n\tm.logger.Listen(session1)\n\tassert.True(t, session1.Active())\n\n\t// Try another session\n\tsession2 := newSession(0, actor, cancel)\n\tassert.Equal(t, 1, m.logger.ActiveSessions())\n\tassert.True(t, m.canStartStream(session2))\n\t// session1 is removed and stopped\n\tassert.Equal(t, 0, m.logger.ActiveSessions())\n\tassert.False(t, session1.Active())\n}\n"
  },
  {
    "path": "management/session.go",
    "content": "package management\n\nimport (\n\t\"context\"\n\t\"math/rand\"\n\t\"sync/atomic\"\n)\n\nconst (\n\t// Indicates how many log messages the listener will hold before dropping.\n\t// Provides a throttling mechanism to drop latest messages if the sender\n\t// can't keep up with the influx of log messages.\n\tlogWindow = 30\n)\n\n// session captures a streaming logs session for a connection of an actor.\ntype session struct {\n\t// Indicates if the session is streaming or not. Modifying this will affect the active session.\n\tactive atomic.Bool\n\t// Allows the session to control the context of the underlying connection to close it out when done. Mostly\n\t// used by the LoggerListener to close out and cleanup a session.\n\tcancel context.CancelFunc\n\t// Actor who started the session\n\tactor actor\n\t// Buffered channel that holds the recent log events\n\tlistener chan *Log\n\t// Types of log events that this session will provide through the listener\n\tfilters *StreamingFilters\n\t// Sampling of the log events this session will send (runs after all other filters if available)\n\tsampler *sampler\n}\n\n// NewSession creates a new session.\nfunc newSession(size int, actor actor, cancel context.CancelFunc) *session {\n\ts := &session{\n\t\tactive:   atomic.Bool{},\n\t\tcancel:   cancel,\n\t\tactor:    actor,\n\t\tlistener: make(chan *Log, size),\n\t\tfilters:  &StreamingFilters{},\n\t}\n\treturn s\n}\n\n// Filters assigns the StreamingFilters to the session\nfunc (s *session) Filters(filters *StreamingFilters) {\n\tif filters != nil {\n\t\ts.filters = filters\n\t\tsampling := filters.Sampling\n\t\t// clamp the sampling values between 0 and 1\n\t\tif sampling < 0 {\n\t\t\tsampling = 0\n\t\t}\n\t\tif sampling > 1 {\n\t\t\tsampling = 1\n\t\t}\n\t\ts.filters.Sampling = sampling\n\t\tif sampling > 0 && sampling < 1 {\n\t\t\ts.sampler = &sampler{\n\t\t\t\tp: int(sampling * 100),\n\t\t\t}\n\t\t}\n\t} else {\n\t\ts.filters = &StreamingFilters{}\n\t}\n}\n\n// Insert attempts to insert the log to the session. If the log event matches the provided session filters, it\n// will be applied to the listener.\nfunc (s *session) Insert(log *Log) {\n\t// Level filters are optional\n\tif s.filters.Level != nil {\n\t\tif *s.filters.Level > log.Level {\n\t\t\treturn\n\t\t}\n\t}\n\t// Event filters are optional\n\tif len(s.filters.Events) != 0 && !contains(s.filters.Events, log.Event) {\n\t\treturn\n\t}\n\t// Sampling is also optional\n\tif s.sampler != nil && !s.sampler.Sample() {\n\t\treturn\n\t}\n\tselect {\n\tcase s.listener <- log:\n\tdefault:\n\t\t// buffer is full, discard\n\t}\n}\n\n// Active returns if the session is active\nfunc (s *session) Active() bool {\n\treturn s.active.Load()\n}\n\n// Stop will halt the session\nfunc (s *session) Stop() {\n\ts.active.Store(false)\n}\n\nfunc contains(array []LogEventType, t LogEventType) bool {\n\tfor _, v := range array {\n\t\tif v == t {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// sampler will send approximately every p percentage log events out of 100.\ntype sampler struct {\n\tp int\n}\n\n// Sample returns true if the event should be part of the sample, false if the event should be dropped.\nfunc (s *sampler) Sample() bool {\n\treturn rand.Intn(100) <= s.p\n\n}\n"
  },
  {
    "path": "management/session_test.go",
    "content": "package management\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// Validate the active states of the session\nfunc TestSession_ActiveControl(t *testing.T) {\n\t_, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\tsession := newSession(4, actor{}, cancel)\n\t// session starts out not active\n\tassert.False(t, session.Active())\n\tsession.active.Store(true)\n\tassert.True(t, session.Active())\n\tsession.Stop()\n\tassert.False(t, session.Active())\n}\n\n// Validate that the session filters events\nfunc TestSession_Insert(t *testing.T) {\n\t_, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\tinfoLevel := new(LogLevel)\n\t*infoLevel = Info\n\twarnLevel := new(LogLevel)\n\t*warnLevel = Warn\n\tfor _, test := range []struct {\n\t\tname      string\n\t\tfilters   StreamingFilters\n\t\texpectLog bool\n\t}{\n\t\t{\n\t\t\tname:      \"none\",\n\t\t\texpectLog: true,\n\t\t},\n\t\t{\n\t\t\tname: \"level\",\n\t\t\tfilters: StreamingFilters{\n\t\t\t\tLevel: infoLevel,\n\t\t\t},\n\t\t\texpectLog: true,\n\t\t},\n\t\t{\n\t\t\tname: \"filtered out level\",\n\t\t\tfilters: StreamingFilters{\n\t\t\t\tLevel: warnLevel,\n\t\t\t},\n\t\t\texpectLog: false,\n\t\t},\n\t\t{\n\t\t\tname: \"events\",\n\t\t\tfilters: StreamingFilters{\n\t\t\t\tEvents: []LogEventType{HTTP},\n\t\t\t},\n\t\t\texpectLog: true,\n\t\t},\n\t\t{\n\t\t\tname: \"filtered out event\",\n\t\t\tfilters: StreamingFilters{\n\t\t\t\tEvents: []LogEventType{Cloudflared},\n\t\t\t},\n\t\t\texpectLog: false,\n\t\t},\n\t\t{\n\t\t\tname: \"sampling\",\n\t\t\tfilters: StreamingFilters{\n\t\t\t\tSampling: 0.9999999,\n\t\t\t},\n\t\t\texpectLog: true,\n\t\t},\n\t\t{\n\t\t\tname: \"sampling (invalid negative)\",\n\t\t\tfilters: StreamingFilters{\n\t\t\t\tSampling: -1.0,\n\t\t\t},\n\t\t\texpectLog: true,\n\t\t},\n\t\t{\n\t\t\tname: \"sampling (invalid too large)\",\n\t\t\tfilters: StreamingFilters{\n\t\t\t\tSampling: 2.0,\n\t\t\t},\n\t\t\texpectLog: true,\n\t\t},\n\t\t{\n\t\t\tname: \"filter and event\",\n\t\t\tfilters: StreamingFilters{\n\t\t\t\tLevel:  infoLevel,\n\t\t\t\tEvents: []LogEventType{HTTP},\n\t\t\t},\n\t\t\texpectLog: true,\n\t\t},\n\t} {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tsession := newSession(4, actor{}, cancel)\n\t\t\tsession.Filters(&test.filters)\n\t\t\tlog := Log{\n\t\t\t\tTime:    time.Now().UTC().Format(time.RFC3339),\n\t\t\t\tEvent:   HTTP,\n\t\t\t\tLevel:   Info,\n\t\t\t\tMessage: \"test\",\n\t\t\t}\n\t\t\tsession.Insert(&log)\n\t\t\tselect {\n\t\t\tcase <-session.listener:\n\t\t\t\trequire.True(t, test.expectLog)\n\t\t\tdefault:\n\t\t\t\trequire.False(t, test.expectLog)\n\t\t\t}\n\t\t})\n\t}\n}\n\n// Validate that the session has a max amount of events to hold\nfunc TestSession_InsertOverflow(t *testing.T) {\n\t_, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\tsession := newSession(1, actor{}, cancel)\n\tlog := Log{\n\t\tTime:    time.Now().UTC().Format(time.RFC3339),\n\t\tEvent:   HTTP,\n\t\tLevel:   Info,\n\t\tMessage: \"test\",\n\t}\n\t// Insert 2 but only max channel size for 1\n\tsession.Insert(&log)\n\tsession.Insert(&log)\n\tselect {\n\tcase <-session.listener:\n\t\t// pass\n\tdefault:\n\t\trequire.Fail(t, \"expected one log event\")\n\t}\n\t// Second dequeue should fail\n\tselect {\n\tcase <-session.listener:\n\t\trequire.Fail(t, \"expected no more remaining log events\")\n\tdefault:\n\t\t// pass\n\t}\n}\n"
  },
  {
    "path": "management/token.go",
    "content": "package management\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/go-jose/go-jose/v4\"\n\t\"github.com/go-jose/go-jose/v4/jwt\"\n)\n\nconst tunnelstoreFEDIssuer = \"fed-tunnelstore\"\n\ntype managementTokenClaims struct {\n\tTunnel tunnel `json:\"tun\"`\n\tActor  actor  `json:\"actor\"`\n\tjwt.Claims\n}\n\n// VerifyTunnel compares the tun claim isn't empty\nfunc (c *managementTokenClaims) verify() bool {\n\treturn c.Tunnel.verify() && c.Actor.verify()\n}\n\ntype tunnel struct {\n\tID         string `json:\"id\"`\n\tAccountTag string `json:\"account_tag\"`\n}\n\n// verify compares the tun claim isn't empty\nfunc (t *tunnel) verify() bool {\n\treturn t.AccountTag != \"\" && t.ID != \"\"\n}\n\ntype actor struct {\n\tID      string `json:\"id\"`\n\tSupport bool   `json:\"support\"`\n}\n\n// verify checks the ID claim isn't empty\nfunc (t *actor) verify() bool {\n\treturn t.ID != \"\"\n}\n\nfunc ParseToken(token string) (*managementTokenClaims, error) {\n\tjwt, err := jwt.ParseSigned(token, []jose.SignatureAlgorithm{jose.ES256})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"malformed jwt: %v\", err)\n\t}\n\n\tvar claims managementTokenClaims\n\t// This is actually safe because we verify the token in the edge before it reaches cloudflared\n\terr = jwt.UnsafeClaimsWithoutVerification(&claims)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"malformed jwt: %v\", err)\n\t}\n\tif !claims.verify() {\n\t\treturn nil, fmt.Errorf(\"invalid management token format provided\")\n\t}\n\treturn &claims, nil\n}\n\nfunc (m *managementTokenClaims) IsFed() bool {\n\treturn m.Issuer == tunnelstoreFEDIssuer\n}\n"
  },
  {
    "path": "management/token_test.go",
    "content": "package management\n\nimport (\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"errors\"\n\t\"testing\"\n\n\t\"github.com/go-jose/go-jose/v4\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nconst (\n\tvalidToken = \"eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IjEifQ.eyJ0dW4iOnsiaWQiOiI3YjA5ODE0OS01MWZlLTRlZTUtYTY4Ny0zZTM3NDQ2NmVmYzciLCJhY2NvdW50X3RhZyI6ImNkMzkxZTljMDYyNmE4Zjc2Y2IxZjY3MGY2NTkxYjA1In0sImFjdG9yIjp7ImlkIjoiZGNhcnJAY2xvdWRmbGFyZS5jb20iLCJzdXBwb3J0IjpmYWxzZX0sInJlcyI6WyJsb2dzIl0sImV4cCI6MTY3NzExNzY5NiwiaWF0IjoxNjc3MTE0MDk2LCJpc3MiOiJ0dW5uZWxzdG9yZSJ9.mKenOdOy3Xi4O-grldFnAAemdlE9WajEpTDC_FwezXQTstWiRTLwU65P5jt4vNsIiZA4OJRq7bH-QYID9wf9NA\" // nolint: gosec\n\n\taccountTag = \"cd391e9c0626a8f76cb1f670f6591b05\"\n\ttunnelID   = \"7b098149-51fe-4ee5-a687-3e374466efc7\"\n\tactorID    = \"45d2751e-6b59-45a9-814d-f630786bd0cd\"\n)\n\ntype invalidManagementTokenClaims struct {\n\tInvalid string `json:\"invalid\"`\n}\n\nfunc TestParseToken(t *testing.T) {\n\tkey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)\n\trequire.NoError(t, err)\n\n\tfor _, test := range []struct {\n\t\tname   string\n\t\tclaims any\n\t\terr    error\n\t}{\n\t\t{\n\t\t\tname: \"Valid\",\n\t\t\tclaims: managementTokenClaims{\n\t\t\t\tTunnel: tunnel{\n\t\t\t\t\tID:         tunnelID,\n\t\t\t\t\tAccountTag: accountTag,\n\t\t\t\t},\n\t\t\t\tActor: actor{\n\t\t\t\t\tID: actorID,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"Invalid claims\",\n\t\t\tclaims: invalidManagementTokenClaims{Invalid: \"invalid\"},\n\t\t\terr:    errors.New(\"invalid management token format provided\"),\n\t\t},\n\t\t{\n\t\t\tname: \"Missing Tunnel\",\n\t\t\tclaims: managementTokenClaims{\n\t\t\t\tActor: actor{\n\t\t\t\t\tID: actorID,\n\t\t\t\t},\n\t\t\t},\n\t\t\terr: errors.New(\"invalid management token format provided\"),\n\t\t},\n\t\t{\n\t\t\tname: \"Missing Tunnel ID\",\n\t\t\tclaims: managementTokenClaims{\n\t\t\t\tTunnel: tunnel{\n\t\t\t\t\tAccountTag: accountTag,\n\t\t\t\t},\n\t\t\t\tActor: actor{\n\t\t\t\t\tID: actorID,\n\t\t\t\t},\n\t\t\t},\n\t\t\terr: errors.New(\"invalid management token format provided\"),\n\t\t},\n\t\t{\n\t\t\tname: \"Missing Account Tag\",\n\t\t\tclaims: managementTokenClaims{\n\t\t\t\tTunnel: tunnel{\n\t\t\t\t\tID: tunnelID,\n\t\t\t\t},\n\t\t\t\tActor: actor{\n\t\t\t\t\tID: actorID,\n\t\t\t\t},\n\t\t\t},\n\t\t\terr: errors.New(\"invalid management token format provided\"),\n\t\t},\n\t\t{\n\t\t\tname: \"Missing Actor\",\n\t\t\tclaims: managementTokenClaims{\n\t\t\t\tTunnel: tunnel{\n\t\t\t\t\tID:         tunnelID,\n\t\t\t\t\tAccountTag: accountTag,\n\t\t\t\t},\n\t\t\t},\n\t\t\terr: errors.New(\"invalid management token format provided\"),\n\t\t},\n\t\t{\n\t\t\tname: \"Missing Actor ID\",\n\t\t\tclaims: managementTokenClaims{\n\t\t\t\tTunnel: tunnel{\n\t\t\t\t\tID: tunnelID,\n\t\t\t\t},\n\t\t\t\tActor: actor{},\n\t\t\t},\n\t\t\terr: errors.New(\"invalid management token format provided\"),\n\t\t},\n\t} {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tjwt := signToken(t, test.claims, key)\n\t\t\tclaims, err := ParseToken(jwt)\n\t\t\tif test.err != nil {\n\t\t\t\trequire.EqualError(t, err, test.err.Error())\n\t\t\t\treturn\n\t\t\t}\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, test.claims, *claims)\n\t\t})\n\t}\n}\n\nfunc signToken(t *testing.T, token any, key *ecdsa.PrivateKey) string {\n\topts := (&jose.SignerOptions{}).WithType(\"JWT\").WithHeader(\"kid\", \"1\")\n\tsigner, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.ES256, Key: key}, opts)\n\trequire.NoError(t, err)\n\tpayload, err := json.Marshal(token)\n\trequire.NoError(t, err)\n\tjws, err := signer.Sign(payload)\n\trequire.NoError(t, err)\n\tjwt, err := jws.CompactSerialize()\n\trequire.NoError(t, err)\n\treturn jwt\n}\n"
  },
  {
    "path": "metrics/config.go",
    "content": "package metrics\n\ntype HistogramConfig struct {\n\tBucketsStart float64\n\tBucketsWidth float64\n\tBucketsCount int\n}\n"
  },
  {
    "path": "metrics/metrics.go",
    "content": "package metrics\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t_ \"net/http/pprof\"\n\t\"runtime\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/facebookgo/grace/gracenet\"\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"github.com/prometheus/client_golang/prometheus/promhttp\"\n\t\"github.com/rs/zerolog\"\n\t\"golang.org/x/net/trace\"\n\n\t\"github.com/cloudflare/cloudflared/diagnostic\"\n)\n\nconst (\n\tstartupTime            = time.Millisecond * 500\n\tdefaultShutdownTimeout = time.Second * 15\n)\n\n// This variable is set at compile time to allow the default local address to change.\nvar Runtime = \"host\"\n\nfunc GetMetricsDefaultAddress(runtimeType string) string {\n\t// When issuing the diagnostic command we may have to reach a server that is\n\t// running in a virtual environment and in that case we must bind to 0.0.0.0\n\t// otherwise the server won't be reachable.\n\tswitch runtimeType {\n\tcase \"virtual\":\n\t\treturn \"0.0.0.0:0\"\n\tdefault:\n\t\treturn \"localhost:0\"\n\t}\n}\n\n// GetMetricsKnownAddresses returns the addresses used by the metrics server to bind at\n// startup time to allow a semi-deterministic approach to know where the server is listening at.\n// The ports were selected because at the time we are in 2024 and they do not collide with any\n// know/registered port according https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers.\nfunc GetMetricsKnownAddresses(runtimeType string) []string {\n\tswitch runtimeType {\n\tcase \"virtual\":\n\t\treturn []string{\"0.0.0.0:20241\", \"0.0.0.0:20242\", \"0.0.0.0:20243\", \"0.0.0.0:20244\", \"0.0.0.0:20245\"}\n\tdefault:\n\t\treturn []string{\"localhost:20241\", \"localhost:20242\", \"localhost:20243\", \"localhost:20244\", \"localhost:20245\"}\n\t}\n}\n\ntype Config struct {\n\tReadyServer         *ReadyServer\n\tDiagnosticHandler   *diagnostic.Handler\n\tQuickTunnelHostname string\n\tOrchestrator        orchestrator\n\n\tShutdownTimeout time.Duration\n}\n\ntype orchestrator interface {\n\tGetVersionedConfigJSON() ([]byte, error)\n}\n\nfunc newMetricsHandler(\n\tconfig Config,\n\tlog *zerolog.Logger,\n) *http.ServeMux {\n\trouter := http.NewServeMux()\n\trouter.Handle(\"/debug/\", http.DefaultServeMux)\n\trouter.Handle(\"/metrics\", promhttp.Handler())\n\trouter.HandleFunc(\"/healthcheck\", func(w http.ResponseWriter, r *http.Request) {\n\t\t_, _ = fmt.Fprintf(w, \"OK\\n\")\n\t})\n\tif config.ReadyServer != nil {\n\t\trouter.Handle(\"/ready\", config.ReadyServer)\n\t}\n\trouter.HandleFunc(\"/quicktunnel\", func(w http.ResponseWriter, r *http.Request) {\n\t\t_, _ = fmt.Fprintf(w, `{\"hostname\":\"%s\"}`, config.QuickTunnelHostname)\n\t})\n\tif config.Orchestrator != nil {\n\t\trouter.HandleFunc(\"/config\", func(w http.ResponseWriter, r *http.Request) {\n\t\t\tjson, err := config.Orchestrator.GetVersionedConfigJSON()\n\t\t\tif err != nil {\n\t\t\t\tw.WriteHeader(500)\n\t\t\t\t_, _ = fmt.Fprintf(w, \"ERR: %v\", err)\n\t\t\t\tlog.Err(err).Msg(\"Failed to serve config\")\n\t\t\t\treturn\n\t\t\t}\n\t\t\t_, _ = w.Write(json)\n\t\t})\n\t}\n\n\tconfig.DiagnosticHandler.InstallEndpoints(router)\n\n\treturn router\n}\n\n// CreateMetricsListener will create a new [net.Listener] by using an\n// known set of ports when the default address is passed with the fallback\n// of choosing a random port when none is available.\n//\n// In case the provided address is not the default one then it will be used\n// as is.\nfunc CreateMetricsListener(listeners *gracenet.Net, laddr string) (net.Listener, error) {\n\tif laddr == GetMetricsDefaultAddress(Runtime) {\n\t\t// On the presence of the default address select\n\t\t// a port from the known set of addresses iteratively.\n\t\taddresses := GetMetricsKnownAddresses(Runtime)\n\t\tfor _, address := range addresses {\n\t\t\tlistener, err := listeners.Listen(\"tcp\", address)\n\t\t\tif err == nil {\n\t\t\t\treturn listener, nil\n\t\t\t}\n\t\t}\n\n\t\t// When no port is available then bind to a random one\n\t\tlistener, err := listeners.Listen(\"tcp\", laddr)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to listen to default metrics address: %w\", err)\n\t\t}\n\n\t\treturn listener, nil\n\t}\n\n\t// Explicitly got a local address then bind to it\n\tlistener, err := listeners.Listen(\"tcp\", laddr)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to bind to address (%s): %w\", laddr, err)\n\t}\n\n\treturn listener, nil\n}\n\nfunc ServeMetrics(\n\tl net.Listener,\n\tctx context.Context,\n\tconfig Config,\n\tlog *zerolog.Logger,\n) (err error) {\n\tvar wg sync.WaitGroup\n\t// Metrics port is privileged, so no need for further access control\n\ttrace.AuthRequest = func(*http.Request) (bool, bool) { return true, true }\n\t// TODO: parameterize ReadTimeout and WriteTimeout. The maximum time we can\n\t// profile CPU usage depends on WriteTimeout\n\th := newMetricsHandler(config, log)\n\tserver := &http.Server{\n\t\tReadTimeout:  10 * time.Second,\n\t\tWriteTimeout: 10 * time.Second,\n\t\tHandler:      h,\n\t}\n\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\terr = server.Serve(l)\n\t}()\n\tlog.Info().Msgf(\"Starting metrics server on %s\", fmt.Sprintf(\"%v/metrics\", l.Addr()))\n\t// server.Serve will hang if server.Shutdown is called before the server is\n\t// fully started up. So add artificial delay.\n\ttime.Sleep(startupTime)\n\n\t<-ctx.Done()\n\tshutdownTimeout := config.ShutdownTimeout\n\tif shutdownTimeout == 0 {\n\t\tshutdownTimeout = defaultShutdownTimeout\n\t}\n\n\tctx, cancel := context.WithTimeout(context.Background(), shutdownTimeout)\n\t_ = server.Shutdown(ctx)\n\tcancel()\n\n\twg.Wait()\n\tif err == http.ErrServerClosed {\n\t\tlog.Info().Msg(\"Metrics server stopped\")\n\t\treturn nil\n\t}\n\tlog.Err(err).Msg(\"Metrics server failed\")\n\treturn err\n}\n\nfunc RegisterBuildInfo(buildType, buildTime, version string) {\n\tbuildInfo := prometheus.NewGaugeVec(\n\t\tprometheus.GaugeOpts{\n\t\t\t// Don't namespace build_info, since we want it to be consistent across all Cloudflare services\n\t\t\tName: \"build_info\",\n\t\t\tHelp: \"Build and version information\",\n\t\t},\n\t\t[]string{\"goversion\", \"type\", \"revision\", \"version\"},\n\t)\n\tprometheus.MustRegister(buildInfo)\n\tbuildInfo.WithLabelValues(runtime.Version(), buildType, buildTime, version).Set(1)\n}\n"
  },
  {
    "path": "metrics/metrics_test.go",
    "content": "package metrics_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/facebookgo/grace/gracenet\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/cloudflare/cloudflared/metrics\"\n)\n\nfunc TestMetricsListenerCreation(t *testing.T) {\n\tt.Parallel()\n\tlisteners := gracenet.Net{}\n\tlistener1, err := metrics.CreateMetricsListener(&listeners, metrics.GetMetricsDefaultAddress(\"host\"))\n\tassert.Equal(t, \"127.0.0.1:20241\", listener1.Addr().String())\n\trequire.NoError(t, err)\n\tlistener2, err := metrics.CreateMetricsListener(&listeners, metrics.GetMetricsDefaultAddress(\"host\"))\n\tassert.Equal(t, \"127.0.0.1:20242\", listener2.Addr().String())\n\trequire.NoError(t, err)\n\tlistener3, err := metrics.CreateMetricsListener(&listeners, metrics.GetMetricsDefaultAddress(\"host\"))\n\tassert.Equal(t, \"127.0.0.1:20243\", listener3.Addr().String())\n\trequire.NoError(t, err)\n\tlistener4, err := metrics.CreateMetricsListener(&listeners, metrics.GetMetricsDefaultAddress(\"host\"))\n\tassert.Equal(t, \"127.0.0.1:20244\", listener4.Addr().String())\n\trequire.NoError(t, err)\n\tlistener5, err := metrics.CreateMetricsListener(&listeners, metrics.GetMetricsDefaultAddress(\"host\"))\n\tassert.Equal(t, \"127.0.0.1:20245\", listener5.Addr().String())\n\trequire.NoError(t, err)\n\tlistener6, err := metrics.CreateMetricsListener(&listeners, metrics.GetMetricsDefaultAddress(\"host\"))\n\taddresses := [5]string{\"127.0.0.1:20241\", \"127.0.0.1:20242\", \"127.0.0.1:20243\", \"127.0.0.1:20244\", \"127.0.0.1:20245\"}\n\tassert.NotContains(t, addresses, listener6.Addr().String())\n\trequire.NoError(t, err)\n\tlistener7, err := metrics.CreateMetricsListener(&listeners, \"localhost:12345\")\n\tassert.Equal(t, \"127.0.0.1:12345\", listener7.Addr().String())\n\trequire.NoError(t, err)\n\terr = listener1.Close()\n\trequire.NoError(t, err)\n\terr = listener2.Close()\n\trequire.NoError(t, err)\n\terr = listener3.Close()\n\trequire.NoError(t, err)\n\terr = listener4.Close()\n\trequire.NoError(t, err)\n\terr = listener5.Close()\n\trequire.NoError(t, err)\n\terr = listener6.Close()\n\trequire.NoError(t, err)\n\terr = listener7.Close()\n\trequire.NoError(t, err)\n}\n"
  },
  {
    "path": "metrics/readiness.go",
    "content": "package metrics\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/google/uuid\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelstate\"\n)\n\n// ReadyServer serves HTTP 200 if the tunnel can serve traffic. Intended for k8s readiness checks.\ntype ReadyServer struct {\n\tclientID uuid.UUID\n\ttracker  *tunnelstate.ConnTracker\n}\n\n// NewReadyServer initializes a ReadyServer and starts listening for dis/connection events.\nfunc NewReadyServer(\n\tclientID uuid.UUID,\n\ttracker *tunnelstate.ConnTracker,\n) *ReadyServer {\n\treturn &ReadyServer{\n\t\tclientID,\n\t\ttracker,\n\t}\n}\n\ntype body struct {\n\tStatus           int       `json:\"status\"`\n\tReadyConnections uint      `json:\"readyConnections\"`\n\tConnectorID      uuid.UUID `json:\"connectorId\"`\n}\n\n// ServeHTTP responds with HTTP 200 if the tunnel is connected to the edge.\nfunc (rs *ReadyServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tstatusCode, readyConnections := rs.makeResponse()\n\tw.WriteHeader(statusCode)\n\tbody := body{\n\t\tStatus:           statusCode,\n\t\tReadyConnections: readyConnections,\n\t\tConnectorID:      rs.clientID,\n\t}\n\tmsg, err := json.Marshal(body)\n\tif err != nil {\n\t\t_, _ = fmt.Fprintf(w, `{\"error\": \"%s\"}`, err)\n\t}\n\t_, _ = w.Write(msg)\n}\n\n// This is the bulk of the logic for ServeHTTP, broken into its own pure function\n// to make unit testing easy.\nfunc (rs *ReadyServer) makeResponse() (statusCode int, readyConnections uint) {\n\treadyConnections = rs.tracker.CountActiveConns()\n\tif readyConnections > 0 {\n\t\treturn http.StatusOK, readyConnections\n\t} else {\n\t\treturn http.StatusServiceUnavailable, readyConnections\n\t}\n}\n"
  },
  {
    "path": "metrics/readiness_test.go",
    "content": "package metrics_test\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/cloudflare/cloudflared/connection\"\n\t\"github.com/cloudflare/cloudflared/metrics\"\n\t\"github.com/cloudflare/cloudflared/tunnelstate\"\n)\n\nfunc mockRequest(t *testing.T, readyServer *metrics.ReadyServer) (int, uint) {\n\tt.Helper()\n\n\tvar readyreadyConnections struct {\n\t\tStatus           int       `json:\"status\"`\n\t\tReadyConnections uint      `json:\"readyConnections\"`\n\t\tConnectorID      uuid.UUID `json:\"connectorId\"`\n\t}\n\trec := httptest.NewRecorder()\n\treadyServer.ServeHTTP(rec, nil)\n\n\tdecoder := json.NewDecoder(rec.Body)\n\terr := decoder.Decode(&readyreadyConnections)\n\trequire.NoError(t, err)\n\treturn rec.Code, readyreadyConnections.ReadyConnections\n}\n\nfunc TestReadinessEventHandling(t *testing.T) {\n\tnopLogger := zerolog.Nop()\n\ttracker := tunnelstate.NewConnTracker(&nopLogger)\n\trs := metrics.NewReadyServer(uuid.Nil, tracker)\n\n\t// start not ok\n\tcode, readyConnections := mockRequest(t, rs)\n\tassert.NotEqualValues(t, http.StatusOK, code)\n\tassert.Zero(t, readyConnections)\n\n\t// one connected => ok\n\ttracker.OnTunnelEvent(connection.Event{\n\t\tIndex:     1,\n\t\tEventType: connection.Connected,\n\t})\n\tcode, readyConnections = mockRequest(t, rs)\n\tassert.EqualValues(t, http.StatusOK, code)\n\tassert.EqualValues(t, 1, readyConnections)\n\n\t// another connected => still ok\n\ttracker.OnTunnelEvent(connection.Event{\n\t\tIndex:     2,\n\t\tEventType: connection.Connected,\n\t})\n\tcode, readyConnections = mockRequest(t, rs)\n\tassert.EqualValues(t, http.StatusOK, code)\n\tassert.EqualValues(t, 2, readyConnections)\n\n\t// one reconnecting => still ok\n\ttracker.OnTunnelEvent(connection.Event{\n\t\tIndex:     2,\n\t\tEventType: connection.Reconnecting,\n\t})\n\tcode, readyConnections = mockRequest(t, rs)\n\tassert.EqualValues(t, http.StatusOK, code)\n\tassert.EqualValues(t, 1, readyConnections)\n\n\t// Regression test for TUN-3777\n\ttracker.OnTunnelEvent(connection.Event{\n\t\tIndex:     1,\n\t\tEventType: connection.RegisteringTunnel,\n\t})\n\tcode, readyConnections = mockRequest(t, rs)\n\tassert.NotEqualValues(t, http.StatusOK, code)\n\tassert.Zero(t, readyConnections)\n\n\t// other connected then unregistered  => not ok\n\ttracker.OnTunnelEvent(connection.Event{\n\t\tIndex:     1,\n\t\tEventType: connection.Connected,\n\t})\n\tcode, readyConnections = mockRequest(t, rs)\n\tassert.EqualValues(t, http.StatusOK, code)\n\tassert.EqualValues(t, 1, readyConnections)\n\ttracker.OnTunnelEvent(connection.Event{\n\t\tIndex:     1,\n\t\tEventType: connection.Unregistering,\n\t})\n\tcode, readyConnections = mockRequest(t, rs)\n\tassert.NotEqualValues(t, http.StatusOK, code)\n\tassert.Zero(t, readyConnections)\n\n\t// other disconnected => not ok\n\ttracker.OnTunnelEvent(connection.Event{\n\t\tIndex:     1,\n\t\tEventType: connection.Disconnected,\n\t})\n\tcode, readyConnections = mockRequest(t, rs)\n\tassert.NotEqualValues(t, http.StatusOK, code)\n\tassert.Zero(t, readyConnections)\n}\n"
  },
  {
    "path": "mocks/mock_limiter.go",
    "content": "// Code generated by MockGen. DO NOT EDIT.\n// Source: ../flow/limiter.go\n//\n// Generated by this command:\n//\n//\tmockgen -typed -build_flags=-tags=gomock -package mocks -destination mock_limiter.go -source=../flow/limiter.go Limiter\n//\n\n// Package mocks is a generated GoMock package.\npackage mocks\n\nimport (\n\treflect \"reflect\"\n\n\tgomock \"go.uber.org/mock/gomock\"\n)\n\n// MockLimiter is a mock of Limiter interface.\ntype MockLimiter struct {\n\tctrl     *gomock.Controller\n\trecorder *MockLimiterMockRecorder\n\tisgomock struct{}\n}\n\n// MockLimiterMockRecorder is the mock recorder for MockLimiter.\ntype MockLimiterMockRecorder struct {\n\tmock *MockLimiter\n}\n\n// NewMockLimiter creates a new mock instance.\nfunc NewMockLimiter(ctrl *gomock.Controller) *MockLimiter {\n\tmock := &MockLimiter{ctrl: ctrl}\n\tmock.recorder = &MockLimiterMockRecorder{mock}\n\treturn mock\n}\n\n// EXPECT returns an object that allows the caller to indicate expected use.\nfunc (m *MockLimiter) EXPECT() *MockLimiterMockRecorder {\n\treturn m.recorder\n}\n\n// Acquire mocks base method.\nfunc (m *MockLimiter) Acquire(flowType string) error {\n\tm.ctrl.T.Helper()\n\tret := m.ctrl.Call(m, \"Acquire\", flowType)\n\tret0, _ := ret[0].(error)\n\treturn ret0\n}\n\n// Acquire indicates an expected call of Acquire.\nfunc (mr *MockLimiterMockRecorder) Acquire(flowType any) *MockLimiterAcquireCall {\n\tmr.mock.ctrl.T.Helper()\n\tcall := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Acquire\", reflect.TypeOf((*MockLimiter)(nil).Acquire), flowType)\n\treturn &MockLimiterAcquireCall{Call: call}\n}\n\n// MockLimiterAcquireCall wrap *gomock.Call\ntype MockLimiterAcquireCall struct {\n\t*gomock.Call\n}\n\n// Return rewrite *gomock.Call.Return\nfunc (c *MockLimiterAcquireCall) Return(arg0 error) *MockLimiterAcquireCall {\n\tc.Call = c.Call.Return(arg0)\n\treturn c\n}\n\n// Do rewrite *gomock.Call.Do\nfunc (c *MockLimiterAcquireCall) Do(f func(string) error) *MockLimiterAcquireCall {\n\tc.Call = c.Call.Do(f)\n\treturn c\n}\n\n// DoAndReturn rewrite *gomock.Call.DoAndReturn\nfunc (c *MockLimiterAcquireCall) DoAndReturn(f func(string) error) *MockLimiterAcquireCall {\n\tc.Call = c.Call.DoAndReturn(f)\n\treturn c\n}\n\n// Release mocks base method.\nfunc (m *MockLimiter) Release() {\n\tm.ctrl.T.Helper()\n\tm.ctrl.Call(m, \"Release\")\n}\n\n// Release indicates an expected call of Release.\nfunc (mr *MockLimiterMockRecorder) Release() *MockLimiterReleaseCall {\n\tmr.mock.ctrl.T.Helper()\n\tcall := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"Release\", reflect.TypeOf((*MockLimiter)(nil).Release))\n\treturn &MockLimiterReleaseCall{Call: call}\n}\n\n// MockLimiterReleaseCall wrap *gomock.Call\ntype MockLimiterReleaseCall struct {\n\t*gomock.Call\n}\n\n// Return rewrite *gomock.Call.Return\nfunc (c *MockLimiterReleaseCall) Return() *MockLimiterReleaseCall {\n\tc.Call = c.Call.Return()\n\treturn c\n}\n\n// Do rewrite *gomock.Call.Do\nfunc (c *MockLimiterReleaseCall) Do(f func()) *MockLimiterReleaseCall {\n\tc.Call = c.Call.Do(f)\n\treturn c\n}\n\n// DoAndReturn rewrite *gomock.Call.DoAndReturn\nfunc (c *MockLimiterReleaseCall) DoAndReturn(f func()) *MockLimiterReleaseCall {\n\tc.Call = c.Call.DoAndReturn(f)\n\treturn c\n}\n\n// SetLimit mocks base method.\nfunc (m *MockLimiter) SetLimit(arg0 uint64) {\n\tm.ctrl.T.Helper()\n\tm.ctrl.Call(m, \"SetLimit\", arg0)\n}\n\n// SetLimit indicates an expected call of SetLimit.\nfunc (mr *MockLimiterMockRecorder) SetLimit(arg0 any) *MockLimiterSetLimitCall {\n\tmr.mock.ctrl.T.Helper()\n\tcall := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, \"SetLimit\", reflect.TypeOf((*MockLimiter)(nil).SetLimit), arg0)\n\treturn &MockLimiterSetLimitCall{Call: call}\n}\n\n// MockLimiterSetLimitCall wrap *gomock.Call\ntype MockLimiterSetLimitCall struct {\n\t*gomock.Call\n}\n\n// Return rewrite *gomock.Call.Return\nfunc (c *MockLimiterSetLimitCall) Return() *MockLimiterSetLimitCall {\n\tc.Call = c.Call.Return()\n\treturn c\n}\n\n// Do rewrite *gomock.Call.Do\nfunc (c *MockLimiterSetLimitCall) Do(f func(uint64)) *MockLimiterSetLimitCall {\n\tc.Call = c.Call.Do(f)\n\treturn c\n}\n\n// DoAndReturn rewrite *gomock.Call.DoAndReturn\nfunc (c *MockLimiterSetLimitCall) DoAndReturn(f func(uint64)) *MockLimiterSetLimitCall {\n\tc.Call = c.Call.DoAndReturn(f)\n\treturn c\n}\n"
  },
  {
    "path": "mocks/mockgen.go",
    "content": "//go:build gomock || generate\n\npackage mocks\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package mocks -destination mock_limiter.go -source=../flow/limiter.go Limiter\"\n"
  },
  {
    "path": "orchestration/config.go",
    "content": "package orchestration\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/ingress\"\n)\n\ntype newRemoteConfig struct {\n\tingress.RemoteConfig\n\t// Add more fields when we support other settings in tunnel orchestration\n}\n\ntype newLocalConfig struct {\n\tRemoteConfig       ingress.RemoteConfig\n\tConfigurationFlags map[string]string `json:\"__configuration_flags,omitempty\"`\n}\n\n// Config is the original config as read and parsed by cloudflared.\ntype Config struct {\n\tIngress             *ingress.Ingress\n\tWarpRouting         ingress.WarpRoutingConfig\n\tOriginDialerService *ingress.OriginDialerService\n\n\t// Extra settings used to configure this instance but that are not eligible for remotely management\n\t// ie. (--protocol, --loglevel, ...)\n\tConfigurationFlags map[string]string\n}\n\nfunc (rc *newLocalConfig) MarshalJSON() ([]byte, error) {\n\tvar r = struct {\n\t\tConfigurationFlags map[string]string `json:\"__configuration_flags,omitempty\"`\n\t\tingress.RemoteConfigJSON\n\t}{\n\t\tConfigurationFlags: rc.ConfigurationFlags,\n\t\tRemoteConfigJSON: ingress.RemoteConfigJSON{\n\t\t\t// UI doesn't support top level configs, so we reconcile to individual ingress configs.\n\t\t\tGlobalOriginRequest: nil,\n\t\t\tIngressRules:        convertToUnvalidatedIngressRules(rc.RemoteConfig.Ingress),\n\t\t\tWarpRouting:         rc.RemoteConfig.WarpRouting.RawConfig(),\n\t\t},\n\t}\n\n\treturn json.Marshal(r)\n}\n\nfunc convertToUnvalidatedIngressRules(i ingress.Ingress) []config.UnvalidatedIngressRule {\n\tresult := make([]config.UnvalidatedIngressRule, 0)\n\tfor _, rule := range i.Rules {\n\t\tvar path string\n\t\tif rule.Path != nil {\n\t\t\tpath = rule.Path.String()\n\t\t}\n\n\t\tnewRule := config.UnvalidatedIngressRule{\n\t\t\tHostname:      rule.Hostname,\n\t\t\tPath:          path,\n\t\t\tService:       rule.Service.String(),\n\t\t\tOriginRequest: ingress.ConvertToRawOriginConfig(rule.Config),\n\t\t}\n\n\t\tresult = append(result, newRule)\n\t}\n\n\treturn result\n}\n"
  },
  {
    "path": "orchestration/config_test.go",
    "content": "package orchestration\n\nimport (\n\t\"encoding/json\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/ingress\"\n)\n\n// TestNewLocalConfig_MarshalJSON tests that we are able to converte a compiled and validated config back\n// into an \"unvalidated\" format which is compatible with Remote Managed configurations.\nfunc TestNewLocalConfig_MarshalJSON(t *testing.T) {\n\trawConfig := []byte(`\n\t{\n\t\t\"originRequest\": {\n\t\t\t\t\t\"connectTimeout\": 160,\n\t\t\t\t\t\"httpHostHeader\": \"default\"\n\t\t},\n\t\t\"ingress\": [\n\t\t\t{\n\t\t\t\t\"hostname\": \"tun.example.com\",\n\t\t\t\t\"service\": \"https://localhost:8000\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"hostname\": \"*\",\n\t\t\t\t\"service\": \"https://localhost:8001\",\n\t\t\t\t\"originRequest\": {\n\t\t\t\t\t\"connectTimeout\": 121,\n\t\t\t\t\t\"tlsTimeout\": 2,\n\t\t\t\t\t\"noHappyEyeballs\": false,\n\t\t\t\t\t\"tcpKeepAlive\": 2,\n\t\t\t\t\t\"keepAliveConnections\": 2,\n\t\t\t\t\t\"keepAliveTimeout\": 2,\n\t\t\t\t\t\"httpHostHeader\": \"def\",\n\t\t\t\t\t\"originServerName\": \"b2\",\n\t\t\t\t\t\"caPool\": \"/tmp/path1\",\n\t\t\t\t\t\"noTLSVerify\": false,\n\t\t\t\t\t\"disableChunkedEncoding\": false,\n\t\t\t\t\t\"bastionMode\": false,\n\t\t\t\t\t\"proxyAddress\": \"interface\",\n\t\t\t\t\t\"proxyPort\": 200,\n\t\t\t\t\t\"proxyType\": \"\",\n\t\t\t\t\t\"ipRules\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"prefix\": \"10.0.0.0/16\",\n\t\t\t\t\t\t\t\"ports\": [3000, 3030],\n\t\t\t\t\t\t\t\"allow\": false\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"prefix\": \"192.16.0.0/24\",\n\t\t\t\t\t\t\t\"ports\": [5000, 5050],\n\t\t\t\t\t\t\t\"allow\": true\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        \"warp-routing\": {\n\t\t\t\"connectTimeout\": 1\n        }\n\t}\n\t`)\n\n\tvar expectedConfig ingress.RemoteConfig\n\terr := json.Unmarshal(rawConfig, &expectedConfig)\n\trequire.NoError(t, err)\n\n\tc := &newLocalConfig{\n\t\tRemoteConfig:       expectedConfig,\n\t\tConfigurationFlags: nil,\n\t}\n\n\tjsonSerde, err := json.Marshal(c)\n\trequire.NoError(t, err)\n\n\tvar remoteConfig ingress.RemoteConfig\n\terr = json.Unmarshal(jsonSerde, &remoteConfig)\n\trequire.NoError(t, err)\n\n\trequire.Equal(t, remoteConfig.WarpRouting, ingress.WarpRoutingConfig{\n\t\tConnectTimeout: config.CustomDuration{\n\t\t\tDuration: time.Second,\n\t\t},\n\t\tTCPKeepAlive: config.CustomDuration{\n\t\t\tDuration: 30 * time.Second, // default value is 30 seconds\n\t\t},\n\t})\n\trequire.Equal(t, remoteConfig.Ingress.Rules, expectedConfig.Ingress.Rules)\n}\n"
  },
  {
    "path": "orchestration/metrics.go",
    "content": "package orchestration\n\nimport (\n\t\"github.com/prometheus/client_golang/prometheus\"\n)\n\nconst (\n\tMetricsNamespace = \"cloudflared\"\n\tMetricsSubsystem = \"orchestration\"\n)\n\nvar (\n\tconfigVersion = prometheus.NewGauge(\n\t\tprometheus.GaugeOpts{\n\t\t\tNamespace: MetricsNamespace,\n\t\t\tSubsystem: MetricsSubsystem,\n\t\t\tName:      \"config_version\",\n\t\t\tHelp:      \"Configuration Version\",\n\t\t},\n\t)\n)\n\nfunc init() {\n\tprometheus.MustRegister(configVersion)\n}\n"
  },
  {
    "path": "orchestration/orchestrator.go",
    "content": "package orchestration\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\tpkgerrors \"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/connection\"\n\tcfdflow \"github.com/cloudflare/cloudflared/flow\"\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\t\"github.com/cloudflare/cloudflared/proxy\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\n// Orchestrator manages configurations, so they can be updatable during runtime\n// properties are static, so it can be read without lock\n// currentVersion and config are read/write infrequently, so their access are synchronized with RWMutex\n// access to proxy is synchronized with atomic.Value, because it uses copy-on-write to provide scalable frequently\n// read when update is infrequent\ntype Orchestrator struct {\n\tcurrentVersion int32\n\t// Used by UpdateConfig to make sure one update at a time\n\tlock sync.RWMutex\n\t// Underlying value is proxy.Proxy, can be read without the lock, but still needs the lock to update\n\tproxy atomic.Value\n\t// Set of internal ingress rules defined at cloudflared startup (separate from user-defined ingress rules)\n\tinternalRules []ingress.Rule\n\t// cloudflared Configuration\n\tconfig *Config\n\ttags   []pogs.Tag\n\t// flowLimiter tracks active sessions across the tunnel and limits new sessions if they are above the limit.\n\tflowLimiter cfdflow.Limiter\n\t// Origin dialer service to manage egress socket dialing.\n\toriginDialerService *ingress.OriginDialerService\n\tlog                 *zerolog.Logger\n\n\t// orchestrator must not handle any more updates after shutdownC is closed\n\tshutdownC <-chan struct{}\n\t// Closing proxyShutdownC will close the previous proxy\n\tproxyShutdownC chan<- struct{}\n}\n\nfunc NewOrchestrator(ctx context.Context,\n\tconfig *Config,\n\ttags []pogs.Tag,\n\tinternalRules []ingress.Rule,\n\tlog *zerolog.Logger,\n) (*Orchestrator, error) {\n\to := &Orchestrator{\n\t\t// Lowest possible version, any remote configuration will have version higher than this\n\t\t// Starting at -1 allows a configuration migration (local to remote) to override the current configuration as it\n\t\t// will start at version 0.\n\t\tcurrentVersion:      -1,\n\t\tinternalRules:       internalRules,\n\t\tconfig:              config,\n\t\ttags:                tags,\n\t\tflowLimiter:         cfdflow.NewLimiter(config.WarpRouting.MaxActiveFlows),\n\t\toriginDialerService: config.OriginDialerService,\n\t\tlog:                 log,\n\t\tshutdownC:           ctx.Done(),\n\t}\n\tif err := o.updateIngress(*config.Ingress, config.WarpRouting); err != nil {\n\t\treturn nil, err\n\t}\n\tgo o.waitToCloseLastProxy()\n\treturn o, nil\n}\n\n// UpdateConfig creates a new proxy with the new ingress rules\nfunc (o *Orchestrator) UpdateConfig(version int32, config []byte) *pogs.UpdateConfigurationResponse {\n\to.lock.Lock()\n\tdefer o.lock.Unlock()\n\n\tif o.currentVersion >= version {\n\t\to.log.Debug().\n\t\t\tInt32(\"current_version\", o.currentVersion).\n\t\t\tInt32(\"received_version\", version).\n\t\t\tMsg(\"Current version is equal or newer than received version\")\n\t\treturn &pogs.UpdateConfigurationResponse{\n\t\t\tLastAppliedVersion: o.currentVersion,\n\t\t}\n\t}\n\tvar newConf newRemoteConfig\n\tif err := json.Unmarshal(config, &newConf); err != nil {\n\t\to.log.Err(err).\n\t\t\tInt32(\"version\", version).\n\t\t\tStr(\"config\", string(config)).\n\t\t\tMsgf(\"Failed to deserialize new configuration\")\n\t\treturn &pogs.UpdateConfigurationResponse{\n\t\t\tLastAppliedVersion: o.currentVersion,\n\t\t\tErr:                err,\n\t\t}\n\t}\n\n\tif err := o.updateIngress(newConf.Ingress, newConf.WarpRouting); err != nil {\n\t\to.log.Err(err).\n\t\t\tInt32(\"version\", version).\n\t\t\tStr(\"config\", string(config)).\n\t\t\tMsgf(\"Failed to update ingress\")\n\t\treturn &pogs.UpdateConfigurationResponse{\n\t\t\tLastAppliedVersion: o.currentVersion,\n\t\t\tErr:                err,\n\t\t}\n\t}\n\to.currentVersion = version\n\n\to.log.Info().\n\t\tInt32(\"version\", version).\n\t\tStr(\"config\", string(config)).\n\t\tMsg(\"Updated to new configuration\")\n\tconfigVersion.Set(float64(version))\n\treturn &pogs.UpdateConfigurationResponse{\n\t\tLastAppliedVersion: o.currentVersion,\n\t}\n}\n\n// overrideRemoteWarpRoutingWithLocalValues overrides the ingress.WarpRoutingConfig that comes from the remote with\n// the local values if there is any.\nfunc (o *Orchestrator) overrideRemoteWarpRoutingWithLocalValues(remoteWarpRouting *ingress.WarpRoutingConfig) error {\n\treturn o.overrideMaxActiveFlows(o.config.ConfigurationFlags[flags.MaxActiveFlows], remoteWarpRouting)\n}\n\n// overrideMaxActiveFlows checks the local configuration flags, and if a value is found for the flags.MaxActiveFlows\n// overrides the value that comes on the remote ingress.WarpRoutingConfig with the local value.\nfunc (o *Orchestrator) overrideMaxActiveFlows(maxActiveFlowsLocalConfig string, remoteWarpRouting *ingress.WarpRoutingConfig) error {\n\t// If max active flows isn't defined locally just use the remote value\n\tif maxActiveFlowsLocalConfig == \"\" {\n\t\treturn nil\n\t}\n\n\tmaxActiveFlowsLocalOverride, err := strconv.ParseUint(maxActiveFlowsLocalConfig, 10, 64)\n\tif err != nil {\n\t\treturn pkgerrors.Wrapf(err, \"failed to parse %s\", flags.MaxActiveFlows)\n\t}\n\n\t// Override the value that comes from the remote with the local value\n\tremoteWarpRouting.MaxActiveFlows = maxActiveFlowsLocalOverride\n\treturn nil\n}\n\n// The caller is responsible to make sure there is no concurrent access\nfunc (o *Orchestrator) updateIngress(ingressRules ingress.Ingress, warpRouting ingress.WarpRoutingConfig) error {\n\tselect {\n\tcase <-o.shutdownC:\n\t\treturn fmt.Errorf(\"cloudflared already shutdown\")\n\tdefault:\n\t}\n\n\t// Overrides the local values, onto the remote values of the warp routing configuration\n\tif err := o.overrideRemoteWarpRoutingWithLocalValues(&warpRouting); err != nil {\n\t\treturn pkgerrors.Wrap(err, \"failed to merge local overrides into warp routing configuration\")\n\t}\n\n\t// Assign the internal ingress rules to the parsed ingress\n\tingressRules.InternalRules = o.internalRules\n\n\t// Check if ingress rules are empty, and add the default route if so.\n\tif ingressRules.IsEmpty() {\n\t\tingressRules.Rules = ingress.GetDefaultIngressRules(o.log)\n\t}\n\n\t// Start new proxy before closing the ones from last version.\n\t// The upside is we don't need to restart proxy from last version, which can fail\n\t// The downside is new version might have ingress rule that require previous version to be shutdown first\n\t// The downside is minimized because none of the ingress.OriginService implementation have that requirement\n\tproxyShutdownC := make(chan struct{})\n\tif err := ingressRules.StartOrigins(o.log, proxyShutdownC); err != nil {\n\t\treturn pkgerrors.Wrap(err, \"failed to start origin\")\n\t}\n\n\t// Update the flow limit since the configuration might have changed\n\to.flowLimiter.SetLimit(warpRouting.MaxActiveFlows)\n\n\t// Update the origin dialer service with the new dialer settings\n\t// We need to update the dialer here instead of creating a new instance of OriginDialerService because it has\n\t// its own references and go routines. Specifically, the UDP dialer is a reference to this same service all the\n\t// way into the datagram manager. Reconstructing the datagram manager is not something we currently provide during\n\t// runtime in response to a configuration push except when starting a tunnel connection.\n\to.originDialerService.UpdateDefaultDialer(ingress.NewDialer(warpRouting))\n\n\t// Create and replace the origin proxy with a new instance\n\tproxy := proxy.NewOriginProxy(ingressRules, o.originDialerService, o.tags, o.flowLimiter, o.log)\n\to.proxy.Store(proxy)\n\to.config.Ingress = &ingressRules\n\to.config.WarpRouting = warpRouting\n\n\t// If proxyShutdownC is nil, there is no previous running proxy\n\tif o.proxyShutdownC != nil {\n\t\tclose(o.proxyShutdownC)\n\t}\n\to.proxyShutdownC = proxyShutdownC\n\treturn nil\n}\n\n// GetConfigJSON returns the current json serialization of the config as the edge understands it\nfunc (o *Orchestrator) GetConfigJSON() ([]byte, error) {\n\to.lock.RLock()\n\tdefer o.lock.RUnlock()\n\n\tc := &newLocalConfig{\n\t\tRemoteConfig: ingress.RemoteConfig{\n\t\t\tIngress:     *o.config.Ingress,\n\t\t\tWarpRouting: o.config.WarpRouting,\n\t\t},\n\t\tConfigurationFlags: o.config.ConfigurationFlags,\n\t}\n\n\treturn json.Marshal(c)\n}\n\n// GetVersionedConfigJSON returns the current version and configuration as JSON\nfunc (o *Orchestrator) GetVersionedConfigJSON() ([]byte, error) {\n\to.lock.RLock()\n\tdefer o.lock.RUnlock()\n\tvar currentConfiguration = struct {\n\t\tVersion int32 `json:\"version\"`\n\t\tConfig  struct {\n\t\t\tIngress       []ingress.Rule              `json:\"ingress\"`\n\t\t\tWarpRouting   config.WarpRoutingConfig    `json:\"warp-routing\"`\n\t\t\tOriginRequest ingress.OriginRequestConfig `json:\"originRequest\"`\n\t\t} `json:\"config\"`\n\t}{\n\t\tVersion: o.currentVersion,\n\t\tConfig: struct {\n\t\t\tIngress       []ingress.Rule              `json:\"ingress\"`\n\t\t\tWarpRouting   config.WarpRoutingConfig    `json:\"warp-routing\"`\n\t\t\tOriginRequest ingress.OriginRequestConfig `json:\"originRequest\"`\n\t\t}{\n\t\t\tIngress:       o.config.Ingress.Rules,\n\t\t\tWarpRouting:   o.config.WarpRouting.RawConfig(),\n\t\t\tOriginRequest: o.config.Ingress.Defaults,\n\t\t},\n\t}\n\treturn json.Marshal(currentConfiguration)\n}\n\n// GetOriginProxy returns an interface to proxy to origin. It satisfies connection.ConfigManager interface\nfunc (o *Orchestrator) GetOriginProxy() (connection.OriginProxy, error) {\n\tval := o.proxy.Load()\n\tif val == nil {\n\t\terr := fmt.Errorf(\"origin proxy not configured\")\n\t\to.log.Error().Msg(err.Error())\n\t\treturn nil, err\n\t}\n\tproxy, ok := val.(connection.OriginProxy)\n\tif !ok {\n\t\terr := fmt.Errorf(\"origin proxy has unexpected value %+v\", val)\n\t\to.log.Error().Msg(err.Error())\n\t\treturn nil, err\n\t}\n\treturn proxy, nil\n}\n\n// GetFlowLimiter returns the flow limiter used across cloudflared, that can be hot reload when\n// the configuration changes.\nfunc (o *Orchestrator) GetFlowLimiter() cfdflow.Limiter {\n\treturn o.flowLimiter\n}\n\nfunc (o *Orchestrator) waitToCloseLastProxy() {\n\t<-o.shutdownC\n\to.lock.Lock()\n\tdefer o.lock.Unlock()\n\n\tif o.proxyShutdownC != nil {\n\t\tclose(o.proxyShutdownC)\n\t\to.proxyShutdownC = nil\n\t}\n}\n"
  },
  {
    "path": "orchestration/orchestrator_test.go",
    "content": "package orchestration\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/gobwas/ws/wsutil\"\n\t\"github.com/google/uuid\"\n\tgows \"github.com/gorilla/websocket\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/cloudflare/cloudflared/cmd/cloudflared/flags\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/connection\"\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\t\"github.com/cloudflare/cloudflared/management\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\nvar (\n\ttestLogger = zerolog.Nop()\n\ttestTags   = []pogs.Tag{\n\t\t{\n\t\t\tName:  \"package\",\n\t\t\tValue: \"orchestration\",\n\t\t},\n\t\t{\n\t\t\tName:  \"purpose\",\n\t\t\tValue: \"test\",\n\t\t},\n\t}\n\ttestDefaultDialer = ingress.NewDialer(ingress.WarpRoutingConfig{\n\t\tConnectTimeout: config.CustomDuration{Duration: 1 * time.Second},\n\t\tTCPKeepAlive:   config.CustomDuration{Duration: 15 * time.Second},\n\t\tMaxActiveFlows: 0,\n\t})\n)\n\n// TestUpdateConfiguration tests that\n// - configurations can be deserialized\n// - proxy can be updated\n// - last applied version and error are returned\n// - configurations can be deserialized\n// - receiving an old version is noop\nfunc TestUpdateConfiguration(t *testing.T) {\n\toriginDialer := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 1 * time.Second,\n\t}, &testLogger)\n\tinitConfig := &Config{\n\t\tIngress:             &ingress.Ingress{},\n\t\tOriginDialerService: originDialer,\n\t}\n\torchestrator, err := NewOrchestrator(t.Context(), initConfig, testTags, []ingress.Rule{ingress.NewManagementRule(management.New(\"management.argotunnel.com\", false, \"1.1.1.1:80\", uuid.Nil, \"\", &testLogger, nil))}, &testLogger)\n\trequire.NoError(t, err)\n\tinitOriginProxy, err := orchestrator.GetOriginProxy()\n\trequire.NoError(t, err)\n\trequire.Implements(t, (*connection.OriginProxy)(nil), initOriginProxy)\n\n\tconfigJSONV2 := []byte(`\n{\n\t\"unknown_field\": \"not_deserialized\",\n    \"originRequest\": {\n        \"connectTimeout\": 90,\n\t\t\"noHappyEyeballs\": true\n    },\n    \"ingress\": [\n        {\n            \"hostname\": \"jira.tunnel.org\",\n\t\t\t\"path\": \"^\\/login\",\n            \"service\": \"http://192.16.19.1:443\",\n            \"originRequest\": {\n                \"noTLSVerify\": true,\n                \"connectTimeout\": 10\n            }\n        },\n\t\t{\n            \"hostname\": \"jira.tunnel.org\",\n            \"service\": \"http://172.32.20.6:80\",\n            \"originRequest\": {\n                \"noTLSVerify\": true,\n                \"connectTimeout\": 30\n            }\n        },\n        {\n            \"service\": \"http_status:404\"\n        }\n    ],\n    \"warp-routing\": {\n        \"connectTimeout\": 10\n    }\n}\n`)\n\n\tupdateWithValidation(t, orchestrator, 2, configJSONV2)\n\tconfigV2 := orchestrator.config\n\t// Validate internal ingress rules\n\trequire.Equal(t, \"management.argotunnel.com\", configV2.Ingress.InternalRules[0].Hostname)\n\trequire.True(t, configV2.Ingress.InternalRules[0].Matches(\"management.argotunnel.com\", \"/ping\"))\n\trequire.Equal(t, \"management\", configV2.Ingress.InternalRules[0].Service.String())\n\t// Validate ingress rule 0\n\trequire.Equal(t, \"jira.tunnel.org\", configV2.Ingress.Rules[0].Hostname)\n\trequire.True(t, configV2.Ingress.Rules[0].Matches(\"jira.tunnel.org\", \"/login\"))\n\trequire.True(t, configV2.Ingress.Rules[0].Matches(\"jira.tunnel.org\", \"/login/2fa\"))\n\trequire.False(t, configV2.Ingress.Rules[0].Matches(\"jira.tunnel.org\", \"/users\"))\n\trequire.Equal(t, \"http://192.16.19.1:443\", configV2.Ingress.Rules[0].Service.String())\n\trequire.Len(t, configV2.Ingress.Rules, 3)\n\t// originRequest of this ingress rule overrides global default\n\trequire.Equal(t, config.CustomDuration{Duration: time.Second * 10}, configV2.Ingress.Rules[0].Config.ConnectTimeout)\n\trequire.True(t, configV2.Ingress.Rules[0].Config.NoTLSVerify)\n\t// Inherited from global default\n\trequire.True(t, configV2.Ingress.Rules[0].Config.NoHappyEyeballs)\n\t// Validate ingress rule 1\n\trequire.Equal(t, \"jira.tunnel.org\", configV2.Ingress.Rules[1].Hostname)\n\trequire.True(t, configV2.Ingress.Rules[1].Matches(\"jira.tunnel.org\", \"/users\"))\n\trequire.Equal(t, \"http://172.32.20.6:80\", configV2.Ingress.Rules[1].Service.String())\n\t// originRequest of this ingress rule overrides global default\n\trequire.Equal(t, config.CustomDuration{Duration: time.Second * 30}, configV2.Ingress.Rules[1].Config.ConnectTimeout)\n\trequire.True(t, configV2.Ingress.Rules[1].Config.NoTLSVerify)\n\t// Inherited from global default\n\trequire.True(t, configV2.Ingress.Rules[1].Config.NoHappyEyeballs)\n\t// Validate ingress rule 2, it's the catch-all rule\n\trequire.True(t, configV2.Ingress.Rules[2].Matches(\"blogs.tunnel.io\", \"/2022/02/10\"))\n\t// Inherited from global default\n\trequire.Equal(t, config.CustomDuration{Duration: time.Second * 90}, configV2.Ingress.Rules[2].Config.ConnectTimeout)\n\trequire.False(t, configV2.Ingress.Rules[2].Config.NoTLSVerify)\n\trequire.True(t, configV2.Ingress.Rules[2].Config.NoHappyEyeballs)\n\trequire.Equal(t, 10*time.Second, configV2.WarpRouting.ConnectTimeout.Duration)\n\n\toriginProxyV2, err := orchestrator.GetOriginProxy()\n\trequire.NoError(t, err)\n\trequire.Implements(t, (*connection.OriginProxy)(nil), originProxyV2)\n\trequire.NotEqual(t, originProxyV2, initOriginProxy)\n\n\t// Should not downgrade to an older version\n\tresp := orchestrator.UpdateConfig(1, nil)\n\trequire.NoError(t, resp.Err)\n\trequire.Equal(t, int32(2), resp.LastAppliedVersion)\n\n\tinvalidJSON := []byte(`\n{\n\t\"originRequest\":\n}\n\n`)\n\n\tresp = orchestrator.UpdateConfig(3, invalidJSON)\n\trequire.Error(t, resp.Err)\n\trequire.Equal(t, int32(2), resp.LastAppliedVersion)\n\toriginProxyV3, err := orchestrator.GetOriginProxy()\n\trequire.NoError(t, err)\n\trequire.Equal(t, originProxyV2, originProxyV3)\n\n\tconfigJSONV10 := []byte(`\n{\n    \"ingress\": [\n        {\n            \"service\": \"hello-world\"\n        }\n    ],\n    \"warp-routing\": {\n    }\n}\n`)\n\tupdateWithValidation(t, orchestrator, 10, configJSONV10)\n\tconfigV10 := orchestrator.config\n\trequire.Len(t, configV10.Ingress.Rules, 1)\n\trequire.True(t, configV10.Ingress.Rules[0].Matches(\"blogs.tunnel.io\", \"/2022/02/10\"))\n\trequire.Equal(t, ingress.HelloWorldService, configV10.Ingress.Rules[0].Service.String())\n\n\toriginProxyV10, err := orchestrator.GetOriginProxy()\n\trequire.NoError(t, err)\n\trequire.Implements(t, (*connection.OriginProxy)(nil), originProxyV10)\n\trequire.NotEqual(t, originProxyV10, originProxyV2)\n}\n\n// Validates that a new version 0 will be applied if the configuration is loaded locally.\n// This will happen when a locally managed tunnel is migrated to remote configuration and receives its first configuration.\nfunc TestUpdateConfiguration_FromMigration(t *testing.T) {\n\toriginDialer := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 1 * time.Second,\n\t}, &testLogger)\n\tinitConfig := &Config{\n\t\tIngress:             &ingress.Ingress{},\n\t\tOriginDialerService: originDialer,\n\t}\n\torchestrator, err := NewOrchestrator(t.Context(), initConfig, testTags, []ingress.Rule{}, &testLogger)\n\trequire.NoError(t, err)\n\tinitOriginProxy, err := orchestrator.GetOriginProxy()\n\trequire.NoError(t, err)\n\trequire.Implements(t, (*connection.OriginProxy)(nil), initOriginProxy)\n\n\tconfigJSONV2 := []byte(`\n{\n    \"ingress\": [\n        {\n            \"service\": \"http_status:404\"\n        }\n    ],\n    \"warp-routing\": {\n    }\n}\n`)\n\tupdateWithValidation(t, orchestrator, 0, configJSONV2)\n\trequire.Len(t, orchestrator.config.Ingress.Rules, 1)\n}\n\n// Validates that the default ingress rule will be set if there is no rule provided from the remote.\nfunc TestUpdateConfiguration_WithoutIngressRule(t *testing.T) {\n\toriginDialer := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 1 * time.Second,\n\t}, &testLogger)\n\tinitConfig := &Config{\n\t\tIngress:             &ingress.Ingress{},\n\t\tOriginDialerService: originDialer,\n\t}\n\torchestrator, err := NewOrchestrator(t.Context(), initConfig, testTags, []ingress.Rule{}, &testLogger)\n\trequire.NoError(t, err)\n\tinitOriginProxy, err := orchestrator.GetOriginProxy()\n\trequire.NoError(t, err)\n\trequire.Implements(t, (*connection.OriginProxy)(nil), initOriginProxy)\n\n\t// We need to create an empty RemoteConfigJSON because that will get unmarshalled to a RemoteConfig\n\temptyConfig := &ingress.RemoteConfigJSON{}\n\tconfigBytes, err := json.Marshal(emptyConfig)\n\tif err != nil {\n\t\trequire.FailNow(t, \"The RemoteConfigJSON shouldn't fail while being marshalled\")\n\t}\n\n\tupdateWithValidation(t, orchestrator, 0, configBytes)\n\trequire.Len(t, orchestrator.config.Ingress.Rules, 1)\n}\n\n// TestConcurrentUpdateAndRead makes sure orchestrator can receive updates and return origin proxy concurrently\nfunc TestConcurrentUpdateAndRead(t *testing.T) {\n\tconst (\n\t\tconcurrentRequests = 200\n\t\thostname           = \"public.tunnels.org\"\n\t\texpectedHost       = \"internal.tunnels.svc.cluster.local\"\n\t\ttcpBody            = \"testProxyTCP\"\n\t)\n\n\thttpOrigin := httptest.NewServer(&validateHostHandler{\n\t\texpectedHost: expectedHost,\n\t\tbody:         t.Name(),\n\t})\n\tdefer httpOrigin.Close()\n\n\ttcpOrigin, err := net.Listen(\"tcp\", \"127.0.0.1:0\")\n\trequire.NoError(t, err)\n\tdefer tcpOrigin.Close()\n\n\toriginDialer := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 1 * time.Second,\n\t}, &testLogger)\n\n\tvar (\n\t\tconfigJSONV1 = []byte(fmt.Sprintf(`\n{\n    \"originRequest\": {\n        \"connectTimeout\": 90,\n\t\t\"noHappyEyeballs\": true\n    },\n    \"ingress\": [\n        {\n            \"hostname\": \"%s\",\n            \"service\": \"%s\",\n            \"originRequest\": {\n\t\t\t\t\"httpHostHeader\": \"%s\",\n                \"connectTimeout\": 10\n            }\n        },\n        {\n            \"service\": \"http_status:404\"\n        }\n    ],\n    \"warp-routing\": {\n    }\n}\n`, hostname, httpOrigin.URL, expectedHost))\n\t\tconfigJSONV2 = []byte(`\n{\n    \"ingress\": [\n        {\n            \"service\": \"http_status:204\"\n        }\n    ],\n    \"warp-routing\": {\n    }\n}\n`)\n\n\t\tconfigJSONV3 = []byte(`\n{\n    \"ingress\": [\n        {\n            \"service\": \"http_status:418\"\n        }\n    ],\n    \"warp-routing\": {\n    }\n}\n`)\n\n\t\t// appliedV2 makes sure v3 is applied after v2\n\t\tappliedV2 = make(chan struct{})\n\n\t\tinitConfig = &Config{\n\t\t\tIngress:             &ingress.Ingress{},\n\t\t\tOriginDialerService: originDialer,\n\t\t}\n\t)\n\n\tctx, cancel := context.WithCancel(t.Context())\n\tdefer cancel()\n\n\torchestrator, err := NewOrchestrator(ctx, initConfig, testTags, []ingress.Rule{}, &testLogger)\n\trequire.NoError(t, err)\n\n\tupdateWithValidation(t, orchestrator, 1, configJSONV1)\n\n\tvar wg sync.WaitGroup\n\t// tcpOrigin will be closed when the test exits. Only the handler routines are included in the wait group\n\tgo func() {\n\t\tserveTCPOrigin(t, tcpOrigin, &wg)\n\t}()\n\tfor i := range concurrentRequests {\n\t\toriginProxy, err := orchestrator.GetOriginProxy()\n\t\trequire.NoError(t, err)\n\t\twg.Add(1)\n\t\tgo func(i int, originProxy connection.OriginProxy) {\n\t\t\tdefer wg.Done()\n\t\t\tresp, err := proxyHTTP(originProxy, hostname)\n\t\t\tassert.NoError(t, err, \"proxyHTTP %d failed %v\", i, err)\n\t\t\tdefer resp.Body.Close()\n\n\t\t\t// The response can be from initOrigin, http_status:204 or http_status:418\n\t\t\tswitch resp.StatusCode {\n\t\t\t// v1 proxy\n\t\t\tcase 200:\n\t\t\t\tbody, err := io.ReadAll(resp.Body)\n\t\t\t\tassert.NoError(t, err)\n\t\t\t\tassert.Equal(t, t.Name(), string(body))\n\t\t\t// v2 proxy\n\t\t\tcase 204:\n\t\t\t\tassert.Greater(t, i, concurrentRequests/4)\n\t\t\t// v3 proxy\n\t\t\tcase 418:\n\t\t\t\tassert.Greater(t, i, concurrentRequests/2)\n\t\t\t}\n\n\t\t\t// Once we have originProxy, it won't be changed by configuration updates.\n\t\t\t// We can infer the version by the ProxyHTTP response code\n\t\t\tpr, pw := io.Pipe()\n\t\t\tw := newRespReadWriteFlusher()\n\n\t\t\t// Write TCP message and make sure it's echo back. This has to be done in a go routune since ProxyTCP doesn't\n\t\t\t// return until the stream is closed.\n\t\t\twg.Add(1)\n\t\t\tgo func() {\n\t\t\t\tdefer wg.Done()\n\t\t\t\tdefer pw.Close()\n\t\t\t\ttcpEyeball(t, pw, tcpBody, w)\n\t\t\t}()\n\n\t\t\terr = proxyTCP(ctx, originProxy, tcpOrigin.Addr().String(), w, pr)\n\t\t\tassert.NoError(t, err, \"proxyTCP %d failed %v\", i, err)\n\t\t}(i, originProxy)\n\n\t\tif i == concurrentRequests/4 {\n\t\t\twg.Add(1)\n\t\t\tgo func() {\n\t\t\t\tdefer wg.Done()\n\t\t\t\tupdateWithValidation(t, orchestrator, 2, configJSONV2)\n\t\t\t\tclose(appliedV2)\n\t\t\t}()\n\t\t}\n\n\t\tif i == concurrentRequests/2 {\n\t\t\twg.Add(1)\n\t\t\tgo func() {\n\t\t\t\tdefer wg.Done()\n\t\t\t\t// Makes sure v2 is applied before v3\n\t\t\t\t<-appliedV2\n\t\t\t\tupdateWithValidation(t, orchestrator, 3, configJSONV3)\n\t\t\t}()\n\t\t}\n\t}\n\n\twg.Wait()\n}\n\n// TestOverrideWarpRoutingConfigWithLocalValues tests that if a value is defined in the Config.ConfigurationFlags,\n// it will override the value that comes from the remote result.\nfunc TestOverrideWarpRoutingConfigWithLocalValues(t *testing.T) {\n\tctx, cancel := context.WithCancel(t.Context())\n\tdefer cancel()\n\n\tassertMaxActiveFlows := func(orchestrator *Orchestrator, expectedValue uint64) {\n\t\tconfigJson, err := orchestrator.GetConfigJSON()\n\t\trequire.NoError(t, err)\n\t\tvar result map[string]interface{}\n\t\terr = json.Unmarshal(configJson, &result)\n\t\trequire.NoError(t, err)\n\t\twarpRouting := result[\"warp-routing\"].(map[string]interface{})\n\t\trequire.EqualValues(t, expectedValue, warpRouting[\"maxActiveFlows\"])\n\t}\n\n\toriginDialer := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 1 * time.Second,\n\t}, &testLogger)\n\n\t// All the possible values set for MaxActiveFlows from the various points that can provide it:\n\t// 1. Initialized value\n\t// 2. Local CLI flag config\n\t// 3. Remote configuration value\n\tinitValue := uint64(0)\n\tlocalValue := uint64(100)\n\tremoteValue := uint64(500)\n\n\tinitConfig := &Config{\n\t\tIngress: &ingress.Ingress{},\n\t\tWarpRouting: ingress.WarpRoutingConfig{\n\t\t\tMaxActiveFlows: initValue,\n\t\t},\n\t\tOriginDialerService: originDialer,\n\t\tConfigurationFlags: map[string]string{\n\t\t\tflags.MaxActiveFlows: fmt.Sprintf(\"%d\", localValue),\n\t\t},\n\t}\n\n\t// We expect the local configuration flag to be the starting value\n\torchestrator, err := NewOrchestrator(ctx, initConfig, testTags, []ingress.Rule{}, &testLogger)\n\trequire.NoError(t, err)\n\n\tassertMaxActiveFlows(orchestrator, localValue)\n\n\t// Assigning the MaxActiveFlows in the remote config should be ignored over the local config\n\tremoteWarpConfig := ingress.WarpRoutingConfig{\n\t\tMaxActiveFlows: remoteValue,\n\t}\n\n\t// Force a configuration refresh\n\terr = orchestrator.updateIngress(ingress.Ingress{}, remoteWarpConfig)\n\trequire.NoError(t, err)\n\n\t// Check the value being used is the local one\n\tassertMaxActiveFlows(orchestrator, localValue)\n}\n\nfunc proxyHTTP(originProxy connection.OriginProxy, hostname string) (*http.Response, error) {\n\treq, err := http.NewRequest(http.MethodGet, fmt.Sprintf(\"http://%s\", hostname), nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tw := httptest.NewRecorder()\n\tlog := zerolog.Nop()\n\trespWriter, err := connection.NewHTTP2RespWriter(req, w, connection.TypeHTTP, &log)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\terr = originProxy.ProxyHTTP(respWriter, tracing.NewTracedHTTPRequest(req, 0, &log), false)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn w.Result(), nil\n}\n\n// nolint: testifylint // this is used inside go routines so it can't use `require.`\nfunc tcpEyeball(t *testing.T, reqWriter io.WriteCloser, body string, respReadWriter *respReadWriteFlusher) {\n\twriteN, err := reqWriter.Write([]byte(body))\n\tassert.NoError(t, err)\n\n\treadBuffer := make([]byte, writeN)\n\tn, err := respReadWriter.Read(readBuffer)\n\tassert.NoError(t, err)\n\tassert.Equal(t, body, string(readBuffer[:n]))\n\tassert.Equal(t, writeN, n)\n}\n\nfunc proxyTCP(ctx context.Context, originProxy connection.OriginProxy, originAddr string, w http.ResponseWriter, reqBody io.ReadCloser) error {\n\treq, err := http.NewRequest(http.MethodGet, fmt.Sprintf(\"http://%s\", originAddr), reqBody)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tlog := zerolog.Nop()\n\trespWriter, err := connection.NewHTTP2RespWriter(req, w, connection.TypeTCP, &log)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ttcpReq := &connection.TCPRequest{\n\t\tDest:    originAddr,\n\t\tCFRay:   \"123\",\n\t\tLBProbe: false,\n\t}\n\trws := connection.NewHTTPResponseReadWriterAcker(respWriter, w.(http.Flusher), req)\n\n\treturn originProxy.ProxyTCP(ctx, rws, tcpReq)\n}\n\nfunc serveTCPOrigin(t *testing.T, tcpOrigin net.Listener, wg *sync.WaitGroup) {\n\tfor {\n\t\tconn, err := tcpOrigin.Accept()\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\twg.Add(1)\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\tdefer conn.Close()\n\n\t\t\techoTCP(t, conn)\n\t\t}()\n\t}\n}\n\n// nolint: testifylint // this is used inside go routines so it can't use `require.`\nfunc echoTCP(t *testing.T, conn net.Conn) {\n\treadBuf := make([]byte, 1000)\n\treadN, err := conn.Read(readBuf)\n\tassert.NoError(t, err)\n\n\twriteN, err := conn.Write(readBuf[:readN])\n\tassert.NoError(t, err)\n\tassert.Equal(t, readN, writeN)\n}\n\ntype validateHostHandler struct {\n\texpectedHost string\n\tbody         string\n}\n\nfunc (vhh *validateHostHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tif r.Host != vhh.expectedHost {\n\t\tw.WriteHeader(http.StatusBadRequest)\n\t\treturn\n\t}\n\tw.WriteHeader(http.StatusOK)\n\t_, _ = w.Write([]byte(vhh.body))\n}\n\n// nolint: testifylint // this is used inside go routines so it can't use `require.`\nfunc updateWithValidation(t *testing.T, orchestrator *Orchestrator, version int32, config []byte) {\n\tresp := orchestrator.UpdateConfig(version, config)\n\tassert.NoError(t, resp.Err)\n\tassert.Equal(t, version, resp.LastAppliedVersion)\n}\n\n// TestClosePreviousProxies makes sure proxies started in the previous configuration version are shutdown\nfunc TestClosePreviousProxies(t *testing.T) {\n\toriginDialer := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 1 * time.Second,\n\t}, &testLogger)\n\tvar (\n\t\thostname             = \"hello.tunnel1.org\"\n\t\tconfigWithHelloWorld = []byte(fmt.Sprintf(`\n{\n    \"ingress\": [\n        {\n\t\t\t\"hostname\": \"%s\",\n            \"service\": \"hello-world\"\n        },\n\t\t{\n\t\t\t\"service\": \"http_status:404\"\n\t\t}\n    ],\n    \"warp-routing\": {\n    }\n}\n`, hostname))\n\n\t\tconfigTeapot = []byte(`\n{\n    \"ingress\": [\n\t\t{\n\t\t\t\"service\": \"http_status:418\"\n\t\t}\n    ],\n    \"warp-routing\": {\n    }\n}\n`)\n\t\tinitConfig = &Config{\n\t\t\tIngress:             &ingress.Ingress{},\n\t\t\tOriginDialerService: originDialer,\n\t\t}\n\t)\n\n\tctx, cancel := context.WithCancel(t.Context())\n\torchestrator, err := NewOrchestrator(ctx, initConfig, testTags, []ingress.Rule{}, &testLogger)\n\trequire.NoError(t, err)\n\n\tupdateWithValidation(t, orchestrator, 1, configWithHelloWorld)\n\n\toriginProxyV1, err := orchestrator.GetOriginProxy()\n\trequire.NoError(t, err)\n\t// nolint: bodyclose\n\tresp, err := proxyHTTP(originProxyV1, hostname)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusOK, resp.StatusCode)\n\n\tupdateWithValidation(t, orchestrator, 2, configTeapot)\n\n\toriginProxyV2, err := orchestrator.GetOriginProxy()\n\trequire.NoError(t, err)\n\t// nolint: bodyclose\n\tresp, err = proxyHTTP(originProxyV2, hostname)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusTeapot, resp.StatusCode)\n\n\t// The hello-world server in config v1 should have been stopped. We wait a bit since it's closed asynchronously.\n\ttime.Sleep(time.Millisecond * 10)\n\t// nolint: bodyclose\n\tresp, err = proxyHTTP(originProxyV1, hostname)\n\trequire.Error(t, err)\n\trequire.Nil(t, resp)\n\n\t// Apply the config with hello world server again, orchestrator should spin up another hello world server\n\tupdateWithValidation(t, orchestrator, 3, configWithHelloWorld)\n\n\toriginProxyV3, err := orchestrator.GetOriginProxy()\n\trequire.NoError(t, err)\n\trequire.NotEqual(t, originProxyV1, originProxyV3)\n\n\t// nolint: bodyclose\n\tresp, err = proxyHTTP(originProxyV3, hostname)\n\trequire.NoError(t, err)\n\trequire.Equal(t, http.StatusOK, resp.StatusCode)\n\n\t// cancel the context should terminate the last proxy\n\tcancel()\n\t// Wait for proxies to shutdown\n\ttime.Sleep(time.Millisecond * 10)\n\n\t// nolint: bodyclose\n\tresp, err = proxyHTTP(originProxyV3, hostname)\n\trequire.Error(t, err)\n\trequire.Nil(t, resp)\n}\n\n// TestPersistentConnection makes sure updating the ingress doesn't intefere with existing connections\nfunc TestPersistentConnection(t *testing.T) {\n\tconst (\n\t\thostname = \"http://ws.tunnel.org\"\n\t)\n\tmsg := t.Name()\n\toriginDialer := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 1 * time.Second,\n\t}, &testLogger)\n\tinitConfig := &Config{\n\t\tIngress:             &ingress.Ingress{},\n\t\tOriginDialerService: originDialer,\n\t}\n\torchestrator, err := NewOrchestrator(t.Context(), initConfig, testTags, []ingress.Rule{}, &testLogger)\n\trequire.NoError(t, err)\n\n\twsOrigin := httptest.NewServer(http.HandlerFunc(wsEcho))\n\tdefer wsOrigin.Close()\n\n\ttcpOrigin, err := net.Listen(\"tcp\", \"127.0.0.1:0\")\n\trequire.NoError(t, err)\n\tdefer tcpOrigin.Close()\n\n\tconfigWithWSAndWarp := []byte(fmt.Sprintf(`\n{\n    \"ingress\": [\n        {\n            \"service\": \"%s\"\n        }\n    ],\n    \"warp-routing\": {\n    }\n}\n`, wsOrigin.URL))\n\n\tupdateWithValidation(t, orchestrator, 1, configWithWSAndWarp)\n\n\toriginProxy, err := orchestrator.GetOriginProxy()\n\trequire.NoError(t, err)\n\n\twsReqReader, wsReqWriter := io.Pipe()\n\twsRespReadWriter := newRespReadWriteFlusher()\n\n\ttcpReqReader, tcpReqWriter := io.Pipe()\n\ttcpRespReadWriter := newRespReadWriteFlusher()\n\n\tctx, cancel := context.WithCancel(t.Context())\n\tdefer cancel()\n\n\tvar wg sync.WaitGroup\n\twg.Add(3)\n\t// Start TCP origin\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tconn, err := tcpOrigin.Accept()\n\t\tassert.NoError(t, err)\n\t\tdefer conn.Close()\n\n\t\t// Expect 3 TCP messages\n\t\tfor i := 0; i < 3; i++ {\n\t\t\techoTCP(t, conn)\n\t\t}\n\t}()\n\t// Simulate cloudflared receiving a TCP connection\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tassert.NoError(t, proxyTCP(ctx, originProxy, tcpOrigin.Addr().String(), tcpRespReadWriter, tcpReqReader))\n\t}()\n\t// Simulate cloudflared receiving a WS connection\n\tgo func() {\n\t\tdefer wg.Done()\n\n\t\treq, err := http.NewRequest(http.MethodGet, hostname, wsReqReader)\n\t\tassert.NoError(t, err)\n\t\t// ProxyHTTP will add Connection, Upgrade and Sec-Websocket-Version headers\n\t\treq.Header.Add(\"Sec-WebSocket-Key\", \"dGhlIHNhbXBsZSBub25jZQ==\")\n\n\t\tlog := zerolog.Nop()\n\t\trespWriter, err := connection.NewHTTP2RespWriter(req, wsRespReadWriter, connection.TypeWebsocket, &log)\n\t\tassert.NoError(t, err)\n\n\t\terr = originProxy.ProxyHTTP(respWriter, tracing.NewTracedHTTPRequest(req, 0, &log), true)\n\t\tassert.NoError(t, err)\n\t}()\n\n\t// Simulate eyeball WS and TCP connections\n\tvalidateWsEcho(t, msg, wsReqWriter, wsRespReadWriter)\n\ttcpEyeball(t, tcpReqWriter, msg, tcpRespReadWriter)\n\n\tconfigNoWSAndWarp := []byte(`\n{\n    \"ingress\": [\n        {\n            \"service\": \"http_status:404\"\n        }\n    ],\n    \"warp-routing\": {\n    }\n}\n`)\n\n\tupdateWithValidation(t, orchestrator, 2, configNoWSAndWarp)\n\t// Make sure connection is still up\n\tvalidateWsEcho(t, msg, wsReqWriter, wsRespReadWriter)\n\ttcpEyeball(t, tcpReqWriter, msg, tcpRespReadWriter)\n\n\tupdateWithValidation(t, orchestrator, 3, configWithWSAndWarp)\n\t// Make sure connection is still up\n\tvalidateWsEcho(t, msg, wsReqWriter, wsRespReadWriter)\n\ttcpEyeball(t, tcpReqWriter, msg, tcpRespReadWriter)\n\n\twsReqWriter.Close()\n\ttcpReqWriter.Close()\n\twg.Wait()\n}\n\nfunc TestSerializeLocalConfig(t *testing.T) {\n\tc := &newLocalConfig{\n\t\tRemoteConfig: ingress.RemoteConfig{\n\t\t\tIngress: ingress.Ingress{},\n\t\t},\n\t\tConfigurationFlags: map[string]string{\"a\": \"b\"},\n\t}\n\n\tresult, err := json.Marshal(c)\n\trequire.NoError(t, err)\n\trequire.JSONEq(t, `{\"__configuration_flags\":{\"a\":\"b\"},\"ingress\":[],\"warp-routing\":{\"connectTimeout\":0,\"tcpKeepAlive\":0}}`, string(result))\n}\n\nfunc wsEcho(w http.ResponseWriter, r *http.Request) {\n\tupgrader := gows.Upgrader{}\n\n\tconn, err := upgrader.Upgrade(w, r, nil)\n\tif err != nil {\n\t\treturn\n\t}\n\tdefer conn.Close()\n\tfor {\n\t\tmt, message, err := conn.ReadMessage()\n\t\tif err != nil {\n\t\t\tfmt.Println(\"read message err\", err)\n\t\t\tbreak\n\t\t}\n\t\terr = conn.WriteMessage(mt, message)\n\t\tif err != nil {\n\t\t\tfmt.Println(\"write message err\", err)\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc validateWsEcho(t *testing.T, msg string, reqWriter io.Writer, respReadWriter io.ReadWriter) {\n\terr := wsutil.WriteClientText(reqWriter, []byte(msg))\n\trequire.NoError(t, err)\n\n\treceivedMsg, err := wsutil.ReadServerText(respReadWriter)\n\trequire.NoError(t, err)\n\trequire.Equal(t, msg, string(receivedMsg))\n}\n\ntype respReadWriteFlusher struct {\n\tio.Reader\n\tw             io.Writer\n\theaders       http.Header\n\tstatusCode    int\n\tsetStatusOnce sync.Once\n\thasStatus     chan struct{}\n}\n\nfunc newRespReadWriteFlusher() *respReadWriteFlusher {\n\tpr, pw := io.Pipe()\n\treturn &respReadWriteFlusher{\n\t\tReader:    pr,\n\t\tw:         pw,\n\t\theaders:   make(http.Header),\n\t\thasStatus: make(chan struct{}),\n\t}\n}\n\nfunc (rrw *respReadWriteFlusher) Write(buf []byte) (int, error) {\n\trrw.WriteHeader(http.StatusOK)\n\treturn rrw.w.Write(buf)\n}\n\nfunc (rrw *respReadWriteFlusher) Flush() {}\n\nfunc (rrw *respReadWriteFlusher) Header() http.Header {\n\treturn rrw.headers\n}\n\nfunc (rrw *respReadWriteFlusher) WriteHeader(statusCode int) {\n\trrw.setStatusOnce.Do(func() {\n\t\trrw.statusCode = statusCode\n\t\tclose(rrw.hasStatus)\n\t})\n}\n"
  },
  {
    "path": "overwatch/app_manager.go",
    "content": "package overwatch\n\n// ServiceCallback is a service notify it's runloop finished.\n// the first parameter is the service type\n// the second parameter is the service name\n// the third parameter is an optional error if the service failed\ntype ServiceCallback func(string, string, error)\n\n// AppManager is the default implementation of overwatch service management\ntype AppManager struct {\n\tservices map[string]Service\n\tcallback ServiceCallback\n}\n\n// NewAppManager creates a new overwatch manager\nfunc NewAppManager(callback ServiceCallback) Manager {\n\treturn &AppManager{services: make(map[string]Service), callback: callback}\n}\n\n// Add takes in a new service to manage.\n// It stops the service if it already exist in the manager and is running\n// It then starts the newly added service\nfunc (m *AppManager) Add(service Service) {\n\t// check for existing service\n\tif currentService, ok := m.services[service.Name()]; ok {\n\t\tif currentService.Hash() == service.Hash() {\n\t\t\treturn // the exact same service, no changes, so move along\n\t\t}\n\t\tcurrentService.Shutdown() //shutdown the listener since a new one is starting\n\t}\n\tm.services[service.Name()] = service\n\n\t//start the service!\n\tgo m.serviceRun(service)\n}\n\n// Remove shutdowns the service by name and removes it from its current management list\nfunc (m *AppManager) Remove(name string) {\n\tif currentService, ok := m.services[name]; ok {\n\t\tcurrentService.Shutdown()\n\t}\n\tdelete(m.services, name)\n}\n\n// Services returns all the current Services being managed\nfunc (m *AppManager) Services() []Service {\n\tvalues := []Service{}\n\tfor _, value := range m.services {\n\t\tvalues = append(values, value)\n\t}\n\treturn values\n}\n\nfunc (m *AppManager) serviceRun(service Service) {\n\terr := service.Run()\n\tif m.callback != nil {\n\t\tm.callback(service.Type(), service.Name(), err)\n\t}\n}\n"
  },
  {
    "path": "overwatch/manager.go",
    "content": "package overwatch\n\n// Service is the required functions for an object to be managed by the overwatch Manager\ntype Service interface {\n\tName() string\n\tType() string\n\tHash() string\n\tShutdown()\n\tRun() error\n}\n\n// Manager is based type to manage running services\ntype Manager interface {\n\tAdd(Service)\n\tRemove(string)\n\tServices() []Service\n}\n"
  },
  {
    "path": "overwatch/manager_test.go",
    "content": "package overwatch\n\nimport (\n\t\"crypto/md5\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\ntype mockService struct {\n\tserviceName string\n\tserviceType string\n\trunError    error\n}\n\nfunc (s *mockService) Name() string {\n\treturn s.serviceName\n}\n\nfunc (s *mockService) Type() string {\n\treturn s.serviceType\n}\n\nfunc (s *mockService) Hash() string {\n\th := md5.New()\n\tio.WriteString(h, s.serviceName)\n\tio.WriteString(h, s.serviceType)\n\treturn fmt.Sprintf(\"%x\", h.Sum(nil))\n}\n\nfunc (s *mockService) Shutdown() {\n}\n\nfunc (s *mockService) Run() error {\n\treturn s.runError\n}\n\nfunc TestManagerAddAndRemove(t *testing.T) {\n\tm := NewAppManager(nil)\n\n\tfirst := &mockService{serviceName: \"first\", serviceType: \"mock\"}\n\tsecond := &mockService{serviceName: \"second\", serviceType: \"mock\"}\n\tm.Add(first)\n\tm.Add(second)\n\tassert.Len(t, m.Services(), 2, \"expected 2 services in the list\")\n\n\tm.Remove(first.Name())\n\tservices := m.Services()\n\tassert.Len(t, services, 1, \"expected 1 service in the list\")\n\tassert.Equal(t, second.Hash(), services[0].Hash(), \"hashes should match. Wrong service was removed\")\n}\n\nfunc TestManagerDuplicate(t *testing.T) {\n\tm := NewAppManager(nil)\n\n\tfirst := &mockService{serviceName: \"first\", serviceType: \"mock\"}\n\tm.Add(first)\n\tm.Add(first)\n\tassert.Len(t, m.Services(), 1, \"expected 1 service in the list\")\n}\n\nfunc TestManagerErrorChannel(t *testing.T) {\n\terrChan := make(chan error)\n\tserviceCallback := func(t string, name string, err error) {\n\t\terrChan <- err\n\t}\n\tm := NewAppManager(serviceCallback)\n\n\terr := errors.New(\"test error\")\n\tfirst := &mockService{serviceName: \"first\", serviceType: \"mock\", runError: err}\n\tm.Add(first)\n\trespErr := <-errChan\n\tassert.Equal(t, err, respErr, \"errors don't match\")\n}\n"
  },
  {
    "path": "packet/decoder.go",
    "content": "package packet\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/google/gopacket\"\n\t\"github.com/google/gopacket/layers\"\n\t\"github.com/pkg/errors\"\n\t\"golang.org/x/net/icmp\"\n)\n\nfunc FindProtocol(p []byte) (layers.IPProtocol, error) {\n\tversion, err := FindIPVersion(p)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tswitch version {\n\tcase 4:\n\t\tif len(p) < ipv4MinHeaderLen {\n\t\t\treturn 0, fmt.Errorf(\"IPv4 packet should have at least %d bytes, got %d bytes\", ipv4MinHeaderLen, len(p))\n\t\t}\n\t\t// Protocol is in the 10th byte of IPv4 header\n\t\treturn layers.IPProtocol(p[9]), nil\n\tcase 6:\n\t\tif len(p) < ipv6HeaderLen {\n\t\t\treturn 0, fmt.Errorf(\"IPv6 packet should have at least %d bytes, got %d bytes\", ipv6HeaderLen, len(p))\n\t\t}\n\t\t// Next header is in the 7th byte of IPv6 header\n\t\treturn layers.IPProtocol(p[6]), nil\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"unknown ip version %d\", version)\n\t}\n}\n\nfunc FindIPVersion(p []byte) (uint8, error) {\n\tif len(p) == 0 {\n\t\treturn 0, fmt.Errorf(\"packet length is 0\")\n\t}\n\treturn p[0] >> 4, nil\n}\n\n// IPDecoder decodes raw packets into IP. It can process packets sequentially without allocating\n// memory for the layers, so it cannot be called concurrently.\ntype IPDecoder struct {\n\tipv4   *layers.IPv4\n\tipv6   *layers.IPv6\n\tlayers uint8\n\n\tv4parser *gopacket.DecodingLayerParser\n\tv6parser *gopacket.DecodingLayerParser\n}\n\nfunc NewIPDecoder() *IPDecoder {\n\tvar (\n\t\tipv4 layers.IPv4\n\t\tipv6 layers.IPv6\n\t)\n\tdlpv4 := gopacket.NewDecodingLayerParser(layers.LayerTypeIPv4)\n\tdlpv4.SetDecodingLayerContainer(gopacket.DecodingLayerSparse(nil))\n\tdlpv4.AddDecodingLayer(&ipv4)\n\t// Stop parsing when it encounter a layer that it doesn't have a parser\n\tdlpv4.IgnoreUnsupported = true\n\n\tdlpv6 := gopacket.NewDecodingLayerParser(layers.LayerTypeIPv6)\n\tdlpv6.SetDecodingLayerContainer(gopacket.DecodingLayerSparse(nil))\n\tdlpv6.AddDecodingLayer(&ipv6)\n\tdlpv6.IgnoreUnsupported = true\n\n\treturn &IPDecoder{\n\t\tipv4:     &ipv4,\n\t\tipv6:     &ipv6,\n\t\tlayers:   1,\n\t\tv4parser: dlpv4,\n\t\tv6parser: dlpv6,\n\t}\n}\n\nfunc (pd *IPDecoder) Decode(packet RawPacket) (*IP, error) {\n\t// Should decode to IP layer\n\tdecoded, err := pd.decodeByVersion(packet.Data)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, layerType := range decoded {\n\t\tswitch layerType {\n\t\tcase layers.LayerTypeIPv4:\n\t\t\treturn newIPv4(pd.ipv4)\n\t\tcase layers.LayerTypeIPv6:\n\t\t\treturn newIPv6(pd.ipv6)\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"no ip layer is decoded\")\n}\n\nfunc (pd *IPDecoder) decodeByVersion(packet []byte) ([]gopacket.LayerType, error) {\n\tversion, err := FindIPVersion(packet)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdecoded := make([]gopacket.LayerType, 0, pd.layers)\n\tswitch version {\n\tcase 4:\n\t\terr = pd.v4parser.DecodeLayers(packet, &decoded)\n\tcase 6:\n\t\terr = pd.v6parser.DecodeLayers(packet, &decoded)\n\tdefault:\n\t\terr = fmt.Errorf(\"unknown ip version %d\", version)\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn decoded, nil\n}\n\n// ICMPDecoder decodes raw packets into IP and ICMP. It can process packets sequentially without allocating\n// memory for the layers, so it cannot be called concurrently.\ntype ICMPDecoder struct {\n\t*IPDecoder\n\ticmpv4 *layers.ICMPv4\n\ticmpv6 *layers.ICMPv6\n}\n\nfunc NewICMPDecoder() *ICMPDecoder {\n\tipDecoder := NewIPDecoder()\n\n\tvar (\n\t\ticmpv4 layers.ICMPv4\n\t\ticmpv6 layers.ICMPv6\n\t)\n\tipDecoder.layers++\n\tipDecoder.v4parser.AddDecodingLayer(&icmpv4)\n\tipDecoder.v6parser.AddDecodingLayer(&icmpv6)\n\n\treturn &ICMPDecoder{\n\t\tIPDecoder: ipDecoder,\n\t\ticmpv4:    &icmpv4,\n\t\ticmpv6:    &icmpv6,\n\t}\n}\n\nfunc (pd *ICMPDecoder) Decode(packet RawPacket) (*ICMP, error) {\n\t// Should decode to IP and optionally ICMP layer\n\tdecoded, err := pd.decodeByVersion(packet.Data)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, layerType := range decoded {\n\t\tswitch layerType {\n\t\tcase layers.LayerTypeICMPv4:\n\t\t\tipv4, err := newIPv4(pd.ipv4)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tmsg, err := icmp.ParseMessage(int(layers.IPProtocolICMPv4), append(pd.icmpv4.Contents, pd.icmpv4.Payload...))\n\t\t\tif err != nil {\n\t\t\t\treturn nil, errors.Wrap(err, \"failed to parse ICMPv4 message\")\n\t\t\t}\n\t\t\treturn &ICMP{\n\t\t\t\tIP:      ipv4,\n\t\t\t\tMessage: msg,\n\t\t\t}, nil\n\t\tcase layers.LayerTypeICMPv6:\n\t\t\tipv6, err := newIPv6(pd.ipv6)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tmsg, err := icmp.ParseMessage(int(layers.IPProtocolICMPv6), append(pd.icmpv6.Contents, pd.icmpv6.Payload...))\n\t\t\tif err != nil {\n\t\t\t\treturn nil, errors.Wrap(err, \"failed to parse ICMPv6\")\n\t\t\t}\n\t\t\treturn &ICMP{\n\t\t\t\tIP:      ipv6,\n\t\t\t\tMessage: msg,\n\t\t\t}, nil\n\t\t}\n\t}\n\tlayers := make([]string, len(decoded))\n\tfor i, l := range decoded {\n\t\tlayers[i] = l.String()\n\t}\n\treturn nil, fmt.Errorf(\"Expect to decode IP and ICMP layers, got %s\", layers)\n}\n"
  },
  {
    "path": "packet/decoder_test.go",
    "content": "package packet\n\nimport (\n\t\"net\"\n\t\"net/netip\"\n\t\"testing\"\n\n\t\"github.com/google/gopacket\"\n\t\"github.com/google/gopacket/layers\"\n\t\"github.com/stretchr/testify/require\"\n\t\"golang.org/x/net/icmp\"\n\t\"golang.org/x/net/ipv4\"\n\t\"golang.org/x/net/ipv6\"\n)\n\nfunc TestDecodeIP(t *testing.T) {\n\tipDecoder := NewIPDecoder()\n\ticmpDecoder := NewICMPDecoder()\n\tudps := []UDP{\n\t\t{\n\t\t\tIP: IP{\n\t\t\t\tSrc:      netip.MustParseAddr(\"172.16.0.1\"),\n\t\t\t\tDst:      netip.MustParseAddr(\"10.0.0.1\"),\n\t\t\t\tProtocol: layers.IPProtocolUDP,\n\t\t\t},\n\t\t\tSrcPort: 31678,\n\t\t\tDstPort: 53,\n\t\t},\n\t\t{\n\n\t\t\tIP: IP{\n\t\t\t\tSrc:      netip.MustParseAddr(\"fd51:2391:523:f4ee::1\"),\n\t\t\t\tDst:      netip.MustParseAddr(\"fd51:2391:697:f4ee::2\"),\n\t\t\t\tProtocol: layers.IPProtocolUDP,\n\t\t\t},\n\t\t\tSrcPort: 52139,\n\t\t\tDstPort: 1053,\n\t\t},\n\t}\n\n\tencoder := NewEncoder()\n\tfor _, udp := range udps {\n\t\tp, err := encoder.Encode(&udp)\n\t\trequire.NoError(t, err)\n\n\t\tipPacket, err := ipDecoder.Decode(p)\n\t\trequire.NoError(t, err)\n\t\tassertIPLayer(t, &udp.IP, ipPacket)\n\n\t\ticmpPacket, err := icmpDecoder.Decode(p)\n\t\trequire.Error(t, err)\n\t\trequire.Nil(t, icmpPacket)\n\t}\n}\n\nfunc TestDecodeICMP(t *testing.T) {\n\tipDecoder := NewIPDecoder()\n\ticmpDecoder := NewICMPDecoder()\n\tvar (\n\t\tipv4Packet = IP{\n\t\t\tSrc:      netip.MustParseAddr(\"172.16.0.1\"),\n\t\t\tDst:      netip.MustParseAddr(\"10.0.0.1\"),\n\t\t\tProtocol: layers.IPProtocolICMPv4,\n\t\t\tTTL:      DefaultTTL,\n\t\t}\n\t\tipv6Packet = IP{\n\t\t\tSrc:      netip.MustParseAddr(\"fd51:2391:523:f4ee::1\"),\n\t\t\tDst:      netip.MustParseAddr(\"fd51:2391:697:f4ee::2\"),\n\t\t\tProtocol: layers.IPProtocolICMPv6,\n\t\t\tTTL:      DefaultTTL,\n\t\t}\n\t\ticmpID  = 100\n\t\ticmpSeq = 52819\n\t)\n\ttests := []struct {\n\t\ttestCase string\n\t\tpacket   *ICMP\n\t}{\n\t\t{\n\t\t\ttestCase: \"icmpv4 time exceed\",\n\t\t\tpacket: &ICMP{\n\t\t\t\tIP: &ipv4Packet,\n\t\t\t\tMessage: &icmp.Message{\n\t\t\t\t\tType: ipv4.ICMPTypeTimeExceeded,\n\t\t\t\t\tCode: 0,\n\t\t\t\t\tBody: &icmp.TimeExceeded{\n\t\t\t\t\t\tData: []byte(\"original packet\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\ttestCase: \"icmpv4 echo\",\n\t\t\tpacket: &ICMP{\n\t\t\t\tIP: &ipv4Packet,\n\t\t\t\tMessage: &icmp.Message{\n\t\t\t\t\tType: ipv4.ICMPTypeEcho,\n\t\t\t\t\tCode: 0,\n\t\t\t\t\tBody: &icmp.Echo{\n\t\t\t\t\t\tID:   icmpID,\n\t\t\t\t\t\tSeq:  icmpSeq,\n\t\t\t\t\t\tData: []byte(\"icmpv4 echo\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\ttestCase: \"icmpv6 destination unreachable\",\n\t\t\tpacket: &ICMP{\n\t\t\t\tIP: &ipv6Packet,\n\t\t\t\tMessage: &icmp.Message{\n\t\t\t\t\tType: ipv6.ICMPTypeDestinationUnreachable,\n\t\t\t\t\tCode: 4,\n\t\t\t\t\tBody: &icmp.DstUnreach{\n\t\t\t\t\t\tData: []byte(\"original packet\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\ttestCase: \"icmpv6 echo\",\n\t\t\tpacket: &ICMP{\n\t\t\t\tIP: &ipv6Packet,\n\t\t\t\tMessage: &icmp.Message{\n\t\t\t\t\tType: ipv6.ICMPTypeEchoRequest,\n\t\t\t\t\tCode: 0,\n\t\t\t\t\tBody: &icmp.Echo{\n\t\t\t\t\t\tID:   icmpID,\n\t\t\t\t\t\tSeq:  icmpSeq,\n\t\t\t\t\t\tData: []byte(\"icmpv6 echo\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tencoder := NewEncoder()\n\tfor _, test := range tests {\n\t\tp, err := encoder.Encode(test.packet)\n\t\trequire.NoError(t, err)\n\n\t\tipPacket, err := ipDecoder.Decode(p)\n\t\trequire.NoError(t, err)\n\t\tif ipPacket.Src.Is4() {\n\t\t\tassertIPLayer(t, &ipv4Packet, ipPacket)\n\t\t} else {\n\t\t\tassertIPLayer(t, &ipv6Packet, ipPacket)\n\t\t}\n\t\ticmpPacket, err := icmpDecoder.Decode(p)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, ipPacket, icmpPacket.IP)\n\n\t\trequire.Equal(t, test.packet.Type, icmpPacket.Type)\n\t\trequire.Equal(t, test.packet.Code, icmpPacket.Code)\n\t\tassertICMPChecksum(t, icmpPacket)\n\t\trequire.Equal(t, test.packet.Body, icmpPacket.Body)\n\t\texpectedBody, err := test.packet.Body.Marshal(test.packet.Type.Protocol())\n\t\trequire.NoError(t, err)\n\t\tdecodedBody, err := icmpPacket.Body.Marshal(test.packet.Type.Protocol())\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, expectedBody, decodedBody)\n\t}\n}\n\n// TestDecodeBadPackets makes sure decoders don't decode invalid packets\nfunc TestDecodeBadPackets(t *testing.T) {\n\tvar (\n\t\tsrcIPv4 = net.ParseIP(\"172.16.0.1\")\n\t\tdstIPv4 = net.ParseIP(\"10.0.0.1\")\n\t)\n\n\tipLayer := layers.IPv4{\n\t\tVersion:  10,\n\t\tSrcIP:    srcIPv4,\n\t\tDstIP:    dstIPv4,\n\t\tProtocol: layers.IPProtocolICMPv4,\n\t\tTTL:      DefaultTTL,\n\t}\n\ticmpLayer := layers.ICMPv4{\n\t\tTypeCode: layers.CreateICMPv4TypeCode(uint8(ipv4.ICMPTypeEcho), 0),\n\t\tId:       100,\n\t\tSeq:      52819,\n\t}\n\twrongIPVersion, err := createPacket(&ipLayer, &icmpLayer, nil, nil)\n\trequire.NoError(t, err)\n\n\ttests := []struct {\n\t\ttestCase string\n\t\tpacket   []byte\n\t}{\n\t\t{\n\t\t\ttestCase: \"unknown IP version\",\n\t\t\tpacket:   wrongIPVersion,\n\t\t},\n\t\t{\n\t\t\ttestCase: \"invalid packet\",\n\t\t\tpacket:   []byte(\"not a packet\"),\n\t\t},\n\t\t{\n\t\t\ttestCase: \"zero length packet\",\n\t\t\tpacket:   []byte{},\n\t\t},\n\t}\n\n\tipDecoder := NewIPDecoder()\n\ticmpDecoder := NewICMPDecoder()\n\tfor _, test := range tests {\n\t\tipPacket, err := ipDecoder.Decode(RawPacket{Data: test.packet})\n\t\trequire.Error(t, err)\n\t\trequire.Nil(t, ipPacket)\n\n\t\ticmpPacket, err := icmpDecoder.Decode(RawPacket{Data: test.packet})\n\t\trequire.Error(t, err)\n\t\trequire.Nil(t, icmpPacket)\n\t}\n}\n\nfunc createPacket(ipLayer, secondLayer, thirdLayer gopacket.SerializableLayer, body []byte) ([]byte, error) {\n\tpayload := gopacket.Payload(body)\n\tpacket := gopacket.NewSerializeBuffer()\n\tvar err error\n\tif thirdLayer != nil {\n\t\terr = gopacket.SerializeLayers(packet, serializeOpts, ipLayer, secondLayer, thirdLayer, payload)\n\t} else {\n\t\terr = gopacket.SerializeLayers(packet, serializeOpts, ipLayer, secondLayer, payload)\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn packet.Bytes(), nil\n}\n\nfunc assertIPLayer(t *testing.T, expected, actual *IP) {\n\trequire.Equal(t, expected.Src, actual.Src)\n\trequire.Equal(t, expected.Dst, actual.Dst)\n\trequire.Equal(t, expected.Protocol, actual.Protocol)\n\trequire.Equal(t, expected.TTL, actual.TTL)\n}\n\ntype UDP struct {\n\tIP\n\tSrcPort, DstPort layers.UDPPort\n}\n\nfunc (u *UDP) EncodeLayers() ([]gopacket.SerializableLayer, error) {\n\tipLayers, err := u.IP.EncodeLayers()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tudpLayer := layers.UDP{\n\t\tSrcPort: u.SrcPort,\n\t\tDstPort: u.DstPort,\n\t}\n\tudpLayer.SetNetworkLayerForChecksum(ipLayers[0].(gopacket.NetworkLayer))\n\treturn append(ipLayers, &udpLayer), nil\n}\n\nfunc FuzzIPDecoder(f *testing.F) {\n\tf.Fuzz(func(t *testing.T, data []byte) {\n\t\tipDecoder := NewIPDecoder()\n\t\tipDecoder.Decode(RawPacket{Data: data})\n\n\t})\n}\n\nfunc FuzzICMPDecoder(f *testing.F) {\n\tf.Fuzz(func(t *testing.T, data []byte) {\n\t\ticmpDecoder := NewICMPDecoder()\n\t\ticmpDecoder.Decode(RawPacket{Data: data})\n\t})\n}\n"
  },
  {
    "path": "packet/encoder.go",
    "content": "package packet\n\nimport (\n\t\"github.com/google/gopacket\"\n)\n\nvar (\n\tserializeOpts = gopacket.SerializeOptions{\n\t\tFixLengths:       true,\n\t\tComputeChecksums: true,\n\t}\n)\n\n// RawPacket represents a raw packet or one encoded by Encoder\ntype RawPacket struct {\n\tData []byte\n}\n\ntype Encoder struct {\n\t// buf is reusable because SerializeLayers calls the Clear method before each encoding\n\tbuf gopacket.SerializeBuffer\n}\n\nfunc NewEncoder() *Encoder {\n\treturn &Encoder{\n\t\tbuf: gopacket.NewSerializeBuffer(),\n\t}\n}\n\nfunc (e *Encoder) Encode(packet Packet) (RawPacket, error) {\n\tencodedLayers, err := packet.EncodeLayers()\n\tif err != nil {\n\t\treturn RawPacket{}, err\n\t}\n\tif err := gopacket.SerializeLayers(e.buf, serializeOpts, encodedLayers...); err != nil {\n\t\treturn RawPacket{}, err\n\t}\n\treturn RawPacket{\n\t\tData: e.buf.Bytes(),\n\t}, nil\n}\n"
  },
  {
    "path": "packet/funnel.go",
    "content": "package packet\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/netip\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n)\n\nvar (\n\tErrFunnelNotFound = errors.New(\"funnel not found\")\n)\n\n// Funnel is an abstraction to pipe from 1 src to 1 or more destinations\ntype Funnel interface {\n\t// Updates the last time traffic went through this funnel\n\tUpdateLastActive()\n\t// LastActive returns the last time there is traffic through this funnel\n\tLastActive() time.Time\n\t// Close closes the funnel. Further call to SendToDst or ReturnToSrc should return an error\n\tClose() error\n\t// Equal compares if 2 funnels are equivalent\n\tEqual(other Funnel) bool\n}\n\n// FunnelUniPipe is a unidirectional pipe for sending raw packets\ntype FunnelUniPipe interface {\n\t// SendPacket sends a packet to/from the funnel. It must not modify the packet,\n\t// and after return it must not read the packet\n\tSendPacket(dst netip.Addr, pk RawPacket) error\n\tClose() error\n}\n\ntype ActivityTracker struct {\n\t// last active unix time. Unit is seconds\n\tlastActive int64\n}\n\nfunc NewActivityTracker() *ActivityTracker {\n\treturn &ActivityTracker{\n\t\tlastActive: time.Now().Unix(),\n\t}\n}\n\nfunc (at *ActivityTracker) UpdateLastActive() {\n\tatomic.StoreInt64(&at.lastActive, time.Now().Unix())\n}\n\nfunc (at *ActivityTracker) LastActive() time.Time {\n\tlastActive := atomic.LoadInt64(&at.lastActive)\n\treturn time.Unix(lastActive, 0)\n}\n\n// FunnelID represents a key type that can be used by FunnelTracker\ntype FunnelID interface {\n\t// Type returns the name of the type that implements the FunnelID\n\tType() string\n\tfmt.Stringer\n}\n\n// FunnelTracker tracks funnel from the perspective of eyeball to origin\ntype FunnelTracker struct {\n\tlock    sync.RWMutex\n\tfunnels map[FunnelID]Funnel\n}\n\nfunc NewFunnelTracker() *FunnelTracker {\n\treturn &FunnelTracker{\n\t\tfunnels: make(map[FunnelID]Funnel),\n\t}\n}\n\nfunc (ft *FunnelTracker) ScheduleCleanup(ctx context.Context, idleTimeout time.Duration) {\n\tcheckIdleTicker := time.NewTicker(idleTimeout)\n\tdefer checkIdleTicker.Stop()\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\tcase <-checkIdleTicker.C:\n\t\t\tft.cleanup(idleTimeout)\n\t\t}\n\t}\n}\n\nfunc (ft *FunnelTracker) cleanup(idleTimeout time.Duration) {\n\tft.lock.Lock()\n\tdefer ft.lock.Unlock()\n\n\tnow := time.Now()\n\tfor id, funnel := range ft.funnels {\n\t\tlastActive := funnel.LastActive()\n\t\tif now.After(lastActive.Add(idleTimeout)) {\n\t\t\tfunnel.Close()\n\t\t\tdelete(ft.funnels, id)\n\t\t}\n\t}\n}\n\nfunc (ft *FunnelTracker) Get(id FunnelID) (Funnel, bool) {\n\tft.lock.RLock()\n\tdefer ft.lock.RUnlock()\n\tfunnel, ok := ft.funnels[id]\n\treturn funnel, ok\n}\n\n// Registers a funnel. If the `id` is already registered and `shouldReplaceFunc` returns true, it closes and replaces\n// the current funnel. If `newFunnelFunc` returns an error, the `id` will remain unregistered, even if it was registered\n// when calling this function.\nfunc (ft *FunnelTracker) GetOrRegister(\n\tid FunnelID,\n\tshouldReplaceFunc func(Funnel) bool,\n\tnewFunnelFunc func() (Funnel, error),\n) (funnel Funnel, new bool, err error) {\n\tft.lock.Lock()\n\tdefer ft.lock.Unlock()\n\tcurrentFunnel, exists := ft.funnels[id]\n\tif exists {\n\t\tif !shouldReplaceFunc(currentFunnel) {\n\t\t\treturn currentFunnel, false, nil\n\t\t}\n\t\tcurrentFunnel.Close()\n\t\tdelete(ft.funnels, id)\n\t}\n\tnewFunnel, err := newFunnelFunc()\n\tif err != nil {\n\t\treturn nil, false, err\n\t}\n\tft.funnels[id] = newFunnel\n\treturn newFunnel, true, nil\n}\n\n// Unregisters and closes a funnel if the funnel equals to the current funnel\nfunc (ft *FunnelTracker) Unregister(id FunnelID, funnel Funnel) (deleted bool) {\n\tft.lock.Lock()\n\tdefer ft.lock.Unlock()\n\tcurrentFunnel, exists := ft.funnels[id]\n\tif !exists {\n\t\treturn true\n\t}\n\tif currentFunnel.Equal(funnel) {\n\t\tcurrentFunnel.Close()\n\t\tdelete(ft.funnels, id)\n\t\treturn true\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "packet/funnel_test.go",
    "content": "package packet\n\nimport (\n\t\"fmt\"\n\t\"net/netip\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\ntype mockFunnelUniPipe struct {\n\tuniPipe chan RawPacket\n}\n\nfunc (mfui *mockFunnelUniPipe) SendPacket(dst netip.Addr, pk RawPacket) error {\n\tmfui.uniPipe <- pk\n\treturn nil\n}\n\nfunc (mfui *mockFunnelUniPipe) Close() error {\n\treturn nil\n}\n\nfunc TestFunnelRegistration(t *testing.T) {\n\tid := testFunnelID{\"id1\"}\n\tfunnelErr := fmt.Errorf(\"expected error\")\n\tnewFunnelFuncErr := func() (Funnel, error) { return nil, funnelErr }\n\tnewFunnelFuncUncalled := func() (Funnel, error) {\n\t\trequire.FailNow(t, \"a new funnel should not be created\")\n\t\tpanic(\"unreached\")\n\t}\n\tfunnel1, newFunnelFunc1 := newFunnelAndFunc(\"funnel1\")\n\tfunnel2, newFunnelFunc2 := newFunnelAndFunc(\"funnel2\")\n\n\tft := NewFunnelTracker()\n\t// Register funnel1\n\tfunnel, new, err := ft.GetOrRegister(id, shouldReplaceFalse, newFunnelFunc1)\n\trequire.NoError(t, err)\n\trequire.True(t, new)\n\trequire.Equal(t, funnel1, funnel)\n\t// Register funnel, no replace\n\tfunnel, new, err = ft.GetOrRegister(id, shouldReplaceFalse, newFunnelFuncUncalled)\n\trequire.NoError(t, err)\n\trequire.False(t, new)\n\trequire.Equal(t, funnel1, funnel)\n\t// Register funnel2, replace\n\tfunnel, new, err = ft.GetOrRegister(id, shouldReplaceTrue, newFunnelFunc2)\n\trequire.NoError(t, err)\n\trequire.True(t, new)\n\trequire.Equal(t, funnel2, funnel)\n\trequire.True(t, funnel1.closed)\n\t// Register funnel error, replace\n\tfunnel, new, err = ft.GetOrRegister(id, shouldReplaceTrue, newFunnelFuncErr)\n\trequire.ErrorIs(t, err, funnelErr)\n\trequire.False(t, new)\n\trequire.Nil(t, funnel)\n\trequire.True(t, funnel2.closed)\n}\n\nfunc TestFunnelUnregister(t *testing.T) {\n\tid := testFunnelID{\"id1\"}\n\tfunnel1, newFunnelFunc1 := newFunnelAndFunc(\"funnel1\")\n\tfunnel2, newFunnelFunc2 := newFunnelAndFunc(\"funnel2\")\n\tfunnel3, newFunnelFunc3 := newFunnelAndFunc(\"funnel3\")\n\n\tft := NewFunnelTracker()\n\t// Register & unregister\n\t_, _, err := ft.GetOrRegister(id, shouldReplaceFalse, newFunnelFunc1)\n\trequire.NoError(t, err)\n\trequire.True(t, ft.Unregister(id, funnel1))\n\trequire.True(t, funnel1.closed)\n\trequire.True(t, ft.Unregister(id, funnel1))\n\t// Register, replace, and unregister\n\t_, _, err = ft.GetOrRegister(id, shouldReplaceFalse, newFunnelFunc2)\n\trequire.NoError(t, err)\n\t_, _, err = ft.GetOrRegister(id, shouldReplaceTrue, newFunnelFunc3)\n\trequire.NoError(t, err)\n\trequire.True(t, funnel2.closed)\n\trequire.False(t, ft.Unregister(id, funnel2))\n\trequire.True(t, ft.Unregister(id, funnel3))\n\trequire.True(t, funnel3.closed)\n}\n\nfunc shouldReplaceFalse(_ Funnel) bool {\n\treturn false\n}\n\nfunc shouldReplaceTrue(_ Funnel) bool {\n\treturn true\n}\n\nfunc newFunnelAndFunc(id string) (*testFunnel, func() (Funnel, error)) {\n\tfunnel := newTestFunnel(id)\n\tfunnelFunc := func() (Funnel, error) {\n\t\treturn funnel, nil\n\t}\n\treturn funnel, funnelFunc\n}\n\ntype testFunnelID struct {\n\tid string\n}\n\nfunc (t testFunnelID) Type() string {\n\treturn \"testFunnelID\"\n}\n\nfunc (t testFunnelID) String() string {\n\treturn t.id\n}\n\ntype testFunnel struct {\n\tid     string\n\tclosed bool\n}\n\nfunc newTestFunnel(id string) *testFunnel {\n\treturn &testFunnel{\n\t\tid,\n\t\tfalse,\n\t}\n}\n\nfunc (tf *testFunnel) Close() error {\n\ttf.closed = true\n\treturn nil\n}\n\nfunc (tf *testFunnel) Equal(other Funnel) bool {\n\treturn tf.id == other.(*testFunnel).id\n}\n\nfunc (tf *testFunnel) LastActive() time.Time {\n\treturn time.Now()\n}\n\nfunc (tf *testFunnel) UpdateLastActive() {}\n"
  },
  {
    "path": "packet/packet.go",
    "content": "package packet\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"net/netip\"\n\n\t\"github.com/google/gopacket\"\n\t\"github.com/google/gopacket/layers\"\n\t\"golang.org/x/net/icmp\"\n\t\"golang.org/x/net/ipv4\"\n\t\"golang.org/x/net/ipv6\"\n)\n\nconst (\n\tipv4MinHeaderLen = 20\n\tipv6HeaderLen    = 40\n\tipv4MinMTU       = 576\n\tipv6MinMTU       = 1280\n\ticmpHeaderLen    = 8\n\t// https://www.rfc-editor.org/rfc/rfc792 and https://datatracker.ietf.org/doc/html/rfc4443#section-3.3 define 2 codes.\n\t// 0 = ttl exceed in transit, 1 = fragment reassembly time exceeded\n\ticmpTTLExceedInTransitCode       = 0\n\tDefaultTTL                 uint8 = 255\n\tpseudoHeaderLen                  = 40\n)\n\n// Packet represents an IP packet or a packet that is encapsulated by IP\ntype Packet interface {\n\t// IPLayer returns the IP of the packet\n\tIPLayer() *IP\n\t// EncodeLayers returns the layers that make up this packet. They can be passed to an Encoder to serialize into RawPacket\n\tEncodeLayers() ([]gopacket.SerializableLayer, error)\n}\n\n// IP represents a generic IP packet. It can be embedded in more specific IP protocols\ntype IP struct {\n\tSrc      netip.Addr\n\tDst      netip.Addr\n\tProtocol layers.IPProtocol\n\tTTL      uint8\n}\n\nfunc newIPv4(ipLayer *layers.IPv4) (*IP, error) {\n\tsrc, ok := netip.AddrFromSlice(ipLayer.SrcIP)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"cannot convert source IP %s to netip.Addr\", ipLayer.SrcIP)\n\t}\n\tdst, ok := netip.AddrFromSlice(ipLayer.DstIP)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"cannot convert source IP %s to netip.Addr\", ipLayer.DstIP)\n\t}\n\treturn &IP{\n\t\tSrc:      src,\n\t\tDst:      dst,\n\t\tProtocol: ipLayer.Protocol,\n\t\tTTL:      ipLayer.TTL,\n\t}, nil\n}\n\nfunc newIPv6(ipLayer *layers.IPv6) (*IP, error) {\n\tsrc, ok := netip.AddrFromSlice(ipLayer.SrcIP)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"cannot convert source IP %s to netip.Addr\", ipLayer.SrcIP)\n\t}\n\tdst, ok := netip.AddrFromSlice(ipLayer.DstIP)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"cannot convert source IP %s to netip.Addr\", ipLayer.DstIP)\n\t}\n\treturn &IP{\n\t\tSrc:      src,\n\t\tDst:      dst,\n\t\tProtocol: ipLayer.NextHeader,\n\t\tTTL:      ipLayer.HopLimit,\n\t}, nil\n}\n\nfunc (ip *IP) IPLayer() *IP {\n\treturn ip\n}\n\nfunc (ip *IP) isIPv4() bool {\n\treturn ip.Src.Is4()\n}\n\nfunc (ip *IP) EncodeLayers() ([]gopacket.SerializableLayer, error) {\n\tif ip.isIPv4() {\n\t\treturn []gopacket.SerializableLayer{\n\t\t\t&layers.IPv4{\n\t\t\t\tVersion:  4,\n\t\t\t\tSrcIP:    ip.Src.AsSlice(),\n\t\t\t\tDstIP:    ip.Dst.AsSlice(),\n\t\t\t\tProtocol: layers.IPProtocol(ip.Protocol),\n\t\t\t\tTTL:      ip.TTL,\n\t\t\t},\n\t\t}, nil\n\t} else {\n\t\treturn []gopacket.SerializableLayer{\n\t\t\t&layers.IPv6{\n\t\t\t\tVersion:    6,\n\t\t\t\tSrcIP:      ip.Src.AsSlice(),\n\t\t\t\tDstIP:      ip.Dst.AsSlice(),\n\t\t\t\tNextHeader: layers.IPProtocol(ip.Protocol),\n\t\t\t\tHopLimit:   ip.TTL,\n\t\t\t},\n\t\t}, nil\n\t}\n}\n\n// ICMP represents is an IP packet + ICMP message\ntype ICMP struct {\n\t*IP\n\t*icmp.Message\n}\n\nfunc (i *ICMP) EncodeLayers() ([]gopacket.SerializableLayer, error) {\n\tipLayers, err := i.IP.EncodeLayers()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar serializedPsh []byte = nil\n\tif i.Protocol == layers.IPProtocolICMPv6 {\n\t\tpsh := &PseudoHeader{\n\t\t\tSrcIP: i.Src.As16(),\n\t\t\tDstIP: i.Dst.As16(),\n\t\t\t// i.Marshal re-calculates the UpperLayerPacketLength\n\t\t\tUpperLayerPacketLength: 0,\n\t\t\tNextHeader:             uint8(i.Protocol),\n\t\t}\n\t\tserializedPsh = psh.Marshal()\n\t}\n\tmsg, err := i.Marshal(serializedPsh)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ticmpLayer := gopacket.Payload(msg)\n\treturn append(ipLayers, icmpLayer), nil\n}\n\n// https://www.rfc-editor.org/rfc/rfc2460#section-8.1\ntype PseudoHeader struct {\n\tSrcIP                  [16]byte\n\tDstIP                  [16]byte\n\tUpperLayerPacketLength uint32\n\tzero                   [3]byte\n\tNextHeader             uint8\n}\n\nfunc (ph *PseudoHeader) Marshal() []byte {\n\tbuf := make([]byte, pseudoHeaderLen)\n\tindex := 0\n\tcopy(buf, ph.SrcIP[:])\n\tindex += 16\n\tcopy(buf[index:], ph.DstIP[:])\n\tindex += 16\n\tbinary.BigEndian.PutUint32(buf[index:], ph.UpperLayerPacketLength)\n\tindex += 4\n\tcopy(buf[index:], ph.zero[:])\n\tbuf[pseudoHeaderLen-1] = ph.NextHeader\n\treturn buf\n}\n\nfunc NewICMPTTLExceedPacket(originalIP *IP, originalPacket RawPacket, routerIP netip.Addr) *ICMP {\n\tvar (\n\t\tprotocol layers.IPProtocol\n\t\ticmpType icmp.Type\n\t)\n\tif originalIP.Dst.Is4() {\n\t\tprotocol = layers.IPProtocolICMPv4\n\t\ticmpType = ipv4.ICMPTypeTimeExceeded\n\t} else {\n\t\tprotocol = layers.IPProtocolICMPv6\n\t\ticmpType = ipv6.ICMPTypeTimeExceeded\n\t}\n\n\treturn &ICMP{\n\t\tIP: &IP{\n\t\t\tSrc:      routerIP,\n\t\t\tDst:      originalIP.Src,\n\t\t\tProtocol: protocol,\n\t\t\tTTL:      DefaultTTL,\n\t\t},\n\t\tMessage: &icmp.Message{\n\t\t\tType: icmpType,\n\t\t\tCode: icmpTTLExceedInTransitCode,\n\t\t\tBody: &icmp.TimeExceeded{\n\t\t\t\tData: originalDatagram(originalPacket, originalIP.Dst.Is4()),\n\t\t\t},\n\t\t},\n\t}\n}\n\n// originalDatagram returns a slice of the original datagram for ICMP error messages\n// https://www.rfc-editor.org/rfc/rfc1812#section-4.3.2.3 suggests to copy as much without exceeding 576 bytes.\n// https://datatracker.ietf.org/doc/html/rfc4443#section-3.3 suggests to copy as much without exceeding 1280 bytes\nfunc originalDatagram(originalPacket RawPacket, isIPv4 bool) []byte {\n\tvar upperBound int\n\tif isIPv4 {\n\t\tupperBound = ipv4MinMTU - ipv4MinHeaderLen - icmpHeaderLen\n\t\tif upperBound > len(originalPacket.Data) {\n\t\t\tupperBound = len(originalPacket.Data)\n\t\t}\n\t} else {\n\t\tupperBound = ipv6MinMTU - ipv6HeaderLen - icmpHeaderLen\n\t\tif upperBound > len(originalPacket.Data) {\n\t\t\tupperBound = len(originalPacket.Data)\n\t\t}\n\t}\n\treturn originalPacket.Data[:upperBound]\n}\n"
  },
  {
    "path": "packet/packet_test.go",
    "content": "package packet\n\nimport (\n\t\"bytes\"\n\t\"net/netip\"\n\t\"testing\"\n\n\t\"github.com/google/gopacket\"\n\t\"github.com/google/gopacket/layers\"\n\t\"github.com/stretchr/testify/require\"\n\t\"golang.org/x/net/icmp\"\n\t\"golang.org/x/net/ipv4\"\n\t\"golang.org/x/net/ipv6\"\n)\n\nfunc TestNewICMPTTLExceedPacket(t *testing.T) {\n\tipv4Packet := IP{\n\t\tSrc:      netip.MustParseAddr(\"192.168.1.1\"),\n\t\tDst:      netip.MustParseAddr(\"10.0.0.1\"),\n\t\tProtocol: layers.IPProtocolICMPv4,\n\t\tTTL:      0,\n\t}\n\ticmpV4Packet := ICMP{\n\t\tIP: &ipv4Packet,\n\t\tMessage: &icmp.Message{\n\t\t\tType: ipv4.ICMPTypeEcho,\n\t\t\tCode: 0,\n\t\t\tBody: &icmp.Echo{\n\t\t\t\tID:   25821,\n\t\t\t\tSeq:  58129,\n\t\t\t\tData: []byte(\"test ttl=0\"),\n\t\t\t},\n\t\t},\n\t}\n\tassertTTLExceedPacket(t, &icmpV4Packet)\n\ticmpV4Packet.Body = &icmp.Echo{\n\t\tID:   3487,\n\t\tSeq:  19183,\n\t\tData: make([]byte, ipv4MinMTU),\n\t}\n\tassertTTLExceedPacket(t, &icmpV4Packet)\n\tipv6Packet := IP{\n\t\tSrc:      netip.MustParseAddr(\"fd51:2391:523:f4ee::1\"),\n\t\tDst:      netip.MustParseAddr(\"fd51:2391:697:f4ee::2\"),\n\t\tProtocol: layers.IPProtocolICMPv6,\n\t\tTTL:      0,\n\t}\n\ticmpV6Packet := ICMP{\n\t\tIP: &ipv6Packet,\n\t\tMessage: &icmp.Message{\n\t\t\tType: ipv6.ICMPTypeEchoRequest,\n\t\t\tCode: 0,\n\t\t\tBody: &icmp.Echo{\n\t\t\t\tID:   25821,\n\t\t\t\tSeq:  58129,\n\t\t\t\tData: []byte(\"test ttl=0\"),\n\t\t\t},\n\t\t},\n\t}\n\tassertTTLExceedPacket(t, &icmpV6Packet)\n\ticmpV6Packet.Body = &icmp.Echo{\n\t\tID:   1497,\n\t\tSeq:  39284,\n\t\tData: make([]byte, ipv6MinMTU),\n\t}\n\tassertTTLExceedPacket(t, &icmpV6Packet)\n}\n\nfunc assertTTLExceedPacket(t *testing.T, pk *ICMP) {\n\tencoder := NewEncoder()\n\trawPacket, err := encoder.Encode(pk)\n\trequire.NoError(t, err)\n\n\tminMTU := ipv4MinMTU\n\theaderLen := ipv4MinHeaderLen\n\trouterIP := netip.MustParseAddr(\"172.16.0.3\")\n\tif pk.Dst.Is6() {\n\t\tminMTU = ipv6MinMTU\n\t\theaderLen = ipv6HeaderLen\n\t\trouterIP = netip.MustParseAddr(\"fd51:2391:697:f4ee::3\")\n\t}\n\n\tttlExceedPacket := NewICMPTTLExceedPacket(pk.IP, rawPacket, routerIP)\n\trequire.Equal(t, routerIP, ttlExceedPacket.Src)\n\trequire.Equal(t, pk.Src, ttlExceedPacket.Dst)\n\trequire.Equal(t, pk.Protocol, ttlExceedPacket.Protocol)\n\trequire.Equal(t, DefaultTTL, ttlExceedPacket.TTL)\n\n\ttimeExceed, ok := ttlExceedPacket.Body.(*icmp.TimeExceeded)\n\trequire.True(t, ok)\n\tif len(rawPacket.Data) > minMTU {\n\t\trequire.True(t, bytes.Equal(timeExceed.Data, rawPacket.Data[:minMTU-headerLen-icmpHeaderLen]))\n\t} else {\n\t\trequire.True(t, bytes.Equal(timeExceed.Data, rawPacket.Data))\n\t}\n\n\trawTTLExceedPacket, err := encoder.Encode(ttlExceedPacket)\n\trequire.NoError(t, err)\n\tif len(rawPacket.Data) > minMTU {\n\t\trequire.Len(t, rawTTLExceedPacket.Data, minMTU)\n\t} else {\n\t\trequire.Len(t, rawTTLExceedPacket.Data, headerLen+icmpHeaderLen+len(rawPacket.Data))\n\t\trequire.True(t, bytes.Equal(rawPacket.Data, rawTTLExceedPacket.Data[headerLen+icmpHeaderLen:]))\n\t}\n\n\tdecoder := NewICMPDecoder()\n\tdecodedPacket, err := decoder.Decode(rawTTLExceedPacket)\n\trequire.NoError(t, err)\n\tassertICMPChecksum(t, decodedPacket)\n}\n\nfunc assertICMPChecksum(t *testing.T, icmpPacket *ICMP) {\n\tbuf := gopacket.NewSerializeBuffer()\n\tif icmpPacket.Protocol == layers.IPProtocolICMPv4 {\n\t\ticmpv4 := layers.ICMPv4{\n\t\t\tTypeCode: layers.CreateICMPv4TypeCode(uint8(icmpPacket.Type.(ipv4.ICMPType)), uint8(icmpPacket.Code)),\n\t\t}\n\t\tswitch body := icmpPacket.Body.(type) {\n\t\tcase *icmp.Echo:\n\t\t\ticmpv4.Id = uint16(body.ID)\n\t\t\ticmpv4.Seq = uint16(body.Seq)\n\t\t\tpayload := gopacket.Payload(body.Data)\n\t\t\trequire.NoError(t, payload.SerializeTo(buf, serializeOpts))\n\t\tdefault:\n\t\t\trequire.NoError(t, serializeICMPAsPayload(icmpPacket.Message, buf))\n\t\t}\n\t\t// SerializeTo sets the checksum in icmpv4\n\t\trequire.NoError(t, icmpv4.SerializeTo(buf, serializeOpts))\n\t\trequire.Equal(t, icmpv4.Checksum, uint16(icmpPacket.Checksum))\n\t} else {\n\t\tswitch body := icmpPacket.Body.(type) {\n\t\tcase *icmp.Echo:\n\t\t\tpayload := gopacket.Payload(body.Data)\n\t\t\trequire.NoError(t, payload.SerializeTo(buf, serializeOpts))\n\t\t\techo := layers.ICMPv6Echo{\n\t\t\t\tIdentifier: uint16(body.ID),\n\t\t\t\tSeqNumber:  uint16(body.Seq),\n\t\t\t}\n\t\t\trequire.NoError(t, echo.SerializeTo(buf, serializeOpts))\n\t\tdefault:\n\t\t\trequire.NoError(t, serializeICMPAsPayload(icmpPacket.Message, buf))\n\t\t}\n\n\t\ticmpv6 := layers.ICMPv6{\n\t\t\tTypeCode: layers.CreateICMPv6TypeCode(uint8(icmpPacket.Type.(ipv6.ICMPType)), uint8(icmpPacket.Code)),\n\t\t}\n\t\tipLayer := layers.IPv6{\n\t\t\tVersion:    6,\n\t\t\tSrcIP:      icmpPacket.Src.AsSlice(),\n\t\t\tDstIP:      icmpPacket.Dst.AsSlice(),\n\t\t\tNextHeader: icmpPacket.Protocol,\n\t\t\tHopLimit:   icmpPacket.TTL,\n\t\t}\n\t\trequire.NoError(t, icmpv6.SetNetworkLayerForChecksum(&ipLayer))\n\n\t\t// SerializeTo sets the checksum in icmpv4\n\t\trequire.NoError(t, icmpv6.SerializeTo(buf, serializeOpts))\n\t\trequire.Equal(t, icmpv6.Checksum, uint16(icmpPacket.Checksum))\n\t}\n}\n\nfunc serializeICMPAsPayload(message *icmp.Message, buf gopacket.SerializeBuffer) error {\n\tserializedBody, err := message.Body.Marshal(message.Type.Protocol())\n\tif err != nil {\n\t\treturn err\n\t}\n\tpayload := gopacket.Payload(serializedBody)\n\treturn payload.SerializeTo(buf, serializeOpts)\n}\n\nfunc TestChecksum(t *testing.T) {\n\tdata := []byte{0x63, 0x2c, 0x49, 0xd6, 0x00, 0x0d, 0xc1, 0xda}\n\tpk := ICMP{\n\t\tIP: &IP{\n\t\t\tSrc:      netip.MustParseAddr(\"2606:4700:110:89c1:c63a:861:e08c:b049\"),\n\t\t\tDst:      netip.MustParseAddr(\"fde8:b693:d420:109b::2\"),\n\t\t\tProtocol: layers.IPProtocolICMPv6,\n\t\t\tTTL:      3,\n\t\t},\n\t\tMessage: &icmp.Message{\n\t\t\tType: ipv6.ICMPTypeEchoRequest,\n\t\t\tCode: 0,\n\t\t\tBody: &icmp.Echo{\n\t\t\t\tID:   0x20a7,\n\t\t\t\tSeq:  8,\n\t\t\t\tData: data,\n\t\t\t},\n\t\t},\n\t}\n\tencoder := NewEncoder()\n\tencoded, err := encoder.Encode(&pk)\n\trequire.NoError(t, err)\n\n\tdecoder := NewICMPDecoder()\n\tdecoded, err := decoder.Decode(encoded)\n\trequire.Equal(t, 0xff96, decoded.Checksum)\n}\n"
  },
  {
    "path": "packet/session.go",
    "content": "package packet\n\nimport \"github.com/google/uuid\"\n\ntype Session struct {\n\tID      uuid.UUID\n\tPayload []byte\n}\n"
  },
  {
    "path": "postinst.sh",
    "content": "#!/bin/bash\nset -eu\nln -sf /usr/bin/cloudflared /usr/local/bin/cloudflared\nmkdir -p /usr/local/etc/cloudflared/\ntouch /usr/local/etc/cloudflared/.installedFromPackageManager || true\n"
  },
  {
    "path": "postrm.sh",
    "content": "#!/bin/bash\nset -eu\nrm -f /usr/local/bin/cloudflared\nrm -f /usr/local/etc/cloudflared/.installedFromPackageManager\n"
  },
  {
    "path": "proxy/logger.go",
    "content": "package proxy\n\nimport (\n\t\"net/http\"\n\t\"strconv\"\n\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/connection\"\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\t\"github.com/cloudflare/cloudflared/management\"\n)\n\nconst (\n\tlogFieldCFRay         = \"cfRay\"\n\tlogFieldLBProbe       = \"lbProbe\"\n\tlogFieldRule          = \"ingressRule\"\n\tlogFieldOriginService = \"originService\"\n\tlogFieldConnIndex     = \"connIndex\"\n\tlogFieldDestAddr      = \"destAddr\"\n)\n\nvar (\n\tLogFieldFlowID = \"flowID\"\n)\n\n// newHTTPLogger creates a child zerolog.Logger from the provided with added context from the HTTP request, ingress\n// services, and connection index.\nfunc newHTTPLogger(logger *zerolog.Logger, connIndex uint8, req *http.Request, rule int, serviceName string) zerolog.Logger {\n\tctx := logger.With().\n\t\tInt(management.EventTypeKey, int(management.HTTP)).\n\t\tUint8(logFieldConnIndex, connIndex)\n\tcfRay := connection.FindCfRayHeader(req)\n\tlbProbe := connection.IsLBProbeRequest(req)\n\tif cfRay != \"\" {\n\t\tctx.Str(logFieldCFRay, cfRay)\n\t}\n\tif lbProbe {\n\t\tctx.Bool(logFieldLBProbe, lbProbe)\n\t}\n\treturn ctx.\n\t\tStr(logFieldOriginService, serviceName).\n\t\tInterface(logFieldRule, rule).\n\t\tLogger()\n}\n\n// newTCPLogger creates a child zerolog.Logger from the provided with added context from the TCPRequest.\nfunc newTCPLogger(logger *zerolog.Logger, req *connection.TCPRequest) zerolog.Logger {\n\treturn logger.With().\n\t\tInt(management.EventTypeKey, int(management.TCP)).\n\t\tUint8(logFieldConnIndex, req.ConnIndex).\n\t\tStr(logFieldOriginService, ingress.ServiceWarpRouting).\n\t\tStr(LogFieldFlowID, req.FlowID).\n\t\tStr(logFieldDestAddr, req.Dest).\n\t\tUint8(logFieldConnIndex, req.ConnIndex).\n\t\tLogger()\n}\n\n// logHTTPRequest logs a Debug message with the corresponding HTTP request details from the eyeball.\nfunc logHTTPRequest(logger *zerolog.Logger, r *http.Request) {\n\tlogger.Debug().\n\t\tStr(\"host\", r.Host).\n\t\tStr(\"path\", r.URL.Path).\n\t\tInterface(\"headers\", r.Header).\n\t\tInt64(\"content-length\", r.ContentLength).\n\t\tMsgf(\"%s %s %s\", r.Method, r.URL, r.Proto)\n}\n\n// logOriginHTTPResponse logs a Debug message of the origin response.\nfunc logOriginHTTPResponse(logger *zerolog.Logger, resp *http.Response) {\n\tresponseByCode.WithLabelValues(strconv.Itoa(resp.StatusCode)).Inc()\n\tlogger.Debug().\n\t\tInt64(\"content-length\", resp.ContentLength).\n\t\tMsgf(\"%s\", resp.Status)\n}\n\n// logRequestError logs an error for the proxied request.\nfunc logRequestError(logger *zerolog.Logger, err error) {\n\trequestErrors.Inc()\n\tlogger.Error().Err(err).Send()\n}\n"
  },
  {
    "path": "proxy/metrics.go",
    "content": "package proxy\n\nimport (\n\t\"github.com/prometheus/client_golang/prometheus\"\n\n\t\"github.com/cloudflare/cloudflared/connection\"\n)\n\n// Metrics uses connection.MetricsNamespace(aka cloudflared) as namespace and connection.TunnelSubsystem\n// (tunnel) as subsystem to keep them consistent with the previous qualifier.\n\nvar (\n\ttotalRequests = prometheus.NewCounter(\n\t\tprometheus.CounterOpts{\n\t\t\tNamespace: connection.MetricsNamespace,\n\t\t\tSubsystem: connection.TunnelSubsystem,\n\t\t\tName:      \"total_requests\",\n\t\t\tHelp:      \"Amount of requests proxied through all the tunnels\",\n\t\t},\n\t)\n\tconcurrentRequests = prometheus.NewGauge(\n\t\tprometheus.GaugeOpts{\n\t\t\tNamespace: connection.MetricsNamespace,\n\t\t\tSubsystem: connection.TunnelSubsystem,\n\t\t\tName:      \"concurrent_requests_per_tunnel\",\n\t\t\tHelp:      \"Concurrent requests proxied through each tunnel\",\n\t\t},\n\t)\n\tresponseByCode = prometheus.NewCounterVec(\n\t\tprometheus.CounterOpts{\n\t\t\tNamespace: connection.MetricsNamespace,\n\t\t\tSubsystem: connection.TunnelSubsystem,\n\t\t\tName:      \"response_by_code\",\n\t\t\tHelp:      \"Count of responses by HTTP status code\",\n\t\t},\n\t\t[]string{\"status_code\"},\n\t)\n\trequestErrors = prometheus.NewCounter(\n\t\tprometheus.CounterOpts{\n\t\t\tNamespace: connection.MetricsNamespace,\n\t\t\tSubsystem: connection.TunnelSubsystem,\n\t\t\tName:      \"request_errors\",\n\t\t\tHelp:      \"Count of error proxying to origin\",\n\t\t},\n\t)\n\tactiveTCPSessions = prometheus.NewGauge(\n\t\tprometheus.GaugeOpts{\n\t\t\tNamespace: connection.MetricsNamespace,\n\t\t\tSubsystem: \"tcp\",\n\t\t\tName:      \"active_sessions\",\n\t\t\tHelp:      \"Concurrent count of TCP sessions that are being proxied to any origin\",\n\t\t},\n\t)\n\ttotalTCPSessions = prometheus.NewCounter(\n\t\tprometheus.CounterOpts{\n\t\t\tNamespace: connection.MetricsNamespace,\n\t\t\tSubsystem: \"tcp\",\n\t\t\tName:      \"total_sessions\",\n\t\t\tHelp:      \"Total count of TCP sessions that have been proxied to any origin\",\n\t\t},\n\t)\n\tconnectLatency = prometheus.NewHistogram(\n\t\tprometheus.HistogramOpts{\n\t\t\tNamespace: connection.MetricsNamespace,\n\t\t\tSubsystem: \"proxy\",\n\t\t\tName:      \"connect_latency\",\n\t\t\tHelp:      \"Time it takes to establish and acknowledge connections in milliseconds\",\n\t\t\tBuckets:   []float64{1, 10, 25, 50, 100, 500, 1000, 5000},\n\t\t},\n\t)\n\tconnectStreamErrors = prometheus.NewCounter(\n\t\tprometheus.CounterOpts{\n\t\t\tNamespace: connection.MetricsNamespace,\n\t\t\tSubsystem: \"proxy\",\n\t\t\tName:      \"connect_streams_errors\",\n\t\t\tHelp:      \"Total count of failure to establish and acknowledge connections\",\n\t\t},\n\t)\n)\n\nfunc init() {\n\tprometheus.MustRegister(\n\t\ttotalRequests,\n\t\tconcurrentRequests,\n\t\tresponseByCode,\n\t\trequestErrors,\n\t\tactiveTCPSessions,\n\t\ttotalTCPSessions,\n\t\tconnectLatency,\n\t\tconnectStreamErrors,\n\t)\n}\n\nfunc incrementRequests() {\n\ttotalRequests.Inc()\n\tconcurrentRequests.Inc()\n}\n\nfunc decrementConcurrentRequests() {\n\tconcurrentRequests.Dec()\n}\n\nfunc incrementTCPRequests() {\n\tincrementRequests()\n\ttotalTCPSessions.Inc()\n\tactiveTCPSessions.Inc()\n}\n\nfunc decrementTCPConcurrentRequests() {\n\tdecrementConcurrentRequests()\n\tactiveTCPSessions.Dec()\n}\n"
  },
  {
    "path": "proxy/proxy.go",
    "content": "package proxy\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/netip\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/trace\"\n\n\tcfdflow \"github.com/cloudflare/cloudflared/flow\"\n\t\"github.com/cloudflare/cloudflared/management\"\n\n\t\"github.com/cloudflare/cloudflared/carrier\"\n\t\"github.com/cloudflare/cloudflared/cfio\"\n\t\"github.com/cloudflare/cloudflared/connection\"\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\t\"github.com/cloudflare/cloudflared/stream\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\nconst (\n\t// TagHeaderNamePrefix indicates a Cloudflared Warp Tag prefix that gets appended for warp traffic stream headers.\n\tTagHeaderNamePrefix = \"Cf-Warp-Tag-\"\n\ttrailerHeaderName   = \"Trailer\"\n)\n\n// Proxy represents a means to Proxy between cloudflared and the origin services.\ntype Proxy struct {\n\tingressRules ingress.Ingress\n\toriginDialer ingress.OriginTCPDialer\n\ttags         []pogs.Tag\n\tflowLimiter  cfdflow.Limiter\n\tlog          *zerolog.Logger\n}\n\n// NewOriginProxy returns a new instance of the Proxy struct.\nfunc NewOriginProxy(\n\tingressRules ingress.Ingress,\n\toriginDialer ingress.OriginDialer,\n\ttags []pogs.Tag,\n\tflowLimiter cfdflow.Limiter,\n\tlog *zerolog.Logger,\n) *Proxy {\n\tproxy := &Proxy{\n\t\tingressRules: ingressRules,\n\t\toriginDialer: originDialer,\n\t\ttags:         tags,\n\t\tflowLimiter:  flowLimiter,\n\t\tlog:          log,\n\t}\n\n\treturn proxy\n}\n\nfunc (p *Proxy) applyIngressMiddleware(rule *ingress.Rule, r *http.Request, w connection.ResponseWriter) (error, bool) {\n\tfor _, handler := range rule.Handlers {\n\t\tresult, err := handler.Handle(r.Context(), r)\n\t\tif err != nil {\n\t\t\treturn errors.Wrap(err, fmt.Sprintf(\"error while processing middleware handler %s\", handler.Name())), false\n\t\t}\n\n\t\tif result.ShouldFilterRequest {\n\t\t\t_ = w.WriteRespHeaders(result.StatusCode, nil)\n\t\t\treturn fmt.Errorf(\"request filtered by middleware handler (%s) due to: %s\", handler.Name(), result.Reason), true\n\t\t}\n\t}\n\treturn nil, true\n}\n\n// ProxyHTTP further depends on ingress rules to establish a connection with the origin service. This may be\n// a simple roundtrip or a tcp/websocket dial depending on ingres rule setup.\nfunc (p *Proxy) ProxyHTTP(\n\tw connection.ResponseWriter,\n\ttr *tracing.TracedHTTPRequest,\n\tisWebsocket bool,\n) error {\n\tincrementRequests()\n\tdefer decrementConcurrentRequests()\n\n\treq := tr.Request\n\tp.appendTagHeaders(req)\n\n\t_, ruleSpan := tr.Tracer().Start(req.Context(), \"ingress_match\",\n\t\ttrace.WithAttributes(attribute.String(\"req-host\", req.Host)))\n\trule, ruleNum := p.ingressRules.FindMatchingRule(req.Host, req.URL.Path)\n\truleSpan.SetAttributes(attribute.Int(\"rule-num\", ruleNum))\n\truleSpan.End()\n\tlogger := newHTTPLogger(p.log, tr.ConnIndex, req, ruleNum, rule.Service.String())\n\tlogHTTPRequest(&logger, req)\n\tif err, applied := p.applyIngressMiddleware(rule, req, w); err != nil {\n\t\tif applied {\n\t\t\tlogRequestError(&logger, err)\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\n\tswitch originProxy := rule.Service.(type) {\n\tcase ingress.HTTPOriginProxy:\n\t\tif err := p.proxyHTTPRequest(\n\t\t\tw,\n\t\t\ttr,\n\t\t\toriginProxy,\n\t\t\tisWebsocket,\n\t\t\trule.Config.DisableChunkedEncoding,\n\t\t\t&logger,\n\t\t); err != nil {\n\t\t\tlogRequestError(&logger, err)\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\tcase ingress.StreamBasedOriginProxy:\n\t\tdest, err := getDestFromRule(rule, req)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tflusher, ok := w.(http.Flusher)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"response writer is not a flusher\")\n\t\t}\n\t\trws := connection.NewHTTPResponseReadWriterAcker(w, flusher, req)\n\t\tlogger := logger.With().Str(logFieldDestAddr, dest).Logger()\n\t\tif err := p.proxyStream(tr.ToTracedContext(), rws, dest, originProxy, &logger); err != nil {\n\t\t\tlogRequestError(&logger, err)\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\tcase ingress.HTTPLocalProxy:\n\t\tp.proxyLocalRequest(originProxy, w, req, isWebsocket)\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"Unrecognized service: %s, %t\", rule.Service, originProxy)\n\t}\n}\n\n// ProxyTCP proxies to a TCP connection between the origin service and cloudflared.\nfunc (p *Proxy) ProxyTCP(\n\tctx context.Context,\n\tconn connection.ReadWriteAcker,\n\treq *connection.TCPRequest,\n) error {\n\tincrementTCPRequests()\n\tdefer decrementTCPConcurrentRequests()\n\n\tlogger := newTCPLogger(p.log, req)\n\n\t// Try to start a new flow\n\tif err := p.flowLimiter.Acquire(management.TCP.String()); err != nil {\n\t\tlogger.Warn().Msg(\"Too many concurrent flows being handled, rejecting tcp proxy\")\n\t\treturn errors.Wrap(err, \"failed to start tcp flow due to rate limiting\")\n\t}\n\tdefer p.flowLimiter.Release()\n\n\tserveCtx, cancel := context.WithCancel(ctx)\n\tdefer cancel()\n\n\ttracedCtx := tracing.NewTracedContext(serveCtx, req.CfTraceID, &logger)\n\tlogger.Debug().Msg(\"tcp proxy stream started\")\n\n\t// Parse the destination into a netip.AddrPort\n\tdest, err := netip.ParseAddrPort(req.Dest)\n\tif err != nil {\n\t\tlogRequestError(&logger, err)\n\t\treturn err\n\t}\n\n\tif err := p.proxyTCPStream(tracedCtx, conn, dest, p.originDialer, &logger); err != nil {\n\t\tlogRequestError(&logger, err)\n\t\treturn err\n\t}\n\n\tlogger.Debug().Msg(\"tcp proxy stream finished successfully\")\n\n\treturn nil\n}\n\n// ProxyHTTPRequest proxies requests of underlying type http and websocket to the origin service.\nfunc (p *Proxy) proxyHTTPRequest(\n\tw connection.ResponseWriter,\n\ttr *tracing.TracedHTTPRequest,\n\thttpService ingress.HTTPOriginProxy,\n\tisWebsocket bool,\n\tdisableChunkedEncoding bool,\n\tlogger *zerolog.Logger,\n) error {\n\troundTripReq := tr.Request\n\tif isWebsocket {\n\t\troundTripReq = tr.Clone(tr.Request.Context())\n\t\troundTripReq.Header.Set(\"Connection\", \"Upgrade\")\n\t\troundTripReq.Header.Set(\"Upgrade\", \"websocket\")\n\t\troundTripReq.Header.Set(\"Sec-Websocket-Version\", \"13\")\n\t\troundTripReq.ContentLength = 0\n\t\troundTripReq.Body = nil\n\t} else {\n\t\t// Support for WSGI Servers by switching transfer encoding from chunked to gzip/deflate\n\t\tif disableChunkedEncoding {\n\t\t\troundTripReq.TransferEncoding = []string{\"gzip\", \"deflate\"}\n\t\t\tcLength, err := strconv.Atoi(tr.Request.Header.Get(\"Content-Length\"))\n\t\t\tif err == nil {\n\t\t\t\troundTripReq.ContentLength = int64(cLength)\n\t\t\t}\n\t\t}\n\t\t// Request origin to keep connection alive to improve performance\n\t\troundTripReq.Header.Set(\"Connection\", \"keep-alive\")\n\t}\n\n\t// Set the User-Agent as an empty string if not provided to avoid inserting golang default UA\n\tif roundTripReq.Header.Get(\"User-Agent\") == \"\" {\n\t\troundTripReq.Header.Set(\"User-Agent\", \"\")\n\t}\n\n\t_, ttfbSpan := tr.Tracer().Start(tr.Context(), \"ttfb_origin\")\n\tresp, err := httpService.RoundTrip(roundTripReq)\n\tif err != nil {\n\t\ttracing.EndWithErrorStatus(ttfbSpan, err)\n\t\tif err := roundTripReq.Context().Err(); err != nil {\n\t\t\treturn errors.Wrap(err, \"Incoming request ended abruptly\")\n\t\t}\n\t\treturn errors.Wrap(err, \"Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared\")\n\t}\n\n\ttracing.EndWithStatusCode(ttfbSpan, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\theaders := make(http.Header, len(resp.Header))\n\t// copy headers\n\tfor k, v := range resp.Header {\n\t\theaders[k] = v\n\t}\n\n\t// Add spans to response header (if available)\n\ttr.AddSpans(headers)\n\n\terr = w.WriteRespHeaders(resp.StatusCode, headers)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Error writing response header\")\n\t}\n\n\tif resp.StatusCode == http.StatusSwitchingProtocols {\n\t\trwc, ok := resp.Body.(io.ReadWriteCloser)\n\t\tif !ok {\n\t\t\treturn errors.New(\"internal error: unsupported connection type\")\n\t\t}\n\t\tdefer rwc.Close()\n\n\t\teyeballStream := &bidirectionalStream{\n\t\t\twriter: w,\n\t\t\treader: tr.Request.Body,\n\t\t}\n\n\t\tstream.Pipe(eyeballStream, rwc, logger)\n\t\treturn nil\n\t}\n\n\tif _, err = cfio.Copy(w, resp.Body); err != nil {\n\t\treturn err\n\t}\n\n\t// copy trailers\n\tcopyTrailers(w, resp)\n\n\tlogOriginHTTPResponse(logger, resp)\n\treturn nil\n}\n\n// proxyStream proxies type TCP and other underlying types if the connection is defined as a stream oriented\n// ingress rule.\n// connectedLogger is used to log when the connection is acknowledged\nfunc (p *Proxy) proxyStream(\n\ttr *tracing.TracedContext,\n\trwa connection.ReadWriteAcker,\n\tdest string,\n\toriginDialer ingress.StreamBasedOriginProxy,\n\tlogger *zerolog.Logger,\n) error {\n\tctx := tr.Context\n\t_, connectSpan := tr.Tracer().Start(ctx, \"stream-connect\")\n\n\tstart := time.Now()\n\toriginConn, err := originDialer.EstablishConnection(ctx, dest, logger)\n\tif err != nil {\n\t\tconnectStreamErrors.Inc()\n\t\ttracing.EndWithErrorStatus(connectSpan, err)\n\t\treturn err\n\t}\n\tconnectSpan.End()\n\tdefer originConn.Close()\n\tlogger.Debug().Msg(\"origin connection established\")\n\n\tencodedSpans := tr.GetSpans()\n\n\tif err := rwa.AckConnection(encodedSpans); err != nil {\n\t\tconnectStreamErrors.Inc()\n\t\treturn err\n\t}\n\n\tconnectLatency.Observe(float64(time.Since(start).Milliseconds()))\n\tlogger.Debug().Msg(\"proxy stream acknowledged\")\n\n\toriginConn.Stream(ctx, rwa, logger)\n\treturn nil\n}\n\n// proxyTCPStream proxies private network type TCP connections as a stream towards an available origin.\n//\n// This is different than proxyStream because it's not leveraged ingress rule services and uses the\n// originDialer from OriginDialerService.\nfunc (p *Proxy) proxyTCPStream(\n\ttr *tracing.TracedContext,\n\ttunnelConn connection.ReadWriteAcker,\n\tdest netip.AddrPort,\n\toriginDialer ingress.OriginTCPDialer,\n\tlogger *zerolog.Logger,\n) error {\n\tctx := tr.Context\n\t_, connectSpan := tr.Tracer().Start(ctx, \"stream-connect\")\n\n\tstart := time.Now()\n\toriginConn, err := originDialer.DialTCP(ctx, dest)\n\tif err != nil {\n\t\tconnectStreamErrors.Inc()\n\t\ttracing.EndWithErrorStatus(connectSpan, err)\n\t\treturn err\n\t}\n\tconnectSpan.End()\n\tdefer originConn.Close()\n\tlogger.Debug().Msg(\"origin connection established\")\n\n\tencodedSpans := tr.GetSpans()\n\n\tif err := tunnelConn.AckConnection(encodedSpans); err != nil {\n\t\tconnectStreamErrors.Inc()\n\t\treturn err\n\t}\n\n\tconnectLatency.Observe(float64(time.Since(start).Milliseconds()))\n\tlogger.Debug().Msg(\"proxy stream acknowledged\")\n\n\tstream.Pipe(tunnelConn, originConn, logger)\n\treturn nil\n}\n\nfunc (p *Proxy) proxyLocalRequest(proxy ingress.HTTPLocalProxy, w connection.ResponseWriter, req *http.Request, isWebsocket bool) {\n\tif isWebsocket {\n\t\t// These headers are added since they are stripped off during an eyeball request to origintunneld, but they\n\t\t// are required during the Handshake process of a WebSocket request.\n\t\treq.Header.Set(\"Connection\", \"Upgrade\")\n\t\treq.Header.Set(\"Upgrade\", \"websocket\")\n\t\treq.Header.Set(\"Sec-Websocket-Version\", \"13\")\n\t}\n\tproxy.ServeHTTP(w, req)\n}\n\ntype bidirectionalStream struct {\n\treader io.Reader\n\twriter io.Writer\n}\n\nfunc (wr *bidirectionalStream) Read(p []byte) (n int, err error) {\n\treturn wr.reader.Read(p)\n}\n\nfunc (wr *bidirectionalStream) Write(p []byte) (n int, err error) {\n\treturn wr.writer.Write(p)\n}\n\nfunc (p *Proxy) appendTagHeaders(r *http.Request) {\n\tfor _, tag := range p.tags {\n\t\tr.Header.Add(TagHeaderNamePrefix+tag.Name, tag.Value)\n\t}\n}\n\nfunc copyTrailers(w connection.ResponseWriter, response *http.Response) {\n\tfor trailerHeader, trailerValues := range response.Trailer {\n\t\tfor _, trailerValue := range trailerValues {\n\t\t\tw.AddTrailer(trailerHeader, trailerValue)\n\t\t}\n\t}\n}\n\nfunc getDestFromRule(rule *ingress.Rule, req *http.Request) (string, error) {\n\tswitch rule.Service.String() {\n\tcase ingress.ServiceBastion:\n\t\treturn carrier.ResolveBastionDest(req)\n\tdefault:\n\t\treturn rule.Service.String(), nil\n\t}\n}\n"
  },
  {
    "path": "proxy/proxy_posix_test.go",
    "content": "//go:build !windows\n\npackage proxy\n\nimport (\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n)\n\nfunc TestUnixSocketOrigin(t *testing.T) {\n\tfile, err := os.CreateTemp(\"\", \"unix.sock\")\n\trequire.NoError(t, err)\n\tos.Remove(file.Name()) // remove the file since binding the socket expects to create it\n\n\tl, err := net.Listen(\"unix\", file.Name())\n\trequire.NoError(t, err)\n\tdefer l.Close()\n\tdefer os.Remove(file.Name())\n\n\tapi := &httptest.Server{\n\t\tListener: l,\n\t\tConfig:   &http.Server{Handler: mockAPI{}},\n\t}\n\tapi.Start()\n\tdefer api.Close()\n\n\tunvalidatedIngress := []config.UnvalidatedIngressRule{\n\t\t{\n\t\t\tHostname: \"unix.example.com\",\n\t\t\tService:  \"unix:\" + file.Name(),\n\t\t},\n\t\t{\n\t\t\tHostname: \"*\",\n\t\t\tService:  \"http_status:404\",\n\t\t},\n\t}\n\n\ttests := []MultipleIngressTest{\n\t\t{\n\t\t\turl:            \"http://unix.example.com\",\n\t\t\texpectedStatus: http.StatusCreated,\n\t\t\texpectedBody:   []byte(\"Created\"),\n\t\t},\n\t}\n\n\trunIngressTestScenarios(t, unvalidatedIngress, tests)\n}\n"
  },
  {
    "path": "proxy/proxy_test.go",
    "content": "package proxy\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"strings\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/gobwas/ws/wsutil\"\n\tgorillaWS \"github.com/gorilla/websocket\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"github.com/urfave/cli/v2\"\n\t\"go.uber.org/mock/gomock\"\n\t\"golang.org/x/sync/errgroup\"\n\n\t\"github.com/cloudflare/cloudflared/mocks\"\n\n\tcfdflow \"github.com/cloudflare/cloudflared/flow\"\n\n\t\"github.com/cloudflare/cloudflared/cfio\"\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/connection\"\n\t\"github.com/cloudflare/cloudflared/hello\"\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\nvar (\n\ttestTags          = []pogs.Tag{{Name: \"Name\", Value: \"value\"}}\n\ttestDefaultDialer = ingress.NewDialer(ingress.WarpRoutingConfig{\n\t\tConnectTimeout: config.CustomDuration{Duration: 1 * time.Second},\n\t\tTCPKeepAlive:   config.CustomDuration{Duration: 15 * time.Second},\n\t\tMaxActiveFlows: 0,\n\t})\n)\n\ntype mockHTTPRespWriter struct {\n\t*httptest.ResponseRecorder\n}\n\nfunc newMockHTTPRespWriter() *mockHTTPRespWriter {\n\treturn &mockHTTPRespWriter{\n\t\thttptest.NewRecorder(),\n\t}\n}\n\nfunc (w *mockHTTPRespWriter) WriteResponse() error {\n\treturn nil\n}\n\nfunc (w *mockHTTPRespWriter) WriteRespHeaders(status int, header http.Header) error {\n\tw.WriteHeader(status)\n\tfor header, val := range header {\n\t\tw.Header()[header] = val\n\t}\n\treturn nil\n}\n\nfunc (w *mockHTTPRespWriter) AddTrailer(trailerName, trailerValue string) {\n\t// do nothing\n}\n\nfunc (w *mockHTTPRespWriter) Read(data []byte) (int, error) {\n\treturn 0, fmt.Errorf(\"mockHTTPRespWriter doesn't implement io.Reader\")\n}\n\nfunc (m *mockHTTPRespWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {\n\tpanic(\"Hijack not implemented\")\n}\n\ntype mockWSRespWriter struct {\n\t*mockHTTPRespWriter\n\twriteNotification chan []byte\n\treader            io.Reader\n}\n\nfunc newMockWSRespWriter(reader io.Reader) *mockWSRespWriter {\n\treturn &mockWSRespWriter{\n\t\tnewMockHTTPRespWriter(),\n\t\tmake(chan []byte),\n\t\treader,\n\t}\n}\n\nfunc (w *mockWSRespWriter) Write(data []byte) (int, error) {\n\tw.writeNotification <- data\n\treturn len(data), nil\n}\n\nfunc (w *mockWSRespWriter) respBody() io.ReadWriter {\n\tdata := <-w.writeNotification\n\treturn bytes.NewBuffer(data)\n}\n\nfunc (w *mockWSRespWriter) Close() error {\n\tclose(w.writeNotification)\n\treturn nil\n}\n\nfunc (w *mockWSRespWriter) Read(data []byte) (int, error) {\n\treturn w.reader.Read(data)\n}\n\nfunc (w *mockWSRespWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {\n\tpanic(\"Hijack not implemented\")\n}\n\ntype mockSSERespWriter struct {\n\t*mockHTTPRespWriter\n\twriteNotification chan []byte\n}\n\nfunc newMockSSERespWriter() *mockSSERespWriter {\n\treturn &mockSSERespWriter{\n\t\tnewMockHTTPRespWriter(),\n\t\tmake(chan []byte),\n\t}\n}\n\nfunc (w *mockSSERespWriter) Write(data []byte) (int, error) {\n\tnewData := make([]byte, len(data))\n\tcopy(newData, data)\n\n\tw.writeNotification <- newData\n\treturn len(data), nil\n}\n\nfunc (w *mockSSERespWriter) WriteString(str string) (int, error) {\n\treturn w.Write([]byte(str))\n}\n\nfunc (w *mockSSERespWriter) ReadBytes() []byte {\n\treturn <-w.writeNotification\n}\n\nfunc TestProxySingleOrigin(t *testing.T) {\n\tlog := zerolog.Nop()\n\n\tctx, cancel := context.WithCancel(t.Context())\n\n\tflagSet := flag.NewFlagSet(t.Name(), flag.PanicOnError)\n\tflagSet.Bool(\"hello-world\", true, \"\")\n\n\tcliCtx := cli.NewContext(cli.NewApp(), flagSet, nil)\n\terr := cliCtx.Set(\"hello-world\", \"true\")\n\trequire.NoError(t, err)\n\n\tingressRule, err := ingress.ParseIngressFromConfigAndCLI(&config.Configuration{}, cliCtx, &log)\n\trequire.NoError(t, err)\n\n\trequire.NoError(t, ingressRule.StartOrigins(&log, ctx.Done()))\n\n\toriginDialer := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 1 * time.Second,\n\t}, &log)\n\n\tproxy := NewOriginProxy(ingressRule, originDialer, testTags, cfdflow.NewLimiter(0), &log)\n\tt.Run(\"testProxyHTTP\", testProxyHTTP(proxy))\n\tt.Run(\"testProxyWebsocket\", testProxyWebsocket(proxy))\n\tt.Run(\"testProxySSE\", testProxySSE(proxy))\n\tcancel()\n}\n\nfunc testProxyHTTP(proxy connection.OriginProxy) func(t *testing.T) {\n\treturn func(t *testing.T) {\n\t\tresponseWriter := newMockHTTPRespWriter()\n\t\treq, err := http.NewRequest(http.MethodGet, \"http://localhost:8080\", nil)\n\t\trequire.NoError(t, err)\n\n\t\tlog := zerolog.Nop()\n\t\terr = proxy.ProxyHTTP(responseWriter, tracing.NewTracedHTTPRequest(req, 0, &log), false)\n\t\trequire.NoError(t, err)\n\t\tfor _, tag := range testTags {\n\t\t\tassert.Equal(t, tag.Value, req.Header.Get(TagHeaderNamePrefix+tag.Name))\n\t\t}\n\n\t\tassert.Equal(t, http.StatusOK, responseWriter.Code)\n\t}\n}\n\nfunc testProxyWebsocket(proxy connection.OriginProxy) func(t *testing.T) {\n\treturn func(t *testing.T) {\n\t\t// WSRoute is a websocket echo handler\n\t\tconst testTimeout = 5 * time.Second * 1000\n\t\tctx, cancel := context.WithTimeout(t.Context(), testTimeout)\n\t\tdefer cancel()\n\t\treadPipe, writePipe := io.Pipe()\n\t\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf(\"http://localhost:8080%s\", hello.WSRoute), readPipe)\n\t\treq.Header.Set(\"Sec-Websocket-Key\", \"dGhlIHNhbXBsZSBub25jZQ==\")\n\t\treq.Header.Set(\"Connection\", \"Upgrade\")\n\t\treq.Header.Set(\"Upgrade\", \"websocket\")\n\t\tresponseWriter := newMockWSRespWriter(nil)\n\n\t\tfinished := make(chan struct{})\n\n\t\terrGroup, ctx := errgroup.WithContext(ctx)\n\t\terrGroup.Go(func() error {\n\t\t\tlog := zerolog.Nop()\n\t\t\terr = proxy.ProxyHTTP(responseWriter, tracing.NewTracedHTTPRequest(req, 0, &log), true)\n\t\t\trequire.NoError(t, err)\n\n\t\t\trequire.Equal(t, http.StatusSwitchingProtocols, responseWriter.Code)\n\t\t\treturn nil\n\t\t})\n\n\t\terrGroup.Go(func() error {\n\t\t\tselect {\n\t\t\tcase <-finished:\n\t\t\tcase <-ctx.Done():\n\t\t\t}\n\t\t\tif ctx.Err() == context.DeadlineExceeded {\n\t\t\t\tt.Errorf(\"Test timed out\")\n\t\t\t\treadPipe.Close()\n\t\t\t\twritePipe.Close()\n\t\t\t\tresponseWriter.Close()\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\n\t\tmsg := []byte(\"test websocket\")\n\t\terr = wsutil.WriteClientText(writePipe, msg)\n\t\trequire.NoError(t, err)\n\n\t\t// ReadServerText reads next data message from rw, considering that caller represents proxy side.\n\t\treturnedMsg, err := wsutil.ReadServerText(responseWriter.respBody())\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, msg, returnedMsg)\n\n\t\terr = wsutil.WriteClientBinary(writePipe, msg)\n\t\trequire.NoError(t, err)\n\n\t\treturnedMsg, err = wsutil.ReadServerBinary(responseWriter.respBody())\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, msg, returnedMsg)\n\n\t\t_ = readPipe.Close()\n\t\t_ = writePipe.Close()\n\t\t_ = responseWriter.Close()\n\n\t\tclose(finished)\n\t\t_ = errGroup.Wait()\n\t}\n}\n\nfunc testProxySSE(proxy connection.OriginProxy) func(t *testing.T) {\n\treturn func(t *testing.T) {\n\t\tvar (\n\t\t\tpushCount = 50\n\t\t\tpushFreq  = time.Millisecond * 10\n\t\t)\n\t\tresponseWriter := newMockSSERespWriter()\n\t\tctx, cancel := context.WithCancel(t.Context())\n\t\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf(\"http://localhost:8080%s?freq=%s\", hello.SSERoute, pushFreq), nil)\n\t\trequire.NoError(t, err)\n\n\t\tvar wg sync.WaitGroup\n\t\twg.Add(1)\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\tlog := zerolog.Nop()\n\t\t\terr = proxy.ProxyHTTP(responseWriter, tracing.NewTracedHTTPRequest(req, 0, &log), false)\n\t\t\trequire.Equal(t, \"context canceled\", err.Error())\n\n\t\t\trequire.Equal(t, http.StatusOK, responseWriter.Code)\n\t\t}()\n\n\t\tfor i := 0; i < pushCount; i++ {\n\t\t\tline := responseWriter.ReadBytes()\n\t\t\texpect := fmt.Sprintf(\"%d\\n\\n\", i)\n\t\t\trequire.Equal(t, []byte(expect), line, \"Expect to read %v, got %v\", expect, line)\n\t\t}\n\n\t\tcancel()\n\t\twg.Wait()\n\t}\n}\n\n// Regression test to guarantee that we always write the contents downstream even if EOF is reached without\n// hitting the delimiter\nfunc TestProxySSEAllData(t *testing.T) {\n\teyeballReader := io.NopCloser(strings.NewReader(\"data\\r\\r\"))\n\tresponseWriter := newMockSSERespWriter()\n\n\t// responseWriter uses an unbuffered channel, so we call in a different go-routine\n\tgo func() {\n\t\t_, _ = cfio.Copy(responseWriter, eyeballReader)\n\t}()\n\n\tresult := string(<-responseWriter.writeNotification)\n\trequire.Equal(t, \"data\\r\\r\", result)\n}\n\nfunc TestProxyMultipleOrigins(t *testing.T) {\n\tapi := httptest.NewServer(mockAPI{})\n\tdefer api.Close()\n\n\tunvalidatedIngress := []config.UnvalidatedIngressRule{\n\t\t{\n\t\t\tHostname: \"api.example.com\",\n\t\t\tService:  api.URL,\n\t\t},\n\t\t{\n\t\t\tHostname: \"hello.example.com\",\n\t\t\tService:  \"hello-world\",\n\t\t},\n\t\t{\n\t\t\tHostname: \"health.example.com\",\n\t\t\tPath:     \"/health\",\n\t\t\tService:  \"http_status:200\",\n\t\t},\n\t\t{\n\t\t\tHostname: \"*\",\n\t\t\tService:  \"http_status:404\",\n\t\t},\n\t}\n\n\ttests := []MultipleIngressTest{\n\t\t{\n\t\t\turl:            \"http://api.example.com\",\n\t\t\texpectedStatus: http.StatusCreated,\n\t\t\texpectedBody:   []byte(\"Created\"),\n\t\t},\n\t\t{\n\t\t\turl:            fmt.Sprintf(\"http://hello.example.com%s\", hello.HealthRoute),\n\t\t\texpectedStatus: http.StatusOK,\n\t\t\texpectedBody:   []byte(\"ok\"),\n\t\t},\n\t\t{\n\t\t\turl:            \"http://health.example.com/health\",\n\t\t\texpectedStatus: http.StatusOK,\n\t\t},\n\t\t{\n\t\t\turl:            \"http://health.example.com/\",\n\t\t\texpectedStatus: http.StatusNotFound,\n\t\t},\n\t\t{\n\t\t\turl:            \"http://not-found.example.com\",\n\t\t\texpectedStatus: http.StatusNotFound,\n\t\t},\n\t}\n\n\trunIngressTestScenarios(t, unvalidatedIngress, tests)\n}\n\ntype MultipleIngressTest struct {\n\turl            string\n\texpectedStatus int\n\texpectedBody   []byte\n}\n\nfunc runIngressTestScenarios(t *testing.T, unvalidatedIngress []config.UnvalidatedIngressRule, tests []MultipleIngressTest) {\n\tingressRule, err := ingress.ParseIngress(&config.Configuration{\n\t\tTunnelID: t.Name(),\n\t\tIngress:  unvalidatedIngress,\n\t})\n\trequire.NoError(t, err)\n\n\tlog := zerolog.Nop()\n\n\tctx, cancel := context.WithCancel(t.Context())\n\trequire.NoError(t, ingressRule.StartOrigins(&log, ctx.Done()))\n\n\toriginDialer := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 1 * time.Second,\n\t}, &log)\n\n\tproxy := NewOriginProxy(ingressRule, originDialer, testTags, cfdflow.NewLimiter(0), &log)\n\n\tfor _, test := range tests {\n\t\tresponseWriter := newMockHTTPRespWriter()\n\t\treq, err := http.NewRequest(http.MethodGet, test.url, nil)\n\t\trequire.NoError(t, err)\n\n\t\terr = proxy.ProxyHTTP(responseWriter, tracing.NewTracedHTTPRequest(req, 0, &log), false)\n\t\trequire.NoError(t, err)\n\n\t\tassert.Equal(t, test.expectedStatus, responseWriter.Code)\n\t\tif test.expectedBody != nil {\n\t\t\tassert.Equal(t, test.expectedBody, responseWriter.Body.Bytes())\n\t\t} else {\n\t\t\tassert.Equal(t, 0, responseWriter.Body.Len())\n\t\t}\n\t}\n\tcancel()\n}\n\ntype mockAPI struct{}\n\nfunc (ma mockAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tw.WriteHeader(http.StatusCreated)\n\t_, _ = w.Write([]byte(\"Created\"))\n}\n\ntype errorOriginTransport struct{}\n\nfunc (errorOriginTransport) RoundTrip(*http.Request) (*http.Response, error) {\n\treturn nil, fmt.Errorf(\"Proxy error\")\n}\n\nfunc TestProxyError(t *testing.T) {\n\ting := ingress.Ingress{\n\t\tRules: []ingress.Rule{\n\t\t\t{\n\t\t\t\tHostname: \"*\",\n\t\t\t\tPath:     nil,\n\t\t\t\tService: ingress.MockOriginHTTPService{\n\t\t\t\t\tTransport: errorOriginTransport{},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tlog := zerolog.Nop()\n\n\toriginDialer := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 1 * time.Second,\n\t}, &log)\n\n\tproxy := NewOriginProxy(ing, originDialer, testTags, cfdflow.NewLimiter(0), &log)\n\n\tresponseWriter := newMockHTTPRespWriter()\n\treq, err := http.NewRequest(http.MethodGet, \"http://127.0.0.1\", nil)\n\trequire.NoError(t, err)\n\n\trequire.Error(t, proxy.ProxyHTTP(responseWriter, tracing.NewTracedHTTPRequest(req, 0, &log), false))\n}\n\ntype replayer struct {\n\tsync.RWMutex\n\trw *bytes.Buffer\n}\n\nfunc (r *replayer) Read(p []byte) (int, error) {\n\tr.RLock()\n\tdefer r.RUnlock()\n\treturn r.rw.Read(p)\n}\n\nfunc (r *replayer) Write(p []byte) (int, error) {\n\tr.Lock()\n\tdefer r.Unlock()\n\tn, err := r.rw.Write(p)\n\treturn n, err\n}\n\nfunc (r *replayer) String() string {\n\tr.Lock()\n\tdefer r.Unlock()\n\treturn r.rw.String()\n}\n\nfunc (r *replayer) Bytes() []byte {\n\tr.Lock()\n\tdefer r.Unlock()\n\treturn r.rw.Bytes()\n}\n\n// TestConnections tests every possible permutation of connection protocols\n// proxied by cloudflared.\n//\n// WS - WS : When a websocket based ingress is configured on the origin and\n// the eyeball is also a websocket client streaming data.\n// TCP - TCP : When teamnet is enabled and an http or tcp service is running\n// on the origin.\n// TCP - WS: When teamnet is enabled and a websocket based service is running\n// on the origin.\n// WS - TCP: When a tcp based ingress is configured on the origin and the\n// eyeball sends tcp packets wrapped in websockets. (E.g: cloudflared access).\nfunc TestConnections(t *testing.T) {\n\tlog := zerolog.Nop()\n\treplayer := &replayer{rw: bytes.NewBuffer([]byte{})}\n\ttype args struct {\n\t\tingressServiceScheme  string\n\t\toriginService         func(*testing.T, net.Listener)\n\t\teyeballResponseWriter connection.ResponseWriter\n\t\teyeballRequestBody    io.ReadCloser\n\n\t\t// eyeball connection type.\n\t\tconnectionType connection.Type\n\n\t\t// requestheaders to be sent in the call to proxy.Proxy\n\t\trequestHeaders http.Header\n\n\t\t// flowLimiterResponse is the response of the cfdflow.Limiter#Acquire method call\n\t\tflowLimiterResponse error\n\t}\n\n\toriginDialer := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 0,\n\t}, &log)\n\n\ttype want struct {\n\t\tmessage []byte\n\t\theaders http.Header\n\t\terr     bool\n\t}\n\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant want\n\t}{\n\t\t{\n\t\t\tname: \"ws-ws proxy\",\n\t\t\targs: args{\n\t\t\t\tingressServiceScheme:  \"ws://\",\n\t\t\t\toriginService:         runEchoWSService,\n\t\t\t\teyeballResponseWriter: newWSRespWriter(replayer),\n\t\t\t\teyeballRequestBody:    newWSRequestBody([]byte(\"test1\")),\n\t\t\t\tconnectionType:        connection.TypeWebsocket,\n\t\t\t\trequestHeaders: map[string][]string{\n\t\t\t\t\t// Example key from https://tools.ietf.org/html/rfc6455#section-1.2\n\t\t\t\t\t\"Sec-Websocket-Key\":     {\"dGhlIHNhbXBsZSBub25jZQ==\"},\n\t\t\t\t\t\"Test-Cloudflared-Echo\": {\"Echo\"},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: want{\n\t\t\t\tmessage: []byte(\"echo-test1\"),\n\t\t\t\theaders: map[string][]string{\n\t\t\t\t\t\"Connection\":            {\"Upgrade\"},\n\t\t\t\t\t\"Sec-Websocket-Accept\":  {\"s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\"},\n\t\t\t\t\t\"Upgrade\":               {\"websocket\"},\n\t\t\t\t\t\"Test-Cloudflared-Echo\": {\"Echo\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"tcp-tcp proxy\",\n\t\t\targs: args{\n\t\t\t\tingressServiceScheme:  \"tcp://\",\n\t\t\t\toriginService:         runEchoTCPService,\n\t\t\t\teyeballResponseWriter: newTCPRespWriter(replayer),\n\t\t\t\teyeballRequestBody:    newTCPRequestBody([]byte(\"test2\")),\n\t\t\t\tconnectionType:        connection.TypeTCP,\n\t\t\t\trequestHeaders: map[string][]string{\n\t\t\t\t\t\"Cf-Cloudflared-Proxy-Src\": {\"non-blank-value\"},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: want{\n\t\t\t\tmessage: []byte(\"echo-test2\"),\n\t\t\t\theaders: http.Header{},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"tcp-ws proxy\",\n\t\t\targs: args{\n\t\t\t\tingressServiceScheme: \"ws://\",\n\t\t\t\toriginService:        runEchoWSService,\n\t\t\t\t// eyeballResponseWriter gets set after roundtrip dial.\n\t\t\t\teyeballRequestBody: newPipedWSRequestBody([]byte(\"test3\")),\n\t\t\t\trequestHeaders: map[string][]string{\n\t\t\t\t\t\"Cf-Cloudflared-Proxy-Src\": {\"non-blank-value\"},\n\t\t\t\t},\n\t\t\t\tconnectionType: connection.TypeTCP,\n\t\t\t},\n\t\t\twant: want{\n\t\t\t\tmessage: []byte(\"echo-test3\"),\n\t\t\t\t// We expect no headers here because they are sent back via\n\t\t\t\t// the stream.\n\t\t\t\theaders: http.Header{},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"ws-tcp proxy\",\n\t\t\targs: args{\n\t\t\t\tingressServiceScheme:  \"tcp://\",\n\t\t\t\toriginService:         runEchoTCPService,\n\t\t\t\teyeballResponseWriter: newWSRespWriter(replayer),\n\t\t\t\teyeballRequestBody:    newWSRequestBody([]byte(\"test4\")),\n\t\t\t\tconnectionType:        connection.TypeWebsocket,\n\t\t\t\trequestHeaders: map[string][]string{\n\t\t\t\t\t// Example key from https://tools.ietf.org/html/rfc6455#section-1.2\n\t\t\t\t\t\"Sec-Websocket-Key\": {\"dGhlIHNhbXBsZSBub25jZQ==\"},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: want{\n\t\t\t\tmessage: []byte(\"echo-test4\"),\n\t\t\t\theaders: map[string][]string{\n\t\t\t\t\t\"Connection\":           {\"Upgrade\"},\n\t\t\t\t\t\"Sec-Websocket-Accept\": {\"s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\"},\n\t\t\t\t\t\"Upgrade\":              {\"websocket\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t// Send (unexpected) HTTP when origin expects WS (to unwrap for raw TCP)\n\t\t\tname: \"http-(ws)tcp proxy\",\n\t\t\targs: args{\n\t\t\t\tingressServiceScheme:  \"tcp://\",\n\t\t\t\toriginService:         runEchoTCPService,\n\t\t\t\teyeballResponseWriter: newMockHTTPRespWriter(),\n\t\t\t\teyeballRequestBody:    http.NoBody,\n\t\t\t\tconnectionType:        connection.TypeHTTP,\n\t\t\t\trequestHeaders: map[string][]string{\n\t\t\t\t\t\"Cf-Cloudflared-Proxy-Src\": {\"non-blank-value\"},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: want{\n\t\t\t\tmessage: []byte{},\n\t\t\t\theaders: map[string][]string{},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"ws-ws proxy when origin is different\",\n\t\t\targs: args{\n\t\t\t\tingressServiceScheme:  \"ws://\",\n\t\t\t\toriginService:         runEchoWSService,\n\t\t\t\teyeballResponseWriter: newWSRespWriter(replayer),\n\t\t\t\teyeballRequestBody:    newWSRequestBody([]byte(\"test1\")),\n\t\t\t\tconnectionType:        connection.TypeWebsocket,\n\t\t\t\trequestHeaders: map[string][]string{\n\t\t\t\t\t// Example key from https://tools.ietf.org/html/rfc6455#section-1.2\n\t\t\t\t\t\"Sec-Websocket-Key\": {\"dGhlIHNhbXBsZSBub25jZQ==\"},\n\t\t\t\t\t\"Origin\":            {\"Different origin\"},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: want{\n\t\t\t\tmessage: []byte(\"Forbidden\\n\"),\n\t\t\t\terr:     false,\n\t\t\t\theaders: map[string][]string{\n\t\t\t\t\t\"Content-Length\":         {\"10\"},\n\t\t\t\t\t\"Content-Type\":           {\"text/plain; charset=utf-8\"},\n\t\t\t\t\t\"Sec-Websocket-Version\":  {\"13\"},\n\t\t\t\t\t\"X-Content-Type-Options\": {\"nosniff\"},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"tcp-* proxy when origin service has already closed the connection/ is no longer running\",\n\t\t\targs: args{\n\t\t\t\tingressServiceScheme: \"tcp://\",\n\t\t\t\toriginService: func(t *testing.T, ln net.Listener) {\n\t\t\t\t\t// closing the listener created by the test.\n\t\t\t\t\tln.Close()\n\t\t\t\t},\n\t\t\t\teyeballResponseWriter: newTCPRespWriter(replayer),\n\t\t\t\teyeballRequestBody:    newTCPRequestBody([]byte(\"test2\")),\n\t\t\t\tconnectionType:        connection.TypeTCP,\n\t\t\t\trequestHeaders: map[string][]string{\n\t\t\t\t\t\"Cf-Cloudflared-Proxy-Src\": {\"non-blank-value\"},\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: want{\n\t\t\t\tmessage: []byte{},\n\t\t\t\terr:     true,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"tcp-* proxy rate limited flow\",\n\t\t\targs: args{\n\t\t\t\tingressServiceScheme:  \"tcp://\",\n\t\t\t\toriginService:         runEchoTCPService,\n\t\t\t\teyeballResponseWriter: newTCPRespWriter(replayer),\n\t\t\t\teyeballRequestBody:    newTCPRequestBody([]byte(\"rate-limited\")),\n\t\t\t\tconnectionType:        connection.TypeTCP,\n\t\t\t\trequestHeaders: map[string][]string{\n\t\t\t\t\t\"Cf-Cloudflared-Proxy-Src\": {\"non-blank-value\"},\n\t\t\t\t},\n\t\t\t\tflowLimiterResponse: cfdflow.ErrTooManyActiveFlows,\n\t\t\t},\n\t\t\twant: want{\n\t\t\t\tmessage: []byte{},\n\t\t\t\terr:     true,\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\tctx, cancel := context.WithCancel(t.Context())\n\t\t\tln, err := net.Listen(\"tcp\", \"127.0.0.1:0\")\n\t\t\trequire.NoError(t, err)\n\t\t\t// Starts origin service\n\t\t\ttest.args.originService(t, ln)\n\n\t\t\tingressRule := createSingleIngressConfig(t, test.args.ingressServiceScheme+ln.Addr().String())\n\t\t\t_ = ingressRule.StartOrigins(&log, ctx.Done())\n\n\t\t\t// Mock flow limiter\n\t\t\tctrl := gomock.NewController(t)\n\t\t\tdefer ctrl.Finish()\n\t\t\tflowLimiter := mocks.NewMockLimiter(ctrl)\n\t\t\tflowLimiter.EXPECT().Acquire(\"tcp\").AnyTimes().Return(test.args.flowLimiterResponse)\n\t\t\tflowLimiter.EXPECT().Release().AnyTimes()\n\n\t\t\tproxy := NewOriginProxy(ingressRule, originDialer, testTags, flowLimiter, &log)\n\n\t\t\tdest := ln.Addr().String()\n\t\t\treq, err := http.NewRequest(\n\t\t\t\thttp.MethodGet,\n\t\t\t\ttest.args.ingressServiceScheme+ln.Addr().String(),\n\t\t\t\ttest.args.eyeballRequestBody,\n\t\t\t)\n\t\t\trequire.NoError(t, err)\n\n\t\t\treq.Header = test.args.requestHeaders\n\t\t\trespWriter := test.args.eyeballResponseWriter\n\n\t\t\tif pipedReqBody, ok := test.args.eyeballRequestBody.(*pipedRequestBody); ok {\n\t\t\t\trespWriter = newTCPRespWriter(pipedReqBody.pipedConn)\n\t\t\t\tgo func() {\n\t\t\t\t\tresp := pipedReqBody.roundtrip(test.args.ingressServiceScheme + ln.Addr().String())\n\t\t\t\t\t_, _ = replayer.Write(resp)\n\t\t\t\t}()\n\t\t\t}\n\t\t\tif test.args.connectionType == connection.TypeTCP {\n\t\t\t\trwa := connection.NewHTTPResponseReadWriterAcker(respWriter, respWriter.(http.Flusher), req)\n\t\t\t\terr = proxy.ProxyTCP(ctx, rwa, &connection.TCPRequest{Dest: dest})\n\t\t\t} else {\n\t\t\t\tlog := zerolog.Nop()\n\t\t\t\terr = proxy.ProxyHTTP(respWriter, tracing.NewTracedHTTPRequest(req, 0, &log), test.args.connectionType == connection.TypeWebsocket)\n\t\t\t}\n\n\t\t\tcancel()\n\t\t\trequire.Equal(t, test.want.err, err != nil)\n\t\t\trequire.Equal(t, test.want.message, replayer.Bytes())\n\t\t\trequire.Equal(t, test.want.headers, respWriter.Header())\n\t\t\treplayer.rw.Reset()\n\t\t})\n\t}\n}\n\ntype requestBody struct {\n\tpw *io.PipeWriter\n\tpr *io.PipeReader\n}\n\nfunc newWSRequestBody(data []byte) *requestBody {\n\tpr, pw := io.Pipe()\n\tgo func() {\n\t\t_ = wsutil.WriteClientBinary(pw, data)\n\t}()\n\treturn &requestBody{\n\t\tpr: pr,\n\t\tpw: pw,\n\t}\n}\n\nfunc newTCPRequestBody(data []byte) *requestBody {\n\tpr, pw := io.Pipe()\n\tgo func() {\n\t\t_, _ = pw.Write(data)\n\t}()\n\treturn &requestBody{\n\t\tpr: pr,\n\t\tpw: pw,\n\t}\n}\n\nfunc (r *requestBody) Read(p []byte) (n int, err error) {\n\treturn r.pr.Read(p)\n}\n\nfunc (r *requestBody) Close() error {\n\t_ = r.pw.Close()\n\t_ = r.pr.Close()\n\treturn nil\n}\n\ntype pipedRequestBody struct {\n\tdialer         gorillaWS.Dialer\n\tpipedConn      net.Conn\n\twsConn         net.Conn\n\tmessageToWrite []byte\n}\n\nfunc newPipedWSRequestBody(data []byte) *pipedRequestBody {\n\tconn1, conn2 := net.Pipe()\n\tdialer := gorillaWS.Dialer{\n\t\tNetDial: func(network, addr string) (net.Conn, error) {\n\t\t\treturn conn2, nil\n\t\t},\n\t}\n\treturn &pipedRequestBody{\n\t\tdialer:         dialer,\n\t\tpipedConn:      conn1,\n\t\twsConn:         conn2,\n\t\tmessageToWrite: data,\n\t}\n}\n\nfunc (p *pipedRequestBody) roundtrip(addr string) []byte {\n\theader := http.Header{}\n\tconn, resp, err := p.dialer.Dial(addr, header)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer conn.Close()\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusSwitchingProtocols {\n\t\tpanic(fmt.Errorf(\"resp returned status code: %d\", resp.StatusCode))\n\t}\n\n\terr = conn.WriteMessage(gorillaWS.TextMessage, p.messageToWrite)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t_, data, err := conn.ReadMessage()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treturn data\n}\n\nfunc (p *pipedRequestBody) Read(data []byte) (n int, err error) {\n\treturn p.pipedConn.Read(data)\n}\n\nfunc (p *pipedRequestBody) Close() error {\n\treturn nil\n}\n\ntype wsRespWriter struct {\n\tw               io.Writer\n\tresponseHeaders http.Header\n\tcode            int\n}\n\n// newWSRespWriter uses wsutil.WriteClientText to generate websocket frames.\n// and wsutil.ReadClientText to translate frames from server to byte data.\n// In essence, this acts as a wsClient.\nfunc newWSRespWriter(w io.Writer) *wsRespWriter {\n\treturn &wsRespWriter{\n\t\tw: w,\n\t}\n}\n\n// Write is written to by ingress.Stream and serves as the output to the client.\nfunc (w *wsRespWriter) Write(p []byte) (int, error) {\n\treturnedMsg, err := wsutil.ReadServerBinary(bytes.NewBuffer(p))\n\tif err != nil {\n\t\t// The data was not returned by a websocket connection.\n\t\tif err != io.ErrUnexpectedEOF {\n\t\t\treturn w.w.Write(p)\n\t\t}\n\t}\n\treturn w.w.Write(returnedMsg)\n}\n\nfunc (w *wsRespWriter) WriteRespHeaders(status int, header http.Header) error {\n\tw.responseHeaders = header\n\tw.code = status\n\treturn nil\n}\n\nfunc (w *wsRespWriter) Flush() {}\n\nfunc (w *wsRespWriter) AddTrailer(trailerName, trailerValue string) {\n\t// do nothing\n}\n\n// respHeaders is a test function to read respHeaders\nfunc (w *wsRespWriter) Header() http.Header {\n\t// Removing indeterminstic header because it cannot be asserted.\n\tw.responseHeaders.Del(\"Date\")\n\treturn w.responseHeaders\n}\n\nfunc (w *wsRespWriter) WriteHeader(status int) {\n\t// unused\n}\n\nfunc (m *wsRespWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {\n\tpanic(\"Hijack not implemented\")\n}\n\ntype mockTCPRespWriter struct {\n\tw               io.Writer\n\tresponseHeaders http.Header\n\tcode            int\n}\n\nfunc newTCPRespWriter(w io.Writer) *mockTCPRespWriter {\n\treturn &mockTCPRespWriter{\n\t\tw: w,\n\t}\n}\n\nfunc (m *mockTCPRespWriter) Read(p []byte) (n int, err error) {\n\treturn len(p), nil\n}\n\nfunc (m *mockTCPRespWriter) Write(p []byte) (n int, err error) {\n\treturn m.w.Write(p)\n}\n\nfunc (m *mockTCPRespWriter) Flush() {}\n\nfunc (m *mockTCPRespWriter) AddTrailer(trailerName, trailerValue string) {\n\t// do nothing\n}\n\nfunc (m *mockTCPRespWriter) WriteRespHeaders(status int, header http.Header) error {\n\tm.responseHeaders = header\n\tm.code = status\n\treturn nil\n}\n\n// respHeaders is a test function to read respHeaders\nfunc (m *mockTCPRespWriter) Header() http.Header {\n\treturn m.responseHeaders\n}\n\nfunc (m *mockTCPRespWriter) WriteHeader(status int) {\n\t// do nothing\n}\n\nfunc (m *mockTCPRespWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {\n\tpanic(\"Hijack not implemented\")\n}\n\nfunc createSingleIngressConfig(t *testing.T, service string) ingress.Ingress {\n\tingressConfig := &config.Configuration{\n\t\tIngress: []config.UnvalidatedIngressRule{\n\t\t\t{\n\t\t\t\tHostname: \"*\",\n\t\t\t\tService:  service,\n\t\t\t},\n\t\t},\n\t}\n\tingressRule, err := ingress.ParseIngress(ingressConfig)\n\trequire.NoError(t, err)\n\treturn ingressRule\n}\n\nfunc runEchoTCPService(t *testing.T, l net.Listener) {\n\tgo func() {\n\t\tfor {\n\t\t\tconn, err := l.Accept()\n\t\t\tif err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\t\t\tdefer conn.Close()\n\n\t\t\tfor {\n\t\t\t\tbuf := make([]byte, 1024)\n\t\t\t\tsize, err := conn.Read(buf)\n\t\t\t\tif err == io.EOF {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tdata := []byte(\"echo-\")\n\t\t\t\tdata = append(data, buf[:size]...)\n\t\t\t\t_, err = conn.Write(data)\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Log(err)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n}\n\nfunc runEchoWSService(t *testing.T, l net.Listener) {\n\tupgrader := gorillaWS.Upgrader{\n\t\tReadBufferSize:  10,\n\t\tWriteBufferSize: 10,\n\t}\n\n\tws := func(w http.ResponseWriter, r *http.Request) {\n\t\theader := make(http.Header)\n\t\tfor k, vs := range r.Header {\n\t\t\tif k == \"Test-Cloudflared-Echo\" {\n\t\t\t\theader[k] = vs\n\t\t\t}\n\t\t}\n\t\tconn, err := upgrader.Upgrade(w, r, header)\n\t\tif err != nil {\n\t\t\tt.Log(err)\n\t\t\treturn\n\t\t}\n\t\tdefer conn.Close()\n\n\t\tfor {\n\t\t\tmessageType, p, err := conn.ReadMessage()\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdata := []byte(\"echo-\")\n\t\t\tdata = append(data, p...)\n\t\t\tif err := conn.WriteMessage(messageType, data); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// nolint: gosec\n\tserver := http.Server{\n\t\tHandler: http.HandlerFunc(ws),\n\t}\n\n\tgo func() {\n\t\terr := server.Serve(l)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}()\n}\n"
  },
  {
    "path": "quic/constants.go",
    "content": "package quic\n\nimport \"time\"\n\nconst (\n\tHandshakeIdleTimeout = 5 * time.Second\n\tMaxIdleTimeout       = 5 * time.Second\n\tMaxIdlePingPeriod    = 1 * time.Second\n\n\t// MaxIncomingStreams is 2^60, which is the maximum supported value by Quic-Go\n\tMaxIncomingStreams = 1 << 60\n)\n"
  },
  {
    "path": "quic/conversion.go",
    "content": "package quic\n\nimport (\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/logging\"\n)\n\n// Helper to convert logging.ByteCount(alias for int64) to float64 used in prometheus\nfunc byteCountToPromCount(count logging.ByteCount) float64 {\n\treturn float64(count)\n}\n\n// Helper to convert Duration to float64 used in prometheus\nfunc durationToPromGauge(duration time.Duration) float64 {\n\treturn float64(duration.Milliseconds())\n}\n\n// Helper to convert https://pkg.go.dev/github.com/quic-go/quic-go@v0.23.0/logging#PacketType into string\nfunc packetTypeString(pt logging.PacketType) string {\n\tswitch pt {\n\tcase logging.PacketTypeInitial:\n\t\treturn \"initial\"\n\tcase logging.PacketTypeHandshake:\n\t\treturn \"handshake\"\n\tcase logging.PacketTypeRetry:\n\t\treturn \"retry\"\n\tcase logging.PacketType0RTT:\n\t\treturn \"0_rtt\"\n\tcase logging.PacketTypeVersionNegotiation:\n\t\treturn \"version_negotiation\"\n\tcase logging.PacketType1RTT:\n\t\treturn \"1_rtt\"\n\tcase logging.PacketTypeStatelessReset:\n\t\treturn \"stateless_reset\"\n\tcase logging.PacketTypeNotDetermined:\n\t\treturn \"undetermined\"\n\tdefault:\n\t\treturn \"unknown_packet_type\"\n\t}\n}\n\n// Helper to convert https://pkg.go.dev/github.com/quic-go/quic-go@v0.23.0/logging#PacketDropReason into string\nfunc packetDropReasonString(reason logging.PacketDropReason) string {\n\tswitch reason {\n\tcase logging.PacketDropKeyUnavailable:\n\t\treturn \"key_unavailable\"\n\tcase logging.PacketDropUnknownConnectionID:\n\t\treturn \"unknown_conn_id\"\n\tcase logging.PacketDropHeaderParseError:\n\t\treturn \"header_parse_err\"\n\tcase logging.PacketDropPayloadDecryptError:\n\t\treturn \"payload_decrypt_err\"\n\tcase logging.PacketDropProtocolViolation:\n\t\treturn \"protocol_violation\"\n\tcase logging.PacketDropDOSPrevention:\n\t\treturn \"dos_prevention\"\n\tcase logging.PacketDropUnsupportedVersion:\n\t\treturn \"unsupported_version\"\n\tcase logging.PacketDropUnexpectedPacket:\n\t\treturn \"unexpected_packet\"\n\tcase logging.PacketDropUnexpectedSourceConnectionID:\n\t\treturn \"unexpected_src_conn_id\"\n\tcase logging.PacketDropUnexpectedVersion:\n\t\treturn \"unexpected_version\"\n\tcase logging.PacketDropDuplicate:\n\t\treturn \"duplicate\"\n\tdefault:\n\t\treturn \"unknown_reason\"\n\t}\n}\n\n// Helper to convert https://pkg.go.dev/github.com/quic-go/quic-go@v0.23.0/logging#PacketLossReason into string\nfunc packetLossReasonString(reason logging.PacketLossReason) string {\n\tswitch reason {\n\tcase logging.PacketLossReorderingThreshold:\n\t\treturn \"reordering\"\n\tcase logging.PacketLossTimeThreshold:\n\t\treturn \"timeout\"\n\tdefault:\n\t\treturn \"unknown_loss_reason\"\n\t}\n}\n\nfunc uint8ToString(input uint8) string {\n\treturn strconv.FormatUint(uint64(input), 10)\n}\n"
  },
  {
    "path": "quic/datagram.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/quic-go/quic-go\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n)\n\nconst (\n\tsessionIDLen = len(uuid.UUID{})\n)\n\ntype BaseDatagramMuxer interface {\n\t// SendToSession suffix the session ID to the payload so the other end of the QUIC connection can demultiplex the\n\t// payload from multiple datagram sessions.\n\tSendToSession(session *packet.Session) error\n\t// ServeReceive starts a loop to receive datagrams from the QUIC connection\n\tServeReceive(ctx context.Context) error\n}\n\ntype DatagramMuxer struct {\n\tsession   quic.Connection\n\tlogger    *zerolog.Logger\n\tdemuxChan chan<- *packet.Session\n}\n\nfunc NewDatagramMuxer(quicSession quic.Connection, log *zerolog.Logger, demuxChan chan<- *packet.Session) *DatagramMuxer {\n\tlogger := log.With().Uint8(\"datagramVersion\", 1).Logger()\n\treturn &DatagramMuxer{\n\t\tsession:   quicSession,\n\t\tlogger:    &logger,\n\t\tdemuxChan: demuxChan,\n\t}\n}\n\n// Maximum application payload to send to / receive from QUIC datagram frame\nfunc (dm *DatagramMuxer) mtu() int {\n\treturn maxDatagramPayloadSize\n}\n\nfunc (dm *DatagramMuxer) SendToSession(session *packet.Session) error {\n\tif len(session.Payload) > dm.mtu() {\n\t\tpacketTooBigDropped.Inc()\n\t\treturn fmt.Errorf(\"origin UDP payload has %d bytes, which exceeds transport MTU %d\", len(session.Payload), dm.mtu())\n\t}\n\tpayloadWithMetadata, err := SuffixSessionID(session.ID, session.Payload)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Failed to suffix session ID to datagram, it will be dropped\")\n\t}\n\tif err := dm.session.SendDatagram(payloadWithMetadata); err != nil {\n\t\treturn errors.Wrap(err, \"Failed to send datagram back to edge\")\n\t}\n\treturn nil\n}\n\nfunc (dm *DatagramMuxer) ServeReceive(ctx context.Context) error {\n\tfor {\n\t\t// Extracts datagram session ID, then sends the session ID and payload to receiver\n\t\t// which determines how to proxy to the origin. It assumes the datagram session has already been\n\t\t// registered with receiver through other side channel\n\t\tmsg, err := dm.session.ReceiveDatagram(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := dm.demux(ctx, msg); err != nil {\n\t\t\tdm.logger.Error().Err(err).Msg(\"Failed to demux datagram\")\n\t\t\tif err == context.Canceled {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (dm *DatagramMuxer) demux(ctx context.Context, msg []byte) error {\n\tsessionID, payload, err := extractSessionID(msg)\n\tif err != nil {\n\t\treturn err\n\t}\n\tsessionDatagram := packet.Session{\n\t\tID:      sessionID,\n\t\tPayload: payload,\n\t}\n\tselect {\n\tcase dm.demuxChan <- &sessionDatagram:\n\t\treturn nil\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\t}\n}\n\n// Each QUIC datagram should be suffixed with session ID.\n// extractSessionID extracts the session ID and a slice with only the payload\nfunc extractSessionID(b []byte) (uuid.UUID, []byte, error) {\n\tmsgLen := len(b)\n\tif msgLen < sessionIDLen {\n\t\treturn uuid.Nil, nil, fmt.Errorf(\"session ID has %d bytes, but data only has %d\", sessionIDLen, len(b))\n\t}\n\t// Parse last 16 bytess as UUID and remove it from slice\n\tsessionID, err := uuid.FromBytes(b[len(b)-sessionIDLen:])\n\tif err != nil {\n\t\treturn uuid.Nil, nil, err\n\t}\n\tb = b[:len(b)-sessionIDLen]\n\treturn sessionID, b, nil\n}\n\n// SuffixSessionID appends the session ID at the end of the payload. Suffix is more performant than prefix because\n// the payload slice might already have enough capacity to append the session ID at the end\nfunc SuffixSessionID(sessionID uuid.UUID, b []byte) ([]byte, error) {\n\treturn suffixMetadata(b, sessionID[:])\n}\n\nfunc suffixMetadata(payload, metadata []byte) ([]byte, error) {\n\tif len(payload)+len(metadata) > MaxDatagramFrameSize {\n\t\treturn nil, fmt.Errorf(\"datagram size exceed %d\", MaxDatagramFrameSize)\n\t}\n\treturn append(payload, metadata...), nil\n}\n"
  },
  {
    "path": "quic/datagram_test.go",
    "content": "package quic\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"encoding/pem\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"net\"\n\t\"net/netip\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/gopacket/layers\"\n\t\"github.com/google/uuid\"\n\t\"github.com/quic-go/quic-go\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/require\"\n\t\"golang.org/x/net/icmp\"\n\t\"golang.org/x/net/ipv4\"\n\t\"golang.org/x/sync/errgroup\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n)\n\nvar (\n\ttestSessionID = uuid.New()\n)\n\nfunc TestSuffixThenRemoveSessionID(t *testing.T) {\n\tmsg := []byte(t.Name())\n\tmsgWithID, err := SuffixSessionID(testSessionID, msg)\n\trequire.NoError(t, err)\n\trequire.Len(t, msgWithID, len(msg)+sessionIDLen)\n\n\tsessionID, msgWithoutID, err := extractSessionID(msgWithID)\n\trequire.NoError(t, err)\n\trequire.Equal(t, msg, msgWithoutID)\n\trequire.Equal(t, testSessionID, sessionID)\n}\n\nfunc TestRemoveSessionIDError(t *testing.T) {\n\t// message is too short to contain session ID\n\tmsg := []byte(\"test\")\n\t_, _, err := extractSessionID(msg)\n\trequire.Error(t, err)\n}\n\nfunc TestSuffixSessionIDError(t *testing.T) {\n\tmsg := make([]byte, MaxDatagramFrameSize-sessionIDLen)\n\t_, err := SuffixSessionID(testSessionID, msg)\n\trequire.NoError(t, err)\n\n\tmsg = make([]byte, MaxDatagramFrameSize-sessionIDLen+1)\n\t_, err = SuffixSessionID(testSessionID, msg)\n\trequire.Error(t, err)\n}\n\nfunc TestDatagram(t *testing.T) {\n\tmaxPayload := make([]byte, maxDatagramPayloadSize)\n\tnoPayloadSession := uuid.New()\n\tmaxPayloadSession := uuid.New()\n\tsessionToPayload := []*packet.Session{\n\t\t{\n\t\t\tID:      noPayloadSession,\n\t\t\tPayload: make([]byte, 0),\n\t\t},\n\t\t{\n\t\t\tID:      maxPayloadSession,\n\t\t\tPayload: maxPayload,\n\t\t},\n\t}\n\n\tpackets := []packet.ICMP{\n\t\t{\n\t\t\tIP: &packet.IP{\n\t\t\t\tSrc:      netip.MustParseAddr(\"172.16.0.1\"),\n\t\t\t\tDst:      netip.MustParseAddr(\"192.168.0.1\"),\n\t\t\t\tProtocol: layers.IPProtocolICMPv4,\n\t\t\t},\n\t\t\tMessage: &icmp.Message{\n\t\t\t\tType: ipv4.ICMPTypeTimeExceeded,\n\t\t\t\tCode: 0,\n\t\t\t\tBody: &icmp.TimeExceeded{\n\t\t\t\t\tData: []byte(\"original packet\"),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tIP: &packet.IP{\n\t\t\t\tSrc:      netip.MustParseAddr(\"172.16.0.2\"),\n\t\t\t\tDst:      netip.MustParseAddr(\"192.168.0.2\"),\n\t\t\t\tProtocol: layers.IPProtocolICMPv4,\n\t\t\t},\n\t\t\tMessage: &icmp.Message{\n\t\t\t\tType: ipv4.ICMPTypeEcho,\n\t\t\t\tCode: 0,\n\t\t\t\tBody: &icmp.Echo{\n\t\t\t\t\tID:   6182,\n\t\t\t\t\tSeq:  9151,\n\t\t\t\t\tData: []byte(\"Test ICMP echo\"),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\ttestDatagram(t, 1, sessionToPayload, nil)\n\ttestDatagram(t, 2, sessionToPayload, packets)\n}\n\nfunc testDatagram(t *testing.T, version uint8, sessionToPayloads []*packet.Session, packets []packet.ICMP) {\n\tquicConfig := &quic.Config{\n\t\tKeepAlivePeriod: 5 * time.Millisecond,\n\t\tEnableDatagrams: true,\n\t}\n\tquicListener := newQUICListener(t, quicConfig)\n\tdefer quicListener.Close()\n\n\tlogger := zerolog.Nop()\n\n\ttracingIdentity, err := tracing.NewIdentity(\"ec31ad8a01fde11fdcabe2efdce36873:52726f6cabc144f5:0:1\")\n\trequire.NoError(t, err)\n\tserializedTracingID, err := tracingIdentity.MarshalBinary()\n\trequire.NoError(t, err)\n\ttracingSpan := &TracingSpanPacket{\n\t\tSpans:           []byte(\"tracing\"),\n\t\tTracingIdentity: serializedTracingID,\n\t}\n\n\terrGroup, ctx := errgroup.WithContext(context.Background())\n\t// Run edge side of datagram muxer\n\terrGroup.Go(func() error {\n\t\t// Accept quic connection\n\t\tquicSession, err := quicListener.Accept(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tsessionDemuxChan := make(chan *packet.Session, 16)\n\n\t\tswitch version {\n\t\tcase 1:\n\t\t\tmuxer := NewDatagramMuxer(quicSession, &logger, sessionDemuxChan)\n\t\t\tmuxer.ServeReceive(ctx)\n\t\tcase 2:\n\t\t\tmuxer := NewDatagramMuxerV2(quicSession, &logger, sessionDemuxChan)\n\t\t\tmuxer.ServeReceive(ctx)\n\n\t\t\tfor _, pk := range packets {\n\t\t\t\treceived, err := muxer.ReceivePacket(ctx)\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tvalidateIPPacket(t, received, &pk)\n\t\t\t\treceived, err = muxer.ReceivePacket(ctx)\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tvalidateIPPacketWithTracing(t, received, &pk, serializedTracingID)\n\t\t\t}\n\t\t\treceived, err := muxer.ReceivePacket(ctx)\n\t\t\trequire.NoError(t, err)\n\t\t\tvalidateTracingSpans(t, received, tracingSpan)\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"unknown datagram version %d\", version)\n\t\t}\n\n\t\tfor _, expectedPayload := range sessionToPayloads {\n\t\t\tactualPayload := <-sessionDemuxChan\n\t\t\trequire.Equal(t, expectedPayload, actualPayload)\n\t\t}\n\t\treturn nil\n\t})\n\n\tlargePayload := make([]byte, MaxDatagramFrameSize)\n\t// Run cloudflared side of datagram muxer\n\terrGroup.Go(func() error {\n\t\ttlsClientConfig := &tls.Config{\n\t\t\tInsecureSkipVerify: true,\n\t\t\tNextProtos:         []string{\"argotunnel\"},\n\t\t}\n\t\tctx, cancel := context.WithCancel(context.Background())\n\t\tdefer cancel()\n\n\t\t// https://github.com/quic-go/quic-go/issues/3793 MTU discovery is disabled on OSX for dual stack listeners\n\t\tudpConn, err := net.ListenUDP(\"udp4\", &net.UDPAddr{IP: net.IPv4zero, Port: 0})\n\t\trequire.NoError(t, err)\n\t\t// Establish quic connection\n\t\tquicSession, err := quic.DialEarly(ctx, udpConn, quicListener.Addr(), tlsClientConfig, quicConfig)\n\t\trequire.NoError(t, err)\n\t\tdefer quicSession.CloseWithError(0, \"\")\n\n\t\t// Wait a few milliseconds for MTU discovery to take place\n\t\ttime.Sleep(time.Millisecond * 100)\n\n\t\tvar muxer BaseDatagramMuxer\n\t\tswitch version {\n\t\tcase 1:\n\t\t\tmuxer = NewDatagramMuxer(quicSession, &logger, nil)\n\t\tcase 2:\n\t\t\tmuxerV2 := NewDatagramMuxerV2(quicSession, &logger, nil)\n\t\t\tencoder := packet.NewEncoder()\n\t\t\tfor _, pk := range packets {\n\t\t\t\tencodedPacket, err := encoder.Encode(&pk)\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NoError(t, muxerV2.SendPacket(RawPacket(encodedPacket)))\n\t\t\t\trequire.NoError(t, muxerV2.SendPacket(&TracedPacket{\n\t\t\t\t\tPacket:          encodedPacket,\n\t\t\t\t\tTracingIdentity: serializedTracingID,\n\t\t\t\t}))\n\t\t\t}\n\t\t\trequire.NoError(t, muxerV2.SendPacket(tracingSpan))\n\t\t\t// Payload larger than transport MTU, should not be sent\n\t\t\trequire.Error(t, muxerV2.SendPacket(RawPacket{\n\t\t\t\tData: largePayload,\n\t\t\t}))\n\t\t\tmuxer = muxerV2\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"unknown datagram version %d\", version)\n\t\t}\n\n\t\tfor _, session := range sessionToPayloads {\n\t\t\trequire.NoError(t, muxer.SendToSession(session))\n\t\t}\n\t\t// Payload larger than transport MTU, should not be sent\n\t\trequire.Error(t, muxer.SendToSession(&packet.Session{\n\t\t\tID:      testSessionID,\n\t\t\tPayload: largePayload,\n\t\t}))\n\n\t\t// Wait for edge to finish receiving the messages\n\t\ttime.Sleep(time.Millisecond * 100)\n\n\t\treturn nil\n\t})\n\n\trequire.NoError(t, errGroup.Wait())\n}\n\nfunc validateIPPacket(t *testing.T, receivedPacket Packet, expectedICMP *packet.ICMP) {\n\trequire.Equal(t, DatagramTypeIP, receivedPacket.Type())\n\trawPacket := receivedPacket.(RawPacket)\n\tdecoder := packet.NewICMPDecoder()\n\treceivedICMP, err := decoder.Decode(packet.RawPacket(rawPacket))\n\trequire.NoError(t, err)\n\tvalidateICMP(t, expectedICMP, receivedICMP)\n}\n\nfunc validateIPPacketWithTracing(t *testing.T, receivedPacket Packet, expectedICMP *packet.ICMP, serializedTracingID []byte) {\n\trequire.Equal(t, DatagramTypeIPWithTrace, receivedPacket.Type())\n\ttracedPacket := receivedPacket.(*TracedPacket)\n\tdecoder := packet.NewICMPDecoder()\n\treceivedICMP, err := decoder.Decode(tracedPacket.Packet)\n\trequire.NoError(t, err)\n\tvalidateICMP(t, expectedICMP, receivedICMP)\n\trequire.True(t, bytes.Equal(tracedPacket.TracingIdentity, serializedTracingID))\n}\n\nfunc validateICMP(t *testing.T, expected, actual *packet.ICMP) {\n\trequire.Equal(t, expected.IP, actual.IP)\n\trequire.Equal(t, expected.Type, actual.Type)\n\trequire.Equal(t, expected.Code, actual.Code)\n\trequire.Equal(t, expected.Body, actual.Body)\n}\n\nfunc validateTracingSpans(t *testing.T, receivedPacket Packet, expectedSpan *TracingSpanPacket) {\n\trequire.Equal(t, DatagramTypeTracingSpan, receivedPacket.Type())\n\ttracingSpans := receivedPacket.(*TracingSpanPacket)\n\trequire.Equal(t, tracingSpans, expectedSpan)\n}\n\nfunc newQUICListener(t *testing.T, config *quic.Config) *quic.Listener {\n\t// Create a simple tls config.\n\ttlsConfig := generateTLSConfig()\n\n\tlistener, err := quic.ListenAddr(\"127.0.0.1:0\", tlsConfig, config)\n\trequire.NoError(t, err)\n\n\treturn listener\n}\n\nfunc generateTLSConfig() *tls.Config {\n\tkey, err := rsa.GenerateKey(rand.Reader, 1024)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\ttemplate := x509.Certificate{SerialNumber: big.NewInt(1)}\n\tcertDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tkeyPEM := pem.EncodeToMemory(&pem.Block{Type: \"RSA PRIVATE KEY\", Bytes: x509.MarshalPKCS1PrivateKey(key)})\n\tcertPEM := pem.EncodeToMemory(&pem.Block{Type: \"CERTIFICATE\", Bytes: certDER})\n\n\ttlsCert, err := tls.X509KeyPair(certPEM, keyPEM)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn &tls.Config{\n\t\tCertificates: []tls.Certificate{tlsCert},\n\t\tNextProtos:   []string{\"argotunnel\"},\n\t}\n}\n"
  },
  {
    "path": "quic/datagramv2.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/quic-go/quic-go\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/packet\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n)\n\ntype DatagramV2Type byte\n\nconst (\n\t// UDP payload\n\tDatagramTypeUDP DatagramV2Type = iota\n\t// Full IP packet\n\tDatagramTypeIP\n\t// DatagramTypeIP + tracing ID\n\tDatagramTypeIPWithTrace\n\t// Tracing spans in protobuf format\n\tDatagramTypeTracingSpan\n)\n\ntype Packet interface {\n\tType() DatagramV2Type\n\tPayload() []byte\n\tMetadata() []byte\n}\n\nconst (\n\ttypeIDLen = 1\n\t// Same as sessionDemuxChan capacity\n\tpacketChanCapacity = 128\n)\n\nfunc SuffixType(b []byte, datagramType DatagramV2Type) ([]byte, error) {\n\tif len(b)+typeIDLen > MaxDatagramFrameSize {\n\t\treturn nil, fmt.Errorf(\"datagram size %d exceeds max frame size %d\", len(b), MaxDatagramFrameSize)\n\t}\n\tb = append(b, byte(datagramType))\n\treturn b, nil\n}\n\n// Maximum application payload to send to / receive from QUIC datagram frame\nfunc (dm *DatagramMuxerV2) mtu() int {\n\treturn maxDatagramPayloadSize\n}\n\ntype DatagramMuxerV2 struct {\n\tsession          quic.Connection\n\tlogger           *zerolog.Logger\n\tsessionDemuxChan chan<- *packet.Session\n\tpacketDemuxChan  chan Packet\n}\n\nfunc NewDatagramMuxerV2(\n\tquicSession quic.Connection,\n\tlog *zerolog.Logger,\n\tsessionDemuxChan chan<- *packet.Session,\n) *DatagramMuxerV2 {\n\tlogger := log.With().Uint8(\"datagramVersion\", 2).Logger()\n\treturn &DatagramMuxerV2{\n\t\tsession:          quicSession,\n\t\tlogger:           &logger,\n\t\tsessionDemuxChan: sessionDemuxChan,\n\t\tpacketDemuxChan:  make(chan Packet, packetChanCapacity),\n\t}\n}\n\n// SendToSession suffix the session ID and datagram version to the payload so the other end of the QUIC connection can\n// demultiplex the payload from multiple datagram sessions\nfunc (dm *DatagramMuxerV2) SendToSession(session *packet.Session) error {\n\tif len(session.Payload) > dm.mtu() {\n\t\tpacketTooBigDropped.Inc()\n\t\treturn fmt.Errorf(\"origin UDP payload has %d bytes, which exceeds transport MTU %d\", len(session.Payload), dm.mtu())\n\t}\n\tmsgWithID, err := SuffixSessionID(session.ID, session.Payload)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Failed to suffix session ID to datagram, it will be dropped\")\n\t}\n\tmsgWithIDAndType, err := SuffixType(msgWithID, DatagramTypeUDP)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Failed to suffix datagram type, it will be dropped\")\n\t}\n\tif err := dm.session.SendDatagram(msgWithIDAndType); err != nil {\n\t\treturn errors.Wrap(err, \"Failed to send datagram back to edge\")\n\t}\n\treturn nil\n}\n\n// SendPacket sends a packet with datagram version in the suffix. If ctx is a TracedContext, it adds the tracing\n// context between payload and datagram version.\n// The other end of the QUIC connection can demultiplex by parsing the payload as IP and look at the source and destination.\nfunc (dm *DatagramMuxerV2) SendPacket(pk Packet) error {\n\tpayloadWithMetadata, err := suffixMetadata(pk.Payload(), pk.Metadata())\n\tif err != nil {\n\t\treturn err\n\t}\n\tpayloadWithMetadataAndType, err := SuffixType(payloadWithMetadata, pk.Type())\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Failed to suffix datagram type, it will be dropped\")\n\t}\n\tif err := dm.session.SendDatagram(payloadWithMetadataAndType); err != nil {\n\t\treturn errors.Wrap(err, \"Failed to send datagram back to edge\")\n\t}\n\treturn nil\n}\n\n// Demux reads datagrams from the QUIC connection and demuxes depending on whether it's a session or packet\nfunc (dm *DatagramMuxerV2) ServeReceive(ctx context.Context) error {\n\tfor {\n\t\tmsg, err := dm.session.ReceiveDatagram(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := dm.demux(ctx, msg); err != nil {\n\t\t\tdm.logger.Error().Err(err).Msg(\"Failed to demux datagram\")\n\t\t\tif err == context.Canceled {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (dm *DatagramMuxerV2) ReceivePacket(ctx context.Context) (pk Packet, err error) {\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn nil, ctx.Err()\n\tcase pk := <-dm.packetDemuxChan:\n\t\treturn pk, nil\n\t}\n}\n\nfunc (dm *DatagramMuxerV2) demux(ctx context.Context, msgWithType []byte) error {\n\tif len(msgWithType) < typeIDLen {\n\t\treturn fmt.Errorf(\"QUIC datagram should have at least %d byte\", typeIDLen)\n\t}\n\tmsgType := DatagramV2Type(msgWithType[len(msgWithType)-typeIDLen])\n\tmsg := msgWithType[0 : len(msgWithType)-typeIDLen]\n\tswitch msgType {\n\tcase DatagramTypeUDP:\n\t\treturn dm.handleSession(ctx, msg)\n\tdefault:\n\t\treturn dm.handlePacket(ctx, msg, msgType)\n\t}\n}\n\nfunc (dm *DatagramMuxerV2) handleSession(ctx context.Context, session []byte) error {\n\tsessionID, payload, err := extractSessionID(session)\n\tif err != nil {\n\t\treturn err\n\t}\n\tsessionDatagram := packet.Session{\n\t\tID:      sessionID,\n\t\tPayload: payload,\n\t}\n\tselect {\n\tcase dm.sessionDemuxChan <- &sessionDatagram:\n\t\treturn nil\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\t}\n}\n\nfunc (dm *DatagramMuxerV2) handlePacket(ctx context.Context, pk []byte, msgType DatagramV2Type) error {\n\tvar demuxedPacket Packet\n\tswitch msgType {\n\tcase DatagramTypeIP:\n\t\tdemuxedPacket = RawPacket(packet.RawPacket{Data: pk})\n\tcase DatagramTypeIPWithTrace:\n\t\ttracingIdentity, payload, err := extractTracingIdentity(pk)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdemuxedPacket = &TracedPacket{\n\t\t\tPacket:          packet.RawPacket{Data: payload},\n\t\t\tTracingIdentity: tracingIdentity,\n\t\t}\n\tcase DatagramTypeTracingSpan:\n\t\ttracingIdentity, spans, err := extractTracingIdentity(pk)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdemuxedPacket = &TracingSpanPacket{\n\t\t\tSpans:           spans,\n\t\t\tTracingIdentity: tracingIdentity,\n\t\t}\n\tdefault:\n\t\treturn fmt.Errorf(\"Unexpected datagram type %d\", msgType)\n\t}\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\tcase dm.packetDemuxChan <- demuxedPacket:\n\t\treturn nil\n\t}\n}\n\nfunc extractTracingIdentity(pk []byte) (tracingIdentity []byte, payload []byte, err error) {\n\tif len(pk) < tracing.IdentityLength {\n\t\treturn nil, nil, fmt.Errorf(\"packet with tracing context should have at least %d bytes, got %v\", tracing.IdentityLength, pk)\n\t}\n\ttracingIdentity = pk[len(pk)-tracing.IdentityLength:]\n\tpayload = pk[:len(pk)-tracing.IdentityLength]\n\treturn tracingIdentity, payload, nil\n}\n\ntype RawPacket packet.RawPacket\n\nfunc (rw RawPacket) Type() DatagramV2Type {\n\treturn DatagramTypeIP\n}\n\nfunc (rw RawPacket) Payload() []byte {\n\treturn rw.Data\n}\n\nfunc (rw RawPacket) Metadata() []byte {\n\treturn []byte{}\n}\n\ntype TracedPacket struct {\n\tPacket          packet.RawPacket\n\tTracingIdentity []byte\n}\n\nfunc (tp *TracedPacket) Type() DatagramV2Type {\n\treturn DatagramTypeIPWithTrace\n}\n\nfunc (tp *TracedPacket) Payload() []byte {\n\treturn tp.Packet.Data\n}\n\nfunc (tp *TracedPacket) Metadata() []byte {\n\treturn tp.TracingIdentity\n}\n\ntype TracingSpanPacket struct {\n\tSpans           []byte\n\tTracingIdentity []byte\n}\n\nfunc (tsp *TracingSpanPacket) Type() DatagramV2Type {\n\treturn DatagramTypeTracingSpan\n}\n\nfunc (tsp *TracingSpanPacket) Payload() []byte {\n\treturn tsp.Spans\n}\n\nfunc (tsp *TracingSpanPacket) Metadata() []byte {\n\treturn tsp.TracingIdentity\n}\n"
  },
  {
    "path": "quic/metrics.go",
    "content": "package quic\n\nimport (\n\t\"reflect\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"github.com/quic-go/quic-go/logging\"\n\t\"github.com/rs/zerolog\"\n)\n\nconst (\n\tnamespace                  = \"quic\"\n\tConnectionIndexMetricLabel = \"conn_index\"\n\tframeTypeMetricLabel       = \"frame_type\"\n\tpacketTypeMetricLabel      = \"packet_type\"\n\treasonMetricLabel          = \"reason\"\n)\n\nvar (\n\tclientMetrics = struct {\n\t\ttotalConnections  prometheus.Counter\n\t\tclosedConnections prometheus.Counter\n\t\tmaxUDPPayloadSize *prometheus.GaugeVec\n\t\tsentFrames        *prometheus.CounterVec\n\t\tsentBytes         *prometheus.CounterVec\n\t\treceivedFrames    *prometheus.CounterVec\n\t\treceivedBytes     *prometheus.CounterVec\n\t\tbufferedPackets   *prometheus.CounterVec\n\t\tdroppedPackets    *prometheus.CounterVec\n\t\tlostPackets       *prometheus.CounterVec\n\t\tminRTT            *prometheus.GaugeVec\n\t\tlatestRTT         *prometheus.GaugeVec\n\t\tsmoothedRTT       *prometheus.GaugeVec\n\t\tmtu               *prometheus.GaugeVec\n\t\tcongestionWindow  *prometheus.GaugeVec\n\t\tcongestionState   *prometheus.GaugeVec\n\t}{\n\t\ttotalConnections: prometheus.NewCounter(\n\t\t\tprometheus.CounterOpts{ //nolint:promlinter\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: \"client\",\n\t\t\t\tName:      \"total_connections\",\n\t\t\t\tHelp:      \"Number of connections initiated\",\n\t\t\t},\n\t\t),\n\t\tclosedConnections: prometheus.NewCounter(\n\t\t\tprometheus.CounterOpts{ //nolint:promlinter\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: \"client\",\n\t\t\t\tName:      \"closed_connections\",\n\t\t\t\tHelp:      \"Number of connections that has been closed\",\n\t\t\t},\n\t\t),\n\t\tmaxUDPPayloadSize: prometheus.NewGaugeVec(\n\t\t\tprometheus.GaugeOpts{\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: \"client\",\n\t\t\t\tName:      \"max_udp_payload\",\n\t\t\t\tHelp:      \"Maximum UDP payload size in bytes for a QUIC packet\",\n\t\t\t},\n\t\t\t[]string{ConnectionIndexMetricLabel},\n\t\t),\n\t\tsentFrames: prometheus.NewCounterVec(\n\t\t\tprometheus.CounterOpts{ //nolint:promlinter\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: \"client\",\n\t\t\t\tName:      \"sent_frames\",\n\t\t\t\tHelp:      \"Number of frames that have been sent through a connection\",\n\t\t\t},\n\t\t\t[]string{ConnectionIndexMetricLabel, frameTypeMetricLabel},\n\t\t),\n\t\tsentBytes: prometheus.NewCounterVec(\n\t\t\tprometheus.CounterOpts{ //nolint:promlinter\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: \"client\",\n\t\t\t\tName:      \"sent_bytes\",\n\t\t\t\tHelp:      \"Number of bytes that have been sent through a connection\",\n\t\t\t},\n\t\t\t[]string{ConnectionIndexMetricLabel},\n\t\t),\n\t\treceivedFrames: prometheus.NewCounterVec(\n\t\t\tprometheus.CounterOpts{ //nolint:promlinter\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: \"client\",\n\t\t\t\tName:      \"received_frames\",\n\t\t\t\tHelp:      \"Number of frames that have been received through a connection\",\n\t\t\t},\n\t\t\t[]string{ConnectionIndexMetricLabel, frameTypeMetricLabel},\n\t\t),\n\t\treceivedBytes: prometheus.NewCounterVec(\n\t\t\tprometheus.CounterOpts{ //nolint:promlinter\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: \"client\",\n\t\t\t\tName:      \"receive_bytes\",\n\t\t\t\tHelp:      \"Number of bytes that have been received through a connection\",\n\t\t\t},\n\t\t\t[]string{ConnectionIndexMetricLabel},\n\t\t),\n\t\tbufferedPackets: prometheus.NewCounterVec(\n\t\t\tprometheus.CounterOpts{ //nolint:promlinter\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: \"client\",\n\t\t\t\tName:      \"buffered_packets\",\n\t\t\t\tHelp:      \"Number of bytes that have been buffered on a connection\",\n\t\t\t},\n\t\t\t[]string{ConnectionIndexMetricLabel, packetTypeMetricLabel},\n\t\t),\n\t\tdroppedPackets: prometheus.NewCounterVec(\n\t\t\tprometheus.CounterOpts{ //nolint:promlinter\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: \"client\",\n\t\t\t\tName:      \"dropped_packets\",\n\t\t\t\tHelp:      \"Number of bytes that have been dropped on a connection\",\n\t\t\t},\n\t\t\t[]string{ConnectionIndexMetricLabel, packetTypeMetricLabel, reasonMetricLabel},\n\t\t),\n\t\tlostPackets: prometheus.NewCounterVec(\n\t\t\tprometheus.CounterOpts{ //nolint:promlinter\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: \"client\",\n\t\t\t\tName:      \"lost_packets\",\n\t\t\t\tHelp:      \"Number of packets that have been lost from a connection\",\n\t\t\t},\n\t\t\t[]string{ConnectionIndexMetricLabel, reasonMetricLabel},\n\t\t),\n\t\tminRTT: prometheus.NewGaugeVec(\n\t\t\tprometheus.GaugeOpts{\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: \"client\",\n\t\t\t\tName:      \"min_rtt\",\n\t\t\t\tHelp:      \"Lowest RTT measured on a connection in millisec\",\n\t\t\t},\n\t\t\t[]string{ConnectionIndexMetricLabel},\n\t\t),\n\t\tlatestRTT: prometheus.NewGaugeVec(\n\t\t\tprometheus.GaugeOpts{\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: \"client\",\n\t\t\t\tName:      \"latest_rtt\",\n\t\t\t\tHelp:      \"Latest RTT measured on a connection\",\n\t\t\t},\n\t\t\t[]string{ConnectionIndexMetricLabel},\n\t\t),\n\t\tsmoothedRTT: prometheus.NewGaugeVec(\n\t\t\tprometheus.GaugeOpts{\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: \"client\",\n\t\t\t\tName:      \"smoothed_rtt\",\n\t\t\t\tHelp:      \"Calculated smoothed RTT measured on a connection in millisec\",\n\t\t\t},\n\t\t\t[]string{ConnectionIndexMetricLabel},\n\t\t),\n\t\tmtu: prometheus.NewGaugeVec(\n\t\t\tprometheus.GaugeOpts{\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: \"client\",\n\t\t\t\tName:      \"mtu\",\n\t\t\t\tHelp:      \"Current maximum transmission unit (MTU) of a connection\",\n\t\t\t},\n\t\t\t[]string{ConnectionIndexMetricLabel},\n\t\t),\n\t\tcongestionWindow: prometheus.NewGaugeVec(\n\t\t\tprometheus.GaugeOpts{\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: \"client\",\n\t\t\t\tName:      \"congestion_window\",\n\t\t\t\tHelp:      \"Current congestion window size\",\n\t\t\t},\n\t\t\t[]string{ConnectionIndexMetricLabel},\n\t\t),\n\t\tcongestionState: prometheus.NewGaugeVec(\n\t\t\tprometheus.GaugeOpts{\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: \"client\",\n\t\t\t\tName:      \"congestion_state\",\n\t\t\t\tHelp:      \"Current congestion control state. See https://pkg.go.dev/github.com/quic-go/quic-go@v0.45.0/logging#CongestionState for what each value maps to\",\n\t\t\t},\n\t\t\t[]string{ConnectionIndexMetricLabel},\n\t\t),\n\t}\n\n\tregisterClient = sync.Once{}\n\n\tpacketTooBigDropped = prometheus.NewCounter(prometheus.CounterOpts{ //nolint:promlinter\n\t\tNamespace: namespace,\n\t\tSubsystem: \"client\",\n\t\tName:      \"packet_too_big_dropped\",\n\t\tHelp:      \"Count of packets received from origin that are too big to send to the edge and are dropped as a result\",\n\t})\n)\n\ntype clientCollector struct {\n\tindex  string\n\tlogger *zerolog.Logger\n}\n\nfunc newClientCollector(index string, logger *zerolog.Logger) *clientCollector {\n\tregisterClient.Do(func() {\n\t\tprometheus.MustRegister(\n\t\t\tclientMetrics.totalConnections,\n\t\t\tclientMetrics.closedConnections,\n\t\t\tclientMetrics.maxUDPPayloadSize,\n\t\t\tclientMetrics.sentFrames,\n\t\t\tclientMetrics.sentBytes,\n\t\t\tclientMetrics.receivedFrames,\n\t\t\tclientMetrics.receivedBytes,\n\t\t\tclientMetrics.bufferedPackets,\n\t\t\tclientMetrics.droppedPackets,\n\t\t\tclientMetrics.lostPackets,\n\t\t\tclientMetrics.minRTT,\n\t\t\tclientMetrics.latestRTT,\n\t\t\tclientMetrics.smoothedRTT,\n\t\t\tclientMetrics.mtu,\n\t\t\tclientMetrics.congestionWindow,\n\t\t\tclientMetrics.congestionState,\n\t\t\tpacketTooBigDropped,\n\t\t)\n\t})\n\n\treturn &clientCollector{\n\t\tindex:  index,\n\t\tlogger: logger,\n\t}\n}\n\nfunc (cc *clientCollector) startedConnection() {\n\tclientMetrics.totalConnections.Inc()\n}\n\nfunc (cc *clientCollector) closedConnection(error) {\n\tclientMetrics.closedConnections.Inc()\n}\n\nfunc (cc *clientCollector) receivedTransportParameters(params *logging.TransportParameters) {\n\tclientMetrics.maxUDPPayloadSize.WithLabelValues(cc.index).Set(float64(params.MaxUDPPayloadSize))\n\tcc.logger.Debug().Msgf(\"Received transport parameters: MaxUDPPayloadSize=%d, MaxIdleTimeout=%v, MaxDatagramFrameSize=%d\", params.MaxUDPPayloadSize, params.MaxIdleTimeout, params.MaxDatagramFrameSize)\n}\n\nfunc (cc *clientCollector) sentPackets(size logging.ByteCount, frames []logging.Frame) {\n\tcc.collectPackets(size, frames, clientMetrics.sentFrames, clientMetrics.sentBytes, sent)\n}\n\nfunc (cc *clientCollector) receivedPackets(size logging.ByteCount, frames []logging.Frame) {\n\tcc.collectPackets(size, frames, clientMetrics.receivedFrames, clientMetrics.receivedBytes, received)\n}\n\nfunc (cc *clientCollector) bufferedPackets(packetType logging.PacketType) {\n\tclientMetrics.bufferedPackets.WithLabelValues(cc.index, packetTypeString(packetType)).Inc()\n}\n\nfunc (cc *clientCollector) droppedPackets(packetType logging.PacketType, size logging.ByteCount, reason logging.PacketDropReason) {\n\tclientMetrics.droppedPackets.WithLabelValues(\n\t\tcc.index,\n\t\tpacketTypeString(packetType),\n\t\tpacketDropReasonString(reason),\n\t).Add(byteCountToPromCount(size))\n}\n\nfunc (cc *clientCollector) lostPackets(reason logging.PacketLossReason) {\n\tclientMetrics.lostPackets.WithLabelValues(cc.index, packetLossReasonString(reason)).Inc()\n}\n\nfunc (cc *clientCollector) updatedRTT(rtt *logging.RTTStats) {\n\tclientMetrics.minRTT.WithLabelValues(cc.index).Set(durationToPromGauge(rtt.MinRTT()))\n\tclientMetrics.latestRTT.WithLabelValues(cc.index).Set(durationToPromGauge(rtt.LatestRTT()))\n\tclientMetrics.smoothedRTT.WithLabelValues(cc.index).Set(durationToPromGauge(rtt.SmoothedRTT()))\n}\n\nfunc (cc *clientCollector) updateCongestionWindow(size logging.ByteCount) {\n\tclientMetrics.congestionWindow.WithLabelValues(cc.index).Set(float64(size))\n}\n\nfunc (cc *clientCollector) updatedCongestionState(state logging.CongestionState) {\n\tclientMetrics.congestionState.WithLabelValues(cc.index).Set(float64(state))\n}\n\nfunc (cc *clientCollector) updateMTU(mtu logging.ByteCount) {\n\tclientMetrics.mtu.WithLabelValues(cc.index).Set(float64(mtu))\n\tcc.logger.Debug().Msgf(\"QUIC MTU updated to %d\", mtu)\n}\n\nfunc (cc *clientCollector) collectPackets(size logging.ByteCount, frames []logging.Frame, counter, bandwidth *prometheus.CounterVec, direction direction) {\n\tfor _, frame := range frames {\n\t\tswitch f := frame.(type) {\n\t\tcase logging.DataBlockedFrame:\n\t\t\tcc.logger.Debug().Msgf(\"%s data_blocked frame\", direction)\n\t\tcase logging.StreamDataBlockedFrame:\n\t\t\tcc.logger.Debug().Int64(\"streamID\", int64(f.StreamID)).Msgf(\"%s stream_data_blocked frame\", direction)\n\t\t}\n\t\tcounter.WithLabelValues(cc.index, frameName(frame)).Inc()\n\t}\n\tbandwidth.WithLabelValues(cc.index).Add(byteCountToPromCount(size))\n}\n\nfunc frameName(frame logging.Frame) string {\n\tif frame == nil {\n\t\treturn \"nil\"\n\t} else {\n\t\tname := reflect.TypeOf(frame).Elem().Name()\n\t\treturn strings.TrimSuffix(name, \"Frame\")\n\t}\n}\n\ntype direction uint8\n\nconst (\n\tsent direction = iota\n\treceived\n)\n\nfunc (d direction) String() string {\n\tif d == sent {\n\t\treturn \"sent\"\n\t}\n\treturn \"received\"\n}\n"
  },
  {
    "path": "quic/param_unix.go",
    "content": "//go:build !windows\n\npackage quic\n\nconst (\n\tMaxDatagramFrameSize = 1350\n\t// maxDatagramPayloadSize is the maximum packet size allowed by warp client\n\tmaxDatagramPayloadSize = 1280\n)\n"
  },
  {
    "path": "quic/param_windows.go",
    "content": "//go:build windows\n\npackage quic\n\nconst (\n\t// Due to https://github.com/quic-go/quic-go/issues/3273, MTU discovery is disabled on Windows\n\t// 1220 is the default value https://github.com/quic-go/quic-go/blob/84e03e59760ceee37359688871bb0688fcc4e98f/internal/protocol/params.go#L138\n\tMaxDatagramFrameSize = 1220\n\t//  3 more bytes are reserved at https://github.com/quic-go/quic-go/blob/v0.24.0/internal/wire/datagram_frame.go#L61\n\tmaxDatagramPayloadSize = MaxDatagramFrameSize - 3 - sessionIDLen - typeIDLen\n)\n"
  },
  {
    "path": "quic/safe_stream.go",
    "content": "package quic\n\nimport (\n\t\"errors\"\n\t\"net\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/rs/zerolog/log\"\n)\n\n// The error that is throw by the writer when there is `no network activity`.\nvar idleTimeoutError = quic.IdleTimeoutError{}\n\ntype SafeStreamCloser struct {\n\tlock         sync.Mutex\n\tstream       quic.Stream\n\twriteTimeout time.Duration\n\tlog          *zerolog.Logger\n\tclosing      atomic.Bool\n}\n\nfunc NewSafeStreamCloser(stream quic.Stream, writeTimeout time.Duration, log *zerolog.Logger) *SafeStreamCloser {\n\treturn &SafeStreamCloser{\n\t\tstream:       stream,\n\t\twriteTimeout: writeTimeout,\n\t\tlog:          log,\n\t}\n}\n\nfunc (s *SafeStreamCloser) Read(p []byte) (n int, err error) {\n\treturn s.stream.Read(p)\n}\n\nfunc (s *SafeStreamCloser) Write(p []byte) (n int, err error) {\n\ts.lock.Lock()\n\tdefer s.lock.Unlock()\n\tif s.writeTimeout > 0 {\n\t\terr = s.stream.SetWriteDeadline(time.Now().Add(s.writeTimeout))\n\t\tif err != nil {\n\t\t\tlog.Err(err).Msg(\"Error setting write deadline for QUIC stream\")\n\t\t}\n\t}\n\tnBytes, err := s.stream.Write(p)\n\tif err != nil {\n\t\ts.handleWriteError(err)\n\t}\n\n\treturn nBytes, err\n}\n\n// Handles the timeout error in case it happened, by canceling the stream write.\nfunc (s *SafeStreamCloser) handleWriteError(err error) {\n\t// If we are closing the stream we just ignore any write error.\n\tif s.closing.Load() {\n\t\treturn\n\t}\n\tvar netErr net.Error\n\tif errors.As(err, &netErr) {\n\t\tif netErr.Timeout() {\n\t\t\t// We don't need to log if what cause the timeout was no network activity.\n\t\t\tif !errors.Is(netErr, &idleTimeoutError) {\n\t\t\t\ts.log.Error().Err(netErr).Msg(\"Closing quic stream due to timeout while writing\")\n\t\t\t}\n\t\t\t// We need to explicitly cancel the write so that it frees all buffers.\n\t\t\ts.stream.CancelWrite(0)\n\t\t}\n\t}\n}\n\nfunc (s *SafeStreamCloser) Close() error {\n\t// Set this stream to a closing state.\n\ts.closing.Store(true)\n\n\t// Make sure a possible writer does not block the lock forever. We need it, so we can close the writer\n\t// side of the stream safely.\n\t_ = s.stream.SetWriteDeadline(time.Now())\n\n\t// This lock is eventually acquired despite Write also acquiring it, because we set a deadline to writes.\n\ts.lock.Lock()\n\tdefer s.lock.Unlock()\n\n\t// We have to clean up the receiving stream ourselves since the Close in the bottom does not handle that.\n\ts.stream.CancelRead(0)\n\treturn s.stream.Close()\n}\n\nfunc (s *SafeStreamCloser) CloseWrite() error {\n\ts.lock.Lock()\n\tdefer s.lock.Unlock()\n\n\t// As documented by the quic-go library, this doesn't actually close the entire stream.\n\t// It prevents further writes, which in turn will result in an EOF signal being sent the other side of stream when\n\t// reading.\n\t// We can still read from this stream.\n\treturn s.stream.Close()\n}\n\nfunc (s *SafeStreamCloser) SetDeadline(deadline time.Time) error {\n\treturn s.stream.SetDeadline(deadline)\n}\n"
  },
  {
    "path": "quic/safe_stream_test.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"encoding/pem\"\n\t\"io\"\n\t\"math/big\"\n\t\"net\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/quic-go/quic-go\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nvar (\n\ttestTLSServerConfig = GenerateTLSConfig()\n\ttestQUICConfig      = &quic.Config{\n\t\tKeepAlivePeriod: 5 * time.Second,\n\t\tEnableDatagrams: true,\n\t}\n\texchanges       = 1000\n\tmsgsPerExchange = 10\n\ttestMsg         = \"Ok message\"\n)\n\nfunc TestSafeStreamClose(t *testing.T) {\n\tudpAddr, err := net.ResolveUDPAddr(\"udp\", \"127.0.0.1:0\")\n\trequire.NoError(t, err)\n\tudpListener, err := net.ListenUDP(udpAddr.Network(), udpAddr)\n\trequire.NoError(t, err)\n\tdefer udpListener.Close()\n\n\tvar serverReady sync.WaitGroup\n\tserverReady.Add(1)\n\n\tvar done sync.WaitGroup\n\tdone.Add(1)\n\tgo func() {\n\t\tdefer done.Done()\n\t\tquicServer(t, &serverReady, udpListener)\n\t}()\n\n\tdone.Add(1)\n\tgo func() {\n\t\tserverReady.Wait()\n\t\tdefer done.Done()\n\t\tquicClient(t, udpListener.LocalAddr())\n\t}()\n\n\tdone.Wait()\n}\n\nfunc quicClient(t *testing.T, addr net.Addr) {\n\ttlsConf := &tls.Config{\n\t\tInsecureSkipVerify: true,\n\t\tNextProtos:         []string{\"argotunnel\"},\n\t}\n\tctx, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\tsession, err := quic.DialAddr(ctx, addr.String(), tlsConf, testQUICConfig)\n\trequire.NoError(t, err)\n\n\tvar wg sync.WaitGroup\n\tfor exchange := 0; exchange < exchanges; exchange++ {\n\t\tquicStream, err := session.AcceptStream(context.Background())\n\t\trequire.NoError(t, err)\n\t\twg.Add(1)\n\n\t\tgo func(iter int) {\n\t\t\tdefer wg.Done()\n\n\t\t\tlog := zerolog.Nop()\n\t\t\tstream := NewSafeStreamCloser(quicStream, 30*time.Second, &log)\n\t\t\tdefer stream.Close()\n\n\t\t\t// Do a bunch of round trips over this stream that should work.\n\t\t\tfor msg := 0; msg < msgsPerExchange; msg++ {\n\t\t\t\tclientRoundTrip(t, stream, true)\n\t\t\t}\n\t\t\t// And one that won't work necessarily, but shouldn't break other streams in the session.\n\t\t\tif iter%2 == 0 {\n\t\t\t\tclientRoundTrip(t, stream, false)\n\t\t\t}\n\t\t}(exchange)\n\t}\n\n\twg.Wait()\n}\n\nfunc quicServer(t *testing.T, serverReady *sync.WaitGroup, conn net.PacketConn) {\n\tctx, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\n\tearlyListener, err := quic.Listen(conn, testTLSServerConfig, testQUICConfig)\n\trequire.NoError(t, err)\n\n\tserverReady.Done()\n\tsession, err := earlyListener.Accept(ctx)\n\trequire.NoError(t, err)\n\n\tvar wg sync.WaitGroup\n\tfor exchange := 0; exchange < exchanges; exchange++ {\n\t\tquicStream, err := session.OpenStreamSync(context.Background())\n\t\trequire.NoError(t, err)\n\t\twg.Add(1)\n\n\t\tgo func(iter int) {\n\t\t\tdefer wg.Done()\n\n\t\t\tlog := zerolog.Nop()\n\t\t\tstream := NewSafeStreamCloser(quicStream, 30*time.Second, &log)\n\t\t\tdefer stream.Close()\n\n\t\t\t// Do a bunch of round trips over this stream that should work.\n\t\t\tfor msg := 0; msg < msgsPerExchange; msg++ {\n\t\t\t\tserverRoundTrip(t, stream, true)\n\t\t\t}\n\t\t\t// And one that won't work necessarily, but shouldn't break other streams in the session.\n\t\t\tif iter%2 == 1 {\n\t\t\t\tserverRoundTrip(t, stream, false)\n\t\t\t}\n\t\t}(exchange)\n\t}\n\n\twg.Wait()\n}\n\nfunc clientRoundTrip(t *testing.T, stream io.ReadWriteCloser, mustWork bool) {\n\tresponse := make([]byte, len(testMsg))\n\t_, err := stream.Read(response)\n\tif !mustWork {\n\t\treturn\n\t}\n\tif err != io.EOF {\n\t\trequire.NoError(t, err)\n\t}\n\trequire.Equal(t, testMsg, string(response))\n}\n\nfunc serverRoundTrip(t *testing.T, stream io.ReadWriteCloser, mustWork bool) {\n\t_, err := stream.Write([]byte(testMsg))\n\tif !mustWork {\n\t\treturn\n\t}\n\trequire.NoError(t, err)\n}\n\n// GenerateTLSConfig sets up a bare-bones TLS config for a QUIC server\nfunc GenerateTLSConfig() *tls.Config {\n\tkey, err := rsa.GenerateKey(rand.Reader, 1024)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\ttemplate := x509.Certificate{SerialNumber: big.NewInt(1)}\n\tcertDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tkeyPEM := pem.EncodeToMemory(&pem.Block{Type: \"RSA PRIVATE KEY\", Bytes: x509.MarshalPKCS1PrivateKey(key)})\n\tcertPEM := pem.EncodeToMemory(&pem.Block{Type: \"CERTIFICATE\", Bytes: certDER})\n\n\ttlsCert, err := tls.X509KeyPair(certPEM, keyPEM)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn &tls.Config{\n\t\tCertificates: []tls.Certificate{tlsCert},\n\t\tNextProtos:   []string{\"argotunnel\"},\n\t}\n}\n"
  },
  {
    "path": "quic/tracing.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"github.com/quic-go/quic-go/logging\"\n\t\"github.com/rs/zerolog\"\n)\n\n// QUICTracer is a wrapper to create new quicConnTracer\ntype tracer struct {\n\tindex  string\n\tlogger *zerolog.Logger\n}\n\nfunc NewClientTracer(logger *zerolog.Logger, index uint8) func(context.Context, logging.Perspective, logging.ConnectionID) *logging.ConnectionTracer {\n\tt := &tracer{\n\t\tindex:  uint8ToString(index),\n\t\tlogger: logger,\n\t}\n\treturn t.TracerForConnection\n}\n\nfunc (t *tracer) TracerForConnection(_ctx context.Context, _p logging.Perspective, _odcid logging.ConnectionID) *logging.ConnectionTracer {\n\treturn newConnTracer(newClientCollector(t.index, t.logger))\n}\n\n// connTracer collects connection level metrics\ntype connTracer struct {\n\tmetricsCollector *clientCollector\n}\n\nfunc newConnTracer(metricsCollector *clientCollector) *logging.ConnectionTracer {\n\ttracer := connTracer{\n\t\tmetricsCollector: metricsCollector,\n\t}\n\treturn &logging.ConnectionTracer{\n\t\tStartedConnection:           tracer.StartedConnection,\n\t\tClosedConnection:            tracer.ClosedConnection,\n\t\tReceivedTransportParameters: tracer.ReceivedTransportParameters,\n\t\tSentLongHeaderPacket:        tracer.SentLongHeaderPacket,\n\t\tSentShortHeaderPacket:       tracer.SentShortHeaderPacket,\n\t\tReceivedLongHeaderPacket:    tracer.ReceivedLongHeaderPacket,\n\t\tReceivedShortHeaderPacket:   tracer.ReceivedShortHeaderPacket,\n\t\tBufferedPacket:              tracer.BufferedPacket,\n\t\tDroppedPacket:               tracer.DroppedPacket,\n\t\tUpdatedMetrics:              tracer.UpdatedMetrics,\n\t\tLostPacket:                  tracer.LostPacket,\n\t\tUpdatedMTU:                  tracer.UpdatedMTU,\n\t\tUpdatedCongestionState:      tracer.UpdatedCongestionState,\n\t}\n}\n\nfunc (ct *connTracer) StartedConnection(local, remote net.Addr, srcConnID, destConnID logging.ConnectionID) {\n\tct.metricsCollector.startedConnection()\n}\n\nfunc (ct *connTracer) ClosedConnection(err error) {\n\tct.metricsCollector.closedConnection(err)\n}\n\nfunc (ct *connTracer) ReceivedTransportParameters(params *logging.TransportParameters) {\n\tct.metricsCollector.receivedTransportParameters(params)\n}\n\nfunc (ct *connTracer) BufferedPacket(pt logging.PacketType, size logging.ByteCount) {\n\tct.metricsCollector.bufferedPackets(pt)\n}\n\nfunc (ct *connTracer) DroppedPacket(pt logging.PacketType, number logging.PacketNumber, size logging.ByteCount, reason logging.PacketDropReason) {\n\tct.metricsCollector.droppedPackets(pt, size, reason)\n}\n\nfunc (ct *connTracer) LostPacket(level logging.EncryptionLevel, number logging.PacketNumber, reason logging.PacketLossReason) {\n\tct.metricsCollector.lostPackets(reason)\n}\n\nfunc (ct *connTracer) UpdatedMetrics(rttStats *logging.RTTStats, cwnd, bytesInFlight logging.ByteCount, packetsInFlight int) {\n\tct.metricsCollector.updatedRTT(rttStats)\n\tct.metricsCollector.updateCongestionWindow(cwnd)\n}\n\nfunc (ct *connTracer) SentLongHeaderPacket(hdr *logging.ExtendedHeader, size logging.ByteCount, ecn logging.ECN, ack *logging.AckFrame, frames []logging.Frame) {\n\tct.metricsCollector.sentPackets(size, frames)\n}\n\nfunc (ct *connTracer) SentShortHeaderPacket(hdr *logging.ShortHeader, size logging.ByteCount, ecn logging.ECN, ack *logging.AckFrame, frames []logging.Frame) {\n\tct.metricsCollector.sentPackets(size, frames)\n}\n\nfunc (ct *connTracer) ReceivedLongHeaderPacket(hdr *logging.ExtendedHeader, size logging.ByteCount, ecn logging.ECN, frames []logging.Frame) {\n\tct.metricsCollector.receivedPackets(size, frames)\n}\n\nfunc (ct *connTracer) ReceivedShortHeaderPacket(hdr *logging.ShortHeader, size logging.ByteCount, ecn logging.ECN, frames []logging.Frame) {\n\tct.metricsCollector.receivedPackets(size, frames)\n}\n\nfunc (ct *connTracer) UpdatedMTU(mtu logging.ByteCount, done bool) {\n\tct.metricsCollector.updateMTU(mtu)\n}\n\nfunc (ct *connTracer) UpdatedCongestionState(state logging.CongestionState) {\n\tct.metricsCollector.updatedCongestionState(state)\n}\n"
  },
  {
    "path": "quic/v3/datagram.go",
    "content": "package v3\n\nimport (\n\t\"encoding/binary\"\n\t\"net/netip\"\n\t\"time\"\n)\n\ntype DatagramType byte\n\nconst (\n\t// UDP Registration\n\tUDPSessionRegistrationType DatagramType = 0x0\n\t// UDP Session Payload\n\tUDPSessionPayloadType DatagramType = 0x1\n\t// DatagramTypeICMP (supporting both ICMPv4 and ICMPv6)\n\tICMPType DatagramType = 0x2\n\t// UDP Session Registration Response\n\tUDPSessionRegistrationResponseType DatagramType = 0x3\n)\n\nconst (\n\t// Total number of bytes representing the [DatagramType]\n\tdatagramTypeLen = 1\n\n\t// 1280 is the default datagram packet length used before MTU discovery: https://github.com/quic-go/quic-go/blob/v0.45.0/internal/protocol/params.go#L12\n\tmaxDatagramPayloadLen = 1280\n)\n\nfunc ParseDatagramType(data []byte) (DatagramType, error) {\n\tif len(data) < datagramTypeLen {\n\t\treturn 0, ErrDatagramHeaderTooSmall\n\t}\n\treturn DatagramType(data[0]), nil\n}\n\n// UDPSessionRegistrationDatagram handles a request to initialize a UDP session on the remote client.\ntype UDPSessionRegistrationDatagram struct {\n\tRequestID        RequestID\n\tDest             netip.AddrPort\n\tTraced           bool\n\tIdleDurationHint time.Duration\n\tPayload          []byte\n}\n\nconst (\n\tsessionRegistrationFlagsIPMask      byte = 0b0000_0001\n\tsessionRegistrationFlagsTracedMask  byte = 0b0000_0010\n\tsessionRegistrationFlagsBundledMask byte = 0b0000_0100\n\n\tsessionRegistrationIPv4DatagramHeaderLen = datagramTypeLen +\n\t\t1 + // Flag length\n\t\t2 + // Destination port length\n\t\t2 + // Idle duration seconds length\n\t\tdatagramRequestIdLen + // Request ID length\n\t\t4 // IPv4 address length\n\n\t// The IPv4 and IPv6 address share space, so adding 12 to the header length gets the space taken by the IPv6 field.\n\tsessionRegistrationIPv6DatagramHeaderLen = sessionRegistrationIPv4DatagramHeaderLen + 12\n)\n\n// The datagram structure for UDPSessionRegistrationDatagram is:\n//\n//   0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7\n//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//  0|      Type     |     Flags     |       Destination Port        |\n//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//  4|     Idle Duration Seconds     |                               |\n//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +\n//  8|                                                               |\n//   +                       Session Identifier                      +\n// 12|                           (16 Bytes)                          |\n//   +                                                               +\n// 16|                                                               |\n//   +                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// 20|                               |   Destination IPv4 Address    |\n//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - - - - - - - - -+\n// 24| Destination IPv4 Address cont |                               |\n//   +- - - - - - - - - - - - - - - -                                +\n// 28|                   Destination IPv6 Address                    |\n//   +                  (extension of IPv4 region)                   +\n// 32|                                                               |\n//   +                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// 36|                               |                               |\n//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +\n//   .                                                               .\n//   .                         Bundle Payload                        .\n//   .                                                               .\n//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\nfunc (s *UDPSessionRegistrationDatagram) MarshalBinary() (data []byte, err error) {\n\tipv6 := s.Dest.Addr().Is6()\n\tvar flags byte\n\tif s.Traced {\n\t\tflags |= sessionRegistrationFlagsTracedMask\n\t}\n\thasPayload := len(s.Payload) > 0\n\tif hasPayload {\n\t\tflags |= sessionRegistrationFlagsBundledMask\n\t}\n\tvar maxPayloadLen int\n\tif ipv6 {\n\t\tmaxPayloadLen = maxDatagramPayloadLen + sessionRegistrationIPv6DatagramHeaderLen\n\t\tflags |= sessionRegistrationFlagsIPMask\n\t} else {\n\t\tmaxPayloadLen = maxDatagramPayloadLen + sessionRegistrationIPv4DatagramHeaderLen\n\t}\n\t// Make sure that the payload being bundled can actually fit in the payload destination\n\tif len(s.Payload) > maxPayloadLen {\n\t\treturn nil, wrapMarshalErr(ErrDatagramPayloadTooLarge)\n\t}\n\t// Allocate the buffer with the right size for the destination IP family\n\tif ipv6 {\n\t\tdata = make([]byte, sessionRegistrationIPv6DatagramHeaderLen+len(s.Payload))\n\t} else {\n\t\tdata = make([]byte, sessionRegistrationIPv4DatagramHeaderLen+len(s.Payload))\n\t}\n\tdata[0] = byte(UDPSessionRegistrationType)\n\tdata[1] = flags\n\tbinary.BigEndian.PutUint16(data[2:4], s.Dest.Port())\n\tbinary.BigEndian.PutUint16(data[4:6], uint16(s.IdleDurationHint.Seconds()))\n\terr = s.RequestID.MarshalBinaryTo(data[6:22])\n\tif err != nil {\n\t\treturn nil, wrapMarshalErr(err)\n\t}\n\tvar end int\n\tif ipv6 {\n\t\tcopy(data[22:38], s.Dest.Addr().AsSlice())\n\t\tend = 38\n\t} else {\n\t\tcopy(data[22:26], s.Dest.Addr().AsSlice())\n\t\tend = 26\n\t}\n\n\tif hasPayload {\n\t\tcopy(data[end:], s.Payload)\n\t}\n\n\treturn data, nil\n}\n\nfunc (s *UDPSessionRegistrationDatagram) UnmarshalBinary(data []byte) error {\n\tdatagramType, err := ParseDatagramType(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif datagramType != UDPSessionRegistrationType {\n\t\treturn wrapUnmarshalErr(ErrInvalidDatagramType)\n\t}\n\n\trequestID, err := RequestIDFromSlice(data[6:22])\n\tif err != nil {\n\t\treturn wrapUnmarshalErr(err)\n\t}\n\n\ttraced := (data[1] & sessionRegistrationFlagsTracedMask) == sessionRegistrationFlagsTracedMask\n\tbundled := (data[1] & sessionRegistrationFlagsBundledMask) == sessionRegistrationFlagsBundledMask\n\tipv6 := (data[1] & sessionRegistrationFlagsIPMask) == sessionRegistrationFlagsIPMask\n\n\tport := binary.BigEndian.Uint16(data[2:4])\n\tvar datagramHeaderSize int\n\tvar dest netip.AddrPort\n\tif ipv6 {\n\t\tdatagramHeaderSize = sessionRegistrationIPv6DatagramHeaderLen\n\t\tdest = netip.AddrPortFrom(netip.AddrFrom16([16]byte(data[22:38])), port)\n\t} else {\n\t\tdatagramHeaderSize = sessionRegistrationIPv4DatagramHeaderLen\n\t\tdest = netip.AddrPortFrom(netip.AddrFrom4([4]byte(data[22:26])), port)\n\t}\n\n\tidle := time.Duration(binary.BigEndian.Uint16(data[4:6])) * time.Second\n\n\tvar payload []byte\n\tif bundled && len(data) >= datagramHeaderSize && len(data[datagramHeaderSize:]) > 0 {\n\t\tpayload = data[datagramHeaderSize:]\n\t}\n\n\t*s = UDPSessionRegistrationDatagram{\n\t\tRequestID:        requestID,\n\t\tDest:             dest,\n\t\tTraced:           traced,\n\t\tIdleDurationHint: idle,\n\t\tPayload:          payload,\n\t}\n\treturn nil\n}\n\n// UDPSessionPayloadDatagram provides the payload for a session to be send to either the origin or the client.\ntype UDPSessionPayloadDatagram struct {\n\tRequestID RequestID\n\tPayload   []byte\n}\n\nconst (\n\tDatagramPayloadHeaderLen = datagramTypeLen + datagramRequestIdLen\n\n\t// The maximum size that a proxied UDP payload can be in a [UDPSessionPayloadDatagram]\n\tmaxPayloadPlusHeaderLen = maxDatagramPayloadLen + DatagramPayloadHeaderLen\n)\n\n// The datagram structure for UDPSessionPayloadDatagram is:\n//\n//   0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7\n//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//  0|      Type     |                                               |\n//   +-+-+-+-+-+-+-+-+                                               +\n//  4|                                                               |\n//   +                                                               +\n//  8|                      Session Identifier                       |\n//   +                           (16 Bytes)                          +\n// 12|                                                               |\n//   +                                               +-+-+-+-+-+-+-+-+\n// 16|                                               |               |\n//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +\n//   .                                                               .\n//   .                             Payload                           .\n//   .                                                               .\n//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n// MarshalPayloadHeaderTo provides a way to insert the Session Payload header into an already existing byte slice\n// without having to allocate and copy the payload into the destination.\n//\n// This method should be used in-place of MarshalBinary which will allocate in-place the required byte array to return.\nfunc MarshalPayloadHeaderTo(requestID RequestID, payload []byte) error {\n\tif len(payload) < DatagramPayloadHeaderLen {\n\t\treturn wrapMarshalErr(ErrDatagramPayloadHeaderTooSmall)\n\t}\n\tpayload[0] = byte(UDPSessionPayloadType)\n\treturn requestID.MarshalBinaryTo(payload[1:DatagramPayloadHeaderLen])\n}\n\nfunc (s *UDPSessionPayloadDatagram) UnmarshalBinary(data []byte) error {\n\tdatagramType, err := ParseDatagramType(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif datagramType != UDPSessionPayloadType {\n\t\treturn wrapUnmarshalErr(ErrInvalidDatagramType)\n\t}\n\n\t// Make sure that the slice provided is the right size to be parsed.\n\tif len(data) < DatagramPayloadHeaderLen || len(data) > maxPayloadPlusHeaderLen {\n\t\treturn wrapUnmarshalErr(ErrDatagramPayloadInvalidSize)\n\t}\n\n\trequestID, err := RequestIDFromSlice(data[1:DatagramPayloadHeaderLen])\n\tif err != nil {\n\t\treturn wrapUnmarshalErr(err)\n\t}\n\n\t*s = UDPSessionPayloadDatagram{\n\t\tRequestID: requestID,\n\t\tPayload:   data[DatagramPayloadHeaderLen:],\n\t}\n\treturn nil\n}\n\n// UDPSessionRegistrationResponseDatagram is used to either return a successful registration or error to the client\n// that requested the registration of a UDP session.\ntype UDPSessionRegistrationResponseDatagram struct {\n\tRequestID    RequestID\n\tResponseType SessionRegistrationResp\n\tErrorMsg     string\n}\n\nconst (\n\tdatagramRespTypeLen   = 1\n\tdatagramRespErrMsgLen = 2\n\n\tdatagramSessionRegistrationResponseLen = datagramTypeLen + datagramRespTypeLen + datagramRequestIdLen + datagramRespErrMsgLen\n\n\t// The maximum size that an error message can be in a [UDPSessionRegistrationResponseDatagram].\n\tmaxResponseErrorMessageLen = maxDatagramPayloadLen - datagramSessionRegistrationResponseLen\n)\n\n// SessionRegistrationResp represents all of the responses that a UDP session registration response\n// can return back to the client.\ntype SessionRegistrationResp byte\n\nconst (\n\t// Session was received and is ready to proxy.\n\tResponseOk SessionRegistrationResp = 0x00\n\t// Session registration was unable to reach the requested origin destination.\n\tResponseDestinationUnreachable SessionRegistrationResp = 0x01\n\t// Session registration was unable to bind to a local UDP socket.\n\tResponseUnableToBindSocket SessionRegistrationResp = 0x02\n\t// Session registration failed due to the number of flows being higher than the limit.\n\tResponseTooManyActiveFlows SessionRegistrationResp = 0x03\n\t// Session registration failed with an unexpected error but provided a message.\n\tResponseErrorWithMsg SessionRegistrationResp = 0xff\n)\n\n// The datagram structure for UDPSessionRegistrationResponseDatagram is:\n//\n//   0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7\n//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//  0|      Type     |   Resp Type   |                               |\n//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +\n//  4|                                                               |\n//   +                       Session Identifier                      +\n//  8|                           (16 Bytes)                          |\n//   +                                                               +\n// 12|                                                               |\n//   +                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// 16|                               |          Error Length         |\n//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//   .                                                               .\n//   .                                                               .\n//   .                                                               .\n//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\nfunc (s *UDPSessionRegistrationResponseDatagram) MarshalBinary() (data []byte, err error) {\n\tif len(s.ErrorMsg) > maxResponseErrorMessageLen {\n\t\treturn nil, wrapMarshalErr(ErrDatagramResponseMsgInvalidSize)\n\t}\n\t// nolint: gosec\n\terrMsgLen := uint16(len(s.ErrorMsg))\n\n\tdata = make([]byte, datagramSessionRegistrationResponseLen+errMsgLen)\n\tdata[0] = byte(UDPSessionRegistrationResponseType)\n\tdata[1] = byte(s.ResponseType)\n\terr = s.RequestID.MarshalBinaryTo(data[2:18])\n\tif err != nil {\n\t\treturn nil, wrapMarshalErr(err)\n\t}\n\n\tif errMsgLen > 0 {\n\t\tbinary.BigEndian.PutUint16(data[18:20], errMsgLen)\n\t\tcopy(data[20:], []byte(s.ErrorMsg))\n\t}\n\n\treturn data, nil\n}\n\nfunc (s *UDPSessionRegistrationResponseDatagram) UnmarshalBinary(data []byte) error {\n\tdatagramType, err := ParseDatagramType(data)\n\tif err != nil {\n\t\treturn wrapUnmarshalErr(err)\n\t}\n\tif datagramType != UDPSessionRegistrationResponseType {\n\t\treturn wrapUnmarshalErr(ErrInvalidDatagramType)\n\t}\n\n\tif len(data) < datagramSessionRegistrationResponseLen {\n\t\treturn wrapUnmarshalErr(ErrDatagramResponseInvalidSize)\n\t}\n\n\trespType := SessionRegistrationResp(data[1])\n\n\trequestID, err := RequestIDFromSlice(data[2:18])\n\tif err != nil {\n\t\treturn wrapUnmarshalErr(err)\n\t}\n\n\terrMsgLen := binary.BigEndian.Uint16(data[18:20])\n\tif errMsgLen > maxResponseErrorMessageLen {\n\t\treturn wrapUnmarshalErr(ErrDatagramResponseMsgTooLargeMaximum)\n\t}\n\n\tif len(data[20:]) < int(errMsgLen) {\n\t\treturn wrapUnmarshalErr(ErrDatagramResponseMsgTooLargeDatagram)\n\t}\n\n\tvar errMsg string\n\tif errMsgLen > 0 {\n\t\terrMsg = string(data[20:])\n\t}\n\n\t*s = UDPSessionRegistrationResponseDatagram{\n\t\tRequestID:    requestID,\n\t\tResponseType: respType,\n\t\tErrorMsg:     errMsg,\n\t}\n\treturn nil\n}\n\n// ICMPDatagram is used to propagate ICMPv4 and ICMPv6 payloads.\ntype ICMPDatagram struct {\n\tPayload []byte\n}\n\n// The maximum size that an ICMP packet can be.\nconst maxICMPPayloadLen = maxDatagramPayloadLen\n\n// The datagram structure for ICMPDatagram is:\n//\n//   0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7\n//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//  0|      Type     |                                               |\n//   +-+-+-+-+-+-+-+-+                                               +\n//   .                          Payload                              .\n//   .                                                               .\n//   .                                                               .\n//   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\nfunc (d *ICMPDatagram) MarshalBinary() (data []byte, err error) {\n\tif len(d.Payload) > maxICMPPayloadLen {\n\t\treturn nil, wrapMarshalErr(ErrDatagramICMPPayloadTooLarge)\n\t}\n\t// We shouldn't attempt to marshal an ICMP datagram with no ICMP payload provided\n\tif len(d.Payload) == 0 {\n\t\treturn nil, wrapMarshalErr(ErrDatagramICMPPayloadMissing)\n\t}\n\t// Make room for the 1 byte ICMPType header\n\tdatagram := make([]byte, len(d.Payload)+datagramTypeLen)\n\tdatagram[0] = byte(ICMPType)\n\tcopy(datagram[1:], d.Payload)\n\treturn datagram, nil\n}\n\nfunc (d *ICMPDatagram) UnmarshalBinary(data []byte) error {\n\tdatagramType, err := ParseDatagramType(data)\n\tif err != nil {\n\t\treturn wrapUnmarshalErr(err)\n\t}\n\tif datagramType != ICMPType {\n\t\treturn wrapUnmarshalErr(ErrInvalidDatagramType)\n\t}\n\n\tif len(data[1:]) > maxDatagramPayloadLen {\n\t\treturn wrapUnmarshalErr(ErrDatagramICMPPayloadTooLarge)\n\t}\n\n\t// We shouldn't attempt to unmarshal an ICMP datagram with no ICMP payload provided\n\tif len(data[1:]) == 0 {\n\t\treturn wrapUnmarshalErr(ErrDatagramICMPPayloadMissing)\n\t}\n\n\tpayload := make([]byte, len(data[1:]))\n\tcopy(payload, data[1:])\n\td.Payload = payload\n\treturn nil\n}\n"
  },
  {
    "path": "quic/v3/datagram_errors.go",
    "content": "package v3\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\nvar (\n\tErrInvalidDatagramType                 error = errors.New(\"invalid datagram type expected\")\n\tErrDatagramHeaderTooSmall              error = fmt.Errorf(\"datagram should have at least %d byte\", datagramTypeLen)\n\tErrDatagramPayloadTooLarge             error = errors.New(\"payload length is too large to be bundled in datagram\")\n\tErrDatagramPayloadHeaderTooSmall       error = errors.New(\"payload length is too small to fit the datagram header\")\n\tErrDatagramPayloadInvalidSize          error = errors.New(\"datagram provided is an invalid size\")\n\tErrDatagramResponseMsgInvalidSize      error = errors.New(\"datagram response message is an invalid size\")\n\tErrDatagramResponseInvalidSize         error = errors.New(\"datagram response is an invalid size\")\n\tErrDatagramResponseMsgTooLargeMaximum  error = fmt.Errorf(\"datagram response error message length exceeds the length of the datagram maximum: %d\", maxResponseErrorMessageLen)\n\tErrDatagramResponseMsgTooLargeDatagram error = fmt.Errorf(\"datagram response error message length exceeds the length of the provided datagram\")\n\tErrDatagramICMPPayloadTooLarge         error = fmt.Errorf(\"datagram icmp payload exceeds %d bytes\", maxICMPPayloadLen)\n\tErrDatagramICMPPayloadMissing          error = errors.New(\"datagram icmp payload is missing\")\n)\n\nfunc wrapMarshalErr(err error) error {\n\treturn fmt.Errorf(\"datagram marshal error: %w\", err)\n}\n\nfunc wrapUnmarshalErr(err error) error {\n\treturn fmt.Errorf(\"datagram unmarshal error: %w\", err)\n}\n"
  },
  {
    "path": "quic/v3/datagram_test.go",
    "content": "package v3_test\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"net/netip\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/require\"\n\n\tv3 \"github.com/cloudflare/cloudflared/quic/v3\"\n)\n\nfunc makePayload(size int) []byte {\n\tpayload := make([]byte, size)\n\t_, _ = rand.Read(payload)\n\treturn payload\n}\n\nfunc makePayloads(size int, count int) [][]byte {\n\tpayloads := make([][]byte, count)\n\tfor i := range payloads {\n\t\tpayloads[i] = makePayload(size)\n\t}\n\treturn payloads\n}\n\nfunc TestSessionRegistration_MarshalUnmarshal(t *testing.T) {\n\tpayload := makePayload(1280)\n\ttests := []*v3.UDPSessionRegistrationDatagram{\n\t\t// Default (IPv4)\n\t\t{\n\t\t\tRequestID:        testRequestID,\n\t\t\tDest:             netip.MustParseAddrPort(\"1.1.1.1:8080\"),\n\t\t\tTraced:           false,\n\t\t\tIdleDurationHint: 5 * time.Second,\n\t\t\tPayload:          nil,\n\t\t},\n\t\t// Request ID (max)\n\t\t{\n\t\t\tRequestID: mustRequestID([16]byte{\n\t\t\t\t^uint8(0), ^uint8(0), ^uint8(0), ^uint8(0),\n\t\t\t\t^uint8(0), ^uint8(0), ^uint8(0), ^uint8(0),\n\t\t\t\t^uint8(0), ^uint8(0), ^uint8(0), ^uint8(0),\n\t\t\t\t^uint8(0), ^uint8(0), ^uint8(0), ^uint8(0),\n\t\t\t}),\n\t\t\tDest:             netip.MustParseAddrPort(\"1.1.1.1:8080\"),\n\t\t\tTraced:           false,\n\t\t\tIdleDurationHint: 5 * time.Second,\n\t\t\tPayload:          nil,\n\t\t},\n\t\t// IPv6\n\t\t{\n\t\t\tRequestID:        testRequestID,\n\t\t\tDest:             netip.MustParseAddrPort(\"[fc00::0]:8080\"),\n\t\t\tTraced:           false,\n\t\t\tIdleDurationHint: 5 * time.Second,\n\t\t\tPayload:          nil,\n\t\t},\n\t\t// Traced\n\t\t{\n\t\t\tRequestID:        testRequestID,\n\t\t\tDest:             netip.MustParseAddrPort(\"1.1.1.1:8080\"),\n\t\t\tTraced:           true,\n\t\t\tIdleDurationHint: 5 * time.Second,\n\t\t\tPayload:          nil,\n\t\t},\n\t\t// IdleDurationHint (max)\n\t\t{\n\t\t\tRequestID:        testRequestID,\n\t\t\tDest:             netip.MustParseAddrPort(\"1.1.1.1:8080\"),\n\t\t\tTraced:           false,\n\t\t\tIdleDurationHint: 65535 * time.Second,\n\t\t\tPayload:          nil,\n\t\t},\n\t\t// Payload\n\t\t{\n\t\t\tRequestID:        testRequestID,\n\t\t\tDest:             netip.MustParseAddrPort(\"1.1.1.1:8080\"),\n\t\t\tTraced:           false,\n\t\t\tIdleDurationHint: 5 * time.Second,\n\t\t\tPayload:          []byte{0xff, 0xaa, 0xcc, 0x44},\n\t\t},\n\t\t// Payload (max: 1254) for IPv4\n\t\t{\n\t\t\tRequestID:        testRequestID,\n\t\t\tDest:             netip.MustParseAddrPort(\"1.1.1.1:8080\"),\n\t\t\tTraced:           false,\n\t\t\tIdleDurationHint: 5 * time.Second,\n\t\t\tPayload:          payload,\n\t\t},\n\t\t// Payload (max: 1242) for IPv4\n\t\t{\n\t\t\tRequestID:        testRequestID,\n\t\t\tDest:             netip.MustParseAddrPort(\"1.1.1.1:8080\"),\n\t\t\tTraced:           false,\n\t\t\tIdleDurationHint: 5 * time.Second,\n\t\t\tPayload:          payload[:1242],\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tmarshaled, err := tt.MarshalBinary()\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tunmarshaled := v3.UDPSessionRegistrationDatagram{}\n\t\terr = unmarshaled.UnmarshalBinary(marshaled)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif !compareRegistrationDatagrams(t, tt, &unmarshaled) {\n\t\t\tt.Errorf(\"not equal:\\n%+v\\n%+v\", tt, &unmarshaled)\n\t\t}\n\t}\n}\n\nfunc TestSessionRegistration_MarshalBinary(t *testing.T) {\n\tt.Run(\"idle hint too large\", func(t *testing.T) {\n\t\t// idle hint duration overflows back to 1\n\t\tdatagram := &v3.UDPSessionRegistrationDatagram{\n\t\t\tRequestID:        testRequestID,\n\t\t\tDest:             netip.MustParseAddrPort(\"1.1.1.1:8080\"),\n\t\t\tTraced:           false,\n\t\t\tIdleDurationHint: 65537 * time.Second,\n\t\t\tPayload:          nil,\n\t\t}\n\t\texpected := &v3.UDPSessionRegistrationDatagram{\n\t\t\tRequestID:        testRequestID,\n\t\t\tDest:             netip.MustParseAddrPort(\"1.1.1.1:8080\"),\n\t\t\tTraced:           false,\n\t\t\tIdleDurationHint: 1 * time.Second,\n\t\t\tPayload:          nil,\n\t\t}\n\t\tmarshaled, err := datagram.MarshalBinary()\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tunmarshaled := v3.UDPSessionRegistrationDatagram{}\n\t\terr = unmarshaled.UnmarshalBinary(marshaled)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif !compareRegistrationDatagrams(t, expected, &unmarshaled) {\n\t\t\tt.Errorf(\"not equal:\\n%+v\\n%+v\", expected, &unmarshaled)\n\t\t}\n\t})\n}\n\nfunc TestTypeUnmarshalErrors(t *testing.T) {\n\tt.Run(\"invalid length\", func(t *testing.T) {\n\t\td1 := v3.UDPSessionRegistrationDatagram{}\n\t\terr := d1.UnmarshalBinary([]byte{})\n\t\tif !errors.Is(err, v3.ErrDatagramHeaderTooSmall) {\n\t\t\tt.Errorf(\"expected invalid length to throw error\")\n\t\t}\n\n\t\td2 := v3.UDPSessionPayloadDatagram{}\n\t\terr = d2.UnmarshalBinary([]byte{})\n\t\tif !errors.Is(err, v3.ErrDatagramHeaderTooSmall) {\n\t\t\tt.Errorf(\"expected invalid length to throw error\")\n\t\t}\n\n\t\td3 := v3.UDPSessionRegistrationResponseDatagram{}\n\t\terr = d3.UnmarshalBinary([]byte{})\n\t\tif !errors.Is(err, v3.ErrDatagramHeaderTooSmall) {\n\t\t\tt.Errorf(\"expected invalid length to throw error\")\n\t\t}\n\n\t\td4 := v3.ICMPDatagram{}\n\t\terr = d4.UnmarshalBinary([]byte{})\n\t\tif !errors.Is(err, v3.ErrDatagramHeaderTooSmall) {\n\t\t\tt.Errorf(\"expected invalid length to throw error\")\n\t\t}\n\t})\n\n\tt.Run(\"invalid types\", func(t *testing.T) {\n\t\td1 := v3.UDPSessionRegistrationDatagram{}\n\t\terr := d1.UnmarshalBinary([]byte{byte(v3.UDPSessionRegistrationResponseType)})\n\t\tif !errors.Is(err, v3.ErrInvalidDatagramType) {\n\t\t\tt.Errorf(\"expected invalid type to throw error\")\n\t\t}\n\n\t\td2 := v3.UDPSessionPayloadDatagram{}\n\t\terr = d2.UnmarshalBinary([]byte{byte(v3.UDPSessionRegistrationType)})\n\t\tif !errors.Is(err, v3.ErrInvalidDatagramType) {\n\t\t\tt.Errorf(\"expected invalid type to throw error\")\n\t\t}\n\n\t\td3 := v3.UDPSessionRegistrationResponseDatagram{}\n\t\terr = d3.UnmarshalBinary([]byte{byte(v3.UDPSessionPayloadType)})\n\t\tif !errors.Is(err, v3.ErrInvalidDatagramType) {\n\t\t\tt.Errorf(\"expected invalid type to throw error\")\n\t\t}\n\n\t\td4 := v3.ICMPDatagram{}\n\t\terr = d4.UnmarshalBinary([]byte{byte(v3.UDPSessionPayloadType)})\n\t\tif !errors.Is(err, v3.ErrInvalidDatagramType) {\n\t\t\tt.Errorf(\"expected invalid type to throw error\")\n\t\t}\n\t})\n}\n\nfunc TestSessionPayload(t *testing.T) {\n\tt.Run(\"basic\", func(t *testing.T) {\n\t\tpayload := makePayload(128)\n\t\terr := v3.MarshalPayloadHeaderTo(testRequestID, payload[0:17])\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tunmarshaled := v3.UDPSessionPayloadDatagram{}\n\t\terr = unmarshaled.UnmarshalBinary(payload)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\trequire.Equal(t, testRequestID, unmarshaled.RequestID)\n\t\trequire.Equal(t, payload[17:], unmarshaled.Payload)\n\t})\n\n\tt.Run(\"empty\", func(t *testing.T) {\n\t\tpayload := makePayload(17)\n\t\terr := v3.MarshalPayloadHeaderTo(testRequestID, payload)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tunmarshaled := v3.UDPSessionPayloadDatagram{}\n\t\terr = unmarshaled.UnmarshalBinary(payload)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\trequire.Equal(t, testRequestID, unmarshaled.RequestID)\n\t\trequire.Equal(t, payload[17:], unmarshaled.Payload)\n\t})\n\n\tt.Run(\"header size too small\", func(t *testing.T) {\n\t\tpayload := makePayload(16)\n\t\terr := v3.MarshalPayloadHeaderTo(testRequestID, payload)\n\t\tif !errors.Is(err, v3.ErrDatagramPayloadHeaderTooSmall) {\n\t\t\tt.Errorf(\"expected an error\")\n\t\t}\n\t})\n\n\tt.Run(\"payload size too small\", func(t *testing.T) {\n\t\tpayload := makePayload(17)\n\t\terr := v3.MarshalPayloadHeaderTo(testRequestID, payload)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tunmarshaled := v3.UDPSessionPayloadDatagram{}\n\t\terr = unmarshaled.UnmarshalBinary(payload[:16])\n\t\tif !errors.Is(err, v3.ErrDatagramPayloadInvalidSize) {\n\t\t\tt.Errorf(\"expected an error: %s\", err)\n\t\t}\n\t})\n\n\tt.Run(\"payload size too large\", func(t *testing.T) {\n\t\tdatagram := makePayload(17 + 1281) // 1280 is the largest payload size allowed\n\t\terr := v3.MarshalPayloadHeaderTo(testRequestID, datagram)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tunmarshaled := v3.UDPSessionPayloadDatagram{}\n\t\terr = unmarshaled.UnmarshalBinary(datagram[:])\n\t\tif !errors.Is(err, v3.ErrDatagramPayloadInvalidSize) {\n\t\t\tt.Errorf(\"expected an error: %s\", err)\n\t\t}\n\t})\n}\n\nfunc TestSessionRegistrationResponse(t *testing.T) {\n\tvalidRespTypes := []v3.SessionRegistrationResp{\n\t\tv3.ResponseOk,\n\t\tv3.ResponseDestinationUnreachable,\n\t\tv3.ResponseUnableToBindSocket,\n\t\tv3.ResponseErrorWithMsg,\n\t}\n\tt.Run(\"basic\", func(t *testing.T) {\n\t\tfor _, responseType := range validRespTypes {\n\t\t\tdatagram := &v3.UDPSessionRegistrationResponseDatagram{\n\t\t\t\tRequestID:    testRequestID,\n\t\t\t\tResponseType: responseType,\n\t\t\t\tErrorMsg:     \"test\",\n\t\t\t}\n\t\t\tmarshaled, err := datagram.MarshalBinary()\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\tunmarshaled := &v3.UDPSessionRegistrationResponseDatagram{}\n\t\t\terr = unmarshaled.UnmarshalBinary(marshaled)\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\trequire.Equal(t, datagram, unmarshaled)\n\t\t}\n\t})\n\n\tt.Run(\"unsupported resp type is valid\", func(t *testing.T) {\n\t\tdatagram := &v3.UDPSessionRegistrationResponseDatagram{\n\t\t\tRequestID:    testRequestID,\n\t\t\tResponseType: v3.SessionRegistrationResp(0xfc),\n\t\t\tErrorMsg:     \"\",\n\t\t}\n\t\tmarshaled, err := datagram.MarshalBinary()\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tunmarshaled := &v3.UDPSessionRegistrationResponseDatagram{}\n\t\terr = unmarshaled.UnmarshalBinary(marshaled)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\trequire.Equal(t, datagram, unmarshaled)\n\t})\n\n\tt.Run(\"too small to unmarshal\", func(t *testing.T) {\n\t\tpayload := makePayload(17)\n\t\tpayload[0] = byte(v3.UDPSessionRegistrationResponseType)\n\t\tunmarshaled := &v3.UDPSessionRegistrationResponseDatagram{}\n\t\terr := unmarshaled.UnmarshalBinary(payload)\n\t\tif !errors.Is(err, v3.ErrDatagramResponseInvalidSize) {\n\t\t\tt.Errorf(\"expected an error\")\n\t\t}\n\t})\n\n\tt.Run(\"error message too long\", func(t *testing.T) {\n\t\tmessage := \"\"\n\t\tfor i := 0; i < 1280; i++ {\n\t\t\tmessage += \"a\"\n\t\t}\n\t\tdatagram := &v3.UDPSessionRegistrationResponseDatagram{\n\t\t\tRequestID:    testRequestID,\n\t\t\tResponseType: v3.SessionRegistrationResp(0xfc),\n\t\t\tErrorMsg:     message,\n\t\t}\n\t\t_, err := datagram.MarshalBinary()\n\t\tif !errors.Is(err, v3.ErrDatagramResponseMsgInvalidSize) {\n\t\t\tt.Errorf(\"expected an error\")\n\t\t}\n\t})\n\n\tt.Run(\"error message too large to unmarshal\", func(t *testing.T) {\n\t\tpayload := makePayload(1280)\n\t\tpayload[0] = byte(v3.UDPSessionRegistrationResponseType)\n\t\tbinary.BigEndian.PutUint16(payload[18:20], 1280) // larger than the datagram size could be\n\t\tunmarshaled := &v3.UDPSessionRegistrationResponseDatagram{}\n\t\terr := unmarshaled.UnmarshalBinary(payload)\n\t\tif !errors.Is(err, v3.ErrDatagramResponseMsgTooLargeMaximum) {\n\t\t\tt.Errorf(\"expected an error: %v\", err)\n\t\t}\n\t})\n\n\tt.Run(\"error message larger than provided buffer\", func(t *testing.T) {\n\t\tpayload := makePayload(1000)\n\t\tpayload[0] = byte(v3.UDPSessionRegistrationResponseType)\n\t\tbinary.BigEndian.PutUint16(payload[18:20], 1001) // larger than the datagram size provided\n\t\tunmarshaled := &v3.UDPSessionRegistrationResponseDatagram{}\n\t\terr := unmarshaled.UnmarshalBinary(payload)\n\t\tif !errors.Is(err, v3.ErrDatagramResponseMsgTooLargeDatagram) {\n\t\t\tt.Errorf(\"expected an error: %v\", err)\n\t\t}\n\t})\n}\n\nfunc TestICMPDatagram(t *testing.T) {\n\tt.Run(\"basic\", func(t *testing.T) {\n\t\tpayload := makePayload(128)\n\t\tdatagram := v3.ICMPDatagram{Payload: payload}\n\t\tmarshaled, err := datagram.MarshalBinary()\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tunmarshaled := &v3.ICMPDatagram{}\n\t\terr = unmarshaled.UnmarshalBinary(marshaled)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\trequire.Equal(t, payload, unmarshaled.Payload)\n\t})\n\n\tt.Run(\"payload size empty\", func(t *testing.T) {\n\t\tpayload := []byte{}\n\t\tdatagram := v3.ICMPDatagram{Payload: payload}\n\t\t_, err := datagram.MarshalBinary()\n\t\tif !errors.Is(err, v3.ErrDatagramICMPPayloadMissing) {\n\t\t\tt.Errorf(\"expected an error: %s\", err)\n\t\t}\n\t\tpayload = []byte{byte(v3.ICMPType)}\n\t\tunmarshaled := &v3.ICMPDatagram{}\n\t\terr = unmarshaled.UnmarshalBinary(payload)\n\t\tif !errors.Is(err, v3.ErrDatagramICMPPayloadMissing) {\n\t\t\tt.Errorf(\"expected an error: %s\", err)\n\t\t}\n\t})\n\n\tt.Run(\"payload size too large\", func(t *testing.T) {\n\t\tpayload := makePayload(1280 + 1) // larger than the datagram size could be\n\t\tdatagram := v3.ICMPDatagram{Payload: payload}\n\t\t_, err := datagram.MarshalBinary()\n\t\tif !errors.Is(err, v3.ErrDatagramICMPPayloadTooLarge) {\n\t\t\tt.Errorf(\"expected an error: %s\", err)\n\t\t}\n\t\tpayload = makePayload(1280 + 2) // larger than the datagram size could be + header\n\t\tpayload[0] = byte(v3.ICMPType)\n\t\tunmarshaled := &v3.ICMPDatagram{}\n\t\terr = unmarshaled.UnmarshalBinary(payload)\n\t\tif !errors.Is(err, v3.ErrDatagramICMPPayloadTooLarge) {\n\t\t\tt.Errorf(\"expected an error: %s\", err)\n\t\t}\n\t})\n}\n\nfunc compareRegistrationDatagrams(t *testing.T, l *v3.UDPSessionRegistrationDatagram, r *v3.UDPSessionRegistrationDatagram) bool {\n\trequire.Equal(t, l.Payload, r.Payload)\n\treturn l.RequestID == r.RequestID &&\n\t\tl.Dest == r.Dest &&\n\t\tl.IdleDurationHint == r.IdleDurationHint &&\n\t\tl.Traced == r.Traced\n}\n\nfunc FuzzRegistrationDatagram(f *testing.F) {\n\tf.Fuzz(func(t *testing.T, data []byte) {\n\t\tunmarshaled := v3.UDPSessionRegistrationDatagram{}\n\t\terr := unmarshaled.UnmarshalBinary(data)\n\t\tif err == nil {\n\t\t\t_, _ = unmarshaled.MarshalBinary()\n\t\t}\n\t})\n}\n\nfunc FuzzPayloadDatagram(f *testing.F) {\n\tf.Fuzz(func(t *testing.T, data []byte) {\n\t\tunmarshaled := v3.UDPSessionPayloadDatagram{}\n\t\t_ = unmarshaled.UnmarshalBinary(data)\n\t})\n}\n\nfunc FuzzRegistrationResponseDatagram(f *testing.F) {\n\tf.Fuzz(func(t *testing.T, data []byte) {\n\t\tunmarshaled := v3.UDPSessionRegistrationResponseDatagram{}\n\t\terr := unmarshaled.UnmarshalBinary(data)\n\t\tif err == nil {\n\t\t\t_, _ = unmarshaled.MarshalBinary()\n\t\t}\n\t})\n}\n\nfunc FuzzICMPDatagram(f *testing.F) {\n\tf.Fuzz(func(t *testing.T, data []byte) {\n\t\tunmarshaled := v3.ICMPDatagram{}\n\t\terr := unmarshaled.UnmarshalBinary(data)\n\t\tif err == nil {\n\t\t\t_, _ = unmarshaled.MarshalBinary()\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "quic/v3/icmp.go",
    "content": "package v3\n\nimport (\n\t\"context\"\n\n\t\"github.com/rs/zerolog\"\n\t\"go.opentelemetry.io/otel/trace\"\n\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\t\"github.com/cloudflare/cloudflared/packet\"\n\t\"github.com/cloudflare/cloudflared/tracing\"\n)\n\n// packetResponder is an implementation of the [ingress.ICMPResponder] which provides the ICMP Flow manager the\n// return path to return and ICMP Echo response back to the QUIC muxer.\ntype packetResponder struct {\n\tdatagramMuxer DatagramICMPWriter\n\tconnID        uint8\n}\n\nfunc newPacketResponder(datagramMuxer DatagramICMPWriter, connID uint8) ingress.ICMPResponder {\n\treturn &packetResponder{\n\t\tdatagramMuxer,\n\t\tconnID,\n\t}\n}\n\nfunc (pr *packetResponder) ConnectionIndex() uint8 {\n\treturn pr.connID\n}\n\nfunc (pr *packetResponder) ReturnPacket(pk *packet.ICMP) error {\n\treturn pr.datagramMuxer.SendICMPPacket(pk)\n}\n\nfunc (pr *packetResponder) AddTraceContext(tracedCtx *tracing.TracedContext, serializedIdentity []byte) {\n\t// datagram v3 does not support tracing ICMP packets\n}\n\nfunc (pr *packetResponder) RequestSpan(ctx context.Context, pk *packet.ICMP) (context.Context, trace.Span) {\n\t// datagram v3 does not support tracing ICMP packets\n\treturn ctx, tracing.NewNoopSpan()\n}\n\nfunc (pr *packetResponder) ReplySpan(ctx context.Context, logger *zerolog.Logger) (context.Context, trace.Span) {\n\t// datagram v3 does not support tracing ICMP packets\n\treturn ctx, tracing.NewNoopSpan()\n}\n\nfunc (pr *packetResponder) ExportSpan() {\n\t// datagram v3 does not support tracing ICMP packets\n}\n"
  },
  {
    "path": "quic/v3/icmp_test.go",
    "content": "package v3_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\t\"github.com/cloudflare/cloudflared/packet\"\n)\n\ntype noopICMPRouter struct{}\n\nfunc (noopICMPRouter) Request(ctx context.Context, pk *packet.ICMP, responder ingress.ICMPResponder) error {\n\treturn nil\n}\nfunc (noopICMPRouter) ConvertToTTLExceeded(pk *packet.ICMP, rawPacket packet.RawPacket) *packet.ICMP {\n\treturn nil\n}\n\ntype mockICMPRouter struct {\n\trecv chan *packet.ICMP\n}\n\nfunc newMockICMPRouter() *mockICMPRouter {\n\treturn &mockICMPRouter{\n\t\trecv: make(chan *packet.ICMP, 1),\n\t}\n}\n\nfunc (m *mockICMPRouter) Request(ctx context.Context, pk *packet.ICMP, responder ingress.ICMPResponder) error {\n\tm.recv <- pk\n\treturn nil\n}\nfunc (mockICMPRouter) ConvertToTTLExceeded(pk *packet.ICMP, rawPacket packet.RawPacket) *packet.ICMP {\n\treturn packet.NewICMPTTLExceedPacket(pk.IP, rawPacket, testLocalAddr.AddrPort().Addr())\n}\n\nfunc assertICMPEqual(t *testing.T, expected *packet.ICMP, actual *packet.ICMP) {\n\tif expected.Src != actual.Src {\n\t\tt.Fatalf(\"Src address not equal: %+v\\t%+v\", expected, actual)\n\t}\n\tif expected.Dst != actual.Dst {\n\t\tt.Fatalf(\"Dst address not equal: %+v\\t%+v\", expected, actual)\n\t}\n}\n"
  },
  {
    "path": "quic/v3/manager.go",
    "content": "package v3\n\nimport (\n\t\"errors\"\n\t\"sync\"\n\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\t\"github.com/cloudflare/cloudflared/management\"\n\n\tcfdflow \"github.com/cloudflare/cloudflared/flow\"\n)\n\nvar (\n\t// ErrSessionNotFound indicates that a session has not been registered yet for the request id.\n\tErrSessionNotFound = errors.New(\"flow not found\")\n\t// ErrSessionBoundToOtherConn is returned when a registration already exists for a different connection.\n\tErrSessionBoundToOtherConn = errors.New(\"flow is in use by another connection\")\n\t// ErrSessionAlreadyRegistered is returned when a registration already exists for this connection.\n\tErrSessionAlreadyRegistered = errors.New(\"flow is already registered for this connection\")\n\t// ErrSessionRegistrationRateLimited is returned when a registration fails due to rate limiting on the number of active flows.\n\tErrSessionRegistrationRateLimited = errors.New(\"flow registration rate limited\")\n)\n\ntype SessionManager interface {\n\t// RegisterSession will register a new session if it does not already exist for the request ID.\n\t// During new session creation, the session will also bind the UDP socket for the origin.\n\t// If the session exists for a different connection, it will return [ErrSessionBoundToOtherConn].\n\tRegisterSession(request *UDPSessionRegistrationDatagram, conn DatagramConn) (Session, error)\n\t// GetSession returns an active session if available for the provided connection.\n\t// If the session does not exist, it will return [ErrSessionNotFound]. If the session exists for a different\n\t// connection, it will return [ErrSessionBoundToOtherConn].\n\tGetSession(requestID RequestID) (Session, error)\n\t// UnregisterSession will remove a session from the current session manager. It will attempt to close the session\n\t// before removal.\n\tUnregisterSession(requestID RequestID)\n}\n\ntype sessionManager struct {\n\tsessions     map[RequestID]Session\n\tmutex        sync.RWMutex\n\toriginDialer ingress.OriginUDPDialer\n\tlimiter      cfdflow.Limiter\n\tmetrics      Metrics\n\tlog          *zerolog.Logger\n}\n\nfunc NewSessionManager(metrics Metrics, log *zerolog.Logger, originDialer ingress.OriginUDPDialer, limiter cfdflow.Limiter) SessionManager {\n\treturn &sessionManager{\n\t\tsessions:     make(map[RequestID]Session),\n\t\toriginDialer: originDialer,\n\t\tlimiter:      limiter,\n\t\tmetrics:      metrics,\n\t\tlog:          log,\n\t}\n}\n\nfunc (s *sessionManager) RegisterSession(request *UDPSessionRegistrationDatagram, conn DatagramConn) (Session, error) {\n\ts.mutex.Lock()\n\tdefer s.mutex.Unlock()\n\t// Check to make sure session doesn't already exist for requestID\n\tif session, exists := s.sessions[request.RequestID]; exists {\n\t\tif conn.ID() == session.ConnectionID() {\n\t\t\treturn nil, ErrSessionAlreadyRegistered\n\t\t}\n\t\treturn nil, ErrSessionBoundToOtherConn\n\t}\n\n\t// Try to start a new session\n\tif err := s.limiter.Acquire(management.UDP.String()); err != nil {\n\t\treturn nil, ErrSessionRegistrationRateLimited\n\t}\n\n\t// Attempt to bind the UDP socket for the new session\n\torigin, err := s.originDialer.DialUDP(request.Dest)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// Create and insert the new session in the map\n\tsession := NewSession(\n\t\trequest.RequestID,\n\t\trequest.IdleDurationHint,\n\t\torigin,\n\t\torigin.RemoteAddr(),\n\t\torigin.LocalAddr(),\n\t\tconn,\n\t\ts.metrics,\n\t\ts.log)\n\ts.sessions[request.RequestID] = session\n\treturn session, nil\n}\n\nfunc (s *sessionManager) GetSession(requestID RequestID) (Session, error) {\n\ts.mutex.RLock()\n\tdefer s.mutex.RUnlock()\n\tsession, exists := s.sessions[requestID]\n\tif exists {\n\t\treturn session, nil\n\t}\n\treturn nil, ErrSessionNotFound\n}\n\nfunc (s *sessionManager) UnregisterSession(requestID RequestID) {\n\ts.mutex.Lock()\n\tdefer s.mutex.Unlock()\n\t// Get the session and make sure to close it if it isn't already closed\n\tsession, exists := s.sessions[requestID]\n\tif exists {\n\t\t// We ignore any errors when attempting to close the session\n\t\t_ = session.Close()\n\t}\n\tdelete(s.sessions, requestID)\n\ts.limiter.Release()\n}\n"
  },
  {
    "path": "quic/v3/manager_test.go",
    "content": "package v3_test\n\nimport (\n\t\"errors\"\n\t\"net/netip\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/require\"\n\t\"go.uber.org/mock/gomock\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/mocks\"\n\n\tcfdflow \"github.com/cloudflare/cloudflared/flow\"\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\tv3 \"github.com/cloudflare/cloudflared/quic/v3\"\n)\n\nvar (\n\ttestDefaultDialer = ingress.NewDialer(ingress.WarpRoutingConfig{\n\t\tConnectTimeout: config.CustomDuration{Duration: 1 * time.Second},\n\t\tTCPKeepAlive:   config.CustomDuration{Duration: 15 * time.Second},\n\t\tMaxActiveFlows: 0,\n\t})\n)\n\nfunc TestRegisterSession(t *testing.T) {\n\tlog := zerolog.Nop()\n\toriginDialerService := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 0,\n\t}, &log)\n\tmanager := v3.NewSessionManager(&noopMetrics{}, &log, originDialerService, cfdflow.NewLimiter(0))\n\n\trequest := v3.UDPSessionRegistrationDatagram{\n\t\tRequestID:        testRequestID,\n\t\tDest:             netip.MustParseAddrPort(\"127.0.0.1:5000\"),\n\t\tTraced:           false,\n\t\tIdleDurationHint: 5 * time.Second,\n\t\tPayload:          nil,\n\t}\n\tsession, err := manager.RegisterSession(&request, &noopEyeball{})\n\tif err != nil {\n\t\tt.Fatalf(\"register session should've succeeded: %v\", err)\n\t}\n\tif request.RequestID != session.ID() {\n\t\tt.Fatalf(\"session id doesn't match: %v != %v\", request.RequestID, session.ID())\n\t}\n\n\t// We shouldn't be able to register another session with the same request id\n\t_, err = manager.RegisterSession(&request, &noopEyeball{})\n\tif !errors.Is(err, v3.ErrSessionAlreadyRegistered) {\n\t\tt.Fatalf(\"session is already registered for this connection: %v\", err)\n\t}\n\n\t// We shouldn't be able to register another session with the same request id for a different connection\n\t_, err = manager.RegisterSession(&request, &noopEyeball{connID: 1})\n\tif !errors.Is(err, v3.ErrSessionBoundToOtherConn) {\n\t\tt.Fatalf(\"session is already registered for a separate connection: %v\", err)\n\t}\n\n\t// Get session\n\tsessionGet, err := manager.GetSession(request.RequestID)\n\tif err != nil {\n\t\tt.Fatalf(\"get session failed: %v\", err)\n\t}\n\tif session.ID() != sessionGet.ID() {\n\t\tt.Fatalf(\"session's do not match: %v != %v\", session.ID(), sessionGet.ID())\n\t}\n\n\t// Remove the session\n\tmanager.UnregisterSession(request.RequestID)\n\n\t// Get session should fail\n\t_, err = manager.GetSession(request.RequestID)\n\tif !errors.Is(err, v3.ErrSessionNotFound) {\n\t\tt.Fatalf(\"get session failed: %v\", err)\n\t}\n\n\t// Closing the original session should return that the socket is already closed (by the session unregistration)\n\terr = session.Close()\n\tif err != nil && !strings.Contains(err.Error(), \"use of closed network connection\") {\n\t\tt.Fatalf(\"session should've closed without issue: %v\", err)\n\t}\n}\n\nfunc TestGetSession_Empty(t *testing.T) {\n\tlog := zerolog.Nop()\n\toriginDialerService := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 0,\n\t}, &log)\n\tmanager := v3.NewSessionManager(&noopMetrics{}, &log, originDialerService, cfdflow.NewLimiter(0))\n\n\t_, err := manager.GetSession(testRequestID)\n\tif !errors.Is(err, v3.ErrSessionNotFound) {\n\t\tt.Fatalf(\"get session find no session: %v\", err)\n\t}\n}\n\nfunc TestRegisterSessionRateLimit(t *testing.T) {\n\tlog := zerolog.Nop()\n\toriginDialerService := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 0,\n\t}, &log)\n\tctrl := gomock.NewController(t)\n\n\tflowLimiterMock := mocks.NewMockLimiter(ctrl)\n\n\tflowLimiterMock.EXPECT().Acquire(\"udp\").Return(cfdflow.ErrTooManyActiveFlows)\n\tflowLimiterMock.EXPECT().Release().Times(0)\n\n\tmanager := v3.NewSessionManager(&noopMetrics{}, &log, originDialerService, flowLimiterMock)\n\n\trequest := v3.UDPSessionRegistrationDatagram{\n\t\tRequestID:        testRequestID,\n\t\tDest:             netip.MustParseAddrPort(\"127.0.0.1:5000\"),\n\t\tTraced:           false,\n\t\tIdleDurationHint: 5 * time.Second,\n\t\tPayload:          nil,\n\t}\n\t_, err := manager.RegisterSession(&request, &noopEyeball{})\n\trequire.ErrorIs(t, err, v3.ErrSessionRegistrationRateLimited)\n}\n"
  },
  {
    "path": "quic/v3/metrics.go",
    "content": "package v3\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n\n\t\"github.com/cloudflare/cloudflared/quic\"\n)\n\nconst (\n\tnamespace      = \"cloudflared\"\n\tsubsystem_udp  = \"udp\"\n\tsubsystem_icmp = \"icmp\"\n\n\tcommandMetricLabel = \"command\"\n\treasonMetricLabel  = \"reason\"\n)\n\ntype DroppedReason int\n\nconst (\n\tDroppedWriteFailed DroppedReason = iota\n\tDroppedWriteDeadlineExceeded\n\tDroppedWriteFull\n\tDroppedWriteFlowUnknown\n\tDroppedReadFailed\n\t// Origin payloads that are too large to proxy.\n\tDroppedReadTooLarge\n)\n\nvar droppedReason = map[DroppedReason]string{\n\tDroppedWriteFailed:           \"write_failed\",\n\tDroppedWriteDeadlineExceeded: \"write_deadline_exceeded\",\n\tDroppedWriteFull:             \"write_full\",\n\tDroppedWriteFlowUnknown:      \"write_flow_unknown\",\n\tDroppedReadFailed:            \"read_failed\",\n\tDroppedReadTooLarge:          \"read_too_large\",\n}\n\nfunc (dr DroppedReason) String() string {\n\treturn droppedReason[dr]\n}\n\ntype Metrics interface {\n\tIncrementFlows(connIndex uint8)\n\tDecrementFlows(connIndex uint8)\n\tFailedFlow(connIndex uint8)\n\tRetryFlowResponse(connIndex uint8)\n\tMigrateFlow(connIndex uint8)\n\tUnsupportedRemoteCommand(connIndex uint8, command string)\n\tDroppedUDPDatagram(connIndex uint8, reason DroppedReason)\n\tDroppedICMPPackets(connIndex uint8, reason DroppedReason)\n}\n\ntype metrics struct {\n\tactiveUDPFlows            *prometheus.GaugeVec\n\ttotalUDPFlows             *prometheus.CounterVec\n\tretryFlowResponses        *prometheus.CounterVec\n\tmigratedFlows             *prometheus.CounterVec\n\tunsupportedRemoteCommands *prometheus.CounterVec\n\tdroppedUDPDatagrams       *prometheus.CounterVec\n\tdroppedICMPPackets        *prometheus.CounterVec\n\tfailedFlows               *prometheus.CounterVec\n}\n\nfunc (m *metrics) IncrementFlows(connIndex uint8) {\n\tm.totalUDPFlows.WithLabelValues(fmt.Sprintf(\"%d\", connIndex)).Inc()\n\tm.activeUDPFlows.WithLabelValues(fmt.Sprintf(\"%d\", connIndex)).Inc()\n}\n\nfunc (m *metrics) DecrementFlows(connIndex uint8) {\n\tm.activeUDPFlows.WithLabelValues(fmt.Sprintf(\"%d\", connIndex)).Dec()\n}\n\nfunc (m *metrics) FailedFlow(connIndex uint8) {\n\tm.failedFlows.WithLabelValues(fmt.Sprintf(\"%d\", connIndex)).Inc()\n}\n\nfunc (m *metrics) RetryFlowResponse(connIndex uint8) {\n\tm.retryFlowResponses.WithLabelValues(fmt.Sprintf(\"%d\", connIndex)).Inc()\n}\n\nfunc (m *metrics) MigrateFlow(connIndex uint8) {\n\tm.migratedFlows.WithLabelValues(fmt.Sprintf(\"%d\", connIndex)).Inc()\n}\n\nfunc (m *metrics) UnsupportedRemoteCommand(connIndex uint8, command string) {\n\tm.unsupportedRemoteCommands.WithLabelValues(fmt.Sprintf(\"%d\", connIndex), command).Inc()\n}\n\nfunc (m *metrics) DroppedUDPDatagram(connIndex uint8, reason DroppedReason) {\n\tm.droppedUDPDatagrams.WithLabelValues(fmt.Sprintf(\"%d\", connIndex), reason.String()).Inc()\n}\n\nfunc (m *metrics) DroppedICMPPackets(connIndex uint8, reason DroppedReason) {\n\tm.droppedICMPPackets.WithLabelValues(fmt.Sprintf(\"%d\", connIndex), reason.String()).Inc()\n}\n\nfunc NewMetrics(registerer prometheus.Registerer) Metrics {\n\tm := &metrics{\n\t\tactiveUDPFlows: prometheus.NewGaugeVec(prometheus.GaugeOpts{\n\t\t\tNamespace: namespace,\n\t\t\tSubsystem: subsystem_udp,\n\t\t\tName:      \"active_flows\",\n\t\t\tHelp:      \"Concurrent count of UDP flows that are being proxied to any origin\",\n\t\t}, []string{quic.ConnectionIndexMetricLabel}),\n\t\ttotalUDPFlows: prometheus.NewCounterVec(prometheus.CounterOpts{ //nolint:promlinter\n\t\t\tNamespace: namespace,\n\t\t\tSubsystem: subsystem_udp,\n\t\t\tName:      \"total_flows\",\n\t\t\tHelp:      \"Total count of UDP flows that have been proxied to any origin\",\n\t\t}, []string{quic.ConnectionIndexMetricLabel}),\n\t\tfailedFlows: prometheus.NewCounterVec(prometheus.CounterOpts{ //nolint:promlinter\n\t\t\tNamespace: namespace,\n\t\t\tSubsystem: subsystem_udp,\n\t\t\tName:      \"failed_flows\",\n\t\t\tHelp:      \"Total count of flows that errored and closed\",\n\t\t}, []string{quic.ConnectionIndexMetricLabel}),\n\t\tretryFlowResponses: prometheus.NewCounterVec(prometheus.CounterOpts{ //nolint:promlinter\n\t\t\tNamespace: namespace,\n\t\t\tSubsystem: subsystem_udp,\n\t\t\tName:      \"retry_flow_responses\",\n\t\t\tHelp:      \"Total count of UDP flows that have had to send their registration response more than once\",\n\t\t}, []string{quic.ConnectionIndexMetricLabel}),\n\t\tmigratedFlows: prometheus.NewCounterVec(prometheus.CounterOpts{ //nolint:promlinter\n\t\t\tNamespace: namespace,\n\t\t\tSubsystem: subsystem_udp,\n\t\t\tName:      \"migrated_flows\",\n\t\t\tHelp:      \"Total count of UDP flows have been migrated across local connections\",\n\t\t}, []string{quic.ConnectionIndexMetricLabel}),\n\t\tunsupportedRemoteCommands: prometheus.NewCounterVec(prometheus.CounterOpts{ //nolint:promlinter\n\t\t\tNamespace: namespace,\n\t\t\tSubsystem: subsystem_udp,\n\t\t\tName:      \"unsupported_remote_command_total\",\n\t\t\tHelp:      \"Total count of unsupported remote RPC commands called\",\n\t\t}, []string{quic.ConnectionIndexMetricLabel, commandMetricLabel}),\n\t\tdroppedUDPDatagrams: prometheus.NewCounterVec(prometheus.CounterOpts{ //nolint:promlinter\n\t\t\tNamespace: namespace,\n\t\t\tSubsystem: subsystem_udp,\n\t\t\tName:      \"dropped_datagrams\",\n\t\t\tHelp:      \"Total count of UDP dropped datagrams\",\n\t\t}, []string{quic.ConnectionIndexMetricLabel, reasonMetricLabel}),\n\t\tdroppedICMPPackets: prometheus.NewCounterVec(prometheus.CounterOpts{ //nolint:promlinter\n\t\t\tNamespace: namespace,\n\t\t\tSubsystem: subsystem_icmp,\n\t\t\tName:      \"dropped_packets\",\n\t\t\tHelp:      \"Total count of ICMP dropped datagrams\",\n\t\t}, []string{quic.ConnectionIndexMetricLabel, reasonMetricLabel}),\n\t}\n\tregisterer.MustRegister(\n\t\tm.activeUDPFlows,\n\t\tm.totalUDPFlows,\n\t\tm.failedFlows,\n\t\tm.retryFlowResponses,\n\t\tm.migratedFlows,\n\t\tm.unsupportedRemoteCommands,\n\t\tm.droppedUDPDatagrams,\n\t\tm.droppedICMPPackets,\n\t)\n\treturn m\n}\n"
  },
  {
    "path": "quic/v3/metrics_test.go",
    "content": "package v3_test\n\nimport v3 \"github.com/cloudflare/cloudflared/quic/v3\"\n\ntype noopMetrics struct{}\n\nfunc (noopMetrics) IncrementFlows(connIndex uint8)                              {}\nfunc (noopMetrics) DecrementFlows(connIndex uint8)                              {}\nfunc (noopMetrics) FailedFlow(connIndex uint8)                                  {}\nfunc (noopMetrics) PayloadTooLarge(connIndex uint8)                             {}\nfunc (noopMetrics) RetryFlowResponse(connIndex uint8)                           {}\nfunc (noopMetrics) MigrateFlow(connIndex uint8)                                 {}\nfunc (noopMetrics) UnsupportedRemoteCommand(connIndex uint8, command string)    {}\nfunc (noopMetrics) DroppedUDPDatagram(connIndex uint8, reason v3.DroppedReason) {}\nfunc (noopMetrics) DroppedICMPPackets(connIndex uint8, reason v3.DroppedReason) {}\n"
  },
  {
    "path": "quic/v3/muxer.go",
    "content": "package v3\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\t\"github.com/cloudflare/cloudflared/packet\"\n)\n\nconst (\n\t// Allocating a 16 channel buffer here allows for the writer to be slightly faster than the reader.\n\t// This has worked previously well for datagramv2, so we will start with this as well\n\tdemuxChanCapacity = 16\n\t// This provides a small buffer for the PacketRouter to poll ICMP packets from the QUIC connection\n\t// before writing them to the origin.\n\ticmpDatagramChanCapacity = 128\n\n\tlogSrcKey      = \"src\"\n\tlogDstKey      = \"dst\"\n\tlogICMPTypeKey = \"type\"\n\tlogDurationKey = \"durationMS\"\n)\n\n// DatagramConn is the bridge that multiplexes writes and reads of datagrams for UDP sessions and ICMP packets to\n// a connection.\ntype DatagramConn interface {\n\tDatagramUDPWriter\n\tDatagramICMPWriter\n\t// Serve provides a server interface to process and handle incoming QUIC datagrams and demux their datagram v3 payloads.\n\tServe(context.Context) error\n\t// ID indicates connection index identifier\n\tID() uint8\n}\n\n// DatagramUDPWriter provides the Muxer interface to create proper UDP Datagrams when sending over a connection.\ntype DatagramUDPWriter interface {\n\tSendUDPSessionDatagram(datagram []byte) error\n\tSendUDPSessionResponse(id RequestID, resp SessionRegistrationResp) error\n}\n\n// DatagramICMPWriter provides the Muxer interface to create ICMP Datagrams when sending over a connection.\ntype DatagramICMPWriter interface {\n\tSendICMPPacket(icmp *packet.ICMP) error\n\tSendICMPTTLExceed(icmp *packet.ICMP, rawPacket packet.RawPacket) error\n}\n\n// QuicConnection provides an interface that matches [quic.Connection] for only the datagram operations.\n//\n// We currently rely on the mutex for the [quic.Connection.SendDatagram] and [quic.Connection.ReceiveDatagram] and\n// do not have any locking for them. If the implementation in quic-go were to ever change, we would need to make\n// sure that we lock properly on these operations.\ntype QuicConnection interface {\n\tContext() context.Context\n\tSendDatagram(payload []byte) error\n\tReceiveDatagram(context.Context) ([]byte, error)\n}\n\ntype datagramConn struct {\n\tconn             QuicConnection\n\tindex            uint8\n\tsessionManager   SessionManager\n\ticmpRouter       ingress.ICMPRouter\n\tmetrics          Metrics\n\tlogger           *zerolog.Logger\n\tdatagrams        chan []byte\n\ticmpDatagramChan chan *ICMPDatagram\n\treadErrors       chan error\n\n\ticmpEncoderPool sync.Pool // a pool of *packet.Encoder\n\ticmpDecoderPool sync.Pool\n}\n\nfunc NewDatagramConn(conn QuicConnection, sessionManager SessionManager, icmpRouter ingress.ICMPRouter, index uint8, metrics Metrics, logger *zerolog.Logger) DatagramConn {\n\tlog := logger.With().Uint8(\"datagramVersion\", 3).Logger()\n\treturn &datagramConn{\n\t\tconn:             conn,\n\t\tindex:            index,\n\t\tsessionManager:   sessionManager,\n\t\ticmpRouter:       icmpRouter,\n\t\tmetrics:          metrics,\n\t\tlogger:           &log,\n\t\tdatagrams:        make(chan []byte, demuxChanCapacity),\n\t\ticmpDatagramChan: make(chan *ICMPDatagram, icmpDatagramChanCapacity),\n\t\treadErrors:       make(chan error, 2),\n\t\ticmpEncoderPool: sync.Pool{\n\t\t\tNew: func() any {\n\t\t\t\treturn packet.NewEncoder()\n\t\t\t},\n\t\t},\n\t\ticmpDecoderPool: sync.Pool{\n\t\t\tNew: func() any {\n\t\t\t\treturn packet.NewICMPDecoder()\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc (c *datagramConn) ID() uint8 {\n\treturn c.index\n}\n\nfunc (c *datagramConn) SendUDPSessionDatagram(datagram []byte) error {\n\treturn c.conn.SendDatagram(datagram)\n}\n\nfunc (c *datagramConn) SendUDPSessionResponse(id RequestID, resp SessionRegistrationResp) error {\n\tdatagram := UDPSessionRegistrationResponseDatagram{\n\t\tRequestID:    id,\n\t\tResponseType: resp,\n\t}\n\tdata, err := datagram.MarshalBinary()\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn c.conn.SendDatagram(data)\n}\n\nfunc (c *datagramConn) SendICMPPacket(icmp *packet.ICMP) error {\n\tcachedEncoder := c.icmpEncoderPool.Get()\n\t// The encoded packet is a slice to a buffer owned by the encoder, so we shouldn't return the encoder back to the\n\t// pool until the encoded packet is sent.\n\tdefer c.icmpEncoderPool.Put(cachedEncoder)\n\tencoder, ok := cachedEncoder.(*packet.Encoder)\n\tif !ok {\n\t\treturn fmt.Errorf(\"encoderPool returned %T, expect *packet.Encoder\", cachedEncoder)\n\t}\n\tpayload, err := encoder.Encode(icmp)\n\tif err != nil {\n\t\treturn err\n\t}\n\ticmpDatagram := ICMPDatagram{\n\t\tPayload: payload.Data,\n\t}\n\tdatagram, err := icmpDatagram.MarshalBinary()\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn c.conn.SendDatagram(datagram)\n}\n\nfunc (c *datagramConn) SendICMPTTLExceed(icmp *packet.ICMP, rawPacket packet.RawPacket) error {\n\treturn c.SendICMPPacket(c.icmpRouter.ConvertToTTLExceeded(icmp, rawPacket))\n}\n\n// pollDatagrams will read datagrams from the underlying connection until the provided context is done.\nfunc (c *datagramConn) pollDatagrams(ctx context.Context) {\n\tfor ctx.Err() == nil {\n\t\tdatagram, err := c.conn.ReceiveDatagram(ctx)\n\t\t// If the read returns an error, we want to return the failure to the channel.\n\t\tif err != nil {\n\t\t\tc.readErrors <- err\n\t\t\treturn\n\t\t}\n\t\tc.datagrams <- datagram\n\t}\n\tif ctx.Err() != nil {\n\t\tc.readErrors <- ctx.Err()\n\t}\n}\n\n// Serve will begin the process of receiving datagrams from the [quic.Connection] and demuxing them to their destination.\n// The [DatagramConn] when serving, will be responsible for the sessions it accepts.\nfunc (c *datagramConn) Serve(ctx context.Context) error {\n\tconnCtx := c.conn.Context()\n\t// We want to make sure that we cancel the reader context if the Serve method returns. This could also mean that the\n\t// underlying connection is also closing, but that is handled outside of the context of the datagram muxer.\n\treadCtx, cancel := context.WithCancel(connCtx)\n\tdefer cancel()\n\tgo c.pollDatagrams(readCtx)\n\t// Processing ICMP datagrams also monitors the reader context since the ICMP datagrams from the reader are the input\n\t// for the routine.\n\tgo c.processICMPDatagrams(readCtx)\n\tfor {\n\t\t// We make sure to monitor the context of cloudflared and the underlying connection to return if any errors occur.\n\t\tvar datagram []byte\n\t\tselect {\n\t\t// Monitor the context of cloudflared\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\t// Monitor the context of the underlying quic connection\n\t\tcase <-connCtx.Done():\n\t\t\treturn connCtx.Err()\n\t\t// Monitor for any hard errors from reading the connection\n\t\tcase err := <-c.readErrors:\n\t\t\treturn err\n\t\t// Wait and dequeue datagrams as they come in\n\t\tcase d := <-c.datagrams:\n\t\t\tdatagram = d\n\t\t}\n\n\t\t// Each incoming datagram will be processed in a new go routine to handle the demuxing and action associated.\n\t\ttyp, err := ParseDatagramType(datagram)\n\t\tif err != nil {\n\t\t\tc.logger.Err(err).Msgf(\"unable to parse datagram type: %d\", typ)\n\t\t\tcontinue\n\t\t}\n\t\tswitch typ {\n\t\tcase UDPSessionRegistrationType:\n\t\t\treg := &UDPSessionRegistrationDatagram{}\n\t\t\terr := reg.UnmarshalBinary(datagram)\n\t\t\tif err != nil {\n\t\t\t\tc.logger.Err(err).Msgf(\"unable to unmarshal session registration datagram\")\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tlogger := c.logger.With().Str(logFlowID, reg.RequestID.String()).Logger()\n\t\t\t// We bind the new session to the quic connection context instead of cloudflared context to allow for the\n\t\t\t// quic connection to close and close only the sessions bound to it. Closing of cloudflared will also\n\t\t\t// initiate the close of the quic connection, so we don't have to worry about the application context\n\t\t\t// in the scope of a session.\n\t\t\t//\n\t\t\t// Additionally, we spin out the registration into a separate go routine to handle the Serve'ing of the\n\t\t\t// session in a separate routine from the demuxer.\n\t\t\tgo c.handleSessionRegistrationDatagram(connCtx, reg, &logger)\n\t\tcase UDPSessionPayloadType:\n\t\t\tpayload := &UDPSessionPayloadDatagram{}\n\t\t\terr := payload.UnmarshalBinary(datagram)\n\t\t\tif err != nil {\n\t\t\t\tc.logger.Err(err).Msgf(\"unable to unmarshal session payload datagram\")\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tlogger := c.logger.With().Str(logFlowID, payload.RequestID.String()).Logger()\n\t\t\tc.handleSessionPayloadDatagram(payload, &logger)\n\t\tcase ICMPType:\n\t\t\tpacket := &ICMPDatagram{}\n\t\t\terr := packet.UnmarshalBinary(datagram)\n\t\t\tif err != nil {\n\t\t\t\tc.logger.Err(err).Msgf(\"unable to unmarshal icmp datagram\")\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tc.handleICMPPacket(packet)\n\t\tcase UDPSessionRegistrationResponseType:\n\t\t\t// cloudflared should never expect to receive UDP session responses as it will not initiate new\n\t\t\t// sessions towards the edge.\n\t\t\tc.logger.Error().Msgf(\"unexpected datagram type received: %d\", UDPSessionRegistrationResponseType)\n\t\t\tcontinue\n\t\tdefault:\n\t\t\tc.logger.Error().Msgf(\"unknown datagram type received: %d\", typ)\n\t\t}\n\t}\n}\n\n// This method handles new registrations of a session and the serve loop for the session.\nfunc (c *datagramConn) handleSessionRegistrationDatagram(ctx context.Context, datagram *UDPSessionRegistrationDatagram, logger *zerolog.Logger) {\n\tlog := logger.With().\n\t\tStr(logFlowID, datagram.RequestID.String()).\n\t\tStr(logDstKey, datagram.Dest.String()).\n\t\tLogger()\n\tsession, err := c.sessionManager.RegisterSession(datagram, c)\n\tif err != nil {\n\t\tswitch err {\n\t\tcase ErrSessionAlreadyRegistered:\n\t\t\t// Session is already registered and likely the response got lost\n\t\t\tc.handleSessionAlreadyRegistered(datagram.RequestID, &log)\n\t\tcase ErrSessionBoundToOtherConn:\n\t\t\t// Session is already registered but to a different connection\n\t\t\tc.handleSessionMigration(datagram.RequestID, &log)\n\t\tcase ErrSessionRegistrationRateLimited:\n\t\t\t// There are too many concurrent sessions so we return an error to force a retry later\n\t\t\tc.handleSessionRegistrationRateLimited(datagram, &log)\n\t\tdefault:\n\t\t\tlog.Err(err).Msg(\"flow registration failure\")\n\t\t\tc.handleSessionRegistrationFailure(datagram.RequestID, &log)\n\t\t}\n\t\treturn\n\t}\n\tlog = log.With().Str(logSrcKey, session.LocalAddr().String()).Logger()\n\tc.metrics.IncrementFlows(c.index)\n\t// Make sure to eventually remove the session from the session manager when the session is closed\n\tdefer c.sessionManager.UnregisterSession(session.ID())\n\tdefer c.metrics.DecrementFlows(c.index)\n\n\t// Respond that we are able to process the new session\n\terr = c.SendUDPSessionResponse(datagram.RequestID, ResponseOk)\n\tif err != nil {\n\t\tlog.Err(err).Msgf(\"flow registration failure: unable to send session registration response\")\n\t\treturn\n\t}\n\n\t// We bind the context of the session to the [quic.Connection] that initiated the session.\n\t// [Session.Serve] is blocking and will continue this go routine till the end of the session lifetime.\n\tstart := time.Now()\n\terr = session.Serve(ctx)\n\telapsedMS := time.Since(start).Milliseconds()\n\tlog = log.With().Int64(logDurationKey, elapsedMS).Logger()\n\tif err == nil {\n\t\t// We typically don't expect a session to close without some error response. [SessionIdleErr] is the typical\n\t\t// expected error response.\n\t\tlog.Warn().Msg(\"flow closed: no explicit close or timeout elapsed\")\n\t\treturn\n\t}\n\t// SessionIdleErr and SessionCloseErr are valid and successful error responses to end a session.\n\tif errors.Is(err, SessionIdleErr{}) || errors.Is(err, SessionCloseErr) {\n\t\tlog.Debug().Msgf(\"flow closed: %s\", err.Error())\n\t\treturn\n\t}\n\n\t// All other errors should be reported as errors\n\tlog.Err(err).Msgf(\"flow closed with an error\")\n}\n\nfunc (c *datagramConn) handleSessionAlreadyRegistered(requestID RequestID, logger *zerolog.Logger) {\n\t// Send another registration response since the session is already active\n\terr := c.SendUDPSessionResponse(requestID, ResponseOk)\n\tif err != nil {\n\t\tlogger.Err(err).Msgf(\"flow registration failure: unable to send an additional flow registration response\")\n\t\treturn\n\t}\n\n\tsession, err := c.sessionManager.GetSession(requestID)\n\tif err != nil {\n\t\t// If for some reason we can not find the session after attempting to register it, we can just return\n\t\t// instead of trying to reset the idle timer for it.\n\t\treturn\n\t}\n\t// The session is already running in another routine so we want to restart the idle timeout since no proxied\n\t// packets have come down yet.\n\tsession.ResetIdleTimer()\n\tc.metrics.RetryFlowResponse(c.index)\n\tlogger.Debug().Msgf(\"flow registration response retry\")\n}\n\nfunc (c *datagramConn) handleSessionMigration(requestID RequestID, logger *zerolog.Logger) {\n\t// We need to migrate the currently running session to this edge connection.\n\tsession, err := c.sessionManager.GetSession(requestID)\n\tif err != nil {\n\t\t// If for some reason we can not find the session after attempting to register it, we can just return\n\t\t// instead of trying to reset the idle timer for it.\n\t\treturn\n\t}\n\n\t// Migrate the session to use this edge connection instead of the currently running one.\n\t// We also pass in this connection's logger to override the existing logger for the session.\n\tsession.Migrate(c, c.conn.Context(), c.logger)\n\n\t// Send another registration response since the session is already active\n\terr = c.SendUDPSessionResponse(requestID, ResponseOk)\n\tif err != nil {\n\t\tlogger.Err(err).Msgf(\"flow registration failure: unable to send an additional flow registration response\")\n\t\treturn\n\t}\n\tlogger.Debug().Msgf(\"flow registration migration\")\n}\n\nfunc (c *datagramConn) handleSessionRegistrationFailure(requestID RequestID, logger *zerolog.Logger) {\n\terr := c.SendUDPSessionResponse(requestID, ResponseUnableToBindSocket)\n\tif err != nil {\n\t\tlogger.Err(err).Msgf(\"unable to send flow registration error response (%d)\", ResponseUnableToBindSocket)\n\t}\n}\n\nfunc (c *datagramConn) handleSessionRegistrationRateLimited(datagram *UDPSessionRegistrationDatagram, logger *zerolog.Logger) {\n\tc.logger.Warn().Msg(\"Too many concurrent sessions being handled, rejecting udp proxy\")\n\n\trateLimitResponse := ResponseTooManyActiveFlows\n\terr := c.SendUDPSessionResponse(datagram.RequestID, rateLimitResponse)\n\tif err != nil {\n\t\tlogger.Err(err).Msgf(\"unable to send flow registration error response (%d)\", rateLimitResponse)\n\t}\n}\n\n// Handles incoming datagrams that need to be sent to a registered session.\nfunc (c *datagramConn) handleSessionPayloadDatagram(datagram *UDPSessionPayloadDatagram, logger *zerolog.Logger) {\n\ts, err := c.sessionManager.GetSession(datagram.RequestID)\n\tif err != nil {\n\t\tc.metrics.DroppedUDPDatagram(c.index, DroppedWriteFlowUnknown)\n\t\tlogger.Err(err).Msgf(\"unable to find flow\")\n\t\treturn\n\t}\n\ts.Write(datagram.Payload)\n}\n\n// Handles incoming ICMP datagrams into a serialized channel to be handled by a single consumer.\nfunc (c *datagramConn) handleICMPPacket(datagram *ICMPDatagram) {\n\tif c.icmpRouter == nil {\n\t\t// ICMPRouter is disabled so we drop the current packet and ignore all incoming ICMP packets\n\t\treturn\n\t}\n\tselect {\n\tcase c.icmpDatagramChan <- datagram:\n\tdefault:\n\t\t// If the ICMP datagram channel is full, drop any additional incoming.\n\t\tc.metrics.DroppedICMPPackets(c.index, DroppedWriteFull)\n\t\tc.logger.Warn().Msg(\"failed to write icmp packet to origin: dropped\")\n\t}\n}\n\n// Consumes from the ICMP datagram channel to write out the ICMP requests to an origin.\nfunc (c *datagramConn) processICMPDatagrams(ctx context.Context) {\n\tif c.icmpRouter == nil {\n\t\t// ICMPRouter is disabled so we ignore all incoming ICMP packets\n\t\treturn\n\t}\n\n\tfor {\n\t\tselect {\n\t\t// If the provided context is closed we want to exit the write loop\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\tcase datagram := <-c.icmpDatagramChan:\n\t\t\tc.writeICMPPacket(datagram)\n\t\t}\n\t}\n}\n\nfunc (c *datagramConn) writeICMPPacket(datagram *ICMPDatagram) {\n\t// Decode the provided ICMPDatagram as an ICMP packet\n\trawPacket := packet.RawPacket{Data: datagram.Payload}\n\tcachedDecoder := c.icmpDecoderPool.Get()\n\tdefer c.icmpDecoderPool.Put(cachedDecoder)\n\tdecoder, ok := cachedDecoder.(*packet.ICMPDecoder)\n\tif !ok {\n\t\tc.metrics.DroppedICMPPackets(c.index, DroppedWriteFailed)\n\t\tc.logger.Error().Msg(\"Could not get ICMPDecoder from the pool. Dropping packet\")\n\t\treturn\n\t}\n\n\ticmp, err := decoder.Decode(rawPacket)\n\n\tif err != nil {\n\t\tc.metrics.DroppedICMPPackets(c.index, DroppedWriteFailed)\n\t\tc.logger.Err(err).Msgf(\"unable to marshal icmp packet\")\n\t\treturn\n\t}\n\n\t// If the ICMP packet's TTL is expired, we won't send it to the origin and immediately return a TTL Exceeded Message\n\tif icmp.TTL <= 1 {\n\t\tif err := c.SendICMPTTLExceed(icmp, rawPacket); err != nil {\n\t\t\tc.metrics.DroppedICMPPackets(c.index, DroppedWriteFailed)\n\t\t\tc.logger.Err(err).Msg(\"failed to return ICMP TTL exceed error\")\n\t\t}\n\t\treturn\n\t}\n\ticmp.TTL--\n\n\t// The context isn't really needed here since it's only really used throughout the ICMP router as a way to store\n\t// the tracing context, however datagram V3 does not support tracing ICMP packets, so we just pass the current\n\t// connection context which will have no tracing information available.\n\terr = c.icmpRouter.Request(c.conn.Context(), icmp, newPacketResponder(c, c.index))\n\tif err != nil {\n\t\tc.metrics.DroppedICMPPackets(c.index, DroppedWriteFailed)\n\t\tc.logger.Err(err).\n\t\t\tStr(logSrcKey, icmp.Src.String()).\n\t\t\tStr(logDstKey, icmp.Dst.String()).\n\t\t\tInterface(logICMPTypeKey, icmp.Type).\n\t\t\tMsgf(\"unable to write icmp datagram to origin\")\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "quic/v3/muxer_test.go",
    "content": "package v3_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/netip\"\n\t\"slices\"\n\t\"sort\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/fortytw2/leaktest\"\n\t\"github.com/google/gopacket/layers\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\t\"golang.org/x/net/icmp\"\n\t\"golang.org/x/net/ipv4\"\n\n\tcfdflow \"github.com/cloudflare/cloudflared/flow\"\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\t\"github.com/cloudflare/cloudflared/packet\"\n\tv3 \"github.com/cloudflare/cloudflared/quic/v3\"\n)\n\ntype noopEyeball struct {\n\tconnID uint8\n}\n\nfunc (noopEyeball) Serve(ctx context.Context) error              { return nil }\nfunc (n noopEyeball) ID() uint8                                  { return n.connID }\nfunc (noopEyeball) SendUDPSessionDatagram(datagram []byte) error { return nil }\nfunc (noopEyeball) SendUDPSessionResponse(id v3.RequestID, resp v3.SessionRegistrationResp) error {\n\treturn nil\n}\nfunc (noopEyeball) SendICMPPacket(icmp *packet.ICMP) error                                { return nil }\nfunc (noopEyeball) SendICMPTTLExceed(icmp *packet.ICMP, rawPacket packet.RawPacket) error { return nil }\n\ntype mockEyeball struct {\n\tconnID uint8\n\t// datagram sent via SendUDPSessionDatagram\n\trecvData chan []byte\n\t// responses sent via SendUDPSessionResponse\n\trecvResp chan struct {\n\t\tid   v3.RequestID\n\t\tresp v3.SessionRegistrationResp\n\t}\n}\n\nfunc newMockEyeball() mockEyeball {\n\treturn mockEyeball{\n\t\tconnID:   0,\n\t\trecvData: make(chan []byte, 1),\n\t\trecvResp: make(chan struct {\n\t\t\tid   v3.RequestID\n\t\t\tresp v3.SessionRegistrationResp\n\t\t}, 1),\n\t}\n}\n\nfunc (mockEyeball) Serve(ctx context.Context) error { return nil }\nfunc (m *mockEyeball) ID() uint8                    { return m.connID }\n\nfunc (m *mockEyeball) SendUDPSessionDatagram(datagram []byte) error {\n\tb := make([]byte, len(datagram))\n\tcopy(b, datagram)\n\tm.recvData <- b\n\treturn nil\n}\n\nfunc (m *mockEyeball) SendUDPSessionResponse(id v3.RequestID, resp v3.SessionRegistrationResp) error {\n\tm.recvResp <- struct {\n\t\tid   v3.RequestID\n\t\tresp v3.SessionRegistrationResp\n\t}{\n\t\tid, resp,\n\t}\n\treturn nil\n}\n\nfunc (m *mockEyeball) SendICMPPacket(icmp *packet.ICMP) error { return nil }\nfunc (m *mockEyeball) SendICMPTTLExceed(icmp *packet.ICMP, rawPacket packet.RawPacket) error {\n\treturn nil\n}\n\nfunc TestDatagramConn_New(t *testing.T) {\n\tlog := zerolog.Nop()\n\toriginDialerService := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 0,\n\t}, &log)\n\tconn := v3.NewDatagramConn(newMockQuicConn(t.Context()), v3.NewSessionManager(&noopMetrics{}, &log, originDialerService, cfdflow.NewLimiter(0)), &noopICMPRouter{}, 0, &noopMetrics{}, &log)\n\tif conn == nil {\n\t\tt.Fatal(\"expected valid connection\")\n\t}\n}\n\nfunc TestDatagramConn_SendUDPSessionDatagram(t *testing.T) {\n\tlog := zerolog.Nop()\n\toriginDialerService := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 0,\n\t}, &log)\n\tconnCtx, connCancel := context.WithCancelCause(t.Context())\n\tdefer connCancel(context.Canceled)\n\tquic := newMockQuicConn(connCtx)\n\tconn := v3.NewDatagramConn(quic, v3.NewSessionManager(&noopMetrics{}, &log, originDialerService, cfdflow.NewLimiter(0)), &noopICMPRouter{}, 0, &noopMetrics{}, &log)\n\n\tpayload := []byte{0xef, 0xef}\n\terr := conn.SendUDPSessionDatagram(payload)\n\trequire.NoError(t, err)\n\n\tp := <-quic.recv\n\tif !slices.Equal(p, payload) {\n\t\tt.Fatal(\"datagram sent does not match datagram received on quic side\")\n\t}\n}\n\nfunc TestDatagramConn_SendUDPSessionResponse(t *testing.T) {\n\tlog := zerolog.Nop()\n\toriginDialerService := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 0,\n\t}, &log)\n\tconnCtx, connCancel := context.WithCancelCause(t.Context())\n\tdefer connCancel(context.Canceled)\n\tquic := newMockQuicConn(connCtx)\n\tconn := v3.NewDatagramConn(quic, v3.NewSessionManager(&noopMetrics{}, &log, originDialerService, cfdflow.NewLimiter(0)), &noopICMPRouter{}, 0, &noopMetrics{}, &log)\n\n\terr := conn.SendUDPSessionResponse(testRequestID, v3.ResponseDestinationUnreachable)\n\trequire.NoError(t, err)\n\n\tresp := <-quic.recv\n\tvar response v3.UDPSessionRegistrationResponseDatagram\n\terr = response.UnmarshalBinary(resp)\n\trequire.NoError(t, err)\n\n\texpected := v3.UDPSessionRegistrationResponseDatagram{\n\t\tRequestID:    testRequestID,\n\t\tResponseType: v3.ResponseDestinationUnreachable,\n\t}\n\tif response != expected {\n\t\tt.Fatal(\"datagram response sent does not match expected datagram response received\")\n\t}\n}\n\nfunc TestDatagramConnServe_ApplicationClosed(t *testing.T) {\n\tlog := zerolog.Nop()\n\toriginDialerService := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 0,\n\t}, &log)\n\tconnCtx, connCancel := context.WithCancelCause(t.Context())\n\tdefer connCancel(context.Canceled)\n\tquic := newMockQuicConn(connCtx)\n\tconn := v3.NewDatagramConn(quic, v3.NewSessionManager(&noopMetrics{}, &log, originDialerService, cfdflow.NewLimiter(0)), &noopICMPRouter{}, 0, &noopMetrics{}, &log)\n\n\tctx, cancel := context.WithTimeout(t.Context(), 1*time.Second)\n\tdefer cancel()\n\terr := conn.Serve(ctx)\n\tif !errors.Is(err, context.DeadlineExceeded) {\n\t\tt.Fatal(err)\n\t}\n}\n\nfunc TestDatagramConnServe_ConnectionClosed(t *testing.T) {\n\tlog := zerolog.Nop()\n\toriginDialerService := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 0,\n\t}, &log)\n\tconnCtx, connCancel := context.WithCancelCause(t.Context())\n\tdefer connCancel(context.Canceled)\n\tquic := newMockQuicConn(connCtx)\n\tctx, cancel := context.WithTimeout(t.Context(), 1*time.Second)\n\tdefer cancel()\n\tquic.ctx = ctx\n\tconn := v3.NewDatagramConn(quic, v3.NewSessionManager(&noopMetrics{}, &log, originDialerService, cfdflow.NewLimiter(0)), &noopICMPRouter{}, 0, &noopMetrics{}, &log)\n\n\terr := conn.Serve(t.Context())\n\tif !errors.Is(err, context.DeadlineExceeded) {\n\t\tt.Fatal(err)\n\t}\n}\n\nfunc TestDatagramConnServe_ReceiveDatagramError(t *testing.T) {\n\tlog := zerolog.Nop()\n\toriginDialerService := ingress.NewOriginDialer(ingress.OriginConfig{\n\t\tDefaultDialer:   testDefaultDialer,\n\t\tTCPWriteTimeout: 0,\n\t}, &log)\n\tquic := &mockQuicConnReadError{err: net.ErrClosed}\n\tconn := v3.NewDatagramConn(quic, v3.NewSessionManager(&noopMetrics{}, &log, originDialerService, cfdflow.NewLimiter(0)), &noopICMPRouter{}, 0, &noopMetrics{}, &log)\n\n\terr := conn.Serve(t.Context())\n\tif !errors.Is(err, net.ErrClosed) {\n\t\tt.Fatal(err)\n\t}\n}\n\nfunc TestDatagramConnServe_SessionRegistrationRateLimit(t *testing.T) {\n\tlog := zerolog.Nop()\n\tconnCtx, connCancel := context.WithCancelCause(t.Context())\n\tdefer connCancel(context.Canceled)\n\tquic := newMockQuicConn(connCtx)\n\tsessionManager := &mockSessionManager{\n\t\texpectedRegErr: v3.ErrSessionRegistrationRateLimited,\n\t}\n\tconn := v3.NewDatagramConn(quic, sessionManager, &noopICMPRouter{}, 0, &noopMetrics{}, &log)\n\n\t// Setup the muxer\n\tctx, cancel := context.WithCancelCause(t.Context())\n\tdefer cancel(context.Canceled)\n\tdone := make(chan error, 1)\n\tgo func() {\n\t\tdone <- conn.Serve(ctx)\n\t}()\n\n\t// Send new session registration\n\tdatagram := newRegisterSessionDatagram(testRequestID)\n\tquic.send <- datagram\n\n\t// Wait for session registration response with failure\n\tdatagram = <-quic.recv\n\tvar resp v3.UDPSessionRegistrationResponseDatagram\n\terr := resp.UnmarshalBinary(datagram)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\trequire.EqualValues(t, testRequestID, resp.RequestID)\n\trequire.EqualValues(t, v3.ResponseTooManyActiveFlows, resp.ResponseType)\n\n\tassertContextClosed(t, ctx, done, cancel)\n}\n\nfunc TestDatagramConnServe_ErrorDatagramTypes(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tfor _, test := range []struct {\n\t\tname     string\n\t\tinput    []byte\n\t\texpected string\n\t}{\n\t\t{\n\t\t\t\"empty\",\n\t\t\t[]byte{},\n\t\t\t\"{\\\"level\\\":\\\"error\\\",\\\"datagramVersion\\\":3,\\\"error\\\":\\\"datagram should have at least 1 byte\\\",\\\"message\\\":\\\"unable to parse datagram type: 0\\\"}\\n\",\n\t\t},\n\t\t{\n\t\t\t\"unexpected\",\n\t\t\t[]byte{byte(v3.UDPSessionRegistrationResponseType)},\n\t\t\t\"{\\\"level\\\":\\\"error\\\",\\\"datagramVersion\\\":3,\\\"message\\\":\\\"unexpected datagram type received: 3\\\"}\\n\",\n\t\t},\n\t\t{\n\t\t\t\"unknown\",\n\t\t\t[]byte{99},\n\t\t\t\"{\\\"level\\\":\\\"error\\\",\\\"datagramVersion\\\":3,\\\"message\\\":\\\"unknown datagram type received: 99\\\"}\\n\",\n\t\t},\n\t} {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tlogOutput := new(LockedBuffer)\n\t\t\tlog := zerolog.New(logOutput)\n\t\t\tconnCtx, connCancel := context.WithCancelCause(t.Context())\n\t\t\tdefer connCancel(context.Canceled)\n\t\t\tquic := newMockQuicConn(connCtx)\n\t\t\tquic.send <- test.input\n\t\t\tconn := v3.NewDatagramConn(quic, &mockSessionManager{}, &noopICMPRouter{}, 0, &noopMetrics{}, &log)\n\n\t\t\tctx, cancel := context.WithTimeout(t.Context(), 1*time.Second)\n\t\t\tdefer cancel()\n\t\t\terr := conn.Serve(ctx)\n\t\t\t// we cancel the Serve method to check to see if the log output was written since the unsupported datagram\n\t\t\t// is dropped with only a log message as a side-effect.\n\t\t\tif !errors.Is(err, context.DeadlineExceeded) {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\n\t\t\tout := logOutput.String()\n\t\t\tif out != test.expected {\n\t\t\t\tt.Fatalf(\"incorrect log output expected: %s\", out)\n\t\t\t}\n\t\t})\n\t}\n}\n\ntype LockedBuffer struct {\n\tbytes.Buffer\n\tl sync.Mutex\n}\n\nfunc (b *LockedBuffer) Write(p []byte) (n int, err error) {\n\tb.l.Lock()\n\tdefer b.l.Unlock()\n\treturn b.Buffer.Write(p)\n}\n\nfunc (b *LockedBuffer) String() string {\n\tb.l.Lock()\n\tdefer b.l.Unlock()\n\treturn b.Buffer.String()\n}\n\nfunc TestDatagramConnServe_RegisterSession_SessionManagerError(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tlog := zerolog.Nop()\n\tconnCtx, connCancel := context.WithCancelCause(t.Context())\n\tdefer connCancel(context.Canceled)\n\tquic := newMockQuicConn(connCtx)\n\texpectedErr := errors.New(\"unable to register session\")\n\tsessionManager := mockSessionManager{expectedRegErr: expectedErr}\n\tconn := v3.NewDatagramConn(quic, &sessionManager, &noopICMPRouter{}, 0, &noopMetrics{}, &log)\n\n\t// Setup the muxer\n\tctx, cancel := context.WithCancelCause(t.Context())\n\tdefer cancel(errors.New(\"other error\"))\n\tdone := make(chan error, 1)\n\tgo func() {\n\t\tdone <- conn.Serve(ctx)\n\t}()\n\n\t// Send new session registration\n\tdatagram := newRegisterSessionDatagram(testRequestID)\n\tquic.send <- datagram\n\n\t// Wait for session registration response with failure\n\tdatagram = <-quic.recv\n\tvar resp v3.UDPSessionRegistrationResponseDatagram\n\terr := resp.UnmarshalBinary(datagram)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tif resp.RequestID != testRequestID || resp.ResponseType != v3.ResponseUnableToBindSocket {\n\t\tt.Fatalf(\"expected registration response failure\")\n\t}\n\n\t// Cancel the muxer Serve context and make sure it closes with the expected error\n\tassertContextClosed(t, ctx, done, cancel)\n}\n\nfunc TestDatagramConnServe(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tlog := zerolog.Nop()\n\tconnCtx, connCancel := context.WithCancelCause(t.Context())\n\tdefer connCancel(context.Canceled)\n\tquic := newMockQuicConn(connCtx)\n\tsession := newMockSession()\n\tsessionManager := mockSessionManager{session: &session}\n\tconn := v3.NewDatagramConn(quic, &sessionManager, &noopICMPRouter{}, 0, &noopMetrics{}, &log)\n\n\t// Setup the muxer\n\tctx, cancel := context.WithCancelCause(t.Context())\n\tdefer cancel(errors.New(\"other error\"))\n\tdone := make(chan error, 1)\n\tgo func() {\n\t\tdone <- conn.Serve(ctx)\n\t}()\n\n\t// Send new session registration\n\tdatagram := newRegisterSessionDatagram(testRequestID)\n\tquic.send <- datagram\n\n\t// Wait for session registration response with success\n\tdatagram = <-quic.recv\n\tvar resp v3.UDPSessionRegistrationResponseDatagram\n\terr := resp.UnmarshalBinary(datagram)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tif resp.RequestID != testRequestID || resp.ResponseType != v3.ResponseOk {\n\t\tt.Fatalf(\"expected registration response ok\")\n\t}\n\n\t// We expect the session to be served\n\ttimer := time.NewTimer(15 * time.Second)\n\tdefer timer.Stop()\n\tselect {\n\tcase <-session.served:\n\t\tbreak\n\tcase <-timer.C:\n\t\tt.Fatalf(\"expected session serve to be called\")\n\t}\n\n\t// Cancel the muxer Serve context and make sure it closes with the expected error\n\tassertContextClosed(t, ctx, done, cancel)\n}\n\n// This test exists because decoding multiple packets in parallel with the same decoder\n// instances causes inteference resulting in multiple different raw packets being decoded\n// as the same decoded packet.\nfunc TestDatagramConnServeDecodeMultipleICMPInParallel(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tlog := zerolog.Nop()\n\tconnCtx, connCancel := context.WithCancelCause(t.Context())\n\tdefer connCancel(context.Canceled)\n\tquic := newMockQuicConn(connCtx)\n\tsession := newMockSession()\n\tsessionManager := mockSessionManager{session: &session}\n\trouter := newMockICMPRouter()\n\tconn := v3.NewDatagramConn(quic, &sessionManager, router, 0, &noopMetrics{}, &log)\n\n\t// Setup the muxer\n\tctx, cancel := context.WithCancelCause(t.Context())\n\tdefer cancel(errors.New(\"other error\"))\n\tdone := make(chan error, 1)\n\tgo func() {\n\t\tdone <- conn.Serve(ctx)\n\t}()\n\n\tpacketCount := 100\n\tpackets := make([]*packet.ICMP, 100)\n\tipTemplate := \"10.0.0.%d\"\n\tfor i := 1; i <= packetCount; i++ {\n\t\tpackets[i-1] = &packet.ICMP{\n\t\t\tIP: &packet.IP{\n\t\t\t\tSrc:      netip.MustParseAddr(\"192.168.1.1\"),\n\t\t\t\tDst:      netip.MustParseAddr(fmt.Sprintf(ipTemplate, i)),\n\t\t\t\tProtocol: layers.IPProtocolICMPv4,\n\t\t\t\tTTL:      20,\n\t\t\t},\n\t\t\tMessage: &icmp.Message{\n\t\t\t\tType: ipv4.ICMPTypeEcho,\n\t\t\t\tCode: 0,\n\t\t\t\tBody: &icmp.Echo{\n\t\t\t\t\tID:   25821,\n\t\t\t\t\tSeq:  58129,\n\t\t\t\t\tData: []byte(\"test\"),\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t}\n\n\twg := sync.WaitGroup{}\n\tvar receivedPackets []*packet.ICMP\n\tgo func() {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn\n\t\t\tcase icmpPacket := <-router.recv:\n\t\t\t\treceivedPackets = append(receivedPackets, icmpPacket)\n\t\t\t\twg.Done()\n\t\t\t}\n\t\t}\n\t}()\n\n\tfor _, p := range packets {\n\t\t// We increment here but only decrement when receiving the packet\n\t\twg.Add(1)\n\t\tgo func() {\n\t\t\tdatagram := newICMPDatagram(p)\n\t\t\tquic.send <- datagram\n\t\t}()\n\t}\n\n\twg.Wait()\n\n\t// If there were duplicates then we won't have the same number of IPs\n\tpacketSet := make(map[netip.Addr]*packet.ICMP, 0)\n\tfor _, p := range receivedPackets {\n\t\tpacketSet[p.Dst] = p\n\t}\n\tassert.Equal(t, len(packetSet), len(packets))\n\n\t// Sort the slice by last byte of IP address (the one we increment for each destination)\n\t// and then check that we have one match for each packet sent\n\tsort.Slice(receivedPackets, func(i, j int) bool {\n\t\treturn receivedPackets[i].Dst.As4()[3] < receivedPackets[j].Dst.As4()[3]\n\t})\n\tfor i, p := range receivedPackets {\n\t\tassert.Equal(t, p.Dst, packets[i].Dst)\n\t}\n\n\t// Cancel the muxer Serve context and make sure it closes with the expected error\n\tassertContextClosed(t, ctx, done, cancel)\n}\n\nfunc TestDatagramConnServe_RegisterTwice(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tlog := zerolog.Nop()\n\tconnCtx, connCancel := context.WithCancelCause(t.Context())\n\tdefer connCancel(context.Canceled)\n\tquic := newMockQuicConn(connCtx)\n\tsession := newMockSession()\n\tsessionManager := mockSessionManager{session: &session}\n\tconn := v3.NewDatagramConn(quic, &sessionManager, &noopICMPRouter{}, 0, &noopMetrics{}, &log)\n\n\t// Setup the muxer\n\tctx, cancel := context.WithCancelCause(t.Context())\n\tdefer cancel(errors.New(\"other error\"))\n\tdone := make(chan error, 1)\n\tgo func() {\n\t\tdone <- conn.Serve(ctx)\n\t}()\n\n\t// Send new session registration\n\tdatagram := newRegisterSessionDatagram(testRequestID)\n\tquic.send <- datagram\n\n\t// Wait for session registration response with success\n\tdatagram = <-quic.recv\n\tvar resp v3.UDPSessionRegistrationResponseDatagram\n\terr := resp.UnmarshalBinary(datagram)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tif resp.RequestID != testRequestID || resp.ResponseType != v3.ResponseOk {\n\t\tt.Fatalf(\"expected registration response ok\")\n\t}\n\n\t// Set the session manager to return already registered\n\tsessionManager.expectedRegErr = v3.ErrSessionAlreadyRegistered\n\t// Send the registration again as if we didn't receive it at the edge\n\tdatagram = newRegisterSessionDatagram(testRequestID)\n\tquic.send <- datagram\n\n\t// Wait for session registration response with success\n\tdatagram = <-quic.recv\n\terr = resp.UnmarshalBinary(datagram)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tif resp.RequestID != testRequestID || resp.ResponseType != v3.ResponseOk {\n\t\tt.Fatalf(\"expected registration response ok\")\n\t}\n\n\t// We expect the session to be served\n\ttimer := time.NewTimer(15 * time.Second)\n\tdefer timer.Stop()\n\tselect {\n\tcase <-session.served:\n\t\tbreak\n\tcase <-timer.C:\n\t\tt.Fatalf(\"expected session serve to be called\")\n\t}\n\n\t// Cancel the muxer Serve context and make sure it closes with the expected error\n\tassertContextClosed(t, ctx, done, cancel)\n}\n\nfunc TestDatagramConnServe_MigrateConnection(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tlog := zerolog.Nop()\n\tconnCtx, connCancel := context.WithCancelCause(t.Context())\n\tdefer connCancel(context.Canceled)\n\tquic := newMockQuicConn(connCtx)\n\tsession := newMockSession()\n\tsessionManager := mockSessionManager{session: &session}\n\tconn := v3.NewDatagramConn(quic, &sessionManager, &noopICMPRouter{}, 0, &noopMetrics{}, &log)\n\tconn2Ctx, conn2Cancel := context.WithCancelCause(t.Context())\n\tdefer conn2Cancel(context.Canceled)\n\tquic2 := newMockQuicConn(conn2Ctx)\n\tconn2 := v3.NewDatagramConn(quic2, &sessionManager, &noopICMPRouter{}, 1, &noopMetrics{}, &log)\n\n\t// Setup the muxer\n\tctx, cancel := context.WithCancelCause(t.Context())\n\tdefer cancel(errors.New(\"other error\"))\n\tdone := make(chan error, 1)\n\tgo func() {\n\t\tdone <- conn.Serve(ctx)\n\t}()\n\n\tctx2, cancel2 := context.WithCancelCause(t.Context())\n\tdefer cancel2(errors.New(\"other error\"))\n\tdone2 := make(chan error, 1)\n\tgo func() {\n\t\tdone2 <- conn2.Serve(ctx2)\n\t}()\n\n\t// Send new session registration\n\tdatagram := newRegisterSessionDatagram(testRequestID)\n\tquic.send <- datagram\n\n\t// Wait for session registration response with success\n\tdatagram = <-quic.recv\n\tvar resp v3.UDPSessionRegistrationResponseDatagram\n\terr := resp.UnmarshalBinary(datagram)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tif resp.RequestID != testRequestID || resp.ResponseType != v3.ResponseOk {\n\t\tt.Fatalf(\"expected registration response ok\")\n\t}\n\n\t// Set the session manager to return already registered to another connection\n\tsessionManager.expectedRegErr = v3.ErrSessionBoundToOtherConn\n\t// Send the registration again as if we didn't receive it at the edge for a new connection\n\tdatagram = newRegisterSessionDatagram(testRequestID)\n\tquic2.send <- datagram\n\n\t// Wait for session registration response with success\n\tdatagram = <-quic2.recv\n\terr = resp.UnmarshalBinary(datagram)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tif resp.RequestID != testRequestID || resp.ResponseType != v3.ResponseOk {\n\t\tt.Fatalf(\"expected registration response ok\")\n\t}\n\n\t// We expect the session to be served\n\ttimer := time.NewTimer(15 * time.Second)\n\tdefer timer.Stop()\n\tselect {\n\tcase <-session.served:\n\t\tbreak\n\tcase <-timer.C:\n\t\tt.Fatalf(\"expected session serve to be called\")\n\t}\n\n\t// Expect session to be migrated\n\tselect {\n\tcase id := <-session.migrated:\n\t\tif id != conn2.ID() {\n\t\t\tt.Fatalf(\"expected session to be migrated to connection 2\")\n\t\t}\n\tcase <-timer.C:\n\t\tt.Fatalf(\"expected session migration to be called\")\n\t}\n\n\t// Cancel the muxer Serve context and make sure it closes with the expected error\n\tassertContextClosed(t, ctx, done, cancel)\n\t// Cancel the second muxer Serve context and make sure it closes with the expected error\n\tassertContextClosed(t, ctx2, done2, cancel2)\n}\n\nfunc TestDatagramConnServe_Payload_GetSessionError(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tlog := zerolog.Nop()\n\tconnCtx, connCancel := context.WithCancelCause(t.Context())\n\tdefer connCancel(context.Canceled)\n\tquic := newMockQuicConn(connCtx)\n\t// mockSessionManager will return the ErrSessionNotFound for any session attempting to be queried by the muxer\n\tsessionManager := mockSessionManager{session: nil, expectedGetErr: v3.ErrSessionNotFound}\n\tconn := v3.NewDatagramConn(quic, &sessionManager, &noopICMPRouter{}, 0, &noopMetrics{}, &log)\n\n\t// Setup the muxer\n\tctx, cancel := context.WithCancelCause(t.Context())\n\tdefer cancel(errors.New(\"other error\"))\n\tdone := make(chan error, 1)\n\tgo func() {\n\t\tdone <- conn.Serve(ctx)\n\t}()\n\n\t// Send new session registration\n\tdatagram := newSessionPayloadDatagram(testRequestID, []byte{0xef, 0xef})\n\tquic.send <- datagram\n\n\t// Since the muxer should eventually discard a failed registration request, there is no side-effect\n\t// that the registration was failed beyond the muxer accepting the registration request. As such, the\n\t// test can only ensure that the quic.send channel was consumed and that the muxer closes normally\n\t// afterwards with the expected context cancelled trigger.\n\n\t// Cancel the muxer Serve context and make sure it closes with the expected error\n\tassertContextClosed(t, ctx, done, cancel)\n}\n\nfunc TestDatagramConnServe_Payloads(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tlog := zerolog.Nop()\n\tconnCtx, connCancel := context.WithCancelCause(t.Context())\n\tdefer connCancel(context.Canceled)\n\tquic := newMockQuicConn(connCtx)\n\tsession := newMockSession()\n\tsessionManager := mockSessionManager{session: &session}\n\tconn := v3.NewDatagramConn(quic, &sessionManager, &noopICMPRouter{}, 0, &noopMetrics{}, &log)\n\n\t// Setup the muxer\n\tctx, cancel := context.WithCancelCause(t.Context())\n\tdefer cancel(errors.New(\"other error\"))\n\tdone := make(chan error, 1)\n\tgo func() {\n\t\tdone <- conn.Serve(ctx)\n\t}()\n\n\t// Send session payloads\n\texpectedPayloads := makePayloads(256, 16)\n\tgo func() {\n\t\tfor _, payload := range expectedPayloads {\n\t\t\tdatagram := newSessionPayloadDatagram(testRequestID, payload)\n\t\t\tquic.send <- datagram\n\t\t}\n\t}()\n\n\t// Session should receive the payloads (in-order)\n\tfor i, payload := range expectedPayloads {\n\t\tselect {\n\t\tcase recv := <-session.recv:\n\t\t\tif !slices.Equal(recv, payload) {\n\t\t\t\tt.Fatalf(\"expected session receieve the payload[%d] sent via the muxer: (%x) (%x)\", i, recv[:16], payload[:16])\n\t\t\t}\n\t\tcase err := <-ctx.Done():\n\t\t\t// we expect the payload to return before the context to cancel on the session\n\t\t\tt.Fatal(err)\n\t\t}\n\t}\n\n\t// Cancel the muxer Serve context and make sure it closes with the expected error\n\tassertContextClosed(t, ctx, done, cancel)\n}\n\nfunc TestDatagramConnServe_ICMPDatagram_TTLDecremented(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tlog := zerolog.Nop()\n\tconnCtx, connCancel := context.WithCancelCause(t.Context())\n\tdefer connCancel(context.Canceled)\n\tquic := newMockQuicConn(connCtx)\n\trouter := newMockICMPRouter()\n\tconn := v3.NewDatagramConn(quic, &mockSessionManager{}, router, 0, &noopMetrics{}, &log)\n\n\t// Setup the muxer\n\tctx, cancel := context.WithCancelCause(t.Context())\n\tdefer cancel(errors.New(\"other error\"))\n\tdone := make(chan error, 1)\n\tgo func() {\n\t\tdone <- conn.Serve(ctx)\n\t}()\n\n\t// Send new ICMP Echo request\n\texpectedICMP := &packet.ICMP{\n\t\tIP: &packet.IP{\n\t\t\tSrc:      netip.MustParseAddr(\"192.168.1.1\"),\n\t\t\tDst:      netip.MustParseAddr(\"10.0.0.1\"),\n\t\t\tProtocol: layers.IPProtocolICMPv4,\n\t\t\tTTL:      20,\n\t\t},\n\t\tMessage: &icmp.Message{\n\t\t\tType: ipv4.ICMPTypeEcho,\n\t\t\tCode: 0,\n\t\t\tBody: &icmp.Echo{\n\t\t\t\tID:   25821,\n\t\t\t\tSeq:  58129,\n\t\t\t\tData: []byte(\"test ttl=0\"),\n\t\t\t},\n\t\t},\n\t}\n\tdatagram := newICMPDatagram(expectedICMP)\n\tquic.send <- datagram\n\n\t// Router should receive the packet\n\tactualICMP := <-router.recv\n\tassertICMPEqual(t, expectedICMP, actualICMP)\n\tif expectedICMP.TTL-1 != actualICMP.TTL {\n\t\tt.Fatalf(\"TTL should be decremented by one before sending to origin: %d, %d\", expectedICMP.TTL, actualICMP.TTL)\n\t}\n\n\t// Cancel the muxer Serve context and make sure it closes with the expected error\n\tassertContextClosed(t, ctx, done, cancel)\n}\n\nfunc TestDatagramConnServe_ICMPDatagram_TTLExceeded(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tlog := zerolog.Nop()\n\tconnCtx, connCancel := context.WithCancelCause(t.Context())\n\tdefer connCancel(context.Canceled)\n\tquic := newMockQuicConn(connCtx)\n\trouter := newMockICMPRouter()\n\tconn := v3.NewDatagramConn(quic, &mockSessionManager{}, router, 0, &noopMetrics{}, &log)\n\n\t// Setup the muxer\n\tctx, cancel := context.WithCancelCause(t.Context())\n\tdefer cancel(errors.New(\"other error\"))\n\tdone := make(chan error, 1)\n\tgo func() {\n\t\tdone <- conn.Serve(ctx)\n\t}()\n\n\t// Send new ICMP Echo request\n\texpectedICMP := &packet.ICMP{\n\t\tIP: &packet.IP{\n\t\t\tSrc:      netip.MustParseAddr(\"192.168.1.1\"),\n\t\t\tDst:      netip.MustParseAddr(\"10.0.0.1\"),\n\t\t\tProtocol: layers.IPProtocolICMPv4,\n\t\t\tTTL:      0,\n\t\t},\n\t\tMessage: &icmp.Message{\n\t\t\tType: ipv4.ICMPTypeEcho,\n\t\t\tCode: 0,\n\t\t\tBody: &icmp.Echo{\n\t\t\t\tID:   25821,\n\t\t\t\tSeq:  58129,\n\t\t\t\tData: []byte(\"test ttl=0\"),\n\t\t\t},\n\t\t},\n\t}\n\tdatagram := newICMPDatagram(expectedICMP)\n\tquic.send <- datagram\n\n\t// Origin should not receive a packet\n\tselect {\n\tcase <-router.recv:\n\t\tt.Fatalf(\"TTL should be expired and no origin ICMP sent\")\n\tdefault:\n\t}\n\n\t// Eyeball should receive the packet\n\tdatagram = <-quic.recv\n\ticmpDatagram := v3.ICMPDatagram{}\n\terr := icmpDatagram.UnmarshalBinary(datagram)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdecoder := packet.NewICMPDecoder()\n\tttlExpiredICMP, err := decoder.Decode(packet.RawPacket{Data: icmpDatagram.Payload})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// Packet should be a TTL Exceeded ICMP\n\tif ttlExpiredICMP.TTL != packet.DefaultTTL || ttlExpiredICMP.Message.Type != ipv4.ICMPTypeTimeExceeded {\n\t\tt.Fatalf(\"ICMP packet should be a ICMP Exceeded: %+v\", ttlExpiredICMP)\n\t}\n\n\t// Cancel the muxer Serve context and make sure it closes with the expected error\n\tassertContextClosed(t, ctx, done, cancel)\n}\n\nfunc newRegisterSessionDatagram(id v3.RequestID) []byte {\n\tdatagram := v3.UDPSessionRegistrationDatagram{\n\t\tRequestID:        id,\n\t\tDest:             netip.MustParseAddrPort(\"127.0.0.1:8080\"),\n\t\tIdleDurationHint: 5 * time.Second,\n\t}\n\tpayload, err := datagram.MarshalBinary()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn payload\n}\n\nfunc newSessionPayloadDatagram(id v3.RequestID, payload []byte) []byte {\n\tdatagram := make([]byte, len(payload)+17)\n\terr := v3.MarshalPayloadHeaderTo(id, datagram[:])\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tcopy(datagram[17:], payload)\n\treturn datagram\n}\n\nfunc newICMPDatagram(pk *packet.ICMP) []byte {\n\tencoder := packet.NewEncoder()\n\trawPacket, err := encoder.Encode(pk)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdatagram := v3.ICMPDatagram{\n\t\tPayload: rawPacket.Data,\n\t}\n\tpayload, err := datagram.MarshalBinary()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn payload\n}\n\n// Cancel the provided context and make sure it closes with the expected cancellation error\nfunc assertContextClosed(t *testing.T, ctx context.Context, done <-chan error, cancel context.CancelCauseFunc) {\n\tcancel(errExpectedContextCanceled)\n\terr := <-done\n\tif !errors.Is(err, context.Canceled) {\n\t\tt.Fatal(err)\n\t}\n\tif !errors.Is(context.Cause(ctx), errExpectedContextCanceled) {\n\t\tt.Fatal(err)\n\t}\n}\n\ntype mockQuicConn struct {\n\tctx  context.Context\n\tsend chan []byte\n\trecv chan []byte\n}\n\nfunc newMockQuicConn(ctx context.Context) *mockQuicConn {\n\treturn &mockQuicConn{\n\t\tctx:  ctx,\n\t\tsend: make(chan []byte, 1),\n\t\trecv: make(chan []byte, 1),\n\t}\n}\n\nfunc (m *mockQuicConn) Context() context.Context {\n\treturn m.ctx\n}\n\nfunc (m *mockQuicConn) SendDatagram(payload []byte) error {\n\tb := make([]byte, len(payload))\n\tcopy(b, payload)\n\tm.recv <- b\n\treturn nil\n}\n\nfunc (m *mockQuicConn) ReceiveDatagram(_ context.Context) ([]byte, error) {\n\tselect {\n\tcase <-m.ctx.Done():\n\t\treturn nil, m.ctx.Err()\n\tcase b := <-m.send:\n\t\treturn b, nil\n\t}\n}\n\ntype mockQuicConnReadError struct {\n\terr error\n}\n\nfunc (m *mockQuicConnReadError) Context() context.Context {\n\treturn context.Background()\n}\n\nfunc (m *mockQuicConnReadError) SendDatagram(payload []byte) error {\n\treturn nil\n}\n\nfunc (m *mockQuicConnReadError) ReceiveDatagram(_ context.Context) ([]byte, error) {\n\treturn nil, m.err\n}\n\ntype mockSessionManager struct {\n\tsession v3.Session\n\n\texpectedRegErr error\n\texpectedGetErr error\n}\n\nfunc (m *mockSessionManager) RegisterSession(request *v3.UDPSessionRegistrationDatagram, conn v3.DatagramConn) (v3.Session, error) {\n\treturn m.session, m.expectedRegErr\n}\n\nfunc (m *mockSessionManager) GetSession(requestID v3.RequestID) (v3.Session, error) {\n\treturn m.session, m.expectedGetErr\n}\n\nfunc (m *mockSessionManager) UnregisterSession(requestID v3.RequestID) {}\n\ntype mockSession struct {\n\tserved   chan struct{}\n\tmigrated chan uint8\n\trecv     chan []byte\n}\n\nfunc newMockSession() mockSession {\n\treturn mockSession{\n\t\tserved:   make(chan struct{}),\n\t\tmigrated: make(chan uint8, 2),\n\t\trecv:     make(chan []byte, 1),\n\t}\n}\n\nfunc (m *mockSession) ID() v3.RequestID     { return testRequestID }\nfunc (m *mockSession) RemoteAddr() net.Addr { return testOriginAddr }\nfunc (m *mockSession) LocalAddr() net.Addr  { return testLocalAddr }\nfunc (m *mockSession) ConnectionID() uint8  { return 0 }\nfunc (m *mockSession) Migrate(conn v3.DatagramConn, ctx context.Context, log *zerolog.Logger) {\n\tm.migrated <- conn.ID()\n}\nfunc (m *mockSession) ResetIdleTimer() {}\n\nfunc (m *mockSession) Serve(ctx context.Context) error {\n\tclose(m.served)\n\treturn v3.SessionCloseErr\n}\n\nfunc (m *mockSession) Write(payload []byte) {\n\tb := make([]byte, len(payload))\n\tcopy(b, payload)\n\tm.recv <- b\n}\n\nfunc (m *mockSession) Close() error {\n\treturn nil\n}\n"
  },
  {
    "path": "quic/v3/request.go",
    "content": "package v3\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n)\n\nconst (\n\tdatagramRequestIdLen = 16\n)\n\nvar (\n\t// ErrInvalidRequestIDLen is returned when the provided request id can not be parsed from the provided byte slice.\n\tErrInvalidRequestIDLen error = errors.New(\"invalid request id length provided\")\n\t// ErrInvalidPayloadDestLen is returned when the provided destination byte slice cannot fit the whole request id.\n\tErrInvalidPayloadDestLen error = errors.New(\"invalid payload size provided\")\n)\n\n// RequestID is the request-id-v2 identifier, it is used to distinguish between specific flows or sessions proxied\n// from the edge to cloudflared.\ntype RequestID uint128\n\ntype uint128 struct {\n\thi uint64\n\tlo uint64\n}\n\n// RequestIDFromSlice reads a request ID from a byte slice.\nfunc RequestIDFromSlice(data []byte) (RequestID, error) {\n\tif len(data) != datagramRequestIdLen {\n\t\treturn RequestID{}, ErrInvalidRequestIDLen\n\t}\n\n\treturn RequestID{\n\t\thi: binary.BigEndian.Uint64(data[:8]),\n\t\tlo: binary.BigEndian.Uint64(data[8:]),\n\t}, nil\n}\n\nfunc (id RequestID) String() string {\n\treturn fmt.Sprintf(\"%016x%016x\", id.hi, id.lo)\n}\n\n// Compare returns an integer comparing two IPs.\n// The result will be 0 if id == id2, -1 if id < id2, and +1 if id > id2.\n// The definition of \"less than\" is the same as the [RequestID.Less] method.\nfunc (id RequestID) Compare(id2 RequestID) int {\n\thi1, hi2 := id.hi, id2.hi\n\tif hi1 < hi2 {\n\t\treturn -1\n\t}\n\tif hi1 > hi2 {\n\t\treturn 1\n\t}\n\tlo1, lo2 := id.lo, id2.lo\n\tif lo1 < lo2 {\n\t\treturn -1\n\t}\n\tif lo1 > lo2 {\n\t\treturn 1\n\t}\n\treturn 0\n}\n\n// Less reports whether id sorts before id2.\nfunc (id RequestID) Less(id2 RequestID) bool { return id.Compare(id2) == -1 }\n\n// MarshalBinaryTo writes the id to the provided destination byte slice; the byte slice must be of at least size 16.\nfunc (id RequestID) MarshalBinaryTo(data []byte) error {\n\tif len(data) < datagramRequestIdLen {\n\t\treturn ErrInvalidPayloadDestLen\n\t}\n\tbinary.BigEndian.PutUint64(data[:8], id.hi)\n\tbinary.BigEndian.PutUint64(data[8:], id.lo)\n\treturn nil\n}\n\nfunc (id *RequestID) UnmarshalBinary(data []byte) error {\n\tif len(data) != 16 {\n\t\treturn fmt.Errorf(\"invalid length slice provided to unmarshal: %d (expected 16)\", len(data))\n\t}\n\n\t*id = RequestID{\n\t\tbinary.BigEndian.Uint64(data[:8]),\n\t\tbinary.BigEndian.Uint64(data[8:]),\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "quic/v3/request_test.go",
    "content": "package v3_test\n\nimport (\n\t\"crypto/rand\"\n\t\"slices\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n\n\tv3 \"github.com/cloudflare/cloudflared/quic/v3\"\n)\n\nvar (\n\ttestRequestIDBytes = [16]byte{\n\t\t0x00, 0x11, 0x22, 0x33,\n\t\t0x44, 0x55, 0x66, 0x77,\n\t\t0x88, 0x99, 0xaa, 0xbb,\n\t\t0xcc, 0xdd, 0xee, 0xff,\n\t}\n\ttestRequestID = mustRequestID(testRequestIDBytes)\n)\n\nfunc mustRequestID(data [16]byte) v3.RequestID {\n\tid, err := v3.RequestIDFromSlice(data[:])\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn id\n}\n\nfunc TestRequestIDParsing(t *testing.T) {\n\tbuf1 := make([]byte, 16)\n\tn, err := rand.Read(buf1)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif n != 16 {\n\t\tt.Fatalf(\"did not read 16 bytes: %d\", n)\n\t}\n\tid, err := v3.RequestIDFromSlice(buf1)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tbuf2 := make([]byte, 16)\n\terr = id.MarshalBinaryTo(buf2)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif !slices.Equal(buf1, buf2) {\n\t\tt.Fatalf(\"buf1 != buf2: %+v %+v\", buf1, buf2)\n\t}\n}\n\nfunc TestRequestID_MarshalBinary(t *testing.T) {\n\tbuf := make([]byte, 16)\n\terr := testRequestID.MarshalBinaryTo(buf)\n\trequire.NoError(t, err)\n\trequire.Len(t, buf, 16)\n\n\tparsed := v3.RequestID{}\n\terr = parsed.UnmarshalBinary(buf)\n\trequire.NoError(t, err)\n\trequire.Equal(t, testRequestID, parsed)\n}\n"
  },
  {
    "path": "quic/v3/session.go",
    "content": "package v3\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/rs/zerolog\"\n)\n\nconst (\n\t// A default is provided in the case that the client does not provide a close idle timeout.\n\tdefaultCloseIdleAfter = 210 * time.Second\n\n\t// The maximum payload from the origin that we will be able to read. However, even though we will\n\t// read 1500 bytes from the origin, we limit the amount of bytes to be proxied to less than\n\t// this value (maxDatagramPayloadLen).\n\tmaxOriginUDPPacketSize = 1500\n\n\t// The maximum amount of datagrams a session will queue up before it begins dropping datagrams.\n\t// This channel buffer is small because we assume that the dedicated writer to the origin is typically\n\t// fast enought to keep the channel empty.\n\twriteChanCapacity = 512\n\n\tlogFlowID        = \"flowID\"\n\tlogPacketSizeKey = \"packetSize\"\n)\n\n// SessionCloseErr indicates that the session's Close method was called.\nvar SessionCloseErr error = errors.New(\"flow was closed directly\") //nolint:errname\n\n// SessionIdleErr is returned when the session was closed because there was no communication\n// in either direction over the session for the timeout period.\ntype SessionIdleErr struct { //nolint:errname\n\ttimeout time.Duration\n}\n\nfunc (e SessionIdleErr) Error() string {\n\treturn fmt.Sprintf(\"flow was idle for %v\", e.timeout)\n}\n\nfunc (e SessionIdleErr) Is(target error) bool {\n\t_, ok := target.(SessionIdleErr)\n\treturn ok\n}\n\nfunc newSessionIdleErr(timeout time.Duration) error {\n\treturn SessionIdleErr{timeout}\n}\n\ntype Session interface {\n\tio.Closer\n\tID() RequestID\n\tConnectionID() uint8\n\tRemoteAddr() net.Addr\n\tLocalAddr() net.Addr\n\tResetIdleTimer()\n\tMigrate(eyeball DatagramConn, ctx context.Context, logger *zerolog.Logger)\n\t// Serve starts the event loop for processing UDP packets\n\tServe(ctx context.Context) error\n\tWrite(payload []byte)\n}\n\ntype session struct {\n\tid             RequestID\n\tcloseAfterIdle time.Duration\n\torigin         io.ReadWriteCloser\n\toriginAddr     net.Addr\n\tlocalAddr      net.Addr\n\teyeball        atomic.Pointer[DatagramConn]\n\twriteChan      chan []byte\n\t// activeAtChan is used to communicate the last read/write time\n\tactiveAtChan chan time.Time\n\terrChan      chan error\n\t// The close channel signal only exists for the write loop because the read loop is always waiting on a read\n\t// from the UDP socket to the origin. To close the read loop we close the socket.\n\t// Additionally, we can't close the writeChan to indicate that writes are complete because the producer (edge)\n\t// side may still be trying to write to this session.\n\tcloseWrite  chan struct{}\n\tcontextChan chan context.Context\n\tmetrics     Metrics\n\tlog         *zerolog.Logger\n\n\t// A special close function that we wrap with sync.Once to make sure it is only called once\n\tcloseFn func() error\n}\n\nfunc NewSession(\n\tid RequestID,\n\tcloseAfterIdle time.Duration,\n\torigin io.ReadWriteCloser,\n\toriginAddr net.Addr,\n\tlocalAddr net.Addr,\n\teyeball DatagramConn,\n\tmetrics Metrics,\n\tlog *zerolog.Logger,\n) Session {\n\tlogger := log.With().Str(logFlowID, id.String()).Logger()\n\twriteChan := make(chan []byte, writeChanCapacity)\n\t// errChan has three slots to allow for all writers (the closeFn, the read loop and the write loop) to\n\t// write to the channel without blocking since there is only ever one value read from the errChan by the\n\t// waitForCloseCondition.\n\terrChan := make(chan error, 3)\n\tcloseWrite := make(chan struct{})\n\tsession := &session{\n\t\tid:             id,\n\t\tcloseAfterIdle: closeAfterIdle,\n\t\torigin:         origin,\n\t\toriginAddr:     originAddr,\n\t\tlocalAddr:      localAddr,\n\t\teyeball:        atomic.Pointer[DatagramConn]{},\n\t\twriteChan:      writeChan,\n\t\t// activeAtChan has low capacity. It can be full when there are many concurrent read/write. markActive() will\n\t\t// drop instead of blocking because last active time only needs to be an approximation\n\t\tactiveAtChan: make(chan time.Time, 1),\n\t\terrChan:      errChan,\n\t\tcloseWrite:   closeWrite,\n\t\t// contextChan is an unbounded channel to help enforce one active migration of a session at a time.\n\t\tcontextChan: make(chan context.Context),\n\t\tmetrics:     metrics,\n\t\tlog:         &logger,\n\t\tcloseFn: sync.OnceValue(func() error {\n\t\t\t// We don't want to block on sending to the close channel if it is already full\n\t\t\tselect {\n\t\t\tcase errChan <- SessionCloseErr:\n\t\t\tdefault:\n\t\t\t}\n\t\t\t// Indicate to the write loop that the session is now closed\n\t\t\tclose(closeWrite)\n\t\t\t// Close the socket directly to unblock the read loop and cause it to also end\n\t\t\treturn origin.Close()\n\t\t}),\n\t}\n\tsession.eyeball.Store(&eyeball)\n\treturn session\n}\n\nfunc (s *session) ID() RequestID {\n\treturn s.id\n}\n\nfunc (s *session) RemoteAddr() net.Addr {\n\treturn s.originAddr\n}\n\nfunc (s *session) LocalAddr() net.Addr {\n\treturn s.localAddr\n}\n\nfunc (s *session) ConnectionID() uint8 {\n\teyeball := *(s.eyeball.Load())\n\treturn eyeball.ID()\n}\n\nfunc (s *session) Migrate(eyeball DatagramConn, ctx context.Context, logger *zerolog.Logger) {\n\tcurrent := *(s.eyeball.Load())\n\t// Only migrate if the connection ids are different.\n\tif current.ID() != eyeball.ID() {\n\t\ts.eyeball.Store(&eyeball)\n\t\ts.contextChan <- ctx\n\t\tlog := logger.With().Str(logFlowID, s.id.String()).Logger()\n\t\ts.log = &log\n\t}\n\t// The session is already running so we want to restart the idle timeout since no proxied packets have come down yet.\n\ts.markActive()\n\tconnectionIndex := eyeball.ID()\n\ts.metrics.MigrateFlow(connectionIndex)\n}\n\nfunc (s *session) Serve(ctx context.Context) error {\n\tgo s.writeLoop()\n\tgo s.readLoop()\n\treturn s.waitForCloseCondition(ctx, s.closeAfterIdle)\n}\n\n// Read datagrams from the origin and write them to the connection.\nfunc (s *session) readLoop() {\n\t// QUIC implementation copies data to another buffer before returning https://github.com/quic-go/quic-go/blob/v0.24.0/session.go#L1967-L1975\n\t// This makes it safe to share readBuffer between iterations\n\treadBuffer := [maxOriginUDPPacketSize + DatagramPayloadHeaderLen]byte{}\n\t// To perform a zero copy write when passing the datagram to the connection, we prepare the buffer with\n\t// the required datagram header information. We can reuse this buffer for this session since the header is the\n\t// same for the each read.\n\t_ = MarshalPayloadHeaderTo(s.id, readBuffer[:DatagramPayloadHeaderLen])\n\tfor {\n\t\t// Read from the origin UDP socket\n\t\tn, err := s.origin.Read(readBuffer[DatagramPayloadHeaderLen:])\n\t\tif err != nil {\n\t\t\tif isConnectionClosed(err) {\n\t\t\t\ts.log.Debug().Msgf(\"flow (read) connection closed: %v\", err)\n\t\t\t}\n\t\t\ts.closeSession(err)\n\t\t\treturn\n\t\t}\n\t\tif n < 0 {\n\t\t\ts.metrics.DroppedUDPDatagram(s.ConnectionID(), DroppedReadFailed)\n\t\t\ts.log.Warn().Int(logPacketSizeKey, n).Msg(\"flow (origin) packet read was negative and was dropped\")\n\t\t\tcontinue\n\t\t}\n\t\tif n > maxDatagramPayloadLen {\n\t\t\ts.metrics.DroppedUDPDatagram(s.ConnectionID(), DroppedReadTooLarge)\n\t\t\ts.log.Error().Int(logPacketSizeKey, n).Msg(\"flow (origin) packet read was too large and was dropped\")\n\t\t\tcontinue\n\t\t}\n\t\t// We need to synchronize on the eyeball in-case that the connection was migrated. This should be rarely a point\n\t\t// of lock contention, as a migration can only happen during startup of a session before traffic flow.\n\t\teyeball := *(s.eyeball.Load())\n\t\t// Sending a packet to the session does block on the [quic.Connection], however, this is okay because it\n\t\t// will cause back-pressure to the kernel buffer if the writes are not fast enough to the edge.\n\t\terr = eyeball.SendUDPSessionDatagram(readBuffer[:DatagramPayloadHeaderLen+n])\n\t\tif err != nil {\n\t\t\ts.closeSession(err)\n\t\t\treturn\n\t\t}\n\t\t// Mark the session as active since we proxied a valid packet from the origin.\n\t\ts.markActive()\n\t}\n}\n\nfunc (s *session) Write(payload []byte) {\n\tselect {\n\tcase s.writeChan <- payload:\n\tdefault:\n\t\ts.metrics.DroppedUDPDatagram(s.ConnectionID(), DroppedWriteFull)\n\t\ts.log.Error().Msg(\"failed to write flow payload to origin: dropped\")\n\t}\n}\n\n// Read datagrams from the write channel to the origin.\nfunc (s *session) writeLoop() {\n\tfor {\n\t\tselect {\n\t\tcase <-s.closeWrite:\n\t\t\t// When the closeWrite channel is closed, we will no longer write to the origin and end this\n\t\t\t// goroutine since the session is now closed.\n\t\t\treturn\n\t\tcase payload := <-s.writeChan:\n\t\t\tn, err := s.origin.Write(payload)\n\t\t\tif err != nil {\n\t\t\t\t// Check if this is a write deadline exceeded to the connection\n\t\t\t\tif errors.Is(err, os.ErrDeadlineExceeded) {\n\t\t\t\t\ts.metrics.DroppedUDPDatagram(s.ConnectionID(), DroppedWriteDeadlineExceeded)\n\t\t\t\t\ts.log.Warn().Err(err).Msg(\"flow (write) deadline exceeded: dropping packet\")\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif isConnectionClosed(err) {\n\t\t\t\t\ts.log.Debug().Msgf(\"flow (write) connection closed: %v\", err)\n\t\t\t\t}\n\t\t\t\ts.log.Err(err).Msg(\"failed to write flow payload to origin\")\n\t\t\t\ts.closeSession(err)\n\t\t\t\t// If we fail to write to the origin socket, we need to end the writer and close the session\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// Write must return a non-nil error if it returns n < len(p). https://pkg.go.dev/io#Writer\n\t\t\tif n < len(payload) {\n\t\t\t\ts.metrics.DroppedUDPDatagram(s.ConnectionID(), DroppedWriteFailed)\n\t\t\t\ts.log.Err(io.ErrShortWrite).Msg(\"failed to write the full flow payload to origin\")\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Mark the session as active since we successfully proxied a packet to the origin.\n\t\t\ts.markActive()\n\t\t}\n\t}\n}\n\nfunc isConnectionClosed(err error) bool {\n\treturn errors.Is(err, net.ErrClosed) || errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF)\n}\n\n// Send an error to the error channel to report that an error has either happened on the tunnel or origin side of the\n// proxied connection.\nfunc (s *session) closeSession(err error) {\n\tselect {\n\tcase s.errChan <- err:\n\tdefault:\n\t\t// In the case that the errChan is already full, we will skip over it and return as to not block\n\t\t// the caller because we should start cleaning up the session.\n\t\ts.log.Warn().Msg(\"error channel was full\")\n\t}\n}\n\n// ResetIdleTimer will restart the current idle timer.\n//\n// This public method is used to allow operators of sessions the ability to extend the session using information that is\n// known external to the session itself.\nfunc (s *session) ResetIdleTimer() {\n\ts.markActive()\n}\n\n// Sends the last active time to the idle checker loop without blocking. activeAtChan will only be full when there\n// are many concurrent read/write. It is fine to lose some precision\nfunc (s *session) markActive() {\n\tselect {\n\tcase s.activeAtChan <- time.Now():\n\tdefault:\n\t}\n}\n\nfunc (s *session) Close() error {\n\t// Make sure that we only close the origin connection once\n\treturn s.closeFn()\n}\n\nfunc (s *session) waitForCloseCondition(ctx context.Context, closeAfterIdle time.Duration) error {\n\tconnCtx := ctx\n\t// Closing the session at the end cancels read so Serve() can return, additionally, it closes the\n\t// closeWrite channel which indicates to the write loop to return.\n\tdefer s.Close()\n\tif closeAfterIdle == 0 {\n\t\t// Provided that the default caller doesn't specify one\n\t\tcloseAfterIdle = defaultCloseIdleAfter\n\t}\n\n\tcheckIdleTimer := time.NewTimer(closeAfterIdle)\n\tdefer checkIdleTimer.Stop()\n\n\tfor {\n\t\tselect {\n\t\tcase <-connCtx.Done():\n\t\t\treturn connCtx.Err()\n\t\tcase newContext := <-s.contextChan:\n\t\t\t// During migration of a session, we need to make sure that the context of the new connection is used instead\n\t\t\t// of the old connection context. This will ensure that when the old connection goes away, this session will\n\t\t\t// still be active on the existing connection.\n\t\t\tconnCtx = newContext\n\t\t\tcontinue\n\t\tcase reason := <-s.errChan:\n\t\t\t// Any error returned here is from the read or write loops indicating that it can no longer process datagrams\n\t\t\t// and as such the session needs to close.\n\t\t\ts.metrics.FailedFlow(s.ConnectionID())\n\t\t\treturn reason\n\t\tcase <-checkIdleTimer.C:\n\t\t\t// The check idle timer will only return after an idle period since the last active\n\t\t\t// operation (read or write).\n\t\t\treturn newSessionIdleErr(closeAfterIdle)\n\t\tcase <-s.activeAtChan:\n\t\t\t// The session is still active, we want to reset the timer. First we have to stop the timer, drain the\n\t\t\t// current value and then reset. It's okay if we lose some time on this operation as we don't need to\n\t\t\t// close an idle session directly on-time.\n\t\t\tif !checkIdleTimer.Stop() {\n\t\t\t\t<-checkIdleTimer.C\n\t\t\t}\n\t\t\tcheckIdleTimer.Reset(closeAfterIdle)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "quic/v3/session_fuzz_test.go",
    "content": "package v3_test\n\nimport (\n\t\"testing\"\n)\n\n// FuzzSessionWrite verifies that we don't run into any panics when writing a single variable sized payload to the origin.\nfunc FuzzSessionWrite(f *testing.F) {\n\tf.Fuzz(func(t *testing.T, b []byte) {\n\t\t// The origin transport read is bound to 1280 bytes\n\t\tif len(b) > 1280 {\n\t\t\tb = b[:1280]\n\t\t}\n\t\ttestSessionWrite(t, [][]byte{b})\n\t})\n}\n\n// FuzzSessionRead verifies that we don't run into any panics when reading a single variable sized payload from the origin.\nfunc FuzzSessionRead(f *testing.F) {\n\tf.Fuzz(func(t *testing.T, b []byte) {\n\t\t// The origin transport read is bound to 1280 bytes\n\t\tif len(b) > 1280 {\n\t\t\tb = b[:1280]\n\t\t}\n\t\ttestSessionRead(t, [][]byte{b})\n\t})\n}\n"
  },
  {
    "path": "quic/v3/session_test.go",
    "content": "package v3_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n\t\"net/netip\"\n\t\"slices\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/fortytw2/leaktest\"\n\t\"github.com/rs/zerolog\"\n\n\tv3 \"github.com/cloudflare/cloudflared/quic/v3\"\n)\n\nvar (\n\terrExpectedContextCanceled = errors.New(\"expected context canceled\")\n\n\ttestOriginAddr = net.UDPAddrFromAddrPort(netip.MustParseAddrPort(\"127.0.0.1:0\"))\n\ttestLocalAddr  = net.UDPAddrFromAddrPort(netip.MustParseAddrPort(\"127.0.0.1:0\"))\n)\n\nfunc TestSessionNew(t *testing.T) {\n\tlog := zerolog.Nop()\n\tsession := v3.NewSession(testRequestID, 5*time.Second, nil, testOriginAddr, testLocalAddr, &noopEyeball{}, &noopMetrics{}, &log)\n\tif testRequestID != session.ID() {\n\t\tt.Fatalf(\"session id doesn't match: %s != %s\", testRequestID, session.ID())\n\t}\n}\n\nfunc testSessionWrite(t *testing.T, payloads [][]byte) {\n\tlog := zerolog.Nop()\n\torigin, server := net.Pipe()\n\tdefer origin.Close()\n\tdefer server.Close()\n\t// Start origin server reads\n\tserverRead := make(chan []byte, len(payloads))\n\tgo func() {\n\t\tfor range len(payloads) {\n\t\t\tbuf := make([]byte, 1500)\n\t\t\t_, _ = server.Read(buf[:])\n\t\t\tserverRead <- buf\n\t\t}\n\t\tclose(serverRead)\n\t}()\n\n\t// Create a session\n\tsession := v3.NewSession(testRequestID, 5*time.Second, origin, testOriginAddr, testLocalAddr, &noopEyeball{}, &noopMetrics{}, &log)\n\tdefer session.Close()\n\t// Start the Serve to begin the writeLoop\n\tctx, cancel := context.WithCancelCause(t.Context())\n\tdefer cancel(context.Canceled)\n\tdone := make(chan error)\n\tgo func() {\n\t\tdone <- session.Serve(ctx)\n\t}()\n\t// Write the payloads to the session\n\tfor _, payload := range payloads {\n\t\tsession.Write(payload)\n\t}\n\n\t// Read from the origin to ensure the payloads were received (in-order)\n\tfor i, payload := range payloads {\n\t\tread := <-serverRead\n\t\tif !slices.Equal(payload, read[:len(payload)]) {\n\t\t\tt.Fatalf(\"payload[%d] provided from origin and read value are not the same (%x) and (%x)\", i, payload[:16], read[:16])\n\t\t}\n\t}\n\t_, more := <-serverRead\n\tif more {\n\t\tt.Fatalf(\"expected the session to have all of the origin payloads received: %d\", len(serverRead))\n\t}\n\n\tassertContextClosed(t, ctx, done, cancel)\n}\n\nfunc TestSessionWrite(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tfor i := range 1280 {\n\t\tpayloads := makePayloads(i, 16)\n\t\ttestSessionWrite(t, payloads)\n\t}\n}\n\nfunc testSessionRead(t *testing.T, payloads [][]byte) {\n\tlog := zerolog.Nop()\n\torigin, server := net.Pipe()\n\tdefer origin.Close()\n\tdefer server.Close()\n\teyeball := newMockEyeball()\n\tsession := v3.NewSession(testRequestID, 3*time.Second, origin, testOriginAddr, testLocalAddr, &eyeball, &noopMetrics{}, &log)\n\tdefer session.Close()\n\n\tctx, cancel := context.WithCancelCause(t.Context())\n\tdefer cancel(context.Canceled)\n\tdone := make(chan error)\n\tgo func() {\n\t\tdone <- session.Serve(ctx)\n\t}()\n\n\t// Write from the origin server to the eyeball\n\tgo func() {\n\t\tfor _, payload := range payloads {\n\t\t\t_, _ = server.Write(payload)\n\t\t}\n\t}()\n\n\t// Read from the eyeball to ensure the payloads were received (in-order)\n\tfor i, payload := range payloads {\n\t\tselect {\n\t\tcase data := <-eyeball.recvData:\n\t\t\t// check received data matches provided from origin\n\t\t\texpectedData := makePayload(1500)\n\t\t\t_ = v3.MarshalPayloadHeaderTo(testRequestID, expectedData[:])\n\t\t\tcopy(expectedData[17:], payload)\n\t\t\tif !slices.Equal(expectedData[:v3.DatagramPayloadHeaderLen+len(payload)], data) {\n\t\t\t\tt.Fatalf(\"expected datagram[%d] did not equal expected\", i)\n\t\t\t}\n\t\tcase err := <-ctx.Done():\n\t\t\t// we expect the payload to return before the context to cancel on the session\n\t\t\tt.Fatal(err)\n\t\t}\n\t}\n\n\tassertContextClosed(t, ctx, done, cancel)\n}\n\nfunc TestSessionRead(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tfor i := range 1280 {\n\t\tpayloads := makePayloads(i, 16)\n\t\ttestSessionRead(t, payloads)\n\t}\n}\n\nfunc TestSessionRead_OriginTooLarge(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tlog := zerolog.Nop()\n\teyeball := newMockEyeball()\n\tpayload := makePayload(1281)\n\torigin, server := net.Pipe()\n\tdefer origin.Close()\n\tdefer server.Close()\n\tsession := v3.NewSession(testRequestID, 2*time.Second, origin, testOriginAddr, testLocalAddr, &eyeball, &noopMetrics{}, &log)\n\tdefer session.Close()\n\n\tdone := make(chan error)\n\tgo func() {\n\t\tdone <- session.Serve(t.Context())\n\t}()\n\n\t// Attempt to write a payload too large from the origin\n\t_, err := server.Write(payload)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tselect {\n\tcase data := <-eyeball.recvData:\n\t\t// we never expect a read to make it here because the origin provided a payload that is too large\n\t\t// for cloudflared to proxy and it will drop it.\n\t\tt.Fatalf(\"we should never proxy a payload of this size: %d\", len(data))\n\tcase err := <-done:\n\t\tif !errors.Is(err, v3.SessionIdleErr{}) {\n\t\t\tt.Error(err)\n\t\t}\n\t}\n}\n\nfunc TestSessionServe_Migrate(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tlog := zerolog.Nop()\n\teyeball := newMockEyeball()\n\tpipe1, pipe2 := net.Pipe()\n\tsession := v3.NewSession(testRequestID, 2*time.Second, pipe2, testOriginAddr, testLocalAddr, &eyeball, &noopMetrics{}, &log)\n\tdefer session.Close()\n\n\tdone := make(chan error)\n\teyeball1Ctx, cancel := context.WithCancelCause(t.Context())\n\tgo func() {\n\t\tdone <- session.Serve(eyeball1Ctx)\n\t}()\n\n\t// Migrate the session to a new connection before origin sends data\n\teyeball2 := newMockEyeball()\n\teyeball2.connID = 1\n\teyeball2Ctx := t.Context()\n\tsession.Migrate(&eyeball2, eyeball2Ctx, &log)\n\n\t// Cancel the origin eyeball context; this should not cancel the session\n\tcontextCancelErr := errors.New(\"context canceled for first eyeball connection\")\n\tcancel(contextCancelErr)\n\tselect {\n\tcase <-done:\n\t\tt.Fatalf(\"expected session to still be running\")\n\tdefault:\n\t}\n\tif context.Cause(eyeball1Ctx) != contextCancelErr {\n\t\tt.Fatalf(\"first eyeball context should be cancelled manually: %+v\", context.Cause(eyeball1Ctx))\n\t}\n\n\t// Origin sends data\n\tpayload2 := []byte{0xde}\n\t_, _ = pipe1.Write(payload2)\n\n\t// Expect write to eyeball2\n\tdata := <-eyeball2.recvData\n\tif len(data) <= 17 || !slices.Equal(payload2, data[17:]) {\n\t\tt.Fatalf(\"expected data to write to eyeball2 after migration: %+v\", data)\n\t}\n\n\tselect {\n\tcase data := <-eyeball.recvData:\n\t\tt.Fatalf(\"expected no data to write to eyeball1 after migration: %+v\", data)\n\tdefault:\n\t}\n\n\terr := <-done\n\tif !errors.Is(err, v3.SessionIdleErr{}) {\n\t\tt.Error(err)\n\t}\n\tif eyeball2Ctx.Err() != nil {\n\t\tt.Fatalf(\"second eyeball context should be not be cancelled\")\n\t}\n}\n\nfunc TestSessionServe_Migrate_CloseContext2(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tlog := zerolog.Nop()\n\teyeball := newMockEyeball()\n\tpipe1, pipe2 := net.Pipe()\n\tsession := v3.NewSession(testRequestID, 2*time.Second, pipe2, testOriginAddr, testLocalAddr, &eyeball, &noopMetrics{}, &log)\n\tdefer session.Close()\n\n\tdone := make(chan error)\n\teyeball1Ctx, cancel := context.WithCancelCause(t.Context())\n\tgo func() {\n\t\tdone <- session.Serve(eyeball1Ctx)\n\t}()\n\n\t// Migrate the session to a new connection before origin sends data\n\teyeball2 := newMockEyeball()\n\teyeball2.connID = 1\n\teyeball2Ctx, cancel2 := context.WithCancelCause(t.Context())\n\tsession.Migrate(&eyeball2, eyeball2Ctx, &log)\n\n\t// Cancel the origin eyeball context; this should not cancel the session\n\tcontextCancelErr := errors.New(\"context canceled for first eyeball connection\")\n\tcancel(contextCancelErr)\n\tselect {\n\tcase <-done:\n\t\tt.Fatalf(\"expected session to still be running\")\n\tdefault:\n\t}\n\tif !errors.Is(context.Cause(eyeball1Ctx), contextCancelErr) {\n\t\tt.Fatalf(\"first eyeball context should be cancelled manually: %+v\", context.Cause(eyeball1Ctx))\n\t}\n\n\t// Origin sends data\n\tpayload2 := []byte{0xde}\n\t_, _ = pipe1.Write(payload2)\n\n\t// Expect write to eyeball2\n\tdata := <-eyeball2.recvData\n\tif len(data) <= 17 || !slices.Equal(payload2, data[17:]) {\n\t\tt.Fatalf(\"expected data to write to eyeball2 after migration: %+v\", data)\n\t}\n\n\tselect {\n\tcase data := <-eyeball.recvData:\n\t\tt.Fatalf(\"expected no data to write to eyeball1 after migration: %+v\", data)\n\tdefault:\n\t}\n\n\t// Close the connection2 context manually\n\tcontextCancel2Err := errors.New(\"context canceled for second eyeball connection\")\n\tcancel2(contextCancel2Err)\n\terr := <-done\n\tif err != context.Canceled {\n\t\tt.Fatalf(\"session Serve should be done: %+v\", err)\n\t}\n\tif context.Cause(eyeball2Ctx) != contextCancel2Err {\n\t\tt.Fatalf(\"second eyeball context should have been cancelled manually: %+v\", context.Cause(eyeball2Ctx))\n\t}\n}\n\nfunc TestSessionClose_Multiple(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tlog := zerolog.Nop()\n\torigin, server := net.Pipe()\n\tdefer origin.Close()\n\tdefer server.Close()\n\tsession := v3.NewSession(testRequestID, 5*time.Second, origin, testOriginAddr, testLocalAddr, &noopEyeball{}, &noopMetrics{}, &log)\n\terr := session.Close()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tb := [1500]byte{}\n\t_, err = server.Read(b[:])\n\tif !errors.Is(err, io.EOF) {\n\t\tt.Fatalf(\"origin server connection should be closed: %s\", err)\n\t}\n\t// subsequent closes shouldn't call close again or cause any errors\n\terr = session.Close()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\t_, err = server.Read(b[:])\n\tif !errors.Is(err, io.EOF) {\n\t\tt.Fatalf(\"origin server connection should still be closed: %s\", err)\n\t}\n}\n\nfunc TestSessionServe_IdleTimeout(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tlog := zerolog.Nop()\n\torigin, server := net.Pipe()\n\tdefer origin.Close()\n\tdefer server.Close()\n\tcloseAfterIdle := 2 * time.Second\n\tsession := v3.NewSession(testRequestID, closeAfterIdle, origin, testOriginAddr, testLocalAddr, &noopEyeball{}, &noopMetrics{}, &log)\n\terr := session.Serve(t.Context())\n\n\t// Session should idle timeout if no reads or writes occur\n\tif !errors.Is(err, v3.SessionIdleErr{}) {\n\t\tt.Fatal(err)\n\t}\n\t// session should be closed\n\tb := [1500]byte{}\n\t_, err = server.Read(b[:])\n\tif !errors.Is(err, io.EOF) {\n\t\tt.Fatalf(\"session should be closed after Serve returns\")\n\t}\n\t// closing a session again should not return an error\n\terr = session.Close()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n}\n\nfunc TestSessionServe_ParentContextCanceled(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tlog := zerolog.Nop()\n\torigin, server := net.Pipe()\n\tdefer origin.Close()\n\tdefer server.Close()\n\tcloseAfterIdle := 10 * time.Second\n\n\tsession := v3.NewSession(testRequestID, closeAfterIdle, origin, testOriginAddr, testLocalAddr, &noopEyeball{}, &noopMetrics{}, &log)\n\tctx, cancel := context.WithTimeout(t.Context(), 2*time.Second)\n\tdefer cancel()\n\terr := session.Serve(ctx)\n\tif !errors.Is(err, context.DeadlineExceeded) {\n\t\tt.Fatal(err)\n\t}\n\t// session should be closed\n\tb := [1500]byte{}\n\t_, err = server.Read(b[:])\n\tif !errors.Is(err, io.EOF) {\n\t\tt.Fatalf(\"session should be closed after Serve returns\")\n\t}\n\t// closing a session again should not return an error\n\terr = session.Close()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n}\n\nfunc TestSessionServe_ReadErrors(t *testing.T) {\n\tdefer leaktest.Check(t)()\n\tlog := zerolog.Nop()\n\torigin := newTestErrOrigin(net.ErrClosed, nil)\n\tsession := v3.NewSession(testRequestID, 30*time.Second, &origin, testOriginAddr, testLocalAddr, &noopEyeball{}, &noopMetrics{}, &log)\n\terr := session.Serve(t.Context())\n\tif !errors.Is(err, net.ErrClosed) {\n\t\tt.Fatal(err)\n\t}\n}\n\ntype testErrOrigin struct {\n\treadErr  error\n\twriteErr error\n}\n\nfunc newTestErrOrigin(readErr error, writeErr error) testErrOrigin {\n\treturn testErrOrigin{readErr, writeErr}\n}\n\nfunc (o *testErrOrigin) Read(p []byte) (n int, err error) {\n\treturn 0, o.readErr\n}\n\nfunc (o *testErrOrigin) Write(p []byte) (n int, err error) {\n\treturn len(p), o.writeErr\n}\n\nfunc (o *testErrOrigin) Close() error {\n\treturn nil\n}\n"
  },
  {
    "path": "release/index.html",
    "content": "<!-- TODO(TUN-9963): Create pipeline to push this file to repo automatically -->\n\n<html>\n<body>\n<h1>Cloudflare packages</h1>\n<ul>\n    <li><a href=\"#cloudflared-packages\">Cloudflared packages</a></li>\n    <li><a href=\"#gokeyless-packages\">Gokeyless Packages</a></li>\n</ul>\n\n<br>\n<h2><a name=\"cloudflared-packages\">Cloudflared</a></h2>\n\n<ul>\n    <li><a href=\"#debian-any\">Any Debian Based Distribution (Recommended)</a></li>\n    <li><a href=\"#debian-bookworm\">Debian Bookworm</a></li>\n    <li><a href=\"#ubuntu-focal\">Ubuntu 20.04 (Focal Fossa)</a></li>\n    <li><a href=\"#ubuntu-jammy\">Ubuntu 22.04 (Jammy Jellyfish)</a></li>\n    <li><a href=\"#ubuntu-noble\">Ubuntu 24.04 (Noble Numbat)</a></li>\n    <li><a href=\"#Amazon-Linux\">Amazon Linux</a></li>\n    <li><a href=\"#RHEL-generic\">RHEL Generic</a></li>\n    <li><a href=\"#centos-7\">Centos 7</a></li>\n    <li><a href=\"#centos-8\">Centos 8</a></li>\n    <li><a href=\"#centos-stream\">Centos Stream</a></li>\n</ul>\n\n<h3 style=\"color: #d9534f;\">Warning: Public Key Rollover (30 October 2025)</h3>\n<p style=\"background-color: #fff3cd; border-left: 4px solid #ffc107; padding: 10px; margin: 10px 0;\">\n    <strong>We have rolled our public key for package signing.</strong> If you are using RPM-based distributions (RHEL,\n    CentOS, Amazon Linux, etc.) or Debian Trixie and have the old key installed, RPM/Deb packages will no longer work with the old key.\n    Please update your repository configuration using the instructions below to ensure you can continue receiving\n    package updates. The previous keys will still work for other distributions for the time being, but it is now DEPRECATED and will be removed on 30 April 2026\n</p>\n\n<h3><a name=\"debian-any\">Any Debian Based Distribution (Recommended)</a></h3>\n<pre>\n# Add cloudflare gpg key\nsudo mkdir -p --mode=0755 /usr/share/keyrings\ncurl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null\n\n# Add this repo to your apt repositories\n# Stable\necho 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main' | sudo tee /etc/apt/sources.list.d/cloudflared.list\n# Nightly\necho 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://next.pkg.cloudflare.com/cloudflared any main' | sudo tee /etc/apt/sources.list.d/cloudflared.list\n\n# install cloudflared\nsudo apt-get update && sudo apt-get install cloudflared\n</pre>\n\n<h3><a name=\"debian-bookworm\">Debian Bookworm</a></h3>\n<pre>\n# Add cloudflare gpg key\nsudo mkdir -p --mode=0755 /usr/share/keyrings\ncurl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null\n\n# Add this repo to your apt repositories\n# Stable\necho 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared bookworm main' | sudo tee /etc/apt/sources.list.d/cloudflared.list\n# Nightly\necho 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://next.pkg.cloudflare.com/cloudflared bookworm main' | sudo tee /etc/apt/sources.list.d/cloudflared.list\n\n# install cloudflared\nsudo apt-get update && sudo apt-get install cloudflared\n</pre>\n\n<h3><a name=\"ubuntu-focal\">Ubuntu 20.04 (Focal Fossa)</a></h3>\n<pre>\n# Add cloudflare gpg key\nsudo mkdir -p --mode=0755 /usr/share/keyrings\ncurl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null\n\n# Add this repo to your apt repositories\n# Stable\necho 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared focal main' | sudo tee /etc/apt/sources.list.d/cloudflared.list\n# Nightly\necho 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://next.pkg.cloudflare.com/cloudflared focal main' | sudo tee /etc/apt/sources.list.d/cloudflared.list\n\n# install cloudflared\nsudo apt-get update && sudo apt-get install cloudflared\n</pre>\n\n<h3><a name=\"ubuntu-jammy\">Ubuntu 22.04 (Jammy Jellyfish)</a></h3>\n<pre>\n# Add cloudflare gpg key\nsudo mkdir -p --mode=0755 /usr/share/keyrings\ncurl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null\n\n# Add this repo to your apt repositories\n# Stable\necho 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared jammy main' | sudo tee /etc/apt/sources.list.d/cloudflared.list\n# Nightly\necho 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://next.pkg.cloudflare.com/cloudflared jammy main' | sudo tee /etc/apt/sources.list.d/cloudflared.list\n\n# install cloudflared\nsudo apt-get update && sudo apt-get install cloudflared\n</pre>\n\n<h3><a name=\"ubuntu-noble\">Ubuntu 24.04 (Noble Numbat)</a></h3>\n<pre>\n# Add cloudflare gpg key\nsudo mkdir -p --mode=0755 /usr/share/keyrings\ncurl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null\n\n# Add this repo to your apt repositories\n# Stable\necho 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared noble main' | sudo tee /etc/apt/sources.list.d/cloudflared.list\n# Nightly\necho 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://next.pkg.cloudflare.com/cloudflared noble main' | sudo tee /etc/apt/sources.list.d/cloudflared.list\n\n# install cloudflared\nsudo apt-get update && sudo apt-get install cloudflared\n</pre>\n\n<h3><a name=\"Amazon-Linux\">Amazon Linux</a></h3>\n<pre>\n# Add cloudflared.repo to /etc/yum.repos.d/\n# Stable\ncurl -fsSl https://pkg.cloudflare.com/cloudflared.repo | sudo tee /etc/yum.repos.d/cloudflared.repo\n# Nightly\ncurl -fsSl https://next.pkg.cloudflare.com/cloudflared.repo | sudo tee /etc/yum.repos.d/cloudflared.repo\n\n#update repo\nsudo yum update\n\n# install cloudflared\nsudo yum install cloudflared\n</pre>\n\n\n<h3><a name=\"RHEL-generic\">RHEL Generic</a></h3>\n<pre>\n# Add cloudflared.repo to /etc/yum.repos.d/\n# Stable\ncurl -fsSl https://pkg.cloudflare.com/cloudflared.repo | sudo tee /etc/yum.repos.d/cloudflared.repo\n# Nightly\ncurl -fsSl https://next.pkg.cloudflare.com/cloudflared.repo | sudo tee /etc/yum.repos.d/cloudflared.repo\n\n#update repo\nsudo yum update\n\n# install cloudflared\nsudo yum install cloudflared\n</pre>\n\n\n<h3><a name=\"centos-7\">Centos 7</a></h3>\n<pre>\n# This requires yum config-manager\nsudo yum install yum-utils\n\n# Add cloudflared.repo to config-manager\n# Stable\nsudo yum-config-manager --add-repo https://pkg.cloudflare.com/cloudflared.repo\n# Nightly\nsudo yum-config-manager --add-repo https://next.pkg.cloudflare.com/cloudflared.repo\n\n# install cloudflared\nyum install cloudflared\n</pre>\n\n<h3><a name=\"centos-8\">Centos 8</a></h3>\n<pre>\n# This requires dnf config-manager\n# Add cloudflared.repo to config-manager\n# Stable\nsudo dnf config-manager --add-repo https://pkg.cloudflare.com/cloudflared.repo\n# Nightly\nsudo dnf config-manager --add-repo https://next.pkg.cloudflare.com/cloudflared.repo\n\n# install cloudflared\nsudo dnf install cloudflared\n</pre>\n\n<h3><a name=\"centos-stream\">Centos Stream</a></h3>\n<pre>\n# This requires dnf config-manager\n# Add cloudflared.repo to config-manager\n# Stable\nsudo dnf config-manager --add-repo https://pkg.cloudflare.com/cloudflared.repo\n# Nightly\nsudo dnf config-manager --add-repo https://next.pkg.cloudflare.com/cloudflared.repo\n\n# install cloudflared\nsudo dnf install cloudflared\n</pre>\n\n\n<h2><a name=\"gokeyless-packages\"></a>Gokeyless</a></h2>\n<h3><a name=\"go-keyless-debian\">Debian</a></h3>\n<pre>\nsudo mkdir -p --mode=0755 /usr/share/keyrings\ncurl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null\n\n# Add this repo to your apt repositories\necho 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/gokeyless buster main' | sudo tee /etc/apt/sources.list.d/cloudflare.list\n\n# install gokeyless\nsudo apt-get update && sudo apt-get install gokeyless\n</pre>\n\n<h3><a name=\"go-keyless-centos\">Centos 8</a></h3>\n<pre>\n# This requires dnf config-manager\n# Add gokeyless.repo to config-manager\nsudo dnf config-manager --add-repo https://pkg.cloudflare.com/gokeyless.repo\n\n# install gokeyless\nsudo dnf install gokeyless\n</pre>\n</body>\n</html>\n"
  },
  {
    "path": "release_pkgs.py",
    "content": "\"\"\"\n    This is a utility for creating deb and rpm packages, signing them \n    and uploading them to a storage and adding metadata to workers KV.\n\n    It has two over-arching responsiblities:\n    1. Create deb and yum repositories from .deb and .rpm files. \n       This is also responsible for signing the packages and generally preparing \n       them to be in an uploadable state.\n    2. Upload these packages to a storage in a format that apt and yum expect.\n\"\"\"\nimport argparse\nimport base64\nimport logging\nimport os\nimport shutil\nfrom pathlib import Path\nfrom subprocess import Popen, PIPE\n\nimport boto3\nimport gnupg\nfrom botocore.client import Config\nfrom botocore.exceptions import ClientError\n\n# The front facing R2 URL to access assets from.\nR2_ASSET_URL = 'https://demo-r2-worker.cloudflare-tunnel.workers.dev/'\n\n\nclass PkgUploader:\n    def __init__(self, account_id, bucket_name, client_id, client_secret):\n        self.account_id = account_id\n        self.bucket_name = bucket_name\n        self.client_id = client_id\n        self.client_secret = client_secret\n\n    def upload_pkg_to_r2(self, filename, upload_file_path):\n        endpoint_url = f\"https://{self.account_id}.r2.cloudflarestorage.com\"\n\n        config = Config(\n            region_name='auto',\n            s3={\n                \"addressing_style\": \"path\",\n            }\n        )\n\n        r2 = boto3.client(\n            \"s3\",\n            endpoint_url=endpoint_url,\n            aws_access_key_id=self.client_id,\n            aws_secret_access_key=self.client_secret,\n            config=config,\n        )\n\n        print(f\"uploading asset: {filename} to {upload_file_path} in bucket {self.bucket_name}...\")\n        try:\n            r2.upload_file(filename, self.bucket_name, upload_file_path)\n        except ClientError as e:\n            raise e\n\n\nclass PkgCreator:\n    \"\"\"\n        The distribution conf is what dictates to reprepro, the debian packaging building\n        and signing tool we use, what distros to support, what GPG key to use for signing\n        and what to call the debian binary etc. This function creates it \"./conf/distributions\".\n\n        origin - name of your package (String)\n        label - label of your package (could be same as the name) (String)\n        release - release you want this to be distributed for (List of Strings)\n        components - could be a channel like main/stable/beta\n        archs - Architecture (List of Strings)\n        description - (String)\n        gpg_key_id - gpg key id of what you want to use to sign the packages.(String) \n    \"\"\"\n\n    def create_distribution_conf(self,\n                                 file_path,\n                                 origin,\n                                 label,\n                                 releases,\n                                 archs,\n                                 components,\n                                 description,\n                                 gpg_key_id):\n        with open(file_path, \"w+\") as distributions_file:\n            for release in releases:\n                distributions_file.write(f\"Origin: {origin}\\n\")\n                distributions_file.write(f\"Label: {label}\\n\")\n                distributions_file.write(f\"Codename: {release}\\n\")\n                archs_list = \" \".join(archs)\n                distributions_file.write(f\"Architectures: {archs_list}\\n\")\n                distributions_file.write(f\"Components: {components}\\n\")\n                distributions_file.write(f\"Description: {description} - {release}\\n\")\n                distributions_file.write(f\"SignWith: {gpg_key_id}\\n\")\n                distributions_file.write(\"\\n\")\n        return distributions_file\n\n    \"\"\"\n        Uses the reprepro tool to generate packages, sign them and create the InRelease as specified\n        by the distribution_conf file. \n\n        This function creates three folders db, pool and dist. \n        db and pool contain information and metadata about builds. We can ignore these.\n        dist: contains all the pkgs and signed releases that are necessary for an apt download.\n    \"\"\"\n\n    def create_deb_pkgs(self, release, deb_file):\n        print(f\"creating deb pkgs: {release} : {deb_file}\")\n        p = Popen([\"reprepro\", \"includedeb\", release, deb_file], stdout=PIPE, stderr=PIPE)\n        out, err = p.communicate()\n        if p.returncode != 0:\n            print(f\"create deb_pkgs result => {out}, {err}\")\n            raise\n\n    def create_rpm_pkgs(self, artifacts_path, gpg_key_name):\n        self._setup_rpm_pkg_directories(artifacts_path, gpg_key_name)\n        p = Popen([\"createrepo_c\", \"./rpm\"], stdout=PIPE, stderr=PIPE)\n        out, err = p.communicate()\n        if p.returncode != 0:\n            print(f\"create rpm_pkgs result => {out}, {err}\")\n            raise\n\n        self._sign_repomd()\n\n    \"\"\"\n        creates a <binary>.repo file with details like so\n        [cloudflared-stable]\n        name=cloudflared-stable\n        baseurl=https://pkg.cloudflare.com/cloudflared/rpm\n        enabled=1\n        type=rpm\n        gpgcheck=1\n        gpgkey=https://pkg.cloudflare.com/cloudflare-main.gpg\n    \"\"\"\n\n    def create_repo_file(self, file_path, binary_name, baseurl, gpgkey_url):\n        repo_file_path = os.path.join(file_path, binary_name + '.repo')\n        with open(repo_file_path, \"w+\") as repo_file:\n            repo_file.write(f\"[{binary_name}-stable]\\n\")\n            repo_file.write(f\"name={binary_name}-stable\\n\")\n            repo_file.write(f\"baseurl={baseurl}/rpm\\n\")\n            repo_file.write(\"enabled=1\\n\")\n            repo_file.write(\"type=rpm\\n\")\n            repo_file.write(\"gpgcheck=1\\n\")\n            repo_file.write(f\"gpgkey={gpgkey_url}\\n\")\n        return repo_file_path\n\n\n    def _sign_rpms(self, file_path, gpg_key_name):\n        p = Popen([\"rpm\", \"--define\", f\"_gpg_name {gpg_key_name}\", \"--addsign\", file_path], stdout=PIPE, stderr=PIPE)\n        out, err = p.communicate()\n        if p.returncode != 0:\n            print(f\"rpm sign result result => {out}, {err}\")\n            raise\n\n    def _sign_repomd(self):\n        p = Popen([\"gpg\", \"--batch\", \"--yes\", \"--detach-sign\", \"--armor\", \"./rpm/repodata/repomd.xml\"], stdout=PIPE, stderr=PIPE)\n        out, err = p.communicate()\n        if p.returncode != 0:\n            print(f\"sign repomd result => {out}, {err}\")\n            raise\n\n    \"\"\"\n        sets up and signs the RPM directories in the following format:\n        - rpm \n           - aarch64\n           - x86_64\n           - 386\n\n        this assumes the assets are in the format <prefix>-<aarch64/x86_64/386>.rpm\n    \"\"\"\n\n    def _setup_rpm_pkg_directories(self, artifacts_path, gpg_key_name, archs=[\"aarch64\", \"x86_64\", \"386\"]):\n        for arch in archs:\n            for root, _, files in os.walk(artifacts_path):\n                for file in files:\n                    if file.endswith(f\"{arch}.rpm\"):\n                        new_dir = f\"./rpm/{arch}\"\n                        os.makedirs(new_dir, exist_ok=True)\n                        old_path = os.path.join(root, file)\n                        new_path = os.path.join(new_dir, file)\n                        shutil.copyfile(old_path, new_path)\n                        self._sign_rpms(new_path, gpg_key_name)\n\n    \"\"\"\n        imports gpg keys into the system so reprepro and createrepo can use it to sign packages.\n        it returns the GPG ID after a successful import\n    \"\"\"\n\n    def import_gpg_keys(self, private_key, public_key):\n        gpg = gnupg.GPG()\n        private_key = base64.b64decode(private_key)\n        import_result = gpg.import_keys(private_key)\n        if not import_result.fingerprints:\n            raise Exception(\"Failed to import private key\")\n\n        public_key = base64.b64decode(public_key)\n        gpg.import_keys(public_key)\n\n        imported_fingerprint = import_result.fingerprints[0]\n        data = gpg.list_keys(secret=True)\n\n        # Find the specific key we just imported by comparing fingerprints\n        for key in data:\n            if key[\"fingerprint\"] == imported_fingerprint:\n                return (key[\"fingerprint\"], key[\"uids\"][0])\n\n        raise Exception(f\"Could not find imported key with fingerprint {imported_fingerprint}\")\n\n    def import_multiple_gpg_keys(self, primary_private_key, primary_public_key, secondary_private_key=None, secondary_public_key=None):\n        \"\"\"\n        Import one or two GPG keypairs. Returns a list of (fingerprint, uid) with the primary first.\n        \"\"\"\n        results = []\n        if primary_private_key and primary_public_key:\n            results.append(self.import_gpg_keys(primary_private_key, primary_public_key))\n        if secondary_private_key and secondary_public_key:\n            # Ensure secondary is imported and appended\n            results.append(self.import_gpg_keys(secondary_private_key, secondary_public_key))\n        return results\n\n    \"\"\"\n        basically rpm --import <key_file>\n        This enables us to sign rpms.\n    \"\"\"\n\n    def import_rpm_key(self, public_key):\n        file_name = \"pb.key\"\n        with open(file_name, \"wb\") as f:\n            public_key = base64.b64decode(public_key)\n            f.write(public_key)\n\n        p = Popen([\"rpm\", \"--import\", file_name], stdout=PIPE, stderr=PIPE)\n        out, err = p.communicate()\n        if p.returncode != 0:\n            print(f\"create rpm import result => {out}, {err}\")\n            raise\n\n\n\"\"\"\n    Walks through a directory and uploads it's assets to R2.\n    directory : root directory to walk through (String).\n    release: release string. If this value is none, a specific release path will not be created \n              and the release will be uploaded to the default path. \n    binary: name of the binary to upload\n\"\"\"\n\n\ndef upload_from_directories(pkg_uploader, directory, release, binary):\n    for root, _, files in os.walk(directory):\n        for file in files:\n            upload_file_name = os.path.join(binary, root, file)\n            if release:\n                upload_file_name = os.path.join(release, upload_file_name)\n            filename = os.path.join(root, file)\n            try:\n                pkg_uploader.upload_pkg_to_r2(filename, upload_file_name)\n            except ClientError as e:\n                logging.error(e)\n                return\n\n\n\"\"\" \n    1. looks into a artifacts folder for cloudflared debs\n    2. creates Packages.gz, InRelease (signed) files\n    3. uploads them to Cloudflare R2 \n\n    pkg_creator, pkg_uploader: are instantiations of the two classes above.\n\n    gpg_key_id: is an id indicating the key the package should be signed with. The public key of this id will be \n    uploaded to R2 so it can be presented to apt downloaders.\n\n    release_version: is the cloudflared release version. Only provide this if you want a permanent backup.\n\"\"\"\n\n\ndef create_deb_packaging(pkg_creator, pkg_uploader, releases, primary_gpg_key_id, secondary_gpg_key_id, binary_name, archs, package_component,\n                         release_version):\n    # set configuration for package creation.\n    print(f\"initialising configuration for {binary_name} , {archs}\")\n    Path(\"./conf\").mkdir(parents=True, exist_ok=True)\n    # If in rollover mode (secondary provided), tell reprepro to sign with both keys.\n    sign_with_ids = primary_gpg_key_id if not secondary_gpg_key_id else f\"{primary_gpg_key_id} {secondary_gpg_key_id}\"\n    pkg_creator.create_distribution_conf(\n        \"./conf/distributions\",\n        binary_name,\n        binary_name,\n        releases,\n        archs,\n        package_component,\n        f\"apt repository for {binary_name}\",\n        sign_with_ids)\n\n    # create deb pkgs\n    for release in releases:\n        for arch in archs:\n            print(f\"creating deb pkgs for {release} and {arch}...\")\n            pkg_creator.create_deb_pkgs(release, f\"./artifacts/cloudflared-linux-{arch}.deb\")\n\n    print(\"uploading latest to r2...\")\n    upload_from_directories(pkg_uploader, \"dists\", None, binary_name)\n    upload_from_directories(pkg_uploader, \"pool\", None, binary_name)\n\n    if release_version:\n        print(f\"uploading versioned release {release_version} to r2...\")\n        upload_from_directories(pkg_uploader, \"dists\", release_version, binary_name)\n        upload_from_directories(pkg_uploader, \"pool\", release_version, binary_name)\n\n\ndef create_rpm_packaging(\n        pkg_creator,\n        pkg_uploader,\n        artifacts_path,\n        release_version,\n        binary_name,\n        gpg_key_name,\n        base_url,\n        gpg_key_url,\n        upload_repo_file=False,\n):\n    print(f\"creating rpm pkgs...\")\n    pkg_creator.create_rpm_pkgs(artifacts_path, gpg_key_name)\n    repo_file = pkg_creator.create_repo_file(artifacts_path, binary_name, base_url, gpg_key_url)\n\n    print(\"Uploading repo file\")\n    pkg_uploader.upload_pkg_to_r2(repo_file, binary_name + \".repo\")\n\n    print(\"uploading latest to r2...\")\n    upload_from_directories(pkg_uploader, \"rpm\", None, binary_name)\n\n    if upload_repo_file:\n        print(f\"uploading versioned release {release_version} to r2...\")\n        upload_from_directories(pkg_uploader, \"rpm\", release_version, binary_name)\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(\n        description=\"Creates linux releases and uploads them in a packaged format\"\n    )\n\n    parser.add_argument(\n        \"--bucket\", default=os.environ.get(\"R2_BUCKET\"), help=\"R2 Bucket name\"\n    )\n    parser.add_argument(\n        \"--id\", default=os.environ.get(\"R2_CLIENT_ID\"), help=\"R2 Client ID\"\n    )\n    parser.add_argument(\n        \"--secret\", default=os.environ.get(\"R2_CLIENT_SECRET\"), help=\"R2 Client Secret\"\n    )\n    parser.add_argument(\n        \"--account\", default=os.environ.get(\"R2_ACCOUNT_ID\"), help=\"R2 Account Tag\"\n    )\n    parser.add_argument(\n        \"--release-tag\", default=os.environ.get(\"RELEASE_VERSION\"), help=\"Release version you want your pkgs to be\\\n            prefixed with. Leave empty if you don't want tagged release versions backed up to R2.\"\n    )\n\n    parser.add_argument(\n        \"--binary\", default=os.environ.get(\"BINARY_NAME\"), help=\"The name of the binary the packages are for\"\n    )\n\n    parser.add_argument(\n        \"--gpg-private-key\", default=os.environ.get(\"LINUX_SIGNING_PRIVATE_KEY\"), help=\"GPG private key to sign the\\\n            packages\"\n    )\n\n    parser.add_argument(\n        \"--gpg-public-key\", default=os.environ.get(\"LINUX_SIGNING_PUBLIC_KEY\"), help=\"GPG public key used for\\\n            signing packages\"\n    )\n\n    # Optional secondary keypair for key rollover\n    parser.add_argument(\n        \"--gpg-private-key-2\", default=os.environ.get(\"LINUX_SIGNING_PRIVATE_KEY_2\"), help=\"Secondary GPG private key for rollover\"\n    )\n    parser.add_argument(\n        \"--gpg-public-key-2\", default=os.environ.get(\"LINUX_SIGNING_PUBLIC_KEY_2\"), help=\"Secondary GPG public key for rollover\"\n    )\n\n    parser.add_argument(\n        \"--gpg-public-key-url\", default=os.environ.get(\"GPG_PUBLIC_KEY_URL\"), help=\"GPG public key url that\\\n            downloaders can use to verify signing\"\n    )\n\n    parser.add_argument(\n        \"--pkg-upload-url\", default=os.environ.get(\"PKG_URL\"), help=\"URL to be used by downloaders\"\n    )\n\n    parser.add_argument(\n        \"--deb-based-releases\", default=[\"any\", \"bookworm\", \"noble\", \"jammy\", \"focal\", \"bionic\", \"xenial\"],\n        help=\"list of debian based releases that need to be packaged for\"\n    )\n\n    parser.add_argument(\n        \"--archs\", default=[\"amd64\", \"386\", \"arm64\", \"arm\", \"armhf\"], help=\"list of architectures we want to package for. Note that\\\n            it is the caller's responsiblity to ensure that these debs are already present in a directory. This script\\\n            will not build binaries or create their debs.\"\n    )\n\n    parser.add_argument(\n        \"--upload-repo-file\", action='store_true', help=\"Upload RPM repo file to R2\"\n    )\n    args = parser.parse_args()\n\n    return args\n\n\nif __name__ == \"__main__\":\n    try:\n        args = parse_args()\n    except Exception as e:\n        logging.exception(e)\n        exit(1)\n\n    pkg_creator = PkgCreator()\n    # Import one or two keypairs; primary first\n    key_results = pkg_creator.import_multiple_gpg_keys(\n        args.gpg_private_key,\n        args.gpg_public_key,\n        args.gpg_private_key_2,\n        args.gpg_public_key_2,\n    )\n    if not key_results or len(key_results) == 0:\n        raise SystemExit(\"No GPG keys were provided for signing\")\n    primary_gpg_key_id, primary_gpg_key_name = key_results[0]\n    secondary_gpg_key_id = None\n    secondary_gpg_key_name = None\n    if len(key_results) > 1:\n        secondary_gpg_key_id, secondary_gpg_key_name = key_results[1]\n\n    if args.gpg_private_key_2:\n        print(f\"signing RPM with secondary gpg_key: {secondary_gpg_key_id}\")\n        pkg_creator.import_rpm_key(args.gpg_public_key_2)\n    else:\n        print(f\"signing RPM with primary gpg_key: {primary_gpg_key_name}\")\n        pkg_creator.import_rpm_key(args.gpg_public_key)\n\n\n    pkg_uploader = PkgUploader(args.account, args.bucket, args.id, args.secret)\n    print(f\"signing deb with primary gpg_key: {primary_gpg_key_id} and secondary gpg_key: {secondary_gpg_key_id}\")\n    create_deb_packaging(\n        pkg_creator,\n        pkg_uploader,\n        args.deb_based_releases,\n        primary_gpg_key_id,\n        secondary_gpg_key_id,\n        args.binary,\n        args.archs,\n        \"main\",\n        args.release_tag,\n    )\n\n    create_rpm_packaging(\n        pkg_creator,\n        pkg_uploader,\n        \"./artifacts\",\n        args.release_tag,\n        args.binary,\n        secondary_gpg_key_name,\n        args.pkg_upload_url,\n        args.gpg_public_key_url,\n        args.upload_repo_file,\n    )\n"
  },
  {
    "path": "retry/backoffhandler.go",
    "content": "package retry\n\nimport (\n\t\"context\"\n\t\"math/rand\"\n\t\"time\"\n)\n\nconst (\n\tDefaultBaseTime time.Duration = time.Second\n)\n\n// Redeclare time functions so they can be overridden in tests.\ntype Clock struct {\n\tNow   func() time.Time\n\tAfter func(d time.Duration) <-chan time.Time\n}\n\n// BackoffHandler manages exponential backoff and limits the maximum number of retries.\n// The base time period is 1 second, doubling with each retry.\n// After initial success, a grace period can be set to reset the backoff timer if\n// a connection is maintained successfully for a long enough period. The base grace period\n// is 2 seconds, doubling with each retry.\ntype BackoffHandler struct {\n\t// MaxRetries sets the maximum number of retries to perform. The default value\n\t// of 0 disables retry completely.\n\tmaxRetries uint\n\t// RetryForever caps the exponential backoff period according to MaxRetries\n\t// but allows you to retry indefinitely.\n\tretryForever bool\n\t// BaseTime sets the initial backoff period.\n\tbaseTime time.Duration\n\n\tretries       uint\n\tresetDeadline time.Time\n\n\tClock Clock\n}\n\nfunc NewBackoff(maxRetries uint, baseTime time.Duration, retryForever bool) BackoffHandler {\n\treturn BackoffHandler{\n\t\tmaxRetries:   maxRetries,\n\t\tbaseTime:     baseTime,\n\t\tretryForever: retryForever,\n\t\tClock:        Clock{Now: time.Now, After: time.After},\n\t}\n}\n\nfunc (b BackoffHandler) GetMaxBackoffDuration(ctx context.Context) (time.Duration, bool) {\n\t// Follows the same logic as Backoff, but without mutating the receiver.\n\t// This select has to happen first to reflect the actual behaviour of the Backoff function.\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn time.Duration(0), false\n\tdefault:\n\t}\n\tif !b.resetDeadline.IsZero() && b.Clock.Now().After(b.resetDeadline) {\n\t\t// b.retries would be set to 0 at this point\n\t\treturn time.Second, true\n\t}\n\tif b.retries >= b.maxRetries && !b.retryForever {\n\t\treturn time.Duration(0), false\n\t}\n\tmaxTimeToWait := b.GetBaseTime() * 1 << (b.retries + 1)\n\treturn maxTimeToWait, true\n}\n\n// BackoffTimer returns a channel that sends the current time when the exponential backoff timeout expires.\n// Returns nil if the maximum number of retries have been used.\nfunc (b *BackoffHandler) BackoffTimer() <-chan time.Time {\n\tif !b.resetDeadline.IsZero() && b.Clock.Now().After(b.resetDeadline) {\n\t\tb.retries = 0\n\t\tb.resetDeadline = time.Time{}\n\t}\n\tif b.retries >= b.maxRetries {\n\t\tif !b.retryForever {\n\t\t\treturn nil\n\t\t}\n\t} else {\n\t\tb.retries++\n\t}\n\tmaxTimeToWait := b.GetBaseTime() * (1 << b.retries)\n\ttimeToWait := time.Duration(rand.Int63n(maxTimeToWait.Nanoseconds())) // #nosec G404\n\treturn b.Clock.After(timeToWait)\n}\n\n// Backoff is used to wait according to exponential backoff. Returns false if the\n// maximum number of retries have been used or if the underlying context has been cancelled.\nfunc (b *BackoffHandler) Backoff(ctx context.Context) bool {\n\tc := b.BackoffTimer()\n\tif c == nil {\n\t\treturn false\n\t}\n\tselect {\n\tcase <-c:\n\t\treturn true\n\tcase <-ctx.Done():\n\t\treturn false\n\t}\n}\n\n// Sets a grace period within which the backoff timer is maintained. After the grace\n// period expires, the number of retries & backoff duration is reset.\nfunc (b *BackoffHandler) SetGracePeriod() time.Duration {\n\tmaxTimeToWait := b.GetBaseTime() * 2 << (b.retries + 1)\n\ttimeToWait := time.Duration(rand.Int63n(maxTimeToWait.Nanoseconds())) // #nosec G404\n\tb.resetDeadline = b.Clock.Now().Add(timeToWait)\n\n\treturn timeToWait\n}\n\nfunc (b BackoffHandler) GetBaseTime() time.Duration {\n\tif b.baseTime == 0 {\n\t\treturn DefaultBaseTime\n\t}\n\treturn b.baseTime\n}\n\n// Retries returns the number of retries consumed so far.\nfunc (b *BackoffHandler) Retries() int {\n\treturn int(b.retries) // #nosec G115\n}\n\nfunc (b *BackoffHandler) ReachedMaxRetries() bool {\n\treturn b.retries == b.maxRetries\n}\n\nfunc (b *BackoffHandler) ResetNow() {\n\tb.resetDeadline = b.Clock.Now()\n\tb.retries = 0\n}\n"
  },
  {
    "path": "retry/backoffhandler_test.go",
    "content": "package retry\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc immediateTimeAfter(time.Duration) <-chan time.Time {\n\tc := make(chan time.Time, 1)\n\tc <- time.Now()\n\treturn c\n}\n\nfunc TestBackoffRetries(t *testing.T) {\n\tctx := context.Background()\n\t// make backoff return immediately\n\tbackoff := BackoffHandler{maxRetries: 3, Clock: Clock{time.Now, immediateTimeAfter}}\n\tif !backoff.Backoff(ctx) {\n\t\tt.Fatalf(\"backoff failed immediately\")\n\t}\n\tif !backoff.Backoff(ctx) {\n\t\tt.Fatalf(\"backoff failed after 1 retry\")\n\t}\n\tif !backoff.Backoff(ctx) {\n\t\tt.Fatalf(\"backoff failed after 2 retry\")\n\t}\n\tif backoff.Backoff(ctx) {\n\t\tt.Fatalf(\"backoff allowed after 3 (max) retries\")\n\t}\n}\n\nfunc TestBackoffCancel(t *testing.T) {\n\tctx, cancelFunc := context.WithCancel(context.Background())\n\t// prevent backoff from returning normally\n\tafter := func(time.Duration) <-chan time.Time { return make(chan time.Time) }\n\tbackoff := BackoffHandler{maxRetries: 3, Clock: Clock{time.Now, after}}\n\tcancelFunc()\n\tif backoff.Backoff(ctx) {\n\t\tt.Fatalf(\"backoff allowed after cancel\")\n\t}\n\tif _, ok := backoff.GetMaxBackoffDuration(ctx); ok {\n\t\tt.Fatalf(\"backoff allowed after cancel\")\n\t}\n}\n\nfunc TestBackoffGracePeriod(t *testing.T) {\n\tctx := context.Background()\n\tcurrentTime := time.Now()\n\t// make Clock.Now return whatever we like\n\tnow := func() time.Time { return currentTime }\n\t// make backoff return immediately\n\tbackoff := BackoffHandler{maxRetries: 1, Clock: Clock{now, immediateTimeAfter}}\n\tif !backoff.Backoff(ctx) {\n\t\tt.Fatalf(\"backoff failed immediately\")\n\t}\n\t// the next call to Backoff would fail unless it's after the grace period\n\tgracePeriod := backoff.SetGracePeriod()\n\t// advance time to after the grace period, which at most will be 8 seconds, but we will advance +1 second.\n\tcurrentTime = currentTime.Add(gracePeriod + time.Second)\n\tif !backoff.Backoff(ctx) {\n\t\tt.Fatalf(\"backoff failed after the grace period expired\")\n\t}\n\t// confirm we ignore grace period after backoff\n\tif backoff.Backoff(ctx) {\n\t\tt.Fatalf(\"backoff allowed after 1 (max) retry\")\n\t}\n}\n\nfunc TestGetMaxBackoffDurationRetries(t *testing.T) {\n\tctx := context.Background()\n\t// make backoff return immediately\n\tbackoff := BackoffHandler{maxRetries: 3, Clock: Clock{time.Now, immediateTimeAfter}}\n\tif _, ok := backoff.GetMaxBackoffDuration(ctx); !ok {\n\t\tt.Fatalf(\"backoff failed immediately\")\n\t}\n\tbackoff.Backoff(ctx) // noop\n\tif _, ok := backoff.GetMaxBackoffDuration(ctx); !ok {\n\t\tt.Fatalf(\"backoff failed after 1 retry\")\n\t}\n\tbackoff.Backoff(ctx) // noop\n\tif _, ok := backoff.GetMaxBackoffDuration(ctx); !ok {\n\t\tt.Fatalf(\"backoff failed after 2 retry\")\n\t}\n\tbackoff.Backoff(ctx) // noop\n\tif _, ok := backoff.GetMaxBackoffDuration(ctx); ok {\n\t\tt.Fatalf(\"backoff allowed after 3 (max) retries\")\n\t}\n\tif backoff.Backoff(ctx) {\n\t\tt.Fatalf(\"backoff allowed after 3 (max) retries\")\n\t}\n}\n\nfunc TestGetMaxBackoffDuration(t *testing.T) {\n\tctx := context.Background()\n\t// make backoff return immediately\n\tbackoff := BackoffHandler{maxRetries: 3, Clock: Clock{time.Now, immediateTimeAfter}}\n\tif duration, ok := backoff.GetMaxBackoffDuration(ctx); !ok || duration > time.Second*2 {\n\t\tt.Fatalf(\"backoff (%s) didn't return < 2 seconds on first retry\", duration)\n\t}\n\tbackoff.Backoff(ctx) // noop\n\tif duration, ok := backoff.GetMaxBackoffDuration(ctx); !ok || duration > time.Second*4 {\n\t\tt.Fatalf(\"backoff (%s) didn't return < 4 seconds on second retry\", duration)\n\t}\n\tbackoff.Backoff(ctx) // noop\n\tif duration, ok := backoff.GetMaxBackoffDuration(ctx); !ok || duration > time.Second*8 {\n\t\tt.Fatalf(\"backoff (%s) didn't return < 8 seconds on third retry\", duration)\n\t}\n\tbackoff.Backoff(ctx) // noop\n\tif duration, ok := backoff.GetMaxBackoffDuration(ctx); ok || duration != 0 {\n\t\tt.Fatalf(\"backoff (%s) didn't return 0 seconds on fourth retry (exceeding limit)\", duration)\n\t}\n}\n\nfunc TestBackoffRetryForever(t *testing.T) {\n\tctx := context.Background()\n\t// make backoff return immediately\n\tbackoff := BackoffHandler{maxRetries: 3, retryForever: true, Clock: Clock{time.Now, immediateTimeAfter}}\n\tif duration, ok := backoff.GetMaxBackoffDuration(ctx); !ok || duration > time.Second*2 {\n\t\tt.Fatalf(\"backoff (%s) didn't return < 2 seconds on first retry\", duration)\n\t}\n\tbackoff.Backoff(ctx) // noop\n\tif duration, ok := backoff.GetMaxBackoffDuration(ctx); !ok || duration > time.Second*4 {\n\t\tt.Fatalf(\"backoff (%s) didn't return < 4 seconds on second retry\", duration)\n\t}\n\tbackoff.Backoff(ctx) // noop\n\tif duration, ok := backoff.GetMaxBackoffDuration(ctx); !ok || duration > time.Second*8 {\n\t\tt.Fatalf(\"backoff (%s) didn't return < 8 seconds on third retry\", duration)\n\t}\n\tif !backoff.Backoff(ctx) {\n\t\tt.Fatalf(\"backoff refused on fourth retry despire RetryForever\")\n\t}\n\tif duration, ok := backoff.GetMaxBackoffDuration(ctx); !ok || duration > time.Second*16 {\n\t\tt.Fatalf(\"backoff returned %v instead of 8 seconds on fourth retry\", duration)\n\t}\n\tif !backoff.Backoff(ctx) {\n\t\tt.Fatalf(\"backoff refused on fifth retry despire RetryForever\")\n\t}\n\tif duration, ok := backoff.GetMaxBackoffDuration(ctx); !ok || duration > time.Second*16 {\n\t\tt.Fatalf(\"backoff returned %v instead of 8 seconds on fifth retry\", duration)\n\t}\n}\n"
  },
  {
    "path": "signal/safe_signal.go",
    "content": "package signal\n\nimport (\n\t\"sync\"\n)\n\n// Signal lets goroutines signal that some event has occurred. Other goroutines can wait for the signal.\ntype Signal struct {\n\tch   chan struct{}\n\tonce sync.Once\n}\n\n// New wraps a channel and turns it into a signal for a one-time event.\nfunc New(ch chan struct{}) *Signal {\n\treturn &Signal{\n\t\tch:   ch,\n\t\tonce: sync.Once{},\n\t}\n}\n\n// Notify alerts any goroutines waiting on this signal that the event has occurred.\n// After the first call to Notify(), future calls are no-op.\nfunc (s *Signal) Notify() {\n\ts.once.Do(func() {\n\t\tclose(s.ch)\n\t})\n}\n\n// Wait returns a channel which will be written to when Notify() is called for the first time.\n// This channel will never be written to a second time.\nfunc (s *Signal) Wait() <-chan struct{} {\n\treturn s.ch\n}\n"
  },
  {
    "path": "signal/safe_signal_test.go",
    "content": "package signal\n\nimport (\n\t\"testing\"\n)\n\nfunc TestMultiNotifyDoesntCrash(t *testing.T) {\n\tsig := New(make(chan struct{}))\n\tsig.Notify()\n\tsig.Notify()\n\t// If code has reached here without crashing, the test has passed.\n}\n\nfunc TestWait(t *testing.T) {\n\tsig := New(make(chan struct{}))\n\tsig.Notify()\n\tselect {\n\tcase <-sig.Wait():\n\t\t// Test succeeds\n\t\treturn\n\tdefault:\n\t\t// sig.Wait() should have been read from, because sig.Notify() wrote to it.\n\t\tt.Fail()\n\t}\n}\n"
  },
  {
    "path": "socks/auth_handler.go",
    "content": "package socks\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\nconst (\n\t// NoAuth means no authentication is used when connecting\n\tNoAuth = uint8(0)\n\n\t// UserPassAuth means a user/password is used when connecting\n\tUserPassAuth = uint8(2)\n\n\tnoAcceptable    = uint8(255)\n\tuserAuthVersion = uint8(1)\n\tauthSuccess     = uint8(0)\n\tauthFailure     = uint8(1)\n)\n\n// AuthHandler handles socks authentication requests\ntype AuthHandler interface {\n\tHandle(io.Reader, io.Writer) error\n\tRegister(uint8, Authenticator)\n}\n\n// StandardAuthHandler loads the default authenticators\ntype StandardAuthHandler struct {\n\tauthenticators map[uint8]Authenticator\n}\n\n// NewAuthHandler creates a default auth handler\nfunc NewAuthHandler() AuthHandler {\n\tdefaults := make(map[uint8]Authenticator)\n\tdefaults[NoAuth] = NewNoAuthAuthenticator()\n\treturn &StandardAuthHandler{\n\t\tauthenticators: defaults,\n\t}\n}\n\n// Register adds/replaces an Authenticator to use when handling Authentication requests\nfunc (h *StandardAuthHandler) Register(method uint8, a Authenticator) {\n\th.authenticators[method] = a\n}\n\n// Handle gets the methods from the SOCKS5 client and authenticates with the first supported method\nfunc (h *StandardAuthHandler) Handle(bufConn io.Reader, conn io.Writer) error {\n\tmethods, err := readMethods(bufConn)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Failed to read auth methods: %v\", err)\n\t}\n\n\t// first supported method is used\n\tfor _, method := range methods {\n\t\tauthenticator := h.authenticators[method]\n\t\tif authenticator != nil {\n\t\t\treturn authenticator.Handle(bufConn, conn)\n\t\t}\n\t}\n\n\t// failed to authenticate. No supported authentication type found\n\tconn.Write([]byte{socks5Version, noAcceptable})\n\treturn fmt.Errorf(\"unknown authentication type\")\n}\n\n// readMethods is used to read the number and type of methods\nfunc readMethods(r io.Reader) ([]byte, error) {\n\theader := []byte{0}\n\tif _, err := r.Read(header); err != nil {\n\t\treturn nil, err\n\t}\n\n\tnumMethods := int(header[0])\n\tmethods := make([]byte, numMethods)\n\t_, err := io.ReadAtLeast(r, methods, numMethods)\n\treturn methods, err\n}\n"
  },
  {
    "path": "socks/authenticator.go",
    "content": "package socks\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n// Authenticator is the connection passed in as a reader/writer to support different authentication types\ntype Authenticator interface {\n\tHandle(io.Reader, io.Writer) error\n}\n\n// NoAuthAuthenticator is used to handle the No Authentication mode\ntype NoAuthAuthenticator struct{}\n\n// NewNoAuthAuthenticator creates a authless Authenticator\nfunc NewNoAuthAuthenticator() Authenticator {\n\treturn &NoAuthAuthenticator{}\n}\n\n// Handle writes back the version and NoAuth\nfunc (a *NoAuthAuthenticator) Handle(reader io.Reader, writer io.Writer) error {\n\t_, err := writer.Write([]byte{socks5Version, NoAuth})\n\treturn err\n}\n\n// UserPassAuthAuthenticator is used to handle the user/password mode\ntype UserPassAuthAuthenticator struct {\n\tIsValid func(string, string) bool\n}\n\n// NewUserPassAuthAuthenticator creates a new username/password validator Authenticator\nfunc NewUserPassAuthAuthenticator(isValid func(string, string) bool) Authenticator {\n\treturn &UserPassAuthAuthenticator{\n\t\tIsValid: isValid,\n\t}\n}\n\n// Handle writes back the version and NoAuth\nfunc (a *UserPassAuthAuthenticator) Handle(reader io.Reader, writer io.Writer) error {\n\tif _, err := writer.Write([]byte{socks5Version, UserPassAuth}); err != nil {\n\t\treturn err\n\t}\n\n\t// Get the version and username length\n\theader := []byte{0, 0}\n\tif _, err := io.ReadAtLeast(reader, header, 2); err != nil {\n\t\treturn err\n\t}\n\n\t// Ensure compatibility. Someone call E-harmony\n\tif header[0] != userAuthVersion {\n\t\treturn fmt.Errorf(\"Unsupported auth version: %v\", header[0])\n\t}\n\n\t// Get the user name\n\tuserLen := int(header[1])\n\tuser := make([]byte, userLen)\n\tif _, err := io.ReadAtLeast(reader, user, userLen); err != nil {\n\t\treturn err\n\t}\n\n\t// Get the password length\n\tif _, err := reader.Read(header[:1]); err != nil {\n\t\treturn err\n\t}\n\n\t// Get the password\n\tpassLen := int(header[0])\n\tpass := make([]byte, passLen)\n\tif _, err := io.ReadAtLeast(reader, pass, passLen); err != nil {\n\t\treturn err\n\t}\n\n\t// Verify the password\n\tif a.IsValid(string(user), string(pass)) {\n\t\t_, err := writer.Write([]byte{userAuthVersion, authSuccess})\n\t\treturn err\n\t}\n\n\t// password failed. Write back failure\n\tif _, err := writer.Write([]byte{userAuthVersion, authFailure}); err != nil {\n\t\treturn err\n\t}\n\n\treturn fmt.Errorf(\"User authentication failed\")\n}\n"
  },
  {
    "path": "socks/connection_handler.go",
    "content": "package socks\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io\"\n)\n\n// ConnectionHandler is the Serve method to handle connections\n// from a local TCP listener of the standard library (net.Listener)\ntype ConnectionHandler interface {\n\tServe(io.ReadWriter) error\n}\n\n// StandardConnectionHandler is the base implementation of handling SOCKS5 requests\ntype StandardConnectionHandler struct {\n\trequestHandler RequestHandler\n\tauthHandler    AuthHandler\n}\n\n// NewConnectionHandler creates a standard SOCKS5 connection handler\n// This process connections from a generic TCP listener from the standard library\nfunc NewConnectionHandler(requestHandler RequestHandler) ConnectionHandler {\n\treturn &StandardConnectionHandler{\n\t\trequestHandler: requestHandler,\n\t\tauthHandler:    NewAuthHandler(),\n\t}\n}\n\n// Serve process new connection created after calling `Accept()` in the standard library\nfunc (h *StandardConnectionHandler) Serve(c io.ReadWriter) error {\n\tbufConn := bufio.NewReader(c)\n\n\t// read the version byte\n\tversion := []byte{0}\n\tif _, err := bufConn.Read(version); err != nil {\n\t\treturn err\n\t}\n\n\t// ensure compatibility\n\tif version[0] != socks5Version {\n\t\treturn fmt.Errorf(\"Unsupported SOCKS version: %v\", version)\n\t}\n\n\t// handle auth\n\tif err := h.authHandler.Handle(bufConn, c); err != nil {\n\t\treturn err\n\t}\n\n\t// process command/request\n\treq, err := NewRequest(bufConn)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn h.requestHandler.Handle(req, c)\n}\n"
  },
  {
    "path": "socks/connection_handler_test.go",
    "content": "package socks\n\nimport (\n\t\"encoding/json\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"golang.org/x/net/proxy\"\n)\n\ntype successResponse struct {\n\tStatus string `json:\"status\"`\n}\n\nfunc sendSocksRequest(t *testing.T) []byte {\n\tdialer, err := proxy.SOCKS5(\"tcp\", \"127.0.0.1:8086\", nil, proxy.Direct)\n\tassert.NoError(t, err)\n\n\thttpTransport := &http.Transport{}\n\thttpClient := &http.Client{Transport: httpTransport}\n\t// set our socks5 as the dialer\n\thttpTransport.Dial = dialer.Dial\n\n\treq, err := http.NewRequest(\"GET\", \"http://127.0.0.1:8085\", nil)\n\tassert.NoError(t, err)\n\n\tresp, err := httpClient.Do(req)\n\tassert.NoError(t, err)\n\tdefer resp.Body.Close()\n\n\tb, err := io.ReadAll(resp.Body)\n\tassert.NoError(t, err)\n\n\treturn b\n}\n\nfunc startTestServer(t *testing.T, httpHandler func(w http.ResponseWriter, r *http.Request)) {\n\t// create a socks server\n\trequestHandler := NewRequestHandler(NewNetDialer(), nil)\n\tsocksServer := NewConnectionHandler(requestHandler)\n\tlistener, err := net.Listen(\"tcp\", \"localhost:8086\")\n\tassert.NoError(t, err)\n\n\tgo func() {\n\t\tdefer listener.Close()\n\t\tfor {\n\t\t\tconn, _ := listener.Accept()\n\t\t\tgo socksServer.Serve(conn)\n\t\t}\n\t}()\n\n\t// create an http server\n\tmux := http.NewServeMux()\n\tmux.HandleFunc(\"/\", httpHandler)\n\n\t// start the servers\n\tgo http.ListenAndServe(\"localhost:8085\", mux)\n}\n\nfunc respondWithJSON(w http.ResponseWriter, v interface{}, status int) {\n\tdata, _ := json.Marshal(v)\n\n\tw.Header().Set(\"Content-Type\", \"application/json\")\n\tw.WriteHeader(status)\n\tw.Write(data)\n}\n\nfunc OkJSONResponseHandler(w http.ResponseWriter, r *http.Request) {\n\tresp := successResponse{\n\t\tStatus: \"ok\",\n\t}\n\trespondWithJSON(w, resp, http.StatusOK)\n}\n\nfunc TestSocksConnection(t *testing.T) {\n\tstartTestServer(t, OkJSONResponseHandler)\n\ttime.Sleep(100 * time.Millisecond)\n\tb := sendSocksRequest(t)\n\tassert.True(t, len(b) > 0, \"no data returned!\")\n\n\tvar resp successResponse\n\tjson.Unmarshal(b, &resp)\n\n\tassert.True(t, resp.Status == \"ok\", \"response didn't return ok\")\n}\n"
  },
  {
    "path": "socks/dialer.go",
    "content": "package socks\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n)\n\n// Dialer is used to provided the transport of the proxy\ntype Dialer interface {\n\tDial(string) (io.ReadWriteCloser, *AddrSpec, error)\n}\n\n// NetDialer is a standard TCP dialer\ntype NetDialer struct {\n}\n\n// NewNetDialer creates a new dialer\nfunc NewNetDialer() Dialer {\n\treturn &NetDialer{}\n}\n\n// Dial is a base TCP dialer\nfunc (d *NetDialer) Dial(address string) (io.ReadWriteCloser, *AddrSpec, error) {\n\tc, err := net.Dial(\"tcp\", address)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tlocal := c.LocalAddr().(*net.TCPAddr)\n\taddr := AddrSpec{IP: local.IP, Port: local.Port}\n\n\treturn c, &addr, nil\n}\n\n// ConnDialer is like NetDialer but with an existing TCP dialer already created\ntype ConnDialer struct {\n\tconn net.Conn\n}\n\n// NewConnDialer creates a new dialer with a already created net.conn (TCP expected)\nfunc NewConnDialer(conn net.Conn) Dialer {\n\treturn &ConnDialer{\n\t\tconn: conn,\n\t}\n}\n\n// Dial is a TCP dialer but already created\nfunc (d *ConnDialer) Dial(address string) (io.ReadWriteCloser, *AddrSpec, error) {\n\tlocal, ok := d.conn.LocalAddr().(*net.TCPAddr)\n\tif !ok {\n\t\treturn nil, nil, fmt.Errorf(\"not a tcp connection\")\n\t}\n\n\taddr := AddrSpec{IP: local.IP, Port: local.Port}\n\treturn d.conn, &addr, nil\n}\n"
  },
  {
    "path": "socks/request.go",
    "content": "package socks\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"strconv\"\n)\n\nconst (\n\t// version\n\tsocks5Version = uint8(5)\n\n\t// commands https://tools.ietf.org/html/rfc1928#section-4\n\tconnectCommand   = uint8(1)\n\tbindCommand      = uint8(2)\n\tassociateCommand = uint8(3)\n\n\t// address types\n\tipv4Address = uint8(1)\n\tfqdnAddress = uint8(3)\n\tipv6Address = uint8(4)\n)\n\n// https://tools.ietf.org/html/rfc1928#section-6\nconst (\n\tsuccessReply uint8 = iota\n\tserverFailure\n\truleFailure\n\tnetworkUnreachable\n\thostUnreachable\n\tconnectionRefused\n\tttlExpired\n\tcommandNotSupported\n\taddrTypeNotSupported\n)\n\n// AddrSpec is used to return the target IPv4, IPv6, or a FQDN\ntype AddrSpec struct {\n\tFQDN string\n\tIP   net.IP\n\tPort int\n}\n\n// String gives a host version of the Address\nfunc (a *AddrSpec) String() string {\n\tif a.FQDN != \"\" {\n\t\treturn fmt.Sprintf(\"%s (%s):%d\", a.FQDN, a.IP, a.Port)\n\t}\n\treturn fmt.Sprintf(\"%s:%d\", a.IP, a.Port)\n}\n\n// Address returns a string suitable to dial; prefer returning IP-based\n// address, fallback to FQDN\nfunc (a AddrSpec) Address() string {\n\tif len(a.IP) != 0 {\n\t\treturn net.JoinHostPort(a.IP.String(), strconv.Itoa(a.Port))\n\t}\n\treturn net.JoinHostPort(a.FQDN, strconv.Itoa(a.Port))\n}\n\n// Request is a SOCKS5 command with supporting field of the connection\ntype Request struct {\n\t// Protocol version\n\tVersion uint8\n\t// Requested command\n\tCommand uint8\n\t// AddrSpec of the destination\n\tDestAddr *AddrSpec\n\t// reading from the connection\n\tbufConn io.Reader\n}\n\n// NewRequest creates a new request from the connection data stream\nfunc NewRequest(bufConn io.Reader) (*Request, error) {\n\t// Read the version byte\n\theader := []byte{0, 0, 0}\n\tif _, err := io.ReadAtLeast(bufConn, header, 3); err != nil {\n\t\treturn nil, fmt.Errorf(\"Failed to get command version: %v\", err)\n\t}\n\n\t// ensure compatibility\n\tif header[0] != socks5Version {\n\t\treturn nil, fmt.Errorf(\"Unsupported command version: %v\", header[0])\n\t}\n\n\t// Read in the destination address\n\tdest, err := readAddrSpec(bufConn)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &Request{\n\t\tVersion:  socks5Version,\n\t\tCommand:  header[1],\n\t\tDestAddr: dest,\n\t\tbufConn:  bufConn,\n\t}, nil\n}\n\nfunc sendReply(w io.Writer, resp uint8, addr *AddrSpec) error {\n\tvar addrType uint8\n\tvar addrBody []byte\n\tvar addrPort uint16\n\tswitch {\n\tcase addr == nil:\n\t\taddrType = ipv4Address\n\t\taddrBody = []byte{0, 0, 0, 0}\n\t\taddrPort = 0\n\n\tcase addr.FQDN != \"\":\n\t\taddrType = fqdnAddress\n\t\taddrBody = append([]byte{byte(len(addr.FQDN))}, addr.FQDN...)\n\t\taddrPort = uint16(addr.Port)\n\n\tcase addr.IP.To4() != nil:\n\t\taddrType = ipv4Address\n\t\taddrBody = []byte(addr.IP.To4())\n\t\taddrPort = uint16(addr.Port)\n\n\tcase addr.IP.To16() != nil:\n\t\taddrType = ipv6Address\n\t\taddrBody = []byte(addr.IP.To16())\n\t\taddrPort = uint16(addr.Port)\n\n\tdefault:\n\t\treturn fmt.Errorf(\"Failed to format address: %v\", addr)\n\t}\n\n\t// Format the message\n\tmsg := make([]byte, 6+len(addrBody))\n\tmsg[0] = socks5Version\n\tmsg[1] = resp\n\tmsg[2] = 0 // Reserved\n\tmsg[3] = addrType\n\tcopy(msg[4:], addrBody)\n\tmsg[4+len(addrBody)] = byte(addrPort >> 8)\n\tmsg[4+len(addrBody)+1] = byte(addrPort & 0xff)\n\n\t// Send the message\n\t_, err := w.Write(msg)\n\treturn err\n}\n\n// readAddrSpec is used to read AddrSpec.\n// Expects an address type byte, followed by the address and port\nfunc readAddrSpec(r io.Reader) (*AddrSpec, error) {\n\td := &AddrSpec{}\n\n\t// Get the address type\n\taddrType := []byte{0}\n\tif _, err := r.Read(addrType); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Handle on a per type basis\n\tswitch addrType[0] {\n\tcase ipv4Address:\n\t\taddr := make([]byte, 4)\n\t\tif _, err := io.ReadAtLeast(r, addr, len(addr)); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\td.IP = net.IP(addr)\n\n\tcase ipv6Address:\n\t\taddr := make([]byte, 16)\n\t\tif _, err := io.ReadAtLeast(r, addr, len(addr)); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\td.IP = net.IP(addr)\n\n\tcase fqdnAddress:\n\t\tif _, err := r.Read(addrType); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\taddrLen := int(addrType[0])\n\t\tfqdn := make([]byte, addrLen)\n\t\tif _, err := io.ReadAtLeast(r, fqdn, addrLen); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\td.FQDN = string(fqdn)\n\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"Unrecognized address type\")\n\t}\n\n\t// Read the port\n\tport := []byte{0, 0}\n\tif _, err := io.ReadAtLeast(r, port, 2); err != nil {\n\t\treturn nil, err\n\t}\n\td.Port = (int(port[0]) << 8) | int(port[1])\n\n\treturn d, nil\n}\n"
  },
  {
    "path": "socks/request_handler.go",
    "content": "package socks\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"strings\"\n\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/ipaccess\"\n)\n\n// RequestHandler is the functions needed to handle a SOCKS5 command\ntype RequestHandler interface {\n\tHandle(*Request, io.ReadWriter) error\n}\n\n// StandardRequestHandler implements the base socks5 command processing\ntype StandardRequestHandler struct {\n\tdialer       Dialer\n\taccessPolicy *ipaccess.Policy\n}\n\n// NewRequestHandler creates a standard SOCKS5 request handler\n// This handles the SOCKS5 commands and proxies them to their destination\nfunc NewRequestHandler(dialer Dialer, accessPolicy *ipaccess.Policy) RequestHandler {\n\treturn &StandardRequestHandler{\n\t\tdialer:       dialer,\n\t\taccessPolicy: accessPolicy,\n\t}\n}\n\n// Handle processes and responds to socks5 commands\nfunc (h *StandardRequestHandler) Handle(req *Request, conn io.ReadWriter) error {\n\tswitch req.Command {\n\tcase connectCommand:\n\t\treturn h.handleConnect(conn, req)\n\tcase bindCommand:\n\t\treturn h.handleBind(conn, req)\n\tcase associateCommand:\n\t\treturn h.handleAssociate(conn, req)\n\tdefault:\n\t\tif err := sendReply(conn, commandNotSupported, nil); err != nil {\n\t\t\treturn fmt.Errorf(\"Failed to send reply: %v\", err)\n\t\t}\n\t\treturn fmt.Errorf(\"Unsupported command: %v\", req.Command)\n\t}\n}\n\n// handleConnect is used to handle a connect command\nfunc (h *StandardRequestHandler) handleConnect(conn io.ReadWriter, req *Request) error {\n\tif h.accessPolicy != nil {\n\t\tif req.DestAddr.IP == nil {\n\t\t\taddr, err := net.ResolveIPAddr(\"ip\", req.DestAddr.FQDN)\n\t\t\tif err != nil {\n\t\t\t\t_ = sendReply(conn, ruleFailure, req.DestAddr)\n\t\t\t\treturn fmt.Errorf(\"unable to resolve host to confirm access\")\n\t\t\t}\n\n\t\t\treq.DestAddr.IP = addr.IP\n\t\t}\n\t\tif allowed, rule := h.accessPolicy.Allowed(req.DestAddr.IP, req.DestAddr.Port); !allowed {\n\t\t\t_ = sendReply(conn, ruleFailure, req.DestAddr)\n\t\t\tif rule != nil {\n\t\t\t\treturn fmt.Errorf(\"Connect to %v denied due to iprule: %s\", req.DestAddr, rule.String())\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"Connect to %v denied\", req.DestAddr)\n\t\t}\n\t}\n\n\ttarget, localAddr, err := h.dialer.Dial(req.DestAddr.Address())\n\tif err != nil {\n\t\tmsg := err.Error()\n\t\tresp := hostUnreachable\n\t\tif strings.Contains(msg, \"refused\") {\n\t\t\tresp = connectionRefused\n\t\t} else if strings.Contains(msg, \"network is unreachable\") {\n\t\t\tresp = networkUnreachable\n\t\t}\n\t\tif err := sendReply(conn, resp, nil); err != nil {\n\t\t\treturn fmt.Errorf(\"Failed to send reply: %v\", err)\n\t\t}\n\t\treturn fmt.Errorf(\"Connect to %v failed: %v\", req.DestAddr, err)\n\t}\n\tdefer target.Close()\n\n\t// Send success\n\tif err := sendReply(conn, successReply, localAddr); err != nil {\n\t\treturn fmt.Errorf(\"Failed to send reply: %v\", err)\n\t}\n\n\t// Start proxying\n\tproxyDone := make(chan error, 2)\n\n\tgo func() {\n\t\t_, e := io.Copy(target, req.bufConn)\n\t\tproxyDone <- e\n\t}()\n\n\tgo func() {\n\t\t_, e := io.Copy(conn, target)\n\t\tproxyDone <- e\n\t}()\n\n\t// Wait for both\n\tfor i := 0; i < 2; i++ {\n\t\te := <-proxyDone\n\t\tif e != nil {\n\t\t\treturn e\n\t\t}\n\t}\n\treturn nil\n}\n\n// handleBind is used to handle a bind command\n// TODO: Support bind command\nfunc (h *StandardRequestHandler) handleBind(conn io.ReadWriter, req *Request) error {\n\tif err := sendReply(conn, commandNotSupported, nil); err != nil {\n\t\treturn fmt.Errorf(\"Failed to send reply: %v\", err)\n\t}\n\treturn nil\n}\n\n// handleAssociate is used to handle a connect command\n// TODO: Support associate command\nfunc (h *StandardRequestHandler) handleAssociate(conn io.ReadWriter, req *Request) error {\n\tif err := sendReply(conn, commandNotSupported, nil); err != nil {\n\t\treturn fmt.Errorf(\"Failed to send reply: %v\", err)\n\t}\n\treturn nil\n}\n\nfunc StreamHandler(tunnelConn io.ReadWriter, originConn net.Conn, log *zerolog.Logger) {\n\tdialer := NewConnDialer(originConn)\n\trequestHandler := NewRequestHandler(dialer, nil)\n\tsocksServer := NewConnectionHandler(requestHandler)\n\n\tif err := socksServer.Serve(tunnelConn); err != nil {\n\t\tlog.Debug().Err(err).Msg(\"Socks stream handler error\")\n\t}\n}\n\nfunc StreamNetHandler(tunnelConn io.ReadWriter, accessPolicy *ipaccess.Policy, log *zerolog.Logger) {\n\tdialer := NewNetDialer()\n\trequestHandler := NewRequestHandler(dialer, accessPolicy)\n\tsocksServer := NewConnectionHandler(requestHandler)\n\n\tif err := socksServer.Serve(tunnelConn); err != nil {\n\t\tlog.Debug().Err(err).Msg(\"Socks stream handler error\")\n\t}\n}\n"
  },
  {
    "path": "socks/request_handler_test.go",
    "content": "package socks\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/cloudflare/cloudflared/ipaccess\"\n)\n\nfunc TestUnsupportedBind(t *testing.T) {\n\treq := createRequest(t, socks5Version, bindCommand, \"2001:db8::68\", 1337, false)\n\tvar b bytes.Buffer\n\n\trequestHandler := NewRequestHandler(NewNetDialer(), nil)\n\terr := requestHandler.Handle(req, &b)\n\tassert.NoError(t, err)\n\tassert.True(t, b.Bytes()[1] == commandNotSupported, \"expected a response\")\n}\n\nfunc TestUnsupportedAssociate(t *testing.T) {\n\treq := createRequest(t, socks5Version, associateCommand, \"127.0.0.1\", 1337, false)\n\tvar b bytes.Buffer\n\n\trequestHandler := NewRequestHandler(NewNetDialer(), nil)\n\terr := requestHandler.Handle(req, &b)\n\tassert.NoError(t, err)\n\tassert.True(t, b.Bytes()[1] == commandNotSupported, \"expected a response\")\n}\n\nfunc TestHandleConnect(t *testing.T) {\n\treq := createRequest(t, socks5Version, connectCommand, \"127.0.0.1\", 1337, false)\n\tvar b bytes.Buffer\n\n\trequestHandler := NewRequestHandler(NewNetDialer(), nil)\n\terr := requestHandler.Handle(req, &b)\n\tassert.Error(t, err)\n\tassert.True(t, b.Bytes()[1] == connectionRefused, \"expected a response\")\n}\n\nfunc TestHandleConnectIPAccess(t *testing.T) {\n\tprefix := \"127.0.0.0/24\"\n\trule1, _ := ipaccess.NewRuleByCIDR(&prefix, []int{1337}, true)\n\trule2, _ := ipaccess.NewRuleByCIDR(&prefix, []int{1338}, false)\n\trules := []ipaccess.Rule{rule1, rule2}\n\tvar b bytes.Buffer\n\n\taccessPolicy, _ := ipaccess.NewPolicy(false, nil)\n\trequestHandler := NewRequestHandler(NewNetDialer(), accessPolicy)\n\treq := createRequest(t, socks5Version, connectCommand, \"127.0.0.1\", 1337, false)\n\terr := requestHandler.Handle(req, &b)\n\tassert.Error(t, err)\n\tassert.True(t, b.Bytes()[1] == ruleFailure, \"expected to be denied as no rules and defaultAllow=false\")\n\n\tb.Reset()\n\taccessPolicy, _ = ipaccess.NewPolicy(true, nil)\n\trequestHandler = NewRequestHandler(NewNetDialer(), accessPolicy)\n\treq = createRequest(t, socks5Version, connectCommand, \"127.0.0.1\", 1337, false)\n\terr = requestHandler.Handle(req, &b)\n\tassert.Error(t, err)\n\tassert.True(t, b.Bytes()[1] == connectionRefused, \"expected to be allowed as no rules and defaultAllow=true\")\n\n\tb.Reset()\n\taccessPolicy, _ = ipaccess.NewPolicy(false, rules)\n\trequestHandler = NewRequestHandler(NewNetDialer(), accessPolicy)\n\treq = createRequest(t, socks5Version, connectCommand, \"127.0.0.1\", 1337, false)\n\terr = requestHandler.Handle(req, &b)\n\tassert.Error(t, err)\n\tassert.True(t, b.Bytes()[1] == connectionRefused, \"expected to be allowed as matching rule\")\n\n\tb.Reset()\n\treq = createRequest(t, socks5Version, connectCommand, \"127.0.0.1\", 1338, false)\n\terr = requestHandler.Handle(req, &b)\n\tassert.Error(t, err)\n\tassert.True(t, b.Bytes()[1] == ruleFailure, \"expected to be denied as matching rule\")\n\n\tb.Reset()\n\treq = createRequest(t, socks5Version, connectCommand, \"127.0.0.1\", 1339, false)\n\terr = requestHandler.Handle(req, &b)\n\tassert.Error(t, err)\n\tassert.True(t, b.Bytes()[1] == ruleFailure, \"expect to be denied as no matching rule and defaultAllow=false\")\n}\n"
  },
  {
    "path": "socks/request_test.go",
    "content": "package socks\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"net\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc createRequestData(version, command uint8, ip net.IP, port uint16) []byte {\n\t// set the command\n\tb := []byte{version, command, 0}\n\n\t// append the ip\n\tif len(ip) == net.IPv4len {\n\t\tb = append(b, 1)\n\t\tb = append(b, ip.To4()...)\n\t} else {\n\t\tb = append(b, 4)\n\t\tb = append(b, ip.To16()...)\n\t}\n\n\t// append the port\n\tp := []byte{0, 0}\n\tbinary.BigEndian.PutUint16(p, port)\n\tb = append(b, p...)\n\n\treturn b\n}\n\nfunc createRequest(t *testing.T, version, command uint8, ipStr string, port uint16, shouldFail bool) *Request {\n\tip := net.ParseIP(ipStr)\n\tdata := createRequestData(version, command, ip, port)\n\treader := bytes.NewReader(data)\n\treq, err := NewRequest(reader)\n\tif shouldFail {\n\t\tassert.Error(t, err)\n\t\treturn nil\n\t}\n\tassert.NoError(t, err)\n\tassert.True(t, req.Version == socks5Version, \"version doesn't match expectation: %v\", req.Version)\n\tassert.True(t, req.Command == command, \"command doesn't match expectation: %v\", req.Command)\n\tassert.True(t, req.DestAddr.Port == int(port), \"port doesn't match expectation: %v\", req.DestAddr.Port)\n\tassert.True(t, req.DestAddr.IP.String() == ipStr, \"ip doesn't match expectation: %v\", req.DestAddr.IP.String())\n\n\treturn req\n}\n\nfunc TestValidConnectRequest(t *testing.T) {\n\tcreateRequest(t, socks5Version, connectCommand, \"127.0.0.1\", 1337, false)\n}\n\nfunc TestValidBindRequest(t *testing.T) {\n\tcreateRequest(t, socks5Version, bindCommand, \"2001:db8::68\", 1337, false)\n}\n\nfunc TestValidAssociateRequest(t *testing.T) {\n\tcreateRequest(t, socks5Version, associateCommand, \"127.0.0.1\", 1234, false)\n}\n\nfunc TestInValidVersionRequest(t *testing.T) {\n\tcreateRequest(t, 4, connectCommand, \"127.0.0.1\", 1337, true)\n}\n\nfunc TestInValidIPRequest(t *testing.T) {\n\tcreateRequest(t, 4, connectCommand, \"127.0.01\", 1337, true)\n}\n"
  },
  {
    "path": "sshgen/sshgen.go",
    "content": "package sshgen\n\nimport (\n\t\"bytes\"\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"crypto/x509\"\n\t\"encoding/json\"\n\t\"encoding/pem\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/go-jose/go-jose/v4\"\n\t\"github.com/go-jose/go-jose/v4/jwt\"\n\thomedir \"github.com/mitchellh/go-homedir\"\n\t\"github.com/pkg/errors\"\n\tgossh \"golang.org/x/crypto/ssh\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n\tcfpath \"github.com/cloudflare/cloudflared/token\"\n)\n\nconst (\n\tsignEndpoint = \"/cdn-cgi/access/cert_sign\"\n\tkeyName      = \"cf_key\"\n)\n\n// signPayload represents the request body sent to the sign handler API\ntype signPayload struct {\n\tPublicKey string `json:\"public_key\"`\n\tJWT       string `json:\"jwt\"`\n\tIssuer    string `json:\"issuer\"`\n}\n\n// signResponse represents the response body from the sign handler API\ntype signResponse struct {\n\tKeyID       string    `json:\"id\"`\n\tCertificate string    `json:\"certificate\"`\n\tExpiresAt   time.Time `json:\"expires_at\"`\n}\n\n// ErrorResponse struct stores error information after any error-prone function\ntype errorResponse struct {\n\tStatus  int    `json:\"status\"`\n\tMessage string `json:\"message\"`\n}\n\nvar mockRequest func(url, contentType string, body io.Reader) (*http.Response, error) = nil\n\nvar signatureAlgs = []jose.SignatureAlgorithm{jose.RS256}\n\n// GenerateShortLivedCertificate generates and stores a keypair for short lived certs\nfunc GenerateShortLivedCertificate(appURL *url.URL, token string) error {\n\tfullName, err := cfpath.GenerateSSHCertFilePathFromURL(appURL, keyName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcert, err := handleCertificateGeneration(token, fullName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tname := fullName + \"-cert.pub\"\n\tif err := writeKey(name, []byte(cert)); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// handleCertificateGeneration takes a JWT and uses it build a signPayload\n// to send to the Sign endpoint with the public key from the keypair it generated\nfunc handleCertificateGeneration(token, fullName string) (string, error) {\n\tpub, err := generateKeyPair(fullName)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn SignCert(token, string(pub))\n}\n\nfunc SignCert(token, pubKey string) (string, error) {\n\tif token == \"\" {\n\t\treturn \"\", errors.New(\"invalid token\")\n\t}\n\n\tparsedToken, err := jwt.ParseSigned(token, signatureAlgs)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to parse JWT\")\n\t}\n\n\tclaims := jwt.Claims{}\n\terr = parsedToken.UnsafeClaimsWithoutVerification(&claims)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to retrieve JWT claims\")\n\t}\n\n\tbuf, err := json.Marshal(&signPayload{\n\t\tPublicKey: pubKey,\n\t\tJWT:       token,\n\t\tIssuer:    claims.Issuer,\n\t})\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to marshal signPayload\")\n\t}\n\tvar res *http.Response\n\tif mockRequest != nil {\n\t\tres, err = mockRequest(claims.Issuer+signEndpoint, \"application/json\", bytes.NewBuffer(buf))\n\t} else {\n\t\tclient := http.Client{\n\t\t\tTimeout: 10 * time.Second,\n\t\t}\n\t\tres, err = client.Post(claims.Issuer+signEndpoint, \"application/json\", bytes.NewBuffer(buf))\n\t}\n\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to send request\")\n\t}\n\tdefer res.Body.Close()\n\n\tdecoder := json.NewDecoder(res.Body)\n\n\tif res.StatusCode != 200 {\n\t\tvar errResponse errorResponse\n\t\tif err := decoder.Decode(&errResponse); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\treturn \"\", fmt.Errorf(\"%d: %s\", errResponse.Status, errResponse.Message)\n\t}\n\n\tvar signRes signResponse\n\tif err := decoder.Decode(&signRes); err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to decode HTTP response\")\n\t}\n\treturn signRes.Certificate, nil\n}\n\n// generateKeyPair creates a EC keypair (P256) and stores them in the homedir.\n// returns the generated public key from the successful keypair generation\nfunc generateKeyPair(fullName string) ([]byte, error) {\n\tpubKeyName := fullName + \".pub\"\n\n\texist, err := config.FileExists(pubKeyName)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif exist {\n\t\treturn os.ReadFile(pubKeyName)\n\t}\n\n\tkey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tparsed, err := x509.MarshalECPrivateKey(key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := writeKey(fullName, pem.EncodeToMemory(&pem.Block{\n\t\tType:  \"EC PRIVATE KEY\",\n\t\tBytes: parsed,\n\t})); err != nil {\n\t\treturn nil, err\n\t}\n\n\tpub, err := gossh.NewPublicKey(&key.PublicKey)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdata := gossh.MarshalAuthorizedKey(pub)\n\n\tif err := writeKey(pubKeyName, data); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn data, nil\n}\n\n// writeKey will write a key to disk in DER format (it's a standard pem key)\nfunc writeKey(filename string, data []byte) error {\n\tfilepath, err := homedir.Expand(filename)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn os.WriteFile(filepath, data, 0600)\n}\n"
  },
  {
    "path": "sshgen/sshgen_test.go",
    "content": "//go:build !windows\n\npackage sshgen\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"net/url\"\n\t\"os\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/go-jose/go-jose/v4\"\n\t\"github.com/go-jose/go-jose/v4/jwt\"\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n\tcfpath \"github.com/cloudflare/cloudflared/token\"\n)\n\nconst (\n\taudTest   = \"cf-test-aud\"\n\tnonceTest = \"asfd\"\n)\n\ntype signingArguments struct {\n\tPrincipals   []string `json:\"principals\"`\n\tClientPubKey string   `json:\"public_key\"`\n\tDuration     string   `json:\"duration\"`\n}\n\nfunc TestCertGenSuccess(t *testing.T) {\n\turl, _ := url.Parse(\"https://cf-test-access.com/testpath\")\n\ttoken := tokenGenerator()\n\n\tfullName, err := cfpath.GenerateSSHCertFilePathFromURL(url, keyName)\n\tassert.NoError(t, err)\n\tassert.True(t, strings.HasSuffix(fullName, \"/cf-test-access.com-testpath-cf_key\"))\n\n\tpubKeyName := fullName + \".pub\"\n\tcertKeyName := fullName + \"-cert.pub\"\n\n\tdefer func() {\n\t\tos.Remove(fullName)\n\t\tos.Remove(pubKeyName)\n\t\tos.Remove(certKeyName)\n\t}()\n\n\tresp := signingArguments{\n\t\tPrincipals:   []string{\"dalton\"},\n\t\tClientPubKey: \"ecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg+0rYq4mNGIAHiH1xPOJXfmOpTEwFIcyXzGJieTOhRs8AAAAIbmlzdHAyNTYAAABBBJIcsq02e8ZaofJXOZKp7yQdKW/JIouJ90lybr76hHIRrZBL1t4JEimfLvNDphPrTW9VDQaIcBSKNaxRqHOS8jezoJbhFGWhqQAAAAEAAAAgZWU5OTliNGRkZmFmNjgxNDEwMTVhMDJiY2ZhMTdiN2UAAAAKAAAABmF1c3RpbgAAAABc1KFoAAAAAFzUohwAAAAAAAAARwAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAAGgAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAAhuaXN0cDI1NgAAAEEEeAuYR56XaxvH5Z1p0hDCTQ7wC4dbj0Gc+LOKu1f94og2ilZTv9tutg8cZrqAT97REmGH6j9KIOVLGsPVjajSKAAAAGQAAAATZWNkc2Etc2hhMi1uaXN0cDI1NgAAAEkAAAAhAORY9ZO3TQsrUm6ajnVW+arbnVfTkxYBYFlVoeOEXKZuAAAAIG96A8nQnTuprWXLSemWL68RXC1NVKnBOIPD2Z7UIOB1\",\n\t\tDuration:     \"3m\",\n\t}\n\tw := httptest.NewRecorder()\n\trespJson, err := json.Marshal(resp)\n\tassert.NoError(t, err)\n\tw.Write(respJson)\n\tmockRequest = func(url, contentType string, body io.Reader) (*http.Response, error) {\n\t\tassert.Contains(t, \"/cdn-cgi/access/cert_sign\", url)\n\t\tassert.Equal(t, \"application/json\", contentType)\n\t\tbuf, err := io.ReadAll(body)\n\t\tassert.NoError(t, err)\n\t\tassert.NotEmpty(t, buf)\n\t\treturn w.Result(), nil\n\t}\n\n\terr = GenerateShortLivedCertificate(url, token)\n\tassert.NoError(t, err)\n\n\texist, err := config.FileExists(fullName)\n\tassert.NoError(t, err)\n\tif !exist {\n\t\tassert.FailNow(t, fmt.Sprintf(\"key should exist at: %s\", fullName), fullName)\n\t\treturn\n\t}\n\n\texist, err = config.FileExists(pubKeyName)\n\tassert.NoError(t, err)\n\tif !exist {\n\t\tassert.FailNow(t, fmt.Sprintf(\"key should exist at: %s\", pubKeyName), pubKeyName)\n\t\treturn\n\t}\n\n\texist, err = config.FileExists(certKeyName)\n\tassert.NoError(t, err)\n\tif !exist {\n\t\tassert.FailNow(t, fmt.Sprintf(\"key should exist at: %s\", certKeyName), certKeyName)\n\t\treturn\n\t}\n}\n\nfunc tokenGenerator() string {\n\tiat := time.Now()\n\texp := time.Now().Add(time.Minute * 5)\n\n\tclaims := jwt.Claims{\n\t\tAudience: jwt.Audience{audTest},\n\t\tIssuedAt: jwt.NewNumericDate(iat),\n\t\tExpiry:   jwt.NewNumericDate(exp),\n\t}\n\n\tkey, err := rsa.GenerateKey(rand.Reader, 4096)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tsigner, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.RS256, Key: key}, (&jose.SignerOptions{}).WithType(\"JWT\"))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tsignedToken, err := jwt.Signed(signer).Claims(claims).Serialize()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treturn signedToken\n}\n"
  },
  {
    "path": "stream/debug.go",
    "content": "package stream\n\nimport (\n\t\"io\"\n\t\"sync/atomic\"\n\n\t\"github.com/rs/zerolog\"\n)\n\n// DebugStream will tee each read and write to the output logger as a debug message\ntype DebugStream struct {\n\treader io.Reader\n\twriter io.Writer\n\tlog    *zerolog.Logger\n\tmax    uint64\n\tcount  atomic.Uint64\n}\n\nfunc NewDebugStream(stream io.ReadWriter, logger *zerolog.Logger, max uint64) *DebugStream {\n\treturn &DebugStream{\n\t\treader: stream,\n\t\twriter: stream,\n\t\tlog:    logger,\n\t\tmax:    max,\n\t}\n}\n\nfunc (d *DebugStream) Read(p []byte) (n int, err error) {\n\tn, err = d.reader.Read(p)\n\tif n > 0 && d.max > d.count.Load() {\n\t\td.count.Add(1)\n\t\tif err != nil {\n\t\t\td.log.Err(err).\n\t\t\t\tStr(\"dir\", \"r\").\n\t\t\t\tInt(\"count\", n).\n\t\t\t\tMsgf(\"%+q\", p[:n])\n\t\t} else {\n\t\t\td.log.Debug().\n\t\t\t\tStr(\"dir\", \"r\").\n\t\t\t\tInt(\"count\", n).\n\t\t\t\tMsgf(\"%+q\", p[:n])\n\t\t}\n\t}\n\treturn\n}\n\nfunc (d *DebugStream) Write(p []byte) (n int, err error) {\n\tn, err = d.writer.Write(p)\n\tif n > 0 && d.max > d.count.Load() {\n\t\td.count.Add(1)\n\t\tif err != nil {\n\t\t\td.log.Err(err).\n\t\t\t\tStr(\"dir\", \"w\").\n\t\t\t\tInt(\"count\", n).\n\t\t\t\tMsgf(\"%+q\", p[:n])\n\t\t} else {\n\t\t\td.log.Debug().\n\t\t\t\tStr(\"dir\", \"w\").\n\t\t\t\tInt(\"count\", n).\n\t\t\t\tMsgf(\"%+q\", p[:n])\n\t\t}\n\t}\n\treturn\n}\n"
  },
  {
    "path": "stream/stream.go",
    "content": "package stream\n\nimport (\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"io\"\n\t\"runtime/debug\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/cfio\"\n)\n\ntype Stream interface {\n\tReader\n\tWriterCloser\n}\n\ntype Reader interface {\n\tio.Reader\n}\n\ntype WriterCloser interface {\n\tio.Writer\n\tWriteCloser\n}\n\ntype WriteCloser interface {\n\tCloseWrite() error\n}\n\ntype nopCloseWriterAdapter struct {\n\tio.ReadWriter\n}\n\nfunc NopCloseWriterAdapter(stream io.ReadWriter) *nopCloseWriterAdapter {\n\treturn &nopCloseWriterAdapter{stream}\n}\n\nfunc (n *nopCloseWriterAdapter) CloseWrite() error {\n\treturn nil\n}\n\ntype bidirectionalStreamStatus struct {\n\tdoneChan chan struct{}\n\tanyDone  uint32\n}\n\nfunc newBiStreamStatus() *bidirectionalStreamStatus {\n\treturn &bidirectionalStreamStatus{\n\t\tdoneChan: make(chan struct{}, 2),\n\t\tanyDone:  0,\n\t}\n}\n\nfunc (s *bidirectionalStreamStatus) markUniStreamDone() {\n\tatomic.StoreUint32(&s.anyDone, 1)\n\ts.doneChan <- struct{}{}\n}\n\nfunc (s *bidirectionalStreamStatus) wait(maxWaitForSecondStream time.Duration) error {\n\t<-s.doneChan\n\n\t// Only wait for second stream to finish if maxWait is greater than zero\n\tif maxWaitForSecondStream > 0 {\n\n\t\ttimer := time.NewTimer(maxWaitForSecondStream)\n\t\tdefer timer.Stop()\n\n\t\tselect {\n\t\tcase <-timer.C:\n\t\t\treturn fmt.Errorf(\"timeout waiting for second stream to finish\")\n\t\tcase <-s.doneChan:\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn nil\n}\nfunc (s *bidirectionalStreamStatus) isAnyDone() bool {\n\treturn atomic.LoadUint32(&s.anyDone) > 0\n}\n\n// Pipe copies copy data to & from provided io.ReadWriters.\nfunc Pipe(tunnelConn, originConn io.ReadWriter, log *zerolog.Logger) {\n\tPipeBidirectional(NopCloseWriterAdapter(tunnelConn), NopCloseWriterAdapter(originConn), 0, log)\n}\n\n// PipeBidirectional copies data two BidirectionStreams. It is a special case of Pipe where it receives a concept that allows for Read and Write side to be closed independently.\n// The main difference is that when piping data from a reader to a writer, if EOF is read, then this implementation propagates the EOF signal to the destination/writer by closing the write side of the\n// Bidirectional Stream.\n// Finally, depending on once EOF is ready from one of the provided streams, the other direction of streaming data will have a configured time period to also finish, otherwise,\n// the method will return immediately  with a timeout error. It is however, the responsability of the caller to close the associated streams in both ends in order to free all the resources/go-routines.\nfunc PipeBidirectional(downstream, upstream Stream, maxWaitForSecondStream time.Duration, log *zerolog.Logger) error {\n\tstatus := newBiStreamStatus()\n\n\tgo unidirectionalStream(downstream, upstream, \"upstream->downstream\", status, log)\n\tgo unidirectionalStream(upstream, downstream, \"downstream->upstream\", status, log)\n\n\tif err := status.wait(maxWaitForSecondStream); err != nil {\n\t\treturn errors.Wrap(err, \"unable to wait for both streams while proxying\")\n\t}\n\n\treturn nil\n}\n\nfunc unidirectionalStream(dst WriterCloser, src Reader, dir string, status *bidirectionalStreamStatus, log *zerolog.Logger) {\n\tdefer func() {\n\t\t// The bidirectional streaming spawns 2 goroutines to stream each direction.\n\t\t// If any ends, the callstack returns, meaning the Tunnel request/stream (depending on http2 vs quic) will\n\t\t// close. In such case, if the other direction did not stop (due to application level stopping, e.g., if a\n\t\t// server/origin listens forever until closure), it may read/write from the underlying ReadWriter (backed by\n\t\t// the Edge<->cloudflared transport) in an unexpected state.\n\t\t// Because of this, we set this recover() logic.\n\t\tif err := recover(); err != nil {\n\t\t\tif status.isAnyDone() {\n\t\t\t\t// We handle such unexpected errors only when we detect that one side of the streaming is done.\n\t\t\t\tlog.Debug().Msgf(\"recovered from panic in stream.Pipe for %s, error %s, %s\", dir, err, debug.Stack())\n\t\t\t} else {\n\t\t\t\t// Otherwise, this is unexpected, but we prevent the program from crashing anyway.\n\t\t\t\tlog.Warn().Msgf(\"recovered from panic in stream.Pipe for %s, error %s, %s\", dir, err, debug.Stack())\n\t\t\t\tsentry.CurrentHub().Recover(err)\n\t\t\t\tsentry.Flush(time.Second * 5)\n\t\t\t}\n\t\t}\n\t}()\n\n\tdefer dst.CloseWrite()\n\n\t_, err := copyData(dst, src, dir)\n\tif err != nil {\n\t\tlog.Debug().Msgf(\"%s copy: %v\", dir, err)\n\t}\n\tstatus.markUniStreamDone()\n}\n\n// when set to true, enables logging of content copied to/from origin and tunnel\nconst debugCopy = false\n\nfunc copyData(dst io.Writer, src io.Reader, dir string) (written int64, err error) {\n\tif debugCopy {\n\t\t// copyBuffer is based on stdio Copy implementation but shows copied data\n\t\tcopyBuffer := func(dst io.Writer, src io.Reader, dir string) (written int64, err error) {\n\t\t\tvar buf []byte\n\t\t\tsize := 32 * 1024\n\t\t\tbuf = make([]byte, size)\n\t\t\tfor {\n\t\t\t\tt := time.Now()\n\t\t\t\tnr, er := src.Read(buf)\n\t\t\t\tif nr > 0 {\n\t\t\t\t\tfmt.Println(dir, t.UnixNano(), \"\\n\"+hex.Dump(buf[0:nr]))\n\t\t\t\t\tnw, ew := dst.Write(buf[0:nr])\n\t\t\t\t\tif nw < 0 || nr < nw {\n\t\t\t\t\t\tnw = 0\n\t\t\t\t\t\tif ew == nil {\n\t\t\t\t\t\t\tew = errors.New(\"invalid write\")\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\twritten += int64(nw)\n\t\t\t\t\tif ew != nil {\n\t\t\t\t\t\terr = ew\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tif nr != nw {\n\t\t\t\t\t\terr = io.ErrShortWrite\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif er != nil {\n\t\t\t\t\tif er != io.EOF {\n\t\t\t\t\t\terr = er\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn written, err\n\t\t}\n\t\treturn copyBuffer(dst, src, dir)\n\t} else {\n\t\treturn cfio.Copy(dst, src)\n\t}\n}\n"
  },
  {
    "path": "stream/stream_test.go",
    "content": "package stream\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestPipeBidirectionalFinishBothSides(t *testing.T) {\n\tfun := func(upstream, downstream *mockedStream) {\n\t\tdownstream.closeReader()\n\t\tupstream.closeReader()\n\t}\n\n\ttestPipeBidirectionalUnblocking(t, fun, time.Millisecond*200, false)\n}\n\nfunc TestPipeBidirectionalFinishOneSideTimeout(t *testing.T) {\n\tfun := func(upstream, downstream *mockedStream) {\n\t\tdownstream.closeReader()\n\t}\n\n\ttestPipeBidirectionalUnblocking(t, fun, time.Millisecond*200, true)\n}\n\nfunc TestPipeBidirectionalClosingWriteBothSidesAlsoExists(t *testing.T) {\n\tfun := func(upstream, downstream *mockedStream) {\n\t\tdownstream.CloseWrite()\n\t\tupstream.CloseWrite()\n\n\t\tdownstream.writeToReader(\"abc\")\n\t\tupstream.writeToReader(\"abc\")\n\t}\n\n\ttestPipeBidirectionalUnblocking(t, fun, time.Millisecond*200, false)\n}\n\nfunc TestPipeBidirectionalClosingWriteSingleSideAlsoExists(t *testing.T) {\n\tfun := func(upstream, downstream *mockedStream) {\n\t\tdownstream.CloseWrite()\n\n\t\tdownstream.writeToReader(\"abc\")\n\t\tupstream.writeToReader(\"abc\")\n\t}\n\n\ttestPipeBidirectionalUnblocking(t, fun, time.Millisecond*200, true)\n}\n\nfunc testPipeBidirectionalUnblocking(t *testing.T, afterFun func(*mockedStream, *mockedStream), timeout time.Duration, expectTimeout bool) {\n\tlogger := zerolog.Nop()\n\n\tdownstream := newMockedStream()\n\tupstream := newMockedStream()\n\n\tresultCh := make(chan error)\n\tgo func() {\n\t\tresultCh <- PipeBidirectional(downstream, upstream, timeout, &logger)\n\t}()\n\n\tafterFun(upstream, downstream)\n\n\tselect {\n\tcase err := <-resultCh:\n\t\tif expectTimeout {\n\t\t\trequire.NotNil(t, err)\n\t\t} else {\n\t\t\trequire.Nil(t, err)\n\t\t}\n\n\tcase <-time.After(timeout * 2):\n\t\trequire.Fail(t, \"test timeout\")\n\t}\n}\n\nfunc newMockedStream() *mockedStream {\n\treturn &mockedStream{\n\t\treadCh:  make(chan *string),\n\t\twriteCh: make(chan struct{}),\n\t}\n}\n\ntype mockedStream struct {\n\treadCh  chan *string\n\twriteCh chan struct{}\n\n\twriteCloseOnce sync.Once\n}\n\nfunc (m *mockedStream) Read(p []byte) (n int, err error) {\n\tresult := <-m.readCh\n\tif result == nil {\n\t\treturn 0, io.EOF\n\t}\n\n\treturn len(*result), nil\n}\n\nfunc (m *mockedStream) Write(p []byte) (n int, err error) {\n\t<-m.writeCh\n\n\treturn 0, fmt.Errorf(\"closed\")\n}\n\nfunc (m *mockedStream) CloseWrite() error {\n\tm.writeCloseOnce.Do(func() {\n\t\tclose(m.writeCh)\n\t})\n\n\treturn nil\n}\n\nfunc (m *mockedStream) closeReader() {\n\tclose(m.readCh)\n}\nfunc (m *mockedStream) writeToReader(content string) {\n\tm.readCh <- &content\n}\n"
  },
  {
    "path": "supervisor/conn_aware_logger.go",
    "content": "package supervisor\n\nimport (\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/connection\"\n\t\"github.com/cloudflare/cloudflared/tunnelstate\"\n)\n\ntype ConnAwareLogger struct {\n\ttracker *tunnelstate.ConnTracker\n\tlogger  *zerolog.Logger\n}\n\nfunc NewConnAwareLogger(logger *zerolog.Logger, tracker *tunnelstate.ConnTracker, observer *connection.Observer) *ConnAwareLogger {\n\tconnAwareLogger := &ConnAwareLogger{\n\t\ttracker: tracker,\n\t\tlogger:  logger,\n\t}\n\n\tobserver.RegisterSink(connAwareLogger.tracker)\n\n\treturn connAwareLogger\n}\n\nfunc (c *ConnAwareLogger) ReplaceLogger(logger *zerolog.Logger) *ConnAwareLogger {\n\treturn &ConnAwareLogger{\n\t\ttracker: c.tracker,\n\t\tlogger:  logger,\n\t}\n}\n\nfunc (c *ConnAwareLogger) ConnAwareLogger() *zerolog.Event {\n\tif c.tracker.CountActiveConns() == 0 {\n\t\treturn c.logger.Error()\n\t}\n\treturn c.logger.Warn()\n}\n\nfunc (c *ConnAwareLogger) Logger() *zerolog.Logger {\n\treturn c.logger\n}\n"
  },
  {
    "path": "supervisor/external_control.go",
    "content": "package supervisor\n\nimport (\n\t\"time\"\n)\n\ntype ReconnectSignal struct {\n\t// wait this many seconds before re-establish the connection\n\tDelay time.Duration\n}\n\n// Error allows us to use ReconnectSignal as a special error to force connection abort\nfunc (r ReconnectSignal) Error() string {\n\treturn \"reconnect signal\"\n}\n\nfunc (r ReconnectSignal) DelayBeforeReconnect() {\n\tif r.Delay > 0 {\n\t\ttime.Sleep(r.Delay)\n\t}\n}\n"
  },
  {
    "path": "supervisor/fuse.go",
    "content": "package supervisor\n\nimport \"sync\"\n\n// booleanFuse is a data structure that can be set once to a particular value using Fuse(value).\n// Subsequent calls to Fuse() will have no effect.\ntype booleanFuse struct {\n\tvalue int32\n\tmu    sync.Mutex\n\tcond  *sync.Cond\n}\n\nfunc newBooleanFuse() *booleanFuse {\n\tf := &booleanFuse{}\n\tf.cond = sync.NewCond(&f.mu)\n\treturn f\n}\n\n// Value gets the value\nfunc (f *booleanFuse) Value() bool {\n\t// 0: unset\n\t// 1: set true\n\t// 2: set false\n\tf.mu.Lock()\n\tdefer f.mu.Unlock()\n\treturn f.value == 1\n}\n\nfunc (f *booleanFuse) Fuse(result bool) {\n\tf.mu.Lock()\n\tdefer f.mu.Unlock()\n\tnewValue := int32(2)\n\tif result {\n\t\tnewValue = 1\n\t}\n\tif f.value == 0 {\n\t\tf.value = newValue\n\t\tf.cond.Broadcast()\n\t}\n}\n\n// Await blocks until Fuse has been called at least once.\nfunc (f *booleanFuse) Await() bool {\n\tf.mu.Lock()\n\tdefer f.mu.Unlock()\n\tfor f.value == 0 {\n\t\tf.cond.Wait()\n\t}\n\treturn f.value == 1\n}\n"
  },
  {
    "path": "supervisor/metrics.go",
    "content": "package supervisor\n\nimport (\n\t\"github.com/prometheus/client_golang/prometheus\"\n\n\t\"github.com/cloudflare/cloudflared/connection\"\n)\n\n// Metrics uses connection.MetricsNamespace(aka cloudflared) as namespace and connection.TunnelSubsystem\n// (tunnel) as subsystem to keep them consistent with the previous qualifier.\n\nvar (\n\thaConnections = prometheus.NewGauge(\n\t\tprometheus.GaugeOpts{\n\t\t\tNamespace: connection.MetricsNamespace,\n\t\t\tSubsystem: connection.TunnelSubsystem,\n\t\t\tName:      \"ha_connections\",\n\t\t\tHelp:      \"Number of active ha connections\",\n\t\t},\n\t)\n)\n\nfunc init() {\n\tprometheus.MustRegister(\n\t\thaConnections,\n\t)\n}\n"
  },
  {
    "path": "supervisor/pqtunnels.go",
    "content": "package supervisor\n\nimport (\n\t\"crypto/tls\"\n\t\"fmt\"\n\n\t\"github.com/cloudflare/cloudflared/features\"\n)\n\nconst (\n\tX25519Kyber768Draft00PQKex     = tls.CurveID(0x6399) // X25519Kyber768Draft00\n\tX25519Kyber768Draft00PQKexName = \"X25519Kyber768Draft00\"\n\tP256Kyber768Draft00PQKex       = tls.CurveID(0xfe32) // P256Kyber768Draft00\n\tP256Kyber768Draft00PQKexName   = \"P256Kyber768Draft00\"\n\tX25519MLKEM768PQKex            = tls.CurveID(0x11ec) // X25519MLKEM768\n\tX25519MLKEM768PQKexName        = \"X25519MLKEM768\"\n)\n\nvar (\n\tnonFipsPostQuantumStrictPKex []tls.CurveID = []tls.CurveID{X25519MLKEM768PQKex}\n\tnonFipsPostQuantumPreferPKex []tls.CurveID = []tls.CurveID{X25519MLKEM768PQKex}\n\tfipsPostQuantumStrictPKex    []tls.CurveID = []tls.CurveID{P256Kyber768Draft00PQKex}\n\tfipsPostQuantumPreferPKex    []tls.CurveID = []tls.CurveID{P256Kyber768Draft00PQKex, tls.CurveP256}\n)\n\nfunc removeDuplicates(curves []tls.CurveID) []tls.CurveID {\n\tbucket := make(map[tls.CurveID]bool)\n\tvar result []tls.CurveID\n\tfor _, curve := range curves {\n\t\tif _, ok := bucket[curve]; !ok {\n\t\t\tbucket[curve] = true\n\t\t\tresult = append(result, curve)\n\t\t}\n\t}\n\treturn result\n}\n\nfunc curvePreference(pqMode features.PostQuantumMode, fipsEnabled bool, currentCurve []tls.CurveID) ([]tls.CurveID, error) {\n\tswitch pqMode {\n\tcase features.PostQuantumStrict:\n\t\t// If the user passes the -post-quantum flag, we override\n\t\t// CurvePreferences to only support hybrid post-quantum key agreements.\n\t\tif fipsEnabled {\n\t\t\treturn fipsPostQuantumStrictPKex, nil\n\t\t}\n\t\treturn nonFipsPostQuantumStrictPKex, nil\n\tcase features.PostQuantumPrefer:\n\t\tif fipsEnabled {\n\t\t\t// Ensure that all curves returned are FIPS compliant.\n\t\t\t// Moreover the first curves are post-quantum and then the\n\t\t\t// non post-quantum.\n\t\t\treturn fipsPostQuantumPreferPKex, nil\n\t\t}\n\t\tcurves := append(nonFipsPostQuantumPreferPKex, currentCurve...)\n\t\tcurves = removeDuplicates(curves)\n\t\treturn curves, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"Unexpected post quantum mode\")\n\t}\n}\n"
  },
  {
    "path": "supervisor/pqtunnels_test.go",
    "content": "package supervisor\n\nimport (\n\t\"crypto/tls\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"slices\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/cloudflare/cloudflared/features\"\n\t\"github.com/cloudflare/cloudflared/fips\"\n)\n\nfunc TestCurvePreferences(t *testing.T) {\n\t// This tests if the correct curves are returned\n\t// given a PostQuantumMode and a FIPS enabled bool\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname           string\n\t\tcurrentCurves  []tls.CurveID\n\t\texpectedCurves []tls.CurveID\n\t\tpqMode         features.PostQuantumMode\n\t\tfipsEnabled    bool\n\t}{\n\t\t{\n\t\t\tname:           \"FIPS with Prefer PQ\",\n\t\t\tpqMode:         features.PostQuantumPrefer,\n\t\t\tfipsEnabled:    true,\n\t\t\tcurrentCurves:  []tls.CurveID{tls.CurveP384},\n\t\t\texpectedCurves: []tls.CurveID{P256Kyber768Draft00PQKex, tls.CurveP256},\n\t\t},\n\t\t{\n\t\t\tname:           \"FIPS with Strict PQ\",\n\t\t\tpqMode:         features.PostQuantumStrict,\n\t\t\tfipsEnabled:    true,\n\t\t\tcurrentCurves:  []tls.CurveID{tls.CurveP256, tls.CurveP384},\n\t\t\texpectedCurves: []tls.CurveID{P256Kyber768Draft00PQKex},\n\t\t},\n\t\t{\n\t\t\tname:           \"FIPS with Prefer PQ - no duplicates\",\n\t\t\tpqMode:         features.PostQuantumPrefer,\n\t\t\tfipsEnabled:    true,\n\t\t\tcurrentCurves:  []tls.CurveID{tls.CurveP256},\n\t\t\texpectedCurves: []tls.CurveID{P256Kyber768Draft00PQKex, tls.CurveP256},\n\t\t},\n\t\t{\n\t\t\tname:           \"Non FIPS with Prefer PQ\",\n\t\t\tpqMode:         features.PostQuantumPrefer,\n\t\t\tfipsEnabled:    false,\n\t\t\tcurrentCurves:  []tls.CurveID{tls.CurveP256},\n\t\t\texpectedCurves: []tls.CurveID{X25519MLKEM768PQKex, tls.CurveP256},\n\t\t},\n\t\t{\n\t\t\tname:           \"Non FIPS with Prefer PQ - no duplicates\",\n\t\t\tpqMode:         features.PostQuantumPrefer,\n\t\t\tfipsEnabled:    false,\n\t\t\tcurrentCurves:  []tls.CurveID{X25519Kyber768Draft00PQKex, tls.CurveP256},\n\t\t\texpectedCurves: []tls.CurveID{X25519MLKEM768PQKex, X25519Kyber768Draft00PQKex, tls.CurveP256},\n\t\t},\n\t\t{\n\t\t\tname:           \"Non FIPS with Prefer PQ - correct preference order\",\n\t\t\tpqMode:         features.PostQuantumPrefer,\n\t\t\tfipsEnabled:    false,\n\t\t\tcurrentCurves:  []tls.CurveID{tls.CurveP256, X25519Kyber768Draft00PQKex},\n\t\t\texpectedCurves: []tls.CurveID{X25519MLKEM768PQKex, tls.CurveP256, X25519Kyber768Draft00PQKex},\n\t\t},\n\t\t{\n\t\t\tname:           \"Non FIPS with Strict PQ\",\n\t\t\tpqMode:         features.PostQuantumStrict,\n\t\t\tfipsEnabled:    false,\n\t\t\tcurrentCurves:  []tls.CurveID{tls.CurveP256},\n\t\t\texpectedCurves: []tls.CurveID{X25519MLKEM768PQKex},\n\t\t},\n\t}\n\n\tfor _, tcase := range tests {\n\t\tt.Run(tcase.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tcurves, err := curvePreference(tcase.pqMode, tcase.fipsEnabled, tcase.currentCurves)\n\t\t\trequire.NoError(t, err)\n\t\t\tassert.Equal(t, tcase.expectedCurves, curves)\n\t\t})\n\t}\n}\n\nfunc runClientServerHandshake(t *testing.T, curves []tls.CurveID) []tls.CurveID {\n\tvar advertisedCurves []tls.CurveID\n\tts := httptest.NewUnstartedServer(nil)\n\tts.TLS = &tls.Config{ // nolint: gosec\n\t\tGetConfigForClient: func(chi *tls.ClientHelloInfo) (*tls.Config, error) {\n\t\t\tadvertisedCurves = slices.Clone(chi.SupportedCurves)\n\t\t\treturn nil, nil\n\t\t},\n\t}\n\tts.StartTLS()\n\tdefer ts.Close()\n\tclientTlsConfig := ts.Client().Transport.(*http.Transport).TLSClientConfig\n\tclientTlsConfig.CurvePreferences = curves\n\tresp, err := ts.Client().Head(ts.URL)\n\tif err != nil {\n\t\tt.Error(err)\n\t\treturn nil\n\t}\n\tdefer resp.Body.Close()\n\treturn advertisedCurves\n}\n\nfunc TestSupportedCurvesNegotiation(t *testing.T) {\n\tfor _, tcase := range []features.PostQuantumMode{features.PostQuantumPrefer} {\n\t\tcurves, err := curvePreference(tcase, fips.IsFipsEnabled(), make([]tls.CurveID, 0))\n\t\trequire.NoError(t, err)\n\t\tadvertisedCurves := runClientServerHandshake(t, curves)\n\t\tassert.Equal(t, curves, advertisedCurves)\n\t}\n}\n"
  },
  {
    "path": "supervisor/supervisor.go",
    "content": "package supervisor\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"github.com/quic-go/quic-go\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/connection\"\n\t\"github.com/cloudflare/cloudflared/edgediscovery\"\n\t\"github.com/cloudflare/cloudflared/orchestration\"\n\tv3 \"github.com/cloudflare/cloudflared/quic/v3\"\n\t\"github.com/cloudflare/cloudflared/retry\"\n\t\"github.com/cloudflare/cloudflared/signal\"\n\t\"github.com/cloudflare/cloudflared/tunnelstate\"\n)\n\nconst (\n\t// Waiting time before retrying a failed tunnel connection\n\ttunnelRetryDuration = time.Second * 10\n\t// Interval between registering new tunnels\n\tregistrationInterval = time.Second\n)\n\n// Supervisor manages non-declarative tunnels. Establishes TCP connections with the edge, and\n// reconnects them if they disconnect.\ntype Supervisor struct {\n\tconfig                  *TunnelConfig\n\torchestrator            *orchestration.Orchestrator\n\tedgeIPs                 *edgediscovery.Edge\n\tedgeTunnelServer        TunnelServer\n\ttunnelErrors            chan tunnelError\n\ttunnelsConnecting       map[int]chan struct{}\n\ttunnelsProtocolFallback map[int]*protocolFallback\n\t// nextConnectedIndex and nextConnectedSignal are used to wait for all\n\t// currently-connecting tunnels to finish connecting so we can reset backoff timer\n\tnextConnectedIndex  int\n\tnextConnectedSignal chan struct{}\n\n\tlog          *ConnAwareLogger\n\tlogTransport *zerolog.Logger\n\n\treconnectCh       chan ReconnectSignal\n\tgracefulShutdownC <-chan struct{}\n}\n\nvar errEarlyShutdown = errors.New(\"shutdown started\")\n\ntype tunnelError struct {\n\tindex int\n\terr   error\n}\n\nfunc NewSupervisor(config *TunnelConfig, orchestrator *orchestration.Orchestrator, reconnectCh chan ReconnectSignal, gracefulShutdownC <-chan struct{}) (*Supervisor, error) {\n\tisStaticEdge := len(config.EdgeAddrs) > 0\n\n\tvar err error\n\tvar edgeIPs *edgediscovery.Edge\n\tif isStaticEdge { // static edge addresses\n\t\tedgeIPs, err = edgediscovery.StaticEdge(config.Log, config.EdgeAddrs)\n\t} else {\n\t\tedgeIPs, err = edgediscovery.ResolveEdge(config.Log, config.Region, config.EdgeIPVersion)\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttracker := tunnelstate.NewConnTracker(config.Log)\n\tlog := NewConnAwareLogger(config.Log, tracker, config.Observer)\n\n\tedgeAddrHandler := NewIPAddrFallback(config.MaxEdgeAddrRetries)\n\tedgeBindAddr := config.EdgeBindAddr\n\n\tdatagramMetrics := v3.NewMetrics(prometheus.DefaultRegisterer)\n\n\tsessionManager := v3.NewSessionManager(datagramMetrics, config.Log, config.OriginDialerService, orchestrator.GetFlowLimiter())\n\n\tedgeTunnelServer := EdgeTunnelServer{\n\t\tconfig:            config,\n\t\torchestrator:      orchestrator,\n\t\tsessionManager:    sessionManager,\n\t\tdatagramMetrics:   datagramMetrics,\n\t\tedgeAddrs:         edgeIPs,\n\t\tedgeAddrHandler:   edgeAddrHandler,\n\t\tedgeBindAddr:      edgeBindAddr,\n\t\ttracker:           tracker,\n\t\treconnectCh:       reconnectCh,\n\t\tgracefulShutdownC: gracefulShutdownC,\n\t\tconnAwareLogger:   log,\n\t}\n\n\treturn &Supervisor{\n\t\tconfig:                  config,\n\t\torchestrator:            orchestrator,\n\t\tedgeIPs:                 edgeIPs,\n\t\tedgeTunnelServer:        &edgeTunnelServer,\n\t\ttunnelErrors:            make(chan tunnelError),\n\t\ttunnelsConnecting:       map[int]chan struct{}{},\n\t\ttunnelsProtocolFallback: map[int]*protocolFallback{},\n\t\tlog:                     log,\n\t\tlogTransport:            config.LogTransport,\n\t\treconnectCh:             reconnectCh,\n\t\tgracefulShutdownC:       gracefulShutdownC,\n\t}, nil\n}\n\nfunc (s *Supervisor) Run(\n\tctx context.Context,\n\tconnectedSignal *signal.Signal,\n) error {\n\tif s.config.ICMPRouterServer != nil {\n\t\tgo func() {\n\t\t\tif err := s.config.ICMPRouterServer.Serve(ctx); err != nil {\n\t\t\t\tif errors.Is(err, net.ErrClosed) {\n\t\t\t\t\ts.log.Logger().Info().Err(err).Msg(\"icmp router terminated\")\n\t\t\t\t} else {\n\t\t\t\t\ts.log.Logger().Err(err).Msg(\"icmp router terminated\")\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\t}\n\n\t// Setup DNS Resolver refresh\n\tgo s.config.OriginDNSService.StartRefreshLoop(ctx)\n\n\tif err := s.initialize(ctx, connectedSignal); err != nil {\n\t\tif err == errEarlyShutdown {\n\t\t\treturn nil\n\t\t}\n\t\ts.log.Logger().Error().Err(err).Msg(\"initial tunnel connection failed\")\n\t\treturn err\n\t}\n\tvar tunnelsWaiting []int\n\ttunnelsActive := s.config.HAConnections\n\n\tbackoff := retry.NewBackoff(s.config.Retries, tunnelRetryDuration, true)\n\tvar backoffTimer <-chan time.Time\n\n\tshuttingDown := false\n\tfor {\n\t\tselect {\n\t\t// Context cancelled\n\t\tcase <-ctx.Done():\n\t\t\tfor tunnelsActive > 0 {\n\t\t\t\t<-s.tunnelErrors\n\t\t\t\ttunnelsActive--\n\t\t\t}\n\t\t\treturn nil\n\t\t// startTunnel completed with a response\n\t\t// (note that this may also be caused by context cancellation)\n\t\tcase tunnelError := <-s.tunnelErrors:\n\t\t\ttunnelsActive--\n\t\t\ts.log.ConnAwareLogger().Err(tunnelError.err).Int(connection.LogFieldConnIndex, tunnelError.index).Msg(\"Connection terminated\")\n\t\t\tif tunnelError.err != nil && !shuttingDown {\n\t\t\t\tswitch tunnelError.err.(type) {\n\t\t\t\tcase ReconnectSignal:\n\t\t\t\t\t// For tunnels that closed with reconnect signal, we reconnect immediately\n\t\t\t\t\tgo s.startTunnel(ctx, tunnelError.index, s.newConnectedTunnelSignal(tunnelError.index))\n\t\t\t\t\ttunnelsActive++\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\t// Make sure we don't continue if there is no more fallback allowed\n\t\t\t\tif _, retry := s.tunnelsProtocolFallback[tunnelError.index].GetMaxBackoffDuration(ctx); !retry {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\ttunnelsWaiting = append(tunnelsWaiting, tunnelError.index)\n\t\t\t\ts.waitForNextTunnel(tunnelError.index)\n\n\t\t\t\tif backoffTimer == nil {\n\t\t\t\t\tbackoffTimer = backoff.BackoffTimer()\n\t\t\t\t}\n\t\t\t} else if tunnelsActive == 0 {\n\t\t\t\ts.log.ConnAwareLogger().Msg(\"no more connections active and exiting\")\n\t\t\t\t// All connected tunnels exited gracefully, no more work to do\n\t\t\t\treturn nil\n\t\t\t}\n\t\t// Backoff was set and its timer expired\n\t\tcase <-backoffTimer:\n\t\t\tbackoffTimer = nil\n\t\t\tfor _, index := range tunnelsWaiting {\n\t\t\t\tgo s.startTunnel(ctx, index, s.newConnectedTunnelSignal(index))\n\t\t\t}\n\t\t\ttunnelsActive += len(tunnelsWaiting)\n\t\t\ttunnelsWaiting = nil\n\t\t// Tunnel successfully connected\n\t\tcase <-s.nextConnectedSignal:\n\t\t\tif !s.waitForNextTunnel(s.nextConnectedIndex) && len(tunnelsWaiting) == 0 {\n\t\t\t\t// No more tunnels outstanding, clear backoff timer\n\t\t\t\tbackoff.SetGracePeriod()\n\t\t\t}\n\t\tcase <-s.gracefulShutdownC:\n\t\t\tshuttingDown = true\n\t\t}\n\t}\n}\n\n// Returns nil if initialization succeeded, else the initialization error.\n// Attempts here will be made to connect one tunnel, if successful, it will\n// connect the available tunnels up to config.HAConnections.\nfunc (s *Supervisor) initialize(\n\tctx context.Context,\n\tconnectedSignal *signal.Signal,\n) error {\n\tavailableAddrs := s.edgeIPs.AvailableAddrs()\n\tif s.config.HAConnections > availableAddrs {\n\t\ts.log.Logger().Info().Msgf(\"You requested %d HA connections but I can give you at most %d.\", s.config.HAConnections, availableAddrs)\n\t\ts.config.HAConnections = availableAddrs\n\t}\n\ts.tunnelsProtocolFallback[0] = &protocolFallback{\n\t\tretry.NewBackoff(s.config.Retries, retry.DefaultBaseTime, true),\n\t\ts.config.ProtocolSelector.Current(),\n\t\tfalse,\n\t}\n\n\tgo s.startFirstTunnel(ctx, connectedSignal)\n\n\t// Wait for response from first tunnel before proceeding to attempt other HA edge tunnels\n\tselect {\n\tcase <-ctx.Done():\n\t\t<-s.tunnelErrors\n\t\treturn ctx.Err()\n\tcase tunnelError := <-s.tunnelErrors:\n\t\treturn tunnelError.err\n\tcase <-s.gracefulShutdownC:\n\t\treturn errEarlyShutdown\n\tcase <-connectedSignal.Wait():\n\t}\n\n\t// At least one successful connection, so start the rest\n\tfor i := 1; i < s.config.HAConnections; i++ {\n\t\ts.tunnelsProtocolFallback[i] = &protocolFallback{\n\t\t\tretry.NewBackoff(s.config.Retries, retry.DefaultBaseTime, true),\n\t\t\t// Set the protocol we know the first tunnel connected with.\n\t\t\ts.tunnelsProtocolFallback[0].protocol,\n\t\t\tfalse,\n\t\t}\n\t\tgo s.startTunnel(ctx, i, s.newConnectedTunnelSignal(i))\n\t\ttime.Sleep(registrationInterval)\n\t}\n\treturn nil\n}\n\n// startTunnel starts the first tunnel connection. The resulting error will be sent on\n// s.tunnelErrors. It will send a signal via connectedSignal if registration succeed\nfunc (s *Supervisor) startFirstTunnel(\n\tctx context.Context,\n\tconnectedSignal *signal.Signal,\n) {\n\tvar err error\n\tconst firstConnIndex = 0\n\tisStaticEdge := len(s.config.EdgeAddrs) > 0\n\tdefer func() {\n\t\ts.tunnelErrors <- tunnelError{index: firstConnIndex, err: err}\n\t}()\n\n\t// If the first tunnel disconnects, keep restarting it.\n\tfor {\n\t\terr = s.edgeTunnelServer.Serve(ctx, firstConnIndex, s.tunnelsProtocolFallback[firstConnIndex], connectedSignal)\n\t\tif ctx.Err() != nil {\n\t\t\treturn\n\t\t}\n\t\tif err == nil {\n\t\t\treturn\n\t\t}\n\t\t// Make sure we don't continue if there is no more fallback allowed\n\t\tif _, retry := s.tunnelsProtocolFallback[firstConnIndex].GetMaxBackoffDuration(ctx); !retry {\n\t\t\treturn\n\t\t}\n\t\t// Try again for Unauthorized errors because we hope them to be\n\t\t// transient due to edge propagation lag on new Tunnels.\n\t\tif strings.Contains(err.Error(), \"Unauthorized\") {\n\t\t\tcontinue\n\t\t}\n\t\tswitch err.(type) {\n\t\tcase edgediscovery.ErrNoAddressesLeft:\n\t\t\t// If your provided addresses are not available, we will keep trying regardless.\n\t\t\tif !isStaticEdge {\n\t\t\t\treturn\n\t\t\t}\n\t\tcase connection.DupConnRegisterTunnelError,\n\t\t\t*quic.IdleTimeoutError,\n\t\t\t*quic.ApplicationError,\n\t\t\tedgediscovery.DialError,\n\t\t\t*connection.EdgeQuicDialError,\n\t\t\t*connection.ControlStreamError,\n\t\t\t*connection.StreamListenerError,\n\t\t\t*connection.DatagramManagerError:\n\t\t\t// Try again for these types of errors\n\t\tdefault:\n\t\t\t// Uncaught errors should bail startup\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// startTunnel starts a new tunnel connection. The resulting error will be sent on\n// s.tunnelError as this is expected to run in a goroutine.\nfunc (s *Supervisor) startTunnel(\n\tctx context.Context,\n\tindex int,\n\tconnectedSignal *signal.Signal,\n) {\n\t// nolint: gosec\n\terr := s.edgeTunnelServer.Serve(ctx, uint8(index), s.tunnelsProtocolFallback[index], connectedSignal)\n\ts.tunnelErrors <- tunnelError{index: index, err: err}\n}\n\nfunc (s *Supervisor) newConnectedTunnelSignal(index int) *signal.Signal {\n\tsig := make(chan struct{})\n\ts.tunnelsConnecting[index] = sig\n\ts.nextConnectedSignal = sig\n\ts.nextConnectedIndex = index\n\treturn signal.New(sig)\n}\n\nfunc (s *Supervisor) waitForNextTunnel(index int) bool {\n\tdelete(s.tunnelsConnecting, index)\n\ts.nextConnectedSignal = nil\n\tfor k, v := range s.tunnelsConnecting {\n\t\ts.nextConnectedIndex = k\n\t\ts.nextConnectedSignal = v\n\t\treturn true\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "supervisor/tunnel.go",
    "content": "package supervisor\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/netip\"\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/quic-go/quic-go\"\n\t\"github.com/rs/zerolog\"\n\t\"golang.org/x/sync/errgroup\"\n\n\t\"github.com/cloudflare/cloudflared/client\"\n\t\"github.com/cloudflare/cloudflared/connection\"\n\t\"github.com/cloudflare/cloudflared/edgediscovery\"\n\t\"github.com/cloudflare/cloudflared/edgediscovery/allregions\"\n\t\"github.com/cloudflare/cloudflared/features\"\n\t\"github.com/cloudflare/cloudflared/fips\"\n\t\"github.com/cloudflare/cloudflared/ingress\"\n\t\"github.com/cloudflare/cloudflared/ingress/origins\"\n\t\"github.com/cloudflare/cloudflared/management\"\n\t\"github.com/cloudflare/cloudflared/orchestration\"\n\tquicpogs \"github.com/cloudflare/cloudflared/quic\"\n\tv3 \"github.com/cloudflare/cloudflared/quic/v3\"\n\t\"github.com/cloudflare/cloudflared/retry\"\n\t\"github.com/cloudflare/cloudflared/signal\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n\t\"github.com/cloudflare/cloudflared/tunnelstate\"\n)\n\nconst (\n\tdialTimeout = 15 * time.Second\n)\n\ntype TunnelConfig struct {\n\tClientConfig       *client.Config\n\tGracePeriod        time.Duration\n\tCloseConnOnce      *sync.Once // Used to close connectedSignal no more than once\n\tEdgeAddrs          []string\n\tRegion             string\n\tEdgeIPVersion      allregions.ConfigIPVersion\n\tEdgeBindAddr       net.IP\n\tHAConnections      int\n\tIsAutoupdated      bool\n\tLBPool             string\n\tTags               []pogs.Tag\n\tLog                *zerolog.Logger\n\tLogTransport       *zerolog.Logger\n\tObserver           *connection.Observer\n\tReportedVersion    string\n\tRetries            uint\n\tMaxEdgeAddrRetries uint8\n\tRunFromTerminal    bool\n\n\tNeedPQ bool\n\n\tNamedTunnel         *connection.TunnelProperties\n\tProtocolSelector    connection.ProtocolSelector\n\tEdgeTLSConfigs      map[connection.Protocol]*tls.Config\n\tICMPRouterServer    ingress.ICMPRouterServer\n\tOriginDNSService    *origins.DNSResolverService\n\tOriginDialerService *ingress.OriginDialerService\n\n\tRPCTimeout         time.Duration\n\tWriteStreamTimeout time.Duration\n\n\tDisableQUICPathMTUDiscovery         bool\n\tQUICConnectionLevelFlowControlLimit uint64\n\tQUICStreamLevelFlowControlLimit     uint64\n}\n\nfunc (c *TunnelConfig) connectionOptions(originLocalAddr string, previousAttempts uint8) *client.ConnectionOptionsSnapshot {\n\t// attempt to parse out origin IP, but don't fail since it's informational field\n\thost, _, _ := net.SplitHostPort(originLocalAddr)\n\toriginIP := net.ParseIP(host)\n\treturn c.ClientConfig.ConnectionOptionsSnapshot(originIP, previousAttempts)\n}\n\nfunc StartTunnelDaemon(\n\tctx context.Context,\n\tconfig *TunnelConfig,\n\torchestrator *orchestration.Orchestrator,\n\tconnectedSignal *signal.Signal,\n\treconnectCh chan ReconnectSignal,\n\tgraceShutdownC <-chan struct{},\n) error {\n\ts, err := NewSupervisor(config, orchestrator, reconnectCh, graceShutdownC)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn s.Run(ctx, connectedSignal)\n}\n\ntype ConnectivityError struct {\n\treachedMaxRetries bool\n}\n\nfunc NewConnectivityError(hasReachedMaxRetries bool) *ConnectivityError {\n\treturn &ConnectivityError{\n\t\treachedMaxRetries: hasReachedMaxRetries,\n\t}\n}\n\nfunc (e *ConnectivityError) Error() string {\n\treturn fmt.Sprintf(\"connectivity error - reached max retries: %t\", e.HasReachedMaxRetries())\n}\n\nfunc (e *ConnectivityError) HasReachedMaxRetries() bool {\n\treturn e.reachedMaxRetries\n}\n\n// EdgeAddrHandler provides a mechanism switch between behaviors in ServeTunnel\n// for handling the errors when attempting to make edge connections.\ntype EdgeAddrHandler interface {\n\t// ShouldGetNewAddress will check the edge connection error and determine if\n\t// the edge address should be replaced with a new one. Also, will return if the\n\t// error should be recognized as a connectivity error, or otherwise, a general\n\t// application error.\n\tShouldGetNewAddress(connIndex uint8, err error) (needsNewAddress bool, connectivityError error)\n}\n\nfunc NewIPAddrFallback(maxRetries uint8) *ipAddrFallback {\n\treturn &ipAddrFallback{\n\t\tretriesByConnIndex: make(map[uint8]uint8),\n\t\tmaxRetries:         maxRetries,\n\t}\n}\n\n// ipAddrFallback will have more conditions to fall back to a new address for certain\n// edge connection errors. This means that this handler will return true for isConnectivityError\n// for more cases like duplicate connection register and edge quic dial errors.\ntype ipAddrFallback struct {\n\tm                  sync.Mutex\n\tretriesByConnIndex map[uint8]uint8\n\tmaxRetries         uint8\n}\n\nfunc (f *ipAddrFallback) ShouldGetNewAddress(connIndex uint8, err error) (needsNewAddress bool, connectivityError error) {\n\tf.m.Lock()\n\tdefer f.m.Unlock()\n\tswitch err.(type) {\n\tcase nil: // maintain current IP address\n\t// Try the next address if it was a quic.IdleTimeoutError\n\t// DupConnRegisterTunnelError needs to also receive a new ip address\n\tcase connection.DupConnRegisterTunnelError,\n\t\t*quic.IdleTimeoutError:\n\t\treturn true, nil\n\t// Network problems should be retried with new address immediately and report\n\t// as connectivity error\n\tcase edgediscovery.DialError, *connection.EdgeQuicDialError:\n\t\tif f.retriesByConnIndex[connIndex] >= f.maxRetries {\n\t\t\tf.retriesByConnIndex[connIndex] = 0\n\t\t\treturn true, NewConnectivityError(true)\n\t\t}\n\t\tf.retriesByConnIndex[connIndex]++\n\t\treturn true, NewConnectivityError(false)\n\tdefault: // maintain current IP address\n\t}\n\treturn false, nil\n}\n\ntype EdgeTunnelServer struct {\n\tconfig            *TunnelConfig\n\torchestrator      *orchestration.Orchestrator\n\tsessionManager    v3.SessionManager\n\tdatagramMetrics   v3.Metrics\n\tedgeAddrHandler   EdgeAddrHandler\n\tedgeAddrs         *edgediscovery.Edge\n\tedgeBindAddr      net.IP\n\treconnectCh       chan ReconnectSignal\n\tgracefulShutdownC <-chan struct{}\n\ttracker           *tunnelstate.ConnTracker\n\n\tconnAwareLogger *ConnAwareLogger\n}\n\ntype TunnelServer interface {\n\tServe(ctx context.Context, connIndex uint8, protocolFallback *protocolFallback, connectedSignal *signal.Signal) error\n}\n\nfunc (e *EdgeTunnelServer) Serve(ctx context.Context, connIndex uint8, protocolFallback *protocolFallback, connectedSignal *signal.Signal) error {\n\thaConnections.Inc()\n\tdefer haConnections.Dec()\n\n\tconnectedFuse := newBooleanFuse()\n\tgo func() {\n\t\tif connectedFuse.Await() {\n\t\t\tconnectedSignal.Notify()\n\t\t}\n\t}()\n\t// Ensure the above goroutine will terminate if we return without connecting\n\tdefer connectedFuse.Fuse(false)\n\n\t// Fetch IP address to associated connection index\n\taddr, err := e.edgeAddrs.GetAddr(int(connIndex))\n\tswitch err.(type) {\n\tcase nil: // no error\n\tcase edgediscovery.ErrNoAddressesLeft:\n\t\treturn err\n\tdefault:\n\t\treturn err\n\t}\n\n\tlogger := e.config.Log.With().\n\t\tInt(management.EventTypeKey, int(management.Cloudflared)).\n\t\tIPAddr(connection.LogFieldIPAddress, addr.UDP.IP).\n\t\tUint8(connection.LogFieldConnIndex, connIndex).\n\t\tLogger()\n\tconnLog := e.connAwareLogger.ReplaceLogger(&logger)\n\n\t// Each connection to keep its own copy of protocol, because individual connections might fallback\n\t// to another protocol when a particular metal doesn't support new protocol\n\t// Each connection can also have it's own IP version because individual connections might fallback\n\t// to another IP version.\n\terr, shouldFallbackProtocol := e.serveTunnel(\n\t\tctx,\n\t\tconnLog,\n\t\taddr,\n\t\tconnIndex,\n\t\tconnectedFuse,\n\t\tprotocolFallback,\n\t\tprotocolFallback.protocol,\n\t)\n\n\t// Check if the connection error was from an IP issue with the host or\n\t// establishing a connection to the edge and if so, rotate the IP address.\n\tshouldRotateEdgeIP, cErr := e.edgeAddrHandler.ShouldGetNewAddress(connIndex, err)\n\tif shouldRotateEdgeIP {\n\t\t// rotate IP, but forcing internal state to assign a new IP to connection index.\n\t\tif _, err := e.edgeAddrs.GetDifferentAddr(int(connIndex), true); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// In addition, if it is a connectivity error, and we have exhausted the configurable maximum edge IPs to rotate,\n\t\t// then just fallback protocol on next iteration run.\n\t\tconnectivityErr, ok := cErr.(*ConnectivityError)\n\t\tif ok {\n\t\t\tshouldFallbackProtocol = connectivityErr.HasReachedMaxRetries()\n\t\t}\n\t}\n\n\t// set connection has re-connecting and log the next retrying backoff\n\tduration, ok := protocolFallback.GetMaxBackoffDuration(ctx)\n\tif !ok {\n\t\treturn err\n\t}\n\te.config.Observer.SendReconnect(connIndex)\n\tconnLog.Logger().Info().Msgf(\"Retrying connection in up to %s\", duration)\n\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\tcase <-e.gracefulShutdownC:\n\t\treturn nil\n\tcase <-protocolFallback.BackoffTimer():\n\t\t// should we fallback protocol? If not, just return. Otherwise, set new protocol for next method call.\n\t\tif !shouldFallbackProtocol {\n\t\t\treturn err\n\t\t}\n\n\t\t// If a single connection has connected with the current protocol, we know we know we don't have to fallback\n\t\t// to a different protocol.\n\t\tif e.tracker.HasConnectedWith(e.config.ProtocolSelector.Current()) {\n\t\t\treturn err\n\t\t}\n\n\t\tif !selectNextProtocol(\n\t\t\tconnLog.Logger(),\n\t\t\tprotocolFallback,\n\t\t\te.config.ProtocolSelector,\n\t\t\terr,\n\t\t) {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn err\n}\n\n// protocolFallback is a wrapper around backoffHandler that will try fallback option when backoff reaches\n// max retries\ntype protocolFallback struct {\n\tretry.BackoffHandler\n\tprotocol   connection.Protocol\n\tinFallback bool\n}\n\nfunc (pf *protocolFallback) reset() {\n\tpf.ResetNow()\n\tpf.inFallback = false\n}\n\nfunc (pf *protocolFallback) fallback(fallback connection.Protocol) {\n\tpf.ResetNow()\n\tpf.protocol = fallback\n\tpf.inFallback = true\n}\n\n// selectNextProtocol picks connection protocol for the next retry iteration,\n// returns true if it was able to pick the protocol, false if we are out of options and should stop retrying\nfunc selectNextProtocol(\n\tconnLog *zerolog.Logger,\n\tprotocolBackoff *protocolFallback,\n\tselector connection.ProtocolSelector,\n\tcause error,\n) bool {\n\tisQuicBroken := isQuicBroken(cause)\n\t_, hasFallback := selector.Fallback()\n\n\tif protocolBackoff.ReachedMaxRetries() || (hasFallback && isQuicBroken) {\n\t\tif isQuicBroken {\n\t\t\tconnLog.Warn().Msg(\"If this log occurs persistently, and cloudflared is unable to connect to \" +\n\t\t\t\t\"Cloudflare Network with `quic` protocol, then most likely your machine/network is getting its egress \" +\n\t\t\t\t\"UDP to port 7844 (or others) blocked or dropped. Make sure to allow egress connectivity as per \" +\n\t\t\t\t\"https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/configuration/ports-and-ips/\\n\" +\n\t\t\t\t\"If you are using private routing to this Tunnel, then ICMP, UDP (and Private DNS Resolution) will not work \" +\n\t\t\t\t\"unless your cloudflared can connect with Cloudflare Network with `quic`.\")\n\t\t}\n\n\t\tfallback, hasFallback := selector.Fallback()\n\t\tif !hasFallback {\n\t\t\treturn false\n\t\t}\n\t\t// Already using fallback protocol, no point to retry\n\t\tif protocolBackoff.protocol == fallback {\n\t\t\treturn false\n\t\t}\n\t\tconnLog.Info().Msgf(\"Switching to fallback protocol %s\", fallback)\n\t\tprotocolBackoff.fallback(fallback)\n\t} else if !protocolBackoff.inFallback {\n\t\tcurrent := selector.Current()\n\t\tif protocolBackoff.protocol != current {\n\t\t\tprotocolBackoff.protocol = current\n\t\t\tconnLog.Info().Msgf(\"Changing protocol to %s\", current)\n\t\t}\n\t}\n\treturn true\n}\n\nfunc isQuicBroken(cause error) bool {\n\tvar idleTimeoutError *quic.IdleTimeoutError\n\tif errors.As(cause, &idleTimeoutError) {\n\t\treturn true\n\t}\n\n\tvar transportError *quic.TransportError\n\tif errors.As(cause, &transportError) && strings.Contains(cause.Error(), \"operation not permitted\") {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// ServeTunnel runs a single tunnel connection, returns nil on graceful shutdown,\n// on error returns a flag indicating if error can be retried\nfunc (e *EdgeTunnelServer) serveTunnel(\n\tctx context.Context,\n\tconnLog *ConnAwareLogger,\n\taddr *allregions.EdgeAddr,\n\tconnIndex uint8,\n\tfuse *booleanFuse,\n\tbackoff *protocolFallback,\n\tprotocol connection.Protocol,\n) (err error, recoverable bool) {\n\t// Treat panics as recoverable errors\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tvar ok bool\n\t\t\terr, ok = r.(error)\n\t\t\tif !ok {\n\t\t\t\terr = fmt.Errorf(\"ServeTunnel: %v\", r)\n\t\t\t}\n\t\t\terr = errors.Wrapf(err, \"stack trace: %s\", string(debug.Stack()))\n\t\t\trecoverable = true\n\t\t}\n\t}()\n\n\tdefer e.config.Observer.SendDisconnect(connIndex)\n\terr, recoverable = e.serveConnection(\n\t\tctx,\n\t\tconnLog,\n\t\taddr,\n\t\tconnIndex,\n\t\tfuse,\n\t\tbackoff,\n\t\tprotocol,\n\t)\n\n\tif err != nil {\n\t\tswitch err := err.(type) {\n\t\tcase connection.DupConnRegisterTunnelError:\n\t\t\tconnLog.ConnAwareLogger().Err(err).Msg(\"Unable to establish connection.\")\n\t\t\t// don't retry this connection anymore, let supervisor pick a new address\n\t\t\treturn err, false\n\t\tcase connection.ServerRegisterTunnelError:\n\t\t\tconnLog.ConnAwareLogger().Err(err).Msg(\"Register tunnel error from server side\")\n\t\t\t// Don't send registration error return from server to Sentry. They are\n\t\t\t// logged on server side\n\t\t\treturn err.Cause, !err.Permanent\n\t\tcase *connection.EdgeQuicDialError:\n\t\t\treturn err, false\n\t\tcase ReconnectSignal:\n\t\t\tconnLog.Logger().Info().\n\t\t\t\tIPAddr(connection.LogFieldIPAddress, addr.UDP.IP).\n\t\t\t\tUint8(connection.LogFieldConnIndex, connIndex).\n\t\t\t\tMsgf(\"Restarting connection due to reconnect signal in %s\", err.Delay)\n\t\t\terr.DelayBeforeReconnect()\n\t\t\treturn err, true\n\t\tdefault:\n\t\t\tif err == context.Canceled {\n\t\t\t\tconnLog.Logger().Debug().Err(err).Msgf(\"Serve tunnel error\")\n\t\t\t\treturn err, false\n\t\t\t}\n\t\t\tconnLog.ConnAwareLogger().Err(err).Msgf(\"Serve tunnel error\")\n\t\t\t_, permanent := err.(unrecoverableError)\n\t\t\treturn err, !permanent\n\t\t}\n\t}\n\treturn nil, false\n}\n\nfunc (e *EdgeTunnelServer) serveConnection(\n\tctx context.Context,\n\tconnLog *ConnAwareLogger,\n\taddr *allregions.EdgeAddr,\n\tconnIndex uint8,\n\tfuse *booleanFuse,\n\tbackoff *protocolFallback,\n\tprotocol connection.Protocol,\n) (err error, recoverable bool) {\n\tconnectedFuse := &connectedFuse{\n\t\tfuse:    fuse,\n\t\tbackoff: backoff,\n\t}\n\tcontrolStream := connection.NewControlStream(\n\t\te.config.Observer,\n\t\tconnectedFuse,\n\t\te.config.NamedTunnel,\n\t\tconnIndex,\n\t\taddr.UDP.IP,\n\t\tnil,\n\t\te.config.RPCTimeout,\n\t\te.gracefulShutdownC,\n\t\te.config.GracePeriod,\n\t\tprotocol,\n\t)\n\n\tswitch protocol {\n\tcase connection.QUIC:\n\t\t// nolint: gosec\n\t\tconnOptions := e.config.connectionOptions(addr.UDP.String(), uint8(backoff.Retries()))\n\t\t// nolint: zerologlint\n\t\tconnOptions.LogFields(connLog.Logger().Debug().Uint8(connection.LogFieldConnIndex, connIndex)).Msgf(\"Tunnel connection options\")\n\t\treturn e.serveQUIC(ctx,\n\t\t\taddr.UDP.AddrPort(),\n\t\t\tconnLog,\n\t\t\tconnOptions,\n\t\t\tcontrolStream,\n\t\t\tconnIndex)\n\n\tcase connection.HTTP2:\n\t\tedgeConn, err := edgediscovery.DialEdge(ctx, dialTimeout, e.config.EdgeTLSConfigs[protocol], addr.TCP, e.edgeBindAddr)\n\t\tif err != nil {\n\t\t\tconnLog.ConnAwareLogger().Err(err).Msg(\"Unable to establish connection with Cloudflare edge\")\n\t\t\treturn err, true\n\t\t}\n\n\t\t// nolint: gosec\n\t\tconnOptions := e.config.connectionOptions(edgeConn.LocalAddr().String(), uint8(backoff.Retries()))\n\t\t// nolint: zerologlint\n\t\tconnOptions.LogFields(connLog.Logger().Debug().Uint8(connection.LogFieldConnIndex, connIndex)).Msgf(\"Tunnel connection options\")\n\t\tif err := e.serveHTTP2(\n\t\t\tctx,\n\t\t\tconnLog,\n\t\t\tedgeConn,\n\t\t\tconnOptions,\n\t\t\tcontrolStream,\n\t\t\tconnIndex,\n\t\t); err != nil {\n\t\t\treturn err, false\n\t\t}\n\n\tdefault:\n\t\treturn fmt.Errorf(\"invalid protocol selected: %s\", protocol), false\n\t}\n\treturn\n}\n\ntype unrecoverableError struct {\n\terr error\n}\n\nfunc (r unrecoverableError) Error() string {\n\treturn r.err.Error()\n}\n\nfunc (e *EdgeTunnelServer) serveHTTP2(\n\tctx context.Context,\n\tconnLog *ConnAwareLogger,\n\ttlsServerConn net.Conn,\n\tconnOptions *client.ConnectionOptionsSnapshot,\n\tcontrolStreamHandler connection.ControlStreamHandler,\n\tconnIndex uint8,\n) error {\n\tpqMode := connOptions.FeatureSnapshot.PostQuantum\n\tif pqMode == features.PostQuantumStrict {\n\t\treturn unrecoverableError{errors.New(\"HTTP/2 transport does not support post-quantum\")}\n\t}\n\n\tconnLog.Logger().Debug().Msgf(\"Connecting via http2\")\n\th2conn := connection.NewHTTP2Connection(\n\t\ttlsServerConn,\n\t\te.orchestrator,\n\t\tconnOptions,\n\t\te.config.Observer,\n\t\tconnIndex,\n\t\tcontrolStreamHandler,\n\t\te.config.Log,\n\t)\n\n\terrGroup, serveCtx := errgroup.WithContext(ctx)\n\terrGroup.Go(func() error {\n\t\treturn h2conn.Serve(serveCtx)\n\t})\n\n\terrGroup.Go(func() error {\n\t\terr := listenReconnect(serveCtx, e.reconnectCh, e.gracefulShutdownC)\n\t\tif err != nil {\n\t\t\t// forcefully break the connection (this is only used for testing)\n\t\t\t// errgroup will return context canceled for the h2conn.Serve\n\t\t\tconnLog.Logger().Debug().Msg(\"Forcefully breaking http2 connection\")\n\t\t}\n\t\treturn err\n\t})\n\n\treturn errGroup.Wait()\n}\n\nfunc (e *EdgeTunnelServer) serveQUIC(\n\tctx context.Context,\n\tedgeAddr netip.AddrPort,\n\tconnLogger *ConnAwareLogger,\n\tconnOptions *client.ConnectionOptionsSnapshot,\n\tcontrolStreamHandler connection.ControlStreamHandler,\n\tconnIndex uint8,\n) (err error, recoverable bool) {\n\ttlsConfig := e.config.EdgeTLSConfigs[connection.QUIC]\n\n\tpqMode := connOptions.FeatureSnapshot.PostQuantum\n\tcurvePref, err := curvePreference(pqMode, fips.IsFipsEnabled(), tlsConfig.CurvePreferences)\n\tif err != nil {\n\t\tconnLogger.ConnAwareLogger().Err(err).Msgf(\"failed to get curve preferences\")\n\t\treturn err, true\n\t}\n\n\tconnLogger.Logger().Info().Msgf(\"Tunnel connection curve preferences: %v\", curvePref)\n\n\ttlsConfig.CurvePreferences = curvePref\n\n\t// quic-go 0.44 increases the initial packet size to 1280 by default. That breaks anyone running tunnel through WARP\n\t// because WARP MTU is 1280.\n\tvar initialPacketSize uint16 = 1252\n\tif edgeAddr.Addr().Is4() {\n\t\tinitialPacketSize = 1232\n\t}\n\n\tquicConfig := &quic.Config{\n\t\tHandshakeIdleTimeout:       quicpogs.HandshakeIdleTimeout,\n\t\tMaxIdleTimeout:             quicpogs.MaxIdleTimeout,\n\t\tKeepAlivePeriod:            quicpogs.MaxIdlePingPeriod,\n\t\tMaxIncomingStreams:         quicpogs.MaxIncomingStreams,\n\t\tMaxIncomingUniStreams:      quicpogs.MaxIncomingStreams,\n\t\tEnableDatagrams:            true,\n\t\tTracer:                     quicpogs.NewClientTracer(connLogger.Logger(), connIndex),\n\t\tDisablePathMTUDiscovery:    e.config.DisableQUICPathMTUDiscovery,\n\t\tMaxConnectionReceiveWindow: e.config.QUICConnectionLevelFlowControlLimit,\n\t\tMaxStreamReceiveWindow:     e.config.QUICStreamLevelFlowControlLimit,\n\t\tInitialPacketSize:          initialPacketSize,\n\t}\n\n\t// Dial the QUIC connection to the edge\n\tconn, err := connection.DialQuic(\n\t\tctx,\n\t\tquicConfig,\n\t\ttlsConfig,\n\t\tedgeAddr,\n\t\te.edgeBindAddr,\n\t\tconnIndex,\n\t\tconnLogger.Logger(),\n\t)\n\tif err != nil {\n\t\tconnLogger.ConnAwareLogger().Err(err).Msgf(\"Failed to dial a quic connection\")\n\n\t\te.reportErrorToSentry(err, connOptions.FeatureSnapshot.PostQuantum)\n\t\treturn err, true\n\t}\n\n\tvar datagramSessionManager connection.DatagramSessionHandler\n\tif connOptions.FeatureSnapshot.DatagramVersion == features.DatagramV3 {\n\t\tdatagramSessionManager = connection.NewDatagramV3Connection(\n\t\t\tctx,\n\t\t\tconn,\n\t\t\te.sessionManager,\n\t\t\te.config.ICMPRouterServer,\n\t\t\tconnIndex,\n\t\t\te.datagramMetrics,\n\t\t\tconnLogger.Logger(),\n\t\t)\n\t} else {\n\t\tdatagramSessionManager = connection.NewDatagramV2Connection(\n\t\t\tctx,\n\t\t\tconn,\n\t\t\te.config.OriginDialerService,\n\t\t\te.config.ICMPRouterServer,\n\t\t\tconnIndex,\n\t\t\te.config.RPCTimeout,\n\t\t\te.config.WriteStreamTimeout,\n\t\t\te.orchestrator.GetFlowLimiter(),\n\t\t\tconnLogger.Logger(),\n\t\t)\n\t}\n\n\t// Wrap the [quic.Connection] as a TunnelConnection\n\ttunnelConn := connection.NewTunnelConnection(\n\t\tctx,\n\t\tconn,\n\t\tconnIndex,\n\t\te.orchestrator,\n\t\tdatagramSessionManager,\n\t\tcontrolStreamHandler,\n\t\tconnOptions,\n\t\te.config.RPCTimeout,\n\t\te.config.WriteStreamTimeout,\n\t\te.config.GracePeriod,\n\t\tconnLogger.Logger(),\n\t)\n\n\t// Serve the TunnelConnection\n\terrGroup, serveCtx := errgroup.WithContext(ctx)\n\terrGroup.Go(func() error {\n\t\terr := tunnelConn.Serve(serveCtx)\n\t\tif err != nil {\n\t\t\tconnLogger.ConnAwareLogger().Err(err).Msg(\"failed to serve tunnel connection\")\n\t\t}\n\t\treturn err\n\t})\n\n\terrGroup.Go(func() error {\n\t\terr := listenReconnect(serveCtx, e.reconnectCh, e.gracefulShutdownC)\n\t\tif err != nil {\n\t\t\t// forcefully break the connection (this is only used for testing)\n\t\t\t// errgroup will return context canceled for the tunnelConn.Serve\n\t\t\tconnLogger.Logger().Debug().Msg(\"Forcefully breaking tunnel connection\")\n\t\t}\n\t\treturn err\n\t})\n\n\treturn errGroup.Wait(), false\n}\n\n// The reportErrorToSentry is an helper function that handles\n// verifies if an error should be reported to Sentry.\nfunc (e *EdgeTunnelServer) reportErrorToSentry(err error, pqMode features.PostQuantumMode) {\n\tdialErr, ok := err.(*connection.EdgeQuicDialError)\n\tif ok {\n\t\t// The TransportError provides an Unwrap function however\n\t\t// the err MAY not always be set\n\t\ttransportErr, ok := dialErr.Cause.(*quic.TransportError)\n\t\tif ok &&\n\t\t\ttransportErr.ErrorCode.IsCryptoError() &&\n\t\t\tfips.IsFipsEnabled() &&\n\t\t\tpqMode == features.PostQuantumStrict {\n\t\t\t// Only report to Sentry when using FIPS, PQ,\n\t\t\t// and the error is a Crypto error reported by\n\t\t\t// an EdgeQuicDialError\n\t\t\tsentry.CaptureException(err)\n\t\t}\n\t}\n}\n\nfunc listenReconnect(ctx context.Context, reconnectCh <-chan ReconnectSignal, gracefulShutdownCh <-chan struct{}) error {\n\tselect {\n\tcase reconnect := <-reconnectCh:\n\t\treturn reconnect\n\tcase <-gracefulShutdownCh:\n\t\treturn nil\n\tcase <-ctx.Done():\n\t\treturn nil\n\t}\n}\n\ntype connectedFuse struct {\n\tfuse    *booleanFuse\n\tbackoff *protocolFallback\n}\n\nfunc (cf *connectedFuse) Connected() {\n\tcf.fuse.Fuse(true)\n\tcf.backoff.reset()\n}\n\nfunc (cf *connectedFuse) IsConnected() bool {\n\treturn cf.fuse.Value()\n}\n"
  },
  {
    "path": "supervisor/tunnel_test.go",
    "content": "package supervisor\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/cloudflare/cloudflared/connection\"\n\t\"github.com/cloudflare/cloudflared/edgediscovery\"\n\t\"github.com/cloudflare/cloudflared/retry\"\n)\n\ntype dynamicMockFetcher struct {\n\tprotocolPercents edgediscovery.ProtocolPercents\n\terr              error\n}\n\nfunc (dmf *dynamicMockFetcher) fetch() edgediscovery.PercentageFetcher {\n\treturn func() (edgediscovery.ProtocolPercents, error) {\n\t\treturn dmf.protocolPercents, dmf.err\n\t}\n}\n\nfunc immediateTimeAfter(time.Duration) <-chan time.Time {\n\tc := make(chan time.Time, 1)\n\tc <- time.Now()\n\treturn c\n}\n\nfunc TestWaitForBackoffFallback(t *testing.T) {\n\tmaxRetries := uint(3)\n\tbackoff := retry.NewBackoff(maxRetries, 40*time.Millisecond, false)\n\tbackoff.Clock.After = immediateTimeAfter\n\tlog := zerolog.Nop()\n\tresolveTTL := 10 * time.Second\n\tmockFetcher := dynamicMockFetcher{\n\t\tprotocolPercents: edgediscovery.ProtocolPercents{edgediscovery.ProtocolPercent{Protocol: \"quic\", Percentage: 100}},\n\t}\n\tprotocolSelector, err := connection.NewProtocolSelector(\n\t\t\"auto\",\n\t\t\"\",\n\t\tfalse,\n\t\tfalse,\n\t\tmockFetcher.fetch(),\n\t\tresolveTTL,\n\t\t&log,\n\t)\n\tassert.NoError(t, err)\n\n\tinitProtocol := protocolSelector.Current()\n\tassert.Equal(t, connection.QUIC, initProtocol)\n\n\tprotoFallback := &protocolFallback{\n\t\tbackoff,\n\t\tinitProtocol,\n\t\tfalse,\n\t}\n\n\t// Retry #0 and #1. At retry #2, we switch protocol, so the fallback loop has one more retry than this\n\tfor i := 0; i < int(maxRetries-1); i++ {\n\t\tprotoFallback.BackoffTimer() // simulate retry\n\t\tok := selectNextProtocol(&log, protoFallback, protocolSelector, nil)\n\t\tassert.True(t, ok)\n\t\tassert.Equal(t, initProtocol, protoFallback.protocol)\n\t}\n\n\t// Retry fallback protocol\n\tprotoFallback.BackoffTimer() // simulate retry\n\tok := selectNextProtocol(&log, protoFallback, protocolSelector, nil)\n\tassert.True(t, ok)\n\tfallback, ok := protocolSelector.Fallback()\n\tassert.True(t, ok)\n\tassert.Equal(t, fallback, protoFallback.protocol)\n\tassert.Equal(t, connection.HTTP2, protoFallback.protocol)\n\n\tcurrentGlobalProtocol := protocolSelector.Current()\n\tassert.Equal(t, initProtocol, currentGlobalProtocol)\n\n\t// Simulate max retries again (retries reset after protocol switch)\n\tfor i := 0; i < int(maxRetries); i++ {\n\t\tprotoFallback.BackoffTimer()\n\t}\n\t// No protocol to fallback, return error\n\tok = selectNextProtocol(&log, protoFallback, protocolSelector, nil)\n\tassert.False(t, ok)\n\n\tprotoFallback.reset()\n\tprotoFallback.BackoffTimer() // simulate retry\n\tok = selectNextProtocol(&log, protoFallback, protocolSelector, nil)\n\tassert.True(t, ok)\n\tassert.Equal(t, initProtocol, protoFallback.protocol)\n\n\tprotoFallback.reset()\n\tprotoFallback.BackoffTimer() // simulate retry\n\tok = selectNextProtocol(&log, protoFallback, protocolSelector, &quic.IdleTimeoutError{})\n\t// Check that we get a true after the first try itself when this flag is true. This allows us to immediately\n\t// switch protocols when there is a fallback.\n\tassert.True(t, ok)\n\n\t// But if there is no fallback available, then we exhaust the retries despite the type of error.\n\t// The reason why there's no fallback available is because we pick a specific protocol instead of letting it be auto.\n\tprotocolSelector, err = connection.NewProtocolSelector(\n\t\t\"quic\",\n\t\t\"\",\n\t\tfalse,\n\t\tfalse,\n\t\tmockFetcher.fetch(),\n\t\tresolveTTL,\n\t\t&log,\n\t)\n\tassert.NoError(t, err)\n\tprotoFallback = &protocolFallback{backoff, protocolSelector.Current(), false}\n\tfor i := 0; i < int(maxRetries-1); i++ {\n\t\tprotoFallback.BackoffTimer() // simulate retry\n\t\tok := selectNextProtocol(&log, protoFallback, protocolSelector, &quic.IdleTimeoutError{})\n\t\tassert.True(t, ok)\n\t\tassert.Equal(t, connection.QUIC, protoFallback.protocol)\n\t}\n\t// And finally it fails as it should, with no fallback.\n\tprotoFallback.BackoffTimer()\n\tok = selectNextProtocol(&log, protoFallback, protocolSelector, &quic.IdleTimeoutError{})\n\tassert.False(t, ok)\n}\n"
  },
  {
    "path": "supervisor/tunnelsforha.go",
    "content": "package supervisor\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n)\n\n// tunnelsForHA maps this cloudflared instance's HA connections to the tunnel IDs they serve.\ntype tunnelsForHA struct {\n\tsync.Mutex\n\tmetrics *prometheus.GaugeVec\n\tentries map[uint8]string\n}\n\n// NewTunnelsForHA initializes the Prometheus metrics etc for a tunnelsForHA.\nfunc NewTunnelsForHA() tunnelsForHA {\n\tmetrics := prometheus.NewGaugeVec(\n\t\tprometheus.GaugeOpts{\n\t\t\tName: \"tunnel_ids\",\n\t\t\tHelp: \"The ID of all tunnels (and their corresponding HA connection ID) running in this instance of cloudflared.\",\n\t\t},\n\t\t[]string{\"tunnel_id\", \"ha_conn_id\"},\n\t)\n\tprometheus.MustRegister(metrics)\n\n\treturn tunnelsForHA{\n\t\tmetrics: metrics,\n\t\tentries: make(map[uint8]string),\n\t}\n}\n\n// Track a new tunnel ID, removing the disconnected tunnel (if any) and update metrics.\nfunc (t *tunnelsForHA) AddTunnelID(haConn uint8, tunnelID string) {\n\tt.Lock()\n\tdefer t.Unlock()\n\thaStr := fmt.Sprintf(\"%v\", haConn)\n\tif oldTunnelID, ok := t.entries[haConn]; ok {\n\t\tt.metrics.WithLabelValues(oldTunnelID, haStr).Dec()\n\t}\n\tt.entries[haConn] = tunnelID\n\tt.metrics.WithLabelValues(tunnelID, haStr).Inc()\n}\n\nfunc (t *tunnelsForHA) String() string {\n\tt.Lock()\n\tdefer t.Unlock()\n\treturn fmt.Sprintf(\"%v\", t.entries)\n}\n"
  },
  {
    "path": "tlsconfig/certreloader.go",
    "content": "package tlsconfig\n\nimport (\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\t\"sync\"\n\n\t\"github.com/getsentry/sentry-go\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\t\"github.com/urfave/cli/v2\"\n)\n\nconst (\n\tOriginCAPoolFlag = \"origin-ca-pool\"\n\tCaCertFlag       = \"cacert\"\n)\n\n// CertReloader can load and reload a TLS certificate from a particular filepath.\n// Hooks into tls.Config's GetCertificate to allow a TLS server to update its certificate without restarting.\ntype CertReloader struct {\n\tsync.Mutex\n\tcertificate *tls.Certificate\n\tcertPath    string\n\tkeyPath     string\n}\n\n// NewCertReloader makes a CertReloader. It loads the cert during initialization to make sure certPath and keyPath are valid\nfunc NewCertReloader(certPath, keyPath string) (*CertReloader, error) {\n\tcr := new(CertReloader)\n\tcr.certPath = certPath\n\tcr.keyPath = keyPath\n\tif err := cr.LoadCert(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn cr, nil\n}\n\n// Cert returns the TLS certificate most recently read by the CertReloader.\n// This method works as a direct utility method for tls.Config#Cert.\nfunc (cr *CertReloader) Cert(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {\n\tcr.Lock()\n\tdefer cr.Unlock()\n\treturn cr.certificate, nil\n}\n\n// ClientCert returns the TLS certificate most recently read by the CertReloader.\n// This method works as a direct utility method for tls.Config#ClientCert.\nfunc (cr *CertReloader) ClientCert(certRequestInfo *tls.CertificateRequestInfo) (*tls.Certificate, error) {\n\tcr.Lock()\n\tdefer cr.Unlock()\n\treturn cr.certificate, nil\n}\n\n// LoadCert loads a TLS certificate from the CertReloader's specified filepath.\n// Call this after writing a new certificate to the disk (e.g. after renewing a certificate)\nfunc (cr *CertReloader) LoadCert() error {\n\tcr.Lock()\n\tdefer cr.Unlock()\n\n\tcert, err := tls.LoadX509KeyPair(cr.certPath, cr.keyPath)\n\n\t// Keep the old certificate if there's a problem reading the new one.\n\tif err != nil {\n\t\tsentry.CaptureException(fmt.Errorf(\"Error parsing X509 key pair: %v\", err))\n\t\treturn err\n\t}\n\tcr.certificate = &cert\n\treturn nil\n}\n\nfunc LoadOriginCA(originCAPoolFilename string, log *zerolog.Logger) (*x509.CertPool, error) {\n\tvar originCustomCAPool []byte\n\n\tif originCAPoolFilename != \"\" {\n\t\tvar err error\n\t\toriginCustomCAPool, err = os.ReadFile(originCAPoolFilename)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, fmt.Sprintf(\"unable to read the file %s for --%s\", originCAPoolFilename, OriginCAPoolFlag))\n\t\t}\n\t}\n\n\toriginCertPool, err := loadOriginCertPool(originCustomCAPool, log)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"error loading the certificate pool\")\n\t}\n\n\t// Windows users should be notified that they can use the flag\n\tif runtime.GOOS == \"windows\" && originCAPoolFilename == \"\" {\n\t\tlog.Info().Msgf(\"cloudflared does not support loading the system root certificate pool on Windows. Please use --%s <PATH> to specify the path to the certificate pool\", OriginCAPoolFlag)\n\t}\n\n\treturn originCertPool, nil\n}\n\nfunc LoadCustomOriginCA(originCAFilename string) (*x509.CertPool, error) {\n\t// First, obtain the system certificate pool\n\tcertPool, err := x509.SystemCertPool()\n\tif err != nil {\n\t\tcertPool = x509.NewCertPool()\n\t}\n\n\t// Next, append the Cloudflare CAs into the system pool\n\tcfRootCA, err := GetCloudflareRootCA()\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"could not append Cloudflare Root CAs to cloudflared certificate pool\")\n\t}\n\tfor _, cert := range cfRootCA {\n\t\tcertPool.AddCert(cert)\n\t}\n\n\tif originCAFilename == \"\" {\n\t\treturn certPool, nil\n\t}\n\n\tcustomOriginCA, err := os.ReadFile(originCAFilename)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, fmt.Sprintf(\"unable to read the file %s\", originCAFilename))\n\t}\n\n\tif !certPool.AppendCertsFromPEM(customOriginCA) {\n\t\treturn nil, fmt.Errorf(\"error appending custom CA to cert pool\")\n\t}\n\treturn certPool, nil\n}\n\nfunc CreateTunnelConfig(c *cli.Context, serverName string) (*tls.Config, error) {\n\tvar rootCAs []string\n\tif c.String(CaCertFlag) != \"\" {\n\t\trootCAs = append(rootCAs, c.String(CaCertFlag))\n\t}\n\n\tuserConfig := &TLSParameters{RootCAs: rootCAs, ServerName: serverName}\n\ttlsConfig, err := GetConfig(userConfig)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif tlsConfig.RootCAs == nil {\n\t\trootCAPool, err := x509.SystemCertPool()\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"unable to get x509 system cert pool\")\n\t\t}\n\t\tcfRootCA, err := GetCloudflareRootCA()\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"could not append Cloudflare Root CAs to cloudflared certificate pool\")\n\t\t}\n\t\tfor _, cert := range cfRootCA {\n\t\t\trootCAPool.AddCert(cert)\n\t\t}\n\t\ttlsConfig.RootCAs = rootCAPool\n\t}\n\n\tif tlsConfig.ServerName == \"\" && !tlsConfig.InsecureSkipVerify {\n\t\treturn nil, fmt.Errorf(\"either ServerName or InsecureSkipVerify must be specified in the tls.Config\")\n\t}\n\treturn tlsConfig, nil\n}\n\nfunc loadOriginCertPool(originCAPoolPEM []byte, log *zerolog.Logger) (*x509.CertPool, error) {\n\t// Get the global pool\n\tcertPool, err := loadGlobalCertPool(log)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Then, add any custom origin CA pool the user may have passed\n\tif originCAPoolPEM != nil {\n\t\tif !certPool.AppendCertsFromPEM(originCAPoolPEM) {\n\t\t\tlog.Info().Msg(\"could not append the provided origin CA to the cloudflared certificate pool\")\n\t\t}\n\t}\n\n\treturn certPool, nil\n}\n\nfunc loadGlobalCertPool(log *zerolog.Logger) (*x509.CertPool, error) {\n\t// First, obtain the system certificate pool\n\tcertPool, err := x509.SystemCertPool()\n\tif err != nil {\n\t\tif runtime.GOOS != \"windows\" { // See https://github.com/golang/go/issues/16736\n\t\t\tlog.Err(err).Msg(\"error obtaining the system certificates\")\n\t\t}\n\t\tcertPool = x509.NewCertPool()\n\t}\n\n\t// Next, append the Cloudflare CAs into the system pool\n\tcfRootCA, err := GetCloudflareRootCA()\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"could not append Cloudflare Root CAs to cloudflared certificate pool\")\n\t}\n\tfor _, cert := range cfRootCA {\n\t\tcertPool.AddCert(cert)\n\t}\n\n\t// Finally, add the Hello certificate into the pool (since it's self-signed)\n\thelloCert, err := GetHelloCertificateX509()\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"could not append Hello server certificate to cloudflared certificate pool\")\n\t}\n\tcertPool.AddCert(helloCert)\n\n\treturn certPool, nil\n}\n"
  },
  {
    "path": "tlsconfig/cloudflare_ca.go",
    "content": "package tlsconfig\n\nimport (\n\t\"crypto/x509\"\n\t\"encoding/pem\"\n)\n\n// TODO: remove the Origin CA root certs when migrated to Authenticated Origin Pull certs\nvar cloudflareRootCA = []byte(`\nIssuer: C=US, ST=California, L=San Francisco, O=CloudFlare, Inc., OU=CloudFlare Origin SSL ECC Certificate Authority\n-----BEGIN CERTIFICATE-----\nMIICiTCCAi6gAwIBAgIUXZP3MWb8MKwBE1Qbawsp1sfA/Y4wCgYIKoZIzj0EAwIw\ngY8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T\nYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMTgwNgYDVQQL\nEy9DbG91ZEZsYXJlIE9yaWdpbiBTU0wgRUNDIENlcnRpZmljYXRlIEF1dGhvcml0\neTAeFw0xOTA4MjMyMTA4MDBaFw0yOTA4MTUxNzAwMDBaMIGPMQswCQYDVQQGEwJV\nUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEZ\nMBcGA1UEChMQQ2xvdWRGbGFyZSwgSW5jLjE4MDYGA1UECxMvQ2xvdWRGbGFyZSBP\ncmlnaW4gU1NMIEVDQyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwWTATBgcqhkjOPQIB\nBggqhkjOPQMBBwNCAASR+sGALuaGshnUbcxKry+0LEXZ4NY6JUAtSeA6g87K3jaA\nxpIg9G50PokpfWkhbarLfpcZu0UAoYy2su0EhN7wo2YwZDAOBgNVHQ8BAf8EBAMC\nAQYwEgYDVR0TAQH/BAgwBgEB/wIBAjAdBgNVHQ4EFgQUhTBdOypw1O3VkmcH/es5\ntBoOOKcwHwYDVR0jBBgwFoAUhTBdOypw1O3VkmcH/es5tBoOOKcwCgYIKoZIzj0E\nAwIDSQAwRgIhAKilfntP2ILGZjwajktkBtXE1pB4Y/fjAfLkIRUzrI15AiEA5UCL\nXYZZ9m2c3fKwIenMMojL1eqydsgqj/wK4p5kagQ=\n-----END CERTIFICATE-----\nIssuer: C=US, O=CloudFlare, Inc., OU=CloudFlare Origin SSL Certificate Authority, L=San Francisco, ST=California\n-----BEGIN CERTIFICATE-----\nMIIEADCCAuigAwIBAgIID+rOSdTGfGcwDQYJKoZIhvcNAQELBQAwgYsxCzAJBgNV\nBAYTAlVTMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMTQwMgYDVQQLEytDbG91\nZEZsYXJlIE9yaWdpbiBTU0wgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MRYwFAYDVQQH\nEw1TYW4gRnJhbmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMB4XDTE5MDgyMzIx\nMDgwMFoXDTI5MDgxNTE3MDAwMFowgYsxCzAJBgNVBAYTAlVTMRkwFwYDVQQKExBD\nbG91ZEZsYXJlLCBJbmMuMTQwMgYDVQQLEytDbG91ZEZsYXJlIE9yaWdpbiBTU0wg\nQ2VydGlmaWNhdGUgQXV0aG9yaXR5MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRMw\nEQYDVQQIEwpDYWxpZm9ybmlhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\nAQEAwEiVZ/UoQpHmFsHvk5isBxRehukP8DG9JhFev3WZtG76WoTthvLJFRKFCHXm\nV6Z5/66Z4S09mgsUuFwvJzMnE6Ej6yIsYNCb9r9QORa8BdhrkNn6kdTly3mdnykb\nOomnwbUfLlExVgNdlP0XoRoeMwbQ4598foiHblO2B/LKuNfJzAMfS7oZe34b+vLB\nyrP/1bgCSLdc1AxQc1AC0EsQQhgcyTJNgnG4va1c7ogPlwKyhbDyZ4e59N5lbYPJ\nSmXI/cAe3jXj1FBLJZkwnoDKe0v13xeF+nF32smSH0qB7aJX2tBMW4TWtFPmzs5I\nlwrFSySWAdwYdgxw180yKU0dvwIDAQABo2YwZDAOBgNVHQ8BAf8EBAMCAQYwEgYD\nVR0TAQH/BAgwBgEB/wIBAjAdBgNVHQ4EFgQUJOhTV118NECHqeuU27rhFnj8KaQw\nHwYDVR0jBBgwFoAUJOhTV118NECHqeuU27rhFnj8KaQwDQYJKoZIhvcNAQELBQAD\nggEBAHwOf9Ur1l0Ar5vFE6PNrZWrDfQIMyEfdgSKofCdTckbqXNTiXdgbHs+TWoQ\nwAB0pfJDAHJDXOTCWRyTeXOseeOi5Btj5CnEuw3P0oXqdqevM1/+uWp0CM35zgZ8\nVD4aITxity0djzE6Qnx3Syzz+ZkoBgTnNum7d9A66/V636x4vTeqbZFBr9erJzgz\nhhurjcoacvRNhnjtDRM0dPeiCJ50CP3wEYuvUzDHUaowOsnLCjQIkWbR7Ni6KEIk\nMOz2U0OBSif3FTkhCgZWQKOOLo1P42jHC3ssUZAtVNXrCk3fw9/E15k8NPkBazZ6\n0iykLhH1trywrKRMVw67F44IE8Y=\n-----END CERTIFICATE-----\nIssuer: C=US, O=CloudFlare, Inc., OU=Origin Pull, L=San Francisco, ST=California, CN=origin-pull.cloudflare.net\n-----BEGIN CERTIFICATE-----\nMIIGCjCCA/KgAwIBAgIIV5G6lVbCLmEwDQYJKoZIhvcNAQENBQAwgZAxCzAJBgNV\nBAYTAlVTMRkwFwYDVQQKExBDbG91ZEZsYXJlLCBJbmMuMRQwEgYDVQQLEwtPcmln\naW4gUHVsbDEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZv\ncm5pYTEjMCEGA1UEAxMab3JpZ2luLXB1bGwuY2xvdWRmbGFyZS5uZXQwHhcNMTkx\nMDEwMTg0NTAwWhcNMjkxMTAxMTcwMDAwWjCBkDELMAkGA1UEBhMCVVMxGTAXBgNV\nBAoTEENsb3VkRmxhcmUsIEluYy4xFDASBgNVBAsTC09yaWdpbiBQdWxsMRYwFAYD\nVQQHEw1TYW4gRnJhbmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMSMwIQYDVQQD\nExpvcmlnaW4tcHVsbC5jbG91ZGZsYXJlLm5ldDCCAiIwDQYJKoZIhvcNAQEBBQAD\nggIPADCCAgoCggIBAN2y2zojYfl0bKfhp0AJBFeV+jQqbCw3sHmvEPwLmqDLqynI\n42tZXR5y914ZB9ZrwbL/K5O46exd/LujJnV2b3dzcx5rtiQzso0xzljqbnbQT20e\nihx/WrF4OkZKydZzsdaJsWAPuplDH5P7J82q3re88jQdgE5hqjqFZ3clCG7lxoBw\nhLaazm3NJJlUfzdk97ouRvnFGAuXd5cQVx8jYOOeU60sWqmMe4QHdOvpqB91bJoY\nQSKVFjUgHeTpN8tNpKJfb9LIn3pun3bC9NKNHtRKMNX3Kl/sAPq7q/AlndvA2Kw3\nDkum2mHQUGdzVHqcOgea9BGjLK2h7SuX93zTWL02u799dr6Xkrad/WShHchfjjRn\naL35niJUDr02YJtPgxWObsrfOU63B8juLUphW/4BOjjJyAG5l9j1//aUGEi/sEe5\nlqVv0P78QrxoxR+MMXiJwQab5FB8TG/ac6mRHgF9CmkX90uaRh+OC07XjTdfSKGR\nPpM9hB2ZhLol/nf8qmoLdoD5HvODZuKu2+muKeVHXgw2/A6wM7OwrinxZiyBk5Hh\nCvaADH7PZpU6z/zv5NU5HSvXiKtCzFuDu4/Zfi34RfHXeCUfHAb4KfNRXJwMsxUa\n+4ZpSAX2G6RnGU5meuXpU5/V+DQJp/e69XyyY6RXDoMywaEFlIlXBqjRRA2pAgMB\nAAGjZjBkMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgECMB0GA1Ud\nDgQWBBRDWUsraYuA4REzalfNVzjann3F6zAfBgNVHSMEGDAWgBRDWUsraYuA4REz\nalfNVzjann3F6zANBgkqhkiG9w0BAQ0FAAOCAgEAkQ+T9nqcSlAuW/90DeYmQOW1\nQhqOor5psBEGvxbNGV2hdLJY8h6QUq48BCevcMChg/L1CkznBNI40i3/6heDn3IS\nzVEwXKf34pPFCACWVMZxbQjkNRTiH8iRur9EsaNQ5oXCPJkhwg2+IFyoPAAYURoX\nVcI9SCDUa45clmYHJ/XYwV1icGVI8/9b2JUqklnOTa5tugwIUi5sTfipNcJXHhgz\n6BKYDl0/UP0lLKbsUETXeTGDiDpxZYIgbcFrRDDkHC6BSvdWVEiH5b9mH2BON60z\n0O0j8EEKTwi9jnafVtZQXP/D8yoVowdFDjXcKkOPF/1gIh9qrFR6GdoPVgB3SkLc\n5ulBqZaCHm563jsvWb/kXJnlFxW+1bsO9BDD6DweBcGdNurgmH625wBXksSdD7y/\nfakk8DagjbjKShYlPEFOAqEcliwjF45eabL0t27MJV61O/jHzHL3dknXeE4BDa2j\nbA+JbyJeUMtU7KMsxvx82RmhqBEJJDBCJ3scVptvhDMRrtqDBW5JShxoAOcpFQGm\niYWicn46nPDjgTU0bX1ZPpTpryXbvciVL5RkVBuyX2ntcOLDPlZWgxZCBp96x07F\nAnOzKgZk4RzZPNAxCXERVxajn/FLcOhglVAKo5H0ac+AitlQ0ip55D2/mf8o72tM\nfVQ6VpyjEXdiIXWUq/o=\n-----END CERTIFICATE-----`)\n\nfunc GetCloudflareRootCA() ([]*x509.Certificate, error) {\n\tvar certs []*x509.Certificate\n\tpemBlocks := cloudflareRootCA\n\tfor len(pemBlocks) > 0 {\n\t\tvar block *pem.Block\n\t\tblock, pemBlocks = pem.Decode(pemBlocks)\n\t\tif block == nil {\n\t\t\tbreak\n\t\t}\n\t\tif block.Type != \"CERTIFICATE\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tcert, err := x509.ParseCertificate(block.Bytes)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tcerts = append(certs, cert)\n\t}\n\n\treturn certs, nil\n}\n"
  },
  {
    "path": "tlsconfig/hello_ca.go",
    "content": "package tlsconfig\n\nimport (\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n)\n\nconst (\n\thelloKey = `\n-----BEGIN EC PARAMETERS-----\nBgUrgQQAIg==\n-----END EC PARAMETERS-----\n-----BEGIN EC PRIVATE KEY-----\nMIGkAgEBBDBGGfwhIJdiUiJUVIItqJjEIMmlXxsMa8TQeer47+g+cIZ466rgg8EK\n+Mdn6BY48GCgBwYFK4EEACKhZANiAASW//A9iDbPKg3OLkn7yJqLer32g9I5lBKR\ntPc/zBubQLLz9lAaYI6AOQiJXhGr5JkKmQfi1sYHK5rJITPFy4W8Et4hHLdazDZH\nWnEd+TStQABFUjrhtqXPWmGKcly0pOE=\n-----END EC PRIVATE KEY-----`\n\n\thelloCRT = `\n-----BEGIN CERTIFICATE-----\nMIICiDCCAg6gAwIBAgIJAJ/FfkBTtbuIMAkGByqGSM49BAEwfzELMAkGA1UEBhMC\nVVMxDjAMBgNVBAgMBVRleGFzMQ8wDQYDVQQHDAZBdXN0aW4xGTAXBgNVBAoMEENs\nb3VkZmxhcmUsIEluYy4xNDAyBgNVBAMMK0FyZ28gVHVubmVsIFNhbXBsZSBIZWxs\nbyBTZXJ2ZXIgQ2VydGlmaWNhdGUwHhcNMTgwMzE5MjMwNTMyWhcNMjgwMzE2MjMw\nNTMyWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkF1\nc3RpbjEZMBcGA1UECgwQQ2xvdWRmbGFyZSwgSW5jLjE0MDIGA1UEAwwrQXJnbyBU\ndW5uZWwgU2FtcGxlIEhlbGxvIFNlcnZlciBDZXJ0aWZpY2F0ZTB2MBAGByqGSM49\nAgEGBSuBBAAiA2IABJb/8D2INs8qDc4uSfvImot6vfaD0jmUEpG09z/MG5tAsvP2\nUBpgjoA5CIleEavkmQqZB+LWxgcrmskhM8XLhbwS3iEct1rMNkdacR35NK1AAEVS\nOuG2pc9aYYpyXLSk4aNXMFUwUwYDVR0RBEwwSoIJbG9jYWxob3N0ghFjbG91ZGZs\nYXJlZC1oZWxsb4ISY2xvdWRmbGFyZWQyLWhlbGxvhwR/AAABhxAAAAAAAAAAAAAA\nAAAAAAABMAkGByqGSM49BAEDaQAwZgIxAPxkdghH6y8xLMnY9Bom3Llf4NYM6yB9\nPD1YsaNUJTsxjTk3YY1Jsp+yzK0yUKtTZwIxAPcdvqCF2/iR9H288pCT1TgtO0a9\ncJL9RY1lq7DIGN37v1ZXReWaD+3hNokY8NriVg==\n-----END CERTIFICATE-----`\n)\n\nfunc GetHelloCertificate() (tls.Certificate, error) {\n\treturn tls.X509KeyPair([]byte(helloCRT), []byte(helloKey))\n}\n\nfunc GetHelloCertificateX509() (*x509.Certificate, error) {\n\thelloCertificate, err := GetHelloCertificate()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn x509.ParseCertificate(helloCertificate.Certificate[0])\n}\n"
  },
  {
    "path": "tlsconfig/testcert.pem",
    "content": "-----BEGIN CERTIFICATE-----\nMIICBjCCAbCgAwIBAgIJAPKk4bYMrSFMMA0GCSqGSIb3DQEBCwUAMF0xCzAJBgNV\nBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEPMA0GA1UEBwwGQXVzdGluMRkwFwYDVQQK\nDBBDbG91ZGZsYXJlLCBJbmMuMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMTgxMTE1\nMjA1NzU3WhcNMjgxMTEyMjA1NzU3WjBdMQswCQYDVQQGEwJVUzEOMAwGA1UECAwF\nVGV4YXMxDzANBgNVBAcMBkF1c3RpbjEZMBcGA1UECgwQQ2xvdWRmbGFyZSwgSW5j\nLjESMBAGA1UEAwwJbG9jYWxob3N0MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOQN\npTRn5wLf8SSI5x2kpDvbdDy7lfhamJ2En4Q+wy1cSKp8bn8/oyhVF7QTsimDGTI4\n45pV9nDfNJPYB3IW0x0CAwEAAaNTMFEwHQYDVR0OBBYEFE4jIa97mIEiYFa02X++\nuu5mCEn+MB8GA1UdIwQYMBaAFE4jIa97mIEiYFa02X++uu5mCEn+MA8GA1UdEwEB\n/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADQQAkE+pDee0o5cNcZRUszy8sTQzB1Wlp\nJ6ucfmo16crqRaK7uGvhkMyibIc4D8z2Cxw3aI3IMMFoIIlYoYKiUcbd\n-----END CERTIFICATE-----"
  },
  {
    "path": "tlsconfig/testcert2.pem",
    "content": "-----BEGIN CERTIFICATE-----\nMIICBjCCAbCgAwIBAgIJAN6cXRTbJtFnMA0GCSqGSIb3DQEBCwUAMF0xCzAJBgNV\nBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEPMA0GA1UEBwwGQXVzdGluMRgwFgYDVQQK\nDA9DbG91ZGZsYXJlLCBJbmMxEzARBgNVBAMMCmxvY2FsaG9zdDIwHhcNMTgxMTE1\nMjExMTU4WhcNMjgxMTEyMjExMTU4WjBdMQswCQYDVQQGEwJVUzEOMAwGA1UECAwF\nVGV4YXMxDzANBgNVBAcMBkF1c3RpbjEYMBYGA1UECgwPQ2xvdWRmbGFyZSwgSW5j\nMRMwEQYDVQQDDApsb2NhbGhvc3QyMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKQx\nIMZ6QgXoul2ITF/7sly4fW2Ol+a/AYw42zCWhVqOXv8AhY21I0Q8lkRR6wOroQwZ\nO7jKKOcE5TnR/NRcZr8CAwEAAaNTMFEwHQYDVR0OBBYEFONKxLZc2RUD0KTHkAz4\n8nrb5688MB8GA1UdIwQYMBaAFONKxLZc2RUD0KTHkAz48nrb5688MA8GA1UdEwEB\n/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADQQA56pwhvGpNPjyLcWfJHu/vI3ZjdoLB\nLnrkRaMjJmv0H0Beh4upJhoz8u6lhMACerKQrrdQhEPB2u+maFrEBtmN\n-----END CERTIFICATE-----"
  },
  {
    "path": "tlsconfig/testkey.pem",
    "content": "-----BEGIN PRIVATE KEY-----\nMIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEA5A2lNGfnAt/xJIjn\nHaSkO9t0PLuV+FqYnYSfhD7DLVxIqnxufz+jKFUXtBOyKYMZMjjjmlX2cN80k9gH\nchbTHQIDAQABAkAoeDtu91lJa1AxuZG58vOqI6GW/Xr5naojmdts7m5YaAhDa7DE\nzJUp4d8SP5cGBf1/PB3x6Cu9UviFNQ16wmzJAiEA8gUm4UYpWZD4Ze2l/xb+BK8D\nIglSUIy1VxW+X1G55wMCIQDxOfXiFzPqnv/e5avKGv6CU11Dhmbi1OpiyybZTjGz\nXwIhAM3bE/cJdqJ4bNBGE6umIupY8pFA3IMnLBempwbsvPOBAiEAgzJ+5OSxu92W\nVGidsmJUIhWtF9i1hJFAmVLcYjwBFAkCICtjP/vv0qOZWk4mAAn2zz9UVWp45DSR\np/FA8V77ohXD\n-----END PRIVATE KEY-----\n"
  },
  {
    "path": "tlsconfig/tlsconfig.go",
    "content": "// Package tlsconfig provides convenience functions for configuring TLS connections from the\n// command line.\npackage tlsconfig\n\nimport (\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"os\"\n\n\t\"github.com/pkg/errors\"\n)\n\n// Config is the user provided parameters to create a tls.Config\ntype TLSParameters struct {\n\tCert                 string\n\tKey                  string\n\tGetCertificate       *CertReloader\n\tGetClientCertificate *CertReloader\n\tClientCAs            []string\n\tRootCAs              []string\n\tServerName           string\n\tCurvePreferences     []tls.CurveID\n\tMinVersion           uint16 // min tls version. If zero, TLS1.0 is defined as minimum.\n\tMaxVersion           uint16 // max tls version. If zero, last TLS version is used defined as limit (currently TLS1.3)\n}\n\n// GetConfig returns a TLS configuration according to the Config set by the user.\nfunc GetConfig(p *TLSParameters) (*tls.Config, error) {\n\ttlsconfig := &tls.Config{}\n\tif p.Cert != \"\" && p.Key != \"\" {\n\t\tcert, err := tls.LoadX509KeyPair(p.Cert, p.Key)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"Error parsing X509 key pair\")\n\t\t}\n\t\ttlsconfig.Certificates = []tls.Certificate{cert}\n\t\t// BuildNameToCertificate parses Certificates and builds NameToCertificate from common name\n\t\t// and SAN fields of leaf certificates\n\t\ttlsconfig.BuildNameToCertificate()\n\t}\n\n\tif p.GetCertificate != nil {\n\t\t// GetCertificate is called when client supplies SNI info or Certificates is empty.\n\t\t// Order of retrieving certificate is GetCertificate, NameToCertificate and lastly first element of Certificates\n\t\ttlsconfig.GetCertificate = p.GetCertificate.Cert\n\t}\n\n\tif p.GetClientCertificate != nil {\n\t\t// GetClientCertificate is called when using an HTTP client library and mTLS is required.\n\t\ttlsconfig.GetClientCertificate = p.GetClientCertificate.ClientCert\n\t}\n\n\tif len(p.ClientCAs) > 0 {\n\t\t// set of root certificate authorities that servers use if required to verify a client certificate\n\t\t// by the policy in ClientAuth\n\t\tclientCAs, err := LoadCert(p.ClientCAs)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"Error loading client CAs\")\n\t\t}\n\t\ttlsconfig.ClientCAs = clientCAs\n\t\t// server's policy for TLS Client Authentication. Default is no client cert\n\t\ttlsconfig.ClientAuth = tls.RequireAndVerifyClientCert\n\t}\n\n\tif len(p.RootCAs) > 0 {\n\t\trootCAs, err := LoadCert(p.RootCAs)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"Error loading root CAs\")\n\t\t}\n\t\ttlsconfig.RootCAs = rootCAs\n\t}\n\n\tif p.ServerName != \"\" {\n\t\ttlsconfig.ServerName = p.ServerName\n\t}\n\n\tif len(p.CurvePreferences) > 0 {\n\t\ttlsconfig.CurvePreferences = p.CurvePreferences\n\t} else {\n\t\t// Cloudflare optimize CurveP256\n\t\ttlsconfig.CurvePreferences = []tls.CurveID{tls.CurveP256}\n\t}\n\n\ttlsconfig.MinVersion = p.MinVersion\n\ttlsconfig.MaxVersion = p.MaxVersion\n\n\treturn tlsconfig, nil\n}\n\n// LoadCert creates a CertPool containing all certificates in a PEM-format file.\nfunc LoadCert(certPaths []string) (*x509.CertPool, error) {\n\tca := x509.NewCertPool()\n\tfor _, certPath := range certPaths {\n\t\tcaCert, err := os.ReadFile(certPath)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrapf(err, \"Error reading certificate %s\", certPath)\n\t\t}\n\t\tif !ca.AppendCertsFromPEM(caCert) {\n\t\t\treturn nil, errors.Wrapf(err, \"Error parsing certificate %s\", certPath)\n\t\t}\n\t}\n\treturn ca, nil\n}\n"
  },
  {
    "path": "tlsconfig/tlsconfig_test.go",
    "content": "package tlsconfig\n\nimport (\n\t\"crypto/tls\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\n// testcert.pem and testcert2.pem are Generated using `openssl req -newkey rsa:512 -nodes -x509 -days 3650`\nconst (\n\ttestcertCommonName = \"localhost\"\n)\n\nfunc TestGetFromEmptyConfig(t *testing.T) {\n\tc := &TLSParameters{}\n\n\ttlsConfig, err := GetConfig(c)\n\tassert.NoError(t, err)\n\tassert.Empty(t, tlsConfig.Certificates)\n\n\tassert.Empty(t, tlsConfig.NameToCertificate)\n\n\tassert.Nil(t, tlsConfig.ClientCAs)\n\tassert.Equal(t, tls.NoClientCert, tlsConfig.ClientAuth)\n\n\tassert.Nil(t, tlsConfig.RootCAs)\n\n\tassert.Len(t, tlsConfig.CurvePreferences, 1)\n\tassert.Equal(t, tls.CurveP256, tlsConfig.CurvePreferences[0])\n}\n\nfunc TestGetConfig(t *testing.T) {\n\tcert, err := tls.LoadX509KeyPair(\"testcert.pem\", \"testkey.pem\")\n\tassert.NoError(t, err)\n\n\tc := &TLSParameters{\n\t\tCert:             \"testcert.pem\",\n\t\tKey:              \"testkey.pem\",\n\t\tClientCAs:        []string{\"testcert.pem\", \"testcert2.pem\"},\n\t\tRootCAs:          []string{\"testcert.pem\", \"testcert2.pem\"},\n\t\tServerName:       \"test\",\n\t\tCurvePreferences: []tls.CurveID{tls.CurveP384},\n\t}\n\ttlsConfig, err := GetConfig(c)\n\tassert.NoError(t, err)\n\tassert.Len(t, tlsConfig.Certificates, 1)\n\tassert.Equal(t, cert, tlsConfig.Certificates[0])\n\n\tassert.Equal(t, cert, *tlsConfig.NameToCertificate[testcertCommonName])\n\n\tassert.NotNil(t, tlsConfig.ClientCAs)\n\tassert.Equal(t, tls.RequireAndVerifyClientCert, tlsConfig.ClientAuth)\n\n\tassert.NotNil(t, tlsConfig.RootCAs)\n\n\tassert.Len(t, tlsConfig.CurvePreferences, 1)\n\tassert.Equal(t, tls.CurveP384, tlsConfig.CurvePreferences[0])\n}\n\nfunc TestCertReloader(t *testing.T) {\n\texpectedCert, err := tls.LoadX509KeyPair(\"testcert.pem\", \"testkey.pem\")\n\tassert.NoError(t, err)\n\n\tcertReloader, err := NewCertReloader(\"testcert.pem\", \"testkey.pem\")\n\tassert.NoError(t, err)\n\n\tchi := &tls.ClientHelloInfo{ServerName: testcertCommonName}\n\tcert, err := certReloader.Cert(chi)\n\tassert.NoError(t, err)\n\tassert.Equal(t, expectedCert, *cert)\n\n\tc := &TLSParameters{\n\t\tGetCertificate: certReloader,\n\t}\n\ttlsConfig, err := GetConfig(c)\n\tassert.NoError(t, err)\n\n\tcert, err = tlsConfig.GetCertificate(chi)\n\tassert.NoError(t, err)\n\tassert.Equal(t, expectedCert, *cert)\n}\n"
  },
  {
    "path": "token/encrypt.go",
    "content": "// Package encrypter is suitable for encrypting messages you would like to securely share between two points.\n// Useful for providing end to end encryption (E2EE). It uses Box (NaCl) for encrypting the messages.\n// tldr is it uses Elliptic Curves (Curve25519) for the keys, XSalsa20 and Poly1305 for encryption.\n// You can read more here https://godoc.org/golang.org/x/crypto/nacl/box.\n//\n//\tmsg := []byte(\"super safe message.\")\n//\talice, err := NewEncrypter(\"alice_priv_key.pem\", \"alice_pub_key.pem\")\n//\tif err != nil {\n//\t\tlog.Fatal(err)\n//\t}\n//\n//\tbob, err := NewEncrypter(\"bob_priv_key.pem\", \"bob_pub_key.pem\")\n//\tif err != nil {\n//\t\tlog.Fatal(err)\n//\t}\n//\tencrypted, err := alice.Encrypt(msg, bob.PublicKey())\n//\tif err != nil {\n//\t\tlog.Fatal(err)\n//\t}\n//\n//\tdata, err := bob.Decrypt(encrypted, alice.PublicKey())\n//\tif err != nil {\n//\t\tlog.Fatal(err)\n//\t}\n//\tfmt.Println(string(data))\npackage token\n\nimport (\n\t\"bytes\"\n\t\"crypto/rand\"\n\t\"encoding/base64\"\n\t\"encoding/pem\"\n\t\"errors\"\n\t\"io\"\n\t\"os\"\n\n\t\"golang.org/x/crypto/nacl/box\"\n)\n\n// Encrypter represents a keypair value with auxiliary functions to make\n// doing encryption and decryption easier\ntype Encrypter struct {\n\tprivateKey *[32]byte\n\tpublicKey  *[32]byte\n}\n\n// NewEncrypter returns a new encrypter with initialized keypair\nfunc NewEncrypter(privateKey, publicKey string) (*Encrypter, error) {\n\te := &Encrypter{}\n\tpubKey, key, err := e.fetchOrGenerateKeys(privateKey, publicKey)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\te.privateKey, e.publicKey = key, pubKey\n\treturn e, nil\n}\n\n// PublicKey returns a base64 encoded public key. Useful for transport (like in HTTP requests)\nfunc (e *Encrypter) PublicKey() string {\n\treturn base64.URLEncoding.EncodeToString(e.publicKey[:])\n}\n\n// Decrypt data that was encrypted using our publicKey. It will use our privateKey and the sender's publicKey to decrypt\n// data is an encrypted buffer of data, mostly like from the Encrypt function. Messages contain the nonce data on the front\n// of the message.\n// senderPublicKey is a base64 encoded version of the sender's public key (most likely from the PublicKey function).\n// The return value is the decrypted buffer or an error.\nfunc (e *Encrypter) Decrypt(data []byte, senderPublicKey string) ([]byte, error) {\n\tvar decryptNonce [24]byte\n\tcopy(decryptNonce[:], data[:24]) // we pull the nonce from the front of the actual message.\n\tpubKey, err := e.decodePublicKey(senderPublicKey)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdecrypted, ok := box.Open(nil, data[24:], &decryptNonce, pubKey, e.privateKey)\n\tif !ok {\n\t\treturn nil, errors.New(\"failed to decrypt message\")\n\t}\n\treturn decrypted, nil\n}\n\n// Encrypt data using our privateKey and the recipient publicKey\n// data is a buffer of data that we would like to encrypt. Messages will have the nonce added to front\n// as they have to unique for each message shared.\n// recipientPublicKey is a base64 encoded version of the sender's public key (most likely from the PublicKey function).\n// The return value is the encrypted buffer or an error.\nfunc (e *Encrypter) Encrypt(data []byte, recipientPublicKey string) ([]byte, error) {\n\tvar nonce [24]byte\n\tif _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {\n\t\treturn nil, err\n\t}\n\n\tpubKey, err := e.decodePublicKey(recipientPublicKey)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// This encrypts msg and adds the nonce to the front of the message, since the nonce has to be\n\t// the same for encrypting and decrypting\n\treturn box.Seal(nonce[:], data, &nonce, pubKey, e.privateKey), nil\n}\n\n// WriteKeys keys will take the currently initialized keypair and write them to provided filenames\nfunc (e *Encrypter) WriteKeys(privateKey, publicKey string) error {\n\tif err := e.writeKey(e.privateKey[:], \"BOX PRIVATE KEY\", privateKey); err != nil {\n\t\treturn err\n\t}\n\treturn e.writeKey(e.publicKey[:], \"PUBLIC KEY\", publicKey)\n}\n\n// fetchOrGenerateKeys will either load or create a keypair if it doesn't exist\nfunc (e *Encrypter) fetchOrGenerateKeys(privateKey, publicKey string) (*[32]byte, *[32]byte, error) {\n\tkey, err := e.fetchKey(privateKey)\n\tif os.IsNotExist(err) {\n\t\treturn box.GenerateKey(rand.Reader)\n\t} else if err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tpub, err := e.fetchKey(publicKey)\n\tif os.IsNotExist(err) {\n\t\treturn box.GenerateKey(rand.Reader)\n\t} else if err != nil {\n\t\treturn nil, nil, err\n\t}\n\treturn pub, key, nil\n}\n\n// writeKey will write a key to disk in DER format (it's a standard pem key)\nfunc (e *Encrypter) writeKey(key []byte, pemType, filename string) error {\n\tdata := pem.EncodeToMemory(&pem.Block{\n\t\tType:  pemType,\n\t\tBytes: key,\n\t})\n\n\tf, err := os.Create(filename)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_, err = f.Write(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// fetchKey will load a a DER formatted key from disk\nfunc (e *Encrypter) fetchKey(filename string) (*[32]byte, error) {\n\tf, err := os.Open(filename)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tbuf := new(bytes.Buffer)\n\tio.Copy(buf, f)\n\n\tp, _ := pem.Decode(buf.Bytes())\n\tif p == nil {\n\t\treturn nil, errors.New(\"Failed to decode key\")\n\t}\n\tvar newKey [32]byte\n\tcopy(newKey[:], p.Bytes)\n\n\treturn &newKey, nil\n}\n\n// decodePublicKey will base64 decode the provided key to the box representation\nfunc (e *Encrypter) decodePublicKey(key string) (*[32]byte, error) {\n\tpub, err := base64.URLEncoding.DecodeString(key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar newKey [32]byte\n\tcopy(newKey[:], pub)\n\treturn &newKey, nil\n}\n"
  },
  {
    "path": "token/launch_browser_darwin.go",
    "content": "//go:build darwin\n\npackage token\n\nimport (\n\t\"os/exec\"\n)\n\nfunc getBrowserCmd(url string) *exec.Cmd {\n\treturn exec.Command(\"open\", url)\n}\n"
  },
  {
    "path": "token/launch_browser_other.go",
    "content": "//go:build !windows && !darwin && !linux && !netbsd && !freebsd && !openbsd\n\npackage token\n\nimport (\n\t\"os/exec\"\n)\n\nfunc getBrowserCmd(url string) *exec.Cmd {\n\treturn nil\n}\n"
  },
  {
    "path": "token/launch_browser_unix.go",
    "content": "//go:build linux || freebsd || openbsd || netbsd\n\npackage token\n\nimport (\n\t\"os/exec\"\n)\n\nfunc getBrowserCmd(url string) *exec.Cmd {\n\treturn exec.Command(\"xdg-open\", url)\n}\n"
  },
  {
    "path": "token/launch_browser_windows.go",
    "content": "//go:build windows\n\npackage token\n\nimport (\n\t\"fmt\"\n\t\"os/exec\"\n\t\"syscall\"\n)\n\nfunc getBrowserCmd(url string) *exec.Cmd {\n\tcmd := exec.Command(\"cmd\")\n\t// CmdLine is only defined when compiling for windows.\n\t// Empty string is the cmd proc \"Title\". Needs to be included because the start command will interpret the first\n\t// quoted string as that field and we want to quote the URL.\n\tcmd.SysProcAttr = &syscall.SysProcAttr{CmdLine: fmt.Sprintf(`/c start \"\" \"%s\"`, url)}\n\treturn cmd\n}\n"
  },
  {
    "path": "token/path.go",
    "content": "package token\n\nimport (\n\t\"fmt\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\thomedir \"github.com/mitchellh/go-homedir\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n)\n\n// GenerateSSHCertFilePathFromURL will return a file path for creating short lived certificates\nfunc GenerateSSHCertFilePathFromURL(url *url.URL, suffix string) (string, error) {\n\tconfigPath, err := getConfigPath()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tname := strings.Replace(fmt.Sprintf(\"%s%s-%s\", url.Hostname(), url.EscapedPath(), suffix), \"/\", \"-\", -1)\n\treturn filepath.Join(configPath, name), nil\n}\n\n// GenerateAppTokenFilePathFromURL will return a filepath for given Access org token\nfunc GenerateAppTokenFilePathFromURL(appDomain, aud string, suffix string) (string, error) {\n\tconfigPath, err := getConfigPath()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tname := fmt.Sprintf(\"%s-%s-%s\", appDomain, aud, suffix)\n\tname = strings.Replace(strings.Replace(name, \"/\", \"-\", -1), \"*\", \"-\", -1)\n\treturn filepath.Join(configPath, name), nil\n}\n\n// generateOrgTokenFilePathFromURL will return a filepath for given Access application token\nfunc generateOrgTokenFilePathFromURL(authDomain string) (string, error) {\n\tconfigPath, err := getConfigPath()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tname := strings.Replace(fmt.Sprintf(\"%s-org-token\", authDomain), \"/\", \"-\", -1)\n\treturn filepath.Join(configPath, name), nil\n}\n\nfunc getConfigPath() (string, error) {\n\tconfigPath, err := homedir.Expand(config.DefaultConfigSearchDirectories()[0])\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tok, err := config.FileExists(configPath)\n\tif !ok && err == nil {\n\t\t// create config directory if doesn't already exist\n\t\terr = os.Mkdir(configPath, 0700)\n\t}\n\treturn configPath, err\n}\n"
  },
  {
    "path": "token/shell.go",
    "content": "package token\n\n// OpenBrowser opens the specified URL in the default browser of the user\nfunc OpenBrowser(url string) error {\n\treturn getBrowserCmd(url).Start()\n}\n"
  },
  {
    "path": "token/signal_test.go",
    "content": "//go:build linux || darwin\n\npackage token\n\nimport (\n\t\"os\"\n\t\"syscall\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestSignalHandler(t *testing.T) {\n\tsigHandler := signalHandler{signals: []os.Signal{syscall.SIGUSR1}}\n\thandlerRan := false\n\tdone := make(chan struct{})\n\ttimer := time.NewTimer(time.Second)\n\tsigHandler.register(func() {\n\t\thandlerRan = true\n\t\tdone <- struct{}{}\n\t})\n\n\tp, err := os.FindProcess(os.Getpid())\n\trequire.Nil(t, err)\n\tp.Signal(syscall.SIGUSR1)\n\n\t// Blocks for up to one second to make sure the handler callback runs before the assert.\n\tselect {\n\tcase <-done:\n\t\tassert.True(t, handlerRan)\n\tcase <-timer.C:\n\t\tt.Fail()\n\t}\n\tsigHandler.deregister()\n}\n\nfunc TestSignalHandlerClose(t *testing.T) {\n\tsigHandler := signalHandler{signals: []os.Signal{syscall.SIGUSR1}}\n\tdone := make(chan struct{})\n\ttimer := time.NewTimer(time.Second)\n\tsigHandler.register(func() { done <- struct{}{} })\n\tsigHandler.deregister()\n\n\tp, err := os.FindProcess(os.Getpid())\n\trequire.Nil(t, err)\n\tp.Signal(syscall.SIGUSR1)\n\tselect {\n\tcase <-done:\n\t\tt.Fail()\n\tcase <-timer.C:\n\t}\n}\n"
  },
  {
    "path": "token/token.go",
    "content": "package token\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"os/signal\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/go-jose/go-jose/v4\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/config\"\n\t\"github.com/cloudflare/cloudflared/retry\"\n)\n\nconst (\n\tkeyName                    = \"token\"\n\ttokenCookie                = \"CF_Authorization\"\n\tappSessionCookie           = \"CF_AppSession\"\n\tappDomainHeader            = \"CF-Access-Domain\"\n\tappAUDHeader               = \"CF-Access-Aud\"\n\tAccessLoginWorkerPath      = \"/cdn-cgi/access/login\"\n\tAccessAuthorizedWorkerPath = \"/cdn-cgi/access/authorized\"\n)\n\nvar (\n\tuserAgent     = \"DEV\"\n\tsignatureAlgs = []jose.SignatureAlgorithm{jose.RS256}\n)\n\ntype AppInfo struct {\n\tAuthDomain string\n\tAppAUD     string\n\tAppDomain  string\n}\n\ntype lock struct {\n\tlockFilePath string\n\tbackoff      *retry.BackoffHandler\n\tsigHandler   *signalHandler\n}\n\ntype signalHandler struct {\n\tsigChannel chan os.Signal\n\tsignals    []os.Signal\n}\n\ntype jwtPayload struct {\n\tAud   []string `json:\"-\"`\n\tEmail string   `json:\"email\"`\n\tExp   int      `json:\"exp\"`\n\tIat   int      `json:\"iat\"`\n\tNbf   int      `json:\"nbf\"`\n\tIss   string   `json:\"iss\"`\n\tType  string   `json:\"type\"`\n\tSubt  string   `json:\"sub\"`\n}\n\ntype transferServiceResponse struct {\n\tAppToken string `json:\"app_token\"`\n\tOrgToken string `json:\"org_token\"`\n}\n\nfunc (p *jwtPayload) UnmarshalJSON(data []byte) error {\n\ttype Alias jwtPayload\n\tif err := json.Unmarshal(data, (*Alias)(p)); err != nil {\n\t\treturn err\n\t}\n\tvar audParser struct {\n\t\tAud any `json:\"aud\"`\n\t}\n\tif err := json.Unmarshal(data, &audParser); err != nil {\n\t\treturn err\n\t}\n\tswitch aud := audParser.Aud.(type) {\n\tcase string:\n\t\tp.Aud = []string{aud}\n\tcase []any:\n\t\tfor _, a := range aud {\n\t\t\ts, ok := a.(string)\n\t\t\tif !ok {\n\t\t\t\treturn errors.New(\"aud array contains non-string elements\")\n\t\t\t}\n\t\t\tp.Aud = append(p.Aud, s)\n\t\t}\n\tdefault:\n\t\treturn errors.New(\"aud field is not a string or an array of strings\")\n\t}\n\treturn nil\n}\n\nfunc (p jwtPayload) isExpired() bool {\n\treturn int(time.Now().Unix()) > p.Exp\n}\n\nfunc (s *signalHandler) register(handler func()) {\n\ts.sigChannel = make(chan os.Signal, 1)\n\tsignal.Notify(s.sigChannel, s.signals...)\n\tgo func(s *signalHandler) {\n\t\tfor range s.sigChannel {\n\t\t\thandler()\n\t\t}\n\t}(s)\n}\n\nfunc (s *signalHandler) deregister() {\n\tsignal.Stop(s.sigChannel)\n\tclose(s.sigChannel)\n}\n\nfunc errDeleteTokenFailed(lockFilePath string) error {\n\treturn fmt.Errorf(\"failed to acquire a new Access token. Please try to delete %s\", lockFilePath)\n}\n\n// newLock will get a new file lock\nfunc newLock(path string) *lock {\n\tlockPath := path + \".lock\"\n\tbackoff := retry.NewBackoff(uint(7), retry.DefaultBaseTime, false)\n\treturn &lock{\n\t\tlockFilePath: lockPath,\n\t\tbackoff:      &backoff,\n\t\tsigHandler: &signalHandler{\n\t\t\tsignals: []os.Signal{syscall.SIGINT, syscall.SIGTERM},\n\t\t},\n\t}\n}\n\nfunc (l *lock) Acquire() error {\n\t// Intercept SIGINT and SIGTERM to release lock before exiting\n\tl.sigHandler.register(func() {\n\t\t_ = l.deleteLockFile()\n\t\tos.Exit(0)\n\t})\n\n\t// Check for a lock file\n\t// if the lock file exists; start polling\n\t// if not, create the lock file and go through the normal flow.\n\t// See AUTH-1736 for the reason why we do all this\n\tfor isTokenLocked(l.lockFilePath) {\n\t\tif l.backoff.Backoff(context.Background()) {\n\t\t\tcontinue\n\t\t}\n\n\t\tif err := l.deleteLockFile(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// Create a lock file so other processes won't also try to get the token at\n\t// the same time\n\tif err := os.WriteFile(l.lockFilePath, []byte{}, 0600); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (l *lock) deleteLockFile() error {\n\tif err := os.Remove(l.lockFilePath); err != nil && !os.IsNotExist(err) {\n\t\treturn errDeleteTokenFailed(l.lockFilePath)\n\t}\n\treturn nil\n}\n\nfunc (l *lock) Release() error {\n\tdefer l.sigHandler.deregister()\n\treturn l.deleteLockFile()\n}\n\n// isTokenLocked checks to see if there is another process attempting to get the token already\nfunc isTokenLocked(lockFilePath string) bool {\n\texists, err := config.FileExists(lockFilePath)\n\treturn exists && err == nil\n}\n\nfunc Init(version string) {\n\tuserAgent = fmt.Sprintf(\"cloudflared/%s\", version)\n}\n\n// FetchTokenWithRedirect will either load a stored token or generate a new one\n// it appends the full url as the redirect URL to the access cli request if opening the browser\nfunc FetchTokenWithRedirect(appURL *url.URL, appInfo *AppInfo, autoClose bool, isFedramp bool, log *zerolog.Logger) (string, error) {\n\treturn getToken(appURL, appInfo, false, autoClose, isFedramp, log)\n}\n\n// FetchToken will either load a stored token or generate a new one\n// it appends the host of the appURL as the redirect URL to the access cli request if opening the browser\nfunc FetchToken(appURL *url.URL, appInfo *AppInfo, autoClose bool, isFedramp bool, log *zerolog.Logger) (string, error) {\n\treturn getToken(appURL, appInfo, true, autoClose, isFedramp, log)\n}\n\n// getToken will either load a stored token or generate a new one\nfunc getToken(appURL *url.URL, appInfo *AppInfo, useHostOnly bool, autoClose bool, isFedramp bool, log *zerolog.Logger) (string, error) {\n\tif token, err := GetAppTokenIfExists(appInfo); token != \"\" && err == nil {\n\t\treturn token, nil\n\t}\n\n\tappTokenPath, err := GenerateAppTokenFilePathFromURL(appInfo.AppDomain, appInfo.AppAUD, keyName)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to generate app token file path\")\n\t}\n\n\tfileLockAppToken := newLock(appTokenPath)\n\tif err = fileLockAppToken.Acquire(); err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to acquire app token lock\")\n\t}\n\tdefer func() {\n\t\t_ = fileLockAppToken.Release()\n\t}()\n\n\t// check to see if another process has gotten a token while we waited for the lock\n\tif token, err := GetAppTokenIfExists(appInfo); token != \"\" && err == nil {\n\t\treturn token, nil\n\t}\n\n\t// If an app token couldn't be found on disk, check for an org token and attempt to exchange it for an app token.\n\tvar orgTokenPath string\n\torgToken, err := GetOrgTokenIfExists(appInfo.AuthDomain)\n\tif err != nil {\n\t\torgTokenPath, err = generateOrgTokenFilePathFromURL(appInfo.AuthDomain)\n\t\tif err != nil {\n\t\t\treturn \"\", errors.Wrap(err, \"failed to generate org token file path\")\n\t\t}\n\n\t\tfileLockOrgToken := newLock(orgTokenPath)\n\t\tif err = fileLockOrgToken.Acquire(); err != nil {\n\t\t\treturn \"\", errors.Wrap(err, \"failed to acquire org token lock\")\n\t\t}\n\t\tdefer func() {\n\t\t\t_ = fileLockOrgToken.Release()\n\t\t}()\n\t\t// check if an org token has been created since the lock was acquired\n\t\torgToken, err = GetOrgTokenIfExists(appInfo.AuthDomain)\n\t}\n\tif err == nil {\n\t\tif appToken, err := exchangeOrgToken(appURL, orgToken); err != nil {\n\t\t\tlog.Debug().Msgf(\"failed to exchange org token for app token: %s\", err)\n\t\t} else {\n\t\t\t// generate app path\n\t\t\tif err := os.WriteFile(appTokenPath, []byte(appToken), 0600); err != nil {\n\t\t\t\treturn \"\", errors.Wrap(err, \"failed to write app token to disk\")\n\t\t\t}\n\t\t\treturn appToken, nil\n\t\t}\n\t}\n\treturn getTokensFromEdge(appURL, appInfo.AppAUD, appTokenPath, orgTokenPath, useHostOnly, autoClose, isFedramp, log)\n}\n\n// getTokensFromEdge will attempt to use the transfer service to retrieve an app and org token, save them to disk,\n// and return the app token.\nfunc getTokensFromEdge(appURL *url.URL, appAUD, appTokenPath, orgTokenPath string, useHostOnly bool, autoClose bool, isFedramp bool, log *zerolog.Logger) (string, error) {\n\t// If no org token exists or if it couldn't be exchanged for an app token, then run the transfer service flow.\n\n\t// this weird parameter is the resource name (token) and the key/value\n\t// we want to send to the transfer service. the key is token and the value\n\t// is blank (basically just the id generated in the transfer service)\n\tresourceData, err := RunTransfer(appURL, appAUD, keyName, keyName, \"\", true, useHostOnly, autoClose, isFedramp, log)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to run transfer service\")\n\t}\n\tvar resp transferServiceResponse\n\tif err = json.Unmarshal(resourceData, &resp); err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to marshal transfer service response\")\n\t}\n\n\t// If we were able to get the auth domain and generate an org token path, lets write it to disk.\n\tif orgTokenPath != \"\" {\n\t\tif err := os.WriteFile(orgTokenPath, []byte(resp.OrgToken), 0600); err != nil {\n\t\t\treturn \"\", errors.Wrap(err, \"failed to write org token to disk\")\n\t\t}\n\t}\n\n\tif err := os.WriteFile(appTokenPath, []byte(resp.AppToken), 0600); err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to write app token to disk\")\n\t}\n\n\treturn resp.AppToken, nil\n}\n\n// GetAppInfo makes a request to the appURL and stops at the first redirect. The 302 location header will contain the\n// auth domain\nfunc GetAppInfo(reqURL *url.URL) (*AppInfo, error) {\n\tclient := &http.Client{\n\t\t// do not follow redirects\n\t\tCheckRedirect: func(req *http.Request, via []*http.Request) error {\n\t\t\t// stop after hitting login endpoint since it will contain app path\n\t\t\tif strings.Contains(via[len(via)-1].URL.Path, AccessLoginWorkerPath) {\n\t\t\t\treturn http.ErrUseLastResponse\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t\tTimeout: time.Second * 7,\n\t}\n\n\tappInfoReq, err := http.NewRequest(\"HEAD\", reqURL.String(), nil)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to create app info request\")\n\t}\n\tappInfoReq.Header.Add(\"User-Agent\", userAgent)\n\tresp, err := client.Do(appInfoReq)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to get app info\")\n\t}\n\tresp.Body.Close()\n\n\tvar aud string\n\tlocation := resp.Request.URL\n\tif strings.Contains(location.Path, AccessLoginWorkerPath) {\n\t\taud = resp.Request.URL.Query().Get(\"kid\")\n\t\tif aud == \"\" {\n\t\t\treturn nil, errors.New(\"Empty app aud\")\n\t\t}\n\t} else if audHeader := resp.Header.Get(appAUDHeader); audHeader != \"\" {\n\t\t// 403/401 from the edge will have aud in a header\n\t\taud = audHeader\n\t} else {\n\t\treturn nil, fmt.Errorf(\"failed to find Access application at %s\", reqURL.String())\n\t}\n\n\tdomain := resp.Header.Get(appDomainHeader)\n\tif domain == \"\" {\n\t\treturn nil, errors.New(\"Empty app domain\")\n\t}\n\n\treturn &AppInfo{location.Hostname(), aud, domain}, nil\n}\n\nfunc handleRedirects(req *http.Request, via []*http.Request, orgToken string) error {\n\t// attach org token to login request\n\tif strings.Contains(req.URL.Path, AccessLoginWorkerPath) {\n\t\treq.AddCookie(&http.Cookie{Name: tokenCookie, Value: orgToken})\n\t}\n\n\t// attach app session cookie to authorized request\n\tif strings.Contains(req.URL.Path, AccessAuthorizedWorkerPath) {\n\t\t// We need to check and see if the CF_APP_SESSION cookie was set\n\t\tfor _, prevReq := range via {\n\t\t\tif prevReq != nil && prevReq.Response != nil {\n\t\t\t\tfor _, c := range prevReq.Response.Cookies() {\n\t\t\t\t\tif c.Name == appSessionCookie {\n\t\t\t\t\t\treq.AddCookie(&http.Cookie{Name: appSessionCookie, Value: c.Value})\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// stop after hitting authorized endpoint since it will contain the app token\n\tif len(via) > 0 && strings.Contains(via[len(via)-1].URL.Path, AccessAuthorizedWorkerPath) {\n\t\treturn http.ErrUseLastResponse\n\t}\n\treturn nil\n}\n\n// exchangeOrgToken attaches an org token to a request to the appURL and returns an app token. This uses the Access SSO\n// flow to automatically generate and return an app token without the login page.\nfunc exchangeOrgToken(appURL *url.URL, orgToken string) (string, error) {\n\tclient := &http.Client{\n\t\tCheckRedirect: func(req *http.Request, via []*http.Request) error {\n\t\t\treturn handleRedirects(req, via, orgToken)\n\t\t},\n\t\tTimeout: time.Second * 7,\n\t}\n\n\tappTokenRequest, err := http.NewRequest(\"HEAD\", appURL.String(), nil)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to create app token request\")\n\t}\n\tappTokenRequest.Header.Add(\"User-Agent\", userAgent)\n\tresp, err := client.Do(appTokenRequest)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"failed to get app token\")\n\t}\n\tresp.Body.Close()\n\tvar appToken string\n\tfor _, c := range resp.Cookies() {\n\t\t//if Org token revoked on exchange, getTokensFromEdge instead\n\t\tvalidAppToken := c.Name == tokenCookie && time.Now().Before(c.Expires)\n\t\tif validAppToken {\n\t\t\tappToken = c.Value\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif len(appToken) > 0 {\n\t\treturn appToken, nil\n\t}\n\treturn \"\", fmt.Errorf(\"response from %s did not contain app token\", resp.Request.URL.String())\n}\n\nfunc GetOrgTokenIfExists(authDomain string) (string, error) {\n\tpath, err := generateOrgTokenFilePathFromURL(authDomain)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\ttoken, err := getTokenIfExists(path)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tvar payload jwtPayload\n\terr = json.Unmarshal(token.UnsafePayloadWithoutVerification(), &payload)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif payload.isExpired() {\n\t\terr := os.Remove(path)\n\t\treturn \"\", err\n\t}\n\treturn token.CompactSerialize()\n}\n\nfunc GetAppTokenIfExists(appInfo *AppInfo) (string, error) {\n\tpath, err := GenerateAppTokenFilePathFromURL(appInfo.AppDomain, appInfo.AppAUD, keyName)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\ttoken, err := getTokenIfExists(path)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tvar payload jwtPayload\n\terr = json.Unmarshal(token.UnsafePayloadWithoutVerification(), &payload)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif payload.isExpired() {\n\t\terr := os.Remove(path)\n\t\treturn \"\", err\n\t}\n\treturn token.CompactSerialize()\n}\n\n// GetTokenIfExists will return the token from local storage if it exists and not expired\nfunc getTokenIfExists(path string) (*jose.JSONWebSignature, error) {\n\tcontent, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttoken, err := jose.ParseSigned(string(content), signatureAlgs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn token, nil\n}\n\n// RemoveTokenIfExists removes the a token from local storage if it exists\nfunc RemoveTokenIfExists(appInfo *AppInfo) error {\n\tpath, err := GenerateAppTokenFilePathFromURL(appInfo.AppDomain, appInfo.AppAUD, keyName)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err := os.Remove(path); err != nil && !os.IsNotExist(err) {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "token/token_test.go",
    "content": "package token\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"testing\"\n)\n\nfunc TestHandleRedirects_AttachOrgToken(t *testing.T) {\n\treq, _ := http.NewRequest(\"GET\", \"http://example.com/cdn-cgi/access/login\", nil)\n\tvia := []*http.Request{}\n\torgToken := \"orgTokenValue\"\n\n\t_ = handleRedirects(req, via, orgToken)\n\n\t// Check if the orgToken cookie is attached\n\tcookies := req.Cookies()\n\tfound := false\n\tfor _, cookie := range cookies {\n\t\tif cookie.Name == tokenCookie && cookie.Value == orgToken {\n\t\t\tfound = true\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif !found {\n\t\tt.Errorf(\"OrgToken cookie not attached to the request.\")\n\t}\n}\n\nfunc TestHandleRedirects_AttachAppSessionCookie(t *testing.T) {\n\treq, _ := http.NewRequest(\"GET\", \"http://example.com/cdn-cgi/access/authorized\", nil)\n\tvia := []*http.Request{\n\t\t{\n\t\t\tURL: &url.URL{Path: \"/cdn-cgi/access/login\"},\n\t\t\tResponse: &http.Response{\n\t\t\t\tHeader: http.Header{\"Set-Cookie\": {\"CF_AppSession=appSessionValue\"}},\n\t\t\t},\n\t\t},\n\t}\n\torgToken := \"orgTokenValue\"\n\n\terr := handleRedirects(req, via, orgToken)\n\n\t// Check if the appSessionCookie is attached to the request\n\tcookies := req.Cookies()\n\tfound := false\n\tfor _, cookie := range cookies {\n\t\tif cookie.Name == appSessionCookie && cookie.Value == \"appSessionValue\" {\n\t\t\tfound = true\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif !found {\n\t\tt.Errorf(\"AppSessionCookie not attached to the request.\")\n\t}\n\n\tif err != nil {\n\t\tt.Errorf(\"Expected no error, got %v\", err)\n\t}\n}\n\nfunc TestHandleRedirects_StopAtAuthorizedEndpoint(t *testing.T) {\n\treq, _ := http.NewRequest(\"GET\", \"http://example.com/cdn-cgi/access/authorized\", nil)\n\tvia := []*http.Request{\n\t\t{\n\t\t\tURL: &url.URL{Path: \"other\"},\n\t\t},\n\t\t{\n\t\t\tURL: &url.URL{Path: AccessAuthorizedWorkerPath},\n\t\t},\n\t}\n\torgToken := \"orgTokenValue\"\n\n\terr := handleRedirects(req, via, orgToken)\n\n\t// Check if ErrUseLastResponse is returned\n\tif err != http.ErrUseLastResponse {\n\t\tt.Errorf(\"Expected ErrUseLastResponse, got %v\", err)\n\t}\n}\n\nfunc TestJwtPayloadUnmarshal_AudAsString(t *testing.T) {\n\tjwt := `{\"aud\":\"7afbdaf987054f889b3bdd0d29ebfcd2\"}`\n\tvar payload jwtPayload\n\tif err := json.Unmarshal([]byte(jwt), &payload); err != nil {\n\t\tt.Errorf(\"Expected no error, got %v\", err)\n\t}\n\tif len(payload.Aud) != 1 || payload.Aud[0] != \"7afbdaf987054f889b3bdd0d29ebfcd2\" {\n\t\tt.Errorf(\"Expected aud to be 7afbdaf987054f889b3bdd0d29ebfcd2, got %v\", payload.Aud)\n\t}\n}\n\nfunc TestJwtPayloadUnmarshal_AudAsSlice(t *testing.T) {\n\tjwt := `{\"aud\":[\"7afbdaf987054f889b3bdd0d29ebfcd2\", \"f835c0016f894768976c01e076844efe\"]}`\n\tvar payload jwtPayload\n\tif err := json.Unmarshal([]byte(jwt), &payload); err != nil {\n\t\tt.Errorf(\"Expected no error, got %v\", err)\n\t}\n\tif len(payload.Aud) != 2 || payload.Aud[0] != \"7afbdaf987054f889b3bdd0d29ebfcd2\" || payload.Aud[1] != \"f835c0016f894768976c01e076844efe\" {\n\t\tt.Errorf(\"Expected aud to be [7afbdaf987054f889b3bdd0d29ebfcd2, f835c0016f894768976c01e076844efe], got %v\", payload.Aud)\n\t}\n}\n\nfunc TestJwtPayloadUnmarshal_FailsWhenAudIsInt(t *testing.T) {\n\tjwt := `{\"aud\":123}`\n\tvar payload jwtPayload\n\terr := json.Unmarshal([]byte(jwt), &payload)\n\twantErr := \"aud field is not a string or an array of strings\"\n\tif err.Error() != wantErr {\n\t\tt.Errorf(\"Expected %v, got %v\", wantErr, err)\n\t}\n}\n\nfunc TestJwtPayloadUnmarshal_FailsWhenAudIsArrayOfInts(t *testing.T) {\n\tjwt := `{\"aud\": [999, 123] }`\n\tvar payload jwtPayload\n\terr := json.Unmarshal([]byte(jwt), &payload)\n\twantErr := \"aud array contains non-string elements\"\n\tif err.Error() != wantErr {\n\t\tt.Errorf(\"Expected %v, got %v\", wantErr, err)\n\t}\n}\n\nfunc TestJwtPayloadUnmarshal_FailsWhenAudIsOmitted(t *testing.T) {\n\tjwt := `{}`\n\tvar payload jwtPayload\n\terr := json.Unmarshal([]byte(jwt), &payload)\n\twantErr := \"aud field is not a string or an array of strings\"\n\tif err.Error() != wantErr {\n\t\tt.Errorf(\"Expected %v, got %v\", wantErr, err)\n\t}\n}\n"
  },
  {
    "path": "token/transfer.go",
    "content": "package token\n\nimport (\n\t\"bytes\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/rs/zerolog\"\n)\n\nconst (\n\tbaseStoreURL  = \"https://login.cloudflareaccess.org/\"\n\tfedStoreURL   = \"https://login.fed.cloudflareaccess.org/\"\n\tclientTimeout = time.Second * 60\n)\n\n// RunTransfer does the transfer \"dance\" with the end result downloading the supported resource.\n// The expanded description is run is encapsulation of shared business logic needed\n// to request a resource (token/cert/etc) from the transfer service (loginhelper).\n// The \"dance\" we refer to is building a HTTP request, opening that in a browser waiting for\n// the user to complete an action, while it long polls in the background waiting for an\n// action to be completed to download the resource.\nfunc RunTransfer(transferURL *url.URL, appAUD, resourceName, key, value string, shouldEncrypt bool, useHostOnly bool, autoClose bool, fedramp bool, log *zerolog.Logger) ([]byte, error) {\n\tencrypterClient, err := NewEncrypter(\"cloudflared_priv.pem\", \"cloudflared_pub.pem\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\trequestURL, err := buildRequestURL(transferURL, appAUD, key, value+encrypterClient.PublicKey(), shouldEncrypt, useHostOnly, autoClose)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// See AUTH-1423 for why we use stderr (the way git wraps ssh)\n\terr = OpenBrowser(requestURL)\n\tif err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"Please open the following URL and log in with your Cloudflare account:\\n\\n%s\\n\\nLeave cloudflared running to download the %s automatically.\\n\", requestURL, resourceName)\n\t} else {\n\t\tfmt.Fprintf(os.Stderr, \"A browser window should have opened at the following URL:\\n\\n%s\\n\\nIf the browser failed to open, please visit the URL above directly in your browser.\\n\", requestURL)\n\t}\n\n\tvar resourceData []byte\n\n\tstoreURL := baseStoreURL\n\n\tif fedramp {\n\t\tstoreURL = fedStoreURL\n\t}\n\n\tif shouldEncrypt {\n\t\tbuf, key, err := transferRequest(storeURL+\"transfer/\"+encrypterClient.PublicKey(), log)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tdecodedBuf, err := base64.StdEncoding.DecodeString(string(buf))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdecrypted, err := encrypterClient.Decrypt(decodedBuf, key)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tresourceData = decrypted\n\t} else {\n\t\tbuf, _, err := transferRequest(storeURL+encrypterClient.PublicKey(), log)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tresourceData = buf\n\t}\n\n\treturn resourceData, nil\n}\n\n// BuildRequestURL creates a request suitable for a resource transfer.\n// it will return a constructed url based off the base url and query key/value provided.\n// cli will build a url for cli transfer request.\nfunc buildRequestURL(baseURL *url.URL, appAUD string, key, value string, cli, useHostOnly bool, autoClose bool) (string, error) {\n\tq := baseURL.Query()\n\tq.Set(key, value)\n\tq.Set(\"aud\", appAUD)\n\tbaseURL.RawQuery = q.Encode()\n\tif useHostOnly {\n\t\tbaseURL.Path = \"\"\n\t}\n\t// TODO: pass arg for tunnel login\n\tif !cli {\n\t\treturn baseURL.String(), nil\n\t}\n\tq.Set(\"redirect_url\", baseURL.String()) // we add the token as a query param on both the redirect_url and the main url\n\tq.Set(\"send_org_token\", \"true\")         // indicates that the cli endpoint should return both the org and app token\n\tq.Set(\"edge_token_transfer\", \"true\")    // use new LoginHelper service built on workers\n\tif autoClose {\n\t\tq.Set(\"close_interstitial\", \"true\") // Automatically close the success window.\n\t}\n\n\tbaseURL.RawQuery = q.Encode() // and this actual baseURL.\n\tbaseURL.Path = \"cdn-cgi/access/cli\"\n\treturn baseURL.String(), nil\n}\n\n// transferRequest downloads the requested resource from the request URL\nfunc transferRequest(requestURL string, log *zerolog.Logger) ([]byte, string, error) {\n\tclient := &http.Client{Timeout: clientTimeout}\n\tconst pollAttempts = 10\n\t// we do \"long polling\" on the endpoint to get the resource.\n\tfor i := 0; i < pollAttempts; i++ {\n\t\tbuf, key, err := poll(client, requestURL, log)\n\t\tif err != nil {\n\t\t\treturn nil, \"\", err\n\t\t} else if len(buf) > 0 {\n\t\t\treturn buf, key, nil\n\t\t}\n\t}\n\treturn nil, \"\", errors.New(\"Failed to fetch resource\")\n}\n\n// poll the endpoint for the request resource, waiting for the user interaction\nfunc poll(client *http.Client, requestURL string, log *zerolog.Logger) ([]byte, string, error) {\n\treq, err := http.NewRequest(http.MethodGet, requestURL, nil)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\treq.Header.Set(\"User-Agent\", userAgent)\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\tdefer resp.Body.Close()\n\n\t// ignore everything other than server errors as the resource\n\t// may not exist until the user does the interaction\n\tif resp.StatusCode >= 500 {\n\t\tbuf := new(bytes.Buffer)\n\t\tif _, err := io.Copy(buf, resp.Body); err != nil {\n\t\t\treturn nil, \"\", err\n\t\t}\n\n\t\treturn nil, \"\", fmt.Errorf(\"error on request %d: %s\", resp.StatusCode, buf.String())\n\t}\n\tif resp.StatusCode != 200 {\n\t\tlog.Info().Msg(\"Waiting for login...\")\n\t\treturn nil, \"\", nil\n\t}\n\n\tbuf := new(bytes.Buffer)\n\tif _, err := io.Copy(buf, resp.Body); err != nil {\n\t\treturn nil, \"\", err\n\t}\n\treturn buf.Bytes(), resp.Header.Get(\"service-public-key\"), nil\n}\n"
  },
  {
    "path": "tracing/client.go",
    "content": "package tracing\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"sync\"\n\n\tcoltracepb \"go.opentelemetry.io/proto/otlp/collector/trace/v1\"\n\ttracepb \"go.opentelemetry.io/proto/otlp/trace/v1\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\nconst (\n\tMaxTraceAmount = 20\n)\n\nvar (\n\terrNoTraces   = errors.New(\"no traces recorded to be exported\")\n\terrNoopTracer = errors.New(\"noop tracer has no traces\")\n)\n\ntype InMemoryClient interface {\n\t// Spans returns a copy of the list of in-memory stored spans as a base64\n\t// encoded otlp protobuf string.\n\tSpans() (string, error)\n\t// ExportProtoSpans returns a copy of the list of in-memory stored spans as otlp\n\t// protobuf byte array and clears the in-memory spans.\n\tExportProtoSpans() ([]byte, error)\n}\n\n// InMemoryOtlpClient is a client implementation for otlptrace.Client\ntype InMemoryOtlpClient struct {\n\tmu    sync.Mutex\n\tspans []*tracepb.ResourceSpans\n}\n\nfunc (mc *InMemoryOtlpClient) Start(_ context.Context) error {\n\treturn nil\n}\n\nfunc (mc *InMemoryOtlpClient) Stop(_ context.Context) error {\n\treturn nil\n}\n\n// UploadTraces adds the provided list of spans to the in-memory list.\nfunc (mc *InMemoryOtlpClient) UploadTraces(_ context.Context, protoSpans []*tracepb.ResourceSpans) error {\n\tmc.mu.Lock()\n\tdefer mc.mu.Unlock()\n\t// Catch to make sure too many traces aren't being added to response header.\n\t// Returning nil makes sure we don't fail to send the traces we already recorded.\n\tif len(mc.spans)+len(protoSpans) > MaxTraceAmount {\n\t\treturn nil\n\t}\n\tmc.spans = append(mc.spans, protoSpans...)\n\treturn nil\n}\n\n// Spans returns the list of in-memory stored spans as a base64 encoded otlp protobuf string.\nfunc (mc *InMemoryOtlpClient) Spans() (string, error) {\n\tdata, err := mc.ExportProtoSpans()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn base64.StdEncoding.EncodeToString(data), nil\n}\n\n// ProtoSpans returns the list of in-memory stored spans as the protobuf byte array.\nfunc (mc *InMemoryOtlpClient) ExportProtoSpans() ([]byte, error) {\n\tmc.mu.Lock()\n\tdefer mc.mu.Unlock()\n\tif len(mc.spans) <= 0 {\n\t\treturn nil, errNoTraces\n\t}\n\tpbRequest := &coltracepb.ExportTraceServiceRequest{\n\t\tResourceSpans: mc.spans,\n\t}\n\tserializedSpans, err := proto.Marshal(pbRequest)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tmc.spans = make([]*tracepb.ResourceSpans, 0)\n\treturn serializedSpans, nil\n}\n\n// NoopOtlpClient is a client implementation for otlptrace.Client that does nothing\ntype NoopOtlpClient struct{}\n\nfunc (mc *NoopOtlpClient) Start(_ context.Context) error {\n\treturn nil\n}\n\nfunc (mc *NoopOtlpClient) Stop(_ context.Context) error {\n\treturn nil\n}\n\nfunc (mc *NoopOtlpClient) UploadTraces(_ context.Context, _ []*tracepb.ResourceSpans) error {\n\treturn nil\n}\n\n// Spans always returns no traces error\nfunc (mc *NoopOtlpClient) Spans() (string, error) {\n\treturn \"\", errNoopTracer\n}\n\n// Spans always returns no traces error\nfunc (mc *NoopOtlpClient) ExportProtoSpans() ([]byte, error) {\n\treturn nil, errNoopTracer\n}\n\nfunc (mc *NoopOtlpClient) ClearSpans() {}\n"
  },
  {
    "path": "tracing/client_test.go",
    "content": "package tracing\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"go.opentelemetry.io/otel/exporters/otlp/otlptrace\"\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.7.0\"\n\t\"go.opentelemetry.io/otel/trace\"\n\tcommonpb \"go.opentelemetry.io/proto/otlp/common/v1\"\n\tresourcepb \"go.opentelemetry.io/proto/otlp/resource/v1\"\n\ttracepb \"go.opentelemetry.io/proto/otlp/trace/v1\"\n)\n\nconst (\n\tresourceSchemaUrl   = \"http://example.com/custom-resource-schema\"\n\tinstrumentSchemaUrl = semconv.SchemaURL\n)\n\nvar (\n\ttraceId      = []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}\n\tspanId       = []byte{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}\n\tparentSpanId = []byte{0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08}\n\tstartTime    = time.Date(2022, 4, 4, 0, 0, 0, 0, time.UTC)\n\tendTime      = startTime.Add(5 * time.Second)\n\n\ttraceState, _ = trace.ParseTraceState(\"key1=val1,key2=val2\")\n\tinstrScope    = &commonpb.InstrumentationScope{Name: \"go.opentelemetry.io/test/otel\", Version: \"v1.6.0\"}\n\totlpKeyValues = []*commonpb.KeyValue{\n\t\t{\n\t\t\tKey: \"string_key\",\n\t\t\tValue: &commonpb.AnyValue{\n\t\t\t\tValue: &commonpb.AnyValue_StringValue{\n\t\t\t\t\tStringValue: \"string value\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tKey: \"bool_key\",\n\t\t\tValue: &commonpb.AnyValue{\n\t\t\t\tValue: &commonpb.AnyValue_BoolValue{\n\t\t\t\t\tBoolValue: true,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\totlpResource = &resourcepb.Resource{\n\t\tAttributes: []*commonpb.KeyValue{\n\t\t\t{\n\t\t\t\tKey: \"service.name\",\n\t\t\t\tValue: &commonpb.AnyValue{\n\t\t\t\t\tValue: &commonpb.AnyValue_StringValue{\n\t\t\t\t\t\tStringValue: \"service-name\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n)\n\nvar _ otlptrace.Client = (*InMemoryOtlpClient)(nil)\nvar _ InMemoryClient = (*InMemoryOtlpClient)(nil)\nvar _ otlptrace.Client = (*NoopOtlpClient)(nil)\nvar _ InMemoryClient = (*NoopOtlpClient)(nil)\n\nfunc TestUploadTraces(t *testing.T) {\n\tclient := &InMemoryOtlpClient{}\n\tspans := createResourceSpans([]*tracepb.Span{createOtlpSpan(traceId)})\n\tspans2 := createResourceSpans([]*tracepb.Span{createOtlpSpan(traceId)})\n\terr := client.UploadTraces(context.Background(), spans)\n\tassert.NoError(t, err)\n\terr = client.UploadTraces(context.Background(), spans2)\n\tassert.NoError(t, err)\n\tassert.Len(t, client.spans, 2)\n}\n\nfunc TestSpans(t *testing.T) {\n\tclient := &InMemoryOtlpClient{}\n\tspans := createResourceSpans([]*tracepb.Span{createOtlpSpan(traceId)})\n\terr := client.UploadTraces(context.Background(), spans)\n\tassert.NoError(t, err)\n\tassert.Len(t, client.spans, 1)\n\tenc, err := client.Spans()\n\tassert.NoError(t, err)\n\texpected := \"CsECCiAKHgoMc2VydmljZS5uYW1lEg4KDHNlcnZpY2UtbmFtZRLxAQonCh1nby5vcGVudGVsZW1ldHJ5LmlvL3Rlc3Qvb3RlbBIGdjEuNi4wEp0BChAAAQIDBAUGBwgJCgsMDQ4PEgj//v38+/r5+BoTa2V5MT12YWwxLGtleTI9dmFsMiIIDw4NDAsKCQgqCnRyYWNlX25hbWUwATkAANJvaYjiFkEA8teZaojiFkocCgpzdHJpbmdfa2V5Eg4KDHN0cmluZyB2YWx1ZUoOCghib29sX2tleRICEAF6EhIOc3RhdHVzIG1lc3NhZ2UYARomaHR0cHM6Ly9vcGVudGVsZW1ldHJ5LmlvL3NjaGVtYXMvMS43LjAaKWh0dHA6Ly9leGFtcGxlLmNvbS9jdXN0b20tcmVzb3VyY2Utc2NoZW1h\"\n\tassert.Equal(t, expected, enc)\n}\n\nfunc TestSpansEmpty(t *testing.T) {\n\tclient := &InMemoryOtlpClient{}\n\terr := client.UploadTraces(context.Background(), []*tracepb.ResourceSpans{})\n\tassert.NoError(t, err)\n\tassert.Len(t, client.spans, 0)\n\t_, err = client.Spans()\n\tassert.ErrorIs(t, err, errNoTraces)\n}\n\nfunc TestSpansNil(t *testing.T) {\n\tclient := &InMemoryOtlpClient{}\n\terr := client.UploadTraces(context.Background(), nil)\n\tassert.NoError(t, err)\n\tassert.Len(t, client.spans, 0)\n\t_, err = client.Spans()\n\tassert.ErrorIs(t, err, errNoTraces)\n}\n\nfunc TestSpansTooManySpans(t *testing.T) {\n\tclient := &InMemoryOtlpClient{}\n\tfor i := 0; i < MaxTraceAmount+1; i++ {\n\t\tspans := createResourceSpans([]*tracepb.Span{createOtlpSpan(traceId)})\n\t\terr := client.UploadTraces(context.Background(), spans)\n\t\tassert.NoError(t, err)\n\t}\n\tassert.Len(t, client.spans, MaxTraceAmount)\n\t_, err := client.Spans()\n\tassert.NoError(t, err)\n}\n\nfunc createResourceSpans(spans []*tracepb.Span) []*tracepb.ResourceSpans {\n\treturn []*tracepb.ResourceSpans{createResourceSpan(spans)}\n}\n\nfunc createResourceSpan(spans []*tracepb.Span) *tracepb.ResourceSpans {\n\treturn &tracepb.ResourceSpans{\n\t\tResource: otlpResource,\n\t\tScopeSpans: []*tracepb.ScopeSpans{\n\t\t\t{\n\t\t\t\tScope:     instrScope,\n\t\t\t\tSpans:     spans,\n\t\t\t\tSchemaUrl: instrumentSchemaUrl,\n\t\t\t},\n\t\t},\n\t\tSchemaUrl: resourceSchemaUrl,\n\t}\n}\n\nfunc createOtlpSpan(tid []byte) *tracepb.Span {\n\treturn &tracepb.Span{\n\t\tTraceId:                tid,\n\t\tSpanId:                 spanId,\n\t\tTraceState:             traceState.String(),\n\t\tParentSpanId:           parentSpanId,\n\t\tName:                   \"trace_name\",\n\t\tKind:                   tracepb.Span_SPAN_KIND_INTERNAL,\n\t\tStartTimeUnixNano:      uint64(startTime.UnixNano()),\n\t\tEndTimeUnixNano:        uint64(endTime.UnixNano()),\n\t\tAttributes:             otlpKeyValues,\n\t\tDroppedAttributesCount: 0,\n\t\tEvents:                 nil,\n\t\tDroppedEventsCount:     0,\n\t\tLinks:                  nil,\n\t\tDroppedLinksCount:      0,\n\t\tStatus: &tracepb.Status{\n\t\t\tMessage: \"status message\",\n\t\t\tCode:    tracepb.Status_STATUS_CODE_OK,\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "tracing/identity.go",
    "content": "package tracing\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nconst (\n\t// 16 bytes for tracing ID, 8 bytes for span ID and 1 byte for flags\n\tIdentityLength = 16 + 8 + 1\n)\n\ntype Identity struct {\n\t// Based on https://www.jaegertracing.io/docs/1.36/client-libraries/#value\n\t// parent span ID is always 0 for our case\n\ttraceIDUpper uint64\n\ttraceIDLower uint64\n\tspanID       uint64\n\tflags        uint8\n}\n\n// TODO: TUN-6604 Remove this. To reconstruct into Jaeger propagation format, convert tracingContext to tracing.Identity\nfunc (tc *Identity) String() string {\n\treturn fmt.Sprintf(\"%016x%016x:%x:0:%x\", tc.traceIDUpper, tc.traceIDLower, tc.spanID, tc.flags)\n}\n\nfunc (tc *Identity) MarshalBinary() ([]byte, error) {\n\tbuf := bytes.NewBuffer(make([]byte, 0, IdentityLength))\n\tfor _, field := range []interface{}{\n\t\ttc.traceIDUpper,\n\t\ttc.traceIDLower,\n\t\ttc.spanID,\n\t\ttc.flags,\n\t} {\n\t\tif err := binary.Write(buf, binary.BigEndian, field); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn buf.Bytes(), nil\n}\n\nfunc (tc *Identity) UnmarshalBinary(data []byte) error {\n\tif len(data) < IdentityLength {\n\t\treturn fmt.Errorf(\"expect tracingContext to have at least %d bytes, got %d\", IdentityLength, len(data))\n\t}\n\n\tbuf := bytes.NewBuffer(data)\n\tfor _, field := range []interface{}{\n\t\t&tc.traceIDUpper,\n\t\t&tc.traceIDLower,\n\t\t&tc.spanID,\n\t\t&tc.flags,\n\t} {\n\t\tif err := binary.Read(buf, binary.BigEndian, field); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc NewIdentity(trace string) (*Identity, error) {\n\tparts := strings.Split(trace, separator)\n\tif len(parts) != 4 {\n\t\treturn nil, fmt.Errorf(\"trace '%s' doesn't have exactly 4 parts separated by %s\", trace, separator)\n\t}\n\tconst base = 16\n\ttracingID, err := padTracingID(parts[0])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttraceIDUpper, err := strconv.ParseUint(tracingID[:16], base, 64)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse first 16 bytes of tracing ID as uint64, err: %w\", err)\n\t}\n\ttraceIDLower, err := strconv.ParseUint(tracingID[16:], base, 64)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse last 16 bytes of tracing ID as uint64, err: %w\", err)\n\t}\n\tspanID, err := strconv.ParseUint(parts[1], base, 64)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse span ID as uint64, err: %w\", err)\n\t}\n\tflags, err := strconv.ParseUint(parts[3], base, 8)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse flag as uint8, err: %w\", err)\n\t}\n\treturn &Identity{\n\t\ttraceIDUpper: traceIDUpper,\n\t\ttraceIDLower: traceIDLower,\n\t\tspanID:       spanID,\n\t\tflags:        uint8(flags),\n\t}, nil\n}\n\nfunc padTracingID(tracingID string) (string, error) {\n\tif len(tracingID) == 0 {\n\t\treturn \"\", fmt.Errorf(\"missing tracing ID\")\n\t}\n\tif len(tracingID) == traceID128bitsWidth {\n\t\treturn tracingID, nil\n\t}\n\t// Correctly left pad the trace to a length of 32\n\tleft := traceID128bitsWidth - len(tracingID)\n\tpaddedTracingID := strings.Repeat(\"0\", left) + tracingID\n\treturn paddedTracingID, nil\n}\n"
  },
  {
    "path": "tracing/identity_test.go",
    "content": "package tracing\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestNewIdentity(t *testing.T) {\n\ttestCases := []struct {\n\t\ttestCase string\n\t\ttrace    string\n\t\texpected string\n\t}{\n\t\t{\n\t\t\ttestCase: \"full length trace\",\n\t\t\ttrace:    \"ec31ad8a01fde11fdcabe2efdce36873:52726f6cabc144f5:0:1\",\n\t\t\texpected: \"ec31ad8a01fde11fdcabe2efdce36873:52726f6cabc144f5:0:1\",\n\t\t},\n\t\t{\n\t\t\ttestCase: \"short trace ID\",\n\t\t\ttrace:    \"ad8a01fde11fdcabe2efdce36873:52726f6cabc144f5:0:1\",\n\t\t\texpected: \"0000ad8a01fde11fdcabe2efdce36873:52726f6cabc144f5:0:1\",\n\t\t},\n\t\t{\n\t\t\ttestCase: \"short trace ID with 0s in the middle\",\n\t\t\ttrace:    \"ad8a01fde11f000002efdce36873:52726f6cabc144f5:0:1\",\n\t\t\texpected: \"0000ad8a01fde11f000002efdce36873:52726f6cabc144f5:0:1\",\n\t\t},\n\t\t{\n\t\t\ttestCase: \"short trace ID with 0s in the beginning and middle\",\n\t\t\ttrace:    \"001ad8a01fde11fdcabe2efdce36873:52726f6cabc144f5:0:1\",\n\t\t\texpected: \"0001ad8a01fde11fdcabe2efdce36873:52726f6cabc144f5:0:1\",\n\t\t},\n\t\t{\n\t\t\ttestCase: \"no trace\",\n\t\t\ttrace:    \"\",\n\t\t},\n\t\t{\n\t\t\ttestCase: \"missing flags\",\n\t\t\ttrace:    \"ec31ad8a01fde11fdcabe2efdce36873:52726f6cabc144f5:0\",\n\t\t},\n\t\t{\n\t\t\ttestCase: \"missing separator\",\n\t\t\ttrace:    \"ec31ad8a01fde11fdcabe2efdce3687352726f6cabc144f501\",\n\t\t},\n\t}\n\n\tfor _, testCase := range testCases {\n\t\tidentity, err := NewIdentity(testCase.trace)\n\t\tif testCase.expected != \"\" {\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, testCase.expected, identity.String())\n\n\t\t\tserializedIdentity, err := identity.MarshalBinary()\n\t\t\trequire.NoError(t, err)\n\t\t\tdeserializedIdentity := new(Identity)\n\t\t\terr = deserializedIdentity.UnmarshalBinary(serializedIdentity)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, identity, deserializedIdentity)\n\n\t\t} else {\n\t\t\trequire.Error(t, err)\n\t\t\trequire.Nil(t, identity)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tracing/tracing.go",
    "content": "package tracing\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"net/http\"\n\t\"os\"\n\t\"runtime\"\n\t\"strings\"\n\n\t\"github.com/rs/zerolog\"\n\totelContrib \"go.opentelemetry.io/contrib/propagators/jaeger\"\n\t\"go.opentelemetry.io/otel\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n\t\"go.opentelemetry.io/otel/exporters/otlp/otlptrace\"\n\t\"go.opentelemetry.io/otel/propagation\"\n\t\"go.opentelemetry.io/otel/sdk/resource\"\n\ttracesdk \"go.opentelemetry.io/otel/sdk/trace\"\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.7.0\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\nconst (\n\tservice              = \"cloudflared\"\n\ttracerInstrumentName = \"origin\"\n\n\tTracerContextName         = \"cf-trace-id\"\n\tTracerContextNameOverride = \"uber-trace-id\"\n\n\tIntCloudflaredTracingHeader = \"cf-int-cloudflared-tracing\"\n\n\tMaxErrorDescriptionLen = 100\n\ttraceHttpStatusCodeKey = \"upstreamStatusCode\"\n\n\ttraceID128bitsWidth = 128 / 4\n\tseparator           = \":\"\n)\n\nvar (\n\tCanonicalCloudflaredTracingHeader = http.CanonicalHeaderKey(IntCloudflaredTracingHeader)\n\tHttp2TransportAttribute           = trace.WithAttributes(transportAttributeKey.String(\"http2\"))\n\tQuicTransportAttribute            = trace.WithAttributes(transportAttributeKey.String(\"quic\"))\n\tHostOSAttribute                   = semconv.HostTypeKey.String(runtime.GOOS)\n\tHostArchAttribute                 = semconv.HostArchKey.String(runtime.GOARCH)\n\n\totelVersionAttribute        attribute.KeyValue\n\thostnameAttribute           attribute.KeyValue\n\tcloudflaredVersionAttribute attribute.KeyValue\n\tserviceAttribute            = semconv.ServiceNameKey.String(service)\n\n\ttransportAttributeKey   = attribute.Key(\"transport\")\n\totelVersionAttributeKey = attribute.Key(\"jaeger.version\")\n\n\terrNoopTracerProvider = errors.New(\"noop tracer provider records no spans\")\n)\n\nfunc init() {\n\t// Register the jaeger propagator globally.\n\totel.SetTextMapPropagator(otelContrib.Jaeger{})\n\totelVersionAttribute = otelVersionAttributeKey.String(fmt.Sprintf(\"go-otel-%s\", otel.Version()))\n\tif hostname, err := os.Hostname(); err == nil {\n\t\thostnameAttribute = attribute.String(\"hostname\", hostname)\n\t}\n}\n\nfunc Init(version string) {\n\tcloudflaredVersionAttribute = semconv.ProcessRuntimeVersionKey.String(version)\n}\n\ntype TracedHTTPRequest struct {\n\t*http.Request\n\t*cfdTracer\n\tConnIndex uint8 // The connection index used to proxy the request\n}\n\n// NewTracedHTTPRequest creates a new tracer for the current HTTP request context.\nfunc NewTracedHTTPRequest(req *http.Request, connIndex uint8, log *zerolog.Logger) *TracedHTTPRequest {\n\tctx, exists := extractTrace(req)\n\tif !exists {\n\t\treturn &TracedHTTPRequest{req, &cfdTracer{trace.NewNoopTracerProvider(), &NoopOtlpClient{}, log}, connIndex}\n\t}\n\treturn &TracedHTTPRequest{req.WithContext(ctx), newCfdTracer(ctx, log), connIndex}\n}\n\nfunc (tr *TracedHTTPRequest) ToTracedContext() *TracedContext {\n\treturn &TracedContext{tr.Context(), tr.cfdTracer}\n}\n\ntype TracedContext struct {\n\tcontext.Context\n\t*cfdTracer\n}\n\n// NewTracedContext creates a new tracer for the current context.\nfunc NewTracedContext(ctx context.Context, traceContext string, log *zerolog.Logger) *TracedContext {\n\tctx, exists := extractTraceFromString(ctx, traceContext)\n\tif !exists {\n\t\treturn &TracedContext{ctx, &cfdTracer{trace.NewNoopTracerProvider(), &NoopOtlpClient{}, log}}\n\t}\n\treturn &TracedContext{ctx, newCfdTracer(ctx, log)}\n}\n\ntype cfdTracer struct {\n\ttrace.TracerProvider\n\texporter InMemoryClient\n\tlog      *zerolog.Logger\n}\n\n// NewCfdTracer creates a new tracer for the current request context.\nfunc newCfdTracer(ctx context.Context, log *zerolog.Logger) *cfdTracer {\n\tmc := new(InMemoryOtlpClient)\n\texp, err := otlptrace.New(ctx, mc)\n\tif err != nil {\n\t\treturn &cfdTracer{trace.NewNoopTracerProvider(), &NoopOtlpClient{}, log}\n\t}\n\ttp := tracesdk.NewTracerProvider(\n\t\t// We want to dump to in-memory exporter immediately\n\t\ttracesdk.WithSyncer(exp),\n\t\t// Record information about this application in a Resource.\n\t\ttracesdk.WithResource(resource.NewWithAttributes(\n\t\t\tsemconv.SchemaURL,\n\t\t\tserviceAttribute,\n\t\t\totelVersionAttribute,\n\t\t\thostnameAttribute,\n\t\t\tcloudflaredVersionAttribute,\n\t\t\tHostOSAttribute,\n\t\t\tHostArchAttribute,\n\t\t)),\n\t)\n\n\treturn &cfdTracer{tp, mc, log}\n}\n\nfunc (cft *cfdTracer) Tracer() trace.Tracer {\n\treturn cft.TracerProvider.Tracer(tracerInstrumentName)\n}\n\n// GetSpans returns the spans as base64 encoded string of protobuf otlp traces.\nfunc (cft *cfdTracer) GetSpans() (enc string) {\n\tenc, err := cft.exporter.Spans()\n\tswitch err {\n\tcase nil:\n\t\tbreak\n\tcase errNoTraces:\n\t\tcft.log.Trace().Err(err).Msgf(\"expected traces to be available\")\n\t\treturn\n\tcase errNoopTracer:\n\t\treturn // noop tracer has no traces\n\tdefault:\n\t\tcft.log.Debug().Err(err)\n\t\treturn\n\t}\n\treturn\n}\n\n// GetProtoSpans returns the spans as the otlp traces in protobuf byte array.\nfunc (cft *cfdTracer) GetProtoSpans() (proto []byte) {\n\tproto, err := cft.exporter.ExportProtoSpans()\n\tswitch err {\n\tcase nil:\n\t\tbreak\n\tcase errNoTraces:\n\t\tcft.log.Trace().Err(err).Msgf(\"expected traces to be available\")\n\t\treturn\n\tcase errNoopTracer:\n\t\treturn // noop tracer has no traces\n\tdefault:\n\t\tcft.log.Debug().Err(err)\n\t\treturn\n\t}\n\treturn\n}\n\n// AddSpans assigns spans as base64 encoded protobuf otlp traces to provided\n// HTTP headers.\nfunc (cft *cfdTracer) AddSpans(headers http.Header) {\n\tif headers == nil {\n\t\treturn\n\t}\n\n\tenc := cft.GetSpans()\n\t// No need to add header if no traces\n\tif enc == \"\" {\n\t\treturn\n\t}\n\n\theaders[CanonicalCloudflaredTracingHeader] = []string{enc}\n}\n\n// End will set the OK status for the span and then end it.\nfunc End(span trace.Span) {\n\tendSpan(span, -1, codes.Ok, nil)\n}\n\n// EndWithErrorStatus will set a status for the span and then end it.\nfunc EndWithErrorStatus(span trace.Span, err error) {\n\tendSpan(span, -1, codes.Error, err)\n}\n\n// EndWithStatusCode will set a status for the span and then end it.\nfunc EndWithStatusCode(span trace.Span, statusCode int) {\n\tendSpan(span, statusCode, codes.Ok, nil)\n}\n\n// EndWithErrorStatus will set a status for the span and then end it.\nfunc endSpan(span trace.Span, upstreamStatusCode int, spanStatusCode codes.Code, err error) {\n\tif span == nil {\n\t\treturn\n\t}\n\n\tif upstreamStatusCode > 0 {\n\t\tspan.SetAttributes(attribute.Int(traceHttpStatusCodeKey, upstreamStatusCode))\n\t}\n\n\t// add error to status buf cap description\n\terrDescription := \"\"\n\tif err != nil {\n\t\terrDescription = err.Error()\n\t\tl := int(math.Min(float64(len(errDescription)), MaxErrorDescriptionLen))\n\t\terrDescription = errDescription[:l]\n\t}\n\n\tspan.SetStatus(spanStatusCode, errDescription)\n\tspan.End()\n}\n\n// extractTraceFromString will extract the trace information from the provided\n// propagated trace string context.\nfunc extractTraceFromString(ctx context.Context, trace string) (context.Context, bool) {\n\tif trace == \"\" {\n\t\treturn ctx, false\n\t}\n\t// Jaeger specific separator\n\tparts := strings.Split(trace, separator)\n\tif len(parts) != 4 {\n\t\treturn ctx, false\n\t}\n\tif parts[0] == \"\" {\n\t\treturn ctx, false\n\t}\n\t// Correctly left pad the trace to a length of 32\n\tif len(parts[0]) < traceID128bitsWidth {\n\t\tleft := traceID128bitsWidth - len(parts[0])\n\t\tparts[0] = strings.Repeat(\"0\", left) + parts[0]\n\t\ttrace = strings.Join(parts, separator)\n\t}\n\t// Override the 'cf-trace-id' as 'uber-trace-id' so the jaeger propagator can extract it.\n\ttraceHeader := map[string]string{TracerContextNameOverride: trace}\n\tremoteCtx := otel.GetTextMapPropagator().Extract(ctx, propagation.MapCarrier(traceHeader))\n\treturn remoteCtx, true\n}\n\n// extractTrace attempts to check for a cf-trace-id from a request and return the\n// trace context with the provided http.Request.\nfunc extractTrace(req *http.Request) (context.Context, bool) {\n\t// Only add tracing for requests with appropriately tagged headers\n\tremoteTraces := req.Header.Values(TracerContextName)\n\tif len(remoteTraces) <= 0 {\n\t\t// Strip the cf-trace-id header\n\t\treq.Header.Del(TracerContextName)\n\t\treturn nil, false\n\t}\n\n\ttraceHeader := map[string]string{}\n\tfor _, t := range remoteTraces {\n\t\t// Override the 'cf-trace-id' as 'uber-trace-id' so the jaeger propagator can extract it.\n\t\t// Last entry wins if multiple provided\n\t\ttraceHeader[TracerContextNameOverride] = t\n\t}\n\n\t// Strip the cf-trace-id header\n\treq.Header.Del(TracerContextName)\n\n\tif traceHeader[TracerContextNameOverride] == \"\" {\n\t\treturn nil, false\n\t}\n\n\tremoteCtx := otel.GetTextMapPropagator().Extract(req.Context(), propagation.MapCarrier(traceHeader))\n\treturn remoteCtx, true\n}\n\nfunc NewNoopSpan() trace.Span {\n\treturn trace.SpanFromContext(nil)\n}\n"
  },
  {
    "path": "tracing/tracing_test.go",
    "content": "package tracing\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"github.com/rs/zerolog\"\n\t\"github.com/stretchr/testify/assert\"\n\ttracesdk \"go.opentelemetry.io/otel/sdk/trace\"\n\t\"go.opentelemetry.io/otel/trace\"\n\ttracepb \"go.opentelemetry.io/proto/otlp/trace/v1\"\n)\n\nfunc TestNewCfTracer(t *testing.T) {\n\tlog := zerolog.Nop()\n\treq := httptest.NewRequest(\"GET\", \"http://localhost\", nil)\n\treq.Header.Add(TracerContextName, \"14cb070dde8e51fc5ae8514e69ba42ca:b38f1bf5eae406f3:0:1\")\n\ttr := NewTracedHTTPRequest(req, 0, &log)\n\tassert.NotNil(t, tr)\n\tassert.IsType(t, tracesdk.NewTracerProvider(), tr.TracerProvider)\n\tassert.IsType(t, &InMemoryOtlpClient{}, tr.exporter)\n}\n\nfunc TestNewCfTracerMultiple(t *testing.T) {\n\tlog := zerolog.Nop()\n\treq := httptest.NewRequest(\"GET\", \"http://localhost\", nil)\n\treq.Header.Add(TracerContextName, \"1241ce3ecdefc68854e8514e69ba42ca:b38f1bf5eae406f3:0:1\")\n\treq.Header.Add(TracerContextName, \"14cb070dde8e51fc5ae8514e69ba42ca:b38f1bf5eae406f3:0:1\")\n\ttr := NewTracedHTTPRequest(req, 0, &log)\n\tassert.NotNil(t, tr)\n\tassert.IsType(t, tracesdk.NewTracerProvider(), tr.TracerProvider)\n\tassert.IsType(t, &InMemoryOtlpClient{}, tr.exporter)\n}\n\nfunc TestNewCfTracerNilHeader(t *testing.T) {\n\tlog := zerolog.Nop()\n\treq := httptest.NewRequest(\"GET\", \"http://localhost\", nil)\n\treq.Header[http.CanonicalHeaderKey(TracerContextName)] = nil\n\ttr := NewTracedHTTPRequest(req, 0, &log)\n\tassert.NotNil(t, tr)\n\tassert.IsType(t, trace.NewNoopTracerProvider(), tr.TracerProvider)\n\tassert.IsType(t, &NoopOtlpClient{}, tr.exporter)\n}\n\nfunc TestNewCfTracerInvalidHeaders(t *testing.T) {\n\tlog := zerolog.Nop()\n\treq := httptest.NewRequest(\"GET\", \"http://localhost\", nil)\n\tfor _, test := range [][]string{nil, {\"\"}} {\n\t\treq.Header[http.CanonicalHeaderKey(TracerContextName)] = test\n\t\ttr := NewTracedHTTPRequest(req, 0, &log)\n\t\tassert.NotNil(t, tr)\n\t\tassert.IsType(t, trace.NewNoopTracerProvider(), tr.TracerProvider)\n\t\tassert.IsType(t, &NoopOtlpClient{}, tr.exporter)\n\t}\n}\n\nfunc TestAddingSpansWithNilMap(t *testing.T) {\n\tlog := zerolog.Nop()\n\treq := httptest.NewRequest(\"GET\", \"http://localhost\", nil)\n\treq.Header.Add(TracerContextName, \"14cb070dde8e51fc5ae8514e69ba42ca:b38f1bf5eae406f3:0:1\")\n\ttr := NewTracedHTTPRequest(req, 0, &log)\n\n\texporter := tr.exporter.(*InMemoryOtlpClient)\n\n\t// add fake spans\n\tspans := createResourceSpans([]*tracepb.Span{createOtlpSpan(traceId)})\n\terr := exporter.UploadTraces(context.Background(), spans)\n\tassert.NoError(t, err)\n\n\t// a panic shouldn't occur\n\ttr.AddSpans(nil)\n}\n\nfunc FuzzNewIdentity(f *testing.F) {\n\tf.Fuzz(func(t *testing.T, trace string) {\n\t\t_, _ = NewIdentity(trace)\n\t})\n}\n"
  },
  {
    "path": "tunnelrpc/metrics/metrics.go",
    "content": "package metrics\n\nimport (\n\t\"github.com/prometheus/client_golang/prometheus\"\n)\n\nconst (\n\tmetricsNamespace = \"cloudflared\"\n\trpcSubsystem     = \"rpc\"\n)\n\n// CloudflaredServer operation labels\n// CloudflaredServer is an extension of SessionManager with additional methods, but it's helpful\n// to visualize it separately in the metrics since they are technically different client/servers.\nconst (\n\tCloudflared = \"cloudflared\"\n)\n\n// ConfigurationManager operation labels\nconst (\n\tConfigurationManager = \"config\"\n\n\tOperationUpdateConfiguration = \"update_configuration\"\n)\n\n// SessionManager operation labels\nconst (\n\tSessionManager = \"session\"\n\n\tOperationRegisterUdpSession   = \"register_udp_session\"\n\tOperationUnregisterUdpSession = \"unregister_udp_session\"\n)\n\n// RegistrationServer operation labels\nconst (\n\tRegistration = \"registration\"\n\n\tOperationRegisterConnection       = \"register_connection\"\n\tOperationUnregisterConnection     = \"unregister_connection\"\n\tOperationUpdateLocalConfiguration = \"update_local_configuration\"\n)\n\ntype rpcMetrics struct {\n\tserverOperations        *prometheus.CounterVec\n\tserverFailures          *prometheus.CounterVec\n\tserverOperationsLatency *prometheus.HistogramVec\n\n\tClientOperations        *prometheus.CounterVec\n\tClientFailures          *prometheus.CounterVec\n\tClientOperationsLatency *prometheus.HistogramVec\n}\n\nvar CapnpMetrics *rpcMetrics = &rpcMetrics{\n\tserverOperations: prometheus.NewCounterVec(\n\t\tprometheus.CounterOpts{\n\t\t\tNamespace: metricsNamespace,\n\t\t\tSubsystem: rpcSubsystem,\n\t\t\tName:      \"server_operations\",\n\t\t\tHelp:      \"Number of rpc methods by handler served\",\n\t\t},\n\t\t[]string{\"handler\", \"method\"},\n\t),\n\tserverFailures: prometheus.NewCounterVec(\n\t\tprometheus.CounterOpts{\n\t\t\tNamespace: metricsNamespace,\n\t\t\tSubsystem: rpcSubsystem,\n\t\t\tName:      \"server_failures\",\n\t\t\tHelp:      \"Number of rpc methods failures by handler served\",\n\t\t},\n\t\t[]string{\"handler\", \"method\"},\n\t),\n\tserverOperationsLatency: prometheus.NewHistogramVec(\n\t\tprometheus.HistogramOpts{\n\t\t\tNamespace: metricsNamespace,\n\t\t\tSubsystem: rpcSubsystem,\n\t\t\tName:      \"server_latency_secs\",\n\t\t\tHelp:      \"Latency of rpc methods by handler served\",\n\t\t\t// Bucket starts at 50ms, each bucket grows by a factor of 3, up to 5 buckets and is expressed as seconds:\n\t\t\t// 50ms, 150ms, 450ms, 1350ms, 4050ms\n\t\t\tBuckets: prometheus.ExponentialBuckets(0.05, 3, 5),\n\t\t},\n\t\t[]string{\"handler\", \"method\"},\n\t),\n\tClientOperations: prometheus.NewCounterVec(\n\t\tprometheus.CounterOpts{\n\t\t\tNamespace: metricsNamespace,\n\t\t\tSubsystem: rpcSubsystem,\n\t\t\tName:      \"client_operations\",\n\t\t\tHelp:      \"Number of rpc methods by handler requested\",\n\t\t},\n\t\t[]string{\"handler\", \"method\"},\n\t),\n\tClientFailures: prometheus.NewCounterVec(\n\t\tprometheus.CounterOpts{\n\t\t\tNamespace: metricsNamespace,\n\t\t\tSubsystem: rpcSubsystem,\n\t\t\tName:      \"client_failures\",\n\t\t\tHelp:      \"Number of rpc method failures by handler requested\",\n\t\t},\n\t\t[]string{\"handler\", \"method\"},\n\t),\n\tClientOperationsLatency: prometheus.NewHistogramVec(\n\t\tprometheus.HistogramOpts{\n\t\t\tNamespace: metricsNamespace,\n\t\t\tSubsystem: rpcSubsystem,\n\t\t\tName:      \"client_latency_secs\",\n\t\t\tHelp:      \"Latency of rpc methods by handler requested\",\n\t\t\t// Bucket starts at 50ms, each bucket grows by a factor of 3, up to 5 buckets and is expressed as seconds:\n\t\t\t// 50ms, 150ms, 450ms, 1350ms, 4050ms\n\t\t\tBuckets: prometheus.ExponentialBuckets(0.05, 3, 5),\n\t\t},\n\t\t[]string{\"handler\", \"method\"},\n\t),\n}\n\nfunc ObserveServerHandler(inner func() error, handler, method string) error {\n\tdefer CapnpMetrics.serverOperations.WithLabelValues(handler, method).Inc()\n\ttimer := prometheus.NewTimer(prometheus.ObserverFunc(func(s float64) {\n\t\tCapnpMetrics.serverOperationsLatency.WithLabelValues(handler, method).Observe(s)\n\t}))\n\tdefer timer.ObserveDuration()\n\n\terr := inner()\n\tif err != nil {\n\t\tCapnpMetrics.serverFailures.WithLabelValues(handler, method).Inc()\n\t}\n\treturn err\n}\n\nfunc NewClientOperationLatencyObserver(server string, method string) *prometheus.Timer {\n\treturn prometheus.NewTimer(prometheus.ObserverFunc(func(s float64) {\n\t\tCapnpMetrics.ClientOperationsLatency.WithLabelValues(server, method).Observe(s)\n\t}))\n}\n\nfunc init() {\n\tprometheus.MustRegister(CapnpMetrics.serverOperations)\n\tprometheus.MustRegister(CapnpMetrics.serverFailures)\n\tprometheus.MustRegister(CapnpMetrics.serverOperationsLatency)\n\tprometheus.MustRegister(CapnpMetrics.ClientOperations)\n\tprometheus.MustRegister(CapnpMetrics.ClientFailures)\n\tprometheus.MustRegister(CapnpMetrics.ClientOperationsLatency)\n}\n"
  },
  {
    "path": "tunnelrpc/pogs/cloudflared_server.go",
    "content": "package pogs\n\nimport (\n\tcapnp \"zombiezen.com/go/capnproto2\"\n\t\"zombiezen.com/go/capnproto2/rpc\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/proto\"\n)\n\ntype CloudflaredServer interface {\n\tSessionManager\n\tConfigurationManager\n}\n\ntype CloudflaredServer_PogsImpl struct {\n\tSessionManager_PogsImpl\n\tConfigurationManager_PogsImpl\n}\n\nfunc CloudflaredServer_ServerToClient(s SessionManager, c ConfigurationManager) proto.CloudflaredServer {\n\treturn proto.CloudflaredServer_ServerToClient(CloudflaredServer_PogsImpl{\n\t\tSessionManager_PogsImpl:       SessionManager_PogsImpl{s},\n\t\tConfigurationManager_PogsImpl: ConfigurationManager_PogsImpl{c},\n\t})\n}\n\ntype CloudflaredServer_PogsClient struct {\n\tSessionManager_PogsClient\n\tConfigurationManager_PogsClient\n\tClient capnp.Client\n\tConn   *rpc.Conn\n}\n\nfunc NewCloudflaredServer_PogsClient(client capnp.Client, conn *rpc.Conn) CloudflaredServer_PogsClient {\n\tsessionManagerClient := SessionManager_PogsClient{\n\t\tClient: client,\n\t\tConn:   conn,\n\t}\n\tconfigManagerClient := ConfigurationManager_PogsClient{\n\t\tClient: client,\n\t\tConn:   conn,\n\t}\n\treturn CloudflaredServer_PogsClient{\n\t\tSessionManager_PogsClient:       sessionManagerClient,\n\t\tConfigurationManager_PogsClient: configManagerClient,\n\t\tClient:                          client,\n\t\tConn:                            conn,\n\t}\n}\n\nfunc (c CloudflaredServer_PogsClient) Close() error {\n\tc.Client.Close()\n\treturn c.Conn.Close()\n}\n"
  },
  {
    "path": "tunnelrpc/pogs/configuration_manager.go",
    "content": "package pogs\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tcapnp \"zombiezen.com/go/capnproto2\"\n\t\"zombiezen.com/go/capnproto2/rpc\"\n\t\"zombiezen.com/go/capnproto2/server\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/metrics\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/proto\"\n)\n\ntype ConfigurationManager interface {\n\t// UpdateConfiguration is the call provided to cloudflared to load the latest remote configuration.\n\tUpdateConfiguration(ctx context.Context, version int32, config []byte) *UpdateConfigurationResponse\n}\n\ntype ConfigurationManager_PogsImpl struct {\n\timpl ConfigurationManager\n}\n\nfunc ConfigurationManager_ServerToClient(c ConfigurationManager) proto.ConfigurationManager {\n\treturn proto.ConfigurationManager_ServerToClient(ConfigurationManager_PogsImpl{c})\n}\n\nfunc (i ConfigurationManager_PogsImpl) UpdateConfiguration(p proto.ConfigurationManager_updateConfiguration) error {\n\treturn metrics.ObserveServerHandler(func() error { return i.updateConfiguration(p) }, metrics.ConfigurationManager, metrics.OperationUpdateConfiguration)\n}\n\nfunc (i ConfigurationManager_PogsImpl) updateConfiguration(p proto.ConfigurationManager_updateConfiguration) error {\n\tserver.Ack(p.Options)\n\n\tversion := p.Params.Version()\n\tconfig, err := p.Params.Config()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tresult, err := p.Results.NewResult()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tupdateResp := i.impl.UpdateConfiguration(p.Ctx, version, config)\n\treturn updateResp.Marshal(result)\n}\n\ntype ConfigurationManager_PogsClient struct {\n\tClient capnp.Client\n\tConn   *rpc.Conn\n}\n\nfunc (c ConfigurationManager_PogsClient) Close() error {\n\tc.Client.Close()\n\treturn c.Conn.Close()\n}\n\nfunc (c ConfigurationManager_PogsClient) UpdateConfiguration(ctx context.Context, version int32, config []byte) (*UpdateConfigurationResponse, error) {\n\tclient := proto.ConfigurationManager{Client: c.Client}\n\tpromise := client.UpdateConfiguration(ctx, func(p proto.ConfigurationManager_updateConfiguration_Params) error {\n\t\tp.SetVersion(version)\n\t\treturn p.SetConfig(config)\n\t})\n\tresult, err := promise.Result().Struct()\n\tif err != nil {\n\t\treturn nil, wrapRPCError(err)\n\t}\n\tresponse := new(UpdateConfigurationResponse)\n\n\terr = response.Unmarshal(result)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn response, nil\n}\n\ntype UpdateConfigurationResponse struct {\n\tLastAppliedVersion int32 `json:\"lastAppliedVersion\"`\n\tErr                error `json:\"err\"`\n}\n\nfunc (p *UpdateConfigurationResponse) Marshal(s proto.UpdateConfigurationResponse) error {\n\ts.SetLatestAppliedVersion(p.LastAppliedVersion)\n\tif p.Err != nil {\n\t\treturn s.SetErr(p.Err.Error())\n\t}\n\treturn nil\n}\n\nfunc (p *UpdateConfigurationResponse) Unmarshal(s proto.UpdateConfigurationResponse) error {\n\tp.LastAppliedVersion = s.LatestAppliedVersion()\n\trespErr, err := s.Err()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif respErr != \"\" {\n\t\tp.Err = fmt.Errorf(\"%s\", respErr)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "tunnelrpc/pogs/errors.go",
    "content": "package pogs\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\ntype RetryableError struct {\n\terr   error\n\tDelay time.Duration\n}\n\nfunc (re *RetryableError) Error() string {\n\treturn re.err.Error()\n}\n\n// RetryErrorAfter wraps err to indicate that client should retry after delay\nfunc RetryErrorAfter(err error, delay time.Duration) *RetryableError {\n\treturn &RetryableError{\n\t\terr:   err,\n\t\tDelay: delay,\n\t}\n}\n\nfunc (re *RetryableError) Unwrap() error {\n\treturn re.err\n}\n\n// RPCError is used to indicate errors returned by the RPC subsystem rather\n// than failure of a remote operation\ntype RPCError struct {\n\terr error\n}\n\nfunc (re *RPCError) Error() string {\n\treturn re.err.Error()\n}\n\nfunc wrapRPCError(err error) *RPCError {\n\tif err != nil {\n\t\treturn &RPCError{\n\t\t\terr: err,\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc newRPCError(format string, args ...interface{}) *RPCError {\n\treturn &RPCError{\n\t\tfmt.Errorf(format, args...),\n\t}\n}\n\nfunc (re *RPCError) Unwrap() error {\n\treturn re.err\n}\n"
  },
  {
    "path": "tunnelrpc/pogs/quic_metadata_protocol.go",
    "content": "package pogs\n\nimport (\n\t\"fmt\"\n\n\tcapnp \"zombiezen.com/go/capnproto2\"\n\t\"zombiezen.com/go/capnproto2/pogs\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/proto\"\n)\n\n// ConnectionType indicates the type of underlying connection proxied within the QUIC stream.\ntype ConnectionType uint16\n\nconst (\n\tConnectionTypeHTTP ConnectionType = iota\n\tConnectionTypeWebsocket\n\tConnectionTypeTCP\n)\n\nvar (\n\t// ErrorFlowConnectRateLimitedMetadata is the Metadata entry that allows to know if a request was rate limited on connect.\n\tErrorFlowConnectRateLimitedMetadata = Metadata{Key: \"FlowConnectRateLimited\", Val: \"true\"}\n)\n\nfunc (c ConnectionType) String() string {\n\tswitch c {\n\tcase ConnectionTypeHTTP:\n\t\treturn \"http\"\n\tcase ConnectionTypeWebsocket:\n\t\treturn \"ws\"\n\tcase ConnectionTypeTCP:\n\t\treturn \"tcp\"\n\t}\n\tpanic(fmt.Sprintf(\"invalid ConnectionType: %d\", c))\n}\n\n// ConnectRequest is the representation of metadata sent at the start of a QUIC application handshake.\ntype ConnectRequest struct {\n\tDest     string         `capnp:\"dest\"`\n\tType     ConnectionType `capnp:\"type\"`\n\tMetadata []Metadata     `capnp:\"metadata\"`\n}\n\n// Metadata is a representation of key value based data sent via RequestMeta.\ntype Metadata struct {\n\tKey string `capnp:\"key\"`\n\tVal string `capnp:\"val\"`\n}\n\n// MetadataMap returns a map format of []Metadata.\nfunc (r *ConnectRequest) MetadataMap() map[string]string {\n\tmetadataMap := make(map[string]string)\n\tfor _, metadata := range r.Metadata {\n\t\tmetadataMap[metadata.Key] = metadata.Val\n\t}\n\treturn metadataMap\n}\n\nfunc (r *ConnectRequest) FromPogs(msg *capnp.Message) error {\n\tmetadata, err := proto.ReadRootConnectRequest(msg)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn pogs.Extract(r, proto.ConnectRequest_TypeID, metadata.Struct)\n}\n\nfunc (r *ConnectRequest) ToPogs() (*capnp.Message, error) {\n\tmsg, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\troot, err := proto.NewRootConnectRequest(seg)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := pogs.Insert(proto.ConnectRequest_TypeID, root.Struct, r); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn msg, nil\n}\n\n// ConnectResponse is a representation of metadata sent as a response to a QUIC application handshake.\ntype ConnectResponse struct {\n\tError    string     `capnp:\"error\"`\n\tMetadata []Metadata `capnp:\"metadata\"`\n}\n\nfunc (r *ConnectResponse) FromPogs(msg *capnp.Message) error {\n\tmetadata, err := proto.ReadRootConnectResponse(msg)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn pogs.Extract(r, proto.ConnectResponse_TypeID, metadata.Struct)\n}\n\nfunc (r *ConnectResponse) ToPogs() (*capnp.Message, error) {\n\tmsg, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\troot, err := proto.NewRootConnectResponse(seg)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := pogs.Insert(proto.ConnectResponse_TypeID, root.Struct, r); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn msg, nil\n}\n"
  },
  {
    "path": "tunnelrpc/pogs/registration_server.go",
    "content": "package pogs\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\tcapnp \"zombiezen.com/go/capnproto2\"\n\t\"zombiezen.com/go/capnproto2/pogs\"\n\t\"zombiezen.com/go/capnproto2/rpc\"\n\t\"zombiezen.com/go/capnproto2/server\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/metrics\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/proto\"\n)\n\ntype RegistrationServer interface {\n\t// RegisterConnection is the call typically handled by the edge to initiate and authenticate a new connection\n\t// for cloudflared.\n\tRegisterConnection(ctx context.Context, auth TunnelAuth, tunnelID uuid.UUID, connIndex byte, options *ConnectionOptions) (*ConnectionDetails, error)\n\t// UnregisterConnection is the call typically handled by the edge to close an existing connection for cloudflared.\n\tUnregisterConnection(ctx context.Context)\n\t// UpdateLocalConfiguration is the call typically handled by the edge for cloudflared to provide the current\n\t// configuration it is operating with.\n\tUpdateLocalConfiguration(ctx context.Context, config []byte) error\n}\n\ntype RegistrationServer_PogsImpl struct {\n\timpl RegistrationServer\n}\n\nfunc RegistrationServer_ServerToClient(s RegistrationServer) proto.RegistrationServer {\n\treturn proto.RegistrationServer_ServerToClient(RegistrationServer_PogsImpl{s})\n}\n\nfunc (i RegistrationServer_PogsImpl) RegisterConnection(p proto.RegistrationServer_registerConnection) error {\n\treturn metrics.ObserveServerHandler(func() error { return i.registerConnection(p) }, metrics.Registration, metrics.OperationRegisterConnection)\n}\n\nfunc (i RegistrationServer_PogsImpl) registerConnection(p proto.RegistrationServer_registerConnection) error {\n\tserver.Ack(p.Options)\n\n\tauth, err := p.Params.Auth()\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar pogsAuth TunnelAuth\n\terr = pogsAuth.UnmarshalCapnproto(auth)\n\tif err != nil {\n\t\treturn err\n\t}\n\tuuidBytes, err := p.Params.TunnelId()\n\tif err != nil {\n\t\treturn err\n\t}\n\ttunnelID, err := uuid.FromBytes(uuidBytes)\n\tif err != nil {\n\t\treturn err\n\t}\n\tconnIndex := p.Params.ConnIndex()\n\toptions, err := p.Params.Options()\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar pogsOptions ConnectionOptions\n\terr = pogsOptions.UnmarshalCapnproto(options)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tconnDetails, callError := i.impl.RegisterConnection(p.Ctx, pogsAuth, tunnelID, connIndex, &pogsOptions)\n\n\tresp, err := p.Results.NewResult()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif callError != nil {\n\t\tif connError, err := resp.Result().NewError(); err != nil {\n\t\t\treturn err\n\t\t} else {\n\t\t\treturn MarshalError(connError, callError)\n\t\t}\n\t}\n\n\tif details, err := resp.Result().NewConnectionDetails(); err != nil {\n\t\treturn err\n\t} else {\n\t\treturn connDetails.MarshalCapnproto(details)\n\t}\n}\n\nfunc (i RegistrationServer_PogsImpl) UnregisterConnection(p proto.RegistrationServer_unregisterConnection) error {\n\treturn metrics.ObserveServerHandler(func() error {\n\t\tserver.Ack(p.Options)\n\t\ti.impl.UnregisterConnection(p.Ctx)\n\t\treturn nil // No metrics will be reported for failure as this method has no return value\n\t}, metrics.Registration, metrics.OperationUnregisterConnection)\n}\n\nfunc (i RegistrationServer_PogsImpl) UpdateLocalConfiguration(p proto.RegistrationServer_updateLocalConfiguration) error {\n\treturn metrics.ObserveServerHandler(func() error { return i.updateLocalConfiguration(p) }, metrics.Registration, metrics.OperationUpdateLocalConfiguration)\n}\n\nfunc (i RegistrationServer_PogsImpl) updateLocalConfiguration(c proto.RegistrationServer_updateLocalConfiguration) error {\n\tserver.Ack(c.Options)\n\n\tconfigBytes, err := c.Params.Config()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn i.impl.UpdateLocalConfiguration(c.Ctx, configBytes)\n}\n\ntype RegistrationServer_PogsClient struct {\n\tClient capnp.Client\n\tConn   *rpc.Conn\n}\n\nfunc NewRegistrationServer_PogsClient(client capnp.Client, conn *rpc.Conn) RegistrationServer_PogsClient {\n\treturn RegistrationServer_PogsClient{\n\t\tClient: client,\n\t\tConn:   conn,\n\t}\n}\n\nfunc (c RegistrationServer_PogsClient) Close() error {\n\tc.Client.Close()\n\treturn c.Conn.Close()\n}\n\nfunc (c RegistrationServer_PogsClient) RegisterConnection(ctx context.Context, auth TunnelAuth, tunnelID uuid.UUID, connIndex byte, options *ConnectionOptions) (*ConnectionDetails, error) {\n\tclient := proto.TunnelServer{Client: c.Client}\n\tpromise := client.RegisterConnection(ctx, func(p proto.RegistrationServer_registerConnection_Params) error {\n\t\ttunnelAuth, err := p.NewAuth()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err = auth.MarshalCapnproto(tunnelAuth); err != nil {\n\t\t\treturn err\n\t\t}\n\t\terr = p.SetAuth(tunnelAuth)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\terr = p.SetTunnelId(tunnelID[:])\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tp.SetConnIndex(connIndex)\n\t\tconnectionOptions, err := p.NewOptions()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\terr = options.MarshalCapnproto(connectionOptions)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n\tresponse, err := promise.Result().Struct()\n\tif err != nil {\n\t\treturn nil, wrapRPCError(err)\n\t}\n\tresult := response.Result()\n\tswitch result.Which() {\n\tcase proto.ConnectionResponse_result_Which_error:\n\t\tresultError, err := result.Error()\n\t\tif err != nil {\n\t\t\treturn nil, wrapRPCError(err)\n\t\t}\n\t\tcause, err := resultError.Cause()\n\t\tif err != nil {\n\t\t\treturn nil, wrapRPCError(err)\n\t\t}\n\t\terr = errors.New(cause)\n\t\tif resultError.ShouldRetry() {\n\t\t\terr = RetryErrorAfter(err, time.Duration(resultError.RetryAfter()))\n\t\t}\n\t\treturn nil, err\n\n\tcase proto.ConnectionResponse_result_Which_connectionDetails:\n\t\tconnDetails, err := result.ConnectionDetails()\n\t\tif err != nil {\n\t\t\treturn nil, wrapRPCError(err)\n\t\t}\n\t\tdetails := new(ConnectionDetails)\n\t\tif err = details.UnmarshalCapnproto(connDetails); err != nil {\n\t\t\treturn nil, wrapRPCError(err)\n\t\t}\n\t\treturn details, nil\n\t}\n\n\treturn nil, newRPCError(\"unknown result which %d\", result.Which())\n}\n\nfunc (c RegistrationServer_PogsClient) SendLocalConfiguration(ctx context.Context, config []byte) error {\n\tclient := proto.TunnelServer{Client: c.Client}\n\tpromise := client.UpdateLocalConfiguration(ctx, func(p proto.RegistrationServer_updateLocalConfiguration_Params) error {\n\t\tif err := p.SetConfig(config); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn nil\n\t})\n\n\t_, err := promise.Struct()\n\tif err != nil {\n\t\treturn wrapRPCError(err)\n\t}\n\n\treturn nil\n}\n\nfunc (c RegistrationServer_PogsClient) UnregisterConnection(ctx context.Context) error {\n\tclient := proto.TunnelServer{Client: c.Client}\n\tpromise := client.UnregisterConnection(ctx, func(p proto.RegistrationServer_unregisterConnection_Params) error {\n\t\treturn nil\n\t})\n\t_, err := promise.Struct()\n\tif err != nil {\n\t\treturn wrapRPCError(err)\n\t}\n\treturn nil\n}\n\ntype ClientInfo struct {\n\tClientID []byte `capnp:\"clientId\"` // must be a slice for capnp compatibility\n\tFeatures []string\n\tVersion  string\n\tArch     string\n}\n\ntype ConnectionOptions struct {\n\tClient              ClientInfo\n\tOriginLocalIP       net.IP `capnp:\"originLocalIp\"`\n\tReplaceExisting     bool\n\tCompressionQuality  uint8\n\tNumPreviousAttempts uint8\n}\n\ntype TunnelAuth struct {\n\tAccountTag   string\n\tTunnelSecret []byte\n}\n\nfunc (p *ConnectionOptions) MarshalCapnproto(s proto.ConnectionOptions) error {\n\treturn pogs.Insert(proto.ConnectionOptions_TypeID, s.Struct, p)\n}\n\nfunc (p *ConnectionOptions) UnmarshalCapnproto(s proto.ConnectionOptions) error {\n\treturn pogs.Extract(p, proto.ConnectionOptions_TypeID, s.Struct)\n}\n\nfunc (a *TunnelAuth) MarshalCapnproto(s proto.TunnelAuth) error {\n\treturn pogs.Insert(proto.TunnelAuth_TypeID, s.Struct, a)\n}\n\nfunc (a *TunnelAuth) UnmarshalCapnproto(s proto.TunnelAuth) error {\n\treturn pogs.Extract(a, proto.TunnelAuth_TypeID, s.Struct)\n}\n\ntype ConnectionDetails struct {\n\tUUID                    uuid.UUID\n\tLocation                string\n\tTunnelIsRemotelyManaged bool\n}\n\nfunc (details *ConnectionDetails) MarshalCapnproto(s proto.ConnectionDetails) error {\n\tif err := s.SetUuid(details.UUID[:]); err != nil {\n\t\treturn err\n\t}\n\tif err := s.SetLocationName(details.Location); err != nil {\n\t\treturn err\n\t}\n\ts.SetTunnelIsRemotelyManaged(details.TunnelIsRemotelyManaged)\n\n\treturn nil\n}\n\nfunc (details *ConnectionDetails) UnmarshalCapnproto(s proto.ConnectionDetails) error {\n\tuuidBytes, err := s.Uuid()\n\tif err != nil {\n\t\treturn err\n\t}\n\tdetails.UUID, err = uuid.FromBytes(uuidBytes)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdetails.Location, err = s.LocationName()\n\tif err != nil {\n\t\treturn err\n\t}\n\tdetails.TunnelIsRemotelyManaged = s.TunnelIsRemotelyManaged()\n\n\treturn err\n}\n\nfunc MarshalError(s proto.ConnectionError, err error) error {\n\tif err := s.SetCause(err.Error()); err != nil {\n\t\treturn err\n\t}\n\tif retryableErr, ok := err.(*RetryableError); ok {\n\t\ts.SetShouldRetry(true)\n\t\ts.SetRetryAfter(int64(retryableErr.Delay))\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "tunnelrpc/pogs/registration_server_test.go",
    "content": "package pogs\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\tcapnp \"zombiezen.com/go/capnproto2\"\n\t\"zombiezen.com/go/capnproto2/rpc\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/proto\"\n)\n\nconst testAccountTag = \"abc123\"\n\nfunc TestMarshalConnectionOptions(t *testing.T) {\n\tclientID := uuid.New()\n\torig := ConnectionOptions{\n\t\tClient: ClientInfo{\n\t\t\tClientID: clientID[:],\n\t\t\tFeatures: []string{\"a\", \"b\"},\n\t\t\tVersion:  \"1.2.3\",\n\t\t\tArch:     \"macos\",\n\t\t},\n\t\tOriginLocalIP:      []byte{10, 2, 3, 4},\n\t\tReplaceExisting:    false,\n\t\tCompressionQuality: 1,\n\t}\n\n\t_, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))\n\trequire.NoError(t, err)\n\tcapnpOpts, err := proto.NewConnectionOptions(seg)\n\trequire.NoError(t, err)\n\n\terr = orig.MarshalCapnproto(capnpOpts)\n\tassert.NoError(t, err)\n\n\tvar pogsOpts ConnectionOptions\n\terr = pogsOpts.UnmarshalCapnproto(capnpOpts)\n\tassert.NoError(t, err)\n\n\tassert.Equal(t, orig, pogsOpts)\n}\n\nfunc TestConnectionRegistrationRPC(t *testing.T) {\n\tp1, p2 := net.Pipe()\n\n\tt1, t2 := rpc.StreamTransport(p1), rpc.StreamTransport(p2)\n\n\t// Server-side\n\ttestImpl := testConnectionRegistrationServer{}\n\tsrv := RegistrationServer_ServerToClient(&testImpl)\n\tserverConn := rpc.NewConn(t1, rpc.MainInterface(srv.Client))\n\tdefer serverConn.Wait()\n\n\tctx := context.Background()\n\tclientConn := rpc.NewConn(t2)\n\tdefer clientConn.Close()\n\tclient := RegistrationServer_PogsClient{\n\t\tClient: clientConn.Bootstrap(ctx),\n\t\tConn:   clientConn,\n\t}\n\tdefer client.Close()\n\n\tclientID := uuid.New()\n\toptions := &ConnectionOptions{\n\t\tClient: ClientInfo{\n\t\t\tClientID: clientID[:],\n\t\t\tFeatures: []string{\"foo\"},\n\t\t\tVersion:  \"1.2.3\",\n\t\t\tArch:     \"macos\",\n\t\t},\n\t\tOriginLocalIP:      net.IP{10, 20, 30, 40},\n\t\tReplaceExisting:    true,\n\t\tCompressionQuality: 0,\n\t}\n\n\texpectedDetails := ConnectionDetails{\n\t\tUUID:     uuid.New(),\n\t\tLocation: \"TEST\",\n\t}\n\ttestImpl.details = &expectedDetails\n\ttestImpl.err = nil\n\n\tauth := TunnelAuth{\n\t\tAccountTag:   testAccountTag,\n\t\tTunnelSecret: []byte{1, 2, 3, 4},\n\t}\n\n\t// success\n\ttunnelID := uuid.New()\n\tdetails, err := client.RegisterConnection(ctx, auth, tunnelID, 2, options)\n\tassert.NoError(t, err)\n\tassert.Equal(t, expectedDetails, *details)\n\n\t// regular error\n\ttestImpl.details = nil\n\ttestImpl.err = errors.New(\"internal\")\n\n\t_, err = client.RegisterConnection(ctx, auth, tunnelID, 2, options)\n\tassert.EqualError(t, err, \"internal\")\n\n\t// retriable error\n\ttestImpl.details = nil\n\tconst delay = 27 * time.Second\n\ttestImpl.err = RetryErrorAfter(errors.New(\"retryable\"), delay)\n\n\t_, err = client.RegisterConnection(ctx, auth, tunnelID, 2, options)\n\tassert.EqualError(t, err, \"retryable\")\n\n\tre, ok := err.(*RetryableError)\n\tassert.True(t, ok)\n\tassert.Equal(t, delay, re.Delay)\n}\n\ntype testConnectionRegistrationServer struct {\n\tdetails *ConnectionDetails\n\terr     error\n}\n\nfunc (t *testConnectionRegistrationServer) UpdateLocalConfiguration(ctx context.Context, config []byte) error {\n\t// do nothing at this point\n\treturn nil\n}\n\nfunc (t *testConnectionRegistrationServer) RegisterConnection(ctx context.Context, auth TunnelAuth, tunnelID uuid.UUID, connIndex byte, options *ConnectionOptions) (*ConnectionDetails, error) {\n\tif auth.AccountTag != testAccountTag {\n\t\tpanic(\"bad account tag: \" + auth.AccountTag)\n\t}\n\tif t.err != nil {\n\t\treturn nil, t.err\n\t}\n\tif t.details != nil {\n\t\treturn t.details, nil\n\t}\n\n\tpanic(\"either details or err mush be set\")\n}\n\nfunc (t *testConnectionRegistrationServer) UnregisterConnection(ctx context.Context) {\n\tpanic(\"unimplemented: UnregisterConnection\")\n}\n"
  },
  {
    "path": "tunnelrpc/pogs/session_manager.go",
    "content": "package pogs\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\tcapnp \"zombiezen.com/go/capnproto2\"\n\t\"zombiezen.com/go/capnproto2/rpc\"\n\t\"zombiezen.com/go/capnproto2/server\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/metrics\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/proto\"\n)\n\ntype SessionManager interface {\n\t// RegisterUdpSession is the call provided to cloudflared to handle an incoming\n\t// capnproto RegisterUdpSession request from the edge.\n\tRegisterUdpSession(ctx context.Context, sessionID uuid.UUID, dstIP net.IP, dstPort uint16, closeAfterIdleHint time.Duration, traceContext string) (*RegisterUdpSessionResponse, error)\n\t// UnregisterUdpSession is the call provided to cloudflared to handle an incoming\n\t// capnproto UnregisterUdpSession request from the edge.\n\tUnregisterUdpSession(ctx context.Context, sessionID uuid.UUID, message string) error\n}\n\ntype SessionManager_PogsImpl struct {\n\timpl SessionManager\n}\n\nfunc SessionManager_ServerToClient(s SessionManager) proto.SessionManager {\n\treturn proto.SessionManager_ServerToClient(SessionManager_PogsImpl{s})\n}\n\nfunc (i SessionManager_PogsImpl) RegisterUdpSession(p proto.SessionManager_registerUdpSession) error {\n\treturn metrics.ObserveServerHandler(func() error { return i.registerUdpSession(p) }, metrics.SessionManager, metrics.OperationRegisterUdpSession)\n}\n\nfunc (i SessionManager_PogsImpl) registerUdpSession(p proto.SessionManager_registerUdpSession) error {\n\tserver.Ack(p.Options)\n\n\tsessionIDRaw, err := p.Params.SessionId()\n\tif err != nil {\n\t\treturn err\n\t}\n\tsessionID, err := uuid.FromBytes(sessionIDRaw)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdstIPRaw, err := p.Params.DstIp()\n\tif err != nil {\n\t\treturn err\n\t}\n\tdstIP := net.IP(dstIPRaw)\n\tif dstIP == nil {\n\t\treturn fmt.Errorf(\"%v is not valid IP\", dstIPRaw)\n\t}\n\tdstPort := p.Params.DstPort()\n\n\tcloseIdleAfterHint := time.Duration(p.Params.CloseAfterIdleHint())\n\n\ttraceContext, err := p.Params.TraceContext()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tresp, registrationErr := i.impl.RegisterUdpSession(p.Ctx, sessionID, dstIP, dstPort, closeIdleAfterHint, traceContext)\n\tif registrationErr != nil {\n\t\t// Make sure to assign a response even if one is not returned from register\n\t\tif resp == nil {\n\t\t\tresp = &RegisterUdpSessionResponse{}\n\t\t}\n\t\tresp.Err = registrationErr\n\t}\n\n\tresult, err := p.Results.NewResult()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn resp.Marshal(result)\n}\n\nfunc (i SessionManager_PogsImpl) UnregisterUdpSession(p proto.SessionManager_unregisterUdpSession) error {\n\treturn metrics.ObserveServerHandler(func() error { return i.unregisterUdpSession(p) }, metrics.SessionManager, metrics.OperationUnregisterUdpSession)\n}\n\nfunc (i SessionManager_PogsImpl) unregisterUdpSession(p proto.SessionManager_unregisterUdpSession) error {\n\tserver.Ack(p.Options)\n\n\tsessionIDRaw, err := p.Params.SessionId()\n\tif err != nil {\n\t\treturn err\n\t}\n\tsessionID, err := uuid.FromBytes(sessionIDRaw)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tmessage, err := p.Params.Message()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn i.impl.UnregisterUdpSession(p.Ctx, sessionID, message)\n}\n\ntype RegisterUdpSessionResponse struct {\n\tErr   error\n\tSpans []byte // Spans in protobuf format\n}\n\nfunc (p *RegisterUdpSessionResponse) Marshal(s proto.RegisterUdpSessionResponse) error {\n\tif p.Err != nil {\n\t\treturn s.SetErr(p.Err.Error())\n\t}\n\tif err := s.SetSpans(p.Spans); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (p *RegisterUdpSessionResponse) Unmarshal(s proto.RegisterUdpSessionResponse) error {\n\trespErr, err := s.Err()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif respErr != \"\" {\n\t\tp.Err = fmt.Errorf(\"%s\", respErr)\n\t}\n\tp.Spans, err = s.Spans()\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\ntype SessionManager_PogsClient struct {\n\tClient capnp.Client\n\tConn   *rpc.Conn\n}\n\nfunc NewSessionManager_PogsClient(client capnp.Client, conn *rpc.Conn) SessionManager_PogsClient {\n\treturn SessionManager_PogsClient{\n\t\tClient: client,\n\t\tConn:   conn,\n\t}\n}\n\nfunc (c SessionManager_PogsClient) Close() error {\n\tc.Client.Close()\n\treturn c.Conn.Close()\n}\n\nfunc (c SessionManager_PogsClient) RegisterUdpSession(ctx context.Context, sessionID uuid.UUID, dstIP net.IP, dstPort uint16, closeAfterIdleHint time.Duration, traceContext string) (*RegisterUdpSessionResponse, error) {\n\tclient := proto.SessionManager{Client: c.Client}\n\tpromise := client.RegisterUdpSession(ctx, func(p proto.SessionManager_registerUdpSession_Params) error {\n\t\tif err := p.SetSessionId(sessionID[:]); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := p.SetDstIp(dstIP); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tp.SetDstPort(dstPort)\n\t\tp.SetCloseAfterIdleHint(int64(closeAfterIdleHint))\n\t\t_ = p.SetTraceContext(traceContext)\n\t\treturn nil\n\t})\n\tresult, err := promise.Result().Struct()\n\tif err != nil {\n\t\treturn nil, wrapRPCError(err)\n\t}\n\tresponse := new(RegisterUdpSessionResponse)\n\n\terr = response.Unmarshal(result)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn response, nil\n}\n\nfunc (c SessionManager_PogsClient) UnregisterUdpSession(ctx context.Context, sessionID uuid.UUID, message string) error {\n\tclient := proto.SessionManager{Client: c.Client}\n\tpromise := client.UnregisterUdpSession(ctx, func(p proto.SessionManager_unregisterUdpSession_Params) error {\n\t\tif err := p.SetSessionId(sessionID[:]); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := p.SetMessage(message); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n\t_, err := promise.Struct()\n\treturn err\n}\n"
  },
  {
    "path": "tunnelrpc/pogs/tag.go",
    "content": "package pogs\n\n// Tag previously was a legacy tunnel capnp struct but was deprecated. To help reduce the amount of changes imposed\n// by removing this simple struct, it was copied out of the capnp and provided here instead.\ntype Tag struct {\n\tName  string\n\tValue string\n}\n"
  },
  {
    "path": "tunnelrpc/proto/go.capnp",
    "content": "# Generate go.capnp.out with:\n# capnp compile -o- go.capnp > go.capnp.out\n# Must run inside this directory to preserve paths.\n\n@0xd12a1c51fedd6c88;\n\nannotation package(file) :Text;\n# The Go package name for the generated file.\n\nannotation import(file) :Text;\n# The Go import path that the generated file is accessible from.\n# Used to generate import statements and check if two types are in the\n# same package.\n\nannotation doc(struct, field, enum) :Text;\n# Adds a doc comment to the generated code.\n\nannotation tag(enumerant) :Text;\n# Changes the string representation of the enum in the generated code.\n\nannotation notag(enumerant) :Void;\n# Removes the string representation of the enum in the generated code.\n\nannotation customtype(field) :Text;\n# OBSOLETE, not used by code generator.\n\nannotation name(struct, field, union, enum, enumerant, interface, method, param, annotation, const, group) :Text;\n# Used to rename the element in the generated code.\n\n$package(\"capnp\");\n$import(\"zombiezen.com/go/capnproto2\");\n"
  },
  {
    "path": "tunnelrpc/proto/quic_metadata_protocol.capnp",
    "content": "using Go = import \"go.capnp\";\n@0xb29021ef7421cc32;\n\n$Go.package(\"proto\");\n$Go.import(\"github.com/cloudflare/cloudflared/tunnelrpc\");\n\n\nstruct ConnectRequest @0xc47116a1045e4061 {\n\tdest @0 :Text;\n\ttype @1 :ConnectionType;\n\tmetadata @2 :List(Metadata);\n}\n\nenum ConnectionType @0xc52e1bac26d379c8 {\n\thttp @0;\n\twebsocket @1;\n\ttcp @2;\n}\n\nstruct Metadata @0xe1446b97bfd1cd37 {\n    key @0 :Text;\n\tval @1 :Text;\n}\n\nstruct ConnectResponse @0xb1032ec91cef8727 {\n\terror @0 :Text;\n\tmetadata @1 :List(Metadata);\n}\n"
  },
  {
    "path": "tunnelrpc/proto/quic_metadata_protocol.capnp.go",
    "content": "// Code generated by capnpc-go. DO NOT EDIT.\n\npackage proto\n\nimport (\n\tcapnp \"zombiezen.com/go/capnproto2\"\n\ttext \"zombiezen.com/go/capnproto2/encoding/text\"\n\tschemas \"zombiezen.com/go/capnproto2/schemas\"\n)\n\ntype ConnectRequest struct{ capnp.Struct }\n\n// ConnectRequest_TypeID is the unique identifier for the type ConnectRequest.\nconst ConnectRequest_TypeID = 0xc47116a1045e4061\n\nfunc NewConnectRequest(s *capnp.Segment) (ConnectRequest, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2})\n\treturn ConnectRequest{st}, err\n}\n\nfunc NewRootConnectRequest(s *capnp.Segment) (ConnectRequest, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2})\n\treturn ConnectRequest{st}, err\n}\n\nfunc ReadRootConnectRequest(msg *capnp.Message) (ConnectRequest, error) {\n\troot, err := msg.RootPtr()\n\treturn ConnectRequest{root.Struct()}, err\n}\n\nfunc (s ConnectRequest) String() string {\n\tstr, _ := text.Marshal(0xc47116a1045e4061, s.Struct)\n\treturn str\n}\n\nfunc (s ConnectRequest) Dest() (string, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.Text(), err\n}\n\nfunc (s ConnectRequest) HasDest() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ConnectRequest) DestBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.TextBytes(), err\n}\n\nfunc (s ConnectRequest) SetDest(v string) error {\n\treturn s.Struct.SetText(0, v)\n}\n\nfunc (s ConnectRequest) Type() ConnectionType {\n\treturn ConnectionType(s.Struct.Uint16(0))\n}\n\nfunc (s ConnectRequest) SetType(v ConnectionType) {\n\ts.Struct.SetUint16(0, uint16(v))\n}\n\nfunc (s ConnectRequest) Metadata() (Metadata_List, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn Metadata_List{List: p.List()}, err\n}\n\nfunc (s ConnectRequest) HasMetadata() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ConnectRequest) SetMetadata(v Metadata_List) error {\n\treturn s.Struct.SetPtr(1, v.List.ToPtr())\n}\n\n// NewMetadata sets the metadata field to a newly\n// allocated Metadata_List, preferring placement in s's segment.\nfunc (s ConnectRequest) NewMetadata(n int32) (Metadata_List, error) {\n\tl, err := NewMetadata_List(s.Struct.Segment(), n)\n\tif err != nil {\n\t\treturn Metadata_List{}, err\n\t}\n\terr = s.Struct.SetPtr(1, l.List.ToPtr())\n\treturn l, err\n}\n\n// ConnectRequest_List is a list of ConnectRequest.\ntype ConnectRequest_List struct{ capnp.List }\n\n// NewConnectRequest creates a new list of ConnectRequest.\nfunc NewConnectRequest_List(s *capnp.Segment, sz int32) (ConnectRequest_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}, sz)\n\treturn ConnectRequest_List{l}, err\n}\n\nfunc (s ConnectRequest_List) At(i int) ConnectRequest { return ConnectRequest{s.List.Struct(i)} }\n\nfunc (s ConnectRequest_List) Set(i int, v ConnectRequest) error { return s.List.SetStruct(i, v.Struct) }\n\nfunc (s ConnectRequest_List) String() string {\n\tstr, _ := text.MarshalList(0xc47116a1045e4061, s.List)\n\treturn str\n}\n\n// ConnectRequest_Promise is a wrapper for a ConnectRequest promised by a client call.\ntype ConnectRequest_Promise struct{ *capnp.Pipeline }\n\nfunc (p ConnectRequest_Promise) Struct() (ConnectRequest, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn ConnectRequest{s}, err\n}\n\ntype ConnectionType uint16\n\n// ConnectionType_TypeID is the unique identifier for the type ConnectionType.\nconst ConnectionType_TypeID = 0xc52e1bac26d379c8\n\n// Values of ConnectionType.\nconst (\n\tConnectionType_http      ConnectionType = 0\n\tConnectionType_websocket ConnectionType = 1\n\tConnectionType_tcp       ConnectionType = 2\n)\n\n// String returns the enum's constant name.\nfunc (c ConnectionType) String() string {\n\tswitch c {\n\tcase ConnectionType_http:\n\t\treturn \"http\"\n\tcase ConnectionType_websocket:\n\t\treturn \"websocket\"\n\tcase ConnectionType_tcp:\n\t\treturn \"tcp\"\n\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\n// ConnectionTypeFromString returns the enum value with a name,\n// or the zero value if there's no such value.\nfunc ConnectionTypeFromString(c string) ConnectionType {\n\tswitch c {\n\tcase \"http\":\n\t\treturn ConnectionType_http\n\tcase \"websocket\":\n\t\treturn ConnectionType_websocket\n\tcase \"tcp\":\n\t\treturn ConnectionType_tcp\n\n\tdefault:\n\t\treturn 0\n\t}\n}\n\ntype ConnectionType_List struct{ capnp.List }\n\nfunc NewConnectionType_List(s *capnp.Segment, sz int32) (ConnectionType_List, error) {\n\tl, err := capnp.NewUInt16List(s, sz)\n\treturn ConnectionType_List{l.List}, err\n}\n\nfunc (l ConnectionType_List) At(i int) ConnectionType {\n\tul := capnp.UInt16List{List: l.List}\n\treturn ConnectionType(ul.At(i))\n}\n\nfunc (l ConnectionType_List) Set(i int, v ConnectionType) {\n\tul := capnp.UInt16List{List: l.List}\n\tul.Set(i, uint16(v))\n}\n\ntype Metadata struct{ capnp.Struct }\n\n// Metadata_TypeID is the unique identifier for the type Metadata.\nconst Metadata_TypeID = 0xe1446b97bfd1cd37\n\nfunc NewMetadata(s *capnp.Segment) (Metadata, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2})\n\treturn Metadata{st}, err\n}\n\nfunc NewRootMetadata(s *capnp.Segment) (Metadata, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2})\n\treturn Metadata{st}, err\n}\n\nfunc ReadRootMetadata(msg *capnp.Message) (Metadata, error) {\n\troot, err := msg.RootPtr()\n\treturn Metadata{root.Struct()}, err\n}\n\nfunc (s Metadata) String() string {\n\tstr, _ := text.Marshal(0xe1446b97bfd1cd37, s.Struct)\n\treturn str\n}\n\nfunc (s Metadata) Key() (string, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.Text(), err\n}\n\nfunc (s Metadata) HasKey() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s Metadata) KeyBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.TextBytes(), err\n}\n\nfunc (s Metadata) SetKey(v string) error {\n\treturn s.Struct.SetText(0, v)\n}\n\nfunc (s Metadata) Val() (string, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.Text(), err\n}\n\nfunc (s Metadata) HasVal() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s Metadata) ValBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.TextBytes(), err\n}\n\nfunc (s Metadata) SetVal(v string) error {\n\treturn s.Struct.SetText(1, v)\n}\n\n// Metadata_List is a list of Metadata.\ntype Metadata_List struct{ capnp.List }\n\n// NewMetadata creates a new list of Metadata.\nfunc NewMetadata_List(s *capnp.Segment, sz int32) (Metadata_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}, sz)\n\treturn Metadata_List{l}, err\n}\n\nfunc (s Metadata_List) At(i int) Metadata { return Metadata{s.List.Struct(i)} }\n\nfunc (s Metadata_List) Set(i int, v Metadata) error { return s.List.SetStruct(i, v.Struct) }\n\nfunc (s Metadata_List) String() string {\n\tstr, _ := text.MarshalList(0xe1446b97bfd1cd37, s.List)\n\treturn str\n}\n\n// Metadata_Promise is a wrapper for a Metadata promised by a client call.\ntype Metadata_Promise struct{ *capnp.Pipeline }\n\nfunc (p Metadata_Promise) Struct() (Metadata, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn Metadata{s}, err\n}\n\ntype ConnectResponse struct{ capnp.Struct }\n\n// ConnectResponse_TypeID is the unique identifier for the type ConnectResponse.\nconst ConnectResponse_TypeID = 0xb1032ec91cef8727\n\nfunc NewConnectResponse(s *capnp.Segment) (ConnectResponse, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2})\n\treturn ConnectResponse{st}, err\n}\n\nfunc NewRootConnectResponse(s *capnp.Segment) (ConnectResponse, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2})\n\treturn ConnectResponse{st}, err\n}\n\nfunc ReadRootConnectResponse(msg *capnp.Message) (ConnectResponse, error) {\n\troot, err := msg.RootPtr()\n\treturn ConnectResponse{root.Struct()}, err\n}\n\nfunc (s ConnectResponse) String() string {\n\tstr, _ := text.Marshal(0xb1032ec91cef8727, s.Struct)\n\treturn str\n}\n\nfunc (s ConnectResponse) Error() (string, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.Text(), err\n}\n\nfunc (s ConnectResponse) HasError() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ConnectResponse) ErrorBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.TextBytes(), err\n}\n\nfunc (s ConnectResponse) SetError(v string) error {\n\treturn s.Struct.SetText(0, v)\n}\n\nfunc (s ConnectResponse) Metadata() (Metadata_List, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn Metadata_List{List: p.List()}, err\n}\n\nfunc (s ConnectResponse) HasMetadata() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ConnectResponse) SetMetadata(v Metadata_List) error {\n\treturn s.Struct.SetPtr(1, v.List.ToPtr())\n}\n\n// NewMetadata sets the metadata field to a newly\n// allocated Metadata_List, preferring placement in s's segment.\nfunc (s ConnectResponse) NewMetadata(n int32) (Metadata_List, error) {\n\tl, err := NewMetadata_List(s.Struct.Segment(), n)\n\tif err != nil {\n\t\treturn Metadata_List{}, err\n\t}\n\terr = s.Struct.SetPtr(1, l.List.ToPtr())\n\treturn l, err\n}\n\n// ConnectResponse_List is a list of ConnectResponse.\ntype ConnectResponse_List struct{ capnp.List }\n\n// NewConnectResponse creates a new list of ConnectResponse.\nfunc NewConnectResponse_List(s *capnp.Segment, sz int32) (ConnectResponse_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}, sz)\n\treturn ConnectResponse_List{l}, err\n}\n\nfunc (s ConnectResponse_List) At(i int) ConnectResponse { return ConnectResponse{s.List.Struct(i)} }\n\nfunc (s ConnectResponse_List) Set(i int, v ConnectResponse) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s ConnectResponse_List) String() string {\n\tstr, _ := text.MarshalList(0xb1032ec91cef8727, s.List)\n\treturn str\n}\n\n// ConnectResponse_Promise is a wrapper for a ConnectResponse promised by a client call.\ntype ConnectResponse_Promise struct{ *capnp.Pipeline }\n\nfunc (p ConnectResponse_Promise) Struct() (ConnectResponse, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn ConnectResponse{s}, err\n}\n\nconst schema_b29021ef7421cc32 = \"x\\xda\\xb4\\x911k\\x14A\\x1c\\xc5\\xdf\\x9b\\xcde-\\x0e\" +\n\t\"\\xf7\\x86KlT\\xc2\\x05Q\\x13\\xdc\\x8b\\xc9\\x09\\xa2 \\x1c\" +\n\t\"\\x18A%\\xc1\\x9b`mX7\\x83\\x09w\\xee\\xce\\xed\\xce\" +\n\t\"\\x19\\xee\\x13\\xd8\\xda\\x89\\xa5\\xbd \\x09X\\xdb((h!\" +\n\t\"\\x16\\xd6\\x0a66\\xf9\\x04\\xb22\\x0b\\x9b\\x83\\x90B\\x04\\xbb\" +\n\t\"\\xe1\\xcd\\x9by\\xbf\\xff\\xff5\\xbeu\\xc5r\\xed\\x11\\x01\\xd5\" +\n\t\"\\xa8M\\x17\\x17\\x9e\\x1e\\x9c\\xf9\\xd8\\xf6\\xf6 C\\x16+\\x9f\" +\n\t\"Z\\xf6\\xa0\\xf5l\\x1f5\\xe1\\x03\\xcb/~Q\\xbe\\xf1\\x01\" +\n\t\"\\xb9\\xb7\\x0b\\x16Q\\xf7\\xc1\\xd4\\xcbS\\xc3wP!\\x8fZ\" +\n\t\";-\\xfe`\\xf3\\x06}\\xa0y\\x8d\\xaf\\xc1\\xe2\\xc3\\xf8\\xeb\" +\n\t\"\\xf9W\\xa7\\xdb\\xef!C11\\x83\\x9d\\x9f\\xceI\\xf7\\xa8\" +\n\t\"\\xf9\\x9b\\xf7\\xc0\\xe2\\xea\\xe7/o\\x9f\\xf7W\\xbf\\x1fC\\xd0\" +\n\t\"\\x99\\x15\\xfbl\\x86\\xa5yA8\\x08;J\\x12=\\xc8\\xcc\" +\n\t\"t\\xbcd\\xb2\\xd4\\xa6K\\xc3\\xd1N\\xbc\\xf9X\\xdbh+\" +\n\t\"\\xb2\\xd1f\\xa9\\xc5\\xe9\\xa0\\x1dG&1\\xd7o\\xa6I\\xa2\" +\n\t\"c\\xbb\\xa1s\\x13\\xa4I\\xae{\\xa4:\\xe1M\\x01S\\x04\" +\n\t\"\\xe4\\xc2\\x0a\\xa0\\xceyT\\x97\\x05%9C'\\x86w\\x01\" +\n\t\"u\\xc9\\xa3\\xba-8\\xa7\\xb3,\\xcdX\\x87`\\x1d,\\xaa\" +\n\t\"\\x14\\x00<\\x09\\xf6<\\xb21\\xa1\\x07\\x9d\\xf8\\xaf\\x80\\xc3\\x91\" +\n\t\"\\xafs\\xeb\\xf8\\xea\\x87|\\xb7\\x16\\x01\\xd5\\xf5\\xa8\\xd6\\x04+\" +\n\t\"\\xbc;N[\\xf5\\xa8z\\x82Rp\\x86\\x02\\x90\\xeb\\x8ey\" +\n\t\"\\xcd\\xa3\\xda\\x16\\x0c\\xb6tn+\\xe4\\xc0\\x8e\\x8df0)\" +\n\t\"\\x03d\\xf0_'\\xd9I\\x93\\xfb\\xfe\\xd8\\x94\\x9b\\xae\\x97p\" +\n\t\"g\\x17\\xdd\\x87rv\\x03\\xa0\\x90r\\x1e\\x08\\xb6\\xad5\\xc5\" +\n\t\"\\xae~\\x98\\xa7q_\\x83\\xd6\\xb7\\xb19\\x8c\\xab\\xfdU\\xdc\" +\n\t\"\\xba\\xb6s\\xe5\\xc5\\x91J\\xe7\\x8f\\xab\\xd4\\x89\\x17=\\xaa+\" +\n\t\"\\x82~_\\x8f\\xab\\xed\\xf8O\\xa2Au\\xfe\\x13\\x00\\x00\\xff\" +\n\t\"\\xff\\x1d\\xce\\xd1\\xb0\"\n\nfunc init() {\n\tschemas.Register(schema_b29021ef7421cc32,\n\t\t0xb1032ec91cef8727,\n\t\t0xc47116a1045e4061,\n\t\t0xc52e1bac26d379c8,\n\t\t0xe1446b97bfd1cd37)\n}\n"
  },
  {
    "path": "tunnelrpc/proto/tunnelrpc.capnp",
    "content": "using Go = import \"go.capnp\";\n@0xdb8274f9144abc7e;\n$Go.package(\"proto\");\n$Go.import(\"github.com/cloudflare/cloudflared/tunnelrpc\");\n\n# === DEPRECATED Legacy Tunnel Authentication and Registration methods/servers ===\n# \n# These structs and interfaces are no longer used but it is important to keep\n# them around to make sure backwards compatibility within the rpc protocol is\n# maintained.\n\nstruct Authentication @0xc082ef6e0d42ed1d {\n    # DEPRECATED: Legacy tunnel authentication mechanism\n    key @0 :Text;\n    email @1 :Text;\n    originCAKey @2 :Text;\n}\n\nstruct TunnelRegistration @0xf41a0f001ad49e46 {\n    # DEPRECATED: Legacy tunnel authentication mechanism\n    err @0 :Text;\n    # the url to access the tunnel\n    url @1 :Text;\n    # Used to inform the client of actions taken.\n    logLines @2 :List(Text);\n    # In case of error, whether the client should attempt to reconnect.\n    permanentFailure @3 :Bool;\n    # Displayed to user\n    tunnelID @4 :Text;\n    # How long should this connection wait to retry in seconds, if the error wasn't permanent\n    retryAfterSeconds @5 :UInt16;\n    # A unique ID used to reconnect this tunnel.\n    eventDigest @6 :Data;\n    # A unique ID used to prove this tunnel was previously connected to a given metal.\n    connDigest @7 :Data;\n}\n\nstruct RegistrationOptions @0xc793e50592935b4a {\n    # DEPRECATED: Legacy tunnel authentication mechanism\n    \n    # The tunnel client's unique identifier, used to verify a reconnection.\n    clientId @0 :Text;\n    # Information about the running binary.\n    version @1 :Text;\n    os @2 :Text;\n    # What to do with existing tunnels for the given hostname.\n    existingTunnelPolicy @3 :ExistingTunnelPolicy;\n    # If using the balancing policy, identifies the LB pool to use.\n    poolName @4 :Text;\n    # Client-defined tags to associate with the tunnel\n    tags @5 :List(Tag);\n    # A unique identifier for a high-availability connection made by a single client.\n    connectionId @6 :UInt8;\n    # origin LAN IP\n    originLocalIp @7 :Text;\n    # whether Argo Tunnel client has been autoupdated\n    isAutoupdated @8 :Bool;\n    # whether Argo Tunnel client is run from a terminal\n    runFromTerminal @9 :Bool;\n    # cross stream compression setting, 0 - off, 3 - high\n    compressionQuality @10 :UInt64;\n    uuid @11 :Text;\n    # number of previous attempts to send RegisterTunnel/ReconnectTunnel\n    numPreviousAttempts @12 :UInt8;\n    # Set of features this cloudflared knows it supports\n    features @13 :List(Text);\n}\n\nenum ExistingTunnelPolicy @0x84cb9536a2cf6d3c {\n    # DEPRECATED: Legacy tunnel registration mechanism\n\n    ignore @0;\n    disconnect @1;\n    balance @2;\n}\n\nstruct ServerInfo @0xf2c68e2547ec3866 {\n    # DEPRECATED: Legacy tunnel registration mechanism\n\n    locationName @0 :Text;\n}\n\nstruct AuthenticateResponse @0x82c325a07ad22a65 {\n    # DEPRECATED: Legacy tunnel registration mechanism\n\n    permanentErr @0 :Text;\n    retryableErr @1 :Text;\n    jwt @2 :Data;\n    hoursUntilRefresh @3 :UInt8;\n}\n\ninterface TunnelServer @0xea58385c65416035 extends (RegistrationServer) {\n    # DEPRECATED: Legacy tunnel authentication server\n\n    registerTunnel @0 (originCert :Data, hostname :Text, options :RegistrationOptions) -> (result :TunnelRegistration);\n    getServerInfo @1 () -> (result :ServerInfo);\n    unregisterTunnel @2 (gracePeriodNanoSec :Int64) -> ();\n    # obsoleteDeclarativeTunnelConnect RPC deprecated in TUN-3019\n    obsoleteDeclarativeTunnelConnect @3 () -> ();\n    authenticate @4 (originCert :Data, hostname :Text, options :RegistrationOptions) -> (result :AuthenticateResponse);\n    reconnectTunnel @5 (jwt :Data, eventDigest :Data, connDigest :Data, hostname :Text, options :RegistrationOptions) -> (result :TunnelRegistration);\n}\n\nstruct Tag @0xcbd96442ae3bb01a {\n    # DEPRECATED: Legacy tunnel additional HTTP header mechanism \n\n    name @0 :Text;\n    value @1 :Text;\n}\n\n# === End DEPRECATED Objects ===\n\nstruct ClientInfo @0x83ced0145b2f114b {\n    # The tunnel client's unique identifier, used to verify a reconnection.\n    clientId @0 :Data;\n    # Set of features this cloudflared knows it supports\n    features @1 :List(Text);\n    # Information about the running binary.\n    version @2 :Text;\n    # Client OS and CPU info\n    arch @3 :Text;\n}\n\nstruct ConnectionOptions @0xb4bf9861fe035d04 {\n    # client details\n    client @0 :ClientInfo;\n    # origin LAN IP\n    originLocalIp @1 :Data;\n    # What to do if connection already exists\n    replaceExisting @2 :Bool;\n    # cross stream compression setting, 0 - off, 3 - high\n    compressionQuality @3 :UInt8;\n    # number of previous attempts to send RegisterConnection\n    numPreviousAttempts @4 :UInt8;\n}\n\nstruct ConnectionResponse @0xdbaa9d03d52b62dc {\n    result :union {\n        error @0 :ConnectionError;\n        connectionDetails @1 :ConnectionDetails;\n    }\n}\n\nstruct ConnectionError @0xf5f383d2785edb86 {\n    cause @0 :Text;\n    # How long should this connection wait to retry in ns\n    retryAfter @1 :Int64;\n    shouldRetry @2 :Bool;\n}\n\nstruct ConnectionDetails @0xb5f39f082b9ac18a {\n    # identifier of this connection\n    uuid @0 :Data;\n    # airport code of the colo where this connection landed\n    locationName @1 :Text;\n    # tells if the tunnel is remotely managed\n    tunnelIsRemotelyManaged @2: Bool;\n}\n\nstruct TunnelAuth @0x9496331ab9cd463f {\n  accountTag @0 :Text;\n  tunnelSecret @1 :Data;\n}\n\ninterface RegistrationServer @0xf71695ec7fe85497 {\n    registerConnection @0 (auth :TunnelAuth, tunnelId :Data, connIndex :UInt8, options :ConnectionOptions) -> (result :ConnectionResponse);\n    unregisterConnection @1 () -> ();\n    updateLocalConfiguration @2 (config :Data) -> ();\n}\n\nstruct RegisterUdpSessionResponse @0xab6d5210c1f26687 {\n    err @0 :Text;\n    spans @1 :Data;\n}\n\ninterface SessionManager @0x839445a59fb01686 {\n    # Let the edge decide closeAfterIdle to make sure cloudflared doesn't close session before the edge closes its side\n    registerUdpSession @0 (sessionId :Data, dstIp :Data, dstPort :UInt16, closeAfterIdleHint :Int64, traceContext :Text = \"\") -> (result :RegisterUdpSessionResponse);\n    unregisterUdpSession @1 (sessionId :Data, message :Text) -> ();\n}\n\nstruct UpdateConfigurationResponse @0xdb58ff694ba05cf9 {\n    # Latest configuration that was applied successfully. The err field might be populated at the same time to indicate\n    # that cloudflared is using an older configuration because the latest cannot be applied\n    latestAppliedVersion @0 :Int32;\n    # Any error encountered when trying to apply the last configuration\n    err @1 :Text;\n}\n\n# ConfigurationManager defines RPC to manage cloudflared configuration remotely\ninterface ConfigurationManager @0xb48edfbdaa25db04 {\n    updateConfiguration @0 (version :Int32, config :Data) -> (result: UpdateConfigurationResponse);\n}\n\ninterface CloudflaredServer @0xf548cef9dea2a4a1 extends(SessionManager, ConfigurationManager) {}"
  },
  {
    "path": "tunnelrpc/proto/tunnelrpc.capnp.go",
    "content": "// Code generated by capnpc-go. DO NOT EDIT.\n\npackage proto\n\nimport (\n\tstrconv \"strconv\"\n\n\tcontext \"golang.org/x/net/context\"\n\tcapnp \"zombiezen.com/go/capnproto2\"\n\ttext \"zombiezen.com/go/capnproto2/encoding/text\"\n\tschemas \"zombiezen.com/go/capnproto2/schemas\"\n\tserver \"zombiezen.com/go/capnproto2/server\"\n)\n\ntype Authentication struct{ capnp.Struct }\n\n// Authentication_TypeID is the unique identifier for the type Authentication.\nconst Authentication_TypeID = 0xc082ef6e0d42ed1d\n\nfunc NewAuthentication(s *capnp.Segment) (Authentication, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3})\n\treturn Authentication{st}, err\n}\n\nfunc NewRootAuthentication(s *capnp.Segment) (Authentication, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3})\n\treturn Authentication{st}, err\n}\n\nfunc ReadRootAuthentication(msg *capnp.Message) (Authentication, error) {\n\troot, err := msg.RootPtr()\n\treturn Authentication{root.Struct()}, err\n}\n\nfunc (s Authentication) String() string {\n\tstr, _ := text.Marshal(0xc082ef6e0d42ed1d, s.Struct)\n\treturn str\n}\n\nfunc (s Authentication) Key() (string, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.Text(), err\n}\n\nfunc (s Authentication) HasKey() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s Authentication) KeyBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.TextBytes(), err\n}\n\nfunc (s Authentication) SetKey(v string) error {\n\treturn s.Struct.SetText(0, v)\n}\n\nfunc (s Authentication) Email() (string, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.Text(), err\n}\n\nfunc (s Authentication) HasEmail() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s Authentication) EmailBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.TextBytes(), err\n}\n\nfunc (s Authentication) SetEmail(v string) error {\n\treturn s.Struct.SetText(1, v)\n}\n\nfunc (s Authentication) OriginCAKey() (string, error) {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.Text(), err\n}\n\nfunc (s Authentication) HasOriginCAKey() bool {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s Authentication) OriginCAKeyBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.TextBytes(), err\n}\n\nfunc (s Authentication) SetOriginCAKey(v string) error {\n\treturn s.Struct.SetText(2, v)\n}\n\n// Authentication_List is a list of Authentication.\ntype Authentication_List struct{ capnp.List }\n\n// NewAuthentication creates a new list of Authentication.\nfunc NewAuthentication_List(s *capnp.Segment, sz int32) (Authentication_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3}, sz)\n\treturn Authentication_List{l}, err\n}\n\nfunc (s Authentication_List) At(i int) Authentication { return Authentication{s.List.Struct(i)} }\n\nfunc (s Authentication_List) Set(i int, v Authentication) error { return s.List.SetStruct(i, v.Struct) }\n\nfunc (s Authentication_List) String() string {\n\tstr, _ := text.MarshalList(0xc082ef6e0d42ed1d, s.List)\n\treturn str\n}\n\n// Authentication_Promise is a wrapper for a Authentication promised by a client call.\ntype Authentication_Promise struct{ *capnp.Pipeline }\n\nfunc (p Authentication_Promise) Struct() (Authentication, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn Authentication{s}, err\n}\n\ntype TunnelRegistration struct{ capnp.Struct }\n\n// TunnelRegistration_TypeID is the unique identifier for the type TunnelRegistration.\nconst TunnelRegistration_TypeID = 0xf41a0f001ad49e46\n\nfunc NewTunnelRegistration(s *capnp.Segment) (TunnelRegistration, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 6})\n\treturn TunnelRegistration{st}, err\n}\n\nfunc NewRootTunnelRegistration(s *capnp.Segment) (TunnelRegistration, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 6})\n\treturn TunnelRegistration{st}, err\n}\n\nfunc ReadRootTunnelRegistration(msg *capnp.Message) (TunnelRegistration, error) {\n\troot, err := msg.RootPtr()\n\treturn TunnelRegistration{root.Struct()}, err\n}\n\nfunc (s TunnelRegistration) String() string {\n\tstr, _ := text.Marshal(0xf41a0f001ad49e46, s.Struct)\n\treturn str\n}\n\nfunc (s TunnelRegistration) Err() (string, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.Text(), err\n}\n\nfunc (s TunnelRegistration) HasErr() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelRegistration) ErrBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.TextBytes(), err\n}\n\nfunc (s TunnelRegistration) SetErr(v string) error {\n\treturn s.Struct.SetText(0, v)\n}\n\nfunc (s TunnelRegistration) Url() (string, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.Text(), err\n}\n\nfunc (s TunnelRegistration) HasUrl() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelRegistration) UrlBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.TextBytes(), err\n}\n\nfunc (s TunnelRegistration) SetUrl(v string) error {\n\treturn s.Struct.SetText(1, v)\n}\n\nfunc (s TunnelRegistration) LogLines() (capnp.TextList, error) {\n\tp, err := s.Struct.Ptr(2)\n\treturn capnp.TextList{List: p.List()}, err\n}\n\nfunc (s TunnelRegistration) HasLogLines() bool {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelRegistration) SetLogLines(v capnp.TextList) error {\n\treturn s.Struct.SetPtr(2, v.List.ToPtr())\n}\n\n// NewLogLines sets the logLines field to a newly\n// allocated capnp.TextList, preferring placement in s's segment.\nfunc (s TunnelRegistration) NewLogLines(n int32) (capnp.TextList, error) {\n\tl, err := capnp.NewTextList(s.Struct.Segment(), n)\n\tif err != nil {\n\t\treturn capnp.TextList{}, err\n\t}\n\terr = s.Struct.SetPtr(2, l.List.ToPtr())\n\treturn l, err\n}\n\nfunc (s TunnelRegistration) PermanentFailure() bool {\n\treturn s.Struct.Bit(0)\n}\n\nfunc (s TunnelRegistration) SetPermanentFailure(v bool) {\n\ts.Struct.SetBit(0, v)\n}\n\nfunc (s TunnelRegistration) TunnelID() (string, error) {\n\tp, err := s.Struct.Ptr(3)\n\treturn p.Text(), err\n}\n\nfunc (s TunnelRegistration) HasTunnelID() bool {\n\tp, err := s.Struct.Ptr(3)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelRegistration) TunnelIDBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(3)\n\treturn p.TextBytes(), err\n}\n\nfunc (s TunnelRegistration) SetTunnelID(v string) error {\n\treturn s.Struct.SetText(3, v)\n}\n\nfunc (s TunnelRegistration) RetryAfterSeconds() uint16 {\n\treturn s.Struct.Uint16(2)\n}\n\nfunc (s TunnelRegistration) SetRetryAfterSeconds(v uint16) {\n\ts.Struct.SetUint16(2, v)\n}\n\nfunc (s TunnelRegistration) EventDigest() ([]byte, error) {\n\tp, err := s.Struct.Ptr(4)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s TunnelRegistration) HasEventDigest() bool {\n\tp, err := s.Struct.Ptr(4)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelRegistration) SetEventDigest(v []byte) error {\n\treturn s.Struct.SetData(4, v)\n}\n\nfunc (s TunnelRegistration) ConnDigest() ([]byte, error) {\n\tp, err := s.Struct.Ptr(5)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s TunnelRegistration) HasConnDigest() bool {\n\tp, err := s.Struct.Ptr(5)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelRegistration) SetConnDigest(v []byte) error {\n\treturn s.Struct.SetData(5, v)\n}\n\n// TunnelRegistration_List is a list of TunnelRegistration.\ntype TunnelRegistration_List struct{ capnp.List }\n\n// NewTunnelRegistration creates a new list of TunnelRegistration.\nfunc NewTunnelRegistration_List(s *capnp.Segment, sz int32) (TunnelRegistration_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 6}, sz)\n\treturn TunnelRegistration_List{l}, err\n}\n\nfunc (s TunnelRegistration_List) At(i int) TunnelRegistration {\n\treturn TunnelRegistration{s.List.Struct(i)}\n}\n\nfunc (s TunnelRegistration_List) Set(i int, v TunnelRegistration) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s TunnelRegistration_List) String() string {\n\tstr, _ := text.MarshalList(0xf41a0f001ad49e46, s.List)\n\treturn str\n}\n\n// TunnelRegistration_Promise is a wrapper for a TunnelRegistration promised by a client call.\ntype TunnelRegistration_Promise struct{ *capnp.Pipeline }\n\nfunc (p TunnelRegistration_Promise) Struct() (TunnelRegistration, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn TunnelRegistration{s}, err\n}\n\ntype RegistrationOptions struct{ capnp.Struct }\n\n// RegistrationOptions_TypeID is the unique identifier for the type RegistrationOptions.\nconst RegistrationOptions_TypeID = 0xc793e50592935b4a\n\nfunc NewRegistrationOptions(s *capnp.Segment) (RegistrationOptions, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 8})\n\treturn RegistrationOptions{st}, err\n}\n\nfunc NewRootRegistrationOptions(s *capnp.Segment) (RegistrationOptions, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 8})\n\treturn RegistrationOptions{st}, err\n}\n\nfunc ReadRootRegistrationOptions(msg *capnp.Message) (RegistrationOptions, error) {\n\troot, err := msg.RootPtr()\n\treturn RegistrationOptions{root.Struct()}, err\n}\n\nfunc (s RegistrationOptions) String() string {\n\tstr, _ := text.Marshal(0xc793e50592935b4a, s.Struct)\n\treturn str\n}\n\nfunc (s RegistrationOptions) ClientId() (string, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.Text(), err\n}\n\nfunc (s RegistrationOptions) HasClientId() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s RegistrationOptions) ClientIdBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.TextBytes(), err\n}\n\nfunc (s RegistrationOptions) SetClientId(v string) error {\n\treturn s.Struct.SetText(0, v)\n}\n\nfunc (s RegistrationOptions) Version() (string, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.Text(), err\n}\n\nfunc (s RegistrationOptions) HasVersion() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s RegistrationOptions) VersionBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.TextBytes(), err\n}\n\nfunc (s RegistrationOptions) SetVersion(v string) error {\n\treturn s.Struct.SetText(1, v)\n}\n\nfunc (s RegistrationOptions) Os() (string, error) {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.Text(), err\n}\n\nfunc (s RegistrationOptions) HasOs() bool {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s RegistrationOptions) OsBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.TextBytes(), err\n}\n\nfunc (s RegistrationOptions) SetOs(v string) error {\n\treturn s.Struct.SetText(2, v)\n}\n\nfunc (s RegistrationOptions) ExistingTunnelPolicy() ExistingTunnelPolicy {\n\treturn ExistingTunnelPolicy(s.Struct.Uint16(0))\n}\n\nfunc (s RegistrationOptions) SetExistingTunnelPolicy(v ExistingTunnelPolicy) {\n\ts.Struct.SetUint16(0, uint16(v))\n}\n\nfunc (s RegistrationOptions) PoolName() (string, error) {\n\tp, err := s.Struct.Ptr(3)\n\treturn p.Text(), err\n}\n\nfunc (s RegistrationOptions) HasPoolName() bool {\n\tp, err := s.Struct.Ptr(3)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s RegistrationOptions) PoolNameBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(3)\n\treturn p.TextBytes(), err\n}\n\nfunc (s RegistrationOptions) SetPoolName(v string) error {\n\treturn s.Struct.SetText(3, v)\n}\n\nfunc (s RegistrationOptions) Tags() (Tag_List, error) {\n\tp, err := s.Struct.Ptr(4)\n\treturn Tag_List{List: p.List()}, err\n}\n\nfunc (s RegistrationOptions) HasTags() bool {\n\tp, err := s.Struct.Ptr(4)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s RegistrationOptions) SetTags(v Tag_List) error {\n\treturn s.Struct.SetPtr(4, v.List.ToPtr())\n}\n\n// NewTags sets the tags field to a newly\n// allocated Tag_List, preferring placement in s's segment.\nfunc (s RegistrationOptions) NewTags(n int32) (Tag_List, error) {\n\tl, err := NewTag_List(s.Struct.Segment(), n)\n\tif err != nil {\n\t\treturn Tag_List{}, err\n\t}\n\terr = s.Struct.SetPtr(4, l.List.ToPtr())\n\treturn l, err\n}\n\nfunc (s RegistrationOptions) ConnectionId() uint8 {\n\treturn s.Struct.Uint8(2)\n}\n\nfunc (s RegistrationOptions) SetConnectionId(v uint8) {\n\ts.Struct.SetUint8(2, v)\n}\n\nfunc (s RegistrationOptions) OriginLocalIp() (string, error) {\n\tp, err := s.Struct.Ptr(5)\n\treturn p.Text(), err\n}\n\nfunc (s RegistrationOptions) HasOriginLocalIp() bool {\n\tp, err := s.Struct.Ptr(5)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s RegistrationOptions) OriginLocalIpBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(5)\n\treturn p.TextBytes(), err\n}\n\nfunc (s RegistrationOptions) SetOriginLocalIp(v string) error {\n\treturn s.Struct.SetText(5, v)\n}\n\nfunc (s RegistrationOptions) IsAutoupdated() bool {\n\treturn s.Struct.Bit(24)\n}\n\nfunc (s RegistrationOptions) SetIsAutoupdated(v bool) {\n\ts.Struct.SetBit(24, v)\n}\n\nfunc (s RegistrationOptions) RunFromTerminal() bool {\n\treturn s.Struct.Bit(25)\n}\n\nfunc (s RegistrationOptions) SetRunFromTerminal(v bool) {\n\ts.Struct.SetBit(25, v)\n}\n\nfunc (s RegistrationOptions) CompressionQuality() uint64 {\n\treturn s.Struct.Uint64(8)\n}\n\nfunc (s RegistrationOptions) SetCompressionQuality(v uint64) {\n\ts.Struct.SetUint64(8, v)\n}\n\nfunc (s RegistrationOptions) Uuid() (string, error) {\n\tp, err := s.Struct.Ptr(6)\n\treturn p.Text(), err\n}\n\nfunc (s RegistrationOptions) HasUuid() bool {\n\tp, err := s.Struct.Ptr(6)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s RegistrationOptions) UuidBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(6)\n\treturn p.TextBytes(), err\n}\n\nfunc (s RegistrationOptions) SetUuid(v string) error {\n\treturn s.Struct.SetText(6, v)\n}\n\nfunc (s RegistrationOptions) NumPreviousAttempts() uint8 {\n\treturn s.Struct.Uint8(4)\n}\n\nfunc (s RegistrationOptions) SetNumPreviousAttempts(v uint8) {\n\ts.Struct.SetUint8(4, v)\n}\n\nfunc (s RegistrationOptions) Features() (capnp.TextList, error) {\n\tp, err := s.Struct.Ptr(7)\n\treturn capnp.TextList{List: p.List()}, err\n}\n\nfunc (s RegistrationOptions) HasFeatures() bool {\n\tp, err := s.Struct.Ptr(7)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s RegistrationOptions) SetFeatures(v capnp.TextList) error {\n\treturn s.Struct.SetPtr(7, v.List.ToPtr())\n}\n\n// NewFeatures sets the features field to a newly\n// allocated capnp.TextList, preferring placement in s's segment.\nfunc (s RegistrationOptions) NewFeatures(n int32) (capnp.TextList, error) {\n\tl, err := capnp.NewTextList(s.Struct.Segment(), n)\n\tif err != nil {\n\t\treturn capnp.TextList{}, err\n\t}\n\terr = s.Struct.SetPtr(7, l.List.ToPtr())\n\treturn l, err\n}\n\n// RegistrationOptions_List is a list of RegistrationOptions.\ntype RegistrationOptions_List struct{ capnp.List }\n\n// NewRegistrationOptions creates a new list of RegistrationOptions.\nfunc NewRegistrationOptions_List(s *capnp.Segment, sz int32) (RegistrationOptions_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 16, PointerCount: 8}, sz)\n\treturn RegistrationOptions_List{l}, err\n}\n\nfunc (s RegistrationOptions_List) At(i int) RegistrationOptions {\n\treturn RegistrationOptions{s.List.Struct(i)}\n}\n\nfunc (s RegistrationOptions_List) Set(i int, v RegistrationOptions) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s RegistrationOptions_List) String() string {\n\tstr, _ := text.MarshalList(0xc793e50592935b4a, s.List)\n\treturn str\n}\n\n// RegistrationOptions_Promise is a wrapper for a RegistrationOptions promised by a client call.\ntype RegistrationOptions_Promise struct{ *capnp.Pipeline }\n\nfunc (p RegistrationOptions_Promise) Struct() (RegistrationOptions, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn RegistrationOptions{s}, err\n}\n\ntype ExistingTunnelPolicy uint16\n\n// ExistingTunnelPolicy_TypeID is the unique identifier for the type ExistingTunnelPolicy.\nconst ExistingTunnelPolicy_TypeID = 0x84cb9536a2cf6d3c\n\n// Values of ExistingTunnelPolicy.\nconst (\n\tExistingTunnelPolicy_ignore     ExistingTunnelPolicy = 0\n\tExistingTunnelPolicy_disconnect ExistingTunnelPolicy = 1\n\tExistingTunnelPolicy_balance    ExistingTunnelPolicy = 2\n)\n\n// String returns the enum's constant name.\nfunc (c ExistingTunnelPolicy) String() string {\n\tswitch c {\n\tcase ExistingTunnelPolicy_ignore:\n\t\treturn \"ignore\"\n\tcase ExistingTunnelPolicy_disconnect:\n\t\treturn \"disconnect\"\n\tcase ExistingTunnelPolicy_balance:\n\t\treturn \"balance\"\n\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\n// ExistingTunnelPolicyFromString returns the enum value with a name,\n// or the zero value if there's no such value.\nfunc ExistingTunnelPolicyFromString(c string) ExistingTunnelPolicy {\n\tswitch c {\n\tcase \"ignore\":\n\t\treturn ExistingTunnelPolicy_ignore\n\tcase \"disconnect\":\n\t\treturn ExistingTunnelPolicy_disconnect\n\tcase \"balance\":\n\t\treturn ExistingTunnelPolicy_balance\n\n\tdefault:\n\t\treturn 0\n\t}\n}\n\ntype ExistingTunnelPolicy_List struct{ capnp.List }\n\nfunc NewExistingTunnelPolicy_List(s *capnp.Segment, sz int32) (ExistingTunnelPolicy_List, error) {\n\tl, err := capnp.NewUInt16List(s, sz)\n\treturn ExistingTunnelPolicy_List{l.List}, err\n}\n\nfunc (l ExistingTunnelPolicy_List) At(i int) ExistingTunnelPolicy {\n\tul := capnp.UInt16List{List: l.List}\n\treturn ExistingTunnelPolicy(ul.At(i))\n}\n\nfunc (l ExistingTunnelPolicy_List) Set(i int, v ExistingTunnelPolicy) {\n\tul := capnp.UInt16List{List: l.List}\n\tul.Set(i, uint16(v))\n}\n\ntype ServerInfo struct{ capnp.Struct }\n\n// ServerInfo_TypeID is the unique identifier for the type ServerInfo.\nconst ServerInfo_TypeID = 0xf2c68e2547ec3866\n\nfunc NewServerInfo(s *capnp.Segment) (ServerInfo, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn ServerInfo{st}, err\n}\n\nfunc NewRootServerInfo(s *capnp.Segment) (ServerInfo, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn ServerInfo{st}, err\n}\n\nfunc ReadRootServerInfo(msg *capnp.Message) (ServerInfo, error) {\n\troot, err := msg.RootPtr()\n\treturn ServerInfo{root.Struct()}, err\n}\n\nfunc (s ServerInfo) String() string {\n\tstr, _ := text.Marshal(0xf2c68e2547ec3866, s.Struct)\n\treturn str\n}\n\nfunc (s ServerInfo) LocationName() (string, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.Text(), err\n}\n\nfunc (s ServerInfo) HasLocationName() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ServerInfo) LocationNameBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.TextBytes(), err\n}\n\nfunc (s ServerInfo) SetLocationName(v string) error {\n\treturn s.Struct.SetText(0, v)\n}\n\n// ServerInfo_List is a list of ServerInfo.\ntype ServerInfo_List struct{ capnp.List }\n\n// NewServerInfo creates a new list of ServerInfo.\nfunc NewServerInfo_List(s *capnp.Segment, sz int32) (ServerInfo_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz)\n\treturn ServerInfo_List{l}, err\n}\n\nfunc (s ServerInfo_List) At(i int) ServerInfo { return ServerInfo{s.List.Struct(i)} }\n\nfunc (s ServerInfo_List) Set(i int, v ServerInfo) error { return s.List.SetStruct(i, v.Struct) }\n\nfunc (s ServerInfo_List) String() string {\n\tstr, _ := text.MarshalList(0xf2c68e2547ec3866, s.List)\n\treturn str\n}\n\n// ServerInfo_Promise is a wrapper for a ServerInfo promised by a client call.\ntype ServerInfo_Promise struct{ *capnp.Pipeline }\n\nfunc (p ServerInfo_Promise) Struct() (ServerInfo, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn ServerInfo{s}, err\n}\n\ntype AuthenticateResponse struct{ capnp.Struct }\n\n// AuthenticateResponse_TypeID is the unique identifier for the type AuthenticateResponse.\nconst AuthenticateResponse_TypeID = 0x82c325a07ad22a65\n\nfunc NewAuthenticateResponse(s *capnp.Segment) (AuthenticateResponse, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 3})\n\treturn AuthenticateResponse{st}, err\n}\n\nfunc NewRootAuthenticateResponse(s *capnp.Segment) (AuthenticateResponse, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 3})\n\treturn AuthenticateResponse{st}, err\n}\n\nfunc ReadRootAuthenticateResponse(msg *capnp.Message) (AuthenticateResponse, error) {\n\troot, err := msg.RootPtr()\n\treturn AuthenticateResponse{root.Struct()}, err\n}\n\nfunc (s AuthenticateResponse) String() string {\n\tstr, _ := text.Marshal(0x82c325a07ad22a65, s.Struct)\n\treturn str\n}\n\nfunc (s AuthenticateResponse) PermanentErr() (string, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.Text(), err\n}\n\nfunc (s AuthenticateResponse) HasPermanentErr() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s AuthenticateResponse) PermanentErrBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.TextBytes(), err\n}\n\nfunc (s AuthenticateResponse) SetPermanentErr(v string) error {\n\treturn s.Struct.SetText(0, v)\n}\n\nfunc (s AuthenticateResponse) RetryableErr() (string, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.Text(), err\n}\n\nfunc (s AuthenticateResponse) HasRetryableErr() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s AuthenticateResponse) RetryableErrBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.TextBytes(), err\n}\n\nfunc (s AuthenticateResponse) SetRetryableErr(v string) error {\n\treturn s.Struct.SetText(1, v)\n}\n\nfunc (s AuthenticateResponse) Jwt() ([]byte, error) {\n\tp, err := s.Struct.Ptr(2)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s AuthenticateResponse) HasJwt() bool {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s AuthenticateResponse) SetJwt(v []byte) error {\n\treturn s.Struct.SetData(2, v)\n}\n\nfunc (s AuthenticateResponse) HoursUntilRefresh() uint8 {\n\treturn s.Struct.Uint8(0)\n}\n\nfunc (s AuthenticateResponse) SetHoursUntilRefresh(v uint8) {\n\ts.Struct.SetUint8(0, v)\n}\n\n// AuthenticateResponse_List is a list of AuthenticateResponse.\ntype AuthenticateResponse_List struct{ capnp.List }\n\n// NewAuthenticateResponse creates a new list of AuthenticateResponse.\nfunc NewAuthenticateResponse_List(s *capnp.Segment, sz int32) (AuthenticateResponse_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 3}, sz)\n\treturn AuthenticateResponse_List{l}, err\n}\n\nfunc (s AuthenticateResponse_List) At(i int) AuthenticateResponse {\n\treturn AuthenticateResponse{s.List.Struct(i)}\n}\n\nfunc (s AuthenticateResponse_List) Set(i int, v AuthenticateResponse) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s AuthenticateResponse_List) String() string {\n\tstr, _ := text.MarshalList(0x82c325a07ad22a65, s.List)\n\treturn str\n}\n\n// AuthenticateResponse_Promise is a wrapper for a AuthenticateResponse promised by a client call.\ntype AuthenticateResponse_Promise struct{ *capnp.Pipeline }\n\nfunc (p AuthenticateResponse_Promise) Struct() (AuthenticateResponse, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn AuthenticateResponse{s}, err\n}\n\ntype TunnelServer struct{ Client capnp.Client }\n\n// TunnelServer_TypeID is the unique identifier for the type TunnelServer.\nconst TunnelServer_TypeID = 0xea58385c65416035\n\nfunc (c TunnelServer) RegisterTunnel(ctx context.Context, params func(TunnelServer_registerTunnel_Params) error, opts ...capnp.CallOption) TunnelServer_registerTunnel_Results_Promise {\n\tif c.Client == nil {\n\t\treturn TunnelServer_registerTunnel_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xea58385c65416035,\n\t\t\tMethodID:      0,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:TunnelServer\",\n\t\t\tMethodName:    \"registerTunnel\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 0, PointerCount: 3}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error { return params(TunnelServer_registerTunnel_Params{Struct: s}) }\n\t}\n\treturn TunnelServer_registerTunnel_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\nfunc (c TunnelServer) GetServerInfo(ctx context.Context, params func(TunnelServer_getServerInfo_Params) error, opts ...capnp.CallOption) TunnelServer_getServerInfo_Results_Promise {\n\tif c.Client == nil {\n\t\treturn TunnelServer_getServerInfo_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xea58385c65416035,\n\t\t\tMethodID:      1,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:TunnelServer\",\n\t\t\tMethodName:    \"getServerInfo\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 0, PointerCount: 0}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error { return params(TunnelServer_getServerInfo_Params{Struct: s}) }\n\t}\n\treturn TunnelServer_getServerInfo_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\nfunc (c TunnelServer) UnregisterTunnel(ctx context.Context, params func(TunnelServer_unregisterTunnel_Params) error, opts ...capnp.CallOption) TunnelServer_unregisterTunnel_Results_Promise {\n\tif c.Client == nil {\n\t\treturn TunnelServer_unregisterTunnel_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xea58385c65416035,\n\t\t\tMethodID:      2,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:TunnelServer\",\n\t\t\tMethodName:    \"unregisterTunnel\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 8, PointerCount: 0}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error { return params(TunnelServer_unregisterTunnel_Params{Struct: s}) }\n\t}\n\treturn TunnelServer_unregisterTunnel_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\nfunc (c TunnelServer) ObsoleteDeclarativeTunnelConnect(ctx context.Context, params func(TunnelServer_obsoleteDeclarativeTunnelConnect_Params) error, opts ...capnp.CallOption) TunnelServer_obsoleteDeclarativeTunnelConnect_Results_Promise {\n\tif c.Client == nil {\n\t\treturn TunnelServer_obsoleteDeclarativeTunnelConnect_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xea58385c65416035,\n\t\t\tMethodID:      3,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:TunnelServer\",\n\t\t\tMethodName:    \"obsoleteDeclarativeTunnelConnect\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 0, PointerCount: 0}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error {\n\t\t\treturn params(TunnelServer_obsoleteDeclarativeTunnelConnect_Params{Struct: s})\n\t\t}\n\t}\n\treturn TunnelServer_obsoleteDeclarativeTunnelConnect_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\nfunc (c TunnelServer) Authenticate(ctx context.Context, params func(TunnelServer_authenticate_Params) error, opts ...capnp.CallOption) TunnelServer_authenticate_Results_Promise {\n\tif c.Client == nil {\n\t\treturn TunnelServer_authenticate_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xea58385c65416035,\n\t\t\tMethodID:      4,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:TunnelServer\",\n\t\t\tMethodName:    \"authenticate\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 0, PointerCount: 3}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error { return params(TunnelServer_authenticate_Params{Struct: s}) }\n\t}\n\treturn TunnelServer_authenticate_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\nfunc (c TunnelServer) ReconnectTunnel(ctx context.Context, params func(TunnelServer_reconnectTunnel_Params) error, opts ...capnp.CallOption) TunnelServer_reconnectTunnel_Results_Promise {\n\tif c.Client == nil {\n\t\treturn TunnelServer_reconnectTunnel_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xea58385c65416035,\n\t\t\tMethodID:      5,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:TunnelServer\",\n\t\t\tMethodName:    \"reconnectTunnel\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 0, PointerCount: 5}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error { return params(TunnelServer_reconnectTunnel_Params{Struct: s}) }\n\t}\n\treturn TunnelServer_reconnectTunnel_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\nfunc (c TunnelServer) RegisterConnection(ctx context.Context, params func(RegistrationServer_registerConnection_Params) error, opts ...capnp.CallOption) RegistrationServer_registerConnection_Results_Promise {\n\tif c.Client == nil {\n\t\treturn RegistrationServer_registerConnection_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xf71695ec7fe85497,\n\t\t\tMethodID:      0,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:RegistrationServer\",\n\t\t\tMethodName:    \"registerConnection\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 8, PointerCount: 3}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error { return params(RegistrationServer_registerConnection_Params{Struct: s}) }\n\t}\n\treturn RegistrationServer_registerConnection_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\nfunc (c TunnelServer) UnregisterConnection(ctx context.Context, params func(RegistrationServer_unregisterConnection_Params) error, opts ...capnp.CallOption) RegistrationServer_unregisterConnection_Results_Promise {\n\tif c.Client == nil {\n\t\treturn RegistrationServer_unregisterConnection_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xf71695ec7fe85497,\n\t\t\tMethodID:      1,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:RegistrationServer\",\n\t\t\tMethodName:    \"unregisterConnection\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 0, PointerCount: 0}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error { return params(RegistrationServer_unregisterConnection_Params{Struct: s}) }\n\t}\n\treturn RegistrationServer_unregisterConnection_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\nfunc (c TunnelServer) UpdateLocalConfiguration(ctx context.Context, params func(RegistrationServer_updateLocalConfiguration_Params) error, opts ...capnp.CallOption) RegistrationServer_updateLocalConfiguration_Results_Promise {\n\tif c.Client == nil {\n\t\treturn RegistrationServer_updateLocalConfiguration_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xf71695ec7fe85497,\n\t\t\tMethodID:      2,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:RegistrationServer\",\n\t\t\tMethodName:    \"updateLocalConfiguration\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 0, PointerCount: 1}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error {\n\t\t\treturn params(RegistrationServer_updateLocalConfiguration_Params{Struct: s})\n\t\t}\n\t}\n\treturn RegistrationServer_updateLocalConfiguration_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\n\ntype TunnelServer_Server interface {\n\tRegisterTunnel(TunnelServer_registerTunnel) error\n\n\tGetServerInfo(TunnelServer_getServerInfo) error\n\n\tUnregisterTunnel(TunnelServer_unregisterTunnel) error\n\n\tObsoleteDeclarativeTunnelConnect(TunnelServer_obsoleteDeclarativeTunnelConnect) error\n\n\tAuthenticate(TunnelServer_authenticate) error\n\n\tReconnectTunnel(TunnelServer_reconnectTunnel) error\n\n\tRegisterConnection(RegistrationServer_registerConnection) error\n\n\tUnregisterConnection(RegistrationServer_unregisterConnection) error\n\n\tUpdateLocalConfiguration(RegistrationServer_updateLocalConfiguration) error\n}\n\nfunc TunnelServer_ServerToClient(s TunnelServer_Server) TunnelServer {\n\tc, _ := s.(server.Closer)\n\treturn TunnelServer{Client: server.New(TunnelServer_Methods(nil, s), c)}\n}\n\nfunc TunnelServer_Methods(methods []server.Method, s TunnelServer_Server) []server.Method {\n\tif cap(methods) == 0 {\n\t\tmethods = make([]server.Method, 0, 9)\n\t}\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xea58385c65416035,\n\t\t\tMethodID:      0,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:TunnelServer\",\n\t\t\tMethodName:    \"registerTunnel\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := TunnelServer_registerTunnel{c, opts, TunnelServer_registerTunnel_Params{Struct: p}, TunnelServer_registerTunnel_Results{Struct: r}}\n\t\t\treturn s.RegisterTunnel(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 1},\n\t})\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xea58385c65416035,\n\t\t\tMethodID:      1,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:TunnelServer\",\n\t\t\tMethodName:    \"getServerInfo\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := TunnelServer_getServerInfo{c, opts, TunnelServer_getServerInfo_Params{Struct: p}, TunnelServer_getServerInfo_Results{Struct: r}}\n\t\t\treturn s.GetServerInfo(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 1},\n\t})\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xea58385c65416035,\n\t\t\tMethodID:      2,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:TunnelServer\",\n\t\t\tMethodName:    \"unregisterTunnel\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := TunnelServer_unregisterTunnel{c, opts, TunnelServer_unregisterTunnel_Params{Struct: p}, TunnelServer_unregisterTunnel_Results{Struct: r}}\n\t\t\treturn s.UnregisterTunnel(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 0},\n\t})\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xea58385c65416035,\n\t\t\tMethodID:      3,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:TunnelServer\",\n\t\t\tMethodName:    \"obsoleteDeclarativeTunnelConnect\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := TunnelServer_obsoleteDeclarativeTunnelConnect{c, opts, TunnelServer_obsoleteDeclarativeTunnelConnect_Params{Struct: p}, TunnelServer_obsoleteDeclarativeTunnelConnect_Results{Struct: r}}\n\t\t\treturn s.ObsoleteDeclarativeTunnelConnect(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 0},\n\t})\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xea58385c65416035,\n\t\t\tMethodID:      4,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:TunnelServer\",\n\t\t\tMethodName:    \"authenticate\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := TunnelServer_authenticate{c, opts, TunnelServer_authenticate_Params{Struct: p}, TunnelServer_authenticate_Results{Struct: r}}\n\t\t\treturn s.Authenticate(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 1},\n\t})\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xea58385c65416035,\n\t\t\tMethodID:      5,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:TunnelServer\",\n\t\t\tMethodName:    \"reconnectTunnel\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := TunnelServer_reconnectTunnel{c, opts, TunnelServer_reconnectTunnel_Params{Struct: p}, TunnelServer_reconnectTunnel_Results{Struct: r}}\n\t\t\treturn s.ReconnectTunnel(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 1},\n\t})\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xf71695ec7fe85497,\n\t\t\tMethodID:      0,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:RegistrationServer\",\n\t\t\tMethodName:    \"registerConnection\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := RegistrationServer_registerConnection{c, opts, RegistrationServer_registerConnection_Params{Struct: p}, RegistrationServer_registerConnection_Results{Struct: r}}\n\t\t\treturn s.RegisterConnection(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 1},\n\t})\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xf71695ec7fe85497,\n\t\t\tMethodID:      1,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:RegistrationServer\",\n\t\t\tMethodName:    \"unregisterConnection\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := RegistrationServer_unregisterConnection{c, opts, RegistrationServer_unregisterConnection_Params{Struct: p}, RegistrationServer_unregisterConnection_Results{Struct: r}}\n\t\t\treturn s.UnregisterConnection(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 0},\n\t})\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xf71695ec7fe85497,\n\t\t\tMethodID:      2,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:RegistrationServer\",\n\t\t\tMethodName:    \"updateLocalConfiguration\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := RegistrationServer_updateLocalConfiguration{c, opts, RegistrationServer_updateLocalConfiguration_Params{Struct: p}, RegistrationServer_updateLocalConfiguration_Results{Struct: r}}\n\t\t\treturn s.UpdateLocalConfiguration(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 0},\n\t})\n\n\treturn methods\n}\n\n// TunnelServer_registerTunnel holds the arguments for a server call to TunnelServer.registerTunnel.\ntype TunnelServer_registerTunnel struct {\n\tCtx     context.Context\n\tOptions capnp.CallOptions\n\tParams  TunnelServer_registerTunnel_Params\n\tResults TunnelServer_registerTunnel_Results\n}\n\n// TunnelServer_getServerInfo holds the arguments for a server call to TunnelServer.getServerInfo.\ntype TunnelServer_getServerInfo struct {\n\tCtx     context.Context\n\tOptions capnp.CallOptions\n\tParams  TunnelServer_getServerInfo_Params\n\tResults TunnelServer_getServerInfo_Results\n}\n\n// TunnelServer_unregisterTunnel holds the arguments for a server call to TunnelServer.unregisterTunnel.\ntype TunnelServer_unregisterTunnel struct {\n\tCtx     context.Context\n\tOptions capnp.CallOptions\n\tParams  TunnelServer_unregisterTunnel_Params\n\tResults TunnelServer_unregisterTunnel_Results\n}\n\n// TunnelServer_obsoleteDeclarativeTunnelConnect holds the arguments for a server call to TunnelServer.obsoleteDeclarativeTunnelConnect.\ntype TunnelServer_obsoleteDeclarativeTunnelConnect struct {\n\tCtx     context.Context\n\tOptions capnp.CallOptions\n\tParams  TunnelServer_obsoleteDeclarativeTunnelConnect_Params\n\tResults TunnelServer_obsoleteDeclarativeTunnelConnect_Results\n}\n\n// TunnelServer_authenticate holds the arguments for a server call to TunnelServer.authenticate.\ntype TunnelServer_authenticate struct {\n\tCtx     context.Context\n\tOptions capnp.CallOptions\n\tParams  TunnelServer_authenticate_Params\n\tResults TunnelServer_authenticate_Results\n}\n\n// TunnelServer_reconnectTunnel holds the arguments for a server call to TunnelServer.reconnectTunnel.\ntype TunnelServer_reconnectTunnel struct {\n\tCtx     context.Context\n\tOptions capnp.CallOptions\n\tParams  TunnelServer_reconnectTunnel_Params\n\tResults TunnelServer_reconnectTunnel_Results\n}\n\ntype TunnelServer_registerTunnel_Params struct{ capnp.Struct }\n\n// TunnelServer_registerTunnel_Params_TypeID is the unique identifier for the type TunnelServer_registerTunnel_Params.\nconst TunnelServer_registerTunnel_Params_TypeID = 0xb70431c0dc014915\n\nfunc NewTunnelServer_registerTunnel_Params(s *capnp.Segment) (TunnelServer_registerTunnel_Params, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3})\n\treturn TunnelServer_registerTunnel_Params{st}, err\n}\n\nfunc NewRootTunnelServer_registerTunnel_Params(s *capnp.Segment) (TunnelServer_registerTunnel_Params, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3})\n\treturn TunnelServer_registerTunnel_Params{st}, err\n}\n\nfunc ReadRootTunnelServer_registerTunnel_Params(msg *capnp.Message) (TunnelServer_registerTunnel_Params, error) {\n\troot, err := msg.RootPtr()\n\treturn TunnelServer_registerTunnel_Params{root.Struct()}, err\n}\n\nfunc (s TunnelServer_registerTunnel_Params) String() string {\n\tstr, _ := text.Marshal(0xb70431c0dc014915, s.Struct)\n\treturn str\n}\n\nfunc (s TunnelServer_registerTunnel_Params) OriginCert() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s TunnelServer_registerTunnel_Params) HasOriginCert() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelServer_registerTunnel_Params) SetOriginCert(v []byte) error {\n\treturn s.Struct.SetData(0, v)\n}\n\nfunc (s TunnelServer_registerTunnel_Params) Hostname() (string, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.Text(), err\n}\n\nfunc (s TunnelServer_registerTunnel_Params) HasHostname() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelServer_registerTunnel_Params) HostnameBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.TextBytes(), err\n}\n\nfunc (s TunnelServer_registerTunnel_Params) SetHostname(v string) error {\n\treturn s.Struct.SetText(1, v)\n}\n\nfunc (s TunnelServer_registerTunnel_Params) Options() (RegistrationOptions, error) {\n\tp, err := s.Struct.Ptr(2)\n\treturn RegistrationOptions{Struct: p.Struct()}, err\n}\n\nfunc (s TunnelServer_registerTunnel_Params) HasOptions() bool {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelServer_registerTunnel_Params) SetOptions(v RegistrationOptions) error {\n\treturn s.Struct.SetPtr(2, v.Struct.ToPtr())\n}\n\n// NewOptions sets the options field to a newly\n// allocated RegistrationOptions struct, preferring placement in s's segment.\nfunc (s TunnelServer_registerTunnel_Params) NewOptions() (RegistrationOptions, error) {\n\tss, err := NewRegistrationOptions(s.Struct.Segment())\n\tif err != nil {\n\t\treturn RegistrationOptions{}, err\n\t}\n\terr = s.Struct.SetPtr(2, ss.Struct.ToPtr())\n\treturn ss, err\n}\n\n// TunnelServer_registerTunnel_Params_List is a list of TunnelServer_registerTunnel_Params.\ntype TunnelServer_registerTunnel_Params_List struct{ capnp.List }\n\n// NewTunnelServer_registerTunnel_Params creates a new list of TunnelServer_registerTunnel_Params.\nfunc NewTunnelServer_registerTunnel_Params_List(s *capnp.Segment, sz int32) (TunnelServer_registerTunnel_Params_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3}, sz)\n\treturn TunnelServer_registerTunnel_Params_List{l}, err\n}\n\nfunc (s TunnelServer_registerTunnel_Params_List) At(i int) TunnelServer_registerTunnel_Params {\n\treturn TunnelServer_registerTunnel_Params{s.List.Struct(i)}\n}\n\nfunc (s TunnelServer_registerTunnel_Params_List) Set(i int, v TunnelServer_registerTunnel_Params) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s TunnelServer_registerTunnel_Params_List) String() string {\n\tstr, _ := text.MarshalList(0xb70431c0dc014915, s.List)\n\treturn str\n}\n\n// TunnelServer_registerTunnel_Params_Promise is a wrapper for a TunnelServer_registerTunnel_Params promised by a client call.\ntype TunnelServer_registerTunnel_Params_Promise struct{ *capnp.Pipeline }\n\nfunc (p TunnelServer_registerTunnel_Params_Promise) Struct() (TunnelServer_registerTunnel_Params, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn TunnelServer_registerTunnel_Params{s}, err\n}\n\nfunc (p TunnelServer_registerTunnel_Params_Promise) Options() RegistrationOptions_Promise {\n\treturn RegistrationOptions_Promise{Pipeline: p.Pipeline.GetPipeline(2)}\n}\n\ntype TunnelServer_registerTunnel_Results struct{ capnp.Struct }\n\n// TunnelServer_registerTunnel_Results_TypeID is the unique identifier for the type TunnelServer_registerTunnel_Results.\nconst TunnelServer_registerTunnel_Results_TypeID = 0xf2c122394f447e8e\n\nfunc NewTunnelServer_registerTunnel_Results(s *capnp.Segment) (TunnelServer_registerTunnel_Results, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn TunnelServer_registerTunnel_Results{st}, err\n}\n\nfunc NewRootTunnelServer_registerTunnel_Results(s *capnp.Segment) (TunnelServer_registerTunnel_Results, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn TunnelServer_registerTunnel_Results{st}, err\n}\n\nfunc ReadRootTunnelServer_registerTunnel_Results(msg *capnp.Message) (TunnelServer_registerTunnel_Results, error) {\n\troot, err := msg.RootPtr()\n\treturn TunnelServer_registerTunnel_Results{root.Struct()}, err\n}\n\nfunc (s TunnelServer_registerTunnel_Results) String() string {\n\tstr, _ := text.Marshal(0xf2c122394f447e8e, s.Struct)\n\treturn str\n}\n\nfunc (s TunnelServer_registerTunnel_Results) Result() (TunnelRegistration, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn TunnelRegistration{Struct: p.Struct()}, err\n}\n\nfunc (s TunnelServer_registerTunnel_Results) HasResult() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelServer_registerTunnel_Results) SetResult(v TunnelRegistration) error {\n\treturn s.Struct.SetPtr(0, v.Struct.ToPtr())\n}\n\n// NewResult sets the result field to a newly\n// allocated TunnelRegistration struct, preferring placement in s's segment.\nfunc (s TunnelServer_registerTunnel_Results) NewResult() (TunnelRegistration, error) {\n\tss, err := NewTunnelRegistration(s.Struct.Segment())\n\tif err != nil {\n\t\treturn TunnelRegistration{}, err\n\t}\n\terr = s.Struct.SetPtr(0, ss.Struct.ToPtr())\n\treturn ss, err\n}\n\n// TunnelServer_registerTunnel_Results_List is a list of TunnelServer_registerTunnel_Results.\ntype TunnelServer_registerTunnel_Results_List struct{ capnp.List }\n\n// NewTunnelServer_registerTunnel_Results creates a new list of TunnelServer_registerTunnel_Results.\nfunc NewTunnelServer_registerTunnel_Results_List(s *capnp.Segment, sz int32) (TunnelServer_registerTunnel_Results_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz)\n\treturn TunnelServer_registerTunnel_Results_List{l}, err\n}\n\nfunc (s TunnelServer_registerTunnel_Results_List) At(i int) TunnelServer_registerTunnel_Results {\n\treturn TunnelServer_registerTunnel_Results{s.List.Struct(i)}\n}\n\nfunc (s TunnelServer_registerTunnel_Results_List) Set(i int, v TunnelServer_registerTunnel_Results) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s TunnelServer_registerTunnel_Results_List) String() string {\n\tstr, _ := text.MarshalList(0xf2c122394f447e8e, s.List)\n\treturn str\n}\n\n// TunnelServer_registerTunnel_Results_Promise is a wrapper for a TunnelServer_registerTunnel_Results promised by a client call.\ntype TunnelServer_registerTunnel_Results_Promise struct{ *capnp.Pipeline }\n\nfunc (p TunnelServer_registerTunnel_Results_Promise) Struct() (TunnelServer_registerTunnel_Results, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn TunnelServer_registerTunnel_Results{s}, err\n}\n\nfunc (p TunnelServer_registerTunnel_Results_Promise) Result() TunnelRegistration_Promise {\n\treturn TunnelRegistration_Promise{Pipeline: p.Pipeline.GetPipeline(0)}\n}\n\ntype TunnelServer_getServerInfo_Params struct{ capnp.Struct }\n\n// TunnelServer_getServerInfo_Params_TypeID is the unique identifier for the type TunnelServer_getServerInfo_Params.\nconst TunnelServer_getServerInfo_Params_TypeID = 0xdc3ed6801961e502\n\nfunc NewTunnelServer_getServerInfo_Params(s *capnp.Segment) (TunnelServer_getServerInfo_Params, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})\n\treturn TunnelServer_getServerInfo_Params{st}, err\n}\n\nfunc NewRootTunnelServer_getServerInfo_Params(s *capnp.Segment) (TunnelServer_getServerInfo_Params, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})\n\treturn TunnelServer_getServerInfo_Params{st}, err\n}\n\nfunc ReadRootTunnelServer_getServerInfo_Params(msg *capnp.Message) (TunnelServer_getServerInfo_Params, error) {\n\troot, err := msg.RootPtr()\n\treturn TunnelServer_getServerInfo_Params{root.Struct()}, err\n}\n\nfunc (s TunnelServer_getServerInfo_Params) String() string {\n\tstr, _ := text.Marshal(0xdc3ed6801961e502, s.Struct)\n\treturn str\n}\n\n// TunnelServer_getServerInfo_Params_List is a list of TunnelServer_getServerInfo_Params.\ntype TunnelServer_getServerInfo_Params_List struct{ capnp.List }\n\n// NewTunnelServer_getServerInfo_Params creates a new list of TunnelServer_getServerInfo_Params.\nfunc NewTunnelServer_getServerInfo_Params_List(s *capnp.Segment, sz int32) (TunnelServer_getServerInfo_Params_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0}, sz)\n\treturn TunnelServer_getServerInfo_Params_List{l}, err\n}\n\nfunc (s TunnelServer_getServerInfo_Params_List) At(i int) TunnelServer_getServerInfo_Params {\n\treturn TunnelServer_getServerInfo_Params{s.List.Struct(i)}\n}\n\nfunc (s TunnelServer_getServerInfo_Params_List) Set(i int, v TunnelServer_getServerInfo_Params) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s TunnelServer_getServerInfo_Params_List) String() string {\n\tstr, _ := text.MarshalList(0xdc3ed6801961e502, s.List)\n\treturn str\n}\n\n// TunnelServer_getServerInfo_Params_Promise is a wrapper for a TunnelServer_getServerInfo_Params promised by a client call.\ntype TunnelServer_getServerInfo_Params_Promise struct{ *capnp.Pipeline }\n\nfunc (p TunnelServer_getServerInfo_Params_Promise) Struct() (TunnelServer_getServerInfo_Params, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn TunnelServer_getServerInfo_Params{s}, err\n}\n\ntype TunnelServer_getServerInfo_Results struct{ capnp.Struct }\n\n// TunnelServer_getServerInfo_Results_TypeID is the unique identifier for the type TunnelServer_getServerInfo_Results.\nconst TunnelServer_getServerInfo_Results_TypeID = 0xe3e37d096a5b564e\n\nfunc NewTunnelServer_getServerInfo_Results(s *capnp.Segment) (TunnelServer_getServerInfo_Results, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn TunnelServer_getServerInfo_Results{st}, err\n}\n\nfunc NewRootTunnelServer_getServerInfo_Results(s *capnp.Segment) (TunnelServer_getServerInfo_Results, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn TunnelServer_getServerInfo_Results{st}, err\n}\n\nfunc ReadRootTunnelServer_getServerInfo_Results(msg *capnp.Message) (TunnelServer_getServerInfo_Results, error) {\n\troot, err := msg.RootPtr()\n\treturn TunnelServer_getServerInfo_Results{root.Struct()}, err\n}\n\nfunc (s TunnelServer_getServerInfo_Results) String() string {\n\tstr, _ := text.Marshal(0xe3e37d096a5b564e, s.Struct)\n\treturn str\n}\n\nfunc (s TunnelServer_getServerInfo_Results) Result() (ServerInfo, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn ServerInfo{Struct: p.Struct()}, err\n}\n\nfunc (s TunnelServer_getServerInfo_Results) HasResult() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelServer_getServerInfo_Results) SetResult(v ServerInfo) error {\n\treturn s.Struct.SetPtr(0, v.Struct.ToPtr())\n}\n\n// NewResult sets the result field to a newly\n// allocated ServerInfo struct, preferring placement in s's segment.\nfunc (s TunnelServer_getServerInfo_Results) NewResult() (ServerInfo, error) {\n\tss, err := NewServerInfo(s.Struct.Segment())\n\tif err != nil {\n\t\treturn ServerInfo{}, err\n\t}\n\terr = s.Struct.SetPtr(0, ss.Struct.ToPtr())\n\treturn ss, err\n}\n\n// TunnelServer_getServerInfo_Results_List is a list of TunnelServer_getServerInfo_Results.\ntype TunnelServer_getServerInfo_Results_List struct{ capnp.List }\n\n// NewTunnelServer_getServerInfo_Results creates a new list of TunnelServer_getServerInfo_Results.\nfunc NewTunnelServer_getServerInfo_Results_List(s *capnp.Segment, sz int32) (TunnelServer_getServerInfo_Results_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz)\n\treturn TunnelServer_getServerInfo_Results_List{l}, err\n}\n\nfunc (s TunnelServer_getServerInfo_Results_List) At(i int) TunnelServer_getServerInfo_Results {\n\treturn TunnelServer_getServerInfo_Results{s.List.Struct(i)}\n}\n\nfunc (s TunnelServer_getServerInfo_Results_List) Set(i int, v TunnelServer_getServerInfo_Results) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s TunnelServer_getServerInfo_Results_List) String() string {\n\tstr, _ := text.MarshalList(0xe3e37d096a5b564e, s.List)\n\treturn str\n}\n\n// TunnelServer_getServerInfo_Results_Promise is a wrapper for a TunnelServer_getServerInfo_Results promised by a client call.\ntype TunnelServer_getServerInfo_Results_Promise struct{ *capnp.Pipeline }\n\nfunc (p TunnelServer_getServerInfo_Results_Promise) Struct() (TunnelServer_getServerInfo_Results, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn TunnelServer_getServerInfo_Results{s}, err\n}\n\nfunc (p TunnelServer_getServerInfo_Results_Promise) Result() ServerInfo_Promise {\n\treturn ServerInfo_Promise{Pipeline: p.Pipeline.GetPipeline(0)}\n}\n\ntype TunnelServer_unregisterTunnel_Params struct{ capnp.Struct }\n\n// TunnelServer_unregisterTunnel_Params_TypeID is the unique identifier for the type TunnelServer_unregisterTunnel_Params.\nconst TunnelServer_unregisterTunnel_Params_TypeID = 0x9b87b390babc2ccf\n\nfunc NewTunnelServer_unregisterTunnel_Params(s *capnp.Segment) (TunnelServer_unregisterTunnel_Params, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0})\n\treturn TunnelServer_unregisterTunnel_Params{st}, err\n}\n\nfunc NewRootTunnelServer_unregisterTunnel_Params(s *capnp.Segment) (TunnelServer_unregisterTunnel_Params, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0})\n\treturn TunnelServer_unregisterTunnel_Params{st}, err\n}\n\nfunc ReadRootTunnelServer_unregisterTunnel_Params(msg *capnp.Message) (TunnelServer_unregisterTunnel_Params, error) {\n\troot, err := msg.RootPtr()\n\treturn TunnelServer_unregisterTunnel_Params{root.Struct()}, err\n}\n\nfunc (s TunnelServer_unregisterTunnel_Params) String() string {\n\tstr, _ := text.Marshal(0x9b87b390babc2ccf, s.Struct)\n\treturn str\n}\n\nfunc (s TunnelServer_unregisterTunnel_Params) GracePeriodNanoSec() int64 {\n\treturn int64(s.Struct.Uint64(0))\n}\n\nfunc (s TunnelServer_unregisterTunnel_Params) SetGracePeriodNanoSec(v int64) {\n\ts.Struct.SetUint64(0, uint64(v))\n}\n\n// TunnelServer_unregisterTunnel_Params_List is a list of TunnelServer_unregisterTunnel_Params.\ntype TunnelServer_unregisterTunnel_Params_List struct{ capnp.List }\n\n// NewTunnelServer_unregisterTunnel_Params creates a new list of TunnelServer_unregisterTunnel_Params.\nfunc NewTunnelServer_unregisterTunnel_Params_List(s *capnp.Segment, sz int32) (TunnelServer_unregisterTunnel_Params_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0}, sz)\n\treturn TunnelServer_unregisterTunnel_Params_List{l}, err\n}\n\nfunc (s TunnelServer_unregisterTunnel_Params_List) At(i int) TunnelServer_unregisterTunnel_Params {\n\treturn TunnelServer_unregisterTunnel_Params{s.List.Struct(i)}\n}\n\nfunc (s TunnelServer_unregisterTunnel_Params_List) Set(i int, v TunnelServer_unregisterTunnel_Params) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s TunnelServer_unregisterTunnel_Params_List) String() string {\n\tstr, _ := text.MarshalList(0x9b87b390babc2ccf, s.List)\n\treturn str\n}\n\n// TunnelServer_unregisterTunnel_Params_Promise is a wrapper for a TunnelServer_unregisterTunnel_Params promised by a client call.\ntype TunnelServer_unregisterTunnel_Params_Promise struct{ *capnp.Pipeline }\n\nfunc (p TunnelServer_unregisterTunnel_Params_Promise) Struct() (TunnelServer_unregisterTunnel_Params, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn TunnelServer_unregisterTunnel_Params{s}, err\n}\n\ntype TunnelServer_unregisterTunnel_Results struct{ capnp.Struct }\n\n// TunnelServer_unregisterTunnel_Results_TypeID is the unique identifier for the type TunnelServer_unregisterTunnel_Results.\nconst TunnelServer_unregisterTunnel_Results_TypeID = 0xa29a916d4ebdd894\n\nfunc NewTunnelServer_unregisterTunnel_Results(s *capnp.Segment) (TunnelServer_unregisterTunnel_Results, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})\n\treturn TunnelServer_unregisterTunnel_Results{st}, err\n}\n\nfunc NewRootTunnelServer_unregisterTunnel_Results(s *capnp.Segment) (TunnelServer_unregisterTunnel_Results, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})\n\treturn TunnelServer_unregisterTunnel_Results{st}, err\n}\n\nfunc ReadRootTunnelServer_unregisterTunnel_Results(msg *capnp.Message) (TunnelServer_unregisterTunnel_Results, error) {\n\troot, err := msg.RootPtr()\n\treturn TunnelServer_unregisterTunnel_Results{root.Struct()}, err\n}\n\nfunc (s TunnelServer_unregisterTunnel_Results) String() string {\n\tstr, _ := text.Marshal(0xa29a916d4ebdd894, s.Struct)\n\treturn str\n}\n\n// TunnelServer_unregisterTunnel_Results_List is a list of TunnelServer_unregisterTunnel_Results.\ntype TunnelServer_unregisterTunnel_Results_List struct{ capnp.List }\n\n// NewTunnelServer_unregisterTunnel_Results creates a new list of TunnelServer_unregisterTunnel_Results.\nfunc NewTunnelServer_unregisterTunnel_Results_List(s *capnp.Segment, sz int32) (TunnelServer_unregisterTunnel_Results_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0}, sz)\n\treturn TunnelServer_unregisterTunnel_Results_List{l}, err\n}\n\nfunc (s TunnelServer_unregisterTunnel_Results_List) At(i int) TunnelServer_unregisterTunnel_Results {\n\treturn TunnelServer_unregisterTunnel_Results{s.List.Struct(i)}\n}\n\nfunc (s TunnelServer_unregisterTunnel_Results_List) Set(i int, v TunnelServer_unregisterTunnel_Results) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s TunnelServer_unregisterTunnel_Results_List) String() string {\n\tstr, _ := text.MarshalList(0xa29a916d4ebdd894, s.List)\n\treturn str\n}\n\n// TunnelServer_unregisterTunnel_Results_Promise is a wrapper for a TunnelServer_unregisterTunnel_Results promised by a client call.\ntype TunnelServer_unregisterTunnel_Results_Promise struct{ *capnp.Pipeline }\n\nfunc (p TunnelServer_unregisterTunnel_Results_Promise) Struct() (TunnelServer_unregisterTunnel_Results, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn TunnelServer_unregisterTunnel_Results{s}, err\n}\n\ntype TunnelServer_obsoleteDeclarativeTunnelConnect_Params struct{ capnp.Struct }\n\n// TunnelServer_obsoleteDeclarativeTunnelConnect_Params_TypeID is the unique identifier for the type TunnelServer_obsoleteDeclarativeTunnelConnect_Params.\nconst TunnelServer_obsoleteDeclarativeTunnelConnect_Params_TypeID = 0xa766b24d4fe5da35\n\nfunc NewTunnelServer_obsoleteDeclarativeTunnelConnect_Params(s *capnp.Segment) (TunnelServer_obsoleteDeclarativeTunnelConnect_Params, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})\n\treturn TunnelServer_obsoleteDeclarativeTunnelConnect_Params{st}, err\n}\n\nfunc NewRootTunnelServer_obsoleteDeclarativeTunnelConnect_Params(s *capnp.Segment) (TunnelServer_obsoleteDeclarativeTunnelConnect_Params, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})\n\treturn TunnelServer_obsoleteDeclarativeTunnelConnect_Params{st}, err\n}\n\nfunc ReadRootTunnelServer_obsoleteDeclarativeTunnelConnect_Params(msg *capnp.Message) (TunnelServer_obsoleteDeclarativeTunnelConnect_Params, error) {\n\troot, err := msg.RootPtr()\n\treturn TunnelServer_obsoleteDeclarativeTunnelConnect_Params{root.Struct()}, err\n}\n\nfunc (s TunnelServer_obsoleteDeclarativeTunnelConnect_Params) String() string {\n\tstr, _ := text.Marshal(0xa766b24d4fe5da35, s.Struct)\n\treturn str\n}\n\n// TunnelServer_obsoleteDeclarativeTunnelConnect_Params_List is a list of TunnelServer_obsoleteDeclarativeTunnelConnect_Params.\ntype TunnelServer_obsoleteDeclarativeTunnelConnect_Params_List struct{ capnp.List }\n\n// NewTunnelServer_obsoleteDeclarativeTunnelConnect_Params creates a new list of TunnelServer_obsoleteDeclarativeTunnelConnect_Params.\nfunc NewTunnelServer_obsoleteDeclarativeTunnelConnect_Params_List(s *capnp.Segment, sz int32) (TunnelServer_obsoleteDeclarativeTunnelConnect_Params_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0}, sz)\n\treturn TunnelServer_obsoleteDeclarativeTunnelConnect_Params_List{l}, err\n}\n\nfunc (s TunnelServer_obsoleteDeclarativeTunnelConnect_Params_List) At(i int) TunnelServer_obsoleteDeclarativeTunnelConnect_Params {\n\treturn TunnelServer_obsoleteDeclarativeTunnelConnect_Params{s.List.Struct(i)}\n}\n\nfunc (s TunnelServer_obsoleteDeclarativeTunnelConnect_Params_List) Set(i int, v TunnelServer_obsoleteDeclarativeTunnelConnect_Params) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s TunnelServer_obsoleteDeclarativeTunnelConnect_Params_List) String() string {\n\tstr, _ := text.MarshalList(0xa766b24d4fe5da35, s.List)\n\treturn str\n}\n\n// TunnelServer_obsoleteDeclarativeTunnelConnect_Params_Promise is a wrapper for a TunnelServer_obsoleteDeclarativeTunnelConnect_Params promised by a client call.\ntype TunnelServer_obsoleteDeclarativeTunnelConnect_Params_Promise struct{ *capnp.Pipeline }\n\nfunc (p TunnelServer_obsoleteDeclarativeTunnelConnect_Params_Promise) Struct() (TunnelServer_obsoleteDeclarativeTunnelConnect_Params, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn TunnelServer_obsoleteDeclarativeTunnelConnect_Params{s}, err\n}\n\ntype TunnelServer_obsoleteDeclarativeTunnelConnect_Results struct{ capnp.Struct }\n\n// TunnelServer_obsoleteDeclarativeTunnelConnect_Results_TypeID is the unique identifier for the type TunnelServer_obsoleteDeclarativeTunnelConnect_Results.\nconst TunnelServer_obsoleteDeclarativeTunnelConnect_Results_TypeID = 0xfeac5c8f4899ef7c\n\nfunc NewTunnelServer_obsoleteDeclarativeTunnelConnect_Results(s *capnp.Segment) (TunnelServer_obsoleteDeclarativeTunnelConnect_Results, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})\n\treturn TunnelServer_obsoleteDeclarativeTunnelConnect_Results{st}, err\n}\n\nfunc NewRootTunnelServer_obsoleteDeclarativeTunnelConnect_Results(s *capnp.Segment) (TunnelServer_obsoleteDeclarativeTunnelConnect_Results, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})\n\treturn TunnelServer_obsoleteDeclarativeTunnelConnect_Results{st}, err\n}\n\nfunc ReadRootTunnelServer_obsoleteDeclarativeTunnelConnect_Results(msg *capnp.Message) (TunnelServer_obsoleteDeclarativeTunnelConnect_Results, error) {\n\troot, err := msg.RootPtr()\n\treturn TunnelServer_obsoleteDeclarativeTunnelConnect_Results{root.Struct()}, err\n}\n\nfunc (s TunnelServer_obsoleteDeclarativeTunnelConnect_Results) String() string {\n\tstr, _ := text.Marshal(0xfeac5c8f4899ef7c, s.Struct)\n\treturn str\n}\n\n// TunnelServer_obsoleteDeclarativeTunnelConnect_Results_List is a list of TunnelServer_obsoleteDeclarativeTunnelConnect_Results.\ntype TunnelServer_obsoleteDeclarativeTunnelConnect_Results_List struct{ capnp.List }\n\n// NewTunnelServer_obsoleteDeclarativeTunnelConnect_Results creates a new list of TunnelServer_obsoleteDeclarativeTunnelConnect_Results.\nfunc NewTunnelServer_obsoleteDeclarativeTunnelConnect_Results_List(s *capnp.Segment, sz int32) (TunnelServer_obsoleteDeclarativeTunnelConnect_Results_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0}, sz)\n\treturn TunnelServer_obsoleteDeclarativeTunnelConnect_Results_List{l}, err\n}\n\nfunc (s TunnelServer_obsoleteDeclarativeTunnelConnect_Results_List) At(i int) TunnelServer_obsoleteDeclarativeTunnelConnect_Results {\n\treturn TunnelServer_obsoleteDeclarativeTunnelConnect_Results{s.List.Struct(i)}\n}\n\nfunc (s TunnelServer_obsoleteDeclarativeTunnelConnect_Results_List) Set(i int, v TunnelServer_obsoleteDeclarativeTunnelConnect_Results) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s TunnelServer_obsoleteDeclarativeTunnelConnect_Results_List) String() string {\n\tstr, _ := text.MarshalList(0xfeac5c8f4899ef7c, s.List)\n\treturn str\n}\n\n// TunnelServer_obsoleteDeclarativeTunnelConnect_Results_Promise is a wrapper for a TunnelServer_obsoleteDeclarativeTunnelConnect_Results promised by a client call.\ntype TunnelServer_obsoleteDeclarativeTunnelConnect_Results_Promise struct{ *capnp.Pipeline }\n\nfunc (p TunnelServer_obsoleteDeclarativeTunnelConnect_Results_Promise) Struct() (TunnelServer_obsoleteDeclarativeTunnelConnect_Results, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn TunnelServer_obsoleteDeclarativeTunnelConnect_Results{s}, err\n}\n\ntype TunnelServer_authenticate_Params struct{ capnp.Struct }\n\n// TunnelServer_authenticate_Params_TypeID is the unique identifier for the type TunnelServer_authenticate_Params.\nconst TunnelServer_authenticate_Params_TypeID = 0x85c8cea1ab1894f3\n\nfunc NewTunnelServer_authenticate_Params(s *capnp.Segment) (TunnelServer_authenticate_Params, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3})\n\treturn TunnelServer_authenticate_Params{st}, err\n}\n\nfunc NewRootTunnelServer_authenticate_Params(s *capnp.Segment) (TunnelServer_authenticate_Params, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3})\n\treturn TunnelServer_authenticate_Params{st}, err\n}\n\nfunc ReadRootTunnelServer_authenticate_Params(msg *capnp.Message) (TunnelServer_authenticate_Params, error) {\n\troot, err := msg.RootPtr()\n\treturn TunnelServer_authenticate_Params{root.Struct()}, err\n}\n\nfunc (s TunnelServer_authenticate_Params) String() string {\n\tstr, _ := text.Marshal(0x85c8cea1ab1894f3, s.Struct)\n\treturn str\n}\n\nfunc (s TunnelServer_authenticate_Params) OriginCert() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s TunnelServer_authenticate_Params) HasOriginCert() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelServer_authenticate_Params) SetOriginCert(v []byte) error {\n\treturn s.Struct.SetData(0, v)\n}\n\nfunc (s TunnelServer_authenticate_Params) Hostname() (string, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.Text(), err\n}\n\nfunc (s TunnelServer_authenticate_Params) HasHostname() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelServer_authenticate_Params) HostnameBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.TextBytes(), err\n}\n\nfunc (s TunnelServer_authenticate_Params) SetHostname(v string) error {\n\treturn s.Struct.SetText(1, v)\n}\n\nfunc (s TunnelServer_authenticate_Params) Options() (RegistrationOptions, error) {\n\tp, err := s.Struct.Ptr(2)\n\treturn RegistrationOptions{Struct: p.Struct()}, err\n}\n\nfunc (s TunnelServer_authenticate_Params) HasOptions() bool {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelServer_authenticate_Params) SetOptions(v RegistrationOptions) error {\n\treturn s.Struct.SetPtr(2, v.Struct.ToPtr())\n}\n\n// NewOptions sets the options field to a newly\n// allocated RegistrationOptions struct, preferring placement in s's segment.\nfunc (s TunnelServer_authenticate_Params) NewOptions() (RegistrationOptions, error) {\n\tss, err := NewRegistrationOptions(s.Struct.Segment())\n\tif err != nil {\n\t\treturn RegistrationOptions{}, err\n\t}\n\terr = s.Struct.SetPtr(2, ss.Struct.ToPtr())\n\treturn ss, err\n}\n\n// TunnelServer_authenticate_Params_List is a list of TunnelServer_authenticate_Params.\ntype TunnelServer_authenticate_Params_List struct{ capnp.List }\n\n// NewTunnelServer_authenticate_Params creates a new list of TunnelServer_authenticate_Params.\nfunc NewTunnelServer_authenticate_Params_List(s *capnp.Segment, sz int32) (TunnelServer_authenticate_Params_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 3}, sz)\n\treturn TunnelServer_authenticate_Params_List{l}, err\n}\n\nfunc (s TunnelServer_authenticate_Params_List) At(i int) TunnelServer_authenticate_Params {\n\treturn TunnelServer_authenticate_Params{s.List.Struct(i)}\n}\n\nfunc (s TunnelServer_authenticate_Params_List) Set(i int, v TunnelServer_authenticate_Params) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s TunnelServer_authenticate_Params_List) String() string {\n\tstr, _ := text.MarshalList(0x85c8cea1ab1894f3, s.List)\n\treturn str\n}\n\n// TunnelServer_authenticate_Params_Promise is a wrapper for a TunnelServer_authenticate_Params promised by a client call.\ntype TunnelServer_authenticate_Params_Promise struct{ *capnp.Pipeline }\n\nfunc (p TunnelServer_authenticate_Params_Promise) Struct() (TunnelServer_authenticate_Params, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn TunnelServer_authenticate_Params{s}, err\n}\n\nfunc (p TunnelServer_authenticate_Params_Promise) Options() RegistrationOptions_Promise {\n\treturn RegistrationOptions_Promise{Pipeline: p.Pipeline.GetPipeline(2)}\n}\n\ntype TunnelServer_authenticate_Results struct{ capnp.Struct }\n\n// TunnelServer_authenticate_Results_TypeID is the unique identifier for the type TunnelServer_authenticate_Results.\nconst TunnelServer_authenticate_Results_TypeID = 0xfc5edf80e39c0796\n\nfunc NewTunnelServer_authenticate_Results(s *capnp.Segment) (TunnelServer_authenticate_Results, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn TunnelServer_authenticate_Results{st}, err\n}\n\nfunc NewRootTunnelServer_authenticate_Results(s *capnp.Segment) (TunnelServer_authenticate_Results, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn TunnelServer_authenticate_Results{st}, err\n}\n\nfunc ReadRootTunnelServer_authenticate_Results(msg *capnp.Message) (TunnelServer_authenticate_Results, error) {\n\troot, err := msg.RootPtr()\n\treturn TunnelServer_authenticate_Results{root.Struct()}, err\n}\n\nfunc (s TunnelServer_authenticate_Results) String() string {\n\tstr, _ := text.Marshal(0xfc5edf80e39c0796, s.Struct)\n\treturn str\n}\n\nfunc (s TunnelServer_authenticate_Results) Result() (AuthenticateResponse, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn AuthenticateResponse{Struct: p.Struct()}, err\n}\n\nfunc (s TunnelServer_authenticate_Results) HasResult() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelServer_authenticate_Results) SetResult(v AuthenticateResponse) error {\n\treturn s.Struct.SetPtr(0, v.Struct.ToPtr())\n}\n\n// NewResult sets the result field to a newly\n// allocated AuthenticateResponse struct, preferring placement in s's segment.\nfunc (s TunnelServer_authenticate_Results) NewResult() (AuthenticateResponse, error) {\n\tss, err := NewAuthenticateResponse(s.Struct.Segment())\n\tif err != nil {\n\t\treturn AuthenticateResponse{}, err\n\t}\n\terr = s.Struct.SetPtr(0, ss.Struct.ToPtr())\n\treturn ss, err\n}\n\n// TunnelServer_authenticate_Results_List is a list of TunnelServer_authenticate_Results.\ntype TunnelServer_authenticate_Results_List struct{ capnp.List }\n\n// NewTunnelServer_authenticate_Results creates a new list of TunnelServer_authenticate_Results.\nfunc NewTunnelServer_authenticate_Results_List(s *capnp.Segment, sz int32) (TunnelServer_authenticate_Results_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz)\n\treturn TunnelServer_authenticate_Results_List{l}, err\n}\n\nfunc (s TunnelServer_authenticate_Results_List) At(i int) TunnelServer_authenticate_Results {\n\treturn TunnelServer_authenticate_Results{s.List.Struct(i)}\n}\n\nfunc (s TunnelServer_authenticate_Results_List) Set(i int, v TunnelServer_authenticate_Results) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s TunnelServer_authenticate_Results_List) String() string {\n\tstr, _ := text.MarshalList(0xfc5edf80e39c0796, s.List)\n\treturn str\n}\n\n// TunnelServer_authenticate_Results_Promise is a wrapper for a TunnelServer_authenticate_Results promised by a client call.\ntype TunnelServer_authenticate_Results_Promise struct{ *capnp.Pipeline }\n\nfunc (p TunnelServer_authenticate_Results_Promise) Struct() (TunnelServer_authenticate_Results, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn TunnelServer_authenticate_Results{s}, err\n}\n\nfunc (p TunnelServer_authenticate_Results_Promise) Result() AuthenticateResponse_Promise {\n\treturn AuthenticateResponse_Promise{Pipeline: p.Pipeline.GetPipeline(0)}\n}\n\ntype TunnelServer_reconnectTunnel_Params struct{ capnp.Struct }\n\n// TunnelServer_reconnectTunnel_Params_TypeID is the unique identifier for the type TunnelServer_reconnectTunnel_Params.\nconst TunnelServer_reconnectTunnel_Params_TypeID = 0xa353a3556df74984\n\nfunc NewTunnelServer_reconnectTunnel_Params(s *capnp.Segment) (TunnelServer_reconnectTunnel_Params, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 5})\n\treturn TunnelServer_reconnectTunnel_Params{st}, err\n}\n\nfunc NewRootTunnelServer_reconnectTunnel_Params(s *capnp.Segment) (TunnelServer_reconnectTunnel_Params, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 5})\n\treturn TunnelServer_reconnectTunnel_Params{st}, err\n}\n\nfunc ReadRootTunnelServer_reconnectTunnel_Params(msg *capnp.Message) (TunnelServer_reconnectTunnel_Params, error) {\n\troot, err := msg.RootPtr()\n\treturn TunnelServer_reconnectTunnel_Params{root.Struct()}, err\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params) String() string {\n\tstr, _ := text.Marshal(0xa353a3556df74984, s.Struct)\n\treturn str\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params) Jwt() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params) HasJwt() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params) SetJwt(v []byte) error {\n\treturn s.Struct.SetData(0, v)\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params) EventDigest() ([]byte, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params) HasEventDigest() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params) SetEventDigest(v []byte) error {\n\treturn s.Struct.SetData(1, v)\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params) ConnDigest() ([]byte, error) {\n\tp, err := s.Struct.Ptr(2)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params) HasConnDigest() bool {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params) SetConnDigest(v []byte) error {\n\treturn s.Struct.SetData(2, v)\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params) Hostname() (string, error) {\n\tp, err := s.Struct.Ptr(3)\n\treturn p.Text(), err\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params) HasHostname() bool {\n\tp, err := s.Struct.Ptr(3)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params) HostnameBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(3)\n\treturn p.TextBytes(), err\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params) SetHostname(v string) error {\n\treturn s.Struct.SetText(3, v)\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params) Options() (RegistrationOptions, error) {\n\tp, err := s.Struct.Ptr(4)\n\treturn RegistrationOptions{Struct: p.Struct()}, err\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params) HasOptions() bool {\n\tp, err := s.Struct.Ptr(4)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params) SetOptions(v RegistrationOptions) error {\n\treturn s.Struct.SetPtr(4, v.Struct.ToPtr())\n}\n\n// NewOptions sets the options field to a newly\n// allocated RegistrationOptions struct, preferring placement in s's segment.\nfunc (s TunnelServer_reconnectTunnel_Params) NewOptions() (RegistrationOptions, error) {\n\tss, err := NewRegistrationOptions(s.Struct.Segment())\n\tif err != nil {\n\t\treturn RegistrationOptions{}, err\n\t}\n\terr = s.Struct.SetPtr(4, ss.Struct.ToPtr())\n\treturn ss, err\n}\n\n// TunnelServer_reconnectTunnel_Params_List is a list of TunnelServer_reconnectTunnel_Params.\ntype TunnelServer_reconnectTunnel_Params_List struct{ capnp.List }\n\n// NewTunnelServer_reconnectTunnel_Params creates a new list of TunnelServer_reconnectTunnel_Params.\nfunc NewTunnelServer_reconnectTunnel_Params_List(s *capnp.Segment, sz int32) (TunnelServer_reconnectTunnel_Params_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 5}, sz)\n\treturn TunnelServer_reconnectTunnel_Params_List{l}, err\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params_List) At(i int) TunnelServer_reconnectTunnel_Params {\n\treturn TunnelServer_reconnectTunnel_Params{s.List.Struct(i)}\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params_List) Set(i int, v TunnelServer_reconnectTunnel_Params) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s TunnelServer_reconnectTunnel_Params_List) String() string {\n\tstr, _ := text.MarshalList(0xa353a3556df74984, s.List)\n\treturn str\n}\n\n// TunnelServer_reconnectTunnel_Params_Promise is a wrapper for a TunnelServer_reconnectTunnel_Params promised by a client call.\ntype TunnelServer_reconnectTunnel_Params_Promise struct{ *capnp.Pipeline }\n\nfunc (p TunnelServer_reconnectTunnel_Params_Promise) Struct() (TunnelServer_reconnectTunnel_Params, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn TunnelServer_reconnectTunnel_Params{s}, err\n}\n\nfunc (p TunnelServer_reconnectTunnel_Params_Promise) Options() RegistrationOptions_Promise {\n\treturn RegistrationOptions_Promise{Pipeline: p.Pipeline.GetPipeline(4)}\n}\n\ntype TunnelServer_reconnectTunnel_Results struct{ capnp.Struct }\n\n// TunnelServer_reconnectTunnel_Results_TypeID is the unique identifier for the type TunnelServer_reconnectTunnel_Results.\nconst TunnelServer_reconnectTunnel_Results_TypeID = 0xd4d18de97bb12de3\n\nfunc NewTunnelServer_reconnectTunnel_Results(s *capnp.Segment) (TunnelServer_reconnectTunnel_Results, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn TunnelServer_reconnectTunnel_Results{st}, err\n}\n\nfunc NewRootTunnelServer_reconnectTunnel_Results(s *capnp.Segment) (TunnelServer_reconnectTunnel_Results, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn TunnelServer_reconnectTunnel_Results{st}, err\n}\n\nfunc ReadRootTunnelServer_reconnectTunnel_Results(msg *capnp.Message) (TunnelServer_reconnectTunnel_Results, error) {\n\troot, err := msg.RootPtr()\n\treturn TunnelServer_reconnectTunnel_Results{root.Struct()}, err\n}\n\nfunc (s TunnelServer_reconnectTunnel_Results) String() string {\n\tstr, _ := text.Marshal(0xd4d18de97bb12de3, s.Struct)\n\treturn str\n}\n\nfunc (s TunnelServer_reconnectTunnel_Results) Result() (TunnelRegistration, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn TunnelRegistration{Struct: p.Struct()}, err\n}\n\nfunc (s TunnelServer_reconnectTunnel_Results) HasResult() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelServer_reconnectTunnel_Results) SetResult(v TunnelRegistration) error {\n\treturn s.Struct.SetPtr(0, v.Struct.ToPtr())\n}\n\n// NewResult sets the result field to a newly\n// allocated TunnelRegistration struct, preferring placement in s's segment.\nfunc (s TunnelServer_reconnectTunnel_Results) NewResult() (TunnelRegistration, error) {\n\tss, err := NewTunnelRegistration(s.Struct.Segment())\n\tif err != nil {\n\t\treturn TunnelRegistration{}, err\n\t}\n\terr = s.Struct.SetPtr(0, ss.Struct.ToPtr())\n\treturn ss, err\n}\n\n// TunnelServer_reconnectTunnel_Results_List is a list of TunnelServer_reconnectTunnel_Results.\ntype TunnelServer_reconnectTunnel_Results_List struct{ capnp.List }\n\n// NewTunnelServer_reconnectTunnel_Results creates a new list of TunnelServer_reconnectTunnel_Results.\nfunc NewTunnelServer_reconnectTunnel_Results_List(s *capnp.Segment, sz int32) (TunnelServer_reconnectTunnel_Results_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz)\n\treturn TunnelServer_reconnectTunnel_Results_List{l}, err\n}\n\nfunc (s TunnelServer_reconnectTunnel_Results_List) At(i int) TunnelServer_reconnectTunnel_Results {\n\treturn TunnelServer_reconnectTunnel_Results{s.List.Struct(i)}\n}\n\nfunc (s TunnelServer_reconnectTunnel_Results_List) Set(i int, v TunnelServer_reconnectTunnel_Results) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s TunnelServer_reconnectTunnel_Results_List) String() string {\n\tstr, _ := text.MarshalList(0xd4d18de97bb12de3, s.List)\n\treturn str\n}\n\n// TunnelServer_reconnectTunnel_Results_Promise is a wrapper for a TunnelServer_reconnectTunnel_Results promised by a client call.\ntype TunnelServer_reconnectTunnel_Results_Promise struct{ *capnp.Pipeline }\n\nfunc (p TunnelServer_reconnectTunnel_Results_Promise) Struct() (TunnelServer_reconnectTunnel_Results, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn TunnelServer_reconnectTunnel_Results{s}, err\n}\n\nfunc (p TunnelServer_reconnectTunnel_Results_Promise) Result() TunnelRegistration_Promise {\n\treturn TunnelRegistration_Promise{Pipeline: p.Pipeline.GetPipeline(0)}\n}\n\ntype Tag struct{ capnp.Struct }\n\n// Tag_TypeID is the unique identifier for the type Tag.\nconst Tag_TypeID = 0xcbd96442ae3bb01a\n\nfunc NewTag(s *capnp.Segment) (Tag, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2})\n\treturn Tag{st}, err\n}\n\nfunc NewRootTag(s *capnp.Segment) (Tag, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2})\n\treturn Tag{st}, err\n}\n\nfunc ReadRootTag(msg *capnp.Message) (Tag, error) {\n\troot, err := msg.RootPtr()\n\treturn Tag{root.Struct()}, err\n}\n\nfunc (s Tag) String() string {\n\tstr, _ := text.Marshal(0xcbd96442ae3bb01a, s.Struct)\n\treturn str\n}\n\nfunc (s Tag) Name() (string, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.Text(), err\n}\n\nfunc (s Tag) HasName() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s Tag) NameBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.TextBytes(), err\n}\n\nfunc (s Tag) SetName(v string) error {\n\treturn s.Struct.SetText(0, v)\n}\n\nfunc (s Tag) Value() (string, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.Text(), err\n}\n\nfunc (s Tag) HasValue() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s Tag) ValueBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.TextBytes(), err\n}\n\nfunc (s Tag) SetValue(v string) error {\n\treturn s.Struct.SetText(1, v)\n}\n\n// Tag_List is a list of Tag.\ntype Tag_List struct{ capnp.List }\n\n// NewTag creates a new list of Tag.\nfunc NewTag_List(s *capnp.Segment, sz int32) (Tag_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}, sz)\n\treturn Tag_List{l}, err\n}\n\nfunc (s Tag_List) At(i int) Tag { return Tag{s.List.Struct(i)} }\n\nfunc (s Tag_List) Set(i int, v Tag) error { return s.List.SetStruct(i, v.Struct) }\n\nfunc (s Tag_List) String() string {\n\tstr, _ := text.MarshalList(0xcbd96442ae3bb01a, s.List)\n\treturn str\n}\n\n// Tag_Promise is a wrapper for a Tag promised by a client call.\ntype Tag_Promise struct{ *capnp.Pipeline }\n\nfunc (p Tag_Promise) Struct() (Tag, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn Tag{s}, err\n}\n\ntype ClientInfo struct{ capnp.Struct }\n\n// ClientInfo_TypeID is the unique identifier for the type ClientInfo.\nconst ClientInfo_TypeID = 0x83ced0145b2f114b\n\nfunc NewClientInfo(s *capnp.Segment) (ClientInfo, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 4})\n\treturn ClientInfo{st}, err\n}\n\nfunc NewRootClientInfo(s *capnp.Segment) (ClientInfo, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 4})\n\treturn ClientInfo{st}, err\n}\n\nfunc ReadRootClientInfo(msg *capnp.Message) (ClientInfo, error) {\n\troot, err := msg.RootPtr()\n\treturn ClientInfo{root.Struct()}, err\n}\n\nfunc (s ClientInfo) String() string {\n\tstr, _ := text.Marshal(0x83ced0145b2f114b, s.Struct)\n\treturn str\n}\n\nfunc (s ClientInfo) ClientId() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s ClientInfo) HasClientId() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ClientInfo) SetClientId(v []byte) error {\n\treturn s.Struct.SetData(0, v)\n}\n\nfunc (s ClientInfo) Features() (capnp.TextList, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn capnp.TextList{List: p.List()}, err\n}\n\nfunc (s ClientInfo) HasFeatures() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ClientInfo) SetFeatures(v capnp.TextList) error {\n\treturn s.Struct.SetPtr(1, v.List.ToPtr())\n}\n\n// NewFeatures sets the features field to a newly\n// allocated capnp.TextList, preferring placement in s's segment.\nfunc (s ClientInfo) NewFeatures(n int32) (capnp.TextList, error) {\n\tl, err := capnp.NewTextList(s.Struct.Segment(), n)\n\tif err != nil {\n\t\treturn capnp.TextList{}, err\n\t}\n\terr = s.Struct.SetPtr(1, l.List.ToPtr())\n\treturn l, err\n}\n\nfunc (s ClientInfo) Version() (string, error) {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.Text(), err\n}\n\nfunc (s ClientInfo) HasVersion() bool {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ClientInfo) VersionBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.TextBytes(), err\n}\n\nfunc (s ClientInfo) SetVersion(v string) error {\n\treturn s.Struct.SetText(2, v)\n}\n\nfunc (s ClientInfo) Arch() (string, error) {\n\tp, err := s.Struct.Ptr(3)\n\treturn p.Text(), err\n}\n\nfunc (s ClientInfo) HasArch() bool {\n\tp, err := s.Struct.Ptr(3)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ClientInfo) ArchBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(3)\n\treturn p.TextBytes(), err\n}\n\nfunc (s ClientInfo) SetArch(v string) error {\n\treturn s.Struct.SetText(3, v)\n}\n\n// ClientInfo_List is a list of ClientInfo.\ntype ClientInfo_List struct{ capnp.List }\n\n// NewClientInfo creates a new list of ClientInfo.\nfunc NewClientInfo_List(s *capnp.Segment, sz int32) (ClientInfo_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 4}, sz)\n\treturn ClientInfo_List{l}, err\n}\n\nfunc (s ClientInfo_List) At(i int) ClientInfo { return ClientInfo{s.List.Struct(i)} }\n\nfunc (s ClientInfo_List) Set(i int, v ClientInfo) error { return s.List.SetStruct(i, v.Struct) }\n\nfunc (s ClientInfo_List) String() string {\n\tstr, _ := text.MarshalList(0x83ced0145b2f114b, s.List)\n\treturn str\n}\n\n// ClientInfo_Promise is a wrapper for a ClientInfo promised by a client call.\ntype ClientInfo_Promise struct{ *capnp.Pipeline }\n\nfunc (p ClientInfo_Promise) Struct() (ClientInfo, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn ClientInfo{s}, err\n}\n\ntype ConnectionOptions struct{ capnp.Struct }\n\n// ConnectionOptions_TypeID is the unique identifier for the type ConnectionOptions.\nconst ConnectionOptions_TypeID = 0xb4bf9861fe035d04\n\nfunc NewConnectionOptions(s *capnp.Segment) (ConnectionOptions, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2})\n\treturn ConnectionOptions{st}, err\n}\n\nfunc NewRootConnectionOptions(s *capnp.Segment) (ConnectionOptions, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2})\n\treturn ConnectionOptions{st}, err\n}\n\nfunc ReadRootConnectionOptions(msg *capnp.Message) (ConnectionOptions, error) {\n\troot, err := msg.RootPtr()\n\treturn ConnectionOptions{root.Struct()}, err\n}\n\nfunc (s ConnectionOptions) String() string {\n\tstr, _ := text.Marshal(0xb4bf9861fe035d04, s.Struct)\n\treturn str\n}\n\nfunc (s ConnectionOptions) Client() (ClientInfo, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn ClientInfo{Struct: p.Struct()}, err\n}\n\nfunc (s ConnectionOptions) HasClient() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ConnectionOptions) SetClient(v ClientInfo) error {\n\treturn s.Struct.SetPtr(0, v.Struct.ToPtr())\n}\n\n// NewClient sets the client field to a newly\n// allocated ClientInfo struct, preferring placement in s's segment.\nfunc (s ConnectionOptions) NewClient() (ClientInfo, error) {\n\tss, err := NewClientInfo(s.Struct.Segment())\n\tif err != nil {\n\t\treturn ClientInfo{}, err\n\t}\n\terr = s.Struct.SetPtr(0, ss.Struct.ToPtr())\n\treturn ss, err\n}\n\nfunc (s ConnectionOptions) OriginLocalIp() ([]byte, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s ConnectionOptions) HasOriginLocalIp() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ConnectionOptions) SetOriginLocalIp(v []byte) error {\n\treturn s.Struct.SetData(1, v)\n}\n\nfunc (s ConnectionOptions) ReplaceExisting() bool {\n\treturn s.Struct.Bit(0)\n}\n\nfunc (s ConnectionOptions) SetReplaceExisting(v bool) {\n\ts.Struct.SetBit(0, v)\n}\n\nfunc (s ConnectionOptions) CompressionQuality() uint8 {\n\treturn s.Struct.Uint8(1)\n}\n\nfunc (s ConnectionOptions) SetCompressionQuality(v uint8) {\n\ts.Struct.SetUint8(1, v)\n}\n\nfunc (s ConnectionOptions) NumPreviousAttempts() uint8 {\n\treturn s.Struct.Uint8(2)\n}\n\nfunc (s ConnectionOptions) SetNumPreviousAttempts(v uint8) {\n\ts.Struct.SetUint8(2, v)\n}\n\n// ConnectionOptions_List is a list of ConnectionOptions.\ntype ConnectionOptions_List struct{ capnp.List }\n\n// NewConnectionOptions creates a new list of ConnectionOptions.\nfunc NewConnectionOptions_List(s *capnp.Segment, sz int32) (ConnectionOptions_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}, sz)\n\treturn ConnectionOptions_List{l}, err\n}\n\nfunc (s ConnectionOptions_List) At(i int) ConnectionOptions {\n\treturn ConnectionOptions{s.List.Struct(i)}\n}\n\nfunc (s ConnectionOptions_List) Set(i int, v ConnectionOptions) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s ConnectionOptions_List) String() string {\n\tstr, _ := text.MarshalList(0xb4bf9861fe035d04, s.List)\n\treturn str\n}\n\n// ConnectionOptions_Promise is a wrapper for a ConnectionOptions promised by a client call.\ntype ConnectionOptions_Promise struct{ *capnp.Pipeline }\n\nfunc (p ConnectionOptions_Promise) Struct() (ConnectionOptions, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn ConnectionOptions{s}, err\n}\n\nfunc (p ConnectionOptions_Promise) Client() ClientInfo_Promise {\n\treturn ClientInfo_Promise{Pipeline: p.Pipeline.GetPipeline(0)}\n}\n\ntype ConnectionResponse struct{ capnp.Struct }\ntype ConnectionResponse_result ConnectionResponse\ntype ConnectionResponse_result_Which uint16\n\nconst (\n\tConnectionResponse_result_Which_error             ConnectionResponse_result_Which = 0\n\tConnectionResponse_result_Which_connectionDetails ConnectionResponse_result_Which = 1\n)\n\nfunc (w ConnectionResponse_result_Which) String() string {\n\tconst s = \"errorconnectionDetails\"\n\tswitch w {\n\tcase ConnectionResponse_result_Which_error:\n\t\treturn s[0:5]\n\tcase ConnectionResponse_result_Which_connectionDetails:\n\t\treturn s[5:22]\n\n\t}\n\treturn \"ConnectionResponse_result_Which(\" + strconv.FormatUint(uint64(w), 10) + \")\"\n}\n\n// ConnectionResponse_TypeID is the unique identifier for the type ConnectionResponse.\nconst ConnectionResponse_TypeID = 0xdbaa9d03d52b62dc\n\nfunc NewConnectionResponse(s *capnp.Segment) (ConnectionResponse, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})\n\treturn ConnectionResponse{st}, err\n}\n\nfunc NewRootConnectionResponse(s *capnp.Segment) (ConnectionResponse, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})\n\treturn ConnectionResponse{st}, err\n}\n\nfunc ReadRootConnectionResponse(msg *capnp.Message) (ConnectionResponse, error) {\n\troot, err := msg.RootPtr()\n\treturn ConnectionResponse{root.Struct()}, err\n}\n\nfunc (s ConnectionResponse) String() string {\n\tstr, _ := text.Marshal(0xdbaa9d03d52b62dc, s.Struct)\n\treturn str\n}\n\nfunc (s ConnectionResponse) Result() ConnectionResponse_result { return ConnectionResponse_result(s) }\n\nfunc (s ConnectionResponse_result) Which() ConnectionResponse_result_Which {\n\treturn ConnectionResponse_result_Which(s.Struct.Uint16(0))\n}\nfunc (s ConnectionResponse_result) Error() (ConnectionError, error) {\n\tif s.Struct.Uint16(0) != 0 {\n\t\tpanic(\"Which() != error\")\n\t}\n\tp, err := s.Struct.Ptr(0)\n\treturn ConnectionError{Struct: p.Struct()}, err\n}\n\nfunc (s ConnectionResponse_result) HasError() bool {\n\tif s.Struct.Uint16(0) != 0 {\n\t\treturn false\n\t}\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ConnectionResponse_result) SetError(v ConnectionError) error {\n\ts.Struct.SetUint16(0, 0)\n\treturn s.Struct.SetPtr(0, v.Struct.ToPtr())\n}\n\n// NewError sets the error field to a newly\n// allocated ConnectionError struct, preferring placement in s's segment.\nfunc (s ConnectionResponse_result) NewError() (ConnectionError, error) {\n\ts.Struct.SetUint16(0, 0)\n\tss, err := NewConnectionError(s.Struct.Segment())\n\tif err != nil {\n\t\treturn ConnectionError{}, err\n\t}\n\terr = s.Struct.SetPtr(0, ss.Struct.ToPtr())\n\treturn ss, err\n}\n\nfunc (s ConnectionResponse_result) ConnectionDetails() (ConnectionDetails, error) {\n\tif s.Struct.Uint16(0) != 1 {\n\t\tpanic(\"Which() != connectionDetails\")\n\t}\n\tp, err := s.Struct.Ptr(0)\n\treturn ConnectionDetails{Struct: p.Struct()}, err\n}\n\nfunc (s ConnectionResponse_result) HasConnectionDetails() bool {\n\tif s.Struct.Uint16(0) != 1 {\n\t\treturn false\n\t}\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ConnectionResponse_result) SetConnectionDetails(v ConnectionDetails) error {\n\ts.Struct.SetUint16(0, 1)\n\treturn s.Struct.SetPtr(0, v.Struct.ToPtr())\n}\n\n// NewConnectionDetails sets the connectionDetails field to a newly\n// allocated ConnectionDetails struct, preferring placement in s's segment.\nfunc (s ConnectionResponse_result) NewConnectionDetails() (ConnectionDetails, error) {\n\ts.Struct.SetUint16(0, 1)\n\tss, err := NewConnectionDetails(s.Struct.Segment())\n\tif err != nil {\n\t\treturn ConnectionDetails{}, err\n\t}\n\terr = s.Struct.SetPtr(0, ss.Struct.ToPtr())\n\treturn ss, err\n}\n\n// ConnectionResponse_List is a list of ConnectionResponse.\ntype ConnectionResponse_List struct{ capnp.List }\n\n// NewConnectionResponse creates a new list of ConnectionResponse.\nfunc NewConnectionResponse_List(s *capnp.Segment, sz int32) (ConnectionResponse_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz)\n\treturn ConnectionResponse_List{l}, err\n}\n\nfunc (s ConnectionResponse_List) At(i int) ConnectionResponse {\n\treturn ConnectionResponse{s.List.Struct(i)}\n}\n\nfunc (s ConnectionResponse_List) Set(i int, v ConnectionResponse) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s ConnectionResponse_List) String() string {\n\tstr, _ := text.MarshalList(0xdbaa9d03d52b62dc, s.List)\n\treturn str\n}\n\n// ConnectionResponse_Promise is a wrapper for a ConnectionResponse promised by a client call.\ntype ConnectionResponse_Promise struct{ *capnp.Pipeline }\n\nfunc (p ConnectionResponse_Promise) Struct() (ConnectionResponse, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn ConnectionResponse{s}, err\n}\n\nfunc (p ConnectionResponse_Promise) Result() ConnectionResponse_result_Promise {\n\treturn ConnectionResponse_result_Promise{p.Pipeline}\n}\n\n// ConnectionResponse_result_Promise is a wrapper for a ConnectionResponse_result promised by a client call.\ntype ConnectionResponse_result_Promise struct{ *capnp.Pipeline }\n\nfunc (p ConnectionResponse_result_Promise) Struct() (ConnectionResponse_result, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn ConnectionResponse_result{s}, err\n}\n\nfunc (p ConnectionResponse_result_Promise) Error() ConnectionError_Promise {\n\treturn ConnectionError_Promise{Pipeline: p.Pipeline.GetPipeline(0)}\n}\n\nfunc (p ConnectionResponse_result_Promise) ConnectionDetails() ConnectionDetails_Promise {\n\treturn ConnectionDetails_Promise{Pipeline: p.Pipeline.GetPipeline(0)}\n}\n\ntype ConnectionError struct{ capnp.Struct }\n\n// ConnectionError_TypeID is the unique identifier for the type ConnectionError.\nconst ConnectionError_TypeID = 0xf5f383d2785edb86\n\nfunc NewConnectionError(s *capnp.Segment) (ConnectionError, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 1})\n\treturn ConnectionError{st}, err\n}\n\nfunc NewRootConnectionError(s *capnp.Segment) (ConnectionError, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 1})\n\treturn ConnectionError{st}, err\n}\n\nfunc ReadRootConnectionError(msg *capnp.Message) (ConnectionError, error) {\n\troot, err := msg.RootPtr()\n\treturn ConnectionError{root.Struct()}, err\n}\n\nfunc (s ConnectionError) String() string {\n\tstr, _ := text.Marshal(0xf5f383d2785edb86, s.Struct)\n\treturn str\n}\n\nfunc (s ConnectionError) Cause() (string, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.Text(), err\n}\n\nfunc (s ConnectionError) HasCause() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ConnectionError) CauseBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.TextBytes(), err\n}\n\nfunc (s ConnectionError) SetCause(v string) error {\n\treturn s.Struct.SetText(0, v)\n}\n\nfunc (s ConnectionError) RetryAfter() int64 {\n\treturn int64(s.Struct.Uint64(0))\n}\n\nfunc (s ConnectionError) SetRetryAfter(v int64) {\n\ts.Struct.SetUint64(0, uint64(v))\n}\n\nfunc (s ConnectionError) ShouldRetry() bool {\n\treturn s.Struct.Bit(64)\n}\n\nfunc (s ConnectionError) SetShouldRetry(v bool) {\n\ts.Struct.SetBit(64, v)\n}\n\n// ConnectionError_List is a list of ConnectionError.\ntype ConnectionError_List struct{ capnp.List }\n\n// NewConnectionError creates a new list of ConnectionError.\nfunc NewConnectionError_List(s *capnp.Segment, sz int32) (ConnectionError_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 16, PointerCount: 1}, sz)\n\treturn ConnectionError_List{l}, err\n}\n\nfunc (s ConnectionError_List) At(i int) ConnectionError { return ConnectionError{s.List.Struct(i)} }\n\nfunc (s ConnectionError_List) Set(i int, v ConnectionError) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s ConnectionError_List) String() string {\n\tstr, _ := text.MarshalList(0xf5f383d2785edb86, s.List)\n\treturn str\n}\n\n// ConnectionError_Promise is a wrapper for a ConnectionError promised by a client call.\ntype ConnectionError_Promise struct{ *capnp.Pipeline }\n\nfunc (p ConnectionError_Promise) Struct() (ConnectionError, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn ConnectionError{s}, err\n}\n\ntype ConnectionDetails struct{ capnp.Struct }\n\n// ConnectionDetails_TypeID is the unique identifier for the type ConnectionDetails.\nconst ConnectionDetails_TypeID = 0xb5f39f082b9ac18a\n\nfunc NewConnectionDetails(s *capnp.Segment) (ConnectionDetails, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2})\n\treturn ConnectionDetails{st}, err\n}\n\nfunc NewRootConnectionDetails(s *capnp.Segment) (ConnectionDetails, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2})\n\treturn ConnectionDetails{st}, err\n}\n\nfunc ReadRootConnectionDetails(msg *capnp.Message) (ConnectionDetails, error) {\n\troot, err := msg.RootPtr()\n\treturn ConnectionDetails{root.Struct()}, err\n}\n\nfunc (s ConnectionDetails) String() string {\n\tstr, _ := text.Marshal(0xb5f39f082b9ac18a, s.Struct)\n\treturn str\n}\n\nfunc (s ConnectionDetails) Uuid() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s ConnectionDetails) HasUuid() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ConnectionDetails) SetUuid(v []byte) error {\n\treturn s.Struct.SetData(0, v)\n}\n\nfunc (s ConnectionDetails) LocationName() (string, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.Text(), err\n}\n\nfunc (s ConnectionDetails) HasLocationName() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ConnectionDetails) LocationNameBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.TextBytes(), err\n}\n\nfunc (s ConnectionDetails) SetLocationName(v string) error {\n\treturn s.Struct.SetText(1, v)\n}\n\nfunc (s ConnectionDetails) TunnelIsRemotelyManaged() bool {\n\treturn s.Struct.Bit(0)\n}\n\nfunc (s ConnectionDetails) SetTunnelIsRemotelyManaged(v bool) {\n\ts.Struct.SetBit(0, v)\n}\n\n// ConnectionDetails_List is a list of ConnectionDetails.\ntype ConnectionDetails_List struct{ capnp.List }\n\n// NewConnectionDetails creates a new list of ConnectionDetails.\nfunc NewConnectionDetails_List(s *capnp.Segment, sz int32) (ConnectionDetails_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}, sz)\n\treturn ConnectionDetails_List{l}, err\n}\n\nfunc (s ConnectionDetails_List) At(i int) ConnectionDetails {\n\treturn ConnectionDetails{s.List.Struct(i)}\n}\n\nfunc (s ConnectionDetails_List) Set(i int, v ConnectionDetails) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s ConnectionDetails_List) String() string {\n\tstr, _ := text.MarshalList(0xb5f39f082b9ac18a, s.List)\n\treturn str\n}\n\n// ConnectionDetails_Promise is a wrapper for a ConnectionDetails promised by a client call.\ntype ConnectionDetails_Promise struct{ *capnp.Pipeline }\n\nfunc (p ConnectionDetails_Promise) Struct() (ConnectionDetails, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn ConnectionDetails{s}, err\n}\n\ntype TunnelAuth struct{ capnp.Struct }\n\n// TunnelAuth_TypeID is the unique identifier for the type TunnelAuth.\nconst TunnelAuth_TypeID = 0x9496331ab9cd463f\n\nfunc NewTunnelAuth(s *capnp.Segment) (TunnelAuth, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2})\n\treturn TunnelAuth{st}, err\n}\n\nfunc NewRootTunnelAuth(s *capnp.Segment) (TunnelAuth, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2})\n\treturn TunnelAuth{st}, err\n}\n\nfunc ReadRootTunnelAuth(msg *capnp.Message) (TunnelAuth, error) {\n\troot, err := msg.RootPtr()\n\treturn TunnelAuth{root.Struct()}, err\n}\n\nfunc (s TunnelAuth) String() string {\n\tstr, _ := text.Marshal(0x9496331ab9cd463f, s.Struct)\n\treturn str\n}\n\nfunc (s TunnelAuth) AccountTag() (string, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.Text(), err\n}\n\nfunc (s TunnelAuth) HasAccountTag() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelAuth) AccountTagBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.TextBytes(), err\n}\n\nfunc (s TunnelAuth) SetAccountTag(v string) error {\n\treturn s.Struct.SetText(0, v)\n}\n\nfunc (s TunnelAuth) TunnelSecret() ([]byte, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s TunnelAuth) HasTunnelSecret() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s TunnelAuth) SetTunnelSecret(v []byte) error {\n\treturn s.Struct.SetData(1, v)\n}\n\n// TunnelAuth_List is a list of TunnelAuth.\ntype TunnelAuth_List struct{ capnp.List }\n\n// NewTunnelAuth creates a new list of TunnelAuth.\nfunc NewTunnelAuth_List(s *capnp.Segment, sz int32) (TunnelAuth_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}, sz)\n\treturn TunnelAuth_List{l}, err\n}\n\nfunc (s TunnelAuth_List) At(i int) TunnelAuth { return TunnelAuth{s.List.Struct(i)} }\n\nfunc (s TunnelAuth_List) Set(i int, v TunnelAuth) error { return s.List.SetStruct(i, v.Struct) }\n\nfunc (s TunnelAuth_List) String() string {\n\tstr, _ := text.MarshalList(0x9496331ab9cd463f, s.List)\n\treturn str\n}\n\n// TunnelAuth_Promise is a wrapper for a TunnelAuth promised by a client call.\ntype TunnelAuth_Promise struct{ *capnp.Pipeline }\n\nfunc (p TunnelAuth_Promise) Struct() (TunnelAuth, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn TunnelAuth{s}, err\n}\n\ntype RegistrationServer struct{ Client capnp.Client }\n\n// RegistrationServer_TypeID is the unique identifier for the type RegistrationServer.\nconst RegistrationServer_TypeID = 0xf71695ec7fe85497\n\nfunc (c RegistrationServer) RegisterConnection(ctx context.Context, params func(RegistrationServer_registerConnection_Params) error, opts ...capnp.CallOption) RegistrationServer_registerConnection_Results_Promise {\n\tif c.Client == nil {\n\t\treturn RegistrationServer_registerConnection_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xf71695ec7fe85497,\n\t\t\tMethodID:      0,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:RegistrationServer\",\n\t\t\tMethodName:    \"registerConnection\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 8, PointerCount: 3}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error { return params(RegistrationServer_registerConnection_Params{Struct: s}) }\n\t}\n\treturn RegistrationServer_registerConnection_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\nfunc (c RegistrationServer) UnregisterConnection(ctx context.Context, params func(RegistrationServer_unregisterConnection_Params) error, opts ...capnp.CallOption) RegistrationServer_unregisterConnection_Results_Promise {\n\tif c.Client == nil {\n\t\treturn RegistrationServer_unregisterConnection_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xf71695ec7fe85497,\n\t\t\tMethodID:      1,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:RegistrationServer\",\n\t\t\tMethodName:    \"unregisterConnection\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 0, PointerCount: 0}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error { return params(RegistrationServer_unregisterConnection_Params{Struct: s}) }\n\t}\n\treturn RegistrationServer_unregisterConnection_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\nfunc (c RegistrationServer) UpdateLocalConfiguration(ctx context.Context, params func(RegistrationServer_updateLocalConfiguration_Params) error, opts ...capnp.CallOption) RegistrationServer_updateLocalConfiguration_Results_Promise {\n\tif c.Client == nil {\n\t\treturn RegistrationServer_updateLocalConfiguration_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xf71695ec7fe85497,\n\t\t\tMethodID:      2,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:RegistrationServer\",\n\t\t\tMethodName:    \"updateLocalConfiguration\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 0, PointerCount: 1}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error {\n\t\t\treturn params(RegistrationServer_updateLocalConfiguration_Params{Struct: s})\n\t\t}\n\t}\n\treturn RegistrationServer_updateLocalConfiguration_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\n\ntype RegistrationServer_Server interface {\n\tRegisterConnection(RegistrationServer_registerConnection) error\n\n\tUnregisterConnection(RegistrationServer_unregisterConnection) error\n\n\tUpdateLocalConfiguration(RegistrationServer_updateLocalConfiguration) error\n}\n\nfunc RegistrationServer_ServerToClient(s RegistrationServer_Server) RegistrationServer {\n\tc, _ := s.(server.Closer)\n\treturn RegistrationServer{Client: server.New(RegistrationServer_Methods(nil, s), c)}\n}\n\nfunc RegistrationServer_Methods(methods []server.Method, s RegistrationServer_Server) []server.Method {\n\tif cap(methods) == 0 {\n\t\tmethods = make([]server.Method, 0, 3)\n\t}\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xf71695ec7fe85497,\n\t\t\tMethodID:      0,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:RegistrationServer\",\n\t\t\tMethodName:    \"registerConnection\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := RegistrationServer_registerConnection{c, opts, RegistrationServer_registerConnection_Params{Struct: p}, RegistrationServer_registerConnection_Results{Struct: r}}\n\t\t\treturn s.RegisterConnection(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 1},\n\t})\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xf71695ec7fe85497,\n\t\t\tMethodID:      1,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:RegistrationServer\",\n\t\t\tMethodName:    \"unregisterConnection\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := RegistrationServer_unregisterConnection{c, opts, RegistrationServer_unregisterConnection_Params{Struct: p}, RegistrationServer_unregisterConnection_Results{Struct: r}}\n\t\t\treturn s.UnregisterConnection(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 0},\n\t})\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xf71695ec7fe85497,\n\t\t\tMethodID:      2,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:RegistrationServer\",\n\t\t\tMethodName:    \"updateLocalConfiguration\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := RegistrationServer_updateLocalConfiguration{c, opts, RegistrationServer_updateLocalConfiguration_Params{Struct: p}, RegistrationServer_updateLocalConfiguration_Results{Struct: r}}\n\t\t\treturn s.UpdateLocalConfiguration(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 0},\n\t})\n\n\treturn methods\n}\n\n// RegistrationServer_registerConnection holds the arguments for a server call to RegistrationServer.registerConnection.\ntype RegistrationServer_registerConnection struct {\n\tCtx     context.Context\n\tOptions capnp.CallOptions\n\tParams  RegistrationServer_registerConnection_Params\n\tResults RegistrationServer_registerConnection_Results\n}\n\n// RegistrationServer_unregisterConnection holds the arguments for a server call to RegistrationServer.unregisterConnection.\ntype RegistrationServer_unregisterConnection struct {\n\tCtx     context.Context\n\tOptions capnp.CallOptions\n\tParams  RegistrationServer_unregisterConnection_Params\n\tResults RegistrationServer_unregisterConnection_Results\n}\n\n// RegistrationServer_updateLocalConfiguration holds the arguments for a server call to RegistrationServer.updateLocalConfiguration.\ntype RegistrationServer_updateLocalConfiguration struct {\n\tCtx     context.Context\n\tOptions capnp.CallOptions\n\tParams  RegistrationServer_updateLocalConfiguration_Params\n\tResults RegistrationServer_updateLocalConfiguration_Results\n}\n\ntype RegistrationServer_registerConnection_Params struct{ capnp.Struct }\n\n// RegistrationServer_registerConnection_Params_TypeID is the unique identifier for the type RegistrationServer_registerConnection_Params.\nconst RegistrationServer_registerConnection_Params_TypeID = 0xe6646dec8feaa6ee\n\nfunc NewRegistrationServer_registerConnection_Params(s *capnp.Segment) (RegistrationServer_registerConnection_Params, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 3})\n\treturn RegistrationServer_registerConnection_Params{st}, err\n}\n\nfunc NewRootRegistrationServer_registerConnection_Params(s *capnp.Segment) (RegistrationServer_registerConnection_Params, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 3})\n\treturn RegistrationServer_registerConnection_Params{st}, err\n}\n\nfunc ReadRootRegistrationServer_registerConnection_Params(msg *capnp.Message) (RegistrationServer_registerConnection_Params, error) {\n\troot, err := msg.RootPtr()\n\treturn RegistrationServer_registerConnection_Params{root.Struct()}, err\n}\n\nfunc (s RegistrationServer_registerConnection_Params) String() string {\n\tstr, _ := text.Marshal(0xe6646dec8feaa6ee, s.Struct)\n\treturn str\n}\n\nfunc (s RegistrationServer_registerConnection_Params) Auth() (TunnelAuth, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn TunnelAuth{Struct: p.Struct()}, err\n}\n\nfunc (s RegistrationServer_registerConnection_Params) HasAuth() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s RegistrationServer_registerConnection_Params) SetAuth(v TunnelAuth) error {\n\treturn s.Struct.SetPtr(0, v.Struct.ToPtr())\n}\n\n// NewAuth sets the auth field to a newly\n// allocated TunnelAuth struct, preferring placement in s's segment.\nfunc (s RegistrationServer_registerConnection_Params) NewAuth() (TunnelAuth, error) {\n\tss, err := NewTunnelAuth(s.Struct.Segment())\n\tif err != nil {\n\t\treturn TunnelAuth{}, err\n\t}\n\terr = s.Struct.SetPtr(0, ss.Struct.ToPtr())\n\treturn ss, err\n}\n\nfunc (s RegistrationServer_registerConnection_Params) TunnelId() ([]byte, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s RegistrationServer_registerConnection_Params) HasTunnelId() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s RegistrationServer_registerConnection_Params) SetTunnelId(v []byte) error {\n\treturn s.Struct.SetData(1, v)\n}\n\nfunc (s RegistrationServer_registerConnection_Params) ConnIndex() uint8 {\n\treturn s.Struct.Uint8(0)\n}\n\nfunc (s RegistrationServer_registerConnection_Params) SetConnIndex(v uint8) {\n\ts.Struct.SetUint8(0, v)\n}\n\nfunc (s RegistrationServer_registerConnection_Params) Options() (ConnectionOptions, error) {\n\tp, err := s.Struct.Ptr(2)\n\treturn ConnectionOptions{Struct: p.Struct()}, err\n}\n\nfunc (s RegistrationServer_registerConnection_Params) HasOptions() bool {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s RegistrationServer_registerConnection_Params) SetOptions(v ConnectionOptions) error {\n\treturn s.Struct.SetPtr(2, v.Struct.ToPtr())\n}\n\n// NewOptions sets the options field to a newly\n// allocated ConnectionOptions struct, preferring placement in s's segment.\nfunc (s RegistrationServer_registerConnection_Params) NewOptions() (ConnectionOptions, error) {\n\tss, err := NewConnectionOptions(s.Struct.Segment())\n\tif err != nil {\n\t\treturn ConnectionOptions{}, err\n\t}\n\terr = s.Struct.SetPtr(2, ss.Struct.ToPtr())\n\treturn ss, err\n}\n\n// RegistrationServer_registerConnection_Params_List is a list of RegistrationServer_registerConnection_Params.\ntype RegistrationServer_registerConnection_Params_List struct{ capnp.List }\n\n// NewRegistrationServer_registerConnection_Params creates a new list of RegistrationServer_registerConnection_Params.\nfunc NewRegistrationServer_registerConnection_Params_List(s *capnp.Segment, sz int32) (RegistrationServer_registerConnection_Params_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 3}, sz)\n\treturn RegistrationServer_registerConnection_Params_List{l}, err\n}\n\nfunc (s RegistrationServer_registerConnection_Params_List) At(i int) RegistrationServer_registerConnection_Params {\n\treturn RegistrationServer_registerConnection_Params{s.List.Struct(i)}\n}\n\nfunc (s RegistrationServer_registerConnection_Params_List) Set(i int, v RegistrationServer_registerConnection_Params) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s RegistrationServer_registerConnection_Params_List) String() string {\n\tstr, _ := text.MarshalList(0xe6646dec8feaa6ee, s.List)\n\treturn str\n}\n\n// RegistrationServer_registerConnection_Params_Promise is a wrapper for a RegistrationServer_registerConnection_Params promised by a client call.\ntype RegistrationServer_registerConnection_Params_Promise struct{ *capnp.Pipeline }\n\nfunc (p RegistrationServer_registerConnection_Params_Promise) Struct() (RegistrationServer_registerConnection_Params, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn RegistrationServer_registerConnection_Params{s}, err\n}\n\nfunc (p RegistrationServer_registerConnection_Params_Promise) Auth() TunnelAuth_Promise {\n\treturn TunnelAuth_Promise{Pipeline: p.Pipeline.GetPipeline(0)}\n}\n\nfunc (p RegistrationServer_registerConnection_Params_Promise) Options() ConnectionOptions_Promise {\n\treturn ConnectionOptions_Promise{Pipeline: p.Pipeline.GetPipeline(2)}\n}\n\ntype RegistrationServer_registerConnection_Results struct{ capnp.Struct }\n\n// RegistrationServer_registerConnection_Results_TypeID is the unique identifier for the type RegistrationServer_registerConnection_Results.\nconst RegistrationServer_registerConnection_Results_TypeID = 0xea50d822450d1f17\n\nfunc NewRegistrationServer_registerConnection_Results(s *capnp.Segment) (RegistrationServer_registerConnection_Results, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn RegistrationServer_registerConnection_Results{st}, err\n}\n\nfunc NewRootRegistrationServer_registerConnection_Results(s *capnp.Segment) (RegistrationServer_registerConnection_Results, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn RegistrationServer_registerConnection_Results{st}, err\n}\n\nfunc ReadRootRegistrationServer_registerConnection_Results(msg *capnp.Message) (RegistrationServer_registerConnection_Results, error) {\n\troot, err := msg.RootPtr()\n\treturn RegistrationServer_registerConnection_Results{root.Struct()}, err\n}\n\nfunc (s RegistrationServer_registerConnection_Results) String() string {\n\tstr, _ := text.Marshal(0xea50d822450d1f17, s.Struct)\n\treturn str\n}\n\nfunc (s RegistrationServer_registerConnection_Results) Result() (ConnectionResponse, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn ConnectionResponse{Struct: p.Struct()}, err\n}\n\nfunc (s RegistrationServer_registerConnection_Results) HasResult() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s RegistrationServer_registerConnection_Results) SetResult(v ConnectionResponse) error {\n\treturn s.Struct.SetPtr(0, v.Struct.ToPtr())\n}\n\n// NewResult sets the result field to a newly\n// allocated ConnectionResponse struct, preferring placement in s's segment.\nfunc (s RegistrationServer_registerConnection_Results) NewResult() (ConnectionResponse, error) {\n\tss, err := NewConnectionResponse(s.Struct.Segment())\n\tif err != nil {\n\t\treturn ConnectionResponse{}, err\n\t}\n\terr = s.Struct.SetPtr(0, ss.Struct.ToPtr())\n\treturn ss, err\n}\n\n// RegistrationServer_registerConnection_Results_List is a list of RegistrationServer_registerConnection_Results.\ntype RegistrationServer_registerConnection_Results_List struct{ capnp.List }\n\n// NewRegistrationServer_registerConnection_Results creates a new list of RegistrationServer_registerConnection_Results.\nfunc NewRegistrationServer_registerConnection_Results_List(s *capnp.Segment, sz int32) (RegistrationServer_registerConnection_Results_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz)\n\treturn RegistrationServer_registerConnection_Results_List{l}, err\n}\n\nfunc (s RegistrationServer_registerConnection_Results_List) At(i int) RegistrationServer_registerConnection_Results {\n\treturn RegistrationServer_registerConnection_Results{s.List.Struct(i)}\n}\n\nfunc (s RegistrationServer_registerConnection_Results_List) Set(i int, v RegistrationServer_registerConnection_Results) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s RegistrationServer_registerConnection_Results_List) String() string {\n\tstr, _ := text.MarshalList(0xea50d822450d1f17, s.List)\n\treturn str\n}\n\n// RegistrationServer_registerConnection_Results_Promise is a wrapper for a RegistrationServer_registerConnection_Results promised by a client call.\ntype RegistrationServer_registerConnection_Results_Promise struct{ *capnp.Pipeline }\n\nfunc (p RegistrationServer_registerConnection_Results_Promise) Struct() (RegistrationServer_registerConnection_Results, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn RegistrationServer_registerConnection_Results{s}, err\n}\n\nfunc (p RegistrationServer_registerConnection_Results_Promise) Result() ConnectionResponse_Promise {\n\treturn ConnectionResponse_Promise{Pipeline: p.Pipeline.GetPipeline(0)}\n}\n\ntype RegistrationServer_unregisterConnection_Params struct{ capnp.Struct }\n\n// RegistrationServer_unregisterConnection_Params_TypeID is the unique identifier for the type RegistrationServer_unregisterConnection_Params.\nconst RegistrationServer_unregisterConnection_Params_TypeID = 0xf9cb7f4431a307d0\n\nfunc NewRegistrationServer_unregisterConnection_Params(s *capnp.Segment) (RegistrationServer_unregisterConnection_Params, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})\n\treturn RegistrationServer_unregisterConnection_Params{st}, err\n}\n\nfunc NewRootRegistrationServer_unregisterConnection_Params(s *capnp.Segment) (RegistrationServer_unregisterConnection_Params, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})\n\treturn RegistrationServer_unregisterConnection_Params{st}, err\n}\n\nfunc ReadRootRegistrationServer_unregisterConnection_Params(msg *capnp.Message) (RegistrationServer_unregisterConnection_Params, error) {\n\troot, err := msg.RootPtr()\n\treturn RegistrationServer_unregisterConnection_Params{root.Struct()}, err\n}\n\nfunc (s RegistrationServer_unregisterConnection_Params) String() string {\n\tstr, _ := text.Marshal(0xf9cb7f4431a307d0, s.Struct)\n\treturn str\n}\n\n// RegistrationServer_unregisterConnection_Params_List is a list of RegistrationServer_unregisterConnection_Params.\ntype RegistrationServer_unregisterConnection_Params_List struct{ capnp.List }\n\n// NewRegistrationServer_unregisterConnection_Params creates a new list of RegistrationServer_unregisterConnection_Params.\nfunc NewRegistrationServer_unregisterConnection_Params_List(s *capnp.Segment, sz int32) (RegistrationServer_unregisterConnection_Params_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0}, sz)\n\treturn RegistrationServer_unregisterConnection_Params_List{l}, err\n}\n\nfunc (s RegistrationServer_unregisterConnection_Params_List) At(i int) RegistrationServer_unregisterConnection_Params {\n\treturn RegistrationServer_unregisterConnection_Params{s.List.Struct(i)}\n}\n\nfunc (s RegistrationServer_unregisterConnection_Params_List) Set(i int, v RegistrationServer_unregisterConnection_Params) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s RegistrationServer_unregisterConnection_Params_List) String() string {\n\tstr, _ := text.MarshalList(0xf9cb7f4431a307d0, s.List)\n\treturn str\n}\n\n// RegistrationServer_unregisterConnection_Params_Promise is a wrapper for a RegistrationServer_unregisterConnection_Params promised by a client call.\ntype RegistrationServer_unregisterConnection_Params_Promise struct{ *capnp.Pipeline }\n\nfunc (p RegistrationServer_unregisterConnection_Params_Promise) Struct() (RegistrationServer_unregisterConnection_Params, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn RegistrationServer_unregisterConnection_Params{s}, err\n}\n\ntype RegistrationServer_unregisterConnection_Results struct{ capnp.Struct }\n\n// RegistrationServer_unregisterConnection_Results_TypeID is the unique identifier for the type RegistrationServer_unregisterConnection_Results.\nconst RegistrationServer_unregisterConnection_Results_TypeID = 0xb046e578094b1ead\n\nfunc NewRegistrationServer_unregisterConnection_Results(s *capnp.Segment) (RegistrationServer_unregisterConnection_Results, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})\n\treturn RegistrationServer_unregisterConnection_Results{st}, err\n}\n\nfunc NewRootRegistrationServer_unregisterConnection_Results(s *capnp.Segment) (RegistrationServer_unregisterConnection_Results, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})\n\treturn RegistrationServer_unregisterConnection_Results{st}, err\n}\n\nfunc ReadRootRegistrationServer_unregisterConnection_Results(msg *capnp.Message) (RegistrationServer_unregisterConnection_Results, error) {\n\troot, err := msg.RootPtr()\n\treturn RegistrationServer_unregisterConnection_Results{root.Struct()}, err\n}\n\nfunc (s RegistrationServer_unregisterConnection_Results) String() string {\n\tstr, _ := text.Marshal(0xb046e578094b1ead, s.Struct)\n\treturn str\n}\n\n// RegistrationServer_unregisterConnection_Results_List is a list of RegistrationServer_unregisterConnection_Results.\ntype RegistrationServer_unregisterConnection_Results_List struct{ capnp.List }\n\n// NewRegistrationServer_unregisterConnection_Results creates a new list of RegistrationServer_unregisterConnection_Results.\nfunc NewRegistrationServer_unregisterConnection_Results_List(s *capnp.Segment, sz int32) (RegistrationServer_unregisterConnection_Results_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0}, sz)\n\treturn RegistrationServer_unregisterConnection_Results_List{l}, err\n}\n\nfunc (s RegistrationServer_unregisterConnection_Results_List) At(i int) RegistrationServer_unregisterConnection_Results {\n\treturn RegistrationServer_unregisterConnection_Results{s.List.Struct(i)}\n}\n\nfunc (s RegistrationServer_unregisterConnection_Results_List) Set(i int, v RegistrationServer_unregisterConnection_Results) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s RegistrationServer_unregisterConnection_Results_List) String() string {\n\tstr, _ := text.MarshalList(0xb046e578094b1ead, s.List)\n\treturn str\n}\n\n// RegistrationServer_unregisterConnection_Results_Promise is a wrapper for a RegistrationServer_unregisterConnection_Results promised by a client call.\ntype RegistrationServer_unregisterConnection_Results_Promise struct{ *capnp.Pipeline }\n\nfunc (p RegistrationServer_unregisterConnection_Results_Promise) Struct() (RegistrationServer_unregisterConnection_Results, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn RegistrationServer_unregisterConnection_Results{s}, err\n}\n\ntype RegistrationServer_updateLocalConfiguration_Params struct{ capnp.Struct }\n\n// RegistrationServer_updateLocalConfiguration_Params_TypeID is the unique identifier for the type RegistrationServer_updateLocalConfiguration_Params.\nconst RegistrationServer_updateLocalConfiguration_Params_TypeID = 0xc5d6e311876a3604\n\nfunc NewRegistrationServer_updateLocalConfiguration_Params(s *capnp.Segment) (RegistrationServer_updateLocalConfiguration_Params, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn RegistrationServer_updateLocalConfiguration_Params{st}, err\n}\n\nfunc NewRootRegistrationServer_updateLocalConfiguration_Params(s *capnp.Segment) (RegistrationServer_updateLocalConfiguration_Params, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn RegistrationServer_updateLocalConfiguration_Params{st}, err\n}\n\nfunc ReadRootRegistrationServer_updateLocalConfiguration_Params(msg *capnp.Message) (RegistrationServer_updateLocalConfiguration_Params, error) {\n\troot, err := msg.RootPtr()\n\treturn RegistrationServer_updateLocalConfiguration_Params{root.Struct()}, err\n}\n\nfunc (s RegistrationServer_updateLocalConfiguration_Params) String() string {\n\tstr, _ := text.Marshal(0xc5d6e311876a3604, s.Struct)\n\treturn str\n}\n\nfunc (s RegistrationServer_updateLocalConfiguration_Params) Config() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s RegistrationServer_updateLocalConfiguration_Params) HasConfig() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s RegistrationServer_updateLocalConfiguration_Params) SetConfig(v []byte) error {\n\treturn s.Struct.SetData(0, v)\n}\n\n// RegistrationServer_updateLocalConfiguration_Params_List is a list of RegistrationServer_updateLocalConfiguration_Params.\ntype RegistrationServer_updateLocalConfiguration_Params_List struct{ capnp.List }\n\n// NewRegistrationServer_updateLocalConfiguration_Params creates a new list of RegistrationServer_updateLocalConfiguration_Params.\nfunc NewRegistrationServer_updateLocalConfiguration_Params_List(s *capnp.Segment, sz int32) (RegistrationServer_updateLocalConfiguration_Params_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz)\n\treturn RegistrationServer_updateLocalConfiguration_Params_List{l}, err\n}\n\nfunc (s RegistrationServer_updateLocalConfiguration_Params_List) At(i int) RegistrationServer_updateLocalConfiguration_Params {\n\treturn RegistrationServer_updateLocalConfiguration_Params{s.List.Struct(i)}\n}\n\nfunc (s RegistrationServer_updateLocalConfiguration_Params_List) Set(i int, v RegistrationServer_updateLocalConfiguration_Params) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s RegistrationServer_updateLocalConfiguration_Params_List) String() string {\n\tstr, _ := text.MarshalList(0xc5d6e311876a3604, s.List)\n\treturn str\n}\n\n// RegistrationServer_updateLocalConfiguration_Params_Promise is a wrapper for a RegistrationServer_updateLocalConfiguration_Params promised by a client call.\ntype RegistrationServer_updateLocalConfiguration_Params_Promise struct{ *capnp.Pipeline }\n\nfunc (p RegistrationServer_updateLocalConfiguration_Params_Promise) Struct() (RegistrationServer_updateLocalConfiguration_Params, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn RegistrationServer_updateLocalConfiguration_Params{s}, err\n}\n\ntype RegistrationServer_updateLocalConfiguration_Results struct{ capnp.Struct }\n\n// RegistrationServer_updateLocalConfiguration_Results_TypeID is the unique identifier for the type RegistrationServer_updateLocalConfiguration_Results.\nconst RegistrationServer_updateLocalConfiguration_Results_TypeID = 0xe5ceae5d6897d7be\n\nfunc NewRegistrationServer_updateLocalConfiguration_Results(s *capnp.Segment) (RegistrationServer_updateLocalConfiguration_Results, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})\n\treturn RegistrationServer_updateLocalConfiguration_Results{st}, err\n}\n\nfunc NewRootRegistrationServer_updateLocalConfiguration_Results(s *capnp.Segment) (RegistrationServer_updateLocalConfiguration_Results, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})\n\treturn RegistrationServer_updateLocalConfiguration_Results{st}, err\n}\n\nfunc ReadRootRegistrationServer_updateLocalConfiguration_Results(msg *capnp.Message) (RegistrationServer_updateLocalConfiguration_Results, error) {\n\troot, err := msg.RootPtr()\n\treturn RegistrationServer_updateLocalConfiguration_Results{root.Struct()}, err\n}\n\nfunc (s RegistrationServer_updateLocalConfiguration_Results) String() string {\n\tstr, _ := text.Marshal(0xe5ceae5d6897d7be, s.Struct)\n\treturn str\n}\n\n// RegistrationServer_updateLocalConfiguration_Results_List is a list of RegistrationServer_updateLocalConfiguration_Results.\ntype RegistrationServer_updateLocalConfiguration_Results_List struct{ capnp.List }\n\n// NewRegistrationServer_updateLocalConfiguration_Results creates a new list of RegistrationServer_updateLocalConfiguration_Results.\nfunc NewRegistrationServer_updateLocalConfiguration_Results_List(s *capnp.Segment, sz int32) (RegistrationServer_updateLocalConfiguration_Results_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0}, sz)\n\treturn RegistrationServer_updateLocalConfiguration_Results_List{l}, err\n}\n\nfunc (s RegistrationServer_updateLocalConfiguration_Results_List) At(i int) RegistrationServer_updateLocalConfiguration_Results {\n\treturn RegistrationServer_updateLocalConfiguration_Results{s.List.Struct(i)}\n}\n\nfunc (s RegistrationServer_updateLocalConfiguration_Results_List) Set(i int, v RegistrationServer_updateLocalConfiguration_Results) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s RegistrationServer_updateLocalConfiguration_Results_List) String() string {\n\tstr, _ := text.MarshalList(0xe5ceae5d6897d7be, s.List)\n\treturn str\n}\n\n// RegistrationServer_updateLocalConfiguration_Results_Promise is a wrapper for a RegistrationServer_updateLocalConfiguration_Results promised by a client call.\ntype RegistrationServer_updateLocalConfiguration_Results_Promise struct{ *capnp.Pipeline }\n\nfunc (p RegistrationServer_updateLocalConfiguration_Results_Promise) Struct() (RegistrationServer_updateLocalConfiguration_Results, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn RegistrationServer_updateLocalConfiguration_Results{s}, err\n}\n\ntype RegisterUdpSessionResponse struct{ capnp.Struct }\n\n// RegisterUdpSessionResponse_TypeID is the unique identifier for the type RegisterUdpSessionResponse.\nconst RegisterUdpSessionResponse_TypeID = 0xab6d5210c1f26687\n\nfunc NewRegisterUdpSessionResponse(s *capnp.Segment) (RegisterUdpSessionResponse, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2})\n\treturn RegisterUdpSessionResponse{st}, err\n}\n\nfunc NewRootRegisterUdpSessionResponse(s *capnp.Segment) (RegisterUdpSessionResponse, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2})\n\treturn RegisterUdpSessionResponse{st}, err\n}\n\nfunc ReadRootRegisterUdpSessionResponse(msg *capnp.Message) (RegisterUdpSessionResponse, error) {\n\troot, err := msg.RootPtr()\n\treturn RegisterUdpSessionResponse{root.Struct()}, err\n}\n\nfunc (s RegisterUdpSessionResponse) String() string {\n\tstr, _ := text.Marshal(0xab6d5210c1f26687, s.Struct)\n\treturn str\n}\n\nfunc (s RegisterUdpSessionResponse) Err() (string, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.Text(), err\n}\n\nfunc (s RegisterUdpSessionResponse) HasErr() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s RegisterUdpSessionResponse) ErrBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.TextBytes(), err\n}\n\nfunc (s RegisterUdpSessionResponse) SetErr(v string) error {\n\treturn s.Struct.SetText(0, v)\n}\n\nfunc (s RegisterUdpSessionResponse) Spans() ([]byte, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s RegisterUdpSessionResponse) HasSpans() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s RegisterUdpSessionResponse) SetSpans(v []byte) error {\n\treturn s.Struct.SetData(1, v)\n}\n\n// RegisterUdpSessionResponse_List is a list of RegisterUdpSessionResponse.\ntype RegisterUdpSessionResponse_List struct{ capnp.List }\n\n// NewRegisterUdpSessionResponse creates a new list of RegisterUdpSessionResponse.\nfunc NewRegisterUdpSessionResponse_List(s *capnp.Segment, sz int32) (RegisterUdpSessionResponse_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}, sz)\n\treturn RegisterUdpSessionResponse_List{l}, err\n}\n\nfunc (s RegisterUdpSessionResponse_List) At(i int) RegisterUdpSessionResponse {\n\treturn RegisterUdpSessionResponse{s.List.Struct(i)}\n}\n\nfunc (s RegisterUdpSessionResponse_List) Set(i int, v RegisterUdpSessionResponse) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s RegisterUdpSessionResponse_List) String() string {\n\tstr, _ := text.MarshalList(0xab6d5210c1f26687, s.List)\n\treturn str\n}\n\n// RegisterUdpSessionResponse_Promise is a wrapper for a RegisterUdpSessionResponse promised by a client call.\ntype RegisterUdpSessionResponse_Promise struct{ *capnp.Pipeline }\n\nfunc (p RegisterUdpSessionResponse_Promise) Struct() (RegisterUdpSessionResponse, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn RegisterUdpSessionResponse{s}, err\n}\n\ntype SessionManager struct{ Client capnp.Client }\n\n// SessionManager_TypeID is the unique identifier for the type SessionManager.\nconst SessionManager_TypeID = 0x839445a59fb01686\n\nfunc (c SessionManager) RegisterUdpSession(ctx context.Context, params func(SessionManager_registerUdpSession_Params) error, opts ...capnp.CallOption) SessionManager_registerUdpSession_Results_Promise {\n\tif c.Client == nil {\n\t\treturn SessionManager_registerUdpSession_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0x839445a59fb01686,\n\t\t\tMethodID:      0,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:SessionManager\",\n\t\t\tMethodName:    \"registerUdpSession\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 16, PointerCount: 3}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error { return params(SessionManager_registerUdpSession_Params{Struct: s}) }\n\t}\n\treturn SessionManager_registerUdpSession_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\nfunc (c SessionManager) UnregisterUdpSession(ctx context.Context, params func(SessionManager_unregisterUdpSession_Params) error, opts ...capnp.CallOption) SessionManager_unregisterUdpSession_Results_Promise {\n\tif c.Client == nil {\n\t\treturn SessionManager_unregisterUdpSession_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0x839445a59fb01686,\n\t\t\tMethodID:      1,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:SessionManager\",\n\t\t\tMethodName:    \"unregisterUdpSession\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 0, PointerCount: 2}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error { return params(SessionManager_unregisterUdpSession_Params{Struct: s}) }\n\t}\n\treturn SessionManager_unregisterUdpSession_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\n\ntype SessionManager_Server interface {\n\tRegisterUdpSession(SessionManager_registerUdpSession) error\n\n\tUnregisterUdpSession(SessionManager_unregisterUdpSession) error\n}\n\nfunc SessionManager_ServerToClient(s SessionManager_Server) SessionManager {\n\tc, _ := s.(server.Closer)\n\treturn SessionManager{Client: server.New(SessionManager_Methods(nil, s), c)}\n}\n\nfunc SessionManager_Methods(methods []server.Method, s SessionManager_Server) []server.Method {\n\tif cap(methods) == 0 {\n\t\tmethods = make([]server.Method, 0, 2)\n\t}\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0x839445a59fb01686,\n\t\t\tMethodID:      0,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:SessionManager\",\n\t\t\tMethodName:    \"registerUdpSession\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := SessionManager_registerUdpSession{c, opts, SessionManager_registerUdpSession_Params{Struct: p}, SessionManager_registerUdpSession_Results{Struct: r}}\n\t\t\treturn s.RegisterUdpSession(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 1},\n\t})\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0x839445a59fb01686,\n\t\t\tMethodID:      1,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:SessionManager\",\n\t\t\tMethodName:    \"unregisterUdpSession\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := SessionManager_unregisterUdpSession{c, opts, SessionManager_unregisterUdpSession_Params{Struct: p}, SessionManager_unregisterUdpSession_Results{Struct: r}}\n\t\t\treturn s.UnregisterUdpSession(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 0},\n\t})\n\n\treturn methods\n}\n\n// SessionManager_registerUdpSession holds the arguments for a server call to SessionManager.registerUdpSession.\ntype SessionManager_registerUdpSession struct {\n\tCtx     context.Context\n\tOptions capnp.CallOptions\n\tParams  SessionManager_registerUdpSession_Params\n\tResults SessionManager_registerUdpSession_Results\n}\n\n// SessionManager_unregisterUdpSession holds the arguments for a server call to SessionManager.unregisterUdpSession.\ntype SessionManager_unregisterUdpSession struct {\n\tCtx     context.Context\n\tOptions capnp.CallOptions\n\tParams  SessionManager_unregisterUdpSession_Params\n\tResults SessionManager_unregisterUdpSession_Results\n}\n\ntype SessionManager_registerUdpSession_Params struct{ capnp.Struct }\n\n// SessionManager_registerUdpSession_Params_TypeID is the unique identifier for the type SessionManager_registerUdpSession_Params.\nconst SessionManager_registerUdpSession_Params_TypeID = 0x904e297b87fbecea\n\nfunc NewSessionManager_registerUdpSession_Params(s *capnp.Segment) (SessionManager_registerUdpSession_Params, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 3})\n\treturn SessionManager_registerUdpSession_Params{st}, err\n}\n\nfunc NewRootSessionManager_registerUdpSession_Params(s *capnp.Segment) (SessionManager_registerUdpSession_Params, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 16, PointerCount: 3})\n\treturn SessionManager_registerUdpSession_Params{st}, err\n}\n\nfunc ReadRootSessionManager_registerUdpSession_Params(msg *capnp.Message) (SessionManager_registerUdpSession_Params, error) {\n\troot, err := msg.RootPtr()\n\treturn SessionManager_registerUdpSession_Params{root.Struct()}, err\n}\n\nfunc (s SessionManager_registerUdpSession_Params) String() string {\n\tstr, _ := text.Marshal(0x904e297b87fbecea, s.Struct)\n\treturn str\n}\n\nfunc (s SessionManager_registerUdpSession_Params) SessionId() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s SessionManager_registerUdpSession_Params) HasSessionId() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s SessionManager_registerUdpSession_Params) SetSessionId(v []byte) error {\n\treturn s.Struct.SetData(0, v)\n}\n\nfunc (s SessionManager_registerUdpSession_Params) DstIp() ([]byte, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s SessionManager_registerUdpSession_Params) HasDstIp() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s SessionManager_registerUdpSession_Params) SetDstIp(v []byte) error {\n\treturn s.Struct.SetData(1, v)\n}\n\nfunc (s SessionManager_registerUdpSession_Params) DstPort() uint16 {\n\treturn s.Struct.Uint16(0)\n}\n\nfunc (s SessionManager_registerUdpSession_Params) SetDstPort(v uint16) {\n\ts.Struct.SetUint16(0, v)\n}\n\nfunc (s SessionManager_registerUdpSession_Params) CloseAfterIdleHint() int64 {\n\treturn int64(s.Struct.Uint64(8))\n}\n\nfunc (s SessionManager_registerUdpSession_Params) SetCloseAfterIdleHint(v int64) {\n\ts.Struct.SetUint64(8, uint64(v))\n}\n\nfunc (s SessionManager_registerUdpSession_Params) TraceContext() (string, error) {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.Text(), err\n}\n\nfunc (s SessionManager_registerUdpSession_Params) HasTraceContext() bool {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s SessionManager_registerUdpSession_Params) TraceContextBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(2)\n\treturn p.TextBytes(), err\n}\n\nfunc (s SessionManager_registerUdpSession_Params) SetTraceContext(v string) error {\n\treturn s.Struct.SetText(2, v)\n}\n\n// SessionManager_registerUdpSession_Params_List is a list of SessionManager_registerUdpSession_Params.\ntype SessionManager_registerUdpSession_Params_List struct{ capnp.List }\n\n// NewSessionManager_registerUdpSession_Params creates a new list of SessionManager_registerUdpSession_Params.\nfunc NewSessionManager_registerUdpSession_Params_List(s *capnp.Segment, sz int32) (SessionManager_registerUdpSession_Params_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 16, PointerCount: 3}, sz)\n\treturn SessionManager_registerUdpSession_Params_List{l}, err\n}\n\nfunc (s SessionManager_registerUdpSession_Params_List) At(i int) SessionManager_registerUdpSession_Params {\n\treturn SessionManager_registerUdpSession_Params{s.List.Struct(i)}\n}\n\nfunc (s SessionManager_registerUdpSession_Params_List) Set(i int, v SessionManager_registerUdpSession_Params) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s SessionManager_registerUdpSession_Params_List) String() string {\n\tstr, _ := text.MarshalList(0x904e297b87fbecea, s.List)\n\treturn str\n}\n\n// SessionManager_registerUdpSession_Params_Promise is a wrapper for a SessionManager_registerUdpSession_Params promised by a client call.\ntype SessionManager_registerUdpSession_Params_Promise struct{ *capnp.Pipeline }\n\nfunc (p SessionManager_registerUdpSession_Params_Promise) Struct() (SessionManager_registerUdpSession_Params, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn SessionManager_registerUdpSession_Params{s}, err\n}\n\ntype SessionManager_registerUdpSession_Results struct{ capnp.Struct }\n\n// SessionManager_registerUdpSession_Results_TypeID is the unique identifier for the type SessionManager_registerUdpSession_Results.\nconst SessionManager_registerUdpSession_Results_TypeID = 0x8635c6b4f45bf5cd\n\nfunc NewSessionManager_registerUdpSession_Results(s *capnp.Segment) (SessionManager_registerUdpSession_Results, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn SessionManager_registerUdpSession_Results{st}, err\n}\n\nfunc NewRootSessionManager_registerUdpSession_Results(s *capnp.Segment) (SessionManager_registerUdpSession_Results, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn SessionManager_registerUdpSession_Results{st}, err\n}\n\nfunc ReadRootSessionManager_registerUdpSession_Results(msg *capnp.Message) (SessionManager_registerUdpSession_Results, error) {\n\troot, err := msg.RootPtr()\n\treturn SessionManager_registerUdpSession_Results{root.Struct()}, err\n}\n\nfunc (s SessionManager_registerUdpSession_Results) String() string {\n\tstr, _ := text.Marshal(0x8635c6b4f45bf5cd, s.Struct)\n\treturn str\n}\n\nfunc (s SessionManager_registerUdpSession_Results) Result() (RegisterUdpSessionResponse, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn RegisterUdpSessionResponse{Struct: p.Struct()}, err\n}\n\nfunc (s SessionManager_registerUdpSession_Results) HasResult() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s SessionManager_registerUdpSession_Results) SetResult(v RegisterUdpSessionResponse) error {\n\treturn s.Struct.SetPtr(0, v.Struct.ToPtr())\n}\n\n// NewResult sets the result field to a newly\n// allocated RegisterUdpSessionResponse struct, preferring placement in s's segment.\nfunc (s SessionManager_registerUdpSession_Results) NewResult() (RegisterUdpSessionResponse, error) {\n\tss, err := NewRegisterUdpSessionResponse(s.Struct.Segment())\n\tif err != nil {\n\t\treturn RegisterUdpSessionResponse{}, err\n\t}\n\terr = s.Struct.SetPtr(0, ss.Struct.ToPtr())\n\treturn ss, err\n}\n\n// SessionManager_registerUdpSession_Results_List is a list of SessionManager_registerUdpSession_Results.\ntype SessionManager_registerUdpSession_Results_List struct{ capnp.List }\n\n// NewSessionManager_registerUdpSession_Results creates a new list of SessionManager_registerUdpSession_Results.\nfunc NewSessionManager_registerUdpSession_Results_List(s *capnp.Segment, sz int32) (SessionManager_registerUdpSession_Results_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz)\n\treturn SessionManager_registerUdpSession_Results_List{l}, err\n}\n\nfunc (s SessionManager_registerUdpSession_Results_List) At(i int) SessionManager_registerUdpSession_Results {\n\treturn SessionManager_registerUdpSession_Results{s.List.Struct(i)}\n}\n\nfunc (s SessionManager_registerUdpSession_Results_List) Set(i int, v SessionManager_registerUdpSession_Results) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s SessionManager_registerUdpSession_Results_List) String() string {\n\tstr, _ := text.MarshalList(0x8635c6b4f45bf5cd, s.List)\n\treturn str\n}\n\n// SessionManager_registerUdpSession_Results_Promise is a wrapper for a SessionManager_registerUdpSession_Results promised by a client call.\ntype SessionManager_registerUdpSession_Results_Promise struct{ *capnp.Pipeline }\n\nfunc (p SessionManager_registerUdpSession_Results_Promise) Struct() (SessionManager_registerUdpSession_Results, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn SessionManager_registerUdpSession_Results{s}, err\n}\n\nfunc (p SessionManager_registerUdpSession_Results_Promise) Result() RegisterUdpSessionResponse_Promise {\n\treturn RegisterUdpSessionResponse_Promise{Pipeline: p.Pipeline.GetPipeline(0)}\n}\n\ntype SessionManager_unregisterUdpSession_Params struct{ capnp.Struct }\n\n// SessionManager_unregisterUdpSession_Params_TypeID is the unique identifier for the type SessionManager_unregisterUdpSession_Params.\nconst SessionManager_unregisterUdpSession_Params_TypeID = 0x96b74375ce9b0ef6\n\nfunc NewSessionManager_unregisterUdpSession_Params(s *capnp.Segment) (SessionManager_unregisterUdpSession_Params, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2})\n\treturn SessionManager_unregisterUdpSession_Params{st}, err\n}\n\nfunc NewRootSessionManager_unregisterUdpSession_Params(s *capnp.Segment) (SessionManager_unregisterUdpSession_Params, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2})\n\treturn SessionManager_unregisterUdpSession_Params{st}, err\n}\n\nfunc ReadRootSessionManager_unregisterUdpSession_Params(msg *capnp.Message) (SessionManager_unregisterUdpSession_Params, error) {\n\troot, err := msg.RootPtr()\n\treturn SessionManager_unregisterUdpSession_Params{root.Struct()}, err\n}\n\nfunc (s SessionManager_unregisterUdpSession_Params) String() string {\n\tstr, _ := text.Marshal(0x96b74375ce9b0ef6, s.Struct)\n\treturn str\n}\n\nfunc (s SessionManager_unregisterUdpSession_Params) SessionId() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s SessionManager_unregisterUdpSession_Params) HasSessionId() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s SessionManager_unregisterUdpSession_Params) SetSessionId(v []byte) error {\n\treturn s.Struct.SetData(0, v)\n}\n\nfunc (s SessionManager_unregisterUdpSession_Params) Message() (string, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.Text(), err\n}\n\nfunc (s SessionManager_unregisterUdpSession_Params) HasMessage() bool {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s SessionManager_unregisterUdpSession_Params) MessageBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(1)\n\treturn p.TextBytes(), err\n}\n\nfunc (s SessionManager_unregisterUdpSession_Params) SetMessage(v string) error {\n\treturn s.Struct.SetText(1, v)\n}\n\n// SessionManager_unregisterUdpSession_Params_List is a list of SessionManager_unregisterUdpSession_Params.\ntype SessionManager_unregisterUdpSession_Params_List struct{ capnp.List }\n\n// NewSessionManager_unregisterUdpSession_Params creates a new list of SessionManager_unregisterUdpSession_Params.\nfunc NewSessionManager_unregisterUdpSession_Params_List(s *capnp.Segment, sz int32) (SessionManager_unregisterUdpSession_Params_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 2}, sz)\n\treturn SessionManager_unregisterUdpSession_Params_List{l}, err\n}\n\nfunc (s SessionManager_unregisterUdpSession_Params_List) At(i int) SessionManager_unregisterUdpSession_Params {\n\treturn SessionManager_unregisterUdpSession_Params{s.List.Struct(i)}\n}\n\nfunc (s SessionManager_unregisterUdpSession_Params_List) Set(i int, v SessionManager_unregisterUdpSession_Params) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s SessionManager_unregisterUdpSession_Params_List) String() string {\n\tstr, _ := text.MarshalList(0x96b74375ce9b0ef6, s.List)\n\treturn str\n}\n\n// SessionManager_unregisterUdpSession_Params_Promise is a wrapper for a SessionManager_unregisterUdpSession_Params promised by a client call.\ntype SessionManager_unregisterUdpSession_Params_Promise struct{ *capnp.Pipeline }\n\nfunc (p SessionManager_unregisterUdpSession_Params_Promise) Struct() (SessionManager_unregisterUdpSession_Params, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn SessionManager_unregisterUdpSession_Params{s}, err\n}\n\ntype SessionManager_unregisterUdpSession_Results struct{ capnp.Struct }\n\n// SessionManager_unregisterUdpSession_Results_TypeID is the unique identifier for the type SessionManager_unregisterUdpSession_Results.\nconst SessionManager_unregisterUdpSession_Results_TypeID = 0xf24ec4ab5891b676\n\nfunc NewSessionManager_unregisterUdpSession_Results(s *capnp.Segment) (SessionManager_unregisterUdpSession_Results, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})\n\treturn SessionManager_unregisterUdpSession_Results{st}, err\n}\n\nfunc NewRootSessionManager_unregisterUdpSession_Results(s *capnp.Segment) (SessionManager_unregisterUdpSession_Results, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})\n\treturn SessionManager_unregisterUdpSession_Results{st}, err\n}\n\nfunc ReadRootSessionManager_unregisterUdpSession_Results(msg *capnp.Message) (SessionManager_unregisterUdpSession_Results, error) {\n\troot, err := msg.RootPtr()\n\treturn SessionManager_unregisterUdpSession_Results{root.Struct()}, err\n}\n\nfunc (s SessionManager_unregisterUdpSession_Results) String() string {\n\tstr, _ := text.Marshal(0xf24ec4ab5891b676, s.Struct)\n\treturn str\n}\n\n// SessionManager_unregisterUdpSession_Results_List is a list of SessionManager_unregisterUdpSession_Results.\ntype SessionManager_unregisterUdpSession_Results_List struct{ capnp.List }\n\n// NewSessionManager_unregisterUdpSession_Results creates a new list of SessionManager_unregisterUdpSession_Results.\nfunc NewSessionManager_unregisterUdpSession_Results_List(s *capnp.Segment, sz int32) (SessionManager_unregisterUdpSession_Results_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0}, sz)\n\treturn SessionManager_unregisterUdpSession_Results_List{l}, err\n}\n\nfunc (s SessionManager_unregisterUdpSession_Results_List) At(i int) SessionManager_unregisterUdpSession_Results {\n\treturn SessionManager_unregisterUdpSession_Results{s.List.Struct(i)}\n}\n\nfunc (s SessionManager_unregisterUdpSession_Results_List) Set(i int, v SessionManager_unregisterUdpSession_Results) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s SessionManager_unregisterUdpSession_Results_List) String() string {\n\tstr, _ := text.MarshalList(0xf24ec4ab5891b676, s.List)\n\treturn str\n}\n\n// SessionManager_unregisterUdpSession_Results_Promise is a wrapper for a SessionManager_unregisterUdpSession_Results promised by a client call.\ntype SessionManager_unregisterUdpSession_Results_Promise struct{ *capnp.Pipeline }\n\nfunc (p SessionManager_unregisterUdpSession_Results_Promise) Struct() (SessionManager_unregisterUdpSession_Results, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn SessionManager_unregisterUdpSession_Results{s}, err\n}\n\ntype UpdateConfigurationResponse struct{ capnp.Struct }\n\n// UpdateConfigurationResponse_TypeID is the unique identifier for the type UpdateConfigurationResponse.\nconst UpdateConfigurationResponse_TypeID = 0xdb58ff694ba05cf9\n\nfunc NewUpdateConfigurationResponse(s *capnp.Segment) (UpdateConfigurationResponse, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})\n\treturn UpdateConfigurationResponse{st}, err\n}\n\nfunc NewRootUpdateConfigurationResponse(s *capnp.Segment) (UpdateConfigurationResponse, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})\n\treturn UpdateConfigurationResponse{st}, err\n}\n\nfunc ReadRootUpdateConfigurationResponse(msg *capnp.Message) (UpdateConfigurationResponse, error) {\n\troot, err := msg.RootPtr()\n\treturn UpdateConfigurationResponse{root.Struct()}, err\n}\n\nfunc (s UpdateConfigurationResponse) String() string {\n\tstr, _ := text.Marshal(0xdb58ff694ba05cf9, s.Struct)\n\treturn str\n}\n\nfunc (s UpdateConfigurationResponse) LatestAppliedVersion() int32 {\n\treturn int32(s.Struct.Uint32(0))\n}\n\nfunc (s UpdateConfigurationResponse) SetLatestAppliedVersion(v int32) {\n\ts.Struct.SetUint32(0, uint32(v))\n}\n\nfunc (s UpdateConfigurationResponse) Err() (string, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.Text(), err\n}\n\nfunc (s UpdateConfigurationResponse) HasErr() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s UpdateConfigurationResponse) ErrBytes() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.TextBytes(), err\n}\n\nfunc (s UpdateConfigurationResponse) SetErr(v string) error {\n\treturn s.Struct.SetText(0, v)\n}\n\n// UpdateConfigurationResponse_List is a list of UpdateConfigurationResponse.\ntype UpdateConfigurationResponse_List struct{ capnp.List }\n\n// NewUpdateConfigurationResponse creates a new list of UpdateConfigurationResponse.\nfunc NewUpdateConfigurationResponse_List(s *capnp.Segment, sz int32) (UpdateConfigurationResponse_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz)\n\treturn UpdateConfigurationResponse_List{l}, err\n}\n\nfunc (s UpdateConfigurationResponse_List) At(i int) UpdateConfigurationResponse {\n\treturn UpdateConfigurationResponse{s.List.Struct(i)}\n}\n\nfunc (s UpdateConfigurationResponse_List) Set(i int, v UpdateConfigurationResponse) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s UpdateConfigurationResponse_List) String() string {\n\tstr, _ := text.MarshalList(0xdb58ff694ba05cf9, s.List)\n\treturn str\n}\n\n// UpdateConfigurationResponse_Promise is a wrapper for a UpdateConfigurationResponse promised by a client call.\ntype UpdateConfigurationResponse_Promise struct{ *capnp.Pipeline }\n\nfunc (p UpdateConfigurationResponse_Promise) Struct() (UpdateConfigurationResponse, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn UpdateConfigurationResponse{s}, err\n}\n\ntype ConfigurationManager struct{ Client capnp.Client }\n\n// ConfigurationManager_TypeID is the unique identifier for the type ConfigurationManager.\nconst ConfigurationManager_TypeID = 0xb48edfbdaa25db04\n\nfunc (c ConfigurationManager) UpdateConfiguration(ctx context.Context, params func(ConfigurationManager_updateConfiguration_Params) error, opts ...capnp.CallOption) ConfigurationManager_updateConfiguration_Results_Promise {\n\tif c.Client == nil {\n\t\treturn ConfigurationManager_updateConfiguration_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xb48edfbdaa25db04,\n\t\t\tMethodID:      0,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:ConfigurationManager\",\n\t\t\tMethodName:    \"updateConfiguration\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 8, PointerCount: 1}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error { return params(ConfigurationManager_updateConfiguration_Params{Struct: s}) }\n\t}\n\treturn ConfigurationManager_updateConfiguration_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\n\ntype ConfigurationManager_Server interface {\n\tUpdateConfiguration(ConfigurationManager_updateConfiguration) error\n}\n\nfunc ConfigurationManager_ServerToClient(s ConfigurationManager_Server) ConfigurationManager {\n\tc, _ := s.(server.Closer)\n\treturn ConfigurationManager{Client: server.New(ConfigurationManager_Methods(nil, s), c)}\n}\n\nfunc ConfigurationManager_Methods(methods []server.Method, s ConfigurationManager_Server) []server.Method {\n\tif cap(methods) == 0 {\n\t\tmethods = make([]server.Method, 0, 1)\n\t}\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xb48edfbdaa25db04,\n\t\t\tMethodID:      0,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:ConfigurationManager\",\n\t\t\tMethodName:    \"updateConfiguration\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := ConfigurationManager_updateConfiguration{c, opts, ConfigurationManager_updateConfiguration_Params{Struct: p}, ConfigurationManager_updateConfiguration_Results{Struct: r}}\n\t\t\treturn s.UpdateConfiguration(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 1},\n\t})\n\n\treturn methods\n}\n\n// ConfigurationManager_updateConfiguration holds the arguments for a server call to ConfigurationManager.updateConfiguration.\ntype ConfigurationManager_updateConfiguration struct {\n\tCtx     context.Context\n\tOptions capnp.CallOptions\n\tParams  ConfigurationManager_updateConfiguration_Params\n\tResults ConfigurationManager_updateConfiguration_Results\n}\n\ntype ConfigurationManager_updateConfiguration_Params struct{ capnp.Struct }\n\n// ConfigurationManager_updateConfiguration_Params_TypeID is the unique identifier for the type ConfigurationManager_updateConfiguration_Params.\nconst ConfigurationManager_updateConfiguration_Params_TypeID = 0xb177ca2526a3ca76\n\nfunc NewConfigurationManager_updateConfiguration_Params(s *capnp.Segment) (ConfigurationManager_updateConfiguration_Params, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})\n\treturn ConfigurationManager_updateConfiguration_Params{st}, err\n}\n\nfunc NewRootConfigurationManager_updateConfiguration_Params(s *capnp.Segment) (ConfigurationManager_updateConfiguration_Params, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})\n\treturn ConfigurationManager_updateConfiguration_Params{st}, err\n}\n\nfunc ReadRootConfigurationManager_updateConfiguration_Params(msg *capnp.Message) (ConfigurationManager_updateConfiguration_Params, error) {\n\troot, err := msg.RootPtr()\n\treturn ConfigurationManager_updateConfiguration_Params{root.Struct()}, err\n}\n\nfunc (s ConfigurationManager_updateConfiguration_Params) String() string {\n\tstr, _ := text.Marshal(0xb177ca2526a3ca76, s.Struct)\n\treturn str\n}\n\nfunc (s ConfigurationManager_updateConfiguration_Params) Version() int32 {\n\treturn int32(s.Struct.Uint32(0))\n}\n\nfunc (s ConfigurationManager_updateConfiguration_Params) SetVersion(v int32) {\n\ts.Struct.SetUint32(0, uint32(v))\n}\n\nfunc (s ConfigurationManager_updateConfiguration_Params) Config() ([]byte, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn []byte(p.Data()), err\n}\n\nfunc (s ConfigurationManager_updateConfiguration_Params) HasConfig() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ConfigurationManager_updateConfiguration_Params) SetConfig(v []byte) error {\n\treturn s.Struct.SetData(0, v)\n}\n\n// ConfigurationManager_updateConfiguration_Params_List is a list of ConfigurationManager_updateConfiguration_Params.\ntype ConfigurationManager_updateConfiguration_Params_List struct{ capnp.List }\n\n// NewConfigurationManager_updateConfiguration_Params creates a new list of ConfigurationManager_updateConfiguration_Params.\nfunc NewConfigurationManager_updateConfiguration_Params_List(s *capnp.Segment, sz int32) (ConfigurationManager_updateConfiguration_Params_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz)\n\treturn ConfigurationManager_updateConfiguration_Params_List{l}, err\n}\n\nfunc (s ConfigurationManager_updateConfiguration_Params_List) At(i int) ConfigurationManager_updateConfiguration_Params {\n\treturn ConfigurationManager_updateConfiguration_Params{s.List.Struct(i)}\n}\n\nfunc (s ConfigurationManager_updateConfiguration_Params_List) Set(i int, v ConfigurationManager_updateConfiguration_Params) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s ConfigurationManager_updateConfiguration_Params_List) String() string {\n\tstr, _ := text.MarshalList(0xb177ca2526a3ca76, s.List)\n\treturn str\n}\n\n// ConfigurationManager_updateConfiguration_Params_Promise is a wrapper for a ConfigurationManager_updateConfiguration_Params promised by a client call.\ntype ConfigurationManager_updateConfiguration_Params_Promise struct{ *capnp.Pipeline }\n\nfunc (p ConfigurationManager_updateConfiguration_Params_Promise) Struct() (ConfigurationManager_updateConfiguration_Params, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn ConfigurationManager_updateConfiguration_Params{s}, err\n}\n\ntype ConfigurationManager_updateConfiguration_Results struct{ capnp.Struct }\n\n// ConfigurationManager_updateConfiguration_Results_TypeID is the unique identifier for the type ConfigurationManager_updateConfiguration_Results.\nconst ConfigurationManager_updateConfiguration_Results_TypeID = 0x958096448eb3373e\n\nfunc NewConfigurationManager_updateConfiguration_Results(s *capnp.Segment) (ConfigurationManager_updateConfiguration_Results, error) {\n\tst, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn ConfigurationManager_updateConfiguration_Results{st}, err\n}\n\nfunc NewRootConfigurationManager_updateConfiguration_Results(s *capnp.Segment) (ConfigurationManager_updateConfiguration_Results, error) {\n\tst, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})\n\treturn ConfigurationManager_updateConfiguration_Results{st}, err\n}\n\nfunc ReadRootConfigurationManager_updateConfiguration_Results(msg *capnp.Message) (ConfigurationManager_updateConfiguration_Results, error) {\n\troot, err := msg.RootPtr()\n\treturn ConfigurationManager_updateConfiguration_Results{root.Struct()}, err\n}\n\nfunc (s ConfigurationManager_updateConfiguration_Results) String() string {\n\tstr, _ := text.Marshal(0x958096448eb3373e, s.Struct)\n\treturn str\n}\n\nfunc (s ConfigurationManager_updateConfiguration_Results) Result() (UpdateConfigurationResponse, error) {\n\tp, err := s.Struct.Ptr(0)\n\treturn UpdateConfigurationResponse{Struct: p.Struct()}, err\n}\n\nfunc (s ConfigurationManager_updateConfiguration_Results) HasResult() bool {\n\tp, err := s.Struct.Ptr(0)\n\treturn p.IsValid() || err != nil\n}\n\nfunc (s ConfigurationManager_updateConfiguration_Results) SetResult(v UpdateConfigurationResponse) error {\n\treturn s.Struct.SetPtr(0, v.Struct.ToPtr())\n}\n\n// NewResult sets the result field to a newly\n// allocated UpdateConfigurationResponse struct, preferring placement in s's segment.\nfunc (s ConfigurationManager_updateConfiguration_Results) NewResult() (UpdateConfigurationResponse, error) {\n\tss, err := NewUpdateConfigurationResponse(s.Struct.Segment())\n\tif err != nil {\n\t\treturn UpdateConfigurationResponse{}, err\n\t}\n\terr = s.Struct.SetPtr(0, ss.Struct.ToPtr())\n\treturn ss, err\n}\n\n// ConfigurationManager_updateConfiguration_Results_List is a list of ConfigurationManager_updateConfiguration_Results.\ntype ConfigurationManager_updateConfiguration_Results_List struct{ capnp.List }\n\n// NewConfigurationManager_updateConfiguration_Results creates a new list of ConfigurationManager_updateConfiguration_Results.\nfunc NewConfigurationManager_updateConfiguration_Results_List(s *capnp.Segment, sz int32) (ConfigurationManager_updateConfiguration_Results_List, error) {\n\tl, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz)\n\treturn ConfigurationManager_updateConfiguration_Results_List{l}, err\n}\n\nfunc (s ConfigurationManager_updateConfiguration_Results_List) At(i int) ConfigurationManager_updateConfiguration_Results {\n\treturn ConfigurationManager_updateConfiguration_Results{s.List.Struct(i)}\n}\n\nfunc (s ConfigurationManager_updateConfiguration_Results_List) Set(i int, v ConfigurationManager_updateConfiguration_Results) error {\n\treturn s.List.SetStruct(i, v.Struct)\n}\n\nfunc (s ConfigurationManager_updateConfiguration_Results_List) String() string {\n\tstr, _ := text.MarshalList(0x958096448eb3373e, s.List)\n\treturn str\n}\n\n// ConfigurationManager_updateConfiguration_Results_Promise is a wrapper for a ConfigurationManager_updateConfiguration_Results promised by a client call.\ntype ConfigurationManager_updateConfiguration_Results_Promise struct{ *capnp.Pipeline }\n\nfunc (p ConfigurationManager_updateConfiguration_Results_Promise) Struct() (ConfigurationManager_updateConfiguration_Results, error) {\n\ts, err := p.Pipeline.Struct()\n\treturn ConfigurationManager_updateConfiguration_Results{s}, err\n}\n\nfunc (p ConfigurationManager_updateConfiguration_Results_Promise) Result() UpdateConfigurationResponse_Promise {\n\treturn UpdateConfigurationResponse_Promise{Pipeline: p.Pipeline.GetPipeline(0)}\n}\n\ntype CloudflaredServer struct{ Client capnp.Client }\n\n// CloudflaredServer_TypeID is the unique identifier for the type CloudflaredServer.\nconst CloudflaredServer_TypeID = 0xf548cef9dea2a4a1\n\nfunc (c CloudflaredServer) RegisterUdpSession(ctx context.Context, params func(SessionManager_registerUdpSession_Params) error, opts ...capnp.CallOption) SessionManager_registerUdpSession_Results_Promise {\n\tif c.Client == nil {\n\t\treturn SessionManager_registerUdpSession_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0x839445a59fb01686,\n\t\t\tMethodID:      0,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:SessionManager\",\n\t\t\tMethodName:    \"registerUdpSession\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 16, PointerCount: 3}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error { return params(SessionManager_registerUdpSession_Params{Struct: s}) }\n\t}\n\treturn SessionManager_registerUdpSession_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\nfunc (c CloudflaredServer) UnregisterUdpSession(ctx context.Context, params func(SessionManager_unregisterUdpSession_Params) error, opts ...capnp.CallOption) SessionManager_unregisterUdpSession_Results_Promise {\n\tif c.Client == nil {\n\t\treturn SessionManager_unregisterUdpSession_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0x839445a59fb01686,\n\t\t\tMethodID:      1,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:SessionManager\",\n\t\t\tMethodName:    \"unregisterUdpSession\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 0, PointerCount: 2}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error { return params(SessionManager_unregisterUdpSession_Params{Struct: s}) }\n\t}\n\treturn SessionManager_unregisterUdpSession_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\nfunc (c CloudflaredServer) UpdateConfiguration(ctx context.Context, params func(ConfigurationManager_updateConfiguration_Params) error, opts ...capnp.CallOption) ConfigurationManager_updateConfiguration_Results_Promise {\n\tif c.Client == nil {\n\t\treturn ConfigurationManager_updateConfiguration_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}\n\t}\n\tcall := &capnp.Call{\n\t\tCtx: ctx,\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xb48edfbdaa25db04,\n\t\t\tMethodID:      0,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:ConfigurationManager\",\n\t\t\tMethodName:    \"updateConfiguration\",\n\t\t},\n\t\tOptions: capnp.NewCallOptions(opts),\n\t}\n\tif params != nil {\n\t\tcall.ParamsSize = capnp.ObjectSize{DataSize: 8, PointerCount: 1}\n\t\tcall.ParamsFunc = func(s capnp.Struct) error { return params(ConfigurationManager_updateConfiguration_Params{Struct: s}) }\n\t}\n\treturn ConfigurationManager_updateConfiguration_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}\n}\n\ntype CloudflaredServer_Server interface {\n\tRegisterUdpSession(SessionManager_registerUdpSession) error\n\n\tUnregisterUdpSession(SessionManager_unregisterUdpSession) error\n\n\tUpdateConfiguration(ConfigurationManager_updateConfiguration) error\n}\n\nfunc CloudflaredServer_ServerToClient(s CloudflaredServer_Server) CloudflaredServer {\n\tc, _ := s.(server.Closer)\n\treturn CloudflaredServer{Client: server.New(CloudflaredServer_Methods(nil, s), c)}\n}\n\nfunc CloudflaredServer_Methods(methods []server.Method, s CloudflaredServer_Server) []server.Method {\n\tif cap(methods) == 0 {\n\t\tmethods = make([]server.Method, 0, 3)\n\t}\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0x839445a59fb01686,\n\t\t\tMethodID:      0,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:SessionManager\",\n\t\t\tMethodName:    \"registerUdpSession\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := SessionManager_registerUdpSession{c, opts, SessionManager_registerUdpSession_Params{Struct: p}, SessionManager_registerUdpSession_Results{Struct: r}}\n\t\t\treturn s.RegisterUdpSession(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 1},\n\t})\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0x839445a59fb01686,\n\t\t\tMethodID:      1,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:SessionManager\",\n\t\t\tMethodName:    \"unregisterUdpSession\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := SessionManager_unregisterUdpSession{c, opts, SessionManager_unregisterUdpSession_Params{Struct: p}, SessionManager_unregisterUdpSession_Results{Struct: r}}\n\t\t\treturn s.UnregisterUdpSession(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 0},\n\t})\n\n\tmethods = append(methods, server.Method{\n\t\tMethod: capnp.Method{\n\t\t\tInterfaceID:   0xb48edfbdaa25db04,\n\t\t\tMethodID:      0,\n\t\t\tInterfaceName: \"tunnelrpc/proto/tunnelrpc.capnp:ConfigurationManager\",\n\t\t\tMethodName:    \"updateConfiguration\",\n\t\t},\n\t\tImpl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {\n\t\t\tcall := ConfigurationManager_updateConfiguration{c, opts, ConfigurationManager_updateConfiguration_Params{Struct: p}, ConfigurationManager_updateConfiguration_Results{Struct: r}}\n\t\t\treturn s.UpdateConfiguration(call)\n\t\t},\n\t\tResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 1},\n\t})\n\n\treturn methods\n}\n\nconst schema_db8274f9144abc7e = \"x\\xda\\xccZ}t\\x14\\xd7u\\xbfw\\xde.#\\xc9\\x12\" +\n\t\"\\xbb\\xe3\\xd9\\x04!E^G\\x07\\xda\\x9a\\x04cAIm\" +\n\t\"\\x9aD\\x12\\x96\\x88\\x85\\x01k\\xb4\\x90\\xe3\\x83q\\x8eG\\xbb\" +\n\t\"O\\xd2\\xa8\\xbb3\\x9b\\x99Y\\x19\\x11;|\\x04\\x8c\\xf1\\xb1\" +\n\t\"\\x1dC\\xc06Jh\\x08\\x8e\\xdbS9IM\\x8c\\x9b\\xa6\" +\n\t\"\\xc7nM\\x1a\\xc7\\x89\\x1d\\x13\\xe3cR\\x08N\\xd3\\x94\\xd0\" +\n\t\"6>\\xa4\\xae\\xbf\\x9a\\xc3i\\xea\\xe9\\xb93;\\x1f\\xda\\x15\" +\n\t\"H\\x82\\xf6\\x9c\\xfe\\x07w\\xef\\xbc\\xf7\\xee\\xef\\xfd\\xee}\\xbf\" +\n\t\"w\\x9f\\xae{\\xb1\\xb6Ch\\x8boN\\x00(G\\xe2\\xb3\" +\n\t\"\\x1c\\xbe\\xe0\\xd5M\\x07\\xe7\\xff\\xfd6P\\xaeFt>\\xff\" +\n\t\"\\xcc\\xca\\xd4y{\\xdbi\\x883\\x11`\\xc9\\xe3\\xe28\\xca\" +\n\t\"\\xcf\\x8a\\\"\\x80\\xfc]\\xf1_\\x01\\x9d{>\\xf8\\xe4W\\x1f\" +\n\t\"\\xef\\xde\\xfb\\x05\\x90\\xaef\\xa13\\xe0\\x92\\x035\\x9bP>\" +\n\t\"\\\\C\\x9e\\xdf\\xac\\xd9)7\\xd4\\x8a\\x00\\xce\\xcd\\xd2\\xa2\\xdb\" +\n\t\"R\\xaf\\x1c#\\xef\\xe8\\xd01\\x1a\\xfa\\xbd\\x9a\\xf5(\\xd7\\x92\" +\n\t\"\\x9b\\x1c\\xaf\\xa5\\xa1?^\\xf8\\xc9\\xa1\\x8f\\xed{i;H\" +\n\t\"W\\x0b\\x13\\x86~\\xabv\\x1c\\xe5\\xda:\\xd7\\xb3\\xee\\x16@\" +\n\t\"\\xe7\\x9d\\xbd\\x8dO|\\xed\\xd8\\x0fw\\x80\\xb4\\x10\\xa1\\xbc\\xd2\" +\n\t\"\\x96\\xba:\\x01P^Z\\xf7\\x97\\x80\\xce\\xcb\\xef\\xdd\\xf6\\xee\" +\n\t\"\\x91\\x1f,\\xbd\\x07\\xa4E\\xe4\\x80\\xe4p\\xa2\\xae\\x8f\\x1c\\xde\" +\n\t\"\\xaak\\x07t\\xde8\\xf7_;?w\\xcd\\x9a\\x87@Y\" +\n\t\"\\x84\\x82?\\x84t\\xc5J\\x01p\\xc9\\xc2+\\xd2\\x08\\xe8\\xb4\" +\n\t\"\\xafx\\xf9\\xbbMK\\x1e\\xde[\\xb1v\\x81<\\x95\\xfa\\xf5\" +\n\t\"(\\xf3zZ\\x91Z\\x7f'\\xa0\\xf3\\xc9?z\\xea\\xc1\\xae\" +\n\t\"\\x87\\xb7\\xec\\x03ii0\\xe1\\xf3\\xf5\\xf7\\xd1\\x84g\\xebi\" +\n\t\"\\xc2\\xff\\x9c\\xfd\\xe5c\\xa5\\x1b\\xbf\\xf3pyE\\xee(\\xf1\" +\n\t\"\\x86\\xf5\\xe4\\xf0\\xe1\\x06\\x1a\\xa1ud\\xfe\\x1d\\xdf{\\xfe\\xa9\" +\n\t\"G@Y\\x82\\xe8\\xbc\\xde\\xff\\x91\\x13\\xec\\xc0\\xf8iX\\x87\" +\n\t\"\\\"-p\\xc9\\xd6\\x86W\\x11P\\xde\\xe7\\xfa\\xfe\\xe4\\xa3\\xcf\" +\n\t\"\\xfc\\xcdCO\\xed\\xfc2(\\x0b\\x11\\x01\\\\8\\xcf7,\" +\n\t\"\\xa0\\xc1\\xa4\\xd94\\xdb\\xde\\x93\\xcf\\xae)\\xec\\x1e;\\xe4\\x01\" +\n\t\"\\xe4\\xfe~\\xc3\\xec\\xc5\\x02\\xc4\\x9c\\xed=\\xbf-\\xac{,\" +\n\t\"\\xf3X\\x19\\xba8\\xfd\\xd46\\xbb\\x95\\xe2\\xee\\x99\\xed\\xc6\\xbd\" +\n\t\"\\xf4ggoY\\xfd\\xed\\x81?\\x8f|\\xcb\\x13\\xe3\\xf4\\xed\" +\n\t\"\\xce\\x81\\xb7\\x8f&\\xfb\\x0aOL\\x86\\x08O\\xfc\\x0c\\xe5\\xad\" +\n\t\"\\x09B\\xe4\\xee\\x04\\xad\\xf1\\x9bW\\xdd\\\\\\xbb\\xf1\\xec\\x8a'\" +\n\t\"AZ\\xe2\\x0fs*\\xb1\\x8d\\x86\\x19y\\xf1\\xb1\\xdf\\x9b\\xff\" +\n\t\"\\xe2\\x9d\\x87AY\\x8a\\xe1\\xee\\xd0o(\\xbf\\xe5~\\x1b;\" +\n\t\"=\\x7f\\xfc\\xd9_<x\\xa4\\x8ad\\xab\\x93\\xe3(\\xf3\\xa4\" +\n\t\"\\x8b{\\xf2S\\xf2n\\xfa\\x97\\x13\\xbb\\x9d\\xbd\\xaf>\\xfaw\" +\n\t\"G*\\x09\\xec\\xaek4\\xb9\\x07=\\xbf%\\x0f$\\xdd\\xf8\" +\n\t\"\\xee;:\\xf6\\x91\\x9a\\xaf\\xbe\\xf3\\xf4\\xa4\\xeeOK{P\" +\n\t\"~Y\\xa2\\x09~$\\x11\\x93>\\xd0\\x83\\xaf?\\xd7\\x16\\xfb\" +\n\t\"N\\x94j\\x85+\\x9bh\\xad;\\xae$\\x87\\x96\\xdf,o\" +\n\t\"\\xd0\\xdf\\xdc\\xf6\\\\\\x05(\\xae\\xe3|y\\x13\\xca7\\xc84\" +\n\t\"\\xdaR\\x99\\x9cc\\x1f\\x1b\\xde)\\x9d\\xf9\\xe9\\xf3\\x1e(^\" +\n\t\"\\xe4\\xc7\\xe517r\\x996n\\xe5m_\\xda\\x13?\\xfb\" +\n\t\"\\xa5\\x17hq\\x91$\\x88\\xd7\\xb8\\xfcL\\x1dB\\xf9\\x9a\\x94\" +\n\t\";rj\\x0e\\x03t\\x9a\\x9e\\xfc\\xe3o-\\xcf\\x9dzi\" +\n\t\"\\xb2\\x1dy|N+\\xcaO\\xcf\\xa1\\xc9\\x0f\\xcf!T\\xcf\" +\n\t\",<\\xfc\\xb9_?p\\xfc\\xb5r(\\xee\\xe4\\x0d\\x8d.\" +\n\t\"k\\xe67\\xd2\\xe4\\xe77\\x1c\\xbcYsn=]\\x89\\x8c\" +\n\t\"\\xeb\\xd9\\xdd\\xf8\\xcf(\\xab\\x8d4\\xdc\\xed\\x8d4\\\\@\\xd1\" +\n\t\"\\xc9\\xbc\\x8f6\\x8e\\xa1|\\xca\\xf5>\\xe1\\x8e-\\x9cU\\xe7\" +\n\t\"n\\xf9\\xe9'_\\x8f\\xb0\\xeaT\\xe3\\x95D\\x875\\x9f\\xbe\" +\n\t\"m\\xb8\\xf6\\xee3g\\xa2\\xcb:\\xde\\xe8\\\"\\xfck\\xf7\\xd3\" +\n\t\"\\xbf\\xfd\\x87G\\x86n\\xff\\xd6\\xb1\\xb3\\x11&\\xd5\\xce=D\" +\n\t\"\\x9f\\xfe\\xfb\\x9f\\xbd\\xf1\\xc5s\\x85\\xdc\\xbf\\xb89\\xe3\\xefN\" +\n\t\"\\xed\\xdca7\\xa4\\xb9TS\\xe6\\xa4\\x1b\\xba[O\\xf6\\xbe\" +\n\t\"\\x11\\x05\\x1c\\x9bLrhi\\xa2\\xc1\\x97\\xde\\xd1\\xc97\\\\\" +\n\t\"\\x7f\\xeb\\x1bUT\\xfbD\\xd30\\xcaJ\\x13}\\xb0\\xbai\" +\n\t\"'\\xca\\xbcy\\x0e\\x803\\xf2W\\xbbo}\\xe2\\xfbk\\xde\" +\n\t\"\\xf6\\xd2\\xd8]\\xcb\\xba\\xe6~Z\\xcb\\x83\\x9f\\xef\\xba\\xe5\\x86\" +\n\t\"\\xd6\\xa3oG\\xc3P\\x9a)\\xb1d\\xad\\x99f\\x1a\\xb8\\xfe\" +\n\t\"\\xdc\\xa7\\xe6?\\xf8\\x83\\xb7+\\xf6\\xcau\\xdc\\xd5\\xbc\\x1e\\xe5\" +\n\t\"\\x03\\xcd\\x04\\xd7~r~s\\xc5\\x9f\\xbe\\xd6\\x94hz\\xb7\" +\n\t\"\\x02\\xdaY\\xe4\\xfbl\\xf3\\x18\\xca'\\x9a]\\x98\\x9a_ \" +\n\t\"F\\x7f\\xed\\xeb\\x87\\xfe\\xf1\\xfc\\xb1\\x9b\\xde\\xab\\x8a\\xe1\\xf9\\x96\" +\n\t\"=(\\xff\\xbc\\x85\\x86=\\xd5\\\"\\xca\\xa7Z~\\x1f\\xc0\\xb9\" +\n\t\"\\xe7\\xf4g6\\xbe\\xfa\\x85w\\xde\\xab\\xa4\\x98\\x07|\\xcb6\" +\n\t\"\\x94\\xcf\\xba_\\xfc\\xb2\\x85\\x18\\xfb\\xc8\\xda\\x7f\\xdb|n\\xdf\" +\n\t\"\\x07\\x7f[5\\xf6\\xd6\\xab\\xc6P\\xde\\x7f\\x15y\\xee\\xbb\\xea\" +\n\t\"\\x05\\xf9\\x9a4\\xa5\\xe2+\\xe2cm]\\x9b_:\\x1f\\xd9\" +\n\t\"*)\\xbd\\x89\\xe0yX\\xfc\\xca\\x99-\\xbf\\xf8\\xcc\\xef&\" +\n\t\"\\x90/}\\xa5\\xbbSi\\x82\\xe7\\xae7\\xf7\\xdf\\xf4\\xc5\\x0d\" +\n\t\"\\xdfx?B\\x90\\xee\\xf4\\xb7\\xe9S\\xbb\\xa4\\xeb<o\\x16\" +\n\t\"\\xe3\\xd9EE\\xd3\\xb0\\x8dE\\xbe!{mV-\\xea\\xc5\" +\n\t\"e\\x9d%{\\x88\\xeb\\xb6\\x96Um\\xde\\xc7\\xadb\\xc2\\xd0\" +\n\t\"-\\xde\\x8b\\xa8$Y\\x0c \\x86\\x00\\x92:\\x0c\\xa0\\xdc\\xc1\" +\n\t\"P\\xc9\\x0b(!\\xa6\\x88.\\x92F\\xc6!\\x86\\x8a-\\xa0\" +\n\t\"$\\x08)*\\xb4\\xd2g[\\x01\\x94<Ce\\xa3\\x80\\xc8\" +\n\t\"R\\xc8\\x00\\xa4\\xd2\\x1e\\x00e#Ce\\xbb\\x80N\\x91\\x9b\" +\n\t\"\\x05U\\xe7:$\\xecn\\xd3\\xc4z\\x10\\xb0\\x1e\\xd01\\xb9\" +\n\t\"m\\x8e\\xaa\\xfdyH\\xf0\\x88Y\\x1c\\xbe\\xd3\\xc6\\x06\\x10\\xb0\" +\n\t\"\\x01\\xd0\\x192J\\xa6\\xb5N\\xb7Q\\xcb\\xf7\\xf1\\x01\\x93[\" +\n\t\"8\\x84\\xb3@\\xc0Y\\x80A\\x90\\xb1\\x0b\\x05\\x99\\xe1\\x96\\xa5\" +\n\t\"\\x19\\xfa\\xeavUW\\x07\\xb9I\\xe1\\xd5\\xb08@p\\x94\" +\n\t\"\\xa1\\x7f\\xe8Imc H\\x0bE\\x0cO\\x1d\\xf4y+\" +\n\t\"}x\\x1c\\x04\\xa9EtL>\\xa8Y67q]\\xae\" +\n\t\"\\xe8\\x0e\\xcd\\x0c\\xbd\\x03\\x9d\\x92\\xee\\xfd\\x80\\xdc\\xf4~H\\xd0\" +\n\t\"\\xa4\\x1d\\xd8\\x8b\\xd3X\\xe2\\x8dy\\x8d\\xebv\\x8f\\xce\\x06\\x8c\" +\n\t\"\\x0a\\xf4WN\\x86\\xfe\\xca2\\xfa\\xdb#\\xe8o]\\x0e\\xa0\" +\n\t\"\\xdc\\xc5P\\xb9W@\\x89\\x95\\xe1\\xdf\\xb1\\x00@\\xd9\\xc2P\" +\n\t\"\\xb9_@'\\xebM\\x92\\x03\\x80\\x00\\xd8\\x01\\xae\\xda%\\x93\" +\n\t\"[d\\x9b\\x0d\\xd8\\xcb\\xd0\\xc5\\x7f6\\xe0\\xe6\\x11nR\\x04\" +\n\t\"\\xfe~$T3;\\x14\\xec\\xd9\\x94\\xcc\\xea\\xde\\xa8Y\\xb6\" +\n\t\"\\xa6\\x0f\\xaeu\\xed\\xbdF\\\"\\xafeG)\\xb6zw\\xb5\" +\n\t\"-\\xcb\\x00\\x10\\xa5\\x0f\\xac\\x07@A\\x92\\x96\\x03\\xb4k\\x83\" +\n\t\"\\xbaar'\\xa7YYC\\xd79\\xb0\\xac\\xbd\\xb9_\\xcd\" +\n\t\"\\xabz\\x96\\x07\\xd3\\x89\\x17\\x9a\\xce\\x9b&\\xc3\\xcd\\x11n^\" +\n\t\"\\xabFX=\\xafW5\\xd5\\x82\\x05\\xa0\\xd4\\x07\\xa0v\\xaf\" +\n\t\"\\x07P\\xba\\x18*\\xbd\\x11PW\\x13\\xa8\\xab\\x18*\\xb7F\" +\n\t\"@]G\\xa0\\xf62T6\\x08\\xe8\\x18\\xa66\\xa8\\xe97\" +\n\t\"r`f\\x94\\x99\\x96\\xad\\xab\\x05N\\x00\\x96\\xc1\\xd9l\\x14\" +\n\t\"m\\xcd\\xd0-L\\x86\\x87\\x12 &#\\xb0\\xd5L\\xc5U\" +\n\t\"\\x8f\\xaa\\xd7\\xfa\\\\\\xf3\\xa9f\\xe8\\xf3\\xfa\\xb8U\\xca\\xdbh\" +\n\t\")\\xb1 \\x9e\\x86e\\x00J\\x0dC%%`\\xbb\\xe9\\xfd\" +\n\t\"\\x9e\\x0c5\\xc7\\xff\\xde\\xdc\\x01\\x96\\xa9`\\xee\\xbb\\xfb\\\"\\xb4\" +\n\t\"\\xf3\\xb1\\xdc\\xb18\\xa4\\x1d\\x96\\xa1\\xdcEPng\\xa8<\" +\n\t\"D\\xfcD\\x8f\\x9f\\x0f\\x8c\\x01(\\x0f1T\\xbe\\\"\\xa0\\x14\" +\n\t\"\\x13R\\x18C\\x94\\xf6Sqy\\x94\\xa1\\xf2u\\x01\\x1d\\xcb\" +\n\t\"\\x9b\\xba\\x070\\xe7c\\x9e\\xceYvO\\xd1\\xff\\xdf\\xe6\\x9c\" +\n\t\"e\\xf7\\x1a\\xa6\\x8d\\\"\\x08(\\x02\\xd1\\xdc\\xb0x\\xe7\\x00%\" +\n\t\"bO.\\xcfo\\xd2\\x98nc\\x1c\\x04\\x8c\\x13\\x08\\xa6\\x9a\" +\n\t\"\\xe57\\x1aT\\x82\\xf8F\\xbb\\xbcc a\\x1d\\xc0\\xd4Y\" +\n\t\"\\xea\\x91\\xac\\xb3\\xc4\\xec!\\xaf\\x88\\xf8 \\\\C\\x84\\xfa\\x03\" +\n\t\"\\x86\\xca\\x1fF@h\\xa30\\xaec\\xa8|\\\\@G\\xcd\" +\n\t\"f\\x8d\\x92n\\xaf\\x05\\xa6\\x0eV$Q\\x86C\\\"k\\xf2\" +\n\t\"\\x90R\\xfe\\xb4\\xb5\\x17\\xac\\x16\\x86>\\xa0\\x0d\\x96L\\xd5\\x8e\" +\n\t\"lW\\xa9\\x98Sm>\\xe1\\xa72Wh\\xc3\\xa6\\\"K\" +\n\t\" `.\\x91,~\\xf5\\xab\\xa2\\x0b+XQ\\xa0\\xfa&\" +\n\t\"\\x03\\x8a\\x98\\xf1Q\\x86\\xca\\xf5\\x93\\xef\\xf7\\xe6\\x02\\xb7,u\" +\n\t\"\\x90W\\x15\\x9fY\\x17\\x01H\\xe7Y\\x82\\x80\\x0e5:\\xd3\" +\n\t\"\\xaeu#E\\x9b\\xd6R\\xef8\\xdeb\\x88\\xa5\\xf3\\x18*\" +\n\t\"\\xd7\\x09\\xd8\\x80\\xef;\\xdej\\x16\\xee\\x09\\xb7-\\xcdM\\xd3\" +\n\t\"01\\x19\\x9e\\xfcex\\xb2\\xe5\\x09\\xd0\\xd0\\xbb\\xb8\\xadj\" +\n\t\"y\\xa4l\\x0f\\xf4q\\x05\\x88\\xd3\\xabZ!\\x84\\x9ey^\" +\n\t\"\\xaf\\x9a\\xa0t\\x8b\\xee\\x1d\\xa5K\\x92\\xa1\\xf2!\\x01\\x9dA\" +\n\t\"\\xa2r/7Q3rkT\\xdd\\xc80\\x9e\\x0dy~\" +\n\t\"yS\\xf7\\xf1\\xb4\\xcb\\x9c\\x19\\x8ec\\xf220A\\x04\\xa6\" +\n\t\"H\\x11D\\xcaEk\\xa8\\x07\\x02\\x02l\\xed\\x0f\\xcbEP\" +\n\t\"zwQN\\xdd\\xcbP\\xd9\\x1b9\\xcfv\\xaf\\x8c\\xd6\\x8b\" +\n\t\"X\\x0ac\\x00\\xd2~\\xe2\\xcf^\\x86\\xcaAa\\xa2j\\xe0\" +\n\t\"#\\\\\\xb7\\xbb\\xb4A\\x10\\xb9\\x15Zi\\x89]\\xda \\x07\" +\n\t\"f]n\\x19\\xaf\\x9d\\x16*F\\xbfe\\xe4\\xb9\\xcd\\xbbx\" +\n\t\"6\\xafRf\\x8ep\\xef\\xf72M\\xfd\\x8d\\x9e\\x9a\\xd7}\" +\n\t\"U9\\xe6\\xf1\\x9by\\xa2-\\x92g\\xad!\\xb5\\x03\\x98\\x17\" +\n\t\".\\x0e\\x93O\\xe4\\xa1\\xd2J[EU\\xb7\\xaa\\xca\\x8f|\" +\n\t\"\\xf1Ux%\\xa6\\x8a@a\\xea\\x05\\xd5'\\xf8\\xfer\\xcb\" +\n\t\"Y\\xf9\\xf8\\x89\\xc6\\xb9<\\x8c3\\x08sY\\x18f b\" +\n\t\"b `\\x0c\\xb0=\\xeb\\x0eX\\x15k|\\xbakK\\xf8\" +\n\t\"\\x0a2\\xe6*H\\xffB\\x8e~\\x17C\\x92\\x0e\\x81 5\" +\n\t\"\\x88\\x8e\\xbf~\\xf4\\xbf\\x17\\xab\\xd4`|\\xea\\xf2u\\x8bK\" +\n\t\"A\\xb4h\\xc6H\\x12-\\x9b,\\x89\\xccI\\xce\\xdcm\\xd1\" +\n\t\"\\x1c*\\x9f\\xb9\\xbb\\xc7\\xc2t\\xf1\\xce\\\\\\x00\\xe9\\xc0!\\x00\" +\n\t\"\\xe5 C\\xe5\\x1b\\x02\\xb6{B\\x11\\x93a\\x13\\xaa\\xcc{\" +\n\t\"O\\x01\\xad2 \\x9dU\\xf3\\xe1\\x11\\xec\\x98\\xbc\\x98W\\xb3\" +\n\t\"\\xbc\\x1b\\xcb\\xa2\\x0f\\x10A@t\\x93\\xadP4\\xb9e\\xa1\" +\n\t\"f\\xe8JI\\xcdk\\xcc\\x1e\\x0d\\x94\\xbb^*\\xf4\\x9a|\" +\n\t\"DC\\xa3du\\xda6/\\x88E\\xdb\\xaa\\xd2\\xf5\\xd3\\x80\" +\n\t\"\\xc9\\xaf\\xc1\\xae\\xbe\\x0ce\\x1e\\x89\\xdf\\x0e\\x86\\xca\\xaa\\x08L\" +\n\t\"=t*\\xdf\\xc4PY\\x1b\\xc2\\xa4|\\x0f@Y\\xcbP\" +\n\t\"\\xb9C\\xc0D\\xa9\\xa4\\x05'\\x8f\\x937\\xb2\\xee\\xceCb\" +\n\t\"\\x8dZ\\xa8<\\x80z,\\xa1\\x8f\\x17\\x0c\\x9b\\xe7G=\\xd6\" +\n\t\"\\xe6\\xc2\\xb8gZ7+\\x0a\\xbfwn\\xfe\\x7fR\\xac\\xb1\" +\n\t\"\\xa9\\xae\\x90\\xed\\x1eR\\x15[\\xd0:\\xd9\\x16,\\x8e\\x04\\xe3\" +\n\t\"\\xaf{u\\x7f\\x18\\x8c\\xf8'|4(N\\xbc@[\\xeb\" +\n\t\"#_\\x8e\\xa8\\x13\\xc4\\x9bC\\x9f\\xa9\\xeb\\xf1d%\\xcbM\" +\n\t\"\\xd0UFV\\xcdWW\\x19V\\xb8\\xa0\\xbe\\x9ei\\x05\\x89\" +\n\t\"NM\\xe9,\\x1a\\xba\\xcb\\xd3\\xeb\\xfd\\xe1\\xe5Q\\\\\\x09\\x90\" +\n\t\"\\xd9\\x88\\x0c3\\xdb1\\xc4I\\xde\\x8a\\xcb\\x012w\\x91\\xfd\" +\n\t\"^\\x0c\\xa1\\x92w`\\x13@f\\x0b\\xd9\\xef\\xc7\\xe0\\xaa-\" +\n\t\"\\xef\\xc2q\\x80\\xcc\\xfdd~\\x94\\xdcc\\xccMmy\\x9f\" +\n\t\";\\xfc^\\xb2\\x1f${<\\x96\\xc28\\x80|\\x00\\x17\\x00\" +\n\t\"d\\x1e%\\xfb\\x11\\xb2\\xcf\\x12R8\\x0b@>\\x8c\\xc3\\x00\" +\n\t\"\\x99'\\xc9\\xfe\\x0c\\xd9\\xc5x\\x0a\\xdd.6\\x9a\\x00\\x99\\xbf\" +\n\t\"&\\xfb\\xf7\\xc9^\\xd3\\x98\\xc2\\x1a\\x00\\xf9\\xa8k\\x7f\\x8e\\xec\" +\n\t\"?&{\\xed\\xdc\\x14\\xd6\\x02\\xc8?\\xc2m\\x00\\x99\\x1f\\x92\" +\n\t\"\\xfd5\\xb2\\xd7a\\x8ad\\xb6|\\x1c\\xc7\\x002\\xaf\\x91\\xfd\" +\n\t\"\\x9f\\xc8~\\xc5\\xac\\x14^\\x01 \\xff\\xdc]\\xcfI\\xb2\\xff\" +\n\t\"\\x8a\\xec\\xf5\\xb1\\x14is\\xf9\\x97x\\x08 \\xf3+\\xb2\\xff\" +\n\t\"\\x07\\xd9\\x1b\\xc4\\x146\\x00\\xc8\\xbfq\\xe3:G\\xf6\\x1a\\xa1\" +\n\t\"\\xe2z\\xeb\\xf3\\xba\\xe2\\x0e\\xcb\\x0c+\\xe0\\x0c/\\xd7*\\x9c\" +\n\t\"pC\\xc5D\\xd8L\\x07\\xc4\\x04\\xa0S4\\x8c\\xfc\\x9a\\x89\" +\n\t\"\\xf9\\x92\\xb0\\xd5A\\xcb\\xbf/'\\xc3^\\\" \\x19\\x03u\" +\n\t\"\\x08\\x09C\\xef\\xc9\\x05\\x05\\xad\\xb2z\\xfa+\\xd1\\xac\\xce\\x92\" +\n\t\"m\\x94\\x8a\\x90&F\\xe6\\x82\\x1ab\\x96\\xf4\\x15\\xa6QX\" +\n\t\"\\x8b\\xdc,h\\xba\\x9a\\x9f\\xa2\\xaa\\xd6\\x82\\x80\\xb5P.`\" +\n\t\"\\xfe\\xd8\\x17/\\xb1\\x17\\xbe\\xfd\\x07\\xbcf\\x17\\xe2\\xb5\\xb8V\" +\n\t\"\\x1d\\xac\\x10\\x1d\\x0b\\xa6\\x10\\x1d\\x09=RD\\xd3#j\\xbe\" +\n\t\"T\\xad\\xe9/Mh\\xf6q+AZc\\xaa{\\x8e\\xdf\" +\n\t\"\\x1d\\xac(n\\x17\\x14\\\\\\xeb\\xaaU\\x88\\xab\\xb8D\\xbdJ\" +\n\t\"q\\x8d\\x87\\x97\\x18?\\xf6\\xa5\\xad\\x91\\x1b`^\\xb5\\xb9e\" +\n\t\"w\\x16\\xb1\\x98\\xd7x\\xee\\xd3\\xdcLD\\x85IT\\x8f\\xcd\" +\n\t\"\\xe4\\xe4\\x9b\\xa0\\xff\\xdc\\xe01\\xf2 B \\x08\\xe5\\xe0g\" +\n\t\"\\x88\\xf0 \\xb7\\xbd\\x7f\\xf5\\xe8\\x03\\x86\\xa7\\xbc\\xd0\\xba\\xac1\" +\n\t\"\\\\9\\xc8\\xa6\\xde\\xa3\\xb0\\xdd;]\\xb5=\\x93\\xeaN\\xab\" +\n\t\"\\x10\\xa37\\x9b\\x9a\\x19\\x8c:\\x89\\xc8\\xf5/i\\x91\\x96\\x1d\" +\n\t\"\\xa5\\xc1\\x06\\x86\\xcaP$\\x0d8\\x9d\\xd59\\x86J1\\x94\" +\n\t\"\\x1d\\x85\\xbe\\xb0_*1\\xa1\\xdc0\\xa5\\xf3\\xbb\\xc8P\\xb9\" +\n\t\"K\\xc0\\x84Z\\xb2\\x870\\x19\\xbe\\xa7M\\x00db#\\x8f\" +\n\t\"\\xf2\\xa1G\\xcfq\\xc0\\x8d~zGN\\xf5\\xe0\\xa1g\\xba\" +\n\t\"\\xd7\\xfb\\xe9\\x05\\xef_\\x13\\xa7\\xdc\\xd2\\xe0\\xc5c\\xba\\xaa\\xc2\" +\n\t\"\\xe7Q\\x82\\xa6&n7\\xbaz\\xdb\\x7fSB\\xff\\xcd@\" +\n\t\":\\xbc\\x09\\x04\\xe9/D\\x0c\\xdfI\\xd0\\x7f\\x16\\x91\\x0e\\x98\" +\n\t\" H\\xfbD\\x14\\x82g?\\xf4\\x9f\\xf7\\xa4]\\xf7\\x81 \" +\n\t\"\\xed\\x10\\x91\\x05\\xafv\\xe8\\xf7\\xd1\\xdbF\\xeb\\x10\\x04\\xe9n\" +\n\t\"\\x11c\\xc1{)\\xfa]x\\xe9\\xb3\\xc3 H\\x9a\\x88\\xf1\" +\n\t\"\\xe0A\\x10\\xfd\\xe7!\\xe9\\xf6m H\\xeb\\xc2\\x161\\xb4\" +\n\t\"{qt\\xa0\\xe3\\xe7\\x02\\xa4\\xddl\\x98\\xd80\\xf6\\xbc\\x00\" +\n\t\":\\xd0\\xf1/\\x8b\\xecB\\xb7E\\xd7\\xcb\\xefpB\\\"\\xab\" +\n\t\"\\xda\\xbc\\x83\\x14\\xb8W\\x10\\xb1\\\\\\x11\\xa1\\x03\\x95\\x18F\\x1e\" +\n\t\"!\\\"\\xfd\\xad\\xcb\\xea\\xe9T\\xe5\\xcf%)\\\\\\x7f\\x94K\" +\n\t\"\\xac\\xd7\\x17i\\xf5{\\xe5\\xa6\\xdcG\\x8f\\x8c>\\xecv\\x80\" +\n\t\"Qi\\x14\\xa6P\\xf5\\x17)\\xbb\\xde\\xe2\\xc3\\xd4`\\x9e\\xdc\" +\n\t\"\\xbd:\\x98\\xe58\\x15\\xfc\\x1f3TNFR\\xff\\x04\\x19\" +\n\t\"_a\\xa8\\xbc\\x1e\\x91\\xbb\\xa7\\xa8\\x1e\\x9cd\\xa8\\xbc\\x1b\\xbe\" +\n\t\"\\x95\\xbcu\\x1f\\x80\\xf2.\\xc3\\xbe\\x88z\\x93\\xfe\\x9b\\x1c\\x7f\" +\n\t\"G\\x1a\\xc7\\xd5n\\xe8i\\xb78\\xee\\x01\\xc8\\xd4\\x90\\xf6I\" +\n\t\"\\xb9\\xda-\\xe6i7\\x09\\xfb\\x012I\\xb2\\x7f(\\xaa\\xdd\" +\n\t\"\\xe6\\xe2z\\x80L#\\xd9\\xe7\\xe1\\xc4\\xdb\\xbfX2Cy\" +\n\t\"\\x9d7\\x06Wi\\xfa\\xa4\\x82\\xc0\\x7f\\xbcA{\\x85\\xaa\\xe5\" +\n\t\"K&\\x87\\xca\\xdbNOWD\\\"y\\xaf:^\\x1b6\" +\n\t\"C\\xe4\\xcc\\xa1\\x15\\xb4hg\\xd0\\x98\\x99\\xfa,\\xcc\\x1b\\xa5\" +\n\t\"\\xdc@^5y\\xce\\xdd}\\xa4r\\xd1\\xcb\\xe2J\\x0dF\" +\n\t\"\\xfe\\xe6\\x02 |\\x1a\\x8f\\xa4\\xc24N\\xd8n\\xd34L\" +\n\t\"\\xa8\\xb8\\xd6,\\x0e\\xaf5\\xc1\\xadf}x\\xb1\\x94\\x84\\x8e\" +\n\t\"\\xf2\\xcd\\xb2?\\xbc\\x8d\\xa5\\xb3j\\xc9\\xe2U\\xf8\\x00\\xe3f\" +\n\t\"\\xd0\\xb6\\xb3\\x86\\x8cR>\\xd7\\xc7A\\xb4\\xcd\\xd1\\xaa\\xcbd\" +\n\t\"|\\xba\\xd5\\x9ay5\\xb3\\xde\\xad\\x99\\xfeS/\\xfa/\\xba\" +\n\t\"\\x922\\x06\\x82\\xb4\\x9aj\\xa6\\xff\\xea\\x88\\xfe\\xdf\\x1cH\\x9d\" +\n\t\"\\xe3 H\\x9f\\xa0\\x9a\\xe9\\xbf\\xb8\\xa3\\xff\\x8a,\\xb5\\xbd\\x08\" +\n\t\"\\x82\\xd4\\x16y\\x01\\xf3Q\\xaaz\\x01\\xf3~H\\xd8\\x9a\\xf7\" +\n\t\"C\\xf90\\x16*Oc\\xaae\\xd1\\x8eH\\xcd\\xe5\\xb6\\x9c\" +\n\t\"\\xda\\xbd\\x16\\xd1\\xe5\\xbc\\x17M\\xfb}%\\xf8\\xeb\\x9f\\xff\\x9b\" +\n\t\"\\xa6\\xa0\\x7f\\xb6\\xfeO\\x00\\x00\\x00\\xff\\xff\\xb4\\x0bQ\\xfc\"\n\nfunc init() {\n\tschemas.Register(schema_db8274f9144abc7e,\n\t\t0x82c325a07ad22a65,\n\t\t0x839445a59fb01686,\n\t\t0x83ced0145b2f114b,\n\t\t0x84cb9536a2cf6d3c,\n\t\t0x85c8cea1ab1894f3,\n\t\t0x8635c6b4f45bf5cd,\n\t\t0x904e297b87fbecea,\n\t\t0x9496331ab9cd463f,\n\t\t0x958096448eb3373e,\n\t\t0x96b74375ce9b0ef6,\n\t\t0x97b3c5c260257622,\n\t\t0x9b87b390babc2ccf,\n\t\t0xa29a916d4ebdd894,\n\t\t0xa353a3556df74984,\n\t\t0xa766b24d4fe5da35,\n\t\t0xab6d5210c1f26687,\n\t\t0xb046e578094b1ead,\n\t\t0xb177ca2526a3ca76,\n\t\t0xb48edfbdaa25db04,\n\t\t0xb4bf9861fe035d04,\n\t\t0xb5f39f082b9ac18a,\n\t\t0xb70431c0dc014915,\n\t\t0xc082ef6e0d42ed1d,\n\t\t0xc5d6e311876a3604,\n\t\t0xc793e50592935b4a,\n\t\t0xcbd96442ae3bb01a,\n\t\t0xd4d18de97bb12de3,\n\t\t0xdb58ff694ba05cf9,\n\t\t0xdbaa9d03d52b62dc,\n\t\t0xdc3ed6801961e502,\n\t\t0xe3e37d096a5b564e,\n\t\t0xe5ceae5d6897d7be,\n\t\t0xe6646dec8feaa6ee,\n\t\t0xea50d822450d1f17,\n\t\t0xea58385c65416035,\n\t\t0xf24ec4ab5891b676,\n\t\t0xf2c122394f447e8e,\n\t\t0xf2c68e2547ec3866,\n\t\t0xf41a0f001ad49e46,\n\t\t0xf548cef9dea2a4a1,\n\t\t0xf5f383d2785edb86,\n\t\t0xf71695ec7fe85497,\n\t\t0xf9cb7f4431a307d0,\n\t\t0xfc5edf80e39c0796,\n\t\t0xfeac5c8f4899ef7c)\n}\n"
  },
  {
    "path": "tunnelrpc/quic/cloudflared_client.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n\n\t\"zombiezen.com/go/capnproto2/rpc\"\n\n\t\"github.com/google/uuid\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/metrics\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\n// CloudflaredClient calls capnp rpc methods of SessionManager and ConfigurationManager.\ntype CloudflaredClient struct {\n\tclient         pogs.CloudflaredServer_PogsClient\n\ttransport      rpc.Transport\n\trequestTimeout time.Duration\n}\n\nfunc NewCloudflaredClient(ctx context.Context, stream io.ReadWriteCloser, requestTimeout time.Duration) (*CloudflaredClient, error) {\n\tn, err := stream.Write(rpcStreamProtocolSignature[:])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif n != len(rpcStreamProtocolSignature) {\n\t\treturn nil, fmt.Errorf(\"expect to write %d bytes for RPC stream protocol signature, wrote %d\", len(rpcStreamProtocolSignature), n)\n\t}\n\ttransport := tunnelrpc.SafeTransport(stream)\n\tconn := tunnelrpc.NewClientConn(transport)\n\tclient := pogs.NewCloudflaredServer_PogsClient(conn.Bootstrap(ctx), conn)\n\treturn &CloudflaredClient{\n\t\tclient:         client,\n\t\ttransport:      transport,\n\t\trequestTimeout: requestTimeout,\n\t}, nil\n}\n\nfunc (c *CloudflaredClient) RegisterUdpSession(ctx context.Context, sessionID uuid.UUID, dstIP net.IP, dstPort uint16, closeIdleAfterHint time.Duration, traceContext string) (*pogs.RegisterUdpSessionResponse, error) {\n\tctx, cancel := context.WithTimeout(ctx, c.requestTimeout)\n\tdefer cancel()\n\tdefer metrics.CapnpMetrics.ClientOperations.WithLabelValues(metrics.Cloudflared, metrics.OperationRegisterUdpSession).Inc()\n\ttimer := metrics.NewClientOperationLatencyObserver(metrics.Cloudflared, metrics.OperationRegisterUdpSession)\n\tdefer timer.ObserveDuration()\n\n\tresp, err := c.client.RegisterUdpSession(ctx, sessionID, dstIP, dstPort, closeIdleAfterHint, traceContext)\n\tif err != nil {\n\t\tmetrics.CapnpMetrics.ClientFailures.WithLabelValues(metrics.Cloudflared, metrics.OperationRegisterUdpSession).Inc()\n\t}\n\treturn resp, err\n}\n\nfunc (c *CloudflaredClient) UnregisterUdpSession(ctx context.Context, sessionID uuid.UUID, message string) error {\n\tctx, cancel := context.WithTimeout(ctx, c.requestTimeout)\n\tdefer cancel()\n\tdefer metrics.CapnpMetrics.ClientOperations.WithLabelValues(metrics.Cloudflared, metrics.OperationUnregisterUdpSession).Inc()\n\ttimer := metrics.NewClientOperationLatencyObserver(metrics.Cloudflared, metrics.OperationUnregisterUdpSession)\n\tdefer timer.ObserveDuration()\n\n\terr := c.client.UnregisterUdpSession(ctx, sessionID, message)\n\tif err != nil {\n\t\tmetrics.CapnpMetrics.ClientFailures.WithLabelValues(metrics.Cloudflared, metrics.OperationUnregisterUdpSession).Inc()\n\t}\n\treturn err\n}\n\nfunc (c *CloudflaredClient) UpdateConfiguration(ctx context.Context, version int32, config []byte) (*pogs.UpdateConfigurationResponse, error) {\n\tctx, cancel := context.WithTimeout(ctx, c.requestTimeout)\n\tdefer cancel()\n\tdefer metrics.CapnpMetrics.ClientOperations.WithLabelValues(metrics.Cloudflared, metrics.OperationUpdateConfiguration).Inc()\n\ttimer := metrics.NewClientOperationLatencyObserver(metrics.Cloudflared, metrics.OperationUpdateConfiguration)\n\tdefer timer.ObserveDuration()\n\n\tresp, err := c.client.UpdateConfiguration(ctx, version, config)\n\tif err != nil {\n\t\tmetrics.CapnpMetrics.ClientFailures.WithLabelValues(metrics.Cloudflared, metrics.OperationUpdateConfiguration).Inc()\n\t}\n\treturn resp, err\n}\n\nfunc (c *CloudflaredClient) Close() {\n\t_ = c.client.Close()\n\t_ = c.transport.Close()\n}\n"
  },
  {
    "path": "tunnelrpc/quic/cloudflared_server.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\n// HandleRequestFunc wraps the proxied request from the upstream and also provides methods on the stream to\n// handle the response back.\ntype HandleRequestFunc = func(ctx context.Context, stream *RequestServerStream) error\n\n// CloudflaredServer provides a handler interface for a client to provide methods to handle the different types of\n// requests that can be communicated by the stream.\ntype CloudflaredServer struct {\n\thandleRequest   HandleRequestFunc\n\tsessionManager  pogs.SessionManager\n\tconfigManager   pogs.ConfigurationManager\n\tresponseTimeout time.Duration\n}\n\nfunc NewCloudflaredServer(handleRequest HandleRequestFunc, sessionManager pogs.SessionManager, configManager pogs.ConfigurationManager, responseTimeout time.Duration) *CloudflaredServer {\n\treturn &CloudflaredServer{\n\t\thandleRequest:   handleRequest,\n\t\tsessionManager:  sessionManager,\n\t\tconfigManager:   configManager,\n\t\tresponseTimeout: responseTimeout,\n\t}\n}\n\n// Serve executes the defined handlers in ServerStream on the provided stream if it is a proper RPC stream with the\n// correct preamble protocol signature.\nfunc (s *CloudflaredServer) Serve(ctx context.Context, stream io.ReadWriteCloser) error {\n\tsignature, err := determineProtocol(stream)\n\tif err != nil {\n\t\treturn err\n\t}\n\tswitch signature {\n\tcase dataStreamProtocolSignature:\n\t\treturn s.handleRequest(ctx, &RequestServerStream{stream})\n\tcase rpcStreamProtocolSignature:\n\t\treturn s.handleRPC(ctx, stream)\n\tdefault:\n\t\treturn fmt.Errorf(\"unknown protocol %v\", signature)\n\t}\n}\n\nfunc (s *CloudflaredServer) handleRPC(ctx context.Context, stream io.ReadWriteCloser) error {\n\tctx, cancel := context.WithTimeout(ctx, s.responseTimeout)\n\tdefer cancel()\n\ttransport := tunnelrpc.SafeTransport(stream)\n\tdefer transport.Close()\n\n\tmain := pogs.CloudflaredServer_ServerToClient(s.sessionManager, s.configManager)\n\trpcConn := tunnelrpc.NewServerConn(transport, main.Client)\n\tdefer rpcConn.Close()\n\n\t// We ignore the errors here because if cloudflared fails to handle a request, we will just move on.\n\tselect {\n\tcase <-rpcConn.Done():\n\tcase <-ctx.Done():\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "tunnelrpc/quic/protocol.go",
    "content": "package quic\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n// protocolSignature defines the first 6 bytes of the stream, which is used to distinguish the type of stream. It\n// ensures whoever performs a handshake does not write data before writing the metadata.\ntype protocolSignature [6]byte\n\nvar (\n\t// dataStreamProtocolSignature is a custom protocol signature for data stream\n\tdataStreamProtocolSignature = protocolSignature{0x0A, 0x36, 0xCD, 0x12, 0xA1, 0x3E}\n\n\t// rpcStreamProtocolSignature is a custom protocol signature for RPC stream\n\trpcStreamProtocolSignature = protocolSignature{0x52, 0xBB, 0x82, 0x5C, 0xDB, 0x65}\n\n\terrDataStreamNotSupported = fmt.Errorf(\"data protocol not supported\")\n\terrRPCStreamNotSupported  = fmt.Errorf(\"rpc protocol not supported\")\n)\n\ntype protocolVersion string\n\nconst (\n\tprotocolV1 protocolVersion = \"01\"\n\n\tprotocolVersionLength = 2\n)\n\n// determineProtocol reads the first 6 bytes from the stream to determine which protocol is spoken by the client.\n// The protocols are magic byte arrays understood by both sides of the stream.\nfunc determineProtocol(stream io.Reader) (protocolSignature, error) {\n\tsignature, err := readSignature(stream)\n\tif err != nil {\n\t\treturn protocolSignature{}, err\n\t}\n\tswitch signature {\n\tcase dataStreamProtocolSignature:\n\t\treturn dataStreamProtocolSignature, nil\n\tcase rpcStreamProtocolSignature:\n\t\treturn rpcStreamProtocolSignature, nil\n\tdefault:\n\t\treturn protocolSignature{}, fmt.Errorf(\"unknown signature %v\", signature)\n\t}\n}\n\nfunc writeDataStreamPreamble(stream io.Writer) error {\n\tif err := writeSignature(stream, dataStreamProtocolSignature); err != nil {\n\t\treturn err\n\t}\n\n\treturn writeVersion(stream)\n}\n\nfunc writeVersion(stream io.Writer) error {\n\t_, err := stream.Write([]byte(protocolV1)[:protocolVersionLength])\n\treturn err\n}\n\nfunc readVersion(stream io.Reader) (string, error) {\n\tversion := make([]byte, protocolVersionLength)\n\t_, err := stream.Read(version)\n\treturn string(version), err\n}\n\nfunc readSignature(stream io.Reader) (protocolSignature, error) {\n\tvar signature protocolSignature\n\tif _, err := io.ReadFull(stream, signature[:]); err != nil {\n\t\treturn protocolSignature{}, err\n\t}\n\treturn signature, nil\n}\n\nfunc writeSignature(stream io.Writer, signature protocolSignature) error {\n\t_, err := stream.Write(signature[:])\n\treturn err\n}\n"
  },
  {
    "path": "tunnelrpc/quic/request_client_stream.go",
    "content": "package quic\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\n\tcapnp \"zombiezen.com/go/capnproto2\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\n// RequestClientStream is a stream to provide requests to the server. This operation is typically driven by the edge service.\ntype RequestClientStream struct {\n\tio.ReadWriteCloser\n}\n\n// WriteConnectRequestData writes requestMeta to a stream.\nfunc (rcs *RequestClientStream) WriteConnectRequestData(dest string, connectionType pogs.ConnectionType, metadata ...pogs.Metadata) error {\n\tconnectRequest := &pogs.ConnectRequest{\n\t\tDest:     dest,\n\t\tType:     connectionType,\n\t\tMetadata: metadata,\n\t}\n\n\tmsg, err := connectRequest.ToPogs()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := writeDataStreamPreamble(rcs); err != nil {\n\t\treturn err\n\t}\n\treturn capnp.NewEncoder(rcs).Encode(msg)\n}\n\n// ReadConnectResponseData reads the response from the rpc stream to a ConnectResponse.\nfunc (rcs *RequestClientStream) ReadConnectResponseData() (*pogs.ConnectResponse, error) {\n\tsignature, err := determineProtocol(rcs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif signature != dataStreamProtocolSignature {\n\t\treturn nil, fmt.Errorf(\"wrong protocol signature %v\", signature)\n\t}\n\n\t// This is a NO-OP for now. We could cause a branching if we wanted to use multiple versions.\n\tif _, err := readVersion(rcs); err != nil {\n\t\treturn nil, err\n\t}\n\n\tmsg, err := capnp.NewDecoder(rcs).Decode()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tr := &pogs.ConnectResponse{}\n\tif err := r.FromPogs(msg); err != nil {\n\t\treturn nil, err\n\t}\n\treturn r, nil\n}\n"
  },
  {
    "path": "tunnelrpc/quic/request_server_stream.go",
    "content": "package quic\n\nimport (\n\t\"io\"\n\n\tcapnp \"zombiezen.com/go/capnproto2\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\n// RequestServerStream is a stream to serve requests\ntype RequestServerStream struct {\n\tio.ReadWriteCloser\n}\n\n// ReadConnectRequestData reads the handshake data from a QUIC stream.\nfunc (rss *RequestServerStream) ReadConnectRequestData() (*pogs.ConnectRequest, error) {\n\t// This is a NO-OP for now. We could cause a branching if we wanted to use multiple versions.\n\tif _, err := readVersion(rss); err != nil {\n\t\treturn nil, err\n\t}\n\n\tmsg, err := capnp.NewDecoder(rss).Decode()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tr := &pogs.ConnectRequest{}\n\tif err := r.FromPogs(msg); err != nil {\n\t\treturn nil, err\n\t}\n\treturn r, nil\n}\n\n// WriteConnectResponseData writes response to a QUIC stream.\nfunc (rss *RequestServerStream) WriteConnectResponseData(respErr error, metadata ...pogs.Metadata) error {\n\tvar connectResponse *pogs.ConnectResponse\n\tif respErr != nil {\n\t\tconnectResponse = &pogs.ConnectResponse{\n\t\t\tError:    respErr.Error(),\n\t\t\tMetadata: metadata,\n\t\t}\n\t} else {\n\t\tconnectResponse = &pogs.ConnectResponse{\n\t\t\tMetadata: metadata,\n\t\t}\n\t}\n\n\tmsg, err := connectResponse.ToPogs()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := writeDataStreamPreamble(rss); err != nil {\n\t\treturn err\n\t}\n\treturn capnp.NewEncoder(rss).Encode(msg)\n}\n"
  },
  {
    "path": "tunnelrpc/quic/request_server_stream_test.go",
    "content": "package quic\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\nconst (\n\ttestCloseIdleAfterHint = time.Minute * 2\n)\n\nfunc TestConnectRequestData(t *testing.T) {\n\ttests := []struct {\n\t\tname           string\n\t\thostname       string\n\t\tconnectionType pogs.ConnectionType\n\t\tmetadata       []pogs.Metadata\n\t}{\n\t\t{\n\t\t\tname:           \"Signature verified and request metadata is unmarshaled and read correctly\",\n\t\t\thostname:       \"tunnel.com\",\n\t\t\tconnectionType: pogs.ConnectionTypeHTTP,\n\t\t\tmetadata: []pogs.Metadata{\n\t\t\t\t{\n\t\t\t\t\tKey: \"key\",\n\t\t\t\t\tVal: \"1234\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tb := &bytes.Buffer{}\n\t\t\treqClientStream := RequestClientStream{noopCloser{b}}\n\t\t\terr := reqClientStream.WriteConnectRequestData(test.hostname, test.connectionType, test.metadata...)\n\t\t\trequire.NoError(t, err)\n\t\t\tprotocol, err := determineProtocol(b)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, dataStreamProtocolSignature, protocol)\n\t\t\treqServerStream := RequestServerStream{&noopCloser{b}}\n\n\t\t\treqMeta, err := reqServerStream.ReadConnectRequestData()\n\t\t\trequire.NoError(t, err)\n\n\t\t\tassert.Equal(t, test.metadata, reqMeta.Metadata)\n\t\t\tassert.Equal(t, test.hostname, reqMeta.Dest)\n\t\t\tassert.Equal(t, test.connectionType, reqMeta.Type)\n\t\t})\n\t}\n}\n\nfunc TestConnectResponseMeta(t *testing.T) {\n\ttests := []struct {\n\t\tname     string\n\t\terr      error\n\t\tmetadata []pogs.Metadata\n\t}{\n\t\t{\n\t\t\tname: \"Signature verified and response metadata is unmarshaled and read correctly\",\n\t\t\tmetadata: []pogs.Metadata{\n\t\t\t\t{\n\t\t\t\t\tKey: \"key\",\n\t\t\t\t\tVal: \"1234\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"If error is not empty, other fields should be blank\",\n\t\t\terr:  errors.New(\"something happened\"),\n\t\t\tmetadata: []pogs.Metadata{\n\t\t\t\t{\n\t\t\t\t\tKey: \"key\",\n\t\t\t\t\tVal: \"1234\",\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\tb := &bytes.Buffer{}\n\t\t\treqServerStream := RequestServerStream{noopCloser{b}}\n\t\t\terr := reqServerStream.WriteConnectResponseData(test.err, test.metadata...)\n\t\t\trequire.NoError(t, err)\n\n\t\t\treqClientStream := RequestClientStream{noopCloser{b}}\n\t\t\trespMeta, err := reqClientStream.ReadConnectResponseData()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, test.metadata, respMeta.Metadata)\n\t\t})\n\t}\n}\n\nfunc TestRegisterUdpSession(t *testing.T) {\n\tunregisterMessage := \"closed by eyeball\"\n\n\ttests := []struct {\n\t\tname             string\n\t\tsessionRPCServer mockSessionRPCServer\n\t}{\n\t\t{\n\t\t\tname: \"RegisterUdpSession (no trace context)\",\n\t\t\tsessionRPCServer: mockSessionRPCServer{\n\t\t\t\tsessionID:         uuid.New(),\n\t\t\t\tdstIP:             net.IP{172, 16, 0, 1},\n\t\t\t\tdstPort:           8000,\n\t\t\t\tcloseIdleAfter:    testCloseIdleAfterHint,\n\t\t\t\tunregisterMessage: unregisterMessage,\n\t\t\t\ttraceContext:      \"\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"RegisterUdpSession (with trace context)\",\n\t\t\tsessionRPCServer: mockSessionRPCServer{\n\t\t\t\tsessionID:         uuid.New(),\n\t\t\t\tdstIP:             net.IP{172, 16, 0, 1},\n\t\t\t\tdstPort:           8000,\n\t\t\t\tcloseIdleAfter:    testCloseIdleAfterHint,\n\t\t\t\tunregisterMessage: unregisterMessage,\n\t\t\t\ttraceContext:      \"1241ce3ecdefc68854e8514e69ba42ca:b38f1bf5eae406f3:0:1\",\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\tclientStream, serverStream := newMockRPCStreams()\n\t\t\tsessionRegisteredChan := make(chan struct{})\n\t\t\tgo func() {\n\t\t\t\tss := NewCloudflaredServer(nil, test.sessionRPCServer, nil, 10*time.Second)\n\t\t\t\terr := ss.Serve(t.Context(), serverStream)\n\t\t\t\tassert.NoError(t, err)\n\n\t\t\t\tserverStream.Close()\n\t\t\t\tclose(sessionRegisteredChan)\n\t\t\t}()\n\n\t\t\trpcClientStream, err := NewCloudflaredClient(t.Context(), clientStream, 5*time.Second)\n\t\t\trequire.NoError(t, err)\n\n\t\t\treg, err := rpcClientStream.RegisterUdpSession(t.Context(), test.sessionRPCServer.sessionID, test.sessionRPCServer.dstIP, test.sessionRPCServer.dstPort, testCloseIdleAfterHint, test.sessionRPCServer.traceContext)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.NoError(t, reg.Err)\n\n\t\t\t// Different sessionID, the RPC server should reject the registration\n\t\t\treg, err = rpcClientStream.RegisterUdpSession(t.Context(), uuid.New(), test.sessionRPCServer.dstIP, test.sessionRPCServer.dstPort, testCloseIdleAfterHint, test.sessionRPCServer.traceContext)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Error(t, reg.Err)\n\n\t\t\trequire.NoError(t, rpcClientStream.UnregisterUdpSession(t.Context(), test.sessionRPCServer.sessionID, unregisterMessage))\n\n\t\t\t// Different sessionID, the RPC server should reject the unregistration\n\t\t\trequire.Error(t, rpcClientStream.UnregisterUdpSession(t.Context(), uuid.New(), unregisterMessage))\n\n\t\t\trpcClientStream.Close()\n\t\t\t<-sessionRegisteredChan\n\t\t})\n\t}\n}\n\nfunc TestManageConfiguration(t *testing.T) {\n\tvar (\n\t\tversion int32 = 168\n\t\tconfig        = []byte(t.Name())\n\t)\n\tclientStream, serverStream := newMockRPCStreams()\n\n\tconfigRPCServer := mockConfigRPCServer{\n\t\tversion: version,\n\t\tconfig:  config,\n\t}\n\n\tupdatedChan := make(chan struct{})\n\tgo func() {\n\t\tserver := NewCloudflaredServer(nil, nil, configRPCServer, 10*time.Second)\n\t\terr := server.Serve(t.Context(), serverStream)\n\t\tassert.NoError(t, err)\n\n\t\tserverStream.Close()\n\t\tclose(updatedChan)\n\t}()\n\n\tctx, cancel := context.WithTimeout(t.Context(), time.Second)\n\tdefer cancel()\n\trpcClientStream, err := NewCloudflaredClient(ctx, clientStream, 5*time.Second)\n\trequire.NoError(t, err)\n\n\tresult, err := rpcClientStream.UpdateConfiguration(ctx, version, config)\n\trequire.NoError(t, err)\n\n\trequire.Equal(t, version, result.LastAppliedVersion)\n\trequire.NoError(t, result.Err)\n\n\trpcClientStream.Close()\n\t<-updatedChan\n}\n\ntype mockSessionRPCServer struct {\n\tsessionID         uuid.UUID\n\tdstIP             net.IP\n\tdstPort           uint16\n\tcloseIdleAfter    time.Duration\n\tunregisterMessage string\n\ttraceContext      string\n}\n\nfunc (s mockSessionRPCServer) RegisterUdpSession(_ context.Context, sessionID uuid.UUID, dstIP net.IP, dstPort uint16, closeIdleAfter time.Duration, traceContext string) (*pogs.RegisterUdpSessionResponse, error) {\n\tif s.sessionID != sessionID {\n\t\treturn nil, fmt.Errorf(\"expect session ID %s, got %s\", s.sessionID, sessionID)\n\t}\n\tif !s.dstIP.Equal(dstIP) {\n\t\treturn nil, fmt.Errorf(\"expect destination IP %s, got %s\", s.dstIP, dstIP)\n\t}\n\tif s.dstPort != dstPort {\n\t\treturn nil, fmt.Errorf(\"expect destination port %d, got %d\", s.dstPort, dstPort)\n\t}\n\tif s.closeIdleAfter != closeIdleAfter {\n\t\treturn nil, fmt.Errorf(\"expect closeIdleAfter %d, got %d\", s.closeIdleAfter, closeIdleAfter)\n\t}\n\tif s.traceContext != traceContext {\n\t\treturn nil, fmt.Errorf(\"expect traceContext %s, got %s\", s.traceContext, traceContext)\n\t}\n\treturn &pogs.RegisterUdpSessionResponse{}, nil\n}\n\nfunc (s mockSessionRPCServer) UnregisterUdpSession(_ context.Context, sessionID uuid.UUID, message string) error {\n\tif s.sessionID != sessionID {\n\t\treturn fmt.Errorf(\"expect session ID %s, got %s\", s.sessionID, sessionID)\n\t}\n\tif s.unregisterMessage != message {\n\t\treturn fmt.Errorf(\"expect unregister message %s, got %s\", s.unregisterMessage, message)\n\t}\n\treturn nil\n}\n\ntype mockConfigRPCServer struct {\n\tversion int32\n\tconfig  []byte\n}\n\nfunc (s mockConfigRPCServer) UpdateConfiguration(_ context.Context, version int32, config []byte) *pogs.UpdateConfigurationResponse {\n\tif s.version != version {\n\t\treturn &pogs.UpdateConfigurationResponse{\n\t\t\tErr: fmt.Errorf(\"expect version %d, got %d\", s.version, version),\n\t\t}\n\t}\n\tif !bytes.Equal(s.config, config) {\n\t\treturn &pogs.UpdateConfigurationResponse{\n\t\t\tErr: fmt.Errorf(\"expect config %v, got %v\", s.config, config),\n\t\t}\n\t}\n\treturn &pogs.UpdateConfigurationResponse{LastAppliedVersion: version}\n}\n\ntype mockRPCStream struct {\n\tio.ReadCloser\n\tio.WriteCloser\n}\n\nfunc newMockRPCStreams() (client io.ReadWriteCloser, server io.ReadWriteCloser) {\n\tclientReader, serverWriter := io.Pipe()\n\tserverReader, clientWriter := io.Pipe()\n\n\tclient = mockRPCStream{clientReader, clientWriter}\n\tserver = mockRPCStream{serverReader, serverWriter}\n\treturn\n}\n\nfunc (s mockRPCStream) Close() error {\n\t_ = s.ReadCloser.Close()\n\t_ = s.WriteCloser.Close()\n\treturn nil\n}\n\ntype noopCloser struct {\n\tio.ReadWriter\n}\n\nfunc (noopCloser) Close() error {\n\treturn nil\n}\n"
  },
  {
    "path": "tunnelrpc/quic/session_client.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"zombiezen.com/go/capnproto2/rpc\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/metrics\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\n// SessionClient calls capnp rpc methods of SessionManager.\ntype SessionClient struct {\n\tclient         pogs.SessionManager_PogsClient\n\ttransport      rpc.Transport\n\trequestTimeout time.Duration\n}\n\nfunc NewSessionClient(ctx context.Context, stream io.ReadWriteCloser, requestTimeout time.Duration) (*SessionClient, error) {\n\tn, err := stream.Write(rpcStreamProtocolSignature[:])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif n != len(rpcStreamProtocolSignature) {\n\t\treturn nil, fmt.Errorf(\"expect to write %d bytes for RPC stream protocol signature, wrote %d\", len(rpcStreamProtocolSignature), n)\n\t}\n\ttransport := tunnelrpc.SafeTransport(stream)\n\tconn := tunnelrpc.NewClientConn(transport)\n\treturn &SessionClient{\n\t\tclient:         pogs.NewSessionManager_PogsClient(conn.Bootstrap(ctx), conn),\n\t\ttransport:      transport,\n\t\trequestTimeout: requestTimeout,\n\t}, nil\n}\n\nfunc (c *SessionClient) RegisterUdpSession(ctx context.Context, sessionID uuid.UUID, dstIP net.IP, dstPort uint16, closeIdleAfterHint time.Duration, traceContext string) (*pogs.RegisterUdpSessionResponse, error) {\n\tctx, cancel := context.WithTimeout(ctx, c.requestTimeout)\n\tdefer cancel()\n\tdefer metrics.CapnpMetrics.ClientOperations.WithLabelValues(metrics.SessionManager, metrics.OperationRegisterUdpSession).Inc()\n\ttimer := metrics.NewClientOperationLatencyObserver(metrics.SessionManager, metrics.OperationRegisterUdpSession)\n\tdefer timer.ObserveDuration()\n\n\tresp, err := c.client.RegisterUdpSession(ctx, sessionID, dstIP, dstPort, closeIdleAfterHint, traceContext)\n\tif err != nil {\n\t\tmetrics.CapnpMetrics.ClientFailures.WithLabelValues(metrics.SessionManager, metrics.OperationRegisterUdpSession).Inc()\n\t}\n\treturn resp, err\n}\n\nfunc (c *SessionClient) UnregisterUdpSession(ctx context.Context, sessionID uuid.UUID, message string) error {\n\tctx, cancel := context.WithTimeout(ctx, c.requestTimeout)\n\tdefer cancel()\n\tdefer metrics.CapnpMetrics.ClientOperations.WithLabelValues(metrics.SessionManager, metrics.OperationUnregisterUdpSession).Inc()\n\ttimer := metrics.NewClientOperationLatencyObserver(metrics.SessionManager, metrics.OperationUnregisterUdpSession)\n\tdefer timer.ObserveDuration()\n\n\terr := c.client.UnregisterUdpSession(ctx, sessionID, message)\n\tif err != nil {\n\t\tmetrics.CapnpMetrics.ClientFailures.WithLabelValues(metrics.SessionManager, metrics.OperationUnregisterUdpSession).Inc()\n\t}\n\treturn err\n}\n\nfunc (c *SessionClient) Close() {\n\t_ = c.client.Close()\n\t_ = c.transport.Close()\n}\n"
  },
  {
    "path": "tunnelrpc/quic/session_server.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\n// SessionManagerServer handles streams with the SessionManager RPCs.\ntype SessionManagerServer struct {\n\tsessionManager  pogs.SessionManager\n\tresponseTimeout time.Duration\n}\n\nfunc NewSessionManagerServer(sessionManager pogs.SessionManager, responseTimeout time.Duration) *SessionManagerServer {\n\treturn &SessionManagerServer{\n\t\tsessionManager:  sessionManager,\n\t\tresponseTimeout: responseTimeout,\n\t}\n}\n\nfunc (s *SessionManagerServer) Serve(ctx context.Context, stream io.ReadWriteCloser) error {\n\tsignature, err := determineProtocol(stream)\n\tif err != nil {\n\t\treturn err\n\t}\n\tswitch signature {\n\tcase rpcStreamProtocolSignature:\n\t\tbreak\n\tcase dataStreamProtocolSignature:\n\t\treturn errDataStreamNotSupported\n\tdefault:\n\t\treturn fmt.Errorf(\"unknown protocol %v\", signature)\n\t}\n\n\t// Every new quic.Stream request aligns to a new RPC request, this is why there is a timeout for the server-side\n\t// of the RPC request.\n\tctx, cancel := context.WithTimeout(ctx, s.responseTimeout)\n\tdefer cancel()\n\n\ttransport := tunnelrpc.SafeTransport(stream)\n\tdefer transport.Close()\n\n\tmain := pogs.SessionManager_ServerToClient(s.sessionManager)\n\trpcConn := tunnelrpc.NewServerConn(transport, main.Client)\n\tdefer rpcConn.Close()\n\n\tselect {\n\tcase <-rpcConn.Done():\n\t\treturn nil\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\t}\n}\n"
  },
  {
    "path": "tunnelrpc/registration_client.go",
    "content": "package tunnelrpc\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"zombiezen.com/go/capnproto2/rpc\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/metrics\"\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\ntype RegistrationClient interface {\n\tRegisterConnection(\n\t\tctx context.Context,\n\t\tauth pogs.TunnelAuth,\n\t\ttunnelID uuid.UUID,\n\t\toptions *pogs.ConnectionOptions,\n\t\tconnIndex uint8,\n\t\tedgeAddress net.IP,\n\t) (*pogs.ConnectionDetails, error)\n\tSendLocalConfiguration(ctx context.Context, config []byte) error\n\tGracefulShutdown(ctx context.Context, gracePeriod time.Duration) error\n\tClose()\n}\n\ntype registrationClient struct {\n\tclient         pogs.RegistrationServer_PogsClient\n\ttransport      rpc.Transport\n\trequestTimeout time.Duration\n}\n\nfunc NewRegistrationClient(ctx context.Context, stream io.ReadWriteCloser, requestTimeout time.Duration) RegistrationClient {\n\ttransport := SafeTransport(stream)\n\tconn := NewClientConn(transport)\n\tclient := pogs.NewRegistrationServer_PogsClient(conn.Bootstrap(ctx), conn)\n\treturn &registrationClient{\n\t\tclient:         client,\n\t\ttransport:      transport,\n\t\trequestTimeout: requestTimeout,\n\t}\n}\n\nfunc (r *registrationClient) RegisterConnection(\n\tctx context.Context,\n\tauth pogs.TunnelAuth,\n\ttunnelID uuid.UUID,\n\toptions *pogs.ConnectionOptions,\n\tconnIndex uint8,\n\tedgeAddress net.IP,\n) (*pogs.ConnectionDetails, error) {\n\tctx, cancel := context.WithTimeout(ctx, r.requestTimeout)\n\tdefer cancel()\n\tdefer metrics.CapnpMetrics.ClientOperations.WithLabelValues(metrics.Registration, metrics.OperationRegisterConnection).Inc()\n\ttimer := metrics.NewClientOperationLatencyObserver(metrics.Registration, metrics.OperationRegisterConnection)\n\tdefer timer.ObserveDuration()\n\n\tconn, err := r.client.RegisterConnection(ctx, auth, tunnelID, connIndex, options)\n\tif err != nil {\n\t\tmetrics.CapnpMetrics.ClientFailures.WithLabelValues(metrics.Registration, metrics.OperationRegisterConnection).Inc()\n\t}\n\treturn conn, err\n}\n\nfunc (r *registrationClient) SendLocalConfiguration(ctx context.Context, config []byte) error {\n\tctx, cancel := context.WithTimeout(ctx, r.requestTimeout)\n\tdefer cancel()\n\tdefer metrics.CapnpMetrics.ClientOperations.WithLabelValues(metrics.Registration, metrics.OperationUpdateLocalConfiguration).Inc()\n\ttimer := metrics.NewClientOperationLatencyObserver(metrics.Registration, metrics.OperationUpdateLocalConfiguration)\n\tdefer timer.ObserveDuration()\n\n\terr := r.client.SendLocalConfiguration(ctx, config)\n\tif err != nil {\n\t\tmetrics.CapnpMetrics.ClientFailures.WithLabelValues(metrics.Registration, metrics.OperationUpdateLocalConfiguration).Inc()\n\t}\n\treturn err\n}\n\nfunc (r *registrationClient) GracefulShutdown(ctx context.Context, gracePeriod time.Duration) error {\n\tctx, cancel := context.WithTimeout(ctx, gracePeriod)\n\tdefer cancel()\n\tdefer metrics.CapnpMetrics.ClientOperations.WithLabelValues(metrics.Registration, metrics.OperationUnregisterConnection).Inc()\n\ttimer := metrics.NewClientOperationLatencyObserver(metrics.Registration, metrics.OperationUnregisterConnection)\n\tdefer timer.ObserveDuration()\n\terr := r.client.UnregisterConnection(ctx)\n\tif err != nil {\n\t\tmetrics.CapnpMetrics.ClientFailures.WithLabelValues(metrics.Registration, metrics.OperationUnregisterConnection).Inc()\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (r *registrationClient) Close() {\n\t// Closing the client will also close the connection\n\t_ = r.client.Close()\n\t// Closing the transport also closes the stream\n\t_ = r.transport.Close()\n}\n"
  },
  {
    "path": "tunnelrpc/registration_server.go",
    "content": "package tunnelrpc\n\nimport (\n\t\"context\"\n\t\"io\"\n\n\t\"github.com/cloudflare/cloudflared/tunnelrpc/pogs\"\n)\n\n// RegistrationServer provides a handler interface for a client to provide methods to handle the different types of\n// requests that can be communicated by the stream.\ntype RegistrationServer struct {\n\tregistrationServer pogs.RegistrationServer\n}\n\nfunc NewRegistrationServer(registrationServer pogs.RegistrationServer) *RegistrationServer {\n\treturn &RegistrationServer{\n\t\tregistrationServer: registrationServer,\n\t}\n}\n\n// Serve listens for all RegistrationServer RPCs, including UnregisterConnection until the underlying connection\n// is terminated.\nfunc (s *RegistrationServer) Serve(ctx context.Context, stream io.ReadWriteCloser) error {\n\ttransport := SafeTransport(stream)\n\tdefer transport.Close()\n\n\tmain := pogs.RegistrationServer_ServerToClient(s.registrationServer)\n\trpcConn := NewServerConn(transport, main.Client)\n\n\tselect {\n\tcase <-rpcConn.Done():\n\t\treturn rpcConn.Wait()\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\t}\n}\n"
  },
  {
    "path": "tunnelrpc/utils.go",
    "content": "package tunnelrpc\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/pkg/errors\"\n\tcapnp \"zombiezen.com/go/capnproto2\"\n\t\"zombiezen.com/go/capnproto2/rpc\"\n)\n\nconst (\n\t// These default values are here so that we give some time for the underlying connection/stream\n\t// to recover in the face of what we believe to be temporarily errors.\n\t// We don't want to be too aggressive, as the end result of giving a final error (non-temporary)\n\t// will result in the connection to be dropped.\n\t// In turn, the other side will probably reconnect, which will put again more pressure in the overall system.\n\t// So, the best solution is to give it some conservative time to recover.\n\tdefaultSleepBetweenTemporaryError = 500 * time.Millisecond\n\tdefaultMaxRetries                 = 3\n)\n\ntype readWriterSafeTemporaryErrorCloser struct {\n\tio.ReadWriteCloser\n\n\tretries             int\n\tsleepBetweenRetries time.Duration\n\tmaxRetries          int\n}\n\nfunc (r *readWriterSafeTemporaryErrorCloser) Read(p []byte) (n int, err error) {\n\tn, err = r.ReadWriteCloser.Read(p)\n\n\t// if there was a failure reading from the read closer, and the error is temporary, try again in some seconds\n\t// otherwise, just fail without a temporary error.\n\tif n == 0 && err != nil && isTemporaryError(err) {\n\t\tif r.retries >= r.maxRetries {\n\t\t\treturn 0, errors.Wrap(err, \"failed read from capnproto ReaderWriter after multiple temporary errors\")\n\t\t} else {\n\t\t\tr.retries += 1\n\n\t\t\t// sleep for some time to prevent quick read loops that cause exhaustion of CPU resources\n\t\t\ttime.Sleep(r.sleepBetweenRetries)\n\t\t}\n\t}\n\n\tif err == nil {\n\t\tr.retries = 0\n\t}\n\n\treturn n, err\n}\n\nfunc SafeTransport(rw io.ReadWriteCloser) rpc.Transport {\n\treturn rpc.StreamTransport(&readWriterSafeTemporaryErrorCloser{\n\t\tReadWriteCloser:     rw,\n\t\tmaxRetries:          defaultMaxRetries,\n\t\tsleepBetweenRetries: defaultSleepBetweenTemporaryError,\n\t})\n}\n\n// isTemporaryError reports whether e has a Temporary() method that\n// returns true.\nfunc isTemporaryError(e error) bool {\n\ttype temp interface {\n\t\tTemporary() bool\n\t}\n\tt, ok := e.(temp)\n\treturn ok && t.Temporary()\n}\n\n// NoopCapnpLogger provides a logger to discard all capnp rpc internal logging messages as\n// they are by default provided to stdout if no logger interface is provided. These logging\n// messages in cloudflared have typically not provided a high amount of pratical value\n// as the messages are extremely verbose and don't provide a good insight into the message\n// contents or rpc method names.\ntype noopCapnpLogger struct{}\n\nfunc (noopCapnpLogger) Infof(ctx context.Context, format string, args ...interface{})  {}\nfunc (noopCapnpLogger) Errorf(ctx context.Context, format string, args ...interface{}) {}\n\nfunc NewClientConn(transport rpc.Transport) *rpc.Conn {\n\treturn rpc.NewConn(transport, rpc.ConnLog(noopCapnpLogger{}))\n}\n\nfunc NewServerConn(transport rpc.Transport, client capnp.Client) *rpc.Conn {\n\treturn rpc.NewConn(transport, rpc.MainInterface(client), rpc.ConnLog(noopCapnpLogger{}))\n}\n"
  },
  {
    "path": "tunnelstate/conntracker.go",
    "content": "package tunnelstate\n\nimport (\n\t\"net\"\n\t\"sync\"\n\n\t\"github.com/rs/zerolog\"\n\n\t\"github.com/cloudflare/cloudflared/connection\"\n)\n\ntype ConnTracker struct {\n\tmutex sync.RWMutex\n\t// int is the connection Index\n\tconnectionInfo map[uint8]ConnectionInfo\n\tlog            *zerolog.Logger\n}\n\ntype ConnectionInfo struct {\n\tIsConnected bool                `json:\"isConnected,omitempty\"`\n\tProtocol    connection.Protocol `json:\"protocol,omitempty\"`\n\tEdgeAddress net.IP              `json:\"edgeAddress,omitempty\"`\n}\n\n// Convinience struct to extend the connection with its index.\ntype IndexedConnectionInfo struct {\n\tConnectionInfo\n\tIndex uint8 `json:\"index,omitempty\"`\n}\n\nfunc NewConnTracker(\n\tlog *zerolog.Logger,\n) *ConnTracker {\n\treturn &ConnTracker{\n\t\tconnectionInfo: make(map[uint8]ConnectionInfo, 0),\n\t\tlog:            log,\n\t}\n}\n\nfunc (ct *ConnTracker) OnTunnelEvent(c connection.Event) {\n\tswitch c.EventType {\n\tcase connection.Connected:\n\t\tct.mutex.Lock()\n\t\tci := ConnectionInfo{\n\t\t\tIsConnected: true,\n\t\t\tProtocol:    c.Protocol,\n\t\t\tEdgeAddress: c.EdgeAddress,\n\t\t}\n\t\tct.connectionInfo[c.Index] = ci\n\t\tct.mutex.Unlock()\n\tcase connection.Disconnected, connection.Reconnecting, connection.RegisteringTunnel, connection.Unregistering:\n\t\tct.mutex.Lock()\n\t\tci := ct.connectionInfo[c.Index]\n\t\tci.IsConnected = false\n\t\tct.connectionInfo[c.Index] = ci\n\t\tct.mutex.Unlock()\n\tdefault:\n\t\tct.log.Error().Msgf(\"Unknown connection event case %v\", c)\n\t}\n}\n\nfunc (ct *ConnTracker) CountActiveConns() uint {\n\tct.mutex.RLock()\n\tdefer ct.mutex.RUnlock()\n\tactive := uint(0)\n\tfor _, ci := range ct.connectionInfo {\n\t\tif ci.IsConnected {\n\t\t\tactive++\n\t\t}\n\t}\n\treturn active\n}\n\n// HasConnectedWith checks if we've ever had a successful connection to the edge\n// with said protocol.\nfunc (ct *ConnTracker) HasConnectedWith(protocol connection.Protocol) bool {\n\tct.mutex.RLock()\n\tdefer ct.mutex.RUnlock()\n\tfor _, ci := range ct.connectionInfo {\n\t\tif ci.Protocol == protocol {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Returns the connection information iff it is connected this\n// also leverages the [IndexedConnectionInfo] to also provide the connection index\nfunc (ct *ConnTracker) GetActiveConnections() []IndexedConnectionInfo {\n\tct.mutex.RLock()\n\tdefer ct.mutex.RUnlock()\n\n\tconnections := make([]IndexedConnectionInfo, 0)\n\n\tfor key, value := range ct.connectionInfo {\n\t\tif value.IsConnected {\n\t\t\tinfo := IndexedConnectionInfo{value, key}\n\t\t\tconnections = append(connections, info)\n\t\t}\n\t}\n\n\treturn connections\n}\n"
  },
  {
    "path": "validation/validation.go",
    "content": "package validation\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/coreos/go-oidc/v3/oidc\"\n\t\"github.com/pkg/errors\"\n\t\"golang.org/x/net/idna\"\n)\n\nconst (\n\tdefaultScheme   = \"http\"\n\taccessDomain    = \"cloudflareaccess.com\"\n\taccessCertPath  = \"/cdn-cgi/access/certs\"\n\taccessJwtHeader = \"Cf-access-jwt-assertion\"\n)\n\nvar (\n\tsupportedProtocols = []string{\"http\", \"https\", \"rdp\", \"ssh\", \"smb\", \"tcp\"}\n\tvalidationTimeout  = time.Duration(30 * time.Second)\n)\n\nfunc ValidateHostname(hostname string) (string, error) {\n\tif hostname == \"\" {\n\t\treturn \"\", nil\n\t}\n\t// users gives url(contains schema) not just hostname\n\tif strings.Contains(hostname, \":\") || strings.Contains(hostname, \"%3A\") {\n\t\tunescapeHostname, err := url.PathUnescape(hostname)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"Hostname(actually a URL) %s has invalid escape characters %s\", hostname, unescapeHostname)\n\t\t}\n\t\thostnameToURL, err := url.Parse(unescapeHostname)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"Hostname(actually a URL) %s has invalid format %s\", hostname, hostnameToURL)\n\t\t}\n\t\tasciiHostname, err := idna.ToASCII(hostnameToURL.Hostname())\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"Hostname(actually a URL) %s has invalid ASCII encdoing %s\", hostname, asciiHostname)\n\t\t}\n\t\treturn asciiHostname, nil\n\t}\n\n\tasciiHostname, err := idna.ToASCII(hostname)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"Hostname %s has invalid ASCII encdoing %s\", hostname, asciiHostname)\n\t}\n\thostnameToURL, err := url.Parse(asciiHostname)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"Hostname %s is not valid\", hostnameToURL)\n\t}\n\treturn hostnameToURL.RequestURI(), nil\n\n}\n\n// ValidateUrl returns a validated version of `originUrl` with a scheme prepended (by default http://).\n// Note: when originUrl contains a scheme, the path is removed:\n//\n//\tValidateUrl(\"https://localhost:8080/api/\") => \"https://localhost:8080\"\n//\n// but when it does not, the path is preserved:\n//\n//\tValidateUrl(\"localhost:8080/api/\") => \"http://localhost:8080/api/\"\n//\n// This is arguably a bug, but changing it might break some cloudflared users.\nfunc ValidateUrl(originUrl string) (*url.URL, error) {\n\turlStr, err := validateUrlString(originUrl)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn url.Parse(urlStr)\n}\n\nfunc validateUrlString(originUrl string) (string, error) {\n\tif originUrl == \"\" {\n\t\treturn \"\", fmt.Errorf(\"URL should not be empty\")\n\t}\n\n\tif net.ParseIP(originUrl) != nil {\n\t\treturn validateIP(\"\", originUrl, \"\")\n\t} else if strings.HasPrefix(originUrl, \"[\") && strings.HasSuffix(originUrl, \"]\") {\n\t\t// ParseIP doesn't recoginze [::1]\n\t\treturn validateIP(\"\", originUrl[1:len(originUrl)-1], \"\")\n\t}\n\n\thost, port, err := net.SplitHostPort(originUrl)\n\t// user might pass in an ip address like 127.0.0.1\n\tif err == nil && net.ParseIP(host) != nil {\n\t\treturn validateIP(\"\", host, port)\n\t}\n\n\tunescapedUrl, err := url.PathUnescape(originUrl)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"URL %s has invalid escape characters %s\", originUrl, unescapedUrl)\n\t}\n\n\tparsedUrl, err := url.Parse(unescapedUrl)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"URL %s has invalid format\", originUrl)\n\t}\n\n\t// if the url is in the form of host:port, IsAbs() will think host is the schema\n\tvar hostname string\n\thasScheme := parsedUrl.IsAbs() && parsedUrl.Host != \"\"\n\tif hasScheme {\n\t\terr := validateScheme(parsedUrl.Scheme)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\t// The earlier check for ip address will miss the case http://[::1]\n\t\t// and http://[::1]:8080\n\t\tif net.ParseIP(parsedUrl.Hostname()) != nil {\n\t\t\treturn validateIP(parsedUrl.Scheme, parsedUrl.Hostname(), parsedUrl.Port())\n\t\t}\n\t\thostname, err = ValidateHostname(parsedUrl.Hostname())\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"URL %s has invalid format\", originUrl)\n\t\t}\n\t\tif parsedUrl.Port() != \"\" {\n\t\t\treturn fmt.Sprintf(\"%s://%s\", parsedUrl.Scheme, net.JoinHostPort(hostname, parsedUrl.Port())), nil\n\t\t}\n\t\treturn fmt.Sprintf(\"%s://%s\", parsedUrl.Scheme, hostname), nil\n\t} else {\n\t\tif host == \"\" {\n\t\t\thostname, err = ValidateHostname(originUrl)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", fmt.Errorf(\"URL no %s has invalid format\", originUrl)\n\t\t\t}\n\t\t\treturn fmt.Sprintf(\"%s://%s\", defaultScheme, hostname), nil\n\t\t} else {\n\t\t\thostname, err = ValidateHostname(host)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", fmt.Errorf(\"URL %s has invalid format\", originUrl)\n\t\t\t}\n\t\t\t// This is why the path is preserved when `originUrl` doesn't have a schema.\n\t\t\t// Using `parsedUrl.Port()` here, instead of `port`, would remove the path\n\t\t\treturn fmt.Sprintf(\"%s://%s\", defaultScheme, net.JoinHostPort(hostname, port)), nil\n\t\t}\n\t}\n\n}\n\nfunc validateScheme(scheme string) error {\n\tfor _, protocol := range supportedProtocols {\n\t\tif scheme == protocol {\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn fmt.Errorf(\"Currently Cloudflare Tunnel does not support %s protocol.\", scheme)\n}\n\nfunc validateIP(scheme, host, port string) (string, error) {\n\tif scheme == \"\" {\n\t\tscheme = defaultScheme\n\t}\n\tif port != \"\" {\n\t\treturn fmt.Sprintf(\"%s://%s\", scheme, net.JoinHostPort(host, port)), nil\n\t} else if strings.Contains(host, \":\") {\n\t\t// IPv6\n\t\treturn fmt.Sprintf(\"%s://[%s]\", scheme, host), nil\n\t}\n\treturn fmt.Sprintf(\"%s://%s\", scheme, host), nil\n}\n\n// Access checks if a JWT from Cloudflare Access is valid.\ntype Access struct {\n\tverifier *oidc.IDTokenVerifier\n}\n\nfunc NewAccessValidator(ctx context.Context, domain, issuer, applicationAUD string) (*Access, error) {\n\tdomainURL, err := validateUrlString(domain)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tissuerURL, err := validateUrlString(issuer)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// An issuerURL from Cloudflare Access will always use HTTPS.\n\tissuerURL = strings.Replace(issuerURL, \"http:\", \"https:\", 1)\n\n\tkeySet := oidc.NewRemoteKeySet(ctx, domainURL+accessCertPath)\n\treturn &Access{oidc.NewVerifier(issuerURL, keySet, &oidc.Config{ClientID: applicationAUD})}, nil\n}\n\nfunc (a *Access) Validate(ctx context.Context, jwt string) error {\n\ttoken, err := a.verifier.Verify(ctx, jwt)\n\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"token is invalid: %s\", jwt)\n\t}\n\n\t// Perform extra sanity checks, just to be safe.\n\n\tif token == nil {\n\t\treturn fmt.Errorf(\"token is nil: %s\", jwt)\n\t}\n\n\tif !strings.HasSuffix(token.Issuer, accessDomain) {\n\t\treturn fmt.Errorf(\"token has non-cloudflare issuer of %s: %s\", token.Issuer, jwt)\n\t}\n\n\treturn nil\n}\n\nfunc (a *Access) ValidateRequest(ctx context.Context, r *http.Request) error {\n\treturn a.Validate(ctx, r.Header.Get(accessJwtHeader))\n}\n"
  },
  {
    "path": "validation/validation_test.go",
    "content": "package validation\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"testing\"\n\n\t\"context\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"net/url\"\n\t\"strings\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestValidateHostname(t *testing.T) {\n\tvar inputHostname string\n\thostname, err := ValidateHostname(inputHostname)\n\tassert.Equal(t, err, nil)\n\tassert.Empty(t, hostname)\n\n\tinputHostname = \"hello.example.com\"\n\thostname, err = ValidateHostname(inputHostname)\n\tassert.Nil(t, err)\n\tassert.Equal(t, \"hello.example.com\", hostname)\n\n\tinputHostname = \"http://hello.example.com\"\n\thostname, err = ValidateHostname(inputHostname)\n\tassert.Nil(t, err)\n\tassert.Equal(t, \"hello.example.com\", hostname)\n\n\tinputHostname = \"bücher.example.com\"\n\thostname, err = ValidateHostname(inputHostname)\n\tassert.Nil(t, err)\n\tassert.Equal(t, \"xn--bcher-kva.example.com\", hostname)\n\n\tinputHostname = \"http://bücher.example.com\"\n\thostname, err = ValidateHostname(inputHostname)\n\tassert.Nil(t, err)\n\tassert.Equal(t, \"xn--bcher-kva.example.com\", hostname)\n\n\tinputHostname = \"http%3A%2F%2Fhello.example.com\"\n\thostname, err = ValidateHostname(inputHostname)\n\tassert.Nil(t, err)\n\tassert.Equal(t, \"hello.example.com\", hostname)\n\n}\n\nfunc TestValidateUrl(t *testing.T) {\n\ttype testCase struct {\n\t\tinput          string\n\t\texpectedOutput string\n\t}\n\ttestCases := []testCase{\n\t\t{\"http://localhost\", \"http://localhost\"},\n\t\t{\"http://localhost/\", \"http://localhost\"},\n\t\t{\"http://localhost/api\", \"http://localhost\"},\n\t\t{\"http://localhost/api/\", \"http://localhost\"},\n\t\t{\"https://localhost\", \"https://localhost\"},\n\t\t{\"https://localhost/\", \"https://localhost\"},\n\t\t{\"https://localhost/api\", \"https://localhost\"},\n\t\t{\"https://localhost/api/\", \"https://localhost\"},\n\t\t{\"https://localhost:8080\", \"https://localhost:8080\"},\n\t\t{\"https://localhost:8080/\", \"https://localhost:8080\"},\n\t\t{\"https://localhost:8080/api\", \"https://localhost:8080\"},\n\t\t{\"https://localhost:8080/api/\", \"https://localhost:8080\"},\n\t\t{\"localhost\", \"http://localhost\"},\n\t\t{\"localhost/\", \"http://localhost/\"},\n\t\t{\"localhost/api\", \"http://localhost/api\"},\n\t\t{\"localhost/api/\", \"http://localhost/api/\"},\n\t\t{\"localhost:8080\", \"http://localhost:8080\"},\n\t\t{\"localhost:8080/\", \"http://localhost:8080/\"},\n\t\t{\"localhost:8080/api\", \"http://localhost:8080/api\"},\n\t\t{\"localhost:8080/api/\", \"http://localhost:8080/api/\"},\n\t\t{\"localhost:8080/api/?asdf\", \"http://localhost:8080/api/?asdf\"},\n\t\t{\"http://127.0.0.1:8080\", \"http://127.0.0.1:8080\"},\n\t\t{\"127.0.0.1:8080\", \"http://127.0.0.1:8080\"},\n\t\t{\"127.0.0.1\", \"http://127.0.0.1\"},\n\t\t{\"https://127.0.0.1:8080\", \"https://127.0.0.1:8080\"},\n\t\t{\"[::1]:8080\", \"http://[::1]:8080\"},\n\t\t{\"http://[::1]\", \"http://[::1]\"},\n\t\t{\"http://[::1]:8080\", \"http://[::1]:8080\"},\n\t\t{\"[::1]\", \"http://[::1]\"},\n\t\t{\"https://example.com\", \"https://example.com\"},\n\t\t{\"example.com\", \"http://example.com\"},\n\t\t{\"http://hello.example.com\", \"http://hello.example.com\"},\n\t\t{\"hello.example.com\", \"http://hello.example.com\"},\n\t\t{\"hello.example.com:8080\", \"http://hello.example.com:8080\"},\n\t\t{\"https://hello.example.com:8080\", \"https://hello.example.com:8080\"},\n\t\t{\"https://bücher.example.com\", \"https://xn--bcher-kva.example.com\"},\n\t\t{\"bücher.example.com\", \"http://xn--bcher-kva.example.com\"},\n\t\t{\"https%3A%2F%2Fhello.example.com\", \"https://hello.example.com\"},\n\t\t{\"https://alex:12345@hello.example.com:8080\", \"https://hello.example.com:8080\"},\n\t}\n\tfor i, testCase := range testCases {\n\t\tvalidUrl, err := ValidateUrl(testCase.input)\n\t\tassert.NoError(t, err, \"test case %v\", i)\n\t\tassert.Equal(t, testCase.expectedOutput, validUrl.String(), \"test case %v\", i)\n\t}\n\n\tvalidUrl, err := ValidateUrl(\"\")\n\tassert.Equal(t, fmt.Errorf(\"URL should not be empty\"), err)\n\tassert.Empty(t, validUrl)\n\n\tvalidUrl, err = ValidateUrl(\"ftp://alex:12345@hello.example.com:8080/robot.txt\")\n\tassert.Equal(t, \"Currently Cloudflare Tunnel does not support ftp protocol.\", err.Error())\n\tassert.Empty(t, validUrl)\n\n}\n\nfunc TestNewAccessValidatorOk(t *testing.T) {\n\tctx := context.Background()\n\turl := \"test.cloudflareaccess.com\"\n\taccess, err := NewAccessValidator(ctx, url, url, \"\")\n\n\tassert.NoError(t, err)\n\tassert.NotNil(t, access)\n\n\tassert.Error(t, access.Validate(ctx, \"\"))\n\tassert.Error(t, access.Validate(ctx, \"invalid\"))\n\n\treq := httptest.NewRequest(\"GET\", \"https://test.cloudflareaccess.com\", nil)\n\treq.Header.Set(accessJwtHeader, \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c\")\n\tassert.Error(t, access.ValidateRequest(ctx, req))\n}\n\nfunc TestNewAccessValidatorErr(t *testing.T) {\n\tctx := context.Background()\n\n\turls := []string{\n\t\t\"\",\n\t\t\"ftp://test.cloudflareaccess.com\",\n\t\t\"wss://cloudflarenone.com\",\n\t}\n\n\tfor _, url := range urls {\n\t\taccess, err := NewAccessValidator(ctx, url, url, \"\")\n\n\t\tassert.Error(t, err, url)\n\t\tassert.Nil(t, access)\n\t}\n}\n\ntype testRoundTripper func(req *http.Request) (*http.Response, error)\n\nfunc (f testRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {\n\treturn f(req)\n}\n\nfunc emptyResponse(statusCode int) *http.Response {\n\treturn &http.Response{\n\t\tStatusCode: statusCode,\n\t\tBody:       io.NopCloser(bytes.NewReader(nil)),\n\t\tHeader:     make(http.Header),\n\t}\n}\n\nfunc createMockServerAndClient(handler http.Handler) (*httptest.Server, *http.Client, error) {\n\tclient := http.DefaultClient\n\tserver := httptest.NewServer(handler)\n\n\tclient.Transport = &http.Transport{\n\t\tProxy: func(req *http.Request) (*url.URL, error) {\n\t\t\treturn url.Parse(server.URL)\n\t\t},\n\t}\n\n\treturn server, client, nil\n}\n\nfunc createSecureMockServerAndClient(handler http.Handler) (*httptest.Server, *http.Client, error) {\n\tclient := http.DefaultClient\n\tserver := httptest.NewTLSServer(handler)\n\n\tcert, err := x509.ParseCertificate(server.TLS.Certificates[0].Certificate[0])\n\tif err != nil {\n\t\tserver.Close()\n\t\treturn nil, nil, err\n\t}\n\n\tcertpool := x509.NewCertPool()\n\tcertpool.AddCert(cert)\n\n\tclient.Transport = &http.Transport{\n\t\tDialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {\n\t\t\treturn net.Dial(\"tcp\", server.URL[strings.LastIndex(server.URL, \"/\")+1:])\n\t\t},\n\t\tTLSClientConfig: &tls.Config{\n\t\t\tRootCAs: certpool,\n\t\t},\n\t}\n\n\treturn server, client, nil\n}\n\nfunc FuzzNewAccessValidator(f *testing.F) {\n\tf.Fuzz(func(t *testing.T, domain string, issuer string, applicationAUD string) {\n\t\tctx := context.Background()\n\t\t_, _ = NewAccessValidator(ctx, domain, issuer, applicationAUD)\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/BurntSushi/toml/.gitignore",
    "content": "/toml.test\n/toml-test\n"
  },
  {
    "path": "vendor/github.com/BurntSushi/toml/COPYING",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013 TOML authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/BurntSushi/toml/README.md",
    "content": "TOML stands for Tom's Obvious, Minimal Language. This Go package provides a\nreflection interface similar to Go's standard library `json` and `xml` packages.\n\nCompatible with TOML version [v1.0.0](https://toml.io/en/v1.0.0).\n\nDocumentation: https://godocs.io/github.com/BurntSushi/toml\n\nSee the [releases page](https://github.com/BurntSushi/toml/releases) for a\nchangelog; this information is also in the git tag annotations (e.g. `git show\nv0.4.0`).\n\nThis library requires Go 1.13 or newer; add it to your go.mod with:\n\n    % go get github.com/BurntSushi/toml@latest\n\nIt also comes with a TOML validator CLI tool:\n\n    % go install github.com/BurntSushi/toml/cmd/tomlv@latest\n    % tomlv some-toml-file.toml\n\n### Examples\nFor the simplest example, consider some TOML file as just a list of keys and\nvalues:\n\n```toml\nAge = 25\nCats = [ \"Cauchy\", \"Plato\" ]\nPi = 3.14\nPerfection = [ 6, 28, 496, 8128 ]\nDOB = 1987-07-05T05:45:00Z\n```\n\nWhich can be decoded with:\n\n```go\ntype Config struct {\n\tAge        int\n\tCats       []string\n\tPi         float64\n\tPerfection []int\n\tDOB        time.Time\n}\n\nvar conf Config\n_, err := toml.Decode(tomlData, &conf)\n```\n\nYou can also use struct tags if your struct field name doesn't map to a TOML key\nvalue directly:\n\n```toml\nsome_key_NAME = \"wat\"\n```\n\n```go\ntype TOML struct {\n    ObscureKey string `toml:\"some_key_NAME\"`\n}\n```\n\nBeware that like other decoders **only exported fields** are considered when\nencoding and decoding; private fields are silently ignored.\n\n### Using the `Marshaler` and `encoding.TextUnmarshaler` interfaces\nHere's an example that automatically parses values in a `mail.Address`:\n\n```toml\ncontacts = [\n    \"Donald Duck <donald@duckburg.com>\",\n    \"Scrooge McDuck <scrooge@duckburg.com>\",\n]\n```\n\nCan be decoded with:\n\n```go\n// Create address type which satisfies the encoding.TextUnmarshaler interface.\ntype address struct {\n\t*mail.Address\n}\n\nfunc (a *address) UnmarshalText(text []byte) error {\n\tvar err error\n\ta.Address, err = mail.ParseAddress(string(text))\n\treturn err\n}\n\n// Decode it.\nfunc decode() {\n\tblob := `\n\t\tcontacts = [\n\t\t\t\"Donald Duck <donald@duckburg.com>\",\n\t\t\t\"Scrooge McDuck <scrooge@duckburg.com>\",\n\t\t]\n\t`\n\n\tvar contacts struct {\n\t\tContacts []address\n\t}\n\n\t_, err := toml.Decode(blob, &contacts)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfor _, c := range contacts.Contacts {\n\t\tfmt.Printf(\"%#v\\n\", c.Address)\n\t}\n\n\t// Output:\n\t// &mail.Address{Name:\"Donald Duck\", Address:\"donald@duckburg.com\"}\n\t// &mail.Address{Name:\"Scrooge McDuck\", Address:\"scrooge@duckburg.com\"}\n}\n```\n\nTo target TOML specifically you can implement `UnmarshalTOML` TOML interface in\na similar way.\n\n### More complex usage\nSee the [`_example/`](/_example) directory for a more complex example.\n"
  },
  {
    "path": "vendor/github.com/BurntSushi/toml/decode.go",
    "content": "package toml\n\nimport (\n\t\"bytes\"\n\t\"encoding\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"math\"\n\t\"os\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\n// Unmarshaler is the interface implemented by objects that can unmarshal a\n// TOML description of themselves.\ntype Unmarshaler interface {\n\tUnmarshalTOML(interface{}) error\n}\n\n// Unmarshal decodes the contents of `data` in TOML format into a pointer `v`.\nfunc Unmarshal(data []byte, v interface{}) error {\n\t_, err := NewDecoder(bytes.NewReader(data)).Decode(v)\n\treturn err\n}\n\n// Decode the TOML data in to the pointer v.\n//\n// See the documentation on Decoder for a description of the decoding process.\nfunc Decode(data string, v interface{}) (MetaData, error) {\n\treturn NewDecoder(strings.NewReader(data)).Decode(v)\n}\n\n// DecodeFile is just like Decode, except it will automatically read the\n// contents of the file at path and decode it for you.\nfunc DecodeFile(path string, v interface{}) (MetaData, error) {\n\tfp, err := os.Open(path)\n\tif err != nil {\n\t\treturn MetaData{}, err\n\t}\n\tdefer fp.Close()\n\treturn NewDecoder(fp).Decode(v)\n}\n\n// Primitive is a TOML value that hasn't been decoded into a Go value.\n//\n// This type can be used for any value, which will cause decoding to be delayed.\n// You can use the PrimitiveDecode() function to \"manually\" decode these values.\n//\n// NOTE: The underlying representation of a `Primitive` value is subject to\n// change. Do not rely on it.\n//\n// NOTE: Primitive values are still parsed, so using them will only avoid the\n// overhead of reflection. They can be useful when you don't know the exact type\n// of TOML data until runtime.\ntype Primitive struct {\n\tundecoded interface{}\n\tcontext   Key\n}\n\n// The significand precision for float32 and float64 is 24 and 53 bits; this is\n// the range a natural number can be stored in a float without loss of data.\nconst (\n\tmaxSafeFloat32Int = 16777215                // 2^24-1\n\tmaxSafeFloat64Int = int64(9007199254740991) // 2^53-1\n)\n\n// Decoder decodes TOML data.\n//\n// TOML tables correspond to Go structs or maps (dealer's choice – they can be\n// used interchangeably).\n//\n// TOML table arrays correspond to either a slice of structs or a slice of maps.\n//\n// TOML datetimes correspond to Go time.Time values. Local datetimes are parsed\n// in the local timezone.\n//\n// time.Duration types are treated as nanoseconds if the TOML value is an\n// integer, or they're parsed with time.ParseDuration() if they're strings.\n//\n// All other TOML types (float, string, int, bool and array) correspond to the\n// obvious Go types.\n//\n// An exception to the above rules is if a type implements the TextUnmarshaler\n// interface, in which case any primitive TOML value (floats, strings, integers,\n// booleans, datetimes) will be converted to a []byte and given to the value's\n// UnmarshalText method. See the Unmarshaler example for a demonstration with\n// email addresses.\n//\n// Key mapping\n//\n// TOML keys can map to either keys in a Go map or field names in a Go struct.\n// The special `toml` struct tag can be used to map TOML keys to struct fields\n// that don't match the key name exactly (see the example). A case insensitive\n// match to struct names will be tried if an exact match can't be found.\n//\n// The mapping between TOML values and Go values is loose. That is, there may\n// exist TOML values that cannot be placed into your representation, and there\n// may be parts of your representation that do not correspond to TOML values.\n// This loose mapping can be made stricter by using the IsDefined and/or\n// Undecoded methods on the MetaData returned.\n//\n// This decoder does not handle cyclic types. Decode will not terminate if a\n// cyclic type is passed.\ntype Decoder struct {\n\tr io.Reader\n}\n\n// NewDecoder creates a new Decoder.\nfunc NewDecoder(r io.Reader) *Decoder {\n\treturn &Decoder{r: r}\n}\n\nvar (\n\tunmarshalToml = reflect.TypeOf((*Unmarshaler)(nil)).Elem()\n\tunmarshalText = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()\n\tprimitiveType = reflect.TypeOf((*Primitive)(nil)).Elem()\n)\n\n// Decode TOML data in to the pointer `v`.\nfunc (dec *Decoder) Decode(v interface{}) (MetaData, error) {\n\trv := reflect.ValueOf(v)\n\tif rv.Kind() != reflect.Ptr {\n\t\ts := \"%q\"\n\t\tif reflect.TypeOf(v) == nil {\n\t\t\ts = \"%v\"\n\t\t}\n\n\t\treturn MetaData{}, fmt.Errorf(\"toml: cannot decode to non-pointer \"+s, reflect.TypeOf(v))\n\t}\n\tif rv.IsNil() {\n\t\treturn MetaData{}, fmt.Errorf(\"toml: cannot decode to nil value of %q\", reflect.TypeOf(v))\n\t}\n\n\t// Check if this is a supported type: struct, map, interface{}, or something\n\t// that implements UnmarshalTOML or UnmarshalText.\n\trv = indirect(rv)\n\trt := rv.Type()\n\tif rv.Kind() != reflect.Struct && rv.Kind() != reflect.Map &&\n\t\t!(rv.Kind() == reflect.Interface && rv.NumMethod() == 0) &&\n\t\t!rt.Implements(unmarshalToml) && !rt.Implements(unmarshalText) {\n\t\treturn MetaData{}, fmt.Errorf(\"toml: cannot decode to type %s\", rt)\n\t}\n\n\t// TODO: parser should read from io.Reader? Or at the very least, make it\n\t// read from []byte rather than string\n\tdata, err := ioutil.ReadAll(dec.r)\n\tif err != nil {\n\t\treturn MetaData{}, err\n\t}\n\n\tp, err := parse(string(data))\n\tif err != nil {\n\t\treturn MetaData{}, err\n\t}\n\n\tmd := MetaData{\n\t\tmapping: p.mapping,\n\t\tkeyInfo: p.keyInfo,\n\t\tkeys:    p.ordered,\n\t\tdecoded: make(map[string]struct{}, len(p.ordered)),\n\t\tcontext: nil,\n\t\tdata:    data,\n\t}\n\treturn md, md.unify(p.mapping, rv)\n}\n\n// PrimitiveDecode is just like the other `Decode*` functions, except it\n// decodes a TOML value that has already been parsed. Valid primitive values\n// can *only* be obtained from values filled by the decoder functions,\n// including this method. (i.e., `v` may contain more `Primitive`\n// values.)\n//\n// Meta data for primitive values is included in the meta data returned by\n// the `Decode*` functions with one exception: keys returned by the Undecoded\n// method will only reflect keys that were decoded. Namely, any keys hidden\n// behind a Primitive will be considered undecoded. Executing this method will\n// update the undecoded keys in the meta data. (See the example.)\nfunc (md *MetaData) PrimitiveDecode(primValue Primitive, v interface{}) error {\n\tmd.context = primValue.context\n\tdefer func() { md.context = nil }()\n\treturn md.unify(primValue.undecoded, rvalue(v))\n}\n\n// unify performs a sort of type unification based on the structure of `rv`,\n// which is the client representation.\n//\n// Any type mismatch produces an error. Finding a type that we don't know\n// how to handle produces an unsupported type error.\nfunc (md *MetaData) unify(data interface{}, rv reflect.Value) error {\n\t// Special case. Look for a `Primitive` value.\n\t// TODO: #76 would make this superfluous after implemented.\n\tif rv.Type() == primitiveType {\n\t\t// Save the undecoded data and the key context into the primitive\n\t\t// value.\n\t\tcontext := make(Key, len(md.context))\n\t\tcopy(context, md.context)\n\t\trv.Set(reflect.ValueOf(Primitive{\n\t\t\tundecoded: data,\n\t\t\tcontext:   context,\n\t\t}))\n\t\treturn nil\n\t}\n\n\trvi := rv.Interface()\n\tif v, ok := rvi.(Unmarshaler); ok {\n\t\treturn v.UnmarshalTOML(data)\n\t}\n\tif v, ok := rvi.(encoding.TextUnmarshaler); ok {\n\t\treturn md.unifyText(data, v)\n\t}\n\n\t// TODO:\n\t// The behavior here is incorrect whenever a Go type satisfies the\n\t// encoding.TextUnmarshaler interface but also corresponds to a TOML hash or\n\t// array. In particular, the unmarshaler should only be applied to primitive\n\t// TOML values. But at this point, it will be applied to all kinds of values\n\t// and produce an incorrect error whenever those values are hashes or arrays\n\t// (including arrays of tables).\n\n\tk := rv.Kind()\n\n\tif k >= reflect.Int && k <= reflect.Uint64 {\n\t\treturn md.unifyInt(data, rv)\n\t}\n\tswitch k {\n\tcase reflect.Ptr:\n\t\telem := reflect.New(rv.Type().Elem())\n\t\terr := md.unify(data, reflect.Indirect(elem))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trv.Set(elem)\n\t\treturn nil\n\tcase reflect.Struct:\n\t\treturn md.unifyStruct(data, rv)\n\tcase reflect.Map:\n\t\treturn md.unifyMap(data, rv)\n\tcase reflect.Array:\n\t\treturn md.unifyArray(data, rv)\n\tcase reflect.Slice:\n\t\treturn md.unifySlice(data, rv)\n\tcase reflect.String:\n\t\treturn md.unifyString(data, rv)\n\tcase reflect.Bool:\n\t\treturn md.unifyBool(data, rv)\n\tcase reflect.Interface:\n\t\tif rv.NumMethod() > 0 { // Only support empty interfaces are supported.\n\t\t\treturn md.e(\"unsupported type %s\", rv.Type())\n\t\t}\n\t\treturn md.unifyAnything(data, rv)\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn md.unifyFloat64(data, rv)\n\t}\n\treturn md.e(\"unsupported type %s\", rv.Kind())\n}\n\nfunc (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error {\n\ttmap, ok := mapping.(map[string]interface{})\n\tif !ok {\n\t\tif mapping == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn md.e(\"type mismatch for %s: expected table but found %T\",\n\t\t\trv.Type().String(), mapping)\n\t}\n\n\tfor key, datum := range tmap {\n\t\tvar f *field\n\t\tfields := cachedTypeFields(rv.Type())\n\t\tfor i := range fields {\n\t\t\tff := &fields[i]\n\t\t\tif ff.name == key {\n\t\t\t\tf = ff\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif f == nil && strings.EqualFold(ff.name, key) {\n\t\t\t\tf = ff\n\t\t\t}\n\t\t}\n\t\tif f != nil {\n\t\t\tsubv := rv\n\t\t\tfor _, i := range f.index {\n\t\t\t\tsubv = indirect(subv.Field(i))\n\t\t\t}\n\n\t\t\tif isUnifiable(subv) {\n\t\t\t\tmd.decoded[md.context.add(key).String()] = struct{}{}\n\t\t\t\tmd.context = append(md.context, key)\n\n\t\t\t\terr := md.unify(datum, subv)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tmd.context = md.context[0 : len(md.context)-1]\n\t\t\t} else if f.name != \"\" {\n\t\t\t\treturn md.e(\"cannot write unexported field %s.%s\", rv.Type().String(), f.name)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (md *MetaData) unifyMap(mapping interface{}, rv reflect.Value) error {\n\tkeyType := rv.Type().Key().Kind()\n\tif keyType != reflect.String && keyType != reflect.Interface {\n\t\treturn fmt.Errorf(\"toml: cannot decode to a map with non-string key type (%s in %q)\",\n\t\t\tkeyType, rv.Type())\n\t}\n\n\ttmap, ok := mapping.(map[string]interface{})\n\tif !ok {\n\t\tif tmap == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn md.badtype(\"map\", mapping)\n\t}\n\tif rv.IsNil() {\n\t\trv.Set(reflect.MakeMap(rv.Type()))\n\t}\n\tfor k, v := range tmap {\n\t\tmd.decoded[md.context.add(k).String()] = struct{}{}\n\t\tmd.context = append(md.context, k)\n\n\t\trvval := reflect.Indirect(reflect.New(rv.Type().Elem()))\n\n\t\terr := md.unify(v, indirect(rvval))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tmd.context = md.context[0 : len(md.context)-1]\n\n\t\trvkey := indirect(reflect.New(rv.Type().Key()))\n\n\t\tswitch keyType {\n\t\tcase reflect.Interface:\n\t\t\trvkey.Set(reflect.ValueOf(k))\n\t\tcase reflect.String:\n\t\t\trvkey.SetString(k)\n\t\t}\n\n\t\trv.SetMapIndex(rvkey, rvval)\n\t}\n\treturn nil\n}\n\nfunc (md *MetaData) unifyArray(data interface{}, rv reflect.Value) error {\n\tdatav := reflect.ValueOf(data)\n\tif datav.Kind() != reflect.Slice {\n\t\tif !datav.IsValid() {\n\t\t\treturn nil\n\t\t}\n\t\treturn md.badtype(\"slice\", data)\n\t}\n\tif l := datav.Len(); l != rv.Len() {\n\t\treturn md.e(\"expected array length %d; got TOML array of length %d\", rv.Len(), l)\n\t}\n\treturn md.unifySliceArray(datav, rv)\n}\n\nfunc (md *MetaData) unifySlice(data interface{}, rv reflect.Value) error {\n\tdatav := reflect.ValueOf(data)\n\tif datav.Kind() != reflect.Slice {\n\t\tif !datav.IsValid() {\n\t\t\treturn nil\n\t\t}\n\t\treturn md.badtype(\"slice\", data)\n\t}\n\tn := datav.Len()\n\tif rv.IsNil() || rv.Cap() < n {\n\t\trv.Set(reflect.MakeSlice(rv.Type(), n, n))\n\t}\n\trv.SetLen(n)\n\treturn md.unifySliceArray(datav, rv)\n}\n\nfunc (md *MetaData) unifySliceArray(data, rv reflect.Value) error {\n\tl := data.Len()\n\tfor i := 0; i < l; i++ {\n\t\terr := md.unify(data.Index(i).Interface(), indirect(rv.Index(i)))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (md *MetaData) unifyString(data interface{}, rv reflect.Value) error {\n\t_, ok := rv.Interface().(json.Number)\n\tif ok {\n\t\tif i, ok := data.(int64); ok {\n\t\t\trv.SetString(strconv.FormatInt(i, 10))\n\t\t} else if f, ok := data.(float64); ok {\n\t\t\trv.SetString(strconv.FormatFloat(f, 'f', -1, 64))\n\t\t} else {\n\t\t\treturn md.badtype(\"string\", data)\n\t\t}\n\t\treturn nil\n\t}\n\n\tif s, ok := data.(string); ok {\n\t\trv.SetString(s)\n\t\treturn nil\n\t}\n\treturn md.badtype(\"string\", data)\n}\n\nfunc (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error {\n\trvk := rv.Kind()\n\n\tif num, ok := data.(float64); ok {\n\t\tswitch rvk {\n\t\tcase reflect.Float32:\n\t\t\tif num < -math.MaxFloat32 || num > math.MaxFloat32 {\n\t\t\t\treturn md.parseErr(errParseRange{i: num, size: rvk.String()})\n\t\t\t}\n\t\t\tfallthrough\n\t\tcase reflect.Float64:\n\t\t\trv.SetFloat(num)\n\t\tdefault:\n\t\t\tpanic(\"bug\")\n\t\t}\n\t\treturn nil\n\t}\n\n\tif num, ok := data.(int64); ok {\n\t\tif (rvk == reflect.Float32 && (num < -maxSafeFloat32Int || num > maxSafeFloat32Int)) ||\n\t\t\t(rvk == reflect.Float64 && (num < -maxSafeFloat64Int || num > maxSafeFloat64Int)) {\n\t\t\treturn md.parseErr(errParseRange{i: num, size: rvk.String()})\n\t\t}\n\t\trv.SetFloat(float64(num))\n\t\treturn nil\n\t}\n\n\treturn md.badtype(\"float\", data)\n}\n\nfunc (md *MetaData) unifyInt(data interface{}, rv reflect.Value) error {\n\t_, ok := rv.Interface().(time.Duration)\n\tif ok {\n\t\t// Parse as string duration, and fall back to regular integer parsing\n\t\t// (as nanosecond) if this is not a string.\n\t\tif s, ok := data.(string); ok {\n\t\t\tdur, err := time.ParseDuration(s)\n\t\t\tif err != nil {\n\t\t\t\treturn md.parseErr(errParseDuration{s})\n\t\t\t}\n\t\t\trv.SetInt(int64(dur))\n\t\t\treturn nil\n\t\t}\n\t}\n\n\tnum, ok := data.(int64)\n\tif !ok {\n\t\treturn md.badtype(\"integer\", data)\n\t}\n\n\trvk := rv.Kind()\n\tswitch {\n\tcase rvk >= reflect.Int && rvk <= reflect.Int64:\n\t\tif (rvk == reflect.Int8 && (num < math.MinInt8 || num > math.MaxInt8)) ||\n\t\t\t(rvk == reflect.Int16 && (num < math.MinInt16 || num > math.MaxInt16)) ||\n\t\t\t(rvk == reflect.Int32 && (num < math.MinInt32 || num > math.MaxInt32)) {\n\t\t\treturn md.parseErr(errParseRange{i: num, size: rvk.String()})\n\t\t}\n\t\trv.SetInt(num)\n\tcase rvk >= reflect.Uint && rvk <= reflect.Uint64:\n\t\tunum := uint64(num)\n\t\tif rvk == reflect.Uint8 && (num < 0 || unum > math.MaxUint8) ||\n\t\t\trvk == reflect.Uint16 && (num < 0 || unum > math.MaxUint16) ||\n\t\t\trvk == reflect.Uint32 && (num < 0 || unum > math.MaxUint32) {\n\t\t\treturn md.parseErr(errParseRange{i: num, size: rvk.String()})\n\t\t}\n\t\trv.SetUint(unum)\n\tdefault:\n\t\tpanic(\"unreachable\")\n\t}\n\treturn nil\n}\n\nfunc (md *MetaData) unifyBool(data interface{}, rv reflect.Value) error {\n\tif b, ok := data.(bool); ok {\n\t\trv.SetBool(b)\n\t\treturn nil\n\t}\n\treturn md.badtype(\"boolean\", data)\n}\n\nfunc (md *MetaData) unifyAnything(data interface{}, rv reflect.Value) error {\n\trv.Set(reflect.ValueOf(data))\n\treturn nil\n}\n\nfunc (md *MetaData) unifyText(data interface{}, v encoding.TextUnmarshaler) error {\n\tvar s string\n\tswitch sdata := data.(type) {\n\tcase Marshaler:\n\t\ttext, err := sdata.MarshalTOML()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\ts = string(text)\n\tcase encoding.TextMarshaler:\n\t\ttext, err := sdata.MarshalText()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\ts = string(text)\n\tcase fmt.Stringer:\n\t\ts = sdata.String()\n\tcase string:\n\t\ts = sdata\n\tcase bool:\n\t\ts = fmt.Sprintf(\"%v\", sdata)\n\tcase int64:\n\t\ts = fmt.Sprintf(\"%d\", sdata)\n\tcase float64:\n\t\ts = fmt.Sprintf(\"%f\", sdata)\n\tdefault:\n\t\treturn md.badtype(\"primitive (string-like)\", data)\n\t}\n\tif err := v.UnmarshalText([]byte(s)); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (md *MetaData) badtype(dst string, data interface{}) error {\n\treturn md.e(\"incompatible types: TOML value has type %T; destination has type %s\", data, dst)\n}\n\nfunc (md *MetaData) parseErr(err error) error {\n\tk := md.context.String()\n\treturn ParseError{\n\t\tLastKey:  k,\n\t\tPosition: md.keyInfo[k].pos,\n\t\tLine:     md.keyInfo[k].pos.Line,\n\t\terr:      err,\n\t\tinput:    string(md.data),\n\t}\n}\n\nfunc (md *MetaData) e(format string, args ...interface{}) error {\n\tf := \"toml: \"\n\tif len(md.context) > 0 {\n\t\tf = fmt.Sprintf(\"toml: (last key %q): \", md.context)\n\t\tp := md.keyInfo[md.context.String()].pos\n\t\tif p.Line > 0 {\n\t\t\tf = fmt.Sprintf(\"toml: line %d (last key %q): \", p.Line, md.context)\n\t\t}\n\t}\n\treturn fmt.Errorf(f+format, args...)\n}\n\n// rvalue returns a reflect.Value of `v`. All pointers are resolved.\nfunc rvalue(v interface{}) reflect.Value {\n\treturn indirect(reflect.ValueOf(v))\n}\n\n// indirect returns the value pointed to by a pointer.\n//\n// Pointers are followed until the value is not a pointer. New values are\n// allocated for each nil pointer.\n//\n// An exception to this rule is if the value satisfies an interface of interest\n// to us (like encoding.TextUnmarshaler).\nfunc indirect(v reflect.Value) reflect.Value {\n\tif v.Kind() != reflect.Ptr {\n\t\tif v.CanSet() {\n\t\t\tpv := v.Addr()\n\t\t\tpvi := pv.Interface()\n\t\t\tif _, ok := pvi.(encoding.TextUnmarshaler); ok {\n\t\t\t\treturn pv\n\t\t\t}\n\t\t\tif _, ok := pvi.(Unmarshaler); ok {\n\t\t\t\treturn pv\n\t\t\t}\n\t\t}\n\t\treturn v\n\t}\n\tif v.IsNil() {\n\t\tv.Set(reflect.New(v.Type().Elem()))\n\t}\n\treturn indirect(reflect.Indirect(v))\n}\n\nfunc isUnifiable(rv reflect.Value) bool {\n\tif rv.CanSet() {\n\t\treturn true\n\t}\n\trvi := rv.Interface()\n\tif _, ok := rvi.(encoding.TextUnmarshaler); ok {\n\t\treturn true\n\t}\n\tif _, ok := rvi.(Unmarshaler); ok {\n\t\treturn true\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/BurntSushi/toml/decode_go116.go",
    "content": "//go:build go1.16\n// +build go1.16\n\npackage toml\n\nimport (\n\t\"io/fs\"\n)\n\n// DecodeFS is just like Decode, except it will automatically read the contents\n// of the file at `path` from a fs.FS instance.\nfunc DecodeFS(fsys fs.FS, path string, v interface{}) (MetaData, error) {\n\tfp, err := fsys.Open(path)\n\tif err != nil {\n\t\treturn MetaData{}, err\n\t}\n\tdefer fp.Close()\n\treturn NewDecoder(fp).Decode(v)\n}\n"
  },
  {
    "path": "vendor/github.com/BurntSushi/toml/deprecated.go",
    "content": "package toml\n\nimport (\n\t\"encoding\"\n\t\"io\"\n)\n\n// Deprecated: use encoding.TextMarshaler\ntype TextMarshaler encoding.TextMarshaler\n\n// Deprecated: use encoding.TextUnmarshaler\ntype TextUnmarshaler encoding.TextUnmarshaler\n\n// Deprecated: use MetaData.PrimitiveDecode.\nfunc PrimitiveDecode(primValue Primitive, v interface{}) error {\n\tmd := MetaData{decoded: make(map[string]struct{})}\n\treturn md.unify(primValue.undecoded, rvalue(v))\n}\n\n// Deprecated: use NewDecoder(reader).Decode(&value).\nfunc DecodeReader(r io.Reader, v interface{}) (MetaData, error) { return NewDecoder(r).Decode(v) }\n"
  },
  {
    "path": "vendor/github.com/BurntSushi/toml/doc.go",
    "content": "/*\nPackage toml implements decoding and encoding of TOML files.\n\nThis package supports TOML v1.0.0, as listed on https://toml.io\n\nThere is also support for delaying decoding with the Primitive type, and\nquerying the set of keys in a TOML document with the MetaData type.\n\nThe github.com/BurntSushi/toml/cmd/tomlv package implements a TOML validator,\nand can be used to verify if TOML document is valid. It can also be used to\nprint the type of each key.\n*/\npackage toml\n"
  },
  {
    "path": "vendor/github.com/BurntSushi/toml/encode.go",
    "content": "package toml\n\nimport (\n\t\"bufio\"\n\t\"encoding\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/BurntSushi/toml/internal\"\n)\n\ntype tomlEncodeError struct{ error }\n\nvar (\n\terrArrayNilElement = errors.New(\"toml: cannot encode array with nil element\")\n\terrNonString       = errors.New(\"toml: cannot encode a map with non-string key type\")\n\terrNoKey           = errors.New(\"toml: top-level values must be Go maps or structs\")\n\terrAnything        = errors.New(\"\") // used in testing\n)\n\nvar dblQuotedReplacer = strings.NewReplacer(\n\t\"\\\"\", \"\\\\\\\"\",\n\t\"\\\\\", \"\\\\\\\\\",\n\t\"\\x00\", `\\u0000`,\n\t\"\\x01\", `\\u0001`,\n\t\"\\x02\", `\\u0002`,\n\t\"\\x03\", `\\u0003`,\n\t\"\\x04\", `\\u0004`,\n\t\"\\x05\", `\\u0005`,\n\t\"\\x06\", `\\u0006`,\n\t\"\\x07\", `\\u0007`,\n\t\"\\b\", `\\b`,\n\t\"\\t\", `\\t`,\n\t\"\\n\", `\\n`,\n\t\"\\x0b\", `\\u000b`,\n\t\"\\f\", `\\f`,\n\t\"\\r\", `\\r`,\n\t\"\\x0e\", `\\u000e`,\n\t\"\\x0f\", `\\u000f`,\n\t\"\\x10\", `\\u0010`,\n\t\"\\x11\", `\\u0011`,\n\t\"\\x12\", `\\u0012`,\n\t\"\\x13\", `\\u0013`,\n\t\"\\x14\", `\\u0014`,\n\t\"\\x15\", `\\u0015`,\n\t\"\\x16\", `\\u0016`,\n\t\"\\x17\", `\\u0017`,\n\t\"\\x18\", `\\u0018`,\n\t\"\\x19\", `\\u0019`,\n\t\"\\x1a\", `\\u001a`,\n\t\"\\x1b\", `\\u001b`,\n\t\"\\x1c\", `\\u001c`,\n\t\"\\x1d\", `\\u001d`,\n\t\"\\x1e\", `\\u001e`,\n\t\"\\x1f\", `\\u001f`,\n\t\"\\x7f\", `\\u007f`,\n)\n\nvar (\n\tmarshalToml = reflect.TypeOf((*Marshaler)(nil)).Elem()\n\tmarshalText = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()\n\ttimeType    = reflect.TypeOf((*time.Time)(nil)).Elem()\n)\n\n// Marshaler is the interface implemented by types that can marshal themselves\n// into valid TOML.\ntype Marshaler interface {\n\tMarshalTOML() ([]byte, error)\n}\n\n// Encoder encodes a Go to a TOML document.\n//\n// The mapping between Go values and TOML values should be precisely the same as\n// for the Decode* functions.\n//\n// time.Time is encoded as a RFC 3339 string, and time.Duration as its string\n// representation.\n//\n// The toml.Marshaler and encoder.TextMarshaler interfaces are supported to\n// encoding the value as custom TOML.\n//\n// If you want to write arbitrary binary data then you will need to use\n// something like base64 since TOML does not have any binary types.\n//\n// When encoding TOML hashes (Go maps or structs), keys without any sub-hashes\n// are encoded first.\n//\n// Go maps will be sorted alphabetically by key for deterministic output.\n//\n// The toml struct tag can be used to provide the key name; if omitted the\n// struct field name will be used. If the \"omitempty\" option is present the\n// following value will be skipped:\n//\n//   - arrays, slices, maps, and string with len of 0\n//   - struct with all zero values\n//   - bool false\n//\n// If omitzero is given all int and float types with a value of 0 will be\n// skipped.\n//\n// Encoding Go values without a corresponding TOML representation will return an\n// error. Examples of this includes maps with non-string keys, slices with nil\n// elements, embedded non-struct types, and nested slices containing maps or\n// structs. (e.g. [][]map[string]string is not allowed but []map[string]string\n// is okay, as is []map[string][]string).\n//\n// NOTE: only exported keys are encoded due to the use of reflection. Unexported\n// keys are silently discarded.\ntype Encoder struct {\n\t// String to use for a single indentation level; default is two spaces.\n\tIndent string\n\n\tw          *bufio.Writer\n\thasWritten bool // written any output to w yet?\n}\n\n// NewEncoder create a new Encoder.\nfunc NewEncoder(w io.Writer) *Encoder {\n\treturn &Encoder{\n\t\tw:      bufio.NewWriter(w),\n\t\tIndent: \"  \",\n\t}\n}\n\n// Encode writes a TOML representation of the Go value to the Encoder's writer.\n//\n// An error is returned if the value given cannot be encoded to a valid TOML\n// document.\nfunc (enc *Encoder) Encode(v interface{}) error {\n\trv := eindirect(reflect.ValueOf(v))\n\tif err := enc.safeEncode(Key([]string{}), rv); err != nil {\n\t\treturn err\n\t}\n\treturn enc.w.Flush()\n}\n\nfunc (enc *Encoder) safeEncode(key Key, rv reflect.Value) (err error) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tif terr, ok := r.(tomlEncodeError); ok {\n\t\t\t\terr = terr.error\n\t\t\t\treturn\n\t\t\t}\n\t\t\tpanic(r)\n\t\t}\n\t}()\n\tenc.encode(key, rv)\n\treturn nil\n}\n\nfunc (enc *Encoder) encode(key Key, rv reflect.Value) {\n\t// If we can marshal the type to text, then we use that. This prevents the\n\t// encoder for handling these types as generic structs (or whatever the\n\t// underlying type of a TextMarshaler is).\n\tswitch {\n\tcase isMarshaler(rv):\n\t\tenc.writeKeyValue(key, rv, false)\n\t\treturn\n\tcase rv.Type() == primitiveType: // TODO: #76 would make this superfluous after implemented.\n\t\tenc.encode(key, reflect.ValueOf(rv.Interface().(Primitive).undecoded))\n\t\treturn\n\t}\n\n\tk := rv.Kind()\n\tswitch k {\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,\n\t\treflect.Int64,\n\t\treflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,\n\t\treflect.Uint64,\n\t\treflect.Float32, reflect.Float64, reflect.String, reflect.Bool:\n\t\tenc.writeKeyValue(key, rv, false)\n\tcase reflect.Array, reflect.Slice:\n\t\tif typeEqual(tomlArrayHash, tomlTypeOfGo(rv)) {\n\t\t\tenc.eArrayOfTables(key, rv)\n\t\t} else {\n\t\t\tenc.writeKeyValue(key, rv, false)\n\t\t}\n\tcase reflect.Interface:\n\t\tif rv.IsNil() {\n\t\t\treturn\n\t\t}\n\t\tenc.encode(key, rv.Elem())\n\tcase reflect.Map:\n\t\tif rv.IsNil() {\n\t\t\treturn\n\t\t}\n\t\tenc.eTable(key, rv)\n\tcase reflect.Ptr:\n\t\tif rv.IsNil() {\n\t\t\treturn\n\t\t}\n\t\tenc.encode(key, rv.Elem())\n\tcase reflect.Struct:\n\t\tenc.eTable(key, rv)\n\tdefault:\n\t\tencPanic(fmt.Errorf(\"unsupported type for key '%s': %s\", key, k))\n\t}\n}\n\n// eElement encodes any value that can be an array element.\nfunc (enc *Encoder) eElement(rv reflect.Value) {\n\tswitch v := rv.Interface().(type) {\n\tcase time.Time: // Using TextMarshaler adds extra quotes, which we don't want.\n\t\tformat := time.RFC3339Nano\n\t\tswitch v.Location() {\n\t\tcase internal.LocalDatetime:\n\t\t\tformat = \"2006-01-02T15:04:05.999999999\"\n\t\tcase internal.LocalDate:\n\t\t\tformat = \"2006-01-02\"\n\t\tcase internal.LocalTime:\n\t\t\tformat = \"15:04:05.999999999\"\n\t\t}\n\t\tswitch v.Location() {\n\t\tdefault:\n\t\t\tenc.wf(v.Format(format))\n\t\tcase internal.LocalDatetime, internal.LocalDate, internal.LocalTime:\n\t\t\tenc.wf(v.In(time.UTC).Format(format))\n\t\t}\n\t\treturn\n\tcase Marshaler:\n\t\ts, err := v.MarshalTOML()\n\t\tif err != nil {\n\t\t\tencPanic(err)\n\t\t}\n\t\tif s == nil {\n\t\t\tencPanic(errors.New(\"MarshalTOML returned nil and no error\"))\n\t\t}\n\t\tenc.w.Write(s)\n\t\treturn\n\tcase encoding.TextMarshaler:\n\t\ts, err := v.MarshalText()\n\t\tif err != nil {\n\t\t\tencPanic(err)\n\t\t}\n\t\tif s == nil {\n\t\t\tencPanic(errors.New(\"MarshalText returned nil and no error\"))\n\t\t}\n\t\tenc.writeQuoted(string(s))\n\t\treturn\n\tcase time.Duration:\n\t\tenc.writeQuoted(v.String())\n\t\treturn\n\tcase json.Number:\n\t\tn, _ := rv.Interface().(json.Number)\n\n\t\tif n == \"\" { /// Useful zero value.\n\t\t\tenc.w.WriteByte('0')\n\t\t\treturn\n\t\t} else if v, err := n.Int64(); err == nil {\n\t\t\tenc.eElement(reflect.ValueOf(v))\n\t\t\treturn\n\t\t} else if v, err := n.Float64(); err == nil {\n\t\t\tenc.eElement(reflect.ValueOf(v))\n\t\t\treturn\n\t\t}\n\t\tencPanic(errors.New(fmt.Sprintf(\"Unable to convert \\\"%s\\\" to neither int64 nor float64\", n)))\n\t}\n\n\tswitch rv.Kind() {\n\tcase reflect.Ptr:\n\t\tenc.eElement(rv.Elem())\n\t\treturn\n\tcase reflect.String:\n\t\tenc.writeQuoted(rv.String())\n\tcase reflect.Bool:\n\t\tenc.wf(strconv.FormatBool(rv.Bool()))\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\tenc.wf(strconv.FormatInt(rv.Int(), 10))\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:\n\t\tenc.wf(strconv.FormatUint(rv.Uint(), 10))\n\tcase reflect.Float32:\n\t\tf := rv.Float()\n\t\tif math.IsNaN(f) {\n\t\t\tenc.wf(\"nan\")\n\t\t} else if math.IsInf(f, 0) {\n\t\t\tenc.wf(\"%cinf\", map[bool]byte{true: '-', false: '+'}[math.Signbit(f)])\n\t\t} else {\n\t\t\tenc.wf(floatAddDecimal(strconv.FormatFloat(f, 'f', -1, 32)))\n\t\t}\n\tcase reflect.Float64:\n\t\tf := rv.Float()\n\t\tif math.IsNaN(f) {\n\t\t\tenc.wf(\"nan\")\n\t\t} else if math.IsInf(f, 0) {\n\t\t\tenc.wf(\"%cinf\", map[bool]byte{true: '-', false: '+'}[math.Signbit(f)])\n\t\t} else {\n\t\t\tenc.wf(floatAddDecimal(strconv.FormatFloat(f, 'f', -1, 64)))\n\t\t}\n\tcase reflect.Array, reflect.Slice:\n\t\tenc.eArrayOrSliceElement(rv)\n\tcase reflect.Struct:\n\t\tenc.eStruct(nil, rv, true)\n\tcase reflect.Map:\n\t\tenc.eMap(nil, rv, true)\n\tcase reflect.Interface:\n\t\tenc.eElement(rv.Elem())\n\tdefault:\n\t\tencPanic(fmt.Errorf(\"unexpected type: %T\", rv.Interface()))\n\t}\n}\n\n// By the TOML spec, all floats must have a decimal with at least one number on\n// either side.\nfunc floatAddDecimal(fstr string) string {\n\tif !strings.Contains(fstr, \".\") {\n\t\treturn fstr + \".0\"\n\t}\n\treturn fstr\n}\n\nfunc (enc *Encoder) writeQuoted(s string) {\n\tenc.wf(\"\\\"%s\\\"\", dblQuotedReplacer.Replace(s))\n}\n\nfunc (enc *Encoder) eArrayOrSliceElement(rv reflect.Value) {\n\tlength := rv.Len()\n\tenc.wf(\"[\")\n\tfor i := 0; i < length; i++ {\n\t\telem := eindirect(rv.Index(i))\n\t\tenc.eElement(elem)\n\t\tif i != length-1 {\n\t\t\tenc.wf(\", \")\n\t\t}\n\t}\n\tenc.wf(\"]\")\n}\n\nfunc (enc *Encoder) eArrayOfTables(key Key, rv reflect.Value) {\n\tif len(key) == 0 {\n\t\tencPanic(errNoKey)\n\t}\n\tfor i := 0; i < rv.Len(); i++ {\n\t\ttrv := eindirect(rv.Index(i))\n\t\tif isNil(trv) {\n\t\t\tcontinue\n\t\t}\n\t\tenc.newline()\n\t\tenc.wf(\"%s[[%s]]\", enc.indentStr(key), key)\n\t\tenc.newline()\n\t\tenc.eMapOrStruct(key, trv, false)\n\t}\n}\n\nfunc (enc *Encoder) eTable(key Key, rv reflect.Value) {\n\tif len(key) == 1 {\n\t\t// Output an extra newline between top-level tables.\n\t\t// (The newline isn't written if nothing else has been written though.)\n\t\tenc.newline()\n\t}\n\tif len(key) > 0 {\n\t\tenc.wf(\"%s[%s]\", enc.indentStr(key), key)\n\t\tenc.newline()\n\t}\n\tenc.eMapOrStruct(key, rv, false)\n}\n\nfunc (enc *Encoder) eMapOrStruct(key Key, rv reflect.Value, inline bool) {\n\tswitch rv.Kind() {\n\tcase reflect.Map:\n\t\tenc.eMap(key, rv, inline)\n\tcase reflect.Struct:\n\t\tenc.eStruct(key, rv, inline)\n\tdefault:\n\t\t// Should never happen?\n\t\tpanic(\"eTable: unhandled reflect.Value Kind: \" + rv.Kind().String())\n\t}\n}\n\nfunc (enc *Encoder) eMap(key Key, rv reflect.Value, inline bool) {\n\trt := rv.Type()\n\tif rt.Key().Kind() != reflect.String {\n\t\tencPanic(errNonString)\n\t}\n\n\t// Sort keys so that we have deterministic output. And write keys directly\n\t// underneath this key first, before writing sub-structs or sub-maps.\n\tvar mapKeysDirect, mapKeysSub []string\n\tfor _, mapKey := range rv.MapKeys() {\n\t\tk := mapKey.String()\n\t\tif typeIsTable(tomlTypeOfGo(eindirect(rv.MapIndex(mapKey)))) {\n\t\t\tmapKeysSub = append(mapKeysSub, k)\n\t\t} else {\n\t\t\tmapKeysDirect = append(mapKeysDirect, k)\n\t\t}\n\t}\n\n\tvar writeMapKeys = func(mapKeys []string, trailC bool) {\n\t\tsort.Strings(mapKeys)\n\t\tfor i, mapKey := range mapKeys {\n\t\t\tval := eindirect(rv.MapIndex(reflect.ValueOf(mapKey)))\n\t\t\tif isNil(val) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif inline {\n\t\t\t\tenc.writeKeyValue(Key{mapKey}, val, true)\n\t\t\t\tif trailC || i != len(mapKeys)-1 {\n\t\t\t\t\tenc.wf(\", \")\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tenc.encode(key.add(mapKey), val)\n\t\t\t}\n\t\t}\n\t}\n\n\tif inline {\n\t\tenc.wf(\"{\")\n\t}\n\twriteMapKeys(mapKeysDirect, len(mapKeysSub) > 0)\n\twriteMapKeys(mapKeysSub, false)\n\tif inline {\n\t\tenc.wf(\"}\")\n\t}\n}\n\nconst is32Bit = (32 << (^uint(0) >> 63)) == 32\n\nfunc pointerTo(t reflect.Type) reflect.Type {\n\tif t.Kind() == reflect.Ptr {\n\t\treturn pointerTo(t.Elem())\n\t}\n\treturn t\n}\n\nfunc (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {\n\t// Write keys for fields directly under this key first, because if we write\n\t// a field that creates a new table then all keys under it will be in that\n\t// table (not the one we're writing here).\n\t//\n\t// Fields is a [][]int: for fieldsDirect this always has one entry (the\n\t// struct index). For fieldsSub it contains two entries: the parent field\n\t// index from tv, and the field indexes for the fields of the sub.\n\tvar (\n\t\trt                      = rv.Type()\n\t\tfieldsDirect, fieldsSub [][]int\n\t\taddFields               func(rt reflect.Type, rv reflect.Value, start []int)\n\t)\n\taddFields = func(rt reflect.Type, rv reflect.Value, start []int) {\n\t\tfor i := 0; i < rt.NumField(); i++ {\n\t\t\tf := rt.Field(i)\n\t\t\tisEmbed := f.Anonymous && pointerTo(f.Type).Kind() == reflect.Struct\n\t\t\tif f.PkgPath != \"\" && !isEmbed { /// Skip unexported fields.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\topts := getOptions(f.Tag)\n\t\t\tif opts.skip {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tfrv := eindirect(rv.Field(i))\n\n\t\t\t// Treat anonymous struct fields with tag names as though they are\n\t\t\t// not anonymous, like encoding/json does.\n\t\t\t//\n\t\t\t// Non-struct anonymous fields use the normal encoding logic.\n\t\t\tif isEmbed {\n\t\t\t\tif getOptions(f.Tag).name == \"\" && frv.Kind() == reflect.Struct {\n\t\t\t\t\taddFields(frv.Type(), frv, append(start, f.Index...))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif typeIsTable(tomlTypeOfGo(frv)) {\n\t\t\t\tfieldsSub = append(fieldsSub, append(start, f.Index...))\n\t\t\t} else {\n\t\t\t\t// Copy so it works correct on 32bit archs; not clear why this\n\t\t\t\t// is needed. See #314, and https://www.reddit.com/r/golang/comments/pnx8v4\n\t\t\t\t// This also works fine on 64bit, but 32bit archs are somewhat\n\t\t\t\t// rare and this is a wee bit faster.\n\t\t\t\tif is32Bit {\n\t\t\t\t\tcopyStart := make([]int, len(start))\n\t\t\t\t\tcopy(copyStart, start)\n\t\t\t\t\tfieldsDirect = append(fieldsDirect, append(copyStart, f.Index...))\n\t\t\t\t} else {\n\t\t\t\t\tfieldsDirect = append(fieldsDirect, append(start, f.Index...))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\taddFields(rt, rv, nil)\n\n\twriteFields := func(fields [][]int) {\n\t\tfor _, fieldIndex := range fields {\n\t\t\tfieldType := rt.FieldByIndex(fieldIndex)\n\t\t\tfieldVal := eindirect(rv.FieldByIndex(fieldIndex))\n\n\t\t\tif isNil(fieldVal) { /// Don't write anything for nil fields.\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\topts := getOptions(fieldType.Tag)\n\t\t\tif opts.skip {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tkeyName := fieldType.Name\n\t\t\tif opts.name != \"\" {\n\t\t\t\tkeyName = opts.name\n\t\t\t}\n\t\t\tif opts.omitempty && isEmpty(fieldVal) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif opts.omitzero && isZero(fieldVal) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif inline {\n\t\t\t\tenc.writeKeyValue(Key{keyName}, fieldVal, true)\n\t\t\t\tif fieldIndex[0] != len(fields)-1 {\n\t\t\t\t\tenc.wf(\", \")\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tenc.encode(key.add(keyName), fieldVal)\n\t\t\t}\n\t\t}\n\t}\n\n\tif inline {\n\t\tenc.wf(\"{\")\n\t}\n\twriteFields(fieldsDirect)\n\twriteFields(fieldsSub)\n\tif inline {\n\t\tenc.wf(\"}\")\n\t}\n}\n\n// tomlTypeOfGo returns the TOML type name of the Go value's type.\n//\n// It is used to determine whether the types of array elements are mixed (which\n// is forbidden). If the Go value is nil, then it is illegal for it to be an\n// array element, and valueIsNil is returned as true.\n//\n// The type may be `nil`, which means no concrete TOML type could be found.\nfunc tomlTypeOfGo(rv reflect.Value) tomlType {\n\tif isNil(rv) || !rv.IsValid() {\n\t\treturn nil\n\t}\n\n\tif rv.Kind() == reflect.Struct {\n\t\tif rv.Type() == timeType {\n\t\t\treturn tomlDatetime\n\t\t}\n\t\tif isMarshaler(rv) {\n\t\t\treturn tomlString\n\t\t}\n\t\treturn tomlHash\n\t}\n\n\tif isMarshaler(rv) {\n\t\treturn tomlString\n\t}\n\n\tswitch rv.Kind() {\n\tcase reflect.Bool:\n\t\treturn tomlBool\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,\n\t\treflect.Int64,\n\t\treflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,\n\t\treflect.Uint64:\n\t\treturn tomlInteger\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn tomlFloat\n\tcase reflect.Array, reflect.Slice:\n\t\tif isTableArray(rv) {\n\t\t\treturn tomlArrayHash\n\t\t}\n\t\treturn tomlArray\n\tcase reflect.Ptr, reflect.Interface:\n\t\treturn tomlTypeOfGo(rv.Elem())\n\tcase reflect.String:\n\t\treturn tomlString\n\tcase reflect.Map:\n\t\treturn tomlHash\n\tdefault:\n\t\tencPanic(errors.New(\"unsupported type: \" + rv.Kind().String()))\n\t\tpanic(\"unreachable\")\n\t}\n}\n\nfunc isMarshaler(rv reflect.Value) bool {\n\treturn rv.Type().Implements(marshalText) || rv.Type().Implements(marshalToml)\n}\n\n// isTableArray reports if all entries in the array or slice are a table.\nfunc isTableArray(arr reflect.Value) bool {\n\tif isNil(arr) || !arr.IsValid() || arr.Len() == 0 {\n\t\treturn false\n\t}\n\n\tret := true\n\tfor i := 0; i < arr.Len(); i++ {\n\t\ttt := tomlTypeOfGo(eindirect(arr.Index(i)))\n\t\t// Don't allow nil.\n\t\tif tt == nil {\n\t\t\tencPanic(errArrayNilElement)\n\t\t}\n\n\t\tif ret && !typeEqual(tomlHash, tt) {\n\t\t\tret = false\n\t\t}\n\t}\n\treturn ret\n}\n\ntype tagOptions struct {\n\tskip      bool // \"-\"\n\tname      string\n\tomitempty bool\n\tomitzero  bool\n}\n\nfunc getOptions(tag reflect.StructTag) tagOptions {\n\tt := tag.Get(\"toml\")\n\tif t == \"-\" {\n\t\treturn tagOptions{skip: true}\n\t}\n\tvar opts tagOptions\n\tparts := strings.Split(t, \",\")\n\topts.name = parts[0]\n\tfor _, s := range parts[1:] {\n\t\tswitch s {\n\t\tcase \"omitempty\":\n\t\t\topts.omitempty = true\n\t\tcase \"omitzero\":\n\t\t\topts.omitzero = true\n\t\t}\n\t}\n\treturn opts\n}\n\nfunc isZero(rv reflect.Value) bool {\n\tswitch rv.Kind() {\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\treturn rv.Int() == 0\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:\n\t\treturn rv.Uint() == 0\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn rv.Float() == 0.0\n\t}\n\treturn false\n}\n\nfunc isEmpty(rv reflect.Value) bool {\n\tswitch rv.Kind() {\n\tcase reflect.Array, reflect.Slice, reflect.Map, reflect.String:\n\t\treturn rv.Len() == 0\n\tcase reflect.Struct:\n\t\treturn reflect.Zero(rv.Type()).Interface() == rv.Interface()\n\tcase reflect.Bool:\n\t\treturn !rv.Bool()\n\t}\n\treturn false\n}\n\nfunc (enc *Encoder) newline() {\n\tif enc.hasWritten {\n\t\tenc.wf(\"\\n\")\n\t}\n}\n\n// Write a key/value pair:\n//\n//   key = <any value>\n//\n// This is also used for \"k = v\" in inline tables; so something like this will\n// be written in three calls:\n//\n//     ┌────────────────────┐\n//     │      ┌───┐  ┌─────┐│\n//     v      v   v  v     vv\n//     key = {k = v, k2 = v2}\n//\nfunc (enc *Encoder) writeKeyValue(key Key, val reflect.Value, inline bool) {\n\tif len(key) == 0 {\n\t\tencPanic(errNoKey)\n\t}\n\tenc.wf(\"%s%s = \", enc.indentStr(key), key.maybeQuoted(len(key)-1))\n\tenc.eElement(val)\n\tif !inline {\n\t\tenc.newline()\n\t}\n}\n\nfunc (enc *Encoder) wf(format string, v ...interface{}) {\n\t_, err := fmt.Fprintf(enc.w, format, v...)\n\tif err != nil {\n\t\tencPanic(err)\n\t}\n\tenc.hasWritten = true\n}\n\nfunc (enc *Encoder) indentStr(key Key) string {\n\treturn strings.Repeat(enc.Indent, len(key)-1)\n}\n\nfunc encPanic(err error) {\n\tpanic(tomlEncodeError{err})\n}\n\n// Resolve any level of pointers to the actual value (e.g. **string → string).\nfunc eindirect(v reflect.Value) reflect.Value {\n\tif v.Kind() != reflect.Ptr && v.Kind() != reflect.Interface {\n\t\tif isMarshaler(v) {\n\t\t\treturn v\n\t\t}\n\t\tif v.CanAddr() { /// Special case for marshalers; see #358.\n\t\t\tif pv := v.Addr(); isMarshaler(pv) {\n\t\t\t\treturn pv\n\t\t\t}\n\t\t}\n\t\treturn v\n\t}\n\n\tif v.IsNil() {\n\t\treturn v\n\t}\n\n\treturn eindirect(v.Elem())\n}\n\nfunc isNil(rv reflect.Value) bool {\n\tswitch rv.Kind() {\n\tcase reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:\n\t\treturn rv.IsNil()\n\tdefault:\n\t\treturn false\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/BurntSushi/toml/error.go",
    "content": "package toml\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\n// ParseError is returned when there is an error parsing the TOML syntax.\n//\n// For example invalid syntax, duplicate keys, etc.\n//\n// In addition to the error message itself, you can also print detailed location\n// information with context by using ErrorWithPosition():\n//\n//     toml: error: Key 'fruit' was already created and cannot be used as an array.\n//\n//     At line 4, column 2-7:\n//\n//           2 | fruit = []\n//           3 |\n//           4 | [[fruit]] # Not allowed\n//                 ^^^^^\n//\n// Furthermore, the ErrorWithUsage() can be used to print the above with some\n// more detailed usage guidance:\n//\n//    toml: error: newlines not allowed within inline tables\n//\n//    At line 1, column 18:\n//\n//          1 | x = [{ key = 42 #\n//                               ^\n//\n//    Error help:\n//\n//      Inline tables must always be on a single line:\n//\n//          table = {key = 42, second = 43}\n//\n//      It is invalid to split them over multiple lines like so:\n//\n//          # INVALID\n//          table = {\n//              key    = 42,\n//              second = 43\n//          }\n//\n//      Use regular for this:\n//\n//          [table]\n//          key    = 42\n//          second = 43\ntype ParseError struct {\n\tMessage  string   // Short technical message.\n\tUsage    string   // Longer message with usage guidance; may be blank.\n\tPosition Position // Position of the error\n\tLastKey  string   // Last parsed key, may be blank.\n\tLine     int      // Line the error occurred. Deprecated: use Position.\n\n\terr   error\n\tinput string\n}\n\n// Position of an error.\ntype Position struct {\n\tLine  int // Line number, starting at 1.\n\tStart int // Start of error, as byte offset starting at 0.\n\tLen   int // Lenght in bytes.\n}\n\nfunc (pe ParseError) Error() string {\n\tmsg := pe.Message\n\tif msg == \"\" { // Error from errorf()\n\t\tmsg = pe.err.Error()\n\t}\n\n\tif pe.LastKey == \"\" {\n\t\treturn fmt.Sprintf(\"toml: line %d: %s\", pe.Position.Line, msg)\n\t}\n\treturn fmt.Sprintf(\"toml: line %d (last key %q): %s\",\n\t\tpe.Position.Line, pe.LastKey, msg)\n}\n\n// ErrorWithUsage() returns the error with detailed location context.\n//\n// See the documentation on ParseError.\nfunc (pe ParseError) ErrorWithPosition() string {\n\tif pe.input == \"\" { // Should never happen, but just in case.\n\t\treturn pe.Error()\n\t}\n\n\tvar (\n\t\tlines = strings.Split(pe.input, \"\\n\")\n\t\tcol   = pe.column(lines)\n\t\tb     = new(strings.Builder)\n\t)\n\n\tmsg := pe.Message\n\tif msg == \"\" {\n\t\tmsg = pe.err.Error()\n\t}\n\n\t// TODO: don't show control characters as literals? This may not show up\n\t// well everywhere.\n\n\tif pe.Position.Len == 1 {\n\t\tfmt.Fprintf(b, \"toml: error: %s\\n\\nAt line %d, column %d:\\n\\n\",\n\t\t\tmsg, pe.Position.Line, col+1)\n\t} else {\n\t\tfmt.Fprintf(b, \"toml: error: %s\\n\\nAt line %d, column %d-%d:\\n\\n\",\n\t\t\tmsg, pe.Position.Line, col, col+pe.Position.Len)\n\t}\n\tif pe.Position.Line > 2 {\n\t\tfmt.Fprintf(b, \"% 7d | %s\\n\", pe.Position.Line-2, lines[pe.Position.Line-3])\n\t}\n\tif pe.Position.Line > 1 {\n\t\tfmt.Fprintf(b, \"% 7d | %s\\n\", pe.Position.Line-1, lines[pe.Position.Line-2])\n\t}\n\tfmt.Fprintf(b, \"% 7d | %s\\n\", pe.Position.Line, lines[pe.Position.Line-1])\n\tfmt.Fprintf(b, \"% 10s%s%s\\n\", \"\", strings.Repeat(\" \", col), strings.Repeat(\"^\", pe.Position.Len))\n\treturn b.String()\n}\n\n// ErrorWithUsage() returns the error with detailed location context and usage\n// guidance.\n//\n// See the documentation on ParseError.\nfunc (pe ParseError) ErrorWithUsage() string {\n\tm := pe.ErrorWithPosition()\n\tif u, ok := pe.err.(interface{ Usage() string }); ok && u.Usage() != \"\" {\n\t\tlines := strings.Split(strings.TrimSpace(u.Usage()), \"\\n\")\n\t\tfor i := range lines {\n\t\t\tif lines[i] != \"\" {\n\t\t\t\tlines[i] = \"    \" + lines[i]\n\t\t\t}\n\t\t}\n\t\treturn m + \"Error help:\\n\\n\" + strings.Join(lines, \"\\n\") + \"\\n\"\n\t}\n\treturn m\n}\n\nfunc (pe ParseError) column(lines []string) int {\n\tvar pos, col int\n\tfor i := range lines {\n\t\tll := len(lines[i]) + 1 // +1 for the removed newline\n\t\tif pos+ll >= pe.Position.Start {\n\t\t\tcol = pe.Position.Start - pos\n\t\t\tif col < 0 { // Should never happen, but just in case.\n\t\t\t\tcol = 0\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tpos += ll\n\t}\n\n\treturn col\n}\n\ntype (\n\terrLexControl       struct{ r rune }\n\terrLexEscape        struct{ r rune }\n\terrLexUTF8          struct{ b byte }\n\terrLexInvalidNum    struct{ v string }\n\terrLexInvalidDate   struct{ v string }\n\terrLexInlineTableNL struct{}\n\terrLexStringNL      struct{}\n\terrParseRange       struct {\n\t\ti    interface{} // int or float\n\t\tsize string      // \"int64\", \"uint16\", etc.\n\t}\n\terrParseDuration struct{ d string }\n)\n\nfunc (e errLexControl) Error() string {\n\treturn fmt.Sprintf(\"TOML files cannot contain control characters: '0x%02x'\", e.r)\n}\nfunc (e errLexControl) Usage() string { return \"\" }\n\nfunc (e errLexEscape) Error() string        { return fmt.Sprintf(`invalid escape in string '\\%c'`, e.r) }\nfunc (e errLexEscape) Usage() string        { return usageEscape }\nfunc (e errLexUTF8) Error() string          { return fmt.Sprintf(\"invalid UTF-8 byte: 0x%02x\", e.b) }\nfunc (e errLexUTF8) Usage() string          { return \"\" }\nfunc (e errLexInvalidNum) Error() string    { return fmt.Sprintf(\"invalid number: %q\", e.v) }\nfunc (e errLexInvalidNum) Usage() string    { return \"\" }\nfunc (e errLexInvalidDate) Error() string   { return fmt.Sprintf(\"invalid date: %q\", e.v) }\nfunc (e errLexInvalidDate) Usage() string   { return \"\" }\nfunc (e errLexInlineTableNL) Error() string { return \"newlines not allowed within inline tables\" }\nfunc (e errLexInlineTableNL) Usage() string { return usageInlineNewline }\nfunc (e errLexStringNL) Error() string      { return \"strings cannot contain newlines\" }\nfunc (e errLexStringNL) Usage() string      { return usageStringNewline }\nfunc (e errParseRange) Error() string       { return fmt.Sprintf(\"%v is out of range for %s\", e.i, e.size) }\nfunc (e errParseRange) Usage() string       { return usageIntOverflow }\nfunc (e errParseDuration) Error() string    { return fmt.Sprintf(\"invalid duration: %q\", e.d) }\nfunc (e errParseDuration) Usage() string    { return usageDuration }\n\nconst usageEscape = `\nA '\\' inside a \"-delimited string is interpreted as an escape character.\n\nThe following escape sequences are supported:\n\\b, \\t, \\n, \\f, \\r, \\\", \\\\, \\uXXXX, and \\UXXXXXXXX\n\nTo prevent a '\\' from being recognized as an escape character, use either:\n\n- a ' or '''-delimited string; escape characters aren't processed in them; or\n- write two backslashes to get a single backslash: '\\\\'.\n\nIf you're trying to add a Windows path (e.g. \"C:\\Users\\martin\") then using '/'\ninstead of '\\' will usually also work: \"C:/Users/martin\".\n`\n\nconst usageInlineNewline = `\nInline tables must always be on a single line:\n\n    table = {key = 42, second = 43}\n\nIt is invalid to split them over multiple lines like so:\n\n    # INVALID\n    table = {\n        key    = 42,\n        second = 43\n    }\n\nUse regular for this:\n\n    [table]\n    key    = 42\n    second = 43\n`\n\nconst usageStringNewline = `\nStrings must always be on a single line, and cannot span more than one line:\n\n    # INVALID\n    string = \"Hello,\n    world!\"\n\nInstead use \"\"\" or ''' to split strings over multiple lines:\n\n    string = \"\"\"Hello,\n    world!\"\"\"\n`\n\nconst usageIntOverflow = `\nThis number is too large; this may be an error in the TOML, but it can also be a\nbug in the program that uses too small of an integer.\n\nThe maximum and minimum values are:\n\n    size   │ lowest         │ highest\n    ───────┼────────────────┼──────────\n    int8   │ -128           │ 127\n    int16  │ -32,768        │ 32,767\n    int32  │ -2,147,483,648 │ 2,147,483,647\n    int64  │ -9.2 × 10¹⁷    │ 9.2 × 10¹⁷\n    uint8  │ 0              │ 255\n    uint16 │ 0              │ 65535\n    uint32 │ 0              │ 4294967295\n    uint64 │ 0              │ 1.8 × 10¹⁸\n\nint refers to int32 on 32-bit systems and int64 on 64-bit systems.\n`\n\nconst usageDuration = `\nA duration must be as \"number<unit>\", without any spaces. Valid units are:\n\n    ns         nanoseconds (billionth of a second)\n    us, µs     microseconds (millionth of a second)\n    ms         milliseconds (thousands of a second)\n    s          seconds\n    m          minutes\n    h          hours\n\nYou can combine multiple units; for example \"5m10s\" for 5 minutes and 10\nseconds.\n`\n"
  },
  {
    "path": "vendor/github.com/BurntSushi/toml/internal/tz.go",
    "content": "package internal\n\nimport \"time\"\n\n// Timezones used for local datetime, date, and time TOML types.\n//\n// The exact way times and dates without a timezone should be interpreted is not\n// well-defined in the TOML specification and left to the implementation. These\n// defaults to current local timezone offset of the computer, but this can be\n// changed by changing these variables before decoding.\n//\n// TODO:\n// Ideally we'd like to offer people the ability to configure the used timezone\n// by setting Decoder.Timezone and Encoder.Timezone; however, this is a bit\n// tricky: the reason we use three different variables for this is to support\n// round-tripping – without these specific TZ names we wouldn't know which\n// format to use.\n//\n// There isn't a good way to encode this right now though, and passing this sort\n// of information also ties in to various related issues such as string format\n// encoding, encoding of comments, etc.\n//\n// So, for the time being, just put this in internal until we can write a good\n// comprehensive API for doing all of this.\n//\n// The reason they're exported is because they're referred from in e.g.\n// internal/tag.\n//\n// Note that this behaviour is valid according to the TOML spec as the exact\n// behaviour is left up to implementations.\nvar (\n\tlocalOffset   = func() int { _, o := time.Now().Zone(); return o }()\n\tLocalDatetime = time.FixedZone(\"datetime-local\", localOffset)\n\tLocalDate     = time.FixedZone(\"date-local\", localOffset)\n\tLocalTime     = time.FixedZone(\"time-local\", localOffset)\n)\n"
  },
  {
    "path": "vendor/github.com/BurntSushi/toml/lex.go",
    "content": "package toml\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"runtime\"\n\t\"strings\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n)\n\ntype itemType int\n\nconst (\n\titemError itemType = iota\n\titemNIL            // used in the parser to indicate no type\n\titemEOF\n\titemText\n\titemString\n\titemRawString\n\titemMultilineString\n\titemRawMultilineString\n\titemBool\n\titemInteger\n\titemFloat\n\titemDatetime\n\titemArray // the start of an array\n\titemArrayEnd\n\titemTableStart\n\titemTableEnd\n\titemArrayTableStart\n\titemArrayTableEnd\n\titemKeyStart\n\titemKeyEnd\n\titemCommentStart\n\titemInlineTableStart\n\titemInlineTableEnd\n)\n\nconst eof = 0\n\ntype stateFn func(lx *lexer) stateFn\n\nfunc (p Position) String() string {\n\treturn fmt.Sprintf(\"at line %d; start %d; length %d\", p.Line, p.Start, p.Len)\n}\n\ntype lexer struct {\n\tinput string\n\tstart int\n\tpos   int\n\tline  int\n\tstate stateFn\n\titems chan item\n\n\t// Allow for backing up up to 4 runes. This is necessary because TOML\n\t// contains 3-rune tokens (\"\"\" and ''').\n\tprevWidths [4]int\n\tnprev      int  // how many of prevWidths are in use\n\tatEOF      bool // If we emit an eof, we can still back up, but it is not OK to call next again.\n\n\t// A stack of state functions used to maintain context.\n\t//\n\t// The idea is to reuse parts of the state machine in various places. For\n\t// example, values can appear at the top level or within arbitrarily nested\n\t// arrays. The last state on the stack is used after a value has been lexed.\n\t// Similarly for comments.\n\tstack []stateFn\n}\n\ntype item struct {\n\ttyp itemType\n\tval string\n\terr error\n\tpos Position\n}\n\nfunc (lx *lexer) nextItem() item {\n\tfor {\n\t\tselect {\n\t\tcase item := <-lx.items:\n\t\t\treturn item\n\t\tdefault:\n\t\t\tlx.state = lx.state(lx)\n\t\t\t//fmt.Printf(\"     STATE %-24s  current: %-10s\tstack: %s\\n\", lx.state, lx.current(), lx.stack)\n\t\t}\n\t}\n}\n\nfunc lex(input string) *lexer {\n\tlx := &lexer{\n\t\tinput: input,\n\t\tstate: lexTop,\n\t\titems: make(chan item, 10),\n\t\tstack: make([]stateFn, 0, 10),\n\t\tline:  1,\n\t}\n\treturn lx\n}\n\nfunc (lx *lexer) push(state stateFn) {\n\tlx.stack = append(lx.stack, state)\n}\n\nfunc (lx *lexer) pop() stateFn {\n\tif len(lx.stack) == 0 {\n\t\treturn lx.errorf(\"BUG in lexer: no states to pop\")\n\t}\n\tlast := lx.stack[len(lx.stack)-1]\n\tlx.stack = lx.stack[0 : len(lx.stack)-1]\n\treturn last\n}\n\nfunc (lx *lexer) current() string {\n\treturn lx.input[lx.start:lx.pos]\n}\n\nfunc (lx lexer) getPos() Position {\n\tp := Position{\n\t\tLine:  lx.line,\n\t\tStart: lx.start,\n\t\tLen:   lx.pos - lx.start,\n\t}\n\tif p.Len <= 0 {\n\t\tp.Len = 1\n\t}\n\treturn p\n}\n\nfunc (lx *lexer) emit(typ itemType) {\n\t// Needed for multiline strings ending with an incomplete UTF-8 sequence.\n\tif lx.start > lx.pos {\n\t\tlx.error(errLexUTF8{lx.input[lx.pos]})\n\t\treturn\n\t}\n\tlx.items <- item{typ: typ, pos: lx.getPos(), val: lx.current()}\n\tlx.start = lx.pos\n}\n\nfunc (lx *lexer) emitTrim(typ itemType) {\n\tlx.items <- item{typ: typ, pos: lx.getPos(), val: strings.TrimSpace(lx.current())}\n\tlx.start = lx.pos\n}\n\nfunc (lx *lexer) next() (r rune) {\n\tif lx.atEOF {\n\t\tpanic(\"BUG in lexer: next called after EOF\")\n\t}\n\tif lx.pos >= len(lx.input) {\n\t\tlx.atEOF = true\n\t\treturn eof\n\t}\n\n\tif lx.input[lx.pos] == '\\n' {\n\t\tlx.line++\n\t}\n\tlx.prevWidths[3] = lx.prevWidths[2]\n\tlx.prevWidths[2] = lx.prevWidths[1]\n\tlx.prevWidths[1] = lx.prevWidths[0]\n\tif lx.nprev < 4 {\n\t\tlx.nprev++\n\t}\n\n\tr, w := utf8.DecodeRuneInString(lx.input[lx.pos:])\n\tif r == utf8.RuneError {\n\t\tlx.error(errLexUTF8{lx.input[lx.pos]})\n\t\treturn utf8.RuneError\n\t}\n\n\t// Note: don't use peek() here, as this calls next().\n\tif isControl(r) || (r == '\\r' && (len(lx.input)-1 == lx.pos || lx.input[lx.pos+1] != '\\n')) {\n\t\tlx.errorControlChar(r)\n\t\treturn utf8.RuneError\n\t}\n\n\tlx.prevWidths[0] = w\n\tlx.pos += w\n\treturn r\n}\n\n// ignore skips over the pending input before this point.\nfunc (lx *lexer) ignore() {\n\tlx.start = lx.pos\n}\n\n// backup steps back one rune. Can be called 4 times between calls to next.\nfunc (lx *lexer) backup() {\n\tif lx.atEOF {\n\t\tlx.atEOF = false\n\t\treturn\n\t}\n\tif lx.nprev < 1 {\n\t\tpanic(\"BUG in lexer: backed up too far\")\n\t}\n\tw := lx.prevWidths[0]\n\tlx.prevWidths[0] = lx.prevWidths[1]\n\tlx.prevWidths[1] = lx.prevWidths[2]\n\tlx.prevWidths[2] = lx.prevWidths[3]\n\tlx.nprev--\n\n\tlx.pos -= w\n\tif lx.pos < len(lx.input) && lx.input[lx.pos] == '\\n' {\n\t\tlx.line--\n\t}\n}\n\n// accept consumes the next rune if it's equal to `valid`.\nfunc (lx *lexer) accept(valid rune) bool {\n\tif lx.next() == valid {\n\t\treturn true\n\t}\n\tlx.backup()\n\treturn false\n}\n\n// peek returns but does not consume the next rune in the input.\nfunc (lx *lexer) peek() rune {\n\tr := lx.next()\n\tlx.backup()\n\treturn r\n}\n\n// skip ignores all input that matches the given predicate.\nfunc (lx *lexer) skip(pred func(rune) bool) {\n\tfor {\n\t\tr := lx.next()\n\t\tif pred(r) {\n\t\t\tcontinue\n\t\t}\n\t\tlx.backup()\n\t\tlx.ignore()\n\t\treturn\n\t}\n}\n\n// error stops all lexing by emitting an error and returning `nil`.\n//\n// Note that any value that is a character is escaped if it's a special\n// character (newlines, tabs, etc.).\nfunc (lx *lexer) error(err error) stateFn {\n\tif lx.atEOF {\n\t\treturn lx.errorPrevLine(err)\n\t}\n\tlx.items <- item{typ: itemError, pos: lx.getPos(), err: err}\n\treturn nil\n}\n\n// errorfPrevline is like error(), but sets the position to the last column of\n// the previous line.\n//\n// This is so that unexpected EOF or NL errors don't show on a new blank line.\nfunc (lx *lexer) errorPrevLine(err error) stateFn {\n\tpos := lx.getPos()\n\tpos.Line--\n\tpos.Len = 1\n\tpos.Start = lx.pos - 1\n\tlx.items <- item{typ: itemError, pos: pos, err: err}\n\treturn nil\n}\n\n// errorPos is like error(), but allows explicitly setting the position.\nfunc (lx *lexer) errorPos(start, length int, err error) stateFn {\n\tpos := lx.getPos()\n\tpos.Start = start\n\tpos.Len = length\n\tlx.items <- item{typ: itemError, pos: pos, err: err}\n\treturn nil\n}\n\n// errorf is like error, and creates a new error.\nfunc (lx *lexer) errorf(format string, values ...interface{}) stateFn {\n\tif lx.atEOF {\n\t\tpos := lx.getPos()\n\t\tpos.Line--\n\t\tpos.Len = 1\n\t\tpos.Start = lx.pos - 1\n\t\tlx.items <- item{typ: itemError, pos: pos, err: fmt.Errorf(format, values...)}\n\t\treturn nil\n\t}\n\tlx.items <- item{typ: itemError, pos: lx.getPos(), err: fmt.Errorf(format, values...)}\n\treturn nil\n}\n\nfunc (lx *lexer) errorControlChar(cc rune) stateFn {\n\treturn lx.errorPos(lx.pos-1, 1, errLexControl{cc})\n}\n\n// lexTop consumes elements at the top level of TOML data.\nfunc lexTop(lx *lexer) stateFn {\n\tr := lx.next()\n\tif isWhitespace(r) || isNL(r) {\n\t\treturn lexSkip(lx, lexTop)\n\t}\n\tswitch r {\n\tcase '#':\n\t\tlx.push(lexTop)\n\t\treturn lexCommentStart\n\tcase '[':\n\t\treturn lexTableStart\n\tcase eof:\n\t\tif lx.pos > lx.start {\n\t\t\treturn lx.errorf(\"unexpected EOF\")\n\t\t}\n\t\tlx.emit(itemEOF)\n\t\treturn nil\n\t}\n\n\t// At this point, the only valid item can be a key, so we back up\n\t// and let the key lexer do the rest.\n\tlx.backup()\n\tlx.push(lexTopEnd)\n\treturn lexKeyStart\n}\n\n// lexTopEnd is entered whenever a top-level item has been consumed. (A value\n// or a table.) It must see only whitespace, and will turn back to lexTop\n// upon a newline. If it sees EOF, it will quit the lexer successfully.\nfunc lexTopEnd(lx *lexer) stateFn {\n\tr := lx.next()\n\tswitch {\n\tcase r == '#':\n\t\t// a comment will read to a newline for us.\n\t\tlx.push(lexTop)\n\t\treturn lexCommentStart\n\tcase isWhitespace(r):\n\t\treturn lexTopEnd\n\tcase isNL(r):\n\t\tlx.ignore()\n\t\treturn lexTop\n\tcase r == eof:\n\t\tlx.emit(itemEOF)\n\t\treturn nil\n\t}\n\treturn lx.errorf(\n\t\t\"expected a top-level item to end with a newline, comment, or EOF, but got %q instead\",\n\t\tr)\n}\n\n// lexTable lexes the beginning of a table. Namely, it makes sure that\n// it starts with a character other than '.' and ']'.\n// It assumes that '[' has already been consumed.\n// It also handles the case that this is an item in an array of tables.\n// e.g., '[[name]]'.\nfunc lexTableStart(lx *lexer) stateFn {\n\tif lx.peek() == '[' {\n\t\tlx.next()\n\t\tlx.emit(itemArrayTableStart)\n\t\tlx.push(lexArrayTableEnd)\n\t} else {\n\t\tlx.emit(itemTableStart)\n\t\tlx.push(lexTableEnd)\n\t}\n\treturn lexTableNameStart\n}\n\nfunc lexTableEnd(lx *lexer) stateFn {\n\tlx.emit(itemTableEnd)\n\treturn lexTopEnd\n}\n\nfunc lexArrayTableEnd(lx *lexer) stateFn {\n\tif r := lx.next(); r != ']' {\n\t\treturn lx.errorf(\"expected end of table array name delimiter ']', but got %q instead\", r)\n\t}\n\tlx.emit(itemArrayTableEnd)\n\treturn lexTopEnd\n}\n\nfunc lexTableNameStart(lx *lexer) stateFn {\n\tlx.skip(isWhitespace)\n\tswitch r := lx.peek(); {\n\tcase r == ']' || r == eof:\n\t\treturn lx.errorf(\"unexpected end of table name (table names cannot be empty)\")\n\tcase r == '.':\n\t\treturn lx.errorf(\"unexpected table separator (table names cannot be empty)\")\n\tcase r == '\"' || r == '\\'':\n\t\tlx.ignore()\n\t\tlx.push(lexTableNameEnd)\n\t\treturn lexQuotedName\n\tdefault:\n\t\tlx.push(lexTableNameEnd)\n\t\treturn lexBareName\n\t}\n}\n\n// lexTableNameEnd reads the end of a piece of a table name, optionally\n// consuming whitespace.\nfunc lexTableNameEnd(lx *lexer) stateFn {\n\tlx.skip(isWhitespace)\n\tswitch r := lx.next(); {\n\tcase isWhitespace(r):\n\t\treturn lexTableNameEnd\n\tcase r == '.':\n\t\tlx.ignore()\n\t\treturn lexTableNameStart\n\tcase r == ']':\n\t\treturn lx.pop()\n\tdefault:\n\t\treturn lx.errorf(\"expected '.' or ']' to end table name, but got %q instead\", r)\n\t}\n}\n\n// lexBareName lexes one part of a key or table.\n//\n// It assumes that at least one valid character for the table has already been\n// read.\n//\n// Lexes only one part, e.g. only 'a' inside 'a.b'.\nfunc lexBareName(lx *lexer) stateFn {\n\tr := lx.next()\n\tif isBareKeyChar(r) {\n\t\treturn lexBareName\n\t}\n\tlx.backup()\n\tlx.emit(itemText)\n\treturn lx.pop()\n}\n\n// lexBareName lexes one part of a key or table.\n//\n// It assumes that at least one valid character for the table has already been\n// read.\n//\n// Lexes only one part, e.g. only '\"a\"' inside '\"a\".b'.\nfunc lexQuotedName(lx *lexer) stateFn {\n\tr := lx.next()\n\tswitch {\n\tcase isWhitespace(r):\n\t\treturn lexSkip(lx, lexValue)\n\tcase r == '\"':\n\t\tlx.ignore() // ignore the '\"'\n\t\treturn lexString\n\tcase r == '\\'':\n\t\tlx.ignore() // ignore the \"'\"\n\t\treturn lexRawString\n\tcase r == eof:\n\t\treturn lx.errorf(\"unexpected EOF; expected value\")\n\tdefault:\n\t\treturn lx.errorf(\"expected value but found %q instead\", r)\n\t}\n}\n\n// lexKeyStart consumes all key parts until a '='.\nfunc lexKeyStart(lx *lexer) stateFn {\n\tlx.skip(isWhitespace)\n\tswitch r := lx.peek(); {\n\tcase r == '=' || r == eof:\n\t\treturn lx.errorf(\"unexpected '=': key name appears blank\")\n\tcase r == '.':\n\t\treturn lx.errorf(\"unexpected '.': keys cannot start with a '.'\")\n\tcase r == '\"' || r == '\\'':\n\t\tlx.ignore()\n\t\tfallthrough\n\tdefault: // Bare key\n\t\tlx.emit(itemKeyStart)\n\t\treturn lexKeyNameStart\n\t}\n}\n\nfunc lexKeyNameStart(lx *lexer) stateFn {\n\tlx.skip(isWhitespace)\n\tswitch r := lx.peek(); {\n\tcase r == '=' || r == eof:\n\t\treturn lx.errorf(\"unexpected '='\")\n\tcase r == '.':\n\t\treturn lx.errorf(\"unexpected '.'\")\n\tcase r == '\"' || r == '\\'':\n\t\tlx.ignore()\n\t\tlx.push(lexKeyEnd)\n\t\treturn lexQuotedName\n\tdefault:\n\t\tlx.push(lexKeyEnd)\n\t\treturn lexBareName\n\t}\n}\n\n// lexKeyEnd consumes the end of a key and trims whitespace (up to the key\n// separator).\nfunc lexKeyEnd(lx *lexer) stateFn {\n\tlx.skip(isWhitespace)\n\tswitch r := lx.next(); {\n\tcase isWhitespace(r):\n\t\treturn lexSkip(lx, lexKeyEnd)\n\tcase r == eof:\n\t\treturn lx.errorf(\"unexpected EOF; expected key separator '='\")\n\tcase r == '.':\n\t\tlx.ignore()\n\t\treturn lexKeyNameStart\n\tcase r == '=':\n\t\tlx.emit(itemKeyEnd)\n\t\treturn lexSkip(lx, lexValue)\n\tdefault:\n\t\treturn lx.errorf(\"expected '.' or '=', but got %q instead\", r)\n\t}\n}\n\n// lexValue starts the consumption of a value anywhere a value is expected.\n// lexValue will ignore whitespace.\n// After a value is lexed, the last state on the next is popped and returned.\nfunc lexValue(lx *lexer) stateFn {\n\t// We allow whitespace to precede a value, but NOT newlines.\n\t// In array syntax, the array states are responsible for ignoring newlines.\n\tr := lx.next()\n\tswitch {\n\tcase isWhitespace(r):\n\t\treturn lexSkip(lx, lexValue)\n\tcase isDigit(r):\n\t\tlx.backup() // avoid an extra state and use the same as above\n\t\treturn lexNumberOrDateStart\n\t}\n\tswitch r {\n\tcase '[':\n\t\tlx.ignore()\n\t\tlx.emit(itemArray)\n\t\treturn lexArrayValue\n\tcase '{':\n\t\tlx.ignore()\n\t\tlx.emit(itemInlineTableStart)\n\t\treturn lexInlineTableValue\n\tcase '\"':\n\t\tif lx.accept('\"') {\n\t\t\tif lx.accept('\"') {\n\t\t\t\tlx.ignore() // Ignore \"\"\"\n\t\t\t\treturn lexMultilineString\n\t\t\t}\n\t\t\tlx.backup()\n\t\t}\n\t\tlx.ignore() // ignore the '\"'\n\t\treturn lexString\n\tcase '\\'':\n\t\tif lx.accept('\\'') {\n\t\t\tif lx.accept('\\'') {\n\t\t\t\tlx.ignore() // Ignore \"\"\"\n\t\t\t\treturn lexMultilineRawString\n\t\t\t}\n\t\t\tlx.backup()\n\t\t}\n\t\tlx.ignore() // ignore the \"'\"\n\t\treturn lexRawString\n\tcase '.': // special error case, be kind to users\n\t\treturn lx.errorf(\"floats must start with a digit, not '.'\")\n\tcase 'i', 'n':\n\t\tif (lx.accept('n') && lx.accept('f')) || (lx.accept('a') && lx.accept('n')) {\n\t\t\tlx.emit(itemFloat)\n\t\t\treturn lx.pop()\n\t\t}\n\tcase '-', '+':\n\t\treturn lexDecimalNumberStart\n\t}\n\tif unicode.IsLetter(r) {\n\t\t// Be permissive here; lexBool will give a nice error if the\n\t\t// user wrote something like\n\t\t//   x = foo\n\t\t// (i.e. not 'true' or 'false' but is something else word-like.)\n\t\tlx.backup()\n\t\treturn lexBool\n\t}\n\tif r == eof {\n\t\treturn lx.errorf(\"unexpected EOF; expected value\")\n\t}\n\treturn lx.errorf(\"expected value but found %q instead\", r)\n}\n\n// lexArrayValue consumes one value in an array. It assumes that '[' or ','\n// have already been consumed. All whitespace and newlines are ignored.\nfunc lexArrayValue(lx *lexer) stateFn {\n\tr := lx.next()\n\tswitch {\n\tcase isWhitespace(r) || isNL(r):\n\t\treturn lexSkip(lx, lexArrayValue)\n\tcase r == '#':\n\t\tlx.push(lexArrayValue)\n\t\treturn lexCommentStart\n\tcase r == ',':\n\t\treturn lx.errorf(\"unexpected comma\")\n\tcase r == ']':\n\t\treturn lexArrayEnd\n\t}\n\n\tlx.backup()\n\tlx.push(lexArrayValueEnd)\n\treturn lexValue\n}\n\n// lexArrayValueEnd consumes everything between the end of an array value and\n// the next value (or the end of the array): it ignores whitespace and newlines\n// and expects either a ',' or a ']'.\nfunc lexArrayValueEnd(lx *lexer) stateFn {\n\tswitch r := lx.next(); {\n\tcase isWhitespace(r) || isNL(r):\n\t\treturn lexSkip(lx, lexArrayValueEnd)\n\tcase r == '#':\n\t\tlx.push(lexArrayValueEnd)\n\t\treturn lexCommentStart\n\tcase r == ',':\n\t\tlx.ignore()\n\t\treturn lexArrayValue // move on to the next value\n\tcase r == ']':\n\t\treturn lexArrayEnd\n\tdefault:\n\t\treturn lx.errorf(\"expected a comma (',') or array terminator (']'), but got %s\", runeOrEOF(r))\n\t}\n}\n\n// lexArrayEnd finishes the lexing of an array.\n// It assumes that a ']' has just been consumed.\nfunc lexArrayEnd(lx *lexer) stateFn {\n\tlx.ignore()\n\tlx.emit(itemArrayEnd)\n\treturn lx.pop()\n}\n\n// lexInlineTableValue consumes one key/value pair in an inline table.\n// It assumes that '{' or ',' have already been consumed. Whitespace is ignored.\nfunc lexInlineTableValue(lx *lexer) stateFn {\n\tr := lx.next()\n\tswitch {\n\tcase isWhitespace(r):\n\t\treturn lexSkip(lx, lexInlineTableValue)\n\tcase isNL(r):\n\t\treturn lx.errorPrevLine(errLexInlineTableNL{})\n\tcase r == '#':\n\t\tlx.push(lexInlineTableValue)\n\t\treturn lexCommentStart\n\tcase r == ',':\n\t\treturn lx.errorf(\"unexpected comma\")\n\tcase r == '}':\n\t\treturn lexInlineTableEnd\n\t}\n\tlx.backup()\n\tlx.push(lexInlineTableValueEnd)\n\treturn lexKeyStart\n}\n\n// lexInlineTableValueEnd consumes everything between the end of an inline table\n// key/value pair and the next pair (or the end of the table):\n// it ignores whitespace and expects either a ',' or a '}'.\nfunc lexInlineTableValueEnd(lx *lexer) stateFn {\n\tswitch r := lx.next(); {\n\tcase isWhitespace(r):\n\t\treturn lexSkip(lx, lexInlineTableValueEnd)\n\tcase isNL(r):\n\t\treturn lx.errorPrevLine(errLexInlineTableNL{})\n\tcase r == '#':\n\t\tlx.push(lexInlineTableValueEnd)\n\t\treturn lexCommentStart\n\tcase r == ',':\n\t\tlx.ignore()\n\t\tlx.skip(isWhitespace)\n\t\tif lx.peek() == '}' {\n\t\t\treturn lx.errorf(\"trailing comma not allowed in inline tables\")\n\t\t}\n\t\treturn lexInlineTableValue\n\tcase r == '}':\n\t\treturn lexInlineTableEnd\n\tdefault:\n\t\treturn lx.errorf(\"expected a comma or an inline table terminator '}', but got %s instead\", runeOrEOF(r))\n\t}\n}\n\nfunc runeOrEOF(r rune) string {\n\tif r == eof {\n\t\treturn \"end of file\"\n\t}\n\treturn \"'\" + string(r) + \"'\"\n}\n\n// lexInlineTableEnd finishes the lexing of an inline table.\n// It assumes that a '}' has just been consumed.\nfunc lexInlineTableEnd(lx *lexer) stateFn {\n\tlx.ignore()\n\tlx.emit(itemInlineTableEnd)\n\treturn lx.pop()\n}\n\n// lexString consumes the inner contents of a string. It assumes that the\n// beginning '\"' has already been consumed and ignored.\nfunc lexString(lx *lexer) stateFn {\n\tr := lx.next()\n\tswitch {\n\tcase r == eof:\n\t\treturn lx.errorf(`unexpected EOF; expected '\"'`)\n\tcase isNL(r):\n\t\treturn lx.errorPrevLine(errLexStringNL{})\n\tcase r == '\\\\':\n\t\tlx.push(lexString)\n\t\treturn lexStringEscape\n\tcase r == '\"':\n\t\tlx.backup()\n\t\tlx.emit(itemString)\n\t\tlx.next()\n\t\tlx.ignore()\n\t\treturn lx.pop()\n\t}\n\treturn lexString\n}\n\n// lexMultilineString consumes the inner contents of a string. It assumes that\n// the beginning '\"\"\"' has already been consumed and ignored.\nfunc lexMultilineString(lx *lexer) stateFn {\n\tr := lx.next()\n\tswitch r {\n\tdefault:\n\t\treturn lexMultilineString\n\tcase eof:\n\t\treturn lx.errorf(`unexpected EOF; expected '\"\"\"'`)\n\tcase '\\\\':\n\t\treturn lexMultilineStringEscape\n\tcase '\"':\n\t\t/// Found \" → try to read two more \"\".\n\t\tif lx.accept('\"') {\n\t\t\tif lx.accept('\"') {\n\t\t\t\t/// Peek ahead: the string can contain \" and \"\", including at the\n\t\t\t\t/// end: \"\"\"str\"\"\"\"\"\n\t\t\t\t/// 6 or more at the end, however, is an error.\n\t\t\t\tif lx.peek() == '\"' {\n\t\t\t\t\t/// Check if we already lexed 5 's; if so we have 6 now, and\n\t\t\t\t\t/// that's just too many man!\n\t\t\t\t\t///\n\t\t\t\t\t/// Second check is for the edge case:\n\t\t\t\t\t///\n\t\t\t\t\t///            two quotes allowed.\n\t\t\t\t\t///            vv\n\t\t\t\t\t///   \"\"\"lol \\\"\"\"\"\"\"\n\t\t\t\t\t///          ^^  ^^^---- closing three\n\t\t\t\t\t///     escaped\n\t\t\t\t\t///\n\t\t\t\t\t/// But ugly, but it works\n\t\t\t\t\tif strings.HasSuffix(lx.current(), `\"\"\"\"\"`) && !strings.HasSuffix(lx.current(), `\\\"\"\"\"\"`) {\n\t\t\t\t\t\treturn lx.errorf(`unexpected '\"\"\"\"\"\"'`)\n\t\t\t\t\t}\n\t\t\t\t\tlx.backup()\n\t\t\t\t\tlx.backup()\n\t\t\t\t\treturn lexMultilineString\n\t\t\t\t}\n\n\t\t\t\tlx.backup() /// backup: don't include the \"\"\" in the item.\n\t\t\t\tlx.backup()\n\t\t\t\tlx.backup()\n\t\t\t\tlx.emit(itemMultilineString)\n\t\t\t\tlx.next() /// Read over ''' again and discard it.\n\t\t\t\tlx.next()\n\t\t\t\tlx.next()\n\t\t\t\tlx.ignore()\n\t\t\t\treturn lx.pop()\n\t\t\t}\n\t\t\tlx.backup()\n\t\t}\n\t\treturn lexMultilineString\n\t}\n}\n\n// lexRawString consumes a raw string. Nothing can be escaped in such a string.\n// It assumes that the beginning \"'\" has already been consumed and ignored.\nfunc lexRawString(lx *lexer) stateFn {\n\tr := lx.next()\n\tswitch {\n\tdefault:\n\t\treturn lexRawString\n\tcase r == eof:\n\t\treturn lx.errorf(`unexpected EOF; expected \"'\"`)\n\tcase isNL(r):\n\t\treturn lx.errorPrevLine(errLexStringNL{})\n\tcase r == '\\'':\n\t\tlx.backup()\n\t\tlx.emit(itemRawString)\n\t\tlx.next()\n\t\tlx.ignore()\n\t\treturn lx.pop()\n\t}\n}\n\n// lexMultilineRawString consumes a raw string. Nothing can be escaped in such\n// a string. It assumes that the beginning \"'''\" has already been consumed and\n// ignored.\nfunc lexMultilineRawString(lx *lexer) stateFn {\n\tr := lx.next()\n\tswitch r {\n\tdefault:\n\t\treturn lexMultilineRawString\n\tcase eof:\n\t\treturn lx.errorf(`unexpected EOF; expected \"'''\"`)\n\tcase '\\'':\n\t\t/// Found ' → try to read two more ''.\n\t\tif lx.accept('\\'') {\n\t\t\tif lx.accept('\\'') {\n\t\t\t\t/// Peek ahead: the string can contain ' and '', including at the\n\t\t\t\t/// end: '''str'''''\n\t\t\t\t/// 6 or more at the end, however, is an error.\n\t\t\t\tif lx.peek() == '\\'' {\n\t\t\t\t\t/// Check if we already lexed 5 's; if so we have 6 now, and\n\t\t\t\t\t/// that's just too many man!\n\t\t\t\t\tif strings.HasSuffix(lx.current(), \"'''''\") {\n\t\t\t\t\t\treturn lx.errorf(`unexpected \"''''''\"`)\n\t\t\t\t\t}\n\t\t\t\t\tlx.backup()\n\t\t\t\t\tlx.backup()\n\t\t\t\t\treturn lexMultilineRawString\n\t\t\t\t}\n\n\t\t\t\tlx.backup() /// backup: don't include the ''' in the item.\n\t\t\t\tlx.backup()\n\t\t\t\tlx.backup()\n\t\t\t\tlx.emit(itemRawMultilineString)\n\t\t\t\tlx.next() /// Read over ''' again and discard it.\n\t\t\t\tlx.next()\n\t\t\t\tlx.next()\n\t\t\t\tlx.ignore()\n\t\t\t\treturn lx.pop()\n\t\t\t}\n\t\t\tlx.backup()\n\t\t}\n\t\treturn lexMultilineRawString\n\t}\n}\n\n// lexMultilineStringEscape consumes an escaped character. It assumes that the\n// preceding '\\\\' has already been consumed.\nfunc lexMultilineStringEscape(lx *lexer) stateFn {\n\tif isNL(lx.next()) { /// \\ escaping newline.\n\t\treturn lexMultilineString\n\t}\n\tlx.backup()\n\tlx.push(lexMultilineString)\n\treturn lexStringEscape(lx)\n}\n\nfunc lexStringEscape(lx *lexer) stateFn {\n\tr := lx.next()\n\tswitch r {\n\tcase 'b':\n\t\tfallthrough\n\tcase 't':\n\t\tfallthrough\n\tcase 'n':\n\t\tfallthrough\n\tcase 'f':\n\t\tfallthrough\n\tcase 'r':\n\t\tfallthrough\n\tcase '\"':\n\t\tfallthrough\n\tcase ' ', '\\t':\n\t\t// Inside \"\"\" .. \"\"\" strings you can use \\ to escape newlines, and any\n\t\t// amount of whitespace can be between the \\ and \\n.\n\t\tfallthrough\n\tcase '\\\\':\n\t\treturn lx.pop()\n\tcase 'u':\n\t\treturn lexShortUnicodeEscape\n\tcase 'U':\n\t\treturn lexLongUnicodeEscape\n\t}\n\treturn lx.error(errLexEscape{r})\n}\n\nfunc lexShortUnicodeEscape(lx *lexer) stateFn {\n\tvar r rune\n\tfor i := 0; i < 4; i++ {\n\t\tr = lx.next()\n\t\tif !isHexadecimal(r) {\n\t\t\treturn lx.errorf(\n\t\t\t\t`expected four hexadecimal digits after '\\u', but got %q instead`,\n\t\t\t\tlx.current())\n\t\t}\n\t}\n\treturn lx.pop()\n}\n\nfunc lexLongUnicodeEscape(lx *lexer) stateFn {\n\tvar r rune\n\tfor i := 0; i < 8; i++ {\n\t\tr = lx.next()\n\t\tif !isHexadecimal(r) {\n\t\t\treturn lx.errorf(\n\t\t\t\t`expected eight hexadecimal digits after '\\U', but got %q instead`,\n\t\t\t\tlx.current())\n\t\t}\n\t}\n\treturn lx.pop()\n}\n\n// lexNumberOrDateStart processes the first character of a value which begins\n// with a digit. It exists to catch values starting with '0', so that\n// lexBaseNumberOrDate can differentiate base prefixed integers from other\n// types.\nfunc lexNumberOrDateStart(lx *lexer) stateFn {\n\tr := lx.next()\n\tswitch r {\n\tcase '0':\n\t\treturn lexBaseNumberOrDate\n\t}\n\n\tif !isDigit(r) {\n\t\t// The only way to reach this state is if the value starts\n\t\t// with a digit, so specifically treat anything else as an\n\t\t// error.\n\t\treturn lx.errorf(\"expected a digit but got %q\", r)\n\t}\n\n\treturn lexNumberOrDate\n}\n\n// lexNumberOrDate consumes either an integer, float or datetime.\nfunc lexNumberOrDate(lx *lexer) stateFn {\n\tr := lx.next()\n\tif isDigit(r) {\n\t\treturn lexNumberOrDate\n\t}\n\tswitch r {\n\tcase '-', ':':\n\t\treturn lexDatetime\n\tcase '_':\n\t\treturn lexDecimalNumber\n\tcase '.', 'e', 'E':\n\t\treturn lexFloat\n\t}\n\n\tlx.backup()\n\tlx.emit(itemInteger)\n\treturn lx.pop()\n}\n\n// lexDatetime consumes a Datetime, to a first approximation.\n// The parser validates that it matches one of the accepted formats.\nfunc lexDatetime(lx *lexer) stateFn {\n\tr := lx.next()\n\tif isDigit(r) {\n\t\treturn lexDatetime\n\t}\n\tswitch r {\n\tcase '-', ':', 'T', 't', ' ', '.', 'Z', 'z', '+':\n\t\treturn lexDatetime\n\t}\n\n\tlx.backup()\n\tlx.emitTrim(itemDatetime)\n\treturn lx.pop()\n}\n\n// lexHexInteger consumes a hexadecimal integer after seeing the '0x' prefix.\nfunc lexHexInteger(lx *lexer) stateFn {\n\tr := lx.next()\n\tif isHexadecimal(r) {\n\t\treturn lexHexInteger\n\t}\n\tswitch r {\n\tcase '_':\n\t\treturn lexHexInteger\n\t}\n\n\tlx.backup()\n\tlx.emit(itemInteger)\n\treturn lx.pop()\n}\n\n// lexOctalInteger consumes an octal integer after seeing the '0o' prefix.\nfunc lexOctalInteger(lx *lexer) stateFn {\n\tr := lx.next()\n\tif isOctal(r) {\n\t\treturn lexOctalInteger\n\t}\n\tswitch r {\n\tcase '_':\n\t\treturn lexOctalInteger\n\t}\n\n\tlx.backup()\n\tlx.emit(itemInteger)\n\treturn lx.pop()\n}\n\n// lexBinaryInteger consumes a binary integer after seeing the '0b' prefix.\nfunc lexBinaryInteger(lx *lexer) stateFn {\n\tr := lx.next()\n\tif isBinary(r) {\n\t\treturn lexBinaryInteger\n\t}\n\tswitch r {\n\tcase '_':\n\t\treturn lexBinaryInteger\n\t}\n\n\tlx.backup()\n\tlx.emit(itemInteger)\n\treturn lx.pop()\n}\n\n// lexDecimalNumber consumes a decimal float or integer.\nfunc lexDecimalNumber(lx *lexer) stateFn {\n\tr := lx.next()\n\tif isDigit(r) {\n\t\treturn lexDecimalNumber\n\t}\n\tswitch r {\n\tcase '.', 'e', 'E':\n\t\treturn lexFloat\n\tcase '_':\n\t\treturn lexDecimalNumber\n\t}\n\n\tlx.backup()\n\tlx.emit(itemInteger)\n\treturn lx.pop()\n}\n\n// lexDecimalNumber consumes the first digit of a number beginning with a sign.\n// It assumes the sign has already been consumed. Values which start with a sign\n// are only allowed to be decimal integers or floats.\n//\n// The special \"nan\" and \"inf\" values are also recognized.\nfunc lexDecimalNumberStart(lx *lexer) stateFn {\n\tr := lx.next()\n\n\t// Special error cases to give users better error messages\n\tswitch r {\n\tcase 'i':\n\t\tif !lx.accept('n') || !lx.accept('f') {\n\t\t\treturn lx.errorf(\"invalid float: '%s'\", lx.current())\n\t\t}\n\t\tlx.emit(itemFloat)\n\t\treturn lx.pop()\n\tcase 'n':\n\t\tif !lx.accept('a') || !lx.accept('n') {\n\t\t\treturn lx.errorf(\"invalid float: '%s'\", lx.current())\n\t\t}\n\t\tlx.emit(itemFloat)\n\t\treturn lx.pop()\n\tcase '0':\n\t\tp := lx.peek()\n\t\tswitch p {\n\t\tcase 'b', 'o', 'x':\n\t\t\treturn lx.errorf(\"cannot use sign with non-decimal numbers: '%s%c'\", lx.current(), p)\n\t\t}\n\tcase '.':\n\t\treturn lx.errorf(\"floats must start with a digit, not '.'\")\n\t}\n\n\tif isDigit(r) {\n\t\treturn lexDecimalNumber\n\t}\n\n\treturn lx.errorf(\"expected a digit but got %q\", r)\n}\n\n// lexBaseNumberOrDate differentiates between the possible values which\n// start with '0'. It assumes that before reaching this state, the initial '0'\n// has been consumed.\nfunc lexBaseNumberOrDate(lx *lexer) stateFn {\n\tr := lx.next()\n\t// Note: All datetimes start with at least two digits, so we don't\n\t// handle date characters (':', '-', etc.) here.\n\tif isDigit(r) {\n\t\treturn lexNumberOrDate\n\t}\n\tswitch r {\n\tcase '_':\n\t\t// Can only be decimal, because there can't be an underscore\n\t\t// between the '0' and the base designator, and dates can't\n\t\t// contain underscores.\n\t\treturn lexDecimalNumber\n\tcase '.', 'e', 'E':\n\t\treturn lexFloat\n\tcase 'b':\n\t\tr = lx.peek()\n\t\tif !isBinary(r) {\n\t\t\tlx.errorf(\"not a binary number: '%s%c'\", lx.current(), r)\n\t\t}\n\t\treturn lexBinaryInteger\n\tcase 'o':\n\t\tr = lx.peek()\n\t\tif !isOctal(r) {\n\t\t\tlx.errorf(\"not an octal number: '%s%c'\", lx.current(), r)\n\t\t}\n\t\treturn lexOctalInteger\n\tcase 'x':\n\t\tr = lx.peek()\n\t\tif !isHexadecimal(r) {\n\t\t\tlx.errorf(\"not a hexidecimal number: '%s%c'\", lx.current(), r)\n\t\t}\n\t\treturn lexHexInteger\n\t}\n\n\tlx.backup()\n\tlx.emit(itemInteger)\n\treturn lx.pop()\n}\n\n// lexFloat consumes the elements of a float. It allows any sequence of\n// float-like characters, so floats emitted by the lexer are only a first\n// approximation and must be validated by the parser.\nfunc lexFloat(lx *lexer) stateFn {\n\tr := lx.next()\n\tif isDigit(r) {\n\t\treturn lexFloat\n\t}\n\tswitch r {\n\tcase '_', '.', '-', '+', 'e', 'E':\n\t\treturn lexFloat\n\t}\n\n\tlx.backup()\n\tlx.emit(itemFloat)\n\treturn lx.pop()\n}\n\n// lexBool consumes a bool string: 'true' or 'false.\nfunc lexBool(lx *lexer) stateFn {\n\tvar rs []rune\n\tfor {\n\t\tr := lx.next()\n\t\tif !unicode.IsLetter(r) {\n\t\t\tlx.backup()\n\t\t\tbreak\n\t\t}\n\t\trs = append(rs, r)\n\t}\n\ts := string(rs)\n\tswitch s {\n\tcase \"true\", \"false\":\n\t\tlx.emit(itemBool)\n\t\treturn lx.pop()\n\t}\n\treturn lx.errorf(\"expected value but found %q instead\", s)\n}\n\n// lexCommentStart begins the lexing of a comment. It will emit\n// itemCommentStart and consume no characters, passing control to lexComment.\nfunc lexCommentStart(lx *lexer) stateFn {\n\tlx.ignore()\n\tlx.emit(itemCommentStart)\n\treturn lexComment\n}\n\n// lexComment lexes an entire comment. It assumes that '#' has been consumed.\n// It will consume *up to* the first newline character, and pass control\n// back to the last state on the stack.\nfunc lexComment(lx *lexer) stateFn {\n\tswitch r := lx.next(); {\n\tcase isNL(r) || r == eof:\n\t\tlx.backup()\n\t\tlx.emit(itemText)\n\t\treturn lx.pop()\n\tdefault:\n\t\treturn lexComment\n\t}\n}\n\n// lexSkip ignores all slurped input and moves on to the next state.\nfunc lexSkip(lx *lexer, nextState stateFn) stateFn {\n\tlx.ignore()\n\treturn nextState\n}\n\nfunc (s stateFn) String() string {\n\tname := runtime.FuncForPC(reflect.ValueOf(s).Pointer()).Name()\n\tif i := strings.LastIndexByte(name, '.'); i > -1 {\n\t\tname = name[i+1:]\n\t}\n\tif s == nil {\n\t\tname = \"<nil>\"\n\t}\n\treturn name + \"()\"\n}\n\nfunc (itype itemType) String() string {\n\tswitch itype {\n\tcase itemError:\n\t\treturn \"Error\"\n\tcase itemNIL:\n\t\treturn \"NIL\"\n\tcase itemEOF:\n\t\treturn \"EOF\"\n\tcase itemText:\n\t\treturn \"Text\"\n\tcase itemString, itemRawString, itemMultilineString, itemRawMultilineString:\n\t\treturn \"String\"\n\tcase itemBool:\n\t\treturn \"Bool\"\n\tcase itemInteger:\n\t\treturn \"Integer\"\n\tcase itemFloat:\n\t\treturn \"Float\"\n\tcase itemDatetime:\n\t\treturn \"DateTime\"\n\tcase itemTableStart:\n\t\treturn \"TableStart\"\n\tcase itemTableEnd:\n\t\treturn \"TableEnd\"\n\tcase itemKeyStart:\n\t\treturn \"KeyStart\"\n\tcase itemKeyEnd:\n\t\treturn \"KeyEnd\"\n\tcase itemArray:\n\t\treturn \"Array\"\n\tcase itemArrayEnd:\n\t\treturn \"ArrayEnd\"\n\tcase itemCommentStart:\n\t\treturn \"CommentStart\"\n\tcase itemInlineTableStart:\n\t\treturn \"InlineTableStart\"\n\tcase itemInlineTableEnd:\n\t\treturn \"InlineTableEnd\"\n\t}\n\tpanic(fmt.Sprintf(\"BUG: Unknown type '%d'.\", int(itype)))\n}\n\nfunc (item item) String() string {\n\treturn fmt.Sprintf(\"(%s, %s)\", item.typ.String(), item.val)\n}\n\nfunc isWhitespace(r rune) bool { return r == '\\t' || r == ' ' }\nfunc isNL(r rune) bool         { return r == '\\n' || r == '\\r' }\nfunc isControl(r rune) bool { // Control characters except \\t, \\r, \\n\n\tswitch r {\n\tcase '\\t', '\\r', '\\n':\n\t\treturn false\n\tdefault:\n\t\treturn (r >= 0x00 && r <= 0x1f) || r == 0x7f\n\t}\n}\nfunc isDigit(r rune) bool  { return r >= '0' && r <= '9' }\nfunc isBinary(r rune) bool { return r == '0' || r == '1' }\nfunc isOctal(r rune) bool  { return r >= '0' && r <= '7' }\nfunc isHexadecimal(r rune) bool {\n\treturn (r >= '0' && r <= '9') || (r >= 'a' && r <= 'f') || (r >= 'A' && r <= 'F')\n}\nfunc isBareKeyChar(r rune) bool {\n\treturn (r >= 'A' && r <= 'Z') ||\n\t\t(r >= 'a' && r <= 'z') ||\n\t\t(r >= '0' && r <= '9') ||\n\t\tr == '_' || r == '-'\n}\n"
  },
  {
    "path": "vendor/github.com/BurntSushi/toml/meta.go",
    "content": "package toml\n\nimport (\n\t\"strings\"\n)\n\n// MetaData allows access to meta information about TOML data that's not\n// accessible otherwise.\n//\n// It allows checking if a key is defined in the TOML data, whether any keys\n// were undecoded, and the TOML type of a key.\ntype MetaData struct {\n\tcontext Key // Used only during decoding.\n\n\tkeyInfo map[string]keyInfo\n\tmapping map[string]interface{}\n\tkeys    []Key\n\tdecoded map[string]struct{}\n\tdata    []byte // Input file; for errors.\n}\n\n// IsDefined reports if the key exists in the TOML data.\n//\n// The key should be specified hierarchically, for example to access the TOML\n// key \"a.b.c\" you would use IsDefined(\"a\", \"b\", \"c\"). Keys are case sensitive.\n//\n// Returns false for an empty key.\nfunc (md *MetaData) IsDefined(key ...string) bool {\n\tif len(key) == 0 {\n\t\treturn false\n\t}\n\n\tvar (\n\t\thash      map[string]interface{}\n\t\tok        bool\n\t\thashOrVal interface{} = md.mapping\n\t)\n\tfor _, k := range key {\n\t\tif hash, ok = hashOrVal.(map[string]interface{}); !ok {\n\t\t\treturn false\n\t\t}\n\t\tif hashOrVal, ok = hash[k]; !ok {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Type returns a string representation of the type of the key specified.\n//\n// Type will return the empty string if given an empty key or a key that does\n// not exist. Keys are case sensitive.\nfunc (md *MetaData) Type(key ...string) string {\n\tif ki, ok := md.keyInfo[Key(key).String()]; ok {\n\t\treturn ki.tomlType.typeString()\n\t}\n\treturn \"\"\n}\n\n// Keys returns a slice of every key in the TOML data, including key groups.\n//\n// Each key is itself a slice, where the first element is the top of the\n// hierarchy and the last is the most specific. The list will have the same\n// order as the keys appeared in the TOML data.\n//\n// All keys returned are non-empty.\nfunc (md *MetaData) Keys() []Key {\n\treturn md.keys\n}\n\n// Undecoded returns all keys that have not been decoded in the order in which\n// they appear in the original TOML document.\n//\n// This includes keys that haven't been decoded because of a Primitive value.\n// Once the Primitive value is decoded, the keys will be considered decoded.\n//\n// Also note that decoding into an empty interface will result in no decoding,\n// and so no keys will be considered decoded.\n//\n// In this sense, the Undecoded keys correspond to keys in the TOML document\n// that do not have a concrete type in your representation.\nfunc (md *MetaData) Undecoded() []Key {\n\tundecoded := make([]Key, 0, len(md.keys))\n\tfor _, key := range md.keys {\n\t\tif _, ok := md.decoded[key.String()]; !ok {\n\t\t\tundecoded = append(undecoded, key)\n\t\t}\n\t}\n\treturn undecoded\n}\n\n// Key represents any TOML key, including key groups. Use (MetaData).Keys to get\n// values of this type.\ntype Key []string\n\nfunc (k Key) String() string {\n\tss := make([]string, len(k))\n\tfor i := range k {\n\t\tss[i] = k.maybeQuoted(i)\n\t}\n\treturn strings.Join(ss, \".\")\n}\n\nfunc (k Key) maybeQuoted(i int) string {\n\tif k[i] == \"\" {\n\t\treturn `\"\"`\n\t}\n\tfor _, c := range k[i] {\n\t\tif !isBareKeyChar(c) {\n\t\t\treturn `\"` + dblQuotedReplacer.Replace(k[i]) + `\"`\n\t\t}\n\t}\n\treturn k[i]\n}\n\nfunc (k Key) add(piece string) Key {\n\tnewKey := make(Key, len(k)+1)\n\tcopy(newKey, k)\n\tnewKey[len(k)] = piece\n\treturn newKey\n}\n"
  },
  {
    "path": "vendor/github.com/BurntSushi/toml/parse.go",
    "content": "package toml\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\t\"unicode/utf8\"\n\n\t\"github.com/BurntSushi/toml/internal\"\n)\n\ntype parser struct {\n\tlx         *lexer\n\tcontext    Key      // Full key for the current hash in scope.\n\tcurrentKey string   // Base key name for everything except hashes.\n\tpos        Position // Current position in the TOML file.\n\n\tordered []Key // List of keys in the order that they appear in the TOML data.\n\n\tkeyInfo   map[string]keyInfo     // Map keyname → info about the TOML key.\n\tmapping   map[string]interface{} // Map keyname → key value.\n\timplicits map[string]struct{}    // Record implicit keys (e.g. \"key.group.names\").\n}\n\ntype keyInfo struct {\n\tpos      Position\n\ttomlType tomlType\n}\n\nfunc parse(data string) (p *parser, err error) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tif pErr, ok := r.(ParseError); ok {\n\t\t\t\tpErr.input = data\n\t\t\t\terr = pErr\n\t\t\t\treturn\n\t\t\t}\n\t\t\tpanic(r)\n\t\t}\n\t}()\n\n\t// Read over BOM; do this here as the lexer calls utf8.DecodeRuneInString()\n\t// which mangles stuff.\n\tif strings.HasPrefix(data, \"\\xff\\xfe\") || strings.HasPrefix(data, \"\\xfe\\xff\") {\n\t\tdata = data[2:]\n\t}\n\n\t// Examine first few bytes for NULL bytes; this probably means it's a UTF-16\n\t// file (second byte in surrogate pair being NULL). Again, do this here to\n\t// avoid having to deal with UTF-8/16 stuff in the lexer.\n\tex := 6\n\tif len(data) < 6 {\n\t\tex = len(data)\n\t}\n\tif i := strings.IndexRune(data[:ex], 0); i > -1 {\n\t\treturn nil, ParseError{\n\t\t\tMessage:  \"files cannot contain NULL bytes; probably using UTF-16; TOML files must be UTF-8\",\n\t\t\tPosition: Position{Line: 1, Start: i, Len: 1},\n\t\t\tLine:     1,\n\t\t\tinput:    data,\n\t\t}\n\t}\n\n\tp = &parser{\n\t\tkeyInfo:   make(map[string]keyInfo),\n\t\tmapping:   make(map[string]interface{}),\n\t\tlx:        lex(data),\n\t\tordered:   make([]Key, 0),\n\t\timplicits: make(map[string]struct{}),\n\t}\n\tfor {\n\t\titem := p.next()\n\t\tif item.typ == itemEOF {\n\t\t\tbreak\n\t\t}\n\t\tp.topLevel(item)\n\t}\n\n\treturn p, nil\n}\n\nfunc (p *parser) panicErr(it item, err error) {\n\tpanic(ParseError{\n\t\terr:      err,\n\t\tPosition: it.pos,\n\t\tLine:     it.pos.Len,\n\t\tLastKey:  p.current(),\n\t})\n}\n\nfunc (p *parser) panicItemf(it item, format string, v ...interface{}) {\n\tpanic(ParseError{\n\t\tMessage:  fmt.Sprintf(format, v...),\n\t\tPosition: it.pos,\n\t\tLine:     it.pos.Len,\n\t\tLastKey:  p.current(),\n\t})\n}\n\nfunc (p *parser) panicf(format string, v ...interface{}) {\n\tpanic(ParseError{\n\t\tMessage:  fmt.Sprintf(format, v...),\n\t\tPosition: p.pos,\n\t\tLine:     p.pos.Line,\n\t\tLastKey:  p.current(),\n\t})\n}\n\nfunc (p *parser) next() item {\n\tit := p.lx.nextItem()\n\t//fmt.Printf(\"ITEM %-18s line %-3d │ %q\\n\", it.typ, it.pos.Line, it.val)\n\tif it.typ == itemError {\n\t\tif it.err != nil {\n\t\t\tpanic(ParseError{\n\t\t\t\tPosition: it.pos,\n\t\t\t\tLine:     it.pos.Line,\n\t\t\t\tLastKey:  p.current(),\n\t\t\t\terr:      it.err,\n\t\t\t})\n\t\t}\n\n\t\tp.panicItemf(it, \"%s\", it.val)\n\t}\n\treturn it\n}\n\nfunc (p *parser) nextPos() item {\n\tit := p.next()\n\tp.pos = it.pos\n\treturn it\n}\n\nfunc (p *parser) bug(format string, v ...interface{}) {\n\tpanic(fmt.Sprintf(\"BUG: \"+format+\"\\n\\n\", v...))\n}\n\nfunc (p *parser) expect(typ itemType) item {\n\tit := p.next()\n\tp.assertEqual(typ, it.typ)\n\treturn it\n}\n\nfunc (p *parser) assertEqual(expected, got itemType) {\n\tif expected != got {\n\t\tp.bug(\"Expected '%s' but got '%s'.\", expected, got)\n\t}\n}\n\nfunc (p *parser) topLevel(item item) {\n\tswitch item.typ {\n\tcase itemCommentStart: // # ..\n\t\tp.expect(itemText)\n\tcase itemTableStart: // [ .. ]\n\t\tname := p.nextPos()\n\n\t\tvar key Key\n\t\tfor ; name.typ != itemTableEnd && name.typ != itemEOF; name = p.next() {\n\t\t\tkey = append(key, p.keyString(name))\n\t\t}\n\t\tp.assertEqual(itemTableEnd, name.typ)\n\n\t\tp.addContext(key, false)\n\t\tp.setType(\"\", tomlHash, item.pos)\n\t\tp.ordered = append(p.ordered, key)\n\tcase itemArrayTableStart: // [[ .. ]]\n\t\tname := p.nextPos()\n\n\t\tvar key Key\n\t\tfor ; name.typ != itemArrayTableEnd && name.typ != itemEOF; name = p.next() {\n\t\t\tkey = append(key, p.keyString(name))\n\t\t}\n\t\tp.assertEqual(itemArrayTableEnd, name.typ)\n\n\t\tp.addContext(key, true)\n\t\tp.setType(\"\", tomlArrayHash, item.pos)\n\t\tp.ordered = append(p.ordered, key)\n\tcase itemKeyStart: // key = ..\n\t\touterContext := p.context\n\t\t/// Read all the key parts (e.g. 'a' and 'b' in 'a.b')\n\t\tk := p.nextPos()\n\t\tvar key Key\n\t\tfor ; k.typ != itemKeyEnd && k.typ != itemEOF; k = p.next() {\n\t\t\tkey = append(key, p.keyString(k))\n\t\t}\n\t\tp.assertEqual(itemKeyEnd, k.typ)\n\n\t\t/// The current key is the last part.\n\t\tp.currentKey = key[len(key)-1]\n\n\t\t/// All the other parts (if any) are the context; need to set each part\n\t\t/// as implicit.\n\t\tcontext := key[:len(key)-1]\n\t\tfor i := range context {\n\t\t\tp.addImplicitContext(append(p.context, context[i:i+1]...))\n\t\t}\n\n\t\t/// Set value.\n\t\tvItem := p.next()\n\t\tval, typ := p.value(vItem, false)\n\t\tp.set(p.currentKey, val, typ, vItem.pos)\n\t\tp.ordered = append(p.ordered, p.context.add(p.currentKey))\n\n\t\t/// Remove the context we added (preserving any context from [tbl] lines).\n\t\tp.context = outerContext\n\t\tp.currentKey = \"\"\n\tdefault:\n\t\tp.bug(\"Unexpected type at top level: %s\", item.typ)\n\t}\n}\n\n// Gets a string for a key (or part of a key in a table name).\nfunc (p *parser) keyString(it item) string {\n\tswitch it.typ {\n\tcase itemText:\n\t\treturn it.val\n\tcase itemString, itemMultilineString,\n\t\titemRawString, itemRawMultilineString:\n\t\ts, _ := p.value(it, false)\n\t\treturn s.(string)\n\tdefault:\n\t\tp.bug(\"Unexpected key type: %s\", it.typ)\n\t}\n\tpanic(\"unreachable\")\n}\n\nvar datetimeRepl = strings.NewReplacer(\n\t\"z\", \"Z\",\n\t\"t\", \"T\",\n\t\" \", \"T\")\n\n// value translates an expected value from the lexer into a Go value wrapped\n// as an empty interface.\nfunc (p *parser) value(it item, parentIsArray bool) (interface{}, tomlType) {\n\tswitch it.typ {\n\tcase itemString:\n\t\treturn p.replaceEscapes(it, it.val), p.typeOfPrimitive(it)\n\tcase itemMultilineString:\n\t\treturn p.replaceEscapes(it, stripFirstNewline(p.stripEscapedNewlines(it.val))), p.typeOfPrimitive(it)\n\tcase itemRawString:\n\t\treturn it.val, p.typeOfPrimitive(it)\n\tcase itemRawMultilineString:\n\t\treturn stripFirstNewline(it.val), p.typeOfPrimitive(it)\n\tcase itemInteger:\n\t\treturn p.valueInteger(it)\n\tcase itemFloat:\n\t\treturn p.valueFloat(it)\n\tcase itemBool:\n\t\tswitch it.val {\n\t\tcase \"true\":\n\t\t\treturn true, p.typeOfPrimitive(it)\n\t\tcase \"false\":\n\t\t\treturn false, p.typeOfPrimitive(it)\n\t\tdefault:\n\t\t\tp.bug(\"Expected boolean value, but got '%s'.\", it.val)\n\t\t}\n\tcase itemDatetime:\n\t\treturn p.valueDatetime(it)\n\tcase itemArray:\n\t\treturn p.valueArray(it)\n\tcase itemInlineTableStart:\n\t\treturn p.valueInlineTable(it, parentIsArray)\n\tdefault:\n\t\tp.bug(\"Unexpected value type: %s\", it.typ)\n\t}\n\tpanic(\"unreachable\")\n}\n\nfunc (p *parser) valueInteger(it item) (interface{}, tomlType) {\n\tif !numUnderscoresOK(it.val) {\n\t\tp.panicItemf(it, \"Invalid integer %q: underscores must be surrounded by digits\", it.val)\n\t}\n\tif numHasLeadingZero(it.val) {\n\t\tp.panicItemf(it, \"Invalid integer %q: cannot have leading zeroes\", it.val)\n\t}\n\n\tnum, err := strconv.ParseInt(it.val, 0, 64)\n\tif err != nil {\n\t\t// Distinguish integer values. Normally, it'd be a bug if the lexer\n\t\t// provides an invalid integer, but it's possible that the number is\n\t\t// out of range of valid values (which the lexer cannot determine).\n\t\t// So mark the former as a bug but the latter as a legitimate user\n\t\t// error.\n\t\tif e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange {\n\t\t\tp.panicErr(it, errParseRange{i: it.val, size: \"int64\"})\n\t\t} else {\n\t\t\tp.bug(\"Expected integer value, but got '%s'.\", it.val)\n\t\t}\n\t}\n\treturn num, p.typeOfPrimitive(it)\n}\n\nfunc (p *parser) valueFloat(it item) (interface{}, tomlType) {\n\tparts := strings.FieldsFunc(it.val, func(r rune) bool {\n\t\tswitch r {\n\t\tcase '.', 'e', 'E':\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t})\n\tfor _, part := range parts {\n\t\tif !numUnderscoresOK(part) {\n\t\t\tp.panicItemf(it, \"Invalid float %q: underscores must be surrounded by digits\", it.val)\n\t\t}\n\t}\n\tif len(parts) > 0 && numHasLeadingZero(parts[0]) {\n\t\tp.panicItemf(it, \"Invalid float %q: cannot have leading zeroes\", it.val)\n\t}\n\tif !numPeriodsOK(it.val) {\n\t\t// As a special case, numbers like '123.' or '1.e2',\n\t\t// which are valid as far as Go/strconv are concerned,\n\t\t// must be rejected because TOML says that a fractional\n\t\t// part consists of '.' followed by 1+ digits.\n\t\tp.panicItemf(it, \"Invalid float %q: '.' must be followed by one or more digits\", it.val)\n\t}\n\tval := strings.Replace(it.val, \"_\", \"\", -1)\n\tif val == \"+nan\" || val == \"-nan\" { // Go doesn't support this, but TOML spec does.\n\t\tval = \"nan\"\n\t}\n\tnum, err := strconv.ParseFloat(val, 64)\n\tif err != nil {\n\t\tif e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange {\n\t\t\tp.panicErr(it, errParseRange{i: it.val, size: \"float64\"})\n\t\t} else {\n\t\t\tp.panicItemf(it, \"Invalid float value: %q\", it.val)\n\t\t}\n\t}\n\treturn num, p.typeOfPrimitive(it)\n}\n\nvar dtTypes = []struct {\n\tfmt  string\n\tzone *time.Location\n}{\n\t{time.RFC3339Nano, time.Local},\n\t{\"2006-01-02T15:04:05.999999999\", internal.LocalDatetime},\n\t{\"2006-01-02\", internal.LocalDate},\n\t{\"15:04:05.999999999\", internal.LocalTime},\n}\n\nfunc (p *parser) valueDatetime(it item) (interface{}, tomlType) {\n\tit.val = datetimeRepl.Replace(it.val)\n\tvar (\n\t\tt   time.Time\n\t\tok  bool\n\t\terr error\n\t)\n\tfor _, dt := range dtTypes {\n\t\tt, err = time.ParseInLocation(dt.fmt, it.val, dt.zone)\n\t\tif err == nil {\n\t\t\tok = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif !ok {\n\t\tp.panicItemf(it, \"Invalid TOML Datetime: %q.\", it.val)\n\t}\n\treturn t, p.typeOfPrimitive(it)\n}\n\nfunc (p *parser) valueArray(it item) (interface{}, tomlType) {\n\tp.setType(p.currentKey, tomlArray, it.pos)\n\n\tvar (\n\t\ttypes []tomlType\n\n\t\t// Initialize to a non-nil empty slice. This makes it consistent with\n\t\t// how S = [] decodes into a non-nil slice inside something like struct\n\t\t// { S []string }. See #338\n\t\tarray = []interface{}{}\n\t)\n\tfor it = p.next(); it.typ != itemArrayEnd; it = p.next() {\n\t\tif it.typ == itemCommentStart {\n\t\t\tp.expect(itemText)\n\t\t\tcontinue\n\t\t}\n\n\t\tval, typ := p.value(it, true)\n\t\tarray = append(array, val)\n\t\ttypes = append(types, typ)\n\n\t\t// XXX: types isn't used here, we need it to record the accurate type\n\t\t// information.\n\t\t//\n\t\t// Not entirely sure how to best store this; could use \"key[0]\",\n\t\t// \"key[1]\" notation, or maybe store it on the Array type?\n\t}\n\treturn array, tomlArray\n}\n\nfunc (p *parser) valueInlineTable(it item, parentIsArray bool) (interface{}, tomlType) {\n\tvar (\n\t\thash         = make(map[string]interface{})\n\t\touterContext = p.context\n\t\touterKey     = p.currentKey\n\t)\n\n\tp.context = append(p.context, p.currentKey)\n\tprevContext := p.context\n\tp.currentKey = \"\"\n\n\tp.addImplicit(p.context)\n\tp.addContext(p.context, parentIsArray)\n\n\t/// Loop over all table key/value pairs.\n\tfor it := p.next(); it.typ != itemInlineTableEnd; it = p.next() {\n\t\tif it.typ == itemCommentStart {\n\t\t\tp.expect(itemText)\n\t\t\tcontinue\n\t\t}\n\n\t\t/// Read all key parts.\n\t\tk := p.nextPos()\n\t\tvar key Key\n\t\tfor ; k.typ != itemKeyEnd && k.typ != itemEOF; k = p.next() {\n\t\t\tkey = append(key, p.keyString(k))\n\t\t}\n\t\tp.assertEqual(itemKeyEnd, k.typ)\n\n\t\t/// The current key is the last part.\n\t\tp.currentKey = key[len(key)-1]\n\n\t\t/// All the other parts (if any) are the context; need to set each part\n\t\t/// as implicit.\n\t\tcontext := key[:len(key)-1]\n\t\tfor i := range context {\n\t\t\tp.addImplicitContext(append(p.context, context[i:i+1]...))\n\t\t}\n\n\t\t/// Set the value.\n\t\tval, typ := p.value(p.next(), false)\n\t\tp.set(p.currentKey, val, typ, it.pos)\n\t\tp.ordered = append(p.ordered, p.context.add(p.currentKey))\n\t\thash[p.currentKey] = val\n\n\t\t/// Restore context.\n\t\tp.context = prevContext\n\t}\n\tp.context = outerContext\n\tp.currentKey = outerKey\n\treturn hash, tomlHash\n}\n\n// numHasLeadingZero checks if this number has leading zeroes, allowing for '0',\n// +/- signs, and base prefixes.\nfunc numHasLeadingZero(s string) bool {\n\tif len(s) > 1 && s[0] == '0' && !(s[1] == 'b' || s[1] == 'o' || s[1] == 'x') { // Allow 0b, 0o, 0x\n\t\treturn true\n\t}\n\tif len(s) > 2 && (s[0] == '-' || s[0] == '+') && s[1] == '0' {\n\t\treturn true\n\t}\n\treturn false\n}\n\n// numUnderscoresOK checks whether each underscore in s is surrounded by\n// characters that are not underscores.\nfunc numUnderscoresOK(s string) bool {\n\tswitch s {\n\tcase \"nan\", \"+nan\", \"-nan\", \"inf\", \"-inf\", \"+inf\":\n\t\treturn true\n\t}\n\taccept := false\n\tfor _, r := range s {\n\t\tif r == '_' {\n\t\t\tif !accept {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\t// isHexadecimal is a superset of all the permissable characters\n\t\t// surrounding an underscore.\n\t\taccept = isHexadecimal(r)\n\t}\n\treturn accept\n}\n\n// numPeriodsOK checks whether every period in s is followed by a digit.\nfunc numPeriodsOK(s string) bool {\n\tperiod := false\n\tfor _, r := range s {\n\t\tif period && !isDigit(r) {\n\t\t\treturn false\n\t\t}\n\t\tperiod = r == '.'\n\t}\n\treturn !period\n}\n\n// Set the current context of the parser, where the context is either a hash or\n// an array of hashes, depending on the value of the `array` parameter.\n//\n// Establishing the context also makes sure that the key isn't a duplicate, and\n// will create implicit hashes automatically.\nfunc (p *parser) addContext(key Key, array bool) {\n\tvar ok bool\n\n\t// Always start at the top level and drill down for our context.\n\thashContext := p.mapping\n\tkeyContext := make(Key, 0)\n\n\t// We only need implicit hashes for key[0:-1]\n\tfor _, k := range key[0 : len(key)-1] {\n\t\t_, ok = hashContext[k]\n\t\tkeyContext = append(keyContext, k)\n\n\t\t// No key? Make an implicit hash and move on.\n\t\tif !ok {\n\t\t\tp.addImplicit(keyContext)\n\t\t\thashContext[k] = make(map[string]interface{})\n\t\t}\n\n\t\t// If the hash context is actually an array of tables, then set\n\t\t// the hash context to the last element in that array.\n\t\t//\n\t\t// Otherwise, it better be a table, since this MUST be a key group (by\n\t\t// virtue of it not being the last element in a key).\n\t\tswitch t := hashContext[k].(type) {\n\t\tcase []map[string]interface{}:\n\t\t\thashContext = t[len(t)-1]\n\t\tcase map[string]interface{}:\n\t\t\thashContext = t\n\t\tdefault:\n\t\t\tp.panicf(\"Key '%s' was already created as a hash.\", keyContext)\n\t\t}\n\t}\n\n\tp.context = keyContext\n\tif array {\n\t\t// If this is the first element for this array, then allocate a new\n\t\t// list of tables for it.\n\t\tk := key[len(key)-1]\n\t\tif _, ok := hashContext[k]; !ok {\n\t\t\thashContext[k] = make([]map[string]interface{}, 0, 4)\n\t\t}\n\n\t\t// Add a new table. But make sure the key hasn't already been used\n\t\t// for something else.\n\t\tif hash, ok := hashContext[k].([]map[string]interface{}); ok {\n\t\t\thashContext[k] = append(hash, make(map[string]interface{}))\n\t\t} else {\n\t\t\tp.panicf(\"Key '%s' was already created and cannot be used as an array.\", key)\n\t\t}\n\t} else {\n\t\tp.setValue(key[len(key)-1], make(map[string]interface{}))\n\t}\n\tp.context = append(p.context, key[len(key)-1])\n}\n\n// set calls setValue and setType.\nfunc (p *parser) set(key string, val interface{}, typ tomlType, pos Position) {\n\tp.setValue(key, val)\n\tp.setType(key, typ, pos)\n\n}\n\n// setValue sets the given key to the given value in the current context.\n// It will make sure that the key hasn't already been defined, account for\n// implicit key groups.\nfunc (p *parser) setValue(key string, value interface{}) {\n\tvar (\n\t\ttmpHash    interface{}\n\t\tok         bool\n\t\thash       = p.mapping\n\t\tkeyContext Key\n\t)\n\tfor _, k := range p.context {\n\t\tkeyContext = append(keyContext, k)\n\t\tif tmpHash, ok = hash[k]; !ok {\n\t\t\tp.bug(\"Context for key '%s' has not been established.\", keyContext)\n\t\t}\n\t\tswitch t := tmpHash.(type) {\n\t\tcase []map[string]interface{}:\n\t\t\t// The context is a table of hashes. Pick the most recent table\n\t\t\t// defined as the current hash.\n\t\t\thash = t[len(t)-1]\n\t\tcase map[string]interface{}:\n\t\t\thash = t\n\t\tdefault:\n\t\t\tp.panicf(\"Key '%s' has already been defined.\", keyContext)\n\t\t}\n\t}\n\tkeyContext = append(keyContext, key)\n\n\tif _, ok := hash[key]; ok {\n\t\t// Normally redefining keys isn't allowed, but the key could have been\n\t\t// defined implicitly and it's allowed to be redefined concretely. (See\n\t\t// the `valid/implicit-and-explicit-after.toml` in toml-test)\n\t\t//\n\t\t// But we have to make sure to stop marking it as an implicit. (So that\n\t\t// another redefinition provokes an error.)\n\t\t//\n\t\t// Note that since it has already been defined (as a hash), we don't\n\t\t// want to overwrite it. So our business is done.\n\t\tif p.isArray(keyContext) {\n\t\t\tp.removeImplicit(keyContext)\n\t\t\thash[key] = value\n\t\t\treturn\n\t\t}\n\t\tif p.isImplicit(keyContext) {\n\t\t\tp.removeImplicit(keyContext)\n\t\t\treturn\n\t\t}\n\n\t\t// Otherwise, we have a concrete key trying to override a previous\n\t\t// key, which is *always* wrong.\n\t\tp.panicf(\"Key '%s' has already been defined.\", keyContext)\n\t}\n\n\thash[key] = value\n}\n\n// setType sets the type of a particular value at a given key. It should be\n// called immediately AFTER setValue.\n//\n// Note that if `key` is empty, then the type given will be applied to the\n// current context (which is either a table or an array of tables).\nfunc (p *parser) setType(key string, typ tomlType, pos Position) {\n\tkeyContext := make(Key, 0, len(p.context)+1)\n\tkeyContext = append(keyContext, p.context...)\n\tif len(key) > 0 { // allow type setting for hashes\n\t\tkeyContext = append(keyContext, key)\n\t}\n\t// Special case to make empty keys (\"\" = 1) work.\n\t// Without it it will set \"\" rather than `\"\"`.\n\t// TODO: why is this needed? And why is this only needed here?\n\tif len(keyContext) == 0 {\n\t\tkeyContext = Key{\"\"}\n\t}\n\tp.keyInfo[keyContext.String()] = keyInfo{tomlType: typ, pos: pos}\n}\n\n// Implicit keys need to be created when tables are implied in \"a.b.c.d = 1\" and\n// \"[a.b.c]\" (the \"a\", \"b\", and \"c\" hashes are never created explicitly).\nfunc (p *parser) addImplicit(key Key)     { p.implicits[key.String()] = struct{}{} }\nfunc (p *parser) removeImplicit(key Key)  { delete(p.implicits, key.String()) }\nfunc (p *parser) isImplicit(key Key) bool { _, ok := p.implicits[key.String()]; return ok }\nfunc (p *parser) isArray(key Key) bool    { return p.keyInfo[key.String()].tomlType == tomlArray }\nfunc (p *parser) addImplicitContext(key Key) {\n\tp.addImplicit(key)\n\tp.addContext(key, false)\n}\n\n// current returns the full key name of the current context.\nfunc (p *parser) current() string {\n\tif len(p.currentKey) == 0 {\n\t\treturn p.context.String()\n\t}\n\tif len(p.context) == 0 {\n\t\treturn p.currentKey\n\t}\n\treturn fmt.Sprintf(\"%s.%s\", p.context, p.currentKey)\n}\n\nfunc stripFirstNewline(s string) string {\n\tif len(s) > 0 && s[0] == '\\n' {\n\t\treturn s[1:]\n\t}\n\tif len(s) > 1 && s[0] == '\\r' && s[1] == '\\n' {\n\t\treturn s[2:]\n\t}\n\treturn s\n}\n\n// Remove newlines inside triple-quoted strings if a line ends with \"\\\".\nfunc (p *parser) stripEscapedNewlines(s string) string {\n\tsplit := strings.Split(s, \"\\n\")\n\tif len(split) < 1 {\n\t\treturn s\n\t}\n\n\tescNL := false // Keep track of the last non-blank line was escaped.\n\tfor i, line := range split {\n\t\tline = strings.TrimRight(line, \" \\t\\r\")\n\n\t\tif len(line) == 0 || line[len(line)-1] != '\\\\' {\n\t\t\tsplit[i] = strings.TrimRight(split[i], \"\\r\")\n\t\t\tif !escNL && i != len(split)-1 {\n\t\t\t\tsplit[i] += \"\\n\"\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tescBS := true\n\t\tfor j := len(line) - 1; j >= 0 && line[j] == '\\\\'; j-- {\n\t\t\tescBS = !escBS\n\t\t}\n\t\tif escNL {\n\t\t\tline = strings.TrimLeft(line, \" \\t\\r\")\n\t\t}\n\t\tescNL = !escBS\n\n\t\tif escBS {\n\t\t\tsplit[i] += \"\\n\"\n\t\t\tcontinue\n\t\t}\n\n\t\tif i == len(split)-1 {\n\t\t\tp.panicf(\"invalid escape: '\\\\ '\")\n\t\t}\n\n\t\tsplit[i] = line[:len(line)-1] // Remove \\\n\t\tif len(split)-1 > i {\n\t\t\tsplit[i+1] = strings.TrimLeft(split[i+1], \" \\t\\r\")\n\t\t}\n\t}\n\treturn strings.Join(split, \"\")\n}\n\nfunc (p *parser) replaceEscapes(it item, str string) string {\n\treplaced := make([]rune, 0, len(str))\n\ts := []byte(str)\n\tr := 0\n\tfor r < len(s) {\n\t\tif s[r] != '\\\\' {\n\t\t\tc, size := utf8.DecodeRune(s[r:])\n\t\t\tr += size\n\t\t\treplaced = append(replaced, c)\n\t\t\tcontinue\n\t\t}\n\t\tr += 1\n\t\tif r >= len(s) {\n\t\t\tp.bug(\"Escape sequence at end of string.\")\n\t\t\treturn \"\"\n\t\t}\n\t\tswitch s[r] {\n\t\tdefault:\n\t\t\tp.bug(\"Expected valid escape code after \\\\, but got %q.\", s[r])\n\t\tcase ' ', '\\t':\n\t\t\tp.panicItemf(it, \"invalid escape: '\\\\%c'\", s[r])\n\t\tcase 'b':\n\t\t\treplaced = append(replaced, rune(0x0008))\n\t\t\tr += 1\n\t\tcase 't':\n\t\t\treplaced = append(replaced, rune(0x0009))\n\t\t\tr += 1\n\t\tcase 'n':\n\t\t\treplaced = append(replaced, rune(0x000A))\n\t\t\tr += 1\n\t\tcase 'f':\n\t\t\treplaced = append(replaced, rune(0x000C))\n\t\t\tr += 1\n\t\tcase 'r':\n\t\t\treplaced = append(replaced, rune(0x000D))\n\t\t\tr += 1\n\t\tcase '\"':\n\t\t\treplaced = append(replaced, rune(0x0022))\n\t\t\tr += 1\n\t\tcase '\\\\':\n\t\t\treplaced = append(replaced, rune(0x005C))\n\t\t\tr += 1\n\t\tcase 'u':\n\t\t\t// At this point, we know we have a Unicode escape of the form\n\t\t\t// `uXXXX` at [r, r+5). (Because the lexer guarantees this\n\t\t\t// for us.)\n\t\t\tescaped := p.asciiEscapeToUnicode(it, s[r+1:r+5])\n\t\t\treplaced = append(replaced, escaped)\n\t\t\tr += 5\n\t\tcase 'U':\n\t\t\t// At this point, we know we have a Unicode escape of the form\n\t\t\t// `uXXXX` at [r, r+9). (Because the lexer guarantees this\n\t\t\t// for us.)\n\t\t\tescaped := p.asciiEscapeToUnicode(it, s[r+1:r+9])\n\t\t\treplaced = append(replaced, escaped)\n\t\t\tr += 9\n\t\t}\n\t}\n\treturn string(replaced)\n}\n\nfunc (p *parser) asciiEscapeToUnicode(it item, bs []byte) rune {\n\ts := string(bs)\n\thex, err := strconv.ParseUint(strings.ToLower(s), 16, 32)\n\tif err != nil {\n\t\tp.bug(\"Could not parse '%s' as a hexadecimal number, but the lexer claims it's OK: %s\", s, err)\n\t}\n\tif !utf8.ValidRune(rune(hex)) {\n\t\tp.panicItemf(it, \"Escaped character '\\\\u%s' is not valid UTF-8.\", s)\n\t}\n\treturn rune(hex)\n}\n"
  },
  {
    "path": "vendor/github.com/BurntSushi/toml/type_fields.go",
    "content": "package toml\n\n// Struct field handling is adapted from code in encoding/json:\n//\n// Copyright 2010 The Go Authors.  All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the Go distribution.\n\nimport (\n\t\"reflect\"\n\t\"sort\"\n\t\"sync\"\n)\n\n// A field represents a single field found in a struct.\ntype field struct {\n\tname  string       // the name of the field (`toml` tag included)\n\ttag   bool         // whether field has a `toml` tag\n\tindex []int        // represents the depth of an anonymous field\n\ttyp   reflect.Type // the type of the field\n}\n\n// byName sorts field by name, breaking ties with depth,\n// then breaking ties with \"name came from toml tag\", then\n// breaking ties with index sequence.\ntype byName []field\n\nfunc (x byName) Len() int { return len(x) }\n\nfunc (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }\n\nfunc (x byName) Less(i, j int) bool {\n\tif x[i].name != x[j].name {\n\t\treturn x[i].name < x[j].name\n\t}\n\tif len(x[i].index) != len(x[j].index) {\n\t\treturn len(x[i].index) < len(x[j].index)\n\t}\n\tif x[i].tag != x[j].tag {\n\t\treturn x[i].tag\n\t}\n\treturn byIndex(x).Less(i, j)\n}\n\n// byIndex sorts field by index sequence.\ntype byIndex []field\n\nfunc (x byIndex) Len() int { return len(x) }\n\nfunc (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }\n\nfunc (x byIndex) Less(i, j int) bool {\n\tfor k, xik := range x[i].index {\n\t\tif k >= len(x[j].index) {\n\t\t\treturn false\n\t\t}\n\t\tif xik != x[j].index[k] {\n\t\t\treturn xik < x[j].index[k]\n\t\t}\n\t}\n\treturn len(x[i].index) < len(x[j].index)\n}\n\n// typeFields returns a list of fields that TOML should recognize for the given\n// type. The algorithm is breadth-first search over the set of structs to\n// include - the top struct and then any reachable anonymous structs.\nfunc typeFields(t reflect.Type) []field {\n\t// Anonymous fields to explore at the current level and the next.\n\tcurrent := []field{}\n\tnext := []field{{typ: t}}\n\n\t// Count of queued names for current level and the next.\n\tvar count map[reflect.Type]int\n\tvar nextCount map[reflect.Type]int\n\n\t// Types already visited at an earlier level.\n\tvisited := map[reflect.Type]bool{}\n\n\t// Fields found.\n\tvar fields []field\n\n\tfor len(next) > 0 {\n\t\tcurrent, next = next, current[:0]\n\t\tcount, nextCount = nextCount, map[reflect.Type]int{}\n\n\t\tfor _, f := range current {\n\t\t\tif visited[f.typ] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tvisited[f.typ] = true\n\n\t\t\t// Scan f.typ for fields to include.\n\t\t\tfor i := 0; i < f.typ.NumField(); i++ {\n\t\t\t\tsf := f.typ.Field(i)\n\t\t\t\tif sf.PkgPath != \"\" && !sf.Anonymous { // unexported\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\topts := getOptions(sf.Tag)\n\t\t\t\tif opts.skip {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tindex := make([]int, len(f.index)+1)\n\t\t\t\tcopy(index, f.index)\n\t\t\t\tindex[len(f.index)] = i\n\n\t\t\t\tft := sf.Type\n\t\t\t\tif ft.Name() == \"\" && ft.Kind() == reflect.Ptr {\n\t\t\t\t\t// Follow pointer.\n\t\t\t\t\tft = ft.Elem()\n\t\t\t\t}\n\n\t\t\t\t// Record found field and index sequence.\n\t\t\t\tif opts.name != \"\" || !sf.Anonymous || ft.Kind() != reflect.Struct {\n\t\t\t\t\ttagged := opts.name != \"\"\n\t\t\t\t\tname := opts.name\n\t\t\t\t\tif name == \"\" {\n\t\t\t\t\t\tname = sf.Name\n\t\t\t\t\t}\n\t\t\t\t\tfields = append(fields, field{name, tagged, index, ft})\n\t\t\t\t\tif count[f.typ] > 1 {\n\t\t\t\t\t\t// If there were multiple instances, add a second,\n\t\t\t\t\t\t// so that the annihilation code will see a duplicate.\n\t\t\t\t\t\t// It only cares about the distinction between 1 or 2,\n\t\t\t\t\t\t// so don't bother generating any more copies.\n\t\t\t\t\t\tfields = append(fields, fields[len(fields)-1])\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Record new anonymous struct to explore in next round.\n\t\t\t\tnextCount[ft]++\n\t\t\t\tif nextCount[ft] == 1 {\n\t\t\t\t\tf := field{name: ft.Name(), index: index, typ: ft}\n\t\t\t\t\tnext = append(next, f)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tsort.Sort(byName(fields))\n\n\t// Delete all fields that are hidden by the Go rules for embedded fields,\n\t// except that fields with TOML tags are promoted.\n\n\t// The fields are sorted in primary order of name, secondary order\n\t// of field index length. Loop over names; for each name, delete\n\t// hidden fields by choosing the one dominant field that survives.\n\tout := fields[:0]\n\tfor advance, i := 0, 0; i < len(fields); i += advance {\n\t\t// One iteration per name.\n\t\t// Find the sequence of fields with the name of this first field.\n\t\tfi := fields[i]\n\t\tname := fi.name\n\t\tfor advance = 1; i+advance < len(fields); advance++ {\n\t\t\tfj := fields[i+advance]\n\t\t\tif fj.name != name {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif advance == 1 { // Only one field with this name\n\t\t\tout = append(out, fi)\n\t\t\tcontinue\n\t\t}\n\t\tdominant, ok := dominantField(fields[i : i+advance])\n\t\tif ok {\n\t\t\tout = append(out, dominant)\n\t\t}\n\t}\n\n\tfields = out\n\tsort.Sort(byIndex(fields))\n\n\treturn fields\n}\n\n// dominantField looks through the fields, all of which are known to\n// have the same name, to find the single field that dominates the\n// others using Go's embedding rules, modified by the presence of\n// TOML tags. If there are multiple top-level fields, the boolean\n// will be false: This condition is an error in Go and we skip all\n// the fields.\nfunc dominantField(fields []field) (field, bool) {\n\t// The fields are sorted in increasing index-length order. The winner\n\t// must therefore be one with the shortest index length. Drop all\n\t// longer entries, which is easy: just truncate the slice.\n\tlength := len(fields[0].index)\n\ttagged := -1 // Index of first tagged field.\n\tfor i, f := range fields {\n\t\tif len(f.index) > length {\n\t\t\tfields = fields[:i]\n\t\t\tbreak\n\t\t}\n\t\tif f.tag {\n\t\t\tif tagged >= 0 {\n\t\t\t\t// Multiple tagged fields at the same level: conflict.\n\t\t\t\t// Return no field.\n\t\t\t\treturn field{}, false\n\t\t\t}\n\t\t\ttagged = i\n\t\t}\n\t}\n\tif tagged >= 0 {\n\t\treturn fields[tagged], true\n\t}\n\t// All remaining fields have the same length. If there's more than one,\n\t// we have a conflict (two fields named \"X\" at the same level) and we\n\t// return no field.\n\tif len(fields) > 1 {\n\t\treturn field{}, false\n\t}\n\treturn fields[0], true\n}\n\nvar fieldCache struct {\n\tsync.RWMutex\n\tm map[reflect.Type][]field\n}\n\n// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.\nfunc cachedTypeFields(t reflect.Type) []field {\n\tfieldCache.RLock()\n\tf := fieldCache.m[t]\n\tfieldCache.RUnlock()\n\tif f != nil {\n\t\treturn f\n\t}\n\n\t// Compute fields without lock.\n\t// Might duplicate effort but won't hold other computations back.\n\tf = typeFields(t)\n\tif f == nil {\n\t\tf = []field{}\n\t}\n\n\tfieldCache.Lock()\n\tif fieldCache.m == nil {\n\t\tfieldCache.m = map[reflect.Type][]field{}\n\t}\n\tfieldCache.m[t] = f\n\tfieldCache.Unlock()\n\treturn f\n}\n"
  },
  {
    "path": "vendor/github.com/BurntSushi/toml/type_toml.go",
    "content": "package toml\n\n// tomlType represents any Go type that corresponds to a TOML type.\n// While the first draft of the TOML spec has a simplistic type system that\n// probably doesn't need this level of sophistication, we seem to be militating\n// toward adding real composite types.\ntype tomlType interface {\n\ttypeString() string\n}\n\n// typeEqual accepts any two types and returns true if they are equal.\nfunc typeEqual(t1, t2 tomlType) bool {\n\tif t1 == nil || t2 == nil {\n\t\treturn false\n\t}\n\treturn t1.typeString() == t2.typeString()\n}\n\nfunc typeIsTable(t tomlType) bool {\n\treturn typeEqual(t, tomlHash) || typeEqual(t, tomlArrayHash)\n}\n\ntype tomlBaseType string\n\nfunc (btype tomlBaseType) typeString() string {\n\treturn string(btype)\n}\n\nfunc (btype tomlBaseType) String() string {\n\treturn btype.typeString()\n}\n\nvar (\n\ttomlInteger   tomlBaseType = \"Integer\"\n\ttomlFloat     tomlBaseType = \"Float\"\n\ttomlDatetime  tomlBaseType = \"Datetime\"\n\ttomlString    tomlBaseType = \"String\"\n\ttomlBool      tomlBaseType = \"Bool\"\n\ttomlArray     tomlBaseType = \"Array\"\n\ttomlHash      tomlBaseType = \"Hash\"\n\ttomlArrayHash tomlBaseType = \"ArrayHash\"\n)\n\n// typeOfPrimitive returns a tomlType of any primitive value in TOML.\n// Primitive values are: Integer, Float, Datetime, String and Bool.\n//\n// Passing a lexer item other than the following will cause a BUG message\n// to occur: itemString, itemBool, itemInteger, itemFloat, itemDatetime.\nfunc (p *parser) typeOfPrimitive(lexItem item) tomlType {\n\tswitch lexItem.typ {\n\tcase itemInteger:\n\t\treturn tomlInteger\n\tcase itemFloat:\n\t\treturn tomlFloat\n\tcase itemDatetime:\n\t\treturn tomlDatetime\n\tcase itemString:\n\t\treturn tomlString\n\tcase itemMultilineString:\n\t\treturn tomlString\n\tcase itemRawString:\n\t\treturn tomlString\n\tcase itemRawMultilineString:\n\t\treturn tomlString\n\tcase itemBool:\n\t\treturn tomlBool\n\t}\n\tp.bug(\"Cannot infer primitive type of lex item '%s'.\", lexItem)\n\tpanic(\"unreachable\")\n}\n"
  },
  {
    "path": "vendor/github.com/beorn7/perks/LICENSE",
    "content": "Copyright (C) 2013 Blake Mizerany\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/beorn7/perks/quantile/exampledata.txt",
    "content": "8\n5\n26\n12\n5\n235\n13\n6\n28\n30\n3\n3\n3\n3\n5\n2\n33\n7\n2\n4\n7\n12\n14\n5\n8\n3\n10\n4\n5\n3\n6\n6\n209\n20\n3\n10\n14\n3\n4\n6\n8\n5\n11\n7\n3\n2\n3\n3\n212\n5\n222\n4\n10\n10\n5\n6\n3\n8\n3\n10\n254\n220\n2\n3\n5\n24\n5\n4\n222\n7\n3\n3\n223\n8\n15\n12\n14\n14\n3\n2\n2\n3\n13\n3\n11\n4\n4\n6\n5\n7\n13\n5\n3\n5\n2\n5\n3\n5\n2\n7\n15\n17\n14\n3\n6\n6\n3\n17\n5\n4\n7\n6\n4\n4\n8\n6\n8\n3\n9\n3\n6\n3\n4\n5\n3\n3\n660\n4\n6\n10\n3\n6\n3\n2\n5\n13\n2\n4\n4\n10\n4\n8\n4\n3\n7\n9\n9\n3\n10\n37\n3\n13\n4\n12\n3\n6\n10\n8\n5\n21\n2\n3\n8\n3\n2\n3\n3\n4\n12\n2\n4\n8\n8\n4\n3\n2\n20\n1\n6\n32\n2\n11\n6\n18\n3\n8\n11\n3\n212\n3\n4\n2\n6\n7\n12\n11\n3\n2\n16\n10\n6\n4\n6\n3\n2\n7\n3\n2\n2\n2\n2\n5\n6\n4\n3\n10\n3\n4\n6\n5\n3\n4\n4\n5\n6\n4\n3\n4\n4\n5\n7\n5\n5\n3\n2\n7\n2\n4\n12\n4\n5\n6\n2\n4\n4\n8\n4\n15\n13\n7\n16\n5\n3\n23\n5\n5\n7\n3\n2\n9\n8\n7\n5\n8\n11\n4\n10\n76\n4\n47\n4\n3\n2\n7\n4\n2\n3\n37\n10\n4\n2\n20\n5\n4\n4\n10\n10\n4\n3\n7\n23\n240\n7\n13\n5\n5\n3\n3\n2\n5\n4\n2\n8\n7\n19\n2\n23\n8\n7\n2\n5\n3\n8\n3\n8\n13\n5\n5\n5\n2\n3\n23\n4\n9\n8\n4\n3\n3\n5\n220\n2\n3\n4\n6\n14\n3\n53\n6\n2\n5\n18\n6\n3\n219\n6\n5\n2\n5\n3\n6\n5\n15\n4\n3\n17\n3\n2\n4\n7\n2\n3\n3\n4\n4\n3\n2\n664\n6\n3\n23\n5\n5\n16\n5\n8\n2\n4\n2\n24\n12\n3\n2\n3\n5\n8\n3\n5\n4\n3\n14\n3\n5\n8\n2\n3\n7\n9\n4\n2\n3\n6\n8\n4\n3\n4\n6\n5\n3\n3\n6\n3\n19\n4\n4\n6\n3\n6\n3\n5\n22\n5\n4\n4\n3\n8\n11\n4\n9\n7\n6\n13\n4\n4\n4\n6\n17\n9\n3\n3\n3\n4\n3\n221\n5\n11\n3\n4\n2\n12\n6\n3\n5\n7\n5\n7\n4\n9\n7\n14\n37\n19\n217\n16\n3\n5\n2\n2\n7\n19\n7\n6\n7\n4\n24\n5\n11\n4\n7\n7\n9\n13\n3\n4\n3\n6\n28\n4\n4\n5\n5\n2\n5\n6\n4\n4\n6\n10\n5\n4\n3\n2\n3\n3\n6\n5\n5\n4\n3\n2\n3\n7\n4\n6\n18\n16\n8\n16\n4\n5\n8\n6\n9\n13\n1545\n6\n215\n6\n5\n6\n3\n45\n31\n5\n2\n2\n4\n3\n3\n2\n5\n4\n3\n5\n7\n7\n4\n5\n8\n5\n4\n749\n2\n31\n9\n11\n2\n11\n5\n4\n4\n7\n9\n11\n4\n5\n4\n7\n3\n4\n6\n2\n15\n3\n4\n3\n4\n3\n5\n2\n13\n5\n5\n3\n3\n23\n4\n4\n5\n7\n4\n13\n2\n4\n3\n4\n2\n6\n2\n7\n3\n5\n5\n3\n29\n5\n4\n4\n3\n10\n2\n3\n79\n16\n6\n6\n7\n7\n3\n5\n5\n7\n4\n3\n7\n9\n5\n6\n5\n9\n6\n3\n6\n4\n17\n2\n10\n9\n3\n6\n2\n3\n21\n22\n5\n11\n4\n2\n17\n2\n224\n2\n14\n3\n4\n4\n2\n4\n4\n4\n4\n5\n3\n4\n4\n10\n2\n6\n3\n3\n5\n7\n2\n7\n5\n6\n3\n218\n2\n2\n5\n2\n6\n3\n5\n222\n14\n6\n33\n3\n2\n5\n3\n3\n3\n9\n5\n3\n3\n2\n7\n4\n3\n4\n3\n5\n6\n5\n26\n4\n13\n9\n7\n3\n221\n3\n3\n4\n4\n4\n4\n2\n18\n5\n3\n7\n9\n6\n8\n3\n10\n3\n11\n9\n5\n4\n17\n5\n5\n6\n6\n3\n2\n4\n12\n17\n6\n7\n218\n4\n2\n4\n10\n3\n5\n15\n3\n9\n4\n3\n3\n6\n29\n3\n3\n4\n5\n5\n3\n8\n5\n6\n6\n7\n5\n3\n5\n3\n29\n2\n31\n5\n15\n24\n16\n5\n207\n4\n3\n3\n2\n15\n4\n4\n13\n5\n5\n4\n6\n10\n2\n7\n8\n4\n6\n20\n5\n3\n4\n3\n12\n12\n5\n17\n7\n3\n3\n3\n6\n10\n3\n5\n25\n80\n4\n9\n3\n2\n11\n3\n3\n2\n3\n8\n7\n5\n5\n19\n5\n3\n3\n12\n11\n2\n6\n5\n5\n5\n3\n3\n3\n4\n209\n14\n3\n2\n5\n19\n4\n4\n3\n4\n14\n5\n6\n4\n13\n9\n7\n4\n7\n10\n2\n9\n5\n7\n2\n8\n4\n6\n5\n5\n222\n8\n7\n12\n5\n216\n3\n4\n4\n6\n3\n14\n8\n7\n13\n4\n3\n3\n3\n3\n17\n5\n4\n3\n33\n6\n6\n33\n7\n5\n3\n8\n7\n5\n2\n9\n4\n2\n233\n24\n7\n4\n8\n10\n3\n4\n15\n2\n16\n3\n3\n13\n12\n7\n5\n4\n207\n4\n2\n4\n27\n15\n2\n5\n2\n25\n6\n5\n5\n6\n13\n6\n18\n6\n4\n12\n225\n10\n7\n5\n2\n2\n11\n4\n14\n21\n8\n10\n3\n5\n4\n232\n2\n5\n5\n3\n7\n17\n11\n6\n6\n23\n4\n6\n3\n5\n4\n2\n17\n3\n6\n5\n8\n3\n2\n2\n14\n9\n4\n4\n2\n5\n5\n3\n7\n6\n12\n6\n10\n3\n6\n2\n2\n19\n5\n4\n4\n9\n2\n4\n13\n3\n5\n6\n3\n6\n5\n4\n9\n6\n3\n5\n7\n3\n6\n6\n4\n3\n10\n6\n3\n221\n3\n5\n3\n6\n4\n8\n5\n3\n6\n4\n4\n2\n54\n5\n6\n11\n3\n3\n4\n4\n4\n3\n7\n3\n11\n11\n7\n10\n6\n13\n223\n213\n15\n231\n7\n3\n7\n228\n2\n3\n4\n4\n5\n6\n7\n4\n13\n3\n4\n5\n3\n6\n4\n6\n7\n2\n4\n3\n4\n3\n3\n6\n3\n7\n3\n5\n18\n5\n6\n8\n10\n3\n3\n3\n2\n4\n2\n4\n4\n5\n6\n6\n4\n10\n13\n3\n12\n5\n12\n16\n8\n4\n19\n11\n2\n4\n5\n6\n8\n5\n6\n4\n18\n10\n4\n2\n216\n6\n6\n6\n2\n4\n12\n8\n3\n11\n5\n6\n14\n5\n3\n13\n4\n5\n4\n5\n3\n28\n6\n3\n7\n219\n3\n9\n7\n3\n10\n6\n3\n4\n19\n5\n7\n11\n6\n15\n19\n4\n13\n11\n3\n7\n5\n10\n2\n8\n11\n2\n6\n4\n6\n24\n6\n3\n3\n3\n3\n6\n18\n4\n11\n4\n2\n5\n10\n8\n3\n9\n5\n3\n4\n5\n6\n2\n5\n7\n4\n4\n14\n6\n4\n4\n5\n5\n7\n2\n4\n3\n7\n3\n3\n6\n4\n5\n4\n4\n4\n3\n3\n3\n3\n8\n14\n2\n3\n5\n3\n2\n4\n5\n3\n7\n3\n3\n18\n3\n4\n4\n5\n7\n3\n3\n3\n13\n5\n4\n8\n211\n5\n5\n3\n5\n2\n5\n4\n2\n655\n6\n3\n5\n11\n2\n5\n3\n12\n9\n15\n11\n5\n12\n217\n2\n6\n17\n3\n3\n207\n5\n5\n4\n5\n9\n3\n2\n8\n5\n4\n3\n2\n5\n12\n4\n14\n5\n4\n2\n13\n5\n8\n4\n225\n4\n3\n4\n5\n4\n3\n3\n6\n23\n9\n2\n6\n7\n233\n4\n4\n6\n18\n3\n4\n6\n3\n4\n4\n2\n3\n7\n4\n13\n227\n4\n3\n5\n4\n2\n12\n9\n17\n3\n7\n14\n6\n4\n5\n21\n4\n8\n9\n2\n9\n25\n16\n3\n6\n4\n7\n8\n5\n2\n3\n5\n4\n3\n3\n5\n3\n3\n3\n2\n3\n19\n2\n4\n3\n4\n2\n3\n4\n4\n2\n4\n3\n3\n3\n2\n6\n3\n17\n5\n6\n4\n3\n13\n5\n3\n3\n3\n4\n9\n4\n2\n14\n12\n4\n5\n24\n4\n3\n37\n12\n11\n21\n3\n4\n3\n13\n4\n2\n3\n15\n4\n11\n4\n4\n3\n8\n3\n4\n4\n12\n8\n5\n3\n3\n4\n2\n220\n3\n5\n223\n3\n3\n3\n10\n3\n15\n4\n241\n9\n7\n3\n6\n6\n23\n4\n13\n7\n3\n4\n7\n4\n9\n3\n3\n4\n10\n5\n5\n1\n5\n24\n2\n4\n5\n5\n6\n14\n3\n8\n2\n3\n5\n13\n13\n3\n5\n2\n3\n15\n3\n4\n2\n10\n4\n4\n4\n5\n5\n3\n5\n3\n4\n7\n4\n27\n3\n6\n4\n15\n3\n5\n6\n6\n5\n4\n8\n3\n9\n2\n6\n3\n4\n3\n7\n4\n18\n3\n11\n3\n3\n8\n9\n7\n24\n3\n219\n7\n10\n4\n5\n9\n12\n2\n5\n4\n4\n4\n3\n3\n19\n5\n8\n16\n8\n6\n22\n3\n23\n3\n242\n9\n4\n3\n3\n5\n7\n3\n3\n5\n8\n3\n7\n5\n14\n8\n10\n3\n4\n3\n7\n4\n6\n7\n4\n10\n4\n3\n11\n3\n7\n10\n3\n13\n6\n8\n12\n10\n5\n7\n9\n3\n4\n7\n7\n10\n8\n30\n9\n19\n4\n3\n19\n15\n4\n13\n3\n215\n223\n4\n7\n4\n8\n17\n16\n3\n7\n6\n5\n5\n4\n12\n3\n7\n4\n4\n13\n4\n5\n2\n5\n6\n5\n6\n6\n7\n10\n18\n23\n9\n3\n3\n6\n5\n2\n4\n2\n7\n3\n3\n2\n5\n5\n14\n10\n224\n6\n3\n4\n3\n7\n5\n9\n3\n6\n4\n2\n5\n11\n4\n3\n3\n2\n8\n4\n7\n4\n10\n7\n3\n3\n18\n18\n17\n3\n3\n3\n4\n5\n3\n3\n4\n12\n7\n3\n11\n13\n5\n4\n7\n13\n5\n4\n11\n3\n12\n3\n6\n4\n4\n21\n4\n6\n9\n5\n3\n10\n8\n4\n6\n4\n4\n6\n5\n4\n8\n6\n4\n6\n4\n4\n5\n9\n6\n3\n4\n2\n9\n3\n18\n2\n4\n3\n13\n3\n6\n6\n8\n7\n9\n3\n2\n16\n3\n4\n6\n3\n2\n33\n22\n14\n4\n9\n12\n4\n5\n6\n3\n23\n9\n4\n3\n5\n5\n3\n4\n5\n3\n5\n3\n10\n4\n5\n5\n8\n4\n4\n6\n8\n5\n4\n3\n4\n6\n3\n3\n3\n5\n9\n12\n6\n5\n9\n3\n5\n3\n2\n2\n2\n18\n3\n2\n21\n2\n5\n4\n6\n4\n5\n10\n3\n9\n3\n2\n10\n7\n3\n6\n6\n4\n4\n8\n12\n7\n3\n7\n3\n3\n9\n3\n4\n5\n4\n4\n5\n5\n10\n15\n4\n4\n14\n6\n227\n3\n14\n5\n216\n22\n5\n4\n2\n2\n6\n3\n4\n2\n9\n9\n4\n3\n28\n13\n11\n4\n5\n3\n3\n2\n3\n3\n5\n3\n4\n3\n5\n23\n26\n3\n4\n5\n6\n4\n6\n3\n5\n5\n3\n4\n3\n2\n2\n2\n7\n14\n3\n6\n7\n17\n2\n2\n15\n14\n16\n4\n6\n7\n13\n6\n4\n5\n6\n16\n3\n3\n28\n3\n6\n15\n3\n9\n2\n4\n6\n3\n3\n22\n4\n12\n6\n7\n2\n5\n4\n10\n3\n16\n6\n9\n2\n5\n12\n7\n5\n5\n5\n5\n2\n11\n9\n17\n4\n3\n11\n7\n3\n5\n15\n4\n3\n4\n211\n8\n7\n5\n4\n7\n6\n7\n6\n3\n6\n5\n6\n5\n3\n4\n4\n26\n4\n6\n10\n4\n4\n3\n2\n3\n3\n4\n5\n9\n3\n9\n4\n4\n5\n5\n8\n2\n4\n2\n3\n8\n4\n11\n19\n5\n8\n6\n3\n5\n6\n12\n3\n2\n4\n16\n12\n3\n4\n4\n8\n6\n5\n6\n6\n219\n8\n222\n6\n16\n3\n13\n19\n5\n4\n3\n11\n6\n10\n4\n7\n7\n12\n5\n3\n3\n5\n6\n10\n3\n8\n2\n5\n4\n7\n2\n4\n4\n2\n12\n9\n6\n4\n2\n40\n2\n4\n10\n4\n223\n4\n2\n20\n6\n7\n24\n5\n4\n5\n2\n20\n16\n6\n5\n13\n2\n3\n3\n19\n3\n2\n4\n5\n6\n7\n11\n12\n5\n6\n7\n7\n3\n5\n3\n5\n3\n14\n3\n4\n4\n2\n11\n1\n7\n3\n9\n6\n11\n12\n5\n8\n6\n221\n4\n2\n12\n4\n3\n15\n4\n5\n226\n7\n218\n7\n5\n4\n5\n18\n4\n5\n9\n4\n4\n2\n9\n18\n18\n9\n5\n6\n6\n3\n3\n7\n3\n5\n4\n4\n4\n12\n3\n6\n31\n5\n4\n7\n3\n6\n5\n6\n5\n11\n2\n2\n11\n11\n6\n7\n5\n8\n7\n10\n5\n23\n7\n4\n3\n5\n34\n2\n5\n23\n7\n3\n6\n8\n4\n4\n4\n2\n5\n3\n8\n5\n4\n8\n25\n2\n3\n17\n8\n3\n4\n8\n7\n3\n15\n6\n5\n7\n21\n9\n5\n6\n6\n5\n3\n2\n3\n10\n3\n6\n3\n14\n7\n4\n4\n8\n7\n8\n2\n6\n12\n4\n213\n6\n5\n21\n8\n2\n5\n23\n3\n11\n2\n3\n6\n25\n2\n3\n6\n7\n6\n6\n4\n4\n6\n3\n17\n9\n7\n6\n4\n3\n10\n7\n2\n3\n3\n3\n11\n8\n3\n7\n6\n4\n14\n36\n3\n4\n3\n3\n22\n13\n21\n4\n2\n7\n4\n4\n17\n15\n3\n7\n11\n2\n4\n7\n6\n209\n6\n3\n2\n2\n24\n4\n9\n4\n3\n3\n3\n29\n2\n2\n4\n3\n3\n5\n4\n6\n3\n3\n2\n4\n"
  },
  {
    "path": "vendor/github.com/beorn7/perks/quantile/stream.go",
    "content": "// Package quantile computes approximate quantiles over an unbounded data\n// stream within low memory and CPU bounds.\n//\n// A small amount of accuracy is traded to achieve the above properties.\n//\n// Multiple streams can be merged before calling Query to generate a single set\n// of results. This is meaningful when the streams represent the same type of\n// data. See Merge and Samples.\n//\n// For more detailed information about the algorithm used, see:\n//\n// Effective Computation of Biased Quantiles over Data Streams\n//\n// http://www.cs.rutgers.edu/~muthu/bquant.pdf\npackage quantile\n\nimport (\n\t\"math\"\n\t\"sort\"\n)\n\n// Sample holds an observed value and meta information for compression. JSON\n// tags have been added for convenience.\ntype Sample struct {\n\tValue float64 `json:\",string\"`\n\tWidth float64 `json:\",string\"`\n\tDelta float64 `json:\",string\"`\n}\n\n// Samples represents a slice of samples. It implements sort.Interface.\ntype Samples []Sample\n\nfunc (a Samples) Len() int           { return len(a) }\nfunc (a Samples) Less(i, j int) bool { return a[i].Value < a[j].Value }\nfunc (a Samples) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }\n\ntype invariant func(s *stream, r float64) float64\n\n// NewLowBiased returns an initialized Stream for low-biased quantiles\n// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but\n// error guarantees can still be given even for the lower ranks of the data\n// distribution.\n//\n// The provided epsilon is a relative error, i.e. the true quantile of a value\n// returned by a query is guaranteed to be within (1±Epsilon)*Quantile.\n//\n// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error\n// properties.\nfunc NewLowBiased(epsilon float64) *Stream {\n\tƒ := func(s *stream, r float64) float64 {\n\t\treturn 2 * epsilon * r\n\t}\n\treturn newStream(ƒ)\n}\n\n// NewHighBiased returns an initialized Stream for high-biased quantiles\n// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but\n// error guarantees can still be given even for the higher ranks of the data\n// distribution.\n//\n// The provided epsilon is a relative error, i.e. the true quantile of a value\n// returned by a query is guaranteed to be within 1-(1±Epsilon)*(1-Quantile).\n//\n// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error\n// properties.\nfunc NewHighBiased(epsilon float64) *Stream {\n\tƒ := func(s *stream, r float64) float64 {\n\t\treturn 2 * epsilon * (s.n - r)\n\t}\n\treturn newStream(ƒ)\n}\n\n// NewTargeted returns an initialized Stream concerned with a particular set of\n// quantile values that are supplied a priori. Knowing these a priori reduces\n// space and computation time. The targets map maps the desired quantiles to\n// their absolute errors, i.e. the true quantile of a value returned by a query\n// is guaranteed to be within (Quantile±Epsilon).\n//\n// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error properties.\nfunc NewTargeted(targetMap map[float64]float64) *Stream {\n\t// Convert map to slice to avoid slow iterations on a map.\n\t// ƒ is called on the hot path, so converting the map to a slice\n\t// beforehand results in significant CPU savings.\n\ttargets := targetMapToSlice(targetMap)\n\n\tƒ := func(s *stream, r float64) float64 {\n\t\tvar m = math.MaxFloat64\n\t\tvar f float64\n\t\tfor _, t := range targets {\n\t\t\tif t.quantile*s.n <= r {\n\t\t\t\tf = (2 * t.epsilon * r) / t.quantile\n\t\t\t} else {\n\t\t\t\tf = (2 * t.epsilon * (s.n - r)) / (1 - t.quantile)\n\t\t\t}\n\t\t\tif f < m {\n\t\t\t\tm = f\n\t\t\t}\n\t\t}\n\t\treturn m\n\t}\n\treturn newStream(ƒ)\n}\n\ntype target struct {\n\tquantile float64\n\tepsilon  float64\n}\n\nfunc targetMapToSlice(targetMap map[float64]float64) []target {\n\ttargets := make([]target, 0, len(targetMap))\n\n\tfor quantile, epsilon := range targetMap {\n\t\tt := target{\n\t\t\tquantile: quantile,\n\t\t\tepsilon:  epsilon,\n\t\t}\n\t\ttargets = append(targets, t)\n\t}\n\n\treturn targets\n}\n\n// Stream computes quantiles for a stream of float64s. It is not thread-safe by\n// design. Take care when using across multiple goroutines.\ntype Stream struct {\n\t*stream\n\tb      Samples\n\tsorted bool\n}\n\nfunc newStream(ƒ invariant) *Stream {\n\tx := &stream{ƒ: ƒ}\n\treturn &Stream{x, make(Samples, 0, 500), true}\n}\n\n// Insert inserts v into the stream.\nfunc (s *Stream) Insert(v float64) {\n\ts.insert(Sample{Value: v, Width: 1})\n}\n\nfunc (s *Stream) insert(sample Sample) {\n\ts.b = append(s.b, sample)\n\ts.sorted = false\n\tif len(s.b) == cap(s.b) {\n\t\ts.flush()\n\t}\n}\n\n// Query returns the computed qth percentiles value. If s was created with\n// NewTargeted, and q is not in the set of quantiles provided a priori, Query\n// will return an unspecified result.\nfunc (s *Stream) Query(q float64) float64 {\n\tif !s.flushed() {\n\t\t// Fast path when there hasn't been enough data for a flush;\n\t\t// this also yields better accuracy for small sets of data.\n\t\tl := len(s.b)\n\t\tif l == 0 {\n\t\t\treturn 0\n\t\t}\n\t\ti := int(math.Ceil(float64(l) * q))\n\t\tif i > 0 {\n\t\t\ti -= 1\n\t\t}\n\t\ts.maybeSort()\n\t\treturn s.b[i].Value\n\t}\n\ts.flush()\n\treturn s.stream.query(q)\n}\n\n// Merge merges samples into the underlying streams samples. This is handy when\n// merging multiple streams from separate threads, database shards, etc.\n//\n// ATTENTION: This method is broken and does not yield correct results. The\n// underlying algorithm is not capable of merging streams correctly.\nfunc (s *Stream) Merge(samples Samples) {\n\tsort.Sort(samples)\n\ts.stream.merge(samples)\n}\n\n// Reset reinitializes and clears the list reusing the samples buffer memory.\nfunc (s *Stream) Reset() {\n\ts.stream.reset()\n\ts.b = s.b[:0]\n}\n\n// Samples returns stream samples held by s.\nfunc (s *Stream) Samples() Samples {\n\tif !s.flushed() {\n\t\treturn s.b\n\t}\n\ts.flush()\n\treturn s.stream.samples()\n}\n\n// Count returns the total number of samples observed in the stream\n// since initialization.\nfunc (s *Stream) Count() int {\n\treturn len(s.b) + s.stream.count()\n}\n\nfunc (s *Stream) flush() {\n\ts.maybeSort()\n\ts.stream.merge(s.b)\n\ts.b = s.b[:0]\n}\n\nfunc (s *Stream) maybeSort() {\n\tif !s.sorted {\n\t\ts.sorted = true\n\t\tsort.Sort(s.b)\n\t}\n}\n\nfunc (s *Stream) flushed() bool {\n\treturn len(s.stream.l) > 0\n}\n\ntype stream struct {\n\tn float64\n\tl []Sample\n\tƒ invariant\n}\n\nfunc (s *stream) reset() {\n\ts.l = s.l[:0]\n\ts.n = 0\n}\n\nfunc (s *stream) insert(v float64) {\n\ts.merge(Samples{{v, 1, 0}})\n}\n\nfunc (s *stream) merge(samples Samples) {\n\t// TODO(beorn7): This tries to merge not only individual samples, but\n\t// whole summaries. The paper doesn't mention merging summaries at\n\t// all. Unittests show that the merging is inaccurate. Find out how to\n\t// do merges properly.\n\tvar r float64\n\ti := 0\n\tfor _, sample := range samples {\n\t\tfor ; i < len(s.l); i++ {\n\t\t\tc := s.l[i]\n\t\t\tif c.Value > sample.Value {\n\t\t\t\t// Insert at position i.\n\t\t\t\ts.l = append(s.l, Sample{})\n\t\t\t\tcopy(s.l[i+1:], s.l[i:])\n\t\t\t\ts.l[i] = Sample{\n\t\t\t\t\tsample.Value,\n\t\t\t\t\tsample.Width,\n\t\t\t\t\tmath.Max(sample.Delta, math.Floor(s.ƒ(s, r))-1),\n\t\t\t\t\t// TODO(beorn7): How to calculate delta correctly?\n\t\t\t\t}\n\t\t\t\ti++\n\t\t\t\tgoto inserted\n\t\t\t}\n\t\t\tr += c.Width\n\t\t}\n\t\ts.l = append(s.l, Sample{sample.Value, sample.Width, 0})\n\t\ti++\n\tinserted:\n\t\ts.n += sample.Width\n\t\tr += sample.Width\n\t}\n\ts.compress()\n}\n\nfunc (s *stream) count() int {\n\treturn int(s.n)\n}\n\nfunc (s *stream) query(q float64) float64 {\n\tt := math.Ceil(q * s.n)\n\tt += math.Ceil(s.ƒ(s, t) / 2)\n\tp := s.l[0]\n\tvar r float64\n\tfor _, c := range s.l[1:] {\n\t\tr += p.Width\n\t\tif r+c.Width+c.Delta > t {\n\t\t\treturn p.Value\n\t\t}\n\t\tp = c\n\t}\n\treturn p.Value\n}\n\nfunc (s *stream) compress() {\n\tif len(s.l) < 2 {\n\t\treturn\n\t}\n\tx := s.l[len(s.l)-1]\n\txi := len(s.l) - 1\n\tr := s.n - 1 - x.Width\n\n\tfor i := len(s.l) - 2; i >= 0; i-- {\n\t\tc := s.l[i]\n\t\tif c.Width+x.Width+x.Delta <= s.ƒ(s, r) {\n\t\t\tx.Width += c.Width\n\t\t\ts.l[xi] = x\n\t\t\t// Remove element at i.\n\t\t\tcopy(s.l[i:], s.l[i+1:])\n\t\t\ts.l = s.l[:len(s.l)-1]\n\t\t\txi -= 1\n\t\t} else {\n\t\t\tx = c\n\t\t\txi = i\n\t\t}\n\t\tr -= c.Width\n\t}\n}\n\nfunc (s *stream) samples() Samples {\n\tsamples := make(Samples, len(s.l))\n\tcopy(samples, s.l)\n\treturn samples\n}\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/LICENSE.txt",
    "content": "Copyright (c) 2016 Caleb Spare\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/README.md",
    "content": "# xxhash\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/cespare/xxhash/v2.svg)](https://pkg.go.dev/github.com/cespare/xxhash/v2)\n[![Test](https://github.com/cespare/xxhash/actions/workflows/test.yml/badge.svg)](https://github.com/cespare/xxhash/actions/workflows/test.yml)\n\nxxhash is a Go implementation of the 64-bit [xxHash] algorithm, XXH64. This is a\nhigh-quality hashing algorithm that is much faster than anything in the Go\nstandard library.\n\nThis package provides a straightforward API:\n\n```\nfunc Sum64(b []byte) uint64\nfunc Sum64String(s string) uint64\ntype Digest struct{ ... }\n    func New() *Digest\n```\n\nThe `Digest` type implements hash.Hash64. Its key methods are:\n\n```\nfunc (*Digest) Write([]byte) (int, error)\nfunc (*Digest) WriteString(string) (int, error)\nfunc (*Digest) Sum64() uint64\n```\n\nThe package is written with optimized pure Go and also contains even faster\nassembly implementations for amd64 and arm64. If desired, the `purego` build tag\nopts into using the Go code even on those architectures.\n\n[xxHash]: http://cyan4973.github.io/xxHash/\n\n## Compatibility\n\nThis package is in a module and the latest code is in version 2 of the module.\nYou need a version of Go with at least \"minimal module compatibility\" to use\ngithub.com/cespare/xxhash/v2:\n\n* 1.9.7+ for Go 1.9\n* 1.10.3+ for Go 1.10\n* Go 1.11 or later\n\nI recommend using the latest release of Go.\n\n## Benchmarks\n\nHere are some quick benchmarks comparing the pure-Go and assembly\nimplementations of Sum64.\n\n| input size | purego    | asm       |\n| ---------- | --------- | --------- |\n| 4 B        |  1.3 GB/s |  1.2 GB/s |\n| 16 B       |  2.9 GB/s |  3.5 GB/s |\n| 100 B      |  6.9 GB/s |  8.1 GB/s |\n| 4 KB       | 11.7 GB/s | 16.7 GB/s |\n| 10 MB      | 12.0 GB/s | 17.3 GB/s |\n\nThese numbers were generated on Ubuntu 20.04 with an Intel Xeon Platinum 8252C\nCPU using the following commands under Go 1.19.2:\n\n```\nbenchstat <(go test -tags purego -benchtime 500ms -count 15 -bench 'Sum64$')\nbenchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$')\n```\n\n## Projects using this package\n\n- [InfluxDB](https://github.com/influxdata/influxdb)\n- [Prometheus](https://github.com/prometheus/prometheus)\n- [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics)\n- [FreeCache](https://github.com/coocood/freecache)\n- [FastCache](https://github.com/VictoriaMetrics/fastcache)\n- [Ristretto](https://github.com/dgraph-io/ristretto)\n- [Badger](https://github.com/dgraph-io/badger)\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/testall.sh",
    "content": "#!/bin/bash\nset -eu -o pipefail\n\n# Small convenience script for running the tests with various combinations of\n# arch/tags. This assumes we're running on amd64 and have qemu available.\n\ngo test ./...\ngo test -tags purego ./...\nGOARCH=arm64 go test\nGOARCH=arm64 go test -tags purego\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash.go",
    "content": "// Package xxhash implements the 64-bit variant of xxHash (XXH64) as described\n// at http://cyan4973.github.io/xxHash/.\npackage xxhash\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"math/bits\"\n)\n\nconst (\n\tprime1 uint64 = 11400714785074694791\n\tprime2 uint64 = 14029467366897019727\n\tprime3 uint64 = 1609587929392839161\n\tprime4 uint64 = 9650029242287828579\n\tprime5 uint64 = 2870177450012600261\n)\n\n// Store the primes in an array as well.\n//\n// The consts are used when possible in Go code to avoid MOVs but we need a\n// contiguous array for the assembly code.\nvar primes = [...]uint64{prime1, prime2, prime3, prime4, prime5}\n\n// Digest implements hash.Hash64.\n//\n// Note that a zero-valued Digest is not ready to receive writes.\n// Call Reset or create a Digest using New before calling other methods.\ntype Digest struct {\n\tv1    uint64\n\tv2    uint64\n\tv3    uint64\n\tv4    uint64\n\ttotal uint64\n\tmem   [32]byte\n\tn     int // how much of mem is used\n}\n\n// New creates a new Digest with a zero seed.\nfunc New() *Digest {\n\treturn NewWithSeed(0)\n}\n\n// NewWithSeed creates a new Digest with the given seed.\nfunc NewWithSeed(seed uint64) *Digest {\n\tvar d Digest\n\td.ResetWithSeed(seed)\n\treturn &d\n}\n\n// Reset clears the Digest's state so that it can be reused.\n// It uses a seed value of zero.\nfunc (d *Digest) Reset() {\n\td.ResetWithSeed(0)\n}\n\n// ResetWithSeed clears the Digest's state so that it can be reused.\n// It uses the given seed to initialize the state.\nfunc (d *Digest) ResetWithSeed(seed uint64) {\n\td.v1 = seed + prime1 + prime2\n\td.v2 = seed + prime2\n\td.v3 = seed\n\td.v4 = seed - prime1\n\td.total = 0\n\td.n = 0\n}\n\n// Size always returns 8 bytes.\nfunc (d *Digest) Size() int { return 8 }\n\n// BlockSize always returns 32 bytes.\nfunc (d *Digest) BlockSize() int { return 32 }\n\n// Write adds more data to d. It always returns len(b), nil.\nfunc (d *Digest) Write(b []byte) (n int, err error) {\n\tn = len(b)\n\td.total += uint64(n)\n\n\tmemleft := d.mem[d.n&(len(d.mem)-1):]\n\n\tif d.n+n < 32 {\n\t\t// This new data doesn't even fill the current block.\n\t\tcopy(memleft, b)\n\t\td.n += n\n\t\treturn\n\t}\n\n\tif d.n > 0 {\n\t\t// Finish off the partial block.\n\t\tc := copy(memleft, b)\n\t\td.v1 = round(d.v1, u64(d.mem[0:8]))\n\t\td.v2 = round(d.v2, u64(d.mem[8:16]))\n\t\td.v3 = round(d.v3, u64(d.mem[16:24]))\n\t\td.v4 = round(d.v4, u64(d.mem[24:32]))\n\t\tb = b[c:]\n\t\td.n = 0\n\t}\n\n\tif len(b) >= 32 {\n\t\t// One or more full blocks left.\n\t\tnw := writeBlocks(d, b)\n\t\tb = b[nw:]\n\t}\n\n\t// Store any remaining partial block.\n\tcopy(d.mem[:], b)\n\td.n = len(b)\n\n\treturn\n}\n\n// Sum appends the current hash to b and returns the resulting slice.\nfunc (d *Digest) Sum(b []byte) []byte {\n\ts := d.Sum64()\n\treturn append(\n\t\tb,\n\t\tbyte(s>>56),\n\t\tbyte(s>>48),\n\t\tbyte(s>>40),\n\t\tbyte(s>>32),\n\t\tbyte(s>>24),\n\t\tbyte(s>>16),\n\t\tbyte(s>>8),\n\t\tbyte(s),\n\t)\n}\n\n// Sum64 returns the current hash.\nfunc (d *Digest) Sum64() uint64 {\n\tvar h uint64\n\n\tif d.total >= 32 {\n\t\tv1, v2, v3, v4 := d.v1, d.v2, d.v3, d.v4\n\t\th = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4)\n\t\th = mergeRound(h, v1)\n\t\th = mergeRound(h, v2)\n\t\th = mergeRound(h, v3)\n\t\th = mergeRound(h, v4)\n\t} else {\n\t\th = d.v3 + prime5\n\t}\n\n\th += d.total\n\n\tb := d.mem[:d.n&(len(d.mem)-1)]\n\tfor ; len(b) >= 8; b = b[8:] {\n\t\tk1 := round(0, u64(b[:8]))\n\t\th ^= k1\n\t\th = rol27(h)*prime1 + prime4\n\t}\n\tif len(b) >= 4 {\n\t\th ^= uint64(u32(b[:4])) * prime1\n\t\th = rol23(h)*prime2 + prime3\n\t\tb = b[4:]\n\t}\n\tfor ; len(b) > 0; b = b[1:] {\n\t\th ^= uint64(b[0]) * prime5\n\t\th = rol11(h) * prime1\n\t}\n\n\th ^= h >> 33\n\th *= prime2\n\th ^= h >> 29\n\th *= prime3\n\th ^= h >> 32\n\n\treturn h\n}\n\nconst (\n\tmagic         = \"xxh\\x06\"\n\tmarshaledSize = len(magic) + 8*5 + 32\n)\n\n// MarshalBinary implements the encoding.BinaryMarshaler interface.\nfunc (d *Digest) MarshalBinary() ([]byte, error) {\n\tb := make([]byte, 0, marshaledSize)\n\tb = append(b, magic...)\n\tb = appendUint64(b, d.v1)\n\tb = appendUint64(b, d.v2)\n\tb = appendUint64(b, d.v3)\n\tb = appendUint64(b, d.v4)\n\tb = appendUint64(b, d.total)\n\tb = append(b, d.mem[:d.n]...)\n\tb = b[:len(b)+len(d.mem)-d.n]\n\treturn b, nil\n}\n\n// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.\nfunc (d *Digest) UnmarshalBinary(b []byte) error {\n\tif len(b) < len(magic) || string(b[:len(magic)]) != magic {\n\t\treturn errors.New(\"xxhash: invalid hash state identifier\")\n\t}\n\tif len(b) != marshaledSize {\n\t\treturn errors.New(\"xxhash: invalid hash state size\")\n\t}\n\tb = b[len(magic):]\n\tb, d.v1 = consumeUint64(b)\n\tb, d.v2 = consumeUint64(b)\n\tb, d.v3 = consumeUint64(b)\n\tb, d.v4 = consumeUint64(b)\n\tb, d.total = consumeUint64(b)\n\tcopy(d.mem[:], b)\n\td.n = int(d.total % uint64(len(d.mem)))\n\treturn nil\n}\n\nfunc appendUint64(b []byte, x uint64) []byte {\n\tvar a [8]byte\n\tbinary.LittleEndian.PutUint64(a[:], x)\n\treturn append(b, a[:]...)\n}\n\nfunc consumeUint64(b []byte) ([]byte, uint64) {\n\tx := u64(b)\n\treturn b[8:], x\n}\n\nfunc u64(b []byte) uint64 { return binary.LittleEndian.Uint64(b) }\nfunc u32(b []byte) uint32 { return binary.LittleEndian.Uint32(b) }\n\nfunc round(acc, input uint64) uint64 {\n\tacc += input * prime2\n\tacc = rol31(acc)\n\tacc *= prime1\n\treturn acc\n}\n\nfunc mergeRound(acc, val uint64) uint64 {\n\tval = round(0, val)\n\tacc ^= val\n\tacc = acc*prime1 + prime4\n\treturn acc\n}\n\nfunc rol1(x uint64) uint64  { return bits.RotateLeft64(x, 1) }\nfunc rol7(x uint64) uint64  { return bits.RotateLeft64(x, 7) }\nfunc rol11(x uint64) uint64 { return bits.RotateLeft64(x, 11) }\nfunc rol12(x uint64) uint64 { return bits.RotateLeft64(x, 12) }\nfunc rol18(x uint64) uint64 { return bits.RotateLeft64(x, 18) }\nfunc rol23(x uint64) uint64 { return bits.RotateLeft64(x, 23) }\nfunc rol27(x uint64) uint64 { return bits.RotateLeft64(x, 27) }\nfunc rol31(x uint64) uint64 { return bits.RotateLeft64(x, 31) }\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s",
    "content": "//go:build !appengine && gc && !purego\n// +build !appengine\n// +build gc\n// +build !purego\n\n#include \"textflag.h\"\n\n// Registers:\n#define h      AX\n#define d      AX\n#define p      SI // pointer to advance through b\n#define n      DX\n#define end    BX // loop end\n#define v1     R8\n#define v2     R9\n#define v3     R10\n#define v4     R11\n#define x      R12\n#define prime1 R13\n#define prime2 R14\n#define prime4 DI\n\n#define round(acc, x) \\\n\tIMULQ prime2, x   \\\n\tADDQ  x, acc      \\\n\tROLQ  $31, acc    \\\n\tIMULQ prime1, acc\n\n// round0 performs the operation x = round(0, x).\n#define round0(x) \\\n\tIMULQ prime2, x \\\n\tROLQ  $31, x    \\\n\tIMULQ prime1, x\n\n// mergeRound applies a merge round on the two registers acc and x.\n// It assumes that prime1, prime2, and prime4 have been loaded.\n#define mergeRound(acc, x) \\\n\tround0(x)         \\\n\tXORQ  x, acc      \\\n\tIMULQ prime1, acc \\\n\tADDQ  prime4, acc\n\n// blockLoop processes as many 32-byte blocks as possible,\n// updating v1, v2, v3, and v4. It assumes that there is at least one block\n// to process.\n#define blockLoop() \\\nloop:  \\\n\tMOVQ +0(p), x  \\\n\tround(v1, x)   \\\n\tMOVQ +8(p), x  \\\n\tround(v2, x)   \\\n\tMOVQ +16(p), x \\\n\tround(v3, x)   \\\n\tMOVQ +24(p), x \\\n\tround(v4, x)   \\\n\tADDQ $32, p    \\\n\tCMPQ p, end    \\\n\tJLE  loop\n\n// func Sum64(b []byte) uint64\nTEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32\n\t// Load fixed primes.\n\tMOVQ ·primes+0(SB), prime1\n\tMOVQ ·primes+8(SB), prime2\n\tMOVQ ·primes+24(SB), prime4\n\n\t// Load slice.\n\tMOVQ b_base+0(FP), p\n\tMOVQ b_len+8(FP), n\n\tLEAQ (p)(n*1), end\n\n\t// The first loop limit will be len(b)-32.\n\tSUBQ $32, end\n\n\t// Check whether we have at least one block.\n\tCMPQ n, $32\n\tJLT  noBlocks\n\n\t// Set up initial state (v1, v2, v3, v4).\n\tMOVQ prime1, v1\n\tADDQ prime2, v1\n\tMOVQ prime2, v2\n\tXORQ v3, v3\n\tXORQ v4, v4\n\tSUBQ prime1, v4\n\n\tblockLoop()\n\n\tMOVQ v1, h\n\tROLQ $1, h\n\tMOVQ v2, x\n\tROLQ $7, x\n\tADDQ x, h\n\tMOVQ v3, x\n\tROLQ $12, x\n\tADDQ x, h\n\tMOVQ v4, x\n\tROLQ $18, x\n\tADDQ x, h\n\n\tmergeRound(h, v1)\n\tmergeRound(h, v2)\n\tmergeRound(h, v3)\n\tmergeRound(h, v4)\n\n\tJMP afterBlocks\n\nnoBlocks:\n\tMOVQ ·primes+32(SB), h\n\nafterBlocks:\n\tADDQ n, h\n\n\tADDQ $24, end\n\tCMPQ p, end\n\tJG   try4\n\nloop8:\n\tMOVQ  (p), x\n\tADDQ  $8, p\n\tround0(x)\n\tXORQ  x, h\n\tROLQ  $27, h\n\tIMULQ prime1, h\n\tADDQ  prime4, h\n\n\tCMPQ p, end\n\tJLE  loop8\n\ntry4:\n\tADDQ $4, end\n\tCMPQ p, end\n\tJG   try1\n\n\tMOVL  (p), x\n\tADDQ  $4, p\n\tIMULQ prime1, x\n\tXORQ  x, h\n\n\tROLQ  $23, h\n\tIMULQ prime2, h\n\tADDQ  ·primes+16(SB), h\n\ntry1:\n\tADDQ $4, end\n\tCMPQ p, end\n\tJGE  finalize\n\nloop1:\n\tMOVBQZX (p), x\n\tADDQ    $1, p\n\tIMULQ   ·primes+32(SB), x\n\tXORQ    x, h\n\tROLQ    $11, h\n\tIMULQ   prime1, h\n\n\tCMPQ p, end\n\tJL   loop1\n\nfinalize:\n\tMOVQ  h, x\n\tSHRQ  $33, x\n\tXORQ  x, h\n\tIMULQ prime2, h\n\tMOVQ  h, x\n\tSHRQ  $29, x\n\tXORQ  x, h\n\tIMULQ ·primes+16(SB), h\n\tMOVQ  h, x\n\tSHRQ  $32, x\n\tXORQ  x, h\n\n\tMOVQ h, ret+24(FP)\n\tRET\n\n// func writeBlocks(d *Digest, b []byte) int\nTEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40\n\t// Load fixed primes needed for round.\n\tMOVQ ·primes+0(SB), prime1\n\tMOVQ ·primes+8(SB), prime2\n\n\t// Load slice.\n\tMOVQ b_base+8(FP), p\n\tMOVQ b_len+16(FP), n\n\tLEAQ (p)(n*1), end\n\tSUBQ $32, end\n\n\t// Load vN from d.\n\tMOVQ s+0(FP), d\n\tMOVQ 0(d), v1\n\tMOVQ 8(d), v2\n\tMOVQ 16(d), v3\n\tMOVQ 24(d), v4\n\n\t// We don't need to check the loop condition here; this function is\n\t// always called with at least one block of data to process.\n\tblockLoop()\n\n\t// Copy vN back to d.\n\tMOVQ v1, 0(d)\n\tMOVQ v2, 8(d)\n\tMOVQ v3, 16(d)\n\tMOVQ v4, 24(d)\n\n\t// The number of bytes written is p minus the old base pointer.\n\tSUBQ b_base+8(FP), p\n\tMOVQ p, ret+32(FP)\n\n\tRET\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s",
    "content": "//go:build !appengine && gc && !purego\n// +build !appengine\n// +build gc\n// +build !purego\n\n#include \"textflag.h\"\n\n// Registers:\n#define digest\tR1\n#define h\tR2 // return value\n#define p\tR3 // input pointer\n#define n\tR4 // input length\n#define nblocks\tR5 // n / 32\n#define prime1\tR7\n#define prime2\tR8\n#define prime3\tR9\n#define prime4\tR10\n#define prime5\tR11\n#define v1\tR12\n#define v2\tR13\n#define v3\tR14\n#define v4\tR15\n#define x1\tR20\n#define x2\tR21\n#define x3\tR22\n#define x4\tR23\n\n#define round(acc, x) \\\n\tMADD prime2, acc, x, acc \\\n\tROR  $64-31, acc         \\\n\tMUL  prime1, acc\n\n// round0 performs the operation x = round(0, x).\n#define round0(x) \\\n\tMUL prime2, x \\\n\tROR $64-31, x \\\n\tMUL prime1, x\n\n#define mergeRound(acc, x) \\\n\tround0(x)                     \\\n\tEOR  x, acc                   \\\n\tMADD acc, prime4, prime1, acc\n\n// blockLoop processes as many 32-byte blocks as possible,\n// updating v1, v2, v3, and v4. It assumes that n >= 32.\n#define blockLoop() \\\n\tLSR     $5, n, nblocks  \\\n\tPCALIGN $16             \\\n\tloop:                   \\\n\tLDP.P   16(p), (x1, x2) \\\n\tLDP.P   16(p), (x3, x4) \\\n\tround(v1, x1)           \\\n\tround(v2, x2)           \\\n\tround(v3, x3)           \\\n\tround(v4, x4)           \\\n\tSUB     $1, nblocks     \\\n\tCBNZ    nblocks, loop\n\n// func Sum64(b []byte) uint64\nTEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32\n\tLDP b_base+0(FP), (p, n)\n\n\tLDP  ·primes+0(SB), (prime1, prime2)\n\tLDP  ·primes+16(SB), (prime3, prime4)\n\tMOVD ·primes+32(SB), prime5\n\n\tCMP  $32, n\n\tCSEL LT, prime5, ZR, h // if n < 32 { h = prime5 } else { h = 0 }\n\tBLT  afterLoop\n\n\tADD  prime1, prime2, v1\n\tMOVD prime2, v2\n\tMOVD $0, v3\n\tNEG  prime1, v4\n\n\tblockLoop()\n\n\tROR $64-1, v1, x1\n\tROR $64-7, v2, x2\n\tADD x1, x2\n\tROR $64-12, v3, x3\n\tROR $64-18, v4, x4\n\tADD x3, x4\n\tADD x2, x4, h\n\n\tmergeRound(h, v1)\n\tmergeRound(h, v2)\n\tmergeRound(h, v3)\n\tmergeRound(h, v4)\n\nafterLoop:\n\tADD n, h\n\n\tTBZ   $4, n, try8\n\tLDP.P 16(p), (x1, x2)\n\n\tround0(x1)\n\n\t// NOTE: here and below, sequencing the EOR after the ROR (using a\n\t// rotated register) is worth a small but measurable speedup for small\n\t// inputs.\n\tROR  $64-27, h\n\tEOR  x1 @> 64-27, h, h\n\tMADD h, prime4, prime1, h\n\n\tround0(x2)\n\tROR  $64-27, h\n\tEOR  x2 @> 64-27, h, h\n\tMADD h, prime4, prime1, h\n\ntry8:\n\tTBZ    $3, n, try4\n\tMOVD.P 8(p), x1\n\n\tround0(x1)\n\tROR  $64-27, h\n\tEOR  x1 @> 64-27, h, h\n\tMADD h, prime4, prime1, h\n\ntry4:\n\tTBZ     $2, n, try2\n\tMOVWU.P 4(p), x2\n\n\tMUL  prime1, x2\n\tROR  $64-23, h\n\tEOR  x2 @> 64-23, h, h\n\tMADD h, prime3, prime2, h\n\ntry2:\n\tTBZ     $1, n, try1\n\tMOVHU.P 2(p), x3\n\tAND     $255, x3, x1\n\tLSR     $8, x3, x2\n\n\tMUL prime5, x1\n\tROR $64-11, h\n\tEOR x1 @> 64-11, h, h\n\tMUL prime1, h\n\n\tMUL prime5, x2\n\tROR $64-11, h\n\tEOR x2 @> 64-11, h, h\n\tMUL prime1, h\n\ntry1:\n\tTBZ   $0, n, finalize\n\tMOVBU (p), x4\n\n\tMUL prime5, x4\n\tROR $64-11, h\n\tEOR x4 @> 64-11, h, h\n\tMUL prime1, h\n\nfinalize:\n\tEOR h >> 33, h\n\tMUL prime2, h\n\tEOR h >> 29, h\n\tMUL prime3, h\n\tEOR h >> 32, h\n\n\tMOVD h, ret+24(FP)\n\tRET\n\n// func writeBlocks(d *Digest, b []byte) int\nTEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40\n\tLDP ·primes+0(SB), (prime1, prime2)\n\n\t// Load state. Assume v[1-4] are stored contiguously.\n\tMOVD d+0(FP), digest\n\tLDP  0(digest), (v1, v2)\n\tLDP  16(digest), (v3, v4)\n\n\tLDP b_base+8(FP), (p, n)\n\n\tblockLoop()\n\n\t// Store updated state.\n\tSTP (v1, v2), 0(digest)\n\tSTP (v3, v4), 16(digest)\n\n\tBIC  $31, n\n\tMOVD n, ret+32(FP)\n\tRET\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_asm.go",
    "content": "//go:build (amd64 || arm64) && !appengine && gc && !purego\n// +build amd64 arm64\n// +build !appengine\n// +build gc\n// +build !purego\n\npackage xxhash\n\n// Sum64 computes the 64-bit xxHash digest of b with a zero seed.\n//\n//go:noescape\nfunc Sum64(b []byte) uint64\n\n//go:noescape\nfunc writeBlocks(d *Digest, b []byte) int\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_other.go",
    "content": "//go:build (!amd64 && !arm64) || appengine || !gc || purego\n// +build !amd64,!arm64 appengine !gc purego\n\npackage xxhash\n\n// Sum64 computes the 64-bit xxHash digest of b with a zero seed.\nfunc Sum64(b []byte) uint64 {\n\t// A simpler version would be\n\t//   d := New()\n\t//   d.Write(b)\n\t//   return d.Sum64()\n\t// but this is faster, particularly for small inputs.\n\n\tn := len(b)\n\tvar h uint64\n\n\tif n >= 32 {\n\t\tv1 := primes[0] + prime2\n\t\tv2 := prime2\n\t\tv3 := uint64(0)\n\t\tv4 := -primes[0]\n\t\tfor len(b) >= 32 {\n\t\t\tv1 = round(v1, u64(b[0:8:len(b)]))\n\t\t\tv2 = round(v2, u64(b[8:16:len(b)]))\n\t\t\tv3 = round(v3, u64(b[16:24:len(b)]))\n\t\t\tv4 = round(v4, u64(b[24:32:len(b)]))\n\t\t\tb = b[32:len(b):len(b)]\n\t\t}\n\t\th = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4)\n\t\th = mergeRound(h, v1)\n\t\th = mergeRound(h, v2)\n\t\th = mergeRound(h, v3)\n\t\th = mergeRound(h, v4)\n\t} else {\n\t\th = prime5\n\t}\n\n\th += uint64(n)\n\n\tfor ; len(b) >= 8; b = b[8:] {\n\t\tk1 := round(0, u64(b[:8]))\n\t\th ^= k1\n\t\th = rol27(h)*prime1 + prime4\n\t}\n\tif len(b) >= 4 {\n\t\th ^= uint64(u32(b[:4])) * prime1\n\t\th = rol23(h)*prime2 + prime3\n\t\tb = b[4:]\n\t}\n\tfor ; len(b) > 0; b = b[1:] {\n\t\th ^= uint64(b[0]) * prime5\n\t\th = rol11(h) * prime1\n\t}\n\n\th ^= h >> 33\n\th *= prime2\n\th ^= h >> 29\n\th *= prime3\n\th ^= h >> 32\n\n\treturn h\n}\n\nfunc writeBlocks(d *Digest, b []byte) int {\n\tv1, v2, v3, v4 := d.v1, d.v2, d.v3, d.v4\n\tn := len(b)\n\tfor len(b) >= 32 {\n\t\tv1 = round(v1, u64(b[0:8:len(b)]))\n\t\tv2 = round(v2, u64(b[8:16:len(b)]))\n\t\tv3 = round(v3, u64(b[16:24:len(b)]))\n\t\tv4 = round(v4, u64(b[24:32:len(b)]))\n\t\tb = b[32:len(b):len(b)]\n\t}\n\td.v1, d.v2, d.v3, d.v4 = v1, v2, v3, v4\n\treturn n - len(b)\n}\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_safe.go",
    "content": "//go:build appengine\n// +build appengine\n\n// This file contains the safe implementations of otherwise unsafe-using code.\n\npackage xxhash\n\n// Sum64String computes the 64-bit xxHash digest of s with a zero seed.\nfunc Sum64String(s string) uint64 {\n\treturn Sum64([]byte(s))\n}\n\n// WriteString adds more data to d. It always returns len(s), nil.\nfunc (d *Digest) WriteString(s string) (n int, err error) {\n\treturn d.Write([]byte(s))\n}\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go",
    "content": "//go:build !appengine\n// +build !appengine\n\n// This file encapsulates usage of unsafe.\n// xxhash_safe.go contains the safe implementations.\n\npackage xxhash\n\nimport (\n\t\"unsafe\"\n)\n\n// In the future it's possible that compiler optimizations will make these\n// XxxString functions unnecessary by realizing that calls such as\n// Sum64([]byte(s)) don't need to copy s. See https://go.dev/issue/2205.\n// If that happens, even if we keep these functions they can be replaced with\n// the trivial safe code.\n\n// NOTE: The usual way of doing an unsafe string-to-[]byte conversion is:\n//\n//   var b []byte\n//   bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))\n//   bh.Data = (*reflect.StringHeader)(unsafe.Pointer(&s)).Data\n//   bh.Len = len(s)\n//   bh.Cap = len(s)\n//\n// Unfortunately, as of Go 1.15.3 the inliner's cost model assigns a high enough\n// weight to this sequence of expressions that any function that uses it will\n// not be inlined. Instead, the functions below use a different unsafe\n// conversion designed to minimize the inliner weight and allow both to be\n// inlined. There is also a test (TestInlining) which verifies that these are\n// inlined.\n//\n// See https://github.com/golang/go/issues/42739 for discussion.\n\n// Sum64String computes the 64-bit xxHash digest of s with a zero seed.\n// It may be faster than Sum64([]byte(s)) by avoiding a copy.\nfunc Sum64String(s string) uint64 {\n\tb := *(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)}))\n\treturn Sum64(b)\n}\n\n// WriteString adds more data to d. It always returns len(s), nil.\n// It may be faster than Write([]byte(s)) by avoiding a copy.\nfunc (d *Digest) WriteString(s string) (n int, err error) {\n\td.Write(*(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)})))\n\t// d.Write always returns len(s), nil.\n\t// Ignoring the return output and returning these fixed values buys a\n\t// savings of 6 in the inliner's cost model.\n\treturn len(s), nil\n}\n\n// sliceHeader is similar to reflect.SliceHeader, but it assumes that the layout\n// of the first two words is the same as the layout of a string.\ntype sliceHeader struct {\n\ts   string\n\tcap int\n}\n"
  },
  {
    "path": "vendor/github.com/coreos/go-oidc/v3/LICENSE",
    "content": "Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "vendor/github.com/coreos/go-oidc/v3/NOTICE",
    "content": "CoreOS Project\nCopyright 2014 CoreOS, Inc\n\nThis product includes software developed at CoreOS, Inc.\n(http://www.coreos.com/).\n"
  },
  {
    "path": "vendor/github.com/coreos/go-oidc/v3/oidc/jose.go",
    "content": "package oidc\n\nimport jose \"github.com/go-jose/go-jose/v4\"\n\n// JOSE asymmetric signing algorithm values as defined by RFC 7518\n//\n// see: https://tools.ietf.org/html/rfc7518#section-3.1\nconst (\n\tRS256 = \"RS256\" // RSASSA-PKCS-v1.5 using SHA-256\n\tRS384 = \"RS384\" // RSASSA-PKCS-v1.5 using SHA-384\n\tRS512 = \"RS512\" // RSASSA-PKCS-v1.5 using SHA-512\n\tES256 = \"ES256\" // ECDSA using P-256 and SHA-256\n\tES384 = \"ES384\" // ECDSA using P-384 and SHA-384\n\tES512 = \"ES512\" // ECDSA using P-521 and SHA-512\n\tPS256 = \"PS256\" // RSASSA-PSS using SHA256 and MGF1-SHA256\n\tPS384 = \"PS384\" // RSASSA-PSS using SHA384 and MGF1-SHA384\n\tPS512 = \"PS512\" // RSASSA-PSS using SHA512 and MGF1-SHA512\n\tEdDSA = \"EdDSA\" // Ed25519 using SHA-512\n)\n\nvar allAlgs = []jose.SignatureAlgorithm{\n\tjose.RS256,\n\tjose.RS384,\n\tjose.RS512,\n\tjose.ES256,\n\tjose.ES384,\n\tjose.ES512,\n\tjose.PS256,\n\tjose.PS384,\n\tjose.PS512,\n\tjose.EdDSA,\n}\n"
  },
  {
    "path": "vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go",
    "content": "package oidc\n\nimport (\n\t\"context\"\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/rsa\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"sync\"\n\n\tjose \"github.com/go-jose/go-jose/v4\"\n)\n\n// StaticKeySet is a verifier that validates JWT against a static set of public keys.\ntype StaticKeySet struct {\n\t// PublicKeys used to verify the JWT. Supported types are *rsa.PublicKey and\n\t// *ecdsa.PublicKey.\n\tPublicKeys []crypto.PublicKey\n}\n\n// VerifySignature compares the signature against a static set of public keys.\nfunc (s *StaticKeySet) VerifySignature(ctx context.Context, jwt string) ([]byte, error) {\n\t// Algorithms are already checked by Verifier, so this parse method accepts\n\t// any algorithm.\n\tjws, err := jose.ParseSigned(jwt, allAlgs)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parsing jwt: %v\", err)\n\t}\n\tfor _, pub := range s.PublicKeys {\n\t\tswitch pub.(type) {\n\t\tcase *rsa.PublicKey:\n\t\tcase *ecdsa.PublicKey:\n\t\tcase ed25519.PublicKey:\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"invalid public key type provided: %T\", pub)\n\t\t}\n\t\tpayload, err := jws.Verify(pub)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\treturn payload, nil\n\t}\n\treturn nil, fmt.Errorf(\"no public keys able to verify jwt\")\n}\n\n// NewRemoteKeySet returns a KeySet that can validate JSON web tokens by using HTTP\n// GETs to fetch JSON web token sets hosted at a remote URL. This is automatically\n// used by NewProvider using the URLs returned by OpenID Connect discovery, but is\n// exposed for providers that don't support discovery or to prevent round trips to the\n// discovery URL.\n//\n// The returned KeySet is a long lived verifier that caches keys based on any\n// keys change. Reuse a common remote key set instead of creating new ones as needed.\nfunc NewRemoteKeySet(ctx context.Context, jwksURL string) *RemoteKeySet {\n\treturn newRemoteKeySet(ctx, jwksURL)\n}\n\nfunc newRemoteKeySet(ctx context.Context, jwksURL string) *RemoteKeySet {\n\treturn &RemoteKeySet{\n\t\tjwksURL: jwksURL,\n\t\t// For historical reasons, this package uses contexts for configuration, not just\n\t\t// cancellation. In hindsight, this was a bad idea.\n\t\t//\n\t\t// Attemps to reason about how cancels should work with background requests have\n\t\t// largely lead to confusion. Use the context here as a config bag-of-values and\n\t\t// ignore the cancel function.\n\t\tctx: context.WithoutCancel(ctx),\n\t}\n}\n\n// RemoteKeySet is a KeySet implementation that validates JSON web tokens against\n// a jwks_uri endpoint.\ntype RemoteKeySet struct {\n\tjwksURL string\n\n\t// Used for configuration. Cancelation is ignored.\n\tctx context.Context\n\n\t// guard all other fields\n\tmu sync.RWMutex\n\n\t// inflight suppresses parallel execution of updateKeys and allows\n\t// multiple goroutines to wait for its result.\n\tinflight *inflight\n\n\t// A set of cached keys.\n\tcachedKeys []jose.JSONWebKey\n}\n\n// inflight is used to wait on some in-flight request from multiple goroutines.\ntype inflight struct {\n\tdoneCh chan struct{}\n\n\tkeys []jose.JSONWebKey\n\terr  error\n}\n\nfunc newInflight() *inflight {\n\treturn &inflight{doneCh: make(chan struct{})}\n}\n\n// wait returns a channel that multiple goroutines can receive on. Once it returns\n// a value, the inflight request is done and result() can be inspected.\nfunc (i *inflight) wait() <-chan struct{} {\n\treturn i.doneCh\n}\n\n// done can only be called by a single goroutine. It records the result of the\n// inflight request and signals other goroutines that the result is safe to\n// inspect.\nfunc (i *inflight) done(keys []jose.JSONWebKey, err error) {\n\ti.keys = keys\n\ti.err = err\n\tclose(i.doneCh)\n}\n\n// result cannot be called until the wait() channel has returned a value.\nfunc (i *inflight) result() ([]jose.JSONWebKey, error) {\n\treturn i.keys, i.err\n}\n\n// paresdJWTKey is a context key that allows common setups to avoid parsing the\n// JWT twice. It holds a *jose.JSONWebSignature value.\nvar parsedJWTKey contextKey\n\n// VerifySignature validates a payload against a signature from the jwks_uri.\n//\n// Users MUST NOT call this method directly and should use an IDTokenVerifier\n// instead. This method skips critical validations such as 'alg' values and is\n// only exported to implement the KeySet interface.\nfunc (r *RemoteKeySet) VerifySignature(ctx context.Context, jwt string) ([]byte, error) {\n\tjws, ok := ctx.Value(parsedJWTKey).(*jose.JSONWebSignature)\n\tif !ok {\n\t\t// The algorithm values are already enforced by the Validator, which also sets\n\t\t// the context value above to pre-parsed signature.\n\t\t//\n\t\t// Practically, this codepath isn't called in normal use of this package, but\n\t\t// if it is, the algorithms have already been checked.\n\t\tvar err error\n\t\tjws, err = jose.ParseSigned(jwt, allAlgs)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"oidc: malformed jwt: %v\", err)\n\t\t}\n\t}\n\treturn r.verify(ctx, jws)\n}\n\nfunc (r *RemoteKeySet) verify(ctx context.Context, jws *jose.JSONWebSignature) ([]byte, error) {\n\t// We don't support JWTs signed with multiple signatures.\n\tkeyID := \"\"\n\tfor _, sig := range jws.Signatures {\n\t\tkeyID = sig.Header.KeyID\n\t\tbreak\n\t}\n\n\tkeys := r.keysFromCache()\n\tfor _, key := range keys {\n\t\tif keyID == \"\" || key.KeyID == keyID {\n\t\t\tif payload, err := jws.Verify(&key); err == nil {\n\t\t\t\treturn payload, nil\n\t\t\t}\n\t\t}\n\t}\n\n\t// If the kid doesn't match, check for new keys from the remote. This is the\n\t// strategy recommended by the spec.\n\t//\n\t// https://openid.net/specs/openid-connect-core-1_0.html#RotateSigKeys\n\tkeys, err := r.keysFromRemote(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"fetching keys %w\", err)\n\t}\n\n\tfor _, key := range keys {\n\t\tif keyID == \"\" || key.KeyID == keyID {\n\t\t\tif payload, err := jws.Verify(&key); err == nil {\n\t\t\t\treturn payload, nil\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, errors.New(\"failed to verify id token signature\")\n}\n\nfunc (r *RemoteKeySet) keysFromCache() (keys []jose.JSONWebKey) {\n\tr.mu.RLock()\n\tdefer r.mu.RUnlock()\n\treturn r.cachedKeys\n}\n\n// keysFromRemote syncs the key set from the remote set, records the values in the\n// cache, and returns the key set.\nfunc (r *RemoteKeySet) keysFromRemote(ctx context.Context) ([]jose.JSONWebKey, error) {\n\t// Need to lock to inspect the inflight request field.\n\tr.mu.Lock()\n\t// If there's not a current inflight request, create one.\n\tif r.inflight == nil {\n\t\tr.inflight = newInflight()\n\n\t\t// This goroutine has exclusive ownership over the current inflight\n\t\t// request. It releases the resource by nil'ing the inflight field\n\t\t// once the goroutine is done.\n\t\tgo func() {\n\t\t\t// Sync keys and finish inflight when that's done.\n\t\t\tkeys, err := r.updateKeys()\n\n\t\t\tr.inflight.done(keys, err)\n\n\t\t\t// Lock to update the keys and indicate that there is no longer an\n\t\t\t// inflight request.\n\t\t\tr.mu.Lock()\n\t\t\tdefer r.mu.Unlock()\n\n\t\t\tif err == nil {\n\t\t\t\tr.cachedKeys = keys\n\t\t\t}\n\n\t\t\t// Free inflight so a different request can run.\n\t\t\tr.inflight = nil\n\t\t}()\n\t}\n\tinflight := r.inflight\n\tr.mu.Unlock()\n\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn nil, ctx.Err()\n\tcase <-inflight.wait():\n\t\treturn inflight.result()\n\t}\n}\n\nfunc (r *RemoteKeySet) updateKeys() ([]jose.JSONWebKey, error) {\n\treq, err := http.NewRequest(\"GET\", r.jwksURL, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"oidc: can't create request: %v\", err)\n\t}\n\n\tresp, err := doRequest(r.ctx, req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"oidc: get keys failed %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to read response body: %v\", err)\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"oidc: get keys failed: %s %s\", resp.Status, body)\n\t}\n\n\tvar keySet jose.JSONWebKeySet\n\terr = unmarshalResp(resp, body, &keySet)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"oidc: failed to decode keys: %v %s\", err, body)\n\t}\n\treturn keySet.Keys, nil\n}\n"
  },
  {
    "path": "vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go",
    "content": "// Package oidc implements OpenID Connect client logic for the golang.org/x/oauth2 package.\npackage oidc\n\nimport (\n\t\"context\"\n\t\"crypto/sha256\"\n\t\"crypto/sha512\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"hash\"\n\t\"io\"\n\t\"mime\"\n\t\"net/http\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"golang.org/x/oauth2\"\n)\n\nconst (\n\t// ScopeOpenID is the mandatory scope for all OpenID Connect OAuth2 requests.\n\tScopeOpenID = \"openid\"\n\n\t// ScopeOfflineAccess is an optional scope defined by OpenID Connect for requesting\n\t// OAuth2 refresh tokens.\n\t//\n\t// Support for this scope differs between OpenID Connect providers. For instance\n\t// Google rejects it, favoring appending \"access_type=offline\" as part of the\n\t// authorization request instead.\n\t//\n\t// See: https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess\n\tScopeOfflineAccess = \"offline_access\"\n)\n\nvar (\n\terrNoAtHash      = errors.New(\"id token did not have an access token hash\")\n\terrInvalidAtHash = errors.New(\"access token hash does not match value in ID token\")\n)\n\ntype contextKey int\n\nvar issuerURLKey contextKey\n\n// ClientContext returns a new Context that carries the provided HTTP client.\n//\n// This method sets the same context key used by the golang.org/x/oauth2 package,\n// so the returned context works for that package too.\n//\n//\tmyClient := &http.Client{}\n//\tctx := oidc.ClientContext(parentContext, myClient)\n//\n//\t// This will use the custom client\n//\tprovider, err := oidc.NewProvider(ctx, \"https://accounts.example.com\")\nfunc ClientContext(ctx context.Context, client *http.Client) context.Context {\n\treturn context.WithValue(ctx, oauth2.HTTPClient, client)\n}\n\nfunc getClient(ctx context.Context) *http.Client {\n\tif c, ok := ctx.Value(oauth2.HTTPClient).(*http.Client); ok {\n\t\treturn c\n\t}\n\treturn nil\n}\n\n// InsecureIssuerURLContext allows discovery to work when the issuer_url reported\n// by upstream is mismatched with the discovery URL. This is meant for integration\n// with off-spec providers such as Azure.\n//\n//\tdiscoveryBaseURL := \"https://login.microsoftonline.com/organizations/v2.0\"\n//\tissuerURL := \"https://login.microsoftonline.com/my-tenantid/v2.0\"\n//\n//\tctx := oidc.InsecureIssuerURLContext(parentContext, issuerURL)\n//\n//\t// Provider will be discovered with the discoveryBaseURL, but use issuerURL\n//\t// for future issuer validation.\n//\tprovider, err := oidc.NewProvider(ctx, discoveryBaseURL)\n//\n// This is insecure because validating the correct issuer is critical for multi-tenant\n// providers. Any overrides here MUST be carefully reviewed.\nfunc InsecureIssuerURLContext(ctx context.Context, issuerURL string) context.Context {\n\treturn context.WithValue(ctx, issuerURLKey, issuerURL)\n}\n\nfunc doRequest(ctx context.Context, req *http.Request) (*http.Response, error) {\n\tclient := http.DefaultClient\n\tif c := getClient(ctx); c != nil {\n\t\tclient = c\n\t}\n\treturn client.Do(req.WithContext(ctx))\n}\n\n// Provider represents an OpenID Connect server's configuration.\ntype Provider struct {\n\tissuer        string\n\tauthURL       string\n\ttokenURL      string\n\tdeviceAuthURL string\n\tuserInfoURL   string\n\tjwksURL       string\n\talgorithms    []string\n\n\t// Raw claims returned by the server.\n\trawClaims []byte\n\n\t// Guards all of the following fields.\n\tmu sync.Mutex\n\t// HTTP client specified from the initial NewProvider request. This is used\n\t// when creating the common key set.\n\tclient *http.Client\n\t// A key set that uses context.Background() and is shared between all code paths\n\t// that don't have a convinent way of supplying a unique context.\n\tcommonRemoteKeySet KeySet\n}\n\nfunc (p *Provider) remoteKeySet() KeySet {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tif p.commonRemoteKeySet == nil {\n\t\tctx := context.Background()\n\t\tif p.client != nil {\n\t\t\tctx = ClientContext(ctx, p.client)\n\t\t}\n\t\tp.commonRemoteKeySet = NewRemoteKeySet(ctx, p.jwksURL)\n\t}\n\treturn p.commonRemoteKeySet\n}\n\ntype providerJSON struct {\n\tIssuer        string   `json:\"issuer\"`\n\tAuthURL       string   `json:\"authorization_endpoint\"`\n\tTokenURL      string   `json:\"token_endpoint\"`\n\tDeviceAuthURL string   `json:\"device_authorization_endpoint\"`\n\tJWKSURL       string   `json:\"jwks_uri\"`\n\tUserInfoURL   string   `json:\"userinfo_endpoint\"`\n\tAlgorithms    []string `json:\"id_token_signing_alg_values_supported\"`\n}\n\n// supportedAlgorithms is a list of algorithms explicitly supported by this\n// package. If a provider supports other algorithms, such as HS256 or none,\n// those values won't be passed to the IDTokenVerifier.\nvar supportedAlgorithms = map[string]bool{\n\tRS256: true,\n\tRS384: true,\n\tRS512: true,\n\tES256: true,\n\tES384: true,\n\tES512: true,\n\tPS256: true,\n\tPS384: true,\n\tPS512: true,\n\tEdDSA: true,\n}\n\n// ProviderConfig allows direct creation of a [Provider] from metadata\n// configuration. This is intended for interop with providers that don't support\n// discovery, or host the JSON discovery document at an off-spec path.\n//\n// The ProviderConfig struct specifies JSON struct tags to support document\n// parsing.\n//\n//\t// Directly fetch the metadata document.\n//\tresp, err := http.Get(\"https://login.example.com/custom-metadata-path\")\n//\tif err != nil {\n//\t\t// ...\n//\t}\n//\tdefer resp.Body.Close()\n//\n//\t// Parse config from JSON metadata.\n//\tconfig := &oidc.ProviderConfig{}\n//\tif err := json.NewDecoder(resp.Body).Decode(config); err != nil {\n//\t\t// ...\n//\t}\n//\tp := config.NewProvider(context.Background())\n//\n// For providers that implement discovery, use [NewProvider] instead.\n//\n// See: https://openid.net/specs/openid-connect-discovery-1_0.html\ntype ProviderConfig struct {\n\t// IssuerURL is the identity of the provider, and the string it uses to sign\n\t// ID tokens with. For example \"https://accounts.google.com\". This value MUST\n\t// match ID tokens exactly.\n\tIssuerURL string `json:\"issuer\"`\n\t// AuthURL is the endpoint used by the provider to support the OAuth 2.0\n\t// authorization endpoint.\n\tAuthURL string `json:\"authorization_endpoint\"`\n\t// TokenURL is the endpoint used by the provider to support the OAuth 2.0\n\t// token endpoint.\n\tTokenURL string `json:\"token_endpoint\"`\n\t// DeviceAuthURL is the endpoint used by the provider to support the OAuth 2.0\n\t// device authorization endpoint.\n\tDeviceAuthURL string `json:\"device_authorization_endpoint\"`\n\t// UserInfoURL is the endpoint used by the provider to support the OpenID\n\t// Connect UserInfo flow.\n\t//\n\t// https://openid.net/specs/openid-connect-core-1_0.html#UserInfo\n\tUserInfoURL string `json:\"userinfo_endpoint\"`\n\t// JWKSURL is the endpoint used by the provider to advertise public keys to\n\t// verify issued ID tokens. This endpoint is polled as new keys are made\n\t// available.\n\tJWKSURL string `json:\"jwks_uri\"`\n\n\t// Algorithms, if provided, indicate a list of JWT algorithms allowed to sign\n\t// ID tokens. If not provided, this defaults to the algorithms advertised by\n\t// the JWK endpoint, then the set of algorithms supported by this package.\n\tAlgorithms []string `json:\"id_token_signing_alg_values_supported\"`\n}\n\n// NewProvider initializes a provider from a set of endpoints, rather than\n// through discovery.\n//\n// The provided context is only used for [http.Client] configuration through\n// [ClientContext], not cancelation.\nfunc (p *ProviderConfig) NewProvider(ctx context.Context) *Provider {\n\treturn &Provider{\n\t\tissuer:        p.IssuerURL,\n\t\tauthURL:       p.AuthURL,\n\t\ttokenURL:      p.TokenURL,\n\t\tdeviceAuthURL: p.DeviceAuthURL,\n\t\tuserInfoURL:   p.UserInfoURL,\n\t\tjwksURL:       p.JWKSURL,\n\t\talgorithms:    p.Algorithms,\n\t\tclient:        getClient(ctx),\n\t}\n}\n\n// NewProvider uses the OpenID Connect discovery mechanism to construct a Provider.\n// The issuer is the URL identifier for the service. For example: \"https://accounts.google.com\"\n// or \"https://login.salesforce.com\".\n//\n// OpenID Connect providers that don't implement discovery or host the discovery\n// document at a non-spec complaint path (such as requiring a URL parameter),\n// should use [ProviderConfig] instead.\n//\n// See: https://openid.net/specs/openid-connect-discovery-1_0.html\nfunc NewProvider(ctx context.Context, issuer string) (*Provider, error) {\n\twellKnown := strings.TrimSuffix(issuer, \"/\") + \"/.well-known/openid-configuration\"\n\treq, err := http.NewRequest(\"GET\", wellKnown, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tresp, err := doRequest(ctx, req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to read response body: %v\", err)\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"%s: %s\", resp.Status, body)\n\t}\n\n\tvar p providerJSON\n\terr = unmarshalResp(resp, body, &p)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"oidc: failed to decode provider discovery object: %v\", err)\n\t}\n\n\tissuerURL, skipIssuerValidation := ctx.Value(issuerURLKey).(string)\n\tif !skipIssuerValidation {\n\t\tissuerURL = issuer\n\t}\n\tif p.Issuer != issuerURL && !skipIssuerValidation {\n\t\treturn nil, fmt.Errorf(\"oidc: issuer URL provided to client (%q) did not match the issuer URL returned by provider (%q)\", issuer, p.Issuer)\n\t}\n\tvar algs []string\n\tfor _, a := range p.Algorithms {\n\t\tif supportedAlgorithms[a] {\n\t\t\talgs = append(algs, a)\n\t\t}\n\t}\n\treturn &Provider{\n\t\tissuer:        issuerURL,\n\t\tauthURL:       p.AuthURL,\n\t\ttokenURL:      p.TokenURL,\n\t\tdeviceAuthURL: p.DeviceAuthURL,\n\t\tuserInfoURL:   p.UserInfoURL,\n\t\tjwksURL:       p.JWKSURL,\n\t\talgorithms:    algs,\n\t\trawClaims:     body,\n\t\tclient:        getClient(ctx),\n\t}, nil\n}\n\n// Claims unmarshals raw fields returned by the server during discovery.\n//\n//\tvar claims struct {\n//\t    ScopesSupported []string `json:\"scopes_supported\"`\n//\t    ClaimsSupported []string `json:\"claims_supported\"`\n//\t}\n//\n//\tif err := provider.Claims(&claims); err != nil {\n//\t    // handle unmarshaling error\n//\t}\n//\n// For a list of fields defined by the OpenID Connect spec see:\n// https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata\nfunc (p *Provider) Claims(v interface{}) error {\n\tif p.rawClaims == nil {\n\t\treturn errors.New(\"oidc: claims not set\")\n\t}\n\treturn json.Unmarshal(p.rawClaims, v)\n}\n\n// Endpoint returns the OAuth2 auth and token endpoints for the given provider.\nfunc (p *Provider) Endpoint() oauth2.Endpoint {\n\treturn oauth2.Endpoint{AuthURL: p.authURL, DeviceAuthURL: p.deviceAuthURL, TokenURL: p.tokenURL}\n}\n\n// UserInfoEndpoint returns the OpenID Connect userinfo endpoint for the given\n// provider.\nfunc (p *Provider) UserInfoEndpoint() string {\n\treturn p.userInfoURL\n}\n\n// UserInfo represents the OpenID Connect userinfo claims.\ntype UserInfo struct {\n\tSubject       string `json:\"sub\"`\n\tProfile       string `json:\"profile\"`\n\tEmail         string `json:\"email\"`\n\tEmailVerified bool   `json:\"email_verified\"`\n\n\tclaims []byte\n}\n\ntype userInfoRaw struct {\n\tSubject string `json:\"sub\"`\n\tProfile string `json:\"profile\"`\n\tEmail   string `json:\"email\"`\n\t// Handle providers that return email_verified as a string\n\t// https://forums.aws.amazon.com/thread.jspa?messageID=949441&#949441 and\n\t// https://discuss.elastic.co/t/openid-error-after-authenticating-against-aws-cognito/206018/11\n\tEmailVerified stringAsBool `json:\"email_verified\"`\n}\n\n// Claims unmarshals the raw JSON object claims into the provided object.\nfunc (u *UserInfo) Claims(v interface{}) error {\n\tif u.claims == nil {\n\t\treturn errors.New(\"oidc: claims not set\")\n\t}\n\treturn json.Unmarshal(u.claims, v)\n}\n\n// UserInfo uses the token source to query the provider's user info endpoint.\nfunc (p *Provider) UserInfo(ctx context.Context, tokenSource oauth2.TokenSource) (*UserInfo, error) {\n\tif p.userInfoURL == \"\" {\n\t\treturn nil, errors.New(\"oidc: user info endpoint is not supported by this provider\")\n\t}\n\n\treq, err := http.NewRequest(\"GET\", p.userInfoURL, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"oidc: create GET request: %v\", err)\n\t}\n\n\ttoken, err := tokenSource.Token()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"oidc: get access token: %v\", err)\n\t}\n\ttoken.SetAuthHeader(req)\n\n\tresp, err := doRequest(ctx, req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"%s: %s\", resp.Status, body)\n\t}\n\n\tct := resp.Header.Get(\"Content-Type\")\n\tmediaType, _, parseErr := mime.ParseMediaType(ct)\n\tif parseErr == nil && mediaType == \"application/jwt\" {\n\t\tpayload, err := p.remoteKeySet().VerifySignature(ctx, string(body))\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"oidc: invalid userinfo jwt signature %v\", err)\n\t\t}\n\t\tbody = payload\n\t}\n\n\tvar userInfo userInfoRaw\n\tif err := json.Unmarshal(body, &userInfo); err != nil {\n\t\treturn nil, fmt.Errorf(\"oidc: failed to decode userinfo: %v\", err)\n\t}\n\treturn &UserInfo{\n\t\tSubject:       userInfo.Subject,\n\t\tProfile:       userInfo.Profile,\n\t\tEmail:         userInfo.Email,\n\t\tEmailVerified: bool(userInfo.EmailVerified),\n\t\tclaims:        body,\n\t}, nil\n}\n\n// IDToken is an OpenID Connect extension that provides a predictable representation\n// of an authorization event.\n//\n// The ID Token only holds fields OpenID Connect requires. To access additional\n// claims returned by the server, use the Claims method.\ntype IDToken struct {\n\t// The URL of the server which issued this token. OpenID Connect\n\t// requires this value always be identical to the URL used for\n\t// initial discovery.\n\t//\n\t// Note: Because of a known issue with Google Accounts' implementation\n\t// this value may differ when using Google.\n\t//\n\t// See: https://developers.google.com/identity/protocols/OpenIDConnect#obtainuserinfo\n\tIssuer string\n\n\t// The client ID, or set of client IDs, that this token is issued for. For\n\t// common uses, this is the client that initialized the auth flow.\n\t//\n\t// This package ensures the audience contains an expected value.\n\tAudience []string\n\n\t// A unique string which identifies the end user.\n\tSubject string\n\n\t// Expiry of the token. Ths package will not process tokens that have\n\t// expired unless that validation is explicitly turned off.\n\tExpiry time.Time\n\t// When the token was issued by the provider.\n\tIssuedAt time.Time\n\n\t// Initial nonce provided during the authentication redirect.\n\t//\n\t// This package does NOT provided verification on the value of this field\n\t// and it's the user's responsibility to ensure it contains a valid value.\n\tNonce string\n\n\t// at_hash claim, if set in the ID token. Callers can verify an access token\n\t// that corresponds to the ID token using the VerifyAccessToken method.\n\tAccessTokenHash string\n\n\t// signature algorithm used for ID token, needed to compute a verification hash of an\n\t// access token\n\tsigAlgorithm string\n\n\t// Raw payload of the id_token.\n\tclaims []byte\n\n\t// Map of distributed claim names to claim sources\n\tdistributedClaims map[string]claimSource\n}\n\n// Claims unmarshals the raw JSON payload of the ID Token into a provided struct.\n//\n//\tidToken, err := idTokenVerifier.Verify(rawIDToken)\n//\tif err != nil {\n//\t\t// handle error\n//\t}\n//\tvar claims struct {\n//\t\tEmail         string `json:\"email\"`\n//\t\tEmailVerified bool   `json:\"email_verified\"`\n//\t}\n//\tif err := idToken.Claims(&claims); err != nil {\n//\t\t// handle error\n//\t}\nfunc (i *IDToken) Claims(v interface{}) error {\n\tif i.claims == nil {\n\t\treturn errors.New(\"oidc: claims not set\")\n\t}\n\treturn json.Unmarshal(i.claims, v)\n}\n\n// VerifyAccessToken verifies that the hash of the access token that corresponds to the iD token\n// matches the hash in the id token. It returns an error if the hashes  don't match.\n// It is the caller's responsibility to ensure that the optional access token hash is present for the ID token\n// before calling this method. See https://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken\nfunc (i *IDToken) VerifyAccessToken(accessToken string) error {\n\tif i.AccessTokenHash == \"\" {\n\t\treturn errNoAtHash\n\t}\n\tvar h hash.Hash\n\tswitch i.sigAlgorithm {\n\tcase RS256, ES256, PS256:\n\t\th = sha256.New()\n\tcase RS384, ES384, PS384:\n\t\th = sha512.New384()\n\tcase RS512, ES512, PS512, EdDSA:\n\t\th = sha512.New()\n\tdefault:\n\t\treturn fmt.Errorf(\"oidc: unsupported signing algorithm %q\", i.sigAlgorithm)\n\t}\n\th.Write([]byte(accessToken)) // hash documents that Write will never return an error\n\tsum := h.Sum(nil)[:h.Size()/2]\n\tactual := base64.RawURLEncoding.EncodeToString(sum)\n\tif actual != i.AccessTokenHash {\n\t\treturn errInvalidAtHash\n\t}\n\treturn nil\n}\n\ntype idToken struct {\n\tIssuer       string                 `json:\"iss\"`\n\tSubject      string                 `json:\"sub\"`\n\tAudience     audience               `json:\"aud\"`\n\tExpiry       jsonTime               `json:\"exp\"`\n\tIssuedAt     jsonTime               `json:\"iat\"`\n\tNotBefore    *jsonTime              `json:\"nbf\"`\n\tNonce        string                 `json:\"nonce\"`\n\tAtHash       string                 `json:\"at_hash\"`\n\tClaimNames   map[string]string      `json:\"_claim_names\"`\n\tClaimSources map[string]claimSource `json:\"_claim_sources\"`\n}\n\ntype claimSource struct {\n\tEndpoint    string `json:\"endpoint\"`\n\tAccessToken string `json:\"access_token\"`\n}\n\ntype stringAsBool bool\n\nfunc (sb *stringAsBool) UnmarshalJSON(b []byte) error {\n\tswitch string(b) {\n\tcase \"true\", `\"true\"`:\n\t\t*sb = true\n\tcase \"false\", `\"false\"`:\n\t\t*sb = false\n\tdefault:\n\t\treturn errors.New(\"invalid value for boolean\")\n\t}\n\treturn nil\n}\n\ntype audience []string\n\nfunc (a *audience) UnmarshalJSON(b []byte) error {\n\tvar s string\n\tif json.Unmarshal(b, &s) == nil {\n\t\t*a = audience{s}\n\t\treturn nil\n\t}\n\tvar auds []string\n\tif err := json.Unmarshal(b, &auds); err != nil {\n\t\treturn err\n\t}\n\t*a = auds\n\treturn nil\n}\n\ntype jsonTime time.Time\n\nfunc (j *jsonTime) UnmarshalJSON(b []byte) error {\n\tvar n json.Number\n\tif err := json.Unmarshal(b, &n); err != nil {\n\t\treturn err\n\t}\n\tvar unix int64\n\n\tif t, err := n.Int64(); err == nil {\n\t\tunix = t\n\t} else {\n\t\tf, err := n.Float64()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tunix = int64(f)\n\t}\n\t*j = jsonTime(time.Unix(unix, 0))\n\treturn nil\n}\n\nfunc unmarshalResp(r *http.Response, body []byte, v interface{}) error {\n\terr := json.Unmarshal(body, &v)\n\tif err == nil {\n\t\treturn nil\n\t}\n\tct := r.Header.Get(\"Content-Type\")\n\tmediaType, _, parseErr := mime.ParseMediaType(ct)\n\tif parseErr == nil && mediaType == \"application/json\" {\n\t\treturn fmt.Errorf(\"got Content-Type = application/json, but could not unmarshal as JSON: %v\", err)\n\t}\n\treturn fmt.Errorf(\"expected Content-Type = application/json, got %q: %v\", ct, err)\n}\n"
  },
  {
    "path": "vendor/github.com/coreos/go-oidc/v3/oidc/verify.go",
    "content": "package oidc\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n\n\tjose \"github.com/go-jose/go-jose/v4\"\n\t\"golang.org/x/oauth2\"\n)\n\nconst (\n\tissuerGoogleAccounts         = \"https://accounts.google.com\"\n\tissuerGoogleAccountsNoScheme = \"accounts.google.com\"\n)\n\n// TokenExpiredError indicates that Verify failed because the token was expired. This\n// error does NOT indicate that the token is not also invalid for other reasons. Other\n// checks might have failed if the expiration check had not failed.\ntype TokenExpiredError struct {\n\t// Expiry is the time when the token expired.\n\tExpiry time.Time\n}\n\nfunc (e *TokenExpiredError) Error() string {\n\treturn fmt.Sprintf(\"oidc: token is expired (Token Expiry: %v)\", e.Expiry)\n}\n\n// KeySet is a set of publc JSON Web Keys that can be used to validate the signature\n// of JSON web tokens. This is expected to be backed by a remote key set through\n// provider metadata discovery or an in-memory set of keys delivered out-of-band.\ntype KeySet interface {\n\t// VerifySignature parses the JSON web token, verifies the signature, and returns\n\t// the raw payload. Header and claim fields are validated by other parts of the\n\t// package. For example, the KeySet does not need to check values such as signature\n\t// algorithm, issuer, and audience since the IDTokenVerifier validates these values\n\t// independently.\n\t//\n\t// If VerifySignature makes HTTP requests to verify the token, it's expected to\n\t// use any HTTP client associated with the context through ClientContext.\n\tVerifySignature(ctx context.Context, jwt string) (payload []byte, err error)\n}\n\n// IDTokenVerifier provides verification for ID Tokens.\ntype IDTokenVerifier struct {\n\tkeySet KeySet\n\tconfig *Config\n\tissuer string\n}\n\n// NewVerifier returns a verifier manually constructed from a key set and issuer URL.\n//\n// It's easier to use provider discovery to construct an IDTokenVerifier than creating\n// one directly. This method is intended to be used with provider that don't support\n// metadata discovery, or avoiding round trips when the key set URL is already known.\n//\n// This constructor can be used to create a verifier directly using the issuer URL and\n// JSON Web Key Set URL without using discovery:\n//\n//\tkeySet := oidc.NewRemoteKeySet(ctx, \"https://www.googleapis.com/oauth2/v3/certs\")\n//\tverifier := oidc.NewVerifier(\"https://accounts.google.com\", keySet, config)\n//\n// Or a static key set (e.g. for testing):\n//\n//\tkeySet := &oidc.StaticKeySet{PublicKeys: []crypto.PublicKey{pub1, pub2}}\n//\tverifier := oidc.NewVerifier(\"https://accounts.google.com\", keySet, config)\nfunc NewVerifier(issuerURL string, keySet KeySet, config *Config) *IDTokenVerifier {\n\treturn &IDTokenVerifier{keySet: keySet, config: config, issuer: issuerURL}\n}\n\n// Config is the configuration for an IDTokenVerifier.\ntype Config struct {\n\t// Expected audience of the token. For a majority of the cases this is expected to be\n\t// the ID of the client that initialized the login flow. It may occasionally differ if\n\t// the provider supports the authorizing party (azp) claim.\n\t//\n\t// If not provided, users must explicitly set SkipClientIDCheck.\n\tClientID string\n\t// If specified, only this set of algorithms may be used to sign the JWT.\n\t//\n\t// If the IDTokenVerifier is created from a provider with (*Provider).Verifier, this\n\t// defaults to the set of algorithms the provider supports. Otherwise this values\n\t// defaults to RS256.\n\tSupportedSigningAlgs []string\n\n\t// If true, no ClientID check performed. Must be true if ClientID field is empty.\n\tSkipClientIDCheck bool\n\t// If true, token expiry is not checked.\n\tSkipExpiryCheck bool\n\n\t// SkipIssuerCheck is intended for specialized cases where the the caller wishes to\n\t// defer issuer validation. When enabled, callers MUST independently verify the Token's\n\t// Issuer is a known good value.\n\t//\n\t// Mismatched issuers often indicate client mis-configuration. If mismatches are\n\t// unexpected, evaluate if the provided issuer URL is incorrect instead of enabling\n\t// this option.\n\tSkipIssuerCheck bool\n\n\t// Time function to check Token expiry. Defaults to time.Now\n\tNow func() time.Time\n\n\t// InsecureSkipSignatureCheck causes this package to skip JWT signature validation.\n\t// It's intended for special cases where providers (such as Azure), use the \"none\"\n\t// algorithm.\n\t//\n\t// This option can only be enabled safely when the ID Token is received directly\n\t// from the provider after the token exchange.\n\t//\n\t// This option MUST NOT be used when receiving an ID Token from sources other\n\t// than the token endpoint.\n\tInsecureSkipSignatureCheck bool\n}\n\n// VerifierContext returns an IDTokenVerifier that uses the provider's key set to\n// verify JWTs. As opposed to Verifier, the context is used to configure requests\n// to the upstream JWKs endpoint. The provided context's cancellation is ignored.\nfunc (p *Provider) VerifierContext(ctx context.Context, config *Config) *IDTokenVerifier {\n\treturn p.newVerifier(NewRemoteKeySet(ctx, p.jwksURL), config)\n}\n\n// Verifier returns an IDTokenVerifier that uses the provider's key set to verify JWTs.\n//\n// The returned verifier uses a background context for all requests to the upstream\n// JWKs endpoint. To control that context, use VerifierContext instead.\nfunc (p *Provider) Verifier(config *Config) *IDTokenVerifier {\n\treturn p.newVerifier(p.remoteKeySet(), config)\n}\n\nfunc (p *Provider) newVerifier(keySet KeySet, config *Config) *IDTokenVerifier {\n\tif len(config.SupportedSigningAlgs) == 0 && len(p.algorithms) > 0 {\n\t\t// Make a copy so we don't modify the config values.\n\t\tcp := &Config{}\n\t\t*cp = *config\n\t\tcp.SupportedSigningAlgs = p.algorithms\n\t\tconfig = cp\n\t}\n\treturn NewVerifier(p.issuer, keySet, config)\n}\n\nfunc contains(sli []string, ele string) bool {\n\tfor _, s := range sli {\n\t\tif s == ele {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Returns the Claims from the distributed JWT token\nfunc resolveDistributedClaim(ctx context.Context, verifier *IDTokenVerifier, src claimSource) ([]byte, error) {\n\treq, err := http.NewRequest(\"GET\", src.Endpoint, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"malformed request: %v\", err)\n\t}\n\tif src.AccessToken != \"\" {\n\t\treq.Header.Set(\"Authorization\", \"Bearer \"+src.AccessToken)\n\t}\n\n\tresp, err := doRequest(ctx, req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"oidc: Request to endpoint failed: %v\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to read response body: %v\", err)\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"oidc: request failed: %v\", resp.StatusCode)\n\t}\n\n\ttoken, err := verifier.Verify(ctx, string(body))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"malformed response body: %v\", err)\n\t}\n\n\treturn token.claims, nil\n}\n\n// Verify parses a raw ID Token, verifies it's been signed by the provider, performs\n// any additional checks depending on the Config, and returns the payload.\n//\n// Verify does NOT do nonce validation, which is the callers responsibility.\n//\n// See: https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation\n//\n//\toauth2Token, err := oauth2Config.Exchange(ctx, r.URL.Query().Get(\"code\"))\n//\tif err != nil {\n//\t    // handle error\n//\t}\n//\n//\t// Extract the ID Token from oauth2 token.\n//\trawIDToken, ok := oauth2Token.Extra(\"id_token\").(string)\n//\tif !ok {\n//\t    // handle error\n//\t}\n//\n//\ttoken, err := verifier.Verify(ctx, rawIDToken)\nfunc (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDToken, error) {\n\tvar supportedSigAlgs []jose.SignatureAlgorithm\n\tfor _, alg := range v.config.SupportedSigningAlgs {\n\t\tsupportedSigAlgs = append(supportedSigAlgs, jose.SignatureAlgorithm(alg))\n\t}\n\tif len(supportedSigAlgs) == 0 {\n\t\t// If no algorithms were specified by both the config and discovery, default\n\t\t// to the one mandatory algorithm \"RS256\".\n\t\tsupportedSigAlgs = []jose.SignatureAlgorithm{jose.RS256}\n\t}\n\tif v.config.InsecureSkipSignatureCheck {\n\t\t// \"none\" is a required value to even parse a JWT with the \"none\" algorithm\n\t\t// using go-jose.\n\t\tsupportedSigAlgs = append(supportedSigAlgs, \"none\")\n\t}\n\n\t// Parse and verify the signature first. This at least forces the user to have\n\t// a valid, signed ID token before we do any other processing.\n\tjws, err := jose.ParseSigned(rawIDToken, supportedSigAlgs)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"oidc: malformed jwt: %v\", err)\n\t}\n\tswitch len(jws.Signatures) {\n\tcase 0:\n\t\treturn nil, fmt.Errorf(\"oidc: id token not signed\")\n\tcase 1:\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"oidc: multiple signatures on id token not supported\")\n\t}\n\tsig := jws.Signatures[0]\n\n\tvar payload []byte\n\tif v.config.InsecureSkipSignatureCheck {\n\t\t// Yolo mode.\n\t\tpayload = jws.UnsafePayloadWithoutVerification()\n\t} else {\n\t\t// The JWT is attached here for the happy path to avoid the verifier from\n\t\t// having to parse the JWT twice.\n\t\tctx = context.WithValue(ctx, parsedJWTKey, jws)\n\t\tpayload, err = v.keySet.VerifySignature(ctx, rawIDToken)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to verify signature: %v\", err)\n\t\t}\n\t}\n\tvar token idToken\n\tif err := json.Unmarshal(payload, &token); err != nil {\n\t\treturn nil, fmt.Errorf(\"oidc: failed to unmarshal claims: %v\", err)\n\t}\n\n\tdistributedClaims := make(map[string]claimSource)\n\n\t//step through the token to map claim names to claim sources\"\n\tfor cn, src := range token.ClaimNames {\n\t\tif src == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"oidc: failed to obtain source from claim name\")\n\t\t}\n\t\ts, ok := token.ClaimSources[src]\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"oidc: source does not exist\")\n\t\t}\n\t\tdistributedClaims[cn] = s\n\t}\n\n\tt := &IDToken{\n\t\tIssuer:            token.Issuer,\n\t\tSubject:           token.Subject,\n\t\tAudience:          []string(token.Audience),\n\t\tExpiry:            time.Time(token.Expiry),\n\t\tIssuedAt:          time.Time(token.IssuedAt),\n\t\tNonce:             token.Nonce,\n\t\tAccessTokenHash:   token.AtHash,\n\t\tclaims:            payload,\n\t\tdistributedClaims: distributedClaims,\n\t\tsigAlgorithm:      sig.Header.Algorithm,\n\t}\n\n\t// Check issuer.\n\tif !v.config.SkipIssuerCheck && t.Issuer != v.issuer {\n\t\t// Google sometimes returns \"accounts.google.com\" as the issuer claim instead of\n\t\t// the required \"https://accounts.google.com\". Detect this case and allow it only\n\t\t// for Google.\n\t\t//\n\t\t// We will not add hooks to let other providers go off spec like this.\n\t\tif !(v.issuer == issuerGoogleAccounts && t.Issuer == issuerGoogleAccountsNoScheme) {\n\t\t\treturn nil, fmt.Errorf(\"oidc: id token issued by a different provider, expected %q got %q\", v.issuer, t.Issuer)\n\t\t}\n\t}\n\n\t// If a client ID has been provided, make sure it's part of the audience. SkipClientIDCheck must be true if ClientID is empty.\n\t//\n\t// This check DOES NOT ensure that the ClientID is the party to which the ID Token was issued (i.e. Authorized party).\n\tif !v.config.SkipClientIDCheck {\n\t\tif v.config.ClientID != \"\" {\n\t\t\tif !contains(t.Audience, v.config.ClientID) {\n\t\t\t\treturn nil, fmt.Errorf(\"oidc: expected audience %q got %q\", v.config.ClientID, t.Audience)\n\t\t\t}\n\t\t} else {\n\t\t\treturn nil, fmt.Errorf(\"oidc: invalid configuration, clientID must be provided or SkipClientIDCheck must be set\")\n\t\t}\n\t}\n\n\t// If a SkipExpiryCheck is false, make sure token is not expired.\n\tif !v.config.SkipExpiryCheck {\n\t\tnow := time.Now\n\t\tif v.config.Now != nil {\n\t\t\tnow = v.config.Now\n\t\t}\n\t\tnowTime := now()\n\n\t\tif t.Expiry.Before(nowTime) {\n\t\t\treturn nil, &TokenExpiredError{Expiry: t.Expiry}\n\t\t}\n\n\t\t// If nbf claim is provided in token, ensure that it is indeed in the past.\n\t\tif token.NotBefore != nil {\n\t\t\tnbfTime := time.Time(*token.NotBefore)\n\t\t\t// Set to 5 minutes since this is what other OpenID Connect providers do to deal with clock skew.\n\t\t\t// https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/6.12.2/src/Microsoft.IdentityModel.Tokens/TokenValidationParameters.cs#L149-L153\n\t\t\tleeway := 5 * time.Minute\n\n\t\t\tif nowTime.Add(leeway).Before(nbfTime) {\n\t\t\t\treturn nil, fmt.Errorf(\"oidc: current time %v before the nbf (not before) time: %v\", nowTime, nbfTime)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn t, nil\n}\n\n// Nonce returns an auth code option which requires the ID Token created by the\n// OpenID Connect provider to contain the specified nonce.\nfunc Nonce(nonce string) oauth2.AuthCodeOption {\n\treturn oauth2.SetAuthURLParam(\"nonce\", nonce)\n}\n"
  },
  {
    "path": "vendor/github.com/coreos/go-systemd/v22/LICENSE",
    "content": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction, and\ndistribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by the copyright\nowner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all other entities\nthat control, are controlled by, or are under common control with that entity.\nFor the purposes of this definition, \"control\" means (i) the power, direct or\nindirect, to cause the direction or management of such entity, whether by\ncontract or otherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising\npermissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications, including\nbut not limited to software source code, documentation source, and configuration\nfiles.\n\n\"Object\" form shall mean any form resulting from mechanical transformation or\ntranslation of a Source form, including but not limited to compiled object code,\ngenerated documentation, and conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or Object form, made\navailable under the License, as indicated by a copyright notice that is included\nin or attached to the work (an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object form, that\nis based on (or derived from) the Work and for which the editorial revisions,\nannotations, elaborations, or other modifications represent, as a whole, an\noriginal work of authorship. For the purposes of this License, Derivative Works\nshall not include works that remain separable from, or merely link (or bind by\nname) to the interfaces of, the Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including the original version\nof the Work and any modifications or additions to that Work or Derivative Works\nthereof, that is intentionally submitted to Licensor for inclusion in the Work\nby the copyright owner or by an individual or Legal Entity authorized to submit\non behalf of the copyright owner. For the purposes of this definition,\n\"submitted\" means any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems, and\nissue tracking systems that are managed by, or on behalf of, the Licensor for\nthe purpose of discussing and improving the Work, but excluding communication\nthat is conspicuously marked or otherwise designated in writing by the copyright\nowner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf\nof whom a Contribution has been received by Licensor and subsequently\nincorporated within the Work.\n\n2. Grant of Copyright License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable copyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the Work and such\nDerivative Works in Source or Object form.\n\n3. Grant of Patent License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable (except as stated in this section) patent license to make, have\nmade, use, offer to sell, sell, import, and otherwise transfer the Work, where\nsuch license applies only to those patent claims licensable by such Contributor\nthat are necessarily infringed by their Contribution(s) alone or by combination\nof their Contribution(s) with the Work to which such Contribution(s) was\nsubmitted. If You institute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work or a\nContribution incorporated within the Work constitutes direct or contributory\npatent infringement, then any patent licenses granted to You under this License\nfor that Work shall terminate as of the date such litigation is filed.\n\n4. Redistribution.\n\nYou may reproduce and distribute copies of the Work or Derivative Works thereof\nin any medium, with or without modifications, and in Source or Object form,\nprovided that You meet the following conditions:\n\nYou must give any other recipients of the Work or Derivative Works a copy of\nthis License; and\nYou must cause any modified files to carry prominent notices stating that You\nchanged the files; and\nYou must retain, in the Source form of any Derivative Works that You distribute,\nall copyright, patent, trademark, and attribution notices from the Source form\nof the Work, excluding those notices that do not pertain to any part of the\nDerivative Works; and\nIf the Work includes a \"NOTICE\" text file as part of its distribution, then any\nDerivative Works that You distribute must include a readable copy of the\nattribution notices contained within such NOTICE file, excluding those notices\nthat do not pertain to any part of the Derivative Works, in at least one of the\nfollowing places: within a NOTICE text file distributed as part of the\nDerivative Works; within the Source form or documentation, if provided along\nwith the Derivative Works; or, within a display generated by the Derivative\nWorks, if and wherever such third-party notices normally appear. The contents of\nthe NOTICE file are for informational purposes only and do not modify the\nLicense. You may add Your own attribution notices within Derivative Works that\nYou distribute, alongside or as an addendum to the NOTICE text from the Work,\nprovided that such additional attribution notices cannot be construed as\nmodifying the License.\nYou may add Your own copyright statement to Your modifications and may provide\nadditional or different license terms and conditions for use, reproduction, or\ndistribution of Your modifications, or for any such Derivative Works as a whole,\nprovided Your use, reproduction, and distribution of the Work otherwise complies\nwith the conditions stated in this License.\n\n5. Submission of Contributions.\n\nUnless You explicitly state otherwise, any Contribution intentionally submitted\nfor inclusion in the Work by You to the Licensor shall be under the terms and\nconditions of this License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify the terms of\nany separate license agreement you may have executed with Licensor regarding\nsuch Contributions.\n\n6. Trademarks.\n\nThis License does not grant permission to use the trade names, trademarks,\nservice marks, or product names of the Licensor, except as required for\nreasonable and customary use in describing the origin of the Work and\nreproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty.\n\nUnless required by applicable law or agreed to in writing, Licensor provides the\nWork (and each Contributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,\nincluding, without limitation, any warranties or conditions of TITLE,\nNON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are\nsolely responsible for determining the appropriateness of using or\nredistributing the Work and assume any risks associated with Your exercise of\npermissions under this License.\n\n8. Limitation of Liability.\n\nIn no event and under no legal theory, whether in tort (including negligence),\ncontract, or otherwise, unless required by applicable law (such as deliberate\nand grossly negligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special, incidental,\nor consequential damages of any character arising as a result of this License or\nout of the use or inability to use the Work (including but not limited to\ndamages for loss of goodwill, work stoppage, computer failure or malfunction, or\nany and all other commercial damages or losses), even if such Contributor has\nbeen advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability.\n\nWhile redistributing the Work or Derivative Works thereof, You may choose to\noffer, and charge a fee for, acceptance of support, warranty, indemnity, or\nother liability obligations and/or rights consistent with this License. However,\nin accepting such obligations, You may act only on Your own behalf and on Your\nsole responsibility, not on behalf of any other Contributor, and only if You\nagree to indemnify, defend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason of your\naccepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work\n\nTo apply the Apache License to your work, attach the following boilerplate\nnotice, with the fields enclosed by brackets \"[]\" replaced with your own\nidentifying information. (Don't include the brackets!) The text should be\nenclosed in the appropriate comment syntax for the file format. We also\nrecommend that a file or class name and description of purpose be included on\nthe same \"printed page\" as the copyright notice for easier identification within\nthird-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/github.com/coreos/go-systemd/v22/NOTICE",
    "content": "CoreOS Project\nCopyright 2018 CoreOS, Inc\n\nThis product includes software developed at CoreOS, Inc.\n(http://www.coreos.com/).\n"
  },
  {
    "path": "vendor/github.com/coreos/go-systemd/v22/daemon/sdnotify.go",
    "content": "// Copyright 2014 Docker, Inc.\n// Copyright 2015-2018 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//    http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n\n// Package daemon provides a Go implementation of the sd_notify protocol.\n// It can be used to inform systemd of service start-up completion, watchdog\n// events, and other status changes.\n//\n// https://www.freedesktop.org/software/systemd/man/sd_notify.html#Description\npackage daemon\n\nimport (\n\t\"net\"\n\t\"os\"\n)\n\nconst (\n\t// SdNotifyReady tells the service manager that service startup is finished\n\t// or the service finished loading its configuration.\n\tSdNotifyReady = \"READY=1\"\n\n\t// SdNotifyStopping tells the service manager that the service is beginning\n\t// its shutdown.\n\tSdNotifyStopping = \"STOPPING=1\"\n\n\t// SdNotifyReloading tells the service manager that this service is\n\t// reloading its configuration. Note that you must call SdNotifyReady when\n\t// it completed reloading.\n\tSdNotifyReloading = \"RELOADING=1\"\n\n\t// SdNotifyWatchdog tells the service manager to update the watchdog\n\t// timestamp for the service.\n\tSdNotifyWatchdog = \"WATCHDOG=1\"\n)\n\n// SdNotify sends a message to the init daemon. It is common to ignore the error.\n// If `unsetEnvironment` is true, the environment variable `NOTIFY_SOCKET`\n// will be unconditionally unset.\n//\n// It returns one of the following:\n// (false, nil) - notification not supported (i.e. NOTIFY_SOCKET is unset)\n// (false, err) - notification supported, but failure happened (e.g. error connecting to NOTIFY_SOCKET or while sending data)\n// (true, nil) - notification supported, data has been sent\nfunc SdNotify(unsetEnvironment bool, state string) (bool, error) {\n\tsocketAddr := &net.UnixAddr{\n\t\tName: os.Getenv(\"NOTIFY_SOCKET\"),\n\t\tNet:  \"unixgram\",\n\t}\n\n\t// NOTIFY_SOCKET not set\n\tif socketAddr.Name == \"\" {\n\t\treturn false, nil\n\t}\n\n\tif unsetEnvironment {\n\t\tif err := os.Unsetenv(\"NOTIFY_SOCKET\"); err != nil {\n\t\t\treturn false, err\n\t\t}\n\t}\n\n\tconn, err := net.DialUnix(socketAddr.Net, nil, socketAddr)\n\t// Error connecting to NOTIFY_SOCKET\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tdefer conn.Close()\n\n\tif _, err = conn.Write([]byte(state)); err != nil {\n\t\treturn false, err\n\t}\n\treturn true, nil\n}\n"
  },
  {
    "path": "vendor/github.com/coreos/go-systemd/v22/daemon/watchdog.go",
    "content": "// Copyright 2016 CoreOS, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage daemon\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"time\"\n)\n\n// SdWatchdogEnabled returns watchdog information for a service.\n// Processes should call daemon.SdNotify(false, daemon.SdNotifyWatchdog) every\n// time / 2.\n// If `unsetEnvironment` is true, the environment variables `WATCHDOG_USEC` and\n// `WATCHDOG_PID` will be unconditionally unset.\n//\n// It returns one of the following:\n// (0, nil) - watchdog isn't enabled or we aren't the watched PID.\n// (0, err) - an error happened (e.g. error converting time).\n// (time, nil) - watchdog is enabled and we can send ping.  time is delay\n// before inactive service will be killed.\nfunc SdWatchdogEnabled(unsetEnvironment bool) (time.Duration, error) {\n\twusec := os.Getenv(\"WATCHDOG_USEC\")\n\twpid := os.Getenv(\"WATCHDOG_PID\")\n\tif unsetEnvironment {\n\t\twusecErr := os.Unsetenv(\"WATCHDOG_USEC\")\n\t\twpidErr := os.Unsetenv(\"WATCHDOG_PID\")\n\t\tif wusecErr != nil {\n\t\t\treturn 0, wusecErr\n\t\t}\n\t\tif wpidErr != nil {\n\t\t\treturn 0, wpidErr\n\t\t}\n\t}\n\n\tif wusec == \"\" {\n\t\treturn 0, nil\n\t}\n\ts, err := strconv.Atoi(wusec)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"error converting WATCHDOG_USEC: %s\", err)\n\t}\n\tif s <= 0 {\n\t\treturn 0, fmt.Errorf(\"error WATCHDOG_USEC must be a positive number\")\n\t}\n\tinterval := time.Duration(s) * time.Microsecond\n\n\tif wpid == \"\" {\n\t\treturn interval, nil\n\t}\n\tp, err := strconv.Atoi(wpid)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"error converting WATCHDOG_PID: %s\", err)\n\t}\n\tif os.Getpid() != p {\n\t\treturn 0, nil\n\t}\n\n\treturn interval, nil\n}\n"
  },
  {
    "path": "vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Brian Goff\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": "vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go",
    "content": "package md2man\n\nimport (\n\t\"github.com/russross/blackfriday/v2\"\n)\n\n// Render converts a markdown document into a roff formatted document.\nfunc Render(doc []byte) []byte {\n\trenderer := NewRoffRenderer()\n\n\treturn blackfriday.Run(doc,\n\t\t[]blackfriday.Option{blackfriday.WithRenderer(renderer),\n\t\t\tblackfriday.WithExtensions(renderer.GetExtensions())}...)\n}\n"
  },
  {
    "path": "vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go",
    "content": "package md2man\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/russross/blackfriday/v2\"\n)\n\n// roffRenderer implements the blackfriday.Renderer interface for creating\n// roff format (manpages) from markdown text\ntype roffRenderer struct {\n\textensions   blackfriday.Extensions\n\tlistCounters []int\n\tfirstHeader  bool\n\tdefineTerm   bool\n\tlistDepth    int\n}\n\nconst (\n\ttitleHeader      = \".TH \"\n\ttopLevelHeader   = \"\\n\\n.SH \"\n\tsecondLevelHdr   = \"\\n.SH \"\n\totherHeader      = \"\\n.SS \"\n\tcrTag            = \"\\n\"\n\temphTag          = \"\\\\fI\"\n\temphCloseTag     = \"\\\\fP\"\n\tstrongTag        = \"\\\\fB\"\n\tstrongCloseTag   = \"\\\\fP\"\n\tbreakTag         = \"\\n.br\\n\"\n\tparaTag          = \"\\n.PP\\n\"\n\thruleTag         = \"\\n.ti 0\\n\\\\l'\\\\n(.lu'\\n\"\n\tlinkTag          = \"\\n\\\\[la]\"\n\tlinkCloseTag     = \"\\\\[ra]\"\n\tcodespanTag      = \"\\\\fB\\\\fC\"\n\tcodespanCloseTag = \"\\\\fR\"\n\tcodeTag          = \"\\n.PP\\n.RS\\n\\n.nf\\n\"\n\tcodeCloseTag     = \"\\n.fi\\n.RE\\n\"\n\tquoteTag         = \"\\n.PP\\n.RS\\n\"\n\tquoteCloseTag    = \"\\n.RE\\n\"\n\tlistTag          = \"\\n.RS\\n\"\n\tlistCloseTag     = \"\\n.RE\\n\"\n\targlistTag       = \"\\n.TP\\n\"\n\ttableStart       = \"\\n.TS\\nallbox;\\n\"\n\ttableEnd         = \".TE\\n\"\n\ttableCellStart   = \"T{\\n\"\n\ttableCellEnd     = \"\\nT}\\n\"\n)\n\n// NewRoffRenderer creates a new blackfriday Renderer for generating roff documents\n// from markdown\nfunc NewRoffRenderer() *roffRenderer { // nolint: golint\n\tvar extensions blackfriday.Extensions\n\n\textensions |= blackfriday.NoIntraEmphasis\n\textensions |= blackfriday.Tables\n\textensions |= blackfriday.FencedCode\n\textensions |= blackfriday.SpaceHeadings\n\textensions |= blackfriday.Footnotes\n\textensions |= blackfriday.Titleblock\n\textensions |= blackfriday.DefinitionLists\n\treturn &roffRenderer{\n\t\textensions: extensions,\n\t}\n}\n\n// GetExtensions returns the list of extensions used by this renderer implementation\nfunc (r *roffRenderer) GetExtensions() blackfriday.Extensions {\n\treturn r.extensions\n}\n\n// RenderHeader handles outputting the header at document start\nfunc (r *roffRenderer) RenderHeader(w io.Writer, ast *blackfriday.Node) {\n\t// disable hyphenation\n\tout(w, \".nh\\n\")\n}\n\n// RenderFooter handles outputting the footer at the document end; the roff\n// renderer has no footer information\nfunc (r *roffRenderer) RenderFooter(w io.Writer, ast *blackfriday.Node) {\n}\n\n// RenderNode is called for each node in a markdown document; based on the node\n// type the equivalent roff output is sent to the writer\nfunc (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus {\n\n\tvar walkAction = blackfriday.GoToNext\n\n\tswitch node.Type {\n\tcase blackfriday.Text:\n\t\tr.handleText(w, node, entering)\n\tcase blackfriday.Softbreak:\n\t\tout(w, crTag)\n\tcase blackfriday.Hardbreak:\n\t\tout(w, breakTag)\n\tcase blackfriday.Emph:\n\t\tif entering {\n\t\t\tout(w, emphTag)\n\t\t} else {\n\t\t\tout(w, emphCloseTag)\n\t\t}\n\tcase blackfriday.Strong:\n\t\tif entering {\n\t\t\tout(w, strongTag)\n\t\t} else {\n\t\t\tout(w, strongCloseTag)\n\t\t}\n\tcase blackfriday.Link:\n\t\tif !entering {\n\t\t\tout(w, linkTag+string(node.LinkData.Destination)+linkCloseTag)\n\t\t}\n\tcase blackfriday.Image:\n\t\t// ignore images\n\t\twalkAction = blackfriday.SkipChildren\n\tcase blackfriday.Code:\n\t\tout(w, codespanTag)\n\t\tescapeSpecialChars(w, node.Literal)\n\t\tout(w, codespanCloseTag)\n\tcase blackfriday.Document:\n\t\tbreak\n\tcase blackfriday.Paragraph:\n\t\t// roff .PP markers break lists\n\t\tif r.listDepth > 0 {\n\t\t\treturn blackfriday.GoToNext\n\t\t}\n\t\tif entering {\n\t\t\tout(w, paraTag)\n\t\t} else {\n\t\t\tout(w, crTag)\n\t\t}\n\tcase blackfriday.BlockQuote:\n\t\tif entering {\n\t\t\tout(w, quoteTag)\n\t\t} else {\n\t\t\tout(w, quoteCloseTag)\n\t\t}\n\tcase blackfriday.Heading:\n\t\tr.handleHeading(w, node, entering)\n\tcase blackfriday.HorizontalRule:\n\t\tout(w, hruleTag)\n\tcase blackfriday.List:\n\t\tr.handleList(w, node, entering)\n\tcase blackfriday.Item:\n\t\tr.handleItem(w, node, entering)\n\tcase blackfriday.CodeBlock:\n\t\tout(w, codeTag)\n\t\tescapeSpecialChars(w, node.Literal)\n\t\tout(w, codeCloseTag)\n\tcase blackfriday.Table:\n\t\tr.handleTable(w, node, entering)\n\tcase blackfriday.TableCell:\n\t\tr.handleTableCell(w, node, entering)\n\tcase blackfriday.TableHead:\n\tcase blackfriday.TableBody:\n\tcase blackfriday.TableRow:\n\t\t// no action as cell entries do all the nroff formatting\n\t\treturn blackfriday.GoToNext\n\tdefault:\n\t\tfmt.Fprintln(os.Stderr, \"WARNING: go-md2man does not handle node type \"+node.Type.String())\n\t}\n\treturn walkAction\n}\n\nfunc (r *roffRenderer) handleText(w io.Writer, node *blackfriday.Node, entering bool) {\n\tvar (\n\t\tstart, end string\n\t)\n\t// handle special roff table cell text encapsulation\n\tif node.Parent.Type == blackfriday.TableCell {\n\t\tif len(node.Literal) > 30 {\n\t\t\tstart = tableCellStart\n\t\t\tend = tableCellEnd\n\t\t} else {\n\t\t\t// end rows that aren't terminated by \"tableCellEnd\" with a cr if end of row\n\t\t\tif node.Parent.Next == nil && !node.Parent.IsHeader {\n\t\t\t\tend = crTag\n\t\t\t}\n\t\t}\n\t}\n\tout(w, start)\n\tescapeSpecialChars(w, node.Literal)\n\tout(w, end)\n}\n\nfunc (r *roffRenderer) handleHeading(w io.Writer, node *blackfriday.Node, entering bool) {\n\tif entering {\n\t\tswitch node.Level {\n\t\tcase 1:\n\t\t\tif !r.firstHeader {\n\t\t\t\tout(w, titleHeader)\n\t\t\t\tr.firstHeader = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tout(w, topLevelHeader)\n\t\tcase 2:\n\t\t\tout(w, secondLevelHdr)\n\t\tdefault:\n\t\t\tout(w, otherHeader)\n\t\t}\n\t}\n}\n\nfunc (r *roffRenderer) handleList(w io.Writer, node *blackfriday.Node, entering bool) {\n\topenTag := listTag\n\tcloseTag := listCloseTag\n\tif node.ListFlags&blackfriday.ListTypeDefinition != 0 {\n\t\t// tags for definition lists handled within Item node\n\t\topenTag = \"\"\n\t\tcloseTag = \"\"\n\t}\n\tif entering {\n\t\tr.listDepth++\n\t\tif node.ListFlags&blackfriday.ListTypeOrdered != 0 {\n\t\t\tr.listCounters = append(r.listCounters, 1)\n\t\t}\n\t\tout(w, openTag)\n\t} else {\n\t\tif node.ListFlags&blackfriday.ListTypeOrdered != 0 {\n\t\t\tr.listCounters = r.listCounters[:len(r.listCounters)-1]\n\t\t}\n\t\tout(w, closeTag)\n\t\tr.listDepth--\n\t}\n}\n\nfunc (r *roffRenderer) handleItem(w io.Writer, node *blackfriday.Node, entering bool) {\n\tif entering {\n\t\tif node.ListFlags&blackfriday.ListTypeOrdered != 0 {\n\t\t\tout(w, fmt.Sprintf(\".IP \\\"%3d.\\\" 5\\n\", r.listCounters[len(r.listCounters)-1]))\n\t\t\tr.listCounters[len(r.listCounters)-1]++\n\t\t} else if node.ListFlags&blackfriday.ListTypeDefinition != 0 {\n\t\t\t// state machine for handling terms and following definitions\n\t\t\t// since blackfriday does not distinguish them properly, nor\n\t\t\t// does it seperate them into separate lists as it should\n\t\t\tif !r.defineTerm {\n\t\t\t\tout(w, arglistTag)\n\t\t\t\tr.defineTerm = true\n\t\t\t} else {\n\t\t\t\tr.defineTerm = false\n\t\t\t}\n\t\t} else {\n\t\t\tout(w, \".IP \\\\(bu 2\\n\")\n\t\t}\n\t} else {\n\t\tout(w, \"\\n\")\n\t}\n}\n\nfunc (r *roffRenderer) handleTable(w io.Writer, node *blackfriday.Node, entering bool) {\n\tif entering {\n\t\tout(w, tableStart)\n\t\t//call walker to count cells (and rows?) so format section can be produced\n\t\tcolumns := countColumns(node)\n\t\tout(w, strings.Repeat(\"l \", columns)+\"\\n\")\n\t\tout(w, strings.Repeat(\"l \", columns)+\".\\n\")\n\t} else {\n\t\tout(w, tableEnd)\n\t}\n}\n\nfunc (r *roffRenderer) handleTableCell(w io.Writer, node *blackfriday.Node, entering bool) {\n\tvar (\n\t\tstart, end string\n\t)\n\tif node.IsHeader {\n\t\tstart = codespanTag\n\t\tend = codespanCloseTag\n\t}\n\tif entering {\n\t\tif node.Prev != nil && node.Prev.Type == blackfriday.TableCell {\n\t\t\tout(w, \"\\t\"+start)\n\t\t} else {\n\t\t\tout(w, start)\n\t\t}\n\t} else {\n\t\t// need to carriage return if we are at the end of the header row\n\t\tif node.IsHeader && node.Next == nil {\n\t\t\tend = end + crTag\n\t\t}\n\t\tout(w, end)\n\t}\n}\n\n// because roff format requires knowing the column count before outputting any table\n// data we need to walk a table tree and count the columns\nfunc countColumns(node *blackfriday.Node) int {\n\tvar columns int\n\n\tnode.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus {\n\t\tswitch node.Type {\n\t\tcase blackfriday.TableRow:\n\t\t\tif !entering {\n\t\t\t\treturn blackfriday.Terminate\n\t\t\t}\n\t\tcase blackfriday.TableCell:\n\t\t\tif entering {\n\t\t\t\tcolumns++\n\t\t\t}\n\t\tdefault:\n\t\t}\n\t\treturn blackfriday.GoToNext\n\t})\n\treturn columns\n}\n\nfunc out(w io.Writer, output string) {\n\tio.WriteString(w, output) // nolint: errcheck\n}\n\nfunc needsBackslash(c byte) bool {\n\tfor _, r := range []byte(\"-_&\\\\~\") {\n\t\tif c == r {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc escapeSpecialChars(w io.Writer, text []byte) {\n\tfor i := 0; i < len(text); i++ {\n\t\t// escape initial apostrophe or period\n\t\tif len(text) >= 1 && (text[0] == '\\'' || text[0] == '.') {\n\t\t\tout(w, \"\\\\&\")\n\t\t}\n\n\t\t// directly copy normal characters\n\t\torg := i\n\n\t\tfor i < len(text) && !needsBackslash(text[i]) {\n\t\t\ti++\n\t\t}\n\t\tif i > org {\n\t\t\tw.Write(text[org:i]) // nolint: errcheck\n\t\t}\n\n\t\t// escape a character\n\t\tif i >= len(text) {\n\t\t\tbreak\n\t\t}\n\n\t\tw.Write([]byte{'\\\\', text[i]}) // nolint: errcheck\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/LICENSE",
    "content": "ISC License\n\nCopyright (c) 2012-2016 Dave Collins <dave@davec.name>\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted, provided that the above\ncopyright notice and this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\nWITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\nANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\nWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\nACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\nOR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/bypass.go",
    "content": "// Copyright (c) 2015-2016 Dave Collins <dave@davec.name>\n//\n// Permission to use, copy, modify, and distribute this software for any\n// purpose with or without fee is hereby granted, provided that the above\n// copyright notice and this permission notice appear in all copies.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n\n// NOTE: Due to the following build constraints, this file will only be compiled\n// when the code is not running on Google App Engine, compiled by GopherJS, and\n// \"-tags safe\" is not added to the go build command line.  The \"disableunsafe\"\n// tag is deprecated and thus should not be used.\n// Go versions prior to 1.4 are disabled because they use a different layout\n// for interfaces which make the implementation of unsafeReflectValue more complex.\n// +build !js,!appengine,!safe,!disableunsafe,go1.4\n\npackage spew\n\nimport (\n\t\"reflect\"\n\t\"unsafe\"\n)\n\nconst (\n\t// UnsafeDisabled is a build-time constant which specifies whether or\n\t// not access to the unsafe package is available.\n\tUnsafeDisabled = false\n\n\t// ptrSize is the size of a pointer on the current arch.\n\tptrSize = unsafe.Sizeof((*byte)(nil))\n)\n\ntype flag uintptr\n\nvar (\n\t// flagRO indicates whether the value field of a reflect.Value\n\t// is read-only.\n\tflagRO flag\n\n\t// flagAddr indicates whether the address of the reflect.Value's\n\t// value may be taken.\n\tflagAddr flag\n)\n\n// flagKindMask holds the bits that make up the kind\n// part of the flags field. In all the supported versions,\n// it is in the lower 5 bits.\nconst flagKindMask = flag(0x1f)\n\n// Different versions of Go have used different\n// bit layouts for the flags type. This table\n// records the known combinations.\nvar okFlags = []struct {\n\tro, addr flag\n}{{\n\t// From Go 1.4 to 1.5\n\tro:   1 << 5,\n\taddr: 1 << 7,\n}, {\n\t// Up to Go tip.\n\tro:   1<<5 | 1<<6,\n\taddr: 1 << 8,\n}}\n\nvar flagValOffset = func() uintptr {\n\tfield, ok := reflect.TypeOf(reflect.Value{}).FieldByName(\"flag\")\n\tif !ok {\n\t\tpanic(\"reflect.Value has no flag field\")\n\t}\n\treturn field.Offset\n}()\n\n// flagField returns a pointer to the flag field of a reflect.Value.\nfunc flagField(v *reflect.Value) *flag {\n\treturn (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset))\n}\n\n// unsafeReflectValue converts the passed reflect.Value into a one that bypasses\n// the typical safety restrictions preventing access to unaddressable and\n// unexported data.  It works by digging the raw pointer to the underlying\n// value out of the protected value and generating a new unprotected (unsafe)\n// reflect.Value to it.\n//\n// This allows us to check for implementations of the Stringer and error\n// interfaces to be used for pretty printing ordinarily unaddressable and\n// inaccessible values such as unexported struct fields.\nfunc unsafeReflectValue(v reflect.Value) reflect.Value {\n\tif !v.IsValid() || (v.CanInterface() && v.CanAddr()) {\n\t\treturn v\n\t}\n\tflagFieldPtr := flagField(&v)\n\t*flagFieldPtr &^= flagRO\n\t*flagFieldPtr |= flagAddr\n\treturn v\n}\n\n// Sanity checks against future reflect package changes\n// to the type or semantics of the Value.flag field.\nfunc init() {\n\tfield, ok := reflect.TypeOf(reflect.Value{}).FieldByName(\"flag\")\n\tif !ok {\n\t\tpanic(\"reflect.Value has no flag field\")\n\t}\n\tif field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() {\n\t\tpanic(\"reflect.Value flag field has changed kind\")\n\t}\n\ttype t0 int\n\tvar t struct {\n\t\tA t0\n\t\t// t0 will have flagEmbedRO set.\n\t\tt0\n\t\t// a will have flagStickyRO set\n\t\ta t0\n\t}\n\tvA := reflect.ValueOf(t).FieldByName(\"A\")\n\tva := reflect.ValueOf(t).FieldByName(\"a\")\n\tvt0 := reflect.ValueOf(t).FieldByName(\"t0\")\n\n\t// Infer flagRO from the difference between the flags\n\t// for the (otherwise identical) fields in t.\n\tflagPublic := *flagField(&vA)\n\tflagWithRO := *flagField(&va) | *flagField(&vt0)\n\tflagRO = flagPublic ^ flagWithRO\n\n\t// Infer flagAddr from the difference between a value\n\t// taken from a pointer and not.\n\tvPtrA := reflect.ValueOf(&t).Elem().FieldByName(\"A\")\n\tflagNoPtr := *flagField(&vA)\n\tflagPtr := *flagField(&vPtrA)\n\tflagAddr = flagNoPtr ^ flagPtr\n\n\t// Check that the inferred flags tally with one of the known versions.\n\tfor _, f := range okFlags {\n\t\tif flagRO == f.ro && flagAddr == f.addr {\n\t\t\treturn\n\t\t}\n\t}\n\tpanic(\"reflect.Value read-only flag has changed semantics\")\n}\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/bypasssafe.go",
    "content": "// Copyright (c) 2015-2016 Dave Collins <dave@davec.name>\n//\n// Permission to use, copy, modify, and distribute this software for any\n// purpose with or without fee is hereby granted, provided that the above\n// copyright notice and this permission notice appear in all copies.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n\n// NOTE: Due to the following build constraints, this file will only be compiled\n// when the code is running on Google App Engine, compiled by GopherJS, or\n// \"-tags safe\" is added to the go build command line.  The \"disableunsafe\"\n// tag is deprecated and thus should not be used.\n// +build js appengine safe disableunsafe !go1.4\n\npackage spew\n\nimport \"reflect\"\n\nconst (\n\t// UnsafeDisabled is a build-time constant which specifies whether or\n\t// not access to the unsafe package is available.\n\tUnsafeDisabled = true\n)\n\n// unsafeReflectValue typically converts the passed reflect.Value into a one\n// that bypasses the typical safety restrictions preventing access to\n// unaddressable and unexported data.  However, doing this relies on access to\n// the unsafe package.  This is a stub version which simply returns the passed\n// reflect.Value when the unsafe package is not available.\nfunc unsafeReflectValue(v reflect.Value) reflect.Value {\n\treturn v\n}\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/common.go",
    "content": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\npackage spew\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strconv\"\n)\n\n// Some constants in the form of bytes to avoid string overhead.  This mirrors\n// the technique used in the fmt package.\nvar (\n\tpanicBytes            = []byte(\"(PANIC=\")\n\tplusBytes             = []byte(\"+\")\n\tiBytes                = []byte(\"i\")\n\ttrueBytes             = []byte(\"true\")\n\tfalseBytes            = []byte(\"false\")\n\tinterfaceBytes        = []byte(\"(interface {})\")\n\tcommaNewlineBytes     = []byte(\",\\n\")\n\tnewlineBytes          = []byte(\"\\n\")\n\topenBraceBytes        = []byte(\"{\")\n\topenBraceNewlineBytes = []byte(\"{\\n\")\n\tcloseBraceBytes       = []byte(\"}\")\n\tasteriskBytes         = []byte(\"*\")\n\tcolonBytes            = []byte(\":\")\n\tcolonSpaceBytes       = []byte(\": \")\n\topenParenBytes        = []byte(\"(\")\n\tcloseParenBytes       = []byte(\")\")\n\tspaceBytes            = []byte(\" \")\n\tpointerChainBytes     = []byte(\"->\")\n\tnilAngleBytes         = []byte(\"<nil>\")\n\tmaxNewlineBytes       = []byte(\"<max depth reached>\\n\")\n\tmaxShortBytes         = []byte(\"<max>\")\n\tcircularBytes         = []byte(\"<already shown>\")\n\tcircularShortBytes    = []byte(\"<shown>\")\n\tinvalidAngleBytes     = []byte(\"<invalid>\")\n\topenBracketBytes      = []byte(\"[\")\n\tcloseBracketBytes     = []byte(\"]\")\n\tpercentBytes          = []byte(\"%\")\n\tprecisionBytes        = []byte(\".\")\n\topenAngleBytes        = []byte(\"<\")\n\tcloseAngleBytes       = []byte(\">\")\n\topenMapBytes          = []byte(\"map[\")\n\tcloseMapBytes         = []byte(\"]\")\n\tlenEqualsBytes        = []byte(\"len=\")\n\tcapEqualsBytes        = []byte(\"cap=\")\n)\n\n// hexDigits is used to map a decimal value to a hex digit.\nvar hexDigits = \"0123456789abcdef\"\n\n// catchPanic handles any panics that might occur during the handleMethods\n// calls.\nfunc catchPanic(w io.Writer, v reflect.Value) {\n\tif err := recover(); err != nil {\n\t\tw.Write(panicBytes)\n\t\tfmt.Fprintf(w, \"%v\", err)\n\t\tw.Write(closeParenBytes)\n\t}\n}\n\n// handleMethods attempts to call the Error and String methods on the underlying\n// type the passed reflect.Value represents and outputes the result to Writer w.\n//\n// It handles panics in any called methods by catching and displaying the error\n// as the formatted value.\nfunc handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) {\n\t// We need an interface to check if the type implements the error or\n\t// Stringer interface.  However, the reflect package won't give us an\n\t// interface on certain things like unexported struct fields in order\n\t// to enforce visibility rules.  We use unsafe, when it's available,\n\t// to bypass these restrictions since this package does not mutate the\n\t// values.\n\tif !v.CanInterface() {\n\t\tif UnsafeDisabled {\n\t\t\treturn false\n\t\t}\n\n\t\tv = unsafeReflectValue(v)\n\t}\n\n\t// Choose whether or not to do error and Stringer interface lookups against\n\t// the base type or a pointer to the base type depending on settings.\n\t// Technically calling one of these methods with a pointer receiver can\n\t// mutate the value, however, types which choose to satisify an error or\n\t// Stringer interface with a pointer receiver should not be mutating their\n\t// state inside these interface methods.\n\tif !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() {\n\t\tv = unsafeReflectValue(v)\n\t}\n\tif v.CanAddr() {\n\t\tv = v.Addr()\n\t}\n\n\t// Is it an error or Stringer?\n\tswitch iface := v.Interface().(type) {\n\tcase error:\n\t\tdefer catchPanic(w, v)\n\t\tif cs.ContinueOnMethod {\n\t\t\tw.Write(openParenBytes)\n\t\t\tw.Write([]byte(iface.Error()))\n\t\t\tw.Write(closeParenBytes)\n\t\t\tw.Write(spaceBytes)\n\t\t\treturn false\n\t\t}\n\n\t\tw.Write([]byte(iface.Error()))\n\t\treturn true\n\n\tcase fmt.Stringer:\n\t\tdefer catchPanic(w, v)\n\t\tif cs.ContinueOnMethod {\n\t\t\tw.Write(openParenBytes)\n\t\t\tw.Write([]byte(iface.String()))\n\t\t\tw.Write(closeParenBytes)\n\t\t\tw.Write(spaceBytes)\n\t\t\treturn false\n\t\t}\n\t\tw.Write([]byte(iface.String()))\n\t\treturn true\n\t}\n\treturn false\n}\n\n// printBool outputs a boolean value as true or false to Writer w.\nfunc printBool(w io.Writer, val bool) {\n\tif val {\n\t\tw.Write(trueBytes)\n\t} else {\n\t\tw.Write(falseBytes)\n\t}\n}\n\n// printInt outputs a signed integer value to Writer w.\nfunc printInt(w io.Writer, val int64, base int) {\n\tw.Write([]byte(strconv.FormatInt(val, base)))\n}\n\n// printUint outputs an unsigned integer value to Writer w.\nfunc printUint(w io.Writer, val uint64, base int) {\n\tw.Write([]byte(strconv.FormatUint(val, base)))\n}\n\n// printFloat outputs a floating point value using the specified precision,\n// which is expected to be 32 or 64bit, to Writer w.\nfunc printFloat(w io.Writer, val float64, precision int) {\n\tw.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision)))\n}\n\n// printComplex outputs a complex value using the specified float precision\n// for the real and imaginary parts to Writer w.\nfunc printComplex(w io.Writer, c complex128, floatPrecision int) {\n\tr := real(c)\n\tw.Write(openParenBytes)\n\tw.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision)))\n\ti := imag(c)\n\tif i >= 0 {\n\t\tw.Write(plusBytes)\n\t}\n\tw.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision)))\n\tw.Write(iBytes)\n\tw.Write(closeParenBytes)\n}\n\n// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x'\n// prefix to Writer w.\nfunc printHexPtr(w io.Writer, p uintptr) {\n\t// Null pointer.\n\tnum := uint64(p)\n\tif num == 0 {\n\t\tw.Write(nilAngleBytes)\n\t\treturn\n\t}\n\n\t// Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix\n\tbuf := make([]byte, 18)\n\n\t// It's simpler to construct the hex string right to left.\n\tbase := uint64(16)\n\ti := len(buf) - 1\n\tfor num >= base {\n\t\tbuf[i] = hexDigits[num%base]\n\t\tnum /= base\n\t\ti--\n\t}\n\tbuf[i] = hexDigits[num]\n\n\t// Add '0x' prefix.\n\ti--\n\tbuf[i] = 'x'\n\ti--\n\tbuf[i] = '0'\n\n\t// Strip unused leading bytes.\n\tbuf = buf[i:]\n\tw.Write(buf)\n}\n\n// valuesSorter implements sort.Interface to allow a slice of reflect.Value\n// elements to be sorted.\ntype valuesSorter struct {\n\tvalues  []reflect.Value\n\tstrings []string // either nil or same len and values\n\tcs      *ConfigState\n}\n\n// newValuesSorter initializes a valuesSorter instance, which holds a set of\n// surrogate keys on which the data should be sorted.  It uses flags in\n// ConfigState to decide if and how to populate those surrogate keys.\nfunc newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface {\n\tvs := &valuesSorter{values: values, cs: cs}\n\tif canSortSimply(vs.values[0].Kind()) {\n\t\treturn vs\n\t}\n\tif !cs.DisableMethods {\n\t\tvs.strings = make([]string, len(values))\n\t\tfor i := range vs.values {\n\t\t\tb := bytes.Buffer{}\n\t\t\tif !handleMethods(cs, &b, vs.values[i]) {\n\t\t\t\tvs.strings = nil\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tvs.strings[i] = b.String()\n\t\t}\n\t}\n\tif vs.strings == nil && cs.SpewKeys {\n\t\tvs.strings = make([]string, len(values))\n\t\tfor i := range vs.values {\n\t\t\tvs.strings[i] = Sprintf(\"%#v\", vs.values[i].Interface())\n\t\t}\n\t}\n\treturn vs\n}\n\n// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted\n// directly, or whether it should be considered for sorting by surrogate keys\n// (if the ConfigState allows it).\nfunc canSortSimply(kind reflect.Kind) bool {\n\t// This switch parallels valueSortLess, except for the default case.\n\tswitch kind {\n\tcase reflect.Bool:\n\t\treturn true\n\tcase reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:\n\t\treturn true\n\tcase reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:\n\t\treturn true\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn true\n\tcase reflect.String:\n\t\treturn true\n\tcase reflect.Uintptr:\n\t\treturn true\n\tcase reflect.Array:\n\t\treturn true\n\t}\n\treturn false\n}\n\n// Len returns the number of values in the slice.  It is part of the\n// sort.Interface implementation.\nfunc (s *valuesSorter) Len() int {\n\treturn len(s.values)\n}\n\n// Swap swaps the values at the passed indices.  It is part of the\n// sort.Interface implementation.\nfunc (s *valuesSorter) Swap(i, j int) {\n\ts.values[i], s.values[j] = s.values[j], s.values[i]\n\tif s.strings != nil {\n\t\ts.strings[i], s.strings[j] = s.strings[j], s.strings[i]\n\t}\n}\n\n// valueSortLess returns whether the first value should sort before the second\n// value.  It is used by valueSorter.Less as part of the sort.Interface\n// implementation.\nfunc valueSortLess(a, b reflect.Value) bool {\n\tswitch a.Kind() {\n\tcase reflect.Bool:\n\t\treturn !a.Bool() && b.Bool()\n\tcase reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:\n\t\treturn a.Int() < b.Int()\n\tcase reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:\n\t\treturn a.Uint() < b.Uint()\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn a.Float() < b.Float()\n\tcase reflect.String:\n\t\treturn a.String() < b.String()\n\tcase reflect.Uintptr:\n\t\treturn a.Uint() < b.Uint()\n\tcase reflect.Array:\n\t\t// Compare the contents of both arrays.\n\t\tl := a.Len()\n\t\tfor i := 0; i < l; i++ {\n\t\t\tav := a.Index(i)\n\t\t\tbv := b.Index(i)\n\t\t\tif av.Interface() == bv.Interface() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn valueSortLess(av, bv)\n\t\t}\n\t}\n\treturn a.String() < b.String()\n}\n\n// Less returns whether the value at index i should sort before the\n// value at index j.  It is part of the sort.Interface implementation.\nfunc (s *valuesSorter) Less(i, j int) bool {\n\tif s.strings == nil {\n\t\treturn valueSortLess(s.values[i], s.values[j])\n\t}\n\treturn s.strings[i] < s.strings[j]\n}\n\n// sortValues is a sort function that handles both native types and any type that\n// can be converted to error or Stringer.  Other inputs are sorted according to\n// their Value.String() value to ensure display stability.\nfunc sortValues(values []reflect.Value, cs *ConfigState) {\n\tif len(values) == 0 {\n\t\treturn\n\t}\n\tsort.Sort(newValuesSorter(values, cs))\n}\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/config.go",
    "content": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\npackage spew\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n)\n\n// ConfigState houses the configuration options used by spew to format and\n// display values.  There is a global instance, Config, that is used to control\n// all top-level Formatter and Dump functionality.  Each ConfigState instance\n// provides methods equivalent to the top-level functions.\n//\n// The zero value for ConfigState provides no indentation.  You would typically\n// want to set it to a space or a tab.\n//\n// Alternatively, you can use NewDefaultConfig to get a ConfigState instance\n// with default settings.  See the documentation of NewDefaultConfig for default\n// values.\ntype ConfigState struct {\n\t// Indent specifies the string to use for each indentation level.  The\n\t// global config instance that all top-level functions use set this to a\n\t// single space by default.  If you would like more indentation, you might\n\t// set this to a tab with \"\\t\" or perhaps two spaces with \"  \".\n\tIndent string\n\n\t// MaxDepth controls the maximum number of levels to descend into nested\n\t// data structures.  The default, 0, means there is no limit.\n\t//\n\t// NOTE: Circular data structures are properly detected, so it is not\n\t// necessary to set this value unless you specifically want to limit deeply\n\t// nested data structures.\n\tMaxDepth int\n\n\t// DisableMethods specifies whether or not error and Stringer interfaces are\n\t// invoked for types that implement them.\n\tDisableMethods bool\n\n\t// DisablePointerMethods specifies whether or not to check for and invoke\n\t// error and Stringer interfaces on types which only accept a pointer\n\t// receiver when the current type is not a pointer.\n\t//\n\t// NOTE: This might be an unsafe action since calling one of these methods\n\t// with a pointer receiver could technically mutate the value, however,\n\t// in practice, types which choose to satisify an error or Stringer\n\t// interface with a pointer receiver should not be mutating their state\n\t// inside these interface methods.  As a result, this option relies on\n\t// access to the unsafe package, so it will not have any effect when\n\t// running in environments without access to the unsafe package such as\n\t// Google App Engine or with the \"safe\" build tag specified.\n\tDisablePointerMethods bool\n\n\t// DisablePointerAddresses specifies whether to disable the printing of\n\t// pointer addresses. This is useful when diffing data structures in tests.\n\tDisablePointerAddresses bool\n\n\t// DisableCapacities specifies whether to disable the printing of capacities\n\t// for arrays, slices, maps and channels. This is useful when diffing\n\t// data structures in tests.\n\tDisableCapacities bool\n\n\t// ContinueOnMethod specifies whether or not recursion should continue once\n\t// a custom error or Stringer interface is invoked.  The default, false,\n\t// means it will print the results of invoking the custom error or Stringer\n\t// interface and return immediately instead of continuing to recurse into\n\t// the internals of the data type.\n\t//\n\t// NOTE: This flag does not have any effect if method invocation is disabled\n\t// via the DisableMethods or DisablePointerMethods options.\n\tContinueOnMethod bool\n\n\t// SortKeys specifies map keys should be sorted before being printed. Use\n\t// this to have a more deterministic, diffable output.  Note that only\n\t// native types (bool, int, uint, floats, uintptr and string) and types\n\t// that support the error or Stringer interfaces (if methods are\n\t// enabled) are supported, with other types sorted according to the\n\t// reflect.Value.String() output which guarantees display stability.\n\tSortKeys bool\n\n\t// SpewKeys specifies that, as a last resort attempt, map keys should\n\t// be spewed to strings and sorted by those strings.  This is only\n\t// considered if SortKeys is true.\n\tSpewKeys bool\n}\n\n// Config is the active configuration of the top-level functions.\n// The configuration can be changed by modifying the contents of spew.Config.\nvar Config = ConfigState{Indent: \" \"}\n\n// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were\n// passed with a Formatter interface returned by c.NewFormatter.  It returns\n// the formatted string as a value that satisfies error.  See NewFormatter\n// for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Errorf(format string, a ...interface{}) (err error) {\n\treturn fmt.Errorf(format, c.convertArgs(a)...)\n}\n\n// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were\n// passed with a Formatter interface returned by c.NewFormatter.  It returns\n// the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) {\n\treturn fmt.Fprint(w, c.convertArgs(a)...)\n}\n\n// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were\n// passed with a Formatter interface returned by c.NewFormatter.  It returns\n// the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {\n\treturn fmt.Fprintf(w, format, c.convertArgs(a)...)\n}\n\n// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it\n// passed with a Formatter interface returned by c.NewFormatter.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {\n\treturn fmt.Fprintln(w, c.convertArgs(a)...)\n}\n\n// Print is a wrapper for fmt.Print that treats each argument as if it were\n// passed with a Formatter interface returned by c.NewFormatter.  It returns\n// the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Print(c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Print(a ...interface{}) (n int, err error) {\n\treturn fmt.Print(c.convertArgs(a)...)\n}\n\n// Printf is a wrapper for fmt.Printf that treats each argument as if it were\n// passed with a Formatter interface returned by c.NewFormatter.  It returns\n// the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) {\n\treturn fmt.Printf(format, c.convertArgs(a)...)\n}\n\n// Println is a wrapper for fmt.Println that treats each argument as if it were\n// passed with a Formatter interface returned by c.NewFormatter.  It returns\n// the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Println(c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Println(a ...interface{}) (n int, err error) {\n\treturn fmt.Println(c.convertArgs(a)...)\n}\n\n// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were\n// passed with a Formatter interface returned by c.NewFormatter.  It returns\n// the resulting string.  See NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Sprint(c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Sprint(a ...interface{}) string {\n\treturn fmt.Sprint(c.convertArgs(a)...)\n}\n\n// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were\n// passed with a Formatter interface returned by c.NewFormatter.  It returns\n// the resulting string.  See NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Sprintf(format string, a ...interface{}) string {\n\treturn fmt.Sprintf(format, c.convertArgs(a)...)\n}\n\n// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it\n// were passed with a Formatter interface returned by c.NewFormatter.  It\n// returns the resulting string.  See NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Sprintln(a ...interface{}) string {\n\treturn fmt.Sprintln(c.convertArgs(a)...)\n}\n\n/*\nNewFormatter returns a custom formatter that satisfies the fmt.Formatter\ninterface.  As a result, it integrates cleanly with standard fmt package\nprinting functions.  The formatter is useful for inline printing of smaller data\ntypes similar to the standard %v format specifier.\n\nThe custom formatter only responds to the %v (most compact), %+v (adds pointer\naddresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb\ncombinations.  Any other verbs such as %x and %q will be sent to the the\nstandard fmt package for formatting.  In addition, the custom formatter ignores\nthe width and precision arguments (however they will still work on the format\nspecifiers not handled by the custom formatter).\n\nTypically this function shouldn't be called directly.  It is much easier to make\nuse of the custom formatter by calling one of the convenience functions such as\nc.Printf, c.Println, or c.Printf.\n*/\nfunc (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter {\n\treturn newFormatter(c, v)\n}\n\n// Fdump formats and displays the passed arguments to io.Writer w.  It formats\n// exactly the same as Dump.\nfunc (c *ConfigState) Fdump(w io.Writer, a ...interface{}) {\n\tfdump(c, w, a...)\n}\n\n/*\nDump displays the passed parameters to standard out with newlines, customizable\nindentation, and additional debug information such as complete types and all\npointer addresses used to indirect to the final value.  It provides the\nfollowing features over the built-in printing facilities provided by the fmt\npackage:\n\n\t* Pointers are dereferenced and followed\n\t* Circular data structures are detected and handled properly\n\t* Custom Stringer/error interfaces are optionally invoked, including\n\t  on unexported types\n\t* Custom types which only implement the Stringer/error interfaces via\n\t  a pointer receiver are optionally invoked when passing non-pointer\n\t  variables\n\t* Byte arrays and slices are dumped like the hexdump -C command which\n\t  includes offsets, byte values in hex, and ASCII output\n\nThe configuration options are controlled by modifying the public members\nof c.  See ConfigState for options documentation.\n\nSee Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to\nget the formatted result as a string.\n*/\nfunc (c *ConfigState) Dump(a ...interface{}) {\n\tfdump(c, os.Stdout, a...)\n}\n\n// Sdump returns a string with the passed arguments formatted exactly the same\n// as Dump.\nfunc (c *ConfigState) Sdump(a ...interface{}) string {\n\tvar buf bytes.Buffer\n\tfdump(c, &buf, a...)\n\treturn buf.String()\n}\n\n// convertArgs accepts a slice of arguments and returns a slice of the same\n// length with each argument converted to a spew Formatter interface using\n// the ConfigState associated with s.\nfunc (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) {\n\tformatters = make([]interface{}, len(args))\n\tfor index, arg := range args {\n\t\tformatters[index] = newFormatter(c, arg)\n\t}\n\treturn formatters\n}\n\n// NewDefaultConfig returns a ConfigState with the following default settings.\n//\n// \tIndent: \" \"\n// \tMaxDepth: 0\n// \tDisableMethods: false\n// \tDisablePointerMethods: false\n// \tContinueOnMethod: false\n// \tSortKeys: false\nfunc NewDefaultConfig() *ConfigState {\n\treturn &ConfigState{Indent: \" \"}\n}\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/doc.go",
    "content": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n/*\nPackage spew implements a deep pretty printer for Go data structures to aid in\ndebugging.\n\nA quick overview of the additional features spew provides over the built-in\nprinting facilities for Go data types are as follows:\n\n\t* Pointers are dereferenced and followed\n\t* Circular data structures are detected and handled properly\n\t* Custom Stringer/error interfaces are optionally invoked, including\n\t  on unexported types\n\t* Custom types which only implement the Stringer/error interfaces via\n\t  a pointer receiver are optionally invoked when passing non-pointer\n\t  variables\n\t* Byte arrays and slices are dumped like the hexdump -C command which\n\t  includes offsets, byte values in hex, and ASCII output (only when using\n\t  Dump style)\n\nThere are two different approaches spew allows for dumping Go data structures:\n\n\t* Dump style which prints with newlines, customizable indentation,\n\t  and additional debug information such as types and all pointer addresses\n\t  used to indirect to the final value\n\t* A custom Formatter interface that integrates cleanly with the standard fmt\n\t  package and replaces %v, %+v, %#v, and %#+v to provide inline printing\n\t  similar to the default %v while providing the additional functionality\n\t  outlined above and passing unsupported format verbs such as %x and %q\n\t  along to fmt\n\nQuick Start\n\nThis section demonstrates how to quickly get started with spew.  See the\nsections below for further details on formatting and configuration options.\n\nTo dump a variable with full newlines, indentation, type, and pointer\ninformation use Dump, Fdump, or Sdump:\n\tspew.Dump(myVar1, myVar2, ...)\n\tspew.Fdump(someWriter, myVar1, myVar2, ...)\n\tstr := spew.Sdump(myVar1, myVar2, ...)\n\nAlternatively, if you would prefer to use format strings with a compacted inline\nprinting style, use the convenience wrappers Printf, Fprintf, etc with\n%v (most compact), %+v (adds pointer addresses), %#v (adds types), or\n%#+v (adds types and pointer addresses):\n\tspew.Printf(\"myVar1: %v -- myVar2: %+v\", myVar1, myVar2)\n\tspew.Printf(\"myVar3: %#v -- myVar4: %#+v\", myVar3, myVar4)\n\tspew.Fprintf(someWriter, \"myVar1: %v -- myVar2: %+v\", myVar1, myVar2)\n\tspew.Fprintf(someWriter, \"myVar3: %#v -- myVar4: %#+v\", myVar3, myVar4)\n\nConfiguration Options\n\nConfiguration of spew is handled by fields in the ConfigState type.  For\nconvenience, all of the top-level functions use a global state available\nvia the spew.Config global.\n\nIt is also possible to create a ConfigState instance that provides methods\nequivalent to the top-level functions.  This allows concurrent configuration\noptions.  See the ConfigState documentation for more details.\n\nThe following configuration options are available:\n\t* Indent\n\t\tString to use for each indentation level for Dump functions.\n\t\tIt is a single space by default.  A popular alternative is \"\\t\".\n\n\t* MaxDepth\n\t\tMaximum number of levels to descend into nested data structures.\n\t\tThere is no limit by default.\n\n\t* DisableMethods\n\t\tDisables invocation of error and Stringer interface methods.\n\t\tMethod invocation is enabled by default.\n\n\t* DisablePointerMethods\n\t\tDisables invocation of error and Stringer interface methods on types\n\t\twhich only accept pointer receivers from non-pointer variables.\n\t\tPointer method invocation is enabled by default.\n\n\t* DisablePointerAddresses\n\t\tDisablePointerAddresses specifies whether to disable the printing of\n\t\tpointer addresses. This is useful when diffing data structures in tests.\n\n\t* DisableCapacities\n\t\tDisableCapacities specifies whether to disable the printing of\n\t\tcapacities for arrays, slices, maps and channels. This is useful when\n\t\tdiffing data structures in tests.\n\n\t* ContinueOnMethod\n\t\tEnables recursion into types after invoking error and Stringer interface\n\t\tmethods. Recursion after method invocation is disabled by default.\n\n\t* SortKeys\n\t\tSpecifies map keys should be sorted before being printed. Use\n\t\tthis to have a more deterministic, diffable output.  Note that\n\t\tonly native types (bool, int, uint, floats, uintptr and string)\n\t\tand types which implement error or Stringer interfaces are\n\t\tsupported with other types sorted according to the\n\t\treflect.Value.String() output which guarantees display\n\t\tstability.  Natural map order is used by default.\n\n\t* SpewKeys\n\t\tSpecifies that, as a last resort attempt, map keys should be\n\t\tspewed to strings and sorted by those strings.  This is only\n\t\tconsidered if SortKeys is true.\n\nDump Usage\n\nSimply call spew.Dump with a list of variables you want to dump:\n\n\tspew.Dump(myVar1, myVar2, ...)\n\nYou may also call spew.Fdump if you would prefer to output to an arbitrary\nio.Writer.  For example, to dump to standard error:\n\n\tspew.Fdump(os.Stderr, myVar1, myVar2, ...)\n\nA third option is to call spew.Sdump to get the formatted output as a string:\n\n\tstr := spew.Sdump(myVar1, myVar2, ...)\n\nSample Dump Output\n\nSee the Dump example for details on the setup of the types and variables being\nshown here.\n\n\t(main.Foo) {\n\t unexportedField: (*main.Bar)(0xf84002e210)({\n\t  flag: (main.Flag) flagTwo,\n\t  data: (uintptr) <nil>\n\t }),\n\t ExportedField: (map[interface {}]interface {}) (len=1) {\n\t  (string) (len=3) \"one\": (bool) true\n\t }\n\t}\n\nByte (and uint8) arrays and slices are displayed uniquely like the hexdump -C\ncommand as shown.\n\t([]uint8) (len=32 cap=32) {\n\t 00000000  11 12 13 14 15 16 17 18  19 1a 1b 1c 1d 1e 1f 20  |............... |\n\t 00000010  21 22 23 24 25 26 27 28  29 2a 2b 2c 2d 2e 2f 30  |!\"#$%&'()*+,-./0|\n\t 00000020  31 32                                             |12|\n\t}\n\nCustom Formatter\n\nSpew provides a custom formatter that implements the fmt.Formatter interface\nso that it integrates cleanly with standard fmt package printing functions. The\nformatter is useful for inline printing of smaller data types similar to the\nstandard %v format specifier.\n\nThe custom formatter only responds to the %v (most compact), %+v (adds pointer\naddresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb\ncombinations.  Any other verbs such as %x and %q will be sent to the the\nstandard fmt package for formatting.  In addition, the custom formatter ignores\nthe width and precision arguments (however they will still work on the format\nspecifiers not handled by the custom formatter).\n\nCustom Formatter Usage\n\nThe simplest way to make use of the spew custom formatter is to call one of the\nconvenience functions such as spew.Printf, spew.Println, or spew.Printf.  The\nfunctions have syntax you are most likely already familiar with:\n\n\tspew.Printf(\"myVar1: %v -- myVar2: %+v\", myVar1, myVar2)\n\tspew.Printf(\"myVar3: %#v -- myVar4: %#+v\", myVar3, myVar4)\n\tspew.Println(myVar, myVar2)\n\tspew.Fprintf(os.Stderr, \"myVar1: %v -- myVar2: %+v\", myVar1, myVar2)\n\tspew.Fprintf(os.Stderr, \"myVar3: %#v -- myVar4: %#+v\", myVar3, myVar4)\n\nSee the Index for the full list convenience functions.\n\nSample Formatter Output\n\nDouble pointer to a uint8:\n\t  %v: <**>5\n\t %+v: <**>(0xf8400420d0->0xf8400420c8)5\n\t %#v: (**uint8)5\n\t%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5\n\nPointer to circular struct with a uint8 field and a pointer to itself:\n\t  %v: <*>{1 <*><shown>}\n\t %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>}\n\t %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>}\n\t%#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)<shown>}\n\nSee the Printf example for details on the setup of variables being shown\nhere.\n\nErrors\n\nSince it is possible for custom Stringer/error interfaces to panic, spew\ndetects them and handles them internally by printing the panic information\ninline with the output.  Since spew is intended to provide deep pretty printing\ncapabilities on structures, it intentionally does not return any errors.\n*/\npackage spew\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/dump.go",
    "content": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\npackage spew\n\nimport (\n\t\"bytes\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nvar (\n\t// uint8Type is a reflect.Type representing a uint8.  It is used to\n\t// convert cgo types to uint8 slices for hexdumping.\n\tuint8Type = reflect.TypeOf(uint8(0))\n\n\t// cCharRE is a regular expression that matches a cgo char.\n\t// It is used to detect character arrays to hexdump them.\n\tcCharRE = regexp.MustCompile(`^.*\\._Ctype_char$`)\n\n\t// cUnsignedCharRE is a regular expression that matches a cgo unsigned\n\t// char.  It is used to detect unsigned character arrays to hexdump\n\t// them.\n\tcUnsignedCharRE = regexp.MustCompile(`^.*\\._Ctype_unsignedchar$`)\n\n\t// cUint8tCharRE is a regular expression that matches a cgo uint8_t.\n\t// It is used to detect uint8_t arrays to hexdump them.\n\tcUint8tCharRE = regexp.MustCompile(`^.*\\._Ctype_uint8_t$`)\n)\n\n// dumpState contains information about the state of a dump operation.\ntype dumpState struct {\n\tw                io.Writer\n\tdepth            int\n\tpointers         map[uintptr]int\n\tignoreNextType   bool\n\tignoreNextIndent bool\n\tcs               *ConfigState\n}\n\n// indent performs indentation according to the depth level and cs.Indent\n// option.\nfunc (d *dumpState) indent() {\n\tif d.ignoreNextIndent {\n\t\td.ignoreNextIndent = false\n\t\treturn\n\t}\n\td.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth))\n}\n\n// unpackValue returns values inside of non-nil interfaces when possible.\n// This is useful for data types like structs, arrays, slices, and maps which\n// can contain varying types packed inside an interface.\nfunc (d *dumpState) unpackValue(v reflect.Value) reflect.Value {\n\tif v.Kind() == reflect.Interface && !v.IsNil() {\n\t\tv = v.Elem()\n\t}\n\treturn v\n}\n\n// dumpPtr handles formatting of pointers by indirecting them as necessary.\nfunc (d *dumpState) dumpPtr(v reflect.Value) {\n\t// Remove pointers at or below the current depth from map used to detect\n\t// circular refs.\n\tfor k, depth := range d.pointers {\n\t\tif depth >= d.depth {\n\t\t\tdelete(d.pointers, k)\n\t\t}\n\t}\n\n\t// Keep list of all dereferenced pointers to show later.\n\tpointerChain := make([]uintptr, 0)\n\n\t// Figure out how many levels of indirection there are by dereferencing\n\t// pointers and unpacking interfaces down the chain while detecting circular\n\t// references.\n\tnilFound := false\n\tcycleFound := false\n\tindirects := 0\n\tve := v\n\tfor ve.Kind() == reflect.Ptr {\n\t\tif ve.IsNil() {\n\t\t\tnilFound = true\n\t\t\tbreak\n\t\t}\n\t\tindirects++\n\t\taddr := ve.Pointer()\n\t\tpointerChain = append(pointerChain, addr)\n\t\tif pd, ok := d.pointers[addr]; ok && pd < d.depth {\n\t\t\tcycleFound = true\n\t\t\tindirects--\n\t\t\tbreak\n\t\t}\n\t\td.pointers[addr] = d.depth\n\n\t\tve = ve.Elem()\n\t\tif ve.Kind() == reflect.Interface {\n\t\t\tif ve.IsNil() {\n\t\t\t\tnilFound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tve = ve.Elem()\n\t\t}\n\t}\n\n\t// Display type information.\n\td.w.Write(openParenBytes)\n\td.w.Write(bytes.Repeat(asteriskBytes, indirects))\n\td.w.Write([]byte(ve.Type().String()))\n\td.w.Write(closeParenBytes)\n\n\t// Display pointer information.\n\tif !d.cs.DisablePointerAddresses && len(pointerChain) > 0 {\n\t\td.w.Write(openParenBytes)\n\t\tfor i, addr := range pointerChain {\n\t\t\tif i > 0 {\n\t\t\t\td.w.Write(pointerChainBytes)\n\t\t\t}\n\t\t\tprintHexPtr(d.w, addr)\n\t\t}\n\t\td.w.Write(closeParenBytes)\n\t}\n\n\t// Display dereferenced value.\n\td.w.Write(openParenBytes)\n\tswitch {\n\tcase nilFound:\n\t\td.w.Write(nilAngleBytes)\n\n\tcase cycleFound:\n\t\td.w.Write(circularBytes)\n\n\tdefault:\n\t\td.ignoreNextType = true\n\t\td.dump(ve)\n\t}\n\td.w.Write(closeParenBytes)\n}\n\n// dumpSlice handles formatting of arrays and slices.  Byte (uint8 under\n// reflection) arrays and slices are dumped in hexdump -C fashion.\nfunc (d *dumpState) dumpSlice(v reflect.Value) {\n\t// Determine whether this type should be hex dumped or not.  Also,\n\t// for types which should be hexdumped, try to use the underlying data\n\t// first, then fall back to trying to convert them to a uint8 slice.\n\tvar buf []uint8\n\tdoConvert := false\n\tdoHexDump := false\n\tnumEntries := v.Len()\n\tif numEntries > 0 {\n\t\tvt := v.Index(0).Type()\n\t\tvts := vt.String()\n\t\tswitch {\n\t\t// C types that need to be converted.\n\t\tcase cCharRE.MatchString(vts):\n\t\t\tfallthrough\n\t\tcase cUnsignedCharRE.MatchString(vts):\n\t\t\tfallthrough\n\t\tcase cUint8tCharRE.MatchString(vts):\n\t\t\tdoConvert = true\n\n\t\t// Try to use existing uint8 slices and fall back to converting\n\t\t// and copying if that fails.\n\t\tcase vt.Kind() == reflect.Uint8:\n\t\t\t// We need an addressable interface to convert the type\n\t\t\t// to a byte slice.  However, the reflect package won't\n\t\t\t// give us an interface on certain things like\n\t\t\t// unexported struct fields in order to enforce\n\t\t\t// visibility rules.  We use unsafe, when available, to\n\t\t\t// bypass these restrictions since this package does not\n\t\t\t// mutate the values.\n\t\t\tvs := v\n\t\t\tif !vs.CanInterface() || !vs.CanAddr() {\n\t\t\t\tvs = unsafeReflectValue(vs)\n\t\t\t}\n\t\t\tif !UnsafeDisabled {\n\t\t\t\tvs = vs.Slice(0, numEntries)\n\n\t\t\t\t// Use the existing uint8 slice if it can be\n\t\t\t\t// type asserted.\n\t\t\t\tiface := vs.Interface()\n\t\t\t\tif slice, ok := iface.([]uint8); ok {\n\t\t\t\t\tbuf = slice\n\t\t\t\t\tdoHexDump = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// The underlying data needs to be converted if it can't\n\t\t\t// be type asserted to a uint8 slice.\n\t\t\tdoConvert = true\n\t\t}\n\n\t\t// Copy and convert the underlying type if needed.\n\t\tif doConvert && vt.ConvertibleTo(uint8Type) {\n\t\t\t// Convert and copy each element into a uint8 byte\n\t\t\t// slice.\n\t\t\tbuf = make([]uint8, numEntries)\n\t\t\tfor i := 0; i < numEntries; i++ {\n\t\t\t\tvv := v.Index(i)\n\t\t\t\tbuf[i] = uint8(vv.Convert(uint8Type).Uint())\n\t\t\t}\n\t\t\tdoHexDump = true\n\t\t}\n\t}\n\n\t// Hexdump the entire slice as needed.\n\tif doHexDump {\n\t\tindent := strings.Repeat(d.cs.Indent, d.depth)\n\t\tstr := indent + hex.Dump(buf)\n\t\tstr = strings.Replace(str, \"\\n\", \"\\n\"+indent, -1)\n\t\tstr = strings.TrimRight(str, d.cs.Indent)\n\t\td.w.Write([]byte(str))\n\t\treturn\n\t}\n\n\t// Recursively call dump for each item.\n\tfor i := 0; i < numEntries; i++ {\n\t\td.dump(d.unpackValue(v.Index(i)))\n\t\tif i < (numEntries - 1) {\n\t\t\td.w.Write(commaNewlineBytes)\n\t\t} else {\n\t\t\td.w.Write(newlineBytes)\n\t\t}\n\t}\n}\n\n// dump is the main workhorse for dumping a value.  It uses the passed reflect\n// value to figure out what kind of object we are dealing with and formats it\n// appropriately.  It is a recursive function, however circular data structures\n// are detected and handled properly.\nfunc (d *dumpState) dump(v reflect.Value) {\n\t// Handle invalid reflect values immediately.\n\tkind := v.Kind()\n\tif kind == reflect.Invalid {\n\t\td.w.Write(invalidAngleBytes)\n\t\treturn\n\t}\n\n\t// Handle pointers specially.\n\tif kind == reflect.Ptr {\n\t\td.indent()\n\t\td.dumpPtr(v)\n\t\treturn\n\t}\n\n\t// Print type information unless already handled elsewhere.\n\tif !d.ignoreNextType {\n\t\td.indent()\n\t\td.w.Write(openParenBytes)\n\t\td.w.Write([]byte(v.Type().String()))\n\t\td.w.Write(closeParenBytes)\n\t\td.w.Write(spaceBytes)\n\t}\n\td.ignoreNextType = false\n\n\t// Display length and capacity if the built-in len and cap functions\n\t// work with the value's kind and the len/cap itself is non-zero.\n\tvalueLen, valueCap := 0, 0\n\tswitch v.Kind() {\n\tcase reflect.Array, reflect.Slice, reflect.Chan:\n\t\tvalueLen, valueCap = v.Len(), v.Cap()\n\tcase reflect.Map, reflect.String:\n\t\tvalueLen = v.Len()\n\t}\n\tif valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 {\n\t\td.w.Write(openParenBytes)\n\t\tif valueLen != 0 {\n\t\t\td.w.Write(lenEqualsBytes)\n\t\t\tprintInt(d.w, int64(valueLen), 10)\n\t\t}\n\t\tif !d.cs.DisableCapacities && valueCap != 0 {\n\t\t\tif valueLen != 0 {\n\t\t\t\td.w.Write(spaceBytes)\n\t\t\t}\n\t\t\td.w.Write(capEqualsBytes)\n\t\t\tprintInt(d.w, int64(valueCap), 10)\n\t\t}\n\t\td.w.Write(closeParenBytes)\n\t\td.w.Write(spaceBytes)\n\t}\n\n\t// Call Stringer/error interfaces if they exist and the handle methods flag\n\t// is enabled\n\tif !d.cs.DisableMethods {\n\t\tif (kind != reflect.Invalid) && (kind != reflect.Interface) {\n\t\t\tif handled := handleMethods(d.cs, d.w, v); handled {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tswitch kind {\n\tcase reflect.Invalid:\n\t\t// Do nothing.  We should never get here since invalid has already\n\t\t// been handled above.\n\n\tcase reflect.Bool:\n\t\tprintBool(d.w, v.Bool())\n\n\tcase reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:\n\t\tprintInt(d.w, v.Int(), 10)\n\n\tcase reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:\n\t\tprintUint(d.w, v.Uint(), 10)\n\n\tcase reflect.Float32:\n\t\tprintFloat(d.w, v.Float(), 32)\n\n\tcase reflect.Float64:\n\t\tprintFloat(d.w, v.Float(), 64)\n\n\tcase reflect.Complex64:\n\t\tprintComplex(d.w, v.Complex(), 32)\n\n\tcase reflect.Complex128:\n\t\tprintComplex(d.w, v.Complex(), 64)\n\n\tcase reflect.Slice:\n\t\tif v.IsNil() {\n\t\t\td.w.Write(nilAngleBytes)\n\t\t\tbreak\n\t\t}\n\t\tfallthrough\n\n\tcase reflect.Array:\n\t\td.w.Write(openBraceNewlineBytes)\n\t\td.depth++\n\t\tif (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {\n\t\t\td.indent()\n\t\t\td.w.Write(maxNewlineBytes)\n\t\t} else {\n\t\t\td.dumpSlice(v)\n\t\t}\n\t\td.depth--\n\t\td.indent()\n\t\td.w.Write(closeBraceBytes)\n\n\tcase reflect.String:\n\t\td.w.Write([]byte(strconv.Quote(v.String())))\n\n\tcase reflect.Interface:\n\t\t// The only time we should get here is for nil interfaces due to\n\t\t// unpackValue calls.\n\t\tif v.IsNil() {\n\t\t\td.w.Write(nilAngleBytes)\n\t\t}\n\n\tcase reflect.Ptr:\n\t\t// Do nothing.  We should never get here since pointers have already\n\t\t// been handled above.\n\n\tcase reflect.Map:\n\t\t// nil maps should be indicated as different than empty maps\n\t\tif v.IsNil() {\n\t\t\td.w.Write(nilAngleBytes)\n\t\t\tbreak\n\t\t}\n\n\t\td.w.Write(openBraceNewlineBytes)\n\t\td.depth++\n\t\tif (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {\n\t\t\td.indent()\n\t\t\td.w.Write(maxNewlineBytes)\n\t\t} else {\n\t\t\tnumEntries := v.Len()\n\t\t\tkeys := v.MapKeys()\n\t\t\tif d.cs.SortKeys {\n\t\t\t\tsortValues(keys, d.cs)\n\t\t\t}\n\t\t\tfor i, key := range keys {\n\t\t\t\td.dump(d.unpackValue(key))\n\t\t\t\td.w.Write(colonSpaceBytes)\n\t\t\t\td.ignoreNextIndent = true\n\t\t\t\td.dump(d.unpackValue(v.MapIndex(key)))\n\t\t\t\tif i < (numEntries - 1) {\n\t\t\t\t\td.w.Write(commaNewlineBytes)\n\t\t\t\t} else {\n\t\t\t\t\td.w.Write(newlineBytes)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\td.depth--\n\t\td.indent()\n\t\td.w.Write(closeBraceBytes)\n\n\tcase reflect.Struct:\n\t\td.w.Write(openBraceNewlineBytes)\n\t\td.depth++\n\t\tif (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {\n\t\t\td.indent()\n\t\t\td.w.Write(maxNewlineBytes)\n\t\t} else {\n\t\t\tvt := v.Type()\n\t\t\tnumFields := v.NumField()\n\t\t\tfor i := 0; i < numFields; i++ {\n\t\t\t\td.indent()\n\t\t\t\tvtf := vt.Field(i)\n\t\t\t\td.w.Write([]byte(vtf.Name))\n\t\t\t\td.w.Write(colonSpaceBytes)\n\t\t\t\td.ignoreNextIndent = true\n\t\t\t\td.dump(d.unpackValue(v.Field(i)))\n\t\t\t\tif i < (numFields - 1) {\n\t\t\t\t\td.w.Write(commaNewlineBytes)\n\t\t\t\t} else {\n\t\t\t\t\td.w.Write(newlineBytes)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\td.depth--\n\t\td.indent()\n\t\td.w.Write(closeBraceBytes)\n\n\tcase reflect.Uintptr:\n\t\tprintHexPtr(d.w, uintptr(v.Uint()))\n\n\tcase reflect.UnsafePointer, reflect.Chan, reflect.Func:\n\t\tprintHexPtr(d.w, v.Pointer())\n\n\t// There were not any other types at the time this code was written, but\n\t// fall back to letting the default fmt package handle it in case any new\n\t// types are added.\n\tdefault:\n\t\tif v.CanInterface() {\n\t\t\tfmt.Fprintf(d.w, \"%v\", v.Interface())\n\t\t} else {\n\t\t\tfmt.Fprintf(d.w, \"%v\", v.String())\n\t\t}\n\t}\n}\n\n// fdump is a helper function to consolidate the logic from the various public\n// methods which take varying writers and config states.\nfunc fdump(cs *ConfigState, w io.Writer, a ...interface{}) {\n\tfor _, arg := range a {\n\t\tif arg == nil {\n\t\t\tw.Write(interfaceBytes)\n\t\t\tw.Write(spaceBytes)\n\t\t\tw.Write(nilAngleBytes)\n\t\t\tw.Write(newlineBytes)\n\t\t\tcontinue\n\t\t}\n\n\t\td := dumpState{w: w, cs: cs}\n\t\td.pointers = make(map[uintptr]int)\n\t\td.dump(reflect.ValueOf(arg))\n\t\td.w.Write(newlineBytes)\n\t}\n}\n\n// Fdump formats and displays the passed arguments to io.Writer w.  It formats\n// exactly the same as Dump.\nfunc Fdump(w io.Writer, a ...interface{}) {\n\tfdump(&Config, w, a...)\n}\n\n// Sdump returns a string with the passed arguments formatted exactly the same\n// as Dump.\nfunc Sdump(a ...interface{}) string {\n\tvar buf bytes.Buffer\n\tfdump(&Config, &buf, a...)\n\treturn buf.String()\n}\n\n/*\nDump displays the passed parameters to standard out with newlines, customizable\nindentation, and additional debug information such as complete types and all\npointer addresses used to indirect to the final value.  It provides the\nfollowing features over the built-in printing facilities provided by the fmt\npackage:\n\n\t* Pointers are dereferenced and followed\n\t* Circular data structures are detected and handled properly\n\t* Custom Stringer/error interfaces are optionally invoked, including\n\t  on unexported types\n\t* Custom types which only implement the Stringer/error interfaces via\n\t  a pointer receiver are optionally invoked when passing non-pointer\n\t  variables\n\t* Byte arrays and slices are dumped like the hexdump -C command which\n\t  includes offsets, byte values in hex, and ASCII output\n\nThe configuration options are controlled by an exported package global,\nspew.Config.  See ConfigState for options documentation.\n\nSee Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to\nget the formatted result as a string.\n*/\nfunc Dump(a ...interface{}) {\n\tfdump(&Config, os.Stdout, a...)\n}\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/format.go",
    "content": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\npackage spew\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// supportedFlags is a list of all the character flags supported by fmt package.\nconst supportedFlags = \"0-+# \"\n\n// formatState implements the fmt.Formatter interface and contains information\n// about the state of a formatting operation.  The NewFormatter function can\n// be used to get a new Formatter which can be used directly as arguments\n// in standard fmt package printing calls.\ntype formatState struct {\n\tvalue          interface{}\n\tfs             fmt.State\n\tdepth          int\n\tpointers       map[uintptr]int\n\tignoreNextType bool\n\tcs             *ConfigState\n}\n\n// buildDefaultFormat recreates the original format string without precision\n// and width information to pass in to fmt.Sprintf in the case of an\n// unrecognized type.  Unless new types are added to the language, this\n// function won't ever be called.\nfunc (f *formatState) buildDefaultFormat() (format string) {\n\tbuf := bytes.NewBuffer(percentBytes)\n\n\tfor _, flag := range supportedFlags {\n\t\tif f.fs.Flag(int(flag)) {\n\t\t\tbuf.WriteRune(flag)\n\t\t}\n\t}\n\n\tbuf.WriteRune('v')\n\n\tformat = buf.String()\n\treturn format\n}\n\n// constructOrigFormat recreates the original format string including precision\n// and width information to pass along to the standard fmt package.  This allows\n// automatic deferral of all format strings this package doesn't support.\nfunc (f *formatState) constructOrigFormat(verb rune) (format string) {\n\tbuf := bytes.NewBuffer(percentBytes)\n\n\tfor _, flag := range supportedFlags {\n\t\tif f.fs.Flag(int(flag)) {\n\t\t\tbuf.WriteRune(flag)\n\t\t}\n\t}\n\n\tif width, ok := f.fs.Width(); ok {\n\t\tbuf.WriteString(strconv.Itoa(width))\n\t}\n\n\tif precision, ok := f.fs.Precision(); ok {\n\t\tbuf.Write(precisionBytes)\n\t\tbuf.WriteString(strconv.Itoa(precision))\n\t}\n\n\tbuf.WriteRune(verb)\n\n\tformat = buf.String()\n\treturn format\n}\n\n// unpackValue returns values inside of non-nil interfaces when possible and\n// ensures that types for values which have been unpacked from an interface\n// are displayed when the show types flag is also set.\n// This is useful for data types like structs, arrays, slices, and maps which\n// can contain varying types packed inside an interface.\nfunc (f *formatState) unpackValue(v reflect.Value) reflect.Value {\n\tif v.Kind() == reflect.Interface {\n\t\tf.ignoreNextType = false\n\t\tif !v.IsNil() {\n\t\t\tv = v.Elem()\n\t\t}\n\t}\n\treturn v\n}\n\n// formatPtr handles formatting of pointers by indirecting them as necessary.\nfunc (f *formatState) formatPtr(v reflect.Value) {\n\t// Display nil if top level pointer is nil.\n\tshowTypes := f.fs.Flag('#')\n\tif v.IsNil() && (!showTypes || f.ignoreNextType) {\n\t\tf.fs.Write(nilAngleBytes)\n\t\treturn\n\t}\n\n\t// Remove pointers at or below the current depth from map used to detect\n\t// circular refs.\n\tfor k, depth := range f.pointers {\n\t\tif depth >= f.depth {\n\t\t\tdelete(f.pointers, k)\n\t\t}\n\t}\n\n\t// Keep list of all dereferenced pointers to possibly show later.\n\tpointerChain := make([]uintptr, 0)\n\n\t// Figure out how many levels of indirection there are by derferencing\n\t// pointers and unpacking interfaces down the chain while detecting circular\n\t// references.\n\tnilFound := false\n\tcycleFound := false\n\tindirects := 0\n\tve := v\n\tfor ve.Kind() == reflect.Ptr {\n\t\tif ve.IsNil() {\n\t\t\tnilFound = true\n\t\t\tbreak\n\t\t}\n\t\tindirects++\n\t\taddr := ve.Pointer()\n\t\tpointerChain = append(pointerChain, addr)\n\t\tif pd, ok := f.pointers[addr]; ok && pd < f.depth {\n\t\t\tcycleFound = true\n\t\t\tindirects--\n\t\t\tbreak\n\t\t}\n\t\tf.pointers[addr] = f.depth\n\n\t\tve = ve.Elem()\n\t\tif ve.Kind() == reflect.Interface {\n\t\t\tif ve.IsNil() {\n\t\t\t\tnilFound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tve = ve.Elem()\n\t\t}\n\t}\n\n\t// Display type or indirection level depending on flags.\n\tif showTypes && !f.ignoreNextType {\n\t\tf.fs.Write(openParenBytes)\n\t\tf.fs.Write(bytes.Repeat(asteriskBytes, indirects))\n\t\tf.fs.Write([]byte(ve.Type().String()))\n\t\tf.fs.Write(closeParenBytes)\n\t} else {\n\t\tif nilFound || cycleFound {\n\t\t\tindirects += strings.Count(ve.Type().String(), \"*\")\n\t\t}\n\t\tf.fs.Write(openAngleBytes)\n\t\tf.fs.Write([]byte(strings.Repeat(\"*\", indirects)))\n\t\tf.fs.Write(closeAngleBytes)\n\t}\n\n\t// Display pointer information depending on flags.\n\tif f.fs.Flag('+') && (len(pointerChain) > 0) {\n\t\tf.fs.Write(openParenBytes)\n\t\tfor i, addr := range pointerChain {\n\t\t\tif i > 0 {\n\t\t\t\tf.fs.Write(pointerChainBytes)\n\t\t\t}\n\t\t\tprintHexPtr(f.fs, addr)\n\t\t}\n\t\tf.fs.Write(closeParenBytes)\n\t}\n\n\t// Display dereferenced value.\n\tswitch {\n\tcase nilFound:\n\t\tf.fs.Write(nilAngleBytes)\n\n\tcase cycleFound:\n\t\tf.fs.Write(circularShortBytes)\n\n\tdefault:\n\t\tf.ignoreNextType = true\n\t\tf.format(ve)\n\t}\n}\n\n// format is the main workhorse for providing the Formatter interface.  It\n// uses the passed reflect value to figure out what kind of object we are\n// dealing with and formats it appropriately.  It is a recursive function,\n// however circular data structures are detected and handled properly.\nfunc (f *formatState) format(v reflect.Value) {\n\t// Handle invalid reflect values immediately.\n\tkind := v.Kind()\n\tif kind == reflect.Invalid {\n\t\tf.fs.Write(invalidAngleBytes)\n\t\treturn\n\t}\n\n\t// Handle pointers specially.\n\tif kind == reflect.Ptr {\n\t\tf.formatPtr(v)\n\t\treturn\n\t}\n\n\t// Print type information unless already handled elsewhere.\n\tif !f.ignoreNextType && f.fs.Flag('#') {\n\t\tf.fs.Write(openParenBytes)\n\t\tf.fs.Write([]byte(v.Type().String()))\n\t\tf.fs.Write(closeParenBytes)\n\t}\n\tf.ignoreNextType = false\n\n\t// Call Stringer/error interfaces if they exist and the handle methods\n\t// flag is enabled.\n\tif !f.cs.DisableMethods {\n\t\tif (kind != reflect.Invalid) && (kind != reflect.Interface) {\n\t\t\tif handled := handleMethods(f.cs, f.fs, v); handled {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tswitch kind {\n\tcase reflect.Invalid:\n\t\t// Do nothing.  We should never get here since invalid has already\n\t\t// been handled above.\n\n\tcase reflect.Bool:\n\t\tprintBool(f.fs, v.Bool())\n\n\tcase reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:\n\t\tprintInt(f.fs, v.Int(), 10)\n\n\tcase reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:\n\t\tprintUint(f.fs, v.Uint(), 10)\n\n\tcase reflect.Float32:\n\t\tprintFloat(f.fs, v.Float(), 32)\n\n\tcase reflect.Float64:\n\t\tprintFloat(f.fs, v.Float(), 64)\n\n\tcase reflect.Complex64:\n\t\tprintComplex(f.fs, v.Complex(), 32)\n\n\tcase reflect.Complex128:\n\t\tprintComplex(f.fs, v.Complex(), 64)\n\n\tcase reflect.Slice:\n\t\tif v.IsNil() {\n\t\t\tf.fs.Write(nilAngleBytes)\n\t\t\tbreak\n\t\t}\n\t\tfallthrough\n\n\tcase reflect.Array:\n\t\tf.fs.Write(openBracketBytes)\n\t\tf.depth++\n\t\tif (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {\n\t\t\tf.fs.Write(maxShortBytes)\n\t\t} else {\n\t\t\tnumEntries := v.Len()\n\t\t\tfor i := 0; i < numEntries; i++ {\n\t\t\t\tif i > 0 {\n\t\t\t\t\tf.fs.Write(spaceBytes)\n\t\t\t\t}\n\t\t\t\tf.ignoreNextType = true\n\t\t\t\tf.format(f.unpackValue(v.Index(i)))\n\t\t\t}\n\t\t}\n\t\tf.depth--\n\t\tf.fs.Write(closeBracketBytes)\n\n\tcase reflect.String:\n\t\tf.fs.Write([]byte(v.String()))\n\n\tcase reflect.Interface:\n\t\t// The only time we should get here is for nil interfaces due to\n\t\t// unpackValue calls.\n\t\tif v.IsNil() {\n\t\t\tf.fs.Write(nilAngleBytes)\n\t\t}\n\n\tcase reflect.Ptr:\n\t\t// Do nothing.  We should never get here since pointers have already\n\t\t// been handled above.\n\n\tcase reflect.Map:\n\t\t// nil maps should be indicated as different than empty maps\n\t\tif v.IsNil() {\n\t\t\tf.fs.Write(nilAngleBytes)\n\t\t\tbreak\n\t\t}\n\n\t\tf.fs.Write(openMapBytes)\n\t\tf.depth++\n\t\tif (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {\n\t\t\tf.fs.Write(maxShortBytes)\n\t\t} else {\n\t\t\tkeys := v.MapKeys()\n\t\t\tif f.cs.SortKeys {\n\t\t\t\tsortValues(keys, f.cs)\n\t\t\t}\n\t\t\tfor i, key := range keys {\n\t\t\t\tif i > 0 {\n\t\t\t\t\tf.fs.Write(spaceBytes)\n\t\t\t\t}\n\t\t\t\tf.ignoreNextType = true\n\t\t\t\tf.format(f.unpackValue(key))\n\t\t\t\tf.fs.Write(colonBytes)\n\t\t\t\tf.ignoreNextType = true\n\t\t\t\tf.format(f.unpackValue(v.MapIndex(key)))\n\t\t\t}\n\t\t}\n\t\tf.depth--\n\t\tf.fs.Write(closeMapBytes)\n\n\tcase reflect.Struct:\n\t\tnumFields := v.NumField()\n\t\tf.fs.Write(openBraceBytes)\n\t\tf.depth++\n\t\tif (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {\n\t\t\tf.fs.Write(maxShortBytes)\n\t\t} else {\n\t\t\tvt := v.Type()\n\t\t\tfor i := 0; i < numFields; i++ {\n\t\t\t\tif i > 0 {\n\t\t\t\t\tf.fs.Write(spaceBytes)\n\t\t\t\t}\n\t\t\t\tvtf := vt.Field(i)\n\t\t\t\tif f.fs.Flag('+') || f.fs.Flag('#') {\n\t\t\t\t\tf.fs.Write([]byte(vtf.Name))\n\t\t\t\t\tf.fs.Write(colonBytes)\n\t\t\t\t}\n\t\t\t\tf.format(f.unpackValue(v.Field(i)))\n\t\t\t}\n\t\t}\n\t\tf.depth--\n\t\tf.fs.Write(closeBraceBytes)\n\n\tcase reflect.Uintptr:\n\t\tprintHexPtr(f.fs, uintptr(v.Uint()))\n\n\tcase reflect.UnsafePointer, reflect.Chan, reflect.Func:\n\t\tprintHexPtr(f.fs, v.Pointer())\n\n\t// There were not any other types at the time this code was written, but\n\t// fall back to letting the default fmt package handle it if any get added.\n\tdefault:\n\t\tformat := f.buildDefaultFormat()\n\t\tif v.CanInterface() {\n\t\t\tfmt.Fprintf(f.fs, format, v.Interface())\n\t\t} else {\n\t\t\tfmt.Fprintf(f.fs, format, v.String())\n\t\t}\n\t}\n}\n\n// Format satisfies the fmt.Formatter interface. See NewFormatter for usage\n// details.\nfunc (f *formatState) Format(fs fmt.State, verb rune) {\n\tf.fs = fs\n\n\t// Use standard formatting for verbs that are not v.\n\tif verb != 'v' {\n\t\tformat := f.constructOrigFormat(verb)\n\t\tfmt.Fprintf(fs, format, f.value)\n\t\treturn\n\t}\n\n\tif f.value == nil {\n\t\tif fs.Flag('#') {\n\t\t\tfs.Write(interfaceBytes)\n\t\t}\n\t\tfs.Write(nilAngleBytes)\n\t\treturn\n\t}\n\n\tf.format(reflect.ValueOf(f.value))\n}\n\n// newFormatter is a helper function to consolidate the logic from the various\n// public methods which take varying config states.\nfunc newFormatter(cs *ConfigState, v interface{}) fmt.Formatter {\n\tfs := &formatState{value: v, cs: cs}\n\tfs.pointers = make(map[uintptr]int)\n\treturn fs\n}\n\n/*\nNewFormatter returns a custom formatter that satisfies the fmt.Formatter\ninterface.  As a result, it integrates cleanly with standard fmt package\nprinting functions.  The formatter is useful for inline printing of smaller data\ntypes similar to the standard %v format specifier.\n\nThe custom formatter only responds to the %v (most compact), %+v (adds pointer\naddresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb\ncombinations.  Any other verbs such as %x and %q will be sent to the the\nstandard fmt package for formatting.  In addition, the custom formatter ignores\nthe width and precision arguments (however they will still work on the format\nspecifiers not handled by the custom formatter).\n\nTypically this function shouldn't be called directly.  It is much easier to make\nuse of the custom formatter by calling one of the convenience functions such as\nPrintf, Println, or Fprintf.\n*/\nfunc NewFormatter(v interface{}) fmt.Formatter {\n\treturn newFormatter(&Config, v)\n}\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/spew.go",
    "content": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\npackage spew\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were\n// passed with a default Formatter interface returned by NewFormatter.  It\n// returns the formatted string as a value that satisfies error.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Errorf(format string, a ...interface{}) (err error) {\n\treturn fmt.Errorf(format, convertArgs(a)...)\n}\n\n// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were\n// passed with a default Formatter interface returned by NewFormatter.  It\n// returns the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Fprint(w io.Writer, a ...interface{}) (n int, err error) {\n\treturn fmt.Fprint(w, convertArgs(a)...)\n}\n\n// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were\n// passed with a default Formatter interface returned by NewFormatter.  It\n// returns the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {\n\treturn fmt.Fprintf(w, format, convertArgs(a)...)\n}\n\n// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it\n// passed with a default Formatter interface returned by NewFormatter.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Fprintln(w io.Writer, a ...interface{}) (n int, err error) {\n\treturn fmt.Fprintln(w, convertArgs(a)...)\n}\n\n// Print is a wrapper for fmt.Print that treats each argument as if it were\n// passed with a default Formatter interface returned by NewFormatter.  It\n// returns the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Print(spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Print(a ...interface{}) (n int, err error) {\n\treturn fmt.Print(convertArgs(a)...)\n}\n\n// Printf is a wrapper for fmt.Printf that treats each argument as if it were\n// passed with a default Formatter interface returned by NewFormatter.  It\n// returns the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Printf(format string, a ...interface{}) (n int, err error) {\n\treturn fmt.Printf(format, convertArgs(a)...)\n}\n\n// Println is a wrapper for fmt.Println that treats each argument as if it were\n// passed with a default Formatter interface returned by NewFormatter.  It\n// returns the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Println(spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Println(a ...interface{}) (n int, err error) {\n\treturn fmt.Println(convertArgs(a)...)\n}\n\n// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were\n// passed with a default Formatter interface returned by NewFormatter.  It\n// returns the resulting string.  See NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Sprint(a ...interface{}) string {\n\treturn fmt.Sprint(convertArgs(a)...)\n}\n\n// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were\n// passed with a default Formatter interface returned by NewFormatter.  It\n// returns the resulting string.  See NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Sprintf(format string, a ...interface{}) string {\n\treturn fmt.Sprintf(format, convertArgs(a)...)\n}\n\n// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it\n// were passed with a default Formatter interface returned by NewFormatter.  It\n// returns the resulting string.  See NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Sprintln(a ...interface{}) string {\n\treturn fmt.Sprintln(convertArgs(a)...)\n}\n\n// convertArgs accepts a slice of arguments and returns a slice of the same\n// length with each argument converted to a default spew Formatter interface.\nfunc convertArgs(args []interface{}) (formatters []interface{}) {\n\tformatters = make([]interface{}, len(args))\n\tfor index, arg := range args {\n\t\tformatters[index] = NewFormatter(arg)\n\t}\n\treturn formatters\n}\n"
  },
  {
    "path": "vendor/github.com/facebookgo/grace/gracenet/net.go",
    "content": "// Package gracenet provides a family of Listen functions that either open a\n// fresh connection or provide an inherited connection from when the process\n// was started. The behave like their counterparts in the net package, but\n// transparently provide support for graceful restarts without dropping\n// connections. This is provided in a systemd socket activation compatible form\n// to allow using socket activation.\n//\n// BUG: Doesn't handle closing of listeners.\npackage gracenet\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n)\n\nconst (\n\t// Used to indicate a graceful restart in the new process.\n\tenvCountKey       = \"LISTEN_FDS\"\n\tenvCountKeyPrefix = envCountKey + \"=\"\n)\n\n// In order to keep the working directory the same as when we started we record\n// it at startup.\nvar originalWD, _ = os.Getwd()\n\n// Net provides the family of Listen functions and maintains the associated\n// state. Typically you will have only once instance of Net per application.\ntype Net struct {\n\tinherited   []net.Listener\n\tactive      []net.Listener\n\tmutex       sync.Mutex\n\tinheritOnce sync.Once\n\n\t// used in tests to override the default behavior of starting from fd 3.\n\tfdStart int\n}\n\nfunc (n *Net) inherit() error {\n\tvar retErr error\n\tn.inheritOnce.Do(func() {\n\t\tn.mutex.Lock()\n\t\tdefer n.mutex.Unlock()\n\t\tcountStr := os.Getenv(envCountKey)\n\t\tif countStr == \"\" {\n\t\t\treturn\n\t\t}\n\t\tcount, err := strconv.Atoi(countStr)\n\t\tif err != nil {\n\t\t\tretErr = fmt.Errorf(\"found invalid count value: %s=%s\", envCountKey, countStr)\n\t\t\treturn\n\t\t}\n\n\t\t// In tests this may be overridden.\n\t\tfdStart := n.fdStart\n\t\tif fdStart == 0 {\n\t\t\t// In normal operations if we are inheriting, the listeners will begin at\n\t\t\t// fd 3.\n\t\t\tfdStart = 3\n\t\t}\n\n\t\tfor i := fdStart; i < fdStart+count; i++ {\n\t\t\tfile := os.NewFile(uintptr(i), \"listener\")\n\t\t\tl, err := net.FileListener(file)\n\t\t\tif err != nil {\n\t\t\t\tfile.Close()\n\t\t\t\tretErr = fmt.Errorf(\"error inheriting socket fd %d: %s\", i, err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif err := file.Close(); err != nil {\n\t\t\t\tretErr = fmt.Errorf(\"error closing inherited socket fd %d: %s\", i, err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tn.inherited = append(n.inherited, l)\n\t\t}\n\t})\n\treturn retErr\n}\n\n// Listen announces on the local network address laddr. The network net must be\n// a stream-oriented network: \"tcp\", \"tcp4\", \"tcp6\", \"unix\" or \"unixpacket\". It\n// returns an inherited net.Listener for the matching network and address, or\n// creates a new one using net.Listen.\nfunc (n *Net) Listen(nett, laddr string) (net.Listener, error) {\n\tswitch nett {\n\tdefault:\n\t\treturn nil, net.UnknownNetworkError(nett)\n\tcase \"tcp\", \"tcp4\", \"tcp6\":\n\t\taddr, err := net.ResolveTCPAddr(nett, laddr)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn n.ListenTCP(nett, addr)\n\tcase \"unix\", \"unixpacket\", \"invalid_unix_net_for_test\":\n\t\taddr, err := net.ResolveUnixAddr(nett, laddr)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn n.ListenUnix(nett, addr)\n\t}\n}\n\n// ListenTCP announces on the local network address laddr. The network net must\n// be: \"tcp\", \"tcp4\" or \"tcp6\". It returns an inherited net.Listener for the\n// matching network and address, or creates a new one using net.ListenTCP.\nfunc (n *Net) ListenTCP(nett string, laddr *net.TCPAddr) (*net.TCPListener, error) {\n\tif err := n.inherit(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tn.mutex.Lock()\n\tdefer n.mutex.Unlock()\n\n\t// look for an inherited listener\n\tfor i, l := range n.inherited {\n\t\tif l == nil { // we nil used inherited listeners\n\t\t\tcontinue\n\t\t}\n\t\tif isSameAddr(l.Addr(), laddr) {\n\t\t\tn.inherited[i] = nil\n\t\t\tn.active = append(n.active, l)\n\t\t\treturn l.(*net.TCPListener), nil\n\t\t}\n\t}\n\n\t// make a fresh listener\n\tl, err := net.ListenTCP(nett, laddr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tn.active = append(n.active, l)\n\treturn l, nil\n}\n\n// ListenUnix announces on the local network address laddr. The network net\n// must be a: \"unix\" or \"unixpacket\". It returns an inherited net.Listener for\n// the matching network and address, or creates a new one using net.ListenUnix.\nfunc (n *Net) ListenUnix(nett string, laddr *net.UnixAddr) (*net.UnixListener, error) {\n\tif err := n.inherit(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tn.mutex.Lock()\n\tdefer n.mutex.Unlock()\n\n\t// look for an inherited listener\n\tfor i, l := range n.inherited {\n\t\tif l == nil { // we nil used inherited listeners\n\t\t\tcontinue\n\t\t}\n\t\tif isSameAddr(l.Addr(), laddr) {\n\t\t\tn.inherited[i] = nil\n\t\t\tn.active = append(n.active, l)\n\t\t\treturn l.(*net.UnixListener), nil\n\t\t}\n\t}\n\n\t// make a fresh listener\n\tl, err := net.ListenUnix(nett, laddr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tn.active = append(n.active, l)\n\treturn l, nil\n}\n\n// activeListeners returns a snapshot copy of the active listeners.\nfunc (n *Net) activeListeners() ([]net.Listener, error) {\n\tn.mutex.Lock()\n\tdefer n.mutex.Unlock()\n\tls := make([]net.Listener, len(n.active))\n\tcopy(ls, n.active)\n\treturn ls, nil\n}\n\nfunc isSameAddr(a1, a2 net.Addr) bool {\n\tif a1.Network() != a2.Network() {\n\t\treturn false\n\t}\n\ta1s := a1.String()\n\ta2s := a2.String()\n\tif a1s == a2s {\n\t\treturn true\n\t}\n\n\t// This allows for ipv6 vs ipv4 local addresses to compare as equal. This\n\t// scenario is common when listening on localhost.\n\tconst ipv6prefix = \"[::]\"\n\ta1s = strings.TrimPrefix(a1s, ipv6prefix)\n\ta2s = strings.TrimPrefix(a2s, ipv6prefix)\n\tconst ipv4prefix = \"0.0.0.0\"\n\ta1s = strings.TrimPrefix(a1s, ipv4prefix)\n\ta2s = strings.TrimPrefix(a2s, ipv4prefix)\n\treturn a1s == a2s\n}\n\n// StartProcess starts a new process passing it the active listeners. It\n// doesn't fork, but starts a new process using the same environment and\n// arguments as when it was originally started. This allows for a newly\n// deployed binary to be started. It returns the pid of the newly started\n// process when successful.\nfunc (n *Net) StartProcess() (int, error) {\n\tlisteners, err := n.activeListeners()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\t// Extract the fds from the listeners.\n\tfiles := make([]*os.File, len(listeners))\n\tfor i, l := range listeners {\n\t\tfiles[i], err = l.(filer).File()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tdefer files[i].Close()\n\t}\n\n\t// Use the original binary location. This works with symlinks such that if\n\t// the file it points to has been changed we will use the updated symlink.\n\targv0, err := exec.LookPath(os.Args[0])\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\t// Pass on the environment and replace the old count key with the new one.\n\tvar env []string\n\tfor _, v := range os.Environ() {\n\t\tif !strings.HasPrefix(v, envCountKeyPrefix) {\n\t\t\tenv = append(env, v)\n\t\t}\n\t}\n\tenv = append(env, fmt.Sprintf(\"%s%d\", envCountKeyPrefix, len(listeners)))\n\n\tallFiles := append([]*os.File{os.Stdin, os.Stdout, os.Stderr}, files...)\n\tprocess, err := os.StartProcess(argv0, os.Args, &os.ProcAttr{\n\t\tDir:   originalWD,\n\t\tEnv:   env,\n\t\tFiles: allFiles,\n\t})\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn process.Pid, nil\n}\n\ntype filer interface {\n\tFile() (*os.File, error)\n}\n"
  },
  {
    "path": "vendor/github.com/fortytw2/leaktest/.travis.yml",
    "content": "language: go\ngo:\n - 1.8\n - 1.9\n - \"1.10\"\n - \"1.11\"\n - tip\n\nscript:\n - go test -v -race -parallel 5 -coverprofile=coverage.txt -covermode=atomic ./\n - go test github.com/fortytw2/leaktest -run ^TestEmptyLeak$\n\nbefore_install:\n  - pip install --user codecov\nafter_success:\n  - codecov\n"
  },
  {
    "path": "vendor/github.com/fortytw2/leaktest/LICENSE",
    "content": "Copyright (c) 2012 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(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": "vendor/github.com/fortytw2/leaktest/README.md",
    "content": "## Leaktest [![Build Status](https://travis-ci.org/fortytw2/leaktest.svg?branch=master)](https://travis-ci.org/fortytw2/leaktest) [![codecov](https://codecov.io/gh/fortytw2/leaktest/branch/master/graph/badge.svg)](https://codecov.io/gh/fortytw2/leaktest) [![Sourcegraph](https://sourcegraph.com/github.com/fortytw2/leaktest/-/badge.svg)](https://sourcegraph.com/github.com/fortytw2/leaktest?badge) [![Documentation](https://godoc.org/github.com/fortytw2/gpt?status.svg)](http://godoc.org/github.com/fortytw2/leaktest)\n\nRefactored, tested variant of the goroutine leak detector found in both\n`net/http` tests and the `cockroachdb` source tree.\n\nTakes a snapshot of running goroutines at the start of a test, and at the end -\ncompares the two and _voila_. Ignores runtime/sys goroutines. Doesn't play nice\nwith `t.Parallel()` right now, but there are plans to do so.\n\n### Installation\n\nGo 1.7+\n\n```\ngo get -u github.com/fortytw2/leaktest\n```\n\nGo 1.5/1.6 need to use the tag `v1.0.0`, as newer versions depend on\n`context.Context`.\n\n### Example\n\nThese tests fail, because they leak a goroutine\n\n```go\n// Default \"Check\" will poll for 5 seconds to check that all\n// goroutines are cleaned up\nfunc TestPool(t *testing.T) {\n    defer leaktest.Check(t)()\n\n    go func() {\n        for {\n            time.Sleep(time.Second)\n        }\n    }()\n}\n\n// Helper function to timeout after X duration\nfunc TestPoolTimeout(t *testing.T) {\n    defer leaktest.CheckTimeout(t, time.Second)()\n\n    go func() {\n        for {\n            time.Sleep(time.Second)\n        }\n    }()\n}\n\n// Use Go 1.7+ context.Context for cancellation\nfunc TestPoolContext(t *testing.T) {\n    ctx, _ := context.WithTimeout(context.Background(), time.Second)\n    defer leaktest.CheckContext(ctx, t)()\n\n    go func() {\n        for {\n            time.Sleep(time.Second)\n        }\n    }()\n}\n```\n\n## LICENSE\n\nSame BSD-style as Go, see LICENSE\n"
  },
  {
    "path": "vendor/github.com/fortytw2/leaktest/leaktest.go",
    "content": "// Copyright 2013 The Go 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\n// Package leaktest provides tools to detect leaked goroutines in tests.\n// To use it, call \"defer leaktest.Check(t)()\" at the beginning of each\n// test that may use goroutines.\n// copied out of the cockroachdb source tree with slight modifications to be\n// more re-useable\npackage leaktest\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\ntype goroutine struct {\n\tid    uint64\n\tstack string\n}\n\ntype goroutineByID []*goroutine\n\nfunc (g goroutineByID) Len() int           { return len(g) }\nfunc (g goroutineByID) Less(i, j int) bool { return g[i].id < g[j].id }\nfunc (g goroutineByID) Swap(i, j int)      { g[i], g[j] = g[j], g[i] }\n\nfunc interestingGoroutine(g string) (*goroutine, error) {\n\tsl := strings.SplitN(g, \"\\n\", 2)\n\tif len(sl) != 2 {\n\t\treturn nil, fmt.Errorf(\"error parsing stack: %q\", g)\n\t}\n\tstack := strings.TrimSpace(sl[1])\n\tif strings.HasPrefix(stack, \"testing.RunTests\") {\n\t\treturn nil, nil\n\t}\n\n\tif stack == \"\" ||\n\t\t// Ignore HTTP keep alives\n\t\tstrings.Contains(stack, \").readLoop(\") ||\n\t\tstrings.Contains(stack, \").writeLoop(\") ||\n\t\t// Below are the stacks ignored by the upstream leaktest code.\n\t\tstrings.Contains(stack, \"testing.Main(\") ||\n\t\tstrings.Contains(stack, \"testing.(*T).Run(\") ||\n\t\tstrings.Contains(stack, \"runtime.goexit\") ||\n\t\tstrings.Contains(stack, \"created by runtime.gc\") ||\n\t\tstrings.Contains(stack, \"interestingGoroutines\") ||\n\t\tstrings.Contains(stack, \"runtime.MHeap_Scavenger\") ||\n\t\tstrings.Contains(stack, \"signal.signal_recv\") ||\n\t\tstrings.Contains(stack, \"sigterm.handler\") ||\n\t\tstrings.Contains(stack, \"runtime_mcall\") ||\n\t\tstrings.Contains(stack, \"goroutine in C code\") {\n\t\treturn nil, nil\n\t}\n\n\t// Parse the goroutine's ID from the header line.\n\th := strings.SplitN(sl[0], \" \", 3)\n\tif len(h) < 3 {\n\t\treturn nil, fmt.Errorf(\"error parsing stack header: %q\", sl[0])\n\t}\n\tid, err := strconv.ParseUint(h[1], 10, 64)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing goroutine id: %s\", err)\n\t}\n\n\treturn &goroutine{id: id, stack: strings.TrimSpace(g)}, nil\n}\n\n// interestingGoroutines returns all goroutines we care about for the purpose\n// of leak checking. It excludes testing or runtime ones.\nfunc interestingGoroutines(t ErrorReporter) []*goroutine {\n\tbuf := make([]byte, 2<<20)\n\tbuf = buf[:runtime.Stack(buf, true)]\n\tvar gs []*goroutine\n\tfor _, g := range strings.Split(string(buf), \"\\n\\n\") {\n\t\tgr, err := interestingGoroutine(g)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"leaktest: %s\", err)\n\t\t\tcontinue\n\t\t} else if gr == nil {\n\t\t\tcontinue\n\t\t}\n\t\tgs = append(gs, gr)\n\t}\n\tsort.Sort(goroutineByID(gs))\n\treturn gs\n}\n\n// ErrorReporter is a tiny subset of a testing.TB to make testing not such a\n// massive pain\ntype ErrorReporter interface {\n\tErrorf(format string, args ...interface{})\n}\n\n// Check snapshots the currently-running goroutines and returns a\n// function to be run at the end of tests to see whether any\n// goroutines leaked, waiting up to 5 seconds in error conditions\nfunc Check(t ErrorReporter) func() {\n\treturn CheckTimeout(t, 5*time.Second)\n}\n\n// CheckTimeout is the same as Check, but with a configurable timeout\nfunc CheckTimeout(t ErrorReporter, dur time.Duration) func() {\n\tctx, cancel := context.WithCancel(context.Background())\n\tfn := CheckContext(ctx, t)\n\treturn func() {\n\t\ttimer := time.AfterFunc(dur, cancel)\n\t\tfn()\n\t\t// Remember to clean up the timer and context\n\t\ttimer.Stop()\n\t\tcancel()\n\t}\n}\n\n// CheckContext is the same as Check, but uses a context.Context for\n// cancellation and timeout control\nfunc CheckContext(ctx context.Context, t ErrorReporter) func() {\n\torig := map[uint64]bool{}\n\tfor _, g := range interestingGoroutines(t) {\n\t\torig[g.id] = true\n\t}\n\treturn func() {\n\t\tvar leaked []string\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\tt.Errorf(\"leaktest: timed out checking goroutines\")\n\t\t\tdefault:\n\t\t\t\tleaked = make([]string, 0)\n\t\t\t\tfor _, g := range interestingGoroutines(t) {\n\t\t\t\t\tif !orig[g.id] {\n\t\t\t\t\t\tleaked = append(leaked, g.stack)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif len(leaked) == 0 {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t// don't spin needlessly\n\t\t\t\ttime.Sleep(time.Millisecond * 50)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tfor _, g := range leaked {\n\t\t\tt.Errorf(\"leaktest: leaked goroutine: %v\", g)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/.editorconfig",
    "content": "root = true\n\n[*.go]\nindent_style = tab\nindent_size = 4\ninsert_final_newline = true\n\n[*.{yml,yaml}]\nindent_style = space\nindent_size = 2\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/.gitattributes",
    "content": "go.sum linguist-generated\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/.gitignore",
    "content": "# Setup a Global .gitignore for OS and editor generated files:\n# https://help.github.com/articles/ignoring-files\n# git config --global core.excludesfile ~/.gitignore_global\n\n.vagrant\n*.sublime-project\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/.travis.yml",
    "content": "sudo: false\nlanguage: go\n\ngo:\n  - \"stable\"\n  - \"1.11.x\"\n  - \"1.10.x\"\n  - \"1.9.x\"\n\nmatrix:\n  include:\n    - go: \"stable\"\n      env: GOLINT=true\n  allow_failures:\n    - go: tip\n  fast_finish: true\n\n\nbefore_install:\n  - if [ ! -z \"${GOLINT}\" ]; then go get -u golang.org/x/lint/golint; fi\n\nscript:\n  - go test --race ./...\n\nafter_script:\n  - test -z \"$(gofmt -s -l -w . | tee /dev/stderr)\"\n  - if [ ! -z  \"${GOLINT}\" ]; then echo running golint; golint --set_exit_status  ./...; else echo skipping golint; fi\n  - go vet ./...\n\nos:\n  - linux\n  - osx\n  - windows\n\nnotifications:\n  email: false\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/AUTHORS",
    "content": "# Names should be added to this file as\n#\tName or Organization <email address>\n# The email address is not required for organizations.\n\n# You can update this list using the following command:\n#\n#   $ git shortlog -se | awk '{print $2 \" \" $3 \" \" $4}'\n\n# Please keep the list sorted.\n\nAaron L <aaron@bettercoder.net>\nAdrien Bustany <adrien@bustany.org>\nAmit Krishnan <amit.krishnan@oracle.com>\nAnmol Sethi <me@anmol.io>\nBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>\nBruno Bigras <bigras.bruno@gmail.com>\nCaleb Spare <cespare@gmail.com>\nCase Nelson <case@teammating.com>\nChris Howey <chris@howey.me> <howeyc@gmail.com>\nChristoffer Buchholz <christoffer.buchholz@gmail.com>\nDaniel Wagner-Hall <dawagner@gmail.com>\nDave Cheney <dave@cheney.net>\nEvan Phoenix <evan@fallingsnow.net>\nFrancisco Souza <f@souza.cc>\nHari haran <hariharan.uno@gmail.com>\nJohn C Barstow\nKelvin Fo <vmirage@gmail.com>\nKen-ichirou MATSUZAWA <chamas@h4.dion.ne.jp>\nMatt Layher <mdlayher@gmail.com>\nNathan Youngman <git@nathany.com>\nNickolai Zeldovich <nickolai@csail.mit.edu>\nPatrick <patrick@dropbox.com>\nPaul Hammond <paul@paulhammond.org>\nPawel Knap <pawelknap88@gmail.com>\nPieter Droogendijk <pieter@binky.org.uk>\nPursuit92 <JoshChase@techpursuit.net>\nRiku Voipio <riku.voipio@linaro.org>\nRob Figueiredo <robfig@gmail.com>\nRodrigo Chiossi <rodrigochiossi@gmail.com>\nSlawek Ligus <root@ooz.ie>\nSoge Zhang <zhssoge@gmail.com>\nTiffany Jernigan <tiffany.jernigan@intel.com>\nTilak Sharma <tilaks@google.com>\nTom Payne <twpayne@gmail.com>\nTravis Cline <travis.cline@gmail.com>\nTudor Golubenco <tudor.g@gmail.com>\nVahe Khachikyan <vahe@live.ca>\nYukang <moorekang@gmail.com>\nbronze1man <bronze1man@gmail.com>\ndebrando <denis.brandolini@gmail.com>\nhenrikedwards <henrik.edwards@gmail.com>\n铁哥 <guotie.9@gmail.com>\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/CHANGELOG.md",
    "content": "# Changelog\n\n## v1.4.7 / 2018-01-09\n\n* BSD/macOS: Fix possible deadlock on closing the watcher on kqueue (thanks @nhooyr and @glycerine)\n* Tests: Fix missing verb on format string (thanks @rchiossi)\n* Linux: Fix deadlock in Remove (thanks @aarondl)\n* Linux: Watch.Add improvements (avoid race, fix consistency, reduce garbage) (thanks @twpayne)\n* Docs: Moved FAQ into the README (thanks @vahe)\n* Linux: Properly handle inotify's IN_Q_OVERFLOW event (thanks @zeldovich)\n* Docs: replace references to OS X with macOS\n\n## v1.4.2 / 2016-10-10\n\n* Linux: use InotifyInit1 with IN_CLOEXEC to stop leaking a file descriptor to a child process when using fork/exec [#178](https://github.com/fsnotify/fsnotify/pull/178) (thanks @pattyshack)\n\n## v1.4.1 / 2016-10-04\n\n* Fix flaky inotify stress test on Linux [#177](https://github.com/fsnotify/fsnotify/pull/177) (thanks @pattyshack)\n\n## v1.4.0 / 2016-10-01\n\n* add a String() method to Event.Op [#165](https://github.com/fsnotify/fsnotify/pull/165) (thanks @oozie)\n\n## v1.3.1 / 2016-06-28\n\n* Windows: fix for double backslash when watching the root of a drive [#151](https://github.com/fsnotify/fsnotify/issues/151) (thanks @brunoqc)\n\n## v1.3.0 / 2016-04-19\n\n* Support linux/arm64 by [patching](https://go-review.googlesource.com/#/c/21971/) x/sys/unix and switching to to it from syscall (thanks @suihkulokki) [#135](https://github.com/fsnotify/fsnotify/pull/135)\n\n## v1.2.10 / 2016-03-02\n\n* Fix golint errors in windows.go [#121](https://github.com/fsnotify/fsnotify/pull/121) (thanks @tiffanyfj)\n\n## v1.2.9 / 2016-01-13\n\nkqueue: Fix logic for CREATE after REMOVE [#111](https://github.com/fsnotify/fsnotify/pull/111) (thanks @bep)\n\n## v1.2.8 / 2015-12-17\n\n* kqueue: fix race condition in Close [#105](https://github.com/fsnotify/fsnotify/pull/105) (thanks @djui for reporting the issue and @ppknap for writing a failing test)\n* inotify: fix race in test\n* enable race detection for continuous integration (Linux, Mac, Windows)\n\n## v1.2.5 / 2015-10-17\n\n* inotify: use epoll_create1 for arm64 support (requires Linux 2.6.27 or later) [#100](https://github.com/fsnotify/fsnotify/pull/100) (thanks @suihkulokki)\n* inotify: fix path leaks [#73](https://github.com/fsnotify/fsnotify/pull/73) (thanks @chamaken)\n* kqueue: watch for rename events on subdirectories [#83](https://github.com/fsnotify/fsnotify/pull/83) (thanks @guotie)\n* kqueue: avoid infinite loops from symlinks cycles [#101](https://github.com/fsnotify/fsnotify/pull/101) (thanks @illicitonion)\n\n## v1.2.1 / 2015-10-14\n\n* kqueue: don't watch named pipes [#98](https://github.com/fsnotify/fsnotify/pull/98) (thanks @evanphx)\n\n## v1.2.0 / 2015-02-08\n\n* inotify: use epoll to wake up readEvents [#66](https://github.com/fsnotify/fsnotify/pull/66) (thanks @PieterD)\n* inotify: closing watcher should now always shut down goroutine [#63](https://github.com/fsnotify/fsnotify/pull/63) (thanks @PieterD)\n* kqueue: close kqueue after removing watches, fixes [#59](https://github.com/fsnotify/fsnotify/issues/59)\n\n## v1.1.1 / 2015-02-05\n\n* inotify: Retry read on EINTR [#61](https://github.com/fsnotify/fsnotify/issues/61) (thanks @PieterD)\n\n## v1.1.0 / 2014-12-12\n\n* kqueue: rework internals [#43](https://github.com/fsnotify/fsnotify/pull/43)\n    * add low-level functions\n    * only need to store flags on directories\n    * less mutexes [#13](https://github.com/fsnotify/fsnotify/issues/13)\n    * done can be an unbuffered channel\n    * remove calls to os.NewSyscallError\n* More efficient string concatenation for Event.String() [#52](https://github.com/fsnotify/fsnotify/pull/52) (thanks @mdlayher)\n* kqueue: fix regression in  rework causing subdirectories to be watched [#48](https://github.com/fsnotify/fsnotify/issues/48)\n* kqueue: cleanup internal watch before sending remove event [#51](https://github.com/fsnotify/fsnotify/issues/51)\n\n## v1.0.4 / 2014-09-07\n\n* kqueue: add dragonfly to the build tags.\n* Rename source code files, rearrange code so exported APIs are at the top.\n* Add done channel to example code. [#37](https://github.com/fsnotify/fsnotify/pull/37) (thanks @chenyukang)\n\n## v1.0.3 / 2014-08-19\n\n* [Fix] Windows MOVED_TO now translates to Create like on BSD and Linux. [#36](https://github.com/fsnotify/fsnotify/issues/36)\n\n## v1.0.2 / 2014-08-17\n\n* [Fix] Missing create events on macOS. [#14](https://github.com/fsnotify/fsnotify/issues/14) (thanks @zhsso)\n* [Fix] Make ./path and path equivalent. (thanks @zhsso)\n\n## v1.0.0 / 2014-08-15\n\n* [API] Remove AddWatch on Windows, use Add.\n* Improve documentation for exported identifiers. [#30](https://github.com/fsnotify/fsnotify/issues/30)\n* Minor updates based on feedback from golint.\n\n## dev / 2014-07-09\n\n* Moved to [github.com/fsnotify/fsnotify](https://github.com/fsnotify/fsnotify).\n* Use os.NewSyscallError instead of returning errno (thanks @hariharan-uno)\n\n## dev / 2014-07-04\n\n* kqueue: fix incorrect mutex used in Close()\n* Update example to demonstrate usage of Op.\n\n## dev / 2014-06-28\n\n* [API] Don't set the Write Op for attribute notifications [#4](https://github.com/fsnotify/fsnotify/issues/4)\n* Fix for String() method on Event (thanks Alex Brainman)\n* Don't build on Plan 9 or Solaris (thanks @4ad)\n\n## dev / 2014-06-21\n\n* Events channel of type Event rather than *Event.\n* [internal] use syscall constants directly for inotify and kqueue.\n* [internal] kqueue: rename events to kevents and fileEvent to event.\n\n## dev / 2014-06-19\n\n* Go 1.3+ required on Windows (uses syscall.ERROR_MORE_DATA internally).\n* [internal] remove cookie from Event struct (unused).\n* [internal] Event struct has the same definition across every OS.\n* [internal] remove internal watch and removeWatch methods.\n\n## dev / 2014-06-12\n\n* [API] Renamed Watch() to Add() and RemoveWatch() to Remove().\n* [API] Pluralized channel names: Events and Errors.\n* [API] Renamed FileEvent struct to Event.\n* [API] Op constants replace methods like IsCreate().\n\n## dev / 2014-06-12\n\n* Fix data race on kevent buffer (thanks @tilaks) [#98](https://github.com/howeyc/fsnotify/pull/98)\n\n## dev / 2014-05-23\n\n* [API] Remove current implementation of WatchFlags.\n    * current implementation doesn't take advantage of OS for efficiency\n    * provides little benefit over filtering events as they are received, but has  extra bookkeeping and mutexes\n    * no tests for the current implementation\n    * not fully implemented on Windows [#93](https://github.com/howeyc/fsnotify/issues/93#issuecomment-39285195)\n\n## v0.9.3 / 2014-12-31\n\n* kqueue: cleanup internal watch before sending remove event [#51](https://github.com/fsnotify/fsnotify/issues/51)\n\n## v0.9.2 / 2014-08-17\n\n* [Backport] Fix missing create events on macOS. [#14](https://github.com/fsnotify/fsnotify/issues/14) (thanks @zhsso)\n\n## v0.9.1 / 2014-06-12\n\n* Fix data race on kevent buffer (thanks @tilaks) [#98](https://github.com/howeyc/fsnotify/pull/98)\n\n## v0.9.0 / 2014-01-17\n\n* IsAttrib() for events that only concern a file's metadata [#79][] (thanks @abustany)\n* [Fix] kqueue: fix deadlock [#77][] (thanks @cespare)\n* [NOTICE] Development has moved to `code.google.com/p/go.exp/fsnotify` in preparation for inclusion in the Go standard library.\n\n## v0.8.12 / 2013-11-13\n\n* [API] Remove FD_SET and friends from Linux adapter\n\n## v0.8.11 / 2013-11-02\n\n* [Doc] Add Changelog [#72][] (thanks @nathany)\n* [Doc] Spotlight and double modify events on macOS [#62][] (reported by @paulhammond)\n\n## v0.8.10 / 2013-10-19\n\n* [Fix] kqueue: remove file watches when parent directory is removed [#71][] (reported by @mdwhatcott)\n* [Fix] kqueue: race between Close and readEvents [#70][] (reported by @bernerdschaefer)\n* [Doc] specify OS-specific limits in README (thanks @debrando)\n\n## v0.8.9 / 2013-09-08\n\n* [Doc] Contributing (thanks @nathany)\n* [Doc] update package path in example code [#63][] (thanks @paulhammond)\n* [Doc] GoCI badge in README (Linux only) [#60][]\n* [Doc] Cross-platform testing with Vagrant  [#59][] (thanks @nathany)\n\n## v0.8.8 / 2013-06-17\n\n* [Fix] Windows: handle `ERROR_MORE_DATA` on Windows [#49][] (thanks @jbowtie)\n\n## v0.8.7 / 2013-06-03\n\n* [API] Make syscall flags internal\n* [Fix] inotify: ignore event changes\n* [Fix] race in symlink test [#45][] (reported by @srid)\n* [Fix] tests on Windows\n* lower case error messages\n\n## v0.8.6 / 2013-05-23\n\n* kqueue: Use EVT_ONLY flag on Darwin\n* [Doc] Update README with full example\n\n## v0.8.5 / 2013-05-09\n\n* [Fix] inotify: allow monitoring of \"broken\" symlinks (thanks @tsg)\n\n## v0.8.4 / 2013-04-07\n\n* [Fix] kqueue: watch all file events [#40][] (thanks @ChrisBuchholz)\n\n## v0.8.3 / 2013-03-13\n\n* [Fix] inoitfy/kqueue memory leak [#36][] (reported by @nbkolchin)\n* [Fix] kqueue: use fsnFlags for watching a directory [#33][] (reported by @nbkolchin)\n\n## v0.8.2 / 2013-02-07\n\n* [Doc] add Authors\n* [Fix] fix data races for map access [#29][] (thanks @fsouza)\n\n## v0.8.1 / 2013-01-09\n\n* [Fix] Windows path separators\n* [Doc] BSD License\n\n## v0.8.0 / 2012-11-09\n\n* kqueue: directory watching improvements (thanks @vmirage)\n* inotify: add `IN_MOVED_TO` [#25][] (requested by @cpisto)\n* [Fix] kqueue: deleting watched directory [#24][] (reported by @jakerr)\n\n## v0.7.4 / 2012-10-09\n\n* [Fix] inotify: fixes from https://codereview.appspot.com/5418045/ (ugorji)\n* [Fix] kqueue: preserve watch flags when watching for delete [#21][] (reported by @robfig)\n* [Fix] kqueue: watch the directory even if it isn't a new watch (thanks @robfig)\n* [Fix] kqueue: modify after recreation of file\n\n## v0.7.3 / 2012-09-27\n\n* [Fix] kqueue: watch with an existing folder inside the watched folder (thanks @vmirage)\n* [Fix] kqueue: no longer get duplicate CREATE events\n\n## v0.7.2 / 2012-09-01\n\n* kqueue: events for created directories\n\n## v0.7.1 / 2012-07-14\n\n* [Fix] for renaming files\n\n## v0.7.0 / 2012-07-02\n\n* [Feature] FSNotify flags\n* [Fix] inotify: Added file name back to event path\n\n## v0.6.0 / 2012-06-06\n\n* kqueue: watch files after directory created (thanks @tmc)\n\n## v0.5.1 / 2012-05-22\n\n* [Fix] inotify: remove all watches before Close()\n\n## v0.5.0 / 2012-05-03\n\n* [API] kqueue: return errors during watch instead of sending over channel\n* kqueue: match symlink behavior on Linux\n* inotify: add `DELETE_SELF` (requested by @taralx)\n* [Fix] kqueue: handle EINTR (reported by @robfig)\n* [Doc] Godoc example [#1][] (thanks @davecheney)\n\n## v0.4.0 / 2012-03-30\n\n* Go 1 released: build with go tool\n* [Feature] Windows support using winfsnotify\n* Windows does not have attribute change notifications\n* Roll attribute notifications into IsModify\n\n## v0.3.0 / 2012-02-19\n\n* kqueue: add files when watch directory\n\n## v0.2.0 / 2011-12-30\n\n* update to latest Go weekly code\n\n## v0.1.0 / 2011-10-19\n\n* kqueue: add watch on file creation to match inotify\n* kqueue: create file event\n* inotify: ignore `IN_IGNORED` events\n* event String()\n* linux: common FileEvent functions\n* initial commit\n\n[#79]: https://github.com/howeyc/fsnotify/pull/79\n[#77]: https://github.com/howeyc/fsnotify/pull/77\n[#72]: https://github.com/howeyc/fsnotify/issues/72\n[#71]: https://github.com/howeyc/fsnotify/issues/71\n[#70]: https://github.com/howeyc/fsnotify/issues/70\n[#63]: https://github.com/howeyc/fsnotify/issues/63\n[#62]: https://github.com/howeyc/fsnotify/issues/62\n[#60]: https://github.com/howeyc/fsnotify/issues/60\n[#59]: https://github.com/howeyc/fsnotify/issues/59\n[#49]: https://github.com/howeyc/fsnotify/issues/49\n[#45]: https://github.com/howeyc/fsnotify/issues/45\n[#40]: https://github.com/howeyc/fsnotify/issues/40\n[#36]: https://github.com/howeyc/fsnotify/issues/36\n[#33]: https://github.com/howeyc/fsnotify/issues/33\n[#29]: https://github.com/howeyc/fsnotify/issues/29\n[#25]: https://github.com/howeyc/fsnotify/issues/25\n[#24]: https://github.com/howeyc/fsnotify/issues/24\n[#21]: https://github.com/howeyc/fsnotify/issues/21\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/CONTRIBUTING.md",
    "content": "# Contributing\n\n## Issues\n\n* Request features and report bugs using the [GitHub Issue Tracker](https://github.com/fsnotify/fsnotify/issues).\n* Please indicate the platform you are using fsnotify on.\n* A code example to reproduce the problem is appreciated.\n\n## Pull Requests\n\n### Contributor License Agreement\n\nfsnotify is derived from code in the [golang.org/x/exp](https://godoc.org/golang.org/x/exp) package and it may be included [in the standard library](https://github.com/fsnotify/fsnotify/issues/1) in the future. Therefore fsnotify carries the same [LICENSE](https://github.com/fsnotify/fsnotify/blob/master/LICENSE) as Go. Contributors retain their copyright, so you need to fill out a short form before we can accept your contribution: [Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual).\n\nPlease indicate that you have signed the CLA in your pull request.\n\n### How fsnotify is Developed\n\n* Development is done on feature branches.\n* Tests are run on BSD, Linux, macOS and Windows.\n* Pull requests are reviewed and [applied to master][am] using [hub][].\n  * Maintainers may modify or squash commits rather than asking contributors to.\n* To issue a new release, the maintainers will:\n  * Update the CHANGELOG\n  * Tag a version, which will become available through gopkg.in.\n \n### How to Fork\n\nFor smooth sailing, always use the original import path. Installing with `go get` makes this easy. \n\n1. Install from GitHub (`go get -u github.com/fsnotify/fsnotify`)\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Ensure everything works and the tests pass (see below)\n4. Commit your changes (`git commit -am 'Add some feature'`)\n\nContribute upstream:\n\n1. Fork fsnotify on GitHub\n2. Add your remote (`git remote add fork git@github.com:mycompany/repo.git`)\n3. Push to the branch (`git push fork my-new-feature`)\n4. Create a new Pull Request on GitHub\n\nThis workflow is [thoroughly explained by Katrina Owen](https://splice.com/blog/contributing-open-source-git-repositories-go/).\n\n### Testing\n\nfsnotify uses build tags to compile different code on Linux, BSD, macOS, and Windows.\n\nBefore doing a pull request, please do your best to test your changes on multiple platforms, and list which platforms you were able/unable to test on.\n\nTo aid in cross-platform testing there is a Vagrantfile for Linux and BSD.\n\n* Install [Vagrant](http://www.vagrantup.com/) and [VirtualBox](https://www.virtualbox.org/)\n* Setup [Vagrant Gopher](https://github.com/nathany/vagrant-gopher) in your `src` folder.\n* Run `vagrant up` from the project folder. You can also setup just one box with `vagrant up linux` or `vagrant up bsd` (note: the BSD box doesn't support Windows hosts at this time, and NFS may prompt for your host OS password)\n* Once setup, you can run the test suite on a given OS with a single command `vagrant ssh linux -c 'cd fsnotify/fsnotify; go test'`.\n* When you're done, you will want to halt or destroy the Vagrant boxes.\n\nNotice: fsnotify file system events won't trigger in shared folders. The tests get around this limitation by using the /tmp directory.\n\nRight now there is no equivalent solution for Windows and macOS, but there are Windows VMs [freely available from Microsoft](http://www.modern.ie/en-us/virtualization-tools#downloads).\n\n### Maintainers\n\nHelp maintaining fsnotify is welcome. To be a maintainer:\n\n* Submit a pull request and sign the CLA as above.\n* You must be able to run the test suite on Mac, Windows, Linux and BSD.\n\nTo keep master clean, the fsnotify project uses the \"apply mail\" workflow outlined in Nathaniel Talbott's post [\"Merge pull request\" Considered Harmful][am]. This requires installing [hub][].\n\nAll code changes should be internal pull requests.\n\nReleases are tagged using [Semantic Versioning](http://semver.org/).\n\n[hub]: https://github.com/github/hub\n[am]: http://blog.spreedly.com/2014/06/24/merge-pull-request-considered-harmful/#.VGa5yZPF_Zs\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/LICENSE",
    "content": "Copyright (c) 2012 The Go Authors. All rights reserved.\nCopyright (c) 2012-2019 fsnotify Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(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": "vendor/github.com/fsnotify/fsnotify/README.md",
    "content": "# File system notifications for Go\n\n[![GoDoc](https://godoc.org/github.com/fsnotify/fsnotify?status.svg)](https://godoc.org/github.com/fsnotify/fsnotify) [![Go Report Card](https://goreportcard.com/badge/github.com/fsnotify/fsnotify)](https://goreportcard.com/report/github.com/fsnotify/fsnotify)\n\nfsnotify utilizes [golang.org/x/sys](https://godoc.org/golang.org/x/sys) rather than `syscall` from the standard library. Ensure you have the latest version installed by running:\n\n```console\ngo get -u golang.org/x/sys/...\n```\n\nCross platform: Windows, Linux, BSD and macOS.\n\n| Adapter               | OS                               | Status                                                                                                                          |\n| --------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |\n| inotify               | Linux 2.6.27 or later, Android\\* | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) |\n| kqueue                | BSD, macOS, iOS\\*                | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) |\n| ReadDirectoryChangesW | Windows                          | Supported [![Build Status](https://travis-ci.org/fsnotify/fsnotify.svg?branch=master)](https://travis-ci.org/fsnotify/fsnotify) |\n| FSEvents              | macOS                            | [Planned](https://github.com/fsnotify/fsnotify/issues/11)                                                                       |\n| FEN                   | Solaris 11                       | [In Progress](https://github.com/fsnotify/fsnotify/issues/12)                                                                   |\n| fanotify              | Linux 2.6.37+                    | [Planned](https://github.com/fsnotify/fsnotify/issues/114)                                                                      |\n| USN Journals          | Windows                          | [Maybe](https://github.com/fsnotify/fsnotify/issues/53)                                                                         |\n| Polling               | *All*                            | [Maybe](https://github.com/fsnotify/fsnotify/issues/9)                                                                          |\n\n\\* Android and iOS are untested.\n\nPlease see [the documentation](https://godoc.org/github.com/fsnotify/fsnotify) and consult the [FAQ](#faq) for usage information.\n\n## API stability\n\nfsnotify is a fork of [howeyc/fsnotify](https://godoc.org/github.com/howeyc/fsnotify) with a new API as of v1.0. The API is based on [this design document](http://goo.gl/MrYxyA). \n\nAll [releases](https://github.com/fsnotify/fsnotify/releases) are tagged based on [Semantic Versioning](http://semver.org/). Further API changes are [planned](https://github.com/fsnotify/fsnotify/milestones), and will be tagged with a new major revision number.\n\nGo 1.6 supports dependencies located in the `vendor/` folder. Unless you are creating a library, it is recommended that you copy fsnotify into `vendor/github.com/fsnotify/fsnotify` within your project, and likewise for `golang.org/x/sys`.\n\n## Usage\n\n```go\npackage main\n\nimport (\n\t\"log\"\n\n\t\"github.com/fsnotify/fsnotify\"\n)\n\nfunc main() {\n\twatcher, err := fsnotify.NewWatcher()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer watcher.Close()\n\n\tdone := make(chan bool)\n\tgo func() {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase event, ok := <-watcher.Events:\n\t\t\t\tif !ok {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tlog.Println(\"event:\", event)\n\t\t\t\tif event.Op&fsnotify.Write == fsnotify.Write {\n\t\t\t\t\tlog.Println(\"modified file:\", event.Name)\n\t\t\t\t}\n\t\t\tcase err, ok := <-watcher.Errors:\n\t\t\t\tif !ok {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tlog.Println(\"error:\", err)\n\t\t\t}\n\t\t}\n\t}()\n\n\terr = watcher.Add(\"/tmp/foo\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\t<-done\n}\n```\n\n## Contributing\n\nPlease refer to [CONTRIBUTING][] before opening an issue or pull request.\n\n## Example\n\nSee [example_test.go](https://github.com/fsnotify/fsnotify/blob/master/example_test.go).\n\n## FAQ\n\n**When a file is moved to another directory is it still being watched?**\n\nNo (it shouldn't be, unless you are watching where it was moved to).\n\n**When I watch a directory, are all subdirectories watched as well?**\n\nNo, you must add watches for any directory you want to watch (a recursive watcher is on the roadmap [#18][]).\n\n**Do I have to watch the Error and Event channels in a separate goroutine?**\n\nAs of now, yes. Looking into making this single-thread friendly (see [howeyc #7][#7])\n\n**Why am I receiving multiple events for the same file on OS X?**\n\nSpotlight indexing on OS X can result in multiple events (see [howeyc #62][#62]). A temporary workaround is to add your folder(s) to the *Spotlight Privacy settings* until we have a native FSEvents implementation (see [#11][]).\n\n**How many files can be watched at once?**\n\nThere are OS-specific limits as to how many watches can be created:\n* Linux: /proc/sys/fs/inotify/max_user_watches contains the limit, reaching this limit results in a \"no space left on device\" error.\n* BSD / OSX: sysctl variables \"kern.maxfiles\" and \"kern.maxfilesperproc\", reaching these limits results in a \"too many open files\" error.\n\n**Why don't notifications work with NFS filesystems or filesystem in userspace (FUSE)?**\n\nfsnotify requires support from underlying OS to work. The current NFS protocol does not provide network level support for file notifications.\n\n[#62]: https://github.com/howeyc/fsnotify/issues/62\n[#18]: https://github.com/fsnotify/fsnotify/issues/18\n[#11]: https://github.com/fsnotify/fsnotify/issues/11\n[#7]: https://github.com/howeyc/fsnotify/issues/7\n\n[contributing]: https://github.com/fsnotify/fsnotify/blob/master/CONTRIBUTING.md\n\n## Related Projects\n\n* [notify](https://github.com/rjeczalik/notify)\n* [fsevents](https://github.com/fsnotify/fsevents)\n\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/fen.go",
    "content": "// Copyright 2010 The Go 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\n// +build solaris\n\npackage fsnotify\n\nimport (\n\t\"errors\"\n)\n\n// Watcher watches a set of files, delivering events to a channel.\ntype Watcher struct {\n\tEvents chan Event\n\tErrors chan error\n}\n\n// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events.\nfunc NewWatcher() (*Watcher, error) {\n\treturn nil, errors.New(\"FEN based watcher not yet supported for fsnotify\\n\")\n}\n\n// Close removes all watches and closes the events channel.\nfunc (w *Watcher) Close() error {\n\treturn nil\n}\n\n// Add starts watching the named file or directory (non-recursively).\nfunc (w *Watcher) Add(name string) error {\n\treturn nil\n}\n\n// Remove stops watching the the named file or directory (non-recursively).\nfunc (w *Watcher) Remove(name string) error {\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/fsnotify.go",
    "content": "// Copyright 2012 The Go 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\n// +build !plan9\n\n// Package fsnotify provides a platform-independent interface for file system notifications.\npackage fsnotify\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n)\n\n// Event represents a single file system notification.\ntype Event struct {\n\tName string // Relative path to the file or directory.\n\tOp   Op     // File operation that triggered the event.\n}\n\n// Op describes a set of file operations.\ntype Op uint32\n\n// These are the generalized file operations that can trigger a notification.\nconst (\n\tCreate Op = 1 << iota\n\tWrite\n\tRemove\n\tRename\n\tChmod\n)\n\nfunc (op Op) String() string {\n\t// Use a buffer for efficient string concatenation\n\tvar buffer bytes.Buffer\n\n\tif op&Create == Create {\n\t\tbuffer.WriteString(\"|CREATE\")\n\t}\n\tif op&Remove == Remove {\n\t\tbuffer.WriteString(\"|REMOVE\")\n\t}\n\tif op&Write == Write {\n\t\tbuffer.WriteString(\"|WRITE\")\n\t}\n\tif op&Rename == Rename {\n\t\tbuffer.WriteString(\"|RENAME\")\n\t}\n\tif op&Chmod == Chmod {\n\t\tbuffer.WriteString(\"|CHMOD\")\n\t}\n\tif buffer.Len() == 0 {\n\t\treturn \"\"\n\t}\n\treturn buffer.String()[1:] // Strip leading pipe\n}\n\n// String returns a string representation of the event in the form\n// \"file: REMOVE|WRITE|...\"\nfunc (e Event) String() string {\n\treturn fmt.Sprintf(\"%q: %s\", e.Name, e.Op.String())\n}\n\n// Common errors that can be reported by a watcher\nvar (\n\tErrEventOverflow = errors.New(\"fsnotify queue overflow\")\n)\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/inotify.go",
    "content": "// Copyright 2010 The Go 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\n// +build linux\n\npackage fsnotify\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\n// Watcher watches a set of files, delivering events to a channel.\ntype Watcher struct {\n\tEvents   chan Event\n\tErrors   chan error\n\tmu       sync.Mutex // Map access\n\tfd       int\n\tpoller   *fdPoller\n\twatches  map[string]*watch // Map of inotify watches (key: path)\n\tpaths    map[int]string    // Map of watched paths (key: watch descriptor)\n\tdone     chan struct{}     // Channel for sending a \"quit message\" to the reader goroutine\n\tdoneResp chan struct{}     // Channel to respond to Close\n}\n\n// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events.\nfunc NewWatcher() (*Watcher, error) {\n\t// Create inotify fd\n\tfd, errno := unix.InotifyInit1(unix.IN_CLOEXEC)\n\tif fd == -1 {\n\t\treturn nil, errno\n\t}\n\t// Create epoll\n\tpoller, err := newFdPoller(fd)\n\tif err != nil {\n\t\tunix.Close(fd)\n\t\treturn nil, err\n\t}\n\tw := &Watcher{\n\t\tfd:       fd,\n\t\tpoller:   poller,\n\t\twatches:  make(map[string]*watch),\n\t\tpaths:    make(map[int]string),\n\t\tEvents:   make(chan Event),\n\t\tErrors:   make(chan error),\n\t\tdone:     make(chan struct{}),\n\t\tdoneResp: make(chan struct{}),\n\t}\n\n\tgo w.readEvents()\n\treturn w, nil\n}\n\nfunc (w *Watcher) isClosed() bool {\n\tselect {\n\tcase <-w.done:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// Close removes all watches and closes the events channel.\nfunc (w *Watcher) Close() error {\n\tif w.isClosed() {\n\t\treturn nil\n\t}\n\n\t// Send 'close' signal to goroutine, and set the Watcher to closed.\n\tclose(w.done)\n\n\t// Wake up goroutine\n\tw.poller.wake()\n\n\t// Wait for goroutine to close\n\t<-w.doneResp\n\n\treturn nil\n}\n\n// Add starts watching the named file or directory (non-recursively).\nfunc (w *Watcher) Add(name string) error {\n\tname = filepath.Clean(name)\n\tif w.isClosed() {\n\t\treturn errors.New(\"inotify instance already closed\")\n\t}\n\n\tconst agnosticEvents = unix.IN_MOVED_TO | unix.IN_MOVED_FROM |\n\t\tunix.IN_CREATE | unix.IN_ATTRIB | unix.IN_MODIFY |\n\t\tunix.IN_MOVE_SELF | unix.IN_DELETE | unix.IN_DELETE_SELF\n\n\tvar flags uint32 = agnosticEvents\n\n\tw.mu.Lock()\n\tdefer w.mu.Unlock()\n\twatchEntry := w.watches[name]\n\tif watchEntry != nil {\n\t\tflags |= watchEntry.flags | unix.IN_MASK_ADD\n\t}\n\twd, errno := unix.InotifyAddWatch(w.fd, name, flags)\n\tif wd == -1 {\n\t\treturn errno\n\t}\n\n\tif watchEntry == nil {\n\t\tw.watches[name] = &watch{wd: uint32(wd), flags: flags}\n\t\tw.paths[wd] = name\n\t} else {\n\t\twatchEntry.wd = uint32(wd)\n\t\twatchEntry.flags = flags\n\t}\n\n\treturn nil\n}\n\n// Remove stops watching the named file or directory (non-recursively).\nfunc (w *Watcher) Remove(name string) error {\n\tname = filepath.Clean(name)\n\n\t// Fetch the watch.\n\tw.mu.Lock()\n\tdefer w.mu.Unlock()\n\twatch, ok := w.watches[name]\n\n\t// Remove it from inotify.\n\tif !ok {\n\t\treturn fmt.Errorf(\"can't remove non-existent inotify watch for: %s\", name)\n\t}\n\n\t// We successfully removed the watch if InotifyRmWatch doesn't return an\n\t// error, we need to clean up our internal state to ensure it matches\n\t// inotify's kernel state.\n\tdelete(w.paths, int(watch.wd))\n\tdelete(w.watches, name)\n\n\t// inotify_rm_watch will return EINVAL if the file has been deleted;\n\t// the inotify will already have been removed.\n\t// watches and pathes are deleted in ignoreLinux() implicitly and asynchronously\n\t// by calling inotify_rm_watch() below. e.g. readEvents() goroutine receives IN_IGNORE\n\t// so that EINVAL means that the wd is being rm_watch()ed or its file removed\n\t// by another thread and we have not received IN_IGNORE event.\n\tsuccess, errno := unix.InotifyRmWatch(w.fd, watch.wd)\n\tif success == -1 {\n\t\t// TODO: Perhaps it's not helpful to return an error here in every case.\n\t\t// the only two possible errors are:\n\t\t// EBADF, which happens when w.fd is not a valid file descriptor of any kind.\n\t\t// EINVAL, which is when fd is not an inotify descriptor or wd is not a valid watch descriptor.\n\t\t// Watch descriptors are invalidated when they are removed explicitly or implicitly;\n\t\t// explicitly by inotify_rm_watch, implicitly when the file they are watching is deleted.\n\t\treturn errno\n\t}\n\n\treturn nil\n}\n\ntype watch struct {\n\twd    uint32 // Watch descriptor (as returned by the inotify_add_watch() syscall)\n\tflags uint32 // inotify flags of this watch (see inotify(7) for the list of valid flags)\n}\n\n// readEvents reads from the inotify file descriptor, converts the\n// received events into Event objects and sends them via the Events channel\nfunc (w *Watcher) readEvents() {\n\tvar (\n\t\tbuf   [unix.SizeofInotifyEvent * 4096]byte // Buffer for a maximum of 4096 raw events\n\t\tn     int                                  // Number of bytes read with read()\n\t\terrno error                                // Syscall errno\n\t\tok    bool                                 // For poller.wait\n\t)\n\n\tdefer close(w.doneResp)\n\tdefer close(w.Errors)\n\tdefer close(w.Events)\n\tdefer unix.Close(w.fd)\n\tdefer w.poller.close()\n\n\tfor {\n\t\t// See if we have been closed.\n\t\tif w.isClosed() {\n\t\t\treturn\n\t\t}\n\n\t\tok, errno = w.poller.wait()\n\t\tif errno != nil {\n\t\t\tselect {\n\t\t\tcase w.Errors <- errno:\n\t\t\tcase <-w.done:\n\t\t\t\treturn\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\tn, errno = unix.Read(w.fd, buf[:])\n\t\t// If a signal interrupted execution, see if we've been asked to close, and try again.\n\t\t// http://man7.org/linux/man-pages/man7/signal.7.html :\n\t\t// \"Before Linux 3.8, reads from an inotify(7) file descriptor were not restartable\"\n\t\tif errno == unix.EINTR {\n\t\t\tcontinue\n\t\t}\n\n\t\t// unix.Read might have been woken up by Close. If so, we're done.\n\t\tif w.isClosed() {\n\t\t\treturn\n\t\t}\n\n\t\tif n < unix.SizeofInotifyEvent {\n\t\t\tvar err error\n\t\t\tif n == 0 {\n\t\t\t\t// If EOF is received. This should really never happen.\n\t\t\t\terr = io.EOF\n\t\t\t} else if n < 0 {\n\t\t\t\t// If an error occurred while reading.\n\t\t\t\terr = errno\n\t\t\t} else {\n\t\t\t\t// Read was too short.\n\t\t\t\terr = errors.New(\"notify: short read in readEvents()\")\n\t\t\t}\n\t\t\tselect {\n\t\t\tcase w.Errors <- err:\n\t\t\tcase <-w.done:\n\t\t\t\treturn\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tvar offset uint32\n\t\t// We don't know how many events we just read into the buffer\n\t\t// While the offset points to at least one whole event...\n\t\tfor offset <= uint32(n-unix.SizeofInotifyEvent) {\n\t\t\t// Point \"raw\" to the event in the buffer\n\t\t\traw := (*unix.InotifyEvent)(unsafe.Pointer(&buf[offset]))\n\n\t\t\tmask := uint32(raw.Mask)\n\t\t\tnameLen := uint32(raw.Len)\n\n\t\t\tif mask&unix.IN_Q_OVERFLOW != 0 {\n\t\t\t\tselect {\n\t\t\t\tcase w.Errors <- ErrEventOverflow:\n\t\t\t\tcase <-w.done:\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If the event happened to the watched directory or the watched file, the kernel\n\t\t\t// doesn't append the filename to the event, but we would like to always fill the\n\t\t\t// the \"Name\" field with a valid filename. We retrieve the path of the watch from\n\t\t\t// the \"paths\" map.\n\t\t\tw.mu.Lock()\n\t\t\tname, ok := w.paths[int(raw.Wd)]\n\t\t\t// IN_DELETE_SELF occurs when the file/directory being watched is removed.\n\t\t\t// This is a sign to clean up the maps, otherwise we are no longer in sync\n\t\t\t// with the inotify kernel state which has already deleted the watch\n\t\t\t// automatically.\n\t\t\tif ok && mask&unix.IN_DELETE_SELF == unix.IN_DELETE_SELF {\n\t\t\t\tdelete(w.paths, int(raw.Wd))\n\t\t\t\tdelete(w.watches, name)\n\t\t\t}\n\t\t\tw.mu.Unlock()\n\n\t\t\tif nameLen > 0 {\n\t\t\t\t// Point \"bytes\" at the first byte of the filename\n\t\t\t\tbytes := (*[unix.PathMax]byte)(unsafe.Pointer(&buf[offset+unix.SizeofInotifyEvent]))\n\t\t\t\t// The filename is padded with NULL bytes. TrimRight() gets rid of those.\n\t\t\t\tname += \"/\" + strings.TrimRight(string(bytes[0:nameLen]), \"\\000\")\n\t\t\t}\n\n\t\t\tevent := newEvent(name, mask)\n\n\t\t\t// Send the events that are not ignored on the events channel\n\t\t\tif !event.ignoreLinux(mask) {\n\t\t\t\tselect {\n\t\t\t\tcase w.Events <- event:\n\t\t\t\tcase <-w.done:\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Move to the next event in the buffer\n\t\t\toffset += unix.SizeofInotifyEvent + nameLen\n\t\t}\n\t}\n}\n\n// Certain types of events can be \"ignored\" and not sent over the Events\n// channel. Such as events marked ignore by the kernel, or MODIFY events\n// against files that do not exist.\nfunc (e *Event) ignoreLinux(mask uint32) bool {\n\t// Ignore anything the inotify API says to ignore\n\tif mask&unix.IN_IGNORED == unix.IN_IGNORED {\n\t\treturn true\n\t}\n\n\t// If the event is not a DELETE or RENAME, the file must exist.\n\t// Otherwise the event is ignored.\n\t// *Note*: this was put in place because it was seen that a MODIFY\n\t// event was sent after the DELETE. This ignores that MODIFY and\n\t// assumes a DELETE will come or has come if the file doesn't exist.\n\tif !(e.Op&Remove == Remove || e.Op&Rename == Rename) {\n\t\t_, statErr := os.Lstat(e.Name)\n\t\treturn os.IsNotExist(statErr)\n\t}\n\treturn false\n}\n\n// newEvent returns an platform-independent Event based on an inotify mask.\nfunc newEvent(name string, mask uint32) Event {\n\te := Event{Name: name}\n\tif mask&unix.IN_CREATE == unix.IN_CREATE || mask&unix.IN_MOVED_TO == unix.IN_MOVED_TO {\n\t\te.Op |= Create\n\t}\n\tif mask&unix.IN_DELETE_SELF == unix.IN_DELETE_SELF || mask&unix.IN_DELETE == unix.IN_DELETE {\n\t\te.Op |= Remove\n\t}\n\tif mask&unix.IN_MODIFY == unix.IN_MODIFY {\n\t\te.Op |= Write\n\t}\n\tif mask&unix.IN_MOVE_SELF == unix.IN_MOVE_SELF || mask&unix.IN_MOVED_FROM == unix.IN_MOVED_FROM {\n\t\te.Op |= Rename\n\t}\n\tif mask&unix.IN_ATTRIB == unix.IN_ATTRIB {\n\t\te.Op |= Chmod\n\t}\n\treturn e\n}\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/inotify_poller.go",
    "content": "// Copyright 2015 The Go 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\n// +build linux\n\npackage fsnotify\n\nimport (\n\t\"errors\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\ntype fdPoller struct {\n\tfd   int    // File descriptor (as returned by the inotify_init() syscall)\n\tepfd int    // Epoll file descriptor\n\tpipe [2]int // Pipe for waking up\n}\n\nfunc emptyPoller(fd int) *fdPoller {\n\tpoller := new(fdPoller)\n\tpoller.fd = fd\n\tpoller.epfd = -1\n\tpoller.pipe[0] = -1\n\tpoller.pipe[1] = -1\n\treturn poller\n}\n\n// Create a new inotify poller.\n// This creates an inotify handler, and an epoll handler.\nfunc newFdPoller(fd int) (*fdPoller, error) {\n\tvar errno error\n\tpoller := emptyPoller(fd)\n\tdefer func() {\n\t\tif errno != nil {\n\t\t\tpoller.close()\n\t\t}\n\t}()\n\tpoller.fd = fd\n\n\t// Create epoll fd\n\tpoller.epfd, errno = unix.EpollCreate1(unix.EPOLL_CLOEXEC)\n\tif poller.epfd == -1 {\n\t\treturn nil, errno\n\t}\n\t// Create pipe; pipe[0] is the read end, pipe[1] the write end.\n\terrno = unix.Pipe2(poller.pipe[:], unix.O_NONBLOCK|unix.O_CLOEXEC)\n\tif errno != nil {\n\t\treturn nil, errno\n\t}\n\n\t// Register inotify fd with epoll\n\tevent := unix.EpollEvent{\n\t\tFd:     int32(poller.fd),\n\t\tEvents: unix.EPOLLIN,\n\t}\n\terrno = unix.EpollCtl(poller.epfd, unix.EPOLL_CTL_ADD, poller.fd, &event)\n\tif errno != nil {\n\t\treturn nil, errno\n\t}\n\n\t// Register pipe fd with epoll\n\tevent = unix.EpollEvent{\n\t\tFd:     int32(poller.pipe[0]),\n\t\tEvents: unix.EPOLLIN,\n\t}\n\terrno = unix.EpollCtl(poller.epfd, unix.EPOLL_CTL_ADD, poller.pipe[0], &event)\n\tif errno != nil {\n\t\treturn nil, errno\n\t}\n\n\treturn poller, nil\n}\n\n// Wait using epoll.\n// Returns true if something is ready to be read,\n// false if there is not.\nfunc (poller *fdPoller) wait() (bool, error) {\n\t// 3 possible events per fd, and 2 fds, makes a maximum of 6 events.\n\t// I don't know whether epoll_wait returns the number of events returned,\n\t// or the total number of events ready.\n\t// I decided to catch both by making the buffer one larger than the maximum.\n\tevents := make([]unix.EpollEvent, 7)\n\tfor {\n\t\tn, errno := unix.EpollWait(poller.epfd, events, -1)\n\t\tif n == -1 {\n\t\t\tif errno == unix.EINTR {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn false, errno\n\t\t}\n\t\tif n == 0 {\n\t\t\t// If there are no events, try again.\n\t\t\tcontinue\n\t\t}\n\t\tif n > 6 {\n\t\t\t// This should never happen. More events were returned than should be possible.\n\t\t\treturn false, errors.New(\"epoll_wait returned more events than I know what to do with\")\n\t\t}\n\t\tready := events[:n]\n\t\tepollhup := false\n\t\tepollerr := false\n\t\tepollin := false\n\t\tfor _, event := range ready {\n\t\t\tif event.Fd == int32(poller.fd) {\n\t\t\t\tif event.Events&unix.EPOLLHUP != 0 {\n\t\t\t\t\t// This should not happen, but if it does, treat it as a wakeup.\n\t\t\t\t\tepollhup = true\n\t\t\t\t}\n\t\t\t\tif event.Events&unix.EPOLLERR != 0 {\n\t\t\t\t\t// If an error is waiting on the file descriptor, we should pretend\n\t\t\t\t\t// something is ready to read, and let unix.Read pick up the error.\n\t\t\t\t\tepollerr = true\n\t\t\t\t}\n\t\t\t\tif event.Events&unix.EPOLLIN != 0 {\n\t\t\t\t\t// There is data to read.\n\t\t\t\t\tepollin = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tif event.Fd == int32(poller.pipe[0]) {\n\t\t\t\tif event.Events&unix.EPOLLHUP != 0 {\n\t\t\t\t\t// Write pipe descriptor was closed, by us. This means we're closing down the\n\t\t\t\t\t// watcher, and we should wake up.\n\t\t\t\t}\n\t\t\t\tif event.Events&unix.EPOLLERR != 0 {\n\t\t\t\t\t// If an error is waiting on the pipe file descriptor.\n\t\t\t\t\t// This is an absolute mystery, and should never ever happen.\n\t\t\t\t\treturn false, errors.New(\"Error on the pipe descriptor.\")\n\t\t\t\t}\n\t\t\t\tif event.Events&unix.EPOLLIN != 0 {\n\t\t\t\t\t// This is a regular wakeup, so we have to clear the buffer.\n\t\t\t\t\terr := poller.clearWake()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn false, err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif epollhup || epollerr || epollin {\n\t\t\treturn true, nil\n\t\t}\n\t\treturn false, nil\n\t}\n}\n\n// Close the write end of the poller.\nfunc (poller *fdPoller) wake() error {\n\tbuf := make([]byte, 1)\n\tn, errno := unix.Write(poller.pipe[1], buf)\n\tif n == -1 {\n\t\tif errno == unix.EAGAIN {\n\t\t\t// Buffer is full, poller will wake.\n\t\t\treturn nil\n\t\t}\n\t\treturn errno\n\t}\n\treturn nil\n}\n\nfunc (poller *fdPoller) clearWake() error {\n\t// You have to be woken up a LOT in order to get to 100!\n\tbuf := make([]byte, 100)\n\tn, errno := unix.Read(poller.pipe[0], buf)\n\tif n == -1 {\n\t\tif errno == unix.EAGAIN {\n\t\t\t// Buffer is empty, someone else cleared our wake.\n\t\t\treturn nil\n\t\t}\n\t\treturn errno\n\t}\n\treturn nil\n}\n\n// Close all poller file descriptors, but not the one passed to it.\nfunc (poller *fdPoller) close() {\n\tif poller.pipe[1] != -1 {\n\t\tunix.Close(poller.pipe[1])\n\t}\n\tif poller.pipe[0] != -1 {\n\t\tunix.Close(poller.pipe[0])\n\t}\n\tif poller.epfd != -1 {\n\t\tunix.Close(poller.epfd)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/kqueue.go",
    "content": "// Copyright 2010 The Go 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\n// +build freebsd openbsd netbsd dragonfly darwin\n\npackage fsnotify\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sync\"\n\t\"time\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\n// Watcher watches a set of files, delivering events to a channel.\ntype Watcher struct {\n\tEvents chan Event\n\tErrors chan error\n\tdone   chan struct{} // Channel for sending a \"quit message\" to the reader goroutine\n\n\tkq int // File descriptor (as returned by the kqueue() syscall).\n\n\tmu              sync.Mutex        // Protects access to watcher data\n\twatches         map[string]int    // Map of watched file descriptors (key: path).\n\texternalWatches map[string]bool   // Map of watches added by user of the library.\n\tdirFlags        map[string]uint32 // Map of watched directories to fflags used in kqueue.\n\tpaths           map[int]pathInfo  // Map file descriptors to path names for processing kqueue events.\n\tfileExists      map[string]bool   // Keep track of if we know this file exists (to stop duplicate create events).\n\tisClosed        bool              // Set to true when Close() is first called\n}\n\ntype pathInfo struct {\n\tname  string\n\tisDir bool\n}\n\n// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events.\nfunc NewWatcher() (*Watcher, error) {\n\tkq, err := kqueue()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tw := &Watcher{\n\t\tkq:              kq,\n\t\twatches:         make(map[string]int),\n\t\tdirFlags:        make(map[string]uint32),\n\t\tpaths:           make(map[int]pathInfo),\n\t\tfileExists:      make(map[string]bool),\n\t\texternalWatches: make(map[string]bool),\n\t\tEvents:          make(chan Event),\n\t\tErrors:          make(chan error),\n\t\tdone:            make(chan struct{}),\n\t}\n\n\tgo w.readEvents()\n\treturn w, nil\n}\n\n// Close removes all watches and closes the events channel.\nfunc (w *Watcher) Close() error {\n\tw.mu.Lock()\n\tif w.isClosed {\n\t\tw.mu.Unlock()\n\t\treturn nil\n\t}\n\tw.isClosed = true\n\n\t// copy paths to remove while locked\n\tvar pathsToRemove = make([]string, 0, len(w.watches))\n\tfor name := range w.watches {\n\t\tpathsToRemove = append(pathsToRemove, name)\n\t}\n\tw.mu.Unlock()\n\t// unlock before calling Remove, which also locks\n\n\tfor _, name := range pathsToRemove {\n\t\tw.Remove(name)\n\t}\n\n\t// send a \"quit\" message to the reader goroutine\n\tclose(w.done)\n\n\treturn nil\n}\n\n// Add starts watching the named file or directory (non-recursively).\nfunc (w *Watcher) Add(name string) error {\n\tw.mu.Lock()\n\tw.externalWatches[name] = true\n\tw.mu.Unlock()\n\t_, err := w.addWatch(name, noteAllEvents)\n\treturn err\n}\n\n// Remove stops watching the the named file or directory (non-recursively).\nfunc (w *Watcher) Remove(name string) error {\n\tname = filepath.Clean(name)\n\tw.mu.Lock()\n\twatchfd, ok := w.watches[name]\n\tw.mu.Unlock()\n\tif !ok {\n\t\treturn fmt.Errorf(\"can't remove non-existent kevent watch for: %s\", name)\n\t}\n\n\tconst registerRemove = unix.EV_DELETE\n\tif err := register(w.kq, []int{watchfd}, registerRemove, 0); err != nil {\n\t\treturn err\n\t}\n\n\tunix.Close(watchfd)\n\n\tw.mu.Lock()\n\tisDir := w.paths[watchfd].isDir\n\tdelete(w.watches, name)\n\tdelete(w.paths, watchfd)\n\tdelete(w.dirFlags, name)\n\tw.mu.Unlock()\n\n\t// Find all watched paths that are in this directory that are not external.\n\tif isDir {\n\t\tvar pathsToRemove []string\n\t\tw.mu.Lock()\n\t\tfor _, path := range w.paths {\n\t\t\twdir, _ := filepath.Split(path.name)\n\t\t\tif filepath.Clean(wdir) == name {\n\t\t\t\tif !w.externalWatches[path.name] {\n\t\t\t\t\tpathsToRemove = append(pathsToRemove, path.name)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tw.mu.Unlock()\n\t\tfor _, name := range pathsToRemove {\n\t\t\t// Since these are internal, not much sense in propagating error\n\t\t\t// to the user, as that will just confuse them with an error about\n\t\t\t// a path they did not explicitly watch themselves.\n\t\t\tw.Remove(name)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// Watch all events (except NOTE_EXTEND, NOTE_LINK, NOTE_REVOKE)\nconst noteAllEvents = unix.NOTE_DELETE | unix.NOTE_WRITE | unix.NOTE_ATTRIB | unix.NOTE_RENAME\n\n// keventWaitTime to block on each read from kevent\nvar keventWaitTime = durationToTimespec(100 * time.Millisecond)\n\n// addWatch adds name to the watched file set.\n// The flags are interpreted as described in kevent(2).\n// Returns the real path to the file which was added, if any, which may be different from the one passed in the case of symlinks.\nfunc (w *Watcher) addWatch(name string, flags uint32) (string, error) {\n\tvar isDir bool\n\t// Make ./name and name equivalent\n\tname = filepath.Clean(name)\n\n\tw.mu.Lock()\n\tif w.isClosed {\n\t\tw.mu.Unlock()\n\t\treturn \"\", errors.New(\"kevent instance already closed\")\n\t}\n\twatchfd, alreadyWatching := w.watches[name]\n\t// We already have a watch, but we can still override flags.\n\tif alreadyWatching {\n\t\tisDir = w.paths[watchfd].isDir\n\t}\n\tw.mu.Unlock()\n\n\tif !alreadyWatching {\n\t\tfi, err := os.Lstat(name)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\n\t\t// Don't watch sockets.\n\t\tif fi.Mode()&os.ModeSocket == os.ModeSocket {\n\t\t\treturn \"\", nil\n\t\t}\n\n\t\t// Don't watch named pipes.\n\t\tif fi.Mode()&os.ModeNamedPipe == os.ModeNamedPipe {\n\t\t\treturn \"\", nil\n\t\t}\n\n\t\t// Follow Symlinks\n\t\t// Unfortunately, Linux can add bogus symlinks to watch list without\n\t\t// issue, and Windows can't do symlinks period (AFAIK). To  maintain\n\t\t// consistency, we will act like everything is fine. There will simply\n\t\t// be no file events for broken symlinks.\n\t\t// Hence the returns of nil on errors.\n\t\tif fi.Mode()&os.ModeSymlink == os.ModeSymlink {\n\t\t\tname, err = filepath.EvalSymlinks(name)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", nil\n\t\t\t}\n\n\t\t\tw.mu.Lock()\n\t\t\t_, alreadyWatching = w.watches[name]\n\t\t\tw.mu.Unlock()\n\n\t\t\tif alreadyWatching {\n\t\t\t\treturn name, nil\n\t\t\t}\n\n\t\t\tfi, err = os.Lstat(name)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", nil\n\t\t\t}\n\t\t}\n\n\t\twatchfd, err = unix.Open(name, openMode, 0700)\n\t\tif watchfd == -1 {\n\t\t\treturn \"\", err\n\t\t}\n\n\t\tisDir = fi.IsDir()\n\t}\n\n\tconst registerAdd = unix.EV_ADD | unix.EV_CLEAR | unix.EV_ENABLE\n\tif err := register(w.kq, []int{watchfd}, registerAdd, flags); err != nil {\n\t\tunix.Close(watchfd)\n\t\treturn \"\", err\n\t}\n\n\tif !alreadyWatching {\n\t\tw.mu.Lock()\n\t\tw.watches[name] = watchfd\n\t\tw.paths[watchfd] = pathInfo{name: name, isDir: isDir}\n\t\tw.mu.Unlock()\n\t}\n\n\tif isDir {\n\t\t// Watch the directory if it has not been watched before,\n\t\t// or if it was watched before, but perhaps only a NOTE_DELETE (watchDirectoryFiles)\n\t\tw.mu.Lock()\n\n\t\twatchDir := (flags&unix.NOTE_WRITE) == unix.NOTE_WRITE &&\n\t\t\t(!alreadyWatching || (w.dirFlags[name]&unix.NOTE_WRITE) != unix.NOTE_WRITE)\n\t\t// Store flags so this watch can be updated later\n\t\tw.dirFlags[name] = flags\n\t\tw.mu.Unlock()\n\n\t\tif watchDir {\n\t\t\tif err := w.watchDirectoryFiles(name); err != nil {\n\t\t\t\treturn \"\", err\n\t\t\t}\n\t\t}\n\t}\n\treturn name, nil\n}\n\n// readEvents reads from kqueue and converts the received kevents into\n// Event values that it sends down the Events channel.\nfunc (w *Watcher) readEvents() {\n\teventBuffer := make([]unix.Kevent_t, 10)\n\nloop:\n\tfor {\n\t\t// See if there is a message on the \"done\" channel\n\t\tselect {\n\t\tcase <-w.done:\n\t\t\tbreak loop\n\t\tdefault:\n\t\t}\n\n\t\t// Get new events\n\t\tkevents, err := read(w.kq, eventBuffer, &keventWaitTime)\n\t\t// EINTR is okay, the syscall was interrupted before timeout expired.\n\t\tif err != nil && err != unix.EINTR {\n\t\t\tselect {\n\t\t\tcase w.Errors <- err:\n\t\t\tcase <-w.done:\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// Flush the events we received to the Events channel\n\t\tfor len(kevents) > 0 {\n\t\t\tkevent := &kevents[0]\n\t\t\twatchfd := int(kevent.Ident)\n\t\t\tmask := uint32(kevent.Fflags)\n\t\t\tw.mu.Lock()\n\t\t\tpath := w.paths[watchfd]\n\t\t\tw.mu.Unlock()\n\t\t\tevent := newEvent(path.name, mask)\n\n\t\t\tif path.isDir && !(event.Op&Remove == Remove) {\n\t\t\t\t// Double check to make sure the directory exists. This can happen when\n\t\t\t\t// we do a rm -fr on a recursively watched folders and we receive a\n\t\t\t\t// modification event first but the folder has been deleted and later\n\t\t\t\t// receive the delete event\n\t\t\t\tif _, err := os.Lstat(event.Name); os.IsNotExist(err) {\n\t\t\t\t\t// mark is as delete event\n\t\t\t\t\tevent.Op |= Remove\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif event.Op&Rename == Rename || event.Op&Remove == Remove {\n\t\t\t\tw.Remove(event.Name)\n\t\t\t\tw.mu.Lock()\n\t\t\t\tdelete(w.fileExists, event.Name)\n\t\t\t\tw.mu.Unlock()\n\t\t\t}\n\n\t\t\tif path.isDir && event.Op&Write == Write && !(event.Op&Remove == Remove) {\n\t\t\t\tw.sendDirectoryChangeEvents(event.Name)\n\t\t\t} else {\n\t\t\t\t// Send the event on the Events channel.\n\t\t\t\tselect {\n\t\t\t\tcase w.Events <- event:\n\t\t\t\tcase <-w.done:\n\t\t\t\t\tbreak loop\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif event.Op&Remove == Remove {\n\t\t\t\t// Look for a file that may have overwritten this.\n\t\t\t\t// For example, mv f1 f2 will delete f2, then create f2.\n\t\t\t\tif path.isDir {\n\t\t\t\t\tfileDir := filepath.Clean(event.Name)\n\t\t\t\t\tw.mu.Lock()\n\t\t\t\t\t_, found := w.watches[fileDir]\n\t\t\t\t\tw.mu.Unlock()\n\t\t\t\t\tif found {\n\t\t\t\t\t\t// make sure the directory exists before we watch for changes. When we\n\t\t\t\t\t\t// do a recursive watch and perform rm -fr, the parent directory might\n\t\t\t\t\t\t// have gone missing, ignore the missing directory and let the\n\t\t\t\t\t\t// upcoming delete event remove the watch from the parent directory.\n\t\t\t\t\t\tif _, err := os.Lstat(fileDir); err == nil {\n\t\t\t\t\t\t\tw.sendDirectoryChangeEvents(fileDir)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfilePath := filepath.Clean(event.Name)\n\t\t\t\t\tif fileInfo, err := os.Lstat(filePath); err == nil {\n\t\t\t\t\t\tw.sendFileCreatedEventIfNew(filePath, fileInfo)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Move to next event\n\t\t\tkevents = kevents[1:]\n\t\t}\n\t}\n\n\t// cleanup\n\terr := unix.Close(w.kq)\n\tif err != nil {\n\t\t// only way the previous loop breaks is if w.done was closed so we need to async send to w.Errors.\n\t\tselect {\n\t\tcase w.Errors <- err:\n\t\tdefault:\n\t\t}\n\t}\n\tclose(w.Events)\n\tclose(w.Errors)\n}\n\n// newEvent returns an platform-independent Event based on kqueue Fflags.\nfunc newEvent(name string, mask uint32) Event {\n\te := Event{Name: name}\n\tif mask&unix.NOTE_DELETE == unix.NOTE_DELETE {\n\t\te.Op |= Remove\n\t}\n\tif mask&unix.NOTE_WRITE == unix.NOTE_WRITE {\n\t\te.Op |= Write\n\t}\n\tif mask&unix.NOTE_RENAME == unix.NOTE_RENAME {\n\t\te.Op |= Rename\n\t}\n\tif mask&unix.NOTE_ATTRIB == unix.NOTE_ATTRIB {\n\t\te.Op |= Chmod\n\t}\n\treturn e\n}\n\nfunc newCreateEvent(name string) Event {\n\treturn Event{Name: name, Op: Create}\n}\n\n// watchDirectoryFiles to mimic inotify when adding a watch on a directory\nfunc (w *Watcher) watchDirectoryFiles(dirPath string) error {\n\t// Get all files\n\tfiles, err := ioutil.ReadDir(dirPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor _, fileInfo := range files {\n\t\tfilePath := filepath.Join(dirPath, fileInfo.Name())\n\t\tfilePath, err = w.internalWatch(filePath, fileInfo)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tw.mu.Lock()\n\t\tw.fileExists[filePath] = true\n\t\tw.mu.Unlock()\n\t}\n\n\treturn nil\n}\n\n// sendDirectoryEvents searches the directory for newly created files\n// and sends them over the event channel. This functionality is to have\n// the BSD version of fsnotify match Linux inotify which provides a\n// create event for files created in a watched directory.\nfunc (w *Watcher) sendDirectoryChangeEvents(dirPath string) {\n\t// Get all files\n\tfiles, err := ioutil.ReadDir(dirPath)\n\tif err != nil {\n\t\tselect {\n\t\tcase w.Errors <- err:\n\t\tcase <-w.done:\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Search for new files\n\tfor _, fileInfo := range files {\n\t\tfilePath := filepath.Join(dirPath, fileInfo.Name())\n\t\terr := w.sendFileCreatedEventIfNew(filePath, fileInfo)\n\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// sendFileCreatedEvent sends a create event if the file isn't already being tracked.\nfunc (w *Watcher) sendFileCreatedEventIfNew(filePath string, fileInfo os.FileInfo) (err error) {\n\tw.mu.Lock()\n\t_, doesExist := w.fileExists[filePath]\n\tw.mu.Unlock()\n\tif !doesExist {\n\t\t// Send create event\n\t\tselect {\n\t\tcase w.Events <- newCreateEvent(filePath):\n\t\tcase <-w.done:\n\t\t\treturn\n\t\t}\n\t}\n\n\t// like watchDirectoryFiles (but without doing another ReadDir)\n\tfilePath, err = w.internalWatch(filePath, fileInfo)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tw.mu.Lock()\n\tw.fileExists[filePath] = true\n\tw.mu.Unlock()\n\n\treturn nil\n}\n\nfunc (w *Watcher) internalWatch(name string, fileInfo os.FileInfo) (string, error) {\n\tif fileInfo.IsDir() {\n\t\t// mimic Linux providing delete events for subdirectories\n\t\t// but preserve the flags used if currently watching subdirectory\n\t\tw.mu.Lock()\n\t\tflags := w.dirFlags[name]\n\t\tw.mu.Unlock()\n\n\t\tflags |= unix.NOTE_DELETE | unix.NOTE_RENAME\n\t\treturn w.addWatch(name, flags)\n\t}\n\n\t// watch file to mimic Linux inotify\n\treturn w.addWatch(name, noteAllEvents)\n}\n\n// kqueue creates a new kernel event queue and returns a descriptor.\nfunc kqueue() (kq int, err error) {\n\tkq, err = unix.Kqueue()\n\tif kq == -1 {\n\t\treturn kq, err\n\t}\n\treturn kq, nil\n}\n\n// register events with the queue\nfunc register(kq int, fds []int, flags int, fflags uint32) error {\n\tchanges := make([]unix.Kevent_t, len(fds))\n\n\tfor i, fd := range fds {\n\t\t// SetKevent converts int to the platform-specific types:\n\t\tunix.SetKevent(&changes[i], fd, unix.EVFILT_VNODE, flags)\n\t\tchanges[i].Fflags = fflags\n\t}\n\n\t// register the events\n\tsuccess, err := unix.Kevent(kq, changes, nil, nil)\n\tif success == -1 {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// read retrieves pending events, or waits until an event occurs.\n// A timeout of nil blocks indefinitely, while 0 polls the queue.\nfunc read(kq int, events []unix.Kevent_t, timeout *unix.Timespec) ([]unix.Kevent_t, error) {\n\tn, err := unix.Kevent(kq, nil, events, timeout)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn events[0:n], nil\n}\n\n// durationToTimespec prepares a timeout value\nfunc durationToTimespec(d time.Duration) unix.Timespec {\n\treturn unix.NsecToTimespec(d.Nanoseconds())\n}\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/open_mode_bsd.go",
    "content": "// Copyright 2013 The Go 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\n// +build freebsd openbsd netbsd dragonfly\n\npackage fsnotify\n\nimport \"golang.org/x/sys/unix\"\n\nconst openMode = unix.O_NONBLOCK | unix.O_RDONLY | unix.O_CLOEXEC\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/open_mode_darwin.go",
    "content": "// Copyright 2013 The Go 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\n// +build darwin\n\npackage fsnotify\n\nimport \"golang.org/x/sys/unix\"\n\n// note: this constant is not defined on BSD\nconst openMode = unix.O_EVTONLY | unix.O_CLOEXEC\n"
  },
  {
    "path": "vendor/github.com/fsnotify/fsnotify/windows.go",
    "content": "// Copyright 2011 The Go 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\n// +build windows\n\npackage fsnotify\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"sync\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n// Watcher watches a set of files, delivering events to a channel.\ntype Watcher struct {\n\tEvents   chan Event\n\tErrors   chan error\n\tisClosed bool           // Set to true when Close() is first called\n\tmu       sync.Mutex     // Map access\n\tport     syscall.Handle // Handle to completion port\n\twatches  watchMap       // Map of watches (key: i-number)\n\tinput    chan *input    // Inputs to the reader are sent on this channel\n\tquit     chan chan<- error\n}\n\n// NewWatcher establishes a new watcher with the underlying OS and begins waiting for events.\nfunc NewWatcher() (*Watcher, error) {\n\tport, e := syscall.CreateIoCompletionPort(syscall.InvalidHandle, 0, 0, 0)\n\tif e != nil {\n\t\treturn nil, os.NewSyscallError(\"CreateIoCompletionPort\", e)\n\t}\n\tw := &Watcher{\n\t\tport:    port,\n\t\twatches: make(watchMap),\n\t\tinput:   make(chan *input, 1),\n\t\tEvents:  make(chan Event, 50),\n\t\tErrors:  make(chan error),\n\t\tquit:    make(chan chan<- error, 1),\n\t}\n\tgo w.readEvents()\n\treturn w, nil\n}\n\n// Close removes all watches and closes the events channel.\nfunc (w *Watcher) Close() error {\n\tif w.isClosed {\n\t\treturn nil\n\t}\n\tw.isClosed = true\n\n\t// Send \"quit\" message to the reader goroutine\n\tch := make(chan error)\n\tw.quit <- ch\n\tif err := w.wakeupReader(); err != nil {\n\t\treturn err\n\t}\n\treturn <-ch\n}\n\n// Add starts watching the named file or directory (non-recursively).\nfunc (w *Watcher) Add(name string) error {\n\tif w.isClosed {\n\t\treturn errors.New(\"watcher already closed\")\n\t}\n\tin := &input{\n\t\top:    opAddWatch,\n\t\tpath:  filepath.Clean(name),\n\t\tflags: sysFSALLEVENTS,\n\t\treply: make(chan error),\n\t}\n\tw.input <- in\n\tif err := w.wakeupReader(); err != nil {\n\t\treturn err\n\t}\n\treturn <-in.reply\n}\n\n// Remove stops watching the the named file or directory (non-recursively).\nfunc (w *Watcher) Remove(name string) error {\n\tin := &input{\n\t\top:    opRemoveWatch,\n\t\tpath:  filepath.Clean(name),\n\t\treply: make(chan error),\n\t}\n\tw.input <- in\n\tif err := w.wakeupReader(); err != nil {\n\t\treturn err\n\t}\n\treturn <-in.reply\n}\n\nconst (\n\t// Options for AddWatch\n\tsysFSONESHOT = 0x80000000\n\tsysFSONLYDIR = 0x1000000\n\n\t// Events\n\tsysFSACCESS     = 0x1\n\tsysFSALLEVENTS  = 0xfff\n\tsysFSATTRIB     = 0x4\n\tsysFSCLOSE      = 0x18\n\tsysFSCREATE     = 0x100\n\tsysFSDELETE     = 0x200\n\tsysFSDELETESELF = 0x400\n\tsysFSMODIFY     = 0x2\n\tsysFSMOVE       = 0xc0\n\tsysFSMOVEDFROM  = 0x40\n\tsysFSMOVEDTO    = 0x80\n\tsysFSMOVESELF   = 0x800\n\n\t// Special events\n\tsysFSIGNORED   = 0x8000\n\tsysFSQOVERFLOW = 0x4000\n)\n\nfunc newEvent(name string, mask uint32) Event {\n\te := Event{Name: name}\n\tif mask&sysFSCREATE == sysFSCREATE || mask&sysFSMOVEDTO == sysFSMOVEDTO {\n\t\te.Op |= Create\n\t}\n\tif mask&sysFSDELETE == sysFSDELETE || mask&sysFSDELETESELF == sysFSDELETESELF {\n\t\te.Op |= Remove\n\t}\n\tif mask&sysFSMODIFY == sysFSMODIFY {\n\t\te.Op |= Write\n\t}\n\tif mask&sysFSMOVE == sysFSMOVE || mask&sysFSMOVESELF == sysFSMOVESELF || mask&sysFSMOVEDFROM == sysFSMOVEDFROM {\n\t\te.Op |= Rename\n\t}\n\tif mask&sysFSATTRIB == sysFSATTRIB {\n\t\te.Op |= Chmod\n\t}\n\treturn e\n}\n\nconst (\n\topAddWatch = iota\n\topRemoveWatch\n)\n\nconst (\n\tprovisional uint64 = 1 << (32 + iota)\n)\n\ntype input struct {\n\top    int\n\tpath  string\n\tflags uint32\n\treply chan error\n}\n\ntype inode struct {\n\thandle syscall.Handle\n\tvolume uint32\n\tindex  uint64\n}\n\ntype watch struct {\n\tov     syscall.Overlapped\n\tino    *inode            // i-number\n\tpath   string            // Directory path\n\tmask   uint64            // Directory itself is being watched with these notify flags\n\tnames  map[string]uint64 // Map of names being watched and their notify flags\n\trename string            // Remembers the old name while renaming a file\n\tbuf    [4096]byte\n}\n\ntype indexMap map[uint64]*watch\ntype watchMap map[uint32]indexMap\n\nfunc (w *Watcher) wakeupReader() error {\n\te := syscall.PostQueuedCompletionStatus(w.port, 0, 0, nil)\n\tif e != nil {\n\t\treturn os.NewSyscallError(\"PostQueuedCompletionStatus\", e)\n\t}\n\treturn nil\n}\n\nfunc getDir(pathname string) (dir string, err error) {\n\tattr, e := syscall.GetFileAttributes(syscall.StringToUTF16Ptr(pathname))\n\tif e != nil {\n\t\treturn \"\", os.NewSyscallError(\"GetFileAttributes\", e)\n\t}\n\tif attr&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {\n\t\tdir = pathname\n\t} else {\n\t\tdir, _ = filepath.Split(pathname)\n\t\tdir = filepath.Clean(dir)\n\t}\n\treturn\n}\n\nfunc getIno(path string) (ino *inode, err error) {\n\th, e := syscall.CreateFile(syscall.StringToUTF16Ptr(path),\n\t\tsyscall.FILE_LIST_DIRECTORY,\n\t\tsyscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,\n\t\tnil, syscall.OPEN_EXISTING,\n\t\tsyscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OVERLAPPED, 0)\n\tif e != nil {\n\t\treturn nil, os.NewSyscallError(\"CreateFile\", e)\n\t}\n\tvar fi syscall.ByHandleFileInformation\n\tif e = syscall.GetFileInformationByHandle(h, &fi); e != nil {\n\t\tsyscall.CloseHandle(h)\n\t\treturn nil, os.NewSyscallError(\"GetFileInformationByHandle\", e)\n\t}\n\tino = &inode{\n\t\thandle: h,\n\t\tvolume: fi.VolumeSerialNumber,\n\t\tindex:  uint64(fi.FileIndexHigh)<<32 | uint64(fi.FileIndexLow),\n\t}\n\treturn ino, nil\n}\n\n// Must run within the I/O thread.\nfunc (m watchMap) get(ino *inode) *watch {\n\tif i := m[ino.volume]; i != nil {\n\t\treturn i[ino.index]\n\t}\n\treturn nil\n}\n\n// Must run within the I/O thread.\nfunc (m watchMap) set(ino *inode, watch *watch) {\n\ti := m[ino.volume]\n\tif i == nil {\n\t\ti = make(indexMap)\n\t\tm[ino.volume] = i\n\t}\n\ti[ino.index] = watch\n}\n\n// Must run within the I/O thread.\nfunc (w *Watcher) addWatch(pathname string, flags uint64) error {\n\tdir, err := getDir(pathname)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif flags&sysFSONLYDIR != 0 && pathname != dir {\n\t\treturn nil\n\t}\n\tino, err := getIno(dir)\n\tif err != nil {\n\t\treturn err\n\t}\n\tw.mu.Lock()\n\twatchEntry := w.watches.get(ino)\n\tw.mu.Unlock()\n\tif watchEntry == nil {\n\t\tif _, e := syscall.CreateIoCompletionPort(ino.handle, w.port, 0, 0); e != nil {\n\t\t\tsyscall.CloseHandle(ino.handle)\n\t\t\treturn os.NewSyscallError(\"CreateIoCompletionPort\", e)\n\t\t}\n\t\twatchEntry = &watch{\n\t\t\tino:   ino,\n\t\t\tpath:  dir,\n\t\t\tnames: make(map[string]uint64),\n\t\t}\n\t\tw.mu.Lock()\n\t\tw.watches.set(ino, watchEntry)\n\t\tw.mu.Unlock()\n\t\tflags |= provisional\n\t} else {\n\t\tsyscall.CloseHandle(ino.handle)\n\t}\n\tif pathname == dir {\n\t\twatchEntry.mask |= flags\n\t} else {\n\t\twatchEntry.names[filepath.Base(pathname)] |= flags\n\t}\n\tif err = w.startRead(watchEntry); err != nil {\n\t\treturn err\n\t}\n\tif pathname == dir {\n\t\twatchEntry.mask &= ^provisional\n\t} else {\n\t\twatchEntry.names[filepath.Base(pathname)] &= ^provisional\n\t}\n\treturn nil\n}\n\n// Must run within the I/O thread.\nfunc (w *Watcher) remWatch(pathname string) error {\n\tdir, err := getDir(pathname)\n\tif err != nil {\n\t\treturn err\n\t}\n\tino, err := getIno(dir)\n\tif err != nil {\n\t\treturn err\n\t}\n\tw.mu.Lock()\n\twatch := w.watches.get(ino)\n\tw.mu.Unlock()\n\tif watch == nil {\n\t\treturn fmt.Errorf(\"can't remove non-existent watch for: %s\", pathname)\n\t}\n\tif pathname == dir {\n\t\tw.sendEvent(watch.path, watch.mask&sysFSIGNORED)\n\t\twatch.mask = 0\n\t} else {\n\t\tname := filepath.Base(pathname)\n\t\tw.sendEvent(filepath.Join(watch.path, name), watch.names[name]&sysFSIGNORED)\n\t\tdelete(watch.names, name)\n\t}\n\treturn w.startRead(watch)\n}\n\n// Must run within the I/O thread.\nfunc (w *Watcher) deleteWatch(watch *watch) {\n\tfor name, mask := range watch.names {\n\t\tif mask&provisional == 0 {\n\t\t\tw.sendEvent(filepath.Join(watch.path, name), mask&sysFSIGNORED)\n\t\t}\n\t\tdelete(watch.names, name)\n\t}\n\tif watch.mask != 0 {\n\t\tif watch.mask&provisional == 0 {\n\t\t\tw.sendEvent(watch.path, watch.mask&sysFSIGNORED)\n\t\t}\n\t\twatch.mask = 0\n\t}\n}\n\n// Must run within the I/O thread.\nfunc (w *Watcher) startRead(watch *watch) error {\n\tif e := syscall.CancelIo(watch.ino.handle); e != nil {\n\t\tw.Errors <- os.NewSyscallError(\"CancelIo\", e)\n\t\tw.deleteWatch(watch)\n\t}\n\tmask := toWindowsFlags(watch.mask)\n\tfor _, m := range watch.names {\n\t\tmask |= toWindowsFlags(m)\n\t}\n\tif mask == 0 {\n\t\tif e := syscall.CloseHandle(watch.ino.handle); e != nil {\n\t\t\tw.Errors <- os.NewSyscallError(\"CloseHandle\", e)\n\t\t}\n\t\tw.mu.Lock()\n\t\tdelete(w.watches[watch.ino.volume], watch.ino.index)\n\t\tw.mu.Unlock()\n\t\treturn nil\n\t}\n\te := syscall.ReadDirectoryChanges(watch.ino.handle, &watch.buf[0],\n\t\tuint32(unsafe.Sizeof(watch.buf)), false, mask, nil, &watch.ov, 0)\n\tif e != nil {\n\t\terr := os.NewSyscallError(\"ReadDirectoryChanges\", e)\n\t\tif e == syscall.ERROR_ACCESS_DENIED && watch.mask&provisional == 0 {\n\t\t\t// Watched directory was probably removed\n\t\t\tif w.sendEvent(watch.path, watch.mask&sysFSDELETESELF) {\n\t\t\t\tif watch.mask&sysFSONESHOT != 0 {\n\t\t\t\t\twatch.mask = 0\n\t\t\t\t}\n\t\t\t}\n\t\t\terr = nil\n\t\t}\n\t\tw.deleteWatch(watch)\n\t\tw.startRead(watch)\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// readEvents reads from the I/O completion port, converts the\n// received events into Event objects and sends them via the Events channel.\n// Entry point to the I/O thread.\nfunc (w *Watcher) readEvents() {\n\tvar (\n\t\tn, key uint32\n\t\tov     *syscall.Overlapped\n\t)\n\truntime.LockOSThread()\n\n\tfor {\n\t\te := syscall.GetQueuedCompletionStatus(w.port, &n, &key, &ov, syscall.INFINITE)\n\t\twatch := (*watch)(unsafe.Pointer(ov))\n\n\t\tif watch == nil {\n\t\t\tselect {\n\t\t\tcase ch := <-w.quit:\n\t\t\t\tw.mu.Lock()\n\t\t\t\tvar indexes []indexMap\n\t\t\t\tfor _, index := range w.watches {\n\t\t\t\t\tindexes = append(indexes, index)\n\t\t\t\t}\n\t\t\t\tw.mu.Unlock()\n\t\t\t\tfor _, index := range indexes {\n\t\t\t\t\tfor _, watch := range index {\n\t\t\t\t\t\tw.deleteWatch(watch)\n\t\t\t\t\t\tw.startRead(watch)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvar err error\n\t\t\t\tif e := syscall.CloseHandle(w.port); e != nil {\n\t\t\t\t\terr = os.NewSyscallError(\"CloseHandle\", e)\n\t\t\t\t}\n\t\t\t\tclose(w.Events)\n\t\t\t\tclose(w.Errors)\n\t\t\t\tch <- err\n\t\t\t\treturn\n\t\t\tcase in := <-w.input:\n\t\t\t\tswitch in.op {\n\t\t\t\tcase opAddWatch:\n\t\t\t\t\tin.reply <- w.addWatch(in.path, uint64(in.flags))\n\t\t\t\tcase opRemoveWatch:\n\t\t\t\t\tin.reply <- w.remWatch(in.path)\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch e {\n\t\tcase syscall.ERROR_MORE_DATA:\n\t\t\tif watch == nil {\n\t\t\t\tw.Errors <- errors.New(\"ERROR_MORE_DATA has unexpectedly null lpOverlapped buffer\")\n\t\t\t} else {\n\t\t\t\t// The i/o succeeded but the buffer is full.\n\t\t\t\t// In theory we should be building up a full packet.\n\t\t\t\t// In practice we can get away with just carrying on.\n\t\t\t\tn = uint32(unsafe.Sizeof(watch.buf))\n\t\t\t}\n\t\tcase syscall.ERROR_ACCESS_DENIED:\n\t\t\t// Watched directory was probably removed\n\t\t\tw.sendEvent(watch.path, watch.mask&sysFSDELETESELF)\n\t\t\tw.deleteWatch(watch)\n\t\t\tw.startRead(watch)\n\t\t\tcontinue\n\t\tcase syscall.ERROR_OPERATION_ABORTED:\n\t\t\t// CancelIo was called on this handle\n\t\t\tcontinue\n\t\tdefault:\n\t\t\tw.Errors <- os.NewSyscallError(\"GetQueuedCompletionPort\", e)\n\t\t\tcontinue\n\t\tcase nil:\n\t\t}\n\n\t\tvar offset uint32\n\t\tfor {\n\t\t\tif n == 0 {\n\t\t\t\tw.Events <- newEvent(\"\", sysFSQOVERFLOW)\n\t\t\t\tw.Errors <- errors.New(\"short read in readEvents()\")\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Point \"raw\" to the event in the buffer\n\t\t\traw := (*syscall.FileNotifyInformation)(unsafe.Pointer(&watch.buf[offset]))\n\t\t\tbuf := (*[syscall.MAX_PATH]uint16)(unsafe.Pointer(&raw.FileName))\n\t\t\tname := syscall.UTF16ToString(buf[:raw.FileNameLength/2])\n\t\t\tfullname := filepath.Join(watch.path, name)\n\n\t\t\tvar mask uint64\n\t\t\tswitch raw.Action {\n\t\t\tcase syscall.FILE_ACTION_REMOVED:\n\t\t\t\tmask = sysFSDELETESELF\n\t\t\tcase syscall.FILE_ACTION_MODIFIED:\n\t\t\t\tmask = sysFSMODIFY\n\t\t\tcase syscall.FILE_ACTION_RENAMED_OLD_NAME:\n\t\t\t\twatch.rename = name\n\t\t\tcase syscall.FILE_ACTION_RENAMED_NEW_NAME:\n\t\t\t\tif watch.names[watch.rename] != 0 {\n\t\t\t\t\twatch.names[name] |= watch.names[watch.rename]\n\t\t\t\t\tdelete(watch.names, watch.rename)\n\t\t\t\t\tmask = sysFSMOVESELF\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsendNameEvent := func() {\n\t\t\t\tif w.sendEvent(fullname, watch.names[name]&mask) {\n\t\t\t\t\tif watch.names[name]&sysFSONESHOT != 0 {\n\t\t\t\t\t\tdelete(watch.names, name)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif raw.Action != syscall.FILE_ACTION_RENAMED_NEW_NAME {\n\t\t\t\tsendNameEvent()\n\t\t\t}\n\t\t\tif raw.Action == syscall.FILE_ACTION_REMOVED {\n\t\t\t\tw.sendEvent(fullname, watch.names[name]&sysFSIGNORED)\n\t\t\t\tdelete(watch.names, name)\n\t\t\t}\n\t\t\tif w.sendEvent(fullname, watch.mask&toFSnotifyFlags(raw.Action)) {\n\t\t\t\tif watch.mask&sysFSONESHOT != 0 {\n\t\t\t\t\twatch.mask = 0\n\t\t\t\t}\n\t\t\t}\n\t\t\tif raw.Action == syscall.FILE_ACTION_RENAMED_NEW_NAME {\n\t\t\t\tfullname = filepath.Join(watch.path, watch.rename)\n\t\t\t\tsendNameEvent()\n\t\t\t}\n\n\t\t\t// Move to the next event in the buffer\n\t\t\tif raw.NextEntryOffset == 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\toffset += raw.NextEntryOffset\n\n\t\t\t// Error!\n\t\t\tif offset >= n {\n\t\t\t\tw.Errors <- errors.New(\"Windows system assumed buffer larger than it is, events have likely been missed.\")\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif err := w.startRead(watch); err != nil {\n\t\t\tw.Errors <- err\n\t\t}\n\t}\n}\n\nfunc (w *Watcher) sendEvent(name string, mask uint64) bool {\n\tif mask == 0 {\n\t\treturn false\n\t}\n\tevent := newEvent(name, uint32(mask))\n\tselect {\n\tcase ch := <-w.quit:\n\t\tw.quit <- ch\n\tcase w.Events <- event:\n\t}\n\treturn true\n}\n\nfunc toWindowsFlags(mask uint64) uint32 {\n\tvar m uint32\n\tif mask&sysFSACCESS != 0 {\n\t\tm |= syscall.FILE_NOTIFY_CHANGE_LAST_ACCESS\n\t}\n\tif mask&sysFSMODIFY != 0 {\n\t\tm |= syscall.FILE_NOTIFY_CHANGE_LAST_WRITE\n\t}\n\tif mask&sysFSATTRIB != 0 {\n\t\tm |= syscall.FILE_NOTIFY_CHANGE_ATTRIBUTES\n\t}\n\tif mask&(sysFSMOVE|sysFSCREATE|sysFSDELETE) != 0 {\n\t\tm |= syscall.FILE_NOTIFY_CHANGE_FILE_NAME | syscall.FILE_NOTIFY_CHANGE_DIR_NAME\n\t}\n\treturn m\n}\n\nfunc toFSnotifyFlags(action uint32) uint64 {\n\tswitch action {\n\tcase syscall.FILE_ACTION_ADDED:\n\t\treturn sysFSCREATE\n\tcase syscall.FILE_ACTION_REMOVED:\n\t\treturn sysFSDELETE\n\tcase syscall.FILE_ACTION_MODIFIED:\n\t\treturn sysFSMODIFY\n\tcase syscall.FILE_ACTION_RENAMED_OLD_NAME:\n\t\treturn sysFSMOVEDFROM\n\tcase syscall.FILE_ACTION_RENAMED_NEW_NAME:\n\t\treturn sysFSMOVEDTO\n\t}\n\treturn 0\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/.codecov.yml",
    "content": "codecov:\n  # across\n  notify:\n    # Do not notify until at least this number of reports have been uploaded\n    # from the CI pipeline. We normally have more than that number, but 6\n    # should be enough to get a first notification.\n    after_n_builds: 6\ncoverage:\n  status:\n    project:\n      default:\n        # Do not fail the commit status if the coverage was reduced up to this value\n        threshold: 0.5%\n    patch:\n      default:\n        informational: true\nignore:\n  - \"log_fallback.go\"\n  - \"internal/testutils\"\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/.craft.yml",
    "content": "minVersion: 2.14.0\nchangelog:\n  policy: auto\nversioning:\n  policy: auto\nartifactProvider:\n  name: none\ntargets:\n  - name: github\n    tagPrefix: v\n  - name: github\n    tagPrefix: otel/v\n    tagOnly: true\n  - name: github\n    tagPrefix: echo/v\n    tagOnly: true\n  - name: github\n    tagPrefix: fasthttp/v\n    tagOnly: true\n  - name: github\n    tagPrefix: fiber/v\n    tagOnly: true\n  - name: github\n    tagPrefix: gin/v\n    tagOnly: true\n  - name: github\n    tagPrefix: iris/v\n    tagOnly: true\n  - name: github\n    tagPrefix: negroni/v\n    tagOnly: true\n  - name: github\n    tagPrefix: logrus/v\n    tagOnly: true\n  - name: github\n    tagPrefix: slog/v\n    tagOnly: true\n  - name: github\n    tagPrefix: zerolog/v\n    tagOnly: true\n  - name: github\n    tagPrefix: zap/v\n    tagOnly: true\n  - name: registry\n    sdks:\n      github:getsentry/sentry-go:\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/.gitattributes",
    "content": "# Tell Git to use LF for line endings on all platforms.\n# Required to have correct test data on Windows.\n# https://github.com/mvdan/github-actions-golang#caveats\n# https://github.com/actions/checkout/issues/135#issuecomment-613361104\n* text eol=lf\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/.gitignore",
    "content": "# Code coverage artifacts\ncoverage.txt\ncoverage.out\ncoverage.html\n.coverage/\n\n# Just my personal way of tracking stuff — Kamil\nFIXME.md\nTODO.md\n!NOTES.md\n\n# IDE system files\n.idea\n.vscode\n\n# Local Claude Code settings that should not be committed\n.claude/settings.local.json\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/.golangci.yml",
    "content": "version: \"2\"\nlinters:\n  default: none\n  enable:\n    - bodyclose\n    - dogsled\n    - dupl\n    - errcheck\n    - gochecknoinits\n    - goconst\n    - gocritic\n    - gocyclo\n    - godot\n    - gosec\n    - govet\n    - ineffassign\n    - misspell\n    - nakedret\n    - prealloc\n    - revive\n    - staticcheck\n    - unconvert\n    - unparam\n    - unused\n    - whitespace\n  exclusions:\n    generated: lax\n    presets:\n      - comments\n      - common-false-positives\n      - legacy\n      - std-error-handling\n    rules:\n      - linters:\n          - goconst\n          - prealloc\n        path: _test\\.go\n      - linters:\n          - gosec\n        path: _test\\.go\n        text: 'G306:'\n      - linters:\n          - unused\n        path: errors_test\\.go\n      - linters:\n          - bodyclose\n          - errcheck\n        path: http/example_test\\.go\n    paths:\n      - third_party$\n      - builtin$\n      - examples$\nformatters:\n  enable:\n    - gofmt\n    - goimports\n  exclusions:\n    generated: lax\n    paths:\n      - third_party$\n      - builtin$\n      - examples$\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/CHANGELOG.md",
    "content": "# Changelog\n\n## 0.43.0\n\n### Breaking Changes 🛠\n\n- Add support for go 1.26 by @giortzisg in [#1193](https://github.com/getsentry/sentry-go/pull/1193)\n  - bump minimum supported go version to 1.24\n- change type signature of attributes for Logs and Metrics. by @giortzisg in [#1205](https://github.com/getsentry/sentry-go/pull/1205)\n  - users are not supposed to modify Attributes directly on the Log/Metric itself, but this is still is a breaking change on the type.\n- Send uint64 overflowing attributes as numbers. by @giortzisg in [#1198](https://github.com/getsentry/sentry-go/pull/1198)\n  - The SDK was converting overflowing uint64 attributes to strings for slog and logrus integrations. To eliminate double types for these attributes, the SDK now sends the overflowing attribute as is, and lets the server handle the overflow appropriately.\n  - It is expected that overflowing unsigned integers would now get dropped, instead of converted to strings.\n\n### New Features ✨\n\n- Add zap logging integration by @giortzisg in [#1184](https://github.com/getsentry/sentry-go/pull/1184)\n- Log specific message for RequestEntityTooLarge by @giortzisg in [#1185](https://github.com/getsentry/sentry-go/pull/1185)\n\n### Bug Fixes 🐛\n\n- Improve otel span map cleanup performance by @giortzisg in [#1200](https://github.com/getsentry/sentry-go/pull/1200)\n- Ensure correct signal delivery on multi-client setups by @giortzisg in [#1190](https://github.com/getsentry/sentry-go/pull/1190)\n\n### Internal Changes 🔧\n\n#### Deps\n\n- Bump golang.org/x/crypto to 0.48.0 by @giortzisg in [#1196](https://github.com/getsentry/sentry-go/pull/1196)\n- Use go1.24.0 by @giortzisg in [#1195](https://github.com/getsentry/sentry-go/pull/1195)\n- Bump github.com/gofiber/fiber/v2 from 2.52.9 to 2.52.11 in /fiber by @dependabot in [#1191](https://github.com/getsentry/sentry-go/pull/1191)\n- Bump getsentry/craft from 2.19.0 to 2.20.1 by @dependabot in [#1187](https://github.com/getsentry/sentry-go/pull/1187)\n\n#### Other\n\n- Add omitzero and remove custom serialization by @giortzisg in [#1197](https://github.com/getsentry/sentry-go/pull/1197)\n- Rename Telemetry Processor components by @giortzisg in [#1186](https://github.com/getsentry/sentry-go/pull/1186)\n\n## 0.42.0\n\n### Breaking Changes 🛠\n\n- refactor Telemetry Processor to use TelemetryItem instead of ItemConvertible by @giortzisg in [#1180](https://github.com/getsentry/sentry-go/pull/1180)\n  - remove ToEnvelopeItem from single log items\n  - rename TelemetryBuffer to Telemetry Processor to adhere to spec\n  - remove unsed ToEnvelopeItem(dsn) from Event.\n\n### New Features ✨\n\n- Add metric support by @aldy505 in [#1151](https://github.com/getsentry/sentry-go/pull/1151)\n  - support for three metric methods (counter, gauge, distribution)\n  - custom metric units\n  - unexport batchlogger\n\n### Internal Changes 🔧\n\n#### Release\n\n- Fix changelog-preview permissions by @BYK in [#1181](https://github.com/getsentry/sentry-go/pull/1181)\n- Switch from action-prepare-release to Craft by @BYK in [#1167](https://github.com/getsentry/sentry-go/pull/1167)\n\n#### Other\n\n- (repo) Add Claude Code settings with basic permissions by @philipphofmann in [#1175](https://github.com/getsentry/sentry-go/pull/1175)\n- Update release and changelog-preview workflows by @giortzisg in [#1177](https://github.com/getsentry/sentry-go/pull/1177)\n- Bump echo to 4.10.1 by @giortzisg in [#1174](https://github.com/getsentry/sentry-go/pull/1174)\n\n## 0.41.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.41.0.\n\n### Features\n\n- Add HTTP client integration for distributed tracing via `sentryhttpclient` package ([#876](https://github.com/getsentry/sentry-go/pull/876))\n  - Provides an `http.RoundTripper` implementation that automatically creates spans for outgoing HTTP requests\n  - Supports trace propagation targets configuration via `WithTracePropagationTargets` option\n  - Example usage:\n    ```go\n    import sentryhttpclient \"github.com/getsentry/sentry-go/httpclient\"\n\n    roundTripper := sentryhttpclient.NewSentryRoundTripper(nil)\n    client := &http.Client{\n        Transport: roundTripper,\n    }\n    ```\n- Add `ClientOptions.PropagateTraceparent` option to control W3C `traceparent` header propagation in outgoing HTTP requests ([#1161](https://github.com/getsentry/sentry-go/pull/1161))\n- Add `SpanID` field to structured logs ([#1169](https://github.com/getsentry/sentry-go/pull/1169))\n\n## 0.40.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.40.0.\n\n### Bug Fixes\n\n- Disable `DisableTelemetryBuffer` flag and noop Telemetry Buffer, to prevent a panic at runtime ([#1149](https://github.com/getsentry/sentry-go/pull/1149)).\n\n## 0.39.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.39.0.\n\n### Features\n\n- Drop events from the telemetry buffer when rate-limited or transport is full, allowing the buffer queue to empty itself under load ([#1138](https://github.com/getsentry/sentry-go/pull/1138)).\n\n### Bug Fixes\n\n- Fix scheduler's `hasWork()` method to check if buffers are ready to flush. The previous implementation was causing CPU spikes ([#1143](https://github.com/getsentry/sentry-go/pull/1143)).\n\n## 0.38.0\n\n### Breaking Changes\n\n### Features\n\n- Introduce a new async envelope transport and telemetry buffer to prioritize and batch events ([#1094](https://github.com/getsentry/sentry-go/pull/1094), [#1093](https://github.com/getsentry/sentry-go/pull/1093), [#1107](https://github.com/getsentry/sentry-go/pull/1107)).\n  - Advantages:\n    - Prioritized, per-category buffers (errors, transactions, logs, check-ins) reduce starvation and improve resilience under load\n    - Batching for high-volume logs (up to 100 items or 5s) cuts network overhead\n    - Bounded memory with eviction policies\n    - Improved flush behavior with context-aware flushing\n- Add `ClientOptions.DisableTelemetryBuffer` to opt out and fall back to the legacy transport layer (`HTTPTransport` / `HTTPSyncTransport`).\n  \n  ```go\n  err := sentry.Init(sentry.ClientOptions{\n    Dsn: \"__DSN__\",\n    DisableTelemetryBuffer: true, // fallback to legacy transport\n  })\n  ```\n\n### Notes\n\n- If a custom `Transport` is provided, the SDK automatically disables the telemetry buffer and uses the legacy transport for compatibility.\n\n## 0.37.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.37.0.\n\n### Breaking Changes\n\n- Behavioral change for the `TraceIgnoreStatusCodes` option. The option now defaults to ignoring 404 status codes ([#1122](https://github.com/getsentry/sentry-go/pull/1122)).\n\n### Features\n\n- Add `sentry.origin` attribute to structured logs to identify log origin for `slog` and `logrus` integrations (`auto.log.slog`, `auto.log.logrus`) ([#1121](https://github.com/getsentry/sentry-go/pull/1121)).\n\n### Bug Fixes\n\n- Fix `slog` event handler to use the initial context, ensuring events use the correct hub/span when the emission context lacks one ([#1133](https://github.com/getsentry/sentry-go/pull/1133)).\n- Improve exception chain processing by checking pointer values when tracking visited errors, avoiding instability for certain wrapped errors ([#1132](https://github.com/getsentry/sentry-go/pull/1132)).\n\n### Misc\n\n- Bump `golang.org/x/net` to v0.38.0 ([#1126](https://github.com/getsentry/sentry-go/pull/1126)).\n\n## 0.36.2\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.36.2.\n\n### Bug Fixes\n\n- Fix context propagation for logs to ensure logger instances correctly inherit span and hub information from their creation context ([#1118](https://github.com/getsentry/sentry-go/pull/1118))\n  - Logs now properly propagate trace context from the logger's original context, even when emitted in a different context\n  - The logger will first check the emission context, then fall back to its creation context, and finally to the current hub\n\n## 0.36.1\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.36.1.\n\n### Bug Fixes\n\n- Prevent panic when converting error chains containing non-comparable error types by using a safe fallback for visited detection in exception conversion ([#1113](https://github.com/getsentry/sentry-go/pull/1113))\n\n## 0.36.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.36.0.\n\n### Breaking Changes\n\n- Behavioral change for the `MaxBreadcrumbs` client option. Removed the hard limit of 100 breadcrumbs, allowing users to set a larger limit and also changed the default limit from 30 to 100 ([#1106](https://github.com/getsentry/sentry-go/pull/1106)))\n\n- The changes to error handling ([#1075](https://github.com/getsentry/sentry-go/pull/1075)) will affect issue grouping. It is expected that any wrapped and complex errors will be grouped under a new issue group.\n\n### Features\n\n- Add support for improved issue grouping with enhanced error chain handling ([#1075](https://github.com/getsentry/sentry-go/pull/1075))\n\n  The SDK now provides better handling of complex error scenarios, particularly when dealing with multiple related errors or error chains. This feature automatically detects and properly structures errors created with Go's `errors.Join()` function and other multi-error patterns.\n\n  ```go\n  // Multiple errors are now properly grouped and displayed in Sentry\n  err1 := errors.New(\"err1\")\n  err2 := errors.New(\"err2\") \n  combinedErr := errors.Join(err1, err2)\n  \n  // When captured, these will be shown as related exceptions in Sentry\n  sentry.CaptureException(combinedErr)\n  ```\n\n- Add `TraceIgnoreStatusCodes` option to allow filtering of HTTP transactions based on status codes ([#1089](https://github.com/getsentry/sentry-go/pull/1089))\n  - Configure which HTTP status codes should not be traced by providing single codes or ranges\n  - Example: `TraceIgnoreStatusCodes: [][]int{{404}, {500, 599}}` ignores 404 and server errors 500-599\n\n### Bug Fixes\n\n- Fix logs being incorrectly filtered by `BeforeSend` callback ([#1109](https://github.com/getsentry/sentry-go/pull/1109))\n  - Logs now bypass the `processEvent` method and are sent directly to the transport\n  - This ensures logs are only filtered by `BeforeSendLog`, not by the error/message `BeforeSend` callback\n\n### Misc\n\n- Add support for Go 1.25 and drop support for Go 1.22 ([#1103](https://github.com/getsentry/sentry-go/pull/1103))\n\n## 0.35.3\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.35.3.\n\n### Bug Fixes\n\n- Add missing rate limit categories ([#1082](https://github.com/getsentry/sentry-go/pull/1082))\n\n## 0.35.2\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.35.2.\n\n### Bug Fixes\n\n- Fix OpenTelemetry spans being created as transactions instead of child spans ([#1073](https://github.com/getsentry/sentry-go/pull/1073))\n\n### Misc\n\n- Add `MockTransport` to test clients for improved testing ([#1071](https://github.com/getsentry/sentry-go/pull/1071))\n\n## 0.35.1\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.35.1.\n\n### Bug Fixes\n\n- Fix race conditions when accessing the scope during logging operations ([#1050](https://github.com/getsentry/sentry-go/pull/1050))\n- Fix nil pointer dereference with malformed URLs when tracing is enabled in `fasthttp` and `fiber` integrations ([#1055](https://github.com/getsentry/sentry-go/pull/1055))\n\n### Misc\n\n- Bump `github.com/gofiber/fiber/v2` from 2.52.5 to 2.52.9 in `/fiber` ([#1067](https://github.com/getsentry/sentry-go/pull/1067))\n\n## 0.35.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.35.0.\n\n### Breaking Changes\n\n- Changes to the logging API ([#1046](https://github.com/getsentry/sentry-go/pull/1046))\n\nThe logging API now supports a fluent interface for structured logging with attributes:\n\n```go\n// usage before\nlogger := sentry.NewLogger(ctx)\n// attributes weren't being set permanently\nlogger.SetAttributes(\n    attribute.String(\"version\", \"1.0.0\"),\n)\nlogger.Infof(ctx, \"Message with parameters %d and %d\", 1, 2)\n\n// new behavior\nctx := context.Background()\nlogger := sentry.NewLogger(ctx)\n\n// Set permanent attributes on the logger\nlogger.SetAttributes(\n    attribute.String(\"version\", \"1.0.0\"),\n)\n\n// Chain attributes on individual log entries\nlogger.Info().\n    String(\"key.string\", \"value\").\n    Int(\"key.int\", 42).\n    Bool(\"key.bool\", true).\n    Emitf(\"Message with parameters %d and %d\", 1, 2)\n```\n\n### Bug Fixes\n\n- Correctly serialize `FailureIssueThreshold` and `RecoveryThreshold` onto check-in payloads ([#1060](https://github.com/getsentry/sentry-go/pull/1060))\n\n## 0.34.1\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.34.1.\n\n### Bug Fixes\n\n- Allow flush to be used multiple times without issues, particularly for the batch logger ([#1051](https://github.com/getsentry/sentry-go/pull/1051))\n- Fix race condition in `Scope.GetSpan()` method by adding proper mutex locking ([#1044](https://github.com/getsentry/sentry-go/pull/1044))\n- Guard transport on `Close()` to prevent panic when called multiple times ([#1044](https://github.com/getsentry/sentry-go/pull/1044))\n\n## 0.34.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.34.0.\n\n### Breaking Changes\n\n- Logrus structured logging support replaces the `sentrylogrus.Hook` signature from a `*Hook` to an interface.\n\n```go\nvar hook *sentrylogrus.Hook\nhook = sentrylogrus.New(\n    // ... your setup\n)\n\n// should change the definition to \nvar hook sentrylogrus.Hook\nhook = sentrylogrus.New(\n    // ... your setup\n)\n```\n\n### Features\n\n- Structured logging support for [slog](https://pkg.go.dev/log/slog). ([#1033](https://github.com/getsentry/sentry-go/pull/1033))\n\n```go\nctx := context.Background()\nhandler := sentryslog.Option{\n    EventLevel: []slog.Level{slog.LevelError, sentryslog.LevelFatal}, // Only Error and Fatal as events\n    LogLevel:   []slog.Level{slog.LevelWarn, slog.LevelInfo},         // Only Warn and Info as logs\n}.NewSentryHandler(ctx)\nlogger := slog.New(handler)\nlogger.Info(\"hello\"))\n```\n\n- Structured logging support for [logrus](https://github.com/sirupsen/logrus). ([#1036](https://github.com/getsentry/sentry-go/pull/1036))\n```go\nlogHook, _ := sentrylogrus.NewLogHook(\n    []logrus.Level{logrus.InfoLevel, logrus.WarnLevel}, \n    sentry.ClientOptions{\n        Dsn: \"your-dsn\",\n        EnableLogs: true, // Required for log entries    \n    })\ndefer logHook.Flush(5 * time.Secod)\nlogrus.RegisterExitHandler(func() {\n    logHook.Flush(5 * time.Second)\n})\n\nlogger := logrus.New()\nlogger.AddHook(logHook)\nlogger.Infof(\"hello\")\n```\n\n- Add support for flushing events with context using `FlushWithContext()`. ([#935](https://github.com/getsentry/sentry-go/pull/935))\n\n```go\nctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\ndefer cancel()\n\nif !sentry.FlushWithContext(ctx) {\n    // Handle timeout or cancellation\n}\n```\n\n- Add support for custom fingerprints in slog integration. ([#1039](https://github.com/getsentry/sentry-go/pull/1039))\n\n### Deprecations \n\n- Slog structured logging support replaces `Level` option with `EventLevel` and `LogLevel` options, for specifying fine-grained levels for capturing events and logs.\n\n```go \nhandler := sentryslog.Option{\n    EventLevel: []slog.Level{slog.LevelWarn, slog.LevelError, sentryslog.LevelFatal},\n    LogLevel:   []slog.Level{slog.LevelDebug, slog.LevelInfo, slog.LevelWarn, slog.LevelError, sentryslog.LevelFatal},\n}.NewSentryHandler(ctx)\n```\n\n- Logrus structured logging support replaces `New` and `NewFromClient` functions to `NewEventHook`, `NewEventHookFromClient`, to match the newly added `NewLogHook` functions, and specify the hook type being created each time.\n\n```go\nlogHook, err := sentrylogrus.NewLogHook(\n    []logrus.Level{logrus.InfoLevel},\n    sentry.ClientOptions{})\neventHook, err := sentrylogrus.NewEventHook([]logrus.Level{\n    logrus.ErrorLevel,\n    logrus.FatalLevel,\n    logrus.PanicLevel,\n}, sentry.ClientOptions{})\n```\n\n### Bug Fixes\n\n- Fix issue where `ContinueTrace()` would panic when `sentry-trace` header does not exist. ([#1026](https://github.com/getsentry/sentry-go/pull/1026))\n- Fix incorrect log level signature in structured logging. ([#1034](https://github.com/getsentry/sentry-go/pull/1034))\n- Remove `sentry.origin` attribute from Sentry logger to prevent confusion in spans. ([#1038](https://github.com/getsentry/sentry-go/pull/1038))\n- Don't gate user information behind `SendDefaultPII` flag for logs. ([#1032](https://github.com/getsentry/sentry-go/pull/1032))\n\n### Misc\n\n- Add more sensitive HTTP headers to the default list of headers that are scrubbed by default. ([#1008](https://github.com/getsentry/sentry-go/pull/1008))\n\n## 0.33.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.33.0.\n\n\n### Breaking Changes\n\n- Rename the internal `Logger` to `DebugLogger`. This feature was only used when you set `Debug: True` in your `sentry.Init()` call. If you haven't used the Logger directly, no changes are necessary. ([#1012](https://github.com/getsentry/sentry-go/issues/1012))\n\n### Features\n\n- Add support for [Structured Logging](https://docs.sentry.io/product/explore/logs/). ([#1010](https://github.com/getsentry/sentry-go/issues/1010))\n\n  ```go\n  logger := sentry.NewLogger(ctx)\n  logger.Info(ctx, \"Hello, Logs!\")\n  ```\n\n  You can learn more about Sentry Logs on our [docs](https://docs.sentry.io/product/explore/logs/) and the [examples](https://github.com/getsentry/sentry-go/blob/master/_examples/logs/main.go).\n\n- Add new attributes APIs, which are currently only exposed on logs. ([#1007](https://github.com/getsentry/sentry-go/issues/1007))\n\n### Bug Fixes\n\n- Do not push a new scope on `StartSpan`. ([#1013](https://github.com/getsentry/sentry-go/issues/1013))\n- Fix an issue where the propagated smapling decision wasn't used. ([#995](https://github.com/getsentry/sentry-go/issues/995))\n- [Otel] Prefer `httpRoute` over `httpTarget` for span descriptions. ([#1002](https://github.com/getsentry/sentry-go/issues/1002))\n\n### Misc\n\n- Update `github.com/stretchr/testify` to v1.8.4. ([#988](https://github.com/getsentry/sentry-go/issues/988))  \n\n## 0.32.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.32.0.\n\n### Breaking Changes\n\n- Bump the minimum Go version to 1.22. The supported versions are 1.22, 1.23 and 1.24. ([#967](https://github.com/getsentry/sentry-go/issues/967))\n- Setting any values on `span.Extra` has no effect anymore. Use `SetData(name string, value interface{})` instead. ([#864](https://github.com/getsentry/sentry-go/pull/864))\n\n### Features\n\n- Add a `MockTransport` and `MockScope`. ([#972](https://github.com/getsentry/sentry-go/pull/972))\n\n### Bug Fixes\n\n- Fix writing `*http.Request` in the Logrus JSONFormatter. ([#955](https://github.com/getsentry/sentry-go/issues/955))\n\n### Misc\n\n- Transaction `data` attributes are now seralized as trace context data attributes, allowing you to query these attributes in the [Trace Explorer](https://docs.sentry.io/product/explore/traces/).\n\n## 0.31.1\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.31.1.\n\n### Bug Fixes\n\n- Correct wrong module name for `sentry-go/logrus` ([#950](https://github.com/getsentry/sentry-go/pull/950))\n\n## 0.31.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.31.0.\n\n### Breaking Changes\n\n- Remove support for metrics. Read more about the end of the Metrics beta [here](https://sentry.zendesk.com/hc/en-us/articles/26369339769883-Metrics-Beta-Ended-on-October-7th). ([#914](https://github.com/getsentry/sentry-go/pull/914))\n\n- Remove support for profiling. ([#915](https://github.com/getsentry/sentry-go/pull/915))\n\n- Remove `Segment` field from the `User` struct. This field is no longer used in the Sentry product. ([#928](https://github.com/getsentry/sentry-go/pull/928))\n\n- Every integration is now a separate module, reducing the binary size and number of dependencies. Once you update `sentry-go` to latest version, you'll need to `go get` the integration you want to use. For example, if you want to use the `echo` integration, you'll need to run `go get github.com/getsentry/sentry-go/echo` ([#919](github.com/getsentry/sentry-go/pull/919)).\n\n### Features\n\nAdd the ability to override `hub` in `context` for integrations that use custom context. ([#931](https://github.com/getsentry/sentry-go/pull/931))\n\n- Add `HubProvider` Hook for `sentrylogrus`, enabling dynamic Sentry hub allocation for each log entry or goroutine. ([#936](https://github.com/getsentry/sentry-go/pull/936))\n\nThis change enhances compatibility with Sentry's recommendation of using separate hubs per goroutine. To ensure a separate Sentry hub for each goroutine, configure the `HubProvider` like this:\n\n```go\nhook, err := sentrylogrus.New(nil, sentry.ClientOptions{})\nif err != nil {\n    log.Fatalf(\"Failed to initialize Sentry hook: %v\", err)\n}\n\n// Set a custom HubProvider to generate a new hub for each goroutine or log entry\nhook.SetHubProvider(func() *sentry.Hub {\n    client, _ := sentry.NewClient(sentry.ClientOptions{})\n    return sentry.NewHub(client, sentry.NewScope())\n})\n\nlogrus.AddHook(hook)\n```\n\n### Bug Fixes\n\n- Add support for closing worker goroutines started by the `HTTPTranport` to prevent goroutine leaks. ([#894](https://github.com/getsentry/sentry-go/pull/894))\n\n```go\nclient, _ := sentry.NewClient()\ndefer client.Close()\n```\n\nWorker can be also closed by calling `Close()` method on the `HTTPTransport` instance. `Close` should be called after `Flush` and before terminating the program otherwise some events may be lost.\n\n```go\ntransport := sentry.NewHTTPTransport()\ndefer transport.Close()\n```\n\n### Misc\n\n- Bump [gin-gonic/gin](https://github.com/gin-gonic/gin) to v1.9.1. ([#946](https://github.com/getsentry/sentry-go/pull/946))\n\n## 0.30.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.30.0.\n\n### Features\n\n- Add `sentryzerolog` integration ([#857](https://github.com/getsentry/sentry-go/pull/857))\n- Add `sentryslog` integration ([#865](https://github.com/getsentry/sentry-go/pull/865))\n- Always set Mechanism Type to generic ([#896](https://github.com/getsentry/sentry-go/pull/897))\n\n### Bug Fixes\n\n- Prevent panic in `fasthttp` and `fiber` integration in case a malformed URL has to be parsed ([#912](https://github.com/getsentry/sentry-go/pull/912))\n\n### Misc\n\nDrop support for Go 1.18, 1.19 and 1.20. The currently supported Go versions are the last 3 stable releases: 1.23, 1.22 and 1.21.\n\n## 0.29.1\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.29.1.\n\n### Bug Fixes\n\n- Correlate errors to the current trace ([#886](https://github.com/getsentry/sentry-go/pull/886))\n- Set the trace context when the transaction finishes ([#888](https://github.com/getsentry/sentry-go/pull/888))\n\n### Misc\n\n- Update the `sentrynegroni` integration to use the latest (v3.1.1) version of Negroni ([#885](https://github.com/getsentry/sentry-go/pull/885))\n\n## 0.29.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.29.0.\n\n### Breaking Changes\n\n- Remove the `sentrymartini` integration ([#861](https://github.com/getsentry/sentry-go/pull/861))\n- The `WrapResponseWriter` has been moved from the `sentryhttp` package to the `internal/httputils` package. If you've imported it previosuly, you'll need to copy the implementation in your project. ([#871](https://github.com/getsentry/sentry-go/pull/871))\n\n### Features\n\n- Add new convenience methods to continue a trace and propagate tracing headers for error-only use cases. ([#862](https://github.com/getsentry/sentry-go/pull/862))\n\n  If you are not using one of our integrations, you can manually continue an incoming trace by using `sentry.ContinueTrace()` by providing the `sentry-trace` and `baggage` header received from a downstream SDK.\n\n  ```go\n  hub := sentry.CurrentHub()\n  sentry.ContinueTrace(hub, r.Header.Get(sentry.SentryTraceHeader), r.Header.Get(sentry.SentryBaggageHeader)),\n  ```\n\n  You can use `hub.GetTraceparent()` and `hub.GetBaggage()` to fetch the necessary header values for outgoing HTTP requests.\n\n  ```go\n  hub := sentry.GetHubFromContext(ctx)\n  req, _ := http.NewRequest(\"GET\", \"http://localhost:3000\", nil)\n  req.Header.Add(sentry.SentryTraceHeader, hub.GetTraceparent())\n  req.Header.Add(sentry.SentryBaggageHeader, hub.GetBaggage())\n  ```\n\n### Bug Fixes\n\n- Initialize `HTTPTransport.limit` if `nil` ([#844](https://github.com/getsentry/sentry-go/pull/844))\n- Fix `sentry.StartTransaction()` returning a transaction with an outdated context on existing transactions ([#854](https://github.com/getsentry/sentry-go/pull/854))\n- Treat `Proxy-Authorization` as a sensitive header ([#859](https://github.com/getsentry/sentry-go/pull/859))\n- Add support for the `http.Hijacker` interface to the `sentrynegroni` package ([#871](https://github.com/getsentry/sentry-go/pull/871))\n- Go version >= 1.23: Use value from `http.Request.Pattern` for HTTP transaction names when using `sentryhttp` & `sentrynegroni` ([#875](https://github.com/getsentry/sentry-go/pull/875))\n- Go version >= 1.21: Fix closure functions name grouping ([#877](https://github.com/getsentry/sentry-go/pull/877))\n\n### Misc\n\n- Collect `span` origins ([#849](https://github.com/getsentry/sentry-go/pull/849))\n\n## 0.28.1\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.28.1.\n\n### Bug Fixes\n\n- Implement `http.ResponseWriter` to hook into various parts of the response process ([#837](https://github.com/getsentry/sentry-go/pull/837))\n\n## 0.28.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.28.0.\n\n### Features\n\n- Add a `Fiber` performance tracing & error reporting integration ([#795](https://github.com/getsentry/sentry-go/pull/795))\n- Add performance tracing to the `Echo` integration ([#722](https://github.com/getsentry/sentry-go/pull/722))\n- Add performance tracing to the `FastHTTP` integration ([#732](https://github.com/getsentry/sentry-go/pull/723))\n- Add performance tracing to the `Iris` integration ([#809](https://github.com/getsentry/sentry-go/pull/809))\n- Add performance tracing to the `Negroni` integration ([#808](https://github.com/getsentry/sentry-go/pull/808))\n- Add `FailureIssueThreshold` & `RecoveryThreshold` to `MonitorConfig` ([#775](https://github.com/getsentry/sentry-go/pull/775))\n- Use `errors.Unwrap()` to create exception groups ([#792](https://github.com/getsentry/sentry-go/pull/792))\n- Add support for matching on strings for `ClientOptions.IgnoreErrors` & `ClientOptions.IgnoreTransactions` ([#819](https://github.com/getsentry/sentry-go/pull/819))\n- Add `http.request.method` attribute for performance span data ([#786](https://github.com/getsentry/sentry-go/pull/786))\n- Accept `interface{}` for span data values ([#784](https://github.com/getsentry/sentry-go/pull/784))\n\n### Bug Fixes\n\n- Fix missing stack trace for parsing error in `logrusentry` ([#689](https://github.com/getsentry/sentry-go/pull/689))\n\n## 0.27.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.27.0.\n\n### Breaking Changes\n\n- `Exception.ThreadId` is now typed as `uint64`. It was wrongly typed as `string` before. ([#770](https://github.com/getsentry/sentry-go/pull/770))\n\n### Misc\n\n- Export `Event.Attachments` ([#771](https://github.com/getsentry/sentry-go/pull/771))\n\n## 0.26.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.26.0.\n\n### Breaking Changes\n\nAs previously announced, this release removes some methods from the SDK.\n\n- `sentry.TransactionName()` use `sentry.WithTransactionName()` instead.\n- `sentry.OpName()` use `sentry.WithOpName()` instead.\n- `sentry.TransctionSource()` use `sentry.WithTransactionSource()` instead.\n- `sentry.SpanSampled()` use `sentry.WithSpanSampled()` instead.\n\n### Features\n\n- Add `WithDescription` span option ([#751](https://github.com/getsentry/sentry-go/pull/751))\n\n  ```go\n  span := sentry.StartSpan(ctx, \"http.client\", WithDescription(\"GET /api/users\"))\n  ```\n- Add support for package name parsing in Go 1.20 and higher ([#730](https://github.com/getsentry/sentry-go/pull/730))\n\n### Bug Fixes\n\n- Apply `ClientOptions.SampleRate` only to errors & messages ([#754](https://github.com/getsentry/sentry-go/pull/754))\n- Check if git is available before executing any git commands ([#737](https://github.com/getsentry/sentry-go/pull/737))\n\n## 0.25.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.25.0.\n\n### Breaking Changes\n\nAs previously announced, this release removes two global constants from the SDK.\n\n- `sentry.Version` was removed. Use `sentry.SDKVersion` instead ([#727](https://github.com/getsentry/sentry-go/pull/727))\n- `sentry.SDKIdentifier` was removed. Use `Client.GetSDKIdentifier()` instead ([#727](https://github.com/getsentry/sentry-go/pull/727))\n\n### Features\n\n- Add `ClientOptions.IgnoreTransactions`, which allows you to ignore specific transactions based on their name ([#717](https://github.com/getsentry/sentry-go/pull/717))\n- Add `ClientOptions.Tags`, which allows you to set global tags that are applied to all events. You can also define tags by setting `SENTRY_TAGS_` environment variables ([#718](https://github.com/getsentry/sentry-go/pull/718))\n\n### Bug fixes\n\n- Fix an issue in the profiler that would cause an infinite loop if the duration of a transaction is longer than 30 seconds ([#724](https://github.com/getsentry/sentry-go/issues/724))\n\n### Misc\n\n- `dsn.RequestHeaders()` is not to be removed, though it is still considered deprecated and should only be used when using a custom transport that sends events to the `/store` endpoint ([#720](https://github.com/getsentry/sentry-go/pull/720))\n\n## 0.24.1\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.24.1.\n\n### Bug fixes\n\n- Prevent a panic in `sentryotel.flushSpanProcessor()` ([(#711)](https://github.com/getsentry/sentry-go/pull/711))\n- Prevent a panic when setting the SDK identifier ([#715](https://github.com/getsentry/sentry-go/pull/715))\n\n## 0.24.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.24.0.\n\n### Deprecations\n\n- `sentry.Version` to be removed in 0.25.0. Use `sentry.SDKVersion` instead.\n- `sentry.SDKIdentifier` to be removed in 0.25.0. Use `Client.GetSDKIdentifier()` instead.\n- `dsn.RequestHeaders()` to be removed after 0.25.0, but no earlier than December 1, 2023. Requests to the `/envelope` endpoint are authenticated using the DSN in the envelope header.\n\n### Features\n\n- Run a single instance of the profiler instead of multiple ones for each Go routine ([#655](https://github.com/getsentry/sentry-go/pull/655))\n- Use the route path as the transaction names when using the Gin integration ([#675](https://github.com/getsentry/sentry-go/pull/675))\n- Set the SDK name accordingly when a framework integration is used ([#694](https://github.com/getsentry/sentry-go/pull/694))\n- Read release information (VCS revision) from `debug.ReadBuildInfo` ([#704](https://github.com/getsentry/sentry-go/pull/704))\n\n### Bug fixes\n\n- [otel] Fix incorrect usage of `attributes.Value.AsString` ([#684](https://github.com/getsentry/sentry-go/pull/684))\n- Fix trace function name parsing in profiler on go1.21+ ([#695](https://github.com/getsentry/sentry-go/pull/695))\n\n### Misc\n\n- Test against Go 1.21 ([#695](https://github.com/getsentry/sentry-go/pull/695))\n- Make tests more robust ([#698](https://github.com/getsentry/sentry-go/pull/698), [#699](https://github.com/getsentry/sentry-go/pull/699), [#700](https://github.com/getsentry/sentry-go/pull/700), [#702](https://github.com/getsentry/sentry-go/pull/702))\n\n## 0.23.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.23.0.\n\n### Features\n\n- Initial support for [Cron Monitoring](https://docs.sentry.io/product/crons/) ([#661](https://github.com/getsentry/sentry-go/pull/661))\n\n  This is how the basic usage of the feature looks like:\n\n  ```go\n  // 🟡 Notify Sentry your job is running:\n  checkinId := sentry.CaptureCheckIn(\n    &sentry.CheckIn{\n      MonitorSlug: \"<monitor-slug>\",\n      Status:      sentry.CheckInStatusInProgress,\n    },\n    nil,\n  )\n\n  // Execute your scheduled task here...\n\n  // 🟢 Notify Sentry your job has completed successfully:\n  sentry.CaptureCheckIn(\n    &sentry.CheckIn{\n      ID:          *checkinId,\n      MonitorSlug: \"<monitor-slug>\",\n      Status:      sentry.CheckInStatusOK,\n    },\n    nil,\n  )\n  ```\n\n  A full example of using Crons Monitoring is available [here](https://github.com/getsentry/sentry-go/blob/dde4d360660838f3c2e0ced8205bc8f7a8d312d9/_examples/crons/main.go).\n\n  More documentation on configuring and using Crons [can be found here](https://docs.sentry.io/platforms/go/crons/).\n\n- Add support for [Event Attachments](https://docs.sentry.io/platforms/go/enriching-events/attachments/) ([#670](https://github.com/getsentry/sentry-go/pull/670))\n\n  It's now possible to add file/binary payloads to Sentry events:\n\n  ```go\n  sentry.ConfigureScope(func(scope *sentry.Scope) {\n    scope.AddAttachment(&Attachment{\n      Filename:    \"report.html\",\n      ContentType: \"text/html\",\n      Payload:     []byte(\"<h1>Look, HTML</h1>\"),\n    })\n  })\n  ```\n\n  The attachment will then be accessible on the Issue Details page.\n\n- Add sampling decision to trace envelope header ([#666](https://github.com/getsentry/sentry-go/pull/666))\n- Expose SpanFromContext function ([#672](https://github.com/getsentry/sentry-go/pull/672))\n\n### Bug fixes\n\n- Make `Span.Finish` a no-op when the span is already finished ([#660](https://github.com/getsentry/sentry-go/pull/660))\n\n## 0.22.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.22.0.\n\nThis release contains initial [profiling](https://docs.sentry.io/product/profiling/) support, as well as a few bug fixes and improvements.\n\n### Features\n\n- Initial (alpha) support for [profiling](https://docs.sentry.io/product/profiling/) ([#626](https://github.com/getsentry/sentry-go/pull/626))\n\n  Profiling is disabled by default. To enable it, configure both `TracesSampleRate` and `ProfilesSampleRate` when initializing the SDK:\n\n  ```go\n  err := sentry.Init(sentry.ClientOptions{\n    Dsn: \"__DSN__\",\n    EnableTracing: true,\n    TracesSampleRate: 1.0,\n    // The sampling rate for profiling is relative to TracesSampleRate. In this case, we'll capture profiles for 100% of transactions.\n    ProfilesSampleRate: 1.0,\n  })\n  ```\n\n  More documentation on profiling and current limitations [can be found here](https://docs.sentry.io/platforms/go/profiling/).\n\n- Add transactions/tracing support go the Gin integration ([#644](https://github.com/getsentry/sentry-go/pull/644))\n\n### Bug fixes\n\n- Always set a valid source on transactions ([#637](https://github.com/getsentry/sentry-go/pull/637))\n- Clone scope.Context in more places to avoid panics on concurrent reads and writes ([#638](https://github.com/getsentry/sentry-go/pull/638))\n  - Fixes [#570](https://github.com/getsentry/sentry-go/issues/570)\n- Fix frames recognized as not being in-app still showing as in-app ([#647](https://github.com/getsentry/sentry-go/pull/647))\n\n## 0.21.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.21.0.\n\nNote: this release includes one **breaking change** and some **deprecations**, which are listed below.\n\n### Breaking Changes\n\n**This change does not apply if you use [https://sentry.io](https://sentry.io)**\n\n- Remove support for the `/store` endpoint ([#631](https://github.com/getsentry/sentry-go/pull/631))\n  - This change requires a self-hosted version of Sentry 20.6.0 or higher. If you are using a version of [self-hosted Sentry](https://develop.sentry.dev/self-hosted/) (aka *on-premise*) older than 20.6.0, then you will need to [upgrade](https://develop.sentry.dev/self-hosted/releases/) your instance.\n\n### Features\n\n- Rename four span option functions ([#611](https://github.com/getsentry/sentry-go/pull/611), [#624](https://github.com/getsentry/sentry-go/pull/624))\n  - `TransctionSource` -> `WithTransactionSource`\n  - `SpanSampled` -> `WithSpanSampled`\n  - `OpName` -> `WithOpName`\n  - `TransactionName` -> `WithTransactionName`\n  - Old functions `TransctionSource`, `SpanSampled`, `OpName`, and `TransactionName` are still available but are now **deprecated** and will be removed in a future release.\n- Make `client.EventFromMessage` and `client.EventFromException` methods public ([#607](https://github.com/getsentry/sentry-go/pull/607))\n- Add `client.SetException` method ([#607](https://github.com/getsentry/sentry-go/pull/607))\n  - This allows to set or add errors to an existing `Event`.\n\n### Bug Fixes\n\n- Protect from panics while doing concurrent reads/writes to Span data fields ([#609](https://github.com/getsentry/sentry-go/pull/609))\n- [otel] Improve detection of Sentry-related spans ([#632](https://github.com/getsentry/sentry-go/pull/632), [#636](https://github.com/getsentry/sentry-go/pull/636))\n  - Fixes cases when HTTP spans containing requests to Sentry were captured by Sentry ([#627](https://github.com/getsentry/sentry-go/issues/627))\n\n### Misc\n\n- Drop testing in (legacy) GOPATH mode ([#618](https://github.com/getsentry/sentry-go/pull/618))\n- Remove outdated documentation from https://pkg.go.dev/github.com/getsentry/sentry-go ([#623](https://github.com/getsentry/sentry-go/pull/623))\n\n## 0.20.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.20.0.\n\nNote: this release has some **breaking changes**, which are listed below.\n\n### Breaking Changes\n\n- Remove the following methods: `Scope.SetTransaction()`, `Scope.Transaction()` ([#605](https://github.com/getsentry/sentry-go/pull/605))\n\n  Span.Name should be used instead to access the transaction's name.\n\n  For example, the following [`TracesSampler`](https://docs.sentry.io/platforms/go/configuration/sampling/#setting-a-sampling-function) function should be now written as follows:\n\n  **Before:**\n  ```go\n  TracesSampler: func(ctx sentry.SamplingContext) float64 {\n    hub := sentry.GetHubFromContext(ctx.Span.Context())\n    if hub.Scope().Transaction() == \"GET /health\" {\n      return 0\n    }\n    return 1\n  },\n  ```\n\n  **After:**\n  ```go\n  TracesSampler: func(ctx sentry.SamplingContext) float64 {\n    if ctx.Span.Name == \"GET /health\" {\n      return 0\n    }\n    return 1\n  },\n  ```\n\n### Features\n\n- Add `Span.SetContext()` method ([#599](https://github.com/getsentry/sentry-go/pull/599/))\n  - It is recommended to use it instead of `hub.Scope().SetContext` when setting or updating context on transactions.\n- Add `DebugMeta` interface to `Event` and extend `Frame` structure with more fields ([#606](https://github.com/getsentry/sentry-go/pull/606))\n  - More about DebugMeta interface [here](https://develop.sentry.dev/sdk/event-payloads/debugmeta/).\n\n### Bug Fixes\n\n- [otel] Fix missing OpenTelemetry context on some events ([#599](https://github.com/getsentry/sentry-go/pull/599), [#605](https://github.com/getsentry/sentry-go/pull/605))\n  - Fixes ([#596](https://github.com/getsentry/sentry-go/issues/596)).\n- [otel] Better handling for HTTP span attributes ([#610](https://github.com/getsentry/sentry-go/pull/610))\n\n### Misc\n\n- Bump minimum versions: `github.com/kataras/iris/v12` to 12.2.0, `github.com/labstack/echo/v4` to v4.10.0 ([#595](https://github.com/getsentry/sentry-go/pull/595))\n  - Resolves [GO-2022-1144 / CVE-2022-41717](https://deps.dev/advisory/osv/GO-2022-1144), [GO-2023-1495 / CVE-2022-41721](https://deps.dev/advisory/osv/GO-2023-1495), [GO-2022-1059 / CVE-2022-32149](https://deps.dev/advisory/osv/GO-2022-1059).\n- Bump `google.golang.org/protobuf` minimum required version to 1.29.1  ([#604](https://github.com/getsentry/sentry-go/pull/604))\n  - This fixes a potential denial of service issue ([CVE-2023-24535](https://github.com/advisories/GHSA-hw7c-3rfg-p46j)).\n- Exclude the `otel` module when building in GOPATH mode ([#615](https://github.com/getsentry/sentry-go/pull/615))\n\n## 0.19.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.19.0.\n\n### Features\n\n- Add support for exception mechanism metadata ([#564](https://github.com/getsentry/sentry-go/pull/564/))\n  - More about exception mechanisms [here](https://develop.sentry.dev/sdk/event-payloads/exception/#exception-mechanism).\n\n### Bug Fixes\n- [otel] Use the correct \"trace\" context when sending a Sentry error ([#580](https://github.com/getsentry/sentry-go/pull/580/))\n\n\n### Misc\n- Drop support for Go 1.17, add support for Go 1.20 ([#563](https://github.com/getsentry/sentry-go/pull/563/))\n  - According to our policy, we're officially supporting the last three minor releases of Go.\n- Switch repository license to MIT ([#583](https://github.com/getsentry/sentry-go/pull/583/))\n  - More about Sentry licensing [here](https://open.sentry.io/licensing/).\n- Bump `golang.org/x/text` minimum required version to 0.3.8 ([#586](https://github.com/getsentry/sentry-go/pull/586))\n  - This fixes [CVE-2022-32149](https://github.com/advisories/GHSA-69ch-w2m2-3vjp) vulnerability.\n\n## 0.18.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.18.0.\nThis release contains initial support for [OpenTelemetry](https://opentelemetry.io/) and various other bug fixes and improvements.\n\n**Note**: This is the last release supporting Go 1.17.\n\n### Features\n\n- Initial support for [OpenTelemetry](https://opentelemetry.io/).\n  You can now send all your OpenTelemetry spans to Sentry.\n\n  Install the `otel` module\n\n  ```bash\n  go get github.com/getsentry/sentry-go \\\n         github.com/getsentry/sentry-go/otel\n  ```\n\n  Configure the Sentry and OpenTelemetry SDKs\n\n  ```go\n  import (\n      \"go.opentelemetry.io/otel\"\n      sdktrace \"go.opentelemetry.io/otel/sdk/trace\"\n      \"github.com/getsentry/sentry-go\"\n      \"github.com/getsentry/sentry-go/otel\"\n      // ...\n  )\n\n  // Initlaize the Sentry SDK\n  sentry.Init(sentry.ClientOptions{\n      Dsn:              \"__DSN__\",\n      EnableTracing:    true,\n      TracesSampleRate: 1.0,\n  })\n\n  // Set up the Sentry span processor\n  tp := sdktrace.NewTracerProvider(\n      sdktrace.WithSpanProcessor(sentryotel.NewSentrySpanProcessor()),\n      // ...\n  )\n  otel.SetTracerProvider(tp)\n\n  // Set up the Sentry propagator\n  otel.SetTextMapPropagator(sentryotel.NewSentryPropagator())\n  ```\n\n  You can read more about using OpenTelemetry with Sentry in our [docs](https://docs.sentry.io/platforms/go/performance/instrumentation/opentelemetry/).\n\n### Bug Fixes\n\n- Do not freeze the Dynamic Sampling Context when no Sentry values are present in the baggage header ([#532](https://github.com/getsentry/sentry-go/pull/532))\n- Create a frozen Dynamic Sampling Context when calling `span.ToBaggage()` ([#566](https://github.com/getsentry/sentry-go/pull/566))\n- Fix baggage parsing and encoding in vendored otel package ([#568](https://github.com/getsentry/sentry-go/pull/568))\n\n### Misc\n\n- Add `Span.SetDynamicSamplingContext()` ([#539](https://github.com/getsentry/sentry-go/pull/539/))\n- Add various getters for `Dsn` ([#540](https://github.com/getsentry/sentry-go/pull/540))\n- Add `SpanOption::SpanSampled` ([#546](https://github.com/getsentry/sentry-go/pull/546))\n- Add `Span.SetData()` ([#542](https://github.com/getsentry/sentry-go/pull/542))\n- Add `Span.IsTransaction()` ([#543](https://github.com/getsentry/sentry-go/pull/543))\n- Add `Span.GetTransaction()` method ([#558](https://github.com/getsentry/sentry-go/pull/558))\n\n## 0.17.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.17.0.\nThis release contains a new `BeforeSendTransaction` hook option and corrects two regressions introduced in `0.16.0`.\n\n### Features\n\n- Add `BeforeSendTransaction` hook to `ClientOptions` ([#517](https://github.com/getsentry/sentry-go/pull/517))\n  - Here's [an example](https://github.com/getsentry/sentry-go/blob/master/_examples/http/main.go#L56-L66) of how BeforeSendTransaction can be used to modify or drop transaction events.\n\n### Bug Fixes\n\n- Do not crash in Span.Finish() when the Client is empty [#520](https://github.com/getsentry/sentry-go/pull/520)\n  - Fixes [#518](https://github.com/getsentry/sentry-go/issues/518)\n- Attach non-PII/non-sensitive request headers to events when `ClientOptions.SendDefaultPii` is set to `false` ([#524](https://github.com/getsentry/sentry-go/pull/524))\n  - Fixes [#523](https://github.com/getsentry/sentry-go/issues/523)\n\n### Misc\n\n- Clarify how to handle logrus.Fatalf events ([#501](https://github.com/getsentry/sentry-go/pull/501/))\n- Rename the `examples` directory to `_examples` ([#521](https://github.com/getsentry/sentry-go/pull/521))\n  - This removes an indirect dependency to `github.com/golang-jwt/jwt`\n\n## 0.16.0\n\nThe Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.16.0.\nDue to ongoing work towards a stable API for `v1.0.0`, we sadly had to include **two breaking changes** in this release.\n\n### Breaking Changes\n\n- Add `EnableTracing`, a boolean option flag to enable performance monitoring (`false` by default).\n   - If you're using `TracesSampleRate` or `TracesSampler`, this option is **required** to enable performance monitoring.\n\n      ```go\n      sentry.Init(sentry.ClientOptions{\n          EnableTracing: true,\n          TracesSampleRate: 1.0,\n      })\n      ```\n- Unify TracesSampler [#498](https://github.com/getsentry/sentry-go/pull/498)\n    - `TracesSampler` was changed to a callback that must return a `float64` between `0.0` and `1.0`.\n\n       For example, you can apply a sample rate of `1.0` (100%) to all `/api` transactions, and a sample rate of `0.5` (50%) to all other transactions.\n       You can read more about this in our [SDK docs](https://docs.sentry.io/platforms/go/configuration/filtering/#using-sampling-to-filter-transaction-events).\n\n       ```go\n       sentry.Init(sentry.ClientOptions{\n           TracesSampler: sentry.TracesSampler(func(ctx sentry.SamplingContext) float64 {\n                hub := sentry.GetHubFromContext(ctx.Span.Context())\n                name := hub.Scope().Transaction()\n\n                if strings.HasPrefix(name, \"GET /api\") {\n                    return 1.0\n                }\n\n                return 0.5\n            }),\n        }\n        ```\n\n### Features\n\n- Send errors logged with [Logrus](https://github.com/sirupsen/logrus) to Sentry.\n    - Have a look at our [logrus examples](https://github.com/getsentry/sentry-go/blob/master/_examples/logrus/main.go) on how to use the integration.\n- Add support for Dynamic Sampling [#491](https://github.com/getsentry/sentry-go/pull/491)\n    - You can read more about Dynamic Sampling in our [product docs](https://docs.sentry.io/product/data-management-settings/dynamic-sampling/).\n- Add detailed logging about the reason transactions are being dropped.\n    - You can enable SDK logging via `sentry.ClientOptions.Debug: true`.\n\n### Bug Fixes\n\n- Do not clone the hub when calling `StartTransaction` [#505](https://github.com/getsentry/sentry-go/pull/505)\n    - Fixes [#502](https://github.com/getsentry/sentry-go/issues/502)\n\n## 0.15.0\n\n- fix: Scope values should not override Event values (#446)\n- feat: Make maximum amount of spans configurable (#460)\n- feat: Add a method to start a transaction (#482)\n- feat: Extend User interface by adding Data, Name and Segment (#483)\n- feat: Add ClientOptions.SendDefaultPII (#485)\n\n## 0.14.0\n\n- feat: Add function to continue from trace string (#434)\n- feat: Add `max-depth` options (#428)\n- *[breaking]* ref: Use a `Context` type mapping to a `map[string]interface{}` for all event contexts (#444)\n- *[breaking]* ref: Replace deprecated `ioutil` pkg with `os` & `io` (#454)\n- ref: Optimize `stacktrace.go` from size and speed (#467)\n- ci: Test against `go1.19` and `go1.18`, drop `go1.16` and `go1.15` support (#432, #477)\n- deps: Dependency update to fix CVEs (#462, #464, #477)\n\n_NOTE:_ This version drops support for Go 1.16 and Go 1.15. The currently supported Go versions are the last 3 stable releases: 1.19, 1.18 and 1.17.\n\n## v0.13.0\n\n- ref: Change DSN ProjectID to be a string (#420)\n- fix: When extracting PCs from stack frames, try the `PC` field (#393)\n- build: Bump gin-gonic/gin from v1.4.0 to v1.7.7 (#412)\n- build: Bump Go version in go.mod (#410)\n- ci: Bump golangci-lint version in GH workflow (#419)\n- ci: Update GraphQL config with appropriate permissions (#417)\n- ci: ci: Add craft release automation (#422)\n\n## v0.12.0\n\n- feat: Automatic Release detection (#363, #369, #386, #400)\n- fix: Do not change Hub.lastEventID for transactions (#379)\n- fix: Do not clear LastEventID when events are dropped (#382)\n- Updates to documentation (#366, #385)\n\n_NOTE:_\nThis version drops support for Go 1.14, however no changes have been made that would make the SDK not work with Go 1.14. The currently supported Go versions are the last 3 stable releases: 1.15, 1.16 and 1.17.\nThere are two behavior changes related to `LastEventID`, both of which were intended to align the behavior of the Sentry Go SDK with other Sentry SDKs.\nThe new [automatic release detection feature](https://github.com/getsentry/sentry-go/issues/335) makes it easier to use Sentry and separate events per release without requiring extra work from users. We intend to improve this functionality in a future release by utilizing information that will be available in runtime starting with Go 1.18. The tracking issue is [#401](https://github.com/getsentry/sentry-go/issues/401).\n\n## v0.11.0\n\n- feat(transports): Category-based Rate Limiting ([#354](https://github.com/getsentry/sentry-go/pull/354))\n- feat(transports): Report User-Agent identifying SDK ([#357](https://github.com/getsentry/sentry-go/pull/357))\n- fix(scope): Include event processors in clone ([#349](https://github.com/getsentry/sentry-go/pull/349))\n- Improvements to `go doc` documentation ([#344](https://github.com/getsentry/sentry-go/pull/344), [#350](https://github.com/getsentry/sentry-go/pull/350), [#351](https://github.com/getsentry/sentry-go/pull/351))\n- Miscellaneous changes to our testing infrastructure with GitHub Actions\n  ([57123a40](https://github.com/getsentry/sentry-go/commit/57123a409be55f61b1d5a6da93c176c55a399ad0), [#128](https://github.com/getsentry/sentry-go/pull/128), [#338](https://github.com/getsentry/sentry-go/pull/338), [#345](https://github.com/getsentry/sentry-go/pull/345), [#346](https://github.com/getsentry/sentry-go/pull/346), [#352](https://github.com/getsentry/sentry-go/pull/352), [#353](https://github.com/getsentry/sentry-go/pull/353), [#355](https://github.com/getsentry/sentry-go/pull/355))\n\n_NOTE:_\nThis version drops support for Go 1.13. The currently supported Go versions are the last 3 stable releases: 1.14, 1.15 and 1.16.\nUsers of the tracing functionality (`StartSpan`, etc) should upgrade to this version to benefit from separate rate limits for errors and transactions.\nThere are no breaking changes and upgrading should be a smooth experience for all users.\n\n## v0.10.0\n\n- feat: Debug connection reuse (#323)\n- fix: Send root span data as `Event.Extra` (#329)\n- fix: Do not double sample transactions (#328)\n- fix: Do not override trace context of transactions (#327)\n- fix: Drain and close API response bodies (#322)\n- ci: Run tests against Go tip (#319)\n- ci: Move away from Travis in favor of GitHub Actions (#314) (#321)\n\n## v0.9.0\n\n- feat: Initial tracing and performance monitoring support (#285)\n- doc: Revamp sentryhttp documentation (#304)\n- fix: Hub.PopScope never empties the scope stack (#300)\n- ref: Report Event.Timestamp in local time (#299)\n- ref: Report Breadcrumb.Timestamp in local time (#299)\n\n_NOTE:_\nThis version introduces support for [Sentry's Performance Monitoring](https://docs.sentry.io/platforms/go/performance/).\nThe new tracing capabilities are beta, and we plan to expand them on future versions. Feedback is welcome, please open new issues on GitHub.\nThe `sentryhttp` package got better API docs, an [updated usage example](https://github.com/getsentry/sentry-go/tree/master/_examples/http) and support for creating automatic transactions as part of Performance Monitoring.\n\n## v0.8.0\n\n- build: Bump required version of Iris (#296)\n- fix: avoid unnecessary allocation in Client.processEvent (#293)\n- doc: Remove deprecation of sentryhttp.HandleFunc (#284)\n- ref: Update sentryhttp example (#283)\n- doc: Improve documentation of sentryhttp package (#282)\n- doc: Clarify SampleRate documentation (#279)\n- fix: Remove RawStacktrace (#278)\n- docs: Add example of custom HTTP transport\n- ci: Test against go1.15, drop go1.12 support (#271)\n\n_NOTE:_\nThis version comes with a few updates. Some examples and documentation have been\nimproved. We've bumped the supported version of the Iris framework to avoid\nLGPL-licensed modules in the module dependency graph.\nThe `Exception.RawStacktrace` and `Thread.RawStacktrace` fields have been\nremoved to conform to Sentry's ingestion protocol, only `Exception.Stacktrace`\nand `Thread.Stacktrace` should appear in user code.\n\n## v0.7.0\n\n- feat: Include original error when event cannot be encoded as JSON (#258)\n- feat: Use Hub from request context when available (#217, #259)\n- feat: Extract stack frames from golang.org/x/xerrors (#262)\n- feat: Make Environment Integration preserve existing context data (#261)\n- feat: Recover and RecoverWithContext with arbitrary types (#268)\n- feat: Report bad usage of CaptureMessage and CaptureEvent (#269)\n- feat: Send debug logging to stderr by default (#266)\n- feat: Several improvements to documentation (#223, #245, #250, #265)\n- feat: Example of Recover followed by panic (#241, #247)\n- feat: Add Transactions and Spans (to support OpenTelemetry Sentry Exporter) (#235, #243, #254)\n- fix: Set either Frame.Filename or Frame.AbsPath (#233)\n- fix: Clone requestBody to new Scope (#244)\n- fix: Synchronize access and mutation of Hub.lastEventID (#264)\n- fix: Avoid repeated syscalls in prepareEvent (#256)\n- fix: Do not allocate new RNG for every event (#256)\n- fix: Remove stale replace directive in go.mod (#255)\n- fix(http): Deprecate HandleFunc, remove duplication (#260)\n\n_NOTE:_\nThis version comes packed with several fixes and improvements and no breaking\nchanges.\nNotably, there is a change in how the SDK reports file names in stack traces\nthat should resolve any ambiguity when looking at stack traces and using the\nSuspect Commits feature.\nWe recommend all users to upgrade.\n\n## v0.6.1\n\n- fix: Use NewEvent to init Event struct (#220)\n\n_NOTE:_\nA change introduced in v0.6.0 with the intent of avoiding allocations made a\npattern used in official examples break in certain circumstances (attempting\nto write to a nil map).\nThis release reverts the change such that maps in the Event struct are always\nallocated.\n\n## v0.6.0\n\n- feat: Read module dependencies from runtime/debug (#199)\n- feat: Support chained errors using Unwrap (#206)\n- feat: Report chain of errors when available (#185)\n- **[breaking]** fix: Accept http.RoundTripper to customize transport (#205)\n  Before the SDK accepted a concrete value of type `*http.Transport` in\n  `ClientOptions`, now it accepts any value implementing the `http.RoundTripper`\n  interface. Note that `*http.Transport` implements `http.RoundTripper`, so most\n  code bases will continue to work unchanged.\n  Users of custom transport gain the ability to pass in other implementations of\n  `http.RoundTripper` and may be able to simplify their code bases.\n- fix: Do not panic when scope event processor drops event (#192)\n- **[breaking]** fix: Use time.Time for timestamps (#191)\n  Users of sentry-go typically do not need to manipulate timestamps manually.\n  For those who do, the field type changed from `int64` to `time.Time`, which\n  should be more convenient to use. The recommended way to get the current time\n  is `time.Now().UTC()`.\n- fix: Report usage error including stack trace (#189)\n- feat: Add Exception.ThreadID field (#183)\n- ci: Test against Go 1.14, drop 1.11 (#170)\n- feat: Limit reading bytes from request bodies (#168)\n- **[breaking]** fix: Rename fasthttp integration package sentryhttp => sentryfasthttp\n  The current recommendation is to use a named import, in which case existing\n  code should not require any change:\n  ```go\n  package main\n\n  import (\n  \t\"fmt\"\n\n  \t\"github.com/getsentry/sentry-go\"\n  \tsentryfasthttp \"github.com/getsentry/sentry-go/fasthttp\"\n  \t\"github.com/valyala/fasthttp\"\n  )\n  ```\n\n_NOTE:_\nThis version includes some new features and a few breaking changes, none of\nwhich should pose troubles with upgrading. Most code bases should be able to\nupgrade without any changes.\n\n## v0.5.1\n\n- fix: Ignore err.Cause() when it is nil (#160)\n\n## v0.5.0\n\n- fix: Synchronize access to HTTPTransport.disabledUntil (#158)\n- docs: Update Flush documentation (#153)\n- fix: HTTPTransport.Flush panic and data race (#140)\n\n_NOTE:_\nThis version changes the implementation of the default transport, modifying the\nbehavior of `sentry.Flush`. The previous behavior was to wait until there were\nno buffered events; new concurrent events kept `Flush` from returning. The new\nbehavior is to wait until the last event prior to the call to `Flush` has been\nsent or the timeout; new concurrent events have no effect. The new behavior is\ninline with the [Unified API\nGuidelines](https://docs.sentry.io/development/sdk-dev/unified-api/).\n\nWe have updated the documentation and examples to clarify that `Flush` is meant\nto be called typically only once before program termination, to wait for\nin-flight events to be sent to Sentry. Calling `Flush` after every event is not\nrecommended, as it introduces unnecessary latency to the surrounding function.\nPlease verify the usage of `sentry.Flush` in your code base.\n\n## v0.4.0\n\n- fix(stacktrace): Correctly report package names (#127)\n- fix(stacktrace): Do not rely on AbsPath of files (#123)\n- build: Require github.com/ugorji/go@v1.1.7 (#110)\n- fix: Correctly store last event id (#99)\n- fix: Include request body in event payload (#94)\n- build: Reset go.mod version to 1.11 (#109)\n- fix: Eliminate data race in modules integration (#105)\n- feat: Add support for path prefixes in the DSN (#102)\n- feat: Add HTTPClient option (#86)\n- feat: Extract correct type and value from top-most error (#85)\n- feat: Check for broken pipe errors in Gin integration (#82)\n- fix: Client.CaptureMessage accept nil EventModifier (#72)\n\n## v0.3.1\n\n- feat: Send extra information exposed by the Go runtime (#76)\n- fix: Handle new lines in module integration (#65)\n- fix: Make sure that cache is locked when updating for contextifyFramesIntegration\n- ref: Update Iris integration and example to version 12\n- misc: Remove indirect dependencies in order to move them to separate go.mod files\n\n## v0.3.0\n\n- feat: Retry event marshaling without contextual data if the first pass fails\n- fix: Include `url.Parse` error in `DsnParseError`\n- fix: Make more `Scope` methods safe for concurrency\n- fix: Synchronize concurrent access to `Hub.client`\n- ref: Remove mutex from `Scope` exported API\n- ref: Remove mutex from `Hub` exported API\n- ref: Compile regexps for `filterFrames` only once\n- ref: Change `SampleRate` type to `float64`\n- doc: `Scope.Clear` not safe for concurrent use\n- ci: Test sentry-go with `go1.13`, drop `go1.10`\n\n_NOTE:_\nThis version removes some of the internal APIs that landed publicly (namely `Hub/Scope` mutex structs) and may require (but shouldn't) some changes to your code.\nIt's not done through major version update, as we are still in `0.x` stage.\n\n## v0.2.1\n\n- fix: Run `Contextify` integration on `Threads` as well\n\n## v0.2.0\n\n- feat: Add `SetTransaction()` method on the `Scope`\n- feat: `fasthttp` framework support with `sentryfasthttp` package\n- fix: Add `RWMutex` locks to internal `Hub` and `Scope` changes\n\n## v0.1.3\n\n- feat: Move frames context reading into `contextifyFramesIntegration` (#28)\n\n_NOTE:_\nIn case of any performance issues due to source contexts IO, you can let us know and turn off the integration in the meantime with:\n\n```go\nsentry.Init(sentry.ClientOptions{\n\tIntegrations: func(integrations []sentry.Integration) []sentry.Integration {\n\t\tvar filteredIntegrations []sentry.Integration\n\t\tfor _, integration := range integrations {\n\t\t\tif integration.Name() == \"ContextifyFrames\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfilteredIntegrations = append(filteredIntegrations, integration)\n\t\t}\n\t\treturn filteredIntegrations\n\t},\n})\n```\n\n## v0.1.2\n\n- feat: Better source code location resolution and more useful inapp frames (#26)\n- feat: Use `noopTransport` when no `Dsn` provided (#27)\n- ref: Allow empty `Dsn` instead of returning an error (#22)\n- fix: Use `NewScope` instead of literal struct inside a `scope.Clear` call (#24)\n- fix: Add to `WaitGroup` before the request is put inside a buffer (#25)\n\n## v0.1.1\n\n- fix: Check for initialized `Client` in `AddBreadcrumbs` (#20)\n- build: Bump version when releasing with Craft (#19)\n\n## v0.1.0\n\n- First stable release! \\o/\n\n## v0.0.1-beta.5\n\n- feat: **[breaking]** Add `NewHTTPTransport` and `NewHTTPSyncTransport` which accepts all transport options\n- feat: New `HTTPSyncTransport` that blocks after each call\n- feat: New `Echo` integration\n- ref: **[breaking]** Remove `BufferSize` option from `ClientOptions` and move it to `HTTPTransport` instead\n- ref: Export default `HTTPTransport`\n- ref: Export `net/http` integration handler\n- ref: Set `Request` instantly in the package handlers, not in `recoverWithSentry` so it can be accessed later on\n- ci: Add craft config\n\n## v0.0.1-beta.4\n\n- feat: `IgnoreErrors` client option and corresponding integration\n- ref: Reworked `net/http` integration, wrote better example and complete readme\n- ref: Reworked `Gin` integration, wrote better example and complete readme\n- ref: Reworked `Iris` integration, wrote better example and complete readme\n- ref: Reworked `Negroni` integration, wrote better example and complete readme\n- ref: Reworked `Martini` integration, wrote better example and complete readme\n- ref: Remove `Handle()` from frameworks handlers and return it directly from New\n\n## v0.0.1-beta.3\n\n- feat: `Iris` framework support with `sentryiris` package\n- feat: `Gin` framework support with `sentrygin` package\n- feat: `Martini` framework support with `sentrymartini` package\n- feat: `Negroni` framework support with `sentrynegroni` package\n- feat: Add `Hub.Clone()` for easier frameworks integration\n- feat: Return `EventID` from `Recovery` methods\n- feat: Add `NewScope` and `NewEvent` functions and use them in the whole codebase\n- feat: Add `AddEventProcessor` to the `Client`\n- fix: Operate on requests body copy instead of the original\n- ref: Try to read source files from the root directory, based on the filename as well, to make it work on AWS Lambda\n- ref: Remove `gocertifi` dependence and document how to provide your own certificates\n- ref: **[breaking]** Remove `Decorate` and `DecorateFunc` methods in favor of `sentryhttp` package\n- ref: **[breaking]** Allow for integrations to live on the client, by passing client instance in `SetupOnce` method\n- ref: **[breaking]** Remove `GetIntegration` from the `Hub`\n- ref: **[breaking]** Remove `GlobalEventProcessors` getter from the public API\n\n## v0.0.1-beta.2\n\n- feat: Add `AttachStacktrace` client option to include stacktrace for messages\n- feat: Add `BufferSize` client option to configure transport buffer size\n- feat: Add `SetRequest` method on a `Scope` to control `Request` context data\n- feat: Add `FromHTTPRequest` for `Request` type for easier extraction\n- ref: Extract `Request` information more accurately\n- fix: Attach `ServerName`, `Release`, `Dist`, `Environment` options to the event\n- fix: Don't log events dropped due to full transport buffer as sent\n- fix: Don't panic and create an appropriate event when called `CaptureException` or `Recover` with `nil` value\n\n## v0.0.1-beta\n\n- Initial release\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/CONTRIBUTING.md",
    "content": "# Contributing to sentry-go\n\nHey, thank you if you're reading this, we welcome your contribution!\n\n## Sending a Pull Request\n\nPlease help us save time when reviewing your PR by following this simple\nprocess:\n\n1. Is your PR a simple typo fix? Read no further, **click that green \"Create\n   pull request\" button**!\n\n2. For more complex PRs that involve behavior changes or new APIs, please\n   consider [opening an **issue**][new-issue] describing the problem you're\n   trying to solve if there's not one already.\n\n   A PR is often one specific solution to a problem and sometimes talking about\n   the problem unfolds new possible solutions. Remember we will be responsible\n   for maintaining the changes later.\n\n3. Fixing a bug and changing a behavior? Please add automated tests to prevent\n   future regression.\n\n4. Practice writing good commit messages. We have [commit\n   guidelines][commit-guide].\n\n5. We have [guidelines for PR submitters][pr-guide]. A short summary:\n\n   - Good PR descriptions are very helpful and most of the time they include\n     **why** something is done and why done in this particular way. Also list\n     other possible solutions that were considered and discarded.\n   - Be your own first reviewer. Make sure your code compiles and passes the\n     existing tests.\n\n[new-issue]: https://github.com/getsentry/sentry-go/issues/new/choose\n[commit-guide]: https://develop.sentry.dev/code-review/#commit-guidelines\n[pr-guide]: https://develop.sentry.dev/code-review/#guidelines-for-submitters\n\nPlease also read through our [SDK Development docs](https://develop.sentry.dev/sdk/).\nIt contains information about SDK features, expected payloads and best practices for\ncontributing to Sentry SDKs.\n\n## Community\n\nThe public-facing channels for support and development of Sentry SDKs can be found on [Discord](https://discord.gg/Ww9hbqr).\n\n## Testing\n\n```console\n$ go test\n```\n\n### Watch mode\n\nUse: https://github.com/cespare/reflex\n\n```console\n$ reflex -g '*.go' -d \"none\" -- sh -c 'printf \"\\n\"; go test'\n```\n\n### With data race detection\n\n```console\n$ go test -race\n```\n\n### Coverage\n\n```console\n$ go test -race -coverprofile=coverage.txt -covermode=atomic && go tool cover -html coverage.txt\n```\n\n## Linting\n\nLint with [`golangci-lint`](https://github.com/golangci/golangci-lint):\n\n```console\n$ golangci-lint run\n```\n\n## Release\n\n1. Update `CHANGELOG.md` with new version in `vX.X.X` format title and list of changes.\n\n   The command below can be used to get a list of changes since the last tag, with the format used in `CHANGELOG.md`:\n\n   ```console\n   $ git log --no-merges --format=%s $(git describe --abbrev=0).. | sed 's/^/- /'\n   ```\n\n2. Commit with `misc: vX.X.X changelog` commit message and push to `master`.\n\n3. Let [`craft`](https://github.com/getsentry/craft) do the rest:\n\n   ```console\n   $ craft prepare X.X.X\n   $ craft publish X.X.X\n   ```\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 Functional Software, Inc. dba Sentry\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": "vendor/github.com/getsentry/sentry-go/MIGRATION.md",
    "content": "# `raven-go` to `sentry-go` Migration Guide\n\nA [`raven-go` to `sentry-go` migration guide](https://docs.sentry.io/platforms/go/migration/) is available at the official Sentry documentation site.\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/Makefile",
    "content": ".DEFAULT_GOAL := help\n\nMKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))\nMKFILE_DIR := $(dir $(MKFILE_PATH))\nALL_GO_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \\; | sort)\nGO = go\nTIMEOUT = 300\n\n# Parse Makefile and display the help\nhelp: ## Show help\n\t@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = \":.*?## \"}; {printf \"\\033[36m%-30s\\033[0m %s\\n\", $$1, $$2}'\n.PHONY: help\n\nbuild: ## Build everything\n\tfor dir in $(ALL_GO_MOD_DIRS); do \\\n\t\tcd \"$${dir}\"; \\\n\t\techo \">>> Running 'go build' for module: $${dir}\"; \\\n\t\tgo build ./...; \\\n\tdone;\n.PHONY: build\n\n### Tests (inspired by https://github.com/open-telemetry/opentelemetry-go/blob/main/Makefile)\nTEST_TARGETS := test-short test-verbose test-race\ntest-race:    ARGS=-race\ntest-short:   ARGS=-short\ntest-verbose: ARGS=-v -race\n$(TEST_TARGETS): test\ntest: $(ALL_GO_MOD_DIRS:%=test/%)  ## Run tests\ntest/%: DIR=$*\ntest/%:\n\t@echo \">>> Running tests for module: $(DIR)\"\n\t@# We use '-count=1' to disable test caching.\n\t(cd $(DIR) && $(GO) test -count=1 -timeout $(TIMEOUT)s $(ARGS) ./...)\n.PHONY: $(TEST_TARGETS) test\n\n# Coverage\nCOVERAGE_MODE    = atomic\nCOVERAGE_PROFILE = coverage.out\nCOVERAGE_REPORT_DIR = .coverage\nCOVERAGE_REPORT_DIR_ABS = \"$(MKFILE_DIR)/$(COVERAGE_REPORT_DIR)\"\n$(COVERAGE_REPORT_DIR):\n\tmkdir -p $(COVERAGE_REPORT_DIR)\nclean-report-dir: $(COVERAGE_REPORT_DIR)\n\ttest $(COVERAGE_REPORT_DIR) && rm -f $(COVERAGE_REPORT_DIR)/*\ntest-coverage: $(COVERAGE_REPORT_DIR) clean-report-dir  ## Test with coverage enabled\n\tset -e ; \\\n\tfor dir in $(ALL_GO_MOD_DIRS); do \\\n\t  echo \">>> Running tests with coverage for module: $${dir}\"; \\\n\t  DIR_ABS=$$(python -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' $${dir}) ; \\\n\t  REPORT_NAME=$$(basename $${DIR_ABS}); \\\n\t  (cd \"$${dir}\" && \\\n\t    $(GO) test -count=1 -timeout $(TIMEOUT)s -coverpkg=./... -covermode=$(COVERAGE_MODE) -coverprofile=\"$(COVERAGE_PROFILE)\" ./... && \\\n\t\tcp $(COVERAGE_PROFILE) \"$(COVERAGE_REPORT_DIR_ABS)/$${REPORT_NAME}_$(COVERAGE_PROFILE)\" && \\\n\t    $(GO) tool cover -html=$(COVERAGE_PROFILE) -o coverage.html); \\\n\tdone;\n.PHONY: test-coverage clean-report-dir\ntest-race-coverage: $(COVERAGE_REPORT_DIR) clean-report-dir  ## Run tests with race detection and coverage\n\tset -e ; \\\n\tfor dir in $(ALL_GO_MOD_DIRS); do \\\n\t  echo \">>> Running tests with race detection and coverage for module: $${dir}\"; \\\n\t  DIR_ABS=$$(python -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' $${dir}) ; \\\n\t  REPORT_NAME=$$(basename $${DIR_ABS}); \\\n\t  (cd \"$${dir}\" && \\\n\t    $(GO) test -count=1 -timeout $(TIMEOUT)s -race -coverpkg=./... -covermode=$(COVERAGE_MODE) -coverprofile=\"$(COVERAGE_PROFILE)\" ./... && \\\n\t\tcp $(COVERAGE_PROFILE) \"$(COVERAGE_REPORT_DIR_ABS)/$${REPORT_NAME}_$(COVERAGE_PROFILE)\" && \\\n\t    $(GO) tool cover -html=$(COVERAGE_PROFILE) -o coverage.html); \\\n\tdone;\n.PHONY: test-race-coverage\nmod-tidy: ## Check go.mod tidiness\n\tset -e ; \\\n\tfor dir in $(ALL_GO_MOD_DIRS); do \\\n\t\techo \">>> Running 'go mod tidy' for module: $${dir}\"; \\\n\t\t(cd \"$${dir}\" && GOTOOLCHAIN=local go mod tidy -go=1.24.0 -compat=1.24.0); \\\n\tdone; \\\n\tgit diff --exit-code;\n.PHONY: mod-tidy\n\nvet: ## Run \"go vet\"\n\tset -e ; \\\n\tfor dir in $(ALL_GO_MOD_DIRS); do \\\n\t\techo \">>> Running 'go vet' for module: $${dir}\"; \\\n\t\t(cd \"$${dir}\" && go vet ./...); \\\n\tdone;\n.PHONY: vet\n\n\nlint: ## Lint (using \"golangci-lint\")\n\tgolangci-lint run\n.PHONY: lint\n\nfmt: ## Format all Go files\n\tgofmt -l -w -s .\n.PHONY: fmt\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/README.md",
    "content": "<p align=\"center\">\n  <a href=\"https://sentry.io/?utm_source=github&utm_medium=logo\" target=\"_blank\">\n    <picture>\n      <source srcset=\"https://sentry-brand.storage.googleapis.com/sentry-logo-white.png\" media=\"(prefers-color-scheme: dark)\" />\n      <source srcset=\"https://sentry-brand.storage.googleapis.com/sentry-logo-black.png\" media=\"(prefers-color-scheme: light), (prefers-color-scheme: no-preference)\" />\n      <img src=\"https://sentry-brand.storage.googleapis.com/sentry-logo-black.png\" alt=\"Sentry\" width=\"280\">\n    </picture>\n  </a>\n</p>\n\n# Official Sentry SDK for Go\n\n[![Build Status](https://github.com/getsentry/sentry-go/actions/workflows/test.yml/badge.svg)](https://github.com/getsentry/sentry-go/actions/workflows/test.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/getsentry/sentry-go)](https://goreportcard.com/report/github.com/getsentry/sentry-go)\n[![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/Ww9hbqr)\n[![X Follow](https://img.shields.io/twitter/follow/sentry?label=sentry&style=social)](https://x.com/intent/follow?screen_name=sentry)\n[![go.dev](https://img.shields.io/badge/go.dev-pkg-007d9c.svg?style=flat)](https://pkg.go.dev/github.com/getsentry/sentry-go)\n\n`sentry-go` provides a Sentry client implementation for the Go programming\nlanguage. This is the next generation of the Go SDK for [Sentry](https://sentry.io/),\nintended to replace the `raven-go` package.\n\n> Looking for the old `raven-go` SDK documentation? See the Legacy client section [here](https://docs.sentry.io/clients/go/).\n> If you want to start using `sentry-go` instead, check out the [migration guide](https://docs.sentry.io/platforms/go/migration/).\n\n## Requirements\n\nThe only requirement is a Go compiler.\n\nWe verify this package against the 3 most recent releases of Go. Those are the\nsupported versions. The exact versions are defined in\n[`GitHub workflow`](.github/workflows/test.yml).\n\nIn addition, we run tests against the current master branch of the Go toolchain,\nthough support for this configuration is best-effort.\n\n## Installation\n\n`sentry-go` can be installed like any other Go library through `go get`:\n\n```console\n$ go get github.com/getsentry/sentry-go@latest\n```\n\nCheck out the [list of released versions](https://github.com/getsentry/sentry-go/releases).\n\n## Configuration\n\nTo use `sentry-go`, you’ll need to import the `sentry-go` package and initialize\nit with your DSN and other [options](https://pkg.go.dev/github.com/getsentry/sentry-go#ClientOptions).\n\nIf not specified in the SDK initialization, the\n[DSN](https://docs.sentry.io/product/sentry-basics/dsn-explainer/),\n[Release](https://docs.sentry.io/product/releases/) and\n[Environment](https://docs.sentry.io/product/sentry-basics/environments/)\nare read from the environment variables `SENTRY_DSN`, `SENTRY_RELEASE` and\n`SENTRY_ENVIRONMENT`, respectively.\n\nMore on this in the [Configuration section of the official Sentry Go SDK documentation](https://docs.sentry.io/platforms/go/configuration/).\n\n## Usage\n\nThe SDK supports reporting errors and tracking application performance.\n\nTo get started, have a look at one of our [examples](_examples/):\n- [Basic error instrumentation](_examples/basic/main.go)\n- [Error and tracing for HTTP servers](_examples/http/main.go)\n\nWe also provide a [complete API reference](https://pkg.go.dev/github.com/getsentry/sentry-go).\n\nFor more detailed information about how to get the most out of `sentry-go`,\ncheck out the official documentation:\n\n- [Sentry Go SDK documentation](https://docs.sentry.io/platforms/go/)\n- Guides:\n  - [net/http](https://docs.sentry.io/platforms/go/guides/http/)\n  - [echo](https://docs.sentry.io/platforms/go/guides/echo/)\n  - [fasthttp](https://docs.sentry.io/platforms/go/guides/fasthttp/)\n  - [fiber](https://docs.sentry.io/platforms/go/guides/fiber/)\n  - [gin](https://docs.sentry.io/platforms/go/guides/gin/)\n  - [iris](https://docs.sentry.io/platforms/go/guides/iris/)\n  - [logrus](https://docs.sentry.io/platforms/go/guides/logrus/)\n  - [negroni](https://docs.sentry.io/platforms/go/guides/negroni/)\n  - [slog](https://docs.sentry.io/platforms/go/guides/slog/)\n  - [zerolog](https://docs.sentry.io/platforms/go/guides/zerolog/)\n\n## Resources\n\n- [Bug Tracker](https://github.com/getsentry/sentry-go/issues)\n- [GitHub Project](https://github.com/getsentry/sentry-go)\n- [![go.dev](https://img.shields.io/badge/go.dev-pkg-007d9c.svg?style=flat)](https://pkg.go.dev/github.com/getsentry/sentry-go)\n- [![Documentation](https://img.shields.io/badge/documentation-sentry.io-green.svg)](https://docs.sentry.io/platforms/go/)\n- [![Discussions](https://img.shields.io/github/discussions/getsentry/sentry-go.svg)](https://github.com/getsentry/sentry-go/discussions)\n- [![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/Ww9hbqr)\n- [![Stack Overflow](https://img.shields.io/badge/stack%20overflow-sentry-green.svg)](http://stackoverflow.com/questions/tagged/sentry)\n- [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry)\n\n## License\n\nLicensed under\n[The MIT License](https://opensource.org/licenses/mit/), see\n[`LICENSE`](LICENSE).\n\n## Community\n\nJoin Sentry's [`#go` channel on Discord](https://discord.gg/Ww9hbqr) to get\ninvolved and help us improve the SDK!\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/attribute/builder.go",
    "content": "package attribute\n\ntype Builder struct {\n\tKey   string\n\tValue Value\n}\n\n// String returns a Builder for a string value.\nfunc String(key, value string) Builder {\n\treturn Builder{key, StringValue(value)}\n}\n\n// Int64 returns a Builder for an int64.\nfunc Int64(key string, value int64) Builder {\n\treturn Builder{key, Int64Value(value)}\n}\n\n// Int returns a Builder for an int64.\nfunc Int(key string, value int) Builder {\n\treturn Builder{key, IntValue(value)}\n}\n\n// Float64 returns a Builder for a float64.\nfunc Float64(key string, v float64) Builder {\n\treturn Builder{key, Float64Value(v)}\n}\n\n// Bool returns a Builder for a boolean.\nfunc Bool(key string, v bool) Builder {\n\treturn Builder{key, BoolValue(v)}\n}\n\n// Valid checks for valid key and type.\nfunc (b *Builder) Valid() bool {\n\treturn len(b.Key) > 0 && b.Value.Type() != INVALID\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/attribute/rawhelpers.go",
    "content": "// Copied from https://github.com/open-telemetry/opentelemetry-go/blob/cc43e01c27892252aac9a8f20da28cdde957a289/attribute/rawhelpers.go\n// Copyright The OpenTelemetry Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage attribute\n\nimport (\n\t\"math\"\n)\n\nfunc boolToRaw(b bool) uint64 { // b is not a control flag.\n\tif b {\n\t\treturn 1\n\t}\n\treturn 0\n}\n\nfunc rawToBool(r uint64) bool {\n\treturn r != 0\n}\n\nfunc int64ToRaw(i int64) uint64 {\n\t// Assumes original was a valid int64 (overflow not checked).\n\treturn uint64(i) // nolint: gosec\n}\n\nfunc rawToInt64(r uint64) int64 {\n\t// Assumes original was a valid int64 (overflow not checked).\n\treturn int64(r) // nolint: gosec\n}\n\nfunc float64ToRaw(f float64) uint64 {\n\treturn math.Float64bits(f)\n}\n\nfunc rawToFloat64(r uint64) float64 {\n\treturn math.Float64frombits(r)\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/attribute/value.go",
    "content": "// Adapted from https://github.com/open-telemetry/opentelemetry-go/blob/cc43e01c27892252aac9a8f20da28cdde957a289/attribute/value.go\n//\n// Copyright The OpenTelemetry Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage attribute\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strconv\"\n)\n\n// Type describes the type of the data Value holds.\ntype Type int // redefines builtin Type.\n\n// Value represents the value part in key-value pairs.\ntype Value struct {\n\tvtype    Type\n\tnumeric  uint64\n\tstringly string\n}\n\nconst (\n\t// INVALID is used for a Value with no value set.\n\tINVALID Type = iota\n\t// BOOL is a boolean Type Value.\n\tBOOL\n\t// INT64 is a 64-bit signed integral Type Value.\n\tINT64\n\t// FLOAT64 is a 64-bit floating point Type Value.\n\tFLOAT64\n\t// STRING is a string Type Value.\n\tSTRING\n\t// UINT64 is a 64-bit unsigned integral Type Value.\n\t//\n\t// This type is intentionally not exposed through the Builder API.\n\tUINT64\n)\n\n// BoolValue creates a BOOL Value.\nfunc BoolValue(v bool) Value {\n\treturn Value{\n\t\tvtype:   BOOL,\n\t\tnumeric: boolToRaw(v),\n\t}\n}\n\n// IntValue creates an INT64 Value.\nfunc IntValue(v int) Value {\n\treturn Int64Value(int64(v))\n}\n\n// Int64Value creates an INT64 Value.\nfunc Int64Value(v int64) Value {\n\treturn Value{\n\t\tvtype:   INT64,\n\t\tnumeric: int64ToRaw(v),\n\t}\n}\n\n// Float64Value creates a FLOAT64 Value.\nfunc Float64Value(v float64) Value {\n\treturn Value{\n\t\tvtype:   FLOAT64,\n\t\tnumeric: float64ToRaw(v),\n\t}\n}\n\n// StringValue creates a STRING Value.\nfunc StringValue(v string) Value {\n\treturn Value{\n\t\tvtype:    STRING,\n\t\tstringly: v,\n\t}\n}\n\n// Uint64Value creates a UINT64 Value.\n//\n// This constructor is intentionally not exposed through the Builder API.\nfunc Uint64Value(v uint64) Value {\n\treturn Value{\n\t\tvtype:   UINT64,\n\t\tnumeric: v,\n\t}\n}\n\n// Type returns a type of the Value.\nfunc (v Value) Type() Type {\n\treturn v.vtype\n}\n\n// AsBool returns the bool value. Make sure that the Value's type is\n// BOOL.\nfunc (v Value) AsBool() bool {\n\treturn rawToBool(v.numeric)\n}\n\n// AsInt64 returns the int64 value. Make sure that the Value's type is\n// INT64.\nfunc (v Value) AsInt64() int64 {\n\treturn rawToInt64(v.numeric)\n}\n\n// AsFloat64 returns the float64 value. Make sure that the Value's\n// type is FLOAT64.\nfunc (v Value) AsFloat64() float64 {\n\treturn rawToFloat64(v.numeric)\n}\n\n// AsString returns the string value. Make sure that the Value's type\n// is STRING.\nfunc (v Value) AsString() string {\n\treturn v.stringly\n}\n\n// AsUint64 returns the uint64 value. Make sure that the Value's type is\n// UINT64.\nfunc (v Value) AsUint64() uint64 {\n\treturn v.numeric\n}\n\ntype unknownValueType struct{}\n\n// AsInterface returns Value's data as interface{}.\nfunc (v Value) AsInterface() interface{} {\n\tswitch v.Type() {\n\tcase BOOL:\n\t\treturn v.AsBool()\n\tcase INT64:\n\t\treturn v.AsInt64()\n\tcase FLOAT64:\n\t\treturn v.AsFloat64()\n\tcase STRING:\n\t\treturn v.stringly\n\tcase UINT64:\n\t\treturn v.numeric\n\t}\n\treturn unknownValueType{}\n}\n\n// String returns a string representation of Value's data.\nfunc (v Value) String() string {\n\tswitch v.Type() {\n\tcase BOOL:\n\t\treturn strconv.FormatBool(v.AsBool())\n\tcase INT64:\n\t\treturn strconv.FormatInt(v.AsInt64(), 10)\n\tcase FLOAT64:\n\t\treturn fmt.Sprint(v.AsFloat64())\n\tcase STRING:\n\t\treturn v.stringly\n\tcase UINT64:\n\t\treturn strconv.FormatUint(v.numeric, 10)\n\tdefault:\n\t\treturn \"unknown\"\n\t}\n}\n\n// MarshalJSON returns the JSON encoding of the Value.\nfunc (v Value) MarshalJSON() ([]byte, error) {\n\tvar jsonVal struct {\n\t\tValue any    `json:\"value\"`\n\t\tType  string `json:\"type\"`\n\t}\n\tjsonVal.Type = mapTypesToStr[v.Type()]\n\tjsonVal.Value = v.AsInterface()\n\treturn json.Marshal(jsonVal)\n}\n\nfunc (t Type) String() string {\n\tswitch t {\n\tcase BOOL:\n\t\treturn \"bool\"\n\tcase INT64:\n\t\treturn \"int64\"\n\tcase FLOAT64:\n\t\treturn \"float64\"\n\tcase STRING:\n\t\treturn \"string\"\n\tcase UINT64:\n\t\treturn \"uint64\"\n\t}\n\treturn \"invalid\"\n}\n\n// mapTypesToStr is a map from attribute.Type to the primitive types the server understands.\n// https://develop.sentry.dev/sdk/foundations/data-model/attributes/#primitive-types\nvar mapTypesToStr = map[Type]string{\n\tINVALID: \"\",\n\tBOOL:    \"boolean\",\n\tINT64:   \"integer\",\n\tFLOAT64: \"double\",\n\tSTRING:  \"string\",\n\tUINT64:  \"integer\", // wire format: same \"integer\" type\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/batch_processor.go",
    "content": "package sentry\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n)\n\nconst (\n\tbatchSize           = 100\n\tdefaultBatchTimeout = 5 * time.Second\n)\n\ntype batchProcessor[T any] struct {\n\tsendBatch    func([]T)\n\titemCh       chan T\n\tflushCh      chan chan struct{}\n\tcancel       context.CancelFunc\n\twg           sync.WaitGroup\n\tstartOnce    sync.Once\n\tshutdownOnce sync.Once\n\tbatchTimeout time.Duration\n}\n\nfunc newBatchProcessor[T any](sendBatch func([]T)) *batchProcessor[T] {\n\treturn &batchProcessor[T]{\n\t\titemCh:       make(chan T, batchSize),\n\t\tflushCh:      make(chan chan struct{}),\n\t\tsendBatch:    sendBatch,\n\t\tbatchTimeout: defaultBatchTimeout,\n\t}\n}\n\n// WithBatchTimeout sets a custom batch timeout for the processor.\n// This is useful for testing or when different timing behavior is needed.\nfunc (p *batchProcessor[T]) WithBatchTimeout(timeout time.Duration) *batchProcessor[T] {\n\tp.batchTimeout = timeout\n\treturn p\n}\n\nfunc (p *batchProcessor[T]) Send(item T) bool {\n\tselect {\n\tcase p.itemCh <- item:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc (p *batchProcessor[T]) Start() {\n\tp.startOnce.Do(func() {\n\t\tctx, cancel := context.WithCancel(context.Background())\n\t\tp.cancel = cancel\n\t\tp.wg.Add(1)\n\t\tgo p.run(ctx)\n\t})\n}\n\nfunc (p *batchProcessor[T]) Flush(timeout <-chan struct{}) {\n\tdone := make(chan struct{})\n\tselect {\n\tcase p.flushCh <- done:\n\t\tselect {\n\t\tcase <-done:\n\t\tcase <-timeout:\n\t\t}\n\tcase <-timeout:\n\t}\n}\n\nfunc (p *batchProcessor[T]) Shutdown() {\n\tp.shutdownOnce.Do(func() {\n\t\tif p.cancel != nil {\n\t\t\tp.cancel()\n\t\t\tp.wg.Wait()\n\t\t}\n\t})\n}\n\nfunc (p *batchProcessor[T]) run(ctx context.Context) {\n\tdefer p.wg.Done()\n\tvar items []T\n\ttimer := time.NewTimer(0)\n\ttimer.Stop()\n\tdefer timer.Stop()\n\n\tfor {\n\t\tselect {\n\t\tcase item := <-p.itemCh:\n\t\t\tif len(items) == 0 {\n\t\t\t\ttimer.Reset(p.batchTimeout)\n\t\t\t}\n\t\t\titems = append(items, item)\n\t\t\tif len(items) >= batchSize {\n\t\t\t\tp.sendBatch(items)\n\t\t\t\titems = nil\n\t\t\t}\n\t\tcase <-timer.C:\n\t\t\tif len(items) > 0 {\n\t\t\t\tp.sendBatch(items)\n\t\t\t\titems = nil\n\t\t\t}\n\t\tcase done := <-p.flushCh:\n\t\tflushDrain:\n\t\t\tfor {\n\t\t\t\tselect {\n\t\t\t\tcase item := <-p.itemCh:\n\t\t\t\t\titems = append(items, item)\n\t\t\t\tdefault:\n\t\t\t\t\tbreak flushDrain\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif len(items) > 0 {\n\t\t\t\tp.sendBatch(items)\n\t\t\t\titems = nil\n\t\t\t}\n\t\t\tclose(done)\n\t\tcase <-ctx.Done():\n\t\tdrain:\n\t\t\tfor {\n\t\t\t\tselect {\n\t\t\t\tcase item := <-p.itemCh:\n\t\t\t\t\titems = append(items, item)\n\t\t\t\tdefault:\n\t\t\t\t\tbreak drain\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif len(items) > 0 {\n\t\t\t\tp.sendBatch(items)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/check_in.go",
    "content": "package sentry\n\nimport \"time\"\n\ntype CheckInStatus string\n\nconst (\n\tCheckInStatusInProgress CheckInStatus = \"in_progress\"\n\tCheckInStatusOK         CheckInStatus = \"ok\"\n\tCheckInStatusError      CheckInStatus = \"error\"\n)\n\ntype checkInScheduleType string\n\nconst (\n\tcheckInScheduleTypeCrontab  checkInScheduleType = \"crontab\"\n\tcheckInScheduleTypeInterval checkInScheduleType = \"interval\"\n)\n\ntype MonitorSchedule interface {\n\t// scheduleType is a private method that must be implemented for monitor schedule\n\t// implementation. It should never be called. This method is made for having\n\t// specific private implementation of MonitorSchedule interface.\n\tscheduleType() checkInScheduleType\n}\n\ntype crontabSchedule struct {\n\tType  string `json:\"type\"`\n\tValue string `json:\"value\"`\n}\n\nfunc (c crontabSchedule) scheduleType() checkInScheduleType {\n\treturn checkInScheduleTypeCrontab\n}\n\n// CrontabSchedule defines the MonitorSchedule with a cron format.\n// Example: \"8 * * * *\".\nfunc CrontabSchedule(scheduleString string) MonitorSchedule {\n\treturn crontabSchedule{\n\t\tType:  string(checkInScheduleTypeCrontab),\n\t\tValue: scheduleString,\n\t}\n}\n\ntype intervalSchedule struct {\n\tType  string `json:\"type\"`\n\tValue int64  `json:\"value\"`\n\tUnit  string `json:\"unit\"`\n}\n\nfunc (i intervalSchedule) scheduleType() checkInScheduleType {\n\treturn checkInScheduleTypeInterval\n}\n\ntype MonitorScheduleUnit string\n\nconst (\n\tMonitorScheduleUnitMinute MonitorScheduleUnit = \"minute\"\n\tMonitorScheduleUnitHour   MonitorScheduleUnit = \"hour\"\n\tMonitorScheduleUnitDay    MonitorScheduleUnit = \"day\"\n\tMonitorScheduleUnitWeek   MonitorScheduleUnit = \"week\"\n\tMonitorScheduleUnitMonth  MonitorScheduleUnit = \"month\"\n\tMonitorScheduleUnitYear   MonitorScheduleUnit = \"year\"\n)\n\n// IntervalSchedule defines the MonitorSchedule with an interval format.\n//\n// Example:\n//\n//\tIntervalSchedule(1, sentry.MonitorScheduleUnitDay)\nfunc IntervalSchedule(value int64, unit MonitorScheduleUnit) MonitorSchedule {\n\treturn intervalSchedule{\n\t\tType:  string(checkInScheduleTypeInterval),\n\t\tValue: value,\n\t\tUnit:  string(unit),\n\t}\n}\n\ntype MonitorConfig struct { //nolint: maligned // prefer readability over optimal memory layout\n\tSchedule MonitorSchedule `json:\"schedule,omitempty\"`\n\t// The allowed margin of minutes after the expected check-in time that\n\t// the monitor will not be considered missed for.\n\tCheckInMargin int64 `json:\"checkin_margin,omitempty\"`\n\t// The allowed duration in minutes that the monitor may be `in_progress`\n\t// for before being considered failed due to timeout.\n\tMaxRuntime int64 `json:\"max_runtime,omitempty\"`\n\t// A tz database string representing the timezone which the monitor's execution schedule is in.\n\t// See: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones\n\tTimezone string `json:\"timezone,omitempty\"`\n\t// The number of consecutive failed check-ins it takes before an issue is created.\n\tFailureIssueThreshold int64 `json:\"failure_issue_threshold,omitempty\"`\n\t// The number of consecutive OK check-ins it takes before an issue is resolved.\n\tRecoveryThreshold int64 `json:\"recovery_threshold,omitempty\"`\n}\n\ntype CheckIn struct { //nolint: maligned // prefer readability over optimal memory layout\n\t// Check-In ID (unique and client generated)\n\tID EventID `json:\"check_in_id\"`\n\t// The distinct slug of the monitor.\n\tMonitorSlug string `json:\"monitor_slug\"`\n\t// The status of the check-in.\n\tStatus CheckInStatus `json:\"status\"`\n\t// The duration of the check-in. Will only take effect if the status is ok or error.\n\tDuration time.Duration `json:\"duration,omitempty\"`\n}\n\n// serializedCheckIn is used by checkInMarshalJSON method on Event struct.\n// See https://develop.sentry.dev/sdk/check-ins/\ntype serializedCheckIn struct { //nolint: maligned\n\t// Check-In ID (unique and client generated).\n\tCheckInID string `json:\"check_in_id\"`\n\t// The distinct slug of the monitor.\n\tMonitorSlug string `json:\"monitor_slug\"`\n\t// The status of the check-in.\n\tStatus CheckInStatus `json:\"status\"`\n\t// The duration of the check-in in seconds. Will only take effect if the status is ok or error.\n\tDuration      float64        `json:\"duration,omitempty\"`\n\tRelease       string         `json:\"release,omitempty\"`\n\tEnvironment   string         `json:\"environment,omitempty\"`\n\tMonitorConfig *MonitorConfig `json:\"monitor_config,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/client.go",
    "content": "package sentry\n\nimport (\n\t\"context\"\n\t\"crypto/x509\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"os\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go/internal/debug\"\n\t\"github.com/getsentry/sentry-go/internal/debuglog\"\n\thttpInternal \"github.com/getsentry/sentry-go/internal/http\"\n\t\"github.com/getsentry/sentry-go/internal/protocol\"\n\t\"github.com/getsentry/sentry-go/internal/ratelimit\"\n\t\"github.com/getsentry/sentry-go/internal/telemetry\"\n)\n\n// The identifier of the SDK.\nconst sdkIdentifier = \"sentry.go\"\n\nconst (\n\t// maxErrorDepth is the maximum number of errors reported in a chain of errors.\n\t// This protects the SDK from an arbitrarily long chain of wrapped errors.\n\t//\n\t// An additional consideration is that arguably reporting a long chain of errors\n\t// is of little use when debugging production errors with Sentry. The Sentry UI\n\t// is not optimized for long chains either. The top-level error together with a\n\t// stack trace is often the most useful information.\n\tmaxErrorDepth = 100\n\n\t// defaultMaxSpans limits the default number of recorded spans per transaction. The limit is\n\t// meant to bound memory usage and prevent too large transaction events that\n\t// would be rejected by Sentry.\n\tdefaultMaxSpans = 1000\n\n\t// defaultMaxBreadcrumbs is the default maximum number of breadcrumbs added to\n\t// an event. Can be overwritten with the MaxBreadcrumbs option.\n\tdefaultMaxBreadcrumbs = 100\n)\n\n// hostname is the host name reported by the kernel. It is precomputed once to\n// avoid syscalls when capturing events.\n//\n// The error is ignored because retrieving the host name is best-effort. If the\n// error is non-nil, there is nothing to do other than retrying. We choose not\n// to retry for now.\nvar hostname, _ = os.Hostname()\n\n// lockedRand is a random number generator safe for concurrent use. Its API is\n// intentionally limited and it is not meant as a full replacement for a\n// rand.Rand.\ntype lockedRand struct {\n\tmu sync.Mutex\n\tr  *rand.Rand\n}\n\n// Float64 returns a pseudo-random number in [0.0,1.0).\nfunc (r *lockedRand) Float64() float64 {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\treturn r.r.Float64()\n}\n\n// rng is the internal random number generator.\n//\n// We do not use the global functions from math/rand because, while they are\n// safe for concurrent use, any package in a build could change the seed and\n// affect the generated numbers, for instance making them deterministic. On the\n// other hand, the source returned from rand.NewSource is not safe for\n// concurrent use, so we need to couple its use with a sync.Mutex.\nvar rng = &lockedRand{\n\t// #nosec G404 -- We are fine using transparent, non-secure value here.\n\tr: rand.New(rand.NewSource(time.Now().UnixNano())),\n}\n\n// usageError is used to report to Sentry an SDK usage error.\n//\n// It is not exported because it is never returned by any function or method in\n// the exported API.\ntype usageError struct {\n\terror\n}\n\n// DebugLogger is an instance of log.Logger that is used to provide debug information about running Sentry Client\n// can be enabled by either using debuglog.SetOutput directly or with Debug client option.\nvar DebugLogger = debuglog.GetLogger()\n\n// EventProcessor is a function that processes an event.\n// Event processors are used to change an event before it is sent to Sentry.\ntype EventProcessor func(event *Event, hint *EventHint) *Event\n\n// EventModifier is the interface that wraps the ApplyToEvent method.\n//\n// ApplyToEvent changes an event based on external data and/or\n// an event hint.\ntype EventModifier interface {\n\tApplyToEvent(event *Event, hint *EventHint, client *Client) *Event\n}\n\nvar globalEventProcessors []EventProcessor\n\n// AddGlobalEventProcessor adds processor to the global list of event\n// processors. Global event processors apply to all events.\n//\n// AddGlobalEventProcessor is deprecated. Most users will prefer to initialize\n// the SDK with Init and provide a ClientOptions.BeforeSend function or use\n// Scope.AddEventProcessor instead.\nfunc AddGlobalEventProcessor(processor EventProcessor) {\n\tglobalEventProcessors = append(globalEventProcessors, processor)\n}\n\n// Integration allows for registering a functions that modify or discard captured events.\ntype Integration interface {\n\tName() string\n\tSetupOnce(client *Client)\n}\n\n// ClientOptions that configures a SDK Client.\ntype ClientOptions struct {\n\t// The DSN to use. If the DSN is not set, the client is effectively\n\t// disabled.\n\tDsn string\n\t// In debug mode, the debug information is printed to stdout to help you\n\t// understand what sentry is doing.\n\tDebug bool\n\t// Configures whether SDK should generate and attach stacktraces to pure\n\t// capture message calls.\n\tAttachStacktrace bool\n\t// The sample rate for event submission in the range [0.0, 1.0]. By default,\n\t// all events are sent. Thus, as a historical special case, the sample rate\n\t// 0.0 is treated as if it was 1.0. To drop all events, set the DSN to the\n\t// empty string.\n\tSampleRate float64\n\t// Enable performance tracing.\n\tEnableTracing bool\n\t// The sample rate for sampling traces in the range [0.0, 1.0].\n\tTracesSampleRate float64\n\t// Used to customize the sampling of traces, overrides TracesSampleRate.\n\tTracesSampler TracesSampler\n\t// Control with URLs trace propagation should be enabled. Does not support regex patterns.\n\tTracePropagationTargets []string\n\t// PropagateTraceparent is used to control whether the W3C Trace Context HTTP traceparent header\n\t// is propagated on outgoing http requests.\n\tPropagateTraceparent bool\n\t// List of regexp strings that will be used to match against event's message\n\t// and if applicable, caught errors type and value.\n\t// If the match is found, then a whole event will be dropped.\n\tIgnoreErrors []string\n\t// List of regexp strings that will be used to match against a transaction's\n\t// name.  If a match is found, then the transaction  will be dropped.\n\tIgnoreTransactions []string\n\t// If this flag is enabled, certain personally identifiable information (PII) is added by active integrations.\n\t// By default, no such data is sent.\n\tSendDefaultPII bool\n\t// BeforeSend is called before error events are sent to Sentry.\n\t// You can use it to mutate the event or return nil to discard it.\n\tBeforeSend func(event *Event, hint *EventHint) *Event\n\t// BeforeSendLong is called before log events are sent to Sentry.\n\t// You can use it to mutate the log event or return nil to discard it.\n\tBeforeSendLog func(event *Log) *Log\n\t// BeforeSendTransaction is called before transaction events are sent to Sentry.\n\t// Use it to mutate the transaction or return nil to discard the transaction.\n\tBeforeSendTransaction func(event *Event, hint *EventHint) *Event\n\t// Before breadcrumb add callback.\n\tBeforeBreadcrumb func(breadcrumb *Breadcrumb, hint *BreadcrumbHint) *Breadcrumb\n\t// BeforeSendMetric is called before metric events are sent to Sentry.\n\t// You can use it to mutate the metric or return nil to discard it.\n\tBeforeSendMetric func(metric *Metric) *Metric\n\t// Integrations to be installed on the current Client, receives default\n\t// integrations.\n\tIntegrations func([]Integration) []Integration\n\t// io.Writer implementation that should be used with the Debug mode.\n\tDebugWriter io.Writer\n\t// The transport to use. Defaults to HTTPTransport.\n\tTransport Transport\n\t// The server name to be reported.\n\tServerName string\n\t// The release to be sent with events.\n\t//\n\t// Some Sentry features are built around releases, and, thus, reporting\n\t// events with a non-empty release improves the product experience. See\n\t// https://docs.sentry.io/product/releases/.\n\t//\n\t// If Release is not set, the SDK will try to derive a default value\n\t// from environment variables or the Git repository in the working\n\t// directory.\n\t//\n\t// If you distribute a compiled binary, it is recommended to set the\n\t// Release value explicitly at build time. As an example, you can use:\n\t//\n\t// \tgo build -ldflags='-X main.release=VALUE'\n\t//\n\t// That will set the value of a predeclared variable 'release' in the\n\t// 'main' package to 'VALUE'. Then, use that variable when initializing\n\t// the SDK:\n\t//\n\t// \tsentry.Init(ClientOptions{Release: release})\n\t//\n\t// See https://golang.org/cmd/go/ and https://golang.org/cmd/link/ for\n\t// the official documentation of -ldflags and -X, respectively.\n\tRelease string\n\t// The dist to be sent with events.\n\tDist string\n\t// The environment to be sent with events.\n\tEnvironment string\n\t// Maximum number of breadcrumbs\n\t// when MaxBreadcrumbs is negative then ignore breadcrumbs.\n\tMaxBreadcrumbs int\n\t// Maximum number of spans.\n\t//\n\t// See https://develop.sentry.dev/sdk/envelopes/#size-limits for size limits\n\t// applied during event ingestion. Events that exceed these limits might get dropped.\n\tMaxSpans int\n\t// An optional pointer to http.Client that will be used with a default\n\t// HTTPTransport. Using your own client will make HTTPTransport, HTTPProxy,\n\t// HTTPSProxy and CaCerts options ignored.\n\tHTTPClient *http.Client\n\t// An optional pointer to http.Transport that will be used with a default\n\t// HTTPTransport. Using your own transport will make HTTPProxy, HTTPSProxy\n\t// and CaCerts options ignored.\n\tHTTPTransport http.RoundTripper\n\t// An optional HTTP proxy to use.\n\t// This will default to the HTTP_PROXY environment variable.\n\tHTTPProxy string\n\t// An optional HTTPS proxy to use.\n\t// This will default to the HTTPS_PROXY environment variable.\n\t// HTTPS_PROXY takes precedence over HTTP_PROXY for https requests.\n\tHTTPSProxy string\n\t// An optional set of SSL certificates to use.\n\tCaCerts *x509.CertPool\n\t// MaxErrorDepth is the maximum number of errors reported in a chain of errors.\n\t// This protects the SDK from an arbitrarily long chain of wrapped errors.\n\t//\n\t// An additional consideration is that arguably reporting a long chain of errors\n\t// is of little use when debugging production errors with Sentry. The Sentry UI\n\t// is not optimized for long chains either. The top-level error together with a\n\t// stack trace is often the most useful information.\n\tMaxErrorDepth int\n\t// Default event tags. These are overridden by tags set on a scope.\n\tTags map[string]string\n\t// EnableLogs controls when logs should be emitted.\n\tEnableLogs bool\n\t// DisableMetrics controls when metrics should be emitted.\n\tDisableMetrics bool\n\t// TraceIgnoreStatusCodes is a list of HTTP status codes that should not be traced.\n\t// Each element can be either:\n\t// - A single-element slice [code] for a specific status code\n\t// - A two-element slice [min, max] for a range of status codes (inclusive)\n\t// When an HTTP request results in a status code that matches any of these codes or ranges,\n\t// the transaction will not be sent to Sentry.\n\t//\n\t// Examples:\n\t//   [][]int{{404}}                           // ignore only status code 404\n\t//   [][]int{{400, 405}}                     // ignore status codes 400-405\n\t//   [][]int{{404}, {500}}                   // ignore status codes 404 and 500\n\t//   [][]int{{404}, {400, 405}, {500, 599}}  // ignore 404, range 400-405, and range 500-599\n\t//\n\t// By default, this ignores 404 status codes.\n\t//\n\t// IMPORTANT: to not ignore any status codes, the option should be an empty slice and not nil. The nil option is\n\t// used for defaulting to 404 ignores.\n\tTraceIgnoreStatusCodes [][]int\n\t// DisableTelemetryBuffer disables the telemetry buffer layer for prioritizing events and uses the old transport layer.\n\tDisableTelemetryBuffer bool\n}\n\n// Client is the underlying processor that is used by the main API and Hub\n// instances. It must be created with NewClient.\ntype Client struct {\n\tmu              sync.RWMutex\n\toptions         ClientOptions\n\tdsn             *Dsn\n\teventProcessors []EventProcessor\n\tintegrations    []Integration\n\tsdkIdentifier   string\n\tsdkVersion      string\n\t// Transport is read-only. Replacing the transport of an existing client is\n\t// not supported, create a new client instead.\n\tTransport          Transport\n\tbatchLogger        *logBatchProcessor\n\tbatchMeter         *metricBatchProcessor\n\ttelemetryProcessor *telemetry.Processor\n}\n\n// NewClient creates and returns an instance of Client configured using\n// ClientOptions.\n//\n// Most users will not create clients directly. Instead, initialize the SDK with\n// Init and use the package-level functions (for simple programs that run on a\n// single goroutine) or hub methods (for concurrent programs, for example web\n// servers).\nfunc NewClient(options ClientOptions) (*Client, error) {\n\t// The default error event sample rate for all SDKs is 1.0 (send all).\n\t//\n\t// In Go, the zero value (default) for float64 is 0.0, which means that\n\t// constructing a client with NewClient(ClientOptions{}), or, equivalently,\n\t// initializing the SDK with Init(ClientOptions{}) without an explicit\n\t// SampleRate would drop all events.\n\t//\n\t// To retain the desired default behavior, we exceptionally flip SampleRate\n\t// from 0.0 to 1.0 here. Setting the sample rate to 0.0 is not very useful\n\t// anyway, and the same end result can be achieved in many other ways like\n\t// not initializing the SDK, setting the DSN to the empty string or using an\n\t// event processor that always returns nil.\n\t//\n\t// An alternative API could be such that default options don't need to be\n\t// the same as Go's zero values, for example using the Functional Options\n\t// pattern. That would either require a breaking change if we want to reuse\n\t// the obvious NewClient name, or a new function as an alternative\n\t// constructor.\n\tif options.SampleRate == 0.0 {\n\t\toptions.SampleRate = 1.0\n\t}\n\n\tif options.Debug {\n\t\tdebugWriter := options.DebugWriter\n\t\tif debugWriter == nil {\n\t\t\tdebugWriter = os.Stderr\n\t\t}\n\t\tdebuglog.SetOutput(debugWriter)\n\t}\n\n\tif options.Dsn == \"\" {\n\t\toptions.Dsn = os.Getenv(\"SENTRY_DSN\")\n\t}\n\n\tif options.Release == \"\" {\n\t\toptions.Release = defaultRelease()\n\t}\n\n\tif options.Environment == \"\" {\n\t\toptions.Environment = os.Getenv(\"SENTRY_ENVIRONMENT\")\n\t}\n\n\tif options.MaxErrorDepth == 0 {\n\t\toptions.MaxErrorDepth = maxErrorDepth\n\t}\n\n\tif options.MaxSpans == 0 {\n\t\toptions.MaxSpans = defaultMaxSpans\n\t}\n\n\tif options.TraceIgnoreStatusCodes == nil {\n\t\toptions.TraceIgnoreStatusCodes = [][]int{{404}}\n\t}\n\n\t// SENTRYGODEBUG is a comma-separated list of key=value pairs (similar\n\t// to GODEBUG). It is not a supported feature: recognized debug options\n\t// may change any time.\n\t//\n\t// The intended public is SDK developers. It is orthogonal to\n\t// options.Debug, which is also available for SDK users.\n\tdbg := strings.Split(os.Getenv(\"SENTRYGODEBUG\"), \",\")\n\tsort.Strings(dbg)\n\t// dbgOpt returns true when the given debug option is enabled, for\n\t// example SENTRYGODEBUG=someopt=1.\n\tdbgOpt := func(opt string) bool {\n\t\ts := opt + \"=1\"\n\t\treturn dbg[sort.SearchStrings(dbg, s)%len(dbg)] == s\n\t}\n\tif dbgOpt(\"httpdump\") || dbgOpt(\"httptrace\") {\n\t\toptions.HTTPTransport = &debug.Transport{\n\t\t\tRoundTripper: http.DefaultTransport,\n\t\t\tOutput:       os.Stderr,\n\t\t\tDump:         dbgOpt(\"httpdump\"),\n\t\t\tTrace:        dbgOpt(\"httptrace\"),\n\t\t}\n\t}\n\n\tvar dsn *Dsn\n\tif options.Dsn != \"\" {\n\t\tvar err error\n\t\tdsn, err = NewDsn(options.Dsn)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tclient := Client{\n\t\toptions:       options,\n\t\tdsn:           dsn,\n\t\tsdkIdentifier: sdkIdentifier,\n\t\tsdkVersion:    SDKVersion,\n\t}\n\n\tclient.setupTransport()\n\n\t// noop Telemetry Buffers and Processor fow now\n\t// if !options.DisableTelemetryBuffer {\n\t// \tclient.setupTelemetryProcessor()\n\t// } else\n\tif options.EnableLogs {\n\t\tclient.batchLogger = newLogBatchProcessor(&client)\n\t\tclient.batchLogger.Start()\n\t}\n\n\tif !options.DisableMetrics {\n\t\tclient.batchMeter = newMetricBatchProcessor(&client)\n\t\tclient.batchMeter.Start()\n\t}\n\n\tclient.setupIntegrations()\n\n\treturn &client, nil\n}\n\nfunc (client *Client) setupTransport() {\n\topts := client.options\n\ttransport := opts.Transport\n\n\tif transport == nil {\n\t\tif opts.Dsn == \"\" {\n\t\t\ttransport = new(noopTransport)\n\t\t} else {\n\t\t\ttransport = NewHTTPTransport()\n\t\t}\n\t}\n\n\ttransport.Configure(opts)\n\tclient.Transport = transport\n}\n\nfunc (client *Client) setupTelemetryProcessor() { // nolint: unused\n\tif client.options.DisableTelemetryBuffer {\n\t\treturn\n\t}\n\n\tif client.dsn == nil {\n\t\tdebuglog.Println(\"Telemetry buffer disabled: no DSN configured\")\n\t\treturn\n\t}\n\n\t// We currently disallow using custom Transport with the new Telemetry Processor, due to the difference in transport signatures.\n\t// The option should be enabled when the new Transport interface signature changes.\n\tif client.options.Transport != nil {\n\t\tdebuglog.Println(\"Cannot enable Telemetry Processor/Buffers with custom Transport: fallback to old transport\")\n\t\tif client.options.EnableLogs {\n\t\t\tclient.batchLogger = newLogBatchProcessor(client)\n\t\t\tclient.batchLogger.Start()\n\t\t}\n\t\tif !client.options.DisableMetrics {\n\t\t\tclient.batchMeter = newMetricBatchProcessor(client)\n\t\t\tclient.batchMeter.Start()\n\t\t}\n\t\treturn\n\t}\n\n\ttransport := httpInternal.NewAsyncTransport(httpInternal.TransportOptions{\n\t\tDsn:           client.options.Dsn,\n\t\tHTTPClient:    client.options.HTTPClient,\n\t\tHTTPTransport: client.options.HTTPTransport,\n\t\tHTTPProxy:     client.options.HTTPProxy,\n\t\tHTTPSProxy:    client.options.HTTPSProxy,\n\t\tCaCerts:       client.options.CaCerts,\n\t})\n\tclient.Transport = &internalAsyncTransportAdapter{transport: transport}\n\n\tbuffers := map[ratelimit.Category]telemetry.Buffer[protocol.TelemetryItem]{\n\t\tratelimit.CategoryError:       telemetry.NewRingBuffer[protocol.TelemetryItem](ratelimit.CategoryError, 100, telemetry.OverflowPolicyDropOldest, 1, 0),\n\t\tratelimit.CategoryTransaction: telemetry.NewRingBuffer[protocol.TelemetryItem](ratelimit.CategoryTransaction, 1000, telemetry.OverflowPolicyDropOldest, 1, 0),\n\t\tratelimit.CategoryLog:         telemetry.NewRingBuffer[protocol.TelemetryItem](ratelimit.CategoryLog, 10*100, telemetry.OverflowPolicyDropOldest, 100, 5*time.Second),\n\t\tratelimit.CategoryMonitor:     telemetry.NewRingBuffer[protocol.TelemetryItem](ratelimit.CategoryMonitor, 100, telemetry.OverflowPolicyDropOldest, 1, 0),\n\t\tratelimit.CategoryTraceMetric: telemetry.NewRingBuffer[protocol.TelemetryItem](ratelimit.CategoryTraceMetric, 10*100, telemetry.OverflowPolicyDropOldest, 100, 5*time.Second),\n\t}\n\n\tsdkInfo := &protocol.SdkInfo{\n\t\tName:    client.sdkIdentifier,\n\t\tVersion: client.sdkVersion,\n\t}\n\n\tclient.telemetryProcessor = telemetry.NewProcessor(buffers, transport, &client.dsn.Dsn, sdkInfo)\n}\n\nfunc (client *Client) setupIntegrations() {\n\tintegrations := []Integration{\n\t\tnew(contextifyFramesIntegration),\n\t\tnew(environmentIntegration),\n\t\tnew(modulesIntegration),\n\t\tnew(ignoreErrorsIntegration),\n\t\tnew(ignoreTransactionsIntegration),\n\t\tnew(globalTagsIntegration),\n\t}\n\n\tif client.options.Integrations != nil {\n\t\tintegrations = client.options.Integrations(integrations)\n\t}\n\n\tfor _, integration := range integrations {\n\t\tif client.integrationAlreadyInstalled(integration.Name()) {\n\t\t\tdebuglog.Printf(\"Integration %s is already installed\\n\", integration.Name())\n\t\t\tcontinue\n\t\t}\n\t\tclient.integrations = append(client.integrations, integration)\n\t\tintegration.SetupOnce(client)\n\t\tdebuglog.Printf(\"Integration installed: %s\\n\", integration.Name())\n\t}\n\n\tsort.Slice(client.integrations, func(i, j int) bool {\n\t\treturn client.integrations[i].Name() < client.integrations[j].Name()\n\t})\n}\n\n// AddEventProcessor adds an event processor to the client. It must not be\n// called from concurrent goroutines. Most users will prefer to use\n// ClientOptions.BeforeSend or Scope.AddEventProcessor instead.\n//\n// Note that typical programs have only a single client created by Init and the\n// client is shared among multiple hubs, one per goroutine, such that adding an\n// event processor to the client affects all hubs that share the client.\nfunc (client *Client) AddEventProcessor(processor EventProcessor) {\n\tclient.eventProcessors = append(client.eventProcessors, processor)\n}\n\n// Options return ClientOptions for the current Client.\nfunc (client *Client) Options() ClientOptions {\n\t// Note: internally, consider using `client.options` instead of `client.Options()` to avoid copying the object each time.\n\treturn client.options\n}\n\n// CaptureMessage captures an arbitrary message.\nfunc (client *Client) CaptureMessage(message string, hint *EventHint, scope EventModifier) *EventID {\n\tevent := client.EventFromMessage(message, LevelInfo)\n\treturn client.CaptureEvent(event, hint, scope)\n}\n\n// CaptureException captures an error.\nfunc (client *Client) CaptureException(exception error, hint *EventHint, scope EventModifier) *EventID {\n\tevent := client.EventFromException(exception, LevelError)\n\treturn client.CaptureEvent(event, hint, scope)\n}\n\n// CaptureCheckIn captures a check in.\nfunc (client *Client) CaptureCheckIn(checkIn *CheckIn, monitorConfig *MonitorConfig, scope EventModifier) *EventID {\n\tevent := client.EventFromCheckIn(checkIn, monitorConfig)\n\tif event != nil && event.CheckIn != nil {\n\t\tclient.CaptureEvent(event, nil, scope)\n\t\treturn &event.CheckIn.ID\n\t}\n\treturn nil\n}\n\n// CaptureEvent captures an event on the currently active client if any.\n//\n// The event must already be assembled. Typically, code would instead use\n// the utility methods like CaptureException. The return value is the\n// event ID. In case Sentry is disabled or event was dropped, the return value will be nil.\nfunc (client *Client) CaptureEvent(event *Event, hint *EventHint, scope EventModifier) *EventID {\n\treturn client.processEvent(event, hint, scope)\n}\n\nfunc (client *Client) captureLog(log *Log, _ *Scope) bool {\n\tif log == nil {\n\t\treturn false\n\t}\n\n\tif client.options.BeforeSendLog != nil {\n\t\tlog = client.options.BeforeSendLog(log)\n\t\tif log == nil {\n\t\t\tdebuglog.Println(\"Log dropped due to BeforeSendLog callback.\")\n\t\t\treturn false\n\t\t}\n\t}\n\n\tif client.telemetryProcessor != nil {\n\t\tif !client.telemetryProcessor.Add(log) {\n\t\t\tdebuglog.Print(\"Dropping log: telemetry buffer full or category missing\")\n\t\t\treturn false\n\t\t}\n\t} else if client.batchLogger != nil {\n\t\tif !client.batchLogger.Send(log) {\n\t\t\tdebuglog.Printf(\"Dropping log [%s]: buffer full\", log.Level)\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc (client *Client) captureMetric(metric *Metric, _ *Scope) bool {\n\tif metric == nil {\n\t\treturn false\n\t}\n\n\tif client.options.BeforeSendMetric != nil {\n\t\tmetric = client.options.BeforeSendMetric(metric)\n\t\tif metric == nil {\n\t\t\tdebuglog.Println(\"Metric dropped due to BeforeSendMetric callback.\")\n\t\t\treturn false\n\t\t}\n\t}\n\n\tif client.telemetryProcessor != nil {\n\t\tif !client.telemetryProcessor.Add(metric) {\n\t\t\tdebuglog.Printf(\"Dropping metric: telemetry buffer full or category missing\")\n\t\t\treturn false\n\t\t}\n\t} else if client.batchMeter != nil {\n\t\tif !client.batchMeter.Send(metric) {\n\t\t\tdebuglog.Printf(\"Dropping metric %q: buffer full\", metric.Name)\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\n// Recover captures a panic.\n// Returns EventID if successfully, or nil if there's no error to recover from.\nfunc (client *Client) Recover(err interface{}, hint *EventHint, scope EventModifier) *EventID {\n\tif err == nil {\n\t\terr = recover()\n\t}\n\n\t// Normally we would not pass a nil Context, but RecoverWithContext doesn't\n\t// use the Context for communicating deadline nor cancelation. All it does\n\t// is store the Context in the EventHint and there nil means the Context is\n\t// not available.\n\t// nolint: staticcheck\n\treturn client.RecoverWithContext(nil, err, hint, scope)\n}\n\n// RecoverWithContext captures a panic and passes relevant context object.\n// Returns EventID if successfully, or nil if there's no error to recover from.\nfunc (client *Client) RecoverWithContext(\n\tctx context.Context,\n\terr interface{},\n\thint *EventHint,\n\tscope EventModifier,\n) *EventID {\n\tif err == nil {\n\t\terr = recover()\n\t}\n\tif err == nil {\n\t\treturn nil\n\t}\n\n\tif ctx != nil {\n\t\tif hint == nil {\n\t\t\thint = &EventHint{}\n\t\t}\n\t\tif hint.Context == nil {\n\t\t\thint.Context = ctx\n\t\t}\n\t}\n\n\tvar event *Event\n\tswitch err := err.(type) {\n\tcase error:\n\t\tevent = client.EventFromException(err, LevelFatal)\n\tcase string:\n\t\tevent = client.EventFromMessage(err, LevelFatal)\n\tdefault:\n\t\tevent = client.EventFromMessage(fmt.Sprintf(\"%#v\", err), LevelFatal)\n\t}\n\treturn client.CaptureEvent(event, hint, scope)\n}\n\n// Flush waits until the underlying Transport sends any buffered events to the\n// Sentry server, blocking for at most the given timeout. It returns false if\n// the timeout was reached. In that case, some events may not have been sent.\n//\n// Flush should be called before terminating the program to avoid\n// unintentionally dropping events.\n//\n// Do not call Flush indiscriminately after every call to CaptureEvent,\n// CaptureException or CaptureMessage. Instead, to have the SDK send events over\n// the network synchronously, configure it to use the HTTPSyncTransport in the\n// call to Init.\nfunc (client *Client) Flush(timeout time.Duration) bool {\n\tif client.batchLogger != nil || client.batchMeter != nil || client.telemetryProcessor != nil {\n\t\tctx, cancel := context.WithTimeout(context.Background(), timeout)\n\t\tdefer cancel()\n\t\treturn client.FlushWithContext(ctx)\n\t}\n\treturn client.Transport.Flush(timeout)\n}\n\n// FlushWithContext waits until the underlying Transport sends any buffered events\n// to the Sentry server, blocking for at most the duration specified by the context.\n// It returns false if the context is canceled before the events are sent. In such a case,\n// some events may not be delivered.\n//\n// FlushWithContext should be called before terminating the program to ensure no\n// events are unintentionally dropped.\n//\n// Avoid calling FlushWithContext indiscriminately after each call to CaptureEvent,\n// CaptureException, or CaptureMessage. To send events synchronously over the network,\n// configure the SDK to use HTTPSyncTransport during initialization with Init.\n\nfunc (client *Client) FlushWithContext(ctx context.Context) bool {\n\tif client.batchLogger != nil {\n\t\tclient.batchLogger.Flush(ctx.Done())\n\t}\n\tif client.batchMeter != nil {\n\t\tclient.batchMeter.Flush(ctx.Done())\n\t}\n\tif client.telemetryProcessor != nil {\n\t\treturn client.telemetryProcessor.FlushWithContext(ctx)\n\t}\n\treturn client.Transport.FlushWithContext(ctx)\n}\n\n// Close clean up underlying Transport resources.\n//\n// Close should be called after Flush and before terminating the program\n// otherwise some events may be lost.\nfunc (client *Client) Close() {\n\tif client.telemetryProcessor != nil {\n\t\tclient.telemetryProcessor.Close(5 * time.Second)\n\t}\n\tif client.batchLogger != nil {\n\t\tclient.batchLogger.Shutdown()\n\t}\n\tif client.batchMeter != nil {\n\t\tclient.batchMeter.Shutdown()\n\t}\n\tclient.Transport.Close()\n}\n\n// EventFromMessage creates an event from the given message string.\nfunc (client *Client) EventFromMessage(message string, level Level) *Event {\n\tif message == \"\" {\n\t\terr := usageError{fmt.Errorf(\"%s called with empty message\", callerFunctionName())}\n\t\treturn client.EventFromException(err, level)\n\t}\n\tevent := NewEvent()\n\tevent.Level = level\n\tevent.Message = message\n\n\tif client.options.AttachStacktrace {\n\t\tevent.Threads = []Thread{{\n\t\t\tStacktrace: NewStacktrace(),\n\t\t\tCrashed:    false,\n\t\t\tCurrent:    true,\n\t\t}}\n\t}\n\n\treturn event\n}\n\n// EventFromException creates a new Sentry event from the given `error` instance.\nfunc (client *Client) EventFromException(exception error, level Level) *Event {\n\tevent := NewEvent()\n\tevent.Level = level\n\n\terr := exception\n\tif err == nil {\n\t\terr = usageError{fmt.Errorf(\"%s called with nil error\", callerFunctionName())}\n\t}\n\n\tevent.SetException(err, client.options.MaxErrorDepth)\n\n\treturn event\n}\n\n// EventFromCheckIn creates a new Sentry event from the given `check_in` instance.\nfunc (client *Client) EventFromCheckIn(checkIn *CheckIn, monitorConfig *MonitorConfig) *Event {\n\tif checkIn == nil {\n\t\treturn nil\n\t}\n\n\tevent := NewEvent()\n\tevent.Type = checkInType\n\n\tvar checkInID EventID\n\tif checkIn.ID == \"\" {\n\t\tcheckInID = EventID(uuid())\n\t} else {\n\t\tcheckInID = checkIn.ID\n\t}\n\n\tevent.CheckIn = &CheckIn{\n\t\tID:          checkInID,\n\t\tMonitorSlug: checkIn.MonitorSlug,\n\t\tStatus:      checkIn.Status,\n\t\tDuration:    checkIn.Duration,\n\t}\n\tevent.MonitorConfig = monitorConfig\n\n\treturn event\n}\n\nfunc (client *Client) SetSDKIdentifier(identifier string) {\n\tclient.mu.Lock()\n\tdefer client.mu.Unlock()\n\n\tclient.sdkIdentifier = identifier\n}\n\nfunc (client *Client) GetSDKIdentifier() string {\n\tclient.mu.RLock()\n\tdefer client.mu.RUnlock()\n\n\treturn client.sdkIdentifier\n}\n\nfunc (client *Client) processEvent(event *Event, hint *EventHint, scope EventModifier) *EventID {\n\tif event == nil {\n\t\terr := usageError{fmt.Errorf(\"%s called with nil event\", callerFunctionName())}\n\t\treturn client.CaptureException(err, hint, scope)\n\t}\n\n\t// Transactions are sampled by options.TracesSampleRate or\n\t// options.TracesSampler when they are started. Other events\n\t// (errors, messages) are sampled here. Does not apply to check-ins.\n\tif event.Type != transactionType && event.Type != checkInType && !sample(client.options.SampleRate) {\n\t\tdebuglog.Println(\"Event dropped due to SampleRate hit.\")\n\t\treturn nil\n\t}\n\n\tif event = client.prepareEvent(event, hint, scope); event == nil {\n\t\treturn nil\n\t}\n\n\t// Apply beforeSend* processors\n\tif hint == nil {\n\t\thint = &EventHint{}\n\t}\n\tswitch event.Type {\n\tcase transactionType:\n\t\tif client.options.BeforeSendTransaction != nil {\n\t\t\tif event = client.options.BeforeSendTransaction(event, hint); event == nil {\n\t\t\t\tdebuglog.Println(\"Transaction dropped due to BeforeSendTransaction callback.\")\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\tcase checkInType: // not a default case, since we shouldn't apply BeforeSend on check-in events\n\tdefault:\n\t\tif client.options.BeforeSend != nil {\n\t\t\tif event = client.options.BeforeSend(event, hint); event == nil {\n\t\t\t\tdebuglog.Println(\"Event dropped due to BeforeSend callback.\")\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\n\tif client.telemetryProcessor != nil {\n\t\tif !client.telemetryProcessor.Add(event) {\n\t\t\tdebuglog.Println(\"Event dropped: telemetry buffer full or unavailable\")\n\t\t}\n\t} else {\n\t\tclient.Transport.SendEvent(event)\n\t}\n\n\treturn &event.EventID\n}\n\nfunc (client *Client) prepareEvent(event *Event, hint *EventHint, scope EventModifier) *Event {\n\tif event.EventID == \"\" {\n\t\t// TODO set EventID when the event is created, same as in other SDKs. It's necessary for profileTransaction.ID.\n\t\tevent.EventID = EventID(uuid())\n\t}\n\n\tif event.Timestamp.IsZero() {\n\t\tevent.Timestamp = time.Now()\n\t}\n\n\tif event.Level == \"\" {\n\t\tevent.Level = LevelInfo\n\t}\n\n\tif event.ServerName == \"\" {\n\t\tevent.ServerName = client.options.ServerName\n\n\t\tif event.ServerName == \"\" {\n\t\t\tevent.ServerName = hostname\n\t\t}\n\t}\n\n\tif event.Release == \"\" {\n\t\tevent.Release = client.options.Release\n\t}\n\n\tif event.Dist == \"\" {\n\t\tevent.Dist = client.options.Dist\n\t}\n\n\tif event.Environment == \"\" {\n\t\tevent.Environment = client.options.Environment\n\t}\n\n\tevent.Platform = \"go\"\n\tevent.Sdk = SdkInfo{\n\t\tName:         client.GetSDKIdentifier(),\n\t\tVersion:      SDKVersion,\n\t\tIntegrations: client.listIntegrations(),\n\t\tPackages: []SdkPackage{{\n\t\t\tName:    \"sentry-go\",\n\t\t\tVersion: SDKVersion,\n\t\t}},\n\t}\n\n\tif scope != nil {\n\t\tevent = scope.ApplyToEvent(event, hint, client)\n\t\tif event == nil {\n\t\t\treturn nil\n\t\t}\n\t}\n\n\tfor _, processor := range client.eventProcessors {\n\t\tid := event.EventID\n\t\tevent = processor(event, hint)\n\t\tif event == nil {\n\t\t\tdebuglog.Printf(\"Event dropped by one of the Client EventProcessors: %s\\n\", id)\n\t\t\treturn nil\n\t\t}\n\t}\n\n\tfor _, processor := range globalEventProcessors {\n\t\tid := event.EventID\n\t\tevent = processor(event, hint)\n\t\tif event == nil {\n\t\t\tdebuglog.Printf(\"Event dropped by one of the Global EventProcessors: %s\\n\", id)\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn event\n}\n\nfunc (client *Client) listIntegrations() []string {\n\tintegrations := make([]string, len(client.integrations))\n\tfor i, integration := range client.integrations {\n\t\tintegrations[i] = integration.Name()\n\t}\n\treturn integrations\n}\n\nfunc (client *Client) integrationAlreadyInstalled(name string) bool {\n\tfor _, integration := range client.integrations {\n\t\tif integration.Name() == name {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// sample returns true with the given probability, which must be in the range\n// [0.0, 1.0].\nfunc sample(probability float64) bool {\n\treturn rng.Float64() < probability\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/doc.go",
    "content": "/*\nPackage repository: https://github.com/getsentry/sentry-go/\n\nFor more information about Sentry and SDK features, please have a look at the official documentation site: https://docs.sentry.io/platforms/go/\n*/\npackage sentry\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/dsn.go",
    "content": "package sentry\n\nimport (\n\t\"github.com/getsentry/sentry-go/internal/protocol\"\n)\n\n// Re-export protocol types to maintain public API compatibility\n\n// Dsn is used as the remote address source to client transport.\ntype Dsn struct {\n\tprotocol.Dsn\n}\n\n// DsnParseError represents an error that occurs if a Sentry\n// DSN cannot be parsed.\ntype DsnParseError = protocol.DsnParseError\n\n// NewDsn creates a Dsn by parsing rawURL. Most users will never call this\n// function directly. It is provided for use in custom Transport\n// implementations.\nfunc NewDsn(rawURL string) (*Dsn, error) {\n\tprotocolDsn, err := protocol.NewDsn(rawURL)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Dsn{Dsn: *protocolDsn}, nil\n}\n\n// RequestHeaders returns all the necessary headers that have to be used in the transport when sending events\n// to the /store endpoint.\n//\n// Deprecated: This method shall only be used if you want to implement your own transport that sends events to\n// the /store endpoint. If you're using the transport provided by the SDK, all necessary headers to authenticate\n// against the /envelope endpoint are added automatically.\nfunc (dsn Dsn) RequestHeaders() map[string]string {\n\treturn dsn.Dsn.RequestHeaders(SDKVersion)\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/dynamic_sampling_context.go",
    "content": "package sentry\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/getsentry/sentry-go/internal/otel/baggage\"\n)\n\nconst (\n\tsentryPrefix = \"sentry-\"\n)\n\n// DynamicSamplingContext holds information about the current event that can be used to make dynamic sampling decisions.\ntype DynamicSamplingContext struct {\n\tEntries map[string]string\n\tFrozen  bool\n}\n\nfunc DynamicSamplingContextFromHeader(header []byte) (DynamicSamplingContext, error) {\n\tbag, err := baggage.Parse(string(header))\n\tif err != nil {\n\t\treturn DynamicSamplingContext{}, err\n\t}\n\n\tentries := map[string]string{}\n\tfor _, member := range bag.Members() {\n\t\t// We only store baggage members if their key starts with \"sentry-\".\n\t\tif k, v := member.Key(), member.Value(); strings.HasPrefix(k, sentryPrefix) {\n\t\t\tentries[strings.TrimPrefix(k, sentryPrefix)] = v\n\t\t}\n\t}\n\n\treturn DynamicSamplingContext{\n\t\tEntries: entries,\n\t\t// If there's at least one Sentry value, we consider the DSC frozen\n\t\tFrozen: len(entries) > 0,\n\t}, nil\n}\n\nfunc DynamicSamplingContextFromTransaction(span *Span) DynamicSamplingContext {\n\thub := hubFromContext(span.Context())\n\tscope := hub.Scope()\n\tclient := hub.Client()\n\n\tif client == nil || scope == nil {\n\t\treturn DynamicSamplingContext{\n\t\t\tEntries: map[string]string{},\n\t\t\tFrozen:  false,\n\t\t}\n\t}\n\n\tentries := make(map[string]string)\n\n\tif traceID := span.TraceID.String(); traceID != \"\" {\n\t\tentries[\"trace_id\"] = traceID\n\t}\n\tif sampleRate := span.sampleRate; sampleRate != 0 {\n\t\tentries[\"sample_rate\"] = strconv.FormatFloat(sampleRate, 'f', -1, 64)\n\t}\n\n\tif dsn := client.dsn; dsn != nil {\n\t\tif publicKey := dsn.GetPublicKey(); publicKey != \"\" {\n\t\t\tentries[\"public_key\"] = publicKey\n\t\t}\n\t}\n\tif release := client.options.Release; release != \"\" {\n\t\tentries[\"release\"] = release\n\t}\n\tif environment := client.options.Environment; environment != \"\" {\n\t\tentries[\"environment\"] = environment\n\t}\n\n\t// Only include the transaction name if it's of good quality (not empty and not SourceURL)\n\tif span.Source != \"\" && span.Source != SourceURL {\n\t\tif span.IsTransaction() {\n\t\t\tentries[\"transaction\"] = span.Name\n\t\t}\n\t}\n\n\tentries[\"sampled\"] = strconv.FormatBool(span.Sampled.Bool())\n\n\treturn DynamicSamplingContext{Entries: entries, Frozen: true}\n}\n\nfunc (d DynamicSamplingContext) HasEntries() bool {\n\treturn len(d.Entries) > 0\n}\n\nfunc (d DynamicSamplingContext) IsFrozen() bool {\n\treturn d.Frozen\n}\n\nfunc (d DynamicSamplingContext) String() string {\n\tmembers := []baggage.Member{}\n\tfor k, entry := range d.Entries {\n\t\tmember, err := baggage.NewMember(sentryPrefix+k, entry)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tmembers = append(members, member)\n\t}\n\n\tif len(members) == 0 {\n\t\treturn \"\"\n\t}\n\n\tbaggage, err := baggage.New(members...)\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\n\treturn baggage.String()\n}\n\n// Constructs a new DynamicSamplingContext using a scope and client. Accessing\n// fields on the scope are not thread safe, and this function should only be\n// called within scope methods.\nfunc DynamicSamplingContextFromScope(scope *Scope, client *Client) DynamicSamplingContext {\n\tentries := map[string]string{}\n\n\tif client == nil || scope == nil {\n\t\treturn DynamicSamplingContext{\n\t\t\tEntries: entries,\n\t\t\tFrozen:  false,\n\t\t}\n\t}\n\n\tpropagationContext := scope.propagationContext\n\n\tif traceID := propagationContext.TraceID.String(); traceID != \"\" {\n\t\tentries[\"trace_id\"] = traceID\n\t}\n\tif sampleRate := client.options.TracesSampleRate; sampleRate != 0 {\n\t\tentries[\"sample_rate\"] = strconv.FormatFloat(sampleRate, 'f', -1, 64)\n\t}\n\n\tif dsn := client.dsn; dsn != nil {\n\t\tif publicKey := dsn.GetPublicKey(); publicKey != \"\" {\n\t\t\tentries[\"public_key\"] = publicKey\n\t\t}\n\t}\n\tif release := client.options.Release; release != \"\" {\n\t\tentries[\"release\"] = release\n\t}\n\tif environment := client.options.Environment; environment != \"\" {\n\t\tentries[\"environment\"] = environment\n\t}\n\n\treturn DynamicSamplingContext{\n\t\tEntries: entries,\n\t\tFrozen:  true,\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/exception.go",
    "content": "package sentry\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"slices\"\n)\n\nconst (\n\tMechanismTypeGeneric string = \"generic\"\n\tMechanismTypeChained string = \"chained\"\n\tMechanismTypeUnwrap  string = \"unwrap\"\n\tMechanismSourceCause string = \"cause\"\n)\n\ntype visited struct {\n\tptrs map[uintptr]struct{}\n\tmsgs map[string]struct{}\n}\n\nfunc (v *visited) seenError(err error) bool {\n\tt := reflect.ValueOf(err)\n\tif t.Kind() == reflect.Ptr && !t.IsNil() {\n\t\tptr := t.Pointer()\n\t\tif _, ok := v.ptrs[ptr]; ok {\n\t\t\treturn true\n\t\t}\n\t\tv.ptrs[ptr] = struct{}{}\n\t\treturn false\n\t}\n\n\tkey := t.String() + err.Error()\n\tif _, ok := v.msgs[key]; ok {\n\t\treturn true\n\t}\n\tv.msgs[key] = struct{}{}\n\treturn false\n}\n\nfunc convertErrorToExceptions(err error, maxErrorDepth int) []Exception {\n\tvar exceptions []Exception\n\tvis := &visited{\n\t\tptrs: make(map[uintptr]struct{}),\n\t\tmsgs: make(map[string]struct{}),\n\t}\n\tconvertErrorDFS(err, &exceptions, nil, \"\", vis, maxErrorDepth, 0)\n\n\t// mechanism type is used for debugging purposes, but since we can't really distinguish the origin of who invoked\n\t// captureException, we set it to nil if the error is not chained.\n\tif len(exceptions) == 1 {\n\t\texceptions[0].Mechanism = nil\n\t}\n\n\tslices.Reverse(exceptions)\n\n\t// Add a trace of the current stack to the top level(outermost) error in a chain if\n\t// it doesn't have a stack trace yet.\n\t// We only add to the most recent error to avoid duplication and because the\n\t// current stack is most likely unrelated to errors deeper in the chain.\n\tif len(exceptions) > 0 && exceptions[len(exceptions)-1].Stacktrace == nil {\n\t\texceptions[len(exceptions)-1].Stacktrace = NewStacktrace()\n\t}\n\n\treturn exceptions\n}\n\nfunc convertErrorDFS(err error, exceptions *[]Exception, parentID *int, source string, visited *visited, maxErrorDepth int, currentDepth int) {\n\tif err == nil {\n\t\treturn\n\t}\n\n\tif visited.seenError(err) {\n\t\treturn\n\t}\n\n\t_, isExceptionGroup := err.(interface{ Unwrap() []error })\n\n\texception := Exception{\n\t\tValue:      err.Error(),\n\t\tType:       reflect.TypeOf(err).String(),\n\t\tStacktrace: ExtractStacktrace(err),\n\t}\n\n\tcurrentID := len(*exceptions)\n\n\tvar mechanismType string\n\n\tif parentID == nil {\n\t\tmechanismType = MechanismTypeGeneric\n\t\tsource = \"\"\n\t} else {\n\t\tmechanismType = MechanismTypeChained\n\t}\n\n\texception.Mechanism = &Mechanism{\n\t\tType:             mechanismType,\n\t\tExceptionID:      currentID,\n\t\tParentID:         parentID,\n\t\tSource:           source,\n\t\tIsExceptionGroup: isExceptionGroup,\n\t}\n\n\t*exceptions = append(*exceptions, exception)\n\n\tif maxErrorDepth >= 0 && currentDepth >= maxErrorDepth {\n\t\treturn\n\t}\n\n\tswitch v := err.(type) {\n\tcase interface{ Unwrap() []error }:\n\t\tunwrapped := v.Unwrap()\n\t\tfor i := range unwrapped {\n\t\t\tif unwrapped[i] != nil {\n\t\t\t\tchildSource := fmt.Sprintf(\"errors[%d]\", i)\n\t\t\t\tconvertErrorDFS(unwrapped[i], exceptions, &currentID, childSource, visited, maxErrorDepth, currentDepth+1)\n\t\t\t}\n\t\t}\n\tcase interface{ Unwrap() error }:\n\t\tunwrapped := v.Unwrap()\n\t\tif unwrapped != nil {\n\t\t\tconvertErrorDFS(unwrapped, exceptions, &currentID, MechanismTypeUnwrap, visited, maxErrorDepth, currentDepth+1)\n\t\t}\n\tcase interface{ Cause() error }:\n\t\tcause := v.Cause()\n\t\tif cause != nil {\n\t\t\tconvertErrorDFS(cause, exceptions, &currentID, MechanismSourceCause, visited, maxErrorDepth, currentDepth+1)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/hub.go",
    "content": "package sentry\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go/internal/debuglog\"\n)\n\ntype contextKey int\n\n// Keys used to store values in a Context. Use with Context.Value to access\n// values stored by the SDK.\nconst (\n\t// HubContextKey is the key used to store the current Hub.\n\tHubContextKey = contextKey(1)\n\t// RequestContextKey is the key used to store the current http.Request.\n\tRequestContextKey = contextKey(2)\n)\n\n// currentHub is the initial Hub with no Client bound and an empty Scope.\nvar currentHub = NewHub(nil, NewScope())\n\n// Hub is the central object that manages scopes and clients.\n//\n// This can be used to capture events and manage the scope.\n// The default hub that is available automatically.\n//\n// In most situations developers do not need to interface the hub. Instead\n// toplevel convenience functions are exposed that will automatically dispatch\n// to global (CurrentHub) hub.  In some situations this might not be\n// possible in which case it might become necessary to manually work with the\n// hub. This is for instance the case when working with async code.\ntype Hub struct {\n\tmu          sync.RWMutex\n\tstack       *stack\n\tlastEventID EventID\n}\n\ntype layer struct {\n\t// mu protects concurrent reads and writes to client.\n\tmu     sync.RWMutex\n\tclient *Client\n\t// scope is read-only, not protected by mu.\n\tscope *Scope\n}\n\n// Client returns the layer's client. Safe for concurrent use.\nfunc (l *layer) Client() *Client {\n\tl.mu.RLock()\n\tdefer l.mu.RUnlock()\n\treturn l.client\n}\n\n// SetClient sets the layer's client. Safe for concurrent use.\nfunc (l *layer) SetClient(c *Client) {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tl.client = c\n}\n\ntype stack []*layer\n\n// NewHub returns an instance of a Hub with provided Client and Scope bound.\nfunc NewHub(client *Client, scope *Scope) *Hub {\n\thub := Hub{\n\t\tstack: &stack{{\n\t\t\tclient: client,\n\t\t\tscope:  scope,\n\t\t}},\n\t}\n\treturn &hub\n}\n\n// CurrentHub returns an instance of previously initialized Hub stored in the global namespace.\nfunc CurrentHub() *Hub {\n\treturn currentHub\n}\n\n// LastEventID returns the ID of the last event (error or message) captured\n// through the hub and sent to the underlying transport.\n//\n// Transactions and events dropped by sampling or event processors do not change\n// the last event ID.\n//\n// LastEventID is a convenience method to cover use cases in which errors are\n// captured indirectly and the ID is needed. For example, it can be used as part\n// of an HTTP middleware to log the ID of the last error, if any.\n//\n// For more flexibility, consider instead using the ClientOptions.BeforeSend\n// function or event processors.\nfunc (hub *Hub) LastEventID() EventID {\n\thub.mu.RLock()\n\tdefer hub.mu.RUnlock()\n\n\treturn hub.lastEventID\n}\n\n// stackTop returns the top layer of the hub stack. Valid hubs always have at\n// least one layer, therefore stackTop always return a non-nil pointer.\nfunc (hub *Hub) stackTop() *layer {\n\thub.mu.RLock()\n\tdefer hub.mu.RUnlock()\n\n\tstack := hub.stack\n\tstackLen := len(*stack)\n\ttop := (*stack)[stackLen-1]\n\treturn top\n}\n\n// Clone returns a copy of the current Hub with top-most scope and client copied over.\nfunc (hub *Hub) Clone() *Hub {\n\ttop := hub.stackTop()\n\tscope := top.scope\n\tif scope != nil {\n\t\tscope = scope.Clone()\n\t}\n\treturn NewHub(top.Client(), scope)\n}\n\n// Scope returns top-level Scope of the current Hub or nil if no Scope is bound.\nfunc (hub *Hub) Scope() *Scope {\n\ttop := hub.stackTop()\n\treturn top.scope\n}\n\n// Client returns top-level Client of the current Hub or nil if no Client is bound.\nfunc (hub *Hub) Client() *Client {\n\ttop := hub.stackTop()\n\treturn top.Client()\n}\n\n// PushScope pushes a new scope for the current Hub and reuses previously bound Client.\nfunc (hub *Hub) PushScope() *Scope {\n\ttop := hub.stackTop()\n\n\tvar scope *Scope\n\tif top.scope != nil {\n\t\tscope = top.scope.Clone()\n\t} else {\n\t\tscope = NewScope()\n\t}\n\n\thub.mu.Lock()\n\tdefer hub.mu.Unlock()\n\n\t*hub.stack = append(*hub.stack, &layer{\n\t\tclient: top.Client(),\n\t\tscope:  scope,\n\t})\n\n\treturn scope\n}\n\n// PopScope drops the most recent scope.\n//\n// Calls to PopScope must be coordinated with PushScope. For most cases, using\n// WithScope should be more convenient.\n//\n// Calls to PopScope that do not match previous calls to PushScope are silently\n// ignored.\nfunc (hub *Hub) PopScope() {\n\thub.mu.Lock()\n\tdefer hub.mu.Unlock()\n\n\tstack := *hub.stack\n\tstackLen := len(stack)\n\tif stackLen > 1 {\n\t\t// Never pop the last item off the stack, the stack should always have\n\t\t// at least one item.\n\t\t*hub.stack = stack[0 : stackLen-1]\n\t}\n}\n\n// BindClient binds a new Client for the current Hub.\nfunc (hub *Hub) BindClient(client *Client) {\n\ttop := hub.stackTop()\n\ttop.SetClient(client)\n}\n\n// WithScope runs f in an isolated temporary scope.\n//\n// It is useful when extra data should be sent with a single capture call, for\n// instance a different level or tags.\n//\n// The scope passed to f starts as a clone of the current scope and can be\n// freely modified without affecting the current scope.\n//\n// It is a shorthand for PushScope followed by PopScope.\nfunc (hub *Hub) WithScope(f func(scope *Scope)) {\n\tscope := hub.PushScope()\n\tdefer hub.PopScope()\n\tf(scope)\n}\n\n// ConfigureScope runs f in the current scope.\n//\n// It is useful to set data that applies to all events that share the current\n// scope.\n//\n// Modifying the scope affects all references to the current scope.\n//\n// See also WithScope for making isolated temporary changes.\nfunc (hub *Hub) ConfigureScope(f func(scope *Scope)) {\n\tscope := hub.Scope()\n\tf(scope)\n}\n\n// CaptureEvent calls the method of a same name on currently bound Client instance\n// passing it a top-level Scope.\n// Returns EventID if successfully, or nil if there's no Scope or Client available.\nfunc (hub *Hub) CaptureEvent(event *Event) *EventID {\n\tclient, scope := hub.Client(), hub.Scope()\n\tif client == nil || scope == nil {\n\t\treturn nil\n\t}\n\teventID := client.CaptureEvent(event, nil, scope)\n\n\tif event.Type != transactionType && eventID != nil {\n\t\thub.mu.Lock()\n\t\thub.lastEventID = *eventID\n\t\thub.mu.Unlock()\n\t}\n\treturn eventID\n}\n\n// CaptureMessage calls the method of a same name on currently bound Client instance\n// passing it a top-level Scope.\n// Returns EventID if successfully, or nil if there's no Scope or Client available.\nfunc (hub *Hub) CaptureMessage(message string) *EventID {\n\tclient, scope := hub.Client(), hub.Scope()\n\tif client == nil || scope == nil {\n\t\treturn nil\n\t}\n\teventID := client.CaptureMessage(message, nil, scope)\n\n\tif eventID != nil {\n\t\thub.mu.Lock()\n\t\thub.lastEventID = *eventID\n\t\thub.mu.Unlock()\n\t}\n\treturn eventID\n}\n\n// CaptureException calls the method of a same name on currently bound Client instance\n// passing it a top-level Scope.\n// Returns EventID if successfully, or nil if there's no Scope or Client available.\nfunc (hub *Hub) CaptureException(exception error) *EventID {\n\tclient, scope := hub.Client(), hub.Scope()\n\tif client == nil || scope == nil {\n\t\treturn nil\n\t}\n\teventID := client.CaptureException(exception, &EventHint{OriginalException: exception}, scope)\n\n\tif eventID != nil {\n\t\thub.mu.Lock()\n\t\thub.lastEventID = *eventID\n\t\thub.mu.Unlock()\n\t}\n\treturn eventID\n}\n\n// CaptureCheckIn calls the method of the same name on currently bound Client instance\n// passing it a top-level Scope.\n// Returns CheckInID if the check-in was captured successfully, or nil otherwise.\nfunc (hub *Hub) CaptureCheckIn(checkIn *CheckIn, monitorConfig *MonitorConfig) *EventID {\n\tclient, scope := hub.Client(), hub.Scope()\n\tif client == nil {\n\t\treturn nil\n\t}\n\n\treturn client.CaptureCheckIn(checkIn, monitorConfig, scope)\n}\n\n// AddBreadcrumb records a new breadcrumb.\n//\n// The total number of breadcrumbs that can be recorded are limited by the\n// configuration on the client.\nfunc (hub *Hub) AddBreadcrumb(breadcrumb *Breadcrumb, hint *BreadcrumbHint) {\n\tclient := hub.Client()\n\n\t// If there's no client, just store it on the scope straight away\n\tif client == nil {\n\t\thub.Scope().AddBreadcrumb(breadcrumb, defaultMaxBreadcrumbs)\n\t\treturn\n\t}\n\n\tlimit := client.options.MaxBreadcrumbs\n\tswitch {\n\tcase limit < 0:\n\t\treturn\n\tcase limit == 0:\n\t\tlimit = defaultMaxBreadcrumbs\n\t}\n\n\tif client.options.BeforeBreadcrumb != nil {\n\t\tif hint == nil {\n\t\t\thint = &BreadcrumbHint{}\n\t\t}\n\t\tif breadcrumb = client.options.BeforeBreadcrumb(breadcrumb, hint); breadcrumb == nil {\n\t\t\tdebuglog.Println(\"breadcrumb dropped due to BeforeBreadcrumb callback.\")\n\t\t\treturn\n\t\t}\n\t}\n\n\thub.Scope().AddBreadcrumb(breadcrumb, limit)\n}\n\n// Recover calls the method of a same name on currently bound Client instance\n// passing it a top-level Scope.\n// Returns EventID if successfully, or nil if there's no Scope or Client available.\nfunc (hub *Hub) Recover(err interface{}) *EventID {\n\tif err == nil {\n\t\terr = recover()\n\t}\n\tclient, scope := hub.Client(), hub.Scope()\n\tif client == nil || scope == nil {\n\t\treturn nil\n\t}\n\treturn client.Recover(err, &EventHint{RecoveredException: err}, scope)\n}\n\n// RecoverWithContext calls the method of a same name on currently bound Client instance\n// passing it a top-level Scope.\n// Returns EventID if successfully, or nil if there's no Scope or Client available.\nfunc (hub *Hub) RecoverWithContext(ctx context.Context, err interface{}) *EventID {\n\tif err == nil {\n\t\terr = recover()\n\t}\n\tclient, scope := hub.Client(), hub.Scope()\n\tif client == nil || scope == nil {\n\t\treturn nil\n\t}\n\treturn client.RecoverWithContext(ctx, err, &EventHint{RecoveredException: err}, scope)\n}\n\n// Flush waits until the underlying Transport sends any buffered events to the\n// Sentry server, blocking for at most the given timeout. It returns false if\n// the timeout was reached. In that case, some events may not have been sent.\n//\n// Flush should be called before terminating the program to avoid\n// unintentionally dropping events.\n//\n// Do not call Flush indiscriminately after every call to CaptureEvent,\n// CaptureException or CaptureMessage. Instead, to have the SDK send events over\n// the network synchronously, configure it to use the HTTPSyncTransport in the\n// call to Init.\nfunc (hub *Hub) Flush(timeout time.Duration) bool {\n\tclient := hub.Client()\n\n\tif client == nil {\n\t\treturn false\n\t}\n\n\treturn client.Flush(timeout)\n}\n\n// FlushWithContext waits until the underlying Transport sends any buffered events\n// to the Sentry server, blocking for at most the duration specified by the context.\n// It returns false if the context is canceled before the events are sent. In such a case,\n// some events may not be delivered.\n//\n// FlushWithContext should be called before terminating the program to ensure no\n// events are unintentionally dropped.\n//\n// Avoid calling FlushWithContext indiscriminately after each call to CaptureEvent,\n// CaptureException, or CaptureMessage. To send events synchronously over the network,\n// configure the SDK to use HTTPSyncTransport during initialization with Init.\n\nfunc (hub *Hub) FlushWithContext(ctx context.Context) bool {\n\tclient := hub.Client()\n\n\tif client == nil {\n\t\treturn false\n\t}\n\n\treturn client.FlushWithContext(ctx)\n}\n\n// GetTraceparent returns the current Sentry traceparent string, to be used as a HTTP header value\n// or HTML meta tag value.\n// This function is context aware, as in it either returns the traceparent based\n// on the current span, or the scope's propagation context.\nfunc (hub *Hub) GetTraceparent() string {\n\tscope := hub.Scope()\n\n\tif scope.span != nil {\n\t\treturn scope.span.ToSentryTrace()\n\t}\n\n\treturn fmt.Sprintf(\"%s-%s\", scope.propagationContext.TraceID, scope.propagationContext.SpanID)\n}\n\n// GetTraceparentW3C returns the current traceparent string in W3C format.\n// This is intended for propagation to downstream services that expect the W3C header.\nfunc (hub *Hub) GetTraceparentW3C() string {\n\tscope := hub.Scope()\n\tif scope.span != nil {\n\t\treturn scope.span.ToTraceparent()\n\t}\n\n\treturn fmt.Sprintf(\"00-%s-%s-00\", scope.propagationContext.TraceID, scope.propagationContext.SpanID)\n}\n\n// GetBaggage returns the current Sentry baggage string, to be used as a HTTP header value\n// or HTML meta tag value.\n// This function is context aware, as in it either returns the baggage based\n// on the current span or the scope's propagation context.\nfunc (hub *Hub) GetBaggage() string {\n\tscope := hub.Scope()\n\n\tif scope.span != nil {\n\t\treturn scope.span.ToBaggage()\n\t}\n\n\treturn scope.propagationContext.DynamicSamplingContext.String()\n}\n\n// HasHubOnContext checks whether Hub instance is bound to a given Context struct.\nfunc HasHubOnContext(ctx context.Context) bool {\n\t_, ok := ctx.Value(HubContextKey).(*Hub)\n\treturn ok\n}\n\n// GetHubFromContext tries to retrieve Hub instance from the given Context struct\n// or return nil if one is not found.\nfunc GetHubFromContext(ctx context.Context) *Hub {\n\tif hub, ok := ctx.Value(HubContextKey).(*Hub); ok {\n\t\treturn hub\n\t}\n\treturn nil\n}\n\n// hubFromContext returns either a hub stored in the context or the current hub.\n// The return value is guaranteed to be non-nil, unlike GetHubFromContext.\nfunc hubFromContext(ctx context.Context) *Hub {\n\tif hub, ok := ctx.Value(HubContextKey).(*Hub); ok {\n\t\treturn hub\n\t}\n\treturn currentHub\n}\n\n// SetHubOnContext stores given Hub instance on the Context struct and returns a new Context.\nfunc SetHubOnContext(ctx context.Context, hub *Hub) context.Context {\n\treturn context.WithValue(ctx, HubContextKey, hub)\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/integrations.go",
    "content": "package sentry\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/getsentry/sentry-go/internal/debuglog\"\n)\n\n// ================================\n// Modules Integration\n// ================================\n\ntype modulesIntegration struct {\n\tonce    sync.Once\n\tmodules map[string]string\n}\n\nfunc (mi *modulesIntegration) Name() string {\n\treturn \"Modules\"\n}\n\nfunc (mi *modulesIntegration) SetupOnce(client *Client) {\n\tclient.AddEventProcessor(mi.processor)\n}\n\nfunc (mi *modulesIntegration) processor(event *Event, _ *EventHint) *Event {\n\tif len(event.Modules) == 0 {\n\t\tmi.once.Do(func() {\n\t\t\tinfo, ok := debug.ReadBuildInfo()\n\t\t\tif !ok {\n\t\t\t\tdebuglog.Print(\"The Modules integration is not available in binaries built without module support.\")\n\t\t\t\treturn\n\t\t\t}\n\t\t\tmi.modules = extractModules(info)\n\t\t})\n\t}\n\tevent.Modules = mi.modules\n\treturn event\n}\n\nfunc extractModules(info *debug.BuildInfo) map[string]string {\n\tmodules := map[string]string{\n\t\tinfo.Main.Path: info.Main.Version,\n\t}\n\tfor _, dep := range info.Deps {\n\t\tver := dep.Version\n\t\tif dep.Replace != nil {\n\t\t\tver += fmt.Sprintf(\" => %s %s\", dep.Replace.Path, dep.Replace.Version)\n\t\t}\n\t\tmodules[dep.Path] = strings.TrimSuffix(ver, \" \")\n\t}\n\treturn modules\n}\n\n// ================================\n// Environment Integration\n// ================================\n\ntype environmentIntegration struct{}\n\nfunc (ei *environmentIntegration) Name() string {\n\treturn \"Environment\"\n}\n\nfunc (ei *environmentIntegration) SetupOnce(client *Client) {\n\tclient.AddEventProcessor(ei.processor)\n}\n\nfunc (ei *environmentIntegration) processor(event *Event, _ *EventHint) *Event {\n\t// Initialize maps as necessary.\n\tcontextNames := []string{\"device\", \"os\", \"runtime\"}\n\tif event.Contexts == nil {\n\t\tevent.Contexts = make(map[string]Context, len(contextNames))\n\t}\n\tfor _, name := range contextNames {\n\t\tif event.Contexts[name] == nil {\n\t\t\tevent.Contexts[name] = make(Context)\n\t\t}\n\t}\n\n\t// Set contextual information preserving existing data. For each context, if\n\t// the existing value is not of type map[string]interface{}, then no\n\t// additional information is added.\n\tif deviceContext, ok := event.Contexts[\"device\"]; ok {\n\t\tif _, ok := deviceContext[\"arch\"]; !ok {\n\t\t\tdeviceContext[\"arch\"] = runtime.GOARCH\n\t\t}\n\t\tif _, ok := deviceContext[\"num_cpu\"]; !ok {\n\t\t\tdeviceContext[\"num_cpu\"] = runtime.NumCPU()\n\t\t}\n\t}\n\tif osContext, ok := event.Contexts[\"os\"]; ok {\n\t\tif _, ok := osContext[\"name\"]; !ok {\n\t\t\tosContext[\"name\"] = runtime.GOOS\n\t\t}\n\t}\n\tif runtimeContext, ok := event.Contexts[\"runtime\"]; ok {\n\t\tif _, ok := runtimeContext[\"name\"]; !ok {\n\t\t\truntimeContext[\"name\"] = \"go\"\n\t\t}\n\t\tif _, ok := runtimeContext[\"version\"]; !ok {\n\t\t\truntimeContext[\"version\"] = runtime.Version()\n\t\t}\n\t\tif _, ok := runtimeContext[\"go_numroutines\"]; !ok {\n\t\t\truntimeContext[\"go_numroutines\"] = runtime.NumGoroutine()\n\t\t}\n\t\tif _, ok := runtimeContext[\"go_maxprocs\"]; !ok {\n\t\t\truntimeContext[\"go_maxprocs\"] = runtime.GOMAXPROCS(0)\n\t\t}\n\t\tif _, ok := runtimeContext[\"go_numcgocalls\"]; !ok {\n\t\t\truntimeContext[\"go_numcgocalls\"] = runtime.NumCgoCall()\n\t\t}\n\t}\n\treturn event\n}\n\n// ================================\n// Ignore Errors Integration\n// ================================\n\ntype ignoreErrorsIntegration struct {\n\tignoreErrors []*regexp.Regexp\n}\n\nfunc (iei *ignoreErrorsIntegration) Name() string {\n\treturn \"IgnoreErrors\"\n}\n\nfunc (iei *ignoreErrorsIntegration) SetupOnce(client *Client) {\n\tiei.ignoreErrors = transformStringsIntoRegexps(client.options.IgnoreErrors)\n\tclient.AddEventProcessor(iei.processor)\n}\n\nfunc (iei *ignoreErrorsIntegration) processor(event *Event, _ *EventHint) *Event {\n\tsuspects := getIgnoreErrorsSuspects(event)\n\n\tfor _, suspect := range suspects {\n\t\tfor _, pattern := range iei.ignoreErrors {\n\t\t\tif pattern.Match([]byte(suspect)) || strings.Contains(suspect, pattern.String()) {\n\t\t\t\tdebuglog.Printf(\"Event dropped due to being matched by `IgnoreErrors` option.\"+\n\t\t\t\t\t\"| Value matched: %s | Filter used: %s\", suspect, pattern)\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\n\treturn event\n}\n\nfunc transformStringsIntoRegexps(strings []string) []*regexp.Regexp {\n\tvar exprs []*regexp.Regexp\n\n\tfor _, s := range strings {\n\t\tr, err := regexp.Compile(s)\n\t\tif err == nil {\n\t\t\texprs = append(exprs, r)\n\t\t}\n\t}\n\n\treturn exprs\n}\n\nfunc getIgnoreErrorsSuspects(event *Event) []string {\n\tsuspects := []string{}\n\n\tif event.Message != \"\" {\n\t\tsuspects = append(suspects, event.Message)\n\t}\n\n\tfor _, ex := range event.Exception {\n\t\tsuspects = append(suspects, ex.Type, ex.Value)\n\t}\n\n\treturn suspects\n}\n\n// ================================\n// Ignore Transactions Integration\n// ================================\n\ntype ignoreTransactionsIntegration struct {\n\tignoreTransactions []*regexp.Regexp\n}\n\nfunc (iei *ignoreTransactionsIntegration) Name() string {\n\treturn \"IgnoreTransactions\"\n}\n\nfunc (iei *ignoreTransactionsIntegration) SetupOnce(client *Client) {\n\tiei.ignoreTransactions = transformStringsIntoRegexps(client.options.IgnoreTransactions)\n\tclient.AddEventProcessor(iei.processor)\n}\n\nfunc (iei *ignoreTransactionsIntegration) processor(event *Event, _ *EventHint) *Event {\n\tsuspect := event.Transaction\n\tif suspect == \"\" {\n\t\treturn event\n\t}\n\n\tfor _, pattern := range iei.ignoreTransactions {\n\t\tif pattern.Match([]byte(suspect)) || strings.Contains(suspect, pattern.String()) {\n\t\t\tdebuglog.Printf(\"Transaction dropped due to being matched by `IgnoreTransactions` option.\"+\n\t\t\t\t\"| Value matched: %s | Filter used: %s\", suspect, pattern)\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn event\n}\n\n// ================================\n// Contextify Frames Integration\n// ================================\n\ntype contextifyFramesIntegration struct {\n\tsr              sourceReader\n\tcontextLines    int\n\tcachedLocations sync.Map\n}\n\nfunc (cfi *contextifyFramesIntegration) Name() string {\n\treturn \"ContextifyFrames\"\n}\n\nfunc (cfi *contextifyFramesIntegration) SetupOnce(client *Client) {\n\tcfi.sr = newSourceReader()\n\tcfi.contextLines = 5\n\n\tclient.AddEventProcessor(cfi.processor)\n}\n\nfunc (cfi *contextifyFramesIntegration) processor(event *Event, _ *EventHint) *Event {\n\t// Range over all exceptions\n\tfor _, ex := range event.Exception {\n\t\t// If it has no stacktrace, just bail out\n\t\tif ex.Stacktrace == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\t// If it does, it should have frames, so try to contextify them\n\t\tex.Stacktrace.Frames = cfi.contextify(ex.Stacktrace.Frames)\n\t}\n\n\t// Range over all threads\n\tfor _, th := range event.Threads {\n\t\t// If it has no stacktrace, just bail out\n\t\tif th.Stacktrace == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\t// If it does, it should have frames, so try to contextify them\n\t\tth.Stacktrace.Frames = cfi.contextify(th.Stacktrace.Frames)\n\t}\n\n\treturn event\n}\n\nfunc (cfi *contextifyFramesIntegration) contextify(frames []Frame) []Frame {\n\tcontextifiedFrames := make([]Frame, 0, len(frames))\n\n\tfor _, frame := range frames {\n\t\tif !frame.InApp {\n\t\t\tcontextifiedFrames = append(contextifiedFrames, frame)\n\t\t\tcontinue\n\t\t}\n\n\t\tvar path string\n\n\t\tif cachedPath, ok := cfi.cachedLocations.Load(frame.AbsPath); ok {\n\t\t\tif p, ok := cachedPath.(string); ok {\n\t\t\t\tpath = p\n\t\t\t}\n\t\t} else {\n\t\t\t// Optimize for happy path here\n\t\t\tif fileExists(frame.AbsPath) {\n\t\t\t\tpath = frame.AbsPath\n\t\t\t} else {\n\t\t\t\tpath = cfi.findNearbySourceCodeLocation(frame.AbsPath)\n\t\t\t}\n\t\t}\n\n\t\tif path == \"\" {\n\t\t\tcontextifiedFrames = append(contextifiedFrames, frame)\n\t\t\tcontinue\n\t\t}\n\n\t\tlines, contextLine := cfi.sr.readContextLines(path, frame.Lineno, cfi.contextLines)\n\t\tcontextifiedFrames = append(contextifiedFrames, cfi.addContextLinesToFrame(frame, lines, contextLine))\n\t}\n\n\treturn contextifiedFrames\n}\n\nfunc (cfi *contextifyFramesIntegration) findNearbySourceCodeLocation(originalPath string) string {\n\ttrimmedPath := strings.TrimPrefix(originalPath, \"/\")\n\tcomponents := strings.Split(trimmedPath, \"/\")\n\n\tfor len(components) > 0 {\n\t\tcomponents = components[1:]\n\t\tpossibleLocation := strings.Join(components, \"/\")\n\n\t\tif fileExists(possibleLocation) {\n\t\t\tcfi.cachedLocations.Store(originalPath, possibleLocation)\n\t\t\treturn possibleLocation\n\t\t}\n\t}\n\n\tcfi.cachedLocations.Store(originalPath, \"\")\n\treturn \"\"\n}\n\nfunc (cfi *contextifyFramesIntegration) addContextLinesToFrame(frame Frame, lines [][]byte, contextLine int) Frame {\n\tfor i, line := range lines {\n\t\tswitch {\n\t\tcase i < contextLine:\n\t\t\tframe.PreContext = append(frame.PreContext, string(line))\n\t\tcase i == contextLine:\n\t\t\tframe.ContextLine = string(line)\n\t\tdefault:\n\t\t\tframe.PostContext = append(frame.PostContext, string(line))\n\t\t}\n\t}\n\treturn frame\n}\n\n// ================================\n// Global Tags Integration\n// ================================\n\nconst envTagsPrefix = \"SENTRY_TAGS_\"\n\ntype globalTagsIntegration struct {\n\ttags    map[string]string\n\tenvTags map[string]string\n}\n\nfunc (ti *globalTagsIntegration) Name() string {\n\treturn \"GlobalTags\"\n}\n\nfunc (ti *globalTagsIntegration) SetupOnce(client *Client) {\n\tti.tags = make(map[string]string, len(client.options.Tags))\n\tfor k, v := range client.options.Tags {\n\t\tti.tags[k] = v\n\t}\n\n\tti.envTags = loadEnvTags()\n\n\tclient.AddEventProcessor(ti.processor)\n}\n\nfunc (ti *globalTagsIntegration) processor(event *Event, _ *EventHint) *Event {\n\tif len(ti.tags) == 0 && len(ti.envTags) == 0 {\n\t\treturn event\n\t}\n\n\tif event.Tags == nil {\n\t\tevent.Tags = make(map[string]string, len(ti.tags)+len(ti.envTags))\n\t}\n\n\tfor k, v := range ti.tags {\n\t\tif _, ok := event.Tags[k]; !ok {\n\t\t\tevent.Tags[k] = v\n\t\t}\n\t}\n\n\tfor k, v := range ti.envTags {\n\t\tif _, ok := event.Tags[k]; !ok {\n\t\t\tevent.Tags[k] = v\n\t\t}\n\t}\n\n\treturn event\n}\n\nfunc loadEnvTags() map[string]string {\n\ttags := map[string]string{}\n\tfor _, pair := range os.Environ() {\n\t\tparts := strings.Split(pair, \"=\")\n\t\tif !strings.HasPrefix(parts[0], envTagsPrefix) {\n\t\t\tcontinue\n\t\t}\n\t\ttag := strings.TrimPrefix(parts[0], envTagsPrefix)\n\t\ttags[tag] = parts[1]\n\t}\n\treturn tags\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/interfaces.go",
    "content": "package sentry\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go/attribute\"\n\t\"github.com/getsentry/sentry-go/internal/debuglog\"\n\t\"github.com/getsentry/sentry-go/internal/protocol\"\n\t\"github.com/getsentry/sentry-go/internal/ratelimit\"\n)\n\nconst errorType = \"\"\nconst eventType = \"event\"\nconst transactionType = \"transaction\"\nconst checkInType = \"check_in\"\n\nvar logEvent = struct {\n\tType        string\n\tContentType string\n}{\n\t\"log\",\n\t\"application/vnd.sentry.items.log+json\",\n}\n\nvar traceMetricEvent = struct {\n\tType        string\n\tContentType string\n}{\n\t\"trace_metric\",\n\t\"application/vnd.sentry.items.trace-metric+json\",\n}\n\n// Level marks the severity of the event.\ntype Level string\n\n// Describes the severity of the event.\nconst (\n\tLevelDebug   Level = \"debug\"\n\tLevelInfo    Level = \"info\"\n\tLevelWarning Level = \"warning\"\n\tLevelError   Level = \"error\"\n\tLevelFatal   Level = \"fatal\"\n)\n\n// SdkInfo contains all metadata about the SDK.\ntype SdkInfo = protocol.SdkInfo\ntype SdkPackage = protocol.SdkPackage\n\n// TODO: This type could be more useful, as map of interface{} is too generic\n// and requires a lot of type assertions in beforeBreadcrumb calls\n// plus it could just be map[string]interface{} then.\n\n// BreadcrumbHint contains information that can be associated with a Breadcrumb.\ntype BreadcrumbHint map[string]interface{}\n\n// Breadcrumb specifies an application event that occurred before a Sentry event.\n// An event may contain one or more breadcrumbs.\ntype Breadcrumb struct {\n\tType      string                 `json:\"type,omitempty\"`\n\tCategory  string                 `json:\"category,omitempty\"`\n\tMessage   string                 `json:\"message,omitempty\"`\n\tData      map[string]interface{} `json:\"data,omitempty\"`\n\tLevel     Level                  `json:\"level,omitempty\"`\n\tTimestamp time.Time              `json:\"timestamp,omitzero\"`\n}\n\n// TODO: provide constants for known breadcrumb types.\n// See https://develop.sentry.dev/sdk/event-payloads/breadcrumbs/#breadcrumb-types.\n\n// Logger provides a chaining API for structured logging to Sentry.\ntype Logger interface {\n\t// Write implements the io.Writer interface. Currently, the [sentry.Hub] is\n\t// context aware, in order to get the correct trace correlation. Using this\n\t// might result in incorrect span association on logs. If you need to use\n\t// Write it is recommended to create a NewLogger so that the associated context\n\t// is passed correctly.\n\tWrite(p []byte) (n int, err error)\n\n\t// SetAttributes allows attaching parameters to the logger using the attribute API.\n\t// These attributes will be included in all subsequent log entries.\n\tSetAttributes(...attribute.Builder)\n\n\t// Trace defines the [sentry.LogLevel] for the log entry.\n\tTrace() LogEntry\n\t// Debug defines the [sentry.LogLevel] for the log entry.\n\tDebug() LogEntry\n\t// Info defines the [sentry.LogLevel] for the log entry.\n\tInfo() LogEntry\n\t// Warn defines the [sentry.LogLevel] for the log entry.\n\tWarn() LogEntry\n\t// Error defines the [sentry.LogLevel] for the log entry.\n\tError() LogEntry\n\t// Fatal defines the [sentry.LogLevel] for the log entry.\n\tFatal() LogEntry\n\t// Panic defines the [sentry.LogLevel] for the log entry.\n\tPanic() LogEntry\n\t// LFatal defines the [sentry.LogLevel] for the log entry. This only sets\n\t// the level to fatal, but does not panic or exit.\n\tLFatal() LogEntry\n\t// GetCtx returns the [context.Context] set on the logger.\n\tGetCtx() context.Context\n}\n\n// LogEntry defines the interface for a log entry that supports chaining attributes.\ntype LogEntry interface {\n\t// WithCtx creates a new LogEntry with the specified context without overwriting the previous one.\n\tWithCtx(ctx context.Context) LogEntry\n\t// String adds a string attribute to the LogEntry.\n\tString(key, value string) LogEntry\n\t// Int adds an int attribute to the LogEntry.\n\tInt(key string, value int) LogEntry\n\t// Int64 adds an int64 attribute to the LogEntry.\n\tInt64(key string, value int64) LogEntry\n\t// Float64 adds a float64 attribute to the LogEntry.\n\tFloat64(key string, value float64) LogEntry\n\t// Bool adds a bool attribute to the LogEntry.\n\tBool(key string, value bool) LogEntry\n\t// Emit emits the LogEntry with the provided arguments.\n\tEmit(args ...interface{})\n\t// Emitf emits the LogEntry using a format string and arguments.\n\tEmitf(format string, args ...interface{})\n}\n\n// Meter provides an interface for recording metrics.\ntype Meter interface {\n\t// WithCtx returns a new Meter that uses the given context for trace/span association.\n\tWithCtx(ctx context.Context) Meter\n\t// SetAttributes allows attaching parameters to the meter using the attribute API.\n\t// These attributes will be included in all subsequent metrics.\n\tSetAttributes(attrs ...attribute.Builder)\n\t// Count records a count metric.\n\tCount(name string, count int64, opts ...MeterOption)\n\t// Gauge records a gauge metric.\n\tGauge(name string, value float64, opts ...MeterOption)\n\t// Distribution records a distribution metric.\n\tDistribution(name string, sample float64, opts ...MeterOption)\n}\n\n// MeterOption configures a metric recording call.\ntype MeterOption func(*meterOptions)\n\ntype meterOptions struct {\n\tunit       string\n\tscope      *Scope\n\tattributes map[string]attribute.Value\n}\n\n// WithUnit sets the unit for the metric (e.g., \"millisecond\", \"byte\").\nfunc WithUnit(unit string) MeterOption {\n\treturn func(o *meterOptions) {\n\t\to.unit = unit\n\t}\n}\n\n// WithScopeOverride sets a custom scope for the metric, overriding the default scope from the hub.\nfunc WithScopeOverride(scope *Scope) MeterOption {\n\treturn func(o *meterOptions) {\n\t\to.scope = scope\n\t}\n}\n\n// WithAttributes sets attributes for the metric.\nfunc WithAttributes(attrs ...attribute.Builder) MeterOption {\n\treturn func(o *meterOptions) {\n\t\tif o.attributes == nil {\n\t\t\to.attributes = make(map[string]attribute.Value, len(attrs))\n\t\t}\n\t\tfor _, a := range attrs {\n\t\t\tif a.Value.Type() == attribute.INVALID {\n\t\t\t\tdebuglog.Printf(\"invalid attribute: %v\", a)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\to.attributes[a.Key] = a.Value\n\t\t}\n\t}\n}\n\n// Attachment allows associating files with your events to aid in investigation.\n// An event may contain one or more attachments.\ntype Attachment struct {\n\tFilename    string\n\tContentType string\n\tPayload     []byte\n}\n\n// User describes the user associated with an Event. If this is used, at least\n// an ID or an IP address should be provided.\ntype User struct {\n\tID        string            `json:\"id,omitempty\"`\n\tEmail     string            `json:\"email,omitempty\"`\n\tIPAddress string            `json:\"ip_address,omitempty\"`\n\tUsername  string            `json:\"username,omitempty\"`\n\tName      string            `json:\"name,omitempty\"`\n\tData      map[string]string `json:\"data,omitempty\"`\n}\n\nfunc (u User) IsEmpty() bool {\n\tif u.ID != \"\" {\n\t\treturn false\n\t}\n\n\tif u.Email != \"\" {\n\t\treturn false\n\t}\n\n\tif u.IPAddress != \"\" {\n\t\treturn false\n\t}\n\n\tif u.Username != \"\" {\n\t\treturn false\n\t}\n\n\tif u.Name != \"\" {\n\t\treturn false\n\t}\n\n\tif len(u.Data) > 0 {\n\t\treturn false\n\t}\n\n\treturn true\n}\n\n// Request contains information on a HTTP request related to the event.\ntype Request struct {\n\tURL         string            `json:\"url,omitempty\"`\n\tMethod      string            `json:\"method,omitempty\"`\n\tData        string            `json:\"data,omitempty\"`\n\tQueryString string            `json:\"query_string,omitempty\"`\n\tCookies     string            `json:\"cookies,omitempty\"`\n\tHeaders     map[string]string `json:\"headers,omitempty\"`\n\tEnv         map[string]string `json:\"env,omitempty\"`\n}\n\nvar sensitiveHeaders = map[string]struct{}{\n\t\"_csrf\":               {},\n\t\"_csrf_token\":         {},\n\t\"_session\":            {},\n\t\"_xsrf\":               {},\n\t\"Api-Key\":             {},\n\t\"Apikey\":              {},\n\t\"Auth\":                {},\n\t\"Authorization\":       {},\n\t\"Cookie\":              {},\n\t\"Credentials\":         {},\n\t\"Csrf\":                {},\n\t\"Csrf-Token\":          {},\n\t\"Csrftoken\":           {},\n\t\"Ip-Address\":          {},\n\t\"Passwd\":              {},\n\t\"Password\":            {},\n\t\"Private-Key\":         {},\n\t\"Privatekey\":          {},\n\t\"Proxy-Authorization\": {},\n\t\"Remote-Addr\":         {},\n\t\"Secret\":              {},\n\t\"Session\":             {},\n\t\"Sessionid\":           {},\n\t\"Token\":               {},\n\t\"User-Session\":        {},\n\t\"X-Api-Key\":           {},\n\t\"X-Csrftoken\":         {},\n\t\"X-Forwarded-For\":     {},\n\t\"X-Real-Ip\":           {},\n\t\"XSRF-TOKEN\":          {},\n}\n\n// NewRequest returns a new Sentry Request from the given http.Request.\n//\n// NewRequest avoids operations that depend on network access. In particular, it\n// does not read r.Body.\nfunc NewRequest(r *http.Request) *Request {\n\tprot := protocol.SchemeHTTP\n\tif r.TLS != nil || r.Header.Get(\"X-Forwarded-Proto\") == \"https\" {\n\t\tprot = protocol.SchemeHTTPS\n\t}\n\turl := fmt.Sprintf(\"%s://%s%s\", prot, r.Host, r.URL.Path)\n\n\tvar cookies string\n\tvar env map[string]string\n\theaders := map[string]string{}\n\n\tif client := CurrentHub().Client(); client != nil && client.options.SendDefaultPII {\n\t\t// We read only the first Cookie header because of the specification:\n\t\t// https://tools.ietf.org/html/rfc6265#section-5.4\n\t\t// When the user agent generates an HTTP request, the user agent MUST NOT\n\t\t// attach more than one Cookie header field.\n\t\tcookies = r.Header.Get(\"Cookie\")\n\n\t\theaders = make(map[string]string, len(r.Header))\n\t\tfor k, v := range r.Header {\n\t\t\theaders[k] = strings.Join(v, \",\")\n\t\t}\n\n\t\tif addr, port, err := net.SplitHostPort(r.RemoteAddr); err == nil {\n\t\t\tenv = map[string]string{\"REMOTE_ADDR\": addr, \"REMOTE_PORT\": port}\n\t\t}\n\t} else {\n\t\tfor k, v := range r.Header {\n\t\t\tif _, ok := sensitiveHeaders[k]; !ok {\n\t\t\t\theaders[k] = strings.Join(v, \",\")\n\t\t\t}\n\t\t}\n\t}\n\n\theaders[\"Host\"] = r.Host\n\n\treturn &Request{\n\t\tURL:         url,\n\t\tMethod:      r.Method,\n\t\tQueryString: r.URL.RawQuery,\n\t\tCookies:     cookies,\n\t\tHeaders:     headers,\n\t\tEnv:         env,\n\t}\n}\n\n// Mechanism is the mechanism by which an exception was generated and handled.\ntype Mechanism struct {\n\tType             string         `json:\"type\"`\n\tDescription      string         `json:\"description,omitempty\"`\n\tHelpLink         string         `json:\"help_link,omitempty\"`\n\tSource           string         `json:\"source,omitempty\"`\n\tHandled          *bool          `json:\"handled,omitempty\"`\n\tParentID         *int           `json:\"parent_id,omitempty\"`\n\tExceptionID      int            `json:\"exception_id\"`\n\tIsExceptionGroup bool           `json:\"is_exception_group,omitempty\"`\n\tData             map[string]any `json:\"data,omitempty\"`\n}\n\n// SetUnhandled indicates that the exception is an unhandled exception, i.e.\n// from a panic.\nfunc (m *Mechanism) SetUnhandled() {\n\tm.Handled = Pointer(false)\n}\n\n// Exception specifies an error that occurred.\ntype Exception struct {\n\tType       string      `json:\"type,omitempty\"`  // used as the main issue title\n\tValue      string      `json:\"value,omitempty\"` // used as the main issue subtitle\n\tModule     string      `json:\"module,omitempty\"`\n\tThreadID   uint64      `json:\"thread_id,omitempty\"`\n\tStacktrace *Stacktrace `json:\"stacktrace,omitempty\"`\n\tMechanism  *Mechanism  `json:\"mechanism,omitempty\"`\n}\n\n// SDKMetaData is a struct to stash data which is needed at some point in the SDK's event processing pipeline\n// but which shouldn't get send to Sentry.\ntype SDKMetaData struct {\n\tdsc DynamicSamplingContext\n}\n\n// Contains information about how the name of the transaction was determined.\ntype TransactionInfo struct {\n\tSource TransactionSource `json:\"source,omitempty\"`\n}\n\n// The DebugMeta interface is not used in Golang apps, but may be populated\n// when proxying Events from other platforms, like iOS, Android, and the\n// Web.  (See: https://develop.sentry.dev/sdk/event-payloads/debugmeta/ ).\ntype DebugMeta struct {\n\tSdkInfo *DebugMetaSdkInfo `json:\"sdk_info,omitempty\"`\n\tImages  []DebugMetaImage  `json:\"images,omitempty\"`\n}\n\ntype DebugMetaSdkInfo struct {\n\tSdkName           string `json:\"sdk_name,omitempty\"`\n\tVersionMajor      int    `json:\"version_major,omitempty\"`\n\tVersionMinor      int    `json:\"version_minor,omitempty\"`\n\tVersionPatchlevel int    `json:\"version_patchlevel,omitempty\"`\n}\n\ntype DebugMetaImage struct {\n\tType        string `json:\"type,omitempty\"`         // all\n\tImageAddr   string `json:\"image_addr,omitempty\"`   // macho,elf,pe\n\tImageSize   int    `json:\"image_size,omitempty\"`   // macho,elf,pe\n\tDebugID     string `json:\"debug_id,omitempty\"`     // macho,elf,pe,wasm,sourcemap\n\tDebugFile   string `json:\"debug_file,omitempty\"`   // macho,elf,pe,wasm\n\tCodeID      string `json:\"code_id,omitempty\"`      // macho,elf,pe,wasm\n\tCodeFile    string `json:\"code_file,omitempty\"`    // macho,elf,pe,wasm,sourcemap\n\tImageVmaddr string `json:\"image_vmaddr,omitempty\"` // macho,elf,pe\n\tArch        string `json:\"arch,omitempty\"`         // macho,elf,pe\n\tUUID        string `json:\"uuid,omitempty\"`         // proguard\n}\n\n// EventID is a hexadecimal string representing a unique uuid4 for an Event.\n// An EventID must be 32 characters long, lowercase and not have any dashes.\ntype EventID string\n\ntype Context = map[string]interface{}\n\n// Event is the fundamental data structure that is sent to Sentry.\ntype Event struct {\n\tBreadcrumbs []*Breadcrumb          `json:\"breadcrumbs,omitempty\"`\n\tContexts    map[string]Context     `json:\"contexts,omitempty\"`\n\tDist        string                 `json:\"dist,omitempty\"`\n\tEnvironment string                 `json:\"environment,omitempty\"`\n\tEventID     EventID                `json:\"event_id,omitempty\"`\n\tExtra       map[string]interface{} `json:\"extra,omitempty\"`\n\tFingerprint []string               `json:\"fingerprint,omitempty\"`\n\tLevel       Level                  `json:\"level,omitempty\"`\n\tMessage     string                 `json:\"message,omitempty\"`\n\tPlatform    string                 `json:\"platform,omitempty\"`\n\tRelease     string                 `json:\"release,omitempty\"`\n\tSdk         SdkInfo                `json:\"sdk,omitempty\"`\n\tServerName  string                 `json:\"server_name,omitempty\"`\n\tThreads     []Thread               `json:\"threads,omitempty\"`\n\tTags        map[string]string      `json:\"tags,omitempty\"`\n\tTimestamp   time.Time              `json:\"timestamp,omitzero\"`\n\tTransaction string                 `json:\"transaction,omitempty\"`\n\tUser        User                   `json:\"user,omitempty\"`\n\tLogger      string                 `json:\"logger,omitempty\"`\n\tModules     map[string]string      `json:\"modules,omitempty\"`\n\tRequest     *Request               `json:\"request,omitempty\"`\n\tException   []Exception            `json:\"exception,omitempty\"`\n\tDebugMeta   *DebugMeta             `json:\"debug_meta,omitempty\"`\n\tAttachments []*Attachment          `json:\"-\"`\n\n\t// The fields below are only relevant for transactions.\n\n\tType            string           `json:\"type,omitempty\"`\n\tStartTime       time.Time        `json:\"start_timestamp,omitzero\"`\n\tSpans           []*Span          `json:\"spans,omitempty\"`\n\tTransactionInfo *TransactionInfo `json:\"transaction_info,omitempty\"`\n\n\t// The fields below are only relevant for crons/check ins\n\n\tCheckIn       *CheckIn       `json:\"check_in,omitempty\"`\n\tMonitorConfig *MonitorConfig `json:\"monitor_config,omitempty\"`\n\n\t// The fields below are only relevant for logs\n\tLogs []Log `json:\"-\"`\n\n\t// The fields below are only relevant for metrics\n\tMetrics []Metric `json:\"-\"`\n\n\t// The fields below are not part of the final JSON payload.\n\n\tsdkMetaData SDKMetaData\n}\n\n// SetException appends the unwrapped errors to the event's exception list.\n//\n// maxErrorDepth is the maximum depth of the error chain we will look\n// into while unwrapping the errors. If maxErrorDepth is -1, we will\n// unwrap all errors in the chain.\nfunc (e *Event) SetException(exception error, maxErrorDepth int) {\n\tif exception == nil {\n\t\treturn\n\t}\n\n\texceptions := convertErrorToExceptions(exception, maxErrorDepth)\n\tif len(exceptions) == 0 {\n\t\treturn\n\t}\n\n\te.Exception = exceptions\n}\n\n// ToEnvelopeItem converts the Event to a Sentry envelope item.\nfunc (e *Event) ToEnvelopeItem() (*protocol.EnvelopeItem, error) {\n\teventBody, err := json.Marshal(e)\n\tif err != nil {\n\t\t// Try fallback: remove problematic fields and retry\n\t\te.Breadcrumbs = nil\n\t\te.Contexts = nil\n\t\te.Extra = map[string]interface{}{\n\t\t\t\"info\": fmt.Sprintf(\"Could not encode original event as JSON. \"+\n\t\t\t\t\"Succeeded by removing Breadcrumbs, Contexts and Extra. \"+\n\t\t\t\t\"Please verify the data you attach to the scope. \"+\n\t\t\t\t\"Error: %s\", err),\n\t\t}\n\n\t\teventBody, err = json.Marshal(e)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"event could not be marshaled even with fallback: %w\", err)\n\t\t}\n\n\t\tDebugLogger.Printf(\"Event marshaling succeeded with fallback after removing problematic fields\")\n\t}\n\n\t// TODO: all event types should be abstracted to implement EnvelopeItemConvertible and convert themselves.\n\tvar item *protocol.EnvelopeItem\n\tswitch e.Type {\n\tcase transactionType:\n\t\titem = protocol.NewEnvelopeItem(protocol.EnvelopeItemTypeTransaction, eventBody)\n\tcase checkInType:\n\t\titem = protocol.NewEnvelopeItem(protocol.EnvelopeItemTypeCheckIn, eventBody)\n\tcase logEvent.Type:\n\t\titem = protocol.NewLogItem(len(e.Logs), eventBody)\n\tcase traceMetricEvent.Type:\n\t\titem = protocol.NewTraceMetricItem(len(e.Metrics), eventBody)\n\tdefault:\n\t\titem = protocol.NewEnvelopeItem(protocol.EnvelopeItemTypeEvent, eventBody)\n\t}\n\n\treturn item, nil\n}\n\n// GetCategory returns the rate limit category for this event.\nfunc (e *Event) GetCategory() ratelimit.Category {\n\treturn e.toCategory()\n}\n\n// GetEventID returns the event ID.\nfunc (e *Event) GetEventID() string {\n\treturn string(e.EventID)\n}\n\n// GetSdkInfo returns SDK information for the envelope header.\nfunc (e *Event) GetSdkInfo() *protocol.SdkInfo {\n\treturn &e.Sdk\n}\n\n// GetDynamicSamplingContext returns trace context for the envelope header.\nfunc (e *Event) GetDynamicSamplingContext() map[string]string {\n\ttrace := make(map[string]string)\n\tif dsc := e.sdkMetaData.dsc; dsc.HasEntries() {\n\t\tfor k, v := range dsc.Entries {\n\t\t\ttrace[k] = v\n\t\t}\n\t}\n\treturn trace\n}\n\n// TODO: Event.Contexts map[string]interface{} => map[string]EventContext,\n// to prevent accidentally storing T when we mean *T.\n// For example, the TraceContext must be stored as *TraceContext to pick up the\n// MarshalJSON method (and avoid copying).\n// type EventContext interface{ EventContext() }\n\n// MarshalJSON converts the Event struct to JSON.\nfunc (e *Event) MarshalJSON() ([]byte, error) {\n\tif e.Type == checkInType {\n\t\treturn e.checkInMarshalJSON()\n\t}\n\treturn e.defaultMarshalJSON()\n}\n\nfunc (e *Event) defaultMarshalJSON() ([]byte, error) {\n\t// event aliases Event to allow calling json.Marshal without an infinite\n\t// loop. It preserves all fields while none of the attached methods.\n\ttype event Event\n\n\tif e.Type == transactionType {\n\t\treturn json.Marshal(struct{ *event }{(*event)(e)})\n\t}\n\t// metrics and logs should be serialized under the same `items` json field.\n\tif e.Type == logEvent.Type {\n\t\ttype logEvent struct {\n\t\t\t*event\n\t\t\tItems []Log           `json:\"items,omitempty\"`\n\t\t\tType  json.RawMessage `json:\"type,omitempty\"`\n\t\t}\n\t\treturn json.Marshal(logEvent{event: (*event)(e), Items: e.Logs})\n\t}\n\n\tif e.Type == traceMetricEvent.Type {\n\t\ttype metricEvent struct {\n\t\t\t*event\n\t\t\tItems []Metric        `json:\"items,omitempty\"`\n\t\t\tType  json.RawMessage `json:\"type,omitempty\"`\n\t\t}\n\t\treturn json.Marshal(metricEvent{event: (*event)(e), Items: e.Metrics})\n\t}\n\n\t// errorEvent is like Event with shadowed fields for customizing JSON\n\t// marshaling.\n\ttype errorEvent struct {\n\t\t*event\n\n\t\t// The fields below are not part of error events and only make sense to\n\t\t// be sent for transactions. They shadow the respective fields in Event\n\t\t// and are meant to remain nil, triggering the omitempty behavior.\n\n\t\tType            json.RawMessage `json:\"type,omitempty\"`\n\t\tStartTime       json.RawMessage `json:\"start_timestamp,omitempty\"`\n\t\tSpans           json.RawMessage `json:\"spans,omitempty\"`\n\t\tTransactionInfo json.RawMessage `json:\"transaction_info,omitempty\"`\n\t}\n\n\tx := errorEvent{event: (*event)(e)}\n\treturn json.Marshal(x)\n}\n\nfunc (e *Event) checkInMarshalJSON() ([]byte, error) {\n\tcheckIn := serializedCheckIn{\n\t\tCheckInID:     string(e.CheckIn.ID),\n\t\tMonitorSlug:   e.CheckIn.MonitorSlug,\n\t\tStatus:        e.CheckIn.Status,\n\t\tDuration:      e.CheckIn.Duration.Seconds(),\n\t\tRelease:       e.Release,\n\t\tEnvironment:   e.Environment,\n\t\tMonitorConfig: nil,\n\t}\n\n\tif e.MonitorConfig != nil {\n\t\tcheckIn.MonitorConfig = &MonitorConfig{\n\t\t\tSchedule:              e.MonitorConfig.Schedule,\n\t\t\tCheckInMargin:         e.MonitorConfig.CheckInMargin,\n\t\t\tMaxRuntime:            e.MonitorConfig.MaxRuntime,\n\t\t\tTimezone:              e.MonitorConfig.Timezone,\n\t\t\tFailureIssueThreshold: e.MonitorConfig.FailureIssueThreshold,\n\t\t\tRecoveryThreshold:     e.MonitorConfig.RecoveryThreshold,\n\t\t}\n\t}\n\n\treturn json.Marshal(checkIn)\n}\n\nfunc (e *Event) toCategory() ratelimit.Category {\n\tswitch e.Type {\n\tcase errorType:\n\t\treturn ratelimit.CategoryError\n\tcase transactionType:\n\t\treturn ratelimit.CategoryTransaction\n\tcase logEvent.Type:\n\t\treturn ratelimit.CategoryLog\n\tcase checkInType:\n\t\treturn ratelimit.CategoryMonitor\n\tcase traceMetricEvent.Type:\n\t\treturn ratelimit.CategoryTraceMetric\n\tdefault:\n\t\treturn ratelimit.CategoryUnknown\n\t}\n}\n\n// NewEvent creates a new Event.\nfunc NewEvent() *Event {\n\treturn &Event{\n\t\tContexts: make(map[string]Context),\n\t\tExtra:    make(map[string]interface{}),\n\t\tTags:     make(map[string]string),\n\t\tModules:  make(map[string]string),\n\t}\n}\n\n// Thread specifies threads that were running at the time of an event.\ntype Thread struct {\n\tID         string      `json:\"id,omitempty\"`\n\tName       string      `json:\"name,omitempty\"`\n\tStacktrace *Stacktrace `json:\"stacktrace,omitempty\"`\n\tCrashed    bool        `json:\"crashed,omitempty\"`\n\tCurrent    bool        `json:\"current,omitempty\"`\n}\n\n// EventHint contains information that can be associated with an Event.\ntype EventHint struct {\n\tData               interface{}\n\tEventID            string\n\tOriginalException  error\n\tRecoveredException interface{}\n\tContext            context.Context\n\tRequest            *http.Request\n\tResponse           *http.Response\n}\n\ntype Log struct {\n\tTimestamp  time.Time                  `json:\"timestamp,omitzero\"`\n\tTraceID    TraceID                    `json:\"trace_id\"`\n\tSpanID     SpanID                     `json:\"span_id,omitzero\"`\n\tLevel      LogLevel                   `json:\"level\"`\n\tSeverity   int                        `json:\"severity_number,omitempty\"`\n\tBody       string                     `json:\"body\"`\n\tAttributes map[string]attribute.Value `json:\"attributes,omitempty\"`\n}\n\n// GetCategory returns the rate limit category for logs.\nfunc (l *Log) GetCategory() ratelimit.Category {\n\treturn ratelimit.CategoryLog\n}\n\n// GetEventID returns empty string (event ID set when batching).\nfunc (l *Log) GetEventID() string {\n\treturn \"\"\n}\n\n// GetSdkInfo returns nil (SDK info set when batching).\nfunc (l *Log) GetSdkInfo() *protocol.SdkInfo {\n\treturn nil\n}\n\n// GetDynamicSamplingContext returns nil (trace context set when batching).\nfunc (l *Log) GetDynamicSamplingContext() map[string]string {\n\treturn nil\n}\n\ntype MetricType string\n\nconst (\n\tMetricTypeInvalid      MetricType = \"\"\n\tMetricTypeCounter      MetricType = \"counter\"\n\tMetricTypeGauge        MetricType = \"gauge\"\n\tMetricTypeDistribution MetricType = \"distribution\"\n)\n\ntype Metric struct {\n\tTimestamp  time.Time                  `json:\"timestamp,omitzero\"`\n\tTraceID    TraceID                    `json:\"trace_id\"`\n\tSpanID     SpanID                     `json:\"span_id,omitzero\"`\n\tType       MetricType                 `json:\"type\"`\n\tName       string                     `json:\"name\"`\n\tValue      MetricValue                `json:\"value\"`\n\tUnit       string                     `json:\"unit,omitempty\"`\n\tAttributes map[string]attribute.Value `json:\"attributes,omitempty\"`\n}\n\n// GetCategory returns the rate limit category for metrics.\nfunc (m *Metric) GetCategory() ratelimit.Category {\n\treturn ratelimit.CategoryTraceMetric\n}\n\n// GetEventID returns empty string (event ID set when batching).\nfunc (m *Metric) GetEventID() string {\n\treturn \"\"\n}\n\n// GetSdkInfo returns nil (SDK info set when batching).\nfunc (m *Metric) GetSdkInfo() *protocol.SdkInfo {\n\treturn nil\n}\n\n// GetDynamicSamplingContext returns nil (trace context set when batching).\nfunc (m *Metric) GetDynamicSamplingContext() map[string]string {\n\treturn nil\n}\n\n// MetricValue stores metric values with full precision.\n// It supports int64 (for counters) and float64 (for gauges and distributions).\ntype MetricValue struct {\n\tvalue attribute.Value\n}\n\n// Int64MetricValue creates a MetricValue from an int64.\n// Used for counter metrics to preserve full int64 precision.\nfunc Int64MetricValue(v int64) MetricValue {\n\treturn MetricValue{value: attribute.Int64Value(v)}\n}\n\n// Float64MetricValue creates a MetricValue from a float64.\n// Used for gauge and distribution metrics.\nfunc Float64MetricValue(v float64) MetricValue {\n\treturn MetricValue{value: attribute.Float64Value(v)}\n}\n\n// Type returns the type of the stored value (attribute.INT64 or attribute.FLOAT64).\nfunc (v MetricValue) Type() attribute.Type {\n\treturn v.value.Type()\n}\n\n// Int64 returns the value as int64 if it holds an int64.\n// The second return value indicates whether the type matched.\nfunc (v MetricValue) Int64() (int64, bool) {\n\tif v.value.Type() == attribute.INT64 {\n\t\treturn v.value.AsInt64(), true\n\t}\n\treturn 0, false\n}\n\n// Float64 returns the value as float64 if it holds a float64.\n// The second return value indicates whether the type matched.\nfunc (v MetricValue) Float64() (float64, bool) {\n\tif v.value.Type() == attribute.FLOAT64 {\n\t\treturn v.value.AsFloat64(), true\n\t}\n\treturn 0, false\n}\n\n// AsInterface returns the value as int64 or float64.\n// Use type assertion or type switch to handle the result.\nfunc (v MetricValue) AsInterface() any {\n\treturn v.value.AsInterface()\n}\n\n// MarshalJSON serializes the value as a bare number.\nfunc (v MetricValue) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value.AsInterface())\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/debug/transport.go",
    "content": "package debug\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/http/httptrace\"\n\t\"net/http/httputil\"\n)\n\n// Transport implements http.RoundTripper and can be used to wrap other HTTP\n// transports for debugging, normally http.DefaultTransport.\ntype Transport struct {\n\thttp.RoundTripper\n\tOutput io.Writer\n\t// Dump controls whether to dump HTTP request and responses.\n\tDump bool\n\t// Trace enables usage of net/http/httptrace.\n\tTrace bool\n}\n\nfunc (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {\n\tvar buf bytes.Buffer\n\tif t.Dump {\n\t\tb, err := httputil.DumpRequestOut(req, true)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\t_, err = buf.Write(ensureTrailingNewline(b))\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n\tif t.Trace {\n\t\ttrace := &httptrace.ClientTrace{\n\t\t\tDNSDone: func(di httptrace.DNSDoneInfo) {\n\t\t\t\tfmt.Fprintf(&buf, \"* DNS %v → %v\\n\", req.Host, di.Addrs)\n\t\t\t},\n\t\t\tGotConn: func(ci httptrace.GotConnInfo) {\n\t\t\t\tfmt.Fprintf(&buf, \"* Connection local=%v remote=%v\", ci.Conn.LocalAddr(), ci.Conn.RemoteAddr())\n\t\t\t\tif ci.Reused {\n\t\t\t\t\tfmt.Fprint(&buf, \" (reused)\")\n\t\t\t\t}\n\t\t\t\tif ci.WasIdle {\n\t\t\t\t\tfmt.Fprintf(&buf, \" (idle %v)\", ci.IdleTime)\n\t\t\t\t}\n\t\t\t\tfmt.Fprintln(&buf)\n\t\t\t},\n\t\t}\n\t\treq = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))\n\t}\n\tresp, err := t.RoundTripper.RoundTrip(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif t.Dump {\n\t\tb, err := httputil.DumpResponse(resp, true)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\t_, err = buf.Write(ensureTrailingNewline(b))\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n\t_, err = io.Copy(t.Output, &buf)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn resp, nil\n}\n\nfunc ensureTrailingNewline(b []byte) []byte {\n\tif len(b) > 0 && b[len(b)-1] != '\\n' {\n\t\tb = append(b, '\\n')\n\t}\n\treturn b\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/debuglog/log.go",
    "content": "package debuglog\n\nimport (\n\t\"io\"\n\t\"log\"\n)\n\n// logger is the global debug logger instance.\nvar logger = log.New(io.Discard, \"[Sentry] \", log.LstdFlags)\n\n// SetOutput changes the output destination of the logger.\nfunc SetOutput(w io.Writer) {\n\tlogger.SetOutput(w)\n}\n\n// GetLogger returns the current logger instance.\n// This function is thread-safe and can be called concurrently.\nfunc GetLogger() *log.Logger {\n\treturn logger\n}\n\n// Printf calls Printf on the underlying logger.\nfunc Printf(format string, args ...interface{}) {\n\tlogger.Printf(format, args...)\n}\n\n// Println calls Println on the underlying logger.\nfunc Println(args ...interface{}) {\n\tlogger.Println(args...)\n}\n\n// Print calls Print on the underlying logger.\nfunc Print(args ...interface{}) {\n\tlogger.Print(args...)\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/http/transport.go",
    "content": "package http\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go/internal/debuglog\"\n\t\"github.com/getsentry/sentry-go/internal/protocol\"\n\t\"github.com/getsentry/sentry-go/internal/ratelimit\"\n\t\"github.com/getsentry/sentry-go/internal/util\"\n)\n\nconst (\n\tapiVersion = 7\n\n\tdefaultTimeout   = time.Second * 30\n\tdefaultQueueSize = 1000\n)\n\nvar (\n\tErrTransportQueueFull = errors.New(\"transport queue full\")\n\tErrTransportClosed    = errors.New(\"transport is closed\")\n\tErrEmptyEnvelope      = errors.New(\"empty envelope provided\")\n)\n\ntype TransportOptions struct {\n\tDsn           string\n\tHTTPClient    *http.Client\n\tHTTPTransport http.RoundTripper\n\tHTTPProxy     string\n\tHTTPSProxy    string\n\tCaCerts       *x509.CertPool\n}\n\nfunc getProxyConfig(options TransportOptions) func(*http.Request) (*url.URL, error) {\n\tif len(options.HTTPSProxy) > 0 {\n\t\treturn func(*http.Request) (*url.URL, error) {\n\t\t\treturn url.Parse(options.HTTPSProxy)\n\t\t}\n\t}\n\n\tif len(options.HTTPProxy) > 0 {\n\t\treturn func(*http.Request) (*url.URL, error) {\n\t\t\treturn url.Parse(options.HTTPProxy)\n\t\t}\n\t}\n\n\treturn http.ProxyFromEnvironment\n}\n\nfunc getTLSConfig(options TransportOptions) *tls.Config {\n\tif options.CaCerts != nil {\n\t\treturn &tls.Config{\n\t\t\tRootCAs:    options.CaCerts,\n\t\t\tMinVersion: tls.VersionTLS12,\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc getSentryRequestFromEnvelope(ctx context.Context, dsn *protocol.Dsn, envelope *protocol.Envelope) (r *http.Request, err error) {\n\tdefer func() {\n\t\tif r != nil {\n\t\t\tsdkName := envelope.Header.Sdk.Name\n\t\t\tsdkVersion := envelope.Header.Sdk.Version\n\n\t\t\tr.Header.Set(\"User-Agent\", fmt.Sprintf(\"%s/%s\", sdkName, sdkVersion))\n\t\t\tr.Header.Set(\"Content-Type\", \"application/x-sentry-envelope\")\n\n\t\t\tauth := fmt.Sprintf(\"Sentry sentry_version=%d, \"+\n\t\t\t\t\"sentry_client=%s/%s, sentry_key=%s\", apiVersion, sdkName, sdkVersion, dsn.GetPublicKey())\n\n\t\t\tif dsn.GetSecretKey() != \"\" {\n\t\t\t\tauth = fmt.Sprintf(\"%s, sentry_secret=%s\", auth, dsn.GetSecretKey())\n\t\t\t}\n\n\t\t\tr.Header.Set(\"X-Sentry-Auth\", auth)\n\t\t}\n\t}()\n\n\tvar buf bytes.Buffer\n\t_, err = envelope.WriteTo(&buf)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn http.NewRequestWithContext(\n\t\tctx,\n\t\thttp.MethodPost,\n\t\tdsn.GetAPIURL().String(),\n\t\t&buf,\n\t)\n}\n\nfunc categoryFromEnvelope(envelope *protocol.Envelope) ratelimit.Category {\n\tif envelope == nil || len(envelope.Items) == 0 {\n\t\treturn ratelimit.CategoryAll\n\t}\n\n\tfor _, item := range envelope.Items {\n\t\tif item == nil || item.Header == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch item.Header.Type {\n\t\tcase protocol.EnvelopeItemTypeEvent:\n\t\t\treturn ratelimit.CategoryError\n\t\tcase protocol.EnvelopeItemTypeTransaction:\n\t\t\treturn ratelimit.CategoryTransaction\n\t\tcase protocol.EnvelopeItemTypeCheckIn:\n\t\t\treturn ratelimit.CategoryMonitor\n\t\tcase protocol.EnvelopeItemTypeLog:\n\t\t\treturn ratelimit.CategoryLog\n\t\tcase protocol.EnvelopeItemTypeAttachment:\n\t\t\tcontinue\n\t\tdefault:\n\t\t\treturn ratelimit.CategoryAll\n\t\t}\n\t}\n\n\treturn ratelimit.CategoryAll\n}\n\n// SyncTransport is a blocking implementation of Transport.\n//\n// Clients using this transport will send requests to Sentry sequentially and\n// block until a response is returned.\n//\n// The blocking behavior is useful in a limited set of use cases. For example,\n// use it when deploying code to a Function as a Service (\"Serverless\")\n// platform, where any work happening in a background goroutine is not\n// guaranteed to execute.\n//\n// For most cases, prefer AsyncTransport.\ntype SyncTransport struct {\n\tdsn       *protocol.Dsn\n\tclient    *http.Client\n\ttransport http.RoundTripper\n\n\tmu     sync.Mutex\n\tlimits ratelimit.Map\n\n\tTimeout time.Duration\n}\n\nfunc NewSyncTransport(options TransportOptions) protocol.TelemetryTransport {\n\tdsn, err := protocol.NewDsn(options.Dsn)\n\tif err != nil || dsn == nil {\n\t\tdebuglog.Printf(\"Transport is disabled: invalid dsn: %v\\n\", err)\n\t\treturn NewNoopTransport()\n\t}\n\n\ttransport := &SyncTransport{\n\t\tTimeout: defaultTimeout,\n\t\tlimits:  make(ratelimit.Map),\n\t\tdsn:     dsn,\n\t}\n\n\tif options.HTTPTransport != nil {\n\t\ttransport.transport = options.HTTPTransport\n\t} else {\n\t\ttransport.transport = &http.Transport{\n\t\t\tProxy:           getProxyConfig(options),\n\t\t\tTLSClientConfig: getTLSConfig(options),\n\t\t}\n\t}\n\n\tif options.HTTPClient != nil {\n\t\ttransport.client = options.HTTPClient\n\t} else {\n\t\ttransport.client = &http.Client{\n\t\t\tTransport: transport.transport,\n\t\t\tTimeout:   transport.Timeout,\n\t\t}\n\t}\n\n\treturn transport\n}\n\nfunc (t *SyncTransport) SendEnvelope(envelope *protocol.Envelope) error {\n\treturn t.SendEnvelopeWithContext(context.Background(), envelope)\n}\n\nfunc (t *SyncTransport) Close() {}\n\nfunc (t *SyncTransport) IsRateLimited(category ratelimit.Category) bool {\n\treturn t.disabled(category)\n}\n\nfunc (t *SyncTransport) HasCapacity() bool { return true }\n\nfunc (t *SyncTransport) SendEnvelopeWithContext(ctx context.Context, envelope *protocol.Envelope) error {\n\tif envelope == nil || len(envelope.Items) == 0 {\n\t\treturn ErrEmptyEnvelope\n\t}\n\n\tcategory := categoryFromEnvelope(envelope)\n\tif t.disabled(category) {\n\t\treturn nil\n\t}\n\n\trequest, err := getSentryRequestFromEnvelope(ctx, t.dsn, envelope)\n\tif err != nil {\n\t\tdebuglog.Printf(\"There was an issue creating the request: %v\", err)\n\t\treturn err\n\t}\n\tidentifier := util.EnvelopeIdentifier(envelope)\n\tdebuglog.Printf(\n\t\t\"Sending %s to %s project: %s\",\n\t\tidentifier,\n\t\tt.dsn.GetHost(),\n\t\tt.dsn.GetProjectID(),\n\t)\n\n\tresponse, err := t.client.Do(request)\n\tif err != nil {\n\t\tdebuglog.Printf(\"There was an issue with sending an event: %v\", err)\n\t\treturn err\n\t}\n\tutil.HandleHTTPResponse(response, identifier)\n\n\tt.mu.Lock()\n\tif t.limits == nil {\n\t\tt.limits = make(ratelimit.Map)\n\t}\n\tt.limits.Merge(ratelimit.FromResponse(response))\n\tt.mu.Unlock()\n\n\t_, _ = io.CopyN(io.Discard, response.Body, util.MaxDrainResponseBytes)\n\treturn response.Body.Close()\n}\n\nfunc (t *SyncTransport) Flush(_ time.Duration) bool {\n\treturn true\n}\n\nfunc (t *SyncTransport) FlushWithContext(_ context.Context) bool {\n\treturn true\n}\n\nfunc (t *SyncTransport) disabled(c ratelimit.Category) bool {\n\tt.mu.Lock()\n\tdefer t.mu.Unlock()\n\tdisabled := t.limits.IsRateLimited(c)\n\tif disabled {\n\t\tdebuglog.Printf(\"Too many requests for %q, backing off till: %v\", c, t.limits.Deadline(c))\n\t}\n\treturn disabled\n}\n\n// AsyncTransport is the default, non-blocking, implementation of Transport.\n//\n// Clients using this transport will enqueue requests in a queue and return to\n// the caller before any network communication has happened. Requests are sent\n// to Sentry sequentially from a background goroutine.\ntype AsyncTransport struct {\n\tdsn       *protocol.Dsn\n\tclient    *http.Client\n\ttransport http.RoundTripper\n\n\tqueue chan *protocol.Envelope\n\n\tmu     sync.RWMutex\n\tlimits ratelimit.Map\n\n\tdone chan struct{}\n\twg   sync.WaitGroup\n\n\tflushRequest chan chan struct{}\n\n\tsentCount    int64\n\tdroppedCount int64\n\terrorCount   int64\n\n\tQueueSize int\n\tTimeout   time.Duration\n\n\tstartOnce sync.Once\n\tcloseOnce sync.Once\n}\n\nfunc NewAsyncTransport(options TransportOptions) protocol.TelemetryTransport {\n\tdsn, err := protocol.NewDsn(options.Dsn)\n\tif err != nil || dsn == nil {\n\t\tdebuglog.Printf(\"Transport is disabled: invalid dsn: %v\", err)\n\t\treturn NewNoopTransport()\n\t}\n\n\ttransport := &AsyncTransport{\n\t\tQueueSize: defaultQueueSize,\n\t\tTimeout:   defaultTimeout,\n\t\tdone:      make(chan struct{}),\n\t\tlimits:    make(ratelimit.Map),\n\t\tdsn:       dsn,\n\t}\n\n\ttransport.queue = make(chan *protocol.Envelope, transport.QueueSize)\n\ttransport.flushRequest = make(chan chan struct{})\n\n\tif options.HTTPTransport != nil {\n\t\ttransport.transport = options.HTTPTransport\n\t} else {\n\t\ttransport.transport = &http.Transport{\n\t\t\tProxy:           getProxyConfig(options),\n\t\t\tTLSClientConfig: getTLSConfig(options),\n\t\t}\n\t}\n\n\tif options.HTTPClient != nil {\n\t\ttransport.client = options.HTTPClient\n\t} else {\n\t\ttransport.client = &http.Client{\n\t\t\tTransport: transport.transport,\n\t\t\tTimeout:   transport.Timeout,\n\t\t}\n\t}\n\n\ttransport.start()\n\treturn transport\n}\n\nfunc (t *AsyncTransport) start() {\n\tt.startOnce.Do(func() {\n\t\tt.wg.Add(1)\n\t\tgo t.worker()\n\t})\n}\n\n// HasCapacity reports whether the async transport queue appears to have space\n// for at least one more envelope. This is a best-effort, non-blocking check.\nfunc (t *AsyncTransport) HasCapacity() bool {\n\tt.mu.RLock()\n\tdefer t.mu.RUnlock()\n\tselect {\n\tcase <-t.done:\n\t\treturn false\n\tdefault:\n\t}\n\treturn len(t.queue) < cap(t.queue)\n}\n\nfunc (t *AsyncTransport) SendEnvelope(envelope *protocol.Envelope) error {\n\tselect {\n\tcase <-t.done:\n\t\treturn ErrTransportClosed\n\tdefault:\n\t}\n\n\tif envelope == nil || len(envelope.Items) == 0 {\n\t\treturn ErrEmptyEnvelope\n\t}\n\n\tcategory := categoryFromEnvelope(envelope)\n\tif t.isRateLimited(category) {\n\t\treturn nil\n\t}\n\n\tselect {\n\tcase t.queue <- envelope:\n\t\tidentifier := util.EnvelopeIdentifier(envelope)\n\t\tdebuglog.Printf(\n\t\t\t\"Sending %s to %s project: %s\",\n\t\t\tidentifier,\n\t\t\tt.dsn.GetHost(),\n\t\t\tt.dsn.GetProjectID(),\n\t\t)\n\t\treturn nil\n\tdefault:\n\t\tatomic.AddInt64(&t.droppedCount, 1)\n\t\treturn ErrTransportQueueFull\n\t}\n}\n\nfunc (t *AsyncTransport) Flush(timeout time.Duration) bool {\n\tctx, cancel := context.WithTimeout(context.Background(), timeout)\n\tdefer cancel()\n\treturn t.FlushWithContext(ctx)\n}\n\nfunc (t *AsyncTransport) FlushWithContext(ctx context.Context) bool {\n\tflushResponse := make(chan struct{})\n\tselect {\n\tcase t.flushRequest <- flushResponse:\n\t\tselect {\n\t\tcase <-flushResponse:\n\t\t\tdebuglog.Println(\"Buffer flushed successfully.\")\n\t\t\treturn true\n\t\tcase <-ctx.Done():\n\t\t\tdebuglog.Println(\"Failed to flush, buffer timed out.\")\n\t\t\treturn false\n\t\t}\n\tcase <-ctx.Done():\n\t\tdebuglog.Println(\"Failed to flush, buffer timed out.\")\n\t\treturn false\n\t}\n}\n\nfunc (t *AsyncTransport) Close() {\n\tt.closeOnce.Do(func() {\n\t\tclose(t.done)\n\t\tclose(t.queue)\n\t\tclose(t.flushRequest)\n\t\tt.wg.Wait()\n\t})\n}\n\nfunc (t *AsyncTransport) IsRateLimited(category ratelimit.Category) bool {\n\treturn t.isRateLimited(category)\n}\n\nfunc (t *AsyncTransport) worker() {\n\tdefer t.wg.Done()\n\n\tfor {\n\t\tselect {\n\t\tcase <-t.done:\n\t\t\treturn\n\t\tcase envelope, open := <-t.queue:\n\t\t\tif !open {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tt.processEnvelope(envelope)\n\t\tcase flushResponse, open := <-t.flushRequest:\n\t\t\tif !open {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tt.drainQueue()\n\t\t\tclose(flushResponse)\n\t\t}\n\t}\n}\n\nfunc (t *AsyncTransport) drainQueue() {\n\tfor {\n\t\tselect {\n\t\tcase envelope, open := <-t.queue:\n\t\t\tif !open {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tt.processEnvelope(envelope)\n\t\tdefault:\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (t *AsyncTransport) processEnvelope(envelope *protocol.Envelope) {\n\tif t.sendEnvelopeHTTP(envelope) {\n\t\tatomic.AddInt64(&t.sentCount, 1)\n\t} else {\n\t\tatomic.AddInt64(&t.errorCount, 1)\n\t}\n}\n\nfunc (t *AsyncTransport) sendEnvelopeHTTP(envelope *protocol.Envelope) bool {\n\tcategory := categoryFromEnvelope(envelope)\n\tif t.isRateLimited(category) {\n\t\treturn false\n\t}\n\n\tctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)\n\tdefer cancel()\n\n\trequest, err := getSentryRequestFromEnvelope(ctx, t.dsn, envelope)\n\tif err != nil {\n\t\tdebuglog.Printf(\"Failed to create request from envelope: %v\", err)\n\t\treturn false\n\t}\n\n\tresponse, err := t.client.Do(request)\n\tif err != nil {\n\t\tdebuglog.Printf(\"HTTP request failed: %v\", err)\n\t\treturn false\n\t}\n\tdefer response.Body.Close()\n\n\tidentifier := util.EnvelopeIdentifier(envelope)\n\tsuccess := util.HandleHTTPResponse(response, identifier)\n\n\tt.mu.Lock()\n\tif t.limits == nil {\n\t\tt.limits = make(ratelimit.Map)\n\t}\n\tt.limits.Merge(ratelimit.FromResponse(response))\n\tt.mu.Unlock()\n\n\t_, _ = io.CopyN(io.Discard, response.Body, util.MaxDrainResponseBytes)\n\treturn success\n}\n\nfunc (t *AsyncTransport) isRateLimited(category ratelimit.Category) bool {\n\tt.mu.RLock()\n\tdefer t.mu.RUnlock()\n\tlimited := t.limits.IsRateLimited(category)\n\tif limited {\n\t\tdebuglog.Printf(\"Rate limited for category %q until %v\", category, t.limits.Deadline(category))\n\t}\n\treturn limited\n}\n\n// NoopTransport is a transport implementation that drops all events.\n// Used internally when an empty or invalid DSN is provided.\ntype NoopTransport struct{}\n\nfunc NewNoopTransport() *NoopTransport {\n\tdebuglog.Println(\"Transport initialized with invalid DSN. Using NoopTransport. No events will be delivered.\")\n\treturn &NoopTransport{}\n}\n\nfunc (t *NoopTransport) SendEnvelope(_ *protocol.Envelope) error {\n\tdebuglog.Println(\"Envelope dropped due to NoopTransport usage.\")\n\treturn nil\n}\n\nfunc (t *NoopTransport) IsRateLimited(_ ratelimit.Category) bool {\n\treturn false\n}\n\nfunc (t *NoopTransport) Flush(_ time.Duration) bool {\n\treturn true\n}\n\nfunc (t *NoopTransport) FlushWithContext(_ context.Context) bool {\n\treturn true\n}\n\nfunc (t *NoopTransport) Close() {\n\t// Nothing to close\n}\n\nfunc (t *NoopTransport) HasCapacity() bool { return true }\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/otel/baggage/README.md",
    "content": "## Why do we have this \"otel/baggage\" folder?\n\nThe root sentry-go SDK (namely, the Dynamic Sampling functionality) needs an implementation of the [baggage spec](https://www.w3.org/TR/baggage/).\nFor that reason, we've taken the existing baggage implementation from the [opentelemetry-go](https://github.com/open-telemetry/opentelemetry-go/) repository, and fixed a few things that in our opinion were violating the specification.\n\nThese issues are:\n1. Baggage string value `one%20two` should be properly parsed as \"one two\"\n1. Baggage string value `one+two` should be parsed as \"one+two\"\n1. Go string value \"one two\" should be encoded as `one%20two` (percent encoding), and NOT as `one+two` (URL query encoding).\n1. Go string value \"1=1\" might be encoded as `1=1`, because the spec says: \"Note, value MAY contain any number of the equal sign (=) characters. Parsers MUST NOT assume that the equal sign is only used to separate key and value.\". `1%3D1` is also valid, but to simplify the implementation we're not doing it.\n\nChanges were made in this PR: https://github.com/getsentry/sentry-go/pull/568\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/otel/baggage/baggage.go",
    "content": "// Adapted from https://github.com/open-telemetry/opentelemetry-go/blob/c21b6b6bb31a2f74edd06e262f1690f3f6ea3d5c/baggage/baggage.go\n//\n// Copyright The OpenTelemetry Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage baggage\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"regexp\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"github.com/getsentry/sentry-go/internal/otel/baggage/internal/baggage\"\n)\n\nconst (\n\tmaxMembers               = 180\n\tmaxBytesPerMembers       = 4096\n\tmaxBytesPerBaggageString = 8192\n\n\tlistDelimiter     = \",\"\n\tkeyValueDelimiter = \"=\"\n\tpropertyDelimiter = \";\"\n\n\tkeyDef      = `([\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2E\\x30-\\x39\\x41-\\x5a\\x5e-\\x7a\\x7c\\x7e]+)`\n\tvalueDef    = `([\\x21\\x23-\\x2b\\x2d-\\x3a\\x3c-\\x5B\\x5D-\\x7e]*)`\n\tkeyValueDef = `\\s*` + keyDef + `\\s*` + keyValueDelimiter + `\\s*` + valueDef + `\\s*`\n)\n\nvar (\n\tkeyRe      = regexp.MustCompile(`^` + keyDef + `$`)\n\tvalueRe    = regexp.MustCompile(`^` + valueDef + `$`)\n\tpropertyRe = regexp.MustCompile(`^(?:\\s*` + keyDef + `\\s*|` + keyValueDef + `)$`)\n)\n\nvar (\n\terrInvalidKey      = errors.New(\"invalid key\")\n\terrInvalidValue    = errors.New(\"invalid value\")\n\terrInvalidProperty = errors.New(\"invalid baggage list-member property\")\n\terrInvalidMember   = errors.New(\"invalid baggage list-member\")\n\terrMemberNumber    = errors.New(\"too many list-members in baggage-string\")\n\terrMemberBytes     = errors.New(\"list-member too large\")\n\terrBaggageBytes    = errors.New(\"baggage-string too large\")\n)\n\n// Property is an additional metadata entry for a baggage list-member.\ntype Property struct {\n\tkey, value string\n\n\t// hasValue indicates if a zero-value value means the property does not\n\t// have a value or if it was the zero-value.\n\thasValue bool\n\n\t// hasData indicates whether the created property contains data or not.\n\t// Properties that do not contain data are invalid with no other check\n\t// required.\n\thasData bool\n}\n\n// NewKeyProperty returns a new Property for key.\n//\n// If key is invalid, an error will be returned.\nfunc NewKeyProperty(key string) (Property, error) {\n\tif !keyRe.MatchString(key) {\n\t\treturn newInvalidProperty(), fmt.Errorf(\"%w: %q\", errInvalidKey, key)\n\t}\n\n\tp := Property{key: key, hasData: true}\n\treturn p, nil\n}\n\n// NewKeyValueProperty returns a new Property for key with value.\n//\n// If key or value are invalid, an error will be returned.\nfunc NewKeyValueProperty(key, value string) (Property, error) {\n\tif !keyRe.MatchString(key) {\n\t\treturn newInvalidProperty(), fmt.Errorf(\"%w: %q\", errInvalidKey, key)\n\t}\n\tif !valueRe.MatchString(value) {\n\t\treturn newInvalidProperty(), fmt.Errorf(\"%w: %q\", errInvalidValue, value)\n\t}\n\n\tp := Property{\n\t\tkey:      key,\n\t\tvalue:    value,\n\t\thasValue: true,\n\t\thasData:  true,\n\t}\n\treturn p, nil\n}\n\nfunc newInvalidProperty() Property {\n\treturn Property{}\n}\n\n// parseProperty attempts to decode a Property from the passed string. It\n// returns an error if the input is invalid according to the W3C Baggage\n// specification.\nfunc parseProperty(property string) (Property, error) {\n\tif property == \"\" {\n\t\treturn newInvalidProperty(), nil\n\t}\n\n\tmatch := propertyRe.FindStringSubmatch(property)\n\tif len(match) != 4 {\n\t\treturn newInvalidProperty(), fmt.Errorf(\"%w: %q\", errInvalidProperty, property)\n\t}\n\n\tp := Property{hasData: true}\n\tif match[1] != \"\" {\n\t\tp.key = match[1]\n\t} else {\n\t\tp.key = match[2]\n\t\tp.value = match[3]\n\t\tp.hasValue = true\n\t}\n\n\treturn p, nil\n}\n\n// validate ensures p conforms to the W3C Baggage specification, returning an\n// error otherwise.\nfunc (p Property) validate() error {\n\terrFunc := func(err error) error {\n\t\treturn fmt.Errorf(\"invalid property: %w\", err)\n\t}\n\n\tif !p.hasData {\n\t\treturn errFunc(fmt.Errorf(\"%w: %q\", errInvalidProperty, p))\n\t}\n\n\tif !keyRe.MatchString(p.key) {\n\t\treturn errFunc(fmt.Errorf(\"%w: %q\", errInvalidKey, p.key))\n\t}\n\tif p.hasValue && !valueRe.MatchString(p.value) {\n\t\treturn errFunc(fmt.Errorf(\"%w: %q\", errInvalidValue, p.value))\n\t}\n\tif !p.hasValue && p.value != \"\" {\n\t\treturn errFunc(errors.New(\"inconsistent value\"))\n\t}\n\treturn nil\n}\n\n// Key returns the Property key.\nfunc (p Property) Key() string {\n\treturn p.key\n}\n\n// Value returns the Property value. Additionally, a boolean value is returned\n// indicating if the returned value is the empty if the Property has a value\n// that is empty or if the value is not set.\nfunc (p Property) Value() (string, bool) {\n\treturn p.value, p.hasValue\n}\n\n// String encodes Property into a string compliant with the W3C Baggage\n// specification.\nfunc (p Property) String() string {\n\tif p.hasValue {\n\t\treturn fmt.Sprintf(\"%s%s%v\", p.key, keyValueDelimiter, p.value)\n\t}\n\treturn p.key\n}\n\ntype properties []Property\n\nfunc fromInternalProperties(iProps []baggage.Property) properties {\n\tif len(iProps) == 0 {\n\t\treturn nil\n\t}\n\n\tprops := make(properties, len(iProps))\n\tfor i, p := range iProps {\n\t\tprops[i] = Property{\n\t\t\tkey:      p.Key,\n\t\t\tvalue:    p.Value,\n\t\t\thasValue: p.HasValue,\n\t\t}\n\t}\n\treturn props\n}\n\nfunc (p properties) asInternal() []baggage.Property {\n\tif len(p) == 0 {\n\t\treturn nil\n\t}\n\n\tiProps := make([]baggage.Property, len(p))\n\tfor i, prop := range p {\n\t\tiProps[i] = baggage.Property{\n\t\t\tKey:      prop.key,\n\t\t\tValue:    prop.value,\n\t\t\tHasValue: prop.hasValue,\n\t\t}\n\t}\n\treturn iProps\n}\n\nfunc (p properties) Copy() properties {\n\tif len(p) == 0 {\n\t\treturn nil\n\t}\n\n\tprops := make(properties, len(p))\n\tcopy(props, p)\n\treturn props\n}\n\n// validate ensures each Property in p conforms to the W3C Baggage\n// specification, returning an error otherwise.\nfunc (p properties) validate() error {\n\tfor _, prop := range p {\n\t\tif err := prop.validate(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// String encodes properties into a string compliant with the W3C Baggage\n// specification.\nfunc (p properties) String() string {\n\tprops := make([]string, len(p))\n\tfor i, prop := range p {\n\t\tprops[i] = prop.String()\n\t}\n\treturn strings.Join(props, propertyDelimiter)\n}\n\n// Member is a list-member of a baggage-string as defined by the W3C Baggage\n// specification.\ntype Member struct {\n\tkey, value string\n\tproperties properties\n\n\t// hasData indicates whether the created property contains data or not.\n\t// Properties that do not contain data are invalid with no other check\n\t// required.\n\thasData bool\n}\n\n// NewMember returns a new Member from the passed arguments. The key will be\n// used directly while the value will be url decoded after validation. An error\n// is returned if the created Member would be invalid according to the W3C\n// Baggage specification.\nfunc NewMember(key, value string, props ...Property) (Member, error) {\n\tm := Member{\n\t\tkey:        key,\n\t\tvalue:      value,\n\t\tproperties: properties(props).Copy(),\n\t\thasData:    true,\n\t}\n\tif err := m.validate(); err != nil {\n\t\treturn newInvalidMember(), err\n\t}\n\t//// NOTE(anton): I don't think we need to unescape here\n\t// decodedValue, err := url.PathUnescape(value)\n\t// if err != nil {\n\t// \treturn newInvalidMember(), fmt.Errorf(\"%w: %q\", errInvalidValue, value)\n\t// }\n\t// m.value = decodedValue\n\treturn m, nil\n}\n\nfunc newInvalidMember() Member {\n\treturn Member{}\n}\n\n// parseMember attempts to decode a Member from the passed string. It returns\n// an error if the input is invalid according to the W3C Baggage\n// specification.\nfunc parseMember(member string) (Member, error) {\n\tif n := len(member); n > maxBytesPerMembers {\n\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %d\", errMemberBytes, n)\n\t}\n\n\tvar (\n\t\tkey, value string\n\t\tprops      properties\n\t)\n\n\tparts := strings.SplitN(member, propertyDelimiter, 2)\n\tswitch len(parts) {\n\tcase 2:\n\t\t// Parse the member properties.\n\t\tfor _, pStr := range strings.Split(parts[1], propertyDelimiter) {\n\t\t\tp, err := parseProperty(pStr)\n\t\t\tif err != nil {\n\t\t\t\treturn newInvalidMember(), err\n\t\t\t}\n\t\t\tprops = append(props, p)\n\t\t}\n\t\tfallthrough\n\tcase 1:\n\t\t// Parse the member key/value pair.\n\n\t\t// Take into account a value can contain equal signs (=).\n\t\tkv := strings.SplitN(parts[0], keyValueDelimiter, 2)\n\t\tif len(kv) != 2 {\n\t\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %q\", errInvalidMember, member)\n\t\t}\n\t\t// \"Leading and trailing whitespaces are allowed but MUST be trimmed\n\t\t// when converting the header into a data structure.\"\n\t\tkey = strings.TrimSpace(kv[0])\n\t\tvalue = strings.TrimSpace(kv[1])\n\t\tvar err error\n\t\tif !keyRe.MatchString(key) {\n\t\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %q\", errInvalidKey, key)\n\t\t}\n\t\tif !valueRe.MatchString(value) {\n\t\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %q\", errInvalidValue, value)\n\t\t}\n\t\tdecodedValue, err := url.PathUnescape(value)\n\t\tif err != nil {\n\t\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %q\", err, value)\n\t\t}\n\t\tvalue = decodedValue\n\tdefault:\n\t\t// This should never happen unless a developer has changed the string\n\t\t// splitting somehow. Panic instead of failing silently and allowing\n\t\t// the bug to slip past the CI checks.\n\t\tpanic(\"failed to parse baggage member\")\n\t}\n\n\treturn Member{key: key, value: value, properties: props, hasData: true}, nil\n}\n\n// validate ensures m conforms to the W3C Baggage specification.\n// A key is just an ASCII string, but a value must be URL encoded UTF-8,\n// returning an error otherwise.\nfunc (m Member) validate() error {\n\tif !m.hasData {\n\t\treturn fmt.Errorf(\"%w: %q\", errInvalidMember, m)\n\t}\n\n\tif !keyRe.MatchString(m.key) {\n\t\treturn fmt.Errorf(\"%w: %q\", errInvalidKey, m.key)\n\t}\n\t//// NOTE(anton): IMO it's too early to validate the value here.\n\t// if !valueRe.MatchString(m.value) {\n\t// \treturn fmt.Errorf(\"%w: %q\", errInvalidValue, m.value)\n\t// }\n\treturn m.properties.validate()\n}\n\n// Key returns the Member key.\nfunc (m Member) Key() string { return m.key }\n\n// Value returns the Member value.\nfunc (m Member) Value() string { return m.value }\n\n// Properties returns a copy of the Member properties.\nfunc (m Member) Properties() []Property { return m.properties.Copy() }\n\n// String encodes Member into a string compliant with the W3C Baggage\n// specification.\nfunc (m Member) String() string {\n\t// A key is just an ASCII string, but a value is URL encoded UTF-8.\n\ts := fmt.Sprintf(\"%s%s%s\", m.key, keyValueDelimiter, percentEncodeValue(m.value))\n\tif len(m.properties) > 0 {\n\t\ts = fmt.Sprintf(\"%s%s%s\", s, propertyDelimiter, m.properties.String())\n\t}\n\treturn s\n}\n\n// percentEncodeValue encodes the baggage value, using percent-encoding for\n// disallowed octets.\nfunc percentEncodeValue(s string) string {\n\tconst upperhex = \"0123456789ABCDEF\"\n\tvar sb strings.Builder\n\n\tfor byteIndex, width := 0, 0; byteIndex < len(s); byteIndex += width {\n\t\truneValue, w := utf8.DecodeRuneInString(s[byteIndex:])\n\t\twidth = w\n\t\tchar := string(runeValue)\n\t\tif valueRe.MatchString(char) && char != \"%\" {\n\t\t\t// The character is returned as is, no need to percent-encode\n\t\t\tsb.WriteString(char)\n\t\t} else {\n\t\t\t// We need to percent-encode each byte of the multi-octet character\n\t\t\tfor j := 0; j < width; j++ {\n\t\t\t\tb := s[byteIndex+j]\n\t\t\t\tsb.WriteByte('%')\n\t\t\t\t// Bitwise operations are inspired by \"net/url\"\n\t\t\t\tsb.WriteByte(upperhex[b>>4])\n\t\t\t\tsb.WriteByte(upperhex[b&15])\n\t\t\t}\n\t\t}\n\t}\n\treturn sb.String()\n}\n\n// Baggage is a list of baggage members representing the baggage-string as\n// defined by the W3C Baggage specification.\ntype Baggage struct { //nolint:golint\n\tlist baggage.List\n}\n\n// New returns a new valid Baggage. It returns an error if it results in a\n// Baggage exceeding limits set in that specification.\n//\n// It expects all the provided members to have already been validated.\nfunc New(members ...Member) (Baggage, error) {\n\tif len(members) == 0 {\n\t\treturn Baggage{}, nil\n\t}\n\n\tb := make(baggage.List)\n\tfor _, m := range members {\n\t\tif !m.hasData {\n\t\t\treturn Baggage{}, errInvalidMember\n\t\t}\n\n\t\t// OpenTelemetry resolves duplicates by last-one-wins.\n\t\tb[m.key] = baggage.Item{\n\t\t\tValue:      m.value,\n\t\t\tProperties: m.properties.asInternal(),\n\t\t}\n\t}\n\n\t// Check member numbers after deduplication.\n\tif len(b) > maxMembers {\n\t\treturn Baggage{}, errMemberNumber\n\t}\n\n\tbag := Baggage{b}\n\tif n := len(bag.String()); n > maxBytesPerBaggageString {\n\t\treturn Baggage{}, fmt.Errorf(\"%w: %d\", errBaggageBytes, n)\n\t}\n\n\treturn bag, nil\n}\n\n// Parse attempts to decode a baggage-string from the passed string. It\n// returns an error if the input is invalid according to the W3C Baggage\n// specification.\n//\n// If there are duplicate list-members contained in baggage, the last one\n// defined (reading left-to-right) will be the only one kept. This diverges\n// from the W3C Baggage specification which allows duplicate list-members, but\n// conforms to the OpenTelemetry Baggage specification.\nfunc Parse(bStr string) (Baggage, error) {\n\tif bStr == \"\" {\n\t\treturn Baggage{}, nil\n\t}\n\n\tif n := len(bStr); n > maxBytesPerBaggageString {\n\t\treturn Baggage{}, fmt.Errorf(\"%w: %d\", errBaggageBytes, n)\n\t}\n\n\tb := make(baggage.List)\n\tfor _, memberStr := range strings.Split(bStr, listDelimiter) {\n\t\tm, err := parseMember(memberStr)\n\t\tif err != nil {\n\t\t\treturn Baggage{}, err\n\t\t}\n\t\t// OpenTelemetry resolves duplicates by last-one-wins.\n\t\tb[m.key] = baggage.Item{\n\t\t\tValue:      m.value,\n\t\t\tProperties: m.properties.asInternal(),\n\t\t}\n\t}\n\n\t// OpenTelemetry does not allow for duplicate list-members, but the W3C\n\t// specification does. Now that we have deduplicated, ensure the baggage\n\t// does not exceed list-member limits.\n\tif len(b) > maxMembers {\n\t\treturn Baggage{}, errMemberNumber\n\t}\n\n\treturn Baggage{b}, nil\n}\n\n// Member returns the baggage list-member identified by key.\n//\n// If there is no list-member matching the passed key the returned Member will\n// be a zero-value Member.\n// The returned member is not validated, as we assume the validation happened\n// when it was added to the Baggage.\nfunc (b Baggage) Member(key string) Member {\n\tv, ok := b.list[key]\n\tif !ok {\n\t\t// We do not need to worry about distinguishing between the situation\n\t\t// where a zero-valued Member is included in the Baggage because a\n\t\t// zero-valued Member is invalid according to the W3C Baggage\n\t\t// specification (it has an empty key).\n\t\treturn newInvalidMember()\n\t}\n\n\treturn Member{\n\t\tkey:        key,\n\t\tvalue:      v.Value,\n\t\tproperties: fromInternalProperties(v.Properties),\n\t\thasData:    true,\n\t}\n}\n\n// Members returns all the baggage list-members.\n// The order of the returned list-members does not have significance.\n//\n// The returned members are not validated, as we assume the validation happened\n// when they were added to the Baggage.\nfunc (b Baggage) Members() []Member {\n\tif len(b.list) == 0 {\n\t\treturn nil\n\t}\n\n\tmembers := make([]Member, 0, len(b.list))\n\tfor k, v := range b.list {\n\t\tmembers = append(members, Member{\n\t\t\tkey:        k,\n\t\t\tvalue:      v.Value,\n\t\t\tproperties: fromInternalProperties(v.Properties),\n\t\t\thasData:    true,\n\t\t})\n\t}\n\treturn members\n}\n\n// SetMember returns a copy the Baggage with the member included. If the\n// baggage contains a Member with the same key the existing Member is\n// replaced.\n//\n// If member is invalid according to the W3C Baggage specification, an error\n// is returned with the original Baggage.\nfunc (b Baggage) SetMember(member Member) (Baggage, error) {\n\tif !member.hasData {\n\t\treturn b, errInvalidMember\n\t}\n\n\tn := len(b.list)\n\tif _, ok := b.list[member.key]; !ok {\n\t\tn++\n\t}\n\tlist := make(baggage.List, n)\n\n\tfor k, v := range b.list {\n\t\t// Do not copy if we are just going to overwrite.\n\t\tif k == member.key {\n\t\t\tcontinue\n\t\t}\n\t\tlist[k] = v\n\t}\n\n\tlist[member.key] = baggage.Item{\n\t\tValue:      member.value,\n\t\tProperties: member.properties.asInternal(),\n\t}\n\n\treturn Baggage{list: list}, nil\n}\n\n// DeleteMember returns a copy of the Baggage with the list-member identified\n// by key removed.\nfunc (b Baggage) DeleteMember(key string) Baggage {\n\tn := len(b.list)\n\tif _, ok := b.list[key]; ok {\n\t\tn--\n\t}\n\tlist := make(baggage.List, n)\n\n\tfor k, v := range b.list {\n\t\tif k == key {\n\t\t\tcontinue\n\t\t}\n\t\tlist[k] = v\n\t}\n\n\treturn Baggage{list: list}\n}\n\n// Len returns the number of list-members in the Baggage.\nfunc (b Baggage) Len() int {\n\treturn len(b.list)\n}\n\n// String encodes Baggage into a string compliant with the W3C Baggage\n// specification. The returned string will be invalid if the Baggage contains\n// any invalid list-members.\nfunc (b Baggage) String() string {\n\tmembers := make([]string, 0, len(b.list))\n\tfor k, v := range b.list {\n\t\tmembers = append(members, Member{\n\t\t\tkey:        k,\n\t\t\tvalue:      v.Value,\n\t\t\tproperties: fromInternalProperties(v.Properties),\n\t\t}.String())\n\t}\n\treturn strings.Join(members, listDelimiter)\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/otel/baggage/internal/baggage/baggage.go",
    "content": "// Adapted from https://github.com/open-telemetry/opentelemetry-go/blob/c21b6b6bb31a2f74edd06e262f1690f3f6ea3d5c/internal/baggage/baggage.go\n//\n// Copyright The OpenTelemetry Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n/*\nPackage baggage provides base types and functionality to store and retrieve\nbaggage in Go context. This package exists because the OpenTracing bridge to\nOpenTelemetry needs to synchronize state whenever baggage for a context is\nmodified and that context contains an OpenTracing span. If it were not for\nthis need this package would not need to exist and the\n`go.opentelemetry.io/otel/baggage` package would be the singular place where\nW3C baggage is handled.\n*/\npackage baggage\n\n// List is the collection of baggage members. The W3C allows for duplicates,\n// but OpenTelemetry does not, therefore, this is represented as a map.\ntype List map[string]Item\n\n// Item is the value and metadata properties part of a list-member.\ntype Item struct {\n\tValue      string\n\tProperties []Property\n}\n\n// Property is a metadata entry for a list-member.\ntype Property struct {\n\tKey, Value string\n\n\t// HasValue indicates if a zero-value value means the property does not\n\t// have a value or if it was the zero-value.\n\tHasValue bool\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/protocol/dsn.go",
    "content": "package protocol\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\n// apiVersion is the version of the Sentry API.\nconst apiVersion = \"7\"\n\ntype scheme string\n\nconst (\n\tSchemeHTTP  scheme = \"http\"\n\tSchemeHTTPS scheme = \"https\"\n)\n\nfunc (scheme scheme) defaultPort() int {\n\tswitch scheme {\n\tcase SchemeHTTPS:\n\t\treturn 443\n\tcase SchemeHTTP:\n\t\treturn 80\n\tdefault:\n\t\treturn 80\n\t}\n}\n\n// DsnParseError represents an error that occurs if a Sentry\n// DSN cannot be parsed.\ntype DsnParseError struct {\n\tMessage string\n}\n\nfunc (e DsnParseError) Error() string {\n\treturn \"[Sentry] DsnParseError: \" + e.Message\n}\n\n// Dsn is used as the remote address source to client transport.\ntype Dsn struct {\n\tscheme    scheme\n\tpublicKey string\n\tsecretKey string\n\thost      string\n\tport      int\n\tpath      string\n\tprojectID string\n}\n\n// NewDsn creates a Dsn by parsing rawURL. Most users will never call this\n// function directly. It is provided for use in custom Transport\n// implementations.\nfunc NewDsn(rawURL string) (*Dsn, error) {\n\t// Parse\n\tparsedURL, err := url.Parse(rawURL)\n\tif err != nil {\n\t\treturn nil, &DsnParseError{fmt.Sprintf(\"invalid url: %v\", err)}\n\t}\n\n\t// Scheme\n\tvar scheme scheme\n\tswitch parsedURL.Scheme {\n\tcase \"http\":\n\t\tscheme = SchemeHTTP\n\tcase \"https\":\n\t\tscheme = SchemeHTTPS\n\tdefault:\n\t\treturn nil, &DsnParseError{\"invalid scheme\"}\n\t}\n\n\t// PublicKey\n\tpublicKey := parsedURL.User.Username()\n\tif publicKey == \"\" {\n\t\treturn nil, &DsnParseError{\"empty username\"}\n\t}\n\n\t// SecretKey\n\tvar secretKey string\n\tif parsedSecretKey, ok := parsedURL.User.Password(); ok {\n\t\tsecretKey = parsedSecretKey\n\t}\n\n\t// Host\n\thost := parsedURL.Hostname()\n\tif host == \"\" {\n\t\treturn nil, &DsnParseError{\"empty host\"}\n\t}\n\n\t// Port\n\tvar port int\n\tif p := parsedURL.Port(); p != \"\" {\n\t\tport, err = strconv.Atoi(p)\n\t\tif err != nil {\n\t\t\treturn nil, &DsnParseError{\"invalid port\"}\n\t\t}\n\t} else {\n\t\tport = scheme.defaultPort()\n\t}\n\n\t// ProjectID\n\tif parsedURL.Path == \"\" || parsedURL.Path == \"/\" {\n\t\treturn nil, &DsnParseError{\"empty project id\"}\n\t}\n\tpathSegments := strings.Split(parsedURL.Path[1:], \"/\")\n\tprojectID := pathSegments[len(pathSegments)-1]\n\n\tif projectID == \"\" {\n\t\treturn nil, &DsnParseError{\"empty project id\"}\n\t}\n\n\t// Path\n\tvar path string\n\tif len(pathSegments) > 1 {\n\t\tpath = \"/\" + strings.Join(pathSegments[0:len(pathSegments)-1], \"/\")\n\t}\n\n\treturn &Dsn{\n\t\tscheme:    scheme,\n\t\tpublicKey: publicKey,\n\t\tsecretKey: secretKey,\n\t\thost:      host,\n\t\tport:      port,\n\t\tpath:      path,\n\t\tprojectID: projectID,\n\t}, nil\n}\n\n// String formats Dsn struct into a valid string url.\nfunc (dsn Dsn) String() string {\n\tvar url string\n\turl += fmt.Sprintf(\"%s://%s\", dsn.scheme, dsn.publicKey)\n\tif dsn.secretKey != \"\" {\n\t\turl += fmt.Sprintf(\":%s\", dsn.secretKey)\n\t}\n\turl += fmt.Sprintf(\"@%s\", dsn.host)\n\tif dsn.port != dsn.scheme.defaultPort() {\n\t\turl += fmt.Sprintf(\":%d\", dsn.port)\n\t}\n\tif dsn.path != \"\" {\n\t\turl += dsn.path\n\t}\n\turl += fmt.Sprintf(\"/%s\", dsn.projectID)\n\treturn url\n}\n\n// Get the scheme of the DSN.\nfunc (dsn Dsn) GetScheme() string {\n\treturn string(dsn.scheme)\n}\n\n// Get the public key of the DSN.\nfunc (dsn Dsn) GetPublicKey() string {\n\treturn dsn.publicKey\n}\n\n// Get the secret key of the DSN.\nfunc (dsn Dsn) GetSecretKey() string {\n\treturn dsn.secretKey\n}\n\n// Get the host of the DSN.\nfunc (dsn Dsn) GetHost() string {\n\treturn dsn.host\n}\n\n// Get the port of the DSN.\nfunc (dsn Dsn) GetPort() int {\n\treturn dsn.port\n}\n\n// Get the path of the DSN.\nfunc (dsn Dsn) GetPath() string {\n\treturn dsn.path\n}\n\n// Get the project ID of the DSN.\nfunc (dsn Dsn) GetProjectID() string {\n\treturn dsn.projectID\n}\n\n// GetAPIURL returns the URL of the envelope endpoint of the project\n// associated with the DSN.\nfunc (dsn Dsn) GetAPIURL() *url.URL {\n\tvar rawURL string\n\trawURL += fmt.Sprintf(\"%s://%s\", dsn.scheme, dsn.host)\n\tif dsn.port != dsn.scheme.defaultPort() {\n\t\trawURL += fmt.Sprintf(\":%d\", dsn.port)\n\t}\n\tif dsn.path != \"\" {\n\t\trawURL += dsn.path\n\t}\n\trawURL += fmt.Sprintf(\"/api/%s/%s/\", dsn.projectID, \"envelope\")\n\tparsedURL, _ := url.Parse(rawURL)\n\treturn parsedURL\n}\n\n// RequestHeaders returns all the necessary headers that have to be used in the transport when sending events\n// to the /store endpoint.\n//\n// Deprecated: This method shall only be used if you want to implement your own transport that sends events to\n// the /store endpoint. If you're using the transport provided by the SDK, all necessary headers to authenticate\n// against the /envelope endpoint are added automatically.\nfunc (dsn Dsn) RequestHeaders(sdkVersion string) map[string]string {\n\tauth := fmt.Sprintf(\"Sentry sentry_version=%s, sentry_timestamp=%d, \"+\n\t\t\"sentry_client=sentry.go/%s, sentry_key=%s\", apiVersion, time.Now().Unix(), sdkVersion, dsn.publicKey)\n\n\tif dsn.secretKey != \"\" {\n\t\tauth = fmt.Sprintf(\"%s, sentry_secret=%s\", auth, dsn.secretKey)\n\t}\n\n\treturn map[string]string{\n\t\t\"Content-Type\":  \"application/json\",\n\t\t\"X-Sentry-Auth\": auth,\n\t}\n}\n\n// MarshalJSON converts the Dsn struct to JSON.\nfunc (dsn Dsn) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(dsn.String())\n}\n\n// UnmarshalJSON converts JSON data to the Dsn struct.\nfunc (dsn *Dsn) UnmarshalJSON(data []byte) error {\n\tvar str string\n\t_ = json.Unmarshal(data, &str)\n\tnewDsn, err := NewDsn(str)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*dsn = *newDsn\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/protocol/envelope.go",
    "content": "package protocol\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"time\"\n)\n\n// Envelope represents a Sentry envelope containing headers and items.\ntype Envelope struct {\n\tHeader *EnvelopeHeader `json:\"-\"`\n\tItems  []*EnvelopeItem `json:\"-\"`\n}\n\n// EnvelopeHeader represents the header of a Sentry envelope.\ntype EnvelopeHeader struct {\n\t// EventID is the unique identifier for this event\n\tEventID string `json:\"event_id\"`\n\n\t// SentAt is the timestamp when the event was sent from the SDK as string in RFC 3339 format.\n\t// Used for clock drift correction of the event timestamp. The time zone must be UTC.\n\tSentAt time.Time `json:\"sent_at,omitzero\"`\n\n\t// Dsn can be used for self-authenticated envelopes.\n\t// This means that the envelope has all the information necessary to be sent to sentry.\n\t// In this case the full DSN must be stored in this key.\n\tDsn string `json:\"dsn,omitempty\"`\n\n\t// Sdk carries the same payload as the sdk interface in the event payload but can be carried for all events.\n\t// This means that SDK information can be carried for minidumps, session data and other submissions.\n\tSdk *SdkInfo `json:\"sdk,omitempty\"`\n\n\t// Trace contains the [Dynamic Sampling Context](https://develop.sentry.dev/sdk/telemetry/traces/dynamic-sampling-context/)\n\tTrace map[string]string `json:\"trace,omitempty\"`\n}\n\n// EnvelopeItemType represents the type of envelope item.\ntype EnvelopeItemType string\n\n// Constants for envelope item types as defined in the Sentry documentation.\nconst (\n\tEnvelopeItemTypeEvent       EnvelopeItemType = \"event\"\n\tEnvelopeItemTypeTransaction EnvelopeItemType = \"transaction\"\n\tEnvelopeItemTypeCheckIn     EnvelopeItemType = \"check_in\"\n\tEnvelopeItemTypeAttachment  EnvelopeItemType = \"attachment\"\n\tEnvelopeItemTypeLog         EnvelopeItemType = \"log\"\n\tEnvelopeItemTypeTraceMetric EnvelopeItemType = \"trace_metric\"\n)\n\n// EnvelopeItemHeader represents the header of an envelope item.\ntype EnvelopeItemHeader struct {\n\t// Type specifies the type of this Item and its contents.\n\t// Based on the Item type, more headers may be required.\n\tType EnvelopeItemType `json:\"type\"`\n\n\t// Length is the length of the payload in bytes.\n\t// If no length is specified, the payload implicitly goes to the next newline.\n\t// For payloads containing newline characters, the length must be specified.\n\tLength *int `json:\"length,omitempty\"`\n\n\t// Filename is the name of the attachment file (used for attachments)\n\tFilename string `json:\"filename,omitempty\"`\n\n\t// ContentType is the MIME type of the item payload (used for attachments and some other item types)\n\tContentType string `json:\"content_type,omitempty\"`\n\n\t// ItemCount is the number of items in a batch (used for logs)\n\tItemCount *int `json:\"item_count,omitempty\"`\n}\n\n// EnvelopeItem represents a single item or batch within an envelope.\ntype EnvelopeItem struct {\n\tHeader  *EnvelopeItemHeader `json:\"-\"`\n\tPayload []byte              `json:\"-\"`\n}\n\n// NewEnvelope creates a new envelope with the given header.\nfunc NewEnvelope(header *EnvelopeHeader) *Envelope {\n\treturn &Envelope{\n\t\tHeader: header,\n\t\tItems:  make([]*EnvelopeItem, 0),\n\t}\n}\n\n// AddItem adds an item to the envelope.\nfunc (e *Envelope) AddItem(item *EnvelopeItem) {\n\tif item == nil {\n\t\treturn\n\t}\n\te.Items = append(e.Items, item)\n}\n\n// Serialize serializes the envelope to the Sentry envelope format.\n//\n// Format: Headers \"\\n\" { Item } [ \"\\n\" ]\n// Item: Headers \"\\n\" Payload \"\\n\".\nfunc (e *Envelope) Serialize() ([]byte, error) {\n\tvar buf bytes.Buffer\n\n\theaderBytes, err := json.Marshal(e.Header)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to marshal envelope header: %w\", err)\n\t}\n\n\tif _, err := buf.Write(headerBytes); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to write envelope header: %w\", err)\n\t}\n\n\tif _, err := buf.WriteString(\"\\n\"); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to write newline after envelope header: %w\", err)\n\t}\n\n\tfor _, item := range e.Items {\n\t\tif err := e.writeItem(&buf, item); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to write envelope item: %w\", err)\n\t\t}\n\t}\n\n\treturn buf.Bytes(), nil\n}\n\n// WriteTo writes the envelope to the given writer in the Sentry envelope format.\nfunc (e *Envelope) WriteTo(w io.Writer) (int64, error) {\n\tdata, err := e.Serialize()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tn, err := w.Write(data)\n\treturn int64(n), err\n}\n\n// writeItem writes a single envelope item to the buffer.\nfunc (e *Envelope) writeItem(buf *bytes.Buffer, item *EnvelopeItem) error {\n\theaderBytes, err := json.Marshal(item.Header)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to marshal item header: %w\", err)\n\t}\n\n\tif _, err := buf.Write(headerBytes); err != nil {\n\t\treturn fmt.Errorf(\"failed to write item header: %w\", err)\n\t}\n\n\tif _, err := buf.WriteString(\"\\n\"); err != nil {\n\t\treturn fmt.Errorf(\"failed to write newline after item header: %w\", err)\n\t}\n\n\tif len(item.Payload) > 0 {\n\t\tif _, err := buf.Write(item.Payload); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to write item payload: %w\", err)\n\t\t}\n\t}\n\n\tif _, err := buf.WriteString(\"\\n\"); err != nil {\n\t\treturn fmt.Errorf(\"failed to write newline after item payload: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// Size returns the total size of the envelope when serialized.\nfunc (e *Envelope) Size() (int, error) {\n\tdata, err := e.Serialize()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn len(data), nil\n}\n\n// NewEnvelopeItem creates a new envelope item with the specified type and payload.\nfunc NewEnvelopeItem(itemType EnvelopeItemType, payload []byte) *EnvelopeItem {\n\tlength := len(payload)\n\treturn &EnvelopeItem{\n\t\tHeader: &EnvelopeItemHeader{\n\t\t\tType:   itemType,\n\t\t\tLength: &length,\n\t\t},\n\t\tPayload: payload,\n\t}\n}\n\n// NewAttachmentItem creates a new envelope item for an attachment.\n// Parameters: filename, contentType, payload.\nfunc NewAttachmentItem(filename, contentType string, payload []byte) *EnvelopeItem {\n\tlength := len(payload)\n\treturn &EnvelopeItem{\n\t\tHeader: &EnvelopeItemHeader{\n\t\t\tType:        EnvelopeItemTypeAttachment,\n\t\t\tLength:      &length,\n\t\t\tContentType: contentType,\n\t\t\tFilename:    filename,\n\t\t},\n\t\tPayload: payload,\n\t}\n}\n\n// NewLogItem creates a new envelope item for logs.\nfunc NewLogItem(itemCount int, payload []byte) *EnvelopeItem {\n\tlength := len(payload)\n\treturn &EnvelopeItem{\n\t\tHeader: &EnvelopeItemHeader{\n\t\t\tType:        EnvelopeItemTypeLog,\n\t\t\tLength:      &length,\n\t\t\tItemCount:   &itemCount,\n\t\t\tContentType: \"application/vnd.sentry.items.log+json\",\n\t\t},\n\t\tPayload: payload,\n\t}\n}\n\n// NewTraceMetricItem creates a new envelope item for trace metrics.\nfunc NewTraceMetricItem(itemCount int, payload []byte) *EnvelopeItem {\n\tlength := len(payload)\n\treturn &EnvelopeItem{\n\t\tHeader: &EnvelopeItemHeader{\n\t\t\tType:        EnvelopeItemTypeTraceMetric,\n\t\t\tLength:      &length,\n\t\t\tItemCount:   &itemCount,\n\t\t\tContentType: \"application/vnd.sentry.items.trace-metric+json\",\n\t\t},\n\t\tPayload: payload,\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/protocol/interfaces.go",
    "content": "package protocol\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go/internal/ratelimit\"\n)\n\n// TelemetryItem represents any telemetry data that can be stored in buffers and sent to Sentry.\n// This is the base interface that all telemetry items must implement.\ntype TelemetryItem interface {\n\t// GetCategory returns the rate limit category for this item.\n\tGetCategory() ratelimit.Category\n\n\t// GetEventID returns the event ID for this item.\n\tGetEventID() string\n\n\t// GetSdkInfo returns SDK information for the envelope header.\n\tGetSdkInfo() *SdkInfo\n\n\t// GetDynamicSamplingContext returns trace context for the envelope header.\n\tGetDynamicSamplingContext() map[string]string\n}\n\n// EnvelopeItemConvertible represents items that can be converted directly to envelope items.\ntype EnvelopeItemConvertible interface {\n\tTelemetryItem\n\n\t// ToEnvelopeItem converts the item to a Sentry envelope item.\n\tToEnvelopeItem() (*EnvelopeItem, error)\n}\n\n// TelemetryTransport represents the envelope-first transport interface.\n// This interface is designed for the telemetry buffer system and provides\n// non-blocking sends with backpressure signals.\ntype TelemetryTransport interface {\n\t// SendEnvelope sends an envelope to Sentry. Returns immediately with\n\t// backpressure error if the queue is full.\n\tSendEnvelope(envelope *Envelope) error\n\n\t// HasCapacity reports whether the transport has capacity to accept at least one more envelope.\n\tHasCapacity() bool\n\n\t// IsRateLimited checks if a specific category is currently rate limited\n\tIsRateLimited(category ratelimit.Category) bool\n\n\t// Flush waits for all pending envelopes to be sent, with timeout\n\tFlush(timeout time.Duration) bool\n\n\t// FlushWithContext waits for all pending envelopes to be sent\n\tFlushWithContext(ctx context.Context) bool\n\n\t// Close shuts down the transport gracefully\n\tClose()\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/protocol/log_batch.go",
    "content": "package protocol\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/getsentry/sentry-go/internal/ratelimit\"\n)\n\n// LogAttribute is the JSON representation for a single log attribute value.\ntype LogAttribute struct {\n\tValue any    `json:\"value\"`\n\tType  string `json:\"type\"`\n}\n\n// Logs is a container for multiple log items which knows how to convert\n// itself into a single batched log envelope item.\ntype Logs []TelemetryItem\n\nfunc (ls Logs) ToEnvelopeItem() (*EnvelopeItem, error) {\n\t// Convert each log to its JSON representation\n\titems := make([]json.RawMessage, 0, len(ls))\n\tfor _, log := range ls {\n\t\tlogPayload, err := json.Marshal(log)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\titems = append(items, logPayload)\n\t}\n\n\tif len(items) == 0 {\n\t\treturn nil, nil\n\t}\n\n\twrapper := struct {\n\t\tItems []json.RawMessage `json:\"items\"`\n\t}{Items: items}\n\n\tpayload, err := json.Marshal(wrapper)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn NewLogItem(len(ls), payload), nil\n}\n\nfunc (Logs) GetCategory() ratelimit.Category              { return ratelimit.CategoryLog }\nfunc (Logs) GetEventID() string                           { return \"\" }\nfunc (Logs) GetSdkInfo() *SdkInfo                         { return nil }\nfunc (Logs) GetDynamicSamplingContext() map[string]string { return nil }\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/protocol/metric_batch.go",
    "content": "package protocol\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/getsentry/sentry-go/internal/ratelimit\"\n)\n\ntype Metrics []TelemetryItem\n\nfunc (ms Metrics) ToEnvelopeItem() (*EnvelopeItem, error) {\n\t// Convert each metric to its JSON representation\n\titems := make([]json.RawMessage, 0, len(ms))\n\tfor _, metric := range ms {\n\t\tmetricPayload, err := json.Marshal(metric)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\titems = append(items, metricPayload)\n\t}\n\n\tif len(items) == 0 {\n\t\treturn nil, nil\n\t}\n\n\twrapper := struct {\n\t\tItems []json.RawMessage `json:\"items\"`\n\t}{Items: items}\n\n\tpayload, err := json.Marshal(wrapper)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn NewTraceMetricItem(len(items), payload), nil\n}\n\nfunc (Metrics) GetCategory() ratelimit.Category              { return ratelimit.CategoryTraceMetric }\nfunc (Metrics) GetEventID() string                           { return \"\" }\nfunc (Metrics) GetSdkInfo() *SdkInfo                         { return nil }\nfunc (Metrics) GetDynamicSamplingContext() map[string]string { return nil }\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/protocol/types.go",
    "content": "package protocol\n\n// SdkInfo contains SDK metadata.\ntype SdkInfo struct {\n\tName         string       `json:\"name,omitempty\"`\n\tVersion      string       `json:\"version,omitempty\"`\n\tIntegrations []string     `json:\"integrations,omitempty\"`\n\tPackages     []SdkPackage `json:\"packages,omitempty\"`\n}\n\n// SdkPackage describes a package that was installed.\ntype SdkPackage struct {\n\tName    string `json:\"name,omitempty\"`\n\tVersion string `json:\"version,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/protocol/uuid.go",
    "content": "package protocol\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/hex\"\n)\n\n// GenerateEventID generates a random UUID v4 for use as a Sentry event ID.\nfunc GenerateEventID() string {\n\tid := make([]byte, 16)\n\t// Prefer rand.Read over rand.Reader, see https://go-review.googlesource.com/c/go/+/272326/.\n\t_, _ = rand.Read(id)\n\tid[6] &= 0x0F // clear version\n\tid[6] |= 0x40 // set version to 4 (random uuid)\n\tid[8] &= 0x3F // clear variant\n\tid[8] |= 0x80 // set to IETF variant\n\treturn hex.EncodeToString(id)\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/ratelimit/category.go",
    "content": "package ratelimit\n\nimport (\n\t\"strings\"\n\n\t\"golang.org/x/text/cases\"\n\t\"golang.org/x/text/language\"\n)\n\n// Reference:\n// https://github.com/getsentry/relay/blob/46dfaa850b8717a6e22c3e9a275ba17fe673b9da/relay-base-schema/src/data_category.rs#L231-L271\n\n// Category classifies supported payload types that can be ingested by Sentry\n// and, therefore, rate limited.\ntype Category string\n\n// Known rate limit categories that are specified in rate limit headers.\nconst (\n\tCategoryUnknown     Category = \"unknown\" // Unknown category should not get rate limited\n\tCategoryAll         Category = \"\"        // Special category for empty categories (applies to all)\n\tCategoryError       Category = \"error\"\n\tCategoryTransaction Category = \"transaction\"\n\tCategoryLog         Category = \"log_item\"\n\tCategoryMonitor     Category = \"monitor\"\n\tCategoryTraceMetric Category = \"trace_metric\"\n)\n\n// knownCategories is the set of currently known categories. Other categories\n// are ignored for the purpose of rate-limiting.\nvar knownCategories = map[Category]struct{}{\n\tCategoryAll:         {},\n\tCategoryError:       {},\n\tCategoryTransaction: {},\n\tCategoryLog:         {},\n\tCategoryMonitor:     {},\n\tCategoryTraceMetric: {},\n}\n\n// String returns the category formatted for debugging.\nfunc (c Category) String() string {\n\tswitch c {\n\tcase CategoryAll:\n\t\treturn \"CategoryAll\"\n\tcase CategoryError:\n\t\treturn \"CategoryError\"\n\tcase CategoryTransaction:\n\t\treturn \"CategoryTransaction\"\n\tcase CategoryLog:\n\t\treturn \"CategoryLog\"\n\tcase CategoryMonitor:\n\t\treturn \"CategoryMonitor\"\n\tcase CategoryTraceMetric:\n\t\treturn \"CategoryTraceMetric\"\n\tdefault:\n\t\t// For unknown categories, use the original formatting logic\n\t\tcaser := cases.Title(language.English)\n\t\trv := \"Category\"\n\t\tfor _, w := range strings.Fields(string(c)) {\n\t\t\trv += caser.String(w)\n\t\t}\n\t\treturn rv\n\t}\n}\n\n// Priority represents the importance level of a category for buffer management.\ntype Priority int\n\nconst (\n\tPriorityCritical Priority = iota + 1\n\tPriorityHigh\n\tPriorityMedium\n\tPriorityLow\n\tPriorityLowest\n)\n\nfunc (p Priority) String() string {\n\tswitch p {\n\tcase PriorityCritical:\n\t\treturn \"critical\"\n\tcase PriorityHigh:\n\t\treturn \"high\"\n\tcase PriorityMedium:\n\t\treturn \"medium\"\n\tcase PriorityLow:\n\t\treturn \"low\"\n\tcase PriorityLowest:\n\t\treturn \"lowest\"\n\tdefault:\n\t\treturn \"unknown\"\n\t}\n}\n\n// GetPriority returns the priority level for this category.\nfunc (c Category) GetPriority() Priority {\n\tswitch c {\n\tcase CategoryError:\n\t\treturn PriorityCritical\n\tcase CategoryMonitor:\n\t\treturn PriorityHigh\n\tcase CategoryLog:\n\t\treturn PriorityLow\n\tcase CategoryTransaction:\n\t\treturn PriorityMedium\n\tcase CategoryTraceMetric:\n\t\treturn PriorityLow\n\tdefault:\n\t\treturn PriorityMedium\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/ratelimit/deadline.go",
    "content": "package ratelimit\n\nimport \"time\"\n\n// A Deadline is a time instant when a rate limit expires.\ntype Deadline time.Time\n\n// After reports whether the deadline d is after other.\nfunc (d Deadline) After(other Deadline) bool {\n\treturn time.Time(d).After(time.Time(other))\n}\n\n// Equal reports whether d and e represent the same deadline.\nfunc (d Deadline) Equal(e Deadline) bool {\n\treturn time.Time(d).Equal(time.Time(e))\n}\n\n// String returns the deadline formatted for debugging.\nfunc (d Deadline) String() string {\n\t// Like time.Time.String, but without the monotonic clock reading.\n\treturn time.Time(d).Round(0).String()\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/ratelimit/doc.go",
    "content": "// Package ratelimit provides tools to work with rate limits imposed by Sentry's\n// data ingestion pipeline.\npackage ratelimit\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/ratelimit/map.go",
    "content": "package ratelimit\n\nimport (\n\t\"net/http\"\n\t\"time\"\n)\n\n// Map maps categories to rate limit deadlines.\n//\n// A rate limit is in effect for a given category if either the category's\n// deadline or the deadline for the special CategoryAll has not yet expired.\n//\n// Use IsRateLimited to check whether a category is rate-limited.\ntype Map map[Category]Deadline\n\n// IsRateLimited returns true if the category is currently rate limited.\nfunc (m Map) IsRateLimited(c Category) bool {\n\treturn m.isRateLimited(c, time.Now())\n}\n\nfunc (m Map) isRateLimited(c Category, now time.Time) bool {\n\treturn m.Deadline(c).After(Deadline(now))\n}\n\n// Deadline returns the deadline when the rate limit for the given category or\n// the special CategoryAll expire, whichever is furthest into the future.\nfunc (m Map) Deadline(c Category) Deadline {\n\tcategoryDeadline := m[c]\n\tallDeadline := m[CategoryAll]\n\tif categoryDeadline.After(allDeadline) {\n\t\treturn categoryDeadline\n\t}\n\treturn allDeadline\n}\n\n// Merge merges the other map into m.\n//\n// If a category appears in both maps, the deadline that is furthest into the\n// future is preserved.\nfunc (m Map) Merge(other Map) {\n\tfor c, d := range other {\n\t\tif d.After(m[c]) {\n\t\t\tm[c] = d\n\t\t}\n\t}\n}\n\n// FromResponse returns a rate limit map from an HTTP response.\nfunc FromResponse(r *http.Response) Map {\n\treturn fromResponse(r, time.Now())\n}\n\nfunc fromResponse(r *http.Response, now time.Time) Map {\n\ts := r.Header.Get(\"X-Sentry-Rate-Limits\")\n\tif s != \"\" {\n\t\treturn parseXSentryRateLimits(s, now)\n\t}\n\tif r.StatusCode == http.StatusTooManyRequests {\n\t\ts := r.Header.Get(\"Retry-After\")\n\t\tdeadline, _ := parseRetryAfter(s, now)\n\t\treturn Map{CategoryAll: deadline}\n\t}\n\treturn Map{}\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/ratelimit/rate_limits.go",
    "content": "package ratelimit\n\nimport (\n\t\"errors\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\nvar errInvalidXSRLRetryAfter = errors.New(\"invalid retry-after value\")\n\n// parseXSentryRateLimits returns a RateLimits map by parsing an input string in\n// the format of the X-Sentry-Rate-Limits header.\n//\n// Example\n//\n//\tX-Sentry-Rate-Limits: 60:transaction, 2700:default;error;security\n//\n// This will rate limit transactions for the next 60 seconds and errors for the\n// next 2700 seconds.\n//\n// Limits for unknown categories are ignored.\nfunc parseXSentryRateLimits(s string, now time.Time) Map {\n\t// https://github.com/getsentry/relay/blob/0424a2e017d193a93918053c90cdae9472d164bf/relay-server/src/utils/rate_limits.rs#L44-L82\n\tm := make(Map, len(knownCategories))\n\tfor _, limit := range strings.Split(s, \",\") {\n\t\tlimit = strings.TrimSpace(limit)\n\t\tif limit == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tcomponents := strings.Split(limit, \":\")\n\t\tif len(components) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tretryAfter, err := parseXSRLRetryAfter(strings.TrimSpace(components[0]), now)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tcategories := \"\"\n\t\tif len(components) > 1 {\n\t\t\tcategories = components[1]\n\t\t}\n\t\tfor _, category := range strings.Split(categories, \";\") {\n\t\t\tc := Category(strings.ToLower(strings.TrimSpace(category)))\n\t\t\tif _, ok := knownCategories[c]; !ok {\n\t\t\t\t// skip unknown categories, keep m small\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// always keep the deadline furthest into the future\n\t\t\tif retryAfter.After(m[c]) {\n\t\t\t\tm[c] = retryAfter\n\t\t\t}\n\t\t}\n\t}\n\treturn m\n}\n\n// parseXSRLRetryAfter parses a string into a retry-after rate limit deadline.\n//\n// Valid input is a number, possibly signed and possibly floating-point,\n// indicating the number of seconds to wait before sending another request.\n// Negative values are treated as zero. Fractional values are rounded to the\n// next integer.\nfunc parseXSRLRetryAfter(s string, now time.Time) (Deadline, error) {\n\t// https://github.com/getsentry/relay/blob/0424a2e017d193a93918053c90cdae9472d164bf/relay-quotas/src/rate_limit.rs#L88-L96\n\tf, err := strconv.ParseFloat(s, 64)\n\tif err != nil {\n\t\treturn Deadline{}, errInvalidXSRLRetryAfter\n\t}\n\td := time.Duration(math.Ceil(math.Max(f, 0.0))) * time.Second\n\tif d < 0 {\n\t\td = 0\n\t}\n\treturn Deadline(now.Add(d)), nil\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/ratelimit/retry_after.go",
    "content": "package ratelimit\n\nimport (\n\t\"errors\"\n\t\"strconv\"\n\t\"time\"\n)\n\nconst defaultRetryAfter = 1 * time.Minute\n\nvar errInvalidRetryAfter = errors.New(\"invalid input\")\n\n// parseRetryAfter parses a string s as in the standard Retry-After HTTP header\n// and returns a deadline until when requests are rate limited and therefore new\n// requests should not be sent. The input may be either a date or a non-negative\n// integer number of seconds.\n//\n// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After\n//\n// parseRetryAfter always returns a usable deadline, even in case of an error.\n//\n// This is the original rate limiting mechanism used by Sentry, superseeded by\n// the X-Sentry-Rate-Limits response header.\nfunc parseRetryAfter(s string, now time.Time) (Deadline, error) {\n\tif s == \"\" {\n\t\tgoto invalid\n\t}\n\tif n, err := strconv.Atoi(s); err == nil {\n\t\tif n < 0 {\n\t\t\tgoto invalid\n\t\t}\n\t\td := time.Duration(n) * time.Second\n\t\treturn Deadline(now.Add(d)), nil\n\t}\n\tif date, err := time.Parse(time.RFC1123, s); err == nil {\n\t\treturn Deadline(date), nil\n\t}\ninvalid:\n\treturn Deadline(now.Add(defaultRetryAfter)), errInvalidRetryAfter\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/telemetry/bucketed_buffer.go",
    "content": "package telemetry\n\nimport (\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go/internal/ratelimit\"\n)\n\nconst (\n\tdefaultBucketedCapacity = 100\n\tperBucketItemLimit      = 100\n)\n\ntype Bucket[T any] struct {\n\ttraceID       string\n\titems         []T\n\tcreatedAt     time.Time\n\tlastUpdatedAt time.Time\n}\n\n// BucketedBuffer groups items by trace id, flushing per bucket.\ntype BucketedBuffer[T any] struct {\n\tmu sync.RWMutex\n\n\tbuckets    []*Bucket[T]\n\ttraceIndex map[string]int\n\n\thead int\n\ttail int\n\n\titemCapacity   int\n\tbucketCapacity int\n\n\ttotalItems  int\n\tbucketCount int\n\n\tcategory       ratelimit.Category\n\tpriority       ratelimit.Priority\n\toverflowPolicy OverflowPolicy\n\tbatchSize      int\n\ttimeout        time.Duration\n\tlastFlushTime  time.Time\n\n\toffered   int64\n\tdropped   int64\n\tonDropped func(item T, reason string)\n}\n\nfunc NewBucketedBuffer[T any](\n\tcategory ratelimit.Category,\n\tcapacity int,\n\toverflowPolicy OverflowPolicy,\n\tbatchSize int,\n\ttimeout time.Duration,\n) *BucketedBuffer[T] {\n\tif capacity <= 0 {\n\t\tcapacity = defaultBucketedCapacity\n\t}\n\tif batchSize <= 0 {\n\t\tbatchSize = 1\n\t}\n\tif timeout < 0 {\n\t\ttimeout = 0\n\t}\n\n\tbucketCapacity := capacity / 10\n\tif bucketCapacity < 10 {\n\t\tbucketCapacity = 10\n\t}\n\n\treturn &BucketedBuffer[T]{\n\t\tbuckets:        make([]*Bucket[T], bucketCapacity),\n\t\ttraceIndex:     make(map[string]int),\n\t\titemCapacity:   capacity,\n\t\tbucketCapacity: bucketCapacity,\n\t\tcategory:       category,\n\t\tpriority:       category.GetPriority(),\n\t\toverflowPolicy: overflowPolicy,\n\t\tbatchSize:      batchSize,\n\t\ttimeout:        timeout,\n\t\tlastFlushTime:  time.Now(),\n\t}\n}\n\nfunc (b *BucketedBuffer[T]) Offer(item T) bool {\n\tatomic.AddInt64(&b.offered, 1)\n\n\ttraceID := \"\"\n\tif ta, ok := any(item).(TraceAware); ok {\n\t\tif tid, hasTrace := ta.GetTraceID(); hasTrace {\n\t\t\ttraceID = tid\n\t\t}\n\t}\n\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\treturn b.offerToBucket(item, traceID)\n}\n\nfunc (b *BucketedBuffer[T]) offerToBucket(item T, traceID string) bool {\n\tif traceID != \"\" {\n\t\tif idx, exists := b.traceIndex[traceID]; exists {\n\t\t\tbucket := b.buckets[idx]\n\t\t\tif len(bucket.items) >= perBucketItemLimit {\n\t\t\t\tdelete(b.traceIndex, traceID)\n\t\t\t} else {\n\t\t\t\tbucket.items = append(bucket.items, item)\n\t\t\t\tbucket.lastUpdatedAt = time.Now()\n\t\t\t\tb.totalItems++\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\n\tif b.totalItems >= b.itemCapacity {\n\t\treturn b.handleOverflow(item, traceID)\n\t}\n\tif b.bucketCount >= b.bucketCapacity {\n\t\treturn b.handleOverflow(item, traceID)\n\t}\n\n\tbucket := &Bucket[T]{\n\t\ttraceID:       traceID,\n\t\titems:         []T{item},\n\t\tcreatedAt:     time.Now(),\n\t\tlastUpdatedAt: time.Now(),\n\t}\n\tb.buckets[b.tail] = bucket\n\tif traceID != \"\" {\n\t\tb.traceIndex[traceID] = b.tail\n\t}\n\tb.tail = (b.tail + 1) % b.bucketCapacity\n\tb.bucketCount++\n\tb.totalItems++\n\treturn true\n}\n\nfunc (b *BucketedBuffer[T]) handleOverflow(item T, traceID string) bool {\n\tswitch b.overflowPolicy {\n\tcase OverflowPolicyDropOldest:\n\t\toldestBucket := b.buckets[b.head]\n\t\tif oldestBucket == nil {\n\t\t\tatomic.AddInt64(&b.dropped, 1)\n\t\t\tif b.onDropped != nil {\n\t\t\t\tb.onDropped(item, \"buffer_full_invalid_state\")\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\t\tif oldestBucket.traceID != \"\" {\n\t\t\tdelete(b.traceIndex, oldestBucket.traceID)\n\t\t}\n\t\tdroppedCount := len(oldestBucket.items)\n\t\tatomic.AddInt64(&b.dropped, int64(droppedCount))\n\t\tif b.onDropped != nil {\n\t\t\tfor _, di := range oldestBucket.items {\n\t\t\t\tb.onDropped(di, \"buffer_full_drop_oldest_bucket\")\n\t\t\t}\n\t\t}\n\t\tb.totalItems -= droppedCount\n\t\tb.bucketCount--\n\t\tb.head = (b.head + 1) % b.bucketCapacity\n\t\t// add new bucket\n\t\tbucket := &Bucket[T]{traceID: traceID, items: []T{item}, createdAt: time.Now(), lastUpdatedAt: time.Now()}\n\t\tb.buckets[b.tail] = bucket\n\t\tif traceID != \"\" {\n\t\t\tb.traceIndex[traceID] = b.tail\n\t\t}\n\t\tb.tail = (b.tail + 1) % b.bucketCapacity\n\t\tb.bucketCount++\n\t\tb.totalItems++\n\t\treturn true\n\tcase OverflowPolicyDropNewest:\n\t\tatomic.AddInt64(&b.dropped, 1)\n\t\tif b.onDropped != nil {\n\t\t\tb.onDropped(item, \"buffer_full_drop_newest\")\n\t\t}\n\t\treturn false\n\tdefault:\n\t\tatomic.AddInt64(&b.dropped, 1)\n\t\tif b.onDropped != nil {\n\t\t\tb.onDropped(item, \"unknown_overflow_policy\")\n\t\t}\n\t\treturn false\n\t}\n}\n\nfunc (b *BucketedBuffer[T]) Poll() (T, bool) {\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\tvar zero T\n\tif b.bucketCount == 0 {\n\t\treturn zero, false\n\t}\n\tbucket := b.buckets[b.head]\n\tif bucket == nil || len(bucket.items) == 0 {\n\t\treturn zero, false\n\t}\n\titem := bucket.items[0]\n\tbucket.items = bucket.items[1:]\n\tb.totalItems--\n\tif len(bucket.items) == 0 {\n\t\tif bucket.traceID != \"\" {\n\t\t\tdelete(b.traceIndex, bucket.traceID)\n\t\t}\n\t\tb.buckets[b.head] = nil\n\t\tb.head = (b.head + 1) % b.bucketCapacity\n\t\tb.bucketCount--\n\t}\n\treturn item, true\n}\n\nfunc (b *BucketedBuffer[T]) PollBatch(maxItems int) []T {\n\tif maxItems <= 0 {\n\t\treturn nil\n\t}\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\tif b.bucketCount == 0 {\n\t\treturn nil\n\t}\n\tres := make([]T, 0, maxItems)\n\tfor len(res) < maxItems && b.bucketCount > 0 {\n\t\tbucket := b.buckets[b.head]\n\t\tif bucket == nil {\n\t\t\tbreak\n\t\t}\n\t\tn := maxItems - len(res)\n\t\tif n > len(bucket.items) {\n\t\t\tn = len(bucket.items)\n\t\t}\n\t\tres = append(res, bucket.items[:n]...)\n\t\tbucket.items = bucket.items[n:]\n\t\tb.totalItems -= n\n\t\tif len(bucket.items) == 0 {\n\t\t\tif bucket.traceID != \"\" {\n\t\t\t\tdelete(b.traceIndex, bucket.traceID)\n\t\t\t}\n\t\t\tb.buckets[b.head] = nil\n\t\t\tb.head = (b.head + 1) % b.bucketCapacity\n\t\t\tb.bucketCount--\n\t\t}\n\t}\n\treturn res\n}\n\nfunc (b *BucketedBuffer[T]) PollIfReady() []T {\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\tif b.bucketCount == 0 {\n\t\treturn nil\n\t}\n\tready := b.totalItems >= b.batchSize || (b.timeout > 0 && time.Since(b.lastFlushTime) >= b.timeout)\n\tif !ready {\n\t\treturn nil\n\t}\n\toldest := b.buckets[b.head]\n\tif oldest == nil {\n\t\treturn nil\n\t}\n\titems := oldest.items\n\tif oldest.traceID != \"\" {\n\t\tdelete(b.traceIndex, oldest.traceID)\n\t}\n\tb.buckets[b.head] = nil\n\tb.head = (b.head + 1) % b.bucketCapacity\n\tb.totalItems -= len(items)\n\tb.bucketCount--\n\tb.lastFlushTime = time.Now()\n\treturn items\n}\n\nfunc (b *BucketedBuffer[T]) Drain() []T {\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\tif b.bucketCount == 0 {\n\t\treturn nil\n\t}\n\tres := make([]T, 0, b.totalItems)\n\tfor i := 0; i < b.bucketCount; i++ {\n\t\tidx := (b.head + i) % b.bucketCapacity\n\t\tbucket := b.buckets[idx]\n\t\tif bucket != nil {\n\t\t\tres = append(res, bucket.items...)\n\t\t\tb.buckets[idx] = nil\n\t\t}\n\t}\n\tb.traceIndex = make(map[string]int)\n\tb.head = 0\n\tb.tail = 0\n\tb.totalItems = 0\n\tb.bucketCount = 0\n\treturn res\n}\n\nfunc (b *BucketedBuffer[T]) Peek() (T, bool) {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\tvar zero T\n\tif b.bucketCount == 0 {\n\t\treturn zero, false\n\t}\n\tbucket := b.buckets[b.head]\n\tif bucket == nil || len(bucket.items) == 0 {\n\t\treturn zero, false\n\t}\n\treturn bucket.items[0], true\n}\n\nfunc (b *BucketedBuffer[T]) Size() int     { b.mu.RLock(); defer b.mu.RUnlock(); return b.totalItems }\nfunc (b *BucketedBuffer[T]) Capacity() int { b.mu.RLock(); defer b.mu.RUnlock(); return b.itemCapacity }\nfunc (b *BucketedBuffer[T]) Category() ratelimit.Category {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\treturn b.category\n}\nfunc (b *BucketedBuffer[T]) Priority() ratelimit.Priority {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\treturn b.priority\n}\nfunc (b *BucketedBuffer[T]) IsEmpty() bool {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\treturn b.bucketCount == 0\n}\nfunc (b *BucketedBuffer[T]) IsFull() bool {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\treturn b.totalItems >= b.itemCapacity\n}\nfunc (b *BucketedBuffer[T]) Utilization() float64 {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\tif b.itemCapacity == 0 {\n\t\treturn 0\n\t}\n\treturn float64(b.totalItems) / float64(b.itemCapacity)\n}\nfunc (b *BucketedBuffer[T]) OfferedCount() int64  { return atomic.LoadInt64(&b.offered) }\nfunc (b *BucketedBuffer[T]) DroppedCount() int64  { return atomic.LoadInt64(&b.dropped) }\nfunc (b *BucketedBuffer[T]) AcceptedCount() int64 { return b.OfferedCount() - b.DroppedCount() }\nfunc (b *BucketedBuffer[T]) DropRate() float64 {\n\toff := b.OfferedCount()\n\tif off == 0 {\n\t\treturn 0\n\t}\n\treturn float64(b.DroppedCount()) / float64(off)\n}\n\nfunc (b *BucketedBuffer[T]) GetMetrics() BufferMetrics {\n\tb.mu.RLock()\n\tsize := b.totalItems\n\tutil := 0.0\n\tif b.itemCapacity > 0 {\n\t\tutil = float64(b.totalItems) / float64(b.itemCapacity)\n\t}\n\tb.mu.RUnlock()\n\treturn BufferMetrics{Category: b.category, Priority: b.priority, Capacity: b.itemCapacity, Size: size, Utilization: util, OfferedCount: b.OfferedCount(), DroppedCount: b.DroppedCount(), AcceptedCount: b.AcceptedCount(), DropRate: b.DropRate(), LastUpdated: time.Now()}\n}\n\nfunc (b *BucketedBuffer[T]) SetDroppedCallback(callback func(item T, reason string)) {\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\tb.onDropped = callback\n}\nfunc (b *BucketedBuffer[T]) Clear() {\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\tfor i := 0; i < b.bucketCapacity; i++ {\n\t\tb.buckets[i] = nil\n\t}\n\tb.traceIndex = make(map[string]int)\n\tb.head = 0\n\tb.tail = 0\n\tb.totalItems = 0\n\tb.bucketCount = 0\n}\nfunc (b *BucketedBuffer[T]) IsReadyToFlush() bool {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\tif b.bucketCount == 0 {\n\t\treturn false\n\t}\n\tif b.totalItems >= b.batchSize {\n\t\treturn true\n\t}\n\tif b.timeout > 0 && time.Since(b.lastFlushTime) >= b.timeout {\n\t\treturn true\n\t}\n\treturn false\n}\nfunc (b *BucketedBuffer[T]) MarkFlushed() {\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\tb.lastFlushTime = time.Now()\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/telemetry/buffer.go",
    "content": "package telemetry\n\nimport (\n\t\"github.com/getsentry/sentry-go/internal/ratelimit\"\n)\n\n// Buffer defines the common interface for all buffer implementations.\ntype Buffer[T any] interface {\n\t// Core operations\n\tOffer(item T) bool\n\tPoll() (T, bool)\n\tPollBatch(maxItems int) []T\n\tPollIfReady() []T\n\tDrain() []T\n\tPeek() (T, bool)\n\n\t// State queries\n\tSize() int\n\tCapacity() int\n\tIsEmpty() bool\n\tIsFull() bool\n\tUtilization() float64\n\n\t// Flush management\n\tIsReadyToFlush() bool\n\tMarkFlushed()\n\n\t// Category/Priority\n\tCategory() ratelimit.Category\n\tPriority() ratelimit.Priority\n\n\t// Metrics\n\tOfferedCount() int64\n\tDroppedCount() int64\n\tAcceptedCount() int64\n\tDropRate() float64\n\tGetMetrics() BufferMetrics\n\n\t// Configuration\n\tSetDroppedCallback(callback func(item T, reason string))\n\tClear()\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/telemetry/processor.go",
    "content": "package telemetry\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go/internal/protocol\"\n\t\"github.com/getsentry/sentry-go/internal/ratelimit\"\n)\n\n// Processor is the top-level object that wraps the scheduler and buffers.\ntype Processor struct {\n\tscheduler *Scheduler\n}\n\n// NewProcessor creates a new Processor with the given configuration.\nfunc NewProcessor(\n\tbuffers map[ratelimit.Category]Buffer[protocol.TelemetryItem],\n\ttransport protocol.TelemetryTransport,\n\tdsn *protocol.Dsn,\n\tsdkInfo *protocol.SdkInfo,\n) *Processor {\n\tscheduler := NewScheduler(buffers, transport, dsn, sdkInfo)\n\tscheduler.Start()\n\n\treturn &Processor{\n\t\tscheduler: scheduler,\n\t}\n}\n\n// Add adds a TelemetryItem to the appropriate buffer based on its category.\nfunc (b *Processor) Add(item protocol.TelemetryItem) bool {\n\treturn b.scheduler.Add(item)\n}\n\n// Flush forces all buffers to flush within the given timeout.\nfunc (b *Processor) Flush(timeout time.Duration) bool {\n\treturn b.scheduler.Flush(timeout)\n}\n\n// FlushWithContext flushes with a custom context for cancellation.\nfunc (b *Processor) FlushWithContext(ctx context.Context) bool {\n\treturn b.scheduler.FlushWithContext(ctx)\n}\n\n// Close stops the buffer, flushes remaining data, and releases resources.\nfunc (b *Processor) Close(timeout time.Duration) {\n\tb.scheduler.Stop(timeout)\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/telemetry/ring_buffer.go",
    "content": "package telemetry\n\nimport (\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go/internal/ratelimit\"\n)\n\nconst defaultCapacity = 100\n\n// RingBuffer is a thread-safe ring buffer with overflow policies.\ntype RingBuffer[T any] struct {\n\tmu       sync.RWMutex\n\titems    []T\n\thead     int\n\ttail     int\n\tsize     int\n\tcapacity int\n\n\tcategory       ratelimit.Category\n\tpriority       ratelimit.Priority\n\toverflowPolicy OverflowPolicy\n\n\tbatchSize     int\n\ttimeout       time.Duration\n\tlastFlushTime time.Time\n\n\toffered   int64\n\tdropped   int64\n\tonDropped func(item T, reason string)\n}\n\nfunc NewRingBuffer[T any](category ratelimit.Category, capacity int, overflowPolicy OverflowPolicy, batchSize int, timeout time.Duration) *RingBuffer[T] {\n\tif capacity <= 0 {\n\t\tcapacity = defaultCapacity\n\t}\n\n\tif batchSize <= 0 {\n\t\tbatchSize = 1\n\t}\n\n\tif timeout < 0 {\n\t\ttimeout = 0\n\t}\n\n\treturn &RingBuffer[T]{\n\t\titems:          make([]T, capacity),\n\t\tcapacity:       capacity,\n\t\tcategory:       category,\n\t\tpriority:       category.GetPriority(),\n\t\toverflowPolicy: overflowPolicy,\n\t\tbatchSize:      batchSize,\n\t\ttimeout:        timeout,\n\t\tlastFlushTime:  time.Now(),\n\t}\n}\n\nfunc (b *RingBuffer[T]) SetDroppedCallback(callback func(item T, reason string)) {\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\tb.onDropped = callback\n}\n\nfunc (b *RingBuffer[T]) Offer(item T) bool {\n\tatomic.AddInt64(&b.offered, 1)\n\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\n\tif b.size < b.capacity {\n\t\tb.items[b.tail] = item\n\t\tb.tail = (b.tail + 1) % b.capacity\n\t\tb.size++\n\t\treturn true\n\t}\n\n\tswitch b.overflowPolicy {\n\tcase OverflowPolicyDropOldest:\n\t\toldItem := b.items[b.head]\n\t\tb.items[b.head] = item\n\t\tb.head = (b.head + 1) % b.capacity\n\t\tb.tail = (b.tail + 1) % b.capacity\n\n\t\tatomic.AddInt64(&b.dropped, 1)\n\t\tif b.onDropped != nil {\n\t\t\tb.onDropped(oldItem, \"buffer_full_drop_oldest\")\n\t\t}\n\t\treturn true\n\n\tcase OverflowPolicyDropNewest:\n\t\tatomic.AddInt64(&b.dropped, 1)\n\t\tif b.onDropped != nil {\n\t\t\tb.onDropped(item, \"buffer_full_drop_newest\")\n\t\t}\n\t\treturn false\n\n\tdefault:\n\t\tatomic.AddInt64(&b.dropped, 1)\n\t\tif b.onDropped != nil {\n\t\t\tb.onDropped(item, \"unknown_overflow_policy\")\n\t\t}\n\t\treturn false\n\t}\n}\n\nfunc (b *RingBuffer[T]) Poll() (T, bool) {\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\n\tvar zero T\n\tif b.size == 0 {\n\t\treturn zero, false\n\t}\n\n\titem := b.items[b.head]\n\tb.items[b.head] = zero\n\tb.head = (b.head + 1) % b.capacity\n\tb.size--\n\n\treturn item, true\n}\n\nfunc (b *RingBuffer[T]) PollBatch(maxItems int) []T {\n\tif maxItems <= 0 {\n\t\treturn nil\n\t}\n\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\n\tif b.size == 0 {\n\t\treturn nil\n\t}\n\n\titemCount := maxItems\n\tif itemCount > b.size {\n\t\titemCount = b.size\n\t}\n\n\tresult := make([]T, itemCount)\n\tvar zero T\n\n\tfor i := 0; i < itemCount; i++ {\n\t\tresult[i] = b.items[b.head]\n\t\tb.items[b.head] = zero\n\t\tb.head = (b.head + 1) % b.capacity\n\t\tb.size--\n\t}\n\n\treturn result\n}\n\nfunc (b *RingBuffer[T]) Drain() []T {\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\n\tif b.size == 0 {\n\t\treturn nil\n\t}\n\n\tresult := make([]T, b.size)\n\tindex := 0\n\tvar zero T\n\n\tfor i := 0; i < b.size; i++ {\n\t\tpos := (b.head + i) % b.capacity\n\t\tresult[index] = b.items[pos]\n\t\tb.items[pos] = zero\n\t\tindex++\n\t}\n\n\tb.head = 0\n\tb.tail = 0\n\tb.size = 0\n\n\treturn result\n}\n\nfunc (b *RingBuffer[T]) Peek() (T, bool) {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\n\tvar zero T\n\tif b.size == 0 {\n\t\treturn zero, false\n\t}\n\n\treturn b.items[b.head], true\n}\n\nfunc (b *RingBuffer[T]) Size() int {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\treturn b.size\n}\n\nfunc (b *RingBuffer[T]) Capacity() int {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\treturn b.capacity\n}\n\nfunc (b *RingBuffer[T]) Category() ratelimit.Category {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\treturn b.category\n}\n\nfunc (b *RingBuffer[T]) Priority() ratelimit.Priority {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\treturn b.priority\n}\n\nfunc (b *RingBuffer[T]) IsEmpty() bool {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\treturn b.size == 0\n}\n\nfunc (b *RingBuffer[T]) IsFull() bool {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\treturn b.size == b.capacity\n}\n\nfunc (b *RingBuffer[T]) Utilization() float64 {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\treturn float64(b.size) / float64(b.capacity)\n}\n\nfunc (b *RingBuffer[T]) OfferedCount() int64 {\n\treturn atomic.LoadInt64(&b.offered)\n}\n\nfunc (b *RingBuffer[T]) DroppedCount() int64 {\n\treturn atomic.LoadInt64(&b.dropped)\n}\n\nfunc (b *RingBuffer[T]) AcceptedCount() int64 {\n\treturn b.OfferedCount() - b.DroppedCount()\n}\n\nfunc (b *RingBuffer[T]) DropRate() float64 {\n\toffered := b.OfferedCount()\n\tif offered == 0 {\n\t\treturn 0.0\n\t}\n\treturn float64(b.DroppedCount()) / float64(offered)\n}\n\nfunc (b *RingBuffer[T]) Clear() {\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\n\tvar zero T\n\tfor i := 0; i < b.capacity; i++ {\n\t\tb.items[i] = zero\n\t}\n\n\tb.head = 0\n\tb.tail = 0\n\tb.size = 0\n}\n\nfunc (b *RingBuffer[T]) GetMetrics() BufferMetrics {\n\tb.mu.RLock()\n\tsize := b.size\n\tutil := float64(b.size) / float64(b.capacity)\n\tb.mu.RUnlock()\n\n\treturn BufferMetrics{\n\t\tCategory:      b.category,\n\t\tPriority:      b.priority,\n\t\tCapacity:      b.capacity,\n\t\tSize:          size,\n\t\tUtilization:   util,\n\t\tOfferedCount:  b.OfferedCount(),\n\t\tDroppedCount:  b.DroppedCount(),\n\t\tAcceptedCount: b.AcceptedCount(),\n\t\tDropRate:      b.DropRate(),\n\t\tLastUpdated:   time.Now(),\n\t}\n}\n\nfunc (b *RingBuffer[T]) IsReadyToFlush() bool {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\n\tif b.size == 0 {\n\t\treturn false\n\t}\n\n\tif b.size >= b.batchSize {\n\t\treturn true\n\t}\n\n\tif b.timeout > 0 && time.Since(b.lastFlushTime) >= b.timeout {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc (b *RingBuffer[T]) MarkFlushed() {\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\tb.lastFlushTime = time.Now()\n}\n\nfunc (b *RingBuffer[T]) PollIfReady() []T {\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\n\tif b.size == 0 {\n\t\treturn nil\n\t}\n\n\tready := b.size >= b.batchSize ||\n\t\t(b.timeout > 0 && time.Since(b.lastFlushTime) >= b.timeout)\n\n\tif !ready {\n\t\treturn nil\n\t}\n\n\titemCount := b.batchSize\n\tif itemCount > b.size {\n\t\titemCount = b.size\n\t}\n\n\tresult := make([]T, itemCount)\n\tvar zero T\n\n\tfor i := 0; i < itemCount; i++ {\n\t\tresult[i] = b.items[b.head]\n\t\tb.items[b.head] = zero\n\t\tb.head = (b.head + 1) % b.capacity\n\t\tb.size--\n\t}\n\n\tb.lastFlushTime = time.Now()\n\treturn result\n}\n\ntype BufferMetrics struct {\n\tCategory      ratelimit.Category `json:\"category\"`\n\tPriority      ratelimit.Priority `json:\"priority\"`\n\tCapacity      int                `json:\"capacity\"`\n\tSize          int                `json:\"size\"`\n\tUtilization   float64            `json:\"utilization\"`\n\tOfferedCount  int64              `json:\"offered_count\"`\n\tDroppedCount  int64              `json:\"dropped_count\"`\n\tAcceptedCount int64              `json:\"accepted_count\"`\n\tDropRate      float64            `json:\"drop_rate\"`\n\tLastUpdated   time.Time          `json:\"last_updated\"`\n}\n\n// OverflowPolicy defines how the ring buffer handles overflow.\ntype OverflowPolicy int\n\nconst (\n\tOverflowPolicyDropOldest OverflowPolicy = iota\n\tOverflowPolicyDropNewest\n)\n\nfunc (op OverflowPolicy) String() string {\n\tswitch op {\n\tcase OverflowPolicyDropOldest:\n\t\treturn \"drop_oldest\"\n\tcase OverflowPolicyDropNewest:\n\t\treturn \"drop_newest\"\n\tdefault:\n\t\treturn \"unknown\"\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/telemetry/scheduler.go",
    "content": "package telemetry\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go/internal/debuglog\"\n\t\"github.com/getsentry/sentry-go/internal/protocol\"\n\t\"github.com/getsentry/sentry-go/internal/ratelimit\"\n)\n\n// Scheduler implements a weighted round-robin scheduler for processing buffered events.\ntype Scheduler struct {\n\tbuffers   map[ratelimit.Category]Buffer[protocol.TelemetryItem]\n\ttransport protocol.TelemetryTransport\n\tdsn       *protocol.Dsn\n\tsdkInfo   *protocol.SdkInfo\n\n\tcurrentCycle []ratelimit.Priority\n\tcyclePos     int\n\n\tctx          context.Context\n\tcancel       context.CancelFunc\n\tprocessingWg sync.WaitGroup\n\n\tmu         sync.Mutex\n\tcond       *sync.Cond\n\tstartOnce  sync.Once\n\tfinishOnce sync.Once\n}\n\nfunc NewScheduler(\n\tbuffers map[ratelimit.Category]Buffer[protocol.TelemetryItem],\n\ttransport protocol.TelemetryTransport,\n\tdsn *protocol.Dsn,\n\tsdkInfo *protocol.SdkInfo,\n) *Scheduler {\n\tctx, cancel := context.WithCancel(context.Background())\n\n\tpriorityWeights := map[ratelimit.Priority]int{\n\t\tratelimit.PriorityCritical: 5,\n\t\tratelimit.PriorityHigh:     4,\n\t\tratelimit.PriorityMedium:   3,\n\t\tratelimit.PriorityLow:      2,\n\t\tratelimit.PriorityLowest:   1,\n\t}\n\n\tvar currentCycle []ratelimit.Priority\n\tfor priority, weight := range priorityWeights {\n\t\thasBuffers := false\n\t\tfor _, buffer := range buffers {\n\t\t\tif buffer.Priority() == priority {\n\t\t\t\thasBuffers = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif hasBuffers {\n\t\t\tfor i := 0; i < weight; i++ {\n\t\t\t\tcurrentCycle = append(currentCycle, priority)\n\t\t\t}\n\t\t}\n\t}\n\n\ts := &Scheduler{\n\t\tbuffers:      buffers,\n\t\ttransport:    transport,\n\t\tdsn:          dsn,\n\t\tsdkInfo:      sdkInfo,\n\t\tcurrentCycle: currentCycle,\n\t\tctx:          ctx,\n\t\tcancel:       cancel,\n\t}\n\ts.cond = sync.NewCond(&s.mu)\n\n\treturn s\n}\n\nfunc (s *Scheduler) Start() {\n\ts.startOnce.Do(func() {\n\t\ts.processingWg.Add(1)\n\t\tgo s.run()\n\t})\n}\n\nfunc (s *Scheduler) Stop(timeout time.Duration) {\n\ts.finishOnce.Do(func() {\n\t\ts.Flush(timeout)\n\n\t\ts.cancel()\n\t\ts.cond.Broadcast()\n\n\t\tdone := make(chan struct{})\n\t\tgo func() {\n\t\t\tdefer close(done)\n\t\t\ts.processingWg.Wait()\n\t\t}()\n\n\t\tselect {\n\t\tcase <-done:\n\t\tcase <-time.After(timeout):\n\t\t\tdebuglog.Printf(\"scheduler stop timed out after %v\", timeout)\n\t\t}\n\t})\n}\n\nfunc (s *Scheduler) Signal() {\n\ts.cond.Signal()\n}\n\nfunc (s *Scheduler) Add(item protocol.TelemetryItem) bool {\n\tcategory := item.GetCategory()\n\tbuffer, exists := s.buffers[category]\n\tif !exists {\n\t\treturn false\n\t}\n\n\taccepted := buffer.Offer(item)\n\tif accepted {\n\t\ts.Signal()\n\t}\n\treturn accepted\n}\n\nfunc (s *Scheduler) Flush(timeout time.Duration) bool {\n\tctx, cancel := context.WithTimeout(context.Background(), timeout)\n\tdefer cancel()\n\treturn s.FlushWithContext(ctx)\n}\n\nfunc (s *Scheduler) FlushWithContext(ctx context.Context) bool {\n\ts.flushBuffers()\n\treturn s.transport.FlushWithContext(ctx)\n}\n\nfunc (s *Scheduler) run() {\n\tdefer s.processingWg.Done()\n\n\tgo func() {\n\t\tticker := time.NewTicker(100 * time.Millisecond)\n\t\tdefer ticker.Stop()\n\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-ticker.C:\n\t\t\t\ts.cond.Broadcast()\n\t\t\tcase <-s.ctx.Done():\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\tfor {\n\t\ts.mu.Lock()\n\n\t\tfor !s.hasWork() && s.ctx.Err() == nil {\n\t\t\ts.cond.Wait()\n\t\t}\n\n\t\tif s.ctx.Err() != nil {\n\t\t\ts.mu.Unlock()\n\t\t\treturn\n\t\t}\n\n\t\ts.mu.Unlock()\n\t\ts.processNextBatch()\n\t}\n}\n\nfunc (s *Scheduler) hasWork() bool {\n\tfor _, buffer := range s.buffers {\n\t\tif buffer.IsReadyToFlush() {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (s *Scheduler) processNextBatch() {\n\tif len(s.currentCycle) == 0 {\n\t\treturn\n\t}\n\n\tpriority := s.currentCycle[s.cyclePos]\n\ts.cyclePos = (s.cyclePos + 1) % len(s.currentCycle)\n\n\tvar bufferToProcess Buffer[protocol.TelemetryItem]\n\tvar categoryToProcess ratelimit.Category\n\tfor category, buffer := range s.buffers {\n\t\tif buffer.Priority() == priority && buffer.IsReadyToFlush() {\n\t\t\tbufferToProcess = buffer\n\t\t\tcategoryToProcess = category\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif bufferToProcess != nil {\n\t\ts.processItems(bufferToProcess, categoryToProcess, false)\n\t}\n}\n\nfunc (s *Scheduler) processItems(buffer Buffer[protocol.TelemetryItem], category ratelimit.Category, force bool) {\n\tvar items []protocol.TelemetryItem\n\n\tif force {\n\t\titems = buffer.Drain()\n\t} else {\n\t\titems = buffer.PollIfReady()\n\t}\n\n\t// drop the current batch if rate-limited or if transport is full\n\tif len(items) == 0 || s.isRateLimited(category) || !s.transport.HasCapacity() {\n\t\treturn\n\t}\n\n\tswitch category {\n\tcase ratelimit.CategoryLog:\n\t\tlogs := protocol.Logs(items)\n\t\theader := &protocol.EnvelopeHeader{EventID: protocol.GenerateEventID(), SentAt: time.Now(), Sdk: s.sdkInfo}\n\t\tif s.dsn != nil {\n\t\t\theader.Dsn = s.dsn.String()\n\t\t}\n\t\tenvelope := protocol.NewEnvelope(header)\n\t\titem, err := logs.ToEnvelopeItem()\n\t\tif err != nil {\n\t\t\tdebuglog.Printf(\"error creating log batch envelope item: %v\", err)\n\t\t\treturn\n\t\t}\n\t\tenvelope.AddItem(item)\n\t\tif err := s.transport.SendEnvelope(envelope); err != nil {\n\t\t\tdebuglog.Printf(\"error sending envelope: %v\", err)\n\t\t}\n\t\treturn\n\tcase ratelimit.CategoryTraceMetric:\n\t\tmetrics := protocol.Metrics(items)\n\t\theader := &protocol.EnvelopeHeader{EventID: protocol.GenerateEventID(), SentAt: time.Now(), Sdk: s.sdkInfo}\n\t\tif s.dsn != nil {\n\t\t\theader.Dsn = s.dsn.String()\n\t\t}\n\t\tenvelope := protocol.NewEnvelope(header)\n\t\titem, err := metrics.ToEnvelopeItem()\n\t\tif err != nil {\n\t\t\tdebuglog.Printf(\"error creating trace metric batch envelope item: %v\", err)\n\t\t\treturn\n\t\t}\n\t\tenvelope.AddItem(item)\n\t\tif err := s.transport.SendEnvelope(envelope); err != nil {\n\t\t\tdebuglog.Printf(\"error sending envelope: %v\", err)\n\t\t}\n\t\treturn\n\tdefault:\n\t\t// if the buffers are properly configured, buffer.PollIfReady should return a single item for every category\n\t\t// other than logs. We still iterate over the items just in case, because we don't want to send broken envelopes.\n\t\tfor _, it := range items {\n\t\t\tconvertible, ok := it.(protocol.EnvelopeItemConvertible)\n\t\t\tif !ok {\n\t\t\t\tdebuglog.Printf(\"item does not implement EnvelopeItemConvertible: %T\", it)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ts.sendItem(convertible)\n\t\t}\n\t}\n}\n\nfunc (s *Scheduler) sendItem(item protocol.EnvelopeItemConvertible) {\n\theader := &protocol.EnvelopeHeader{\n\t\tEventID: item.GetEventID(),\n\t\tSentAt:  time.Now(),\n\t\tTrace:   item.GetDynamicSamplingContext(),\n\t\tSdk:     s.sdkInfo,\n\t}\n\tif header.EventID == \"\" {\n\t\theader.EventID = protocol.GenerateEventID()\n\t}\n\tif s.dsn != nil {\n\t\theader.Dsn = s.dsn.String()\n\t}\n\tenvelope := protocol.NewEnvelope(header)\n\tenvItem, err := item.ToEnvelopeItem()\n\tif err != nil {\n\t\tdebuglog.Printf(\"error while converting to envelope item: %v\", err)\n\t\treturn\n\t}\n\tenvelope.AddItem(envItem)\n\tif err := s.transport.SendEnvelope(envelope); err != nil {\n\t\tdebuglog.Printf(\"error sending envelope: %v\", err)\n\t}\n}\n\nfunc (s *Scheduler) flushBuffers() {\n\tfor category, buffer := range s.buffers {\n\t\tif !buffer.IsEmpty() {\n\t\t\ts.processItems(buffer, category, true)\n\t\t}\n\t}\n}\n\nfunc (s *Scheduler) isRateLimited(category ratelimit.Category) bool {\n\treturn s.transport.IsRateLimited(category)\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/telemetry/trace_aware.go",
    "content": "package telemetry\n\n// TraceAware is implemented by items that can expose a trace ID.\n// BucketedBuffer uses this to group items by trace.\ntype TraceAware interface {\n\tGetTraceID() (string, bool)\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/util/map.go",
    "content": "package util\n\nimport \"sync\"\n\ntype SyncMap[K comparable, V any] struct {\n\tm sync.Map\n}\n\nfunc (s *SyncMap[K, V]) Store(key K, value V) {\n\ts.m.Store(key, value)\n}\n\nfunc (s *SyncMap[K, V]) CompareAndDelete(key K, value V) {\n\ts.m.CompareAndDelete(key, value)\n}\n\nfunc (s *SyncMap[K, V]) Load(key K) (V, bool) {\n\tv, ok := s.m.Load(key)\n\tif !ok {\n\t\tvar zero V\n\t\treturn zero, false\n\t}\n\treturn v.(V), true\n}\n\nfunc (s *SyncMap[K, V]) Delete(key K) {\n\ts.m.Delete(key)\n}\n\nfunc (s *SyncMap[K, V]) LoadOrStore(key K, value V) (V, bool) {\n\tactual, loaded := s.m.LoadOrStore(key, value)\n\treturn actual.(V), loaded\n}\n\nfunc (s *SyncMap[K, V]) Clear() {\n\ts.m.Clear()\n}\n\nfunc (s *SyncMap[K, V]) Range(f func(key K, value V) bool) {\n\ts.m.Range(func(key, value any) bool {\n\t\treturn f(key.(K), value.(V))\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/internal/util/util.go",
    "content": "package util\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\n\t\"github.com/getsentry/sentry-go/internal/debuglog\"\n\t\"github.com/getsentry/sentry-go/internal/protocol\"\n)\n\n// MaxDrainResponseBytes is the maximum number of bytes that transport\n// implementations will read from response bodies when draining them.\nconst MaxDrainResponseBytes = 16 << 10\n\n// HandleHTTPResponse is a helper method that reads the HTTP response and handles debug output.\nfunc HandleHTTPResponse(response *http.Response, identifier string) bool {\n\tif response.StatusCode >= 200 && response.StatusCode < 300 {\n\t\treturn true\n\t}\n\n\tif response.StatusCode >= 400 && response.StatusCode <= 599 {\n\t\tbody, err := io.ReadAll(io.LimitReader(response.Body, MaxDrainResponseBytes))\n\t\tif err != nil {\n\t\t\tdebuglog.Printf(\"Error while reading response body: %v\", err)\n\t\t\treturn false\n\t\t}\n\n\t\tswitch {\n\t\tcase response.StatusCode == http.StatusRequestEntityTooLarge:\n\t\t\tdebuglog.Printf(\"Sending %s failed because the request was too large: %s\", identifier, string(body))\n\t\tcase response.StatusCode >= 500:\n\t\t\tdebuglog.Printf(\"Sending %s failed with server error %d: %s\", identifier, response.StatusCode, string(body))\n\t\tdefault:\n\t\t\tdebuglog.Printf(\"Sending %s failed with client error %d: %s\", identifier, response.StatusCode, string(body))\n\t\t}\n\t\treturn false\n\t}\n\n\tdebuglog.Printf(\"Unexpected status code %d for event %s\", response.StatusCode, identifier)\n\treturn false\n}\n\n// EnvelopeIdentifier returns a human-readable identifier for the event to be used in log messages.\n// Format: \"<description> [<event-id>]\".\nfunc EnvelopeIdentifier(envelope *protocol.Envelope) string {\n\tif envelope == nil || len(envelope.Items) == 0 {\n\t\treturn \"empty envelope\"\n\t}\n\n\tvar description string\n\t// we don't currently support mixed envelope types, so all event types would have the same type.\n\titemType := envelope.Items[0].Header.Type\n\n\tswitch itemType {\n\tcase protocol.EnvelopeItemTypeEvent:\n\t\tdescription = \"error\"\n\tcase protocol.EnvelopeItemTypeTransaction:\n\t\tdescription = \"transaction\"\n\tcase protocol.EnvelopeItemTypeCheckIn:\n\t\tdescription = \"check-in\"\n\tcase protocol.EnvelopeItemTypeLog:\n\t\tlogCount := 0\n\t\tfor _, item := range envelope.Items {\n\t\t\tif item != nil && item.Header != nil && item.Header.Type == protocol.EnvelopeItemTypeLog && item.Header.ItemCount != nil {\n\t\t\t\tlogCount += *item.Header.ItemCount\n\t\t\t}\n\t\t}\n\t\tdescription = fmt.Sprintf(\"%d log events\", logCount)\n\tcase protocol.EnvelopeItemTypeTraceMetric:\n\t\tmetricCount := 0\n\t\tfor _, item := range envelope.Items {\n\t\t\tif item != nil && item.Header != nil && item.Header.Type == protocol.EnvelopeItemTypeTraceMetric && item.Header.ItemCount != nil {\n\t\t\t\tmetricCount += *item.Header.ItemCount\n\t\t\t}\n\t\t}\n\t\tdescription = fmt.Sprintf(\"%d metric events\", metricCount)\n\tdefault:\n\t\tdescription = fmt.Sprintf(\"%s event\", itemType)\n\t}\n\n\treturn fmt.Sprintf(\"%s [%s]\", description, envelope.Header.EventID)\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/log.go",
    "content": "package sentry\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"maps\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go/attribute\"\n\t\"github.com/getsentry/sentry-go/internal/debuglog\"\n)\n\ntype LogLevel string\n\nconst (\n\tLogLevelTrace LogLevel = \"trace\"\n\tLogLevelDebug LogLevel = \"debug\"\n\tLogLevelInfo  LogLevel = \"info\"\n\tLogLevelWarn  LogLevel = \"warn\"\n\tLogLevelError LogLevel = \"error\"\n\tLogLevelFatal LogLevel = \"fatal\"\n)\n\nconst (\n\tLogSeverityTrace   int = 1\n\tLogSeverityDebug   int = 5\n\tLogSeverityInfo    int = 9\n\tLogSeverityWarning int = 13\n\tLogSeverityError   int = 17\n\tLogSeverityFatal   int = 21\n)\n\ntype sentryLogger struct {\n\tctx               context.Context\n\thub               *Hub\n\tattributes        map[string]attribute.Value\n\tdefaultAttributes map[string]attribute.Value\n\tmu                sync.RWMutex\n}\n\ntype logEntry struct {\n\tlogger      *sentryLogger\n\tctx         context.Context\n\tlevel       LogLevel\n\tseverity    int\n\tattributes  map[string]attribute.Value\n\tshouldPanic bool\n\tshouldFatal bool\n}\n\n// NewLogger returns a Logger that emits logs to Sentry. If logging is turned off, all logs get discarded.\nfunc NewLogger(ctx context.Context) Logger { // nolint: dupl\n\tvar hub *Hub\n\thub = GetHubFromContext(ctx)\n\tif hub == nil {\n\t\thub = CurrentHub()\n\t}\n\n\tclient := hub.Client()\n\tif client != nil && client.options.EnableLogs {\n\t\t// Build default attrs\n\t\tserverAddr := client.options.ServerName\n\t\tif serverAddr == \"\" {\n\t\t\tserverAddr, _ = os.Hostname()\n\t\t}\n\n\t\tdefaults := map[string]string{\n\t\t\t\"sentry.release\":        client.options.Release,\n\t\t\t\"sentry.environment\":    client.options.Environment,\n\t\t\t\"sentry.server.address\": serverAddr,\n\t\t\t\"sentry.sdk.name\":       client.sdkIdentifier,\n\t\t\t\"sentry.sdk.version\":    client.sdkVersion,\n\t\t}\n\n\t\tdefaultAttrs := make(map[string]attribute.Value, len(defaults))\n\t\tfor k, v := range defaults {\n\t\t\tif v != \"\" {\n\t\t\t\tdefaultAttrs[k] = attribute.StringValue(v)\n\t\t\t}\n\t\t}\n\n\t\treturn &sentryLogger{\n\t\t\tctx:               ctx,\n\t\t\thub:               hub,\n\t\t\tattributes:        make(map[string]attribute.Value),\n\t\t\tdefaultAttributes: defaultAttrs,\n\t\t\tmu:                sync.RWMutex{},\n\t\t}\n\t}\n\n\tdebuglog.Println(\"fallback to noopLogger: enableLogs disabled\")\n\treturn &noopLogger{}\n}\n\nfunc (l *sentryLogger) Write(p []byte) (int, error) {\n\tmsg := strings.TrimRight(string(p), \"\\n\")\n\tl.Info().Emit(msg)\n\treturn len(p), nil\n}\n\nfunc (l *sentryLogger) log(ctx context.Context, level LogLevel, severity int, message string, entryAttrs map[string]attribute.Value, args ...interface{}) {\n\tif message == \"\" {\n\t\treturn\n\t}\n\n\thub := hubFromContexts(ctx, l.ctx)\n\tif hub == nil {\n\t\thub = l.hub\n\t}\n\tclient := hub.Client()\n\tif client == nil {\n\t\treturn\n\t}\n\n\tscope := hub.Scope()\n\ttraceID, spanID := resolveTrace(scope, ctx, l.ctx)\n\n\t// Pre-allocate with capacity hint to avoid map growth reallocations\n\testimatedCap := len(l.defaultAttributes) + len(entryAttrs) + len(args) + 8 // scope ~3 + instance ~5\n\tattrs := make(map[string]attribute.Value, estimatedCap)\n\n\t// attribute precedence: default -> scope -> instance (from SetAttrs) -> entry-specific\n\tfor k, v := range l.defaultAttributes {\n\t\tattrs[k] = v\n\t}\n\tscope.populateAttrs(attrs)\n\n\tl.mu.RLock()\n\tfor k, v := range l.attributes {\n\t\tattrs[k] = v\n\t}\n\tl.mu.RUnlock()\n\n\tfor k, v := range entryAttrs {\n\t\tattrs[k] = v\n\t}\n\n\tif len(args) > 0 {\n\t\tattrs[\"sentry.message.template\"] = attribute.StringValue(message)\n\t\tfor i, p := range args {\n\t\t\tattrs[fmt.Sprintf(\"sentry.message.parameters.%d\", i)] = attribute.StringValue(fmt.Sprintf(\"%+v\", p))\n\t\t}\n\t}\n\n\tlog := &Log{\n\t\tTimestamp:  time.Now(),\n\t\tTraceID:    traceID,\n\t\tSpanID:     spanID,\n\t\tLevel:      level,\n\t\tSeverity:   severity,\n\t\tBody:       fmt.Sprintf(message, args...),\n\t\tAttributes: attrs,\n\t}\n\n\tclient.captureLog(log, scope)\n\tif client.options.Debug {\n\t\tdebuglog.Printf(message, args...)\n\t}\n}\n\nfunc (l *sentryLogger) SetAttributes(attrs ...attribute.Builder) {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\n\tfor _, a := range attrs {\n\t\tif a.Value.Type() == attribute.INVALID {\n\t\t\tdebuglog.Printf(\"invalid attribute: %v\", a)\n\t\t\tcontinue\n\t\t}\n\t\tl.attributes[a.Key] = a.Value\n\t}\n}\n\nfunc (l *sentryLogger) Trace() LogEntry {\n\treturn &logEntry{\n\t\tlogger:     l,\n\t\tctx:        l.ctx,\n\t\tlevel:      LogLevelTrace,\n\t\tseverity:   LogSeverityTrace,\n\t\tattributes: make(map[string]attribute.Value),\n\t}\n}\n\nfunc (l *sentryLogger) Debug() LogEntry {\n\treturn &logEntry{\n\t\tlogger:     l,\n\t\tctx:        l.ctx,\n\t\tlevel:      LogLevelDebug,\n\t\tseverity:   LogSeverityDebug,\n\t\tattributes: make(map[string]attribute.Value),\n\t}\n}\n\nfunc (l *sentryLogger) Info() LogEntry {\n\treturn &logEntry{\n\t\tlogger:     l,\n\t\tctx:        l.ctx,\n\t\tlevel:      LogLevelInfo,\n\t\tseverity:   LogSeverityInfo,\n\t\tattributes: make(map[string]attribute.Value),\n\t}\n}\n\nfunc (l *sentryLogger) Warn() LogEntry {\n\treturn &logEntry{\n\t\tlogger:     l,\n\t\tctx:        l.ctx,\n\t\tlevel:      LogLevelWarn,\n\t\tseverity:   LogSeverityWarning,\n\t\tattributes: make(map[string]attribute.Value),\n\t}\n}\n\nfunc (l *sentryLogger) Error() LogEntry {\n\treturn &logEntry{\n\t\tlogger:     l,\n\t\tctx:        l.ctx,\n\t\tlevel:      LogLevelError,\n\t\tseverity:   LogSeverityError,\n\t\tattributes: make(map[string]attribute.Value),\n\t}\n}\n\nfunc (l *sentryLogger) Fatal() LogEntry {\n\treturn &logEntry{\n\t\tlogger:      l,\n\t\tctx:         l.ctx,\n\t\tlevel:       LogLevelFatal,\n\t\tseverity:    LogSeverityFatal,\n\t\tattributes:  make(map[string]attribute.Value),\n\t\tshouldFatal: true,\n\t}\n}\n\nfunc (l *sentryLogger) Panic() LogEntry {\n\treturn &logEntry{\n\t\tlogger:      l,\n\t\tctx:         l.ctx,\n\t\tlevel:       LogLevelFatal,\n\t\tseverity:    LogSeverityFatal,\n\t\tattributes:  make(map[string]attribute.Value),\n\t\tshouldPanic: true,\n\t}\n}\n\nfunc (l *sentryLogger) LFatal() LogEntry {\n\treturn &logEntry{\n\t\tlogger:     l,\n\t\tctx:        l.ctx,\n\t\tlevel:      LogLevelFatal,\n\t\tseverity:   LogSeverityFatal,\n\t\tattributes: make(map[string]attribute.Value),\n\t}\n}\n\nfunc (l *sentryLogger) GetCtx() context.Context {\n\treturn l.ctx\n}\n\nfunc (e *logEntry) WithCtx(ctx context.Context) LogEntry {\n\treturn &logEntry{\n\t\tlogger:      e.logger,\n\t\tctx:         ctx,\n\t\tlevel:       e.level,\n\t\tseverity:    e.severity,\n\t\tattributes:  maps.Clone(e.attributes),\n\t\tshouldPanic: e.shouldPanic,\n\t\tshouldFatal: e.shouldFatal,\n\t}\n}\n\nfunc (e *logEntry) String(key, value string) LogEntry {\n\te.attributes[key] = attribute.StringValue(value)\n\treturn e\n}\n\nfunc (e *logEntry) Int(key string, value int) LogEntry {\n\te.attributes[key] = attribute.Int64Value(int64(value))\n\treturn e\n}\n\nfunc (e *logEntry) Int64(key string, value int64) LogEntry {\n\te.attributes[key] = attribute.Int64Value(value)\n\treturn e\n}\n\nfunc (e *logEntry) Float64(key string, value float64) LogEntry {\n\te.attributes[key] = attribute.Float64Value(value)\n\treturn e\n}\n\nfunc (e *logEntry) Bool(key string, value bool) LogEntry {\n\te.attributes[key] = attribute.BoolValue(value)\n\treturn e\n}\n\n// Uint64 adds uint64 attributes to the log entry.\n//\n// This method is intentionally not part of the LogEntry interface to avoid exposing uint64 in the public API.\nfunc (e *logEntry) Uint64(key string, value uint64) LogEntry {\n\te.attributes[key] = attribute.Uint64Value(value)\n\treturn e\n}\n\nfunc (e *logEntry) Emit(args ...interface{}) {\n\te.logger.log(e.ctx, e.level, e.severity, fmt.Sprint(args...), e.attributes)\n\n\tif e.level == LogLevelFatal {\n\t\tif e.shouldPanic {\n\t\t\tpanic(fmt.Sprint(args...))\n\t\t}\n\t\tif e.shouldFatal {\n\t\t\tos.Exit(1)\n\t\t}\n\t}\n}\n\nfunc (e *logEntry) Emitf(format string, args ...interface{}) {\n\te.logger.log(e.ctx, e.level, e.severity, format, e.attributes, args...)\n\n\tif e.level == LogLevelFatal {\n\t\tif e.shouldPanic {\n\t\t\tformattedMessage := fmt.Sprintf(format, args...)\n\t\t\tpanic(formattedMessage)\n\t\t}\n\t\tif e.shouldFatal {\n\t\t\tos.Exit(1)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/log_batch_processor.go",
    "content": "package sentry\n\nimport (\n\t\"time\"\n)\n\n// logBatchProcessor batches logs and sends them to Sentry.\ntype logBatchProcessor struct {\n\t*batchProcessor[Log]\n}\n\nfunc newLogBatchProcessor(client *Client) *logBatchProcessor {\n\treturn &logBatchProcessor{\n\t\tbatchProcessor: newBatchProcessor(func(items []Log) {\n\t\t\tif len(items) == 0 {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tevent := NewEvent()\n\t\t\tevent.Timestamp = time.Now()\n\t\t\tevent.EventID = EventID(uuid())\n\t\t\tevent.Type = logEvent.Type\n\t\t\tevent.Logs = items\n\n\t\t\tclient.Transport.SendEvent(event)\n\t\t}),\n\t}\n}\n\nfunc (p *logBatchProcessor) Send(log *Log) bool {\n\treturn p.batchProcessor.Send(*log)\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/log_fallback.go",
    "content": "package sentry\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/getsentry/sentry-go/attribute\"\n\t\"github.com/getsentry/sentry-go/internal/debuglog\"\n)\n\n// Fallback, no-op logger if logging is disabled.\ntype noopLogger struct{}\n\n// noopLogEntry implements LogEntry for the no-op logger.\ntype noopLogEntry struct {\n\tlevel       LogLevel\n\tshouldPanic bool\n\tshouldFatal bool\n}\n\nfunc (n *noopLogEntry) WithCtx(_ context.Context) LogEntry {\n\treturn n\n}\n\nfunc (n *noopLogEntry) String(_, _ string) LogEntry {\n\treturn n\n}\n\nfunc (n *noopLogEntry) Int(_ string, _ int) LogEntry {\n\treturn n\n}\n\nfunc (n *noopLogEntry) Int64(_ string, _ int64) LogEntry {\n\treturn n\n}\n\nfunc (n *noopLogEntry) Float64(_ string, _ float64) LogEntry {\n\treturn n\n}\n\nfunc (n *noopLogEntry) Bool(_ string, _ bool) LogEntry {\n\treturn n\n}\n\nfunc (n *noopLogEntry) Attributes(_ ...attribute.Builder) LogEntry {\n\treturn n\n}\n\nfunc (n *noopLogEntry) Emit(args ...interface{}) {\n\tdebuglog.Printf(\"Log with level=[%v] is being dropped. Turn on logging via EnableLogs\", n.level)\n\tif n.level == LogLevelFatal {\n\t\tif n.shouldPanic {\n\t\t\tpanic(args)\n\t\t}\n\t\tif n.shouldFatal {\n\t\t\tos.Exit(1)\n\t\t}\n\t}\n}\n\nfunc (n *noopLogEntry) Emitf(message string, args ...interface{}) {\n\tdebuglog.Printf(\"Log with level=[%v] is being dropped. Turn on logging via EnableLogs\", n.level)\n\tif n.level == LogLevelFatal {\n\t\tif n.shouldPanic {\n\t\t\tpanic(fmt.Sprintf(message, args...))\n\t\t}\n\t\tif n.shouldFatal {\n\t\t\tos.Exit(1)\n\t\t}\n\t}\n}\n\nfunc (n *noopLogger) GetCtx() context.Context { return context.Background() }\n\nfunc (*noopLogger) Trace() LogEntry {\n\treturn &noopLogEntry{level: LogLevelTrace}\n}\n\nfunc (*noopLogger) Debug() LogEntry {\n\treturn &noopLogEntry{level: LogLevelDebug}\n}\n\nfunc (*noopLogger) Info() LogEntry {\n\treturn &noopLogEntry{level: LogLevelInfo}\n}\n\nfunc (*noopLogger) Warn() LogEntry {\n\treturn &noopLogEntry{level: LogLevelWarn}\n}\n\nfunc (*noopLogger) Error() LogEntry {\n\treturn &noopLogEntry{level: LogLevelError}\n}\n\nfunc (*noopLogger) Fatal() LogEntry {\n\treturn &noopLogEntry{level: LogLevelFatal, shouldFatal: true}\n}\n\nfunc (*noopLogger) Panic() LogEntry {\n\treturn &noopLogEntry{level: LogLevelFatal, shouldPanic: true}\n}\n\nfunc (*noopLogger) LFatal() LogEntry {\n\treturn &noopLogEntry{level: LogLevelFatal}\n}\n\nfunc (*noopLogger) SetAttributes(...attribute.Builder) {\n\tdebuglog.Printf(\"No attributes attached. Turn on logging via EnableLogs\")\n}\n\nfunc (*noopLogger) Write(_ []byte) (n int, err error) {\n\treturn 0, fmt.Errorf(\"log with level=[%v] is being dropped. Turn on logging via EnableLogs\", LogLevelInfo)\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/metric_batch_processor.go",
    "content": "package sentry\n\nimport (\n\t\"time\"\n)\n\n// metricBatchProcessor batches metrics and sends them to Sentry.\ntype metricBatchProcessor struct {\n\t*batchProcessor[Metric]\n}\n\nfunc newMetricBatchProcessor(client *Client) *metricBatchProcessor {\n\treturn &metricBatchProcessor{\n\t\tbatchProcessor: newBatchProcessor(func(items []Metric) {\n\t\t\tif len(items) == 0 {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tevent := NewEvent()\n\t\t\tevent.Timestamp = time.Now()\n\t\t\tevent.EventID = EventID(uuid())\n\t\t\tevent.Type = traceMetricEvent.Type\n\t\t\tevent.Metrics = items\n\n\t\t\tclient.Transport.SendEvent(event)\n\t\t}),\n\t}\n}\n\nfunc (p *metricBatchProcessor) Send(metric *Metric) bool {\n\treturn p.batchProcessor.Send(*metric)\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/metrics.go",
    "content": "package sentry\n\nimport (\n\t\"context\"\n\t\"maps\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go/attribute\"\n\t\"github.com/getsentry/sentry-go/internal/debuglog\"\n)\n\n// Duration Units.\nconst (\n\tUnitNanosecond  = \"nanosecond\"\n\tUnitMicrosecond = \"microsecond\"\n\tUnitMillisecond = \"millisecond\"\n\tUnitSecond      = \"second\"\n\tUnitMinute      = \"minute\"\n\tUnitHour        = \"hour\"\n\tUnitDay         = \"day\"\n\tUnitWeek        = \"week\"\n)\n\n// Information Units.\nconst (\n\tUnitBit      = \"bit\"\n\tUnitByte     = \"byte\"\n\tUnitKilobyte = \"kilobyte\"\n\tUnitKibibyte = \"kibibyte\"\n\tUnitMegabyte = \"megabyte\"\n\tUnitMebibyte = \"mebibyte\"\n\tUnitGigabyte = \"gigabyte\"\n\tUnitGibibyte = \"gibibyte\"\n\tUnitTerabyte = \"terabyte\"\n\tUnitTebibyte = \"tebibyte\"\n\tUnitPetabyte = \"petabyte\"\n\tUnitPebibyte = \"pebibyte\"\n\tUnitExabyte  = \"exabyte\"\n\tUnitExbibyte = \"exbibyte\"\n)\n\n// Fraction Units.\nconst (\n\tUnitRatio   = \"ratio\"\n\tUnitPercent = \"percent\"\n)\n\n// NewMeter returns a new Meter. If there is no Client bound to the current hub, or if metrics are disabled,\n// it returns a no-op Meter that discards all metrics.\nfunc NewMeter(ctx context.Context) Meter {\n\thub := GetHubFromContext(ctx)\n\tif hub == nil {\n\t\thub = CurrentHub()\n\t}\n\tclient := hub.Client()\n\tif client != nil && !client.options.DisableMetrics {\n\t\t// build default attrs\n\t\tserverAddr := client.options.ServerName\n\t\tif serverAddr == \"\" {\n\t\t\tserverAddr, _ = os.Hostname()\n\t\t}\n\n\t\tdefaults := map[string]string{\n\t\t\t\"sentry.release\":        client.options.Release,\n\t\t\t\"sentry.environment\":    client.options.Environment,\n\t\t\t\"sentry.server.address\": serverAddr,\n\t\t\t\"sentry.sdk.name\":       client.sdkIdentifier,\n\t\t\t\"sentry.sdk.version\":    client.sdkVersion,\n\t\t}\n\n\t\tdefaultAttrs := make(map[string]attribute.Value)\n\t\tfor k, v := range defaults {\n\t\t\tif v != \"\" {\n\t\t\t\tdefaultAttrs[k] = attribute.StringValue(v)\n\t\t\t}\n\t\t}\n\n\t\treturn &sentryMeter{\n\t\t\tctx:               ctx,\n\t\t\thub:               hub,\n\t\t\tattributes:        make(map[string]attribute.Value),\n\t\t\tdefaultAttributes: defaultAttrs,\n\t\t\tmu:                sync.RWMutex{},\n\t\t}\n\t}\n\n\tdebuglog.Printf(\"fallback to noopMeter: metrics disabled\")\n\treturn &noopMeter{}\n}\n\ntype sentryMeter struct {\n\tctx               context.Context\n\thub               *Hub\n\tattributes        map[string]attribute.Value\n\tdefaultAttributes map[string]attribute.Value\n\tmu                sync.RWMutex\n}\n\nfunc (m *sentryMeter) emit(ctx context.Context, metricType MetricType, name string, value MetricValue, unit string, attributes map[string]attribute.Value, customScope *Scope) {\n\tif name == \"\" {\n\t\tdebuglog.Println(\"empty name provided, dropping metric\")\n\t\treturn\n\t}\n\n\thub := hubFromContexts(ctx, m.ctx)\n\tif hub == nil {\n\t\thub = m.hub\n\t}\n\n\tclient := hub.Client()\n\tif client == nil {\n\t\treturn\n\t}\n\n\tscope := hub.Scope()\n\tif customScope != nil {\n\t\tscope = customScope\n\t}\n\ttraceID, spanID := resolveTrace(scope, ctx, m.ctx)\n\n\t// Pre-allocate with capacity hint to avoid map growth reallocations\n\testimatedCap := len(m.defaultAttributes) + len(attributes) + 8 // scope ~3 + call-specific ~5\n\tattrs := make(map[string]attribute.Value, estimatedCap)\n\n\t// attribute precedence: default -> scope -> instance (from SetAttrs) -> entry-specific\n\tfor k, v := range m.defaultAttributes {\n\t\tattrs[k] = v\n\t}\n\tscope.populateAttrs(attrs)\n\n\tm.mu.RLock()\n\tfor k, v := range m.attributes {\n\t\tattrs[k] = v\n\t}\n\tm.mu.RUnlock()\n\n\tfor k, v := range attributes {\n\t\tattrs[k] = v\n\t}\n\n\tmetric := &Metric{\n\t\tTimestamp:  time.Now(),\n\t\tTraceID:    traceID,\n\t\tSpanID:     spanID,\n\t\tType:       metricType,\n\t\tName:       name,\n\t\tValue:      value,\n\t\tUnit:       unit,\n\t\tAttributes: attrs,\n\t}\n\n\tif client.captureMetric(metric, scope) && client.options.Debug {\n\t\tdebuglog.Printf(\"Metric %s [%s]: %v %s\", metricType, name, value.AsInterface(), unit)\n\t}\n}\n\n// WithCtx returns a new Meter that uses the given context for trace/span association.\nfunc (m *sentryMeter) WithCtx(ctx context.Context) Meter {\n\tm.mu.RLock()\n\tattrsCopy := maps.Clone(m.attributes)\n\tm.mu.RUnlock()\n\n\treturn &sentryMeter{\n\t\tctx:               ctx,\n\t\thub:               m.hub,\n\t\tattributes:        attrsCopy,\n\t\tdefaultAttributes: m.defaultAttributes,\n\t\tmu:                sync.RWMutex{},\n\t}\n}\n\nfunc (m *sentryMeter) applyOptions(opts []MeterOption) *meterOptions {\n\to := &meterOptions{}\n\tfor _, opt := range opts {\n\t\topt(o)\n\t}\n\treturn o\n}\n\n// Count implements Meter.\nfunc (m *sentryMeter) Count(name string, count int64, opts ...MeterOption) {\n\to := m.applyOptions(opts)\n\tm.emit(m.ctx, MetricTypeCounter, name, Int64MetricValue(count), o.unit, o.attributes, o.scope)\n}\n\n// Distribution implements Meter.\nfunc (m *sentryMeter) Distribution(name string, sample float64, opts ...MeterOption) {\n\to := m.applyOptions(opts)\n\tm.emit(m.ctx, MetricTypeDistribution, name, Float64MetricValue(sample), o.unit, o.attributes, o.scope)\n}\n\n// Gauge implements Meter.\nfunc (m *sentryMeter) Gauge(name string, value float64, opts ...MeterOption) {\n\to := m.applyOptions(opts)\n\tm.emit(m.ctx, MetricTypeGauge, name, Float64MetricValue(value), o.unit, o.attributes, o.scope)\n}\n\n// SetAttributes implements Meter.\nfunc (m *sentryMeter) SetAttributes(attrs ...attribute.Builder) {\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\n\tfor _, a := range attrs {\n\t\tif a.Value.Type() == attribute.INVALID {\n\t\t\tdebuglog.Printf(\"invalid attribute: %v\", a)\n\t\t\tcontinue\n\t\t}\n\t\tm.attributes[a.Key] = a.Value\n\t}\n}\n\n// noopMeter is a no-operation implementation of Meter.\n// This is used when there is no client available in the context or when metrics are disabled.\ntype noopMeter struct{}\n\n// WithCtx implements Meter.\nfunc (n *noopMeter) WithCtx(_ context.Context) Meter {\n\treturn n\n}\n\n// Count implements Meter.\nfunc (n *noopMeter) Count(name string, _ int64, _ ...MeterOption) {\n\tdebuglog.Printf(\"Metric %q is being dropped. Turn on metrics by setting DisableMetrics to false\", name)\n}\n\n// Distribution implements Meter.\nfunc (n *noopMeter) Distribution(name string, _ float64, _ ...MeterOption) {\n\tdebuglog.Printf(\"Metric %q is being dropped. Turn on metrics by setting DisableMetrics to false\", name)\n}\n\n// Gauge implements Meter.\nfunc (n *noopMeter) Gauge(name string, _ float64, _ ...MeterOption) {\n\tdebuglog.Printf(\"Metric %q is being dropped. Turn on metrics by setting DisableMetrics to false\", name)\n}\n\n// SetAttributes implements Meter.\nfunc (n *noopMeter) SetAttributes(_ ...attribute.Builder) {\n\tdebuglog.Printf(\"No attributes attached. Turn on metrics by setting DisableMetrics to false\")\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/mocks.go",
    "content": "package sentry\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"time\"\n)\n\n// MockScope implements [Scope] for use in tests.\ntype MockScope struct {\n\tbreadcrumb      *Breadcrumb\n\tshouldDropEvent bool\n}\n\nfunc (scope *MockScope) AddBreadcrumb(breadcrumb *Breadcrumb, _ int) {\n\tscope.breadcrumb = breadcrumb\n}\n\nfunc (scope *MockScope) ApplyToEvent(event *Event, _ *EventHint, _ *Client) *Event {\n\tif scope.shouldDropEvent {\n\t\treturn nil\n\t}\n\treturn event\n}\n\n// MockTransport implements [Transport] for use in tests.\ntype MockTransport struct {\n\tmu        sync.Mutex\n\tevents    []*Event\n\tlastEvent *Event\n}\n\nfunc (t *MockTransport) Configure(_ ClientOptions) {}\nfunc (t *MockTransport) SendEvent(event *Event) {\n\tt.mu.Lock()\n\tdefer t.mu.Unlock()\n\tt.events = append(t.events, event)\n\tt.lastEvent = event\n}\nfunc (t *MockTransport) Flush(_ time.Duration) bool {\n\treturn true\n}\nfunc (t *MockTransport) FlushWithContext(_ context.Context) bool { return true }\nfunc (t *MockTransport) Events() []*Event {\n\tt.mu.Lock()\n\tdefer t.mu.Unlock()\n\treturn t.events\n}\nfunc (t *MockTransport) Close() {}\n\n// MockLogEntry implements [sentry.LogEntry] for use in tests.\ntype MockLogEntry struct {\n\tAttributes map[string]any\n}\n\nfunc NewMockLogEntry() *MockLogEntry {\n\treturn &MockLogEntry{Attributes: make(map[string]any)}\n}\n\nfunc (m *MockLogEntry) WithCtx(_ context.Context) LogEntry { return m }\nfunc (m *MockLogEntry) String(key, value string) LogEntry  { m.Attributes[key] = value; return m }\nfunc (m *MockLogEntry) Int(key string, value int) LogEntry {\n\tm.Attributes[key] = int64(value)\n\treturn m\n}\nfunc (m *MockLogEntry) Int64(key string, value int64) LogEntry {\n\tm.Attributes[key] = value\n\treturn m\n}\nfunc (m *MockLogEntry) Float64(key string, value float64) LogEntry {\n\tm.Attributes[key] = value\n\treturn m\n}\nfunc (m *MockLogEntry) Bool(key string, value bool) LogEntry {\n\tm.Attributes[key] = value\n\treturn m\n}\nfunc (m *MockLogEntry) Emit(...any)          {}\nfunc (m *MockLogEntry) Emitf(string, ...any) {}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/propagation_context.go",
    "content": "package sentry\n\nimport (\n\t\"crypto/rand\"\n)\n\ntype PropagationContext struct {\n\tTraceID                TraceID                `json:\"trace_id\"`\n\tSpanID                 SpanID                 `json:\"span_id\"`\n\tParentSpanID           SpanID                 `json:\"parent_span_id,omitzero\"`\n\tDynamicSamplingContext DynamicSamplingContext `json:\"-\"`\n}\n\nfunc (p PropagationContext) Map() map[string]interface{} {\n\tm := map[string]interface{}{\n\t\t\"trace_id\": p.TraceID,\n\t\t\"span_id\":  p.SpanID,\n\t}\n\n\tif p.ParentSpanID != zeroSpanID {\n\t\tm[\"parent_span_id\"] = p.ParentSpanID\n\t}\n\n\treturn m\n}\n\nfunc NewPropagationContext() PropagationContext {\n\tp := PropagationContext{}\n\n\tif _, err := rand.Read(p.TraceID[:]); err != nil {\n\t\tpanic(err)\n\t}\n\n\tif _, err := rand.Read(p.SpanID[:]); err != nil {\n\t\tpanic(err)\n\t}\n\n\treturn p\n}\n\nfunc PropagationContextFromHeaders(trace, baggage string) (PropagationContext, error) {\n\tp := NewPropagationContext()\n\n\tif _, err := rand.Read(p.SpanID[:]); err != nil {\n\t\tpanic(err)\n\t}\n\n\thasTrace := false\n\tif trace != \"\" {\n\t\tif tpc, valid := ParseTraceParentContext([]byte(trace)); valid {\n\t\t\thasTrace = true\n\t\t\tp.TraceID = tpc.TraceID\n\t\t\tp.ParentSpanID = tpc.ParentSpanID\n\t\t}\n\t}\n\n\tif baggage != \"\" {\n\t\tdsc, err := DynamicSamplingContextFromHeader([]byte(baggage))\n\t\tif err != nil {\n\t\t\treturn PropagationContext{}, err\n\t\t}\n\t\tp.DynamicSamplingContext = dsc\n\t}\n\n\t// In case a sentry-trace header is present but there are no sentry-related\n\t// values in the baggage, create an empty, frozen DynamicSamplingContext.\n\tif hasTrace && !p.DynamicSamplingContext.HasEntries() {\n\t\tp.DynamicSamplingContext = DynamicSamplingContext{\n\t\t\tFrozen: true,\n\t\t}\n\t}\n\n\treturn p, nil\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/scope.go",
    "content": "package sentry\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go/attribute\"\n\t\"github.com/getsentry/sentry-go/internal/debuglog\"\n)\n\n// Scope holds contextual data for the current scope.\n//\n// The scope is an object that can cloned efficiently and stores data that is\n// locally relevant to an event. For instance the scope will hold recorded\n// breadcrumbs and similar information.\n//\n// The scope can be interacted with in two ways. First, the scope is routinely\n// updated with information by functions such as AddBreadcrumb which will modify\n// the current scope. Second, the current scope can be configured through the\n// ConfigureScope function or Hub method of the same name.\n//\n// The scope is meant to be modified but not inspected directly. When preparing\n// an event for reporting, the current client adds information from the current\n// scope into the event.\ntype Scope struct {\n\tmu          sync.RWMutex\n\tbreadcrumbs []*Breadcrumb\n\tattachments []*Attachment\n\tuser        User\n\ttags        map[string]string\n\tcontexts    map[string]Context\n\textra       map[string]interface{}\n\tfingerprint []string\n\tlevel       Level\n\trequest     *http.Request\n\t// requestBody holds a reference to the original request.Body.\n\trequestBody interface {\n\t\t// Bytes returns bytes from the original body, lazily buffered as the\n\t\t// original body is read.\n\t\tBytes() []byte\n\t\t// Overflow returns true if the body is larger than the maximum buffer\n\t\t// size.\n\t\tOverflow() bool\n\t}\n\teventProcessors []EventProcessor\n\n\tpropagationContext PropagationContext\n\tspan               *Span\n}\n\n// NewScope creates a new Scope.\nfunc NewScope() *Scope {\n\treturn &Scope{\n\t\tbreadcrumbs:        make([]*Breadcrumb, 0),\n\t\tattachments:        make([]*Attachment, 0),\n\t\ttags:               make(map[string]string),\n\t\tcontexts:           make(map[string]Context),\n\t\textra:              make(map[string]interface{}),\n\t\tfingerprint:        make([]string, 0),\n\t\tpropagationContext: NewPropagationContext(),\n\t}\n}\n\n// AddBreadcrumb adds new breadcrumb to the current scope\n// and optionally throws the old one if limit is reached.\nfunc (scope *Scope) AddBreadcrumb(breadcrumb *Breadcrumb, limit int) {\n\tif breadcrumb.Timestamp.IsZero() {\n\t\tbreadcrumb.Timestamp = time.Now()\n\t}\n\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tscope.breadcrumbs = append(scope.breadcrumbs, breadcrumb)\n\tif len(scope.breadcrumbs) > limit {\n\t\tscope.breadcrumbs = scope.breadcrumbs[1 : limit+1]\n\t}\n}\n\n// ClearBreadcrumbs clears all breadcrumbs from the current scope.\nfunc (scope *Scope) ClearBreadcrumbs() {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tscope.breadcrumbs = []*Breadcrumb{}\n}\n\n// AddAttachment adds new attachment to the current scope.\nfunc (scope *Scope) AddAttachment(attachment *Attachment) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tscope.attachments = append(scope.attachments, attachment)\n}\n\n// ClearAttachments clears all attachments from the current scope.\nfunc (scope *Scope) ClearAttachments() {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tscope.attachments = []*Attachment{}\n}\n\n// SetUser sets the user for the current scope.\nfunc (scope *Scope) SetUser(user User) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tscope.user = user\n}\n\n// SetRequest sets the request for the current scope.\nfunc (scope *Scope) SetRequest(r *http.Request) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tscope.request = r\n\n\tif r == nil {\n\t\treturn\n\t}\n\n\t// Don't buffer request body if we know it is oversized.\n\tif r.ContentLength > maxRequestBodyBytes {\n\t\treturn\n\t}\n\t// Don't buffer if there is no body.\n\tif r.Body == nil || r.Body == http.NoBody {\n\t\treturn\n\t}\n\tbuf := &limitedBuffer{Capacity: maxRequestBodyBytes}\n\tr.Body = readCloser{\n\t\tReader: io.TeeReader(r.Body, buf),\n\t\tCloser: r.Body,\n\t}\n\tscope.requestBody = buf\n}\n\n// SetRequestBody sets the request body for the current scope.\n//\n// This method should only be called when the body bytes are already available\n// in memory. Typically, the request body is buffered lazily from the\n// Request.Body from SetRequest.\nfunc (scope *Scope) SetRequestBody(b []byte) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tcapacity := maxRequestBodyBytes\n\toverflow := false\n\tif len(b) > capacity {\n\t\toverflow = true\n\t\tb = b[:capacity]\n\t}\n\tscope.requestBody = &limitedBuffer{\n\t\tCapacity: capacity,\n\t\tBuffer:   *bytes.NewBuffer(b),\n\t\toverflow: overflow,\n\t}\n}\n\n// maxRequestBodyBytes is the default maximum request body size to send to\n// Sentry.\nconst maxRequestBodyBytes = 10 * 1024\n\n// A limitedBuffer is like a bytes.Buffer, but limited to store at most Capacity\n// bytes. Any writes past the capacity are silently discarded, similar to\n// io.Discard.\ntype limitedBuffer struct {\n\tCapacity int\n\n\tbytes.Buffer\n\toverflow bool\n}\n\n// Write implements io.Writer.\nfunc (b *limitedBuffer) Write(p []byte) (n int, err error) {\n\t// Silently ignore writes after overflow.\n\tif b.overflow {\n\t\treturn len(p), nil\n\t}\n\tleft := b.Capacity - b.Len()\n\tif left < 0 {\n\t\tleft = 0\n\t}\n\tif len(p) > left {\n\t\tb.overflow = true\n\t\tp = p[:left]\n\t}\n\treturn b.Buffer.Write(p)\n}\n\n// Overflow returns true if the limitedBuffer discarded bytes written to it.\nfunc (b *limitedBuffer) Overflow() bool {\n\treturn b.overflow\n}\n\n// readCloser combines an io.Reader and an io.Closer to implement io.ReadCloser.\ntype readCloser struct {\n\tio.Reader\n\tio.Closer\n}\n\n// SetTag adds a tag to the current scope.\nfunc (scope *Scope) SetTag(key, value string) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tscope.tags[key] = value\n}\n\n// SetTags assigns multiple tags to the current scope.\nfunc (scope *Scope) SetTags(tags map[string]string) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tfor k, v := range tags {\n\t\tscope.tags[k] = v\n\t}\n}\n\n// RemoveTag removes a tag from the current scope.\nfunc (scope *Scope) RemoveTag(key string) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tdelete(scope.tags, key)\n}\n\n// SetContext adds a context to the current scope.\nfunc (scope *Scope) SetContext(key string, value Context) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tscope.contexts[key] = value\n}\n\n// SetContexts assigns multiple contexts to the current scope.\nfunc (scope *Scope) SetContexts(contexts map[string]Context) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tfor k, v := range contexts {\n\t\tscope.contexts[k] = v\n\t}\n}\n\n// RemoveContext removes a context from the current scope.\nfunc (scope *Scope) RemoveContext(key string) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tdelete(scope.contexts, key)\n}\n\n// SetExtra adds an extra to the current scope.\nfunc (scope *Scope) SetExtra(key string, value interface{}) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tscope.extra[key] = value\n}\n\n// SetExtras assigns multiple extras to the current scope.\nfunc (scope *Scope) SetExtras(extra map[string]interface{}) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tfor k, v := range extra {\n\t\tscope.extra[k] = v\n\t}\n}\n\n// RemoveExtra removes a extra from the current scope.\nfunc (scope *Scope) RemoveExtra(key string) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tdelete(scope.extra, key)\n}\n\n// SetFingerprint sets new fingerprint for the current scope.\nfunc (scope *Scope) SetFingerprint(fingerprint []string) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tscope.fingerprint = fingerprint\n}\n\n// SetLevel sets new level for the current scope.\nfunc (scope *Scope) SetLevel(level Level) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tscope.level = level\n}\n\n// SetPropagationContext sets the propagation context for the current scope.\nfunc (scope *Scope) SetPropagationContext(propagationContext PropagationContext) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tscope.propagationContext = propagationContext\n}\n\n// GetSpan returns the span from the current scope.\nfunc (scope *Scope) GetSpan() *Span {\n\tscope.mu.RLock()\n\tdefer scope.mu.RUnlock()\n\n\treturn scope.span\n}\n\n// SetSpan sets a span for the current scope.\nfunc (scope *Scope) SetSpan(span *Span) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tscope.span = span\n}\n\n// Clone returns a copy of the current scope with all data copied over.\nfunc (scope *Scope) Clone() *Scope {\n\tscope.mu.RLock()\n\tdefer scope.mu.RUnlock()\n\n\tclone := NewScope()\n\tclone.user = scope.user\n\tclone.breadcrumbs = make([]*Breadcrumb, len(scope.breadcrumbs))\n\tcopy(clone.breadcrumbs, scope.breadcrumbs)\n\tclone.attachments = make([]*Attachment, len(scope.attachments))\n\tcopy(clone.attachments, scope.attachments)\n\tfor key, value := range scope.tags {\n\t\tclone.tags[key] = value\n\t}\n\tfor key, value := range scope.contexts {\n\t\tclone.contexts[key] = cloneContext(value)\n\t}\n\tfor key, value := range scope.extra {\n\t\tclone.extra[key] = value\n\t}\n\tclone.fingerprint = make([]string, len(scope.fingerprint))\n\tcopy(clone.fingerprint, scope.fingerprint)\n\tclone.level = scope.level\n\tclone.request = scope.request\n\tclone.requestBody = scope.requestBody\n\tclone.eventProcessors = scope.eventProcessors\n\tclone.propagationContext = scope.propagationContext\n\tclone.span = scope.span\n\treturn clone\n}\n\n// Clear removes the data from the current scope. Not safe for concurrent use.\nfunc (scope *Scope) Clear() {\n\t*scope = *NewScope()\n}\n\n// AddEventProcessor adds an event processor to the current scope.\nfunc (scope *Scope) AddEventProcessor(processor EventProcessor) {\n\tscope.mu.Lock()\n\tdefer scope.mu.Unlock()\n\n\tscope.eventProcessors = append(scope.eventProcessors, processor)\n}\n\n// ApplyToEvent takes the data from the current scope and attaches it to the event.\nfunc (scope *Scope) ApplyToEvent(event *Event, hint *EventHint, client *Client) *Event {\n\tscope.mu.RLock()\n\tdefer scope.mu.RUnlock()\n\n\tif len(scope.breadcrumbs) > 0 {\n\t\tevent.Breadcrumbs = append(event.Breadcrumbs, scope.breadcrumbs...)\n\t}\n\n\tif len(scope.attachments) > 0 {\n\t\tevent.Attachments = append(event.Attachments, scope.attachments...)\n\t}\n\n\tif len(scope.tags) > 0 {\n\t\tif event.Tags == nil {\n\t\t\tevent.Tags = make(map[string]string, len(scope.tags))\n\t\t}\n\n\t\tfor key, value := range scope.tags {\n\t\t\tevent.Tags[key] = value\n\t\t}\n\t}\n\n\tif len(scope.contexts) > 0 {\n\t\tif event.Contexts == nil {\n\t\t\tevent.Contexts = make(map[string]Context)\n\t\t}\n\n\t\tfor key, value := range scope.contexts {\n\t\t\tif key == \"trace\" && event.Type == transactionType {\n\t\t\t\t// Do not override trace context of\n\t\t\t\t// transactions, otherwise it breaks the\n\t\t\t\t// transaction event representation.\n\t\t\t\t// For error events, the trace context is used\n\t\t\t\t// to link errors and traces/spans in Sentry.\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Ensure we are not overwriting event fields\n\t\t\tif _, ok := event.Contexts[key]; !ok {\n\t\t\t\tevent.Contexts[key] = cloneContext(value)\n\t\t\t}\n\t\t}\n\t}\n\n\tif event.Contexts == nil {\n\t\tevent.Contexts = make(map[string]Context)\n\t}\n\n\tif scope.span != nil {\n\t\tif _, ok := event.Contexts[\"trace\"]; !ok {\n\t\t\tevent.Contexts[\"trace\"] = scope.span.traceContext().Map()\n\t\t}\n\n\t\ttransaction := scope.span.GetTransaction()\n\t\tif transaction != nil {\n\t\t\tevent.sdkMetaData.dsc = DynamicSamplingContextFromTransaction(transaction)\n\t\t}\n\t} else {\n\t\tevent.Contexts[\"trace\"] = scope.propagationContext.Map()\n\n\t\tdsc := scope.propagationContext.DynamicSamplingContext\n\t\tif !dsc.HasEntries() && client != nil {\n\t\t\tdsc = DynamicSamplingContextFromScope(scope, client)\n\t\t}\n\t\tevent.sdkMetaData.dsc = dsc\n\t}\n\n\tif len(scope.extra) > 0 {\n\t\tif event.Extra == nil {\n\t\t\tevent.Extra = make(map[string]interface{}, len(scope.extra))\n\t\t}\n\n\t\tfor key, value := range scope.extra {\n\t\t\tevent.Extra[key] = value\n\t\t}\n\t}\n\n\tif event.User.IsEmpty() {\n\t\tevent.User = scope.user\n\t}\n\n\tif len(event.Fingerprint) == 0 {\n\t\tevent.Fingerprint = append(event.Fingerprint, scope.fingerprint...)\n\t}\n\n\tif scope.level != \"\" {\n\t\tevent.Level = scope.level\n\t}\n\n\tif event.Request == nil && scope.request != nil {\n\t\tevent.Request = NewRequest(scope.request)\n\t\t// NOTE: The SDK does not attempt to send partial request body data.\n\t\t//\n\t\t// The reason being that Sentry's ingest pipeline and UI are optimized\n\t\t// to show structured data. Additionally, tooling around PII scrubbing\n\t\t// relies on structured data; truncated request bodies would create\n\t\t// invalid payloads that are more prone to leaking PII data.\n\t\t//\n\t\t// Users can still send more data along their events if they want to,\n\t\t// for example using Event.Extra.\n\t\tif scope.requestBody != nil && !scope.requestBody.Overflow() {\n\t\t\tevent.Request.Data = string(scope.requestBody.Bytes())\n\t\t}\n\t}\n\n\tfor _, processor := range scope.eventProcessors {\n\t\tid := event.EventID\n\t\tevent = processor(event, hint)\n\t\tif event == nil {\n\t\t\tdebuglog.Printf(\"Event dropped by one of the Scope EventProcessors: %s\\n\", id)\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn event\n}\n\n// cloneContext returns a new context with keys and values copied from the passed one.\n//\n// Note: a new Context (map) is returned, but the function does NOT do\n// a proper deep copy: if some context values are pointer types (e.g. maps),\n// they won't be properly copied.\nfunc cloneContext(c Context) Context {\n\tres := make(Context, len(c))\n\tfor k, v := range c {\n\t\tres[k] = v\n\t}\n\treturn res\n}\n\nfunc (scope *Scope) populateAttrs(attrs map[string]attribute.Value) {\n\tif scope == nil {\n\t\treturn\n\t}\n\n\tscope.mu.RLock()\n\tdefer scope.mu.RUnlock()\n\n\t// Add user-related attributes\n\tif !scope.user.IsEmpty() {\n\t\tif scope.user.ID != \"\" {\n\t\t\tattrs[\"user.id\"] = attribute.StringValue(scope.user.ID)\n\t\t}\n\t\tif scope.user.Name != \"\" {\n\t\t\tattrs[\"user.name\"] = attribute.StringValue(scope.user.Name)\n\t\t}\n\t\tif scope.user.Email != \"\" {\n\t\t\tattrs[\"user.email\"] = attribute.StringValue(scope.user.Email)\n\t\t}\n\t}\n\n\t// In the future, add scope.attributes here\n\t// for k, v := range scope.attributes {\n\t//     attrs[k] = v\n\t// }\n}\n\n// hubFromContexts is a helper to return the first hub found in the given contexts.\nfunc hubFromContexts(ctxs ...context.Context) *Hub {\n\tfor _, ctx := range ctxs {\n\t\tif ctx == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif hub := GetHubFromContext(ctx); hub != nil {\n\t\t\treturn hub\n\t\t}\n\t}\n\treturn nil\n}\n\n// resolveTrace resolves trace ID and span ID from the given scope and contexts.\n//\n// The resolution order follows a most-specific-to-least-specific pattern:\n//  1. Check for span directly in contexts (SpanFromContext) - this is the most specific\n//     source as it represents a span explicitly attached to the current operation's context\n//  2. Check scope's span - provides access to span set on the hub's scope\n//  3. Fall back to scope's propagation context trace ID\n//\n// This ordering ensures we always use the most contextually relevant tracing information.\n// For example, if a specific span is active for an operation, we use that span's trace/span IDs\n// rather than accidentally using a different span that might be set on the hub's scope.\nfunc resolveTrace(scope *Scope, ctxs ...context.Context) (traceID TraceID, spanID SpanID) {\n\tvar span *Span\n\n\tfor _, ctx := range ctxs {\n\t\tif ctx == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif span = SpanFromContext(ctx); span != nil {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif scope != nil {\n\t\tscope.mu.RLock()\n\t\tif span == nil {\n\t\t\tspan = scope.span\n\t\t}\n\t\tif span != nil {\n\t\t\ttraceID = span.TraceID\n\t\t\tspanID = span.SpanID\n\t\t} else {\n\t\t\ttraceID = scope.propagationContext.TraceID\n\t\t}\n\t\tscope.mu.RUnlock()\n\t}\n\n\treturn traceID, spanID\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/sentry.go",
    "content": "package sentry\n\nimport (\n\t\"context\"\n\t\"time\"\n)\n\n// The version of the SDK.\nconst SDKVersion = \"0.43.0\"\n\n// apiVersion is the minimum version of the Sentry API compatible with the\n// sentry-go SDK.\nconst apiVersion = \"7\"\n\n// Init initializes the SDK with options. The returned error is non-nil if\n// options is invalid, for instance if a malformed DSN is provided.\nfunc Init(options ClientOptions) error {\n\thub := CurrentHub()\n\tclient, err := NewClient(options)\n\tif err != nil {\n\t\treturn err\n\t}\n\thub.BindClient(client)\n\treturn nil\n}\n\n// AddBreadcrumb records a new breadcrumb.\n//\n// The total number of breadcrumbs that can be recorded are limited by the\n// configuration on the client.\nfunc AddBreadcrumb(breadcrumb *Breadcrumb) {\n\thub := CurrentHub()\n\thub.AddBreadcrumb(breadcrumb, nil)\n}\n\n// CaptureMessage captures an arbitrary message.\nfunc CaptureMessage(message string) *EventID {\n\thub := CurrentHub()\n\treturn hub.CaptureMessage(message)\n}\n\n// CaptureException captures an error.\nfunc CaptureException(exception error) *EventID {\n\thub := CurrentHub()\n\treturn hub.CaptureException(exception)\n}\n\n// CaptureCheckIn captures a (cron) monitor check-in.\nfunc CaptureCheckIn(checkIn *CheckIn, monitorConfig *MonitorConfig) *EventID {\n\thub := CurrentHub()\n\treturn hub.CaptureCheckIn(checkIn, monitorConfig)\n}\n\n// CaptureEvent captures an event on the currently active client if any.\n//\n// The event must already be assembled. Typically code would instead use\n// the utility methods like CaptureException. The return value is the\n// event ID. In case Sentry is disabled or event was dropped, the return value will be nil.\nfunc CaptureEvent(event *Event) *EventID {\n\thub := CurrentHub()\n\treturn hub.CaptureEvent(event)\n}\n\n// Recover captures a panic.\nfunc Recover() *EventID {\n\tif err := recover(); err != nil {\n\t\thub := CurrentHub()\n\t\treturn hub.Recover(err)\n\t}\n\treturn nil\n}\n\n// RecoverWithContext captures a panic and passes relevant context object.\nfunc RecoverWithContext(ctx context.Context) *EventID {\n\terr := recover()\n\tif err == nil {\n\t\treturn nil\n\t}\n\n\thub := GetHubFromContext(ctx)\n\tif hub == nil {\n\t\thub = CurrentHub()\n\t}\n\n\treturn hub.RecoverWithContext(ctx, err)\n}\n\n// WithScope is a shorthand for CurrentHub().WithScope.\nfunc WithScope(f func(scope *Scope)) {\n\thub := CurrentHub()\n\thub.WithScope(f)\n}\n\n// ConfigureScope is a shorthand for CurrentHub().ConfigureScope.\nfunc ConfigureScope(f func(scope *Scope)) {\n\thub := CurrentHub()\n\thub.ConfigureScope(f)\n}\n\n// PushScope is a shorthand for CurrentHub().PushScope.\nfunc PushScope() {\n\thub := CurrentHub()\n\thub.PushScope()\n}\n\n// PopScope is a shorthand for CurrentHub().PopScope.\nfunc PopScope() {\n\thub := CurrentHub()\n\thub.PopScope()\n}\n\n// Flush waits until the underlying Transport sends any buffered events to the\n// Sentry server, blocking for at most the given timeout. It returns false if\n// the timeout was reached. In that case, some events may not have been sent.\n//\n// Flush should be called before terminating the program to avoid\n// unintentionally dropping events.\n//\n// Do not call Flush indiscriminately after every call to CaptureEvent,\n// CaptureException or CaptureMessage. Instead, to have the SDK send events over\n// the network synchronously, configure it to use the HTTPSyncTransport in the\n// call to Init.\nfunc Flush(timeout time.Duration) bool {\n\thub := CurrentHub()\n\treturn hub.Flush(timeout)\n}\n\n// FlushWithContext waits until the underlying Transport sends any buffered events\n// to the Sentry server, blocking for at most the duration specified by the context.\n// It returns false if the context is canceled before the events are sent. In such a case,\n// some events may not be delivered.\n//\n// FlushWithContext should be called before terminating the program to ensure no\n// events are unintentionally dropped.\n//\n// Avoid calling FlushWithContext indiscriminately after each call to CaptureEvent,\n// CaptureException, or CaptureMessage. To send events synchronously over the network,\n// configure the SDK to use HTTPSyncTransport during initialization with Init.\n\nfunc FlushWithContext(ctx context.Context) bool {\n\thub := CurrentHub()\n\treturn hub.FlushWithContext(ctx)\n}\n\n// LastEventID returns an ID of last captured event.\nfunc LastEventID() EventID {\n\thub := CurrentHub()\n\treturn hub.LastEventID()\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/sourcereader.go",
    "content": "package sentry\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"sync\"\n)\n\ntype sourceReader struct {\n\tmu    sync.Mutex\n\tcache map[string][][]byte\n}\n\nfunc newSourceReader() sourceReader {\n\treturn sourceReader{\n\t\tcache: make(map[string][][]byte),\n\t}\n}\n\nfunc (sr *sourceReader) readContextLines(filename string, line, context int) ([][]byte, int) {\n\tsr.mu.Lock()\n\tdefer sr.mu.Unlock()\n\n\tlines, ok := sr.cache[filename]\n\n\tif !ok {\n\t\tdata, err := os.ReadFile(filename)\n\t\tif err != nil {\n\t\t\tsr.cache[filename] = nil\n\t\t\treturn nil, 0\n\t\t}\n\t\tlines = bytes.Split(data, []byte{'\\n'})\n\t\tsr.cache[filename] = lines\n\t}\n\n\treturn sr.calculateContextLines(lines, line, context)\n}\n\nfunc (sr *sourceReader) calculateContextLines(lines [][]byte, line, context int) ([][]byte, int) {\n\t// Stacktrace lines are 1-indexed, slices are 0-indexed\n\tline--\n\n\t// contextLine points to a line that caused an issue itself, in relation to\n\t// returned slice.\n\tcontextLine := context\n\n\tif lines == nil || line >= len(lines) || line < 0 {\n\t\treturn nil, 0\n\t}\n\n\tif context < 0 {\n\t\tcontext = 0\n\t\tcontextLine = 0\n\t}\n\n\tstart := line - context\n\n\tif start < 0 {\n\t\tcontextLine += start\n\t\tstart = 0\n\t}\n\n\tend := line + context + 1\n\n\tif end > len(lines) {\n\t\tend = len(lines)\n\t}\n\n\treturn lines[start:end], contextLine\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/span_recorder.go",
    "content": "package sentry\n\nimport (\n\t\"sync\"\n\n\t\"github.com/getsentry/sentry-go/internal/debuglog\"\n)\n\n// A spanRecorder stores a span tree that makes up a transaction. Safe for\n// concurrent use. It is okay to add child spans from multiple goroutines.\ntype spanRecorder struct {\n\tmu           sync.Mutex\n\tspans        []*Span\n\toverflowOnce sync.Once\n}\n\n// record stores a span. The first stored span is assumed to be the root of a\n// span tree.\nfunc (r *spanRecorder) record(s *Span) {\n\tmaxSpans := defaultMaxSpans\n\tif client := CurrentHub().Client(); client != nil {\n\t\tmaxSpans = client.options.MaxSpans\n\t}\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\tif len(r.spans) >= maxSpans {\n\t\tr.overflowOnce.Do(func() {\n\t\t\troot := r.spans[0]\n\t\t\tdebuglog.Printf(\"Too many spans: dropping spans from transaction with TraceID=%s SpanID=%s limit=%d\",\n\t\t\t\troot.TraceID, root.SpanID, maxSpans)\n\t\t})\n\t\t// TODO(tracing): mark the transaction event in some way to\n\t\t// communicate that spans were dropped.\n\t\treturn\n\t}\n\tr.spans = append(r.spans, s)\n}\n\n// root returns the first recorded span. Returns nil if none have been recorded.\nfunc (r *spanRecorder) root() *Span {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\tif len(r.spans) == 0 {\n\t\treturn nil\n\t}\n\treturn r.spans[0]\n}\n\n// children returns a list of all recorded spans, except the root. Returns nil\n// if there are no children.\nfunc (r *spanRecorder) children() []*Span {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\tif len(r.spans) < 2 {\n\t\treturn nil\n\t}\n\treturn r.spans[1:]\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/stacktrace.go",
    "content": "package sentry\n\nimport (\n\t\"go/build\"\n\t\"reflect\"\n\t\"runtime\"\n\t\"slices\"\n\t\"strings\"\n)\n\nconst unknown string = \"unknown\"\n\n// The module download is split into two parts: downloading the go.mod and downloading the actual code.\n// If you have dependencies only needed for tests, then they will show up in your go.mod,\n// and go get will download their go.mods, but it will not download their code.\n// The test-only dependencies get downloaded only when you need it, such as the first time you run go test.\n//\n// https://github.com/golang/go/issues/26913#issuecomment-411976222\n\n// Stacktrace holds information about the frames of the stack.\ntype Stacktrace struct {\n\tFrames        []Frame `json:\"frames,omitempty\"`\n\tFramesOmitted []uint  `json:\"frames_omitted,omitempty\"`\n}\n\n// NewStacktrace creates a stacktrace using runtime.Callers.\nfunc NewStacktrace() *Stacktrace {\n\tpcs := make([]uintptr, 100)\n\tn := runtime.Callers(1, pcs)\n\n\tif n == 0 {\n\t\treturn nil\n\t}\n\n\truntimeFrames := extractFrames(pcs[:n])\n\tframes := createFrames(runtimeFrames)\n\n\tstacktrace := Stacktrace{\n\t\tFrames: frames,\n\t}\n\n\treturn &stacktrace\n}\n\n// TODO: Make it configurable so that anyone can provide their own implementation?\n// Use of reflection allows us to not have a hard dependency on any given\n// package, so we don't have to import it.\n\n// ExtractStacktrace creates a new Stacktrace based on the given error.\nfunc ExtractStacktrace(err error) *Stacktrace {\n\tmethod := extractReflectedStacktraceMethod(err)\n\n\tvar pcs []uintptr\n\n\tif method.IsValid() {\n\t\tpcs = extractPcs(method)\n\t} else {\n\t\tpcs = extractXErrorsPC(err)\n\t}\n\n\tif len(pcs) == 0 {\n\t\treturn nil\n\t}\n\n\truntimeFrames := extractFrames(pcs)\n\tframes := createFrames(runtimeFrames)\n\n\tstacktrace := Stacktrace{\n\t\tFrames: frames,\n\t}\n\n\treturn &stacktrace\n}\n\nfunc extractReflectedStacktraceMethod(err error) reflect.Value {\n\terrValue := reflect.ValueOf(err)\n\n\t// https://github.com/go-errors/errors\n\tmethodStackFrames := errValue.MethodByName(\"StackFrames\")\n\tif methodStackFrames.IsValid() {\n\t\treturn methodStackFrames\n\t}\n\n\t// https://github.com/pkg/errors\n\tmethodStackTrace := errValue.MethodByName(\"StackTrace\")\n\tif methodStackTrace.IsValid() {\n\t\treturn methodStackTrace\n\t}\n\n\t// https://github.com/pingcap/errors\n\tmethodGetStackTracer := errValue.MethodByName(\"GetStackTracer\")\n\tif methodGetStackTracer.IsValid() {\n\t\tstacktracer := methodGetStackTracer.Call(nil)[0]\n\t\tstacktracerStackTrace := reflect.ValueOf(stacktracer).MethodByName(\"StackTrace\")\n\n\t\tif stacktracerStackTrace.IsValid() {\n\t\t\treturn stacktracerStackTrace\n\t\t}\n\t}\n\n\treturn reflect.Value{}\n}\n\nfunc extractPcs(method reflect.Value) []uintptr {\n\tvar pcs []uintptr\n\n\tstacktrace := method.Call(nil)[0]\n\n\tif stacktrace.Kind() != reflect.Slice {\n\t\treturn nil\n\t}\n\n\tfor i := 0; i < stacktrace.Len(); i++ {\n\t\tpc := stacktrace.Index(i)\n\n\t\tswitch pc.Kind() {\n\t\tcase reflect.Uintptr:\n\t\t\tpcs = append(pcs, uintptr(pc.Uint()))\n\t\tcase reflect.Struct:\n\t\t\tfor _, fieldName := range []string{\"ProgramCounter\", \"PC\"} {\n\t\t\t\tfield := pc.FieldByName(fieldName)\n\t\t\t\tif !field.IsValid() {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif field.Kind() == reflect.Uintptr {\n\t\t\t\t\tpcs = append(pcs, uintptr(field.Uint()))\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn pcs\n}\n\n// extractXErrorsPC extracts program counters from error values compatible with\n// the error types from golang.org/x/xerrors.\n//\n// It returns nil if err is not compatible with errors from that package or if\n// no program counters are stored in err.\nfunc extractXErrorsPC(err error) []uintptr {\n\t// This implementation uses the reflect package to avoid a hard dependency\n\t// on third-party packages.\n\n\t// We don't know if err matches the expected type. For simplicity, instead\n\t// of trying to account for all possible ways things can go wrong, some\n\t// assumptions are made and if they are violated the code will panic. We\n\t// recover from any panic and ignore it, returning nil.\n\t//nolint: errcheck\n\tdefer func() { recover() }()\n\n\tfield := reflect.ValueOf(err).Elem().FieldByName(\"frame\") // type Frame struct{ frames [3]uintptr }\n\tfield = field.FieldByName(\"frames\")\n\tfield = field.Slice(1, field.Len()) // drop first pc pointing to xerrors.New\n\tpc := make([]uintptr, field.Len())\n\tfor i := 0; i < field.Len(); i++ {\n\t\tpc[i] = uintptr(field.Index(i).Uint())\n\t}\n\treturn pc\n}\n\n// Frame represents a function call and it's metadata. Frames are associated\n// with a Stacktrace.\ntype Frame struct {\n\tFunction string `json:\"function,omitempty\"`\n\tSymbol   string `json:\"symbol,omitempty\"`\n\t// Module is, despite the name, the Sentry protocol equivalent of a Go\n\t// package's import path.\n\tModule      string                 `json:\"module,omitempty\"`\n\tFilename    string                 `json:\"filename,omitempty\"`\n\tAbsPath     string                 `json:\"abs_path,omitempty\"`\n\tLineno      int                    `json:\"lineno,omitempty\"`\n\tColno       int                    `json:\"colno,omitempty\"`\n\tPreContext  []string               `json:\"pre_context,omitempty\"`\n\tContextLine string                 `json:\"context_line,omitempty\"`\n\tPostContext []string               `json:\"post_context,omitempty\"`\n\tInApp       bool                   `json:\"in_app\"`\n\tVars        map[string]interface{} `json:\"vars,omitempty\"`\n\t// Package and the below are not used for Go stack trace frames.  In\n\t// other platforms it refers to a container where the Module can be\n\t// found.  For example, a Java JAR, a .NET Assembly, or a native\n\t// dynamic library.  They exists for completeness, allowing the\n\t// construction and reporting of custom event payloads.\n\tPackage         string `json:\"package,omitempty\"`\n\tInstructionAddr string `json:\"instruction_addr,omitempty\"`\n\tAddrMode        string `json:\"addr_mode,omitempty\"`\n\tSymbolAddr      string `json:\"symbol_addr,omitempty\"`\n\tImageAddr       string `json:\"image_addr,omitempty\"`\n\tPlatform        string `json:\"platform,omitempty\"`\n\tStackStart      bool   `json:\"stack_start,omitempty\"`\n}\n\n// NewFrame assembles a stacktrace frame out of runtime.Frame.\nfunc NewFrame(f runtime.Frame) Frame {\n\tfunction := f.Function\n\tvar pkg string\n\n\tif function != \"\" {\n\t\tpkg, function = splitQualifiedFunctionName(function)\n\t}\n\n\treturn newFrame(pkg, function, f.File, f.Line)\n}\n\n// Like filepath.IsAbs() but doesn't care what platform you run this on.\n// I.e. it also recognizies `/path/to/file` when run on Windows.\nfunc isAbsPath(path string) bool {\n\tif len(path) == 0 {\n\t\treturn false\n\t}\n\n\t// If the volume name starts with a double slash, this is an absolute path.\n\tif len(path) >= 1 && (path[0] == '/' || path[0] == '\\\\') {\n\t\treturn true\n\t}\n\n\t// Windows absolute path, see https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats\n\tif len(path) >= 3 && path[1] == ':' && (path[2] == '/' || path[2] == '\\\\') {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc newFrame(module string, function string, file string, line int) Frame {\n\tframe := Frame{\n\t\tLineno:   line,\n\t\tModule:   module,\n\t\tFunction: function,\n\t}\n\n\tswitch {\n\tcase len(file) == 0:\n\t\tframe.Filename = unknown\n\t\t// Leave abspath as the empty string to be omitted when serializing event as JSON.\n\tcase isAbsPath(file):\n\t\tframe.AbsPath = file\n\t\t// TODO: in the general case, it is not trivial to come up with a\n\t\t// \"project relative\" path with the data we have in run time.\n\t\t// We shall not use filepath.Base because it creates ambiguous paths and\n\t\t// affects the \"Suspect Commits\" feature.\n\t\t// For now, leave relpath empty to be omitted when serializing the event\n\t\t// as JSON. Improve this later.\n\tdefault:\n\t\t// f.File is a relative path. This may happen when the binary is built\n\t\t// with the -trimpath flag.\n\t\tframe.Filename = file\n\t\t// Omit abspath when serializing the event as JSON.\n\t}\n\n\tsetInAppFrame(&frame)\n\n\treturn frame\n}\n\n// splitQualifiedFunctionName splits a package path-qualified function name into\n// package name and function name. Such qualified names are found in\n// runtime.Frame.Function values.\nfunc splitQualifiedFunctionName(name string) (pkg string, fun string) {\n\tpkg = packageName(name)\n\tif len(pkg) > 0 {\n\t\tfun = name[len(pkg)+1:]\n\t}\n\treturn\n}\n\nfunc extractFrames(pcs []uintptr) []runtime.Frame {\n\tvar frames = make([]runtime.Frame, 0, len(pcs))\n\tcallersFrames := runtime.CallersFrames(pcs)\n\n\tfor {\n\t\tcallerFrame, more := callersFrames.Next()\n\n\t\tframes = append(frames, callerFrame)\n\n\t\tif !more {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tslices.Reverse(frames)\n\treturn frames\n}\n\n// createFrames creates Frame objects while filtering out frames that are not\n// meant to be reported to Sentry, those are frames internal to the SDK or Go.\nfunc createFrames(frames []runtime.Frame) []Frame {\n\tif len(frames) == 0 {\n\t\treturn nil\n\t}\n\n\tresult := make([]Frame, 0, len(frames))\n\n\tfor _, frame := range frames {\n\t\tfunction := frame.Function\n\t\tvar pkg string\n\t\tif function != \"\" {\n\t\t\tpkg, function = splitQualifiedFunctionName(function)\n\t\t}\n\n\t\tif !shouldSkipFrame(pkg) {\n\t\t\tresult = append(result, newFrame(pkg, function, frame.File, frame.Line))\n\t\t}\n\t}\n\n\t// Fix issues grouping errors with the new fully qualified function names\n\t// introduced from Go 1.21\n\tresult = cleanupFunctionNamePrefix(result)\n\treturn result\n}\n\n// TODO ID: why do we want to do this?\n// I'm not aware of other SDKs skipping all Sentry frames, regardless of their position in the stactrace.\n// For example, in the .NET SDK, only the first frames are skipped until the call to the SDK.\n// As is, this will also hide any intermediate frames in the stack and make debugging issues harder.\nfunc shouldSkipFrame(module string) bool {\n\t// Skip Go internal frames.\n\tif module == \"runtime\" || module == \"testing\" {\n\t\treturn true\n\t}\n\n\t// Skip Sentry internal frames, except for frames in _test packages (for testing).\n\tif strings.HasPrefix(module, \"github.com/getsentry/sentry-go\") &&\n\t\t!strings.HasSuffix(module, \"_test\") {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// On Windows, GOROOT has backslashes, but we want forward slashes.\nvar goRoot = strings.ReplaceAll(build.Default.GOROOT, \"\\\\\", \"/\")\n\nfunc setInAppFrame(frame *Frame) {\n\tframe.InApp = true\n\tif strings.HasPrefix(frame.AbsPath, goRoot) || strings.Contains(frame.Module, \"vendor\") ||\n\t\tstrings.Contains(frame.Module, \"third_party\") {\n\t\tframe.InApp = false\n\t}\n}\n\nfunc callerFunctionName() string {\n\tpcs := make([]uintptr, 1)\n\truntime.Callers(3, pcs)\n\tcallersFrames := runtime.CallersFrames(pcs)\n\tcallerFrame, _ := callersFrames.Next()\n\treturn baseName(callerFrame.Function)\n}\n\n// packageName returns the package part of the symbol name, or the empty string\n// if there is none.\n// It replicates https://golang.org/pkg/debug/gosym/#Sym.PackageName, avoiding a\n// dependency on debug/gosym.\nfunc packageName(name string) string {\n\tif isCompilerGeneratedSymbol(name) {\n\t\treturn \"\"\n\t}\n\n\tpathend := strings.LastIndex(name, \"/\")\n\tif pathend < 0 {\n\t\tpathend = 0\n\t}\n\n\tif i := strings.Index(name[pathend:], \".\"); i != -1 {\n\t\treturn name[:pathend+i]\n\t}\n\treturn \"\"\n}\n\n// baseName returns the symbol name without the package or receiver name.\n// It replicates https://golang.org/pkg/debug/gosym/#Sym.BaseName, avoiding a\n// dependency on debug/gosym.\nfunc baseName(name string) string {\n\tif i := strings.LastIndex(name, \".\"); i != -1 {\n\t\treturn name[i+1:]\n\t}\n\treturn name\n}\n\nfunc isCompilerGeneratedSymbol(name string) bool {\n\t// In versions of Go 1.20 and above a prefix of \"type:\" and \"go:\" is a\n\t// compiler-generated symbol that doesn't belong to any package.\n\t// See variable reservedimports in cmd/compile/internal/gc/subr.go\n\tif strings.HasPrefix(name, \"go:\") || strings.HasPrefix(name, \"type:\") {\n\t\treturn true\n\t}\n\treturn false\n}\n\n// Walk backwards through the results and for the current function name\n// remove it's parent function's prefix, leaving only it's actual name. This\n// fixes issues grouping errors with the new fully qualified function names\n// introduced from Go 1.21.\nfunc cleanupFunctionNamePrefix(f []Frame) []Frame {\n\tfor i := len(f) - 1; i > 0; i-- {\n\t\tname := f[i].Function\n\t\tparentName := f[i-1].Function + \".\"\n\n\t\tif !strings.HasPrefix(name, parentName) {\n\t\t\tcontinue\n\t\t}\n\n\t\tf[i].Function = name[len(parentName):]\n\t}\n\n\treturn f\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/traces_sampler.go",
    "content": "package sentry\n\n// A SamplingContext is passed to a TracesSampler to determine a sampling\n// decision.\n//\n// TODO(tracing): possibly expand SamplingContext to include custom /\n// user-provided data.\ntype SamplingContext struct {\n\tSpan   *Span // The current span, always non-nil.\n\tParent *Span // The parent span, may be nil.\n}\n\n// The TracesSample type is an adapter to allow the use of ordinary\n// functions as a TracesSampler.\ntype TracesSampler func(ctx SamplingContext) float64\n\nfunc (f TracesSampler) Sample(ctx SamplingContext) float64 {\n\treturn f(ctx)\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/tracing.go",
    "content": "package sentry\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go/internal/debuglog\"\n)\n\nconst (\n\tSentryTraceHeader   = \"sentry-trace\"\n\tSentryBaggageHeader = \"baggage\"\n\tTraceparentHeader   = \"traceparent\"\n)\n\n// SpanOrigin indicates what created a trace or a span. See: https://develop.sentry.dev/sdk/performance/trace-origin/\ntype SpanOrigin string\n\nconst (\n\tSpanOriginManual   = \"manual\"\n\tSpanOriginEcho     = \"auto.http.echo\"\n\tSpanOriginFastHTTP = \"auto.http.fasthttp\"\n\tSpanOriginFiber    = \"auto.http.fiber\"\n\tSpanOriginGin      = \"auto.http.gin\"\n\tSpanOriginStdLib   = \"auto.http.stdlib\"\n\tSpanOriginIris     = \"auto.http.iris\"\n\tSpanOriginNegroni  = \"auto.http.negroni\"\n)\n\n// A Span is the building block of a Sentry transaction. Spans build up a tree\n// structure of timed operations. The span tree makes up a transaction event\n// that is sent to Sentry when the root span is finished.\n//\n// Spans must be started with either StartSpan or Span.StartChild.\ntype Span struct { //nolint: maligned // prefer readability over optimal memory layout (see note below *)\n\tTraceID      TraceID           `json:\"trace_id\"`\n\tSpanID       SpanID            `json:\"span_id\"`\n\tParentSpanID SpanID            `json:\"parent_span_id,omitzero\"`\n\tName         string            `json:\"name,omitempty\"`\n\tOp           string            `json:\"op,omitempty\"`\n\tDescription  string            `json:\"description,omitempty\"`\n\tStatus       SpanStatus        `json:\"status,omitempty\"`\n\tTags         map[string]string `json:\"tags,omitempty\"`\n\tStartTime    time.Time         `json:\"start_timestamp,omitzero\"`\n\tEndTime      time.Time         `json:\"timestamp,omitzero\"`\n\t// Deprecated: use Data instead. To be removed in 0.33.0\n\tExtra   map[string]interface{} `json:\"-\"`\n\tData    map[string]interface{} `json:\"data,omitempty\"`\n\tSampled Sampled                `json:\"-\"`\n\tSource  TransactionSource      `json:\"-\"`\n\tOrigin  SpanOrigin             `json:\"origin,omitempty\"`\n\n\t// mu protects concurrent writes to map fields\n\tmu sync.RWMutex\n\t// sample rate the span was sampled with.\n\tsampleRate float64\n\t// ctx is the context where the span was started. Always non-nil.\n\tctx context.Context\n\t// Dynamic Sampling context\n\tdynamicSamplingContext DynamicSamplingContext\n\t// parent refers to the immediate local parent span. A remote parent span is\n\t// only referenced by setting ParentSpanID.\n\tparent *Span\n\t// recorder stores all spans in a transaction. Guaranteed to be non-nil.\n\trecorder *spanRecorder\n\t// span context, can only be set on transactions\n\tcontexts map[string]Context\n\t// a Once instance to make sure that Finish() is only called once.\n\tfinishOnce sync.Once\n\t// explicitSampled is a flag for configuring sampling by using `WithSpanSampled` option.\n\texplicitSampled Sampled\n}\n\n// TraceParentContext describes the context of a (remote) parent span.\n//\n// The context is normally extracted from a received \"sentry-trace\" header and\n// used to initialize a new transaction.\n//\n// Note: the name might be not the best one. It was taken mostly to stay aligned\n// with other SDKs, and it alludes to W3C \"traceparent\" header (https://www.w3.org/TR/trace-context/),\n// which serves a similar purpose to \"sentry-trace\". We should eventually consider\n// making this type internal-only and give it a better name.\ntype TraceParentContext struct {\n\tTraceID      TraceID\n\tParentSpanID SpanID\n\tSampled      Sampled\n}\n\n// (*) Note on maligned:\n//\n// We prefer readability over optimal memory layout. If we ever decide to\n// reorder fields, we can use a tool:\n//\n// go run honnef.co/go/tools/cmd/structlayout -json . Span | go run honnef.co/go/tools/cmd/structlayout-optimize\n//\n// Other structs would deserve reordering as well, for example Event.\n\n// TODO: make Span.Tags and Span.Data opaque types (struct{unexported []slice}).\n// An opaque type allows us to add methods and make it more convenient to use\n// than maps, because maps require careful nil checks to use properly or rely on\n// explicit initialization for every span, even when there might be no\n// tags/data. For Span.Data, must gracefully handle values that cannot be\n// marshaled into JSON (see transport.go:getRequestBodyFromEvent).\n\n// StartSpan starts a new span to describe an operation. The new span will be a\n// child of the last span stored in ctx, if any.\n//\n// One or more options can be used to modify the span properties. Typically one\n// option as a function literal is enough. Combining multiple options can be\n// useful to define and reuse specific properties with named functions.\n//\n// Caller should call the Finish method on the span to mark its end. Finishing a\n// root span sends the span and all of its children, recursively, as a\n// transaction to Sentry.\nfunc StartSpan(ctx context.Context, operation string, options ...SpanOption) *Span {\n\tparent, hasParent := ctx.Value(spanContextKey{}).(*Span)\n\tvar span Span\n\tspan = Span{\n\t\t// defaults\n\t\tOp:        operation,\n\t\tStartTime: time.Now(),\n\t\tSampled:   SampledUndefined,\n\n\t\tctx:    context.WithValue(ctx, spanContextKey{}, &span),\n\t\tparent: parent,\n\t}\n\n\t_, err := rand.Read(span.SpanID[:])\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tif hasParent {\n\t\tspan.TraceID = parent.TraceID\n\t\tspan.ParentSpanID = parent.SpanID\n\t\tspan.Origin = parent.Origin\n\t} else {\n\t\t// Only set the Source if this is a transaction\n\t\tspan.Source = SourceCustom\n\t\tspan.Origin = SpanOriginManual\n\n\t\t// Implementation note:\n\t\t//\n\t\t// While math/rand is ~2x faster than crypto/rand (exact\n\t\t// difference depends on hardware / OS), crypto/rand is probably\n\t\t// fast enough and a safer choice.\n\t\t//\n\t\t// For reference, OpenTelemetry [1] uses crypto/rand to seed\n\t\t// math/rand. AFAICT this approach does not preserve the\n\t\t// properties from crypto/rand that make it suitable for\n\t\t// cryptography. While it might be debatable whether those\n\t\t// properties are important for us here, again, we're taking the\n\t\t// safer path.\n\t\t//\n\t\t// See [2a] & [2b] for a discussion of some of the properties we\n\t\t// obtain by using crypto/rand and [3a] & [3b] for why we avoid\n\t\t// math/rand.\n\t\t//\n\t\t// Because the math/rand seed has only 64 bits (int64), if the\n\t\t// first thing we do after seeding an RNG is to read in a random\n\t\t// TraceID, there are only 2^64 possible values. Compared to\n\t\t// UUID v4 that have 122 random bits, there is a much greater\n\t\t// chance of collision [4a] & [4b].\n\t\t//\n\t\t// [1]:  https://github.com/open-telemetry/opentelemetry-go/blob/958041ddf619a128/sdk/trace/trace.go#L25-L31\n\t\t// [2a]: https://security.stackexchange.com/q/120352/246345\n\t\t// [2b]: https://security.stackexchange.com/a/120365/246345\n\t\t// [3a]: https://github.com/golang/go/issues/11871#issuecomment-126333686\n\t\t// [3b]: https://github.com/golang/go/issues/11871#issuecomment-126357889\n\t\t// [4a]: https://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions\n\t\t// [4b]: https://www.wolframalpha.com/input/?i=sqrt%282*2%5E64*ln%281%2F%281-0.5%29%29%29\n\t\t_, err := rand.Read(span.TraceID[:])\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n\n\t// Apply options to override defaults.\n\tfor _, option := range options {\n\t\toption(&span)\n\t}\n\n\tspan.Sampled = span.sample()\n\n\tspan.recorder = &spanRecorder{}\n\tif hasParent {\n\t\tspan.recorder = parent.spanRecorder()\n\t}\n\n\tspan.recorder.record(&span)\n\n\tclientOptions := span.clientOptions()\n\tif clientOptions.EnableTracing {\n\t\thub := hubFromContext(ctx)\n\t\thub.Scope().SetSpan(&span)\n\t}\n\n\treturn &span\n}\n\n// Finish sets the span's end time, unless already set. If the span is the root\n// of a span tree, Finish sends the span tree to Sentry as a transaction.\n//\n// The logic is executed at most once per span, so that (incorrectly) calling it twice\n// never double sends to Sentry.\nfunc (s *Span) Finish() {\n\ts.finishOnce.Do(s.doFinish)\n}\n\n// Context returns the context containing the span.\nfunc (s *Span) Context() context.Context { return s.ctx }\n\n// StartChild starts a new child span.\n//\n// The call span.StartChild(operation, options...) is a shortcut for\n// StartSpan(span.Context(), operation, options...).\nfunc (s *Span) StartChild(operation string, options ...SpanOption) *Span {\n\treturn StartSpan(s.Context(), operation, options...)\n}\n\n// SetTag sets a tag on the span. It is recommended to use SetTag instead of\n// accessing the tags map directly as SetTag takes care of initializing the map\n// when necessary.\nfunc (s *Span) SetTag(name, value string) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tif s.Tags == nil {\n\t\ts.Tags = make(map[string]string)\n\t}\n\ts.Tags[name] = value\n}\n\n// SetData sets a data on the span. It is recommended to use SetData instead of\n// accessing the data map directly as SetData takes care of initializing the map\n// when necessary.\nfunc (s *Span) SetData(name string, value interface{}) {\n\tif value == nil {\n\t\treturn\n\t}\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tif s.Data == nil {\n\t\ts.Data = make(map[string]interface{})\n\t}\n\ts.Data[name] = value\n}\n\n// SetContext sets a context on the span. It is recommended to use SetContext instead of\n// accessing the contexts map directly as SetContext takes care of initializing the map\n// when necessary.\nfunc (s *Span) SetContext(key string, value Context) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tif s.contexts == nil {\n\t\ts.contexts = make(map[string]Context)\n\t}\n\ts.contexts[key] = value\n}\n\n// IsTransaction checks if the given span is a transaction.\nfunc (s *Span) IsTransaction() bool {\n\treturn s.parent == nil\n}\n\n// GetTransaction returns the transaction that contains this span.\n//\n// For transaction spans it returns itself. For spans that were created manually\n// the method returns \"nil\".\nfunc (s *Span) GetTransaction() *Span {\n\tspanRecorder := s.spanRecorder()\n\tif spanRecorder == nil {\n\t\t// This probably means that the Span was created manually (not via\n\t\t// StartTransaction/StartSpan or StartChild).\n\t\t// Return \"nil\" to indicate that it's not a normal situation.\n\t\treturn nil\n\t}\n\trecorderRoot := spanRecorder.root()\n\tif recorderRoot == nil {\n\t\t// Same as above: manually created Span.\n\t\treturn nil\n\t}\n\treturn recorderRoot\n}\n\n// TODO(tracing): maybe add shortcuts to get/set transaction name. Right now the\n// transaction name is in the Scope, as it has existed there historically, prior\n// to tracing.\n//\n// See Scope.Transaction() and Scope.SetTransaction().\n//\n// func (s *Span) TransactionName() string\n// func (s *Span) SetTransactionName(name string)\n\n// ToSentryTrace returns the serialized TraceParentContext from a transaction/span.\n// Use this function to propagate the TraceParentContext to a downstream SDK,\n// either as the value of the \"sentry-trace\" HTTP header, or as an html \"sentry-trace\" meta tag.\nfunc (s *Span) ToSentryTrace() string {\n\t// TODO(tracing): add instrumentation for outgoing HTTP requests using\n\t// ToSentryTrace.\n\tvar b strings.Builder\n\tfmt.Fprintf(&b, \"%s-%s\", s.TraceID.Hex(), s.SpanID.Hex())\n\tswitch s.Sampled {\n\tcase SampledTrue:\n\t\tb.WriteString(\"-1\")\n\tcase SampledFalse:\n\t\tb.WriteString(\"-0\")\n\t}\n\treturn b.String()\n}\n\n// ToTraceparent returns the W3C traceparent header value for the span.\nfunc (s *Span) ToTraceparent() string {\n\ttraceFlags := \"00\"\n\tif s.Sampled == SampledTrue {\n\t\ttraceFlags = \"01\"\n\t}\n\treturn fmt.Sprintf(\"00-%s-%s-%s\", s.TraceID.String(), s.SpanID.String(), traceFlags)\n}\n\n// ToBaggage returns the serialized DynamicSamplingContext from a transaction.\n// Use this function to propagate the DynamicSamplingContext to a downstream SDK,\n// either as the value of the \"baggage\" HTTP header, or as an html \"baggage\" meta tag.\nfunc (s *Span) ToBaggage() string {\n\tt := s.GetTransaction()\n\tif t == nil {\n\t\treturn \"\"\n\t}\n\n\t// In case there is currently no frozen DynamicSamplingContext attached to the transaction,\n\t// create one from the properties of the transaction.\n\tif !s.dynamicSamplingContext.IsFrozen() {\n\t\t// This will return a frozen DynamicSamplingContext.\n\t\tif dsc := DynamicSamplingContextFromTransaction(t); dsc.HasEntries() {\n\t\t\tt.dynamicSamplingContext = dsc\n\t\t}\n\t}\n\n\treturn t.dynamicSamplingContext.String()\n}\n\n// SetDynamicSamplingContext sets the given dynamic sampling context on the\n// current transaction.\nfunc (s *Span) SetDynamicSamplingContext(dsc DynamicSamplingContext) {\n\tif s.IsTransaction() {\n\t\ts.dynamicSamplingContext = dsc\n\t}\n}\n\n// shouldIgnoreStatusCode checks if the transaction should be ignored based on HTTP status code.\nfunc (s *Span) shouldIgnoreStatusCode() bool {\n\tif !s.IsTransaction() {\n\t\treturn false\n\t}\n\n\tignoreStatusCodes := s.clientOptions().TraceIgnoreStatusCodes\n\tif len(ignoreStatusCodes) == 0 {\n\t\treturn false\n\t}\n\n\ts.mu.Lock()\n\tstatusCodeData, exists := s.Data[\"http.response.status_code\"]\n\ts.mu.Unlock()\n\n\tif !exists {\n\t\treturn false\n\t}\n\n\tstatusCode, ok := statusCodeData.(int)\n\tif !ok {\n\t\treturn false\n\t}\n\n\tfor _, ignoredRange := range ignoreStatusCodes {\n\t\tswitch len(ignoredRange) {\n\t\tcase 1:\n\t\t\t// Single status code\n\t\t\tif statusCode == ignoredRange[0] {\n\t\t\t\ts.mu.Lock()\n\t\t\t\ts.Sampled = SampledFalse\n\t\t\t\ts.mu.Unlock()\n\t\t\t\tdebuglog.Printf(\"dropping transaction with status code %v: found in TraceIgnoreStatusCodes\", statusCode)\n\t\t\t\treturn true\n\t\t\t}\n\t\tcase 2:\n\t\t\t// Range of status codes [min, max]\n\t\t\tif ignoredRange[0] <= statusCode && statusCode <= ignoredRange[1] {\n\t\t\t\ts.mu.Lock()\n\t\t\t\ts.Sampled = SampledFalse\n\t\t\t\ts.mu.Unlock()\n\t\t\t\tdebuglog.Printf(\"dropping transaction with status code %v: found in TraceIgnoreStatusCodes range [%d, %d]\", statusCode, ignoredRange[0], ignoredRange[1])\n\t\t\t\treturn true\n\t\t\t}\n\t\tdefault:\n\t\t\tdebuglog.Printf(\"incorrect TraceIgnoreStatusCodes format: %v\", ignoredRange)\n\t\t}\n\t}\n\n\treturn false\n}\n\n// doFinish runs the actual Span.Finish() logic.\nfunc (s *Span) doFinish() {\n\tif s.EndTime.IsZero() {\n\t\ts.EndTime = monotonicTimeSince(s.StartTime)\n\t}\n\n\thub := hubFromContext(s.ctx)\n\tif !s.IsTransaction() {\n\t\tif s.parent != nil {\n\t\t\thub.Scope().SetSpan(s.parent)\n\t\t}\n\t}\n\n\tif s.shouldIgnoreStatusCode() {\n\t\treturn\n\t}\n\n\tif !s.Sampled.Bool() {\n\t\treturn\n\t}\n\tevent := s.toEvent()\n\tif event == nil {\n\t\treturn\n\t}\n\n\t// TODO(tracing): add breadcrumbs\n\t// (see https://github.com/getsentry/sentry-python/blob/f6f3525f8812f609/sentry_sdk/tracing.py#L372)\n\n\thub.CaptureEvent(event)\n}\n\n// sentryTracePattern matches either\n//\n//\tTRACE_ID - SPAN_ID\n//\t[[:xdigit:]]{32}-[[:xdigit:]]{16}\n//\n// or\n//\n//\tTRACE_ID - SPAN_ID - SAMPLED\n//\t[[:xdigit:]]{32}-[[:xdigit:]]{16}-[01]\nvar sentryTracePattern = regexp.MustCompile(`^([[:xdigit:]]{32})-([[:xdigit:]]{16})(?:-([01]))?$`)\n\n// updateFromSentryTrace parses a sentry-trace HTTP header (as returned by\n// ToSentryTrace) and updates fields of the span. If the header cannot be\n// recognized as valid, the span is left unchanged. The returned value indicates\n// whether the span was updated.\nfunc (s *Span) updateFromSentryTrace(header []byte) (updated bool) {\n\tm := sentryTracePattern.FindSubmatch(header)\n\tif m == nil {\n\t\t// no match\n\t\treturn false\n\t}\n\t_, _ = hex.Decode(s.TraceID[:], m[1])\n\t_, _ = hex.Decode(s.ParentSpanID[:], m[2])\n\tif len(m[3]) != 0 {\n\t\tswitch m[3][0] {\n\t\tcase '0':\n\t\t\ts.Sampled = SampledFalse\n\t\tcase '1':\n\t\t\ts.Sampled = SampledTrue\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (s *Span) updateFromBaggage(header []byte) {\n\tif s.IsTransaction() {\n\t\tdsc, err := DynamicSamplingContextFromHeader(header)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\n\t\ts.dynamicSamplingContext = dsc\n\t}\n}\n\nfunc (s *Span) clientOptions() *ClientOptions {\n\tclient := hubFromContext(s.ctx).Client()\n\tif client != nil {\n\t\treturn &client.options\n\t}\n\treturn &ClientOptions{}\n}\n\nfunc (s *Span) sample() Sampled {\n\tclientOptions := s.clientOptions()\n\t// https://develop.sentry.dev/sdk/performance/#sampling\n\t// #1 tracing is not enabled.\n\tif !clientOptions.EnableTracing {\n\t\tdebuglog.Printf(\"Dropping transaction: EnableTracing is set to %t\", clientOptions.EnableTracing)\n\t\ts.sampleRate = 0.0\n\t\treturn SampledFalse\n\t}\n\n\t// #2 explicit sampling decision via StartSpan/StartTransaction options.\n\tif s.explicitSampled != SampledUndefined {\n\t\tdebuglog.Printf(\"Using explicit sampling decision from StartSpan/StartTransaction: %v\", s.explicitSampled)\n\t\tswitch s.explicitSampled {\n\t\tcase SampledTrue:\n\t\t\ts.sampleRate = 1.0\n\t\tcase SampledFalse:\n\t\t\ts.sampleRate = 0.0\n\t\t}\n\t\treturn s.explicitSampled\n\t}\n\n\t// Variant for non-transaction spans: they inherit the parent decision.\n\t// Note: non-transaction should always have a parent, but we check both\n\t// conditions anyway -- the first for semantic meaning, the second to\n\t// avoid a nil pointer dereference.\n\tif !s.IsTransaction() && s.parent != nil {\n\t\treturn s.parent.Sampled\n\t}\n\n\t// #3 use TracesSampler from ClientOptions.\n\tsampler := clientOptions.TracesSampler\n\tsamplingContext := SamplingContext{\n\t\tSpan:   s,\n\t\tParent: s.parent,\n\t}\n\n\tif sampler != nil {\n\t\ttracesSamplerSampleRate := sampler.Sample(samplingContext)\n\t\ts.sampleRate = tracesSamplerSampleRate\n\t\t// tracesSampler can update the sample_rate on frozen DSC\n\t\tif s.dynamicSamplingContext.HasEntries() {\n\t\t\ts.dynamicSamplingContext.Entries[\"sample_rate\"] = strconv.FormatFloat(tracesSamplerSampleRate, 'f', -1, 64)\n\t\t}\n\t\tif tracesSamplerSampleRate < 0.0 || tracesSamplerSampleRate > 1.0 {\n\t\t\tdebuglog.Printf(\"Dropping transaction: Returned TracesSampler rate is out of range [0.0, 1.0]: %f\", tracesSamplerSampleRate)\n\t\t\treturn SampledFalse\n\t\t}\n\t\tif tracesSamplerSampleRate == 0.0 {\n\t\t\tdebuglog.Printf(\"Dropping transaction: Returned TracesSampler rate is: %f\", tracesSamplerSampleRate)\n\t\t\treturn SampledFalse\n\t\t}\n\n\t\tif rng.Float64() < tracesSamplerSampleRate {\n\t\t\treturn SampledTrue\n\t\t}\n\t\tdebuglog.Printf(\"Dropping transaction: TracesSampler returned rate: %f\", tracesSamplerSampleRate)\n\n\t\treturn SampledFalse\n\t}\n\n\t// #4 inherit parent decision.\n\tif s.Sampled != SampledUndefined {\n\t\tdebuglog.Printf(\"Using sampling decision from parent: %v\", s.Sampled)\n\t\tswitch s.Sampled {\n\t\tcase SampledTrue:\n\t\t\ts.sampleRate = 1.0\n\t\tcase SampledFalse:\n\t\t\ts.sampleRate = 0.0\n\t\t}\n\t\treturn s.Sampled\n\t}\n\n\t// #5 use TracesSampleRate from ClientOptions.\n\tsampleRate := clientOptions.TracesSampleRate\n\ts.sampleRate = sampleRate\n\t// tracesSampleRate can update the sample_rate on frozen DSC\n\tif s.dynamicSamplingContext.HasEntries() {\n\t\ts.dynamicSamplingContext.Entries[\"sample_rate\"] = strconv.FormatFloat(sampleRate, 'f', -1, 64)\n\t}\n\tif sampleRate < 0.0 || sampleRate > 1.0 {\n\t\tdebuglog.Printf(\"Dropping transaction: TracesSampleRate out of range [0.0, 1.0]: %f\", sampleRate)\n\t\treturn SampledFalse\n\t}\n\tif sampleRate == 0.0 {\n\t\tdebuglog.Printf(\"Dropping transaction: TracesSampleRate rate is: %f\", sampleRate)\n\t\treturn SampledFalse\n\t}\n\n\tif rng.Float64() < sampleRate {\n\t\treturn SampledTrue\n\t}\n\n\treturn SampledFalse\n}\n\nfunc (s *Span) toEvent() *Event {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tif !s.IsTransaction() {\n\t\treturn nil // only transactions can be transformed into events\n\t}\n\n\tchildren := s.recorder.children()\n\tfinished := make([]*Span, 0, len(children))\n\tfor _, child := range children {\n\t\tif child.EndTime.IsZero() {\n\t\t\tdebuglog.Printf(\"Dropped unfinished span: Op=%q TraceID=%s SpanID=%s\", child.Op, child.TraceID, child.SpanID)\n\t\t\tcontinue\n\t\t}\n\t\tfinished = append(finished, child)\n\t}\n\n\t// Create and attach a DynamicSamplingContext to the transaction.\n\t// If the DynamicSamplingContext is not frozen at this point, we can assume being head of trace.\n\tif !s.dynamicSamplingContext.IsFrozen() {\n\t\ts.dynamicSamplingContext = DynamicSamplingContextFromTransaction(s)\n\t}\n\n\tcontexts := make(map[string]Context, len(s.contexts)+1)\n\tfor k, v := range s.contexts {\n\t\tcontexts[k] = cloneContext(v)\n\t}\n\tcontexts[\"trace\"] = s.traceContext().Map()\n\n\t// Make sure that the transaction source is valid\n\ttransactionSource := s.Source\n\tif !transactionSource.isValid() {\n\t\ttransactionSource = SourceCustom\n\t}\n\n\treturn &Event{\n\t\tType:        transactionType,\n\t\tTransaction: s.Name,\n\t\tContexts:    contexts,\n\t\tTags:        s.Tags,\n\t\tTimestamp:   s.EndTime,\n\t\tStartTime:   s.StartTime,\n\t\tSpans:       finished,\n\t\tTransactionInfo: &TransactionInfo{\n\t\t\tSource: transactionSource,\n\t\t},\n\t\tsdkMetaData: SDKMetaData{\n\t\t\tdsc: s.dynamicSamplingContext,\n\t\t},\n\t}\n}\n\nfunc (s *Span) traceContext() *TraceContext {\n\treturn &TraceContext{\n\t\tTraceID:      s.TraceID,\n\t\tSpanID:       s.SpanID,\n\t\tParentSpanID: s.ParentSpanID,\n\t\tOp:           s.Op,\n\t\tData:         s.Data,\n\t\tDescription:  s.Description,\n\t\tStatus:       s.Status,\n\t}\n}\n\n// spanRecorder stores the span tree. Guaranteed to be non-nil.\nfunc (s *Span) spanRecorder() *spanRecorder { return s.recorder }\n\n// ParseTraceParentContext parses a sentry-trace header and builds a TraceParentContext from the\n// parsed values. If the header was parsed correctly, the second returned argument\n// (\"valid\") will be set to true, otherwise (e.g., empty or malformed header) it will\n// be false.\nfunc ParseTraceParentContext(header []byte) (traceParentContext TraceParentContext, valid bool) {\n\ts := Span{}\n\tupdated := s.updateFromSentryTrace(header)\n\tif !updated {\n\t\treturn TraceParentContext{}, false\n\t}\n\treturn TraceParentContext{\n\t\tTraceID:      s.TraceID,\n\t\tParentSpanID: s.ParentSpanID,\n\t\tSampled:      s.Sampled,\n\t}, true\n}\n\n// TraceID identifies a trace.\ntype TraceID [16]byte\n\nfunc (id TraceID) Hex() []byte {\n\tb := make([]byte, hex.EncodedLen(len(id)))\n\thex.Encode(b, id[:])\n\treturn b\n}\n\nfunc (id TraceID) String() string {\n\treturn string(id.Hex())\n}\n\nfunc (id TraceID) MarshalText() ([]byte, error) {\n\treturn id.Hex(), nil\n}\n\n// SpanID identifies a span.\ntype SpanID [8]byte\n\nfunc (id SpanID) Hex() []byte {\n\tb := make([]byte, hex.EncodedLen(len(id)))\n\thex.Encode(b, id[:])\n\treturn b\n}\n\nfunc (id SpanID) String() string {\n\treturn string(id.Hex())\n}\n\nfunc (id SpanID) MarshalText() ([]byte, error) {\n\treturn id.Hex(), nil\n}\n\n// Zero values of TraceID and SpanID used for comparisons.\nvar (\n\tzeroTraceID TraceID\n\tzeroSpanID  SpanID\n)\n\n// Contains information about how the name of the transaction was determined.\ntype TransactionSource string\n\nconst (\n\tSourceCustom    TransactionSource = \"custom\"\n\tSourceURL       TransactionSource = \"url\"\n\tSourceRoute     TransactionSource = \"route\"\n\tSourceView      TransactionSource = \"view\"\n\tSourceComponent TransactionSource = \"component\"\n\tSourceTask      TransactionSource = \"task\"\n)\n\n// A set of all valid transaction sources.\nvar allTransactionSources = map[TransactionSource]struct{}{\n\tSourceCustom:    {},\n\tSourceURL:       {},\n\tSourceRoute:     {},\n\tSourceView:      {},\n\tSourceComponent: {},\n\tSourceTask:      {},\n}\n\n// isValid returns 'true' if the given transaction source is a valid\n// source as recognized by the envelope protocol:\n// https://develop.sentry.dev/sdk/event-payloads/transaction/#transaction-annotations\nfunc (ts TransactionSource) isValid() bool {\n\t_, found := allTransactionSources[ts]\n\treturn found\n}\n\n// SpanStatus is the status of a span.\ntype SpanStatus uint8\n\n// Implementation note:\n//\n// In Relay (ingestion), the SpanStatus type is an enum used as\n// Annotated<SpanStatus> when embedded in structs, making it effectively\n// Option<SpanStatus>. It means the status is either null or one of the known\n// string values.\n//\n// In Snuba (search), the SpanStatus is stored as an uint8 and defaulted to 2\n// (\"unknown\") when not set. It means that Discover searches for\n// `transaction.status:unknown` return both transactions/spans with status\n// `null` or `\"unknown\"`. Searches for `transaction.status:\"\"` return nothing.\n//\n// With that in mind, the Go SDK default is SpanStatusUndefined, which is\n// null/omitted when serializing to JSON, but integrations may update the status\n// automatically based on contextual information.\n\nconst (\n\tSpanStatusUndefined SpanStatus = iota\n\tSpanStatusOK\n\tSpanStatusCanceled\n\tSpanStatusUnknown\n\tSpanStatusInvalidArgument\n\tSpanStatusDeadlineExceeded\n\tSpanStatusNotFound\n\tSpanStatusAlreadyExists\n\tSpanStatusPermissionDenied\n\tSpanStatusResourceExhausted\n\tSpanStatusFailedPrecondition\n\tSpanStatusAborted\n\tSpanStatusOutOfRange\n\tSpanStatusUnimplemented\n\tSpanStatusInternalError\n\tSpanStatusUnavailable\n\tSpanStatusDataLoss\n\tSpanStatusUnauthenticated\n\tmaxSpanStatus\n)\n\nvar spanStatuses = [maxSpanStatus]string{\n\t\"\",\n\t\"ok\",\n\t\"cancelled\", // [sic]\n\t\"unknown\",\n\t\"invalid_argument\",\n\t\"deadline_exceeded\",\n\t\"not_found\",\n\t\"already_exists\",\n\t\"permission_denied\",\n\t\"resource_exhausted\",\n\t\"failed_precondition\",\n\t\"aborted\",\n\t\"out_of_range\",\n\t\"unimplemented\",\n\t\"internal_error\",\n\t\"unavailable\",\n\t\"data_loss\",\n\t\"unauthenticated\",\n}\n\nfunc (ss SpanStatus) String() string {\n\tif ss >= maxSpanStatus {\n\t\treturn \"\"\n\t}\n\treturn spanStatuses[ss]\n}\n\nfunc (ss SpanStatus) MarshalJSON() ([]byte, error) {\n\ts := ss.String()\n\tif s == \"\" {\n\t\treturn []byte(\"null\"), nil\n\t}\n\treturn json.Marshal(s)\n}\n\n// A TraceContext carries information about an ongoing trace and is meant to be\n// stored in Event.Contexts (as *TraceContext).\ntype TraceContext struct {\n\tTraceID      TraceID                `json:\"trace_id\"`\n\tSpanID       SpanID                 `json:\"span_id\"`\n\tParentSpanID SpanID                 `json:\"parent_span_id,omitzero\"`\n\tOp           string                 `json:\"op,omitempty\"`\n\tDescription  string                 `json:\"description,omitempty\"`\n\tStatus       SpanStatus             `json:\"status,omitempty\"`\n\tData         map[string]interface{} `json:\"data,omitempty\"`\n}\n\nfunc (tc TraceContext) Map() map[string]interface{} {\n\tm := map[string]interface{}{\n\t\t\"trace_id\": tc.TraceID,\n\t\t\"span_id\":  tc.SpanID,\n\t}\n\n\tif tc.ParentSpanID != [8]byte{} {\n\t\tm[\"parent_span_id\"] = tc.ParentSpanID\n\t}\n\n\tif tc.Op != \"\" {\n\t\tm[\"op\"] = tc.Op\n\t}\n\n\tif tc.Description != \"\" {\n\t\tm[\"description\"] = tc.Description\n\t}\n\n\tif tc.Status > 0 && tc.Status < maxSpanStatus {\n\t\tm[\"status\"] = tc.Status\n\t}\n\n\tif len(tc.Data) > 0 {\n\t\tm[\"data\"] = tc.Data\n\t}\n\n\treturn m\n}\n\n// Sampled signifies a sampling decision.\ntype Sampled int8\n\n// The possible trace sampling decisions are: SampledFalse, SampledUndefined\n// (default) and SampledTrue.\nconst (\n\tSampledFalse     Sampled = -1\n\tSampledUndefined Sampled = 0\n\tSampledTrue      Sampled = 1\n)\n\nfunc (s Sampled) String() string {\n\tswitch s {\n\tcase SampledFalse:\n\t\treturn \"SampledFalse\"\n\tcase SampledUndefined:\n\t\treturn \"SampledUndefined\"\n\tcase SampledTrue:\n\t\treturn \"SampledTrue\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"SampledInvalid(%d)\", s)\n\t}\n}\n\n// Bool returns true if the sample decision is SampledTrue, false otherwise.\nfunc (s Sampled) Bool() bool {\n\treturn s == SampledTrue\n}\n\n// A SpanOption is a function that can modify the properties of a span.\ntype SpanOption func(s *Span)\n\n// WithTransactionName option sets the name of the current transaction.\n//\n// A span tree has a single transaction name, therefore using this option when\n// starting a span affects the span tree as a whole, potentially overwriting a\n// name set previously.\nfunc WithTransactionName(name string) SpanOption {\n\treturn func(s *Span) {\n\t\ts.Name = name\n\t}\n}\n\n// WithDescription sets the description of a span.\nfunc WithDescription(description string) SpanOption {\n\treturn func(s *Span) {\n\t\ts.Description = description\n\t}\n}\n\n// WithOpName sets the operation name for a given span.\nfunc WithOpName(name string) SpanOption {\n\treturn func(s *Span) {\n\t\ts.Op = name\n\t}\n}\n\n// WithTransactionSource sets the source of the transaction name.\n//\n// Note: if the transaction source is not a valid source (as described\n// by the spec https://develop.sentry.dev/sdk/event-payloads/transaction/#transaction-annotations),\n// it will be corrected to \"custom\" eventually, before the transaction is sent.\nfunc WithTransactionSource(source TransactionSource) SpanOption {\n\treturn func(s *Span) {\n\t\ts.Source = source\n\t}\n}\n\n// WithSpanSampled updates the sampling flag for a given span.\nfunc WithSpanSampled(sampled Sampled) SpanOption {\n\treturn func(s *Span) {\n\t\ts.explicitSampled = sampled\n\t}\n}\n\n// WithSpanOrigin sets the origin of the span.\nfunc WithSpanOrigin(origin SpanOrigin) SpanOption {\n\treturn func(s *Span) {\n\t\ts.Origin = origin\n\t}\n}\n\n// ContinueTrace continues a trace based on traceparent and baggage values.\n// If the SDK is configured with tracing enabled,\n// this function returns populated SpanOption.\n// In any other cases, it populates the propagation context on the scope.\nfunc ContinueTrace(hub *Hub, traceparent, baggage string) SpanOption {\n\tscope := hub.Scope()\n\tpropagationContext, _ := PropagationContextFromHeaders(traceparent, baggage)\n\tscope.SetPropagationContext(propagationContext)\n\n\treturn ContinueFromHeaders(traceparent, baggage)\n}\n\n// ContinueFromRequest returns a span option that updates the span to continue\n// an existing trace. If it cannot detect an existing trace in the request, the\n// span will be left unchanged.\n//\n// ContinueFromRequest is an alias for:\n//\n// ContinueFromHeaders(r.Header.Get(SentryTraceHeader), r.Header.Get(SentryBaggageHeader)).\nfunc ContinueFromRequest(r *http.Request) SpanOption {\n\treturn ContinueFromHeaders(r.Header.Get(SentryTraceHeader), r.Header.Get(SentryBaggageHeader))\n}\n\n// ContinueFromHeaders returns a span option that updates the span to continue\n// an existing TraceID and propagates the Dynamic Sampling context.\nfunc ContinueFromHeaders(trace, baggage string) SpanOption {\n\treturn func(s *Span) {\n\t\tif trace != \"\" {\n\t\t\ts.updateFromSentryTrace([]byte(trace))\n\n\t\t\tif baggage != \"\" {\n\t\t\t\ts.updateFromBaggage([]byte(baggage))\n\t\t\t}\n\n\t\t\t// In case a sentry-trace header is present but there are no sentry-related\n\t\t\t// values in the baggage, create an empty, frozen DynamicSamplingContext.\n\t\t\tif !s.dynamicSamplingContext.HasEntries() {\n\t\t\t\ts.dynamicSamplingContext = DynamicSamplingContext{\n\t\t\t\t\tFrozen: true,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n// ContinueFromTrace returns a span option that updates the span to continue\n// an existing TraceID.\nfunc ContinueFromTrace(trace string) SpanOption {\n\treturn func(s *Span) {\n\t\tif trace == \"\" {\n\t\t\treturn\n\t\t}\n\t\ts.updateFromSentryTrace([]byte(trace))\n\t}\n}\n\n// spanContextKey is used to store span values in contexts.\ntype spanContextKey struct{}\n\n// TransactionFromContext returns the root span of the current transaction. It\n// returns nil if no transaction is tracked in the context.\nfunc TransactionFromContext(ctx context.Context) *Span {\n\tif span, ok := ctx.Value(spanContextKey{}).(*Span); ok {\n\t\treturn span.recorder.root()\n\t}\n\treturn nil\n}\n\n// SpanFromContext returns the last span stored in the context, or nil if no span\n// is set on the context.\nfunc SpanFromContext(ctx context.Context) *Span {\n\tif span, ok := ctx.Value(spanContextKey{}).(*Span); ok {\n\t\treturn span\n\t}\n\treturn nil\n}\n\n// StartTransaction will create a transaction (root span) if there's no existing\n// transaction in the context otherwise, it will return the existing transaction.\nfunc StartTransaction(ctx context.Context, name string, options ...SpanOption) *Span {\n\tcurrentTransaction, exists := ctx.Value(spanContextKey{}).(*Span)\n\tif exists {\n\t\tcurrentTransaction.ctx = ctx\n\t\treturn currentTransaction\n\t}\n\n\toptions = append(options, WithTransactionName(name))\n\treturn StartSpan(\n\t\tctx,\n\t\t\"\",\n\t\toptions...,\n\t)\n}\n\n// HTTPtoSpanStatus converts an HTTP status code to a SpanStatus.\nfunc HTTPtoSpanStatus(code int) SpanStatus {\n\tif code < http.StatusBadRequest {\n\t\treturn SpanStatusOK\n\t}\n\tif http.StatusBadRequest <= code && code < http.StatusInternalServerError {\n\t\tswitch code {\n\t\tcase http.StatusForbidden:\n\t\t\treturn SpanStatusPermissionDenied\n\t\tcase http.StatusNotFound:\n\t\t\treturn SpanStatusNotFound\n\t\tcase http.StatusTooManyRequests:\n\t\t\treturn SpanStatusResourceExhausted\n\t\tcase http.StatusRequestEntityTooLarge:\n\t\t\treturn SpanStatusFailedPrecondition\n\t\tcase http.StatusUnauthorized:\n\t\t\treturn SpanStatusUnauthenticated\n\t\tcase http.StatusConflict:\n\t\t\treturn SpanStatusAlreadyExists\n\t\tdefault:\n\t\t\treturn SpanStatusInvalidArgument\n\t\t}\n\t}\n\tif http.StatusInternalServerError <= code && code < 600 {\n\t\tswitch code {\n\t\tcase http.StatusGatewayTimeout:\n\t\t\treturn SpanStatusDeadlineExceeded\n\t\tcase http.StatusNotImplemented:\n\t\t\treturn SpanStatusUnimplemented\n\t\tcase http.StatusServiceUnavailable:\n\t\t\treturn SpanStatusUnavailable\n\t\tdefault:\n\t\t\treturn SpanStatusInternalError\n\t\t}\n\t}\n\treturn SpanStatusUnknown\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/transport.go",
    "content": "package sentry\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go/internal/debuglog\"\n\thttpinternal \"github.com/getsentry/sentry-go/internal/http\"\n\t\"github.com/getsentry/sentry-go/internal/protocol\"\n\t\"github.com/getsentry/sentry-go/internal/ratelimit\"\n\t\"github.com/getsentry/sentry-go/internal/util\"\n)\n\nconst (\n\tdefaultBufferSize = 1000\n\tdefaultTimeout    = time.Second * 30\n)\n\n// Transport is used by the Client to deliver events to remote server.\ntype Transport interface {\n\tFlush(timeout time.Duration) bool\n\tFlushWithContext(ctx context.Context) bool\n\tConfigure(options ClientOptions)\n\tSendEvent(event *Event)\n\tClose()\n}\n\nfunc getProxyConfig(options ClientOptions) func(*http.Request) (*url.URL, error) {\n\tif options.HTTPSProxy != \"\" {\n\t\treturn func(*http.Request) (*url.URL, error) {\n\t\t\treturn url.Parse(options.HTTPSProxy)\n\t\t}\n\t}\n\n\tif options.HTTPProxy != \"\" {\n\t\treturn func(*http.Request) (*url.URL, error) {\n\t\t\treturn url.Parse(options.HTTPProxy)\n\t\t}\n\t}\n\n\treturn http.ProxyFromEnvironment\n}\n\nfunc getTLSConfig(options ClientOptions) *tls.Config {\n\tif options.CaCerts != nil {\n\t\t// #nosec G402 -- We should be using `MinVersion: tls.VersionTLS12`,\n\t\t// \t\t\t\t but we don't want to break peoples code without the major bump.\n\t\treturn &tls.Config{\n\t\t\tRootCAs: options.CaCerts,\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc getRequestBodyFromEvent(event *Event) []byte {\n\tbody, err := json.Marshal(event)\n\tif err == nil {\n\t\treturn body\n\t}\n\n\tmsg := fmt.Sprintf(\"Could not encode original event as JSON. \"+\n\t\t\"Succeeded by removing Breadcrumbs, Contexts and Extra. \"+\n\t\t\"Please verify the data you attach to the scope. \"+\n\t\t\"Error: %s\", err)\n\t// Try to serialize the event, with all the contextual data that allows for interface{} stripped.\n\tevent.Breadcrumbs = nil\n\tevent.Contexts = nil\n\tevent.Extra = map[string]interface{}{\n\t\t\"info\": msg,\n\t}\n\tbody, err = json.Marshal(event)\n\tif err == nil {\n\t\tdebuglog.Println(msg)\n\t\treturn body\n\t}\n\n\t// This should _only_ happen when Event.Exception[0].Stacktrace.Frames[0].Vars is unserializable\n\t// Which won't ever happen, as we don't use it now (although it's the part of public interface accepted by Sentry)\n\t// Juuust in case something, somehow goes utterly wrong.\n\tdebuglog.Println(\"Event couldn't be marshaled, even with stripped contextual data. Skipping delivery. \" +\n\t\t\"Please notify the SDK owners with possibly broken payload.\")\n\treturn nil\n}\n\nfunc encodeAttachment(enc *json.Encoder, b io.Writer, attachment *Attachment) error {\n\t// Attachment header\n\terr := enc.Encode(struct {\n\t\tType        string `json:\"type\"`\n\t\tLength      int    `json:\"length\"`\n\t\tFilename    string `json:\"filename\"`\n\t\tContentType string `json:\"content_type,omitempty\"`\n\t}{\n\t\tType:        \"attachment\",\n\t\tLength:      len(attachment.Payload),\n\t\tFilename:    attachment.Filename,\n\t\tContentType: attachment.ContentType,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Attachment payload\n\tif _, err = b.Write(attachment.Payload); err != nil {\n\t\treturn err\n\t}\n\n\t// \"Envelopes should be terminated with a trailing newline.\"\n\t//\n\t// [1]: https://develop.sentry.dev/sdk/envelopes/#envelopes\n\tif _, err := b.Write([]byte(\"\\n\")); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc encodeEnvelopeItem(enc *json.Encoder, itemType string, body json.RawMessage) error {\n\t// Item header\n\terr := enc.Encode(struct {\n\t\tType   string `json:\"type\"`\n\t\tLength int    `json:\"length\"`\n\t}{\n\t\tType:   itemType,\n\t\tLength: len(body),\n\t})\n\tif err == nil {\n\t\t// payload\n\t\terr = enc.Encode(body)\n\t}\n\treturn err\n}\n\nfunc encodeEnvelopeLogs(enc *json.Encoder, count int, body json.RawMessage) error {\n\terr := enc.Encode(\n\t\tstruct {\n\t\t\tType        string `json:\"type\"`\n\t\t\tItemCount   int    `json:\"item_count\"`\n\t\t\tContentType string `json:\"content_type\"`\n\t\t}{\n\t\t\tType:        logEvent.Type,\n\t\t\tItemCount:   count,\n\t\t\tContentType: logEvent.ContentType,\n\t\t})\n\tif err == nil {\n\t\terr = enc.Encode(body)\n\t}\n\treturn err\n}\n\nfunc encodeEnvelopeMetrics(enc *json.Encoder, count int, body json.RawMessage) error {\n\terr := enc.Encode(\n\t\tstruct {\n\t\t\tType        string `json:\"type\"`\n\t\t\tItemCount   int    `json:\"item_count\"`\n\t\t\tContentType string `json:\"content_type\"`\n\t\t}{\n\t\t\tType:        traceMetricEvent.Type,\n\t\t\tItemCount:   count,\n\t\t\tContentType: traceMetricEvent.ContentType,\n\t\t})\n\tif err == nil {\n\t\terr = enc.Encode(body)\n\t}\n\treturn err\n}\n\nfunc envelopeFromBody(event *Event, dsn *Dsn, sentAt time.Time, body json.RawMessage) (*bytes.Buffer, error) {\n\tvar b bytes.Buffer\n\tenc := json.NewEncoder(&b)\n\n\t// Construct the trace envelope header\n\tvar trace = map[string]string{}\n\tif dsc := event.sdkMetaData.dsc; dsc.HasEntries() {\n\t\tfor k, v := range dsc.Entries {\n\t\t\ttrace[k] = v\n\t\t}\n\t}\n\n\t// Envelope header\n\terr := enc.Encode(struct {\n\t\tEventID EventID           `json:\"event_id\"`\n\t\tSentAt  time.Time         `json:\"sent_at\"`\n\t\tDsn     string            `json:\"dsn\"`\n\t\tSdk     map[string]string `json:\"sdk\"`\n\t\tTrace   map[string]string `json:\"trace,omitempty\"`\n\t}{\n\t\tEventID: event.EventID,\n\t\tSentAt:  sentAt,\n\t\tTrace:   trace,\n\t\tDsn:     dsn.String(),\n\t\tSdk: map[string]string{\n\t\t\t\"name\":    event.Sdk.Name,\n\t\t\t\"version\": event.Sdk.Version,\n\t\t},\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tswitch event.Type {\n\tcase transactionType, checkInType:\n\t\terr = encodeEnvelopeItem(enc, event.Type, body)\n\tcase logEvent.Type:\n\t\terr = encodeEnvelopeLogs(enc, len(event.Logs), body)\n\tcase traceMetricEvent.Type:\n\t\terr = encodeEnvelopeMetrics(enc, len(event.Metrics), body)\n\tdefault:\n\t\terr = encodeEnvelopeItem(enc, eventType, body)\n\t}\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Attachments\n\tfor _, attachment := range event.Attachments {\n\t\tif err := encodeAttachment(enc, &b, attachment); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn &b, nil\n}\n\nfunc getRequestFromEvent(ctx context.Context, event *Event, dsn *Dsn) (r *http.Request, err error) {\n\tdefer func() {\n\t\tif r != nil {\n\t\t\tr.Header.Set(\"User-Agent\", fmt.Sprintf(\"%s/%s\", event.Sdk.Name, event.Sdk.Version))\n\t\t\tr.Header.Set(\"Content-Type\", \"application/x-sentry-envelope\")\n\n\t\t\tauth := fmt.Sprintf(\"Sentry sentry_version=%s, \"+\n\t\t\t\t\"sentry_client=%s/%s, sentry_key=%s\", apiVersion, event.Sdk.Name, event.Sdk.Version, dsn.GetPublicKey())\n\n\t\t\t// The key sentry_secret is effectively deprecated and no longer needs to be set.\n\t\t\t// However, since it was required in older self-hosted versions,\n\t\t\t// it should still passed through to Sentry if set.\n\t\t\tif dsn.GetSecretKey() != \"\" {\n\t\t\t\tauth = fmt.Sprintf(\"%s, sentry_secret=%s\", auth, dsn.GetSecretKey())\n\t\t\t}\n\n\t\t\tr.Header.Set(\"X-Sentry-Auth\", auth)\n\t\t}\n\t}()\n\n\tbody := getRequestBodyFromEvent(event)\n\tif body == nil {\n\t\treturn nil, errors.New(\"event could not be marshaled\")\n\t}\n\n\tenvelope, err := envelopeFromBody(event, dsn, time.Now(), body)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif ctx == nil {\n\t\tctx = context.Background()\n\t}\n\n\treturn http.NewRequestWithContext(\n\t\tctx,\n\t\thttp.MethodPost,\n\t\tdsn.GetAPIURL().String(),\n\t\tenvelope,\n\t)\n}\n\n// ================================\n// HTTPTransport\n// ================================\n\n// A batch groups items that are processed sequentially.\ntype batch struct {\n\titems   chan batchItem\n\tstarted chan struct{} // closed to signal items started to be worked on\n\tdone    chan struct{} // closed to signal completion of all items\n}\n\ntype batchItem struct {\n\trequest         *http.Request\n\tcategory        ratelimit.Category\n\teventIdentifier string\n}\n\n// HTTPTransport is the default, non-blocking, implementation of Transport.\n//\n// Clients using this transport will enqueue requests in a buffer and return to\n// the caller before any network communication has happened. Requests are sent\n// to Sentry sequentially from a background goroutine.\ntype HTTPTransport struct {\n\tdsn       *Dsn\n\tclient    *http.Client\n\ttransport http.RoundTripper\n\n\t// buffer is a channel of batches. Calling Flush terminates work on the\n\t// current in-flight items and starts a new batch for subsequent events.\n\tbuffer chan batch\n\n\tstartOnce sync.Once\n\tcloseOnce sync.Once\n\n\t// Size of the transport buffer. Defaults to 30.\n\tBufferSize int\n\t// HTTP Client request timeout. Defaults to 30 seconds.\n\tTimeout time.Duration\n\n\tmu     sync.RWMutex\n\tlimits ratelimit.Map\n\n\t// receiving signal will terminate worker.\n\tdone chan struct{}\n}\n\n// NewHTTPTransport returns a new pre-configured instance of HTTPTransport.\nfunc NewHTTPTransport() *HTTPTransport {\n\ttransport := HTTPTransport{\n\t\tBufferSize: defaultBufferSize,\n\t\tTimeout:    defaultTimeout,\n\t\tdone:       make(chan struct{}),\n\t}\n\treturn &transport\n}\n\n// Configure is called by the Client itself, providing it it's own ClientOptions.\nfunc (t *HTTPTransport) Configure(options ClientOptions) {\n\tdsn, err := NewDsn(options.Dsn)\n\tif err != nil {\n\t\tdebuglog.Printf(\"%v\\n\", err)\n\t\treturn\n\t}\n\tt.dsn = dsn\n\n\t// A buffered channel with capacity 1 works like a mutex, ensuring only one\n\t// goroutine can access the current batch at a given time. Access is\n\t// synchronized by reading from and writing to the channel.\n\tt.buffer = make(chan batch, 1)\n\tt.buffer <- batch{\n\t\titems:   make(chan batchItem, t.BufferSize),\n\t\tstarted: make(chan struct{}),\n\t\tdone:    make(chan struct{}),\n\t}\n\n\tif options.HTTPTransport != nil {\n\t\tt.transport = options.HTTPTransport\n\t} else {\n\t\tt.transport = &http.Transport{\n\t\t\tProxy:           getProxyConfig(options),\n\t\t\tTLSClientConfig: getTLSConfig(options),\n\t\t}\n\t}\n\n\tif options.HTTPClient != nil {\n\t\tt.client = options.HTTPClient\n\t} else {\n\t\tt.client = &http.Client{\n\t\t\tTransport: t.transport,\n\t\t\tTimeout:   t.Timeout,\n\t\t}\n\t}\n\n\tt.startOnce.Do(func() {\n\t\tgo t.worker()\n\t})\n}\n\n// SendEvent assembles a new packet out of Event and sends it to the remote server.\nfunc (t *HTTPTransport) SendEvent(event *Event) {\n\tt.SendEventWithContext(context.Background(), event)\n}\n\n// SendEventWithContext assembles a new packet out of Event and sends it to the remote server.\nfunc (t *HTTPTransport) SendEventWithContext(ctx context.Context, event *Event) {\n\tif t.dsn == nil {\n\t\treturn\n\t}\n\n\tcategory := event.toCategory()\n\n\tif t.disabled(category) {\n\t\treturn\n\t}\n\n\trequest, err := getRequestFromEvent(ctx, event, t.dsn)\n\tif err != nil {\n\t\treturn\n\t}\n\n\t// <-t.buffer is equivalent to acquiring a lock to access the current batch.\n\t// A few lines below, t.buffer <- b releases the lock.\n\t//\n\t// The lock must be held during the select block below to guarantee that\n\t// b.items is not closed while trying to send to it. Remember that sending\n\t// on a closed channel panics.\n\t//\n\t// Note that the select block takes a bounded amount of CPU time because of\n\t// the default case that is executed if sending on b.items would block. That\n\t// is, the event is dropped if it cannot be sent immediately to the b.items\n\t// channel (used as a queue).\n\tb := <-t.buffer\n\n\tidentifier := eventIdentifier(event)\n\n\tselect {\n\tcase b.items <- batchItem{\n\t\trequest:         request,\n\t\tcategory:        category,\n\t\teventIdentifier: identifier,\n\t}:\n\t\tdebuglog.Printf(\n\t\t\t\"Sending %s to %s project: %s\",\n\t\t\tidentifier,\n\t\t\tt.dsn.GetHost(),\n\t\t\tt.dsn.GetProjectID(),\n\t\t)\n\tdefault:\n\t\tdebuglog.Println(\"Event dropped due to transport buffer being full.\")\n\t}\n\n\tt.buffer <- b\n}\n\n// Flush waits until any buffered events are sent to the Sentry server, blocking\n// for at most the given timeout. It returns false if the timeout was reached.\n// In that case, some events may not have been sent.\n//\n// Flush should be called before terminating the program to avoid\n// unintentionally dropping events.\n//\n// Do not call Flush indiscriminately after every call to SendEvent. Instead, to\n// have the SDK send events over the network synchronously, configure it to use\n// the HTTPSyncTransport in the call to Init.\nfunc (t *HTTPTransport) Flush(timeout time.Duration) bool {\n\tctx, cancel := context.WithTimeout(context.Background(), timeout)\n\tdefer cancel()\n\treturn t.FlushWithContext(ctx)\n}\n\n// FlushWithContext works like Flush, but it accepts a context.Context instead of a timeout.\nfunc (t *HTTPTransport) FlushWithContext(ctx context.Context) bool {\n\treturn t.flushInternal(ctx.Done())\n}\n\nfunc (t *HTTPTransport) flushInternal(timeout <-chan struct{}) bool {\n\t// Wait until processing the current batch has started or the timeout.\n\t//\n\t// We must wait until the worker has seen the current batch, because it is\n\t// the only way b.done will be closed. If we do not wait, there is a\n\t// possible execution flow in which b.done is never closed, and the only way\n\t// out of Flush would be waiting for the timeout, which is undesired.\n\tvar b batch\n\n\tfor {\n\t\tselect {\n\t\tcase b = <-t.buffer:\n\t\t\tselect {\n\t\t\tcase <-b.started:\n\t\t\t\tgoto started\n\t\t\tdefault:\n\t\t\t\tt.buffer <- b\n\t\t\t}\n\t\tcase <-timeout:\n\t\t\tgoto fail\n\t\t}\n\t}\n\nstarted:\n\t// Signal that there won't be any more items in this batch, so that the\n\t// worker inner loop can end.\n\tclose(b.items)\n\t// Start a new batch for subsequent events.\n\tt.buffer <- batch{\n\t\titems:   make(chan batchItem, t.BufferSize),\n\t\tstarted: make(chan struct{}),\n\t\tdone:    make(chan struct{}),\n\t}\n\n\t// Wait until the current batch is done or the timeout.\n\tselect {\n\tcase <-b.done:\n\t\tdebuglog.Println(\"Buffer flushed successfully.\")\n\t\treturn true\n\tcase <-timeout:\n\t\tgoto fail\n\t}\n\nfail:\n\tdebuglog.Println(\"Buffer flushing was canceled or timed out.\")\n\treturn false\n}\n\n// Close will terminate events sending loop.\n// It useful to prevent goroutines leak in case of multiple HTTPTransport instances initiated.\n//\n// Close should be called after Flush and before terminating the program\n// otherwise some events may be lost.\nfunc (t *HTTPTransport) Close() {\n\tt.closeOnce.Do(func() {\n\t\tclose(t.done)\n\t})\n}\n\nfunc (t *HTTPTransport) worker() {\n\tfor b := range t.buffer {\n\t\t// Signal that processing of the current batch has started.\n\t\tclose(b.started)\n\n\t\t// Return the batch to the buffer so that other goroutines can use it.\n\t\t// Equivalent to releasing a lock.\n\t\tt.buffer <- b\n\n\t\t// Process all batch items.\n\tloop:\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-t.done:\n\t\t\t\treturn\n\t\t\tcase item, open := <-b.items:\n\t\t\t\tif !open {\n\t\t\t\t\tbreak loop\n\t\t\t\t}\n\t\t\t\tif t.disabled(item.category) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tresponse, err := t.client.Do(item.request)\n\t\t\t\tif err != nil {\n\t\t\t\t\tdebuglog.Printf(\"There was an issue with sending an event: %v\", err)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tutil.HandleHTTPResponse(response, item.eventIdentifier)\n\n\t\t\t\tt.mu.Lock()\n\t\t\t\tif t.limits == nil {\n\t\t\t\t\tt.limits = make(ratelimit.Map)\n\t\t\t\t}\n\t\t\t\tt.limits.Merge(ratelimit.FromResponse(response))\n\t\t\t\tt.mu.Unlock()\n\n\t\t\t\t// Drain body up to a limit and close it, allowing the\n\t\t\t\t// transport to reuse TCP connections.\n\t\t\t\t_, _ = io.CopyN(io.Discard, response.Body, util.MaxDrainResponseBytes)\n\t\t\t\tresponse.Body.Close()\n\t\t\t}\n\t\t}\n\n\t\t// Signal that processing of the batch is done.\n\t\tclose(b.done)\n\t}\n}\n\nfunc (t *HTTPTransport) disabled(c ratelimit.Category) bool {\n\tt.mu.RLock()\n\tdefer t.mu.RUnlock()\n\tdisabled := t.limits.IsRateLimited(c)\n\tif disabled {\n\t\tdebuglog.Printf(\"Too many requests for %q, backing off till: %v\", c, t.limits.Deadline(c))\n\t}\n\treturn disabled\n}\n\n// ================================\n// HTTPSyncTransport\n// ================================\n\n// HTTPSyncTransport is a blocking implementation of Transport.\n//\n// Clients using this transport will send requests to Sentry sequentially and\n// block until a response is returned.\n//\n// The blocking behavior is useful in a limited set of use cases. For example,\n// use it when deploying code to a Function as a Service (\"Serverless\")\n// platform, where any work happening in a background goroutine is not\n// guaranteed to execute.\n//\n// For most cases, prefer HTTPTransport.\ntype HTTPSyncTransport struct {\n\tdsn       *Dsn\n\tclient    *http.Client\n\ttransport http.RoundTripper\n\n\tmu     sync.Mutex\n\tlimits ratelimit.Map\n\n\t// HTTP Client request timeout. Defaults to 30 seconds.\n\tTimeout time.Duration\n}\n\n// NewHTTPSyncTransport returns a new pre-configured instance of HTTPSyncTransport.\nfunc NewHTTPSyncTransport() *HTTPSyncTransport {\n\ttransport := HTTPSyncTransport{\n\t\tTimeout: defaultTimeout,\n\t\tlimits:  make(ratelimit.Map),\n\t}\n\n\treturn &transport\n}\n\n// Configure is called by the Client itself, providing it it's own ClientOptions.\nfunc (t *HTTPSyncTransport) Configure(options ClientOptions) {\n\tdsn, err := NewDsn(options.Dsn)\n\tif err != nil {\n\t\tdebuglog.Printf(\"%v\\n\", err)\n\t\treturn\n\t}\n\tt.dsn = dsn\n\n\tif options.HTTPTransport != nil {\n\t\tt.transport = options.HTTPTransport\n\t} else {\n\t\tt.transport = &http.Transport{\n\t\t\tProxy:           getProxyConfig(options),\n\t\t\tTLSClientConfig: getTLSConfig(options),\n\t\t}\n\t}\n\n\tif options.HTTPClient != nil {\n\t\tt.client = options.HTTPClient\n\t} else {\n\t\tt.client = &http.Client{\n\t\t\tTransport: t.transport,\n\t\t\tTimeout:   t.Timeout,\n\t\t}\n\t}\n}\n\n// SendEvent assembles a new packet out of Event and sends it to the remote server.\nfunc (t *HTTPSyncTransport) SendEvent(event *Event) {\n\tt.SendEventWithContext(context.Background(), event)\n}\n\nfunc (t *HTTPSyncTransport) Close() {}\n\n// SendEventWithContext assembles a new packet out of Event and sends it to the remote server.\nfunc (t *HTTPSyncTransport) SendEventWithContext(ctx context.Context, event *Event) {\n\tif t.dsn == nil {\n\t\treturn\n\t}\n\n\tif t.disabled(event.toCategory()) {\n\t\treturn\n\t}\n\n\trequest, err := getRequestFromEvent(ctx, event, t.dsn)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tidentifier := eventIdentifier(event)\n\tdebuglog.Printf(\n\t\t\"Sending %s to %s project: %s\",\n\t\tidentifier,\n\t\tt.dsn.GetHost(),\n\t\tt.dsn.GetProjectID(),\n\t)\n\n\tresponse, err := t.client.Do(request)\n\tif err != nil {\n\t\tdebuglog.Printf(\"There was an issue with sending an event: %v\", err)\n\t\treturn\n\t}\n\tutil.HandleHTTPResponse(response, identifier)\n\n\tt.mu.Lock()\n\tif t.limits == nil {\n\t\tt.limits = make(ratelimit.Map)\n\t}\n\n\tt.limits.Merge(ratelimit.FromResponse(response))\n\tt.mu.Unlock()\n\n\t// Drain body up to a limit and close it, allowing the\n\t// transport to reuse TCP connections.\n\t_, _ = io.CopyN(io.Discard, response.Body, util.MaxDrainResponseBytes)\n\tresponse.Body.Close()\n}\n\n// Flush is a no-op for HTTPSyncTransport. It always returns true immediately.\nfunc (t *HTTPSyncTransport) Flush(_ time.Duration) bool {\n\treturn true\n}\n\n// FlushWithContext is a no-op for HTTPSyncTransport. It always returns true immediately.\nfunc (t *HTTPSyncTransport) FlushWithContext(_ context.Context) bool {\n\treturn true\n}\n\nfunc (t *HTTPSyncTransport) disabled(c ratelimit.Category) bool {\n\tt.mu.Lock()\n\tdefer t.mu.Unlock()\n\tdisabled := t.limits.IsRateLimited(c)\n\tif disabled {\n\t\tdebuglog.Printf(\"Too many requests for %q, backing off till: %v\", c, t.limits.Deadline(c))\n\t}\n\treturn disabled\n}\n\n// ================================\n// noopTransport\n// ================================\n\n// noopTransport is an implementation of Transport interface which drops all the events.\n// Only used internally when an empty DSN is provided, which effectively disables the SDK.\ntype noopTransport struct{}\n\nvar _ Transport = noopTransport{}\n\nfunc (noopTransport) Configure(ClientOptions) {\n\tdebuglog.Println(\"Sentry client initialized with an empty DSN. Using noopTransport. No events will be delivered.\")\n}\n\nfunc (noopTransport) SendEvent(*Event) {\n\tdebuglog.Println(\"Event dropped due to noopTransport usage.\")\n}\n\nfunc (noopTransport) Flush(time.Duration) bool {\n\treturn true\n}\n\nfunc (noopTransport) FlushWithContext(context.Context) bool {\n\treturn true\n}\n\nfunc (noopTransport) Close() {}\n\n// ================================\n// Internal Transport Adapters\n// ================================\n\n// newInternalAsyncTransport creates a new AsyncTransport from internal/http\n// wrapped to satisfy the Transport interface.\n//\n// This is not yet exposed in the public API and is for internal experimentation.\nfunc newInternalAsyncTransport() Transport {\n\treturn &internalAsyncTransportAdapter{}\n}\n\n// internalAsyncTransportAdapter wraps the internal AsyncTransport to implement\n// the root-level Transport interface.\ntype internalAsyncTransportAdapter struct {\n\ttransport protocol.TelemetryTransport\n\tdsn       *protocol.Dsn\n}\n\nfunc (a *internalAsyncTransportAdapter) Configure(options ClientOptions) {\n\ttransportOptions := httpinternal.TransportOptions{\n\t\tDsn:           options.Dsn,\n\t\tHTTPClient:    options.HTTPClient,\n\t\tHTTPTransport: options.HTTPTransport,\n\t\tHTTPProxy:     options.HTTPProxy,\n\t\tHTTPSProxy:    options.HTTPSProxy,\n\t\tCaCerts:       options.CaCerts,\n\t}\n\n\ta.transport = httpinternal.NewAsyncTransport(transportOptions)\n\n\tif options.Dsn != \"\" {\n\t\tdsn, err := protocol.NewDsn(options.Dsn)\n\t\tif err != nil {\n\t\t\tdebuglog.Printf(\"Failed to parse DSN in adapter: %v\\n\", err)\n\t\t} else {\n\t\t\ta.dsn = dsn\n\t\t}\n\t}\n}\n\nfunc (a *internalAsyncTransportAdapter) SendEvent(event *Event) {\n\theader := &protocol.EnvelopeHeader{EventID: string(event.EventID), SentAt: time.Now(), Sdk: &protocol.SdkInfo{Name: event.Sdk.Name, Version: event.Sdk.Version}}\n\tif a.dsn != nil {\n\t\theader.Dsn = a.dsn.String()\n\t}\n\tif header.EventID == \"\" {\n\t\theader.EventID = protocol.GenerateEventID()\n\t}\n\tenvelope := protocol.NewEnvelope(header)\n\titem, err := event.ToEnvelopeItem()\n\tif err != nil {\n\t\tdebuglog.Printf(\"Failed to convert event to envelope item: %v\", err)\n\t\treturn\n\t}\n\tenvelope.AddItem(item)\n\n\tfor _, attachment := range event.Attachments {\n\t\tattachmentItem := protocol.NewAttachmentItem(attachment.Filename, attachment.ContentType, attachment.Payload)\n\t\tenvelope.AddItem(attachmentItem)\n\t}\n\n\tif err := a.transport.SendEnvelope(envelope); err != nil {\n\t\tdebuglog.Printf(\"Error sending envelope: %v\", err)\n\t}\n}\n\nfunc (a *internalAsyncTransportAdapter) Flush(timeout time.Duration) bool {\n\treturn a.transport.Flush(timeout)\n}\n\nfunc (a *internalAsyncTransportAdapter) FlushWithContext(ctx context.Context) bool {\n\treturn a.transport.FlushWithContext(ctx)\n}\n\nfunc (a *internalAsyncTransportAdapter) Close() {\n\ta.transport.Close()\n}\n"
  },
  {
    "path": "vendor/github.com/getsentry/sentry-go/util.go",
    "content": "package sentry\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/getsentry/sentry-go/internal/debuglog\"\n\t\"github.com/getsentry/sentry-go/internal/protocol\"\n\texec \"golang.org/x/sys/execabs\"\n)\n\nfunc uuid() string {\n\treturn protocol.GenerateEventID()\n}\n\nfunc fileExists(fileName string) bool {\n\t_, err := os.Stat(fileName)\n\treturn err == nil\n}\n\n// monotonicTimeSince replaces uses of time.Now() to take into account the\n// monotonic clock reading stored in start, such that duration = end - start is\n// unaffected by changes in the system wall clock.\nfunc monotonicTimeSince(start time.Time) (end time.Time) {\n\treturn start.Add(time.Since(start))\n}\n\n// nolint: unused\nfunc prettyPrint(data interface{}) {\n\tdbg, _ := json.MarshalIndent(data, \"\", \"  \")\n\tfmt.Println(string(dbg))\n}\n\n// defaultRelease attempts to guess a default release for the currently running\n// program.\nfunc defaultRelease() (release string) {\n\t// Return first non-empty environment variable known to hold release info, if any.\n\tenvs := []string{\n\t\t\"SENTRY_RELEASE\",\n\t\t\"HEROKU_SLUG_COMMIT\",\n\t\t\"SOURCE_VERSION\",\n\t\t\"CODEBUILD_RESOLVED_SOURCE_VERSION\",\n\t\t\"CIRCLE_SHA1\",\n\t\t\"GAE_DEPLOYMENT_ID\",\n\t\t\"GITHUB_SHA\",             // GitHub Actions - https://help.github.com/en/actions\n\t\t\"COMMIT_REF\",             // Netlify - https://docs.netlify.com/\n\t\t\"VERCEL_GIT_COMMIT_SHA\",  // Vercel - https://vercel.com/\n\t\t\"ZEIT_GITHUB_COMMIT_SHA\", // Zeit (now known as Vercel)\n\t\t\"ZEIT_GITLAB_COMMIT_SHA\",\n\t\t\"ZEIT_BITBUCKET_COMMIT_SHA\",\n\t}\n\tfor _, e := range envs {\n\t\tif release = os.Getenv(e); release != \"\" {\n\t\t\tdebuglog.Printf(\"Using release from environment variable %s: %s\", e, release)\n\t\t\treturn release\n\t\t}\n\t}\n\n\tif info, ok := debug.ReadBuildInfo(); ok {\n\t\tbuildInfoVcsRevision := revisionFromBuildInfo(info)\n\t\tif len(buildInfoVcsRevision) > 0 {\n\t\t\treturn buildInfoVcsRevision\n\t\t}\n\t}\n\n\t// Derive a version string from Git. Example outputs:\n\t// \tv1.0.1-0-g9de4\n\t// \tv2.0-8-g77df-dirty\n\t// \t4f72d7\n\tif _, err := exec.LookPath(\"git\"); err == nil {\n\t\tcmd := exec.Command(\"git\", \"describe\", \"--long\", \"--always\", \"--dirty\")\n\t\tb, err := cmd.Output()\n\t\tif err != nil {\n\t\t\t// Either Git is not available or the current directory is not a\n\t\t\t// Git repository.\n\t\t\tvar s strings.Builder\n\t\t\tfmt.Fprintf(&s, \"Release detection failed: %v\", err)\n\t\t\tif err, ok := err.(*exec.ExitError); ok && len(err.Stderr) > 0 {\n\t\t\t\tfmt.Fprintf(&s, \": %s\", err.Stderr)\n\t\t\t}\n\t\t\tdebuglog.Print(s.String())\n\t\t} else {\n\t\t\trelease = strings.TrimSpace(string(b))\n\t\t\tdebuglog.Printf(\"Using release from Git: %s\", release)\n\t\t\treturn release\n\t\t}\n\t}\n\n\tdebuglog.Print(\"Some Sentry features will not be available. See https://docs.sentry.io/product/releases/.\")\n\tdebuglog.Print(\"To stop seeing this message, pass a Release to sentry.Init or set the SENTRY_RELEASE environment variable.\")\n\treturn \"\"\n}\n\nfunc revisionFromBuildInfo(info *debug.BuildInfo) string {\n\tfor _, setting := range info.Settings {\n\t\tif setting.Key == \"vcs.revision\" && setting.Value != \"\" {\n\t\t\tdebuglog.Printf(\"Using release from debug info: %s\", setting.Value)\n\t\t\treturn setting.Value\n\t\t}\n\t}\n\n\treturn \"\"\n}\n\nfunc Pointer[T any](v T) *T {\n\treturn &v\n}\n\n// eventIdentifier returns a human-readable identifier for the event to be used in log messages.\n// Format: \"<description> [<event-id>]\".\nfunc eventIdentifier(event *Event) string {\n\tvar description string\n\tswitch event.Type {\n\tcase errorType:\n\t\tdescription = \"error\"\n\tcase transactionType:\n\t\tdescription = \"transaction\"\n\tcase checkInType:\n\t\tdescription = \"check-in\"\n\tcase logEvent.Type:\n\t\tdescription = fmt.Sprintf(\"%d log events\", len(event.Logs))\n\tcase traceMetricEvent.Type:\n\t\tdescription = fmt.Sprintf(\"%d metric events\", len(event.Metrics))\n\tdefault:\n\t\tdescription = fmt.Sprintf(\"%s event\", event.Type)\n\t}\n\treturn fmt.Sprintf(\"%s [%s]\", description, event.EventID)\n}\n"
  },
  {
    "path": "vendor/github.com/go-chi/chi/v5/.gitignore",
    "content": ".idea\n*.sw?\n.vscode\n"
  },
  {
    "path": "vendor/github.com/go-chi/chi/v5/CHANGELOG.md",
    "content": "# Changelog\n\n## v5.0.12 (2024-02-16)\n\n- History of changes: see https://github.com/go-chi/chi/compare/v5.0.11...v5.0.12\n\n\n## v5.0.11 (2023-12-19)\n\n- History of changes: see https://github.com/go-chi/chi/compare/v5.0.10...v5.0.11\n\n\n## v5.0.10 (2023-07-13)\n\n- Fixed small edge case in tests of v5.0.9 for older Go versions\n- History of changes: see https://github.com/go-chi/chi/compare/v5.0.9...v5.0.10\n\n\n## v5.0.9 (2023-07-13)\n\n- History of changes: see https://github.com/go-chi/chi/compare/v5.0.8...v5.0.9\n\n\n## v5.0.8 (2022-12-07)\n\n- History of changes: see https://github.com/go-chi/chi/compare/v5.0.7...v5.0.8\n\n\n## v5.0.7 (2021-11-18)\n\n- History of changes: see https://github.com/go-chi/chi/compare/v5.0.6...v5.0.7\n\n\n## v5.0.6 (2021-11-15)\n\n- History of changes: see https://github.com/go-chi/chi/compare/v5.0.5...v5.0.6\n\n\n## v5.0.5 (2021-10-27)\n\n- History of changes: see https://github.com/go-chi/chi/compare/v5.0.4...v5.0.5\n\n\n## v5.0.4 (2021-08-29)\n\n- History of changes: see https://github.com/go-chi/chi/compare/v5.0.3...v5.0.4\n\n\n## v5.0.3 (2021-04-29)\n\n- History of changes: see https://github.com/go-chi/chi/compare/v5.0.2...v5.0.3\n\n\n## v5.0.2 (2021-03-25)\n\n- History of changes: see https://github.com/go-chi/chi/compare/v5.0.1...v5.0.2\n\n\n## v5.0.1 (2021-03-10)\n\n- Small improvements\n- History of changes: see https://github.com/go-chi/chi/compare/v5.0.0...v5.0.1\n\n\n## v5.0.0 (2021-02-27)\n\n- chi v5, `github.com/go-chi/chi/v5` introduces the adoption of Go's SIV to adhere to the current state-of-the-tools in Go.\n- chi v1.5.x did not work out as planned, as the Go tooling is too powerful and chi's adoption is too wide.\n  The most responsible thing to do for everyone's benefit is to just release v5 with SIV, so I present to you all,\n  chi v5 at `github.com/go-chi/chi/v5`. I hope someday the developer experience and ergonomics I've been seeking\n  will still come to fruition in some form, see https://github.com/golang/go/issues/44550\n- History of changes: see https://github.com/go-chi/chi/compare/v1.5.4...v5.0.0\n\n\n## v1.5.4 (2021-02-27)\n\n- Undo prior retraction in v1.5.3 as we prepare for v5.0.0 release\n- History of changes: see https://github.com/go-chi/chi/compare/v1.5.3...v1.5.4\n\n\n## v1.5.3 (2021-02-21)\n\n- Update go.mod to go 1.16 with new retract directive marking all versions without prior go.mod support\n- History of changes: see https://github.com/go-chi/chi/compare/v1.5.2...v1.5.3\n\n\n## v1.5.2 (2021-02-10)\n\n- Reverting allocation optimization as a precaution as go test -race fails.\n- Minor improvements, see history below\n- History of changes: see https://github.com/go-chi/chi/compare/v1.5.1...v1.5.2\n\n\n## v1.5.1 (2020-12-06)\n\n- Performance improvement: removing 1 allocation by foregoing context.WithValue, thank you @bouk for\n  your contribution (https://github.com/go-chi/chi/pull/555). Note: new benchmarks posted in README.\n- `middleware.CleanPath`: new middleware that clean's request path of double slashes\n- deprecate & remove `chi.ServerBaseContext` in favour of stdlib `http.Server#BaseContext`\n- plus other tiny improvements, see full commit history below\n- History of changes: see https://github.com/go-chi/chi/compare/v4.1.2...v1.5.1\n\n\n## v1.5.0 (2020-11-12) - now with go.mod support\n\n`chi` dates back to 2016 with it's original implementation as one of the first routers to adopt the newly introduced\ncontext.Context api to the stdlib -- set out to design a router that is faster, more modular and simpler than anything\nelse out there -- while not introducing any custom handler types or dependencies. Today, `chi` still has zero dependencies,\nand in many ways is future proofed from changes, given it's minimal nature. Between versions, chi's iterations have been very\nincremental, with the architecture and api being the same today as it was originally designed in 2016. For this reason it \nmakes chi a pretty easy project to maintain, as well thanks to the many amazing community contributions over the years\nto who all help make chi better (total of 86 contributors to date -- thanks all!).\n\nChi has been a labour of love, art and engineering, with the goals to offer beautiful ergonomics, flexibility, performance\nand simplicity when building HTTP services with Go. I've strived to keep the router very minimal in surface area / code size,\nand always improving the code wherever possible -- and as of today the `chi` package is just 1082 lines of code (not counting\nmiddlewares, which are all optional). As well, I don't have the exact metrics, but from my analysis and email exchanges from\ncompanies and developers, chi is used by thousands of projects around the world -- thank you all as there is no better form of\njoy for me than to have art I had started be helpful and enjoyed by others. And of course I use chi in all of my own projects too :)\n\nFor me, the aesthetics of chi's code and usage are very important. With the introduction of Go's module support\n(which I'm a big fan of), chi's past versioning scheme choice to v2, v3 and v4 would mean I'd require the import path\nof \"github.com/go-chi/chi/v4\", leading to the lengthy discussion at https://github.com/go-chi/chi/issues/462.\nHaha, to some, you may be scratching your head why I've spent > 1 year stalling to adopt \"/vXX\" convention in the import\npath -- which isn't horrible in general -- but for chi, I'm unable to accept it as I strive for perfection in it's API design,\naesthetics and simplicity. It just doesn't feel good to me given chi's simple nature -- I do not foresee a \"v5\" or \"v6\",\nand upgrading between versions in the future will also be just incremental.\n\nI do understand versioning is a part of the API design as well, which is why the solution for a while has been to \"do nothing\",\nas Go supports both old and new import paths with/out go.mod. However, now that Go module support has had time to iron out kinks and\nis adopted everywhere, it's time for chi to get with the times. Luckily, I've discovered a path forward that will make me happy,\nwhile also not breaking anyone's app who adopted a prior versioning from tags in v2/v3/v4. I've made an experimental release of\nv1.5.0 with go.mod silently, and tested it with new and old projects, to ensure the developer experience is preserved, and it's\nlargely unnoticed. Fortunately, Go's toolchain will check the tags of a repo and consider the \"latest\" tag the one with go.mod.\nHowever, you can still request a specific older tag such as v4.1.2, and everything will \"just work\". But new users can just\n`go get github.com/go-chi/chi` or `go get github.com/go-chi/chi@latest` and they will get the latest version which contains\ngo.mod support, which is v1.5.0+. `chi` will not change very much over the years, just like it hasn't changed much from 4 years ago.\nTherefore, we will stay on v1.x from here on, starting from v1.5.0. Any breaking changes will bump a \"minor\" release and\nbackwards-compatible improvements/fixes will bump a \"tiny\" release.\n\nFor existing projects who want to upgrade to the latest go.mod version, run: `go get -u github.com/go-chi/chi@v1.5.0`,\nwhich will get you on the go.mod version line (as Go's mod cache may still remember v4.x). Brand new systems can run\n`go get -u github.com/go-chi/chi` or `go get -u github.com/go-chi/chi@latest` to install chi, which will install v1.5.0+\nbuilt with go.mod support.\n\nMy apologies to the developers who will disagree with the decisions above, but, hope you'll try it and see it's a very\nminor request which is backwards compatible and won't break your existing installations.\n\nCheers all, happy coding!\n\n\n---\n\n\n## v4.1.2 (2020-06-02)\n\n- fix that handles MethodNotAllowed with path variables, thank you @caseyhadden for your contribution\n- fix to replace nested wildcards correctly in RoutePattern, thank you @@unmultimedio for your contribution\n- History of changes: see https://github.com/go-chi/chi/compare/v4.1.1...v4.1.2\n\n\n## v4.1.1 (2020-04-16)\n\n- fix for issue https://github.com/go-chi/chi/issues/411 which allows for overlapping regexp\n  route to the correct handler through a recursive tree search, thanks to @Jahaja for the PR/fix!\n- new middleware.RouteHeaders as a simple router for request headers with wildcard support\n- History of changes: see https://github.com/go-chi/chi/compare/v4.1.0...v4.1.1\n\n\n## v4.1.0 (2020-04-1)\n\n- middleware.LogEntry: Write method on interface now passes the response header\n  and an extra interface type useful for custom logger implementations.\n- middleware.WrapResponseWriter: minor fix\n- middleware.Recoverer: a bit prettier\n- History of changes: see https://github.com/go-chi/chi/compare/v4.0.4...v4.1.0\n\n## v4.0.4 (2020-03-24)\n\n- middleware.Recoverer: new pretty stack trace printing (https://github.com/go-chi/chi/pull/496)\n- a few minor improvements and fixes\n- History of changes: see https://github.com/go-chi/chi/compare/v4.0.3...v4.0.4\n\n\n## v4.0.3 (2020-01-09)\n\n- core: fix regexp routing to include default value when param is not matched\n- middleware: rewrite of middleware.Compress\n- middleware: suppress http.ErrAbortHandler in middleware.Recoverer\n- History of changes: see https://github.com/go-chi/chi/compare/v4.0.2...v4.0.3\n\n\n## v4.0.2 (2019-02-26)\n\n- Minor fixes\n- History of changes: see https://github.com/go-chi/chi/compare/v4.0.1...v4.0.2\n\n\n## v4.0.1 (2019-01-21)\n\n- Fixes issue with compress middleware: #382 #385\n- History of changes: see https://github.com/go-chi/chi/compare/v4.0.0...v4.0.1\n\n\n## v4.0.0 (2019-01-10)\n\n- chi v4 requires Go 1.10.3+ (or Go 1.9.7+) - we have deprecated support for Go 1.7 and 1.8\n- router: respond with 404 on router with no routes (#362)\n- router: additional check to ensure wildcard is at the end of a url pattern (#333)\n- middleware: deprecate use of http.CloseNotifier (#347)\n- middleware: fix RedirectSlashes to include query params on redirect (#334)\n- History of changes: see https://github.com/go-chi/chi/compare/v3.3.4...v4.0.0\n\n\n## v3.3.4 (2019-01-07)\n\n- Minor middleware improvements. No changes to core library/router. Moving v3 into its\n- own branch as a version of chi for Go 1.7, 1.8, 1.9, 1.10, 1.11\n- History of changes: see https://github.com/go-chi/chi/compare/v3.3.3...v3.3.4\n\n\n## v3.3.3 (2018-08-27)\n\n- Minor release\n- See https://github.com/go-chi/chi/compare/v3.3.2...v3.3.3\n\n\n## v3.3.2 (2017-12-22)\n\n- Support to route trailing slashes on mounted sub-routers (#281)\n- middleware: new `ContentCharset` to check matching charsets. Thank you\n  @csucu for your community contribution!\n\n\n## v3.3.1 (2017-11-20)\n\n- middleware: new `AllowContentType` handler for explicit whitelist of accepted request Content-Types\n- middleware: new `SetHeader` handler for short-hand middleware to set a response header key/value\n- Minor bug fixes\n\n\n## v3.3.0 (2017-10-10)\n\n- New chi.RegisterMethod(method) to add support for custom HTTP methods, see _examples/custom-method for usage\n- Deprecated LINK and UNLINK methods from the default list, please use `chi.RegisterMethod(\"LINK\")` and `chi.RegisterMethod(\"UNLINK\")` in an `init()` function\n\n\n## v3.2.1 (2017-08-31)\n\n- Add new `Match(rctx *Context, method, path string) bool` method to `Routes` interface\n  and `Mux`. Match searches the mux's routing tree for a handler that matches the method/path\n- Add new `RouteMethod` to `*Context`\n- Add new `Routes` pointer to `*Context`\n- Add new `middleware.GetHead` to route missing HEAD requests to GET handler\n- Updated benchmarks (see README)\n\n\n## v3.1.5 (2017-08-02)\n\n- Setup golint and go vet for the project\n- As per golint, we've redefined `func ServerBaseContext(h http.Handler, baseCtx context.Context) http.Handler`\n  to `func ServerBaseContext(baseCtx context.Context, h http.Handler) http.Handler`\n\n\n## v3.1.0 (2017-07-10)\n\n- Fix a few minor issues after v3 release\n- Move `docgen` sub-pkg to https://github.com/go-chi/docgen\n- Move `render` sub-pkg to https://github.com/go-chi/render\n- Add new `URLFormat` handler to chi/middleware sub-pkg to make working with url mime \n  suffixes easier, ie. parsing `/articles/1.json` and `/articles/1.xml`. See comments in\n  https://github.com/go-chi/chi/blob/master/middleware/url_format.go for example usage.\n\n\n## v3.0.0 (2017-06-21)\n\n- Major update to chi library with many exciting updates, but also some *breaking changes*\n- URL parameter syntax changed from `/:id` to `/{id}` for even more flexible routing, such as\n  `/articles/{month}-{day}-{year}-{slug}`, `/articles/{id}`, and `/articles/{id}.{ext}` on the\n  same router\n- Support for regexp for routing patterns, in the form of `/{paramKey:regExp}` for example:\n  `r.Get(\"/articles/{name:[a-z]+}\", h)` and `chi.URLParam(r, \"name\")`\n- Add `Method` and `MethodFunc` to `chi.Router` to allow routing definitions such as\n  `r.Method(\"GET\", \"/\", h)` which provides a cleaner interface for custom handlers like\n  in `_examples/custom-handler`\n- Deprecating `mux#FileServer` helper function. Instead, we encourage users to create their\n  own using file handler with the stdlib, see `_examples/fileserver` for an example\n- Add support for LINK/UNLINK http methods via `r.Method()` and `r.MethodFunc()`\n- Moved the chi project to its own organization, to allow chi-related community packages to\n  be easily discovered and supported, at: https://github.com/go-chi\n- *NOTE:* please update your import paths to `\"github.com/go-chi/chi\"`\n- *NOTE:* chi v2 is still available at https://github.com/go-chi/chi/tree/v2\n\n\n## v2.1.0 (2017-03-30)\n\n- Minor improvements and update to the chi core library\n- Introduced a brand new `chi/render` sub-package to complete the story of building\n  APIs to offer a pattern for managing well-defined request / response payloads. Please\n  check out the updated `_examples/rest` example for how it works.\n- Added `MethodNotAllowed(h http.HandlerFunc)` to chi.Router interface\n\n\n## v2.0.0 (2017-01-06)\n\n- After many months of v2 being in an RC state with many companies and users running it in\n  production, the inclusion of some improvements to the middlewares, we are very pleased to\n  announce v2.0.0 of chi.\n\n\n## v2.0.0-rc1 (2016-07-26)\n\n- Huge update! chi v2 is a large refactor targeting Go 1.7+. As of Go 1.7, the popular\n  community `\"net/context\"` package has been included in the standard library as `\"context\"` and\n  utilized by `\"net/http\"` and `http.Request` to managing deadlines, cancelation signals and other\n  request-scoped values. We're very excited about the new context addition and are proud to\n  introduce chi v2, a minimal and powerful routing package for building large HTTP services,\n  with zero external dependencies. Chi focuses on idiomatic design and encourages the use of \n  stdlib HTTP handlers and middlewares.\n- chi v2 deprecates its `chi.Handler` interface and requires `http.Handler` or `http.HandlerFunc`\n- chi v2 stores URL routing parameters and patterns in the standard request context: `r.Context()`\n- chi v2 lower-level routing context is accessible by `chi.RouteContext(r.Context()) *chi.Context`,\n  which provides direct access to URL routing parameters, the routing path and the matching\n  routing patterns.\n- Users upgrading from chi v1 to v2, need to:\n  1. Update the old chi.Handler signature, `func(ctx context.Context, w http.ResponseWriter, r *http.Request)` to\n     the standard http.Handler: `func(w http.ResponseWriter, r *http.Request)`\n  2. Use `chi.URLParam(r *http.Request, paramKey string) string`\n     or `URLParamFromCtx(ctx context.Context, paramKey string) string` to access a url parameter value\n\n\n## v1.0.0 (2016-07-01)\n\n- Released chi v1 stable https://github.com/go-chi/chi/tree/v1.0.0 for Go 1.6 and older.\n\n\n## v0.9.0 (2016-03-31)\n\n- Reuse context objects via sync.Pool for zero-allocation routing [#33](https://github.com/go-chi/chi/pull/33)\n- BREAKING NOTE: due to subtle API changes, previously `chi.URLParams(ctx)[\"id\"]` used to access url parameters\n  has changed to: `chi.URLParam(ctx, \"id\")`\n"
  },
  {
    "path": "vendor/github.com/go-chi/chi/v5/CONTRIBUTING.md",
    "content": "# Contributing\n\n## Prerequisites\n\n1. [Install Go][go-install].\n2. Download the sources and switch the working directory:\n\n    ```bash\n    go get -u -d github.com/go-chi/chi\n    cd $GOPATH/src/github.com/go-chi/chi\n    ```\n\n## Submitting a Pull Request\n\nA typical workflow is:\n\n1. [Fork the repository.][fork]\n2. [Create a topic branch.][branch]\n3. Add tests for your change.\n4. Run `go test`. If your tests pass, return to the step 3.\n5. Implement the change and ensure the steps from the previous step pass.\n6. Run `goimports -w .`, to ensure the new code conforms to Go formatting guideline.\n7. [Add, commit and push your changes.][git-help]\n8. [Submit a pull request.][pull-req]\n\n[go-install]: https://golang.org/doc/install\n[fork]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo\n[branch]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-branches \n[git-help]: https://docs.github.com/en\n[pull-req]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests\n\n"
  },
  {
    "path": "vendor/github.com/go-chi/chi/v5/LICENSE",
    "content": "Copyright (c) 2015-present Peter Kieltyka (https://github.com/pkieltyka), Google Inc.\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject 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, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/go-chi/chi/v5/Makefile",
    "content": ".PHONY: all\nall:\n\t@echo \"**********************************************************\"\n\t@echo \"**                    chi build tool                    **\"\n\t@echo \"**********************************************************\"\n\n\n.PHONY: test\ntest:\n\tgo clean -testcache && $(MAKE) test-router && $(MAKE) test-middleware\n\n.PHONY: test-router\ntest-router:\n\tgo test -race -v .\n\n.PHONY: test-middleware\ntest-middleware:\n\tgo test -race -v ./middleware\n\n.PHONY: docs\ndocs:\n\tnpx docsify-cli serve ./docs\n"
  },
  {
    "path": "vendor/github.com/go-chi/chi/v5/README.md",
    "content": "# <img alt=\"chi\" src=\"https://cdn.rawgit.com/go-chi/chi/master/_examples/chi.svg\" width=\"220\" />\n\n\n[![GoDoc Widget]][GoDoc]\n\n`chi` is a lightweight, idiomatic and composable router for building Go HTTP services. It's\nespecially good at helping you write large REST API services that are kept maintainable as your\nproject grows and changes. `chi` is built on the new `context` package introduced in Go 1.7 to\nhandle signaling, cancelation and request-scoped values across a handler chain.\n\nThe focus of the project has been to seek out an elegant and comfortable design for writing\nREST API servers, written during the development of the Pressly API service that powers our\npublic API service, which in turn powers all of our client-side applications.\n\nThe key considerations of chi's design are: project structure, maintainability, standard http\nhandlers (stdlib-only), developer productivity, and deconstructing a large system into many small\nparts. The core router `github.com/go-chi/chi` is quite small (less than 1000 LOC), but we've also\nincluded some useful/optional subpackages: [middleware](/middleware), [render](https://github.com/go-chi/render)\nand [docgen](https://github.com/go-chi/docgen). We hope you enjoy it too!\n\n## Install\n\n```sh\ngo get -u github.com/go-chi/chi/v5\n```\n\n\n## Features\n\n* **Lightweight** - cloc'd in ~1000 LOC for the chi router\n* **Fast** - yes, see [benchmarks](#benchmarks)\n* **100% compatible with net/http** - use any http or middleware pkg in the ecosystem that is also compatible with `net/http`\n* **Designed for modular/composable APIs** - middlewares, inline middlewares, route groups and sub-router mounting\n* **Context control** - built on new `context` package, providing value chaining, cancellations and timeouts\n* **Robust** - in production at Pressly, Cloudflare, Heroku, 99Designs, and many others (see [discussion](https://github.com/go-chi/chi/issues/91))\n* **Doc generation** - `docgen` auto-generates routing documentation from your source to JSON or Markdown\n* **Go.mod support** - as of v5, go.mod support (see [CHANGELOG](https://github.com/go-chi/chi/blob/master/CHANGELOG.md))\n* **No external dependencies** - plain ol' Go stdlib + net/http\n\n\n## Examples\n\nSee [_examples/](https://github.com/go-chi/chi/blob/master/_examples/) for a variety of examples.\n\n\n**As easy as:**\n\n```go\npackage main\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/go-chi/chi/v5\"\n\t\"github.com/go-chi/chi/v5/middleware\"\n)\n\nfunc main() {\n\tr := chi.NewRouter()\n\tr.Use(middleware.Logger)\n\tr.Get(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tw.Write([]byte(\"welcome\"))\n\t})\n\thttp.ListenAndServe(\":3000\", r)\n}\n```\n\n**REST Preview:**\n\nHere is a little preview of what routing looks like with chi. Also take a look at the generated routing docs\nin JSON ([routes.json](https://github.com/go-chi/chi/blob/master/_examples/rest/routes.json)) and in\nMarkdown ([routes.md](https://github.com/go-chi/chi/blob/master/_examples/rest/routes.md)).\n\nI highly recommend reading the source of the [examples](https://github.com/go-chi/chi/blob/master/_examples/) listed\nabove, they will show you all the features of chi and serve as a good form of documentation.\n\n```go\nimport (\n  //...\n  \"context\"\n  \"github.com/go-chi/chi/v5\"\n  \"github.com/go-chi/chi/v5/middleware\"\n)\n\nfunc main() {\n  r := chi.NewRouter()\n\n  // A good base middleware stack\n  r.Use(middleware.RequestID)\n  r.Use(middleware.RealIP)\n  r.Use(middleware.Logger)\n  r.Use(middleware.Recoverer)\n\n  // Set a timeout value on the request context (ctx), that will signal\n  // through ctx.Done() that the request has timed out and further\n  // processing should be stopped.\n  r.Use(middleware.Timeout(60 * time.Second))\n\n  r.Get(\"/\", func(w http.ResponseWriter, r *http.Request) {\n    w.Write([]byte(\"hi\"))\n  })\n\n  // RESTy routes for \"articles\" resource\n  r.Route(\"/articles\", func(r chi.Router) {\n    r.With(paginate).Get(\"/\", listArticles)                           // GET /articles\n    r.With(paginate).Get(\"/{month}-{day}-{year}\", listArticlesByDate) // GET /articles/01-16-2017\n\n    r.Post(\"/\", createArticle)                                        // POST /articles\n    r.Get(\"/search\", searchArticles)                                  // GET /articles/search\n\n    // Regexp url parameters:\n    r.Get(\"/{articleSlug:[a-z-]+}\", getArticleBySlug)                // GET /articles/home-is-toronto\n\n    // Subrouters:\n    r.Route(\"/{articleID}\", func(r chi.Router) {\n      r.Use(ArticleCtx)\n      r.Get(\"/\", getArticle)                                          // GET /articles/123\n      r.Put(\"/\", updateArticle)                                       // PUT /articles/123\n      r.Delete(\"/\", deleteArticle)                                    // DELETE /articles/123\n    })\n  })\n\n  // Mount the admin sub-router\n  r.Mount(\"/admin\", adminRouter())\n\n  http.ListenAndServe(\":3333\", r)\n}\n\nfunc ArticleCtx(next http.Handler) http.Handler {\n  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n    articleID := chi.URLParam(r, \"articleID\")\n    article, err := dbGetArticle(articleID)\n    if err != nil {\n      http.Error(w, http.StatusText(404), 404)\n      return\n    }\n    ctx := context.WithValue(r.Context(), \"article\", article)\n    next.ServeHTTP(w, r.WithContext(ctx))\n  })\n}\n\nfunc getArticle(w http.ResponseWriter, r *http.Request) {\n  ctx := r.Context()\n  article, ok := ctx.Value(\"article\").(*Article)\n  if !ok {\n    http.Error(w, http.StatusText(422), 422)\n    return\n  }\n  w.Write([]byte(fmt.Sprintf(\"title:%s\", article.Title)))\n}\n\n// A completely separate router for administrator routes\nfunc adminRouter() http.Handler {\n  r := chi.NewRouter()\n  r.Use(AdminOnly)\n  r.Get(\"/\", adminIndex)\n  r.Get(\"/accounts\", adminListAccounts)\n  return r\n}\n\nfunc AdminOnly(next http.Handler) http.Handler {\n  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n    ctx := r.Context()\n    perm, ok := ctx.Value(\"acl.permission\").(YourPermissionType)\n    if !ok || !perm.IsAdmin() {\n      http.Error(w, http.StatusText(403), 403)\n      return\n    }\n    next.ServeHTTP(w, r)\n  })\n}\n```\n\n\n## Router interface\n\nchi's router is based on a kind of [Patricia Radix trie](https://en.wikipedia.org/wiki/Radix_tree).\nThe router is fully compatible with `net/http`.\n\nBuilt on top of the tree is the `Router` interface:\n\n```go\n// Router consisting of the core routing methods used by chi's Mux,\n// using only the standard net/http.\ntype Router interface {\n\thttp.Handler\n\tRoutes\n\n\t// Use appends one or more middlewares onto the Router stack.\n\tUse(middlewares ...func(http.Handler) http.Handler)\n\n\t// With adds inline middlewares for an endpoint handler.\n\tWith(middlewares ...func(http.Handler) http.Handler) Router\n\n\t// Group adds a new inline-Router along the current routing\n\t// path, with a fresh middleware stack for the inline-Router.\n\tGroup(fn func(r Router)) Router\n\n\t// Route mounts a sub-Router along a `pattern` string.\n\tRoute(pattern string, fn func(r Router)) Router\n\n\t// Mount attaches another http.Handler along ./pattern/*\n\tMount(pattern string, h http.Handler)\n\n\t// Handle and HandleFunc adds routes for `pattern` that matches\n\t// all HTTP methods.\n\tHandle(pattern string, h http.Handler)\n\tHandleFunc(pattern string, h http.HandlerFunc)\n\n\t// Method and MethodFunc adds routes for `pattern` that matches\n\t// the `method` HTTP method.\n\tMethod(method, pattern string, h http.Handler)\n\tMethodFunc(method, pattern string, h http.HandlerFunc)\n\n\t// HTTP-method routing along `pattern`\n\tConnect(pattern string, h http.HandlerFunc)\n\tDelete(pattern string, h http.HandlerFunc)\n\tGet(pattern string, h http.HandlerFunc)\n\tHead(pattern string, h http.HandlerFunc)\n\tOptions(pattern string, h http.HandlerFunc)\n\tPatch(pattern string, h http.HandlerFunc)\n\tPost(pattern string, h http.HandlerFunc)\n\tPut(pattern string, h http.HandlerFunc)\n\tTrace(pattern string, h http.HandlerFunc)\n\n\t// NotFound defines a handler to respond whenever a route could\n\t// not be found.\n\tNotFound(h http.HandlerFunc)\n\n\t// MethodNotAllowed defines a handler to respond whenever a method is\n\t// not allowed.\n\tMethodNotAllowed(h http.HandlerFunc)\n}\n\n// Routes interface adds two methods for router traversal, which is also\n// used by the github.com/go-chi/docgen package to generate documentation for Routers.\ntype Routes interface {\n\t// Routes returns the routing tree in an easily traversable structure.\n\tRoutes() []Route\n\n\t// Middlewares returns the list of middlewares in use by the router.\n\tMiddlewares() Middlewares\n\n\t// Match searches the routing tree for a handler that matches\n\t// the method/path - similar to routing a http request, but without\n\t// executing the handler thereafter.\n\tMatch(rctx *Context, method, path string) bool\n}\n```\n\nEach routing method accepts a URL `pattern` and chain of `handlers`. The URL pattern\nsupports named params (ie. `/users/{userID}`) and wildcards (ie. `/admin/*`). URL parameters\ncan be fetched at runtime by calling `chi.URLParam(r, \"userID\")` for named parameters\nand `chi.URLParam(r, \"*\")` for a wildcard parameter.\n\n\n### Middleware handlers\n\nchi's middlewares are just stdlib net/http middleware handlers. There is nothing special\nabout them, which means the router and all the tooling is designed to be compatible and\nfriendly with any middleware in the community. This offers much better extensibility and reuse\nof packages and is at the heart of chi's purpose.\n\nHere is an example of a standard net/http middleware where we assign a context key `\"user\"`\nthe value of `\"123\"`. This middleware sets a hypothetical user identifier on the request\ncontext and calls the next handler in the chain.\n\n```go\n// HTTP middleware setting a value on the request context\nfunc MyMiddleware(next http.Handler) http.Handler {\n  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n    // create new context from `r` request context, and assign key `\"user\"`\n    // to value of `\"123\"`\n    ctx := context.WithValue(r.Context(), \"user\", \"123\")\n\n    // call the next handler in the chain, passing the response writer and\n    // the updated request object with the new context value.\n    //\n    // note: context.Context values are nested, so any previously set\n    // values will be accessible as well, and the new `\"user\"` key\n    // will be accessible from this point forward.\n    next.ServeHTTP(w, r.WithContext(ctx))\n  })\n}\n```\n\n\n### Request handlers\n\nchi uses standard net/http request handlers. This little snippet is an example of a http.Handler\nfunc that reads a user identifier from the request context - hypothetically, identifying\nthe user sending an authenticated request, validated+set by a previous middleware handler.\n\n```go\n// HTTP handler accessing data from the request context.\nfunc MyRequestHandler(w http.ResponseWriter, r *http.Request) {\n  // here we read from the request context and fetch out `\"user\"` key set in\n  // the MyMiddleware example above.\n  user := r.Context().Value(\"user\").(string)\n\n  // respond to the client\n  w.Write([]byte(fmt.Sprintf(\"hi %s\", user)))\n}\n```\n\n\n### URL parameters\n\nchi's router parses and stores URL parameters right onto the request context. Here is\nan example of how to access URL params in your net/http handlers. And of course, middlewares\nare able to access the same information.\n\n```go\n// HTTP handler accessing the url routing parameters.\nfunc MyRequestHandler(w http.ResponseWriter, r *http.Request) {\n  // fetch the url parameter `\"userID\"` from the request of a matching\n  // routing pattern. An example routing pattern could be: /users/{userID}\n  userID := chi.URLParam(r, \"userID\")\n\n  // fetch `\"key\"` from the request context\n  ctx := r.Context()\n  key := ctx.Value(\"key\").(string)\n\n  // respond to the client\n  w.Write([]byte(fmt.Sprintf(\"hi %v, %v\", userID, key)))\n}\n```\n\n\n## Middlewares\n\nchi comes equipped with an optional `middleware` package, providing a suite of standard\n`net/http` middlewares. Please note, any middleware in the ecosystem that is also compatible\nwith `net/http` can be used with chi's mux.\n\n### Core middlewares\n\n----------------------------------------------------------------------------------------------------\n| chi/middleware Handler | description                                                             |\n| :--------------------- | :---------------------------------------------------------------------- |\n| [AllowContentEncoding] | Enforces a whitelist of request Content-Encoding headers                |\n| [AllowContentType]     | Explicit whitelist of accepted request Content-Types                    |\n| [BasicAuth]            | Basic HTTP authentication                                               |\n| [Compress]             | Gzip compression for clients that accept compressed responses           |\n| [ContentCharset]       | Ensure charset for Content-Type request headers                         |\n| [CleanPath]            | Clean double slashes from request path                                  |\n| [GetHead]              | Automatically route undefined HEAD requests to GET handlers             |\n| [Heartbeat]            | Monitoring endpoint to check the servers pulse                          |\n| [Logger]               | Logs the start and end of each request with the elapsed processing time |\n| [NoCache]              | Sets response headers to prevent clients from caching                   |\n| [Profiler]             | Easily attach net/http/pprof to your routers                            |\n| [RealIP]               | Sets a http.Request's RemoteAddr to either X-Real-IP or X-Forwarded-For |\n| [Recoverer]            | Gracefully absorb panics and prints the stack trace                     |\n| [RequestID]            | Injects a request ID into the context of each request                   |\n| [RedirectSlashes]      | Redirect slashes on routing paths                                       |\n| [RouteHeaders]         | Route handling for request headers                                      |\n| [SetHeader]            | Short-hand middleware to set a response header key/value                |\n| [StripSlashes]         | Strip slashes on routing paths                                          |\n| [Sunset]               | Sunset set Deprecation/Sunset header to response                        |\n| [Throttle]             | Puts a ceiling on the number of concurrent requests                     |\n| [Timeout]              | Signals to the request context when the timeout deadline is reached     |\n| [URLFormat]            | Parse extension from url and put it on request context                  |\n| [WithValue]            | Short-hand middleware to set a key/value on the request context         |\n----------------------------------------------------------------------------------------------------\n\n[AllowContentEncoding]: https://pkg.go.dev/github.com/go-chi/chi/middleware#AllowContentEncoding\n[AllowContentType]: https://pkg.go.dev/github.com/go-chi/chi/middleware#AllowContentType\n[BasicAuth]: https://pkg.go.dev/github.com/go-chi/chi/middleware#BasicAuth\n[Compress]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Compress\n[ContentCharset]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ContentCharset\n[CleanPath]: https://pkg.go.dev/github.com/go-chi/chi/middleware#CleanPath\n[GetHead]: https://pkg.go.dev/github.com/go-chi/chi/middleware#GetHead\n[GetReqID]: https://pkg.go.dev/github.com/go-chi/chi/middleware#GetReqID\n[Heartbeat]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Heartbeat\n[Logger]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Logger\n[NoCache]: https://pkg.go.dev/github.com/go-chi/chi/middleware#NoCache\n[Profiler]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Profiler\n[RealIP]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RealIP\n[Recoverer]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Recoverer\n[RedirectSlashes]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RedirectSlashes\n[RequestLogger]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RequestLogger\n[RequestID]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RequestID\n[RouteHeaders]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RouteHeaders\n[SetHeader]: https://pkg.go.dev/github.com/go-chi/chi/middleware#SetHeader\n[StripSlashes]: https://pkg.go.dev/github.com/go-chi/chi/middleware#StripSlashes\n[Sunset]: https://pkg.go.dev/github.com/go-chi/chi/v5/middleware#Sunset\n[Throttle]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Throttle\n[ThrottleBacklog]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ThrottleBacklog\n[ThrottleWithOpts]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ThrottleWithOpts\n[Timeout]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Timeout\n[URLFormat]: https://pkg.go.dev/github.com/go-chi/chi/middleware#URLFormat\n[WithLogEntry]: https://pkg.go.dev/github.com/go-chi/chi/middleware#WithLogEntry\n[WithValue]: https://pkg.go.dev/github.com/go-chi/chi/middleware#WithValue\n[Compressor]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Compressor\n[DefaultLogFormatter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#DefaultLogFormatter\n[EncoderFunc]: https://pkg.go.dev/github.com/go-chi/chi/middleware#EncoderFunc\n[HeaderRoute]: https://pkg.go.dev/github.com/go-chi/chi/middleware#HeaderRoute\n[HeaderRouter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#HeaderRouter\n[LogEntry]: https://pkg.go.dev/github.com/go-chi/chi/middleware#LogEntry\n[LogFormatter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#LogFormatter\n[LoggerInterface]: https://pkg.go.dev/github.com/go-chi/chi/middleware#LoggerInterface\n[ThrottleOpts]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ThrottleOpts\n[WrapResponseWriter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#WrapResponseWriter\n\n### Extra middlewares & packages\n\nPlease see https://github.com/go-chi for additional packages.\n\n--------------------------------------------------------------------------------------------------------------------\n| package                                            | description                                                 |\n|:---------------------------------------------------|:-------------------------------------------------------------\n| [cors](https://github.com/go-chi/cors)             | Cross-origin resource sharing (CORS)                        |\n| [docgen](https://github.com/go-chi/docgen)         | Print chi.Router routes at runtime                          |\n| [jwtauth](https://github.com/go-chi/jwtauth)       | JWT authentication                                          |\n| [hostrouter](https://github.com/go-chi/hostrouter) | Domain/host based request routing                           |\n| [httplog](https://github.com/go-chi/httplog)       | Small but powerful structured HTTP request logging          |\n| [httprate](https://github.com/go-chi/httprate)     | HTTP request rate limiter                                   |\n| [httptracer](https://github.com/go-chi/httptracer) | HTTP request performance tracing library                    |\n| [httpvcr](https://github.com/go-chi/httpvcr)       | Write deterministic tests for external sources              |\n| [stampede](https://github.com/go-chi/stampede)     | HTTP request coalescer                                      |\n--------------------------------------------------------------------------------------------------------------------\n\n\n## context?\n\n`context` is a tiny pkg that provides simple interface to signal context across call stacks\nand goroutines. It was originally written by [Sameer Ajmani](https://github.com/Sajmani)\nand is available in stdlib since go1.7.\n\nLearn more at https://blog.golang.org/context\n\nand..\n* Docs: https://golang.org/pkg/context\n* Source: https://github.com/golang/go/tree/master/src/context\n\n\n## Benchmarks\n\nThe benchmark suite: https://github.com/pkieltyka/go-http-routing-benchmark\n\nResults as of Nov 29, 2020 with Go 1.15.5 on Linux AMD 3950x\n\n```shell\nBenchmarkChi_Param          \t3075895\t        384 ns/op\t      400 B/op      2 allocs/op\nBenchmarkChi_Param5         \t2116603\t        566 ns/op\t      400 B/op      2 allocs/op\nBenchmarkChi_Param20        \t 964117\t       1227 ns/op\t      400 B/op      2 allocs/op\nBenchmarkChi_ParamWrite     \t2863413\t        420 ns/op\t      400 B/op      2 allocs/op\nBenchmarkChi_GithubStatic   \t3045488\t        395 ns/op\t      400 B/op      2 allocs/op\nBenchmarkChi_GithubParam    \t2204115\t        540 ns/op\t      400 B/op      2 allocs/op\nBenchmarkChi_GithubAll      \t  10000\t     113811 ns/op\t    81203 B/op    406 allocs/op\nBenchmarkChi_GPlusStatic    \t3337485\t        359 ns/op\t      400 B/op      2 allocs/op\nBenchmarkChi_GPlusParam     \t2825853\t        423 ns/op\t      400 B/op      2 allocs/op\nBenchmarkChi_GPlus2Params   \t2471697\t        483 ns/op\t      400 B/op      2 allocs/op\nBenchmarkChi_GPlusAll       \t 194220\t       5950 ns/op\t     5200 B/op     26 allocs/op\nBenchmarkChi_ParseStatic    \t3365324\t        356 ns/op\t      400 B/op      2 allocs/op\nBenchmarkChi_ParseParam     \t2976614\t        404 ns/op\t      400 B/op      2 allocs/op\nBenchmarkChi_Parse2Params   \t2638084\t        439 ns/op\t      400 B/op      2 allocs/op\nBenchmarkChi_ParseAll       \t 109567\t      11295 ns/op\t    10400 B/op     52 allocs/op\nBenchmarkChi_StaticAll      \t  16846\t      71308 ns/op\t    62802 B/op    314 allocs/op\n```\n\nComparison with other routers: https://gist.github.com/pkieltyka/123032f12052520aaccab752bd3e78cc\n\nNOTE: the allocs in the benchmark above are from the calls to http.Request's\n`WithContext(context.Context)` method that clones the http.Request, sets the `Context()`\non the duplicated (alloc'd) request and returns it the new request object. This is just\nhow setting context on a request in Go works.\n\n\n## Credits\n\n* Carl Jackson for https://github.com/zenazn/goji\n  * Parts of chi's thinking comes from goji, and chi's middleware package\n    sources from [goji](https://github.com/zenazn/goji/tree/master/web/middleware).\n  * Please see goji's [LICENSE](https://github.com/zenazn/goji/blob/master/LICENSE) (MIT)\n* Armon Dadgar for https://github.com/armon/go-radix\n* Contributions: [@VojtechVitek](https://github.com/VojtechVitek)\n\nWe'll be more than happy to see [your contributions](./CONTRIBUTING.md)!\n\n\n## Beyond REST\n\nchi is just a http router that lets you decompose request handling into many smaller layers.\nMany companies use chi to write REST services for their public APIs. But, REST is just a convention\nfor managing state via HTTP, and there's a lot of other pieces required to write a complete client-server\nsystem or network of microservices.\n\nLooking beyond REST, I also recommend some newer works in the field:\n* [webrpc](https://github.com/webrpc/webrpc) - Web-focused RPC client+server framework with code-gen\n* [gRPC](https://github.com/grpc/grpc-go) - Google's RPC framework via protobufs\n* [graphql](https://github.com/99designs/gqlgen) - Declarative query language\n* [NATS](https://nats.io) - lightweight pub-sub\n\n\n## License\n\nCopyright (c) 2015-present [Peter Kieltyka](https://github.com/pkieltyka)\n\nLicensed under [MIT License](./LICENSE)\n\n[GoDoc]: https://pkg.go.dev/github.com/go-chi/chi/v5\n[GoDoc Widget]: https://godoc.org/github.com/go-chi/chi?status.svg\n[Travis]: https://travis-ci.org/go-chi/chi\n[Travis Widget]: https://travis-ci.org/go-chi/chi.svg?branch=master\n"
  },
  {
    "path": "vendor/github.com/go-chi/chi/v5/SECURITY.md",
    "content": "# Reporting Security Issues\n\nWe appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.\n\nTo report a security issue, please use the GitHub Security Advisory [\"Report a Vulnerability\"](https://github.com/go-chi/chi/security/advisories/new) tab.\n"
  },
  {
    "path": "vendor/github.com/go-chi/chi/v5/chain.go",
    "content": "package chi\n\nimport \"net/http\"\n\n// Chain returns a Middlewares type from a slice of middleware handlers.\nfunc Chain(middlewares ...func(http.Handler) http.Handler) Middlewares {\n\treturn Middlewares(middlewares)\n}\n\n// Handler builds and returns a http.Handler from the chain of middlewares,\n// with `h http.Handler` as the final handler.\nfunc (mws Middlewares) Handler(h http.Handler) http.Handler {\n\treturn &ChainHandler{h, chain(mws, h), mws}\n}\n\n// HandlerFunc builds and returns a http.Handler from the chain of middlewares,\n// with `h http.Handler` as the final handler.\nfunc (mws Middlewares) HandlerFunc(h http.HandlerFunc) http.Handler {\n\treturn &ChainHandler{h, chain(mws, h), mws}\n}\n\n// ChainHandler is a http.Handler with support for handler composition and\n// execution.\ntype ChainHandler struct {\n\tEndpoint    http.Handler\n\tchain       http.Handler\n\tMiddlewares Middlewares\n}\n\nfunc (c *ChainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tc.chain.ServeHTTP(w, r)\n}\n\n// chain builds a http.Handler composed of an inline middleware stack and endpoint\n// handler in the order they are passed.\nfunc chain(middlewares []func(http.Handler) http.Handler, endpoint http.Handler) http.Handler {\n\t// Return ahead of time if there aren't any middlewares for the chain\n\tif len(middlewares) == 0 {\n\t\treturn endpoint\n\t}\n\n\t// Wrap the end handler with the middleware chain\n\th := middlewares[len(middlewares)-1](endpoint)\n\tfor i := len(middlewares) - 2; i >= 0; i-- {\n\t\th = middlewares[i](h)\n\t}\n\n\treturn h\n}\n"
  },
  {
    "path": "vendor/github.com/go-chi/chi/v5/chi.go",
    "content": "// Package chi is a small, idiomatic and composable router for building HTTP services.\n//\n// chi requires Go 1.14 or newer.\n//\n// Example:\n//\n//\tpackage main\n//\n//\timport (\n//\t\t\"net/http\"\n//\n//\t\t\"github.com/go-chi/chi/v5\"\n//\t\t\"github.com/go-chi/chi/v5/middleware\"\n//\t)\n//\n//\tfunc main() {\n//\t\tr := chi.NewRouter()\n//\t\tr.Use(middleware.Logger)\n//\t\tr.Use(middleware.Recoverer)\n//\n//\t\tr.Get(\"/\", func(w http.ResponseWriter, r *http.Request) {\n//\t\t\tw.Write([]byte(\"root.\"))\n//\t\t})\n//\n//\t\thttp.ListenAndServe(\":3333\", r)\n//\t}\n//\n// See github.com/go-chi/chi/_examples/ for more in-depth examples.\n//\n// URL patterns allow for easy matching of path components in HTTP\n// requests. The matching components can then be accessed using\n// chi.URLParam(). All patterns must begin with a slash.\n//\n// A simple named placeholder {name} matches any sequence of characters\n// up to the next / or the end of the URL. Trailing slashes on paths must\n// be handled explicitly.\n//\n// A placeholder with a name followed by a colon allows a regular\n// expression match, for example {number:\\\\d+}. The regular expression\n// syntax is Go's normal regexp RE2 syntax, except that / will never be\n// matched. An anonymous regexp pattern is allowed, using an empty string\n// before the colon in the placeholder, such as {:\\\\d+}\n//\n// The special placeholder of asterisk matches the rest of the requested\n// URL. Any trailing characters in the pattern are ignored. This is the only\n// placeholder which will match / characters.\n//\n// Examples:\n//\n//\t\"/user/{name}\" matches \"/user/jsmith\" but not \"/user/jsmith/info\" or \"/user/jsmith/\"\n//\t\"/user/{name}/info\" matches \"/user/jsmith/info\"\n//\t\"/page/*\" matches \"/page/intro/latest\"\n//\t\"/page/{other}/latest\" also matches \"/page/intro/latest\"\n//\t\"/date/{yyyy:\\\\d\\\\d\\\\d\\\\d}/{mm:\\\\d\\\\d}/{dd:\\\\d\\\\d}\" matches \"/date/2017/04/01\"\npackage chi\n\nimport \"net/http\"\n\n// NewRouter returns a new Mux object that implements the Router interface.\nfunc NewRouter() *Mux {\n\treturn NewMux()\n}\n\n// Router consisting of the core routing methods used by chi's Mux,\n// using only the standard net/http.\ntype Router interface {\n\thttp.Handler\n\tRoutes\n\n\t// Use appends one or more middlewares onto the Router stack.\n\tUse(middlewares ...func(http.Handler) http.Handler)\n\n\t// With adds inline middlewares for an endpoint handler.\n\tWith(middlewares ...func(http.Handler) http.Handler) Router\n\n\t// Group adds a new inline-Router along the current routing\n\t// path, with a fresh middleware stack for the inline-Router.\n\tGroup(fn func(r Router)) Router\n\n\t// Route mounts a sub-Router along a `pattern`` string.\n\tRoute(pattern string, fn func(r Router)) Router\n\n\t// Mount attaches another http.Handler along ./pattern/*\n\tMount(pattern string, h http.Handler)\n\n\t// Handle and HandleFunc adds routes for `pattern` that matches\n\t// all HTTP methods.\n\tHandle(pattern string, h http.Handler)\n\tHandleFunc(pattern string, h http.HandlerFunc)\n\n\t// Method and MethodFunc adds routes for `pattern` that matches\n\t// the `method` HTTP method.\n\tMethod(method, pattern string, h http.Handler)\n\tMethodFunc(method, pattern string, h http.HandlerFunc)\n\n\t// HTTP-method routing along `pattern`\n\tConnect(pattern string, h http.HandlerFunc)\n\tDelete(pattern string, h http.HandlerFunc)\n\tGet(pattern string, h http.HandlerFunc)\n\tHead(pattern string, h http.HandlerFunc)\n\tOptions(pattern string, h http.HandlerFunc)\n\tPatch(pattern string, h http.HandlerFunc)\n\tPost(pattern string, h http.HandlerFunc)\n\tPut(pattern string, h http.HandlerFunc)\n\tTrace(pattern string, h http.HandlerFunc)\n\n\t// NotFound defines a handler to respond whenever a route could\n\t// not be found.\n\tNotFound(h http.HandlerFunc)\n\n\t// MethodNotAllowed defines a handler to respond whenever a method is\n\t// not allowed.\n\tMethodNotAllowed(h http.HandlerFunc)\n}\n\n// Routes interface adds two methods for router traversal, which is also\n// used by the `docgen` subpackage to generation documentation for Routers.\ntype Routes interface {\n\t// Routes returns the routing tree in an easily traversable structure.\n\tRoutes() []Route\n\n\t// Middlewares returns the list of middlewares in use by the router.\n\tMiddlewares() Middlewares\n\n\t// Match searches the routing tree for a handler that matches\n\t// the method/path - similar to routing a http request, but without\n\t// executing the handler thereafter.\n\tMatch(rctx *Context, method, path string) bool\n\n\t// Find searches the routing tree for the pattern that matches\n\t// the method/path.\n\tFind(rctx *Context, method, path string) string\n}\n\n// Middlewares type is a slice of standard middleware handlers with methods\n// to compose middleware chains and http.Handler's.\ntype Middlewares []func(http.Handler) http.Handler\n"
  },
  {
    "path": "vendor/github.com/go-chi/chi/v5/context.go",
    "content": "package chi\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"strings\"\n)\n\n// URLParam returns the url parameter from a http.Request object.\nfunc URLParam(r *http.Request, key string) string {\n\tif rctx := RouteContext(r.Context()); rctx != nil {\n\t\treturn rctx.URLParam(key)\n\t}\n\treturn \"\"\n}\n\n// URLParamFromCtx returns the url parameter from a http.Request Context.\nfunc URLParamFromCtx(ctx context.Context, key string) string {\n\tif rctx := RouteContext(ctx); rctx != nil {\n\t\treturn rctx.URLParam(key)\n\t}\n\treturn \"\"\n}\n\n// RouteContext returns chi's routing Context object from a\n// http.Request Context.\nfunc RouteContext(ctx context.Context) *Context {\n\tval, _ := ctx.Value(RouteCtxKey).(*Context)\n\treturn val\n}\n\n// NewRouteContext returns a new routing Context object.\nfunc NewRouteContext() *Context {\n\treturn &Context{}\n}\n\nvar (\n\t// RouteCtxKey is the context.Context key to store the request context.\n\tRouteCtxKey = &contextKey{\"RouteContext\"}\n)\n\n// Context is the default routing context set on the root node of a\n// request context to track route patterns, URL parameters and\n// an optional routing path.\ntype Context struct {\n\tRoutes Routes\n\n\t// parentCtx is the parent of this one, for using Context as a\n\t// context.Context directly. This is an optimization that saves\n\t// 1 allocation.\n\tparentCtx context.Context\n\n\t// Routing path/method override used during the route search.\n\t// See Mux#routeHTTP method.\n\tRoutePath   string\n\tRouteMethod string\n\n\t// URLParams are the stack of routeParams captured during the\n\t// routing lifecycle across a stack of sub-routers.\n\tURLParams RouteParams\n\n\t// Route parameters matched for the current sub-router. It is\n\t// intentionally unexported so it can't be tampered.\n\trouteParams RouteParams\n\n\t// The endpoint routing pattern that matched the request URI path\n\t// or `RoutePath` of the current sub-router. This value will update\n\t// during the lifecycle of a request passing through a stack of\n\t// sub-routers.\n\troutePattern string\n\n\t// Routing pattern stack throughout the lifecycle of the request,\n\t// across all connected routers. It is a record of all matching\n\t// patterns across a stack of sub-routers.\n\tRoutePatterns []string\n\n\tmethodsAllowed   []methodTyp // allowed methods in case of a 405\n\tmethodNotAllowed bool\n}\n\n// Reset a routing context to its initial state.\nfunc (x *Context) Reset() {\n\tx.Routes = nil\n\tx.RoutePath = \"\"\n\tx.RouteMethod = \"\"\n\tx.RoutePatterns = x.RoutePatterns[:0]\n\tx.URLParams.Keys = x.URLParams.Keys[:0]\n\tx.URLParams.Values = x.URLParams.Values[:0]\n\n\tx.routePattern = \"\"\n\tx.routeParams.Keys = x.routeParams.Keys[:0]\n\tx.routeParams.Values = x.routeParams.Values[:0]\n\tx.methodNotAllowed = false\n\tx.methodsAllowed = x.methodsAllowed[:0]\n\tx.parentCtx = nil\n}\n\n// URLParam returns the corresponding URL parameter value from the request\n// routing context.\nfunc (x *Context) URLParam(key string) string {\n\tfor k := len(x.URLParams.Keys) - 1; k >= 0; k-- {\n\t\tif x.URLParams.Keys[k] == key {\n\t\t\treturn x.URLParams.Values[k]\n\t\t}\n\t}\n\treturn \"\"\n}\n\n// RoutePattern builds the routing pattern string for the particular\n// request, at the particular point during routing. This means, the value\n// will change throughout the execution of a request in a router. That is\n// why it's advised to only use this value after calling the next handler.\n//\n// For example,\n//\n//\tfunc Instrument(next http.Handler) http.Handler {\n//\t\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n//\t\t\tnext.ServeHTTP(w, r)\n//\t\t\troutePattern := chi.RouteContext(r.Context()).RoutePattern()\n//\t\t\tmeasure(w, r, routePattern)\n//\t\t})\n//\t}\nfunc (x *Context) RoutePattern() string {\n\tif x == nil {\n\t\treturn \"\"\n\t}\n\troutePattern := strings.Join(x.RoutePatterns, \"\")\n\troutePattern = replaceWildcards(routePattern)\n\tif routePattern != \"/\" {\n\t\troutePattern = strings.TrimSuffix(routePattern, \"//\")\n\t\troutePattern = strings.TrimSuffix(routePattern, \"/\")\n\t}\n\treturn routePattern\n}\n\n// replaceWildcards takes a route pattern and recursively replaces all\n// occurrences of \"/*/\" to \"/\".\nfunc replaceWildcards(p string) string {\n\tif strings.Contains(p, \"/*/\") {\n\t\treturn replaceWildcards(strings.Replace(p, \"/*/\", \"/\", -1))\n\t}\n\treturn p\n}\n\n// RouteParams is a structure to track URL routing parameters efficiently.\ntype RouteParams struct {\n\tKeys, Values []string\n}\n\n// Add will append a URL parameter to the end of the route param\nfunc (s *RouteParams) Add(key, value string) {\n\ts.Keys = append(s.Keys, key)\n\ts.Values = append(s.Values, value)\n}\n\n// contextKey is a value for use with context.WithValue. It's used as\n// a pointer so it fits in an interface{} without allocation. This technique\n// for defining context keys was copied from Go 1.7's new use of context in net/http.\ntype contextKey struct {\n\tname string\n}\n\nfunc (k *contextKey) String() string {\n\treturn \"chi context value \" + k.name\n}\n"
  },
  {
    "path": "vendor/github.com/go-chi/chi/v5/mux.go",
    "content": "package chi\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\t\"sync\"\n)\n\nvar _ Router = &Mux{}\n\n// Mux is a simple HTTP route multiplexer that parses a request path,\n// records any URL params, and executes an end handler. It implements\n// the http.Handler interface and is friendly with the standard library.\n//\n// Mux is designed to be fast, minimal and offer a powerful API for building\n// modular and composable HTTP services with a large set of handlers. It's\n// particularly useful for writing large REST API services that break a handler\n// into many smaller parts composed of middlewares and end handlers.\ntype Mux struct {\n\t// The computed mux handler made of the chained middleware stack and\n\t// the tree router\n\thandler http.Handler\n\n\t// The radix trie router\n\ttree *node\n\n\t// Custom method not allowed handler\n\tmethodNotAllowedHandler http.HandlerFunc\n\n\t// A reference to the parent mux used by subrouters when mounting\n\t// to a parent mux\n\tparent *Mux\n\n\t// Routing context pool\n\tpool *sync.Pool\n\n\t// Custom route not found handler\n\tnotFoundHandler http.HandlerFunc\n\n\t// The middleware stack\n\tmiddlewares []func(http.Handler) http.Handler\n\n\t// Controls the behaviour of middleware chain generation when a mux\n\t// is registered as an inline group inside another mux.\n\tinline bool\n}\n\n// NewMux returns a newly initialized Mux object that implements the Router\n// interface.\nfunc NewMux() *Mux {\n\tmux := &Mux{tree: &node{}, pool: &sync.Pool{}}\n\tmux.pool.New = func() interface{} {\n\t\treturn NewRouteContext()\n\t}\n\treturn mux\n}\n\n// ServeHTTP is the single method of the http.Handler interface that makes\n// Mux interoperable with the standard library. It uses a sync.Pool to get and\n// reuse routing contexts for each request.\nfunc (mx *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\t// Ensure the mux has some routes defined on the mux\n\tif mx.handler == nil {\n\t\tmx.NotFoundHandler().ServeHTTP(w, r)\n\t\treturn\n\t}\n\n\t// Check if a routing context already exists from a parent router.\n\trctx, _ := r.Context().Value(RouteCtxKey).(*Context)\n\tif rctx != nil {\n\t\tmx.handler.ServeHTTP(w, r)\n\t\treturn\n\t}\n\n\t// Fetch a RouteContext object from the sync pool, and call the computed\n\t// mx.handler that is comprised of mx.middlewares + mx.routeHTTP.\n\t// Once the request is finished, reset the routing context and put it back\n\t// into the pool for reuse from another request.\n\trctx = mx.pool.Get().(*Context)\n\trctx.Reset()\n\trctx.Routes = mx\n\trctx.parentCtx = r.Context()\n\n\t// NOTE: r.WithContext() causes 2 allocations and context.WithValue() causes 1 allocation\n\tr = r.WithContext(context.WithValue(r.Context(), RouteCtxKey, rctx))\n\n\t// Serve the request and once its done, put the request context back in the sync pool\n\tmx.handler.ServeHTTP(w, r)\n\tmx.pool.Put(rctx)\n}\n\n// Use appends a middleware handler to the Mux middleware stack.\n//\n// The middleware stack for any Mux will execute before searching for a matching\n// route to a specific handler, which provides opportunity to respond early,\n// change the course of the request execution, or set request-scoped values for\n// the next http.Handler.\nfunc (mx *Mux) Use(middlewares ...func(http.Handler) http.Handler) {\n\tif mx.handler != nil {\n\t\tpanic(\"chi: all middlewares must be defined before routes on a mux\")\n\t}\n\tmx.middlewares = append(mx.middlewares, middlewares...)\n}\n\n// Handle adds the route `pattern` that matches any http method to\n// execute the `handler` http.Handler.\nfunc (mx *Mux) Handle(pattern string, handler http.Handler) {\n\tif method, rest, found := strings.Cut(pattern, \" \"); found {\n\t\tmx.Method(method, rest, handler)\n\t\treturn\n\t}\n\n\tmx.handle(mALL, pattern, handler)\n}\n\n// HandleFunc adds the route `pattern` that matches any http method to\n// execute the `handlerFn` http.HandlerFunc.\nfunc (mx *Mux) HandleFunc(pattern string, handlerFn http.HandlerFunc) {\n\tif method, rest, found := strings.Cut(pattern, \" \"); found {\n\t\tmx.Method(method, rest, handlerFn)\n\t\treturn\n\t}\n\n\tmx.handle(mALL, pattern, handlerFn)\n}\n\n// Method adds the route `pattern` that matches `method` http method to\n// execute the `handler` http.Handler.\nfunc (mx *Mux) Method(method, pattern string, handler http.Handler) {\n\tm, ok := methodMap[strings.ToUpper(method)]\n\tif !ok {\n\t\tpanic(fmt.Sprintf(\"chi: '%s' http method is not supported.\", method))\n\t}\n\tmx.handle(m, pattern, handler)\n}\n\n// MethodFunc adds the route `pattern` that matches `method` http method to\n// execute the `handlerFn` http.HandlerFunc.\nfunc (mx *Mux) MethodFunc(method, pattern string, handlerFn http.HandlerFunc) {\n\tmx.Method(method, pattern, handlerFn)\n}\n\n// Connect adds the route `pattern` that matches a CONNECT http method to\n// execute the `handlerFn` http.HandlerFunc.\nfunc (mx *Mux) Connect(pattern string, handlerFn http.HandlerFunc) {\n\tmx.handle(mCONNECT, pattern, handlerFn)\n}\n\n// Delete adds the route `pattern` that matches a DELETE http method to\n// execute the `handlerFn` http.HandlerFunc.\nfunc (mx *Mux) Delete(pattern string, handlerFn http.HandlerFunc) {\n\tmx.handle(mDELETE, pattern, handlerFn)\n}\n\n// Get adds the route `pattern` that matches a GET http method to\n// execute the `handlerFn` http.HandlerFunc.\nfunc (mx *Mux) Get(pattern string, handlerFn http.HandlerFunc) {\n\tmx.handle(mGET, pattern, handlerFn)\n}\n\n// Head adds the route `pattern` that matches a HEAD http method to\n// execute the `handlerFn` http.HandlerFunc.\nfunc (mx *Mux) Head(pattern string, handlerFn http.HandlerFunc) {\n\tmx.handle(mHEAD, pattern, handlerFn)\n}\n\n// Options adds the route `pattern` that matches an OPTIONS http method to\n// execute the `handlerFn` http.HandlerFunc.\nfunc (mx *Mux) Options(pattern string, handlerFn http.HandlerFunc) {\n\tmx.handle(mOPTIONS, pattern, handlerFn)\n}\n\n// Patch adds the route `pattern` that matches a PATCH http method to\n// execute the `handlerFn` http.HandlerFunc.\nfunc (mx *Mux) Patch(pattern string, handlerFn http.HandlerFunc) {\n\tmx.handle(mPATCH, pattern, handlerFn)\n}\n\n// Post adds the route `pattern` that matches a POST http method to\n// execute the `handlerFn` http.HandlerFunc.\nfunc (mx *Mux) Post(pattern string, handlerFn http.HandlerFunc) {\n\tmx.handle(mPOST, pattern, handlerFn)\n}\n\n// Put adds the route `pattern` that matches a PUT http method to\n// execute the `handlerFn` http.HandlerFunc.\nfunc (mx *Mux) Put(pattern string, handlerFn http.HandlerFunc) {\n\tmx.handle(mPUT, pattern, handlerFn)\n}\n\n// Trace adds the route `pattern` that matches a TRACE http method to\n// execute the `handlerFn` http.HandlerFunc.\nfunc (mx *Mux) Trace(pattern string, handlerFn http.HandlerFunc) {\n\tmx.handle(mTRACE, pattern, handlerFn)\n}\n\n// NotFound sets a custom http.HandlerFunc for routing paths that could\n// not be found. The default 404 handler is `http.NotFound`.\nfunc (mx *Mux) NotFound(handlerFn http.HandlerFunc) {\n\t// Build NotFound handler chain\n\tm := mx\n\thFn := handlerFn\n\tif mx.inline && mx.parent != nil {\n\t\tm = mx.parent\n\t\thFn = Chain(mx.middlewares...).HandlerFunc(hFn).ServeHTTP\n\t}\n\n\t// Update the notFoundHandler from this point forward\n\tm.notFoundHandler = hFn\n\tm.updateSubRoutes(func(subMux *Mux) {\n\t\tif subMux.notFoundHandler == nil {\n\t\t\tsubMux.NotFound(hFn)\n\t\t}\n\t})\n}\n\n// MethodNotAllowed sets a custom http.HandlerFunc for routing paths where the\n// method is unresolved. The default handler returns a 405 with an empty body.\nfunc (mx *Mux) MethodNotAllowed(handlerFn http.HandlerFunc) {\n\t// Build MethodNotAllowed handler chain\n\tm := mx\n\thFn := handlerFn\n\tif mx.inline && mx.parent != nil {\n\t\tm = mx.parent\n\t\thFn = Chain(mx.middlewares...).HandlerFunc(hFn).ServeHTTP\n\t}\n\n\t// Update the methodNotAllowedHandler from this point forward\n\tm.methodNotAllowedHandler = hFn\n\tm.updateSubRoutes(func(subMux *Mux) {\n\t\tif subMux.methodNotAllowedHandler == nil {\n\t\t\tsubMux.MethodNotAllowed(hFn)\n\t\t}\n\t})\n}\n\n// With adds inline middlewares for an endpoint handler.\nfunc (mx *Mux) With(middlewares ...func(http.Handler) http.Handler) Router {\n\t// Similarly as in handle(), we must build the mux handler once additional\n\t// middleware registration isn't allowed for this stack, like now.\n\tif !mx.inline && mx.handler == nil {\n\t\tmx.updateRouteHandler()\n\t}\n\n\t// Copy middlewares from parent inline muxs\n\tvar mws Middlewares\n\tif mx.inline {\n\t\tmws = make(Middlewares, len(mx.middlewares))\n\t\tcopy(mws, mx.middlewares)\n\t}\n\tmws = append(mws, middlewares...)\n\n\tim := &Mux{\n\t\tpool: mx.pool, inline: true, parent: mx, tree: mx.tree, middlewares: mws,\n\t\tnotFoundHandler: mx.notFoundHandler, methodNotAllowedHandler: mx.methodNotAllowedHandler,\n\t}\n\n\treturn im\n}\n\n// Group creates a new inline-Mux with a copy of middleware stack. It's useful\n// for a group of handlers along the same routing path that use an additional\n// set of middlewares. See _examples/.\nfunc (mx *Mux) Group(fn func(r Router)) Router {\n\tim := mx.With()\n\tif fn != nil {\n\t\tfn(im)\n\t}\n\treturn im\n}\n\n// Route creates a new Mux and mounts it along the `pattern` as a subrouter.\n// Effectively, this is a short-hand call to Mount. See _examples/.\nfunc (mx *Mux) Route(pattern string, fn func(r Router)) Router {\n\tif fn == nil {\n\t\tpanic(fmt.Sprintf(\"chi: attempting to Route() a nil subrouter on '%s'\", pattern))\n\t}\n\tsubRouter := NewRouter()\n\tfn(subRouter)\n\tmx.Mount(pattern, subRouter)\n\treturn subRouter\n}\n\n// Mount attaches another http.Handler or chi Router as a subrouter along a routing\n// path. It's very useful to split up a large API as many independent routers and\n// compose them as a single service using Mount. See _examples/.\n//\n// Note that Mount() simply sets a wildcard along the `pattern` that will continue\n// routing at the `handler`, which in most cases is another chi.Router. As a result,\n// if you define two Mount() routes on the exact same pattern the mount will panic.\nfunc (mx *Mux) Mount(pattern string, handler http.Handler) {\n\tif handler == nil {\n\t\tpanic(fmt.Sprintf(\"chi: attempting to Mount() a nil handler on '%s'\", pattern))\n\t}\n\n\t// Provide runtime safety for ensuring a pattern isn't mounted on an existing\n\t// routing pattern.\n\tif mx.tree.findPattern(pattern+\"*\") || mx.tree.findPattern(pattern+\"/*\") {\n\t\tpanic(fmt.Sprintf(\"chi: attempting to Mount() a handler on an existing path, '%s'\", pattern))\n\t}\n\n\t// Assign sub-Router's with the parent not found & method not allowed handler if not specified.\n\tsubr, ok := handler.(*Mux)\n\tif ok && subr.notFoundHandler == nil && mx.notFoundHandler != nil {\n\t\tsubr.NotFound(mx.notFoundHandler)\n\t}\n\tif ok && subr.methodNotAllowedHandler == nil && mx.methodNotAllowedHandler != nil {\n\t\tsubr.MethodNotAllowed(mx.methodNotAllowedHandler)\n\t}\n\n\tmountHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\trctx := RouteContext(r.Context())\n\n\t\t// shift the url path past the previous subrouter\n\t\trctx.RoutePath = mx.nextRoutePath(rctx)\n\n\t\t// reset the wildcard URLParam which connects the subrouter\n\t\tn := len(rctx.URLParams.Keys) - 1\n\t\tif n >= 0 && rctx.URLParams.Keys[n] == \"*\" && len(rctx.URLParams.Values) > n {\n\t\t\trctx.URLParams.Values[n] = \"\"\n\t\t}\n\n\t\thandler.ServeHTTP(w, r)\n\t})\n\n\tif pattern == \"\" || pattern[len(pattern)-1] != '/' {\n\t\tmx.handle(mALL|mSTUB, pattern, mountHandler)\n\t\tmx.handle(mALL|mSTUB, pattern+\"/\", mountHandler)\n\t\tpattern += \"/\"\n\t}\n\n\tmethod := mALL\n\tsubroutes, _ := handler.(Routes)\n\tif subroutes != nil {\n\t\tmethod |= mSTUB\n\t}\n\tn := mx.handle(method, pattern+\"*\", mountHandler)\n\n\tif subroutes != nil {\n\t\tn.subroutes = subroutes\n\t}\n}\n\n// Routes returns a slice of routing information from the tree,\n// useful for traversing available routes of a router.\nfunc (mx *Mux) Routes() []Route {\n\treturn mx.tree.routes()\n}\n\n// Middlewares returns a slice of middleware handler functions.\nfunc (mx *Mux) Middlewares() Middlewares {\n\treturn mx.middlewares\n}\n\n// Match searches the routing tree for a handler that matches the method/path.\n// It's similar to routing a http request, but without executing the handler\n// thereafter.\n//\n// Note: the *Context state is updated during execution, so manage\n// the state carefully or make a NewRouteContext().\nfunc (mx *Mux) Match(rctx *Context, method, path string) bool {\n\treturn mx.Find(rctx, method, path) != \"\"\n}\n\n// Find searches the routing tree for the pattern that matches\n// the method/path.\n//\n// Note: the *Context state is updated during execution, so manage\n// the state carefully or make a NewRouteContext().\nfunc (mx *Mux) Find(rctx *Context, method, path string) string {\n\tm, ok := methodMap[method]\n\tif !ok {\n\t\treturn \"\"\n\t}\n\n\tnode, _, _ := mx.tree.FindRoute(rctx, m, path)\n\tpattern := rctx.routePattern\n\n\tif node != nil {\n\t\tif node.subroutes == nil {\n\t\t\te := node.endpoints[m]\n\t\t\treturn e.pattern\n\t\t}\n\n\t\trctx.RoutePath = mx.nextRoutePath(rctx)\n\t\tsubPattern := node.subroutes.Find(rctx, method, rctx.RoutePath)\n\t\tif subPattern == \"\" {\n\t\t\treturn \"\"\n\t\t}\n\n\t\tpattern = strings.TrimSuffix(pattern, \"/*\")\n\t\tpattern += subPattern\n\t}\n\n\treturn pattern\n}\n\n// NotFoundHandler returns the default Mux 404 responder whenever a route\n// cannot be found.\nfunc (mx *Mux) NotFoundHandler() http.HandlerFunc {\n\tif mx.notFoundHandler != nil {\n\t\treturn mx.notFoundHandler\n\t}\n\treturn http.NotFound\n}\n\n// MethodNotAllowedHandler returns the default Mux 405 responder whenever\n// a method cannot be resolved for a route.\nfunc (mx *Mux) MethodNotAllowedHandler(methodsAllowed ...methodTyp) http.HandlerFunc {\n\tif mx.methodNotAllowedHandler != nil {\n\t\treturn mx.methodNotAllowedHandler\n\t}\n\treturn methodNotAllowedHandler(methodsAllowed...)\n}\n\n// handle registers a http.Handler in the routing tree for a particular http method\n// and routing pattern.\nfunc (mx *Mux) handle(method methodTyp, pattern string, handler http.Handler) *node {\n\tif len(pattern) == 0 || pattern[0] != '/' {\n\t\tpanic(fmt.Sprintf(\"chi: routing pattern must begin with '/' in '%s'\", pattern))\n\t}\n\n\t// Build the computed routing handler for this routing pattern.\n\tif !mx.inline && mx.handler == nil {\n\t\tmx.updateRouteHandler()\n\t}\n\n\t// Build endpoint handler with inline middlewares for the route\n\tvar h http.Handler\n\tif mx.inline {\n\t\tmx.handler = http.HandlerFunc(mx.routeHTTP)\n\t\th = Chain(mx.middlewares...).Handler(handler)\n\t} else {\n\t\th = handler\n\t}\n\n\t// Add the endpoint to the tree and return the node\n\treturn mx.tree.InsertRoute(method, pattern, h)\n}\n\n// routeHTTP routes a http.Request through the Mux routing tree to serve\n// the matching handler for a particular http method.\nfunc (mx *Mux) routeHTTP(w http.ResponseWriter, r *http.Request) {\n\t// Grab the route context object\n\trctx := r.Context().Value(RouteCtxKey).(*Context)\n\n\t// The request routing path\n\troutePath := rctx.RoutePath\n\tif routePath == \"\" {\n\t\tif r.URL.RawPath != \"\" {\n\t\t\troutePath = r.URL.RawPath\n\t\t} else {\n\t\t\troutePath = r.URL.Path\n\t\t}\n\t\tif routePath == \"\" {\n\t\t\troutePath = \"/\"\n\t\t}\n\t}\n\n\t// Check if method is supported by chi\n\tif rctx.RouteMethod == \"\" {\n\t\trctx.RouteMethod = r.Method\n\t}\n\tmethod, ok := methodMap[rctx.RouteMethod]\n\tif !ok {\n\t\tmx.MethodNotAllowedHandler().ServeHTTP(w, r)\n\t\treturn\n\t}\n\n\t// Find the route\n\tif _, _, h := mx.tree.FindRoute(rctx, method, routePath); h != nil {\n\t\tif supportsPathValue {\n\t\t\tsetPathValue(rctx, r)\n\t\t}\n\n\t\th.ServeHTTP(w, r)\n\t\treturn\n\t}\n\tif rctx.methodNotAllowed {\n\t\tmx.MethodNotAllowedHandler(rctx.methodsAllowed...).ServeHTTP(w, r)\n\t} else {\n\t\tmx.NotFoundHandler().ServeHTTP(w, r)\n\t}\n}\n\nfunc (mx *Mux) nextRoutePath(rctx *Context) string {\n\troutePath := \"/\"\n\tnx := len(rctx.routeParams.Keys) - 1 // index of last param in list\n\tif nx >= 0 && rctx.routeParams.Keys[nx] == \"*\" && len(rctx.routeParams.Values) > nx {\n\t\troutePath = \"/\" + rctx.routeParams.Values[nx]\n\t}\n\treturn routePath\n}\n\n// Recursively update data on child routers.\nfunc (mx *Mux) updateSubRoutes(fn func(subMux *Mux)) {\n\tfor _, r := range mx.tree.routes() {\n\t\tsubMux, ok := r.SubRoutes.(*Mux)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tfn(subMux)\n\t}\n}\n\n// updateRouteHandler builds the single mux handler that is a chain of the middleware\n// stack, as defined by calls to Use(), and the tree router (Mux) itself. After this\n// point, no other middlewares can be registered on this Mux's stack. But you can still\n// compose additional middlewares via Group()'s or using a chained middleware handler.\nfunc (mx *Mux) updateRouteHandler() {\n\tmx.handler = chain(mx.middlewares, http.HandlerFunc(mx.routeHTTP))\n}\n\n// methodNotAllowedHandler is a helper function to respond with a 405,\n// method not allowed. It sets the Allow header with the list of allowed\n// methods for the route.\nfunc methodNotAllowedHandler(methodsAllowed ...methodTyp) func(w http.ResponseWriter, r *http.Request) {\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\tfor _, m := range methodsAllowed {\n\t\t\tw.Header().Add(\"Allow\", reverseMethodMap[m])\n\t\t}\n\t\tw.WriteHeader(405)\n\t\tw.Write(nil)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/go-chi/chi/v5/path_value.go",
    "content": "//go:build go1.22 && !tinygo\n// +build go1.22,!tinygo\n\n\npackage chi\n\nimport \"net/http\"\n\n// supportsPathValue is true if the Go version is 1.22 and above.\n//\n// If this is true, `net/http.Request` has methods `SetPathValue` and `PathValue`.\nconst supportsPathValue = true\n\n// setPathValue sets the path values in the Request value\n// based on the provided request context.\nfunc setPathValue(rctx *Context, r *http.Request) {\n\tfor i, key := range rctx.URLParams.Keys {\n\t\tvalue := rctx.URLParams.Values[i]\n\t\tr.SetPathValue(key, value)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/go-chi/chi/v5/path_value_fallback.go",
    "content": "//go:build !go1.22 || tinygo\n// +build !go1.22 tinygo\n\npackage chi\n\nimport \"net/http\"\n\n// supportsPathValue is true if the Go version is 1.22 and above.\n//\n// If this is true, `net/http.Request` has methods `SetPathValue` and `PathValue`.\nconst supportsPathValue = false\n\n// setPathValue sets the path values in the Request value\n// based on the provided request context.\n//\n// setPathValue is only supported in Go 1.22 and above so\n// this is just a blank function so that it compiles.\nfunc setPathValue(rctx *Context, r *http.Request) {\n}\n"
  },
  {
    "path": "vendor/github.com/go-chi/chi/v5/tree.go",
    "content": "package chi\n\n// Radix tree implementation below is a based on the original work by\n// Armon Dadgar in https://github.com/armon/go-radix/blob/master/radix.go\n// (MIT licensed). It's been heavily modified for use as a HTTP routing tree.\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype methodTyp uint\n\nconst (\n\tmSTUB methodTyp = 1 << iota\n\tmCONNECT\n\tmDELETE\n\tmGET\n\tmHEAD\n\tmOPTIONS\n\tmPATCH\n\tmPOST\n\tmPUT\n\tmTRACE\n)\n\nvar mALL = mCONNECT | mDELETE | mGET | mHEAD |\n\tmOPTIONS | mPATCH | mPOST | mPUT | mTRACE\n\nvar methodMap = map[string]methodTyp{\n\thttp.MethodConnect: mCONNECT,\n\thttp.MethodDelete:  mDELETE,\n\thttp.MethodGet:     mGET,\n\thttp.MethodHead:    mHEAD,\n\thttp.MethodOptions: mOPTIONS,\n\thttp.MethodPatch:   mPATCH,\n\thttp.MethodPost:    mPOST,\n\thttp.MethodPut:     mPUT,\n\thttp.MethodTrace:   mTRACE,\n}\n\nvar reverseMethodMap = map[methodTyp]string{\n\tmCONNECT: http.MethodConnect,\n\tmDELETE:  http.MethodDelete,\n\tmGET:     http.MethodGet,\n\tmHEAD:    http.MethodHead,\n\tmOPTIONS: http.MethodOptions,\n\tmPATCH:   http.MethodPatch,\n\tmPOST:    http.MethodPost,\n\tmPUT:     http.MethodPut,\n\tmTRACE:   http.MethodTrace,\n}\n\n// RegisterMethod adds support for custom HTTP method handlers, available\n// via Router#Method and Router#MethodFunc\nfunc RegisterMethod(method string) {\n\tif method == \"\" {\n\t\treturn\n\t}\n\tmethod = strings.ToUpper(method)\n\tif _, ok := methodMap[method]; ok {\n\t\treturn\n\t}\n\tn := len(methodMap)\n\tif n > strconv.IntSize-2 {\n\t\tpanic(fmt.Sprintf(\"chi: max number of methods reached (%d)\", strconv.IntSize))\n\t}\n\tmt := methodTyp(2 << n)\n\tmethodMap[method] = mt\n\tmALL |= mt\n}\n\ntype nodeTyp uint8\n\nconst (\n\tntStatic   nodeTyp = iota // /home\n\tntRegexp                  // /{id:[0-9]+}\n\tntParam                   // /{user}\n\tntCatchAll                // /api/v1/*\n)\n\ntype node struct {\n\t// subroutes on the leaf node\n\tsubroutes Routes\n\n\t// regexp matcher for regexp nodes\n\trex *regexp.Regexp\n\n\t// HTTP handler endpoints on the leaf node\n\tendpoints endpoints\n\n\t// prefix is the common prefix we ignore\n\tprefix string\n\n\t// child nodes should be stored in-order for iteration,\n\t// in groups of the node type.\n\tchildren [ntCatchAll + 1]nodes\n\n\t// first byte of the child prefix\n\ttail byte\n\n\t// node type: static, regexp, param, catchAll\n\ttyp nodeTyp\n\n\t// first byte of the prefix\n\tlabel byte\n}\n\n// endpoints is a mapping of http method constants to handlers\n// for a given route.\ntype endpoints map[methodTyp]*endpoint\n\ntype endpoint struct {\n\t// endpoint handler\n\thandler http.Handler\n\n\t// pattern is the routing pattern for handler nodes\n\tpattern string\n\n\t// parameter keys recorded on handler nodes\n\tparamKeys []string\n}\n\nfunc (s endpoints) Value(method methodTyp) *endpoint {\n\tmh, ok := s[method]\n\tif !ok {\n\t\tmh = &endpoint{}\n\t\ts[method] = mh\n\t}\n\treturn mh\n}\n\nfunc (n *node) InsertRoute(method methodTyp, pattern string, handler http.Handler) *node {\n\tvar parent *node\n\tsearch := pattern\n\n\tfor {\n\t\t// Handle key exhaustion\n\t\tif len(search) == 0 {\n\t\t\t// Insert or update the node's leaf handler\n\t\t\tn.setEndpoint(method, handler, pattern)\n\t\t\treturn n\n\t\t}\n\n\t\t// We're going to be searching for a wild node next,\n\t\t// in this case, we need to get the tail\n\t\tvar label = search[0]\n\t\tvar segTail byte\n\t\tvar segEndIdx int\n\t\tvar segTyp nodeTyp\n\t\tvar segRexpat string\n\t\tif label == '{' || label == '*' {\n\t\t\tsegTyp, _, segRexpat, segTail, _, segEndIdx = patNextSegment(search)\n\t\t}\n\n\t\tvar prefix string\n\t\tif segTyp == ntRegexp {\n\t\t\tprefix = segRexpat\n\t\t}\n\n\t\t// Look for the edge to attach to\n\t\tparent = n\n\t\tn = n.getEdge(segTyp, label, segTail, prefix)\n\n\t\t// No edge, create one\n\t\tif n == nil {\n\t\t\tchild := &node{label: label, tail: segTail, prefix: search}\n\t\t\thn := parent.addChild(child, search)\n\t\t\thn.setEndpoint(method, handler, pattern)\n\n\t\t\treturn hn\n\t\t}\n\n\t\t// Found an edge to match the pattern\n\n\t\tif n.typ > ntStatic {\n\t\t\t// We found a param node, trim the param from the search path and continue.\n\t\t\t// This param/wild pattern segment would already be on the tree from a previous\n\t\t\t// call to addChild when creating a new node.\n\t\t\tsearch = search[segEndIdx:]\n\t\t\tcontinue\n\t\t}\n\n\t\t// Static nodes fall below here.\n\t\t// Determine longest prefix of the search key on match.\n\t\tcommonPrefix := longestPrefix(search, n.prefix)\n\t\tif commonPrefix == len(n.prefix) {\n\t\t\t// the common prefix is as long as the current node's prefix we're attempting to insert.\n\t\t\t// keep the search going.\n\t\t\tsearch = search[commonPrefix:]\n\t\t\tcontinue\n\t\t}\n\n\t\t// Split the node\n\t\tchild := &node{\n\t\t\ttyp:    ntStatic,\n\t\t\tprefix: search[:commonPrefix],\n\t\t}\n\t\tparent.replaceChild(search[0], segTail, child)\n\n\t\t// Restore the existing node\n\t\tn.label = n.prefix[commonPrefix]\n\t\tn.prefix = n.prefix[commonPrefix:]\n\t\tchild.addChild(n, n.prefix)\n\n\t\t// If the new key is a subset, set the method/handler on this node and finish.\n\t\tsearch = search[commonPrefix:]\n\t\tif len(search) == 0 {\n\t\t\tchild.setEndpoint(method, handler, pattern)\n\t\t\treturn child\n\t\t}\n\n\t\t// Create a new edge for the node\n\t\tsubchild := &node{\n\t\t\ttyp:    ntStatic,\n\t\t\tlabel:  search[0],\n\t\t\tprefix: search,\n\t\t}\n\t\thn := child.addChild(subchild, search)\n\t\thn.setEndpoint(method, handler, pattern)\n\t\treturn hn\n\t}\n}\n\n// addChild appends the new `child` node to the tree using the `pattern` as the trie key.\n// For a URL router like chi's, we split the static, param, regexp and wildcard segments\n// into different nodes. In addition, addChild will recursively call itself until every\n// pattern segment is added to the url pattern tree as individual nodes, depending on type.\nfunc (n *node) addChild(child *node, prefix string) *node {\n\tsearch := prefix\n\n\t// handler leaf node added to the tree is the child.\n\t// this may be overridden later down the flow\n\thn := child\n\n\t// Parse next segment\n\tsegTyp, _, segRexpat, segTail, segStartIdx, segEndIdx := patNextSegment(search)\n\n\t// Add child depending on next up segment\n\tswitch segTyp {\n\n\tcase ntStatic:\n\t\t// Search prefix is all static (that is, has no params in path)\n\t\t// noop\n\n\tdefault:\n\t\t// Search prefix contains a param, regexp or wildcard\n\n\t\tif segTyp == ntRegexp {\n\t\t\trex, err := regexp.Compile(segRexpat)\n\t\t\tif err != nil {\n\t\t\t\tpanic(fmt.Sprintf(\"chi: invalid regexp pattern '%s' in route param\", segRexpat))\n\t\t\t}\n\t\t\tchild.prefix = segRexpat\n\t\t\tchild.rex = rex\n\t\t}\n\n\t\tif segStartIdx == 0 {\n\t\t\t// Route starts with a param\n\t\t\tchild.typ = segTyp\n\n\t\t\tif segTyp == ntCatchAll {\n\t\t\t\tsegStartIdx = -1\n\t\t\t} else {\n\t\t\t\tsegStartIdx = segEndIdx\n\t\t\t}\n\t\t\tif segStartIdx < 0 {\n\t\t\t\tsegStartIdx = len(search)\n\t\t\t}\n\t\t\tchild.tail = segTail // for params, we set the tail\n\n\t\t\tif segStartIdx != len(search) {\n\t\t\t\t// add static edge for the remaining part, split the end.\n\t\t\t\t// its not possible to have adjacent param nodes, so its certainly\n\t\t\t\t// going to be a static node next.\n\n\t\t\t\tsearch = search[segStartIdx:] // advance search position\n\n\t\t\t\tnn := &node{\n\t\t\t\t\ttyp:    ntStatic,\n\t\t\t\t\tlabel:  search[0],\n\t\t\t\t\tprefix: search,\n\t\t\t\t}\n\t\t\t\thn = child.addChild(nn, search)\n\t\t\t}\n\n\t\t} else if segStartIdx > 0 {\n\t\t\t// Route has some param\n\n\t\t\t// starts with a static segment\n\t\t\tchild.typ = ntStatic\n\t\t\tchild.prefix = search[:segStartIdx]\n\t\t\tchild.rex = nil\n\n\t\t\t// add the param edge node\n\t\t\tsearch = search[segStartIdx:]\n\n\t\t\tnn := &node{\n\t\t\t\ttyp:   segTyp,\n\t\t\t\tlabel: search[0],\n\t\t\t\ttail:  segTail,\n\t\t\t}\n\t\t\thn = child.addChild(nn, search)\n\n\t\t}\n\t}\n\n\tn.children[child.typ] = append(n.children[child.typ], child)\n\tn.children[child.typ].Sort()\n\treturn hn\n}\n\nfunc (n *node) replaceChild(label, tail byte, child *node) {\n\tfor i := 0; i < len(n.children[child.typ]); i++ {\n\t\tif n.children[child.typ][i].label == label && n.children[child.typ][i].tail == tail {\n\t\t\tn.children[child.typ][i] = child\n\t\t\tn.children[child.typ][i].label = label\n\t\t\tn.children[child.typ][i].tail = tail\n\t\t\treturn\n\t\t}\n\t}\n\tpanic(\"chi: replacing missing child\")\n}\n\nfunc (n *node) getEdge(ntyp nodeTyp, label, tail byte, prefix string) *node {\n\tnds := n.children[ntyp]\n\tfor i := 0; i < len(nds); i++ {\n\t\tif nds[i].label == label && nds[i].tail == tail {\n\t\t\tif ntyp == ntRegexp && nds[i].prefix != prefix {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn nds[i]\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (n *node) setEndpoint(method methodTyp, handler http.Handler, pattern string) {\n\t// Set the handler for the method type on the node\n\tif n.endpoints == nil {\n\t\tn.endpoints = make(endpoints)\n\t}\n\n\tparamKeys := patParamKeys(pattern)\n\n\tif method&mSTUB == mSTUB {\n\t\tn.endpoints.Value(mSTUB).handler = handler\n\t}\n\tif method&mALL == mALL {\n\t\th := n.endpoints.Value(mALL)\n\t\th.handler = handler\n\t\th.pattern = pattern\n\t\th.paramKeys = paramKeys\n\t\tfor _, m := range methodMap {\n\t\t\th := n.endpoints.Value(m)\n\t\t\th.handler = handler\n\t\t\th.pattern = pattern\n\t\t\th.paramKeys = paramKeys\n\t\t}\n\t} else {\n\t\th := n.endpoints.Value(method)\n\t\th.handler = handler\n\t\th.pattern = pattern\n\t\th.paramKeys = paramKeys\n\t}\n}\n\nfunc (n *node) FindRoute(rctx *Context, method methodTyp, path string) (*node, endpoints, http.Handler) {\n\t// Reset the context routing pattern and params\n\trctx.routePattern = \"\"\n\trctx.routeParams.Keys = rctx.routeParams.Keys[:0]\n\trctx.routeParams.Values = rctx.routeParams.Values[:0]\n\n\t// Find the routing handlers for the path\n\trn := n.findRoute(rctx, method, path)\n\tif rn == nil {\n\t\treturn nil, nil, nil\n\t}\n\n\t// Record the routing params in the request lifecycle\n\trctx.URLParams.Keys = append(rctx.URLParams.Keys, rctx.routeParams.Keys...)\n\trctx.URLParams.Values = append(rctx.URLParams.Values, rctx.routeParams.Values...)\n\n\t// Record the routing pattern in the request lifecycle\n\tif rn.endpoints[method].pattern != \"\" {\n\t\trctx.routePattern = rn.endpoints[method].pattern\n\t\trctx.RoutePatterns = append(rctx.RoutePatterns, rctx.routePattern)\n\t}\n\n\treturn rn, rn.endpoints, rn.endpoints[method].handler\n}\n\n// Recursive edge traversal by checking all nodeTyp groups along the way.\n// It's like searching through a multi-dimensional radix trie.\nfunc (n *node) findRoute(rctx *Context, method methodTyp, path string) *node {\n\tnn := n\n\tsearch := path\n\n\tfor t, nds := range nn.children {\n\t\tntyp := nodeTyp(t)\n\t\tif len(nds) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tvar xn *node\n\t\txsearch := search\n\n\t\tvar label byte\n\t\tif search != \"\" {\n\t\t\tlabel = search[0]\n\t\t}\n\n\t\tswitch ntyp {\n\t\tcase ntStatic:\n\t\t\txn = nds.findEdge(label)\n\t\t\tif xn == nil || !strings.HasPrefix(xsearch, xn.prefix) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\txsearch = xsearch[len(xn.prefix):]\n\n\t\tcase ntParam, ntRegexp:\n\t\t\t// short-circuit and return no matching route for empty param values\n\t\t\tif xsearch == \"\" {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// serially loop through each node grouped by the tail delimiter\n\t\t\tfor idx := 0; idx < len(nds); idx++ {\n\t\t\t\txn = nds[idx]\n\n\t\t\t\t// label for param nodes is the delimiter byte\n\t\t\t\tp := strings.IndexByte(xsearch, xn.tail)\n\n\t\t\t\tif p < 0 {\n\t\t\t\t\tif xn.tail == '/' {\n\t\t\t\t\t\tp = len(xsearch)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t} else if ntyp == ntRegexp && p == 0 {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif ntyp == ntRegexp && xn.rex != nil {\n\t\t\t\t\tif !xn.rex.MatchString(xsearch[:p]) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t} else if strings.IndexByte(xsearch[:p], '/') != -1 {\n\t\t\t\t\t// avoid a match across path segments\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tprevlen := len(rctx.routeParams.Values)\n\t\t\t\trctx.routeParams.Values = append(rctx.routeParams.Values, xsearch[:p])\n\t\t\t\txsearch = xsearch[p:]\n\n\t\t\t\tif len(xsearch) == 0 {\n\t\t\t\t\tif xn.isLeaf() {\n\t\t\t\t\t\th := xn.endpoints[method]\n\t\t\t\t\t\tif h != nil && h.handler != nil {\n\t\t\t\t\t\t\trctx.routeParams.Keys = append(rctx.routeParams.Keys, h.paramKeys...)\n\t\t\t\t\t\t\treturn xn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor endpoints := range xn.endpoints {\n\t\t\t\t\t\t\tif endpoints == mALL || endpoints == mSTUB {\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\trctx.methodsAllowed = append(rctx.methodsAllowed, endpoints)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// flag that the routing context found a route, but not a corresponding\n\t\t\t\t\t\t// supported method\n\t\t\t\t\t\trctx.methodNotAllowed = true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// recursively find the next node on this branch\n\t\t\t\tfin := xn.findRoute(rctx, method, xsearch)\n\t\t\t\tif fin != nil {\n\t\t\t\t\treturn fin\n\t\t\t\t}\n\n\t\t\t\t// not found on this branch, reset vars\n\t\t\t\trctx.routeParams.Values = rctx.routeParams.Values[:prevlen]\n\t\t\t\txsearch = search\n\t\t\t}\n\n\t\t\trctx.routeParams.Values = append(rctx.routeParams.Values, \"\")\n\n\t\tdefault:\n\t\t\t// catch-all nodes\n\t\t\trctx.routeParams.Values = append(rctx.routeParams.Values, search)\n\t\t\txn = nds[0]\n\t\t\txsearch = \"\"\n\t\t}\n\n\t\tif xn == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\t// did we find it yet?\n\t\tif len(xsearch) == 0 {\n\t\t\tif xn.isLeaf() {\n\t\t\t\th := xn.endpoints[method]\n\t\t\t\tif h != nil && h.handler != nil {\n\t\t\t\t\trctx.routeParams.Keys = append(rctx.routeParams.Keys, h.paramKeys...)\n\t\t\t\t\treturn xn\n\t\t\t\t}\n\n\t\t\t\tfor endpoints := range xn.endpoints {\n\t\t\t\t\tif endpoints == mALL || endpoints == mSTUB {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\trctx.methodsAllowed = append(rctx.methodsAllowed, endpoints)\n\t\t\t\t}\n\n\t\t\t\t// flag that the routing context found a route, but not a corresponding\n\t\t\t\t// supported method\n\t\t\t\trctx.methodNotAllowed = true\n\t\t\t}\n\t\t}\n\n\t\t// recursively find the next node..\n\t\tfin := xn.findRoute(rctx, method, xsearch)\n\t\tif fin != nil {\n\t\t\treturn fin\n\t\t}\n\n\t\t// Did not find final handler, let's remove the param here if it was set\n\t\tif xn.typ > ntStatic {\n\t\t\tif len(rctx.routeParams.Values) > 0 {\n\t\t\t\trctx.routeParams.Values = rctx.routeParams.Values[:len(rctx.routeParams.Values)-1]\n\t\t\t}\n\t\t}\n\n\t}\n\n\treturn nil\n}\n\nfunc (n *node) findEdge(ntyp nodeTyp, label byte) *node {\n\tnds := n.children[ntyp]\n\tnum := len(nds)\n\tidx := 0\n\n\tswitch ntyp {\n\tcase ntStatic, ntParam, ntRegexp:\n\t\ti, j := 0, num-1\n\t\tfor i <= j {\n\t\t\tidx = i + (j-i)/2\n\t\t\tif label > nds[idx].label {\n\t\t\t\ti = idx + 1\n\t\t\t} else if label < nds[idx].label {\n\t\t\t\tj = idx - 1\n\t\t\t} else {\n\t\t\t\ti = num // breaks cond\n\t\t\t}\n\t\t}\n\t\tif nds[idx].label != label {\n\t\t\treturn nil\n\t\t}\n\t\treturn nds[idx]\n\n\tdefault: // catch all\n\t\treturn nds[idx]\n\t}\n}\n\nfunc (n *node) isLeaf() bool {\n\treturn n.endpoints != nil\n}\n\nfunc (n *node) findPattern(pattern string) bool {\n\tnn := n\n\tfor _, nds := range nn.children {\n\t\tif len(nds) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tn = nn.findEdge(nds[0].typ, pattern[0])\n\t\tif n == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tvar idx int\n\t\tvar xpattern string\n\n\t\tswitch n.typ {\n\t\tcase ntStatic:\n\t\t\tidx = longestPrefix(pattern, n.prefix)\n\t\t\tif idx < len(n.prefix) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\tcase ntParam, ntRegexp:\n\t\t\tidx = strings.IndexByte(pattern, '}') + 1\n\n\t\tcase ntCatchAll:\n\t\t\tidx = longestPrefix(pattern, \"*\")\n\n\t\tdefault:\n\t\t\tpanic(\"chi: unknown node type\")\n\t\t}\n\n\t\txpattern = pattern[idx:]\n\t\tif len(xpattern) == 0 {\n\t\t\treturn true\n\t\t}\n\n\t\treturn n.findPattern(xpattern)\n\t}\n\treturn false\n}\n\nfunc (n *node) routes() []Route {\n\trts := []Route{}\n\n\tn.walk(func(eps endpoints, subroutes Routes) bool {\n\t\tif eps[mSTUB] != nil && eps[mSTUB].handler != nil && subroutes == nil {\n\t\t\treturn false\n\t\t}\n\n\t\t// Group methodHandlers by unique patterns\n\t\tpats := make(map[string]endpoints)\n\n\t\tfor mt, h := range eps {\n\t\t\tif h.pattern == \"\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tp, ok := pats[h.pattern]\n\t\t\tif !ok {\n\t\t\t\tp = endpoints{}\n\t\t\t\tpats[h.pattern] = p\n\t\t\t}\n\t\t\tp[mt] = h\n\t\t}\n\n\t\tfor p, mh := range pats {\n\t\t\ths := make(map[string]http.Handler)\n\t\t\tif mh[mALL] != nil && mh[mALL].handler != nil {\n\t\t\t\ths[\"*\"] = mh[mALL].handler\n\t\t\t}\n\n\t\t\tfor mt, h := range mh {\n\t\t\t\tif h.handler == nil {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tm := methodTypString(mt)\n\t\t\t\tif m == \"\" {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\ths[m] = h.handler\n\t\t\t}\n\n\t\t\trt := Route{subroutes, hs, p}\n\t\t\trts = append(rts, rt)\n\t\t}\n\n\t\treturn false\n\t})\n\n\treturn rts\n}\n\nfunc (n *node) walk(fn func(eps endpoints, subroutes Routes) bool) bool {\n\t// Visit the leaf values if any\n\tif (n.endpoints != nil || n.subroutes != nil) && fn(n.endpoints, n.subroutes) {\n\t\treturn true\n\t}\n\n\t// Recurse on the children\n\tfor _, ns := range n.children {\n\t\tfor _, cn := range ns {\n\t\t\tif cn.walk(fn) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\n// patNextSegment returns the next segment details from a pattern:\n// node type, param key, regexp string, param tail byte, param starting index, param ending index\nfunc patNextSegment(pattern string) (nodeTyp, string, string, byte, int, int) {\n\tps := strings.Index(pattern, \"{\")\n\tws := strings.Index(pattern, \"*\")\n\n\tif ps < 0 && ws < 0 {\n\t\treturn ntStatic, \"\", \"\", 0, 0, len(pattern) // we return the entire thing\n\t}\n\n\t// Sanity check\n\tif ps >= 0 && ws >= 0 && ws < ps {\n\t\tpanic(\"chi: wildcard '*' must be the last pattern in a route, otherwise use a '{param}'\")\n\t}\n\n\tvar tail byte = '/' // Default endpoint tail to / byte\n\n\tif ps >= 0 {\n\t\t// Param/Regexp pattern is next\n\t\tnt := ntParam\n\n\t\t// Read to closing } taking into account opens and closes in curl count (cc)\n\t\tcc := 0\n\t\tpe := ps\n\t\tfor i, c := range pattern[ps:] {\n\t\t\tif c == '{' {\n\t\t\t\tcc++\n\t\t\t} else if c == '}' {\n\t\t\t\tcc--\n\t\t\t\tif cc == 0 {\n\t\t\t\t\tpe = ps + i\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif pe == ps {\n\t\t\tpanic(\"chi: route param closing delimiter '}' is missing\")\n\t\t}\n\n\t\tkey := pattern[ps+1 : pe]\n\t\tpe++ // set end to next position\n\n\t\tif pe < len(pattern) {\n\t\t\ttail = pattern[pe]\n\t\t}\n\n\t\tkey, rexpat, isRegexp := strings.Cut(key, \":\")\n\t\tif isRegexp {\n\t\t\tnt = ntRegexp\n\t\t}\n\n\t\tif len(rexpat) > 0 {\n\t\t\tif rexpat[0] != '^' {\n\t\t\t\trexpat = \"^\" + rexpat\n\t\t\t}\n\t\t\tif rexpat[len(rexpat)-1] != '$' {\n\t\t\t\trexpat += \"$\"\n\t\t\t}\n\t\t}\n\n\t\treturn nt, key, rexpat, tail, ps, pe\n\t}\n\n\t// Wildcard pattern as finale\n\tif ws < len(pattern)-1 {\n\t\tpanic(\"chi: wildcard '*' must be the last value in a route. trim trailing text or use a '{param}' instead\")\n\t}\n\treturn ntCatchAll, \"*\", \"\", 0, ws, len(pattern)\n}\n\nfunc patParamKeys(pattern string) []string {\n\tpat := pattern\n\tparamKeys := []string{}\n\tfor {\n\t\tptyp, paramKey, _, _, _, e := patNextSegment(pat)\n\t\tif ptyp == ntStatic {\n\t\t\treturn paramKeys\n\t\t}\n\t\tfor i := 0; i < len(paramKeys); i++ {\n\t\t\tif paramKeys[i] == paramKey {\n\t\t\t\tpanic(fmt.Sprintf(\"chi: routing pattern '%s' contains duplicate param key, '%s'\", pattern, paramKey))\n\t\t\t}\n\t\t}\n\t\tparamKeys = append(paramKeys, paramKey)\n\t\tpat = pat[e:]\n\t}\n}\n\n// longestPrefix finds the length of the shared prefix\n// of two strings\nfunc longestPrefix(k1, k2 string) int {\n\tmax := len(k1)\n\tif l := len(k2); l < max {\n\t\tmax = l\n\t}\n\tvar i int\n\tfor i = 0; i < max; i++ {\n\t\tif k1[i] != k2[i] {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn i\n}\n\nfunc methodTypString(method methodTyp) string {\n\tfor s, t := range methodMap {\n\t\tif method == t {\n\t\t\treturn s\n\t\t}\n\t}\n\treturn \"\"\n}\n\ntype nodes []*node\n\n// Sort the list of nodes by label\nfunc (ns nodes) Sort()              { sort.Sort(ns); ns.tailSort() }\nfunc (ns nodes) Len() int           { return len(ns) }\nfunc (ns nodes) Swap(i, j int)      { ns[i], ns[j] = ns[j], ns[i] }\nfunc (ns nodes) Less(i, j int) bool { return ns[i].label < ns[j].label }\n\n// tailSort pushes nodes with '/' as the tail to the end of the list for param nodes.\n// The list order determines the traversal order.\nfunc (ns nodes) tailSort() {\n\tfor i := len(ns) - 1; i >= 0; i-- {\n\t\tif ns[i].typ > ntStatic && ns[i].tail == '/' {\n\t\t\tns.Swap(i, len(ns)-1)\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (ns nodes) findEdge(label byte) *node {\n\tnum := len(ns)\n\tidx := 0\n\ti, j := 0, num-1\n\tfor i <= j {\n\t\tidx = i + (j-i)/2\n\t\tif label > ns[idx].label {\n\t\t\ti = idx + 1\n\t\t} else if label < ns[idx].label {\n\t\t\tj = idx - 1\n\t\t} else {\n\t\t\ti = num // breaks cond\n\t\t}\n\t}\n\tif ns[idx].label != label {\n\t\treturn nil\n\t}\n\treturn ns[idx]\n}\n\n// Route describes the details of a routing handler.\n// Handlers map key is an HTTP method\ntype Route struct {\n\tSubRoutes Routes\n\tHandlers  map[string]http.Handler\n\tPattern   string\n}\n\n// WalkFunc is the type of the function called for each method and route visited by Walk.\ntype WalkFunc func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error\n\n// Walk walks any router tree that implements Routes interface.\nfunc Walk(r Routes, walkFn WalkFunc) error {\n\treturn walk(r, walkFn, \"\")\n}\n\nfunc walk(r Routes, walkFn WalkFunc, parentRoute string, parentMw ...func(http.Handler) http.Handler) error {\n\tfor _, route := range r.Routes() {\n\t\tmws := make([]func(http.Handler) http.Handler, len(parentMw))\n\t\tcopy(mws, parentMw)\n\t\tmws = append(mws, r.Middlewares()...)\n\n\t\tif route.SubRoutes != nil {\n\t\t\tif err := walk(route.SubRoutes, walkFn, parentRoute+route.Pattern, mws...); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tfor method, handler := range route.Handlers {\n\t\t\tif method == \"*\" {\n\t\t\t\t// Ignore a \"catchAll\" method, since we pass down all the specific methods for each route.\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tfullRoute := parentRoute + route.Pattern\n\t\t\tfullRoute = strings.Replace(fullRoute, \"/*/\", \"/\", -1)\n\n\t\t\tif chain, ok := handler.(*ChainHandler); ok {\n\t\t\t\tif err := walkFn(method, fullRoute, chain.Endpoint, append(mws, chain.Middlewares...)...); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif err := walkFn(method, fullRoute, handler, mws...); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/go-chi/cors/LICENSE",
    "content": "Copyright (c) 2014 Olivier Poitrey <rs@dailymotion.com>\nCopyright (c) 2016-Present https://github.com/go-chi authors\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject 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, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/go-chi/cors/README.md",
    "content": "# CORS net/http middleware\n\n[go-chi/cors](https://github.com/go-chi/cors) is a fork of [github.com/rs/cors](https://github.com/rs/cors) that\nprovides a `net/http` compatible middleware for performing preflight CORS checks on the server side. These headers\nare required for using the browser native [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).\n\nThis middleware is designed to be used as a top-level middleware on the [chi](https://github.com/go-chi/chi) router.\nApplying with within a `r.Group()` or using `With()` will not work without routes matching `OPTIONS` added.\n\n## Usage\n\n```go\nfunc main() {\n  r := chi.NewRouter()\n\n  // Basic CORS\n  // for more ideas, see: https://developer.github.com/v3/#cross-origin-resource-sharing\n  r.Use(cors.Handler(cors.Options{\n    // AllowedOrigins:   []string{\"https://foo.com\"}, // Use this to allow specific origin hosts\n    AllowedOrigins:   []string{\"https://*\", \"http://*\"},\n    // AllowOriginFunc:  func(r *http.Request, origin string) bool { return true },\n    AllowedMethods:   []string{\"GET\", \"POST\", \"PUT\", \"DELETE\", \"OPTIONS\"},\n    AllowedHeaders:   []string{\"Accept\", \"Authorization\", \"Content-Type\", \"X-CSRF-Token\"},\n    ExposedHeaders:   []string{\"Link\"},\n    AllowCredentials: false,\n    MaxAge:           300, // Maximum value not ignored by any of major browsers\n  }))\n\n  r.Get(\"/\", func(w http.ResponseWriter, r *http.Request) {\n    w.Write([]byte(\"welcome\"))\n  })\n\n  http.ListenAndServe(\":3000\", r)\n}\n```\n\n## Credits\n\nAll credit for the original work of this middleware goes out to [github.com/rs](github.com/rs).\n"
  },
  {
    "path": "vendor/github.com/go-chi/cors/cors.go",
    "content": "// cors package is net/http handler to handle CORS related requests\n// as defined by http://www.w3.org/TR/cors/\n//\n// You can configure it by passing an option struct to cors.New:\n//\n//     c := cors.New(cors.Options{\n//         AllowedOrigins: []string{\"foo.com\"},\n//         AllowedMethods: []string{\"GET\", \"POST\", \"DELETE\"},\n//         AllowCredentials: true,\n//     })\n//\n// Then insert the handler in the chain:\n//\n//     handler = c.Handler(handler)\n//\n// See Options documentation for more options.\n//\n// The resulting handler is a standard net/http handler.\npackage cors\n\nimport (\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Options is a configuration container to setup the CORS middleware.\ntype Options struct {\n\t// AllowedOrigins is a list of origins a cross-domain request can be executed from.\n\t// If the special \"*\" value is present in the list, all origins will be allowed.\n\t// An origin may contain a wildcard (*) to replace 0 or more characters\n\t// (i.e.: http://*.domain.com). Usage of wildcards implies a small performance penalty.\n\t// Only one wildcard can be used per origin.\n\t// Default value is [\"*\"]\n\tAllowedOrigins []string\n\n\t// AllowOriginFunc is a custom function to validate the origin. It takes the origin\n\t// as argument and returns true if allowed or false otherwise. If this option is\n\t// set, the content of AllowedOrigins is ignored.\n\tAllowOriginFunc func(r *http.Request, origin string) bool\n\n\t// AllowedMethods is a list of methods the client is allowed to use with\n\t// cross-domain requests. Default value is simple methods (HEAD, GET and POST).\n\tAllowedMethods []string\n\n\t// AllowedHeaders is list of non simple headers the client is allowed to use with\n\t// cross-domain requests.\n\t// If the special \"*\" value is present in the list, all headers will be allowed.\n\t// Default value is [] but \"Origin\" is always appended to the list.\n\tAllowedHeaders []string\n\n\t// ExposedHeaders indicates which headers are safe to expose to the API of a CORS\n\t// API specification\n\tExposedHeaders []string\n\n\t// AllowCredentials indicates whether the request can include user credentials like\n\t// cookies, HTTP authentication or client side SSL certificates.\n\tAllowCredentials bool\n\n\t// MaxAge indicates how long (in seconds) the results of a preflight request\n\t// can be cached\n\tMaxAge int\n\n\t// OptionsPassthrough instructs preflight to let other potential next handlers to\n\t// process the OPTIONS method. Turn this on if your application handles OPTIONS.\n\tOptionsPassthrough bool\n\n\t// Debugging flag adds additional output to debug server side CORS issues\n\tDebug bool\n}\n\n// Logger generic interface for logger\ntype Logger interface {\n\tPrintf(string, ...interface{})\n}\n\n// Cors http handler\ntype Cors struct {\n\t// Debug logger\n\tLog Logger\n\n\t// Normalized list of plain allowed origins\n\tallowedOrigins []string\n\n\t// List of allowed origins containing wildcards\n\tallowedWOrigins []wildcard\n\n\t// Optional origin validator function\n\tallowOriginFunc func(r *http.Request, origin string) bool\n\n\t// Normalized list of allowed headers\n\tallowedHeaders []string\n\n\t// Normalized list of allowed methods\n\tallowedMethods []string\n\n\t// Normalized list of exposed headers\n\texposedHeaders []string\n\tmaxAge         int\n\n\t// Set to true when allowed origins contains a \"*\"\n\tallowedOriginsAll bool\n\n\t// Set to true when allowed headers contains a \"*\"\n\tallowedHeadersAll bool\n\n\tallowCredentials  bool\n\toptionPassthrough bool\n}\n\n// New creates a new Cors handler with the provided options.\nfunc New(options Options) *Cors {\n\tc := &Cors{\n\t\texposedHeaders:    convert(options.ExposedHeaders, http.CanonicalHeaderKey),\n\t\tallowOriginFunc:   options.AllowOriginFunc,\n\t\tallowCredentials:  options.AllowCredentials,\n\t\tmaxAge:            options.MaxAge,\n\t\toptionPassthrough: options.OptionsPassthrough,\n\t}\n\tif options.Debug && c.Log == nil {\n\t\tc.Log = log.New(os.Stdout, \"[cors] \", log.LstdFlags)\n\t}\n\n\t// Normalize options\n\t// Note: for origins and methods matching, the spec requires a case-sensitive matching.\n\t// As it may error prone, we chose to ignore the spec here.\n\n\t// Allowed Origins\n\tif len(options.AllowedOrigins) == 0 {\n\t\tif options.AllowOriginFunc == nil {\n\t\t\t// Default is all origins\n\t\t\tc.allowedOriginsAll = true\n\t\t}\n\t} else {\n\t\tc.allowedOrigins = []string{}\n\t\tc.allowedWOrigins = []wildcard{}\n\t\tfor _, origin := range options.AllowedOrigins {\n\t\t\t// Normalize\n\t\t\torigin = strings.ToLower(origin)\n\t\t\tif origin == \"*\" {\n\t\t\t\t// If \"*\" is present in the list, turn the whole list into a match all\n\t\t\t\tc.allowedOriginsAll = true\n\t\t\t\tc.allowedOrigins = nil\n\t\t\t\tc.allowedWOrigins = nil\n\t\t\t\tbreak\n\t\t\t} else if i := strings.IndexByte(origin, '*'); i >= 0 {\n\t\t\t\t// Split the origin in two: start and end string without the *\n\t\t\t\tw := wildcard{origin[0:i], origin[i+1:]}\n\t\t\t\tc.allowedWOrigins = append(c.allowedWOrigins, w)\n\t\t\t} else {\n\t\t\t\tc.allowedOrigins = append(c.allowedOrigins, origin)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Allowed Headers\n\tif len(options.AllowedHeaders) == 0 {\n\t\t// Use sensible defaults\n\t\tc.allowedHeaders = []string{\"Origin\", \"Accept\", \"Content-Type\"}\n\t} else {\n\t\t// Origin is always appended as some browsers will always request for this header at preflight\n\t\tc.allowedHeaders = convert(append(options.AllowedHeaders, \"Origin\"), http.CanonicalHeaderKey)\n\t\tfor _, h := range options.AllowedHeaders {\n\t\t\tif h == \"*\" {\n\t\t\t\tc.allowedHeadersAll = true\n\t\t\t\tc.allowedHeaders = nil\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\t// Allowed Methods\n\tif len(options.AllowedMethods) == 0 {\n\t\t// Default is spec's \"simple\" methods\n\t\tc.allowedMethods = []string{http.MethodGet, http.MethodPost, http.MethodHead}\n\t} else {\n\t\tc.allowedMethods = convert(options.AllowedMethods, strings.ToUpper)\n\t}\n\n\treturn c\n}\n\n// Handler creates a new Cors handler with passed options.\nfunc Handler(options Options) func(next http.Handler) http.Handler {\n\tc := New(options)\n\treturn c.Handler\n}\n\n// AllowAll create a new Cors handler with permissive configuration allowing all\n// origins with all standard methods with any header and credentials.\nfunc AllowAll() *Cors {\n\treturn New(Options{\n\t\tAllowedOrigins: []string{\"*\"},\n\t\tAllowedMethods: []string{\n\t\t\thttp.MethodHead,\n\t\t\thttp.MethodGet,\n\t\t\thttp.MethodPost,\n\t\t\thttp.MethodPut,\n\t\t\thttp.MethodPatch,\n\t\t\thttp.MethodDelete,\n\t\t},\n\t\tAllowedHeaders:   []string{\"*\"},\n\t\tAllowCredentials: false,\n\t})\n}\n\n// Handler apply the CORS specification on the request, and add relevant CORS headers\n// as necessary.\nfunc (c *Cors) Handler(next http.Handler) http.Handler {\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tif r.Method == http.MethodOptions && r.Header.Get(\"Access-Control-Request-Method\") != \"\" {\n\t\t\tc.logf(\"Handler: Preflight request\")\n\t\t\tc.handlePreflight(w, r)\n\t\t\t// Preflight requests are standalone and should stop the chain as some other\n\t\t\t// middleware may not handle OPTIONS requests correctly. One typical example\n\t\t\t// is authentication middleware ; OPTIONS requests won't carry authentication\n\t\t\t// headers (see #1)\n\t\t\tif c.optionPassthrough {\n\t\t\t\tnext.ServeHTTP(w, r)\n\t\t\t} else {\n\t\t\t\tw.WriteHeader(http.StatusOK)\n\t\t\t}\n\t\t} else {\n\t\t\tc.logf(\"Handler: Actual request\")\n\t\t\tc.handleActualRequest(w, r)\n\t\t\tnext.ServeHTTP(w, r)\n\t\t}\n\t})\n}\n\n// handlePreflight handles pre-flight CORS requests\nfunc (c *Cors) handlePreflight(w http.ResponseWriter, r *http.Request) {\n\theaders := w.Header()\n\torigin := r.Header.Get(\"Origin\")\n\n\tif r.Method != http.MethodOptions {\n\t\tc.logf(\"Preflight aborted: %s!=OPTIONS\", r.Method)\n\t\treturn\n\t}\n\t// Always set Vary headers\n\t// see https://github.com/rs/cors/issues/10,\n\t//     https://github.com/rs/cors/commit/dbdca4d95feaa7511a46e6f1efb3b3aa505bc43f#commitcomment-12352001\n\theaders.Add(\"Vary\", \"Origin\")\n\theaders.Add(\"Vary\", \"Access-Control-Request-Method\")\n\theaders.Add(\"Vary\", \"Access-Control-Request-Headers\")\n\n\tif origin == \"\" {\n\t\tc.logf(\"Preflight aborted: empty origin\")\n\t\treturn\n\t}\n\tif !c.isOriginAllowed(r, origin) {\n\t\tc.logf(\"Preflight aborted: origin '%s' not allowed\", origin)\n\t\treturn\n\t}\n\n\treqMethod := r.Header.Get(\"Access-Control-Request-Method\")\n\tif !c.isMethodAllowed(reqMethod) {\n\t\tc.logf(\"Preflight aborted: method '%s' not allowed\", reqMethod)\n\t\treturn\n\t}\n\treqHeaders := parseHeaderList(r.Header.Get(\"Access-Control-Request-Headers\"))\n\tif !c.areHeadersAllowed(reqHeaders) {\n\t\tc.logf(\"Preflight aborted: headers '%v' not allowed\", reqHeaders)\n\t\treturn\n\t}\n\tif c.allowedOriginsAll {\n\t\theaders.Set(\"Access-Control-Allow-Origin\", \"*\")\n\t} else {\n\t\theaders.Set(\"Access-Control-Allow-Origin\", origin)\n\t}\n\t// Spec says: Since the list of methods can be unbounded, simply returning the method indicated\n\t// by Access-Control-Request-Method (if supported) can be enough\n\theaders.Set(\"Access-Control-Allow-Methods\", strings.ToUpper(reqMethod))\n\tif len(reqHeaders) > 0 {\n\n\t\t// Spec says: Since the list of headers can be unbounded, simply returning supported headers\n\t\t// from Access-Control-Request-Headers can be enough\n\t\theaders.Set(\"Access-Control-Allow-Headers\", strings.Join(reqHeaders, \", \"))\n\t}\n\tif c.allowCredentials {\n\t\theaders.Set(\"Access-Control-Allow-Credentials\", \"true\")\n\t}\n\tif c.maxAge > 0 {\n\t\theaders.Set(\"Access-Control-Max-Age\", strconv.Itoa(c.maxAge))\n\t}\n\tc.logf(\"Preflight response headers: %v\", headers)\n}\n\n// handleActualRequest handles simple cross-origin requests, actual request or redirects\nfunc (c *Cors) handleActualRequest(w http.ResponseWriter, r *http.Request) {\n\theaders := w.Header()\n\torigin := r.Header.Get(\"Origin\")\n\n\t// Always set Vary, see https://github.com/rs/cors/issues/10\n\theaders.Add(\"Vary\", \"Origin\")\n\tif origin == \"\" {\n\t\tc.logf(\"Actual request no headers added: missing origin\")\n\t\treturn\n\t}\n\tif !c.isOriginAllowed(r, origin) {\n\t\tc.logf(\"Actual request no headers added: origin '%s' not allowed\", origin)\n\t\treturn\n\t}\n\n\t// Note that spec does define a way to specifically disallow a simple method like GET or\n\t// POST. Access-Control-Allow-Methods is only used for pre-flight requests and the\n\t// spec doesn't instruct to check the allowed methods for simple cross-origin requests.\n\t// We think it's a nice feature to be able to have control on those methods though.\n\tif !c.isMethodAllowed(r.Method) {\n\t\tc.logf(\"Actual request no headers added: method '%s' not allowed\", r.Method)\n\n\t\treturn\n\t}\n\tif c.allowedOriginsAll {\n\t\theaders.Set(\"Access-Control-Allow-Origin\", \"*\")\n\t} else {\n\t\theaders.Set(\"Access-Control-Allow-Origin\", origin)\n\t}\n\tif len(c.exposedHeaders) > 0 {\n\t\theaders.Set(\"Access-Control-Expose-Headers\", strings.Join(c.exposedHeaders, \", \"))\n\t}\n\tif c.allowCredentials {\n\t\theaders.Set(\"Access-Control-Allow-Credentials\", \"true\")\n\t}\n\tc.logf(\"Actual response added headers: %v\", headers)\n}\n\n// convenience method. checks if a logger is set.\nfunc (c *Cors) logf(format string, a ...interface{}) {\n\tif c.Log != nil {\n\t\tc.Log.Printf(format, a...)\n\t}\n}\n\n// isOriginAllowed checks if a given origin is allowed to perform cross-domain requests\n// on the endpoint\nfunc (c *Cors) isOriginAllowed(r *http.Request, origin string) bool {\n\tif c.allowOriginFunc != nil {\n\t\treturn c.allowOriginFunc(r, origin)\n\t}\n\tif c.allowedOriginsAll {\n\t\treturn true\n\t}\n\torigin = strings.ToLower(origin)\n\tfor _, o := range c.allowedOrigins {\n\t\tif o == origin {\n\t\t\treturn true\n\t\t}\n\t}\n\tfor _, w := range c.allowedWOrigins {\n\t\tif w.match(origin) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// isMethodAllowed checks if a given method can be used as part of a cross-domain request\n// on the endpoint\nfunc (c *Cors) isMethodAllowed(method string) bool {\n\tif len(c.allowedMethods) == 0 {\n\t\t// If no method allowed, always return false, even for preflight request\n\t\treturn false\n\t}\n\tmethod = strings.ToUpper(method)\n\tif method == http.MethodOptions {\n\t\t// Always allow preflight requests\n\t\treturn true\n\t}\n\tfor _, m := range c.allowedMethods {\n\t\tif m == method {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// areHeadersAllowed checks if a given list of headers are allowed to used within\n// a cross-domain request.\nfunc (c *Cors) areHeadersAllowed(requestedHeaders []string) bool {\n\tif c.allowedHeadersAll || len(requestedHeaders) == 0 {\n\t\treturn true\n\t}\n\tfor _, header := range requestedHeaders {\n\t\theader = http.CanonicalHeaderKey(header)\n\t\tfound := false\n\t\tfor _, h := range c.allowedHeaders {\n\t\t\tif h == header {\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/go-chi/cors/utils.go",
    "content": "package cors\n\nimport \"strings\"\n\nconst toLower = 'a' - 'A'\n\ntype converter func(string) string\n\ntype wildcard struct {\n\tprefix string\n\tsuffix string\n}\n\nfunc (w wildcard) match(s string) bool {\n\treturn len(s) >= len(w.prefix+w.suffix) && strings.HasPrefix(s, w.prefix) && strings.HasSuffix(s, w.suffix)\n}\n\n// convert converts a list of string using the passed converter function\nfunc convert(s []string, c converter) []string {\n\tout := []string{}\n\tfor _, i := range s {\n\t\tout = append(out, c(i))\n\t}\n\treturn out\n}\n\n// parseHeaderList tokenize + normalize a string containing a list of headers\nfunc parseHeaderList(headerList string) []string {\n\tl := len(headerList)\n\th := make([]byte, 0, l)\n\tupper := true\n\t// Estimate the number headers in order to allocate the right splice size\n\tt := 0\n\tfor i := 0; i < l; i++ {\n\t\tif headerList[i] == ',' {\n\t\t\tt++\n\t\t}\n\t}\n\theaders := make([]string, 0, t)\n\tfor i := 0; i < l; i++ {\n\t\tb := headerList[i]\n\t\tif b >= 'a' && b <= 'z' {\n\t\t\tif upper {\n\t\t\t\th = append(h, b-toLower)\n\t\t\t} else {\n\t\t\t\th = append(h, b)\n\t\t\t}\n\t\t} else if b >= 'A' && b <= 'Z' {\n\t\t\tif !upper {\n\t\t\t\th = append(h, b+toLower)\n\t\t\t} else {\n\t\t\t\th = append(h, b)\n\t\t\t}\n\t\t} else if b == '-' || b == '_' || b == '.' || (b >= '0' && b <= '9') {\n\t\t\th = append(h, b)\n\t\t}\n\n\t\tif b == ' ' || b == ',' || i == l-1 {\n\t\t\tif len(h) > 0 {\n\t\t\t\t// Flush the found header\n\t\t\t\theaders = append(headers, string(h))\n\t\t\t\th = h[:0]\n\t\t\t\tupper = true\n\t\t\t}\n\t\t} else {\n\t\t\tupper = b == '-'\n\t\t}\n\t}\n\treturn headers\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/.gitignore",
    "content": "jose-util/jose-util\njose-util.t.err"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/.golangci.yml",
    "content": "# https://github.com/golangci/golangci-lint\n\nrun:\n  skip-files:\n    - doc_test.go\n  modules-download-mode: readonly\n\nlinters:\n  enable-all: true\n  disable:\n    - gochecknoglobals\n    - goconst\n    - lll\n    - maligned\n    - nakedret\n    - scopelint\n    - unparam\n    - funlen # added in 1.18 (requires go-jose changes before it can be enabled)\n\nlinters-settings:\n  gocyclo:\n    min-complexity: 35\n\nissues:\n  exclude-rules:\n    - text: \"don't use ALL_CAPS in Go names\"\n      linters:\n        - golint\n    - text: \"hardcoded credentials\"\n      linters:\n        - gosec\n    - text: \"weak cryptographic primitive\"\n      linters:\n        - gosec\n    - path: json/\n      linters:\n        - dupl\n        - errcheck\n        - gocritic\n        - gocyclo\n        - golint\n        - govet\n        - ineffassign\n        - staticcheck\n        - structcheck\n        - stylecheck\n        - unused\n    - path: _test\\.go\n      linters:\n        - scopelint\n    - path: jwk.go\n      linters:\n        - gocyclo\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/.travis.yml",
    "content": "language: go\n\nmatrix:\n  fast_finish: true\n  allow_failures:\n    - go: tip\n\ngo:\n  - \"1.13.x\"\n  - \"1.14.x\"\n  - tip\n\nbefore_script:\n  - export PATH=$HOME/.local/bin:$PATH\n\nbefore_install:\n  - go get -u github.com/mattn/goveralls github.com/wadey/gocovmerge\n  - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.18.0\n  - pip install cram --user\n\nscript:\n  - go test -v -covermode=count -coverprofile=profile.cov .\n  - go test -v -covermode=count -coverprofile=cryptosigner/profile.cov ./cryptosigner\n  - go test -v -covermode=count -coverprofile=cipher/profile.cov ./cipher\n  - go test -v -covermode=count -coverprofile=jwt/profile.cov ./jwt\n  - go test -v ./json  # no coverage for forked encoding/json package\n  - golangci-lint run\n  - cd jose-util && go build && PATH=$PWD:$PATH cram -v jose-util.t # cram tests jose-util\n  - cd ..\n\nafter_success:\n  - gocovmerge *.cov */*.cov > merged.coverprofile\n  - goveralls -coverprofile merged.coverprofile -service=travis-ci\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md",
    "content": "# Contributing\n\nIf you would like to contribute code to go-jose you can do so through GitHub by\nforking the repository and sending a pull request.\n\nWhen submitting code, please make every effort to follow existing conventions\nand style in order to keep the code as readable as possible. Please also make\nsure all tests pass by running `go test`, and format your code with `go fmt`.\nWe also recommend using `golint` and `errcheck`.\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/README.md",
    "content": "# Go JOSE\n\n[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4)\n[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4/jwt.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4/jwt)\n[![license](https://img.shields.io/badge/license-apache_2.0-blue.svg?style=flat)](https://raw.githubusercontent.com/go-jose/go-jose/master/LICENSE)\n\nPackage jose aims to provide an implementation of the Javascript Object Signing\nand Encryption set of standards. This includes support for JSON Web Encryption,\nJSON Web Signature, and JSON Web Token standards.\n\n## Overview\n\nThe implementation follows the\n[JSON Web Encryption](https://dx.doi.org/10.17487/RFC7516) (RFC 7516),\n[JSON Web Signature](https://dx.doi.org/10.17487/RFC7515) (RFC 7515), and\n[JSON Web Token](https://dx.doi.org/10.17487/RFC7519) (RFC 7519) specifications.\nTables of supported algorithms are shown below. The library supports both\nthe compact and JWS/JWE JSON Serialization formats, and has optional support for\nmultiple recipients. It also comes with a small command-line utility\n([`jose-util`](https://pkg.go.dev/github.com/go-jose/go-jose/jose-util))\nfor dealing with JOSE messages in a shell.\n\n**Note**: We use a forked version of the `encoding/json` package from the Go\nstandard library which uses case-sensitive matching for member names (instead\nof [case-insensitive matching](https://www.ietf.org/mail-archive/web/json/current/msg03763.html)).\nThis is to avoid differences in interpretation of messages between go-jose and\nlibraries in other languages.\n\n### Versions\n\nThe forthcoming Version 5 will be released with several breaking API changes,\nand will require Golang's `encoding/json/v2`, which is currently requires \nGo 1.25 built with GOEXPERIMENT=jsonv2.\n\nVersion 4 is the current stable version:\n\n    import \"github.com/go-jose/go-jose/v4\"\n\nIt supports at least the current and previous Golang release. Currently it\nrequires Golang 1.24.\n\nVersion 3 is only receiving critical security updates. Migration to Version 4 is recommended.\n\nVersions 1 and 2 are obsolete, but can be found in the old repository, [square/go-jose](https://github.com/square/go-jose).\n\n### Supported algorithms\n\nSee below for a table of supported algorithms. Algorithm identifiers match\nthe names in the [JSON Web Algorithms](https://dx.doi.org/10.17487/RFC7518)\nstandard where possible. The Godoc reference has a list of constants.\n\n| Key encryption         | Algorithm identifier(s)                        |\n|:-----------------------|:-----------------------------------------------|\n| RSA-PKCS#1v1.5         | RSA1_5                                         |\n| RSA-OAEP               | RSA-OAEP, RSA-OAEP-256                         |\n| AES key wrap           | A128KW, A192KW, A256KW                         |\n| AES-GCM key wrap       | A128GCMKW, A192GCMKW, A256GCMKW                |\n| ECDH-ES + AES key wrap | ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW |\n| ECDH-ES (direct)       | ECDH-ES<sup>1</sup>                            |\n| Direct encryption      | dir<sup>1</sup>                                |\n\n<sup>1. Not supported in multi-recipient mode</sup>\n\n| Signing / MAC     | Algorithm identifier(s) |\n|:------------------|:------------------------|\n| RSASSA-PKCS#1v1.5 | RS256, RS384, RS512     |\n| RSASSA-PSS        | PS256, PS384, PS512     |\n| HMAC              | HS256, HS384, HS512     |\n| ECDSA             | ES256, ES384, ES512     |\n| Ed25519           | EdDSA<sup>2</sup>       |\n\n<sup>2. Only available in version 2 of the package</sup>\n\n| Content encryption | Algorithm identifier(s)                     |\n|:-------------------|:--------------------------------------------|\n| AES-CBC+HMAC       | A128CBC-HS256, A192CBC-HS384, A256CBC-HS512 |\n| AES-GCM            | A128GCM, A192GCM, A256GCM                   |\n\n| Compression        | Algorithm identifiers(s) |\n|:-------------------|--------------------------|\n| DEFLATE (RFC 1951) | DEF                      |\n\n### Supported key types\n\nSee below for a table of supported key types. These are understood by the\nlibrary, and can be passed to corresponding functions such as `NewEncrypter` or\n`NewSigner`. Each of these keys can also be wrapped in a JWK if desired, which\nallows attaching a key id.\n\n| Algorithm(s)      | Corresponding types                                                                                                                  |\n|:------------------|--------------------------------------------------------------------------------------------------------------------------------------|\n| RSA               | *[rsa.PublicKey](https://pkg.go.dev/crypto/rsa/#PublicKey), *[rsa.PrivateKey](https://pkg.go.dev/crypto/rsa/#PrivateKey)             |\n| ECDH, ECDSA       | *[ecdsa.PublicKey](https://pkg.go.dev/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](https://pkg.go.dev/crypto/ecdsa/#PrivateKey)     |\n| EdDSA<sup>1</sup> | [ed25519.PublicKey](https://pkg.go.dev/crypto/ed25519#PublicKey), [ed25519.PrivateKey](https://pkg.go.dev/crypto/ed25519#PrivateKey) |\n| AES, HMAC         | []byte                                                                                                                               |\n\n<sup>1. Only available in version 2 or later of the package</sup>\n\n## Examples\n\n[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4)\n[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4/jwt.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4/jwt)\n\nExamples can be found in the Godoc\nreference for this package. The\n[`jose-util`](https://github.com/go-jose/go-jose/tree/main/jose-util)\nsubdirectory also contains a small command-line utility which might be useful\nas an example as well.\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/SECURITY.md",
    "content": "# Security Policy\nThis document explains how to contact the Let's Encrypt security team to report security vulnerabilities.\n\n## Supported Versions\n| Version | Supported |\n| ------- | ----------|\n| >= v3   | &check; |\n| v2      | &cross; |\n| v1      | &cross; |\n\n## Reporting a vulnerability\n\nPlease see [https://letsencrypt.org/contact/#security](https://letsencrypt.org/contact/#security) for the email address to report a vulnerability. Ensure that the subject line for your report contains the word `vulnerability` and is descriptive. Your email should be acknowledged within 24 hours. If you do not receive a response within 24 hours, please follow-up again with another email.\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/asymmetric.go",
    "content": "/*-\n * Copyright 2014 Square Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage jose\n\nimport (\n\t\"crypto\"\n\t\"crypto/aes\"\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/sha1\"\n\t\"crypto/sha256\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math/big\"\n\n\tjosecipher \"github.com/go-jose/go-jose/v4/cipher\"\n\t\"github.com/go-jose/go-jose/v4/json\"\n)\n\n// A generic RSA-based encrypter/verifier\ntype rsaEncrypterVerifier struct {\n\tpublicKey *rsa.PublicKey\n}\n\n// A generic RSA-based decrypter/signer\ntype rsaDecrypterSigner struct {\n\tprivateKey *rsa.PrivateKey\n}\n\n// A generic EC-based encrypter/verifier\ntype ecEncrypterVerifier struct {\n\tpublicKey *ecdsa.PublicKey\n}\n\ntype edEncrypterVerifier struct {\n\tpublicKey ed25519.PublicKey\n}\n\n// A key generator for ECDH-ES\ntype ecKeyGenerator struct {\n\tsize      int\n\talgID     string\n\tpublicKey *ecdsa.PublicKey\n}\n\n// A generic EC-based decrypter/signer\ntype ecDecrypterSigner struct {\n\tprivateKey *ecdsa.PrivateKey\n}\n\ntype edDecrypterSigner struct {\n\tprivateKey ed25519.PrivateKey\n}\n\n// newRSARecipient creates recipientKeyInfo based on the given key.\nfunc newRSARecipient(keyAlg KeyAlgorithm, publicKey *rsa.PublicKey) (recipientKeyInfo, error) {\n\t// Verify that key management algorithm is supported by this encrypter\n\tswitch keyAlg {\n\tcase RSA1_5, RSA_OAEP, RSA_OAEP_256:\n\tdefault:\n\t\treturn recipientKeyInfo{}, ErrUnsupportedAlgorithm\n\t}\n\n\tif publicKey == nil {\n\t\treturn recipientKeyInfo{}, errors.New(\"invalid public key\")\n\t}\n\n\treturn recipientKeyInfo{\n\t\tkeyAlg: keyAlg,\n\t\tkeyEncrypter: &rsaEncrypterVerifier{\n\t\t\tpublicKey: publicKey,\n\t\t},\n\t}, nil\n}\n\n// newRSASigner creates a recipientSigInfo based on the given key.\nfunc newRSASigner(sigAlg SignatureAlgorithm, privateKey *rsa.PrivateKey) (recipientSigInfo, error) {\n\t// Verify that key management algorithm is supported by this encrypter\n\tswitch sigAlg {\n\tcase RS256, RS384, RS512, PS256, PS384, PS512:\n\tdefault:\n\t\treturn recipientSigInfo{}, ErrUnsupportedAlgorithm\n\t}\n\n\tif privateKey == nil {\n\t\treturn recipientSigInfo{}, errors.New(\"invalid private key\")\n\t}\n\n\treturn recipientSigInfo{\n\t\tsigAlg: sigAlg,\n\t\tpublicKey: staticPublicKey(&JSONWebKey{\n\t\t\tKey: privateKey.Public(),\n\t\t}),\n\t\tsigner: &rsaDecrypterSigner{\n\t\t\tprivateKey: privateKey,\n\t\t},\n\t}, nil\n}\n\nfunc newEd25519Signer(sigAlg SignatureAlgorithm, privateKey ed25519.PrivateKey) (recipientSigInfo, error) {\n\tif sigAlg != EdDSA {\n\t\treturn recipientSigInfo{}, ErrUnsupportedAlgorithm\n\t}\n\n\tif privateKey == nil {\n\t\treturn recipientSigInfo{}, errors.New(\"invalid private key\")\n\t}\n\treturn recipientSigInfo{\n\t\tsigAlg: sigAlg,\n\t\tpublicKey: staticPublicKey(&JSONWebKey{\n\t\t\tKey: privateKey.Public(),\n\t\t}),\n\t\tsigner: &edDecrypterSigner{\n\t\t\tprivateKey: privateKey,\n\t\t},\n\t}, nil\n}\n\n// newECDHRecipient creates recipientKeyInfo based on the given key.\nfunc newECDHRecipient(keyAlg KeyAlgorithm, publicKey *ecdsa.PublicKey) (recipientKeyInfo, error) {\n\t// Verify that key management algorithm is supported by this encrypter\n\tswitch keyAlg {\n\tcase ECDH_ES, ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW:\n\tdefault:\n\t\treturn recipientKeyInfo{}, ErrUnsupportedAlgorithm\n\t}\n\n\tif publicKey == nil || !publicKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) {\n\t\treturn recipientKeyInfo{}, errors.New(\"invalid public key\")\n\t}\n\n\treturn recipientKeyInfo{\n\t\tkeyAlg: keyAlg,\n\t\tkeyEncrypter: &ecEncrypterVerifier{\n\t\t\tpublicKey: publicKey,\n\t\t},\n\t}, nil\n}\n\n// newECDSASigner creates a recipientSigInfo based on the given key.\nfunc newECDSASigner(sigAlg SignatureAlgorithm, privateKey *ecdsa.PrivateKey) (recipientSigInfo, error) {\n\t// Verify that key management algorithm is supported by this encrypter\n\tswitch sigAlg {\n\tcase ES256, ES384, ES512:\n\tdefault:\n\t\treturn recipientSigInfo{}, ErrUnsupportedAlgorithm\n\t}\n\n\tif privateKey == nil {\n\t\treturn recipientSigInfo{}, errors.New(\"invalid private key\")\n\t}\n\n\treturn recipientSigInfo{\n\t\tsigAlg: sigAlg,\n\t\tpublicKey: staticPublicKey(&JSONWebKey{\n\t\t\tKey: privateKey.Public(),\n\t\t}),\n\t\tsigner: &ecDecrypterSigner{\n\t\t\tprivateKey: privateKey,\n\t\t},\n\t}, nil\n}\n\n// Encrypt the given payload and update the object.\nfunc (ctx rsaEncrypterVerifier) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {\n\tencryptedKey, err := ctx.encrypt(cek, alg)\n\tif err != nil {\n\t\treturn recipientInfo{}, err\n\t}\n\n\treturn recipientInfo{\n\t\tencryptedKey: encryptedKey,\n\t\theader:       &rawHeader{},\n\t}, nil\n}\n\n// Encrypt the given payload. Based on the key encryption algorithm,\n// this will either use RSA-PKCS1v1.5 or RSA-OAEP (with SHA-1 or SHA-256).\nfunc (ctx rsaEncrypterVerifier) encrypt(cek []byte, alg KeyAlgorithm) ([]byte, error) {\n\tswitch alg {\n\tcase RSA1_5:\n\t\treturn rsa.EncryptPKCS1v15(RandReader, ctx.publicKey, cek)\n\tcase RSA_OAEP:\n\t\treturn rsa.EncryptOAEP(sha1.New(), RandReader, ctx.publicKey, cek, []byte{})\n\tcase RSA_OAEP_256:\n\t\treturn rsa.EncryptOAEP(sha256.New(), RandReader, ctx.publicKey, cek, []byte{})\n\t}\n\n\treturn nil, ErrUnsupportedAlgorithm\n}\n\n// Decrypt the given payload and return the content encryption key.\nfunc (ctx rsaDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {\n\treturn ctx.decrypt(recipient.encryptedKey, headers.getAlgorithm(), generator)\n}\n\n// Decrypt the given payload. Based on the key encryption algorithm,\n// this will either use RSA-PKCS1v1.5 or RSA-OAEP (with SHA-1 or SHA-256).\nfunc (ctx rsaDecrypterSigner) decrypt(jek []byte, alg KeyAlgorithm, generator keyGenerator) ([]byte, error) {\n\t// Note: The random reader on decrypt operations is only used for blinding,\n\t// so stubbing is meanlingless (hence the direct use of rand.Reader).\n\tswitch alg {\n\tcase RSA1_5:\n\t\tdefer func() {\n\t\t\t// DecryptPKCS1v15SessionKey sometimes panics on an invalid payload\n\t\t\t// because of an index out of bounds error, which we want to ignore.\n\t\t\t// This has been fixed in Go 1.3.1 (released 2014/08/13), the recover()\n\t\t\t// only exists for preventing crashes with unpatched versions.\n\t\t\t// See: https://groups.google.com/forum/#!topic/golang-dev/7ihX6Y6kx9k\n\t\t\t// See: https://code.google.com/p/go/source/detail?r=58ee390ff31602edb66af41ed10901ec95904d33\n\t\t\t_ = recover()\n\t\t}()\n\n\t\t// Perform some input validation.\n\t\tkeyBytes := ctx.privateKey.PublicKey.N.BitLen() / 8\n\t\tif keyBytes != len(jek) {\n\t\t\t// Input size is incorrect, the encrypted payload should always match\n\t\t\t// the size of the public modulus (e.g. using a 2048 bit key will\n\t\t\t// produce 256 bytes of output). Reject this since it's invalid input.\n\t\t\treturn nil, ErrCryptoFailure\n\t\t}\n\n\t\tcek, _, err := generator.genKey()\n\t\tif err != nil {\n\t\t\treturn nil, ErrCryptoFailure\n\t\t}\n\n\t\t// When decrypting an RSA-PKCS1v1.5 payload, we must take precautions to\n\t\t// prevent chosen-ciphertext attacks as described in RFC 3218, \"Preventing\n\t\t// the Million Message Attack on Cryptographic Message Syntax\". We are\n\t\t// therefore deliberately ignoring errors here.\n\t\t_ = rsa.DecryptPKCS1v15SessionKey(rand.Reader, ctx.privateKey, jek, cek)\n\n\t\treturn cek, nil\n\tcase RSA_OAEP:\n\t\t// Use rand.Reader for RSA blinding\n\t\treturn rsa.DecryptOAEP(sha1.New(), rand.Reader, ctx.privateKey, jek, []byte{})\n\tcase RSA_OAEP_256:\n\t\t// Use rand.Reader for RSA blinding\n\t\treturn rsa.DecryptOAEP(sha256.New(), rand.Reader, ctx.privateKey, jek, []byte{})\n\t}\n\n\treturn nil, ErrUnsupportedAlgorithm\n}\n\n// Sign the given payload\nfunc (ctx rsaDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {\n\tvar hash crypto.Hash\n\n\tswitch alg {\n\tcase RS256, PS256:\n\t\thash = crypto.SHA256\n\tcase RS384, PS384:\n\t\thash = crypto.SHA384\n\tcase RS512, PS512:\n\t\thash = crypto.SHA512\n\tdefault:\n\t\treturn Signature{}, ErrUnsupportedAlgorithm\n\t}\n\n\thasher := hash.New()\n\n\t// According to documentation, Write() on hash never fails\n\t_, _ = hasher.Write(payload)\n\thashed := hasher.Sum(nil)\n\n\tvar out []byte\n\tvar err error\n\n\tswitch alg {\n\tcase RS256, RS384, RS512:\n\t\t// TODO(https://github.com/go-jose/go-jose/issues/40): As of go1.20, the\n\t\t// random parameter is legacy and ignored, and it can be nil.\n\t\t// https://cs.opensource.google/go/go/+/refs/tags/go1.20:src/crypto/rsa/pkcs1v15.go;l=263;bpv=0;bpt=1\n\t\tout, err = rsa.SignPKCS1v15(RandReader, ctx.privateKey, hash, hashed)\n\tcase PS256, PS384, PS512:\n\t\tout, err = rsa.SignPSS(RandReader, ctx.privateKey, hash, hashed, &rsa.PSSOptions{\n\t\t\tSaltLength: rsa.PSSSaltLengthEqualsHash,\n\t\t})\n\t}\n\n\tif err != nil {\n\t\treturn Signature{}, err\n\t}\n\n\treturn Signature{\n\t\tSignature: out,\n\t\tprotected: &rawHeader{},\n\t}, nil\n}\n\n// Verify the given payload\nfunc (ctx rsaEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {\n\tvar hash crypto.Hash\n\n\tswitch alg {\n\tcase RS256, PS256:\n\t\thash = crypto.SHA256\n\tcase RS384, PS384:\n\t\thash = crypto.SHA384\n\tcase RS512, PS512:\n\t\thash = crypto.SHA512\n\tdefault:\n\t\treturn ErrUnsupportedAlgorithm\n\t}\n\n\thasher := hash.New()\n\n\t// According to documentation, Write() on hash never fails\n\t_, _ = hasher.Write(payload)\n\thashed := hasher.Sum(nil)\n\n\tswitch alg {\n\tcase RS256, RS384, RS512:\n\t\treturn rsa.VerifyPKCS1v15(ctx.publicKey, hash, hashed, signature)\n\tcase PS256, PS384, PS512:\n\t\treturn rsa.VerifyPSS(ctx.publicKey, hash, hashed, signature, nil)\n\t}\n\n\treturn ErrUnsupportedAlgorithm\n}\n\n// Encrypt the given payload and update the object.\nfunc (ctx ecEncrypterVerifier) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {\n\tswitch alg {\n\tcase ECDH_ES:\n\t\t// ECDH-ES mode doesn't wrap a key, the shared secret is used directly as the key.\n\t\treturn recipientInfo{\n\t\t\theader: &rawHeader{},\n\t\t}, nil\n\tcase ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW:\n\tdefault:\n\t\treturn recipientInfo{}, ErrUnsupportedAlgorithm\n\t}\n\n\tgenerator := ecKeyGenerator{\n\t\talgID:     string(alg),\n\t\tpublicKey: ctx.publicKey,\n\t}\n\n\tswitch alg {\n\tcase ECDH_ES_A128KW:\n\t\tgenerator.size = 16\n\tcase ECDH_ES_A192KW:\n\t\tgenerator.size = 24\n\tcase ECDH_ES_A256KW:\n\t\tgenerator.size = 32\n\t}\n\n\tkek, header, err := generator.genKey()\n\tif err != nil {\n\t\treturn recipientInfo{}, err\n\t}\n\n\tblock, err := aes.NewCipher(kek)\n\tif err != nil {\n\t\treturn recipientInfo{}, err\n\t}\n\n\tjek, err := josecipher.KeyWrap(block, cek)\n\tif err != nil {\n\t\treturn recipientInfo{}, err\n\t}\n\n\treturn recipientInfo{\n\t\tencryptedKey: jek,\n\t\theader:       &header,\n\t}, nil\n}\n\n// Get key size for EC key generator\nfunc (ctx ecKeyGenerator) keySize() int {\n\treturn ctx.size\n}\n\n// Get a content encryption key for ECDH-ES\nfunc (ctx ecKeyGenerator) genKey() ([]byte, rawHeader, error) {\n\tpriv, err := ecdsa.GenerateKey(ctx.publicKey.Curve, RandReader)\n\tif err != nil {\n\t\treturn nil, rawHeader{}, err\n\t}\n\n\tout := josecipher.DeriveECDHES(ctx.algID, []byte{}, []byte{}, priv, ctx.publicKey, ctx.size)\n\n\tb, err := json.Marshal(&JSONWebKey{\n\t\tKey: &priv.PublicKey,\n\t})\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\theaders := rawHeader{\n\t\theaderEPK: makeRawMessage(b),\n\t}\n\n\treturn out, headers, nil\n}\n\n// Decrypt the given payload and return the content encryption key.\nfunc (ctx ecDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {\n\tepk, err := headers.getEPK()\n\tif err != nil {\n\t\treturn nil, errors.New(\"go-jose/go-jose: invalid epk header\")\n\t}\n\tif epk == nil {\n\t\treturn nil, errors.New(\"go-jose/go-jose: missing epk header\")\n\t}\n\n\tpublicKey, ok := epk.Key.(*ecdsa.PublicKey)\n\tif publicKey == nil || !ok {\n\t\treturn nil, errors.New(\"go-jose/go-jose: invalid epk header\")\n\t}\n\n\tif !ctx.privateKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) {\n\t\treturn nil, errors.New(\"go-jose/go-jose: invalid public key in epk header\")\n\t}\n\n\tapuData, err := headers.getAPU()\n\tif err != nil {\n\t\treturn nil, errors.New(\"go-jose/go-jose: invalid apu header\")\n\t}\n\tapvData, err := headers.getAPV()\n\tif err != nil {\n\t\treturn nil, errors.New(\"go-jose/go-jose: invalid apv header\")\n\t}\n\n\tderiveKey := func(algID string, size int) []byte {\n\t\treturn josecipher.DeriveECDHES(algID, apuData.bytes(), apvData.bytes(), ctx.privateKey, publicKey, size)\n\t}\n\n\tvar keySize int\n\n\talgorithm := headers.getAlgorithm()\n\tswitch algorithm {\n\tcase ECDH_ES:\n\t\t// ECDH-ES uses direct key agreement, no key unwrapping necessary.\n\t\treturn deriveKey(string(headers.getEncryption()), generator.keySize()), nil\n\tcase ECDH_ES_A128KW:\n\t\tkeySize = 16\n\tcase ECDH_ES_A192KW:\n\t\tkeySize = 24\n\tcase ECDH_ES_A256KW:\n\t\tkeySize = 32\n\tdefault:\n\t\treturn nil, ErrUnsupportedAlgorithm\n\t}\n\n\tkey := deriveKey(string(algorithm), keySize)\n\tblock, err := aes.NewCipher(key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn josecipher.KeyUnwrap(block, recipient.encryptedKey)\n}\n\nfunc (ctx edDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {\n\tif alg != EdDSA {\n\t\treturn Signature{}, ErrUnsupportedAlgorithm\n\t}\n\n\tsig, err := ctx.privateKey.Sign(RandReader, payload, crypto.Hash(0))\n\tif err != nil {\n\t\treturn Signature{}, err\n\t}\n\n\treturn Signature{\n\t\tSignature: sig,\n\t\tprotected: &rawHeader{},\n\t}, nil\n}\n\nfunc (ctx edEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {\n\tif alg != EdDSA {\n\t\treturn ErrUnsupportedAlgorithm\n\t}\n\tok := ed25519.Verify(ctx.publicKey, payload, signature)\n\tif !ok {\n\t\treturn errors.New(\"go-jose/go-jose: ed25519 signature failed to verify\")\n\t}\n\treturn nil\n}\n\n// Sign the given payload\nfunc (ctx ecDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {\n\tvar expectedBitSize int\n\tvar hash crypto.Hash\n\n\tswitch alg {\n\tcase ES256:\n\t\texpectedBitSize = 256\n\t\thash = crypto.SHA256\n\tcase ES384:\n\t\texpectedBitSize = 384\n\t\thash = crypto.SHA384\n\tcase ES512:\n\t\texpectedBitSize = 521\n\t\thash = crypto.SHA512\n\t}\n\n\tcurveBits := ctx.privateKey.Curve.Params().BitSize\n\tif expectedBitSize != curveBits {\n\t\treturn Signature{}, fmt.Errorf(\"go-jose/go-jose: expected %d bit key, got %d bits instead\", expectedBitSize, curveBits)\n\t}\n\n\thasher := hash.New()\n\n\t// According to documentation, Write() on hash never fails\n\t_, _ = hasher.Write(payload)\n\thashed := hasher.Sum(nil)\n\n\tr, s, err := ecdsa.Sign(RandReader, ctx.privateKey, hashed)\n\tif err != nil {\n\t\treturn Signature{}, err\n\t}\n\n\tkeyBytes := curveBits / 8\n\tif curveBits%8 > 0 {\n\t\tkeyBytes++\n\t}\n\n\t// We serialize the outputs (r and s) into big-endian byte arrays and pad\n\t// them with zeros on the left to make sure the sizes work out. Both arrays\n\t// must be keyBytes long, and the output must be 2*keyBytes long.\n\trBytes := r.Bytes()\n\trBytesPadded := make([]byte, keyBytes)\n\tcopy(rBytesPadded[keyBytes-len(rBytes):], rBytes)\n\n\tsBytes := s.Bytes()\n\tsBytesPadded := make([]byte, keyBytes)\n\tcopy(sBytesPadded[keyBytes-len(sBytes):], sBytes)\n\n\tout := append(rBytesPadded, sBytesPadded...)\n\n\treturn Signature{\n\t\tSignature: out,\n\t\tprotected: &rawHeader{},\n\t}, nil\n}\n\n// Verify the given payload\nfunc (ctx ecEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {\n\tvar keySize int\n\tvar hash crypto.Hash\n\n\tswitch alg {\n\tcase ES256:\n\t\tkeySize = 32\n\t\thash = crypto.SHA256\n\tcase ES384:\n\t\tkeySize = 48\n\t\thash = crypto.SHA384\n\tcase ES512:\n\t\tkeySize = 66\n\t\thash = crypto.SHA512\n\tdefault:\n\t\treturn ErrUnsupportedAlgorithm\n\t}\n\n\tif len(signature) != 2*keySize {\n\t\treturn fmt.Errorf(\"go-jose/go-jose: invalid signature size, have %d bytes, wanted %d\", len(signature), 2*keySize)\n\t}\n\n\thasher := hash.New()\n\n\t// According to documentation, Write() on hash never fails\n\t_, _ = hasher.Write(payload)\n\thashed := hasher.Sum(nil)\n\n\tr := big.NewInt(0).SetBytes(signature[:keySize])\n\ts := big.NewInt(0).SetBytes(signature[keySize:])\n\n\tmatch := ecdsa.Verify(ctx.publicKey, hashed, r, s)\n\tif !match {\n\t\treturn errors.New(\"go-jose/go-jose: ecdsa signature failed to verify\")\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/cipher/cbc_hmac.go",
    "content": "/*-\n * Copyright 2014 Square Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage josecipher\n\nimport (\n\t\"bytes\"\n\t\"crypto/cipher\"\n\t\"crypto/hmac\"\n\t\"crypto/sha256\"\n\t\"crypto/sha512\"\n\t\"crypto/subtle\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"hash\"\n)\n\nconst (\n\tnonceBytes = 16\n)\n\n// NewCBCHMAC instantiates a new AEAD based on CBC+HMAC.\nfunc NewCBCHMAC(key []byte, newBlockCipher func([]byte) (cipher.Block, error)) (cipher.AEAD, error) {\n\tkeySize := len(key) / 2\n\tintegrityKey := key[:keySize]\n\tencryptionKey := key[keySize:]\n\n\tblockCipher, err := newBlockCipher(encryptionKey)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar hash func() hash.Hash\n\tswitch keySize {\n\tcase 16:\n\t\thash = sha256.New\n\tcase 24:\n\t\thash = sha512.New384\n\tcase 32:\n\t\thash = sha512.New\n\t}\n\n\treturn &cbcAEAD{\n\t\thash:         hash,\n\t\tblockCipher:  blockCipher,\n\t\tauthtagBytes: keySize,\n\t\tintegrityKey: integrityKey,\n\t}, nil\n}\n\n// An AEAD based on CBC+HMAC\ntype cbcAEAD struct {\n\thash         func() hash.Hash\n\tauthtagBytes int\n\tintegrityKey []byte\n\tblockCipher  cipher.Block\n}\n\nfunc (ctx *cbcAEAD) NonceSize() int {\n\treturn nonceBytes\n}\n\nfunc (ctx *cbcAEAD) Overhead() int {\n\t// Maximum overhead is block size (for padding) plus auth tag length, where\n\t// the length of the auth tag is equivalent to the key size.\n\treturn ctx.blockCipher.BlockSize() + ctx.authtagBytes\n}\n\n// Seal encrypts and authenticates the plaintext.\nfunc (ctx *cbcAEAD) Seal(dst, nonce, plaintext, data []byte) []byte {\n\t// Output buffer -- must take care not to mangle plaintext input.\n\tciphertext := make([]byte, uint64(len(plaintext))+uint64(ctx.Overhead()))[:len(plaintext)]\n\tcopy(ciphertext, plaintext)\n\tciphertext = padBuffer(ciphertext, ctx.blockCipher.BlockSize())\n\n\tcbc := cipher.NewCBCEncrypter(ctx.blockCipher, nonce)\n\n\tcbc.CryptBlocks(ciphertext, ciphertext)\n\tauthtag := ctx.computeAuthTag(data, nonce, ciphertext)\n\n\tret, out := resize(dst, uint64(len(dst))+uint64(len(ciphertext))+uint64(len(authtag)))\n\tcopy(out, ciphertext)\n\tcopy(out[len(ciphertext):], authtag)\n\n\treturn ret\n}\n\n// Open decrypts and authenticates the ciphertext.\nfunc (ctx *cbcAEAD) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {\n\tif len(ciphertext) < ctx.authtagBytes {\n\t\treturn nil, errors.New(\"go-jose/go-jose: invalid ciphertext (too short)\")\n\t}\n\n\toffset := len(ciphertext) - ctx.authtagBytes\n\texpectedTag := ctx.computeAuthTag(data, nonce, ciphertext[:offset])\n\tmatch := subtle.ConstantTimeCompare(expectedTag, ciphertext[offset:])\n\tif match != 1 {\n\t\treturn nil, errors.New(\"go-jose/go-jose: invalid ciphertext (auth tag mismatch)\")\n\t}\n\n\tcbc := cipher.NewCBCDecrypter(ctx.blockCipher, nonce)\n\n\t// Make copy of ciphertext buffer, don't want to modify in place\n\tbuffer := append([]byte{}, ciphertext[:offset]...)\n\n\tif len(buffer)%ctx.blockCipher.BlockSize() > 0 {\n\t\treturn nil, errors.New(\"go-jose/go-jose: invalid ciphertext (invalid length)\")\n\t}\n\n\tcbc.CryptBlocks(buffer, buffer)\n\n\t// Remove padding\n\tplaintext, err := unpadBuffer(buffer, ctx.blockCipher.BlockSize())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tret, out := resize(dst, uint64(len(dst))+uint64(len(plaintext)))\n\tcopy(out, plaintext)\n\n\treturn ret, nil\n}\n\n// Compute an authentication tag\nfunc (ctx *cbcAEAD) computeAuthTag(aad, nonce, ciphertext []byte) []byte {\n\tbuffer := make([]byte, uint64(len(aad))+uint64(len(nonce))+uint64(len(ciphertext))+8)\n\tn := 0\n\tn += copy(buffer, aad)\n\tn += copy(buffer[n:], nonce)\n\tn += copy(buffer[n:], ciphertext)\n\tbinary.BigEndian.PutUint64(buffer[n:], uint64(len(aad))*8)\n\n\t// According to documentation, Write() on hash.Hash never fails.\n\thmac := hmac.New(ctx.hash, ctx.integrityKey)\n\t_, _ = hmac.Write(buffer)\n\n\treturn hmac.Sum(nil)[:ctx.authtagBytes]\n}\n\n// resize ensures that the given slice has a capacity of at least n bytes.\n// If the capacity of the slice is less than n, a new slice is allocated\n// and the existing data will be copied.\nfunc resize(in []byte, n uint64) (head, tail []byte) {\n\tif uint64(cap(in)) >= n {\n\t\thead = in[:n]\n\t} else {\n\t\thead = make([]byte, n)\n\t\tcopy(head, in)\n\t}\n\n\ttail = head[len(in):]\n\treturn\n}\n\n// Apply padding\nfunc padBuffer(buffer []byte, blockSize int) []byte {\n\tmissing := blockSize - (len(buffer) % blockSize)\n\tret, out := resize(buffer, uint64(len(buffer))+uint64(missing))\n\tpadding := bytes.Repeat([]byte{byte(missing)}, missing)\n\tcopy(out, padding)\n\treturn ret\n}\n\n// Remove padding\nfunc unpadBuffer(buffer []byte, blockSize int) ([]byte, error) {\n\tif len(buffer)%blockSize != 0 {\n\t\treturn nil, errors.New(\"go-jose/go-jose: invalid padding\")\n\t}\n\n\tlast := buffer[len(buffer)-1]\n\tcount := int(last)\n\n\tif count == 0 || count > blockSize || count > len(buffer) {\n\t\treturn nil, errors.New(\"go-jose/go-jose: invalid padding\")\n\t}\n\n\tpadding := bytes.Repeat([]byte{last}, count)\n\tif !bytes.HasSuffix(buffer, padding) {\n\t\treturn nil, errors.New(\"go-jose/go-jose: invalid padding\")\n\t}\n\n\treturn buffer[:len(buffer)-count], nil\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/cipher/concat_kdf.go",
    "content": "/*-\n * Copyright 2014 Square Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage josecipher\n\nimport (\n\t\"crypto\"\n\t\"encoding/binary\"\n\t\"hash\"\n\t\"io\"\n)\n\ntype concatKDF struct {\n\tz, info []byte\n\ti       uint32\n\tcache   []byte\n\thasher  hash.Hash\n}\n\n// NewConcatKDF builds a KDF reader based on the given inputs.\nfunc NewConcatKDF(hash crypto.Hash, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo []byte) io.Reader {\n\tbuffer := make([]byte, uint64(len(algID))+uint64(len(ptyUInfo))+uint64(len(ptyVInfo))+uint64(len(supPubInfo))+uint64(len(supPrivInfo)))\n\tn := 0\n\tn += copy(buffer, algID)\n\tn += copy(buffer[n:], ptyUInfo)\n\tn += copy(buffer[n:], ptyVInfo)\n\tn += copy(buffer[n:], supPubInfo)\n\tcopy(buffer[n:], supPrivInfo)\n\n\thasher := hash.New()\n\n\treturn &concatKDF{\n\t\tz:      z,\n\t\tinfo:   buffer,\n\t\thasher: hasher,\n\t\tcache:  []byte{},\n\t\ti:      1,\n\t}\n}\n\nfunc (ctx *concatKDF) Read(out []byte) (int, error) {\n\tcopied := copy(out, ctx.cache)\n\tctx.cache = ctx.cache[copied:]\n\n\tfor copied < len(out) {\n\t\tctx.hasher.Reset()\n\n\t\t// Write on a hash.Hash never fails\n\t\t_ = binary.Write(ctx.hasher, binary.BigEndian, ctx.i)\n\t\t_, _ = ctx.hasher.Write(ctx.z)\n\t\t_, _ = ctx.hasher.Write(ctx.info)\n\n\t\thash := ctx.hasher.Sum(nil)\n\t\tchunkCopied := copy(out[copied:], hash)\n\t\tcopied += chunkCopied\n\t\tctx.cache = hash[chunkCopied:]\n\n\t\tctx.i++\n\t}\n\n\treturn copied, nil\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/cipher/ecdh_es.go",
    "content": "/*-\n * Copyright 2014 Square Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage josecipher\n\nimport (\n\t\"bytes\"\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"encoding/binary\"\n)\n\n// DeriveECDHES derives a shared encryption key using ECDH/ConcatKDF as described in JWE/JWA.\n// It is an error to call this function with a private/public key that are not on the same\n// curve. Callers must ensure that the keys are valid before calling this function. Output\n// size may be at most 1<<16 bytes (64 KiB).\nfunc DeriveECDHES(alg string, apuData, apvData []byte, priv *ecdsa.PrivateKey, pub *ecdsa.PublicKey, size int) []byte {\n\tif size > 1<<16 {\n\t\tpanic(\"ECDH-ES output size too large, must be less than or equal to 1<<16\")\n\t}\n\n\t// algId, partyUInfo, partyVInfo inputs must be prefixed with the length\n\talgID := lengthPrefixed([]byte(alg))\n\tptyUInfo := lengthPrefixed(apuData)\n\tptyVInfo := lengthPrefixed(apvData)\n\n\t// suppPubInfo is the encoded length of the output size in bits\n\tsupPubInfo := make([]byte, 4)\n\tbinary.BigEndian.PutUint32(supPubInfo, uint32(size)*8)\n\n\tif !priv.PublicKey.Curve.IsOnCurve(pub.X, pub.Y) {\n\t\tpanic(\"public key not on same curve as private key\")\n\t}\n\n\tz, _ := priv.Curve.ScalarMult(pub.X, pub.Y, priv.D.Bytes())\n\tzBytes := z.Bytes()\n\n\t// Note that calling z.Bytes() on a big.Int may strip leading zero bytes from\n\t// the returned byte array. This can lead to a problem where zBytes will be\n\t// shorter than expected which breaks the key derivation. Therefore we must pad\n\t// to the full length of the expected coordinate here before calling the KDF.\n\toctSize := dSize(priv.Curve)\n\tif len(zBytes) != octSize {\n\t\tzBytes = append(bytes.Repeat([]byte{0}, octSize-len(zBytes)), zBytes...)\n\t}\n\n\treader := NewConcatKDF(crypto.SHA256, zBytes, algID, ptyUInfo, ptyVInfo, supPubInfo, []byte{})\n\tkey := make([]byte, size)\n\n\t// Read on the KDF will never fail\n\t_, _ = reader.Read(key)\n\n\treturn key\n}\n\n// dSize returns the size in octets for a coordinate on a elliptic curve.\nfunc dSize(curve elliptic.Curve) int {\n\torder := curve.Params().P\n\tbitLen := order.BitLen()\n\tsize := bitLen / 8\n\tif bitLen%8 != 0 {\n\t\tsize++\n\t}\n\treturn size\n}\n\nfunc lengthPrefixed(data []byte) []byte {\n\tout := make([]byte, len(data)+4)\n\tbinary.BigEndian.PutUint32(out, uint32(len(data)))\n\tcopy(out[4:], data)\n\treturn out\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/cipher/key_wrap.go",
    "content": "/*-\n * Copyright 2014 Square Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage josecipher\n\nimport (\n\t\"crypto/cipher\"\n\t\"crypto/subtle\"\n\t\"encoding/binary\"\n\t\"errors\"\n)\n\nvar defaultIV = []byte{0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6}\n\n// KeyWrap implements NIST key wrapping; it wraps a content encryption key (cek) with the given block cipher.\nfunc KeyWrap(block cipher.Block, cek []byte) ([]byte, error) {\n\tif len(cek)%8 != 0 {\n\t\treturn nil, errors.New(\"go-jose/go-jose: key wrap input must be 8 byte blocks\")\n\t}\n\n\tn := len(cek) / 8\n\tr := make([][]byte, n)\n\n\tfor i := range r {\n\t\tr[i] = make([]byte, 8)\n\t\tcopy(r[i], cek[i*8:])\n\t}\n\n\tbuffer := make([]byte, 16)\n\ttBytes := make([]byte, 8)\n\tcopy(buffer, defaultIV)\n\n\tfor t := 0; t < 6*n; t++ {\n\t\tcopy(buffer[8:], r[t%n])\n\n\t\tblock.Encrypt(buffer, buffer)\n\n\t\tbinary.BigEndian.PutUint64(tBytes, uint64(t+1))\n\n\t\tfor i := 0; i < 8; i++ {\n\t\t\tbuffer[i] ^= tBytes[i]\n\t\t}\n\t\tcopy(r[t%n], buffer[8:])\n\t}\n\n\tout := make([]byte, (n+1)*8)\n\tcopy(out, buffer[:8])\n\tfor i := range r {\n\t\tcopy(out[(i+1)*8:], r[i])\n\t}\n\n\treturn out, nil\n}\n\n// KeyUnwrap implements NIST key unwrapping; it unwraps a content encryption key (cek) with the given block cipher.\nfunc KeyUnwrap(block cipher.Block, ciphertext []byte) ([]byte, error) {\n\tif len(ciphertext)%8 != 0 {\n\t\treturn nil, errors.New(\"go-jose/go-jose: key wrap input must be 8 byte blocks\")\n\t}\n\n\tn := (len(ciphertext) / 8) - 1\n\tr := make([][]byte, n)\n\n\tfor i := range r {\n\t\tr[i] = make([]byte, 8)\n\t\tcopy(r[i], ciphertext[(i+1)*8:])\n\t}\n\n\tbuffer := make([]byte, 16)\n\ttBytes := make([]byte, 8)\n\tcopy(buffer[:8], ciphertext[:8])\n\n\tfor t := 6*n - 1; t >= 0; t-- {\n\t\tbinary.BigEndian.PutUint64(tBytes, uint64(t+1))\n\n\t\tfor i := 0; i < 8; i++ {\n\t\t\tbuffer[i] ^= tBytes[i]\n\t\t}\n\t\tcopy(buffer[8:], r[t%n])\n\n\t\tblock.Decrypt(buffer, buffer)\n\n\t\tcopy(r[t%n], buffer[8:])\n\t}\n\n\tif subtle.ConstantTimeCompare(buffer[:8], defaultIV) == 0 {\n\t\treturn nil, errors.New(\"go-jose/go-jose: failed to unwrap key\")\n\t}\n\n\tout := make([]byte, n*8)\n\tfor i := range r {\n\t\tcopy(out[i*8:], r[i])\n\t}\n\n\treturn out, nil\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/crypter.go",
    "content": "/*-\n * Copyright 2014 Square Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage jose\n\nimport (\n\t\"crypto/ecdsa\"\n\t\"crypto/rsa\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/go-jose/go-jose/v4/json\"\n)\n\n// Encrypter represents an encrypter which produces an encrypted JWE object.\ntype Encrypter interface {\n\tEncrypt(plaintext []byte) (*JSONWebEncryption, error)\n\tEncryptWithAuthData(plaintext []byte, aad []byte) (*JSONWebEncryption, error)\n\tOptions() EncrypterOptions\n}\n\n// A generic content cipher\ntype contentCipher interface {\n\tkeySize() int\n\tencrypt(cek []byte, aad, plaintext []byte) (*aeadParts, error)\n\tdecrypt(cek []byte, aad []byte, parts *aeadParts) ([]byte, error)\n}\n\n// A key generator (for generating/getting a CEK)\ntype keyGenerator interface {\n\tkeySize() int\n\tgenKey() ([]byte, rawHeader, error)\n}\n\n// A generic key encrypter\ntype keyEncrypter interface {\n\tencryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) // Encrypt a key\n}\n\n// A generic key decrypter\ntype keyDecrypter interface {\n\tdecryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) // Decrypt a key\n}\n\n// A generic encrypter based on the given key encrypter and content cipher.\ntype genericEncrypter struct {\n\tcontentAlg     ContentEncryption\n\tcompressionAlg CompressionAlgorithm\n\tcipher         contentCipher\n\trecipients     []recipientKeyInfo\n\tkeyGenerator   keyGenerator\n\textraHeaders   map[HeaderKey]interface{}\n}\n\ntype recipientKeyInfo struct {\n\tkeyID        string\n\tkeyAlg       KeyAlgorithm\n\tkeyEncrypter keyEncrypter\n}\n\n// EncrypterOptions represents options that can be set on new encrypters.\ntype EncrypterOptions struct {\n\tCompression CompressionAlgorithm\n\n\t// Optional map of name/value pairs to be inserted into the protected\n\t// header of a JWS object. Some specifications which make use of\n\t// JWS require additional values here.\n\t//\n\t// Values will be serialized by [json.Marshal] and must be valid inputs to\n\t// that function.\n\t//\n\t// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal\n\tExtraHeaders map[HeaderKey]interface{}\n}\n\n// WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it\n// if necessary, and returns the updated EncrypterOptions.\n//\n// The v parameter will be serialized by [json.Marshal] and must be a valid\n// input to that function.\n//\n// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal\nfunc (eo *EncrypterOptions) WithHeader(k HeaderKey, v interface{}) *EncrypterOptions {\n\tif eo.ExtraHeaders == nil {\n\t\teo.ExtraHeaders = map[HeaderKey]interface{}{}\n\t}\n\teo.ExtraHeaders[k] = v\n\treturn eo\n}\n\n// WithContentType adds a content type (\"cty\") header and returns the updated\n// EncrypterOptions.\nfunc (eo *EncrypterOptions) WithContentType(contentType ContentType) *EncrypterOptions {\n\treturn eo.WithHeader(HeaderContentType, contentType)\n}\n\n// WithType adds a type (\"typ\") header and returns the updated EncrypterOptions.\nfunc (eo *EncrypterOptions) WithType(typ ContentType) *EncrypterOptions {\n\treturn eo.WithHeader(HeaderType, typ)\n}\n\n// Recipient represents an algorithm/key to encrypt messages to.\n//\n// PBES2Count and PBES2Salt correspond with the  \"p2c\" and \"p2s\" headers used\n// on the password-based encryption algorithms PBES2-HS256+A128KW,\n// PBES2-HS384+A192KW, and PBES2-HS512+A256KW. If they are not provided a safe\n// default of 100000 will be used for the count and a 128-bit random salt will\n// be generated.\ntype Recipient struct {\n\tAlgorithm KeyAlgorithm\n\t// Key must have one of these types:\n\t//  - ed25519.PublicKey\n\t//  - *ecdsa.PublicKey\n\t//  - *rsa.PublicKey\n\t//  - *JSONWebKey\n\t//  - JSONWebKey\n\t//  - []byte (a symmetric key)\n\t//  - Any type that satisfies the OpaqueKeyEncrypter interface\n\t//\n\t// The type of Key must match the value of Algorithm.\n\tKey        interface{}\n\tKeyID      string\n\tPBES2Count int\n\tPBES2Salt  []byte\n}\n\n// NewEncrypter creates an appropriate encrypter based on the key type\nfunc NewEncrypter(enc ContentEncryption, rcpt Recipient, opts *EncrypterOptions) (Encrypter, error) {\n\tencrypter := &genericEncrypter{\n\t\tcontentAlg: enc,\n\t\trecipients: []recipientKeyInfo{},\n\t\tcipher:     getContentCipher(enc),\n\t}\n\tif opts != nil {\n\t\tencrypter.compressionAlg = opts.Compression\n\t\tencrypter.extraHeaders = opts.ExtraHeaders\n\t}\n\n\tif encrypter.cipher == nil {\n\t\treturn nil, ErrUnsupportedAlgorithm\n\t}\n\n\tvar keyID string\n\tvar rawKey interface{}\n\tswitch encryptionKey := rcpt.Key.(type) {\n\tcase JSONWebKey:\n\t\tkeyID, rawKey = encryptionKey.KeyID, encryptionKey.Key\n\tcase *JSONWebKey:\n\t\tkeyID, rawKey = encryptionKey.KeyID, encryptionKey.Key\n\tcase OpaqueKeyEncrypter:\n\t\tkeyID, rawKey = encryptionKey.KeyID(), encryptionKey\n\tdefault:\n\t\trawKey = encryptionKey\n\t}\n\n\tswitch rcpt.Algorithm {\n\tcase DIRECT:\n\t\t// Direct encryption mode must be treated differently\n\t\tkeyBytes, ok := rawKey.([]byte)\n\t\tif !ok {\n\t\t\treturn nil, ErrUnsupportedKeyType\n\t\t}\n\t\tif encrypter.cipher.keySize() != len(keyBytes) {\n\t\t\treturn nil, ErrInvalidKeySize\n\t\t}\n\t\tencrypter.keyGenerator = staticKeyGenerator{\n\t\t\tkey: keyBytes,\n\t\t}\n\t\trecipientInfo, _ := newSymmetricRecipient(rcpt.Algorithm, keyBytes)\n\t\trecipientInfo.keyID = keyID\n\t\tif rcpt.KeyID != \"\" {\n\t\t\trecipientInfo.keyID = rcpt.KeyID\n\t\t}\n\t\tencrypter.recipients = []recipientKeyInfo{recipientInfo}\n\t\treturn encrypter, nil\n\tcase ECDH_ES:\n\t\t// ECDH-ES (w/o key wrapping) is similar to DIRECT mode\n\t\tkeyDSA, ok := rawKey.(*ecdsa.PublicKey)\n\t\tif !ok {\n\t\t\treturn nil, ErrUnsupportedKeyType\n\t\t}\n\t\tencrypter.keyGenerator = ecKeyGenerator{\n\t\t\tsize:      encrypter.cipher.keySize(),\n\t\t\talgID:     string(enc),\n\t\t\tpublicKey: keyDSA,\n\t\t}\n\t\trecipientInfo, _ := newECDHRecipient(rcpt.Algorithm, keyDSA)\n\t\trecipientInfo.keyID = keyID\n\t\tif rcpt.KeyID != \"\" {\n\t\t\trecipientInfo.keyID = rcpt.KeyID\n\t\t}\n\t\tencrypter.recipients = []recipientKeyInfo{recipientInfo}\n\t\treturn encrypter, nil\n\tdefault:\n\t\t// Can just add a standard recipient\n\t\tencrypter.keyGenerator = randomKeyGenerator{\n\t\t\tsize: encrypter.cipher.keySize(),\n\t\t}\n\t\terr := encrypter.addRecipient(rcpt)\n\t\treturn encrypter, err\n\t}\n}\n\n// NewMultiEncrypter creates a multi-encrypter based on the given parameters\nfunc NewMultiEncrypter(enc ContentEncryption, rcpts []Recipient, opts *EncrypterOptions) (Encrypter, error) {\n\tcipher := getContentCipher(enc)\n\n\tif cipher == nil {\n\t\treturn nil, ErrUnsupportedAlgorithm\n\t}\n\tif len(rcpts) == 0 {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: recipients is nil or empty\")\n\t}\n\n\tencrypter := &genericEncrypter{\n\t\tcontentAlg: enc,\n\t\trecipients: []recipientKeyInfo{},\n\t\tcipher:     cipher,\n\t\tkeyGenerator: randomKeyGenerator{\n\t\t\tsize: cipher.keySize(),\n\t\t},\n\t}\n\n\tif opts != nil {\n\t\tencrypter.compressionAlg = opts.Compression\n\t\tencrypter.extraHeaders = opts.ExtraHeaders\n\t}\n\n\tfor _, recipient := range rcpts {\n\t\terr := encrypter.addRecipient(recipient)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn encrypter, nil\n}\n\nfunc (ctx *genericEncrypter) addRecipient(recipient Recipient) (err error) {\n\tvar recipientInfo recipientKeyInfo\n\n\tswitch recipient.Algorithm {\n\tcase DIRECT, ECDH_ES:\n\t\treturn fmt.Errorf(\"go-jose/go-jose: key algorithm '%s' not supported in multi-recipient mode\", recipient.Algorithm)\n\t}\n\n\trecipientInfo, err = makeJWERecipient(recipient.Algorithm, recipient.Key)\n\tif recipient.KeyID != \"\" {\n\t\trecipientInfo.keyID = recipient.KeyID\n\t}\n\n\tswitch recipient.Algorithm {\n\tcase PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW:\n\t\tif sr, ok := recipientInfo.keyEncrypter.(*symmetricKeyCipher); ok {\n\t\t\tsr.p2c = recipient.PBES2Count\n\t\t\tsr.p2s = recipient.PBES2Salt\n\t\t}\n\t}\n\n\tif err == nil {\n\t\tctx.recipients = append(ctx.recipients, recipientInfo)\n\t}\n\treturn err\n}\n\nfunc makeJWERecipient(alg KeyAlgorithm, encryptionKey interface{}) (recipientKeyInfo, error) {\n\tswitch encryptionKey := encryptionKey.(type) {\n\tcase *rsa.PublicKey:\n\t\treturn newRSARecipient(alg, encryptionKey)\n\tcase *ecdsa.PublicKey:\n\t\treturn newECDHRecipient(alg, encryptionKey)\n\tcase []byte:\n\t\treturn newSymmetricRecipient(alg, encryptionKey)\n\tcase string:\n\t\treturn newSymmetricRecipient(alg, []byte(encryptionKey))\n\tcase JSONWebKey:\n\t\trecipient, err := makeJWERecipient(alg, encryptionKey.Key)\n\t\trecipient.keyID = encryptionKey.KeyID\n\t\treturn recipient, err\n\tcase *JSONWebKey:\n\t\trecipient, err := makeJWERecipient(alg, encryptionKey.Key)\n\t\trecipient.keyID = encryptionKey.KeyID\n\t\treturn recipient, err\n\tcase OpaqueKeyEncrypter:\n\t\treturn newOpaqueKeyEncrypter(alg, encryptionKey)\n\t}\n\treturn recipientKeyInfo{}, ErrUnsupportedKeyType\n}\n\n// newDecrypter creates an appropriate decrypter based on the key type\nfunc newDecrypter(decryptionKey interface{}) (keyDecrypter, error) {\n\tswitch decryptionKey := decryptionKey.(type) {\n\tcase *rsa.PrivateKey:\n\t\treturn &rsaDecrypterSigner{\n\t\t\tprivateKey: decryptionKey,\n\t\t}, nil\n\tcase *ecdsa.PrivateKey:\n\t\treturn &ecDecrypterSigner{\n\t\t\tprivateKey: decryptionKey,\n\t\t}, nil\n\tcase []byte:\n\t\treturn &symmetricKeyCipher{\n\t\t\tkey: decryptionKey,\n\t\t}, nil\n\tcase string:\n\t\treturn &symmetricKeyCipher{\n\t\t\tkey: []byte(decryptionKey),\n\t\t}, nil\n\tcase JSONWebKey:\n\t\treturn newDecrypter(decryptionKey.Key)\n\tcase *JSONWebKey:\n\t\treturn newDecrypter(decryptionKey.Key)\n\tcase OpaqueKeyDecrypter:\n\t\treturn &opaqueKeyDecrypter{decrypter: decryptionKey}, nil\n\tdefault:\n\t\treturn nil, ErrUnsupportedKeyType\n\t}\n}\n\n// Implementation of encrypt method producing a JWE object.\nfunc (ctx *genericEncrypter) Encrypt(plaintext []byte) (*JSONWebEncryption, error) {\n\treturn ctx.EncryptWithAuthData(plaintext, nil)\n}\n\n// Implementation of encrypt method producing a JWE object.\nfunc (ctx *genericEncrypter) EncryptWithAuthData(plaintext, aad []byte) (*JSONWebEncryption, error) {\n\tobj := &JSONWebEncryption{}\n\tobj.aad = aad\n\n\tobj.protected = &rawHeader{}\n\terr := obj.protected.set(headerEncryption, ctx.contentAlg)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tobj.recipients = make([]recipientInfo, len(ctx.recipients))\n\n\tif len(ctx.recipients) == 0 {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: no recipients to encrypt to\")\n\t}\n\n\tcek, headers, err := ctx.keyGenerator.genKey()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tobj.protected.merge(&headers)\n\n\tfor i, info := range ctx.recipients {\n\t\trecipient, err := info.keyEncrypter.encryptKey(cek, info.keyAlg)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\terr = recipient.header.set(headerAlgorithm, info.keyAlg)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif info.keyID != \"\" {\n\t\t\terr = recipient.header.set(headerKeyID, info.keyID)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\tobj.recipients[i] = recipient\n\t}\n\n\tif len(ctx.recipients) == 1 {\n\t\t// Move per-recipient headers into main protected header if there's\n\t\t// only a single recipient.\n\t\tobj.protected.merge(obj.recipients[0].header)\n\t\tobj.recipients[0].header = nil\n\t}\n\n\tif ctx.compressionAlg != NONE {\n\t\tplaintext, err = compress(ctx.compressionAlg, plaintext)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\terr = obj.protected.set(headerCompression, ctx.compressionAlg)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tfor k, v := range ctx.extraHeaders {\n\t\tb, err := json.Marshal(v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t(*obj.protected)[k] = makeRawMessage(b)\n\t}\n\n\tauthData := obj.computeAuthData()\n\tparts, err := ctx.cipher.encrypt(cek, authData, plaintext)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tobj.iv = parts.iv\n\tobj.ciphertext = parts.ciphertext\n\tobj.tag = parts.tag\n\n\treturn obj, nil\n}\n\nfunc (ctx *genericEncrypter) Options() EncrypterOptions {\n\treturn EncrypterOptions{\n\t\tCompression:  ctx.compressionAlg,\n\t\tExtraHeaders: ctx.extraHeaders,\n\t}\n}\n\n// Decrypt and validate the object and return the plaintext. This\n// function does not support multi-recipient. If you desire multi-recipient\n// decryption use DecryptMulti instead.\n//\n// The decryptionKey argument must contain a private or symmetric key\n// and must have one of these types:\n//   - *ecdsa.PrivateKey\n//   - *rsa.PrivateKey\n//   - *JSONWebKey\n//   - JSONWebKey\n//   - *JSONWebKeySet\n//   - JSONWebKeySet\n//   - []byte (a symmetric key)\n//   - string (a symmetric key)\n//   - Any type that satisfies the OpaqueKeyDecrypter interface.\n//\n// Note that ed25519 is only available for signatures, not encryption, so is\n// not an option here.\n//\n// Automatically decompresses plaintext, but returns an error if the decompressed\n// data would be >250kB or >10x the size of the compressed data, whichever is larger.\nfunc (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) {\n\theaders := obj.mergedHeaders(nil)\n\n\tif len(obj.recipients) > 1 {\n\t\treturn nil, errors.New(\"go-jose/go-jose: too many recipients in payload; expecting only one\")\n\t}\n\n\terr := headers.checkNoCritical()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tkey, err := tryJWKS(decryptionKey, obj.Header)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdecrypter, err := newDecrypter(key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcipher := getContentCipher(headers.getEncryption())\n\tif cipher == nil {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: unsupported enc value '%s'\", string(headers.getEncryption()))\n\t}\n\n\tgenerator := randomKeyGenerator{\n\t\tsize: cipher.keySize(),\n\t}\n\n\tparts := &aeadParts{\n\t\tiv:         obj.iv,\n\t\tciphertext: obj.ciphertext,\n\t\ttag:        obj.tag,\n\t}\n\n\tauthData := obj.computeAuthData()\n\n\tvar plaintext []byte\n\trecipient := obj.recipients[0]\n\trecipientHeaders := obj.mergedHeaders(&recipient)\n\n\tcek, err := decrypter.decryptKey(recipientHeaders, &recipient, generator)\n\tif err == nil {\n\t\t// Found a valid CEK -- let's try to decrypt.\n\t\tplaintext, err = cipher.decrypt(cek, authData, parts)\n\t}\n\n\tif plaintext == nil {\n\t\treturn nil, ErrCryptoFailure\n\t}\n\n\t// The \"zip\" header parameter may only be present in the protected header.\n\tif comp := obj.protected.getCompression(); comp != \"\" {\n\t\tplaintext, err = decompress(comp, plaintext)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: failed to decompress plaintext: %v\", err)\n\t\t}\n\t}\n\n\treturn plaintext, nil\n}\n\n// DecryptMulti decrypts and validates the object and returns the plaintexts,\n// with support for multiple recipients. It returns the index of the recipient\n// for which the decryption was successful, the merged headers for that recipient,\n// and the plaintext.\n//\n// The decryptionKey argument must have one of the types allowed for the\n// decryptionKey argument of Decrypt().\n//\n// Automatically decompresses plaintext, but returns an error if the decompressed\n// data would be >250kB or >3x the size of the compressed data, whichever is larger.\nfunc (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Header, []byte, error) {\n\tglobalHeaders := obj.mergedHeaders(nil)\n\n\terr := globalHeaders.checkNoCritical()\n\tif err != nil {\n\t\treturn -1, Header{}, nil, err\n\t}\n\n\tkey, err := tryJWKS(decryptionKey, obj.Header)\n\tif err != nil {\n\t\treturn -1, Header{}, nil, err\n\t}\n\tdecrypter, err := newDecrypter(key)\n\tif err != nil {\n\t\treturn -1, Header{}, nil, err\n\t}\n\n\tencryption := globalHeaders.getEncryption()\n\tcipher := getContentCipher(encryption)\n\tif cipher == nil {\n\t\treturn -1, Header{}, nil, fmt.Errorf(\"go-jose/go-jose: unsupported enc value '%s'\", string(encryption))\n\t}\n\n\tgenerator := randomKeyGenerator{\n\t\tsize: cipher.keySize(),\n\t}\n\n\tparts := &aeadParts{\n\t\tiv:         obj.iv,\n\t\tciphertext: obj.ciphertext,\n\t\ttag:        obj.tag,\n\t}\n\n\tauthData := obj.computeAuthData()\n\n\tindex := -1\n\tvar plaintext []byte\n\tvar headers rawHeader\n\n\tfor i, recipient := range obj.recipients {\n\t\trecipientHeaders := obj.mergedHeaders(&recipient)\n\n\t\tcek, err := decrypter.decryptKey(recipientHeaders, &recipient, generator)\n\t\tif err == nil {\n\t\t\t// Found a valid CEK -- let's try to decrypt.\n\t\t\tplaintext, err = cipher.decrypt(cek, authData, parts)\n\t\t\tif err == nil {\n\t\t\t\tindex = i\n\t\t\t\theaders = recipientHeaders\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tif plaintext == nil {\n\t\treturn -1, Header{}, nil, ErrCryptoFailure\n\t}\n\n\t// The \"zip\" header parameter may only be present in the protected header.\n\tif comp := obj.protected.getCompression(); comp != \"\" {\n\t\tplaintext, err = decompress(comp, plaintext)\n\t\tif err != nil {\n\t\t\treturn -1, Header{}, nil, fmt.Errorf(\"go-jose/go-jose: failed to decompress plaintext: %v\", err)\n\t\t}\n\t}\n\n\tsanitized, err := headers.sanitized()\n\tif err != nil {\n\t\treturn -1, Header{}, nil, fmt.Errorf(\"go-jose/go-jose: failed to sanitize header: %v\", err)\n\t}\n\n\treturn index, sanitized, plaintext, err\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/doc.go",
    "content": "/*-\n * Copyright 2014 Square Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\nPackage jose aims to provide an implementation of the Javascript Object Signing\nand Encryption set of standards. It implements encryption and signing based on\nthe JSON Web Encryption and JSON Web Signature standards, with optional JSON Web\nToken support available in a sub-package. The library supports both the compact\nand JWS/JWE JSON Serialization formats, and has optional support for multiple\nrecipients.\n*/\npackage jose\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/encoding.go",
    "content": "/*-\n * Copyright 2014 Square Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage jose\n\nimport (\n\t\"bytes\"\n\t\"compress/flate\"\n\t\"encoding/base64\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/big\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\"github.com/go-jose/go-jose/v4/json\"\n)\n\n// Helper function to serialize known-good objects.\n// Precondition: value is not a nil pointer.\nfunc mustSerializeJSON(value interface{}) []byte {\n\tout, err := json.Marshal(value)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\t// We never want to serialize the top-level value \"null,\" since it's not a\n\t// valid JOSE message. But if a caller passes in a nil pointer to this method,\n\t// MarshalJSON will happily serialize it as the top-level value \"null\". If\n\t// that value is then embedded in another operation, for instance by being\n\t// base64-encoded and fed as input to a signing algorithm\n\t// (https://github.com/go-jose/go-jose/issues/22), the result will be\n\t// incorrect. Because this method is intended for known-good objects, and a nil\n\t// pointer is not a known-good object, we are free to panic in this case.\n\t// Note: It's not possible to directly check whether the data pointed at by an\n\t// interface is a nil pointer, so we do this hacky workaround.\n\t// https://groups.google.com/forum/#!topic/golang-nuts/wnH302gBa4I\n\tif string(out) == \"null\" {\n\t\tpanic(\"Tried to serialize a nil pointer.\")\n\t}\n\treturn out\n}\n\n// Strip all newlines and whitespace\nfunc stripWhitespace(data string) string {\n\tbuf := strings.Builder{}\n\tbuf.Grow(len(data))\n\tfor _, r := range data {\n\t\tif !unicode.IsSpace(r) {\n\t\t\tbuf.WriteRune(r)\n\t\t}\n\t}\n\treturn buf.String()\n}\n\n// Perform compression based on algorithm\nfunc compress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) {\n\tswitch algorithm {\n\tcase DEFLATE:\n\t\treturn deflate(input)\n\tdefault:\n\t\treturn nil, ErrUnsupportedAlgorithm\n\t}\n}\n\n// Perform decompression based on algorithm\nfunc decompress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) {\n\tswitch algorithm {\n\tcase DEFLATE:\n\t\treturn inflate(input)\n\tdefault:\n\t\treturn nil, ErrUnsupportedAlgorithm\n\t}\n}\n\n// deflate compresses the input.\nfunc deflate(input []byte) ([]byte, error) {\n\toutput := new(bytes.Buffer)\n\n\t// Writing to byte buffer, err is always nil\n\twriter, _ := flate.NewWriter(output, 1)\n\t_, _ = io.Copy(writer, bytes.NewBuffer(input))\n\n\terr := writer.Close()\n\treturn output.Bytes(), err\n}\n\n// inflate decompresses the input.\n//\n// Errors if the decompressed data would be >250kB or >10x the size of the\n// compressed data, whichever is larger.\nfunc inflate(input []byte) ([]byte, error) {\n\toutput := new(bytes.Buffer)\n\treader := flate.NewReader(bytes.NewBuffer(input))\n\n\tmaxCompressedSize := max(250_000, 10*int64(len(input)))\n\n\tlimit := maxCompressedSize + 1\n\tn, err := io.CopyN(output, reader, limit)\n\tif err != nil && err != io.EOF {\n\t\treturn nil, err\n\t}\n\tif n == limit {\n\t\treturn nil, fmt.Errorf(\"uncompressed data would be too large (>%d bytes)\", maxCompressedSize)\n\t}\n\n\terr = reader.Close()\n\treturn output.Bytes(), err\n}\n\n// byteBuffer represents a slice of bytes that can be serialized to url-safe base64.\ntype byteBuffer struct {\n\tdata []byte\n}\n\nfunc newBuffer(data []byte) *byteBuffer {\n\tif data == nil {\n\t\treturn nil\n\t}\n\treturn &byteBuffer{\n\t\tdata: data,\n\t}\n}\n\nfunc newFixedSizeBuffer(data []byte, length int) *byteBuffer {\n\tif len(data) > length {\n\t\tpanic(\"go-jose/go-jose: invalid call to newFixedSizeBuffer (len(data) > length)\")\n\t}\n\tpad := make([]byte, length-len(data))\n\treturn newBuffer(append(pad, data...))\n}\n\nfunc newBufferFromInt(num uint64) *byteBuffer {\n\tdata := make([]byte, 8)\n\tbinary.BigEndian.PutUint64(data, num)\n\treturn newBuffer(bytes.TrimLeft(data, \"\\x00\"))\n}\n\nfunc (b *byteBuffer) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(b.base64())\n}\n\nfunc (b *byteBuffer) UnmarshalJSON(data []byte) error {\n\tvar encoded string\n\terr := json.Unmarshal(data, &encoded)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif encoded == \"\" {\n\t\treturn nil\n\t}\n\n\tdecoded, err := base64.RawURLEncoding.DecodeString(encoded)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*b = *newBuffer(decoded)\n\n\treturn nil\n}\n\nfunc (b *byteBuffer) base64() string {\n\treturn base64.RawURLEncoding.EncodeToString(b.data)\n}\n\nfunc (b *byteBuffer) bytes() []byte {\n\t// Handling nil here allows us to transparently handle nil slices when serializing.\n\tif b == nil {\n\t\treturn nil\n\t}\n\treturn b.data\n}\n\nfunc (b byteBuffer) bigInt() *big.Int {\n\treturn new(big.Int).SetBytes(b.data)\n}\n\nfunc (b byteBuffer) toInt() int {\n\treturn int(b.bigInt().Int64())\n}\n\nfunc base64EncodeLen(sl []byte) int {\n\treturn base64.RawURLEncoding.EncodedLen(len(sl))\n}\n\nfunc base64JoinWithDots(inputs ...[]byte) string {\n\tif len(inputs) == 0 {\n\t\treturn \"\"\n\t}\n\n\t// Count of dots.\n\ttotalCount := len(inputs) - 1\n\n\tfor _, input := range inputs {\n\t\ttotalCount += base64EncodeLen(input)\n\t}\n\n\tout := make([]byte, totalCount)\n\tstartEncode := 0\n\tfor i, input := range inputs {\n\t\tbase64.RawURLEncoding.Encode(out[startEncode:], input)\n\n\t\tif i == len(inputs)-1 {\n\t\t\tcontinue\n\t\t}\n\n\t\tstartEncode += base64EncodeLen(input)\n\t\tout[startEncode] = '.'\n\t\tstartEncode++\n\t}\n\n\treturn string(out)\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/json/LICENSE",
    "content": "Copyright (c) 2012 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(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": "vendor/github.com/go-jose/go-jose/v4/json/README.md",
    "content": "# Safe JSON\n\nThis repository contains a fork of the `encoding/json` package from Go 1.6.\n\nThe following changes were made:\n\n* Object deserialization uses case-sensitive member name matching instead of\n  [case-insensitive matching](https://www.ietf.org/mail-archive/web/json/current/msg03763.html).\n  This is to avoid differences in the interpretation of JOSE messages between\n  go-jose and libraries written in other languages.\n* When deserializing a JSON object, we check for duplicate keys and reject the\n  input whenever we detect a duplicate. Rather than trying to work with malformed\n  data, we prefer to reject it right away.\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/json/decode.go",
    "content": "// Copyright 2010 The Go 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\n// Represents JSON data structure using native Go types: booleans, floats,\n// strings, arrays, and maps.\n\npackage json\n\nimport (\n\t\"bytes\"\n\t\"encoding\"\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"reflect\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"unicode\"\n\t\"unicode/utf16\"\n\t\"unicode/utf8\"\n)\n\n// Unmarshal parses the JSON-encoded data and stores the result\n// in the value pointed to by v.\n//\n// Unmarshal uses the inverse of the encodings that\n// Marshal uses, allocating maps, slices, and pointers as necessary,\n// with the following additional rules:\n//\n// To unmarshal JSON into a pointer, Unmarshal first handles the case of\n// the JSON being the JSON literal null.  In that case, Unmarshal sets\n// the pointer to nil.  Otherwise, Unmarshal unmarshals the JSON into\n// the value pointed at by the pointer.  If the pointer is nil, Unmarshal\n// allocates a new value for it to point to.\n//\n// To unmarshal JSON into a struct, Unmarshal matches incoming object\n// keys to the keys used by Marshal (either the struct field name or its tag),\n// preferring an exact match but also accepting a case-insensitive match.\n// Unmarshal will only set exported fields of the struct.\n//\n// To unmarshal JSON into an interface value,\n// Unmarshal stores one of these in the interface value:\n//\n//\tbool, for JSON booleans\n//\tfloat64, for JSON numbers\n//\tstring, for JSON strings\n//\t[]interface{}, for JSON arrays\n//\tmap[string]interface{}, for JSON objects\n//\tnil for JSON null\n//\n// To unmarshal a JSON array into a slice, Unmarshal resets the slice length\n// to zero and then appends each element to the slice.\n// As a special case, to unmarshal an empty JSON array into a slice,\n// Unmarshal replaces the slice with a new empty slice.\n//\n// To unmarshal a JSON array into a Go array, Unmarshal decodes\n// JSON array elements into corresponding Go array elements.\n// If the Go array is smaller than the JSON array,\n// the additional JSON array elements are discarded.\n// If the JSON array is smaller than the Go array,\n// the additional Go array elements are set to zero values.\n//\n// To unmarshal a JSON object into a string-keyed map, Unmarshal first\n// establishes a map to use, If the map is nil, Unmarshal allocates a new map.\n// Otherwise Unmarshal reuses the existing map, keeping existing entries.\n// Unmarshal then stores key-value pairs from the JSON object into the map.\n//\n// If a JSON value is not appropriate for a given target type,\n// or if a JSON number overflows the target type, Unmarshal\n// skips that field and completes the unmarshaling as best it can.\n// If no more serious errors are encountered, Unmarshal returns\n// an UnmarshalTypeError describing the earliest such error.\n//\n// The JSON null value unmarshals into an interface, map, pointer, or slice\n// by setting that Go value to nil. Because null is often used in JSON to mean\n// “not present,” unmarshaling a JSON null into any other Go type has no effect\n// on the value and produces no error.\n//\n// When unmarshaling quoted strings, invalid UTF-8 or\n// invalid UTF-16 surrogate pairs are not treated as an error.\n// Instead, they are replaced by the Unicode replacement\n// character U+FFFD.\nfunc Unmarshal(data []byte, v interface{}) error {\n\t// Check for well-formedness.\n\t// Avoids filling out half a data structure\n\t// before discovering a JSON syntax error.\n\tvar d decodeState\n\terr := checkValid(data, &d.scan)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\td.init(data)\n\treturn d.unmarshal(v)\n}\n\n// Unmarshaler is the interface implemented by objects\n// that can unmarshal a JSON description of themselves.\n// The input can be assumed to be a valid encoding of\n// a JSON value. UnmarshalJSON must copy the JSON data\n// if it wishes to retain the data after returning.\ntype Unmarshaler interface {\n\tUnmarshalJSON([]byte) error\n}\n\n// An UnmarshalTypeError describes a JSON value that was\n// not appropriate for a value of a specific Go type.\ntype UnmarshalTypeError struct {\n\tValue  string       // description of JSON value - \"bool\", \"array\", \"number -5\"\n\tType   reflect.Type // type of Go value it could not be assigned to\n\tOffset int64        // error occurred after reading Offset bytes\n}\n\nfunc (e *UnmarshalTypeError) Error() string {\n\treturn \"json: cannot unmarshal \" + e.Value + \" into Go value of type \" + e.Type.String()\n}\n\n// An UnmarshalFieldError describes a JSON object key that\n// led to an unexported (and therefore unwritable) struct field.\n// (No longer used; kept for compatibility.)\ntype UnmarshalFieldError struct {\n\tKey   string\n\tType  reflect.Type\n\tField reflect.StructField\n}\n\nfunc (e *UnmarshalFieldError) Error() string {\n\treturn \"json: cannot unmarshal object key \" + strconv.Quote(e.Key) + \" into unexported field \" + e.Field.Name + \" of type \" + e.Type.String()\n}\n\n// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.\n// (The argument to Unmarshal must be a non-nil pointer.)\ntype InvalidUnmarshalError struct {\n\tType reflect.Type\n}\n\nfunc (e *InvalidUnmarshalError) Error() string {\n\tif e.Type == nil {\n\t\treturn \"json: Unmarshal(nil)\"\n\t}\n\n\tif e.Type.Kind() != reflect.Ptr {\n\t\treturn \"json: Unmarshal(non-pointer \" + e.Type.String() + \")\"\n\t}\n\treturn \"json: Unmarshal(nil \" + e.Type.String() + \")\"\n}\n\nfunc (d *decodeState) unmarshal(v interface{}) (err error) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tif _, ok := r.(runtime.Error); ok {\n\t\t\t\tpanic(r)\n\t\t\t}\n\t\t\terr = r.(error)\n\t\t}\n\t}()\n\n\trv := reflect.ValueOf(v)\n\tif rv.Kind() != reflect.Ptr || rv.IsNil() {\n\t\treturn &InvalidUnmarshalError{reflect.TypeOf(v)}\n\t}\n\n\td.scan.reset()\n\t// We decode rv not rv.Elem because the Unmarshaler interface\n\t// test must be applied at the top level of the value.\n\td.value(rv)\n\treturn d.savedError\n}\n\n// A Number represents a JSON number literal.\ntype Number string\n\n// String returns the literal text of the number.\nfunc (n Number) String() string { return string(n) }\n\n// Float64 returns the number as a float64.\nfunc (n Number) Float64() (float64, error) {\n\treturn strconv.ParseFloat(string(n), 64)\n}\n\n// Int64 returns the number as an int64.\nfunc (n Number) Int64() (int64, error) {\n\treturn strconv.ParseInt(string(n), 10, 64)\n}\n\n// isValidNumber reports whether s is a valid JSON number literal.\nfunc isValidNumber(s string) bool {\n\t// This function implements the JSON numbers grammar.\n\t// See https://tools.ietf.org/html/rfc7159#section-6\n\t// and http://json.org/number.gif\n\n\tif s == \"\" {\n\t\treturn false\n\t}\n\n\t// Optional -\n\tif s[0] == '-' {\n\t\ts = s[1:]\n\t\tif s == \"\" {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// Digits\n\tswitch {\n\tdefault:\n\t\treturn false\n\n\tcase s[0] == '0':\n\t\ts = s[1:]\n\n\tcase '1' <= s[0] && s[0] <= '9':\n\t\ts = s[1:]\n\t\tfor len(s) > 0 && '0' <= s[0] && s[0] <= '9' {\n\t\t\ts = s[1:]\n\t\t}\n\t}\n\n\t// . followed by 1 or more digits.\n\tif len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' {\n\t\ts = s[2:]\n\t\tfor len(s) > 0 && '0' <= s[0] && s[0] <= '9' {\n\t\t\ts = s[1:]\n\t\t}\n\t}\n\n\t// e or E followed by an optional - or + and\n\t// 1 or more digits.\n\tif len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {\n\t\ts = s[1:]\n\t\tif s[0] == '+' || s[0] == '-' {\n\t\t\ts = s[1:]\n\t\t\tif s == \"\" {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tfor len(s) > 0 && '0' <= s[0] && s[0] <= '9' {\n\t\t\ts = s[1:]\n\t\t}\n\t}\n\n\t// Make sure we are at the end.\n\treturn s == \"\"\n}\n\ntype NumberUnmarshalType int\n\nconst (\n\t// unmarshal a JSON number into an interface{} as a float64\n\tUnmarshalFloat NumberUnmarshalType = iota\n\t// unmarshal a JSON number into an interface{} as a `json.Number`\n\tUnmarshalJSONNumber\n\t// unmarshal a JSON number into an interface{} as a int64\n\t// if value is an integer otherwise float64\n\tUnmarshalIntOrFloat\n)\n\n// decodeState represents the state while decoding a JSON value.\ntype decodeState struct {\n\tdata       []byte\n\toff        int // read offset in data\n\tscan       scanner\n\tnextscan   scanner // for calls to nextValue\n\tsavedError error\n\tnumberType NumberUnmarshalType\n}\n\n// errPhase is used for errors that should not happen unless\n// there is a bug in the JSON decoder or something is editing\n// the data slice while the decoder executes.\nvar errPhase = errors.New(\"JSON decoder out of sync - data changing underfoot?\")\n\nfunc (d *decodeState) init(data []byte) *decodeState {\n\td.data = data\n\td.off = 0\n\td.savedError = nil\n\treturn d\n}\n\n// error aborts the decoding by panicking with err.\nfunc (d *decodeState) error(err error) {\n\tpanic(err)\n}\n\n// saveError saves the first err it is called with,\n// for reporting at the end of the unmarshal.\nfunc (d *decodeState) saveError(err error) {\n\tif d.savedError == nil {\n\t\td.savedError = err\n\t}\n}\n\n// next cuts off and returns the next full JSON value in d.data[d.off:].\n// The next value is known to be an object or array, not a literal.\nfunc (d *decodeState) next() []byte {\n\tc := d.data[d.off]\n\titem, rest, err := nextValue(d.data[d.off:], &d.nextscan)\n\tif err != nil {\n\t\td.error(err)\n\t}\n\td.off = len(d.data) - len(rest)\n\n\t// Our scanner has seen the opening brace/bracket\n\t// and thinks we're still in the middle of the object.\n\t// invent a closing brace/bracket to get it out.\n\tif c == '{' {\n\t\td.scan.step(&d.scan, '}')\n\t} else {\n\t\td.scan.step(&d.scan, ']')\n\t}\n\n\treturn item\n}\n\n// scanWhile processes bytes in d.data[d.off:] until it\n// receives a scan code not equal to op.\n// It updates d.off and returns the new scan code.\nfunc (d *decodeState) scanWhile(op int) int {\n\tvar newOp int\n\tfor {\n\t\tif d.off >= len(d.data) {\n\t\t\tnewOp = d.scan.eof()\n\t\t\td.off = len(d.data) + 1 // mark processed EOF with len+1\n\t\t} else {\n\t\t\tc := d.data[d.off]\n\t\t\td.off++\n\t\t\tnewOp = d.scan.step(&d.scan, c)\n\t\t}\n\t\tif newOp != op {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn newOp\n}\n\n// value decodes a JSON value from d.data[d.off:] into the value.\n// it updates d.off to point past the decoded value.\nfunc (d *decodeState) value(v reflect.Value) {\n\tif !v.IsValid() {\n\t\t_, rest, err := nextValue(d.data[d.off:], &d.nextscan)\n\t\tif err != nil {\n\t\t\td.error(err)\n\t\t}\n\t\td.off = len(d.data) - len(rest)\n\n\t\t// d.scan thinks we're still at the beginning of the item.\n\t\t// Feed in an empty string - the shortest, simplest value -\n\t\t// so that it knows we got to the end of the value.\n\t\tif d.scan.redo {\n\t\t\t// rewind.\n\t\t\td.scan.redo = false\n\t\t\td.scan.step = stateBeginValue\n\t\t}\n\t\td.scan.step(&d.scan, '\"')\n\t\td.scan.step(&d.scan, '\"')\n\n\t\tn := len(d.scan.parseState)\n\t\tif n > 0 && d.scan.parseState[n-1] == parseObjectKey {\n\t\t\t// d.scan thinks we just read an object key; finish the object\n\t\t\td.scan.step(&d.scan, ':')\n\t\t\td.scan.step(&d.scan, '\"')\n\t\t\td.scan.step(&d.scan, '\"')\n\t\t\td.scan.step(&d.scan, '}')\n\t\t}\n\n\t\treturn\n\t}\n\n\tswitch op := d.scanWhile(scanSkipSpace); op {\n\tdefault:\n\t\td.error(errPhase)\n\n\tcase scanBeginArray:\n\t\td.array(v)\n\n\tcase scanBeginObject:\n\t\td.object(v)\n\n\tcase scanBeginLiteral:\n\t\td.literal(v)\n\t}\n}\n\ntype unquotedValue struct{}\n\n// valueQuoted is like value but decodes a\n// quoted string literal or literal null into an interface value.\n// If it finds anything other than a quoted string literal or null,\n// valueQuoted returns unquotedValue{}.\nfunc (d *decodeState) valueQuoted() interface{} {\n\tswitch op := d.scanWhile(scanSkipSpace); op {\n\tdefault:\n\t\td.error(errPhase)\n\n\tcase scanBeginArray:\n\t\td.array(reflect.Value{})\n\n\tcase scanBeginObject:\n\t\td.object(reflect.Value{})\n\n\tcase scanBeginLiteral:\n\t\tswitch v := d.literalInterface().(type) {\n\t\tcase nil, string:\n\t\t\treturn v\n\t\t}\n\t}\n\treturn unquotedValue{}\n}\n\n// indirect walks down v allocating pointers as needed,\n// until it gets to a non-pointer.\n// if it encounters an Unmarshaler, indirect stops and returns that.\n// if decodingNull is true, indirect stops at the last pointer so it can be set to nil.\nfunc (d *decodeState) indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {\n\t// If v is a named type and is addressable,\n\t// start with its address, so that if the type has pointer methods,\n\t// we find them.\n\tif v.Kind() != reflect.Ptr && v.Type().Name() != \"\" && v.CanAddr() {\n\t\tv = v.Addr()\n\t}\n\tfor {\n\t\t// Load value from interface, but only if the result will be\n\t\t// usefully addressable.\n\t\tif v.Kind() == reflect.Interface && !v.IsNil() {\n\t\t\te := v.Elem()\n\t\t\tif e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {\n\t\t\t\tv = e\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tif v.Kind() != reflect.Ptr {\n\t\t\tbreak\n\t\t}\n\n\t\tif v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() {\n\t\t\tbreak\n\t\t}\n\t\tif v.IsNil() {\n\t\t\tv.Set(reflect.New(v.Type().Elem()))\n\t\t}\n\t\tif v.Type().NumMethod() > 0 {\n\t\t\tif u, ok := v.Interface().(Unmarshaler); ok {\n\t\t\t\treturn u, nil, reflect.Value{}\n\t\t\t}\n\t\t\tif u, ok := v.Interface().(encoding.TextUnmarshaler); ok {\n\t\t\t\treturn nil, u, reflect.Value{}\n\t\t\t}\n\t\t}\n\t\tv = v.Elem()\n\t}\n\treturn nil, nil, v\n}\n\n// array consumes an array from d.data[d.off-1:], decoding into the value v.\n// the first byte of the array ('[') has been read already.\nfunc (d *decodeState) array(v reflect.Value) {\n\t// Check for unmarshaler.\n\tu, ut, pv := d.indirect(v, false)\n\tif u != nil {\n\t\td.off--\n\t\terr := u.UnmarshalJSON(d.next())\n\t\tif err != nil {\n\t\t\td.error(err)\n\t\t}\n\t\treturn\n\t}\n\tif ut != nil {\n\t\td.saveError(&UnmarshalTypeError{\"array\", v.Type(), int64(d.off)})\n\t\td.off--\n\t\td.next()\n\t\treturn\n\t}\n\n\tv = pv\n\n\t// Check type of target.\n\tswitch v.Kind() {\n\tcase reflect.Interface:\n\t\tif v.NumMethod() == 0 {\n\t\t\t// Decoding into nil interface?  Switch to non-reflect code.\n\t\t\tv.Set(reflect.ValueOf(d.arrayInterface()))\n\t\t\treturn\n\t\t}\n\t\t// Otherwise it's invalid.\n\t\tfallthrough\n\tdefault:\n\t\td.saveError(&UnmarshalTypeError{\"array\", v.Type(), int64(d.off)})\n\t\td.off--\n\t\td.next()\n\t\treturn\n\tcase reflect.Array:\n\tcase reflect.Slice:\n\t\tbreak\n\t}\n\n\ti := 0\n\tfor {\n\t\t// Look ahead for ] - can only happen on first iteration.\n\t\top := d.scanWhile(scanSkipSpace)\n\t\tif op == scanEndArray {\n\t\t\tbreak\n\t\t}\n\n\t\t// Back up so d.value can have the byte we just read.\n\t\td.off--\n\t\td.scan.undo(op)\n\n\t\t// Get element of array, growing if necessary.\n\t\tif v.Kind() == reflect.Slice {\n\t\t\t// Grow slice if necessary\n\t\t\tif i >= v.Cap() {\n\t\t\t\tnewcap := v.Cap() + v.Cap()/2\n\t\t\t\tif newcap < 4 {\n\t\t\t\t\tnewcap = 4\n\t\t\t\t}\n\t\t\t\tnewv := reflect.MakeSlice(v.Type(), v.Len(), newcap)\n\t\t\t\treflect.Copy(newv, v)\n\t\t\t\tv.Set(newv)\n\t\t\t}\n\t\t\tif i >= v.Len() {\n\t\t\t\tv.SetLen(i + 1)\n\t\t\t}\n\t\t}\n\n\t\tif i < v.Len() {\n\t\t\t// Decode into element.\n\t\t\td.value(v.Index(i))\n\t\t} else {\n\t\t\t// Ran out of fixed array: skip.\n\t\t\td.value(reflect.Value{})\n\t\t}\n\t\ti++\n\n\t\t// Next token must be , or ].\n\t\top = d.scanWhile(scanSkipSpace)\n\t\tif op == scanEndArray {\n\t\t\tbreak\n\t\t}\n\t\tif op != scanArrayValue {\n\t\t\td.error(errPhase)\n\t\t}\n\t}\n\n\tif i < v.Len() {\n\t\tif v.Kind() == reflect.Array {\n\t\t\t// Array.  Zero the rest.\n\t\t\tz := reflect.Zero(v.Type().Elem())\n\t\t\tfor ; i < v.Len(); i++ {\n\t\t\t\tv.Index(i).Set(z)\n\t\t\t}\n\t\t} else {\n\t\t\tv.SetLen(i)\n\t\t}\n\t}\n\tif i == 0 && v.Kind() == reflect.Slice {\n\t\tv.Set(reflect.MakeSlice(v.Type(), 0, 0))\n\t}\n}\n\nvar nullLiteral = []byte(\"null\")\n\n// object consumes an object from d.data[d.off-1:], decoding into the value v.\n// the first byte ('{') of the object has been read already.\nfunc (d *decodeState) object(v reflect.Value) {\n\t// Check for unmarshaler.\n\tu, ut, pv := d.indirect(v, false)\n\tif u != nil {\n\t\td.off--\n\t\terr := u.UnmarshalJSON(d.next())\n\t\tif err != nil {\n\t\t\td.error(err)\n\t\t}\n\t\treturn\n\t}\n\tif ut != nil {\n\t\td.saveError(&UnmarshalTypeError{\"object\", v.Type(), int64(d.off)})\n\t\td.off--\n\t\td.next() // skip over { } in input\n\t\treturn\n\t}\n\tv = pv\n\n\t// Decoding into nil interface?  Switch to non-reflect code.\n\tif v.Kind() == reflect.Interface && v.NumMethod() == 0 {\n\t\tv.Set(reflect.ValueOf(d.objectInterface()))\n\t\treturn\n\t}\n\n\t// Check type of target: struct or map[string]T\n\tswitch v.Kind() {\n\tcase reflect.Map:\n\t\t// map must have string kind\n\t\tt := v.Type()\n\t\tif t.Key().Kind() != reflect.String {\n\t\t\td.saveError(&UnmarshalTypeError{\"object\", v.Type(), int64(d.off)})\n\t\t\td.off--\n\t\t\td.next() // skip over { } in input\n\t\t\treturn\n\t\t}\n\t\tif v.IsNil() {\n\t\t\tv.Set(reflect.MakeMap(t))\n\t\t}\n\tcase reflect.Struct:\n\n\tdefault:\n\t\td.saveError(&UnmarshalTypeError{\"object\", v.Type(), int64(d.off)})\n\t\td.off--\n\t\td.next() // skip over { } in input\n\t\treturn\n\t}\n\n\tvar mapElem reflect.Value\n\tkeys := map[string]bool{}\n\n\tfor {\n\t\t// Read opening \" of string key or closing }.\n\t\top := d.scanWhile(scanSkipSpace)\n\t\tif op == scanEndObject {\n\t\t\t// closing } - can only happen on first iteration.\n\t\t\tbreak\n\t\t}\n\t\tif op != scanBeginLiteral {\n\t\t\td.error(errPhase)\n\t\t}\n\n\t\t// Read key.\n\t\tstart := d.off - 1\n\t\top = d.scanWhile(scanContinue)\n\t\titem := d.data[start : d.off-1]\n\t\tkey, ok := unquote(item)\n\t\tif !ok {\n\t\t\td.error(errPhase)\n\t\t}\n\n\t\t// Check for duplicate keys.\n\t\t_, ok = keys[key]\n\t\tif !ok {\n\t\t\tkeys[key] = true\n\t\t} else {\n\t\t\td.error(fmt.Errorf(\"json: duplicate key '%s' in object\", key))\n\t\t}\n\n\t\t// Figure out field corresponding to key.\n\t\tvar subv reflect.Value\n\t\tdestring := false // whether the value is wrapped in a string to be decoded first\n\n\t\tif v.Kind() == reflect.Map {\n\t\t\telemType := v.Type().Elem()\n\t\t\tif !mapElem.IsValid() {\n\t\t\t\tmapElem = reflect.New(elemType).Elem()\n\t\t\t} else {\n\t\t\t\tmapElem.Set(reflect.Zero(elemType))\n\t\t\t}\n\t\t\tsubv = mapElem\n\t\t} else {\n\t\t\tvar f *field\n\t\t\tfields := cachedTypeFields(v.Type())\n\t\t\tfor i := range fields {\n\t\t\t\tff := &fields[i]\n\t\t\t\tif bytes.Equal(ff.nameBytes, []byte(key)) {\n\t\t\t\t\tf = ff\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif f != nil {\n\t\t\t\tsubv = v\n\t\t\t\tdestring = f.quoted\n\t\t\t\tfor _, i := range f.index {\n\t\t\t\t\tif subv.Kind() == reflect.Ptr {\n\t\t\t\t\t\tif subv.IsNil() {\n\t\t\t\t\t\t\tsubv.Set(reflect.New(subv.Type().Elem()))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsubv = subv.Elem()\n\t\t\t\t\t}\n\t\t\t\t\tsubv = subv.Field(i)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Read : before value.\n\t\tif op == scanSkipSpace {\n\t\t\top = d.scanWhile(scanSkipSpace)\n\t\t}\n\t\tif op != scanObjectKey {\n\t\t\td.error(errPhase)\n\t\t}\n\n\t\t// Read value.\n\t\tif destring {\n\t\t\tswitch qv := d.valueQuoted().(type) {\n\t\t\tcase nil:\n\t\t\t\td.literalStore(nullLiteral, subv, false)\n\t\t\tcase string:\n\t\t\t\td.literalStore([]byte(qv), subv, true)\n\t\t\tdefault:\n\t\t\t\td.saveError(fmt.Errorf(\"json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v\", subv.Type()))\n\t\t\t}\n\t\t} else {\n\t\t\td.value(subv)\n\t\t}\n\n\t\t// Write value back to map;\n\t\t// if using struct, subv points into struct already.\n\t\tif v.Kind() == reflect.Map {\n\t\t\tkv := reflect.ValueOf(key).Convert(v.Type().Key())\n\t\t\tv.SetMapIndex(kv, subv)\n\t\t}\n\n\t\t// Next token must be , or }.\n\t\top = d.scanWhile(scanSkipSpace)\n\t\tif op == scanEndObject {\n\t\t\tbreak\n\t\t}\n\t\tif op != scanObjectValue {\n\t\t\td.error(errPhase)\n\t\t}\n\t}\n}\n\n// literal consumes a literal from d.data[d.off-1:], decoding into the value v.\n// The first byte of the literal has been read already\n// (that's how the caller knows it's a literal).\nfunc (d *decodeState) literal(v reflect.Value) {\n\t// All bytes inside literal return scanContinue op code.\n\tstart := d.off - 1\n\top := d.scanWhile(scanContinue)\n\n\t// Scan read one byte too far; back up.\n\td.off--\n\td.scan.undo(op)\n\n\td.literalStore(d.data[start:d.off], v, false)\n}\n\n// convertNumber converts the number literal s to a float64, int64 or a Number\n// depending on d.numberDecodeType.\nfunc (d *decodeState) convertNumber(s string) (interface{}, error) {\n\tswitch d.numberType {\n\n\tcase UnmarshalJSONNumber:\n\t\treturn Number(s), nil\n\tcase UnmarshalIntOrFloat:\n\t\tv, err := strconv.ParseInt(s, 10, 64)\n\t\tif err == nil {\n\t\t\treturn v, nil\n\t\t}\n\n\t\t// tries to parse integer number in scientific notation\n\t\tf, err := strconv.ParseFloat(s, 64)\n\t\tif err != nil {\n\t\t\treturn nil, &UnmarshalTypeError{\"number \" + s, reflect.TypeOf(0.0), int64(d.off)}\n\t\t}\n\n\t\t// if it has no decimal value use int64\n\t\tif fi, fd := math.Modf(f); fd == 0.0 {\n\t\t\treturn int64(fi), nil\n\t\t}\n\t\treturn f, nil\n\tdefault:\n\t\tf, err := strconv.ParseFloat(s, 64)\n\t\tif err != nil {\n\t\t\treturn nil, &UnmarshalTypeError{\"number \" + s, reflect.TypeOf(0.0), int64(d.off)}\n\t\t}\n\t\treturn f, nil\n\t}\n\n}\n\nvar numberType = reflect.TypeOf(Number(\"\"))\n\n// literalStore decodes a literal stored in item into v.\n//\n// fromQuoted indicates whether this literal came from unwrapping a\n// string from the \",string\" struct tag option. this is used only to\n// produce more helpful error messages.\nfunc (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool) {\n\t// Check for unmarshaler.\n\tif len(item) == 0 {\n\t\t//Empty string given\n\t\td.saveError(fmt.Errorf(\"json: invalid use of ,string struct tag, trying to unmarshal %q into %v\", item, v.Type()))\n\t\treturn\n\t}\n\twantptr := item[0] == 'n' // null\n\tu, ut, pv := d.indirect(v, wantptr)\n\tif u != nil {\n\t\terr := u.UnmarshalJSON(item)\n\t\tif err != nil {\n\t\t\td.error(err)\n\t\t}\n\t\treturn\n\t}\n\tif ut != nil {\n\t\tif item[0] != '\"' {\n\t\t\tif fromQuoted {\n\t\t\t\td.saveError(fmt.Errorf(\"json: invalid use of ,string struct tag, trying to unmarshal %q into %v\", item, v.Type()))\n\t\t\t} else {\n\t\t\t\td.saveError(&UnmarshalTypeError{\"string\", v.Type(), int64(d.off)})\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\ts, ok := unquoteBytes(item)\n\t\tif !ok {\n\t\t\tif fromQuoted {\n\t\t\t\td.error(fmt.Errorf(\"json: invalid use of ,string struct tag, trying to unmarshal %q into %v\", item, v.Type()))\n\t\t\t} else {\n\t\t\t\td.error(errPhase)\n\t\t\t}\n\t\t}\n\t\terr := ut.UnmarshalText(s)\n\t\tif err != nil {\n\t\t\td.error(err)\n\t\t}\n\t\treturn\n\t}\n\n\tv = pv\n\n\tswitch c := item[0]; c {\n\tcase 'n': // null\n\t\tswitch v.Kind() {\n\t\tcase reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:\n\t\t\tv.Set(reflect.Zero(v.Type()))\n\t\t\t// otherwise, ignore null for primitives/string\n\t\t}\n\tcase 't', 'f': // true, false\n\t\tvalue := c == 't'\n\t\tswitch v.Kind() {\n\t\tdefault:\n\t\t\tif fromQuoted {\n\t\t\t\td.saveError(fmt.Errorf(\"json: invalid use of ,string struct tag, trying to unmarshal %q into %v\", item, v.Type()))\n\t\t\t} else {\n\t\t\t\td.saveError(&UnmarshalTypeError{\"bool\", v.Type(), int64(d.off)})\n\t\t\t}\n\t\tcase reflect.Bool:\n\t\t\tv.SetBool(value)\n\t\tcase reflect.Interface:\n\t\t\tif v.NumMethod() == 0 {\n\t\t\t\tv.Set(reflect.ValueOf(value))\n\t\t\t} else {\n\t\t\t\td.saveError(&UnmarshalTypeError{\"bool\", v.Type(), int64(d.off)})\n\t\t\t}\n\t\t}\n\n\tcase '\"': // string\n\t\ts, ok := unquoteBytes(item)\n\t\tif !ok {\n\t\t\tif fromQuoted {\n\t\t\t\td.error(fmt.Errorf(\"json: invalid use of ,string struct tag, trying to unmarshal %q into %v\", item, v.Type()))\n\t\t\t} else {\n\t\t\t\td.error(errPhase)\n\t\t\t}\n\t\t}\n\t\tswitch v.Kind() {\n\t\tdefault:\n\t\t\td.saveError(&UnmarshalTypeError{\"string\", v.Type(), int64(d.off)})\n\t\tcase reflect.Slice:\n\t\t\tif v.Type().Elem().Kind() != reflect.Uint8 {\n\t\t\t\td.saveError(&UnmarshalTypeError{\"string\", v.Type(), int64(d.off)})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tb := make([]byte, base64.StdEncoding.DecodedLen(len(s)))\n\t\t\tn, err := base64.StdEncoding.Decode(b, s)\n\t\t\tif err != nil {\n\t\t\t\td.saveError(err)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tv.SetBytes(b[:n])\n\t\tcase reflect.String:\n\t\t\tv.SetString(string(s))\n\t\tcase reflect.Interface:\n\t\t\tif v.NumMethod() == 0 {\n\t\t\t\tv.Set(reflect.ValueOf(string(s)))\n\t\t\t} else {\n\t\t\t\td.saveError(&UnmarshalTypeError{\"string\", v.Type(), int64(d.off)})\n\t\t\t}\n\t\t}\n\n\tdefault: // number\n\t\tif c != '-' && (c < '0' || c > '9') {\n\t\t\tif fromQuoted {\n\t\t\t\td.error(fmt.Errorf(\"json: invalid use of ,string struct tag, trying to unmarshal %q into %v\", item, v.Type()))\n\t\t\t} else {\n\t\t\t\td.error(errPhase)\n\t\t\t}\n\t\t}\n\t\ts := string(item)\n\t\tswitch v.Kind() {\n\t\tdefault:\n\t\t\tif v.Kind() == reflect.String && v.Type() == numberType {\n\t\t\t\tv.SetString(s)\n\t\t\t\tif !isValidNumber(s) {\n\t\t\t\t\td.error(fmt.Errorf(\"json: invalid number literal, trying to unmarshal %q into Number\", item))\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif fromQuoted {\n\t\t\t\td.error(fmt.Errorf(\"json: invalid use of ,string struct tag, trying to unmarshal %q into %v\", item, v.Type()))\n\t\t\t} else {\n\t\t\t\td.error(&UnmarshalTypeError{\"number\", v.Type(), int64(d.off)})\n\t\t\t}\n\t\tcase reflect.Interface:\n\t\t\tn, err := d.convertNumber(s)\n\t\t\tif err != nil {\n\t\t\t\td.saveError(err)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif v.NumMethod() != 0 {\n\t\t\t\td.saveError(&UnmarshalTypeError{\"number\", v.Type(), int64(d.off)})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tv.Set(reflect.ValueOf(n))\n\n\t\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\t\tn, err := strconv.ParseInt(s, 10, 64)\n\t\t\tif err != nil || v.OverflowInt(n) {\n\t\t\t\td.saveError(&UnmarshalTypeError{\"number \" + s, v.Type(), int64(d.off)})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tv.SetInt(n)\n\n\t\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\t\tn, err := strconv.ParseUint(s, 10, 64)\n\t\t\tif err != nil || v.OverflowUint(n) {\n\t\t\t\td.saveError(&UnmarshalTypeError{\"number \" + s, v.Type(), int64(d.off)})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tv.SetUint(n)\n\n\t\tcase reflect.Float32, reflect.Float64:\n\t\t\tn, err := strconv.ParseFloat(s, v.Type().Bits())\n\t\t\tif err != nil || v.OverflowFloat(n) {\n\t\t\t\td.saveError(&UnmarshalTypeError{\"number \" + s, v.Type(), int64(d.off)})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tv.SetFloat(n)\n\t\t}\n\t}\n}\n\n// The xxxInterface routines build up a value to be stored\n// in an empty interface.  They are not strictly necessary,\n// but they avoid the weight of reflection in this common case.\n\n// valueInterface is like value but returns interface{}\nfunc (d *decodeState) valueInterface() interface{} {\n\tswitch d.scanWhile(scanSkipSpace) {\n\tdefault:\n\t\td.error(errPhase)\n\t\tpanic(\"unreachable\")\n\tcase scanBeginArray:\n\t\treturn d.arrayInterface()\n\tcase scanBeginObject:\n\t\treturn d.objectInterface()\n\tcase scanBeginLiteral:\n\t\treturn d.literalInterface()\n\t}\n}\n\n// arrayInterface is like array but returns []interface{}.\nfunc (d *decodeState) arrayInterface() []interface{} {\n\tvar v = make([]interface{}, 0)\n\tfor {\n\t\t// Look ahead for ] - can only happen on first iteration.\n\t\top := d.scanWhile(scanSkipSpace)\n\t\tif op == scanEndArray {\n\t\t\tbreak\n\t\t}\n\n\t\t// Back up so d.value can have the byte we just read.\n\t\td.off--\n\t\td.scan.undo(op)\n\n\t\tv = append(v, d.valueInterface())\n\n\t\t// Next token must be , or ].\n\t\top = d.scanWhile(scanSkipSpace)\n\t\tif op == scanEndArray {\n\t\t\tbreak\n\t\t}\n\t\tif op != scanArrayValue {\n\t\t\td.error(errPhase)\n\t\t}\n\t}\n\treturn v\n}\n\n// objectInterface is like object but returns map[string]interface{}.\nfunc (d *decodeState) objectInterface() map[string]interface{} {\n\tm := make(map[string]interface{})\n\tkeys := map[string]bool{}\n\n\tfor {\n\t\t// Read opening \" of string key or closing }.\n\t\top := d.scanWhile(scanSkipSpace)\n\t\tif op == scanEndObject {\n\t\t\t// closing } - can only happen on first iteration.\n\t\t\tbreak\n\t\t}\n\t\tif op != scanBeginLiteral {\n\t\t\td.error(errPhase)\n\t\t}\n\n\t\t// Read string key.\n\t\tstart := d.off - 1\n\t\top = d.scanWhile(scanContinue)\n\t\titem := d.data[start : d.off-1]\n\t\tkey, ok := unquote(item)\n\t\tif !ok {\n\t\t\td.error(errPhase)\n\t\t}\n\n\t\t// Check for duplicate keys.\n\t\t_, ok = keys[key]\n\t\tif !ok {\n\t\t\tkeys[key] = true\n\t\t} else {\n\t\t\td.error(fmt.Errorf(\"json: duplicate key '%s' in object\", key))\n\t\t}\n\n\t\t// Read : before value.\n\t\tif op == scanSkipSpace {\n\t\t\top = d.scanWhile(scanSkipSpace)\n\t\t}\n\t\tif op != scanObjectKey {\n\t\t\td.error(errPhase)\n\t\t}\n\n\t\t// Read value.\n\t\tm[key] = d.valueInterface()\n\n\t\t// Next token must be , or }.\n\t\top = d.scanWhile(scanSkipSpace)\n\t\tif op == scanEndObject {\n\t\t\tbreak\n\t\t}\n\t\tif op != scanObjectValue {\n\t\t\td.error(errPhase)\n\t\t}\n\t}\n\treturn m\n}\n\n// literalInterface is like literal but returns an interface value.\nfunc (d *decodeState) literalInterface() interface{} {\n\t// All bytes inside literal return scanContinue op code.\n\tstart := d.off - 1\n\top := d.scanWhile(scanContinue)\n\n\t// Scan read one byte too far; back up.\n\td.off--\n\td.scan.undo(op)\n\titem := d.data[start:d.off]\n\n\tswitch c := item[0]; c {\n\tcase 'n': // null\n\t\treturn nil\n\n\tcase 't', 'f': // true, false\n\t\treturn c == 't'\n\n\tcase '\"': // string\n\t\ts, ok := unquote(item)\n\t\tif !ok {\n\t\t\td.error(errPhase)\n\t\t}\n\t\treturn s\n\n\tdefault: // number\n\t\tif c != '-' && (c < '0' || c > '9') {\n\t\t\td.error(errPhase)\n\t\t}\n\t\tn, err := d.convertNumber(string(item))\n\t\tif err != nil {\n\t\t\td.saveError(err)\n\t\t}\n\t\treturn n\n\t}\n}\n\n// getu4 decodes \\uXXXX from the beginning of s, returning the hex value,\n// or it returns -1.\nfunc getu4(s []byte) rune {\n\tif len(s) < 6 || s[0] != '\\\\' || s[1] != 'u' {\n\t\treturn -1\n\t}\n\tr, err := strconv.ParseUint(string(s[2:6]), 16, 64)\n\tif err != nil {\n\t\treturn -1\n\t}\n\treturn rune(r)\n}\n\n// unquote converts a quoted JSON string literal s into an actual string t.\n// The rules are different than for Go, so cannot use strconv.Unquote.\nfunc unquote(s []byte) (t string, ok bool) {\n\ts, ok = unquoteBytes(s)\n\tt = string(s)\n\treturn\n}\n\nfunc unquoteBytes(s []byte) (t []byte, ok bool) {\n\tif len(s) < 2 || s[0] != '\"' || s[len(s)-1] != '\"' {\n\t\treturn\n\t}\n\ts = s[1 : len(s)-1]\n\n\t// Check for unusual characters. If there are none,\n\t// then no unquoting is needed, so return a slice of the\n\t// original bytes.\n\tr := 0\n\tfor r < len(s) {\n\t\tc := s[r]\n\t\tif c == '\\\\' || c == '\"' || c < ' ' {\n\t\t\tbreak\n\t\t}\n\t\tif c < utf8.RuneSelf {\n\t\t\tr++\n\t\t\tcontinue\n\t\t}\n\t\trr, size := utf8.DecodeRune(s[r:])\n\t\tif rr == utf8.RuneError && size == 1 {\n\t\t\tbreak\n\t\t}\n\t\tr += size\n\t}\n\tif r == len(s) {\n\t\treturn s, true\n\t}\n\n\tb := make([]byte, len(s)+2*utf8.UTFMax)\n\tw := copy(b, s[0:r])\n\tfor r < len(s) {\n\t\t// Out of room?  Can only happen if s is full of\n\t\t// malformed UTF-8 and we're replacing each\n\t\t// byte with RuneError.\n\t\tif w >= len(b)-2*utf8.UTFMax {\n\t\t\tnb := make([]byte, (len(b)+utf8.UTFMax)*2)\n\t\t\tcopy(nb, b[0:w])\n\t\t\tb = nb\n\t\t}\n\t\tswitch c := s[r]; {\n\t\tcase c == '\\\\':\n\t\t\tr++\n\t\t\tif r >= len(s) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tswitch s[r] {\n\t\t\tdefault:\n\t\t\t\treturn\n\t\t\tcase '\"', '\\\\', '/', '\\'':\n\t\t\t\tb[w] = s[r]\n\t\t\t\tr++\n\t\t\t\tw++\n\t\t\tcase 'b':\n\t\t\t\tb[w] = '\\b'\n\t\t\t\tr++\n\t\t\t\tw++\n\t\t\tcase 'f':\n\t\t\t\tb[w] = '\\f'\n\t\t\t\tr++\n\t\t\t\tw++\n\t\t\tcase 'n':\n\t\t\t\tb[w] = '\\n'\n\t\t\t\tr++\n\t\t\t\tw++\n\t\t\tcase 'r':\n\t\t\t\tb[w] = '\\r'\n\t\t\t\tr++\n\t\t\t\tw++\n\t\t\tcase 't':\n\t\t\t\tb[w] = '\\t'\n\t\t\t\tr++\n\t\t\t\tw++\n\t\t\tcase 'u':\n\t\t\t\tr--\n\t\t\t\trr := getu4(s[r:])\n\t\t\t\tif rr < 0 {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tr += 6\n\t\t\t\tif utf16.IsSurrogate(rr) {\n\t\t\t\t\trr1 := getu4(s[r:])\n\t\t\t\t\tif dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar {\n\t\t\t\t\t\t// A valid pair; consume.\n\t\t\t\t\t\tr += 6\n\t\t\t\t\t\tw += utf8.EncodeRune(b[w:], dec)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\t// Invalid surrogate; fall back to replacement rune.\n\t\t\t\t\trr = unicode.ReplacementChar\n\t\t\t\t}\n\t\t\t\tw += utf8.EncodeRune(b[w:], rr)\n\t\t\t}\n\n\t\t// Quote, control characters are invalid.\n\t\tcase c == '\"', c < ' ':\n\t\t\treturn\n\n\t\t// ASCII\n\t\tcase c < utf8.RuneSelf:\n\t\t\tb[w] = c\n\t\t\tr++\n\t\t\tw++\n\n\t\t// Coerce to well-formed UTF-8.\n\t\tdefault:\n\t\t\trr, size := utf8.DecodeRune(s[r:])\n\t\t\tr += size\n\t\t\tw += utf8.EncodeRune(b[w:], rr)\n\t\t}\n\t}\n\treturn b[0:w], true\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/json/encode.go",
    "content": "// Copyright 2010 The Go 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\n// Package json implements encoding and decoding of JSON objects as defined in\n// RFC 4627. The mapping between JSON objects and Go values is described\n// in the documentation for the Marshal and Unmarshal functions.\n//\n// See \"JSON and Go\" for an introduction to this package:\n// https://golang.org/doc/articles/json_and_go.html\npackage json\n\nimport (\n\t\"bytes\"\n\t\"encoding\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"math\"\n\t\"reflect\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n)\n\n// Marshal returns the JSON encoding of v.\n//\n// Marshal traverses the value v recursively.\n// If an encountered value implements the Marshaler interface\n// and is not a nil pointer, Marshal calls its MarshalJSON method\n// to produce JSON. If no MarshalJSON method is present but the\n// value implements encoding.TextMarshaler instead, Marshal calls\n// its MarshalText method.\n// The nil pointer exception is not strictly necessary\n// but mimics a similar, necessary exception in the behavior of\n// UnmarshalJSON.\n//\n// Otherwise, Marshal uses the following type-dependent default encodings:\n//\n// Boolean values encode as JSON booleans.\n//\n// Floating point, integer, and Number values encode as JSON numbers.\n//\n// String values encode as JSON strings coerced to valid UTF-8,\n// replacing invalid bytes with the Unicode replacement rune.\n// The angle brackets \"<\" and \">\" are escaped to \"\\u003c\" and \"\\u003e\"\n// to keep some browsers from misinterpreting JSON output as HTML.\n// Ampersand \"&\" is also escaped to \"\\u0026\" for the same reason.\n//\n// Array and slice values encode as JSON arrays, except that\n// []byte encodes as a base64-encoded string, and a nil slice\n// encodes as the null JSON object.\n//\n// Struct values encode as JSON objects. Each exported struct field\n// becomes a member of the object unless\n//   - the field's tag is \"-\", or\n//   - the field is empty and its tag specifies the \"omitempty\" option.\n//\n// The empty values are false, 0, any\n// nil pointer or interface value, and any array, slice, map, or string of\n// length zero. The object's default key string is the struct field name\n// but can be specified in the struct field's tag value. The \"json\" key in\n// the struct field's tag value is the key name, followed by an optional comma\n// and options. Examples:\n//\n//\t// Field is ignored by this package.\n//\tField int `json:\"-\"`\n//\n//\t// Field appears in JSON as key \"myName\".\n//\tField int `json:\"myName\"`\n//\n//\t// Field appears in JSON as key \"myName\" and\n//\t// the field is omitted from the object if its value is empty,\n//\t// as defined above.\n//\tField int `json:\"myName,omitempty\"`\n//\n//\t// Field appears in JSON as key \"Field\" (the default), but\n//\t// the field is skipped if empty.\n//\t// Note the leading comma.\n//\tField int `json:\",omitempty\"`\n//\n// The \"string\" option signals that a field is stored as JSON inside a\n// JSON-encoded string. It applies only to fields of string, floating point,\n// integer, or boolean types. This extra level of encoding is sometimes used\n// when communicating with JavaScript programs:\n//\n//\tInt64String int64 `json:\",string\"`\n//\n// The key name will be used if it's a non-empty string consisting of\n// only Unicode letters, digits, dollar signs, percent signs, hyphens,\n// underscores and slashes.\n//\n// Anonymous struct fields are usually marshaled as if their inner exported fields\n// were fields in the outer struct, subject to the usual Go visibility rules amended\n// as described in the next paragraph.\n// An anonymous struct field with a name given in its JSON tag is treated as\n// having that name, rather than being anonymous.\n// An anonymous struct field of interface type is treated the same as having\n// that type as its name, rather than being anonymous.\n//\n// The Go visibility rules for struct fields are amended for JSON when\n// deciding which field to marshal or unmarshal. If there are\n// multiple fields at the same level, and that level is the least\n// nested (and would therefore be the nesting level selected by the\n// usual Go rules), the following extra rules apply:\n//\n// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered,\n// even if there are multiple untagged fields that would otherwise conflict.\n// 2) If there is exactly one field (tagged or not according to the first rule), that is selected.\n// 3) Otherwise there are multiple fields, and all are ignored; no error occurs.\n//\n// Handling of anonymous struct fields is new in Go 1.1.\n// Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of\n// an anonymous struct field in both current and earlier versions, give the field\n// a JSON tag of \"-\".\n//\n// Map values encode as JSON objects.\n// The map's key type must be string; the map keys are used as JSON object\n// keys, subject to the UTF-8 coercion described for string values above.\n//\n// Pointer values encode as the value pointed to.\n// A nil pointer encodes as the null JSON object.\n//\n// Interface values encode as the value contained in the interface.\n// A nil interface value encodes as the null JSON object.\n//\n// Channel, complex, and function values cannot be encoded in JSON.\n// Attempting to encode such a value causes Marshal to return\n// an UnsupportedTypeError.\n//\n// JSON cannot represent cyclic data structures and Marshal does not\n// handle them.  Passing cyclic structures to Marshal will result in\n// an infinite recursion.\nfunc Marshal(v interface{}) ([]byte, error) {\n\te := &encodeState{}\n\terr := e.marshal(v)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn e.Bytes(), nil\n}\n\n// MarshalIndent is like Marshal but applies Indent to format the output.\nfunc MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {\n\tb, err := Marshal(v)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar buf bytes.Buffer\n\terr = Indent(&buf, b, prefix, indent)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn buf.Bytes(), nil\n}\n\n// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029\n// characters inside string literals changed to \\u003c, \\u003e, \\u0026, \\u2028, \\u2029\n// so that the JSON will be safe to embed inside HTML <script> tags.\n// For historical reasons, web browsers don't honor standard HTML\n// escaping within <script> tags, so an alternative JSON encoding must\n// be used.\nfunc HTMLEscape(dst *bytes.Buffer, src []byte) {\n\t// The characters can only appear in string literals,\n\t// so just scan the string one byte at a time.\n\tstart := 0\n\tfor i, c := range src {\n\t\tif c == '<' || c == '>' || c == '&' {\n\t\t\tif start < i {\n\t\t\t\tdst.Write(src[start:i])\n\t\t\t}\n\t\t\tdst.WriteString(`\\u00`)\n\t\t\tdst.WriteByte(hex[c>>4])\n\t\t\tdst.WriteByte(hex[c&0xF])\n\t\t\tstart = i + 1\n\t\t}\n\t\t// Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).\n\t\tif c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {\n\t\t\tif start < i {\n\t\t\t\tdst.Write(src[start:i])\n\t\t\t}\n\t\t\tdst.WriteString(`\\u202`)\n\t\t\tdst.WriteByte(hex[src[i+2]&0xF])\n\t\t\tstart = i + 3\n\t\t}\n\t}\n\tif start < len(src) {\n\t\tdst.Write(src[start:])\n\t}\n}\n\n// Marshaler is the interface implemented by objects that\n// can marshal themselves into valid JSON.\ntype Marshaler interface {\n\tMarshalJSON() ([]byte, error)\n}\n\n// An UnsupportedTypeError is returned by Marshal when attempting\n// to encode an unsupported value type.\ntype UnsupportedTypeError struct {\n\tType reflect.Type\n}\n\nfunc (e *UnsupportedTypeError) Error() string {\n\treturn \"json: unsupported type: \" + e.Type.String()\n}\n\ntype UnsupportedValueError struct {\n\tValue reflect.Value\n\tStr   string\n}\n\nfunc (e *UnsupportedValueError) Error() string {\n\treturn \"json: unsupported value: \" + e.Str\n}\n\n// Before Go 1.2, an InvalidUTF8Error was returned by Marshal when\n// attempting to encode a string value with invalid UTF-8 sequences.\n// As of Go 1.2, Marshal instead coerces the string to valid UTF-8 by\n// replacing invalid bytes with the Unicode replacement rune U+FFFD.\n// This error is no longer generated but is kept for backwards compatibility\n// with programs that might mention it.\ntype InvalidUTF8Error struct {\n\tS string // the whole string value that caused the error\n}\n\nfunc (e *InvalidUTF8Error) Error() string {\n\treturn \"json: invalid UTF-8 in string: \" + strconv.Quote(e.S)\n}\n\ntype MarshalerError struct {\n\tType reflect.Type\n\tErr  error\n}\n\nfunc (e *MarshalerError) Error() string {\n\treturn \"json: error calling MarshalJSON for type \" + e.Type.String() + \": \" + e.Err.Error()\n}\n\nvar hex = \"0123456789abcdef\"\n\n// An encodeState encodes JSON into a bytes.Buffer.\ntype encodeState struct {\n\tbytes.Buffer // accumulated output\n\tscratch      [64]byte\n}\n\nvar encodeStatePool sync.Pool\n\nfunc newEncodeState() *encodeState {\n\tif v := encodeStatePool.Get(); v != nil {\n\t\te := v.(*encodeState)\n\t\te.Reset()\n\t\treturn e\n\t}\n\treturn new(encodeState)\n}\n\nfunc (e *encodeState) marshal(v interface{}) (err error) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tif _, ok := r.(runtime.Error); ok {\n\t\t\t\tpanic(r)\n\t\t\t}\n\t\t\tif s, ok := r.(string); ok {\n\t\t\t\tpanic(s)\n\t\t\t}\n\t\t\terr = r.(error)\n\t\t}\n\t}()\n\te.reflectValue(reflect.ValueOf(v))\n\treturn nil\n}\n\nfunc (e *encodeState) error(err error) {\n\tpanic(err)\n}\n\nfunc isEmptyValue(v reflect.Value) bool {\n\tswitch v.Kind() {\n\tcase reflect.Array, reflect.Map, reflect.Slice, reflect.String:\n\t\treturn v.Len() == 0\n\tcase reflect.Bool:\n\t\treturn !v.Bool()\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\treturn v.Int() == 0\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\treturn v.Uint() == 0\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn v.Float() == 0\n\tcase reflect.Interface, reflect.Ptr:\n\t\treturn v.IsNil()\n\t}\n\treturn false\n}\n\nfunc (e *encodeState) reflectValue(v reflect.Value) {\n\tvalueEncoder(v)(e, v, false)\n}\n\ntype encoderFunc func(e *encodeState, v reflect.Value, quoted bool)\n\nvar encoderCache struct {\n\tsync.RWMutex\n\tm map[reflect.Type]encoderFunc\n}\n\nfunc valueEncoder(v reflect.Value) encoderFunc {\n\tif !v.IsValid() {\n\t\treturn invalidValueEncoder\n\t}\n\treturn typeEncoder(v.Type())\n}\n\nfunc typeEncoder(t reflect.Type) encoderFunc {\n\tencoderCache.RLock()\n\tf := encoderCache.m[t]\n\tencoderCache.RUnlock()\n\tif f != nil {\n\t\treturn f\n\t}\n\n\t// To deal with recursive types, populate the map with an\n\t// indirect func before we build it. This type waits on the\n\t// real func (f) to be ready and then calls it.  This indirect\n\t// func is only used for recursive types.\n\tencoderCache.Lock()\n\tif encoderCache.m == nil {\n\t\tencoderCache.m = make(map[reflect.Type]encoderFunc)\n\t}\n\tvar wg sync.WaitGroup\n\twg.Add(1)\n\tencoderCache.m[t] = func(e *encodeState, v reflect.Value, quoted bool) {\n\t\twg.Wait()\n\t\tf(e, v, quoted)\n\t}\n\tencoderCache.Unlock()\n\n\t// Compute fields without lock.\n\t// Might duplicate effort but won't hold other computations back.\n\tf = newTypeEncoder(t, true)\n\twg.Done()\n\tencoderCache.Lock()\n\tencoderCache.m[t] = f\n\tencoderCache.Unlock()\n\treturn f\n}\n\nvar (\n\tmarshalerType     = reflect.TypeOf(new(Marshaler)).Elem()\n\ttextMarshalerType = reflect.TypeOf(new(encoding.TextMarshaler)).Elem()\n)\n\n// newTypeEncoder constructs an encoderFunc for a type.\n// The returned encoder only checks CanAddr when allowAddr is true.\nfunc newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc {\n\tif t.Implements(marshalerType) {\n\t\treturn marshalerEncoder\n\t}\n\tif t.Kind() != reflect.Ptr && allowAddr {\n\t\tif reflect.PtrTo(t).Implements(marshalerType) {\n\t\t\treturn newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false))\n\t\t}\n\t}\n\n\tif t.Implements(textMarshalerType) {\n\t\treturn textMarshalerEncoder\n\t}\n\tif t.Kind() != reflect.Ptr && allowAddr {\n\t\tif reflect.PtrTo(t).Implements(textMarshalerType) {\n\t\t\treturn newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false))\n\t\t}\n\t}\n\n\tswitch t.Kind() {\n\tcase reflect.Bool:\n\t\treturn boolEncoder\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\treturn intEncoder\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\treturn uintEncoder\n\tcase reflect.Float32:\n\t\treturn float32Encoder\n\tcase reflect.Float64:\n\t\treturn float64Encoder\n\tcase reflect.String:\n\t\treturn stringEncoder\n\tcase reflect.Interface:\n\t\treturn interfaceEncoder\n\tcase reflect.Struct:\n\t\treturn newStructEncoder(t)\n\tcase reflect.Map:\n\t\treturn newMapEncoder(t)\n\tcase reflect.Slice:\n\t\treturn newSliceEncoder(t)\n\tcase reflect.Array:\n\t\treturn newArrayEncoder(t)\n\tcase reflect.Ptr:\n\t\treturn newPtrEncoder(t)\n\tdefault:\n\t\treturn unsupportedTypeEncoder\n\t}\n}\n\nfunc invalidValueEncoder(e *encodeState, v reflect.Value, quoted bool) {\n\te.WriteString(\"null\")\n}\n\nfunc marshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {\n\tif v.Kind() == reflect.Ptr && v.IsNil() {\n\t\te.WriteString(\"null\")\n\t\treturn\n\t}\n\tm := v.Interface().(Marshaler)\n\tb, err := m.MarshalJSON()\n\tif err == nil {\n\t\t// copy JSON into buffer, checking validity.\n\t\terr = compact(&e.Buffer, b, true)\n\t}\n\tif err != nil {\n\t\te.error(&MarshalerError{v.Type(), err})\n\t}\n}\n\nfunc addrMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {\n\tva := v.Addr()\n\tif va.IsNil() {\n\t\te.WriteString(\"null\")\n\t\treturn\n\t}\n\tm := va.Interface().(Marshaler)\n\tb, err := m.MarshalJSON()\n\tif err == nil {\n\t\t// copy JSON into buffer, checking validity.\n\t\terr = compact(&e.Buffer, b, true)\n\t}\n\tif err != nil {\n\t\te.error(&MarshalerError{v.Type(), err})\n\t}\n}\n\nfunc textMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {\n\tif v.Kind() == reflect.Ptr && v.IsNil() {\n\t\te.WriteString(\"null\")\n\t\treturn\n\t}\n\tm := v.Interface().(encoding.TextMarshaler)\n\tb, err := m.MarshalText()\n\tif err != nil {\n\t\te.error(&MarshalerError{v.Type(), err})\n\t}\n\te.stringBytes(b)\n}\n\nfunc addrTextMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {\n\tva := v.Addr()\n\tif va.IsNil() {\n\t\te.WriteString(\"null\")\n\t\treturn\n\t}\n\tm := va.Interface().(encoding.TextMarshaler)\n\tb, err := m.MarshalText()\n\tif err != nil {\n\t\te.error(&MarshalerError{v.Type(), err})\n\t}\n\te.stringBytes(b)\n}\n\nfunc boolEncoder(e *encodeState, v reflect.Value, quoted bool) {\n\tif quoted {\n\t\te.WriteByte('\"')\n\t}\n\tif v.Bool() {\n\t\te.WriteString(\"true\")\n\t} else {\n\t\te.WriteString(\"false\")\n\t}\n\tif quoted {\n\t\te.WriteByte('\"')\n\t}\n}\n\nfunc intEncoder(e *encodeState, v reflect.Value, quoted bool) {\n\tb := strconv.AppendInt(e.scratch[:0], v.Int(), 10)\n\tif quoted {\n\t\te.WriteByte('\"')\n\t}\n\te.Write(b)\n\tif quoted {\n\t\te.WriteByte('\"')\n\t}\n}\n\nfunc uintEncoder(e *encodeState, v reflect.Value, quoted bool) {\n\tb := strconv.AppendUint(e.scratch[:0], v.Uint(), 10)\n\tif quoted {\n\t\te.WriteByte('\"')\n\t}\n\te.Write(b)\n\tif quoted {\n\t\te.WriteByte('\"')\n\t}\n}\n\ntype floatEncoder int // number of bits\n\nfunc (bits floatEncoder) encode(e *encodeState, v reflect.Value, quoted bool) {\n\tf := v.Float()\n\tif math.IsInf(f, 0) || math.IsNaN(f) {\n\t\te.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, int(bits))})\n\t}\n\tb := strconv.AppendFloat(e.scratch[:0], f, 'g', -1, int(bits))\n\tif quoted {\n\t\te.WriteByte('\"')\n\t}\n\te.Write(b)\n\tif quoted {\n\t\te.WriteByte('\"')\n\t}\n}\n\nvar (\n\tfloat32Encoder = (floatEncoder(32)).encode\n\tfloat64Encoder = (floatEncoder(64)).encode\n)\n\nfunc stringEncoder(e *encodeState, v reflect.Value, quoted bool) {\n\tif v.Type() == numberType {\n\t\tnumStr := v.String()\n\t\t// In Go1.5 the empty string encodes to \"0\", while this is not a valid number literal\n\t\t// we keep compatibility so check validity after this.\n\t\tif numStr == \"\" {\n\t\t\tnumStr = \"0\" // Number's zero-val\n\t\t}\n\t\tif !isValidNumber(numStr) {\n\t\t\te.error(fmt.Errorf(\"json: invalid number literal %q\", numStr))\n\t\t}\n\t\te.WriteString(numStr)\n\t\treturn\n\t}\n\tif quoted {\n\t\tsb, err := Marshal(v.String())\n\t\tif err != nil {\n\t\t\te.error(err)\n\t\t}\n\t\te.string(string(sb))\n\t} else {\n\t\te.string(v.String())\n\t}\n}\n\nfunc interfaceEncoder(e *encodeState, v reflect.Value, quoted bool) {\n\tif v.IsNil() {\n\t\te.WriteString(\"null\")\n\t\treturn\n\t}\n\te.reflectValue(v.Elem())\n}\n\nfunc unsupportedTypeEncoder(e *encodeState, v reflect.Value, quoted bool) {\n\te.error(&UnsupportedTypeError{v.Type()})\n}\n\ntype structEncoder struct {\n\tfields    []field\n\tfieldEncs []encoderFunc\n}\n\nfunc (se *structEncoder) encode(e *encodeState, v reflect.Value, quoted bool) {\n\te.WriteByte('{')\n\tfirst := true\n\tfor i, f := range se.fields {\n\t\tfv := fieldByIndex(v, f.index)\n\t\tif !fv.IsValid() || f.omitEmpty && isEmptyValue(fv) {\n\t\t\tcontinue\n\t\t}\n\t\tif first {\n\t\t\tfirst = false\n\t\t} else {\n\t\t\te.WriteByte(',')\n\t\t}\n\t\te.string(f.name)\n\t\te.WriteByte(':')\n\t\tse.fieldEncs[i](e, fv, f.quoted)\n\t}\n\te.WriteByte('}')\n}\n\nfunc newStructEncoder(t reflect.Type) encoderFunc {\n\tfields := cachedTypeFields(t)\n\tse := &structEncoder{\n\t\tfields:    fields,\n\t\tfieldEncs: make([]encoderFunc, len(fields)),\n\t}\n\tfor i, f := range fields {\n\t\tse.fieldEncs[i] = typeEncoder(typeByIndex(t, f.index))\n\t}\n\treturn se.encode\n}\n\ntype mapEncoder struct {\n\telemEnc encoderFunc\n}\n\nfunc (me *mapEncoder) encode(e *encodeState, v reflect.Value, _ bool) {\n\tif v.IsNil() {\n\t\te.WriteString(\"null\")\n\t\treturn\n\t}\n\te.WriteByte('{')\n\tvar sv stringValues = v.MapKeys()\n\tsort.Sort(sv)\n\tfor i, k := range sv {\n\t\tif i > 0 {\n\t\t\te.WriteByte(',')\n\t\t}\n\t\te.string(k.String())\n\t\te.WriteByte(':')\n\t\tme.elemEnc(e, v.MapIndex(k), false)\n\t}\n\te.WriteByte('}')\n}\n\nfunc newMapEncoder(t reflect.Type) encoderFunc {\n\tif t.Key().Kind() != reflect.String {\n\t\treturn unsupportedTypeEncoder\n\t}\n\tme := &mapEncoder{typeEncoder(t.Elem())}\n\treturn me.encode\n}\n\nfunc encodeByteSlice(e *encodeState, v reflect.Value, _ bool) {\n\tif v.IsNil() {\n\t\te.WriteString(\"null\")\n\t\treturn\n\t}\n\ts := v.Bytes()\n\te.WriteByte('\"')\n\tif len(s) < 1024 {\n\t\t// for small buffers, using Encode directly is much faster.\n\t\tdst := make([]byte, base64.StdEncoding.EncodedLen(len(s)))\n\t\tbase64.StdEncoding.Encode(dst, s)\n\t\te.Write(dst)\n\t} else {\n\t\t// for large buffers, avoid unnecessary extra temporary\n\t\t// buffer space.\n\t\tenc := base64.NewEncoder(base64.StdEncoding, e)\n\t\t_, _ = enc.Write(s)\n\t\tenc.Close()\n\t}\n\te.WriteByte('\"')\n}\n\n// sliceEncoder just wraps an arrayEncoder, checking to make sure the value isn't nil.\ntype sliceEncoder struct {\n\tarrayEnc encoderFunc\n}\n\nfunc (se *sliceEncoder) encode(e *encodeState, v reflect.Value, _ bool) {\n\tif v.IsNil() {\n\t\te.WriteString(\"null\")\n\t\treturn\n\t}\n\tse.arrayEnc(e, v, false)\n}\n\nfunc newSliceEncoder(t reflect.Type) encoderFunc {\n\t// Byte slices get special treatment; arrays don't.\n\tif t.Elem().Kind() == reflect.Uint8 {\n\t\treturn encodeByteSlice\n\t}\n\tenc := &sliceEncoder{newArrayEncoder(t)}\n\treturn enc.encode\n}\n\ntype arrayEncoder struct {\n\telemEnc encoderFunc\n}\n\nfunc (ae *arrayEncoder) encode(e *encodeState, v reflect.Value, _ bool) {\n\te.WriteByte('[')\n\tn := v.Len()\n\tfor i := 0; i < n; i++ {\n\t\tif i > 0 {\n\t\t\te.WriteByte(',')\n\t\t}\n\t\tae.elemEnc(e, v.Index(i), false)\n\t}\n\te.WriteByte(']')\n}\n\nfunc newArrayEncoder(t reflect.Type) encoderFunc {\n\tenc := &arrayEncoder{typeEncoder(t.Elem())}\n\treturn enc.encode\n}\n\ntype ptrEncoder struct {\n\telemEnc encoderFunc\n}\n\nfunc (pe *ptrEncoder) encode(e *encodeState, v reflect.Value, quoted bool) {\n\tif v.IsNil() {\n\t\te.WriteString(\"null\")\n\t\treturn\n\t}\n\tpe.elemEnc(e, v.Elem(), quoted)\n}\n\nfunc newPtrEncoder(t reflect.Type) encoderFunc {\n\tenc := &ptrEncoder{typeEncoder(t.Elem())}\n\treturn enc.encode\n}\n\ntype condAddrEncoder struct {\n\tcanAddrEnc, elseEnc encoderFunc\n}\n\nfunc (ce *condAddrEncoder) encode(e *encodeState, v reflect.Value, quoted bool) {\n\tif v.CanAddr() {\n\t\tce.canAddrEnc(e, v, quoted)\n\t} else {\n\t\tce.elseEnc(e, v, quoted)\n\t}\n}\n\n// newCondAddrEncoder returns an encoder that checks whether its value\n// CanAddr and delegates to canAddrEnc if so, else to elseEnc.\nfunc newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc {\n\tenc := &condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc}\n\treturn enc.encode\n}\n\nfunc isValidTag(s string) bool {\n\tif s == \"\" {\n\t\treturn false\n\t}\n\tfor _, c := range s {\n\t\tswitch {\n\t\tcase strings.ContainsRune(\"!#$%&()*+-./:<=>?@[]^_{|}~ \", c):\n\t\t\t// Backslash and quote chars are reserved, but\n\t\t\t// otherwise any punctuation chars are allowed\n\t\t\t// in a tag name.\n\t\tdefault:\n\t\t\tif !unicode.IsLetter(c) && !unicode.IsDigit(c) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\nfunc fieldByIndex(v reflect.Value, index []int) reflect.Value {\n\tfor _, i := range index {\n\t\tif v.Kind() == reflect.Ptr {\n\t\t\tif v.IsNil() {\n\t\t\t\treturn reflect.Value{}\n\t\t\t}\n\t\t\tv = v.Elem()\n\t\t}\n\t\tv = v.Field(i)\n\t}\n\treturn v\n}\n\nfunc typeByIndex(t reflect.Type, index []int) reflect.Type {\n\tfor _, i := range index {\n\t\tif t.Kind() == reflect.Ptr {\n\t\t\tt = t.Elem()\n\t\t}\n\t\tt = t.Field(i).Type\n\t}\n\treturn t\n}\n\n// stringValues is a slice of reflect.Value holding *reflect.StringValue.\n// It implements the methods to sort by string.\ntype stringValues []reflect.Value\n\nfunc (sv stringValues) Len() int           { return len(sv) }\nfunc (sv stringValues) Swap(i, j int)      { sv[i], sv[j] = sv[j], sv[i] }\nfunc (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }\nfunc (sv stringValues) get(i int) string   { return sv[i].String() }\n\n// NOTE: keep in sync with stringBytes below.\nfunc (e *encodeState) string(s string) int {\n\tlen0 := e.Len()\n\te.WriteByte('\"')\n\tstart := 0\n\tfor i := 0; i < len(s); {\n\t\tif b := s[i]; b < utf8.RuneSelf {\n\t\t\tif 0x20 <= b && b != '\\\\' && b != '\"' && b != '<' && b != '>' && b != '&' {\n\t\t\t\ti++\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif start < i {\n\t\t\t\te.WriteString(s[start:i])\n\t\t\t}\n\t\t\tswitch b {\n\t\t\tcase '\\\\', '\"':\n\t\t\t\te.WriteByte('\\\\')\n\t\t\t\te.WriteByte(b)\n\t\t\tcase '\\n':\n\t\t\t\te.WriteByte('\\\\')\n\t\t\t\te.WriteByte('n')\n\t\t\tcase '\\r':\n\t\t\t\te.WriteByte('\\\\')\n\t\t\t\te.WriteByte('r')\n\t\t\tcase '\\t':\n\t\t\t\te.WriteByte('\\\\')\n\t\t\t\te.WriteByte('t')\n\t\t\tdefault:\n\t\t\t\t// This encodes bytes < 0x20 except for \\n and \\r,\n\t\t\t\t// as well as <, > and &. The latter are escaped because they\n\t\t\t\t// can lead to security holes when user-controlled strings\n\t\t\t\t// are rendered into JSON and served to some browsers.\n\t\t\t\te.WriteString(`\\u00`)\n\t\t\t\te.WriteByte(hex[b>>4])\n\t\t\t\te.WriteByte(hex[b&0xF])\n\t\t\t}\n\t\t\ti++\n\t\t\tstart = i\n\t\t\tcontinue\n\t\t}\n\t\tc, size := utf8.DecodeRuneInString(s[i:])\n\t\tif c == utf8.RuneError && size == 1 {\n\t\t\tif start < i {\n\t\t\t\te.WriteString(s[start:i])\n\t\t\t}\n\t\t\te.WriteString(`\\ufffd`)\n\t\t\ti += size\n\t\t\tstart = i\n\t\t\tcontinue\n\t\t}\n\t\t// U+2028 is LINE SEPARATOR.\n\t\t// U+2029 is PARAGRAPH SEPARATOR.\n\t\t// They are both technically valid characters in JSON strings,\n\t\t// but don't work in JSONP, which has to be evaluated as JavaScript,\n\t\t// and can lead to security holes there. It is valid JSON to\n\t\t// escape them, so we do so unconditionally.\n\t\t// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.\n\t\tif c == '\\u2028' || c == '\\u2029' {\n\t\t\tif start < i {\n\t\t\t\te.WriteString(s[start:i])\n\t\t\t}\n\t\t\te.WriteString(`\\u202`)\n\t\t\te.WriteByte(hex[c&0xF])\n\t\t\ti += size\n\t\t\tstart = i\n\t\t\tcontinue\n\t\t}\n\t\ti += size\n\t}\n\tif start < len(s) {\n\t\te.WriteString(s[start:])\n\t}\n\te.WriteByte('\"')\n\treturn e.Len() - len0\n}\n\n// NOTE: keep in sync with string above.\nfunc (e *encodeState) stringBytes(s []byte) int {\n\tlen0 := e.Len()\n\te.WriteByte('\"')\n\tstart := 0\n\tfor i := 0; i < len(s); {\n\t\tif b := s[i]; b < utf8.RuneSelf {\n\t\t\tif 0x20 <= b && b != '\\\\' && b != '\"' && b != '<' && b != '>' && b != '&' {\n\t\t\t\ti++\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif start < i {\n\t\t\t\te.Write(s[start:i])\n\t\t\t}\n\t\t\tswitch b {\n\t\t\tcase '\\\\', '\"':\n\t\t\t\te.WriteByte('\\\\')\n\t\t\t\te.WriteByte(b)\n\t\t\tcase '\\n':\n\t\t\t\te.WriteByte('\\\\')\n\t\t\t\te.WriteByte('n')\n\t\t\tcase '\\r':\n\t\t\t\te.WriteByte('\\\\')\n\t\t\t\te.WriteByte('r')\n\t\t\tcase '\\t':\n\t\t\t\te.WriteByte('\\\\')\n\t\t\t\te.WriteByte('t')\n\t\t\tdefault:\n\t\t\t\t// This encodes bytes < 0x20 except for \\n and \\r,\n\t\t\t\t// as well as <, >, and &. The latter are escaped because they\n\t\t\t\t// can lead to security holes when user-controlled strings\n\t\t\t\t// are rendered into JSON and served to some browsers.\n\t\t\t\te.WriteString(`\\u00`)\n\t\t\t\te.WriteByte(hex[b>>4])\n\t\t\t\te.WriteByte(hex[b&0xF])\n\t\t\t}\n\t\t\ti++\n\t\t\tstart = i\n\t\t\tcontinue\n\t\t}\n\t\tc, size := utf8.DecodeRune(s[i:])\n\t\tif c == utf8.RuneError && size == 1 {\n\t\t\tif start < i {\n\t\t\t\te.Write(s[start:i])\n\t\t\t}\n\t\t\te.WriteString(`\\ufffd`)\n\t\t\ti += size\n\t\t\tstart = i\n\t\t\tcontinue\n\t\t}\n\t\t// U+2028 is LINE SEPARATOR.\n\t\t// U+2029 is PARAGRAPH SEPARATOR.\n\t\t// They are both technically valid characters in JSON strings,\n\t\t// but don't work in JSONP, which has to be evaluated as JavaScript,\n\t\t// and can lead to security holes there. It is valid JSON to\n\t\t// escape them, so we do so unconditionally.\n\t\t// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.\n\t\tif c == '\\u2028' || c == '\\u2029' {\n\t\t\tif start < i {\n\t\t\t\te.Write(s[start:i])\n\t\t\t}\n\t\t\te.WriteString(`\\u202`)\n\t\t\te.WriteByte(hex[c&0xF])\n\t\t\ti += size\n\t\t\tstart = i\n\t\t\tcontinue\n\t\t}\n\t\ti += size\n\t}\n\tif start < len(s) {\n\t\te.Write(s[start:])\n\t}\n\te.WriteByte('\"')\n\treturn e.Len() - len0\n}\n\n// A field represents a single field found in a struct.\ntype field struct {\n\tname      string\n\tnameBytes []byte // []byte(name)\n\n\ttag       bool\n\tindex     []int\n\ttyp       reflect.Type\n\tomitEmpty bool\n\tquoted    bool\n}\n\nfunc fillField(f field) field {\n\tf.nameBytes = []byte(f.name)\n\treturn f\n}\n\n// byName sorts field by name, breaking ties with depth,\n// then breaking ties with \"name came from json tag\", then\n// breaking ties with index sequence.\ntype byName []field\n\nfunc (x byName) Len() int { return len(x) }\n\nfunc (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }\n\nfunc (x byName) Less(i, j int) bool {\n\tif x[i].name != x[j].name {\n\t\treturn x[i].name < x[j].name\n\t}\n\tif len(x[i].index) != len(x[j].index) {\n\t\treturn len(x[i].index) < len(x[j].index)\n\t}\n\tif x[i].tag != x[j].tag {\n\t\treturn x[i].tag\n\t}\n\treturn byIndex(x).Less(i, j)\n}\n\n// byIndex sorts field by index sequence.\ntype byIndex []field\n\nfunc (x byIndex) Len() int { return len(x) }\n\nfunc (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }\n\nfunc (x byIndex) Less(i, j int) bool {\n\tfor k, xik := range x[i].index {\n\t\tif k >= len(x[j].index) {\n\t\t\treturn false\n\t\t}\n\t\tif xik != x[j].index[k] {\n\t\t\treturn xik < x[j].index[k]\n\t\t}\n\t}\n\treturn len(x[i].index) < len(x[j].index)\n}\n\n// typeFields returns a list of fields that JSON should recognize for the given type.\n// The algorithm is breadth-first search over the set of structs to include - the top struct\n// and then any reachable anonymous structs.\nfunc typeFields(t reflect.Type) []field {\n\t// Anonymous fields to explore at the current level and the next.\n\tcurrent := []field{}\n\tnext := []field{{typ: t}}\n\n\t// Count of queued names for current level and the next.\n\tcount := map[reflect.Type]int{}\n\tnextCount := map[reflect.Type]int{}\n\n\t// Types already visited at an earlier level.\n\tvisited := map[reflect.Type]bool{}\n\n\t// Fields found.\n\tvar fields []field\n\n\tfor len(next) > 0 {\n\t\tcurrent, next = next, current[:0]\n\t\tcount, nextCount = nextCount, map[reflect.Type]int{}\n\n\t\tfor _, f := range current {\n\t\t\tif visited[f.typ] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tvisited[f.typ] = true\n\n\t\t\t// Scan f.typ for fields to include.\n\t\t\tfor i := 0; i < f.typ.NumField(); i++ {\n\t\t\t\tsf := f.typ.Field(i)\n\t\t\t\tif sf.PkgPath != \"\" && !sf.Anonymous { // unexported\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\ttag := sf.Tag.Get(\"json\")\n\t\t\t\tif tag == \"-\" {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tname, opts := parseTag(tag)\n\t\t\t\tif !isValidTag(name) {\n\t\t\t\t\tname = \"\"\n\t\t\t\t}\n\t\t\t\tindex := make([]int, len(f.index)+1)\n\t\t\t\tcopy(index, f.index)\n\t\t\t\tindex[len(f.index)] = i\n\n\t\t\t\tft := sf.Type\n\t\t\t\tif ft.Name() == \"\" && ft.Kind() == reflect.Ptr {\n\t\t\t\t\t// Follow pointer.\n\t\t\t\t\tft = ft.Elem()\n\t\t\t\t}\n\n\t\t\t\t// Only strings, floats, integers, and booleans can be quoted.\n\t\t\t\tquoted := false\n\t\t\t\tif opts.Contains(\"string\") {\n\t\t\t\t\tswitch ft.Kind() {\n\t\t\t\t\tcase reflect.Bool,\n\t\t\t\t\t\treflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,\n\t\t\t\t\t\treflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,\n\t\t\t\t\t\treflect.Float32, reflect.Float64,\n\t\t\t\t\t\treflect.String:\n\t\t\t\t\t\tquoted = true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Record found field and index sequence.\n\t\t\t\tif name != \"\" || !sf.Anonymous || ft.Kind() != reflect.Struct {\n\t\t\t\t\ttagged := name != \"\"\n\t\t\t\t\tif name == \"\" {\n\t\t\t\t\t\tname = sf.Name\n\t\t\t\t\t}\n\t\t\t\t\tfields = append(fields, fillField(field{\n\t\t\t\t\t\tname:      name,\n\t\t\t\t\t\ttag:       tagged,\n\t\t\t\t\t\tindex:     index,\n\t\t\t\t\t\ttyp:       ft,\n\t\t\t\t\t\tomitEmpty: opts.Contains(\"omitempty\"),\n\t\t\t\t\t\tquoted:    quoted,\n\t\t\t\t\t}))\n\t\t\t\t\tif count[f.typ] > 1 {\n\t\t\t\t\t\t// If there were multiple instances, add a second,\n\t\t\t\t\t\t// so that the annihilation code will see a duplicate.\n\t\t\t\t\t\t// It only cares about the distinction between 1 or 2,\n\t\t\t\t\t\t// so don't bother generating any more copies.\n\t\t\t\t\t\tfields = append(fields, fields[len(fields)-1])\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Record new anonymous struct to explore in next round.\n\t\t\t\tnextCount[ft]++\n\t\t\t\tif nextCount[ft] == 1 {\n\t\t\t\t\tnext = append(next, fillField(field{name: ft.Name(), index: index, typ: ft}))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tsort.Sort(byName(fields))\n\n\t// Delete all fields that are hidden by the Go rules for embedded fields,\n\t// except that fields with JSON tags are promoted.\n\n\t// The fields are sorted in primary order of name, secondary order\n\t// of field index length. Loop over names; for each name, delete\n\t// hidden fields by choosing the one dominant field that survives.\n\tout := fields[:0]\n\tfor advance, i := 0, 0; i < len(fields); i += advance {\n\t\t// One iteration per name.\n\t\t// Find the sequence of fields with the name of this first field.\n\t\tfi := fields[i]\n\t\tname := fi.name\n\t\tfor advance = 1; i+advance < len(fields); advance++ {\n\t\t\tfj := fields[i+advance]\n\t\t\tif fj.name != name {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif advance == 1 { // Only one field with this name\n\t\t\tout = append(out, fi)\n\t\t\tcontinue\n\t\t}\n\t\tdominant, ok := dominantField(fields[i : i+advance])\n\t\tif ok {\n\t\t\tout = append(out, dominant)\n\t\t}\n\t}\n\n\tfields = out\n\tsort.Sort(byIndex(fields))\n\n\treturn fields\n}\n\n// dominantField looks through the fields, all of which are known to\n// have the same name, to find the single field that dominates the\n// others using Go's embedding rules, modified by the presence of\n// JSON tags. If there are multiple top-level fields, the boolean\n// will be false: This condition is an error in Go and we skip all\n// the fields.\nfunc dominantField(fields []field) (field, bool) {\n\t// The fields are sorted in increasing index-length order. The winner\n\t// must therefore be one with the shortest index length. Drop all\n\t// longer entries, which is easy: just truncate the slice.\n\tlength := len(fields[0].index)\n\ttagged := -1 // Index of first tagged field.\n\tfor i, f := range fields {\n\t\tif len(f.index) > length {\n\t\t\tfields = fields[:i]\n\t\t\tbreak\n\t\t}\n\t\tif f.tag {\n\t\t\tif tagged >= 0 {\n\t\t\t\t// Multiple tagged fields at the same level: conflict.\n\t\t\t\t// Return no field.\n\t\t\t\treturn field{}, false\n\t\t\t}\n\t\t\ttagged = i\n\t\t}\n\t}\n\tif tagged >= 0 {\n\t\treturn fields[tagged], true\n\t}\n\t// All remaining fields have the same length. If there's more than one,\n\t// we have a conflict (two fields named \"X\" at the same level) and we\n\t// return no field.\n\tif len(fields) > 1 {\n\t\treturn field{}, false\n\t}\n\treturn fields[0], true\n}\n\nvar fieldCache struct {\n\tsync.RWMutex\n\tm map[reflect.Type][]field\n}\n\n// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.\nfunc cachedTypeFields(t reflect.Type) []field {\n\tfieldCache.RLock()\n\tf := fieldCache.m[t]\n\tfieldCache.RUnlock()\n\tif f != nil {\n\t\treturn f\n\t}\n\n\t// Compute fields without lock.\n\t// Might duplicate effort but won't hold other computations back.\n\tf = typeFields(t)\n\tif f == nil {\n\t\tf = []field{}\n\t}\n\n\tfieldCache.Lock()\n\tif fieldCache.m == nil {\n\t\tfieldCache.m = map[reflect.Type][]field{}\n\t}\n\tfieldCache.m[t] = f\n\tfieldCache.Unlock()\n\treturn f\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/json/indent.go",
    "content": "// Copyright 2010 The Go 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 json\n\nimport \"bytes\"\n\n// Compact appends to dst the JSON-encoded src with\n// insignificant space characters elided.\nfunc Compact(dst *bytes.Buffer, src []byte) error {\n\treturn compact(dst, src, false)\n}\n\nfunc compact(dst *bytes.Buffer, src []byte, escape bool) error {\n\torigLen := dst.Len()\n\tvar scan scanner\n\tscan.reset()\n\tstart := 0\n\tfor i, c := range src {\n\t\tif escape && (c == '<' || c == '>' || c == '&') {\n\t\t\tif start < i {\n\t\t\t\tdst.Write(src[start:i])\n\t\t\t}\n\t\t\tdst.WriteString(`\\u00`)\n\t\t\tdst.WriteByte(hex[c>>4])\n\t\t\tdst.WriteByte(hex[c&0xF])\n\t\t\tstart = i + 1\n\t\t}\n\t\t// Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).\n\t\tif c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {\n\t\t\tif start < i {\n\t\t\t\tdst.Write(src[start:i])\n\t\t\t}\n\t\t\tdst.WriteString(`\\u202`)\n\t\t\tdst.WriteByte(hex[src[i+2]&0xF])\n\t\t\tstart = i + 3\n\t\t}\n\t\tv := scan.step(&scan, c)\n\t\tif v >= scanSkipSpace {\n\t\t\tif v == scanError {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif start < i {\n\t\t\t\tdst.Write(src[start:i])\n\t\t\t}\n\t\t\tstart = i + 1\n\t\t}\n\t}\n\tif scan.eof() == scanError {\n\t\tdst.Truncate(origLen)\n\t\treturn scan.err\n\t}\n\tif start < len(src) {\n\t\tdst.Write(src[start:])\n\t}\n\treturn nil\n}\n\nfunc newline(dst *bytes.Buffer, prefix, indent string, depth int) {\n\tdst.WriteByte('\\n')\n\tdst.WriteString(prefix)\n\tfor i := 0; i < depth; i++ {\n\t\tdst.WriteString(indent)\n\t}\n}\n\n// Indent appends to dst an indented form of the JSON-encoded src.\n// Each element in a JSON object or array begins on a new,\n// indented line beginning with prefix followed by one or more\n// copies of indent according to the indentation nesting.\n// The data appended to dst does not begin with the prefix nor\n// any indentation, to make it easier to embed inside other formatted JSON data.\n// Although leading space characters (space, tab, carriage return, newline)\n// at the beginning of src are dropped, trailing space characters\n// at the end of src are preserved and copied to dst.\n// For example, if src has no trailing spaces, neither will dst;\n// if src ends in a trailing newline, so will dst.\nfunc Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {\n\torigLen := dst.Len()\n\tvar scan scanner\n\tscan.reset()\n\tneedIndent := false\n\tdepth := 0\n\tfor _, c := range src {\n\t\tscan.bytes++\n\t\tv := scan.step(&scan, c)\n\t\tif v == scanSkipSpace {\n\t\t\tcontinue\n\t\t}\n\t\tif v == scanError {\n\t\t\tbreak\n\t\t}\n\t\tif needIndent && v != scanEndObject && v != scanEndArray {\n\t\t\tneedIndent = false\n\t\t\tdepth++\n\t\t\tnewline(dst, prefix, indent, depth)\n\t\t}\n\n\t\t// Emit semantically uninteresting bytes\n\t\t// (in particular, punctuation in strings) unmodified.\n\t\tif v == scanContinue {\n\t\t\tdst.WriteByte(c)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Add spacing around real punctuation.\n\t\tswitch c {\n\t\tcase '{', '[':\n\t\t\t// delay indent so that empty object and array are formatted as {} and [].\n\t\t\tneedIndent = true\n\t\t\tdst.WriteByte(c)\n\n\t\tcase ',':\n\t\t\tdst.WriteByte(c)\n\t\t\tnewline(dst, prefix, indent, depth)\n\n\t\tcase ':':\n\t\t\tdst.WriteByte(c)\n\t\t\tdst.WriteByte(' ')\n\n\t\tcase '}', ']':\n\t\t\tif needIndent {\n\t\t\t\t// suppress indent in empty object/array\n\t\t\t\tneedIndent = false\n\t\t\t} else {\n\t\t\t\tdepth--\n\t\t\t\tnewline(dst, prefix, indent, depth)\n\t\t\t}\n\t\t\tdst.WriteByte(c)\n\n\t\tdefault:\n\t\t\tdst.WriteByte(c)\n\t\t}\n\t}\n\tif scan.eof() == scanError {\n\t\tdst.Truncate(origLen)\n\t\treturn scan.err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/json/scanner.go",
    "content": "// Copyright 2010 The Go 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 json\n\n// JSON value parser state machine.\n// Just about at the limit of what is reasonable to write by hand.\n// Some parts are a bit tedious, but overall it nicely factors out the\n// otherwise common code from the multiple scanning functions\n// in this package (Compact, Indent, checkValid, nextValue, etc).\n//\n// This file starts with two simple examples using the scanner\n// before diving into the scanner itself.\n\nimport \"strconv\"\n\n// checkValid verifies that data is valid JSON-encoded data.\n// scan is passed in for use by checkValid to avoid an allocation.\nfunc checkValid(data []byte, scan *scanner) error {\n\tscan.reset()\n\tfor _, c := range data {\n\t\tscan.bytes++\n\t\tif scan.step(scan, c) == scanError {\n\t\t\treturn scan.err\n\t\t}\n\t}\n\tif scan.eof() == scanError {\n\t\treturn scan.err\n\t}\n\treturn nil\n}\n\n// nextValue splits data after the next whole JSON value,\n// returning that value and the bytes that follow it as separate slices.\n// scan is passed in for use by nextValue to avoid an allocation.\nfunc nextValue(data []byte, scan *scanner) (value, rest []byte, err error) {\n\tscan.reset()\n\tfor i, c := range data {\n\t\tv := scan.step(scan, c)\n\t\tif v >= scanEndObject {\n\t\t\tswitch v {\n\t\t\t// probe the scanner with a space to determine whether we will\n\t\t\t// get scanEnd on the next character. Otherwise, if the next character\n\t\t\t// is not a space, scanEndTop allocates a needless error.\n\t\t\tcase scanEndObject, scanEndArray:\n\t\t\t\tif scan.step(scan, ' ') == scanEnd {\n\t\t\t\t\treturn data[:i+1], data[i+1:], nil\n\t\t\t\t}\n\t\t\tcase scanError:\n\t\t\t\treturn nil, nil, scan.err\n\t\t\tcase scanEnd:\n\t\t\t\treturn data[:i], data[i:], nil\n\t\t\t}\n\t\t}\n\t}\n\tif scan.eof() == scanError {\n\t\treturn nil, nil, scan.err\n\t}\n\treturn data, nil, nil\n}\n\n// A SyntaxError is a description of a JSON syntax error.\ntype SyntaxError struct {\n\tmsg    string // description of error\n\tOffset int64  // error occurred after reading Offset bytes\n}\n\nfunc (e *SyntaxError) Error() string { return e.msg }\n\n// A scanner is a JSON scanning state machine.\n// Callers call scan.reset() and then pass bytes in one at a time\n// by calling scan.step(&scan, c) for each byte.\n// The return value, referred to as an opcode, tells the\n// caller about significant parsing events like beginning\n// and ending literals, objects, and arrays, so that the\n// caller can follow along if it wishes.\n// The return value scanEnd indicates that a single top-level\n// JSON value has been completed, *before* the byte that\n// just got passed in.  (The indication must be delayed in order\n// to recognize the end of numbers: is 123 a whole value or\n// the beginning of 12345e+6?).\ntype scanner struct {\n\t// The step is a func to be called to execute the next transition.\n\t// Also tried using an integer constant and a single func\n\t// with a switch, but using the func directly was 10% faster\n\t// on a 64-bit Mac Mini, and it's nicer to read.\n\tstep func(*scanner, byte) int\n\n\t// Reached end of top-level value.\n\tendTop bool\n\n\t// Stack of what we're in the middle of - array values, object keys, object values.\n\tparseState []int\n\n\t// Error that happened, if any.\n\terr error\n\n\t// 1-byte redo (see undo method)\n\tredo      bool\n\tredoCode  int\n\tredoState func(*scanner, byte) int\n\n\t// total bytes consumed, updated by decoder.Decode\n\tbytes int64\n}\n\n// These values are returned by the state transition functions\n// assigned to scanner.state and the method scanner.eof.\n// They give details about the current state of the scan that\n// callers might be interested to know about.\n// It is okay to ignore the return value of any particular\n// call to scanner.state: if one call returns scanError,\n// every subsequent call will return scanError too.\nconst (\n\t// Continue.\n\tscanContinue     = iota // uninteresting byte\n\tscanBeginLiteral        // end implied by next result != scanContinue\n\tscanBeginObject         // begin object\n\tscanObjectKey           // just finished object key (string)\n\tscanObjectValue         // just finished non-last object value\n\tscanEndObject           // end object (implies scanObjectValue if possible)\n\tscanBeginArray          // begin array\n\tscanArrayValue          // just finished array value\n\tscanEndArray            // end array (implies scanArrayValue if possible)\n\tscanSkipSpace           // space byte; can skip; known to be last \"continue\" result\n\n\t// Stop.\n\tscanEnd   // top-level value ended *before* this byte; known to be first \"stop\" result\n\tscanError // hit an error, scanner.err.\n)\n\n// These values are stored in the parseState stack.\n// They give the current state of a composite value\n// being scanned.  If the parser is inside a nested value\n// the parseState describes the nested state, outermost at entry 0.\nconst (\n\tparseObjectKey   = iota // parsing object key (before colon)\n\tparseObjectValue        // parsing object value (after colon)\n\tparseArrayValue         // parsing array value\n)\n\n// reset prepares the scanner for use.\n// It must be called before calling s.step.\nfunc (s *scanner) reset() {\n\ts.step = stateBeginValue\n\ts.parseState = s.parseState[0:0]\n\ts.err = nil\n\ts.redo = false\n\ts.endTop = false\n}\n\n// eof tells the scanner that the end of input has been reached.\n// It returns a scan status just as s.step does.\nfunc (s *scanner) eof() int {\n\tif s.err != nil {\n\t\treturn scanError\n\t}\n\tif s.endTop {\n\t\treturn scanEnd\n\t}\n\ts.step(s, ' ')\n\tif s.endTop {\n\t\treturn scanEnd\n\t}\n\tif s.err == nil {\n\t\ts.err = &SyntaxError{\"unexpected end of JSON input\", s.bytes}\n\t}\n\treturn scanError\n}\n\n// pushParseState pushes a new parse state p onto the parse stack.\nfunc (s *scanner) pushParseState(p int) {\n\ts.parseState = append(s.parseState, p)\n}\n\n// popParseState pops a parse state (already obtained) off the stack\n// and updates s.step accordingly.\nfunc (s *scanner) popParseState() {\n\tn := len(s.parseState) - 1\n\ts.parseState = s.parseState[0:n]\n\ts.redo = false\n\tif n == 0 {\n\t\ts.step = stateEndTop\n\t\ts.endTop = true\n\t} else {\n\t\ts.step = stateEndValue\n\t}\n}\n\nfunc isSpace(c byte) bool {\n\treturn c == ' ' || c == '\\t' || c == '\\r' || c == '\\n'\n}\n\n// stateBeginValueOrEmpty is the state after reading `[`.\nfunc stateBeginValueOrEmpty(s *scanner, c byte) int {\n\tif c <= ' ' && isSpace(c) {\n\t\treturn scanSkipSpace\n\t}\n\tif c == ']' {\n\t\treturn stateEndValue(s, c)\n\t}\n\treturn stateBeginValue(s, c)\n}\n\n// stateBeginValue is the state at the beginning of the input.\nfunc stateBeginValue(s *scanner, c byte) int {\n\tif c <= ' ' && isSpace(c) {\n\t\treturn scanSkipSpace\n\t}\n\tswitch c {\n\tcase '{':\n\t\ts.step = stateBeginStringOrEmpty\n\t\ts.pushParseState(parseObjectKey)\n\t\treturn scanBeginObject\n\tcase '[':\n\t\ts.step = stateBeginValueOrEmpty\n\t\ts.pushParseState(parseArrayValue)\n\t\treturn scanBeginArray\n\tcase '\"':\n\t\ts.step = stateInString\n\t\treturn scanBeginLiteral\n\tcase '-':\n\t\ts.step = stateNeg\n\t\treturn scanBeginLiteral\n\tcase '0': // beginning of 0.123\n\t\ts.step = state0\n\t\treturn scanBeginLiteral\n\tcase 't': // beginning of true\n\t\ts.step = stateT\n\t\treturn scanBeginLiteral\n\tcase 'f': // beginning of false\n\t\ts.step = stateF\n\t\treturn scanBeginLiteral\n\tcase 'n': // beginning of null\n\t\ts.step = stateN\n\t\treturn scanBeginLiteral\n\t}\n\tif '1' <= c && c <= '9' { // beginning of 1234.5\n\t\ts.step = state1\n\t\treturn scanBeginLiteral\n\t}\n\treturn s.error(c, \"looking for beginning of value\")\n}\n\n// stateBeginStringOrEmpty is the state after reading `{`.\nfunc stateBeginStringOrEmpty(s *scanner, c byte) int {\n\tif c <= ' ' && isSpace(c) {\n\t\treturn scanSkipSpace\n\t}\n\tif c == '}' {\n\t\tn := len(s.parseState)\n\t\ts.parseState[n-1] = parseObjectValue\n\t\treturn stateEndValue(s, c)\n\t}\n\treturn stateBeginString(s, c)\n}\n\n// stateBeginString is the state after reading `{\"key\": value,`.\nfunc stateBeginString(s *scanner, c byte) int {\n\tif c <= ' ' && isSpace(c) {\n\t\treturn scanSkipSpace\n\t}\n\tif c == '\"' {\n\t\ts.step = stateInString\n\t\treturn scanBeginLiteral\n\t}\n\treturn s.error(c, \"looking for beginning of object key string\")\n}\n\n// stateEndValue is the state after completing a value,\n// such as after reading `{}` or `true` or `[\"x\"`.\nfunc stateEndValue(s *scanner, c byte) int {\n\tn := len(s.parseState)\n\tif n == 0 {\n\t\t// Completed top-level before the current byte.\n\t\ts.step = stateEndTop\n\t\ts.endTop = true\n\t\treturn stateEndTop(s, c)\n\t}\n\tif c <= ' ' && isSpace(c) {\n\t\ts.step = stateEndValue\n\t\treturn scanSkipSpace\n\t}\n\tps := s.parseState[n-1]\n\tswitch ps {\n\tcase parseObjectKey:\n\t\tif c == ':' {\n\t\t\ts.parseState[n-1] = parseObjectValue\n\t\t\ts.step = stateBeginValue\n\t\t\treturn scanObjectKey\n\t\t}\n\t\treturn s.error(c, \"after object key\")\n\tcase parseObjectValue:\n\t\tif c == ',' {\n\t\t\ts.parseState[n-1] = parseObjectKey\n\t\t\ts.step = stateBeginString\n\t\t\treturn scanObjectValue\n\t\t}\n\t\tif c == '}' {\n\t\t\ts.popParseState()\n\t\t\treturn scanEndObject\n\t\t}\n\t\treturn s.error(c, \"after object key:value pair\")\n\tcase parseArrayValue:\n\t\tif c == ',' {\n\t\t\ts.step = stateBeginValue\n\t\t\treturn scanArrayValue\n\t\t}\n\t\tif c == ']' {\n\t\t\ts.popParseState()\n\t\t\treturn scanEndArray\n\t\t}\n\t\treturn s.error(c, \"after array element\")\n\t}\n\treturn s.error(c, \"\")\n}\n\n// stateEndTop is the state after finishing the top-level value,\n// such as after reading `{}` or `[1,2,3]`.\n// Only space characters should be seen now.\nfunc stateEndTop(s *scanner, c byte) int {\n\tif c != ' ' && c != '\\t' && c != '\\r' && c != '\\n' {\n\t\t// Complain about non-space byte on next call.\n\t\ts.error(c, \"after top-level value\")\n\t}\n\treturn scanEnd\n}\n\n// stateInString is the state after reading `\"`.\nfunc stateInString(s *scanner, c byte) int {\n\tif c == '\"' {\n\t\ts.step = stateEndValue\n\t\treturn scanContinue\n\t}\n\tif c == '\\\\' {\n\t\ts.step = stateInStringEsc\n\t\treturn scanContinue\n\t}\n\tif c < 0x20 {\n\t\treturn s.error(c, \"in string literal\")\n\t}\n\treturn scanContinue\n}\n\n// stateInStringEsc is the state after reading `\"\\` during a quoted string.\nfunc stateInStringEsc(s *scanner, c byte) int {\n\tswitch c {\n\tcase 'b', 'f', 'n', 'r', 't', '\\\\', '/', '\"':\n\t\ts.step = stateInString\n\t\treturn scanContinue\n\tcase 'u':\n\t\ts.step = stateInStringEscU\n\t\treturn scanContinue\n\t}\n\treturn s.error(c, \"in string escape code\")\n}\n\n// stateInStringEscU is the state after reading `\"\\u` during a quoted string.\nfunc stateInStringEscU(s *scanner, c byte) int {\n\tif '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {\n\t\ts.step = stateInStringEscU1\n\t\treturn scanContinue\n\t}\n\t// numbers\n\treturn s.error(c, \"in \\\\u hexadecimal character escape\")\n}\n\n// stateInStringEscU1 is the state after reading `\"\\u1` during a quoted string.\nfunc stateInStringEscU1(s *scanner, c byte) int {\n\tif '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {\n\t\ts.step = stateInStringEscU12\n\t\treturn scanContinue\n\t}\n\t// numbers\n\treturn s.error(c, \"in \\\\u hexadecimal character escape\")\n}\n\n// stateInStringEscU12 is the state after reading `\"\\u12` during a quoted string.\nfunc stateInStringEscU12(s *scanner, c byte) int {\n\tif '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {\n\t\ts.step = stateInStringEscU123\n\t\treturn scanContinue\n\t}\n\t// numbers\n\treturn s.error(c, \"in \\\\u hexadecimal character escape\")\n}\n\n// stateInStringEscU123 is the state after reading `\"\\u123` during a quoted string.\nfunc stateInStringEscU123(s *scanner, c byte) int {\n\tif '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {\n\t\ts.step = stateInString\n\t\treturn scanContinue\n\t}\n\t// numbers\n\treturn s.error(c, \"in \\\\u hexadecimal character escape\")\n}\n\n// stateNeg is the state after reading `-` during a number.\nfunc stateNeg(s *scanner, c byte) int {\n\tif c == '0' {\n\t\ts.step = state0\n\t\treturn scanContinue\n\t}\n\tif '1' <= c && c <= '9' {\n\t\ts.step = state1\n\t\treturn scanContinue\n\t}\n\treturn s.error(c, \"in numeric literal\")\n}\n\n// state1 is the state after reading a non-zero integer during a number,\n// such as after reading `1` or `100` but not `0`.\nfunc state1(s *scanner, c byte) int {\n\tif '0' <= c && c <= '9' {\n\t\ts.step = state1\n\t\treturn scanContinue\n\t}\n\treturn state0(s, c)\n}\n\n// state0 is the state after reading `0` during a number.\nfunc state0(s *scanner, c byte) int {\n\tif c == '.' {\n\t\ts.step = stateDot\n\t\treturn scanContinue\n\t}\n\tif c == 'e' || c == 'E' {\n\t\ts.step = stateE\n\t\treturn scanContinue\n\t}\n\treturn stateEndValue(s, c)\n}\n\n// stateDot is the state after reading the integer and decimal point in a number,\n// such as after reading `1.`.\nfunc stateDot(s *scanner, c byte) int {\n\tif '0' <= c && c <= '9' {\n\t\ts.step = stateDot0\n\t\treturn scanContinue\n\t}\n\treturn s.error(c, \"after decimal point in numeric literal\")\n}\n\n// stateDot0 is the state after reading the integer, decimal point, and subsequent\n// digits of a number, such as after reading `3.14`.\nfunc stateDot0(s *scanner, c byte) int {\n\tif '0' <= c && c <= '9' {\n\t\treturn scanContinue\n\t}\n\tif c == 'e' || c == 'E' {\n\t\ts.step = stateE\n\t\treturn scanContinue\n\t}\n\treturn stateEndValue(s, c)\n}\n\n// stateE is the state after reading the mantissa and e in a number,\n// such as after reading `314e` or `0.314e`.\nfunc stateE(s *scanner, c byte) int {\n\tif c == '+' || c == '-' {\n\t\ts.step = stateESign\n\t\treturn scanContinue\n\t}\n\treturn stateESign(s, c)\n}\n\n// stateESign is the state after reading the mantissa, e, and sign in a number,\n// such as after reading `314e-` or `0.314e+`.\nfunc stateESign(s *scanner, c byte) int {\n\tif '0' <= c && c <= '9' {\n\t\ts.step = stateE0\n\t\treturn scanContinue\n\t}\n\treturn s.error(c, \"in exponent of numeric literal\")\n}\n\n// stateE0 is the state after reading the mantissa, e, optional sign,\n// and at least one digit of the exponent in a number,\n// such as after reading `314e-2` or `0.314e+1` or `3.14e0`.\nfunc stateE0(s *scanner, c byte) int {\n\tif '0' <= c && c <= '9' {\n\t\treturn scanContinue\n\t}\n\treturn stateEndValue(s, c)\n}\n\n// stateT is the state after reading `t`.\nfunc stateT(s *scanner, c byte) int {\n\tif c == 'r' {\n\t\ts.step = stateTr\n\t\treturn scanContinue\n\t}\n\treturn s.error(c, \"in literal true (expecting 'r')\")\n}\n\n// stateTr is the state after reading `tr`.\nfunc stateTr(s *scanner, c byte) int {\n\tif c == 'u' {\n\t\ts.step = stateTru\n\t\treturn scanContinue\n\t}\n\treturn s.error(c, \"in literal true (expecting 'u')\")\n}\n\n// stateTru is the state after reading `tru`.\nfunc stateTru(s *scanner, c byte) int {\n\tif c == 'e' {\n\t\ts.step = stateEndValue\n\t\treturn scanContinue\n\t}\n\treturn s.error(c, \"in literal true (expecting 'e')\")\n}\n\n// stateF is the state after reading `f`.\nfunc stateF(s *scanner, c byte) int {\n\tif c == 'a' {\n\t\ts.step = stateFa\n\t\treturn scanContinue\n\t}\n\treturn s.error(c, \"in literal false (expecting 'a')\")\n}\n\n// stateFa is the state after reading `fa`.\nfunc stateFa(s *scanner, c byte) int {\n\tif c == 'l' {\n\t\ts.step = stateFal\n\t\treturn scanContinue\n\t}\n\treturn s.error(c, \"in literal false (expecting 'l')\")\n}\n\n// stateFal is the state after reading `fal`.\nfunc stateFal(s *scanner, c byte) int {\n\tif c == 's' {\n\t\ts.step = stateFals\n\t\treturn scanContinue\n\t}\n\treturn s.error(c, \"in literal false (expecting 's')\")\n}\n\n// stateFals is the state after reading `fals`.\nfunc stateFals(s *scanner, c byte) int {\n\tif c == 'e' {\n\t\ts.step = stateEndValue\n\t\treturn scanContinue\n\t}\n\treturn s.error(c, \"in literal false (expecting 'e')\")\n}\n\n// stateN is the state after reading `n`.\nfunc stateN(s *scanner, c byte) int {\n\tif c == 'u' {\n\t\ts.step = stateNu\n\t\treturn scanContinue\n\t}\n\treturn s.error(c, \"in literal null (expecting 'u')\")\n}\n\n// stateNu is the state after reading `nu`.\nfunc stateNu(s *scanner, c byte) int {\n\tif c == 'l' {\n\t\ts.step = stateNul\n\t\treturn scanContinue\n\t}\n\treturn s.error(c, \"in literal null (expecting 'l')\")\n}\n\n// stateNul is the state after reading `nul`.\nfunc stateNul(s *scanner, c byte) int {\n\tif c == 'l' {\n\t\ts.step = stateEndValue\n\t\treturn scanContinue\n\t}\n\treturn s.error(c, \"in literal null (expecting 'l')\")\n}\n\n// stateError is the state after reaching a syntax error,\n// such as after reading `[1}` or `5.1.2`.\nfunc stateError(s *scanner, c byte) int {\n\treturn scanError\n}\n\n// error records an error and switches to the error state.\nfunc (s *scanner) error(c byte, context string) int {\n\ts.step = stateError\n\ts.err = &SyntaxError{\"invalid character \" + quoteChar(c) + \" \" + context, s.bytes}\n\treturn scanError\n}\n\n// quoteChar formats c as a quoted character literal\nfunc quoteChar(c byte) string {\n\t// special cases - different from quoted strings\n\tif c == '\\'' {\n\t\treturn `'\\''`\n\t}\n\tif c == '\"' {\n\t\treturn `'\"'`\n\t}\n\n\t// use quoted string with different quotation marks\n\ts := strconv.Quote(string(c))\n\treturn \"'\" + s[1:len(s)-1] + \"'\"\n}\n\n// undo causes the scanner to return scanCode from the next state transition.\n// This gives callers a simple 1-byte undo mechanism.\nfunc (s *scanner) undo(scanCode int) {\n\tif s.redo {\n\t\tpanic(\"json: invalid use of scanner\")\n\t}\n\ts.redoCode = scanCode\n\ts.redoState = s.step\n\ts.step = stateRedo\n\ts.redo = true\n}\n\n// stateRedo helps implement the scanner's 1-byte undo.\nfunc stateRedo(s *scanner, c byte) int {\n\ts.redo = false\n\ts.step = s.redoState\n\treturn s.redoCode\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/json/stream.go",
    "content": "// Copyright 2010 The Go 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 json\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"io\"\n)\n\n// A Decoder reads and decodes JSON objects from an input stream.\ntype Decoder struct {\n\tr     io.Reader\n\tbuf   []byte\n\td     decodeState\n\tscanp int // start of unread data in buf\n\tscan  scanner\n\terr   error\n\n\ttokenState int\n\ttokenStack []int\n}\n\n// NewDecoder returns a new decoder that reads from r.\n//\n// The decoder introduces its own buffering and may\n// read data from r beyond the JSON values requested.\nfunc NewDecoder(r io.Reader) *Decoder {\n\treturn &Decoder{r: r}\n}\n\n// Deprecated: Use `SetNumberType` instead\n// UseNumber causes the Decoder to unmarshal a number into an interface{} as a\n// Number instead of as a float64.\nfunc (dec *Decoder) UseNumber() { dec.d.numberType = UnmarshalJSONNumber }\n\n// SetNumberType causes the Decoder to unmarshal a number into an interface{} as a\n// Number, float64 or int64 depending on `t` enum value.\nfunc (dec *Decoder) SetNumberType(t NumberUnmarshalType) { dec.d.numberType = t }\n\n// Decode reads the next JSON-encoded value from its\n// input and stores it in the value pointed to by v.\n//\n// See the documentation for Unmarshal for details about\n// the conversion of JSON into a Go value.\nfunc (dec *Decoder) Decode(v interface{}) error {\n\tif dec.err != nil {\n\t\treturn dec.err\n\t}\n\n\tif err := dec.tokenPrepareForDecode(); err != nil {\n\t\treturn err\n\t}\n\n\tif !dec.tokenValueAllowed() {\n\t\treturn &SyntaxError{msg: \"not at beginning of value\"}\n\t}\n\n\t// Read whole value into buffer.\n\tn, err := dec.readValue()\n\tif err != nil {\n\t\treturn err\n\t}\n\tdec.d.init(dec.buf[dec.scanp : dec.scanp+n])\n\tdec.scanp += n\n\n\t// Don't save err from unmarshal into dec.err:\n\t// the connection is still usable since we read a complete JSON\n\t// object from it before the error happened.\n\terr = dec.d.unmarshal(v)\n\n\t// fixup token streaming state\n\tdec.tokenValueEnd()\n\n\treturn err\n}\n\n// Buffered returns a reader of the data remaining in the Decoder's\n// buffer. The reader is valid until the next call to Decode.\nfunc (dec *Decoder) Buffered() io.Reader {\n\treturn bytes.NewReader(dec.buf[dec.scanp:])\n}\n\n// readValue reads a JSON value into dec.buf.\n// It returns the length of the encoding.\nfunc (dec *Decoder) readValue() (int, error) {\n\tdec.scan.reset()\n\n\tscanp := dec.scanp\n\tvar err error\nInput:\n\tfor {\n\t\t// Look in the buffer for a new value.\n\t\tfor i, c := range dec.buf[scanp:] {\n\t\t\tdec.scan.bytes++\n\t\t\tv := dec.scan.step(&dec.scan, c)\n\t\t\tif v == scanEnd {\n\t\t\t\tscanp += i\n\t\t\t\tbreak Input\n\t\t\t}\n\t\t\t// scanEnd is delayed one byte.\n\t\t\t// We might block trying to get that byte from src,\n\t\t\t// so instead invent a space byte.\n\t\t\tif (v == scanEndObject || v == scanEndArray) && dec.scan.step(&dec.scan, ' ') == scanEnd {\n\t\t\t\tscanp += i + 1\n\t\t\t\tbreak Input\n\t\t\t}\n\t\t\tif v == scanError {\n\t\t\t\tdec.err = dec.scan.err\n\t\t\t\treturn 0, dec.scan.err\n\t\t\t}\n\t\t}\n\t\tscanp = len(dec.buf)\n\n\t\t// Did the last read have an error?\n\t\t// Delayed until now to allow buffer scan.\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tif dec.scan.step(&dec.scan, ' ') == scanEnd {\n\t\t\t\t\tbreak Input\n\t\t\t\t}\n\t\t\t\tif nonSpace(dec.buf) {\n\t\t\t\t\terr = io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t}\n\t\t\tdec.err = err\n\t\t\treturn 0, err\n\t\t}\n\n\t\tn := scanp - dec.scanp\n\t\terr = dec.refill()\n\t\tscanp = dec.scanp + n\n\t}\n\treturn scanp - dec.scanp, nil\n}\n\nfunc (dec *Decoder) refill() error {\n\t// Make room to read more into the buffer.\n\t// First slide down data already consumed.\n\tif dec.scanp > 0 {\n\t\tn := copy(dec.buf, dec.buf[dec.scanp:])\n\t\tdec.buf = dec.buf[:n]\n\t\tdec.scanp = 0\n\t}\n\n\t// Grow buffer if not large enough.\n\tconst minRead = 512\n\tif cap(dec.buf)-len(dec.buf) < minRead {\n\t\tnewBuf := make([]byte, len(dec.buf), 2*cap(dec.buf)+minRead)\n\t\tcopy(newBuf, dec.buf)\n\t\tdec.buf = newBuf\n\t}\n\n\t// Read.  Delay error for next iteration (after scan).\n\tn, err := dec.r.Read(dec.buf[len(dec.buf):cap(dec.buf)])\n\tdec.buf = dec.buf[0 : len(dec.buf)+n]\n\n\treturn err\n}\n\nfunc nonSpace(b []byte) bool {\n\tfor _, c := range b {\n\t\tif !isSpace(c) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// An Encoder writes JSON objects to an output stream.\ntype Encoder struct {\n\tw   io.Writer\n\terr error\n}\n\n// NewEncoder returns a new encoder that writes to w.\nfunc NewEncoder(w io.Writer) *Encoder {\n\treturn &Encoder{w: w}\n}\n\n// Encode writes the JSON encoding of v to the stream,\n// followed by a newline character.\n//\n// See the documentation for Marshal for details about the\n// conversion of Go values to JSON.\nfunc (enc *Encoder) Encode(v interface{}) error {\n\tif enc.err != nil {\n\t\treturn enc.err\n\t}\n\te := newEncodeState()\n\terr := e.marshal(v)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Terminate each value with a newline.\n\t// This makes the output look a little nicer\n\t// when debugging, and some kind of space\n\t// is required if the encoded value was a number,\n\t// so that the reader knows there aren't more\n\t// digits coming.\n\te.WriteByte('\\n')\n\n\tif _, err = enc.w.Write(e.Bytes()); err != nil {\n\t\tenc.err = err\n\t}\n\tencodeStatePool.Put(e)\n\treturn err\n}\n\n// RawMessage is a raw encoded JSON object.\n// It implements Marshaler and Unmarshaler and can\n// be used to delay JSON decoding or precompute a JSON encoding.\ntype RawMessage []byte\n\n// MarshalJSON returns *m as the JSON encoding of m.\nfunc (m *RawMessage) MarshalJSON() ([]byte, error) {\n\treturn *m, nil\n}\n\n// UnmarshalJSON sets *m to a copy of data.\nfunc (m *RawMessage) UnmarshalJSON(data []byte) error {\n\tif m == nil {\n\t\treturn errors.New(\"json.RawMessage: UnmarshalJSON on nil pointer\")\n\t}\n\t*m = append((*m)[0:0], data...)\n\treturn nil\n}\n\nvar _ Marshaler = (*RawMessage)(nil)\nvar _ Unmarshaler = (*RawMessage)(nil)\n\n// A Token holds a value of one of these types:\n//\n//\tDelim, for the four JSON delimiters [ ] { }\n//\tbool, for JSON booleans\n//\tfloat64, for JSON numbers\n//\tNumber, for JSON numbers\n//\tstring, for JSON string literals\n//\tnil, for JSON null\ntype Token interface{}\n\nconst (\n\ttokenTopValue = iota\n\ttokenArrayStart\n\ttokenArrayValue\n\ttokenArrayComma\n\ttokenObjectStart\n\ttokenObjectKey\n\ttokenObjectColon\n\ttokenObjectValue\n\ttokenObjectComma\n)\n\n// advance tokenstate from a separator state to a value state\nfunc (dec *Decoder) tokenPrepareForDecode() error {\n\t// Note: Not calling peek before switch, to avoid\n\t// putting peek into the standard Decode path.\n\t// peek is only called when using the Token API.\n\tswitch dec.tokenState {\n\tcase tokenArrayComma:\n\t\tc, err := dec.peek()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif c != ',' {\n\t\t\treturn &SyntaxError{\"expected comma after array element\", 0}\n\t\t}\n\t\tdec.scanp++\n\t\tdec.tokenState = tokenArrayValue\n\tcase tokenObjectColon:\n\t\tc, err := dec.peek()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif c != ':' {\n\t\t\treturn &SyntaxError{\"expected colon after object key\", 0}\n\t\t}\n\t\tdec.scanp++\n\t\tdec.tokenState = tokenObjectValue\n\t}\n\treturn nil\n}\n\nfunc (dec *Decoder) tokenValueAllowed() bool {\n\tswitch dec.tokenState {\n\tcase tokenTopValue, tokenArrayStart, tokenArrayValue, tokenObjectValue:\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (dec *Decoder) tokenValueEnd() {\n\tswitch dec.tokenState {\n\tcase tokenArrayStart, tokenArrayValue:\n\t\tdec.tokenState = tokenArrayComma\n\tcase tokenObjectValue:\n\t\tdec.tokenState = tokenObjectComma\n\t}\n}\n\n// A Delim is a JSON array or object delimiter, one of [ ] { or }.\ntype Delim rune\n\nfunc (d Delim) String() string {\n\treturn string(d)\n}\n\n// Token returns the next JSON token in the input stream.\n// At the end of the input stream, Token returns nil, io.EOF.\n//\n// Token guarantees that the delimiters [ ] { } it returns are\n// properly nested and matched: if Token encounters an unexpected\n// delimiter in the input, it will return an error.\n//\n// The input stream consists of basic JSON values—bool, string,\n// number, and null—along with delimiters [ ] { } of type Delim\n// to mark the start and end of arrays and objects.\n// Commas and colons are elided.\nfunc (dec *Decoder) Token() (Token, error) {\n\tfor {\n\t\tc, err := dec.peek()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tswitch c {\n\t\tcase '[':\n\t\t\tif !dec.tokenValueAllowed() {\n\t\t\t\treturn dec.tokenError(c)\n\t\t\t}\n\t\t\tdec.scanp++\n\t\t\tdec.tokenStack = append(dec.tokenStack, dec.tokenState)\n\t\t\tdec.tokenState = tokenArrayStart\n\t\t\treturn Delim('['), nil\n\n\t\tcase ']':\n\t\t\tif dec.tokenState != tokenArrayStart && dec.tokenState != tokenArrayComma {\n\t\t\t\treturn dec.tokenError(c)\n\t\t\t}\n\t\t\tdec.scanp++\n\t\t\tdec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]\n\t\t\tdec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]\n\t\t\tdec.tokenValueEnd()\n\t\t\treturn Delim(']'), nil\n\n\t\tcase '{':\n\t\t\tif !dec.tokenValueAllowed() {\n\t\t\t\treturn dec.tokenError(c)\n\t\t\t}\n\t\t\tdec.scanp++\n\t\t\tdec.tokenStack = append(dec.tokenStack, dec.tokenState)\n\t\t\tdec.tokenState = tokenObjectStart\n\t\t\treturn Delim('{'), nil\n\n\t\tcase '}':\n\t\t\tif dec.tokenState != tokenObjectStart && dec.tokenState != tokenObjectComma {\n\t\t\t\treturn dec.tokenError(c)\n\t\t\t}\n\t\t\tdec.scanp++\n\t\t\tdec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]\n\t\t\tdec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]\n\t\t\tdec.tokenValueEnd()\n\t\t\treturn Delim('}'), nil\n\n\t\tcase ':':\n\t\t\tif dec.tokenState != tokenObjectColon {\n\t\t\t\treturn dec.tokenError(c)\n\t\t\t}\n\t\t\tdec.scanp++\n\t\t\tdec.tokenState = tokenObjectValue\n\t\t\tcontinue\n\n\t\tcase ',':\n\t\t\tif dec.tokenState == tokenArrayComma {\n\t\t\t\tdec.scanp++\n\t\t\t\tdec.tokenState = tokenArrayValue\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif dec.tokenState == tokenObjectComma {\n\t\t\t\tdec.scanp++\n\t\t\t\tdec.tokenState = tokenObjectKey\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn dec.tokenError(c)\n\n\t\tcase '\"':\n\t\t\tif dec.tokenState == tokenObjectStart || dec.tokenState == tokenObjectKey {\n\t\t\t\tvar x string\n\t\t\t\told := dec.tokenState\n\t\t\t\tdec.tokenState = tokenTopValue\n\t\t\t\terr := dec.Decode(&x)\n\t\t\t\tdec.tokenState = old\n\t\t\t\tif err != nil {\n\t\t\t\t\tclearOffset(err)\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tdec.tokenState = tokenObjectColon\n\t\t\t\treturn x, nil\n\t\t\t}\n\t\t\tfallthrough\n\n\t\tdefault:\n\t\t\tif !dec.tokenValueAllowed() {\n\t\t\t\treturn dec.tokenError(c)\n\t\t\t}\n\t\t\tvar x interface{}\n\t\t\tif err := dec.Decode(&x); err != nil {\n\t\t\t\tclearOffset(err)\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn x, nil\n\t\t}\n\t}\n}\n\nfunc clearOffset(err error) {\n\tif s, ok := err.(*SyntaxError); ok {\n\t\ts.Offset = 0\n\t}\n}\n\nfunc (dec *Decoder) tokenError(c byte) (Token, error) {\n\tvar context string\n\tswitch dec.tokenState {\n\tcase tokenTopValue:\n\t\tcontext = \" looking for beginning of value\"\n\tcase tokenArrayStart, tokenArrayValue, tokenObjectValue:\n\t\tcontext = \" looking for beginning of value\"\n\tcase tokenArrayComma:\n\t\tcontext = \" after array element\"\n\tcase tokenObjectKey:\n\t\tcontext = \" looking for beginning of object key string\"\n\tcase tokenObjectColon:\n\t\tcontext = \" after object key\"\n\tcase tokenObjectComma:\n\t\tcontext = \" after object key:value pair\"\n\t}\n\treturn nil, &SyntaxError{\"invalid character \" + quoteChar(c) + \" \" + context, 0}\n}\n\n// More reports whether there is another element in the\n// current array or object being parsed.\nfunc (dec *Decoder) More() bool {\n\tc, err := dec.peek()\n\treturn err == nil && c != ']' && c != '}'\n}\n\nfunc (dec *Decoder) peek() (byte, error) {\n\tvar err error\n\tfor {\n\t\tfor i := dec.scanp; i < len(dec.buf); i++ {\n\t\t\tc := dec.buf[i]\n\t\t\tif isSpace(c) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tdec.scanp = i\n\t\t\treturn c, nil\n\t\t}\n\t\t// buffer has been scanned, now report any error\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\terr = dec.refill()\n\t}\n}\n\n/*\nTODO\n\n// EncodeToken writes the given JSON token to the stream.\n// It returns an error if the delimiters [ ] { } are not properly used.\n//\n// EncodeToken does not call Flush, because usually it is part of\n// a larger operation such as Encode, and those will call Flush when finished.\n// Callers that create an Encoder and then invoke EncodeToken directly,\n// without using Encode, need to call Flush when finished to ensure that\n// the JSON is written to the underlying writer.\nfunc (e *Encoder) EncodeToken(t Token) error  {\n\t...\n}\n\n*/\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/json/tags.go",
    "content": "// Copyright 2011 The Go 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 json\n\nimport (\n\t\"strings\"\n)\n\n// tagOptions is the string following a comma in a struct field's \"json\"\n// tag, or the empty string. It does not include the leading comma.\ntype tagOptions string\n\n// parseTag splits a struct field's json tag into its name and\n// comma-separated options.\nfunc parseTag(tag string) (string, tagOptions) {\n\tif idx := strings.Index(tag, \",\"); idx != -1 {\n\t\treturn tag[:idx], tagOptions(tag[idx+1:])\n\t}\n\treturn tag, tagOptions(\"\")\n}\n\n// Contains reports whether a comma-separated list of options\n// contains a particular substr flag. substr must be surrounded by a\n// string boundary or commas.\nfunc (o tagOptions) Contains(optionName string) bool {\n\tif len(o) == 0 {\n\t\treturn false\n\t}\n\ts := string(o)\n\tfor s != \"\" {\n\t\tvar next string\n\t\ti := strings.Index(s, \",\")\n\t\tif i >= 0 {\n\t\t\ts, next = s[:i], s[i+1:]\n\t\t}\n\t\tif s == optionName {\n\t\t\treturn true\n\t\t}\n\t\ts = next\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/jwe.go",
    "content": "/*-\n * Copyright 2014 Square Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage jose\n\nimport (\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/go-jose/go-jose/v4/json\"\n)\n\n// rawJSONWebEncryption represents a raw JWE JSON object. Used for parsing/serializing.\ntype rawJSONWebEncryption struct {\n\tProtected    *byteBuffer        `json:\"protected,omitempty\"`\n\tUnprotected  *rawHeader         `json:\"unprotected,omitempty\"`\n\tHeader       *rawHeader         `json:\"header,omitempty\"`\n\tRecipients   []rawRecipientInfo `json:\"recipients,omitempty\"`\n\tAad          *byteBuffer        `json:\"aad,omitempty\"`\n\tEncryptedKey *byteBuffer        `json:\"encrypted_key,omitempty\"`\n\tIv           *byteBuffer        `json:\"iv,omitempty\"`\n\tCiphertext   *byteBuffer        `json:\"ciphertext,omitempty\"`\n\tTag          *byteBuffer        `json:\"tag,omitempty\"`\n}\n\n// rawRecipientInfo represents a raw JWE Per-Recipient header JSON object. Used for parsing/serializing.\ntype rawRecipientInfo struct {\n\tHeader       *rawHeader `json:\"header,omitempty\"`\n\tEncryptedKey string     `json:\"encrypted_key,omitempty\"`\n}\n\n// JSONWebEncryption represents an encrypted JWE object after parsing.\ntype JSONWebEncryption struct {\n\tHeader                   Header\n\tprotected, unprotected   *rawHeader\n\trecipients               []recipientInfo\n\taad, iv, ciphertext, tag []byte\n\toriginal                 *rawJSONWebEncryption\n}\n\n// recipientInfo represents a raw JWE Per-Recipient header JSON object after parsing.\ntype recipientInfo struct {\n\theader       *rawHeader\n\tencryptedKey []byte\n}\n\n// GetAuthData retrieves the (optional) authenticated data attached to the object.\nfunc (obj JSONWebEncryption) GetAuthData() []byte {\n\tif obj.aad != nil {\n\t\tout := make([]byte, len(obj.aad))\n\t\tcopy(out, obj.aad)\n\t\treturn out\n\t}\n\n\treturn nil\n}\n\n// Get the merged header values\nfunc (obj JSONWebEncryption) mergedHeaders(recipient *recipientInfo) rawHeader {\n\tout := rawHeader{}\n\tout.merge(obj.protected)\n\tout.merge(obj.unprotected)\n\n\tif recipient != nil {\n\t\tout.merge(recipient.header)\n\t}\n\n\treturn out\n}\n\n// Get the additional authenticated data from a JWE object.\nfunc (obj JSONWebEncryption) computeAuthData() []byte {\n\tvar protected string\n\n\tswitch {\n\tcase obj.original != nil && obj.original.Protected != nil:\n\t\tprotected = obj.original.Protected.base64()\n\tcase obj.protected != nil:\n\t\tprotected = base64.RawURLEncoding.EncodeToString(mustSerializeJSON((obj.protected)))\n\tdefault:\n\t\tprotected = \"\"\n\t}\n\n\toutput := []byte(protected)\n\tif obj.aad != nil {\n\t\toutput = append(output, '.')\n\t\toutput = append(output, []byte(base64.RawURLEncoding.EncodeToString(obj.aad))...)\n\t}\n\n\treturn output\n}\n\nfunc containsKeyAlgorithm(haystack []KeyAlgorithm, needle KeyAlgorithm) bool {\n\tfor _, algorithm := range haystack {\n\t\tif algorithm == needle {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc containsContentEncryption(haystack []ContentEncryption, needle ContentEncryption) bool {\n\tfor _, algorithm := range haystack {\n\t\tif algorithm == needle {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// ParseEncrypted parses an encrypted message in JWE Compact or JWE JSON Serialization.\n//\n// https://datatracker.ietf.org/doc/html/rfc7516#section-3.1\n// https://datatracker.ietf.org/doc/html/rfc7516#section-3.2\n//\n// The keyAlgorithms and contentEncryption parameters are used to validate the \"alg\" and \"enc\"\n// header parameters respectively. They must be nonempty, and each \"alg\" or \"enc\" header in\n// parsed data must contain a value that is present in the corresponding parameter. That\n// includes the protected and unprotected headers as well as all recipients. To accept\n// multiple algorithms, pass a slice of all the algorithms you want to accept.\nfunc ParseEncrypted(input string,\n\tkeyEncryptionAlgorithms []KeyAlgorithm,\n\tcontentEncryption []ContentEncryption,\n) (*JSONWebEncryption, error) {\n\tinput = stripWhitespace(input)\n\tif strings.HasPrefix(input, \"{\") {\n\t\treturn ParseEncryptedJSON(input, keyEncryptionAlgorithms, contentEncryption)\n\t}\n\n\treturn ParseEncryptedCompact(input, keyEncryptionAlgorithms, contentEncryption)\n}\n\n// ParseEncryptedJSON parses a message in JWE JSON Serialization.\n//\n// https://datatracker.ietf.org/doc/html/rfc7516#section-3.2\nfunc ParseEncryptedJSON(\n\tinput string,\n\tkeyEncryptionAlgorithms []KeyAlgorithm,\n\tcontentEncryption []ContentEncryption,\n) (*JSONWebEncryption, error) {\n\tvar parsed rawJSONWebEncryption\n\terr := json.Unmarshal([]byte(input), &parsed)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn parsed.sanitized(keyEncryptionAlgorithms, contentEncryption)\n}\n\n// sanitized produces a cleaned-up JWE object from the raw JSON.\nfunc (parsed *rawJSONWebEncryption) sanitized(\n\tkeyEncryptionAlgorithms []KeyAlgorithm,\n\tcontentEncryption []ContentEncryption,\n) (*JSONWebEncryption, error) {\n\tif len(keyEncryptionAlgorithms) == 0 {\n\t\treturn nil, errors.New(\"go-jose/go-jose: no key algorithms provided\")\n\t}\n\tif len(contentEncryption) == 0 {\n\t\treturn nil, errors.New(\"go-jose/go-jose: no content encryption algorithms provided\")\n\t}\n\n\tobj := &JSONWebEncryption{\n\t\toriginal:    parsed,\n\t\tunprotected: parsed.Unprotected,\n\t}\n\n\t// Check that there is not a nonce in the unprotected headers\n\tif parsed.Unprotected != nil {\n\t\tif nonce := parsed.Unprotected.getNonce(); nonce != \"\" {\n\t\t\treturn nil, ErrUnprotectedNonce\n\t\t}\n\t}\n\tif parsed.Header != nil {\n\t\tif nonce := parsed.Header.getNonce(); nonce != \"\" {\n\t\t\treturn nil, ErrUnprotectedNonce\n\t\t}\n\t}\n\n\tif parsed.Protected != nil && len(parsed.Protected.bytes()) > 0 {\n\t\terr := json.Unmarshal(parsed.Protected.bytes(), &obj.protected)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid protected header: %s, %s\", err, parsed.Protected.base64())\n\t\t}\n\t}\n\n\t// Note: this must be called _after_ we parse the protected header,\n\t// otherwise fields from the protected header will not get picked up.\n\tvar err error\n\tmergedHeaders := obj.mergedHeaders(nil)\n\tobj.Header, err = mergedHeaders.sanitized()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: cannot sanitize merged headers: %v (%v)\", err, mergedHeaders)\n\t}\n\n\tif len(parsed.Recipients) == 0 {\n\t\tobj.recipients = []recipientInfo{\n\t\t\t{\n\t\t\t\theader:       parsed.Header,\n\t\t\t\tencryptedKey: parsed.EncryptedKey.bytes(),\n\t\t\t},\n\t\t}\n\t} else {\n\t\tobj.recipients = make([]recipientInfo, len(parsed.Recipients))\n\t\tfor r := range parsed.Recipients {\n\t\t\tencryptedKey, err := base64.RawURLEncoding.DecodeString(parsed.Recipients[r].EncryptedKey)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\t// Check that there is not a nonce in the unprotected header\n\t\t\tif parsed.Recipients[r].Header != nil && parsed.Recipients[r].Header.getNonce() != \"\" {\n\t\t\t\treturn nil, ErrUnprotectedNonce\n\t\t\t}\n\n\t\t\tobj.recipients[r].header = parsed.Recipients[r].Header\n\t\t\tobj.recipients[r].encryptedKey = encryptedKey\n\t\t}\n\t}\n\n\tfor i, recipient := range obj.recipients {\n\t\theaders := obj.mergedHeaders(&recipient)\n\t\tif headers.getAlgorithm() == \"\" {\n\t\t\treturn nil, fmt.Errorf(`go-jose/go-jose: recipient %d: missing header \"alg\"`, i)\n\t\t}\n\t\tif headers.getEncryption() == \"\" {\n\t\t\treturn nil, fmt.Errorf(`go-jose/go-jose: recipient %d: missing header \"enc\"`, i)\n\t\t}\n\t\terr := validateAlgEnc(headers, keyEncryptionAlgorithms, contentEncryption)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: recipient %d: %s\", i, err)\n\t\t}\n\n\t}\n\n\tif obj.protected != nil {\n\t\terr := validateAlgEnc(*obj.protected, keyEncryptionAlgorithms, contentEncryption)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: protected header: %s\", err)\n\t\t}\n\t}\n\tif obj.unprotected != nil {\n\t\terr := validateAlgEnc(*obj.unprotected, keyEncryptionAlgorithms, contentEncryption)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: unprotected header: %s\", err)\n\t\t}\n\t}\n\n\tobj.iv = parsed.Iv.bytes()\n\tobj.ciphertext = parsed.Ciphertext.bytes()\n\tobj.tag = parsed.Tag.bytes()\n\tobj.aad = parsed.Aad.bytes()\n\n\treturn obj, nil\n}\n\nfunc validateAlgEnc(headers rawHeader, keyAlgorithms []KeyAlgorithm, contentEncryption []ContentEncryption) error {\n\talg := headers.getAlgorithm()\n\tenc := headers.getEncryption()\n\tif alg != \"\" && !containsKeyAlgorithm(keyAlgorithms, alg) {\n\t\treturn fmt.Errorf(\"unexpected key algorithm %q; expected %q\", alg, keyAlgorithms)\n\t}\n\tif enc != \"\" && !containsContentEncryption(contentEncryption, enc) {\n\t\treturn fmt.Errorf(\"unexpected content encryption algorithm %q; expected %q\", enc, contentEncryption)\n\t}\n\treturn nil\n}\n\n// ParseEncryptedCompact parses a message in JWE Compact Serialization.\n//\n// https://datatracker.ietf.org/doc/html/rfc7516#section-3.1\nfunc ParseEncryptedCompact(\n\tinput string,\n\tkeyAlgorithms []KeyAlgorithm,\n\tcontentEncryption []ContentEncryption,\n) (*JSONWebEncryption, error) {\n\tvar parts [5]string\n\tvar ok bool\n\n\tfor i := range 4 {\n\t\tparts[i], input, ok = strings.Cut(input, \".\")\n\t\tif !ok {\n\t\t\treturn nil, errors.New(\"go-jose/go-jose: compact JWE format must have five parts\")\n\t\t}\n\t}\n\t// Validate that the last part does not contain more dots\n\tif strings.ContainsRune(input, '.') {\n\t\treturn nil, errors.New(\"go-jose/go-jose: compact JWE format must have five parts\")\n\t}\n\tparts[4] = input\n\n\trawProtected, err := base64.RawURLEncoding.DecodeString(parts[0])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tencryptedKey, err := base64.RawURLEncoding.DecodeString(parts[1])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tiv, err := base64.RawURLEncoding.DecodeString(parts[2])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tciphertext, err := base64.RawURLEncoding.DecodeString(parts[3])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttag, err := base64.RawURLEncoding.DecodeString(parts[4])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\traw := &rawJSONWebEncryption{\n\t\tProtected:    newBuffer(rawProtected),\n\t\tEncryptedKey: newBuffer(encryptedKey),\n\t\tIv:           newBuffer(iv),\n\t\tCiphertext:   newBuffer(ciphertext),\n\t\tTag:          newBuffer(tag),\n\t}\n\n\treturn raw.sanitized(keyAlgorithms, contentEncryption)\n}\n\n// CompactSerialize serializes an object using the compact serialization format.\nfunc (obj JSONWebEncryption) CompactSerialize() (string, error) {\n\tif len(obj.recipients) != 1 || obj.unprotected != nil ||\n\t\tobj.protected == nil || obj.recipients[0].header != nil {\n\t\treturn \"\", ErrNotSupported\n\t}\n\n\tserializedProtected := mustSerializeJSON(obj.protected)\n\n\treturn base64JoinWithDots(\n\t\tserializedProtected,\n\t\tobj.recipients[0].encryptedKey,\n\t\tobj.iv,\n\t\tobj.ciphertext,\n\t\tobj.tag,\n\t), nil\n}\n\n// FullSerialize serializes an object using the full JSON serialization format.\nfunc (obj JSONWebEncryption) FullSerialize() string {\n\traw := rawJSONWebEncryption{\n\t\tUnprotected:  obj.unprotected,\n\t\tIv:           newBuffer(obj.iv),\n\t\tCiphertext:   newBuffer(obj.ciphertext),\n\t\tEncryptedKey: newBuffer(obj.recipients[0].encryptedKey),\n\t\tTag:          newBuffer(obj.tag),\n\t\tAad:          newBuffer(obj.aad),\n\t\tRecipients:   []rawRecipientInfo{},\n\t}\n\n\tif len(obj.recipients) > 1 {\n\t\tfor _, recipient := range obj.recipients {\n\t\t\tinfo := rawRecipientInfo{\n\t\t\t\tHeader:       recipient.header,\n\t\t\t\tEncryptedKey: base64.RawURLEncoding.EncodeToString(recipient.encryptedKey),\n\t\t\t}\n\t\t\traw.Recipients = append(raw.Recipients, info)\n\t\t}\n\t} else {\n\t\t// Use flattened serialization\n\t\traw.Header = obj.recipients[0].header\n\t\traw.EncryptedKey = newBuffer(obj.recipients[0].encryptedKey)\n\t}\n\n\tif obj.protected != nil {\n\t\traw.Protected = newBuffer(mustSerializeJSON(obj.protected))\n\t}\n\n\treturn string(mustSerializeJSON(raw))\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/jwk.go",
    "content": "/*-\n * Copyright 2014 Square Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage jose\n\nimport (\n\t\"bytes\"\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/elliptic\"\n\t\"crypto/rsa\"\n\t\"crypto/sha1\"\n\t\"crypto/sha256\"\n\t\"crypto/x509\"\n\t\"encoding/base64\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"net/url\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"github.com/go-jose/go-jose/v4/json\"\n)\n\n// rawJSONWebKey represents a public or private key in JWK format, used for parsing/serializing.\ntype rawJSONWebKey struct {\n\tUse string      `json:\"use,omitempty\"`\n\tKty string      `json:\"kty,omitempty\"`\n\tKid string      `json:\"kid,omitempty\"`\n\tCrv string      `json:\"crv,omitempty\"`\n\tAlg string      `json:\"alg,omitempty\"`\n\tK   *byteBuffer `json:\"k,omitempty\"`\n\tX   *byteBuffer `json:\"x,omitempty\"`\n\tY   *byteBuffer `json:\"y,omitempty\"`\n\tN   *byteBuffer `json:\"n,omitempty\"`\n\tE   *byteBuffer `json:\"e,omitempty\"`\n\t// -- Following fields are only used for private keys --\n\t// RSA uses D, P and Q, while ECDSA uses only D. Fields Dp, Dq, and Qi are\n\t// completely optional. Therefore for RSA/ECDSA, D != nil is a contract that\n\t// we have a private key whereas D == nil means we have only a public key.\n\tD  *byteBuffer `json:\"d,omitempty\"`\n\tP  *byteBuffer `json:\"p,omitempty\"`\n\tQ  *byteBuffer `json:\"q,omitempty\"`\n\tDp *byteBuffer `json:\"dp,omitempty\"`\n\tDq *byteBuffer `json:\"dq,omitempty\"`\n\tQi *byteBuffer `json:\"qi,omitempty\"`\n\t// Certificates\n\tX5c       []string `json:\"x5c,omitempty\"`\n\tX5u       string   `json:\"x5u,omitempty\"`\n\tX5tSHA1   string   `json:\"x5t,omitempty\"`\n\tX5tSHA256 string   `json:\"x5t#S256,omitempty\"`\n}\n\n// JSONWebKey represents a public or private key in JWK format. It can be\n// marshaled into JSON and unmarshaled from JSON.\ntype JSONWebKey struct {\n\t// Key is the Go in-memory representation of this key. It must have one\n\t// of these types:\n\t//  - ed25519.PublicKey\n\t//  - ed25519.PrivateKey\n\t//  - *ecdsa.PublicKey\n\t//  - *ecdsa.PrivateKey\n\t//  - *rsa.PublicKey\n\t//  - *rsa.PrivateKey\n\t//  - []byte (a symmetric key)\n\t//\n\t// When marshaling this JSONWebKey into JSON, the \"kty\" header parameter\n\t// will be automatically set based on the type of this field.\n\tKey interface{}\n\t// Key identifier, parsed from `kid` header.\n\tKeyID string\n\t// Key algorithm, parsed from `alg` header.\n\tAlgorithm string\n\t// Key use, parsed from `use` header.\n\tUse string\n\n\t// X.509 certificate chain, parsed from `x5c` header.\n\tCertificates []*x509.Certificate\n\t// X.509 certificate URL, parsed from `x5u` header.\n\tCertificatesURL *url.URL\n\t// X.509 certificate thumbprint (SHA-1), parsed from `x5t` header.\n\tCertificateThumbprintSHA1 []byte\n\t// X.509 certificate thumbprint (SHA-256), parsed from `x5t#S256` header.\n\tCertificateThumbprintSHA256 []byte\n}\n\n// MarshalJSON serializes the given key to its JSON representation.\nfunc (k JSONWebKey) MarshalJSON() ([]byte, error) {\n\tvar raw *rawJSONWebKey\n\tvar err error\n\n\tswitch key := k.Key.(type) {\n\tcase ed25519.PublicKey:\n\t\traw = fromEdPublicKey(key)\n\tcase *ecdsa.PublicKey:\n\t\traw, err = fromEcPublicKey(key)\n\tcase *rsa.PublicKey:\n\t\traw = fromRsaPublicKey(key)\n\tcase ed25519.PrivateKey:\n\t\traw, err = fromEdPrivateKey(key)\n\tcase *ecdsa.PrivateKey:\n\t\traw, err = fromEcPrivateKey(key)\n\tcase *rsa.PrivateKey:\n\t\traw, err = fromRsaPrivateKey(key)\n\tcase []byte:\n\t\traw, err = fromSymmetricKey(key)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: unknown key type '%s'\", reflect.TypeOf(key))\n\t}\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\traw.Kid = k.KeyID\n\traw.Alg = k.Algorithm\n\traw.Use = k.Use\n\n\tfor _, cert := range k.Certificates {\n\t\traw.X5c = append(raw.X5c, base64.StdEncoding.EncodeToString(cert.Raw))\n\t}\n\n\tx5tSHA1Len := len(k.CertificateThumbprintSHA1)\n\tx5tSHA256Len := len(k.CertificateThumbprintSHA256)\n\tif x5tSHA1Len > 0 {\n\t\tif x5tSHA1Len != sha1.Size {\n\t\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid SHA-1 thumbprint (must be %d bytes, not %d)\", sha1.Size, x5tSHA1Len)\n\t\t}\n\t\traw.X5tSHA1 = base64.RawURLEncoding.EncodeToString(k.CertificateThumbprintSHA1)\n\t}\n\tif x5tSHA256Len > 0 {\n\t\tif x5tSHA256Len != sha256.Size {\n\t\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid SHA-256 thumbprint (must be %d bytes, not %d)\", sha256.Size, x5tSHA256Len)\n\t\t}\n\t\traw.X5tSHA256 = base64.RawURLEncoding.EncodeToString(k.CertificateThumbprintSHA256)\n\t}\n\n\t// If cert chain is attached (as opposed to being behind a URL), check the\n\t// keys thumbprints to make sure they match what is expected. This is to\n\t// ensure we don't accidentally produce a JWK with semantically inconsistent\n\t// data in the headers.\n\tif len(k.Certificates) > 0 {\n\t\texpectedSHA1 := sha1.Sum(k.Certificates[0].Raw)\n\t\texpectedSHA256 := sha256.Sum256(k.Certificates[0].Raw)\n\n\t\tif len(k.CertificateThumbprintSHA1) > 0 && !bytes.Equal(k.CertificateThumbprintSHA1, expectedSHA1[:]) {\n\t\t\treturn nil, errors.New(\"go-jose/go-jose: invalid SHA-1 thumbprint, does not match cert chain\")\n\t\t}\n\t\tif len(k.CertificateThumbprintSHA256) > 0 && !bytes.Equal(k.CertificateThumbprintSHA256, expectedSHA256[:]) {\n\t\t\treturn nil, errors.New(\"go-jose/go-jose: invalid or SHA-256 thumbprint, does not match cert chain\")\n\t\t}\n\t}\n\n\tif k.CertificatesURL != nil {\n\t\traw.X5u = k.CertificatesURL.String()\n\t}\n\n\treturn json.Marshal(raw)\n}\n\n// UnmarshalJSON reads a key from its JSON representation.\n//\n// Returns ErrUnsupportedKeyType for unrecognized or unsupported \"kty\" header values.\nfunc (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {\n\tvar raw rawJSONWebKey\n\terr = json.Unmarshal(data, &raw)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcerts, err := parseCertificateChain(raw.X5c)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"go-jose/go-jose: failed to unmarshal x5c field: %s\", err)\n\t}\n\n\tvar key interface{}\n\tvar certPub interface{}\n\tvar keyPub interface{}\n\n\tif len(certs) > 0 {\n\t\t// We need to check that leaf public key matches the key embedded in this\n\t\t// JWK, as required by the standard (see RFC 7517, Section 4.7). Otherwise\n\t\t// the JWK parsed could be semantically invalid. Technically, should also\n\t\t// check key usage fields and other extensions on the cert here, but the\n\t\t// standard doesn't exactly explain how they're supposed to map from the\n\t\t// JWK representation to the X.509 extensions.\n\t\tcertPub = certs[0].PublicKey\n\t}\n\n\tswitch raw.Kty {\n\tcase \"EC\":\n\t\tif raw.D != nil {\n\t\t\tkey, err = raw.ecPrivateKey()\n\t\t\tif err == nil {\n\t\t\t\tkeyPub = key.(*ecdsa.PrivateKey).Public()\n\t\t\t}\n\t\t} else {\n\t\t\tkey, err = raw.ecPublicKey()\n\t\t\tkeyPub = key\n\t\t}\n\tcase \"RSA\":\n\t\tif raw.D != nil {\n\t\t\tkey, err = raw.rsaPrivateKey()\n\t\t\tif err == nil {\n\t\t\t\tkeyPub = key.(*rsa.PrivateKey).Public()\n\t\t\t}\n\t\t} else {\n\t\t\tkey, err = raw.rsaPublicKey()\n\t\t\tkeyPub = key\n\t\t}\n\tcase \"oct\":\n\t\tif certPub != nil {\n\t\t\treturn errors.New(\"go-jose/go-jose: invalid JWK, found 'oct' (symmetric) key with cert chain\")\n\t\t}\n\t\tkey, err = raw.symmetricKey()\n\tcase \"OKP\":\n\t\tif raw.Crv == \"Ed25519\" {\n\t\t\tif raw.D != nil {\n\t\t\t\tkey, err = raw.edPrivateKey()\n\t\t\t\tif err == nil {\n\t\t\t\t\tkeyPub = key.(ed25519.PrivateKey).Public()\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tkey, err = raw.edPublicKey()\n\t\t\t\tkeyPub = key\n\t\t\t}\n\t\t}\n\tcase \"\":\n\t\t// kty MUST be present\n\t\terr = fmt.Errorf(\"go-jose/go-jose: missing json web key type\")\n\t}\n\n\tif err != nil {\n\t\treturn\n\t}\n\n\tif key == nil {\n\t\t// RFC 7517:\n\t\t// 5.  JWK Set Format\n\t\t// ...\n\t\t//     Implementations SHOULD ignore JWKs within a JWK Set that use \"kty\"\n\t\t//     (key type) values that are not understood by them, that are missing\n\t\t//     required members, or for which values are out of the supported\n\t\t//     ranges.\n\t\treturn ErrUnsupportedKeyType\n\t}\n\n\tif certPub != nil && keyPub != nil {\n\t\tif !reflect.DeepEqual(certPub, keyPub) {\n\t\t\treturn errors.New(\"go-jose/go-jose: invalid JWK, public keys in key and x5c fields do not match\")\n\t\t}\n\t}\n\n\t*k = JSONWebKey{Key: key, KeyID: raw.Kid, Algorithm: raw.Alg, Use: raw.Use, Certificates: certs}\n\n\tif raw.X5u != \"\" {\n\t\tk.CertificatesURL, err = url.Parse(raw.X5u)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"go-jose/go-jose: invalid JWK, x5u header is invalid URL: %w\", err)\n\t\t}\n\t}\n\n\t// x5t parameters are base64url-encoded SHA thumbprints\n\t// See RFC 7517, Section 4.8, https://tools.ietf.org/html/rfc7517#section-4.8\n\tx5tSHA1bytes, err := base64.RawURLEncoding.DecodeString(raw.X5tSHA1)\n\tif err != nil {\n\t\treturn errors.New(\"go-jose/go-jose: invalid JWK, x5t header has invalid encoding\")\n\t}\n\n\t// RFC 7517, Section 4.8 is ambiguous as to whether the digest output should be byte or hex,\n\t// for this reason, after base64 decoding, if the size is sha1.Size it's likely that the value is a byte encoded\n\t// checksum so we skip this. Otherwise if the checksum was hex encoded we expect a 40 byte sized array so we'll\n\t// try to hex decode it. When Marshalling this value we'll always use a base64 encoded version of byte format checksum.\n\tif len(x5tSHA1bytes) == 2*sha1.Size {\n\t\thx, err := hex.DecodeString(string(x5tSHA1bytes))\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"go-jose/go-jose: invalid JWK, unable to hex decode x5t: %v\", err)\n\n\t\t}\n\t\tx5tSHA1bytes = hx\n\t}\n\n\tk.CertificateThumbprintSHA1 = x5tSHA1bytes\n\n\tx5tSHA256bytes, err := base64.RawURLEncoding.DecodeString(raw.X5tSHA256)\n\tif err != nil {\n\t\treturn errors.New(\"go-jose/go-jose: invalid JWK, x5t#S256 header has invalid encoding\")\n\t}\n\n\tif len(x5tSHA256bytes) == 2*sha256.Size {\n\t\thx256, err := hex.DecodeString(string(x5tSHA256bytes))\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"go-jose/go-jose: invalid JWK, unable to hex decode x5t#S256: %v\", err)\n\t\t}\n\t\tx5tSHA256bytes = hx256\n\t}\n\n\tk.CertificateThumbprintSHA256 = x5tSHA256bytes\n\n\tx5tSHA1Len := len(k.CertificateThumbprintSHA1)\n\tx5tSHA256Len := len(k.CertificateThumbprintSHA256)\n\tif x5tSHA1Len > 0 && x5tSHA1Len != sha1.Size {\n\t\treturn errors.New(\"go-jose/go-jose: invalid JWK, x5t header is of incorrect size\")\n\t}\n\tif x5tSHA256Len > 0 && x5tSHA256Len != sha256.Size {\n\t\treturn errors.New(\"go-jose/go-jose: invalid JWK, x5t#S256 header is of incorrect size\")\n\t}\n\n\t// If certificate chain *and* thumbprints are set, verify correctness.\n\tif len(k.Certificates) > 0 {\n\t\tleaf := k.Certificates[0]\n\t\tsha1sum := sha1.Sum(leaf.Raw)\n\t\tsha256sum := sha256.Sum256(leaf.Raw)\n\n\t\tif len(k.CertificateThumbprintSHA1) > 0 && !bytes.Equal(sha1sum[:], k.CertificateThumbprintSHA1) {\n\t\t\treturn errors.New(\"go-jose/go-jose: invalid JWK, x5c thumbprint does not match x5t value\")\n\t\t}\n\n\t\tif len(k.CertificateThumbprintSHA256) > 0 && !bytes.Equal(sha256sum[:], k.CertificateThumbprintSHA256) {\n\t\t\treturn errors.New(\"go-jose/go-jose: invalid JWK, x5c thumbprint does not match x5t#S256 value\")\n\t\t}\n\t}\n\n\treturn\n}\n\n// JSONWebKeySet represents a JWK Set object.\ntype JSONWebKeySet struct {\n\tKeys []JSONWebKey `json:\"keys\"`\n}\n\n// Key convenience method returns keys by key ID. Specification states\n// that a JWK Set \"SHOULD\" use distinct key IDs, but allows for some\n// cases where they are not distinct. Hence method returns a slice\n// of JSONWebKeys.\nfunc (s *JSONWebKeySet) Key(kid string) []JSONWebKey {\n\tvar keys []JSONWebKey\n\tfor _, key := range s.Keys {\n\t\tif key.KeyID == kid {\n\t\t\tkeys = append(keys, key)\n\t\t}\n\t}\n\n\treturn keys\n}\n\nconst rsaThumbprintTemplate = `{\"e\":\"%s\",\"kty\":\"RSA\",\"n\":\"%s\"}`\nconst ecThumbprintTemplate = `{\"crv\":\"%s\",\"kty\":\"EC\",\"x\":\"%s\",\"y\":\"%s\"}`\nconst edThumbprintTemplate = `{\"crv\":\"%s\",\"kty\":\"OKP\",\"x\":\"%s\"}`\n\nfunc ecThumbprintInput(curve elliptic.Curve, x, y *big.Int) (string, error) {\n\tcoordLength := curveSize(curve)\n\tcrv, err := curveName(curve)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif len(x.Bytes()) > coordLength || len(y.Bytes()) > coordLength {\n\t\treturn \"\", errors.New(\"go-jose/go-jose: invalid elliptic key (too large)\")\n\t}\n\n\treturn fmt.Sprintf(ecThumbprintTemplate, crv,\n\t\tnewFixedSizeBuffer(x.Bytes(), coordLength).base64(),\n\t\tnewFixedSizeBuffer(y.Bytes(), coordLength).base64()), nil\n}\n\nfunc rsaThumbprintInput(n *big.Int, e int) (string, error) {\n\treturn fmt.Sprintf(rsaThumbprintTemplate,\n\t\tnewBufferFromInt(uint64(e)).base64(),\n\t\tnewBuffer(n.Bytes()).base64()), nil\n}\n\nfunc edThumbprintInput(ed ed25519.PublicKey) (string, error) {\n\tcrv := \"Ed25519\"\n\tif len(ed) > 32 {\n\t\treturn \"\", errors.New(\"go-jose/go-jose: invalid elliptic key (too large)\")\n\t}\n\treturn fmt.Sprintf(edThumbprintTemplate, crv,\n\t\tnewFixedSizeBuffer(ed, 32).base64()), nil\n}\n\n// Thumbprint computes the JWK Thumbprint of a key using the\n// indicated hash algorithm.\nfunc (k *JSONWebKey) Thumbprint(hash crypto.Hash) ([]byte, error) {\n\tvar input string\n\tvar err error\n\tswitch key := k.Key.(type) {\n\tcase ed25519.PublicKey:\n\t\tinput, err = edThumbprintInput(key)\n\tcase *ecdsa.PublicKey:\n\t\tinput, err = ecThumbprintInput(key.Curve, key.X, key.Y)\n\tcase *ecdsa.PrivateKey:\n\t\tinput, err = ecThumbprintInput(key.Curve, key.X, key.Y)\n\tcase *rsa.PublicKey:\n\t\tinput, err = rsaThumbprintInput(key.N, key.E)\n\tcase *rsa.PrivateKey:\n\t\tinput, err = rsaThumbprintInput(key.N, key.E)\n\tcase ed25519.PrivateKey:\n\t\tinput, err = edThumbprintInput(ed25519.PublicKey(key[32:]))\n\tcase OpaqueSigner:\n\t\treturn key.Public().Thumbprint(hash)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: unknown key type '%s'\", reflect.TypeOf(key))\n\t}\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\th := hash.New()\n\t_, _ = h.Write([]byte(input))\n\treturn h.Sum(nil), nil\n}\n\n// IsPublic returns true if the JWK represents a public key (not symmetric, not private).\nfunc (k *JSONWebKey) IsPublic() bool {\n\tswitch k.Key.(type) {\n\tcase *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// Public creates JSONWebKey with corresponding public key if JWK represents asymmetric private key.\nfunc (k *JSONWebKey) Public() JSONWebKey {\n\tif k.IsPublic() {\n\t\treturn *k\n\t}\n\tret := *k\n\tswitch key := k.Key.(type) {\n\tcase *ecdsa.PrivateKey:\n\t\tret.Key = key.Public()\n\tcase *rsa.PrivateKey:\n\t\tret.Key = key.Public()\n\tcase ed25519.PrivateKey:\n\t\tret.Key = key.Public()\n\tdefault:\n\t\treturn JSONWebKey{} // returning invalid key\n\t}\n\treturn ret\n}\n\n// Valid checks that the key contains the expected parameters.\nfunc (k *JSONWebKey) Valid() bool {\n\tif k.Key == nil {\n\t\treturn false\n\t}\n\tswitch key := k.Key.(type) {\n\tcase *ecdsa.PublicKey:\n\t\tif key.Curve == nil || key.X == nil || key.Y == nil {\n\t\t\treturn false\n\t\t}\n\tcase *ecdsa.PrivateKey:\n\t\tif key.Curve == nil || key.X == nil || key.Y == nil || key.D == nil {\n\t\t\treturn false\n\t\t}\n\tcase *rsa.PublicKey:\n\t\tif key.N == nil || key.E == 0 {\n\t\t\treturn false\n\t\t}\n\tcase *rsa.PrivateKey:\n\t\tif key.N == nil || key.E == 0 || key.D == nil || len(key.Primes) < 2 {\n\t\t\treturn false\n\t\t}\n\tcase ed25519.PublicKey:\n\t\tif len(key) != 32 {\n\t\t\treturn false\n\t\t}\n\tcase ed25519.PrivateKey:\n\t\tif len(key) != 64 {\n\t\t\treturn false\n\t\t}\n\tdefault:\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (key rawJSONWebKey) rsaPublicKey() (*rsa.PublicKey, error) {\n\tif key.N == nil || key.E == nil {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid RSA key, missing n/e values\")\n\t}\n\n\treturn &rsa.PublicKey{\n\t\tN: key.N.bigInt(),\n\t\tE: key.E.toInt(),\n\t}, nil\n}\n\nfunc fromEdPublicKey(pub ed25519.PublicKey) *rawJSONWebKey {\n\treturn &rawJSONWebKey{\n\t\tKty: \"OKP\",\n\t\tCrv: \"Ed25519\",\n\t\tX:   newBuffer(pub),\n\t}\n}\n\nfunc fromRsaPublicKey(pub *rsa.PublicKey) *rawJSONWebKey {\n\treturn &rawJSONWebKey{\n\t\tKty: \"RSA\",\n\t\tN:   newBuffer(pub.N.Bytes()),\n\t\tE:   newBufferFromInt(uint64(pub.E)),\n\t}\n}\n\nfunc (key rawJSONWebKey) ecPublicKey() (*ecdsa.PublicKey, error) {\n\tvar curve elliptic.Curve\n\tswitch key.Crv {\n\tcase \"P-256\":\n\t\tcurve = elliptic.P256()\n\tcase \"P-384\":\n\t\tcurve = elliptic.P384()\n\tcase \"P-521\":\n\t\tcurve = elliptic.P521()\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: unsupported elliptic curve '%s'\", key.Crv)\n\t}\n\n\tif key.X == nil || key.Y == nil {\n\t\treturn nil, errors.New(\"go-jose/go-jose: invalid EC key, missing x/y values\")\n\t}\n\n\t// The length of this octet string MUST be the full size of a coordinate for\n\t// the curve specified in the \"crv\" parameter.\n\t// https://tools.ietf.org/html/rfc7518#section-6.2.1.2\n\tif curveSize(curve) != len(key.X.data) {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid EC public key, wrong length for x\")\n\t}\n\n\tif curveSize(curve) != len(key.Y.data) {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid EC public key, wrong length for y\")\n\t}\n\n\tx := key.X.bigInt()\n\ty := key.Y.bigInt()\n\n\tif !curve.IsOnCurve(x, y) {\n\t\treturn nil, errors.New(\"go-jose/go-jose: invalid EC key, X/Y are not on declared curve\")\n\t}\n\n\treturn &ecdsa.PublicKey{\n\t\tCurve: curve,\n\t\tX:     x,\n\t\tY:     y,\n\t}, nil\n}\n\nfunc fromEcPublicKey(pub *ecdsa.PublicKey) (*rawJSONWebKey, error) {\n\tif pub == nil || pub.X == nil || pub.Y == nil {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid EC key (nil, or X/Y missing)\")\n\t}\n\n\tname, err := curveName(pub.Curve)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsize := curveSize(pub.Curve)\n\n\txBytes := pub.X.Bytes()\n\tyBytes := pub.Y.Bytes()\n\n\tif len(xBytes) > size || len(yBytes) > size {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid EC key (X/Y too large)\")\n\t}\n\n\tkey := &rawJSONWebKey{\n\t\tKty: \"EC\",\n\t\tCrv: name,\n\t\tX:   newFixedSizeBuffer(xBytes, size),\n\t\tY:   newFixedSizeBuffer(yBytes, size),\n\t}\n\n\treturn key, nil\n}\n\nfunc (key rawJSONWebKey) edPrivateKey() (ed25519.PrivateKey, error) {\n\tvar missing []string\n\tif key.D == nil {\n\t\tmissing = append(missing, \"D\")\n\t}\n\tif key.X == nil {\n\t\tmissing = append(missing, \"X\")\n\t}\n\n\tif len(missing) > 0 {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid Ed25519 private key, missing %s value(s)\", strings.Join(missing, \", \"))\n\t}\n\n\tprivateKey := make([]byte, ed25519.PrivateKeySize)\n\tcopy(privateKey[0:32], key.D.bytes())\n\tcopy(privateKey[32:], key.X.bytes())\n\trv := ed25519.PrivateKey(privateKey)\n\treturn rv, nil\n}\n\nfunc (key rawJSONWebKey) edPublicKey() (ed25519.PublicKey, error) {\n\tif key.X == nil {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid Ed key, missing x value\")\n\t}\n\tpublicKey := make([]byte, ed25519.PublicKeySize)\n\tcopy(publicKey[0:32], key.X.bytes())\n\trv := ed25519.PublicKey(publicKey)\n\treturn rv, nil\n}\n\nfunc (key rawJSONWebKey) rsaPrivateKey() (*rsa.PrivateKey, error) {\n\tvar missing []string\n\tif key.N == nil {\n\t\tmissing = append(missing, \"N\")\n\t}\n\tif key.E == nil {\n\t\tmissing = append(missing, \"E\")\n\t}\n\tif key.D == nil {\n\t\tmissing = append(missing, \"D\")\n\t}\n\tif key.P == nil {\n\t\tmissing = append(missing, \"P\")\n\t}\n\tif key.Q == nil {\n\t\tmissing = append(missing, \"Q\")\n\t}\n\tif len(missing) > 0 {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid RSA private key, missing %s value(s)\", strings.Join(missing, \", \"))\n\t}\n\n\trv := &rsa.PrivateKey{\n\t\tPublicKey: rsa.PublicKey{\n\t\t\tN: key.N.bigInt(),\n\t\t\tE: key.E.toInt(),\n\t\t},\n\t\tD: key.D.bigInt(),\n\t\tPrimes: []*big.Int{\n\t\t\tkey.P.bigInt(),\n\t\t\tkey.Q.bigInt(),\n\t\t},\n\t}\n\n\tif key.Dp != nil {\n\t\trv.Precomputed.Dp = key.Dp.bigInt()\n\t}\n\tif key.Dq != nil {\n\t\trv.Precomputed.Dq = key.Dq.bigInt()\n\t}\n\tif key.Qi != nil {\n\t\trv.Precomputed.Qinv = key.Qi.bigInt()\n\t}\n\n\terr := rv.Validate()\n\treturn rv, err\n}\n\nfunc fromEdPrivateKey(ed ed25519.PrivateKey) (*rawJSONWebKey, error) {\n\traw := fromEdPublicKey(ed25519.PublicKey(ed[32:]))\n\n\traw.D = newBuffer(ed[0:32])\n\treturn raw, nil\n}\n\nfunc fromRsaPrivateKey(rsa *rsa.PrivateKey) (*rawJSONWebKey, error) {\n\tif len(rsa.Primes) != 2 {\n\t\treturn nil, ErrUnsupportedKeyType\n\t}\n\n\traw := fromRsaPublicKey(&rsa.PublicKey)\n\n\traw.D = newBuffer(rsa.D.Bytes())\n\traw.P = newBuffer(rsa.Primes[0].Bytes())\n\traw.Q = newBuffer(rsa.Primes[1].Bytes())\n\n\tif rsa.Precomputed.Dp != nil {\n\t\traw.Dp = newBuffer(rsa.Precomputed.Dp.Bytes())\n\t}\n\tif rsa.Precomputed.Dq != nil {\n\t\traw.Dq = newBuffer(rsa.Precomputed.Dq.Bytes())\n\t}\n\tif rsa.Precomputed.Qinv != nil {\n\t\traw.Qi = newBuffer(rsa.Precomputed.Qinv.Bytes())\n\t}\n\n\treturn raw, nil\n}\n\nfunc (key rawJSONWebKey) ecPrivateKey() (*ecdsa.PrivateKey, error) {\n\tvar curve elliptic.Curve\n\tswitch key.Crv {\n\tcase \"P-256\":\n\t\tcurve = elliptic.P256()\n\tcase \"P-384\":\n\t\tcurve = elliptic.P384()\n\tcase \"P-521\":\n\t\tcurve = elliptic.P521()\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: unsupported elliptic curve '%s'\", key.Crv)\n\t}\n\n\tvar missing []string\n\tif key.X == nil {\n\t\tmissing = append(missing, \"X\")\n\t}\n\tif key.Y == nil {\n\t\tmissing = append(missing, \"Y\")\n\t}\n\tif key.D == nil {\n\t\tmissing = append(missing, \"D\")\n\t}\n\n\tif len(missing) > 0 {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid EC private key, missing %s value(s)\", strings.Join(missing, \", \"))\n\t}\n\n\t// The length of this octet string MUST be the full size of a coordinate for\n\t// the curve specified in the \"crv\" parameter.\n\t// https://tools.ietf.org/html/rfc7518#section-6.2.1.2\n\tif curveSize(curve) != len(key.X.data) {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid EC private key, wrong length for x\")\n\t}\n\n\tif curveSize(curve) != len(key.Y.data) {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid EC private key, wrong length for y\")\n\t}\n\n\t// https://tools.ietf.org/html/rfc7518#section-6.2.2.1\n\tif dSize(curve) != len(key.D.data) {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid EC private key, wrong length for d\")\n\t}\n\n\tx := key.X.bigInt()\n\ty := key.Y.bigInt()\n\n\tif !curve.IsOnCurve(x, y) {\n\t\treturn nil, errors.New(\"go-jose/go-jose: invalid EC key, X/Y are not on declared curve\")\n\t}\n\n\treturn &ecdsa.PrivateKey{\n\t\tPublicKey: ecdsa.PublicKey{\n\t\t\tCurve: curve,\n\t\t\tX:     x,\n\t\t\tY:     y,\n\t\t},\n\t\tD: key.D.bigInt(),\n\t}, nil\n}\n\nfunc fromEcPrivateKey(ec *ecdsa.PrivateKey) (*rawJSONWebKey, error) {\n\traw, err := fromEcPublicKey(&ec.PublicKey)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif ec.D == nil {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid EC private key\")\n\t}\n\n\traw.D = newFixedSizeBuffer(ec.D.Bytes(), dSize(ec.PublicKey.Curve))\n\n\treturn raw, nil\n}\n\n// dSize returns the size in octets for the \"d\" member of an elliptic curve\n// private key.\n// The length of this octet string MUST be ceiling(log-base-2(n)/8)\n// octets (where n is the order of the curve).\n// https://tools.ietf.org/html/rfc7518#section-6.2.2.1\nfunc dSize(curve elliptic.Curve) int {\n\torder := curve.Params().P\n\tbitLen := order.BitLen()\n\tsize := bitLen / 8\n\tif bitLen%8 != 0 {\n\t\tsize++\n\t}\n\treturn size\n}\n\nfunc fromSymmetricKey(key []byte) (*rawJSONWebKey, error) {\n\treturn &rawJSONWebKey{\n\t\tKty: \"oct\",\n\t\tK:   newBuffer(key),\n\t}, nil\n}\n\nfunc (key rawJSONWebKey) symmetricKey() ([]byte, error) {\n\tif key.K == nil {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid OCT (symmetric) key, missing k value\")\n\t}\n\treturn key.K.bytes(), nil\n}\n\nvar (\n\t// ErrJWKSKidNotFound is returned when a JWKS does not contain a JWK with a\n\t// key ID which matches one in the provided tokens headers.\n\tErrJWKSKidNotFound = errors.New(\"go-jose/go-jose: JWK with matching kid not found in JWK Set\")\n)\n\nfunc tryJWKS(key interface{}, headers ...Header) (interface{}, error) {\n\tvar jwks JSONWebKeySet\n\n\tswitch jwksType := key.(type) {\n\tcase *JSONWebKeySet:\n\t\tjwks = *jwksType\n\tcase JSONWebKeySet:\n\t\tjwks = jwksType\n\tdefault:\n\t\t// If the specified key is not a JWKS, return as is.\n\t\treturn key, nil\n\t}\n\n\t// Determine the KID to search for from the headers.\n\tvar kid string\n\tfor _, header := range headers {\n\t\tif header.KeyID != \"\" {\n\t\t\tkid = header.KeyID\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// If no KID is specified in the headers, reject.\n\tif kid == \"\" {\n\t\treturn nil, ErrJWKSKidNotFound\n\t}\n\n\t// Find the JWK with the matching KID. If no JWK with the specified KID is\n\t// found, reject.\n\tkeys := jwks.Key(kid)\n\tif len(keys) == 0 {\n\t\treturn nil, ErrJWKSKidNotFound\n\t}\n\n\treturn keys[0].Key, nil\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/jws.go",
    "content": "/*-\n * Copyright 2014 Square Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage jose\n\nimport (\n\t\"bytes\"\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/go-jose/go-jose/v4/json\"\n)\n\n// rawJSONWebSignature represents a raw JWS JSON object. Used for parsing/serializing.\ntype rawJSONWebSignature struct {\n\tPayload    *byteBuffer        `json:\"payload,omitempty\"`\n\tSignatures []rawSignatureInfo `json:\"signatures,omitempty\"`\n\tProtected  *byteBuffer        `json:\"protected,omitempty\"`\n\tHeader     *rawHeader         `json:\"header,omitempty\"`\n\tSignature  *byteBuffer        `json:\"signature,omitempty\"`\n}\n\n// rawSignatureInfo represents a single JWS signature over the JWS payload and protected header.\ntype rawSignatureInfo struct {\n\tProtected *byteBuffer `json:\"protected,omitempty\"`\n\tHeader    *rawHeader  `json:\"header,omitempty\"`\n\tSignature *byteBuffer `json:\"signature,omitempty\"`\n}\n\n// JSONWebSignature represents a signed JWS object after parsing.\ntype JSONWebSignature struct {\n\tpayload []byte\n\t// Signatures attached to this object (may be more than one for multi-sig).\n\t// Be careful about accessing these directly, prefer to use Verify() or\n\t// VerifyMulti() to ensure that the data you're getting is verified.\n\tSignatures []Signature\n}\n\n// Signature represents a single signature over the JWS payload and protected header.\ntype Signature struct {\n\t// Merged header fields. Contains both protected and unprotected header\n\t// values. Prefer using Protected and Unprotected fields instead of this.\n\t// Values in this header may or may not have been signed and in general\n\t// should not be trusted.\n\tHeader Header\n\n\t// Protected header. Values in this header were signed and\n\t// will be verified as part of the signature verification process.\n\tProtected Header\n\n\t// Unprotected header. Values in this header were not signed\n\t// and in general should not be trusted.\n\tUnprotected Header\n\n\t// The actual signature value\n\tSignature []byte\n\n\tprotected *rawHeader\n\theader    *rawHeader\n\toriginal  *rawSignatureInfo\n}\n\n// ParseSigned parses a signed message in JWS Compact or JWS JSON Serialization. Validation fails if\n// the JWS is signed with an algorithm that isn't in the provided list of signature algorithms.\n// Applications should decide for themselves which signature algorithms are acceptable. If you're\n// not sure which signature algorithms your application might receive, consult the documentation of\n// the program which provides them or the protocol that you are implementing. You can also try\n// getting an example JWS and decoding it with a tool like https://jwt.io to see what its \"alg\"\n// header parameter indicates. The signature on the JWS does not get validated during parsing. Call\n// Verify() after parsing to validate the signature and obtain the payload.\n//\n// https://datatracker.ietf.org/doc/html/rfc7515#section-7\nfunc ParseSigned(\n\tsignature string,\n\tsignatureAlgorithms []SignatureAlgorithm,\n) (*JSONWebSignature, error) {\n\tsignature = stripWhitespace(signature)\n\tif strings.HasPrefix(signature, \"{\") {\n\t\treturn ParseSignedJSON(signature, signatureAlgorithms)\n\t}\n\n\treturn parseSignedCompact(signature, nil, signatureAlgorithms)\n}\n\n// ParseSignedCompact parses a message in JWS Compact Serialization. Validation fails if the JWS is\n// signed with an algorithm that isn't in the provided list of signature algorithms. Applications\n// should decide for themselves which signature algorithms are acceptable.If you're not sure which\n// signature algorithms your application might receive, consult the documentation of the program\n// which provides them or the protocol that you are implementing. You can also try getting an\n// example JWS and decoding it with a tool like https://jwt.io to see what its \"alg\" header\n// parameter indicates. The signature on the JWS does not get validated during parsing. Call\n// Verify() after parsing to validate the signature and obtain the payload.\n//\n// https://datatracker.ietf.org/doc/html/rfc7515#section-7.1\nfunc ParseSignedCompact(\n\tsignature string,\n\tsignatureAlgorithms []SignatureAlgorithm,\n) (*JSONWebSignature, error) {\n\treturn parseSignedCompact(signature, nil, signatureAlgorithms)\n}\n\n// ParseDetached parses a signed message in compact serialization format with detached payload.\n// Validation fails if the JWS is signed with an algorithm that isn't in the provided list of\n// signature algorithms. Applications should decide for themselves which signature algorithms are\n// acceptable. If you're not sure which signature algorithms your application might receive, consult\n// the documentation of the program which provides them or the protocol that you are implementing.\n// You can also try getting an example JWS and decoding it with a tool like https://jwt.io to see\n// what its \"alg\" header parameter indicates. The signature on the JWS does not get validated during\n// parsing. Call Verify() after parsing to validate the signature and obtain the payload.\n//\n// https://datatracker.ietf.org/doc/html/rfc7515#appendix-F\nfunc ParseDetached(\n\tsignature string,\n\tpayload []byte,\n\tsignatureAlgorithms []SignatureAlgorithm,\n) (*JSONWebSignature, error) {\n\tif payload == nil {\n\t\treturn nil, errors.New(\"go-jose/go-jose: nil payload\")\n\t}\n\treturn parseSignedCompact(stripWhitespace(signature), payload, signatureAlgorithms)\n}\n\n// Get a header value\nfunc (sig Signature) mergedHeaders() rawHeader {\n\tout := rawHeader{}\n\tout.merge(sig.protected)\n\tout.merge(sig.header)\n\treturn out\n}\n\n// Compute data to be signed\nfunc (obj JSONWebSignature) computeAuthData(payload []byte, signature *Signature) ([]byte, error) {\n\tvar authData bytes.Buffer\n\n\tprotectedHeader := new(rawHeader)\n\n\tif signature.original != nil && signature.original.Protected != nil {\n\t\tif err := json.Unmarshal(signature.original.Protected.bytes(), protectedHeader); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tauthData.WriteString(signature.original.Protected.base64())\n\t} else if signature.protected != nil {\n\t\tprotectedHeader = signature.protected\n\t\tauthData.WriteString(base64.RawURLEncoding.EncodeToString(mustSerializeJSON(protectedHeader)))\n\t}\n\n\tneedsBase64 := true\n\n\tif protectedHeader != nil {\n\t\tvar err error\n\t\tif needsBase64, err = protectedHeader.getB64(); err != nil {\n\t\t\tneedsBase64 = true\n\t\t}\n\t}\n\n\tauthData.WriteByte('.')\n\n\tif needsBase64 {\n\t\tauthData.WriteString(base64.RawURLEncoding.EncodeToString(payload))\n\t} else {\n\t\tauthData.Write(payload)\n\t}\n\n\treturn authData.Bytes(), nil\n}\n\n// ParseSignedJSON parses a message in JWS JSON Serialization.\n//\n// https://datatracker.ietf.org/doc/html/rfc7515#section-7.2\nfunc ParseSignedJSON(\n\tinput string,\n\tsignatureAlgorithms []SignatureAlgorithm,\n) (*JSONWebSignature, error) {\n\tvar parsed rawJSONWebSignature\n\terr := json.Unmarshal([]byte(input), &parsed)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn parsed.sanitized(signatureAlgorithms)\n}\n\nfunc containsSignatureAlgorithm(haystack []SignatureAlgorithm, needle SignatureAlgorithm) bool {\n\tfor _, algorithm := range haystack {\n\t\tif algorithm == needle {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// ErrUnexpectedSignatureAlgorithm is returned when the signature algorithm in\n// the JWS header does not match one of the expected algorithms.\ntype ErrUnexpectedSignatureAlgorithm struct {\n\t// Got is the signature algorithm found in the JWS header.\n\tGot      SignatureAlgorithm\n\texpected []SignatureAlgorithm\n}\n\nfunc (e *ErrUnexpectedSignatureAlgorithm) Error() string {\n\treturn fmt.Sprintf(\"unexpected signature algorithm %q; expected %q\", e.Got, e.expected)\n}\n\nfunc newErrUnexpectedSignatureAlgorithm(got SignatureAlgorithm, expected []SignatureAlgorithm) error {\n\treturn &ErrUnexpectedSignatureAlgorithm{\n\t\tGot:      got,\n\t\texpected: expected,\n\t}\n}\n\n// sanitized produces a cleaned-up JWS object from the raw JSON.\nfunc (parsed *rawJSONWebSignature) sanitized(signatureAlgorithms []SignatureAlgorithm) (*JSONWebSignature, error) {\n\tif len(signatureAlgorithms) == 0 {\n\t\treturn nil, errors.New(\"go-jose/go-jose: no signature algorithms specified\")\n\t}\n\tif parsed.Payload == nil {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: missing payload in JWS message\")\n\t}\n\n\tobj := &JSONWebSignature{\n\t\tpayload:    parsed.Payload.bytes(),\n\t\tSignatures: make([]Signature, len(parsed.Signatures)),\n\t}\n\n\tif len(parsed.Signatures) == 0 {\n\t\t// No signatures array, must be flattened serialization\n\t\tsignature := Signature{}\n\t\tif parsed.Protected != nil && len(parsed.Protected.bytes()) > 0 {\n\t\t\tsignature.protected = &rawHeader{}\n\t\t\terr := json.Unmarshal(parsed.Protected.bytes(), signature.protected)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\n\t\t// Check that there is not a nonce in the unprotected header\n\t\tif parsed.Header != nil && parsed.Header.getNonce() != \"\" {\n\t\t\treturn nil, ErrUnprotectedNonce\n\t\t}\n\n\t\tsignature.header = parsed.Header\n\t\tsignature.Signature = parsed.Signature.bytes()\n\t\t// Make a fake \"original\" rawSignatureInfo to store the unprocessed\n\t\t// Protected header. This is necessary because the Protected header can\n\t\t// contain arbitrary fields not registered as part of the spec. See\n\t\t// https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41#section-4\n\t\t// If we unmarshal Protected into a rawHeader with its explicit list of fields,\n\t\t// we cannot marshal losslessly. So we have to keep around the original bytes.\n\t\t// This is used in computeAuthData, which will first attempt to use\n\t\t// the original bytes of a protected header, and fall back on marshaling the\n\t\t// header struct only if those bytes are not available.\n\t\tsignature.original = &rawSignatureInfo{\n\t\t\tProtected: parsed.Protected,\n\t\t\tHeader:    parsed.Header,\n\t\t\tSignature: parsed.Signature,\n\t\t}\n\n\t\tvar err error\n\t\tsignature.Header, err = signature.mergedHeaders().sanitized()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\talg := SignatureAlgorithm(signature.Header.Algorithm)\n\t\tif !containsSignatureAlgorithm(signatureAlgorithms, alg) {\n\t\t\treturn nil, newErrUnexpectedSignatureAlgorithm(alg, signatureAlgorithms)\n\t\t}\n\n\t\tif signature.header != nil {\n\t\t\tsignature.Unprotected, err = signature.header.sanitized()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\n\t\tif signature.protected != nil {\n\t\t\tsignature.Protected, err = signature.protected.sanitized()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\n\t\t// As per RFC 7515 Section 4.1.3, only public keys are allowed to be embedded.\n\t\tjwk := signature.Header.JSONWebKey\n\t\tif jwk != nil && (!jwk.Valid() || !jwk.IsPublic()) {\n\t\t\treturn nil, errors.New(\"go-jose/go-jose: invalid embedded jwk, must be public key\")\n\t\t}\n\n\t\tobj.Signatures = append(obj.Signatures, signature)\n\t}\n\n\tfor i, sig := range parsed.Signatures {\n\t\tif sig.Protected != nil && len(sig.Protected.bytes()) > 0 {\n\t\t\tobj.Signatures[i].protected = &rawHeader{}\n\t\t\terr := json.Unmarshal(sig.Protected.bytes(), obj.Signatures[i].protected)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\n\t\t// Check that there is not a nonce in the unprotected header\n\t\tif sig.Header != nil && sig.Header.getNonce() != \"\" {\n\t\t\treturn nil, ErrUnprotectedNonce\n\t\t}\n\n\t\tvar err error\n\t\tobj.Signatures[i].Header, err = obj.Signatures[i].mergedHeaders().sanitized()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\talg := SignatureAlgorithm(obj.Signatures[i].Header.Algorithm)\n\t\tif !containsSignatureAlgorithm(signatureAlgorithms, alg) {\n\t\t\treturn nil, newErrUnexpectedSignatureAlgorithm(alg, signatureAlgorithms)\n\t\t}\n\n\t\tif obj.Signatures[i].header != nil {\n\t\t\tobj.Signatures[i].Unprotected, err = obj.Signatures[i].header.sanitized()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\n\t\tif obj.Signatures[i].protected != nil {\n\t\t\tobj.Signatures[i].Protected, err = obj.Signatures[i].protected.sanitized()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\n\t\tobj.Signatures[i].Signature = sig.Signature.bytes()\n\n\t\t// As per RFC 7515 Section 4.1.3, only public keys are allowed to be embedded.\n\t\tjwk := obj.Signatures[i].Header.JSONWebKey\n\t\tif jwk != nil && (!jwk.Valid() || !jwk.IsPublic()) {\n\t\t\treturn nil, errors.New(\"go-jose/go-jose: invalid embedded jwk, must be public key\")\n\t\t}\n\n\t\t// Copy value of sig\n\t\toriginal := sig\n\n\t\tobj.Signatures[i].header = sig.Header\n\t\tobj.Signatures[i].original = &original\n\t}\n\n\treturn obj, nil\n}\n\nconst tokenDelim = \".\"\n\n// parseSignedCompact parses a message in compact format.\nfunc parseSignedCompact(\n\tinput string,\n\tpayload []byte,\n\tsignatureAlgorithms []SignatureAlgorithm,\n) (*JSONWebSignature, error) {\n\tprotected, s, ok := strings.Cut(input, tokenDelim)\n\tif !ok { // no period found\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: compact JWS format must have three parts\")\n\t}\n\tclaims, sig, ok := strings.Cut(s, tokenDelim)\n\tif !ok { // only one period found\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: compact JWS format must have three parts\")\n\t}\n\tif strings.ContainsRune(sig, '.') { // too many periods found\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: compact JWS format must have three parts\")\n\t}\n\n\tif claims != \"\" && payload != nil {\n\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: payload is not detached\")\n\t}\n\n\trawProtected, err := base64.RawURLEncoding.DecodeString(protected)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif payload == nil {\n\t\tpayload, err = base64.RawURLEncoding.DecodeString(claims)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tsignature, err := base64.RawURLEncoding.DecodeString(sig)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\traw := &rawJSONWebSignature{\n\t\tPayload:   newBuffer(payload),\n\t\tProtected: newBuffer(rawProtected),\n\t\tSignature: newBuffer(signature),\n\t}\n\treturn raw.sanitized(signatureAlgorithms)\n}\n\nfunc (obj JSONWebSignature) compactSerialize(detached bool) (string, error) {\n\tif len(obj.Signatures) != 1 || obj.Signatures[0].header != nil || obj.Signatures[0].protected == nil {\n\t\treturn \"\", ErrNotSupported\n\t}\n\n\tserializedProtected := mustSerializeJSON(obj.Signatures[0].protected)\n\n\tvar payload []byte\n\tif !detached {\n\t\tpayload = obj.payload\n\t}\n\n\treturn base64JoinWithDots(\n\t\tserializedProtected,\n\t\tpayload,\n\t\tobj.Signatures[0].Signature,\n\t), nil\n}\n\n// CompactSerialize serializes an object using the compact serialization format.\nfunc (obj JSONWebSignature) CompactSerialize() (string, error) {\n\treturn obj.compactSerialize(false)\n}\n\n// DetachedCompactSerialize serializes an object using the compact serialization format with detached payload.\nfunc (obj JSONWebSignature) DetachedCompactSerialize() (string, error) {\n\treturn obj.compactSerialize(true)\n}\n\n// FullSerialize serializes an object using the full JSON serialization format.\nfunc (obj JSONWebSignature) FullSerialize() string {\n\traw := rawJSONWebSignature{\n\t\tPayload: newBuffer(obj.payload),\n\t}\n\n\tif len(obj.Signatures) == 1 {\n\t\tif obj.Signatures[0].protected != nil {\n\t\t\tserializedProtected := mustSerializeJSON(obj.Signatures[0].protected)\n\t\t\traw.Protected = newBuffer(serializedProtected)\n\t\t}\n\t\traw.Header = obj.Signatures[0].header\n\t\traw.Signature = newBuffer(obj.Signatures[0].Signature)\n\t} else {\n\t\traw.Signatures = make([]rawSignatureInfo, len(obj.Signatures))\n\t\tfor i, signature := range obj.Signatures {\n\t\t\traw.Signatures[i] = rawSignatureInfo{\n\t\t\t\tHeader:    signature.header,\n\t\t\t\tSignature: newBuffer(signature.Signature),\n\t\t\t}\n\n\t\t\tif signature.protected != nil {\n\t\t\t\traw.Signatures[i].Protected = newBuffer(mustSerializeJSON(signature.protected))\n\t\t\t}\n\t\t}\n\t}\n\n\treturn string(mustSerializeJSON(raw))\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/jwt/builder.go",
    "content": "/*-\n * Copyright 2016 Zbigniew Mandziejewicz\n * Copyright 2016 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage jwt\n\nimport (\n\t\"bytes\"\n\t\"reflect\"\n\n\t\"github.com/go-jose/go-jose/v4/json\"\n\n\t\"github.com/go-jose/go-jose/v4\"\n)\n\n// Builder is a utility for making JSON Web Tokens. Calls can be chained, and\n// errors are accumulated until the final call to Serialize.\ntype Builder interface {\n\t// Claims encodes claims into JWE/JWS form. Multiple calls will merge claims\n\t// into single JSON object. If you are passing private claims, make sure to set\n\t// struct field tags to specify the name for the JSON key to be used when\n\t// serializing.\n\tClaims(i interface{}) Builder\n\t// Token builds a JSONWebToken from provided data.\n\tToken() (*JSONWebToken, error)\n\t// Serialize serializes a token.\n\tSerialize() (string, error)\n}\n\n// NestedBuilder is a utility for making Signed-Then-Encrypted JSON Web Tokens.\n// Calls can be chained, and errors are accumulated until final call to\n// Serialize.\ntype NestedBuilder interface {\n\t// Claims encodes claims into JWE/JWS form. Multiple calls will merge claims\n\t// into single JSON object. If you are passing private claims, make sure to set\n\t// struct field tags to specify the name for the JSON key to be used when\n\t// serializing.\n\tClaims(i interface{}) NestedBuilder\n\t// Token builds a NestedJSONWebToken from provided data.\n\tToken() (*NestedJSONWebToken, error)\n\t// Serialize serializes a token.\n\tSerialize() (string, error)\n}\n\ntype builder struct {\n\tpayload map[string]interface{}\n\terr     error\n}\n\ntype signedBuilder struct {\n\tbuilder\n\tsig jose.Signer\n}\n\ntype encryptedBuilder struct {\n\tbuilder\n\tenc jose.Encrypter\n}\n\ntype nestedBuilder struct {\n\tbuilder\n\tsig jose.Signer\n\tenc jose.Encrypter\n}\n\n// Signed creates builder for signed tokens.\nfunc Signed(sig jose.Signer) Builder {\n\treturn &signedBuilder{\n\t\tsig: sig,\n\t}\n}\n\n// Encrypted creates builder for encrypted tokens.\nfunc Encrypted(enc jose.Encrypter) Builder {\n\treturn &encryptedBuilder{\n\t\tenc: enc,\n\t}\n}\n\n// SignedAndEncrypted creates builder for signed-then-encrypted tokens.\n// ErrInvalidContentType will be returned if encrypter doesn't have JWT content type.\nfunc SignedAndEncrypted(sig jose.Signer, enc jose.Encrypter) NestedBuilder {\n\tif contentType, _ := enc.Options().ExtraHeaders[jose.HeaderContentType].(jose.ContentType); contentType != \"JWT\" {\n\t\treturn &nestedBuilder{\n\t\t\tbuilder: builder{\n\t\t\t\terr: ErrInvalidContentType,\n\t\t\t},\n\t\t}\n\t}\n\treturn &nestedBuilder{\n\t\tsig: sig,\n\t\tenc: enc,\n\t}\n}\n\nfunc (b builder) claims(i interface{}) builder {\n\tif b.err != nil {\n\t\treturn b\n\t}\n\n\tm, ok := i.(map[string]interface{})\n\tswitch {\n\tcase ok:\n\t\treturn b.merge(m)\n\tcase reflect.Indirect(reflect.ValueOf(i)).Kind() == reflect.Struct:\n\t\tm, err := normalize(i)\n\t\tif err != nil {\n\t\t\treturn builder{\n\t\t\t\terr: err,\n\t\t\t}\n\t\t}\n\t\treturn b.merge(m)\n\tdefault:\n\t\treturn builder{\n\t\t\terr: ErrInvalidClaims,\n\t\t}\n\t}\n}\n\nfunc normalize(i interface{}) (map[string]interface{}, error) {\n\tm := make(map[string]interface{})\n\n\traw, err := json.Marshal(i)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\td := json.NewDecoder(bytes.NewReader(raw))\n\td.SetNumberType(json.UnmarshalJSONNumber)\n\n\tif err := d.Decode(&m); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn m, nil\n}\n\nfunc (b *builder) merge(m map[string]interface{}) builder {\n\tp := make(map[string]interface{})\n\tfor k, v := range b.payload {\n\t\tp[k] = v\n\t}\n\tfor k, v := range m {\n\t\tp[k] = v\n\t}\n\n\treturn builder{\n\t\tpayload: p,\n\t}\n}\n\nfunc (b *builder) token(p func(interface{}) ([]byte, error), h []jose.Header) (*JSONWebToken, error) {\n\treturn &JSONWebToken{\n\t\tpayload: p,\n\t\tHeaders: h,\n\t}, nil\n}\n\nfunc (b *signedBuilder) Claims(i interface{}) Builder {\n\treturn &signedBuilder{\n\t\tbuilder: b.builder.claims(i),\n\t\tsig:     b.sig,\n\t}\n}\n\nfunc (b *signedBuilder) Token() (*JSONWebToken, error) {\n\tsig, err := b.sign()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\th := make([]jose.Header, len(sig.Signatures))\n\tfor i, v := range sig.Signatures {\n\t\th[i] = v.Header\n\t}\n\n\treturn b.builder.token(sig.Verify, h)\n}\n\nfunc (b *signedBuilder) Serialize() (string, error) {\n\tsig, err := b.sign()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn sig.CompactSerialize()\n}\n\nfunc (b *signedBuilder) sign() (*jose.JSONWebSignature, error) {\n\tif b.err != nil {\n\t\treturn nil, b.err\n\t}\n\n\tp, err := json.Marshal(b.payload)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn b.sig.Sign(p)\n}\n\nfunc (b *encryptedBuilder) Claims(i interface{}) Builder {\n\treturn &encryptedBuilder{\n\t\tbuilder: b.builder.claims(i),\n\t\tenc:     b.enc,\n\t}\n}\n\nfunc (b *encryptedBuilder) Serialize() (string, error) {\n\tenc, err := b.encrypt()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn enc.CompactSerialize()\n}\n\nfunc (b *encryptedBuilder) Token() (*JSONWebToken, error) {\n\tenc, err := b.encrypt()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn b.builder.token(enc.Decrypt, []jose.Header{enc.Header})\n}\n\nfunc (b *encryptedBuilder) encrypt() (*jose.JSONWebEncryption, error) {\n\tif b.err != nil {\n\t\treturn nil, b.err\n\t}\n\n\tp, err := json.Marshal(b.payload)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn b.enc.Encrypt(p)\n}\n\nfunc (b *nestedBuilder) Claims(i interface{}) NestedBuilder {\n\treturn &nestedBuilder{\n\t\tbuilder: b.builder.claims(i),\n\t\tsig:     b.sig,\n\t\tenc:     b.enc,\n\t}\n}\n\n// Token produced a token suitable for serialization. It cannot be decrypted\n// without serializing and then deserializing.\nfunc (b *nestedBuilder) Token() (*NestedJSONWebToken, error) {\n\tenc, err := b.signAndEncrypt()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &NestedJSONWebToken{\n\t\tallowedSignatureAlgorithms: nil,\n\t\tenc:                        enc,\n\t\tHeaders:                    []jose.Header{enc.Header},\n\t}, nil\n}\n\nfunc (b *nestedBuilder) Serialize() (string, error) {\n\tenc, err := b.signAndEncrypt()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn enc.CompactSerialize()\n}\n\nfunc (b *nestedBuilder) FullSerialize() (string, error) {\n\tenc, err := b.signAndEncrypt()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn enc.FullSerialize(), nil\n}\n\nfunc (b *nestedBuilder) signAndEncrypt() (*jose.JSONWebEncryption, error) {\n\tif b.err != nil {\n\t\treturn nil, b.err\n\t}\n\n\tp, err := json.Marshal(b.payload)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsig, err := b.sig.Sign(p)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tp2, err := sig.CompactSerialize()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn b.enc.Encrypt([]byte(p2))\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/jwt/claims.go",
    "content": "/*-\n * Copyright 2016 Zbigniew Mandziejewicz\n * Copyright 2016 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage jwt\n\nimport (\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/go-jose/go-jose/v4/json\"\n)\n\n// Claims represents public claim values (as specified in RFC 7519).\ntype Claims struct {\n\tIssuer    string       `json:\"iss,omitempty\"`\n\tSubject   string       `json:\"sub,omitempty\"`\n\tAudience  Audience     `json:\"aud,omitempty\"`\n\tExpiry    *NumericDate `json:\"exp,omitempty\"`\n\tNotBefore *NumericDate `json:\"nbf,omitempty\"`\n\tIssuedAt  *NumericDate `json:\"iat,omitempty\"`\n\tID        string       `json:\"jti,omitempty\"`\n}\n\n// NumericDate represents date and time as the number of seconds since the\n// epoch, ignoring leap seconds. Non-integer values can be represented\n// in the serialized format, but we round to the nearest second.\n// See RFC7519 Section 2: https://tools.ietf.org/html/rfc7519#section-2\ntype NumericDate int64\n\n// NewNumericDate constructs NumericDate from time.Time value.\nfunc NewNumericDate(t time.Time) *NumericDate {\n\tif t.IsZero() {\n\t\treturn nil\n\t}\n\n\t// While RFC 7519 technically states that NumericDate values may be\n\t// non-integer values, we don't bother serializing timestamps in\n\t// claims with sub-second accurancy and just round to the nearest\n\t// second instead. Not convined sub-second accuracy is useful here.\n\tout := NumericDate(t.Unix())\n\treturn &out\n}\n\n// MarshalJSON serializes the given NumericDate into its JSON representation.\nfunc (n NumericDate) MarshalJSON() ([]byte, error) {\n\treturn []byte(strconv.FormatInt(int64(n), 10)), nil\n}\n\n// UnmarshalJSON reads a date from its JSON representation.\nfunc (n *NumericDate) UnmarshalJSON(b []byte) error {\n\ts := string(b)\n\n\tf, err := strconv.ParseFloat(s, 64)\n\tif err != nil {\n\t\treturn ErrUnmarshalNumericDate\n\t}\n\n\t*n = NumericDate(f)\n\treturn nil\n}\n\n// Time returns time.Time representation of NumericDate.\nfunc (n *NumericDate) Time() time.Time {\n\tif n == nil {\n\t\treturn time.Time{}\n\t}\n\treturn time.Unix(int64(*n), 0)\n}\n\n// Audience represents the recipients that the token is intended for.\ntype Audience []string\n\n// UnmarshalJSON reads an audience from its JSON representation.\nfunc (s *Audience) UnmarshalJSON(b []byte) error {\n\tvar v interface{}\n\tif err := json.Unmarshal(b, &v); err != nil {\n\t\treturn err\n\t}\n\n\tswitch v := v.(type) {\n\tcase string:\n\t\t*s = []string{v}\n\tcase []interface{}:\n\t\ta := make([]string, len(v))\n\t\tfor i, e := range v {\n\t\t\ts, ok := e.(string)\n\t\t\tif !ok {\n\t\t\t\treturn ErrUnmarshalAudience\n\t\t\t}\n\t\t\ta[i] = s\n\t\t}\n\t\t*s = a\n\tdefault:\n\t\treturn ErrUnmarshalAudience\n\t}\n\n\treturn nil\n}\n\n// MarshalJSON converts audience to json representation.\nfunc (s Audience) MarshalJSON() ([]byte, error) {\n\tif len(s) == 1 {\n\t\treturn json.Marshal(s[0])\n\t}\n\treturn json.Marshal([]string(s))\n}\n\n// Contains checks whether a given string is included in the Audience\nfunc (s Audience) Contains(v string) bool {\n\tfor _, a := range s {\n\t\tif a == v {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/jwt/doc.go",
    "content": "/*-\n * Copyright 2017 Square Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\nPackage jwt provides an implementation of the JSON Web Token standard.\n*/\npackage jwt\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/jwt/errors.go",
    "content": "/*-\n * Copyright 2016 Zbigniew Mandziejewicz\n * Copyright 2016 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage jwt\n\nimport \"errors\"\n\n// ErrUnmarshalAudience indicates that aud claim could not be unmarshalled.\nvar ErrUnmarshalAudience = errors.New(\"go-jose/go-jose/jwt: expected string or array value to unmarshal to Audience\")\n\n// ErrUnmarshalNumericDate indicates that JWT NumericDate could not be unmarshalled.\nvar ErrUnmarshalNumericDate = errors.New(\"go-jose/go-jose/jwt: expected number value to unmarshal NumericDate\")\n\n// ErrInvalidClaims indicates that given claims have invalid type.\nvar ErrInvalidClaims = errors.New(\"go-jose/go-jose/jwt: expected claims to be value convertible into JSON object\")\n\n// ErrInvalidIssuer indicates invalid iss claim.\nvar ErrInvalidIssuer = errors.New(\"go-jose/go-jose/jwt: validation failed, invalid issuer claim (iss)\")\n\n// ErrInvalidSubject indicates invalid sub claim.\nvar ErrInvalidSubject = errors.New(\"go-jose/go-jose/jwt: validation failed, invalid subject claim (sub)\")\n\n// ErrInvalidAudience indicated invalid aud claim.\nvar ErrInvalidAudience = errors.New(\"go-jose/go-jose/jwt: validation failed, invalid audience claim (aud)\")\n\n// ErrInvalidID indicates invalid jti claim.\nvar ErrInvalidID = errors.New(\"go-jose/go-jose/jwt: validation failed, invalid ID claim (jti)\")\n\n// ErrNotValidYet indicates that token is used before time indicated in nbf claim.\nvar ErrNotValidYet = errors.New(\"go-jose/go-jose/jwt: validation failed, token not valid yet (nbf)\")\n\n// ErrExpired indicates that token is used after expiry time indicated in exp claim.\nvar ErrExpired = errors.New(\"go-jose/go-jose/jwt: validation failed, token is expired (exp)\")\n\n// ErrIssuedInTheFuture indicates that the iat field is in the future.\nvar ErrIssuedInTheFuture = errors.New(\"go-jose/go-jose/jwt: validation field, token issued in the future (iat)\")\n\n// ErrInvalidContentType indicates that token requires JWT cty header.\nvar ErrInvalidContentType = errors.New(\"go-jose/go-jose/jwt: expected content type to be JWT (cty header)\")\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/jwt/jwt.go",
    "content": "/*-\n * Copyright 2016 Zbigniew Mandziejewicz\n * Copyright 2016 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage jwt\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\tjose \"github.com/go-jose/go-jose/v4\"\n\t\"github.com/go-jose/go-jose/v4/json\"\n)\n\n// JSONWebToken represents a JSON Web Token (as specified in RFC7519).\ntype JSONWebToken struct {\n\tpayload           func(k interface{}) ([]byte, error)\n\tunverifiedPayload func() []byte\n\tHeaders           []jose.Header\n}\n\ntype NestedJSONWebToken struct {\n\tenc     *jose.JSONWebEncryption\n\tHeaders []jose.Header\n\t// Used when parsing and decrypting an input\n\tallowedSignatureAlgorithms []jose.SignatureAlgorithm\n}\n\n// Claims deserializes a JSONWebToken into dest using the provided key.\nfunc (t *JSONWebToken) Claims(key interface{}, dest ...interface{}) error {\n\tb, err := t.payload(key)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor _, d := range dest {\n\t\tif err := json.Unmarshal(b, d); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// UnsafeClaimsWithoutVerification deserializes the claims of a\n// JSONWebToken into the dests. For signed JWTs, the claims are not\n// verified. This function won't work for encrypted JWTs.\nfunc (t *JSONWebToken) UnsafeClaimsWithoutVerification(dest ...interface{}) error {\n\tif t.unverifiedPayload == nil {\n\t\treturn fmt.Errorf(\"go-jose/go-jose: Cannot get unverified claims\")\n\t}\n\tclaims := t.unverifiedPayload()\n\tfor _, d := range dest {\n\t\tif err := json.Unmarshal(claims, d); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (t *NestedJSONWebToken) Decrypt(decryptionKey interface{}) (*JSONWebToken, error) {\n\tb, err := t.enc.Decrypt(decryptionKey)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsig, err := ParseSigned(string(b), t.allowedSignatureAlgorithms)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn sig, nil\n}\n\n// ParseSigned parses token from JWS form.\nfunc ParseSigned(s string, signatureAlgorithms []jose.SignatureAlgorithm) (*JSONWebToken, error) {\n\tsig, err := jose.ParseSignedCompact(s, signatureAlgorithms)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\theaders := make([]jose.Header, len(sig.Signatures))\n\tfor i, signature := range sig.Signatures {\n\t\theaders[i] = signature.Header\n\t}\n\n\treturn &JSONWebToken{\n\t\tpayload:           sig.Verify,\n\t\tunverifiedPayload: sig.UnsafePayloadWithoutVerification,\n\t\tHeaders:           headers,\n\t}, nil\n}\n\nfunc validateKeyEncryptionAlgorithm(algs []jose.KeyAlgorithm) error {\n\tfor _, alg := range algs {\n\t\tswitch alg {\n\t\tcase jose.ED25519,\n\t\t\tjose.RSA1_5,\n\t\t\tjose.RSA_OAEP,\n\t\t\tjose.RSA_OAEP_256,\n\t\t\tjose.ECDH_ES,\n\t\t\tjose.ECDH_ES_A128KW,\n\t\t\tjose.ECDH_ES_A192KW,\n\t\t\tjose.ECDH_ES_A256KW:\n\t\t\treturn fmt.Errorf(\"asymmetric encryption algorithms not supported for JWT: \"+\n\t\t\t\t\"invalid key encryption algorithm: %s\", alg)\n\t\tcase jose.PBES2_HS256_A128KW,\n\t\t\tjose.PBES2_HS384_A192KW,\n\t\t\tjose.PBES2_HS512_A256KW:\n\t\t\treturn fmt.Errorf(\"password-based encryption not supported for JWT: \"+\n\t\t\t\t\"invalid key encryption algorithm: %s\", alg)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc parseEncryptedCompact(\n\ts string,\n\tkeyAlgorithms []jose.KeyAlgorithm,\n\tcontentEncryption []jose.ContentEncryption,\n) (*jose.JSONWebEncryption, error) {\n\terr := validateKeyEncryptionAlgorithm(keyAlgorithms)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tenc, err := jose.ParseEncryptedCompact(s, keyAlgorithms, contentEncryption)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn enc, nil\n}\n\n// ParseEncrypted parses token from JWE form.\n//\n// The keyAlgorithms and contentEncryption parameters are used to validate the \"alg\" and \"enc\"\n// header parameters respectively. They must be nonempty, and each \"alg\" or \"enc\" header in\n// parsed data must contain a value that is present in the corresponding parameter. That\n// includes the protected and unprotected headers as well as all recipients. To accept\n// multiple algorithms, pass a slice of all the algorithms you want to accept.\nfunc ParseEncrypted(s string,\n\tkeyAlgorithms []jose.KeyAlgorithm,\n\tcontentEncryption []jose.ContentEncryption,\n) (*JSONWebToken, error) {\n\tenc, err := parseEncryptedCompact(s, keyAlgorithms, contentEncryption)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &JSONWebToken{\n\t\tpayload: enc.Decrypt,\n\t\tHeaders: []jose.Header{enc.Header},\n\t}, nil\n}\n\n// ParseSignedAndEncrypted parses signed-then-encrypted token from JWE form.\n//\n// The encryptionKeyAlgorithms and contentEncryption parameters are used to validate the \"alg\" and \"enc\"\n// header parameters, respectively, of the outer JWE. They must be nonempty, and each \"alg\" or \"enc\"\n// header in parsed data must contain a value that is present in the corresponding parameter. That\n// includes the protected and unprotected headers as well as all recipients. To accept\n// multiple algorithms, pass a slice of all the algorithms you want to accept.\n//\n// The signatureAlgorithms parameter is used to validate the \"alg\" header parameter of the\n// inner JWS. It must be nonempty, and the \"alg\" header in the inner JWS must contain a value\n// that is present in the parameter.\nfunc ParseSignedAndEncrypted(s string,\n\tencryptionKeyAlgorithms []jose.KeyAlgorithm,\n\tcontentEncryption []jose.ContentEncryption,\n\tsignatureAlgorithms []jose.SignatureAlgorithm,\n) (*NestedJSONWebToken, error) {\n\tenc, err := parseEncryptedCompact(s, encryptionKeyAlgorithms, contentEncryption)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcontentType, _ := enc.Header.ExtraHeaders[jose.HeaderContentType].(string)\n\tif strings.ToUpper(contentType) != \"JWT\" {\n\t\treturn nil, ErrInvalidContentType\n\t}\n\n\treturn &NestedJSONWebToken{\n\t\tallowedSignatureAlgorithms: signatureAlgorithms,\n\t\tenc:                        enc,\n\t\tHeaders:                    []jose.Header{enc.Header},\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/jwt/validation.go",
    "content": "/*-\n * Copyright 2016 Zbigniew Mandziejewicz\n * Copyright 2016 Square, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage jwt\n\nimport \"time\"\n\nconst (\n\t// DefaultLeeway defines the default leeway for matching NotBefore/Expiry claims.\n\tDefaultLeeway = 1.0 * time.Minute\n)\n\n// Expected defines values used for protected claims validation.\n// If field has zero value then validation is skipped, with the exception of\n// Time, where the zero value means \"now.\" To skip validating them, set the\n// corresponding field in the Claims struct to nil.\ntype Expected struct {\n\t// Issuer matches the \"iss\" claim exactly.\n\tIssuer string\n\t// Subject matches the \"sub\" claim exactly.\n\tSubject string\n\t// AnyAudience matches if there is a non-empty intersection between\n\t// its values and the values in the \"aud\" claim.\n\tAnyAudience Audience\n\t// ID matches the \"jti\" claim exactly.\n\tID string\n\t// Time matches the \"exp\", \"nbf\" and \"iat\" claims with leeway.\n\tTime time.Time\n}\n\n// WithTime copies expectations with new time.\nfunc (e Expected) WithTime(t time.Time) Expected {\n\te.Time = t\n\treturn e\n}\n\n// Validate checks claims in a token against expected values.\n// A default leeway value of one minute is used to compare time values.\n//\n// The default leeway will cause the token to be deemed valid until one\n// minute after the expiration time. If you're a server application that\n// wants to give an extra minute to client tokens, use this\n// function. If you're a client application wondering if the server\n// will accept your token, use ValidateWithLeeway with a leeway <=0,\n// otherwise this function might make you think a token is valid when\n// it is not.\nfunc (c Claims) Validate(e Expected) error {\n\treturn c.ValidateWithLeeway(e, DefaultLeeway)\n}\n\n// ValidateWithLeeway checks claims in a token against expected values. A\n// custom leeway may be specified for comparing time values. You may pass a\n// zero value to check time values with no leeway, but you should note that\n// numeric date values are rounded to the nearest second and sub-second\n// precision is not supported.\n//\n// The leeway gives some extra time to the token from the server's\n// point of view. That is, if the token is expired, ValidateWithLeeway\n// will still accept the token for 'leeway' amount of time. This fails\n// if you're using this function to check if a server will accept your\n// token, because it will think the token is valid even after it\n// expires. So if you're a client validating if the token is valid to\n// be submitted to a server, use leeway <=0, if you're a server\n// validation a token, use leeway >=0.\nfunc (c Claims) ValidateWithLeeway(e Expected, leeway time.Duration) error {\n\tif e.Issuer != \"\" && e.Issuer != c.Issuer {\n\t\treturn ErrInvalidIssuer\n\t}\n\n\tif e.Subject != \"\" && e.Subject != c.Subject {\n\t\treturn ErrInvalidSubject\n\t}\n\n\tif e.ID != \"\" && e.ID != c.ID {\n\t\treturn ErrInvalidID\n\t}\n\n\tif len(e.AnyAudience) != 0 {\n\t\tvar intersection bool\n\t\tfor _, v := range e.AnyAudience {\n\t\t\tif c.Audience.Contains(v) {\n\t\t\t\tintersection = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif !intersection {\n\t\t\treturn ErrInvalidAudience\n\t\t}\n\t}\n\n\t// validate using the e.Time, or time.Now if not provided\n\tvalidationTime := e.Time\n\tif validationTime.IsZero() {\n\t\tvalidationTime = time.Now()\n\t}\n\n\tif c.NotBefore != nil && validationTime.Add(leeway).Before(c.NotBefore.Time()) {\n\t\treturn ErrNotValidYet\n\t}\n\n\tif c.Expiry != nil && validationTime.Add(-leeway).After(c.Expiry.Time()) {\n\t\treturn ErrExpired\n\t}\n\n\t// IssuedAt is optional but cannot be in the future. This is not required by the RFC, but\n\t// something is misconfigured if this happens and we should not trust it.\n\tif c.IssuedAt != nil && validationTime.Add(leeway).Before(c.IssuedAt.Time()) {\n\t\treturn ErrIssuedInTheFuture\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/opaque.go",
    "content": "/*-\n * Copyright 2018 Square Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage jose\n\n// OpaqueSigner is an interface that supports signing payloads with opaque\n// private key(s). Private key operations performed by implementers may, for\n// example, occur in a hardware module. An OpaqueSigner may rotate signing keys\n// transparently to the user of this interface.\ntype OpaqueSigner interface {\n\t// Public returns the public key of the current signing key.\n\tPublic() *JSONWebKey\n\t// Algs returns a list of supported signing algorithms.\n\tAlgs() []SignatureAlgorithm\n\t// SignPayload signs a payload with the current signing key using the given\n\t// algorithm.\n\tSignPayload(payload []byte, alg SignatureAlgorithm) ([]byte, error)\n}\n\ntype opaqueSigner struct {\n\tsigner OpaqueSigner\n}\n\nfunc newOpaqueSigner(alg SignatureAlgorithm, signer OpaqueSigner) (recipientSigInfo, error) {\n\tvar algSupported bool\n\tfor _, salg := range signer.Algs() {\n\t\tif alg == salg {\n\t\t\talgSupported = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif !algSupported {\n\t\treturn recipientSigInfo{}, ErrUnsupportedAlgorithm\n\t}\n\n\treturn recipientSigInfo{\n\t\tsigAlg:    alg,\n\t\tpublicKey: signer.Public,\n\t\tsigner: &opaqueSigner{\n\t\t\tsigner: signer,\n\t\t},\n\t}, nil\n}\n\nfunc (o *opaqueSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {\n\tout, err := o.signer.SignPayload(payload, alg)\n\tif err != nil {\n\t\treturn Signature{}, err\n\t}\n\n\treturn Signature{\n\t\tSignature: out,\n\t\tprotected: &rawHeader{},\n\t}, nil\n}\n\n// OpaqueVerifier is an interface that supports verifying payloads with opaque\n// public key(s). An OpaqueSigner may rotate signing keys transparently to the\n// user of this interface.\ntype OpaqueVerifier interface {\n\tVerifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error\n}\n\ntype opaqueVerifier struct {\n\tverifier OpaqueVerifier\n}\n\nfunc (o *opaqueVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {\n\treturn o.verifier.VerifyPayload(payload, signature, alg)\n}\n\n// OpaqueKeyEncrypter is an interface that supports encrypting keys with an opaque key.\n//\n// Note: this cannot currently be implemented outside this package because of its\n// unexported method.\ntype OpaqueKeyEncrypter interface {\n\t// KeyID returns the kid\n\tKeyID() string\n\t// Algs returns a list of supported key encryption algorithms.\n\tAlgs() []KeyAlgorithm\n\t// encryptKey encrypts the CEK using the given algorithm.\n\tencryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error)\n}\n\ntype opaqueKeyEncrypter struct {\n\tencrypter OpaqueKeyEncrypter\n}\n\nfunc newOpaqueKeyEncrypter(alg KeyAlgorithm, encrypter OpaqueKeyEncrypter) (recipientKeyInfo, error) {\n\tvar algSupported bool\n\tfor _, salg := range encrypter.Algs() {\n\t\tif alg == salg {\n\t\t\talgSupported = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif !algSupported {\n\t\treturn recipientKeyInfo{}, ErrUnsupportedAlgorithm\n\t}\n\n\treturn recipientKeyInfo{\n\t\tkeyID:  encrypter.KeyID(),\n\t\tkeyAlg: alg,\n\t\tkeyEncrypter: &opaqueKeyEncrypter{\n\t\t\tencrypter: encrypter,\n\t\t},\n\t}, nil\n}\n\nfunc (oke *opaqueKeyEncrypter) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {\n\treturn oke.encrypter.encryptKey(cek, alg)\n}\n\n// OpaqueKeyDecrypter is an interface that supports decrypting keys with an opaque key.\ntype OpaqueKeyDecrypter interface {\n\tDecryptKey(encryptedKey []byte, header Header) ([]byte, error)\n}\n\ntype opaqueKeyDecrypter struct {\n\tdecrypter OpaqueKeyDecrypter\n}\n\nfunc (okd *opaqueKeyDecrypter) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {\n\tmergedHeaders := rawHeader{}\n\tmergedHeaders.merge(&headers)\n\tmergedHeaders.merge(recipient.header)\n\n\theader, err := mergedHeaders.sanitized()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn okd.decrypter.DecryptKey(recipient.encryptedKey, header)\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/shared.go",
    "content": "/*-\n * Copyright 2014 Square Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage jose\n\nimport (\n\t\"crypto/elliptic\"\n\t\"crypto/x509\"\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/go-jose/go-jose/v4/json\"\n)\n\n// KeyAlgorithm represents a key management algorithm.\ntype KeyAlgorithm string\n\n// SignatureAlgorithm represents a signature (or MAC) algorithm.\ntype SignatureAlgorithm string\n\n// ContentEncryption represents a content encryption algorithm.\ntype ContentEncryption string\n\n// CompressionAlgorithm represents an algorithm used for plaintext compression.\ntype CompressionAlgorithm string\n\n// ContentType represents type of the contained data.\ntype ContentType string\n\nvar (\n\t// ErrCryptoFailure represents an error in cryptographic primitive. This\n\t// occurs when, for example, a message had an invalid authentication tag or\n\t// could not be decrypted.\n\tErrCryptoFailure = errors.New(\"go-jose/go-jose: error in cryptographic primitive\")\n\n\t// ErrUnsupportedAlgorithm indicates that a selected algorithm is not\n\t// supported. This occurs when trying to instantiate an encrypter for an\n\t// algorithm that is not yet implemented.\n\tErrUnsupportedAlgorithm = errors.New(\"go-jose/go-jose: unknown/unsupported algorithm\")\n\n\t// ErrUnsupportedKeyType indicates that the given key type/format is not\n\t// supported. This occurs when trying to instantiate an encrypter and passing\n\t// it a key of an unrecognized type or with unsupported parameters, such as\n\t// an RSA private key with more than two primes.\n\tErrUnsupportedKeyType = errors.New(\"go-jose/go-jose: unsupported key type/format\")\n\n\t// ErrInvalidKeySize indicates that the given key is not the correct size\n\t// for the selected algorithm. This can occur, for example, when trying to\n\t// encrypt with AES-256 but passing only a 128-bit key as input.\n\tErrInvalidKeySize = errors.New(\"go-jose/go-jose: invalid key size for algorithm\")\n\n\t// ErrNotSupported serialization of object is not supported. This occurs when\n\t// trying to compact-serialize an object which can't be represented in\n\t// compact form.\n\tErrNotSupported = errors.New(\"go-jose/go-jose: compact serialization not supported for object\")\n\n\t// ErrUnprotectedNonce indicates that while parsing a JWS or JWE object, a\n\t// nonce header parameter was included in an unprotected header object.\n\tErrUnprotectedNonce = errors.New(\"go-jose/go-jose: Nonce parameter included in unprotected header\")\n\n\t// ErrMissingX5cHeader indicates that the JWT header is missing x5c headers.\n\tErrMissingX5cHeader = errors.New(\"go-jose/go-jose: no x5c header present in message\")\n\n\t// ErrUnsupportedEllipticCurve indicates unsupported or unknown elliptic curve has been found.\n\tErrUnsupportedEllipticCurve = errors.New(\"go-jose/go-jose: unsupported/unknown elliptic curve\")\n\n\t// ErrUnsupportedCriticalHeader is returned when a header is marked critical but not supported by go-jose.\n\tErrUnsupportedCriticalHeader = errors.New(\"go-jose/go-jose: unsupported critical header\")\n)\n\n// Key management algorithms\nconst (\n\tED25519            = KeyAlgorithm(\"ED25519\")\n\tRSA1_5             = KeyAlgorithm(\"RSA1_5\")             // RSA-PKCS1v1.5\n\tRSA_OAEP           = KeyAlgorithm(\"RSA-OAEP\")           // RSA-OAEP-SHA1\n\tRSA_OAEP_256       = KeyAlgorithm(\"RSA-OAEP-256\")       // RSA-OAEP-SHA256\n\tA128KW             = KeyAlgorithm(\"A128KW\")             // AES key wrap (128)\n\tA192KW             = KeyAlgorithm(\"A192KW\")             // AES key wrap (192)\n\tA256KW             = KeyAlgorithm(\"A256KW\")             // AES key wrap (256)\n\tDIRECT             = KeyAlgorithm(\"dir\")                // Direct encryption\n\tECDH_ES            = KeyAlgorithm(\"ECDH-ES\")            // ECDH-ES\n\tECDH_ES_A128KW     = KeyAlgorithm(\"ECDH-ES+A128KW\")     // ECDH-ES + AES key wrap (128)\n\tECDH_ES_A192KW     = KeyAlgorithm(\"ECDH-ES+A192KW\")     // ECDH-ES + AES key wrap (192)\n\tECDH_ES_A256KW     = KeyAlgorithm(\"ECDH-ES+A256KW\")     // ECDH-ES + AES key wrap (256)\n\tA128GCMKW          = KeyAlgorithm(\"A128GCMKW\")          // AES-GCM key wrap (128)\n\tA192GCMKW          = KeyAlgorithm(\"A192GCMKW\")          // AES-GCM key wrap (192)\n\tA256GCMKW          = KeyAlgorithm(\"A256GCMKW\")          // AES-GCM key wrap (256)\n\tPBES2_HS256_A128KW = KeyAlgorithm(\"PBES2-HS256+A128KW\") // PBES2 + HMAC-SHA256 + AES key wrap (128)\n\tPBES2_HS384_A192KW = KeyAlgorithm(\"PBES2-HS384+A192KW\") // PBES2 + HMAC-SHA384 + AES key wrap (192)\n\tPBES2_HS512_A256KW = KeyAlgorithm(\"PBES2-HS512+A256KW\") // PBES2 + HMAC-SHA512 + AES key wrap (256)\n)\n\n// Signature algorithms\nconst (\n\tEdDSA = SignatureAlgorithm(\"EdDSA\")\n\tHS256 = SignatureAlgorithm(\"HS256\") // HMAC using SHA-256\n\tHS384 = SignatureAlgorithm(\"HS384\") // HMAC using SHA-384\n\tHS512 = SignatureAlgorithm(\"HS512\") // HMAC using SHA-512\n\tRS256 = SignatureAlgorithm(\"RS256\") // RSASSA-PKCS-v1.5 using SHA-256\n\tRS384 = SignatureAlgorithm(\"RS384\") // RSASSA-PKCS-v1.5 using SHA-384\n\tRS512 = SignatureAlgorithm(\"RS512\") // RSASSA-PKCS-v1.5 using SHA-512\n\tES256 = SignatureAlgorithm(\"ES256\") // ECDSA using P-256 and SHA-256\n\tES384 = SignatureAlgorithm(\"ES384\") // ECDSA using P-384 and SHA-384\n\tES512 = SignatureAlgorithm(\"ES512\") // ECDSA using P-521 and SHA-512\n\tPS256 = SignatureAlgorithm(\"PS256\") // RSASSA-PSS using SHA256 and MGF1-SHA256\n\tPS384 = SignatureAlgorithm(\"PS384\") // RSASSA-PSS using SHA384 and MGF1-SHA384\n\tPS512 = SignatureAlgorithm(\"PS512\") // RSASSA-PSS using SHA512 and MGF1-SHA512\n)\n\n// Content encryption algorithms\nconst (\n\tA128CBC_HS256 = ContentEncryption(\"A128CBC-HS256\") // AES-CBC + HMAC-SHA256 (128)\n\tA192CBC_HS384 = ContentEncryption(\"A192CBC-HS384\") // AES-CBC + HMAC-SHA384 (192)\n\tA256CBC_HS512 = ContentEncryption(\"A256CBC-HS512\") // AES-CBC + HMAC-SHA512 (256)\n\tA128GCM       = ContentEncryption(\"A128GCM\")       // AES-GCM (128)\n\tA192GCM       = ContentEncryption(\"A192GCM\")       // AES-GCM (192)\n\tA256GCM       = ContentEncryption(\"A256GCM\")       // AES-GCM (256)\n)\n\n// Compression algorithms\nconst (\n\tNONE    = CompressionAlgorithm(\"\")    // No compression\n\tDEFLATE = CompressionAlgorithm(\"DEF\") // DEFLATE (RFC 1951)\n)\n\n// A key in the protected header of a JWS object. Use of the Header...\n// constants is preferred to enhance type safety.\ntype HeaderKey string\n\nconst (\n\tHeaderType        = \"typ\" // string\n\tHeaderContentType = \"cty\" // string\n\n\t// These are set by go-jose and shouldn't need to be set by consumers of the\n\t// library.\n\theaderAlgorithm   = \"alg\"  // string\n\theaderEncryption  = \"enc\"  // ContentEncryption\n\theaderCompression = \"zip\"  // CompressionAlgorithm\n\theaderCritical    = \"crit\" // []string\n\n\theaderAPU = \"apu\" // *byteBuffer\n\theaderAPV = \"apv\" // *byteBuffer\n\theaderEPK = \"epk\" // *JSONWebKey\n\theaderIV  = \"iv\"  // *byteBuffer\n\theaderTag = \"tag\" // *byteBuffer\n\theaderX5c = \"x5c\" // []*x509.Certificate\n\n\theaderJWK   = \"jwk\"   // *JSONWebKey\n\theaderKeyID = \"kid\"   // string\n\theaderNonce = \"nonce\" // string\n\theaderB64   = \"b64\"   // bool\n\n\theaderP2C = \"p2c\" // *byteBuffer (int)\n\theaderP2S = \"p2s\" // *byteBuffer ([]byte)\n\n)\n\n// supportedCritical is the set of supported extensions that are understood and processed.\nvar supportedCritical = map[string]struct{}{\n\theaderB64: {},\n}\n\n// rawHeader represents the JOSE header for JWE/JWS objects (used for parsing).\n//\n// The decoding of the constituent items is deferred because we want to marshal\n// some members into particular structs rather than generic maps, but at the\n// same time we need to receive any extra fields unhandled by this library to\n// pass through to consuming code in case it wants to examine them.\ntype rawHeader map[HeaderKey]*json.RawMessage\n\n// Header represents the read-only JOSE header for JWE/JWS objects.\ntype Header struct {\n\tKeyID      string\n\tJSONWebKey *JSONWebKey\n\tAlgorithm  string\n\tNonce      string\n\n\t// Unverified certificate chain parsed from x5c header.\n\tcertificates []*x509.Certificate\n\n\t// At parse time, each header parameter with a name other than \"kid\",\n\t// \"jwk\", \"alg\", \"nonce\", or \"x5c\"  will have its value passed to\n\t// [json.Unmarshal] to unmarshal it into an interface value.\n\t// The resulting value will be stored in this map, with the header\n\t// parameter name as the key.\n\t//\n\t// [json.Unmarshal]: https://pkg.go.dev/encoding/json#Unmarshal\n\tExtraHeaders map[HeaderKey]interface{}\n}\n\n// Certificates verifies & returns the certificate chain present\n// in the x5c header field of a message, if one was present. Returns\n// an error if there was no x5c header present or the chain could\n// not be validated with the given verify options.\nfunc (h Header) Certificates(opts x509.VerifyOptions) ([][]*x509.Certificate, error) {\n\tif len(h.certificates) == 0 {\n\t\treturn nil, ErrMissingX5cHeader\n\t}\n\n\tleaf := h.certificates[0]\n\tif opts.Intermediates == nil {\n\t\topts.Intermediates = x509.NewCertPool()\n\t\tfor _, intermediate := range h.certificates[1:] {\n\t\t\topts.Intermediates.AddCert(intermediate)\n\t\t}\n\t}\n\n\treturn leaf.Verify(opts)\n}\n\nfunc (parsed rawHeader) set(k HeaderKey, v interface{}) error {\n\tb, err := json.Marshal(v)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tparsed[k] = makeRawMessage(b)\n\treturn nil\n}\n\n// getString gets a string from the raw JSON, defaulting to \"\".\nfunc (parsed rawHeader) getString(k HeaderKey) string {\n\tv, ok := parsed[k]\n\tif !ok || v == nil {\n\t\treturn \"\"\n\t}\n\tvar s string\n\terr := json.Unmarshal(*v, &s)\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\treturn s\n}\n\n// getByteBuffer gets a byte buffer from the raw JSON. Returns (nil, nil) if\n// not specified.\nfunc (parsed rawHeader) getByteBuffer(k HeaderKey) (*byteBuffer, error) {\n\tv := parsed[k]\n\tif v == nil {\n\t\treturn nil, nil\n\t}\n\tvar bb *byteBuffer\n\terr := json.Unmarshal(*v, &bb)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn bb, nil\n}\n\n// getAlgorithm extracts parsed \"alg\" from the raw JSON as a KeyAlgorithm.\nfunc (parsed rawHeader) getAlgorithm() KeyAlgorithm {\n\treturn KeyAlgorithm(parsed.getString(headerAlgorithm))\n}\n\n// getSignatureAlgorithm extracts parsed \"alg\" from the raw JSON as a SignatureAlgorithm.\nfunc (parsed rawHeader) getSignatureAlgorithm() SignatureAlgorithm {\n\treturn SignatureAlgorithm(parsed.getString(headerAlgorithm))\n}\n\n// getEncryption extracts parsed \"enc\" from the raw JSON.\nfunc (parsed rawHeader) getEncryption() ContentEncryption {\n\treturn ContentEncryption(parsed.getString(headerEncryption))\n}\n\n// getCompression extracts parsed \"zip\" from the raw JSON.\nfunc (parsed rawHeader) getCompression() CompressionAlgorithm {\n\treturn CompressionAlgorithm(parsed.getString(headerCompression))\n}\n\nfunc (parsed rawHeader) getNonce() string {\n\treturn parsed.getString(headerNonce)\n}\n\n// getEPK extracts parsed \"epk\" from the raw JSON.\nfunc (parsed rawHeader) getEPK() (*JSONWebKey, error) {\n\tv := parsed[headerEPK]\n\tif v == nil {\n\t\treturn nil, nil\n\t}\n\tvar epk *JSONWebKey\n\terr := json.Unmarshal(*v, &epk)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn epk, nil\n}\n\n// getAPU extracts parsed \"apu\" from the raw JSON.\nfunc (parsed rawHeader) getAPU() (*byteBuffer, error) {\n\treturn parsed.getByteBuffer(headerAPU)\n}\n\n// getAPV extracts parsed \"apv\" from the raw JSON.\nfunc (parsed rawHeader) getAPV() (*byteBuffer, error) {\n\treturn parsed.getByteBuffer(headerAPV)\n}\n\n// getIV extracts parsed \"iv\" from the raw JSON.\nfunc (parsed rawHeader) getIV() (*byteBuffer, error) {\n\treturn parsed.getByteBuffer(headerIV)\n}\n\n// getTag extracts parsed \"tag\" from the raw JSON.\nfunc (parsed rawHeader) getTag() (*byteBuffer, error) {\n\treturn parsed.getByteBuffer(headerTag)\n}\n\n// getJWK extracts parsed \"jwk\" from the raw JSON.\nfunc (parsed rawHeader) getJWK() (*JSONWebKey, error) {\n\tv := parsed[headerJWK]\n\tif v == nil {\n\t\treturn nil, nil\n\t}\n\tvar jwk *JSONWebKey\n\terr := json.Unmarshal(*v, &jwk)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn jwk, nil\n}\n\n// getCritical extracts parsed \"crit\" from the raw JSON. If omitted, it\n// returns an empty slice.\nfunc (parsed rawHeader) getCritical() ([]string, error) {\n\tv := parsed[headerCritical]\n\tif v == nil {\n\t\treturn nil, nil\n\t}\n\n\tvar q []string\n\terr := json.Unmarshal(*v, &q)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn q, nil\n}\n\n// checkNoCritical verifies there are no critical headers present.\nfunc (parsed rawHeader) checkNoCritical() error {\n\tif _, ok := parsed[headerCritical]; ok {\n\t\treturn ErrUnsupportedCriticalHeader\n\t}\n\n\treturn nil\n}\n\n// checkSupportedCritical verifies there are no unsupported critical headers.\n// Supported headers are passed in as a set: map of names to empty structs\nfunc (parsed rawHeader) checkSupportedCritical(supported map[string]struct{}) error {\n\tcrit, err := parsed.getCritical()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor _, name := range crit {\n\t\tif _, ok := supported[name]; !ok {\n\t\t\treturn ErrUnsupportedCriticalHeader\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// getS2C extracts parsed \"p2c\" from the raw JSON.\nfunc (parsed rawHeader) getP2C() (int, error) {\n\tv := parsed[headerP2C]\n\tif v == nil {\n\t\treturn 0, nil\n\t}\n\n\tvar p2c int\n\terr := json.Unmarshal(*v, &p2c)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn p2c, nil\n}\n\n// getS2S extracts parsed \"p2s\" from the raw JSON.\nfunc (parsed rawHeader) getP2S() (*byteBuffer, error) {\n\treturn parsed.getByteBuffer(headerP2S)\n}\n\n// getB64 extracts parsed \"b64\" from the raw JSON, defaulting to true.\nfunc (parsed rawHeader) getB64() (bool, error) {\n\tv := parsed[headerB64]\n\tif v == nil {\n\t\treturn true, nil\n\t}\n\n\tvar b64 bool\n\terr := json.Unmarshal(*v, &b64)\n\tif err != nil {\n\t\treturn true, err\n\t}\n\treturn b64, nil\n}\n\n// sanitized produces a cleaned-up header object from the raw JSON.\nfunc (parsed rawHeader) sanitized() (h Header, err error) {\n\tfor k, v := range parsed {\n\t\tif v == nil {\n\t\t\tcontinue\n\t\t}\n\t\tswitch k {\n\t\tcase headerJWK:\n\t\t\tvar jwk *JSONWebKey\n\t\t\terr = json.Unmarshal(*v, &jwk)\n\t\t\tif err != nil {\n\t\t\t\terr = fmt.Errorf(\"failed to unmarshal JWK: %v: %#v\", err, string(*v))\n\t\t\t\treturn\n\t\t\t}\n\t\t\th.JSONWebKey = jwk\n\t\tcase headerKeyID:\n\t\t\tvar s string\n\t\t\terr = json.Unmarshal(*v, &s)\n\t\t\tif err != nil {\n\t\t\t\terr = fmt.Errorf(\"failed to unmarshal key ID: %v: %#v\", err, string(*v))\n\t\t\t\treturn\n\t\t\t}\n\t\t\th.KeyID = s\n\t\tcase headerAlgorithm:\n\t\t\tvar s string\n\t\t\terr = json.Unmarshal(*v, &s)\n\t\t\tif err != nil {\n\t\t\t\terr = fmt.Errorf(\"failed to unmarshal algorithm: %v: %#v\", err, string(*v))\n\t\t\t\treturn\n\t\t\t}\n\t\t\th.Algorithm = s\n\t\tcase headerNonce:\n\t\t\tvar s string\n\t\t\terr = json.Unmarshal(*v, &s)\n\t\t\tif err != nil {\n\t\t\t\terr = fmt.Errorf(\"failed to unmarshal nonce: %v: %#v\", err, string(*v))\n\t\t\t\treturn\n\t\t\t}\n\t\t\th.Nonce = s\n\t\tcase headerX5c:\n\t\t\tc := []string{}\n\t\t\terr = json.Unmarshal(*v, &c)\n\t\t\tif err != nil {\n\t\t\t\terr = fmt.Errorf(\"failed to unmarshal x5c header: %v: %#v\", err, string(*v))\n\t\t\t\treturn\n\t\t\t}\n\t\t\th.certificates, err = parseCertificateChain(c)\n\t\t\tif err != nil {\n\t\t\t\terr = fmt.Errorf(\"failed to unmarshal x5c header: %v: %#v\", err, string(*v))\n\t\t\t\treturn\n\t\t\t}\n\t\tdefault:\n\t\t\tif h.ExtraHeaders == nil {\n\t\t\t\th.ExtraHeaders = map[HeaderKey]interface{}{}\n\t\t\t}\n\t\t\tvar v2 interface{}\n\t\t\terr = json.Unmarshal(*v, &v2)\n\t\t\tif err != nil {\n\t\t\t\terr = fmt.Errorf(\"failed to unmarshal value: %v: %#v\", err, string(*v))\n\t\t\t\treturn\n\t\t\t}\n\t\t\th.ExtraHeaders[k] = v2\n\t\t}\n\t}\n\treturn\n}\n\nfunc parseCertificateChain(chain []string) ([]*x509.Certificate, error) {\n\tout := make([]*x509.Certificate, len(chain))\n\tfor i, cert := range chain {\n\t\traw, err := base64.StdEncoding.DecodeString(cert)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tout[i], err = x509.ParseCertificate(raw)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn out, nil\n}\n\nfunc (parsed rawHeader) isSet(k HeaderKey) bool {\n\tdvr := parsed[k]\n\tif dvr == nil {\n\t\treturn false\n\t}\n\n\tvar dv interface{}\n\terr := json.Unmarshal(*dvr, &dv)\n\tif err != nil {\n\t\treturn true\n\t}\n\n\tif dvStr, ok := dv.(string); ok {\n\t\treturn dvStr != \"\"\n\t}\n\n\treturn true\n}\n\n// Merge headers from src into dst, giving precedence to headers from l.\nfunc (parsed rawHeader) merge(src *rawHeader) {\n\tif src == nil {\n\t\treturn\n\t}\n\n\tfor k, v := range *src {\n\t\tif parsed.isSet(k) {\n\t\t\tcontinue\n\t\t}\n\n\t\tparsed[k] = v\n\t}\n}\n\n// Get JOSE name of curve\nfunc curveName(crv elliptic.Curve) (string, error) {\n\tswitch crv {\n\tcase elliptic.P256():\n\t\treturn \"P-256\", nil\n\tcase elliptic.P384():\n\t\treturn \"P-384\", nil\n\tcase elliptic.P521():\n\t\treturn \"P-521\", nil\n\tdefault:\n\t\treturn \"\", ErrUnsupportedEllipticCurve\n\t}\n}\n\n// Get size of curve in bytes\nfunc curveSize(crv elliptic.Curve) int {\n\tbits := crv.Params().BitSize\n\n\tdiv := bits / 8\n\tmod := bits % 8\n\n\tif mod == 0 {\n\t\treturn div\n\t}\n\n\treturn div + 1\n}\n\nfunc makeRawMessage(b []byte) *json.RawMessage {\n\trm := json.RawMessage(b)\n\treturn &rm\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/signing.go",
    "content": "/*-\n * Copyright 2014 Square Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage jose\n\nimport (\n\t\"bytes\"\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/rsa\"\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/go-jose/go-jose/v4/json\"\n)\n\n// NonceSource represents a source of random nonces to go into JWS objects\ntype NonceSource interface {\n\tNonce() (string, error)\n}\n\n// Signer represents a signer which takes a payload and produces a signed JWS object.\ntype Signer interface {\n\tSign(payload []byte) (*JSONWebSignature, error)\n\tOptions() SignerOptions\n}\n\n// SigningKey represents an algorithm/key used to sign a message.\n//\n// Key must have one of these types:\n//   - ed25519.PrivateKey\n//   - *ecdsa.PrivateKey\n//   - *rsa.PrivateKey\n//   - *JSONWebKey\n//   - JSONWebKey\n//   - []byte (an HMAC key)\n//   - Any type that satisfies the OpaqueSigner interface\n//\n// If the key is an HMAC key, it must have at least as many bytes as the relevant hash output:\n//   - HS256: 32 bytes\n//   - HS384: 48 bytes\n//   - HS512: 64 bytes\ntype SigningKey struct {\n\tAlgorithm SignatureAlgorithm\n\tKey       interface{}\n}\n\n// SignerOptions represents options that can be set when creating signers.\ntype SignerOptions struct {\n\tNonceSource NonceSource\n\tEmbedJWK    bool\n\n\t// Optional map of additional keys to be inserted into the protected header\n\t// of a JWS object. Some specifications which make use of JWS like to insert\n\t// additional values here.\n\t//\n\t// Values will be serialized by [json.Marshal] and must be valid inputs to\n\t// that function.\n\t//\n\t// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal\n\tExtraHeaders map[HeaderKey]interface{}\n}\n\n// WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it\n// if necessary, and returns the updated SignerOptions.\n//\n// The v argument will be serialized by [json.Marshal] and must be a valid\n// input to that function.\n//\n// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal\nfunc (so *SignerOptions) WithHeader(k HeaderKey, v interface{}) *SignerOptions {\n\tif so.ExtraHeaders == nil {\n\t\tso.ExtraHeaders = map[HeaderKey]interface{}{}\n\t}\n\tso.ExtraHeaders[k] = v\n\treturn so\n}\n\n// WithContentType adds a content type (\"cty\") header and returns the updated\n// SignerOptions.\nfunc (so *SignerOptions) WithContentType(contentType ContentType) *SignerOptions {\n\treturn so.WithHeader(HeaderContentType, contentType)\n}\n\n// WithType adds a type (\"typ\") header and returns the updated SignerOptions.\nfunc (so *SignerOptions) WithType(typ ContentType) *SignerOptions {\n\treturn so.WithHeader(HeaderType, typ)\n}\n\n// WithCritical adds the given names to the critical (\"crit\") header and returns\n// the updated SignerOptions.\nfunc (so *SignerOptions) WithCritical(names ...string) *SignerOptions {\n\tif so.ExtraHeaders[headerCritical] == nil {\n\t\tso.WithHeader(headerCritical, make([]string, 0, len(names)))\n\t}\n\tcrit := so.ExtraHeaders[headerCritical].([]string)\n\tso.ExtraHeaders[headerCritical] = append(crit, names...)\n\treturn so\n}\n\n// WithBase64 adds a base64url-encode payload (\"b64\") header and returns the updated\n// SignerOptions. When the \"b64\" value is \"false\", the payload is not base64 encoded.\nfunc (so *SignerOptions) WithBase64(b64 bool) *SignerOptions {\n\tif !b64 {\n\t\tso.WithHeader(headerB64, b64)\n\t\tso.WithCritical(headerB64)\n\t}\n\treturn so\n}\n\ntype payloadSigner interface {\n\tsignPayload(payload []byte, alg SignatureAlgorithm) (Signature, error)\n}\n\ntype payloadVerifier interface {\n\tverifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error\n}\n\ntype genericSigner struct {\n\trecipients   []recipientSigInfo\n\tnonceSource  NonceSource\n\tembedJWK     bool\n\textraHeaders map[HeaderKey]interface{}\n}\n\ntype recipientSigInfo struct {\n\tsigAlg    SignatureAlgorithm\n\tpublicKey func() *JSONWebKey\n\tsigner    payloadSigner\n}\n\nfunc staticPublicKey(jwk *JSONWebKey) func() *JSONWebKey {\n\treturn func() *JSONWebKey {\n\t\treturn jwk\n\t}\n}\n\n// NewSigner creates an appropriate signer based on the key type\nfunc NewSigner(sig SigningKey, opts *SignerOptions) (Signer, error) {\n\treturn NewMultiSigner([]SigningKey{sig}, opts)\n}\n\n// NewMultiSigner creates a signer for multiple recipients\nfunc NewMultiSigner(sigs []SigningKey, opts *SignerOptions) (Signer, error) {\n\tsigner := &genericSigner{recipients: []recipientSigInfo{}}\n\n\tif opts != nil {\n\t\tsigner.nonceSource = opts.NonceSource\n\t\tsigner.embedJWK = opts.EmbedJWK\n\t\tsigner.extraHeaders = opts.ExtraHeaders\n\t}\n\n\tfor _, sig := range sigs {\n\t\terr := signer.addRecipient(sig.Algorithm, sig.Key)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn signer, nil\n}\n\n// newVerifier creates a verifier based on the key type\nfunc newVerifier(verificationKey interface{}) (payloadVerifier, error) {\n\tswitch verificationKey := verificationKey.(type) {\n\tcase ed25519.PublicKey:\n\t\treturn &edEncrypterVerifier{\n\t\t\tpublicKey: verificationKey,\n\t\t}, nil\n\tcase *rsa.PublicKey:\n\t\treturn &rsaEncrypterVerifier{\n\t\t\tpublicKey: verificationKey,\n\t\t}, nil\n\tcase *ecdsa.PublicKey:\n\t\treturn &ecEncrypterVerifier{\n\t\t\tpublicKey: verificationKey,\n\t\t}, nil\n\tcase []byte:\n\t\treturn &symmetricMac{\n\t\t\tkey: verificationKey,\n\t\t}, nil\n\tcase JSONWebKey:\n\t\treturn newVerifier(verificationKey.Key)\n\tcase *JSONWebKey:\n\t\treturn newVerifier(verificationKey.Key)\n\tcase OpaqueVerifier:\n\t\treturn &opaqueVerifier{verifier: verificationKey}, nil\n\tdefault:\n\t\treturn nil, ErrUnsupportedKeyType\n\t}\n}\n\nfunc (ctx *genericSigner) addRecipient(alg SignatureAlgorithm, signingKey interface{}) error {\n\trecipient, err := makeJWSRecipient(alg, signingKey)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tctx.recipients = append(ctx.recipients, recipient)\n\treturn nil\n}\n\nfunc makeJWSRecipient(alg SignatureAlgorithm, signingKey interface{}) (recipientSigInfo, error) {\n\tswitch signingKey := signingKey.(type) {\n\tcase ed25519.PrivateKey:\n\t\treturn newEd25519Signer(alg, signingKey)\n\tcase *rsa.PrivateKey:\n\t\treturn newRSASigner(alg, signingKey)\n\tcase *ecdsa.PrivateKey:\n\t\treturn newECDSASigner(alg, signingKey)\n\tcase []byte:\n\t\treturn newSymmetricSigner(alg, signingKey)\n\tcase JSONWebKey:\n\t\treturn newJWKSigner(alg, signingKey)\n\tcase *JSONWebKey:\n\t\treturn newJWKSigner(alg, *signingKey)\n\tcase OpaqueSigner:\n\t\treturn newOpaqueSigner(alg, signingKey)\n\tdefault:\n\t\treturn recipientSigInfo{}, ErrUnsupportedKeyType\n\t}\n}\n\nfunc newJWKSigner(alg SignatureAlgorithm, signingKey JSONWebKey) (recipientSigInfo, error) {\n\trecipient, err := makeJWSRecipient(alg, signingKey.Key)\n\tif err != nil {\n\t\treturn recipientSigInfo{}, err\n\t}\n\tif recipient.publicKey != nil && recipient.publicKey() != nil {\n\t\t// recipient.publicKey is a JWK synthesized for embedding when recipientSigInfo\n\t\t// was created for the inner key (such as a RSA or ECDSA public key). It contains\n\t\t// the pub key for embedding, but doesn't have extra params like key id.\n\t\tpublicKey := signingKey\n\t\tpublicKey.Key = recipient.publicKey().Key\n\t\trecipient.publicKey = staticPublicKey(&publicKey)\n\n\t\t// This should be impossible, but let's check anyway.\n\t\tif !recipient.publicKey().IsPublic() {\n\t\t\treturn recipientSigInfo{}, errors.New(\"go-jose/go-jose: public key was unexpectedly not public\")\n\t\t}\n\t}\n\treturn recipient, nil\n}\n\nfunc (ctx *genericSigner) Sign(payload []byte) (*JSONWebSignature, error) {\n\tobj := &JSONWebSignature{}\n\tobj.payload = payload\n\tobj.Signatures = make([]Signature, len(ctx.recipients))\n\n\tfor i, recipient := range ctx.recipients {\n\t\tprotected := map[HeaderKey]interface{}{\n\t\t\theaderAlgorithm: string(recipient.sigAlg),\n\t\t}\n\n\t\tif recipient.publicKey != nil && recipient.publicKey() != nil {\n\t\t\t// We want to embed the JWK or set the kid header, but not both. Having a protected\n\t\t\t// header that contains an embedded JWK while also simultaneously containing the kid\n\t\t\t// header is confusing, and at least in ACME the two are considered to be mutually\n\t\t\t// exclusive. The fact that both can exist at the same time is a somewhat unfortunate\n\t\t\t// result of the JOSE spec. We've decided that this library will only include one or\n\t\t\t// the other to avoid this confusion.\n\t\t\t//\n\t\t\t// See https://github.com/go-jose/go-jose/issues/157 for more context.\n\t\t\tif ctx.embedJWK {\n\t\t\t\tprotected[headerJWK] = recipient.publicKey()\n\t\t\t} else {\n\t\t\t\tkeyID := recipient.publicKey().KeyID\n\t\t\t\tif keyID != \"\" {\n\t\t\t\t\tprotected[headerKeyID] = keyID\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ctx.nonceSource != nil {\n\t\t\tnonce, err := ctx.nonceSource.Nonce()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: Error generating nonce: %v\", err)\n\t\t\t}\n\t\t\tprotected[headerNonce] = nonce\n\t\t}\n\n\t\tfor k, v := range ctx.extraHeaders {\n\t\t\tprotected[k] = v\n\t\t}\n\n\t\tserializedProtected := mustSerializeJSON(protected)\n\t\tneedsBase64 := true\n\n\t\tif b64, ok := protected[headerB64]; ok {\n\t\t\tif needsBase64, ok = b64.(bool); !ok {\n\t\t\t\treturn nil, errors.New(\"go-jose/go-jose: Invalid b64 header parameter\")\n\t\t\t}\n\t\t}\n\n\t\tvar input bytes.Buffer\n\n\t\tinput.WriteString(base64.RawURLEncoding.EncodeToString(serializedProtected))\n\t\tinput.WriteByte('.')\n\n\t\tif needsBase64 {\n\t\t\tinput.WriteString(base64.RawURLEncoding.EncodeToString(payload))\n\t\t} else {\n\t\t\tinput.Write(payload)\n\t\t}\n\n\t\tsignatureInfo, err := recipient.signer.signPayload(input.Bytes(), recipient.sigAlg)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tsignatureInfo.protected = &rawHeader{}\n\t\tfor k, v := range protected {\n\t\t\tb, err := json.Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: Error marshalling item %#v: %v\", k, err)\n\t\t\t}\n\t\t\t(*signatureInfo.protected)[k] = makeRawMessage(b)\n\t\t}\n\t\tobj.Signatures[i] = signatureInfo\n\t}\n\n\treturn obj, nil\n}\n\nfunc (ctx *genericSigner) Options() SignerOptions {\n\treturn SignerOptions{\n\t\tNonceSource:  ctx.nonceSource,\n\t\tEmbedJWK:     ctx.embedJWK,\n\t\tExtraHeaders: ctx.extraHeaders,\n\t}\n}\n\n// Verify validates the signature on the object and returns the payload.\n// This function does not support multi-signature. If you desire multi-signature\n// verification use VerifyMulti instead.\n//\n// Be careful when verifying signatures based on embedded JWKs inside the\n// payload header. You cannot assume that the key received in a payload is\n// trusted.\n//\n// The verificationKey argument must have one of these types:\n//   - ed25519.PublicKey\n//   - *ecdsa.PublicKey\n//   - *rsa.PublicKey\n//   - *JSONWebKey\n//   - JSONWebKey\n//   - *JSONWebKeySet\n//   - JSONWebKeySet\n//   - []byte (an HMAC key)\n//   - Any type that implements the OpaqueVerifier interface.\n//\n// If the key is an HMAC key, it must have at least as many bytes as the relevant hash output:\n//   - HS256: 32 bytes\n//   - HS384: 48 bytes\n//   - HS512: 64 bytes\nfunc (obj JSONWebSignature) Verify(verificationKey interface{}) ([]byte, error) {\n\terr := obj.DetachedVerify(obj.payload, verificationKey)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn obj.payload, nil\n}\n\n// UnsafePayloadWithoutVerification returns the payload without\n// verifying it. The content returned from this function cannot be\n// trusted.\nfunc (obj JSONWebSignature) UnsafePayloadWithoutVerification() []byte {\n\treturn obj.payload\n}\n\n// DetachedVerify validates a detached signature on the given payload. In\n// most cases, you will probably want to use Verify instead. DetachedVerify\n// is only useful if you have a payload and signature that are separated from\n// each other.\n//\n// The verificationKey argument must have one of the types allowed for the\n// verificationKey argument of JSONWebSignature.Verify().\nfunc (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey interface{}) error {\n\tkey, err := tryJWKS(verificationKey, obj.headers()...)\n\tif err != nil {\n\t\treturn err\n\t}\n\tverifier, err := newVerifier(key)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif len(obj.Signatures) > 1 {\n\t\treturn errors.New(\"go-jose/go-jose: too many signatures in payload; expecting only one\")\n\t}\n\n\tsignature := obj.Signatures[0]\n\n\tif signature.header != nil {\n\t\t// Per https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.11,\n\t\t// 4.1.11. \"crit\" (Critical) Header Parameter\n\t\t// \"When used, this Header Parameter MUST be integrity\n\t\t// protected; therefore, it MUST occur only within the JWS\n\t\t// Protected Header.\"\n\t\terr = signature.header.checkNoCritical()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif signature.protected != nil {\n\t\terr = signature.protected.checkSupportedCritical(supportedCritical)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tinput, err := obj.computeAuthData(payload, &signature)\n\tif err != nil {\n\t\treturn ErrCryptoFailure\n\t}\n\n\theaders := signature.mergedHeaders()\n\talg := headers.getSignatureAlgorithm()\n\terr = verifier.verifyPayload(input, signature.Signature, alg)\n\tif err == nil {\n\t\treturn nil\n\t}\n\n\treturn ErrCryptoFailure\n}\n\n// VerifyMulti validates (one of the multiple) signatures on the object and\n// returns the index of the signature that was verified, along with the signature\n// object and the payload. We return the signature and index to guarantee that\n// callers are getting the verified value.\n//\n// The verificationKey argument must have one of the types allowed for the\n// verificationKey argument of JSONWebSignature.Verify().\nfunc (obj JSONWebSignature) VerifyMulti(verificationKey interface{}) (int, Signature, []byte, error) {\n\tidx, sig, err := obj.DetachedVerifyMulti(obj.payload, verificationKey)\n\tif err != nil {\n\t\treturn -1, Signature{}, nil, err\n\t}\n\treturn idx, sig, obj.payload, nil\n}\n\n// DetachedVerifyMulti validates a detached signature on the given payload with\n// a signature/object that has potentially multiple signers. This returns the index\n// of the signature that was verified, along with the signature object. We return\n// the signature and index to guarantee that callers are getting the verified value.\n//\n// In most cases, you will probably want to use Verify or VerifyMulti instead.\n// DetachedVerifyMulti is only useful if you have a payload and signature that are\n// separated from each other, and the signature can have multiple signers at the\n// same time.\n//\n// The verificationKey argument must have one of the types allowed for the\n// verificationKey argument of JSONWebSignature.Verify().\nfunc (obj JSONWebSignature) DetachedVerifyMulti(payload []byte, verificationKey interface{}) (int, Signature, error) {\n\tkey, err := tryJWKS(verificationKey, obj.headers()...)\n\tif err != nil {\n\t\treturn -1, Signature{}, err\n\t}\n\tverifier, err := newVerifier(key)\n\tif err != nil {\n\t\treturn -1, Signature{}, err\n\t}\n\nouter:\n\tfor i, signature := range obj.Signatures {\n\t\tif signature.header != nil {\n\t\t\t// Per https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.11,\n\t\t\t// 4.1.11. \"crit\" (Critical) Header Parameter\n\t\t\t// \"When used, this Header Parameter MUST be integrity\n\t\t\t// protected; therefore, it MUST occur only within the JWS\n\t\t\t// Protected Header.\"\n\t\t\terr = signature.header.checkNoCritical()\n\t\t\tif err != nil {\n\t\t\t\tcontinue outer\n\t\t\t}\n\t\t}\n\n\t\tif signature.protected != nil {\n\t\t\t// Check for only supported critical headers\n\t\t\terr = signature.protected.checkSupportedCritical(supportedCritical)\n\t\t\tif err != nil {\n\t\t\t\tcontinue outer\n\t\t\t}\n\t\t}\n\n\t\tinput, err := obj.computeAuthData(payload, &signature)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\theaders := signature.mergedHeaders()\n\t\talg := headers.getSignatureAlgorithm()\n\t\terr = verifier.verifyPayload(input, signature.Signature, alg)\n\t\tif err == nil {\n\t\t\treturn i, signature, nil\n\t\t}\n\t}\n\n\treturn -1, Signature{}, ErrCryptoFailure\n}\n\nfunc (obj JSONWebSignature) headers() []Header {\n\theaders := make([]Header, len(obj.Signatures))\n\tfor i, sig := range obj.Signatures {\n\t\theaders[i] = sig.Header\n\t}\n\treturn headers\n}\n"
  },
  {
    "path": "vendor/github.com/go-jose/go-jose/v4/symmetric.go",
    "content": "/*-\n * Copyright 2014 Square Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage jose\n\nimport (\n\t\"bytes\"\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/hmac\"\n\t\"crypto/pbkdf2\"\n\t\"crypto/rand\"\n\t\"crypto/sha256\"\n\t\"crypto/sha512\"\n\t\"crypto/subtle\"\n\t\"errors\"\n\t\"fmt\"\n\t\"hash\"\n\t\"io\"\n\n\tjosecipher \"github.com/go-jose/go-jose/v4/cipher\"\n)\n\n// RandReader is a cryptographically secure random number generator (stubbed out in tests).\nvar RandReader = rand.Reader\n\nconst (\n\t// RFC7518 recommends a minimum of 1,000 iterations:\n\t// \t- https://tools.ietf.org/html/rfc7518#section-4.8.1.2\n\t//\n\t// NIST recommends a minimum of 10,000:\n\t// \t- https://pages.nist.gov/800-63-3/sp800-63b.html\n\t//\n\t// 1Password increased in 2023 from 100,000 to 650,000:\n\t//  - https://support.1password.com/pbkdf2/\n\t//\n\t// OWASP recommended 600,000 in Dec 2022:\n\t//\t- https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#pbkdf2\n\tdefaultP2C = 600000\n\t// Default salt size: 128 bits\n\tdefaultP2SSize = 16\n)\n\n// Dummy key cipher for shared symmetric key mode\ntype symmetricKeyCipher struct {\n\tkey []byte // Pre-shared content-encryption key\n\tp2c int    // PBES2 Count\n\tp2s []byte // PBES2 Salt Input\n}\n\n// Signer/verifier for MAC modes\ntype symmetricMac struct {\n\tkey []byte\n}\n\n// Input/output from an AEAD operation\ntype aeadParts struct {\n\tiv, ciphertext, tag []byte\n}\n\n// A content cipher based on an AEAD construction\ntype aeadContentCipher struct {\n\tkeyBytes     int\n\tauthtagBytes int\n\tgetAead      func(key []byte) (cipher.AEAD, error)\n}\n\n// Random key generator\ntype randomKeyGenerator struct {\n\tsize int\n}\n\n// Static key generator\ntype staticKeyGenerator struct {\n\tkey []byte\n}\n\n// Create a new content cipher based on AES-GCM\nfunc newAESGCM(keySize int) contentCipher {\n\treturn &aeadContentCipher{\n\t\tkeyBytes:     keySize,\n\t\tauthtagBytes: 16,\n\t\tgetAead: func(key []byte) (cipher.AEAD, error) {\n\t\t\taes, err := aes.NewCipher(key)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\treturn cipher.NewGCM(aes)\n\t\t},\n\t}\n}\n\n// Create a new content cipher based on AES-CBC+HMAC\nfunc newAESCBC(keySize int) contentCipher {\n\treturn &aeadContentCipher{\n\t\tkeyBytes:     keySize * 2,\n\t\tauthtagBytes: keySize,\n\t\tgetAead: func(key []byte) (cipher.AEAD, error) {\n\t\t\treturn josecipher.NewCBCHMAC(key, aes.NewCipher)\n\t\t},\n\t}\n}\n\n// Get an AEAD cipher object for the given content encryption algorithm\nfunc getContentCipher(alg ContentEncryption) contentCipher {\n\tswitch alg {\n\tcase A128GCM:\n\t\treturn newAESGCM(16)\n\tcase A192GCM:\n\t\treturn newAESGCM(24)\n\tcase A256GCM:\n\t\treturn newAESGCM(32)\n\tcase A128CBC_HS256:\n\t\treturn newAESCBC(16)\n\tcase A192CBC_HS384:\n\t\treturn newAESCBC(24)\n\tcase A256CBC_HS512:\n\t\treturn newAESCBC(32)\n\tdefault:\n\t\treturn nil\n\t}\n}\n\n// getPbkdf2Params returns the key length and hash function used in\n// pbkdf2.Key.\nfunc getPbkdf2Params(alg KeyAlgorithm) (int, func() hash.Hash) {\n\tswitch alg {\n\tcase PBES2_HS256_A128KW:\n\t\treturn 16, sha256.New\n\tcase PBES2_HS384_A192KW:\n\t\treturn 24, sha512.New384\n\tcase PBES2_HS512_A256KW:\n\t\treturn 32, sha512.New\n\tdefault:\n\t\tpanic(\"invalid algorithm\")\n\t}\n}\n\n// getRandomSalt generates a new salt of the given size.\nfunc getRandomSalt(size int) ([]byte, error) {\n\tsalt := make([]byte, size)\n\t_, err := io.ReadFull(RandReader, salt)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn salt, nil\n}\n\n// newSymmetricRecipient creates a JWE encrypter based on AES-GCM key wrap.\nfunc newSymmetricRecipient(keyAlg KeyAlgorithm, key []byte) (recipientKeyInfo, error) {\n\tswitch keyAlg {\n\tcase DIRECT, A128GCMKW, A192GCMKW, A256GCMKW, A128KW, A192KW, A256KW:\n\tcase PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW:\n\tdefault:\n\t\treturn recipientKeyInfo{}, ErrUnsupportedAlgorithm\n\t}\n\n\treturn recipientKeyInfo{\n\t\tkeyAlg: keyAlg,\n\t\tkeyEncrypter: &symmetricKeyCipher{\n\t\t\tkey: key,\n\t\t},\n\t}, nil\n}\n\n// newSymmetricSigner creates a recipientSigInfo based on the given key.\nfunc newSymmetricSigner(sigAlg SignatureAlgorithm, key []byte) (recipientSigInfo, error) {\n\t// Verify that key management algorithm is supported by this encrypter\n\tswitch sigAlg {\n\tcase HS256, HS384, HS512:\n\tdefault:\n\t\treturn recipientSigInfo{}, ErrUnsupportedAlgorithm\n\t}\n\n\treturn recipientSigInfo{\n\t\tsigAlg: sigAlg,\n\t\tsigner: &symmetricMac{\n\t\t\tkey: key,\n\t\t},\n\t}, nil\n}\n\n// Generate a random key for the given content cipher\nfunc (ctx randomKeyGenerator) genKey() ([]byte, rawHeader, error) {\n\tkey := make([]byte, ctx.size)\n\t_, err := io.ReadFull(RandReader, key)\n\tif err != nil {\n\t\treturn nil, rawHeader{}, err\n\t}\n\n\treturn key, rawHeader{}, nil\n}\n\n// Key size for random generator\nfunc (ctx randomKeyGenerator) keySize() int {\n\treturn ctx.size\n}\n\n// Generate a static key (for direct mode)\nfunc (ctx staticKeyGenerator) genKey() ([]byte, rawHeader, error) {\n\tcek := make([]byte, len(ctx.key))\n\tcopy(cek, ctx.key)\n\treturn cek, rawHeader{}, nil\n}\n\n// Key size for static generator\nfunc (ctx staticKeyGenerator) keySize() int {\n\treturn len(ctx.key)\n}\n\n// Get key size for this cipher\nfunc (ctx aeadContentCipher) keySize() int {\n\treturn ctx.keyBytes\n}\n\n// Encrypt some data\nfunc (ctx aeadContentCipher) encrypt(key, aad, pt []byte) (*aeadParts, error) {\n\t// Get a new AEAD instance\n\taead, err := ctx.getAead(key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Initialize a new nonce\n\tiv := make([]byte, aead.NonceSize())\n\t_, err = io.ReadFull(RandReader, iv)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tciphertextAndTag := aead.Seal(nil, iv, pt, aad)\n\toffset := len(ciphertextAndTag) - ctx.authtagBytes\n\n\treturn &aeadParts{\n\t\tiv:         iv,\n\t\tciphertext: ciphertextAndTag[:offset],\n\t\ttag:        ciphertextAndTag[offset:],\n\t}, nil\n}\n\n// Decrypt some data\nfunc (ctx aeadContentCipher) decrypt(key, aad []byte, parts *aeadParts) ([]byte, error) {\n\taead, err := ctx.getAead(key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif len(parts.iv) != aead.NonceSize() || len(parts.tag) < ctx.authtagBytes {\n\t\treturn nil, ErrCryptoFailure\n\t}\n\n\treturn aead.Open(nil, parts.iv, append(parts.ciphertext, parts.tag...), aad)\n}\n\n// Encrypt the content encryption key.\nfunc (ctx *symmetricKeyCipher) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {\n\tswitch alg {\n\tcase DIRECT:\n\t\treturn recipientInfo{\n\t\t\theader: &rawHeader{},\n\t\t}, nil\n\tcase A128GCMKW, A192GCMKW, A256GCMKW:\n\t\taead := newAESGCM(len(ctx.key))\n\n\t\tparts, err := aead.encrypt(ctx.key, []byte{}, cek)\n\t\tif err != nil {\n\t\t\treturn recipientInfo{}, err\n\t\t}\n\n\t\theader := &rawHeader{}\n\n\t\tif err = header.set(headerIV, newBuffer(parts.iv)); err != nil {\n\t\t\treturn recipientInfo{}, err\n\t\t}\n\n\t\tif err = header.set(headerTag, newBuffer(parts.tag)); err != nil {\n\t\t\treturn recipientInfo{}, err\n\t\t}\n\n\t\treturn recipientInfo{\n\t\t\theader:       header,\n\t\t\tencryptedKey: parts.ciphertext,\n\t\t}, nil\n\tcase A128KW, A192KW, A256KW:\n\t\tblock, err := aes.NewCipher(ctx.key)\n\t\tif err != nil {\n\t\t\treturn recipientInfo{}, err\n\t\t}\n\n\t\tjek, err := josecipher.KeyWrap(block, cek)\n\t\tif err != nil {\n\t\t\treturn recipientInfo{}, err\n\t\t}\n\n\t\treturn recipientInfo{\n\t\t\tencryptedKey: jek,\n\t\t\theader:       &rawHeader{},\n\t\t}, nil\n\tcase PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW:\n\t\tif len(ctx.p2s) == 0 {\n\t\t\tsalt, err := getRandomSalt(defaultP2SSize)\n\t\t\tif err != nil {\n\t\t\t\treturn recipientInfo{}, err\n\t\t\t}\n\t\t\tctx.p2s = salt\n\t\t}\n\n\t\tif ctx.p2c <= 0 {\n\t\t\tctx.p2c = defaultP2C\n\t\t}\n\n\t\t// salt is UTF8(Alg) || 0x00 || Salt Input\n\t\tsalt := bytes.Join([][]byte{[]byte(alg), ctx.p2s}, []byte{0x00})\n\n\t\t// derive key\n\t\tkeyLen, h := getPbkdf2Params(alg)\n\t\tkey, err := pbkdf2.Key(h, string(ctx.key), salt, ctx.p2c, keyLen)\n\t\tif err != nil {\n\t\t\treturn recipientInfo{}, nil\n\t\t}\n\n\t\t// use AES cipher with derived key\n\t\tblock, err := aes.NewCipher(key)\n\t\tif err != nil {\n\t\t\treturn recipientInfo{}, err\n\t\t}\n\n\t\tjek, err := josecipher.KeyWrap(block, cek)\n\t\tif err != nil {\n\t\t\treturn recipientInfo{}, err\n\t\t}\n\n\t\theader := &rawHeader{}\n\n\t\tif err = header.set(headerP2C, ctx.p2c); err != nil {\n\t\t\treturn recipientInfo{}, err\n\t\t}\n\n\t\tif err = header.set(headerP2S, newBuffer(ctx.p2s)); err != nil {\n\t\t\treturn recipientInfo{}, err\n\t\t}\n\n\t\treturn recipientInfo{\n\t\t\tencryptedKey: jek,\n\t\t\theader:       header,\n\t\t}, nil\n\t}\n\n\treturn recipientInfo{}, ErrUnsupportedAlgorithm\n}\n\n// Decrypt the content encryption key.\nfunc (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {\n\tswitch headers.getAlgorithm() {\n\tcase DIRECT:\n\t\tcek := make([]byte, len(ctx.key))\n\t\tcopy(cek, ctx.key)\n\t\treturn cek, nil\n\tcase A128GCMKW, A192GCMKW, A256GCMKW:\n\t\taead := newAESGCM(len(ctx.key))\n\n\t\tiv, err := headers.getIV()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid IV: %v\", err)\n\t\t}\n\t\ttag, err := headers.getTag()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid tag: %v\", err)\n\t\t}\n\n\t\tparts := &aeadParts{\n\t\t\tiv:         iv.bytes(),\n\t\t\tciphertext: recipient.encryptedKey,\n\t\t\ttag:        tag.bytes(),\n\t\t}\n\n\t\tcek, err := aead.decrypt(ctx.key, []byte{}, parts)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\treturn cek, nil\n\tcase A128KW, A192KW, A256KW:\n\t\tblock, err := aes.NewCipher(ctx.key)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tcek, err := josecipher.KeyUnwrap(block, recipient.encryptedKey)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn cek, nil\n\tcase PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW:\n\t\tp2s, err := headers.getP2S()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid P2S: %v\", err)\n\t\t}\n\t\tif p2s == nil || len(p2s.data) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid P2S: must be present\")\n\t\t}\n\n\t\tp2c, err := headers.getP2C()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid P2C: %v\", err)\n\t\t}\n\t\tif p2c <= 0 {\n\t\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid P2C: must be a positive integer\")\n\t\t}\n\t\tif p2c > 1000000 {\n\t\t\t// An unauthenticated attacker can set a high P2C value. Set an upper limit to avoid\n\t\t\t// DoS attacks.\n\t\t\treturn nil, fmt.Errorf(\"go-jose/go-jose: invalid P2C: too high\")\n\t\t}\n\n\t\t// salt is UTF8(Alg) || 0x00 || Salt Input\n\t\talg := headers.getAlgorithm()\n\t\tsalt := bytes.Join([][]byte{[]byte(alg), p2s.bytes()}, []byte{0x00})\n\n\t\t// derive key\n\t\tkeyLen, h := getPbkdf2Params(alg)\n\t\tkey, err := pbkdf2.Key(h, string(ctx.key), salt, p2c, keyLen)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\t// use AES cipher with derived key\n\t\tblock, err := aes.NewCipher(key)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tcek, err := josecipher.KeyUnwrap(block, recipient.encryptedKey)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn cek, nil\n\t}\n\n\treturn nil, ErrUnsupportedAlgorithm\n}\n\n// Sign the given payload\nfunc (ctx symmetricMac) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {\n\tmac, err := ctx.hmac(payload, alg)\n\tif err != nil {\n\t\treturn Signature{}, err\n\t}\n\n\treturn Signature{\n\t\tSignature: mac,\n\t\tprotected: &rawHeader{},\n\t}, nil\n}\n\n// Verify the given payload\nfunc (ctx symmetricMac) verifyPayload(payload []byte, mac []byte, alg SignatureAlgorithm) error {\n\texpected, err := ctx.hmac(payload, alg)\n\tif err != nil {\n\t\treturn errors.New(\"go-jose/go-jose: failed to compute hmac\")\n\t}\n\n\tif len(mac) != len(expected) {\n\t\treturn errors.New(\"go-jose/go-jose: invalid hmac\")\n\t}\n\n\tmatch := subtle.ConstantTimeCompare(mac, expected)\n\tif match != 1 {\n\t\treturn errors.New(\"go-jose/go-jose: invalid hmac\")\n\t}\n\n\treturn nil\n}\n\n// Compute the HMAC based on the given alg value\nfunc (ctx symmetricMac) hmac(payload []byte, alg SignatureAlgorithm) ([]byte, error) {\n\tvar hash func() hash.Hash\n\n\t// https://datatracker.ietf.org/doc/html/rfc7518#section-3.2\n\t// A key of the same size as the hash output (for instance, 256 bits for\n\t// \"HS256\") or larger MUST be used\n\tswitch alg {\n\tcase HS256:\n\t\tif len(ctx.key)*8 < 256 {\n\t\t\treturn nil, ErrInvalidKeySize\n\t\t}\n\t\thash = sha256.New\n\tcase HS384:\n\t\tif len(ctx.key)*8 < 384 {\n\t\t\treturn nil, ErrInvalidKeySize\n\t\t}\n\t\thash = sha512.New384\n\tcase HS512:\n\t\tif len(ctx.key)*8 < 512 {\n\t\t\treturn nil, ErrInvalidKeySize\n\t\t}\n\t\thash = sha512.New\n\tdefault:\n\t\treturn nil, ErrUnsupportedAlgorithm\n\t}\n\n\thmac := hmac.New(hash, ctx.key)\n\n\t// According to documentation, Write() on hash never fails\n\t_, _ = hmac.Write(payload)\n\treturn hmac.Sum(nil), nil\n}\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/.golangci.yaml",
    "content": "version: \"2\"\n\nrun:\n  timeout: 1m\n  tests: true\n\nlinters:\n  default: none\n  enable: # please keep this alphabetized\n    - asasalint\n    - asciicheck\n    - copyloopvar\n    - dupl\n    - errcheck\n    - forcetypeassert\n    - goconst\n    - gocritic\n    - govet\n    - ineffassign\n    - misspell\n    - musttag\n    - revive\n    - staticcheck\n    - unused\n\nissues:\n  max-issues-per-linter: 0\n  max-same-issues: 10\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/CHANGELOG.md",
    "content": "# CHANGELOG\n\n## v1.0.0-rc1\n\nThis is the first logged release.  Major changes (including breaking changes)\nhave occurred since earlier tags.\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/CONTRIBUTING.md",
    "content": "# Contributing\n\nLogr is open to pull-requests, provided they fit within the intended scope of\nthe project.  Specifically, this library aims to be VERY small and minimalist,\nwith no external dependencies.\n\n## Compatibility\n\nThis project intends to follow [semantic versioning](http://semver.org) and\nis very strict about compatibility.  Any proposed changes MUST follow those\nrules.\n\n## Performance\n\nAs a logging library, logr must be as light-weight as possible.  Any proposed\ncode change must include results of running the [benchmark](./benchmark)\nbefore and after the change.\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/README.md",
    "content": "# A minimal logging API for Go\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/logr.svg)](https://pkg.go.dev/github.com/go-logr/logr)\n[![Go Report Card](https://goreportcard.com/badge/github.com/go-logr/logr)](https://goreportcard.com/report/github.com/go-logr/logr)\n[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/go-logr/logr/badge)](https://securityscorecards.dev/viewer/?platform=github.com&org=go-logr&repo=logr)\n\nlogr offers an(other) opinion on how Go programs and libraries can do logging\nwithout becoming coupled to a particular logging implementation.  This is not\nan implementation of logging - it is an API.  In fact it is two APIs with two\ndifferent sets of users.\n\nThe `Logger` type is intended for application and library authors.  It provides\na relatively small API which can be used everywhere you want to emit logs.  It\ndefers the actual act of writing logs (to files, to stdout, or whatever) to the\n`LogSink` interface.\n\nThe `LogSink` interface is intended for logging library implementers.  It is a\npure interface which can be implemented by logging frameworks to provide the actual logging\nfunctionality.\n\nThis decoupling allows application and library developers to write code in\nterms of `logr.Logger` (which has very low dependency fan-out) while the\nimplementation of logging is managed \"up stack\" (e.g. in or near `main()`.)\nApplication developers can then switch out implementations as necessary.\n\nMany people assert that libraries should not be logging, and as such efforts\nlike this are pointless.  Those people are welcome to convince the authors of\nthe tens-of-thousands of libraries that *DO* write logs that they are all\nwrong.  In the meantime, logr takes a more practical approach.\n\n## Typical usage\n\nSomewhere, early in an application's life, it will make a decision about which\nlogging library (implementation) it actually wants to use.  Something like:\n\n```\n    func main() {\n        // ... other setup code ...\n\n        // Create the \"root\" logger.  We have chosen the \"logimpl\" implementation,\n        // which takes some initial parameters and returns a logr.Logger.\n        logger := logimpl.New(param1, param2)\n\n        // ... other setup code ...\n```\n\nMost apps will call into other libraries, create structures to govern the flow,\netc.  The `logr.Logger` object can be passed to these other libraries, stored\nin structs, or even used as a package-global variable, if needed.  For example:\n\n```\n    app := createTheAppObject(logger)\n    app.Run()\n```\n\nOutside of this early setup, no other packages need to know about the choice of\nimplementation.  They write logs in terms of the `logr.Logger` that they\nreceived:\n\n```\n    type appObject struct {\n        // ... other fields ...\n        logger logr.Logger\n        // ... other fields ...\n    }\n\n    func (app *appObject) Run() {\n        app.logger.Info(\"starting up\", \"timestamp\", time.Now())\n\n        // ... app code ...\n```\n\n## Background\n\nIf the Go standard library had defined an interface for logging, this project\nprobably would not be needed.  Alas, here we are.\n\nWhen the Go developers started developing such an interface with\n[slog](https://github.com/golang/go/issues/56345), they adopted some of the\nlogr design but also left out some parts and changed others:\n\n| Feature | logr | slog |\n|---------|------|------|\n| High-level API | `Logger` (passed by value) | `Logger` (passed by [pointer](https://github.com/golang/go/issues/59126)) |\n| Low-level API | `LogSink` | `Handler` |\n| Stack unwinding | done by `LogSink` | done by `Logger` |\n| Skipping helper functions | `WithCallDepth`, `WithCallStackHelper` | [not supported by Logger](https://github.com/golang/go/issues/59145) |\n| Generating a value for logging on demand | `Marshaler` | `LogValuer` |\n| Log levels | >= 0, higher meaning \"less important\" | positive and negative, with 0 for \"info\" and higher meaning \"more important\" |\n| Error log entries | always logged, don't have a verbosity level | normal log entries with level >= `LevelError` |\n| Passing logger via context | `NewContext`, `FromContext` | no API |\n| Adding a name to a logger | `WithName` | no API |\n| Modify verbosity of log entries in a call chain | `V` | no API |\n| Grouping of key/value pairs | not supported | `WithGroup`, `GroupValue` |\n| Pass context for extracting additional values | no API | API variants like `InfoCtx` |\n\nThe high-level slog API is explicitly meant to be one of many different APIs\nthat can be layered on top of a shared `slog.Handler`. logr is one such\nalternative API, with [interoperability](#slog-interoperability) provided by\nsome conversion functions.\n\n### Inspiration\n\nBefore you consider this package, please read [this blog post by the\ninimitable Dave Cheney][warning-makes-no-sense].  We really appreciate what\nhe has to say, and it largely aligns with our own experiences.\n\n### Differences from Dave's ideas\n\nThe main differences are:\n\n1. Dave basically proposes doing away with the notion of a logging API in favor\nof `fmt.Printf()`.  We disagree, especially when you consider things like output\nlocations, timestamps, file and line decorations, and structured logging.  This\npackage restricts the logging API to just 2 types of logs: info and error.\n\nInfo logs are things you want to tell the user which are not errors.  Error\nlogs are, well, errors.  If your code receives an `error` from a subordinate\nfunction call and is logging that `error` *and not returning it*, use error\nlogs.\n\n2. Verbosity-levels on info logs.  This gives developers a chance to indicate\narbitrary grades of importance for info logs, without assigning names with\nsemantic meaning such as \"warning\", \"trace\", and \"debug.\"  Superficially this\nmay feel very similar, but the primary difference is the lack of semantics.\nBecause verbosity is a numerical value, it's safe to assume that an app running\nwith higher verbosity means more (and less important) logs will be generated.\n\n## Implementations (non-exhaustive)\n\nThere are implementations for the following logging libraries:\n\n- **a function** (can bridge to non-structured libraries): [funcr](https://github.com/go-logr/logr/tree/master/funcr)\n- **a testing.T** (for use in Go tests, with JSON-like output): [testr](https://github.com/go-logr/logr/tree/master/testr)\n- **github.com/google/glog**: [glogr](https://github.com/go-logr/glogr)\n- **k8s.io/klog** (for Kubernetes): [klogr](https://git.k8s.io/klog/klogr)\n- **a testing.T** (with klog-like text output): [ktesting](https://git.k8s.io/klog/ktesting)\n- **go.uber.org/zap**: [zapr](https://github.com/go-logr/zapr)\n- **log** (the Go standard library logger): [stdr](https://github.com/go-logr/stdr)\n- **github.com/sirupsen/logrus**: [logrusr](https://github.com/bombsimon/logrusr)\n- **github.com/wojas/genericr**: [genericr](https://github.com/wojas/genericr) (makes it easy to implement your own backend)\n- **logfmt** (Heroku style [logging](https://www.brandur.org/logfmt)): [logfmtr](https://github.com/iand/logfmtr)\n- **github.com/rs/zerolog**: [zerologr](https://github.com/go-logr/zerologr)\n- **github.com/go-kit/log**: [gokitlogr](https://github.com/tonglil/gokitlogr) (also compatible with github.com/go-kit/kit/log since v0.12.0)\n- **bytes.Buffer** (writing to a buffer): [bufrlogr](https://github.com/tonglil/buflogr) (useful for ensuring values were logged, like during testing)\n\n## slog interoperability\n\nInteroperability goes both ways, using the `logr.Logger` API with a `slog.Handler`\nand using the `slog.Logger` API with a `logr.LogSink`. `FromSlogHandler` and\n`ToSlogHandler` convert between a `logr.Logger` and a `slog.Handler`.\nAs usual, `slog.New` can be used to wrap such a `slog.Handler` in the high-level\nslog API.\n\n### Using a `logr.LogSink` as backend for slog\n\nIdeally, a logr sink implementation should support both logr and slog by\nimplementing both the normal logr interface(s) and `SlogSink`.  Because\nof a conflict in the parameters of the common `Enabled` method, it is [not\npossible to implement both slog.Handler and logr.Sink in the same\ntype](https://github.com/golang/go/issues/59110).\n\nIf both are supported, log calls can go from the high-level APIs to the backend\nwithout the need to convert parameters. `FromSlogHandler` and `ToSlogHandler` can\nconvert back and forth without adding additional wrappers, with one exception:\nwhen `Logger.V` was used to adjust the verbosity for a `slog.Handler`, then\n`ToSlogHandler` has to use a wrapper which adjusts the verbosity for future\nlog calls.\n\nSuch an implementation should also support values that implement specific\ninterfaces from both packages for logging (`logr.Marshaler`, `slog.LogValuer`,\n`slog.GroupValue`). logr does not convert those.\n\nNot supporting slog has several drawbacks:\n- Recording source code locations works correctly if the handler gets called\n  through `slog.Logger`, but may be wrong in other cases. That's because a\n  `logr.Sink` does its own stack unwinding instead of using the program counter\n  provided by the high-level API.\n- slog levels <= 0 can be mapped to logr levels by negating the level without a\n  loss of information. But all slog levels > 0 (e.g. `slog.LevelWarning` as\n  used by `slog.Logger.Warn`) must be mapped to 0 before calling the sink\n  because logr does not support \"more important than info\" levels.\n- The slog group concept is supported by prefixing each key in a key/value\n  pair with the group names, separated by a dot. For structured output like\n  JSON it would be better to group the key/value pairs inside an object.\n- Special slog values and interfaces don't work as expected.\n- The overhead is likely to be higher.\n\nThese drawbacks are severe enough that applications using a mixture of slog and\nlogr should switch to a different backend.\n\n### Using a `slog.Handler` as backend for logr\n\nUsing a plain `slog.Handler` without support for logr works better than the\nother direction:\n- All logr verbosity levels can be mapped 1:1 to their corresponding slog level\n  by negating them.\n- Stack unwinding is done by the `SlogSink` and the resulting program\n  counter is passed to the `slog.Handler`.\n- Names added via `Logger.WithName` are gathered and recorded in an additional\n  attribute with `logger` as key and the names separated by slash as value.\n- `Logger.Error` is turned into a log record with `slog.LevelError` as level\n  and an additional attribute with `err` as key, if an error was provided.\n\nThe main drawback is that `logr.Marshaler` will not be supported. Types should\nideally support both `logr.Marshaler` and `slog.Valuer`. If compatibility\nwith logr implementations without slog support is not important, then\n`slog.Valuer` is sufficient.\n\n### Context support for slog\n\nStoring a logger in a `context.Context` is not supported by\nslog. `NewContextWithSlogLogger` and `FromContextAsSlogLogger` can be\nused to fill this gap. They store and retrieve a `slog.Logger` pointer\nunder the same context key that is also used by `NewContext` and\n`FromContext` for `logr.Logger` value.\n\nWhen `NewContextWithSlogLogger` is followed by `FromContext`, the latter will\nautomatically convert the `slog.Logger` to a\n`logr.Logger`. `FromContextAsSlogLogger` does the same for the other direction.\n\nWith this approach, binaries which use either slog or logr are as efficient as\npossible with no unnecessary allocations. This is also why the API stores a\n`slog.Logger` pointer: when storing a `slog.Handler`, creating a `slog.Logger`\non retrieval would need to allocate one.\n\nThe downside is that switching back and forth needs more allocations. Because\nlogr is the API that is already in use by different packages, in particular\nKubernetes, the recommendation is to use the `logr.Logger` API in code which\nuses contextual logging.\n\nAn alternative to adding values to a logger and storing that logger in the\ncontext is to store the values in the context and to configure a logging\nbackend to extract those values when emitting log entries. This only works when\nlog calls are passed the context, which is not supported by the logr API.\n\nWith the slog API, it is possible, but not\nrequired. https://github.com/veqryn/slog-context is a package for slog which\nprovides additional support code for this approach. It also contains wrappers\nfor the context functions in logr, so developers who prefer to not use the logr\nAPIs directly can use those instead and the resulting code will still be\ninteroperable with logr.\n\n## FAQ\n\n### Conceptual\n\n#### Why structured logging?\n\n- **Structured logs are more easily queryable**: Since you've got\n  key-value pairs, it's much easier to query your structured logs for\n  particular values by filtering on the contents of a particular key --\n  think searching request logs for error codes, Kubernetes reconcilers for\n  the name and namespace of the reconciled object, etc.\n\n- **Structured logging makes it easier to have cross-referenceable logs**:\n  Similarly to searchability, if you maintain conventions around your\n  keys, it becomes easy to gather all log lines related to a particular\n  concept.\n\n- **Structured logs allow better dimensions of filtering**: if you have\n  structure to your logs, you've got more precise control over how much\n  information is logged -- you might choose in a particular configuration\n  to log certain keys but not others, only log lines where a certain key\n  matches a certain value, etc., instead of just having v-levels and names\n  to key off of.\n\n- **Structured logs better represent structured data**: sometimes, the\n  data that you want to log is inherently structured (think tuple-link\n  objects.)  Structured logs allow you to preserve that structure when\n  outputting.\n\n#### Why V-levels?\n\n**V-levels give operators an easy way to control the chattiness of log\noperations**.  V-levels provide a way for a given package to distinguish\nthe relative importance or verbosity of a given log message.  Then, if\na particular logger or package is logging too many messages, the user\nof the package can simply change the v-levels for that library.\n\n#### Why not named levels, like Info/Warning/Error?\n\nRead [Dave Cheney's post][warning-makes-no-sense].  Then read [Differences\nfrom Dave's ideas](#differences-from-daves-ideas).\n\n#### Why not allow format strings, too?\n\n**Format strings negate many of the benefits of structured logs**:\n\n- They're not easily searchable without resorting to fuzzy searching,\n  regular expressions, etc.\n\n- They don't store structured data well, since contents are flattened into\n  a string.\n\n- They're not cross-referenceable.\n\n- They don't compress easily, since the message is not constant.\n\n(Unless you turn positional parameters into key-value pairs with numerical\nkeys, at which point you've gotten key-value logging with meaningless\nkeys.)\n\n### Practical\n\n#### Why key-value pairs, and not a map?\n\nKey-value pairs are *much* easier to optimize, especially around\nallocations.  Zap (a structured logger that inspired logr's interface) has\n[performance measurements](https://github.com/uber-go/zap#performance)\nthat show this quite nicely.\n\nWhile the interface ends up being a little less obvious, you get\npotentially better performance, plus avoid making users type\n`map[string]string{}` every time they want to log.\n\n#### What if my V-levels differ between libraries?\n\nThat's fine.  Control your V-levels on a per-logger basis, and use the\n`WithName` method to pass different loggers to different libraries.\n\nGenerally, you should take care to ensure that you have relatively\nconsistent V-levels within a given logger, however, as this makes deciding\non what verbosity of logs to request easier.\n\n#### But I really want to use a format string!\n\nThat's not actually a question.  Assuming your question is \"how do\nI convert my mental model of logging with format strings to logging with\nconstant messages\":\n\n1. Figure out what the error actually is, as you'd write in a TL;DR style,\n   and use that as a message.\n\n2. For every place you'd write a format specifier, look to the word before\n   it, and add that as a key value pair.\n\nFor instance, consider the following examples (all taken from spots in the\nKubernetes codebase):\n\n- `klog.V(4).Infof(\"Client is returning errors: code %v, error %v\",\n  responseCode, err)` becomes `logger.Error(err, \"client returned an\n  error\", \"code\", responseCode)`\n\n- `klog.V(4).Infof(\"Got a Retry-After %ds response for attempt %d to %v\",\n  seconds, retries, url)` becomes `logger.V(4).Info(\"got a retry-after\n  response when requesting url\", \"attempt\", retries, \"after\n  seconds\", seconds, \"url\", url)`\n\nIf you *really* must use a format string, use it in a key's value, and\ncall `fmt.Sprintf` yourself.  For instance: `log.Printf(\"unable to\nreflect over type %T\")` becomes `logger.Info(\"unable to reflect over\ntype\", \"type\", fmt.Sprintf(\"%T\"))`.  In general though, the cases where\nthis is necessary should be few and far between.\n\n#### How do I choose my V-levels?\n\nThis is basically the only hard constraint: increase V-levels to denote\nmore verbose or more debug-y logs.\n\nOtherwise, you can start out with `0` as \"you always want to see this\",\n`1` as \"common logging that you might *possibly* want to turn off\", and\n`10` as \"I would like to performance-test your log collection stack.\"\n\nThen gradually choose levels in between as you need them, working your way\ndown from 10 (for debug and trace style logs) and up from 1 (for chattier\ninfo-type logs). For reference, slog pre-defines -4 for debug logs\n(corresponds to 4 in logr), which matches what is\n[recommended for Kubernetes](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md#what-method-to-use).\n\n#### How do I choose my keys?\n\nKeys are fairly flexible, and can hold more or less any string\nvalue. For best compatibility with implementations and consistency\nwith existing code in other projects, there are a few conventions you\nshould consider.\n\n- Make your keys human-readable.\n- Constant keys are generally a good idea.\n- Be consistent across your codebase.\n- Keys should naturally match parts of the message string.\n- Use lower case for simple keys and\n  [lowerCamelCase](https://en.wiktionary.org/wiki/lowerCamelCase) for\n  more complex ones. Kubernetes is one example of a project that has\n  [adopted that\n  convention](https://github.com/kubernetes/community/blob/HEAD/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments).\n\nWhile key names are mostly unrestricted (and spaces are acceptable),\nit's generally a good idea to stick to printable ascii characters, or at\nleast match the general character set of your log lines.\n\n#### Why should keys be constant values?\n\nThe point of structured logging is to make later log processing easier.  Your\nkeys are, effectively, the schema of each log message.  If you use different\nkeys across instances of the same log line, you will make your structured logs\nmuch harder to use.  `Sprintf()` is for values, not for keys!\n\n#### Why is this not a pure interface?\n\nThe Logger type is implemented as a struct in order to allow the Go compiler to\noptimize things like high-V `Info` logs that are not triggered.  Not all of\nthese implementations are implemented yet, but this structure was suggested as\na way to ensure they *can* be implemented.  All of the real work is behind the\n`LogSink` interface.\n\n[warning-makes-no-sense]: http://dave.cheney.net/2015/11/05/lets-talk-about-logging\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/SECURITY.md",
    "content": "# Security Policy\n\nIf you have discovered a security vulnerability in this project, please report it\nprivately. **Do not disclose it as a public issue.** This gives us time to work with you\nto fix the issue before public exposure, reducing the chance that the exploit will be\nused before a patch is released.\n\nYou may submit the report in the following ways:\n\n- send an email to go-logr-security@googlegroups.com\n- send us a [private vulnerability report](https://github.com/go-logr/logr/security/advisories/new)\n\nPlease provide the following information in your report:\n\n- A description of the vulnerability and its impact\n- How to reproduce the issue\n\nWe ask that you give us 90 days to work on a fix before public exposure.\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/context.go",
    "content": "/*\nCopyright 2023 The logr Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage logr\n\n// contextKey is how we find Loggers in a context.Context. With Go < 1.21,\n// the value is always a Logger value. With Go >= 1.21, the value can be a\n// Logger value or a slog.Logger pointer.\ntype contextKey struct{}\n\n// notFoundError exists to carry an IsNotFound method.\ntype notFoundError struct{}\n\nfunc (notFoundError) Error() string {\n\treturn \"no logr.Logger was present\"\n}\n\nfunc (notFoundError) IsNotFound() bool {\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/context_noslog.go",
    "content": "//go:build !go1.21\n// +build !go1.21\n\n/*\nCopyright 2019 The logr Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage logr\n\nimport (\n\t\"context\"\n)\n\n// FromContext returns a Logger from ctx or an error if no Logger is found.\nfunc FromContext(ctx context.Context) (Logger, error) {\n\tif v, ok := ctx.Value(contextKey{}).(Logger); ok {\n\t\treturn v, nil\n\t}\n\n\treturn Logger{}, notFoundError{}\n}\n\n// FromContextOrDiscard returns a Logger from ctx.  If no Logger is found, this\n// returns a Logger that discards all log messages.\nfunc FromContextOrDiscard(ctx context.Context) Logger {\n\tif v, ok := ctx.Value(contextKey{}).(Logger); ok {\n\t\treturn v\n\t}\n\n\treturn Discard()\n}\n\n// NewContext returns a new Context, derived from ctx, which carries the\n// provided Logger.\nfunc NewContext(ctx context.Context, logger Logger) context.Context {\n\treturn context.WithValue(ctx, contextKey{}, logger)\n}\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/context_slog.go",
    "content": "//go:build go1.21\n// +build go1.21\n\n/*\nCopyright 2019 The logr Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage logr\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log/slog\"\n)\n\n// FromContext returns a Logger from ctx or an error if no Logger is found.\nfunc FromContext(ctx context.Context) (Logger, error) {\n\tv := ctx.Value(contextKey{})\n\tif v == nil {\n\t\treturn Logger{}, notFoundError{}\n\t}\n\n\tswitch v := v.(type) {\n\tcase Logger:\n\t\treturn v, nil\n\tcase *slog.Logger:\n\t\treturn FromSlogHandler(v.Handler()), nil\n\tdefault:\n\t\t// Not reached.\n\t\tpanic(fmt.Sprintf(\"unexpected value type for logr context key: %T\", v))\n\t}\n}\n\n// FromContextAsSlogLogger returns a slog.Logger from ctx or nil if no such Logger is found.\nfunc FromContextAsSlogLogger(ctx context.Context) *slog.Logger {\n\tv := ctx.Value(contextKey{})\n\tif v == nil {\n\t\treturn nil\n\t}\n\n\tswitch v := v.(type) {\n\tcase Logger:\n\t\treturn slog.New(ToSlogHandler(v))\n\tcase *slog.Logger:\n\t\treturn v\n\tdefault:\n\t\t// Not reached.\n\t\tpanic(fmt.Sprintf(\"unexpected value type for logr context key: %T\", v))\n\t}\n}\n\n// FromContextOrDiscard returns a Logger from ctx.  If no Logger is found, this\n// returns a Logger that discards all log messages.\nfunc FromContextOrDiscard(ctx context.Context) Logger {\n\tif logger, err := FromContext(ctx); err == nil {\n\t\treturn logger\n\t}\n\treturn Discard()\n}\n\n// NewContext returns a new Context, derived from ctx, which carries the\n// provided Logger.\nfunc NewContext(ctx context.Context, logger Logger) context.Context {\n\treturn context.WithValue(ctx, contextKey{}, logger)\n}\n\n// NewContextWithSlogLogger returns a new Context, derived from ctx, which carries the\n// provided slog.Logger.\nfunc NewContextWithSlogLogger(ctx context.Context, logger *slog.Logger) context.Context {\n\treturn context.WithValue(ctx, contextKey{}, logger)\n}\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/discard.go",
    "content": "/*\nCopyright 2020 The logr Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage logr\n\n// Discard returns a Logger that discards all messages logged to it.  It can be\n// used whenever the caller is not interested in the logs.  Logger instances\n// produced by this function always compare as equal.\nfunc Discard() Logger {\n\treturn New(nil)\n}\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/funcr/funcr.go",
    "content": "/*\nCopyright 2021 The logr Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Package funcr implements formatting of structured log messages and\n// optionally captures the call site and timestamp.\n//\n// The simplest way to use it is via its implementation of a\n// github.com/go-logr/logr.LogSink with output through an arbitrary\n// \"write\" function.  See New and NewJSON for details.\n//\n// # Custom LogSinks\n//\n// For users who need more control, a funcr.Formatter can be embedded inside\n// your own custom LogSink implementation. This is useful when the LogSink\n// needs to implement additional methods, for example.\n//\n// # Formatting\n//\n// This will respect logr.Marshaler, fmt.Stringer, and error interfaces for\n// values which are being logged.  When rendering a struct, funcr will use Go's\n// standard JSON tags (all except \"string\").\npackage funcr\n\nimport (\n\t\"bytes\"\n\t\"encoding\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/go-logr/logr\"\n)\n\n// New returns a logr.Logger which is implemented by an arbitrary function.\nfunc New(fn func(prefix, args string), opts Options) logr.Logger {\n\treturn logr.New(newSink(fn, NewFormatter(opts)))\n}\n\n// NewJSON returns a logr.Logger which is implemented by an arbitrary function\n// and produces JSON output.\nfunc NewJSON(fn func(obj string), opts Options) logr.Logger {\n\tfnWrapper := func(_, obj string) {\n\t\tfn(obj)\n\t}\n\treturn logr.New(newSink(fnWrapper, NewFormatterJSON(opts)))\n}\n\n// Underlier exposes access to the underlying logging function. Since\n// callers only have a logr.Logger, they have to know which\n// implementation is in use, so this interface is less of an\n// abstraction and more of a way to test type conversion.\ntype Underlier interface {\n\tGetUnderlying() func(prefix, args string)\n}\n\nfunc newSink(fn func(prefix, args string), formatter Formatter) logr.LogSink {\n\tl := &fnlogger{\n\t\tFormatter: formatter,\n\t\twrite:     fn,\n\t}\n\t// For skipping fnlogger.Info and fnlogger.Error.\n\tl.AddCallDepth(1) // via Formatter\n\treturn l\n}\n\n// Options carries parameters which influence the way logs are generated.\ntype Options struct {\n\t// LogCaller tells funcr to add a \"caller\" key to some or all log lines.\n\t// This has some overhead, so some users might not want it.\n\tLogCaller MessageClass\n\n\t// LogCallerFunc tells funcr to also log the calling function name.  This\n\t// has no effect if caller logging is not enabled (see Options.LogCaller).\n\tLogCallerFunc bool\n\n\t// LogTimestamp tells funcr to add a \"ts\" key to log lines.  This has some\n\t// overhead, so some users might not want it.\n\tLogTimestamp bool\n\n\t// TimestampFormat tells funcr how to render timestamps when LogTimestamp\n\t// is enabled.  If not specified, a default format will be used.  For more\n\t// details, see docs for Go's time.Layout.\n\tTimestampFormat string\n\n\t// LogInfoLevel tells funcr what key to use to log the info level.\n\t// If not specified, the info level will be logged as \"level\".\n\t// If this is set to \"\", the info level will not be logged at all.\n\tLogInfoLevel *string\n\n\t// Verbosity tells funcr which V logs to produce.  Higher values enable\n\t// more logs.  Info logs at or below this level will be written, while logs\n\t// above this level will be discarded.\n\tVerbosity int\n\n\t// RenderBuiltinsHook allows users to mutate the list of key-value pairs\n\t// while a log line is being rendered.  The kvList argument follows logr\n\t// conventions - each pair of slice elements is comprised of a string key\n\t// and an arbitrary value (verified and sanitized before calling this\n\t// hook).  The value returned must follow the same conventions.  This hook\n\t// can be used to audit or modify logged data.  For example, you might want\n\t// to prefix all of funcr's built-in keys with some string.  This hook is\n\t// only called for built-in (provided by funcr itself) key-value pairs.\n\t// Equivalent hooks are offered for key-value pairs saved via\n\t// logr.Logger.WithValues or Formatter.AddValues (see RenderValuesHook) and\n\t// for user-provided pairs (see RenderArgsHook).\n\tRenderBuiltinsHook func(kvList []any) []any\n\n\t// RenderValuesHook is the same as RenderBuiltinsHook, except that it is\n\t// only called for key-value pairs saved via logr.Logger.WithValues.  See\n\t// RenderBuiltinsHook for more details.\n\tRenderValuesHook func(kvList []any) []any\n\n\t// RenderArgsHook is the same as RenderBuiltinsHook, except that it is only\n\t// called for key-value pairs passed directly to Info and Error.  See\n\t// RenderBuiltinsHook for more details.\n\tRenderArgsHook func(kvList []any) []any\n\n\t// MaxLogDepth tells funcr how many levels of nested fields (e.g. a struct\n\t// that contains a struct, etc.) it may log.  Every time it finds a struct,\n\t// slice, array, or map the depth is increased by one.  When the maximum is\n\t// reached, the value will be converted to a string indicating that the max\n\t// depth has been exceeded.  If this field is not specified, a default\n\t// value will be used.\n\tMaxLogDepth int\n}\n\n// MessageClass indicates which category or categories of messages to consider.\ntype MessageClass int\n\nconst (\n\t// None ignores all message classes.\n\tNone MessageClass = iota\n\t// All considers all message classes.\n\tAll\n\t// Info only considers info messages.\n\tInfo\n\t// Error only considers error messages.\n\tError\n)\n\n// fnlogger inherits some of its LogSink implementation from Formatter\n// and just needs to add some glue code.\ntype fnlogger struct {\n\tFormatter\n\twrite func(prefix, args string)\n}\n\nfunc (l fnlogger) WithName(name string) logr.LogSink {\n\tl.AddName(name) // via Formatter\n\treturn &l\n}\n\nfunc (l fnlogger) WithValues(kvList ...any) logr.LogSink {\n\tl.AddValues(kvList) // via Formatter\n\treturn &l\n}\n\nfunc (l fnlogger) WithCallDepth(depth int) logr.LogSink {\n\tl.AddCallDepth(depth) // via Formatter\n\treturn &l\n}\n\nfunc (l fnlogger) Info(level int, msg string, kvList ...any) {\n\tprefix, args := l.FormatInfo(level, msg, kvList)\n\tl.write(prefix, args)\n}\n\nfunc (l fnlogger) Error(err error, msg string, kvList ...any) {\n\tprefix, args := l.FormatError(err, msg, kvList)\n\tl.write(prefix, args)\n}\n\nfunc (l fnlogger) GetUnderlying() func(prefix, args string) {\n\treturn l.write\n}\n\n// Assert conformance to the interfaces.\nvar _ logr.LogSink = &fnlogger{}\nvar _ logr.CallDepthLogSink = &fnlogger{}\nvar _ Underlier = &fnlogger{}\n\n// NewFormatter constructs a Formatter which emits a JSON-like key=value format.\nfunc NewFormatter(opts Options) Formatter {\n\treturn newFormatter(opts, outputKeyValue)\n}\n\n// NewFormatterJSON constructs a Formatter which emits strict JSON.\nfunc NewFormatterJSON(opts Options) Formatter {\n\treturn newFormatter(opts, outputJSON)\n}\n\n// Defaults for Options.\nconst defaultTimestampFormat = \"2006-01-02 15:04:05.000000\"\nconst defaultMaxLogDepth = 16\n\nfunc newFormatter(opts Options, outfmt outputFormat) Formatter {\n\tif opts.TimestampFormat == \"\" {\n\t\topts.TimestampFormat = defaultTimestampFormat\n\t}\n\tif opts.MaxLogDepth == 0 {\n\t\topts.MaxLogDepth = defaultMaxLogDepth\n\t}\n\tif opts.LogInfoLevel == nil {\n\t\topts.LogInfoLevel = new(string)\n\t\t*opts.LogInfoLevel = \"level\"\n\t}\n\tf := Formatter{\n\t\toutputFormat: outfmt,\n\t\tprefix:       \"\",\n\t\tvalues:       nil,\n\t\tdepth:        0,\n\t\topts:         &opts,\n\t}\n\treturn f\n}\n\n// Formatter is an opaque struct which can be embedded in a LogSink\n// implementation. It should be constructed with NewFormatter. Some of\n// its methods directly implement logr.LogSink.\ntype Formatter struct {\n\toutputFormat outputFormat\n\tprefix       string\n\tvalues       []any\n\tvaluesStr    string\n\tdepth        int\n\topts         *Options\n\tgroupName    string // for slog groups\n\tgroups       []groupDef\n}\n\n// outputFormat indicates which outputFormat to use.\ntype outputFormat int\n\nconst (\n\t// outputKeyValue emits a JSON-like key=value format, but not strict JSON.\n\toutputKeyValue outputFormat = iota\n\t// outputJSON emits strict JSON.\n\toutputJSON\n)\n\n// groupDef represents a saved group.  The values may be empty, but we don't\n// know if we need to render the group until the final record is rendered.\ntype groupDef struct {\n\tname   string\n\tvalues string\n}\n\n// PseudoStruct is a list of key-value pairs that gets logged as a struct.\ntype PseudoStruct []any\n\n// render produces a log line, ready to use.\nfunc (f Formatter) render(builtins, args []any) string {\n\t// Empirically bytes.Buffer is faster than strings.Builder for this.\n\tbuf := bytes.NewBuffer(make([]byte, 0, 1024))\n\n\tif f.outputFormat == outputJSON {\n\t\tbuf.WriteByte('{') // for the whole record\n\t}\n\n\t// Render builtins\n\tvals := builtins\n\tif hook := f.opts.RenderBuiltinsHook; hook != nil {\n\t\tvals = hook(f.sanitize(vals))\n\t}\n\tf.flatten(buf, vals, false) // keys are ours, no need to escape\n\tcontinuing := len(builtins) > 0\n\n\t// Turn the inner-most group into a string\n\targsStr := func() string {\n\t\tbuf := bytes.NewBuffer(make([]byte, 0, 1024))\n\n\t\tvals = args\n\t\tif hook := f.opts.RenderArgsHook; hook != nil {\n\t\t\tvals = hook(f.sanitize(vals))\n\t\t}\n\t\tf.flatten(buf, vals, true) // escape user-provided keys\n\n\t\treturn buf.String()\n\t}()\n\n\t// Render the stack of groups from the inside out.\n\tbodyStr := f.renderGroup(f.groupName, f.valuesStr, argsStr)\n\tfor i := len(f.groups) - 1; i >= 0; i-- {\n\t\tgrp := &f.groups[i]\n\t\tif grp.values == \"\" && bodyStr == \"\" {\n\t\t\t// no contents, so we must elide the whole group\n\t\t\tcontinue\n\t\t}\n\t\tbodyStr = f.renderGroup(grp.name, grp.values, bodyStr)\n\t}\n\n\tif bodyStr != \"\" {\n\t\tif continuing {\n\t\t\tbuf.WriteByte(f.comma())\n\t\t}\n\t\tbuf.WriteString(bodyStr)\n\t}\n\n\tif f.outputFormat == outputJSON {\n\t\tbuf.WriteByte('}') // for the whole record\n\t}\n\n\treturn buf.String()\n}\n\n// renderGroup returns a string representation of the named group with rendered\n// values and args.  If the name is empty, this will return the values and args,\n// joined.  If the name is not empty, this will return a single key-value pair,\n// where the value is a grouping of the values and args.  If the values and\n// args are both empty, this will return an empty string, even if the name was\n// specified.\nfunc (f Formatter) renderGroup(name string, values string, args string) string {\n\tbuf := bytes.NewBuffer(make([]byte, 0, 1024))\n\n\tneedClosingBrace := false\n\tif name != \"\" && (values != \"\" || args != \"\") {\n\t\tbuf.WriteString(f.quoted(name, true)) // escape user-provided keys\n\t\tbuf.WriteByte(f.colon())\n\t\tbuf.WriteByte('{')\n\t\tneedClosingBrace = true\n\t}\n\n\tcontinuing := false\n\tif values != \"\" {\n\t\tbuf.WriteString(values)\n\t\tcontinuing = true\n\t}\n\n\tif args != \"\" {\n\t\tif continuing {\n\t\t\tbuf.WriteByte(f.comma())\n\t\t}\n\t\tbuf.WriteString(args)\n\t}\n\n\tif needClosingBrace {\n\t\tbuf.WriteByte('}')\n\t}\n\n\treturn buf.String()\n}\n\n// flatten renders a list of key-value pairs into a buffer.  If escapeKeys is\n// true, the keys are assumed to have non-JSON-compatible characters in them\n// and must be evaluated for escapes.\n//\n// This function returns a potentially modified version of kvList, which\n// ensures that there is a value for every key (adding a value if needed) and\n// that each key is a string (substituting a key if needed).\nfunc (f Formatter) flatten(buf *bytes.Buffer, kvList []any, escapeKeys bool) []any {\n\t// This logic overlaps with sanitize() but saves one type-cast per key,\n\t// which can be measurable.\n\tif len(kvList)%2 != 0 {\n\t\tkvList = append(kvList, noValue)\n\t}\n\tcopied := false\n\tfor i := 0; i < len(kvList); i += 2 {\n\t\tk, ok := kvList[i].(string)\n\t\tif !ok {\n\t\t\tif !copied {\n\t\t\t\tnewList := make([]any, len(kvList))\n\t\t\t\tcopy(newList, kvList)\n\t\t\t\tkvList = newList\n\t\t\t\tcopied = true\n\t\t\t}\n\t\t\tk = f.nonStringKey(kvList[i])\n\t\t\tkvList[i] = k\n\t\t}\n\t\tv := kvList[i+1]\n\n\t\tif i > 0 {\n\t\t\tif f.outputFormat == outputJSON {\n\t\t\t\tbuf.WriteByte(f.comma())\n\t\t\t} else {\n\t\t\t\t// In theory the format could be something we don't understand.  In\n\t\t\t\t// practice, we control it, so it won't be.\n\t\t\t\tbuf.WriteByte(' ')\n\t\t\t}\n\t\t}\n\n\t\tbuf.WriteString(f.quoted(k, escapeKeys))\n\t\tbuf.WriteByte(f.colon())\n\t\tbuf.WriteString(f.pretty(v))\n\t}\n\treturn kvList\n}\n\nfunc (f Formatter) quoted(str string, escape bool) string {\n\tif escape {\n\t\treturn prettyString(str)\n\t}\n\t// this is faster\n\treturn `\"` + str + `\"`\n}\n\nfunc (f Formatter) comma() byte {\n\tif f.outputFormat == outputJSON {\n\t\treturn ','\n\t}\n\treturn ' '\n}\n\nfunc (f Formatter) colon() byte {\n\tif f.outputFormat == outputJSON {\n\t\treturn ':'\n\t}\n\treturn '='\n}\n\nfunc (f Formatter) pretty(value any) string {\n\treturn f.prettyWithFlags(value, 0, 0)\n}\n\nconst (\n\tflagRawStruct = 0x1 // do not print braces on structs\n)\n\n// TODO: This is not fast. Most of the overhead goes here.\nfunc (f Formatter) prettyWithFlags(value any, flags uint32, depth int) string {\n\tif depth > f.opts.MaxLogDepth {\n\t\treturn `\"<max-log-depth-exceeded>\"`\n\t}\n\n\t// Handle types that take full control of logging.\n\tif v, ok := value.(logr.Marshaler); ok {\n\t\t// Replace the value with what the type wants to get logged.\n\t\t// That then gets handled below via reflection.\n\t\tvalue = invokeMarshaler(v)\n\t}\n\n\t// Handle types that want to format themselves.\n\tswitch v := value.(type) {\n\tcase fmt.Stringer:\n\t\tvalue = invokeStringer(v)\n\tcase error:\n\t\tvalue = invokeError(v)\n\t}\n\n\t// Handling the most common types without reflect is a small perf win.\n\tswitch v := value.(type) {\n\tcase bool:\n\t\treturn strconv.FormatBool(v)\n\tcase string:\n\t\treturn prettyString(v)\n\tcase int:\n\t\treturn strconv.FormatInt(int64(v), 10)\n\tcase int8:\n\t\treturn strconv.FormatInt(int64(v), 10)\n\tcase int16:\n\t\treturn strconv.FormatInt(int64(v), 10)\n\tcase int32:\n\t\treturn strconv.FormatInt(int64(v), 10)\n\tcase int64:\n\t\treturn strconv.FormatInt(int64(v), 10)\n\tcase uint:\n\t\treturn strconv.FormatUint(uint64(v), 10)\n\tcase uint8:\n\t\treturn strconv.FormatUint(uint64(v), 10)\n\tcase uint16:\n\t\treturn strconv.FormatUint(uint64(v), 10)\n\tcase uint32:\n\t\treturn strconv.FormatUint(uint64(v), 10)\n\tcase uint64:\n\t\treturn strconv.FormatUint(v, 10)\n\tcase uintptr:\n\t\treturn strconv.FormatUint(uint64(v), 10)\n\tcase float32:\n\t\treturn strconv.FormatFloat(float64(v), 'f', -1, 32)\n\tcase float64:\n\t\treturn strconv.FormatFloat(v, 'f', -1, 64)\n\tcase complex64:\n\t\treturn `\"` + strconv.FormatComplex(complex128(v), 'f', -1, 64) + `\"`\n\tcase complex128:\n\t\treturn `\"` + strconv.FormatComplex(v, 'f', -1, 128) + `\"`\n\tcase PseudoStruct:\n\t\tbuf := bytes.NewBuffer(make([]byte, 0, 1024))\n\t\tv = f.sanitize(v)\n\t\tif flags&flagRawStruct == 0 {\n\t\t\tbuf.WriteByte('{')\n\t\t}\n\t\tfor i := 0; i < len(v); i += 2 {\n\t\t\tif i > 0 {\n\t\t\t\tbuf.WriteByte(f.comma())\n\t\t\t}\n\t\t\tk, _ := v[i].(string) // sanitize() above means no need to check success\n\t\t\t// arbitrary keys might need escaping\n\t\t\tbuf.WriteString(prettyString(k))\n\t\t\tbuf.WriteByte(f.colon())\n\t\t\tbuf.WriteString(f.prettyWithFlags(v[i+1], 0, depth+1))\n\t\t}\n\t\tif flags&flagRawStruct == 0 {\n\t\t\tbuf.WriteByte('}')\n\t\t}\n\t\treturn buf.String()\n\t}\n\n\tbuf := bytes.NewBuffer(make([]byte, 0, 256))\n\tt := reflect.TypeOf(value)\n\tif t == nil {\n\t\treturn \"null\"\n\t}\n\tv := reflect.ValueOf(value)\n\tswitch t.Kind() {\n\tcase reflect.Bool:\n\t\treturn strconv.FormatBool(v.Bool())\n\tcase reflect.String:\n\t\treturn prettyString(v.String())\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\treturn strconv.FormatInt(int64(v.Int()), 10)\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\treturn strconv.FormatUint(uint64(v.Uint()), 10)\n\tcase reflect.Float32:\n\t\treturn strconv.FormatFloat(float64(v.Float()), 'f', -1, 32)\n\tcase reflect.Float64:\n\t\treturn strconv.FormatFloat(v.Float(), 'f', -1, 64)\n\tcase reflect.Complex64:\n\t\treturn `\"` + strconv.FormatComplex(complex128(v.Complex()), 'f', -1, 64) + `\"`\n\tcase reflect.Complex128:\n\t\treturn `\"` + strconv.FormatComplex(v.Complex(), 'f', -1, 128) + `\"`\n\tcase reflect.Struct:\n\t\tif flags&flagRawStruct == 0 {\n\t\t\tbuf.WriteByte('{')\n\t\t}\n\t\tprintComma := false // testing i>0 is not enough because of JSON omitted fields\n\t\tfor i := 0; i < t.NumField(); i++ {\n\t\t\tfld := t.Field(i)\n\t\t\tif fld.PkgPath != \"\" {\n\t\t\t\t// reflect says this field is only defined for non-exported fields.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif !v.Field(i).CanInterface() {\n\t\t\t\t// reflect isn't clear exactly what this means, but we can't use it.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tname := \"\"\n\t\t\tomitempty := false\n\t\t\tif tag, found := fld.Tag.Lookup(\"json\"); found {\n\t\t\t\tif tag == \"-\" {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif comma := strings.Index(tag, \",\"); comma != -1 {\n\t\t\t\t\tif n := tag[:comma]; n != \"\" {\n\t\t\t\t\t\tname = n\n\t\t\t\t\t}\n\t\t\t\t\trest := tag[comma:]\n\t\t\t\t\tif strings.Contains(rest, \",omitempty,\") || strings.HasSuffix(rest, \",omitempty\") {\n\t\t\t\t\t\tomitempty = true\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tname = tag\n\t\t\t\t}\n\t\t\t}\n\t\t\tif omitempty && isEmpty(v.Field(i)) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif printComma {\n\t\t\t\tbuf.WriteByte(f.comma())\n\t\t\t}\n\t\t\tprintComma = true // if we got here, we are rendering a field\n\t\t\tif fld.Anonymous && fld.Type.Kind() == reflect.Struct && name == \"\" {\n\t\t\t\tbuf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), flags|flagRawStruct, depth+1))\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif name == \"\" {\n\t\t\t\tname = fld.Name\n\t\t\t}\n\t\t\t// field names can't contain characters which need escaping\n\t\t\tbuf.WriteString(f.quoted(name, false))\n\t\t\tbuf.WriteByte(f.colon())\n\t\t\tbuf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), 0, depth+1))\n\t\t}\n\t\tif flags&flagRawStruct == 0 {\n\t\t\tbuf.WriteByte('}')\n\t\t}\n\t\treturn buf.String()\n\tcase reflect.Slice, reflect.Array:\n\t\t// If this is outputing as JSON make sure this isn't really a json.RawMessage.\n\t\t// If so just emit \"as-is\" and don't pretty it as that will just print\n\t\t// it as [X,Y,Z,...] which isn't terribly useful vs the string form you really want.\n\t\tif f.outputFormat == outputJSON {\n\t\t\tif rm, ok := value.(json.RawMessage); ok {\n\t\t\t\t// If it's empty make sure we emit an empty value as the array style would below.\n\t\t\t\tif len(rm) > 0 {\n\t\t\t\t\tbuf.Write(rm)\n\t\t\t\t} else {\n\t\t\t\t\tbuf.WriteString(\"null\")\n\t\t\t\t}\n\t\t\t\treturn buf.String()\n\t\t\t}\n\t\t}\n\t\tbuf.WriteByte('[')\n\t\tfor i := 0; i < v.Len(); i++ {\n\t\t\tif i > 0 {\n\t\t\t\tbuf.WriteByte(f.comma())\n\t\t\t}\n\t\t\te := v.Index(i)\n\t\t\tbuf.WriteString(f.prettyWithFlags(e.Interface(), 0, depth+1))\n\t\t}\n\t\tbuf.WriteByte(']')\n\t\treturn buf.String()\n\tcase reflect.Map:\n\t\tbuf.WriteByte('{')\n\t\t// This does not sort the map keys, for best perf.\n\t\tit := v.MapRange()\n\t\ti := 0\n\t\tfor it.Next() {\n\t\t\tif i > 0 {\n\t\t\t\tbuf.WriteByte(f.comma())\n\t\t\t}\n\t\t\t// If a map key supports TextMarshaler, use it.\n\t\t\tkeystr := \"\"\n\t\t\tif m, ok := it.Key().Interface().(encoding.TextMarshaler); ok {\n\t\t\t\ttxt, err := m.MarshalText()\n\t\t\t\tif err != nil {\n\t\t\t\t\tkeystr = fmt.Sprintf(\"<error-MarshalText: %s>\", err.Error())\n\t\t\t\t} else {\n\t\t\t\t\tkeystr = string(txt)\n\t\t\t\t}\n\t\t\t\tkeystr = prettyString(keystr)\n\t\t\t} else {\n\t\t\t\t// prettyWithFlags will produce already-escaped values\n\t\t\t\tkeystr = f.prettyWithFlags(it.Key().Interface(), 0, depth+1)\n\t\t\t\tif t.Key().Kind() != reflect.String {\n\t\t\t\t\t// JSON only does string keys.  Unlike Go's standard JSON, we'll\n\t\t\t\t\t// convert just about anything to a string.\n\t\t\t\t\tkeystr = prettyString(keystr)\n\t\t\t\t}\n\t\t\t}\n\t\t\tbuf.WriteString(keystr)\n\t\t\tbuf.WriteByte(f.colon())\n\t\t\tbuf.WriteString(f.prettyWithFlags(it.Value().Interface(), 0, depth+1))\n\t\t\ti++\n\t\t}\n\t\tbuf.WriteByte('}')\n\t\treturn buf.String()\n\tcase reflect.Ptr, reflect.Interface:\n\t\tif v.IsNil() {\n\t\t\treturn \"null\"\n\t\t}\n\t\treturn f.prettyWithFlags(v.Elem().Interface(), 0, depth)\n\t}\n\treturn fmt.Sprintf(`\"<unhandled-%s>\"`, t.Kind().String())\n}\n\nfunc prettyString(s string) string {\n\t// Avoid escaping (which does allocations) if we can.\n\tif needsEscape(s) {\n\t\treturn strconv.Quote(s)\n\t}\n\tb := bytes.NewBuffer(make([]byte, 0, 1024))\n\tb.WriteByte('\"')\n\tb.WriteString(s)\n\tb.WriteByte('\"')\n\treturn b.String()\n}\n\n// needsEscape determines whether the input string needs to be escaped or not,\n// without doing any allocations.\nfunc needsEscape(s string) bool {\n\tfor _, r := range s {\n\t\tif !strconv.IsPrint(r) || r == '\\\\' || r == '\"' {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc isEmpty(v reflect.Value) bool {\n\tswitch v.Kind() {\n\tcase reflect.Array, reflect.Map, reflect.Slice, reflect.String:\n\t\treturn v.Len() == 0\n\tcase reflect.Bool:\n\t\treturn !v.Bool()\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\treturn v.Int() == 0\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\treturn v.Uint() == 0\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn v.Float() == 0\n\tcase reflect.Complex64, reflect.Complex128:\n\t\treturn v.Complex() == 0\n\tcase reflect.Interface, reflect.Ptr:\n\t\treturn v.IsNil()\n\t}\n\treturn false\n}\n\nfunc invokeMarshaler(m logr.Marshaler) (ret any) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tret = fmt.Sprintf(\"<panic: %s>\", r)\n\t\t}\n\t}()\n\treturn m.MarshalLog()\n}\n\nfunc invokeStringer(s fmt.Stringer) (ret string) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tret = fmt.Sprintf(\"<panic: %s>\", r)\n\t\t}\n\t}()\n\treturn s.String()\n}\n\nfunc invokeError(e error) (ret string) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tret = fmt.Sprintf(\"<panic: %s>\", r)\n\t\t}\n\t}()\n\treturn e.Error()\n}\n\n// Caller represents the original call site for a log line, after considering\n// logr.Logger.WithCallDepth and logr.Logger.WithCallStackHelper.  The File and\n// Line fields will always be provided, while the Func field is optional.\n// Users can set the render hook fields in Options to examine logged key-value\n// pairs, one of which will be {\"caller\", Caller} if the Options.LogCaller\n// field is enabled for the given MessageClass.\ntype Caller struct {\n\t// File is the basename of the file for this call site.\n\tFile string `json:\"file\"`\n\t// Line is the line number in the file for this call site.\n\tLine int `json:\"line\"`\n\t// Func is the function name for this call site, or empty if\n\t// Options.LogCallerFunc is not enabled.\n\tFunc string `json:\"function,omitempty\"`\n}\n\nfunc (f Formatter) caller() Caller {\n\t// +1 for this frame, +1 for Info/Error.\n\tpc, file, line, ok := runtime.Caller(f.depth + 2)\n\tif !ok {\n\t\treturn Caller{\"<unknown>\", 0, \"\"}\n\t}\n\tfn := \"\"\n\tif f.opts.LogCallerFunc {\n\t\tif fp := runtime.FuncForPC(pc); fp != nil {\n\t\t\tfn = fp.Name()\n\t\t}\n\t}\n\n\treturn Caller{filepath.Base(file), line, fn}\n}\n\nconst noValue = \"<no-value>\"\n\nfunc (f Formatter) nonStringKey(v any) string {\n\treturn fmt.Sprintf(\"<non-string-key: %s>\", f.snippet(v))\n}\n\n// snippet produces a short snippet string of an arbitrary value.\nfunc (f Formatter) snippet(v any) string {\n\tconst snipLen = 16\n\n\tsnip := f.pretty(v)\n\tif len(snip) > snipLen {\n\t\tsnip = snip[:snipLen]\n\t}\n\treturn snip\n}\n\n// sanitize ensures that a list of key-value pairs has a value for every key\n// (adding a value if needed) and that each key is a string (substituting a key\n// if needed).\nfunc (f Formatter) sanitize(kvList []any) []any {\n\tif len(kvList)%2 != 0 {\n\t\tkvList = append(kvList, noValue)\n\t}\n\tfor i := 0; i < len(kvList); i += 2 {\n\t\t_, ok := kvList[i].(string)\n\t\tif !ok {\n\t\t\tkvList[i] = f.nonStringKey(kvList[i])\n\t\t}\n\t}\n\treturn kvList\n}\n\n// startGroup opens a new group scope (basically a sub-struct), which locks all\n// the current saved values and starts them anew.  This is needed to satisfy\n// slog.\nfunc (f *Formatter) startGroup(name string) {\n\t// Unnamed groups are just inlined.\n\tif name == \"\" {\n\t\treturn\n\t}\n\n\tn := len(f.groups)\n\tf.groups = append(f.groups[:n:n], groupDef{f.groupName, f.valuesStr})\n\n\t// Start collecting new values.\n\tf.groupName = name\n\tf.valuesStr = \"\"\n\tf.values = nil\n}\n\n// Init configures this Formatter from runtime info, such as the call depth\n// imposed by logr itself.\n// Note that this receiver is a pointer, so depth can be saved.\nfunc (f *Formatter) Init(info logr.RuntimeInfo) {\n\tf.depth += info.CallDepth\n}\n\n// Enabled checks whether an info message at the given level should be logged.\nfunc (f Formatter) Enabled(level int) bool {\n\treturn level <= f.opts.Verbosity\n}\n\n// GetDepth returns the current depth of this Formatter.  This is useful for\n// implementations which do their own caller attribution.\nfunc (f Formatter) GetDepth() int {\n\treturn f.depth\n}\n\n// FormatInfo renders an Info log message into strings.  The prefix will be\n// empty when no names were set (via AddNames), or when the output is\n// configured for JSON.\nfunc (f Formatter) FormatInfo(level int, msg string, kvList []any) (prefix, argsStr string) {\n\targs := make([]any, 0, 64) // using a constant here impacts perf\n\tprefix = f.prefix\n\tif f.outputFormat == outputJSON {\n\t\targs = append(args, \"logger\", prefix)\n\t\tprefix = \"\"\n\t}\n\tif f.opts.LogTimestamp {\n\t\targs = append(args, \"ts\", time.Now().Format(f.opts.TimestampFormat))\n\t}\n\tif policy := f.opts.LogCaller; policy == All || policy == Info {\n\t\targs = append(args, \"caller\", f.caller())\n\t}\n\tif key := *f.opts.LogInfoLevel; key != \"\" {\n\t\targs = append(args, key, level)\n\t}\n\targs = append(args, \"msg\", msg)\n\treturn prefix, f.render(args, kvList)\n}\n\n// FormatError renders an Error log message into strings.  The prefix will be\n// empty when no names were set (via AddNames), or when the output is\n// configured for JSON.\nfunc (f Formatter) FormatError(err error, msg string, kvList []any) (prefix, argsStr string) {\n\targs := make([]any, 0, 64) // using a constant here impacts perf\n\tprefix = f.prefix\n\tif f.outputFormat == outputJSON {\n\t\targs = append(args, \"logger\", prefix)\n\t\tprefix = \"\"\n\t}\n\tif f.opts.LogTimestamp {\n\t\targs = append(args, \"ts\", time.Now().Format(f.opts.TimestampFormat))\n\t}\n\tif policy := f.opts.LogCaller; policy == All || policy == Error {\n\t\targs = append(args, \"caller\", f.caller())\n\t}\n\targs = append(args, \"msg\", msg)\n\tvar loggableErr any\n\tif err != nil {\n\t\tloggableErr = err.Error()\n\t}\n\targs = append(args, \"error\", loggableErr)\n\treturn prefix, f.render(args, kvList)\n}\n\n// AddName appends the specified name.  funcr uses '/' characters to separate\n// name elements.  Callers should not pass '/' in the provided name string, but\n// this library does not actually enforce that.\nfunc (f *Formatter) AddName(name string) {\n\tif len(f.prefix) > 0 {\n\t\tf.prefix += \"/\"\n\t}\n\tf.prefix += name\n}\n\n// AddValues adds key-value pairs to the set of saved values to be logged with\n// each log line.\nfunc (f *Formatter) AddValues(kvList []any) {\n\t// Three slice args forces a copy.\n\tn := len(f.values)\n\tf.values = append(f.values[:n:n], kvList...)\n\n\tvals := f.values\n\tif hook := f.opts.RenderValuesHook; hook != nil {\n\t\tvals = hook(f.sanitize(vals))\n\t}\n\n\t// Pre-render values, so we don't have to do it on each Info/Error call.\n\tbuf := bytes.NewBuffer(make([]byte, 0, 1024))\n\tf.flatten(buf, vals, true) // escape user-provided keys\n\tf.valuesStr = buf.String()\n}\n\n// AddCallDepth increases the number of stack-frames to skip when attributing\n// the log line to a file and line.\nfunc (f *Formatter) AddCallDepth(depth int) {\n\tf.depth += depth\n}\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/funcr/slogsink.go",
    "content": "//go:build go1.21\n// +build go1.21\n\n/*\nCopyright 2023 The logr Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage funcr\n\nimport (\n\t\"context\"\n\t\"log/slog\"\n\n\t\"github.com/go-logr/logr\"\n)\n\nvar _ logr.SlogSink = &fnlogger{}\n\nconst extraSlogSinkDepth = 3 // 2 for slog, 1 for SlogSink\n\nfunc (l fnlogger) Handle(_ context.Context, record slog.Record) error {\n\tkvList := make([]any, 0, 2*record.NumAttrs())\n\trecord.Attrs(func(attr slog.Attr) bool {\n\t\tkvList = attrToKVs(attr, kvList)\n\t\treturn true\n\t})\n\n\tif record.Level >= slog.LevelError {\n\t\tl.WithCallDepth(extraSlogSinkDepth).Error(nil, record.Message, kvList...)\n\t} else {\n\t\tlevel := l.levelFromSlog(record.Level)\n\t\tl.WithCallDepth(extraSlogSinkDepth).Info(level, record.Message, kvList...)\n\t}\n\treturn nil\n}\n\nfunc (l fnlogger) WithAttrs(attrs []slog.Attr) logr.SlogSink {\n\tkvList := make([]any, 0, 2*len(attrs))\n\tfor _, attr := range attrs {\n\t\tkvList = attrToKVs(attr, kvList)\n\t}\n\tl.AddValues(kvList)\n\treturn &l\n}\n\nfunc (l fnlogger) WithGroup(name string) logr.SlogSink {\n\tl.startGroup(name)\n\treturn &l\n}\n\n// attrToKVs appends a slog.Attr to a logr-style kvList.  It handle slog Groups\n// and other details of slog.\nfunc attrToKVs(attr slog.Attr, kvList []any) []any {\n\tattrVal := attr.Value.Resolve()\n\tif attrVal.Kind() == slog.KindGroup {\n\t\tgroupVal := attrVal.Group()\n\t\tgrpKVs := make([]any, 0, 2*len(groupVal))\n\t\tfor _, attr := range groupVal {\n\t\t\tgrpKVs = attrToKVs(attr, grpKVs)\n\t\t}\n\t\tif attr.Key == \"\" {\n\t\t\t// slog says we have to inline these\n\t\t\tkvList = append(kvList, grpKVs...)\n\t\t} else {\n\t\t\tkvList = append(kvList, attr.Key, PseudoStruct(grpKVs))\n\t\t}\n\t} else if attr.Key != \"\" {\n\t\tkvList = append(kvList, attr.Key, attrVal.Any())\n\t}\n\n\treturn kvList\n}\n\n// levelFromSlog adjusts the level by the logger's verbosity and negates it.\n// It ensures that the result is >= 0. This is necessary because the result is\n// passed to a LogSink and that API did not historically document whether\n// levels could be negative or what that meant.\n//\n// Some example usage:\n//\n//\tlogrV0 := getMyLogger()\n//\tlogrV2 := logrV0.V(2)\n//\tslogV2 := slog.New(logr.ToSlogHandler(logrV2))\n//\tslogV2.Debug(\"msg\") // =~ logrV2.V(4) =~ logrV0.V(6)\n//\tslogV2.Info(\"msg\")  // =~  logrV2.V(0) =~ logrV0.V(2)\n//\tslogv2.Warn(\"msg\")  // =~ logrV2.V(-4) =~ logrV0.V(0)\nfunc (l fnlogger) levelFromSlog(level slog.Level) int {\n\tresult := -level\n\tif result < 0 {\n\t\tresult = 0 // because LogSink doesn't expect negative V levels\n\t}\n\treturn int(result)\n}\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/logr.go",
    "content": "/*\nCopyright 2019 The logr Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// This design derives from Dave Cheney's blog:\n//     http://dave.cheney.net/2015/11/05/lets-talk-about-logging\n\n// Package logr defines a general-purpose logging API and abstract interfaces\n// to back that API.  Packages in the Go ecosystem can depend on this package,\n// while callers can implement logging with whatever backend is appropriate.\n//\n// # Usage\n//\n// Logging is done using a Logger instance.  Logger is a concrete type with\n// methods, which defers the actual logging to a LogSink interface.  The main\n// methods of Logger are Info() and Error().  Arguments to Info() and Error()\n// are key/value pairs rather than printf-style formatted strings, emphasizing\n// \"structured logging\".\n//\n// With Go's standard log package, we might write:\n//\n//\tlog.Printf(\"setting target value %s\", targetValue)\n//\n// With logr's structured logging, we'd write:\n//\n//\tlogger.Info(\"setting target\", \"value\", targetValue)\n//\n// Errors are much the same.  Instead of:\n//\n//\tlog.Printf(\"failed to open the pod bay door for user %s: %v\", user, err)\n//\n// We'd write:\n//\n//\tlogger.Error(err, \"failed to open the pod bay door\", \"user\", user)\n//\n// Info() and Error() are very similar, but they are separate methods so that\n// LogSink implementations can choose to do things like attach additional\n// information (such as stack traces) on calls to Error(). Error() messages are\n// always logged, regardless of the current verbosity.  If there is no error\n// instance available, passing nil is valid.\n//\n// # Verbosity\n//\n// Often we want to log information only when the application in \"verbose\n// mode\".  To write log lines that are more verbose, Logger has a V() method.\n// The higher the V-level of a log line, the less critical it is considered.\n// Log-lines with V-levels that are not enabled (as per the LogSink) will not\n// be written.  Level V(0) is the default, and logger.V(0).Info() has the same\n// meaning as logger.Info().  Negative V-levels have the same meaning as V(0).\n// Error messages do not have a verbosity level and are always logged.\n//\n// Where we might have written:\n//\n//\tif flVerbose >= 2 {\n//\t    log.Printf(\"an unusual thing happened\")\n//\t}\n//\n// We can write:\n//\n//\tlogger.V(2).Info(\"an unusual thing happened\")\n//\n// # Logger Names\n//\n// Logger instances can have name strings so that all messages logged through\n// that instance have additional context.  For example, you might want to add\n// a subsystem name:\n//\n//\tlogger.WithName(\"compactor\").Info(\"started\", \"time\", time.Now())\n//\n// The WithName() method returns a new Logger, which can be passed to\n// constructors or other functions for further use.  Repeated use of WithName()\n// will accumulate name \"segments\".  These name segments will be joined in some\n// way by the LogSink implementation.  It is strongly recommended that name\n// segments contain simple identifiers (letters, digits, and hyphen), and do\n// not contain characters that could muddle the log output or confuse the\n// joining operation (e.g. whitespace, commas, periods, slashes, brackets,\n// quotes, etc).\n//\n// # Saved Values\n//\n// Logger instances can store any number of key/value pairs, which will be\n// logged alongside all messages logged through that instance.  For example,\n// you might want to create a Logger instance per managed object:\n//\n// With the standard log package, we might write:\n//\n//\tlog.Printf(\"decided to set field foo to value %q for object %s/%s\",\n//\t    targetValue, object.Namespace, object.Name)\n//\n// With logr we'd write:\n//\n//\t// Elsewhere: set up the logger to log the object name.\n//\tobj.logger = mainLogger.WithValues(\n//\t    \"name\", obj.name, \"namespace\", obj.namespace)\n//\n//\t// later on...\n//\tobj.logger.Info(\"setting foo\", \"value\", targetValue)\n//\n// # Best Practices\n//\n// Logger has very few hard rules, with the goal that LogSink implementations\n// might have a lot of freedom to differentiate.  There are, however, some\n// things to consider.\n//\n// The log message consists of a constant message attached to the log line.\n// This should generally be a simple description of what's occurring, and should\n// never be a format string.  Variable information can then be attached using\n// named values.\n//\n// Keys are arbitrary strings, but should generally be constant values.  Values\n// may be any Go value, but how the value is formatted is determined by the\n// LogSink implementation.\n//\n// Logger instances are meant to be passed around by value. Code that receives\n// such a value can call its methods without having to check whether the\n// instance is ready for use.\n//\n// The zero logger (= Logger{}) is identical to Discard() and discards all log\n// entries. Code that receives a Logger by value can simply call it, the methods\n// will never crash. For cases where passing a logger is optional, a pointer to Logger\n// should be used.\n//\n// # Key Naming Conventions\n//\n// Keys are not strictly required to conform to any specification or regex, but\n// it is recommended that they:\n//   - be human-readable and meaningful (not auto-generated or simple ordinals)\n//   - be constant (not dependent on input data)\n//   - contain only printable characters\n//   - not contain whitespace or punctuation\n//   - use lower case for simple keys and lowerCamelCase for more complex ones\n//\n// These guidelines help ensure that log data is processed properly regardless\n// of the log implementation.  For example, log implementations will try to\n// output JSON data or will store data for later database (e.g. SQL) queries.\n//\n// While users are generally free to use key names of their choice, it's\n// generally best to avoid using the following keys, as they're frequently used\n// by implementations:\n//   - \"caller\": the calling information (file/line) of a particular log line\n//   - \"error\": the underlying error value in the `Error` method\n//   - \"level\": the log level\n//   - \"logger\": the name of the associated logger\n//   - \"msg\": the log message\n//   - \"stacktrace\": the stack trace associated with a particular log line or\n//     error (often from the `Error` message)\n//   - \"ts\": the timestamp for a log line\n//\n// Implementations are encouraged to make use of these keys to represent the\n// above concepts, when necessary (for example, in a pure-JSON output form, it\n// would be necessary to represent at least message and timestamp as ordinary\n// named values).\n//\n// # Break Glass\n//\n// Implementations may choose to give callers access to the underlying\n// logging implementation.  The recommended pattern for this is:\n//\n//\t// Underlier exposes access to the underlying logging implementation.\n//\t// Since callers only have a logr.Logger, they have to know which\n//\t// implementation is in use, so this interface is less of an abstraction\n//\t// and more of way to test type conversion.\n//\ttype Underlier interface {\n//\t    GetUnderlying() <underlying-type>\n//\t}\n//\n// Logger grants access to the sink to enable type assertions like this:\n//\n//\tfunc DoSomethingWithImpl(log logr.Logger) {\n//\t    if underlier, ok := log.GetSink().(impl.Underlier); ok {\n//\t       implLogger := underlier.GetUnderlying()\n//\t       ...\n//\t    }\n//\t}\n//\n// Custom `With*` functions can be implemented by copying the complete\n// Logger struct and replacing the sink in the copy:\n//\n//\t// WithFooBar changes the foobar parameter in the log sink and returns a\n//\t// new logger with that modified sink.  It does nothing for loggers where\n//\t// the sink doesn't support that parameter.\n//\tfunc WithFoobar(log logr.Logger, foobar int) logr.Logger {\n//\t   if foobarLogSink, ok := log.GetSink().(FoobarSink); ok {\n//\t      log = log.WithSink(foobarLogSink.WithFooBar(foobar))\n//\t   }\n//\t   return log\n//\t}\n//\n// Don't use New to construct a new Logger with a LogSink retrieved from an\n// existing Logger. Source code attribution might not work correctly and\n// unexported fields in Logger get lost.\n//\n// Beware that the same LogSink instance may be shared by different logger\n// instances. Calling functions that modify the LogSink will affect all of\n// those.\npackage logr\n\n// New returns a new Logger instance.  This is primarily used by libraries\n// implementing LogSink, rather than end users.  Passing a nil sink will create\n// a Logger which discards all log lines.\nfunc New(sink LogSink) Logger {\n\tlogger := Logger{}\n\tlogger.setSink(sink)\n\tif sink != nil {\n\t\tsink.Init(runtimeInfo)\n\t}\n\treturn logger\n}\n\n// setSink stores the sink and updates any related fields. It mutates the\n// logger and thus is only safe to use for loggers that are not currently being\n// used concurrently.\nfunc (l *Logger) setSink(sink LogSink) {\n\tl.sink = sink\n}\n\n// GetSink returns the stored sink.\nfunc (l Logger) GetSink() LogSink {\n\treturn l.sink\n}\n\n// WithSink returns a copy of the logger with the new sink.\nfunc (l Logger) WithSink(sink LogSink) Logger {\n\tl.setSink(sink)\n\treturn l\n}\n\n// Logger is an interface to an abstract logging implementation.  This is a\n// concrete type for performance reasons, but all the real work is passed on to\n// a LogSink.  Implementations of LogSink should provide their own constructors\n// that return Logger, not LogSink.\n//\n// The underlying sink can be accessed through GetSink and be modified through\n// WithSink. This enables the implementation of custom extensions (see \"Break\n// Glass\" in the package documentation). Normally the sink should be used only\n// indirectly.\ntype Logger struct {\n\tsink  LogSink\n\tlevel int\n}\n\n// Enabled tests whether this Logger is enabled.  For example, commandline\n// flags might be used to set the logging verbosity and disable some info logs.\nfunc (l Logger) Enabled() bool {\n\t// Some implementations of LogSink look at the caller in Enabled (e.g.\n\t// different verbosity levels per package or file), but we only pass one\n\t// CallDepth in (via Init).  This means that all calls from Logger to the\n\t// LogSink's Enabled, Info, and Error methods must have the same number of\n\t// frames.  In other words, Logger methods can't call other Logger methods\n\t// which call these LogSink methods unless we do it the same in all paths.\n\treturn l.sink != nil && l.sink.Enabled(l.level)\n}\n\n// Info logs a non-error message with the given key/value pairs as context.\n//\n// The msg argument should be used to add some constant description to the log\n// line.  The key/value pairs can then be used to add additional variable\n// information.  The key/value pairs must alternate string keys and arbitrary\n// values.\nfunc (l Logger) Info(msg string, keysAndValues ...any) {\n\tif l.sink == nil {\n\t\treturn\n\t}\n\tif l.sink.Enabled(l.level) { // see comment in Enabled\n\t\tif withHelper, ok := l.sink.(CallStackHelperLogSink); ok {\n\t\t\twithHelper.GetCallStackHelper()()\n\t\t}\n\t\tl.sink.Info(l.level, msg, keysAndValues...)\n\t}\n}\n\n// Error logs an error, with the given message and key/value pairs as context.\n// It functions similarly to Info, but may have unique behavior, and should be\n// preferred for logging errors (see the package documentations for more\n// information). The log message will always be emitted, regardless of\n// verbosity level.\n//\n// The msg argument should be used to add context to any underlying error,\n// while the err argument should be used to attach the actual error that\n// triggered this log line, if present. The err parameter is optional\n// and nil may be passed instead of an error instance.\nfunc (l Logger) Error(err error, msg string, keysAndValues ...any) {\n\tif l.sink == nil {\n\t\treturn\n\t}\n\tif withHelper, ok := l.sink.(CallStackHelperLogSink); ok {\n\t\twithHelper.GetCallStackHelper()()\n\t}\n\tl.sink.Error(err, msg, keysAndValues...)\n}\n\n// V returns a new Logger instance for a specific verbosity level, relative to\n// this Logger.  In other words, V-levels are additive.  A higher verbosity\n// level means a log message is less important.  Negative V-levels are treated\n// as 0.\nfunc (l Logger) V(level int) Logger {\n\tif l.sink == nil {\n\t\treturn l\n\t}\n\tif level < 0 {\n\t\tlevel = 0\n\t}\n\tl.level += level\n\treturn l\n}\n\n// GetV returns the verbosity level of the logger. If the logger's LogSink is\n// nil as in the Discard logger, this will always return 0.\nfunc (l Logger) GetV() int {\n\t// 0 if l.sink nil because of the if check in V above.\n\treturn l.level\n}\n\n// WithValues returns a new Logger instance with additional key/value pairs.\n// See Info for documentation on how key/value pairs work.\nfunc (l Logger) WithValues(keysAndValues ...any) Logger {\n\tif l.sink == nil {\n\t\treturn l\n\t}\n\tl.setSink(l.sink.WithValues(keysAndValues...))\n\treturn l\n}\n\n// WithName returns a new Logger instance with the specified name element added\n// to the Logger's name.  Successive calls with WithName append additional\n// suffixes to the Logger's name.  It's strongly recommended that name segments\n// contain only letters, digits, and hyphens (see the package documentation for\n// more information).\nfunc (l Logger) WithName(name string) Logger {\n\tif l.sink == nil {\n\t\treturn l\n\t}\n\tl.setSink(l.sink.WithName(name))\n\treturn l\n}\n\n// WithCallDepth returns a Logger instance that offsets the call stack by the\n// specified number of frames when logging call site information, if possible.\n// This is useful for users who have helper functions between the \"real\" call\n// site and the actual calls to Logger methods.  If depth is 0 the attribution\n// should be to the direct caller of this function.  If depth is 1 the\n// attribution should skip 1 call frame, and so on.  Successive calls to this\n// are additive.\n//\n// If the underlying log implementation supports a WithCallDepth(int) method,\n// it will be called and the result returned.  If the implementation does not\n// support CallDepthLogSink, the original Logger will be returned.\n//\n// To skip one level, WithCallStackHelper() should be used instead of\n// WithCallDepth(1) because it works with implementions that support the\n// CallDepthLogSink and/or CallStackHelperLogSink interfaces.\nfunc (l Logger) WithCallDepth(depth int) Logger {\n\tif l.sink == nil {\n\t\treturn l\n\t}\n\tif withCallDepth, ok := l.sink.(CallDepthLogSink); ok {\n\t\tl.setSink(withCallDepth.WithCallDepth(depth))\n\t}\n\treturn l\n}\n\n// WithCallStackHelper returns a new Logger instance that skips the direct\n// caller when logging call site information, if possible.  This is useful for\n// users who have helper functions between the \"real\" call site and the actual\n// calls to Logger methods and want to support loggers which depend on marking\n// each individual helper function, like loggers based on testing.T.\n//\n// In addition to using that new logger instance, callers also must call the\n// returned function.\n//\n// If the underlying log implementation supports a WithCallDepth(int) method,\n// WithCallDepth(1) will be called to produce a new logger. If it supports a\n// WithCallStackHelper() method, that will be also called. If the\n// implementation does not support either of these, the original Logger will be\n// returned.\nfunc (l Logger) WithCallStackHelper() (func(), Logger) {\n\tif l.sink == nil {\n\t\treturn func() {}, l\n\t}\n\tvar helper func()\n\tif withCallDepth, ok := l.sink.(CallDepthLogSink); ok {\n\t\tl.setSink(withCallDepth.WithCallDepth(1))\n\t}\n\tif withHelper, ok := l.sink.(CallStackHelperLogSink); ok {\n\t\thelper = withHelper.GetCallStackHelper()\n\t} else {\n\t\thelper = func() {}\n\t}\n\treturn helper, l\n}\n\n// IsZero returns true if this logger is an uninitialized zero value\nfunc (l Logger) IsZero() bool {\n\treturn l.sink == nil\n}\n\n// RuntimeInfo holds information that the logr \"core\" library knows which\n// LogSinks might want to know.\ntype RuntimeInfo struct {\n\t// CallDepth is the number of call frames the logr library adds between the\n\t// end-user and the LogSink.  LogSink implementations which choose to print\n\t// the original logging site (e.g. file & line) should climb this many\n\t// additional frames to find it.\n\tCallDepth int\n}\n\n// runtimeInfo is a static global.  It must not be changed at run time.\nvar runtimeInfo = RuntimeInfo{\n\tCallDepth: 1,\n}\n\n// LogSink represents a logging implementation.  End-users will generally not\n// interact with this type.\ntype LogSink interface {\n\t// Init receives optional information about the logr library for LogSink\n\t// implementations that need it.\n\tInit(info RuntimeInfo)\n\n\t// Enabled tests whether this LogSink is enabled at the specified V-level.\n\t// For example, commandline flags might be used to set the logging\n\t// verbosity and disable some info logs.\n\tEnabled(level int) bool\n\n\t// Info logs a non-error message with the given key/value pairs as context.\n\t// The level argument is provided for optional logging.  This method will\n\t// only be called when Enabled(level) is true. See Logger.Info for more\n\t// details.\n\tInfo(level int, msg string, keysAndValues ...any)\n\n\t// Error logs an error, with the given message and key/value pairs as\n\t// context.  See Logger.Error for more details.\n\tError(err error, msg string, keysAndValues ...any)\n\n\t// WithValues returns a new LogSink with additional key/value pairs.  See\n\t// Logger.WithValues for more details.\n\tWithValues(keysAndValues ...any) LogSink\n\n\t// WithName returns a new LogSink with the specified name appended.  See\n\t// Logger.WithName for more details.\n\tWithName(name string) LogSink\n}\n\n// CallDepthLogSink represents a LogSink that knows how to climb the call stack\n// to identify the original call site and can offset the depth by a specified\n// number of frames.  This is useful for users who have helper functions\n// between the \"real\" call site and the actual calls to Logger methods.\n// Implementations that log information about the call site (such as file,\n// function, or line) would otherwise log information about the intermediate\n// helper functions.\n//\n// This is an optional interface and implementations are not required to\n// support it.\ntype CallDepthLogSink interface {\n\t// WithCallDepth returns a LogSink that will offset the call\n\t// stack by the specified number of frames when logging call\n\t// site information.\n\t//\n\t// If depth is 0, the LogSink should skip exactly the number\n\t// of call frames defined in RuntimeInfo.CallDepth when Info\n\t// or Error are called, i.e. the attribution should be to the\n\t// direct caller of Logger.Info or Logger.Error.\n\t//\n\t// If depth is 1 the attribution should skip 1 call frame, and so on.\n\t// Successive calls to this are additive.\n\tWithCallDepth(depth int) LogSink\n}\n\n// CallStackHelperLogSink represents a LogSink that knows how to climb\n// the call stack to identify the original call site and can skip\n// intermediate helper functions if they mark themselves as\n// helper. Go's testing package uses that approach.\n//\n// This is useful for users who have helper functions between the\n// \"real\" call site and the actual calls to Logger methods.\n// Implementations that log information about the call site (such as\n// file, function, or line) would otherwise log information about the\n// intermediate helper functions.\n//\n// This is an optional interface and implementations are not required\n// to support it. Implementations that choose to support this must not\n// simply implement it as WithCallDepth(1), because\n// Logger.WithCallStackHelper will call both methods if they are\n// present. This should only be implemented for LogSinks that actually\n// need it, as with testing.T.\ntype CallStackHelperLogSink interface {\n\t// GetCallStackHelper returns a function that must be called\n\t// to mark the direct caller as helper function when logging\n\t// call site information.\n\tGetCallStackHelper() func()\n}\n\n// Marshaler is an optional interface that logged values may choose to\n// implement. Loggers with structured output, such as JSON, should\n// log the object return by the MarshalLog method instead of the\n// original value.\ntype Marshaler interface {\n\t// MarshalLog can be used to:\n\t//   - ensure that structs are not logged as strings when the original\n\t//     value has a String method: return a different type without a\n\t//     String method\n\t//   - select which fields of a complex type should get logged:\n\t//     return a simpler struct with fewer fields\n\t//   - log unexported fields: return a different struct\n\t//     with exported fields\n\t//\n\t// It may return any value of any type.\n\tMarshalLog() any\n}\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/sloghandler.go",
    "content": "//go:build go1.21\n// +build go1.21\n\n/*\nCopyright 2023 The logr Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage logr\n\nimport (\n\t\"context\"\n\t\"log/slog\"\n)\n\ntype slogHandler struct {\n\t// May be nil, in which case all logs get discarded.\n\tsink LogSink\n\t// Non-nil if sink is non-nil and implements SlogSink.\n\tslogSink SlogSink\n\n\t// groupPrefix collects values from WithGroup calls. It gets added as\n\t// prefix to value keys when handling a log record.\n\tgroupPrefix string\n\n\t// levelBias can be set when constructing the handler to influence the\n\t// slog.Level of log records. A positive levelBias reduces the\n\t// slog.Level value. slog has no API to influence this value after the\n\t// handler got created, so it can only be set indirectly through\n\t// Logger.V.\n\tlevelBias slog.Level\n}\n\nvar _ slog.Handler = &slogHandler{}\n\n// groupSeparator is used to concatenate WithGroup names and attribute keys.\nconst groupSeparator = \".\"\n\n// GetLevel is used for black box unit testing.\nfunc (l *slogHandler) GetLevel() slog.Level {\n\treturn l.levelBias\n}\n\nfunc (l *slogHandler) Enabled(_ context.Context, level slog.Level) bool {\n\treturn l.sink != nil && (level >= slog.LevelError || l.sink.Enabled(l.levelFromSlog(level)))\n}\n\nfunc (l *slogHandler) Handle(ctx context.Context, record slog.Record) error {\n\tif l.slogSink != nil {\n\t\t// Only adjust verbosity level of log entries < slog.LevelError.\n\t\tif record.Level < slog.LevelError {\n\t\t\trecord.Level -= l.levelBias\n\t\t}\n\t\treturn l.slogSink.Handle(ctx, record)\n\t}\n\n\t// No need to check for nil sink here because Handle will only be called\n\t// when Enabled returned true.\n\n\tkvList := make([]any, 0, 2*record.NumAttrs())\n\trecord.Attrs(func(attr slog.Attr) bool {\n\t\tkvList = attrToKVs(attr, l.groupPrefix, kvList)\n\t\treturn true\n\t})\n\tif record.Level >= slog.LevelError {\n\t\tl.sinkWithCallDepth().Error(nil, record.Message, kvList...)\n\t} else {\n\t\tlevel := l.levelFromSlog(record.Level)\n\t\tl.sinkWithCallDepth().Info(level, record.Message, kvList...)\n\t}\n\treturn nil\n}\n\n// sinkWithCallDepth adjusts the stack unwinding so that when Error or Info\n// are called by Handle, code in slog gets skipped.\n//\n// This offset currently (Go 1.21.0) works for calls through\n// slog.New(ToSlogHandler(...)).  There's no guarantee that the call\n// chain won't change. Wrapping the handler will also break unwinding. It's\n// still better than not adjusting at all....\n//\n// This cannot be done when constructing the handler because FromSlogHandler needs\n// access to the original sink without this adjustment. A second copy would\n// work, but then WithAttrs would have to be called for both of them.\nfunc (l *slogHandler) sinkWithCallDepth() LogSink {\n\tif sink, ok := l.sink.(CallDepthLogSink); ok {\n\t\treturn sink.WithCallDepth(2)\n\t}\n\treturn l.sink\n}\n\nfunc (l *slogHandler) WithAttrs(attrs []slog.Attr) slog.Handler {\n\tif l.sink == nil || len(attrs) == 0 {\n\t\treturn l\n\t}\n\n\tclone := *l\n\tif l.slogSink != nil {\n\t\tclone.slogSink = l.slogSink.WithAttrs(attrs)\n\t\tclone.sink = clone.slogSink\n\t} else {\n\t\tkvList := make([]any, 0, 2*len(attrs))\n\t\tfor _, attr := range attrs {\n\t\t\tkvList = attrToKVs(attr, l.groupPrefix, kvList)\n\t\t}\n\t\tclone.sink = l.sink.WithValues(kvList...)\n\t}\n\treturn &clone\n}\n\nfunc (l *slogHandler) WithGroup(name string) slog.Handler {\n\tif l.sink == nil {\n\t\treturn l\n\t}\n\tif name == \"\" {\n\t\t// slog says to inline empty groups\n\t\treturn l\n\t}\n\tclone := *l\n\tif l.slogSink != nil {\n\t\tclone.slogSink = l.slogSink.WithGroup(name)\n\t\tclone.sink = clone.slogSink\n\t} else {\n\t\tclone.groupPrefix = addPrefix(clone.groupPrefix, name)\n\t}\n\treturn &clone\n}\n\n// attrToKVs appends a slog.Attr to a logr-style kvList.  It handle slog Groups\n// and other details of slog.\nfunc attrToKVs(attr slog.Attr, groupPrefix string, kvList []any) []any {\n\tattrVal := attr.Value.Resolve()\n\tif attrVal.Kind() == slog.KindGroup {\n\t\tgroupVal := attrVal.Group()\n\t\tgrpKVs := make([]any, 0, 2*len(groupVal))\n\t\tprefix := groupPrefix\n\t\tif attr.Key != \"\" {\n\t\t\tprefix = addPrefix(groupPrefix, attr.Key)\n\t\t}\n\t\tfor _, attr := range groupVal {\n\t\t\tgrpKVs = attrToKVs(attr, prefix, grpKVs)\n\t\t}\n\t\tkvList = append(kvList, grpKVs...)\n\t} else if attr.Key != \"\" {\n\t\tkvList = append(kvList, addPrefix(groupPrefix, attr.Key), attrVal.Any())\n\t}\n\n\treturn kvList\n}\n\nfunc addPrefix(prefix, name string) string {\n\tif prefix == \"\" {\n\t\treturn name\n\t}\n\tif name == \"\" {\n\t\treturn prefix\n\t}\n\treturn prefix + groupSeparator + name\n}\n\n// levelFromSlog adjusts the level by the logger's verbosity and negates it.\n// It ensures that the result is >= 0. This is necessary because the result is\n// passed to a LogSink and that API did not historically document whether\n// levels could be negative or what that meant.\n//\n// Some example usage:\n//\n//\tlogrV0 := getMyLogger()\n//\tlogrV2 := logrV0.V(2)\n//\tslogV2 := slog.New(logr.ToSlogHandler(logrV2))\n//\tslogV2.Debug(\"msg\") // =~ logrV2.V(4) =~ logrV0.V(6)\n//\tslogV2.Info(\"msg\")  // =~  logrV2.V(0) =~ logrV0.V(2)\n//\tslogv2.Warn(\"msg\")  // =~ logrV2.V(-4) =~ logrV0.V(0)\nfunc (l *slogHandler) levelFromSlog(level slog.Level) int {\n\tresult := -level\n\tresult += l.levelBias // in case the original Logger had a V level\n\tif result < 0 {\n\t\tresult = 0 // because LogSink doesn't expect negative V levels\n\t}\n\treturn int(result)\n}\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/slogr.go",
    "content": "//go:build go1.21\n// +build go1.21\n\n/*\nCopyright 2023 The logr Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage logr\n\nimport (\n\t\"context\"\n\t\"log/slog\"\n)\n\n// FromSlogHandler returns a Logger which writes to the slog.Handler.\n//\n// The logr verbosity level is mapped to slog levels such that V(0) becomes\n// slog.LevelInfo and V(4) becomes slog.LevelDebug.\nfunc FromSlogHandler(handler slog.Handler) Logger {\n\tif handler, ok := handler.(*slogHandler); ok {\n\t\tif handler.sink == nil {\n\t\t\treturn Discard()\n\t\t}\n\t\treturn New(handler.sink).V(int(handler.levelBias))\n\t}\n\treturn New(&slogSink{handler: handler})\n}\n\n// ToSlogHandler returns a slog.Handler which writes to the same sink as the Logger.\n//\n// The returned logger writes all records with level >= slog.LevelError as\n// error log entries with LogSink.Error, regardless of the verbosity level of\n// the Logger:\n//\n//\tlogger := <some Logger with 0 as verbosity level>\n//\tslog.New(ToSlogHandler(logger.V(10))).Error(...) -> logSink.Error(...)\n//\n// The level of all other records gets reduced by the verbosity\n// level of the Logger and the result is negated. If it happens\n// to be negative, then it gets replaced by zero because a LogSink\n// is not expected to handled negative levels:\n//\n//\tslog.New(ToSlogHandler(logger)).Debug(...) -> logger.GetSink().Info(level=4, ...)\n//\tslog.New(ToSlogHandler(logger)).Warning(...) -> logger.GetSink().Info(level=0, ...)\n//\tslog.New(ToSlogHandler(logger)).Info(...) -> logger.GetSink().Info(level=0, ...)\n//\tslog.New(ToSlogHandler(logger.V(4))).Info(...) -> logger.GetSink().Info(level=4, ...)\nfunc ToSlogHandler(logger Logger) slog.Handler {\n\tif sink, ok := logger.GetSink().(*slogSink); ok && logger.GetV() == 0 {\n\t\treturn sink.handler\n\t}\n\n\thandler := &slogHandler{sink: logger.GetSink(), levelBias: slog.Level(logger.GetV())}\n\tif slogSink, ok := handler.sink.(SlogSink); ok {\n\t\thandler.slogSink = slogSink\n\t}\n\treturn handler\n}\n\n// SlogSink is an optional interface that a LogSink can implement to support\n// logging through the slog.Logger or slog.Handler APIs better. It then should\n// also support special slog values like slog.Group. When used as a\n// slog.Handler, the advantages are:\n//\n//   - stack unwinding gets avoided in favor of logging the pre-recorded PC,\n//     as intended by slog\n//   - proper grouping of key/value pairs via WithGroup\n//   - verbosity levels > slog.LevelInfo can be recorded\n//   - less overhead\n//\n// Both APIs (Logger and slog.Logger/Handler) then are supported equally\n// well. Developers can pick whatever API suits them better and/or mix\n// packages which use either API in the same binary with a common logging\n// implementation.\n//\n// This interface is necessary because the type implementing the LogSink\n// interface cannot also implement the slog.Handler interface due to the\n// different prototype of the common Enabled method.\n//\n// An implementation could support both interfaces in two different types, but then\n// additional interfaces would be needed to convert between those types in FromSlogHandler\n// and ToSlogHandler.\ntype SlogSink interface {\n\tLogSink\n\n\tHandle(ctx context.Context, record slog.Record) error\n\tWithAttrs(attrs []slog.Attr) SlogSink\n\tWithGroup(name string) SlogSink\n}\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/slogsink.go",
    "content": "//go:build go1.21\n// +build go1.21\n\n/*\nCopyright 2023 The logr Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage logr\n\nimport (\n\t\"context\"\n\t\"log/slog\"\n\t\"runtime\"\n\t\"time\"\n)\n\nvar (\n\t_ LogSink          = &slogSink{}\n\t_ CallDepthLogSink = &slogSink{}\n\t_ Underlier        = &slogSink{}\n)\n\n// Underlier is implemented by the LogSink returned by NewFromLogHandler.\ntype Underlier interface {\n\t// GetUnderlying returns the Handler used by the LogSink.\n\tGetUnderlying() slog.Handler\n}\n\nconst (\n\t// nameKey is used to log the `WithName` values as an additional attribute.\n\tnameKey = \"logger\"\n\n\t// errKey is used to log the error parameter of Error as an additional attribute.\n\terrKey = \"err\"\n)\n\ntype slogSink struct {\n\tcallDepth int\n\tname      string\n\thandler   slog.Handler\n}\n\nfunc (l *slogSink) Init(info RuntimeInfo) {\n\tl.callDepth = info.CallDepth\n}\n\nfunc (l *slogSink) GetUnderlying() slog.Handler {\n\treturn l.handler\n}\n\nfunc (l *slogSink) WithCallDepth(depth int) LogSink {\n\tnewLogger := *l\n\tnewLogger.callDepth += depth\n\treturn &newLogger\n}\n\nfunc (l *slogSink) Enabled(level int) bool {\n\treturn l.handler.Enabled(context.Background(), slog.Level(-level))\n}\n\nfunc (l *slogSink) Info(level int, msg string, kvList ...interface{}) {\n\tl.log(nil, msg, slog.Level(-level), kvList...)\n}\n\nfunc (l *slogSink) Error(err error, msg string, kvList ...interface{}) {\n\tl.log(err, msg, slog.LevelError, kvList...)\n}\n\nfunc (l *slogSink) log(err error, msg string, level slog.Level, kvList ...interface{}) {\n\tvar pcs [1]uintptr\n\t// skip runtime.Callers, this function, Info/Error, and all helper functions above that.\n\truntime.Callers(3+l.callDepth, pcs[:])\n\n\trecord := slog.NewRecord(time.Now(), level, msg, pcs[0])\n\tif l.name != \"\" {\n\t\trecord.AddAttrs(slog.String(nameKey, l.name))\n\t}\n\tif err != nil {\n\t\trecord.AddAttrs(slog.Any(errKey, err))\n\t}\n\trecord.Add(kvList...)\n\t_ = l.handler.Handle(context.Background(), record)\n}\n\nfunc (l slogSink) WithName(name string) LogSink {\n\tif l.name != \"\" {\n\t\tl.name += \"/\"\n\t}\n\tl.name += name\n\treturn &l\n}\n\nfunc (l slogSink) WithValues(kvList ...interface{}) LogSink {\n\tl.handler = l.handler.WithAttrs(kvListToAttrs(kvList...))\n\treturn &l\n}\n\nfunc kvListToAttrs(kvList ...interface{}) []slog.Attr {\n\t// We don't need the record itself, only its Add method.\n\trecord := slog.NewRecord(time.Time{}, 0, \"\", 0)\n\trecord.Add(kvList...)\n\tattrs := make([]slog.Attr, 0, record.NumAttrs())\n\trecord.Attrs(func(attr slog.Attr) bool {\n\t\tattrs = append(attrs, attr)\n\t\treturn true\n\t})\n\treturn attrs\n}\n"
  },
  {
    "path": "vendor/github.com/go-logr/stdr/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/github.com/go-logr/stdr/README.md",
    "content": "# Minimal Go logging using logr and Go's standard library\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/stdr.svg)](https://pkg.go.dev/github.com/go-logr/stdr)\n\nThis package implements the [logr interface](https://github.com/go-logr/logr)\nin terms of Go's standard log package(https://pkg.go.dev/log).\n"
  },
  {
    "path": "vendor/github.com/go-logr/stdr/stdr.go",
    "content": "/*\nCopyright 2019 The logr Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Package stdr implements github.com/go-logr/logr.Logger in terms of\n// Go's standard log package.\npackage stdr\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"github.com/go-logr/logr\"\n\t\"github.com/go-logr/logr/funcr\"\n)\n\n// The global verbosity level.  See SetVerbosity().\nvar globalVerbosity int\n\n// SetVerbosity sets the global level against which all info logs will be\n// compared.  If this is greater than or equal to the \"V\" of the logger, the\n// message will be logged.  A higher value here means more logs will be written.\n// The previous verbosity value is returned.  This is not concurrent-safe -\n// callers must be sure to call it from only one goroutine.\nfunc SetVerbosity(v int) int {\n\told := globalVerbosity\n\tglobalVerbosity = v\n\treturn old\n}\n\n// New returns a logr.Logger which is implemented by Go's standard log package,\n// or something like it.  If std is nil, this will use a default logger\n// instead.\n//\n// Example: stdr.New(log.New(os.Stderr, \"\", log.LstdFlags|log.Lshortfile)))\nfunc New(std StdLogger) logr.Logger {\n\treturn NewWithOptions(std, Options{})\n}\n\n// NewWithOptions returns a logr.Logger which is implemented by Go's standard\n// log package, or something like it.  See New for details.\nfunc NewWithOptions(std StdLogger, opts Options) logr.Logger {\n\tif std == nil {\n\t\t// Go's log.Default() is only available in 1.16 and higher.\n\t\tstd = log.New(os.Stderr, \"\", log.LstdFlags)\n\t}\n\n\tif opts.Depth < 0 {\n\t\topts.Depth = 0\n\t}\n\n\tfopts := funcr.Options{\n\t\tLogCaller: funcr.MessageClass(opts.LogCaller),\n\t}\n\n\tsl := &logger{\n\t\tFormatter: funcr.NewFormatter(fopts),\n\t\tstd:       std,\n\t}\n\n\t// For skipping our own logger.Info/Error.\n\tsl.Formatter.AddCallDepth(1 + opts.Depth)\n\n\treturn logr.New(sl)\n}\n\n// Options carries parameters which influence the way logs are generated.\ntype Options struct {\n\t// Depth biases the assumed number of call frames to the \"true\" caller.\n\t// This is useful when the calling code calls a function which then calls\n\t// stdr (e.g. a logging shim to another API).  Values less than zero will\n\t// be treated as zero.\n\tDepth int\n\n\t// LogCaller tells stdr to add a \"caller\" key to some or all log lines.\n\t// Go's log package has options to log this natively, too.\n\tLogCaller MessageClass\n\n\t// TODO: add an option to log the date/time\n}\n\n// MessageClass indicates which category or categories of messages to consider.\ntype MessageClass int\n\nconst (\n\t// None ignores all message classes.\n\tNone MessageClass = iota\n\t// All considers all message classes.\n\tAll\n\t// Info only considers info messages.\n\tInfo\n\t// Error only considers error messages.\n\tError\n)\n\n// StdLogger is the subset of the Go stdlib log.Logger API that is needed for\n// this adapter.\ntype StdLogger interface {\n\t// Output is the same as log.Output and log.Logger.Output.\n\tOutput(calldepth int, logline string) error\n}\n\ntype logger struct {\n\tfuncr.Formatter\n\tstd StdLogger\n}\n\nvar _ logr.LogSink = &logger{}\nvar _ logr.CallDepthLogSink = &logger{}\n\nfunc (l logger) Enabled(level int) bool {\n\treturn globalVerbosity >= level\n}\n\nfunc (l logger) Info(level int, msg string, kvList ...interface{}) {\n\tprefix, args := l.FormatInfo(level, msg, kvList)\n\tif prefix != \"\" {\n\t\targs = prefix + \": \" + args\n\t}\n\t_ = l.std.Output(l.Formatter.GetDepth()+1, args)\n}\n\nfunc (l logger) Error(err error, msg string, kvList ...interface{}) {\n\tprefix, args := l.FormatError(err, msg, kvList)\n\tif prefix != \"\" {\n\t\targs = prefix + \": \" + args\n\t}\n\t_ = l.std.Output(l.Formatter.GetDepth()+1, args)\n}\n\nfunc (l logger) WithName(name string) logr.LogSink {\n\tl.Formatter.AddName(name)\n\treturn &l\n}\n\nfunc (l logger) WithValues(kvList ...interface{}) logr.LogSink {\n\tl.Formatter.AddValues(kvList)\n\treturn &l\n}\n\nfunc (l logger) WithCallDepth(depth int) logr.LogSink {\n\tl.Formatter.AddCallDepth(depth)\n\treturn &l\n}\n\n// Underlier exposes access to the underlying logging implementation.  Since\n// callers only have a logr.Logger, they have to know which implementation is\n// in use, so this interface is less of an abstraction and more of way to test\n// type conversion.\ntype Underlier interface {\n\tGetUnderlying() StdLogger\n}\n\n// GetUnderlying returns the StdLogger underneath this logger.  Since StdLogger\n// is itself an interface, the result may or may not be a Go log.Logger.\nfunc (l logger) GetUnderlying() StdLogger {\n\treturn l.std\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/httphead/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2017 Sergey Kamardin\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": "vendor/github.com/gobwas/httphead/README.md",
    "content": "# httphead.[go](https://golang.org)\n\n[![GoDoc][godoc-image]][godoc-url] \n\n> Tiny HTTP header value parsing library in go.\n\n## Overview\n\nThis library contains low-level functions for scanning HTTP RFC2616 compatible header value grammars.\n\n## Install\n\n```shell\n    go get github.com/gobwas/httphead\n```\n\n## Example\n\nThe example below shows how multiple-choise HTTP header value could be parsed with this library:\n\n```go\n\toptions, ok := httphead.ParseOptions([]byte(`foo;bar=1,baz`), nil)\n\tfmt.Println(options, ok)\n\t// Output: [{foo map[bar:1]} {baz map[]}] true\n```\n\nThe low-level example below shows how to optimize keys skipping and selection\nof some key:\n\n```go\n\t// The right part of full header line like:\n\t// X-My-Header: key;foo=bar;baz,key;baz\n\theader := []byte(`foo;a=0,foo;a=1,foo;a=2,foo;a=3`)\n\n\t// We want to search key \"foo\" with an \"a\" parameter that equal to \"2\".\n\tvar (\n\t\tfoo = []byte(`foo`)\n\t\ta   = []byte(`a`)\n\t\tv   = []byte(`2`)\n\t)\n\tvar found bool\n\thttphead.ScanOptions(header, func(i int, key, param, value []byte) Control {\n\t\tif !bytes.Equal(key, foo) {\n\t\t\treturn ControlSkip\n\t\t}\n\t\tif !bytes.Equal(param, a) {\n\t\t\tif bytes.Equal(value, v) {\n\t\t\t\t// Found it!\n\t\t\t\tfound = true\n\t\t\t\treturn ControlBreak\n\t\t\t}\n\t\t\treturn ControlSkip\n\t\t}\n\t\treturn ControlContinue\n\t})\n```\n\nFor more usage examples please see [docs][godoc-url] or package tests.\n\n[godoc-image]: https://godoc.org/github.com/gobwas/httphead?status.svg\n[godoc-url]: https://godoc.org/github.com/gobwas/httphead\n[travis-image]: https://travis-ci.org/gobwas/httphead.svg?branch=master\n[travis-url]: https://travis-ci.org/gobwas/httphead\n"
  },
  {
    "path": "vendor/github.com/gobwas/httphead/cookie.go",
    "content": "package httphead\n\nimport (\n\t\"bytes\"\n)\n\n// ScanCookie scans cookie pairs from data using DefaultCookieScanner.Scan()\n// method.\nfunc ScanCookie(data []byte, it func(key, value []byte) bool) bool {\n\treturn DefaultCookieScanner.Scan(data, it)\n}\n\n// DefaultCookieScanner is a CookieScanner which is used by ScanCookie().\n// Note that it is intended to have the same behavior as http.Request.Cookies()\n// has.\nvar DefaultCookieScanner = CookieScanner{}\n\n// CookieScanner contains options for scanning cookie pairs.\n// See https://tools.ietf.org/html/rfc6265#section-4.1.1\ntype CookieScanner struct {\n\t// DisableNameValidation disables name validation of a cookie. If false,\n\t// only RFC2616 \"tokens\" are accepted.\n\tDisableNameValidation bool\n\n\t// DisableValueValidation disables value validation of a cookie. If false,\n\t// only RFC6265 \"cookie-octet\" characters are accepted.\n\t//\n\t// Note that Strict option also affects validation of a value.\n\t//\n\t// If Strict is false, then scanner begins to allow space and comma\n\t// characters inside the value for better compatibility with non standard\n\t// cookies implementations.\n\tDisableValueValidation bool\n\n\t// BreakOnPairError sets scanner to immediately return after first pair syntax\n\t// validation error.\n\t// If false, scanner will try to skip invalid pair bytes and go ahead.\n\tBreakOnPairError bool\n\n\t// Strict enables strict RFC6265 mode scanning. It affects name and value\n\t// validation, as also some other rules.\n\t// If false, it is intended to bring the same behavior as\n\t// http.Request.Cookies().\n\tStrict bool\n}\n\n// Scan maps data to name and value pairs. Usually data represents value of the\n// Cookie header.\nfunc (c CookieScanner) Scan(data []byte, it func(name, value []byte) bool) bool {\n\tlexer := &Scanner{data: data}\n\n\tconst (\n\t\tstatePair = iota\n\t\tstateBefore\n\t)\n\n\tstate := statePair\n\n\tfor lexer.Buffered() > 0 {\n\t\tswitch state {\n\t\tcase stateBefore:\n\t\t\t// Pairs separated by \";\" and space, according to the RFC6265:\n\t\t\t//   cookie-pair *( \";\" SP cookie-pair )\n\t\t\t//\n\t\t\t// Cookie pairs MUST be separated by (\";\" SP). So our only option\n\t\t\t// here is to fail as syntax error.\n\t\t\ta, b := lexer.Peek2()\n\t\t\tif a != ';' {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tstate = statePair\n\n\t\t\tadvance := 1\n\t\t\tif b == ' ' {\n\t\t\t\tadvance++\n\t\t\t} else if c.Strict {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tlexer.Advance(advance)\n\n\t\tcase statePair:\n\t\t\tif !lexer.FetchUntil(';') {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tvar value []byte\n\t\t\tname := lexer.Bytes()\n\t\t\tif i := bytes.IndexByte(name, '='); i != -1 {\n\t\t\t\tvalue = name[i+1:]\n\t\t\t\tname = name[:i]\n\t\t\t} else if c.Strict {\n\t\t\t\tif !c.BreakOnPairError {\n\t\t\t\t\tgoto nextPair\n\t\t\t\t}\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tif !c.Strict {\n\t\t\t\ttrimLeft(name)\n\t\t\t}\n\t\t\tif !c.DisableNameValidation && !ValidCookieName(name) {\n\t\t\t\tif !c.BreakOnPairError {\n\t\t\t\t\tgoto nextPair\n\t\t\t\t}\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tif !c.Strict {\n\t\t\t\tvalue = trimRight(value)\n\t\t\t}\n\t\t\tvalue = stripQuotes(value)\n\t\t\tif !c.DisableValueValidation && !ValidCookieValue(value, c.Strict) {\n\t\t\t\tif !c.BreakOnPairError {\n\t\t\t\t\tgoto nextPair\n\t\t\t\t}\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tif !it(name, value) {\n\t\t\t\treturn true\n\t\t\t}\n\n\t\tnextPair:\n\t\t\tstate = stateBefore\n\t\t}\n\t}\n\n\treturn true\n}\n\n// ValidCookieValue reports whether given value is a valid RFC6265\n// \"cookie-octet\" bytes.\n//\n// cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E\n//                ; US-ASCII characters excluding CTLs,\n//                ; whitespace DQUOTE, comma, semicolon,\n//                ; and backslash\n//\n// Note that the false strict parameter disables errors on space 0x20 and comma\n// 0x2c. This could be useful to bring some compatibility with non-compliant\n// clients/servers in the real world.\n// It acts the same as standard library cookie parser if strict is false.\nfunc ValidCookieValue(value []byte, strict bool) bool {\n\tif len(value) == 0 {\n\t\treturn true\n\t}\n\tfor _, c := range value {\n\t\tswitch c {\n\t\tcase '\"', ';', '\\\\':\n\t\t\treturn false\n\t\tcase ',', ' ':\n\t\t\tif strict {\n\t\t\t\treturn false\n\t\t\t}\n\t\tdefault:\n\t\t\tif c <= 0x20 {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif c >= 0x7f {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\n// ValidCookieName reports wheter given bytes is a valid RFC2616 \"token\" bytes.\nfunc ValidCookieName(name []byte) bool {\n\tfor _, c := range name {\n\t\tif !OctetTypes[c].IsToken() {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc stripQuotes(bts []byte) []byte {\n\tif last := len(bts) - 1; last > 0 && bts[0] == '\"' && bts[last] == '\"' {\n\t\treturn bts[1:last]\n\t}\n\treturn bts\n}\n\nfunc trimLeft(p []byte) []byte {\n\tvar i int\n\tfor i < len(p) && OctetTypes[p[i]].IsSpace() {\n\t\ti++\n\t}\n\treturn p[i:]\n}\n\nfunc trimRight(p []byte) []byte {\n\tj := len(p)\n\tfor j > 0 && OctetTypes[p[j-1]].IsSpace() {\n\t\tj--\n\t}\n\treturn p[:j]\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/httphead/head.go",
    "content": "package httphead\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n)\n\n// Version contains protocol major and minor version.\ntype Version struct {\n\tMajor int\n\tMinor int\n}\n\n// RequestLine contains parameters parsed from the first request line.\ntype RequestLine struct {\n\tMethod  []byte\n\tURI     []byte\n\tVersion Version\n}\n\n// ResponseLine contains parameters parsed from the first response line.\ntype ResponseLine struct {\n\tVersion Version\n\tStatus  int\n\tReason  []byte\n}\n\n// SplitRequestLine splits given slice of bytes into three chunks without\n// parsing.\nfunc SplitRequestLine(line []byte) (method, uri, version []byte) {\n\treturn split3(line, ' ')\n}\n\n// ParseRequestLine parses http request line like \"GET / HTTP/1.0\".\nfunc ParseRequestLine(line []byte) (r RequestLine, ok bool) {\n\tvar i int\n\tfor i = 0; i < len(line); i++ {\n\t\tc := line[i]\n\t\tif !OctetTypes[c].IsToken() {\n\t\t\tif i > 0 && c == ' ' {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n\tif i == len(line) {\n\t\treturn\n\t}\n\n\tvar proto []byte\n\tr.Method = line[:i]\n\tr.URI, proto = split2(line[i+1:], ' ')\n\tif len(r.URI) == 0 {\n\t\treturn\n\t}\n\tif major, minor, ok := ParseVersion(proto); ok {\n\t\tr.Version.Major = major\n\t\tr.Version.Minor = minor\n\t\treturn r, true\n\t}\n\n\treturn r, false\n}\n\n// SplitResponseLine splits given slice of bytes into three chunks without\n// parsing.\nfunc SplitResponseLine(line []byte) (version, status, reason []byte) {\n\treturn split3(line, ' ')\n}\n\n// ParseResponseLine parses first response line into ResponseLine struct.\nfunc ParseResponseLine(line []byte) (r ResponseLine, ok bool) {\n\tvar (\n\t\tproto  []byte\n\t\tstatus []byte\n\t)\n\tproto, status, r.Reason = split3(line, ' ')\n\tif major, minor, ok := ParseVersion(proto); ok {\n\t\tr.Version.Major = major\n\t\tr.Version.Minor = minor\n\t} else {\n\t\treturn r, false\n\t}\n\tif n, ok := IntFromASCII(status); ok {\n\t\tr.Status = n\n\t} else {\n\t\treturn r, false\n\t}\n\t// TODO(gobwas): parse here r.Reason fot TEXT rule:\n\t//   TEXT = <any OCTET except CTLs,\n\t//           but including LWS>\n\treturn r, true\n}\n\nvar (\n\thttpVersion10     = []byte(\"HTTP/1.0\")\n\thttpVersion11     = []byte(\"HTTP/1.1\")\n\thttpVersionPrefix = []byte(\"HTTP/\")\n)\n\n// ParseVersion parses major and minor version of HTTP protocol.\n// It returns parsed values and true if parse is ok.\nfunc ParseVersion(bts []byte) (major, minor int, ok bool) {\n\tswitch {\n\tcase bytes.Equal(bts, httpVersion11):\n\t\treturn 1, 1, true\n\tcase bytes.Equal(bts, httpVersion10):\n\t\treturn 1, 0, true\n\tcase len(bts) < 8:\n\t\treturn\n\tcase !bytes.Equal(bts[:5], httpVersionPrefix):\n\t\treturn\n\t}\n\n\tbts = bts[5:]\n\n\tdot := bytes.IndexByte(bts, '.')\n\tif dot == -1 {\n\t\treturn\n\t}\n\tmajor, ok = IntFromASCII(bts[:dot])\n\tif !ok {\n\t\treturn\n\t}\n\tminor, ok = IntFromASCII(bts[dot+1:])\n\tif !ok {\n\t\treturn\n\t}\n\n\treturn major, minor, true\n}\n\n// ReadLine reads line from br. It reads until '\\n' and returns bytes without\n// '\\n' or '\\r\\n' at the end.\n// It returns err if and only if line does not end in '\\n'. Note that read\n// bytes returned in any case of error.\n//\n// It is much like the textproto/Reader.ReadLine() except the thing that it\n// returns raw bytes, instead of string. That is, it avoids copying bytes read\n// from br.\n//\n// textproto/Reader.ReadLineBytes() is also makes copy of resulting bytes to be\n// safe with future I/O operations on br.\n//\n// We could control I/O operations on br and do not need to make additional\n// copy for safety.\nfunc ReadLine(br *bufio.Reader) ([]byte, error) {\n\tvar line []byte\n\tfor {\n\t\tbts, err := br.ReadSlice('\\n')\n\t\tif err == bufio.ErrBufferFull {\n\t\t\t// Copy bytes because next read will discard them.\n\t\t\tline = append(line, bts...)\n\t\t\tcontinue\n\t\t}\n\t\t// Avoid copy of single read.\n\t\tif line == nil {\n\t\t\tline = bts\n\t\t} else {\n\t\t\tline = append(line, bts...)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn line, err\n\t\t}\n\t\t// Size of line is at least 1.\n\t\t// In other case bufio.ReadSlice() returns error.\n\t\tn := len(line)\n\t\t// Cut '\\n' or '\\r\\n'.\n\t\tif n > 1 && line[n-2] == '\\r' {\n\t\t\tline = line[:n-2]\n\t\t} else {\n\t\t\tline = line[:n-1]\n\t\t}\n\t\treturn line, nil\n\t}\n}\n\n// ParseHeaderLine parses HTTP header as key-value pair. It returns parsed\n// values and true if parse is ok.\nfunc ParseHeaderLine(line []byte) (k, v []byte, ok bool) {\n\tcolon := bytes.IndexByte(line, ':')\n\tif colon == -1 {\n\t\treturn\n\t}\n\tk = trim(line[:colon])\n\tfor _, c := range k {\n\t\tif !OctetTypes[c].IsToken() {\n\t\t\treturn nil, nil, false\n\t\t}\n\t}\n\tv = trim(line[colon+1:])\n\treturn k, v, true\n}\n\n// IntFromASCII converts ascii encoded decimal numeric value from HTTP entities\n// to an integer.\nfunc IntFromASCII(bts []byte) (ret int, ok bool) {\n\t// ASCII numbers all start with the high-order bits 0011.\n\t// If you see that, and the next bits are 0-9 (0000 - 1001) you can grab those\n\t// bits and interpret them directly as an integer.\n\tvar n int\n\tif n = len(bts); n < 1 {\n\t\treturn 0, false\n\t}\n\tfor i := 0; i < n; i++ {\n\t\tif bts[i]&0xf0 != 0x30 {\n\t\t\treturn 0, false\n\t\t}\n\t\tret += int(bts[i]&0xf) * pow(10, n-i-1)\n\t}\n\treturn ret, true\n}\n\nconst (\n\ttoLower = 'a' - 'A'      // for use with OR.\n\ttoUpper = ^byte(toLower) // for use with AND.\n)\n\n// CanonicalizeHeaderKey is like standard textproto/CanonicalMIMEHeaderKey,\n// except that it operates with slice of bytes and modifies it inplace without\n// copying.\nfunc CanonicalizeHeaderKey(k []byte) {\n\tupper := true\n\tfor i, c := range k {\n\t\tif upper && 'a' <= c && c <= 'z' {\n\t\t\tk[i] &= toUpper\n\t\t} else if !upper && 'A' <= c && c <= 'Z' {\n\t\t\tk[i] |= toLower\n\t\t}\n\t\tupper = c == '-'\n\t}\n}\n\n// pow for integers implementation.\n// See Donald Knuth, The Art of Computer Programming, Volume 2, Section 4.6.3\nfunc pow(a, b int) int {\n\tp := 1\n\tfor b > 0 {\n\t\tif b&1 != 0 {\n\t\t\tp *= a\n\t\t}\n\t\tb >>= 1\n\t\ta *= a\n\t}\n\treturn p\n}\n\nfunc split3(p []byte, sep byte) (p1, p2, p3 []byte) {\n\ta := bytes.IndexByte(p, sep)\n\tb := bytes.IndexByte(p[a+1:], sep)\n\tif a == -1 || b == -1 {\n\t\treturn p, nil, nil\n\t}\n\tb += a + 1\n\treturn p[:a], p[a+1 : b], p[b+1:]\n}\n\nfunc split2(p []byte, sep byte) (p1, p2 []byte) {\n\ti := bytes.IndexByte(p, sep)\n\tif i == -1 {\n\t\treturn p, nil\n\t}\n\treturn p[:i], p[i+1:]\n}\n\nfunc trim(p []byte) []byte {\n\tvar i, j int\n\tfor i = 0; i < len(p) && (p[i] == ' ' || p[i] == '\\t'); {\n\t\ti++\n\t}\n\tfor j = len(p); j > i && (p[j-1] == ' ' || p[j-1] == '\\t'); {\n\t\tj--\n\t}\n\treturn p[i:j]\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/httphead/httphead.go",
    "content": "// Package httphead contains utils for parsing HTTP and HTTP-grammar compatible\n// text protocols headers.\n//\n// That is, this package first aim is to bring ability to easily parse\n// constructions, described here https://tools.ietf.org/html/rfc2616#section-2\npackage httphead\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n)\n\n// ScanTokens parses data in this form:\n//\n// list = 1#token\n//\n// It returns false if data is malformed.\nfunc ScanTokens(data []byte, it func([]byte) bool) bool {\n\tlexer := &Scanner{data: data}\n\n\tvar ok bool\n\tfor lexer.Next() {\n\t\tswitch lexer.Type() {\n\t\tcase ItemToken:\n\t\t\tok = true\n\t\t\tif !it(lexer.Bytes()) {\n\t\t\t\treturn true\n\t\t\t}\n\t\tcase ItemSeparator:\n\t\t\tif !isComma(lexer.Bytes()) {\n\t\t\t\treturn false\n\t\t\t}\n\t\tdefault:\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn ok && !lexer.err\n}\n\n// ParseOptions parses all header options and appends it to given slice of\n// Option. It returns flag of successful (wellformed input) parsing.\n//\n// Note that appended options are all consist of subslices of data. That is,\n// mutation of data will mutate appended options.\nfunc ParseOptions(data []byte, options []Option) ([]Option, bool) {\n\tvar i int\n\tindex := -1\n\treturn options, ScanOptions(data, func(idx int, name, attr, val []byte) Control {\n\t\tif idx != index {\n\t\t\tindex = idx\n\t\t\ti = len(options)\n\t\t\toptions = append(options, Option{Name: name})\n\t\t}\n\t\tif attr != nil {\n\t\t\toptions[i].Parameters.Set(attr, val)\n\t\t}\n\t\treturn ControlContinue\n\t})\n}\n\n// SelectFlag encodes way of options selection.\ntype SelectFlag byte\n\n// String represetns flag as string.\nfunc (f SelectFlag) String() string {\n\tvar flags [2]string\n\tvar n int\n\tif f&SelectCopy != 0 {\n\t\tflags[n] = \"copy\"\n\t\tn++\n\t}\n\tif f&SelectUnique != 0 {\n\t\tflags[n] = \"unique\"\n\t\tn++\n\t}\n\treturn \"[\" + strings.Join(flags[:n], \"|\") + \"]\"\n}\n\nconst (\n\t// SelectCopy causes selector to copy selected option before appending it\n\t// to resulting slice.\n\t// If SelectCopy flag is not passed to selector, then appended options will\n\t// contain sub-slices of the initial data.\n\tSelectCopy SelectFlag = 1 << iota\n\n\t// SelectUnique causes selector to append only not yet existing option to\n\t// resulting slice. Unique is checked by comparing option names.\n\tSelectUnique\n)\n\n// OptionSelector contains configuration for selecting Options from header value.\ntype OptionSelector struct {\n\t// Check is a filter function that applied to every Option that possibly\n\t// could be selected.\n\t// If Check is nil all options will be selected.\n\tCheck func(Option) bool\n\n\t// Flags contains flags for options selection.\n\tFlags SelectFlag\n\n\t// Alloc used to allocate slice of bytes when selector is configured with\n\t// SelectCopy flag. It will be called with number of bytes needed for copy\n\t// of single Option.\n\t// If Alloc is nil make is used.\n\tAlloc func(n int) []byte\n}\n\n// Select parses header data and appends it to given slice of Option.\n// It also returns flag of successful (wellformed input) parsing.\nfunc (s OptionSelector) Select(data []byte, options []Option) ([]Option, bool) {\n\tvar current Option\n\tvar has bool\n\tindex := -1\n\n\talloc := s.Alloc\n\tif alloc == nil {\n\t\talloc = defaultAlloc\n\t}\n\tcheck := s.Check\n\tif check == nil {\n\t\tcheck = defaultCheck\n\t}\n\n\tok := ScanOptions(data, func(idx int, name, attr, val []byte) Control {\n\t\tif idx != index {\n\t\t\tif has && check(current) {\n\t\t\t\tif s.Flags&SelectCopy != 0 {\n\t\t\t\t\tcurrent = current.Copy(alloc(current.Size()))\n\t\t\t\t}\n\t\t\t\toptions = append(options, current)\n\t\t\t\thas = false\n\t\t\t}\n\t\t\tif s.Flags&SelectUnique != 0 {\n\t\t\t\tfor i := len(options) - 1; i >= 0; i-- {\n\t\t\t\t\tif bytes.Equal(options[i].Name, name) {\n\t\t\t\t\t\treturn ControlSkip\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tindex = idx\n\t\t\tcurrent = Option{Name: name}\n\t\t\thas = true\n\t\t}\n\t\tif attr != nil {\n\t\t\tcurrent.Parameters.Set(attr, val)\n\t\t}\n\n\t\treturn ControlContinue\n\t})\n\tif has && check(current) {\n\t\tif s.Flags&SelectCopy != 0 {\n\t\t\tcurrent = current.Copy(alloc(current.Size()))\n\t\t}\n\t\toptions = append(options, current)\n\t}\n\n\treturn options, ok\n}\n\nfunc defaultAlloc(n int) []byte { return make([]byte, n) }\nfunc defaultCheck(Option) bool  { return true }\n\n// Control represents operation that scanner should perform.\ntype Control byte\n\nconst (\n\t// ControlContinue causes scanner to continue scan tokens.\n\tControlContinue Control = iota\n\t// ControlBreak causes scanner to stop scan tokens.\n\tControlBreak\n\t// ControlSkip causes scanner to skip current entity.\n\tControlSkip\n)\n\n// ScanOptions parses data in this form:\n//\n// values = 1#value\n// value = token *( \";\" param )\n// param = token [ \"=\" (token | quoted-string) ]\n//\n// It calls given callback with the index of the option, option itself and its\n// parameter (attribute and its value, both could be nil). Index is useful when\n// header contains multiple choises for the same named option.\n//\n// Given callback should return one of the defined Control* values.\n// ControlSkip means that passed key is not in caller's interest. That is, all\n// parameters of that key will be skipped.\n// ControlBreak means that no more keys and parameters should be parsed. That\n// is, it must break parsing immediately.\n// ControlContinue means that caller want to receive next parameter and its\n// value or the next key.\n//\n// It returns false if data is malformed.\nfunc ScanOptions(data []byte, it func(index int, option, attribute, value []byte) Control) bool {\n\tlexer := &Scanner{data: data}\n\n\tvar ok bool\n\tvar state int\n\tconst (\n\t\tstateKey = iota\n\t\tstateParamBeforeName\n\t\tstateParamName\n\t\tstateParamBeforeValue\n\t\tstateParamValue\n\t)\n\n\tvar (\n\t\tindex             int\n\t\tkey, param, value []byte\n\t\tmustCall          bool\n\t)\n\tfor lexer.Next() {\n\t\tvar (\n\t\t\tcall      bool\n\t\t\tgrowIndex int\n\t\t)\n\n\t\tt := lexer.Type()\n\t\tv := lexer.Bytes()\n\n\t\tswitch t {\n\t\tcase ItemToken:\n\t\t\tswitch state {\n\t\t\tcase stateKey, stateParamBeforeName:\n\t\t\t\tkey = v\n\t\t\t\tstate = stateParamBeforeName\n\t\t\t\tmustCall = true\n\t\t\tcase stateParamName:\n\t\t\t\tparam = v\n\t\t\t\tstate = stateParamBeforeValue\n\t\t\t\tmustCall = true\n\t\t\tcase stateParamValue:\n\t\t\t\tvalue = v\n\t\t\t\tstate = stateParamBeforeName\n\t\t\t\tcall = true\n\t\t\tdefault:\n\t\t\t\treturn false\n\t\t\t}\n\n\t\tcase ItemString:\n\t\t\tif state != stateParamValue {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tvalue = v\n\t\t\tstate = stateParamBeforeName\n\t\t\tcall = true\n\n\t\tcase ItemSeparator:\n\t\t\tswitch {\n\t\t\tcase isComma(v) && state == stateKey:\n\t\t\t\t// Nothing to do.\n\n\t\t\tcase isComma(v) && state == stateParamBeforeName:\n\t\t\t\tstate = stateKey\n\t\t\t\t// Make call only if we have not called this key yet.\n\t\t\t\tcall = mustCall\n\t\t\t\tif !call {\n\t\t\t\t\t// If we have already called callback with the key\n\t\t\t\t\t// that just ended.\n\t\t\t\t\tindex++\n\t\t\t\t} else {\n\t\t\t\t\t// Else grow the index after calling callback.\n\t\t\t\t\tgrowIndex = 1\n\t\t\t\t}\n\n\t\t\tcase isComma(v) && state == stateParamBeforeValue:\n\t\t\t\tstate = stateKey\n\t\t\t\tgrowIndex = 1\n\t\t\t\tcall = true\n\n\t\t\tcase isSemicolon(v) && state == stateParamBeforeName:\n\t\t\t\tstate = stateParamName\n\n\t\t\tcase isSemicolon(v) && state == stateParamBeforeValue:\n\t\t\t\tstate = stateParamName\n\t\t\t\tcall = true\n\n\t\t\tcase isEquality(v) && state == stateParamBeforeValue:\n\t\t\t\tstate = stateParamValue\n\n\t\t\tdefault:\n\t\t\t\treturn false\n\t\t\t}\n\n\t\tdefault:\n\t\t\treturn false\n\t\t}\n\n\t\tif call {\n\t\t\tswitch it(index, key, param, value) {\n\t\t\tcase ControlBreak:\n\t\t\t\t// User want to stop to parsing parameters.\n\t\t\t\treturn true\n\n\t\t\tcase ControlSkip:\n\t\t\t\t// User want to skip current param.\n\t\t\t\tstate = stateKey\n\t\t\t\tlexer.SkipEscaped(',')\n\n\t\t\tcase ControlContinue:\n\t\t\t\t// User is interested in rest of parameters.\n\t\t\t\t// Nothing to do.\n\n\t\t\tdefault:\n\t\t\t\tpanic(\"unexpected control value\")\n\t\t\t}\n\t\t\tok = true\n\t\t\tparam = nil\n\t\t\tvalue = nil\n\t\t\tmustCall = false\n\t\t\tindex += growIndex\n\t\t}\n\t}\n\tif mustCall {\n\t\tok = true\n\t\tit(index, key, param, value)\n\t}\n\n\treturn ok && !lexer.err\n}\n\nfunc isComma(b []byte) bool {\n\treturn len(b) == 1 && b[0] == ','\n}\nfunc isSemicolon(b []byte) bool {\n\treturn len(b) == 1 && b[0] == ';'\n}\nfunc isEquality(b []byte) bool {\n\treturn len(b) == 1 && b[0] == '='\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/httphead/lexer.go",
    "content": "package httphead\n\nimport (\n\t\"bytes\"\n)\n\n// ItemType encodes type of the lexing token.\ntype ItemType int\n\nconst (\n\t// ItemUndef reports that token is undefined.\n\tItemUndef ItemType = iota\n\t// ItemToken reports that token is RFC2616 token.\n\tItemToken\n\t// ItemSeparator reports that token is RFC2616 separator.\n\tItemSeparator\n\t// ItemString reports that token is RFC2616 quouted string.\n\tItemString\n\t// ItemComment reports that token is RFC2616 comment.\n\tItemComment\n\t// ItemOctet reports that token is octet slice.\n\tItemOctet\n)\n\n// Scanner represents header tokens scanner.\n// See https://tools.ietf.org/html/rfc2616#section-2\ntype Scanner struct {\n\tdata []byte\n\tpos  int\n\n\titemType  ItemType\n\titemBytes []byte\n\n\terr bool\n}\n\n// NewScanner creates new RFC2616 data scanner.\nfunc NewScanner(data []byte) *Scanner {\n\treturn &Scanner{data: data}\n}\n\n// Next scans for next token. It returns true on successful scanning, and false\n// on error or EOF.\nfunc (l *Scanner) Next() bool {\n\tc, ok := l.nextChar()\n\tif !ok {\n\t\treturn false\n\t}\n\tswitch c {\n\tcase '\"': // quoted-string;\n\t\treturn l.fetchQuotedString()\n\n\tcase '(': // comment;\n\t\treturn l.fetchComment()\n\n\tcase '\\\\', ')': // unexpected chars;\n\t\tl.err = true\n\t\treturn false\n\n\tdefault:\n\t\treturn l.fetchToken()\n\t}\n}\n\n// FetchUntil fetches ItemOctet from current scanner position to first\n// occurence of the c or to the end of the underlying data.\nfunc (l *Scanner) FetchUntil(c byte) bool {\n\tl.resetItem()\n\tif l.pos == len(l.data) {\n\t\treturn false\n\t}\n\treturn l.fetchOctet(c)\n}\n\n// Peek reads byte at current position without advancing it. On end of data it\n// returns 0.\nfunc (l *Scanner) Peek() byte {\n\tif l.pos == len(l.data) {\n\t\treturn 0\n\t}\n\treturn l.data[l.pos]\n}\n\n// Peek2 reads two first bytes at current position without advancing it.\n// If there not enough data it returs 0.\nfunc (l *Scanner) Peek2() (a, b byte) {\n\tif l.pos == len(l.data) {\n\t\treturn 0, 0\n\t}\n\tif l.pos+1 == len(l.data) {\n\t\treturn l.data[l.pos], 0\n\t}\n\treturn l.data[l.pos], l.data[l.pos+1]\n}\n\n// Buffered reporst how many bytes there are left to scan.\nfunc (l *Scanner) Buffered() int {\n\treturn len(l.data) - l.pos\n}\n\n// Advance moves current position index at n bytes. It returns true on\n// successful move.\nfunc (l *Scanner) Advance(n int) bool {\n\tl.pos += n\n\tif l.pos > len(l.data) {\n\t\tl.pos = len(l.data)\n\t\treturn false\n\t}\n\treturn true\n}\n\n// Skip skips all bytes until first occurence of c.\nfunc (l *Scanner) Skip(c byte) {\n\tif l.err {\n\t\treturn\n\t}\n\t// Reset scanner state.\n\tl.resetItem()\n\n\tif i := bytes.IndexByte(l.data[l.pos:], c); i == -1 {\n\t\t// Reached the end of data.\n\t\tl.pos = len(l.data)\n\t} else {\n\t\tl.pos += i + 1\n\t}\n}\n\n// SkipEscaped skips all bytes until first occurence of non-escaped c.\nfunc (l *Scanner) SkipEscaped(c byte) {\n\tif l.err {\n\t\treturn\n\t}\n\t// Reset scanner state.\n\tl.resetItem()\n\n\tif i := ScanUntil(l.data[l.pos:], c); i == -1 {\n\t\t// Reached the end of data.\n\t\tl.pos = len(l.data)\n\t} else {\n\t\tl.pos += i + 1\n\t}\n}\n\n// Type reports current token type.\nfunc (l *Scanner) Type() ItemType {\n\treturn l.itemType\n}\n\n// Bytes returns current token bytes.\nfunc (l *Scanner) Bytes() []byte {\n\treturn l.itemBytes\n}\n\nfunc (l *Scanner) nextChar() (byte, bool) {\n\t// Reset scanner state.\n\tl.resetItem()\n\n\tif l.err {\n\t\treturn 0, false\n\t}\n\tl.pos += SkipSpace(l.data[l.pos:])\n\tif l.pos == len(l.data) {\n\t\treturn 0, false\n\t}\n\treturn l.data[l.pos], true\n}\n\nfunc (l *Scanner) resetItem() {\n\tl.itemType = ItemUndef\n\tl.itemBytes = nil\n}\n\nfunc (l *Scanner) fetchOctet(c byte) bool {\n\ti := l.pos\n\tif j := bytes.IndexByte(l.data[l.pos:], c); j == -1 {\n\t\t// Reached the end of data.\n\t\tl.pos = len(l.data)\n\t} else {\n\t\tl.pos += j\n\t}\n\n\tl.itemType = ItemOctet\n\tl.itemBytes = l.data[i:l.pos]\n\n\treturn true\n}\n\nfunc (l *Scanner) fetchToken() bool {\n\tn, t := ScanToken(l.data[l.pos:])\n\tif n == -1 {\n\t\tl.err = true\n\t\treturn false\n\t}\n\n\tl.itemType = t\n\tl.itemBytes = l.data[l.pos : l.pos+n]\n\tl.pos += n\n\n\treturn true\n}\n\nfunc (l *Scanner) fetchQuotedString() (ok bool) {\n\tl.pos++\n\n\tn := ScanUntil(l.data[l.pos:], '\"')\n\tif n == -1 {\n\t\tl.err = true\n\t\treturn false\n\t}\n\n\tl.itemType = ItemString\n\tl.itemBytes = RemoveByte(l.data[l.pos:l.pos+n], '\\\\')\n\tl.pos += n + 1\n\n\treturn true\n}\n\nfunc (l *Scanner) fetchComment() (ok bool) {\n\tl.pos++\n\n\tn := ScanPairGreedy(l.data[l.pos:], '(', ')')\n\tif n == -1 {\n\t\tl.err = true\n\t\treturn false\n\t}\n\n\tl.itemType = ItemComment\n\tl.itemBytes = RemoveByte(l.data[l.pos:l.pos+n], '\\\\')\n\tl.pos += n + 1\n\n\treturn true\n}\n\n// ScanUntil scans for first non-escaped character c in given data.\n// It returns index of matched c and -1 if c is not found.\nfunc ScanUntil(data []byte, c byte) (n int) {\n\tfor {\n\t\ti := bytes.IndexByte(data[n:], c)\n\t\tif i == -1 {\n\t\t\treturn -1\n\t\t}\n\t\tn += i\n\t\tif n == 0 || data[n-1] != '\\\\' {\n\t\t\tbreak\n\t\t}\n\t\tn++\n\t}\n\treturn\n}\n\n// ScanPairGreedy scans for complete pair of opening and closing chars in greedy manner.\n// Note that first opening byte must not be present in data.\nfunc ScanPairGreedy(data []byte, open, close byte) (n int) {\n\tvar m int\n\topened := 1\n\tfor {\n\t\ti := bytes.IndexByte(data[n:], close)\n\t\tif i == -1 {\n\t\t\treturn -1\n\t\t}\n\t\tn += i\n\t\t// If found index is not escaped then it is the end.\n\t\tif n == 0 || data[n-1] != '\\\\' {\n\t\t\topened--\n\t\t}\n\n\t\tfor m < i {\n\t\t\tj := bytes.IndexByte(data[m:i], open)\n\t\t\tif j == -1 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tm += j + 1\n\t\t\topened++\n\t\t}\n\n\t\tif opened == 0 {\n\t\t\tbreak\n\t\t}\n\n\t\tn++\n\t\tm = n\n\t}\n\treturn\n}\n\n// RemoveByte returns data without c. If c is not present in data it returns\n// the same slice. If not, it copies data without c.\nfunc RemoveByte(data []byte, c byte) []byte {\n\tj := bytes.IndexByte(data, c)\n\tif j == -1 {\n\t\treturn data\n\t}\n\n\tn := len(data) - 1\n\n\t// If character is present, than allocate slice with n-1 capacity. That is,\n\t// resulting bytes could be at most n-1 length.\n\tresult := make([]byte, n)\n\tk := copy(result, data[:j])\n\n\tfor i := j + 1; i < n; {\n\t\tj = bytes.IndexByte(data[i:], c)\n\t\tif j != -1 {\n\t\t\tk += copy(result[k:], data[i:i+j])\n\t\t\ti = i + j + 1\n\t\t} else {\n\t\t\tk += copy(result[k:], data[i:])\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn result[:k]\n}\n\n// SkipSpace skips spaces and lws-sequences from p.\n// It returns number ob bytes skipped.\nfunc SkipSpace(p []byte) (n int) {\n\tfor len(p) > 0 {\n\t\tswitch {\n\t\tcase len(p) >= 3 &&\n\t\t\tp[0] == '\\r' &&\n\t\t\tp[1] == '\\n' &&\n\t\t\tOctetTypes[p[2]].IsSpace():\n\t\t\tp = p[3:]\n\t\t\tn += 3\n\t\tcase OctetTypes[p[0]].IsSpace():\n\t\t\tp = p[1:]\n\t\t\tn++\n\t\tdefault:\n\t\t\treturn\n\t\t}\n\t}\n\treturn\n}\n\n// ScanToken scan for next token in p. It returns length of the token and its\n// type. It do not trim p.\nfunc ScanToken(p []byte) (n int, t ItemType) {\n\tif len(p) == 0 {\n\t\treturn 0, ItemUndef\n\t}\n\n\tc := p[0]\n\tswitch {\n\tcase OctetTypes[c].IsSeparator():\n\t\treturn 1, ItemSeparator\n\n\tcase OctetTypes[c].IsToken():\n\t\tfor n = 1; n < len(p); n++ {\n\t\t\tc := p[n]\n\t\t\tif !OctetTypes[c].IsToken() {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\treturn n, ItemToken\n\n\tdefault:\n\t\treturn -1, ItemUndef\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/httphead/octet.go",
    "content": "package httphead\n\n// OctetType desribes character type.\n//\n// From the \"Basic Rules\" chapter of RFC2616\n// See https://tools.ietf.org/html/rfc2616#section-2.2\n//\n// OCTET          = <any 8-bit sequence of data>\n// CHAR           = <any US-ASCII character (octets 0 - 127)>\n// UPALPHA        = <any US-ASCII uppercase letter \"A\"..\"Z\">\n// LOALPHA        = <any US-ASCII lowercase letter \"a\"..\"z\">\n// ALPHA          = UPALPHA | LOALPHA\n// DIGIT          = <any US-ASCII digit \"0\"..\"9\">\n// CTL            = <any US-ASCII control character (octets 0 - 31) and DEL (127)>\n// CR             = <US-ASCII CR, carriage return (13)>\n// LF             = <US-ASCII LF, linefeed (10)>\n// SP             = <US-ASCII SP, space (32)>\n// HT             = <US-ASCII HT, horizontal-tab (9)>\n// <\">            = <US-ASCII double-quote mark (34)>\n// CRLF           = CR LF\n// LWS            = [CRLF] 1*( SP | HT )\n//\n// Many HTTP/1.1 header field values consist of words separated by LWS\n// or special characters. These special characters MUST be in a quoted\n// string to be used within a parameter value (as defined in section\n// 3.6).\n//\n// token          = 1*<any CHAR except CTLs or separators>\n// separators     = \"(\" | \")\" | \"<\" | \">\" | \"@\"\n// | \",\" | \";\" | \":\" | \"\\\" | <\">\n// | \"/\" | \"[\" | \"]\" | \"?\" | \"=\"\n// | \"{\" | \"}\" | SP | HT\ntype OctetType byte\n\n// IsChar reports whether octet is CHAR.\nfunc (t OctetType) IsChar() bool { return t&octetChar != 0 }\n\n// IsControl reports whether octet is CTL.\nfunc (t OctetType) IsControl() bool { return t&octetControl != 0 }\n\n// IsSeparator reports whether octet is separator.\nfunc (t OctetType) IsSeparator() bool { return t&octetSeparator != 0 }\n\n// IsSpace reports whether octet is space (SP or HT).\nfunc (t OctetType) IsSpace() bool { return t&octetSpace != 0 }\n\n// IsToken reports whether octet is token.\nfunc (t OctetType) IsToken() bool { return t&octetToken != 0 }\n\nconst (\n\toctetChar OctetType = 1 << iota\n\toctetControl\n\toctetSpace\n\toctetSeparator\n\toctetToken\n)\n\n// OctetTypes is a table of octets.\nvar OctetTypes [256]OctetType\n\nfunc init() {\n\tfor c := 32; c < 256; c++ {\n\t\tvar t OctetType\n\t\tif c <= 127 {\n\t\t\tt |= octetChar\n\t\t}\n\t\tif 0 <= c && c <= 31 || c == 127 {\n\t\t\tt |= octetControl\n\t\t}\n\t\tswitch c {\n\t\tcase '(', ')', '<', '>', '@', ',', ';', ':', '\"', '/', '[', ']', '?', '=', '{', '}', '\\\\':\n\t\t\tt |= octetSeparator\n\t\tcase ' ', '\\t':\n\t\t\tt |= octetSpace | octetSeparator\n\t\t}\n\n\t\tif t.IsChar() && !t.IsControl() && !t.IsSeparator() && !t.IsSpace() {\n\t\t\tt |= octetToken\n\t\t}\n\n\t\tOctetTypes[c] = t\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/httphead/option.go",
    "content": "package httphead\n\nimport (\n\t\"bytes\"\n\t\"sort\"\n)\n\n// Option represents a header option.\ntype Option struct {\n\tName       []byte\n\tParameters Parameters\n}\n\n// Size returns number of bytes need to be allocated for use in opt.Copy.\nfunc (opt Option) Size() int {\n\treturn len(opt.Name) + opt.Parameters.bytes\n}\n\n// Copy copies all underlying []byte slices into p and returns new Option.\n// Note that p must be at least of opt.Size() length.\nfunc (opt Option) Copy(p []byte) Option {\n\tn := copy(p, opt.Name)\n\topt.Name = p[:n]\n\topt.Parameters, p = opt.Parameters.Copy(p[n:])\n\treturn opt\n}\n\n// Clone is a shorthand for making slice of opt.Size() sequenced with Copy()\n// call.\nfunc (opt Option) Clone() Option {\n\treturn opt.Copy(make([]byte, opt.Size()))\n}\n\n// String represents option as a string.\nfunc (opt Option) String() string {\n\treturn \"{\" + string(opt.Name) + \" \" + opt.Parameters.String() + \"}\"\n}\n\n// NewOption creates named option with given parameters.\nfunc NewOption(name string, params map[string]string) Option {\n\tp := Parameters{}\n\tfor k, v := range params {\n\t\tp.Set([]byte(k), []byte(v))\n\t}\n\treturn Option{\n\t\tName:       []byte(name),\n\t\tParameters: p,\n\t}\n}\n\n// Equal reports whether option is equal to b.\nfunc (opt Option) Equal(b Option) bool {\n\tif bytes.Equal(opt.Name, b.Name) {\n\t\treturn opt.Parameters.Equal(b.Parameters)\n\t}\n\treturn false\n}\n\n// Parameters represents option's parameters.\ntype Parameters struct {\n\tpos   int\n\tbytes int\n\tarr   [8]pair\n\tdyn   []pair\n}\n\n// Equal reports whether a equal to b.\nfunc (p Parameters) Equal(b Parameters) bool {\n\tswitch {\n\tcase p.dyn == nil && b.dyn == nil:\n\tcase p.dyn != nil && b.dyn != nil:\n\tdefault:\n\t\treturn false\n\t}\n\n\tad, bd := p.data(), b.data()\n\tif len(ad) != len(bd) {\n\t\treturn false\n\t}\n\n\tsort.Sort(pairs(ad))\n\tsort.Sort(pairs(bd))\n\n\tfor i := 0; i < len(ad); i++ {\n\t\tav, bv := ad[i], bd[i]\n\t\tif !bytes.Equal(av.key, bv.key) || !bytes.Equal(av.value, bv.value) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Size returns number of bytes that needed to copy p.\nfunc (p *Parameters) Size() int {\n\treturn p.bytes\n}\n\n// Copy copies all underlying []byte slices into dst and returns new\n// Parameters.\n// Note that dst must be at least of p.Size() length.\nfunc (p *Parameters) Copy(dst []byte) (Parameters, []byte) {\n\tret := Parameters{\n\t\tpos:   p.pos,\n\t\tbytes: p.bytes,\n\t}\n\tif p.dyn != nil {\n\t\tret.dyn = make([]pair, len(p.dyn))\n\t\tfor i, v := range p.dyn {\n\t\t\tret.dyn[i], dst = v.copy(dst)\n\t\t}\n\t} else {\n\t\tfor i, p := range p.arr {\n\t\t\tret.arr[i], dst = p.copy(dst)\n\t\t}\n\t}\n\treturn ret, dst\n}\n\n// Get returns value by key and flag about existence such value.\nfunc (p *Parameters) Get(key string) (value []byte, ok bool) {\n\tfor _, v := range p.data() {\n\t\tif string(v.key) == key {\n\t\t\treturn v.value, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// Set sets value by key.\nfunc (p *Parameters) Set(key, value []byte) {\n\tp.bytes += len(key) + len(value)\n\n\tif p.pos < len(p.arr) {\n\t\tp.arr[p.pos] = pair{key, value}\n\t\tp.pos++\n\t\treturn\n\t}\n\n\tif p.dyn == nil {\n\t\tp.dyn = make([]pair, len(p.arr), len(p.arr)+1)\n\t\tcopy(p.dyn, p.arr[:])\n\t}\n\tp.dyn = append(p.dyn, pair{key, value})\n}\n\n// ForEach iterates over parameters key-value pairs and calls cb for each one.\nfunc (p *Parameters) ForEach(cb func(k, v []byte) bool) {\n\tfor _, v := range p.data() {\n\t\tif !cb(v.key, v.value) {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n// String represents parameters as a string.\nfunc (p *Parameters) String() (ret string) {\n\tret = \"[\"\n\tfor i, v := range p.data() {\n\t\tif i > 0 {\n\t\t\tret += \" \"\n\t\t}\n\t\tret += string(v.key) + \":\" + string(v.value)\n\t}\n\treturn ret + \"]\"\n}\n\nfunc (p *Parameters) data() []pair {\n\tif p.dyn != nil {\n\t\treturn p.dyn\n\t}\n\treturn p.arr[:p.pos]\n}\n\ntype pair struct {\n\tkey, value []byte\n}\n\nfunc (p pair) copy(dst []byte) (pair, []byte) {\n\tn := copy(dst, p.key)\n\tp.key = dst[:n]\n\tm := n + copy(dst[n:], p.value)\n\tp.value = dst[n:m]\n\n\tdst = dst[m:]\n\n\treturn p, dst\n}\n\ntype pairs []pair\n\nfunc (p pairs) Len() int           { return len(p) }\nfunc (p pairs) Less(a, b int) bool { return bytes.Compare(p[a].key, p[b].key) == -1 }\nfunc (p pairs) Swap(a, b int)      { p[a], p[b] = p[b], p[a] }\n"
  },
  {
    "path": "vendor/github.com/gobwas/httphead/writer.go",
    "content": "package httphead\n\nimport \"io\"\n\nvar (\n\tcomma     = []byte{','}\n\tequality  = []byte{'='}\n\tsemicolon = []byte{';'}\n\tquote     = []byte{'\"'}\n\tescape    = []byte{'\\\\'}\n)\n\n// WriteOptions write options list to the dest.\n// It uses the same form as {Scan,Parse}Options functions:\n// values = 1#value\n// value = token *( \";\" param )\n// param = token [ \"=\" (token | quoted-string) ]\n//\n// It wraps valuse into the quoted-string sequence if it contains any\n// non-token characters.\nfunc WriteOptions(dest io.Writer, options []Option) (n int, err error) {\n\tw := writer{w: dest}\n\tfor i, opt := range options {\n\t\tif i > 0 {\n\t\t\tw.write(comma)\n\t\t}\n\n\t\twriteTokenSanitized(&w, opt.Name)\n\n\t\tfor _, p := range opt.Parameters.data() {\n\t\t\tw.write(semicolon)\n\t\t\twriteTokenSanitized(&w, p.key)\n\t\t\tif len(p.value) != 0 {\n\t\t\t\tw.write(equality)\n\t\t\t\twriteTokenSanitized(&w, p.value)\n\t\t\t}\n\t\t}\n\t}\n\treturn w.result()\n}\n\n// writeTokenSanitized writes token as is or as quouted string if it contains\n// non-token characters.\n//\n// Note that is is not expects LWS sequnces be in s, cause LWS is used only as\n// header field continuation:\n// \"A CRLF is allowed in the definition of TEXT only as part of a header field\n// continuation. It is expected that the folding LWS will be replaced with a\n// single SP before interpretation of the TEXT value.\"\n// See https://tools.ietf.org/html/rfc2616#section-2\n//\n// That is we sanitizing s for writing, so there could not be any header field\n// continuation.\n// That is any CRLF will be escaped as any other control characters not allowd in TEXT.\nfunc writeTokenSanitized(bw *writer, bts []byte) {\n\tvar qt bool\n\tvar pos int\n\tfor i := 0; i < len(bts); i++ {\n\t\tc := bts[i]\n\t\tif !OctetTypes[c].IsToken() && !qt {\n\t\t\tqt = true\n\t\t\tbw.write(quote)\n\t\t}\n\t\tif OctetTypes[c].IsControl() || c == '\"' {\n\t\t\tif !qt {\n\t\t\t\tqt = true\n\t\t\t\tbw.write(quote)\n\t\t\t}\n\t\t\tbw.write(bts[pos:i])\n\t\t\tbw.write(escape)\n\t\t\tbw.write(bts[i : i+1])\n\t\t\tpos = i + 1\n\t\t}\n\t}\n\tif !qt {\n\t\tbw.write(bts)\n\t} else {\n\t\tbw.write(bts[pos:])\n\t\tbw.write(quote)\n\t}\n}\n\ntype writer struct {\n\tw   io.Writer\n\tn   int\n\terr error\n}\n\nfunc (w *writer) write(p []byte) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\tvar n int\n\tn, w.err = w.w.Write(p)\n\tw.n += n\n\treturn\n}\n\nfunc (w *writer) result() (int, error) {\n\treturn w.n, w.err\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/pool/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2017-2019 Sergey Kamardin <gobwas@gmail.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/gobwas/pool/README.md",
    "content": "# pool\n\n[![GoDoc][godoc-image]][godoc-url]\n\n> Tiny memory reuse helpers for Go.\n\n## generic\n\nWithout use of subpackages, `pool` allows to reuse any struct distinguishable\nby size in generic way:\n\n```go\npackage main\n\nimport \"github.com/gobwas/pool\"\n\nfunc main() {\n\tx, n := pool.Get(100) // Returns object with size 128 or nil.\n\tif x == nil {\n\t\t// Create x somehow with knowledge that n is 128.\n\t}\n\tdefer pool.Put(x, n)\n\t\n\t// Work with x.\n}\n```\n\nPool allows you to pass specific options for constructing custom pool:\n\n```go\npackage main\n\nimport \"github.com/gobwas/pool\"\n\nfunc main() {\n\tp := pool.Custom(\n        pool.WithLogSizeMapping(),      // Will ceil size n passed to Get(n) to nearest power of two.\n        pool.WithLogSizeRange(64, 512), // Will reuse objects in logarithmic range [64, 512].\n        pool.WithSize(65536),           // Will reuse object with size 65536.\n    )\n\tx, n := p.Get(1000)  // Returns nil and 1000 because mapped size 1000 => 1024 is not reusing by the pool.\n    defer pool.Put(x, n) // Will not reuse x.\n\t\n\t// Work with x.\n}\n```\n\nNote that there are few non-generic pooling implementations inside subpackages.\n\n## pbytes\n\nSubpackage `pbytes` is intended for `[]byte` reuse.\n\n```go\npackage main\n\nimport \"github.com/gobwas/pool/pbytes\"\n\nfunc main() {\n\tbts := pbytes.GetCap(100) // Returns make([]byte, 0, 128).\n\tdefer pbytes.Put(bts)\n\n\t// Work with bts.\n}\n```\n\nYou can also create your own range for pooling:\n\n```go\npackage main\n\nimport \"github.com/gobwas/pool/pbytes\"\n\nfunc main() {\n\t// Reuse only slices whose capacity is 128, 256, 512 or 1024.\n\tpool := pbytes.New(128, 1024) \n\n\tbts := pool.GetCap(100) // Returns make([]byte, 0, 128).\n\tdefer pool.Put(bts)\n\n\t// Work with bts.\n}\n```\n\n## pbufio\n\nSubpackage `pbufio` is intended for `*bufio.{Reader, Writer}` reuse.\n\n```go\npackage main\n\nimport \"github.com/gobwas/pool/pbufio\"\n\nfunc main() {\n\tbw := pbufio.GetWriter(os.Stdout, 100) // Returns bufio.NewWriterSize(128).\n\tdefer pbufio.PutWriter(bw)\n\n\t// Work with bw.\n}\n```\n\nLike with `pbytes`, you can also create pool with custom reuse bounds.\n\n\n\n[godoc-image]: https://godoc.org/github.com/gobwas/pool?status.svg\n[godoc-url]:   https://godoc.org/github.com/gobwas/pool\n"
  },
  {
    "path": "vendor/github.com/gobwas/pool/generic.go",
    "content": "package pool\n\nimport (\n\t\"sync\"\n\n\t\"github.com/gobwas/pool/internal/pmath\"\n)\n\nvar DefaultPool = New(128, 65536)\n\n// Get pulls object whose generic size is at least of given size. It also\n// returns a real size of x for further pass to Put(). It returns -1 as real\n// size for nil x. Size >-1 does not mean that x is non-nil, so checks must be\n// done.\n//\n// Note that size could be ceiled to the next power of two.\n//\n// Get is a wrapper around DefaultPool.Get().\nfunc Get(size int) (interface{}, int) { return DefaultPool.Get(size) }\n\n// Put takes x and its size for future reuse.\n// Put is a wrapper around DefaultPool.Put().\nfunc Put(x interface{}, size int) { DefaultPool.Put(x, size) }\n\n// Pool contains logic of reusing objects distinguishable by size in generic\n// way.\ntype Pool struct {\n\tpool map[int]*sync.Pool\n\tsize func(int) int\n}\n\n// New creates new Pool that reuses objects which size is in logarithmic range\n// [min, max].\n//\n// Note that it is a shortcut for Custom() constructor with Options provided by\n// WithLogSizeMapping() and WithLogSizeRange(min, max) calls.\nfunc New(min, max int) *Pool {\n\treturn Custom(\n\t\tWithLogSizeMapping(),\n\t\tWithLogSizeRange(min, max),\n\t)\n}\n\n// Custom creates new Pool with given options.\nfunc Custom(opts ...Option) *Pool {\n\tp := &Pool{\n\t\tpool: make(map[int]*sync.Pool),\n\t\tsize: pmath.Identity,\n\t}\n\n\tc := (*poolConfig)(p)\n\tfor _, opt := range opts {\n\t\topt(c)\n\t}\n\n\treturn p\n}\n\n// Get pulls object whose generic size is at least of given size.\n// It also returns a real size of x for further pass to Put() even if x is nil.\n// Note that size could be ceiled to the next power of two.\nfunc (p *Pool) Get(size int) (interface{}, int) {\n\tn := p.size(size)\n\tif pool := p.pool[n]; pool != nil {\n\t\treturn pool.Get(), n\n\t}\n\treturn nil, size\n}\n\n// Put takes x and its size for future reuse.\nfunc (p *Pool) Put(x interface{}, size int) {\n\tif pool := p.pool[size]; pool != nil {\n\t\tpool.Put(x)\n\t}\n}\n\ntype poolConfig Pool\n\n// AddSize adds size n to the map.\nfunc (p *poolConfig) AddSize(n int) {\n\tp.pool[n] = new(sync.Pool)\n}\n\n// SetSizeMapping sets up incoming size mapping function.\nfunc (p *poolConfig) SetSizeMapping(size func(int) int) {\n\tp.size = size\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/pool/internal/pmath/pmath.go",
    "content": "package pmath\n\nconst (\n\tbitsize       = 32 << (^uint(0) >> 63)\n\tmaxint        = int(1<<(bitsize-1) - 1)\n\tmaxintHeadBit = 1 << (bitsize - 2)\n)\n\n// LogarithmicRange iterates from ceiled to power of two min to max,\n// calling cb on each iteration.\nfunc LogarithmicRange(min, max int, cb func(int)) {\n\tif min == 0 {\n\t\tmin = 1\n\t}\n\tfor n := CeilToPowerOfTwo(min); n <= max; n <<= 1 {\n\t\tcb(n)\n\t}\n}\n\n// IsPowerOfTwo reports whether given integer is a power of two.\nfunc IsPowerOfTwo(n int) bool {\n\treturn n&(n-1) == 0\n}\n\n// Identity is identity.\nfunc Identity(n int) int {\n\treturn n\n}\n\n// CeilToPowerOfTwo returns the least power of two integer value greater than\n// or equal to n.\nfunc CeilToPowerOfTwo(n int) int {\n\tif n&maxintHeadBit != 0 && n > maxintHeadBit {\n\t\tpanic(\"argument is too large\")\n\t}\n\tif n <= 2 {\n\t\treturn n\n\t}\n\tn--\n\tn = fillBits(n)\n\tn++\n\treturn n\n}\n\n// FloorToPowerOfTwo returns the greatest power of two integer value less than\n// or equal to n.\nfunc FloorToPowerOfTwo(n int) int {\n\tif n <= 2 {\n\t\treturn n\n\t}\n\tn = fillBits(n)\n\tn >>= 1\n\tn++\n\treturn n\n}\n\nfunc fillBits(n int) int {\n\tn |= n >> 1\n\tn |= n >> 2\n\tn |= n >> 4\n\tn |= n >> 8\n\tn |= n >> 16\n\tn |= n >> 32\n\treturn n\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/pool/option.go",
    "content": "package pool\n\nimport \"github.com/gobwas/pool/internal/pmath\"\n\n// Option configures pool.\ntype Option func(Config)\n\n// Config describes generic pool configuration.\ntype Config interface {\n\tAddSize(n int)\n\tSetSizeMapping(func(int) int)\n}\n\n// WithSizeLogRange returns an Option that will add logarithmic range of\n// pooling sizes containing [min, max] values.\nfunc WithLogSizeRange(min, max int) Option {\n\treturn func(c Config) {\n\t\tpmath.LogarithmicRange(min, max, func(n int) {\n\t\t\tc.AddSize(n)\n\t\t})\n\t}\n}\n\n// WithSize returns an Option that will add given pooling size to the pool.\nfunc WithSize(n int) Option {\n\treturn func(c Config) {\n\t\tc.AddSize(n)\n\t}\n}\n\nfunc WithSizeMapping(sz func(int) int) Option {\n\treturn func(c Config) {\n\t\tc.SetSizeMapping(sz)\n\t}\n}\n\nfunc WithLogSizeMapping() Option {\n\treturn WithSizeMapping(pmath.CeilToPowerOfTwo)\n}\n\nfunc WithIdentitySizeMapping() Option {\n\treturn WithSizeMapping(pmath.Identity)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/pool/pbufio/pbufio.go",
    "content": "// Package pbufio contains tools for pooling bufio.Reader and bufio.Writers.\npackage pbufio\n\nimport (\n\t\"bufio\"\n\t\"io\"\n\n\t\"github.com/gobwas/pool\"\n)\n\nvar (\n\tDefaultWriterPool = NewWriterPool(256, 65536)\n\tDefaultReaderPool = NewReaderPool(256, 65536)\n)\n\n// GetWriter returns bufio.Writer whose buffer has at least size bytes.\n// Note that size could be ceiled to the next power of two.\n// GetWriter is a wrapper around DefaultWriterPool.Get().\nfunc GetWriter(w io.Writer, size int) *bufio.Writer { return DefaultWriterPool.Get(w, size) }\n\n// PutWriter takes bufio.Writer for future reuse.\n// It does not reuse bufio.Writer which underlying buffer size is not power of\n// PutWriter is a wrapper around DefaultWriterPool.Put().\nfunc PutWriter(bw *bufio.Writer) { DefaultWriterPool.Put(bw) }\n\n// GetReader returns bufio.Reader whose buffer has at least size bytes. It returns\n// its capacity for further pass to Put().\n// Note that size could be ceiled to the next power of two.\n// GetReader is a wrapper around DefaultReaderPool.Get().\nfunc GetReader(w io.Reader, size int) *bufio.Reader { return DefaultReaderPool.Get(w, size) }\n\n// PutReader takes bufio.Reader and its size for future reuse.\n// It does not reuse bufio.Reader if size is not power of two or is out of pool\n// min/max range.\n// PutReader is a wrapper around DefaultReaderPool.Put().\nfunc PutReader(bw *bufio.Reader) { DefaultReaderPool.Put(bw) }\n\n// WriterPool contains logic of *bufio.Writer reuse with various size.\ntype WriterPool struct {\n\tpool *pool.Pool\n}\n\n// NewWriterPool creates new WriterPool that reuses writers which size is in\n// logarithmic range [min, max].\nfunc NewWriterPool(min, max int) *WriterPool {\n\treturn &WriterPool{pool.New(min, max)}\n}\n\n// CustomWriterPool creates new WriterPool with given options.\nfunc CustomWriterPool(opts ...pool.Option) *WriterPool {\n\treturn &WriterPool{pool.Custom(opts...)}\n}\n\n// Get returns bufio.Writer whose buffer has at least size bytes.\nfunc (wp *WriterPool) Get(w io.Writer, size int) *bufio.Writer {\n\tv, n := wp.pool.Get(size)\n\tif v != nil {\n\t\tbw := v.(*bufio.Writer)\n\t\tbw.Reset(w)\n\t\treturn bw\n\t}\n\treturn bufio.NewWriterSize(w, n)\n}\n\n// Put takes ownership of bufio.Writer for further reuse.\nfunc (wp *WriterPool) Put(bw *bufio.Writer) {\n\t// Should reset even if we do Reset() inside Get().\n\t// This is done to prevent locking underlying io.Writer from GC.\n\tbw.Reset(nil)\n\twp.pool.Put(bw, writerSize(bw))\n}\n\n// ReaderPool contains logic of *bufio.Reader reuse with various size.\ntype ReaderPool struct {\n\tpool *pool.Pool\n}\n\n// NewReaderPool creates new ReaderPool that reuses writers which size is in\n// logarithmic range [min, max].\nfunc NewReaderPool(min, max int) *ReaderPool {\n\treturn &ReaderPool{pool.New(min, max)}\n}\n\n// CustomReaderPool creates new ReaderPool with given options.\nfunc CustomReaderPool(opts ...pool.Option) *ReaderPool {\n\treturn &ReaderPool{pool.Custom(opts...)}\n}\n\n// Get returns bufio.Reader whose buffer has at least size bytes.\nfunc (rp *ReaderPool) Get(r io.Reader, size int) *bufio.Reader {\n\tv, n := rp.pool.Get(size)\n\tif v != nil {\n\t\tbr := v.(*bufio.Reader)\n\t\tbr.Reset(r)\n\t\treturn br\n\t}\n\treturn bufio.NewReaderSize(r, n)\n}\n\n// Put takes ownership of bufio.Reader for further reuse.\nfunc (rp *ReaderPool) Put(br *bufio.Reader) {\n\t// Should reset even if we do Reset() inside Get().\n\t// This is done to prevent locking underlying io.Reader from GC.\n\tbr.Reset(nil)\n\trp.pool.Put(br, readerSize(br))\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/pool/pbufio/pbufio_go110.go",
    "content": "// +build go1.10\n\npackage pbufio\n\nimport \"bufio\"\n\nfunc writerSize(bw *bufio.Writer) int {\n\treturn bw.Size()\n}\n\nfunc readerSize(br *bufio.Reader) int {\n\treturn br.Size()\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/pool/pbufio/pbufio_go19.go",
    "content": "// +build !go1.10\n\npackage pbufio\n\nimport \"bufio\"\n\nfunc writerSize(bw *bufio.Writer) int {\n\treturn bw.Available() + bw.Buffered()\n}\n\n// readerSize returns buffer size of the given buffered reader.\n// NOTE: current workaround implementation resets underlying io.Reader.\nfunc readerSize(br *bufio.Reader) int {\n\tbr.Reset(sizeReader)\n\tbr.ReadByte()\n\tn := br.Buffered() + 1\n\tbr.Reset(nil)\n\treturn n\n}\n\nvar sizeReader optimisticReader\n\ntype optimisticReader struct{}\n\nfunc (optimisticReader) Read(p []byte) (int, error) {\n\treturn len(p), nil\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/pool/pbytes/pbytes.go",
    "content": "// Package pbytes contains tools for pooling byte pool.\n// Note that by default it reuse slices with capacity from 128 to 65536 bytes.\npackage pbytes\n\n// DefaultPool is used by pacakge level functions.\nvar DefaultPool = New(128, 65536)\n\n// Get returns probably reused slice of bytes with at least capacity of c and\n// exactly len of n.\n// Get is a wrapper around DefaultPool.Get().\nfunc Get(n, c int) []byte { return DefaultPool.Get(n, c) }\n\n// GetCap returns probably reused slice of bytes with at least capacity of n.\n// GetCap is a wrapper around DefaultPool.GetCap().\nfunc GetCap(c int) []byte { return DefaultPool.GetCap(c) }\n\n// GetLen returns probably reused slice of bytes with at least capacity of n\n// and exactly len of n.\n// GetLen is a wrapper around DefaultPool.GetLen().\nfunc GetLen(n int) []byte { return DefaultPool.GetLen(n) }\n\n// Put returns given slice to reuse pool.\n// Put is a wrapper around DefaultPool.Put().\nfunc Put(p []byte) { DefaultPool.Put(p) }\n"
  },
  {
    "path": "vendor/github.com/gobwas/pool/pbytes/pool.go",
    "content": "// +build !pool_sanitize\n\npackage pbytes\n\nimport \"github.com/gobwas/pool\"\n\n// Pool contains logic of reusing byte slices of various size.\ntype Pool struct {\n\tpool *pool.Pool\n}\n\n// New creates new Pool that reuses slices which size is in logarithmic range\n// [min, max].\n//\n// Note that it is a shortcut for Custom() constructor with Options provided by\n// pool.WithLogSizeMapping() and pool.WithLogSizeRange(min, max) calls.\nfunc New(min, max int) *Pool {\n\treturn &Pool{pool.New(min, max)}\n}\n\n// New creates new Pool with given options.\nfunc Custom(opts ...pool.Option) *Pool {\n\treturn &Pool{pool.Custom(opts...)}\n}\n\n// Get returns probably reused slice of bytes with at least capacity of c and\n// exactly len of n.\nfunc (p *Pool) Get(n, c int) []byte {\n\tif n > c {\n\t\tpanic(\"requested length is greater than capacity\")\n\t}\n\n\tv, x := p.pool.Get(c)\n\tif v != nil {\n\t\tbts := v.([]byte)\n\t\tbts = bts[:n]\n\t\treturn bts\n\t}\n\n\treturn make([]byte, n, x)\n}\n\n// Put returns given slice to reuse pool.\n// It does not reuse bytes whose size is not power of two or is out of pool\n// min/max range.\nfunc (p *Pool) Put(bts []byte) {\n\tp.pool.Put(bts, cap(bts))\n}\n\n// GetCap returns probably reused slice of bytes with at least capacity of n.\nfunc (p *Pool) GetCap(c int) []byte {\n\treturn p.Get(0, c)\n}\n\n// GetLen returns probably reused slice of bytes with at least capacity of n\n// and exactly len of n.\nfunc (p *Pool) GetLen(n int) []byte {\n\treturn p.Get(n, n)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/pool/pbytes/pool_sanitize.go",
    "content": "// +build pool_sanitize\n\npackage pbytes\n\nimport (\n\t\"reflect\"\n\t\"runtime\"\n\t\"sync/atomic\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nconst magic = uint64(0x777742)\n\ntype guard struct {\n\tmagic  uint64\n\tsize   int\n\towners int32\n}\n\nconst guardSize = int(unsafe.Sizeof(guard{}))\n\ntype Pool struct {\n\tmin, max int\n}\n\nfunc New(min, max int) *Pool {\n\treturn &Pool{min, max}\n}\n\n// Get returns probably reused slice of bytes with at least capacity of c and\n// exactly len of n.\nfunc (p *Pool) Get(n, c int) []byte {\n\tif n > c {\n\t\tpanic(\"requested length is greater than capacity\")\n\t}\n\n\tpageSize := syscall.Getpagesize()\n\tpages := (c+guardSize)/pageSize + 1\n\tsize := pages * pageSize\n\n\tbts := alloc(size)\n\n\tg := (*guard)(unsafe.Pointer(&bts[0]))\n\t*g = guard{\n\t\tmagic:  magic,\n\t\tsize:   size,\n\t\towners: 1,\n\t}\n\n\treturn bts[guardSize : guardSize+n]\n}\n\nfunc (p *Pool) GetCap(c int) []byte { return p.Get(0, c) }\nfunc (p *Pool) GetLen(n int) []byte { return Get(n, n) }\n\n// Put returns given slice to reuse pool.\nfunc (p *Pool) Put(bts []byte) {\n\thdr := *(*reflect.SliceHeader)(unsafe.Pointer(&bts))\n\tptr := hdr.Data - uintptr(guardSize)\n\n\tg := (*guard)(unsafe.Pointer(ptr))\n\tif g.magic != magic {\n\t\tpanic(\"unknown slice returned to the pool\")\n\t}\n\tif n := atomic.AddInt32(&g.owners, -1); n < 0 {\n\t\tpanic(\"multiple Put() detected\")\n\t}\n\n\t// Disable read and write on bytes memory pages. This will cause panic on\n\t// incorrect access to returned slice.\n\tmprotect(ptr, false, false, g.size)\n\n\truntime.SetFinalizer(&bts, func(b *[]byte) {\n\t\tmprotect(ptr, true, true, g.size)\n\t\tfree(*(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{\n\t\t\tData: ptr,\n\t\t\tLen:  g.size,\n\t\t\tCap:  g.size,\n\t\t})))\n\t})\n}\n\nfunc alloc(n int) []byte {\n\tb, err := unix.Mmap(-1, 0, n, unix.PROT_READ|unix.PROT_WRITE|unix.PROT_EXEC, unix.MAP_SHARED|unix.MAP_ANONYMOUS)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\treturn b\n}\n\nfunc free(b []byte) {\n\tif err := unix.Munmap(b); err != nil {\n\t\tpanic(err.Error())\n\t}\n}\n\nfunc mprotect(ptr uintptr, r, w bool, size int) {\n\t// Need to avoid \"EINVAL addr is not a valid pointer,\n\t// or not a multiple of PAGESIZE.\"\n\tstart := ptr & ^(uintptr(syscall.Getpagesize() - 1))\n\n\tprot := uintptr(syscall.PROT_EXEC)\n\tswitch {\n\tcase r && w:\n\t\tprot |= syscall.PROT_READ | syscall.PROT_WRITE\n\tcase r:\n\t\tprot |= syscall.PROT_READ\n\tcase w:\n\t\tprot |= syscall.PROT_WRITE\n\t}\n\n\t_, _, err := syscall.Syscall(syscall.SYS_MPROTECT,\n\t\tstart, uintptr(size), prot,\n\t)\n\tif err != 0 {\n\t\tpanic(err.Error())\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/pool/pool.go",
    "content": "// Package pool contains helpers for pooling structures distinguishable by\n// size.\n//\n// Quick example:\n//\n//   import \"github.com/gobwas/pool\"\n//\n//   func main() {\n//      // Reuse objects in logarithmic range from 0 to 64 (0,1,2,4,6,8,16,32,64).\n//      p := pool.New(0, 64)\n//\n//      buf, n := p.Get(10) // Returns buffer with 16 capacity.\n//      if buf == nil {\n//          buf = bytes.NewBuffer(make([]byte, n))\n//      }\n//      defer p.Put(buf, n)\n//\n//      // Work with buf.\n//   }\n//\n// There are non-generic implementations for pooling:\n// - pool/pbytes for []byte reuse;\n// - pool/pbufio for *bufio.Reader and *bufio.Writer reuse;\n//\npackage pool\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/.gitignore",
    "content": "bin/\nreports/\ncpu.out\nmem.out\nws.test\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2017-2021 Sergey Kamardin <gobwas@gmail.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/Makefile",
    "content": "BENCH     ?=.\nBENCH_BASE?=master\n\nclean:\n\trm -f bin/reporter\n\trm -fr autobahn/report/*\n\nbin/reporter:\n\tgo build -o bin/reporter ./autobahn\n\nbin/gocovmerge:\n\tgo build -o bin/gocovmerge github.com/wadey/gocovmerge\n\n.PHONY: autobahn\nautobahn: clean bin/reporter \n\t./autobahn/script/test.sh --build --follow-logs\n\tbin/reporter $(PWD)/autobahn/report/index.json\n\n.PHONY: autobahn/report\nautobahn/report: bin/reporter\n\t./bin/reporter -http localhost:5555 ./autobahn/report/index.json\n\ntest:\n\tgo test -coverprofile=ws.coverage .\n\tgo test -coverprofile=wsutil.coverage ./wsutil\n\tgo test -coverprofile=wsfalte.coverage ./wsflate\n\t# No statemenets to cover in ./tests (there are only tests).\n\tgo test ./tests\n\ncover: bin/gocovmerge test autobahn\n\tbin/gocovmerge ws.coverage wsutil.coverage wsflate.coverage autobahn/report/server.coverage > total.coverage\n\nbenchcmp: BENCH_BRANCH=$(shell git rev-parse --abbrev-ref HEAD)\nbenchcmp: BENCH_OLD:=$(shell mktemp -t old.XXXX)\nbenchcmp: BENCH_NEW:=$(shell mktemp -t new.XXXX)\nbenchcmp:\n\tif [ ! -z \"$(shell git status -s)\" ]; then\\\n\t\techo \"could not compare with $(BENCH_BASE) – found unstaged changes\";\\\n\t\texit 1;\\\n\tfi;\\\n\tif [ \"$(BENCH_BRANCH)\" == \"$(BENCH_BASE)\" ]; then\\\n\t\techo \"comparing the same branches\";\\\n\t\texit 1;\\\n\tfi;\\\n\techo \"benchmarking $(BENCH_BRANCH)...\";\\\n\tgo test -run=none -bench=$(BENCH) -benchmem > $(BENCH_NEW);\\\n\techo \"benchmarking $(BENCH_BASE)...\";\\\n\tgit checkout -q $(BENCH_BASE);\\\n\tgo test -run=none -bench=$(BENCH) -benchmem > $(BENCH_OLD);\\\n\tgit checkout -q $(BENCH_BRANCH);\\\n\techo \"\\nresults:\";\\\n\techo \"========\\n\";\\\n\tbenchcmp $(BENCH_OLD) $(BENCH_NEW);\\\n\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/README.md",
    "content": "# ws\n\n[![GoDoc][godoc-image]][godoc-url]\n[![CI][ci-badge]][ci-url]\n\n> [RFC6455][rfc-url] WebSocket implementation in Go.\n\n# Features\n\n- Zero-copy upgrade\n- No intermediate allocations during I/O\n- Low-level API which allows to build your own logic of packet handling and\n  buffers reuse\n- High-level wrappers and helpers around API in `wsutil` package, which allow\n  to start fast without digging the protocol internals\n\n# Documentation\n\n[GoDoc][godoc-url].\n\n# Why\n\nExisting WebSocket implementations do not allow users to reuse I/O buffers\nbetween connections in clear way. This library aims to export efficient\nlow-level interface for working with the protocol without forcing only one way\nit could be used.\n\nBy the way, if you want get the higher-level tools, you can use `wsutil`\npackage.\n\n# Status\n\nLibrary is tagged as `v1*` so its API must not be broken during some\nimprovements or refactoring.\n\nThis implementation of RFC6455 passes [Autobahn Test\nSuite](https://github.com/crossbario/autobahn-testsuite) and currently has\nabout 78% coverage.\n\n# Examples\n\nExample applications using `ws` are developed in separate repository\n[ws-examples](https://github.com/gobwas/ws-examples).\n\n# Usage\n\nThe higher-level example of WebSocket echo server:\n\n```go\npackage main\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/gobwas/ws\"\n\t\"github.com/gobwas/ws/wsutil\"\n)\n\nfunc main() {\n\thttp.ListenAndServe(\":8080\", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tconn, _, _, err := ws.UpgradeHTTP(r, w)\n\t\tif err != nil {\n\t\t\t// handle error\n\t\t}\n\t\tgo func() {\n\t\t\tdefer conn.Close()\n\n\t\t\tfor {\n\t\t\t\tmsg, op, err := wsutil.ReadClientData(conn)\n\t\t\t\tif err != nil {\n\t\t\t\t\t// handle error\n\t\t\t\t}\n\t\t\t\terr = wsutil.WriteServerMessage(conn, op, msg)\n\t\t\t\tif err != nil {\n\t\t\t\t\t// handle error\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\t}))\n}\n```\n\nLower-level, but still high-level example:\n\n\n```go\nimport (\n\t\"net/http\"\n\t\"io\"\n\n\t\"github.com/gobwas/ws\"\n\t\"github.com/gobwas/ws/wsutil\"\n)\n\nfunc main() {\n\thttp.ListenAndServe(\":8080\", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tconn, _, _, err := ws.UpgradeHTTP(r, w)\n\t\tif err != nil {\n\t\t\t// handle error\n\t\t}\n\t\tgo func() {\n\t\t\tdefer conn.Close()\n\n\t\t\tvar (\n\t\t\t\tstate  = ws.StateServerSide\n\t\t\t\treader = wsutil.NewReader(conn, state)\n\t\t\t\twriter = wsutil.NewWriter(conn, state, ws.OpText)\n\t\t\t)\n\t\t\tfor {\n\t\t\t\theader, err := reader.NextFrame()\n\t\t\t\tif err != nil {\n\t\t\t\t\t// handle error\n\t\t\t\t}\n\n\t\t\t\t// Reset writer to write frame with right operation code.\n\t\t\t\twriter.Reset(conn, state, header.OpCode)\n\n\t\t\t\tif _, err = io.Copy(writer, reader); err != nil {\n\t\t\t\t\t// handle error\n\t\t\t\t}\n\t\t\t\tif err = writer.Flush(); err != nil {\n\t\t\t\t\t// handle error\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\t}))\n}\n```\n\nWe can apply the same pattern to read and write structured responses through a JSON encoder and decoder.:\n\n```go\n\t...\n\tvar (\n\t\tr = wsutil.NewReader(conn, ws.StateServerSide)\n\t\tw = wsutil.NewWriter(conn, ws.StateServerSide, ws.OpText)\n\t\tdecoder = json.NewDecoder(r)\n\t\tencoder = json.NewEncoder(w)\n\t)\n\tfor {\n\t\thdr, err = r.NextFrame()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif hdr.OpCode == ws.OpClose {\n\t\t\treturn io.EOF\n\t\t}\n\t\tvar req Request\n\t\tif err := decoder.Decode(&req); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tvar resp Response\n\t\tif err := encoder.Encode(&resp); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err = w.Flush(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t...\n```\n\nThe lower-level example without `wsutil`:\n\n```go\npackage main\n\nimport (\n\t\"net\"\n\t\"io\"\n\n\t\"github.com/gobwas/ws\"\n)\n\nfunc main() {\n\tln, err := net.Listen(\"tcp\", \"localhost:8080\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfor {\n\t\tconn, err := ln.Accept()\n\t\tif err != nil {\n\t\t\t// handle error\n\t\t}\n\t\t_, err = ws.Upgrade(conn)\n\t\tif err != nil {\n\t\t\t// handle error\n\t\t}\n\n\t\tgo func() {\n\t\t\tdefer conn.Close()\n\n\t\t\tfor {\n\t\t\t\theader, err := ws.ReadHeader(conn)\n\t\t\t\tif err != nil {\n\t\t\t\t\t// handle error\n\t\t\t\t}\n\n\t\t\t\tpayload := make([]byte, header.Length)\n\t\t\t\t_, err = io.ReadFull(conn, payload)\n\t\t\t\tif err != nil {\n\t\t\t\t\t// handle error\n\t\t\t\t}\n\t\t\t\tif header.Masked {\n\t\t\t\t\tws.Cipher(payload, header.Mask, 0)\n\t\t\t\t}\n\n\t\t\t\t// Reset the Masked flag, server frames must not be masked as\n\t\t\t\t// RFC6455 says.\n\t\t\t\theader.Masked = false\n\n\t\t\t\tif err := ws.WriteHeader(conn, header); err != nil {\n\t\t\t\t\t// handle error\n\t\t\t\t}\n\t\t\t\tif _, err := conn.Write(payload); err != nil {\n\t\t\t\t\t// handle error\n\t\t\t\t}\n\n\t\t\t\tif header.OpCode == ws.OpClose {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\t}\n}\n```\n\n# Zero-copy upgrade\n\nZero-copy upgrade helps to avoid unnecessary allocations and copying while\nhandling HTTP Upgrade request.\n\nProcessing of all non-websocket headers is made in place with use of registered\nuser callbacks whose arguments are only valid until callback returns.\n\nThe simple example looks like this:\n\n```go\npackage main\n\nimport (\n\t\"net\"\n\t\"log\"\n\n\t\"github.com/gobwas/ws\"\n)\n\nfunc main() {\n\tln, err := net.Listen(\"tcp\", \"localhost:8080\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tu := ws.Upgrader{\n\t\tOnHeader: func(key, value []byte) (err error) {\n\t\t\tlog.Printf(\"non-websocket header: %q=%q\", key, value)\n\t\t\treturn\n\t\t},\n\t}\n\tfor {\n\t\tconn, err := ln.Accept()\n\t\tif err != nil {\n\t\t\t// handle error\n\t\t}\n\n\t\t_, err = u.Upgrade(conn)\n\t\tif err != nil {\n\t\t\t// handle error\n\t\t}\n\t}\n}\n```\n\nUsage of `ws.Upgrader` here brings ability to control incoming connections on\ntcp level and simply not to accept them by some logic.\n\nZero-copy upgrade is for high-load services which have to control many\nresources such as connections buffers.\n\nThe real life example could be like this:\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"net\"\n\t\"net/http\"\n\t\"runtime\"\n\n\t\"github.com/gobwas/httphead\"\n\t\"github.com/gobwas/ws\"\n)\n\nfunc main() {\n\tln, err := net.Listen(\"tcp\", \"localhost:8080\")\n\tif err != nil {\n\t\t// handle error\n\t}\n\n\t// Prepare handshake header writer from http.Header mapping.\n\theader := ws.HandshakeHeaderHTTP(http.Header{\n\t\t\"X-Go-Version\": []string{runtime.Version()},\n\t})\n\n\tu := ws.Upgrader{\n\t\tOnHost: func(host []byte) error {\n\t\t\tif string(host) == \"github.com\" {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn ws.RejectConnectionError(\n\t\t\t\tws.RejectionStatus(403),\n\t\t\t\tws.RejectionHeader(ws.HandshakeHeaderString(\n\t\t\t\t\t\"X-Want-Host: github.com\\r\\n\",\n\t\t\t\t)),\n\t\t\t)\n\t\t},\n\t\tOnHeader: func(key, value []byte) error {\n\t\t\tif string(key) != \"Cookie\" {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tok := httphead.ScanCookie(value, func(key, value []byte) bool {\n\t\t\t\t// Check session here or do some other stuff with cookies.\n\t\t\t\t// Maybe copy some values for future use.\n\t\t\t\treturn true\n\t\t\t})\n\t\t\tif ok {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn ws.RejectConnectionError(\n\t\t\t\tws.RejectionReason(\"bad cookie\"),\n\t\t\t\tws.RejectionStatus(400),\n\t\t\t)\n\t\t},\n\t\tOnBeforeUpgrade: func() (ws.HandshakeHeader, error) {\n\t\t\treturn header, nil\n\t\t},\n\t}\n\tfor {\n\t\tconn, err := ln.Accept()\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\t_, err = u.Upgrade(conn)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"upgrade error: %s\", err)\n\t\t}\n\t}\n}\n```\n\n# Compression\n\nThere is a `ws/wsflate` package to support [Permessage-Deflate Compression\nExtension][rfc-pmce].\n\nIt provides minimalistic I/O wrappers to be used in conjunction with any\ndeflate implementation (for example, the standard library's\n[compress/flate][compress/flate]).\n\nIt is also compatible with `wsutil`'s reader and writer by providing\n`wsflate.MessageState` type, which implements `wsutil.SendExtension` and\n`wsutil.RecvExtension` interfaces.\n\n```go\npackage main\n\nimport (\n\t\"bytes\"\n\t\"log\"\n\t\"net\"\n\n\t\"github.com/gobwas/ws\"\n\t\"github.com/gobwas/ws/wsflate\"\n)\n\nfunc main() {\n\tln, err := net.Listen(\"tcp\", \"localhost:8080\")\n\tif err != nil {\n\t\t// handle error\n\t}\n\te := wsflate.Extension{\n\t\t// We are using default parameters here since we use\n\t\t// wsflate.{Compress,Decompress}Frame helpers below in the code.\n\t\t// This assumes that we use standard compress/flate package as flate\n\t\t// implementation.\n\t\tParameters: wsflate.DefaultParameters,\n\t}\n\tu := ws.Upgrader{\n\t\tNegotiate: e.Negotiate,\n\t}\n\tfor {\n\t\tconn, err := ln.Accept()\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\n\t\t// Reset extension after previous upgrades.\n\t\te.Reset()\n\n\t\t_, err = u.Upgrade(conn)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"upgrade error: %s\", err)\n\t\t\tcontinue\n\t\t}\n\t\tif _, ok := e.Accepted(); !ok {\n\t\t\tlog.Printf(\"didn't negotiate compression for %s\", conn.RemoteAddr())\n\t\t\tconn.Close()\n\t\t\tcontinue\n\t\t}\n\n\t\tgo func() {\n\t\t\tdefer conn.Close()\n\t\t\tfor {\n\t\t\t\tframe, err := ws.ReadFrame(conn)\n\t\t\t\tif err != nil {\n\t\t\t\t\t// Handle error.\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tframe = ws.UnmaskFrameInPlace(frame)\n\n\t\t\t\tif wsflate.IsCompressed(frame.Header) {\n\t\t\t\t\t// Note that even after successful negotiation of\n\t\t\t\t\t// compression extension, both sides are able to send\n\t\t\t\t\t// non-compressed messages.\n\t\t\t\t\tframe, err = wsflate.DecompressFrame(frame)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t// Handle error.\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Do something with frame...\n\n\t\t\t\tack := ws.NewTextFrame([]byte(\"this is an acknowledgement\"))\n\n\t\t\t\t// Compress response unconditionally.\n\t\t\t\tack, err = wsflate.CompressFrame(ack)\n\t\t\t\tif err != nil {\n\t\t\t\t\t// Handle error.\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif err = ws.WriteFrame(conn, ack); err != nil {\n\t\t\t\t\t// Handle error.\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\t}\n}\n```\n\nYou can use compression with `wsutil` package this way:\n\n```go\n\t// Upgrade somehow and negotiate compression to get the conn...\n\n\t// Initialize flate reader. We are using nil as a source io.Reader because\n\t// we will Reset() it in the message i/o loop below.\n\tfr := wsflate.NewReader(nil, func(r io.Reader) wsflate.Decompressor {\n\t\treturn flate.NewReader(r)\n\t})\n\t// Initialize flate writer. We are using nil as a destination io.Writer\n\t// because we will Reset() it in the message i/o loop below.\n\tfw := wsflate.NewWriter(nil, func(w io.Writer) wsflate.Compressor {\n\t\tf, _ := flate.NewWriter(w, 9)\n\t\treturn f\n\t})\n\n\t// Declare compression message state variable.\n\t//\n\t// It has two goals:\n\t// - Allow users to check whether received message is compressed or not.\n\t// - Help wsutil.Reader and wsutil.Writer to set/unset appropriate\n\t//   WebSocket header bits while writing next frame to the wire (it\n\t//   implements wsutil.RecvExtension and wsutil.SendExtension).\n\tvar msg wsflate.MessageState\n\n\t// Initialize WebSocket reader as previously. \n\t// Please note the use of Reader.Extensions field as well as\n\t// of ws.StateExtended flag.\n\trd := &wsutil.Reader{\n\t\tSource:     conn,\n\t\tState:      ws.StateServerSide | ws.StateExtended,\n\t\tExtensions: []wsutil.RecvExtension{\n\t\t\t&msg, \n\t\t},\n\t}\n\n\t// Initialize WebSocket writer with ws.StateExtended flag as well.\n\twr := wsutil.NewWriter(conn, ws.StateServerSide|ws.StateExtended, 0)\n\t// Use the message state as wsutil.SendExtension.\n\twr.SetExtensions(&msg)\n\n\tfor {\n\t\th, err := rd.NextFrame()\n\t\tif err != nil {\n\t\t\t// handle error.\n\t\t}\n\t\tif h.OpCode.IsControl() {\n\t\t\t// handle control frame.\n\t\t}\n\t\tif !msg.IsCompressed() {\n\t\t\t// handle uncompressed frame (skipped for the sake of example\n\t\t\t// simplicity).\n\t\t}\n\n\t\t// Reset the writer to echo same op code.\n\t\twr.Reset(h.OpCode)\n\n\t\t// Reset both flate reader and writer to start the new round of i/o.\n\t\tfr.Reset(rd)\n\t\tfw.Reset(wr)\n\n\t\t// Copy whole message from reader to writer decompressing it and\n\t\t// compressing again.\n\t\tif _, err := io.Copy(fw, fr); err != nil {\n\t\t\t// handle error.\n\t\t}\n\t\t// Flush any remaining buffers from flate writer to WebSocket writer.\n\t\tif err := fw.Close(); err != nil {\n\t\t\t// handle error.\n\t\t}\n\t\t// Flush the whole WebSocket message to the wire.\n\t\tif err := wr.Flush(); err != nil {\n\t\t\t// handle error.\n\t\t}\n\t}\n```\n\n\n[rfc-url]: https://tools.ietf.org/html/rfc6455\n[rfc-pmce]: https://tools.ietf.org/html/rfc7692#section-7\n[godoc-image]: https://godoc.org/github.com/gobwas/ws?status.svg\n[godoc-url]: https://godoc.org/github.com/gobwas/ws\n[compress/flate]: https://golang.org/pkg/compress/flate/\n[ci-badge]:    https://github.com/gobwas/ws/workflows/CI/badge.svg\n[ci-url]:      https://github.com/gobwas/ws/actions?query=workflow%3ACI\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/check.go",
    "content": "package ws\n\nimport \"unicode/utf8\"\n\n// State represents state of websocket endpoint.\n// It used by some functions to be more strict when checking compatibility with RFC6455.\ntype State uint8\n\nconst (\n\t// StateServerSide means that endpoint (caller) is a server.\n\tStateServerSide State = 0x1 << iota\n\t// StateClientSide means that endpoint (caller) is a client.\n\tStateClientSide\n\t// StateExtended means that extension was negotiated during handshake.\n\tStateExtended\n\t// StateFragmented means that endpoint (caller) has received fragmented\n\t// frame and waits for continuation parts.\n\tStateFragmented\n)\n\n// Is checks whether the s has v enabled.\nfunc (s State) Is(v State) bool {\n\treturn uint8(s)&uint8(v) != 0\n}\n\n// Set enables v state on s.\nfunc (s State) Set(v State) State {\n\treturn s | v\n}\n\n// Clear disables v state on s.\nfunc (s State) Clear(v State) State {\n\treturn s & (^v)\n}\n\n// ServerSide reports whether states represents server side.\nfunc (s State) ServerSide() bool { return s.Is(StateServerSide) }\n\n// ClientSide reports whether state represents client side.\nfunc (s State) ClientSide() bool { return s.Is(StateClientSide) }\n\n// Extended reports whether state is extended.\nfunc (s State) Extended() bool { return s.Is(StateExtended) }\n\n// Fragmented reports whether state is fragmented.\nfunc (s State) Fragmented() bool { return s.Is(StateFragmented) }\n\n// ProtocolError describes error during checking/parsing websocket frames or\n// headers.\ntype ProtocolError string\n\n// Error implements error interface.\nfunc (p ProtocolError) Error() string { return string(p) }\n\n// Errors used by the protocol checkers.\nvar (\n\tErrProtocolOpCodeReserved             = ProtocolError(\"use of reserved op code\")\n\tErrProtocolControlPayloadOverflow     = ProtocolError(\"control frame payload limit exceeded\")\n\tErrProtocolControlNotFinal            = ProtocolError(\"control frame is not final\")\n\tErrProtocolNonZeroRsv                 = ProtocolError(\"non-zero rsv bits with no extension negotiated\")\n\tErrProtocolMaskRequired               = ProtocolError(\"frames from client to server must be masked\")\n\tErrProtocolMaskUnexpected             = ProtocolError(\"frames from server to client must be not masked\")\n\tErrProtocolContinuationExpected       = ProtocolError(\"unexpected non-continuation data frame\")\n\tErrProtocolContinuationUnexpected     = ProtocolError(\"unexpected continuation data frame\")\n\tErrProtocolStatusCodeNotInUse         = ProtocolError(\"status code is not in use\")\n\tErrProtocolStatusCodeApplicationLevel = ProtocolError(\"status code is only application level\")\n\tErrProtocolStatusCodeNoMeaning        = ProtocolError(\"status code has no meaning yet\")\n\tErrProtocolStatusCodeUnknown          = ProtocolError(\"status code is not defined in spec\")\n\tErrProtocolInvalidUTF8                = ProtocolError(\"invalid utf8 sequence in close reason\")\n)\n\n// CheckHeader checks h to contain valid header data for given state s.\n//\n// Note that zero state (0) means that state is clean,\n// neither server or client side, nor fragmented, nor extended.\nfunc CheckHeader(h Header, s State) error {\n\tif h.OpCode.IsReserved() {\n\t\treturn ErrProtocolOpCodeReserved\n\t}\n\tif h.OpCode.IsControl() {\n\t\tif h.Length > MaxControlFramePayloadSize {\n\t\t\treturn ErrProtocolControlPayloadOverflow\n\t\t}\n\t\tif !h.Fin {\n\t\t\treturn ErrProtocolControlNotFinal\n\t\t}\n\t}\n\n\tswitch {\n\t// [RFC6455]: MUST be 0 unless an extension is negotiated that defines meanings for\n\t// non-zero values. If a nonzero value is received and none of the\n\t// negotiated extensions defines the meaning of such a nonzero value, the\n\t// receiving endpoint MUST _Fail the WebSocket Connection_.\n\tcase h.Rsv != 0 && !s.Extended():\n\t\treturn ErrProtocolNonZeroRsv\n\n\t// [RFC6455]: The server MUST close the connection upon receiving a frame that is not masked.\n\t// In this case, a server MAY send a Close frame with a status code of 1002 (protocol error)\n\t// as defined in Section 7.4.1. A server MUST NOT mask any frames that it sends to the client.\n\t// A client MUST close a connection if it detects a masked frame. In this case, it MAY use the\n\t// status code 1002 (protocol error) as defined in Section 7.4.1.\n\tcase s.ServerSide() && !h.Masked:\n\t\treturn ErrProtocolMaskRequired\n\tcase s.ClientSide() && h.Masked:\n\t\treturn ErrProtocolMaskUnexpected\n\n\t// [RFC6455]: See detailed explanation in 5.4 section.\n\tcase s.Fragmented() && !h.OpCode.IsControl() && h.OpCode != OpContinuation:\n\t\treturn ErrProtocolContinuationExpected\n\tcase !s.Fragmented() && h.OpCode == OpContinuation:\n\t\treturn ErrProtocolContinuationUnexpected\n\n\tdefault:\n\t\treturn nil\n\t}\n}\n\n// CheckCloseFrameData checks received close information\n// to be valid RFC6455 compatible close info.\n//\n// Note that code.Empty() or code.IsAppLevel() will raise error.\n//\n// If endpoint sends close frame without status code (with frame.Length = 0),\n// application should not check its payload.\nfunc CheckCloseFrameData(code StatusCode, reason string) error {\n\tswitch {\n\tcase code.IsNotUsed():\n\t\treturn ErrProtocolStatusCodeNotInUse\n\n\tcase code.IsProtocolReserved():\n\t\treturn ErrProtocolStatusCodeApplicationLevel\n\n\tcase code == StatusNoMeaningYet:\n\t\treturn ErrProtocolStatusCodeNoMeaning\n\n\tcase code.IsProtocolSpec() && !code.IsProtocolDefined():\n\t\treturn ErrProtocolStatusCodeUnknown\n\n\tcase !utf8.ValidString(reason):\n\t\treturn ErrProtocolInvalidUTF8\n\n\tdefault:\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/cipher.go",
    "content": "package ws\n\nimport (\n\t\"encoding/binary\"\n)\n\n// Cipher applies XOR cipher to the payload using mask.\n// Offset is used to cipher chunked data (e.g. in io.Reader implementations).\n//\n// To convert masked data into unmasked data, or vice versa, the following\n// algorithm is applied.  The same algorithm applies regardless of the\n// direction of the translation, e.g., the same steps are applied to\n// mask the data as to unmask the data.\nfunc Cipher(payload []byte, mask [4]byte, offset int) {\n\tn := len(payload)\n\tif n < 8 {\n\t\tfor i := 0; i < n; i++ {\n\t\t\tpayload[i] ^= mask[(offset+i)%4]\n\t\t}\n\t\treturn\n\t}\n\n\t// Calculate position in mask due to previously processed bytes number.\n\tmpos := offset % 4\n\t// Count number of bytes will processed one by one from the beginning of payload.\n\tln := remain[mpos]\n\t// Count number of bytes will processed one by one from the end of payload.\n\t// This is done to process payload by 8 bytes in each iteration of main loop.\n\trn := (n - ln) % 8\n\n\tfor i := 0; i < ln; i++ {\n\t\tpayload[i] ^= mask[(mpos+i)%4]\n\t}\n\tfor i := n - rn; i < n; i++ {\n\t\tpayload[i] ^= mask[(mpos+i)%4]\n\t}\n\n\t// NOTE: we use here binary.LittleEndian regardless of what is real\n\t// endianness on machine is. To do so, we have to use binary.LittleEndian in\n\t// the masking loop below as well.\n\tvar (\n\t\tm  = binary.LittleEndian.Uint32(mask[:])\n\t\tm2 = uint64(m)<<32 | uint64(m)\n\t)\n\t// Skip already processed right part.\n\t// Get number of uint64 parts remaining to process.\n\tn = (n - ln - rn) >> 3\n\tfor i := 0; i < n; i++ {\n\t\tvar (\n\t\t\tj     = ln + (i << 3)\n\t\t\tchunk = payload[j : j+8]\n\t\t)\n\t\tp := binary.LittleEndian.Uint64(chunk)\n\t\tp = p ^ m2\n\t\tbinary.LittleEndian.PutUint64(chunk, p)\n\t}\n}\n\n// remain maps position in masking key [0,4) to number\n// of bytes that need to be processed manually inside Cipher().\nvar remain = [4]int{0, 3, 2, 1}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/dialer.go",
    "content": "package ws\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/gobwas/httphead\"\n\t\"github.com/gobwas/pool/pbufio\"\n)\n\n// Constants used by Dialer.\nconst (\n\tDefaultClientReadBufferSize  = 4096\n\tDefaultClientWriteBufferSize = 4096\n)\n\n// Handshake represents handshake result.\ntype Handshake struct {\n\t// Protocol is the subprotocol selected during handshake.\n\tProtocol string\n\n\t// Extensions is the list of negotiated extensions.\n\tExtensions []httphead.Option\n}\n\n// Errors used by the websocket client.\nvar (\n\tErrHandshakeBadStatus      = fmt.Errorf(\"unexpected http status\")\n\tErrHandshakeBadSubProtocol = fmt.Errorf(\"unexpected protocol in %q header\", headerSecProtocol)\n\tErrHandshakeBadExtensions  = fmt.Errorf(\"unexpected extensions in %q header\", headerSecProtocol)\n)\n\n// DefaultDialer is dialer that holds no options and is used by Dial function.\nvar DefaultDialer Dialer\n\n// Dial is like Dialer{}.Dial().\nfunc Dial(ctx context.Context, urlstr string) (net.Conn, *bufio.Reader, Handshake, error) {\n\treturn DefaultDialer.Dial(ctx, urlstr)\n}\n\n// Dialer contains options for establishing websocket connection to an url.\ntype Dialer struct {\n\t// ReadBufferSize and WriteBufferSize is an I/O buffer sizes.\n\t// They used to read and write http data while upgrading to WebSocket.\n\t// Allocated buffers are pooled with sync.Pool to avoid extra allocations.\n\t//\n\t// If a size is zero then default value is used.\n\tReadBufferSize, WriteBufferSize int\n\n\t// Timeout is the maximum amount of time a Dial() will wait for a connect\n\t// and an handshake to complete.\n\t//\n\t// The default is no timeout.\n\tTimeout time.Duration\n\n\t// Protocols is the list of subprotocols that the client wants to speak,\n\t// ordered by preference.\n\t//\n\t// See https://tools.ietf.org/html/rfc6455#section-4.1\n\tProtocols []string\n\n\t// Extensions is the list of extensions that client wants to speak.\n\t//\n\t// Note that if server decides to use some of this extensions, Dial() will\n\t// return Handshake struct containing a slice of items, which are the\n\t// shallow copies of the items from this list. That is, internals of\n\t// Extensions items are shared during Dial().\n\t//\n\t// See https://tools.ietf.org/html/rfc6455#section-4.1\n\t// See https://tools.ietf.org/html/rfc6455#section-9.1\n\tExtensions []httphead.Option\n\n\t// Header is an optional HandshakeHeader instance that could be used to\n\t// write additional headers to the handshake request.\n\t//\n\t// It used instead of any key-value mappings to avoid allocations in user\n\t// land.\n\tHeader HandshakeHeader\n\n\t// OnStatusError is the callback that will be called after receiving non\n\t// \"101 Continue\" HTTP response status. It receives an io.Reader object\n\t// representing server response bytes. That is, it gives ability to parse\n\t// HTTP response somehow (probably with http.ReadResponse call) and make a\n\t// decision of further logic.\n\t//\n\t// The arguments are only valid until the callback returns.\n\tOnStatusError func(status int, reason []byte, resp io.Reader)\n\n\t// OnHeader is the callback that will be called after successful parsing of\n\t// header, that is not used during WebSocket handshake procedure. That is,\n\t// it will be called with non-websocket headers, which could be relevant\n\t// for application-level logic.\n\t//\n\t// The arguments are only valid until the callback returns.\n\t//\n\t// Returned value could be used to prevent processing response.\n\tOnHeader func(key, value []byte) (err error)\n\n\t// NetDial is the function that is used to get plain tcp connection.\n\t// If it is not nil, then it is used instead of net.Dialer.\n\tNetDial func(ctx context.Context, network, addr string) (net.Conn, error)\n\n\t// TLSClient is the callback that will be called after successful dial with\n\t// received connection and its remote host name. If it is nil, then the\n\t// default tls.Client() will be used.\n\t// If it is not nil, then TLSConfig field is ignored.\n\tTLSClient func(conn net.Conn, hostname string) net.Conn\n\n\t// TLSConfig is passed to tls.Client() to start TLS over established\n\t// connection. If TLSClient is not nil, then it is ignored. If TLSConfig is\n\t// non-nil and its ServerName is empty, then for every Dial() it will be\n\t// cloned and appropriate ServerName will be set.\n\tTLSConfig *tls.Config\n\n\t// WrapConn is the optional callback that will be called when connection is\n\t// ready for an i/o. That is, it will be called after successful dial and\n\t// TLS initialization (for \"wss\" schemes). It may be helpful for different\n\t// user land purposes such as end to end encryption.\n\t//\n\t// Note that for debugging purposes of an http handshake (e.g. sent request\n\t// and received response), there is an wsutil.DebugDialer struct.\n\tWrapConn func(conn net.Conn) net.Conn\n}\n\n// Dial connects to the url host and upgrades connection to WebSocket.\n//\n// If server has sent frames right after successful handshake then returned\n// buffer will be non-nil. In other cases buffer is always nil. For better\n// memory efficiency received non-nil bufio.Reader should be returned to the\n// inner pool with PutReader() function after use.\n//\n// Note that Dialer does not implement IDNA (RFC5895) logic as net/http does.\n// If you want to dial non-ascii host name, take care of its name serialization\n// avoiding bad request issues. For more info see net/http Request.Write()\n// implementation, especially cleanHost() function.\nfunc (d Dialer) Dial(ctx context.Context, urlstr string) (conn net.Conn, br *bufio.Reader, hs Handshake, err error) {\n\tu, err := url.ParseRequestURI(urlstr)\n\tif err != nil {\n\t\treturn nil, nil, hs, err\n\t}\n\n\t// Prepare context to dial with. Initially it is the same as original, but\n\t// if d.Timeout is non-zero and points to time that is before ctx.Deadline,\n\t// we use more shorter context for dial.\n\tdialctx := ctx\n\n\tvar deadline time.Time\n\tif t := d.Timeout; t != 0 {\n\t\tdeadline = time.Now().Add(t)\n\t\tif d, ok := ctx.Deadline(); !ok || deadline.Before(d) {\n\t\t\tvar cancel context.CancelFunc\n\t\t\tdialctx, cancel = context.WithDeadline(ctx, deadline)\n\t\t\tdefer cancel()\n\t\t}\n\t}\n\tif conn, err = d.dial(dialctx, u); err != nil {\n\t\treturn conn, nil, hs, err\n\t}\n\tdefer func() {\n\t\tif err != nil {\n\t\t\tconn.Close()\n\t\t}\n\t}()\n\tif ctx == context.Background() {\n\t\t// No need to start I/O interrupter goroutine which is not zero-cost.\n\t\tconn.SetDeadline(deadline)\n\t\tdefer conn.SetDeadline(noDeadline)\n\t} else {\n\t\t// Context could be canceled or its deadline could be exceeded.\n\t\t// Start the interrupter goroutine to handle context cancelation.\n\t\tdone := setupContextDeadliner(ctx, conn)\n\t\tdefer func() {\n\t\t\t// Map Upgrade() error to a possible context expiration error. That\n\t\t\t// is, even if Upgrade() err is nil, context could be already\n\t\t\t// expired and connection be \"poisoned\" by SetDeadline() call.\n\t\t\t// In that case we must not return ctx.Err() error.\n\t\t\tdone(&err)\n\t\t}()\n\t}\n\n\tbr, hs, err = d.Upgrade(conn, u)\n\n\treturn conn, br, hs, err\n}\n\nvar (\n\t// netEmptyDialer is a net.Dialer without options, used in Dialer.dial() if\n\t// Dialer.NetDial is not provided.\n\tnetEmptyDialer net.Dialer\n\t// tlsEmptyConfig is an empty tls.Config used as default one.\n\ttlsEmptyConfig tls.Config\n)\n\nfunc tlsDefaultConfig() *tls.Config {\n\treturn &tlsEmptyConfig\n}\n\nfunc hostport(host, defaultPort string) (hostname, addr string) {\n\tvar (\n\t\tcolon   = strings.LastIndexByte(host, ':')\n\t\tbracket = strings.IndexByte(host, ']')\n\t)\n\tif colon > bracket {\n\t\treturn host[:colon], host\n\t}\n\treturn host, host + defaultPort\n}\n\nfunc (d Dialer) dial(ctx context.Context, u *url.URL) (conn net.Conn, err error) {\n\tdial := d.NetDial\n\tif dial == nil {\n\t\tdial = netEmptyDialer.DialContext\n\t}\n\tswitch u.Scheme {\n\tcase \"ws\":\n\t\t_, addr := hostport(u.Host, \":80\")\n\t\tconn, err = dial(ctx, \"tcp\", addr)\n\tcase \"wss\":\n\t\thostname, addr := hostport(u.Host, \":443\")\n\t\tconn, err = dial(ctx, \"tcp\", addr)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ttlsClient := d.TLSClient\n\t\tif tlsClient == nil {\n\t\t\ttlsClient = d.tlsClient\n\t\t}\n\t\tconn = tlsClient(conn, hostname)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unexpected websocket scheme: %q\", u.Scheme)\n\t}\n\tif wrap := d.WrapConn; wrap != nil {\n\t\tconn = wrap(conn)\n\t}\n\treturn conn, err\n}\n\nfunc (d Dialer) tlsClient(conn net.Conn, hostname string) net.Conn {\n\tconfig := d.TLSConfig\n\tif config == nil {\n\t\tconfig = tlsDefaultConfig()\n\t}\n\tif config.ServerName == \"\" {\n\t\tconfig = tlsCloneConfig(config)\n\t\tconfig.ServerName = hostname\n\t}\n\t// Do not make conn.Handshake() here because downstairs we will prepare\n\t// i/o on this conn with proper context's timeout handling.\n\treturn tls.Client(conn, config)\n}\n\nvar (\n\t// This variables are set like in net/net.go.\n\t// noDeadline is just zero value for readability.\n\tnoDeadline = time.Time{}\n\t// aLongTimeAgo is a non-zero time, far in the past, used for immediate\n\t// cancelation of dials.\n\taLongTimeAgo = time.Unix(42, 0)\n)\n\n// Upgrade writes an upgrade request to the given io.ReadWriter conn at given\n// url u and reads a response from it.\n//\n// It is a caller responsibility to manage I/O deadlines on conn.\n//\n// It returns handshake info and some bytes which could be written by the peer\n// right after response and be caught by us during buffered read.\nfunc (d Dialer) Upgrade(conn io.ReadWriter, u *url.URL) (br *bufio.Reader, hs Handshake, err error) {\n\t// headerSeen constants helps to report whether or not some header was seen\n\t// during reading request bytes.\n\tconst (\n\t\theaderSeenUpgrade = 1 << iota\n\t\theaderSeenConnection\n\t\theaderSeenSecAccept\n\n\t\t// headerSeenAll is the value that we expect to receive at the end of\n\t\t// headers read/parse loop.\n\t\theaderSeenAll = 0 |\n\t\t\theaderSeenUpgrade |\n\t\t\theaderSeenConnection |\n\t\t\theaderSeenSecAccept\n\t)\n\n\tbr = pbufio.GetReader(conn,\n\t\tnonZero(d.ReadBufferSize, DefaultClientReadBufferSize),\n\t)\n\tbw := pbufio.GetWriter(conn,\n\t\tnonZero(d.WriteBufferSize, DefaultClientWriteBufferSize),\n\t)\n\tdefer func() {\n\t\tpbufio.PutWriter(bw)\n\t\tif br.Buffered() == 0 || err != nil {\n\t\t\t// Server does not wrote additional bytes to the connection or\n\t\t\t// error occurred. That is, no reason to return buffer.\n\t\t\tpbufio.PutReader(br)\n\t\t\tbr = nil\n\t\t}\n\t}()\n\n\tnonce := make([]byte, nonceSize)\n\tinitNonce(nonce)\n\n\thttpWriteUpgradeRequest(bw, u, nonce, d.Protocols, d.Extensions, d.Header)\n\tif err := bw.Flush(); err != nil {\n\t\treturn br, hs, err\n\t}\n\n\t// Read HTTP status line like \"HTTP/1.1 101 Switching Protocols\".\n\tsl, err := readLine(br)\n\tif err != nil {\n\t\treturn br, hs, err\n\t}\n\t// Begin validation of the response.\n\t// See https://tools.ietf.org/html/rfc6455#section-4.2.2\n\t// Parse request line data like HTTP version, uri and method.\n\tresp, err := httpParseResponseLine(sl)\n\tif err != nil {\n\t\treturn br, hs, err\n\t}\n\t// Even if RFC says \"1.1 or higher\" without mentioning the part of the\n\t// version, we apply it only to minor part.\n\tif resp.major != 1 || resp.minor < 1 {\n\t\terr = ErrHandshakeBadProtocol\n\t\treturn br, hs, err\n\t}\n\tif resp.status != http.StatusSwitchingProtocols {\n\t\terr = StatusError(resp.status)\n\t\tif onStatusError := d.OnStatusError; onStatusError != nil {\n\t\t\t// Invoke callback with multireader of status-line bytes br.\n\t\t\tonStatusError(resp.status, resp.reason,\n\t\t\t\tio.MultiReader(\n\t\t\t\t\tbytes.NewReader(sl),\n\t\t\t\t\tstrings.NewReader(crlf),\n\t\t\t\t\tbr,\n\t\t\t\t),\n\t\t\t)\n\t\t}\n\t\treturn br, hs, err\n\t}\n\t// If response status is 101 then we expect all technical headers to be\n\t// valid. If not, then we stop processing response without giving user\n\t// ability to read non-technical headers. That is, we do not distinguish\n\t// technical errors (such as parsing error) and protocol errors.\n\tvar headerSeen byte\n\tfor {\n\t\tline, e := readLine(br)\n\t\tif e != nil {\n\t\t\terr = e\n\t\t\treturn br, hs, err\n\t\t}\n\t\tif len(line) == 0 {\n\t\t\t// Blank line, no more lines to read.\n\t\t\tbreak\n\t\t}\n\n\t\tk, v, ok := httpParseHeaderLine(line)\n\t\tif !ok {\n\t\t\terr = ErrMalformedResponse\n\t\t\treturn br, hs, err\n\t\t}\n\n\t\tswitch btsToString(k) {\n\t\tcase headerUpgradeCanonical:\n\t\t\theaderSeen |= headerSeenUpgrade\n\t\t\tif !bytes.Equal(v, specHeaderValueUpgrade) && !bytes.EqualFold(v, specHeaderValueUpgrade) {\n\t\t\t\terr = ErrHandshakeBadUpgrade\n\t\t\t\treturn br, hs, err\n\t\t\t}\n\n\t\tcase headerConnectionCanonical:\n\t\t\theaderSeen |= headerSeenConnection\n\t\t\t// Note that as RFC6455 says:\n\t\t\t//   > A |Connection| header field with value \"Upgrade\".\n\t\t\t// That is, in server side, \"Connection\" header could contain\n\t\t\t// multiple token. But in response it must contains exactly one.\n\t\t\tif !bytes.Equal(v, specHeaderValueConnection) && !bytes.EqualFold(v, specHeaderValueConnection) {\n\t\t\t\terr = ErrHandshakeBadConnection\n\t\t\t\treturn br, hs, err\n\t\t\t}\n\n\t\tcase headerSecAcceptCanonical:\n\t\t\theaderSeen |= headerSeenSecAccept\n\t\t\tif !checkAcceptFromNonce(v, nonce) {\n\t\t\t\terr = ErrHandshakeBadSecAccept\n\t\t\t\treturn br, hs, err\n\t\t\t}\n\n\t\tcase headerSecProtocolCanonical:\n\t\t\t// RFC6455 1.3:\n\t\t\t//   \"The server selects one or none of the acceptable protocols\n\t\t\t//   and echoes that value in its handshake to indicate that it has\n\t\t\t//   selected that protocol.\"\n\t\t\tfor _, want := range d.Protocols {\n\t\t\t\tif string(v) == want {\n\t\t\t\t\ths.Protocol = want\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif hs.Protocol == \"\" {\n\t\t\t\t// Server echoed subprotocol that is not present in client\n\t\t\t\t// requested protocols.\n\t\t\t\terr = ErrHandshakeBadSubProtocol\n\t\t\t\treturn br, hs, err\n\t\t\t}\n\n\t\tcase headerSecExtensionsCanonical:\n\t\t\ths.Extensions, err = matchSelectedExtensions(v, d.Extensions, hs.Extensions)\n\t\t\tif err != nil {\n\t\t\t\treturn br, hs, err\n\t\t\t}\n\n\t\tdefault:\n\t\t\tif onHeader := d.OnHeader; onHeader != nil {\n\t\t\t\tif e := onHeader(k, v); e != nil {\n\t\t\t\t\terr = e\n\t\t\t\t\treturn br, hs, err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif err == nil && headerSeen != headerSeenAll {\n\t\tswitch {\n\t\tcase headerSeen&headerSeenUpgrade == 0:\n\t\t\terr = ErrHandshakeBadUpgrade\n\t\tcase headerSeen&headerSeenConnection == 0:\n\t\t\terr = ErrHandshakeBadConnection\n\t\tcase headerSeen&headerSeenSecAccept == 0:\n\t\t\terr = ErrHandshakeBadSecAccept\n\t\tdefault:\n\t\t\tpanic(\"unknown headers state\")\n\t\t}\n\t}\n\treturn br, hs, err\n}\n\n// PutReader returns bufio.Reader instance to the inner reuse pool.\n// It is useful in rare cases, when Dialer.Dial() returns non-nil buffer which\n// contains unprocessed buffered data, that was sent by the server quickly\n// right after handshake.\nfunc PutReader(br *bufio.Reader) {\n\tpbufio.PutReader(br)\n}\n\n// StatusError contains an unexpected status-line code from the server.\ntype StatusError int\n\nfunc (s StatusError) Error() string {\n\treturn \"unexpected HTTP response status: \" + strconv.Itoa(int(s))\n}\n\nfunc isTimeoutError(err error) bool {\n\tt, ok := err.(net.Error)\n\treturn ok && t.Timeout()\n}\n\nfunc matchSelectedExtensions(selected []byte, wanted, received []httphead.Option) ([]httphead.Option, error) {\n\tif len(selected) == 0 {\n\t\treturn received, nil\n\t}\n\tvar (\n\t\tindex  int\n\t\toption httphead.Option\n\t\terr    error\n\t)\n\tindex = -1\n\tmatch := func() (ok bool) {\n\t\tfor _, want := range wanted {\n\t\t\t// A server accepts one or more extensions by including a\n\t\t\t// |Sec-WebSocket-Extensions| header field containing one or more\n\t\t\t// extensions that were requested by the client.\n\t\t\t//\n\t\t\t// The interpretation of any extension parameters, and what\n\t\t\t// constitutes a valid response by a server to a requested set of\n\t\t\t// parameters by a client, will be defined by each such extension.\n\t\t\tif bytes.Equal(option.Name, want.Name) {\n\t\t\t\t// Check parsed extension to be present in client\n\t\t\t\t// requested extensions. We move matched extension\n\t\t\t\t// from client list to avoid allocation of httphead.Option.Name,\n\t\t\t\t// httphead.Option.Parameters have to be copied from the header\n\t\t\t\twant.Parameters, _ = option.Parameters.Copy(make([]byte, option.Parameters.Size()))\n\t\t\t\treceived = append(received, want)\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\tok := httphead.ScanOptions(selected, func(i int, name, attr, val []byte) httphead.Control {\n\t\tif i != index {\n\t\t\t// Met next option.\n\t\t\tindex = i\n\t\t\tif i != 0 && !match() {\n\t\t\t\t// Server returned non-requested extension.\n\t\t\t\terr = ErrHandshakeBadExtensions\n\t\t\t\treturn httphead.ControlBreak\n\t\t\t}\n\t\t\toption = httphead.Option{Name: name}\n\t\t}\n\t\tif attr != nil {\n\t\t\toption.Parameters.Set(attr, val)\n\t\t}\n\t\treturn httphead.ControlContinue\n\t})\n\tif !ok {\n\t\terr = ErrMalformedResponse\n\t\treturn received, err\n\t}\n\tif !match() {\n\t\treturn received, ErrHandshakeBadExtensions\n\t}\n\treturn received, err\n}\n\n// setupContextDeadliner is a helper function that starts connection I/O\n// interrupter goroutine.\n//\n// Started goroutine calls SetDeadline() with long time ago value when context\n// become expired to make any I/O operations failed. It returns done function\n// that stops started goroutine and maps error received from conn I/O methods\n// to possible context expiration error.\n//\n// In concern with possible SetDeadline() call inside interrupter goroutine,\n// caller passes pointer to its I/O error (even if it is nil) to done(&err).\n// That is, even if I/O error is nil, context could be already expired and\n// connection \"poisoned\" by SetDeadline() call. In that case done(&err) will\n// store at *err ctx.Err() result. If err is caused not by timeout, it will\n// leaved untouched.\nfunc setupContextDeadliner(ctx context.Context, conn net.Conn) (done func(*error)) {\n\tvar (\n\t\tquit      = make(chan struct{})\n\t\tinterrupt = make(chan error, 1)\n\t)\n\tgo func() {\n\t\tselect {\n\t\tcase <-quit:\n\t\t\tinterrupt <- nil\n\t\tcase <-ctx.Done():\n\t\t\t// Cancel i/o immediately.\n\t\t\tconn.SetDeadline(aLongTimeAgo)\n\t\t\tinterrupt <- ctx.Err()\n\t\t}\n\t}()\n\treturn func(err *error) {\n\t\tclose(quit)\n\t\t// If ctx.Err() is non-nil and the original err is net.Error with\n\t\t// Timeout() == true, then it means that I/O was canceled by us by\n\t\t// SetDeadline(aLongTimeAgo) call, or by somebody else previously\n\t\t// by conn.SetDeadline(x).\n\t\t//\n\t\t// Even on race condition when both deadlines are expired\n\t\t// (SetDeadline() made not by us and context's), we prefer ctx.Err() to\n\t\t// be returned.\n\t\tif ctxErr := <-interrupt; ctxErr != nil && (*err == nil || isTimeoutError(*err)) {\n\t\t\t*err = ctxErr\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/dialer_tls_go17.go",
    "content": "// +build !go1.8\n\npackage ws\n\nimport \"crypto/tls\"\n\nfunc tlsCloneConfig(c *tls.Config) *tls.Config {\n\t// NOTE: we copying SessionTicketsDisabled and SessionTicketKey here\n\t// without calling inner c.initOnceServer somehow because we only could get\n\t// here from the ws.Dialer code, which is obviously a client and makes\n\t// tls.Client() when it gets new net.Conn.\n\treturn &tls.Config{\n\t\tRand:                        c.Rand,\n\t\tTime:                        c.Time,\n\t\tCertificates:                c.Certificates,\n\t\tNameToCertificate:           c.NameToCertificate,\n\t\tGetCertificate:              c.GetCertificate,\n\t\tRootCAs:                     c.RootCAs,\n\t\tNextProtos:                  c.NextProtos,\n\t\tServerName:                  c.ServerName,\n\t\tClientAuth:                  c.ClientAuth,\n\t\tClientCAs:                   c.ClientCAs,\n\t\tInsecureSkipVerify:          c.InsecureSkipVerify,\n\t\tCipherSuites:                c.CipherSuites,\n\t\tPreferServerCipherSuites:    c.PreferServerCipherSuites,\n\t\tSessionTicketsDisabled:      c.SessionTicketsDisabled,\n\t\tSessionTicketKey:            c.SessionTicketKey,\n\t\tClientSessionCache:          c.ClientSessionCache,\n\t\tMinVersion:                  c.MinVersion,\n\t\tMaxVersion:                  c.MaxVersion,\n\t\tCurvePreferences:            c.CurvePreferences,\n\t\tDynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,\n\t\tRenegotiation:               c.Renegotiation,\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/dialer_tls_go18.go",
    "content": "//go:build go1.8\n// +build go1.8\n\npackage ws\n\nimport \"crypto/tls\"\n\nfunc tlsCloneConfig(c *tls.Config) *tls.Config {\n\treturn c.Clone()\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/doc.go",
    "content": "/*\nPackage ws implements a client and server for the WebSocket protocol as\nspecified in RFC 6455.\n\nThe main purpose of this package is to provide simple low-level API for\nefficient work with protocol.\n\nOverview.\n\nUpgrade to WebSocket (or WebSocket handshake) can be done in two ways.\n\nThe first way is to use `net/http` server:\n\n\thttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tconn, _, _, err := ws.UpgradeHTTP(r, w)\n\t})\n\nThe second and much more efficient way is so-called \"zero-copy upgrade\". It\navoids redundant allocations and copying of not used headers or other request\ndata. User decides by himself which data should be copied.\n\n\tln, err := net.Listen(\"tcp\", \":8080\")\n\tif err != nil {\n\t\t// handle error\n\t}\n\n\tconn, err := ln.Accept()\n\tif err != nil {\n\t\t// handle error\n\t}\n\n\thandshake, err := ws.Upgrade(conn)\n\tif err != nil {\n\t\t// handle error\n\t}\n\nFor customization details see `ws.Upgrader` documentation.\n\nAfter WebSocket handshake you can work with connection in multiple ways.\nThat is, `ws` does not force the only one way of how to work with WebSocket:\n\n\theader, err := ws.ReadHeader(conn)\n\tif err != nil {\n\t\t// handle err\n\t}\n\n\tbuf := make([]byte, header.Length)\n\t_, err := io.ReadFull(conn, buf)\n\tif err != nil {\n\t\t// handle err\n\t}\n\n\tresp := ws.NewBinaryFrame([]byte(\"hello, world!\"))\n\tif err := ws.WriteFrame(conn, frame); err != nil {\n\t    // handle err\n\t}\n\nAs you can see, it stream friendly:\n\n\tconst N = 42\n\n\tws.WriteHeader(ws.Header{\n\t\tFin:    true,\n\t\tLength: N,\n\t\tOpCode: ws.OpBinary,\n\t})\n\n\tio.CopyN(conn, rand.Reader, N)\n\nOr:\n\n\theader, err := ws.ReadHeader(conn)\n\tif err != nil {\n\t\t// handle err\n\t}\n\n\tio.CopyN(ioutil.Discard, conn, header.Length)\n\nFor more info see the documentation.\n*/\npackage ws\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/errors.go",
    "content": "package ws\n\n// RejectOption represents an option used to control the way connection is\n// rejected.\ntype RejectOption func(*ConnectionRejectedError)\n\n// RejectionReason returns an option that makes connection to be rejected with\n// given reason.\nfunc RejectionReason(reason string) RejectOption {\n\treturn func(err *ConnectionRejectedError) {\n\t\terr.reason = reason\n\t}\n}\n\n// RejectionStatus returns an option that makes connection to be rejected with\n// given HTTP status code.\nfunc RejectionStatus(code int) RejectOption {\n\treturn func(err *ConnectionRejectedError) {\n\t\terr.code = code\n\t}\n}\n\n// RejectionHeader returns an option that makes connection to be rejected with\n// given HTTP headers.\nfunc RejectionHeader(h HandshakeHeader) RejectOption {\n\treturn func(err *ConnectionRejectedError) {\n\t\terr.header = h\n\t}\n}\n\n// RejectConnectionError constructs an error that could be used to control the\n// way handshake is rejected by Upgrader.\nfunc RejectConnectionError(options ...RejectOption) error {\n\terr := new(ConnectionRejectedError)\n\tfor _, opt := range options {\n\t\topt(err)\n\t}\n\treturn err\n}\n\n// ConnectionRejectedError represents a rejection of connection during\n// WebSocket handshake error.\n//\n// It can be returned by Upgrader's On* hooks to indicate that WebSocket\n// handshake should be rejected.\ntype ConnectionRejectedError struct {\n\treason string\n\tcode   int\n\theader HandshakeHeader\n}\n\n// Error implements error interface.\nfunc (r *ConnectionRejectedError) Error() string {\n\treturn r.reason\n}\n\nfunc (r *ConnectionRejectedError) StatusCode() int {\n\treturn r.code\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/frame.go",
    "content": "package ws\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"math/rand\"\n)\n\n// Constants defined by specification.\nconst (\n\t// All control frames MUST have a payload length of 125 bytes or less and MUST NOT be fragmented.\n\tMaxControlFramePayloadSize = 125\n)\n\n// OpCode represents operation code.\ntype OpCode byte\n\n// Operation codes defined by specification.\n// See https://tools.ietf.org/html/rfc6455#section-5.2\nconst (\n\tOpContinuation OpCode = 0x0\n\tOpText         OpCode = 0x1\n\tOpBinary       OpCode = 0x2\n\tOpClose        OpCode = 0x8\n\tOpPing         OpCode = 0x9\n\tOpPong         OpCode = 0xa\n)\n\n// IsControl checks whether the c is control operation code.\n// See https://tools.ietf.org/html/rfc6455#section-5.5\nfunc (c OpCode) IsControl() bool {\n\t// RFC6455: Control frames are identified by opcodes where\n\t// the most significant bit of the opcode is 1.\n\t//\n\t// Note that OpCode is only 4 bit length.\n\treturn c&0x8 != 0\n}\n\n// IsData checks whether the c is data operation code.\n// See https://tools.ietf.org/html/rfc6455#section-5.6\nfunc (c OpCode) IsData() bool {\n\t// RFC6455: Data frames (e.g., non-control frames) are identified by opcodes\n\t// where the most significant bit of the opcode is 0.\n\t//\n\t// Note that OpCode is only 4 bit length.\n\treturn c&0x8 == 0\n}\n\n// IsReserved checks whether the c is reserved operation code.\n// See https://tools.ietf.org/html/rfc6455#section-5.2\nfunc (c OpCode) IsReserved() bool {\n\t// RFC6455:\n\t// %x3-7 are reserved for further non-control frames\n\t// %xB-F are reserved for further control frames\n\treturn (0x3 <= c && c <= 0x7) || (0xb <= c && c <= 0xf)\n}\n\n// StatusCode represents the encoded reason for closure of websocket connection.\n//\n// There are few helper methods on StatusCode that helps to define a range in\n// which given code is lay in. accordingly to ranges defined in specification.\n//\n// See https://tools.ietf.org/html/rfc6455#section-7.4\ntype StatusCode uint16\n\n// StatusCodeRange describes range of StatusCode values.\ntype StatusCodeRange struct {\n\tMin, Max StatusCode\n}\n\n// Status code ranges defined by specification.\n// See https://tools.ietf.org/html/rfc6455#section-7.4.2\nvar (\n\tStatusRangeNotInUse    = StatusCodeRange{0, 999}\n\tStatusRangeProtocol    = StatusCodeRange{1000, 2999}\n\tStatusRangeApplication = StatusCodeRange{3000, 3999}\n\tStatusRangePrivate     = StatusCodeRange{4000, 4999}\n)\n\n// Status codes defined by specification.\n// See https://tools.ietf.org/html/rfc6455#section-7.4.1\nconst (\n\tStatusNormalClosure           StatusCode = 1000\n\tStatusGoingAway               StatusCode = 1001\n\tStatusProtocolError           StatusCode = 1002\n\tStatusUnsupportedData         StatusCode = 1003\n\tStatusNoMeaningYet            StatusCode = 1004\n\tStatusInvalidFramePayloadData StatusCode = 1007\n\tStatusPolicyViolation         StatusCode = 1008\n\tStatusMessageTooBig           StatusCode = 1009\n\tStatusMandatoryExt            StatusCode = 1010\n\tStatusInternalServerError     StatusCode = 1011\n\tStatusTLSHandshake            StatusCode = 1015\n\n\t// StatusAbnormalClosure is a special code designated for use in\n\t// applications.\n\tStatusAbnormalClosure StatusCode = 1006\n\n\t// StatusNoStatusRcvd is a special code designated for use in applications.\n\tStatusNoStatusRcvd StatusCode = 1005\n)\n\n// In reports whether the code is defined in given range.\nfunc (s StatusCode) In(r StatusCodeRange) bool {\n\treturn r.Min <= s && s <= r.Max\n}\n\n// Empty reports whether the code is empty.\n// Empty code has no any meaning neither app level codes nor other.\n// This method is useful just to check that code is golang default value 0.\nfunc (s StatusCode) Empty() bool {\n\treturn s == 0\n}\n\n// IsNotUsed reports whether the code is predefined in not used range.\nfunc (s StatusCode) IsNotUsed() bool {\n\treturn s.In(StatusRangeNotInUse)\n}\n\n// IsApplicationSpec reports whether the code should be defined by\n// application, framework or libraries specification.\nfunc (s StatusCode) IsApplicationSpec() bool {\n\treturn s.In(StatusRangeApplication)\n}\n\n// IsPrivateSpec reports whether the code should be defined privately.\nfunc (s StatusCode) IsPrivateSpec() bool {\n\treturn s.In(StatusRangePrivate)\n}\n\n// IsProtocolSpec reports whether the code should be defined by protocol specification.\nfunc (s StatusCode) IsProtocolSpec() bool {\n\treturn s.In(StatusRangeProtocol)\n}\n\n// IsProtocolDefined reports whether the code is already defined by protocol specification.\nfunc (s StatusCode) IsProtocolDefined() bool {\n\tswitch s {\n\tcase StatusNormalClosure,\n\t\tStatusGoingAway,\n\t\tStatusProtocolError,\n\t\tStatusUnsupportedData,\n\t\tStatusInvalidFramePayloadData,\n\t\tStatusPolicyViolation,\n\t\tStatusMessageTooBig,\n\t\tStatusMandatoryExt,\n\t\tStatusInternalServerError,\n\t\tStatusNoStatusRcvd,\n\t\tStatusAbnormalClosure,\n\t\tStatusTLSHandshake:\n\t\treturn true\n\t}\n\treturn false\n}\n\n// IsProtocolReserved reports whether the code is defined by protocol specification\n// to be reserved only for application usage purpose.\nfunc (s StatusCode) IsProtocolReserved() bool {\n\tswitch s {\n\t// [RFC6455]: {1005,1006,1015} is a reserved value and MUST NOT be set as a status code in a\n\t// Close control frame by an endpoint.\n\tcase StatusNoStatusRcvd, StatusAbnormalClosure, StatusTLSHandshake:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// Compiled control frames for common use cases.\n// For construct-serialize optimizations.\nvar (\n\tCompiledPing  = MustCompileFrame(NewPingFrame(nil))\n\tCompiledPong  = MustCompileFrame(NewPongFrame(nil))\n\tCompiledClose = MustCompileFrame(NewCloseFrame(nil))\n\n\tCompiledCloseNormalClosure           = MustCompileFrame(closeFrameNormalClosure)\n\tCompiledCloseGoingAway               = MustCompileFrame(closeFrameGoingAway)\n\tCompiledCloseProtocolError           = MustCompileFrame(closeFrameProtocolError)\n\tCompiledCloseUnsupportedData         = MustCompileFrame(closeFrameUnsupportedData)\n\tCompiledCloseNoMeaningYet            = MustCompileFrame(closeFrameNoMeaningYet)\n\tCompiledCloseInvalidFramePayloadData = MustCompileFrame(closeFrameInvalidFramePayloadData)\n\tCompiledClosePolicyViolation         = MustCompileFrame(closeFramePolicyViolation)\n\tCompiledCloseMessageTooBig           = MustCompileFrame(closeFrameMessageTooBig)\n\tCompiledCloseMandatoryExt            = MustCompileFrame(closeFrameMandatoryExt)\n\tCompiledCloseInternalServerError     = MustCompileFrame(closeFrameInternalServerError)\n\tCompiledCloseTLSHandshake            = MustCompileFrame(closeFrameTLSHandshake)\n)\n\n// Header represents websocket frame header.\n// See https://tools.ietf.org/html/rfc6455#section-5.2\ntype Header struct {\n\tFin    bool\n\tRsv    byte\n\tOpCode OpCode\n\tMasked bool\n\tMask   [4]byte\n\tLength int64\n}\n\n// Rsv1 reports whether the header has first rsv bit set.\nfunc (h Header) Rsv1() bool { return h.Rsv&bit5 != 0 }\n\n// Rsv2 reports whether the header has second rsv bit set.\nfunc (h Header) Rsv2() bool { return h.Rsv&bit6 != 0 }\n\n// Rsv3 reports whether the header has third rsv bit set.\nfunc (h Header) Rsv3() bool { return h.Rsv&bit7 != 0 }\n\n// Rsv creates rsv byte representation from bits.\nfunc Rsv(r1, r2, r3 bool) (rsv byte) {\n\tif r1 {\n\t\trsv |= bit5\n\t}\n\tif r2 {\n\t\trsv |= bit6\n\t}\n\tif r3 {\n\t\trsv |= bit7\n\t}\n\treturn rsv\n}\n\n// RsvBits returns rsv bits from bytes representation.\nfunc RsvBits(rsv byte) (r1, r2, r3 bool) {\n\tr1 = rsv&bit5 != 0\n\tr2 = rsv&bit6 != 0\n\tr3 = rsv&bit7 != 0\n\treturn r1, r2, r3\n}\n\n// Frame represents websocket frame.\n// See https://tools.ietf.org/html/rfc6455#section-5.2\ntype Frame struct {\n\tHeader  Header\n\tPayload []byte\n}\n\n// NewFrame creates frame with given operation code,\n// flag of completeness and payload bytes.\nfunc NewFrame(op OpCode, fin bool, p []byte) Frame {\n\treturn Frame{\n\t\tHeader: Header{\n\t\t\tFin:    fin,\n\t\t\tOpCode: op,\n\t\t\tLength: int64(len(p)),\n\t\t},\n\t\tPayload: p,\n\t}\n}\n\n// NewTextFrame creates text frame with p as payload.\n// Note that p is not copied.\nfunc NewTextFrame(p []byte) Frame {\n\treturn NewFrame(OpText, true, p)\n}\n\n// NewBinaryFrame creates binary frame with p as payload.\n// Note that p is not copied.\nfunc NewBinaryFrame(p []byte) Frame {\n\treturn NewFrame(OpBinary, true, p)\n}\n\n// NewPingFrame creates ping frame with p as payload.\n// Note that p is not copied.\n// Note that p must have length of MaxControlFramePayloadSize bytes or less due\n// to RFC.\nfunc NewPingFrame(p []byte) Frame {\n\treturn NewFrame(OpPing, true, p)\n}\n\n// NewPongFrame creates pong frame with p as payload.\n// Note that p is not copied.\n// Note that p must have length of MaxControlFramePayloadSize bytes or less due\n// to RFC.\nfunc NewPongFrame(p []byte) Frame {\n\treturn NewFrame(OpPong, true, p)\n}\n\n// NewCloseFrame creates close frame with given close body.\n// Note that p is not copied.\n// Note that p must have length of MaxControlFramePayloadSize bytes or less due\n// to RFC.\nfunc NewCloseFrame(p []byte) Frame {\n\treturn NewFrame(OpClose, true, p)\n}\n\n// NewCloseFrameBody encodes a closure code and a reason into a binary\n// representation.\n//\n// It returns slice which is at most MaxControlFramePayloadSize bytes length.\n// If the reason is too big it will be cropped to fit the limit defined by the\n// spec.\n//\n// See https://tools.ietf.org/html/rfc6455#section-5.5\nfunc NewCloseFrameBody(code StatusCode, reason string) []byte {\n\tn := min(2+len(reason), MaxControlFramePayloadSize)\n\tp := make([]byte, n)\n\n\tcrop := min(MaxControlFramePayloadSize-2, len(reason))\n\tPutCloseFrameBody(p, code, reason[:crop])\n\n\treturn p\n}\n\n// PutCloseFrameBody encodes code and reason into buf.\n//\n// It will panic if the buffer is too small to accommodate a code or a reason.\n//\n// PutCloseFrameBody does not check buffer to be RFC compliant, but note that\n// by RFC it must be at most MaxControlFramePayloadSize.\nfunc PutCloseFrameBody(p []byte, code StatusCode, reason string) {\n\t_ = p[1+len(reason)]\n\tbinary.BigEndian.PutUint16(p, uint16(code))\n\tcopy(p[2:], reason)\n}\n\n// MaskFrame masks frame and returns frame with masked payload and Mask header's field set.\n// Note that it copies f payload to prevent collisions.\n// For less allocations you could use MaskFrameInPlace or construct frame manually.\nfunc MaskFrame(f Frame) Frame {\n\treturn MaskFrameWith(f, NewMask())\n}\n\n// MaskFrameWith masks frame with given mask and returns frame\n// with masked payload and Mask header's field set.\n// Note that it copies f payload to prevent collisions.\n// For less allocations you could use MaskFrameInPlaceWith or construct frame manually.\nfunc MaskFrameWith(f Frame, mask [4]byte) Frame {\n\t// TODO(gobwas): check CopyCipher ws copy() Cipher().\n\tp := make([]byte, len(f.Payload))\n\tcopy(p, f.Payload)\n\tf.Payload = p\n\treturn MaskFrameInPlaceWith(f, mask)\n}\n\n// MaskFrameInPlace masks frame and returns frame with masked payload and Mask\n// header's field set.\n// Note that it applies xor cipher to f.Payload without copying, that is, it\n// modifies f.Payload inplace.\nfunc MaskFrameInPlace(f Frame) Frame {\n\treturn MaskFrameInPlaceWith(f, NewMask())\n}\n\nvar zeroMask [4]byte\n\n// UnmaskFrame unmasks frame and returns frame with unmasked payload and Mask\n// header's field cleared.\n// Note that it copies f payload.\nfunc UnmaskFrame(f Frame) Frame {\n\tp := make([]byte, len(f.Payload))\n\tcopy(p, f.Payload)\n\tf.Payload = p\n\treturn UnmaskFrameInPlace(f)\n}\n\n// UnmaskFrameInPlace unmasks frame and returns frame with unmasked payload and\n// Mask header's field cleared.\n// Note that it applies xor cipher to f.Payload without copying, that is, it\n// modifies f.Payload inplace.\nfunc UnmaskFrameInPlace(f Frame) Frame {\n\tCipher(f.Payload, f.Header.Mask, 0)\n\tf.Header.Masked = false\n\tf.Header.Mask = zeroMask\n\treturn f\n}\n\n// MaskFrameInPlaceWith masks frame with given mask and returns frame\n// with masked payload and Mask header's field set.\n// Note that it applies xor cipher to f.Payload without copying, that is, it\n// modifies f.Payload inplace.\nfunc MaskFrameInPlaceWith(f Frame, m [4]byte) Frame {\n\tf.Header.Masked = true\n\tf.Header.Mask = m\n\tCipher(f.Payload, m, 0)\n\treturn f\n}\n\n// NewMask creates new random mask.\nfunc NewMask() (ret [4]byte) {\n\tbinary.BigEndian.PutUint32(ret[:], rand.Uint32())\n\treturn ret\n}\n\n// CompileFrame returns byte representation of given frame.\n// In terms of memory consumption it is useful to precompile static frames\n// which are often used.\nfunc CompileFrame(f Frame) (bts []byte, err error) {\n\tbuf := bytes.NewBuffer(make([]byte, 0, 16))\n\terr = WriteFrame(buf, f)\n\tbts = buf.Bytes()\n\treturn bts, err\n}\n\n// MustCompileFrame is like CompileFrame but panics if frame can not be\n// encoded.\nfunc MustCompileFrame(f Frame) []byte {\n\tbts, err := CompileFrame(f)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn bts\n}\n\nfunc makeCloseFrame(code StatusCode) Frame {\n\treturn NewCloseFrame(NewCloseFrameBody(code, \"\"))\n}\n\nvar (\n\tcloseFrameNormalClosure           = makeCloseFrame(StatusNormalClosure)\n\tcloseFrameGoingAway               = makeCloseFrame(StatusGoingAway)\n\tcloseFrameProtocolError           = makeCloseFrame(StatusProtocolError)\n\tcloseFrameUnsupportedData         = makeCloseFrame(StatusUnsupportedData)\n\tcloseFrameNoMeaningYet            = makeCloseFrame(StatusNoMeaningYet)\n\tcloseFrameInvalidFramePayloadData = makeCloseFrame(StatusInvalidFramePayloadData)\n\tcloseFramePolicyViolation         = makeCloseFrame(StatusPolicyViolation)\n\tcloseFrameMessageTooBig           = makeCloseFrame(StatusMessageTooBig)\n\tcloseFrameMandatoryExt            = makeCloseFrame(StatusMandatoryExt)\n\tcloseFrameInternalServerError     = makeCloseFrame(StatusInternalServerError)\n\tcloseFrameTLSHandshake            = makeCloseFrame(StatusTLSHandshake)\n)\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/http.go",
    "content": "package ws\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n\n\t\"github.com/gobwas/httphead\"\n)\n\nconst (\n\tcrlf          = \"\\r\\n\"\n\tcolonAndSpace = \": \"\n\tcommaAndSpace = \", \"\n)\n\nconst (\n\ttextHeadUpgrade = \"HTTP/1.1 101 Switching Protocols\\r\\nUpgrade: websocket\\r\\nConnection: Upgrade\\r\\n\"\n)\n\nvar (\n\ttextHeadBadRequest          = statusText(http.StatusBadRequest)\n\ttextHeadInternalServerError = statusText(http.StatusInternalServerError)\n\ttextHeadUpgradeRequired     = statusText(http.StatusUpgradeRequired)\n\n\ttextTailErrHandshakeBadProtocol   = errorText(ErrHandshakeBadProtocol)\n\ttextTailErrHandshakeBadMethod     = errorText(ErrHandshakeBadMethod)\n\ttextTailErrHandshakeBadHost       = errorText(ErrHandshakeBadHost)\n\ttextTailErrHandshakeBadUpgrade    = errorText(ErrHandshakeBadUpgrade)\n\ttextTailErrHandshakeBadConnection = errorText(ErrHandshakeBadConnection)\n\ttextTailErrHandshakeBadSecAccept  = errorText(ErrHandshakeBadSecAccept)\n\ttextTailErrHandshakeBadSecKey     = errorText(ErrHandshakeBadSecKey)\n\ttextTailErrHandshakeBadSecVersion = errorText(ErrHandshakeBadSecVersion)\n\ttextTailErrUpgradeRequired        = errorText(ErrHandshakeUpgradeRequired)\n)\n\nconst (\n\t// Every new header must be added to TestHeaderNames test.\n\theaderHost          = \"Host\"\n\theaderUpgrade       = \"Upgrade\"\n\theaderConnection    = \"Connection\"\n\theaderSecVersion    = \"Sec-WebSocket-Version\"\n\theaderSecProtocol   = \"Sec-WebSocket-Protocol\"\n\theaderSecExtensions = \"Sec-WebSocket-Extensions\"\n\theaderSecKey        = \"Sec-WebSocket-Key\"\n\theaderSecAccept     = \"Sec-WebSocket-Accept\"\n\n\theaderHostCanonical          = headerHost\n\theaderUpgradeCanonical       = headerUpgrade\n\theaderConnectionCanonical    = headerConnection\n\theaderSecVersionCanonical    = \"Sec-Websocket-Version\"\n\theaderSecProtocolCanonical   = \"Sec-Websocket-Protocol\"\n\theaderSecExtensionsCanonical = \"Sec-Websocket-Extensions\"\n\theaderSecKeyCanonical        = \"Sec-Websocket-Key\"\n\theaderSecAcceptCanonical     = \"Sec-Websocket-Accept\"\n)\n\nvar (\n\tspecHeaderValueUpgrade         = []byte(\"websocket\")\n\tspecHeaderValueConnection      = []byte(\"Upgrade\")\n\tspecHeaderValueConnectionLower = []byte(\"upgrade\")\n\tspecHeaderValueSecVersion      = []byte(\"13\")\n)\n\nvar (\n\thttpVersion1_0    = []byte(\"HTTP/1.0\")\n\thttpVersion1_1    = []byte(\"HTTP/1.1\")\n\thttpVersionPrefix = []byte(\"HTTP/\")\n)\n\ntype httpRequestLine struct {\n\tmethod, uri  []byte\n\tmajor, minor int\n}\n\ntype httpResponseLine struct {\n\tmajor, minor int\n\tstatus       int\n\treason       []byte\n}\n\n// httpParseRequestLine parses http request line like \"GET / HTTP/1.0\".\nfunc httpParseRequestLine(line []byte) (req httpRequestLine, err error) {\n\tvar proto []byte\n\treq.method, req.uri, proto = bsplit3(line, ' ')\n\n\tvar ok bool\n\treq.major, req.minor, ok = httpParseVersion(proto)\n\tif !ok {\n\t\terr = ErrMalformedRequest\n\t}\n\treturn req, err\n}\n\nfunc httpParseResponseLine(line []byte) (resp httpResponseLine, err error) {\n\tvar (\n\t\tproto  []byte\n\t\tstatus []byte\n\t)\n\tproto, status, resp.reason = bsplit3(line, ' ')\n\n\tvar ok bool\n\tresp.major, resp.minor, ok = httpParseVersion(proto)\n\tif !ok {\n\t\treturn resp, ErrMalformedResponse\n\t}\n\n\tvar convErr error\n\tresp.status, convErr = asciiToInt(status)\n\tif convErr != nil {\n\t\treturn resp, ErrMalformedResponse\n\t}\n\n\treturn resp, nil\n}\n\n// httpParseVersion parses major and minor version of HTTP protocol. It returns\n// parsed values and true if parse is ok.\nfunc httpParseVersion(bts []byte) (major, minor int, ok bool) {\n\tswitch {\n\tcase bytes.Equal(bts, httpVersion1_0):\n\t\treturn 1, 0, true\n\tcase bytes.Equal(bts, httpVersion1_1):\n\t\treturn 1, 1, true\n\tcase len(bts) < 8:\n\t\treturn 0, 0, false\n\tcase !bytes.Equal(bts[:5], httpVersionPrefix):\n\t\treturn 0, 0, false\n\t}\n\n\tbts = bts[5:]\n\n\tdot := bytes.IndexByte(bts, '.')\n\tif dot == -1 {\n\t\treturn 0, 0, false\n\t}\n\tvar err error\n\tmajor, err = asciiToInt(bts[:dot])\n\tif err != nil {\n\t\treturn major, 0, false\n\t}\n\tminor, err = asciiToInt(bts[dot+1:])\n\tif err != nil {\n\t\treturn major, minor, false\n\t}\n\n\treturn major, minor, true\n}\n\n// httpParseHeaderLine parses HTTP header as key-value pair. It returns parsed\n// values and true if parse is ok.\nfunc httpParseHeaderLine(line []byte) (k, v []byte, ok bool) {\n\tcolon := bytes.IndexByte(line, ':')\n\tif colon == -1 {\n\t\treturn nil, nil, false\n\t}\n\n\tk = btrim(line[:colon])\n\t// TODO(gobwas): maybe use just lower here?\n\tcanonicalizeHeaderKey(k)\n\n\tv = btrim(line[colon+1:])\n\n\treturn k, v, true\n}\n\n// httpGetHeader is the same as textproto.MIMEHeader.Get, except the thing,\n// that key is already canonical. This helps to increase performance.\nfunc httpGetHeader(h http.Header, key string) string {\n\tif h == nil {\n\t\treturn \"\"\n\t}\n\tv := h[key]\n\tif len(v) == 0 {\n\t\treturn \"\"\n\t}\n\treturn v[0]\n}\n\n// The request MAY include a header field with the name\n// |Sec-WebSocket-Protocol|.  If present, this value indicates one or more\n// comma-separated subprotocol the client wishes to speak, ordered by\n// preference.  The elements that comprise this value MUST be non-empty strings\n// with characters in the range U+0021 to U+007E not including separator\n// characters as defined in [RFC2616] and MUST all be unique strings.  The ABNF\n// for the value of this header field is 1#token, where the definitions of\n// constructs and rules are as given in [RFC2616].\nfunc strSelectProtocol(h string, check func(string) bool) (ret string, ok bool) {\n\tok = httphead.ScanTokens(strToBytes(h), func(v []byte) bool {\n\t\tif check(btsToString(v)) {\n\t\t\tret = string(v)\n\t\t\treturn false\n\t\t}\n\t\treturn true\n\t})\n\treturn ret, ok\n}\n\nfunc btsSelectProtocol(h []byte, check func([]byte) bool) (ret string, ok bool) {\n\tvar selected []byte\n\tok = httphead.ScanTokens(h, func(v []byte) bool {\n\t\tif check(v) {\n\t\t\tselected = v\n\t\t\treturn false\n\t\t}\n\t\treturn true\n\t})\n\tif ok && selected != nil {\n\t\treturn string(selected), true\n\t}\n\treturn ret, ok\n}\n\nfunc btsSelectExtensions(h []byte, selected []httphead.Option, check func(httphead.Option) bool) ([]httphead.Option, bool) {\n\ts := httphead.OptionSelector{\n\t\tFlags: httphead.SelectCopy,\n\t\tCheck: check,\n\t}\n\treturn s.Select(h, selected)\n}\n\nfunc negotiateMaybe(in httphead.Option, dest []httphead.Option, f func(httphead.Option) (httphead.Option, error)) ([]httphead.Option, error) {\n\tif in.Size() == 0 {\n\t\treturn dest, nil\n\t}\n\topt, err := f(in)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif opt.Size() > 0 {\n\t\tdest = append(dest, opt)\n\t}\n\treturn dest, nil\n}\n\nfunc negotiateExtensions(\n\th []byte, dest []httphead.Option,\n\tf func(httphead.Option) (httphead.Option, error),\n) (_ []httphead.Option, err error) {\n\tindex := -1\n\tvar current httphead.Option\n\tok := httphead.ScanOptions(h, func(i int, name, attr, val []byte) httphead.Control {\n\t\tif i != index {\n\t\t\tdest, err = negotiateMaybe(current, dest, f)\n\t\t\tif err != nil {\n\t\t\t\treturn httphead.ControlBreak\n\t\t\t}\n\t\t\tindex = i\n\t\t\tcurrent = httphead.Option{Name: name}\n\t\t}\n\t\tif attr != nil {\n\t\t\tcurrent.Parameters.Set(attr, val)\n\t\t}\n\t\treturn httphead.ControlContinue\n\t})\n\tif !ok {\n\t\treturn nil, ErrMalformedRequest\n\t}\n\treturn negotiateMaybe(current, dest, f)\n}\n\nfunc httpWriteHeader(bw *bufio.Writer, key, value string) {\n\thttpWriteHeaderKey(bw, key)\n\tbw.WriteString(value)\n\tbw.WriteString(crlf)\n}\n\nfunc httpWriteHeaderBts(bw *bufio.Writer, key string, value []byte) {\n\thttpWriteHeaderKey(bw, key)\n\tbw.Write(value)\n\tbw.WriteString(crlf)\n}\n\nfunc httpWriteHeaderKey(bw *bufio.Writer, key string) {\n\tbw.WriteString(key)\n\tbw.WriteString(colonAndSpace)\n}\n\nfunc httpWriteUpgradeRequest(\n\tbw *bufio.Writer,\n\tu *url.URL,\n\tnonce []byte,\n\tprotocols []string,\n\textensions []httphead.Option,\n\theader HandshakeHeader,\n) {\n\tbw.WriteString(\"GET \")\n\tbw.WriteString(u.RequestURI())\n\tbw.WriteString(\" HTTP/1.1\\r\\n\")\n\n\thttpWriteHeader(bw, headerHost, u.Host)\n\n\thttpWriteHeaderBts(bw, headerUpgrade, specHeaderValueUpgrade)\n\thttpWriteHeaderBts(bw, headerConnection, specHeaderValueConnection)\n\thttpWriteHeaderBts(bw, headerSecVersion, specHeaderValueSecVersion)\n\n\t// NOTE: write nonce bytes as a string to prevent heap allocation –\n\t// WriteString() copy given string into its inner buffer, unlike Write()\n\t// which may write p directly to the underlying io.Writer – which in turn\n\t// will lead to p escape.\n\thttpWriteHeader(bw, headerSecKey, btsToString(nonce))\n\n\tif len(protocols) > 0 {\n\t\thttpWriteHeaderKey(bw, headerSecProtocol)\n\t\tfor i, p := range protocols {\n\t\t\tif i > 0 {\n\t\t\t\tbw.WriteString(commaAndSpace)\n\t\t\t}\n\t\t\tbw.WriteString(p)\n\t\t}\n\t\tbw.WriteString(crlf)\n\t}\n\n\tif len(extensions) > 0 {\n\t\thttpWriteHeaderKey(bw, headerSecExtensions)\n\t\thttphead.WriteOptions(bw, extensions)\n\t\tbw.WriteString(crlf)\n\t}\n\n\tif header != nil {\n\t\theader.WriteTo(bw)\n\t}\n\n\tbw.WriteString(crlf)\n}\n\nfunc httpWriteResponseUpgrade(bw *bufio.Writer, nonce []byte, hs Handshake, header HandshakeHeaderFunc) {\n\tbw.WriteString(textHeadUpgrade)\n\n\thttpWriteHeaderKey(bw, headerSecAccept)\n\twriteAccept(bw, nonce)\n\tbw.WriteString(crlf)\n\n\tif hs.Protocol != \"\" {\n\t\thttpWriteHeader(bw, headerSecProtocol, hs.Protocol)\n\t}\n\tif len(hs.Extensions) > 0 {\n\t\thttpWriteHeaderKey(bw, headerSecExtensions)\n\t\thttphead.WriteOptions(bw, hs.Extensions)\n\t\tbw.WriteString(crlf)\n\t}\n\tif header != nil {\n\t\theader(bw)\n\t}\n\n\tbw.WriteString(crlf)\n}\n\nfunc httpWriteResponseError(bw *bufio.Writer, err error, code int, header HandshakeHeaderFunc) {\n\tswitch code {\n\tcase http.StatusBadRequest:\n\t\tbw.WriteString(textHeadBadRequest)\n\tcase http.StatusInternalServerError:\n\t\tbw.WriteString(textHeadInternalServerError)\n\tcase http.StatusUpgradeRequired:\n\t\tbw.WriteString(textHeadUpgradeRequired)\n\tdefault:\n\t\twriteStatusText(bw, code)\n\t}\n\n\t// Write custom headers.\n\tif header != nil {\n\t\theader(bw)\n\t}\n\n\tswitch err {\n\tcase ErrHandshakeBadProtocol:\n\t\tbw.WriteString(textTailErrHandshakeBadProtocol)\n\tcase ErrHandshakeBadMethod:\n\t\tbw.WriteString(textTailErrHandshakeBadMethod)\n\tcase ErrHandshakeBadHost:\n\t\tbw.WriteString(textTailErrHandshakeBadHost)\n\tcase ErrHandshakeBadUpgrade:\n\t\tbw.WriteString(textTailErrHandshakeBadUpgrade)\n\tcase ErrHandshakeBadConnection:\n\t\tbw.WriteString(textTailErrHandshakeBadConnection)\n\tcase ErrHandshakeBadSecAccept:\n\t\tbw.WriteString(textTailErrHandshakeBadSecAccept)\n\tcase ErrHandshakeBadSecKey:\n\t\tbw.WriteString(textTailErrHandshakeBadSecKey)\n\tcase ErrHandshakeBadSecVersion:\n\t\tbw.WriteString(textTailErrHandshakeBadSecVersion)\n\tcase ErrHandshakeUpgradeRequired:\n\t\tbw.WriteString(textTailErrUpgradeRequired)\n\tcase nil:\n\t\tbw.WriteString(crlf)\n\tdefault:\n\t\twriteErrorText(bw, err)\n\t}\n}\n\nfunc writeStatusText(bw *bufio.Writer, code int) {\n\tbw.WriteString(\"HTTP/1.1 \")\n\tbw.WriteString(strconv.Itoa(code))\n\tbw.WriteByte(' ')\n\tbw.WriteString(http.StatusText(code))\n\tbw.WriteString(crlf)\n\tbw.WriteString(\"Content-Type: text/plain; charset=utf-8\")\n\tbw.WriteString(crlf)\n}\n\nfunc writeErrorText(bw *bufio.Writer, err error) {\n\tbody := err.Error()\n\tbw.WriteString(\"Content-Length: \")\n\tbw.WriteString(strconv.Itoa(len(body)))\n\tbw.WriteString(crlf)\n\tbw.WriteString(crlf)\n\tbw.WriteString(body)\n}\n\n// httpError is like the http.Error with WebSocket context exception.\nfunc httpError(w http.ResponseWriter, body string, code int) {\n\tw.Header().Set(\"Content-Type\", \"text/plain; charset=utf-8\")\n\tw.Header().Set(\"Content-Length\", strconv.Itoa(len(body)))\n\tw.WriteHeader(code)\n\tw.Write([]byte(body))\n}\n\n// statusText is a non-performant status text generator.\n// NOTE: Used only to generate constants.\nfunc statusText(code int) string {\n\tvar buf bytes.Buffer\n\tbw := bufio.NewWriter(&buf)\n\twriteStatusText(bw, code)\n\tbw.Flush()\n\treturn buf.String()\n}\n\n// errorText is a non-performant error text generator.\n// NOTE: Used only to generate constants.\nfunc errorText(err error) string {\n\tvar buf bytes.Buffer\n\tbw := bufio.NewWriter(&buf)\n\twriteErrorText(bw, err)\n\tbw.Flush()\n\treturn buf.String()\n}\n\n// HandshakeHeader is the interface that writes both upgrade request or\n// response headers into a given io.Writer.\ntype HandshakeHeader interface {\n\tio.WriterTo\n}\n\n// HandshakeHeaderString is an adapter to allow the use of headers represented\n// by ordinary string as HandshakeHeader.\ntype HandshakeHeaderString string\n\n// WriteTo implements HandshakeHeader (and io.WriterTo) interface.\nfunc (s HandshakeHeaderString) WriteTo(w io.Writer) (int64, error) {\n\tn, err := io.WriteString(w, string(s))\n\treturn int64(n), err\n}\n\n// HandshakeHeaderBytes is an adapter to allow the use of headers represented\n// by ordinary slice of bytes as HandshakeHeader.\ntype HandshakeHeaderBytes []byte\n\n// WriteTo implements HandshakeHeader (and io.WriterTo) interface.\nfunc (b HandshakeHeaderBytes) WriteTo(w io.Writer) (int64, error) {\n\tn, err := w.Write(b)\n\treturn int64(n), err\n}\n\n// HandshakeHeaderFunc is an adapter to allow the use of headers represented by\n// ordinary function as HandshakeHeader.\ntype HandshakeHeaderFunc func(io.Writer) (int64, error)\n\n// WriteTo implements HandshakeHeader (and io.WriterTo) interface.\nfunc (f HandshakeHeaderFunc) WriteTo(w io.Writer) (int64, error) {\n\treturn f(w)\n}\n\n// HandshakeHeaderHTTP is an adapter to allow the use of http.Header as\n// HandshakeHeader.\ntype HandshakeHeaderHTTP http.Header\n\n// WriteTo implements HandshakeHeader (and io.WriterTo) interface.\nfunc (h HandshakeHeaderHTTP) WriteTo(w io.Writer) (int64, error) {\n\twr := writer{w: w}\n\terr := http.Header(h).Write(&wr)\n\treturn wr.n, err\n}\n\ntype writer struct {\n\tn int64\n\tw io.Writer\n}\n\nfunc (w *writer) WriteString(s string) (int, error) {\n\tn, err := io.WriteString(w.w, s)\n\tw.n += int64(n)\n\treturn n, err\n}\n\nfunc (w *writer) Write(p []byte) (int, error) {\n\tn, err := w.w.Write(p)\n\tw.n += int64(n)\n\treturn n, err\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/nonce.go",
    "content": "package ws\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"crypto/sha1\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"math/rand\"\n)\n\nconst (\n\t// RFC6455: The value of this header field MUST be a nonce consisting of a\n\t// randomly selected 16-byte value that has been base64-encoded (see\n\t// Section 4 of [RFC4648]).  The nonce MUST be selected randomly for each\n\t// connection.\n\tnonceKeySize = 16\n\tnonceSize    = 24 // base64.StdEncoding.EncodedLen(nonceKeySize)\n\n\t// RFC6455: The value of this header field is constructed by concatenating\n\t// /key/, defined above in step 4 in Section 4.2.2, with the string\n\t// \"258EAFA5- E914-47DA-95CA-C5AB0DC85B11\", taking the SHA-1 hash of this\n\t// concatenated value to obtain a 20-byte value and base64- encoding (see\n\t// Section 4 of [RFC4648]) this 20-byte hash.\n\tacceptSize = 28 // base64.StdEncoding.EncodedLen(sha1.Size)\n)\n\n// initNonce fills given slice with random base64-encoded nonce bytes.\nfunc initNonce(dst []byte) {\n\t// NOTE: bts does not escape.\n\tbts := make([]byte, nonceKeySize)\n\tif _, err := rand.Read(bts); err != nil {\n\t\tpanic(fmt.Sprintf(\"rand read error: %s\", err))\n\t}\n\tbase64.StdEncoding.Encode(dst, bts)\n}\n\n// checkAcceptFromNonce reports whether given accept bytes are valid for given\n// nonce bytes.\nfunc checkAcceptFromNonce(accept, nonce []byte) bool {\n\tif len(accept) != acceptSize {\n\t\treturn false\n\t}\n\t// NOTE: expect does not escape.\n\texpect := make([]byte, acceptSize)\n\tinitAcceptFromNonce(expect, nonce)\n\treturn bytes.Equal(expect, accept)\n}\n\n// initAcceptFromNonce fills given slice with accept bytes generated from given\n// nonce bytes. Given buffer should be exactly acceptSize bytes.\nfunc initAcceptFromNonce(accept, nonce []byte) {\n\tconst magic = \"258EAFA5-E914-47DA-95CA-C5AB0DC85B11\"\n\n\tif len(accept) != acceptSize {\n\t\tpanic(\"accept buffer is invalid\")\n\t}\n\tif len(nonce) != nonceSize {\n\t\tpanic(\"nonce is invalid\")\n\t}\n\n\tp := make([]byte, nonceSize+len(magic))\n\tcopy(p[:nonceSize], nonce)\n\tcopy(p[nonceSize:], magic)\n\n\tsum := sha1.Sum(p)\n\tbase64.StdEncoding.Encode(accept, sum[:])\n}\n\nfunc writeAccept(bw *bufio.Writer, nonce []byte) (int, error) {\n\taccept := make([]byte, acceptSize)\n\tinitAcceptFromNonce(accept, nonce)\n\t// NOTE: write accept bytes as a string to prevent heap allocation –\n\t// WriteString() copy given string into its inner buffer, unlike Write()\n\t// which may write p directly to the underlying io.Writer – which in turn\n\t// will lead to p escape.\n\treturn bw.WriteString(btsToString(accept))\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/read.go",
    "content": "package ws\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n)\n\n// Errors used by frame reader.\nvar (\n\tErrHeaderLengthMSB        = fmt.Errorf(\"header error: the most significant bit must be 0\")\n\tErrHeaderLengthUnexpected = fmt.Errorf(\"header error: unexpected payload length bits\")\n)\n\n// ReadHeader reads a frame header from r.\nfunc ReadHeader(r io.Reader) (h Header, err error) {\n\t// Make slice of bytes with capacity 12 that could hold any header.\n\t//\n\t// The maximum header size is 14, but due to the 2 hop reads,\n\t// after first hop that reads first 2 constant bytes, we could reuse 2 bytes.\n\t// So 14 - 2 = 12.\n\tbts := make([]byte, 2, MaxHeaderSize-2)\n\n\t// Prepare to hold first 2 bytes to choose size of next read.\n\t_, err = io.ReadFull(r, bts)\n\tif err != nil {\n\t\treturn h, err\n\t}\n\n\th.Fin = bts[0]&bit0 != 0\n\th.Rsv = (bts[0] & 0x70) >> 4\n\th.OpCode = OpCode(bts[0] & 0x0f)\n\n\tvar extra int\n\n\tif bts[1]&bit0 != 0 {\n\t\th.Masked = true\n\t\textra += 4\n\t}\n\n\tlength := bts[1] & 0x7f\n\tswitch {\n\tcase length < 126:\n\t\th.Length = int64(length)\n\n\tcase length == 126:\n\t\textra += 2\n\n\tcase length == 127:\n\t\textra += 8\n\n\tdefault:\n\t\terr = ErrHeaderLengthUnexpected\n\t\treturn h, err\n\t}\n\n\tif extra == 0 {\n\t\treturn h, err\n\t}\n\n\t// Increase len of bts to extra bytes need to read.\n\t// Overwrite first 2 bytes that was read before.\n\tbts = bts[:extra]\n\t_, err = io.ReadFull(r, bts)\n\tif err != nil {\n\t\treturn h, err\n\t}\n\n\tswitch {\n\tcase length == 126:\n\t\th.Length = int64(binary.BigEndian.Uint16(bts[:2]))\n\t\tbts = bts[2:]\n\n\tcase length == 127:\n\t\tif bts[0]&0x80 != 0 {\n\t\t\terr = ErrHeaderLengthMSB\n\t\t\treturn h, err\n\t\t}\n\t\th.Length = int64(binary.BigEndian.Uint64(bts[:8]))\n\t\tbts = bts[8:]\n\t}\n\n\tif h.Masked {\n\t\tcopy(h.Mask[:], bts)\n\t}\n\n\treturn h, nil\n}\n\n// ReadFrame reads a frame from r.\n// It is not designed for high optimized use case cause it makes allocation\n// for frame.Header.Length size inside to read frame payload into.\n//\n// Note that ReadFrame does not unmask payload.\nfunc ReadFrame(r io.Reader) (f Frame, err error) {\n\tf.Header, err = ReadHeader(r)\n\tif err != nil {\n\t\treturn f, err\n\t}\n\n\tif f.Header.Length > 0 {\n\t\t// int(f.Header.Length) is safe here cause we have\n\t\t// checked it for overflow above in ReadHeader.\n\t\tf.Payload = make([]byte, int(f.Header.Length))\n\t\t_, err = io.ReadFull(r, f.Payload)\n\t}\n\n\treturn f, err\n}\n\n// MustReadFrame is like ReadFrame but panics if frame can not be read.\nfunc MustReadFrame(r io.Reader) Frame {\n\tf, err := ReadFrame(r)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn f\n}\n\n// ParseCloseFrameData parses close frame status code and closure reason if any provided.\n// If there is no status code in the payload\n// the empty status code is returned (code.Empty()) with empty string as a reason.\nfunc ParseCloseFrameData(payload []byte) (code StatusCode, reason string) {\n\tif len(payload) < 2 {\n\t\t// We returning empty StatusCode here, preventing the situation\n\t\t// when endpoint really sent code 1005 and we should return ProtocolError on that.\n\t\t//\n\t\t// In other words, we ignoring this rule [RFC6455:7.1.5]:\n\t\t//   If this Close control frame contains no status code, _The WebSocket\n\t\t//   Connection Close Code_ is considered to be 1005.\n\t\treturn code, reason\n\t}\n\tcode = StatusCode(binary.BigEndian.Uint16(payload))\n\treason = string(payload[2:])\n\treturn code, reason\n}\n\n// ParseCloseFrameDataUnsafe is like ParseCloseFrameData except the thing\n// that it does not copies payload bytes into reason, but prepares unsafe cast.\nfunc ParseCloseFrameDataUnsafe(payload []byte) (code StatusCode, reason string) {\n\tif len(payload) < 2 {\n\t\treturn code, reason\n\t}\n\tcode = StatusCode(binary.BigEndian.Uint16(payload))\n\treason = btsToString(payload[2:])\n\treturn code, reason\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/server.go",
    "content": "package ws\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/gobwas/httphead\"\n\t\"github.com/gobwas/pool/pbufio\"\n)\n\n// Constants used by ConnUpgrader.\nconst (\n\tDefaultServerReadBufferSize  = 4096\n\tDefaultServerWriteBufferSize = 512\n)\n\n// Errors used by both client and server when preparing WebSocket handshake.\nvar (\n\tErrHandshakeBadProtocol = RejectConnectionError(\n\t\tRejectionStatus(http.StatusHTTPVersionNotSupported),\n\t\tRejectionReason(\"handshake error: bad HTTP protocol version\"),\n\t)\n\tErrHandshakeBadMethod = RejectConnectionError(\n\t\tRejectionStatus(http.StatusMethodNotAllowed),\n\t\tRejectionReason(\"handshake error: bad HTTP request method\"),\n\t)\n\tErrHandshakeBadHost = RejectConnectionError(\n\t\tRejectionStatus(http.StatusBadRequest),\n\t\tRejectionReason(fmt.Sprintf(\"handshake error: bad %q header\", headerHost)),\n\t)\n\tErrHandshakeBadUpgrade = RejectConnectionError(\n\t\tRejectionStatus(http.StatusBadRequest),\n\t\tRejectionReason(fmt.Sprintf(\"handshake error: bad %q header\", headerUpgrade)),\n\t)\n\tErrHandshakeBadConnection = RejectConnectionError(\n\t\tRejectionStatus(http.StatusBadRequest),\n\t\tRejectionReason(fmt.Sprintf(\"handshake error: bad %q header\", headerConnection)),\n\t)\n\tErrHandshakeBadSecAccept = RejectConnectionError(\n\t\tRejectionStatus(http.StatusBadRequest),\n\t\tRejectionReason(fmt.Sprintf(\"handshake error: bad %q header\", headerSecAccept)),\n\t)\n\tErrHandshakeBadSecKey = RejectConnectionError(\n\t\tRejectionStatus(http.StatusBadRequest),\n\t\tRejectionReason(fmt.Sprintf(\"handshake error: bad %q header\", headerSecKey)),\n\t)\n\tErrHandshakeBadSecVersion = RejectConnectionError(\n\t\tRejectionStatus(http.StatusBadRequest),\n\t\tRejectionReason(fmt.Sprintf(\"handshake error: bad %q header\", headerSecVersion)),\n\t)\n)\n\n// ErrMalformedResponse is returned by Dialer to indicate that server response\n// can not be parsed.\nvar ErrMalformedResponse = fmt.Errorf(\"malformed HTTP response\")\n\n// ErrMalformedRequest is returned when HTTP request can not be parsed.\nvar ErrMalformedRequest = RejectConnectionError(\n\tRejectionStatus(http.StatusBadRequest),\n\tRejectionReason(\"malformed HTTP request\"),\n)\n\n// ErrHandshakeUpgradeRequired is returned by Upgrader to indicate that\n// connection is rejected because given WebSocket version is malformed.\n//\n// According to RFC6455:\n// If this version does not match a version understood by the server, the\n// server MUST abort the WebSocket handshake described in this section and\n// instead send an appropriate HTTP error code (such as 426 Upgrade Required)\n// and a |Sec-WebSocket-Version| header field indicating the version(s) the\n// server is capable of understanding.\nvar ErrHandshakeUpgradeRequired = RejectConnectionError(\n\tRejectionStatus(http.StatusUpgradeRequired),\n\tRejectionHeader(HandshakeHeaderString(headerSecVersion+\": 13\\r\\n\")),\n\tRejectionReason(fmt.Sprintf(\"handshake error: bad %q header\", headerSecVersion)),\n)\n\n// ErrNotHijacker is an error returned when http.ResponseWriter does not\n// implement http.Hijacker interface.\nvar ErrNotHijacker = RejectConnectionError(\n\tRejectionStatus(http.StatusInternalServerError),\n\tRejectionReason(\"given http.ResponseWriter is not a http.Hijacker\"),\n)\n\n// DefaultHTTPUpgrader is an HTTPUpgrader that holds no options and is used by\n// UpgradeHTTP function.\nvar DefaultHTTPUpgrader HTTPUpgrader\n\n// UpgradeHTTP is like HTTPUpgrader{}.Upgrade().\nfunc UpgradeHTTP(r *http.Request, w http.ResponseWriter) (net.Conn, *bufio.ReadWriter, Handshake, error) {\n\treturn DefaultHTTPUpgrader.Upgrade(r, w)\n}\n\n// DefaultUpgrader is an Upgrader that holds no options and is used by Upgrade\n// function.\nvar DefaultUpgrader Upgrader\n\n// Upgrade is like Upgrader{}.Upgrade().\nfunc Upgrade(conn io.ReadWriter) (Handshake, error) {\n\treturn DefaultUpgrader.Upgrade(conn)\n}\n\n// HTTPUpgrader contains options for upgrading connection to websocket from\n// net/http Handler arguments.\ntype HTTPUpgrader struct {\n\t// Timeout is the maximum amount of time an Upgrade() will spent while\n\t// writing handshake response.\n\t//\n\t// The default is no timeout.\n\tTimeout time.Duration\n\n\t// Header is an optional http.Header mapping that could be used to\n\t// write additional headers to the handshake response.\n\t//\n\t// Note that if present, it will be written in any result of handshake.\n\tHeader http.Header\n\n\t// Protocol is the select function that is used to select subprotocol from\n\t// list requested by client. If this field is set, then the first matched\n\t// protocol is sent to a client as negotiated.\n\tProtocol func(string) bool\n\n\t// Extension is the select function that is used to select extensions from\n\t// list requested by client. If this field is set, then the all matched\n\t// extensions are sent to a client as negotiated.\n\t//\n\t// Deprecated: use Negotiate instead.\n\tExtension func(httphead.Option) bool\n\n\t// Negotiate is the callback that is used to negotiate extensions from\n\t// the client's offer. If this field is set, then the returned non-zero\n\t// extensions are sent to the client as accepted extensions in the\n\t// response.\n\t//\n\t// The argument is only valid until the Negotiate callback returns.\n\t//\n\t// If returned error is non-nil then connection is rejected and response is\n\t// sent with appropriate HTTP error code and body set to error message.\n\t//\n\t// RejectConnectionError could be used to get more control on response.\n\tNegotiate func(httphead.Option) (httphead.Option, error)\n}\n\n// Upgrade upgrades http connection to the websocket connection.\n//\n// It hijacks net.Conn from w and returns received net.Conn and\n// bufio.ReadWriter. On successful handshake it returns Handshake struct\n// describing handshake info.\nfunc (u HTTPUpgrader) Upgrade(r *http.Request, w http.ResponseWriter) (conn net.Conn, rw *bufio.ReadWriter, hs Handshake, err error) {\n\t// Hijack connection first to get the ability to write rejection errors the\n\t// same way as in Upgrader.\n\thj, ok := w.(http.Hijacker)\n\tif ok {\n\t\tconn, rw, err = hj.Hijack()\n\t} else {\n\t\terr = ErrNotHijacker\n\t}\n\tif err != nil {\n\t\thttpError(w, err.Error(), http.StatusInternalServerError)\n\t\treturn conn, rw, hs, err\n\t}\n\n\t// See https://tools.ietf.org/html/rfc6455#section-4.1\n\t// The method of the request MUST be GET, and the HTTP version MUST be at least 1.1.\n\tvar nonce string\n\tif r.Method != http.MethodGet {\n\t\terr = ErrHandshakeBadMethod\n\t} else if r.ProtoMajor < 1 || (r.ProtoMajor == 1 && r.ProtoMinor < 1) {\n\t\terr = ErrHandshakeBadProtocol\n\t} else if r.Host == \"\" {\n\t\terr = ErrHandshakeBadHost\n\t} else if u := httpGetHeader(r.Header, headerUpgradeCanonical); u != \"websocket\" && !strings.EqualFold(u, \"websocket\") {\n\t\terr = ErrHandshakeBadUpgrade\n\t} else if c := httpGetHeader(r.Header, headerConnectionCanonical); c != \"Upgrade\" && !strHasToken(c, \"upgrade\") {\n\t\terr = ErrHandshakeBadConnection\n\t} else if nonce = httpGetHeader(r.Header, headerSecKeyCanonical); len(nonce) != nonceSize {\n\t\terr = ErrHandshakeBadSecKey\n\t} else if v := httpGetHeader(r.Header, headerSecVersionCanonical); v != \"13\" {\n\t\t// According to RFC6455:\n\t\t//\n\t\t// If this version does not match a version understood by the server,\n\t\t// the server MUST abort the WebSocket handshake described in this\n\t\t// section and instead send an appropriate HTTP error code (such as 426\n\t\t// Upgrade Required) and a |Sec-WebSocket-Version| header field\n\t\t// indicating the version(s) the server is capable of understanding.\n\t\t//\n\t\t// So we branching here cause empty or not present version does not\n\t\t// meet the ABNF rules of RFC6455:\n\t\t//\n\t\t// version = DIGIT | (NZDIGIT DIGIT) |\n\t\t// (\"1\" DIGIT DIGIT) | (\"2\" DIGIT DIGIT)\n\t\t// ; Limited to 0-255 range, with no leading zeros\n\t\t//\n\t\t// That is, if version is really invalid – we sent 426 status, if it\n\t\t// not present or empty – it is 400.\n\t\tif v != \"\" {\n\t\t\terr = ErrHandshakeUpgradeRequired\n\t\t} else {\n\t\t\terr = ErrHandshakeBadSecVersion\n\t\t}\n\t}\n\tif check := u.Protocol; err == nil && check != nil {\n\t\tps := r.Header[headerSecProtocolCanonical]\n\t\tfor i := 0; i < len(ps) && err == nil && hs.Protocol == \"\"; i++ {\n\t\t\tvar ok bool\n\t\t\ths.Protocol, ok = strSelectProtocol(ps[i], check)\n\t\t\tif !ok {\n\t\t\t\terr = ErrMalformedRequest\n\t\t\t}\n\t\t}\n\t}\n\tif f := u.Negotiate; err == nil && f != nil {\n\t\tfor _, h := range r.Header[headerSecExtensionsCanonical] {\n\t\t\ths.Extensions, err = negotiateExtensions(strToBytes(h), hs.Extensions, f)\n\t\t\tif err != nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\t// DEPRECATED path.\n\tif check := u.Extension; err == nil && check != nil && u.Negotiate == nil {\n\t\txs := r.Header[headerSecExtensionsCanonical]\n\t\tfor i := 0; i < len(xs) && err == nil; i++ {\n\t\t\tvar ok bool\n\t\t\ths.Extensions, ok = btsSelectExtensions(strToBytes(xs[i]), hs.Extensions, check)\n\t\t\tif !ok {\n\t\t\t\terr = ErrMalformedRequest\n\t\t\t}\n\t\t}\n\t}\n\n\t// Clear deadlines set by server.\n\tconn.SetDeadline(noDeadline)\n\tif t := u.Timeout; t != 0 {\n\t\tconn.SetWriteDeadline(time.Now().Add(t))\n\t\tdefer conn.SetWriteDeadline(noDeadline)\n\t}\n\n\tvar header handshakeHeader\n\tif h := u.Header; h != nil {\n\t\theader[0] = HandshakeHeaderHTTP(h)\n\t}\n\tif err == nil {\n\t\thttpWriteResponseUpgrade(rw.Writer, strToBytes(nonce), hs, header.WriteTo)\n\t\terr = rw.Writer.Flush()\n\t} else {\n\t\tvar code int\n\t\tif rej, ok := err.(*ConnectionRejectedError); ok {\n\t\t\tcode = rej.code\n\t\t\theader[1] = rej.header\n\t\t}\n\t\tif code == 0 {\n\t\t\tcode = http.StatusInternalServerError\n\t\t}\n\t\thttpWriteResponseError(rw.Writer, err, code, header.WriteTo)\n\t\t// Do not store Flush() error to not override already existing one.\n\t\t_ = rw.Writer.Flush()\n\t}\n\treturn conn, rw, hs, err\n}\n\n// Upgrader contains options for upgrading connection to websocket.\ntype Upgrader struct {\n\t// ReadBufferSize and WriteBufferSize is an I/O buffer sizes.\n\t// They used to read and write http data while upgrading to WebSocket.\n\t// Allocated buffers are pooled with sync.Pool to avoid extra allocations.\n\t//\n\t// If a size is zero then default value is used.\n\t//\n\t// Usually it is useful to set read buffer size bigger than write buffer\n\t// size because incoming request could contain long header values, such as\n\t// Cookie. Response, in other way, could be big only if user write multiple\n\t// custom headers. Usually response takes less than 256 bytes.\n\tReadBufferSize, WriteBufferSize int\n\n\t// Protocol is a select function that is used to select subprotocol\n\t// from list requested by client. If this field is set, then the first matched\n\t// protocol is sent to a client as negotiated.\n\t//\n\t// The argument is only valid until the callback returns.\n\tProtocol func([]byte) bool\n\n\t// ProtocolCustrom allow user to parse Sec-WebSocket-Protocol header manually.\n\t// Note that returned bytes must be valid until Upgrade returns.\n\t// If ProtocolCustom is set, it used instead of Protocol function.\n\tProtocolCustom func([]byte) (string, bool)\n\n\t// Extension is a select function that is used to select extensions\n\t// from list requested by client. If this field is set, then the all matched\n\t// extensions are sent to a client as negotiated.\n\t//\n\t// Note that Extension may be called multiple times and implementations\n\t// must track uniqueness of accepted extensions manually.\n\t//\n\t// The argument is only valid until the callback returns.\n\t//\n\t// According to the RFC6455 order of extensions passed by a client is\n\t// significant. That is, returning true from this function means that no\n\t// other extension with the same name should be checked because server\n\t// accepted the most preferable extension right now:\n\t// \"Note that the order of extensions is significant.  Any interactions between\n\t// multiple extensions MAY be defined in the documents defining the extensions.\n\t// In the absence of such definitions, the interpretation is that the header\n\t// fields listed by the client in its request represent a preference of the\n\t// header fields it wishes to use, with the first options listed being most\n\t// preferable.\"\n\t//\n\t// Deprecated: use Negotiate instead.\n\tExtension func(httphead.Option) bool\n\n\t// ExtensionCustom allow user to parse Sec-WebSocket-Extensions header\n\t// manually.\n\t//\n\t// If ExtensionCustom() decides to accept received extension, it must\n\t// append appropriate option to the given slice of httphead.Option.\n\t// It returns results of append() to the given slice and a flag that\n\t// reports whether given header value is wellformed or not.\n\t//\n\t// Note that ExtensionCustom may be called multiple times and\n\t// implementations must track uniqueness of accepted extensions manually.\n\t//\n\t// Note that returned options should be valid until Upgrade returns.\n\t// If ExtensionCustom is set, it used instead of Extension function.\n\tExtensionCustom func([]byte, []httphead.Option) ([]httphead.Option, bool)\n\n\t// Negotiate is the callback that is used to negotiate extensions from\n\t// the client's offer. If this field is set, then the returned non-zero\n\t// extensions are sent to the client as accepted extensions in the\n\t// response.\n\t//\n\t// The argument is only valid until the Negotiate callback returns.\n\t//\n\t// If returned error is non-nil then connection is rejected and response is\n\t// sent with appropriate HTTP error code and body set to error message.\n\t//\n\t// RejectConnectionError could be used to get more control on response.\n\tNegotiate func(httphead.Option) (httphead.Option, error)\n\n\t// Header is an optional HandshakeHeader instance that could be used to\n\t// write additional headers to the handshake response.\n\t//\n\t// It used instead of any key-value mappings to avoid allocations in user\n\t// land.\n\t//\n\t// Note that if present, it will be written in any result of handshake.\n\tHeader HandshakeHeader\n\n\t// OnRequest is a callback that will be called after request line\n\t// successful parsing.\n\t//\n\t// The arguments are only valid until the callback returns.\n\t//\n\t// If returned error is non-nil then connection is rejected and response is\n\t// sent with appropriate HTTP error code and body set to error message.\n\t//\n\t// RejectConnectionError could be used to get more control on response.\n\tOnRequest func(uri []byte) error\n\n\t// OnHost is a callback that will be called after \"Host\" header successful\n\t// parsing.\n\t//\n\t// It is separated from OnHeader callback because the Host header must be\n\t// present in each request since HTTP/1.1. Thus Host header is non-optional\n\t// and required for every WebSocket handshake.\n\t//\n\t// The arguments are only valid until the callback returns.\n\t//\n\t// If returned error is non-nil then connection is rejected and response is\n\t// sent with appropriate HTTP error code and body set to error message.\n\t//\n\t// RejectConnectionError could be used to get more control on response.\n\tOnHost func(host []byte) error\n\n\t// OnHeader is a callback that will be called after successful parsing of\n\t// header, that is not used during WebSocket handshake procedure. That is,\n\t// it will be called with non-websocket headers, which could be relevant\n\t// for application-level logic.\n\t//\n\t// The arguments are only valid until the callback returns.\n\t//\n\t// If returned error is non-nil then connection is rejected and response is\n\t// sent with appropriate HTTP error code and body set to error message.\n\t//\n\t// RejectConnectionError could be used to get more control on response.\n\tOnHeader func(key, value []byte) error\n\n\t// OnBeforeUpgrade is a callback that will be called before sending\n\t// successful upgrade response.\n\t//\n\t// Setting OnBeforeUpgrade allows user to make final application-level\n\t// checks and decide whether this connection is allowed to successfully\n\t// upgrade to WebSocket.\n\t//\n\t// It must return non-nil either HandshakeHeader or error and never both.\n\t//\n\t// If returned error is non-nil then connection is rejected and response is\n\t// sent with appropriate HTTP error code and body set to error message.\n\t//\n\t// RejectConnectionError could be used to get more control on response.\n\tOnBeforeUpgrade func() (header HandshakeHeader, err error)\n}\n\n// Upgrade zero-copy upgrades connection to WebSocket. It interprets given conn\n// as connection with incoming HTTP Upgrade request.\n//\n// It is a caller responsibility to manage i/o timeouts on conn.\n//\n// Non-nil error means that request for the WebSocket upgrade is invalid or\n// malformed and usually connection should be closed.\n// Even when error is non-nil Upgrade will write appropriate response into\n// connection in compliance with RFC.\nfunc (u Upgrader) Upgrade(conn io.ReadWriter) (hs Handshake, err error) {\n\t// headerSeen constants helps to report whether or not some header was seen\n\t// during reading request bytes.\n\tconst (\n\t\theaderSeenHost = 1 << iota\n\t\theaderSeenUpgrade\n\t\theaderSeenConnection\n\t\theaderSeenSecVersion\n\t\theaderSeenSecKey\n\n\t\t// headerSeenAll is the value that we expect to receive at the end of\n\t\t// headers read/parse loop.\n\t\theaderSeenAll = 0 |\n\t\t\theaderSeenHost |\n\t\t\theaderSeenUpgrade |\n\t\t\theaderSeenConnection |\n\t\t\theaderSeenSecVersion |\n\t\t\theaderSeenSecKey\n\t)\n\n\t// Prepare I/O buffers.\n\t// TODO(gobwas): make it configurable.\n\tbr := pbufio.GetReader(conn,\n\t\tnonZero(u.ReadBufferSize, DefaultServerReadBufferSize),\n\t)\n\tbw := pbufio.GetWriter(conn,\n\t\tnonZero(u.WriteBufferSize, DefaultServerWriteBufferSize),\n\t)\n\tdefer func() {\n\t\tpbufio.PutReader(br)\n\t\tpbufio.PutWriter(bw)\n\t}()\n\n\t// Read HTTP request line like \"GET /ws HTTP/1.1\".\n\trl, err := readLine(br)\n\tif err != nil {\n\t\treturn hs, err\n\t}\n\t// Parse request line data like HTTP version, uri and method.\n\treq, err := httpParseRequestLine(rl)\n\tif err != nil {\n\t\treturn hs, err\n\t}\n\n\t// Prepare stack-based handshake header list.\n\theader := handshakeHeader{\n\t\t0: u.Header,\n\t}\n\n\t// Parse and check HTTP request.\n\t// As RFC6455 says:\n\t//   The client's opening handshake consists of the following parts. If the\n\t//   server, while reading the handshake, finds that the client did not\n\t//   send a handshake that matches the description below (note that as per\n\t//   [RFC2616], the order of the header fields is not important), including\n\t//   but not limited to any violations of the ABNF grammar specified for\n\t//   the components of the handshake, the server MUST stop processing the\n\t//   client's handshake and return an HTTP response with an appropriate\n\t//   error code (such as 400 Bad Request).\n\t//\n\t// See https://tools.ietf.org/html/rfc6455#section-4.2.1\n\n\t// An HTTP/1.1 or higher GET request, including a \"Request-URI\".\n\t//\n\t// Even if RFC says \"1.1 or higher\" without mentioning the part of the\n\t// version, we apply it only to minor part.\n\tswitch {\n\tcase req.major != 1 || req.minor < 1:\n\t\t// Abort processing the whole request because we do not even know how\n\t\t// to actually parse it.\n\t\terr = ErrHandshakeBadProtocol\n\n\tcase btsToString(req.method) != http.MethodGet:\n\t\terr = ErrHandshakeBadMethod\n\n\tdefault:\n\t\tif onRequest := u.OnRequest; onRequest != nil {\n\t\t\terr = onRequest(req.uri)\n\t\t}\n\t}\n\t// Start headers read/parse loop.\n\tvar (\n\t\t// headerSeen reports which header was seen by setting corresponding\n\t\t// bit on.\n\t\theaderSeen byte\n\n\t\tnonce = make([]byte, nonceSize)\n\t)\n\tfor err == nil {\n\t\tline, e := readLine(br)\n\t\tif e != nil {\n\t\t\treturn hs, e\n\t\t}\n\t\tif len(line) == 0 {\n\t\t\t// Blank line, no more lines to read.\n\t\t\tbreak\n\t\t}\n\n\t\tk, v, ok := httpParseHeaderLine(line)\n\t\tif !ok {\n\t\t\terr = ErrMalformedRequest\n\t\t\tbreak\n\t\t}\n\n\t\tswitch btsToString(k) {\n\t\tcase headerHostCanonical:\n\t\t\theaderSeen |= headerSeenHost\n\t\t\tif onHost := u.OnHost; onHost != nil {\n\t\t\t\terr = onHost(v)\n\t\t\t}\n\n\t\tcase headerUpgradeCanonical:\n\t\t\theaderSeen |= headerSeenUpgrade\n\t\t\tif !bytes.Equal(v, specHeaderValueUpgrade) && !bytes.EqualFold(v, specHeaderValueUpgrade) {\n\t\t\t\terr = ErrHandshakeBadUpgrade\n\t\t\t}\n\n\t\tcase headerConnectionCanonical:\n\t\t\theaderSeen |= headerSeenConnection\n\t\t\tif !bytes.Equal(v, specHeaderValueConnection) && !btsHasToken(v, specHeaderValueConnectionLower) {\n\t\t\t\terr = ErrHandshakeBadConnection\n\t\t\t}\n\n\t\tcase headerSecVersionCanonical:\n\t\t\theaderSeen |= headerSeenSecVersion\n\t\t\tif !bytes.Equal(v, specHeaderValueSecVersion) {\n\t\t\t\terr = ErrHandshakeUpgradeRequired\n\t\t\t}\n\n\t\tcase headerSecKeyCanonical:\n\t\t\theaderSeen |= headerSeenSecKey\n\t\t\tif len(v) != nonceSize {\n\t\t\t\terr = ErrHandshakeBadSecKey\n\t\t\t} else {\n\t\t\t\tcopy(nonce, v)\n\t\t\t}\n\n\t\tcase headerSecProtocolCanonical:\n\t\t\tif custom, check := u.ProtocolCustom, u.Protocol; hs.Protocol == \"\" && (custom != nil || check != nil) {\n\t\t\t\tvar ok bool\n\t\t\t\tif custom != nil {\n\t\t\t\t\ths.Protocol, ok = custom(v)\n\t\t\t\t} else {\n\t\t\t\t\ths.Protocol, ok = btsSelectProtocol(v, check)\n\t\t\t\t}\n\t\t\t\tif !ok {\n\t\t\t\t\terr = ErrMalformedRequest\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase headerSecExtensionsCanonical:\n\t\t\tif f := u.Negotiate; err == nil && f != nil {\n\t\t\t\ths.Extensions, err = negotiateExtensions(v, hs.Extensions, f)\n\t\t\t}\n\t\t\t// DEPRECATED path.\n\t\t\tif custom, check := u.ExtensionCustom, u.Extension; u.Negotiate == nil && (custom != nil || check != nil) {\n\t\t\t\tvar ok bool\n\t\t\t\tif custom != nil {\n\t\t\t\t\ths.Extensions, ok = custom(v, hs.Extensions)\n\t\t\t\t} else {\n\t\t\t\t\ths.Extensions, ok = btsSelectExtensions(v, hs.Extensions, check)\n\t\t\t\t}\n\t\t\t\tif !ok {\n\t\t\t\t\terr = ErrMalformedRequest\n\t\t\t\t}\n\t\t\t}\n\n\t\tdefault:\n\t\t\tif onHeader := u.OnHeader; onHeader != nil {\n\t\t\t\terr = onHeader(k, v)\n\t\t\t}\n\t\t}\n\t}\n\tswitch {\n\tcase err == nil && headerSeen != headerSeenAll:\n\t\tswitch {\n\t\tcase headerSeen&headerSeenHost == 0:\n\t\t\t// As RFC2616 says:\n\t\t\t//   A client MUST include a Host header field in all HTTP/1.1\n\t\t\t//   request messages. If the requested URI does not include an\n\t\t\t//   Internet host name for the service being requested, then the\n\t\t\t//   Host header field MUST be given with an empty value. An\n\t\t\t//   HTTP/1.1 proxy MUST ensure that any request message it\n\t\t\t//   forwards does contain an appropriate Host header field that\n\t\t\t//   identifies the service being requested by the proxy. All\n\t\t\t//   Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad\n\t\t\t//   Request) status code to any HTTP/1.1 request message which\n\t\t\t//   lacks a Host header field.\n\t\t\terr = ErrHandshakeBadHost\n\t\tcase headerSeen&headerSeenUpgrade == 0:\n\t\t\terr = ErrHandshakeBadUpgrade\n\t\tcase headerSeen&headerSeenConnection == 0:\n\t\t\terr = ErrHandshakeBadConnection\n\t\tcase headerSeen&headerSeenSecVersion == 0:\n\t\t\t// In case of empty or not present version we do not send 426 status,\n\t\t\t// because it does not meet the ABNF rules of RFC6455:\n\t\t\t//\n\t\t\t// version = DIGIT | (NZDIGIT DIGIT) |\n\t\t\t// (\"1\" DIGIT DIGIT) | (\"2\" DIGIT DIGIT)\n\t\t\t// ; Limited to 0-255 range, with no leading zeros\n\t\t\t//\n\t\t\t// That is, if version is really invalid – we sent 426 status as above, if it\n\t\t\t// not present – it is 400.\n\t\t\terr = ErrHandshakeBadSecVersion\n\t\tcase headerSeen&headerSeenSecKey == 0:\n\t\t\terr = ErrHandshakeBadSecKey\n\t\tdefault:\n\t\t\tpanic(\"unknown headers state\")\n\t\t}\n\n\tcase err == nil && u.OnBeforeUpgrade != nil:\n\t\theader[1], err = u.OnBeforeUpgrade()\n\t}\n\tif err != nil {\n\t\tvar code int\n\t\tif rej, ok := err.(*ConnectionRejectedError); ok {\n\t\t\tcode = rej.code\n\t\t\theader[1] = rej.header\n\t\t}\n\t\tif code == 0 {\n\t\t\tcode = http.StatusInternalServerError\n\t\t}\n\t\thttpWriteResponseError(bw, err, code, header.WriteTo)\n\t\t// Do not store Flush() error to not override already existing one.\n\t\t_ = bw.Flush()\n\t\treturn hs, err\n\t}\n\n\thttpWriteResponseUpgrade(bw, nonce, hs, header.WriteTo)\n\terr = bw.Flush()\n\n\treturn hs, err\n}\n\ntype handshakeHeader [2]HandshakeHeader\n\nfunc (hs handshakeHeader) WriteTo(w io.Writer) (n int64, err error) {\n\tfor i := 0; i < len(hs) && err == nil; i++ {\n\t\tif h := hs[i]; h != nil {\n\t\t\tvar m int64\n\t\t\tm, err = h.WriteTo(w)\n\t\t\tn += m\n\t\t}\n\t}\n\treturn n, err\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/util.go",
    "content": "package ws\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\n\t\"github.com/gobwas/httphead\"\n)\n\n// SelectFromSlice creates accept function that could be used as Protocol/Extension\n// select during upgrade.\nfunc SelectFromSlice(accept []string) func(string) bool {\n\tif len(accept) > 16 {\n\t\tmp := make(map[string]struct{}, len(accept))\n\t\tfor _, p := range accept {\n\t\t\tmp[p] = struct{}{}\n\t\t}\n\t\treturn func(p string) bool {\n\t\t\t_, ok := mp[p]\n\t\t\treturn ok\n\t\t}\n\t}\n\treturn func(p string) bool {\n\t\tfor _, ok := range accept {\n\t\t\tif p == ok {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n}\n\n// SelectEqual creates accept function that could be used as Protocol/Extension\n// select during upgrade.\nfunc SelectEqual(v string) func(string) bool {\n\treturn func(p string) bool {\n\t\treturn v == p\n\t}\n}\n\n// asciiToInt converts bytes to int.\nfunc asciiToInt(bts []byte) (ret int, err error) {\n\t// ASCII numbers all start with the high-order bits 0011.\n\t// If you see that, and the next bits are 0-9 (0000 - 1001) you can grab those\n\t// bits and interpret them directly as an integer.\n\tvar n int\n\tif n = len(bts); n < 1 {\n\t\treturn 0, fmt.Errorf(\"converting empty bytes to int\")\n\t}\n\tfor i := 0; i < n; i++ {\n\t\tif bts[i]&0xf0 != 0x30 {\n\t\t\treturn 0, fmt.Errorf(\"%s is not a numeric character\", string(bts[i]))\n\t\t}\n\t\tret += int(bts[i]&0xf) * pow(10, n-i-1)\n\t}\n\treturn ret, nil\n}\n\n// pow for integers implementation.\n// See Donald Knuth, The Art of Computer Programming, Volume 2, Section 4.6.3.\nfunc pow(a, b int) int {\n\tp := 1\n\tfor b > 0 {\n\t\tif b&1 != 0 {\n\t\t\tp *= a\n\t\t}\n\t\tb >>= 1\n\t\ta *= a\n\t}\n\treturn p\n}\n\nfunc bsplit3(bts []byte, sep byte) (b1, b2, b3 []byte) {\n\ta := bytes.IndexByte(bts, sep)\n\tb := bytes.IndexByte(bts[a+1:], sep)\n\tif a == -1 || b == -1 {\n\t\treturn bts, nil, nil\n\t}\n\tb += a + 1\n\treturn bts[:a], bts[a+1 : b], bts[b+1:]\n}\n\nfunc btrim(bts []byte) []byte {\n\tvar i, j int\n\tfor i = 0; i < len(bts) && (bts[i] == ' ' || bts[i] == '\\t'); {\n\t\ti++\n\t}\n\tfor j = len(bts); j > i && (bts[j-1] == ' ' || bts[j-1] == '\\t'); {\n\t\tj--\n\t}\n\treturn bts[i:j]\n}\n\nfunc strHasToken(header, token string) (has bool) {\n\treturn btsHasToken(strToBytes(header), strToBytes(token))\n}\n\nfunc btsHasToken(header, token []byte) (has bool) {\n\thttphead.ScanTokens(header, func(v []byte) bool {\n\t\thas = bytes.EqualFold(v, token)\n\t\treturn !has\n\t})\n\treturn has\n}\n\nconst (\n\ttoLower  = 'a' - 'A'      // for use with OR.\n\ttoUpper  = ^byte(toLower) // for use with AND.\n\ttoLower8 = uint64(toLower) |\n\t\tuint64(toLower)<<8 |\n\t\tuint64(toLower)<<16 |\n\t\tuint64(toLower)<<24 |\n\t\tuint64(toLower)<<32 |\n\t\tuint64(toLower)<<40 |\n\t\tuint64(toLower)<<48 |\n\t\tuint64(toLower)<<56\n)\n\n// Algorithm below is like standard textproto/CanonicalMIMEHeaderKey, except\n// that it operates with slice of bytes and modifies it inplace without copying.\nfunc canonicalizeHeaderKey(k []byte) {\n\tupper := true\n\tfor i, c := range k {\n\t\tif upper && 'a' <= c && c <= 'z' {\n\t\t\tk[i] &= toUpper\n\t\t} else if !upper && 'A' <= c && c <= 'Z' {\n\t\t\tk[i] |= toLower\n\t\t}\n\t\tupper = c == '-'\n\t}\n}\n\n// readLine reads line from br. It reads until '\\n' and returns bytes without\n// '\\n' or '\\r\\n' at the end.\n// It returns err if and only if line does not end in '\\n'. Note that read\n// bytes returned in any case of error.\n//\n// It is much like the textproto/Reader.ReadLine() except the thing that it\n// returns raw bytes, instead of string. That is, it avoids copying bytes read\n// from br.\n//\n// textproto/Reader.ReadLineBytes() is also makes copy of resulting bytes to be\n// safe with future I/O operations on br.\n//\n// We could control I/O operations on br and do not need to make additional\n// copy for safety.\n//\n// NOTE: it may return copied flag to notify that returned buffer is safe to\n// use.\nfunc readLine(br *bufio.Reader) ([]byte, error) {\n\tvar line []byte\n\tfor {\n\t\tbts, err := br.ReadSlice('\\n')\n\t\tif err == bufio.ErrBufferFull {\n\t\t\t// Copy bytes because next read will discard them.\n\t\t\tline = append(line, bts...)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Avoid copy of single read.\n\t\tif line == nil {\n\t\t\tline = bts\n\t\t} else {\n\t\t\tline = append(line, bts...)\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn line, err\n\t\t}\n\n\t\t// Size of line is at least 1.\n\t\t// In other case bufio.ReadSlice() returns error.\n\t\tn := len(line)\n\n\t\t// Cut '\\n' or '\\r\\n'.\n\t\tif n > 1 && line[n-2] == '\\r' {\n\t\t\tline = line[:n-2]\n\t\t} else {\n\t\t\tline = line[:n-1]\n\t\t}\n\n\t\treturn line, nil\n\t}\n}\n\nfunc min(a, b int) int {\n\tif a < b {\n\t\treturn a\n\t}\n\treturn b\n}\n\nfunc nonZero(a, b int) int {\n\tif a != 0 {\n\t\treturn a\n\t}\n\treturn b\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/util_purego.go",
    "content": "//go:build purego\n// +build purego\n\npackage ws\n\nfunc strToBytes(str string) (bts []byte) {\n\treturn []byte(str)\n}\n\nfunc btsToString(bts []byte) (str string) {\n\treturn string(bts)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/util_unsafe.go",
    "content": "//go:build !purego\n// +build !purego\n\npackage ws\n\nimport (\n\t\"reflect\"\n\t\"unsafe\"\n)\n\nfunc strToBytes(str string) (bts []byte) {\n\ts := (*reflect.StringHeader)(unsafe.Pointer(&str))\n\tb := (*reflect.SliceHeader)(unsafe.Pointer(&bts))\n\tb.Data = s.Data\n\tb.Len = s.Len\n\tb.Cap = s.Len\n\treturn bts\n}\n\nfunc btsToString(bts []byte) (str string) {\n\treturn *(*string)(unsafe.Pointer(&bts))\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/write.go",
    "content": "package ws\n\nimport (\n\t\"encoding/binary\"\n\t\"io\"\n)\n\n// Header size length bounds in bytes.\nconst (\n\tMaxHeaderSize = 14\n\tMinHeaderSize = 2\n)\n\nconst (\n\tbit0 = 0x80\n\tbit1 = 0x40\n\tbit2 = 0x20\n\tbit3 = 0x10\n\tbit4 = 0x08\n\tbit5 = 0x04\n\tbit6 = 0x02\n\tbit7 = 0x01\n\n\tlen7  = int64(125)\n\tlen16 = int64(^(uint16(0)))\n\tlen64 = int64(^(uint64(0)) >> 1)\n)\n\n// HeaderSize returns number of bytes that are needed to encode given header.\n// It returns -1 if header is malformed.\nfunc HeaderSize(h Header) (n int) {\n\tswitch {\n\tcase h.Length < 126:\n\t\tn = 2\n\tcase h.Length <= len16:\n\t\tn = 4\n\tcase h.Length <= len64:\n\t\tn = 10\n\tdefault:\n\t\treturn -1\n\t}\n\tif h.Masked {\n\t\tn += len(h.Mask)\n\t}\n\treturn n\n}\n\n// WriteHeader writes header binary representation into w.\nfunc WriteHeader(w io.Writer, h Header) error {\n\t// Make slice of bytes with capacity 14 that could hold any header.\n\tbts := make([]byte, MaxHeaderSize)\n\n\tif h.Fin {\n\t\tbts[0] |= bit0\n\t}\n\tbts[0] |= h.Rsv << 4\n\tbts[0] |= byte(h.OpCode)\n\n\tvar n int\n\tswitch {\n\tcase h.Length <= len7:\n\t\tbts[1] = byte(h.Length)\n\t\tn = 2\n\n\tcase h.Length <= len16:\n\t\tbts[1] = 126\n\t\tbinary.BigEndian.PutUint16(bts[2:4], uint16(h.Length))\n\t\tn = 4\n\n\tcase h.Length <= len64:\n\t\tbts[1] = 127\n\t\tbinary.BigEndian.PutUint64(bts[2:10], uint64(h.Length))\n\t\tn = 10\n\n\tdefault:\n\t\treturn ErrHeaderLengthUnexpected\n\t}\n\n\tif h.Masked {\n\t\tbts[1] |= bit0\n\t\tn += copy(bts[n:], h.Mask[:])\n\t}\n\n\t_, err := w.Write(bts[:n])\n\n\treturn err\n}\n\n// WriteFrame writes frame binary representation into w.\nfunc WriteFrame(w io.Writer, f Frame) error {\n\terr := WriteHeader(w, f.Header)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = w.Write(f.Payload)\n\treturn err\n}\n\n// MustWriteFrame is like WriteFrame but panics if frame can not be read.\nfunc MustWriteFrame(w io.Writer, f Frame) {\n\tif err := WriteFrame(w, f); err != nil {\n\t\tpanic(err)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/wsutil/cipher.go",
    "content": "package wsutil\n\nimport (\n\t\"io\"\n\n\t\"github.com/gobwas/pool/pbytes\"\n\t\"github.com/gobwas/ws\"\n)\n\n// CipherReader implements io.Reader that applies xor-cipher to the bytes read\n// from source.\n// It could help to unmask WebSocket frame payload on the fly.\ntype CipherReader struct {\n\tr    io.Reader\n\tmask [4]byte\n\tpos  int\n}\n\n// NewCipherReader creates xor-cipher reader from r with given mask.\nfunc NewCipherReader(r io.Reader, mask [4]byte) *CipherReader {\n\treturn &CipherReader{r, mask, 0}\n}\n\n// Reset resets CipherReader to read from r with given mask.\nfunc (c *CipherReader) Reset(r io.Reader, mask [4]byte) {\n\tc.r = r\n\tc.mask = mask\n\tc.pos = 0\n}\n\n// Read implements io.Reader interface. It applies mask given during\n// initialization to every read byte.\nfunc (c *CipherReader) Read(p []byte) (n int, err error) {\n\tn, err = c.r.Read(p)\n\tws.Cipher(p[:n], c.mask, c.pos)\n\tc.pos += n\n\treturn n, err\n}\n\n// CipherWriter implements io.Writer that applies xor-cipher to the bytes\n// written to the destination writer. It does not modify the original bytes.\ntype CipherWriter struct {\n\tw    io.Writer\n\tmask [4]byte\n\tpos  int\n}\n\n// NewCipherWriter creates xor-cipher writer to w with given mask.\nfunc NewCipherWriter(w io.Writer, mask [4]byte) *CipherWriter {\n\treturn &CipherWriter{w, mask, 0}\n}\n\n// Reset reset CipherWriter to write to w with given mask.\nfunc (c *CipherWriter) Reset(w io.Writer, mask [4]byte) {\n\tc.w = w\n\tc.mask = mask\n\tc.pos = 0\n}\n\n// Write implements io.Writer interface. It applies masking during\n// initialization to every sent byte. It does not modify original slice.\nfunc (c *CipherWriter) Write(p []byte) (n int, err error) {\n\tcp := pbytes.GetLen(len(p))\n\tdefer pbytes.Put(cp)\n\n\tcopy(cp, p)\n\tws.Cipher(cp, c.mask, c.pos)\n\tn, err = c.w.Write(cp)\n\tc.pos += n\n\n\treturn n, err\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/wsutil/dialer.go",
    "content": "package wsutil\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net\"\n\t\"net/http\"\n\n\t\"github.com/gobwas/ws\"\n)\n\n// DebugDialer is a wrapper around ws.Dialer. It tracks i/o of WebSocket\n// handshake. That is, it gives ability to receive copied HTTP request and\n// response bytes that made inside Dialer.Dial().\n//\n// Note that it must not be used in production applications that requires\n// Dial() to be efficient.\ntype DebugDialer struct {\n\t// Dialer contains WebSocket connection establishment options.\n\tDialer ws.Dialer\n\n\t// OnRequest and OnResponse are the callbacks that will be called with the\n\t// HTTP request and response respectively.\n\tOnRequest, OnResponse func([]byte)\n}\n\n// Dial connects to the url host and upgrades connection to WebSocket. It makes\n// it by calling d.Dialer.Dial().\nfunc (d *DebugDialer) Dial(ctx context.Context, urlstr string) (conn net.Conn, br *bufio.Reader, hs ws.Handshake, err error) {\n\t// Need to copy Dialer to prevent original object mutation.\n\tdialer := d.Dialer\n\tvar (\n\t\treqBuf bytes.Buffer\n\t\tresBuf bytes.Buffer\n\n\t\tresContentLength int64\n\t)\n\tuserWrap := dialer.WrapConn\n\tdialer.WrapConn = func(c net.Conn) net.Conn {\n\t\tif userWrap != nil {\n\t\t\tc = userWrap(c)\n\t\t}\n\n\t\t// Save the pointer to the raw connection.\n\t\tconn = c\n\n\t\tvar (\n\t\t\tr io.Reader = conn\n\t\t\tw io.Writer = conn\n\t\t)\n\t\tif d.OnResponse != nil {\n\t\t\tr = &prefetchResponseReader{\n\t\t\t\tsource:        conn,\n\t\t\t\tbuffer:        &resBuf,\n\t\t\t\tcontentLength: &resContentLength,\n\t\t\t}\n\t\t}\n\t\tif d.OnRequest != nil {\n\t\t\tw = io.MultiWriter(conn, &reqBuf)\n\t\t}\n\t\treturn rwConn{conn, r, w}\n\t}\n\n\t_, br, hs, err = dialer.Dial(ctx, urlstr)\n\n\tif onRequest := d.OnRequest; onRequest != nil {\n\t\tonRequest(reqBuf.Bytes())\n\t}\n\tif onResponse := d.OnResponse; onResponse != nil {\n\t\t// We must split response inside buffered bytes from other received\n\t\t// bytes from server.\n\t\tp := resBuf.Bytes()\n\t\tn := bytes.Index(p, headEnd)\n\t\th := n + len(headEnd)         // Head end index.\n\t\tn = h + int(resContentLength) // Body end index.\n\n\t\tonResponse(p[:n])\n\n\t\tif br != nil {\n\t\t\t// If br is non-nil, then it mean two things. First is that\n\t\t\t// handshake is OK and server has sent additional bytes – probably\n\t\t\t// immediate sent frames (or weird but possible response body).\n\t\t\t// Second, the bad one, is that br buffer's source is now rwConn\n\t\t\t// instance from above WrapConn call. It is incorrect, so we must\n\t\t\t// fix it.\n\t\t\tvar r io.Reader = conn\n\t\t\tif len(p) > h {\n\t\t\t\t// Buffer contains more than just HTTP headers bytes.\n\t\t\t\tr = io.MultiReader(\n\t\t\t\t\tbytes.NewReader(p[h:]),\n\t\t\t\t\tconn,\n\t\t\t\t)\n\t\t\t}\n\t\t\tbr.Reset(r)\n\t\t\t// Must make br.Buffered() to be non-zero.\n\t\t\tbr.Peek(len(p[h:]))\n\t\t}\n\t}\n\n\treturn conn, br, hs, err\n}\n\ntype rwConn struct {\n\tnet.Conn\n\n\tr io.Reader\n\tw io.Writer\n}\n\nfunc (rwc rwConn) Read(p []byte) (int, error) {\n\treturn rwc.r.Read(p)\n}\n\nfunc (rwc rwConn) Write(p []byte) (int, error) {\n\treturn rwc.w.Write(p)\n}\n\nvar headEnd = []byte(\"\\r\\n\\r\\n\")\n\ntype prefetchResponseReader struct {\n\tsource io.Reader // Original connection source.\n\treader io.Reader // Wrapped reader used to read from by clients.\n\tbuffer *bytes.Buffer\n\n\tcontentLength *int64\n}\n\nfunc (r *prefetchResponseReader) Read(p []byte) (int, error) {\n\tif r.reader == nil {\n\t\tresp, err := http.ReadResponse(bufio.NewReader(\n\t\t\tio.TeeReader(r.source, r.buffer),\n\t\t), nil)\n\t\tif err == nil {\n\t\t\t*r.contentLength, _ = io.Copy(ioutil.Discard, resp.Body)\n\t\t\tresp.Body.Close()\n\t\t}\n\t\tbts := r.buffer.Bytes()\n\t\tr.reader = io.MultiReader(\n\t\t\tbytes.NewReader(bts),\n\t\t\tr.source,\n\t\t)\n\t}\n\treturn r.reader.Read(p)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/wsutil/extenstion.go",
    "content": "package wsutil\n\nimport \"github.com/gobwas/ws\"\n\n// RecvExtension is an interface for clearing fragment header RSV bits.\ntype RecvExtension interface {\n\tUnsetBits(ws.Header) (ws.Header, error)\n}\n\n// RecvExtensionFunc is an adapter to allow the use of ordinary functions as\n// RecvExtension.\ntype RecvExtensionFunc func(ws.Header) (ws.Header, error)\n\n// BitsRecv implements RecvExtension.\nfunc (fn RecvExtensionFunc) UnsetBits(h ws.Header) (ws.Header, error) {\n\treturn fn(h)\n}\n\n// SendExtension is an interface for setting fragment header RSV bits.\ntype SendExtension interface {\n\tSetBits(ws.Header) (ws.Header, error)\n}\n\n// SendExtensionFunc is an adapter to allow the use of ordinary functions as\n// SendExtension.\ntype SendExtensionFunc func(ws.Header) (ws.Header, error)\n\n// BitsSend implements SendExtension.\nfunc (fn SendExtensionFunc) SetBits(h ws.Header) (ws.Header, error) {\n\treturn fn(h)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/wsutil/handler.go",
    "content": "package wsutil\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"strconv\"\n\n\t\"github.com/gobwas/pool/pbytes\"\n\t\"github.com/gobwas/ws\"\n)\n\n// ClosedError returned when peer has closed the connection with appropriate\n// code and a textual reason.\ntype ClosedError struct {\n\tCode   ws.StatusCode\n\tReason string\n}\n\n// Error implements error interface.\nfunc (err ClosedError) Error() string {\n\treturn \"ws closed: \" + strconv.FormatUint(uint64(err.Code), 10) + \" \" + err.Reason\n}\n\n// ControlHandler contains logic of handling control frames.\n//\n// The intentional way to use it is to read the next frame header from the\n// connection, optionally check its validity via ws.CheckHeader() and if it is\n// not a ws.OpText of ws.OpBinary (or ws.OpContinuation) – pass it to Handle()\n// method.\n//\n// That is, passed header should be checked to get rid of unexpected errors.\n//\n// The Handle() method will read out all control frame payload (if any) and\n// write necessary bytes as a rfc compatible response.\ntype ControlHandler struct {\n\tSrc   io.Reader\n\tDst   io.Writer\n\tState ws.State\n\n\t// DisableSrcCiphering disables unmasking payload data read from Src.\n\t// It is useful when wsutil.Reader is used or when frame payload already\n\t// pulled and ciphered out from the connection (and introduced by\n\t// bytes.Reader, for example).\n\tDisableSrcCiphering bool\n}\n\n// ErrNotControlFrame is returned by ControlHandler to indicate that given\n// header could not be handled.\nvar ErrNotControlFrame = errors.New(\"not a control frame\")\n\n// Handle handles control frames regarding to the c.State and writes responses\n// to the c.Dst when needed.\n//\n// It returns ErrNotControlFrame when given header is not of ws.OpClose,\n// ws.OpPing or ws.OpPong operation code.\nfunc (c ControlHandler) Handle(h ws.Header) error {\n\tswitch h.OpCode {\n\tcase ws.OpPing:\n\t\treturn c.HandlePing(h)\n\tcase ws.OpPong:\n\t\treturn c.HandlePong(h)\n\tcase ws.OpClose:\n\t\treturn c.HandleClose(h)\n\t}\n\treturn ErrNotControlFrame\n}\n\n// HandlePing handles ping frame and writes specification compatible response\n// to the c.Dst.\nfunc (c ControlHandler) HandlePing(h ws.Header) error {\n\tif h.Length == 0 {\n\t\t// The most common case when ping is empty.\n\t\t// Note that when sending masked frame the mask for empty payload is\n\t\t// just four zero bytes.\n\t\treturn ws.WriteHeader(c.Dst, ws.Header{\n\t\t\tFin:    true,\n\t\t\tOpCode: ws.OpPong,\n\t\t\tMasked: c.State.ClientSide(),\n\t\t})\n\t}\n\n\t// In other way reply with Pong frame with copied payload.\n\tp := pbytes.GetLen(int(h.Length) + ws.HeaderSize(ws.Header{\n\t\tLength: h.Length,\n\t\tMasked: c.State.ClientSide(),\n\t}))\n\tdefer pbytes.Put(p)\n\n\t// Deal with ciphering i/o:\n\t// Masking key is used to mask the \"Payload data\" defined in the same\n\t// section as frame-payload-data, which includes \"Extension data\" and\n\t// \"Application data\".\n\t//\n\t// See https://tools.ietf.org/html/rfc6455#section-5.3\n\t//\n\t// NOTE: We prefer ControlWriter with preallocated buffer to\n\t// ws.WriteHeader because it performs one syscall instead of two.\n\tw := NewControlWriterBuffer(c.Dst, c.State, ws.OpPong, p)\n\tr := c.Src\n\tif c.State.ServerSide() && !c.DisableSrcCiphering {\n\t\tr = NewCipherReader(r, h.Mask)\n\t}\n\n\t_, err := io.Copy(w, r)\n\tif err == nil {\n\t\terr = w.Flush()\n\t}\n\n\treturn err\n}\n\n// HandlePong handles pong frame by discarding it.\nfunc (c ControlHandler) HandlePong(h ws.Header) error {\n\tif h.Length == 0 {\n\t\treturn nil\n\t}\n\n\tbuf := pbytes.GetLen(int(h.Length))\n\tdefer pbytes.Put(buf)\n\n\t// Discard pong message according to the RFC6455:\n\t// A Pong frame MAY be sent unsolicited. This serves as a\n\t// unidirectional heartbeat. A response to an unsolicited Pong frame\n\t// is not expected.\n\t_, err := io.CopyBuffer(ioutil.Discard, c.Src, buf)\n\n\treturn err\n}\n\n// HandleClose handles close frame, makes protocol validity checks and writes\n// specification compatible response to the c.Dst.\nfunc (c ControlHandler) HandleClose(h ws.Header) error {\n\tif h.Length == 0 {\n\t\terr := ws.WriteHeader(c.Dst, ws.Header{\n\t\t\tFin:    true,\n\t\t\tOpCode: ws.OpClose,\n\t\t\tMasked: c.State.ClientSide(),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Due to RFC, we should interpret the code as no status code\n\t\t// received:\n\t\t//   If this Close control frame contains no status code, _The WebSocket\n\t\t//   Connection Close Code_ is considered to be 1005.\n\t\t//\n\t\t// See https://tools.ietf.org/html/rfc6455#section-7.1.5\n\t\treturn ClosedError{\n\t\t\tCode: ws.StatusNoStatusRcvd,\n\t\t}\n\t}\n\n\t// Prepare bytes both for reading reason and sending response.\n\tp := pbytes.GetLen(int(h.Length) + ws.HeaderSize(ws.Header{\n\t\tLength: h.Length,\n\t\tMasked: c.State.ClientSide(),\n\t}))\n\tdefer pbytes.Put(p)\n\n\t// Get the subslice to read the frame payload out.\n\tsubp := p[:h.Length]\n\n\tr := c.Src\n\tif c.State.ServerSide() && !c.DisableSrcCiphering {\n\t\tr = NewCipherReader(r, h.Mask)\n\t}\n\tif _, err := io.ReadFull(r, subp); err != nil {\n\t\treturn err\n\t}\n\n\tcode, reason := ws.ParseCloseFrameData(subp)\n\tif err := ws.CheckCloseFrameData(code, reason); err != nil {\n\t\t// Here we could not use the prepared bytes because there is no\n\t\t// guarantee that it may fit our protocol error closure code and a\n\t\t// reason.\n\t\tc.closeWithProtocolError(err)\n\t\treturn err\n\t}\n\n\t// Deal with ciphering i/o:\n\t// Masking key is used to mask the \"Payload data\" defined in the same\n\t// section as frame-payload-data, which includes \"Extension data\" and\n\t// \"Application data\".\n\t//\n\t// See https://tools.ietf.org/html/rfc6455#section-5.3\n\t//\n\t// NOTE: We prefer ControlWriter with preallocated buffer to\n\t// ws.WriteHeader because it performs one syscall instead of two.\n\tw := NewControlWriterBuffer(c.Dst, c.State, ws.OpClose, p)\n\n\t// RFC6455#5.5.1:\n\t// If an endpoint receives a Close frame and did not previously\n\t// send a Close frame, the endpoint MUST send a Close frame in\n\t// response. (When sending a Close frame in response, the endpoint\n\t// typically echoes the status code it received.)\n\t_, err := w.Write(p[:2])\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err := w.Flush(); err != nil {\n\t\treturn err\n\t}\n\treturn ClosedError{\n\t\tCode:   code,\n\t\tReason: reason,\n\t}\n}\n\nfunc (c ControlHandler) closeWithProtocolError(reason error) error {\n\tf := ws.NewCloseFrame(ws.NewCloseFrameBody(\n\t\tws.StatusProtocolError, reason.Error(),\n\t))\n\tif c.State.ClientSide() {\n\t\tws.MaskFrameInPlace(f)\n\t}\n\treturn ws.WriteFrame(c.Dst, f)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/wsutil/helper.go",
    "content": "package wsutil\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"io/ioutil\"\n\n\t\"github.com/gobwas/ws\"\n)\n\n// Message represents a message from peer, that could be presented in one or\n// more frames. That is, it contains payload of all message fragments and\n// operation code of initial frame for this message.\ntype Message struct {\n\tOpCode  ws.OpCode\n\tPayload []byte\n}\n\n// ReadMessage is a helper function that reads next message from r. It appends\n// received message(s) to the third argument and returns the result of it and\n// an error if some failure happened. That is, it probably could receive more\n// than one message when peer sending fragmented message in multiple frames and\n// want to send some control frame between fragments. Then returned slice will\n// contain those control frames at first, and then result of gluing fragments.\n//\n// TODO(gobwas): add DefaultReader with buffer size options.\nfunc ReadMessage(r io.Reader, s ws.State, m []Message) ([]Message, error) {\n\trd := Reader{\n\t\tSource:    r,\n\t\tState:     s,\n\t\tCheckUTF8: true,\n\t\tOnIntermediate: func(hdr ws.Header, src io.Reader) error {\n\t\t\tbts, err := ioutil.ReadAll(src)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tm = append(m, Message{hdr.OpCode, bts})\n\t\t\treturn nil\n\t\t},\n\t}\n\th, err := rd.NextFrame()\n\tif err != nil {\n\t\treturn m, err\n\t}\n\tvar p []byte\n\tif h.Fin {\n\t\t// No more frames will be read. Use fixed sized buffer to read payload.\n\t\tp = make([]byte, h.Length)\n\t\t// It is not possible to receive io.EOF here because Reader does not\n\t\t// return EOF if frame payload was successfully fetched.\n\t\t// Thus we consistent here with io.Reader behavior.\n\t\t_, err = io.ReadFull(&rd, p)\n\t} else {\n\t\t// Frame is fragmented, thus use ioutil.ReadAll behavior.\n\t\tvar buf bytes.Buffer\n\t\t_, err = buf.ReadFrom(&rd)\n\t\tp = buf.Bytes()\n\t}\n\tif err != nil {\n\t\treturn m, err\n\t}\n\treturn append(m, Message{h.OpCode, p}), nil\n}\n\n// ReadClientMessage reads next message from r, considering that caller\n// represents server side.\n// It is a shortcut for ReadMessage(r, ws.StateServerSide, m).\nfunc ReadClientMessage(r io.Reader, m []Message) ([]Message, error) {\n\treturn ReadMessage(r, ws.StateServerSide, m)\n}\n\n// ReadServerMessage reads next message from r, considering that caller\n// represents client side.\n// It is a shortcut for ReadMessage(r, ws.StateClientSide, m).\nfunc ReadServerMessage(r io.Reader, m []Message) ([]Message, error) {\n\treturn ReadMessage(r, ws.StateClientSide, m)\n}\n\n// ReadData is a helper function that reads next data (non-control) message\n// from rw.\n// It takes care on handling all control frames. It will write response on\n// control frames to the write part of rw. It blocks until some data frame\n// will be received.\n//\n// Note this may handle and write control frames into the writer part of a\n// given io.ReadWriter.\nfunc ReadData(rw io.ReadWriter, s ws.State) ([]byte, ws.OpCode, error) {\n\treturn readData(rw, s, ws.OpText|ws.OpBinary)\n}\n\n// ReadClientData reads next data message from rw, considering that caller\n// represents server side. It is a shortcut for ReadData(rw, ws.StateServerSide).\n//\n// Note this may handle and write control frames into the writer part of a\n// given io.ReadWriter.\nfunc ReadClientData(rw io.ReadWriter) ([]byte, ws.OpCode, error) {\n\treturn ReadData(rw, ws.StateServerSide)\n}\n\n// ReadClientText reads next text message from rw, considering that caller\n// represents server side. It is a shortcut for ReadData(rw, ws.StateServerSide).\n// It discards received binary messages.\n//\n// Note this may handle and write control frames into the writer part of a\n// given io.ReadWriter.\nfunc ReadClientText(rw io.ReadWriter) ([]byte, error) {\n\tp, _, err := readData(rw, ws.StateServerSide, ws.OpText)\n\treturn p, err\n}\n\n// ReadClientBinary reads next binary message from rw, considering that caller\n// represents server side. It is a shortcut for ReadData(rw, ws.StateServerSide).\n// It discards received text messages.\n//\n// Note this may handle and write control frames into the writer part of a given\n// io.ReadWriter.\nfunc ReadClientBinary(rw io.ReadWriter) ([]byte, error) {\n\tp, _, err := readData(rw, ws.StateServerSide, ws.OpBinary)\n\treturn p, err\n}\n\n// ReadServerData reads next data message from rw, considering that caller\n// represents client side. It is a shortcut for ReadData(rw, ws.StateClientSide).\n//\n// Note this may handle and write control frames into the writer part of a\n// given io.ReadWriter.\nfunc ReadServerData(rw io.ReadWriter) ([]byte, ws.OpCode, error) {\n\treturn ReadData(rw, ws.StateClientSide)\n}\n\n// ReadServerText reads next text message from rw, considering that caller\n// represents client side. It is a shortcut for ReadData(rw, ws.StateClientSide).\n// It discards received binary messages.\n//\n// Note this may handle and write control frames into the writer part of a given\n// io.ReadWriter.\nfunc ReadServerText(rw io.ReadWriter) ([]byte, error) {\n\tp, _, err := readData(rw, ws.StateClientSide, ws.OpText)\n\treturn p, err\n}\n\n// ReadServerBinary reads next binary message from rw, considering that caller\n// represents client side. It is a shortcut for ReadData(rw, ws.StateClientSide).\n// It discards received text messages.\n//\n// Note this may handle and write control frames into the writer part of a\n// given io.ReadWriter.\nfunc ReadServerBinary(rw io.ReadWriter) ([]byte, error) {\n\tp, _, err := readData(rw, ws.StateClientSide, ws.OpBinary)\n\treturn p, err\n}\n\n// WriteMessage is a helper function that writes message to the w. It\n// constructs single frame with given operation code and payload.\n// It uses given state to prepare side-dependent things, like cipher\n// payload bytes from client to server. It will not mutate p bytes if\n// cipher must be made.\n//\n// If you want to write message in fragmented frames, use Writer instead.\nfunc WriteMessage(w io.Writer, s ws.State, op ws.OpCode, p []byte) error {\n\treturn writeFrame(w, s, op, true, p)\n}\n\n// WriteServerMessage writes message to w, considering that caller\n// represents server side.\nfunc WriteServerMessage(w io.Writer, op ws.OpCode, p []byte) error {\n\treturn WriteMessage(w, ws.StateServerSide, op, p)\n}\n\n// WriteServerText is the same as WriteServerMessage with\n// ws.OpText.\nfunc WriteServerText(w io.Writer, p []byte) error {\n\treturn WriteServerMessage(w, ws.OpText, p)\n}\n\n// WriteServerBinary is the same as WriteServerMessage with\n// ws.OpBinary.\nfunc WriteServerBinary(w io.Writer, p []byte) error {\n\treturn WriteServerMessage(w, ws.OpBinary, p)\n}\n\n// WriteClientMessage writes message to w, considering that caller\n// represents client side.\nfunc WriteClientMessage(w io.Writer, op ws.OpCode, p []byte) error {\n\treturn WriteMessage(w, ws.StateClientSide, op, p)\n}\n\n// WriteClientText is the same as WriteClientMessage with\n// ws.OpText.\nfunc WriteClientText(w io.Writer, p []byte) error {\n\treturn WriteClientMessage(w, ws.OpText, p)\n}\n\n// WriteClientBinary is the same as WriteClientMessage with\n// ws.OpBinary.\nfunc WriteClientBinary(w io.Writer, p []byte) error {\n\treturn WriteClientMessage(w, ws.OpBinary, p)\n}\n\n// HandleClientControlMessage handles control frame from conn and writes\n// response when needed.\n//\n// It considers that caller represents server side.\nfunc HandleClientControlMessage(conn io.Writer, msg Message) error {\n\treturn HandleControlMessage(conn, ws.StateServerSide, msg)\n}\n\n// HandleServerControlMessage handles control frame from conn and writes\n// response when needed.\n//\n// It considers that caller represents client side.\nfunc HandleServerControlMessage(conn io.Writer, msg Message) error {\n\treturn HandleControlMessage(conn, ws.StateClientSide, msg)\n}\n\n// HandleControlMessage handles message which was read by ReadMessage()\n// functions.\n//\n// That is, it is expected, that payload is already unmasked and frame header\n// were checked by ws.CheckHeader() call.\nfunc HandleControlMessage(conn io.Writer, state ws.State, msg Message) error {\n\treturn (ControlHandler{\n\t\tDisableSrcCiphering: true,\n\t\tSrc:                 bytes.NewReader(msg.Payload),\n\t\tDst:                 conn,\n\t\tState:               state,\n\t}).Handle(ws.Header{\n\t\tLength: int64(len(msg.Payload)),\n\t\tOpCode: msg.OpCode,\n\t\tFin:    true,\n\t\tMasked: state.ServerSide(),\n\t})\n}\n\n// ControlFrameHandler returns FrameHandlerFunc for handling control frames.\n// For more info see ControlHandler docs.\nfunc ControlFrameHandler(w io.Writer, state ws.State) FrameHandlerFunc {\n\treturn func(h ws.Header, r io.Reader) error {\n\t\treturn (ControlHandler{\n\t\t\tDisableSrcCiphering: true,\n\t\t\tSrc:                 r,\n\t\t\tDst:                 w,\n\t\t\tState:               state,\n\t\t}).Handle(h)\n\t}\n}\n\nfunc readData(rw io.ReadWriter, s ws.State, want ws.OpCode) ([]byte, ws.OpCode, error) {\n\tcontrolHandler := ControlFrameHandler(rw, s)\n\trd := Reader{\n\t\tSource:          rw,\n\t\tState:           s,\n\t\tCheckUTF8:       true,\n\t\tSkipHeaderCheck: false,\n\t\tOnIntermediate:  controlHandler,\n\t}\n\tfor {\n\t\thdr, err := rd.NextFrame()\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\tif hdr.OpCode.IsControl() {\n\t\t\tif err := controlHandler(hdr, &rd); err != nil {\n\t\t\t\treturn nil, 0, err\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif hdr.OpCode&want == 0 {\n\t\t\tif err := rd.Discard(); err != nil {\n\t\t\t\treturn nil, 0, err\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tbts, err := ioutil.ReadAll(&rd)\n\n\t\treturn bts, hdr.OpCode, err\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/wsutil/reader.go",
    "content": "package wsutil\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"io/ioutil\"\n\n\t\"github.com/gobwas/ws\"\n)\n\n// ErrNoFrameAdvance means that Reader's Read() method was called without\n// preceding NextFrame() call.\nvar ErrNoFrameAdvance = errors.New(\"no frame advance\")\n\n// ErrFrameTooLarge indicates that a message of length higher than\n// MaxFrameSize was being read.\nvar ErrFrameTooLarge = errors.New(\"frame too large\")\n\n// FrameHandlerFunc handles parsed frame header and its body represented by\n// io.Reader.\n//\n// Note that reader represents already unmasked body.\ntype FrameHandlerFunc func(ws.Header, io.Reader) error\n\n// Reader is a wrapper around source io.Reader which represents WebSocket\n// connection. It contains options for reading messages from source.\n//\n// Reader implements io.Reader, which Read() method reads payload of incoming\n// WebSocket frames. It also takes care on fragmented frames and possibly\n// intermediate control frames between them.\n//\n// Note that Reader's methods are not goroutine safe.\ntype Reader struct {\n\tSource io.Reader\n\tState  ws.State\n\n\t// SkipHeaderCheck disables checking header bits to be RFC6455 compliant.\n\tSkipHeaderCheck bool\n\n\t// CheckUTF8 enables UTF-8 checks for text frames payload. If incoming\n\t// bytes are not valid UTF-8 sequence, ErrInvalidUTF8 returned.\n\tCheckUTF8 bool\n\n\t// Extensions is a list of negotiated extensions for reader Source.\n\t// It is used to meet the specs and clear appropriate bits in fragment\n\t// header RSV segment.\n\tExtensions []RecvExtension\n\n\t// MaxFrameSize controls the maximum frame size in bytes\n\t// that can be read. A message exceeding that size will return\n\t// a ErrFrameTooLarge to the application.\n\t//\n\t// Not setting this field means there is no limit.\n\tMaxFrameSize int64\n\n\tOnContinuation FrameHandlerFunc\n\tOnIntermediate FrameHandlerFunc\n\n\topCode ws.OpCode        // Used to store message op code on fragmentation.\n\tframe  io.Reader        // Used to as frame reader.\n\traw    io.LimitedReader // Used to discard frames without cipher.\n\tutf8   UTF8Reader       // Used to check UTF8 sequences if CheckUTF8 is true.\n}\n\n// NewReader creates new frame reader that reads from r keeping given state to\n// make some protocol validity checks when it needed.\nfunc NewReader(r io.Reader, s ws.State) *Reader {\n\treturn &Reader{\n\t\tSource: r,\n\t\tState:  s,\n\t}\n}\n\n// NewClientSideReader is a helper function that calls NewReader with r and\n// ws.StateClientSide.\nfunc NewClientSideReader(r io.Reader) *Reader {\n\treturn NewReader(r, ws.StateClientSide)\n}\n\n// NewServerSideReader is a helper function that calls NewReader with r and\n// ws.StateServerSide.\nfunc NewServerSideReader(r io.Reader) *Reader {\n\treturn NewReader(r, ws.StateServerSide)\n}\n\n// Read implements io.Reader. It reads the next message payload into p.\n// It takes care on fragmented messages.\n//\n// The error is io.EOF only if all of message bytes were read.\n// If an io.EOF happens during reading some but not all the message bytes\n// Read() returns io.ErrUnexpectedEOF.\n//\n// The error is ErrNoFrameAdvance if no NextFrame() call was made before\n// reading next message bytes.\nfunc (r *Reader) Read(p []byte) (n int, err error) {\n\tif r.frame == nil {\n\t\tif !r.fragmented() {\n\t\t\t// Every new Read() must be preceded by NextFrame() call.\n\t\t\treturn 0, ErrNoFrameAdvance\n\t\t}\n\t\t// Read next continuation or intermediate control frame.\n\t\t_, err := r.NextFrame()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tif r.frame == nil {\n\t\t\t// We handled intermediate control and now got nothing to read.\n\t\t\treturn 0, nil\n\t\t}\n\t}\n\n\tn, err = r.frame.Read(p)\n\tif err != nil && err != io.EOF {\n\t\treturn n, err\n\t}\n\tif err == nil && r.raw.N != 0 {\n\t\treturn n, nil\n\t}\n\n\t// EOF condition (either err is io.EOF or r.raw.N is zero).\n\tswitch {\n\tcase r.raw.N != 0:\n\t\terr = io.ErrUnexpectedEOF\n\n\tcase r.fragmented():\n\t\terr = nil\n\t\tr.resetFragment()\n\n\tcase r.CheckUTF8 && !r.utf8.Valid():\n\t\t// NOTE: check utf8 only when full message received, since partial\n\t\t// reads may be invalid.\n\t\tn = r.utf8.Accepted()\n\t\terr = ErrInvalidUTF8\n\n\tdefault:\n\t\tr.reset()\n\t\terr = io.EOF\n\t}\n\n\treturn n, err\n}\n\n// Discard discards current message unread bytes.\n// It discards all frames of fragmented message.\nfunc (r *Reader) Discard() (err error) {\n\tfor {\n\t\t_, err = io.Copy(ioutil.Discard, &r.raw)\n\t\tif err != nil {\n\t\t\tbreak\n\t\t}\n\t\tif !r.fragmented() {\n\t\t\tbreak\n\t\t}\n\t\tif _, err = r.NextFrame(); err != nil {\n\t\t\tbreak\n\t\t}\n\t}\n\tr.reset()\n\treturn err\n}\n\n// NextFrame prepares r to read next message. It returns received frame header\n// and non-nil error on failure.\n//\n// Note that next NextFrame() call must be done after receiving or discarding\n// all current message bytes.\nfunc (r *Reader) NextFrame() (hdr ws.Header, err error) {\n\thdr, err = ws.ReadHeader(r.Source)\n\tif err == io.EOF && r.fragmented() {\n\t\t// If we are in fragmented state EOF means that is was totally\n\t\t// unexpected.\n\t\t//\n\t\t// NOTE: This is necessary to prevent callers such that\n\t\t// ioutil.ReadAll to receive some amount of bytes without an error.\n\t\t// ReadAll() ignores an io.EOF error, thus caller may think that\n\t\t// whole message fetched, but actually only part of it.\n\t\terr = io.ErrUnexpectedEOF\n\t}\n\tif err == nil && !r.SkipHeaderCheck {\n\t\terr = ws.CheckHeader(hdr, r.State)\n\t}\n\tif err != nil {\n\t\treturn hdr, err\n\t}\n\n\tif n := r.MaxFrameSize; n > 0 && hdr.Length > n {\n\t\treturn hdr, ErrFrameTooLarge\n\t}\n\n\t// Save raw reader to use it on discarding frame without ciphering and\n\t// other streaming checks.\n\tr.raw = io.LimitedReader{\n\t\tR: r.Source,\n\t\tN: hdr.Length,\n\t}\n\n\tframe := io.Reader(&r.raw)\n\tif hdr.Masked {\n\t\tframe = NewCipherReader(frame, hdr.Mask)\n\t}\n\n\tfor _, x := range r.Extensions {\n\t\thdr, err = x.UnsetBits(hdr)\n\t\tif err != nil {\n\t\t\treturn hdr, err\n\t\t}\n\t}\n\n\tif r.fragmented() {\n\t\tif hdr.OpCode.IsControl() {\n\t\t\tif cb := r.OnIntermediate; cb != nil {\n\t\t\t\terr = cb(hdr, frame)\n\t\t\t}\n\t\t\tif err == nil {\n\t\t\t\t// Ensure that src is empty.\n\t\t\t\t_, err = io.Copy(ioutil.Discard, &r.raw)\n\t\t\t}\n\t\t\treturn hdr, err\n\t\t}\n\t} else {\n\t\tr.opCode = hdr.OpCode\n\t}\n\tif r.CheckUTF8 && (hdr.OpCode == ws.OpText || (r.fragmented() && r.opCode == ws.OpText)) {\n\t\tr.utf8.Source = frame\n\t\tframe = &r.utf8\n\t}\n\n\t// Save reader with ciphering and other streaming checks.\n\tr.frame = frame\n\n\tif hdr.OpCode == ws.OpContinuation {\n\t\tif cb := r.OnContinuation; cb != nil {\n\t\t\terr = cb(hdr, frame)\n\t\t}\n\t}\n\n\tif hdr.Fin {\n\t\tr.State = r.State.Clear(ws.StateFragmented)\n\t} else {\n\t\tr.State = r.State.Set(ws.StateFragmented)\n\t}\n\n\treturn hdr, err\n}\n\nfunc (r *Reader) fragmented() bool {\n\treturn r.State.Fragmented()\n}\n\nfunc (r *Reader) resetFragment() {\n\tr.raw = io.LimitedReader{}\n\tr.frame = nil\n\t// Reset source of the UTF8Reader, but not the state.\n\tr.utf8.Source = nil\n}\n\nfunc (r *Reader) reset() {\n\tr.raw = io.LimitedReader{}\n\tr.frame = nil\n\tr.utf8 = UTF8Reader{}\n\tr.opCode = 0\n}\n\n// NextReader prepares next message read from r. It returns header that\n// describes the message and io.Reader to read message's payload. It returns\n// non-nil error when it is not possible to read message's initial frame.\n//\n// Note that next NextReader() on the same r should be done after reading all\n// bytes from previously returned io.Reader. For more performant way to discard\n// message use Reader and its Discard() method.\n//\n// Note that it will not handle any \"intermediate\" frames, that possibly could\n// be received between text/binary continuation frames. That is, if peer sent\n// text/binary frame with fin flag \"false\", then it could send ping frame, and\n// eventually remaining part of text/binary frame with fin \"true\" – with\n// NextReader() the ping frame will be dropped without any notice. To handle\n// this rare, but possible situation (and if you do not know exactly which\n// frames peer could send), you could use Reader with OnIntermediate field set.\nfunc NextReader(r io.Reader, s ws.State) (ws.Header, io.Reader, error) {\n\trd := &Reader{\n\t\tSource: r,\n\t\tState:  s,\n\t}\n\theader, err := rd.NextFrame()\n\tif err != nil {\n\t\treturn header, nil, err\n\t}\n\treturn header, rd, nil\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/wsutil/upgrader.go",
    "content": "package wsutil\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\n\t\"github.com/gobwas/ws\"\n)\n\n// DebugUpgrader is a wrapper around ws.Upgrader. It tracks I/O of a\n// WebSocket handshake.\n//\n// Note that it must not be used in production applications that requires\n// Upgrade() to be efficient.\ntype DebugUpgrader struct {\n\t// Upgrader contains upgrade to WebSocket options.\n\tUpgrader ws.Upgrader\n\n\t// OnRequest and OnResponse are the callbacks that will be called with the\n\t// HTTP request and response respectively.\n\tOnRequest, OnResponse func([]byte)\n}\n\n// Upgrade calls Upgrade() on underlying ws.Upgrader and tracks I/O on conn.\nfunc (d *DebugUpgrader) Upgrade(conn io.ReadWriter) (hs ws.Handshake, err error) {\n\tvar (\n\t\t// Take the Reader and Writer parts from conn to be probably replaced\n\t\t// below.\n\t\tr io.Reader = conn\n\t\tw io.Writer = conn\n\t)\n\tif onRequest := d.OnRequest; onRequest != nil {\n\t\tvar buf bytes.Buffer\n\t\t// First, we must read the entire request.\n\t\treq, err := http.ReadRequest(bufio.NewReader(\n\t\t\tio.TeeReader(conn, &buf),\n\t\t))\n\t\tif err == nil {\n\t\t\t// Fulfill the buffer with the response body.\n\t\t\tio.Copy(ioutil.Discard, req.Body)\n\t\t\treq.Body.Close()\n\t\t}\n\t\tonRequest(buf.Bytes())\n\n\t\tr = io.MultiReader(\n\t\t\t&buf, conn,\n\t\t)\n\t}\n\n\tif onResponse := d.OnResponse; onResponse != nil {\n\t\tvar buf bytes.Buffer\n\t\t// Intercept the response stream written by the Upgrade().\n\t\tw = io.MultiWriter(\n\t\t\tconn, &buf,\n\t\t)\n\t\tdefer func() {\n\t\t\tonResponse(buf.Bytes())\n\t\t}()\n\t}\n\n\treturn d.Upgrader.Upgrade(struct {\n\t\tio.Reader\n\t\tio.Writer\n\t}{r, w})\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/wsutil/utf8.go",
    "content": "package wsutil\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n// ErrInvalidUTF8 is returned by UTF8 reader on invalid utf8 sequence.\nvar ErrInvalidUTF8 = fmt.Errorf(\"invalid utf8\")\n\n// UTF8Reader implements io.Reader that calculates utf8 validity state after\n// every read byte from Source.\n//\n// Note that in some cases client must call r.Valid() after all bytes are read\n// to ensure that all of them are valid utf8 sequences. That is, some io helper\n// functions such io.ReadAtLeast or io.ReadFull could discard the error\n// information returned by the reader when they receive all of requested bytes.\n// For example, the last read sequence is invalid and UTF8Reader returns number\n// of bytes read and an error. But helper function decides to discard received\n// error due to all requested bytes are completely read from the source.\n//\n// Another possible case is when some valid sequence become split by the read\n// bound. Then UTF8Reader can not make decision about validity of the last\n// sequence cause it is not fully read yet. And if the read stops, Valid() will\n// return false, even if Read() by itself dit not.\ntype UTF8Reader struct {\n\tSource io.Reader\n\n\taccepted int\n\n\tstate uint32\n\tcodep uint32\n}\n\n// NewUTF8Reader creates utf8 reader that reads from r.\nfunc NewUTF8Reader(r io.Reader) *UTF8Reader {\n\treturn &UTF8Reader{\n\t\tSource: r,\n\t}\n}\n\n// Reset resets utf8 reader to read from r.\nfunc (u *UTF8Reader) Reset(r io.Reader) {\n\tu.Source = r\n\tu.state = 0\n\tu.codep = 0\n}\n\n// Read implements io.Reader.\nfunc (u *UTF8Reader) Read(p []byte) (n int, err error) {\n\tn, err = u.Source.Read(p)\n\n\taccepted := 0\n\ts, c := u.state, u.codep\n\tfor i := 0; i < n; i++ {\n\t\tc, s = decode(s, c, p[i])\n\t\tif s == utf8Reject {\n\t\t\tu.state = s\n\t\t\treturn accepted, ErrInvalidUTF8\n\t\t}\n\t\tif s == utf8Accept {\n\t\t\taccepted = i + 1\n\t\t}\n\t}\n\tu.state, u.codep = s, c\n\tu.accepted = accepted\n\n\treturn n, err\n}\n\n// Valid checks current reader state. It returns true if all read bytes are\n// valid UTF-8 sequences, and false if not.\nfunc (u *UTF8Reader) Valid() bool {\n\treturn u.state == utf8Accept\n}\n\n// Accepted returns number of valid bytes in last Read().\nfunc (u *UTF8Reader) Accepted() int {\n\treturn u.accepted\n}\n\n// Below is port of UTF-8 decoder from http://bjoern.hoehrmann.de/utf-8/decoder/dfa/\n//\n// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal in the Software without restriction, including without limitation the\n// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n// sell copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n// IN THE SOFTWARE.\n\nconst (\n\tutf8Accept = 0\n\tutf8Reject = 12\n)\n\nvar utf8d = [...]byte{\n\t// The first part of the table maps bytes to character classes that\n\t// to reduce the size of the transition table and create bitmasks.\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,\n\t7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n\t8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n\t10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 11, 6, 6, 6, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,\n\n\t// The second part is a transition table that maps a combination\n\t// of a state of the automaton and a character class to a state.\n\t0, 12, 24, 36, 60, 96, 84, 12, 12, 12, 48, 72, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t12, 0, 12, 12, 12, 12, 12, 0, 12, 0, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24, 12, 24, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12,\n\t12, 36, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n}\n\nfunc decode(state, codep uint32, b byte) (uint32, uint32) {\n\tt := uint32(utf8d[b])\n\n\tif state != utf8Accept {\n\t\tcodep = (uint32(b) & 0x3f) | (codep << 6)\n\t} else {\n\t\tcodep = (0xff >> t) & uint32(b)\n\t}\n\n\treturn codep, uint32(utf8d[256+state+t])\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/wsutil/writer.go",
    "content": "package wsutil\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/gobwas/pool\"\n\t\"github.com/gobwas/pool/pbytes\"\n\t\"github.com/gobwas/ws\"\n)\n\n// DefaultWriteBuffer contains size of Writer's default buffer. It used by\n// Writer constructor functions.\nvar DefaultWriteBuffer = 4096\n\nvar (\n\t// ErrNotEmpty is returned by Writer.WriteThrough() to indicate that buffer is\n\t// not empty and write through could not be done. That is, caller should call\n\t// Writer.FlushFragment() to make buffer empty.\n\tErrNotEmpty = fmt.Errorf(\"writer not empty\")\n\n\t// ErrControlOverflow is returned by ControlWriter.Write() to indicate that\n\t// no more data could be written to the underlying io.Writer because\n\t// MaxControlFramePayloadSize limit is reached.\n\tErrControlOverflow = fmt.Errorf(\"control frame payload overflow\")\n)\n\n// Constants which are represent frame length ranges.\nconst (\n\tlen7  = int64(125) // 126 and 127 are reserved values\n\tlen16 = int64(^uint16(0))\n\tlen64 = int64((^uint64(0)) >> 1)\n)\n\n// ControlWriter is a wrapper around Writer that contains some guards for\n// buffered writes of control frames.\ntype ControlWriter struct {\n\tw     *Writer\n\tlimit int\n\tn     int\n}\n\n// NewControlWriter contains ControlWriter with Writer inside whose buffer size\n// is at most ws.MaxControlFramePayloadSize + ws.MaxHeaderSize.\nfunc NewControlWriter(dest io.Writer, state ws.State, op ws.OpCode) *ControlWriter {\n\treturn &ControlWriter{\n\t\tw:     NewWriterSize(dest, state, op, ws.MaxControlFramePayloadSize),\n\t\tlimit: ws.MaxControlFramePayloadSize,\n\t}\n}\n\n// NewControlWriterBuffer returns a new ControlWriter with buf as a buffer.\n//\n// Note that it reserves x bytes of buf for header data, where x could be\n// ws.MinHeaderSize or ws.MinHeaderSize+4 (depending on state). At most\n// (ws.MaxControlFramePayloadSize + x) bytes of buf will be used.\n//\n// It panics if len(buf) <= ws.MinHeaderSize + x.\nfunc NewControlWriterBuffer(dest io.Writer, state ws.State, op ws.OpCode, buf []byte) *ControlWriter {\n\tmax := ws.MaxControlFramePayloadSize + headerSize(state, ws.MaxControlFramePayloadSize)\n\tif len(buf) > max {\n\t\tbuf = buf[:max]\n\t}\n\n\tw := NewWriterBuffer(dest, state, op, buf)\n\n\treturn &ControlWriter{\n\t\tw:     w,\n\t\tlimit: len(w.buf),\n\t}\n}\n\n// Write implements io.Writer. It writes to the underlying Writer until it\n// returns error or until ControlWriter write limit will be exceeded.\nfunc (c *ControlWriter) Write(p []byte) (n int, err error) {\n\tif c.n+len(p) > c.limit {\n\t\treturn 0, ErrControlOverflow\n\t}\n\treturn c.w.Write(p)\n}\n\n// Flush flushes all buffered data to the underlying io.Writer.\nfunc (c *ControlWriter) Flush() error {\n\treturn c.w.Flush()\n}\n\nvar writers = pool.New(128, 65536)\n\n// GetWriter tries to reuse Writer getting it from the pool.\n//\n// This function is intended for memory consumption optimizations, because\n// NewWriter*() functions make allocations for inner buffer.\n//\n// Note the it ceils n to the power of two.\n//\n// If you have your own bytes buffer pool you could use NewWriterBuffer to use\n// pooled bytes in writer.\nfunc GetWriter(dest io.Writer, state ws.State, op ws.OpCode, n int) *Writer {\n\tx, m := writers.Get(n)\n\tif x != nil {\n\t\tw := x.(*Writer)\n\t\tw.Reset(dest, state, op)\n\t\treturn w\n\t}\n\t// NOTE: we use m instead of n, because m is an attempt to reuse w of such\n\t// size in the future.\n\treturn NewWriterBufferSize(dest, state, op, m)\n}\n\n// PutWriter puts w for future reuse by GetWriter().\nfunc PutWriter(w *Writer) {\n\tw.Reset(nil, 0, 0)\n\twriters.Put(w, w.Size())\n}\n\n// Writer contains logic of buffering output data into a WebSocket fragments.\n// It is much the same as bufio.Writer, except the thing that it works with\n// WebSocket frames, not the raw data.\n//\n// Writer writes frames with specified OpCode.\n// It uses ws.State to decide whether the output frames must be masked.\n//\n// Note that it does not check control frame size or other RFC rules.\n// That is, it must be used with special care to write control frames without\n// violation of RFC. You could use ControlWriter that wraps Writer and contains\n// some guards for writing control frames.\n//\n// If an error occurs writing to a Writer, no more data will be accepted and\n// all subsequent writes will return the error.\n//\n// After all data has been written, the client should call the Flush() method\n// to guarantee all data has been forwarded to the underlying io.Writer.\ntype Writer struct {\n\t// dest specifies a destination of buffer flushes.\n\tdest io.Writer\n\n\t// op specifies the WebSocket operation code used in flushed frames.\n\top ws.OpCode\n\n\t// state specifies the state of the Writer.\n\tstate ws.State\n\n\t// extensions is a list of negotiated extensions for writer Dest.\n\t// It is used to meet the specs and set appropriate bits in fragment\n\t// header RSV segment.\n\textensions []SendExtension\n\n\t// noFlush reports whether buffer must grow instead of being flushed.\n\tnoFlush bool\n\n\t// Raw representation of the buffer, including reserved header bytes.\n\traw []byte\n\n\t// Writeable part of buffer, without reserved header bytes.\n\t// Resetting this to nil will not result in reallocation if raw is not nil.\n\t// And vice versa: if buf is not nil, then Writer is assumed as ready and\n\t// initialized.\n\tbuf []byte\n\n\t// Buffered bytes counter.\n\tn int\n\n\tdirty bool\n\tfseq  int\n\terr   error\n}\n\n// NewWriter returns a new Writer whose buffer has the DefaultWriteBuffer size.\nfunc NewWriter(dest io.Writer, state ws.State, op ws.OpCode) *Writer {\n\treturn NewWriterBufferSize(dest, state, op, 0)\n}\n\n// NewWriterSize returns a new Writer whose buffer size is at most n + ws.MaxHeaderSize.\n// That is, output frames payload length could be up to n, except the case when\n// Write() is called on empty Writer with len(p) > n.\n//\n// If n <= 0 then the default buffer size is used as Writer's buffer size.\nfunc NewWriterSize(dest io.Writer, state ws.State, op ws.OpCode, n int) *Writer {\n\tif n > 0 {\n\t\tn += headerSize(state, n)\n\t}\n\treturn NewWriterBufferSize(dest, state, op, n)\n}\n\n// NewWriterBufferSize returns a new Writer whose buffer size is equal to n.\n// If n <= ws.MinHeaderSize then the default buffer size is used.\n//\n// Note that Writer will reserve x bytes for header data, where x is in range\n// [ws.MinHeaderSize,ws.MaxHeaderSize]. That is, frames flushed by Writer\n// will not have payload length equal to n, except the case when Write() is\n// called on empty Writer with len(p) > n.\nfunc NewWriterBufferSize(dest io.Writer, state ws.State, op ws.OpCode, n int) *Writer {\n\tif n <= ws.MinHeaderSize {\n\t\tn = DefaultWriteBuffer\n\t}\n\treturn NewWriterBuffer(dest, state, op, make([]byte, n))\n}\n\n// NewWriterBuffer returns a new Writer with buf as a buffer.\n//\n// Note that it reserves x bytes of buf for header data, where x is in range\n// [ws.MinHeaderSize,ws.MaxHeaderSize] (depending on state and buf size).\n//\n// You could use ws.HeaderSize() to calculate number of bytes needed to store\n// header data.\n//\n// It panics if len(buf) is too small to fit header and payload data.\nfunc NewWriterBuffer(dest io.Writer, state ws.State, op ws.OpCode, buf []byte) *Writer {\n\tw := &Writer{\n\t\tdest:  dest,\n\t\tstate: state,\n\t\top:    op,\n\t\traw:   buf,\n\t}\n\tw.initBuf()\n\treturn w\n}\n\nfunc (w *Writer) initBuf() {\n\toffset := reserve(w.state, len(w.raw))\n\tif len(w.raw) <= offset {\n\t\tpanic(\"wsutil: writer buffer is too small\")\n\t}\n\tw.buf = w.raw[offset:]\n}\n\n// Reset resets Writer as it was created by New() methods.\n// Note that Reset does reset extensions and other options was set after\n// Writer initialization.\nfunc (w *Writer) Reset(dest io.Writer, state ws.State, op ws.OpCode) {\n\tw.dest = dest\n\tw.state = state\n\tw.op = op\n\n\tw.initBuf()\n\n\tw.n = 0\n\tw.dirty = false\n\tw.fseq = 0\n\tw.extensions = w.extensions[:0]\n\tw.noFlush = false\n}\n\n// ResetOp is an quick version of Reset().\n// ResetOp does reset unwritten fragments and does not reset results of\n// SetExtensions() or DisableFlush() methods.\nfunc (w *Writer) ResetOp(op ws.OpCode) {\n\tw.op = op\n\tw.n = 0\n\tw.dirty = false\n\tw.fseq = 0\n}\n\n// SetExtensions adds xs as extensions to be used during writes.\nfunc (w *Writer) SetExtensions(xs ...SendExtension) {\n\tw.extensions = xs\n}\n\n// DisableFlush denies Writer to write fragments.\nfunc (w *Writer) DisableFlush() {\n\tw.noFlush = true\n}\n\n// Size returns the size of the underlying buffer in bytes (not including\n// WebSocket header bytes).\nfunc (w *Writer) Size() int {\n\treturn len(w.buf)\n}\n\n// Available returns how many bytes are unused in the buffer.\nfunc (w *Writer) Available() int {\n\treturn len(w.buf) - w.n\n}\n\n// Buffered returns the number of bytes that have been written into the current\n// buffer.\nfunc (w *Writer) Buffered() int {\n\treturn w.n\n}\n\n// Write implements io.Writer.\n//\n// Note that even if the Writer was created to have N-sized buffer, Write()\n// with payload of N bytes will not fit into that buffer. Writer reserves some\n// space to fit WebSocket header data.\nfunc (w *Writer) Write(p []byte) (n int, err error) {\n\t// Even empty p may make a sense.\n\tw.dirty = true\n\n\tvar nn int\n\tfor len(p) > w.Available() && w.err == nil {\n\t\tif w.noFlush {\n\t\t\tw.Grow(len(p))\n\t\t\tcontinue\n\t\t}\n\t\tif w.Buffered() == 0 {\n\t\t\t// Large write, empty buffer. Write directly from p to avoid copy.\n\t\t\t// Trade off here is that we make additional Write() to underlying\n\t\t\t// io.Writer when writing frame header.\n\t\t\t//\n\t\t\t// On large buffers additional write is better than copying.\n\t\t\tnn, _ = w.WriteThrough(p)\n\t\t} else {\n\t\t\tnn = copy(w.buf[w.n:], p)\n\t\t\tw.n += nn\n\t\t\tw.FlushFragment()\n\t\t}\n\t\tn += nn\n\t\tp = p[nn:]\n\t}\n\tif w.err != nil {\n\t\treturn n, w.err\n\t}\n\tnn = copy(w.buf[w.n:], p)\n\tw.n += nn\n\tn += nn\n\n\t// Even if w.Available() == 0 we will not flush buffer preventively because\n\t// this could bring unwanted fragmentation. That is, user could create\n\t// buffer with size that fits exactly all further Write() call, and then\n\t// call Flush(), excepting that single and not fragmented frame will be\n\t// sent. With preemptive flush this case will produce two frames – last one\n\t// will be empty and just to set fin = true.\n\n\treturn n, w.err\n}\n\nfunc ceilPowerOfTwo(n int) int {\n\tn |= n >> 1\n\tn |= n >> 2\n\tn |= n >> 4\n\tn |= n >> 8\n\tn |= n >> 16\n\tn |= n >> 32\n\tn++\n\treturn n\n}\n\n// Grow grows Writer's internal buffer capacity to guarantee space for another\n// n bytes of _payload_ -- that is, frame header is not included in n.\nfunc (w *Writer) Grow(n int) {\n\t// NOTE: we must respect the possibility of header reserved bytes grow.\n\tvar (\n\t\tsize       = len(w.raw)\n\t\tprevOffset = len(w.raw) - len(w.buf)\n\t\tnextOffset = len(w.raw) - len(w.buf)\n\t\tbuffered   = w.Buffered()\n\t)\n\tfor cap := size - nextOffset - buffered; cap < n; {\n\t\t// This loop runs twice only at split cases, when reservation of raw\n\t\t// buffer space for the header shrinks capacity of new buffer such that\n\t\t// it still less than n.\n\t\t//\n\t\t// Loop is safe here because:\n\t\t// - (offset + buffered + n) is greater than size, otherwise (cap < n)\n\t\t//   would be false:\n\t\t//   size  = offset + buffered + freeSpace (cap)\n\t\t//   size' = offset + buffered + wantSpace (n)\n\t\t//   Since (cap < n) is true in the loop condition, size' is guaranteed\n\t\t//   to be greater => no infinite loop.\n\t\tsize = ceilPowerOfTwo(nextOffset + buffered + n)\n\t\tnextOffset = reserve(w.state, size)\n\t\tcap = size - nextOffset - buffered\n\t}\n\tif size < len(w.raw) {\n\t\tpanic(\"wsutil: buffer grow leads to its reduce\")\n\t}\n\tif size == len(w.raw) {\n\t\treturn\n\t}\n\tp := make([]byte, size)\n\tcopy(p[nextOffset-prevOffset:], w.raw[:prevOffset+buffered])\n\tw.raw = p\n\tw.buf = w.raw[nextOffset:]\n}\n\n// WriteThrough writes data bypassing the buffer.\n// Note that Writer's buffer must be empty before calling WriteThrough().\nfunc (w *Writer) WriteThrough(p []byte) (n int, err error) {\n\tif w.err != nil {\n\t\treturn 0, w.err\n\t}\n\tif w.Buffered() != 0 {\n\t\treturn 0, ErrNotEmpty\n\t}\n\n\tvar frame ws.Frame\n\tframe.Header = ws.Header{\n\t\tOpCode: w.opCode(),\n\t\tFin:    false,\n\t\tLength: int64(len(p)),\n\t}\n\tfor _, x := range w.extensions {\n\t\tframe.Header, err = x.SetBits(frame.Header)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t}\n\tif w.state.ClientSide() {\n\t\t// Should copy bytes to prevent corruption of caller data.\n\t\tpayload := pbytes.GetLen(len(p))\n\t\tdefer pbytes.Put(payload)\n\t\tcopy(payload, p)\n\n\t\tframe.Payload = payload\n\t\tframe = ws.MaskFrameInPlace(frame)\n\t} else {\n\t\tframe.Payload = p\n\t}\n\n\tw.err = ws.WriteFrame(w.dest, frame)\n\tif w.err == nil {\n\t\tn = len(p)\n\t}\n\n\tw.dirty = true\n\tw.fseq++\n\n\treturn n, w.err\n}\n\n// ReadFrom implements io.ReaderFrom.\nfunc (w *Writer) ReadFrom(src io.Reader) (n int64, err error) {\n\tvar nn int\n\tfor err == nil {\n\t\tif w.Available() == 0 {\n\t\t\tif w.noFlush {\n\t\t\t\tw.Grow(w.Buffered()) // Twice bigger.\n\t\t\t} else {\n\t\t\t\terr = w.FlushFragment()\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// We copy the behavior of bufio.Writer here.\n\t\t// Also, from the docs on io.ReaderFrom:\n\t\t//   ReadFrom reads data from r until EOF or error.\n\t\t//\n\t\t// See https://codereview.appspot.com/76400048/#ps1\n\t\tconst maxEmptyReads = 100\n\t\tvar nr int\n\t\tfor nr < maxEmptyReads {\n\t\t\tnn, err = src.Read(w.buf[w.n:])\n\t\t\tif nn != 0 || err != nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tnr++\n\t\t}\n\t\tif nr == maxEmptyReads {\n\t\t\treturn n, io.ErrNoProgress\n\t\t}\n\n\t\tw.n += nn\n\t\tn += int64(nn)\n\t}\n\tif err == io.EOF {\n\t\t// NOTE: Do not flush preemptively.\n\t\t// See the Write() sources for more info.\n\t\terr = nil\n\t\tw.dirty = true\n\t}\n\treturn n, err\n}\n\n// Flush writes any buffered data to the underlying io.Writer.\n// It sends the frame with \"fin\" flag set to true.\n//\n// If no Write() or ReadFrom() was made, then Flush() does nothing.\nfunc (w *Writer) Flush() error {\n\tif (!w.dirty && w.Buffered() == 0) || w.err != nil {\n\t\treturn w.err\n\t}\n\n\tw.err = w.flushFragment(true)\n\tw.n = 0\n\tw.dirty = false\n\tw.fseq = 0\n\n\treturn w.err\n}\n\n// FlushFragment writes any buffered data to the underlying io.Writer.\n// It sends the frame with \"fin\" flag set to false.\nfunc (w *Writer) FlushFragment() error {\n\tif w.Buffered() == 0 || w.err != nil {\n\t\treturn w.err\n\t}\n\n\tw.err = w.flushFragment(false)\n\tw.n = 0\n\tw.fseq++\n\n\treturn w.err\n}\n\nfunc (w *Writer) flushFragment(fin bool) (err error) {\n\tvar (\n\t\tpayload = w.buf[:w.n]\n\t\theader  = ws.Header{\n\t\t\tOpCode: w.opCode(),\n\t\t\tFin:    fin,\n\t\t\tLength: int64(len(payload)),\n\t\t}\n\t)\n\tfor _, ext := range w.extensions {\n\t\theader, err = ext.SetBits(header)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif w.state.ClientSide() {\n\t\theader.Masked = true\n\t\theader.Mask = ws.NewMask()\n\t\tws.Cipher(payload, header.Mask, 0)\n\t}\n\t// Write header to the header segment of the raw buffer.\n\tvar (\n\t\toffset = len(w.raw) - len(w.buf)\n\t\tskip   = offset - ws.HeaderSize(header)\n\t)\n\tbuf := bytesWriter{\n\t\tbuf: w.raw[skip:offset],\n\t}\n\tif err := ws.WriteHeader(&buf, header); err != nil {\n\t\t// Must never be reached.\n\t\tpanic(\"dump header error: \" + err.Error())\n\t}\n\t_, err = w.dest.Write(w.raw[skip : offset+w.n])\n\treturn err\n}\n\nfunc (w *Writer) opCode() ws.OpCode {\n\tif w.fseq > 0 {\n\t\treturn ws.OpContinuation\n\t}\n\treturn w.op\n}\n\nvar errNoSpace = fmt.Errorf(\"not enough buffer space\")\n\ntype bytesWriter struct {\n\tbuf []byte\n\tpos int\n}\n\nfunc (w *bytesWriter) Write(p []byte) (int, error) {\n\tn := copy(w.buf[w.pos:], p)\n\tw.pos += n\n\tif n != len(p) {\n\t\treturn n, errNoSpace\n\t}\n\treturn n, nil\n}\n\nfunc writeFrame(w io.Writer, s ws.State, op ws.OpCode, fin bool, p []byte) error {\n\tvar frame ws.Frame\n\tif s.ClientSide() {\n\t\t// Should copy bytes to prevent corruption of caller data.\n\t\tpayload := pbytes.GetLen(len(p))\n\t\tdefer pbytes.Put(payload)\n\n\t\tcopy(payload, p)\n\n\t\tframe = ws.NewFrame(op, fin, payload)\n\t\tframe = ws.MaskFrameInPlace(frame)\n\t} else {\n\t\tframe = ws.NewFrame(op, fin, p)\n\t}\n\n\treturn ws.WriteFrame(w, frame)\n}\n\n// reserve calculates number of bytes need to be reserved for frame header.\n//\n// Note that instead of ws.HeaderSize() it does calculation based on the buffer\n// size, not the payload size.\nfunc reserve(state ws.State, n int) (offset int) {\n\tvar mask int\n\tif state.ClientSide() {\n\t\tmask = 4\n\t}\n\tswitch {\n\tcase n <= int(len7)+mask+2:\n\t\treturn mask + 2\n\tcase n <= int(len16)+mask+4:\n\t\treturn mask + 4\n\tdefault:\n\t\treturn mask + 10\n\t}\n}\n\n// headerSize returns number of bytes needed to encode header of a frame with\n// given state and length.\nfunc headerSize(s ws.State, n int) int {\n\treturn ws.HeaderSize(ws.Header{\n\t\tLength: int64(n),\n\t\tMasked: s.ClientSide(),\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/ws/wsutil/wsutil.go",
    "content": "/*\nPackage wsutil provides utilities for working with WebSocket protocol.\n\nOverview:\n\n\t// Read masked text message from peer and check utf8 encoding.\n\theader, err := ws.ReadHeader(conn)\n\tif err != nil {\n\t\t// handle err\n\t}\n\n\t// Prepare to read payload.\n\tr := io.LimitReader(conn, header.Length)\n\tr = wsutil.NewCipherReader(r, header.Mask)\n\tr = wsutil.NewUTF8Reader(r)\n\n\tpayload, err := ioutil.ReadAll(r)\n\tif err != nil {\n\t\t// handle err\n\t}\n\nYou could get the same behavior using just `wsutil.Reader`:\n\n\tr := wsutil.Reader{\n\t\tSource:    conn,\n\t\tCheckUTF8: true,\n\t}\n\n\tpayload, err := ioutil.ReadAll(r)\n\tif err != nil {\n\t\t// handle err\n\t}\n\nOr even simplest:\n\n\tpayload, err := wsutil.ReadClientText(conn)\n\tif err != nil {\n\t\t// handle err\n\t}\n\nPackage is also exports tools for buffered writing:\n\n\t// Create buffered writer, that will buffer output bytes and send them as\n\t// 128-length fragments (with exception on large writes, see the doc).\n\twriter := wsutil.NewWriterSize(conn, ws.StateServerSide, ws.OpText, 128)\n\n\t_, err := io.CopyN(writer, rand.Reader, 100)\n\tif err == nil {\n\t\terr = writer.Flush()\n\t}\n\tif err != nil {\n\t\t// handle error\n\t}\n\nFor more utils and helpers see the documentation.\n*/\npackage wsutil\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/.gitignore",
    "content": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n#*\n*~\n\n# examples binaries\nexamples/synscan/synscan\nexamples/pfdump/pfdump\nexamples/pcapdump/pcapdump\nexamples/httpassembly/httpassembly\nexamples/statsassembly/statsassembly\nexamples/arpscan/arpscan\nexamples/bidirectional/bidirectional\nexamples/bytediff/bytediff\nexamples/reassemblydump/reassemblydump\nlayers/gen\nmacs/gen\npcap/pcap_tester\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/.travis.gofmt.sh",
    "content": "#!/bin/bash\n\ncd \"$(dirname $0)\"\nif [ -n \"$(go fmt ./...)\" ]; then\n  echo \"Go code is not formatted, run 'go fmt github.com/google/stenographer/...'\" >&2\n  exit 1\nfi\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/.travis.golint.sh",
    "content": "#!/bin/bash\n\ncd \"$(dirname $0)\"\n\ngo get golang.org/x/lint/golint\nDIRS=\". tcpassembly tcpassembly/tcpreader ip4defrag reassembly macs pcapgo pcap afpacket pfring routing defrag/lcmdefrag\"\n# Add subdirectories here as we clean up golint on each.\nfor subdir in $DIRS; do\n  pushd $subdir\n  if golint |\n      grep -v CannotSetRFMon |  # pcap exported error name\n      grep -v DataLost |        # tcpassembly/tcpreader exported error name\n      grep .; then\n    exit 1\n  fi\n  popd\ndone\n\npushd layers\nfor file in *.go; do\n  if cat .lint_blacklist | grep -q $file; then\n    echo \"Skipping lint of $file due to .lint_blacklist\"\n  elif golint $file | grep .; then\n    echo \"Lint error in file $file\"\n    exit 1\n  fi\ndone\npopd\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/.travis.govet.sh",
    "content": "#!/bin/bash\n\ncd \"$(dirname $0)\"\nDIRS=\". layers pcap pcapgo tcpassembly tcpassembly/tcpreader routing ip4defrag bytediff macs defrag/lcmdefrag\"\nset -e\nfor subdir in $DIRS; do\n  pushd $subdir\n  go vet\n  popd\ndone\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/.travis.install.sh",
    "content": "#!/bin/bash\n\nset -ev\n\ngo get github.com/google/gopacket\ngo get github.com/google/gopacket/layers\ngo get github.com/google/gopacket/tcpassembly\ngo get github.com/google/gopacket/reassembly\ngo get github.com/google/gopacket/pcapgo\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/.travis.script.sh",
    "content": "#!/bin/bash\n\nset -ev\n\ngo test github.com/google/gopacket\ngo test github.com/google/gopacket/layers\ngo test github.com/google/gopacket/tcpassembly\ngo test github.com/google/gopacket/reassembly\ngo test github.com/google/gopacket/pcapgo \ngo test github.com/google/gopacket/pcap\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/.travis.yml",
    "content": "language: go\ngo:\n - 1.11.x\n - 1.12.x\n - 1.13.x\n - master\n\naddons:\n  apt:\n    packages:\n      libpcap-dev\n\n# use modules except for older versions (see below)\ninstall: true\n\nenv:\n  - GO111MODULE=on\n\nscript: ./.travis.script.sh\n\nmatrix:\n  fast_finish: true\n  allow_failures:\n    - go: master\n\njobs:\n  include:\n    - go: 1.5.x\n      install: ./.travis.install.sh\n    - go: 1.6.x\n      install: ./.travis.install.sh\n    - go: 1.7.x\n      install: ./.travis.install.sh\n    - go: 1.8.x\n      install: ./.travis.install.sh\n    - go: 1.9.x\n      install: ./.travis.install.sh\n    - go: 1.10.x\n      install: ./.travis.install.sh\n    - os: osx\n      go: 1.x\n# windows doesn't work on travis (package installation just hangs and then errors out)\n#    - os: windows\n#      go: 1.x\n#      # We don't need nmap - but that's the only way to get npcap:\n#      before_install: choco install npcap --version 0.86 -y\n    - stage: style\n      name: \"fmt/vet/lint\"\n      go: 1.x\n      script:\n        - ./.travis.gofmt.sh\n        - ./.travis.govet.sh\n        - ./.travis.golint.sh\n\nstages:\n  - style\n  - test\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/AUTHORS",
    "content": "AUTHORS AND MAINTAINERS:\n\nMAIN DEVELOPERS:\nGraeme Connell   <gconnell@google.com, gsconnell@gmail.com>\n\nAUTHORS:\nNigel Tao <nigeltao@google.com>\nCole Mickens <cole.mickens@gmail.com>\nBen Daglish <bdaglish@restorepoint.com>\nLuis Martinez <martinezlc99@gmail.com>\nRemco Verhoef <remco@dutchcoders.io>\nHiroaki Kawai <Hiroaki.Kawai@gmail.com>\nLukas Lueg <lukas.lueg@gmail.com>\nLaurent Hausermann <laurent.hausermann@gmail.com>\nBill Green <bgreen@newrelic.com>\nChristian Mäder <christian.maeder@nine.ch>\nGernot Vormayr <gvormayr@gmail.com>\nVitor Garcia Graveto <victor.graveto@gmail.com>\nElias Chavarria Reyes <elchavar@cisco.com>\nDaniel Rittweiler <ripx80@protonmail.com>\n\nCONTRIBUTORS:\nAttila Oláh <attila@attilaolah.eu>\nVittus Mikiassen <matt.miki.vimik@gmail.com>\nMatthias Radestock <matthias.radestock@gmail.com>\nMatthew Sackman <matthew@wellquite.org>\nLoic Prylli <loicp@google.com>\nAlexandre Fiori <fiorix@gmail.com>\nAdrian Tam <adrian.c.m.tam@gmail.com>\nSatoshi Matsumoto <kaorimatz@gmail.com>\nDavid Stainton <dstainton415@gmail.com>\nJesse Ward <jesse@jesseward.com>\nKane Mathers <kane@kanemathers.name>\nJose Selvi <jselvi@pentester.es>\nYerden Zhumabekov <yerden.zhumabekov@gmail.com>\nJensen Hwa <jensenhwa@gmail.com>\n\n-----------------------------------------------\nFORKED FROM github.com/akrennmair/gopcap\nALL THE FOLLOWING ARE FOR THAT PROJECT\n\nMAIN DEVELOPERS:\nAndreas Krennmair <ak@synflood.at>\n\nCONTRIBUTORS:\nAndrea Nall <anall@andreanall.com>\nDaniel Arndt <danielarndt@gmail.com>\nDustin Sallings <dustin@spy.net>\nGraeme Connell <gconnell@google.com, gsconnell@gmail.com>\nGuillaume Savary <guillaume@savary.name>\nMark Smith <mark@qq.is>\nMiek Gieben <miek@miek.nl>\nMike Bell <mike@mikebell.org>\nTrevor Strohman <strohman@google.com>\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/CONTRIBUTING.md",
    "content": "Contributing To gopacket\n========================\n\nSo you've got some code and you'd like it to be part of gopacket... wonderful!\nWe're happy to accept contributions, whether they're fixes to old protocols, new\nprotocols entirely, or anything else you think would improve the gopacket\nlibrary.  This document is designed to help you to do just that.\n\nThe first section deals with the plumbing:  how to actually get a change\nsubmitted.\n\nThe second section deals with coding style... Go is great in that it\nhas a uniform style implemented by 'go fmt', but there's still some decisions\nwe've made that go above and beyond, and if you follow them, they won't come up\nin your code review.\n\nThe third section deals with some of the implementation decisions we've made,\nwhich may help you to understand the current code and which we may ask you to\nconform to (or provide compelling reasons for ignoring).\n\nOverall, we hope this document will help you to understand our system and write\ngreat code which fits in, and help us to turn around on your code review quickly\nso the code can make it into the master branch as quickly as possible.\n\n\nHow To Submit Code\n------------------\n\nWe use github.com's Pull Request feature to receive code contributions from\nexternal contributors.  See\nhttps://help.github.com/articles/creating-a-pull-request/ for details on\nhow to create a request.\n\nAlso, there's a local script `gc` in the base directory of GoPacket that\nruns a local set of checks, which should give you relatively high confidence\nthat your pull won't fail github pull checks.\n\n```sh\ngo get github.com/google/gopacket\ncd $GOROOT/src/pkg/github.com/google/gopacket\ngit checkout -b <mynewfeature>  # create a new branch to work from\n... code code code ...\n./gc  # Run this to do local commits, it performs a number of checks\n```\n\nTo sum up:\n\n* DO\n    + Pull down the latest version.\n    + Make a feature-specific branch.\n    + Code using the style and methods discussed in the rest of this document.\n    + Use the ./gc command to do local commits or check correctness.\n    + Push your new feature branch up to github.com, as a pull request.\n    + Handle comments and requests from reviewers, pushing new commits up to\n      your feature branch as problems are addressed.\n    + Put interesting comments and discussions into commit comments.\n* DON'T\n    + Push to someone else's branch without their permission.\n\n\nCoding Style\n------------\n\n* Go code must be run through `go fmt`, `go vet`, and `golint`\n* Follow http://golang.org/doc/effective_go.html as much as possible.\n    + In particular, http://golang.org/doc/effective_go.html#mixed-caps.  Enums\n      should be be CamelCase, with acronyms capitalized (TCPSourcePort, vs.\n      TcpSourcePort or TCP_SOURCE_PORT).\n* Bonus points for giving enum types a String() field.\n* Any exported types or functions should have commentary\n  (http://golang.org/doc/effective_go.html#commentary)\n\n\nCoding Methods And Implementation Notes\n---------------------------------------\n\n### Error Handling\n\nMany times, you'll be decoding a protocol and run across something bad, a packet\ncorruption or the like.  How do you handle this?  First off, ALWAYS report the\nerror.  You can do this either by returning the error from the decode() function\n(most common), or if you're up for it you can implement and add an ErrorLayer\nthrough the packet builder (the first method is a simple shortcut that does\nexactly this, then stops any future decoding).\n\nOften, you'll already have decode some part of your protocol by the time you hit\nyour error.  Use your own discretion to determine whether the stuff you've\nalready decoded should be returned to the caller or not:\n\n```go\nfunc decodeMyProtocol(data []byte, p gopacket.PacketBuilder) error {\n  prot := &MyProtocol{}\n  if len(data) < 10 {\n    // This error occurred before we did ANYTHING, so there's nothing in my\n    // protocol that the caller could possibly want.  Just return the error.\n    return fmt.Errorf(\"Length %d less than 10\", len(data))\n  }\n  prot.ImportantField1 = data[:5]\n  prot.ImportantField2 = data[5:10]\n  // At this point, we've already got enough information in 'prot' to\n  // warrant returning it to the caller, so we'll add it now.\n  p.AddLayer(prot)\n  if len(data) < 15 {\n    // We encountered an error later in the packet, but the caller already\n    // has the important info we've gleaned so far.\n    return fmt.Errorf(\"Length %d less than 15\", len(data))\n  }\n  prot.ImportantField3 = data[10:15]\n  return nil  // We've already added the layer, we can just return success.\n}\n```\n\nIn general, our code follows the approach of returning the first error it\nencounters.  In general, we don't trust any bytes after the first error we see.\n\n### What Is A Layer?\n\nThe definition of a layer is up to the discretion of the coder.  It should be\nsomething important enough that it's actually useful to the caller (IE: every\nTLV value should probably NOT be a layer).  However, it can be more granular\nthan a single protocol... IPv6 and SCTP both implement many layers to handle the\nvarious parts of the protocol.  Use your best judgement, and prepare to defend\nyour decisions during code review. ;)\n\n### Performance\n\nWe strive to make gopacket as fast as possible while still providing lots of\nfeatures.  In general, this means:\n\n* Focus performance tuning on common protocols (IP4/6, TCP, etc), and optimize\n  others on an as-needed basis (tons of MPLS on your network?  Time to optimize\n  MPLS!)\n* Use fast operations.  See the toplevel benchmark_test for benchmarks of some\n  of Go's underlying features and types.\n* Test your performance changes!  You should use the ./gc script's --benchmark\n  flag to submit any performance-related changes.  Use pcap/gopacket_benchmark\n  to test your change against a PCAP file based on your traffic patterns.\n* Don't be TOO hacky.  Sometimes, removing an unused struct from a field causes\n  a huge performance hit, due to the way that Go currently handles its segmented\n  stack... don't be afraid to clean it up anyway.  We'll trust the Go compiler\n  to get good enough over time to handle this.  Also, this type of\n  compiler-specific optimization is very fragile; someone adding a field to an\n  entirely different struct elsewhere in the codebase could reverse any gains\n  you might achieve by aligning your allocations.\n* Try to minimize memory allocations.  If possible, use []byte to reference\n  pieces of the input, instead of using string, which requires copying the bytes\n  into a new memory allocation.\n* Think hard about what should be evaluated lazily vs. not.  In general, a\n  layer's struct should almost exactly mirror the layer's frame.  Anything\n  that's more interesting should be a function.  This may not always be\n  possible, but it's a good rule of thumb.\n* Don't fear micro-optimizations.  With the above in mind, we welcome\n  micro-optimizations that we think will have positive/neutral impacts on the\n  majority of workloads.  A prime example of this is pre-allocating certain\n  structs within a larger one:\n\n```go\ntype MyProtocol struct {\n  // Most packets have 1-4 of VeryCommon, so we preallocate it here.\n  initialAllocation [4]uint32\n  VeryCommon []uint32\n}\n\nfunc decodeMyProtocol(data []byte, p gopacket.PacketBuilder) error {\n  prot := &MyProtocol{}\n  prot.VeryCommon = proto.initialAllocation[:0]\n  for len(data) > 4 {\n    field := binary.BigEndian.Uint32(data[:4])\n    data = data[4:]\n    // Since we're using the underlying initialAllocation, we won't need to\n    // allocate new memory for the following append unless we more than 16\n    // bytes of data, which should be the uncommon case.\n    prot.VeryCommon = append(prot.VeryCommon, field)\n  }\n  p.AddLayer(prot)\n  if len(data) > 0 {\n    return fmt.Errorf(\"MyProtocol packet has %d bytes left after decoding\", len(data))\n  }\n  return nil\n}\n```\n\n### Slices And Data\n\nIf you're pulling a slice from the data you're decoding, don't copy it.  Just\nuse the slice itself.\n\n```go\ntype MyProtocol struct {\n  A, B net.IP\n}\nfunc decodeMyProtocol(data []byte, p gopacket.PacketBuilder) error {\n  p.AddLayer(&MyProtocol{\n    A: data[:4],\n    B: data[4:8],\n  })\n  return nil\n}\n```\n\nThe caller has already agreed, by using this library, that they won't modify the\nset of bytes they pass in to the decoder, or the library has already copied the\nset of bytes to a read-only location.  See DecodeOptions.NoCopy for more\ninformation.\n\n### Enums/Types\n\nIf a protocol has an integer field (uint8, uint16, etc) with a couple of known\nvalues that mean something special, make it a type.  This allows us to do really\nnice things like adding a String() function to them, so we can more easily\ndisplay those to users.  Check out layers/enums.go for one example, as well as\nlayers/icmp.go for layer-specific enums.\n\nWhen naming things, try for descriptiveness over suscinctness.  For example,\nchoose DNSResponseRecord over DNSRR.\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/LICENSE",
    "content": "Copyright (c) 2012 Google, Inc. All rights reserved.\nCopyright (c) 2009-2011 Andreas Krennmair. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Andreas Krennmair, Google, nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(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": "vendor/github.com/google/gopacket/README.md",
    "content": "# GoPacket\n\nThis library provides packet decoding capabilities for Go.\nSee [godoc](https://godoc.org/github.com/google/gopacket) for more details.\n\n[![Build Status](https://travis-ci.org/google/gopacket.svg?branch=master)](https://travis-ci.org/google/gopacket)\n[![GoDoc](https://godoc.org/github.com/google/gopacket?status.svg)](https://godoc.org/github.com/google/gopacket)\n\nMinimum Go version required is 1.5 except for pcapgo/EthernetHandle, afpacket, and bsdbpf which need at least 1.9 due to x/sys/unix dependencies.\n\nOriginally forked from the gopcap project written by Andreas\nKrennmair <ak@synflood.at> (http://github.com/akrennmair/gopcap).\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/base.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage gopacket\n\nimport (\n\t\"fmt\"\n)\n\n// Layer represents a single decoded packet layer (using either the\n// OSI or TCP/IP definition of a layer).  When decoding, a packet's data is\n// broken up into a number of layers.  The caller may call LayerType() to\n// figure out which type of layer they've received from the packet.  Optionally,\n// they may then use a type assertion to get the actual layer type for deep\n// inspection of the data.\ntype Layer interface {\n\t// LayerType is the gopacket type for this layer.\n\tLayerType() LayerType\n\t// LayerContents returns the set of bytes that make up this layer.\n\tLayerContents() []byte\n\t// LayerPayload returns the set of bytes contained within this layer, not\n\t// including the layer itself.\n\tLayerPayload() []byte\n}\n\n// Payload is a Layer containing the payload of a packet.  The definition of\n// what constitutes the payload of a packet depends on previous layers; for\n// TCP and UDP, we stop decoding above layer 4 and return the remaining\n// bytes as a Payload.  Payload is an ApplicationLayer.\ntype Payload []byte\n\n// LayerType returns LayerTypePayload\nfunc (p Payload) LayerType() LayerType { return LayerTypePayload }\n\n// LayerContents returns the bytes making up this layer.\nfunc (p Payload) LayerContents() []byte { return []byte(p) }\n\n// LayerPayload returns the payload within this layer.\nfunc (p Payload) LayerPayload() []byte { return nil }\n\n// Payload returns this layer as bytes.\nfunc (p Payload) Payload() []byte { return []byte(p) }\n\n// String implements fmt.Stringer.\nfunc (p Payload) String() string { return fmt.Sprintf(\"%d byte(s)\", len(p)) }\n\n// GoString implements fmt.GoStringer.\nfunc (p Payload) GoString() string { return LongBytesGoString([]byte(p)) }\n\n// CanDecode implements DecodingLayer.\nfunc (p Payload) CanDecode() LayerClass { return LayerTypePayload }\n\n// NextLayerType implements DecodingLayer.\nfunc (p Payload) NextLayerType() LayerType { return LayerTypeZero }\n\n// DecodeFromBytes implements DecodingLayer.\nfunc (p *Payload) DecodeFromBytes(data []byte, df DecodeFeedback) error {\n\t*p = Payload(data)\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (p Payload) SerializeTo(b SerializeBuffer, opts SerializeOptions) error {\n\tbytes, err := b.PrependBytes(len(p))\n\tif err != nil {\n\t\treturn err\n\t}\n\tcopy(bytes, p)\n\treturn nil\n}\n\n// decodePayload decodes data by returning it all in a Payload layer.\nfunc decodePayload(data []byte, p PacketBuilder) error {\n\tpayload := &Payload{}\n\tif err := payload.DecodeFromBytes(data, p); err != nil {\n\t\treturn err\n\t}\n\tp.AddLayer(payload)\n\tp.SetApplicationLayer(payload)\n\treturn nil\n}\n\n// Fragment is a Layer containing a fragment of a larger frame, used by layers\n// like IPv4 and IPv6 that allow for fragmentation of their payloads.\ntype Fragment []byte\n\n// LayerType returns LayerTypeFragment\nfunc (p *Fragment) LayerType() LayerType { return LayerTypeFragment }\n\n// LayerContents implements Layer.\nfunc (p *Fragment) LayerContents() []byte { return []byte(*p) }\n\n// LayerPayload implements Layer.\nfunc (p *Fragment) LayerPayload() []byte { return nil }\n\n// Payload returns this layer as a byte slice.\nfunc (p *Fragment) Payload() []byte { return []byte(*p) }\n\n// String implements fmt.Stringer.\nfunc (p *Fragment) String() string { return fmt.Sprintf(\"%d byte(s)\", len(*p)) }\n\n// CanDecode implements DecodingLayer.\nfunc (p *Fragment) CanDecode() LayerClass { return LayerTypeFragment }\n\n// NextLayerType implements DecodingLayer.\nfunc (p *Fragment) NextLayerType() LayerType { return LayerTypeZero }\n\n// DecodeFromBytes implements DecodingLayer.\nfunc (p *Fragment) DecodeFromBytes(data []byte, df DecodeFeedback) error {\n\t*p = Fragment(data)\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (p *Fragment) SerializeTo(b SerializeBuffer, opts SerializeOptions) error {\n\tbytes, err := b.PrependBytes(len(*p))\n\tif err != nil {\n\t\treturn err\n\t}\n\tcopy(bytes, *p)\n\treturn nil\n}\n\n// decodeFragment decodes data by returning it all in a Fragment layer.\nfunc decodeFragment(data []byte, p PacketBuilder) error {\n\tpayload := &Fragment{}\n\tif err := payload.DecodeFromBytes(data, p); err != nil {\n\t\treturn err\n\t}\n\tp.AddLayer(payload)\n\tp.SetApplicationLayer(payload)\n\treturn nil\n}\n\n// These layers correspond to Internet Protocol Suite (TCP/IP) layers, and their\n// corresponding OSI layers, as best as possible.\n\n// LinkLayer is the packet layer corresponding to TCP/IP layer 1 (OSI layer 2)\ntype LinkLayer interface {\n\tLayer\n\tLinkFlow() Flow\n}\n\n// NetworkLayer is the packet layer corresponding to TCP/IP layer 2 (OSI\n// layer 3)\ntype NetworkLayer interface {\n\tLayer\n\tNetworkFlow() Flow\n}\n\n// TransportLayer is the packet layer corresponding to the TCP/IP layer 3 (OSI\n// layer 4)\ntype TransportLayer interface {\n\tLayer\n\tTransportFlow() Flow\n}\n\n// ApplicationLayer is the packet layer corresponding to the TCP/IP layer 4 (OSI\n// layer 7), also known as the packet payload.\ntype ApplicationLayer interface {\n\tLayer\n\tPayload() []byte\n}\n\n// ErrorLayer is a packet layer created when decoding of the packet has failed.\n// Its payload is all the bytes that we were unable to decode, and the returned\n// error details why the decoding failed.\ntype ErrorLayer interface {\n\tLayer\n\tError() error\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/decode.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage gopacket\n\nimport (\n\t\"errors\"\n)\n\n// DecodeFeedback is used by DecodingLayer layers to provide decoding metadata.\ntype DecodeFeedback interface {\n\t// SetTruncated should be called if during decoding you notice that a packet\n\t// is shorter than internal layer variables (HeaderLength, or the like) say it\n\t// should be.  It sets packet.Metadata().Truncated.\n\tSetTruncated()\n}\n\ntype nilDecodeFeedback struct{}\n\nfunc (nilDecodeFeedback) SetTruncated() {}\n\n// NilDecodeFeedback implements DecodeFeedback by doing nothing.\nvar NilDecodeFeedback DecodeFeedback = nilDecodeFeedback{}\n\n// PacketBuilder is used by layer decoders to store the layers they've decoded,\n// and to defer future decoding via NextDecoder.\n// Typically, the pattern for use is:\n//  func (m *myDecoder) Decode(data []byte, p PacketBuilder) error {\n//    if myLayer, err := myDecodingLogic(data); err != nil {\n//      return err\n//    } else {\n//      p.AddLayer(myLayer)\n//    }\n//    // maybe do this, if myLayer is a LinkLayer\n//    p.SetLinkLayer(myLayer)\n//    return p.NextDecoder(nextDecoder)\n//  }\ntype PacketBuilder interface {\n\tDecodeFeedback\n\t// AddLayer should be called by a decoder immediately upon successful\n\t// decoding of a layer.\n\tAddLayer(l Layer)\n\t// The following functions set the various specific layers in the final\n\t// packet.  Note that if many layers call SetX, the first call is kept and all\n\t// other calls are ignored.\n\tSetLinkLayer(LinkLayer)\n\tSetNetworkLayer(NetworkLayer)\n\tSetTransportLayer(TransportLayer)\n\tSetApplicationLayer(ApplicationLayer)\n\tSetErrorLayer(ErrorLayer)\n\t// NextDecoder should be called by a decoder when they're done decoding a\n\t// packet layer but not done with decoding the entire packet.  The next\n\t// decoder will be called to decode the last AddLayer's LayerPayload.\n\t// Because of this, NextDecoder must only be called once all other\n\t// PacketBuilder calls have been made.  Set*Layer and AddLayer calls after\n\t// NextDecoder calls will behave incorrectly.\n\tNextDecoder(next Decoder) error\n\t// DumpPacketData is used solely for decoding.  If you come across an error\n\t// you need to diagnose while processing a packet, call this and your packet's\n\t// data will be dumped to stderr so you can create a test.  This should never\n\t// be called from a production decoder.\n\tDumpPacketData()\n\t// DecodeOptions returns the decode options\n\tDecodeOptions() *DecodeOptions\n}\n\n// Decoder is an interface for logic to decode a packet layer.  Users may\n// implement a Decoder to handle their own strange packet types, or may use one\n// of the many decoders available in the 'layers' subpackage to decode things\n// for them.\ntype Decoder interface {\n\t// Decode decodes the bytes of a packet, sending decoded values and other\n\t// information to PacketBuilder, and returning an error if unsuccessful.  See\n\t// the PacketBuilder documentation for more details.\n\tDecode([]byte, PacketBuilder) error\n}\n\n// DecodeFunc wraps a function to make it a Decoder.\ntype DecodeFunc func([]byte, PacketBuilder) error\n\n// Decode implements Decoder by calling itself.\nfunc (d DecodeFunc) Decode(data []byte, p PacketBuilder) error {\n\t// function, call thyself.\n\treturn d(data, p)\n}\n\n// DecodePayload is a Decoder that returns a Payload layer containing all\n// remaining bytes.\nvar DecodePayload Decoder = DecodeFunc(decodePayload)\n\n// DecodeUnknown is a Decoder that returns an Unknown layer containing all\n// remaining bytes, useful if you run up against a layer that you're unable to\n// decode yet.  This layer is considered an ErrorLayer.\nvar DecodeUnknown Decoder = DecodeFunc(decodeUnknown)\n\n// DecodeFragment is a Decoder that returns a Fragment layer containing all\n// remaining bytes.\nvar DecodeFragment Decoder = DecodeFunc(decodeFragment)\n\n// LayerTypeZero is an invalid layer type, but can be used to determine whether\n// layer type has actually been set correctly.\nvar LayerTypeZero = RegisterLayerType(0, LayerTypeMetadata{Name: \"Unknown\", Decoder: DecodeUnknown})\n\n// LayerTypeDecodeFailure is the layer type for the default error layer.\nvar LayerTypeDecodeFailure = RegisterLayerType(1, LayerTypeMetadata{Name: \"DecodeFailure\", Decoder: DecodeUnknown})\n\n// LayerTypePayload is the layer type for a payload that we don't try to decode\n// but treat as a success, IE: an application-level payload.\nvar LayerTypePayload = RegisterLayerType(2, LayerTypeMetadata{Name: \"Payload\", Decoder: DecodePayload})\n\n// LayerTypeFragment is the layer type for a fragment of a layer transported\n// by an underlying layer that supports fragmentation.\nvar LayerTypeFragment = RegisterLayerType(3, LayerTypeMetadata{Name: \"Fragment\", Decoder: DecodeFragment})\n\n// DecodeFailure is a packet layer created if decoding of the packet data failed\n// for some reason.  It implements ErrorLayer.  LayerContents will be the entire\n// set of bytes that failed to parse, and Error will return the reason parsing\n// failed.\ntype DecodeFailure struct {\n\tdata  []byte\n\terr   error\n\tstack []byte\n}\n\n// Error returns the error encountered during decoding.\nfunc (d *DecodeFailure) Error() error { return d.err }\n\n// LayerContents implements Layer.\nfunc (d *DecodeFailure) LayerContents() []byte { return d.data }\n\n// LayerPayload implements Layer.\nfunc (d *DecodeFailure) LayerPayload() []byte { return nil }\n\n// String implements fmt.Stringer.\nfunc (d *DecodeFailure) String() string {\n\treturn \"Packet decoding error: \" + d.Error().Error()\n}\n\n// Dump implements Dumper.\nfunc (d *DecodeFailure) Dump() (s string) {\n\tif d.stack != nil {\n\t\ts = string(d.stack)\n\t}\n\treturn\n}\n\n// LayerType returns LayerTypeDecodeFailure\nfunc (d *DecodeFailure) LayerType() LayerType { return LayerTypeDecodeFailure }\n\n// decodeUnknown \"decodes\" unsupported data types by returning an error.\n// This decoder will thus always return a DecodeFailure layer.\nfunc decodeUnknown(data []byte, p PacketBuilder) error {\n\treturn errors.New(\"Layer type not currently supported\")\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/doc.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\n/*\nPackage gopacket provides packet decoding for the Go language.\n\ngopacket contains many sub-packages with additional functionality you may find\nuseful, including:\n\n * layers: You'll probably use this every time.  This contains of the logic\n     built into gopacket for decoding packet protocols.  Note that all example\n     code below assumes that you have imported both gopacket and\n     gopacket/layers.\n * pcap: C bindings to use libpcap to read packets off the wire.\n * pfring: C bindings to use PF_RING to read packets off the wire.\n * afpacket: C bindings for Linux's AF_PACKET to read packets off the wire.\n * tcpassembly: TCP stream reassembly\n\nAlso, if you're looking to dive right into code, see the examples subdirectory\nfor numerous simple binaries built using gopacket libraries.\n\nMinimum go version required is 1.5 except for pcapgo/EthernetHandle, afpacket,\nand bsdbpf which need at least 1.7 due to x/sys/unix dependencies.\n\nBasic Usage\n\ngopacket takes in packet data as a []byte and decodes it into a packet with\na non-zero number of \"layers\".  Each layer corresponds to a protocol\nwithin the bytes.  Once a packet has been decoded, the layers of the packet\ncan be requested from the packet.\n\n // Decode a packet\n packet := gopacket.NewPacket(myPacketData, layers.LayerTypeEthernet, gopacket.Default)\n // Get the TCP layer from this packet\n if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {\n   fmt.Println(\"This is a TCP packet!\")\n   // Get actual TCP data from this layer\n   tcp, _ := tcpLayer.(*layers.TCP)\n   fmt.Printf(\"From src port %d to dst port %d\\n\", tcp.SrcPort, tcp.DstPort)\n }\n // Iterate over all layers, printing out each layer type\n for _, layer := range packet.Layers() {\n   fmt.Println(\"PACKET LAYER:\", layer.LayerType())\n }\n\nPackets can be decoded from a number of starting points.  Many of our base\ntypes implement Decoder, which allow us to decode packets for which\nwe don't have full data.\n\n // Decode an ethernet packet\n ethP := gopacket.NewPacket(p1, layers.LayerTypeEthernet, gopacket.Default)\n // Decode an IPv6 header and everything it contains\n ipP := gopacket.NewPacket(p2, layers.LayerTypeIPv6, gopacket.Default)\n // Decode a TCP header and its payload\n tcpP := gopacket.NewPacket(p3, layers.LayerTypeTCP, gopacket.Default)\n\n\nReading Packets From A Source\n\nMost of the time, you won't just have a []byte of packet data lying around.\nInstead, you'll want to read packets in from somewhere (file, interface, etc)\nand process them.  To do that, you'll want to build a PacketSource.\n\nFirst, you'll need to construct an object that implements the PacketDataSource\ninterface.  There are implementations of this interface bundled with gopacket\nin the gopacket/pcap and gopacket/pfring subpackages... see their documentation\nfor more information on their usage.  Once you have a PacketDataSource, you can\npass it into NewPacketSource, along with a Decoder of your choice, to create\na PacketSource.\n\nOnce you have a PacketSource, you can read packets from it in multiple ways.\nSee the docs for PacketSource for more details.  The easiest method is the\nPackets function, which returns a channel, then asynchronously writes new\npackets into that channel, closing the channel if the packetSource hits an\nend-of-file.\n\n  packetSource := ...  // construct using pcap or pfring\n  for packet := range packetSource.Packets() {\n    handlePacket(packet)  // do something with each packet\n  }\n\nYou can change the decoding options of the packetSource by setting fields in\npacketSource.DecodeOptions... see the following sections for more details.\n\n\nLazy Decoding\n\ngopacket optionally decodes packet data lazily, meaning it\nonly decodes a packet layer when it needs to handle a function call.\n\n // Create a packet, but don't actually decode anything yet\n packet := gopacket.NewPacket(myPacketData, layers.LayerTypeEthernet, gopacket.Lazy)\n // Now, decode the packet up to the first IPv4 layer found but no further.\n // If no IPv4 layer was found, the whole packet will be decoded looking for\n // it.\n ip4 := packet.Layer(layers.LayerTypeIPv4)\n // Decode all layers and return them.  The layers up to the first IPv4 layer\n // are already decoded, and will not require decoding a second time.\n layers := packet.Layers()\n\nLazily-decoded packets are not concurrency-safe.  Since layers have not all been\ndecoded, each call to Layer() or Layers() has the potential to mutate the packet\nin order to decode the next layer.  If a packet is used\nin multiple goroutines concurrently, don't use gopacket.Lazy.  Then gopacket\nwill decode the packet fully, and all future function calls won't mutate the\nobject.\n\n\nNoCopy Decoding\n\nBy default, gopacket will copy the slice passed to NewPacket and store the\ncopy within the packet, so future mutations to the bytes underlying the slice\ndon't affect the packet and its layers.  If you can guarantee that the\nunderlying slice bytes won't be changed, you can use NoCopy to tell\ngopacket.NewPacket, and it'll use the passed-in slice itself.\n\n // This channel returns new byte slices, each of which points to a new\n // memory location that's guaranteed immutable for the duration of the\n // packet.\n for data := range myByteSliceChannel {\n   p := gopacket.NewPacket(data, layers.LayerTypeEthernet, gopacket.NoCopy)\n   doSomethingWithPacket(p)\n }\n\nThe fastest method of decoding is to use both Lazy and NoCopy, but note from\nthe many caveats above that for some implementations either or both may be\ndangerous.\n\n\nPointers To Known Layers\n\nDuring decoding, certain layers are stored in the packet as well-known\nlayer types.  For example, IPv4 and IPv6 are both considered NetworkLayer\nlayers, while TCP and UDP are both TransportLayer layers.  We support 4\nlayers, corresponding to the 4 layers of the TCP/IP layering scheme (roughly\nanagalous to layers 2, 3, 4, and 7 of the OSI model).  To access these,\nyou can use the packet.LinkLayer, packet.NetworkLayer,\npacket.TransportLayer, and packet.ApplicationLayer functions.  Each of\nthese functions returns a corresponding interface\n(gopacket.{Link,Network,Transport,Application}Layer).  The first three\nprovide methods for getting src/dst addresses for that particular layer,\nwhile the final layer provides a Payload function to get payload data.\nThis is helpful, for example, to get payloads for all packets regardless\nof their underlying data type:\n\n // Get packets from some source\n for packet := range someSource {\n   if app := packet.ApplicationLayer(); app != nil {\n     if strings.Contains(string(app.Payload()), \"magic string\") {\n       fmt.Println(\"Found magic string in a packet!\")\n     }\n   }\n }\n\nA particularly useful layer is ErrorLayer, which is set whenever there's\nan error parsing part of the packet.\n\n packet := gopacket.NewPacket(myPacketData, layers.LayerTypeEthernet, gopacket.Default)\n if err := packet.ErrorLayer(); err != nil {\n   fmt.Println(\"Error decoding some part of the packet:\", err)\n }\n\nNote that we don't return an error from NewPacket because we may have decoded\na number of layers successfully before running into our erroneous layer.  You\nmay still be able to get your Ethernet and IPv4 layers correctly, even if\nyour TCP layer is malformed.\n\n\nFlow And Endpoint\n\ngopacket has two useful objects, Flow and Endpoint, for communicating in a protocol\nindependent manner the fact that a packet is coming from A and going to B.\nThe general layer types LinkLayer, NetworkLayer, and TransportLayer all provide\nmethods for extracting their flow information, without worrying about the type\nof the underlying Layer.\n\nA Flow is a simple object made up of a set of two Endpoints, one source and one\ndestination.  It details the sender and receiver of the Layer of the Packet.\n\nAn Endpoint is a hashable representation of a source or destination.  For\nexample, for LayerTypeIPv4, an Endpoint contains the IP address bytes for a v4\nIP packet.  A Flow can be broken into Endpoints, and Endpoints can be combined\ninto Flows:\n\n packet := gopacket.NewPacket(myPacketData, layers.LayerTypeEthernet, gopacket.Lazy)\n netFlow := packet.NetworkLayer().NetworkFlow()\n src, dst := netFlow.Endpoints()\n reverseFlow := gopacket.NewFlow(dst, src)\n\nBoth Endpoint and Flow objects can be used as map keys, and the equality\noperator can compare them, so you can easily group together all packets\nbased on endpoint criteria:\n\n flows := map[gopacket.Endpoint]chan gopacket.Packet\n packet := gopacket.NewPacket(myPacketData, layers.LayerTypeEthernet, gopacket.Lazy)\n // Send all TCP packets to channels based on their destination port.\n if tcp := packet.Layer(layers.LayerTypeTCP); tcp != nil {\n   flows[tcp.TransportFlow().Dst()] <- packet\n }\n // Look for all packets with the same source and destination network address\n if net := packet.NetworkLayer(); net != nil {\n   src, dst := net.NetworkFlow().Endpoints()\n   if src == dst {\n     fmt.Println(\"Fishy packet has same network source and dst: %s\", src)\n   }\n }\n // Find all packets coming from UDP port 1000 to UDP port 500\n interestingFlow := gopacket.FlowFromEndpoints(layers.NewUDPPortEndpoint(1000), layers.NewUDPPortEndpoint(500))\n if t := packet.NetworkLayer(); t != nil && t.TransportFlow() == interestingFlow {\n   fmt.Println(\"Found that UDP flow I was looking for!\")\n }\n\nFor load-balancing purposes, both Flow and Endpoint have FastHash() functions,\nwhich provide quick, non-cryptographic hashes of their contents.  Of particular\nimportance is the fact that Flow FastHash() is symmetric: A->B will have the same\nhash as B->A.  An example usage could be:\n\n channels := [8]chan gopacket.Packet\n for i := 0; i < 8; i++ {\n   channels[i] = make(chan gopacket.Packet)\n   go packetHandler(channels[i])\n }\n for packet := range getPackets() {\n   if net := packet.NetworkLayer(); net != nil {\n     channels[int(net.NetworkFlow().FastHash()) & 0x7] <- packet\n   }\n }\n\nThis allows us to split up a packet stream while still making sure that each\nstream sees all packets for a flow (and its bidirectional opposite).\n\n\nImplementing Your Own Decoder\n\nIf your network has some strange encapsulation, you can implement your own\ndecoder.  In this example, we handle Ethernet packets which are encapsulated\nin a 4-byte header.\n\n // Create a layer type, should be unique and high, so it doesn't conflict,\n // giving it a name and a decoder to use.\n var MyLayerType = gopacket.RegisterLayerType(12345, gopacket.LayerTypeMetadata{Name: \"MyLayerType\", Decoder: gopacket.DecodeFunc(decodeMyLayer)})\n\n // Implement my layer\n type MyLayer struct {\n   StrangeHeader []byte\n   payload []byte\n }\n func (m MyLayer) LayerType() gopacket.LayerType { return MyLayerType }\n func (m MyLayer) LayerContents() []byte { return m.StrangeHeader }\n func (m MyLayer) LayerPayload() []byte { return m.payload }\n\n // Now implement a decoder... this one strips off the first 4 bytes of the\n // packet.\n func decodeMyLayer(data []byte, p gopacket.PacketBuilder) error {\n   // Create my layer\n   p.AddLayer(&MyLayer{data[:4], data[4:]})\n   // Determine how to handle the rest of the packet\n   return p.NextDecoder(layers.LayerTypeEthernet)\n }\n\n // Finally, decode your packets:\n p := gopacket.NewPacket(data, MyLayerType, gopacket.Lazy)\n\nSee the docs for Decoder and PacketBuilder for more details on how coding\ndecoders works, or look at RegisterLayerType and RegisterEndpointType to see how\nto add layer/endpoint types to gopacket.\n\n\nFast Decoding With DecodingLayerParser\n\nTLDR:  DecodingLayerParser takes about 10% of the time as NewPacket to decode\npacket data, but only for known packet stacks.\n\nBasic decoding using gopacket.NewPacket or PacketSource.Packets is somewhat slow\ndue to its need to allocate a new packet and every respective layer.  It's very\nversatile and can handle all known layer types, but sometimes you really only\ncare about a specific set of layers regardless, so that versatility is wasted.\n\nDecodingLayerParser avoids memory allocation altogether by decoding packet\nlayers directly into preallocated objects, which you can then reference to get\nthe packet's information.  A quick example:\n\n func main() {\n   var eth layers.Ethernet\n   var ip4 layers.IPv4\n   var ip6 layers.IPv6\n   var tcp layers.TCP\n   parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, &eth, &ip4, &ip6, &tcp)\n   decoded := []gopacket.LayerType{}\n   for packetData := range somehowGetPacketData() {\n     if err := parser.DecodeLayers(packetData, &decoded); err != nil {\n       fmt.Fprintf(os.Stderr, \"Could not decode layers: %v\\n\", err)\n       continue\n     }\n     for _, layerType := range decoded {\n       switch layerType {\n         case layers.LayerTypeIPv6:\n           fmt.Println(\"    IP6 \", ip6.SrcIP, ip6.DstIP)\n         case layers.LayerTypeIPv4:\n           fmt.Println(\"    IP4 \", ip4.SrcIP, ip4.DstIP)\n       }\n     }\n   }\n }\n\nThe important thing to note here is that the parser is modifying the passed in\nlayers (eth, ip4, ip6, tcp) instead of allocating new ones, thus greatly\nspeeding up the decoding process.  It's even branching based on layer type...\nit'll handle an (eth, ip4, tcp) or (eth, ip6, tcp) stack.  However, it won't\nhandle any other type... since no other decoders were passed in, an (eth, ip4,\nudp) stack will stop decoding after ip4, and only pass back [LayerTypeEthernet,\nLayerTypeIPv4] through the 'decoded' slice (along with an error saying it can't\ndecode a UDP packet).\n\nUnfortunately, not all layers can be used by DecodingLayerParser... only those\nimplementing the DecodingLayer interface are usable.  Also, it's possible to\ncreate DecodingLayers that are not themselves Layers... see\nlayers.IPv6ExtensionSkipper for an example of this.\n\nFaster And Customized Decoding with DecodingLayerContainer\n\nBy default, DecodingLayerParser uses native map to store and search for a layer\nto decode. Though being versatile, in some cases this solution may be not so\noptimal. For example, if you have only few layers faster operations may be\nprovided by sparse array indexing or linear array scan.\n\nTo accomodate these scenarios, DecodingLayerContainer interface is introduced\nalong with its implementations: DecodingLayerSparse, DecodingLayerArray and\nDecodingLayerMap. You can specify a container implementation to\nDecodingLayerParser with SetDecodingLayerContainer method. Example:\n\n dlp := gopacket.NewDecodingLayerParser(LayerTypeEthernet)\n dlp.SetDecodingLayerContainer(gopacket.DecodingLayerSparse(nil))\n var eth layers.Ethernet\n dlp.AddDecodingLayer(&eth)\n // ... add layers and use DecodingLayerParser as usual...\n\nTo skip one level of indirection (though sacrificing some capabilities) you may\nalso use DecodingLayerContainer as a decoding tool as it is. In this case you have to\nhandle unknown layer types and layer panics by yourself. Example:\n\n func main() {\n   var eth layers.Ethernet\n   var ip4 layers.IPv4\n   var ip6 layers.IPv6\n   var tcp layers.TCP\n   dlc := gopacket.DecodingLayerContainer(gopacket.DecodingLayerArray(nil))\n   dlc = dlc.Put(&eth)\n   dlc = dlc.Put(&ip4)\n   dlc = dlc.Put(&ip6)\n   dlc = dlc.Put(&tcp)\n   // you may specify some meaningful DecodeFeedback\n   decoder := dlc.LayersDecoder(LayerTypeEthernet, gopacket.NilDecodeFeedback)\n   decoded := make([]gopacket.LayerType, 0, 20)\n   for packetData := range somehowGetPacketData() {\n     lt, err := decoder(packetData, &decoded)\n     if err != nil {\n       fmt.Fprintf(os.Stderr, \"Could not decode layers: %v\\n\", err)\n       continue\n     }\n     if lt != gopacket.LayerTypeZero {\n       fmt.Fprintf(os.Stderr, \"unknown layer type: %v\\n\", lt)\n       continue\n     }\n     for _, layerType := range decoded {\n       // examine decoded layertypes just as already shown above\n     }\n   }\n }\n\nDecodingLayerSparse is the fastest but most effective when LayerType values\nthat layers in use can decode are not large because otherwise that would lead\nto bigger memory footprint. DecodingLayerArray is very compact and primarily\nusable if the number of decoding layers is not big (up to ~10-15, but please do\nyour own benchmarks). DecodingLayerMap is the most versatile one and used by\nDecodingLayerParser by default. Please refer to tests and benchmarks in layers\nsubpackage to further examine usage examples and performance measurements.\n\nYou may also choose to implement your own DecodingLayerContainer if you want to\nmake use of your own internal packet decoding logic.\n\nCreating Packet Data\n\nAs well as offering the ability to decode packet data, gopacket will allow you\nto create packets from scratch, as well.  A number of gopacket layers implement\nthe SerializableLayer interface; these layers can be serialized to a []byte in\nthe following manner:\n\n  ip := &layers.IPv4{\n    SrcIP: net.IP{1, 2, 3, 4},\n    DstIP: net.IP{5, 6, 7, 8},\n    // etc...\n  }\n  buf := gopacket.NewSerializeBuffer()\n  opts := gopacket.SerializeOptions{}  // See SerializeOptions for more details.\n  err := ip.SerializeTo(buf, opts)\n  if err != nil { panic(err) }\n  fmt.Println(buf.Bytes())  // prints out a byte slice containing the serialized IPv4 layer.\n\nSerializeTo PREPENDS the given layer onto the SerializeBuffer, and they treat\nthe current buffer's Bytes() slice as the payload of the serializing layer.\nTherefore, you can serialize an entire packet by serializing a set of layers in\nreverse order (Payload, then TCP, then IP, then Ethernet, for example).  The\nSerializeBuffer's SerializeLayers function is a helper that does exactly that.\n\nTo generate a (empty and useless, because no fields are set)\nEthernet(IPv4(TCP(Payload))) packet, for example, you can run:\n\n  buf := gopacket.NewSerializeBuffer()\n  opts := gopacket.SerializeOptions{}\n  gopacket.SerializeLayers(buf, opts,\n    &layers.Ethernet{},\n    &layers.IPv4{},\n    &layers.TCP{},\n    gopacket.Payload([]byte{1, 2, 3, 4}))\n  packetData := buf.Bytes()\n\nA Final Note\n\nIf you use gopacket, you'll almost definitely want to make sure gopacket/layers\nis imported, since when imported it sets all the LayerType variables and fills\nin a lot of interesting variables/maps (DecodersByLayerName, etc).  Therefore,\nit's recommended that even if you don't use any layers functions directly, you still import with:\n\n  import (\n    _ \"github.com/google/gopacket/layers\"\n  )\n*/\npackage gopacket\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/flows.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage gopacket\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"strconv\"\n)\n\n// MaxEndpointSize determines the maximum size in bytes of an endpoint address.\n//\n// Endpoints/Flows have a problem:  They need to be hashable.  Therefore, they\n// can't use a byte slice.  The two obvious choices are to use a string or a\n// byte array.  Strings work great, but string creation requires memory\n// allocation, which can be slow.  Arrays work great, but have a fixed size.  We\n// originally used the former, now we've switched to the latter.  Use of a fixed\n// byte-array doubles the speed of constructing a flow (due to not needing to\n// allocate).  This is a huge increase... too much for us to pass up.\n//\n// The end result of this, though, is that an endpoint/flow can't be created\n// using more than MaxEndpointSize bytes per address.\nconst MaxEndpointSize = 16\n\n// Endpoint is the set of bytes used to address packets at various layers.\n// See LinkLayer, NetworkLayer, and TransportLayer specifications.\n// Endpoints are usable as map keys.\ntype Endpoint struct {\n\ttyp EndpointType\n\tlen int\n\traw [MaxEndpointSize]byte\n}\n\n// EndpointType returns the endpoint type associated with this endpoint.\nfunc (a Endpoint) EndpointType() EndpointType { return a.typ }\n\n// Raw returns the raw bytes of this endpoint.  These aren't human-readable\n// most of the time, but they are faster than calling String.\nfunc (a Endpoint) Raw() []byte { return a.raw[:a.len] }\n\n// LessThan provides a stable ordering for all endpoints.  It sorts first based\n// on the EndpointType of an endpoint, then based on the raw bytes of that\n// endpoint.\n//\n// For some endpoints, the actual comparison may not make sense, however this\n// ordering does provide useful information for most Endpoint types.\n// Ordering is based first on endpoint type, then on raw endpoint bytes.\n// Endpoint bytes are sorted lexicographically.\nfunc (a Endpoint) LessThan(b Endpoint) bool {\n\treturn a.typ < b.typ || (a.typ == b.typ && bytes.Compare(a.raw[:a.len], b.raw[:b.len]) < 0)\n}\n\n// fnvHash is used by our FastHash functions, and implements the FNV hash\n// created by Glenn Fowler, Landon Curt Noll, and Phong Vo.\n// See http://isthe.com/chongo/tech/comp/fnv/.\nfunc fnvHash(s []byte) (h uint64) {\n\th = fnvBasis\n\tfor i := 0; i < len(s); i++ {\n\t\th ^= uint64(s[i])\n\t\th *= fnvPrime\n\t}\n\treturn\n}\n\nconst fnvBasis = 14695981039346656037\nconst fnvPrime = 1099511628211\n\n// FastHash provides a quick hashing function for an endpoint, useful if you'd\n// like to split up endpoints by modulos or other load-balancing techniques.\n// It uses a variant of Fowler-Noll-Vo hashing.\n//\n// The output of FastHash is not guaranteed to remain the same through future\n// code revisions, so should not be used to key values in persistent storage.\nfunc (a Endpoint) FastHash() (h uint64) {\n\th = fnvHash(a.raw[:a.len])\n\th ^= uint64(a.typ)\n\th *= fnvPrime\n\treturn\n}\n\n// NewEndpoint creates a new Endpoint object.\n//\n// The size of raw must be less than MaxEndpointSize, otherwise this function\n// will panic.\nfunc NewEndpoint(typ EndpointType, raw []byte) (e Endpoint) {\n\te.len = len(raw)\n\tif e.len > MaxEndpointSize {\n\t\tpanic(\"raw byte length greater than MaxEndpointSize\")\n\t}\n\te.typ = typ\n\tcopy(e.raw[:], raw)\n\treturn\n}\n\n// EndpointTypeMetadata is used to register a new endpoint type.\ntype EndpointTypeMetadata struct {\n\t// Name is the string returned by an EndpointType's String function.\n\tName string\n\t// Formatter is called from an Endpoint's String function to format the raw\n\t// bytes in an Endpoint into a human-readable string.\n\tFormatter func([]byte) string\n}\n\n// EndpointType is the type of a gopacket Endpoint.  This type determines how\n// the bytes stored in the endpoint should be interpreted.\ntype EndpointType int64\n\nvar endpointTypes = map[EndpointType]EndpointTypeMetadata{}\n\n// RegisterEndpointType creates a new EndpointType and registers it globally.\n// It MUST be passed a unique number, or it will panic.  Numbers 0-999 are\n// reserved for gopacket's use.\nfunc RegisterEndpointType(num int, meta EndpointTypeMetadata) EndpointType {\n\tt := EndpointType(num)\n\tif _, ok := endpointTypes[t]; ok {\n\t\tpanic(\"Endpoint type number already in use\")\n\t}\n\tendpointTypes[t] = meta\n\treturn t\n}\n\nfunc (e EndpointType) String() string {\n\tif t, ok := endpointTypes[e]; ok {\n\t\treturn t.Name\n\t}\n\treturn strconv.Itoa(int(e))\n}\n\nfunc (a Endpoint) String() string {\n\tif t, ok := endpointTypes[a.typ]; ok && t.Formatter != nil {\n\t\treturn t.Formatter(a.raw[:a.len])\n\t}\n\treturn fmt.Sprintf(\"%v:%v\", a.typ, a.raw)\n}\n\n// Flow represents the direction of traffic for a packet layer, as a source and destination Endpoint.\n// Flows are usable as map keys.\ntype Flow struct {\n\ttyp        EndpointType\n\tslen, dlen int\n\tsrc, dst   [MaxEndpointSize]byte\n}\n\n// FlowFromEndpoints creates a new flow by pasting together two endpoints.\n// The endpoints must have the same EndpointType, or this function will return\n// an error.\nfunc FlowFromEndpoints(src, dst Endpoint) (_ Flow, err error) {\n\tif src.typ != dst.typ {\n\t\terr = fmt.Errorf(\"Mismatched endpoint types: %v->%v\", src.typ, dst.typ)\n\t\treturn\n\t}\n\treturn Flow{src.typ, src.len, dst.len, src.raw, dst.raw}, nil\n}\n\n// FastHash provides a quick hashing function for a flow, useful if you'd\n// like to split up flows by modulos or other load-balancing techniques.\n// It uses a variant of Fowler-Noll-Vo hashing, and is guaranteed to collide\n// with its reverse flow.  IE: the flow A->B will have the same hash as the flow\n// B->A.\n//\n// The output of FastHash is not guaranteed to remain the same through future\n// code revisions, so should not be used to key values in persistent storage.\nfunc (f Flow) FastHash() (h uint64) {\n\t// This combination must be commutative.  We don't use ^, since that would\n\t// give the same hash for all A->A flows.\n\th = fnvHash(f.src[:f.slen]) + fnvHash(f.dst[:f.dlen])\n\th ^= uint64(f.typ)\n\th *= fnvPrime\n\treturn\n}\n\n// String returns a human-readable representation of this flow, in the form\n// \"Src->Dst\"\nfunc (f Flow) String() string {\n\ts, d := f.Endpoints()\n\treturn fmt.Sprintf(\"%v->%v\", s, d)\n}\n\n// EndpointType returns the EndpointType for this Flow.\nfunc (f Flow) EndpointType() EndpointType {\n\treturn f.typ\n}\n\n// Endpoints returns the two Endpoints for this flow.\nfunc (f Flow) Endpoints() (src, dst Endpoint) {\n\treturn Endpoint{f.typ, f.slen, f.src}, Endpoint{f.typ, f.dlen, f.dst}\n}\n\n// Src returns the source Endpoint for this flow.\nfunc (f Flow) Src() (src Endpoint) {\n\tsrc, _ = f.Endpoints()\n\treturn\n}\n\n// Dst returns the destination Endpoint for this flow.\nfunc (f Flow) Dst() (dst Endpoint) {\n\t_, dst = f.Endpoints()\n\treturn\n}\n\n// Reverse returns a new flow with endpoints reversed.\nfunc (f Flow) Reverse() Flow {\n\treturn Flow{f.typ, f.dlen, f.slen, f.dst, f.src}\n}\n\n// NewFlow creates a new flow.\n//\n// src and dst must have length <= MaxEndpointSize, otherwise NewFlow will\n// panic.\nfunc NewFlow(t EndpointType, src, dst []byte) (f Flow) {\n\tf.slen = len(src)\n\tf.dlen = len(dst)\n\tif f.slen > MaxEndpointSize || f.dlen > MaxEndpointSize {\n\t\tpanic(\"flow raw byte length greater than MaxEndpointSize\")\n\t}\n\tf.typ = t\n\tcopy(f.src[:], src)\n\tcopy(f.dst[:], dst)\n\treturn\n}\n\n// EndpointInvalid is an endpoint type used for invalid endpoints, IE endpoints\n// that are specified incorrectly during creation.\nvar EndpointInvalid = RegisterEndpointType(0, EndpointTypeMetadata{Name: \"invalid\", Formatter: func(b []byte) string {\n\treturn fmt.Sprintf(\"%v\", b)\n}})\n\n// InvalidEndpoint is a singleton Endpoint of type EndpointInvalid.\nvar InvalidEndpoint = NewEndpoint(EndpointInvalid, nil)\n\n// InvalidFlow is a singleton Flow of type EndpointInvalid.\nvar InvalidFlow = NewFlow(EndpointInvalid, nil, nil)\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/gc",
    "content": "#!/bin/bash\n# Copyright 2012 Google, Inc. All rights reserved.\n\n# This script provides a simple way to run benchmarks against previous code and\n# keep a log of how benchmarks change over time.  When used with the --benchmark\n# flag, it runs benchmarks from the current code and from the last commit run\n# with --benchmark, then stores the results in the git commit description.  We\n# rerun the old benchmarks along with the new ones, since there's no guarantee\n# that git commits will happen on the same machine, so machine differences could\n# cause wildly inaccurate results.\n#\n# If you're making changes to 'gopacket' which could cause performance changes,\n# you may be requested to use this commit script to make sure your changes don't\n# have large detrimental effects (or to show off how awesome your performance\n# improvements are).\n#\n# If not run with the --benchmark flag, this script is still very useful... it\n# makes sure all the correct go formatting, building, and testing work as\n# expected.\n\nfunction Usage {\n  cat <<EOF\nUSAGE:  $0 [--benchmark regexp] [--root] [--gen] <git commit flags...>\n\n--benchmark:  Run benchmark comparisons against last benchmark'd commit\n--root:  Run tests that require root priviledges\n--gen:  Generate code for MACs/ports by pulling down external data\n\nNote, some 'git commit' flags are necessary, if all else fails, pass in -a\nEOF\n  exit 1\n}\n\nBENCH=\"\"\nGEN=\"\"\nROOT=\"\"\nwhile [ ! -z \"$1\" ]; do\n  case \"$1\" in\n    \"--benchmark\")\n      BENCH=\"$2\"\n      shift\n      shift\n      ;;\n    \"--gen\")\n      GEN=\"yes\"\n      shift\n      ;;\n    \"--root\")\n      ROOT=\"yes\"\n      shift\n      ;;\n    \"--help\")\n      Usage\n      ;;\n    \"-h\")\n      Usage\n      ;;\n    \"help\")\n      Usage\n      ;;\n    *)\n      break\n      ;;\n  esac\ndone\n\nfunction Root {\n  if [ ! -z \"$ROOT\" ]; then\n    local exec=\"$1\"\n    # Some folks (like me) keep source code in places inaccessible by root (like\n    # NFS), so to make sure things run smoothly we copy them to a /tmp location.\n    local tmpfile=\"$(mktemp -t gopacket_XXXXXXXX)\"\n    echo \"Running root test executable $exec as $tmpfile\"\n    cp \"$exec\" \"$tmpfile\"\n    chmod a+x \"$tmpfile\"\n    shift\n    sudo \"$tmpfile\" \"$@\"\n  fi\n}\n\nif [ \"$#\" -eq \"0\" ]; then\n  Usage\nfi\n\ncd $(dirname $0)\n\n# Check for copyright notices.\nfor filename in $(find ./ -type f -name '*.go'); do\n  if ! head -n 1 \"$filename\" | grep -q Copyright; then\n    echo \"File '$filename' may not have copyright notice\"\n    exit 1\n  fi\ndone\n\nset -e\nset -x\n\nif [ ! -z \"$ROOT\" ]; then\n  echo \"Running SUDO to get root priviledges for root tests\"\n  sudo echo \"have root\"\nfi\n\nif [ ! -z \"$GEN\" ]; then\n  pushd macs\n  go run gen.go | gofmt > valid_mac_prefixes.go\n  popd\n  pushd layers\n  go run gen.go | gofmt > iana_ports.go\n  go run gen2.go | gofmt > enums_generated.go\n  popd\nfi\n\n# Make sure everything is formatted, compiles, and tests pass.\ngo fmt ./...\ngo test -i ./... 2>/dev/null >/dev/null || true\ngo test\ngo build\npushd examples/bytediff\ngo build\npopd\nif [ -f /usr/include/pcap.h ]; then\n  pushd pcap\n  go test ./...\n  go build ./...\n  go build pcap_tester.go\n  Root pcap_tester --mode=basic\n  Root pcap_tester --mode=filtered\n  Root pcap_tester --mode=timestamp || echo \"You might not support timestamp sources\"\n  popd\n  pushd examples/afpacket\n  go build\n  popd\n  pushd examples/pcapdump\n  go build\n  popd\n  pushd examples/arpscan\n  go build\n  popd\n  pushd examples/bidirectional\n  go build\n  popd\n  pushd examples/synscan\n  go build\n  popd\n  pushd examples/httpassembly\n  go build\n  popd\n  pushd examples/statsassembly\n  go build\n  popd\nfi\npushd macs\ngo test ./...\ngofmt -w gen.go\ngo build gen.go\npopd\npushd tcpassembly\ngo test ./...\npopd\npushd reassembly\ngo test ./...\npopd\npushd layers\ngofmt -w gen.go\ngo build gen.go\ngo test ./...\npopd\npushd pcapgo\ngo test ./...\ngo build ./...\npopd\nif [ -f /usr/include/linux/if_packet.h ]; then\n  if grep -q TPACKET_V3 /usr/include/linux/if_packet.h; then\n    pushd afpacket\n    go build ./...\n    go test ./...\n    popd\n  fi\nfi\nif [ -f /usr/include/pfring.h ]; then\n  pushd pfring\n  go test ./...\n  go build ./...\n  popd\n  pushd examples/pfdump\n  go build\n  popd\nfi\npushd ip4defrag\ngo test ./...\npopd\npushd defrag\ngo test ./...\npopd\n\nfor travis_script in `ls .travis.*.sh`; do\n  ./$travis_script\ndone\n\n# Run our initial commit\ngit commit \"$@\"\n\nif [ -z \"$BENCH\" ]; then\n  set +x\n  echo \"We're not benchmarking and we've committed... we're done!\"\n  exit\nfi\n\n### If we get here, we want to run benchmarks from current commit, and compare\n### then to benchmarks from the last --benchmark commit.\n\n# Get our current branch.\nBRANCH=\"$(git branch | grep '^*' | awk '{print $2}')\"\n\n# File we're going to build our commit description in.\nCOMMIT_FILE=\"$(mktemp /tmp/tmp.XXXXXXXX)\"\n\n# Add the word \"BENCH\" to the start of the git commit.\necho -n \"BENCH \" > $COMMIT_FILE\n\n# Get the current description... there must be an easier way.\ngit log -n 1 | grep '^ ' | sed 's/^    //' >> $COMMIT_FILE\n\n# Get the commit sha for the last benchmark commit\nPREV=$(git log -n 1 --grep='BENCHMARK_MARKER_DO_NOT_CHANGE' | head -n 1 | awk '{print $2}')\n\n## Run current benchmarks\n\ncat >> $COMMIT_FILE <<EOF\n\n\n----------------------------------------------------------\nBENCHMARK_MARKER_DO_NOT_CHANGE\n----------------------------------------------------------\n\nGo version $(go version)\n\n\nTEST BENCHMARKS \"$BENCH\"\nEOF\n# go seems to have trouble with 'go test --bench=. ./...'\ngo test --test.bench=\"$BENCH\" 2>&1 | tee -a $COMMIT_FILE\npushd layers\ngo test --test.bench=\"$BENCH\" 2>&1 | tee -a $COMMIT_FILE\npopd\ncat >> $COMMIT_FILE <<EOF\n\n\nPCAP BENCHMARK\nEOF\nif [ \"$BENCH\" -eq \".*\" ]; then\n  go run pcap/gopacket_benchmark/*.go 2>&1 | tee -a $COMMIT_FILE\nfi\n\n\n\n## Reset to last benchmark commit, run benchmarks\n\ngit checkout $PREV\n\ncat >> $COMMIT_FILE <<EOF\n----------------------------------------------------------\nBENCHMARKING AGAINST COMMIT $PREV\n----------------------------------------------------------\n\n\nOLD TEST BENCHMARKS\nEOF\n# go seems to have trouble with 'go test --bench=. ./...'\ngo test --test.bench=\"$BENCH\" 2>&1 | tee -a $COMMIT_FILE\npushd layers\ngo test --test.bench=\"$BENCH\" 2>&1 | tee -a $COMMIT_FILE\npopd\ncat >> $COMMIT_FILE <<EOF\n\n\nOLD PCAP BENCHMARK\nEOF\nif [ \"$BENCH\" -eq \".*\" ]; then\n  go run pcap/gopacket_benchmark/*.go 2>&1 | tee -a $COMMIT_FILE\nfi\n\n\n\n## Reset back to the most recent commit, edit the commit message by appending\n## benchmark results.\ngit checkout $BRANCH\ngit commit --amend -F $COMMIT_FILE\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layerclass.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage gopacket\n\n// LayerClass is a set of LayerTypes, used for grabbing one of a number of\n// different types from a packet.\ntype LayerClass interface {\n\t// Contains returns true if the given layer type should be considered part\n\t// of this layer class.\n\tContains(LayerType) bool\n\t// LayerTypes returns the set of all layer types in this layer class.\n\t// Note that this may not be a fast operation on all LayerClass\n\t// implementations.\n\tLayerTypes() []LayerType\n}\n\n// Contains implements LayerClass.\nfunc (l LayerType) Contains(a LayerType) bool {\n\treturn l == a\n}\n\n// LayerTypes implements LayerClass.\nfunc (l LayerType) LayerTypes() []LayerType {\n\treturn []LayerType{l}\n}\n\n// LayerClassSlice implements a LayerClass with a slice.\ntype LayerClassSlice []bool\n\n// Contains returns true if the given layer type should be considered part\n// of this layer class.\nfunc (s LayerClassSlice) Contains(t LayerType) bool {\n\treturn int(t) < len(s) && s[t]\n}\n\n// LayerTypes returns all layer types in this LayerClassSlice.\n// Because of LayerClassSlice's implementation, this could be quite slow.\nfunc (s LayerClassSlice) LayerTypes() (all []LayerType) {\n\tfor i := 0; i < len(s); i++ {\n\t\tif s[i] {\n\t\t\tall = append(all, LayerType(i))\n\t\t}\n\t}\n\treturn\n}\n\n// NewLayerClassSlice creates a new LayerClassSlice by creating a slice of\n// size max(types) and setting slice[t] to true for each type t.  Note, if\n// you implement your own LayerType and give it a high value, this WILL create\n// a very large slice.\nfunc NewLayerClassSlice(types []LayerType) LayerClassSlice {\n\tvar max LayerType\n\tfor _, typ := range types {\n\t\tif typ > max {\n\t\t\tmax = typ\n\t\t}\n\t}\n\tt := make([]bool, int(max+1))\n\tfor _, typ := range types {\n\t\tt[typ] = true\n\t}\n\treturn t\n}\n\n// LayerClassMap implements a LayerClass with a map.\ntype LayerClassMap map[LayerType]bool\n\n// Contains returns true if the given layer type should be considered part\n// of this layer class.\nfunc (m LayerClassMap) Contains(t LayerType) bool {\n\treturn m[t]\n}\n\n// LayerTypes returns all layer types in this LayerClassMap.\nfunc (m LayerClassMap) LayerTypes() (all []LayerType) {\n\tfor t := range m {\n\t\tall = append(all, t)\n\t}\n\treturn\n}\n\n// NewLayerClassMap creates a LayerClassMap and sets map[t] to true for each\n// type in types.\nfunc NewLayerClassMap(types []LayerType) LayerClassMap {\n\tm := LayerClassMap{}\n\tfor _, typ := range types {\n\t\tm[typ] = true\n\t}\n\treturn m\n}\n\n// NewLayerClass creates a LayerClass, attempting to be smart about which type\n// it creates based on which types are passed in.\nfunc NewLayerClass(types []LayerType) LayerClass {\n\tfor _, typ := range types {\n\t\tif typ > maxLayerType {\n\t\t\t// NewLayerClassSlice could create a very large object, so instead create\n\t\t\t// a map.\n\t\t\treturn NewLayerClassMap(types)\n\t\t}\n\t}\n\treturn NewLayerClassSlice(types)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/.lint_blacklist",
    "content": "dot11.go\neap.go\nendpoints.go\nenums_generated.go\nenums.go\nethernet.go\ngeneve.go\nicmp4.go\nicmp6.go\nigmp.go\nip4.go\nip6.go\nlayertypes.go\nlinux_sll.go\nllc.go\nlldp.go\nmpls.go\nndp.go\nntp.go\nospf.go\npflog.go\npppoe.go\nprism.go\nradiotap.go\nrudp.go\nsctp.go\nsflow.go\ntcp.go\ntcpip.go\ntls.go\ntls_alert.go\ntls_appdata.go\ntls_cipherspec.go\ntls_hanshake.go\ntls_test.go\nudp.go\nudplite.go\nusb.go\nvrrp.go\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/arp.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n// Copyright 2009-2011 Andreas Krennmair. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// Potential values for ARP.Operation.\nconst (\n\tARPRequest = 1\n\tARPReply   = 2\n)\n\n// ARP is a ARP packet header.\ntype ARP struct {\n\tBaseLayer\n\tAddrType          LinkType\n\tProtocol          EthernetType\n\tHwAddressSize     uint8\n\tProtAddressSize   uint8\n\tOperation         uint16\n\tSourceHwAddress   []byte\n\tSourceProtAddress []byte\n\tDstHwAddress      []byte\n\tDstProtAddress    []byte\n}\n\n// LayerType returns LayerTypeARP\nfunc (arp *ARP) LayerType() gopacket.LayerType { return LayerTypeARP }\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (arp *ARP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 8 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"ARP length %d too short\", len(data))\n\t}\n\tarp.AddrType = LinkType(binary.BigEndian.Uint16(data[0:2]))\n\tarp.Protocol = EthernetType(binary.BigEndian.Uint16(data[2:4]))\n\tarp.HwAddressSize = data[4]\n\tarp.ProtAddressSize = data[5]\n\tarp.Operation = binary.BigEndian.Uint16(data[6:8])\n\tarpLength := 8 + 2*arp.HwAddressSize + 2*arp.ProtAddressSize\n\tif len(data) < int(arpLength) {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"ARP length %d too short, %d expected\", len(data), arpLength)\n\t}\n\tarp.SourceHwAddress = data[8 : 8+arp.HwAddressSize]\n\tarp.SourceProtAddress = data[8+arp.HwAddressSize : 8+arp.HwAddressSize+arp.ProtAddressSize]\n\tarp.DstHwAddress = data[8+arp.HwAddressSize+arp.ProtAddressSize : 8+2*arp.HwAddressSize+arp.ProtAddressSize]\n\tarp.DstProtAddress = data[8+2*arp.HwAddressSize+arp.ProtAddressSize : 8+2*arp.HwAddressSize+2*arp.ProtAddressSize]\n\n\tarp.Contents = data[:arpLength]\n\tarp.Payload = data[arpLength:]\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (arp *ARP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tsize := 8 + len(arp.SourceHwAddress) + len(arp.SourceProtAddress) + len(arp.DstHwAddress) + len(arp.DstProtAddress)\n\tbytes, err := b.PrependBytes(size)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif opts.FixLengths {\n\t\tif len(arp.SourceHwAddress) != len(arp.DstHwAddress) {\n\t\t\treturn errors.New(\"mismatched hardware address sizes\")\n\t\t}\n\t\tarp.HwAddressSize = uint8(len(arp.SourceHwAddress))\n\t\tif len(arp.SourceProtAddress) != len(arp.DstProtAddress) {\n\t\t\treturn errors.New(\"mismatched prot address sizes\")\n\t\t}\n\t\tarp.ProtAddressSize = uint8(len(arp.SourceProtAddress))\n\t}\n\tbinary.BigEndian.PutUint16(bytes, uint16(arp.AddrType))\n\tbinary.BigEndian.PutUint16(bytes[2:], uint16(arp.Protocol))\n\tbytes[4] = arp.HwAddressSize\n\tbytes[5] = arp.ProtAddressSize\n\tbinary.BigEndian.PutUint16(bytes[6:], arp.Operation)\n\tstart := 8\n\tfor _, addr := range [][]byte{\n\t\tarp.SourceHwAddress,\n\t\tarp.SourceProtAddress,\n\t\tarp.DstHwAddress,\n\t\tarp.DstProtAddress,\n\t} {\n\t\tcopy(bytes[start:], addr)\n\t\tstart += len(addr)\n\t}\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (arp *ARP) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeARP\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (arp *ARP) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\nfunc decodeARP(data []byte, p gopacket.PacketBuilder) error {\n\n\tarp := &ARP{}\n\treturn decodingLayerDecoder(arp, data, p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/asf.go",
    "content": "// Copyright 2019 The GoPacket Authors. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license that can be found\n// in the LICENSE file in the root of the source tree.\n\npackage layers\n\n// This file implements the ASF RMCP payload specified in section 3.2.2.3 of\n// https://www.dmtf.org/sites/default/files/standards/documents/DSP0136.pdf\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\n\t\"github.com/google/gopacket\"\n)\n\nconst (\n\t// ASFRMCPEnterprise is the IANA-assigned Enterprise Number of the ASF-RMCP.\n\tASFRMCPEnterprise uint32 = 4542\n)\n\n// ASFDataIdentifier encapsulates fields used to uniquely identify the format of\n// the data block.\n//\n// While the enterprise number is almost always 4542 (ASF-RMCP), we support\n// registering layers using structs of this type as a key in case any users are\n// using OEM-extensions.\ntype ASFDataIdentifier struct {\n\n\t// Enterprise is the IANA Enterprise Number associated with the entity that\n\t// defines the message type. A list can be found at\n\t// https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers.\n\t// This can be thought of as the namespace for the message type.\n\tEnterprise uint32\n\n\t// Type is the message type, defined by the entity associated with the\n\t// enterprise above. No pressure, but in the context of EN 4542, 1 byte is\n\t// the difference between sending a ping and telling a machine to do an\n\t// unconditional power down (0x80 and 0x12 respectively).\n\tType uint8\n}\n\n// LayerType returns the payload layer type corresponding to an ASF message\n// type.\nfunc (a ASFDataIdentifier) LayerType() gopacket.LayerType {\n\tif lt := asfDataLayerTypes[a]; lt != 0 {\n\t\treturn lt\n\t}\n\n\t// some layer types don't have a payload, e.g. ASF-RMCP Presence Ping.\n\treturn gopacket.LayerTypePayload\n}\n\n// RegisterASFLayerType allows specifying that the data block of ASF packets\n// with a given enterprise number and type should be processed by a given layer\n// type. This overrides any existing registrations, including defaults.\nfunc RegisterASFLayerType(a ASFDataIdentifier, l gopacket.LayerType) {\n\tasfDataLayerTypes[a] = l\n}\n\nvar (\n\t// ASFDataIdentifierPresencePong is the message type of the response to a\n\t// Presence Ping message. It indicates the sender is ASF-RMCP-aware.\n\tASFDataIdentifierPresencePong = ASFDataIdentifier{\n\t\tEnterprise: ASFRMCPEnterprise,\n\t\tType:       0x40,\n\t}\n\n\t// ASFDataIdentifierPresencePing is a message type sent to a managed client\n\t// to solicit a Presence Pong response. Clients may ignore this if the RMCP\n\t// version is unsupported. Sending this message with a sequence number <255\n\t// is the recommended way of finding out whether an implementation sends\n\t// RMCP ACKs (e.g. iDRAC does, Super Micro does not).\n\t//\n\t// Systems implementing IPMI must respond to this ping to conform to the\n\t// spec, so it is a good substitute for an ICMP ping.\n\tASFDataIdentifierPresencePing = ASFDataIdentifier{\n\t\tEnterprise: ASFRMCPEnterprise,\n\t\tType:       0x80,\n\t}\n\n\t// asfDataLayerTypes is used to find the next layer for a given ASF header.\n\tasfDataLayerTypes = map[ASFDataIdentifier]gopacket.LayerType{\n\t\tASFDataIdentifierPresencePong: LayerTypeASFPresencePong,\n\t}\n)\n\n// ASF defines ASF's generic RMCP message Data block format. See section\n// 3.2.2.3.\ntype ASF struct {\n\tBaseLayer\n\tASFDataIdentifier\n\n\t// Tag is used to match request/response pairs. The tag of a response is set\n\t// to that of the message it is responding to. If a message is\n\t// unidirectional, i.e. not part of a request/response pair, this is set to\n\t// 255.\n\tTag uint8\n\n\t// 1 byte reserved, set to 0x00.\n\n\t// Length is the length of this layer's payload in bytes.\n\tLength uint8\n}\n\n// LayerType returns LayerTypeASF. It partially satisfies Layer and\n// SerializableLayer.\nfunc (*ASF) LayerType() gopacket.LayerType {\n\treturn LayerTypeASF\n}\n\n// CanDecode returns LayerTypeASF. It partially satisfies DecodingLayer.\nfunc (a *ASF) CanDecode() gopacket.LayerClass {\n\treturn a.LayerType()\n}\n\n// DecodeFromBytes makes the layer represent the provided bytes. It partially\n// satisfies DecodingLayer.\nfunc (a *ASF) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 8 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"invalid ASF data header, length %v less than 8\",\n\t\t\tlen(data))\n\t}\n\n\ta.BaseLayer.Contents = data[:8]\n\ta.BaseLayer.Payload = data[8:]\n\n\ta.Enterprise = binary.BigEndian.Uint32(data[:4])\n\ta.Type = uint8(data[4])\n\ta.Tag = uint8(data[5])\n\t// 1 byte reserved\n\ta.Length = uint8(data[7])\n\treturn nil\n}\n\n// NextLayerType returns the layer type corresponding to the message type of\n// this ASF data layer. This partially satisfies DecodingLayer.\nfunc (a *ASF) NextLayerType() gopacket.LayerType {\n\treturn a.ASFDataIdentifier.LayerType()\n}\n\n// SerializeTo writes the serialized fom of this layer into the SerializeBuffer,\n// partially satisfying SerializableLayer.\nfunc (a *ASF) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tpayload := b.Bytes()\n\tbytes, err := b.PrependBytes(8)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbinary.BigEndian.PutUint32(bytes[:4], a.Enterprise)\n\tbytes[4] = uint8(a.Type)\n\tbytes[5] = a.Tag\n\tbytes[6] = 0x00\n\tif opts.FixLengths {\n\t\ta.Length = uint8(len(payload))\n\t}\n\tbytes[7] = a.Length\n\treturn nil\n}\n\n// decodeASF decodes the byte slice into an RMCP-ASF data struct.\nfunc decodeASF(data []byte, p gopacket.PacketBuilder) error {\n\treturn decodingLayerDecoder(&ASF{}, data, p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/asf_presencepong.go",
    "content": "// Copyright 2019 The GoPacket Authors. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license that can be found\n// in the LICENSE file in the root of the source tree.\n\npackage layers\n\n// This file implements the RMCP ASF Presence Pong message, specified in section\n// 3.2.4.3 of\n// https://www.dmtf.org/sites/default/files/standards/documents/DSP0136.pdf. It\n// also contains non-competing elements from IPMI v2.0, specified in section\n// 13.2.4 of\n// https://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/ipmi-intelligent-platform-mgt-interface-spec-2nd-gen-v2-0-spec-update.pdf.\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\n\t\"github.com/google/gopacket\"\n)\n\ntype (\n\t// ASFEntity is the type of individual entities that a Presence Pong\n\t// response can indicate support of. The entities currently implemented by\n\t// the spec are IPMI and ASFv1.\n\tASFEntity uint8\n\n\t// ASFInteraction is the type of individual interactions that a Presence\n\t// Pong response can indicate support for. The interactions currently\n\t// implemented by the spec are RMCP security extensions. Although not\n\t// specified, IPMI uses this field to indicate support for DASH, which is\n\t// supported as well.\n\tASFInteraction uint8\n)\n\nconst (\n\t// ASFDCMIEnterprise is the IANA-assigned Enterprise Number of the Data\n\t// Center Manageability Interface Forum. The Presence Pong response's\n\t// Enterprise field being set to this value indicates support for DCMI. The\n\t// DCMI spec regards the OEM field as reserved, so these should be null.\n\tASFDCMIEnterprise uint32 = 36465\n\n\t// ASFPresencePongEntityIPMI ANDs with Presence Pong's supported entities\n\t// field if the managed system supports IPMI.\n\tASFPresencePongEntityIPMI ASFEntity = 1 << 7\n\n\t// ASFPresencePongEntityASFv1 ANDs with Presence Pong's supported entities\n\t// field if the managed system supports ASF v1.0.\n\tASFPresencePongEntityASFv1 ASFEntity = 1\n\n\t// ASFPresencePongInteractionSecurityExtensions ANDs with Presence Pong's\n\t// supported interactions field if the managed system supports RMCP v2.0\n\t// security extensions. See section 3.2.3.\n\tASFPresencePongInteractionSecurityExtensions ASFInteraction = 1 << 7\n\n\t// ASFPresencePongInteractionDASH ANDs with Presence Pong's supported\n\t// interactions field if the managed system supports DMTF DASH. See\n\t// https://www.dmtf.org/standards/dash.\n\tASFPresencePongInteractionDASH ASFInteraction = 1 << 5\n)\n\n// ASFPresencePong defines the structure of a Presence Pong message's payload.\n// See section 3.2.4.3.\ntype ASFPresencePong struct {\n\tBaseLayer\n\n\t// Enterprise is the IANA Enterprise Number of an entity that has defined\n\t// OEM-specific capabilities for the managed client. If no such capabilities\n\t// exist, this is set to ASF's IANA Enterprise Number.\n\tEnterprise uint32\n\n\t// OEM identifies OEM-specific capabilities. Its structure is defined by the\n\t// OEM. This is set to 0s if no OEM-specific capabilities exist. This\n\t// implementation does not change byte order from the wire for this field.\n\tOEM [4]byte\n\n\t// We break out entities and interactions into separate booleans as\n\t// discovery is the entire point of this type of message, so we assume they\n\t// are accessed. It also makes gopacket's default layer printing more\n\t// useful.\n\n\t// IPMI is true if IPMI is supported by the managed system. There is no\n\t// explicit version in the specification, however given the dates, this is\n\t// assumed to be IPMI v1.0.  Support for IPMI is contained in the \"supported\n\t// entities\" field of the presence pong payload.\n\tIPMI bool\n\n\t// ASFv1 indicates support for ASF v1.0. This seems somewhat redundant as\n\t// ASF must be supported in order to receive a response. This is contained\n\t// in the \"supported entities\" field of the presence pong payload.\n\tASFv1 bool\n\n\t// SecurityExtensions indicates support for RMCP Security Extensions,\n\t// specified in ASF v2.0. This will always be false for v1.x\n\t// implementations. This is contained in the \"supported interactions\" field\n\t// of the presence pong payload. This field is defined in ASF v1.0, but has\n\t// no useful value.\n\tSecurityExtensions bool\n\n\t// DASH is true if DMTF DASH is supported. This is not specified in ASF\n\t// v2.0, but in IPMI v2.0, however the former does not preclude it, so we\n\t// support it.\n\tDASH bool\n\n\t// 6 bytes reserved after the entities and interactions fields, set to 0s.\n}\n\n// SupportsDCMI returns whether the Presence Pong message indicates support for\n// the Data Center Management Interface, which is an extension of IPMI v2.0.\nfunc (a *ASFPresencePong) SupportsDCMI() bool {\n\treturn a.Enterprise == ASFDCMIEnterprise && a.IPMI && a.ASFv1\n}\n\n// LayerType returns LayerTypeASFPresencePong. It partially satisfies Layer and\n// SerializableLayer.\nfunc (*ASFPresencePong) LayerType() gopacket.LayerType {\n\treturn LayerTypeASFPresencePong\n}\n\n// CanDecode returns LayerTypeASFPresencePong. It partially satisfies\n// DecodingLayer.\nfunc (a *ASFPresencePong) CanDecode() gopacket.LayerClass {\n\treturn a.LayerType()\n}\n\n// DecodeFromBytes makes the layer represent the provided bytes. It partially\n// satisfies DecodingLayer.\nfunc (a *ASFPresencePong) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 16 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"invalid ASF presence pong payload, length %v less than 16\",\n\t\t\tlen(data))\n\t}\n\n\ta.BaseLayer.Contents = data[:16]\n\ta.BaseLayer.Payload = data[16:]\n\n\ta.Enterprise = binary.BigEndian.Uint32(data[:4])\n\tcopy(a.OEM[:], data[4:8]) // N.B. no byte order change\n\ta.IPMI = data[8]&uint8(ASFPresencePongEntityIPMI) != 0\n\ta.ASFv1 = data[8]&uint8(ASFPresencePongEntityASFv1) != 0\n\ta.SecurityExtensions = data[9]&uint8(ASFPresencePongInteractionSecurityExtensions) != 0\n\ta.DASH = data[9]&uint8(ASFPresencePongInteractionDASH) != 0\n\t// ignore remaining 6 bytes; should be set to 0s\n\treturn nil\n}\n\n// NextLayerType returns LayerTypePayload, as there are no further layers to\n// decode. This partially satisfies DecodingLayer.\nfunc (a *ASFPresencePong) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\n// SerializeTo writes the serialized fom of this layer into the SerializeBuffer,\n// partially satisfying SerializableLayer.\nfunc (a *ASFPresencePong) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {\n\tbytes, err := b.PrependBytes(16)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbinary.BigEndian.PutUint32(bytes[:4], a.Enterprise)\n\n\tcopy(bytes[4:8], a.OEM[:])\n\n\tbytes[8] = 0\n\tif a.IPMI {\n\t\tbytes[8] |= uint8(ASFPresencePongEntityIPMI)\n\t}\n\tif a.ASFv1 {\n\t\tbytes[8] |= uint8(ASFPresencePongEntityASFv1)\n\t}\n\n\tbytes[9] = 0\n\tif a.SecurityExtensions {\n\t\tbytes[9] |= uint8(ASFPresencePongInteractionSecurityExtensions)\n\t}\n\tif a.DASH {\n\t\tbytes[9] |= uint8(ASFPresencePongInteractionDASH)\n\t}\n\n\t// zero-out remaining 6 bytes\n\tfor i := 10; i < len(bytes); i++ {\n\t\tbytes[i] = 0x00\n\t}\n\n\treturn nil\n}\n\n// decodeASFPresencePong decodes the byte slice into an RMCP-ASF Presence Pong\n// struct.\nfunc decodeASFPresencePong(data []byte, p gopacket.PacketBuilder) error {\n\treturn decodingLayerDecoder(&ASFPresencePong{}, data, p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/base.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"github.com/google/gopacket\"\n)\n\n// BaseLayer is a convenience struct which implements the LayerData and\n// LayerPayload functions of the Layer interface.\ntype BaseLayer struct {\n\t// Contents is the set of bytes that make up this layer.  IE: for an\n\t// Ethernet packet, this would be the set of bytes making up the\n\t// Ethernet frame.\n\tContents []byte\n\t// Payload is the set of bytes contained by (but not part of) this\n\t// Layer.  Again, to take Ethernet as an example, this would be the\n\t// set of bytes encapsulated by the Ethernet protocol.\n\tPayload []byte\n}\n\n// LayerContents returns the bytes of the packet layer.\nfunc (b *BaseLayer) LayerContents() []byte { return b.Contents }\n\n// LayerPayload returns the bytes contained within the packet layer.\nfunc (b *BaseLayer) LayerPayload() []byte { return b.Payload }\n\ntype layerDecodingLayer interface {\n\tgopacket.Layer\n\tDecodeFromBytes([]byte, gopacket.DecodeFeedback) error\n\tNextLayerType() gopacket.LayerType\n}\n\nfunc decodingLayerDecoder(d layerDecodingLayer, data []byte, p gopacket.PacketBuilder) error {\n\terr := d.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\tp.AddLayer(d)\n\tnext := d.NextLayerType()\n\tif next == gopacket.LayerTypeZero {\n\t\treturn nil\n\t}\n\treturn p.NextDecoder(next)\n}\n\n// hacky way to zero out memory... there must be a better way?\nvar lotsOfZeros [1024]byte\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/bfd.go",
    "content": "// Copyright 2017 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n//\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// BFD Control Packet Format\n// -------------------------\n// The current version of BFD's RFC (RFC 5880) contains the following\n// diagram for the BFD Control packet format:\n//\n//      0                   1                   2                   3\n//      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |Vers |  Diag   |Sta|P|F|C|A|D|M|  Detect Mult  |    Length     |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                       My Discriminator                        |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                      Your Discriminator                       |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                    Desired Min TX Interval                    |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                   Required Min RX Interval                    |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                 Required Min Echo RX Interval                 |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//\n//     An optional Authentication Section MAY be present:\n//\n//      0                   1                   2                   3\n//      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |   Auth Type   |   Auth Len    |    Authentication Data...     |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//\n//\n//     Simple Password Authentication Section Format\n//     ---------------------------------------------\n//      0                   1                   2                   3\n//      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |   Auth Type   |   Auth Len    |  Auth Key ID  |  Password...  |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                              ...                              |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//\n//\n//     Keyed MD5 and Meticulous Keyed MD5 Authentication Section Format\n//     ----------------------------------------------------------------\n//      0                   1                   2                   3\n//      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |   Auth Type   |   Auth Len    |  Auth Key ID  |   Reserved    |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                        Sequence Number                        |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                      Auth Key/Digest...                       |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                              ...                              |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//\n//\n//     Keyed SHA1 and Meticulous Keyed SHA1 Authentication Section Format\n//     ------------------------------------------------------------------\n//      0                   1                   2                   3\n//      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |   Auth Type   |   Auth Len    |  Auth Key ID  |   Reserved    |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                        Sequence Number                        |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                       Auth Key/Hash...                        |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                              ...                              |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//\n//     From https://tools.ietf.org/rfc/rfc5880.txt\nconst bfdMinimumRecordSizeInBytes int = 24\n\n// BFDVersion represents the version as decoded from the BFD control message\ntype BFDVersion uint8\n\n// BFDDiagnostic represents diagnostic infomation about a BFD session\ntype BFDDiagnostic uint8\n\n// constants that define BFDDiagnostic flags\nconst (\n\tBFDDiagnosticNone               BFDDiagnostic = 0 // No Diagnostic\n\tBFDDiagnosticTimeExpired        BFDDiagnostic = 1 // Control Detection Time Expired\n\tBFDDiagnosticEchoFailed         BFDDiagnostic = 2 // Echo Function Failed\n\tBFDDiagnosticNeighborSignalDown BFDDiagnostic = 3 // Neighbor Signaled Session Down\n\tBFDDiagnosticForwardPlaneReset  BFDDiagnostic = 4 // Forwarding Plane Reset\n\tBFDDiagnosticPathDown           BFDDiagnostic = 5 // Path Down\n\tBFDDiagnosticConcatPathDown     BFDDiagnostic = 6 // Concatenated Path Down\n\tBFDDiagnosticAdminDown          BFDDiagnostic = 7 // Administratively Down\n\tBFDDiagnosticRevConcatPathDown  BFDDiagnostic = 8 // Reverse Concatenated Path Dow\n)\n\n// String returns a string version of BFDDiagnostic\nfunc (bd BFDDiagnostic) String() string {\n\tswitch bd {\n\tdefault:\n\t\treturn \"Unknown\"\n\tcase BFDDiagnosticNone:\n\t\treturn \"None\"\n\tcase BFDDiagnosticTimeExpired:\n\t\treturn \"Control Detection Time Expired\"\n\tcase BFDDiagnosticEchoFailed:\n\t\treturn \"Echo Function Failed\"\n\tcase BFDDiagnosticNeighborSignalDown:\n\t\treturn \"Neighbor Signaled Session Down\"\n\tcase BFDDiagnosticForwardPlaneReset:\n\t\treturn \"Forwarding Plane Reset\"\n\tcase BFDDiagnosticPathDown:\n\t\treturn \"Path Down\"\n\tcase BFDDiagnosticConcatPathDown:\n\t\treturn \"Concatenated Path Down\"\n\tcase BFDDiagnosticAdminDown:\n\t\treturn \"Administratively Down\"\n\tcase BFDDiagnosticRevConcatPathDown:\n\t\treturn \"Reverse Concatenated Path Down\"\n\t}\n}\n\n// BFDState represents the state of a BFD session\ntype BFDState uint8\n\n// constants that define BFDState\nconst (\n\tBFDStateAdminDown BFDState = 0\n\tBFDStateDown      BFDState = 1\n\tBFDStateInit      BFDState = 2\n\tBFDStateUp        BFDState = 3\n)\n\n// String returns a string version of BFDState\nfunc (s BFDState) String() string {\n\tswitch s {\n\tdefault:\n\t\treturn \"Unknown\"\n\tcase BFDStateAdminDown:\n\t\treturn \"Admin Down\"\n\tcase BFDStateDown:\n\t\treturn \"Down\"\n\tcase BFDStateInit:\n\t\treturn \"Init\"\n\tcase BFDStateUp:\n\t\treturn \"Up\"\n\t}\n}\n\n// BFDDetectMultiplier represents the negotiated transmit interval,\n// multiplied by this value, provides the Detection Time for the\n// receiving system in Asynchronous mode.\ntype BFDDetectMultiplier uint8\n\n// BFDDiscriminator is a unique, nonzero discriminator value used\n// to demultiplex multiple BFD sessions between the same pair of systems.\ntype BFDDiscriminator uint32\n\n// BFDTimeInterval represents a time interval in microseconds\ntype BFDTimeInterval uint32\n\n// BFDAuthType represents the authentication used in the BFD session\ntype BFDAuthType uint8\n\n// constants that define the BFDAuthType\nconst (\n\tBFDAuthTypeNone                BFDAuthType = 0 // No Auth\n\tBFDAuthTypePassword            BFDAuthType = 1 // Simple Password\n\tBFDAuthTypeKeyedMD5            BFDAuthType = 2 // Keyed MD5\n\tBFDAuthTypeMeticulousKeyedMD5  BFDAuthType = 3 // Meticulous Keyed MD5\n\tBFDAuthTypeKeyedSHA1           BFDAuthType = 4 // Keyed SHA1\n\tBFDAuthTypeMeticulousKeyedSHA1 BFDAuthType = 5 // Meticulous Keyed SHA1\n)\n\n// String returns a string version of BFDAuthType\nfunc (at BFDAuthType) String() string {\n\tswitch at {\n\tdefault:\n\t\treturn \"Unknown\"\n\tcase BFDAuthTypeNone:\n\t\treturn \"No Authentication\"\n\tcase BFDAuthTypePassword:\n\t\treturn \"Simple Password\"\n\tcase BFDAuthTypeKeyedMD5:\n\t\treturn \"Keyed MD5\"\n\tcase BFDAuthTypeMeticulousKeyedMD5:\n\t\treturn \"Meticulous Keyed MD5\"\n\tcase BFDAuthTypeKeyedSHA1:\n\t\treturn \"Keyed SHA1\"\n\tcase BFDAuthTypeMeticulousKeyedSHA1:\n\t\treturn \"Meticulous Keyed SHA1\"\n\t}\n}\n\n// BFDAuthKeyID represents the authentication key ID in use for\n// this packet.  This allows multiple keys to be active simultaneously.\ntype BFDAuthKeyID uint8\n\n// BFDAuthSequenceNumber represents the sequence number for this packet.\n// For Keyed Authentication, this value is incremented occasionally.  For\n// Meticulous Keyed Authentication, this value is incremented for each\n// successive packet transmitted for a session.  This provides protection\n// against replay attacks.\ntype BFDAuthSequenceNumber uint32\n\n// BFDAuthData represents the authentication key or digest\ntype BFDAuthData []byte\n\n// BFDAuthHeader represents authentication data used in the BFD session\ntype BFDAuthHeader struct {\n\tAuthType       BFDAuthType\n\tKeyID          BFDAuthKeyID\n\tSequenceNumber BFDAuthSequenceNumber\n\tData           BFDAuthData\n}\n\n// Length returns the data length of the BFDAuthHeader based on the\n// authentication type\nfunc (h *BFDAuthHeader) Length() int {\n\tswitch h.AuthType {\n\tcase BFDAuthTypePassword:\n\t\treturn 3 + len(h.Data)\n\tcase BFDAuthTypeKeyedMD5, BFDAuthTypeMeticulousKeyedMD5:\n\t\treturn 8 + len(h.Data)\n\tcase BFDAuthTypeKeyedSHA1, BFDAuthTypeMeticulousKeyedSHA1:\n\t\treturn 8 + len(h.Data)\n\tdefault:\n\t\treturn 0\n\t}\n}\n\n// BFD represents a BFD control message packet whose payload contains\n// the control information required to for a BFD session.\n//\n// References\n// ----------\n//\n// Wikipedia's BFD entry:\n//     https://en.wikipedia.org/wiki/Bidirectional_Forwarding_Detection\n//     This is the best place to get an overview of BFD.\n//\n// RFC 5880 \"Bidirectional Forwarding Detection (BFD)\" (2010)\n//     https://tools.ietf.org/html/rfc5880\n//     This is the original BFD specification.\n//\n// RFC 5881 \"Bidirectional Forwarding Detection (BFD) for IPv4 and IPv6 (Single Hop)\" (2010)\n//     https://tools.ietf.org/html/rfc5881\n//     Describes the use of the Bidirectional Forwarding Detection (BFD)\n//     protocol over IPv4 and IPv6 for single IP hops.\ntype BFD struct {\n\tBaseLayer // Stores the packet bytes and payload bytes.\n\n\tVersion                   BFDVersion          // Version of the BFD protocol.\n\tDiagnostic                BFDDiagnostic       // Diagnostic code for last state change\n\tState                     BFDState            // Current state\n\tPoll                      bool                // Requesting verification\n\tFinal                     bool                // Responding to a received BFD Control packet that had the Poll (P) bit set.\n\tControlPlaneIndependent   bool                // BFD implementation does not share fate with its control plane\n\tAuthPresent               bool                // Authentication Section is present and the session is to be authenticated\n\tDemand                    bool                // Demand mode is active\n\tMultipoint                bool                // For future point-to-multipoint extensions. Must always be zero\n\tDetectMultiplier          BFDDetectMultiplier // Detection time multiplier\n\tMyDiscriminator           BFDDiscriminator    // A unique, nonzero discriminator value\n\tYourDiscriminator         BFDDiscriminator    // discriminator received from the remote system.\n\tDesiredMinTxInterval      BFDTimeInterval     // Minimum interval, in microseconds,  the local system would like to use when transmitting BFD Control packets\n\tRequiredMinRxInterval     BFDTimeInterval     // Minimum interval, in microseconds, between received BFD Control packets that this system is capable of supporting\n\tRequiredMinEchoRxInterval BFDTimeInterval     // Minimum interval, in microseconds, between received BFD Echo packets that this system is capable of supporting\n\tAuthHeader                *BFDAuthHeader      // Authentication data, variable length.\n}\n\n// Length returns the data length of a BFD Control message which\n// changes based on the presence and type of authentication\n// contained in the message\nfunc (d *BFD) Length() int {\n\tif d.AuthPresent && (d.AuthHeader != nil) {\n\t\treturn bfdMinimumRecordSizeInBytes + d.AuthHeader.Length()\n\t}\n\n\treturn bfdMinimumRecordSizeInBytes\n}\n\n// LayerType returns the layer type of the BFD object, which is LayerTypeBFD.\nfunc (d *BFD) LayerType() gopacket.LayerType {\n\treturn LayerTypeBFD\n}\n\n// decodeBFD analyses a byte slice and attempts to decode it as a BFD\n// control packet\n//\n// If it succeeds, it loads p with information about the packet and returns nil.\n// If it fails, it returns an error (non nil).\n//\n// This function is employed in layertypes.go to register the BFD layer.\nfunc decodeBFD(data []byte, p gopacket.PacketBuilder) error {\n\n\t// Attempt to decode the byte slice.\n\td := &BFD{}\n\terr := d.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// If the decoding worked, add the layer to the packet and set it\n\t// as the application layer too, if there isn't already one.\n\tp.AddLayer(d)\n\tp.SetApplicationLayer(d)\n\n\treturn nil\n}\n\n// DecodeFromBytes analyses a byte slice and attempts to decode it as a BFD\n// control packet.\n//\n// Upon succeeds, it loads the BFD object with information about the packet\n// and returns nil.\n// Upon failure, it returns an error (non nil).\nfunc (d *BFD) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\n\t// If the data block is too short to be a BFD record, then return an error.\n\tif len(data) < bfdMinimumRecordSizeInBytes {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"BFD packet too short\")\n\t}\n\n\tpLen := uint8(data[3])\n\tif len(data) != int(pLen) {\n\t\treturn errors.New(\"BFD packet length does not match\")\n\t}\n\n\t// BFD type embeds type BaseLayer which contains two fields:\n\t//    Contents is supposed to contain the bytes of the data at this level.\n\t//    Payload is supposed to contain the payload of this level.\n\t// Here we set the baselayer to be the bytes of the BFD record.\n\td.BaseLayer = BaseLayer{Contents: data[:len(data)]}\n\n\t// Extract the fields from the block of bytes.\n\t// To make sense of this, refer to the packet diagram\n\t// above and the section on endian conventions.\n\n\t// The first few fields are all packed into the first 32 bits. Unpack them.\n\td.Version = BFDVersion(((data[0] & 0xE0) >> 5))\n\td.Diagnostic = BFDDiagnostic(data[0] & 0x1F)\n\tdata = data[1:]\n\n\td.State = BFDState((data[0] & 0xC0) >> 6)\n\td.Poll = data[0]&0x20 != 0\n\td.Final = data[0]&0x10 != 0\n\td.ControlPlaneIndependent = data[0]&0x08 != 0\n\td.AuthPresent = data[0]&0x04 != 0\n\td.Demand = data[0]&0x02 != 0\n\td.Multipoint = data[0]&0x01 != 0\n\tdata = data[1:]\n\n\tdata, d.DetectMultiplier = data[1:], BFDDetectMultiplier(data[0])\n\tdata, _ = data[1:], uint8(data[0]) // Consume length\n\n\t// The remaining fields can just be copied in big endian order.\n\tdata, d.MyDiscriminator = data[4:], BFDDiscriminator(binary.BigEndian.Uint32(data[:4]))\n\tdata, d.YourDiscriminator = data[4:], BFDDiscriminator(binary.BigEndian.Uint32(data[:4]))\n\tdata, d.DesiredMinTxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4]))\n\tdata, d.RequiredMinRxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4]))\n\tdata, d.RequiredMinEchoRxInterval = data[4:], BFDTimeInterval(binary.BigEndian.Uint32(data[:4]))\n\n\tif d.AuthPresent && (len(data) > 2) {\n\t\td.AuthHeader = &BFDAuthHeader{}\n\t\tdata, d.AuthHeader.AuthType = data[1:], BFDAuthType(data[0])\n\t\tdata, _ = data[1:], uint8(data[0]) // Consume length\n\t\tdata, d.AuthHeader.KeyID = data[1:], BFDAuthKeyID(data[0])\n\n\t\tswitch d.AuthHeader.AuthType {\n\t\tcase BFDAuthTypePassword:\n\t\t\td.AuthHeader.Data = BFDAuthData(data)\n\t\tcase BFDAuthTypeKeyedMD5, BFDAuthTypeMeticulousKeyedMD5:\n\t\t\t// Skipped reserved byte\n\t\t\tdata, d.AuthHeader.SequenceNumber = data[5:], BFDAuthSequenceNumber(binary.BigEndian.Uint32(data[1:5]))\n\t\t\td.AuthHeader.Data = BFDAuthData(data)\n\t\tcase BFDAuthTypeKeyedSHA1, BFDAuthTypeMeticulousKeyedSHA1:\n\t\t\t// Skipped reserved byte\n\t\t\tdata, d.AuthHeader.SequenceNumber = data[5:], BFDAuthSequenceNumber(binary.BigEndian.Uint32(data[1:5]))\n\t\t\td.AuthHeader.Data = BFDAuthData(data)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (d *BFD) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tdata, err := b.PrependBytes(bfdMinimumRecordSizeInBytes)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Pack the first few fields into the first 32 bits.\n\tdata[0] = byte(byte(d.Version<<5) | byte(d.Diagnostic))\n\th := uint8(0)\n\th |= (uint8(d.State) << 6)\n\th |= (uint8(bool2uint8(d.Poll)) << 5)\n\th |= (uint8(bool2uint8(d.Final)) << 4)\n\th |= (uint8(bool2uint8(d.ControlPlaneIndependent)) << 3)\n\th |= (uint8(bool2uint8(d.AuthPresent)) << 2)\n\th |= (uint8(bool2uint8(d.Demand)) << 1)\n\th |= uint8(bool2uint8(d.Multipoint))\n\tdata[1] = byte(h)\n\tdata[2] = byte(d.DetectMultiplier)\n\tdata[3] = byte(d.Length())\n\n\t// The remaining fields can just be copied in big endian order.\n\tbinary.BigEndian.PutUint32(data[4:], uint32(d.MyDiscriminator))\n\tbinary.BigEndian.PutUint32(data[8:], uint32(d.YourDiscriminator))\n\tbinary.BigEndian.PutUint32(data[12:], uint32(d.DesiredMinTxInterval))\n\tbinary.BigEndian.PutUint32(data[16:], uint32(d.RequiredMinRxInterval))\n\tbinary.BigEndian.PutUint32(data[20:], uint32(d.RequiredMinEchoRxInterval))\n\n\tif d.AuthPresent && (d.AuthHeader != nil) {\n\t\tauth, err := b.AppendBytes(int(d.AuthHeader.Length()))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tauth[0] = byte(d.AuthHeader.AuthType)\n\t\tauth[1] = byte(d.AuthHeader.Length())\n\t\tauth[2] = byte(d.AuthHeader.KeyID)\n\n\t\tswitch d.AuthHeader.AuthType {\n\t\tcase BFDAuthTypePassword:\n\t\t\tcopy(auth[3:], d.AuthHeader.Data)\n\t\tcase BFDAuthTypeKeyedMD5, BFDAuthTypeMeticulousKeyedMD5:\n\t\t\tauth[3] = byte(0)\n\t\t\tbinary.BigEndian.PutUint32(auth[4:], uint32(d.AuthHeader.SequenceNumber))\n\t\t\tcopy(auth[8:], d.AuthHeader.Data)\n\t\tcase BFDAuthTypeKeyedSHA1, BFDAuthTypeMeticulousKeyedSHA1:\n\t\t\tauth[3] = byte(0)\n\t\t\tbinary.BigEndian.PutUint32(auth[4:], uint32(d.AuthHeader.SequenceNumber))\n\t\t\tcopy(auth[8:], d.AuthHeader.Data)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// CanDecode returns a set of layers that BFD objects can decode.\n// As BFD objects can only decide the BFD layer, we can return just that layer.\n// Apparently a single layer type implements LayerClass.\nfunc (d *BFD) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeBFD\n}\n\n// NextLayerType specifies the next layer that GoPacket should attempt to\n// analyse after this (BFD) layer. As BFD packets do not contain any payload\n// bytes, there are no further layers to analyse.\nfunc (d *BFD) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypeZero\n}\n\n// Payload returns an empty byte slice as BFD packets do not carry a payload\nfunc (d *BFD) Payload() []byte {\n\treturn nil\n}\n\n// bool2uint8 converts a bool to uint8\nfunc bool2uint8(b bool) uint8 {\n\tif b {\n\t\treturn 1\n\t}\n\treturn 0\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/cdp.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\n// Enum types courtesy of...\n//   http://search.cpan.org/~mchapman/Net-CDP-0.09/lib/Net/CDP.pm\n//   https://code.google.com/p/ladvd/\n//   http://anonsvn.wireshark.org/viewvc/releases/wireshark-1.8.6/epan/dissectors/packet-cdp.c\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// CDPTLVType is the type of each TLV value in a CiscoDiscovery packet.\ntype CDPTLVType uint16\n\n// CDPTLVType values.\nconst (\n\tCDPTLVDevID              CDPTLVType = 0x0001\n\tCDPTLVAddress            CDPTLVType = 0x0002\n\tCDPTLVPortID             CDPTLVType = 0x0003\n\tCDPTLVCapabilities       CDPTLVType = 0x0004\n\tCDPTLVVersion            CDPTLVType = 0x0005\n\tCDPTLVPlatform           CDPTLVType = 0x0006\n\tCDPTLVIPPrefix           CDPTLVType = 0x0007\n\tCDPTLVHello              CDPTLVType = 0x0008\n\tCDPTLVVTPDomain          CDPTLVType = 0x0009\n\tCDPTLVNativeVLAN         CDPTLVType = 0x000a\n\tCDPTLVFullDuplex         CDPTLVType = 0x000b\n\tCDPTLVVLANReply          CDPTLVType = 0x000e\n\tCDPTLVVLANQuery          CDPTLVType = 0x000f\n\tCDPTLVPower              CDPTLVType = 0x0010\n\tCDPTLVMTU                CDPTLVType = 0x0011\n\tCDPTLVExtendedTrust      CDPTLVType = 0x0012\n\tCDPTLVUntrustedCOS       CDPTLVType = 0x0013\n\tCDPTLVSysName            CDPTLVType = 0x0014\n\tCDPTLVSysOID             CDPTLVType = 0x0015\n\tCDPTLVMgmtAddresses      CDPTLVType = 0x0016\n\tCDPTLVLocation           CDPTLVType = 0x0017\n\tCDPTLVExternalPortID     CDPTLVType = 0x0018\n\tCDPTLVPowerRequested     CDPTLVType = 0x0019\n\tCDPTLVPowerAvailable     CDPTLVType = 0x001a\n\tCDPTLVPortUnidirectional CDPTLVType = 0x001b\n\tCDPTLVEnergyWise         CDPTLVType = 0x001d\n\tCDPTLVSparePairPOE       CDPTLVType = 0x001f\n)\n\n// CiscoDiscoveryValue is a TLV value inside a CiscoDiscovery packet layer.\ntype CiscoDiscoveryValue struct {\n\tType   CDPTLVType\n\tLength uint16\n\tValue  []byte\n}\n\n// CiscoDiscovery is a packet layer containing the Cisco Discovery Protocol.\n// See http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm#31885\ntype CiscoDiscovery struct {\n\tBaseLayer\n\tVersion  byte\n\tTTL      byte\n\tChecksum uint16\n\tValues   []CiscoDiscoveryValue\n}\n\n// CDPCapability is the set of capabilities advertised by a CDP device.\ntype CDPCapability uint32\n\n// CDPCapability values.\nconst (\n\tCDPCapMaskRouter     CDPCapability = 0x0001\n\tCDPCapMaskTBBridge   CDPCapability = 0x0002\n\tCDPCapMaskSPBridge   CDPCapability = 0x0004\n\tCDPCapMaskSwitch     CDPCapability = 0x0008\n\tCDPCapMaskHost       CDPCapability = 0x0010\n\tCDPCapMaskIGMPFilter CDPCapability = 0x0020\n\tCDPCapMaskRepeater   CDPCapability = 0x0040\n\tCDPCapMaskPhone      CDPCapability = 0x0080\n\tCDPCapMaskRemote     CDPCapability = 0x0100\n)\n\n// CDPCapabilities represents the capabilities of a device\ntype CDPCapabilities struct {\n\tL3Router        bool\n\tTBBridge        bool\n\tSPBridge        bool\n\tL2Switch        bool\n\tIsHost          bool\n\tIGMPFilter      bool\n\tL1Repeater      bool\n\tIsPhone         bool\n\tRemotelyManaged bool\n}\n\n// CDP Power-over-Ethernet values.\nconst (\n\tCDPPoEFourWire  byte = 0x01\n\tCDPPoEPDArch    byte = 0x02\n\tCDPPoEPDRequest byte = 0x04\n\tCDPPoEPSE       byte = 0x08\n)\n\n// CDPSparePairPoE provides information on PoE.\ntype CDPSparePairPoE struct {\n\tPSEFourWire  bool // Supported / Not supported\n\tPDArchShared bool // Shared / Independent\n\tPDRequestOn  bool // On / Off\n\tPSEOn        bool // On / Off\n}\n\n// CDPVLANDialogue encapsulates a VLAN Query/Reply\ntype CDPVLANDialogue struct {\n\tID   uint8\n\tVLAN uint16\n}\n\n// CDPPowerDialogue encapsulates a Power Query/Reply\ntype CDPPowerDialogue struct {\n\tID     uint16\n\tMgmtID uint16\n\tValues []uint32\n}\n\n// CDPLocation provides location information for a CDP device.\ntype CDPLocation struct {\n\tType     uint8 // Undocumented\n\tLocation string\n}\n\n// CDPHello is a Cisco Hello message (undocumented, hence the \"Unknown\" fields)\ntype CDPHello struct {\n\tOUI              []byte\n\tProtocolID       uint16\n\tClusterMaster    net.IP\n\tUnknown1         net.IP\n\tVersion          byte\n\tSubVersion       byte\n\tStatus           byte\n\tUnknown2         byte\n\tClusterCommander net.HardwareAddr\n\tSwitchMAC        net.HardwareAddr\n\tUnknown3         byte\n\tManagementVLAN   uint16\n}\n\n// CDPEnergyWiseSubtype is used within CDP to define TLV values.\ntype CDPEnergyWiseSubtype uint32\n\n// CDPEnergyWiseSubtype values.\nconst (\n\tCDPEnergyWiseRole    CDPEnergyWiseSubtype = 0x00000007\n\tCDPEnergyWiseDomain  CDPEnergyWiseSubtype = 0x00000008\n\tCDPEnergyWiseName    CDPEnergyWiseSubtype = 0x00000009\n\tCDPEnergyWiseReplyTo CDPEnergyWiseSubtype = 0x00000017\n)\n\n// CDPEnergyWise is used by CDP to monitor and control power usage.\ntype CDPEnergyWise struct {\n\tEncryptedData  []byte\n\tUnknown1       uint32\n\tSequenceNumber uint32\n\tModelNumber    string\n\tUnknown2       uint16\n\tHardwareID     string\n\tSerialNum      string\n\tUnknown3       []byte\n\tRole           string\n\tDomain         string\n\tName           string\n\tReplyUnknown1  []byte\n\tReplyPort      []byte\n\tReplyAddress   []byte\n\tReplyUnknown2  []byte\n\tReplyUnknown3  []byte\n}\n\n// CiscoDiscoveryInfo represents the decoded details for a set of CiscoDiscoveryValues\ntype CiscoDiscoveryInfo struct {\n\tBaseLayer\n\tCDPHello\n\tDeviceID         string\n\tAddresses        []net.IP\n\tPortID           string\n\tCapabilities     CDPCapabilities\n\tVersion          string\n\tPlatform         string\n\tIPPrefixes       []net.IPNet\n\tVTPDomain        string\n\tNativeVLAN       uint16\n\tFullDuplex       bool\n\tVLANReply        CDPVLANDialogue\n\tVLANQuery        CDPVLANDialogue\n\tPowerConsumption uint16\n\tMTU              uint32\n\tExtendedTrust    uint8\n\tUntrustedCOS     uint8\n\tSysName          string\n\tSysOID           string\n\tMgmtAddresses    []net.IP\n\tLocation         CDPLocation\n\tPowerRequest     CDPPowerDialogue\n\tPowerAvailable   CDPPowerDialogue\n\tSparePairPoe     CDPSparePairPoE\n\tEnergyWise       CDPEnergyWise\n\tUnknown          []CiscoDiscoveryValue\n}\n\n// LayerType returns gopacket.LayerTypeCiscoDiscovery.\nfunc (c *CiscoDiscovery) LayerType() gopacket.LayerType {\n\treturn LayerTypeCiscoDiscovery\n}\n\nfunc decodeCiscoDiscovery(data []byte, p gopacket.PacketBuilder) error {\n\tc := &CiscoDiscovery{\n\t\tVersion:  data[0],\n\t\tTTL:      data[1],\n\t\tChecksum: binary.BigEndian.Uint16(data[2:4]),\n\t}\n\tif c.Version != 1 && c.Version != 2 {\n\t\treturn fmt.Errorf(\"Invalid CiscoDiscovery version number %d\", c.Version)\n\t}\n\tvar err error\n\tc.Values, err = decodeCiscoDiscoveryTLVs(data[4:], p)\n\tif err != nil {\n\t\treturn err\n\t}\n\tc.Contents = data[0:4]\n\tc.Payload = data[4:]\n\tp.AddLayer(c)\n\treturn p.NextDecoder(gopacket.DecodeFunc(decodeCiscoDiscoveryInfo))\n}\n\n// LayerType returns gopacket.LayerTypeCiscoDiscoveryInfo.\nfunc (c *CiscoDiscoveryInfo) LayerType() gopacket.LayerType {\n\treturn LayerTypeCiscoDiscoveryInfo\n}\n\nfunc decodeCiscoDiscoveryTLVs(data []byte, p gopacket.PacketBuilder) (values []CiscoDiscoveryValue, err error) {\n\tfor len(data) > 0 {\n\t\tif len(data) < 4 {\n\t\t\tp.SetTruncated()\n\t\t\treturn nil, errors.New(\"CDP TLV < 4 bytes\")\n\t\t}\n\t\tval := CiscoDiscoveryValue{\n\t\t\tType:   CDPTLVType(binary.BigEndian.Uint16(data[:2])),\n\t\t\tLength: binary.BigEndian.Uint16(data[2:4]),\n\t\t}\n\t\tif val.Length < 4 {\n\t\t\terr = fmt.Errorf(\"Invalid CiscoDiscovery value length %d\", val.Length)\n\t\t\tbreak\n\t\t} else if len(data) < int(val.Length) {\n\t\t\tp.SetTruncated()\n\t\t\treturn nil, fmt.Errorf(\"CDP TLV < length %d\", val.Length)\n\t\t}\n\t\tval.Value = data[4:val.Length]\n\t\tvalues = append(values, val)\n\t\tdata = data[val.Length:]\n\t}\n\treturn\n}\n\nfunc decodeCiscoDiscoveryInfo(data []byte, p gopacket.PacketBuilder) error {\n\tvar err error\n\tinfo := &CiscoDiscoveryInfo{BaseLayer: BaseLayer{Contents: data}}\n\tp.AddLayer(info)\n\tvalues, err := decodeCiscoDiscoveryTLVs(data, p)\n\tif err != nil { // Unlikely, as parent decode will fail, but better safe...\n\t\treturn err\n\t}\n\tfor _, val := range values {\n\t\tswitch val.Type {\n\t\tcase CDPTLVDevID:\n\t\t\tinfo.DeviceID = string(val.Value)\n\t\tcase CDPTLVAddress:\n\t\t\tif err = checkCDPTLVLen(val, 4); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.Addresses, err = decodeAddresses(val.Value)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase CDPTLVPortID:\n\t\t\tinfo.PortID = string(val.Value)\n\t\tcase CDPTLVCapabilities:\n\t\t\tif err = checkCDPTLVLen(val, 4); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tval := CDPCapability(binary.BigEndian.Uint32(val.Value[0:4]))\n\t\t\tinfo.Capabilities.L3Router = (val&CDPCapMaskRouter > 0)\n\t\t\tinfo.Capabilities.TBBridge = (val&CDPCapMaskTBBridge > 0)\n\t\t\tinfo.Capabilities.SPBridge = (val&CDPCapMaskSPBridge > 0)\n\t\t\tinfo.Capabilities.L2Switch = (val&CDPCapMaskSwitch > 0)\n\t\t\tinfo.Capabilities.IsHost = (val&CDPCapMaskHost > 0)\n\t\t\tinfo.Capabilities.IGMPFilter = (val&CDPCapMaskIGMPFilter > 0)\n\t\t\tinfo.Capabilities.L1Repeater = (val&CDPCapMaskRepeater > 0)\n\t\t\tinfo.Capabilities.IsPhone = (val&CDPCapMaskPhone > 0)\n\t\t\tinfo.Capabilities.RemotelyManaged = (val&CDPCapMaskRemote > 0)\n\t\tcase CDPTLVVersion:\n\t\t\tinfo.Version = string(val.Value)\n\t\tcase CDPTLVPlatform:\n\t\t\tinfo.Platform = string(val.Value)\n\t\tcase CDPTLVIPPrefix:\n\t\t\tv := val.Value\n\t\t\tl := len(v)\n\t\t\tif l%5 == 0 && l >= 5 {\n\t\t\t\tfor len(v) > 0 {\n\t\t\t\t\t_, ipnet, _ := net.ParseCIDR(fmt.Sprintf(\"%d.%d.%d.%d/%d\", v[0], v[1], v[2], v[3], v[4]))\n\t\t\t\t\tinfo.IPPrefixes = append(info.IPPrefixes, *ipnet)\n\t\t\t\t\tv = v[5:]\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn fmt.Errorf(\"Invalid TLV %v length %d\", val.Type, len(val.Value))\n\t\t\t}\n\t\tcase CDPTLVHello:\n\t\t\tif err = checkCDPTLVLen(val, 32); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tv := val.Value\n\t\t\tinfo.CDPHello.OUI = v[0:3]\n\t\t\tinfo.CDPHello.ProtocolID = binary.BigEndian.Uint16(v[3:5])\n\t\t\tinfo.CDPHello.ClusterMaster = v[5:9]\n\t\t\tinfo.CDPHello.Unknown1 = v[9:13]\n\t\t\tinfo.CDPHello.Version = v[13]\n\t\t\tinfo.CDPHello.SubVersion = v[14]\n\t\t\tinfo.CDPHello.Status = v[15]\n\t\t\tinfo.CDPHello.Unknown2 = v[16]\n\t\t\tinfo.CDPHello.ClusterCommander = v[17:23]\n\t\t\tinfo.CDPHello.SwitchMAC = v[23:29]\n\t\t\tinfo.CDPHello.Unknown3 = v[29]\n\t\t\tinfo.CDPHello.ManagementVLAN = binary.BigEndian.Uint16(v[30:32])\n\t\tcase CDPTLVVTPDomain:\n\t\t\tinfo.VTPDomain = string(val.Value)\n\t\tcase CDPTLVNativeVLAN:\n\t\t\tif err = checkCDPTLVLen(val, 2); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.NativeVLAN = binary.BigEndian.Uint16(val.Value[0:2])\n\t\tcase CDPTLVFullDuplex:\n\t\t\tif err = checkCDPTLVLen(val, 1); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.FullDuplex = (val.Value[0] == 1)\n\t\tcase CDPTLVVLANReply:\n\t\t\tif err = checkCDPTLVLen(val, 3); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.VLANReply.ID = uint8(val.Value[0])\n\t\t\tinfo.VLANReply.VLAN = binary.BigEndian.Uint16(val.Value[1:3])\n\t\tcase CDPTLVVLANQuery:\n\t\t\tif err = checkCDPTLVLen(val, 3); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.VLANQuery.ID = uint8(val.Value[0])\n\t\t\tinfo.VLANQuery.VLAN = binary.BigEndian.Uint16(val.Value[1:3])\n\t\tcase CDPTLVPower:\n\t\t\tif err = checkCDPTLVLen(val, 2); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.PowerConsumption = binary.BigEndian.Uint16(val.Value[0:2])\n\t\tcase CDPTLVMTU:\n\t\t\tif err = checkCDPTLVLen(val, 4); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.MTU = binary.BigEndian.Uint32(val.Value[0:4])\n\t\tcase CDPTLVExtendedTrust:\n\t\t\tif err = checkCDPTLVLen(val, 1); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.ExtendedTrust = uint8(val.Value[0])\n\t\tcase CDPTLVUntrustedCOS:\n\t\t\tif err = checkCDPTLVLen(val, 1); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.UntrustedCOS = uint8(val.Value[0])\n\t\tcase CDPTLVSysName:\n\t\t\tinfo.SysName = string(val.Value)\n\t\tcase CDPTLVSysOID:\n\t\t\tinfo.SysOID = string(val.Value)\n\t\tcase CDPTLVMgmtAddresses:\n\t\t\tif err = checkCDPTLVLen(val, 4); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.MgmtAddresses, err = decodeAddresses(val.Value)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase CDPTLVLocation:\n\t\t\tif err = checkCDPTLVLen(val, 2); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.Location.Type = uint8(val.Value[0])\n\t\t\tinfo.Location.Location = string(val.Value[1:])\n\n\t\t\t//\t\tcase CDPTLVLExternalPortID:\n\t\t\t//\t\t\tUndocumented\n\t\tcase CDPTLVPowerRequested:\n\t\t\tif err = checkCDPTLVLen(val, 4); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.PowerRequest.ID = binary.BigEndian.Uint16(val.Value[0:2])\n\t\t\tinfo.PowerRequest.MgmtID = binary.BigEndian.Uint16(val.Value[2:4])\n\t\t\tfor n := 4; n < len(val.Value); n += 4 {\n\t\t\t\tinfo.PowerRequest.Values = append(info.PowerRequest.Values, binary.BigEndian.Uint32(val.Value[n:n+4]))\n\t\t\t}\n\t\tcase CDPTLVPowerAvailable:\n\t\t\tif err = checkCDPTLVLen(val, 4); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.PowerAvailable.ID = binary.BigEndian.Uint16(val.Value[0:2])\n\t\t\tinfo.PowerAvailable.MgmtID = binary.BigEndian.Uint16(val.Value[2:4])\n\t\t\tfor n := 4; n < len(val.Value); n += 4 {\n\t\t\t\tinfo.PowerAvailable.Values = append(info.PowerAvailable.Values, binary.BigEndian.Uint32(val.Value[n:n+4]))\n\t\t\t}\n\t\t\t//\t\tcase CDPTLVPortUnidirectional\n\t\t\t//\t\t\tUndocumented\n\t\tcase CDPTLVEnergyWise:\n\t\t\tif err = checkCDPTLVLen(val, 72); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.EnergyWise.EncryptedData = val.Value[0:20]\n\t\t\tinfo.EnergyWise.Unknown1 = binary.BigEndian.Uint32(val.Value[20:24])\n\t\t\tinfo.EnergyWise.SequenceNumber = binary.BigEndian.Uint32(val.Value[24:28])\n\t\t\tinfo.EnergyWise.ModelNumber = string(val.Value[28:44])\n\t\t\tinfo.EnergyWise.Unknown2 = binary.BigEndian.Uint16(val.Value[44:46])\n\t\t\tinfo.EnergyWise.HardwareID = string(val.Value[46:49])\n\t\t\tinfo.EnergyWise.SerialNum = string(val.Value[49:60])\n\t\t\tinfo.EnergyWise.Unknown3 = val.Value[60:68]\n\t\t\ttlvLen := binary.BigEndian.Uint16(val.Value[68:70])\n\t\t\ttlvNum := binary.BigEndian.Uint16(val.Value[70:72])\n\t\t\tdata := val.Value[72:]\n\t\t\tif len(data) < int(tlvLen) {\n\t\t\t\treturn fmt.Errorf(\"Invalid TLV length %d vs %d\", tlvLen, len(data))\n\t\t\t}\n\t\t\tnumSeen := 0\n\t\t\tfor len(data) > 8 {\n\t\t\t\tnumSeen++\n\t\t\t\tif numSeen > int(tlvNum) { // Too many TLV's ?\n\t\t\t\t\treturn fmt.Errorf(\"Too many TLV's - wanted %d, saw %d\", tlvNum, numSeen)\n\t\t\t\t}\n\t\t\t\ttType := CDPEnergyWiseSubtype(binary.BigEndian.Uint32(data[0:4]))\n\t\t\t\ttLen := int(binary.BigEndian.Uint32(data[4:8]))\n\t\t\t\tif tLen > len(data)-8 {\n\t\t\t\t\treturn fmt.Errorf(\"Invalid TLV length %d vs %d\", tLen, len(data)-8)\n\t\t\t\t}\n\t\t\t\tdata = data[8:]\n\t\t\t\tswitch tType {\n\t\t\t\tcase CDPEnergyWiseRole:\n\t\t\t\t\tinfo.EnergyWise.Role = string(data[:])\n\t\t\t\tcase CDPEnergyWiseDomain:\n\t\t\t\t\tinfo.EnergyWise.Domain = string(data[:])\n\t\t\t\tcase CDPEnergyWiseName:\n\t\t\t\t\tinfo.EnergyWise.Name = string(data[:])\n\t\t\t\tcase CDPEnergyWiseReplyTo:\n\t\t\t\t\tif len(data) >= 18 {\n\t\t\t\t\t\tinfo.EnergyWise.ReplyUnknown1 = data[0:2]\n\t\t\t\t\t\tinfo.EnergyWise.ReplyPort = data[2:4]\n\t\t\t\t\t\tinfo.EnergyWise.ReplyAddress = data[4:8]\n\t\t\t\t\t\tinfo.EnergyWise.ReplyUnknown2 = data[8:10]\n\t\t\t\t\t\tinfo.EnergyWise.ReplyUnknown3 = data[10:14]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdata = data[tLen:]\n\t\t\t}\n\t\tcase CDPTLVSparePairPOE:\n\t\t\tif err = checkCDPTLVLen(val, 1); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tv := val.Value[0]\n\t\t\tinfo.SparePairPoe.PSEFourWire = (v&CDPPoEFourWire > 0)\n\t\t\tinfo.SparePairPoe.PDArchShared = (v&CDPPoEPDArch > 0)\n\t\t\tinfo.SparePairPoe.PDRequestOn = (v&CDPPoEPDRequest > 0)\n\t\t\tinfo.SparePairPoe.PSEOn = (v&CDPPoEPSE > 0)\n\t\tdefault:\n\t\t\tinfo.Unknown = append(info.Unknown, val)\n\t\t}\n\t}\n\treturn nil\n}\n\n// CDP Protocol Types\nconst (\n\tCDPProtocolTypeNLPID byte = 1\n\tCDPProtocolType802_2 byte = 2\n)\n\n// CDPAddressType is used to define TLV values within CDP addresses.\ntype CDPAddressType uint64\n\n// CDP Address types.\nconst (\n\tCDPAddressTypeCLNP      CDPAddressType = 0x81\n\tCDPAddressTypeIPV4      CDPAddressType = 0xcc\n\tCDPAddressTypeIPV6      CDPAddressType = 0xaaaa030000000800\n\tCDPAddressTypeDECNET    CDPAddressType = 0xaaaa030000006003\n\tCDPAddressTypeAPPLETALK CDPAddressType = 0xaaaa03000000809b\n\tCDPAddressTypeIPX       CDPAddressType = 0xaaaa030000008137\n\tCDPAddressTypeVINES     CDPAddressType = 0xaaaa0300000080c4\n\tCDPAddressTypeXNS       CDPAddressType = 0xaaaa030000000600\n\tCDPAddressTypeAPOLLO    CDPAddressType = 0xaaaa030000008019\n)\n\nfunc decodeAddresses(v []byte) (addresses []net.IP, err error) {\n\tnumaddr := int(binary.BigEndian.Uint32(v[0:4]))\n\tif numaddr < 1 {\n\t\treturn nil, fmt.Errorf(\"Invalid Address TLV number %d\", numaddr)\n\t}\n\tv = v[4:]\n\tif len(v) < numaddr*8 {\n\t\treturn nil, fmt.Errorf(\"Invalid Address TLV length %d\", len(v))\n\t}\n\tfor i := 0; i < numaddr; i++ {\n\t\tprottype := v[0]\n\t\tif prottype != CDPProtocolTypeNLPID && prottype != CDPProtocolType802_2 { // invalid protocol type\n\t\t\treturn nil, fmt.Errorf(\"Invalid Address Protocol %d\", prottype)\n\t\t}\n\t\tprotlen := int(v[1])\n\t\tif (prottype == CDPProtocolTypeNLPID && protlen != 1) ||\n\t\t\t(prottype == CDPProtocolType802_2 && protlen != 3 && protlen != 8) { // invalid length\n\t\t\treturn nil, fmt.Errorf(\"Invalid Address Protocol length %d\", protlen)\n\t\t}\n\t\tplen := make([]byte, 8)\n\t\tcopy(plen[8-protlen:], v[2:2+protlen])\n\t\tprotocol := CDPAddressType(binary.BigEndian.Uint64(plen))\n\t\tv = v[2+protlen:]\n\t\taddrlen := binary.BigEndian.Uint16(v[0:2])\n\t\tab := v[2 : 2+addrlen]\n\t\tif protocol == CDPAddressTypeIPV4 && addrlen == 4 {\n\t\t\taddresses = append(addresses, net.IPv4(ab[0], ab[1], ab[2], ab[3]))\n\t\t} else if protocol == CDPAddressTypeIPV6 && addrlen == 16 {\n\t\t\taddresses = append(addresses, net.IP(ab))\n\t\t} else {\n\t\t\t// only handle IPV4 & IPV6 for now\n\t\t}\n\t\tv = v[2+addrlen:]\n\t\tif len(v) < 8 {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn\n}\n\nfunc (t CDPTLVType) String() (s string) {\n\tswitch t {\n\tcase CDPTLVDevID:\n\t\ts = \"Device ID\"\n\tcase CDPTLVAddress:\n\t\ts = \"Addresses\"\n\tcase CDPTLVPortID:\n\t\ts = \"Port ID\"\n\tcase CDPTLVCapabilities:\n\t\ts = \"Capabilities\"\n\tcase CDPTLVVersion:\n\t\ts = \"Software Version\"\n\tcase CDPTLVPlatform:\n\t\ts = \"Platform\"\n\tcase CDPTLVIPPrefix:\n\t\ts = \"IP Prefix\"\n\tcase CDPTLVHello:\n\t\ts = \"Protocol Hello\"\n\tcase CDPTLVVTPDomain:\n\t\ts = \"VTP Management Domain\"\n\tcase CDPTLVNativeVLAN:\n\t\ts = \"Native VLAN\"\n\tcase CDPTLVFullDuplex:\n\t\ts = \"Full Duplex\"\n\tcase CDPTLVVLANReply:\n\t\ts = \"VoIP VLAN Reply\"\n\tcase CDPTLVVLANQuery:\n\t\ts = \"VLANQuery\"\n\tcase CDPTLVPower:\n\t\ts = \"Power consumption\"\n\tcase CDPTLVMTU:\n\t\ts = \"MTU\"\n\tcase CDPTLVExtendedTrust:\n\t\ts = \"Extended Trust Bitmap\"\n\tcase CDPTLVUntrustedCOS:\n\t\ts = \"Untrusted Port CoS\"\n\tcase CDPTLVSysName:\n\t\ts = \"System Name\"\n\tcase CDPTLVSysOID:\n\t\ts = \"System OID\"\n\tcase CDPTLVMgmtAddresses:\n\t\ts = \"Management Addresses\"\n\tcase CDPTLVLocation:\n\t\ts = \"Location\"\n\tcase CDPTLVExternalPortID:\n\t\ts = \"External Port ID\"\n\tcase CDPTLVPowerRequested:\n\t\ts = \"Power Requested\"\n\tcase CDPTLVPowerAvailable:\n\t\ts = \"Power Available\"\n\tcase CDPTLVPortUnidirectional:\n\t\ts = \"Port Unidirectional\"\n\tcase CDPTLVEnergyWise:\n\t\ts = \"Energy Wise\"\n\tcase CDPTLVSparePairPOE:\n\t\ts = \"Spare Pair POE\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc (a CDPAddressType) String() (s string) {\n\tswitch a {\n\tcase CDPAddressTypeCLNP:\n\t\ts = \"Connectionless Network Protocol\"\n\tcase CDPAddressTypeIPV4:\n\t\ts = \"IPv4\"\n\tcase CDPAddressTypeIPV6:\n\t\ts = \"IPv6\"\n\tcase CDPAddressTypeDECNET:\n\t\ts = \"DECnet Phase IV\"\n\tcase CDPAddressTypeAPPLETALK:\n\t\ts = \"Apple Talk\"\n\tcase CDPAddressTypeIPX:\n\t\ts = \"Novell IPX\"\n\tcase CDPAddressTypeVINES:\n\t\ts = \"Banyan VINES\"\n\tcase CDPAddressTypeXNS:\n\t\ts = \"Xerox Network Systems\"\n\tcase CDPAddressTypeAPOLLO:\n\t\ts = \"Apollo\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc (t CDPEnergyWiseSubtype) String() (s string) {\n\tswitch t {\n\tcase CDPEnergyWiseRole:\n\t\ts = \"Role\"\n\tcase CDPEnergyWiseDomain:\n\t\ts = \"Domain\"\n\tcase CDPEnergyWiseName:\n\t\ts = \"Name\"\n\tcase CDPEnergyWiseReplyTo:\n\t\ts = \"ReplyTo\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc checkCDPTLVLen(v CiscoDiscoveryValue, l int) (err error) {\n\tif len(v.Value) < l {\n\t\terr = fmt.Errorf(\"Invalid TLV %v length %d\", v.Type, len(v.Value))\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/ctp.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"github.com/google/gopacket\"\n)\n\n// EthernetCTPFunction is the function code used by the EthernetCTP protocol to identify each\n// EthernetCTP layer.\ntype EthernetCTPFunction uint16\n\n// EthernetCTPFunction values.\nconst (\n\tEthernetCTPFunctionReply       EthernetCTPFunction = 1\n\tEthernetCTPFunctionForwardData EthernetCTPFunction = 2\n)\n\n// EthernetCTP implements the EthernetCTP protocol, see http://www.mit.edu/people/jhawk/ctp.html.\n// We split EthernetCTP up into the top-level EthernetCTP layer, followed by zero or more\n// EthernetCTPForwardData layers, followed by a final EthernetCTPReply layer.\ntype EthernetCTP struct {\n\tBaseLayer\n\tSkipCount uint16\n}\n\n// LayerType returns gopacket.LayerTypeEthernetCTP.\nfunc (c *EthernetCTP) LayerType() gopacket.LayerType {\n\treturn LayerTypeEthernetCTP\n}\n\n// EthernetCTPForwardData is the ForwardData layer inside EthernetCTP.  See EthernetCTP's docs for more\n// details.\ntype EthernetCTPForwardData struct {\n\tBaseLayer\n\tFunction       EthernetCTPFunction\n\tForwardAddress []byte\n}\n\n// LayerType returns gopacket.LayerTypeEthernetCTPForwardData.\nfunc (c *EthernetCTPForwardData) LayerType() gopacket.LayerType {\n\treturn LayerTypeEthernetCTPForwardData\n}\n\n// ForwardEndpoint returns the EthernetCTPForwardData ForwardAddress as an endpoint.\nfunc (c *EthernetCTPForwardData) ForwardEndpoint() gopacket.Endpoint {\n\treturn gopacket.NewEndpoint(EndpointMAC, c.ForwardAddress)\n}\n\n// EthernetCTPReply is the Reply layer inside EthernetCTP.  See EthernetCTP's docs for more details.\ntype EthernetCTPReply struct {\n\tBaseLayer\n\tFunction      EthernetCTPFunction\n\tReceiptNumber uint16\n\tData          []byte\n}\n\n// LayerType returns gopacket.LayerTypeEthernetCTPReply.\nfunc (c *EthernetCTPReply) LayerType() gopacket.LayerType {\n\treturn LayerTypeEthernetCTPReply\n}\n\n// Payload returns the EthernetCTP reply's Data bytes.\nfunc (c *EthernetCTPReply) Payload() []byte { return c.Data }\n\nfunc decodeEthernetCTP(data []byte, p gopacket.PacketBuilder) error {\n\tc := &EthernetCTP{\n\t\tSkipCount: binary.LittleEndian.Uint16(data[:2]),\n\t\tBaseLayer: BaseLayer{data[:2], data[2:]},\n\t}\n\tif c.SkipCount%2 != 0 {\n\t\treturn fmt.Errorf(\"EthernetCTP skip count is odd: %d\", c.SkipCount)\n\t}\n\tp.AddLayer(c)\n\treturn p.NextDecoder(gopacket.DecodeFunc(decodeEthernetCTPFromFunctionType))\n}\n\n// decodeEthernetCTPFromFunctionType reads in the first 2 bytes to determine the EthernetCTP\n// layer type to decode next, then decodes based on that.\nfunc decodeEthernetCTPFromFunctionType(data []byte, p gopacket.PacketBuilder) error {\n\tfunction := EthernetCTPFunction(binary.LittleEndian.Uint16(data[:2]))\n\tswitch function {\n\tcase EthernetCTPFunctionReply:\n\t\treply := &EthernetCTPReply{\n\t\t\tFunction:      function,\n\t\t\tReceiptNumber: binary.LittleEndian.Uint16(data[2:4]),\n\t\t\tData:          data[4:],\n\t\t\tBaseLayer:     BaseLayer{data, nil},\n\t\t}\n\t\tp.AddLayer(reply)\n\t\tp.SetApplicationLayer(reply)\n\t\treturn nil\n\tcase EthernetCTPFunctionForwardData:\n\t\tforward := &EthernetCTPForwardData{\n\t\t\tFunction:       function,\n\t\t\tForwardAddress: data[2:8],\n\t\t\tBaseLayer:      BaseLayer{data[:8], data[8:]},\n\t\t}\n\t\tp.AddLayer(forward)\n\t\treturn p.NextDecoder(gopacket.DecodeFunc(decodeEthernetCTPFromFunctionType))\n\t}\n\treturn fmt.Errorf(\"Unknown EthernetCTP function type %v\", function)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/dhcpv4.go",
    "content": "// Copyright 2016 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"net\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// DHCPOp rerprents a bootp operation\ntype DHCPOp byte\n\n// bootp operations\nconst (\n\tDHCPOpRequest DHCPOp = 1\n\tDHCPOpReply   DHCPOp = 2\n)\n\n// String returns a string version of a DHCPOp.\nfunc (o DHCPOp) String() string {\n\tswitch o {\n\tcase DHCPOpRequest:\n\t\treturn \"Request\"\n\tcase DHCPOpReply:\n\t\treturn \"Reply\"\n\tdefault:\n\t\treturn \"Unknown\"\n\t}\n}\n\n// DHCPMsgType represents a DHCP operation\ntype DHCPMsgType byte\n\n// Constants that represent DHCP operations\nconst (\n\tDHCPMsgTypeUnspecified DHCPMsgType = iota\n\tDHCPMsgTypeDiscover\n\tDHCPMsgTypeOffer\n\tDHCPMsgTypeRequest\n\tDHCPMsgTypeDecline\n\tDHCPMsgTypeAck\n\tDHCPMsgTypeNak\n\tDHCPMsgTypeRelease\n\tDHCPMsgTypeInform\n)\n\n// String returns a string version of a DHCPMsgType.\nfunc (o DHCPMsgType) String() string {\n\tswitch o {\n\tcase DHCPMsgTypeUnspecified:\n\t\treturn \"Unspecified\"\n\tcase DHCPMsgTypeDiscover:\n\t\treturn \"Discover\"\n\tcase DHCPMsgTypeOffer:\n\t\treturn \"Offer\"\n\tcase DHCPMsgTypeRequest:\n\t\treturn \"Request\"\n\tcase DHCPMsgTypeDecline:\n\t\treturn \"Decline\"\n\tcase DHCPMsgTypeAck:\n\t\treturn \"Ack\"\n\tcase DHCPMsgTypeNak:\n\t\treturn \"Nak\"\n\tcase DHCPMsgTypeRelease:\n\t\treturn \"Release\"\n\tcase DHCPMsgTypeInform:\n\t\treturn \"Inform\"\n\tdefault:\n\t\treturn \"Unknown\"\n\t}\n}\n\n//DHCPMagic is the RFC 2131 \"magic cooke\" for DHCP.\nvar DHCPMagic uint32 = 0x63825363\n\n// DHCPv4 contains data for a single DHCP packet.\ntype DHCPv4 struct {\n\tBaseLayer\n\tOperation    DHCPOp\n\tHardwareType LinkType\n\tHardwareLen  uint8\n\tHardwareOpts uint8\n\tXid          uint32\n\tSecs         uint16\n\tFlags        uint16\n\tClientIP     net.IP\n\tYourClientIP net.IP\n\tNextServerIP net.IP\n\tRelayAgentIP net.IP\n\tClientHWAddr net.HardwareAddr\n\tServerName   []byte\n\tFile         []byte\n\tOptions      DHCPOptions\n}\n\n// DHCPOptions is used to get nicely printed option lists which would normally\n// be cut off after 5 options.\ntype DHCPOptions []DHCPOption\n\n// String returns a string version of the options list.\nfunc (o DHCPOptions) String() string {\n\tbuf := &bytes.Buffer{}\n\tbuf.WriteByte('[')\n\tfor i, opt := range o {\n\t\tbuf.WriteString(opt.String())\n\t\tif i+1 != len(o) {\n\t\t\tbuf.WriteString(\", \")\n\t\t}\n\t}\n\tbuf.WriteByte(']')\n\treturn buf.String()\n}\n\n// LayerType returns gopacket.LayerTypeDHCPv4\nfunc (d *DHCPv4) LayerType() gopacket.LayerType { return LayerTypeDHCPv4 }\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (d *DHCPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 240 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"DHCPv4 length %d too short\", len(data))\n\t}\n\td.Options = d.Options[:0]\n\td.Operation = DHCPOp(data[0])\n\td.HardwareType = LinkType(data[1])\n\td.HardwareLen = data[2]\n\td.HardwareOpts = data[3]\n\td.Xid = binary.BigEndian.Uint32(data[4:8])\n\td.Secs = binary.BigEndian.Uint16(data[8:10])\n\td.Flags = binary.BigEndian.Uint16(data[10:12])\n\td.ClientIP = net.IP(data[12:16])\n\td.YourClientIP = net.IP(data[16:20])\n\td.NextServerIP = net.IP(data[20:24])\n\td.RelayAgentIP = net.IP(data[24:28])\n\td.ClientHWAddr = net.HardwareAddr(data[28 : 28+d.HardwareLen])\n\td.ServerName = data[44:108]\n\td.File = data[108:236]\n\tif binary.BigEndian.Uint32(data[236:240]) != DHCPMagic {\n\t\treturn InvalidMagicCookie\n\t}\n\n\tif len(data) <= 240 {\n\t\t// DHCP Packet could have no option (??)\n\t\treturn nil\n\t}\n\n\toptions := data[240:]\n\n\tstop := len(options)\n\tstart := 0\n\tfor start < stop {\n\t\to := DHCPOption{}\n\t\tif err := o.decode(options[start:]); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif o.Type == DHCPOptEnd {\n\t\t\tbreak\n\t\t}\n\t\td.Options = append(d.Options, o)\n\t\t// Check if the option is a single byte pad\n\t\tif o.Type == DHCPOptPad {\n\t\t\tstart++\n\t\t} else {\n\t\t\tstart += int(o.Length) + 2\n\t\t}\n\t}\n\n\td.Contents = data\n\n\treturn nil\n}\n\n// Len returns the length of a DHCPv4 packet.\nfunc (d *DHCPv4) Len() uint16 {\n\tn := uint16(240)\n\tfor _, o := range d.Options {\n\t\tif o.Type == DHCPOptPad {\n\t\t\tn++\n\t\t} else {\n\t\t\tn += uint16(o.Length) + 2\n\t\t}\n\t}\n\tn++ // for opt end\n\treturn n\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (d *DHCPv4) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tplen := int(d.Len())\n\n\tdata, err := b.PrependBytes(plen)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdata[0] = byte(d.Operation)\n\tdata[1] = byte(d.HardwareType)\n\tif opts.FixLengths {\n\t\td.HardwareLen = uint8(len(d.ClientHWAddr))\n\t}\n\tdata[2] = d.HardwareLen\n\tdata[3] = d.HardwareOpts\n\tbinary.BigEndian.PutUint32(data[4:8], d.Xid)\n\tbinary.BigEndian.PutUint16(data[8:10], d.Secs)\n\tbinary.BigEndian.PutUint16(data[10:12], d.Flags)\n\tcopy(data[12:16], d.ClientIP.To4())\n\tcopy(data[16:20], d.YourClientIP.To4())\n\tcopy(data[20:24], d.NextServerIP.To4())\n\tcopy(data[24:28], d.RelayAgentIP.To4())\n\tcopy(data[28:44], d.ClientHWAddr)\n\tcopy(data[44:108], d.ServerName)\n\tcopy(data[108:236], d.File)\n\tbinary.BigEndian.PutUint32(data[236:240], DHCPMagic)\n\n\tif len(d.Options) > 0 {\n\t\toffset := 240\n\t\tfor _, o := range d.Options {\n\t\t\tif err := o.encode(data[offset:]); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\t// A pad option is only a single byte\n\t\t\tif o.Type == DHCPOptPad {\n\t\t\t\toffset++\n\t\t\t} else {\n\t\t\t\toffset += 2 + len(o.Data)\n\t\t\t}\n\t\t}\n\t\toptend := NewDHCPOption(DHCPOptEnd, nil)\n\t\tif err := optend.encode(data[offset:]); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (d *DHCPv4) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDHCPv4\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (d *DHCPv4) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\nfunc decodeDHCPv4(data []byte, p gopacket.PacketBuilder) error {\n\tdhcp := &DHCPv4{}\n\terr := dhcp.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\tp.AddLayer(dhcp)\n\treturn p.NextDecoder(gopacket.LayerTypePayload)\n}\n\n// DHCPOpt represents a DHCP option or parameter from RFC-2132\ntype DHCPOpt byte\n\n// Constants for the DHCPOpt options.\nconst (\n\tDHCPOptPad                   DHCPOpt = 0\n\tDHCPOptSubnetMask            DHCPOpt = 1   // 4, net.IP\n\tDHCPOptTimeOffset            DHCPOpt = 2   // 4, int32 (signed seconds from UTC)\n\tDHCPOptRouter                DHCPOpt = 3   // n*4, [n]net.IP\n\tDHCPOptTimeServer            DHCPOpt = 4   // n*4, [n]net.IP\n\tDHCPOptNameServer            DHCPOpt = 5   // n*4, [n]net.IP\n\tDHCPOptDNS                   DHCPOpt = 6   // n*4, [n]net.IP\n\tDHCPOptLogServer             DHCPOpt = 7   // n*4, [n]net.IP\n\tDHCPOptCookieServer          DHCPOpt = 8   // n*4, [n]net.IP\n\tDHCPOptLPRServer             DHCPOpt = 9   // n*4, [n]net.IP\n\tDHCPOptImpressServer         DHCPOpt = 10  // n*4, [n]net.IP\n\tDHCPOptResLocServer          DHCPOpt = 11  // n*4, [n]net.IP\n\tDHCPOptHostname              DHCPOpt = 12  // n, string\n\tDHCPOptBootfileSize          DHCPOpt = 13  // 2, uint16\n\tDHCPOptMeritDumpFile         DHCPOpt = 14  // >1, string\n\tDHCPOptDomainName            DHCPOpt = 15  // n, string\n\tDHCPOptSwapServer            DHCPOpt = 16  // n*4, [n]net.IP\n\tDHCPOptRootPath              DHCPOpt = 17  // n, string\n\tDHCPOptExtensionsPath        DHCPOpt = 18  // n, string\n\tDHCPOptIPForwarding          DHCPOpt = 19  // 1, bool\n\tDHCPOptSourceRouting         DHCPOpt = 20  // 1, bool\n\tDHCPOptPolicyFilter          DHCPOpt = 21  // 8*n, [n]{net.IP/net.IP}\n\tDHCPOptDatagramMTU           DHCPOpt = 22  // 2, uint16\n\tDHCPOptDefaultTTL            DHCPOpt = 23  // 1, byte\n\tDHCPOptPathMTUAgingTimeout   DHCPOpt = 24  // 4, uint32\n\tDHCPOptPathPlateuTableOption DHCPOpt = 25  // 2*n, []uint16\n\tDHCPOptInterfaceMTU          DHCPOpt = 26  // 2, uint16\n\tDHCPOptAllSubsLocal          DHCPOpt = 27  // 1, bool\n\tDHCPOptBroadcastAddr         DHCPOpt = 28  // 4, net.IP\n\tDHCPOptMaskDiscovery         DHCPOpt = 29  // 1, bool\n\tDHCPOptMaskSupplier          DHCPOpt = 30  // 1, bool\n\tDHCPOptRouterDiscovery       DHCPOpt = 31  // 1, bool\n\tDHCPOptSolicitAddr           DHCPOpt = 32  // 4, net.IP\n\tDHCPOptStaticRoute           DHCPOpt = 33  // n*8, [n]{net.IP/net.IP} -- note the 2nd is router not mask\n\tDHCPOptARPTrailers           DHCPOpt = 34  // 1, bool\n\tDHCPOptARPTimeout            DHCPOpt = 35  // 4, uint32\n\tDHCPOptEthernetEncap         DHCPOpt = 36  // 1, bool\n\tDHCPOptTCPTTL                DHCPOpt = 37  // 1, byte\n\tDHCPOptTCPKeepAliveInt       DHCPOpt = 38  // 4, uint32\n\tDHCPOptTCPKeepAliveGarbage   DHCPOpt = 39  // 1, bool\n\tDHCPOptNISDomain             DHCPOpt = 40  // n, string\n\tDHCPOptNISServers            DHCPOpt = 41  // 4*n,  [n]net.IP\n\tDHCPOptNTPServers            DHCPOpt = 42  // 4*n, [n]net.IP\n\tDHCPOptVendorOption          DHCPOpt = 43  // n, [n]byte // may be encapsulated.\n\tDHCPOptNetBIOSTCPNS          DHCPOpt = 44  // 4*n, [n]net.IP\n\tDHCPOptNetBIOSTCPDDS         DHCPOpt = 45  // 4*n, [n]net.IP\n\tDHCPOptNETBIOSTCPNodeType    DHCPOpt = 46  // 1, magic byte\n\tDHCPOptNetBIOSTCPScope       DHCPOpt = 47  // n, string\n\tDHCPOptXFontServer           DHCPOpt = 48  // n, string\n\tDHCPOptXDisplayManager       DHCPOpt = 49  // n, string\n\tDHCPOptRequestIP             DHCPOpt = 50  // 4, net.IP\n\tDHCPOptLeaseTime             DHCPOpt = 51  // 4, uint32\n\tDHCPOptExtOptions            DHCPOpt = 52  // 1, 1/2/3\n\tDHCPOptMessageType           DHCPOpt = 53  // 1, 1-7\n\tDHCPOptServerID              DHCPOpt = 54  // 4, net.IP\n\tDHCPOptParamsRequest         DHCPOpt = 55  // n, []byte\n\tDHCPOptMessage               DHCPOpt = 56  // n, 3\n\tDHCPOptMaxMessageSize        DHCPOpt = 57  // 2, uint16\n\tDHCPOptT1                    DHCPOpt = 58  // 4, uint32\n\tDHCPOptT2                    DHCPOpt = 59  // 4, uint32\n\tDHCPOptClassID               DHCPOpt = 60  // n, []byte\n\tDHCPOptClientID              DHCPOpt = 61  // n >=  2, []byte\n\tDHCPOptDomainSearch          DHCPOpt = 119 // n, string\n\tDHCPOptSIPServers            DHCPOpt = 120 // n, url\n\tDHCPOptClasslessStaticRoute  DHCPOpt = 121 //\n\tDHCPOptEnd                   DHCPOpt = 255\n)\n\n// String returns a string version of a DHCPOpt.\nfunc (o DHCPOpt) String() string {\n\tswitch o {\n\tcase DHCPOptPad:\n\t\treturn \"(padding)\"\n\tcase DHCPOptSubnetMask:\n\t\treturn \"SubnetMask\"\n\tcase DHCPOptTimeOffset:\n\t\treturn \"TimeOffset\"\n\tcase DHCPOptRouter:\n\t\treturn \"Router\"\n\tcase DHCPOptTimeServer:\n\t\treturn \"rfc868\" // old time server protocol stringified to dissuade confusion w. NTP\n\tcase DHCPOptNameServer:\n\t\treturn \"ien116\" // obscure nameserver protocol stringified to dissuade confusion w. DNS\n\tcase DHCPOptDNS:\n\t\treturn \"DNS\"\n\tcase DHCPOptLogServer:\n\t\treturn \"mitLCS\" // MIT LCS server protocol yada yada w. Syslog\n\tcase DHCPOptCookieServer:\n\t\treturn \"CookieServer\"\n\tcase DHCPOptLPRServer:\n\t\treturn \"LPRServer\"\n\tcase DHCPOptImpressServer:\n\t\treturn \"ImpressServer\"\n\tcase DHCPOptResLocServer:\n\t\treturn \"ResourceLocationServer\"\n\tcase DHCPOptHostname:\n\t\treturn \"Hostname\"\n\tcase DHCPOptBootfileSize:\n\t\treturn \"BootfileSize\"\n\tcase DHCPOptMeritDumpFile:\n\t\treturn \"MeritDumpFile\"\n\tcase DHCPOptDomainName:\n\t\treturn \"DomainName\"\n\tcase DHCPOptSwapServer:\n\t\treturn \"SwapServer\"\n\tcase DHCPOptRootPath:\n\t\treturn \"RootPath\"\n\tcase DHCPOptExtensionsPath:\n\t\treturn \"ExtensionsPath\"\n\tcase DHCPOptIPForwarding:\n\t\treturn \"IPForwarding\"\n\tcase DHCPOptSourceRouting:\n\t\treturn \"SourceRouting\"\n\tcase DHCPOptPolicyFilter:\n\t\treturn \"PolicyFilter\"\n\tcase DHCPOptDatagramMTU:\n\t\treturn \"DatagramMTU\"\n\tcase DHCPOptDefaultTTL:\n\t\treturn \"DefaultTTL\"\n\tcase DHCPOptPathMTUAgingTimeout:\n\t\treturn \"PathMTUAgingTimeout\"\n\tcase DHCPOptPathPlateuTableOption:\n\t\treturn \"PathPlateuTableOption\"\n\tcase DHCPOptInterfaceMTU:\n\t\treturn \"InterfaceMTU\"\n\tcase DHCPOptAllSubsLocal:\n\t\treturn \"AllSubsLocal\"\n\tcase DHCPOptBroadcastAddr:\n\t\treturn \"BroadcastAddress\"\n\tcase DHCPOptMaskDiscovery:\n\t\treturn \"MaskDiscovery\"\n\tcase DHCPOptMaskSupplier:\n\t\treturn \"MaskSupplier\"\n\tcase DHCPOptRouterDiscovery:\n\t\treturn \"RouterDiscovery\"\n\tcase DHCPOptSolicitAddr:\n\t\treturn \"SolicitAddr\"\n\tcase DHCPOptStaticRoute:\n\t\treturn \"StaticRoute\"\n\tcase DHCPOptARPTrailers:\n\t\treturn \"ARPTrailers\"\n\tcase DHCPOptARPTimeout:\n\t\treturn \"ARPTimeout\"\n\tcase DHCPOptEthernetEncap:\n\t\treturn \"EthernetEncap\"\n\tcase DHCPOptTCPTTL:\n\t\treturn \"TCPTTL\"\n\tcase DHCPOptTCPKeepAliveInt:\n\t\treturn \"TCPKeepAliveInt\"\n\tcase DHCPOptTCPKeepAliveGarbage:\n\t\treturn \"TCPKeepAliveGarbage\"\n\tcase DHCPOptNISDomain:\n\t\treturn \"NISDomain\"\n\tcase DHCPOptNISServers:\n\t\treturn \"NISServers\"\n\tcase DHCPOptNTPServers:\n\t\treturn \"NTPServers\"\n\tcase DHCPOptVendorOption:\n\t\treturn \"VendorOption\"\n\tcase DHCPOptNetBIOSTCPNS:\n\t\treturn \"NetBIOSOverTCPNS\"\n\tcase DHCPOptNetBIOSTCPDDS:\n\t\treturn \"NetBiosOverTCPDDS\"\n\tcase DHCPOptNETBIOSTCPNodeType:\n\t\treturn \"NetBIOSOverTCPNodeType\"\n\tcase DHCPOptNetBIOSTCPScope:\n\t\treturn \"NetBIOSOverTCPScope\"\n\tcase DHCPOptXFontServer:\n\t\treturn \"XFontServer\"\n\tcase DHCPOptXDisplayManager:\n\t\treturn \"XDisplayManager\"\n\tcase DHCPOptEnd:\n\t\treturn \"(end)\"\n\tcase DHCPOptSIPServers:\n\t\treturn \"SipServers\"\n\tcase DHCPOptRequestIP:\n\t\treturn \"RequestIP\"\n\tcase DHCPOptLeaseTime:\n\t\treturn \"LeaseTime\"\n\tcase DHCPOptExtOptions:\n\t\treturn \"ExtOpts\"\n\tcase DHCPOptMessageType:\n\t\treturn \"MessageType\"\n\tcase DHCPOptServerID:\n\t\treturn \"ServerID\"\n\tcase DHCPOptParamsRequest:\n\t\treturn \"ParamsRequest\"\n\tcase DHCPOptMessage:\n\t\treturn \"Message\"\n\tcase DHCPOptMaxMessageSize:\n\t\treturn \"MaxDHCPSize\"\n\tcase DHCPOptT1:\n\t\treturn \"Timer1\"\n\tcase DHCPOptT2:\n\t\treturn \"Timer2\"\n\tcase DHCPOptClassID:\n\t\treturn \"ClassID\"\n\tcase DHCPOptClientID:\n\t\treturn \"ClientID\"\n\tcase DHCPOptDomainSearch:\n\t\treturn \"DomainSearch\"\n\tcase DHCPOptClasslessStaticRoute:\n\t\treturn \"ClasslessStaticRoute\"\n\tdefault:\n\t\treturn \"Unknown\"\n\t}\n}\n\n// DHCPOption rerpresents a DHCP option.\ntype DHCPOption struct {\n\tType   DHCPOpt\n\tLength uint8\n\tData   []byte\n}\n\n// String returns a string version of a DHCP Option.\nfunc (o DHCPOption) String() string {\n\tswitch o.Type {\n\n\tcase DHCPOptHostname, DHCPOptMeritDumpFile, DHCPOptDomainName, DHCPOptRootPath,\n\t\tDHCPOptExtensionsPath, DHCPOptNISDomain, DHCPOptNetBIOSTCPScope, DHCPOptXFontServer,\n\t\tDHCPOptXDisplayManager, DHCPOptMessage, DHCPOptDomainSearch: // string\n\t\treturn fmt.Sprintf(\"Option(%s:%s)\", o.Type, string(o.Data))\n\n\tcase DHCPOptMessageType:\n\t\tif len(o.Data) != 1 {\n\t\t\treturn fmt.Sprintf(\"Option(%s:INVALID)\", o.Type)\n\t\t}\n\t\treturn fmt.Sprintf(\"Option(%s:%s)\", o.Type, DHCPMsgType(o.Data[0]))\n\n\tcase DHCPOptSubnetMask, DHCPOptServerID, DHCPOptBroadcastAddr,\n\t\tDHCPOptSolicitAddr, DHCPOptRequestIP: // net.IP\n\t\tif len(o.Data) < 4 {\n\t\t\treturn fmt.Sprintf(\"Option(%s:INVALID)\", o.Type)\n\t\t}\n\t\treturn fmt.Sprintf(\"Option(%s:%s)\", o.Type, net.IP(o.Data))\n\n\tcase DHCPOptT1, DHCPOptT2, DHCPOptLeaseTime, DHCPOptPathMTUAgingTimeout,\n\t\tDHCPOptARPTimeout, DHCPOptTCPKeepAliveInt: // uint32\n\t\tif len(o.Data) != 4 {\n\t\t\treturn fmt.Sprintf(\"Option(%s:INVALID)\", o.Type)\n\t\t}\n\t\treturn fmt.Sprintf(\"Option(%s:%d)\", o.Type,\n\t\t\tuint32(o.Data[0])<<24|uint32(o.Data[1])<<16|uint32(o.Data[2])<<8|uint32(o.Data[3]))\n\n\tcase DHCPOptParamsRequest:\n\t\tbuf := &bytes.Buffer{}\n\t\tbuf.WriteString(fmt.Sprintf(\"Option(%s:\", o.Type))\n\t\tfor i, v := range o.Data {\n\t\t\tbuf.WriteString(DHCPOpt(v).String())\n\t\t\tif i+1 != len(o.Data) {\n\t\t\t\tbuf.WriteByte(',')\n\t\t\t}\n\t\t}\n\t\tbuf.WriteString(\")\")\n\t\treturn buf.String()\n\n\tdefault:\n\t\treturn fmt.Sprintf(\"Option(%s:%v)\", o.Type, o.Data)\n\t}\n}\n\n// NewDHCPOption constructs a new DHCPOption with a given type and data.\nfunc NewDHCPOption(t DHCPOpt, data []byte) DHCPOption {\n\to := DHCPOption{Type: t}\n\tif data != nil {\n\t\to.Data = data\n\t\to.Length = uint8(len(data))\n\t}\n\treturn o\n}\n\nfunc (o *DHCPOption) encode(b []byte) error {\n\tswitch o.Type {\n\tcase DHCPOptPad, DHCPOptEnd:\n\t\tb[0] = byte(o.Type)\n\tdefault:\n\t\tb[0] = byte(o.Type)\n\t\tb[1] = o.Length\n\t\tcopy(b[2:], o.Data)\n\t}\n\treturn nil\n}\n\nfunc (o *DHCPOption) decode(data []byte) error {\n\tif len(data) < 1 {\n\t\t// Pad/End have a length of 1\n\t\treturn DecOptionNotEnoughData\n\t}\n\to.Type = DHCPOpt(data[0])\n\tswitch o.Type {\n\tcase DHCPOptPad, DHCPOptEnd:\n\t\to.Data = nil\n\tdefault:\n\t\tif len(data) < 2 {\n\t\t\treturn DecOptionNotEnoughData\n\t\t}\n\t\to.Length = data[1]\n\t\tif int(o.Length) > len(data[2:]) {\n\t\t\treturn DecOptionMalformed\n\t\t}\n\t\to.Data = data[2 : 2+int(o.Length)]\n\t}\n\treturn nil\n}\n\n// DHCPv4Error is used for constant errors for DHCPv4. It is needed for test asserts.\ntype DHCPv4Error string\n\n// DHCPv4Error implements error interface.\nfunc (d DHCPv4Error) Error() string {\n\treturn string(d)\n}\n\nconst (\n\t// DecOptionNotEnoughData is returned when there is not enough data during option's decode process\n\tDecOptionNotEnoughData = DHCPv4Error(\"Not enough data to decode\")\n\t// DecOptionMalformed is returned when the option is malformed\n\tDecOptionMalformed = DHCPv4Error(\"Option is malformed\")\n\t// InvalidMagicCookie is returned when Magic cookie is missing into BOOTP header\n\tInvalidMagicCookie = DHCPv4Error(\"Bad DHCP header\")\n)\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/dhcpv6.go",
    "content": "// Copyright 2018 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"net\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// DHCPv6MsgType represents a DHCPv6 operation\ntype DHCPv6MsgType byte\n\n// Constants that represent DHCP operations\nconst (\n\tDHCPv6MsgTypeUnspecified DHCPv6MsgType = iota\n\tDHCPv6MsgTypeSolicit\n\tDHCPv6MsgTypeAdverstise\n\tDHCPv6MsgTypeRequest\n\tDHCPv6MsgTypeConfirm\n\tDHCPv6MsgTypeRenew\n\tDHCPv6MsgTypeRebind\n\tDHCPv6MsgTypeReply\n\tDHCPv6MsgTypeRelease\n\tDHCPv6MsgTypeDecline\n\tDHCPv6MsgTypeReconfigure\n\tDHCPv6MsgTypeInformationRequest\n\tDHCPv6MsgTypeRelayForward\n\tDHCPv6MsgTypeRelayReply\n)\n\n// String returns a string version of a DHCPv6MsgType.\nfunc (o DHCPv6MsgType) String() string {\n\tswitch o {\n\tcase DHCPv6MsgTypeUnspecified:\n\t\treturn \"Unspecified\"\n\tcase DHCPv6MsgTypeSolicit:\n\t\treturn \"Solicit\"\n\tcase DHCPv6MsgTypeAdverstise:\n\t\treturn \"Adverstise\"\n\tcase DHCPv6MsgTypeRequest:\n\t\treturn \"Request\"\n\tcase DHCPv6MsgTypeConfirm:\n\t\treturn \"Confirm\"\n\tcase DHCPv6MsgTypeRenew:\n\t\treturn \"Renew\"\n\tcase DHCPv6MsgTypeRebind:\n\t\treturn \"Rebind\"\n\tcase DHCPv6MsgTypeReply:\n\t\treturn \"Reply\"\n\tcase DHCPv6MsgTypeRelease:\n\t\treturn \"Release\"\n\tcase DHCPv6MsgTypeDecline:\n\t\treturn \"Decline\"\n\tcase DHCPv6MsgTypeReconfigure:\n\t\treturn \"Reconfigure\"\n\tcase DHCPv6MsgTypeInformationRequest:\n\t\treturn \"InformationRequest\"\n\tcase DHCPv6MsgTypeRelayForward:\n\t\treturn \"RelayForward\"\n\tcase DHCPv6MsgTypeRelayReply:\n\t\treturn \"RelayReply\"\n\tdefault:\n\t\treturn \"Unknown\"\n\t}\n}\n\n// DHCPv6 contains data for a single DHCP packet.\ntype DHCPv6 struct {\n\tBaseLayer\n\tMsgType       DHCPv6MsgType\n\tHopCount      uint8\n\tLinkAddr      net.IP\n\tPeerAddr      net.IP\n\tTransactionID []byte\n\tOptions       DHCPv6Options\n}\n\n// LayerType returns gopacket.LayerTypeDHCPv6\nfunc (d *DHCPv6) LayerType() gopacket.LayerType { return LayerTypeDHCPv6 }\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (d *DHCPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 4 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"DHCPv6 length %d too short\", len(data))\n\t}\n\td.BaseLayer = BaseLayer{Contents: data}\n\td.Options = d.Options[:0]\n\td.MsgType = DHCPv6MsgType(data[0])\n\n\toffset := 0\n\tif d.MsgType == DHCPv6MsgTypeRelayForward || d.MsgType == DHCPv6MsgTypeRelayReply {\n\t\tif len(data) < 34 {\n\t\t\tdf.SetTruncated()\n\t\t\treturn fmt.Errorf(\"DHCPv6 length %d too short for message type %d\", len(data), d.MsgType)\n\t\t}\n\t\td.HopCount = data[1]\n\t\td.LinkAddr = net.IP(data[2:18])\n\t\td.PeerAddr = net.IP(data[18:34])\n\t\toffset = 34\n\t} else {\n\t\td.TransactionID = data[1:4]\n\t\toffset = 4\n\t}\n\n\tstop := len(data)\n\tfor offset < stop {\n\t\to := DHCPv6Option{}\n\t\tif err := o.decode(data[offset:]); err != nil {\n\t\t\treturn err\n\t\t}\n\t\td.Options = append(d.Options, o)\n\t\toffset += int(o.Length) + 4 // 2 from option code, 2 from option length\n\t}\n\n\treturn nil\n}\n\n// Len returns the length of a DHCPv6 packet.\nfunc (d *DHCPv6) Len() int {\n\tn := 1\n\tif d.MsgType == DHCPv6MsgTypeRelayForward || d.MsgType == DHCPv6MsgTypeRelayReply {\n\t\tn += 33\n\t} else {\n\t\tn += 3\n\t}\n\n\tfor _, o := range d.Options {\n\t\tn += int(o.Length) + 4 // 2 from option code, 2 from option length\n\t}\n\n\treturn n\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (d *DHCPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tplen := int(d.Len())\n\n\tdata, err := b.PrependBytes(plen)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\toffset := 0\n\tdata[0] = byte(d.MsgType)\n\tif d.MsgType == DHCPv6MsgTypeRelayForward || d.MsgType == DHCPv6MsgTypeRelayReply {\n\t\tdata[1] = byte(d.HopCount)\n\t\tcopy(data[2:18], d.LinkAddr.To16())\n\t\tcopy(data[18:34], d.PeerAddr.To16())\n\t\toffset = 34\n\t} else {\n\t\tcopy(data[1:4], d.TransactionID)\n\t\toffset = 4\n\t}\n\n\tif len(d.Options) > 0 {\n\t\tfor _, o := range d.Options {\n\t\t\tif err := o.encode(data[offset:], opts); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\toffset += int(o.Length) + 4 // 2 from option code, 2 from option length\n\t\t}\n\t}\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (d *DHCPv6) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDHCPv6\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (d *DHCPv6) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\nfunc decodeDHCPv6(data []byte, p gopacket.PacketBuilder) error {\n\tdhcp := &DHCPv6{}\n\terr := dhcp.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\tp.AddLayer(dhcp)\n\treturn p.NextDecoder(gopacket.LayerTypePayload)\n}\n\n// DHCPv6StatusCode represents a DHCP status code - RFC-3315\ntype DHCPv6StatusCode uint16\n\n// Constants for the DHCPv6StatusCode.\nconst (\n\tDHCPv6StatusCodeSuccess DHCPv6StatusCode = iota\n\tDHCPv6StatusCodeUnspecFail\n\tDHCPv6StatusCodeNoAddrsAvail\n\tDHCPv6StatusCodeNoBinding\n\tDHCPv6StatusCodeNotOnLink\n\tDHCPv6StatusCodeUseMulticast\n)\n\n// String returns a string version of a DHCPv6StatusCode.\nfunc (o DHCPv6StatusCode) String() string {\n\tswitch o {\n\tcase DHCPv6StatusCodeSuccess:\n\t\treturn \"Success\"\n\tcase DHCPv6StatusCodeUnspecFail:\n\t\treturn \"UnspecifiedFailure\"\n\tcase DHCPv6StatusCodeNoAddrsAvail:\n\t\treturn \"NoAddressAvailable\"\n\tcase DHCPv6StatusCodeNoBinding:\n\t\treturn \"NoBinding\"\n\tcase DHCPv6StatusCodeNotOnLink:\n\t\treturn \"NotOnLink\"\n\tcase DHCPv6StatusCodeUseMulticast:\n\t\treturn \"UseMulticast\"\n\tdefault:\n\t\treturn \"Unknown\"\n\t}\n}\n\n// DHCPv6DUIDType represents a DHCP DUID - RFC-3315\ntype DHCPv6DUIDType uint16\n\n// Constants for the DHCPv6DUIDType.\nconst (\n\tDHCPv6DUIDTypeLLT DHCPv6DUIDType = iota + 1\n\tDHCPv6DUIDTypeEN\n\tDHCPv6DUIDTypeLL\n)\n\n// String returns a string version of a DHCPv6DUIDType.\nfunc (o DHCPv6DUIDType) String() string {\n\tswitch o {\n\tcase DHCPv6DUIDTypeLLT:\n\t\treturn \"LLT\"\n\tcase DHCPv6DUIDTypeEN:\n\t\treturn \"EN\"\n\tcase DHCPv6DUIDTypeLL:\n\t\treturn \"LL\"\n\tdefault:\n\t\treturn \"Unknown\"\n\t}\n}\n\n// DHCPv6DUID means DHCP Unique Identifier as stated in RFC 3315, section 9 (https://tools.ietf.org/html/rfc3315#page-19)\ntype DHCPv6DUID struct {\n\tType DHCPv6DUIDType\n\t// LLT, LL\n\tHardwareType []byte\n\t// EN\n\tEnterpriseNumber []byte\n\t// LLT\n\tTime []byte\n\t// LLT, LL\n\tLinkLayerAddress net.HardwareAddr\n\t// EN\n\tIdentifier []byte\n}\n\n// DecodeFromBytes decodes the given bytes into a DHCPv6DUID\nfunc (d *DHCPv6DUID) DecodeFromBytes(data []byte) error {\n\tif len(data) < 2 {\n\t\treturn fmt.Errorf(\"Not enough bytes to decode: %d\", len(data))\n\t}\n\n\td.Type = DHCPv6DUIDType(binary.BigEndian.Uint16(data[:2]))\n\tif d.Type == DHCPv6DUIDTypeLLT || d.Type == DHCPv6DUIDTypeLL {\n\t\tif len(data) < 4 {\n\t\t\treturn fmt.Errorf(\"Not enough bytes to decode: %d\", len(data))\n\t\t}\n\t\td.HardwareType = data[2:4]\n\t}\n\n\tif d.Type == DHCPv6DUIDTypeLLT {\n\t\tif len(data) < 8 {\n\t\t\treturn fmt.Errorf(\"Not enough bytes to decode: %d\", len(data))\n\t\t}\n\t\td.Time = data[4:8]\n\t\td.LinkLayerAddress = net.HardwareAddr(data[8:])\n\t} else if d.Type == DHCPv6DUIDTypeEN {\n\t\tif len(data) < 6 {\n\t\t\treturn fmt.Errorf(\"Not enough bytes to decode: %d\", len(data))\n\t\t}\n\t\td.EnterpriseNumber = data[2:6]\n\t\td.Identifier = data[6:]\n\t} else { // DHCPv6DUIDTypeLL\n\t\tif len(data) < 4 {\n\t\t\treturn fmt.Errorf(\"Not enough bytes to decode: %d\", len(data))\n\t\t}\n\t\td.LinkLayerAddress = net.HardwareAddr(data[4:])\n\t}\n\n\treturn nil\n}\n\n// Encode encodes the DHCPv6DUID in a slice of bytes\nfunc (d *DHCPv6DUID) Encode() []byte {\n\tlength := d.Len()\n\tdata := make([]byte, length)\n\tbinary.BigEndian.PutUint16(data[0:2], uint16(d.Type))\n\n\tif d.Type == DHCPv6DUIDTypeLLT || d.Type == DHCPv6DUIDTypeLL {\n\t\tcopy(data[2:4], d.HardwareType)\n\t}\n\n\tif d.Type == DHCPv6DUIDTypeLLT {\n\t\tcopy(data[4:8], d.Time)\n\t\tcopy(data[8:], d.LinkLayerAddress)\n\t} else if d.Type == DHCPv6DUIDTypeEN {\n\t\tcopy(data[2:6], d.EnterpriseNumber)\n\t\tcopy(data[6:], d.Identifier)\n\t} else {\n\t\tcopy(data[4:], d.LinkLayerAddress)\n\t}\n\n\treturn data\n}\n\n// Len returns the length of the DHCPv6DUID, respecting the type\nfunc (d *DHCPv6DUID) Len() int {\n\tlength := 2 // d.Type\n\tif d.Type == DHCPv6DUIDTypeLLT {\n\t\tlength += 2 /*HardwareType*/ + 4 /*d.Time*/ + len(d.LinkLayerAddress)\n\t} else if d.Type == DHCPv6DUIDTypeEN {\n\t\tlength += 4 /*d.EnterpriseNumber*/ + len(d.Identifier)\n\t} else { // LL\n\t\tlength += 2 /*d.HardwareType*/ + len(d.LinkLayerAddress)\n\t}\n\n\treturn length\n}\n\nfunc (d *DHCPv6DUID) String() string {\n\tduid := \"Type: \" + d.Type.String() + \", \"\n\tif d.Type == DHCPv6DUIDTypeLLT {\n\t\tduid += fmt.Sprintf(\"HardwareType: %v, Time: %v, LinkLayerAddress: %v\", d.HardwareType, d.Time, d.LinkLayerAddress)\n\t} else if d.Type == DHCPv6DUIDTypeEN {\n\t\tduid += fmt.Sprintf(\"EnterpriseNumber: %v, Identifier: %v\", d.EnterpriseNumber, d.Identifier)\n\t} else { // DHCPv6DUIDTypeLL\n\t\tduid += fmt.Sprintf(\"HardwareType: %v, LinkLayerAddress: %v\", d.HardwareType, d.LinkLayerAddress)\n\t}\n\treturn duid\n}\n\nfunc decodeDHCPv6DUID(data []byte) (*DHCPv6DUID, error) {\n\tduid := &DHCPv6DUID{}\n\terr := duid.DecodeFromBytes(data)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn duid, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/dhcpv6_options.go",
    "content": "// Copyright 2018 The GoPacket Authors. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"github.com/google/gopacket\"\n)\n\n// DHCPv6Opt represents a DHCP option or parameter from RFC-3315\ntype DHCPv6Opt uint16\n\n// Constants for the DHCPv6Opt options.\nconst (\n\tDHCPv6OptClientID           DHCPv6Opt = 1\n\tDHCPv6OptServerID           DHCPv6Opt = 2\n\tDHCPv6OptIANA               DHCPv6Opt = 3\n\tDHCPv6OptIATA               DHCPv6Opt = 4\n\tDHCPv6OptIAAddr             DHCPv6Opt = 5\n\tDHCPv6OptOro                DHCPv6Opt = 6\n\tDHCPv6OptPreference         DHCPv6Opt = 7\n\tDHCPv6OptElapsedTime        DHCPv6Opt = 8\n\tDHCPv6OptRelayMessage       DHCPv6Opt = 9\n\tDHCPv6OptAuth               DHCPv6Opt = 11\n\tDHCPv6OptUnicast            DHCPv6Opt = 12\n\tDHCPv6OptStatusCode         DHCPv6Opt = 13\n\tDHCPv6OptRapidCommit        DHCPv6Opt = 14\n\tDHCPv6OptUserClass          DHCPv6Opt = 15\n\tDHCPv6OptVendorClass        DHCPv6Opt = 16\n\tDHCPv6OptVendorOpts         DHCPv6Opt = 17\n\tDHCPv6OptInterfaceID        DHCPv6Opt = 18\n\tDHCPv6OptReconfigureMessage DHCPv6Opt = 19\n\tDHCPv6OptReconfigureAccept  DHCPv6Opt = 20\n\n\t// RFC 3319 Session Initiation Protocol (SIP)\n\tDHCPv6OptSIPServersDomainList  DHCPv6Opt = 21\n\tDHCPv6OptSIPServersAddressList DHCPv6Opt = 22\n\n\t// RFC 3646 DNS Configuration\n\tDHCPv6OptDNSServers DHCPv6Opt = 23\n\tDHCPv6OptDomainList DHCPv6Opt = 24\n\n\t// RFC 3633 Prefix Delegation\n\tDHCPv6OptIAPD     DHCPv6Opt = 25\n\tDHCPv6OptIAPrefix DHCPv6Opt = 26\n\n\t// RFC 3898 Network Information Service (NIS)\n\tDHCPv6OptNISServers     DHCPv6Opt = 27\n\tDHCPv6OptNISPServers    DHCPv6Opt = 28\n\tDHCPv6OptNISDomainName  DHCPv6Opt = 29\n\tDHCPv6OptNISPDomainName DHCPv6Opt = 30\n\n\t// RFC 4075 Simple Network Time Protocol (SNTP)\n\tDHCPv6OptSNTPServers DHCPv6Opt = 31\n\n\t// RFC 4242 Information Refresh Time Option\n\tDHCPv6OptInformationRefreshTime DHCPv6Opt = 32\n\n\t// RFC 4280 Broadcast and Multicast Control Servers\n\tDHCPv6OptBCMCSServerDomainNameList DHCPv6Opt = 33\n\tDHCPv6OptBCMCSServerAddressList    DHCPv6Opt = 34\n\n\t// RFC 4776 Civic Address ConfigurationOption\n\tDHCPv6OptGeoconfCivic DHCPv6Opt = 36\n\n\t// RFC 4649 Relay Agent Remote-ID\n\tDHCPv6OptRemoteID DHCPv6Opt = 37\n\n\t// RFC 4580 Relay Agent Subscriber-ID\n\tDHCPv6OptSubscriberID DHCPv6Opt = 38\n\n\t// RFC 4704 Client Full Qualified Domain Name (FQDN)\n\tDHCPv6OptClientFQDN DHCPv6Opt = 39\n\n\t// RFC 5192 Protocol for Carrying Authentication for Network Access (PANA)\n\tDHCPv6OptPanaAgent DHCPv6Opt = 40\n\n\t// RFC 4833 Timezone Options\n\tDHCPv6OptNewPOSIXTimezone DHCPv6Opt = 41\n\tDHCPv6OptNewTZDBTimezone  DHCPv6Opt = 42\n\n\t// RFC 4994 Relay Agent Echo Request\n\tDHCPv6OptEchoRequestOption DHCPv6Opt = 43\n\n\t// RFC 5007 Leasequery\n\tDHCPv6OptLQQuery      DHCPv6Opt = 44\n\tDHCPv6OptCLTTime      DHCPv6Opt = 45\n\tDHCPv6OptClientData   DHCPv6Opt = 46\n\tDHCPv6OptLQRelayData  DHCPv6Opt = 47\n\tDHCPv6OptLQClientLink DHCPv6Opt = 48\n\n\t// RFC 6610 Home Information Discovery in Mobile IPv6 (MIPv6)\n\tDHCPv6OptMIP6HNIDF DHCPv6Opt = 49\n\tDHCPv6OptMIP6VDINF DHCPv6Opt = 50\n\tDHCPv6OptMIP6IDINF DHCPv6Opt = 69\n\tDHCPv6OptMIP6UDINF DHCPv6Opt = 70\n\tDHCPv6OptMIP6HNP   DHCPv6Opt = 71\n\tDHCPv6OptMIP6HAA   DHCPv6Opt = 72\n\tDHCPv6OptMIP6HAF   DHCPv6Opt = 73\n\n\t// RFC 5223 Discovering Location-to-Service Translation (LoST) Servers\n\tDHCPv6OptV6LOST DHCPv6Opt = 51\n\n\t// RFC 5417 Control And Provisioning of Wireless Access Points (CAPWAP)\n\tDHCPv6OptCAPWAPACV6 DHCPv6Opt = 52\n\n\t// RFC 5460 Bulk Leasequery\n\tDHCPv6OptRelayID DHCPv6Opt = 53\n\n\t// RFC 5678 IEEE 802.21 Mobility Services (MoS) Discovery\n\tDHCPv6OptIPv6AddressMoS DHCPv6Opt = 54\n\tDHCPv6OptIPv6FQDNMoS    DHCPv6Opt = 55\n\n\t// RFC 5908 NTP Server Option\n\tDHCPv6OptNTPServer DHCPv6Opt = 56\n\n\t// RFC 5986 Discovering the Local Location Information Server (LIS)\n\tDHCPv6OptV6AccessDomain DHCPv6Opt = 57\n\n\t// RFC 5986 SIP User Agent\n\tDHCPv6OptSIPUACSList DHCPv6Opt = 58\n\n\t// RFC 5970 Options for Network Boot\n\tDHCPv6OptBootFileURL    DHCPv6Opt = 59\n\tDHCPv6OptBootFileParam  DHCPv6Opt = 60\n\tDHCPv6OptClientArchType DHCPv6Opt = 61\n\tDHCPv6OptNII            DHCPv6Opt = 62\n\n\t// RFC 6225 Coordinate-Based Location Configuration Information\n\tDHCPv6OptGeolocation DHCPv6Opt = 63\n\n\t// RFC 6334 Dual-Stack Lite\n\tDHCPv6OptAFTRName DHCPv6Opt = 64\n\n\t// RFC 6440 EAP Re-authentication Protocol (ERP)\n\tDHCPv6OptERPLocalDomainName DHCPv6Opt = 65\n\n\t// RFC 6422 Relay-Supplied DHCP Options\n\tDHCPv6OptRSOO DHCPv6Opt = 66\n\n\t// RFC 6603 Prefix Exclude Option for DHCPv6-based Prefix Delegation\n\tDHCPv6OptPDExclude DHCPv6Opt = 67\n\n\t// RFC 6607 Virtual Subnet Selection\n\tDHCPv6OptVSS DHCPv6Opt = 68\n\n\t// RFC 6731 Improved Recursive DNS Server Selection for Multi-Interfaced Nodes\n\tDHCPv6OptRDNSSSelection DHCPv6Opt = 74\n\n\t// RFC 6784 Kerberos Options for DHCPv6\n\tDHCPv6OptKRBPrincipalName DHCPv6Opt = 75\n\tDHCPv6OptKRBRealmName     DHCPv6Opt = 76\n\tDHCPv6OptKRBKDC           DHCPv6Opt = 77\n\n\t// RFC 6939 Client Link-Layer Address Option\n\tDHCPv6OptClientLinkLayerAddress DHCPv6Opt = 79\n\n\t// RFC 6977 Triggering DHCPv6 Reconfiguration from Relay Agents\n\tDHCPv6OptLinkAddress DHCPv6Opt = 80\n\n\t// RFC 7037 RADIUS Option for the DHCPv6 Relay Agent\n\tDHCPv6OptRADIUS DHCPv6Opt = 81\n\n\t// RFC 7083 Modification to Default Values of SOL_MAX_RT and INF_MAX_RT\n\tDHCPv6OptSolMaxRt DHCPv6Opt = 82\n\tDHCPv6OptInfMaxRt DHCPv6Opt = 83\n\n\t// RFC 7078 Distributing Address Selection Policy\n\tDHCPv6OptAddrSel      DHCPv6Opt = 84\n\tDHCPv6OptAddrSelTable DHCPv6Opt = 85\n\n\t// RFC 7291 DHCP Options for the Port Control Protocol (PCP)\n\tDHCPv6OptV6PCPServer DHCPv6Opt = 86\n\n\t// RFC 7341 DHCPv4-over-DHCPv6 (DHCP 4o6) Transport\n\tDHCPv6OptDHCPv4Message          DHCPv6Opt = 87\n\tDHCPv6OptDHCPv4OverDHCPv6Server DHCPv6Opt = 88\n\n\t// RFC 7598 Configuration of Softwire Address and Port-Mapped Clients\n\tDHCPv6OptS46Rule           DHCPv6Opt = 89\n\tDHCPv6OptS46BR             DHCPv6Opt = 90\n\tDHCPv6OptS46DMR            DHCPv6Opt = 91\n\tDHCPv6OptS46V4V4Bind       DHCPv6Opt = 92\n\tDHCPv6OptS46PortParameters DHCPv6Opt = 93\n\tDHCPv6OptS46ContMAPE       DHCPv6Opt = 94\n\tDHCPv6OptS46ContMAPT       DHCPv6Opt = 95\n\tDHCPv6OptS46ContLW         DHCPv6Opt = 96\n\n\t// RFC 7600 IPv4 Residual Deployment via IPv6\n\tDHCPv6Opt4RD           DHCPv6Opt = 97\n\tDHCPv6Opt4RDMapRule    DHCPv6Opt = 98\n\tDHCPv6Opt4RDNonMapRule DHCPv6Opt = 99\n\n\t// RFC 7653 Active Leasequery\n\tDHCPv6OptLQBaseTime  DHCPv6Opt = 100\n\tDHCPv6OptLQStartTime DHCPv6Opt = 101\n\tDHCPv6OptLQEndTime   DHCPv6Opt = 102\n\n\t// RFC 7710 Captive-Portal Identification\n\tDHCPv6OptCaptivePortal DHCPv6Opt = 103\n\n\t// RFC 7774 Multicast Protocol for Low-Power and Lossy Networks (MPL) Parameter Configuration\n\tDHCPv6OptMPLParameters DHCPv6Opt = 104\n\n\t// RFC 7839 Access-Network-Identifier (ANI)\n\tDHCPv6OptANIATT           DHCPv6Opt = 105\n\tDHCPv6OptANINetworkName   DHCPv6Opt = 106\n\tDHCPv6OptANIAPName        DHCPv6Opt = 107\n\tDHCPv6OptANIAPBSSID       DHCPv6Opt = 108\n\tDHCPv6OptANIOperatorID    DHCPv6Opt = 109\n\tDHCPv6OptANIOperatorRealm DHCPv6Opt = 110\n\n\t// RFC 8026 Unified IPv4-in-IPv6 Softwire Customer Premises Equipment (CPE)\n\tDHCPv6OptS46Priority DHCPv6Opt = 111\n\n\t// draft-ietf-opsawg-mud-25 Manufacturer Usage Description (MUD)\n\tDHCPv6OptMUDURLV6 DHCPv6Opt = 112\n\n\t// RFC 8115 IPv4-Embedded Multicast and Unicast IPv6 Prefixes\n\tDHCPv6OptV6Prefix64 DHCPv6Opt = 113\n\n\t// RFC 8156 DHCPv6 Failover Protocol\n\tDHCPv6OptFBindingStatus           DHCPv6Opt = 114\n\tDHCPv6OptFConnectFlags            DHCPv6Opt = 115\n\tDHCPv6OptFDNSRemovalInfo          DHCPv6Opt = 116\n\tDHCPv6OptFDNSHostName             DHCPv6Opt = 117\n\tDHCPv6OptFDNSZoneName             DHCPv6Opt = 118\n\tDHCPv6OptFDNSFlags                DHCPv6Opt = 119\n\tDHCPv6OptFExpirationTime          DHCPv6Opt = 120\n\tDHCPv6OptFMaxUnacknowledgedBNDUPD DHCPv6Opt = 121\n\tDHCPv6OptFMCLT                    DHCPv6Opt = 122\n\tDHCPv6OptFPartnerLifetime         DHCPv6Opt = 123\n\tDHCPv6OptFPartnerLifetimeSent     DHCPv6Opt = 124\n\tDHCPv6OptFPartnerDownTime         DHCPv6Opt = 125\n\tDHCPv6OptFPartnerRawCltTime       DHCPv6Opt = 126\n\tDHCPv6OptFProtocolVersion         DHCPv6Opt = 127\n\tDHCPv6OptFKeepaliveTime           DHCPv6Opt = 128\n\tDHCPv6OptFReconfigureData         DHCPv6Opt = 129\n\tDHCPv6OptFRelationshipName        DHCPv6Opt = 130\n\tDHCPv6OptFServerFlags             DHCPv6Opt = 131\n\tDHCPv6OptFServerState             DHCPv6Opt = 132\n\tDHCPv6OptFStartTimeOfState        DHCPv6Opt = 133\n\tDHCPv6OptFStateExpirationTime     DHCPv6Opt = 134\n\n\t// RFC 8357 Generalized UDP Source Port for DHCP Relay\n\tDHCPv6OptRelayPort DHCPv6Opt = 135\n\n\t// draft-ietf-netconf-zerotouch-25 Zero Touch Provisioning for Networking Devices\n\tDHCPv6OptV6ZeroTouchRedirect DHCPv6Opt = 136\n\n\t// RFC 6153 Access Network Discovery and Selection Function (ANDSF) Discovery\n\tDHCPv6OptIPV6AddressANDSF DHCPv6Opt = 143\n)\n\n// String returns a string version of a DHCPv6Opt.\nfunc (o DHCPv6Opt) String() string {\n\tswitch o {\n\tcase DHCPv6OptClientID:\n\t\treturn \"ClientID\"\n\tcase DHCPv6OptServerID:\n\t\treturn \"ServerID\"\n\tcase DHCPv6OptIANA:\n\t\treturn \"IA_NA\"\n\tcase DHCPv6OptIATA:\n\t\treturn \"IA_TA\"\n\tcase DHCPv6OptIAAddr:\n\t\treturn \"IAAddr\"\n\tcase DHCPv6OptOro:\n\t\treturn \"Oro\"\n\tcase DHCPv6OptPreference:\n\t\treturn \"Preference\"\n\tcase DHCPv6OptElapsedTime:\n\t\treturn \"ElapsedTime\"\n\tcase DHCPv6OptRelayMessage:\n\t\treturn \"RelayMessage\"\n\tcase DHCPv6OptAuth:\n\t\treturn \"Auth\"\n\tcase DHCPv6OptUnicast:\n\t\treturn \"Unicast\"\n\tcase DHCPv6OptStatusCode:\n\t\treturn \"StatusCode\"\n\tcase DHCPv6OptRapidCommit:\n\t\treturn \"RapidCommit\"\n\tcase DHCPv6OptUserClass:\n\t\treturn \"UserClass\"\n\tcase DHCPv6OptVendorClass:\n\t\treturn \"VendorClass\"\n\tcase DHCPv6OptVendorOpts:\n\t\treturn \"VendorOpts\"\n\tcase DHCPv6OptInterfaceID:\n\t\treturn \"InterfaceID\"\n\tcase DHCPv6OptReconfigureMessage:\n\t\treturn \"ReconfigureMessage\"\n\tcase DHCPv6OptReconfigureAccept:\n\t\treturn \"ReconfigureAccept\"\n\tcase DHCPv6OptSIPServersDomainList:\n\t\treturn \"SIPServersDomainList\"\n\tcase DHCPv6OptSIPServersAddressList:\n\t\treturn \"SIPServersAddressList\"\n\tcase DHCPv6OptDNSServers:\n\t\treturn \"DNSRecursiveNameServer\"\n\tcase DHCPv6OptDomainList:\n\t\treturn \"DomainSearchList\"\n\tcase DHCPv6OptIAPD:\n\t\treturn \"IdentityAssociationPrefixDelegation\"\n\tcase DHCPv6OptIAPrefix:\n\t\treturn \"IAPDPrefix\"\n\tcase DHCPv6OptNISServers:\n\t\treturn \"NISServers\"\n\tcase DHCPv6OptNISPServers:\n\t\treturn \"NISv2Servers\"\n\tcase DHCPv6OptNISDomainName:\n\t\treturn \"NISDomainName\"\n\tcase DHCPv6OptNISPDomainName:\n\t\treturn \"NISv2DomainName\"\n\tcase DHCPv6OptSNTPServers:\n\t\treturn \"SNTPServers\"\n\tcase DHCPv6OptInformationRefreshTime:\n\t\treturn \"InformationRefreshTime\"\n\tcase DHCPv6OptBCMCSServerDomainNameList:\n\t\treturn \"BCMCSControlServersDomainNameList\"\n\tcase DHCPv6OptBCMCSServerAddressList:\n\t\treturn \"BCMCSControlServersAddressList\"\n\tcase DHCPv6OptGeoconfCivic:\n\t\treturn \"CivicAddress\"\n\tcase DHCPv6OptRemoteID:\n\t\treturn \"RelayAgentRemoteID\"\n\tcase DHCPv6OptSubscriberID:\n\t\treturn \"RelayAgentSubscriberID\"\n\tcase DHCPv6OptClientFQDN:\n\t\treturn \"ClientFQDN\"\n\tcase DHCPv6OptPanaAgent:\n\t\treturn \"PANAAuthenticationAgent\"\n\tcase DHCPv6OptNewPOSIXTimezone:\n\t\treturn \"NewPOSIXTimezone\"\n\tcase DHCPv6OptNewTZDBTimezone:\n\t\treturn \"NewTZDBTimezone\"\n\tcase DHCPv6OptEchoRequestOption:\n\t\treturn \"EchoRequest\"\n\tcase DHCPv6OptLQQuery:\n\t\treturn \"LeasequeryQuery\"\n\tcase DHCPv6OptClientData:\n\t\treturn \"LeasequeryClientData\"\n\tcase DHCPv6OptCLTTime:\n\t\treturn \"LeasequeryClientLastTransactionTime\"\n\tcase DHCPv6OptLQRelayData:\n\t\treturn \"LeasequeryRelayData\"\n\tcase DHCPv6OptLQClientLink:\n\t\treturn \"LeasequeryClientLink\"\n\tcase DHCPv6OptMIP6HNIDF:\n\t\treturn \"MIPv6HomeNetworkIDFQDN\"\n\tcase DHCPv6OptMIP6VDINF:\n\t\treturn \"MIPv6VisitedHomeNetworkInformation\"\n\tcase DHCPv6OptMIP6IDINF:\n\t\treturn \"MIPv6IdentifiedHomeNetworkInformation\"\n\tcase DHCPv6OptMIP6UDINF:\n\t\treturn \"MIPv6UnrestrictedHomeNetworkInformation\"\n\tcase DHCPv6OptMIP6HNP:\n\t\treturn \"MIPv6HomeNetworkPrefix\"\n\tcase DHCPv6OptMIP6HAA:\n\t\treturn \"MIPv6HomeAgentAddress\"\n\tcase DHCPv6OptMIP6HAF:\n\t\treturn \"MIPv6HomeAgentFQDN\"\n\tcase DHCPv6OptV6LOST:\n\t\treturn \"LoST Server\"\n\tcase DHCPv6OptCAPWAPACV6:\n\t\treturn \"CAPWAPAccessControllerV6\"\n\tcase DHCPv6OptRelayID:\n\t\treturn \"LeasequeryRelayID\"\n\tcase DHCPv6OptIPv6AddressMoS:\n\t\treturn \"MoSIPv6Address\"\n\tcase DHCPv6OptIPv6FQDNMoS:\n\t\treturn \"MoSDomainNameList\"\n\tcase DHCPv6OptNTPServer:\n\t\treturn \"NTPServer\"\n\tcase DHCPv6OptV6AccessDomain:\n\t\treturn \"AccessNetworkDomainName\"\n\tcase DHCPv6OptSIPUACSList:\n\t\treturn \"SIPUserAgentConfigurationServiceDomains\"\n\tcase DHCPv6OptBootFileURL:\n\t\treturn \"BootFileURL\"\n\tcase DHCPv6OptBootFileParam:\n\t\treturn \"BootFileParameters\"\n\tcase DHCPv6OptClientArchType:\n\t\treturn \"ClientSystemArchitectureType\"\n\tcase DHCPv6OptNII:\n\t\treturn \"ClientNetworkInterfaceIdentifier\"\n\tcase DHCPv6OptGeolocation:\n\t\treturn \"Geolocation\"\n\tcase DHCPv6OptAFTRName:\n\t\treturn \"AFTRName\"\n\tcase DHCPv6OptERPLocalDomainName:\n\t\treturn \"AFTRName\"\n\tcase DHCPv6OptRSOO:\n\t\treturn \"RSOOption\"\n\tcase DHCPv6OptPDExclude:\n\t\treturn \"PrefixExclude\"\n\tcase DHCPv6OptVSS:\n\t\treturn \"VirtualSubnetSelection\"\n\tcase DHCPv6OptRDNSSSelection:\n\t\treturn \"RDNSSSelection\"\n\tcase DHCPv6OptKRBPrincipalName:\n\t\treturn \"KerberosPrincipalName\"\n\tcase DHCPv6OptKRBRealmName:\n\t\treturn \"KerberosRealmName\"\n\tcase DHCPv6OptKRBKDC:\n\t\treturn \"KerberosKDC\"\n\tcase DHCPv6OptClientLinkLayerAddress:\n\t\treturn \"ClientLinkLayerAddress\"\n\tcase DHCPv6OptLinkAddress:\n\t\treturn \"LinkAddress\"\n\tcase DHCPv6OptRADIUS:\n\t\treturn \"RADIUS\"\n\tcase DHCPv6OptSolMaxRt:\n\t\treturn \"SolMaxRt\"\n\tcase DHCPv6OptInfMaxRt:\n\t\treturn \"InfMaxRt\"\n\tcase DHCPv6OptAddrSel:\n\t\treturn \"AddressSelection\"\n\tcase DHCPv6OptAddrSelTable:\n\t\treturn \"AddressSelectionTable\"\n\tcase DHCPv6OptV6PCPServer:\n\t\treturn \"PCPServer\"\n\tcase DHCPv6OptDHCPv4Message:\n\t\treturn \"DHCPv4Message\"\n\tcase DHCPv6OptDHCPv4OverDHCPv6Server:\n\t\treturn \"DHCP4o6ServerAddress\"\n\tcase DHCPv6OptS46Rule:\n\t\treturn \"S46Rule\"\n\tcase DHCPv6OptS46BR:\n\t\treturn \"S46BR\"\n\tcase DHCPv6OptS46DMR:\n\t\treturn \"S46DMR\"\n\tcase DHCPv6OptS46V4V4Bind:\n\t\treturn \"S46IPv4IPv6AddressBinding\"\n\tcase DHCPv6OptS46PortParameters:\n\t\treturn \"S46PortParameters\"\n\tcase DHCPv6OptS46ContMAPE:\n\t\treturn \"S46MAPEContainer\"\n\tcase DHCPv6OptS46ContMAPT:\n\t\treturn \"S46MAPTContainer\"\n\tcase DHCPv6OptS46ContLW:\n\t\treturn \"S46Lightweight4Over6Container\"\n\tcase DHCPv6Opt4RD:\n\t\treturn \"4RD\"\n\tcase DHCPv6Opt4RDMapRule:\n\t\treturn \"4RDMapRule\"\n\tcase DHCPv6Opt4RDNonMapRule:\n\t\treturn \"4RDNonMapRule\"\n\tcase DHCPv6OptLQBaseTime:\n\t\treturn \"LQBaseTime\"\n\tcase DHCPv6OptLQStartTime:\n\t\treturn \"LQStartTime\"\n\tcase DHCPv6OptLQEndTime:\n\t\treturn \"LQEndTime\"\n\tcase DHCPv6OptCaptivePortal:\n\t\treturn \"CaptivePortal\"\n\tcase DHCPv6OptMPLParameters:\n\t\treturn \"MPLParameterConfiguration\"\n\tcase DHCPv6OptANIATT:\n\t\treturn \"ANIAccessTechnologyType\"\n\tcase DHCPv6OptANINetworkName:\n\t\treturn \"ANINetworkName\"\n\tcase DHCPv6OptANIAPName:\n\t\treturn \"ANIAccessPointName\"\n\tcase DHCPv6OptANIAPBSSID:\n\t\treturn \"ANIAccessPointBSSID\"\n\tcase DHCPv6OptANIOperatorID:\n\t\treturn \"ANIOperatorIdentifier\"\n\tcase DHCPv6OptANIOperatorRealm:\n\t\treturn \"ANIOperatorRealm\"\n\tcase DHCPv6OptS46Priority:\n\t\treturn \"S64Priority\"\n\tcase DHCPv6OptMUDURLV6:\n\t\treturn \"ManufacturerUsageDescriptionURL\"\n\tcase DHCPv6OptV6Prefix64:\n\t\treturn \"V6Prefix64\"\n\tcase DHCPv6OptFBindingStatus:\n\t\treturn \"FailoverBindingStatus\"\n\tcase DHCPv6OptFConnectFlags:\n\t\treturn \"FailoverConnectFlags\"\n\tcase DHCPv6OptFDNSRemovalInfo:\n\t\treturn \"FailoverDNSRemovalInfo\"\n\tcase DHCPv6OptFDNSHostName:\n\t\treturn \"FailoverDNSHostName\"\n\tcase DHCPv6OptFDNSZoneName:\n\t\treturn \"FailoverDNSZoneName\"\n\tcase DHCPv6OptFDNSFlags:\n\t\treturn \"FailoverDNSFlags\"\n\tcase DHCPv6OptFExpirationTime:\n\t\treturn \"FailoverExpirationTime\"\n\tcase DHCPv6OptFMaxUnacknowledgedBNDUPD:\n\t\treturn \"FailoverMaxUnacknowledgedBNDUPDMessages\"\n\tcase DHCPv6OptFMCLT:\n\t\treturn \"FailoverMaximumClientLeadTime\"\n\tcase DHCPv6OptFPartnerLifetime:\n\t\treturn \"FailoverPartnerLifetime\"\n\tcase DHCPv6OptFPartnerLifetimeSent:\n\t\treturn \"FailoverPartnerLifetimeSent\"\n\tcase DHCPv6OptFPartnerDownTime:\n\t\treturn \"FailoverPartnerDownTime\"\n\tcase DHCPv6OptFPartnerRawCltTime:\n\t\treturn \"FailoverPartnerRawClientLeadTime\"\n\tcase DHCPv6OptFProtocolVersion:\n\t\treturn \"FailoverProtocolVersion\"\n\tcase DHCPv6OptFKeepaliveTime:\n\t\treturn \"FailoverKeepaliveTime\"\n\tcase DHCPv6OptFReconfigureData:\n\t\treturn \"FailoverReconfigureData\"\n\tcase DHCPv6OptFRelationshipName:\n\t\treturn \"FailoverRelationshipName\"\n\tcase DHCPv6OptFServerFlags:\n\t\treturn \"FailoverServerFlags\"\n\tcase DHCPv6OptFServerState:\n\t\treturn \"FailoverServerState\"\n\tcase DHCPv6OptFStartTimeOfState:\n\t\treturn \"FailoverStartTimeOfState\"\n\tcase DHCPv6OptFStateExpirationTime:\n\t\treturn \"FailoverStateExpirationTime\"\n\tcase DHCPv6OptRelayPort:\n\t\treturn \"RelayPort\"\n\tcase DHCPv6OptV6ZeroTouchRedirect:\n\t\treturn \"ZeroTouch\"\n\tcase DHCPv6OptIPV6AddressANDSF:\n\t\treturn \"ANDSFIPv6Address\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"Unknown(%d)\", uint16(o))\n\t}\n}\n\n// DHCPv6Options is used to get nicely printed option lists which would normally\n// be cut off after 5 options.\ntype DHCPv6Options []DHCPv6Option\n\n// String returns a string version of the options list.\nfunc (o DHCPv6Options) String() string {\n\tbuf := &bytes.Buffer{}\n\tbuf.WriteByte('[')\n\tfor i, opt := range o {\n\t\tbuf.WriteString(opt.String())\n\t\tif i+1 != len(o) {\n\t\t\tbuf.WriteString(\", \")\n\t\t}\n\t}\n\tbuf.WriteByte(']')\n\treturn buf.String()\n}\n\n// DHCPv6Option rerpresents a DHCP option.\ntype DHCPv6Option struct {\n\tCode   DHCPv6Opt\n\tLength uint16\n\tData   []byte\n}\n\n// String returns a string version of a DHCP Option.\nfunc (o DHCPv6Option) String() string {\n\tswitch o.Code {\n\tcase DHCPv6OptClientID, DHCPv6OptServerID:\n\t\tduid, err := decodeDHCPv6DUID(o.Data)\n\t\tif err != nil {\n\t\t\treturn fmt.Sprintf(\"Option(%s:INVALID)\", o.Code)\n\t\t}\n\t\treturn fmt.Sprintf(\"Option(%s:[%s])\", o.Code, duid.String())\n\tcase DHCPv6OptOro:\n\t\toptions := \"\"\n\t\tfor i := 0; i < int(o.Length); i += 2 {\n\t\t\tif options != \"\" {\n\t\t\t\toptions += \",\"\n\t\t\t}\n\t\t\toption := DHCPv6Opt(binary.BigEndian.Uint16(o.Data[i : i+2]))\n\t\t\toptions += option.String()\n\t\t}\n\t\treturn fmt.Sprintf(\"Option(%s:[%s])\", o.Code, options)\n\tdefault:\n\t\treturn fmt.Sprintf(\"Option(%s:%v)\", o.Code, o.Data)\n\t}\n}\n\n// NewDHCPv6Option constructs a new DHCPv6Option with a given type and data.\nfunc NewDHCPv6Option(code DHCPv6Opt, data []byte) DHCPv6Option {\n\to := DHCPv6Option{Code: code}\n\tif data != nil {\n\t\to.Data = data\n\t\to.Length = uint16(len(data))\n\t}\n\n\treturn o\n}\n\nfunc (o *DHCPv6Option) encode(b []byte, opts gopacket.SerializeOptions) error {\n\tbinary.BigEndian.PutUint16(b[0:2], uint16(o.Code))\n\tif opts.FixLengths {\n\t\tbinary.BigEndian.PutUint16(b[2:4], uint16(len(o.Data)))\n\t} else {\n\t\tbinary.BigEndian.PutUint16(b[2:4], o.Length)\n\t}\n\tcopy(b[4:], o.Data)\n\n\treturn nil\n}\n\nfunc (o *DHCPv6Option) decode(data []byte) error {\n\tif len(data) < 4 {\n\t\treturn errors.New(\"not enough data to decode\")\n\t}\n\to.Code = DHCPv6Opt(binary.BigEndian.Uint16(data[0:2]))\n\to.Length = binary.BigEndian.Uint16(data[2:4])\n\tif len(data) < 4+int(o.Length) {\n\t\treturn fmt.Errorf(\"dhcpv6 option size < length %d\", 4+o.Length)\n\t}\n\to.Data = data[4 : 4+o.Length]\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/dns.go",
    "content": "// Copyright 2014, 2018 GoPacket Authors. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"strings\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// DNSClass defines the class associated with a request/response.  Different DNS\n// classes can be thought of as an array of parallel namespace trees.\ntype DNSClass uint16\n\n// DNSClass known values.\nconst (\n\tDNSClassIN  DNSClass = 1   // Internet\n\tDNSClassCS  DNSClass = 2   // the CSNET class (Obsolete)\n\tDNSClassCH  DNSClass = 3   // the CHAOS class\n\tDNSClassHS  DNSClass = 4   // Hesiod [Dyer 87]\n\tDNSClassAny DNSClass = 255 // AnyClass\n)\n\nfunc (dc DNSClass) String() string {\n\tswitch dc {\n\tdefault:\n\t\treturn \"Unknown\"\n\tcase DNSClassIN:\n\t\treturn \"IN\"\n\tcase DNSClassCS:\n\t\treturn \"CS\"\n\tcase DNSClassCH:\n\t\treturn \"CH\"\n\tcase DNSClassHS:\n\t\treturn \"HS\"\n\tcase DNSClassAny:\n\t\treturn \"Any\"\n\t}\n}\n\n// DNSType defines the type of data being requested/returned in a\n// question/answer.\ntype DNSType uint16\n\n// DNSType known values.\nconst (\n\tDNSTypeA     DNSType = 1   // a host address\n\tDNSTypeNS    DNSType = 2   // an authoritative name server\n\tDNSTypeMD    DNSType = 3   // a mail destination (Obsolete - use MX)\n\tDNSTypeMF    DNSType = 4   // a mail forwarder (Obsolete - use MX)\n\tDNSTypeCNAME DNSType = 5   // the canonical name for an alias\n\tDNSTypeSOA   DNSType = 6   // marks the start of a zone of authority\n\tDNSTypeMB    DNSType = 7   // a mailbox domain name (EXPERIMENTAL)\n\tDNSTypeMG    DNSType = 8   // a mail group member (EXPERIMENTAL)\n\tDNSTypeMR    DNSType = 9   // a mail rename domain name (EXPERIMENTAL)\n\tDNSTypeNULL  DNSType = 10  // a null RR (EXPERIMENTAL)\n\tDNSTypeWKS   DNSType = 11  // a well known service description\n\tDNSTypePTR   DNSType = 12  // a domain name pointer\n\tDNSTypeHINFO DNSType = 13  // host information\n\tDNSTypeMINFO DNSType = 14  // mailbox or mail list information\n\tDNSTypeMX    DNSType = 15  // mail exchange\n\tDNSTypeTXT   DNSType = 16  // text strings\n\tDNSTypeAAAA  DNSType = 28  // a IPv6 host address [RFC3596]\n\tDNSTypeSRV   DNSType = 33  // server discovery [RFC2782] [RFC6195]\n\tDNSTypeOPT   DNSType = 41  // OPT Pseudo-RR [RFC6891]\n\tDNSTypeURI   DNSType = 256 // URI RR [RFC7553]\n)\n\nfunc (dt DNSType) String() string {\n\tswitch dt {\n\tdefault:\n\t\treturn \"Unknown\"\n\tcase DNSTypeA:\n\t\treturn \"A\"\n\tcase DNSTypeNS:\n\t\treturn \"NS\"\n\tcase DNSTypeMD:\n\t\treturn \"MD\"\n\tcase DNSTypeMF:\n\t\treturn \"MF\"\n\tcase DNSTypeCNAME:\n\t\treturn \"CNAME\"\n\tcase DNSTypeSOA:\n\t\treturn \"SOA\"\n\tcase DNSTypeMB:\n\t\treturn \"MB\"\n\tcase DNSTypeMG:\n\t\treturn \"MG\"\n\tcase DNSTypeMR:\n\t\treturn \"MR\"\n\tcase DNSTypeNULL:\n\t\treturn \"NULL\"\n\tcase DNSTypeWKS:\n\t\treturn \"WKS\"\n\tcase DNSTypePTR:\n\t\treturn \"PTR\"\n\tcase DNSTypeHINFO:\n\t\treturn \"HINFO\"\n\tcase DNSTypeMINFO:\n\t\treturn \"MINFO\"\n\tcase DNSTypeMX:\n\t\treturn \"MX\"\n\tcase DNSTypeTXT:\n\t\treturn \"TXT\"\n\tcase DNSTypeAAAA:\n\t\treturn \"AAAA\"\n\tcase DNSTypeSRV:\n\t\treturn \"SRV\"\n\tcase DNSTypeOPT:\n\t\treturn \"OPT\"\n\tcase DNSTypeURI:\n\t\treturn \"URI\"\n\t}\n}\n\n// DNSResponseCode provides response codes for question answers.\ntype DNSResponseCode uint8\n\n// DNSResponseCode known values.\nconst (\n\tDNSResponseCodeNoErr     DNSResponseCode = 0  // No error\n\tDNSResponseCodeFormErr   DNSResponseCode = 1  // Format Error                       [RFC1035]\n\tDNSResponseCodeServFail  DNSResponseCode = 2  // Server Failure                     [RFC1035]\n\tDNSResponseCodeNXDomain  DNSResponseCode = 3  // Non-Existent Domain                [RFC1035]\n\tDNSResponseCodeNotImp    DNSResponseCode = 4  // Not Implemented                    [RFC1035]\n\tDNSResponseCodeRefused   DNSResponseCode = 5  // Query Refused                      [RFC1035]\n\tDNSResponseCodeYXDomain  DNSResponseCode = 6  // Name Exists when it should not     [RFC2136]\n\tDNSResponseCodeYXRRSet   DNSResponseCode = 7  // RR Set Exists when it should not   [RFC2136]\n\tDNSResponseCodeNXRRSet   DNSResponseCode = 8  // RR Set that should exist does not  [RFC2136]\n\tDNSResponseCodeNotAuth   DNSResponseCode = 9  // Server Not Authoritative for zone  [RFC2136]\n\tDNSResponseCodeNotZone   DNSResponseCode = 10 // Name not contained in zone         [RFC2136]\n\tDNSResponseCodeBadVers   DNSResponseCode = 16 // Bad OPT Version                    [RFC2671]\n\tDNSResponseCodeBadSig    DNSResponseCode = 16 // TSIG Signature Failure             [RFC2845]\n\tDNSResponseCodeBadKey    DNSResponseCode = 17 // Key not recognized                 [RFC2845]\n\tDNSResponseCodeBadTime   DNSResponseCode = 18 // Signature out of time window       [RFC2845]\n\tDNSResponseCodeBadMode   DNSResponseCode = 19 // Bad TKEY Mode                      [RFC2930]\n\tDNSResponseCodeBadName   DNSResponseCode = 20 // Duplicate key name                 [RFC2930]\n\tDNSResponseCodeBadAlg    DNSResponseCode = 21 // Algorithm not supported            [RFC2930]\n\tDNSResponseCodeBadTruc   DNSResponseCode = 22 // Bad Truncation                     [RFC4635]\n\tDNSResponseCodeBadCookie DNSResponseCode = 23 // Bad/missing Server Cookie          [RFC7873]\n)\n\nfunc (drc DNSResponseCode) String() string {\n\tswitch drc {\n\tdefault:\n\t\treturn \"Unknown\"\n\tcase DNSResponseCodeNoErr:\n\t\treturn \"No Error\"\n\tcase DNSResponseCodeFormErr:\n\t\treturn \"Format Error\"\n\tcase DNSResponseCodeServFail:\n\t\treturn \"Server Failure \"\n\tcase DNSResponseCodeNXDomain:\n\t\treturn \"Non-Existent Domain\"\n\tcase DNSResponseCodeNotImp:\n\t\treturn \"Not Implemented\"\n\tcase DNSResponseCodeRefused:\n\t\treturn \"Query Refused\"\n\tcase DNSResponseCodeYXDomain:\n\t\treturn \"Name Exists when it should not\"\n\tcase DNSResponseCodeYXRRSet:\n\t\treturn \"RR Set Exists when it should not\"\n\tcase DNSResponseCodeNXRRSet:\n\t\treturn \"RR Set that should exist does not\"\n\tcase DNSResponseCodeNotAuth:\n\t\treturn \"Server Not Authoritative for zone\"\n\tcase DNSResponseCodeNotZone:\n\t\treturn \"Name not contained in zone\"\n\tcase DNSResponseCodeBadVers:\n\t\treturn \"Bad OPT Version\"\n\tcase DNSResponseCodeBadKey:\n\t\treturn \"Key not recognized\"\n\tcase DNSResponseCodeBadTime:\n\t\treturn \"Signature out of time window\"\n\tcase DNSResponseCodeBadMode:\n\t\treturn \"Bad TKEY Mode\"\n\tcase DNSResponseCodeBadName:\n\t\treturn \"Duplicate key name\"\n\tcase DNSResponseCodeBadAlg:\n\t\treturn \"Algorithm not supported\"\n\tcase DNSResponseCodeBadTruc:\n\t\treturn \"Bad Truncation\"\n\tcase DNSResponseCodeBadCookie:\n\t\treturn \"Bad Cookie\"\n\t}\n}\n\n// DNSOpCode defines a set of different operation types.\ntype DNSOpCode uint8\n\n// DNSOpCode known values.\nconst (\n\tDNSOpCodeQuery  DNSOpCode = 0 // Query                  [RFC1035]\n\tDNSOpCodeIQuery DNSOpCode = 1 // Inverse Query Obsolete [RFC3425]\n\tDNSOpCodeStatus DNSOpCode = 2 // Status                 [RFC1035]\n\tDNSOpCodeNotify DNSOpCode = 4 // Notify                 [RFC1996]\n\tDNSOpCodeUpdate DNSOpCode = 5 // Update                 [RFC2136]\n)\n\nfunc (doc DNSOpCode) String() string {\n\tswitch doc {\n\tdefault:\n\t\treturn \"Unknown\"\n\tcase DNSOpCodeQuery:\n\t\treturn \"Query\"\n\tcase DNSOpCodeIQuery:\n\t\treturn \"Inverse Query\"\n\tcase DNSOpCodeStatus:\n\t\treturn \"Status\"\n\tcase DNSOpCodeNotify:\n\t\treturn \"Notify\"\n\tcase DNSOpCodeUpdate:\n\t\treturn \"Update\"\n\t}\n}\n\n// DNS is specified in RFC 1034 / RFC 1035\n// +---------------------+\n// |        Header       |\n// +---------------------+\n// |       Question      | the question for the name server\n// +---------------------+\n// |        Answer       | RRs answering the question\n// +---------------------+\n// |      Authority      | RRs pointing toward an authority\n// +---------------------+\n// |      Additional     | RRs holding additional information\n// +---------------------+\n//\n//  DNS Header\n//  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                      ID                       |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    QDCOUNT                    |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    ANCOUNT                    |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    NSCOUNT                    |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    ARCOUNT                    |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\n// DNS contains data from a single Domain Name Service packet.\ntype DNS struct {\n\tBaseLayer\n\n\t// Header fields\n\tID     uint16\n\tQR     bool\n\tOpCode DNSOpCode\n\n\tAA bool  // Authoritative answer\n\tTC bool  // Truncated\n\tRD bool  // Recursion desired\n\tRA bool  // Recursion available\n\tZ  uint8 // Reserved for future use\n\n\tResponseCode DNSResponseCode\n\tQDCount      uint16 // Number of questions to expect\n\tANCount      uint16 // Number of answers to expect\n\tNSCount      uint16 // Number of authorities to expect\n\tARCount      uint16 // Number of additional records to expect\n\n\t// Entries\n\tQuestions   []DNSQuestion\n\tAnswers     []DNSResourceRecord\n\tAuthorities []DNSResourceRecord\n\tAdditionals []DNSResourceRecord\n\n\t// buffer for doing name decoding.  We use a single reusable buffer to avoid\n\t// name decoding on a single object via multiple DecodeFromBytes calls\n\t// requiring constant allocation of small byte slices.\n\tbuffer []byte\n}\n\n// LayerType returns gopacket.LayerTypeDNS.\nfunc (d *DNS) LayerType() gopacket.LayerType { return LayerTypeDNS }\n\n// decodeDNS decodes the byte slice into a DNS type. It also\n// setups the application Layer in PacketBuilder.\nfunc decodeDNS(data []byte, p gopacket.PacketBuilder) error {\n\td := &DNS{}\n\terr := d.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\tp.AddLayer(d)\n\tp.SetApplicationLayer(d)\n\treturn nil\n}\n\n// DecodeFromBytes decodes the slice into the DNS struct.\nfunc (d *DNS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\td.buffer = d.buffer[:0]\n\n\tif len(data) < 12 {\n\t\tdf.SetTruncated()\n\t\treturn errDNSPacketTooShort\n\t}\n\n\t// since there are no further layers, the baselayer's content is\n\t// pointing to this layer\n\td.BaseLayer = BaseLayer{Contents: data[:len(data)]}\n\td.ID = binary.BigEndian.Uint16(data[:2])\n\td.QR = data[2]&0x80 != 0\n\td.OpCode = DNSOpCode(data[2]>>3) & 0x0F\n\td.AA = data[2]&0x04 != 0\n\td.TC = data[2]&0x02 != 0\n\td.RD = data[2]&0x01 != 0\n\td.RA = data[3]&0x80 != 0\n\td.Z = uint8(data[3]>>4) & 0x7\n\td.ResponseCode = DNSResponseCode(data[3] & 0xF)\n\td.QDCount = binary.BigEndian.Uint16(data[4:6])\n\td.ANCount = binary.BigEndian.Uint16(data[6:8])\n\td.NSCount = binary.BigEndian.Uint16(data[8:10])\n\td.ARCount = binary.BigEndian.Uint16(data[10:12])\n\n\td.Questions = d.Questions[:0]\n\td.Answers = d.Answers[:0]\n\td.Authorities = d.Authorities[:0]\n\td.Additionals = d.Additionals[:0]\n\n\toffset := 12\n\tvar err error\n\tfor i := 0; i < int(d.QDCount); i++ {\n\t\tvar q DNSQuestion\n\t\tif offset, err = q.decode(data, offset, df, &d.buffer); err != nil {\n\t\t\treturn err\n\t\t}\n\t\td.Questions = append(d.Questions, q)\n\t}\n\n\t// For some horrible reason, if we do the obvious thing in this loop:\n\t//   var r DNSResourceRecord\n\t//   if blah := r.decode(blah); err != nil {\n\t//     return err\n\t//   }\n\t//   d.Foo = append(d.Foo, r)\n\t// the Go compiler thinks that 'r' escapes to the heap, causing a malloc for\n\t// every Answer, Authority, and Additional.  To get around this, we do\n\t// something really silly:  we append an empty resource record to our slice,\n\t// then use the last value in the slice to call decode.  Since the value is\n\t// already in the slice, there's no WAY it can escape... on the other hand our\n\t// code is MUCH uglier :(\n\tfor i := 0; i < int(d.ANCount); i++ {\n\t\td.Answers = append(d.Answers, DNSResourceRecord{})\n\t\tif offset, err = d.Answers[i].decode(data, offset, df, &d.buffer); err != nil {\n\t\t\td.Answers = d.Answers[:i] // strip off erroneous value\n\t\t\treturn err\n\t\t}\n\t}\n\tfor i := 0; i < int(d.NSCount); i++ {\n\t\td.Authorities = append(d.Authorities, DNSResourceRecord{})\n\t\tif offset, err = d.Authorities[i].decode(data, offset, df, &d.buffer); err != nil {\n\t\t\td.Authorities = d.Authorities[:i] // strip off erroneous value\n\t\t\treturn err\n\t\t}\n\t}\n\tfor i := 0; i < int(d.ARCount); i++ {\n\t\td.Additionals = append(d.Additionals, DNSResourceRecord{})\n\t\tif offset, err = d.Additionals[i].decode(data, offset, df, &d.buffer); err != nil {\n\t\t\td.Additionals = d.Additionals[:i] // strip off erroneous value\n\t\t\treturn err\n\t\t}\n\t\t// extract extended RCODE from OPT RRs, RFC 6891 section 6.1.3\n\t\tif d.Additionals[i].Type == DNSTypeOPT {\n\t\t\td.ResponseCode = DNSResponseCode(uint8(d.ResponseCode) | uint8(d.Additionals[i].TTL>>20&0xF0))\n\t\t}\n\t}\n\n\tif uint16(len(d.Questions)) != d.QDCount {\n\t\treturn errDecodeQueryBadQDCount\n\t} else if uint16(len(d.Answers)) != d.ANCount {\n\t\treturn errDecodeQueryBadANCount\n\t} else if uint16(len(d.Authorities)) != d.NSCount {\n\t\treturn errDecodeQueryBadNSCount\n\t} else if uint16(len(d.Additionals)) != d.ARCount {\n\t\treturn errDecodeQueryBadARCount\n\t}\n\treturn nil\n}\n\n// CanDecode implements gopacket.DecodingLayer.\nfunc (d *DNS) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDNS\n}\n\n// NextLayerType implements gopacket.DecodingLayer.\nfunc (d *DNS) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\n// Payload returns nil.\nfunc (d *DNS) Payload() []byte {\n\treturn nil\n}\n\nfunc b2i(b bool) int {\n\tif b {\n\t\treturn 1\n\t}\n\treturn 0\n}\n\nfunc recSize(rr *DNSResourceRecord) int {\n\tswitch rr.Type {\n\tcase DNSTypeA:\n\t\treturn 4\n\tcase DNSTypeAAAA:\n\t\treturn 16\n\tcase DNSTypeNS:\n\t\treturn len(rr.NS) + 2\n\tcase DNSTypeCNAME:\n\t\treturn len(rr.CNAME) + 2\n\tcase DNSTypePTR:\n\t\treturn len(rr.PTR) + 2\n\tcase DNSTypeSOA:\n\t\treturn len(rr.SOA.MName) + 2 + len(rr.SOA.RName) + 2 + 20\n\tcase DNSTypeMX:\n\t\treturn 2 + len(rr.MX.Name) + 2\n\tcase DNSTypeTXT:\n\t\tl := len(rr.TXTs)\n\t\tfor _, txt := range rr.TXTs {\n\t\t\tl += len(txt)\n\t\t}\n\t\treturn l\n\tcase DNSTypeSRV:\n\t\treturn 6 + len(rr.SRV.Name) + 2\n\tcase DNSTypeURI:\n\t\treturn 4 + len(rr.URI.Target)\n\tcase DNSTypeOPT:\n\t\tl := len(rr.OPT) * 4\n\t\tfor _, opt := range rr.OPT {\n\t\t\tl += len(opt.Data)\n\t\t}\n\t\treturn l\n\t}\n\n\treturn 0\n}\n\nfunc computeSize(recs []DNSResourceRecord) int {\n\tsz := 0\n\tfor _, rr := range recs {\n\t\tv := len(rr.Name)\n\n\t\tif v == 0 {\n\t\t\tsz += v + 11\n\t\t} else {\n\t\t\tsz += v + 12\n\t\t}\n\n\t\tsz += recSize(&rr)\n\t}\n\treturn sz\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\nfunc (d *DNS) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tdsz := 0\n\tfor _, q := range d.Questions {\n\t\tdsz += len(q.Name) + 6\n\t}\n\tdsz += computeSize(d.Answers)\n\tdsz += computeSize(d.Authorities)\n\tdsz += computeSize(d.Additionals)\n\n\tbytes, err := b.PrependBytes(12 + dsz)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbinary.BigEndian.PutUint16(bytes, d.ID)\n\tbytes[2] = byte((b2i(d.QR) << 7) | (int(d.OpCode) << 3) | (b2i(d.AA) << 2) | (b2i(d.TC) << 1) | b2i(d.RD))\n\tbytes[3] = byte((b2i(d.RA) << 7) | (int(d.Z) << 4) | int(d.ResponseCode))\n\n\tif opts.FixLengths {\n\t\td.QDCount = uint16(len(d.Questions))\n\t\td.ANCount = uint16(len(d.Answers))\n\t\td.NSCount = uint16(len(d.Authorities))\n\t\td.ARCount = uint16(len(d.Additionals))\n\t}\n\tbinary.BigEndian.PutUint16(bytes[4:], d.QDCount)\n\tbinary.BigEndian.PutUint16(bytes[6:], d.ANCount)\n\tbinary.BigEndian.PutUint16(bytes[8:], d.NSCount)\n\tbinary.BigEndian.PutUint16(bytes[10:], d.ARCount)\n\n\toff := 12\n\tfor _, qd := range d.Questions {\n\t\tn := qd.encode(bytes, off)\n\t\toff += n\n\t}\n\n\tfor i := range d.Answers {\n\t\t// done this way so we can modify DNSResourceRecord to fix\n\t\t// lengths if requested\n\t\tqa := &d.Answers[i]\n\t\tn, err := qa.encode(bytes, off, opts)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\toff += n\n\t}\n\n\tfor i := range d.Authorities {\n\t\tqa := &d.Authorities[i]\n\t\tn, err := qa.encode(bytes, off, opts)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\toff += n\n\t}\n\tfor i := range d.Additionals {\n\t\tqa := &d.Additionals[i]\n\t\tn, err := qa.encode(bytes, off, opts)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\toff += n\n\t}\n\n\treturn nil\n}\n\nconst maxRecursionLevel = 255\n\nfunc decodeName(data []byte, offset int, buffer *[]byte, level int) ([]byte, int, error) {\n\tif level > maxRecursionLevel {\n\t\treturn nil, 0, errMaxRecursion\n\t} else if offset >= len(data) {\n\t\treturn nil, 0, errDNSNameOffsetTooHigh\n\t} else if offset < 0 {\n\t\treturn nil, 0, errDNSNameOffsetNegative\n\t}\n\tstart := len(*buffer)\n\tindex := offset\n\tif data[index] == 0x00 {\n\t\treturn nil, index + 1, nil\n\t}\nloop:\n\tfor data[index] != 0x00 {\n\t\tswitch data[index] & 0xc0 {\n\t\tdefault:\n\t\t\t/* RFC 1035\n\t\t\t   A domain name represented as a sequence of labels, where\n\t\t\t   each label consists of a length octet followed by that\n\t\t\t   number of octets.  The domain name terminates with the\n\t\t\t   zero length octet for the null label of the root.  Note\n\t\t\t   that this field may be an odd number of octets; no\n\t\t\t   padding is used.\n\t\t\t*/\n\t\t\tindex2 := index + int(data[index]) + 1\n\t\t\tif index2-offset > 255 {\n\t\t\t\treturn nil, 0, errDNSNameTooLong\n\t\t\t} else if index2 < index+1 || index2 > len(data) {\n\t\t\t\treturn nil, 0, errDNSNameInvalidIndex\n\t\t\t}\n\t\t\t*buffer = append(*buffer, '.')\n\t\t\t*buffer = append(*buffer, data[index+1:index2]...)\n\t\t\tindex = index2\n\n\t\tcase 0xc0:\n\t\t\t/* RFC 1035\n\t\t\t   The pointer takes the form of a two octet sequence.\n\n\t\t\t   The first two bits are ones.  This allows a pointer to\n\t\t\t   be distinguished from a label, since the label must\n\t\t\t   begin with two zero bits because labels are restricted\n\t\t\t   to 63 octets or less.  (The 10 and 01 combinations are\n\t\t\t   reserved for future use.)  The OFFSET field specifies\n\t\t\t   an offset from the start of the message (i.e., the\n\t\t\t   first octet of the ID field in the domain header).  A\n\t\t\t   zero offset specifies the first byte of the ID field,\n\t\t\t   etc.\n\n\t\t\t   The compression scheme allows a domain name in a message to be\n\t\t\t   represented as either:\n\t\t\t      - a sequence of labels ending in a zero octet\n\t\t\t      - a pointer\n\t\t\t      - a sequence of labels ending with a pointer\n\t\t\t*/\n\t\t\tif index+2 > len(data) {\n\t\t\t\treturn nil, 0, errDNSPointerOffsetTooHigh\n\t\t\t}\n\t\t\toffsetp := int(binary.BigEndian.Uint16(data[index:index+2]) & 0x3fff)\n\t\t\tif offsetp > len(data) {\n\t\t\t\treturn nil, 0, errDNSPointerOffsetTooHigh\n\t\t\t}\n\t\t\t// This looks a little tricky, but actually isn't.  Because of how\n\t\t\t// decodeName is written, calling it appends the decoded name to the\n\t\t\t// current buffer.  We already have the start of the buffer, then, so\n\t\t\t// once this call is done buffer[start:] will contain our full name.\n\t\t\t_, _, err := decodeName(data, offsetp, buffer, level+1)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, 0, err\n\t\t\t}\n\t\t\tindex++ // pointer is two bytes, so add an extra byte here.\n\t\t\tbreak loop\n\t\t/* EDNS, or other DNS option ? */\n\t\tcase 0x40: // RFC 2673\n\t\t\treturn nil, 0, fmt.Errorf(\"qname '0x40' - RFC 2673 unsupported yet (data=%x index=%d)\",\n\t\t\t\tdata[index], index)\n\n\t\tcase 0x80:\n\t\t\treturn nil, 0, fmt.Errorf(\"qname '0x80' unsupported yet (data=%x index=%d)\",\n\t\t\t\tdata[index], index)\n\t\t}\n\t\tif index >= len(data) {\n\t\t\treturn nil, 0, errDNSIndexOutOfRange\n\t\t}\n\t}\n\tif len(*buffer) <= start {\n\t\treturn (*buffer)[start:], index + 1, nil\n\t}\n\treturn (*buffer)[start+1:], index + 1, nil\n}\n\n// DNSQuestion wraps a single request (question) within a DNS query.\ntype DNSQuestion struct {\n\tName  []byte\n\tType  DNSType\n\tClass DNSClass\n}\n\nfunc (q *DNSQuestion) decode(data []byte, offset int, df gopacket.DecodeFeedback, buffer *[]byte) (int, error) {\n\tname, endq, err := decodeName(data, offset, buffer, 1)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tq.Name = name\n\tq.Type = DNSType(binary.BigEndian.Uint16(data[endq : endq+2]))\n\tq.Class = DNSClass(binary.BigEndian.Uint16(data[endq+2 : endq+4]))\n\n\treturn endq + 4, nil\n}\n\nfunc (q *DNSQuestion) encode(data []byte, offset int) int {\n\tnoff := encodeName(q.Name, data, offset)\n\tnSz := noff - offset\n\tbinary.BigEndian.PutUint16(data[noff:], uint16(q.Type))\n\tbinary.BigEndian.PutUint16(data[noff+2:], uint16(q.Class))\n\treturn nSz + 4\n}\n\n//  DNSResourceRecord\n//  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                                               |\n//  /                                               /\n//  /                      NAME                     /\n//  |                                               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                      TYPE                     |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                     CLASS                     |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                      TTL                      |\n//  |                                               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                   RDLENGTH                    |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|\n//  /                     RDATA                     /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\n// DNSResourceRecord wraps the data from a single DNS resource within a\n// response.\ntype DNSResourceRecord struct {\n\t// Header\n\tName  []byte\n\tType  DNSType\n\tClass DNSClass\n\tTTL   uint32\n\n\t// RDATA Raw Values\n\tDataLength uint16\n\tData       []byte\n\n\t// RDATA Decoded Values\n\tIP             net.IP\n\tNS, CNAME, PTR []byte\n\tTXTs           [][]byte\n\tSOA            DNSSOA\n\tSRV            DNSSRV\n\tMX             DNSMX\n\tOPT            []DNSOPT // See RFC 6891, section 6.1.2\n\tURI            DNSURI\n\n\t// Undecoded TXT for backward compatibility\n\tTXT []byte\n}\n\n// decode decodes the resource record, returning the total length of the record.\nfunc (rr *DNSResourceRecord) decode(data []byte, offset int, df gopacket.DecodeFeedback, buffer *[]byte) (int, error) {\n\tname, endq, err := decodeName(data, offset, buffer, 1)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\trr.Name = name\n\trr.Type = DNSType(binary.BigEndian.Uint16(data[endq : endq+2]))\n\trr.Class = DNSClass(binary.BigEndian.Uint16(data[endq+2 : endq+4]))\n\trr.TTL = binary.BigEndian.Uint32(data[endq+4 : endq+8])\n\trr.DataLength = binary.BigEndian.Uint16(data[endq+8 : endq+10])\n\tend := endq + 10 + int(rr.DataLength)\n\tif end > len(data) {\n\t\treturn 0, errDecodeRecordLength\n\t}\n\trr.Data = data[endq+10 : end]\n\n\tif err = rr.decodeRData(data[:end], endq+10, buffer); err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn endq + 10 + int(rr.DataLength), nil\n}\n\nfunc encodeName(name []byte, data []byte, offset int) int {\n\tl := 0\n\tfor i := range name {\n\t\tif name[i] == '.' {\n\t\t\tdata[offset+i-l] = byte(l)\n\t\t\tl = 0\n\t\t} else {\n\t\t\t// skip one to write the length\n\t\t\tdata[offset+i+1] = name[i]\n\t\t\tl++\n\t\t}\n\t}\n\n\tif len(name) == 0 {\n\t\tdata[offset] = 0x00 // terminal\n\t\treturn offset + 1\n\t}\n\n\t// length for final portion\n\tdata[offset+len(name)-l] = byte(l)\n\tdata[offset+len(name)+1] = 0x00 // terminal\n\treturn offset + len(name) + 2\n}\n\nfunc (rr *DNSResourceRecord) encode(data []byte, offset int, opts gopacket.SerializeOptions) (int, error) {\n\n\tnoff := encodeName(rr.Name, data, offset)\n\tnSz := noff - offset\n\n\tbinary.BigEndian.PutUint16(data[noff:], uint16(rr.Type))\n\tbinary.BigEndian.PutUint16(data[noff+2:], uint16(rr.Class))\n\tbinary.BigEndian.PutUint32(data[noff+4:], uint32(rr.TTL))\n\n\tswitch rr.Type {\n\tcase DNSTypeA:\n\t\tcopy(data[noff+10:], rr.IP.To4())\n\tcase DNSTypeAAAA:\n\t\tcopy(data[noff+10:], rr.IP)\n\tcase DNSTypeNS:\n\t\tencodeName(rr.NS, data, noff+10)\n\tcase DNSTypeCNAME:\n\t\tencodeName(rr.CNAME, data, noff+10)\n\tcase DNSTypePTR:\n\t\tencodeName(rr.PTR, data, noff+10)\n\tcase DNSTypeSOA:\n\t\tnoff2 := encodeName(rr.SOA.MName, data, noff+10)\n\t\tnoff2 = encodeName(rr.SOA.RName, data, noff2)\n\t\tbinary.BigEndian.PutUint32(data[noff2:], rr.SOA.Serial)\n\t\tbinary.BigEndian.PutUint32(data[noff2+4:], rr.SOA.Refresh)\n\t\tbinary.BigEndian.PutUint32(data[noff2+8:], rr.SOA.Retry)\n\t\tbinary.BigEndian.PutUint32(data[noff2+12:], rr.SOA.Expire)\n\t\tbinary.BigEndian.PutUint32(data[noff2+16:], rr.SOA.Minimum)\n\tcase DNSTypeMX:\n\t\tbinary.BigEndian.PutUint16(data[noff+10:], rr.MX.Preference)\n\t\tencodeName(rr.MX.Name, data, noff+12)\n\tcase DNSTypeTXT:\n\t\tnoff2 := noff + 10\n\t\tfor _, txt := range rr.TXTs {\n\t\t\tdata[noff2] = byte(len(txt))\n\t\t\tcopy(data[noff2+1:], txt)\n\t\t\tnoff2 += 1 + len(txt)\n\t\t}\n\tcase DNSTypeSRV:\n\t\tbinary.BigEndian.PutUint16(data[noff+10:], rr.SRV.Priority)\n\t\tbinary.BigEndian.PutUint16(data[noff+12:], rr.SRV.Weight)\n\t\tbinary.BigEndian.PutUint16(data[noff+14:], rr.SRV.Port)\n\t\tencodeName(rr.SRV.Name, data, noff+16)\n\tcase DNSTypeURI:\n\t\tbinary.BigEndian.PutUint16(data[noff+10:], rr.URI.Priority)\n\t\tbinary.BigEndian.PutUint16(data[noff+12:], rr.URI.Weight)\n\t\tcopy(data[noff+14:], rr.URI.Target)\n\tcase DNSTypeOPT:\n\t\tnoff2 := noff + 10\n\t\tfor _, opt := range rr.OPT {\n\t\t\tbinary.BigEndian.PutUint16(data[noff2:], uint16(opt.Code))\n\t\t\tbinary.BigEndian.PutUint16(data[noff2+2:], uint16(len(opt.Data)))\n\t\t\tcopy(data[noff2+4:], opt.Data)\n\t\t\tnoff2 += 4 + len(opt.Data)\n\t\t}\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"serializing resource record of type %v not supported\", rr.Type)\n\t}\n\n\t// DataLength\n\tdSz := recSize(rr)\n\tbinary.BigEndian.PutUint16(data[noff+8:], uint16(dSz))\n\n\tif opts.FixLengths {\n\t\trr.DataLength = uint16(dSz)\n\t}\n\n\treturn nSz + 10 + dSz, nil\n}\n\nfunc (rr *DNSResourceRecord) String() string {\n\n\tif rr.Type == DNSTypeOPT {\n\t\topts := make([]string, len(rr.OPT))\n\t\tfor i, opt := range rr.OPT {\n\t\t\topts[i] = opt.String()\n\t\t}\n\t\treturn \"OPT \" + strings.Join(opts, \",\")\n\t}\n\tif rr.Type == DNSTypeURI {\n\t\treturn fmt.Sprintf(\"URI %d %d %s\", rr.URI.Priority, rr.URI.Weight, string(rr.URI.Target))\n\t}\n\tif rr.Class == DNSClassIN {\n\t\tswitch rr.Type {\n\t\tcase DNSTypeA, DNSTypeAAAA:\n\t\t\treturn rr.IP.String()\n\t\tcase DNSTypeNS:\n\t\t\treturn \"NS \" + string(rr.NS)\n\t\tcase DNSTypeCNAME:\n\t\t\treturn \"CNAME \" + string(rr.CNAME)\n\t\tcase DNSTypePTR:\n\t\t\treturn \"PTR \" + string(rr.PTR)\n\t\tcase DNSTypeTXT:\n\t\t\treturn \"TXT \" + string(rr.TXT)\n\t\t}\n\t}\n\n\treturn fmt.Sprintf(\"<%v, %v>\", rr.Class, rr.Type)\n}\n\nfunc decodeCharacterStrings(data []byte) ([][]byte, error) {\n\tstrings := make([][]byte, 0, 1)\n\tend := len(data)\n\tfor index, index2 := 0, 0; index != end; index = index2 {\n\t\tindex2 = index + 1 + int(data[index]) // index increases by 1..256 and does not overflow\n\t\tif index2 > end {\n\t\t\treturn nil, errCharStringMissData\n\t\t}\n\t\tstrings = append(strings, data[index+1:index2])\n\t}\n\treturn strings, nil\n}\n\nfunc decodeOPTs(data []byte, offset int) ([]DNSOPT, error) {\n\tallOPT := []DNSOPT{}\n\tend := len(data)\n\n\tif offset == end {\n\t\treturn allOPT, nil // There is no data to read\n\t}\n\n\tif offset+4 > end {\n\t\treturn allOPT, fmt.Errorf(\"DNSOPT record is of length %d, it should be at least length 4\", end-offset)\n\t}\n\n\tfor i := offset; i < end; {\n\t\topt := DNSOPT{}\n\t\tif len(data) < i+4 {\n\t\t\treturn allOPT, fmt.Errorf(\"Malformed DNSOPT record.  Length %d < %d\", len(data), i+4)\n\t\t}\n\t\topt.Code = DNSOptionCode(binary.BigEndian.Uint16(data[i : i+2]))\n\t\tl := binary.BigEndian.Uint16(data[i+2 : i+4])\n\t\tif i+4+int(l) > end {\n\t\t\treturn allOPT, fmt.Errorf(\"Malformed DNSOPT record. The length (%d) field implies a packet larger than the one received\", l)\n\t\t}\n\t\topt.Data = data[i+4 : i+4+int(l)]\n\t\tallOPT = append(allOPT, opt)\n\t\ti += int(l) + 4\n\t}\n\treturn allOPT, nil\n}\n\nfunc (rr *DNSResourceRecord) decodeRData(data []byte, offset int, buffer *[]byte) error {\n\tswitch rr.Type {\n\tcase DNSTypeA:\n\t\trr.IP = rr.Data\n\tcase DNSTypeAAAA:\n\t\trr.IP = rr.Data\n\tcase DNSTypeTXT, DNSTypeHINFO:\n\t\trr.TXT = rr.Data\n\t\ttxts, err := decodeCharacterStrings(rr.Data)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trr.TXTs = txts\n\tcase DNSTypeNS:\n\t\tname, _, err := decodeName(data, offset, buffer, 1)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trr.NS = name\n\tcase DNSTypeCNAME:\n\t\tname, _, err := decodeName(data, offset, buffer, 1)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trr.CNAME = name\n\tcase DNSTypePTR:\n\t\tname, _, err := decodeName(data, offset, buffer, 1)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trr.PTR = name\n\tcase DNSTypeSOA:\n\t\tname, endq, err := decodeName(data, offset, buffer, 1)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trr.SOA.MName = name\n\t\tname, endq, err = decodeName(data, endq, buffer, 1)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif len(data) < endq+20 {\n\t\t\treturn errors.New(\"SOA too small\")\n\t\t}\n\t\trr.SOA.RName = name\n\t\trr.SOA.Serial = binary.BigEndian.Uint32(data[endq : endq+4])\n\t\trr.SOA.Refresh = binary.BigEndian.Uint32(data[endq+4 : endq+8])\n\t\trr.SOA.Retry = binary.BigEndian.Uint32(data[endq+8 : endq+12])\n\t\trr.SOA.Expire = binary.BigEndian.Uint32(data[endq+12 : endq+16])\n\t\trr.SOA.Minimum = binary.BigEndian.Uint32(data[endq+16 : endq+20])\n\tcase DNSTypeMX:\n\t\tif len(data) < offset+2 {\n\t\t\treturn errors.New(\"MX too small\")\n\t\t}\n\t\trr.MX.Preference = binary.BigEndian.Uint16(data[offset : offset+2])\n\t\tname, _, err := decodeName(data, offset+2, buffer, 1)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trr.MX.Name = name\n\tcase DNSTypeURI:\n\t\tif len(rr.Data) < 4 {\n\t\t\treturn errors.New(\"URI too small\")\n\t\t}\n\t\trr.URI.Priority = binary.BigEndian.Uint16(data[offset : offset+2])\n\t\trr.URI.Weight = binary.BigEndian.Uint16(data[offset+2 : offset+4])\n\t\trr.URI.Target = rr.Data[4:]\n\tcase DNSTypeSRV:\n\t\tif len(data) < offset+6 {\n\t\t\treturn errors.New(\"SRV too small\")\n\t\t}\n\t\trr.SRV.Priority = binary.BigEndian.Uint16(data[offset : offset+2])\n\t\trr.SRV.Weight = binary.BigEndian.Uint16(data[offset+2 : offset+4])\n\t\trr.SRV.Port = binary.BigEndian.Uint16(data[offset+4 : offset+6])\n\t\tname, _, err := decodeName(data, offset+6, buffer, 1)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trr.SRV.Name = name\n\tcase DNSTypeOPT:\n\t\tallOPT, err := decodeOPTs(data, offset)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trr.OPT = allOPT\n\t}\n\treturn nil\n}\n\n// DNSSOA is a Start of Authority record.  Each domain requires a SOA record at\n// the cutover where a domain is delegated from its parent.\ntype DNSSOA struct {\n\tMName, RName                            []byte\n\tSerial, Refresh, Retry, Expire, Minimum uint32\n}\n\n// DNSSRV is a Service record, defining a location (hostname/port) of a\n// server/service.\ntype DNSSRV struct {\n\tPriority, Weight, Port uint16\n\tName                   []byte\n}\n\n// DNSMX is a mail exchange record, defining a mail server for a recipient's\n// domain.\ntype DNSMX struct {\n\tPreference uint16\n\tName       []byte\n}\n\n// DNSURI is a URI record, defining a target (URI) of a server/service\ntype DNSURI struct {\n\tPriority, Weight uint16\n\tTarget           []byte\n}\n\n// DNSOptionCode represents the code of a DNS Option, see RFC6891, section 6.1.2\ntype DNSOptionCode uint16\n\nfunc (doc DNSOptionCode) String() string {\n\tswitch doc {\n\tdefault:\n\t\treturn \"Unknown\"\n\tcase DNSOptionCodeNSID:\n\t\treturn \"NSID\"\n\tcase DNSOptionCodeDAU:\n\t\treturn \"DAU\"\n\tcase DNSOptionCodeDHU:\n\t\treturn \"DHU\"\n\tcase DNSOptionCodeN3U:\n\t\treturn \"N3U\"\n\tcase DNSOptionCodeEDNSClientSubnet:\n\t\treturn \"EDNSClientSubnet\"\n\tcase DNSOptionCodeEDNSExpire:\n\t\treturn \"EDNSExpire\"\n\tcase DNSOptionCodeCookie:\n\t\treturn \"Cookie\"\n\tcase DNSOptionCodeEDNSKeepAlive:\n\t\treturn \"EDNSKeepAlive\"\n\tcase DNSOptionCodePadding:\n\t\treturn \"CodePadding\"\n\tcase DNSOptionCodeChain:\n\t\treturn \"CodeChain\"\n\tcase DNSOptionCodeEDNSKeyTag:\n\t\treturn \"CodeEDNSKeyTag\"\n\tcase DNSOptionCodeEDNSClientTag:\n\t\treturn \"EDNSClientTag\"\n\tcase DNSOptionCodeEDNSServerTag:\n\t\treturn \"EDNSServerTag\"\n\tcase DNSOptionCodeDeviceID:\n\t\treturn \"DeviceID\"\n\t}\n}\n\n// DNSOptionCode known values. See IANA\nconst (\n\tDNSOptionCodeNSID             DNSOptionCode = 3\n\tDNSOptionCodeDAU              DNSOptionCode = 5\n\tDNSOptionCodeDHU              DNSOptionCode = 6\n\tDNSOptionCodeN3U              DNSOptionCode = 7\n\tDNSOptionCodeEDNSClientSubnet DNSOptionCode = 8\n\tDNSOptionCodeEDNSExpire       DNSOptionCode = 9\n\tDNSOptionCodeCookie           DNSOptionCode = 10\n\tDNSOptionCodeEDNSKeepAlive    DNSOptionCode = 11\n\tDNSOptionCodePadding          DNSOptionCode = 12\n\tDNSOptionCodeChain            DNSOptionCode = 13\n\tDNSOptionCodeEDNSKeyTag       DNSOptionCode = 14\n\tDNSOptionCodeEDNSClientTag    DNSOptionCode = 16\n\tDNSOptionCodeEDNSServerTag    DNSOptionCode = 17\n\tDNSOptionCodeDeviceID         DNSOptionCode = 26946\n)\n\n// DNSOPT is a DNS Option, see RFC6891, section 6.1.2\ntype DNSOPT struct {\n\tCode DNSOptionCode\n\tData []byte\n}\n\nfunc (opt DNSOPT) String() string {\n\treturn fmt.Sprintf(\"%s=%x\", opt.Code, opt.Data)\n}\n\nvar (\n\terrMaxRecursion = errors.New(\"max DNS recursion level hit\")\n\n\terrDNSNameOffsetTooHigh    = errors.New(\"dns name offset too high\")\n\terrDNSNameOffsetNegative   = errors.New(\"dns name offset is negative\")\n\terrDNSPacketTooShort       = errors.New(\"DNS packet too short\")\n\terrDNSNameTooLong          = errors.New(\"dns name is too long\")\n\terrDNSNameInvalidIndex     = errors.New(\"dns name uncomputable: invalid index\")\n\terrDNSPointerOffsetTooHigh = errors.New(\"dns offset pointer too high\")\n\terrDNSIndexOutOfRange      = errors.New(\"dns index walked out of range\")\n\terrDNSNameHasNoData        = errors.New(\"no dns data found for name\")\n\n\terrCharStringMissData = errors.New(\"Insufficient data for a <character-string>\")\n\n\terrDecodeRecordLength = errors.New(\"resource record length exceeds data\")\n\n\terrDecodeQueryBadQDCount = errors.New(\"Invalid query decoding, not the right number of questions\")\n\terrDecodeQueryBadANCount = errors.New(\"Invalid query decoding, not the right number of answers\")\n\terrDecodeQueryBadNSCount = errors.New(\"Invalid query decoding, not the right number of authorities\")\n\terrDecodeQueryBadARCount = errors.New(\"Invalid query decoding, not the right number of additionals info\")\n)\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/doc.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\n/*\nPackage layers provides decoding layers for many common protocols.\n\nThe layers package contains decode implementations for a number of different\ntypes of packet layers.  Users of gopacket will almost always want to also use\nlayers to actually decode packet data into useful pieces. To see the set of\nprotocols that gopacket/layers is currently able to decode,\nlook at the set of LayerTypes defined in the Variables sections. The\nlayers package also defines endpoints for many of the common packet layers\nthat have source/destination addresses associated with them, for example IPv4/6\n(IPs) and TCP/UDP (ports).\nFinally, layers contains a number of useful enumerations (IPProtocol,\nEthernetType, LinkType, PPPType, etc...).  Many of these implement the\ngopacket.Decoder interface, so they can be passed into gopacket as decoders.\n\nMost common protocol layers are named using acronyms or other industry-common\nnames (IPv4, TCP, PPP).  Some of the less common ones have their names expanded\n(CiscoDiscoveryProtocol).\nFor certain protocols, sub-parts of the protocol are split out into their own\nlayers (SCTP, for example).  This is done mostly in cases where portions of the\nprotocol may fulfill the capabilities of interesting layers (SCTPData implements\nApplicationLayer, while base SCTP implements TransportLayer), or possibly\nbecause splitting a protocol into a few layers makes decoding easier.\n\nThis package is meant to be used with its parent,\nhttp://github.com/google/gopacket.\n\nPort Types\n\nInstead of using raw uint16 or uint8 values for ports, we use a different port\ntype for every protocol, for example TCPPort and UDPPort.  This allows us to\noverride string behavior for each port, which we do by setting up port name\nmaps (TCPPortNames, UDPPortNames, etc...).  Well-known ports are annotated with\ntheir protocol names, and their String function displays these names:\n\n  p := TCPPort(80)\n  fmt.Printf(\"Number: %d  String: %v\", p, p)\n  // Prints: \"Number: 80  String: 80(http)\"\n\nModifying Decode Behavior\n\nlayers links together decoding through its enumerations.  For example, after\ndecoding layer type Ethernet, it uses Ethernet.EthernetType as its next decoder.\nAll enumerations that act as decoders, like EthernetType, can be modified by\nusers depending on their preferences.  For example, if you have a spiffy new\nIPv4 decoder that works way better than the one built into layers, you can do\nthis:\n\n var mySpiffyIPv4Decoder gopacket.Decoder = ...\n layers.EthernetTypeMetadata[EthernetTypeIPv4].DecodeWith = mySpiffyIPv4Decoder\n\nThis will make all future ethernet packets use your new decoder to decode IPv4\npackets, instead of the built-in decoder used by gopacket.\n*/\npackage layers\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/dot11.go",
    "content": "// Copyright 2014 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\n// See http://standards.ieee.org/findstds/standard/802.11-2012.html for info on\n// all of the layers in this file.\n\npackage layers\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"hash/crc32\"\n\t\"net\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// Dot11Flags contains the set of 8 flags in the IEEE 802.11 frame control\n// header, all in one place.\ntype Dot11Flags uint8\n\nconst (\n\tDot11FlagsToDS Dot11Flags = 1 << iota\n\tDot11FlagsFromDS\n\tDot11FlagsMF\n\tDot11FlagsRetry\n\tDot11FlagsPowerManagement\n\tDot11FlagsMD\n\tDot11FlagsWEP\n\tDot11FlagsOrder\n)\n\nfunc (d Dot11Flags) ToDS() bool {\n\treturn d&Dot11FlagsToDS != 0\n}\nfunc (d Dot11Flags) FromDS() bool {\n\treturn d&Dot11FlagsFromDS != 0\n}\nfunc (d Dot11Flags) MF() bool {\n\treturn d&Dot11FlagsMF != 0\n}\nfunc (d Dot11Flags) Retry() bool {\n\treturn d&Dot11FlagsRetry != 0\n}\nfunc (d Dot11Flags) PowerManagement() bool {\n\treturn d&Dot11FlagsPowerManagement != 0\n}\nfunc (d Dot11Flags) MD() bool {\n\treturn d&Dot11FlagsMD != 0\n}\nfunc (d Dot11Flags) WEP() bool {\n\treturn d&Dot11FlagsWEP != 0\n}\nfunc (d Dot11Flags) Order() bool {\n\treturn d&Dot11FlagsOrder != 0\n}\n\n// String provides a human readable string for Dot11Flags.\n// This string is possibly subject to change over time; if you're storing this\n// persistently, you should probably store the Dot11Flags value, not its string.\nfunc (a Dot11Flags) String() string {\n\tvar out bytes.Buffer\n\tif a.ToDS() {\n\t\tout.WriteString(\"TO-DS,\")\n\t}\n\tif a.FromDS() {\n\t\tout.WriteString(\"FROM-DS,\")\n\t}\n\tif a.MF() {\n\t\tout.WriteString(\"MF,\")\n\t}\n\tif a.Retry() {\n\t\tout.WriteString(\"Retry,\")\n\t}\n\tif a.PowerManagement() {\n\t\tout.WriteString(\"PowerManagement,\")\n\t}\n\tif a.MD() {\n\t\tout.WriteString(\"MD,\")\n\t}\n\tif a.WEP() {\n\t\tout.WriteString(\"WEP,\")\n\t}\n\tif a.Order() {\n\t\tout.WriteString(\"Order,\")\n\t}\n\n\tif length := out.Len(); length > 0 {\n\t\treturn string(out.Bytes()[:length-1]) // strip final comma\n\t}\n\treturn \"\"\n}\n\ntype Dot11Reason uint16\n\n// TODO: Verify these reasons, and append more reasons if necessary.\n\nconst (\n\tDot11ReasonReserved          Dot11Reason = 1\n\tDot11ReasonUnspecified       Dot11Reason = 2\n\tDot11ReasonAuthExpired       Dot11Reason = 3\n\tDot11ReasonDeauthStLeaving   Dot11Reason = 4\n\tDot11ReasonInactivity        Dot11Reason = 5\n\tDot11ReasonApFull            Dot11Reason = 6\n\tDot11ReasonClass2FromNonAuth Dot11Reason = 7\n\tDot11ReasonClass3FromNonAss  Dot11Reason = 8\n\tDot11ReasonDisasStLeaving    Dot11Reason = 9\n\tDot11ReasonStNotAuth         Dot11Reason = 10\n)\n\n// String provides a human readable string for Dot11Reason.\n// This string is possibly subject to change over time; if you're storing this\n// persistently, you should probably store the Dot11Reason value, not its string.\nfunc (a Dot11Reason) String() string {\n\tswitch a {\n\tcase Dot11ReasonReserved:\n\t\treturn \"Reserved\"\n\tcase Dot11ReasonUnspecified:\n\t\treturn \"Unspecified\"\n\tcase Dot11ReasonAuthExpired:\n\t\treturn \"Auth. expired\"\n\tcase Dot11ReasonDeauthStLeaving:\n\t\treturn \"Deauth. st. leaving\"\n\tcase Dot11ReasonInactivity:\n\t\treturn \"Inactivity\"\n\tcase Dot11ReasonApFull:\n\t\treturn \"Ap. full\"\n\tcase Dot11ReasonClass2FromNonAuth:\n\t\treturn \"Class2 from non auth.\"\n\tcase Dot11ReasonClass3FromNonAss:\n\t\treturn \"Class3 from non ass.\"\n\tcase Dot11ReasonDisasStLeaving:\n\t\treturn \"Disass st. leaving\"\n\tcase Dot11ReasonStNotAuth:\n\t\treturn \"St. not auth.\"\n\tdefault:\n\t\treturn \"Unknown reason\"\n\t}\n}\n\ntype Dot11Status uint16\n\nconst (\n\tDot11StatusSuccess                      Dot11Status = 0\n\tDot11StatusFailure                      Dot11Status = 1  // Unspecified failure\n\tDot11StatusCannotSupportAllCapabilities Dot11Status = 10 // Cannot support all requested capabilities in the Capability Information field\n\tDot11StatusInabilityExistsAssociation   Dot11Status = 11 // Reassociation denied due to inability to confirm that association exists\n\tDot11StatusAssociationDenied            Dot11Status = 12 // Association denied due to reason outside the scope of this standard\n\tDot11StatusAlgorithmUnsupported         Dot11Status = 13 // Responding station does not support the specified authentication algorithm\n\tDot11StatusOufOfExpectedSequence        Dot11Status = 14 // Received an Authentication frame with authentication transaction sequence number out of expected sequence\n\tDot11StatusChallengeFailure             Dot11Status = 15 // Authentication rejected because of challenge failure\n\tDot11StatusTimeout                      Dot11Status = 16 // Authentication rejected due to timeout waiting for next frame in sequence\n\tDot11StatusAPUnableToHandle             Dot11Status = 17 // Association denied because AP is unable to handle additional associated stations\n\tDot11StatusRateUnsupported              Dot11Status = 18 // Association denied due to requesting station not supporting all of the data rates in the BSSBasicRateSet parameter\n)\n\n// String provides a human readable string for Dot11Status.\n// This string is possibly subject to change over time; if you're storing this\n// persistently, you should probably store the Dot11Status value, not its string.\nfunc (a Dot11Status) String() string {\n\tswitch a {\n\tcase Dot11StatusSuccess:\n\t\treturn \"success\"\n\tcase Dot11StatusFailure:\n\t\treturn \"failure\"\n\tcase Dot11StatusCannotSupportAllCapabilities:\n\t\treturn \"cannot-support-all-capabilities\"\n\tcase Dot11StatusInabilityExistsAssociation:\n\t\treturn \"inability-exists-association\"\n\tcase Dot11StatusAssociationDenied:\n\t\treturn \"association-denied\"\n\tcase Dot11StatusAlgorithmUnsupported:\n\t\treturn \"algorithm-unsupported\"\n\tcase Dot11StatusOufOfExpectedSequence:\n\t\treturn \"out-of-expected-sequence\"\n\tcase Dot11StatusChallengeFailure:\n\t\treturn \"challenge-failure\"\n\tcase Dot11StatusTimeout:\n\t\treturn \"timeout\"\n\tcase Dot11StatusAPUnableToHandle:\n\t\treturn \"ap-unable-to-handle\"\n\tcase Dot11StatusRateUnsupported:\n\t\treturn \"rate-unsupported\"\n\tdefault:\n\t\treturn \"unknown status\"\n\t}\n}\n\ntype Dot11AckPolicy uint8\n\nconst (\n\tDot11AckPolicyNormal     Dot11AckPolicy = 0\n\tDot11AckPolicyNone       Dot11AckPolicy = 1\n\tDot11AckPolicyNoExplicit Dot11AckPolicy = 2\n\tDot11AckPolicyBlock      Dot11AckPolicy = 3\n)\n\n// String provides a human readable string for Dot11AckPolicy.\n// This string is possibly subject to change over time; if you're storing this\n// persistently, you should probably store the Dot11AckPolicy value, not its string.\nfunc (a Dot11AckPolicy) String() string {\n\tswitch a {\n\tcase Dot11AckPolicyNormal:\n\t\treturn \"normal-ack\"\n\tcase Dot11AckPolicyNone:\n\t\treturn \"no-ack\"\n\tcase Dot11AckPolicyNoExplicit:\n\t\treturn \"no-explicit-ack\"\n\tcase Dot11AckPolicyBlock:\n\t\treturn \"block-ack\"\n\tdefault:\n\t\treturn \"unknown-ack-policy\"\n\t}\n}\n\ntype Dot11Algorithm uint16\n\nconst (\n\tDot11AlgorithmOpen      Dot11Algorithm = 0\n\tDot11AlgorithmSharedKey Dot11Algorithm = 1\n)\n\n// String provides a human readable string for Dot11Algorithm.\n// This string is possibly subject to change over time; if you're storing this\n// persistently, you should probably store the Dot11Algorithm value, not its string.\nfunc (a Dot11Algorithm) String() string {\n\tswitch a {\n\tcase Dot11AlgorithmOpen:\n\t\treturn \"open\"\n\tcase Dot11AlgorithmSharedKey:\n\t\treturn \"shared-key\"\n\tdefault:\n\t\treturn \"unknown-algorithm\"\n\t}\n}\n\ntype Dot11InformationElementID uint8\n\nconst (\n\tDot11InformationElementIDSSID                      Dot11InformationElementID = 0\n\tDot11InformationElementIDRates                     Dot11InformationElementID = 1\n\tDot11InformationElementIDFHSet                     Dot11InformationElementID = 2\n\tDot11InformationElementIDDSSet                     Dot11InformationElementID = 3\n\tDot11InformationElementIDCFSet                     Dot11InformationElementID = 4\n\tDot11InformationElementIDTIM                       Dot11InformationElementID = 5\n\tDot11InformationElementIDIBSSSet                   Dot11InformationElementID = 6\n\tDot11InformationElementIDCountryInfo               Dot11InformationElementID = 7\n\tDot11InformationElementIDHoppingPatternParam       Dot11InformationElementID = 8\n\tDot11InformationElementIDHoppingPatternTable       Dot11InformationElementID = 9\n\tDot11InformationElementIDRequest                   Dot11InformationElementID = 10\n\tDot11InformationElementIDQBSSLoadElem              Dot11InformationElementID = 11\n\tDot11InformationElementIDEDCAParamSet              Dot11InformationElementID = 12\n\tDot11InformationElementIDTrafficSpec               Dot11InformationElementID = 13\n\tDot11InformationElementIDTrafficClass              Dot11InformationElementID = 14\n\tDot11InformationElementIDSchedule                  Dot11InformationElementID = 15\n\tDot11InformationElementIDChallenge                 Dot11InformationElementID = 16\n\tDot11InformationElementIDPowerConst                Dot11InformationElementID = 32\n\tDot11InformationElementIDPowerCapability           Dot11InformationElementID = 33\n\tDot11InformationElementIDTPCRequest                Dot11InformationElementID = 34\n\tDot11InformationElementIDTPCReport                 Dot11InformationElementID = 35\n\tDot11InformationElementIDSupportedChannels         Dot11InformationElementID = 36\n\tDot11InformationElementIDSwitchChannelAnnounce     Dot11InformationElementID = 37\n\tDot11InformationElementIDMeasureRequest            Dot11InformationElementID = 38\n\tDot11InformationElementIDMeasureReport             Dot11InformationElementID = 39\n\tDot11InformationElementIDQuiet                     Dot11InformationElementID = 40\n\tDot11InformationElementIDIBSSDFS                   Dot11InformationElementID = 41\n\tDot11InformationElementIDERPInfo                   Dot11InformationElementID = 42\n\tDot11InformationElementIDTSDelay                   Dot11InformationElementID = 43\n\tDot11InformationElementIDTCLASProcessing           Dot11InformationElementID = 44\n\tDot11InformationElementIDHTCapabilities            Dot11InformationElementID = 45\n\tDot11InformationElementIDQOSCapability             Dot11InformationElementID = 46\n\tDot11InformationElementIDERPInfo2                  Dot11InformationElementID = 47\n\tDot11InformationElementIDRSNInfo                   Dot11InformationElementID = 48\n\tDot11InformationElementIDESRates                   Dot11InformationElementID = 50\n\tDot11InformationElementIDAPChannelReport           Dot11InformationElementID = 51\n\tDot11InformationElementIDNeighborReport            Dot11InformationElementID = 52\n\tDot11InformationElementIDRCPI                      Dot11InformationElementID = 53\n\tDot11InformationElementIDMobilityDomain            Dot11InformationElementID = 54\n\tDot11InformationElementIDFastBSSTrans              Dot11InformationElementID = 55\n\tDot11InformationElementIDTimeoutInt                Dot11InformationElementID = 56\n\tDot11InformationElementIDRICData                   Dot11InformationElementID = 57\n\tDot11InformationElementIDDSERegisteredLoc          Dot11InformationElementID = 58\n\tDot11InformationElementIDSuppOperatingClass        Dot11InformationElementID = 59\n\tDot11InformationElementIDExtChanSwitchAnnounce     Dot11InformationElementID = 60\n\tDot11InformationElementIDHTInfo                    Dot11InformationElementID = 61\n\tDot11InformationElementIDSecChanOffset             Dot11InformationElementID = 62\n\tDot11InformationElementIDBSSAverageAccessDelay     Dot11InformationElementID = 63\n\tDot11InformationElementIDAntenna                   Dot11InformationElementID = 64\n\tDot11InformationElementIDRSNI                      Dot11InformationElementID = 65\n\tDot11InformationElementIDMeasurePilotTrans         Dot11InformationElementID = 66\n\tDot11InformationElementIDBSSAvailAdmCapacity       Dot11InformationElementID = 67\n\tDot11InformationElementIDBSSACAccDelayWAPIParam    Dot11InformationElementID = 68\n\tDot11InformationElementIDTimeAdvertisement         Dot11InformationElementID = 69\n\tDot11InformationElementIDRMEnabledCapabilities     Dot11InformationElementID = 70\n\tDot11InformationElementIDMultipleBSSID             Dot11InformationElementID = 71\n\tDot11InformationElementID2040BSSCoExist            Dot11InformationElementID = 72\n\tDot11InformationElementID2040BSSIntChanReport      Dot11InformationElementID = 73\n\tDot11InformationElementIDOverlapBSSScanParam       Dot11InformationElementID = 74\n\tDot11InformationElementIDRICDescriptor             Dot11InformationElementID = 75\n\tDot11InformationElementIDManagementMIC             Dot11InformationElementID = 76\n\tDot11InformationElementIDEventRequest              Dot11InformationElementID = 78\n\tDot11InformationElementIDEventReport               Dot11InformationElementID = 79\n\tDot11InformationElementIDDiagnosticRequest         Dot11InformationElementID = 80\n\tDot11InformationElementIDDiagnosticReport          Dot11InformationElementID = 81\n\tDot11InformationElementIDLocationParam             Dot11InformationElementID = 82\n\tDot11InformationElementIDNonTransBSSIDCapability   Dot11InformationElementID = 83\n\tDot11InformationElementIDSSIDList                  Dot11InformationElementID = 84\n\tDot11InformationElementIDMultipleBSSIDIndex        Dot11InformationElementID = 85\n\tDot11InformationElementIDFMSDescriptor             Dot11InformationElementID = 86\n\tDot11InformationElementIDFMSRequest                Dot11InformationElementID = 87\n\tDot11InformationElementIDFMSResponse               Dot11InformationElementID = 88\n\tDot11InformationElementIDQOSTrafficCapability      Dot11InformationElementID = 89\n\tDot11InformationElementIDBSSMaxIdlePeriod          Dot11InformationElementID = 90\n\tDot11InformationElementIDTFSRequest                Dot11InformationElementID = 91\n\tDot11InformationElementIDTFSResponse               Dot11InformationElementID = 92\n\tDot11InformationElementIDWNMSleepMode              Dot11InformationElementID = 93\n\tDot11InformationElementIDTIMBroadcastRequest       Dot11InformationElementID = 94\n\tDot11InformationElementIDTIMBroadcastResponse      Dot11InformationElementID = 95\n\tDot11InformationElementIDCollInterferenceReport    Dot11InformationElementID = 96\n\tDot11InformationElementIDChannelUsage              Dot11InformationElementID = 97\n\tDot11InformationElementIDTimeZone                  Dot11InformationElementID = 98\n\tDot11InformationElementIDDMSRequest                Dot11InformationElementID = 99\n\tDot11InformationElementIDDMSResponse               Dot11InformationElementID = 100\n\tDot11InformationElementIDLinkIdentifier            Dot11InformationElementID = 101\n\tDot11InformationElementIDWakeupSchedule            Dot11InformationElementID = 102\n\tDot11InformationElementIDChannelSwitchTiming       Dot11InformationElementID = 104\n\tDot11InformationElementIDPTIControl                Dot11InformationElementID = 105\n\tDot11InformationElementIDPUBufferStatus            Dot11InformationElementID = 106\n\tDot11InformationElementIDInterworking              Dot11InformationElementID = 107\n\tDot11InformationElementIDAdvertisementProtocol     Dot11InformationElementID = 108\n\tDot11InformationElementIDExpBWRequest              Dot11InformationElementID = 109\n\tDot11InformationElementIDQOSMapSet                 Dot11InformationElementID = 110\n\tDot11InformationElementIDRoamingConsortium         Dot11InformationElementID = 111\n\tDot11InformationElementIDEmergencyAlertIdentifier  Dot11InformationElementID = 112\n\tDot11InformationElementIDMeshConfiguration         Dot11InformationElementID = 113\n\tDot11InformationElementIDMeshID                    Dot11InformationElementID = 114\n\tDot11InformationElementIDMeshLinkMetricReport      Dot11InformationElementID = 115\n\tDot11InformationElementIDCongestionNotification    Dot11InformationElementID = 116\n\tDot11InformationElementIDMeshPeeringManagement     Dot11InformationElementID = 117\n\tDot11InformationElementIDMeshChannelSwitchParam    Dot11InformationElementID = 118\n\tDot11InformationElementIDMeshAwakeWindows          Dot11InformationElementID = 119\n\tDot11InformationElementIDBeaconTiming              Dot11InformationElementID = 120\n\tDot11InformationElementIDMCCAOPSetupRequest        Dot11InformationElementID = 121\n\tDot11InformationElementIDMCCAOPSetupReply          Dot11InformationElementID = 122\n\tDot11InformationElementIDMCCAOPAdvertisement       Dot11InformationElementID = 123\n\tDot11InformationElementIDMCCAOPTeardown            Dot11InformationElementID = 124\n\tDot11InformationElementIDGateAnnouncement          Dot11InformationElementID = 125\n\tDot11InformationElementIDRootAnnouncement          Dot11InformationElementID = 126\n\tDot11InformationElementIDExtCapability             Dot11InformationElementID = 127\n\tDot11InformationElementIDAgereProprietary          Dot11InformationElementID = 128\n\tDot11InformationElementIDPathRequest               Dot11InformationElementID = 130\n\tDot11InformationElementIDPathReply                 Dot11InformationElementID = 131\n\tDot11InformationElementIDPathError                 Dot11InformationElementID = 132\n\tDot11InformationElementIDCiscoCCX1CKIPDeviceName   Dot11InformationElementID = 133\n\tDot11InformationElementIDCiscoCCX2                 Dot11InformationElementID = 136\n\tDot11InformationElementIDProxyUpdate               Dot11InformationElementID = 137\n\tDot11InformationElementIDProxyUpdateConfirmation   Dot11InformationElementID = 138\n\tDot11InformationElementIDAuthMeshPerringExch       Dot11InformationElementID = 139\n\tDot11InformationElementIDMIC                       Dot11InformationElementID = 140\n\tDot11InformationElementIDDestinationURI            Dot11InformationElementID = 141\n\tDot11InformationElementIDUAPSDCoexistence          Dot11InformationElementID = 142\n\tDot11InformationElementIDWakeupSchedule80211ad     Dot11InformationElementID = 143\n\tDot11InformationElementIDExtendedSchedule          Dot11InformationElementID = 144\n\tDot11InformationElementIDSTAAvailability           Dot11InformationElementID = 145\n\tDot11InformationElementIDDMGTSPEC                  Dot11InformationElementID = 146\n\tDot11InformationElementIDNextDMGATI                Dot11InformationElementID = 147\n\tDot11InformationElementIDDMSCapabilities           Dot11InformationElementID = 148\n\tDot11InformationElementIDCiscoUnknown95            Dot11InformationElementID = 149\n\tDot11InformationElementIDVendor2                   Dot11InformationElementID = 150\n\tDot11InformationElementIDDMGOperating              Dot11InformationElementID = 151\n\tDot11InformationElementIDDMGBSSParamChange         Dot11InformationElementID = 152\n\tDot11InformationElementIDDMGBeamRefinement         Dot11InformationElementID = 153\n\tDot11InformationElementIDChannelMeasFeedback       Dot11InformationElementID = 154\n\tDot11InformationElementIDAwakeWindow               Dot11InformationElementID = 157\n\tDot11InformationElementIDMultiBand                 Dot11InformationElementID = 158\n\tDot11InformationElementIDADDBAExtension            Dot11InformationElementID = 159\n\tDot11InformationElementIDNEXTPCPList               Dot11InformationElementID = 160\n\tDot11InformationElementIDPCPHandover               Dot11InformationElementID = 161\n\tDot11InformationElementIDDMGLinkMargin             Dot11InformationElementID = 162\n\tDot11InformationElementIDSwitchingStream           Dot11InformationElementID = 163\n\tDot11InformationElementIDSessionTransmission       Dot11InformationElementID = 164\n\tDot11InformationElementIDDynamicTonePairReport     Dot11InformationElementID = 165\n\tDot11InformationElementIDClusterReport             Dot11InformationElementID = 166\n\tDot11InformationElementIDRelayCapabilities         Dot11InformationElementID = 167\n\tDot11InformationElementIDRelayTransferParameter    Dot11InformationElementID = 168\n\tDot11InformationElementIDBeamlinkMaintenance       Dot11InformationElementID = 169\n\tDot11InformationElementIDMultipleMacSublayers      Dot11InformationElementID = 170\n\tDot11InformationElementIDUPID                      Dot11InformationElementID = 171\n\tDot11InformationElementIDDMGLinkAdaptionAck        Dot11InformationElementID = 172\n\tDot11InformationElementIDSymbolProprietary         Dot11InformationElementID = 173\n\tDot11InformationElementIDMCCAOPAdvertOverview      Dot11InformationElementID = 174\n\tDot11InformationElementIDQuietPeriodRequest        Dot11InformationElementID = 175\n\tDot11InformationElementIDQuietPeriodResponse       Dot11InformationElementID = 177\n\tDot11InformationElementIDECPACPolicy               Dot11InformationElementID = 182\n\tDot11InformationElementIDClusterTimeOffset         Dot11InformationElementID = 183\n\tDot11InformationElementIDAntennaSectorID           Dot11InformationElementID = 190\n\tDot11InformationElementIDVHTCapabilities           Dot11InformationElementID = 191\n\tDot11InformationElementIDVHTOperation              Dot11InformationElementID = 192\n\tDot11InformationElementIDExtendedBSSLoad           Dot11InformationElementID = 193\n\tDot11InformationElementIDWideBWChannelSwitch       Dot11InformationElementID = 194\n\tDot11InformationElementIDVHTTxPowerEnvelope        Dot11InformationElementID = 195\n\tDot11InformationElementIDChannelSwitchWrapper      Dot11InformationElementID = 196\n\tDot11InformationElementIDOperatingModeNotification Dot11InformationElementID = 199\n\tDot11InformationElementIDUPSIM                     Dot11InformationElementID = 200\n\tDot11InformationElementIDReducedNeighborReport     Dot11InformationElementID = 201\n\tDot11InformationElementIDTVHTOperation             Dot11InformationElementID = 202\n\tDot11InformationElementIDDeviceLocation            Dot11InformationElementID = 204\n\tDot11InformationElementIDWhiteSpaceMap             Dot11InformationElementID = 205\n\tDot11InformationElementIDFineTuningMeasureParams   Dot11InformationElementID = 206\n\tDot11InformationElementIDVendor                    Dot11InformationElementID = 221\n)\n\n// String provides a human readable string for Dot11InformationElementID.\n// This string is possibly subject to change over time; if you're storing this\n// persistently, you should probably store the Dot11InformationElementID value,\n// not its string.\nfunc (a Dot11InformationElementID) String() string {\n\tswitch a {\n\tcase Dot11InformationElementIDSSID:\n\t\treturn \"SSID parameter set\"\n\tcase Dot11InformationElementIDRates:\n\t\treturn \"Supported Rates\"\n\tcase Dot11InformationElementIDFHSet:\n\t\treturn \"FH Parameter set\"\n\tcase Dot11InformationElementIDDSSet:\n\t\treturn \"DS Parameter set\"\n\tcase Dot11InformationElementIDCFSet:\n\t\treturn \"CF Parameter set\"\n\tcase Dot11InformationElementIDTIM:\n\t\treturn \"Traffic Indication Map (TIM)\"\n\tcase Dot11InformationElementIDIBSSSet:\n\t\treturn \"IBSS Parameter set\"\n\tcase Dot11InformationElementIDCountryInfo:\n\t\treturn \"Country Information\"\n\tcase Dot11InformationElementIDHoppingPatternParam:\n\t\treturn \"Hopping Pattern Parameters\"\n\tcase Dot11InformationElementIDHoppingPatternTable:\n\t\treturn \"Hopping Pattern Table\"\n\tcase Dot11InformationElementIDRequest:\n\t\treturn \"Request\"\n\tcase Dot11InformationElementIDQBSSLoadElem:\n\t\treturn \"QBSS Load Element\"\n\tcase Dot11InformationElementIDEDCAParamSet:\n\t\treturn \"EDCA Parameter Set\"\n\tcase Dot11InformationElementIDTrafficSpec:\n\t\treturn \"Traffic Specification\"\n\tcase Dot11InformationElementIDTrafficClass:\n\t\treturn \"Traffic Classification\"\n\tcase Dot11InformationElementIDSchedule:\n\t\treturn \"Schedule\"\n\tcase Dot11InformationElementIDChallenge:\n\t\treturn \"Challenge text\"\n\tcase Dot11InformationElementIDPowerConst:\n\t\treturn \"Power Constraint\"\n\tcase Dot11InformationElementIDPowerCapability:\n\t\treturn \"Power Capability\"\n\tcase Dot11InformationElementIDTPCRequest:\n\t\treturn \"TPC Request\"\n\tcase Dot11InformationElementIDTPCReport:\n\t\treturn \"TPC Report\"\n\tcase Dot11InformationElementIDSupportedChannels:\n\t\treturn \"Supported Channels\"\n\tcase Dot11InformationElementIDSwitchChannelAnnounce:\n\t\treturn \"Channel Switch Announcement\"\n\tcase Dot11InformationElementIDMeasureRequest:\n\t\treturn \"Measurement Request\"\n\tcase Dot11InformationElementIDMeasureReport:\n\t\treturn \"Measurement Report\"\n\tcase Dot11InformationElementIDQuiet:\n\t\treturn \"Quiet\"\n\tcase Dot11InformationElementIDIBSSDFS:\n\t\treturn \"IBSS DFS\"\n\tcase Dot11InformationElementIDERPInfo:\n\t\treturn \"ERP Information\"\n\tcase Dot11InformationElementIDTSDelay:\n\t\treturn \"TS Delay\"\n\tcase Dot11InformationElementIDTCLASProcessing:\n\t\treturn \"TCLAS Processing\"\n\tcase Dot11InformationElementIDHTCapabilities:\n\t\treturn \"HT Capabilities (802.11n D1.10)\"\n\tcase Dot11InformationElementIDQOSCapability:\n\t\treturn \"QOS Capability\"\n\tcase Dot11InformationElementIDERPInfo2:\n\t\treturn \"ERP Information-2\"\n\tcase Dot11InformationElementIDRSNInfo:\n\t\treturn \"RSN Information\"\n\tcase Dot11InformationElementIDESRates:\n\t\treturn \"Extended Supported Rates\"\n\tcase Dot11InformationElementIDAPChannelReport:\n\t\treturn \"AP Channel Report\"\n\tcase Dot11InformationElementIDNeighborReport:\n\t\treturn \"Neighbor Report\"\n\tcase Dot11InformationElementIDRCPI:\n\t\treturn \"RCPI\"\n\tcase Dot11InformationElementIDMobilityDomain:\n\t\treturn \"Mobility Domain\"\n\tcase Dot11InformationElementIDFastBSSTrans:\n\t\treturn \"Fast BSS Transition\"\n\tcase Dot11InformationElementIDTimeoutInt:\n\t\treturn \"Timeout Interval\"\n\tcase Dot11InformationElementIDRICData:\n\t\treturn \"RIC Data\"\n\tcase Dot11InformationElementIDDSERegisteredLoc:\n\t\treturn \"DSE Registered Location\"\n\tcase Dot11InformationElementIDSuppOperatingClass:\n\t\treturn \"Supported Operating Classes\"\n\tcase Dot11InformationElementIDExtChanSwitchAnnounce:\n\t\treturn \"Extended Channel Switch Announcement\"\n\tcase Dot11InformationElementIDHTInfo:\n\t\treturn \"HT Information (802.11n D1.10)\"\n\tcase Dot11InformationElementIDSecChanOffset:\n\t\treturn \"Secondary Channel Offset (802.11n D1.10)\"\n\tcase Dot11InformationElementIDBSSAverageAccessDelay:\n\t\treturn \"BSS Average Access Delay\"\n\tcase Dot11InformationElementIDAntenna:\n\t\treturn \"Antenna\"\n\tcase Dot11InformationElementIDRSNI:\n\t\treturn \"RSNI\"\n\tcase Dot11InformationElementIDMeasurePilotTrans:\n\t\treturn \"Measurement Pilot Transmission\"\n\tcase Dot11InformationElementIDBSSAvailAdmCapacity:\n\t\treturn \"BSS Available Admission Capacity\"\n\tcase Dot11InformationElementIDBSSACAccDelayWAPIParam:\n\t\treturn \"BSS AC Access Delay/WAPI Parameter Set\"\n\tcase Dot11InformationElementIDTimeAdvertisement:\n\t\treturn \"Time Advertisement\"\n\tcase Dot11InformationElementIDRMEnabledCapabilities:\n\t\treturn \"RM Enabled Capabilities\"\n\tcase Dot11InformationElementIDMultipleBSSID:\n\t\treturn \"Multiple BSSID\"\n\tcase Dot11InformationElementID2040BSSCoExist:\n\t\treturn \"20/40 BSS Coexistence\"\n\tcase Dot11InformationElementID2040BSSIntChanReport:\n\t\treturn \"20/40 BSS Intolerant Channel Report\"\n\tcase Dot11InformationElementIDOverlapBSSScanParam:\n\t\treturn \"Overlapping BSS Scan Parameters\"\n\tcase Dot11InformationElementIDRICDescriptor:\n\t\treturn \"RIC Descriptor\"\n\tcase Dot11InformationElementIDManagementMIC:\n\t\treturn \"Management MIC\"\n\tcase Dot11InformationElementIDEventRequest:\n\t\treturn \"Event Request\"\n\tcase Dot11InformationElementIDEventReport:\n\t\treturn \"Event Report\"\n\tcase Dot11InformationElementIDDiagnosticRequest:\n\t\treturn \"Diagnostic Request\"\n\tcase Dot11InformationElementIDDiagnosticReport:\n\t\treturn \"Diagnostic Report\"\n\tcase Dot11InformationElementIDLocationParam:\n\t\treturn \"Location Parameters\"\n\tcase Dot11InformationElementIDNonTransBSSIDCapability:\n\t\treturn \"Non Transmitted BSSID Capability\"\n\tcase Dot11InformationElementIDSSIDList:\n\t\treturn \"SSID List\"\n\tcase Dot11InformationElementIDMultipleBSSIDIndex:\n\t\treturn \"Multiple BSSID Index\"\n\tcase Dot11InformationElementIDFMSDescriptor:\n\t\treturn \"FMS Descriptor\"\n\tcase Dot11InformationElementIDFMSRequest:\n\t\treturn \"FMS Request\"\n\tcase Dot11InformationElementIDFMSResponse:\n\t\treturn \"FMS Response\"\n\tcase Dot11InformationElementIDQOSTrafficCapability:\n\t\treturn \"QoS Traffic Capability\"\n\tcase Dot11InformationElementIDBSSMaxIdlePeriod:\n\t\treturn \"BSS Max Idle Period\"\n\tcase Dot11InformationElementIDTFSRequest:\n\t\treturn \"TFS Request\"\n\tcase Dot11InformationElementIDTFSResponse:\n\t\treturn \"TFS Response\"\n\tcase Dot11InformationElementIDWNMSleepMode:\n\t\treturn \"WNM-Sleep Mode\"\n\tcase Dot11InformationElementIDTIMBroadcastRequest:\n\t\treturn \"TIM Broadcast Request\"\n\tcase Dot11InformationElementIDTIMBroadcastResponse:\n\t\treturn \"TIM Broadcast Response\"\n\tcase Dot11InformationElementIDCollInterferenceReport:\n\t\treturn \"Collocated Interference Report\"\n\tcase Dot11InformationElementIDChannelUsage:\n\t\treturn \"Channel Usage\"\n\tcase Dot11InformationElementIDTimeZone:\n\t\treturn \"Time Zone\"\n\tcase Dot11InformationElementIDDMSRequest:\n\t\treturn \"DMS Request\"\n\tcase Dot11InformationElementIDDMSResponse:\n\t\treturn \"DMS Response\"\n\tcase Dot11InformationElementIDLinkIdentifier:\n\t\treturn \"Link Identifier\"\n\tcase Dot11InformationElementIDWakeupSchedule:\n\t\treturn \"Wakeup Schedule\"\n\tcase Dot11InformationElementIDChannelSwitchTiming:\n\t\treturn \"Channel Switch Timing\"\n\tcase Dot11InformationElementIDPTIControl:\n\t\treturn \"PTI Control\"\n\tcase Dot11InformationElementIDPUBufferStatus:\n\t\treturn \"PU Buffer Status\"\n\tcase Dot11InformationElementIDInterworking:\n\t\treturn \"Interworking\"\n\tcase Dot11InformationElementIDAdvertisementProtocol:\n\t\treturn \"Advertisement Protocol\"\n\tcase Dot11InformationElementIDExpBWRequest:\n\t\treturn \"Expedited Bandwidth Request\"\n\tcase Dot11InformationElementIDQOSMapSet:\n\t\treturn \"QoS Map Set\"\n\tcase Dot11InformationElementIDRoamingConsortium:\n\t\treturn \"Roaming Consortium\"\n\tcase Dot11InformationElementIDEmergencyAlertIdentifier:\n\t\treturn \"Emergency Alert Identifier\"\n\tcase Dot11InformationElementIDMeshConfiguration:\n\t\treturn \"Mesh Configuration\"\n\tcase Dot11InformationElementIDMeshID:\n\t\treturn \"Mesh ID\"\n\tcase Dot11InformationElementIDMeshLinkMetricReport:\n\t\treturn \"Mesh Link Metric Report\"\n\tcase Dot11InformationElementIDCongestionNotification:\n\t\treturn \"Congestion Notification\"\n\tcase Dot11InformationElementIDMeshPeeringManagement:\n\t\treturn \"Mesh Peering Management\"\n\tcase Dot11InformationElementIDMeshChannelSwitchParam:\n\t\treturn \"Mesh Channel Switch Parameters\"\n\tcase Dot11InformationElementIDMeshAwakeWindows:\n\t\treturn \"Mesh Awake Windows\"\n\tcase Dot11InformationElementIDBeaconTiming:\n\t\treturn \"Beacon Timing\"\n\tcase Dot11InformationElementIDMCCAOPSetupRequest:\n\t\treturn \"MCCAOP Setup Request\"\n\tcase Dot11InformationElementIDMCCAOPSetupReply:\n\t\treturn \"MCCAOP SETUP Reply\"\n\tcase Dot11InformationElementIDMCCAOPAdvertisement:\n\t\treturn \"MCCAOP Advertisement\"\n\tcase Dot11InformationElementIDMCCAOPTeardown:\n\t\treturn \"MCCAOP Teardown\"\n\tcase Dot11InformationElementIDGateAnnouncement:\n\t\treturn \"Gate Announcement\"\n\tcase Dot11InformationElementIDRootAnnouncement:\n\t\treturn \"Root Announcement\"\n\tcase Dot11InformationElementIDExtCapability:\n\t\treturn \"Extended Capabilities\"\n\tcase Dot11InformationElementIDAgereProprietary:\n\t\treturn \"Agere Proprietary\"\n\tcase Dot11InformationElementIDPathRequest:\n\t\treturn \"Path Request\"\n\tcase Dot11InformationElementIDPathReply:\n\t\treturn \"Path Reply\"\n\tcase Dot11InformationElementIDPathError:\n\t\treturn \"Path Error\"\n\tcase Dot11InformationElementIDCiscoCCX1CKIPDeviceName:\n\t\treturn \"Cisco CCX1 CKIP + Device Name\"\n\tcase Dot11InformationElementIDCiscoCCX2:\n\t\treturn \"Cisco CCX2\"\n\tcase Dot11InformationElementIDProxyUpdate:\n\t\treturn \"Proxy Update\"\n\tcase Dot11InformationElementIDProxyUpdateConfirmation:\n\t\treturn \"Proxy Update Confirmation\"\n\tcase Dot11InformationElementIDAuthMeshPerringExch:\n\t\treturn \"Auhenticated Mesh Perring Exchange\"\n\tcase Dot11InformationElementIDMIC:\n\t\treturn \"MIC (Message Integrity Code)\"\n\tcase Dot11InformationElementIDDestinationURI:\n\t\treturn \"Destination URI\"\n\tcase Dot11InformationElementIDUAPSDCoexistence:\n\t\treturn \"U-APSD Coexistence\"\n\tcase Dot11InformationElementIDWakeupSchedule80211ad:\n\t\treturn \"Wakeup Schedule 802.11ad\"\n\tcase Dot11InformationElementIDExtendedSchedule:\n\t\treturn \"Extended Schedule\"\n\tcase Dot11InformationElementIDSTAAvailability:\n\t\treturn \"STA Availability\"\n\tcase Dot11InformationElementIDDMGTSPEC:\n\t\treturn \"DMG TSPEC\"\n\tcase Dot11InformationElementIDNextDMGATI:\n\t\treturn \"Next DMG ATI\"\n\tcase Dot11InformationElementIDDMSCapabilities:\n\t\treturn \"DMG Capabilities\"\n\tcase Dot11InformationElementIDCiscoUnknown95:\n\t\treturn \"Cisco Unknown 95\"\n\tcase Dot11InformationElementIDVendor2:\n\t\treturn \"Vendor Specific\"\n\tcase Dot11InformationElementIDDMGOperating:\n\t\treturn \"DMG Operating\"\n\tcase Dot11InformationElementIDDMGBSSParamChange:\n\t\treturn \"DMG BSS Parameter Change\"\n\tcase Dot11InformationElementIDDMGBeamRefinement:\n\t\treturn \"DMG Beam Refinement\"\n\tcase Dot11InformationElementIDChannelMeasFeedback:\n\t\treturn \"Channel Measurement Feedback\"\n\tcase Dot11InformationElementIDAwakeWindow:\n\t\treturn \"Awake Window\"\n\tcase Dot11InformationElementIDMultiBand:\n\t\treturn \"Multi Band\"\n\tcase Dot11InformationElementIDADDBAExtension:\n\t\treturn \"ADDBA Extension\"\n\tcase Dot11InformationElementIDNEXTPCPList:\n\t\treturn \"NEXTPCP List\"\n\tcase Dot11InformationElementIDPCPHandover:\n\t\treturn \"PCP Handover\"\n\tcase Dot11InformationElementIDDMGLinkMargin:\n\t\treturn \"DMG Link Margin\"\n\tcase Dot11InformationElementIDSwitchingStream:\n\t\treturn \"Switching Stream\"\n\tcase Dot11InformationElementIDSessionTransmission:\n\t\treturn \"Session Transmission\"\n\tcase Dot11InformationElementIDDynamicTonePairReport:\n\t\treturn \"Dynamic Tone Pairing Report\"\n\tcase Dot11InformationElementIDClusterReport:\n\t\treturn \"Cluster Report\"\n\tcase Dot11InformationElementIDRelayCapabilities:\n\t\treturn \"Relay Capabilities\"\n\tcase Dot11InformationElementIDRelayTransferParameter:\n\t\treturn \"Relay Transfer Parameter\"\n\tcase Dot11InformationElementIDBeamlinkMaintenance:\n\t\treturn \"Beamlink Maintenance\"\n\tcase Dot11InformationElementIDMultipleMacSublayers:\n\t\treturn \"Multiple MAC Sublayers\"\n\tcase Dot11InformationElementIDUPID:\n\t\treturn \"U-PID\"\n\tcase Dot11InformationElementIDDMGLinkAdaptionAck:\n\t\treturn \"DMG Link Adaption Acknowledgment\"\n\tcase Dot11InformationElementIDSymbolProprietary:\n\t\treturn \"Symbol Proprietary\"\n\tcase Dot11InformationElementIDMCCAOPAdvertOverview:\n\t\treturn \"MCCAOP Advertisement Overview\"\n\tcase Dot11InformationElementIDQuietPeriodRequest:\n\t\treturn \"Quiet Period Request\"\n\tcase Dot11InformationElementIDQuietPeriodResponse:\n\t\treturn \"Quiet Period Response\"\n\tcase Dot11InformationElementIDECPACPolicy:\n\t\treturn \"ECPAC Policy\"\n\tcase Dot11InformationElementIDClusterTimeOffset:\n\t\treturn \"Cluster Time Offset\"\n\tcase Dot11InformationElementIDAntennaSectorID:\n\t\treturn \"Antenna Sector ID\"\n\tcase Dot11InformationElementIDVHTCapabilities:\n\t\treturn \"VHT Capabilities (IEEE Std 802.11ac/D3.1)\"\n\tcase Dot11InformationElementIDVHTOperation:\n\t\treturn \"VHT Operation (IEEE Std 802.11ac/D3.1)\"\n\tcase Dot11InformationElementIDExtendedBSSLoad:\n\t\treturn \"Extended BSS Load\"\n\tcase Dot11InformationElementIDWideBWChannelSwitch:\n\t\treturn \"Wide Bandwidth Channel Switch\"\n\tcase Dot11InformationElementIDVHTTxPowerEnvelope:\n\t\treturn \"VHT Tx Power Envelope (IEEE Std 802.11ac/D5.0)\"\n\tcase Dot11InformationElementIDChannelSwitchWrapper:\n\t\treturn \"Channel Switch Wrapper\"\n\tcase Dot11InformationElementIDOperatingModeNotification:\n\t\treturn \"Operating Mode Notification\"\n\tcase Dot11InformationElementIDUPSIM:\n\t\treturn \"UP SIM\"\n\tcase Dot11InformationElementIDReducedNeighborReport:\n\t\treturn \"Reduced Neighbor Report\"\n\tcase Dot11InformationElementIDTVHTOperation:\n\t\treturn \"TVHT Op\"\n\tcase Dot11InformationElementIDDeviceLocation:\n\t\treturn \"Device Location\"\n\tcase Dot11InformationElementIDWhiteSpaceMap:\n\t\treturn \"White Space Map\"\n\tcase Dot11InformationElementIDFineTuningMeasureParams:\n\t\treturn \"Fine Tuning Measure Parameters\"\n\tcase Dot11InformationElementIDVendor:\n\t\treturn \"Vendor\"\n\tdefault:\n\t\treturn \"Unknown information element id\"\n\t}\n}\n\n// Dot11 provides an IEEE 802.11 base packet header.\n// See http://standards.ieee.org/findstds/standard/802.11-2012.html\n// for excruciating detail.\ntype Dot11 struct {\n\tBaseLayer\n\tType           Dot11Type\n\tProto          uint8\n\tFlags          Dot11Flags\n\tDurationID     uint16\n\tAddress1       net.HardwareAddr\n\tAddress2       net.HardwareAddr\n\tAddress3       net.HardwareAddr\n\tAddress4       net.HardwareAddr\n\tSequenceNumber uint16\n\tFragmentNumber uint16\n\tChecksum       uint32\n\tQOS            *Dot11QOS\n\tHTControl      *Dot11HTControl\n\tDataLayer      gopacket.Layer\n}\n\ntype Dot11QOS struct {\n\tTID       uint8 /* Traffic IDentifier */\n\tEOSP      bool  /* End of service period */\n\tAckPolicy Dot11AckPolicy\n\tTXOP      uint8\n}\n\ntype Dot11HTControl struct {\n\tACConstraint bool\n\tRDGMorePPDU  bool\n\n\tVHT *Dot11HTControlVHT\n\tHT  *Dot11HTControlHT\n}\n\ntype Dot11HTControlHT struct {\n\tLinkAdapationControl *Dot11LinkAdapationControl\n\tCalibrationPosition  uint8\n\tCalibrationSequence  uint8\n\tCSISteering          uint8\n\tNDPAnnouncement      bool\n\tDEI                  bool\n}\n\ntype Dot11HTControlVHT struct {\n\tMRQ            bool\n\tUnsolicitedMFB bool\n\tMSI            *uint8\n\tMFB            Dot11HTControlMFB\n\tCompressedMSI  *uint8\n\tSTBCIndication bool\n\tMFSI           *uint8\n\tGID            *uint8\n\tCodingType     *Dot11CodingType\n\tFbTXBeamformed bool\n}\n\ntype Dot11HTControlMFB struct {\n\tNumSTS uint8\n\tVHTMCS uint8\n\tBW     uint8\n\tSNR    int8\n}\n\ntype Dot11LinkAdapationControl struct {\n\tTRQ  bool\n\tMRQ  bool\n\tMSI  uint8\n\tMFSI uint8\n\tASEL *Dot11ASEL\n\tMFB  *uint8\n}\n\ntype Dot11ASEL struct {\n\tCommand uint8\n\tData    uint8\n}\n\ntype Dot11CodingType uint8\n\nconst (\n\tDot11CodingTypeBCC  = 0\n\tDot11CodingTypeLDPC = 1\n)\n\nfunc (a Dot11CodingType) String() string {\n\tswitch a {\n\tcase Dot11CodingTypeBCC:\n\t\treturn \"BCC\"\n\tcase Dot11CodingTypeLDPC:\n\t\treturn \"LDPC\"\n\tdefault:\n\t\treturn \"Unknown coding type\"\n\t}\n}\n\nfunc (m *Dot11HTControlMFB) NoFeedBackPresent() bool {\n\treturn m.VHTMCS == 15 && m.NumSTS == 7\n}\n\nfunc decodeDot11(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11{}\n\terr := d.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\tp.AddLayer(d)\n\tif d.DataLayer != nil {\n\t\tp.AddLayer(d.DataLayer)\n\t}\n\treturn p.NextDecoder(d.NextLayerType())\n}\n\nfunc (m *Dot11) LayerType() gopacket.LayerType  { return LayerTypeDot11 }\nfunc (m *Dot11) CanDecode() gopacket.LayerClass { return LayerTypeDot11 }\nfunc (m *Dot11) NextLayerType() gopacket.LayerType {\n\tif m.DataLayer != nil {\n\t\tif m.Flags.WEP() {\n\t\t\treturn LayerTypeDot11WEP\n\t\t}\n\t\treturn m.DataLayer.(gopacket.DecodingLayer).NextLayerType()\n\t}\n\treturn m.Type.LayerType()\n}\n\nfunc createU8(x uint8) *uint8 {\n\treturn &x\n}\n\nvar dataDecodeMap = map[Dot11Type]func() gopacket.DecodingLayer{\n\tDot11TypeData:                   func() gopacket.DecodingLayer { return &Dot11Data{} },\n\tDot11TypeDataCFAck:              func() gopacket.DecodingLayer { return &Dot11DataCFAck{} },\n\tDot11TypeDataCFPoll:             func() gopacket.DecodingLayer { return &Dot11DataCFPoll{} },\n\tDot11TypeDataCFAckPoll:          func() gopacket.DecodingLayer { return &Dot11DataCFAckPoll{} },\n\tDot11TypeDataNull:               func() gopacket.DecodingLayer { return &Dot11DataNull{} },\n\tDot11TypeDataCFAckNoData:        func() gopacket.DecodingLayer { return &Dot11DataCFAckNoData{} },\n\tDot11TypeDataCFPollNoData:       func() gopacket.DecodingLayer { return &Dot11DataCFPollNoData{} },\n\tDot11TypeDataCFAckPollNoData:    func() gopacket.DecodingLayer { return &Dot11DataCFAckPollNoData{} },\n\tDot11TypeDataQOSData:            func() gopacket.DecodingLayer { return &Dot11DataQOSData{} },\n\tDot11TypeDataQOSDataCFAck:       func() gopacket.DecodingLayer { return &Dot11DataQOSDataCFAck{} },\n\tDot11TypeDataQOSDataCFPoll:      func() gopacket.DecodingLayer { return &Dot11DataQOSDataCFPoll{} },\n\tDot11TypeDataQOSDataCFAckPoll:   func() gopacket.DecodingLayer { return &Dot11DataQOSDataCFAckPoll{} },\n\tDot11TypeDataQOSNull:            func() gopacket.DecodingLayer { return &Dot11DataQOSNull{} },\n\tDot11TypeDataQOSCFPollNoData:    func() gopacket.DecodingLayer { return &Dot11DataQOSCFPollNoData{} },\n\tDot11TypeDataQOSCFAckPollNoData: func() gopacket.DecodingLayer { return &Dot11DataQOSCFAckPollNoData{} },\n}\n\nfunc (m *Dot11) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 10 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"Dot11 length %v too short, %v required\", len(data), 10)\n\t}\n\tm.Type = Dot11Type((data[0])&0xFC) >> 2\n\n\tm.DataLayer = nil\n\tm.Proto = uint8(data[0]) & 0x0003\n\tm.Flags = Dot11Flags(data[1])\n\tm.DurationID = binary.LittleEndian.Uint16(data[2:4])\n\tm.Address1 = net.HardwareAddr(data[4:10])\n\n\toffset := 10\n\n\tmainType := m.Type.MainType()\n\n\tswitch mainType {\n\tcase Dot11TypeCtrl:\n\t\tswitch m.Type {\n\t\tcase Dot11TypeCtrlRTS, Dot11TypeCtrlPowersavePoll, Dot11TypeCtrlCFEnd, Dot11TypeCtrlCFEndAck:\n\t\t\tif len(data) < offset+6 {\n\t\t\t\tdf.SetTruncated()\n\t\t\t\treturn fmt.Errorf(\"Dot11 length %v too short, %v required\", len(data), offset+6)\n\t\t\t}\n\t\t\tm.Address2 = net.HardwareAddr(data[offset : offset+6])\n\t\t\toffset += 6\n\t\t}\n\tcase Dot11TypeMgmt, Dot11TypeData:\n\t\tif len(data) < offset+14 {\n\t\t\tdf.SetTruncated()\n\t\t\treturn fmt.Errorf(\"Dot11 length %v too short, %v required\", len(data), offset+14)\n\t\t}\n\t\tm.Address2 = net.HardwareAddr(data[offset : offset+6])\n\t\toffset += 6\n\t\tm.Address3 = net.HardwareAddr(data[offset : offset+6])\n\t\toffset += 6\n\n\t\tm.SequenceNumber = (binary.LittleEndian.Uint16(data[offset:offset+2]) & 0xFFF0) >> 4\n\t\tm.FragmentNumber = (binary.LittleEndian.Uint16(data[offset:offset+2]) & 0x000F)\n\t\toffset += 2\n\t}\n\n\tif mainType == Dot11TypeData && m.Flags.FromDS() && m.Flags.ToDS() {\n\t\tif len(data) < offset+6 {\n\t\t\tdf.SetTruncated()\n\t\t\treturn fmt.Errorf(\"Dot11 length %v too short, %v required\", len(data), offset+6)\n\t\t}\n\t\tm.Address4 = net.HardwareAddr(data[offset : offset+6])\n\t\toffset += 6\n\t}\n\n\tif m.Type.QOS() {\n\t\tif len(data) < offset+2 {\n\t\t\tdf.SetTruncated()\n\t\t\treturn fmt.Errorf(\"Dot11 length %v too short, %v required\", len(data), offset+6)\n\t\t}\n\t\tm.QOS = &Dot11QOS{\n\t\t\tTID:       (uint8(data[offset]) & 0x0F),\n\t\t\tEOSP:      (uint8(data[offset]) & 0x10) == 0x10,\n\t\t\tAckPolicy: Dot11AckPolicy((uint8(data[offset]) & 0x60) >> 5),\n\t\t\tTXOP:      uint8(data[offset+1]),\n\t\t}\n\t\toffset += 2\n\t}\n\tif m.Flags.Order() && (m.Type.QOS() || mainType == Dot11TypeMgmt) {\n\t\tif len(data) < offset+4 {\n\t\t\tdf.SetTruncated()\n\t\t\treturn fmt.Errorf(\"Dot11 length %v too short, %v required\", len(data), offset+6)\n\t\t}\n\n\t\thtc := &Dot11HTControl{\n\t\t\tACConstraint: data[offset+3]&0x40 != 0,\n\t\t\tRDGMorePPDU:  data[offset+3]&0x80 != 0,\n\t\t}\n\t\tm.HTControl = htc\n\n\t\tif data[offset]&0x1 != 0 { // VHT Variant\n\t\t\tvht := &Dot11HTControlVHT{}\n\t\t\thtc.VHT = vht\n\t\t\tvht.MRQ = data[offset]&0x4 != 0\n\t\t\tvht.UnsolicitedMFB = data[offset+3]&0x20 != 0\n\t\t\tvht.MFB = Dot11HTControlMFB{\n\t\t\t\tNumSTS: uint8(data[offset+1] >> 1 & 0x7),\n\t\t\t\tVHTMCS: uint8(data[offset+1] >> 4 & 0xF),\n\t\t\t\tBW:     uint8(data[offset+2] & 0x3),\n\t\t\t\tSNR:    int8((-(data[offset+2] >> 2 & 0x20))+data[offset+2]>>2&0x1F) + 22,\n\t\t\t}\n\n\t\t\tif vht.UnsolicitedMFB {\n\t\t\t\tif !vht.MFB.NoFeedBackPresent() {\n\t\t\t\t\tvht.CompressedMSI = createU8(data[offset] >> 3 & 0x3)\n\t\t\t\t\tvht.STBCIndication = data[offset]&0x20 != 0\n\t\t\t\t\tvht.CodingType = (*Dot11CodingType)(createU8(data[offset+3] >> 3 & 0x1))\n\t\t\t\t\tvht.FbTXBeamformed = data[offset+3]&0x10 != 0\n\t\t\t\t\tvht.GID = createU8(\n\t\t\t\t\t\tdata[offset]>>6 +\n\t\t\t\t\t\t\t(data[offset+1] & 0x1 << 2) +\n\t\t\t\t\t\t\tdata[offset+3]&0x7<<3)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif vht.MRQ {\n\t\t\t\t\tvht.MSI = createU8((data[offset] >> 3) & 0x07)\n\t\t\t\t}\n\t\t\t\tvht.MFSI = createU8(data[offset]>>6 + (data[offset+1] & 0x1 << 2))\n\t\t\t}\n\n\t\t} else { // HT Variant\n\t\t\tht := &Dot11HTControlHT{}\n\t\t\thtc.HT = ht\n\n\t\t\tlac := &Dot11LinkAdapationControl{}\n\t\t\tht.LinkAdapationControl = lac\n\t\t\tlac.TRQ = data[offset]&0x2 != 0\n\t\t\tlac.MFSI = data[offset]>>6&0x3 + data[offset+1]&0x1<<3\n\t\t\tif data[offset]&0x3C == 0x38 { // ASEL\n\t\t\t\tlac.ASEL = &Dot11ASEL{\n\t\t\t\t\tCommand: data[offset+1] >> 1 & 0x7,\n\t\t\t\t\tData:    data[offset+1] >> 4 & 0xF,\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlac.MRQ = data[offset]&0x4 != 0\n\t\t\t\tif lac.MRQ {\n\t\t\t\t\tlac.MSI = data[offset] >> 3 & 0x7\n\t\t\t\t}\n\t\t\t\tlac.MFB = createU8(data[offset+1] >> 1)\n\t\t\t}\n\t\t\tht.CalibrationPosition = data[offset+2] & 0x3\n\t\t\tht.CalibrationSequence = data[offset+2] >> 2 & 0x3\n\t\t\tht.CSISteering = data[offset+2] >> 6 & 0x3\n\t\t\tht.NDPAnnouncement = data[offset+3]&0x1 != 0\n\t\t\tif mainType != Dot11TypeMgmt {\n\t\t\t\tht.DEI = data[offset+3]&0x20 != 0\n\t\t\t}\n\t\t}\n\n\t\toffset += 4\n\t}\n\n\tif len(data) < offset+4 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"Dot11 length %v too short, %v required\", len(data), offset+4)\n\t}\n\n\tm.BaseLayer = BaseLayer{\n\t\tContents: data[0:offset],\n\t\tPayload:  data[offset : len(data)-4],\n\t}\n\n\tif mainType == Dot11TypeData {\n\t\td := dataDecodeMap[m.Type]\n\t\tif d == nil {\n\t\t\treturn fmt.Errorf(\"unsupported type: %v\", m.Type)\n\t\t}\n\t\tl := d()\n\t\terr := l.DecodeFromBytes(m.BaseLayer.Payload, df)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tm.DataLayer = l.(gopacket.Layer)\n\t}\n\n\tm.Checksum = binary.LittleEndian.Uint32(data[len(data)-4 : len(data)])\n\treturn nil\n}\n\nfunc (m *Dot11) ChecksumValid() bool {\n\t// only for CTRL and MGMT frames\n\th := crc32.NewIEEE()\n\th.Write(m.Contents)\n\th.Write(m.Payload)\n\treturn m.Checksum == h.Sum32()\n}\n\nfunc (m Dot11) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbuf, err := b.PrependBytes(24)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbuf[0] = (uint8(m.Type) << 2) | m.Proto\n\tbuf[1] = uint8(m.Flags)\n\n\tbinary.LittleEndian.PutUint16(buf[2:4], m.DurationID)\n\n\tcopy(buf[4:10], m.Address1)\n\n\toffset := 10\n\n\tswitch m.Type.MainType() {\n\tcase Dot11TypeCtrl:\n\t\tswitch m.Type {\n\t\tcase Dot11TypeCtrlRTS, Dot11TypeCtrlPowersavePoll, Dot11TypeCtrlCFEnd, Dot11TypeCtrlCFEndAck:\n\t\t\tcopy(buf[offset:offset+6], m.Address2)\n\t\t\toffset += 6\n\t\t}\n\tcase Dot11TypeMgmt, Dot11TypeData:\n\t\tcopy(buf[offset:offset+6], m.Address2)\n\t\toffset += 6\n\t\tcopy(buf[offset:offset+6], m.Address3)\n\t\toffset += 6\n\n\t\tbinary.LittleEndian.PutUint16(buf[offset:offset+2], (m.SequenceNumber<<4)|m.FragmentNumber)\n\t\toffset += 2\n\t}\n\n\tif m.Type.MainType() == Dot11TypeData && m.Flags.FromDS() && m.Flags.ToDS() {\n\t\tcopy(buf[offset:offset+6], m.Address4)\n\t\toffset += 6\n\t}\n\n\treturn nil\n}\n\n// Dot11Mgmt is a base for all IEEE 802.11 management layers.\ntype Dot11Mgmt struct {\n\tBaseLayer\n}\n\nfunc (m *Dot11Mgmt) NextLayerType() gopacket.LayerType { return gopacket.LayerTypePayload }\nfunc (m *Dot11Mgmt) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tm.Contents = data\n\treturn nil\n}\n\n// Dot11Ctrl is a base for all IEEE 802.11 control layers.\ntype Dot11Ctrl struct {\n\tBaseLayer\n}\n\nfunc (m *Dot11Ctrl) NextLayerType() gopacket.LayerType { return gopacket.LayerTypePayload }\n\nfunc (m *Dot11Ctrl) LayerType() gopacket.LayerType  { return LayerTypeDot11Ctrl }\nfunc (m *Dot11Ctrl) CanDecode() gopacket.LayerClass { return LayerTypeDot11Ctrl }\nfunc (m *Dot11Ctrl) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tm.Contents = data\n\treturn nil\n}\n\nfunc decodeDot11Ctrl(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11Ctrl{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\n// Dot11WEP contains WEP encrpted IEEE 802.11 data.\ntype Dot11WEP struct {\n\tBaseLayer\n}\n\nfunc (m *Dot11WEP) NextLayerType() gopacket.LayerType { return gopacket.LayerTypePayload }\n\nfunc (m *Dot11WEP) LayerType() gopacket.LayerType  { return LayerTypeDot11WEP }\nfunc (m *Dot11WEP) CanDecode() gopacket.LayerClass { return LayerTypeDot11WEP }\nfunc (m *Dot11WEP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tm.Contents = data\n\treturn nil\n}\n\nfunc decodeDot11WEP(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11WEP{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\n// Dot11Data is a base for all IEEE 802.11 data layers.\ntype Dot11Data struct {\n\tBaseLayer\n}\n\nfunc (m *Dot11Data) NextLayerType() gopacket.LayerType {\n\treturn LayerTypeLLC\n}\n\nfunc (m *Dot11Data) LayerType() gopacket.LayerType  { return LayerTypeDot11Data }\nfunc (m *Dot11Data) CanDecode() gopacket.LayerClass { return LayerTypeDot11Data }\nfunc (m *Dot11Data) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tm.Payload = data\n\treturn nil\n}\n\nfunc decodeDot11Data(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11Data{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\ntype Dot11DataCFAck struct {\n\tDot11Data\n}\n\nfunc decodeDot11DataCFAck(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11DataCFAck{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11DataCFAck) LayerType() gopacket.LayerType  { return LayerTypeDot11DataCFAck }\nfunc (m *Dot11DataCFAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFAck }\nfunc (m *Dot11DataCFAck) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\treturn m.Dot11Data.DecodeFromBytes(data, df)\n}\n\ntype Dot11DataCFPoll struct {\n\tDot11Data\n}\n\nfunc decodeDot11DataCFPoll(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11DataCFPoll{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11DataCFPoll) LayerType() gopacket.LayerType  { return LayerTypeDot11DataCFPoll }\nfunc (m *Dot11DataCFPoll) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFPoll }\nfunc (m *Dot11DataCFPoll) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\treturn m.Dot11Data.DecodeFromBytes(data, df)\n}\n\ntype Dot11DataCFAckPoll struct {\n\tDot11Data\n}\n\nfunc decodeDot11DataCFAckPoll(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11DataCFAckPoll{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11DataCFAckPoll) LayerType() gopacket.LayerType  { return LayerTypeDot11DataCFAckPoll }\nfunc (m *Dot11DataCFAckPoll) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFAckPoll }\nfunc (m *Dot11DataCFAckPoll) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\treturn m.Dot11Data.DecodeFromBytes(data, df)\n}\n\ntype Dot11DataNull struct {\n\tDot11Data\n}\n\nfunc decodeDot11DataNull(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11DataNull{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11DataNull) LayerType() gopacket.LayerType  { return LayerTypeDot11DataNull }\nfunc (m *Dot11DataNull) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataNull }\nfunc (m *Dot11DataNull) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\treturn m.Dot11Data.DecodeFromBytes(data, df)\n}\n\ntype Dot11DataCFAckNoData struct {\n\tDot11Data\n}\n\nfunc decodeDot11DataCFAckNoData(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11DataCFAckNoData{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11DataCFAckNoData) LayerType() gopacket.LayerType  { return LayerTypeDot11DataCFAckNoData }\nfunc (m *Dot11DataCFAckNoData) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataCFAckNoData }\nfunc (m *Dot11DataCFAckNoData) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\treturn m.Dot11Data.DecodeFromBytes(data, df)\n}\n\ntype Dot11DataCFPollNoData struct {\n\tDot11Data\n}\n\nfunc decodeDot11DataCFPollNoData(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11DataCFPollNoData{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11DataCFPollNoData) LayerType() gopacket.LayerType { return LayerTypeDot11DataCFPollNoData }\nfunc (m *Dot11DataCFPollNoData) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11DataCFPollNoData\n}\nfunc (m *Dot11DataCFPollNoData) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\treturn m.Dot11Data.DecodeFromBytes(data, df)\n}\n\ntype Dot11DataCFAckPollNoData struct {\n\tDot11Data\n}\n\nfunc decodeDot11DataCFAckPollNoData(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11DataCFAckPollNoData{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11DataCFAckPollNoData) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11DataCFAckPollNoData\n}\nfunc (m *Dot11DataCFAckPollNoData) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11DataCFAckPollNoData\n}\nfunc (m *Dot11DataCFAckPollNoData) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\treturn m.Dot11Data.DecodeFromBytes(data, df)\n}\n\ntype Dot11DataQOS struct {\n\tDot11Ctrl\n}\n\nfunc (m *Dot11DataQOS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tm.BaseLayer = BaseLayer{Payload: data}\n\treturn nil\n}\n\ntype Dot11DataQOSData struct {\n\tDot11DataQOS\n}\n\nfunc decodeDot11DataQOSData(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11DataQOSData{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11DataQOSData) LayerType() gopacket.LayerType  { return LayerTypeDot11DataQOSData }\nfunc (m *Dot11DataQOSData) CanDecode() gopacket.LayerClass { return LayerTypeDot11DataQOSData }\n\nfunc (m *Dot11DataQOSData) NextLayerType() gopacket.LayerType {\n\treturn LayerTypeDot11Data\n}\n\ntype Dot11DataQOSDataCFAck struct {\n\tDot11DataQOS\n}\n\nfunc decodeDot11DataQOSDataCFAck(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11DataQOSDataCFAck{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11DataQOSDataCFAck) LayerType() gopacket.LayerType { return LayerTypeDot11DataQOSDataCFAck }\nfunc (m *Dot11DataQOSDataCFAck) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11DataQOSDataCFAck\n}\nfunc (m *Dot11DataQOSDataCFAck) NextLayerType() gopacket.LayerType { return LayerTypeDot11DataCFAck }\n\ntype Dot11DataQOSDataCFPoll struct {\n\tDot11DataQOS\n}\n\nfunc decodeDot11DataQOSDataCFPoll(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11DataQOSDataCFPoll{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11DataQOSDataCFPoll) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11DataQOSDataCFPoll\n}\nfunc (m *Dot11DataQOSDataCFPoll) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11DataQOSDataCFPoll\n}\nfunc (m *Dot11DataQOSDataCFPoll) NextLayerType() gopacket.LayerType { return LayerTypeDot11DataCFPoll }\n\ntype Dot11DataQOSDataCFAckPoll struct {\n\tDot11DataQOS\n}\n\nfunc decodeDot11DataQOSDataCFAckPoll(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11DataQOSDataCFAckPoll{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11DataQOSDataCFAckPoll) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11DataQOSDataCFAckPoll\n}\nfunc (m *Dot11DataQOSDataCFAckPoll) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11DataQOSDataCFAckPoll\n}\nfunc (m *Dot11DataQOSDataCFAckPoll) NextLayerType() gopacket.LayerType {\n\treturn LayerTypeDot11DataCFAckPoll\n}\n\ntype Dot11DataQOSNull struct {\n\tDot11DataQOS\n}\n\nfunc decodeDot11DataQOSNull(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11DataQOSNull{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11DataQOSNull) LayerType() gopacket.LayerType     { return LayerTypeDot11DataQOSNull }\nfunc (m *Dot11DataQOSNull) CanDecode() gopacket.LayerClass    { return LayerTypeDot11DataQOSNull }\nfunc (m *Dot11DataQOSNull) NextLayerType() gopacket.LayerType { return LayerTypeDot11DataNull }\n\ntype Dot11DataQOSCFPollNoData struct {\n\tDot11DataQOS\n}\n\nfunc decodeDot11DataQOSCFPollNoData(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11DataQOSCFPollNoData{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11DataQOSCFPollNoData) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11DataQOSCFPollNoData\n}\nfunc (m *Dot11DataQOSCFPollNoData) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11DataQOSCFPollNoData\n}\nfunc (m *Dot11DataQOSCFPollNoData) NextLayerType() gopacket.LayerType {\n\treturn LayerTypeDot11DataCFPollNoData\n}\n\ntype Dot11DataQOSCFAckPollNoData struct {\n\tDot11DataQOS\n}\n\nfunc decodeDot11DataQOSCFAckPollNoData(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11DataQOSCFAckPollNoData{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11DataQOSCFAckPollNoData) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11DataQOSCFAckPollNoData\n}\nfunc (m *Dot11DataQOSCFAckPollNoData) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11DataQOSCFAckPollNoData\n}\nfunc (m *Dot11DataQOSCFAckPollNoData) NextLayerType() gopacket.LayerType {\n\treturn LayerTypeDot11DataCFAckPollNoData\n}\n\ntype Dot11InformationElement struct {\n\tBaseLayer\n\tID     Dot11InformationElementID\n\tLength uint8\n\tOUI    []byte\n\tInfo   []byte\n}\n\nfunc (m *Dot11InformationElement) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11InformationElement\n}\nfunc (m *Dot11InformationElement) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11InformationElement\n}\n\nfunc (m *Dot11InformationElement) NextLayerType() gopacket.LayerType {\n\treturn LayerTypeDot11InformationElement\n}\n\nfunc (m *Dot11InformationElement) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 2 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"Dot11InformationElement length %v too short, %v required\", len(data), 2)\n\t}\n\tm.ID = Dot11InformationElementID(data[0])\n\tm.Length = data[1]\n\toffset := int(2)\n\n\tif len(data) < offset+int(m.Length) {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"Dot11InformationElement length %v too short, %v required\", len(data), offset+int(m.Length))\n\t}\n\tif len(data) < offset+4 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"vendor extension size < %d\", offset+int(m.Length))\n\t}\n\tif m.ID == 221 {\n\t\t// Vendor extension\n\t\tm.OUI = data[offset : offset+4]\n\t\tm.Info = data[offset+4 : offset+int(m.Length)]\n\t} else {\n\t\tm.Info = data[offset : offset+int(m.Length)]\n\t}\n\n\toffset += int(m.Length)\n\n\tm.BaseLayer = BaseLayer{Contents: data[:offset], Payload: data[offset:]}\n\treturn nil\n}\n\nfunc (d *Dot11InformationElement) String() string {\n\tif d.ID == 0 {\n\t\treturn fmt.Sprintf(\"802.11 Information Element (ID: %v, Length: %v, SSID: %v)\", d.ID, d.Length, string(d.Info))\n\t} else if d.ID == 1 {\n\t\trates := \"\"\n\t\tfor i := 0; i < len(d.Info); i++ {\n\t\t\tif d.Info[i]&0x80 == 0 {\n\t\t\t\trates += fmt.Sprintf(\"%.1f \", float32(d.Info[i])*0.5)\n\t\t\t} else {\n\t\t\t\trates += fmt.Sprintf(\"%.1f* \", float32(d.Info[i]&0x7F)*0.5)\n\t\t\t}\n\t\t}\n\t\treturn fmt.Sprintf(\"802.11 Information Element (ID: %v, Length: %v, Rates: %s Mbit)\", d.ID, d.Length, rates)\n\t} else if d.ID == 221 {\n\t\treturn fmt.Sprintf(\"802.11 Information Element (ID: %v, Length: %v, OUI: %X, Info: %X)\", d.ID, d.Length, d.OUI, d.Info)\n\t} else {\n\t\treturn fmt.Sprintf(\"802.11 Information Element (ID: %v, Length: %v, Info: %X)\", d.ID, d.Length, d.Info)\n\t}\n}\n\nfunc (m Dot11InformationElement) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tlength := len(m.Info) + len(m.OUI)\n\tif buf, err := b.PrependBytes(2 + length); err != nil {\n\t\treturn err\n\t} else {\n\t\tbuf[0] = uint8(m.ID)\n\t\tbuf[1] = uint8(length)\n\t\tcopy(buf[2:], m.OUI)\n\t\tcopy(buf[2+len(m.OUI):], m.Info)\n\t}\n\treturn nil\n}\n\nfunc decodeDot11InformationElement(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11InformationElement{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\ntype Dot11CtrlCTS struct {\n\tDot11Ctrl\n}\n\nfunc decodeDot11CtrlCTS(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11CtrlCTS{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11CtrlCTS) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11CtrlCTS\n}\nfunc (m *Dot11CtrlCTS) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11CtrlCTS\n}\nfunc (m *Dot11CtrlCTS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\treturn m.Dot11Ctrl.DecodeFromBytes(data, df)\n}\n\ntype Dot11CtrlRTS struct {\n\tDot11Ctrl\n}\n\nfunc decodeDot11CtrlRTS(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11CtrlRTS{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11CtrlRTS) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11CtrlRTS\n}\nfunc (m *Dot11CtrlRTS) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11CtrlRTS\n}\nfunc (m *Dot11CtrlRTS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\treturn m.Dot11Ctrl.DecodeFromBytes(data, df)\n}\n\ntype Dot11CtrlBlockAckReq struct {\n\tDot11Ctrl\n}\n\nfunc decodeDot11CtrlBlockAckReq(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11CtrlBlockAckReq{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11CtrlBlockAckReq) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11CtrlBlockAckReq\n}\nfunc (m *Dot11CtrlBlockAckReq) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11CtrlBlockAckReq\n}\nfunc (m *Dot11CtrlBlockAckReq) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\treturn m.Dot11Ctrl.DecodeFromBytes(data, df)\n}\n\ntype Dot11CtrlBlockAck struct {\n\tDot11Ctrl\n}\n\nfunc decodeDot11CtrlBlockAck(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11CtrlBlockAck{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11CtrlBlockAck) LayerType() gopacket.LayerType  { return LayerTypeDot11CtrlBlockAck }\nfunc (m *Dot11CtrlBlockAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11CtrlBlockAck }\nfunc (m *Dot11CtrlBlockAck) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\treturn m.Dot11Ctrl.DecodeFromBytes(data, df)\n}\n\ntype Dot11CtrlPowersavePoll struct {\n\tDot11Ctrl\n}\n\nfunc decodeDot11CtrlPowersavePoll(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11CtrlPowersavePoll{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11CtrlPowersavePoll) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11CtrlPowersavePoll\n}\nfunc (m *Dot11CtrlPowersavePoll) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11CtrlPowersavePoll\n}\nfunc (m *Dot11CtrlPowersavePoll) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\treturn m.Dot11Ctrl.DecodeFromBytes(data, df)\n}\n\ntype Dot11CtrlAck struct {\n\tDot11Ctrl\n}\n\nfunc decodeDot11CtrlAck(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11CtrlAck{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11CtrlAck) LayerType() gopacket.LayerType  { return LayerTypeDot11CtrlAck }\nfunc (m *Dot11CtrlAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11CtrlAck }\nfunc (m *Dot11CtrlAck) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\treturn m.Dot11Ctrl.DecodeFromBytes(data, df)\n}\n\ntype Dot11CtrlCFEnd struct {\n\tDot11Ctrl\n}\n\nfunc decodeDot11CtrlCFEnd(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11CtrlCFEnd{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11CtrlCFEnd) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11CtrlCFEnd\n}\nfunc (m *Dot11CtrlCFEnd) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11CtrlCFEnd\n}\nfunc (m *Dot11CtrlCFEnd) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\treturn m.Dot11Ctrl.DecodeFromBytes(data, df)\n}\n\ntype Dot11CtrlCFEndAck struct {\n\tDot11Ctrl\n}\n\nfunc decodeDot11CtrlCFEndAck(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11CtrlCFEndAck{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11CtrlCFEndAck) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11CtrlCFEndAck\n}\nfunc (m *Dot11CtrlCFEndAck) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11CtrlCFEndAck\n}\nfunc (m *Dot11CtrlCFEndAck) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\treturn m.Dot11Ctrl.DecodeFromBytes(data, df)\n}\n\ntype Dot11MgmtAssociationReq struct {\n\tDot11Mgmt\n\tCapabilityInfo uint16\n\tListenInterval uint16\n}\n\nfunc decodeDot11MgmtAssociationReq(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11MgmtAssociationReq{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11MgmtAssociationReq) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11MgmtAssociationReq\n}\nfunc (m *Dot11MgmtAssociationReq) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11MgmtAssociationReq\n}\nfunc (m *Dot11MgmtAssociationReq) NextLayerType() gopacket.LayerType {\n\treturn LayerTypeDot11InformationElement\n}\nfunc (m *Dot11MgmtAssociationReq) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 4 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"Dot11MgmtAssociationReq length %v too short, %v required\", len(data), 4)\n\t}\n\tm.CapabilityInfo = binary.LittleEndian.Uint16(data[0:2])\n\tm.ListenInterval = binary.LittleEndian.Uint16(data[2:4])\n\tm.Payload = data[4:]\n\treturn m.Dot11Mgmt.DecodeFromBytes(data, df)\n}\n\nfunc (m Dot11MgmtAssociationReq) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbuf, err := b.PrependBytes(4)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbinary.LittleEndian.PutUint16(buf[0:2], m.CapabilityInfo)\n\tbinary.LittleEndian.PutUint16(buf[2:4], m.ListenInterval)\n\n\treturn nil\n}\n\ntype Dot11MgmtAssociationResp struct {\n\tDot11Mgmt\n\tCapabilityInfo uint16\n\tStatus         Dot11Status\n\tAID            uint16\n}\n\nfunc decodeDot11MgmtAssociationResp(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11MgmtAssociationResp{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11MgmtAssociationResp) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11MgmtAssociationResp\n}\nfunc (m *Dot11MgmtAssociationResp) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11MgmtAssociationResp\n}\nfunc (m *Dot11MgmtAssociationResp) NextLayerType() gopacket.LayerType {\n\treturn LayerTypeDot11InformationElement\n}\nfunc (m *Dot11MgmtAssociationResp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 6 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"Dot11MgmtAssociationResp length %v too short, %v required\", len(data), 6)\n\t}\n\tm.CapabilityInfo = binary.LittleEndian.Uint16(data[0:2])\n\tm.Status = Dot11Status(binary.LittleEndian.Uint16(data[2:4]))\n\tm.AID = binary.LittleEndian.Uint16(data[4:6])\n\tm.Payload = data[6:]\n\treturn m.Dot11Mgmt.DecodeFromBytes(data, df)\n}\n\nfunc (m Dot11MgmtAssociationResp) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbuf, err := b.PrependBytes(6)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbinary.LittleEndian.PutUint16(buf[0:2], m.CapabilityInfo)\n\tbinary.LittleEndian.PutUint16(buf[2:4], uint16(m.Status))\n\tbinary.LittleEndian.PutUint16(buf[4:6], m.AID)\n\n\treturn nil\n}\n\ntype Dot11MgmtReassociationReq struct {\n\tDot11Mgmt\n\tCapabilityInfo   uint16\n\tListenInterval   uint16\n\tCurrentApAddress net.HardwareAddr\n}\n\nfunc decodeDot11MgmtReassociationReq(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11MgmtReassociationReq{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11MgmtReassociationReq) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11MgmtReassociationReq\n}\nfunc (m *Dot11MgmtReassociationReq) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11MgmtReassociationReq\n}\nfunc (m *Dot11MgmtReassociationReq) NextLayerType() gopacket.LayerType {\n\treturn LayerTypeDot11InformationElement\n}\nfunc (m *Dot11MgmtReassociationReq) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 10 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"Dot11MgmtReassociationReq length %v too short, %v required\", len(data), 10)\n\t}\n\tm.CapabilityInfo = binary.LittleEndian.Uint16(data[0:2])\n\tm.ListenInterval = binary.LittleEndian.Uint16(data[2:4])\n\tm.CurrentApAddress = net.HardwareAddr(data[4:10])\n\tm.Payload = data[10:]\n\treturn m.Dot11Mgmt.DecodeFromBytes(data, df)\n}\n\nfunc (m Dot11MgmtReassociationReq) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbuf, err := b.PrependBytes(10)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbinary.LittleEndian.PutUint16(buf[0:2], m.CapabilityInfo)\n\tbinary.LittleEndian.PutUint16(buf[2:4], m.ListenInterval)\n\n\tcopy(buf[4:10], m.CurrentApAddress)\n\n\treturn nil\n}\n\ntype Dot11MgmtReassociationResp struct {\n\tDot11Mgmt\n}\n\nfunc decodeDot11MgmtReassociationResp(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11MgmtReassociationResp{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11MgmtReassociationResp) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11MgmtReassociationResp\n}\nfunc (m *Dot11MgmtReassociationResp) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11MgmtReassociationResp\n}\nfunc (m *Dot11MgmtReassociationResp) NextLayerType() gopacket.LayerType {\n\treturn LayerTypeDot11InformationElement\n}\n\ntype Dot11MgmtProbeReq struct {\n\tDot11Mgmt\n}\n\nfunc decodeDot11MgmtProbeReq(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11MgmtProbeReq{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11MgmtProbeReq) LayerType() gopacket.LayerType  { return LayerTypeDot11MgmtProbeReq }\nfunc (m *Dot11MgmtProbeReq) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtProbeReq }\nfunc (m *Dot11MgmtProbeReq) NextLayerType() gopacket.LayerType {\n\treturn LayerTypeDot11InformationElement\n}\n\ntype Dot11MgmtProbeResp struct {\n\tDot11Mgmt\n\tTimestamp uint64\n\tInterval  uint16\n\tFlags     uint16\n}\n\nfunc decodeDot11MgmtProbeResp(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11MgmtProbeResp{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11MgmtProbeResp) LayerType() gopacket.LayerType  { return LayerTypeDot11MgmtProbeResp }\nfunc (m *Dot11MgmtProbeResp) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtProbeResp }\nfunc (m *Dot11MgmtProbeResp) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 12 {\n\t\tdf.SetTruncated()\n\n\t\treturn fmt.Errorf(\"Dot11MgmtProbeResp length %v too short, %v required\", len(data), 12)\n\t}\n\n\tm.Timestamp = binary.LittleEndian.Uint64(data[0:8])\n\tm.Interval = binary.LittleEndian.Uint16(data[8:10])\n\tm.Flags = binary.LittleEndian.Uint16(data[10:12])\n\tm.Payload = data[12:]\n\n\treturn m.Dot11Mgmt.DecodeFromBytes(data, df)\n}\n\nfunc (m *Dot11MgmtProbeResp) NextLayerType() gopacket.LayerType {\n\treturn LayerTypeDot11InformationElement\n}\n\nfunc (m Dot11MgmtProbeResp) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbuf, err := b.PrependBytes(12)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbinary.LittleEndian.PutUint64(buf[0:8], m.Timestamp)\n\tbinary.LittleEndian.PutUint16(buf[8:10], m.Interval)\n\tbinary.LittleEndian.PutUint16(buf[10:12], m.Flags)\n\n\treturn nil\n}\n\ntype Dot11MgmtMeasurementPilot struct {\n\tDot11Mgmt\n}\n\nfunc decodeDot11MgmtMeasurementPilot(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11MgmtMeasurementPilot{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11MgmtMeasurementPilot) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11MgmtMeasurementPilot\n}\nfunc (m *Dot11MgmtMeasurementPilot) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11MgmtMeasurementPilot\n}\n\ntype Dot11MgmtBeacon struct {\n\tDot11Mgmt\n\tTimestamp uint64\n\tInterval  uint16\n\tFlags     uint16\n}\n\nfunc decodeDot11MgmtBeacon(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11MgmtBeacon{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11MgmtBeacon) LayerType() gopacket.LayerType  { return LayerTypeDot11MgmtBeacon }\nfunc (m *Dot11MgmtBeacon) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtBeacon }\nfunc (m *Dot11MgmtBeacon) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 12 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"Dot11MgmtBeacon length %v too short, %v required\", len(data), 12)\n\t}\n\tm.Timestamp = binary.LittleEndian.Uint64(data[0:8])\n\tm.Interval = binary.LittleEndian.Uint16(data[8:10])\n\tm.Flags = binary.LittleEndian.Uint16(data[10:12])\n\tm.Payload = data[12:]\n\treturn m.Dot11Mgmt.DecodeFromBytes(data, df)\n}\n\nfunc (m *Dot11MgmtBeacon) NextLayerType() gopacket.LayerType { return LayerTypeDot11InformationElement }\n\nfunc (m Dot11MgmtBeacon) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbuf, err := b.PrependBytes(12)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbinary.LittleEndian.PutUint64(buf[0:8], m.Timestamp)\n\tbinary.LittleEndian.PutUint16(buf[8:10], m.Interval)\n\tbinary.LittleEndian.PutUint16(buf[10:12], m.Flags)\n\n\treturn nil\n}\n\ntype Dot11MgmtATIM struct {\n\tDot11Mgmt\n}\n\nfunc decodeDot11MgmtATIM(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11MgmtATIM{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11MgmtATIM) LayerType() gopacket.LayerType  { return LayerTypeDot11MgmtATIM }\nfunc (m *Dot11MgmtATIM) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtATIM }\n\ntype Dot11MgmtDisassociation struct {\n\tDot11Mgmt\n\tReason Dot11Reason\n}\n\nfunc decodeDot11MgmtDisassociation(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11MgmtDisassociation{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11MgmtDisassociation) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11MgmtDisassociation\n}\nfunc (m *Dot11MgmtDisassociation) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11MgmtDisassociation\n}\nfunc (m *Dot11MgmtDisassociation) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 2 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"Dot11MgmtDisassociation length %v too short, %v required\", len(data), 2)\n\t}\n\tm.Reason = Dot11Reason(binary.LittleEndian.Uint16(data[0:2]))\n\treturn m.Dot11Mgmt.DecodeFromBytes(data, df)\n}\n\nfunc (m Dot11MgmtDisassociation) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbuf, err := b.PrependBytes(2)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbinary.LittleEndian.PutUint16(buf[0:2], uint16(m.Reason))\n\n\treturn nil\n}\n\ntype Dot11MgmtAuthentication struct {\n\tDot11Mgmt\n\tAlgorithm Dot11Algorithm\n\tSequence  uint16\n\tStatus    Dot11Status\n}\n\nfunc decodeDot11MgmtAuthentication(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11MgmtAuthentication{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11MgmtAuthentication) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11MgmtAuthentication\n}\nfunc (m *Dot11MgmtAuthentication) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11MgmtAuthentication\n}\nfunc (m *Dot11MgmtAuthentication) NextLayerType() gopacket.LayerType {\n\treturn LayerTypeDot11InformationElement\n}\nfunc (m *Dot11MgmtAuthentication) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 6 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"Dot11MgmtAuthentication length %v too short, %v required\", len(data), 6)\n\t}\n\tm.Algorithm = Dot11Algorithm(binary.LittleEndian.Uint16(data[0:2]))\n\tm.Sequence = binary.LittleEndian.Uint16(data[2:4])\n\tm.Status = Dot11Status(binary.LittleEndian.Uint16(data[4:6]))\n\tm.Payload = data[6:]\n\treturn m.Dot11Mgmt.DecodeFromBytes(data, df)\n}\n\nfunc (m Dot11MgmtAuthentication) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbuf, err := b.PrependBytes(6)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbinary.LittleEndian.PutUint16(buf[0:2], uint16(m.Algorithm))\n\tbinary.LittleEndian.PutUint16(buf[2:4], m.Sequence)\n\tbinary.LittleEndian.PutUint16(buf[4:6], uint16(m.Status))\n\n\treturn nil\n}\n\ntype Dot11MgmtDeauthentication struct {\n\tDot11Mgmt\n\tReason Dot11Reason\n}\n\nfunc decodeDot11MgmtDeauthentication(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11MgmtDeauthentication{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11MgmtDeauthentication) LayerType() gopacket.LayerType {\n\treturn LayerTypeDot11MgmtDeauthentication\n}\nfunc (m *Dot11MgmtDeauthentication) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot11MgmtDeauthentication\n}\nfunc (m *Dot11MgmtDeauthentication) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 2 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"Dot11MgmtDeauthentication length %v too short, %v required\", len(data), 2)\n\t}\n\tm.Reason = Dot11Reason(binary.LittleEndian.Uint16(data[0:2]))\n\treturn m.Dot11Mgmt.DecodeFromBytes(data, df)\n}\n\nfunc (m Dot11MgmtDeauthentication) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbuf, err := b.PrependBytes(2)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbinary.LittleEndian.PutUint16(buf[0:2], uint16(m.Reason))\n\n\treturn nil\n}\n\ntype Dot11MgmtAction struct {\n\tDot11Mgmt\n}\n\nfunc decodeDot11MgmtAction(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11MgmtAction{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11MgmtAction) LayerType() gopacket.LayerType  { return LayerTypeDot11MgmtAction }\nfunc (m *Dot11MgmtAction) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtAction }\n\ntype Dot11MgmtActionNoAck struct {\n\tDot11Mgmt\n}\n\nfunc decodeDot11MgmtActionNoAck(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11MgmtActionNoAck{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11MgmtActionNoAck) LayerType() gopacket.LayerType  { return LayerTypeDot11MgmtActionNoAck }\nfunc (m *Dot11MgmtActionNoAck) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtActionNoAck }\n\ntype Dot11MgmtArubaWLAN struct {\n\tDot11Mgmt\n}\n\nfunc decodeDot11MgmtArubaWLAN(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot11MgmtArubaWLAN{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *Dot11MgmtArubaWLAN) LayerType() gopacket.LayerType  { return LayerTypeDot11MgmtArubaWLAN }\nfunc (m *Dot11MgmtArubaWLAN) CanDecode() gopacket.LayerClass { return LayerTypeDot11MgmtArubaWLAN }\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/dot1q.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n// Copyright 2009-2011 Andreas Krennmair. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"github.com/google/gopacket\"\n)\n\n// Dot1Q is the packet layer for 802.1Q VLAN headers.\ntype Dot1Q struct {\n\tBaseLayer\n\tPriority       uint8\n\tDropEligible   bool\n\tVLANIdentifier uint16\n\tType           EthernetType\n}\n\n// LayerType returns gopacket.LayerTypeDot1Q\nfunc (d *Dot1Q) LayerType() gopacket.LayerType { return LayerTypeDot1Q }\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (d *Dot1Q) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 4 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"802.1Q tag length %d too short\", len(data))\n\t}\n\td.Priority = (data[0] & 0xE0) >> 5\n\td.DropEligible = data[0]&0x10 != 0\n\td.VLANIdentifier = binary.BigEndian.Uint16(data[:2]) & 0x0FFF\n\td.Type = EthernetType(binary.BigEndian.Uint16(data[2:4]))\n\td.BaseLayer = BaseLayer{Contents: data[:4], Payload: data[4:]}\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (d *Dot1Q) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeDot1Q\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (d *Dot1Q) NextLayerType() gopacket.LayerType {\n\treturn d.Type.LayerType()\n}\n\nfunc decodeDot1Q(data []byte, p gopacket.PacketBuilder) error {\n\td := &Dot1Q{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (d *Dot1Q) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbytes, err := b.PrependBytes(4)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif d.VLANIdentifier > 0xFFF {\n\t\treturn fmt.Errorf(\"vlan identifier %v is too high\", d.VLANIdentifier)\n\t}\n\tfirstBytes := uint16(d.Priority)<<13 | d.VLANIdentifier\n\tif d.DropEligible {\n\t\tfirstBytes |= 0x1000\n\t}\n\tbinary.BigEndian.PutUint16(bytes, firstBytes)\n\tbinary.BigEndian.PutUint16(bytes[2:], uint16(d.Type))\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/eap.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"github.com/google/gopacket\"\n)\n\ntype EAPCode uint8\ntype EAPType uint8\n\nconst (\n\tEAPCodeRequest  EAPCode = 1\n\tEAPCodeResponse EAPCode = 2\n\tEAPCodeSuccess  EAPCode = 3\n\tEAPCodeFailure  EAPCode = 4\n\n\t// EAPTypeNone means that this EAP layer has no Type or TypeData.\n\t// Success and Failure EAPs will have this set.\n\tEAPTypeNone EAPType = 0\n\n\tEAPTypeIdentity     EAPType = 1\n\tEAPTypeNotification EAPType = 2\n\tEAPTypeNACK         EAPType = 3\n\tEAPTypeOTP          EAPType = 4\n\tEAPTypeTokenCard    EAPType = 5\n)\n\n// EAP defines an Extensible Authentication Protocol (rfc 3748) layer.\ntype EAP struct {\n\tBaseLayer\n\tCode     EAPCode\n\tId       uint8\n\tLength   uint16\n\tType     EAPType\n\tTypeData []byte\n}\n\n// LayerType returns LayerTypeEAP.\nfunc (e *EAP) LayerType() gopacket.LayerType { return LayerTypeEAP }\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (e *EAP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 4 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"EAP length %d too short\", len(data))\n\t}\n\te.Code = EAPCode(data[0])\n\te.Id = data[1]\n\te.Length = binary.BigEndian.Uint16(data[2:4])\n\tif len(data) < int(e.Length) {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"EAP length %d too short, %d expected\", len(data), e.Length)\n\t}\n\tswitch {\n\tcase e.Length > 4:\n\t\te.Type = EAPType(data[4])\n\t\te.TypeData = data[5:]\n\tcase e.Length == 4:\n\t\te.Type = 0\n\t\te.TypeData = nil\n\tdefault:\n\t\treturn fmt.Errorf(\"invalid EAP length %d\", e.Length)\n\t}\n\te.BaseLayer.Contents = data[:e.Length]\n\te.BaseLayer.Payload = data[e.Length:] // Should be 0 bytes\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (e *EAP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tif opts.FixLengths {\n\t\te.Length = uint16(len(e.TypeData) + 1)\n\t}\n\tsize := len(e.TypeData) + 4\n\tif size > 4 {\n\t\tsize++\n\t}\n\tbytes, err := b.PrependBytes(size)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbytes[0] = byte(e.Code)\n\tbytes[1] = e.Id\n\tbinary.BigEndian.PutUint16(bytes[2:], e.Length)\n\tif size > 4 {\n\t\tbytes[4] = byte(e.Type)\n\t\tcopy(bytes[5:], e.TypeData)\n\t}\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (e *EAP) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeEAP\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (e *EAP) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypeZero\n}\n\nfunc decodeEAP(data []byte, p gopacket.PacketBuilder) error {\n\te := &EAP{}\n\treturn decodingLayerDecoder(e, data, p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/eapol.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"github.com/google/gopacket\"\n)\n\n// EAPOL defines an EAP over LAN (802.1x) layer.\ntype EAPOL struct {\n\tBaseLayer\n\tVersion uint8\n\tType    EAPOLType\n\tLength  uint16\n}\n\n// LayerType returns LayerTypeEAPOL.\nfunc (e *EAPOL) LayerType() gopacket.LayerType { return LayerTypeEAPOL }\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (e *EAPOL) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 4 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"EAPOL length %d too short\", len(data))\n\t}\n\te.Version = data[0]\n\te.Type = EAPOLType(data[1])\n\te.Length = binary.BigEndian.Uint16(data[2:4])\n\te.BaseLayer = BaseLayer{data[:4], data[4:]}\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer\nfunc (e *EAPOL) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbytes, _ := b.PrependBytes(4)\n\tbytes[0] = e.Version\n\tbytes[1] = byte(e.Type)\n\tbinary.BigEndian.PutUint16(bytes[2:], e.Length)\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (e *EAPOL) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeEAPOL\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (e *EAPOL) NextLayerType() gopacket.LayerType {\n\treturn e.Type.LayerType()\n}\n\nfunc decodeEAPOL(data []byte, p gopacket.PacketBuilder) error {\n\te := &EAPOL{}\n\treturn decodingLayerDecoder(e, data, p)\n}\n\n// EAPOLKeyDescriptorType is an enumeration of key descriptor types\n// as specified by 802.1x in the EAPOL-Key frame\ntype EAPOLKeyDescriptorType uint8\n\n// Enumeration of EAPOLKeyDescriptorType\nconst (\n\tEAPOLKeyDescriptorTypeRC4   EAPOLKeyDescriptorType = 1\n\tEAPOLKeyDescriptorTypeDot11 EAPOLKeyDescriptorType = 2\n\tEAPOLKeyDescriptorTypeWPA   EAPOLKeyDescriptorType = 254\n)\n\nfunc (kdt EAPOLKeyDescriptorType) String() string {\n\tswitch kdt {\n\tcase EAPOLKeyDescriptorTypeRC4:\n\t\treturn \"RC4\"\n\tcase EAPOLKeyDescriptorTypeDot11:\n\t\treturn \"802.11\"\n\tcase EAPOLKeyDescriptorTypeWPA:\n\t\treturn \"WPA\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"unknown descriptor type %d\", kdt)\n\t}\n}\n\n// EAPOLKeyDescriptorVersion is an enumeration of versions specifying the\n// encryption algorithm for the key data and the authentication for the\n// message integrity code (MIC)\ntype EAPOLKeyDescriptorVersion uint8\n\n// Enumeration of EAPOLKeyDescriptorVersion\nconst (\n\tEAPOLKeyDescriptorVersionOther       EAPOLKeyDescriptorVersion = 0\n\tEAPOLKeyDescriptorVersionRC4HMACMD5  EAPOLKeyDescriptorVersion = 1\n\tEAPOLKeyDescriptorVersionAESHMACSHA1 EAPOLKeyDescriptorVersion = 2\n\tEAPOLKeyDescriptorVersionAES128CMAC  EAPOLKeyDescriptorVersion = 3\n)\n\nfunc (v EAPOLKeyDescriptorVersion) String() string {\n\tswitch v {\n\tcase EAPOLKeyDescriptorVersionOther:\n\t\treturn \"Other\"\n\tcase EAPOLKeyDescriptorVersionRC4HMACMD5:\n\t\treturn \"RC4-HMAC-MD5\"\n\tcase EAPOLKeyDescriptorVersionAESHMACSHA1:\n\t\treturn \"AES-HMAC-SHA1-128\"\n\tcase EAPOLKeyDescriptorVersionAES128CMAC:\n\t\treturn \"AES-128-CMAC\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"unknown version %d\", v)\n\t}\n}\n\n// EAPOLKeyType is an enumeration of key derivation types describing\n// the purpose of the keys being derived.\ntype EAPOLKeyType uint8\n\n// Enumeration of EAPOLKeyType\nconst (\n\tEAPOLKeyTypeGroupSMK EAPOLKeyType = 0\n\tEAPOLKeyTypePairwise EAPOLKeyType = 1\n)\n\nfunc (kt EAPOLKeyType) String() string {\n\tswitch kt {\n\tcase EAPOLKeyTypeGroupSMK:\n\t\treturn \"Group/SMK\"\n\tcase EAPOLKeyTypePairwise:\n\t\treturn \"Pairwise\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"unknown key type %d\", kt)\n\t}\n}\n\n// EAPOLKey defines an EAPOL-Key frame for 802.1x authentication\ntype EAPOLKey struct {\n\tBaseLayer\n\tKeyDescriptorType    EAPOLKeyDescriptorType\n\tKeyDescriptorVersion EAPOLKeyDescriptorVersion\n\tKeyType              EAPOLKeyType\n\tKeyIndex             uint8\n\tInstall              bool\n\tKeyACK               bool\n\tKeyMIC               bool\n\tSecure               bool\n\tMICError             bool\n\tRequest              bool\n\tHasEncryptedKeyData  bool\n\tSMKMessage           bool\n\tKeyLength            uint16\n\tReplayCounter        uint64\n\tNonce                []byte\n\tIV                   []byte\n\tRSC                  uint64\n\tID                   uint64\n\tMIC                  []byte\n\tKeyDataLength        uint16\n\tEncryptedKeyData     []byte\n}\n\n// LayerType returns LayerTypeEAPOLKey.\nfunc (ek *EAPOLKey) LayerType() gopacket.LayerType {\n\treturn LayerTypeEAPOLKey\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (ek *EAPOLKey) CanDecode() gopacket.LayerType {\n\treturn LayerTypeEAPOLKey\n}\n\n// NextLayerType returns layers.LayerTypeDot11InformationElement if the key\n// data exists and is unencrypted, otherwise it does not expect a next layer.\nfunc (ek *EAPOLKey) NextLayerType() gopacket.LayerType {\n\tif !ek.HasEncryptedKeyData && ek.KeyDataLength > 0 {\n\t\treturn LayerTypeDot11InformationElement\n\t}\n\treturn gopacket.LayerTypePayload\n}\n\nconst eapolKeyFrameLen = 95\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (ek *EAPOLKey) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < eapolKeyFrameLen {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"EAPOLKey length %v too short, %v required\",\n\t\t\tlen(data), eapolKeyFrameLen)\n\t}\n\n\tek.KeyDescriptorType = EAPOLKeyDescriptorType(data[0])\n\n\tinfo := binary.BigEndian.Uint16(data[1:3])\n\tek.KeyDescriptorVersion = EAPOLKeyDescriptorVersion(info & 0x0007)\n\tek.KeyType = EAPOLKeyType((info & 0x0008) >> 3)\n\tek.KeyIndex = uint8((info & 0x0030) >> 4)\n\tek.Install = (info & 0x0040) != 0\n\tek.KeyACK = (info & 0x0080) != 0\n\tek.KeyMIC = (info & 0x0100) != 0\n\tek.Secure = (info & 0x0200) != 0\n\tek.MICError = (info & 0x0400) != 0\n\tek.Request = (info & 0x0800) != 0\n\tek.HasEncryptedKeyData = (info & 0x1000) != 0\n\tek.SMKMessage = (info & 0x2000) != 0\n\n\tek.KeyLength = binary.BigEndian.Uint16(data[3:5])\n\tek.ReplayCounter = binary.BigEndian.Uint64(data[5:13])\n\n\tek.Nonce = data[13:45]\n\tek.IV = data[45:61]\n\tek.RSC = binary.BigEndian.Uint64(data[61:69])\n\tek.ID = binary.BigEndian.Uint64(data[69:77])\n\tek.MIC = data[77:93]\n\n\tek.KeyDataLength = binary.BigEndian.Uint16(data[93:95])\n\n\ttotalLength := eapolKeyFrameLen + int(ek.KeyDataLength)\n\tif len(data) < totalLength {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"EAPOLKey data length %d too short, %d required\",\n\t\t\tlen(data)-eapolKeyFrameLen, ek.KeyDataLength)\n\t}\n\n\tif ek.HasEncryptedKeyData {\n\t\tek.EncryptedKeyData = data[eapolKeyFrameLen:totalLength]\n\t\tek.BaseLayer = BaseLayer{\n\t\t\tContents: data[:totalLength],\n\t\t\tPayload:  data[totalLength:],\n\t\t}\n\t} else {\n\t\tek.BaseLayer = BaseLayer{\n\t\t\tContents: data[:eapolKeyFrameLen],\n\t\t\tPayload:  data[eapolKeyFrameLen:],\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (ek *EAPOLKey) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbuf, err := b.PrependBytes(eapolKeyFrameLen + len(ek.EncryptedKeyData))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbuf[0] = byte(ek.KeyDescriptorType)\n\n\tvar info uint16\n\tinfo |= uint16(ek.KeyDescriptorVersion)\n\tinfo |= uint16(ek.KeyType) << 3\n\tinfo |= uint16(ek.KeyIndex) << 4\n\tif ek.Install {\n\t\tinfo |= 0x0040\n\t}\n\tif ek.KeyACK {\n\t\tinfo |= 0x0080\n\t}\n\tif ek.KeyMIC {\n\t\tinfo |= 0x0100\n\t}\n\tif ek.Secure {\n\t\tinfo |= 0x0200\n\t}\n\tif ek.MICError {\n\t\tinfo |= 0x0400\n\t}\n\tif ek.Request {\n\t\tinfo |= 0x0800\n\t}\n\tif ek.HasEncryptedKeyData {\n\t\tinfo |= 0x1000\n\t}\n\tif ek.SMKMessage {\n\t\tinfo |= 0x2000\n\t}\n\tbinary.BigEndian.PutUint16(buf[1:3], info)\n\n\tbinary.BigEndian.PutUint16(buf[3:5], ek.KeyLength)\n\tbinary.BigEndian.PutUint64(buf[5:13], ek.ReplayCounter)\n\n\tcopy(buf[13:45], ek.Nonce)\n\tcopy(buf[45:61], ek.IV)\n\tbinary.BigEndian.PutUint64(buf[61:69], ek.RSC)\n\tbinary.BigEndian.PutUint64(buf[69:77], ek.ID)\n\tcopy(buf[77:93], ek.MIC)\n\n\tbinary.BigEndian.PutUint16(buf[93:95], ek.KeyDataLength)\n\tif len(ek.EncryptedKeyData) > 0 {\n\t\tcopy(buf[95:95+len(ek.EncryptedKeyData)], ek.EncryptedKeyData)\n\t}\n\n\treturn nil\n}\n\nfunc decodeEAPOLKey(data []byte, p gopacket.PacketBuilder) error {\n\tek := &EAPOLKey{}\n\treturn decodingLayerDecoder(ek, data, p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/endpoints.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"github.com/google/gopacket\"\n\t\"net\"\n\t\"strconv\"\n)\n\nvar (\n\t// We use two different endpoint types for IPv4 vs IPv6 addresses, so that\n\t// ordering with endpointA.LessThan(endpointB) sanely groups all IPv4\n\t// addresses and all IPv6 addresses, such that IPv6 > IPv4 for all addresses.\n\tEndpointIPv4 = gopacket.RegisterEndpointType(1, gopacket.EndpointTypeMetadata{Name: \"IPv4\", Formatter: func(b []byte) string {\n\t\treturn net.IP(b).String()\n\t}})\n\tEndpointIPv6 = gopacket.RegisterEndpointType(2, gopacket.EndpointTypeMetadata{Name: \"IPv6\", Formatter: func(b []byte) string {\n\t\treturn net.IP(b).String()\n\t}})\n\n\tEndpointMAC = gopacket.RegisterEndpointType(3, gopacket.EndpointTypeMetadata{Name: \"MAC\", Formatter: func(b []byte) string {\n\t\treturn net.HardwareAddr(b).String()\n\t}})\n\tEndpointTCPPort = gopacket.RegisterEndpointType(4, gopacket.EndpointTypeMetadata{Name: \"TCP\", Formatter: func(b []byte) string {\n\t\treturn strconv.Itoa(int(binary.BigEndian.Uint16(b)))\n\t}})\n\tEndpointUDPPort = gopacket.RegisterEndpointType(5, gopacket.EndpointTypeMetadata{Name: \"UDP\", Formatter: func(b []byte) string {\n\t\treturn strconv.Itoa(int(binary.BigEndian.Uint16(b)))\n\t}})\n\tEndpointSCTPPort = gopacket.RegisterEndpointType(6, gopacket.EndpointTypeMetadata{Name: \"SCTP\", Formatter: func(b []byte) string {\n\t\treturn strconv.Itoa(int(binary.BigEndian.Uint16(b)))\n\t}})\n\tEndpointRUDPPort = gopacket.RegisterEndpointType(7, gopacket.EndpointTypeMetadata{Name: \"RUDP\", Formatter: func(b []byte) string {\n\t\treturn strconv.Itoa(int(b[0]))\n\t}})\n\tEndpointUDPLitePort = gopacket.RegisterEndpointType(8, gopacket.EndpointTypeMetadata{Name: \"UDPLite\", Formatter: func(b []byte) string {\n\t\treturn strconv.Itoa(int(binary.BigEndian.Uint16(b)))\n\t}})\n\tEndpointPPP = gopacket.RegisterEndpointType(9, gopacket.EndpointTypeMetadata{Name: \"PPP\", Formatter: func([]byte) string {\n\t\treturn \"point\"\n\t}})\n)\n\n// NewIPEndpoint creates a new IP (v4 or v6) endpoint from a net.IP address.\n// It returns gopacket.InvalidEndpoint if the IP address is invalid.\nfunc NewIPEndpoint(a net.IP) gopacket.Endpoint {\n\tipv4 := a.To4()\n\tif ipv4 != nil {\n\t\treturn gopacket.NewEndpoint(EndpointIPv4, []byte(ipv4))\n\t}\n\n\tipv6 := a.To16()\n\tif ipv6 != nil {\n\t\treturn gopacket.NewEndpoint(EndpointIPv6, []byte(ipv6))\n\t}\n\n\treturn gopacket.InvalidEndpoint\n}\n\n// NewMACEndpoint returns a new MAC address endpoint.\nfunc NewMACEndpoint(a net.HardwareAddr) gopacket.Endpoint {\n\treturn gopacket.NewEndpoint(EndpointMAC, []byte(a))\n}\nfunc newPortEndpoint(t gopacket.EndpointType, p uint16) gopacket.Endpoint {\n\treturn gopacket.NewEndpoint(t, []byte{byte(p >> 8), byte(p)})\n}\n\n// NewTCPPortEndpoint returns an endpoint based on a TCP port.\nfunc NewTCPPortEndpoint(p TCPPort) gopacket.Endpoint {\n\treturn newPortEndpoint(EndpointTCPPort, uint16(p))\n}\n\n// NewUDPPortEndpoint returns an endpoint based on a UDP port.\nfunc NewUDPPortEndpoint(p UDPPort) gopacket.Endpoint {\n\treturn newPortEndpoint(EndpointUDPPort, uint16(p))\n}\n\n// NewSCTPPortEndpoint returns an endpoint based on a SCTP port.\nfunc NewSCTPPortEndpoint(p SCTPPort) gopacket.Endpoint {\n\treturn newPortEndpoint(EndpointSCTPPort, uint16(p))\n}\n\n// NewRUDPPortEndpoint returns an endpoint based on a RUDP port.\nfunc NewRUDPPortEndpoint(p RUDPPort) gopacket.Endpoint {\n\treturn gopacket.NewEndpoint(EndpointRUDPPort, []byte{byte(p)})\n}\n\n// NewUDPLitePortEndpoint returns an endpoint based on a UDPLite port.\nfunc NewUDPLitePortEndpoint(p UDPLitePort) gopacket.Endpoint {\n\treturn newPortEndpoint(EndpointUDPLitePort, uint16(p))\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/enums.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n// Copyright 2009-2011 Andreas Krennmair. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"fmt\"\n\t\"runtime\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// EnumMetadata keeps track of a set of metadata for each enumeration value\n// for protocol enumerations.\ntype EnumMetadata struct {\n\t// DecodeWith is the decoder to use to decode this protocol's data.\n\tDecodeWith gopacket.Decoder\n\t// Name is the name of the enumeration value.\n\tName string\n\t// LayerType is the layer type implied by the given enum.\n\tLayerType gopacket.LayerType\n}\n\n// EthernetType is an enumeration of ethernet type values, and acts as a decoder\n// for any type it supports.\ntype EthernetType uint16\n\nconst (\n\t// EthernetTypeLLC is not an actual ethernet type.  It is instead a\n\t// placeholder we use in Ethernet frames that use the 802.3 standard of\n\t// srcmac|dstmac|length|LLC instead of srcmac|dstmac|ethertype.\n\tEthernetTypeLLC                         EthernetType = 0\n\tEthernetTypeIPv4                        EthernetType = 0x0800\n\tEthernetTypeARP                         EthernetType = 0x0806\n\tEthernetTypeIPv6                        EthernetType = 0x86DD\n\tEthernetTypeCiscoDiscovery              EthernetType = 0x2000\n\tEthernetTypeNortelDiscovery             EthernetType = 0x01a2\n\tEthernetTypeTransparentEthernetBridging EthernetType = 0x6558\n\tEthernetTypeDot1Q                       EthernetType = 0x8100\n\tEthernetTypePPP                         EthernetType = 0x880b\n\tEthernetTypePPPoEDiscovery              EthernetType = 0x8863\n\tEthernetTypePPPoESession                EthernetType = 0x8864\n\tEthernetTypeMPLSUnicast                 EthernetType = 0x8847\n\tEthernetTypeMPLSMulticast               EthernetType = 0x8848\n\tEthernetTypeEAPOL                       EthernetType = 0x888e\n\tEthernetTypeERSPAN                      EthernetType = 0x88be\n\tEthernetTypeQinQ                        EthernetType = 0x88a8\n\tEthernetTypeLinkLayerDiscovery          EthernetType = 0x88cc\n\tEthernetTypeEthernetCTP                 EthernetType = 0x9000\n)\n\n// IPProtocol is an enumeration of IP protocol values, and acts as a decoder\n// for any type it supports.\ntype IPProtocol uint8\n\nconst (\n\tIPProtocolIPv6HopByHop    IPProtocol = 0\n\tIPProtocolICMPv4          IPProtocol = 1\n\tIPProtocolIGMP            IPProtocol = 2\n\tIPProtocolIPv4            IPProtocol = 4\n\tIPProtocolTCP             IPProtocol = 6\n\tIPProtocolUDP             IPProtocol = 17\n\tIPProtocolRUDP            IPProtocol = 27\n\tIPProtocolIPv6            IPProtocol = 41\n\tIPProtocolIPv6Routing     IPProtocol = 43\n\tIPProtocolIPv6Fragment    IPProtocol = 44\n\tIPProtocolGRE             IPProtocol = 47\n\tIPProtocolESP             IPProtocol = 50\n\tIPProtocolAH              IPProtocol = 51\n\tIPProtocolICMPv6          IPProtocol = 58\n\tIPProtocolNoNextHeader    IPProtocol = 59\n\tIPProtocolIPv6Destination IPProtocol = 60\n\tIPProtocolOSPF            IPProtocol = 89\n\tIPProtocolIPIP            IPProtocol = 94\n\tIPProtocolEtherIP         IPProtocol = 97\n\tIPProtocolVRRP            IPProtocol = 112\n\tIPProtocolSCTP            IPProtocol = 132\n\tIPProtocolUDPLite         IPProtocol = 136\n\tIPProtocolMPLSInIP        IPProtocol = 137\n)\n\n// LinkType is an enumeration of link types, and acts as a decoder for any\n// link type it supports.\ntype LinkType uint8\n\nconst (\n\t// According to pcap-linktype(7) and http://www.tcpdump.org/linktypes.html\n\tLinkTypeNull           LinkType = 0\n\tLinkTypeEthernet       LinkType = 1\n\tLinkTypeAX25           LinkType = 3\n\tLinkTypeTokenRing      LinkType = 6\n\tLinkTypeArcNet         LinkType = 7\n\tLinkTypeSLIP           LinkType = 8\n\tLinkTypePPP            LinkType = 9\n\tLinkTypeFDDI           LinkType = 10\n\tLinkTypePPP_HDLC       LinkType = 50\n\tLinkTypePPPEthernet    LinkType = 51\n\tLinkTypeATM_RFC1483    LinkType = 100\n\tLinkTypeRaw            LinkType = 101\n\tLinkTypeC_HDLC         LinkType = 104\n\tLinkTypeIEEE802_11     LinkType = 105\n\tLinkTypeFRelay         LinkType = 107\n\tLinkTypeLoop           LinkType = 108\n\tLinkTypeLinuxSLL       LinkType = 113\n\tLinkTypeLTalk          LinkType = 114\n\tLinkTypePFLog          LinkType = 117\n\tLinkTypePrismHeader    LinkType = 119\n\tLinkTypeIPOverFC       LinkType = 122\n\tLinkTypeSunATM         LinkType = 123\n\tLinkTypeIEEE80211Radio LinkType = 127\n\tLinkTypeARCNetLinux    LinkType = 129\n\tLinkTypeIPOver1394     LinkType = 138\n\tLinkTypeMTP2Phdr       LinkType = 139\n\tLinkTypeMTP2           LinkType = 140\n\tLinkTypeMTP3           LinkType = 141\n\tLinkTypeSCCP           LinkType = 142\n\tLinkTypeDOCSIS         LinkType = 143\n\tLinkTypeLinuxIRDA      LinkType = 144\n\tLinkTypeLinuxLAPD      LinkType = 177\n\tLinkTypeLinuxUSB       LinkType = 220\n\tLinkTypeFC2            LinkType = 224\n\tLinkTypeFC2Framed      LinkType = 225\n\tLinkTypeIPv4           LinkType = 228\n\tLinkTypeIPv6           LinkType = 229\n)\n\n// PPPoECode is the PPPoE code enum, taken from http://tools.ietf.org/html/rfc2516\ntype PPPoECode uint8\n\nconst (\n\tPPPoECodePADI    PPPoECode = 0x09\n\tPPPoECodePADO    PPPoECode = 0x07\n\tPPPoECodePADR    PPPoECode = 0x19\n\tPPPoECodePADS    PPPoECode = 0x65\n\tPPPoECodePADT    PPPoECode = 0xA7\n\tPPPoECodeSession PPPoECode = 0x00\n)\n\n// PPPType is an enumeration of PPP type values, and acts as a decoder for any\n// type it supports.\ntype PPPType uint16\n\nconst (\n\tPPPTypeIPv4          PPPType = 0x0021\n\tPPPTypeIPv6          PPPType = 0x0057\n\tPPPTypeMPLSUnicast   PPPType = 0x0281\n\tPPPTypeMPLSMulticast PPPType = 0x0283\n)\n\n// SCTPChunkType is an enumeration of chunk types inside SCTP packets.\ntype SCTPChunkType uint8\n\nconst (\n\tSCTPChunkTypeData             SCTPChunkType = 0\n\tSCTPChunkTypeInit             SCTPChunkType = 1\n\tSCTPChunkTypeInitAck          SCTPChunkType = 2\n\tSCTPChunkTypeSack             SCTPChunkType = 3\n\tSCTPChunkTypeHeartbeat        SCTPChunkType = 4\n\tSCTPChunkTypeHeartbeatAck     SCTPChunkType = 5\n\tSCTPChunkTypeAbort            SCTPChunkType = 6\n\tSCTPChunkTypeShutdown         SCTPChunkType = 7\n\tSCTPChunkTypeShutdownAck      SCTPChunkType = 8\n\tSCTPChunkTypeError            SCTPChunkType = 9\n\tSCTPChunkTypeCookieEcho       SCTPChunkType = 10\n\tSCTPChunkTypeCookieAck        SCTPChunkType = 11\n\tSCTPChunkTypeShutdownComplete SCTPChunkType = 14\n)\n\n// FDDIFrameControl is an enumeration of FDDI frame control bytes.\ntype FDDIFrameControl uint8\n\nconst (\n\tFDDIFrameControlLLC FDDIFrameControl = 0x50\n)\n\n// EAPOLType is an enumeration of EAPOL packet types.\ntype EAPOLType uint8\n\nconst (\n\tEAPOLTypeEAP      EAPOLType = 0\n\tEAPOLTypeStart    EAPOLType = 1\n\tEAPOLTypeLogOff   EAPOLType = 2\n\tEAPOLTypeKey      EAPOLType = 3\n\tEAPOLTypeASFAlert EAPOLType = 4\n)\n\n// ProtocolFamily is the set of values defined as PF_* in sys/socket.h\ntype ProtocolFamily uint8\n\nconst (\n\tProtocolFamilyIPv4 ProtocolFamily = 2\n\t// BSDs use different values for INET6... glory be.  These values taken from\n\t// tcpdump 4.3.0.\n\tProtocolFamilyIPv6BSD     ProtocolFamily = 24\n\tProtocolFamilyIPv6FreeBSD ProtocolFamily = 28\n\tProtocolFamilyIPv6Darwin  ProtocolFamily = 30\n\tProtocolFamilyIPv6Linux   ProtocolFamily = 10\n)\n\n// Dot11Type is a combination of IEEE 802.11 frame's Type and Subtype fields.\n// By combining these two fields together into a single type, we're able to\n// provide a String function that correctly displays the subtype given the\n// top-level type.\n//\n// If you just care about the top-level type, use the MainType function.\ntype Dot11Type uint8\n\n// MainType strips the subtype information from the given type,\n// returning just the overarching type (Mgmt, Ctrl, Data, Reserved).\nfunc (d Dot11Type) MainType() Dot11Type {\n\treturn d & dot11TypeMask\n}\n\nfunc (d Dot11Type) QOS() bool {\n\treturn d&dot11QOSMask == Dot11TypeDataQOSData\n}\n\nconst (\n\tDot11TypeMgmt     Dot11Type = 0x00\n\tDot11TypeCtrl     Dot11Type = 0x01\n\tDot11TypeData     Dot11Type = 0x02\n\tDot11TypeReserved Dot11Type = 0x03\n\tdot11TypeMask               = 0x03\n\tdot11QOSMask                = 0x23\n\n\t// The following are type/subtype conglomerations.\n\n\t// Management\n\tDot11TypeMgmtAssociationReq    Dot11Type = 0x00\n\tDot11TypeMgmtAssociationResp   Dot11Type = 0x04\n\tDot11TypeMgmtReassociationReq  Dot11Type = 0x08\n\tDot11TypeMgmtReassociationResp Dot11Type = 0x0c\n\tDot11TypeMgmtProbeReq          Dot11Type = 0x10\n\tDot11TypeMgmtProbeResp         Dot11Type = 0x14\n\tDot11TypeMgmtMeasurementPilot  Dot11Type = 0x18\n\tDot11TypeMgmtBeacon            Dot11Type = 0x20\n\tDot11TypeMgmtATIM              Dot11Type = 0x24\n\tDot11TypeMgmtDisassociation    Dot11Type = 0x28\n\tDot11TypeMgmtAuthentication    Dot11Type = 0x2c\n\tDot11TypeMgmtDeauthentication  Dot11Type = 0x30\n\tDot11TypeMgmtAction            Dot11Type = 0x34\n\tDot11TypeMgmtActionNoAck       Dot11Type = 0x38\n\n\t// Control\n\tDot11TypeCtrlWrapper       Dot11Type = 0x1d\n\tDot11TypeCtrlBlockAckReq   Dot11Type = 0x21\n\tDot11TypeCtrlBlockAck      Dot11Type = 0x25\n\tDot11TypeCtrlPowersavePoll Dot11Type = 0x29\n\tDot11TypeCtrlRTS           Dot11Type = 0x2d\n\tDot11TypeCtrlCTS           Dot11Type = 0x31\n\tDot11TypeCtrlAck           Dot11Type = 0x35\n\tDot11TypeCtrlCFEnd         Dot11Type = 0x39\n\tDot11TypeCtrlCFEndAck      Dot11Type = 0x3d\n\n\t// Data\n\tDot11TypeDataCFAck              Dot11Type = 0x06\n\tDot11TypeDataCFPoll             Dot11Type = 0x0a\n\tDot11TypeDataCFAckPoll          Dot11Type = 0x0e\n\tDot11TypeDataNull               Dot11Type = 0x12\n\tDot11TypeDataCFAckNoData        Dot11Type = 0x16\n\tDot11TypeDataCFPollNoData       Dot11Type = 0x1a\n\tDot11TypeDataCFAckPollNoData    Dot11Type = 0x1e\n\tDot11TypeDataQOSData            Dot11Type = 0x22\n\tDot11TypeDataQOSDataCFAck       Dot11Type = 0x26\n\tDot11TypeDataQOSDataCFPoll      Dot11Type = 0x2a\n\tDot11TypeDataQOSDataCFAckPoll   Dot11Type = 0x2e\n\tDot11TypeDataQOSNull            Dot11Type = 0x32\n\tDot11TypeDataQOSCFPollNoData    Dot11Type = 0x3a\n\tDot11TypeDataQOSCFAckPollNoData Dot11Type = 0x3e\n)\n\n// Decode a raw v4 or v6 IP packet.\nfunc decodeIPv4or6(data []byte, p gopacket.PacketBuilder) error {\n\tversion := data[0] >> 4\n\tswitch version {\n\tcase 4:\n\t\treturn decodeIPv4(data, p)\n\tcase 6:\n\t\treturn decodeIPv6(data, p)\n\t}\n\treturn fmt.Errorf(\"Invalid IP packet version %v\", version)\n}\n\nfunc initActualTypeData() {\n\t// Each of the XXXTypeMetadata arrays contains mappings of how to handle enum\n\t// values for various enum types in gopacket/layers.\n\t// These arrays are actually created by gen2.go and stored in\n\t// enums_generated.go.\n\t//\n\t// So, EthernetTypeMetadata[2] contains information on how to handle EthernetType\n\t// 2, including which name to give it and which decoder to use to decode\n\t// packet data of that type.  These arrays are filled by default with all of the\n\t// protocols gopacket/layers knows how to handle, but users of the library can\n\t// add new decoders or override existing ones.  For example, if you write a better\n\t// TCP decoder, you can override IPProtocolMetadata[IPProtocolTCP].DecodeWith\n\t// with your new decoder, and all gopacket/layers decoding will use your new\n\t// decoder whenever they encounter that IPProtocol.\n\n\t// Here we link up all enumerations with their respective names and decoders.\n\tEthernetTypeMetadata[EthernetTypeLLC] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLLC), Name: \"LLC\", LayerType: LayerTypeLLC}\n\tEthernetTypeMetadata[EthernetTypeIPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: \"IPv4\", LayerType: LayerTypeIPv4}\n\tEthernetTypeMetadata[EthernetTypeIPv6] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: \"IPv6\", LayerType: LayerTypeIPv6}\n\tEthernetTypeMetadata[EthernetTypeARP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeARP), Name: \"ARP\", LayerType: LayerTypeARP}\n\tEthernetTypeMetadata[EthernetTypeDot1Q] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot1Q), Name: \"Dot1Q\", LayerType: LayerTypeDot1Q}\n\tEthernetTypeMetadata[EthernetTypePPP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPP), Name: \"PPP\", LayerType: LayerTypePPP}\n\tEthernetTypeMetadata[EthernetTypePPPoEDiscovery] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPPoE), Name: \"PPPoEDiscovery\", LayerType: LayerTypePPPoE}\n\tEthernetTypeMetadata[EthernetTypePPPoESession] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPPoE), Name: \"PPPoESession\", LayerType: LayerTypePPPoE}\n\tEthernetTypeMetadata[EthernetTypeEthernetCTP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEthernetCTP), Name: \"EthernetCTP\", LayerType: LayerTypeEthernetCTP}\n\tEthernetTypeMetadata[EthernetTypeCiscoDiscovery] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeCiscoDiscovery), Name: \"CiscoDiscovery\", LayerType: LayerTypeCiscoDiscovery}\n\tEthernetTypeMetadata[EthernetTypeNortelDiscovery] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeNortelDiscovery), Name: \"NortelDiscovery\", LayerType: LayerTypeNortelDiscovery}\n\tEthernetTypeMetadata[EthernetTypeLinkLayerDiscovery] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLinkLayerDiscovery), Name: \"LinkLayerDiscovery\", LayerType: LayerTypeLinkLayerDiscovery}\n\tEthernetTypeMetadata[EthernetTypeMPLSUnicast] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeMPLS), Name: \"MPLSUnicast\", LayerType: LayerTypeMPLS}\n\tEthernetTypeMetadata[EthernetTypeMPLSMulticast] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeMPLS), Name: \"MPLSMulticast\", LayerType: LayerTypeMPLS}\n\tEthernetTypeMetadata[EthernetTypeEAPOL] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEAPOL), Name: \"EAPOL\", LayerType: LayerTypeEAPOL}\n\tEthernetTypeMetadata[EthernetTypeQinQ] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot1Q), Name: \"Dot1Q\", LayerType: LayerTypeDot1Q}\n\tEthernetTypeMetadata[EthernetTypeTransparentEthernetBridging] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEthernet), Name: \"TransparentEthernetBridging\", LayerType: LayerTypeEthernet}\n\tEthernetTypeMetadata[EthernetTypeERSPAN] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeERSPANII), Name: \"ERSPAN Type II\", LayerType: LayerTypeERSPANII}\n\n\tIPProtocolMetadata[IPProtocolIPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: \"IPv4\", LayerType: LayerTypeIPv4}\n\tIPProtocolMetadata[IPProtocolTCP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeTCP), Name: \"TCP\", LayerType: LayerTypeTCP}\n\tIPProtocolMetadata[IPProtocolUDP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUDP), Name: \"UDP\", LayerType: LayerTypeUDP}\n\tIPProtocolMetadata[IPProtocolICMPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeICMPv4), Name: \"ICMPv4\", LayerType: LayerTypeICMPv4}\n\tIPProtocolMetadata[IPProtocolICMPv6] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeICMPv6), Name: \"ICMPv6\", LayerType: LayerTypeICMPv6}\n\tIPProtocolMetadata[IPProtocolSCTP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTP), Name: \"SCTP\", LayerType: LayerTypeSCTP}\n\tIPProtocolMetadata[IPProtocolIPv6] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: \"IPv6\", LayerType: LayerTypeIPv6}\n\tIPProtocolMetadata[IPProtocolIPIP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: \"IPv4\", LayerType: LayerTypeIPv4}\n\tIPProtocolMetadata[IPProtocolEtherIP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEtherIP), Name: \"EtherIP\", LayerType: LayerTypeEtherIP}\n\tIPProtocolMetadata[IPProtocolRUDP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeRUDP), Name: \"RUDP\", LayerType: LayerTypeRUDP}\n\tIPProtocolMetadata[IPProtocolGRE] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeGRE), Name: \"GRE\", LayerType: LayerTypeGRE}\n\tIPProtocolMetadata[IPProtocolIPv6HopByHop] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6HopByHop), Name: \"IPv6HopByHop\", LayerType: LayerTypeIPv6HopByHop}\n\tIPProtocolMetadata[IPProtocolIPv6Routing] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6Routing), Name: \"IPv6Routing\", LayerType: LayerTypeIPv6Routing}\n\tIPProtocolMetadata[IPProtocolIPv6Fragment] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6Fragment), Name: \"IPv6Fragment\", LayerType: LayerTypeIPv6Fragment}\n\tIPProtocolMetadata[IPProtocolIPv6Destination] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6Destination), Name: \"IPv6Destination\", LayerType: LayerTypeIPv6Destination}\n\tIPProtocolMetadata[IPProtocolOSPF] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeOSPF), Name: \"OSPF\", LayerType: LayerTypeOSPF}\n\tIPProtocolMetadata[IPProtocolAH] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPSecAH), Name: \"IPSecAH\", LayerType: LayerTypeIPSecAH}\n\tIPProtocolMetadata[IPProtocolESP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPSecESP), Name: \"IPSecESP\", LayerType: LayerTypeIPSecESP}\n\tIPProtocolMetadata[IPProtocolUDPLite] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUDPLite), Name: \"UDPLite\", LayerType: LayerTypeUDPLite}\n\tIPProtocolMetadata[IPProtocolMPLSInIP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeMPLS), Name: \"MPLS\", LayerType: LayerTypeMPLS}\n\tIPProtocolMetadata[IPProtocolNoNextHeader] = EnumMetadata{DecodeWith: gopacket.DecodePayload, Name: \"NoNextHeader\", LayerType: gopacket.LayerTypePayload}\n\tIPProtocolMetadata[IPProtocolIGMP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIGMP), Name: \"IGMP\", LayerType: LayerTypeIGMP}\n\tIPProtocolMetadata[IPProtocolVRRP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeVRRP), Name: \"VRRP\", LayerType: LayerTypeVRRP}\n\n\tSCTPChunkTypeMetadata[SCTPChunkTypeData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPData), Name: \"Data\"}\n\tSCTPChunkTypeMetadata[SCTPChunkTypeInit] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPInit), Name: \"Init\"}\n\tSCTPChunkTypeMetadata[SCTPChunkTypeInitAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPInit), Name: \"InitAck\"}\n\tSCTPChunkTypeMetadata[SCTPChunkTypeSack] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPSack), Name: \"Sack\"}\n\tSCTPChunkTypeMetadata[SCTPChunkTypeHeartbeat] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPHeartbeat), Name: \"Heartbeat\"}\n\tSCTPChunkTypeMetadata[SCTPChunkTypeHeartbeatAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPHeartbeat), Name: \"HeartbeatAck\"}\n\tSCTPChunkTypeMetadata[SCTPChunkTypeAbort] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPError), Name: \"Abort\"}\n\tSCTPChunkTypeMetadata[SCTPChunkTypeError] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPError), Name: \"Error\"}\n\tSCTPChunkTypeMetadata[SCTPChunkTypeShutdown] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPShutdown), Name: \"Shutdown\"}\n\tSCTPChunkTypeMetadata[SCTPChunkTypeShutdownAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPShutdownAck), Name: \"ShutdownAck\"}\n\tSCTPChunkTypeMetadata[SCTPChunkTypeCookieEcho] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPCookieEcho), Name: \"CookieEcho\"}\n\tSCTPChunkTypeMetadata[SCTPChunkTypeCookieAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPEmptyLayer), Name: \"CookieAck\"}\n\tSCTPChunkTypeMetadata[SCTPChunkTypeShutdownComplete] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeSCTPEmptyLayer), Name: \"ShutdownComplete\"}\n\n\tPPPTypeMetadata[PPPTypeIPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: \"IPv4\"}\n\tPPPTypeMetadata[PPPTypeIPv6] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: \"IPv6\"}\n\tPPPTypeMetadata[PPPTypeMPLSUnicast] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeMPLS), Name: \"MPLSUnicast\"}\n\tPPPTypeMetadata[PPPTypeMPLSMulticast] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeMPLS), Name: \"MPLSMulticast\"}\n\n\tPPPoECodeMetadata[PPPoECodeSession] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPP), Name: \"PPP\"}\n\n\tLinkTypeMetadata[LinkTypeEthernet] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEthernet), Name: \"Ethernet\"}\n\tLinkTypeMetadata[LinkTypePPP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPP), Name: \"PPP\"}\n\tLinkTypeMetadata[LinkTypeFDDI] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeFDDI), Name: \"FDDI\"}\n\tLinkTypeMetadata[LinkTypeNull] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLoopback), Name: \"Null\"}\n\tLinkTypeMetadata[LinkTypeIEEE802_11] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11), Name: \"Dot11\"}\n\tLinkTypeMetadata[LinkTypeLoop] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLoopback), Name: \"Loop\"}\n\tLinkTypeMetadata[LinkTypeIEEE802_11] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11), Name: \"802.11\"}\n\tLinkTypeMetadata[LinkTypeRaw] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4or6), Name: \"Raw\"}\n\t// See https://github.com/the-tcpdump-group/libpcap/blob/170f717e6e818cdc4bcbbfd906b63088eaa88fa0/pcap/dlt.h#L85\n\t// Or https://github.com/wireshark/wireshark/blob/854cfe53efe44080609c78053ecfb2342ad84a08/wiretap/pcap-common.c#L508\n\tif runtime.GOOS == \"openbsd\" {\n\t\tLinkTypeMetadata[14] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4or6), Name: \"Raw\"}\n\t} else {\n\t\tLinkTypeMetadata[12] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4or6), Name: \"Raw\"}\n\t}\n\tLinkTypeMetadata[LinkTypePFLog] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePFLog), Name: \"PFLog\"}\n\tLinkTypeMetadata[LinkTypeIEEE80211Radio] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeRadioTap), Name: \"RadioTap\"}\n\tLinkTypeMetadata[LinkTypeLinuxUSB] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUSB), Name: \"USB\"}\n\tLinkTypeMetadata[LinkTypeLinuxSLL] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLinuxSLL), Name: \"Linux SLL\"}\n\tLinkTypeMetadata[LinkTypePrismHeader] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePrismHeader), Name: \"Prism\"}\n\n\tFDDIFrameControlMetadata[FDDIFrameControlLLC] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLLC), Name: \"LLC\"}\n\n\tEAPOLTypeMetadata[EAPOLTypeEAP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEAP), Name: \"EAP\", LayerType: LayerTypeEAP}\n\tEAPOLTypeMetadata[EAPOLTypeKey] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEAPOLKey), Name: \"EAPOLKey\", LayerType: LayerTypeEAPOLKey}\n\n\tProtocolFamilyMetadata[ProtocolFamilyIPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: \"IPv4\", LayerType: LayerTypeIPv4}\n\tProtocolFamilyMetadata[ProtocolFamilyIPv6BSD] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: \"IPv6\", LayerType: LayerTypeIPv6}\n\tProtocolFamilyMetadata[ProtocolFamilyIPv6FreeBSD] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: \"IPv6\", LayerType: LayerTypeIPv6}\n\tProtocolFamilyMetadata[ProtocolFamilyIPv6Darwin] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: \"IPv6\", LayerType: LayerTypeIPv6}\n\tProtocolFamilyMetadata[ProtocolFamilyIPv6Linux] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: \"IPv6\", LayerType: LayerTypeIPv6}\n\n\tDot11TypeMetadata[Dot11TypeMgmtAssociationReq] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtAssociationReq), Name: \"MgmtAssociationReq\", LayerType: LayerTypeDot11MgmtAssociationReq}\n\tDot11TypeMetadata[Dot11TypeMgmtAssociationResp] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtAssociationResp), Name: \"MgmtAssociationResp\", LayerType: LayerTypeDot11MgmtAssociationResp}\n\tDot11TypeMetadata[Dot11TypeMgmtReassociationReq] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtReassociationReq), Name: \"MgmtReassociationReq\", LayerType: LayerTypeDot11MgmtReassociationReq}\n\tDot11TypeMetadata[Dot11TypeMgmtReassociationResp] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtReassociationResp), Name: \"MgmtReassociationResp\", LayerType: LayerTypeDot11MgmtReassociationResp}\n\tDot11TypeMetadata[Dot11TypeMgmtProbeReq] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtProbeReq), Name: \"MgmtProbeReq\", LayerType: LayerTypeDot11MgmtProbeReq}\n\tDot11TypeMetadata[Dot11TypeMgmtProbeResp] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtProbeResp), Name: \"MgmtProbeResp\", LayerType: LayerTypeDot11MgmtProbeResp}\n\tDot11TypeMetadata[Dot11TypeMgmtMeasurementPilot] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtMeasurementPilot), Name: \"MgmtMeasurementPilot\", LayerType: LayerTypeDot11MgmtMeasurementPilot}\n\tDot11TypeMetadata[Dot11TypeMgmtBeacon] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtBeacon), Name: \"MgmtBeacon\", LayerType: LayerTypeDot11MgmtBeacon}\n\tDot11TypeMetadata[Dot11TypeMgmtATIM] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtATIM), Name: \"MgmtATIM\", LayerType: LayerTypeDot11MgmtATIM}\n\tDot11TypeMetadata[Dot11TypeMgmtDisassociation] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtDisassociation), Name: \"MgmtDisassociation\", LayerType: LayerTypeDot11MgmtDisassociation}\n\tDot11TypeMetadata[Dot11TypeMgmtAuthentication] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtAuthentication), Name: \"MgmtAuthentication\", LayerType: LayerTypeDot11MgmtAuthentication}\n\tDot11TypeMetadata[Dot11TypeMgmtDeauthentication] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtDeauthentication), Name: \"MgmtDeauthentication\", LayerType: LayerTypeDot11MgmtDeauthentication}\n\tDot11TypeMetadata[Dot11TypeMgmtAction] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtAction), Name: \"MgmtAction\", LayerType: LayerTypeDot11MgmtAction}\n\tDot11TypeMetadata[Dot11TypeMgmtActionNoAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11MgmtActionNoAck), Name: \"MgmtActionNoAck\", LayerType: LayerTypeDot11MgmtActionNoAck}\n\tDot11TypeMetadata[Dot11TypeCtrl] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11Ctrl), Name: \"Ctrl\", LayerType: LayerTypeDot11Ctrl}\n\tDot11TypeMetadata[Dot11TypeCtrlWrapper] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11Ctrl), Name: \"CtrlWrapper\", LayerType: LayerTypeDot11Ctrl}\n\tDot11TypeMetadata[Dot11TypeCtrlBlockAckReq] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlBlockAckReq), Name: \"CtrlBlockAckReq\", LayerType: LayerTypeDot11CtrlBlockAckReq}\n\tDot11TypeMetadata[Dot11TypeCtrlBlockAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlBlockAck), Name: \"CtrlBlockAck\", LayerType: LayerTypeDot11CtrlBlockAck}\n\tDot11TypeMetadata[Dot11TypeCtrlPowersavePoll] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlPowersavePoll), Name: \"CtrlPowersavePoll\", LayerType: LayerTypeDot11CtrlPowersavePoll}\n\tDot11TypeMetadata[Dot11TypeCtrlRTS] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlRTS), Name: \"CtrlRTS\", LayerType: LayerTypeDot11CtrlRTS}\n\tDot11TypeMetadata[Dot11TypeCtrlCTS] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlCTS), Name: \"CtrlCTS\", LayerType: LayerTypeDot11CtrlCTS}\n\tDot11TypeMetadata[Dot11TypeCtrlAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlAck), Name: \"CtrlAck\", LayerType: LayerTypeDot11CtrlAck}\n\tDot11TypeMetadata[Dot11TypeCtrlCFEnd] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlCFEnd), Name: \"CtrlCFEnd\", LayerType: LayerTypeDot11CtrlCFEnd}\n\tDot11TypeMetadata[Dot11TypeCtrlCFEndAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11CtrlCFEndAck), Name: \"CtrlCFEndAck\", LayerType: LayerTypeDot11CtrlCFEndAck}\n\tDot11TypeMetadata[Dot11TypeData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11Data), Name: \"Data\", LayerType: LayerTypeDot11Data}\n\tDot11TypeMetadata[Dot11TypeDataCFAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFAck), Name: \"DataCFAck\", LayerType: LayerTypeDot11DataCFAck}\n\tDot11TypeMetadata[Dot11TypeDataCFPoll] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFPoll), Name: \"DataCFPoll\", LayerType: LayerTypeDot11DataCFPoll}\n\tDot11TypeMetadata[Dot11TypeDataCFAckPoll] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFAckPoll), Name: \"DataCFAckPoll\", LayerType: LayerTypeDot11DataCFAckPoll}\n\tDot11TypeMetadata[Dot11TypeDataNull] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataNull), Name: \"DataNull\", LayerType: LayerTypeDot11DataNull}\n\tDot11TypeMetadata[Dot11TypeDataCFAckNoData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFAckNoData), Name: \"DataCFAckNoData\", LayerType: LayerTypeDot11DataCFAckNoData}\n\tDot11TypeMetadata[Dot11TypeDataCFPollNoData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFPollNoData), Name: \"DataCFPollNoData\", LayerType: LayerTypeDot11DataCFPollNoData}\n\tDot11TypeMetadata[Dot11TypeDataCFAckPollNoData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataCFAckPollNoData), Name: \"DataCFAckPollNoData\", LayerType: LayerTypeDot11DataCFAckPollNoData}\n\tDot11TypeMetadata[Dot11TypeDataQOSData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSData), Name: \"DataQOSData\", LayerType: LayerTypeDot11DataQOSData}\n\tDot11TypeMetadata[Dot11TypeDataQOSDataCFAck] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAck), Name: \"DataQOSDataCFAck\", LayerType: LayerTypeDot11DataQOSDataCFAck}\n\tDot11TypeMetadata[Dot11TypeDataQOSDataCFPoll] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSDataCFPoll), Name: \"DataQOSDataCFPoll\", LayerType: LayerTypeDot11DataQOSDataCFPoll}\n\tDot11TypeMetadata[Dot11TypeDataQOSDataCFAckPoll] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAckPoll), Name: \"DataQOSDataCFAckPoll\", LayerType: LayerTypeDot11DataQOSDataCFAckPoll}\n\tDot11TypeMetadata[Dot11TypeDataQOSNull] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSNull), Name: \"DataQOSNull\", LayerType: LayerTypeDot11DataQOSNull}\n\tDot11TypeMetadata[Dot11TypeDataQOSCFPollNoData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSCFPollNoData), Name: \"DataQOSCFPollNoData\", LayerType: LayerTypeDot11DataQOSCFPollNoData}\n\tDot11TypeMetadata[Dot11TypeDataQOSCFAckPollNoData] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11DataQOSCFAckPollNoData), Name: \"DataQOSCFAckPollNoData\", LayerType: LayerTypeDot11DataQOSCFAckPollNoData}\n\n\tUSBTransportTypeMetadata[USBTransportTypeInterrupt] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUSBInterrupt), Name: \"Interrupt\", LayerType: LayerTypeUSBInterrupt}\n\tUSBTransportTypeMetadata[USBTransportTypeControl] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUSBControl), Name: \"Control\", LayerType: LayerTypeUSBControl}\n\tUSBTransportTypeMetadata[USBTransportTypeBulk] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUSBBulk), Name: \"Bulk\", LayerType: LayerTypeUSBBulk}\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/enums_generated.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n\npackage layers\n\n// Created by gen2.go, don't edit manually\n// Generated at 2017-10-23 10:20:24.458771856 -0600 MDT m=+0.001159033\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/google/gopacket\"\n)\n\nfunc init() {\n\tinitUnknownTypesForLinkType()\n\tinitUnknownTypesForEthernetType()\n\tinitUnknownTypesForPPPType()\n\tinitUnknownTypesForIPProtocol()\n\tinitUnknownTypesForSCTPChunkType()\n\tinitUnknownTypesForPPPoECode()\n\tinitUnknownTypesForFDDIFrameControl()\n\tinitUnknownTypesForEAPOLType()\n\tinitUnknownTypesForProtocolFamily()\n\tinitUnknownTypesForDot11Type()\n\tinitUnknownTypesForUSBTransportType()\n\tinitActualTypeData()\n}\n\n// Decoder calls LinkTypeMetadata.DecodeWith's decoder.\nfunc (a LinkType) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn LinkTypeMetadata[a].DecodeWith.Decode(data, p)\n}\n\n// String returns LinkTypeMetadata.Name.\nfunc (a LinkType) String() string {\n\treturn LinkTypeMetadata[a].Name\n}\n\n// LayerType returns LinkTypeMetadata.LayerType.\nfunc (a LinkType) LayerType() gopacket.LayerType {\n\treturn LinkTypeMetadata[a].LayerType\n}\n\ntype errorDecoderForLinkType int\n\nfunc (a *errorDecoderForLinkType) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn a\n}\nfunc (a *errorDecoderForLinkType) Error() string {\n\treturn fmt.Sprintf(\"Unable to decode LinkType %d\", int(*a))\n}\n\nvar errorDecodersForLinkType [256]errorDecoderForLinkType\nvar LinkTypeMetadata [256]EnumMetadata\n\nfunc initUnknownTypesForLinkType() {\n\tfor i := 0; i < 256; i++ {\n\t\terrorDecodersForLinkType[i] = errorDecoderForLinkType(i)\n\t\tLinkTypeMetadata[i] = EnumMetadata{\n\t\t\tDecodeWith: &errorDecodersForLinkType[i],\n\t\t\tName:       \"UnknownLinkType\",\n\t\t}\n\t}\n}\n\n// Decoder calls EthernetTypeMetadata.DecodeWith's decoder.\nfunc (a EthernetType) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn EthernetTypeMetadata[a].DecodeWith.Decode(data, p)\n}\n\n// String returns EthernetTypeMetadata.Name.\nfunc (a EthernetType) String() string {\n\treturn EthernetTypeMetadata[a].Name\n}\n\n// LayerType returns EthernetTypeMetadata.LayerType.\nfunc (a EthernetType) LayerType() gopacket.LayerType {\n\treturn EthernetTypeMetadata[a].LayerType\n}\n\ntype errorDecoderForEthernetType int\n\nfunc (a *errorDecoderForEthernetType) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn a\n}\nfunc (a *errorDecoderForEthernetType) Error() string {\n\treturn fmt.Sprintf(\"Unable to decode EthernetType %d\", int(*a))\n}\n\nvar errorDecodersForEthernetType [65536]errorDecoderForEthernetType\nvar EthernetTypeMetadata [65536]EnumMetadata\n\nfunc initUnknownTypesForEthernetType() {\n\tfor i := 0; i < 65536; i++ {\n\t\terrorDecodersForEthernetType[i] = errorDecoderForEthernetType(i)\n\t\tEthernetTypeMetadata[i] = EnumMetadata{\n\t\t\tDecodeWith: &errorDecodersForEthernetType[i],\n\t\t\tName:       \"UnknownEthernetType\",\n\t\t}\n\t}\n}\n\n// Decoder calls PPPTypeMetadata.DecodeWith's decoder.\nfunc (a PPPType) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn PPPTypeMetadata[a].DecodeWith.Decode(data, p)\n}\n\n// String returns PPPTypeMetadata.Name.\nfunc (a PPPType) String() string {\n\treturn PPPTypeMetadata[a].Name\n}\n\n// LayerType returns PPPTypeMetadata.LayerType.\nfunc (a PPPType) LayerType() gopacket.LayerType {\n\treturn PPPTypeMetadata[a].LayerType\n}\n\ntype errorDecoderForPPPType int\n\nfunc (a *errorDecoderForPPPType) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn a\n}\nfunc (a *errorDecoderForPPPType) Error() string {\n\treturn fmt.Sprintf(\"Unable to decode PPPType %d\", int(*a))\n}\n\nvar errorDecodersForPPPType [65536]errorDecoderForPPPType\nvar PPPTypeMetadata [65536]EnumMetadata\n\nfunc initUnknownTypesForPPPType() {\n\tfor i := 0; i < 65536; i++ {\n\t\terrorDecodersForPPPType[i] = errorDecoderForPPPType(i)\n\t\tPPPTypeMetadata[i] = EnumMetadata{\n\t\t\tDecodeWith: &errorDecodersForPPPType[i],\n\t\t\tName:       \"UnknownPPPType\",\n\t\t}\n\t}\n}\n\n// Decoder calls IPProtocolMetadata.DecodeWith's decoder.\nfunc (a IPProtocol) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn IPProtocolMetadata[a].DecodeWith.Decode(data, p)\n}\n\n// String returns IPProtocolMetadata.Name.\nfunc (a IPProtocol) String() string {\n\treturn IPProtocolMetadata[a].Name\n}\n\n// LayerType returns IPProtocolMetadata.LayerType.\nfunc (a IPProtocol) LayerType() gopacket.LayerType {\n\treturn IPProtocolMetadata[a].LayerType\n}\n\ntype errorDecoderForIPProtocol int\n\nfunc (a *errorDecoderForIPProtocol) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn a\n}\nfunc (a *errorDecoderForIPProtocol) Error() string {\n\treturn fmt.Sprintf(\"Unable to decode IPProtocol %d\", int(*a))\n}\n\nvar errorDecodersForIPProtocol [256]errorDecoderForIPProtocol\nvar IPProtocolMetadata [256]EnumMetadata\n\nfunc initUnknownTypesForIPProtocol() {\n\tfor i := 0; i < 256; i++ {\n\t\terrorDecodersForIPProtocol[i] = errorDecoderForIPProtocol(i)\n\t\tIPProtocolMetadata[i] = EnumMetadata{\n\t\t\tDecodeWith: &errorDecodersForIPProtocol[i],\n\t\t\tName:       \"UnknownIPProtocol\",\n\t\t}\n\t}\n}\n\n// Decoder calls SCTPChunkTypeMetadata.DecodeWith's decoder.\nfunc (a SCTPChunkType) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn SCTPChunkTypeMetadata[a].DecodeWith.Decode(data, p)\n}\n\n// String returns SCTPChunkTypeMetadata.Name.\nfunc (a SCTPChunkType) String() string {\n\treturn SCTPChunkTypeMetadata[a].Name\n}\n\n// LayerType returns SCTPChunkTypeMetadata.LayerType.\nfunc (a SCTPChunkType) LayerType() gopacket.LayerType {\n\treturn SCTPChunkTypeMetadata[a].LayerType\n}\n\ntype errorDecoderForSCTPChunkType int\n\nfunc (a *errorDecoderForSCTPChunkType) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn a\n}\nfunc (a *errorDecoderForSCTPChunkType) Error() string {\n\treturn fmt.Sprintf(\"Unable to decode SCTPChunkType %d\", int(*a))\n}\n\nvar errorDecodersForSCTPChunkType [256]errorDecoderForSCTPChunkType\nvar SCTPChunkTypeMetadata [256]EnumMetadata\n\nfunc initUnknownTypesForSCTPChunkType() {\n\tfor i := 0; i < 256; i++ {\n\t\terrorDecodersForSCTPChunkType[i] = errorDecoderForSCTPChunkType(i)\n\t\tSCTPChunkTypeMetadata[i] = EnumMetadata{\n\t\t\tDecodeWith: &errorDecodersForSCTPChunkType[i],\n\t\t\tName:       \"UnknownSCTPChunkType\",\n\t\t}\n\t}\n}\n\n// Decoder calls PPPoECodeMetadata.DecodeWith's decoder.\nfunc (a PPPoECode) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn PPPoECodeMetadata[a].DecodeWith.Decode(data, p)\n}\n\n// String returns PPPoECodeMetadata.Name.\nfunc (a PPPoECode) String() string {\n\treturn PPPoECodeMetadata[a].Name\n}\n\n// LayerType returns PPPoECodeMetadata.LayerType.\nfunc (a PPPoECode) LayerType() gopacket.LayerType {\n\treturn PPPoECodeMetadata[a].LayerType\n}\n\ntype errorDecoderForPPPoECode int\n\nfunc (a *errorDecoderForPPPoECode) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn a\n}\nfunc (a *errorDecoderForPPPoECode) Error() string {\n\treturn fmt.Sprintf(\"Unable to decode PPPoECode %d\", int(*a))\n}\n\nvar errorDecodersForPPPoECode [256]errorDecoderForPPPoECode\nvar PPPoECodeMetadata [256]EnumMetadata\n\nfunc initUnknownTypesForPPPoECode() {\n\tfor i := 0; i < 256; i++ {\n\t\terrorDecodersForPPPoECode[i] = errorDecoderForPPPoECode(i)\n\t\tPPPoECodeMetadata[i] = EnumMetadata{\n\t\t\tDecodeWith: &errorDecodersForPPPoECode[i],\n\t\t\tName:       \"UnknownPPPoECode\",\n\t\t}\n\t}\n}\n\n// Decoder calls FDDIFrameControlMetadata.DecodeWith's decoder.\nfunc (a FDDIFrameControl) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn FDDIFrameControlMetadata[a].DecodeWith.Decode(data, p)\n}\n\n// String returns FDDIFrameControlMetadata.Name.\nfunc (a FDDIFrameControl) String() string {\n\treturn FDDIFrameControlMetadata[a].Name\n}\n\n// LayerType returns FDDIFrameControlMetadata.LayerType.\nfunc (a FDDIFrameControl) LayerType() gopacket.LayerType {\n\treturn FDDIFrameControlMetadata[a].LayerType\n}\n\ntype errorDecoderForFDDIFrameControl int\n\nfunc (a *errorDecoderForFDDIFrameControl) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn a\n}\nfunc (a *errorDecoderForFDDIFrameControl) Error() string {\n\treturn fmt.Sprintf(\"Unable to decode FDDIFrameControl %d\", int(*a))\n}\n\nvar errorDecodersForFDDIFrameControl [256]errorDecoderForFDDIFrameControl\nvar FDDIFrameControlMetadata [256]EnumMetadata\n\nfunc initUnknownTypesForFDDIFrameControl() {\n\tfor i := 0; i < 256; i++ {\n\t\terrorDecodersForFDDIFrameControl[i] = errorDecoderForFDDIFrameControl(i)\n\t\tFDDIFrameControlMetadata[i] = EnumMetadata{\n\t\t\tDecodeWith: &errorDecodersForFDDIFrameControl[i],\n\t\t\tName:       \"UnknownFDDIFrameControl\",\n\t\t}\n\t}\n}\n\n// Decoder calls EAPOLTypeMetadata.DecodeWith's decoder.\nfunc (a EAPOLType) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn EAPOLTypeMetadata[a].DecodeWith.Decode(data, p)\n}\n\n// String returns EAPOLTypeMetadata.Name.\nfunc (a EAPOLType) String() string {\n\treturn EAPOLTypeMetadata[a].Name\n}\n\n// LayerType returns EAPOLTypeMetadata.LayerType.\nfunc (a EAPOLType) LayerType() gopacket.LayerType {\n\treturn EAPOLTypeMetadata[a].LayerType\n}\n\ntype errorDecoderForEAPOLType int\n\nfunc (a *errorDecoderForEAPOLType) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn a\n}\nfunc (a *errorDecoderForEAPOLType) Error() string {\n\treturn fmt.Sprintf(\"Unable to decode EAPOLType %d\", int(*a))\n}\n\nvar errorDecodersForEAPOLType [256]errorDecoderForEAPOLType\nvar EAPOLTypeMetadata [256]EnumMetadata\n\nfunc initUnknownTypesForEAPOLType() {\n\tfor i := 0; i < 256; i++ {\n\t\terrorDecodersForEAPOLType[i] = errorDecoderForEAPOLType(i)\n\t\tEAPOLTypeMetadata[i] = EnumMetadata{\n\t\t\tDecodeWith: &errorDecodersForEAPOLType[i],\n\t\t\tName:       \"UnknownEAPOLType\",\n\t\t}\n\t}\n}\n\n// Decoder calls ProtocolFamilyMetadata.DecodeWith's decoder.\nfunc (a ProtocolFamily) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn ProtocolFamilyMetadata[a].DecodeWith.Decode(data, p)\n}\n\n// String returns ProtocolFamilyMetadata.Name.\nfunc (a ProtocolFamily) String() string {\n\treturn ProtocolFamilyMetadata[a].Name\n}\n\n// LayerType returns ProtocolFamilyMetadata.LayerType.\nfunc (a ProtocolFamily) LayerType() gopacket.LayerType {\n\treturn ProtocolFamilyMetadata[a].LayerType\n}\n\ntype errorDecoderForProtocolFamily int\n\nfunc (a *errorDecoderForProtocolFamily) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn a\n}\nfunc (a *errorDecoderForProtocolFamily) Error() string {\n\treturn fmt.Sprintf(\"Unable to decode ProtocolFamily %d\", int(*a))\n}\n\nvar errorDecodersForProtocolFamily [256]errorDecoderForProtocolFamily\nvar ProtocolFamilyMetadata [256]EnumMetadata\n\nfunc initUnknownTypesForProtocolFamily() {\n\tfor i := 0; i < 256; i++ {\n\t\terrorDecodersForProtocolFamily[i] = errorDecoderForProtocolFamily(i)\n\t\tProtocolFamilyMetadata[i] = EnumMetadata{\n\t\t\tDecodeWith: &errorDecodersForProtocolFamily[i],\n\t\t\tName:       \"UnknownProtocolFamily\",\n\t\t}\n\t}\n}\n\n// Decoder calls Dot11TypeMetadata.DecodeWith's decoder.\nfunc (a Dot11Type) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn Dot11TypeMetadata[a].DecodeWith.Decode(data, p)\n}\n\n// String returns Dot11TypeMetadata.Name.\nfunc (a Dot11Type) String() string {\n\treturn Dot11TypeMetadata[a].Name\n}\n\n// LayerType returns Dot11TypeMetadata.LayerType.\nfunc (a Dot11Type) LayerType() gopacket.LayerType {\n\treturn Dot11TypeMetadata[a].LayerType\n}\n\ntype errorDecoderForDot11Type int\n\nfunc (a *errorDecoderForDot11Type) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn a\n}\nfunc (a *errorDecoderForDot11Type) Error() string {\n\treturn fmt.Sprintf(\"Unable to decode Dot11Type %d\", int(*a))\n}\n\nvar errorDecodersForDot11Type [256]errorDecoderForDot11Type\nvar Dot11TypeMetadata [256]EnumMetadata\n\nfunc initUnknownTypesForDot11Type() {\n\tfor i := 0; i < 256; i++ {\n\t\terrorDecodersForDot11Type[i] = errorDecoderForDot11Type(i)\n\t\tDot11TypeMetadata[i] = EnumMetadata{\n\t\t\tDecodeWith: &errorDecodersForDot11Type[i],\n\t\t\tName:       \"UnknownDot11Type\",\n\t\t}\n\t}\n}\n\n// Decoder calls USBTransportTypeMetadata.DecodeWith's decoder.\nfunc (a USBTransportType) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn USBTransportTypeMetadata[a].DecodeWith.Decode(data, p)\n}\n\n// String returns USBTransportTypeMetadata.Name.\nfunc (a USBTransportType) String() string {\n\treturn USBTransportTypeMetadata[a].Name\n}\n\n// LayerType returns USBTransportTypeMetadata.LayerType.\nfunc (a USBTransportType) LayerType() gopacket.LayerType {\n\treturn USBTransportTypeMetadata[a].LayerType\n}\n\ntype errorDecoderForUSBTransportType int\n\nfunc (a *errorDecoderForUSBTransportType) Decode(data []byte, p gopacket.PacketBuilder) error {\n\treturn a\n}\nfunc (a *errorDecoderForUSBTransportType) Error() string {\n\treturn fmt.Sprintf(\"Unable to decode USBTransportType %d\", int(*a))\n}\n\nvar errorDecodersForUSBTransportType [256]errorDecoderForUSBTransportType\nvar USBTransportTypeMetadata [256]EnumMetadata\n\nfunc initUnknownTypesForUSBTransportType() {\n\tfor i := 0; i < 256; i++ {\n\t\terrorDecodersForUSBTransportType[i] = errorDecoderForUSBTransportType(i)\n\t\tUSBTransportTypeMetadata[i] = EnumMetadata{\n\t\t\tDecodeWith: &errorDecodersForUSBTransportType[i],\n\t\t\tName:       \"UnknownUSBTransportType\",\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/erspan2.go",
    "content": "// Copyright 2018 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\n\t\"github.com/google/gopacket\"\n)\n\nconst (\n\t//ERSPANIIVersionObsolete - The obsolete value for the version field\n\tERSPANIIVersionObsolete = 0x0\n\t// ERSPANIIVersion - The current value for the version field\n\tERSPANIIVersion = 0x1\n)\n\n// ERSPANII contains all of the fields found in an ERSPAN Type II header\n// https://tools.ietf.org/html/draft-foschiano-erspan-03\ntype ERSPANII struct {\n\tBaseLayer\n\tIsTruncated                         bool\n\tVersion, CoS, TrunkEncap            uint8\n\tVLANIdentifier, SessionID, Reserved uint16\n\tIndex                               uint32\n}\n\nfunc (erspan2 *ERSPANII) LayerType() gopacket.LayerType { return LayerTypeERSPANII }\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (erspan2 *ERSPANII) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\terspan2Length := 8\n\terspan2.Version = data[0] & 0xF0 >> 4\n\terspan2.VLANIdentifier = binary.BigEndian.Uint16(data[:2]) & 0x0FFF\n\terspan2.CoS = data[2] & 0xE0 >> 5\n\terspan2.TrunkEncap = data[2] & 0x18 >> 3\n\terspan2.IsTruncated = data[2]&0x4>>2 != 0\n\terspan2.SessionID = binary.BigEndian.Uint16(data[2:4]) & 0x03FF\n\terspan2.Reserved = binary.BigEndian.Uint16(data[4:6]) & 0xFFF0 >> 4\n\terspan2.Index = binary.BigEndian.Uint32(data[4:8]) & 0x000FFFFF\n\terspan2.Contents = data[:erspan2Length]\n\terspan2.Payload = data[erspan2Length:]\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (erspan2 *ERSPANII) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbytes, err := b.PrependBytes(8)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ttwoByteInt := uint16(erspan2.Version&0xF)<<12 | erspan2.VLANIdentifier&0x0FFF\n\tbinary.BigEndian.PutUint16(bytes, twoByteInt)\n\n\ttwoByteInt = uint16(erspan2.CoS&0x7)<<13 | uint16(erspan2.TrunkEncap&0x3)<<11 | erspan2.SessionID&0x03FF\n\tif erspan2.IsTruncated {\n\t\ttwoByteInt |= 0x400\n\t}\n\tbinary.BigEndian.PutUint16(bytes[2:], twoByteInt)\n\n\tfourByteInt := uint32(erspan2.Reserved&0x0FFF)<<20 | erspan2.Index&0x000FFFFF\n\tbinary.BigEndian.PutUint32(bytes[4:], fourByteInt)\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (erspan2 *ERSPANII) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeERSPANII\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (erspan2 *ERSPANII) NextLayerType() gopacket.LayerType {\n\treturn LayerTypeEthernet\n}\n\nfunc decodeERSPANII(data []byte, p gopacket.PacketBuilder) error {\n\terspan2 := &ERSPANII{}\n\treturn decodingLayerDecoder(erspan2, data, p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/etherip.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"github.com/google/gopacket\"\n)\n\n// EtherIP is the struct for storing RFC 3378 EtherIP packet headers.\ntype EtherIP struct {\n\tBaseLayer\n\tVersion  uint8\n\tReserved uint16\n}\n\n// LayerType returns gopacket.LayerTypeEtherIP.\nfunc (e *EtherIP) LayerType() gopacket.LayerType { return LayerTypeEtherIP }\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (e *EtherIP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\te.Version = data[0] >> 4\n\te.Reserved = binary.BigEndian.Uint16(data[:2]) & 0x0fff\n\te.BaseLayer = BaseLayer{data[:2], data[2:]}\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (e *EtherIP) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeEtherIP\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (e *EtherIP) NextLayerType() gopacket.LayerType {\n\treturn LayerTypeEthernet\n}\n\nfunc decodeEtherIP(data []byte, p gopacket.PacketBuilder) error {\n\te := &EtherIP{}\n\treturn decodingLayerDecoder(e, data, p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/ethernet.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n// Copyright 2009-2011 Andreas Krennmair. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"github.com/google/gopacket\"\n\t\"net\"\n)\n\n// EthernetBroadcast is the broadcast MAC address used by Ethernet.\nvar EthernetBroadcast = net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}\n\n// Ethernet is the layer for Ethernet frame headers.\ntype Ethernet struct {\n\tBaseLayer\n\tSrcMAC, DstMAC net.HardwareAddr\n\tEthernetType   EthernetType\n\t// Length is only set if a length field exists within this header.  Ethernet\n\t// headers follow two different standards, one that uses an EthernetType, the\n\t// other which defines a length the follows with a LLC header (802.3).  If the\n\t// former is the case, we set EthernetType and Length stays 0.  In the latter\n\t// case, we set Length and EthernetType = EthernetTypeLLC.\n\tLength uint16\n}\n\n// LayerType returns LayerTypeEthernet\nfunc (e *Ethernet) LayerType() gopacket.LayerType { return LayerTypeEthernet }\n\nfunc (e *Ethernet) LinkFlow() gopacket.Flow {\n\treturn gopacket.NewFlow(EndpointMAC, e.SrcMAC, e.DstMAC)\n}\n\nfunc (eth *Ethernet) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 14 {\n\t\treturn errors.New(\"Ethernet packet too small\")\n\t}\n\teth.DstMAC = net.HardwareAddr(data[0:6])\n\teth.SrcMAC = net.HardwareAddr(data[6:12])\n\teth.EthernetType = EthernetType(binary.BigEndian.Uint16(data[12:14]))\n\teth.BaseLayer = BaseLayer{data[:14], data[14:]}\n\teth.Length = 0\n\tif eth.EthernetType < 0x0600 {\n\t\teth.Length = uint16(eth.EthernetType)\n\t\teth.EthernetType = EthernetTypeLLC\n\t\tif cmp := len(eth.Payload) - int(eth.Length); cmp < 0 {\n\t\t\tdf.SetTruncated()\n\t\t} else if cmp > 0 {\n\t\t\t// Strip off bytes at the end, since we have too many bytes\n\t\t\teth.Payload = eth.Payload[:len(eth.Payload)-cmp]\n\t\t}\n\t\t//\tfmt.Println(eth)\n\t}\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (eth *Ethernet) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tif len(eth.DstMAC) != 6 {\n\t\treturn fmt.Errorf(\"invalid dst MAC: %v\", eth.DstMAC)\n\t}\n\tif len(eth.SrcMAC) != 6 {\n\t\treturn fmt.Errorf(\"invalid src MAC: %v\", eth.SrcMAC)\n\t}\n\tpayload := b.Bytes()\n\tbytes, err := b.PrependBytes(14)\n\tif err != nil {\n\t\treturn err\n\t}\n\tcopy(bytes, eth.DstMAC)\n\tcopy(bytes[6:], eth.SrcMAC)\n\tif eth.Length != 0 || eth.EthernetType == EthernetTypeLLC {\n\t\tif opts.FixLengths {\n\t\t\teth.Length = uint16(len(payload))\n\t\t}\n\t\tif eth.EthernetType != EthernetTypeLLC {\n\t\t\treturn fmt.Errorf(\"ethernet type %v not compatible with length value %v\", eth.EthernetType, eth.Length)\n\t\t} else if eth.Length > 0x0600 {\n\t\t\treturn fmt.Errorf(\"invalid ethernet length %v\", eth.Length)\n\t\t}\n\t\tbinary.BigEndian.PutUint16(bytes[12:], eth.Length)\n\t} else {\n\t\tbinary.BigEndian.PutUint16(bytes[12:], uint16(eth.EthernetType))\n\t}\n\tlength := len(b.Bytes())\n\tif length < 60 {\n\t\t// Pad out to 60 bytes.\n\t\tpadding, err := b.AppendBytes(60 - length)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcopy(padding, lotsOfZeros[:])\n\t}\n\treturn nil\n}\n\nfunc (eth *Ethernet) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeEthernet\n}\n\nfunc (eth *Ethernet) NextLayerType() gopacket.LayerType {\n\treturn eth.EthernetType.LayerType()\n}\n\nfunc decodeEthernet(data []byte, p gopacket.PacketBuilder) error {\n\teth := &Ethernet{}\n\terr := eth.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\tp.AddLayer(eth)\n\tp.SetLinkLayer(eth)\n\treturn p.NextDecoder(eth.EthernetType)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/fddi.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"github.com/google/gopacket\"\n\t\"net\"\n)\n\n// FDDI contains the header for FDDI frames.\ntype FDDI struct {\n\tBaseLayer\n\tFrameControl   FDDIFrameControl\n\tPriority       uint8\n\tSrcMAC, DstMAC net.HardwareAddr\n}\n\n// LayerType returns LayerTypeFDDI.\nfunc (f *FDDI) LayerType() gopacket.LayerType { return LayerTypeFDDI }\n\n// LinkFlow returns a new flow of type EndpointMAC.\nfunc (f *FDDI) LinkFlow() gopacket.Flow {\n\treturn gopacket.NewFlow(EndpointMAC, f.SrcMAC, f.DstMAC)\n}\n\nfunc decodeFDDI(data []byte, p gopacket.PacketBuilder) error {\n\tf := &FDDI{\n\t\tFrameControl: FDDIFrameControl(data[0] & 0xF8),\n\t\tPriority:     data[0] & 0x07,\n\t\tSrcMAC:       net.HardwareAddr(data[1:7]),\n\t\tDstMAC:       net.HardwareAddr(data[7:13]),\n\t\tBaseLayer:    BaseLayer{data[:13], data[13:]},\n\t}\n\tp.SetLinkLayer(f)\n\tp.AddLayer(f)\n\treturn p.NextDecoder(f.FrameControl)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/fuzz_layer.go",
    "content": "// Copyright 2019 The GoPacket Authors. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license that can be found\n// in the LICENSE file in the root of the source tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// FuzzLayer is a fuzz target for the layers package of gopacket\n// A fuzz target is a function processing a binary blob (byte slice)\n// The process here is to interpret this data as a packet, and print the layers contents.\n// The decoding options and the starting layer are encoded in the first bytes.\n// The function returns 1 if this is a valid packet (no error layer)\nfunc FuzzLayer(data []byte) int {\n\tif len(data) < 3 {\n\t\treturn 0\n\t}\n\t// use the first two bytes to choose the top level layer\n\tstartLayer := binary.BigEndian.Uint16(data[:2])\n\tvar fuzzOpts = gopacket.DecodeOptions{\n\t\tLazy:                     data[2]&0x1 != 0,\n\t\tNoCopy:                   data[2]&0x2 != 0,\n\t\tSkipDecodeRecovery:       data[2]&0x4 != 0,\n\t\tDecodeStreamsAsDatagrams: data[2]&0x8 != 0,\n\t}\n\tp := gopacket.NewPacket(data[3:], gopacket.LayerType(startLayer), fuzzOpts)\n\tfor _, l := range p.Layers() {\n\t\tgopacket.LayerString(l)\n\t}\n\tif p.ErrorLayer() != nil {\n\t\treturn 0\n\t}\n\treturn 1\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/gen_linted.sh",
    "content": "#!/bin/bash\n\nfor i in *.go; do golint $i | grep -q . || echo $i; done > .linted\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/geneve.go",
    "content": "// Copyright 2016 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// Geneve is specifed here https://tools.ietf.org/html/draft-ietf-nvo3-geneve-03\n// Geneve Header:\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |Ver|  Opt Len  |O|C|    Rsvd.  |          Protocol Type        |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |        Virtual Network Identifier (VNI)       |    Reserved   |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |                    Variable Length Options                    |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\ntype Geneve struct {\n\tBaseLayer\n\tVersion        uint8        // 2 bits\n\tOptionsLength  uint8        // 6 bits\n\tOAMPacket      bool         // 1 bits\n\tCriticalOption bool         // 1 bits\n\tProtocol       EthernetType // 16 bits\n\tVNI            uint32       // 24bits\n\tOptions        []*GeneveOption\n}\n\n// Geneve Tunnel Options\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |          Option Class         |      Type     |R|R|R| Length  |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |                      Variable Option Data                     |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\ntype GeneveOption struct {\n\tClass  uint16 // 16 bits\n\tType   uint8  // 8 bits\n\tFlags  uint8  // 3 bits\n\tLength uint8  // 5 bits\n\tData   []byte\n}\n\n// LayerType returns LayerTypeGeneve\nfunc (gn *Geneve) LayerType() gopacket.LayerType { return LayerTypeGeneve }\n\nfunc decodeGeneveOption(data []byte, gn *Geneve, df gopacket.DecodeFeedback) (*GeneveOption, uint8, error) {\n\tif len(data) < 3 {\n\t\tdf.SetTruncated()\n\t\treturn nil, 0, errors.New(\"geneve option too small\")\n\t}\n\topt := &GeneveOption{}\n\n\topt.Class = binary.BigEndian.Uint16(data[0:2])\n\topt.Type = data[2]\n\topt.Flags = data[3] >> 4\n\topt.Length = (data[3]&0xf)*4 + 4\n\n\tif len(data) < int(opt.Length) {\n\t\tdf.SetTruncated()\n\t\treturn nil, 0, errors.New(\"geneve option too small\")\n\t}\n\topt.Data = make([]byte, opt.Length-4)\n\tcopy(opt.Data, data[4:opt.Length])\n\n\treturn opt, opt.Length, nil\n}\n\nfunc (gn *Geneve) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 7 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"geneve packet too short\")\n\t}\n\n\tgn.Version = data[0] >> 7\n\tgn.OptionsLength = (data[0] & 0x3f) * 4\n\n\tgn.OAMPacket = data[1]&0x80 > 0\n\tgn.CriticalOption = data[1]&0x40 > 0\n\tgn.Protocol = EthernetType(binary.BigEndian.Uint16(data[2:4]))\n\n\tvar buf [4]byte\n\tcopy(buf[1:], data[4:7])\n\tgn.VNI = binary.BigEndian.Uint32(buf[:])\n\n\toffset, length := uint8(8), int32(gn.OptionsLength)\n\tif len(data) < int(length+7) {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"geneve packet too short\")\n\t}\n\n\tfor length > 0 {\n\t\topt, len, err := decodeGeneveOption(data[offset:], gn, df)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tgn.Options = append(gn.Options, opt)\n\n\t\tlength -= int32(len)\n\t\toffset += len\n\t}\n\n\tgn.BaseLayer = BaseLayer{data[:offset], data[offset:]}\n\n\treturn nil\n}\n\nfunc (gn *Geneve) NextLayerType() gopacket.LayerType {\n\treturn gn.Protocol.LayerType()\n}\n\nfunc decodeGeneve(data []byte, p gopacket.PacketBuilder) error {\n\tgn := &Geneve{}\n\treturn decodingLayerDecoder(gn, data, p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/gre.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// GRE is a Generic Routing Encapsulation header.\ntype GRE struct {\n\tBaseLayer\n\tChecksumPresent, RoutingPresent, KeyPresent, SeqPresent, StrictSourceRoute, AckPresent bool\n\tRecursionControl, Flags, Version                                                       uint8\n\tProtocol                                                                               EthernetType\n\tChecksum, Offset                                                                       uint16\n\tKey, Seq, Ack                                                                          uint32\n\t*GRERouting\n}\n\n// GRERouting is GRE routing information, present if the RoutingPresent flag is\n// set.\ntype GRERouting struct {\n\tAddressFamily        uint16\n\tSREOffset, SRELength uint8\n\tRoutingInformation   []byte\n\tNext                 *GRERouting\n}\n\n// LayerType returns gopacket.LayerTypeGRE.\nfunc (g *GRE) LayerType() gopacket.LayerType { return LayerTypeGRE }\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (g *GRE) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tg.ChecksumPresent = data[0]&0x80 != 0\n\tg.RoutingPresent = data[0]&0x40 != 0\n\tg.KeyPresent = data[0]&0x20 != 0\n\tg.SeqPresent = data[0]&0x10 != 0\n\tg.StrictSourceRoute = data[0]&0x08 != 0\n\tg.AckPresent = data[1]&0x80 != 0\n\tg.RecursionControl = data[0] & 0x7\n\tg.Flags = data[1] >> 3\n\tg.Version = data[1] & 0x7\n\tg.Protocol = EthernetType(binary.BigEndian.Uint16(data[2:4]))\n\toffset := 4\n\tif g.ChecksumPresent || g.RoutingPresent {\n\t\tg.Checksum = binary.BigEndian.Uint16(data[offset : offset+2])\n\t\tg.Offset = binary.BigEndian.Uint16(data[offset+2 : offset+4])\n\t\toffset += 4\n\t}\n\tif g.KeyPresent {\n\t\tg.Key = binary.BigEndian.Uint32(data[offset : offset+4])\n\t\toffset += 4\n\t}\n\tif g.SeqPresent {\n\t\tg.Seq = binary.BigEndian.Uint32(data[offset : offset+4])\n\t\toffset += 4\n\t}\n\tif g.RoutingPresent {\n\t\ttail := &g.GRERouting\n\t\tfor {\n\t\t\tsre := &GRERouting{\n\t\t\t\tAddressFamily: binary.BigEndian.Uint16(data[offset : offset+2]),\n\t\t\t\tSREOffset:     data[offset+2],\n\t\t\t\tSRELength:     data[offset+3],\n\t\t\t}\n\t\t\tsre.RoutingInformation = data[offset+4 : offset+4+int(sre.SRELength)]\n\t\t\toffset += 4 + int(sre.SRELength)\n\t\t\tif sre.AddressFamily == 0 && sre.SRELength == 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t(*tail) = sre\n\t\t\ttail = &sre.Next\n\t\t}\n\t}\n\tif g.AckPresent {\n\t\tg.Ack = binary.BigEndian.Uint32(data[offset : offset+4])\n\t\toffset += 4\n\t}\n\tg.BaseLayer = BaseLayer{data[:offset], data[offset:]}\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the SerializationBuffer,\n// implementing gopacket.SerializableLayer. See the docs for gopacket.SerializableLayer for more info.\nfunc (g *GRE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tsize := 4\n\tif g.ChecksumPresent || g.RoutingPresent {\n\t\tsize += 4\n\t}\n\tif g.KeyPresent {\n\t\tsize += 4\n\t}\n\tif g.SeqPresent {\n\t\tsize += 4\n\t}\n\tif g.RoutingPresent {\n\t\tr := g.GRERouting\n\t\tfor r != nil {\n\t\t\tsize += 4 + int(r.SRELength)\n\t\t\tr = r.Next\n\t\t}\n\t\tsize += 4\n\t}\n\tif g.AckPresent {\n\t\tsize += 4\n\t}\n\tbuf, err := b.PrependBytes(size)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// Reset any potentially dirty memory in the first 2 bytes, as these use OR to set flags.\n\tbuf[0] = 0\n\tbuf[1] = 0\n\tif g.ChecksumPresent {\n\t\tbuf[0] |= 0x80\n\t}\n\tif g.RoutingPresent {\n\t\tbuf[0] |= 0x40\n\t}\n\tif g.KeyPresent {\n\t\tbuf[0] |= 0x20\n\t}\n\tif g.SeqPresent {\n\t\tbuf[0] |= 0x10\n\t}\n\tif g.StrictSourceRoute {\n\t\tbuf[0] |= 0x08\n\t}\n\tif g.AckPresent {\n\t\tbuf[1] |= 0x80\n\t}\n\tbuf[0] |= g.RecursionControl\n\tbuf[1] |= g.Flags << 3\n\tbuf[1] |= g.Version\n\tbinary.BigEndian.PutUint16(buf[2:4], uint16(g.Protocol))\n\toffset := 4\n\tif g.ChecksumPresent || g.RoutingPresent {\n\t\t// Don't write the checksum value yet, as we may need to compute it,\n\t\t// which requires the entire header be complete.\n\t\t// Instead we zeroize the memory in case it is dirty.\n\t\tbuf[offset] = 0\n\t\tbuf[offset+1] = 0\n\t\tbinary.BigEndian.PutUint16(buf[offset+2:offset+4], g.Offset)\n\t\toffset += 4\n\t}\n\tif g.KeyPresent {\n\t\tbinary.BigEndian.PutUint32(buf[offset:offset+4], g.Key)\n\t\toffset += 4\n\t}\n\tif g.SeqPresent {\n\t\tbinary.BigEndian.PutUint32(buf[offset:offset+4], g.Seq)\n\t\toffset += 4\n\t}\n\tif g.RoutingPresent {\n\t\tsre := g.GRERouting\n\t\tfor sre != nil {\n\t\t\tbinary.BigEndian.PutUint16(buf[offset:offset+2], sre.AddressFamily)\n\t\t\tbuf[offset+2] = sre.SREOffset\n\t\t\tbuf[offset+3] = sre.SRELength\n\t\t\tcopy(buf[offset+4:offset+4+int(sre.SRELength)], sre.RoutingInformation)\n\t\t\toffset += 4 + int(sre.SRELength)\n\t\t\tsre = sre.Next\n\t\t}\n\t\t// Terminate routing field with a \"NULL\" SRE.\n\t\tbinary.BigEndian.PutUint32(buf[offset:offset+4], 0)\n\t}\n\tif g.AckPresent {\n\t\tbinary.BigEndian.PutUint32(buf[offset:offset+4], g.Ack)\n\t\toffset += 4\n\t}\n\tif g.ChecksumPresent {\n\t\tif opts.ComputeChecksums {\n\t\t\tg.Checksum = tcpipChecksum(b.Bytes(), 0)\n\t\t}\n\n\t\tbinary.BigEndian.PutUint16(buf[4:6], g.Checksum)\n\t}\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (g *GRE) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeGRE\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (g *GRE) NextLayerType() gopacket.LayerType {\n\treturn g.Protocol.LayerType()\n}\n\nfunc decodeGRE(data []byte, p gopacket.PacketBuilder) error {\n\tg := &GRE{}\n\treturn decodingLayerDecoder(g, data, p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/gtp.go",
    "content": "// Copyright 2017 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n//\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"github.com/google/gopacket\"\n)\n\nconst gtpMinimumSizeInBytes int = 8\n\n// GTPExtensionHeader is used to carry extra data and enable future extensions of the GTP  without the need to use another version number.\ntype GTPExtensionHeader struct {\n\tType    uint8\n\tContent []byte\n}\n\n// GTPv1U protocol is used to exchange user data over GTP tunnels across the Sx interfaces.\n// Defined in https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1595\ntype GTPv1U struct {\n\tBaseLayer\n\tVersion             uint8\n\tProtocolType        uint8\n\tReserved            uint8\n\tExtensionHeaderFlag bool\n\tSequenceNumberFlag  bool\n\tNPDUFlag            bool\n\tMessageType         uint8\n\tMessageLength       uint16\n\tTEID                uint32\n\tSequenceNumber      uint16\n\tNPDU                uint8\n\tGTPExtensionHeaders []GTPExtensionHeader\n}\n\n// LayerType returns LayerTypeGTPV1U\nfunc (g *GTPv1U) LayerType() gopacket.LayerType { return LayerTypeGTPv1U }\n\n// DecodeFromBytes analyses a byte slice and attempts to decode it as a GTPv1U packet\nfunc (g *GTPv1U) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\thLen := gtpMinimumSizeInBytes\n\tdLen := len(data)\n\tif dLen < hLen {\n\t\treturn fmt.Errorf(\"GTP packet too small: %d bytes\", dLen)\n\t}\n\tg.Version = (data[0] >> 5) & 0x07\n\tg.ProtocolType = (data[0] >> 4) & 0x01\n\tg.Reserved = (data[0] >> 3) & 0x01\n\tg.SequenceNumberFlag = ((data[0] >> 1) & 0x01) == 1\n\tg.NPDUFlag = (data[0] & 0x01) == 1\n\tg.ExtensionHeaderFlag = ((data[0] >> 2) & 0x01) == 1\n\tg.MessageType = data[1]\n\tg.MessageLength = binary.BigEndian.Uint16(data[2:4])\n\tpLen := 8 + g.MessageLength\n\tif uint16(dLen) < pLen {\n\t\treturn fmt.Errorf(\"GTP packet too small: %d bytes\", dLen)\n\t}\n\t//  Field used to multiplex different connections in the same GTP tunnel.\n\tg.TEID = binary.BigEndian.Uint32(data[4:8])\n\tcIndex := uint16(hLen)\n\tif g.SequenceNumberFlag || g.NPDUFlag || g.ExtensionHeaderFlag {\n\t\thLen += 4\n\t\tcIndex += 4\n\t\tif dLen < hLen {\n\t\t\treturn fmt.Errorf(\"GTP packet too small: %d bytes\", dLen)\n\t\t}\n\t\tif g.SequenceNumberFlag {\n\t\t\tg.SequenceNumber = binary.BigEndian.Uint16(data[8:10])\n\t\t}\n\t\tif g.NPDUFlag {\n\t\t\tg.NPDU = data[10]\n\t\t}\n\t\tif g.ExtensionHeaderFlag {\n\t\t\textensionFlag := true\n\t\t\tfor extensionFlag {\n\t\t\t\textensionType := uint8(data[cIndex-1])\n\t\t\t\textensionLength := uint(data[cIndex])\n\t\t\t\tif extensionLength == 0 {\n\t\t\t\t\treturn fmt.Errorf(\"GTP packet with invalid extension header\")\n\t\t\t\t}\n\t\t\t\t// extensionLength is in 4-octet units\n\t\t\t\tlIndex := cIndex + (uint16(extensionLength) * 4)\n\t\t\t\tif uint16(dLen) < lIndex {\n\t\t\t\t\tfmt.Println(dLen, lIndex)\n\t\t\t\t\treturn fmt.Errorf(\"GTP packet with small extension header: %d bytes\", dLen)\n\t\t\t\t}\n\t\t\t\tcontent := data[cIndex+1 : lIndex-1]\n\t\t\t\teh := GTPExtensionHeader{Type: extensionType, Content: content}\n\t\t\t\tg.GTPExtensionHeaders = append(g.GTPExtensionHeaders, eh)\n\t\t\t\tcIndex = lIndex\n\t\t\t\t// Check if coming bytes are from an extension header\n\t\t\t\textensionFlag = data[cIndex-1] != 0\n\n\t\t\t}\n\t\t}\n\t}\n\tg.BaseLayer = BaseLayer{Contents: data[:cIndex], Payload: data[cIndex:]}\n\treturn nil\n\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (g *GTPv1U) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tdata, err := b.PrependBytes(gtpMinimumSizeInBytes)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdata[0] |= (g.Version << 5)\n\tdata[0] |= (1 << 4)\n\tif len(g.GTPExtensionHeaders) > 0 {\n\t\tdata[0] |= 0x04\n\t\tg.ExtensionHeaderFlag = true\n\t}\n\tif g.SequenceNumberFlag {\n\t\tdata[0] |= 0x02\n\t}\n\tif g.NPDUFlag {\n\t\tdata[0] |= 0x01\n\t}\n\tdata[1] = g.MessageType\n\tbinary.BigEndian.PutUint16(data[2:4], g.MessageLength)\n\tbinary.BigEndian.PutUint32(data[4:8], g.TEID)\n\tif g.ExtensionHeaderFlag || g.SequenceNumberFlag || g.NPDUFlag {\n\t\tdata, err := b.AppendBytes(4)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tbinary.BigEndian.PutUint16(data[:2], g.SequenceNumber)\n\t\tdata[2] = g.NPDU\n\t\tfor _, eh := range g.GTPExtensionHeaders {\n\t\t\tdata[len(data)-1] = eh.Type\n\t\t\tlContent := len(eh.Content)\n\t\t\t// extensionLength is in 4-octet units\n\t\t\textensionLength := (lContent + 2) / 4\n\t\t\t// Get two extra byte for the next extension header type and length\n\t\t\tdata, err = b.AppendBytes(lContent + 2)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tdata[0] = byte(extensionLength)\n\t\t\tcopy(data[1:lContent+1], eh.Content)\n\t\t}\n\t}\n\treturn nil\n\n}\n\n// CanDecode returns a set of layers that GTP objects can decode.\nfunc (g *GTPv1U) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeGTPv1U\n}\n\n// NextLayerType specifies the next layer that GoPacket should attempt to\nfunc (g *GTPv1U) NextLayerType() gopacket.LayerType {\n\tif len(g.LayerPayload()) == 0 {\n\t\treturn gopacket.LayerTypeZero\n\t}\n\tversion := uint8(g.LayerPayload()[0]) >> 4\n\tif version == 4 {\n\t\treturn LayerTypeIPv4\n\t} else if version == 6 {\n\t\treturn LayerTypeIPv6\n\t} else {\n\t\treturn LayerTypePPP\n\t}\n}\n\nfunc decodeGTPv1u(data []byte, p gopacket.PacketBuilder) error {\n\tgtp := &GTPv1U{}\n\terr := gtp.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\tp.AddLayer(gtp)\n\treturn p.NextDecoder(gtp.NextLayerType())\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/iana_ports.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n\npackage layers\n\n// Created by gen.go, don't edit manually\n// Generated at 2017-10-23 09:57:28.214859163 -0600 MDT m=+1.011679290\n// Fetched from \"http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml\"\n\n// TCPPortNames contains the port names for all TCP ports.\nvar TCPPortNames = tcpPortNames\n\n// UDPPortNames contains the port names for all UDP ports.\nvar UDPPortNames = udpPortNames\n\n// SCTPPortNames contains the port names for all SCTP ports.\nvar SCTPPortNames = sctpPortNames\n\nvar tcpPortNames = map[TCPPort]string{\n\t1:     \"tcpmux\",\n\t2:     \"compressnet\",\n\t3:     \"compressnet\",\n\t5:     \"rje\",\n\t7:     \"echo\",\n\t9:     \"discard\",\n\t11:    \"systat\",\n\t13:    \"daytime\",\n\t17:    \"qotd\",\n\t18:    \"msp\",\n\t19:    \"chargen\",\n\t20:    \"ftp-data\",\n\t21:    \"ftp\",\n\t22:    \"ssh\",\n\t23:    \"telnet\",\n\t25:    \"smtp\",\n\t27:    \"nsw-fe\",\n\t29:    \"msg-icp\",\n\t31:    \"msg-auth\",\n\t33:    \"dsp\",\n\t37:    \"time\",\n\t38:    \"rap\",\n\t39:    \"rlp\",\n\t41:    \"graphics\",\n\t42:    \"name\",\n\t43:    \"nicname\",\n\t44:    \"mpm-flags\",\n\t45:    \"mpm\",\n\t46:    \"mpm-snd\",\n\t48:    \"auditd\",\n\t49:    \"tacacs\",\n\t50:    \"re-mail-ck\",\n\t52:    \"xns-time\",\n\t53:    \"domain\",\n\t54:    \"xns-ch\",\n\t55:    \"isi-gl\",\n\t56:    \"xns-auth\",\n\t58:    \"xns-mail\",\n\t62:    \"acas\",\n\t63:    \"whoispp\",\n\t64:    \"covia\",\n\t65:    \"tacacs-ds\",\n\t66:    \"sql-net\",\n\t67:    \"bootps\",\n\t68:    \"bootpc\",\n\t69:    \"tftp\",\n\t70:    \"gopher\",\n\t71:    \"netrjs-1\",\n\t72:    \"netrjs-2\",\n\t73:    \"netrjs-3\",\n\t74:    \"netrjs-4\",\n\t76:    \"deos\",\n\t78:    \"vettcp\",\n\t79:    \"finger\",\n\t80:    \"http\",\n\t82:    \"xfer\",\n\t83:    \"mit-ml-dev\",\n\t84:    \"ctf\",\n\t85:    \"mit-ml-dev\",\n\t86:    \"mfcobol\",\n\t88:    \"kerberos\",\n\t89:    \"su-mit-tg\",\n\t90:    \"dnsix\",\n\t91:    \"mit-dov\",\n\t92:    \"npp\",\n\t93:    \"dcp\",\n\t94:    \"objcall\",\n\t95:    \"supdup\",\n\t96:    \"dixie\",\n\t97:    \"swift-rvf\",\n\t98:    \"tacnews\",\n\t99:    \"metagram\",\n\t101:   \"hostname\",\n\t102:   \"iso-tsap\",\n\t103:   \"gppitnp\",\n\t104:   \"acr-nema\",\n\t105:   \"cso\",\n\t106:   \"3com-tsmux\",\n\t107:   \"rtelnet\",\n\t108:   \"snagas\",\n\t109:   \"pop2\",\n\t110:   \"pop3\",\n\t111:   \"sunrpc\",\n\t112:   \"mcidas\",\n\t113:   \"ident\",\n\t115:   \"sftp\",\n\t116:   \"ansanotify\",\n\t117:   \"uucp-path\",\n\t118:   \"sqlserv\",\n\t119:   \"nntp\",\n\t120:   \"cfdptkt\",\n\t121:   \"erpc\",\n\t122:   \"smakynet\",\n\t123:   \"ntp\",\n\t124:   \"ansatrader\",\n\t125:   \"locus-map\",\n\t126:   \"nxedit\",\n\t127:   \"locus-con\",\n\t128:   \"gss-xlicen\",\n\t129:   \"pwdgen\",\n\t130:   \"cisco-fna\",\n\t131:   \"cisco-tna\",\n\t132:   \"cisco-sys\",\n\t133:   \"statsrv\",\n\t134:   \"ingres-net\",\n\t135:   \"epmap\",\n\t136:   \"profile\",\n\t137:   \"netbios-ns\",\n\t138:   \"netbios-dgm\",\n\t139:   \"netbios-ssn\",\n\t140:   \"emfis-data\",\n\t141:   \"emfis-cntl\",\n\t142:   \"bl-idm\",\n\t143:   \"imap\",\n\t144:   \"uma\",\n\t145:   \"uaac\",\n\t146:   \"iso-tp0\",\n\t147:   \"iso-ip\",\n\t148:   \"jargon\",\n\t149:   \"aed-512\",\n\t150:   \"sql-net\",\n\t151:   \"hems\",\n\t152:   \"bftp\",\n\t153:   \"sgmp\",\n\t154:   \"netsc-prod\",\n\t155:   \"netsc-dev\",\n\t156:   \"sqlsrv\",\n\t157:   \"knet-cmp\",\n\t158:   \"pcmail-srv\",\n\t159:   \"nss-routing\",\n\t160:   \"sgmp-traps\",\n\t161:   \"snmp\",\n\t162:   \"snmptrap\",\n\t163:   \"cmip-man\",\n\t164:   \"cmip-agent\",\n\t165:   \"xns-courier\",\n\t166:   \"s-net\",\n\t167:   \"namp\",\n\t168:   \"rsvd\",\n\t169:   \"send\",\n\t170:   \"print-srv\",\n\t171:   \"multiplex\",\n\t172:   \"cl-1\",\n\t173:   \"xyplex-mux\",\n\t174:   \"mailq\",\n\t175:   \"vmnet\",\n\t176:   \"genrad-mux\",\n\t177:   \"xdmcp\",\n\t178:   \"nextstep\",\n\t179:   \"bgp\",\n\t180:   \"ris\",\n\t181:   \"unify\",\n\t182:   \"audit\",\n\t183:   \"ocbinder\",\n\t184:   \"ocserver\",\n\t185:   \"remote-kis\",\n\t186:   \"kis\",\n\t187:   \"aci\",\n\t188:   \"mumps\",\n\t189:   \"qft\",\n\t190:   \"gacp\",\n\t191:   \"prospero\",\n\t192:   \"osu-nms\",\n\t193:   \"srmp\",\n\t194:   \"irc\",\n\t195:   \"dn6-nlm-aud\",\n\t196:   \"dn6-smm-red\",\n\t197:   \"dls\",\n\t198:   \"dls-mon\",\n\t199:   \"smux\",\n\t200:   \"src\",\n\t201:   \"at-rtmp\",\n\t202:   \"at-nbp\",\n\t203:   \"at-3\",\n\t204:   \"at-echo\",\n\t205:   \"at-5\",\n\t206:   \"at-zis\",\n\t207:   \"at-7\",\n\t208:   \"at-8\",\n\t209:   \"qmtp\",\n\t210:   \"z39-50\",\n\t211:   \"914c-g\",\n\t212:   \"anet\",\n\t213:   \"ipx\",\n\t214:   \"vmpwscs\",\n\t215:   \"softpc\",\n\t216:   \"CAIlic\",\n\t217:   \"dbase\",\n\t218:   \"mpp\",\n\t219:   \"uarps\",\n\t220:   \"imap3\",\n\t221:   \"fln-spx\",\n\t222:   \"rsh-spx\",\n\t223:   \"cdc\",\n\t224:   \"masqdialer\",\n\t242:   \"direct\",\n\t243:   \"sur-meas\",\n\t244:   \"inbusiness\",\n\t245:   \"link\",\n\t246:   \"dsp3270\",\n\t247:   \"subntbcst-tftp\",\n\t248:   \"bhfhs\",\n\t256:   \"rap\",\n\t257:   \"set\",\n\t259:   \"esro-gen\",\n\t260:   \"openport\",\n\t261:   \"nsiiops\",\n\t262:   \"arcisdms\",\n\t263:   \"hdap\",\n\t264:   \"bgmp\",\n\t265:   \"x-bone-ctl\",\n\t266:   \"sst\",\n\t267:   \"td-service\",\n\t268:   \"td-replica\",\n\t269:   \"manet\",\n\t271:   \"pt-tls\",\n\t280:   \"http-mgmt\",\n\t281:   \"personal-link\",\n\t282:   \"cableport-ax\",\n\t283:   \"rescap\",\n\t284:   \"corerjd\",\n\t286:   \"fxp\",\n\t287:   \"k-block\",\n\t308:   \"novastorbakcup\",\n\t309:   \"entrusttime\",\n\t310:   \"bhmds\",\n\t311:   \"asip-webadmin\",\n\t312:   \"vslmp\",\n\t313:   \"magenta-logic\",\n\t314:   \"opalis-robot\",\n\t315:   \"dpsi\",\n\t316:   \"decauth\",\n\t317:   \"zannet\",\n\t318:   \"pkix-timestamp\",\n\t319:   \"ptp-event\",\n\t320:   \"ptp-general\",\n\t321:   \"pip\",\n\t322:   \"rtsps\",\n\t323:   \"rpki-rtr\",\n\t324:   \"rpki-rtr-tls\",\n\t333:   \"texar\",\n\t344:   \"pdap\",\n\t345:   \"pawserv\",\n\t346:   \"zserv\",\n\t347:   \"fatserv\",\n\t348:   \"csi-sgwp\",\n\t349:   \"mftp\",\n\t350:   \"matip-type-a\",\n\t351:   \"matip-type-b\",\n\t352:   \"dtag-ste-sb\",\n\t353:   \"ndsauth\",\n\t354:   \"bh611\",\n\t355:   \"datex-asn\",\n\t356:   \"cloanto-net-1\",\n\t357:   \"bhevent\",\n\t358:   \"shrinkwrap\",\n\t359:   \"nsrmp\",\n\t360:   \"scoi2odialog\",\n\t361:   \"semantix\",\n\t362:   \"srssend\",\n\t363:   \"rsvp-tunnel\",\n\t364:   \"aurora-cmgr\",\n\t365:   \"dtk\",\n\t366:   \"odmr\",\n\t367:   \"mortgageware\",\n\t368:   \"qbikgdp\",\n\t369:   \"rpc2portmap\",\n\t370:   \"codaauth2\",\n\t371:   \"clearcase\",\n\t372:   \"ulistproc\",\n\t373:   \"legent-1\",\n\t374:   \"legent-2\",\n\t375:   \"hassle\",\n\t376:   \"nip\",\n\t377:   \"tnETOS\",\n\t378:   \"dsETOS\",\n\t379:   \"is99c\",\n\t380:   \"is99s\",\n\t381:   \"hp-collector\",\n\t382:   \"hp-managed-node\",\n\t383:   \"hp-alarm-mgr\",\n\t384:   \"arns\",\n\t385:   \"ibm-app\",\n\t386:   \"asa\",\n\t387:   \"aurp\",\n\t388:   \"unidata-ldm\",\n\t389:   \"ldap\",\n\t390:   \"uis\",\n\t391:   \"synotics-relay\",\n\t392:   \"synotics-broker\",\n\t393:   \"meta5\",\n\t394:   \"embl-ndt\",\n\t395:   \"netcp\",\n\t396:   \"netware-ip\",\n\t397:   \"mptn\",\n\t398:   \"kryptolan\",\n\t399:   \"iso-tsap-c2\",\n\t400:   \"osb-sd\",\n\t401:   \"ups\",\n\t402:   \"genie\",\n\t403:   \"decap\",\n\t404:   \"nced\",\n\t405:   \"ncld\",\n\t406:   \"imsp\",\n\t407:   \"timbuktu\",\n\t408:   \"prm-sm\",\n\t409:   \"prm-nm\",\n\t410:   \"decladebug\",\n\t411:   \"rmt\",\n\t412:   \"synoptics-trap\",\n\t413:   \"smsp\",\n\t414:   \"infoseek\",\n\t415:   \"bnet\",\n\t416:   \"silverplatter\",\n\t417:   \"onmux\",\n\t418:   \"hyper-g\",\n\t419:   \"ariel1\",\n\t420:   \"smpte\",\n\t421:   \"ariel2\",\n\t422:   \"ariel3\",\n\t423:   \"opc-job-start\",\n\t424:   \"opc-job-track\",\n\t425:   \"icad-el\",\n\t426:   \"smartsdp\",\n\t427:   \"svrloc\",\n\t428:   \"ocs-cmu\",\n\t429:   \"ocs-amu\",\n\t430:   \"utmpsd\",\n\t431:   \"utmpcd\",\n\t432:   \"iasd\",\n\t433:   \"nnsp\",\n\t434:   \"mobileip-agent\",\n\t435:   \"mobilip-mn\",\n\t436:   \"dna-cml\",\n\t437:   \"comscm\",\n\t438:   \"dsfgw\",\n\t439:   \"dasp\",\n\t440:   \"sgcp\",\n\t441:   \"decvms-sysmgt\",\n\t442:   \"cvc-hostd\",\n\t443:   \"https\",\n\t444:   \"snpp\",\n\t445:   \"microsoft-ds\",\n\t446:   \"ddm-rdb\",\n\t447:   \"ddm-dfm\",\n\t448:   \"ddm-ssl\",\n\t449:   \"as-servermap\",\n\t450:   \"tserver\",\n\t451:   \"sfs-smp-net\",\n\t452:   \"sfs-config\",\n\t453:   \"creativeserver\",\n\t454:   \"contentserver\",\n\t455:   \"creativepartnr\",\n\t456:   \"macon-tcp\",\n\t457:   \"scohelp\",\n\t458:   \"appleqtc\",\n\t459:   \"ampr-rcmd\",\n\t460:   \"skronk\",\n\t461:   \"datasurfsrv\",\n\t462:   \"datasurfsrvsec\",\n\t463:   \"alpes\",\n\t464:   \"kpasswd\",\n\t465:   \"urd\",\n\t466:   \"digital-vrc\",\n\t467:   \"mylex-mapd\",\n\t468:   \"photuris\",\n\t469:   \"rcp\",\n\t470:   \"scx-proxy\",\n\t471:   \"mondex\",\n\t472:   \"ljk-login\",\n\t473:   \"hybrid-pop\",\n\t474:   \"tn-tl-w1\",\n\t475:   \"tcpnethaspsrv\",\n\t476:   \"tn-tl-fd1\",\n\t477:   \"ss7ns\",\n\t478:   \"spsc\",\n\t479:   \"iafserver\",\n\t480:   \"iafdbase\",\n\t481:   \"ph\",\n\t482:   \"bgs-nsi\",\n\t483:   \"ulpnet\",\n\t484:   \"integra-sme\",\n\t485:   \"powerburst\",\n\t486:   \"avian\",\n\t487:   \"saft\",\n\t488:   \"gss-http\",\n\t489:   \"nest-protocol\",\n\t490:   \"micom-pfs\",\n\t491:   \"go-login\",\n\t492:   \"ticf-1\",\n\t493:   \"ticf-2\",\n\t494:   \"pov-ray\",\n\t495:   \"intecourier\",\n\t496:   \"pim-rp-disc\",\n\t497:   \"retrospect\",\n\t498:   \"siam\",\n\t499:   \"iso-ill\",\n\t500:   \"isakmp\",\n\t501:   \"stmf\",\n\t502:   \"mbap\",\n\t503:   \"intrinsa\",\n\t504:   \"citadel\",\n\t505:   \"mailbox-lm\",\n\t506:   \"ohimsrv\",\n\t507:   \"crs\",\n\t508:   \"xvttp\",\n\t509:   \"snare\",\n\t510:   \"fcp\",\n\t511:   \"passgo\",\n\t512:   \"exec\",\n\t513:   \"login\",\n\t514:   \"shell\",\n\t515:   \"printer\",\n\t516:   \"videotex\",\n\t517:   \"talk\",\n\t518:   \"ntalk\",\n\t519:   \"utime\",\n\t520:   \"efs\",\n\t521:   \"ripng\",\n\t522:   \"ulp\",\n\t523:   \"ibm-db2\",\n\t524:   \"ncp\",\n\t525:   \"timed\",\n\t526:   \"tempo\",\n\t527:   \"stx\",\n\t528:   \"custix\",\n\t529:   \"irc-serv\",\n\t530:   \"courier\",\n\t531:   \"conference\",\n\t532:   \"netnews\",\n\t533:   \"netwall\",\n\t534:   \"windream\",\n\t535:   \"iiop\",\n\t536:   \"opalis-rdv\",\n\t537:   \"nmsp\",\n\t538:   \"gdomap\",\n\t539:   \"apertus-ldp\",\n\t540:   \"uucp\",\n\t541:   \"uucp-rlogin\",\n\t542:   \"commerce\",\n\t543:   \"klogin\",\n\t544:   \"kshell\",\n\t545:   \"appleqtcsrvr\",\n\t546:   \"dhcpv6-client\",\n\t547:   \"dhcpv6-server\",\n\t548:   \"afpovertcp\",\n\t549:   \"idfp\",\n\t550:   \"new-rwho\",\n\t551:   \"cybercash\",\n\t552:   \"devshr-nts\",\n\t553:   \"pirp\",\n\t554:   \"rtsp\",\n\t555:   \"dsf\",\n\t556:   \"remotefs\",\n\t557:   \"openvms-sysipc\",\n\t558:   \"sdnskmp\",\n\t559:   \"teedtap\",\n\t560:   \"rmonitor\",\n\t561:   \"monitor\",\n\t562:   \"chshell\",\n\t563:   \"nntps\",\n\t564:   \"9pfs\",\n\t565:   \"whoami\",\n\t566:   \"streettalk\",\n\t567:   \"banyan-rpc\",\n\t568:   \"ms-shuttle\",\n\t569:   \"ms-rome\",\n\t570:   \"meter\",\n\t571:   \"meter\",\n\t572:   \"sonar\",\n\t573:   \"banyan-vip\",\n\t574:   \"ftp-agent\",\n\t575:   \"vemmi\",\n\t576:   \"ipcd\",\n\t577:   \"vnas\",\n\t578:   \"ipdd\",\n\t579:   \"decbsrv\",\n\t580:   \"sntp-heartbeat\",\n\t581:   \"bdp\",\n\t582:   \"scc-security\",\n\t583:   \"philips-vc\",\n\t584:   \"keyserver\",\n\t586:   \"password-chg\",\n\t587:   \"submission\",\n\t588:   \"cal\",\n\t589:   \"eyelink\",\n\t590:   \"tns-cml\",\n\t591:   \"http-alt\",\n\t592:   \"eudora-set\",\n\t593:   \"http-rpc-epmap\",\n\t594:   \"tpip\",\n\t595:   \"cab-protocol\",\n\t596:   \"smsd\",\n\t597:   \"ptcnameservice\",\n\t598:   \"sco-websrvrmg3\",\n\t599:   \"acp\",\n\t600:   \"ipcserver\",\n\t601:   \"syslog-conn\",\n\t602:   \"xmlrpc-beep\",\n\t603:   \"idxp\",\n\t604:   \"tunnel\",\n\t605:   \"soap-beep\",\n\t606:   \"urm\",\n\t607:   \"nqs\",\n\t608:   \"sift-uft\",\n\t609:   \"npmp-trap\",\n\t610:   \"npmp-local\",\n\t611:   \"npmp-gui\",\n\t612:   \"hmmp-ind\",\n\t613:   \"hmmp-op\",\n\t614:   \"sshell\",\n\t615:   \"sco-inetmgr\",\n\t616:   \"sco-sysmgr\",\n\t617:   \"sco-dtmgr\",\n\t618:   \"dei-icda\",\n\t619:   \"compaq-evm\",\n\t620:   \"sco-websrvrmgr\",\n\t621:   \"escp-ip\",\n\t622:   \"collaborator\",\n\t623:   \"oob-ws-http\",\n\t624:   \"cryptoadmin\",\n\t625:   \"dec-dlm\",\n\t626:   \"asia\",\n\t627:   \"passgo-tivoli\",\n\t628:   \"qmqp\",\n\t629:   \"3com-amp3\",\n\t630:   \"rda\",\n\t631:   \"ipp\",\n\t632:   \"bmpp\",\n\t633:   \"servstat\",\n\t634:   \"ginad\",\n\t635:   \"rlzdbase\",\n\t636:   \"ldaps\",\n\t637:   \"lanserver\",\n\t638:   \"mcns-sec\",\n\t639:   \"msdp\",\n\t640:   \"entrust-sps\",\n\t641:   \"repcmd\",\n\t642:   \"esro-emsdp\",\n\t643:   \"sanity\",\n\t644:   \"dwr\",\n\t645:   \"pssc\",\n\t646:   \"ldp\",\n\t647:   \"dhcp-failover\",\n\t648:   \"rrp\",\n\t649:   \"cadview-3d\",\n\t650:   \"obex\",\n\t651:   \"ieee-mms\",\n\t652:   \"hello-port\",\n\t653:   \"repscmd\",\n\t654:   \"aodv\",\n\t655:   \"tinc\",\n\t656:   \"spmp\",\n\t657:   \"rmc\",\n\t658:   \"tenfold\",\n\t660:   \"mac-srvr-admin\",\n\t661:   \"hap\",\n\t662:   \"pftp\",\n\t663:   \"purenoise\",\n\t664:   \"oob-ws-https\",\n\t665:   \"sun-dr\",\n\t666:   \"mdqs\",\n\t667:   \"disclose\",\n\t668:   \"mecomm\",\n\t669:   \"meregister\",\n\t670:   \"vacdsm-sws\",\n\t671:   \"vacdsm-app\",\n\t672:   \"vpps-qua\",\n\t673:   \"cimplex\",\n\t674:   \"acap\",\n\t675:   \"dctp\",\n\t676:   \"vpps-via\",\n\t677:   \"vpp\",\n\t678:   \"ggf-ncp\",\n\t679:   \"mrm\",\n\t680:   \"entrust-aaas\",\n\t681:   \"entrust-aams\",\n\t682:   \"xfr\",\n\t683:   \"corba-iiop\",\n\t684:   \"corba-iiop-ssl\",\n\t685:   \"mdc-portmapper\",\n\t686:   \"hcp-wismar\",\n\t687:   \"asipregistry\",\n\t688:   \"realm-rusd\",\n\t689:   \"nmap\",\n\t690:   \"vatp\",\n\t691:   \"msexch-routing\",\n\t692:   \"hyperwave-isp\",\n\t693:   \"connendp\",\n\t694:   \"ha-cluster\",\n\t695:   \"ieee-mms-ssl\",\n\t696:   \"rushd\",\n\t697:   \"uuidgen\",\n\t698:   \"olsr\",\n\t699:   \"accessnetwork\",\n\t700:   \"epp\",\n\t701:   \"lmp\",\n\t702:   \"iris-beep\",\n\t704:   \"elcsd\",\n\t705:   \"agentx\",\n\t706:   \"silc\",\n\t707:   \"borland-dsj\",\n\t709:   \"entrust-kmsh\",\n\t710:   \"entrust-ash\",\n\t711:   \"cisco-tdp\",\n\t712:   \"tbrpf\",\n\t713:   \"iris-xpc\",\n\t714:   \"iris-xpcs\",\n\t715:   \"iris-lwz\",\n\t729:   \"netviewdm1\",\n\t730:   \"netviewdm2\",\n\t731:   \"netviewdm3\",\n\t741:   \"netgw\",\n\t742:   \"netrcs\",\n\t744:   \"flexlm\",\n\t747:   \"fujitsu-dev\",\n\t748:   \"ris-cm\",\n\t749:   \"kerberos-adm\",\n\t750:   \"rfile\",\n\t751:   \"pump\",\n\t752:   \"qrh\",\n\t753:   \"rrh\",\n\t754:   \"tell\",\n\t758:   \"nlogin\",\n\t759:   \"con\",\n\t760:   \"ns\",\n\t761:   \"rxe\",\n\t762:   \"quotad\",\n\t763:   \"cycleserv\",\n\t764:   \"omserv\",\n\t765:   \"webster\",\n\t767:   \"phonebook\",\n\t769:   \"vid\",\n\t770:   \"cadlock\",\n\t771:   \"rtip\",\n\t772:   \"cycleserv2\",\n\t773:   \"submit\",\n\t774:   \"rpasswd\",\n\t775:   \"entomb\",\n\t776:   \"wpages\",\n\t777:   \"multiling-http\",\n\t780:   \"wpgs\",\n\t800:   \"mdbs-daemon\",\n\t801:   \"device\",\n\t802:   \"mbap-s\",\n\t810:   \"fcp-udp\",\n\t828:   \"itm-mcell-s\",\n\t829:   \"pkix-3-ca-ra\",\n\t830:   \"netconf-ssh\",\n\t831:   \"netconf-beep\",\n\t832:   \"netconfsoaphttp\",\n\t833:   \"netconfsoapbeep\",\n\t847:   \"dhcp-failover2\",\n\t848:   \"gdoi\",\n\t853:   \"domain-s\",\n\t854:   \"dlep\",\n\t860:   \"iscsi\",\n\t861:   \"owamp-control\",\n\t862:   \"twamp-control\",\n\t873:   \"rsync\",\n\t886:   \"iclcnet-locate\",\n\t887:   \"iclcnet-svinfo\",\n\t888:   \"accessbuilder\",\n\t900:   \"omginitialrefs\",\n\t901:   \"smpnameres\",\n\t902:   \"ideafarm-door\",\n\t903:   \"ideafarm-panic\",\n\t910:   \"kink\",\n\t911:   \"xact-backup\",\n\t912:   \"apex-mesh\",\n\t913:   \"apex-edge\",\n\t953:   \"rndc\",\n\t989:   \"ftps-data\",\n\t990:   \"ftps\",\n\t991:   \"nas\",\n\t992:   \"telnets\",\n\t993:   \"imaps\",\n\t995:   \"pop3s\",\n\t996:   \"vsinet\",\n\t997:   \"maitrd\",\n\t998:   \"busboy\",\n\t999:   \"garcon\",\n\t1000:  \"cadlock2\",\n\t1001:  \"webpush\",\n\t1010:  \"surf\",\n\t1021:  \"exp1\",\n\t1022:  \"exp2\",\n\t1025:  \"blackjack\",\n\t1026:  \"cap\",\n\t1029:  \"solid-mux\",\n\t1033:  \"netinfo-local\",\n\t1034:  \"activesync\",\n\t1035:  \"mxxrlogin\",\n\t1036:  \"nsstp\",\n\t1037:  \"ams\",\n\t1038:  \"mtqp\",\n\t1039:  \"sbl\",\n\t1040:  \"netarx\",\n\t1041:  \"danf-ak2\",\n\t1042:  \"afrog\",\n\t1043:  \"boinc-client\",\n\t1044:  \"dcutility\",\n\t1045:  \"fpitp\",\n\t1046:  \"wfremotertm\",\n\t1047:  \"neod1\",\n\t1048:  \"neod2\",\n\t1049:  \"td-postman\",\n\t1050:  \"cma\",\n\t1051:  \"optima-vnet\",\n\t1052:  \"ddt\",\n\t1053:  \"remote-as\",\n\t1054:  \"brvread\",\n\t1055:  \"ansyslmd\",\n\t1056:  \"vfo\",\n\t1057:  \"startron\",\n\t1058:  \"nim\",\n\t1059:  \"nimreg\",\n\t1060:  \"polestar\",\n\t1061:  \"kiosk\",\n\t1062:  \"veracity\",\n\t1063:  \"kyoceranetdev\",\n\t1064:  \"jstel\",\n\t1065:  \"syscomlan\",\n\t1066:  \"fpo-fns\",\n\t1067:  \"instl-boots\",\n\t1068:  \"instl-bootc\",\n\t1069:  \"cognex-insight\",\n\t1070:  \"gmrupdateserv\",\n\t1071:  \"bsquare-voip\",\n\t1072:  \"cardax\",\n\t1073:  \"bridgecontrol\",\n\t1074:  \"warmspotMgmt\",\n\t1075:  \"rdrmshc\",\n\t1076:  \"dab-sti-c\",\n\t1077:  \"imgames\",\n\t1078:  \"avocent-proxy\",\n\t1079:  \"asprovatalk\",\n\t1080:  \"socks\",\n\t1081:  \"pvuniwien\",\n\t1082:  \"amt-esd-prot\",\n\t1083:  \"ansoft-lm-1\",\n\t1084:  \"ansoft-lm-2\",\n\t1085:  \"webobjects\",\n\t1086:  \"cplscrambler-lg\",\n\t1087:  \"cplscrambler-in\",\n\t1088:  \"cplscrambler-al\",\n\t1089:  \"ff-annunc\",\n\t1090:  \"ff-fms\",\n\t1091:  \"ff-sm\",\n\t1092:  \"obrpd\",\n\t1093:  \"proofd\",\n\t1094:  \"rootd\",\n\t1095:  \"nicelink\",\n\t1096:  \"cnrprotocol\",\n\t1097:  \"sunclustermgr\",\n\t1098:  \"rmiactivation\",\n\t1099:  \"rmiregistry\",\n\t1100:  \"mctp\",\n\t1101:  \"pt2-discover\",\n\t1102:  \"adobeserver-1\",\n\t1103:  \"adobeserver-2\",\n\t1104:  \"xrl\",\n\t1105:  \"ftranhc\",\n\t1106:  \"isoipsigport-1\",\n\t1107:  \"isoipsigport-2\",\n\t1108:  \"ratio-adp\",\n\t1110:  \"webadmstart\",\n\t1111:  \"lmsocialserver\",\n\t1112:  \"icp\",\n\t1113:  \"ltp-deepspace\",\n\t1114:  \"mini-sql\",\n\t1115:  \"ardus-trns\",\n\t1116:  \"ardus-cntl\",\n\t1117:  \"ardus-mtrns\",\n\t1118:  \"sacred\",\n\t1119:  \"bnetgame\",\n\t1120:  \"bnetfile\",\n\t1121:  \"rmpp\",\n\t1122:  \"availant-mgr\",\n\t1123:  \"murray\",\n\t1124:  \"hpvmmcontrol\",\n\t1125:  \"hpvmmagent\",\n\t1126:  \"hpvmmdata\",\n\t1127:  \"kwdb-commn\",\n\t1128:  \"saphostctrl\",\n\t1129:  \"saphostctrls\",\n\t1130:  \"casp\",\n\t1131:  \"caspssl\",\n\t1132:  \"kvm-via-ip\",\n\t1133:  \"dfn\",\n\t1134:  \"aplx\",\n\t1135:  \"omnivision\",\n\t1136:  \"hhb-gateway\",\n\t1137:  \"trim\",\n\t1138:  \"encrypted-admin\",\n\t1139:  \"evm\",\n\t1140:  \"autonoc\",\n\t1141:  \"mxomss\",\n\t1142:  \"edtools\",\n\t1143:  \"imyx\",\n\t1144:  \"fuscript\",\n\t1145:  \"x9-icue\",\n\t1146:  \"audit-transfer\",\n\t1147:  \"capioverlan\",\n\t1148:  \"elfiq-repl\",\n\t1149:  \"bvtsonar\",\n\t1150:  \"blaze\",\n\t1151:  \"unizensus\",\n\t1152:  \"winpoplanmess\",\n\t1153:  \"c1222-acse\",\n\t1154:  \"resacommunity\",\n\t1155:  \"nfa\",\n\t1156:  \"iascontrol-oms\",\n\t1157:  \"iascontrol\",\n\t1158:  \"dbcontrol-oms\",\n\t1159:  \"oracle-oms\",\n\t1160:  \"olsv\",\n\t1161:  \"health-polling\",\n\t1162:  \"health-trap\",\n\t1163:  \"sddp\",\n\t1164:  \"qsm-proxy\",\n\t1165:  \"qsm-gui\",\n\t1166:  \"qsm-remote\",\n\t1167:  \"cisco-ipsla\",\n\t1168:  \"vchat\",\n\t1169:  \"tripwire\",\n\t1170:  \"atc-lm\",\n\t1171:  \"atc-appserver\",\n\t1172:  \"dnap\",\n\t1173:  \"d-cinema-rrp\",\n\t1174:  \"fnet-remote-ui\",\n\t1175:  \"dossier\",\n\t1176:  \"indigo-server\",\n\t1177:  \"dkmessenger\",\n\t1178:  \"sgi-storman\",\n\t1179:  \"b2n\",\n\t1180:  \"mc-client\",\n\t1181:  \"3comnetman\",\n\t1182:  \"accelenet\",\n\t1183:  \"llsurfup-http\",\n\t1184:  \"llsurfup-https\",\n\t1185:  \"catchpole\",\n\t1186:  \"mysql-cluster\",\n\t1187:  \"alias\",\n\t1188:  \"hp-webadmin\",\n\t1189:  \"unet\",\n\t1190:  \"commlinx-avl\",\n\t1191:  \"gpfs\",\n\t1192:  \"caids-sensor\",\n\t1193:  \"fiveacross\",\n\t1194:  \"openvpn\",\n\t1195:  \"rsf-1\",\n\t1196:  \"netmagic\",\n\t1197:  \"carrius-rshell\",\n\t1198:  \"cajo-discovery\",\n\t1199:  \"dmidi\",\n\t1200:  \"scol\",\n\t1201:  \"nucleus-sand\",\n\t1202:  \"caiccipc\",\n\t1203:  \"ssslic-mgr\",\n\t1204:  \"ssslog-mgr\",\n\t1205:  \"accord-mgc\",\n\t1206:  \"anthony-data\",\n\t1207:  \"metasage\",\n\t1208:  \"seagull-ais\",\n\t1209:  \"ipcd3\",\n\t1210:  \"eoss\",\n\t1211:  \"groove-dpp\",\n\t1212:  \"lupa\",\n\t1213:  \"mpc-lifenet\",\n\t1214:  \"kazaa\",\n\t1215:  \"scanstat-1\",\n\t1216:  \"etebac5\",\n\t1217:  \"hpss-ndapi\",\n\t1218:  \"aeroflight-ads\",\n\t1219:  \"aeroflight-ret\",\n\t1220:  \"qt-serveradmin\",\n\t1221:  \"sweetware-apps\",\n\t1222:  \"nerv\",\n\t1223:  \"tgp\",\n\t1224:  \"vpnz\",\n\t1225:  \"slinkysearch\",\n\t1226:  \"stgxfws\",\n\t1227:  \"dns2go\",\n\t1228:  \"florence\",\n\t1229:  \"zented\",\n\t1230:  \"periscope\",\n\t1231:  \"menandmice-lpm\",\n\t1232:  \"first-defense\",\n\t1233:  \"univ-appserver\",\n\t1234:  \"search-agent\",\n\t1235:  \"mosaicsyssvc1\",\n\t1236:  \"bvcontrol\",\n\t1237:  \"tsdos390\",\n\t1238:  \"hacl-qs\",\n\t1239:  \"nmsd\",\n\t1240:  \"instantia\",\n\t1241:  \"nessus\",\n\t1242:  \"nmasoverip\",\n\t1243:  \"serialgateway\",\n\t1244:  \"isbconference1\",\n\t1245:  \"isbconference2\",\n\t1246:  \"payrouter\",\n\t1247:  \"visionpyramid\",\n\t1248:  \"hermes\",\n\t1249:  \"mesavistaco\",\n\t1250:  \"swldy-sias\",\n\t1251:  \"servergraph\",\n\t1252:  \"bspne-pcc\",\n\t1253:  \"q55-pcc\",\n\t1254:  \"de-noc\",\n\t1255:  \"de-cache-query\",\n\t1256:  \"de-server\",\n\t1257:  \"shockwave2\",\n\t1258:  \"opennl\",\n\t1259:  \"opennl-voice\",\n\t1260:  \"ibm-ssd\",\n\t1261:  \"mpshrsv\",\n\t1262:  \"qnts-orb\",\n\t1263:  \"dka\",\n\t1264:  \"prat\",\n\t1265:  \"dssiapi\",\n\t1266:  \"dellpwrappks\",\n\t1267:  \"epc\",\n\t1268:  \"propel-msgsys\",\n\t1269:  \"watilapp\",\n\t1270:  \"opsmgr\",\n\t1271:  \"excw\",\n\t1272:  \"cspmlockmgr\",\n\t1273:  \"emc-gateway\",\n\t1274:  \"t1distproc\",\n\t1275:  \"ivcollector\",\n\t1277:  \"miva-mqs\",\n\t1278:  \"dellwebadmin-1\",\n\t1279:  \"dellwebadmin-2\",\n\t1280:  \"pictrography\",\n\t1281:  \"healthd\",\n\t1282:  \"emperion\",\n\t1283:  \"productinfo\",\n\t1284:  \"iee-qfx\",\n\t1285:  \"neoiface\",\n\t1286:  \"netuitive\",\n\t1287:  \"routematch\",\n\t1288:  \"navbuddy\",\n\t1289:  \"jwalkserver\",\n\t1290:  \"winjaserver\",\n\t1291:  \"seagulllms\",\n\t1292:  \"dsdn\",\n\t1293:  \"pkt-krb-ipsec\",\n\t1294:  \"cmmdriver\",\n\t1295:  \"ehtp\",\n\t1296:  \"dproxy\",\n\t1297:  \"sdproxy\",\n\t1298:  \"lpcp\",\n\t1299:  \"hp-sci\",\n\t1300:  \"h323hostcallsc\",\n\t1301:  \"ci3-software-1\",\n\t1302:  \"ci3-software-2\",\n\t1303:  \"sftsrv\",\n\t1304:  \"boomerang\",\n\t1305:  \"pe-mike\",\n\t1306:  \"re-conn-proto\",\n\t1307:  \"pacmand\",\n\t1308:  \"odsi\",\n\t1309:  \"jtag-server\",\n\t1310:  \"husky\",\n\t1311:  \"rxmon\",\n\t1312:  \"sti-envision\",\n\t1313:  \"bmc-patroldb\",\n\t1314:  \"pdps\",\n\t1315:  \"els\",\n\t1316:  \"exbit-escp\",\n\t1317:  \"vrts-ipcserver\",\n\t1318:  \"krb5gatekeeper\",\n\t1319:  \"amx-icsp\",\n\t1320:  \"amx-axbnet\",\n\t1321:  \"pip\",\n\t1322:  \"novation\",\n\t1323:  \"brcd\",\n\t1324:  \"delta-mcp\",\n\t1325:  \"dx-instrument\",\n\t1326:  \"wimsic\",\n\t1327:  \"ultrex\",\n\t1328:  \"ewall\",\n\t1329:  \"netdb-export\",\n\t1330:  \"streetperfect\",\n\t1331:  \"intersan\",\n\t1332:  \"pcia-rxp-b\",\n\t1333:  \"passwrd-policy\",\n\t1334:  \"writesrv\",\n\t1335:  \"digital-notary\",\n\t1336:  \"ischat\",\n\t1337:  \"menandmice-dns\",\n\t1338:  \"wmc-log-svc\",\n\t1339:  \"kjtsiteserver\",\n\t1340:  \"naap\",\n\t1341:  \"qubes\",\n\t1342:  \"esbroker\",\n\t1343:  \"re101\",\n\t1344:  \"icap\",\n\t1345:  \"vpjp\",\n\t1346:  \"alta-ana-lm\",\n\t1347:  \"bbn-mmc\",\n\t1348:  \"bbn-mmx\",\n\t1349:  \"sbook\",\n\t1350:  \"editbench\",\n\t1351:  \"equationbuilder\",\n\t1352:  \"lotusnote\",\n\t1353:  \"relief\",\n\t1354:  \"XSIP-network\",\n\t1355:  \"intuitive-edge\",\n\t1356:  \"cuillamartin\",\n\t1357:  \"pegboard\",\n\t1358:  \"connlcli\",\n\t1359:  \"ftsrv\",\n\t1360:  \"mimer\",\n\t1361:  \"linx\",\n\t1362:  \"timeflies\",\n\t1363:  \"ndm-requester\",\n\t1364:  \"ndm-server\",\n\t1365:  \"adapt-sna\",\n\t1366:  \"netware-csp\",\n\t1367:  \"dcs\",\n\t1368:  \"screencast\",\n\t1369:  \"gv-us\",\n\t1370:  \"us-gv\",\n\t1371:  \"fc-cli\",\n\t1372:  \"fc-ser\",\n\t1373:  \"chromagrafx\",\n\t1374:  \"molly\",\n\t1375:  \"bytex\",\n\t1376:  \"ibm-pps\",\n\t1377:  \"cichlid\",\n\t1378:  \"elan\",\n\t1379:  \"dbreporter\",\n\t1380:  \"telesis-licman\",\n\t1381:  \"apple-licman\",\n\t1382:  \"udt-os\",\n\t1383:  \"gwha\",\n\t1384:  \"os-licman\",\n\t1385:  \"atex-elmd\",\n\t1386:  \"checksum\",\n\t1387:  \"cadsi-lm\",\n\t1388:  \"objective-dbc\",\n\t1389:  \"iclpv-dm\",\n\t1390:  \"iclpv-sc\",\n\t1391:  \"iclpv-sas\",\n\t1392:  \"iclpv-pm\",\n\t1393:  \"iclpv-nls\",\n\t1394:  \"iclpv-nlc\",\n\t1395:  \"iclpv-wsm\",\n\t1396:  \"dvl-activemail\",\n\t1397:  \"audio-activmail\",\n\t1398:  \"video-activmail\",\n\t1399:  \"cadkey-licman\",\n\t1400:  \"cadkey-tablet\",\n\t1401:  \"goldleaf-licman\",\n\t1402:  \"prm-sm-np\",\n\t1403:  \"prm-nm-np\",\n\t1404:  \"igi-lm\",\n\t1405:  \"ibm-res\",\n\t1406:  \"netlabs-lm\",\n\t1407:  \"tibet-server\",\n\t1408:  \"sophia-lm\",\n\t1409:  \"here-lm\",\n\t1410:  \"hiq\",\n\t1411:  \"af\",\n\t1412:  \"innosys\",\n\t1413:  \"innosys-acl\",\n\t1414:  \"ibm-mqseries\",\n\t1415:  \"dbstar\",\n\t1416:  \"novell-lu6-2\",\n\t1417:  \"timbuktu-srv1\",\n\t1418:  \"timbuktu-srv2\",\n\t1419:  \"timbuktu-srv3\",\n\t1420:  \"timbuktu-srv4\",\n\t1421:  \"gandalf-lm\",\n\t1422:  \"autodesk-lm\",\n\t1423:  \"essbase\",\n\t1424:  \"hybrid\",\n\t1425:  \"zion-lm\",\n\t1426:  \"sais\",\n\t1427:  \"mloadd\",\n\t1428:  \"informatik-lm\",\n\t1429:  \"nms\",\n\t1430:  \"tpdu\",\n\t1431:  \"rgtp\",\n\t1432:  \"blueberry-lm\",\n\t1433:  \"ms-sql-s\",\n\t1434:  \"ms-sql-m\",\n\t1435:  \"ibm-cics\",\n\t1436:  \"saism\",\n\t1437:  \"tabula\",\n\t1438:  \"eicon-server\",\n\t1439:  \"eicon-x25\",\n\t1440:  \"eicon-slp\",\n\t1441:  \"cadis-1\",\n\t1442:  \"cadis-2\",\n\t1443:  \"ies-lm\",\n\t1444:  \"marcam-lm\",\n\t1445:  \"proxima-lm\",\n\t1446:  \"ora-lm\",\n\t1447:  \"apri-lm\",\n\t1448:  \"oc-lm\",\n\t1449:  \"peport\",\n\t1450:  \"dwf\",\n\t1451:  \"infoman\",\n\t1452:  \"gtegsc-lm\",\n\t1453:  \"genie-lm\",\n\t1454:  \"interhdl-elmd\",\n\t1455:  \"esl-lm\",\n\t1456:  \"dca\",\n\t1457:  \"valisys-lm\",\n\t1458:  \"nrcabq-lm\",\n\t1459:  \"proshare1\",\n\t1460:  \"proshare2\",\n\t1461:  \"ibm-wrless-lan\",\n\t1462:  \"world-lm\",\n\t1463:  \"nucleus\",\n\t1464:  \"msl-lmd\",\n\t1465:  \"pipes\",\n\t1466:  \"oceansoft-lm\",\n\t1467:  \"csdmbase\",\n\t1468:  \"csdm\",\n\t1469:  \"aal-lm\",\n\t1470:  \"uaiact\",\n\t1471:  \"csdmbase\",\n\t1472:  \"csdm\",\n\t1473:  \"openmath\",\n\t1474:  \"telefinder\",\n\t1475:  \"taligent-lm\",\n\t1476:  \"clvm-cfg\",\n\t1477:  \"ms-sna-server\",\n\t1478:  \"ms-sna-base\",\n\t1479:  \"dberegister\",\n\t1480:  \"pacerforum\",\n\t1481:  \"airs\",\n\t1482:  \"miteksys-lm\",\n\t1483:  \"afs\",\n\t1484:  \"confluent\",\n\t1485:  \"lansource\",\n\t1486:  \"nms-topo-serv\",\n\t1487:  \"localinfosrvr\",\n\t1488:  \"docstor\",\n\t1489:  \"dmdocbroker\",\n\t1490:  \"insitu-conf\",\n\t1492:  \"stone-design-1\",\n\t1493:  \"netmap-lm\",\n\t1494:  \"ica\",\n\t1495:  \"cvc\",\n\t1496:  \"liberty-lm\",\n\t1497:  \"rfx-lm\",\n\t1498:  \"sybase-sqlany\",\n\t1499:  \"fhc\",\n\t1500:  \"vlsi-lm\",\n\t1501:  \"saiscm\",\n\t1502:  \"shivadiscovery\",\n\t1503:  \"imtc-mcs\",\n\t1504:  \"evb-elm\",\n\t1505:  \"funkproxy\",\n\t1506:  \"utcd\",\n\t1507:  \"symplex\",\n\t1508:  \"diagmond\",\n\t1509:  \"robcad-lm\",\n\t1510:  \"mvx-lm\",\n\t1511:  \"3l-l1\",\n\t1512:  \"wins\",\n\t1513:  \"fujitsu-dtc\",\n\t1514:  \"fujitsu-dtcns\",\n\t1515:  \"ifor-protocol\",\n\t1516:  \"vpad\",\n\t1517:  \"vpac\",\n\t1518:  \"vpvd\",\n\t1519:  \"vpvc\",\n\t1520:  \"atm-zip-office\",\n\t1521:  \"ncube-lm\",\n\t1522:  \"ricardo-lm\",\n\t1523:  \"cichild-lm\",\n\t1524:  \"ingreslock\",\n\t1525:  \"orasrv\",\n\t1526:  \"pdap-np\",\n\t1527:  \"tlisrv\",\n\t1529:  \"coauthor\",\n\t1530:  \"rap-service\",\n\t1531:  \"rap-listen\",\n\t1532:  \"miroconnect\",\n\t1533:  \"virtual-places\",\n\t1534:  \"micromuse-lm\",\n\t1535:  \"ampr-info\",\n\t1536:  \"ampr-inter\",\n\t1537:  \"sdsc-lm\",\n\t1538:  \"3ds-lm\",\n\t1539:  \"intellistor-lm\",\n\t1540:  \"rds\",\n\t1541:  \"rds2\",\n\t1542:  \"gridgen-elmd\",\n\t1543:  \"simba-cs\",\n\t1544:  \"aspeclmd\",\n\t1545:  \"vistium-share\",\n\t1546:  \"abbaccuray\",\n\t1547:  \"laplink\",\n\t1548:  \"axon-lm\",\n\t1549:  \"shivahose\",\n\t1550:  \"3m-image-lm\",\n\t1551:  \"hecmtl-db\",\n\t1552:  \"pciarray\",\n\t1553:  \"sna-cs\",\n\t1554:  \"caci-lm\",\n\t1555:  \"livelan\",\n\t1556:  \"veritas-pbx\",\n\t1557:  \"arbortext-lm\",\n\t1558:  \"xingmpeg\",\n\t1559:  \"web2host\",\n\t1560:  \"asci-val\",\n\t1561:  \"facilityview\",\n\t1562:  \"pconnectmgr\",\n\t1563:  \"cadabra-lm\",\n\t1564:  \"pay-per-view\",\n\t1565:  \"winddlb\",\n\t1566:  \"corelvideo\",\n\t1567:  \"jlicelmd\",\n\t1568:  \"tsspmap\",\n\t1569:  \"ets\",\n\t1570:  \"orbixd\",\n\t1571:  \"rdb-dbs-disp\",\n\t1572:  \"chip-lm\",\n\t1573:  \"itscomm-ns\",\n\t1574:  \"mvel-lm\",\n\t1575:  \"oraclenames\",\n\t1576:  \"moldflow-lm\",\n\t1577:  \"hypercube-lm\",\n\t1578:  \"jacobus-lm\",\n\t1579:  \"ioc-sea-lm\",\n\t1580:  \"tn-tl-r1\",\n\t1581:  \"mil-2045-47001\",\n\t1582:  \"msims\",\n\t1583:  \"simbaexpress\",\n\t1584:  \"tn-tl-fd2\",\n\t1585:  \"intv\",\n\t1586:  \"ibm-abtact\",\n\t1587:  \"pra-elmd\",\n\t1588:  \"triquest-lm\",\n\t1589:  \"vqp\",\n\t1590:  \"gemini-lm\",\n\t1591:  \"ncpm-pm\",\n\t1592:  \"commonspace\",\n\t1593:  \"mainsoft-lm\",\n\t1594:  \"sixtrak\",\n\t1595:  \"radio\",\n\t1596:  \"radio-sm\",\n\t1597:  \"orbplus-iiop\",\n\t1598:  \"picknfs\",\n\t1599:  \"simbaservices\",\n\t1600:  \"issd\",\n\t1601:  \"aas\",\n\t1602:  \"inspect\",\n\t1603:  \"picodbc\",\n\t1604:  \"icabrowser\",\n\t1605:  \"slp\",\n\t1606:  \"slm-api\",\n\t1607:  \"stt\",\n\t1608:  \"smart-lm\",\n\t1609:  \"isysg-lm\",\n\t1610:  \"taurus-wh\",\n\t1611:  \"ill\",\n\t1612:  \"netbill-trans\",\n\t1613:  \"netbill-keyrep\",\n\t1614:  \"netbill-cred\",\n\t1615:  \"netbill-auth\",\n\t1616:  \"netbill-prod\",\n\t1617:  \"nimrod-agent\",\n\t1618:  \"skytelnet\",\n\t1619:  \"xs-openstorage\",\n\t1620:  \"faxportwinport\",\n\t1621:  \"softdataphone\",\n\t1622:  \"ontime\",\n\t1623:  \"jaleosnd\",\n\t1624:  \"udp-sr-port\",\n\t1625:  \"svs-omagent\",\n\t1626:  \"shockwave\",\n\t1627:  \"t128-gateway\",\n\t1628:  \"lontalk-norm\",\n\t1629:  \"lontalk-urgnt\",\n\t1630:  \"oraclenet8cman\",\n\t1631:  \"visitview\",\n\t1632:  \"pammratc\",\n\t1633:  \"pammrpc\",\n\t1634:  \"loaprobe\",\n\t1635:  \"edb-server1\",\n\t1636:  \"isdc\",\n\t1637:  \"islc\",\n\t1638:  \"ismc\",\n\t1639:  \"cert-initiator\",\n\t1640:  \"cert-responder\",\n\t1641:  \"invision\",\n\t1642:  \"isis-am\",\n\t1643:  \"isis-ambc\",\n\t1644:  \"saiseh\",\n\t1645:  \"sightline\",\n\t1646:  \"sa-msg-port\",\n\t1647:  \"rsap\",\n\t1648:  \"concurrent-lm\",\n\t1649:  \"kermit\",\n\t1650:  \"nkd\",\n\t1651:  \"shiva-confsrvr\",\n\t1652:  \"xnmp\",\n\t1653:  \"alphatech-lm\",\n\t1654:  \"stargatealerts\",\n\t1655:  \"dec-mbadmin\",\n\t1656:  \"dec-mbadmin-h\",\n\t1657:  \"fujitsu-mmpdc\",\n\t1658:  \"sixnetudr\",\n\t1659:  \"sg-lm\",\n\t1660:  \"skip-mc-gikreq\",\n\t1661:  \"netview-aix-1\",\n\t1662:  \"netview-aix-2\",\n\t1663:  \"netview-aix-3\",\n\t1664:  \"netview-aix-4\",\n\t1665:  \"netview-aix-5\",\n\t1666:  \"netview-aix-6\",\n\t1667:  \"netview-aix-7\",\n\t1668:  \"netview-aix-8\",\n\t1669:  \"netview-aix-9\",\n\t1670:  \"netview-aix-10\",\n\t1671:  \"netview-aix-11\",\n\t1672:  \"netview-aix-12\",\n\t1673:  \"proshare-mc-1\",\n\t1674:  \"proshare-mc-2\",\n\t1675:  \"pdp\",\n\t1676:  \"netcomm1\",\n\t1677:  \"groupwise\",\n\t1678:  \"prolink\",\n\t1679:  \"darcorp-lm\",\n\t1680:  \"microcom-sbp\",\n\t1681:  \"sd-elmd\",\n\t1682:  \"lanyon-lantern\",\n\t1683:  \"ncpm-hip\",\n\t1684:  \"snaresecure\",\n\t1685:  \"n2nremote\",\n\t1686:  \"cvmon\",\n\t1687:  \"nsjtp-ctrl\",\n\t1688:  \"nsjtp-data\",\n\t1689:  \"firefox\",\n\t1690:  \"ng-umds\",\n\t1691:  \"empire-empuma\",\n\t1692:  \"sstsys-lm\",\n\t1693:  \"rrirtr\",\n\t1694:  \"rrimwm\",\n\t1695:  \"rrilwm\",\n\t1696:  \"rrifmm\",\n\t1697:  \"rrisat\",\n\t1698:  \"rsvp-encap-1\",\n\t1699:  \"rsvp-encap-2\",\n\t1700:  \"mps-raft\",\n\t1701:  \"l2f\",\n\t1702:  \"deskshare\",\n\t1703:  \"hb-engine\",\n\t1704:  \"bcs-broker\",\n\t1705:  \"slingshot\",\n\t1706:  \"jetform\",\n\t1707:  \"vdmplay\",\n\t1708:  \"gat-lmd\",\n\t1709:  \"centra\",\n\t1710:  \"impera\",\n\t1711:  \"pptconference\",\n\t1712:  \"registrar\",\n\t1713:  \"conferencetalk\",\n\t1714:  \"sesi-lm\",\n\t1715:  \"houdini-lm\",\n\t1716:  \"xmsg\",\n\t1717:  \"fj-hdnet\",\n\t1718:  \"h323gatedisc\",\n\t1719:  \"h323gatestat\",\n\t1720:  \"h323hostcall\",\n\t1721:  \"caicci\",\n\t1722:  \"hks-lm\",\n\t1723:  \"pptp\",\n\t1724:  \"csbphonemaster\",\n\t1725:  \"iden-ralp\",\n\t1726:  \"iberiagames\",\n\t1727:  \"winddx\",\n\t1728:  \"telindus\",\n\t1729:  \"citynl\",\n\t1730:  \"roketz\",\n\t1731:  \"msiccp\",\n\t1732:  \"proxim\",\n\t1733:  \"siipat\",\n\t1734:  \"cambertx-lm\",\n\t1735:  \"privatechat\",\n\t1736:  \"street-stream\",\n\t1737:  \"ultimad\",\n\t1738:  \"gamegen1\",\n\t1739:  \"webaccess\",\n\t1740:  \"encore\",\n\t1741:  \"cisco-net-mgmt\",\n\t1742:  \"3Com-nsd\",\n\t1743:  \"cinegrfx-lm\",\n\t1744:  \"ncpm-ft\",\n\t1745:  \"remote-winsock\",\n\t1746:  \"ftrapid-1\",\n\t1747:  \"ftrapid-2\",\n\t1748:  \"oracle-em1\",\n\t1749:  \"aspen-services\",\n\t1750:  \"sslp\",\n\t1751:  \"swiftnet\",\n\t1752:  \"lofr-lm\",\n\t1753:  \"predatar-comms\",\n\t1754:  \"oracle-em2\",\n\t1755:  \"ms-streaming\",\n\t1756:  \"capfast-lmd\",\n\t1757:  \"cnhrp\",\n\t1758:  \"tftp-mcast\",\n\t1759:  \"spss-lm\",\n\t1760:  \"www-ldap-gw\",\n\t1761:  \"cft-0\",\n\t1762:  \"cft-1\",\n\t1763:  \"cft-2\",\n\t1764:  \"cft-3\",\n\t1765:  \"cft-4\",\n\t1766:  \"cft-5\",\n\t1767:  \"cft-6\",\n\t1768:  \"cft-7\",\n\t1769:  \"bmc-net-adm\",\n\t1770:  \"bmc-net-svc\",\n\t1771:  \"vaultbase\",\n\t1772:  \"essweb-gw\",\n\t1773:  \"kmscontrol\",\n\t1774:  \"global-dtserv\",\n\t1775:  \"vdab\",\n\t1776:  \"femis\",\n\t1777:  \"powerguardian\",\n\t1778:  \"prodigy-intrnet\",\n\t1779:  \"pharmasoft\",\n\t1780:  \"dpkeyserv\",\n\t1781:  \"answersoft-lm\",\n\t1782:  \"hp-hcip\",\n\t1784:  \"finle-lm\",\n\t1785:  \"windlm\",\n\t1786:  \"funk-logger\",\n\t1787:  \"funk-license\",\n\t1788:  \"psmond\",\n\t1789:  \"hello\",\n\t1790:  \"nmsp\",\n\t1791:  \"ea1\",\n\t1792:  \"ibm-dt-2\",\n\t1793:  \"rsc-robot\",\n\t1794:  \"cera-bcm\",\n\t1795:  \"dpi-proxy\",\n\t1796:  \"vocaltec-admin\",\n\t1797:  \"uma\",\n\t1798:  \"etp\",\n\t1799:  \"netrisk\",\n\t1800:  \"ansys-lm\",\n\t1801:  \"msmq\",\n\t1802:  \"concomp1\",\n\t1803:  \"hp-hcip-gwy\",\n\t1804:  \"enl\",\n\t1805:  \"enl-name\",\n\t1806:  \"musiconline\",\n\t1807:  \"fhsp\",\n\t1808:  \"oracle-vp2\",\n\t1809:  \"oracle-vp1\",\n\t1810:  \"jerand-lm\",\n\t1811:  \"scientia-sdb\",\n\t1812:  \"radius\",\n\t1813:  \"radius-acct\",\n\t1814:  \"tdp-suite\",\n\t1815:  \"mmpft\",\n\t1816:  \"harp\",\n\t1817:  \"rkb-oscs\",\n\t1818:  \"etftp\",\n\t1819:  \"plato-lm\",\n\t1820:  \"mcagent\",\n\t1821:  \"donnyworld\",\n\t1822:  \"es-elmd\",\n\t1823:  \"unisys-lm\",\n\t1824:  \"metrics-pas\",\n\t1825:  \"direcpc-video\",\n\t1826:  \"ardt\",\n\t1827:  \"asi\",\n\t1828:  \"itm-mcell-u\",\n\t1829:  \"optika-emedia\",\n\t1830:  \"net8-cman\",\n\t1831:  \"myrtle\",\n\t1832:  \"tht-treasure\",\n\t1833:  \"udpradio\",\n\t1834:  \"ardusuni\",\n\t1835:  \"ardusmul\",\n\t1836:  \"ste-smsc\",\n\t1837:  \"csoft1\",\n\t1838:  \"talnet\",\n\t1839:  \"netopia-vo1\",\n\t1840:  \"netopia-vo2\",\n\t1841:  \"netopia-vo3\",\n\t1842:  \"netopia-vo4\",\n\t1843:  \"netopia-vo5\",\n\t1844:  \"direcpc-dll\",\n\t1845:  \"altalink\",\n\t1846:  \"tunstall-pnc\",\n\t1847:  \"slp-notify\",\n\t1848:  \"fjdocdist\",\n\t1849:  \"alpha-sms\",\n\t1850:  \"gsi\",\n\t1851:  \"ctcd\",\n\t1852:  \"virtual-time\",\n\t1853:  \"vids-avtp\",\n\t1854:  \"buddy-draw\",\n\t1855:  \"fiorano-rtrsvc\",\n\t1856:  \"fiorano-msgsvc\",\n\t1857:  \"datacaptor\",\n\t1858:  \"privateark\",\n\t1859:  \"gammafetchsvr\",\n\t1860:  \"sunscalar-svc\",\n\t1861:  \"lecroy-vicp\",\n\t1862:  \"mysql-cm-agent\",\n\t1863:  \"msnp\",\n\t1864:  \"paradym-31port\",\n\t1865:  \"entp\",\n\t1866:  \"swrmi\",\n\t1867:  \"udrive\",\n\t1868:  \"viziblebrowser\",\n\t1869:  \"transact\",\n\t1870:  \"sunscalar-dns\",\n\t1871:  \"canocentral0\",\n\t1872:  \"canocentral1\",\n\t1873:  \"fjmpjps\",\n\t1874:  \"fjswapsnp\",\n\t1875:  \"westell-stats\",\n\t1876:  \"ewcappsrv\",\n\t1877:  \"hp-webqosdb\",\n\t1878:  \"drmsmc\",\n\t1879:  \"nettgain-nms\",\n\t1880:  \"vsat-control\",\n\t1881:  \"ibm-mqseries2\",\n\t1882:  \"ecsqdmn\",\n\t1883:  \"mqtt\",\n\t1884:  \"idmaps\",\n\t1885:  \"vrtstrapserver\",\n\t1886:  \"leoip\",\n\t1887:  \"filex-lport\",\n\t1888:  \"ncconfig\",\n\t1889:  \"unify-adapter\",\n\t1890:  \"wilkenlistener\",\n\t1891:  \"childkey-notif\",\n\t1892:  \"childkey-ctrl\",\n\t1893:  \"elad\",\n\t1894:  \"o2server-port\",\n\t1896:  \"b-novative-ls\",\n\t1897:  \"metaagent\",\n\t1898:  \"cymtec-port\",\n\t1899:  \"mc2studios\",\n\t1900:  \"ssdp\",\n\t1901:  \"fjicl-tep-a\",\n\t1902:  \"fjicl-tep-b\",\n\t1903:  \"linkname\",\n\t1904:  \"fjicl-tep-c\",\n\t1905:  \"sugp\",\n\t1906:  \"tpmd\",\n\t1907:  \"intrastar\",\n\t1908:  \"dawn\",\n\t1909:  \"global-wlink\",\n\t1910:  \"ultrabac\",\n\t1911:  \"mtp\",\n\t1912:  \"rhp-iibp\",\n\t1913:  \"armadp\",\n\t1914:  \"elm-momentum\",\n\t1915:  \"facelink\",\n\t1916:  \"persona\",\n\t1917:  \"noagent\",\n\t1918:  \"can-nds\",\n\t1919:  \"can-dch\",\n\t1920:  \"can-ferret\",\n\t1921:  \"noadmin\",\n\t1922:  \"tapestry\",\n\t1923:  \"spice\",\n\t1924:  \"xiip\",\n\t1925:  \"discovery-port\",\n\t1926:  \"egs\",\n\t1927:  \"videte-cipc\",\n\t1928:  \"emsd-port\",\n\t1929:  \"bandwiz-system\",\n\t1930:  \"driveappserver\",\n\t1931:  \"amdsched\",\n\t1932:  \"ctt-broker\",\n\t1933:  \"xmapi\",\n\t1934:  \"xaapi\",\n\t1935:  \"macromedia-fcs\",\n\t1936:  \"jetcmeserver\",\n\t1937:  \"jwserver\",\n\t1938:  \"jwclient\",\n\t1939:  \"jvserver\",\n\t1940:  \"jvclient\",\n\t1941:  \"dic-aida\",\n\t1942:  \"res\",\n\t1943:  \"beeyond-media\",\n\t1944:  \"close-combat\",\n\t1945:  \"dialogic-elmd\",\n\t1946:  \"tekpls\",\n\t1947:  \"sentinelsrm\",\n\t1948:  \"eye2eye\",\n\t1949:  \"ismaeasdaqlive\",\n\t1950:  \"ismaeasdaqtest\",\n\t1951:  \"bcs-lmserver\",\n\t1952:  \"mpnjsc\",\n\t1953:  \"rapidbase\",\n\t1954:  \"abr-api\",\n\t1955:  \"abr-secure\",\n\t1956:  \"vrtl-vmf-ds\",\n\t1957:  \"unix-status\",\n\t1958:  \"dxadmind\",\n\t1959:  \"simp-all\",\n\t1960:  \"nasmanager\",\n\t1961:  \"bts-appserver\",\n\t1962:  \"biap-mp\",\n\t1963:  \"webmachine\",\n\t1964:  \"solid-e-engine\",\n\t1965:  \"tivoli-npm\",\n\t1966:  \"slush\",\n\t1967:  \"sns-quote\",\n\t1968:  \"lipsinc\",\n\t1969:  \"lipsinc1\",\n\t1970:  \"netop-rc\",\n\t1971:  \"netop-school\",\n\t1972:  \"intersys-cache\",\n\t1973:  \"dlsrap\",\n\t1974:  \"drp\",\n\t1975:  \"tcoflashagent\",\n\t1976:  \"tcoregagent\",\n\t1977:  \"tcoaddressbook\",\n\t1978:  \"unisql\",\n\t1979:  \"unisql-java\",\n\t1980:  \"pearldoc-xact\",\n\t1981:  \"p2pq\",\n\t1982:  \"estamp\",\n\t1983:  \"lhtp\",\n\t1984:  \"bb\",\n\t1985:  \"hsrp\",\n\t1986:  \"licensedaemon\",\n\t1987:  \"tr-rsrb-p1\",\n\t1988:  \"tr-rsrb-p2\",\n\t1989:  \"tr-rsrb-p3\",\n\t1990:  \"stun-p1\",\n\t1991:  \"stun-p2\",\n\t1992:  \"stun-p3\",\n\t1993:  \"snmp-tcp-port\",\n\t1994:  \"stun-port\",\n\t1995:  \"perf-port\",\n\t1996:  \"tr-rsrb-port\",\n\t1997:  \"gdp-port\",\n\t1998:  \"x25-svc-port\",\n\t1999:  \"tcp-id-port\",\n\t2000:  \"cisco-sccp\",\n\t2001:  \"dc\",\n\t2002:  \"globe\",\n\t2003:  \"brutus\",\n\t2004:  \"mailbox\",\n\t2005:  \"berknet\",\n\t2006:  \"invokator\",\n\t2007:  \"dectalk\",\n\t2008:  \"conf\",\n\t2009:  \"news\",\n\t2010:  \"search\",\n\t2011:  \"raid-cc\",\n\t2012:  \"ttyinfo\",\n\t2013:  \"raid-am\",\n\t2014:  \"troff\",\n\t2015:  \"cypress\",\n\t2016:  \"bootserver\",\n\t2017:  \"cypress-stat\",\n\t2018:  \"terminaldb\",\n\t2019:  \"whosockami\",\n\t2020:  \"xinupageserver\",\n\t2021:  \"servexec\",\n\t2022:  \"down\",\n\t2023:  \"xinuexpansion3\",\n\t2024:  \"xinuexpansion4\",\n\t2025:  \"ellpack\",\n\t2026:  \"scrabble\",\n\t2027:  \"shadowserver\",\n\t2028:  \"submitserver\",\n\t2029:  \"hsrpv6\",\n\t2030:  \"device2\",\n\t2031:  \"mobrien-chat\",\n\t2032:  \"blackboard\",\n\t2033:  \"glogger\",\n\t2034:  \"scoremgr\",\n\t2035:  \"imsldoc\",\n\t2036:  \"e-dpnet\",\n\t2037:  \"applus\",\n\t2038:  \"objectmanager\",\n\t2039:  \"prizma\",\n\t2040:  \"lam\",\n\t2041:  \"interbase\",\n\t2042:  \"isis\",\n\t2043:  \"isis-bcast\",\n\t2044:  \"rimsl\",\n\t2045:  \"cdfunc\",\n\t2046:  \"sdfunc\",\n\t2047:  \"dls\",\n\t2048:  \"dls-monitor\",\n\t2049:  \"shilp\",\n\t2050:  \"av-emb-config\",\n\t2051:  \"epnsdp\",\n\t2052:  \"clearvisn\",\n\t2053:  \"lot105-ds-upd\",\n\t2054:  \"weblogin\",\n\t2055:  \"iop\",\n\t2056:  \"omnisky\",\n\t2057:  \"rich-cp\",\n\t2058:  \"newwavesearch\",\n\t2059:  \"bmc-messaging\",\n\t2060:  \"teleniumdaemon\",\n\t2061:  \"netmount\",\n\t2062:  \"icg-swp\",\n\t2063:  \"icg-bridge\",\n\t2064:  \"icg-iprelay\",\n\t2065:  \"dlsrpn\",\n\t2066:  \"aura\",\n\t2067:  \"dlswpn\",\n\t2068:  \"avauthsrvprtcl\",\n\t2069:  \"event-port\",\n\t2070:  \"ah-esp-encap\",\n\t2071:  \"acp-port\",\n\t2072:  \"msync\",\n\t2073:  \"gxs-data-port\",\n\t2074:  \"vrtl-vmf-sa\",\n\t2075:  \"newlixengine\",\n\t2076:  \"newlixconfig\",\n\t2077:  \"tsrmagt\",\n\t2078:  \"tpcsrvr\",\n\t2079:  \"idware-router\",\n\t2080:  \"autodesk-nlm\",\n\t2081:  \"kme-trap-port\",\n\t2082:  \"infowave\",\n\t2083:  \"radsec\",\n\t2084:  \"sunclustergeo\",\n\t2085:  \"ada-cip\",\n\t2086:  \"gnunet\",\n\t2087:  \"eli\",\n\t2088:  \"ip-blf\",\n\t2089:  \"sep\",\n\t2090:  \"lrp\",\n\t2091:  \"prp\",\n\t2092:  \"descent3\",\n\t2093:  \"nbx-cc\",\n\t2094:  \"nbx-au\",\n\t2095:  \"nbx-ser\",\n\t2096:  \"nbx-dir\",\n\t2097:  \"jetformpreview\",\n\t2098:  \"dialog-port\",\n\t2099:  \"h2250-annex-g\",\n\t2100:  \"amiganetfs\",\n\t2101:  \"rtcm-sc104\",\n\t2102:  \"zephyr-srv\",\n\t2103:  \"zephyr-clt\",\n\t2104:  \"zephyr-hm\",\n\t2105:  \"minipay\",\n\t2106:  \"mzap\",\n\t2107:  \"bintec-admin\",\n\t2108:  \"comcam\",\n\t2109:  \"ergolight\",\n\t2110:  \"umsp\",\n\t2111:  \"dsatp\",\n\t2112:  \"idonix-metanet\",\n\t2113:  \"hsl-storm\",\n\t2114:  \"newheights\",\n\t2115:  \"kdm\",\n\t2116:  \"ccowcmr\",\n\t2117:  \"mentaclient\",\n\t2118:  \"mentaserver\",\n\t2119:  \"gsigatekeeper\",\n\t2120:  \"qencp\",\n\t2121:  \"scientia-ssdb\",\n\t2122:  \"caupc-remote\",\n\t2123:  \"gtp-control\",\n\t2124:  \"elatelink\",\n\t2125:  \"lockstep\",\n\t2126:  \"pktcable-cops\",\n\t2127:  \"index-pc-wb\",\n\t2128:  \"net-steward\",\n\t2129:  \"cs-live\",\n\t2130:  \"xds\",\n\t2131:  \"avantageb2b\",\n\t2132:  \"solera-epmap\",\n\t2133:  \"zymed-zpp\",\n\t2134:  \"avenue\",\n\t2135:  \"gris\",\n\t2136:  \"appworxsrv\",\n\t2137:  \"connect\",\n\t2138:  \"unbind-cluster\",\n\t2139:  \"ias-auth\",\n\t2140:  \"ias-reg\",\n\t2141:  \"ias-admind\",\n\t2142:  \"tdmoip\",\n\t2143:  \"lv-jc\",\n\t2144:  \"lv-ffx\",\n\t2145:  \"lv-pici\",\n\t2146:  \"lv-not\",\n\t2147:  \"lv-auth\",\n\t2148:  \"veritas-ucl\",\n\t2149:  \"acptsys\",\n\t2150:  \"dynamic3d\",\n\t2151:  \"docent\",\n\t2152:  \"gtp-user\",\n\t2153:  \"ctlptc\",\n\t2154:  \"stdptc\",\n\t2155:  \"brdptc\",\n\t2156:  \"trp\",\n\t2157:  \"xnds\",\n\t2158:  \"touchnetplus\",\n\t2159:  \"gdbremote\",\n\t2160:  \"apc-2160\",\n\t2161:  \"apc-2161\",\n\t2162:  \"navisphere\",\n\t2163:  \"navisphere-sec\",\n\t2164:  \"ddns-v3\",\n\t2165:  \"x-bone-api\",\n\t2166:  \"iwserver\",\n\t2167:  \"raw-serial\",\n\t2168:  \"easy-soft-mux\",\n\t2169:  \"brain\",\n\t2170:  \"eyetv\",\n\t2171:  \"msfw-storage\",\n\t2172:  \"msfw-s-storage\",\n\t2173:  \"msfw-replica\",\n\t2174:  \"msfw-array\",\n\t2175:  \"airsync\",\n\t2176:  \"rapi\",\n\t2177:  \"qwave\",\n\t2178:  \"bitspeer\",\n\t2179:  \"vmrdp\",\n\t2180:  \"mc-gt-srv\",\n\t2181:  \"eforward\",\n\t2182:  \"cgn-stat\",\n\t2183:  \"cgn-config\",\n\t2184:  \"nvd\",\n\t2185:  \"onbase-dds\",\n\t2186:  \"gtaua\",\n\t2187:  \"ssmc\",\n\t2188:  \"radware-rpm\",\n\t2189:  \"radware-rpm-s\",\n\t2190:  \"tivoconnect\",\n\t2191:  \"tvbus\",\n\t2192:  \"asdis\",\n\t2193:  \"drwcs\",\n\t2197:  \"mnp-exchange\",\n\t2198:  \"onehome-remote\",\n\t2199:  \"onehome-help\",\n\t2200:  \"ici\",\n\t2201:  \"ats\",\n\t2202:  \"imtc-map\",\n\t2203:  \"b2-runtime\",\n\t2204:  \"b2-license\",\n\t2205:  \"jps\",\n\t2206:  \"hpocbus\",\n\t2207:  \"hpssd\",\n\t2208:  \"hpiod\",\n\t2209:  \"rimf-ps\",\n\t2210:  \"noaaport\",\n\t2211:  \"emwin\",\n\t2212:  \"leecoposserver\",\n\t2213:  \"kali\",\n\t2214:  \"rpi\",\n\t2215:  \"ipcore\",\n\t2216:  \"vtu-comms\",\n\t2217:  \"gotodevice\",\n\t2218:  \"bounzza\",\n\t2219:  \"netiq-ncap\",\n\t2220:  \"netiq\",\n\t2221:  \"ethernet-ip-s\",\n\t2222:  \"EtherNet-IP-1\",\n\t2223:  \"rockwell-csp2\",\n\t2224:  \"efi-mg\",\n\t2225:  \"rcip-itu\",\n\t2226:  \"di-drm\",\n\t2227:  \"di-msg\",\n\t2228:  \"ehome-ms\",\n\t2229:  \"datalens\",\n\t2230:  \"queueadm\",\n\t2231:  \"wimaxasncp\",\n\t2232:  \"ivs-video\",\n\t2233:  \"infocrypt\",\n\t2234:  \"directplay\",\n\t2235:  \"sercomm-wlink\",\n\t2236:  \"nani\",\n\t2237:  \"optech-port1-lm\",\n\t2238:  \"aviva-sna\",\n\t2239:  \"imagequery\",\n\t2240:  \"recipe\",\n\t2241:  \"ivsd\",\n\t2242:  \"foliocorp\",\n\t2243:  \"magicom\",\n\t2244:  \"nmsserver\",\n\t2245:  \"hao\",\n\t2246:  \"pc-mta-addrmap\",\n\t2247:  \"antidotemgrsvr\",\n\t2248:  \"ums\",\n\t2249:  \"rfmp\",\n\t2250:  \"remote-collab\",\n\t2251:  \"dif-port\",\n\t2252:  \"njenet-ssl\",\n\t2253:  \"dtv-chan-req\",\n\t2254:  \"seispoc\",\n\t2255:  \"vrtp\",\n\t2256:  \"pcc-mfp\",\n\t2257:  \"simple-tx-rx\",\n\t2258:  \"rcts\",\n\t2260:  \"apc-2260\",\n\t2261:  \"comotionmaster\",\n\t2262:  \"comotionback\",\n\t2263:  \"ecwcfg\",\n\t2264:  \"apx500api-1\",\n\t2265:  \"apx500api-2\",\n\t2266:  \"mfserver\",\n\t2267:  \"ontobroker\",\n\t2268:  \"amt\",\n\t2269:  \"mikey\",\n\t2270:  \"starschool\",\n\t2271:  \"mmcals\",\n\t2272:  \"mmcal\",\n\t2273:  \"mysql-im\",\n\t2274:  \"pcttunnell\",\n\t2275:  \"ibridge-data\",\n\t2276:  \"ibridge-mgmt\",\n\t2277:  \"bluectrlproxy\",\n\t2278:  \"s3db\",\n\t2279:  \"xmquery\",\n\t2280:  \"lnvpoller\",\n\t2281:  \"lnvconsole\",\n\t2282:  \"lnvalarm\",\n\t2283:  \"lnvstatus\",\n\t2284:  \"lnvmaps\",\n\t2285:  \"lnvmailmon\",\n\t2286:  \"nas-metering\",\n\t2287:  \"dna\",\n\t2288:  \"netml\",\n\t2289:  \"dict-lookup\",\n\t2290:  \"sonus-logging\",\n\t2291:  \"eapsp\",\n\t2292:  \"mib-streaming\",\n\t2293:  \"npdbgmngr\",\n\t2294:  \"konshus-lm\",\n\t2295:  \"advant-lm\",\n\t2296:  \"theta-lm\",\n\t2297:  \"d2k-datamover1\",\n\t2298:  \"d2k-datamover2\",\n\t2299:  \"pc-telecommute\",\n\t2300:  \"cvmmon\",\n\t2301:  \"cpq-wbem\",\n\t2302:  \"binderysupport\",\n\t2303:  \"proxy-gateway\",\n\t2304:  \"attachmate-uts\",\n\t2305:  \"mt-scaleserver\",\n\t2306:  \"tappi-boxnet\",\n\t2307:  \"pehelp\",\n\t2308:  \"sdhelp\",\n\t2309:  \"sdserver\",\n\t2310:  \"sdclient\",\n\t2311:  \"messageservice\",\n\t2312:  \"wanscaler\",\n\t2313:  \"iapp\",\n\t2314:  \"cr-websystems\",\n\t2315:  \"precise-sft\",\n\t2316:  \"sent-lm\",\n\t2317:  \"attachmate-g32\",\n\t2318:  \"cadencecontrol\",\n\t2319:  \"infolibria\",\n\t2320:  \"siebel-ns\",\n\t2321:  \"rdlap\",\n\t2322:  \"ofsd\",\n\t2323:  \"3d-nfsd\",\n\t2324:  \"cosmocall\",\n\t2325:  \"ansysli\",\n\t2326:  \"idcp\",\n\t2327:  \"xingcsm\",\n\t2328:  \"netrix-sftm\",\n\t2329:  \"nvd\",\n\t2330:  \"tscchat\",\n\t2331:  \"agentview\",\n\t2332:  \"rcc-host\",\n\t2333:  \"snapp\",\n\t2334:  \"ace-client\",\n\t2335:  \"ace-proxy\",\n\t2336:  \"appleugcontrol\",\n\t2337:  \"ideesrv\",\n\t2338:  \"norton-lambert\",\n\t2339:  \"3com-webview\",\n\t2340:  \"wrs-registry\",\n\t2341:  \"xiostatus\",\n\t2342:  \"manage-exec\",\n\t2343:  \"nati-logos\",\n\t2344:  \"fcmsys\",\n\t2345:  \"dbm\",\n\t2346:  \"redstorm-join\",\n\t2347:  \"redstorm-find\",\n\t2348:  \"redstorm-info\",\n\t2349:  \"redstorm-diag\",\n\t2350:  \"psbserver\",\n\t2351:  \"psrserver\",\n\t2352:  \"pslserver\",\n\t2353:  \"pspserver\",\n\t2354:  \"psprserver\",\n\t2355:  \"psdbserver\",\n\t2356:  \"gxtelmd\",\n\t2357:  \"unihub-server\",\n\t2358:  \"futrix\",\n\t2359:  \"flukeserver\",\n\t2360:  \"nexstorindltd\",\n\t2361:  \"tl1\",\n\t2362:  \"digiman\",\n\t2363:  \"mediacntrlnfsd\",\n\t2364:  \"oi-2000\",\n\t2365:  \"dbref\",\n\t2366:  \"qip-login\",\n\t2367:  \"service-ctrl\",\n\t2368:  \"opentable\",\n\t2370:  \"l3-hbmon\",\n\t2371:  \"hp-rda\",\n\t2372:  \"lanmessenger\",\n\t2373:  \"remographlm\",\n\t2374:  \"hydra\",\n\t2375:  \"docker\",\n\t2376:  \"docker-s\",\n\t2377:  \"swarm\",\n\t2379:  \"etcd-client\",\n\t2380:  \"etcd-server\",\n\t2381:  \"compaq-https\",\n\t2382:  \"ms-olap3\",\n\t2383:  \"ms-olap4\",\n\t2384:  \"sd-request\",\n\t2385:  \"sd-data\",\n\t2386:  \"virtualtape\",\n\t2387:  \"vsamredirector\",\n\t2388:  \"mynahautostart\",\n\t2389:  \"ovsessionmgr\",\n\t2390:  \"rsmtp\",\n\t2391:  \"3com-net-mgmt\",\n\t2392:  \"tacticalauth\",\n\t2393:  \"ms-olap1\",\n\t2394:  \"ms-olap2\",\n\t2395:  \"lan900-remote\",\n\t2396:  \"wusage\",\n\t2397:  \"ncl\",\n\t2398:  \"orbiter\",\n\t2399:  \"fmpro-fdal\",\n\t2400:  \"opequus-server\",\n\t2401:  \"cvspserver\",\n\t2402:  \"taskmaster2000\",\n\t2403:  \"taskmaster2000\",\n\t2404:  \"iec-104\",\n\t2405:  \"trc-netpoll\",\n\t2406:  \"jediserver\",\n\t2407:  \"orion\",\n\t2408:  \"railgun-webaccl\",\n\t2409:  \"sns-protocol\",\n\t2410:  \"vrts-registry\",\n\t2411:  \"netwave-ap-mgmt\",\n\t2412:  \"cdn\",\n\t2413:  \"orion-rmi-reg\",\n\t2414:  \"beeyond\",\n\t2415:  \"codima-rtp\",\n\t2416:  \"rmtserver\",\n\t2417:  \"composit-server\",\n\t2418:  \"cas\",\n\t2419:  \"attachmate-s2s\",\n\t2420:  \"dslremote-mgmt\",\n\t2421:  \"g-talk\",\n\t2422:  \"crmsbits\",\n\t2423:  \"rnrp\",\n\t2424:  \"kofax-svr\",\n\t2425:  \"fjitsuappmgr\",\n\t2426:  \"vcmp\",\n\t2427:  \"mgcp-gateway\",\n\t2428:  \"ott\",\n\t2429:  \"ft-role\",\n\t2430:  \"venus\",\n\t2431:  \"venus-se\",\n\t2432:  \"codasrv\",\n\t2433:  \"codasrv-se\",\n\t2434:  \"pxc-epmap\",\n\t2435:  \"optilogic\",\n\t2436:  \"topx\",\n\t2437:  \"unicontrol\",\n\t2438:  \"msp\",\n\t2439:  \"sybasedbsynch\",\n\t2440:  \"spearway\",\n\t2441:  \"pvsw-inet\",\n\t2442:  \"netangel\",\n\t2443:  \"powerclientcsf\",\n\t2444:  \"btpp2sectrans\",\n\t2445:  \"dtn1\",\n\t2446:  \"bues-service\",\n\t2447:  \"ovwdb\",\n\t2448:  \"hpppssvr\",\n\t2449:  \"ratl\",\n\t2450:  \"netadmin\",\n\t2451:  \"netchat\",\n\t2452:  \"snifferclient\",\n\t2453:  \"madge-ltd\",\n\t2454:  \"indx-dds\",\n\t2455:  \"wago-io-system\",\n\t2456:  \"altav-remmgt\",\n\t2457:  \"rapido-ip\",\n\t2458:  \"griffin\",\n\t2459:  \"community\",\n\t2460:  \"ms-theater\",\n\t2461:  \"qadmifoper\",\n\t2462:  \"qadmifevent\",\n\t2463:  \"lsi-raid-mgmt\",\n\t2464:  \"direcpc-si\",\n\t2465:  \"lbm\",\n\t2466:  \"lbf\",\n\t2467:  \"high-criteria\",\n\t2468:  \"qip-msgd\",\n\t2469:  \"mti-tcs-comm\",\n\t2470:  \"taskman-port\",\n\t2471:  \"seaodbc\",\n\t2472:  \"c3\",\n\t2473:  \"aker-cdp\",\n\t2474:  \"vitalanalysis\",\n\t2475:  \"ace-server\",\n\t2476:  \"ace-svr-prop\",\n\t2477:  \"ssm-cvs\",\n\t2478:  \"ssm-cssps\",\n\t2479:  \"ssm-els\",\n\t2480:  \"powerexchange\",\n\t2481:  \"giop\",\n\t2482:  \"giop-ssl\",\n\t2483:  \"ttc\",\n\t2484:  \"ttc-ssl\",\n\t2485:  \"netobjects1\",\n\t2486:  \"netobjects2\",\n\t2487:  \"pns\",\n\t2488:  \"moy-corp\",\n\t2489:  \"tsilb\",\n\t2490:  \"qip-qdhcp\",\n\t2491:  \"conclave-cpp\",\n\t2492:  \"groove\",\n\t2493:  \"talarian-mqs\",\n\t2494:  \"bmc-ar\",\n\t2495:  \"fast-rem-serv\",\n\t2496:  \"dirgis\",\n\t2497:  \"quaddb\",\n\t2498:  \"odn-castraq\",\n\t2499:  \"unicontrol\",\n\t2500:  \"rtsserv\",\n\t2501:  \"rtsclient\",\n\t2502:  \"kentrox-prot\",\n\t2503:  \"nms-dpnss\",\n\t2504:  \"wlbs\",\n\t2505:  \"ppcontrol\",\n\t2506:  \"jbroker\",\n\t2507:  \"spock\",\n\t2508:  \"jdatastore\",\n\t2509:  \"fjmpss\",\n\t2510:  \"fjappmgrbulk\",\n\t2511:  \"metastorm\",\n\t2512:  \"citrixima\",\n\t2513:  \"citrixadmin\",\n\t2514:  \"facsys-ntp\",\n\t2515:  \"facsys-router\",\n\t2516:  \"maincontrol\",\n\t2517:  \"call-sig-trans\",\n\t2518:  \"willy\",\n\t2519:  \"globmsgsvc\",\n\t2520:  \"pvsw\",\n\t2521:  \"adaptecmgr\",\n\t2522:  \"windb\",\n\t2523:  \"qke-llc-v3\",\n\t2524:  \"optiwave-lm\",\n\t2525:  \"ms-v-worlds\",\n\t2526:  \"ema-sent-lm\",\n\t2527:  \"iqserver\",\n\t2528:  \"ncr-ccl\",\n\t2529:  \"utsftp\",\n\t2530:  \"vrcommerce\",\n\t2531:  \"ito-e-gui\",\n\t2532:  \"ovtopmd\",\n\t2533:  \"snifferserver\",\n\t2534:  \"combox-web-acc\",\n\t2535:  \"madcap\",\n\t2536:  \"btpp2audctr1\",\n\t2537:  \"upgrade\",\n\t2538:  \"vnwk-prapi\",\n\t2539:  \"vsiadmin\",\n\t2540:  \"lonworks\",\n\t2541:  \"lonworks2\",\n\t2542:  \"udrawgraph\",\n\t2543:  \"reftek\",\n\t2544:  \"novell-zen\",\n\t2545:  \"sis-emt\",\n\t2546:  \"vytalvaultbrtp\",\n\t2547:  \"vytalvaultvsmp\",\n\t2548:  \"vytalvaultpipe\",\n\t2549:  \"ipass\",\n\t2550:  \"ads\",\n\t2551:  \"isg-uda-server\",\n\t2552:  \"call-logging\",\n\t2553:  \"efidiningport\",\n\t2554:  \"vcnet-link-v10\",\n\t2555:  \"compaq-wcp\",\n\t2556:  \"nicetec-nmsvc\",\n\t2557:  \"nicetec-mgmt\",\n\t2558:  \"pclemultimedia\",\n\t2559:  \"lstp\",\n\t2560:  \"labrat\",\n\t2561:  \"mosaixcc\",\n\t2562:  \"delibo\",\n\t2563:  \"cti-redwood\",\n\t2564:  \"hp-3000-telnet\",\n\t2565:  \"coord-svr\",\n\t2566:  \"pcs-pcw\",\n\t2567:  \"clp\",\n\t2568:  \"spamtrap\",\n\t2569:  \"sonuscallsig\",\n\t2570:  \"hs-port\",\n\t2571:  \"cecsvc\",\n\t2572:  \"ibp\",\n\t2573:  \"trustestablish\",\n\t2574:  \"blockade-bpsp\",\n\t2575:  \"hl7\",\n\t2576:  \"tclprodebugger\",\n\t2577:  \"scipticslsrvr\",\n\t2578:  \"rvs-isdn-dcp\",\n\t2579:  \"mpfoncl\",\n\t2580:  \"tributary\",\n\t2581:  \"argis-te\",\n\t2582:  \"argis-ds\",\n\t2583:  \"mon\",\n\t2584:  \"cyaserv\",\n\t2585:  \"netx-server\",\n\t2586:  \"netx-agent\",\n\t2587:  \"masc\",\n\t2588:  \"privilege\",\n\t2589:  \"quartus-tcl\",\n\t2590:  \"idotdist\",\n\t2591:  \"maytagshuffle\",\n\t2592:  \"netrek\",\n\t2593:  \"mns-mail\",\n\t2594:  \"dts\",\n\t2595:  \"worldfusion1\",\n\t2596:  \"worldfusion2\",\n\t2597:  \"homesteadglory\",\n\t2598:  \"citriximaclient\",\n\t2599:  \"snapd\",\n\t2600:  \"hpstgmgr\",\n\t2601:  \"discp-client\",\n\t2602:  \"discp-server\",\n\t2603:  \"servicemeter\",\n\t2604:  \"nsc-ccs\",\n\t2605:  \"nsc-posa\",\n\t2606:  \"netmon\",\n\t2607:  \"connection\",\n\t2608:  \"wag-service\",\n\t2609:  \"system-monitor\",\n\t2610:  \"versa-tek\",\n\t2611:  \"lionhead\",\n\t2612:  \"qpasa-agent\",\n\t2613:  \"smntubootstrap\",\n\t2614:  \"neveroffline\",\n\t2615:  \"firepower\",\n\t2616:  \"appswitch-emp\",\n\t2617:  \"cmadmin\",\n\t2618:  \"priority-e-com\",\n\t2619:  \"bruce\",\n\t2620:  \"lpsrecommender\",\n\t2621:  \"miles-apart\",\n\t2622:  \"metricadbc\",\n\t2623:  \"lmdp\",\n\t2624:  \"aria\",\n\t2625:  \"blwnkl-port\",\n\t2626:  \"gbjd816\",\n\t2627:  \"moshebeeri\",\n\t2628:  \"dict\",\n\t2629:  \"sitaraserver\",\n\t2630:  \"sitaramgmt\",\n\t2631:  \"sitaradir\",\n\t2632:  \"irdg-post\",\n\t2633:  \"interintelli\",\n\t2634:  \"pk-electronics\",\n\t2635:  \"backburner\",\n\t2636:  \"solve\",\n\t2637:  \"imdocsvc\",\n\t2638:  \"sybaseanywhere\",\n\t2639:  \"aminet\",\n\t2640:  \"ami-control\",\n\t2641:  \"hdl-srv\",\n\t2642:  \"tragic\",\n\t2643:  \"gte-samp\",\n\t2644:  \"travsoft-ipx-t\",\n\t2645:  \"novell-ipx-cmd\",\n\t2646:  \"and-lm\",\n\t2647:  \"syncserver\",\n\t2648:  \"upsnotifyprot\",\n\t2649:  \"vpsipport\",\n\t2650:  \"eristwoguns\",\n\t2651:  \"ebinsite\",\n\t2652:  \"interpathpanel\",\n\t2653:  \"sonus\",\n\t2654:  \"corel-vncadmin\",\n\t2655:  \"unglue\",\n\t2656:  \"kana\",\n\t2657:  \"sns-dispatcher\",\n\t2658:  \"sns-admin\",\n\t2659:  \"sns-query\",\n\t2660:  \"gcmonitor\",\n\t2661:  \"olhost\",\n\t2662:  \"bintec-capi\",\n\t2663:  \"bintec-tapi\",\n\t2664:  \"patrol-mq-gm\",\n\t2665:  \"patrol-mq-nm\",\n\t2666:  \"extensis\",\n\t2667:  \"alarm-clock-s\",\n\t2668:  \"alarm-clock-c\",\n\t2669:  \"toad\",\n\t2670:  \"tve-announce\",\n\t2671:  \"newlixreg\",\n\t2672:  \"nhserver\",\n\t2673:  \"firstcall42\",\n\t2674:  \"ewnn\",\n\t2675:  \"ttc-etap\",\n\t2676:  \"simslink\",\n\t2677:  \"gadgetgate1way\",\n\t2678:  \"gadgetgate2way\",\n\t2679:  \"syncserverssl\",\n\t2680:  \"pxc-sapxom\",\n\t2681:  \"mpnjsomb\",\n\t2683:  \"ncdloadbalance\",\n\t2684:  \"mpnjsosv\",\n\t2685:  \"mpnjsocl\",\n\t2686:  \"mpnjsomg\",\n\t2687:  \"pq-lic-mgmt\",\n\t2688:  \"md-cg-http\",\n\t2689:  \"fastlynx\",\n\t2690:  \"hp-nnm-data\",\n\t2691:  \"itinternet\",\n\t2692:  \"admins-lms\",\n\t2694:  \"pwrsevent\",\n\t2695:  \"vspread\",\n\t2696:  \"unifyadmin\",\n\t2697:  \"oce-snmp-trap\",\n\t2698:  \"mck-ivpip\",\n\t2699:  \"csoft-plusclnt\",\n\t2700:  \"tqdata\",\n\t2701:  \"sms-rcinfo\",\n\t2702:  \"sms-xfer\",\n\t2703:  \"sms-chat\",\n\t2704:  \"sms-remctrl\",\n\t2705:  \"sds-admin\",\n\t2706:  \"ncdmirroring\",\n\t2707:  \"emcsymapiport\",\n\t2708:  \"banyan-net\",\n\t2709:  \"supermon\",\n\t2710:  \"sso-service\",\n\t2711:  \"sso-control\",\n\t2712:  \"aocp\",\n\t2713:  \"raventbs\",\n\t2714:  \"raventdm\",\n\t2715:  \"hpstgmgr2\",\n\t2716:  \"inova-ip-disco\",\n\t2717:  \"pn-requester\",\n\t2718:  \"pn-requester2\",\n\t2719:  \"scan-change\",\n\t2720:  \"wkars\",\n\t2721:  \"smart-diagnose\",\n\t2722:  \"proactivesrvr\",\n\t2723:  \"watchdog-nt\",\n\t2724:  \"qotps\",\n\t2725:  \"msolap-ptp2\",\n\t2726:  \"tams\",\n\t2727:  \"mgcp-callagent\",\n\t2728:  \"sqdr\",\n\t2729:  \"tcim-control\",\n\t2730:  \"nec-raidplus\",\n\t2731:  \"fyre-messanger\",\n\t2732:  \"g5m\",\n\t2733:  \"signet-ctf\",\n\t2734:  \"ccs-software\",\n\t2735:  \"netiq-mc\",\n\t2736:  \"radwiz-nms-srv\",\n\t2737:  \"srp-feedback\",\n\t2738:  \"ndl-tcp-ois-gw\",\n\t2739:  \"tn-timing\",\n\t2740:  \"alarm\",\n\t2741:  \"tsb\",\n\t2742:  \"tsb2\",\n\t2743:  \"murx\",\n\t2744:  \"honyaku\",\n\t2745:  \"urbisnet\",\n\t2746:  \"cpudpencap\",\n\t2747:  \"fjippol-swrly\",\n\t2748:  \"fjippol-polsvr\",\n\t2749:  \"fjippol-cnsl\",\n\t2750:  \"fjippol-port1\",\n\t2751:  \"fjippol-port2\",\n\t2752:  \"rsisysaccess\",\n\t2753:  \"de-spot\",\n\t2754:  \"apollo-cc\",\n\t2755:  \"expresspay\",\n\t2756:  \"simplement-tie\",\n\t2757:  \"cnrp\",\n\t2758:  \"apollo-status\",\n\t2759:  \"apollo-gms\",\n\t2760:  \"sabams\",\n\t2761:  \"dicom-iscl\",\n\t2762:  \"dicom-tls\",\n\t2763:  \"desktop-dna\",\n\t2764:  \"data-insurance\",\n\t2765:  \"qip-audup\",\n\t2766:  \"compaq-scp\",\n\t2767:  \"uadtc\",\n\t2768:  \"uacs\",\n\t2769:  \"exce\",\n\t2770:  \"veronica\",\n\t2771:  \"vergencecm\",\n\t2772:  \"auris\",\n\t2773:  \"rbakcup1\",\n\t2774:  \"rbakcup2\",\n\t2775:  \"smpp\",\n\t2776:  \"ridgeway1\",\n\t2777:  \"ridgeway2\",\n\t2778:  \"gwen-sonya\",\n\t2779:  \"lbc-sync\",\n\t2780:  \"lbc-control\",\n\t2781:  \"whosells\",\n\t2782:  \"everydayrc\",\n\t2783:  \"aises\",\n\t2784:  \"www-dev\",\n\t2785:  \"aic-np\",\n\t2786:  \"aic-oncrpc\",\n\t2787:  \"piccolo\",\n\t2788:  \"fryeserv\",\n\t2789:  \"media-agent\",\n\t2790:  \"plgproxy\",\n\t2791:  \"mtport-regist\",\n\t2792:  \"f5-globalsite\",\n\t2793:  \"initlsmsad\",\n\t2795:  \"livestats\",\n\t2796:  \"ac-tech\",\n\t2797:  \"esp-encap\",\n\t2798:  \"tmesis-upshot\",\n\t2799:  \"icon-discover\",\n\t2800:  \"acc-raid\",\n\t2801:  \"igcp\",\n\t2802:  \"veritas-tcp1\",\n\t2803:  \"btprjctrl\",\n\t2804:  \"dvr-esm\",\n\t2805:  \"wta-wsp-s\",\n\t2806:  \"cspuni\",\n\t2807:  \"cspmulti\",\n\t2808:  \"j-lan-p\",\n\t2809:  \"corbaloc\",\n\t2810:  \"netsteward\",\n\t2811:  \"gsiftp\",\n\t2812:  \"atmtcp\",\n\t2813:  \"llm-pass\",\n\t2814:  \"llm-csv\",\n\t2815:  \"lbc-measure\",\n\t2816:  \"lbc-watchdog\",\n\t2817:  \"nmsigport\",\n\t2818:  \"rmlnk\",\n\t2819:  \"fc-faultnotify\",\n\t2820:  \"univision\",\n\t2821:  \"vrts-at-port\",\n\t2822:  \"ka0wuc\",\n\t2823:  \"cqg-netlan\",\n\t2824:  \"cqg-netlan-1\",\n\t2826:  \"slc-systemlog\",\n\t2827:  \"slc-ctrlrloops\",\n\t2828:  \"itm-lm\",\n\t2829:  \"silkp1\",\n\t2830:  \"silkp2\",\n\t2831:  \"silkp3\",\n\t2832:  \"silkp4\",\n\t2833:  \"glishd\",\n\t2834:  \"evtp\",\n\t2835:  \"evtp-data\",\n\t2836:  \"catalyst\",\n\t2837:  \"repliweb\",\n\t2838:  \"starbot\",\n\t2839:  \"nmsigport\",\n\t2840:  \"l3-exprt\",\n\t2841:  \"l3-ranger\",\n\t2842:  \"l3-hawk\",\n\t2843:  \"pdnet\",\n\t2844:  \"bpcp-poll\",\n\t2845:  \"bpcp-trap\",\n\t2846:  \"aimpp-hello\",\n\t2847:  \"aimpp-port-req\",\n\t2848:  \"amt-blc-port\",\n\t2849:  \"fxp\",\n\t2850:  \"metaconsole\",\n\t2851:  \"webemshttp\",\n\t2852:  \"bears-01\",\n\t2853:  \"ispipes\",\n\t2854:  \"infomover\",\n\t2855:  \"msrp\",\n\t2856:  \"cesdinv\",\n\t2857:  \"simctlp\",\n\t2858:  \"ecnp\",\n\t2859:  \"activememory\",\n\t2860:  \"dialpad-voice1\",\n\t2861:  \"dialpad-voice2\",\n\t2862:  \"ttg-protocol\",\n\t2863:  \"sonardata\",\n\t2864:  \"astromed-main\",\n\t2865:  \"pit-vpn\",\n\t2866:  \"iwlistener\",\n\t2867:  \"esps-portal\",\n\t2868:  \"npep-messaging\",\n\t2869:  \"icslap\",\n\t2870:  \"daishi\",\n\t2871:  \"msi-selectplay\",\n\t2872:  \"radix\",\n\t2874:  \"dxmessagebase1\",\n\t2875:  \"dxmessagebase2\",\n\t2876:  \"sps-tunnel\",\n\t2877:  \"bluelance\",\n\t2878:  \"aap\",\n\t2879:  \"ucentric-ds\",\n\t2880:  \"synapse\",\n\t2881:  \"ndsp\",\n\t2882:  \"ndtp\",\n\t2883:  \"ndnp\",\n\t2884:  \"flashmsg\",\n\t2885:  \"topflow\",\n\t2886:  \"responselogic\",\n\t2887:  \"aironetddp\",\n\t2888:  \"spcsdlobby\",\n\t2889:  \"rsom\",\n\t2890:  \"cspclmulti\",\n\t2891:  \"cinegrfx-elmd\",\n\t2892:  \"snifferdata\",\n\t2893:  \"vseconnector\",\n\t2894:  \"abacus-remote\",\n\t2895:  \"natuslink\",\n\t2896:  \"ecovisiong6-1\",\n\t2897:  \"citrix-rtmp\",\n\t2898:  \"appliance-cfg\",\n\t2899:  \"powergemplus\",\n\t2900:  \"quicksuite\",\n\t2901:  \"allstorcns\",\n\t2902:  \"netaspi\",\n\t2903:  \"suitcase\",\n\t2904:  \"m2ua\",\n\t2905:  \"m3ua\",\n\t2906:  \"caller9\",\n\t2907:  \"webmethods-b2b\",\n\t2908:  \"mao\",\n\t2909:  \"funk-dialout\",\n\t2910:  \"tdaccess\",\n\t2911:  \"blockade\",\n\t2912:  \"epicon\",\n\t2913:  \"boosterware\",\n\t2914:  \"gamelobby\",\n\t2915:  \"tksocket\",\n\t2916:  \"elvin-server\",\n\t2917:  \"elvin-client\",\n\t2918:  \"kastenchasepad\",\n\t2919:  \"roboer\",\n\t2920:  \"roboeda\",\n\t2921:  \"cesdcdman\",\n\t2922:  \"cesdcdtrn\",\n\t2923:  \"wta-wsp-wtp-s\",\n\t2924:  \"precise-vip\",\n\t2926:  \"mobile-file-dl\",\n\t2927:  \"unimobilectrl\",\n\t2928:  \"redstone-cpss\",\n\t2929:  \"amx-webadmin\",\n\t2930:  \"amx-weblinx\",\n\t2931:  \"circle-x\",\n\t2932:  \"incp\",\n\t2933:  \"4-tieropmgw\",\n\t2934:  \"4-tieropmcli\",\n\t2935:  \"qtp\",\n\t2936:  \"otpatch\",\n\t2937:  \"pnaconsult-lm\",\n\t2938:  \"sm-pas-1\",\n\t2939:  \"sm-pas-2\",\n\t2940:  \"sm-pas-3\",\n\t2941:  \"sm-pas-4\",\n\t2942:  \"sm-pas-5\",\n\t2943:  \"ttnrepository\",\n\t2944:  \"megaco-h248\",\n\t2945:  \"h248-binary\",\n\t2946:  \"fjsvmpor\",\n\t2947:  \"gpsd\",\n\t2948:  \"wap-push\",\n\t2949:  \"wap-pushsecure\",\n\t2950:  \"esip\",\n\t2951:  \"ottp\",\n\t2952:  \"mpfwsas\",\n\t2953:  \"ovalarmsrv\",\n\t2954:  \"ovalarmsrv-cmd\",\n\t2955:  \"csnotify\",\n\t2956:  \"ovrimosdbman\",\n\t2957:  \"jmact5\",\n\t2958:  \"jmact6\",\n\t2959:  \"rmopagt\",\n\t2960:  \"dfoxserver\",\n\t2961:  \"boldsoft-lm\",\n\t2962:  \"iph-policy-cli\",\n\t2963:  \"iph-policy-adm\",\n\t2964:  \"bullant-srap\",\n\t2965:  \"bullant-rap\",\n\t2966:  \"idp-infotrieve\",\n\t2967:  \"ssc-agent\",\n\t2968:  \"enpp\",\n\t2969:  \"essp\",\n\t2970:  \"index-net\",\n\t2971:  \"netclip\",\n\t2972:  \"pmsm-webrctl\",\n\t2973:  \"svnetworks\",\n\t2974:  \"signal\",\n\t2975:  \"fjmpcm\",\n\t2976:  \"cns-srv-port\",\n\t2977:  \"ttc-etap-ns\",\n\t2978:  \"ttc-etap-ds\",\n\t2979:  \"h263-video\",\n\t2980:  \"wimd\",\n\t2981:  \"mylxamport\",\n\t2982:  \"iwb-whiteboard\",\n\t2983:  \"netplan\",\n\t2984:  \"hpidsadmin\",\n\t2985:  \"hpidsagent\",\n\t2986:  \"stonefalls\",\n\t2987:  \"identify\",\n\t2988:  \"hippad\",\n\t2989:  \"zarkov\",\n\t2990:  \"boscap\",\n\t2991:  \"wkstn-mon\",\n\t2992:  \"avenyo\",\n\t2993:  \"veritas-vis1\",\n\t2994:  \"veritas-vis2\",\n\t2995:  \"idrs\",\n\t2996:  \"vsixml\",\n\t2997:  \"rebol\",\n\t2998:  \"realsecure\",\n\t2999:  \"remoteware-un\",\n\t3000:  \"hbci\",\n\t3001:  \"origo-native\",\n\t3002:  \"exlm-agent\",\n\t3003:  \"cgms\",\n\t3004:  \"csoftragent\",\n\t3005:  \"geniuslm\",\n\t3006:  \"ii-admin\",\n\t3007:  \"lotusmtap\",\n\t3008:  \"midnight-tech\",\n\t3009:  \"pxc-ntfy\",\n\t3010:  \"gw\",\n\t3011:  \"trusted-web\",\n\t3012:  \"twsdss\",\n\t3013:  \"gilatskysurfer\",\n\t3014:  \"broker-service\",\n\t3015:  \"nati-dstp\",\n\t3016:  \"notify-srvr\",\n\t3017:  \"event-listener\",\n\t3018:  \"srvc-registry\",\n\t3019:  \"resource-mgr\",\n\t3020:  \"cifs\",\n\t3021:  \"agriserver\",\n\t3022:  \"csregagent\",\n\t3023:  \"magicnotes\",\n\t3024:  \"nds-sso\",\n\t3025:  \"arepa-raft\",\n\t3026:  \"agri-gateway\",\n\t3027:  \"LiebDevMgmt-C\",\n\t3028:  \"LiebDevMgmt-DM\",\n\t3029:  \"LiebDevMgmt-A\",\n\t3030:  \"arepa-cas\",\n\t3031:  \"eppc\",\n\t3032:  \"redwood-chat\",\n\t3033:  \"pdb\",\n\t3034:  \"osmosis-aeea\",\n\t3035:  \"fjsv-gssagt\",\n\t3036:  \"hagel-dump\",\n\t3037:  \"hp-san-mgmt\",\n\t3038:  \"santak-ups\",\n\t3039:  \"cogitate\",\n\t3040:  \"tomato-springs\",\n\t3041:  \"di-traceware\",\n\t3042:  \"journee\",\n\t3043:  \"brp\",\n\t3044:  \"epp\",\n\t3045:  \"responsenet\",\n\t3046:  \"di-ase\",\n\t3047:  \"hlserver\",\n\t3048:  \"pctrader\",\n\t3049:  \"nsws\",\n\t3050:  \"gds-db\",\n\t3051:  \"galaxy-server\",\n\t3052:  \"apc-3052\",\n\t3053:  \"dsom-server\",\n\t3054:  \"amt-cnf-prot\",\n\t3055:  \"policyserver\",\n\t3056:  \"cdl-server\",\n\t3057:  \"goahead-fldup\",\n\t3058:  \"videobeans\",\n\t3059:  \"qsoft\",\n\t3060:  \"interserver\",\n\t3061:  \"cautcpd\",\n\t3062:  \"ncacn-ip-tcp\",\n\t3063:  \"ncadg-ip-udp\",\n\t3064:  \"rprt\",\n\t3065:  \"slinterbase\",\n\t3066:  \"netattachsdmp\",\n\t3067:  \"fjhpjp\",\n\t3068:  \"ls3bcast\",\n\t3069:  \"ls3\",\n\t3070:  \"mgxswitch\",\n\t3071:  \"xplat-replicate\",\n\t3072:  \"csd-monitor\",\n\t3073:  \"vcrp\",\n\t3074:  \"xbox\",\n\t3075:  \"orbix-locator\",\n\t3076:  \"orbix-config\",\n\t3077:  \"orbix-loc-ssl\",\n\t3078:  \"orbix-cfg-ssl\",\n\t3079:  \"lv-frontpanel\",\n\t3080:  \"stm-pproc\",\n\t3081:  \"tl1-lv\",\n\t3082:  \"tl1-raw\",\n\t3083:  \"tl1-telnet\",\n\t3084:  \"itm-mccs\",\n\t3085:  \"pcihreq\",\n\t3086:  \"jdl-dbkitchen\",\n\t3087:  \"asoki-sma\",\n\t3088:  \"xdtp\",\n\t3089:  \"ptk-alink\",\n\t3090:  \"stss\",\n\t3091:  \"1ci-smcs\",\n\t3093:  \"rapidmq-center\",\n\t3094:  \"rapidmq-reg\",\n\t3095:  \"panasas\",\n\t3096:  \"ndl-aps\",\n\t3098:  \"umm-port\",\n\t3099:  \"chmd\",\n\t3100:  \"opcon-xps\",\n\t3101:  \"hp-pxpib\",\n\t3102:  \"slslavemon\",\n\t3103:  \"autocuesmi\",\n\t3104:  \"autocuelog\",\n\t3105:  \"cardbox\",\n\t3106:  \"cardbox-http\",\n\t3107:  \"business\",\n\t3108:  \"geolocate\",\n\t3109:  \"personnel\",\n\t3110:  \"sim-control\",\n\t3111:  \"wsynch\",\n\t3112:  \"ksysguard\",\n\t3113:  \"cs-auth-svr\",\n\t3114:  \"ccmad\",\n\t3115:  \"mctet-master\",\n\t3116:  \"mctet-gateway\",\n\t3117:  \"mctet-jserv\",\n\t3118:  \"pkagent\",\n\t3119:  \"d2000kernel\",\n\t3120:  \"d2000webserver\",\n\t3121:  \"pcmk-remote\",\n\t3122:  \"vtr-emulator\",\n\t3123:  \"edix\",\n\t3124:  \"beacon-port\",\n\t3125:  \"a13-an\",\n\t3127:  \"ctx-bridge\",\n\t3128:  \"ndl-aas\",\n\t3129:  \"netport-id\",\n\t3130:  \"icpv2\",\n\t3131:  \"netbookmark\",\n\t3132:  \"ms-rule-engine\",\n\t3133:  \"prism-deploy\",\n\t3134:  \"ecp\",\n\t3135:  \"peerbook-port\",\n\t3136:  \"grubd\",\n\t3137:  \"rtnt-1\",\n\t3138:  \"rtnt-2\",\n\t3139:  \"incognitorv\",\n\t3140:  \"ariliamulti\",\n\t3141:  \"vmodem\",\n\t3142:  \"rdc-wh-eos\",\n\t3143:  \"seaview\",\n\t3144:  \"tarantella\",\n\t3145:  \"csi-lfap\",\n\t3146:  \"bears-02\",\n\t3147:  \"rfio\",\n\t3148:  \"nm-game-admin\",\n\t3149:  \"nm-game-server\",\n\t3150:  \"nm-asses-admin\",\n\t3151:  \"nm-assessor\",\n\t3152:  \"feitianrockey\",\n\t3153:  \"s8-client-port\",\n\t3154:  \"ccmrmi\",\n\t3155:  \"jpegmpeg\",\n\t3156:  \"indura\",\n\t3157:  \"e3consultants\",\n\t3158:  \"stvp\",\n\t3159:  \"navegaweb-port\",\n\t3160:  \"tip-app-server\",\n\t3161:  \"doc1lm\",\n\t3162:  \"sflm\",\n\t3163:  \"res-sap\",\n\t3164:  \"imprs\",\n\t3165:  \"newgenpay\",\n\t3166:  \"sossecollector\",\n\t3167:  \"nowcontact\",\n\t3168:  \"poweronnud\",\n\t3169:  \"serverview-as\",\n\t3170:  \"serverview-asn\",\n\t3171:  \"serverview-gf\",\n\t3172:  \"serverview-rm\",\n\t3173:  \"serverview-icc\",\n\t3174:  \"armi-server\",\n\t3175:  \"t1-e1-over-ip\",\n\t3176:  \"ars-master\",\n\t3177:  \"phonex-port\",\n\t3178:  \"radclientport\",\n\t3179:  \"h2gf-w-2m\",\n\t3180:  \"mc-brk-srv\",\n\t3181:  \"bmcpatrolagent\",\n\t3182:  \"bmcpatrolrnvu\",\n\t3183:  \"cops-tls\",\n\t3184:  \"apogeex-port\",\n\t3185:  \"smpppd\",\n\t3186:  \"iiw-port\",\n\t3187:  \"odi-port\",\n\t3188:  \"brcm-comm-port\",\n\t3189:  \"pcle-infex\",\n\t3190:  \"csvr-proxy\",\n\t3191:  \"csvr-sslproxy\",\n\t3192:  \"firemonrcc\",\n\t3193:  \"spandataport\",\n\t3194:  \"magbind\",\n\t3195:  \"ncu-1\",\n\t3196:  \"ncu-2\",\n\t3197:  \"embrace-dp-s\",\n\t3198:  \"embrace-dp-c\",\n\t3199:  \"dmod-workspace\",\n\t3200:  \"tick-port\",\n\t3201:  \"cpq-tasksmart\",\n\t3202:  \"intraintra\",\n\t3203:  \"netwatcher-mon\",\n\t3204:  \"netwatcher-db\",\n\t3205:  \"isns\",\n\t3206:  \"ironmail\",\n\t3207:  \"vx-auth-port\",\n\t3208:  \"pfu-prcallback\",\n\t3209:  \"netwkpathengine\",\n\t3210:  \"flamenco-proxy\",\n\t3211:  \"avsecuremgmt\",\n\t3212:  \"surveyinst\",\n\t3213:  \"neon24x7\",\n\t3214:  \"jmq-daemon-1\",\n\t3215:  \"jmq-daemon-2\",\n\t3216:  \"ferrari-foam\",\n\t3217:  \"unite\",\n\t3218:  \"smartpackets\",\n\t3219:  \"wms-messenger\",\n\t3220:  \"xnm-ssl\",\n\t3221:  \"xnm-clear-text\",\n\t3222:  \"glbp\",\n\t3223:  \"digivote\",\n\t3224:  \"aes-discovery\",\n\t3225:  \"fcip-port\",\n\t3226:  \"isi-irp\",\n\t3227:  \"dwnmshttp\",\n\t3228:  \"dwmsgserver\",\n\t3229:  \"global-cd-port\",\n\t3230:  \"sftdst-port\",\n\t3231:  \"vidigo\",\n\t3232:  \"mdtp\",\n\t3233:  \"whisker\",\n\t3234:  \"alchemy\",\n\t3235:  \"mdap-port\",\n\t3236:  \"apparenet-ts\",\n\t3237:  \"apparenet-tps\",\n\t3238:  \"apparenet-as\",\n\t3239:  \"apparenet-ui\",\n\t3240:  \"triomotion\",\n\t3241:  \"sysorb\",\n\t3242:  \"sdp-id-port\",\n\t3243:  \"timelot\",\n\t3244:  \"onesaf\",\n\t3245:  \"vieo-fe\",\n\t3246:  \"dvt-system\",\n\t3247:  \"dvt-data\",\n\t3248:  \"procos-lm\",\n\t3249:  \"ssp\",\n\t3250:  \"hicp\",\n\t3251:  \"sysscanner\",\n\t3252:  \"dhe\",\n\t3253:  \"pda-data\",\n\t3254:  \"pda-sys\",\n\t3255:  \"semaphore\",\n\t3256:  \"cpqrpm-agent\",\n\t3257:  \"cpqrpm-server\",\n\t3258:  \"ivecon-port\",\n\t3259:  \"epncdp2\",\n\t3260:  \"iscsi-target\",\n\t3261:  \"winshadow\",\n\t3262:  \"necp\",\n\t3263:  \"ecolor-imager\",\n\t3264:  \"ccmail\",\n\t3265:  \"altav-tunnel\",\n\t3266:  \"ns-cfg-server\",\n\t3267:  \"ibm-dial-out\",\n\t3268:  \"msft-gc\",\n\t3269:  \"msft-gc-ssl\",\n\t3270:  \"verismart\",\n\t3271:  \"csoft-prev\",\n\t3272:  \"user-manager\",\n\t3273:  \"sxmp\",\n\t3274:  \"ordinox-server\",\n\t3275:  \"samd\",\n\t3276:  \"maxim-asics\",\n\t3277:  \"awg-proxy\",\n\t3278:  \"lkcmserver\",\n\t3279:  \"admind\",\n\t3280:  \"vs-server\",\n\t3281:  \"sysopt\",\n\t3282:  \"datusorb\",\n\t3283:  \"Apple Remote Desktop (Net Assistant)\",\n\t3284:  \"4talk\",\n\t3285:  \"plato\",\n\t3286:  \"e-net\",\n\t3287:  \"directvdata\",\n\t3288:  \"cops\",\n\t3289:  \"enpc\",\n\t3290:  \"caps-lm\",\n\t3291:  \"sah-lm\",\n\t3292:  \"cart-o-rama\",\n\t3293:  \"fg-fps\",\n\t3294:  \"fg-gip\",\n\t3295:  \"dyniplookup\",\n\t3296:  \"rib-slm\",\n\t3297:  \"cytel-lm\",\n\t3298:  \"deskview\",\n\t3299:  \"pdrncs\",\n\t3300:  \"ceph\",\n\t3302:  \"mcs-fastmail\",\n\t3303:  \"opsession-clnt\",\n\t3304:  \"opsession-srvr\",\n\t3305:  \"odette-ftp\",\n\t3306:  \"mysql\",\n\t3307:  \"opsession-prxy\",\n\t3308:  \"tns-server\",\n\t3309:  \"tns-adv\",\n\t3310:  \"dyna-access\",\n\t3311:  \"mcns-tel-ret\",\n\t3312:  \"appman-server\",\n\t3313:  \"uorb\",\n\t3314:  \"uohost\",\n\t3315:  \"cdid\",\n\t3316:  \"aicc-cmi\",\n\t3317:  \"vsaiport\",\n\t3318:  \"ssrip\",\n\t3319:  \"sdt-lmd\",\n\t3320:  \"officelink2000\",\n\t3321:  \"vnsstr\",\n\t3326:  \"sftu\",\n\t3327:  \"bbars\",\n\t3328:  \"egptlm\",\n\t3329:  \"hp-device-disc\",\n\t3330:  \"mcs-calypsoicf\",\n\t3331:  \"mcs-messaging\",\n\t3332:  \"mcs-mailsvr\",\n\t3333:  \"dec-notes\",\n\t3334:  \"directv-web\",\n\t3335:  \"directv-soft\",\n\t3336:  \"directv-tick\",\n\t3337:  \"directv-catlg\",\n\t3338:  \"anet-b\",\n\t3339:  \"anet-l\",\n\t3340:  \"anet-m\",\n\t3341:  \"anet-h\",\n\t3342:  \"webtie\",\n\t3343:  \"ms-cluster-net\",\n\t3344:  \"bnt-manager\",\n\t3345:  \"influence\",\n\t3346:  \"trnsprntproxy\",\n\t3347:  \"phoenix-rpc\",\n\t3348:  \"pangolin-laser\",\n\t3349:  \"chevinservices\",\n\t3350:  \"findviatv\",\n\t3351:  \"btrieve\",\n\t3352:  \"ssql\",\n\t3353:  \"fatpipe\",\n\t3354:  \"suitjd\",\n\t3355:  \"ordinox-dbase\",\n\t3356:  \"upnotifyps\",\n\t3357:  \"adtech-test\",\n\t3358:  \"mpsysrmsvr\",\n\t3359:  \"wg-netforce\",\n\t3360:  \"kv-server\",\n\t3361:  \"kv-agent\",\n\t3362:  \"dj-ilm\",\n\t3363:  \"nati-vi-server\",\n\t3364:  \"creativeserver\",\n\t3365:  \"contentserver\",\n\t3366:  \"creativepartnr\",\n\t3372:  \"tip2\",\n\t3373:  \"lavenir-lm\",\n\t3374:  \"cluster-disc\",\n\t3375:  \"vsnm-agent\",\n\t3376:  \"cdbroker\",\n\t3377:  \"cogsys-lm\",\n\t3378:  \"wsicopy\",\n\t3379:  \"socorfs\",\n\t3380:  \"sns-channels\",\n\t3381:  \"geneous\",\n\t3382:  \"fujitsu-neat\",\n\t3383:  \"esp-lm\",\n\t3384:  \"hp-clic\",\n\t3385:  \"qnxnetman\",\n\t3386:  \"gprs-data\",\n\t3387:  \"backroomnet\",\n\t3388:  \"cbserver\",\n\t3389:  \"ms-wbt-server\",\n\t3390:  \"dsc\",\n\t3391:  \"savant\",\n\t3392:  \"efi-lm\",\n\t3393:  \"d2k-tapestry1\",\n\t3394:  \"d2k-tapestry2\",\n\t3395:  \"dyna-lm\",\n\t3396:  \"printer-agent\",\n\t3397:  \"cloanto-lm\",\n\t3398:  \"mercantile\",\n\t3399:  \"csms\",\n\t3400:  \"csms2\",\n\t3401:  \"filecast\",\n\t3402:  \"fxaengine-net\",\n\t3405:  \"nokia-ann-ch1\",\n\t3406:  \"nokia-ann-ch2\",\n\t3407:  \"ldap-admin\",\n\t3408:  \"BESApi\",\n\t3409:  \"networklens\",\n\t3410:  \"networklenss\",\n\t3411:  \"biolink-auth\",\n\t3412:  \"xmlblaster\",\n\t3413:  \"svnet\",\n\t3414:  \"wip-port\",\n\t3415:  \"bcinameservice\",\n\t3416:  \"commandport\",\n\t3417:  \"csvr\",\n\t3418:  \"rnmap\",\n\t3419:  \"softaudit\",\n\t3420:  \"ifcp-port\",\n\t3421:  \"bmap\",\n\t3422:  \"rusb-sys-port\",\n\t3423:  \"xtrm\",\n\t3424:  \"xtrms\",\n\t3425:  \"agps-port\",\n\t3426:  \"arkivio\",\n\t3427:  \"websphere-snmp\",\n\t3428:  \"twcss\",\n\t3429:  \"gcsp\",\n\t3430:  \"ssdispatch\",\n\t3431:  \"ndl-als\",\n\t3432:  \"osdcp\",\n\t3433:  \"opnet-smp\",\n\t3434:  \"opencm\",\n\t3435:  \"pacom\",\n\t3436:  \"gc-config\",\n\t3437:  \"autocueds\",\n\t3438:  \"spiral-admin\",\n\t3439:  \"hri-port\",\n\t3440:  \"ans-console\",\n\t3441:  \"connect-client\",\n\t3442:  \"connect-server\",\n\t3443:  \"ov-nnm-websrv\",\n\t3444:  \"denali-server\",\n\t3445:  \"monp\",\n\t3446:  \"3comfaxrpc\",\n\t3447:  \"directnet\",\n\t3448:  \"dnc-port\",\n\t3449:  \"hotu-chat\",\n\t3450:  \"castorproxy\",\n\t3451:  \"asam\",\n\t3452:  \"sabp-signal\",\n\t3453:  \"pscupd\",\n\t3454:  \"mira\",\n\t3455:  \"prsvp\",\n\t3456:  \"vat\",\n\t3457:  \"vat-control\",\n\t3458:  \"d3winosfi\",\n\t3459:  \"integral\",\n\t3460:  \"edm-manager\",\n\t3461:  \"edm-stager\",\n\t3462:  \"edm-std-notify\",\n\t3463:  \"edm-adm-notify\",\n\t3464:  \"edm-mgr-sync\",\n\t3465:  \"edm-mgr-cntrl\",\n\t3466:  \"workflow\",\n\t3467:  \"rcst\",\n\t3468:  \"ttcmremotectrl\",\n\t3469:  \"pluribus\",\n\t3470:  \"jt400\",\n\t3471:  \"jt400-ssl\",\n\t3472:  \"jaugsremotec-1\",\n\t3473:  \"jaugsremotec-2\",\n\t3474:  \"ttntspauto\",\n\t3475:  \"genisar-port\",\n\t3476:  \"nppmp\",\n\t3477:  \"ecomm\",\n\t3478:  \"stun\",\n\t3479:  \"twrpc\",\n\t3480:  \"plethora\",\n\t3481:  \"cleanerliverc\",\n\t3482:  \"vulture\",\n\t3483:  \"slim-devices\",\n\t3484:  \"gbs-stp\",\n\t3485:  \"celatalk\",\n\t3486:  \"ifsf-hb-port\",\n\t3487:  \"ltctcp\",\n\t3488:  \"fs-rh-srv\",\n\t3489:  \"dtp-dia\",\n\t3490:  \"colubris\",\n\t3491:  \"swr-port\",\n\t3492:  \"tvdumtray-port\",\n\t3493:  \"nut\",\n\t3494:  \"ibm3494\",\n\t3495:  \"seclayer-tcp\",\n\t3496:  \"seclayer-tls\",\n\t3497:  \"ipether232port\",\n\t3498:  \"dashpas-port\",\n\t3499:  \"sccip-media\",\n\t3500:  \"rtmp-port\",\n\t3501:  \"isoft-p2p\",\n\t3502:  \"avinstalldisc\",\n\t3503:  \"lsp-ping\",\n\t3504:  \"ironstorm\",\n\t3505:  \"ccmcomm\",\n\t3506:  \"apc-3506\",\n\t3507:  \"nesh-broker\",\n\t3508:  \"interactionweb\",\n\t3509:  \"vt-ssl\",\n\t3510:  \"xss-port\",\n\t3511:  \"webmail-2\",\n\t3512:  \"aztec\",\n\t3513:  \"arcpd\",\n\t3514:  \"must-p2p\",\n\t3515:  \"must-backplane\",\n\t3516:  \"smartcard-port\",\n\t3517:  \"802-11-iapp\",\n\t3518:  \"artifact-msg\",\n\t3519:  \"nvmsgd\",\n\t3520:  \"galileolog\",\n\t3521:  \"mc3ss\",\n\t3522:  \"nssocketport\",\n\t3523:  \"odeumservlink\",\n\t3524:  \"ecmport\",\n\t3525:  \"eisport\",\n\t3526:  \"starquiz-port\",\n\t3527:  \"beserver-msg-q\",\n\t3528:  \"jboss-iiop\",\n\t3529:  \"jboss-iiop-ssl\",\n\t3530:  \"gf\",\n\t3531:  \"joltid\",\n\t3532:  \"raven-rmp\",\n\t3533:  \"raven-rdp\",\n\t3534:  \"urld-port\",\n\t3535:  \"ms-la\",\n\t3536:  \"snac\",\n\t3537:  \"ni-visa-remote\",\n\t3538:  \"ibm-diradm\",\n\t3539:  \"ibm-diradm-ssl\",\n\t3540:  \"pnrp-port\",\n\t3541:  \"voispeed-port\",\n\t3542:  \"hacl-monitor\",\n\t3543:  \"qftest-lookup\",\n\t3544:  \"teredo\",\n\t3545:  \"camac\",\n\t3547:  \"symantec-sim\",\n\t3548:  \"interworld\",\n\t3549:  \"tellumat-nms\",\n\t3550:  \"ssmpp\",\n\t3551:  \"apcupsd\",\n\t3552:  \"taserver\",\n\t3553:  \"rbr-discovery\",\n\t3554:  \"questnotify\",\n\t3555:  \"razor\",\n\t3556:  \"sky-transport\",\n\t3557:  \"personalos-001\",\n\t3558:  \"mcp-port\",\n\t3559:  \"cctv-port\",\n\t3560:  \"iniserve-port\",\n\t3561:  \"bmc-onekey\",\n\t3562:  \"sdbproxy\",\n\t3563:  \"watcomdebug\",\n\t3564:  \"esimport\",\n\t3565:  \"m2pa\",\n\t3566:  \"quest-data-hub\",\n\t3567:  \"dof-eps\",\n\t3568:  \"dof-tunnel-sec\",\n\t3569:  \"mbg-ctrl\",\n\t3570:  \"mccwebsvr-port\",\n\t3571:  \"megardsvr-port\",\n\t3572:  \"megaregsvrport\",\n\t3573:  \"tag-ups-1\",\n\t3574:  \"dmaf-server\",\n\t3575:  \"ccm-port\",\n\t3576:  \"cmc-port\",\n\t3577:  \"config-port\",\n\t3578:  \"data-port\",\n\t3579:  \"ttat3lb\",\n\t3580:  \"nati-svrloc\",\n\t3581:  \"kfxaclicensing\",\n\t3582:  \"press\",\n\t3583:  \"canex-watch\",\n\t3584:  \"u-dbap\",\n\t3585:  \"emprise-lls\",\n\t3586:  \"emprise-lsc\",\n\t3587:  \"p2pgroup\",\n\t3588:  \"sentinel\",\n\t3589:  \"isomair\",\n\t3590:  \"wv-csp-sms\",\n\t3591:  \"gtrack-server\",\n\t3592:  \"gtrack-ne\",\n\t3593:  \"bpmd\",\n\t3594:  \"mediaspace\",\n\t3595:  \"shareapp\",\n\t3596:  \"iw-mmogame\",\n\t3597:  \"a14\",\n\t3598:  \"a15\",\n\t3599:  \"quasar-server\",\n\t3600:  \"trap-daemon\",\n\t3601:  \"visinet-gui\",\n\t3602:  \"infiniswitchcl\",\n\t3603:  \"int-rcv-cntrl\",\n\t3604:  \"bmc-jmx-port\",\n\t3605:  \"comcam-io\",\n\t3606:  \"splitlock\",\n\t3607:  \"precise-i3\",\n\t3608:  \"trendchip-dcp\",\n\t3609:  \"cpdi-pidas-cm\",\n\t3610:  \"echonet\",\n\t3611:  \"six-degrees\",\n\t3612:  \"hp-dataprotect\",\n\t3613:  \"alaris-disc\",\n\t3614:  \"sigma-port\",\n\t3615:  \"start-network\",\n\t3616:  \"cd3o-protocol\",\n\t3617:  \"sharp-server\",\n\t3618:  \"aairnet-1\",\n\t3619:  \"aairnet-2\",\n\t3620:  \"ep-pcp\",\n\t3621:  \"ep-nsp\",\n\t3622:  \"ff-lr-port\",\n\t3623:  \"haipe-discover\",\n\t3624:  \"dist-upgrade\",\n\t3625:  \"volley\",\n\t3626:  \"bvcdaemon-port\",\n\t3627:  \"jamserverport\",\n\t3628:  \"ept-machine\",\n\t3629:  \"escvpnet\",\n\t3630:  \"cs-remote-db\",\n\t3631:  \"cs-services\",\n\t3632:  \"distcc\",\n\t3633:  \"wacp\",\n\t3634:  \"hlibmgr\",\n\t3635:  \"sdo\",\n\t3636:  \"servistaitsm\",\n\t3637:  \"scservp\",\n\t3638:  \"ehp-backup\",\n\t3639:  \"xap-ha\",\n\t3640:  \"netplay-port1\",\n\t3641:  \"netplay-port2\",\n\t3642:  \"juxml-port\",\n\t3643:  \"audiojuggler\",\n\t3644:  \"ssowatch\",\n\t3645:  \"cyc\",\n\t3646:  \"xss-srv-port\",\n\t3647:  \"splitlock-gw\",\n\t3648:  \"fjcp\",\n\t3649:  \"nmmp\",\n\t3650:  \"prismiq-plugin\",\n\t3651:  \"xrpc-registry\",\n\t3652:  \"vxcrnbuport\",\n\t3653:  \"tsp\",\n\t3654:  \"vaprtm\",\n\t3655:  \"abatemgr\",\n\t3656:  \"abatjss\",\n\t3657:  \"immedianet-bcn\",\n\t3658:  \"ps-ams\",\n\t3659:  \"apple-sasl\",\n\t3660:  \"can-nds-ssl\",\n\t3661:  \"can-ferret-ssl\",\n\t3662:  \"pserver\",\n\t3663:  \"dtp\",\n\t3664:  \"ups-engine\",\n\t3665:  \"ent-engine\",\n\t3666:  \"eserver-pap\",\n\t3667:  \"infoexch\",\n\t3668:  \"dell-rm-port\",\n\t3669:  \"casanswmgmt\",\n\t3670:  \"smile\",\n\t3671:  \"efcp\",\n\t3672:  \"lispworks-orb\",\n\t3673:  \"mediavault-gui\",\n\t3674:  \"wininstall-ipc\",\n\t3675:  \"calltrax\",\n\t3676:  \"va-pacbase\",\n\t3677:  \"roverlog\",\n\t3678:  \"ipr-dglt\",\n\t3679:  \"Escale (Newton Dock)\",\n\t3680:  \"npds-tracker\",\n\t3681:  \"bts-x73\",\n\t3682:  \"cas-mapi\",\n\t3683:  \"bmc-ea\",\n\t3684:  \"faxstfx-port\",\n\t3685:  \"dsx-agent\",\n\t3686:  \"tnmpv2\",\n\t3687:  \"simple-push\",\n\t3688:  \"simple-push-s\",\n\t3689:  \"daap\",\n\t3690:  \"svn\",\n\t3691:  \"magaya-network\",\n\t3692:  \"intelsync\",\n\t3693:  \"easl\",\n\t3695:  \"bmc-data-coll\",\n\t3696:  \"telnetcpcd\",\n\t3697:  \"nw-license\",\n\t3698:  \"sagectlpanel\",\n\t3699:  \"kpn-icw\",\n\t3700:  \"lrs-paging\",\n\t3701:  \"netcelera\",\n\t3702:  \"ws-discovery\",\n\t3703:  \"adobeserver-3\",\n\t3704:  \"adobeserver-4\",\n\t3705:  \"adobeserver-5\",\n\t3706:  \"rt-event\",\n\t3707:  \"rt-event-s\",\n\t3708:  \"sun-as-iiops\",\n\t3709:  \"ca-idms\",\n\t3710:  \"portgate-auth\",\n\t3711:  \"edb-server2\",\n\t3712:  \"sentinel-ent\",\n\t3713:  \"tftps\",\n\t3714:  \"delos-dms\",\n\t3715:  \"anoto-rendezv\",\n\t3716:  \"wv-csp-sms-cir\",\n\t3717:  \"wv-csp-udp-cir\",\n\t3718:  \"opus-services\",\n\t3719:  \"itelserverport\",\n\t3720:  \"ufastro-instr\",\n\t3721:  \"xsync\",\n\t3722:  \"xserveraid\",\n\t3723:  \"sychrond\",\n\t3724:  \"blizwow\",\n\t3725:  \"na-er-tip\",\n\t3726:  \"array-manager\",\n\t3727:  \"e-mdu\",\n\t3728:  \"e-woa\",\n\t3729:  \"fksp-audit\",\n\t3730:  \"client-ctrl\",\n\t3731:  \"smap\",\n\t3732:  \"m-wnn\",\n\t3733:  \"multip-msg\",\n\t3734:  \"synel-data\",\n\t3735:  \"pwdis\",\n\t3736:  \"rs-rmi\",\n\t3737:  \"xpanel\",\n\t3738:  \"versatalk\",\n\t3739:  \"launchbird-lm\",\n\t3740:  \"heartbeat\",\n\t3741:  \"wysdma\",\n\t3742:  \"cst-port\",\n\t3743:  \"ipcs-command\",\n\t3744:  \"sasg\",\n\t3745:  \"gw-call-port\",\n\t3746:  \"linktest\",\n\t3747:  \"linktest-s\",\n\t3748:  \"webdata\",\n\t3749:  \"cimtrak\",\n\t3750:  \"cbos-ip-port\",\n\t3751:  \"gprs-cube\",\n\t3752:  \"vipremoteagent\",\n\t3753:  \"nattyserver\",\n\t3754:  \"timestenbroker\",\n\t3755:  \"sas-remote-hlp\",\n\t3756:  \"canon-capt\",\n\t3757:  \"grf-port\",\n\t3758:  \"apw-registry\",\n\t3759:  \"exapt-lmgr\",\n\t3760:  \"adtempusclient\",\n\t3761:  \"gsakmp\",\n\t3762:  \"gbs-smp\",\n\t3763:  \"xo-wave\",\n\t3764:  \"mni-prot-rout\",\n\t3765:  \"rtraceroute\",\n\t3766:  \"sitewatch-s\",\n\t3767:  \"listmgr-port\",\n\t3768:  \"rblcheckd\",\n\t3769:  \"haipe-otnk\",\n\t3770:  \"cindycollab\",\n\t3771:  \"paging-port\",\n\t3772:  \"ctp\",\n\t3773:  \"ctdhercules\",\n\t3774:  \"zicom\",\n\t3775:  \"ispmmgr\",\n\t3776:  \"dvcprov-port\",\n\t3777:  \"jibe-eb\",\n\t3778:  \"c-h-it-port\",\n\t3779:  \"cognima\",\n\t3780:  \"nnp\",\n\t3781:  \"abcvoice-port\",\n\t3782:  \"iso-tp0s\",\n\t3783:  \"bim-pem\",\n\t3784:  \"bfd-control\",\n\t3785:  \"bfd-echo\",\n\t3786:  \"upstriggervsw\",\n\t3787:  \"fintrx\",\n\t3788:  \"isrp-port\",\n\t3789:  \"remotedeploy\",\n\t3790:  \"quickbooksrds\",\n\t3791:  \"tvnetworkvideo\",\n\t3792:  \"sitewatch\",\n\t3793:  \"dcsoftware\",\n\t3794:  \"jaus\",\n\t3795:  \"myblast\",\n\t3796:  \"spw-dialer\",\n\t3797:  \"idps\",\n\t3798:  \"minilock\",\n\t3799:  \"radius-dynauth\",\n\t3800:  \"pwgpsi\",\n\t3801:  \"ibm-mgr\",\n\t3802:  \"vhd\",\n\t3803:  \"soniqsync\",\n\t3804:  \"iqnet-port\",\n\t3805:  \"tcpdataserver\",\n\t3806:  \"wsmlb\",\n\t3807:  \"spugna\",\n\t3808:  \"sun-as-iiops-ca\",\n\t3809:  \"apocd\",\n\t3810:  \"wlanauth\",\n\t3811:  \"amp\",\n\t3812:  \"neto-wol-server\",\n\t3813:  \"rap-ip\",\n\t3814:  \"neto-dcs\",\n\t3815:  \"lansurveyorxml\",\n\t3816:  \"sunlps-http\",\n\t3817:  \"tapeware\",\n\t3818:  \"crinis-hb\",\n\t3819:  \"epl-slp\",\n\t3820:  \"scp\",\n\t3821:  \"pmcp\",\n\t3822:  \"acp-discovery\",\n\t3823:  \"acp-conduit\",\n\t3824:  \"acp-policy\",\n\t3825:  \"ffserver\",\n\t3826:  \"warmux\",\n\t3827:  \"netmpi\",\n\t3828:  \"neteh\",\n\t3829:  \"neteh-ext\",\n\t3830:  \"cernsysmgmtagt\",\n\t3831:  \"dvapps\",\n\t3832:  \"xxnetserver\",\n\t3833:  \"aipn-auth\",\n\t3834:  \"spectardata\",\n\t3835:  \"spectardb\",\n\t3836:  \"markem-dcp\",\n\t3837:  \"mkm-discovery\",\n\t3838:  \"sos\",\n\t3839:  \"amx-rms\",\n\t3840:  \"flirtmitmir\",\n\t3841:  \"shiprush-db-svr\",\n\t3842:  \"nhci\",\n\t3843:  \"quest-agent\",\n\t3844:  \"rnm\",\n\t3845:  \"v-one-spp\",\n\t3846:  \"an-pcp\",\n\t3847:  \"msfw-control\",\n\t3848:  \"item\",\n\t3849:  \"spw-dnspreload\",\n\t3850:  \"qtms-bootstrap\",\n\t3851:  \"spectraport\",\n\t3852:  \"sse-app-config\",\n\t3853:  \"sscan\",\n\t3854:  \"stryker-com\",\n\t3855:  \"opentrac\",\n\t3856:  \"informer\",\n\t3857:  \"trap-port\",\n\t3858:  \"trap-port-mom\",\n\t3859:  \"nav-port\",\n\t3860:  \"sasp\",\n\t3861:  \"winshadow-hd\",\n\t3862:  \"giga-pocket\",\n\t3863:  \"asap-tcp\",\n\t3864:  \"asap-tcp-tls\",\n\t3865:  \"xpl\",\n\t3866:  \"dzdaemon\",\n\t3867:  \"dzoglserver\",\n\t3868:  \"diameter\",\n\t3869:  \"ovsam-mgmt\",\n\t3870:  \"ovsam-d-agent\",\n\t3871:  \"avocent-adsap\",\n\t3872:  \"oem-agent\",\n\t3873:  \"fagordnc\",\n\t3874:  \"sixxsconfig\",\n\t3875:  \"pnbscada\",\n\t3876:  \"dl-agent\",\n\t3877:  \"xmpcr-interface\",\n\t3878:  \"fotogcad\",\n\t3879:  \"appss-lm\",\n\t3880:  \"igrs\",\n\t3881:  \"idac\",\n\t3882:  \"msdts1\",\n\t3883:  \"vrpn\",\n\t3884:  \"softrack-meter\",\n\t3885:  \"topflow-ssl\",\n\t3886:  \"nei-management\",\n\t3887:  \"ciphire-data\",\n\t3888:  \"ciphire-serv\",\n\t3889:  \"dandv-tester\",\n\t3890:  \"ndsconnect\",\n\t3891:  \"rtc-pm-port\",\n\t3892:  \"pcc-image-port\",\n\t3893:  \"cgi-starapi\",\n\t3894:  \"syam-agent\",\n\t3895:  \"syam-smc\",\n\t3896:  \"sdo-tls\",\n\t3897:  \"sdo-ssh\",\n\t3898:  \"senip\",\n\t3899:  \"itv-control\",\n\t3900:  \"udt-os\",\n\t3901:  \"nimsh\",\n\t3902:  \"nimaux\",\n\t3903:  \"charsetmgr\",\n\t3904:  \"omnilink-port\",\n\t3905:  \"mupdate\",\n\t3906:  \"topovista-data\",\n\t3907:  \"imoguia-port\",\n\t3908:  \"hppronetman\",\n\t3909:  \"surfcontrolcpa\",\n\t3910:  \"prnrequest\",\n\t3911:  \"prnstatus\",\n\t3912:  \"gbmt-stars\",\n\t3913:  \"listcrt-port\",\n\t3914:  \"listcrt-port-2\",\n\t3915:  \"agcat\",\n\t3916:  \"wysdmc\",\n\t3917:  \"aftmux\",\n\t3918:  \"pktcablemmcops\",\n\t3919:  \"hyperip\",\n\t3920:  \"exasoftport1\",\n\t3921:  \"herodotus-net\",\n\t3922:  \"sor-update\",\n\t3923:  \"symb-sb-port\",\n\t3924:  \"mpl-gprs-port\",\n\t3925:  \"zmp\",\n\t3926:  \"winport\",\n\t3927:  \"natdataservice\",\n\t3928:  \"netboot-pxe\",\n\t3929:  \"smauth-port\",\n\t3930:  \"syam-webserver\",\n\t3931:  \"msr-plugin-port\",\n\t3932:  \"dyn-site\",\n\t3933:  \"plbserve-port\",\n\t3934:  \"sunfm-port\",\n\t3935:  \"sdp-portmapper\",\n\t3936:  \"mailprox\",\n\t3937:  \"dvbservdsc\",\n\t3938:  \"dbcontrol-agent\",\n\t3939:  \"aamp\",\n\t3940:  \"xecp-node\",\n\t3941:  \"homeportal-web\",\n\t3942:  \"srdp\",\n\t3943:  \"tig\",\n\t3944:  \"sops\",\n\t3945:  \"emcads\",\n\t3946:  \"backupedge\",\n\t3947:  \"ccp\",\n\t3948:  \"apdap\",\n\t3949:  \"drip\",\n\t3950:  \"namemunge\",\n\t3951:  \"pwgippfax\",\n\t3952:  \"i3-sessionmgr\",\n\t3953:  \"xmlink-connect\",\n\t3954:  \"adrep\",\n\t3955:  \"p2pcommunity\",\n\t3956:  \"gvcp\",\n\t3957:  \"mqe-broker\",\n\t3958:  \"mqe-agent\",\n\t3959:  \"treehopper\",\n\t3960:  \"bess\",\n\t3961:  \"proaxess\",\n\t3962:  \"sbi-agent\",\n\t3963:  \"thrp\",\n\t3964:  \"sasggprs\",\n\t3965:  \"ati-ip-to-ncpe\",\n\t3966:  \"bflckmgr\",\n\t3967:  \"ppsms\",\n\t3968:  \"ianywhere-dbns\",\n\t3969:  \"landmarks\",\n\t3970:  \"lanrevagent\",\n\t3971:  \"lanrevserver\",\n\t3972:  \"iconp\",\n\t3973:  \"progistics\",\n\t3974:  \"citysearch\",\n\t3975:  \"airshot\",\n\t3976:  \"opswagent\",\n\t3977:  \"opswmanager\",\n\t3978:  \"secure-cfg-svr\",\n\t3979:  \"smwan\",\n\t3980:  \"acms\",\n\t3981:  \"starfish\",\n\t3982:  \"eis\",\n\t3983:  \"eisp\",\n\t3984:  \"mapper-nodemgr\",\n\t3985:  \"mapper-mapethd\",\n\t3986:  \"mapper-ws-ethd\",\n\t3987:  \"centerline\",\n\t3988:  \"dcs-config\",\n\t3989:  \"bv-queryengine\",\n\t3990:  \"bv-is\",\n\t3991:  \"bv-smcsrv\",\n\t3992:  \"bv-ds\",\n\t3993:  \"bv-agent\",\n\t3995:  \"iss-mgmt-ssl\",\n\t3996:  \"abcsoftware\",\n\t3997:  \"agentsease-db\",\n\t3998:  \"dnx\",\n\t3999:  \"nvcnet\",\n\t4000:  \"terabase\",\n\t4001:  \"newoak\",\n\t4002:  \"pxc-spvr-ft\",\n\t4003:  \"pxc-splr-ft\",\n\t4004:  \"pxc-roid\",\n\t4005:  \"pxc-pin\",\n\t4006:  \"pxc-spvr\",\n\t4007:  \"pxc-splr\",\n\t4008:  \"netcheque\",\n\t4009:  \"chimera-hwm\",\n\t4010:  \"samsung-unidex\",\n\t4011:  \"altserviceboot\",\n\t4012:  \"pda-gate\",\n\t4013:  \"acl-manager\",\n\t4014:  \"taiclock\",\n\t4015:  \"talarian-mcast1\",\n\t4016:  \"talarian-mcast2\",\n\t4017:  \"talarian-mcast3\",\n\t4018:  \"talarian-mcast4\",\n\t4019:  \"talarian-mcast5\",\n\t4020:  \"trap\",\n\t4021:  \"nexus-portal\",\n\t4022:  \"dnox\",\n\t4023:  \"esnm-zoning\",\n\t4024:  \"tnp1-port\",\n\t4025:  \"partimage\",\n\t4026:  \"as-debug\",\n\t4027:  \"bxp\",\n\t4028:  \"dtserver-port\",\n\t4029:  \"ip-qsig\",\n\t4030:  \"jdmn-port\",\n\t4031:  \"suucp\",\n\t4032:  \"vrts-auth-port\",\n\t4033:  \"sanavigator\",\n\t4034:  \"ubxd\",\n\t4035:  \"wap-push-http\",\n\t4036:  \"wap-push-https\",\n\t4037:  \"ravehd\",\n\t4038:  \"fazzt-ptp\",\n\t4039:  \"fazzt-admin\",\n\t4040:  \"yo-main\",\n\t4041:  \"houston\",\n\t4042:  \"ldxp\",\n\t4043:  \"nirp\",\n\t4044:  \"ltp\",\n\t4045:  \"npp\",\n\t4046:  \"acp-proto\",\n\t4047:  \"ctp-state\",\n\t4049:  \"wafs\",\n\t4050:  \"cisco-wafs\",\n\t4051:  \"cppdp\",\n\t4052:  \"interact\",\n\t4053:  \"ccu-comm-1\",\n\t4054:  \"ccu-comm-2\",\n\t4055:  \"ccu-comm-3\",\n\t4056:  \"lms\",\n\t4057:  \"wfm\",\n\t4058:  \"kingfisher\",\n\t4059:  \"dlms-cosem\",\n\t4060:  \"dsmeter-iatc\",\n\t4061:  \"ice-location\",\n\t4062:  \"ice-slocation\",\n\t4063:  \"ice-router\",\n\t4064:  \"ice-srouter\",\n\t4065:  \"avanti-cdp\",\n\t4066:  \"pmas\",\n\t4067:  \"idp\",\n\t4068:  \"ipfltbcst\",\n\t4069:  \"minger\",\n\t4070:  \"tripe\",\n\t4071:  \"aibkup\",\n\t4072:  \"zieto-sock\",\n\t4073:  \"iRAPP\",\n\t4074:  \"cequint-cityid\",\n\t4075:  \"perimlan\",\n\t4076:  \"seraph\",\n\t4078:  \"cssp\",\n\t4079:  \"santools\",\n\t4080:  \"lorica-in\",\n\t4081:  \"lorica-in-sec\",\n\t4082:  \"lorica-out\",\n\t4083:  \"lorica-out-sec\",\n\t4085:  \"ezmessagesrv\",\n\t4087:  \"applusservice\",\n\t4088:  \"npsp\",\n\t4089:  \"opencore\",\n\t4090:  \"omasgport\",\n\t4091:  \"ewinstaller\",\n\t4092:  \"ewdgs\",\n\t4093:  \"pvxpluscs\",\n\t4094:  \"sysrqd\",\n\t4095:  \"xtgui\",\n\t4096:  \"bre\",\n\t4097:  \"patrolview\",\n\t4098:  \"drmsfsd\",\n\t4099:  \"dpcp\",\n\t4100:  \"igo-incognito\",\n\t4101:  \"brlp-0\",\n\t4102:  \"brlp-1\",\n\t4103:  \"brlp-2\",\n\t4104:  \"brlp-3\",\n\t4105:  \"shofar\",\n\t4106:  \"synchronite\",\n\t4107:  \"j-ac\",\n\t4108:  \"accel\",\n\t4109:  \"izm\",\n\t4110:  \"g2tag\",\n\t4111:  \"xgrid\",\n\t4112:  \"apple-vpns-rp\",\n\t4113:  \"aipn-reg\",\n\t4114:  \"jomamqmonitor\",\n\t4115:  \"cds\",\n\t4116:  \"smartcard-tls\",\n\t4117:  \"hillrserv\",\n\t4118:  \"netscript\",\n\t4119:  \"assuria-slm\",\n\t4120:  \"minirem\",\n\t4121:  \"e-builder\",\n\t4122:  \"fprams\",\n\t4123:  \"z-wave\",\n\t4124:  \"tigv2\",\n\t4125:  \"opsview-envoy\",\n\t4126:  \"ddrepl\",\n\t4127:  \"unikeypro\",\n\t4128:  \"nufw\",\n\t4129:  \"nuauth\",\n\t4130:  \"fronet\",\n\t4131:  \"stars\",\n\t4132:  \"nuts-dem\",\n\t4133:  \"nuts-bootp\",\n\t4134:  \"nifty-hmi\",\n\t4135:  \"cl-db-attach\",\n\t4136:  \"cl-db-request\",\n\t4137:  \"cl-db-remote\",\n\t4138:  \"nettest\",\n\t4139:  \"thrtx\",\n\t4140:  \"cedros-fds\",\n\t4141:  \"oirtgsvc\",\n\t4142:  \"oidocsvc\",\n\t4143:  \"oidsr\",\n\t4145:  \"vvr-control\",\n\t4146:  \"tgcconnect\",\n\t4147:  \"vrxpservman\",\n\t4148:  \"hhb-handheld\",\n\t4149:  \"agslb\",\n\t4150:  \"PowerAlert-nsa\",\n\t4151:  \"menandmice-noh\",\n\t4152:  \"idig-mux\",\n\t4153:  \"mbl-battd\",\n\t4154:  \"atlinks\",\n\t4155:  \"bzr\",\n\t4156:  \"stat-results\",\n\t4157:  \"stat-scanner\",\n\t4158:  \"stat-cc\",\n\t4159:  \"nss\",\n\t4160:  \"jini-discovery\",\n\t4161:  \"omscontact\",\n\t4162:  \"omstopology\",\n\t4163:  \"silverpeakpeer\",\n\t4164:  \"silverpeakcomm\",\n\t4165:  \"altcp\",\n\t4166:  \"joost\",\n\t4167:  \"ddgn\",\n\t4168:  \"pslicser\",\n\t4169:  \"iadt\",\n\t4170:  \"d-cinema-csp\",\n\t4171:  \"ml-svnet\",\n\t4172:  \"pcoip\",\n\t4174:  \"smcluster\",\n\t4175:  \"bccp\",\n\t4176:  \"tl-ipcproxy\",\n\t4177:  \"wello\",\n\t4178:  \"storman\",\n\t4179:  \"MaxumSP\",\n\t4180:  \"httpx\",\n\t4181:  \"macbak\",\n\t4182:  \"pcptcpservice\",\n\t4183:  \"cyborgnet\",\n\t4184:  \"universe-suite\",\n\t4185:  \"wcpp\",\n\t4186:  \"boxbackupstore\",\n\t4187:  \"csc-proxy\",\n\t4188:  \"vatata\",\n\t4189:  \"pcep\",\n\t4190:  \"sieve\",\n\t4192:  \"azeti\",\n\t4193:  \"pvxplusio\",\n\t4197:  \"hctl\",\n\t4199:  \"eims-admin\",\n\t4300:  \"corelccam\",\n\t4301:  \"d-data\",\n\t4302:  \"d-data-control\",\n\t4303:  \"srcp\",\n\t4304:  \"owserver\",\n\t4305:  \"batman\",\n\t4306:  \"pinghgl\",\n\t4307:  \"trueconf\",\n\t4308:  \"compx-lockview\",\n\t4309:  \"dserver\",\n\t4310:  \"mirrtex\",\n\t4311:  \"p6ssmc\",\n\t4312:  \"pscl-mgt\",\n\t4313:  \"perrla\",\n\t4314:  \"choiceview-agt\",\n\t4316:  \"choiceview-clt\",\n\t4320:  \"fdt-rcatp\",\n\t4321:  \"rwhois\",\n\t4322:  \"trim-event\",\n\t4323:  \"trim-ice\",\n\t4325:  \"geognosisman\",\n\t4326:  \"geognosis\",\n\t4327:  \"jaxer-web\",\n\t4328:  \"jaxer-manager\",\n\t4329:  \"publiqare-sync\",\n\t4330:  \"dey-sapi\",\n\t4331:  \"ktickets-rest\",\n\t4333:  \"ahsp\",\n\t4334:  \"netconf-ch-ssh\",\n\t4335:  \"netconf-ch-tls\",\n\t4336:  \"restconf-ch-tls\",\n\t4340:  \"gaia\",\n\t4341:  \"lisp-data\",\n\t4342:  \"lisp-cons\",\n\t4343:  \"unicall\",\n\t4344:  \"vinainstall\",\n\t4345:  \"m4-network-as\",\n\t4346:  \"elanlm\",\n\t4347:  \"lansurveyor\",\n\t4348:  \"itose\",\n\t4349:  \"fsportmap\",\n\t4350:  \"net-device\",\n\t4351:  \"plcy-net-svcs\",\n\t4352:  \"pjlink\",\n\t4353:  \"f5-iquery\",\n\t4354:  \"qsnet-trans\",\n\t4355:  \"qsnet-workst\",\n\t4356:  \"qsnet-assist\",\n\t4357:  \"qsnet-cond\",\n\t4358:  \"qsnet-nucl\",\n\t4359:  \"omabcastltkm\",\n\t4360:  \"matrix-vnet\",\n\t4368:  \"wxbrief\",\n\t4369:  \"epmd\",\n\t4370:  \"elpro-tunnel\",\n\t4371:  \"l2c-control\",\n\t4372:  \"l2c-data\",\n\t4373:  \"remctl\",\n\t4374:  \"psi-ptt\",\n\t4375:  \"tolteces\",\n\t4376:  \"bip\",\n\t4377:  \"cp-spxsvr\",\n\t4378:  \"cp-spxdpy\",\n\t4379:  \"ctdb\",\n\t4389:  \"xandros-cms\",\n\t4390:  \"wiegand\",\n\t4391:  \"apwi-imserver\",\n\t4392:  \"apwi-rxserver\",\n\t4393:  \"apwi-rxspooler\",\n\t4395:  \"omnivisionesx\",\n\t4396:  \"fly\",\n\t4400:  \"ds-srv\",\n\t4401:  \"ds-srvr\",\n\t4402:  \"ds-clnt\",\n\t4403:  \"ds-user\",\n\t4404:  \"ds-admin\",\n\t4405:  \"ds-mail\",\n\t4406:  \"ds-slp\",\n\t4407:  \"nacagent\",\n\t4408:  \"slscc\",\n\t4409:  \"netcabinet-com\",\n\t4410:  \"itwo-server\",\n\t4411:  \"found\",\n\t4413:  \"avi-nms\",\n\t4414:  \"updog\",\n\t4415:  \"brcd-vr-req\",\n\t4416:  \"pjj-player\",\n\t4417:  \"workflowdir\",\n\t4419:  \"cbp\",\n\t4420:  \"nvm-express\",\n\t4421:  \"scaleft\",\n\t4422:  \"tsepisp\",\n\t4423:  \"thingkit\",\n\t4425:  \"netrockey6\",\n\t4426:  \"beacon-port-2\",\n\t4427:  \"drizzle\",\n\t4428:  \"omviserver\",\n\t4429:  \"omviagent\",\n\t4430:  \"rsqlserver\",\n\t4431:  \"wspipe\",\n\t4432:  \"l-acoustics\",\n\t4433:  \"vop\",\n\t4442:  \"saris\",\n\t4443:  \"pharos\",\n\t4444:  \"krb524\",\n\t4445:  \"upnotifyp\",\n\t4446:  \"n1-fwp\",\n\t4447:  \"n1-rmgmt\",\n\t4448:  \"asc-slmd\",\n\t4449:  \"privatewire\",\n\t4450:  \"camp\",\n\t4451:  \"ctisystemmsg\",\n\t4452:  \"ctiprogramload\",\n\t4453:  \"nssalertmgr\",\n\t4454:  \"nssagentmgr\",\n\t4455:  \"prchat-user\",\n\t4456:  \"prchat-server\",\n\t4457:  \"prRegister\",\n\t4458:  \"mcp\",\n\t4484:  \"hpssmgmt\",\n\t4485:  \"assyst-dr\",\n\t4486:  \"icms\",\n\t4487:  \"prex-tcp\",\n\t4488:  \"awacs-ice\",\n\t4500:  \"ipsec-nat-t\",\n\t4535:  \"ehs\",\n\t4536:  \"ehs-ssl\",\n\t4537:  \"wssauthsvc\",\n\t4538:  \"swx-gate\",\n\t4545:  \"worldscores\",\n\t4546:  \"sf-lm\",\n\t4547:  \"lanner-lm\",\n\t4548:  \"synchromesh\",\n\t4549:  \"aegate\",\n\t4550:  \"gds-adppiw-db\",\n\t4551:  \"ieee-mih\",\n\t4552:  \"menandmice-mon\",\n\t4553:  \"icshostsvc\",\n\t4554:  \"msfrs\",\n\t4555:  \"rsip\",\n\t4556:  \"dtn-bundle\",\n\t4559:  \"hylafax\",\n\t4563:  \"amahi-anywhere\",\n\t4566:  \"kwtc\",\n\t4567:  \"tram\",\n\t4568:  \"bmc-reporting\",\n\t4569:  \"iax\",\n\t4570:  \"deploymentmap\",\n\t4573:  \"cardifftec-back\",\n\t4590:  \"rid\",\n\t4591:  \"l3t-at-an\",\n\t4593:  \"ipt-anri-anri\",\n\t4594:  \"ias-session\",\n\t4595:  \"ias-paging\",\n\t4596:  \"ias-neighbor\",\n\t4597:  \"a21-an-1xbs\",\n\t4598:  \"a16-an-an\",\n\t4599:  \"a17-an-an\",\n\t4600:  \"piranha1\",\n\t4601:  \"piranha2\",\n\t4602:  \"mtsserver\",\n\t4603:  \"menandmice-upg\",\n\t4604:  \"irp\",\n\t4605:  \"sixchat\",\n\t4658:  \"playsta2-app\",\n\t4659:  \"playsta2-lob\",\n\t4660:  \"smaclmgr\",\n\t4661:  \"kar2ouche\",\n\t4662:  \"oms\",\n\t4663:  \"noteit\",\n\t4664:  \"ems\",\n\t4665:  \"contclientms\",\n\t4666:  \"eportcomm\",\n\t4667:  \"mmacomm\",\n\t4668:  \"mmaeds\",\n\t4669:  \"eportcommdata\",\n\t4670:  \"light\",\n\t4671:  \"acter\",\n\t4672:  \"rfa\",\n\t4673:  \"cxws\",\n\t4674:  \"appiq-mgmt\",\n\t4675:  \"dhct-status\",\n\t4676:  \"dhct-alerts\",\n\t4677:  \"bcs\",\n\t4678:  \"traversal\",\n\t4679:  \"mgesupervision\",\n\t4680:  \"mgemanagement\",\n\t4681:  \"parliant\",\n\t4682:  \"finisar\",\n\t4683:  \"spike\",\n\t4684:  \"rfid-rp1\",\n\t4685:  \"autopac\",\n\t4686:  \"msp-os\",\n\t4687:  \"nst\",\n\t4688:  \"mobile-p2p\",\n\t4689:  \"altovacentral\",\n\t4690:  \"prelude\",\n\t4691:  \"mtn\",\n\t4692:  \"conspiracy\",\n\t4700:  \"netxms-agent\",\n\t4701:  \"netxms-mgmt\",\n\t4702:  \"netxms-sync\",\n\t4703:  \"npqes-test\",\n\t4704:  \"assuria-ins\",\n\t4711:  \"trinity-dist\",\n\t4725:  \"truckstar\",\n\t4727:  \"fcis\",\n\t4728:  \"capmux\",\n\t4730:  \"gearman\",\n\t4731:  \"remcap\",\n\t4733:  \"resorcs\",\n\t4737:  \"ipdr-sp\",\n\t4738:  \"solera-lpn\",\n\t4739:  \"ipfix\",\n\t4740:  \"ipfixs\",\n\t4741:  \"lumimgrd\",\n\t4742:  \"sicct\",\n\t4743:  \"openhpid\",\n\t4744:  \"ifsp\",\n\t4745:  \"fmp\",\n\t4749:  \"profilemac\",\n\t4750:  \"ssad\",\n\t4751:  \"spocp\",\n\t4752:  \"snap\",\n\t4753:  \"simon\",\n\t4756:  \"RDCenter\",\n\t4774:  \"converge\",\n\t4784:  \"bfd-multi-ctl\",\n\t4786:  \"smart-install\",\n\t4787:  \"sia-ctrl-plane\",\n\t4788:  \"xmcp\",\n\t4800:  \"iims\",\n\t4801:  \"iwec\",\n\t4802:  \"ilss\",\n\t4803:  \"notateit\",\n\t4827:  \"htcp\",\n\t4837:  \"varadero-0\",\n\t4838:  \"varadero-1\",\n\t4839:  \"varadero-2\",\n\t4840:  \"opcua-tcp\",\n\t4841:  \"quosa\",\n\t4842:  \"gw-asv\",\n\t4843:  \"opcua-tls\",\n\t4844:  \"gw-log\",\n\t4845:  \"wcr-remlib\",\n\t4846:  \"contamac-icm\",\n\t4847:  \"wfc\",\n\t4848:  \"appserv-http\",\n\t4849:  \"appserv-https\",\n\t4850:  \"sun-as-nodeagt\",\n\t4851:  \"derby-repli\",\n\t4867:  \"unify-debug\",\n\t4868:  \"phrelay\",\n\t4869:  \"phrelaydbg\",\n\t4870:  \"cc-tracking\",\n\t4871:  \"wired\",\n\t4876:  \"tritium-can\",\n\t4877:  \"lmcs\",\n\t4879:  \"wsdl-event\",\n\t4880:  \"hislip\",\n\t4883:  \"wmlserver\",\n\t4884:  \"hivestor\",\n\t4885:  \"abbs\",\n\t4894:  \"lyskom\",\n\t4899:  \"radmin-port\",\n\t4900:  \"hfcs\",\n\t4901:  \"flr-agent\",\n\t4902:  \"magiccontrol\",\n\t4912:  \"lutap\",\n\t4913:  \"lutcp\",\n\t4914:  \"bones\",\n\t4915:  \"frcs\",\n\t4940:  \"eq-office-4940\",\n\t4941:  \"eq-office-4941\",\n\t4942:  \"eq-office-4942\",\n\t4949:  \"munin\",\n\t4950:  \"sybasesrvmon\",\n\t4951:  \"pwgwims\",\n\t4952:  \"sagxtsds\",\n\t4953:  \"dbsyncarbiter\",\n\t4969:  \"ccss-qmm\",\n\t4970:  \"ccss-qsm\",\n\t4971:  \"burp\",\n\t4984:  \"webyast\",\n\t4985:  \"gerhcs\",\n\t4986:  \"mrip\",\n\t4987:  \"smar-se-port1\",\n\t4988:  \"smar-se-port2\",\n\t4989:  \"parallel\",\n\t4990:  \"busycal\",\n\t4991:  \"vrt\",\n\t4999:  \"hfcs-manager\",\n\t5000:  \"commplex-main\",\n\t5001:  \"commplex-link\",\n\t5002:  \"rfe\",\n\t5003:  \"fmpro-internal\",\n\t5004:  \"avt-profile-1\",\n\t5005:  \"avt-profile-2\",\n\t5006:  \"wsm-server\",\n\t5007:  \"wsm-server-ssl\",\n\t5008:  \"synapsis-edge\",\n\t5009:  \"winfs\",\n\t5010:  \"telelpathstart\",\n\t5011:  \"telelpathattack\",\n\t5012:  \"nsp\",\n\t5013:  \"fmpro-v6\",\n\t5015:  \"fmwp\",\n\t5020:  \"zenginkyo-1\",\n\t5021:  \"zenginkyo-2\",\n\t5022:  \"mice\",\n\t5023:  \"htuilsrv\",\n\t5024:  \"scpi-telnet\",\n\t5025:  \"scpi-raw\",\n\t5026:  \"strexec-d\",\n\t5027:  \"strexec-s\",\n\t5028:  \"qvr\",\n\t5029:  \"infobright\",\n\t5030:  \"surfpass\",\n\t5032:  \"signacert-agent\",\n\t5033:  \"jtnetd-server\",\n\t5034:  \"jtnetd-status\",\n\t5042:  \"asnaacceler8db\",\n\t5043:  \"swxadmin\",\n\t5044:  \"lxi-evntsvc\",\n\t5045:  \"osp\",\n\t5048:  \"texai\",\n\t5049:  \"ivocalize\",\n\t5050:  \"mmcc\",\n\t5051:  \"ita-agent\",\n\t5052:  \"ita-manager\",\n\t5053:  \"rlm\",\n\t5054:  \"rlm-admin\",\n\t5055:  \"unot\",\n\t5056:  \"intecom-ps1\",\n\t5057:  \"intecom-ps2\",\n\t5059:  \"sds\",\n\t5060:  \"sip\",\n\t5061:  \"sips\",\n\t5062:  \"na-localise\",\n\t5063:  \"csrpc\",\n\t5064:  \"ca-1\",\n\t5065:  \"ca-2\",\n\t5066:  \"stanag-5066\",\n\t5067:  \"authentx\",\n\t5068:  \"bitforestsrv\",\n\t5069:  \"i-net-2000-npr\",\n\t5070:  \"vtsas\",\n\t5071:  \"powerschool\",\n\t5072:  \"ayiya\",\n\t5073:  \"tag-pm\",\n\t5074:  \"alesquery\",\n\t5075:  \"pvaccess\",\n\t5080:  \"onscreen\",\n\t5081:  \"sdl-ets\",\n\t5082:  \"qcp\",\n\t5083:  \"qfp\",\n\t5084:  \"llrp\",\n\t5085:  \"encrypted-llrp\",\n\t5086:  \"aprigo-cs\",\n\t5087:  \"biotic\",\n\t5093:  \"sentinel-lm\",\n\t5094:  \"hart-ip\",\n\t5099:  \"sentlm-srv2srv\",\n\t5100:  \"socalia\",\n\t5101:  \"talarian-tcp\",\n\t5102:  \"oms-nonsecure\",\n\t5103:  \"actifio-c2c\",\n\t5106:  \"actifioudsagent\",\n\t5107:  \"actifioreplic\",\n\t5111:  \"taep-as-svc\",\n\t5112:  \"pm-cmdsvr\",\n\t5114:  \"ev-services\",\n\t5115:  \"autobuild\",\n\t5117:  \"gradecam\",\n\t5120:  \"barracuda-bbs\",\n\t5133:  \"nbt-pc\",\n\t5134:  \"ppactivation\",\n\t5135:  \"erp-scale\",\n\t5137:  \"ctsd\",\n\t5145:  \"rmonitor-secure\",\n\t5146:  \"social-alarm\",\n\t5150:  \"atmp\",\n\t5151:  \"esri-sde\",\n\t5152:  \"sde-discovery\",\n\t5153:  \"toruxserver\",\n\t5154:  \"bzflag\",\n\t5155:  \"asctrl-agent\",\n\t5156:  \"rugameonline\",\n\t5157:  \"mediat\",\n\t5161:  \"snmpssh\",\n\t5162:  \"snmpssh-trap\",\n\t5163:  \"sbackup\",\n\t5164:  \"vpa\",\n\t5165:  \"ife-icorp\",\n\t5166:  \"winpcs\",\n\t5167:  \"scte104\",\n\t5168:  \"scte30\",\n\t5172:  \"pcoip-mgmt\",\n\t5190:  \"aol\",\n\t5191:  \"aol-1\",\n\t5192:  \"aol-2\",\n\t5193:  \"aol-3\",\n\t5194:  \"cpscomm\",\n\t5195:  \"ampl-lic\",\n\t5196:  \"ampl-tableproxy\",\n\t5197:  \"tunstall-lwp\",\n\t5200:  \"targus-getdata\",\n\t5201:  \"targus-getdata1\",\n\t5202:  \"targus-getdata2\",\n\t5203:  \"targus-getdata3\",\n\t5209:  \"nomad\",\n\t5215:  \"noteza\",\n\t5221:  \"3exmp\",\n\t5222:  \"xmpp-client\",\n\t5223:  \"hpvirtgrp\",\n\t5224:  \"hpvirtctrl\",\n\t5225:  \"hp-server\",\n\t5226:  \"hp-status\",\n\t5227:  \"perfd\",\n\t5228:  \"hpvroom\",\n\t5229:  \"jaxflow\",\n\t5230:  \"jaxflow-data\",\n\t5231:  \"crusecontrol\",\n\t5232:  \"csedaemon\",\n\t5233:  \"enfs\",\n\t5234:  \"eenet\",\n\t5235:  \"galaxy-network\",\n\t5236:  \"padl2sim\",\n\t5237:  \"mnet-discovery\",\n\t5245:  \"downtools\",\n\t5248:  \"caacws\",\n\t5249:  \"caaclang2\",\n\t5250:  \"soagateway\",\n\t5251:  \"caevms\",\n\t5252:  \"movaz-ssc\",\n\t5253:  \"kpdp\",\n\t5254:  \"logcabin\",\n\t5264:  \"3com-njack-1\",\n\t5265:  \"3com-njack-2\",\n\t5269:  \"xmpp-server\",\n\t5270:  \"cartographerxmp\",\n\t5271:  \"cuelink\",\n\t5272:  \"pk\",\n\t5280:  \"xmpp-bosh\",\n\t5281:  \"undo-lm\",\n\t5282:  \"transmit-port\",\n\t5298:  \"presence\",\n\t5299:  \"nlg-data\",\n\t5300:  \"hacl-hb\",\n\t5301:  \"hacl-gs\",\n\t5302:  \"hacl-cfg\",\n\t5303:  \"hacl-probe\",\n\t5304:  \"hacl-local\",\n\t5305:  \"hacl-test\",\n\t5306:  \"sun-mc-grp\",\n\t5307:  \"sco-aip\",\n\t5308:  \"cfengine\",\n\t5309:  \"jprinter\",\n\t5310:  \"outlaws\",\n\t5312:  \"permabit-cs\",\n\t5313:  \"rrdp\",\n\t5314:  \"opalis-rbt-ipc\",\n\t5315:  \"hacl-poll\",\n\t5316:  \"hpbladems\",\n\t5317:  \"hpdevms\",\n\t5318:  \"pkix-cmc\",\n\t5320:  \"bsfserver-zn\",\n\t5321:  \"bsfsvr-zn-ssl\",\n\t5343:  \"kfserver\",\n\t5344:  \"xkotodrcp\",\n\t5349:  \"stuns\",\n\t5352:  \"dns-llq\",\n\t5353:  \"mdns\",\n\t5354:  \"mdnsresponder\",\n\t5355:  \"llmnr\",\n\t5356:  \"ms-smlbiz\",\n\t5357:  \"wsdapi\",\n\t5358:  \"wsdapi-s\",\n\t5359:  \"ms-alerter\",\n\t5360:  \"ms-sideshow\",\n\t5361:  \"ms-s-sideshow\",\n\t5362:  \"serverwsd2\",\n\t5363:  \"net-projection\",\n\t5397:  \"stresstester\",\n\t5398:  \"elektron-admin\",\n\t5399:  \"securitychase\",\n\t5400:  \"excerpt\",\n\t5401:  \"excerpts\",\n\t5402:  \"mftp\",\n\t5403:  \"hpoms-ci-lstn\",\n\t5404:  \"hpoms-dps-lstn\",\n\t5405:  \"netsupport\",\n\t5406:  \"systemics-sox\",\n\t5407:  \"foresyte-clear\",\n\t5408:  \"foresyte-sec\",\n\t5409:  \"salient-dtasrv\",\n\t5410:  \"salient-usrmgr\",\n\t5411:  \"actnet\",\n\t5412:  \"continuus\",\n\t5413:  \"wwiotalk\",\n\t5414:  \"statusd\",\n\t5415:  \"ns-server\",\n\t5416:  \"sns-gateway\",\n\t5417:  \"sns-agent\",\n\t5418:  \"mcntp\",\n\t5419:  \"dj-ice\",\n\t5420:  \"cylink-c\",\n\t5421:  \"netsupport2\",\n\t5422:  \"salient-mux\",\n\t5423:  \"virtualuser\",\n\t5424:  \"beyond-remote\",\n\t5425:  \"br-channel\",\n\t5426:  \"devbasic\",\n\t5427:  \"sco-peer-tta\",\n\t5428:  \"telaconsole\",\n\t5429:  \"base\",\n\t5430:  \"radec-corp\",\n\t5431:  \"park-agent\",\n\t5432:  \"postgresql\",\n\t5433:  \"pyrrho\",\n\t5434:  \"sgi-arrayd\",\n\t5435:  \"sceanics\",\n\t5443:  \"spss\",\n\t5445:  \"smbdirect\",\n\t5450:  \"tiepie\",\n\t5453:  \"surebox\",\n\t5454:  \"apc-5454\",\n\t5455:  \"apc-5455\",\n\t5456:  \"apc-5456\",\n\t5461:  \"silkmeter\",\n\t5462:  \"ttl-publisher\",\n\t5463:  \"ttlpriceproxy\",\n\t5464:  \"quailnet\",\n\t5465:  \"netops-broker\",\n\t5470:  \"apsolab-col\",\n\t5471:  \"apsolab-cols\",\n\t5472:  \"apsolab-tag\",\n\t5473:  \"apsolab-tags\",\n\t5475:  \"apsolab-data\",\n\t5500:  \"fcp-addr-srvr1\",\n\t5501:  \"fcp-addr-srvr2\",\n\t5502:  \"fcp-srvr-inst1\",\n\t5503:  \"fcp-srvr-inst2\",\n\t5504:  \"fcp-cics-gw1\",\n\t5505:  \"checkoutdb\",\n\t5506:  \"amc\",\n\t5507:  \"psl-management\",\n\t5550:  \"cbus\",\n\t5553:  \"sgi-eventmond\",\n\t5554:  \"sgi-esphttp\",\n\t5555:  \"personal-agent\",\n\t5556:  \"freeciv\",\n\t5557:  \"farenet\",\n\t5565:  \"hpe-dp-bura\",\n\t5566:  \"westec-connect\",\n\t5567:  \"dof-dps-mc-sec\",\n\t5568:  \"sdt\",\n\t5569:  \"rdmnet-ctrl\",\n\t5573:  \"sdmmp\",\n\t5574:  \"lsi-bobcat\",\n\t5575:  \"ora-oap\",\n\t5579:  \"fdtracks\",\n\t5580:  \"tmosms0\",\n\t5581:  \"tmosms1\",\n\t5582:  \"fac-restore\",\n\t5583:  \"tmo-icon-sync\",\n\t5584:  \"bis-web\",\n\t5585:  \"bis-sync\",\n\t5586:  \"att-mt-sms\",\n\t5597:  \"ininmessaging\",\n\t5598:  \"mctfeed\",\n\t5599:  \"esinstall\",\n\t5600:  \"esmmanager\",\n\t5601:  \"esmagent\",\n\t5602:  \"a1-msc\",\n\t5603:  \"a1-bs\",\n\t5604:  \"a3-sdunode\",\n\t5605:  \"a4-sdunode\",\n\t5618:  \"efr\",\n\t5627:  \"ninaf\",\n\t5628:  \"htrust\",\n\t5629:  \"symantec-sfdb\",\n\t5630:  \"precise-comm\",\n\t5631:  \"pcanywheredata\",\n\t5632:  \"pcanywherestat\",\n\t5633:  \"beorl\",\n\t5634:  \"xprtld\",\n\t5635:  \"sfmsso\",\n\t5636:  \"sfm-db-server\",\n\t5637:  \"cssc\",\n\t5638:  \"flcrs\",\n\t5639:  \"ics\",\n\t5646:  \"vfmobile\",\n\t5666:  \"nrpe\",\n\t5670:  \"filemq\",\n\t5671:  \"amqps\",\n\t5672:  \"amqp\",\n\t5673:  \"jms\",\n\t5674:  \"hyperscsi-port\",\n\t5675:  \"v5ua\",\n\t5676:  \"raadmin\",\n\t5677:  \"questdb2-lnchr\",\n\t5678:  \"rrac\",\n\t5679:  \"dccm\",\n\t5680:  \"auriga-router\",\n\t5681:  \"ncxcp\",\n\t5688:  \"ggz\",\n\t5689:  \"qmvideo\",\n\t5693:  \"rbsystem\",\n\t5696:  \"kmip\",\n\t5700:  \"supportassist\",\n\t5705:  \"storageos\",\n\t5713:  \"proshareaudio\",\n\t5714:  \"prosharevideo\",\n\t5715:  \"prosharedata\",\n\t5716:  \"prosharerequest\",\n\t5717:  \"prosharenotify\",\n\t5718:  \"dpm\",\n\t5719:  \"dpm-agent\",\n\t5720:  \"ms-licensing\",\n\t5721:  \"dtpt\",\n\t5722:  \"msdfsr\",\n\t5723:  \"omhs\",\n\t5724:  \"omsdk\",\n\t5725:  \"ms-ilm\",\n\t5726:  \"ms-ilm-sts\",\n\t5727:  \"asgenf\",\n\t5728:  \"io-dist-data\",\n\t5729:  \"openmail\",\n\t5730:  \"unieng\",\n\t5741:  \"ida-discover1\",\n\t5742:  \"ida-discover2\",\n\t5743:  \"watchdoc-pod\",\n\t5744:  \"watchdoc\",\n\t5745:  \"fcopy-server\",\n\t5746:  \"fcopys-server\",\n\t5747:  \"tunatic\",\n\t5748:  \"tunalyzer\",\n\t5750:  \"rscd\",\n\t5755:  \"openmailg\",\n\t5757:  \"x500ms\",\n\t5766:  \"openmailns\",\n\t5767:  \"s-openmail\",\n\t5768:  \"openmailpxy\",\n\t5769:  \"spramsca\",\n\t5770:  \"spramsd\",\n\t5771:  \"netagent\",\n\t5777:  \"dali-port\",\n\t5780:  \"vts-rpc\",\n\t5781:  \"3par-evts\",\n\t5782:  \"3par-mgmt\",\n\t5783:  \"3par-mgmt-ssl\",\n\t5785:  \"3par-rcopy\",\n\t5793:  \"xtreamx\",\n\t5813:  \"icmpd\",\n\t5814:  \"spt-automation\",\n\t5841:  \"shiprush-d-ch\",\n\t5842:  \"reversion\",\n\t5859:  \"wherehoo\",\n\t5863:  \"ppsuitemsg\",\n\t5868:  \"diameters\",\n\t5883:  \"jute\",\n\t5900:  \"rfb\",\n\t5910:  \"cm\",\n\t5911:  \"cpdlc\",\n\t5912:  \"fis\",\n\t5913:  \"ads-c\",\n\t5963:  \"indy\",\n\t5968:  \"mppolicy-v5\",\n\t5969:  \"mppolicy-mgr\",\n\t5984:  \"couchdb\",\n\t5985:  \"wsman\",\n\t5986:  \"wsmans\",\n\t5987:  \"wbem-rmi\",\n\t5988:  \"wbem-http\",\n\t5989:  \"wbem-https\",\n\t5990:  \"wbem-exp-https\",\n\t5991:  \"nuxsl\",\n\t5992:  \"consul-insight\",\n\t5993:  \"cim-rs\",\n\t5999:  \"cvsup\",\n\t6064:  \"ndl-ahp-svc\",\n\t6065:  \"winpharaoh\",\n\t6066:  \"ewctsp\",\n\t6068:  \"gsmp-ancp\",\n\t6069:  \"trip\",\n\t6070:  \"messageasap\",\n\t6071:  \"ssdtp\",\n\t6072:  \"diagnose-proc\",\n\t6073:  \"directplay8\",\n\t6074:  \"max\",\n\t6075:  \"dpm-acm\",\n\t6076:  \"msft-dpm-cert\",\n\t6077:  \"iconstructsrv\",\n\t6084:  \"reload-config\",\n\t6085:  \"konspire2b\",\n\t6086:  \"pdtp\",\n\t6087:  \"ldss\",\n\t6088:  \"doglms\",\n\t6099:  \"raxa-mgmt\",\n\t6100:  \"synchronet-db\",\n\t6101:  \"synchronet-rtc\",\n\t6102:  \"synchronet-upd\",\n\t6103:  \"rets\",\n\t6104:  \"dbdb\",\n\t6105:  \"primaserver\",\n\t6106:  \"mpsserver\",\n\t6107:  \"etc-control\",\n\t6108:  \"sercomm-scadmin\",\n\t6109:  \"globecast-id\",\n\t6110:  \"softcm\",\n\t6111:  \"spc\",\n\t6112:  \"dtspcd\",\n\t6113:  \"dayliteserver\",\n\t6114:  \"wrspice\",\n\t6115:  \"xic\",\n\t6116:  \"xtlserv\",\n\t6117:  \"daylitetouch\",\n\t6121:  \"spdy\",\n\t6122:  \"bex-webadmin\",\n\t6123:  \"backup-express\",\n\t6124:  \"pnbs\",\n\t6130:  \"damewaremobgtwy\",\n\t6133:  \"nbt-wol\",\n\t6140:  \"pulsonixnls\",\n\t6141:  \"meta-corp\",\n\t6142:  \"aspentec-lm\",\n\t6143:  \"watershed-lm\",\n\t6144:  \"statsci1-lm\",\n\t6145:  \"statsci2-lm\",\n\t6146:  \"lonewolf-lm\",\n\t6147:  \"montage-lm\",\n\t6148:  \"ricardo-lm\",\n\t6149:  \"tal-pod\",\n\t6159:  \"efb-aci\",\n\t6160:  \"ecmp\",\n\t6161:  \"patrol-ism\",\n\t6162:  \"patrol-coll\",\n\t6163:  \"pscribe\",\n\t6200:  \"lm-x\",\n\t6209:  \"qmtps\",\n\t6222:  \"radmind\",\n\t6241:  \"jeol-nsdtp-1\",\n\t6242:  \"jeol-nsdtp-2\",\n\t6243:  \"jeol-nsdtp-3\",\n\t6244:  \"jeol-nsdtp-4\",\n\t6251:  \"tl1-raw-ssl\",\n\t6252:  \"tl1-ssh\",\n\t6253:  \"crip\",\n\t6267:  \"gld\",\n\t6268:  \"grid\",\n\t6269:  \"grid-alt\",\n\t6300:  \"bmc-grx\",\n\t6301:  \"bmc-ctd-ldap\",\n\t6306:  \"ufmp\",\n\t6315:  \"scup\",\n\t6316:  \"abb-escp\",\n\t6317:  \"nav-data-cmd\",\n\t6320:  \"repsvc\",\n\t6321:  \"emp-server1\",\n\t6322:  \"emp-server2\",\n\t6324:  \"hrd-ncs\",\n\t6325:  \"dt-mgmtsvc\",\n\t6326:  \"dt-vra\",\n\t6343:  \"sflow\",\n\t6344:  \"streletz\",\n\t6346:  \"gnutella-svc\",\n\t6347:  \"gnutella-rtr\",\n\t6350:  \"adap\",\n\t6355:  \"pmcs\",\n\t6360:  \"metaedit-mu\",\n\t6370:  \"metaedit-se\",\n\t6379:  \"redis\",\n\t6382:  \"metatude-mds\",\n\t6389:  \"clariion-evr01\",\n\t6390:  \"metaedit-ws\",\n\t6417:  \"faxcomservice\",\n\t6418:  \"syserverremote\",\n\t6419:  \"svdrp\",\n\t6420:  \"nim-vdrshell\",\n\t6421:  \"nim-wan\",\n\t6432:  \"pgbouncer\",\n\t6442:  \"tarp\",\n\t6443:  \"sun-sr-https\",\n\t6444:  \"sge-qmaster\",\n\t6445:  \"sge-execd\",\n\t6446:  \"mysql-proxy\",\n\t6455:  \"skip-cert-recv\",\n\t6456:  \"skip-cert-send\",\n\t6464:  \"ieee11073-20701\",\n\t6471:  \"lvision-lm\",\n\t6480:  \"sun-sr-http\",\n\t6481:  \"servicetags\",\n\t6482:  \"ldoms-mgmt\",\n\t6483:  \"SunVTS-RMI\",\n\t6484:  \"sun-sr-jms\",\n\t6485:  \"sun-sr-iiop\",\n\t6486:  \"sun-sr-iiops\",\n\t6487:  \"sun-sr-iiop-aut\",\n\t6488:  \"sun-sr-jmx\",\n\t6489:  \"sun-sr-admin\",\n\t6500:  \"boks\",\n\t6501:  \"boks-servc\",\n\t6502:  \"boks-servm\",\n\t6503:  \"boks-clntd\",\n\t6505:  \"badm-priv\",\n\t6506:  \"badm-pub\",\n\t6507:  \"bdir-priv\",\n\t6508:  \"bdir-pub\",\n\t6509:  \"mgcs-mfp-port\",\n\t6510:  \"mcer-port\",\n\t6513:  \"netconf-tls\",\n\t6514:  \"syslog-tls\",\n\t6515:  \"elipse-rec\",\n\t6543:  \"lds-distrib\",\n\t6544:  \"lds-dump\",\n\t6547:  \"apc-6547\",\n\t6548:  \"apc-6548\",\n\t6549:  \"apc-6549\",\n\t6550:  \"fg-sysupdate\",\n\t6551:  \"sum\",\n\t6558:  \"xdsxdm\",\n\t6566:  \"sane-port\",\n\t6568:  \"canit-store\",\n\t6579:  \"affiliate\",\n\t6580:  \"parsec-master\",\n\t6581:  \"parsec-peer\",\n\t6582:  \"parsec-game\",\n\t6583:  \"joaJewelSuite\",\n\t6600:  \"mshvlm\",\n\t6601:  \"mstmg-sstp\",\n\t6602:  \"wsscomfrmwk\",\n\t6619:  \"odette-ftps\",\n\t6620:  \"kftp-data\",\n\t6621:  \"kftp\",\n\t6622:  \"mcftp\",\n\t6623:  \"ktelnet\",\n\t6624:  \"datascaler-db\",\n\t6625:  \"datascaler-ctl\",\n\t6626:  \"wago-service\",\n\t6627:  \"nexgen\",\n\t6628:  \"afesc-mc\",\n\t6629:  \"nexgen-aux\",\n\t6632:  \"mxodbc-connect\",\n\t6640:  \"ovsdb\",\n\t6653:  \"openflow\",\n\t6655:  \"pcs-sf-ui-man\",\n\t6656:  \"emgmsg\",\n\t6670:  \"vocaltec-gold\",\n\t6671:  \"p4p-portal\",\n\t6672:  \"vision-server\",\n\t6673:  \"vision-elmd\",\n\t6678:  \"vfbp\",\n\t6679:  \"osaut\",\n\t6687:  \"clever-ctrace\",\n\t6688:  \"clever-tcpip\",\n\t6689:  \"tsa\",\n\t6690:  \"cleverdetect\",\n\t6697:  \"ircs-u\",\n\t6701:  \"kti-icad-srvr\",\n\t6702:  \"e-design-net\",\n\t6703:  \"e-design-web\",\n\t6714:  \"ibprotocol\",\n\t6715:  \"fibotrader-com\",\n\t6716:  \"princity-agent\",\n\t6767:  \"bmc-perf-agent\",\n\t6768:  \"bmc-perf-mgrd\",\n\t6769:  \"adi-gxp-srvprt\",\n\t6770:  \"plysrv-http\",\n\t6771:  \"plysrv-https\",\n\t6777:  \"ntz-tracker\",\n\t6778:  \"ntz-p2p-storage\",\n\t6785:  \"dgpf-exchg\",\n\t6786:  \"smc-jmx\",\n\t6787:  \"smc-admin\",\n\t6788:  \"smc-http\",\n\t6789:  \"radg\",\n\t6790:  \"hnmp\",\n\t6791:  \"hnm\",\n\t6801:  \"acnet\",\n\t6817:  \"pentbox-sim\",\n\t6831:  \"ambit-lm\",\n\t6841:  \"netmo-default\",\n\t6842:  \"netmo-http\",\n\t6850:  \"iccrushmore\",\n\t6868:  \"acctopus-cc\",\n\t6888:  \"muse\",\n\t6900:  \"rtimeviewer\",\n\t6901:  \"jetstream\",\n\t6935:  \"ethoscan\",\n\t6936:  \"xsmsvc\",\n\t6946:  \"bioserver\",\n\t6951:  \"otlp\",\n\t6961:  \"jmact3\",\n\t6962:  \"jmevt2\",\n\t6963:  \"swismgr1\",\n\t6964:  \"swismgr2\",\n\t6965:  \"swistrap\",\n\t6966:  \"swispol\",\n\t6969:  \"acmsoda\",\n\t6970:  \"conductor\",\n\t6997:  \"MobilitySrv\",\n\t6998:  \"iatp-highpri\",\n\t6999:  \"iatp-normalpri\",\n\t7000:  \"afs3-fileserver\",\n\t7001:  \"afs3-callback\",\n\t7002:  \"afs3-prserver\",\n\t7003:  \"afs3-vlserver\",\n\t7004:  \"afs3-kaserver\",\n\t7005:  \"afs3-volser\",\n\t7006:  \"afs3-errors\",\n\t7007:  \"afs3-bos\",\n\t7008:  \"afs3-update\",\n\t7009:  \"afs3-rmtsys\",\n\t7010:  \"ups-onlinet\",\n\t7011:  \"talon-disc\",\n\t7012:  \"talon-engine\",\n\t7013:  \"microtalon-dis\",\n\t7014:  \"microtalon-com\",\n\t7015:  \"talon-webserver\",\n\t7016:  \"spg\",\n\t7017:  \"grasp\",\n\t7018:  \"fisa-svc\",\n\t7019:  \"doceri-ctl\",\n\t7020:  \"dpserve\",\n\t7021:  \"dpserveadmin\",\n\t7022:  \"ctdp\",\n\t7023:  \"ct2nmcs\",\n\t7024:  \"vmsvc\",\n\t7025:  \"vmsvc-2\",\n\t7030:  \"op-probe\",\n\t7031:  \"iposplanet\",\n\t7070:  \"arcp\",\n\t7071:  \"iwg1\",\n\t7073:  \"martalk\",\n\t7080:  \"empowerid\",\n\t7099:  \"lazy-ptop\",\n\t7100:  \"font-service\",\n\t7101:  \"elcn\",\n\t7117:  \"rothaga\",\n\t7121:  \"virprot-lm\",\n\t7128:  \"scenidm\",\n\t7129:  \"scenccs\",\n\t7161:  \"cabsm-comm\",\n\t7162:  \"caistoragemgr\",\n\t7163:  \"cacsambroker\",\n\t7164:  \"fsr\",\n\t7165:  \"doc-server\",\n\t7166:  \"aruba-server\",\n\t7167:  \"casrmagent\",\n\t7168:  \"cnckadserver\",\n\t7169:  \"ccag-pib\",\n\t7170:  \"nsrp\",\n\t7171:  \"drm-production\",\n\t7172:  \"metalbend\",\n\t7173:  \"zsecure\",\n\t7174:  \"clutild\",\n\t7200:  \"fodms\",\n\t7201:  \"dlip\",\n\t7202:  \"pon-ictp\",\n\t7215:  \"PS-Server\",\n\t7216:  \"PS-Capture-Pro\",\n\t7227:  \"ramp\",\n\t7228:  \"citrixupp\",\n\t7229:  \"citrixuppg\",\n\t7236:  \"display\",\n\t7237:  \"pads\",\n\t7244:  \"frc-hicp\",\n\t7262:  \"cnap\",\n\t7272:  \"watchme-7272\",\n\t7273:  \"oma-rlp\",\n\t7274:  \"oma-rlp-s\",\n\t7275:  \"oma-ulp\",\n\t7276:  \"oma-ilp\",\n\t7277:  \"oma-ilp-s\",\n\t7278:  \"oma-dcdocbs\",\n\t7279:  \"ctxlic\",\n\t7280:  \"itactionserver1\",\n\t7281:  \"itactionserver2\",\n\t7282:  \"mzca-action\",\n\t7283:  \"genstat\",\n\t7365:  \"lcm-server\",\n\t7391:  \"mindfilesys\",\n\t7392:  \"mrssrendezvous\",\n\t7393:  \"nfoldman\",\n\t7394:  \"fse\",\n\t7395:  \"winqedit\",\n\t7397:  \"hexarc\",\n\t7400:  \"rtps-discovery\",\n\t7401:  \"rtps-dd-ut\",\n\t7402:  \"rtps-dd-mt\",\n\t7410:  \"ionixnetmon\",\n\t7411:  \"daqstream\",\n\t7421:  \"mtportmon\",\n\t7426:  \"pmdmgr\",\n\t7427:  \"oveadmgr\",\n\t7428:  \"ovladmgr\",\n\t7429:  \"opi-sock\",\n\t7430:  \"xmpv7\",\n\t7431:  \"pmd\",\n\t7437:  \"faximum\",\n\t7443:  \"oracleas-https\",\n\t7471:  \"sttunnel\",\n\t7473:  \"rise\",\n\t7474:  \"neo4j\",\n\t7478:  \"openit\",\n\t7491:  \"telops-lmd\",\n\t7500:  \"silhouette\",\n\t7501:  \"ovbus\",\n\t7508:  \"adcp\",\n\t7509:  \"acplt\",\n\t7510:  \"ovhpas\",\n\t7511:  \"pafec-lm\",\n\t7542:  \"saratoga\",\n\t7543:  \"atul\",\n\t7544:  \"nta-ds\",\n\t7545:  \"nta-us\",\n\t7546:  \"cfs\",\n\t7547:  \"cwmp\",\n\t7548:  \"tidp\",\n\t7549:  \"nls-tl\",\n\t7551:  \"controlone-con\",\n\t7560:  \"sncp\",\n\t7563:  \"cfw\",\n\t7566:  \"vsi-omega\",\n\t7569:  \"dell-eql-asm\",\n\t7570:  \"aries-kfinder\",\n\t7574:  \"coherence\",\n\t7588:  \"sun-lm\",\n\t7606:  \"mipi-debug\",\n\t7624:  \"indi\",\n\t7626:  \"simco\",\n\t7627:  \"soap-http\",\n\t7628:  \"zen-pawn\",\n\t7629:  \"xdas\",\n\t7630:  \"hawk\",\n\t7631:  \"tesla-sys-msg\",\n\t7633:  \"pmdfmgt\",\n\t7648:  \"cuseeme\",\n\t7672:  \"imqstomp\",\n\t7673:  \"imqstomps\",\n\t7674:  \"imqtunnels\",\n\t7675:  \"imqtunnel\",\n\t7676:  \"imqbrokerd\",\n\t7677:  \"sun-user-https\",\n\t7680:  \"pando-pub\",\n\t7683:  \"dmt\",\n\t7687:  \"bolt\",\n\t7689:  \"collaber\",\n\t7697:  \"klio\",\n\t7700:  \"em7-secom\",\n\t7707:  \"sync-em7\",\n\t7708:  \"scinet\",\n\t7720:  \"medimageportal\",\n\t7724:  \"nsdeepfreezectl\",\n\t7725:  \"nitrogen\",\n\t7726:  \"freezexservice\",\n\t7727:  \"trident-data\",\n\t7728:  \"osvr\",\n\t7734:  \"smip\",\n\t7738:  \"aiagent\",\n\t7741:  \"scriptview\",\n\t7742:  \"msss\",\n\t7743:  \"sstp-1\",\n\t7744:  \"raqmon-pdu\",\n\t7747:  \"prgp\",\n\t7775:  \"inetfs\",\n\t7777:  \"cbt\",\n\t7778:  \"interwise\",\n\t7779:  \"vstat\",\n\t7781:  \"accu-lmgr\",\n\t7786:  \"minivend\",\n\t7787:  \"popup-reminders\",\n\t7789:  \"office-tools\",\n\t7794:  \"q3ade\",\n\t7797:  \"pnet-conn\",\n\t7798:  \"pnet-enc\",\n\t7799:  \"altbsdp\",\n\t7800:  \"asr\",\n\t7801:  \"ssp-client\",\n\t7810:  \"rbt-wanopt\",\n\t7845:  \"apc-7845\",\n\t7846:  \"apc-7846\",\n\t7847:  \"csoauth\",\n\t7869:  \"mobileanalyzer\",\n\t7870:  \"rbt-smc\",\n\t7871:  \"mdm\",\n\t7878:  \"owms\",\n\t7880:  \"pss\",\n\t7887:  \"ubroker\",\n\t7900:  \"mevent\",\n\t7901:  \"tnos-sp\",\n\t7902:  \"tnos-dp\",\n\t7903:  \"tnos-dps\",\n\t7913:  \"qo-secure\",\n\t7932:  \"t2-drm\",\n\t7933:  \"t2-brm\",\n\t7962:  \"generalsync\",\n\t7967:  \"supercell\",\n\t7979:  \"micromuse-ncps\",\n\t7980:  \"quest-vista\",\n\t7981:  \"sossd-collect\",\n\t7982:  \"sossd-agent\",\n\t7997:  \"pushns\",\n\t7999:  \"irdmi2\",\n\t8000:  \"irdmi\",\n\t8001:  \"vcom-tunnel\",\n\t8002:  \"teradataordbms\",\n\t8003:  \"mcreport\",\n\t8005:  \"mxi\",\n\t8006:  \"wpl-analytics\",\n\t8007:  \"warppipe\",\n\t8008:  \"http-alt\",\n\t8019:  \"qbdb\",\n\t8020:  \"intu-ec-svcdisc\",\n\t8021:  \"intu-ec-client\",\n\t8022:  \"oa-system\",\n\t8025:  \"ca-audit-da\",\n\t8026:  \"ca-audit-ds\",\n\t8032:  \"pro-ed\",\n\t8033:  \"mindprint\",\n\t8034:  \"vantronix-mgmt\",\n\t8040:  \"ampify\",\n\t8041:  \"enguity-xccetp\",\n\t8042:  \"fs-agent\",\n\t8043:  \"fs-server\",\n\t8044:  \"fs-mgmt\",\n\t8051:  \"rocrail\",\n\t8052:  \"senomix01\",\n\t8053:  \"senomix02\",\n\t8054:  \"senomix03\",\n\t8055:  \"senomix04\",\n\t8056:  \"senomix05\",\n\t8057:  \"senomix06\",\n\t8058:  \"senomix07\",\n\t8059:  \"senomix08\",\n\t8066:  \"toad-bi-appsrvr\",\n\t8067:  \"infi-async\",\n\t8070:  \"ucs-isc\",\n\t8074:  \"gadugadu\",\n\t8077:  \"mles\",\n\t8080:  \"http-alt\",\n\t8081:  \"sunproxyadmin\",\n\t8082:  \"us-cli\",\n\t8083:  \"us-srv\",\n\t8086:  \"d-s-n\",\n\t8087:  \"simplifymedia\",\n\t8088:  \"radan-http\",\n\t8090:  \"opsmessaging\",\n\t8091:  \"jamlink\",\n\t8097:  \"sac\",\n\t8100:  \"xprint-server\",\n\t8101:  \"ldoms-migr\",\n\t8102:  \"kz-migr\",\n\t8115:  \"mtl8000-matrix\",\n\t8116:  \"cp-cluster\",\n\t8117:  \"purityrpc\",\n\t8118:  \"privoxy\",\n\t8121:  \"apollo-data\",\n\t8122:  \"apollo-admin\",\n\t8128:  \"paycash-online\",\n\t8129:  \"paycash-wbp\",\n\t8130:  \"indigo-vrmi\",\n\t8131:  \"indigo-vbcp\",\n\t8132:  \"dbabble\",\n\t8140:  \"puppet\",\n\t8148:  \"isdd\",\n\t8153:  \"quantastor\",\n\t8160:  \"patrol\",\n\t8161:  \"patrol-snmp\",\n\t8162:  \"lpar2rrd\",\n\t8181:  \"intermapper\",\n\t8182:  \"vmware-fdm\",\n\t8183:  \"proremote\",\n\t8184:  \"itach\",\n\t8190:  \"gcp-rphy\",\n\t8191:  \"limnerpressure\",\n\t8192:  \"spytechphone\",\n\t8194:  \"blp1\",\n\t8195:  \"blp2\",\n\t8199:  \"vvr-data\",\n\t8200:  \"trivnet1\",\n\t8201:  \"trivnet2\",\n\t8204:  \"lm-perfworks\",\n\t8205:  \"lm-instmgr\",\n\t8206:  \"lm-dta\",\n\t8207:  \"lm-sserver\",\n\t8208:  \"lm-webwatcher\",\n\t8230:  \"rexecj\",\n\t8243:  \"synapse-nhttps\",\n\t8270:  \"robot-remote\",\n\t8276:  \"pando-sec\",\n\t8280:  \"synapse-nhttp\",\n\t8282:  \"libelle\",\n\t8292:  \"blp3\",\n\t8293:  \"hiperscan-id\",\n\t8294:  \"blp4\",\n\t8300:  \"tmi\",\n\t8301:  \"amberon\",\n\t8313:  \"hub-open-net\",\n\t8320:  \"tnp-discover\",\n\t8321:  \"tnp\",\n\t8322:  \"garmin-marine\",\n\t8351:  \"server-find\",\n\t8376:  \"cruise-enum\",\n\t8377:  \"cruise-swroute\",\n\t8378:  \"cruise-config\",\n\t8379:  \"cruise-diags\",\n\t8380:  \"cruise-update\",\n\t8383:  \"m2mservices\",\n\t8400:  \"cvd\",\n\t8401:  \"sabarsd\",\n\t8402:  \"abarsd\",\n\t8403:  \"admind\",\n\t8404:  \"svcloud\",\n\t8405:  \"svbackup\",\n\t8415:  \"dlpx-sp\",\n\t8416:  \"espeech\",\n\t8417:  \"espeech-rtp\",\n\t8423:  \"aritts\",\n\t8442:  \"cybro-a-bus\",\n\t8443:  \"pcsync-https\",\n\t8444:  \"pcsync-http\",\n\t8445:  \"copy\",\n\t8450:  \"npmp\",\n\t8457:  \"nexentamv\",\n\t8470:  \"cisco-avp\",\n\t8471:  \"pim-port\",\n\t8472:  \"otv\",\n\t8473:  \"vp2p\",\n\t8474:  \"noteshare\",\n\t8500:  \"fmtp\",\n\t8501:  \"cmtp-mgt\",\n\t8502:  \"ftnmtp\",\n\t8554:  \"rtsp-alt\",\n\t8555:  \"d-fence\",\n\t8567:  \"dof-tunnel\",\n\t8600:  \"asterix\",\n\t8610:  \"canon-mfnp\",\n\t8611:  \"canon-bjnp1\",\n\t8612:  \"canon-bjnp2\",\n\t8613:  \"canon-bjnp3\",\n\t8614:  \"canon-bjnp4\",\n\t8615:  \"imink\",\n\t8665:  \"monetra\",\n\t8666:  \"monetra-admin\",\n\t8675:  \"msi-cps-rm\",\n\t8686:  \"sun-as-jmxrmi\",\n\t8688:  \"openremote-ctrl\",\n\t8699:  \"vnyx\",\n\t8711:  \"nvc\",\n\t8733:  \"ibus\",\n\t8750:  \"dey-keyneg\",\n\t8763:  \"mc-appserver\",\n\t8764:  \"openqueue\",\n\t8765:  \"ultraseek-http\",\n\t8766:  \"amcs\",\n\t8770:  \"dpap\",\n\t8778:  \"uec\",\n\t8786:  \"msgclnt\",\n\t8787:  \"msgsrvr\",\n\t8793:  \"acd-pm\",\n\t8800:  \"sunwebadmin\",\n\t8804:  \"truecm\",\n\t8873:  \"dxspider\",\n\t8880:  \"cddbp-alt\",\n\t8881:  \"galaxy4d\",\n\t8883:  \"secure-mqtt\",\n\t8888:  \"ddi-tcp-1\",\n\t8889:  \"ddi-tcp-2\",\n\t8890:  \"ddi-tcp-3\",\n\t8891:  \"ddi-tcp-4\",\n\t8892:  \"ddi-tcp-5\",\n\t8893:  \"ddi-tcp-6\",\n\t8894:  \"ddi-tcp-7\",\n\t8899:  \"ospf-lite\",\n\t8900:  \"jmb-cds1\",\n\t8901:  \"jmb-cds2\",\n\t8910:  \"manyone-http\",\n\t8911:  \"manyone-xml\",\n\t8912:  \"wcbackup\",\n\t8913:  \"dragonfly\",\n\t8937:  \"twds\",\n\t8953:  \"ub-dns-control\",\n\t8954:  \"cumulus-admin\",\n\t8980:  \"nod-provider\",\n\t8989:  \"sunwebadmins\",\n\t8990:  \"http-wmap\",\n\t8991:  \"https-wmap\",\n\t8997:  \"oracle-ms-ens\",\n\t8998:  \"canto-roboflow\",\n\t8999:  \"bctp\",\n\t9000:  \"cslistener\",\n\t9001:  \"etlservicemgr\",\n\t9002:  \"dynamid\",\n\t9005:  \"golem\",\n\t9008:  \"ogs-server\",\n\t9009:  \"pichat\",\n\t9010:  \"sdr\",\n\t9020:  \"tambora\",\n\t9021:  \"panagolin-ident\",\n\t9022:  \"paragent\",\n\t9023:  \"swa-1\",\n\t9024:  \"swa-2\",\n\t9025:  \"swa-3\",\n\t9026:  \"swa-4\",\n\t9050:  \"versiera\",\n\t9051:  \"fio-cmgmt\",\n\t9060:  \"CardWeb-IO\",\n\t9080:  \"glrpc\",\n\t9083:  \"emc-pp-mgmtsvc\",\n\t9084:  \"aurora\",\n\t9085:  \"ibm-rsyscon\",\n\t9086:  \"net2display\",\n\t9087:  \"classic\",\n\t9088:  \"sqlexec\",\n\t9089:  \"sqlexec-ssl\",\n\t9090:  \"websm\",\n\t9091:  \"xmltec-xmlmail\",\n\t9092:  \"XmlIpcRegSvc\",\n\t9093:  \"copycat\",\n\t9100:  \"hp-pdl-datastr\",\n\t9101:  \"bacula-dir\",\n\t9102:  \"bacula-fd\",\n\t9103:  \"bacula-sd\",\n\t9104:  \"peerwire\",\n\t9105:  \"xadmin\",\n\t9106:  \"astergate\",\n\t9107:  \"astergatefax\",\n\t9119:  \"mxit\",\n\t9122:  \"grcmp\",\n\t9123:  \"grcp\",\n\t9131:  \"dddp\",\n\t9160:  \"apani1\",\n\t9161:  \"apani2\",\n\t9162:  \"apani3\",\n\t9163:  \"apani4\",\n\t9164:  \"apani5\",\n\t9191:  \"sun-as-jpda\",\n\t9200:  \"wap-wsp\",\n\t9201:  \"wap-wsp-wtp\",\n\t9202:  \"wap-wsp-s\",\n\t9203:  \"wap-wsp-wtp-s\",\n\t9204:  \"wap-vcard\",\n\t9205:  \"wap-vcal\",\n\t9206:  \"wap-vcard-s\",\n\t9207:  \"wap-vcal-s\",\n\t9208:  \"rjcdb-vcards\",\n\t9209:  \"almobile-system\",\n\t9210:  \"oma-mlp\",\n\t9211:  \"oma-mlp-s\",\n\t9212:  \"serverviewdbms\",\n\t9213:  \"serverstart\",\n\t9214:  \"ipdcesgbs\",\n\t9215:  \"insis\",\n\t9216:  \"acme\",\n\t9217:  \"fsc-port\",\n\t9222:  \"teamcoherence\",\n\t9255:  \"mon\",\n\t9278:  \"pegasus\",\n\t9279:  \"pegasus-ctl\",\n\t9280:  \"pgps\",\n\t9281:  \"swtp-port1\",\n\t9282:  \"swtp-port2\",\n\t9283:  \"callwaveiam\",\n\t9284:  \"visd\",\n\t9285:  \"n2h2server\",\n\t9287:  \"cumulus\",\n\t9292:  \"armtechdaemon\",\n\t9293:  \"storview\",\n\t9294:  \"armcenterhttp\",\n\t9295:  \"armcenterhttps\",\n\t9300:  \"vrace\",\n\t9306:  \"sphinxql\",\n\t9312:  \"sphinxapi\",\n\t9318:  \"secure-ts\",\n\t9321:  \"guibase\",\n\t9343:  \"mpidcmgr\",\n\t9344:  \"mphlpdmc\",\n\t9345:  \"rancher\",\n\t9346:  \"ctechlicensing\",\n\t9374:  \"fjdmimgr\",\n\t9380:  \"boxp\",\n\t9387:  \"d2dconfig\",\n\t9388:  \"d2ddatatrans\",\n\t9389:  \"adws\",\n\t9390:  \"otp\",\n\t9396:  \"fjinvmgr\",\n\t9397:  \"mpidcagt\",\n\t9400:  \"sec-t4net-srv\",\n\t9401:  \"sec-t4net-clt\",\n\t9402:  \"sec-pc2fax-srv\",\n\t9418:  \"git\",\n\t9443:  \"tungsten-https\",\n\t9444:  \"wso2esb-console\",\n\t9445:  \"mindarray-ca\",\n\t9450:  \"sntlkeyssrvr\",\n\t9500:  \"ismserver\",\n\t9535:  \"mngsuite\",\n\t9536:  \"laes-bf\",\n\t9555:  \"trispen-sra\",\n\t9592:  \"ldgateway\",\n\t9593:  \"cba8\",\n\t9594:  \"msgsys\",\n\t9595:  \"pds\",\n\t9596:  \"mercury-disc\",\n\t9597:  \"pd-admin\",\n\t9598:  \"vscp\",\n\t9599:  \"robix\",\n\t9600:  \"micromuse-ncpw\",\n\t9612:  \"streamcomm-ds\",\n\t9614:  \"iadt-tls\",\n\t9616:  \"erunbook-agent\",\n\t9617:  \"erunbook-server\",\n\t9618:  \"condor\",\n\t9628:  \"odbcpathway\",\n\t9629:  \"uniport\",\n\t9630:  \"peoctlr\",\n\t9631:  \"peocoll\",\n\t9640:  \"pqsflows\",\n\t9666:  \"zoomcp\",\n\t9667:  \"xmms2\",\n\t9668:  \"tec5-sdctp\",\n\t9694:  \"client-wakeup\",\n\t9695:  \"ccnx\",\n\t9700:  \"board-roar\",\n\t9747:  \"l5nas-parchan\",\n\t9750:  \"board-voip\",\n\t9753:  \"rasadv\",\n\t9762:  \"tungsten-http\",\n\t9800:  \"davsrc\",\n\t9801:  \"sstp-2\",\n\t9802:  \"davsrcs\",\n\t9875:  \"sapv1\",\n\t9876:  \"sd\",\n\t9888:  \"cyborg-systems\",\n\t9889:  \"gt-proxy\",\n\t9898:  \"monkeycom\",\n\t9900:  \"iua\",\n\t9909:  \"domaintime\",\n\t9911:  \"sype-transport\",\n\t9925:  \"xybrid-cloud\",\n\t9950:  \"apc-9950\",\n\t9951:  \"apc-9951\",\n\t9952:  \"apc-9952\",\n\t9953:  \"acis\",\n\t9954:  \"hinp\",\n\t9955:  \"alljoyn-stm\",\n\t9966:  \"odnsp\",\n\t9978:  \"xybrid-rt\",\n\t9979:  \"visweather\",\n\t9981:  \"pumpkindb\",\n\t9987:  \"dsm-scm-target\",\n\t9988:  \"nsesrvr\",\n\t9990:  \"osm-appsrvr\",\n\t9991:  \"osm-oev\",\n\t9992:  \"palace-1\",\n\t9993:  \"palace-2\",\n\t9994:  \"palace-3\",\n\t9995:  \"palace-4\",\n\t9996:  \"palace-5\",\n\t9997:  \"palace-6\",\n\t9998:  \"distinct32\",\n\t9999:  \"distinct\",\n\t10000: \"ndmp\",\n\t10001: \"scp-config\",\n\t10002: \"documentum\",\n\t10003: \"documentum-s\",\n\t10004: \"emcrmirccd\",\n\t10005: \"emcrmird\",\n\t10006: \"netapp-sync\",\n\t10007: \"mvs-capacity\",\n\t10008: \"octopus\",\n\t10009: \"swdtp-sv\",\n\t10010: \"rxapi\",\n\t10020: \"abb-hw\",\n\t10050: \"zabbix-agent\",\n\t10051: \"zabbix-trapper\",\n\t10055: \"qptlmd\",\n\t10080: \"amanda\",\n\t10081: \"famdc\",\n\t10100: \"itap-ddtp\",\n\t10101: \"ezmeeting-2\",\n\t10102: \"ezproxy-2\",\n\t10103: \"ezrelay\",\n\t10104: \"swdtp\",\n\t10107: \"bctp-server\",\n\t10110: \"nmea-0183\",\n\t10113: \"netiq-endpoint\",\n\t10114: \"netiq-qcheck\",\n\t10115: \"netiq-endpt\",\n\t10116: \"netiq-voipa\",\n\t10117: \"iqrm\",\n\t10125: \"cimple\",\n\t10128: \"bmc-perf-sd\",\n\t10129: \"bmc-gms\",\n\t10160: \"qb-db-server\",\n\t10161: \"snmptls\",\n\t10162: \"snmptls-trap\",\n\t10200: \"trisoap\",\n\t10201: \"rsms\",\n\t10252: \"apollo-relay\",\n\t10260: \"axis-wimp-port\",\n\t10261: \"tile-ml\",\n\t10288: \"blocks\",\n\t10321: \"cosir\",\n\t10540: \"MOS-lower\",\n\t10541: \"MOS-upper\",\n\t10542: \"MOS-aux\",\n\t10543: \"MOS-soap\",\n\t10544: \"MOS-soap-opt\",\n\t10548: \"serverdocs\",\n\t10631: \"printopia\",\n\t10800: \"gap\",\n\t10805: \"lpdg\",\n\t10809: \"nbd\",\n\t10860: \"helix\",\n\t10880: \"bveapi\",\n\t10933: \"octopustentacle\",\n\t10990: \"rmiaux\",\n\t11000: \"irisa\",\n\t11001: \"metasys\",\n\t11095: \"weave\",\n\t11103: \"origo-sync\",\n\t11104: \"netapp-icmgmt\",\n\t11105: \"netapp-icdata\",\n\t11106: \"sgi-lk\",\n\t11109: \"sgi-dmfmgr\",\n\t11110: \"sgi-soap\",\n\t11111: \"vce\",\n\t11112: \"dicom\",\n\t11161: \"suncacao-snmp\",\n\t11162: \"suncacao-jmxmp\",\n\t11163: \"suncacao-rmi\",\n\t11164: \"suncacao-csa\",\n\t11165: \"suncacao-websvc\",\n\t11172: \"oemcacao-jmxmp\",\n\t11173: \"t5-straton\",\n\t11174: \"oemcacao-rmi\",\n\t11175: \"oemcacao-websvc\",\n\t11201: \"smsqp\",\n\t11202: \"dcsl-backup\",\n\t11208: \"wifree\",\n\t11211: \"memcache\",\n\t11319: \"imip\",\n\t11320: \"imip-channels\",\n\t11321: \"arena-server\",\n\t11367: \"atm-uhas\",\n\t11371: \"hkp\",\n\t11489: \"asgcypresstcps\",\n\t11600: \"tempest-port\",\n\t11623: \"emc-xsw-dconfig\",\n\t11720: \"h323callsigalt\",\n\t11723: \"emc-xsw-dcache\",\n\t11751: \"intrepid-ssl\",\n\t11796: \"lanschool\",\n\t11876: \"xoraya\",\n\t11967: \"sysinfo-sp\",\n\t12000: \"entextxid\",\n\t12001: \"entextnetwk\",\n\t12002: \"entexthigh\",\n\t12003: \"entextmed\",\n\t12004: \"entextlow\",\n\t12005: \"dbisamserver1\",\n\t12006: \"dbisamserver2\",\n\t12007: \"accuracer\",\n\t12008: \"accuracer-dbms\",\n\t12010: \"edbsrvr\",\n\t12012: \"vipera\",\n\t12013: \"vipera-ssl\",\n\t12109: \"rets-ssl\",\n\t12121: \"nupaper-ss\",\n\t12168: \"cawas\",\n\t12172: \"hivep\",\n\t12300: \"linogridengine\",\n\t12302: \"rads\",\n\t12321: \"warehouse-sss\",\n\t12322: \"warehouse\",\n\t12345: \"italk\",\n\t12753: \"tsaf\",\n\t12865: \"netperf\",\n\t13160: \"i-zipqd\",\n\t13216: \"bcslogc\",\n\t13217: \"rs-pias\",\n\t13218: \"emc-vcas-tcp\",\n\t13223: \"powwow-client\",\n\t13224: \"powwow-server\",\n\t13400: \"doip-data\",\n\t13720: \"bprd\",\n\t13721: \"bpdbm\",\n\t13722: \"bpjava-msvc\",\n\t13724: \"vnetd\",\n\t13782: \"bpcd\",\n\t13783: \"vopied\",\n\t13785: \"nbdb\",\n\t13786: \"nomdb\",\n\t13818: \"dsmcc-config\",\n\t13819: \"dsmcc-session\",\n\t13820: \"dsmcc-passthru\",\n\t13821: \"dsmcc-download\",\n\t13822: \"dsmcc-ccp\",\n\t13823: \"bmdss\",\n\t13894: \"ucontrol\",\n\t13929: \"dta-systems\",\n\t13930: \"medevolve\",\n\t14000: \"scotty-ft\",\n\t14001: \"sua\",\n\t14033: \"sage-best-com1\",\n\t14034: \"sage-best-com2\",\n\t14141: \"vcs-app\",\n\t14142: \"icpp\",\n\t14143: \"icpps\",\n\t14145: \"gcm-app\",\n\t14149: \"vrts-tdd\",\n\t14150: \"vcscmd\",\n\t14154: \"vad\",\n\t14250: \"cps\",\n\t14414: \"ca-web-update\",\n\t14500: \"xpra\",\n\t14936: \"hde-lcesrvr-1\",\n\t14937: \"hde-lcesrvr-2\",\n\t15000: \"hydap\",\n\t15002: \"onep-tls\",\n\t15345: \"xpilot\",\n\t15363: \"3link\",\n\t15555: \"cisco-snat\",\n\t15660: \"bex-xr\",\n\t15740: \"ptp\",\n\t15999: \"programmar\",\n\t16000: \"fmsas\",\n\t16001: \"fmsascon\",\n\t16002: \"gsms\",\n\t16020: \"jwpc\",\n\t16021: \"jwpc-bin\",\n\t16161: \"sun-sea-port\",\n\t16162: \"solaris-audit\",\n\t16309: \"etb4j\",\n\t16310: \"pduncs\",\n\t16311: \"pdefmns\",\n\t16360: \"netserialext1\",\n\t16361: \"netserialext2\",\n\t16367: \"netserialext3\",\n\t16368: \"netserialext4\",\n\t16384: \"connected\",\n\t16385: \"rdgs\",\n\t16619: \"xoms\",\n\t16665: \"axon-tunnel\",\n\t16789: \"cadsisvr\",\n\t16900: \"newbay-snc-mc\",\n\t16950: \"sgcip\",\n\t16991: \"intel-rci-mp\",\n\t16992: \"amt-soap-http\",\n\t16993: \"amt-soap-https\",\n\t16994: \"amt-redir-tcp\",\n\t16995: \"amt-redir-tls\",\n\t17007: \"isode-dua\",\n\t17184: \"vestasdlp\",\n\t17185: \"soundsvirtual\",\n\t17219: \"chipper\",\n\t17220: \"avtp\",\n\t17221: \"avdecc\",\n\t17223: \"isa100-gci\",\n\t17225: \"trdp-md\",\n\t17234: \"integrius-stp\",\n\t17235: \"ssh-mgmt\",\n\t17500: \"db-lsp\",\n\t17555: \"ailith\",\n\t17729: \"ea\",\n\t17754: \"zep\",\n\t17755: \"zigbee-ip\",\n\t17756: \"zigbee-ips\",\n\t17777: \"sw-orion\",\n\t18000: \"biimenu\",\n\t18104: \"radpdf\",\n\t18136: \"racf\",\n\t18181: \"opsec-cvp\",\n\t18182: \"opsec-ufp\",\n\t18183: \"opsec-sam\",\n\t18184: \"opsec-lea\",\n\t18185: \"opsec-omi\",\n\t18186: \"ohsc\",\n\t18187: \"opsec-ela\",\n\t18241: \"checkpoint-rtm\",\n\t18242: \"iclid\",\n\t18243: \"clusterxl\",\n\t18262: \"gv-pf\",\n\t18463: \"ac-cluster\",\n\t18634: \"rds-ib\",\n\t18635: \"rds-ip\",\n\t18668: \"vdmmesh\",\n\t18769: \"ique\",\n\t18881: \"infotos\",\n\t18888: \"apc-necmp\",\n\t19000: \"igrid\",\n\t19007: \"scintilla\",\n\t19020: \"j-link\",\n\t19191: \"opsec-uaa\",\n\t19194: \"ua-secureagent\",\n\t19220: \"cora\",\n\t19283: \"keysrvr\",\n\t19315: \"keyshadow\",\n\t19398: \"mtrgtrans\",\n\t19410: \"hp-sco\",\n\t19411: \"hp-sca\",\n\t19412: \"hp-sessmon\",\n\t19539: \"fxuptp\",\n\t19540: \"sxuptp\",\n\t19541: \"jcp\",\n\t19998: \"iec-104-sec\",\n\t19999: \"dnp-sec\",\n\t20000: \"dnp\",\n\t20001: \"microsan\",\n\t20002: \"commtact-http\",\n\t20003: \"commtact-https\",\n\t20005: \"openwebnet\",\n\t20013: \"ss-idi\",\n\t20014: \"opendeploy\",\n\t20034: \"nburn-id\",\n\t20046: \"tmophl7mts\",\n\t20048: \"mountd\",\n\t20049: \"nfsrdma\",\n\t20057: \"avesterra\",\n\t20167: \"tolfab\",\n\t20202: \"ipdtp-port\",\n\t20222: \"ipulse-ics\",\n\t20480: \"emwavemsg\",\n\t20670: \"track\",\n\t20999: \"athand-mmp\",\n\t21000: \"irtrans\",\n\t21010: \"notezilla-lan\",\n\t21221: \"aigairserver\",\n\t21553: \"rdm-tfs\",\n\t21554: \"dfserver\",\n\t21590: \"vofr-gateway\",\n\t21800: \"tvpm\",\n\t21845: \"webphone\",\n\t21846: \"netspeak-is\",\n\t21847: \"netspeak-cs\",\n\t21848: \"netspeak-acd\",\n\t21849: \"netspeak-cps\",\n\t22000: \"snapenetio\",\n\t22001: \"optocontrol\",\n\t22002: \"optohost002\",\n\t22003: \"optohost003\",\n\t22004: \"optohost004\",\n\t22005: \"optohost004\",\n\t22125: \"dcap\",\n\t22128: \"gsidcap\",\n\t22222: \"easyengine\",\n\t22273: \"wnn6\",\n\t22305: \"cis\",\n\t22335: \"shrewd-control\",\n\t22343: \"cis-secure\",\n\t22347: \"wibukey\",\n\t22350: \"codemeter\",\n\t22351: \"codemeter-cmwan\",\n\t22537: \"caldsoft-backup\",\n\t22555: \"vocaltec-wconf\",\n\t22763: \"talikaserver\",\n\t22800: \"aws-brf\",\n\t22951: \"brf-gw\",\n\t23000: \"inovaport1\",\n\t23001: \"inovaport2\",\n\t23002: \"inovaport3\",\n\t23003: \"inovaport4\",\n\t23004: \"inovaport5\",\n\t23005: \"inovaport6\",\n\t23053: \"gntp\",\n\t23294: \"5afe-dir\",\n\t23333: \"elxmgmt\",\n\t23400: \"novar-dbase\",\n\t23401: \"novar-alarm\",\n\t23402: \"novar-global\",\n\t23456: \"aequus\",\n\t23457: \"aequus-alt\",\n\t23546: \"areaguard-neo\",\n\t24000: \"med-ltp\",\n\t24001: \"med-fsp-rx\",\n\t24002: \"med-fsp-tx\",\n\t24003: \"med-supp\",\n\t24004: \"med-ovw\",\n\t24005: \"med-ci\",\n\t24006: \"med-net-svc\",\n\t24242: \"filesphere\",\n\t24249: \"vista-4gl\",\n\t24321: \"ild\",\n\t24386: \"intel-rci\",\n\t24465: \"tonidods\",\n\t24554: \"binkp\",\n\t24577: \"bilobit\",\n\t24666: \"sdtvwcam\",\n\t24676: \"canditv\",\n\t24677: \"flashfiler\",\n\t24678: \"proactivate\",\n\t24680: \"tcc-http\",\n\t24754: \"cslg\",\n\t24922: \"find\",\n\t25000: \"icl-twobase1\",\n\t25001: \"icl-twobase2\",\n\t25002: \"icl-twobase3\",\n\t25003: \"icl-twobase4\",\n\t25004: \"icl-twobase5\",\n\t25005: \"icl-twobase6\",\n\t25006: \"icl-twobase7\",\n\t25007: \"icl-twobase8\",\n\t25008: \"icl-twobase9\",\n\t25009: \"icl-twobase10\",\n\t25576: \"sauterdongle\",\n\t25604: \"idtp\",\n\t25793: \"vocaltec-hos\",\n\t25900: \"tasp-net\",\n\t25901: \"niobserver\",\n\t25902: \"nilinkanalyst\",\n\t25903: \"niprobe\",\n\t26000: \"quake\",\n\t26133: \"scscp\",\n\t26208: \"wnn6-ds\",\n\t26257: \"cockroach\",\n\t26260: \"ezproxy\",\n\t26261: \"ezmeeting\",\n\t26262: \"k3software-svr\",\n\t26263: \"k3software-cli\",\n\t26486: \"exoline-tcp\",\n\t26487: \"exoconfig\",\n\t26489: \"exonet\",\n\t27345: \"imagepump\",\n\t27442: \"jesmsjc\",\n\t27504: \"kopek-httphead\",\n\t27782: \"ars-vista\",\n\t27876: \"astrolink\",\n\t27999: \"tw-auth-key\",\n\t28000: \"nxlmd\",\n\t28001: \"pqsp\",\n\t28200: \"voxelstorm\",\n\t28240: \"siemensgsm\",\n\t28589: \"bosswave\",\n\t29167: \"otmp\",\n\t29999: \"bingbang\",\n\t30000: \"ndmps\",\n\t30001: \"pago-services1\",\n\t30002: \"pago-services2\",\n\t30003: \"amicon-fpsu-ra\",\n\t30100: \"rwp\",\n\t30260: \"kingdomsonline\",\n\t30400: \"gs-realtime\",\n\t30999: \"ovobs\",\n\t31016: \"ka-sddp\",\n\t31020: \"autotrac-acp\",\n\t31400: \"pace-licensed\",\n\t31416: \"xqosd\",\n\t31457: \"tetrinet\",\n\t31620: \"lm-mon\",\n\t31685: \"dsx-monitor\",\n\t31765: \"gamesmith-port\",\n\t31948: \"iceedcp-tx\",\n\t31949: \"iceedcp-rx\",\n\t32034: \"iracinghelper\",\n\t32249: \"t1distproc60\",\n\t32400: \"plex\",\n\t32483: \"apm-link\",\n\t32635: \"sec-ntb-clnt\",\n\t32636: \"DMExpress\",\n\t32767: \"filenet-powsrm\",\n\t32768: \"filenet-tms\",\n\t32769: \"filenet-rpc\",\n\t32770: \"filenet-nch\",\n\t32771: \"filenet-rmi\",\n\t32772: \"filenet-pa\",\n\t32773: \"filenet-cm\",\n\t32774: \"filenet-re\",\n\t32775: \"filenet-pch\",\n\t32776: \"filenet-peior\",\n\t32777: \"filenet-obrok\",\n\t32801: \"mlsn\",\n\t32811: \"retp\",\n\t32896: \"idmgratm\",\n\t33060: \"mysqlx\",\n\t33123: \"aurora-balaena\",\n\t33331: \"diamondport\",\n\t33333: \"dgi-serv\",\n\t33334: \"speedtrace\",\n\t33434: \"traceroute\",\n\t33656: \"snip-slave\",\n\t34249: \"turbonote-2\",\n\t34378: \"p-net-local\",\n\t34379: \"p-net-remote\",\n\t34567: \"dhanalakshmi\",\n\t34962: \"profinet-rt\",\n\t34963: \"profinet-rtm\",\n\t34964: \"profinet-cm\",\n\t34980: \"ethercat\",\n\t35000: \"heathview\",\n\t35001: \"rt-viewer\",\n\t35002: \"rt-sound\",\n\t35003: \"rt-devicemapper\",\n\t35004: \"rt-classmanager\",\n\t35005: \"rt-labtracker\",\n\t35006: \"rt-helper\",\n\t35100: \"axio-disc\",\n\t35354: \"kitim\",\n\t35355: \"altova-lm\",\n\t35356: \"guttersnex\",\n\t35357: \"openstack-id\",\n\t36001: \"allpeers\",\n\t36524: \"febooti-aw\",\n\t36602: \"observium-agent\",\n\t36700: \"mapx\",\n\t36865: \"kastenxpipe\",\n\t37475: \"neckar\",\n\t37483: \"gdrive-sync\",\n\t37601: \"eftp\",\n\t37654: \"unisys-eportal\",\n\t38000: \"ivs-database\",\n\t38001: \"ivs-insertion\",\n\t38002: \"cresco-control\",\n\t38201: \"galaxy7-data\",\n\t38202: \"fairview\",\n\t38203: \"agpolicy\",\n\t38800: \"sruth\",\n\t38865: \"secrmmsafecopya\",\n\t39681: \"turbonote-1\",\n\t40000: \"safetynetp\",\n\t40404: \"sptx\",\n\t40841: \"cscp\",\n\t40842: \"csccredir\",\n\t40843: \"csccfirewall\",\n\t41111: \"fs-qos\",\n\t41121: \"tentacle\",\n\t41230: \"z-wave-s\",\n\t41794: \"crestron-cip\",\n\t41795: \"crestron-ctp\",\n\t41796: \"crestron-cips\",\n\t41797: \"crestron-ctps\",\n\t42508: \"candp\",\n\t42509: \"candrp\",\n\t42510: \"caerpc\",\n\t43000: \"recvr-rc\",\n\t43188: \"reachout\",\n\t43189: \"ndm-agent-port\",\n\t43190: \"ip-provision\",\n\t43191: \"noit-transport\",\n\t43210: \"shaperai\",\n\t43439: \"eq3-update\",\n\t43440: \"ew-mgmt\",\n\t43441: \"ciscocsdb\",\n\t44123: \"z-wave-tunnel\",\n\t44321: \"pmcd\",\n\t44322: \"pmcdproxy\",\n\t44323: \"pmwebapi\",\n\t44444: \"cognex-dataman\",\n\t44553: \"rbr-debug\",\n\t44818: \"EtherNet-IP-2\",\n\t44900: \"m3da\",\n\t45000: \"asmp\",\n\t45001: \"asmps\",\n\t45002: \"rs-status\",\n\t45045: \"synctest\",\n\t45054: \"invision-ag\",\n\t45514: \"cloudcheck\",\n\t45678: \"eba\",\n\t45824: \"dai-shell\",\n\t45825: \"qdb2service\",\n\t45966: \"ssr-servermgr\",\n\t46336: \"inedo\",\n\t46998: \"spremotetablet\",\n\t46999: \"mediabox\",\n\t47000: \"mbus\",\n\t47001: \"winrm\",\n\t47557: \"dbbrowse\",\n\t47624: \"directplaysrvr\",\n\t47806: \"ap\",\n\t47808: \"bacnet\",\n\t48000: \"nimcontroller\",\n\t48001: \"nimspooler\",\n\t48002: \"nimhub\",\n\t48003: \"nimgtw\",\n\t48004: \"nimbusdb\",\n\t48005: \"nimbusdbctrl\",\n\t48049: \"3gpp-cbsp\",\n\t48050: \"weandsf\",\n\t48128: \"isnetserv\",\n\t48129: \"blp5\",\n\t48556: \"com-bardac-dw\",\n\t48619: \"iqobject\",\n\t48653: \"robotraconteur\",\n\t49000: \"matahari\",\n\t49001: \"nusrp\",\n}\nvar udpPortNames = map[UDPPort]string{\n\t1:     \"tcpmux\",\n\t2:     \"compressnet\",\n\t3:     \"compressnet\",\n\t5:     \"rje\",\n\t7:     \"echo\",\n\t9:     \"discard\",\n\t11:    \"systat\",\n\t13:    \"daytime\",\n\t17:    \"qotd\",\n\t18:    \"msp\",\n\t19:    \"chargen\",\n\t20:    \"ftp-data\",\n\t21:    \"ftp\",\n\t22:    \"ssh\",\n\t23:    \"telnet\",\n\t25:    \"smtp\",\n\t27:    \"nsw-fe\",\n\t29:    \"msg-icp\",\n\t31:    \"msg-auth\",\n\t33:    \"dsp\",\n\t37:    \"time\",\n\t38:    \"rap\",\n\t39:    \"rlp\",\n\t41:    \"graphics\",\n\t42:    \"name\",\n\t43:    \"nicname\",\n\t44:    \"mpm-flags\",\n\t45:    \"mpm\",\n\t46:    \"mpm-snd\",\n\t48:    \"auditd\",\n\t49:    \"tacacs\",\n\t50:    \"re-mail-ck\",\n\t52:    \"xns-time\",\n\t53:    \"domain\",\n\t54:    \"xns-ch\",\n\t55:    \"isi-gl\",\n\t56:    \"xns-auth\",\n\t58:    \"xns-mail\",\n\t62:    \"acas\",\n\t63:    \"whoispp\",\n\t64:    \"covia\",\n\t65:    \"tacacs-ds\",\n\t66:    \"sql-net\",\n\t67:    \"bootps\",\n\t68:    \"bootpc\",\n\t69:    \"tftp\",\n\t70:    \"gopher\",\n\t71:    \"netrjs-1\",\n\t72:    \"netrjs-2\",\n\t73:    \"netrjs-3\",\n\t74:    \"netrjs-4\",\n\t76:    \"deos\",\n\t78:    \"vettcp\",\n\t79:    \"finger\",\n\t80:    \"http\",\n\t82:    \"xfer\",\n\t83:    \"mit-ml-dev\",\n\t84:    \"ctf\",\n\t85:    \"mit-ml-dev\",\n\t86:    \"mfcobol\",\n\t88:    \"kerberos\",\n\t89:    \"su-mit-tg\",\n\t90:    \"dnsix\",\n\t91:    \"mit-dov\",\n\t92:    \"npp\",\n\t93:    \"dcp\",\n\t94:    \"objcall\",\n\t95:    \"supdup\",\n\t96:    \"dixie\",\n\t97:    \"swift-rvf\",\n\t98:    \"tacnews\",\n\t99:    \"metagram\",\n\t101:   \"hostname\",\n\t102:   \"iso-tsap\",\n\t103:   \"gppitnp\",\n\t104:   \"acr-nema\",\n\t105:   \"cso\",\n\t106:   \"3com-tsmux\",\n\t107:   \"rtelnet\",\n\t108:   \"snagas\",\n\t109:   \"pop2\",\n\t110:   \"pop3\",\n\t111:   \"sunrpc\",\n\t112:   \"mcidas\",\n\t113:   \"auth\",\n\t115:   \"sftp\",\n\t116:   \"ansanotify\",\n\t117:   \"uucp-path\",\n\t118:   \"sqlserv\",\n\t119:   \"nntp\",\n\t120:   \"cfdptkt\",\n\t121:   \"erpc\",\n\t122:   \"smakynet\",\n\t123:   \"ntp\",\n\t124:   \"ansatrader\",\n\t125:   \"locus-map\",\n\t126:   \"nxedit\",\n\t127:   \"locus-con\",\n\t128:   \"gss-xlicen\",\n\t129:   \"pwdgen\",\n\t130:   \"cisco-fna\",\n\t131:   \"cisco-tna\",\n\t132:   \"cisco-sys\",\n\t133:   \"statsrv\",\n\t134:   \"ingres-net\",\n\t135:   \"epmap\",\n\t136:   \"profile\",\n\t137:   \"netbios-ns\",\n\t138:   \"netbios-dgm\",\n\t139:   \"netbios-ssn\",\n\t140:   \"emfis-data\",\n\t141:   \"emfis-cntl\",\n\t142:   \"bl-idm\",\n\t143:   \"imap\",\n\t144:   \"uma\",\n\t145:   \"uaac\",\n\t146:   \"iso-tp0\",\n\t147:   \"iso-ip\",\n\t148:   \"jargon\",\n\t149:   \"aed-512\",\n\t150:   \"sql-net\",\n\t151:   \"hems\",\n\t152:   \"bftp\",\n\t153:   \"sgmp\",\n\t154:   \"netsc-prod\",\n\t155:   \"netsc-dev\",\n\t156:   \"sqlsrv\",\n\t157:   \"knet-cmp\",\n\t158:   \"pcmail-srv\",\n\t159:   \"nss-routing\",\n\t160:   \"sgmp-traps\",\n\t161:   \"snmp\",\n\t162:   \"snmptrap\",\n\t163:   \"cmip-man\",\n\t164:   \"cmip-agent\",\n\t165:   \"xns-courier\",\n\t166:   \"s-net\",\n\t167:   \"namp\",\n\t168:   \"rsvd\",\n\t169:   \"send\",\n\t170:   \"print-srv\",\n\t171:   \"multiplex\",\n\t172:   \"cl-1\",\n\t173:   \"xyplex-mux\",\n\t174:   \"mailq\",\n\t175:   \"vmnet\",\n\t176:   \"genrad-mux\",\n\t177:   \"xdmcp\",\n\t178:   \"nextstep\",\n\t179:   \"bgp\",\n\t180:   \"ris\",\n\t181:   \"unify\",\n\t182:   \"audit\",\n\t183:   \"ocbinder\",\n\t184:   \"ocserver\",\n\t185:   \"remote-kis\",\n\t186:   \"kis\",\n\t187:   \"aci\",\n\t188:   \"mumps\",\n\t189:   \"qft\",\n\t190:   \"gacp\",\n\t191:   \"prospero\",\n\t192:   \"osu-nms\",\n\t193:   \"srmp\",\n\t194:   \"irc\",\n\t195:   \"dn6-nlm-aud\",\n\t196:   \"dn6-smm-red\",\n\t197:   \"dls\",\n\t198:   \"dls-mon\",\n\t199:   \"smux\",\n\t200:   \"src\",\n\t201:   \"at-rtmp\",\n\t202:   \"at-nbp\",\n\t203:   \"at-3\",\n\t204:   \"at-echo\",\n\t205:   \"at-5\",\n\t206:   \"at-zis\",\n\t207:   \"at-7\",\n\t208:   \"at-8\",\n\t209:   \"qmtp\",\n\t210:   \"z39-50\",\n\t211:   \"914c-g\",\n\t212:   \"anet\",\n\t213:   \"ipx\",\n\t214:   \"vmpwscs\",\n\t215:   \"softpc\",\n\t216:   \"CAIlic\",\n\t217:   \"dbase\",\n\t218:   \"mpp\",\n\t219:   \"uarps\",\n\t220:   \"imap3\",\n\t221:   \"fln-spx\",\n\t222:   \"rsh-spx\",\n\t223:   \"cdc\",\n\t224:   \"masqdialer\",\n\t242:   \"direct\",\n\t243:   \"sur-meas\",\n\t244:   \"inbusiness\",\n\t245:   \"link\",\n\t246:   \"dsp3270\",\n\t247:   \"subntbcst-tftp\",\n\t248:   \"bhfhs\",\n\t256:   \"rap\",\n\t257:   \"set\",\n\t259:   \"esro-gen\",\n\t260:   \"openport\",\n\t261:   \"nsiiops\",\n\t262:   \"arcisdms\",\n\t263:   \"hdap\",\n\t264:   \"bgmp\",\n\t265:   \"x-bone-ctl\",\n\t266:   \"sst\",\n\t267:   \"td-service\",\n\t268:   \"td-replica\",\n\t269:   \"manet\",\n\t270:   \"gist\",\n\t280:   \"http-mgmt\",\n\t281:   \"personal-link\",\n\t282:   \"cableport-ax\",\n\t283:   \"rescap\",\n\t284:   \"corerjd\",\n\t286:   \"fxp\",\n\t287:   \"k-block\",\n\t308:   \"novastorbakcup\",\n\t309:   \"entrusttime\",\n\t310:   \"bhmds\",\n\t311:   \"asip-webadmin\",\n\t312:   \"vslmp\",\n\t313:   \"magenta-logic\",\n\t314:   \"opalis-robot\",\n\t315:   \"dpsi\",\n\t316:   \"decauth\",\n\t317:   \"zannet\",\n\t318:   \"pkix-timestamp\",\n\t319:   \"ptp-event\",\n\t320:   \"ptp-general\",\n\t321:   \"pip\",\n\t322:   \"rtsps\",\n\t333:   \"texar\",\n\t344:   \"pdap\",\n\t345:   \"pawserv\",\n\t346:   \"zserv\",\n\t347:   \"fatserv\",\n\t348:   \"csi-sgwp\",\n\t349:   \"mftp\",\n\t350:   \"matip-type-a\",\n\t351:   \"matip-type-b\",\n\t352:   \"dtag-ste-sb\",\n\t353:   \"ndsauth\",\n\t354:   \"bh611\",\n\t355:   \"datex-asn\",\n\t356:   \"cloanto-net-1\",\n\t357:   \"bhevent\",\n\t358:   \"shrinkwrap\",\n\t359:   \"nsrmp\",\n\t360:   \"scoi2odialog\",\n\t361:   \"semantix\",\n\t362:   \"srssend\",\n\t363:   \"rsvp-tunnel\",\n\t364:   \"aurora-cmgr\",\n\t365:   \"dtk\",\n\t366:   \"odmr\",\n\t367:   \"mortgageware\",\n\t368:   \"qbikgdp\",\n\t369:   \"rpc2portmap\",\n\t370:   \"codaauth2\",\n\t371:   \"clearcase\",\n\t372:   \"ulistproc\",\n\t373:   \"legent-1\",\n\t374:   \"legent-2\",\n\t375:   \"hassle\",\n\t376:   \"nip\",\n\t377:   \"tnETOS\",\n\t378:   \"dsETOS\",\n\t379:   \"is99c\",\n\t380:   \"is99s\",\n\t381:   \"hp-collector\",\n\t382:   \"hp-managed-node\",\n\t383:   \"hp-alarm-mgr\",\n\t384:   \"arns\",\n\t385:   \"ibm-app\",\n\t386:   \"asa\",\n\t387:   \"aurp\",\n\t388:   \"unidata-ldm\",\n\t389:   \"ldap\",\n\t390:   \"uis\",\n\t391:   \"synotics-relay\",\n\t392:   \"synotics-broker\",\n\t393:   \"meta5\",\n\t394:   \"embl-ndt\",\n\t395:   \"netcp\",\n\t396:   \"netware-ip\",\n\t397:   \"mptn\",\n\t398:   \"kryptolan\",\n\t399:   \"iso-tsap-c2\",\n\t400:   \"osb-sd\",\n\t401:   \"ups\",\n\t402:   \"genie\",\n\t403:   \"decap\",\n\t404:   \"nced\",\n\t405:   \"ncld\",\n\t406:   \"imsp\",\n\t407:   \"timbuktu\",\n\t408:   \"prm-sm\",\n\t409:   \"prm-nm\",\n\t410:   \"decladebug\",\n\t411:   \"rmt\",\n\t412:   \"synoptics-trap\",\n\t413:   \"smsp\",\n\t414:   \"infoseek\",\n\t415:   \"bnet\",\n\t416:   \"silverplatter\",\n\t417:   \"onmux\",\n\t418:   \"hyper-g\",\n\t419:   \"ariel1\",\n\t420:   \"smpte\",\n\t421:   \"ariel2\",\n\t422:   \"ariel3\",\n\t423:   \"opc-job-start\",\n\t424:   \"opc-job-track\",\n\t425:   \"icad-el\",\n\t426:   \"smartsdp\",\n\t427:   \"svrloc\",\n\t428:   \"ocs-cmu\",\n\t429:   \"ocs-amu\",\n\t430:   \"utmpsd\",\n\t431:   \"utmpcd\",\n\t432:   \"iasd\",\n\t433:   \"nnsp\",\n\t434:   \"mobileip-agent\",\n\t435:   \"mobilip-mn\",\n\t436:   \"dna-cml\",\n\t437:   \"comscm\",\n\t438:   \"dsfgw\",\n\t439:   \"dasp\",\n\t440:   \"sgcp\",\n\t441:   \"decvms-sysmgt\",\n\t442:   \"cvc-hostd\",\n\t443:   \"https\",\n\t444:   \"snpp\",\n\t445:   \"microsoft-ds\",\n\t446:   \"ddm-rdb\",\n\t447:   \"ddm-dfm\",\n\t448:   \"ddm-ssl\",\n\t449:   \"as-servermap\",\n\t450:   \"tserver\",\n\t451:   \"sfs-smp-net\",\n\t452:   \"sfs-config\",\n\t453:   \"creativeserver\",\n\t454:   \"contentserver\",\n\t455:   \"creativepartnr\",\n\t456:   \"macon-udp\",\n\t457:   \"scohelp\",\n\t458:   \"appleqtc\",\n\t459:   \"ampr-rcmd\",\n\t460:   \"skronk\",\n\t461:   \"datasurfsrv\",\n\t462:   \"datasurfsrvsec\",\n\t463:   \"alpes\",\n\t464:   \"kpasswd\",\n\t465:   \"igmpv3lite\",\n\t466:   \"digital-vrc\",\n\t467:   \"mylex-mapd\",\n\t468:   \"photuris\",\n\t469:   \"rcp\",\n\t470:   \"scx-proxy\",\n\t471:   \"mondex\",\n\t472:   \"ljk-login\",\n\t473:   \"hybrid-pop\",\n\t474:   \"tn-tl-w2\",\n\t475:   \"tcpnethaspsrv\",\n\t476:   \"tn-tl-fd1\",\n\t477:   \"ss7ns\",\n\t478:   \"spsc\",\n\t479:   \"iafserver\",\n\t480:   \"iafdbase\",\n\t481:   \"ph\",\n\t482:   \"bgs-nsi\",\n\t483:   \"ulpnet\",\n\t484:   \"integra-sme\",\n\t485:   \"powerburst\",\n\t486:   \"avian\",\n\t487:   \"saft\",\n\t488:   \"gss-http\",\n\t489:   \"nest-protocol\",\n\t490:   \"micom-pfs\",\n\t491:   \"go-login\",\n\t492:   \"ticf-1\",\n\t493:   \"ticf-2\",\n\t494:   \"pov-ray\",\n\t495:   \"intecourier\",\n\t496:   \"pim-rp-disc\",\n\t497:   \"retrospect\",\n\t498:   \"siam\",\n\t499:   \"iso-ill\",\n\t500:   \"isakmp\",\n\t501:   \"stmf\",\n\t502:   \"mbap\",\n\t503:   \"intrinsa\",\n\t504:   \"citadel\",\n\t505:   \"mailbox-lm\",\n\t506:   \"ohimsrv\",\n\t507:   \"crs\",\n\t508:   \"xvttp\",\n\t509:   \"snare\",\n\t510:   \"fcp\",\n\t511:   \"passgo\",\n\t512:   \"comsat\",\n\t513:   \"who\",\n\t514:   \"syslog\",\n\t515:   \"printer\",\n\t516:   \"videotex\",\n\t517:   \"talk\",\n\t518:   \"ntalk\",\n\t519:   \"utime\",\n\t520:   \"router\",\n\t521:   \"ripng\",\n\t522:   \"ulp\",\n\t523:   \"ibm-db2\",\n\t524:   \"ncp\",\n\t525:   \"timed\",\n\t526:   \"tempo\",\n\t527:   \"stx\",\n\t528:   \"custix\",\n\t529:   \"irc-serv\",\n\t530:   \"courier\",\n\t531:   \"conference\",\n\t532:   \"netnews\",\n\t533:   \"netwall\",\n\t534:   \"windream\",\n\t535:   \"iiop\",\n\t536:   \"opalis-rdv\",\n\t537:   \"nmsp\",\n\t538:   \"gdomap\",\n\t539:   \"apertus-ldp\",\n\t540:   \"uucp\",\n\t541:   \"uucp-rlogin\",\n\t542:   \"commerce\",\n\t543:   \"klogin\",\n\t544:   \"kshell\",\n\t545:   \"appleqtcsrvr\",\n\t546:   \"dhcpv6-client\",\n\t547:   \"dhcpv6-server\",\n\t548:   \"afpovertcp\",\n\t549:   \"idfp\",\n\t550:   \"new-rwho\",\n\t551:   \"cybercash\",\n\t552:   \"devshr-nts\",\n\t553:   \"pirp\",\n\t554:   \"rtsp\",\n\t555:   \"dsf\",\n\t556:   \"remotefs\",\n\t557:   \"openvms-sysipc\",\n\t558:   \"sdnskmp\",\n\t559:   \"teedtap\",\n\t560:   \"rmonitor\",\n\t561:   \"monitor\",\n\t562:   \"chshell\",\n\t563:   \"nntps\",\n\t564:   \"9pfs\",\n\t565:   \"whoami\",\n\t566:   \"streettalk\",\n\t567:   \"banyan-rpc\",\n\t568:   \"ms-shuttle\",\n\t569:   \"ms-rome\",\n\t570:   \"meter\",\n\t571:   \"meter\",\n\t572:   \"sonar\",\n\t573:   \"banyan-vip\",\n\t574:   \"ftp-agent\",\n\t575:   \"vemmi\",\n\t576:   \"ipcd\",\n\t577:   \"vnas\",\n\t578:   \"ipdd\",\n\t579:   \"decbsrv\",\n\t580:   \"sntp-heartbeat\",\n\t581:   \"bdp\",\n\t582:   \"scc-security\",\n\t583:   \"philips-vc\",\n\t584:   \"keyserver\",\n\t586:   \"password-chg\",\n\t587:   \"submission\",\n\t588:   \"cal\",\n\t589:   \"eyelink\",\n\t590:   \"tns-cml\",\n\t591:   \"http-alt\",\n\t592:   \"eudora-set\",\n\t593:   \"http-rpc-epmap\",\n\t594:   \"tpip\",\n\t595:   \"cab-protocol\",\n\t596:   \"smsd\",\n\t597:   \"ptcnameservice\",\n\t598:   \"sco-websrvrmg3\",\n\t599:   \"acp\",\n\t600:   \"ipcserver\",\n\t601:   \"syslog-conn\",\n\t602:   \"xmlrpc-beep\",\n\t603:   \"idxp\",\n\t604:   \"tunnel\",\n\t605:   \"soap-beep\",\n\t606:   \"urm\",\n\t607:   \"nqs\",\n\t608:   \"sift-uft\",\n\t609:   \"npmp-trap\",\n\t610:   \"npmp-local\",\n\t611:   \"npmp-gui\",\n\t612:   \"hmmp-ind\",\n\t613:   \"hmmp-op\",\n\t614:   \"sshell\",\n\t615:   \"sco-inetmgr\",\n\t616:   \"sco-sysmgr\",\n\t617:   \"sco-dtmgr\",\n\t618:   \"dei-icda\",\n\t619:   \"compaq-evm\",\n\t620:   \"sco-websrvrmgr\",\n\t621:   \"escp-ip\",\n\t622:   \"collaborator\",\n\t623:   \"asf-rmcp\",\n\t624:   \"cryptoadmin\",\n\t625:   \"dec-dlm\",\n\t626:   \"asia\",\n\t627:   \"passgo-tivoli\",\n\t628:   \"qmqp\",\n\t629:   \"3com-amp3\",\n\t630:   \"rda\",\n\t631:   \"ipp\",\n\t632:   \"bmpp\",\n\t633:   \"servstat\",\n\t634:   \"ginad\",\n\t635:   \"rlzdbase\",\n\t636:   \"ldaps\",\n\t637:   \"lanserver\",\n\t638:   \"mcns-sec\",\n\t639:   \"msdp\",\n\t640:   \"entrust-sps\",\n\t641:   \"repcmd\",\n\t642:   \"esro-emsdp\",\n\t643:   \"sanity\",\n\t644:   \"dwr\",\n\t645:   \"pssc\",\n\t646:   \"ldp\",\n\t647:   \"dhcp-failover\",\n\t648:   \"rrp\",\n\t649:   \"cadview-3d\",\n\t650:   \"obex\",\n\t651:   \"ieee-mms\",\n\t652:   \"hello-port\",\n\t653:   \"repscmd\",\n\t654:   \"aodv\",\n\t655:   \"tinc\",\n\t656:   \"spmp\",\n\t657:   \"rmc\",\n\t658:   \"tenfold\",\n\t660:   \"mac-srvr-admin\",\n\t661:   \"hap\",\n\t662:   \"pftp\",\n\t663:   \"purenoise\",\n\t664:   \"asf-secure-rmcp\",\n\t665:   \"sun-dr\",\n\t666:   \"mdqs\",\n\t667:   \"disclose\",\n\t668:   \"mecomm\",\n\t669:   \"meregister\",\n\t670:   \"vacdsm-sws\",\n\t671:   \"vacdsm-app\",\n\t672:   \"vpps-qua\",\n\t673:   \"cimplex\",\n\t674:   \"acap\",\n\t675:   \"dctp\",\n\t676:   \"vpps-via\",\n\t677:   \"vpp\",\n\t678:   \"ggf-ncp\",\n\t679:   \"mrm\",\n\t680:   \"entrust-aaas\",\n\t681:   \"entrust-aams\",\n\t682:   \"xfr\",\n\t683:   \"corba-iiop\",\n\t684:   \"corba-iiop-ssl\",\n\t685:   \"mdc-portmapper\",\n\t686:   \"hcp-wismar\",\n\t687:   \"asipregistry\",\n\t688:   \"realm-rusd\",\n\t689:   \"nmap\",\n\t690:   \"vatp\",\n\t691:   \"msexch-routing\",\n\t692:   \"hyperwave-isp\",\n\t693:   \"connendp\",\n\t694:   \"ha-cluster\",\n\t695:   \"ieee-mms-ssl\",\n\t696:   \"rushd\",\n\t697:   \"uuidgen\",\n\t698:   \"olsr\",\n\t699:   \"accessnetwork\",\n\t700:   \"epp\",\n\t701:   \"lmp\",\n\t702:   \"iris-beep\",\n\t704:   \"elcsd\",\n\t705:   \"agentx\",\n\t706:   \"silc\",\n\t707:   \"borland-dsj\",\n\t709:   \"entrust-kmsh\",\n\t710:   \"entrust-ash\",\n\t711:   \"cisco-tdp\",\n\t712:   \"tbrpf\",\n\t713:   \"iris-xpc\",\n\t714:   \"iris-xpcs\",\n\t715:   \"iris-lwz\",\n\t716:   \"pana\",\n\t729:   \"netviewdm1\",\n\t730:   \"netviewdm2\",\n\t731:   \"netviewdm3\",\n\t741:   \"netgw\",\n\t742:   \"netrcs\",\n\t744:   \"flexlm\",\n\t747:   \"fujitsu-dev\",\n\t748:   \"ris-cm\",\n\t749:   \"kerberos-adm\",\n\t750:   \"loadav\",\n\t751:   \"pump\",\n\t752:   \"qrh\",\n\t753:   \"rrh\",\n\t754:   \"tell\",\n\t758:   \"nlogin\",\n\t759:   \"con\",\n\t760:   \"ns\",\n\t761:   \"rxe\",\n\t762:   \"quotad\",\n\t763:   \"cycleserv\",\n\t764:   \"omserv\",\n\t765:   \"webster\",\n\t767:   \"phonebook\",\n\t769:   \"vid\",\n\t770:   \"cadlock\",\n\t771:   \"rtip\",\n\t772:   \"cycleserv2\",\n\t773:   \"notify\",\n\t774:   \"acmaint-dbd\",\n\t775:   \"acmaint-transd\",\n\t776:   \"wpages\",\n\t777:   \"multiling-http\",\n\t780:   \"wpgs\",\n\t800:   \"mdbs-daemon\",\n\t801:   \"device\",\n\t802:   \"mbap-s\",\n\t810:   \"fcp-udp\",\n\t828:   \"itm-mcell-s\",\n\t829:   \"pkix-3-ca-ra\",\n\t830:   \"netconf-ssh\",\n\t831:   \"netconf-beep\",\n\t832:   \"netconfsoaphttp\",\n\t833:   \"netconfsoapbeep\",\n\t847:   \"dhcp-failover2\",\n\t848:   \"gdoi\",\n\t853:   \"domain-s\",\n\t854:   \"dlep\",\n\t860:   \"iscsi\",\n\t861:   \"owamp-control\",\n\t862:   \"twamp-control\",\n\t873:   \"rsync\",\n\t886:   \"iclcnet-locate\",\n\t887:   \"iclcnet-svinfo\",\n\t888:   \"accessbuilder\",\n\t900:   \"omginitialrefs\",\n\t901:   \"smpnameres\",\n\t902:   \"ideafarm-door\",\n\t903:   \"ideafarm-panic\",\n\t910:   \"kink\",\n\t911:   \"xact-backup\",\n\t912:   \"apex-mesh\",\n\t913:   \"apex-edge\",\n\t989:   \"ftps-data\",\n\t990:   \"ftps\",\n\t991:   \"nas\",\n\t992:   \"telnets\",\n\t993:   \"imaps\",\n\t995:   \"pop3s\",\n\t996:   \"vsinet\",\n\t997:   \"maitrd\",\n\t998:   \"puparp\",\n\t999:   \"applix\",\n\t1000:  \"cadlock2\",\n\t1010:  \"surf\",\n\t1021:  \"exp1\",\n\t1022:  \"exp2\",\n\t1025:  \"blackjack\",\n\t1026:  \"cap\",\n\t1027:  \"6a44\",\n\t1029:  \"solid-mux\",\n\t1033:  \"netinfo-local\",\n\t1034:  \"activesync\",\n\t1035:  \"mxxrlogin\",\n\t1036:  \"nsstp\",\n\t1037:  \"ams\",\n\t1038:  \"mtqp\",\n\t1039:  \"sbl\",\n\t1040:  \"netarx\",\n\t1041:  \"danf-ak2\",\n\t1042:  \"afrog\",\n\t1043:  \"boinc-client\",\n\t1044:  \"dcutility\",\n\t1045:  \"fpitp\",\n\t1046:  \"wfremotertm\",\n\t1047:  \"neod1\",\n\t1048:  \"neod2\",\n\t1049:  \"td-postman\",\n\t1050:  \"cma\",\n\t1051:  \"optima-vnet\",\n\t1052:  \"ddt\",\n\t1053:  \"remote-as\",\n\t1054:  \"brvread\",\n\t1055:  \"ansyslmd\",\n\t1056:  \"vfo\",\n\t1057:  \"startron\",\n\t1058:  \"nim\",\n\t1059:  \"nimreg\",\n\t1060:  \"polestar\",\n\t1061:  \"kiosk\",\n\t1062:  \"veracity\",\n\t1063:  \"kyoceranetdev\",\n\t1064:  \"jstel\",\n\t1065:  \"syscomlan\",\n\t1066:  \"fpo-fns\",\n\t1067:  \"instl-boots\",\n\t1068:  \"instl-bootc\",\n\t1069:  \"cognex-insight\",\n\t1070:  \"gmrupdateserv\",\n\t1071:  \"bsquare-voip\",\n\t1072:  \"cardax\",\n\t1073:  \"bridgecontrol\",\n\t1074:  \"warmspotMgmt\",\n\t1075:  \"rdrmshc\",\n\t1076:  \"dab-sti-c\",\n\t1077:  \"imgames\",\n\t1078:  \"avocent-proxy\",\n\t1079:  \"asprovatalk\",\n\t1080:  \"socks\",\n\t1081:  \"pvuniwien\",\n\t1082:  \"amt-esd-prot\",\n\t1083:  \"ansoft-lm-1\",\n\t1084:  \"ansoft-lm-2\",\n\t1085:  \"webobjects\",\n\t1086:  \"cplscrambler-lg\",\n\t1087:  \"cplscrambler-in\",\n\t1088:  \"cplscrambler-al\",\n\t1089:  \"ff-annunc\",\n\t1090:  \"ff-fms\",\n\t1091:  \"ff-sm\",\n\t1092:  \"obrpd\",\n\t1093:  \"proofd\",\n\t1094:  \"rootd\",\n\t1095:  \"nicelink\",\n\t1096:  \"cnrprotocol\",\n\t1097:  \"sunclustermgr\",\n\t1098:  \"rmiactivation\",\n\t1099:  \"rmiregistry\",\n\t1100:  \"mctp\",\n\t1101:  \"pt2-discover\",\n\t1102:  \"adobeserver-1\",\n\t1103:  \"adobeserver-2\",\n\t1104:  \"xrl\",\n\t1105:  \"ftranhc\",\n\t1106:  \"isoipsigport-1\",\n\t1107:  \"isoipsigport-2\",\n\t1108:  \"ratio-adp\",\n\t1110:  \"nfsd-keepalive\",\n\t1111:  \"lmsocialserver\",\n\t1112:  \"icp\",\n\t1113:  \"ltp-deepspace\",\n\t1114:  \"mini-sql\",\n\t1115:  \"ardus-trns\",\n\t1116:  \"ardus-cntl\",\n\t1117:  \"ardus-mtrns\",\n\t1118:  \"sacred\",\n\t1119:  \"bnetgame\",\n\t1120:  \"bnetfile\",\n\t1121:  \"rmpp\",\n\t1122:  \"availant-mgr\",\n\t1123:  \"murray\",\n\t1124:  \"hpvmmcontrol\",\n\t1125:  \"hpvmmagent\",\n\t1126:  \"hpvmmdata\",\n\t1127:  \"kwdb-commn\",\n\t1128:  \"saphostctrl\",\n\t1129:  \"saphostctrls\",\n\t1130:  \"casp\",\n\t1131:  \"caspssl\",\n\t1132:  \"kvm-via-ip\",\n\t1133:  \"dfn\",\n\t1134:  \"aplx\",\n\t1135:  \"omnivision\",\n\t1136:  \"hhb-gateway\",\n\t1137:  \"trim\",\n\t1138:  \"encrypted-admin\",\n\t1139:  \"evm\",\n\t1140:  \"autonoc\",\n\t1141:  \"mxomss\",\n\t1142:  \"edtools\",\n\t1143:  \"imyx\",\n\t1144:  \"fuscript\",\n\t1145:  \"x9-icue\",\n\t1146:  \"audit-transfer\",\n\t1147:  \"capioverlan\",\n\t1148:  \"elfiq-repl\",\n\t1149:  \"bvtsonar\",\n\t1150:  \"blaze\",\n\t1151:  \"unizensus\",\n\t1152:  \"winpoplanmess\",\n\t1153:  \"c1222-acse\",\n\t1154:  \"resacommunity\",\n\t1155:  \"nfa\",\n\t1156:  \"iascontrol-oms\",\n\t1157:  \"iascontrol\",\n\t1158:  \"dbcontrol-oms\",\n\t1159:  \"oracle-oms\",\n\t1160:  \"olsv\",\n\t1161:  \"health-polling\",\n\t1162:  \"health-trap\",\n\t1163:  \"sddp\",\n\t1164:  \"qsm-proxy\",\n\t1165:  \"qsm-gui\",\n\t1166:  \"qsm-remote\",\n\t1167:  \"cisco-ipsla\",\n\t1168:  \"vchat\",\n\t1169:  \"tripwire\",\n\t1170:  \"atc-lm\",\n\t1171:  \"atc-appserver\",\n\t1172:  \"dnap\",\n\t1173:  \"d-cinema-rrp\",\n\t1174:  \"fnet-remote-ui\",\n\t1175:  \"dossier\",\n\t1176:  \"indigo-server\",\n\t1177:  \"dkmessenger\",\n\t1178:  \"sgi-storman\",\n\t1179:  \"b2n\",\n\t1180:  \"mc-client\",\n\t1181:  \"3comnetman\",\n\t1182:  \"accelenet-data\",\n\t1183:  \"llsurfup-http\",\n\t1184:  \"llsurfup-https\",\n\t1185:  \"catchpole\",\n\t1186:  \"mysql-cluster\",\n\t1187:  \"alias\",\n\t1188:  \"hp-webadmin\",\n\t1189:  \"unet\",\n\t1190:  \"commlinx-avl\",\n\t1191:  \"gpfs\",\n\t1192:  \"caids-sensor\",\n\t1193:  \"fiveacross\",\n\t1194:  \"openvpn\",\n\t1195:  \"rsf-1\",\n\t1196:  \"netmagic\",\n\t1197:  \"carrius-rshell\",\n\t1198:  \"cajo-discovery\",\n\t1199:  \"dmidi\",\n\t1200:  \"scol\",\n\t1201:  \"nucleus-sand\",\n\t1202:  \"caiccipc\",\n\t1203:  \"ssslic-mgr\",\n\t1204:  \"ssslog-mgr\",\n\t1205:  \"accord-mgc\",\n\t1206:  \"anthony-data\",\n\t1207:  \"metasage\",\n\t1208:  \"seagull-ais\",\n\t1209:  \"ipcd3\",\n\t1210:  \"eoss\",\n\t1211:  \"groove-dpp\",\n\t1212:  \"lupa\",\n\t1213:  \"mpc-lifenet\",\n\t1214:  \"kazaa\",\n\t1215:  \"scanstat-1\",\n\t1216:  \"etebac5\",\n\t1217:  \"hpss-ndapi\",\n\t1218:  \"aeroflight-ads\",\n\t1219:  \"aeroflight-ret\",\n\t1220:  \"qt-serveradmin\",\n\t1221:  \"sweetware-apps\",\n\t1222:  \"nerv\",\n\t1223:  \"tgp\",\n\t1224:  \"vpnz\",\n\t1225:  \"slinkysearch\",\n\t1226:  \"stgxfws\",\n\t1227:  \"dns2go\",\n\t1228:  \"florence\",\n\t1229:  \"zented\",\n\t1230:  \"periscope\",\n\t1231:  \"menandmice-lpm\",\n\t1232:  \"first-defense\",\n\t1233:  \"univ-appserver\",\n\t1234:  \"search-agent\",\n\t1235:  \"mosaicsyssvc1\",\n\t1236:  \"bvcontrol\",\n\t1237:  \"tsdos390\",\n\t1238:  \"hacl-qs\",\n\t1239:  \"nmsd\",\n\t1240:  \"instantia\",\n\t1241:  \"nessus\",\n\t1242:  \"nmasoverip\",\n\t1243:  \"serialgateway\",\n\t1244:  \"isbconference1\",\n\t1245:  \"isbconference2\",\n\t1246:  \"payrouter\",\n\t1247:  \"visionpyramid\",\n\t1248:  \"hermes\",\n\t1249:  \"mesavistaco\",\n\t1250:  \"swldy-sias\",\n\t1251:  \"servergraph\",\n\t1252:  \"bspne-pcc\",\n\t1253:  \"q55-pcc\",\n\t1254:  \"de-noc\",\n\t1255:  \"de-cache-query\",\n\t1256:  \"de-server\",\n\t1257:  \"shockwave2\",\n\t1258:  \"opennl\",\n\t1259:  \"opennl-voice\",\n\t1260:  \"ibm-ssd\",\n\t1261:  \"mpshrsv\",\n\t1262:  \"qnts-orb\",\n\t1263:  \"dka\",\n\t1264:  \"prat\",\n\t1265:  \"dssiapi\",\n\t1266:  \"dellpwrappks\",\n\t1267:  \"epc\",\n\t1268:  \"propel-msgsys\",\n\t1269:  \"watilapp\",\n\t1270:  \"opsmgr\",\n\t1271:  \"excw\",\n\t1272:  \"cspmlockmgr\",\n\t1273:  \"emc-gateway\",\n\t1274:  \"t1distproc\",\n\t1275:  \"ivcollector\",\n\t1277:  \"miva-mqs\",\n\t1278:  \"dellwebadmin-1\",\n\t1279:  \"dellwebadmin-2\",\n\t1280:  \"pictrography\",\n\t1281:  \"healthd\",\n\t1282:  \"emperion\",\n\t1283:  \"productinfo\",\n\t1284:  \"iee-qfx\",\n\t1285:  \"neoiface\",\n\t1286:  \"netuitive\",\n\t1287:  \"routematch\",\n\t1288:  \"navbuddy\",\n\t1289:  \"jwalkserver\",\n\t1290:  \"winjaserver\",\n\t1291:  \"seagulllms\",\n\t1292:  \"dsdn\",\n\t1293:  \"pkt-krb-ipsec\",\n\t1294:  \"cmmdriver\",\n\t1295:  \"ehtp\",\n\t1296:  \"dproxy\",\n\t1297:  \"sdproxy\",\n\t1298:  \"lpcp\",\n\t1299:  \"hp-sci\",\n\t1300:  \"h323hostcallsc\",\n\t1301:  \"ci3-software-1\",\n\t1302:  \"ci3-software-2\",\n\t1303:  \"sftsrv\",\n\t1304:  \"boomerang\",\n\t1305:  \"pe-mike\",\n\t1306:  \"re-conn-proto\",\n\t1307:  \"pacmand\",\n\t1308:  \"odsi\",\n\t1309:  \"jtag-server\",\n\t1310:  \"husky\",\n\t1311:  \"rxmon\",\n\t1312:  \"sti-envision\",\n\t1313:  \"bmc-patroldb\",\n\t1314:  \"pdps\",\n\t1315:  \"els\",\n\t1316:  \"exbit-escp\",\n\t1317:  \"vrts-ipcserver\",\n\t1318:  \"krb5gatekeeper\",\n\t1319:  \"amx-icsp\",\n\t1320:  \"amx-axbnet\",\n\t1321:  \"pip\",\n\t1322:  \"novation\",\n\t1323:  \"brcd\",\n\t1324:  \"delta-mcp\",\n\t1325:  \"dx-instrument\",\n\t1326:  \"wimsic\",\n\t1327:  \"ultrex\",\n\t1328:  \"ewall\",\n\t1329:  \"netdb-export\",\n\t1330:  \"streetperfect\",\n\t1331:  \"intersan\",\n\t1332:  \"pcia-rxp-b\",\n\t1333:  \"passwrd-policy\",\n\t1334:  \"writesrv\",\n\t1335:  \"digital-notary\",\n\t1336:  \"ischat\",\n\t1337:  \"menandmice-dns\",\n\t1338:  \"wmc-log-svc\",\n\t1339:  \"kjtsiteserver\",\n\t1340:  \"naap\",\n\t1341:  \"qubes\",\n\t1342:  \"esbroker\",\n\t1343:  \"re101\",\n\t1344:  \"icap\",\n\t1345:  \"vpjp\",\n\t1346:  \"alta-ana-lm\",\n\t1347:  \"bbn-mmc\",\n\t1348:  \"bbn-mmx\",\n\t1349:  \"sbook\",\n\t1350:  \"editbench\",\n\t1351:  \"equationbuilder\",\n\t1352:  \"lotusnote\",\n\t1353:  \"relief\",\n\t1354:  \"XSIP-network\",\n\t1355:  \"intuitive-edge\",\n\t1356:  \"cuillamartin\",\n\t1357:  \"pegboard\",\n\t1358:  \"connlcli\",\n\t1359:  \"ftsrv\",\n\t1360:  \"mimer\",\n\t1361:  \"linx\",\n\t1362:  \"timeflies\",\n\t1363:  \"ndm-requester\",\n\t1364:  \"ndm-server\",\n\t1365:  \"adapt-sna\",\n\t1366:  \"netware-csp\",\n\t1367:  \"dcs\",\n\t1368:  \"screencast\",\n\t1369:  \"gv-us\",\n\t1370:  \"us-gv\",\n\t1371:  \"fc-cli\",\n\t1372:  \"fc-ser\",\n\t1373:  \"chromagrafx\",\n\t1374:  \"molly\",\n\t1375:  \"bytex\",\n\t1376:  \"ibm-pps\",\n\t1377:  \"cichlid\",\n\t1378:  \"elan\",\n\t1379:  \"dbreporter\",\n\t1380:  \"telesis-licman\",\n\t1381:  \"apple-licman\",\n\t1382:  \"udt-os\",\n\t1383:  \"gwha\",\n\t1384:  \"os-licman\",\n\t1385:  \"atex-elmd\",\n\t1386:  \"checksum\",\n\t1387:  \"cadsi-lm\",\n\t1388:  \"objective-dbc\",\n\t1389:  \"iclpv-dm\",\n\t1390:  \"iclpv-sc\",\n\t1391:  \"iclpv-sas\",\n\t1392:  \"iclpv-pm\",\n\t1393:  \"iclpv-nls\",\n\t1394:  \"iclpv-nlc\",\n\t1395:  \"iclpv-wsm\",\n\t1396:  \"dvl-activemail\",\n\t1397:  \"audio-activmail\",\n\t1398:  \"video-activmail\",\n\t1399:  \"cadkey-licman\",\n\t1400:  \"cadkey-tablet\",\n\t1401:  \"goldleaf-licman\",\n\t1402:  \"prm-sm-np\",\n\t1403:  \"prm-nm-np\",\n\t1404:  \"igi-lm\",\n\t1405:  \"ibm-res\",\n\t1406:  \"netlabs-lm\",\n\t1408:  \"sophia-lm\",\n\t1409:  \"here-lm\",\n\t1410:  \"hiq\",\n\t1411:  \"af\",\n\t1412:  \"innosys\",\n\t1413:  \"innosys-acl\",\n\t1414:  \"ibm-mqseries\",\n\t1415:  \"dbstar\",\n\t1416:  \"novell-lu6-2\",\n\t1417:  \"timbuktu-srv1\",\n\t1418:  \"timbuktu-srv2\",\n\t1419:  \"timbuktu-srv3\",\n\t1420:  \"timbuktu-srv4\",\n\t1421:  \"gandalf-lm\",\n\t1422:  \"autodesk-lm\",\n\t1423:  \"essbase\",\n\t1424:  \"hybrid\",\n\t1425:  \"zion-lm\",\n\t1426:  \"sais\",\n\t1427:  \"mloadd\",\n\t1428:  \"informatik-lm\",\n\t1429:  \"nms\",\n\t1430:  \"tpdu\",\n\t1431:  \"rgtp\",\n\t1432:  \"blueberry-lm\",\n\t1433:  \"ms-sql-s\",\n\t1434:  \"ms-sql-m\",\n\t1435:  \"ibm-cics\",\n\t1436:  \"saism\",\n\t1437:  \"tabula\",\n\t1438:  \"eicon-server\",\n\t1439:  \"eicon-x25\",\n\t1440:  \"eicon-slp\",\n\t1441:  \"cadis-1\",\n\t1442:  \"cadis-2\",\n\t1443:  \"ies-lm\",\n\t1444:  \"marcam-lm\",\n\t1445:  \"proxima-lm\",\n\t1446:  \"ora-lm\",\n\t1447:  \"apri-lm\",\n\t1448:  \"oc-lm\",\n\t1449:  \"peport\",\n\t1450:  \"dwf\",\n\t1451:  \"infoman\",\n\t1452:  \"gtegsc-lm\",\n\t1453:  \"genie-lm\",\n\t1454:  \"interhdl-elmd\",\n\t1455:  \"esl-lm\",\n\t1456:  \"dca\",\n\t1457:  \"valisys-lm\",\n\t1458:  \"nrcabq-lm\",\n\t1459:  \"proshare1\",\n\t1460:  \"proshare2\",\n\t1461:  \"ibm-wrless-lan\",\n\t1462:  \"world-lm\",\n\t1463:  \"nucleus\",\n\t1464:  \"msl-lmd\",\n\t1465:  \"pipes\",\n\t1466:  \"oceansoft-lm\",\n\t1467:  \"csdmbase\",\n\t1468:  \"csdm\",\n\t1469:  \"aal-lm\",\n\t1470:  \"uaiact\",\n\t1471:  \"csdmbase\",\n\t1472:  \"csdm\",\n\t1473:  \"openmath\",\n\t1474:  \"telefinder\",\n\t1475:  \"taligent-lm\",\n\t1476:  \"clvm-cfg\",\n\t1477:  \"ms-sna-server\",\n\t1478:  \"ms-sna-base\",\n\t1479:  \"dberegister\",\n\t1480:  \"pacerforum\",\n\t1481:  \"airs\",\n\t1482:  \"miteksys-lm\",\n\t1483:  \"afs\",\n\t1484:  \"confluent\",\n\t1485:  \"lansource\",\n\t1486:  \"nms-topo-serv\",\n\t1487:  \"localinfosrvr\",\n\t1488:  \"docstor\",\n\t1489:  \"dmdocbroker\",\n\t1490:  \"insitu-conf\",\n\t1492:  \"stone-design-1\",\n\t1493:  \"netmap-lm\",\n\t1494:  \"ica\",\n\t1495:  \"cvc\",\n\t1496:  \"liberty-lm\",\n\t1497:  \"rfx-lm\",\n\t1498:  \"sybase-sqlany\",\n\t1499:  \"fhc\",\n\t1500:  \"vlsi-lm\",\n\t1501:  \"saiscm\",\n\t1502:  \"shivadiscovery\",\n\t1503:  \"imtc-mcs\",\n\t1504:  \"evb-elm\",\n\t1505:  \"funkproxy\",\n\t1506:  \"utcd\",\n\t1507:  \"symplex\",\n\t1508:  \"diagmond\",\n\t1509:  \"robcad-lm\",\n\t1510:  \"mvx-lm\",\n\t1511:  \"3l-l1\",\n\t1512:  \"wins\",\n\t1513:  \"fujitsu-dtc\",\n\t1514:  \"fujitsu-dtcns\",\n\t1515:  \"ifor-protocol\",\n\t1516:  \"vpad\",\n\t1517:  \"vpac\",\n\t1518:  \"vpvd\",\n\t1519:  \"vpvc\",\n\t1520:  \"atm-zip-office\",\n\t1521:  \"ncube-lm\",\n\t1522:  \"ricardo-lm\",\n\t1523:  \"cichild-lm\",\n\t1524:  \"ingreslock\",\n\t1525:  \"orasrv\",\n\t1526:  \"pdap-np\",\n\t1527:  \"tlisrv\",\n\t1528:  \"ngr-t\",\n\t1529:  \"coauthor\",\n\t1530:  \"rap-service\",\n\t1531:  \"rap-listen\",\n\t1532:  \"miroconnect\",\n\t1533:  \"virtual-places\",\n\t1534:  \"micromuse-lm\",\n\t1535:  \"ampr-info\",\n\t1536:  \"ampr-inter\",\n\t1537:  \"sdsc-lm\",\n\t1538:  \"3ds-lm\",\n\t1539:  \"intellistor-lm\",\n\t1540:  \"rds\",\n\t1541:  \"rds2\",\n\t1542:  \"gridgen-elmd\",\n\t1543:  \"simba-cs\",\n\t1544:  \"aspeclmd\",\n\t1545:  \"vistium-share\",\n\t1546:  \"abbaccuray\",\n\t1547:  \"laplink\",\n\t1548:  \"axon-lm\",\n\t1549:  \"shivasound\",\n\t1550:  \"3m-image-lm\",\n\t1551:  \"hecmtl-db\",\n\t1552:  \"pciarray\",\n\t1553:  \"sna-cs\",\n\t1554:  \"caci-lm\",\n\t1555:  \"livelan\",\n\t1556:  \"veritas-pbx\",\n\t1557:  \"arbortext-lm\",\n\t1558:  \"xingmpeg\",\n\t1559:  \"web2host\",\n\t1560:  \"asci-val\",\n\t1561:  \"facilityview\",\n\t1562:  \"pconnectmgr\",\n\t1563:  \"cadabra-lm\",\n\t1564:  \"pay-per-view\",\n\t1565:  \"winddlb\",\n\t1566:  \"corelvideo\",\n\t1567:  \"jlicelmd\",\n\t1568:  \"tsspmap\",\n\t1569:  \"ets\",\n\t1570:  \"orbixd\",\n\t1571:  \"rdb-dbs-disp\",\n\t1572:  \"chip-lm\",\n\t1573:  \"itscomm-ns\",\n\t1574:  \"mvel-lm\",\n\t1575:  \"oraclenames\",\n\t1576:  \"moldflow-lm\",\n\t1577:  \"hypercube-lm\",\n\t1578:  \"jacobus-lm\",\n\t1579:  \"ioc-sea-lm\",\n\t1580:  \"tn-tl-r2\",\n\t1581:  \"mil-2045-47001\",\n\t1582:  \"msims\",\n\t1583:  \"simbaexpress\",\n\t1584:  \"tn-tl-fd2\",\n\t1585:  \"intv\",\n\t1586:  \"ibm-abtact\",\n\t1587:  \"pra-elmd\",\n\t1588:  \"triquest-lm\",\n\t1589:  \"vqp\",\n\t1590:  \"gemini-lm\",\n\t1591:  \"ncpm-pm\",\n\t1592:  \"commonspace\",\n\t1593:  \"mainsoft-lm\",\n\t1594:  \"sixtrak\",\n\t1595:  \"radio\",\n\t1596:  \"radio-bc\",\n\t1597:  \"orbplus-iiop\",\n\t1598:  \"picknfs\",\n\t1599:  \"simbaservices\",\n\t1600:  \"issd\",\n\t1601:  \"aas\",\n\t1602:  \"inspect\",\n\t1603:  \"picodbc\",\n\t1604:  \"icabrowser\",\n\t1605:  \"slp\",\n\t1606:  \"slm-api\",\n\t1607:  \"stt\",\n\t1608:  \"smart-lm\",\n\t1609:  \"isysg-lm\",\n\t1610:  \"taurus-wh\",\n\t1611:  \"ill\",\n\t1612:  \"netbill-trans\",\n\t1613:  \"netbill-keyrep\",\n\t1614:  \"netbill-cred\",\n\t1615:  \"netbill-auth\",\n\t1616:  \"netbill-prod\",\n\t1617:  \"nimrod-agent\",\n\t1618:  \"skytelnet\",\n\t1619:  \"xs-openstorage\",\n\t1620:  \"faxportwinport\",\n\t1621:  \"softdataphone\",\n\t1622:  \"ontime\",\n\t1623:  \"jaleosnd\",\n\t1624:  \"udp-sr-port\",\n\t1625:  \"svs-omagent\",\n\t1626:  \"shockwave\",\n\t1627:  \"t128-gateway\",\n\t1628:  \"lontalk-norm\",\n\t1629:  \"lontalk-urgnt\",\n\t1630:  \"oraclenet8cman\",\n\t1631:  \"visitview\",\n\t1632:  \"pammratc\",\n\t1633:  \"pammrpc\",\n\t1634:  \"loaprobe\",\n\t1635:  \"edb-server1\",\n\t1636:  \"isdc\",\n\t1637:  \"islc\",\n\t1638:  \"ismc\",\n\t1639:  \"cert-initiator\",\n\t1640:  \"cert-responder\",\n\t1641:  \"invision\",\n\t1642:  \"isis-am\",\n\t1643:  \"isis-ambc\",\n\t1644:  \"saiseh\",\n\t1645:  \"sightline\",\n\t1646:  \"sa-msg-port\",\n\t1647:  \"rsap\",\n\t1648:  \"concurrent-lm\",\n\t1649:  \"kermit\",\n\t1650:  \"nkd\",\n\t1651:  \"shiva-confsrvr\",\n\t1652:  \"xnmp\",\n\t1653:  \"alphatech-lm\",\n\t1654:  \"stargatealerts\",\n\t1655:  \"dec-mbadmin\",\n\t1656:  \"dec-mbadmin-h\",\n\t1657:  \"fujitsu-mmpdc\",\n\t1658:  \"sixnetudr\",\n\t1659:  \"sg-lm\",\n\t1660:  \"skip-mc-gikreq\",\n\t1661:  \"netview-aix-1\",\n\t1662:  \"netview-aix-2\",\n\t1663:  \"netview-aix-3\",\n\t1664:  \"netview-aix-4\",\n\t1665:  \"netview-aix-5\",\n\t1666:  \"netview-aix-6\",\n\t1667:  \"netview-aix-7\",\n\t1668:  \"netview-aix-8\",\n\t1669:  \"netview-aix-9\",\n\t1670:  \"netview-aix-10\",\n\t1671:  \"netview-aix-11\",\n\t1672:  \"netview-aix-12\",\n\t1673:  \"proshare-mc-1\",\n\t1674:  \"proshare-mc-2\",\n\t1675:  \"pdp\",\n\t1676:  \"netcomm2\",\n\t1677:  \"groupwise\",\n\t1678:  \"prolink\",\n\t1679:  \"darcorp-lm\",\n\t1680:  \"microcom-sbp\",\n\t1681:  \"sd-elmd\",\n\t1682:  \"lanyon-lantern\",\n\t1683:  \"ncpm-hip\",\n\t1684:  \"snaresecure\",\n\t1685:  \"n2nremote\",\n\t1686:  \"cvmon\",\n\t1687:  \"nsjtp-ctrl\",\n\t1688:  \"nsjtp-data\",\n\t1689:  \"firefox\",\n\t1690:  \"ng-umds\",\n\t1691:  \"empire-empuma\",\n\t1692:  \"sstsys-lm\",\n\t1693:  \"rrirtr\",\n\t1694:  \"rrimwm\",\n\t1695:  \"rrilwm\",\n\t1696:  \"rrifmm\",\n\t1697:  \"rrisat\",\n\t1698:  \"rsvp-encap-1\",\n\t1699:  \"rsvp-encap-2\",\n\t1700:  \"mps-raft\",\n\t1701:  \"l2f\",\n\t1702:  \"deskshare\",\n\t1703:  \"hb-engine\",\n\t1704:  \"bcs-broker\",\n\t1705:  \"slingshot\",\n\t1706:  \"jetform\",\n\t1707:  \"vdmplay\",\n\t1708:  \"gat-lmd\",\n\t1709:  \"centra\",\n\t1710:  \"impera\",\n\t1711:  \"pptconference\",\n\t1712:  \"registrar\",\n\t1713:  \"conferencetalk\",\n\t1714:  \"sesi-lm\",\n\t1715:  \"houdini-lm\",\n\t1716:  \"xmsg\",\n\t1717:  \"fj-hdnet\",\n\t1718:  \"h323gatedisc\",\n\t1719:  \"h323gatestat\",\n\t1720:  \"h323hostcall\",\n\t1721:  \"caicci\",\n\t1722:  \"hks-lm\",\n\t1723:  \"pptp\",\n\t1724:  \"csbphonemaster\",\n\t1725:  \"iden-ralp\",\n\t1726:  \"iberiagames\",\n\t1727:  \"winddx\",\n\t1728:  \"telindus\",\n\t1729:  \"citynl\",\n\t1730:  \"roketz\",\n\t1731:  \"msiccp\",\n\t1732:  \"proxim\",\n\t1733:  \"siipat\",\n\t1734:  \"cambertx-lm\",\n\t1735:  \"privatechat\",\n\t1736:  \"street-stream\",\n\t1737:  \"ultimad\",\n\t1738:  \"gamegen1\",\n\t1739:  \"webaccess\",\n\t1740:  \"encore\",\n\t1741:  \"cisco-net-mgmt\",\n\t1742:  \"3Com-nsd\",\n\t1743:  \"cinegrfx-lm\",\n\t1744:  \"ncpm-ft\",\n\t1745:  \"remote-winsock\",\n\t1746:  \"ftrapid-1\",\n\t1747:  \"ftrapid-2\",\n\t1748:  \"oracle-em1\",\n\t1749:  \"aspen-services\",\n\t1750:  \"sslp\",\n\t1751:  \"swiftnet\",\n\t1752:  \"lofr-lm\",\n\t1754:  \"oracle-em2\",\n\t1755:  \"ms-streaming\",\n\t1756:  \"capfast-lmd\",\n\t1757:  \"cnhrp\",\n\t1758:  \"tftp-mcast\",\n\t1759:  \"spss-lm\",\n\t1760:  \"www-ldap-gw\",\n\t1761:  \"cft-0\",\n\t1762:  \"cft-1\",\n\t1763:  \"cft-2\",\n\t1764:  \"cft-3\",\n\t1765:  \"cft-4\",\n\t1766:  \"cft-5\",\n\t1767:  \"cft-6\",\n\t1768:  \"cft-7\",\n\t1769:  \"bmc-net-adm\",\n\t1770:  \"bmc-net-svc\",\n\t1771:  \"vaultbase\",\n\t1772:  \"essweb-gw\",\n\t1773:  \"kmscontrol\",\n\t1774:  \"global-dtserv\",\n\t1776:  \"femis\",\n\t1777:  \"powerguardian\",\n\t1778:  \"prodigy-intrnet\",\n\t1779:  \"pharmasoft\",\n\t1780:  \"dpkeyserv\",\n\t1781:  \"answersoft-lm\",\n\t1782:  \"hp-hcip\",\n\t1784:  \"finle-lm\",\n\t1785:  \"windlm\",\n\t1786:  \"funk-logger\",\n\t1787:  \"funk-license\",\n\t1788:  \"psmond\",\n\t1789:  \"hello\",\n\t1790:  \"nmsp\",\n\t1791:  \"ea1\",\n\t1792:  \"ibm-dt-2\",\n\t1793:  \"rsc-robot\",\n\t1794:  \"cera-bcm\",\n\t1795:  \"dpi-proxy\",\n\t1796:  \"vocaltec-admin\",\n\t1797:  \"uma\",\n\t1798:  \"etp\",\n\t1799:  \"netrisk\",\n\t1800:  \"ansys-lm\",\n\t1801:  \"msmq\",\n\t1802:  \"concomp1\",\n\t1803:  \"hp-hcip-gwy\",\n\t1804:  \"enl\",\n\t1805:  \"enl-name\",\n\t1806:  \"musiconline\",\n\t1807:  \"fhsp\",\n\t1808:  \"oracle-vp2\",\n\t1809:  \"oracle-vp1\",\n\t1810:  \"jerand-lm\",\n\t1811:  \"scientia-sdb\",\n\t1812:  \"radius\",\n\t1813:  \"radius-acct\",\n\t1814:  \"tdp-suite\",\n\t1815:  \"mmpft\",\n\t1816:  \"harp\",\n\t1817:  \"rkb-oscs\",\n\t1818:  \"etftp\",\n\t1819:  \"plato-lm\",\n\t1820:  \"mcagent\",\n\t1821:  \"donnyworld\",\n\t1822:  \"es-elmd\",\n\t1823:  \"unisys-lm\",\n\t1824:  \"metrics-pas\",\n\t1825:  \"direcpc-video\",\n\t1826:  \"ardt\",\n\t1827:  \"asi\",\n\t1828:  \"itm-mcell-u\",\n\t1829:  \"optika-emedia\",\n\t1830:  \"net8-cman\",\n\t1831:  \"myrtle\",\n\t1832:  \"tht-treasure\",\n\t1833:  \"udpradio\",\n\t1834:  \"ardusuni\",\n\t1835:  \"ardusmul\",\n\t1836:  \"ste-smsc\",\n\t1837:  \"csoft1\",\n\t1838:  \"talnet\",\n\t1839:  \"netopia-vo1\",\n\t1840:  \"netopia-vo2\",\n\t1841:  \"netopia-vo3\",\n\t1842:  \"netopia-vo4\",\n\t1843:  \"netopia-vo5\",\n\t1844:  \"direcpc-dll\",\n\t1845:  \"altalink\",\n\t1846:  \"tunstall-pnc\",\n\t1847:  \"slp-notify\",\n\t1848:  \"fjdocdist\",\n\t1849:  \"alpha-sms\",\n\t1850:  \"gsi\",\n\t1851:  \"ctcd\",\n\t1852:  \"virtual-time\",\n\t1853:  \"vids-avtp\",\n\t1854:  \"buddy-draw\",\n\t1855:  \"fiorano-rtrsvc\",\n\t1856:  \"fiorano-msgsvc\",\n\t1857:  \"datacaptor\",\n\t1858:  \"privateark\",\n\t1859:  \"gammafetchsvr\",\n\t1860:  \"sunscalar-svc\",\n\t1861:  \"lecroy-vicp\",\n\t1862:  \"mysql-cm-agent\",\n\t1863:  \"msnp\",\n\t1864:  \"paradym-31port\",\n\t1865:  \"entp\",\n\t1866:  \"swrmi\",\n\t1867:  \"udrive\",\n\t1868:  \"viziblebrowser\",\n\t1869:  \"transact\",\n\t1870:  \"sunscalar-dns\",\n\t1871:  \"canocentral0\",\n\t1872:  \"canocentral1\",\n\t1873:  \"fjmpjps\",\n\t1874:  \"fjswapsnp\",\n\t1875:  \"westell-stats\",\n\t1876:  \"ewcappsrv\",\n\t1877:  \"hp-webqosdb\",\n\t1878:  \"drmsmc\",\n\t1879:  \"nettgain-nms\",\n\t1880:  \"vsat-control\",\n\t1881:  \"ibm-mqseries2\",\n\t1882:  \"ecsqdmn\",\n\t1883:  \"mqtt\",\n\t1884:  \"idmaps\",\n\t1885:  \"vrtstrapserver\",\n\t1886:  \"leoip\",\n\t1887:  \"filex-lport\",\n\t1888:  \"ncconfig\",\n\t1889:  \"unify-adapter\",\n\t1890:  \"wilkenlistener\",\n\t1891:  \"childkey-notif\",\n\t1892:  \"childkey-ctrl\",\n\t1893:  \"elad\",\n\t1894:  \"o2server-port\",\n\t1896:  \"b-novative-ls\",\n\t1897:  \"metaagent\",\n\t1898:  \"cymtec-port\",\n\t1899:  \"mc2studios\",\n\t1900:  \"ssdp\",\n\t1901:  \"fjicl-tep-a\",\n\t1902:  \"fjicl-tep-b\",\n\t1903:  \"linkname\",\n\t1904:  \"fjicl-tep-c\",\n\t1905:  \"sugp\",\n\t1906:  \"tpmd\",\n\t1907:  \"intrastar\",\n\t1908:  \"dawn\",\n\t1909:  \"global-wlink\",\n\t1910:  \"ultrabac\",\n\t1911:  \"mtp\",\n\t1912:  \"rhp-iibp\",\n\t1913:  \"armadp\",\n\t1914:  \"elm-momentum\",\n\t1915:  \"facelink\",\n\t1916:  \"persona\",\n\t1917:  \"noagent\",\n\t1918:  \"can-nds\",\n\t1919:  \"can-dch\",\n\t1920:  \"can-ferret\",\n\t1921:  \"noadmin\",\n\t1922:  \"tapestry\",\n\t1923:  \"spice\",\n\t1924:  \"xiip\",\n\t1925:  \"discovery-port\",\n\t1926:  \"egs\",\n\t1927:  \"videte-cipc\",\n\t1928:  \"emsd-port\",\n\t1929:  \"bandwiz-system\",\n\t1930:  \"driveappserver\",\n\t1931:  \"amdsched\",\n\t1932:  \"ctt-broker\",\n\t1933:  \"xmapi\",\n\t1934:  \"xaapi\",\n\t1935:  \"macromedia-fcs\",\n\t1936:  \"jetcmeserver\",\n\t1937:  \"jwserver\",\n\t1938:  \"jwclient\",\n\t1939:  \"jvserver\",\n\t1940:  \"jvclient\",\n\t1941:  \"dic-aida\",\n\t1942:  \"res\",\n\t1943:  \"beeyond-media\",\n\t1944:  \"close-combat\",\n\t1945:  \"dialogic-elmd\",\n\t1946:  \"tekpls\",\n\t1947:  \"sentinelsrm\",\n\t1948:  \"eye2eye\",\n\t1949:  \"ismaeasdaqlive\",\n\t1950:  \"ismaeasdaqtest\",\n\t1951:  \"bcs-lmserver\",\n\t1952:  \"mpnjsc\",\n\t1953:  \"rapidbase\",\n\t1954:  \"abr-api\",\n\t1955:  \"abr-secure\",\n\t1956:  \"vrtl-vmf-ds\",\n\t1957:  \"unix-status\",\n\t1958:  \"dxadmind\",\n\t1959:  \"simp-all\",\n\t1960:  \"nasmanager\",\n\t1961:  \"bts-appserver\",\n\t1962:  \"biap-mp\",\n\t1963:  \"webmachine\",\n\t1964:  \"solid-e-engine\",\n\t1965:  \"tivoli-npm\",\n\t1966:  \"slush\",\n\t1967:  \"sns-quote\",\n\t1968:  \"lipsinc\",\n\t1969:  \"lipsinc1\",\n\t1970:  \"netop-rc\",\n\t1971:  \"netop-school\",\n\t1972:  \"intersys-cache\",\n\t1973:  \"dlsrap\",\n\t1974:  \"drp\",\n\t1975:  \"tcoflashagent\",\n\t1976:  \"tcoregagent\",\n\t1977:  \"tcoaddressbook\",\n\t1978:  \"unisql\",\n\t1979:  \"unisql-java\",\n\t1980:  \"pearldoc-xact\",\n\t1981:  \"p2pq\",\n\t1982:  \"estamp\",\n\t1983:  \"lhtp\",\n\t1984:  \"bb\",\n\t1985:  \"hsrp\",\n\t1986:  \"licensedaemon\",\n\t1987:  \"tr-rsrb-p1\",\n\t1988:  \"tr-rsrb-p2\",\n\t1989:  \"tr-rsrb-p3\",\n\t1990:  \"stun-p1\",\n\t1991:  \"stun-p2\",\n\t1992:  \"stun-p3\",\n\t1993:  \"snmp-tcp-port\",\n\t1994:  \"stun-port\",\n\t1995:  \"perf-port\",\n\t1996:  \"tr-rsrb-port\",\n\t1997:  \"gdp-port\",\n\t1998:  \"x25-svc-port\",\n\t1999:  \"tcp-id-port\",\n\t2000:  \"cisco-sccp\",\n\t2001:  \"wizard\",\n\t2002:  \"globe\",\n\t2003:  \"brutus\",\n\t2004:  \"emce\",\n\t2005:  \"oracle\",\n\t2006:  \"raid-cd\",\n\t2007:  \"raid-am\",\n\t2008:  \"terminaldb\",\n\t2009:  \"whosockami\",\n\t2010:  \"pipe-server\",\n\t2011:  \"servserv\",\n\t2012:  \"raid-ac\",\n\t2013:  \"raid-cd\",\n\t2014:  \"raid-sf\",\n\t2015:  \"raid-cs\",\n\t2016:  \"bootserver\",\n\t2017:  \"bootclient\",\n\t2018:  \"rellpack\",\n\t2019:  \"about\",\n\t2020:  \"xinupageserver\",\n\t2021:  \"xinuexpansion1\",\n\t2022:  \"xinuexpansion2\",\n\t2023:  \"xinuexpansion3\",\n\t2024:  \"xinuexpansion4\",\n\t2025:  \"xribs\",\n\t2026:  \"scrabble\",\n\t2027:  \"shadowserver\",\n\t2028:  \"submitserver\",\n\t2029:  \"hsrpv6\",\n\t2030:  \"device2\",\n\t2031:  \"mobrien-chat\",\n\t2032:  \"blackboard\",\n\t2033:  \"glogger\",\n\t2034:  \"scoremgr\",\n\t2035:  \"imsldoc\",\n\t2036:  \"e-dpnet\",\n\t2037:  \"applus\",\n\t2038:  \"objectmanager\",\n\t2039:  \"prizma\",\n\t2040:  \"lam\",\n\t2041:  \"interbase\",\n\t2042:  \"isis\",\n\t2043:  \"isis-bcast\",\n\t2044:  \"rimsl\",\n\t2045:  \"cdfunc\",\n\t2046:  \"sdfunc\",\n\t2047:  \"dls\",\n\t2048:  \"dls-monitor\",\n\t2049:  \"shilp\",\n\t2050:  \"av-emb-config\",\n\t2051:  \"epnsdp\",\n\t2052:  \"clearvisn\",\n\t2053:  \"lot105-ds-upd\",\n\t2054:  \"weblogin\",\n\t2055:  \"iop\",\n\t2056:  \"omnisky\",\n\t2057:  \"rich-cp\",\n\t2058:  \"newwavesearch\",\n\t2059:  \"bmc-messaging\",\n\t2060:  \"teleniumdaemon\",\n\t2061:  \"netmount\",\n\t2062:  \"icg-swp\",\n\t2063:  \"icg-bridge\",\n\t2064:  \"icg-iprelay\",\n\t2065:  \"dlsrpn\",\n\t2066:  \"aura\",\n\t2067:  \"dlswpn\",\n\t2068:  \"avauthsrvprtcl\",\n\t2069:  \"event-port\",\n\t2070:  \"ah-esp-encap\",\n\t2071:  \"acp-port\",\n\t2072:  \"msync\",\n\t2073:  \"gxs-data-port\",\n\t2074:  \"vrtl-vmf-sa\",\n\t2075:  \"newlixengine\",\n\t2076:  \"newlixconfig\",\n\t2077:  \"tsrmagt\",\n\t2078:  \"tpcsrvr\",\n\t2079:  \"idware-router\",\n\t2080:  \"autodesk-nlm\",\n\t2081:  \"kme-trap-port\",\n\t2082:  \"infowave\",\n\t2083:  \"radsec\",\n\t2084:  \"sunclustergeo\",\n\t2085:  \"ada-cip\",\n\t2086:  \"gnunet\",\n\t2087:  \"eli\",\n\t2088:  \"ip-blf\",\n\t2089:  \"sep\",\n\t2090:  \"lrp\",\n\t2091:  \"prp\",\n\t2092:  \"descent3\",\n\t2093:  \"nbx-cc\",\n\t2094:  \"nbx-au\",\n\t2095:  \"nbx-ser\",\n\t2096:  \"nbx-dir\",\n\t2097:  \"jetformpreview\",\n\t2098:  \"dialog-port\",\n\t2099:  \"h2250-annex-g\",\n\t2100:  \"amiganetfs\",\n\t2101:  \"rtcm-sc104\",\n\t2102:  \"zephyr-srv\",\n\t2103:  \"zephyr-clt\",\n\t2104:  \"zephyr-hm\",\n\t2105:  \"minipay\",\n\t2106:  \"mzap\",\n\t2107:  \"bintec-admin\",\n\t2108:  \"comcam\",\n\t2109:  \"ergolight\",\n\t2110:  \"umsp\",\n\t2111:  \"dsatp\",\n\t2112:  \"idonix-metanet\",\n\t2113:  \"hsl-storm\",\n\t2114:  \"newheights\",\n\t2115:  \"kdm\",\n\t2116:  \"ccowcmr\",\n\t2117:  \"mentaclient\",\n\t2118:  \"mentaserver\",\n\t2119:  \"gsigatekeeper\",\n\t2120:  \"qencp\",\n\t2121:  \"scientia-ssdb\",\n\t2122:  \"caupc-remote\",\n\t2123:  \"gtp-control\",\n\t2124:  \"elatelink\",\n\t2125:  \"lockstep\",\n\t2126:  \"pktcable-cops\",\n\t2127:  \"index-pc-wb\",\n\t2128:  \"net-steward\",\n\t2129:  \"cs-live\",\n\t2130:  \"xds\",\n\t2131:  \"avantageb2b\",\n\t2132:  \"solera-epmap\",\n\t2133:  \"zymed-zpp\",\n\t2134:  \"avenue\",\n\t2135:  \"gris\",\n\t2136:  \"appworxsrv\",\n\t2137:  \"connect\",\n\t2138:  \"unbind-cluster\",\n\t2139:  \"ias-auth\",\n\t2140:  \"ias-reg\",\n\t2141:  \"ias-admind\",\n\t2142:  \"tdmoip\",\n\t2143:  \"lv-jc\",\n\t2144:  \"lv-ffx\",\n\t2145:  \"lv-pici\",\n\t2146:  \"lv-not\",\n\t2147:  \"lv-auth\",\n\t2148:  \"veritas-ucl\",\n\t2149:  \"acptsys\",\n\t2150:  \"dynamic3d\",\n\t2151:  \"docent\",\n\t2152:  \"gtp-user\",\n\t2153:  \"ctlptc\",\n\t2154:  \"stdptc\",\n\t2155:  \"brdptc\",\n\t2156:  \"trp\",\n\t2157:  \"xnds\",\n\t2158:  \"touchnetplus\",\n\t2159:  \"gdbremote\",\n\t2160:  \"apc-2160\",\n\t2161:  \"apc-2161\",\n\t2162:  \"navisphere\",\n\t2163:  \"navisphere-sec\",\n\t2164:  \"ddns-v3\",\n\t2165:  \"x-bone-api\",\n\t2166:  \"iwserver\",\n\t2167:  \"raw-serial\",\n\t2168:  \"easy-soft-mux\",\n\t2169:  \"brain\",\n\t2170:  \"eyetv\",\n\t2171:  \"msfw-storage\",\n\t2172:  \"msfw-s-storage\",\n\t2173:  \"msfw-replica\",\n\t2174:  \"msfw-array\",\n\t2175:  \"airsync\",\n\t2176:  \"rapi\",\n\t2177:  \"qwave\",\n\t2178:  \"bitspeer\",\n\t2179:  \"vmrdp\",\n\t2180:  \"mc-gt-srv\",\n\t2181:  \"eforward\",\n\t2182:  \"cgn-stat\",\n\t2183:  \"cgn-config\",\n\t2184:  \"nvd\",\n\t2185:  \"onbase-dds\",\n\t2186:  \"gtaua\",\n\t2187:  \"ssmd\",\n\t2190:  \"tivoconnect\",\n\t2191:  \"tvbus\",\n\t2192:  \"asdis\",\n\t2193:  \"drwcs\",\n\t2197:  \"mnp-exchange\",\n\t2198:  \"onehome-remote\",\n\t2199:  \"onehome-help\",\n\t2200:  \"ici\",\n\t2201:  \"ats\",\n\t2202:  \"imtc-map\",\n\t2203:  \"b2-runtime\",\n\t2204:  \"b2-license\",\n\t2205:  \"jps\",\n\t2206:  \"hpocbus\",\n\t2207:  \"hpssd\",\n\t2208:  \"hpiod\",\n\t2209:  \"rimf-ps\",\n\t2210:  \"noaaport\",\n\t2211:  \"emwin\",\n\t2212:  \"leecoposserver\",\n\t2213:  \"kali\",\n\t2214:  \"rpi\",\n\t2215:  \"ipcore\",\n\t2216:  \"vtu-comms\",\n\t2217:  \"gotodevice\",\n\t2218:  \"bounzza\",\n\t2219:  \"netiq-ncap\",\n\t2220:  \"netiq\",\n\t2221:  \"ethernet-ip-s\",\n\t2222:  \"EtherNet-IP-1\",\n\t2223:  \"rockwell-csp2\",\n\t2224:  \"efi-mg\",\n\t2226:  \"di-drm\",\n\t2227:  \"di-msg\",\n\t2228:  \"ehome-ms\",\n\t2229:  \"datalens\",\n\t2230:  \"queueadm\",\n\t2231:  \"wimaxasncp\",\n\t2232:  \"ivs-video\",\n\t2233:  \"infocrypt\",\n\t2234:  \"directplay\",\n\t2235:  \"sercomm-wlink\",\n\t2236:  \"nani\",\n\t2237:  \"optech-port1-lm\",\n\t2238:  \"aviva-sna\",\n\t2239:  \"imagequery\",\n\t2240:  \"recipe\",\n\t2241:  \"ivsd\",\n\t2242:  \"foliocorp\",\n\t2243:  \"magicom\",\n\t2244:  \"nmsserver\",\n\t2245:  \"hao\",\n\t2246:  \"pc-mta-addrmap\",\n\t2247:  \"antidotemgrsvr\",\n\t2248:  \"ums\",\n\t2249:  \"rfmp\",\n\t2250:  \"remote-collab\",\n\t2251:  \"dif-port\",\n\t2252:  \"njenet-ssl\",\n\t2253:  \"dtv-chan-req\",\n\t2254:  \"seispoc\",\n\t2255:  \"vrtp\",\n\t2256:  \"pcc-mfp\",\n\t2257:  \"simple-tx-rx\",\n\t2258:  \"rcts\",\n\t2260:  \"apc-2260\",\n\t2261:  \"comotionmaster\",\n\t2262:  \"comotionback\",\n\t2263:  \"ecwcfg\",\n\t2264:  \"apx500api-1\",\n\t2265:  \"apx500api-2\",\n\t2266:  \"mfserver\",\n\t2267:  \"ontobroker\",\n\t2268:  \"amt\",\n\t2269:  \"mikey\",\n\t2270:  \"starschool\",\n\t2271:  \"mmcals\",\n\t2272:  \"mmcal\",\n\t2273:  \"mysql-im\",\n\t2274:  \"pcttunnell\",\n\t2275:  \"ibridge-data\",\n\t2276:  \"ibridge-mgmt\",\n\t2277:  \"bluectrlproxy\",\n\t2278:  \"s3db\",\n\t2279:  \"xmquery\",\n\t2280:  \"lnvpoller\",\n\t2281:  \"lnvconsole\",\n\t2282:  \"lnvalarm\",\n\t2283:  \"lnvstatus\",\n\t2284:  \"lnvmaps\",\n\t2285:  \"lnvmailmon\",\n\t2286:  \"nas-metering\",\n\t2287:  \"dna\",\n\t2288:  \"netml\",\n\t2289:  \"dict-lookup\",\n\t2290:  \"sonus-logging\",\n\t2291:  \"eapsp\",\n\t2292:  \"mib-streaming\",\n\t2293:  \"npdbgmngr\",\n\t2294:  \"konshus-lm\",\n\t2295:  \"advant-lm\",\n\t2296:  \"theta-lm\",\n\t2297:  \"d2k-datamover1\",\n\t2298:  \"d2k-datamover2\",\n\t2299:  \"pc-telecommute\",\n\t2300:  \"cvmmon\",\n\t2301:  \"cpq-wbem\",\n\t2302:  \"binderysupport\",\n\t2303:  \"proxy-gateway\",\n\t2304:  \"attachmate-uts\",\n\t2305:  \"mt-scaleserver\",\n\t2306:  \"tappi-boxnet\",\n\t2307:  \"pehelp\",\n\t2308:  \"sdhelp\",\n\t2309:  \"sdserver\",\n\t2310:  \"sdclient\",\n\t2311:  \"messageservice\",\n\t2312:  \"wanscaler\",\n\t2313:  \"iapp\",\n\t2314:  \"cr-websystems\",\n\t2315:  \"precise-sft\",\n\t2316:  \"sent-lm\",\n\t2317:  \"attachmate-g32\",\n\t2318:  \"cadencecontrol\",\n\t2319:  \"infolibria\",\n\t2320:  \"siebel-ns\",\n\t2321:  \"rdlap\",\n\t2322:  \"ofsd\",\n\t2323:  \"3d-nfsd\",\n\t2324:  \"cosmocall\",\n\t2325:  \"ansysli\",\n\t2326:  \"idcp\",\n\t2327:  \"xingcsm\",\n\t2328:  \"netrix-sftm\",\n\t2329:  \"nvd\",\n\t2330:  \"tscchat\",\n\t2331:  \"agentview\",\n\t2332:  \"rcc-host\",\n\t2333:  \"snapp\",\n\t2334:  \"ace-client\",\n\t2335:  \"ace-proxy\",\n\t2336:  \"appleugcontrol\",\n\t2337:  \"ideesrv\",\n\t2338:  \"norton-lambert\",\n\t2339:  \"3com-webview\",\n\t2340:  \"wrs-registry\",\n\t2341:  \"xiostatus\",\n\t2342:  \"manage-exec\",\n\t2343:  \"nati-logos\",\n\t2344:  \"fcmsys\",\n\t2345:  \"dbm\",\n\t2346:  \"redstorm-join\",\n\t2347:  \"redstorm-find\",\n\t2348:  \"redstorm-info\",\n\t2349:  \"redstorm-diag\",\n\t2350:  \"psbserver\",\n\t2351:  \"psrserver\",\n\t2352:  \"pslserver\",\n\t2353:  \"pspserver\",\n\t2354:  \"psprserver\",\n\t2355:  \"psdbserver\",\n\t2356:  \"gxtelmd\",\n\t2357:  \"unihub-server\",\n\t2358:  \"futrix\",\n\t2359:  \"flukeserver\",\n\t2360:  \"nexstorindltd\",\n\t2361:  \"tl1\",\n\t2362:  \"digiman\",\n\t2363:  \"mediacntrlnfsd\",\n\t2364:  \"oi-2000\",\n\t2365:  \"dbref\",\n\t2366:  \"qip-login\",\n\t2367:  \"service-ctrl\",\n\t2368:  \"opentable\",\n\t2370:  \"l3-hbmon\",\n\t2372:  \"lanmessenger\",\n\t2381:  \"compaq-https\",\n\t2382:  \"ms-olap3\",\n\t2383:  \"ms-olap4\",\n\t2384:  \"sd-capacity\",\n\t2385:  \"sd-data\",\n\t2386:  \"virtualtape\",\n\t2387:  \"vsamredirector\",\n\t2388:  \"mynahautostart\",\n\t2389:  \"ovsessionmgr\",\n\t2390:  \"rsmtp\",\n\t2391:  \"3com-net-mgmt\",\n\t2392:  \"tacticalauth\",\n\t2393:  \"ms-olap1\",\n\t2394:  \"ms-olap2\",\n\t2395:  \"lan900-remote\",\n\t2396:  \"wusage\",\n\t2397:  \"ncl\",\n\t2398:  \"orbiter\",\n\t2399:  \"fmpro-fdal\",\n\t2400:  \"opequus-server\",\n\t2401:  \"cvspserver\",\n\t2402:  \"taskmaster2000\",\n\t2403:  \"taskmaster2000\",\n\t2404:  \"iec-104\",\n\t2405:  \"trc-netpoll\",\n\t2406:  \"jediserver\",\n\t2407:  \"orion\",\n\t2409:  \"sns-protocol\",\n\t2410:  \"vrts-registry\",\n\t2411:  \"netwave-ap-mgmt\",\n\t2412:  \"cdn\",\n\t2413:  \"orion-rmi-reg\",\n\t2414:  \"beeyond\",\n\t2415:  \"codima-rtp\",\n\t2416:  \"rmtserver\",\n\t2417:  \"composit-server\",\n\t2418:  \"cas\",\n\t2419:  \"attachmate-s2s\",\n\t2420:  \"dslremote-mgmt\",\n\t2421:  \"g-talk\",\n\t2422:  \"crmsbits\",\n\t2423:  \"rnrp\",\n\t2424:  \"kofax-svr\",\n\t2425:  \"fjitsuappmgr\",\n\t2426:  \"vcmp\",\n\t2427:  \"mgcp-gateway\",\n\t2428:  \"ott\",\n\t2429:  \"ft-role\",\n\t2430:  \"venus\",\n\t2431:  \"venus-se\",\n\t2432:  \"codasrv\",\n\t2433:  \"codasrv-se\",\n\t2434:  \"pxc-epmap\",\n\t2435:  \"optilogic\",\n\t2436:  \"topx\",\n\t2437:  \"unicontrol\",\n\t2438:  \"msp\",\n\t2439:  \"sybasedbsynch\",\n\t2440:  \"spearway\",\n\t2441:  \"pvsw-inet\",\n\t2442:  \"netangel\",\n\t2443:  \"powerclientcsf\",\n\t2444:  \"btpp2sectrans\",\n\t2445:  \"dtn1\",\n\t2446:  \"bues-service\",\n\t2447:  \"ovwdb\",\n\t2448:  \"hpppssvr\",\n\t2449:  \"ratl\",\n\t2450:  \"netadmin\",\n\t2451:  \"netchat\",\n\t2452:  \"snifferclient\",\n\t2453:  \"madge-ltd\",\n\t2454:  \"indx-dds\",\n\t2455:  \"wago-io-system\",\n\t2456:  \"altav-remmgt\",\n\t2457:  \"rapido-ip\",\n\t2458:  \"griffin\",\n\t2459:  \"community\",\n\t2460:  \"ms-theater\",\n\t2461:  \"qadmifoper\",\n\t2462:  \"qadmifevent\",\n\t2463:  \"lsi-raid-mgmt\",\n\t2464:  \"direcpc-si\",\n\t2465:  \"lbm\",\n\t2466:  \"lbf\",\n\t2467:  \"high-criteria\",\n\t2468:  \"qip-msgd\",\n\t2469:  \"mti-tcs-comm\",\n\t2470:  \"taskman-port\",\n\t2471:  \"seaodbc\",\n\t2472:  \"c3\",\n\t2473:  \"aker-cdp\",\n\t2474:  \"vitalanalysis\",\n\t2475:  \"ace-server\",\n\t2476:  \"ace-svr-prop\",\n\t2477:  \"ssm-cvs\",\n\t2478:  \"ssm-cssps\",\n\t2479:  \"ssm-els\",\n\t2480:  \"powerexchange\",\n\t2481:  \"giop\",\n\t2482:  \"giop-ssl\",\n\t2483:  \"ttc\",\n\t2484:  \"ttc-ssl\",\n\t2485:  \"netobjects1\",\n\t2486:  \"netobjects2\",\n\t2487:  \"pns\",\n\t2488:  \"moy-corp\",\n\t2489:  \"tsilb\",\n\t2490:  \"qip-qdhcp\",\n\t2491:  \"conclave-cpp\",\n\t2492:  \"groove\",\n\t2493:  \"talarian-mqs\",\n\t2494:  \"bmc-ar\",\n\t2495:  \"fast-rem-serv\",\n\t2496:  \"dirgis\",\n\t2497:  \"quaddb\",\n\t2498:  \"odn-castraq\",\n\t2499:  \"unicontrol\",\n\t2500:  \"rtsserv\",\n\t2501:  \"rtsclient\",\n\t2502:  \"kentrox-prot\",\n\t2503:  \"nms-dpnss\",\n\t2504:  \"wlbs\",\n\t2505:  \"ppcontrol\",\n\t2506:  \"jbroker\",\n\t2507:  \"spock\",\n\t2508:  \"jdatastore\",\n\t2509:  \"fjmpss\",\n\t2510:  \"fjappmgrbulk\",\n\t2511:  \"metastorm\",\n\t2512:  \"citrixima\",\n\t2513:  \"citrixadmin\",\n\t2514:  \"facsys-ntp\",\n\t2515:  \"facsys-router\",\n\t2516:  \"maincontrol\",\n\t2517:  \"call-sig-trans\",\n\t2518:  \"willy\",\n\t2519:  \"globmsgsvc\",\n\t2520:  \"pvsw\",\n\t2521:  \"adaptecmgr\",\n\t2522:  \"windb\",\n\t2523:  \"qke-llc-v3\",\n\t2524:  \"optiwave-lm\",\n\t2525:  \"ms-v-worlds\",\n\t2526:  \"ema-sent-lm\",\n\t2527:  \"iqserver\",\n\t2528:  \"ncr-ccl\",\n\t2529:  \"utsftp\",\n\t2530:  \"vrcommerce\",\n\t2531:  \"ito-e-gui\",\n\t2532:  \"ovtopmd\",\n\t2533:  \"snifferserver\",\n\t2534:  \"combox-web-acc\",\n\t2535:  \"madcap\",\n\t2536:  \"btpp2audctr1\",\n\t2537:  \"upgrade\",\n\t2538:  \"vnwk-prapi\",\n\t2539:  \"vsiadmin\",\n\t2540:  \"lonworks\",\n\t2541:  \"lonworks2\",\n\t2542:  \"udrawgraph\",\n\t2543:  \"reftek\",\n\t2544:  \"novell-zen\",\n\t2545:  \"sis-emt\",\n\t2546:  \"vytalvaultbrtp\",\n\t2547:  \"vytalvaultvsmp\",\n\t2548:  \"vytalvaultpipe\",\n\t2549:  \"ipass\",\n\t2550:  \"ads\",\n\t2551:  \"isg-uda-server\",\n\t2552:  \"call-logging\",\n\t2553:  \"efidiningport\",\n\t2554:  \"vcnet-link-v10\",\n\t2555:  \"compaq-wcp\",\n\t2556:  \"nicetec-nmsvc\",\n\t2557:  \"nicetec-mgmt\",\n\t2558:  \"pclemultimedia\",\n\t2559:  \"lstp\",\n\t2560:  \"labrat\",\n\t2561:  \"mosaixcc\",\n\t2562:  \"delibo\",\n\t2563:  \"cti-redwood\",\n\t2564:  \"hp-3000-telnet\",\n\t2565:  \"coord-svr\",\n\t2566:  \"pcs-pcw\",\n\t2567:  \"clp\",\n\t2568:  \"spamtrap\",\n\t2569:  \"sonuscallsig\",\n\t2570:  \"hs-port\",\n\t2571:  \"cecsvc\",\n\t2572:  \"ibp\",\n\t2573:  \"trustestablish\",\n\t2574:  \"blockade-bpsp\",\n\t2575:  \"hl7\",\n\t2576:  \"tclprodebugger\",\n\t2577:  \"scipticslsrvr\",\n\t2578:  \"rvs-isdn-dcp\",\n\t2579:  \"mpfoncl\",\n\t2580:  \"tributary\",\n\t2581:  \"argis-te\",\n\t2582:  \"argis-ds\",\n\t2583:  \"mon\",\n\t2584:  \"cyaserv\",\n\t2585:  \"netx-server\",\n\t2586:  \"netx-agent\",\n\t2587:  \"masc\",\n\t2588:  \"privilege\",\n\t2589:  \"quartus-tcl\",\n\t2590:  \"idotdist\",\n\t2591:  \"maytagshuffle\",\n\t2592:  \"netrek\",\n\t2593:  \"mns-mail\",\n\t2594:  \"dts\",\n\t2595:  \"worldfusion1\",\n\t2596:  \"worldfusion2\",\n\t2597:  \"homesteadglory\",\n\t2598:  \"citriximaclient\",\n\t2599:  \"snapd\",\n\t2600:  \"hpstgmgr\",\n\t2601:  \"discp-client\",\n\t2602:  \"discp-server\",\n\t2603:  \"servicemeter\",\n\t2604:  \"nsc-ccs\",\n\t2605:  \"nsc-posa\",\n\t2606:  \"netmon\",\n\t2607:  \"connection\",\n\t2608:  \"wag-service\",\n\t2609:  \"system-monitor\",\n\t2610:  \"versa-tek\",\n\t2611:  \"lionhead\",\n\t2612:  \"qpasa-agent\",\n\t2613:  \"smntubootstrap\",\n\t2614:  \"neveroffline\",\n\t2615:  \"firepower\",\n\t2616:  \"appswitch-emp\",\n\t2617:  \"cmadmin\",\n\t2618:  \"priority-e-com\",\n\t2619:  \"bruce\",\n\t2620:  \"lpsrecommender\",\n\t2621:  \"miles-apart\",\n\t2622:  \"metricadbc\",\n\t2623:  \"lmdp\",\n\t2624:  \"aria\",\n\t2625:  \"blwnkl-port\",\n\t2626:  \"gbjd816\",\n\t2627:  \"moshebeeri\",\n\t2628:  \"dict\",\n\t2629:  \"sitaraserver\",\n\t2630:  \"sitaramgmt\",\n\t2631:  \"sitaradir\",\n\t2632:  \"irdg-post\",\n\t2633:  \"interintelli\",\n\t2634:  \"pk-electronics\",\n\t2635:  \"backburner\",\n\t2636:  \"solve\",\n\t2637:  \"imdocsvc\",\n\t2638:  \"sybaseanywhere\",\n\t2639:  \"aminet\",\n\t2640:  \"ami-control\",\n\t2641:  \"hdl-srv\",\n\t2642:  \"tragic\",\n\t2643:  \"gte-samp\",\n\t2644:  \"travsoft-ipx-t\",\n\t2645:  \"novell-ipx-cmd\",\n\t2646:  \"and-lm\",\n\t2647:  \"syncserver\",\n\t2648:  \"upsnotifyprot\",\n\t2649:  \"vpsipport\",\n\t2650:  \"eristwoguns\",\n\t2651:  \"ebinsite\",\n\t2652:  \"interpathpanel\",\n\t2653:  \"sonus\",\n\t2654:  \"corel-vncadmin\",\n\t2655:  \"unglue\",\n\t2656:  \"kana\",\n\t2657:  \"sns-dispatcher\",\n\t2658:  \"sns-admin\",\n\t2659:  \"sns-query\",\n\t2660:  \"gcmonitor\",\n\t2661:  \"olhost\",\n\t2662:  \"bintec-capi\",\n\t2663:  \"bintec-tapi\",\n\t2664:  \"patrol-mq-gm\",\n\t2665:  \"patrol-mq-nm\",\n\t2666:  \"extensis\",\n\t2667:  \"alarm-clock-s\",\n\t2668:  \"alarm-clock-c\",\n\t2669:  \"toad\",\n\t2670:  \"tve-announce\",\n\t2671:  \"newlixreg\",\n\t2672:  \"nhserver\",\n\t2673:  \"firstcall42\",\n\t2674:  \"ewnn\",\n\t2675:  \"ttc-etap\",\n\t2676:  \"simslink\",\n\t2677:  \"gadgetgate1way\",\n\t2678:  \"gadgetgate2way\",\n\t2679:  \"syncserverssl\",\n\t2680:  \"pxc-sapxom\",\n\t2681:  \"mpnjsomb\",\n\t2683:  \"ncdloadbalance\",\n\t2684:  \"mpnjsosv\",\n\t2685:  \"mpnjsocl\",\n\t2686:  \"mpnjsomg\",\n\t2687:  \"pq-lic-mgmt\",\n\t2688:  \"md-cg-http\",\n\t2689:  \"fastlynx\",\n\t2690:  \"hp-nnm-data\",\n\t2691:  \"itinternet\",\n\t2692:  \"admins-lms\",\n\t2694:  \"pwrsevent\",\n\t2695:  \"vspread\",\n\t2696:  \"unifyadmin\",\n\t2697:  \"oce-snmp-trap\",\n\t2698:  \"mck-ivpip\",\n\t2699:  \"csoft-plusclnt\",\n\t2700:  \"tqdata\",\n\t2701:  \"sms-rcinfo\",\n\t2702:  \"sms-xfer\",\n\t2703:  \"sms-chat\",\n\t2704:  \"sms-remctrl\",\n\t2705:  \"sds-admin\",\n\t2706:  \"ncdmirroring\",\n\t2707:  \"emcsymapiport\",\n\t2708:  \"banyan-net\",\n\t2709:  \"supermon\",\n\t2710:  \"sso-service\",\n\t2711:  \"sso-control\",\n\t2712:  \"aocp\",\n\t2713:  \"raventbs\",\n\t2714:  \"raventdm\",\n\t2715:  \"hpstgmgr2\",\n\t2716:  \"inova-ip-disco\",\n\t2717:  \"pn-requester\",\n\t2718:  \"pn-requester2\",\n\t2719:  \"scan-change\",\n\t2720:  \"wkars\",\n\t2721:  \"smart-diagnose\",\n\t2722:  \"proactivesrvr\",\n\t2723:  \"watchdog-nt\",\n\t2724:  \"qotps\",\n\t2725:  \"msolap-ptp2\",\n\t2726:  \"tams\",\n\t2727:  \"mgcp-callagent\",\n\t2728:  \"sqdr\",\n\t2729:  \"tcim-control\",\n\t2730:  \"nec-raidplus\",\n\t2731:  \"fyre-messanger\",\n\t2732:  \"g5m\",\n\t2733:  \"signet-ctf\",\n\t2734:  \"ccs-software\",\n\t2735:  \"netiq-mc\",\n\t2736:  \"radwiz-nms-srv\",\n\t2737:  \"srp-feedback\",\n\t2738:  \"ndl-tcp-ois-gw\",\n\t2739:  \"tn-timing\",\n\t2740:  \"alarm\",\n\t2741:  \"tsb\",\n\t2742:  \"tsb2\",\n\t2743:  \"murx\",\n\t2744:  \"honyaku\",\n\t2745:  \"urbisnet\",\n\t2746:  \"cpudpencap\",\n\t2747:  \"fjippol-swrly\",\n\t2748:  \"fjippol-polsvr\",\n\t2749:  \"fjippol-cnsl\",\n\t2750:  \"fjippol-port1\",\n\t2751:  \"fjippol-port2\",\n\t2752:  \"rsisysaccess\",\n\t2753:  \"de-spot\",\n\t2754:  \"apollo-cc\",\n\t2755:  \"expresspay\",\n\t2756:  \"simplement-tie\",\n\t2757:  \"cnrp\",\n\t2758:  \"apollo-status\",\n\t2759:  \"apollo-gms\",\n\t2760:  \"sabams\",\n\t2761:  \"dicom-iscl\",\n\t2762:  \"dicom-tls\",\n\t2763:  \"desktop-dna\",\n\t2764:  \"data-insurance\",\n\t2765:  \"qip-audup\",\n\t2766:  \"compaq-scp\",\n\t2767:  \"uadtc\",\n\t2768:  \"uacs\",\n\t2769:  \"exce\",\n\t2770:  \"veronica\",\n\t2771:  \"vergencecm\",\n\t2772:  \"auris\",\n\t2773:  \"rbakcup1\",\n\t2774:  \"rbakcup2\",\n\t2775:  \"smpp\",\n\t2776:  \"ridgeway1\",\n\t2777:  \"ridgeway2\",\n\t2778:  \"gwen-sonya\",\n\t2779:  \"lbc-sync\",\n\t2780:  \"lbc-control\",\n\t2781:  \"whosells\",\n\t2782:  \"everydayrc\",\n\t2783:  \"aises\",\n\t2784:  \"www-dev\",\n\t2785:  \"aic-np\",\n\t2786:  \"aic-oncrpc\",\n\t2787:  \"piccolo\",\n\t2788:  \"fryeserv\",\n\t2789:  \"media-agent\",\n\t2790:  \"plgproxy\",\n\t2791:  \"mtport-regist\",\n\t2792:  \"f5-globalsite\",\n\t2793:  \"initlsmsad\",\n\t2795:  \"livestats\",\n\t2796:  \"ac-tech\",\n\t2797:  \"esp-encap\",\n\t2798:  \"tmesis-upshot\",\n\t2799:  \"icon-discover\",\n\t2800:  \"acc-raid\",\n\t2801:  \"igcp\",\n\t2802:  \"veritas-udp1\",\n\t2803:  \"btprjctrl\",\n\t2804:  \"dvr-esm\",\n\t2805:  \"wta-wsp-s\",\n\t2806:  \"cspuni\",\n\t2807:  \"cspmulti\",\n\t2808:  \"j-lan-p\",\n\t2809:  \"corbaloc\",\n\t2810:  \"netsteward\",\n\t2811:  \"gsiftp\",\n\t2812:  \"atmtcp\",\n\t2813:  \"llm-pass\",\n\t2814:  \"llm-csv\",\n\t2815:  \"lbc-measure\",\n\t2816:  \"lbc-watchdog\",\n\t2817:  \"nmsigport\",\n\t2818:  \"rmlnk\",\n\t2819:  \"fc-faultnotify\",\n\t2820:  \"univision\",\n\t2821:  \"vrts-at-port\",\n\t2822:  \"ka0wuc\",\n\t2823:  \"cqg-netlan\",\n\t2824:  \"cqg-netlan-1\",\n\t2826:  \"slc-systemlog\",\n\t2827:  \"slc-ctrlrloops\",\n\t2828:  \"itm-lm\",\n\t2829:  \"silkp1\",\n\t2830:  \"silkp2\",\n\t2831:  \"silkp3\",\n\t2832:  \"silkp4\",\n\t2833:  \"glishd\",\n\t2834:  \"evtp\",\n\t2835:  \"evtp-data\",\n\t2836:  \"catalyst\",\n\t2837:  \"repliweb\",\n\t2838:  \"starbot\",\n\t2839:  \"nmsigport\",\n\t2840:  \"l3-exprt\",\n\t2841:  \"l3-ranger\",\n\t2842:  \"l3-hawk\",\n\t2843:  \"pdnet\",\n\t2844:  \"bpcp-poll\",\n\t2845:  \"bpcp-trap\",\n\t2846:  \"aimpp-hello\",\n\t2847:  \"aimpp-port-req\",\n\t2848:  \"amt-blc-port\",\n\t2849:  \"fxp\",\n\t2850:  \"metaconsole\",\n\t2851:  \"webemshttp\",\n\t2852:  \"bears-01\",\n\t2853:  \"ispipes\",\n\t2854:  \"infomover\",\n\t2856:  \"cesdinv\",\n\t2857:  \"simctlp\",\n\t2858:  \"ecnp\",\n\t2859:  \"activememory\",\n\t2860:  \"dialpad-voice1\",\n\t2861:  \"dialpad-voice2\",\n\t2862:  \"ttg-protocol\",\n\t2863:  \"sonardata\",\n\t2864:  \"astromed-main\",\n\t2865:  \"pit-vpn\",\n\t2866:  \"iwlistener\",\n\t2867:  \"esps-portal\",\n\t2868:  \"npep-messaging\",\n\t2869:  \"icslap\",\n\t2870:  \"daishi\",\n\t2871:  \"msi-selectplay\",\n\t2872:  \"radix\",\n\t2874:  \"dxmessagebase1\",\n\t2875:  \"dxmessagebase2\",\n\t2876:  \"sps-tunnel\",\n\t2877:  \"bluelance\",\n\t2878:  \"aap\",\n\t2879:  \"ucentric-ds\",\n\t2880:  \"synapse\",\n\t2881:  \"ndsp\",\n\t2882:  \"ndtp\",\n\t2883:  \"ndnp\",\n\t2884:  \"flashmsg\",\n\t2885:  \"topflow\",\n\t2886:  \"responselogic\",\n\t2887:  \"aironetddp\",\n\t2888:  \"spcsdlobby\",\n\t2889:  \"rsom\",\n\t2890:  \"cspclmulti\",\n\t2891:  \"cinegrfx-elmd\",\n\t2892:  \"snifferdata\",\n\t2893:  \"vseconnector\",\n\t2894:  \"abacus-remote\",\n\t2895:  \"natuslink\",\n\t2896:  \"ecovisiong6-1\",\n\t2897:  \"citrix-rtmp\",\n\t2898:  \"appliance-cfg\",\n\t2899:  \"powergemplus\",\n\t2900:  \"quicksuite\",\n\t2901:  \"allstorcns\",\n\t2902:  \"netaspi\",\n\t2903:  \"suitcase\",\n\t2904:  \"m2ua\",\n\t2906:  \"caller9\",\n\t2907:  \"webmethods-b2b\",\n\t2908:  \"mao\",\n\t2909:  \"funk-dialout\",\n\t2910:  \"tdaccess\",\n\t2911:  \"blockade\",\n\t2912:  \"epicon\",\n\t2913:  \"boosterware\",\n\t2914:  \"gamelobby\",\n\t2915:  \"tksocket\",\n\t2916:  \"elvin-server\",\n\t2917:  \"elvin-client\",\n\t2918:  \"kastenchasepad\",\n\t2919:  \"roboer\",\n\t2920:  \"roboeda\",\n\t2921:  \"cesdcdman\",\n\t2922:  \"cesdcdtrn\",\n\t2923:  \"wta-wsp-wtp-s\",\n\t2924:  \"precise-vip\",\n\t2926:  \"mobile-file-dl\",\n\t2927:  \"unimobilectrl\",\n\t2928:  \"redstone-cpss\",\n\t2929:  \"amx-webadmin\",\n\t2930:  \"amx-weblinx\",\n\t2931:  \"circle-x\",\n\t2932:  \"incp\",\n\t2933:  \"4-tieropmgw\",\n\t2934:  \"4-tieropmcli\",\n\t2935:  \"qtp\",\n\t2936:  \"otpatch\",\n\t2937:  \"pnaconsult-lm\",\n\t2938:  \"sm-pas-1\",\n\t2939:  \"sm-pas-2\",\n\t2940:  \"sm-pas-3\",\n\t2941:  \"sm-pas-4\",\n\t2942:  \"sm-pas-5\",\n\t2943:  \"ttnrepository\",\n\t2944:  \"megaco-h248\",\n\t2945:  \"h248-binary\",\n\t2946:  \"fjsvmpor\",\n\t2947:  \"gpsd\",\n\t2948:  \"wap-push\",\n\t2949:  \"wap-pushsecure\",\n\t2950:  \"esip\",\n\t2951:  \"ottp\",\n\t2952:  \"mpfwsas\",\n\t2953:  \"ovalarmsrv\",\n\t2954:  \"ovalarmsrv-cmd\",\n\t2955:  \"csnotify\",\n\t2956:  \"ovrimosdbman\",\n\t2957:  \"jmact5\",\n\t2958:  \"jmact6\",\n\t2959:  \"rmopagt\",\n\t2960:  \"dfoxserver\",\n\t2961:  \"boldsoft-lm\",\n\t2962:  \"iph-policy-cli\",\n\t2963:  \"iph-policy-adm\",\n\t2964:  \"bullant-srap\",\n\t2965:  \"bullant-rap\",\n\t2966:  \"idp-infotrieve\",\n\t2967:  \"ssc-agent\",\n\t2968:  \"enpp\",\n\t2969:  \"essp\",\n\t2970:  \"index-net\",\n\t2971:  \"netclip\",\n\t2972:  \"pmsm-webrctl\",\n\t2973:  \"svnetworks\",\n\t2974:  \"signal\",\n\t2975:  \"fjmpcm\",\n\t2976:  \"cns-srv-port\",\n\t2977:  \"ttc-etap-ns\",\n\t2978:  \"ttc-etap-ds\",\n\t2979:  \"h263-video\",\n\t2980:  \"wimd\",\n\t2981:  \"mylxamport\",\n\t2982:  \"iwb-whiteboard\",\n\t2983:  \"netplan\",\n\t2984:  \"hpidsadmin\",\n\t2985:  \"hpidsagent\",\n\t2986:  \"stonefalls\",\n\t2987:  \"identify\",\n\t2988:  \"hippad\",\n\t2989:  \"zarkov\",\n\t2990:  \"boscap\",\n\t2991:  \"wkstn-mon\",\n\t2992:  \"avenyo\",\n\t2993:  \"veritas-vis1\",\n\t2994:  \"veritas-vis2\",\n\t2995:  \"idrs\",\n\t2996:  \"vsixml\",\n\t2997:  \"rebol\",\n\t2998:  \"realsecure\",\n\t2999:  \"remoteware-un\",\n\t3000:  \"hbci\",\n\t3002:  \"exlm-agent\",\n\t3003:  \"cgms\",\n\t3004:  \"csoftragent\",\n\t3005:  \"geniuslm\",\n\t3006:  \"ii-admin\",\n\t3007:  \"lotusmtap\",\n\t3008:  \"midnight-tech\",\n\t3009:  \"pxc-ntfy\",\n\t3010:  \"ping-pong\",\n\t3011:  \"trusted-web\",\n\t3012:  \"twsdss\",\n\t3013:  \"gilatskysurfer\",\n\t3014:  \"broker-service\",\n\t3015:  \"nati-dstp\",\n\t3016:  \"notify-srvr\",\n\t3017:  \"event-listener\",\n\t3018:  \"srvc-registry\",\n\t3019:  \"resource-mgr\",\n\t3020:  \"cifs\",\n\t3021:  \"agriserver\",\n\t3022:  \"csregagent\",\n\t3023:  \"magicnotes\",\n\t3024:  \"nds-sso\",\n\t3025:  \"arepa-raft\",\n\t3026:  \"agri-gateway\",\n\t3027:  \"LiebDevMgmt-C\",\n\t3028:  \"LiebDevMgmt-DM\",\n\t3029:  \"LiebDevMgmt-A\",\n\t3030:  \"arepa-cas\",\n\t3031:  \"eppc\",\n\t3032:  \"redwood-chat\",\n\t3033:  \"pdb\",\n\t3034:  \"osmosis-aeea\",\n\t3035:  \"fjsv-gssagt\",\n\t3036:  \"hagel-dump\",\n\t3037:  \"hp-san-mgmt\",\n\t3038:  \"santak-ups\",\n\t3039:  \"cogitate\",\n\t3040:  \"tomato-springs\",\n\t3041:  \"di-traceware\",\n\t3042:  \"journee\",\n\t3043:  \"brp\",\n\t3044:  \"epp\",\n\t3045:  \"responsenet\",\n\t3046:  \"di-ase\",\n\t3047:  \"hlserver\",\n\t3048:  \"pctrader\",\n\t3049:  \"nsws\",\n\t3050:  \"gds-db\",\n\t3051:  \"galaxy-server\",\n\t3052:  \"apc-3052\",\n\t3053:  \"dsom-server\",\n\t3054:  \"amt-cnf-prot\",\n\t3055:  \"policyserver\",\n\t3056:  \"cdl-server\",\n\t3057:  \"goahead-fldup\",\n\t3058:  \"videobeans\",\n\t3059:  \"qsoft\",\n\t3060:  \"interserver\",\n\t3061:  \"cautcpd\",\n\t3062:  \"ncacn-ip-tcp\",\n\t3063:  \"ncadg-ip-udp\",\n\t3064:  \"rprt\",\n\t3065:  \"slinterbase\",\n\t3066:  \"netattachsdmp\",\n\t3067:  \"fjhpjp\",\n\t3068:  \"ls3bcast\",\n\t3069:  \"ls3\",\n\t3070:  \"mgxswitch\",\n\t3072:  \"csd-monitor\",\n\t3073:  \"vcrp\",\n\t3074:  \"xbox\",\n\t3075:  \"orbix-locator\",\n\t3076:  \"orbix-config\",\n\t3077:  \"orbix-loc-ssl\",\n\t3078:  \"orbix-cfg-ssl\",\n\t3079:  \"lv-frontpanel\",\n\t3080:  \"stm-pproc\",\n\t3081:  \"tl1-lv\",\n\t3082:  \"tl1-raw\",\n\t3083:  \"tl1-telnet\",\n\t3084:  \"itm-mccs\",\n\t3085:  \"pcihreq\",\n\t3086:  \"jdl-dbkitchen\",\n\t3087:  \"asoki-sma\",\n\t3088:  \"xdtp\",\n\t3089:  \"ptk-alink\",\n\t3090:  \"stss\",\n\t3091:  \"1ci-smcs\",\n\t3093:  \"rapidmq-center\",\n\t3094:  \"rapidmq-reg\",\n\t3095:  \"panasas\",\n\t3096:  \"ndl-aps\",\n\t3098:  \"umm-port\",\n\t3099:  \"chmd\",\n\t3100:  \"opcon-xps\",\n\t3101:  \"hp-pxpib\",\n\t3102:  \"slslavemon\",\n\t3103:  \"autocuesmi\",\n\t3104:  \"autocuetime\",\n\t3105:  \"cardbox\",\n\t3106:  \"cardbox-http\",\n\t3107:  \"business\",\n\t3108:  \"geolocate\",\n\t3109:  \"personnel\",\n\t3110:  \"sim-control\",\n\t3111:  \"wsynch\",\n\t3112:  \"ksysguard\",\n\t3113:  \"cs-auth-svr\",\n\t3114:  \"ccmad\",\n\t3115:  \"mctet-master\",\n\t3116:  \"mctet-gateway\",\n\t3117:  \"mctet-jserv\",\n\t3118:  \"pkagent\",\n\t3119:  \"d2000kernel\",\n\t3120:  \"d2000webserver\",\n\t3122:  \"vtr-emulator\",\n\t3123:  \"edix\",\n\t3124:  \"beacon-port\",\n\t3125:  \"a13-an\",\n\t3127:  \"ctx-bridge\",\n\t3128:  \"ndl-aas\",\n\t3129:  \"netport-id\",\n\t3130:  \"icpv2\",\n\t3131:  \"netbookmark\",\n\t3132:  \"ms-rule-engine\",\n\t3133:  \"prism-deploy\",\n\t3134:  \"ecp\",\n\t3135:  \"peerbook-port\",\n\t3136:  \"grubd\",\n\t3137:  \"rtnt-1\",\n\t3138:  \"rtnt-2\",\n\t3139:  \"incognitorv\",\n\t3140:  \"ariliamulti\",\n\t3141:  \"vmodem\",\n\t3142:  \"rdc-wh-eos\",\n\t3143:  \"seaview\",\n\t3144:  \"tarantella\",\n\t3145:  \"csi-lfap\",\n\t3146:  \"bears-02\",\n\t3147:  \"rfio\",\n\t3148:  \"nm-game-admin\",\n\t3149:  \"nm-game-server\",\n\t3150:  \"nm-asses-admin\",\n\t3151:  \"nm-assessor\",\n\t3152:  \"feitianrockey\",\n\t3153:  \"s8-client-port\",\n\t3154:  \"ccmrmi\",\n\t3155:  \"jpegmpeg\",\n\t3156:  \"indura\",\n\t3157:  \"e3consultants\",\n\t3158:  \"stvp\",\n\t3159:  \"navegaweb-port\",\n\t3160:  \"tip-app-server\",\n\t3161:  \"doc1lm\",\n\t3162:  \"sflm\",\n\t3163:  \"res-sap\",\n\t3164:  \"imprs\",\n\t3165:  \"newgenpay\",\n\t3166:  \"sossecollector\",\n\t3167:  \"nowcontact\",\n\t3168:  \"poweronnud\",\n\t3169:  \"serverview-as\",\n\t3170:  \"serverview-asn\",\n\t3171:  \"serverview-gf\",\n\t3172:  \"serverview-rm\",\n\t3173:  \"serverview-icc\",\n\t3174:  \"armi-server\",\n\t3175:  \"t1-e1-over-ip\",\n\t3176:  \"ars-master\",\n\t3177:  \"phonex-port\",\n\t3178:  \"radclientport\",\n\t3179:  \"h2gf-w-2m\",\n\t3180:  \"mc-brk-srv\",\n\t3181:  \"bmcpatrolagent\",\n\t3182:  \"bmcpatrolrnvu\",\n\t3183:  \"cops-tls\",\n\t3184:  \"apogeex-port\",\n\t3185:  \"smpppd\",\n\t3186:  \"iiw-port\",\n\t3187:  \"odi-port\",\n\t3188:  \"brcm-comm-port\",\n\t3189:  \"pcle-infex\",\n\t3190:  \"csvr-proxy\",\n\t3191:  \"csvr-sslproxy\",\n\t3192:  \"firemonrcc\",\n\t3193:  \"spandataport\",\n\t3194:  \"magbind\",\n\t3195:  \"ncu-1\",\n\t3196:  \"ncu-2\",\n\t3197:  \"embrace-dp-s\",\n\t3198:  \"embrace-dp-c\",\n\t3199:  \"dmod-workspace\",\n\t3200:  \"tick-port\",\n\t3201:  \"cpq-tasksmart\",\n\t3202:  \"intraintra\",\n\t3203:  \"netwatcher-mon\",\n\t3204:  \"netwatcher-db\",\n\t3205:  \"isns\",\n\t3206:  \"ironmail\",\n\t3207:  \"vx-auth-port\",\n\t3208:  \"pfu-prcallback\",\n\t3209:  \"netwkpathengine\",\n\t3210:  \"flamenco-proxy\",\n\t3211:  \"avsecuremgmt\",\n\t3212:  \"surveyinst\",\n\t3213:  \"neon24x7\",\n\t3214:  \"jmq-daemon-1\",\n\t3215:  \"jmq-daemon-2\",\n\t3216:  \"ferrari-foam\",\n\t3217:  \"unite\",\n\t3218:  \"smartpackets\",\n\t3219:  \"wms-messenger\",\n\t3220:  \"xnm-ssl\",\n\t3221:  \"xnm-clear-text\",\n\t3222:  \"glbp\",\n\t3223:  \"digivote\",\n\t3224:  \"aes-discovery\",\n\t3225:  \"fcip-port\",\n\t3226:  \"isi-irp\",\n\t3227:  \"dwnmshttp\",\n\t3228:  \"dwmsgserver\",\n\t3229:  \"global-cd-port\",\n\t3230:  \"sftdst-port\",\n\t3231:  \"vidigo\",\n\t3232:  \"mdtp\",\n\t3233:  \"whisker\",\n\t3234:  \"alchemy\",\n\t3235:  \"mdap-port\",\n\t3236:  \"apparenet-ts\",\n\t3237:  \"apparenet-tps\",\n\t3238:  \"apparenet-as\",\n\t3239:  \"apparenet-ui\",\n\t3240:  \"triomotion\",\n\t3241:  \"sysorb\",\n\t3242:  \"sdp-id-port\",\n\t3243:  \"timelot\",\n\t3244:  \"onesaf\",\n\t3245:  \"vieo-fe\",\n\t3246:  \"dvt-system\",\n\t3247:  \"dvt-data\",\n\t3248:  \"procos-lm\",\n\t3249:  \"ssp\",\n\t3250:  \"hicp\",\n\t3251:  \"sysscanner\",\n\t3252:  \"dhe\",\n\t3253:  \"pda-data\",\n\t3254:  \"pda-sys\",\n\t3255:  \"semaphore\",\n\t3256:  \"cpqrpm-agent\",\n\t3257:  \"cpqrpm-server\",\n\t3258:  \"ivecon-port\",\n\t3259:  \"epncdp2\",\n\t3260:  \"iscsi-target\",\n\t3261:  \"winshadow\",\n\t3262:  \"necp\",\n\t3263:  \"ecolor-imager\",\n\t3264:  \"ccmail\",\n\t3265:  \"altav-tunnel\",\n\t3266:  \"ns-cfg-server\",\n\t3267:  \"ibm-dial-out\",\n\t3268:  \"msft-gc\",\n\t3269:  \"msft-gc-ssl\",\n\t3270:  \"verismart\",\n\t3271:  \"csoft-prev\",\n\t3272:  \"user-manager\",\n\t3273:  \"sxmp\",\n\t3274:  \"ordinox-server\",\n\t3275:  \"samd\",\n\t3276:  \"maxim-asics\",\n\t3277:  \"awg-proxy\",\n\t3278:  \"lkcmserver\",\n\t3279:  \"admind\",\n\t3280:  \"vs-server\",\n\t3281:  \"sysopt\",\n\t3282:  \"datusorb\",\n\t3283:  \"Apple Remote Desktop (Net Assistant)\",\n\t3284:  \"4talk\",\n\t3285:  \"plato\",\n\t3286:  \"e-net\",\n\t3287:  \"directvdata\",\n\t3288:  \"cops\",\n\t3289:  \"enpc\",\n\t3290:  \"caps-lm\",\n\t3291:  \"sah-lm\",\n\t3292:  \"cart-o-rama\",\n\t3293:  \"fg-fps\",\n\t3294:  \"fg-gip\",\n\t3295:  \"dyniplookup\",\n\t3296:  \"rib-slm\",\n\t3297:  \"cytel-lm\",\n\t3298:  \"deskview\",\n\t3299:  \"pdrncs\",\n\t3302:  \"mcs-fastmail\",\n\t3303:  \"opsession-clnt\",\n\t3304:  \"opsession-srvr\",\n\t3305:  \"odette-ftp\",\n\t3306:  \"mysql\",\n\t3307:  \"opsession-prxy\",\n\t3308:  \"tns-server\",\n\t3309:  \"tns-adv\",\n\t3310:  \"dyna-access\",\n\t3311:  \"mcns-tel-ret\",\n\t3312:  \"appman-server\",\n\t3313:  \"uorb\",\n\t3314:  \"uohost\",\n\t3315:  \"cdid\",\n\t3316:  \"aicc-cmi\",\n\t3317:  \"vsaiport\",\n\t3318:  \"ssrip\",\n\t3319:  \"sdt-lmd\",\n\t3320:  \"officelink2000\",\n\t3321:  \"vnsstr\",\n\t3326:  \"sftu\",\n\t3327:  \"bbars\",\n\t3328:  \"egptlm\",\n\t3329:  \"hp-device-disc\",\n\t3330:  \"mcs-calypsoicf\",\n\t3331:  \"mcs-messaging\",\n\t3332:  \"mcs-mailsvr\",\n\t3333:  \"dec-notes\",\n\t3334:  \"directv-web\",\n\t3335:  \"directv-soft\",\n\t3336:  \"directv-tick\",\n\t3337:  \"directv-catlg\",\n\t3338:  \"anet-b\",\n\t3339:  \"anet-l\",\n\t3340:  \"anet-m\",\n\t3341:  \"anet-h\",\n\t3342:  \"webtie\",\n\t3343:  \"ms-cluster-net\",\n\t3344:  \"bnt-manager\",\n\t3345:  \"influence\",\n\t3346:  \"trnsprntproxy\",\n\t3347:  \"phoenix-rpc\",\n\t3348:  \"pangolin-laser\",\n\t3349:  \"chevinservices\",\n\t3350:  \"findviatv\",\n\t3351:  \"btrieve\",\n\t3352:  \"ssql\",\n\t3353:  \"fatpipe\",\n\t3354:  \"suitjd\",\n\t3355:  \"ordinox-dbase\",\n\t3356:  \"upnotifyps\",\n\t3357:  \"adtech-test\",\n\t3358:  \"mpsysrmsvr\",\n\t3359:  \"wg-netforce\",\n\t3360:  \"kv-server\",\n\t3361:  \"kv-agent\",\n\t3362:  \"dj-ilm\",\n\t3363:  \"nati-vi-server\",\n\t3364:  \"creativeserver\",\n\t3365:  \"contentserver\",\n\t3366:  \"creativepartnr\",\n\t3372:  \"tip2\",\n\t3373:  \"lavenir-lm\",\n\t3374:  \"cluster-disc\",\n\t3375:  \"vsnm-agent\",\n\t3376:  \"cdbroker\",\n\t3377:  \"cogsys-lm\",\n\t3378:  \"wsicopy\",\n\t3379:  \"socorfs\",\n\t3380:  \"sns-channels\",\n\t3381:  \"geneous\",\n\t3382:  \"fujitsu-neat\",\n\t3383:  \"esp-lm\",\n\t3384:  \"hp-clic\",\n\t3385:  \"qnxnetman\",\n\t3386:  \"gprs-sig\",\n\t3387:  \"backroomnet\",\n\t3388:  \"cbserver\",\n\t3389:  \"ms-wbt-server\",\n\t3390:  \"dsc\",\n\t3391:  \"savant\",\n\t3392:  \"efi-lm\",\n\t3393:  \"d2k-tapestry1\",\n\t3394:  \"d2k-tapestry2\",\n\t3395:  \"dyna-lm\",\n\t3396:  \"printer-agent\",\n\t3397:  \"cloanto-lm\",\n\t3398:  \"mercantile\",\n\t3399:  \"csms\",\n\t3400:  \"csms2\",\n\t3401:  \"filecast\",\n\t3402:  \"fxaengine-net\",\n\t3405:  \"nokia-ann-ch1\",\n\t3406:  \"nokia-ann-ch2\",\n\t3407:  \"ldap-admin\",\n\t3408:  \"BESApi\",\n\t3409:  \"networklens\",\n\t3410:  \"networklenss\",\n\t3411:  \"biolink-auth\",\n\t3412:  \"xmlblaster\",\n\t3413:  \"svnet\",\n\t3414:  \"wip-port\",\n\t3415:  \"bcinameservice\",\n\t3416:  \"commandport\",\n\t3417:  \"csvr\",\n\t3418:  \"rnmap\",\n\t3419:  \"softaudit\",\n\t3420:  \"ifcp-port\",\n\t3421:  \"bmap\",\n\t3422:  \"rusb-sys-port\",\n\t3423:  \"xtrm\",\n\t3424:  \"xtrms\",\n\t3425:  \"agps-port\",\n\t3426:  \"arkivio\",\n\t3427:  \"websphere-snmp\",\n\t3428:  \"twcss\",\n\t3429:  \"gcsp\",\n\t3430:  \"ssdispatch\",\n\t3431:  \"ndl-als\",\n\t3432:  \"osdcp\",\n\t3433:  \"opnet-smp\",\n\t3434:  \"opencm\",\n\t3435:  \"pacom\",\n\t3436:  \"gc-config\",\n\t3437:  \"autocueds\",\n\t3438:  \"spiral-admin\",\n\t3439:  \"hri-port\",\n\t3440:  \"ans-console\",\n\t3441:  \"connect-client\",\n\t3442:  \"connect-server\",\n\t3443:  \"ov-nnm-websrv\",\n\t3444:  \"denali-server\",\n\t3445:  \"monp\",\n\t3446:  \"3comfaxrpc\",\n\t3447:  \"directnet\",\n\t3448:  \"dnc-port\",\n\t3449:  \"hotu-chat\",\n\t3450:  \"castorproxy\",\n\t3451:  \"asam\",\n\t3452:  \"sabp-signal\",\n\t3453:  \"pscupd\",\n\t3454:  \"mira\",\n\t3455:  \"prsvp\",\n\t3456:  \"vat\",\n\t3457:  \"vat-control\",\n\t3458:  \"d3winosfi\",\n\t3459:  \"integral\",\n\t3460:  \"edm-manager\",\n\t3461:  \"edm-stager\",\n\t3462:  \"edm-std-notify\",\n\t3463:  \"edm-adm-notify\",\n\t3464:  \"edm-mgr-sync\",\n\t3465:  \"edm-mgr-cntrl\",\n\t3466:  \"workflow\",\n\t3467:  \"rcst\",\n\t3468:  \"ttcmremotectrl\",\n\t3469:  \"pluribus\",\n\t3470:  \"jt400\",\n\t3471:  \"jt400-ssl\",\n\t3472:  \"jaugsremotec-1\",\n\t3473:  \"jaugsremotec-2\",\n\t3474:  \"ttntspauto\",\n\t3475:  \"genisar-port\",\n\t3476:  \"nppmp\",\n\t3477:  \"ecomm\",\n\t3478:  \"stun\",\n\t3479:  \"twrpc\",\n\t3480:  \"plethora\",\n\t3481:  \"cleanerliverc\",\n\t3482:  \"vulture\",\n\t3483:  \"slim-devices\",\n\t3484:  \"gbs-stp\",\n\t3485:  \"celatalk\",\n\t3486:  \"ifsf-hb-port\",\n\t3487:  \"ltcudp\",\n\t3488:  \"fs-rh-srv\",\n\t3489:  \"dtp-dia\",\n\t3490:  \"colubris\",\n\t3491:  \"swr-port\",\n\t3492:  \"tvdumtray-port\",\n\t3493:  \"nut\",\n\t3494:  \"ibm3494\",\n\t3495:  \"seclayer-tcp\",\n\t3496:  \"seclayer-tls\",\n\t3497:  \"ipether232port\",\n\t3498:  \"dashpas-port\",\n\t3499:  \"sccip-media\",\n\t3500:  \"rtmp-port\",\n\t3501:  \"isoft-p2p\",\n\t3502:  \"avinstalldisc\",\n\t3503:  \"lsp-ping\",\n\t3504:  \"ironstorm\",\n\t3505:  \"ccmcomm\",\n\t3506:  \"apc-3506\",\n\t3507:  \"nesh-broker\",\n\t3508:  \"interactionweb\",\n\t3509:  \"vt-ssl\",\n\t3510:  \"xss-port\",\n\t3511:  \"webmail-2\",\n\t3512:  \"aztec\",\n\t3513:  \"arcpd\",\n\t3514:  \"must-p2p\",\n\t3515:  \"must-backplane\",\n\t3516:  \"smartcard-port\",\n\t3517:  \"802-11-iapp\",\n\t3518:  \"artifact-msg\",\n\t3519:  \"galileo\",\n\t3520:  \"galileolog\",\n\t3521:  \"mc3ss\",\n\t3522:  \"nssocketport\",\n\t3523:  \"odeumservlink\",\n\t3524:  \"ecmport\",\n\t3525:  \"eisport\",\n\t3526:  \"starquiz-port\",\n\t3527:  \"beserver-msg-q\",\n\t3528:  \"jboss-iiop\",\n\t3529:  \"jboss-iiop-ssl\",\n\t3530:  \"gf\",\n\t3531:  \"joltid\",\n\t3532:  \"raven-rmp\",\n\t3533:  \"raven-rdp\",\n\t3534:  \"urld-port\",\n\t3535:  \"ms-la\",\n\t3536:  \"snac\",\n\t3537:  \"ni-visa-remote\",\n\t3538:  \"ibm-diradm\",\n\t3539:  \"ibm-diradm-ssl\",\n\t3540:  \"pnrp-port\",\n\t3541:  \"voispeed-port\",\n\t3542:  \"hacl-monitor\",\n\t3543:  \"qftest-lookup\",\n\t3544:  \"teredo\",\n\t3545:  \"camac\",\n\t3547:  \"symantec-sim\",\n\t3548:  \"interworld\",\n\t3549:  \"tellumat-nms\",\n\t3550:  \"ssmpp\",\n\t3551:  \"apcupsd\",\n\t3552:  \"taserver\",\n\t3553:  \"rbr-discovery\",\n\t3554:  \"questnotify\",\n\t3555:  \"razor\",\n\t3556:  \"sky-transport\",\n\t3557:  \"personalos-001\",\n\t3558:  \"mcp-port\",\n\t3559:  \"cctv-port\",\n\t3560:  \"iniserve-port\",\n\t3561:  \"bmc-onekey\",\n\t3562:  \"sdbproxy\",\n\t3563:  \"watcomdebug\",\n\t3564:  \"esimport\",\n\t3567:  \"dof-eps\",\n\t3568:  \"dof-tunnel-sec\",\n\t3569:  \"mbg-ctrl\",\n\t3570:  \"mccwebsvr-port\",\n\t3571:  \"megardsvr-port\",\n\t3572:  \"megaregsvrport\",\n\t3573:  \"tag-ups-1\",\n\t3574:  \"dmaf-caster\",\n\t3575:  \"ccm-port\",\n\t3576:  \"cmc-port\",\n\t3577:  \"config-port\",\n\t3578:  \"data-port\",\n\t3579:  \"ttat3lb\",\n\t3580:  \"nati-svrloc\",\n\t3581:  \"kfxaclicensing\",\n\t3582:  \"press\",\n\t3583:  \"canex-watch\",\n\t3584:  \"u-dbap\",\n\t3585:  \"emprise-lls\",\n\t3586:  \"emprise-lsc\",\n\t3587:  \"p2pgroup\",\n\t3588:  \"sentinel\",\n\t3589:  \"isomair\",\n\t3590:  \"wv-csp-sms\",\n\t3591:  \"gtrack-server\",\n\t3592:  \"gtrack-ne\",\n\t3593:  \"bpmd\",\n\t3594:  \"mediaspace\",\n\t3595:  \"shareapp\",\n\t3596:  \"iw-mmogame\",\n\t3597:  \"a14\",\n\t3598:  \"a15\",\n\t3599:  \"quasar-server\",\n\t3600:  \"trap-daemon\",\n\t3601:  \"visinet-gui\",\n\t3602:  \"infiniswitchcl\",\n\t3603:  \"int-rcv-cntrl\",\n\t3604:  \"bmc-jmx-port\",\n\t3605:  \"comcam-io\",\n\t3606:  \"splitlock\",\n\t3607:  \"precise-i3\",\n\t3608:  \"trendchip-dcp\",\n\t3609:  \"cpdi-pidas-cm\",\n\t3610:  \"echonet\",\n\t3611:  \"six-degrees\",\n\t3612:  \"hp-dataprotect\",\n\t3613:  \"alaris-disc\",\n\t3614:  \"sigma-port\",\n\t3615:  \"start-network\",\n\t3616:  \"cd3o-protocol\",\n\t3617:  \"sharp-server\",\n\t3618:  \"aairnet-1\",\n\t3619:  \"aairnet-2\",\n\t3620:  \"ep-pcp\",\n\t3621:  \"ep-nsp\",\n\t3622:  \"ff-lr-port\",\n\t3623:  \"haipe-discover\",\n\t3624:  \"dist-upgrade\",\n\t3625:  \"volley\",\n\t3626:  \"bvcdaemon-port\",\n\t3627:  \"jamserverport\",\n\t3628:  \"ept-machine\",\n\t3629:  \"escvpnet\",\n\t3630:  \"cs-remote-db\",\n\t3631:  \"cs-services\",\n\t3632:  \"distcc\",\n\t3633:  \"wacp\",\n\t3634:  \"hlibmgr\",\n\t3635:  \"sdo\",\n\t3636:  \"servistaitsm\",\n\t3637:  \"scservp\",\n\t3638:  \"ehp-backup\",\n\t3639:  \"xap-ha\",\n\t3640:  \"netplay-port1\",\n\t3641:  \"netplay-port2\",\n\t3642:  \"juxml-port\",\n\t3643:  \"audiojuggler\",\n\t3644:  \"ssowatch\",\n\t3645:  \"cyc\",\n\t3646:  \"xss-srv-port\",\n\t3647:  \"splitlock-gw\",\n\t3648:  \"fjcp\",\n\t3649:  \"nmmp\",\n\t3650:  \"prismiq-plugin\",\n\t3651:  \"xrpc-registry\",\n\t3652:  \"vxcrnbuport\",\n\t3653:  \"tsp\",\n\t3654:  \"vaprtm\",\n\t3655:  \"abatemgr\",\n\t3656:  \"abatjss\",\n\t3657:  \"immedianet-bcn\",\n\t3658:  \"ps-ams\",\n\t3659:  \"apple-sasl\",\n\t3660:  \"can-nds-ssl\",\n\t3661:  \"can-ferret-ssl\",\n\t3662:  \"pserver\",\n\t3663:  \"dtp\",\n\t3664:  \"ups-engine\",\n\t3665:  \"ent-engine\",\n\t3666:  \"eserver-pap\",\n\t3667:  \"infoexch\",\n\t3668:  \"dell-rm-port\",\n\t3669:  \"casanswmgmt\",\n\t3670:  \"smile\",\n\t3671:  \"efcp\",\n\t3672:  \"lispworks-orb\",\n\t3673:  \"mediavault-gui\",\n\t3674:  \"wininstall-ipc\",\n\t3675:  \"calltrax\",\n\t3676:  \"va-pacbase\",\n\t3677:  \"roverlog\",\n\t3678:  \"ipr-dglt\",\n\t3679:  \"Escale (Newton Dock)\",\n\t3680:  \"npds-tracker\",\n\t3681:  \"bts-x73\",\n\t3682:  \"cas-mapi\",\n\t3683:  \"bmc-ea\",\n\t3684:  \"faxstfx-port\",\n\t3685:  \"dsx-agent\",\n\t3686:  \"tnmpv2\",\n\t3687:  \"simple-push\",\n\t3688:  \"simple-push-s\",\n\t3689:  \"daap\",\n\t3690:  \"svn\",\n\t3691:  \"magaya-network\",\n\t3692:  \"intelsync\",\n\t3695:  \"bmc-data-coll\",\n\t3696:  \"telnetcpcd\",\n\t3697:  \"nw-license\",\n\t3698:  \"sagectlpanel\",\n\t3699:  \"kpn-icw\",\n\t3700:  \"lrs-paging\",\n\t3701:  \"netcelera\",\n\t3702:  \"ws-discovery\",\n\t3703:  \"adobeserver-3\",\n\t3704:  \"adobeserver-4\",\n\t3705:  \"adobeserver-5\",\n\t3706:  \"rt-event\",\n\t3707:  \"rt-event-s\",\n\t3708:  \"sun-as-iiops\",\n\t3709:  \"ca-idms\",\n\t3710:  \"portgate-auth\",\n\t3711:  \"edb-server2\",\n\t3712:  \"sentinel-ent\",\n\t3713:  \"tftps\",\n\t3714:  \"delos-dms\",\n\t3715:  \"anoto-rendezv\",\n\t3716:  \"wv-csp-sms-cir\",\n\t3717:  \"wv-csp-udp-cir\",\n\t3718:  \"opus-services\",\n\t3719:  \"itelserverport\",\n\t3720:  \"ufastro-instr\",\n\t3721:  \"xsync\",\n\t3722:  \"xserveraid\",\n\t3723:  \"sychrond\",\n\t3724:  \"blizwow\",\n\t3725:  \"na-er-tip\",\n\t3726:  \"array-manager\",\n\t3727:  \"e-mdu\",\n\t3728:  \"e-woa\",\n\t3729:  \"fksp-audit\",\n\t3730:  \"client-ctrl\",\n\t3731:  \"smap\",\n\t3732:  \"m-wnn\",\n\t3733:  \"multip-msg\",\n\t3734:  \"synel-data\",\n\t3735:  \"pwdis\",\n\t3736:  \"rs-rmi\",\n\t3738:  \"versatalk\",\n\t3739:  \"launchbird-lm\",\n\t3740:  \"heartbeat\",\n\t3741:  \"wysdma\",\n\t3742:  \"cst-port\",\n\t3743:  \"ipcs-command\",\n\t3744:  \"sasg\",\n\t3745:  \"gw-call-port\",\n\t3746:  \"linktest\",\n\t3747:  \"linktest-s\",\n\t3748:  \"webdata\",\n\t3749:  \"cimtrak\",\n\t3750:  \"cbos-ip-port\",\n\t3751:  \"gprs-cube\",\n\t3752:  \"vipremoteagent\",\n\t3753:  \"nattyserver\",\n\t3754:  \"timestenbroker\",\n\t3755:  \"sas-remote-hlp\",\n\t3756:  \"canon-capt\",\n\t3757:  \"grf-port\",\n\t3758:  \"apw-registry\",\n\t3759:  \"exapt-lmgr\",\n\t3760:  \"adtempusclient\",\n\t3761:  \"gsakmp\",\n\t3762:  \"gbs-smp\",\n\t3763:  \"xo-wave\",\n\t3764:  \"mni-prot-rout\",\n\t3765:  \"rtraceroute\",\n\t3767:  \"listmgr-port\",\n\t3768:  \"rblcheckd\",\n\t3769:  \"haipe-otnk\",\n\t3770:  \"cindycollab\",\n\t3771:  \"paging-port\",\n\t3772:  \"ctp\",\n\t3773:  \"ctdhercules\",\n\t3774:  \"zicom\",\n\t3775:  \"ispmmgr\",\n\t3776:  \"dvcprov-port\",\n\t3777:  \"jibe-eb\",\n\t3778:  \"c-h-it-port\",\n\t3779:  \"cognima\",\n\t3780:  \"nnp\",\n\t3781:  \"abcvoice-port\",\n\t3782:  \"iso-tp0s\",\n\t3783:  \"bim-pem\",\n\t3784:  \"bfd-control\",\n\t3785:  \"bfd-echo\",\n\t3786:  \"upstriggervsw\",\n\t3787:  \"fintrx\",\n\t3788:  \"isrp-port\",\n\t3789:  \"remotedeploy\",\n\t3790:  \"quickbooksrds\",\n\t3791:  \"tvnetworkvideo\",\n\t3792:  \"sitewatch\",\n\t3793:  \"dcsoftware\",\n\t3794:  \"jaus\",\n\t3795:  \"myblast\",\n\t3796:  \"spw-dialer\",\n\t3797:  \"idps\",\n\t3798:  \"minilock\",\n\t3799:  \"radius-dynauth\",\n\t3800:  \"pwgpsi\",\n\t3801:  \"ibm-mgr\",\n\t3802:  \"vhd\",\n\t3803:  \"soniqsync\",\n\t3804:  \"iqnet-port\",\n\t3805:  \"tcpdataserver\",\n\t3806:  \"wsmlb\",\n\t3807:  \"spugna\",\n\t3808:  \"sun-as-iiops-ca\",\n\t3809:  \"apocd\",\n\t3810:  \"wlanauth\",\n\t3811:  \"amp\",\n\t3812:  \"neto-wol-server\",\n\t3813:  \"rap-ip\",\n\t3814:  \"neto-dcs\",\n\t3815:  \"lansurveyorxml\",\n\t3816:  \"sunlps-http\",\n\t3817:  \"tapeware\",\n\t3818:  \"crinis-hb\",\n\t3819:  \"epl-slp\",\n\t3820:  \"scp\",\n\t3821:  \"pmcp\",\n\t3822:  \"acp-discovery\",\n\t3823:  \"acp-conduit\",\n\t3824:  \"acp-policy\",\n\t3825:  \"ffserver\",\n\t3826:  \"warmux\",\n\t3827:  \"netmpi\",\n\t3828:  \"neteh\",\n\t3829:  \"neteh-ext\",\n\t3830:  \"cernsysmgmtagt\",\n\t3831:  \"dvapps\",\n\t3832:  \"xxnetserver\",\n\t3833:  \"aipn-auth\",\n\t3834:  \"spectardata\",\n\t3835:  \"spectardb\",\n\t3836:  \"markem-dcp\",\n\t3837:  \"mkm-discovery\",\n\t3838:  \"sos\",\n\t3839:  \"amx-rms\",\n\t3840:  \"flirtmitmir\",\n\t3842:  \"nhci\",\n\t3843:  \"quest-agent\",\n\t3844:  \"rnm\",\n\t3845:  \"v-one-spp\",\n\t3846:  \"an-pcp\",\n\t3847:  \"msfw-control\",\n\t3848:  \"item\",\n\t3849:  \"spw-dnspreload\",\n\t3850:  \"qtms-bootstrap\",\n\t3851:  \"spectraport\",\n\t3852:  \"sse-app-config\",\n\t3853:  \"sscan\",\n\t3854:  \"stryker-com\",\n\t3855:  \"opentrac\",\n\t3856:  \"informer\",\n\t3857:  \"trap-port\",\n\t3858:  \"trap-port-mom\",\n\t3859:  \"nav-port\",\n\t3860:  \"sasp\",\n\t3861:  \"winshadow-hd\",\n\t3862:  \"giga-pocket\",\n\t3863:  \"asap-udp\",\n\t3865:  \"xpl\",\n\t3866:  \"dzdaemon\",\n\t3867:  \"dzoglserver\",\n\t3869:  \"ovsam-mgmt\",\n\t3870:  \"ovsam-d-agent\",\n\t3871:  \"avocent-adsap\",\n\t3872:  \"oem-agent\",\n\t3873:  \"fagordnc\",\n\t3874:  \"sixxsconfig\",\n\t3875:  \"pnbscada\",\n\t3876:  \"dl-agent\",\n\t3877:  \"xmpcr-interface\",\n\t3878:  \"fotogcad\",\n\t3879:  \"appss-lm\",\n\t3880:  \"igrs\",\n\t3881:  \"idac\",\n\t3882:  \"msdts1\",\n\t3883:  \"vrpn\",\n\t3884:  \"softrack-meter\",\n\t3885:  \"topflow-ssl\",\n\t3886:  \"nei-management\",\n\t3887:  \"ciphire-data\",\n\t3888:  \"ciphire-serv\",\n\t3889:  \"dandv-tester\",\n\t3890:  \"ndsconnect\",\n\t3891:  \"rtc-pm-port\",\n\t3892:  \"pcc-image-port\",\n\t3893:  \"cgi-starapi\",\n\t3894:  \"syam-agent\",\n\t3895:  \"syam-smc\",\n\t3896:  \"sdo-tls\",\n\t3897:  \"sdo-ssh\",\n\t3898:  \"senip\",\n\t3899:  \"itv-control\",\n\t3900:  \"udt-os\",\n\t3901:  \"nimsh\",\n\t3902:  \"nimaux\",\n\t3903:  \"charsetmgr\",\n\t3904:  \"omnilink-port\",\n\t3905:  \"mupdate\",\n\t3906:  \"topovista-data\",\n\t3907:  \"imoguia-port\",\n\t3908:  \"hppronetman\",\n\t3909:  \"surfcontrolcpa\",\n\t3910:  \"prnrequest\",\n\t3911:  \"prnstatus\",\n\t3912:  \"gbmt-stars\",\n\t3913:  \"listcrt-port\",\n\t3914:  \"listcrt-port-2\",\n\t3915:  \"agcat\",\n\t3916:  \"wysdmc\",\n\t3917:  \"aftmux\",\n\t3918:  \"pktcablemmcops\",\n\t3919:  \"hyperip\",\n\t3920:  \"exasoftport1\",\n\t3921:  \"herodotus-net\",\n\t3922:  \"sor-update\",\n\t3923:  \"symb-sb-port\",\n\t3924:  \"mpl-gprs-port\",\n\t3925:  \"zmp\",\n\t3926:  \"winport\",\n\t3927:  \"natdataservice\",\n\t3928:  \"netboot-pxe\",\n\t3929:  \"smauth-port\",\n\t3930:  \"syam-webserver\",\n\t3931:  \"msr-plugin-port\",\n\t3932:  \"dyn-site\",\n\t3933:  \"plbserve-port\",\n\t3934:  \"sunfm-port\",\n\t3935:  \"sdp-portmapper\",\n\t3936:  \"mailprox\",\n\t3937:  \"dvbservdsc\",\n\t3938:  \"dbcontrol-agent\",\n\t3939:  \"aamp\",\n\t3940:  \"xecp-node\",\n\t3941:  \"homeportal-web\",\n\t3942:  \"srdp\",\n\t3943:  \"tig\",\n\t3944:  \"sops\",\n\t3945:  \"emcads\",\n\t3946:  \"backupedge\",\n\t3947:  \"ccp\",\n\t3948:  \"apdap\",\n\t3949:  \"drip\",\n\t3950:  \"namemunge\",\n\t3951:  \"pwgippfax\",\n\t3952:  \"i3-sessionmgr\",\n\t3953:  \"xmlink-connect\",\n\t3954:  \"adrep\",\n\t3955:  \"p2pcommunity\",\n\t3956:  \"gvcp\",\n\t3957:  \"mqe-broker\",\n\t3958:  \"mqe-agent\",\n\t3959:  \"treehopper\",\n\t3960:  \"bess\",\n\t3961:  \"proaxess\",\n\t3962:  \"sbi-agent\",\n\t3963:  \"thrp\",\n\t3964:  \"sasggprs\",\n\t3965:  \"ati-ip-to-ncpe\",\n\t3966:  \"bflckmgr\",\n\t3967:  \"ppsms\",\n\t3968:  \"ianywhere-dbns\",\n\t3969:  \"landmarks\",\n\t3970:  \"lanrevagent\",\n\t3971:  \"lanrevserver\",\n\t3972:  \"iconp\",\n\t3973:  \"progistics\",\n\t3974:  \"citysearch\",\n\t3975:  \"airshot\",\n\t3976:  \"opswagent\",\n\t3977:  \"opswmanager\",\n\t3978:  \"secure-cfg-svr\",\n\t3979:  \"smwan\",\n\t3980:  \"acms\",\n\t3981:  \"starfish\",\n\t3982:  \"eis\",\n\t3983:  \"eisp\",\n\t3984:  \"mapper-nodemgr\",\n\t3985:  \"mapper-mapethd\",\n\t3986:  \"mapper-ws-ethd\",\n\t3987:  \"centerline\",\n\t3988:  \"dcs-config\",\n\t3989:  \"bv-queryengine\",\n\t3990:  \"bv-is\",\n\t3991:  \"bv-smcsrv\",\n\t3992:  \"bv-ds\",\n\t3993:  \"bv-agent\",\n\t3995:  \"iss-mgmt-ssl\",\n\t3996:  \"abcsoftware\",\n\t3997:  \"agentsease-db\",\n\t3998:  \"dnx\",\n\t3999:  \"nvcnet\",\n\t4000:  \"terabase\",\n\t4001:  \"newoak\",\n\t4002:  \"pxc-spvr-ft\",\n\t4003:  \"pxc-splr-ft\",\n\t4004:  \"pxc-roid\",\n\t4005:  \"pxc-pin\",\n\t4006:  \"pxc-spvr\",\n\t4007:  \"pxc-splr\",\n\t4008:  \"netcheque\",\n\t4009:  \"chimera-hwm\",\n\t4010:  \"samsung-unidex\",\n\t4011:  \"altserviceboot\",\n\t4012:  \"pda-gate\",\n\t4013:  \"acl-manager\",\n\t4014:  \"taiclock\",\n\t4015:  \"talarian-mcast1\",\n\t4016:  \"talarian-mcast2\",\n\t4017:  \"talarian-mcast3\",\n\t4018:  \"talarian-mcast4\",\n\t4019:  \"talarian-mcast5\",\n\t4020:  \"trap\",\n\t4021:  \"nexus-portal\",\n\t4022:  \"dnox\",\n\t4023:  \"esnm-zoning\",\n\t4024:  \"tnp1-port\",\n\t4025:  \"partimage\",\n\t4026:  \"as-debug\",\n\t4027:  \"bxp\",\n\t4028:  \"dtserver-port\",\n\t4029:  \"ip-qsig\",\n\t4030:  \"jdmn-port\",\n\t4031:  \"suucp\",\n\t4032:  \"vrts-auth-port\",\n\t4033:  \"sanavigator\",\n\t4034:  \"ubxd\",\n\t4035:  \"wap-push-http\",\n\t4036:  \"wap-push-https\",\n\t4037:  \"ravehd\",\n\t4038:  \"fazzt-ptp\",\n\t4039:  \"fazzt-admin\",\n\t4040:  \"yo-main\",\n\t4041:  \"houston\",\n\t4042:  \"ldxp\",\n\t4043:  \"nirp\",\n\t4044:  \"ltp\",\n\t4045:  \"npp\",\n\t4046:  \"acp-proto\",\n\t4047:  \"ctp-state\",\n\t4049:  \"wafs\",\n\t4050:  \"cisco-wafs\",\n\t4051:  \"cppdp\",\n\t4052:  \"interact\",\n\t4053:  \"ccu-comm-1\",\n\t4054:  \"ccu-comm-2\",\n\t4055:  \"ccu-comm-3\",\n\t4056:  \"lms\",\n\t4057:  \"wfm\",\n\t4058:  \"kingfisher\",\n\t4059:  \"dlms-cosem\",\n\t4060:  \"dsmeter-iatc\",\n\t4061:  \"ice-location\",\n\t4062:  \"ice-slocation\",\n\t4063:  \"ice-router\",\n\t4064:  \"ice-srouter\",\n\t4065:  \"avanti-cdp\",\n\t4066:  \"pmas\",\n\t4067:  \"idp\",\n\t4068:  \"ipfltbcst\",\n\t4069:  \"minger\",\n\t4070:  \"tripe\",\n\t4071:  \"aibkup\",\n\t4072:  \"zieto-sock\",\n\t4073:  \"iRAPP\",\n\t4074:  \"cequint-cityid\",\n\t4075:  \"perimlan\",\n\t4076:  \"seraph\",\n\t4077:  \"ascomalarm\",\n\t4079:  \"santools\",\n\t4080:  \"lorica-in\",\n\t4081:  \"lorica-in-sec\",\n\t4082:  \"lorica-out\",\n\t4083:  \"lorica-out-sec\",\n\t4084:  \"fortisphere-vm\",\n\t4086:  \"ftsync\",\n\t4089:  \"opencore\",\n\t4090:  \"omasgport\",\n\t4091:  \"ewinstaller\",\n\t4092:  \"ewdgs\",\n\t4093:  \"pvxpluscs\",\n\t4094:  \"sysrqd\",\n\t4095:  \"xtgui\",\n\t4096:  \"bre\",\n\t4097:  \"patrolview\",\n\t4098:  \"drmsfsd\",\n\t4099:  \"dpcp\",\n\t4100:  \"igo-incognito\",\n\t4101:  \"brlp-0\",\n\t4102:  \"brlp-1\",\n\t4103:  \"brlp-2\",\n\t4104:  \"brlp-3\",\n\t4105:  \"shofar\",\n\t4106:  \"synchronite\",\n\t4107:  \"j-ac\",\n\t4108:  \"accel\",\n\t4109:  \"izm\",\n\t4110:  \"g2tag\",\n\t4111:  \"xgrid\",\n\t4112:  \"apple-vpns-rp\",\n\t4113:  \"aipn-reg\",\n\t4114:  \"jomamqmonitor\",\n\t4115:  \"cds\",\n\t4116:  \"smartcard-tls\",\n\t4117:  \"hillrserv\",\n\t4118:  \"netscript\",\n\t4119:  \"assuria-slm\",\n\t4121:  \"e-builder\",\n\t4122:  \"fprams\",\n\t4123:  \"z-wave\",\n\t4124:  \"tigv2\",\n\t4125:  \"opsview-envoy\",\n\t4126:  \"ddrepl\",\n\t4127:  \"unikeypro\",\n\t4128:  \"nufw\",\n\t4129:  \"nuauth\",\n\t4130:  \"fronet\",\n\t4131:  \"stars\",\n\t4132:  \"nuts-dem\",\n\t4133:  \"nuts-bootp\",\n\t4134:  \"nifty-hmi\",\n\t4135:  \"cl-db-attach\",\n\t4136:  \"cl-db-request\",\n\t4137:  \"cl-db-remote\",\n\t4138:  \"nettest\",\n\t4139:  \"thrtx\",\n\t4140:  \"cedros-fds\",\n\t4141:  \"oirtgsvc\",\n\t4142:  \"oidocsvc\",\n\t4143:  \"oidsr\",\n\t4145:  \"vvr-control\",\n\t4146:  \"tgcconnect\",\n\t4147:  \"vrxpservman\",\n\t4148:  \"hhb-handheld\",\n\t4149:  \"agslb\",\n\t4150:  \"PowerAlert-nsa\",\n\t4151:  \"menandmice-noh\",\n\t4152:  \"idig-mux\",\n\t4153:  \"mbl-battd\",\n\t4154:  \"atlinks\",\n\t4155:  \"bzr\",\n\t4156:  \"stat-results\",\n\t4157:  \"stat-scanner\",\n\t4158:  \"stat-cc\",\n\t4159:  \"nss\",\n\t4160:  \"jini-discovery\",\n\t4161:  \"omscontact\",\n\t4162:  \"omstopology\",\n\t4163:  \"silverpeakpeer\",\n\t4164:  \"silverpeakcomm\",\n\t4165:  \"altcp\",\n\t4166:  \"joost\",\n\t4167:  \"ddgn\",\n\t4168:  \"pslicser\",\n\t4169:  \"iadt-disc\",\n\t4172:  \"pcoip\",\n\t4173:  \"mma-discovery\",\n\t4174:  \"sm-disc\",\n\t4177:  \"wello\",\n\t4178:  \"storman\",\n\t4179:  \"MaxumSP\",\n\t4180:  \"httpx\",\n\t4181:  \"macbak\",\n\t4182:  \"pcptcpservice\",\n\t4183:  \"cyborgnet\",\n\t4184:  \"universe-suite\",\n\t4185:  \"wcpp\",\n\t4188:  \"vatata\",\n\t4191:  \"dsmipv6\",\n\t4192:  \"azeti-bd\",\n\t4197:  \"hctl\",\n\t4199:  \"eims-admin\",\n\t4300:  \"corelccam\",\n\t4301:  \"d-data\",\n\t4302:  \"d-data-control\",\n\t4303:  \"srcp\",\n\t4304:  \"owserver\",\n\t4305:  \"batman\",\n\t4306:  \"pinghgl\",\n\t4307:  \"trueconf\",\n\t4308:  \"compx-lockview\",\n\t4309:  \"dserver\",\n\t4310:  \"mirrtex\",\n\t4320:  \"fdt-rcatp\",\n\t4321:  \"rwhois\",\n\t4322:  \"trim-event\",\n\t4323:  \"trim-ice\",\n\t4325:  \"geognosisman\",\n\t4326:  \"geognosis\",\n\t4327:  \"jaxer-web\",\n\t4328:  \"jaxer-manager\",\n\t4333:  \"ahsp\",\n\t4340:  \"gaia\",\n\t4341:  \"lisp-data\",\n\t4342:  \"lisp-control\",\n\t4343:  \"unicall\",\n\t4344:  \"vinainstall\",\n\t4345:  \"m4-network-as\",\n\t4346:  \"elanlm\",\n\t4347:  \"lansurveyor\",\n\t4348:  \"itose\",\n\t4349:  \"fsportmap\",\n\t4350:  \"net-device\",\n\t4351:  \"plcy-net-svcs\",\n\t4352:  \"pjlink\",\n\t4353:  \"f5-iquery\",\n\t4354:  \"qsnet-trans\",\n\t4355:  \"qsnet-workst\",\n\t4356:  \"qsnet-assist\",\n\t4357:  \"qsnet-cond\",\n\t4358:  \"qsnet-nucl\",\n\t4359:  \"omabcastltkm\",\n\t4361:  \"nacnl\",\n\t4362:  \"afore-vdp-disc\",\n\t4366:  \"shadowstream\",\n\t4368:  \"wxbrief\",\n\t4369:  \"epmd\",\n\t4370:  \"elpro-tunnel\",\n\t4371:  \"l2c-disc\",\n\t4372:  \"l2c-data\",\n\t4373:  \"remctl\",\n\t4375:  \"tolteces\",\n\t4376:  \"bip\",\n\t4377:  \"cp-spxsvr\",\n\t4378:  \"cp-spxdpy\",\n\t4379:  \"ctdb\",\n\t4389:  \"xandros-cms\",\n\t4390:  \"wiegand\",\n\t4394:  \"apwi-disc\",\n\t4395:  \"omnivisionesx\",\n\t4400:  \"ds-srv\",\n\t4401:  \"ds-srvr\",\n\t4402:  \"ds-clnt\",\n\t4403:  \"ds-user\",\n\t4404:  \"ds-admin\",\n\t4405:  \"ds-mail\",\n\t4406:  \"ds-slp\",\n\t4412:  \"smallchat\",\n\t4413:  \"avi-nms-disc\",\n\t4416:  \"pjj-player-disc\",\n\t4418:  \"axysbridge\",\n\t4420:  \"nvm-express\",\n\t4425:  \"netrockey6\",\n\t4426:  \"beacon-port-2\",\n\t4430:  \"rsqlserver\",\n\t4432:  \"l-acoustics\",\n\t4441:  \"netblox\",\n\t4442:  \"saris\",\n\t4443:  \"pharos\",\n\t4444:  \"krb524\",\n\t4445:  \"upnotifyp\",\n\t4446:  \"n1-fwp\",\n\t4447:  \"n1-rmgmt\",\n\t4448:  \"asc-slmd\",\n\t4449:  \"privatewire\",\n\t4450:  \"camp\",\n\t4451:  \"ctisystemmsg\",\n\t4452:  \"ctiprogramload\",\n\t4453:  \"nssalertmgr\",\n\t4454:  \"nssagentmgr\",\n\t4455:  \"prchat-user\",\n\t4456:  \"prchat-server\",\n\t4457:  \"prRegister\",\n\t4458:  \"mcp\",\n\t4484:  \"hpssmgmt\",\n\t4486:  \"icms\",\n\t4488:  \"awacs-ice\",\n\t4500:  \"ipsec-nat-t\",\n\t4534:  \"armagetronad\",\n\t4535:  \"ehs\",\n\t4536:  \"ehs-ssl\",\n\t4537:  \"wssauthsvc\",\n\t4538:  \"swx-gate\",\n\t4545:  \"worldscores\",\n\t4546:  \"sf-lm\",\n\t4547:  \"lanner-lm\",\n\t4548:  \"synchromesh\",\n\t4549:  \"aegate\",\n\t4550:  \"gds-adppiw-db\",\n\t4551:  \"ieee-mih\",\n\t4552:  \"menandmice-mon\",\n\t4554:  \"msfrs\",\n\t4555:  \"rsip\",\n\t4556:  \"dtn-bundle\",\n\t4557:  \"mtcevrunqss\",\n\t4558:  \"mtcevrunqman\",\n\t4559:  \"hylafax\",\n\t4566:  \"kwtc\",\n\t4567:  \"tram\",\n\t4568:  \"bmc-reporting\",\n\t4569:  \"iax\",\n\t4591:  \"l3t-at-an\",\n\t4592:  \"hrpd-ith-at-an\",\n\t4593:  \"ipt-anri-anri\",\n\t4594:  \"ias-session\",\n\t4595:  \"ias-paging\",\n\t4596:  \"ias-neighbor\",\n\t4597:  \"a21-an-1xbs\",\n\t4598:  \"a16-an-an\",\n\t4599:  \"a17-an-an\",\n\t4600:  \"piranha1\",\n\t4601:  \"piranha2\",\n\t4621:  \"ventoso\",\n\t4658:  \"playsta2-app\",\n\t4659:  \"playsta2-lob\",\n\t4660:  \"smaclmgr\",\n\t4661:  \"kar2ouche\",\n\t4662:  \"oms\",\n\t4663:  \"noteit\",\n\t4664:  \"ems\",\n\t4665:  \"contclientms\",\n\t4666:  \"eportcomm\",\n\t4667:  \"mmacomm\",\n\t4668:  \"mmaeds\",\n\t4669:  \"eportcommdata\",\n\t4670:  \"light\",\n\t4671:  \"acter\",\n\t4672:  \"rfa\",\n\t4673:  \"cxws\",\n\t4674:  \"appiq-mgmt\",\n\t4675:  \"dhct-status\",\n\t4676:  \"dhct-alerts\",\n\t4677:  \"bcs\",\n\t4678:  \"traversal\",\n\t4679:  \"mgesupervision\",\n\t4680:  \"mgemanagement\",\n\t4681:  \"parliant\",\n\t4682:  \"finisar\",\n\t4683:  \"spike\",\n\t4684:  \"rfid-rp1\",\n\t4685:  \"autopac\",\n\t4686:  \"msp-os\",\n\t4687:  \"nst\",\n\t4688:  \"mobile-p2p\",\n\t4689:  \"altovacentral\",\n\t4690:  \"prelude\",\n\t4691:  \"mtn\",\n\t4692:  \"conspiracy\",\n\t4700:  \"netxms-agent\",\n\t4701:  \"netxms-mgmt\",\n\t4702:  \"netxms-sync\",\n\t4711:  \"trinity-dist\",\n\t4725:  \"truckstar\",\n\t4726:  \"a26-fap-fgw\",\n\t4727:  \"fcis-disc\",\n\t4728:  \"capmux\",\n\t4729:  \"gsmtap\",\n\t4730:  \"gearman\",\n\t4732:  \"ohmtrigger\",\n\t4737:  \"ipdr-sp\",\n\t4738:  \"solera-lpn\",\n\t4739:  \"ipfix\",\n\t4740:  \"ipfixs\",\n\t4741:  \"lumimgrd\",\n\t4742:  \"sicct-sdp\",\n\t4743:  \"openhpid\",\n\t4744:  \"ifsp\",\n\t4745:  \"fmp\",\n\t4746:  \"intelliadm-disc\",\n\t4747:  \"buschtrommel\",\n\t4749:  \"profilemac\",\n\t4750:  \"ssad\",\n\t4751:  \"spocp\",\n\t4752:  \"snap\",\n\t4753:  \"simon-disc\",\n\t4754:  \"gre-in-udp\",\n\t4755:  \"gre-udp-dtls\",\n\t4784:  \"bfd-multi-ctl\",\n\t4785:  \"cncp\",\n\t4789:  \"vxlan\",\n\t4790:  \"vxlan-gpe\",\n\t4791:  \"roce\",\n\t4800:  \"iims\",\n\t4801:  \"iwec\",\n\t4802:  \"ilss\",\n\t4803:  \"notateit-disc\",\n\t4804:  \"aja-ntv4-disc\",\n\t4827:  \"htcp\",\n\t4837:  \"varadero-0\",\n\t4838:  \"varadero-1\",\n\t4839:  \"varadero-2\",\n\t4840:  \"opcua-udp\",\n\t4841:  \"quosa\",\n\t4842:  \"gw-asv\",\n\t4843:  \"opcua-tls\",\n\t4844:  \"gw-log\",\n\t4845:  \"wcr-remlib\",\n\t4846:  \"contamac-icm\",\n\t4847:  \"wfc\",\n\t4848:  \"appserv-http\",\n\t4849:  \"appserv-https\",\n\t4850:  \"sun-as-nodeagt\",\n\t4851:  \"derby-repli\",\n\t4867:  \"unify-debug\",\n\t4868:  \"phrelay\",\n\t4869:  \"phrelaydbg\",\n\t4870:  \"cc-tracking\",\n\t4871:  \"wired\",\n\t4876:  \"tritium-can\",\n\t4877:  \"lmcs\",\n\t4878:  \"inst-discovery\",\n\t4881:  \"socp-t\",\n\t4882:  \"socp-c\",\n\t4884:  \"hivestor\",\n\t4885:  \"abbs\",\n\t4894:  \"lyskom\",\n\t4899:  \"radmin-port\",\n\t4900:  \"hfcs\",\n\t4914:  \"bones\",\n\t4936:  \"an-signaling\",\n\t4937:  \"atsc-mh-ssc\",\n\t4940:  \"eq-office-4940\",\n\t4941:  \"eq-office-4941\",\n\t4942:  \"eq-office-4942\",\n\t4949:  \"munin\",\n\t4950:  \"sybasesrvmon\",\n\t4951:  \"pwgwims\",\n\t4952:  \"sagxtsds\",\n\t4969:  \"ccss-qmm\",\n\t4970:  \"ccss-qsm\",\n\t4980:  \"ctxs-vpp\",\n\t4986:  \"mrip\",\n\t4987:  \"smar-se-port1\",\n\t4988:  \"smar-se-port2\",\n\t4989:  \"parallel\",\n\t4990:  \"busycal\",\n\t4991:  \"vrt\",\n\t4999:  \"hfcs-manager\",\n\t5000:  \"commplex-main\",\n\t5001:  \"commplex-link\",\n\t5002:  \"rfe\",\n\t5003:  \"fmpro-internal\",\n\t5004:  \"avt-profile-1\",\n\t5005:  \"avt-profile-2\",\n\t5006:  \"wsm-server\",\n\t5007:  \"wsm-server-ssl\",\n\t5008:  \"synapsis-edge\",\n\t5009:  \"winfs\",\n\t5010:  \"telelpathstart\",\n\t5011:  \"telelpathattack\",\n\t5012:  \"nsp\",\n\t5013:  \"fmpro-v6\",\n\t5014:  \"onpsocket\",\n\t5020:  \"zenginkyo-1\",\n\t5021:  \"zenginkyo-2\",\n\t5022:  \"mice\",\n\t5023:  \"htuilsrv\",\n\t5024:  \"scpi-telnet\",\n\t5025:  \"scpi-raw\",\n\t5026:  \"strexec-d\",\n\t5027:  \"strexec-s\",\n\t5029:  \"infobright\",\n\t5030:  \"surfpass\",\n\t5031:  \"dmp\",\n\t5042:  \"asnaacceler8db\",\n\t5043:  \"swxadmin\",\n\t5044:  \"lxi-evntsvc\",\n\t5046:  \"vpm-udp\",\n\t5047:  \"iscape\",\n\t5049:  \"ivocalize\",\n\t5050:  \"mmcc\",\n\t5051:  \"ita-agent\",\n\t5052:  \"ita-manager\",\n\t5053:  \"rlm-disc\",\n\t5055:  \"unot\",\n\t5056:  \"intecom-ps1\",\n\t5057:  \"intecom-ps2\",\n\t5058:  \"locus-disc\",\n\t5059:  \"sds\",\n\t5060:  \"sip\",\n\t5061:  \"sips\",\n\t5062:  \"na-localise\",\n\t5064:  \"ca-1\",\n\t5065:  \"ca-2\",\n\t5066:  \"stanag-5066\",\n\t5067:  \"authentx\",\n\t5069:  \"i-net-2000-npr\",\n\t5070:  \"vtsas\",\n\t5071:  \"powerschool\",\n\t5072:  \"ayiya\",\n\t5073:  \"tag-pm\",\n\t5074:  \"alesquery\",\n\t5078:  \"pixelpusher\",\n\t5079:  \"cp-spxrpts\",\n\t5080:  \"onscreen\",\n\t5081:  \"sdl-ets\",\n\t5082:  \"qcp\",\n\t5083:  \"qfp\",\n\t5084:  \"llrp\",\n\t5085:  \"encrypted-llrp\",\n\t5092:  \"magpie\",\n\t5093:  \"sentinel-lm\",\n\t5094:  \"hart-ip\",\n\t5099:  \"sentlm-srv2srv\",\n\t5100:  \"socalia\",\n\t5101:  \"talarian-udp\",\n\t5102:  \"oms-nonsecure\",\n\t5104:  \"tinymessage\",\n\t5105:  \"hughes-ap\",\n\t5111:  \"taep-as-svc\",\n\t5112:  \"pm-cmdsvr\",\n\t5116:  \"emb-proj-cmd\",\n\t5120:  \"barracuda-bbs\",\n\t5133:  \"nbt-pc\",\n\t5136:  \"minotaur-sa\",\n\t5137:  \"ctsd\",\n\t5145:  \"rmonitor-secure\",\n\t5150:  \"atmp\",\n\t5151:  \"esri-sde\",\n\t5152:  \"sde-discovery\",\n\t5154:  \"bzflag\",\n\t5155:  \"asctrl-agent\",\n\t5164:  \"vpa-disc\",\n\t5165:  \"ife-icorp\",\n\t5166:  \"winpcs\",\n\t5167:  \"scte104\",\n\t5168:  \"scte30\",\n\t5190:  \"aol\",\n\t5191:  \"aol-1\",\n\t5192:  \"aol-2\",\n\t5193:  \"aol-3\",\n\t5200:  \"targus-getdata\",\n\t5201:  \"targus-getdata1\",\n\t5202:  \"targus-getdata2\",\n\t5203:  \"targus-getdata3\",\n\t5223:  \"hpvirtgrp\",\n\t5224:  \"hpvirtctrl\",\n\t5225:  \"hp-server\",\n\t5226:  \"hp-status\",\n\t5227:  \"perfd\",\n\t5234:  \"eenet\",\n\t5235:  \"galaxy-network\",\n\t5236:  \"padl2sim\",\n\t5237:  \"mnet-discovery\",\n\t5245:  \"downtools-disc\",\n\t5246:  \"capwap-control\",\n\t5247:  \"capwap-data\",\n\t5248:  \"caacws\",\n\t5249:  \"caaclang2\",\n\t5250:  \"soagateway\",\n\t5251:  \"caevms\",\n\t5252:  \"movaz-ssc\",\n\t5264:  \"3com-njack-1\",\n\t5265:  \"3com-njack-2\",\n\t5270:  \"cartographerxmp\",\n\t5271:  \"cuelink-disc\",\n\t5272:  \"pk\",\n\t5282:  \"transmit-port\",\n\t5298:  \"presence\",\n\t5299:  \"nlg-data\",\n\t5300:  \"hacl-hb\",\n\t5301:  \"hacl-gs\",\n\t5302:  \"hacl-cfg\",\n\t5303:  \"hacl-probe\",\n\t5304:  \"hacl-local\",\n\t5305:  \"hacl-test\",\n\t5306:  \"sun-mc-grp\",\n\t5307:  \"sco-aip\",\n\t5308:  \"cfengine\",\n\t5309:  \"jprinter\",\n\t5310:  \"outlaws\",\n\t5312:  \"permabit-cs\",\n\t5313:  \"rrdp\",\n\t5314:  \"opalis-rbt-ipc\",\n\t5315:  \"hacl-poll\",\n\t5343:  \"kfserver\",\n\t5344:  \"xkotodrcp\",\n\t5349:  \"stuns\",\n\t5350:  \"pcp-multicast\",\n\t5351:  \"pcp\",\n\t5352:  \"dns-llq\",\n\t5353:  \"mdns\",\n\t5354:  \"mdnsresponder\",\n\t5355:  \"llmnr\",\n\t5356:  \"ms-smlbiz\",\n\t5357:  \"wsdapi\",\n\t5358:  \"wsdapi-s\",\n\t5359:  \"ms-alerter\",\n\t5360:  \"ms-sideshow\",\n\t5361:  \"ms-s-sideshow\",\n\t5362:  \"serverwsd2\",\n\t5363:  \"net-projection\",\n\t5364:  \"kdnet\",\n\t5397:  \"stresstester\",\n\t5398:  \"elektron-admin\",\n\t5399:  \"securitychase\",\n\t5400:  \"excerpt\",\n\t5401:  \"excerpts\",\n\t5402:  \"mftp\",\n\t5403:  \"hpoms-ci-lstn\",\n\t5404:  \"hpoms-dps-lstn\",\n\t5405:  \"netsupport\",\n\t5406:  \"systemics-sox\",\n\t5407:  \"foresyte-clear\",\n\t5408:  \"foresyte-sec\",\n\t5409:  \"salient-dtasrv\",\n\t5410:  \"salient-usrmgr\",\n\t5411:  \"actnet\",\n\t5412:  \"continuus\",\n\t5413:  \"wwiotalk\",\n\t5414:  \"statusd\",\n\t5415:  \"ns-server\",\n\t5416:  \"sns-gateway\",\n\t5417:  \"sns-agent\",\n\t5418:  \"mcntp\",\n\t5419:  \"dj-ice\",\n\t5420:  \"cylink-c\",\n\t5421:  \"netsupport2\",\n\t5422:  \"salient-mux\",\n\t5423:  \"virtualuser\",\n\t5424:  \"beyond-remote\",\n\t5425:  \"br-channel\",\n\t5426:  \"devbasic\",\n\t5427:  \"sco-peer-tta\",\n\t5428:  \"telaconsole\",\n\t5429:  \"base\",\n\t5430:  \"radec-corp\",\n\t5431:  \"park-agent\",\n\t5432:  \"postgresql\",\n\t5433:  \"pyrrho\",\n\t5434:  \"sgi-arrayd\",\n\t5435:  \"sceanics\",\n\t5436:  \"pmip6-cntl\",\n\t5437:  \"pmip6-data\",\n\t5443:  \"spss\",\n\t5450:  \"tiepie-disc\",\n\t5453:  \"surebox\",\n\t5454:  \"apc-5454\",\n\t5455:  \"apc-5455\",\n\t5456:  \"apc-5456\",\n\t5461:  \"silkmeter\",\n\t5462:  \"ttl-publisher\",\n\t5463:  \"ttlpriceproxy\",\n\t5464:  \"quailnet\",\n\t5465:  \"netops-broker\",\n\t5474:  \"apsolab-rpc\",\n\t5500:  \"fcp-addr-srvr1\",\n\t5501:  \"fcp-addr-srvr2\",\n\t5502:  \"fcp-srvr-inst1\",\n\t5503:  \"fcp-srvr-inst2\",\n\t5504:  \"fcp-cics-gw1\",\n\t5505:  \"checkoutdb\",\n\t5506:  \"amc\",\n\t5553:  \"sgi-eventmond\",\n\t5554:  \"sgi-esphttp\",\n\t5555:  \"personal-agent\",\n\t5556:  \"freeciv\",\n\t5567:  \"dof-dps-mc-sec\",\n\t5568:  \"sdt\",\n\t5569:  \"rdmnet-device\",\n\t5573:  \"sdmmp\",\n\t5580:  \"tmosms0\",\n\t5581:  \"tmosms1\",\n\t5582:  \"fac-restore\",\n\t5583:  \"tmo-icon-sync\",\n\t5584:  \"bis-web\",\n\t5585:  \"bis-sync\",\n\t5597:  \"ininmessaging\",\n\t5598:  \"mctfeed\",\n\t5599:  \"esinstall\",\n\t5600:  \"esmmanager\",\n\t5601:  \"esmagent\",\n\t5602:  \"a1-msc\",\n\t5603:  \"a1-bs\",\n\t5604:  \"a3-sdunode\",\n\t5605:  \"a4-sdunode\",\n\t5627:  \"ninaf\",\n\t5628:  \"htrust\",\n\t5629:  \"symantec-sfdb\",\n\t5630:  \"precise-comm\",\n\t5631:  \"pcanywheredata\",\n\t5632:  \"pcanywherestat\",\n\t5633:  \"beorl\",\n\t5634:  \"xprtld\",\n\t5670:  \"zre-disc\",\n\t5671:  \"amqps\",\n\t5672:  \"amqp\",\n\t5673:  \"jms\",\n\t5674:  \"hyperscsi-port\",\n\t5675:  \"v5ua\",\n\t5676:  \"raadmin\",\n\t5677:  \"questdb2-lnchr\",\n\t5678:  \"rrac\",\n\t5679:  \"dccm\",\n\t5680:  \"auriga-router\",\n\t5681:  \"ncxcp\",\n\t5682:  \"brightcore\",\n\t5683:  \"coap\",\n\t5684:  \"coaps\",\n\t5687:  \"gog-multiplayer\",\n\t5688:  \"ggz\",\n\t5689:  \"qmvideo\",\n\t5713:  \"proshareaudio\",\n\t5714:  \"prosharevideo\",\n\t5715:  \"prosharedata\",\n\t5716:  \"prosharerequest\",\n\t5717:  \"prosharenotify\",\n\t5718:  \"dpm\",\n\t5719:  \"dpm-agent\",\n\t5720:  \"ms-licensing\",\n\t5721:  \"dtpt\",\n\t5722:  \"msdfsr\",\n\t5723:  \"omhs\",\n\t5724:  \"omsdk\",\n\t5728:  \"io-dist-group\",\n\t5729:  \"openmail\",\n\t5730:  \"unieng\",\n\t5741:  \"ida-discover1\",\n\t5742:  \"ida-discover2\",\n\t5743:  \"watchdoc-pod\",\n\t5744:  \"watchdoc\",\n\t5745:  \"fcopy-server\",\n\t5746:  \"fcopys-server\",\n\t5747:  \"tunatic\",\n\t5748:  \"tunalyzer\",\n\t5750:  \"rscd\",\n\t5755:  \"openmailg\",\n\t5757:  \"x500ms\",\n\t5766:  \"openmailns\",\n\t5767:  \"s-openmail\",\n\t5768:  \"openmailpxy\",\n\t5769:  \"spramsca\",\n\t5770:  \"spramsd\",\n\t5771:  \"netagent\",\n\t5777:  \"dali-port\",\n\t5781:  \"3par-evts\",\n\t5782:  \"3par-mgmt\",\n\t5783:  \"3par-mgmt-ssl\",\n\t5784:  \"ibar\",\n\t5785:  \"3par-rcopy\",\n\t5786:  \"cisco-redu\",\n\t5787:  \"waascluster\",\n\t5793:  \"xtreamx\",\n\t5794:  \"spdp\",\n\t5813:  \"icmpd\",\n\t5814:  \"spt-automation\",\n\t5859:  \"wherehoo\",\n\t5863:  \"ppsuitemsg\",\n\t5900:  \"rfb\",\n\t5910:  \"cm\",\n\t5911:  \"cpdlc\",\n\t5912:  \"fis\",\n\t5913:  \"ads-c\",\n\t5963:  \"indy\",\n\t5968:  \"mppolicy-v5\",\n\t5969:  \"mppolicy-mgr\",\n\t5984:  \"couchdb\",\n\t5985:  \"wsman\",\n\t5986:  \"wsmans\",\n\t5987:  \"wbem-rmi\",\n\t5988:  \"wbem-http\",\n\t5989:  \"wbem-https\",\n\t5990:  \"wbem-exp-https\",\n\t5991:  \"nuxsl\",\n\t5992:  \"consul-insight\",\n\t5999:  \"cvsup\",\n\t6064:  \"ndl-ahp-svc\",\n\t6065:  \"winpharaoh\",\n\t6066:  \"ewctsp\",\n\t6069:  \"trip\",\n\t6070:  \"messageasap\",\n\t6071:  \"ssdtp\",\n\t6072:  \"diagnose-proc\",\n\t6073:  \"directplay8\",\n\t6074:  \"max\",\n\t6080:  \"gue\",\n\t6081:  \"geneve\",\n\t6082:  \"p25cai\",\n\t6083:  \"miami-bcast\",\n\t6085:  \"konspire2b\",\n\t6086:  \"pdtp\",\n\t6087:  \"ldss\",\n\t6088:  \"doglms-notify\",\n\t6100:  \"synchronet-db\",\n\t6101:  \"synchronet-rtc\",\n\t6102:  \"synchronet-upd\",\n\t6103:  \"rets\",\n\t6104:  \"dbdb\",\n\t6105:  \"primaserver\",\n\t6106:  \"mpsserver\",\n\t6107:  \"etc-control\",\n\t6108:  \"sercomm-scadmin\",\n\t6109:  \"globecast-id\",\n\t6110:  \"softcm\",\n\t6111:  \"spc\",\n\t6112:  \"dtspcd\",\n\t6118:  \"tipc\",\n\t6122:  \"bex-webadmin\",\n\t6123:  \"backup-express\",\n\t6124:  \"pnbs\",\n\t6133:  \"nbt-wol\",\n\t6140:  \"pulsonixnls\",\n\t6141:  \"meta-corp\",\n\t6142:  \"aspentec-lm\",\n\t6143:  \"watershed-lm\",\n\t6144:  \"statsci1-lm\",\n\t6145:  \"statsci2-lm\",\n\t6146:  \"lonewolf-lm\",\n\t6147:  \"montage-lm\",\n\t6148:  \"ricardo-lm\",\n\t6149:  \"tal-pod\",\n\t6160:  \"ecmp-data\",\n\t6161:  \"patrol-ism\",\n\t6162:  \"patrol-coll\",\n\t6163:  \"pscribe\",\n\t6200:  \"lm-x\",\n\t6201:  \"thermo-calc\",\n\t6209:  \"qmtps\",\n\t6222:  \"radmind\",\n\t6241:  \"jeol-nsddp-1\",\n\t6242:  \"jeol-nsddp-2\",\n\t6243:  \"jeol-nsddp-3\",\n\t6244:  \"jeol-nsddp-4\",\n\t6251:  \"tl1-raw-ssl\",\n\t6252:  \"tl1-ssh\",\n\t6253:  \"crip\",\n\t6268:  \"grid\",\n\t6269:  \"grid-alt\",\n\t6300:  \"bmc-grx\",\n\t6301:  \"bmc-ctd-ldap\",\n\t6306:  \"ufmp\",\n\t6315:  \"scup-disc\",\n\t6316:  \"abb-escp\",\n\t6317:  \"nav-data\",\n\t6320:  \"repsvc\",\n\t6321:  \"emp-server1\",\n\t6322:  \"emp-server2\",\n\t6324:  \"hrd-ns-disc\",\n\t6343:  \"sflow\",\n\t6346:  \"gnutella-svc\",\n\t6347:  \"gnutella-rtr\",\n\t6350:  \"adap\",\n\t6355:  \"pmcs\",\n\t6360:  \"metaedit-mu\",\n\t6363:  \"ndn\",\n\t6370:  \"metaedit-se\",\n\t6382:  \"metatude-mds\",\n\t6389:  \"clariion-evr01\",\n\t6390:  \"metaedit-ws\",\n\t6417:  \"faxcomservice\",\n\t6419:  \"svdrp-disc\",\n\t6420:  \"nim-vdrshell\",\n\t6421:  \"nim-wan\",\n\t6443:  \"sun-sr-https\",\n\t6444:  \"sge-qmaster\",\n\t6445:  \"sge-execd\",\n\t6446:  \"mysql-proxy\",\n\t6455:  \"skip-cert-recv\",\n\t6456:  \"skip-cert-send\",\n\t6464:  \"ieee11073-20701\",\n\t6471:  \"lvision-lm\",\n\t6480:  \"sun-sr-http\",\n\t6481:  \"servicetags\",\n\t6482:  \"ldoms-mgmt\",\n\t6483:  \"SunVTS-RMI\",\n\t6484:  \"sun-sr-jms\",\n\t6485:  \"sun-sr-iiop\",\n\t6486:  \"sun-sr-iiops\",\n\t6487:  \"sun-sr-iiop-aut\",\n\t6488:  \"sun-sr-jmx\",\n\t6489:  \"sun-sr-admin\",\n\t6500:  \"boks\",\n\t6501:  \"boks-servc\",\n\t6502:  \"boks-servm\",\n\t6503:  \"boks-clntd\",\n\t6505:  \"badm-priv\",\n\t6506:  \"badm-pub\",\n\t6507:  \"bdir-priv\",\n\t6508:  \"bdir-pub\",\n\t6509:  \"mgcs-mfp-port\",\n\t6510:  \"mcer-port\",\n\t6511:  \"dccp-udp\",\n\t6514:  \"syslog-tls\",\n\t6515:  \"elipse-rec\",\n\t6543:  \"lds-distrib\",\n\t6544:  \"lds-dump\",\n\t6547:  \"apc-6547\",\n\t6548:  \"apc-6548\",\n\t6549:  \"apc-6549\",\n\t6550:  \"fg-sysupdate\",\n\t6551:  \"sum\",\n\t6558:  \"xdsxdm\",\n\t6566:  \"sane-port\",\n\t6568:  \"rp-reputation\",\n\t6579:  \"affiliate\",\n\t6580:  \"parsec-master\",\n\t6581:  \"parsec-peer\",\n\t6582:  \"parsec-game\",\n\t6583:  \"joaJewelSuite\",\n\t6619:  \"odette-ftps\",\n\t6620:  \"kftp-data\",\n\t6621:  \"kftp\",\n\t6622:  \"mcftp\",\n\t6623:  \"ktelnet\",\n\t6626:  \"wago-service\",\n\t6627:  \"nexgen\",\n\t6628:  \"afesc-mc\",\n\t6629:  \"nexgen-aux\",\n\t6633:  \"cisco-vpath-tun\",\n\t6634:  \"mpls-pm\",\n\t6635:  \"mpls-udp\",\n\t6636:  \"mpls-udp-dtls\",\n\t6653:  \"openflow\",\n\t6657:  \"palcom-disc\",\n\t6670:  \"vocaltec-gold\",\n\t6671:  \"p4p-portal\",\n\t6672:  \"vision-server\",\n\t6673:  \"vision-elmd\",\n\t6678:  \"vfbp-disc\",\n\t6679:  \"osaut\",\n\t6689:  \"tsa\",\n\t6696:  \"babel\",\n\t6701:  \"kti-icad-srvr\",\n\t6702:  \"e-design-net\",\n\t6703:  \"e-design-web\",\n\t6714:  \"ibprotocol\",\n\t6715:  \"fibotrader-com\",\n\t6767:  \"bmc-perf-agent\",\n\t6768:  \"bmc-perf-mgrd\",\n\t6769:  \"adi-gxp-srvprt\",\n\t6770:  \"plysrv-http\",\n\t6771:  \"plysrv-https\",\n\t6784:  \"bfd-lag\",\n\t6785:  \"dgpf-exchg\",\n\t6786:  \"smc-jmx\",\n\t6787:  \"smc-admin\",\n\t6788:  \"smc-http\",\n\t6790:  \"hnmp\",\n\t6791:  \"hnm\",\n\t6801:  \"acnet\",\n\t6831:  \"ambit-lm\",\n\t6841:  \"netmo-default\",\n\t6842:  \"netmo-http\",\n\t6850:  \"iccrushmore\",\n\t6868:  \"acctopus-st\",\n\t6888:  \"muse\",\n\t6935:  \"ethoscan\",\n\t6936:  \"xsmsvc\",\n\t6946:  \"bioserver\",\n\t6951:  \"otlp\",\n\t6961:  \"jmact3\",\n\t6962:  \"jmevt2\",\n\t6963:  \"swismgr1\",\n\t6964:  \"swismgr2\",\n\t6965:  \"swistrap\",\n\t6966:  \"swispol\",\n\t6969:  \"acmsoda\",\n\t6997:  \"MobilitySrv\",\n\t6998:  \"iatp-highpri\",\n\t6999:  \"iatp-normalpri\",\n\t7000:  \"afs3-fileserver\",\n\t7001:  \"afs3-callback\",\n\t7002:  \"afs3-prserver\",\n\t7003:  \"afs3-vlserver\",\n\t7004:  \"afs3-kaserver\",\n\t7005:  \"afs3-volser\",\n\t7006:  \"afs3-errors\",\n\t7007:  \"afs3-bos\",\n\t7008:  \"afs3-update\",\n\t7009:  \"afs3-rmtsys\",\n\t7010:  \"ups-onlinet\",\n\t7011:  \"talon-disc\",\n\t7012:  \"talon-engine\",\n\t7013:  \"microtalon-dis\",\n\t7014:  \"microtalon-com\",\n\t7015:  \"talon-webserver\",\n\t7016:  \"spg\",\n\t7017:  \"grasp\",\n\t7019:  \"doceri-view\",\n\t7020:  \"dpserve\",\n\t7021:  \"dpserveadmin\",\n\t7022:  \"ctdp\",\n\t7023:  \"ct2nmcs\",\n\t7024:  \"vmsvc\",\n\t7025:  \"vmsvc-2\",\n\t7030:  \"op-probe\",\n\t7040:  \"quest-disc\",\n\t7070:  \"arcp\",\n\t7071:  \"iwg1\",\n\t7080:  \"empowerid\",\n\t7088:  \"zixi-transport\",\n\t7095:  \"jdp-disc\",\n\t7099:  \"lazy-ptop\",\n\t7100:  \"font-service\",\n\t7101:  \"elcn\",\n\t7107:  \"aes-x170\",\n\t7121:  \"virprot-lm\",\n\t7128:  \"scenidm\",\n\t7129:  \"scenccs\",\n\t7161:  \"cabsm-comm\",\n\t7162:  \"caistoragemgr\",\n\t7163:  \"cacsambroker\",\n\t7164:  \"fsr\",\n\t7165:  \"doc-server\",\n\t7166:  \"aruba-server\",\n\t7169:  \"ccag-pib\",\n\t7170:  \"nsrp\",\n\t7171:  \"drm-production\",\n\t7174:  \"clutild\",\n\t7181:  \"janus-disc\",\n\t7200:  \"fodms\",\n\t7201:  \"dlip\",\n\t7227:  \"ramp\",\n\t7235:  \"aspcoordination\",\n\t7244:  \"frc-hicp-disc\",\n\t7262:  \"cnap\",\n\t7272:  \"watchme-7272\",\n\t7273:  \"oma-rlp\",\n\t7274:  \"oma-rlp-s\",\n\t7275:  \"oma-ulp\",\n\t7276:  \"oma-ilp\",\n\t7277:  \"oma-ilp-s\",\n\t7278:  \"oma-dcdocbs\",\n\t7279:  \"ctxlic\",\n\t7280:  \"itactionserver1\",\n\t7281:  \"itactionserver2\",\n\t7282:  \"mzca-alert\",\n\t7365:  \"lcm-server\",\n\t7391:  \"mindfilesys\",\n\t7392:  \"mrssrendezvous\",\n\t7393:  \"nfoldman\",\n\t7394:  \"fse\",\n\t7395:  \"winqedit\",\n\t7397:  \"hexarc\",\n\t7400:  \"rtps-discovery\",\n\t7401:  \"rtps-dd-ut\",\n\t7402:  \"rtps-dd-mt\",\n\t7410:  \"ionixnetmon\",\n\t7411:  \"daqstream\",\n\t7421:  \"mtportmon\",\n\t7426:  \"pmdmgr\",\n\t7427:  \"oveadmgr\",\n\t7428:  \"ovladmgr\",\n\t7429:  \"opi-sock\",\n\t7430:  \"xmpv7\",\n\t7431:  \"pmd\",\n\t7437:  \"faximum\",\n\t7443:  \"oracleas-https\",\n\t7473:  \"rise\",\n\t7491:  \"telops-lmd\",\n\t7500:  \"silhouette\",\n\t7501:  \"ovbus\",\n\t7510:  \"ovhpas\",\n\t7511:  \"pafec-lm\",\n\t7542:  \"saratoga\",\n\t7543:  \"atul\",\n\t7544:  \"nta-ds\",\n\t7545:  \"nta-us\",\n\t7546:  \"cfs\",\n\t7547:  \"cwmp\",\n\t7548:  \"tidp\",\n\t7549:  \"nls-tl\",\n\t7550:  \"cloudsignaling\",\n\t7560:  \"sncp\",\n\t7566:  \"vsi-omega\",\n\t7570:  \"aries-kfinder\",\n\t7574:  \"coherence-disc\",\n\t7588:  \"sun-lm\",\n\t7606:  \"mipi-debug\",\n\t7624:  \"indi\",\n\t7627:  \"soap-http\",\n\t7628:  \"zen-pawn\",\n\t7629:  \"xdas\",\n\t7633:  \"pmdfmgt\",\n\t7648:  \"cuseeme\",\n\t7674:  \"imqtunnels\",\n\t7675:  \"imqtunnel\",\n\t7676:  \"imqbrokerd\",\n\t7677:  \"sun-user-https\",\n\t7680:  \"pando-pub\",\n\t7689:  \"collaber\",\n\t7697:  \"klio\",\n\t7707:  \"sync-em7\",\n\t7708:  \"scinet\",\n\t7720:  \"medimageportal\",\n\t7724:  \"nsdeepfreezectl\",\n\t7725:  \"nitrogen\",\n\t7726:  \"freezexservice\",\n\t7727:  \"trident-data\",\n\t7728:  \"osvr\",\n\t7734:  \"smip\",\n\t7738:  \"aiagent\",\n\t7741:  \"scriptview\",\n\t7743:  \"sstp-1\",\n\t7744:  \"raqmon-pdu\",\n\t7747:  \"prgp\",\n\t7777:  \"cbt\",\n\t7778:  \"interwise\",\n\t7779:  \"vstat\",\n\t7781:  \"accu-lmgr\",\n\t7784:  \"s-bfd\",\n\t7786:  \"minivend\",\n\t7787:  \"popup-reminders\",\n\t7789:  \"office-tools\",\n\t7794:  \"q3ade\",\n\t7797:  \"pnet-conn\",\n\t7798:  \"pnet-enc\",\n\t7799:  \"altbsdp\",\n\t7800:  \"asr\",\n\t7801:  \"ssp-client\",\n\t7802:  \"vns-tp\",\n\t7810:  \"rbt-wanopt\",\n\t7845:  \"apc-7845\",\n\t7846:  \"apc-7846\",\n\t7872:  \"mipv6tls\",\n\t7880:  \"pss\",\n\t7887:  \"ubroker\",\n\t7900:  \"mevent\",\n\t7901:  \"tnos-sp\",\n\t7902:  \"tnos-dp\",\n\t7903:  \"tnos-dps\",\n\t7913:  \"qo-secure\",\n\t7932:  \"t2-drm\",\n\t7933:  \"t2-brm\",\n\t7962:  \"generalsync\",\n\t7967:  \"supercell\",\n\t7979:  \"micromuse-ncps\",\n\t7980:  \"quest-vista\",\n\t7982:  \"sossd-disc\",\n\t7998:  \"usicontentpush\",\n\t7999:  \"irdmi2\",\n\t8000:  \"irdmi\",\n\t8001:  \"vcom-tunnel\",\n\t8002:  \"teradataordbms\",\n\t8003:  \"mcreport\",\n\t8005:  \"mxi\",\n\t8006:  \"wpl-disc\",\n\t8007:  \"warppipe\",\n\t8008:  \"http-alt\",\n\t8019:  \"qbdb\",\n\t8020:  \"intu-ec-svcdisc\",\n\t8021:  \"intu-ec-client\",\n\t8022:  \"oa-system\",\n\t8025:  \"ca-audit-da\",\n\t8026:  \"ca-audit-ds\",\n\t8032:  \"pro-ed\",\n\t8033:  \"mindprint\",\n\t8034:  \"vantronix-mgmt\",\n\t8040:  \"ampify\",\n\t8041:  \"enguity-xccetp\",\n\t8052:  \"senomix01\",\n\t8053:  \"senomix02\",\n\t8054:  \"senomix03\",\n\t8055:  \"senomix04\",\n\t8056:  \"senomix05\",\n\t8057:  \"senomix06\",\n\t8058:  \"senomix07\",\n\t8059:  \"senomix08\",\n\t8060:  \"aero\",\n\t8074:  \"gadugadu\",\n\t8080:  \"http-alt\",\n\t8081:  \"sunproxyadmin\",\n\t8082:  \"us-cli\",\n\t8083:  \"us-srv\",\n\t8086:  \"d-s-n\",\n\t8087:  \"simplifymedia\",\n\t8088:  \"radan-http\",\n\t8097:  \"sac\",\n\t8100:  \"xprint-server\",\n\t8115:  \"mtl8000-matrix\",\n\t8116:  \"cp-cluster\",\n\t8118:  \"privoxy\",\n\t8121:  \"apollo-data\",\n\t8122:  \"apollo-admin\",\n\t8128:  \"paycash-online\",\n\t8129:  \"paycash-wbp\",\n\t8130:  \"indigo-vrmi\",\n\t8131:  \"indigo-vbcp\",\n\t8132:  \"dbabble\",\n\t8148:  \"isdd\",\n\t8149:  \"eor-game\",\n\t8160:  \"patrol\",\n\t8161:  \"patrol-snmp\",\n\t8182:  \"vmware-fdm\",\n\t8184:  \"itach\",\n\t8192:  \"spytechphone\",\n\t8194:  \"blp1\",\n\t8195:  \"blp2\",\n\t8199:  \"vvr-data\",\n\t8200:  \"trivnet1\",\n\t8201:  \"trivnet2\",\n\t8202:  \"aesop\",\n\t8204:  \"lm-perfworks\",\n\t8205:  \"lm-instmgr\",\n\t8206:  \"lm-dta\",\n\t8207:  \"lm-sserver\",\n\t8208:  \"lm-webwatcher\",\n\t8230:  \"rexecj\",\n\t8231:  \"hncp-udp-port\",\n\t8232:  \"hncp-dtls-port\",\n\t8243:  \"synapse-nhttps\",\n\t8276:  \"pando-sec\",\n\t8280:  \"synapse-nhttp\",\n\t8282:  \"libelle-disc\",\n\t8292:  \"blp3\",\n\t8294:  \"blp4\",\n\t8300:  \"tmi\",\n\t8301:  \"amberon\",\n\t8320:  \"tnp-discover\",\n\t8321:  \"tnp\",\n\t8322:  \"garmin-marine\",\n\t8351:  \"server-find\",\n\t8376:  \"cruise-enum\",\n\t8377:  \"cruise-swroute\",\n\t8378:  \"cruise-config\",\n\t8379:  \"cruise-diags\",\n\t8380:  \"cruise-update\",\n\t8383:  \"m2mservices\",\n\t8384:  \"marathontp\",\n\t8400:  \"cvd\",\n\t8401:  \"sabarsd\",\n\t8402:  \"abarsd\",\n\t8403:  \"admind\",\n\t8416:  \"espeech\",\n\t8417:  \"espeech-rtp\",\n\t8442:  \"cybro-a-bus\",\n\t8443:  \"pcsync-https\",\n\t8444:  \"pcsync-http\",\n\t8445:  \"copy-disc\",\n\t8450:  \"npmp\",\n\t8472:  \"otv\",\n\t8473:  \"vp2p\",\n\t8474:  \"noteshare\",\n\t8500:  \"fmtp\",\n\t8501:  \"cmtp-av\",\n\t8503:  \"lsp-self-ping\",\n\t8554:  \"rtsp-alt\",\n\t8555:  \"d-fence\",\n\t8567:  \"dof-tunnel\",\n\t8600:  \"asterix\",\n\t8609:  \"canon-cpp-disc\",\n\t8610:  \"canon-mfnp\",\n\t8611:  \"canon-bjnp1\",\n\t8612:  \"canon-bjnp2\",\n\t8613:  \"canon-bjnp3\",\n\t8614:  \"canon-bjnp4\",\n\t8675:  \"msi-cps-rm-disc\",\n\t8686:  \"sun-as-jmxrmi\",\n\t8732:  \"dtp-net\",\n\t8733:  \"ibus\",\n\t8763:  \"mc-appserver\",\n\t8764:  \"openqueue\",\n\t8765:  \"ultraseek-http\",\n\t8766:  \"amcs\",\n\t8770:  \"dpap\",\n\t8786:  \"msgclnt\",\n\t8787:  \"msgsrvr\",\n\t8793:  \"acd-pm\",\n\t8800:  \"sunwebadmin\",\n\t8804:  \"truecm\",\n\t8805:  \"pfcp\",\n\t8808:  \"ssports-bcast\",\n\t8873:  \"dxspider\",\n\t8880:  \"cddbp-alt\",\n\t8883:  \"secure-mqtt\",\n\t8888:  \"ddi-udp-1\",\n\t8889:  \"ddi-udp-2\",\n\t8890:  \"ddi-udp-3\",\n\t8891:  \"ddi-udp-4\",\n\t8892:  \"ddi-udp-5\",\n\t8893:  \"ddi-udp-6\",\n\t8894:  \"ddi-udp-7\",\n\t8899:  \"ospf-lite\",\n\t8900:  \"jmb-cds1\",\n\t8901:  \"jmb-cds2\",\n\t8910:  \"manyone-http\",\n\t8911:  \"manyone-xml\",\n\t8912:  \"wcbackup\",\n\t8913:  \"dragonfly\",\n\t8954:  \"cumulus-admin\",\n\t8980:  \"nod-provider\",\n\t8981:  \"nod-client\",\n\t8989:  \"sunwebadmins\",\n\t8990:  \"http-wmap\",\n\t8991:  \"https-wmap\",\n\t8999:  \"bctp\",\n\t9000:  \"cslistener\",\n\t9001:  \"etlservicemgr\",\n\t9002:  \"dynamid\",\n\t9007:  \"ogs-client\",\n\t9009:  \"pichat\",\n\t9020:  \"tambora\",\n\t9021:  \"panagolin-ident\",\n\t9022:  \"paragent\",\n\t9023:  \"swa-1\",\n\t9024:  \"swa-2\",\n\t9025:  \"swa-3\",\n\t9026:  \"swa-4\",\n\t9060:  \"CardWeb-RT\",\n\t9080:  \"glrpc\",\n\t9084:  \"aurora\",\n\t9085:  \"ibm-rsyscon\",\n\t9086:  \"net2display\",\n\t9087:  \"classic\",\n\t9088:  \"sqlexec\",\n\t9089:  \"sqlexec-ssl\",\n\t9090:  \"websm\",\n\t9091:  \"xmltec-xmlmail\",\n\t9092:  \"XmlIpcRegSvc\",\n\t9100:  \"hp-pdl-datastr\",\n\t9101:  \"bacula-dir\",\n\t9102:  \"bacula-fd\",\n\t9103:  \"bacula-sd\",\n\t9104:  \"peerwire\",\n\t9105:  \"xadmin\",\n\t9106:  \"astergate-disc\",\n\t9119:  \"mxit\",\n\t9131:  \"dddp\",\n\t9160:  \"apani1\",\n\t9161:  \"apani2\",\n\t9162:  \"apani3\",\n\t9163:  \"apani4\",\n\t9164:  \"apani5\",\n\t9191:  \"sun-as-jpda\",\n\t9200:  \"wap-wsp\",\n\t9201:  \"wap-wsp-wtp\",\n\t9202:  \"wap-wsp-s\",\n\t9203:  \"wap-wsp-wtp-s\",\n\t9204:  \"wap-vcard\",\n\t9205:  \"wap-vcal\",\n\t9206:  \"wap-vcard-s\",\n\t9207:  \"wap-vcal-s\",\n\t9208:  \"rjcdb-vcards\",\n\t9209:  \"almobile-system\",\n\t9210:  \"oma-mlp\",\n\t9211:  \"oma-mlp-s\",\n\t9212:  \"serverviewdbms\",\n\t9213:  \"serverstart\",\n\t9214:  \"ipdcesgbs\",\n\t9215:  \"insis\",\n\t9216:  \"acme\",\n\t9217:  \"fsc-port\",\n\t9222:  \"teamcoherence\",\n\t9255:  \"mon\",\n\t9277:  \"traingpsdata\",\n\t9278:  \"pegasus\",\n\t9279:  \"pegasus-ctl\",\n\t9280:  \"pgps\",\n\t9281:  \"swtp-port1\",\n\t9282:  \"swtp-port2\",\n\t9283:  \"callwaveiam\",\n\t9284:  \"visd\",\n\t9285:  \"n2h2server\",\n\t9286:  \"n2receive\",\n\t9287:  \"cumulus\",\n\t9292:  \"armtechdaemon\",\n\t9293:  \"storview\",\n\t9294:  \"armcenterhttp\",\n\t9295:  \"armcenterhttps\",\n\t9300:  \"vrace\",\n\t9318:  \"secure-ts\",\n\t9321:  \"guibase\",\n\t9343:  \"mpidcmgr\",\n\t9344:  \"mphlpdmc\",\n\t9346:  \"ctechlicensing\",\n\t9374:  \"fjdmimgr\",\n\t9380:  \"boxp\",\n\t9396:  \"fjinvmgr\",\n\t9397:  \"mpidcagt\",\n\t9400:  \"sec-t4net-srv\",\n\t9401:  \"sec-t4net-clt\",\n\t9402:  \"sec-pc2fax-srv\",\n\t9418:  \"git\",\n\t9443:  \"tungsten-https\",\n\t9444:  \"wso2esb-console\",\n\t9450:  \"sntlkeyssrvr\",\n\t9500:  \"ismserver\",\n\t9522:  \"sma-spw\",\n\t9535:  \"mngsuite\",\n\t9536:  \"laes-bf\",\n\t9555:  \"trispen-sra\",\n\t9592:  \"ldgateway\",\n\t9593:  \"cba8\",\n\t9594:  \"msgsys\",\n\t9595:  \"pds\",\n\t9596:  \"mercury-disc\",\n\t9597:  \"pd-admin\",\n\t9598:  \"vscp\",\n\t9599:  \"robix\",\n\t9600:  \"micromuse-ncpw\",\n\t9612:  \"streamcomm-ds\",\n\t9618:  \"condor\",\n\t9628:  \"odbcpathway\",\n\t9629:  \"uniport\",\n\t9632:  \"mc-comm\",\n\t9667:  \"xmms2\",\n\t9668:  \"tec5-sdctp\",\n\t9694:  \"client-wakeup\",\n\t9695:  \"ccnx\",\n\t9700:  \"board-roar\",\n\t9747:  \"l5nas-parchan\",\n\t9750:  \"board-voip\",\n\t9753:  \"rasadv\",\n\t9762:  \"tungsten-http\",\n\t9800:  \"davsrc\",\n\t9801:  \"sstp-2\",\n\t9802:  \"davsrcs\",\n\t9875:  \"sapv1\",\n\t9878:  \"kca-service\",\n\t9888:  \"cyborg-systems\",\n\t9889:  \"gt-proxy\",\n\t9898:  \"monkeycom\",\n\t9899:  \"sctp-tunneling\",\n\t9900:  \"iua\",\n\t9901:  \"enrp\",\n\t9903:  \"multicast-ping\",\n\t9909:  \"domaintime\",\n\t9911:  \"sype-transport\",\n\t9950:  \"apc-9950\",\n\t9951:  \"apc-9951\",\n\t9952:  \"apc-9952\",\n\t9953:  \"acis\",\n\t9955:  \"alljoyn-mcm\",\n\t9956:  \"alljoyn\",\n\t9966:  \"odnsp\",\n\t9987:  \"dsm-scm-target\",\n\t9990:  \"osm-appsrvr\",\n\t9991:  \"osm-oev\",\n\t9992:  \"palace-1\",\n\t9993:  \"palace-2\",\n\t9994:  \"palace-3\",\n\t9995:  \"palace-4\",\n\t9996:  \"palace-5\",\n\t9997:  \"palace-6\",\n\t9998:  \"distinct32\",\n\t9999:  \"distinct\",\n\t10000: \"ndmp\",\n\t10001: \"scp-config\",\n\t10002: \"documentum\",\n\t10003: \"documentum-s\",\n\t10007: \"mvs-capacity\",\n\t10008: \"octopus\",\n\t10009: \"swdtp-sv\",\n\t10050: \"zabbix-agent\",\n\t10051: \"zabbix-trapper\",\n\t10080: \"amanda\",\n\t10081: \"famdc\",\n\t10100: \"itap-ddtp\",\n\t10101: \"ezmeeting-2\",\n\t10102: \"ezproxy-2\",\n\t10103: \"ezrelay\",\n\t10104: \"swdtp\",\n\t10107: \"bctp-server\",\n\t10110: \"nmea-0183\",\n\t10111: \"nmea-onenet\",\n\t10113: \"netiq-endpoint\",\n\t10114: \"netiq-qcheck\",\n\t10115: \"netiq-endpt\",\n\t10116: \"netiq-voipa\",\n\t10117: \"iqrm\",\n\t10128: \"bmc-perf-sd\",\n\t10160: \"qb-db-server\",\n\t10161: \"snmpdtls\",\n\t10162: \"snmpdtls-trap\",\n\t10200: \"trisoap\",\n\t10201: \"rscs\",\n\t10252: \"apollo-relay\",\n\t10253: \"eapol-relay\",\n\t10260: \"axis-wimp-port\",\n\t10288: \"blocks\",\n\t10439: \"bngsync\",\n\t10500: \"hip-nat-t\",\n\t10540: \"MOS-lower\",\n\t10541: \"MOS-upper\",\n\t10542: \"MOS-aux\",\n\t10543: \"MOS-soap\",\n\t10544: \"MOS-soap-opt\",\n\t10800: \"gap\",\n\t10805: \"lpdg\",\n\t10810: \"nmc-disc\",\n\t10860: \"helix\",\n\t10880: \"bveapi\",\n\t10990: \"rmiaux\",\n\t11000: \"irisa\",\n\t11001: \"metasys\",\n\t10023: \"cefd-vmp\",\n\t11095: \"weave\",\n\t11106: \"sgi-lk\",\n\t11108: \"myq-termlink\",\n\t11111: \"vce\",\n\t11112: \"dicom\",\n\t11161: \"suncacao-snmp\",\n\t11162: \"suncacao-jmxmp\",\n\t11163: \"suncacao-rmi\",\n\t11164: \"suncacao-csa\",\n\t11165: \"suncacao-websvc\",\n\t11171: \"snss\",\n\t11201: \"smsqp\",\n\t11208: \"wifree\",\n\t11211: \"memcache\",\n\t11319: \"imip\",\n\t11320: \"imip-channels\",\n\t11321: \"arena-server\",\n\t11367: \"atm-uhas\",\n\t11371: \"hkp\",\n\t11430: \"lsdp\",\n\t11600: \"tempest-port\",\n\t11720: \"h323callsigalt\",\n\t11723: \"emc-xsw-dcache\",\n\t11751: \"intrepid-ssl\",\n\t11796: \"lanschool-mpt\",\n\t11876: \"xoraya\",\n\t11877: \"x2e-disc\",\n\t11967: \"sysinfo-sp\",\n\t12000: \"entextxid\",\n\t12001: \"entextnetwk\",\n\t12002: \"entexthigh\",\n\t12003: \"entextmed\",\n\t12004: \"entextlow\",\n\t12005: \"dbisamserver1\",\n\t12006: \"dbisamserver2\",\n\t12007: \"accuracer\",\n\t12008: \"accuracer-dbms\",\n\t12009: \"ghvpn\",\n\t12012: \"vipera\",\n\t12013: \"vipera-ssl\",\n\t12109: \"rets-ssl\",\n\t12121: \"nupaper-ss\",\n\t12168: \"cawas\",\n\t12172: \"hivep\",\n\t12300: \"linogridengine\",\n\t12321: \"warehouse-sss\",\n\t12322: \"warehouse\",\n\t12345: \"italk\",\n\t12753: \"tsaf\",\n\t13160: \"i-zipqd\",\n\t13216: \"bcslogc\",\n\t13217: \"rs-pias\",\n\t13218: \"emc-vcas-udp\",\n\t13223: \"powwow-client\",\n\t13224: \"powwow-server\",\n\t13400: \"doip-disc\",\n\t13720: \"bprd\",\n\t13721: \"bpdbm\",\n\t13722: \"bpjava-msvc\",\n\t13724: \"vnetd\",\n\t13782: \"bpcd\",\n\t13783: \"vopied\",\n\t13785: \"nbdb\",\n\t13786: \"nomdb\",\n\t13818: \"dsmcc-config\",\n\t13819: \"dsmcc-session\",\n\t13820: \"dsmcc-passthru\",\n\t13821: \"dsmcc-download\",\n\t13822: \"dsmcc-ccp\",\n\t13894: \"ucontrol\",\n\t13929: \"dta-systems\",\n\t14000: \"scotty-ft\",\n\t14001: \"sua\",\n\t14002: \"scotty-disc\",\n\t14033: \"sage-best-com1\",\n\t14034: \"sage-best-com2\",\n\t14141: \"vcs-app\",\n\t14142: \"icpp\",\n\t14145: \"gcm-app\",\n\t14149: \"vrts-tdd\",\n\t14154: \"vad\",\n\t14250: \"cps\",\n\t14414: \"ca-web-update\",\n\t14936: \"hde-lcesrvr-1\",\n\t14937: \"hde-lcesrvr-2\",\n\t15000: \"hydap\",\n\t15118: \"v2g-secc\",\n\t15345: \"xpilot\",\n\t15363: \"3link\",\n\t15555: \"cisco-snat\",\n\t15660: \"bex-xr\",\n\t15740: \"ptp\",\n\t15998: \"2ping\",\n\t16003: \"alfin\",\n\t16161: \"sun-sea-port\",\n\t16309: \"etb4j\",\n\t16310: \"pduncs\",\n\t16311: \"pdefmns\",\n\t16360: \"netserialext1\",\n\t16361: \"netserialext2\",\n\t16367: \"netserialext3\",\n\t16368: \"netserialext4\",\n\t16384: \"connected\",\n\t16666: \"vtp\",\n\t16900: \"newbay-snc-mc\",\n\t16950: \"sgcip\",\n\t16991: \"intel-rci-mp\",\n\t16992: \"amt-soap-http\",\n\t16993: \"amt-soap-https\",\n\t16994: \"amt-redir-tcp\",\n\t16995: \"amt-redir-tls\",\n\t17007: \"isode-dua\",\n\t17185: \"soundsvirtual\",\n\t17219: \"chipper\",\n\t17220: \"avtp\",\n\t17221: \"avdecc\",\n\t17222: \"cpsp\",\n\t17224: \"trdp-pd\",\n\t17225: \"trdp-md\",\n\t17234: \"integrius-stp\",\n\t17235: \"ssh-mgmt\",\n\t17500: \"db-lsp-disc\",\n\t17729: \"ea\",\n\t17754: \"zep\",\n\t17755: \"zigbee-ip\",\n\t17756: \"zigbee-ips\",\n\t18000: \"biimenu\",\n\t18181: \"opsec-cvp\",\n\t18182: \"opsec-ufp\",\n\t18183: \"opsec-sam\",\n\t18184: \"opsec-lea\",\n\t18185: \"opsec-omi\",\n\t18186: \"ohsc\",\n\t18187: \"opsec-ela\",\n\t18241: \"checkpoint-rtm\",\n\t18262: \"gv-pf\",\n\t18463: \"ac-cluster\",\n\t18634: \"rds-ib\",\n\t18635: \"rds-ip\",\n\t18668: \"vdmmesh-disc\",\n\t18769: \"ique\",\n\t18881: \"infotos\",\n\t18888: \"apc-necmp\",\n\t19000: \"igrid\",\n\t19007: \"scintilla\",\n\t19191: \"opsec-uaa\",\n\t19194: \"ua-secureagent\",\n\t19220: \"cora-disc\",\n\t19283: \"keysrvr\",\n\t19315: \"keyshadow\",\n\t19398: \"mtrgtrans\",\n\t19410: \"hp-sco\",\n\t19411: \"hp-sca\",\n\t19412: \"hp-sessmon\",\n\t19539: \"fxuptp\",\n\t19540: \"sxuptp\",\n\t19541: \"jcp\",\n\t19788: \"mle\",\n\t19999: \"dnp-sec\",\n\t20000: \"dnp\",\n\t20001: \"microsan\",\n\t20002: \"commtact-http\",\n\t20003: \"commtact-https\",\n\t20005: \"openwebnet\",\n\t20012: \"ss-idi-disc\",\n\t20014: \"opendeploy\",\n\t20034: \"nburn-id\",\n\t20046: \"tmophl7mts\",\n\t20048: \"mountd\",\n\t20049: \"nfsrdma\",\n\t20167: \"tolfab\",\n\t20202: \"ipdtp-port\",\n\t20222: \"ipulse-ics\",\n\t20480: \"emwavemsg\",\n\t20670: \"track\",\n\t20999: \"athand-mmp\",\n\t21000: \"irtrans\",\n\t21554: \"dfserver\",\n\t21590: \"vofr-gateway\",\n\t21800: \"tvpm\",\n\t21845: \"webphone\",\n\t21846: \"netspeak-is\",\n\t21847: \"netspeak-cs\",\n\t21848: \"netspeak-acd\",\n\t21849: \"netspeak-cps\",\n\t22000: \"snapenetio\",\n\t22001: \"optocontrol\",\n\t22002: \"optohost002\",\n\t22003: \"optohost003\",\n\t22004: \"optohost004\",\n\t22005: \"optohost004\",\n\t22273: \"wnn6\",\n\t22305: \"cis\",\n\t22335: \"shrewd-stream\",\n\t22343: \"cis-secure\",\n\t22347: \"wibukey\",\n\t22350: \"codemeter\",\n\t22555: \"vocaltec-phone\",\n\t22763: \"talikaserver\",\n\t22800: \"aws-brf\",\n\t22951: \"brf-gw\",\n\t23000: \"inovaport1\",\n\t23001: \"inovaport2\",\n\t23002: \"inovaport3\",\n\t23003: \"inovaport4\",\n\t23004: \"inovaport5\",\n\t23005: \"inovaport6\",\n\t23272: \"s102\",\n\t23294: \"5afe-disc\",\n\t23333: \"elxmgmt\",\n\t23400: \"novar-dbase\",\n\t23401: \"novar-alarm\",\n\t23402: \"novar-global\",\n\t24000: \"med-ltp\",\n\t24001: \"med-fsp-rx\",\n\t24002: \"med-fsp-tx\",\n\t24003: \"med-supp\",\n\t24004: \"med-ovw\",\n\t24005: \"med-ci\",\n\t24006: \"med-net-svc\",\n\t24242: \"filesphere\",\n\t24249: \"vista-4gl\",\n\t24321: \"ild\",\n\t24322: \"hid\",\n\t24386: \"intel-rci\",\n\t24465: \"tonidods\",\n\t24554: \"binkp\",\n\t24577: \"bilobit-update\",\n\t24676: \"canditv\",\n\t24677: \"flashfiler\",\n\t24678: \"proactivate\",\n\t24680: \"tcc-http\",\n\t24850: \"assoc-disc\",\n\t24922: \"find\",\n\t25000: \"icl-twobase1\",\n\t25001: \"icl-twobase2\",\n\t25002: \"icl-twobase3\",\n\t25003: \"icl-twobase4\",\n\t25004: \"icl-twobase5\",\n\t25005: \"icl-twobase6\",\n\t25006: \"icl-twobase7\",\n\t25007: \"icl-twobase8\",\n\t25008: \"icl-twobase9\",\n\t25009: \"icl-twobase10\",\n\t25793: \"vocaltec-hos\",\n\t25900: \"tasp-net\",\n\t25901: \"niobserver\",\n\t25902: \"nilinkanalyst\",\n\t25903: \"niprobe\",\n\t25954: \"bf-game\",\n\t25955: \"bf-master\",\n\t26000: \"quake\",\n\t26133: \"scscp\",\n\t26208: \"wnn6-ds\",\n\t26260: \"ezproxy\",\n\t26261: \"ezmeeting\",\n\t26262: \"k3software-svr\",\n\t26263: \"k3software-cli\",\n\t26486: \"exoline-udp\",\n\t26487: \"exoconfig\",\n\t26489: \"exonet\",\n\t27345: \"imagepump\",\n\t27442: \"jesmsjc\",\n\t27504: \"kopek-httphead\",\n\t27782: \"ars-vista\",\n\t27999: \"tw-auth-key\",\n\t28000: \"nxlmd\",\n\t28119: \"a27-ran-ran\",\n\t28200: \"voxelstorm\",\n\t28240: \"siemensgsm\",\n\t29167: \"otmp\",\n\t30001: \"pago-services1\",\n\t30002: \"pago-services2\",\n\t30003: \"amicon-fpsu-ra\",\n\t30004: \"amicon-fpsu-s\",\n\t30260: \"kingdomsonline\",\n\t30832: \"samsung-disc\",\n\t30999: \"ovobs\",\n\t31016: \"ka-kdp\",\n\t31029: \"yawn\",\n\t31416: \"xqosd\",\n\t31457: \"tetrinet\",\n\t31620: \"lm-mon\",\n\t31765: \"gamesmith-port\",\n\t31948: \"iceedcp-tx\",\n\t31949: \"iceedcp-rx\",\n\t32034: \"iracinghelper\",\n\t32249: \"t1distproc60\",\n\t32483: \"apm-link\",\n\t32635: \"sec-ntb-clnt\",\n\t32636: \"DMExpress\",\n\t32767: \"filenet-powsrm\",\n\t32768: \"filenet-tms\",\n\t32769: \"filenet-rpc\",\n\t32770: \"filenet-nch\",\n\t32771: \"filenet-rmi\",\n\t32772: \"filenet-pa\",\n\t32773: \"filenet-cm\",\n\t32774: \"filenet-re\",\n\t32775: \"filenet-pch\",\n\t32776: \"filenet-peior\",\n\t32777: \"filenet-obrok\",\n\t32801: \"mlsn\",\n\t32896: \"idmgratm\",\n\t33123: \"aurora-balaena\",\n\t33331: \"diamondport\",\n\t33334: \"speedtrace-disc\",\n\t33434: \"traceroute\",\n\t33656: \"snip-slave\",\n\t34249: \"turbonote-2\",\n\t34378: \"p-net-local\",\n\t34379: \"p-net-remote\",\n\t34567: \"edi_service\",\n\t34962: \"profinet-rt\",\n\t34963: \"profinet-rtm\",\n\t34964: \"profinet-cm\",\n\t34980: \"ethercat\",\n\t35001: \"rt-viewer\",\n\t35004: \"rt-classmanager\",\n\t35100: \"axio-disc\",\n\t35355: \"altova-lm-disc\",\n\t36001: \"allpeers\",\n\t36411: \"wlcp\",\n\t36865: \"kastenxpipe\",\n\t37475: \"neckar\",\n\t37654: \"unisys-eportal\",\n\t38002: \"crescoctrl-disc\",\n\t38201: \"galaxy7-data\",\n\t38202: \"fairview\",\n\t38203: \"agpolicy\",\n\t39681: \"turbonote-1\",\n\t40000: \"safetynetp\",\n\t40023: \"k-patentssensor\",\n\t40841: \"cscp\",\n\t40842: \"csccredir\",\n\t40843: \"csccfirewall\",\n\t40853: \"ortec-disc\",\n\t41111: \"fs-qos\",\n\t41230: \"z-wave-s\",\n\t41794: \"crestron-cip\",\n\t41795: \"crestron-ctp\",\n\t42508: \"candp\",\n\t42509: \"candrp\",\n\t42510: \"caerpc\",\n\t43000: \"recvr-rc-disc\",\n\t43188: \"reachout\",\n\t43189: \"ndm-agent-port\",\n\t43190: \"ip-provision\",\n\t43210: \"shaperai-disc\",\n\t43439: \"eq3-config\",\n\t43440: \"ew-disc-cmd\",\n\t43441: \"ciscocsdb\",\n\t44321: \"pmcd\",\n\t44322: \"pmcdproxy\",\n\t44544: \"domiq\",\n\t44553: \"rbr-debug\",\n\t44600: \"asihpi\",\n\t44818: \"EtherNet-IP-2\",\n\t44900: \"m3da-disc\",\n\t45000: \"asmp-mon\",\n\t45054: \"invision-ag\",\n\t45514: \"cloudcheck-ping\",\n\t45678: \"eba\",\n\t45825: \"qdb2service\",\n\t45966: \"ssr-servermgr\",\n\t46999: \"mediabox\",\n\t47000: \"mbus\",\n\t47100: \"jvl-mactalk\",\n\t47557: \"dbbrowse\",\n\t47624: \"directplaysrvr\",\n\t47806: \"ap\",\n\t47808: \"bacnet\",\n\t47809: \"presonus-ucnet\",\n\t48000: \"nimcontroller\",\n\t48001: \"nimspooler\",\n\t48002: \"nimhub\",\n\t48003: \"nimgtw\",\n\t48128: \"isnetserv\",\n\t48129: \"blp5\",\n\t48556: \"com-bardac-dw\",\n\t48619: \"iqobject\",\n\t48653: \"robotraconteur\",\n\t49001: \"nusdp-disc\",\n}\nvar sctpPortNames = map[SCTPPort]string{\n\t9:     \"discard\",\n\t20:    \"ftp-data\",\n\t21:    \"ftp\",\n\t22:    \"ssh\",\n\t80:    \"http\",\n\t179:   \"bgp\",\n\t443:   \"https\",\n\t1021:  \"exp1\",\n\t1022:  \"exp2\",\n\t1167:  \"cisco-ipsla\",\n\t1720:  \"h323hostcall\",\n\t2049:  \"nfs\",\n\t2225:  \"rcip-itu\",\n\t2904:  \"m2ua\",\n\t2905:  \"m3ua\",\n\t2944:  \"megaco-h248\",\n\t2945:  \"h248-binary\",\n\t3097:  \"itu-bicc-stc\",\n\t3565:  \"m2pa\",\n\t3863:  \"asap-sctp\",\n\t3864:  \"asap-sctp-tls\",\n\t3868:  \"diameter\",\n\t4333:  \"ahsp\",\n\t4502:  \"a25-fap-fgw\",\n\t4711:  \"trinity-dist\",\n\t4739:  \"ipfix\",\n\t4740:  \"ipfixs\",\n\t5060:  \"sip\",\n\t5061:  \"sips\",\n\t5090:  \"car\",\n\t5091:  \"cxtp\",\n\t5215:  \"noteza\",\n\t5445:  \"smbdirect\",\n\t5672:  \"amqp\",\n\t5675:  \"v5ua\",\n\t5868:  \"diameters\",\n\t5910:  \"cm\",\n\t5911:  \"cpdlc\",\n\t5912:  \"fis\",\n\t5913:  \"ads-c\",\n\t6704:  \"frc-hp\",\n\t6705:  \"frc-mp\",\n\t6706:  \"frc-lp\",\n\t6970:  \"conductor-mpx\",\n\t7626:  \"simco\",\n\t7701:  \"nfapi\",\n\t7728:  \"osvr\",\n\t8471:  \"pim-port\",\n\t9082:  \"lcs-ap\",\n\t9084:  \"aurora\",\n\t9900:  \"iua\",\n\t9901:  \"enrp-sctp\",\n\t9902:  \"enrp-sctp-tls\",\n\t11997: \"wmereceiving\",\n\t11998: \"wmedistribution\",\n\t11999: \"wmereporting\",\n\t14001: \"sua\",\n\t20049: \"nfsrdma\",\n\t25471: \"rna\",\n\t29118: \"sgsap\",\n\t29168: \"sbcap\",\n\t29169: \"iuhsctpassoc\",\n\t30100: \"rwp\",\n\t36412: \"s1-control\",\n\t36422: \"x2-control\",\n\t36423: \"slmap\",\n\t36424: \"nq-ap\",\n\t36443: \"m2ap\",\n\t36444: \"m3ap\",\n\t36462: \"xw-control\",\n\t38412: \"ng-control\",\n\t38422: \"xn-control\",\n\t38472: \"f1-control\",\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/icmp4.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n// Copyright 2009-2011 Andreas Krennmair. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\n\t\"github.com/google/gopacket\"\n)\n\nconst (\n\tICMPv4TypeEchoReply              = 0\n\tICMPv4TypeDestinationUnreachable = 3\n\tICMPv4TypeSourceQuench           = 4\n\tICMPv4TypeRedirect               = 5\n\tICMPv4TypeEchoRequest            = 8\n\tICMPv4TypeRouterAdvertisement    = 9\n\tICMPv4TypeRouterSolicitation     = 10\n\tICMPv4TypeTimeExceeded           = 11\n\tICMPv4TypeParameterProblem       = 12\n\tICMPv4TypeTimestampRequest       = 13\n\tICMPv4TypeTimestampReply         = 14\n\tICMPv4TypeInfoRequest            = 15\n\tICMPv4TypeInfoReply              = 16\n\tICMPv4TypeAddressMaskRequest     = 17\n\tICMPv4TypeAddressMaskReply       = 18\n)\n\nconst (\n\t// DestinationUnreachable\n\tICMPv4CodeNet                 = 0\n\tICMPv4CodeHost                = 1\n\tICMPv4CodeProtocol            = 2\n\tICMPv4CodePort                = 3\n\tICMPv4CodeFragmentationNeeded = 4\n\tICMPv4CodeSourceRoutingFailed = 5\n\tICMPv4CodeNetUnknown          = 6\n\tICMPv4CodeHostUnknown         = 7\n\tICMPv4CodeSourceIsolated      = 8\n\tICMPv4CodeNetAdminProhibited  = 9\n\tICMPv4CodeHostAdminProhibited = 10\n\tICMPv4CodeNetTOS              = 11\n\tICMPv4CodeHostTOS             = 12\n\tICMPv4CodeCommAdminProhibited = 13\n\tICMPv4CodeHostPrecedence      = 14\n\tICMPv4CodePrecedenceCutoff    = 15\n\n\t// TimeExceeded\n\tICMPv4CodeTTLExceeded                    = 0\n\tICMPv4CodeFragmentReassemblyTimeExceeded = 1\n\n\t// ParameterProblem\n\tICMPv4CodePointerIndicatesError = 0\n\tICMPv4CodeMissingOption         = 1\n\tICMPv4CodeBadLength             = 2\n\n\t// Redirect\n\t// ICMPv4CodeNet  = same as for DestinationUnreachable\n\t// ICMPv4CodeHost = same as for DestinationUnreachable\n\tICMPv4CodeTOSNet  = 2\n\tICMPv4CodeTOSHost = 3\n)\n\ntype icmpv4TypeCodeInfoStruct struct {\n\ttypeStr string\n\tcodeStr *map[uint8]string\n}\n\nvar (\n\ticmpv4TypeCodeInfo = map[uint8]icmpv4TypeCodeInfoStruct{\n\t\tICMPv4TypeDestinationUnreachable: icmpv4TypeCodeInfoStruct{\n\t\t\t\"DestinationUnreachable\", &map[uint8]string{\n\t\t\t\tICMPv4CodeNet:                 \"Net\",\n\t\t\t\tICMPv4CodeHost:                \"Host\",\n\t\t\t\tICMPv4CodeProtocol:            \"Protocol\",\n\t\t\t\tICMPv4CodePort:                \"Port\",\n\t\t\t\tICMPv4CodeFragmentationNeeded: \"FragmentationNeeded\",\n\t\t\t\tICMPv4CodeSourceRoutingFailed: \"SourceRoutingFailed\",\n\t\t\t\tICMPv4CodeNetUnknown:          \"NetUnknown\",\n\t\t\t\tICMPv4CodeHostUnknown:         \"HostUnknown\",\n\t\t\t\tICMPv4CodeSourceIsolated:      \"SourceIsolated\",\n\t\t\t\tICMPv4CodeNetAdminProhibited:  \"NetAdminProhibited\",\n\t\t\t\tICMPv4CodeHostAdminProhibited: \"HostAdminProhibited\",\n\t\t\t\tICMPv4CodeNetTOS:              \"NetTOS\",\n\t\t\t\tICMPv4CodeHostTOS:             \"HostTOS\",\n\t\t\t\tICMPv4CodeCommAdminProhibited: \"CommAdminProhibited\",\n\t\t\t\tICMPv4CodeHostPrecedence:      \"HostPrecedence\",\n\t\t\t\tICMPv4CodePrecedenceCutoff:    \"PrecedenceCutoff\",\n\t\t\t},\n\t\t},\n\t\tICMPv4TypeTimeExceeded: icmpv4TypeCodeInfoStruct{\n\t\t\t\"TimeExceeded\", &map[uint8]string{\n\t\t\t\tICMPv4CodeTTLExceeded:                    \"TTLExceeded\",\n\t\t\t\tICMPv4CodeFragmentReassemblyTimeExceeded: \"FragmentReassemblyTimeExceeded\",\n\t\t\t},\n\t\t},\n\t\tICMPv4TypeParameterProblem: icmpv4TypeCodeInfoStruct{\n\t\t\t\"ParameterProblem\", &map[uint8]string{\n\t\t\t\tICMPv4CodePointerIndicatesError: \"PointerIndicatesError\",\n\t\t\t\tICMPv4CodeMissingOption:         \"MissingOption\",\n\t\t\t\tICMPv4CodeBadLength:             \"BadLength\",\n\t\t\t},\n\t\t},\n\t\tICMPv4TypeSourceQuench: icmpv4TypeCodeInfoStruct{\n\t\t\t\"SourceQuench\", nil,\n\t\t},\n\t\tICMPv4TypeRedirect: icmpv4TypeCodeInfoStruct{\n\t\t\t\"Redirect\", &map[uint8]string{\n\t\t\t\tICMPv4CodeNet:     \"Net\",\n\t\t\t\tICMPv4CodeHost:    \"Host\",\n\t\t\t\tICMPv4CodeTOSNet:  \"TOS+Net\",\n\t\t\t\tICMPv4CodeTOSHost: \"TOS+Host\",\n\t\t\t},\n\t\t},\n\t\tICMPv4TypeEchoRequest: icmpv4TypeCodeInfoStruct{\n\t\t\t\"EchoRequest\", nil,\n\t\t},\n\t\tICMPv4TypeEchoReply: icmpv4TypeCodeInfoStruct{\n\t\t\t\"EchoReply\", nil,\n\t\t},\n\t\tICMPv4TypeTimestampRequest: icmpv4TypeCodeInfoStruct{\n\t\t\t\"TimestampRequest\", nil,\n\t\t},\n\t\tICMPv4TypeTimestampReply: icmpv4TypeCodeInfoStruct{\n\t\t\t\"TimestampReply\", nil,\n\t\t},\n\t\tICMPv4TypeInfoRequest: icmpv4TypeCodeInfoStruct{\n\t\t\t\"InfoRequest\", nil,\n\t\t},\n\t\tICMPv4TypeInfoReply: icmpv4TypeCodeInfoStruct{\n\t\t\t\"InfoReply\", nil,\n\t\t},\n\t\tICMPv4TypeRouterSolicitation: icmpv4TypeCodeInfoStruct{\n\t\t\t\"RouterSolicitation\", nil,\n\t\t},\n\t\tICMPv4TypeRouterAdvertisement: icmpv4TypeCodeInfoStruct{\n\t\t\t\"RouterAdvertisement\", nil,\n\t\t},\n\t\tICMPv4TypeAddressMaskRequest: icmpv4TypeCodeInfoStruct{\n\t\t\t\"AddressMaskRequest\", nil,\n\t\t},\n\t\tICMPv4TypeAddressMaskReply: icmpv4TypeCodeInfoStruct{\n\t\t\t\"AddressMaskReply\", nil,\n\t\t},\n\t}\n)\n\ntype ICMPv4TypeCode uint16\n\n// Type returns the ICMPv4 type field.\nfunc (a ICMPv4TypeCode) Type() uint8 {\n\treturn uint8(a >> 8)\n}\n\n// Code returns the ICMPv4 code field.\nfunc (a ICMPv4TypeCode) Code() uint8 {\n\treturn uint8(a)\n}\n\nfunc (a ICMPv4TypeCode) String() string {\n\tt, c := a.Type(), a.Code()\n\tstrInfo, ok := icmpv4TypeCodeInfo[t]\n\tif !ok {\n\t\t// Unknown ICMPv4 type field\n\t\treturn fmt.Sprintf(\"%d(%d)\", t, c)\n\t}\n\ttypeStr := strInfo.typeStr\n\tif strInfo.codeStr == nil && c == 0 {\n\t\t// The ICMPv4 type does not make use of the code field\n\t\treturn fmt.Sprintf(\"%s\", strInfo.typeStr)\n\t}\n\tif strInfo.codeStr == nil && c != 0 {\n\t\t// The ICMPv4 type does not make use of the code field, but it is present anyway\n\t\treturn fmt.Sprintf(\"%s(Code: %d)\", typeStr, c)\n\t}\n\tcodeStr, ok := (*strInfo.codeStr)[c]\n\tif !ok {\n\t\t// We don't know this ICMPv4 code; print the numerical value\n\t\treturn fmt.Sprintf(\"%s(Code: %d)\", typeStr, c)\n\t}\n\treturn fmt.Sprintf(\"%s(%s)\", typeStr, codeStr)\n}\n\nfunc (a ICMPv4TypeCode) GoString() string {\n\tt := reflect.TypeOf(a)\n\treturn fmt.Sprintf(\"%s(%d, %d)\", t.String(), a.Type(), a.Code())\n}\n\n// SerializeTo writes the ICMPv4TypeCode value to the 'bytes' buffer.\nfunc (a ICMPv4TypeCode) SerializeTo(bytes []byte) {\n\tbinary.BigEndian.PutUint16(bytes, uint16(a))\n}\n\n// CreateICMPv4TypeCode is a convenience function to create an ICMPv4TypeCode\n// gopacket type from the ICMPv4 type and code values.\nfunc CreateICMPv4TypeCode(typ uint8, code uint8) ICMPv4TypeCode {\n\treturn ICMPv4TypeCode(binary.BigEndian.Uint16([]byte{typ, code}))\n}\n\n// ICMPv4 is the layer for IPv4 ICMP packet data.\ntype ICMPv4 struct {\n\tBaseLayer\n\tTypeCode ICMPv4TypeCode\n\tChecksum uint16\n\tId       uint16\n\tSeq      uint16\n}\n\n// LayerType returns LayerTypeICMPv4.\nfunc (i *ICMPv4) LayerType() gopacket.LayerType { return LayerTypeICMPv4 }\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (i *ICMPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 8 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"ICMP layer less then 8 bytes for ICMPv4 packet\")\n\t}\n\ti.TypeCode = CreateICMPv4TypeCode(data[0], data[1])\n\ti.Checksum = binary.BigEndian.Uint16(data[2:4])\n\ti.Id = binary.BigEndian.Uint16(data[4:6])\n\ti.Seq = binary.BigEndian.Uint16(data[6:8])\n\ti.BaseLayer = BaseLayer{data[:8], data[8:]}\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (i *ICMPv4) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbytes, err := b.PrependBytes(8)\n\tif err != nil {\n\t\treturn err\n\t}\n\ti.TypeCode.SerializeTo(bytes)\n\tbinary.BigEndian.PutUint16(bytes[4:], i.Id)\n\tbinary.BigEndian.PutUint16(bytes[6:], i.Seq)\n\tif opts.ComputeChecksums {\n\t\tbytes[2] = 0\n\t\tbytes[3] = 0\n\t\ti.Checksum = tcpipChecksum(b.Bytes(), 0)\n\t}\n\tbinary.BigEndian.PutUint16(bytes[2:], i.Checksum)\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (i *ICMPv4) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeICMPv4\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (i *ICMPv4) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\nfunc decodeICMPv4(data []byte, p gopacket.PacketBuilder) error {\n\ti := &ICMPv4{}\n\treturn decodingLayerDecoder(i, data, p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/icmp6.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n// Copyright 2009-2011 Andreas Krennmair. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\n\t\"github.com/google/gopacket\"\n)\n\nconst (\n\t// The following are from RFC 4443\n\tICMPv6TypeDestinationUnreachable = 1\n\tICMPv6TypePacketTooBig           = 2\n\tICMPv6TypeTimeExceeded           = 3\n\tICMPv6TypeParameterProblem       = 4\n\tICMPv6TypeEchoRequest            = 128\n\tICMPv6TypeEchoReply              = 129\n\n\t// The following are from RFC 4861\n\tICMPv6TypeRouterSolicitation    = 133\n\tICMPv6TypeRouterAdvertisement   = 134\n\tICMPv6TypeNeighborSolicitation  = 135\n\tICMPv6TypeNeighborAdvertisement = 136\n\tICMPv6TypeRedirect              = 137\n\n\t// The following are from RFC 2710\n\tICMPv6TypeMLDv1MulticastListenerQueryMessage  = 130\n\tICMPv6TypeMLDv1MulticastListenerReportMessage = 131\n\tICMPv6TypeMLDv1MulticastListenerDoneMessage   = 132\n\n\t// The following are from RFC 3810\n\tICMPv6TypeMLDv2MulticastListenerReportMessageV2 = 143\n)\n\nconst (\n\t// DestinationUnreachable\n\tICMPv6CodeNoRouteToDst           = 0\n\tICMPv6CodeAdminProhibited        = 1\n\tICMPv6CodeBeyondScopeOfSrc       = 2\n\tICMPv6CodeAddressUnreachable     = 3\n\tICMPv6CodePortUnreachable        = 4\n\tICMPv6CodeSrcAddressFailedPolicy = 5\n\tICMPv6CodeRejectRouteToDst       = 6\n\n\t// TimeExceeded\n\tICMPv6CodeHopLimitExceeded               = 0\n\tICMPv6CodeFragmentReassemblyTimeExceeded = 1\n\n\t// ParameterProblem\n\tICMPv6CodeErroneousHeaderField   = 0\n\tICMPv6CodeUnrecognizedNextHeader = 1\n\tICMPv6CodeUnrecognizedIPv6Option = 2\n)\n\ntype icmpv6TypeCodeInfoStruct struct {\n\ttypeStr string\n\tcodeStr *map[uint8]string\n}\n\nvar (\n\ticmpv6TypeCodeInfo = map[uint8]icmpv6TypeCodeInfoStruct{\n\t\tICMPv6TypeDestinationUnreachable: icmpv6TypeCodeInfoStruct{\n\t\t\t\"DestinationUnreachable\", &map[uint8]string{\n\t\t\t\tICMPv6CodeNoRouteToDst:           \"NoRouteToDst\",\n\t\t\t\tICMPv6CodeAdminProhibited:        \"AdminProhibited\",\n\t\t\t\tICMPv6CodeBeyondScopeOfSrc:       \"BeyondScopeOfSrc\",\n\t\t\t\tICMPv6CodeAddressUnreachable:     \"AddressUnreachable\",\n\t\t\t\tICMPv6CodePortUnreachable:        \"PortUnreachable\",\n\t\t\t\tICMPv6CodeSrcAddressFailedPolicy: \"SrcAddressFailedPolicy\",\n\t\t\t\tICMPv6CodeRejectRouteToDst:       \"RejectRouteToDst\",\n\t\t\t},\n\t\t},\n\t\tICMPv6TypePacketTooBig: icmpv6TypeCodeInfoStruct{\n\t\t\t\"PacketTooBig\", nil,\n\t\t},\n\t\tICMPv6TypeTimeExceeded: icmpv6TypeCodeInfoStruct{\n\t\t\t\"TimeExceeded\", &map[uint8]string{\n\t\t\t\tICMPv6CodeHopLimitExceeded:               \"HopLimitExceeded\",\n\t\t\t\tICMPv6CodeFragmentReassemblyTimeExceeded: \"FragmentReassemblyTimeExceeded\",\n\t\t\t},\n\t\t},\n\t\tICMPv6TypeParameterProblem: icmpv6TypeCodeInfoStruct{\n\t\t\t\"ParameterProblem\", &map[uint8]string{\n\t\t\t\tICMPv6CodeErroneousHeaderField:   \"ErroneousHeaderField\",\n\t\t\t\tICMPv6CodeUnrecognizedNextHeader: \"UnrecognizedNextHeader\",\n\t\t\t\tICMPv6CodeUnrecognizedIPv6Option: \"UnrecognizedIPv6Option\",\n\t\t\t},\n\t\t},\n\t\tICMPv6TypeEchoRequest: icmpv6TypeCodeInfoStruct{\n\t\t\t\"EchoRequest\", nil,\n\t\t},\n\t\tICMPv6TypeEchoReply: icmpv6TypeCodeInfoStruct{\n\t\t\t\"EchoReply\", nil,\n\t\t},\n\t\tICMPv6TypeRouterSolicitation: icmpv6TypeCodeInfoStruct{\n\t\t\t\"RouterSolicitation\", nil,\n\t\t},\n\t\tICMPv6TypeRouterAdvertisement: icmpv6TypeCodeInfoStruct{\n\t\t\t\"RouterAdvertisement\", nil,\n\t\t},\n\t\tICMPv6TypeNeighborSolicitation: icmpv6TypeCodeInfoStruct{\n\t\t\t\"NeighborSolicitation\", nil,\n\t\t},\n\t\tICMPv6TypeNeighborAdvertisement: icmpv6TypeCodeInfoStruct{\n\t\t\t\"NeighborAdvertisement\", nil,\n\t\t},\n\t\tICMPv6TypeRedirect: icmpv6TypeCodeInfoStruct{\n\t\t\t\"Redirect\", nil,\n\t\t},\n\t}\n)\n\ntype ICMPv6TypeCode uint16\n\n// Type returns the ICMPv6 type field.\nfunc (a ICMPv6TypeCode) Type() uint8 {\n\treturn uint8(a >> 8)\n}\n\n// Code returns the ICMPv6 code field.\nfunc (a ICMPv6TypeCode) Code() uint8 {\n\treturn uint8(a)\n}\n\nfunc (a ICMPv6TypeCode) String() string {\n\tt, c := a.Type(), a.Code()\n\tstrInfo, ok := icmpv6TypeCodeInfo[t]\n\tif !ok {\n\t\t// Unknown ICMPv6 type field\n\t\treturn fmt.Sprintf(\"%d(%d)\", t, c)\n\t}\n\ttypeStr := strInfo.typeStr\n\tif strInfo.codeStr == nil && c == 0 {\n\t\t// The ICMPv6 type does not make use of the code field\n\t\treturn fmt.Sprintf(\"%s\", strInfo.typeStr)\n\t}\n\tif strInfo.codeStr == nil && c != 0 {\n\t\t// The ICMPv6 type does not make use of the code field, but it is present anyway\n\t\treturn fmt.Sprintf(\"%s(Code: %d)\", typeStr, c)\n\t}\n\tcodeStr, ok := (*strInfo.codeStr)[c]\n\tif !ok {\n\t\t// We don't know this ICMPv6 code; print the numerical value\n\t\treturn fmt.Sprintf(\"%s(Code: %d)\", typeStr, c)\n\t}\n\treturn fmt.Sprintf(\"%s(%s)\", typeStr, codeStr)\n}\n\nfunc (a ICMPv6TypeCode) GoString() string {\n\tt := reflect.TypeOf(a)\n\treturn fmt.Sprintf(\"%s(%d, %d)\", t.String(), a.Type(), a.Code())\n}\n\n// SerializeTo writes the ICMPv6TypeCode value to the 'bytes' buffer.\nfunc (a ICMPv6TypeCode) SerializeTo(bytes []byte) {\n\tbinary.BigEndian.PutUint16(bytes, uint16(a))\n}\n\n// CreateICMPv6TypeCode is a convenience function to create an ICMPv6TypeCode\n// gopacket type from the ICMPv6 type and code values.\nfunc CreateICMPv6TypeCode(typ uint8, code uint8) ICMPv6TypeCode {\n\treturn ICMPv6TypeCode(binary.BigEndian.Uint16([]byte{typ, code}))\n}\n\n// ICMPv6 is the layer for IPv6 ICMP packet data\ntype ICMPv6 struct {\n\tBaseLayer\n\tTypeCode ICMPv6TypeCode\n\tChecksum uint16\n\t// TypeBytes is deprecated and always nil. See the different ICMPv6 message types\n\t// instead (e.g. ICMPv6TypeRouterSolicitation).\n\tTypeBytes []byte\n\ttcpipchecksum\n}\n\n// LayerType returns LayerTypeICMPv6.\nfunc (i *ICMPv6) LayerType() gopacket.LayerType { return LayerTypeICMPv6 }\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (i *ICMPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 4 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"ICMP layer less then 4 bytes for ICMPv6 packet\")\n\t}\n\ti.TypeCode = CreateICMPv6TypeCode(data[0], data[1])\n\ti.Checksum = binary.BigEndian.Uint16(data[2:4])\n\ti.BaseLayer = BaseLayer{data[:4], data[4:]}\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (i *ICMPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbytes, err := b.PrependBytes(4)\n\tif err != nil {\n\t\treturn err\n\t}\n\ti.TypeCode.SerializeTo(bytes)\n\n\tif opts.ComputeChecksums {\n\t\tbytes[2] = 0\n\t\tbytes[3] = 0\n\t\tcsum, err := i.computeChecksum(b.Bytes(), IPProtocolICMPv6)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\ti.Checksum = csum\n\t}\n\tbinary.BigEndian.PutUint16(bytes[2:], i.Checksum)\n\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (i *ICMPv6) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeICMPv6\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (i *ICMPv6) NextLayerType() gopacket.LayerType {\n\tswitch i.TypeCode.Type() {\n\tcase ICMPv6TypeEchoRequest:\n\t\treturn LayerTypeICMPv6Echo\n\tcase ICMPv6TypeEchoReply:\n\t\treturn LayerTypeICMPv6Echo\n\tcase ICMPv6TypeRouterSolicitation:\n\t\treturn LayerTypeICMPv6RouterSolicitation\n\tcase ICMPv6TypeRouterAdvertisement:\n\t\treturn LayerTypeICMPv6RouterAdvertisement\n\tcase ICMPv6TypeNeighborSolicitation:\n\t\treturn LayerTypeICMPv6NeighborSolicitation\n\tcase ICMPv6TypeNeighborAdvertisement:\n\t\treturn LayerTypeICMPv6NeighborAdvertisement\n\tcase ICMPv6TypeRedirect:\n\t\treturn LayerTypeICMPv6Redirect\n\tcase ICMPv6TypeMLDv1MulticastListenerQueryMessage: // Same Code for MLDv1 Query and MLDv2 Query\n\t\tif len(i.Payload) > 20 { // Only payload size differs\n\t\t\treturn LayerTypeMLDv2MulticastListenerQuery\n\t\t} else {\n\t\t\treturn LayerTypeMLDv1MulticastListenerQuery\n\t\t}\n\tcase ICMPv6TypeMLDv1MulticastListenerDoneMessage:\n\t\treturn LayerTypeMLDv1MulticastListenerDone\n\tcase ICMPv6TypeMLDv1MulticastListenerReportMessage:\n\t\treturn LayerTypeMLDv1MulticastListenerReport\n\tcase ICMPv6TypeMLDv2MulticastListenerReportMessageV2:\n\t\treturn LayerTypeMLDv2MulticastListenerReport\n\t}\n\n\treturn gopacket.LayerTypePayload\n}\n\nfunc decodeICMPv6(data []byte, p gopacket.PacketBuilder) error {\n\ti := &ICMPv6{}\n\treturn decodingLayerDecoder(i, data, p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/icmp6msg.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n// Copyright 2009-2011 Andreas Krennmair. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// Based on RFC 4861\n\n// ICMPv6Opt indicate how to decode the data associated with each ICMPv6Option.\ntype ICMPv6Opt uint8\n\nconst (\n\t_ ICMPv6Opt = iota\n\n\t// ICMPv6OptSourceAddress contains the link-layer address of the sender of\n\t// the packet. It is used in the Neighbor Solicitation, Router\n\t// Solicitation, and Router Advertisement packets. Must be ignored for other\n\t// Neighbor discovery messages.\n\tICMPv6OptSourceAddress\n\n\t// ICMPv6OptTargetAddress contains the link-layer address of the target. It\n\t// is used in Neighbor Advertisement and Redirect packets. Must be ignored\n\t// for other Neighbor discovery messages.\n\tICMPv6OptTargetAddress\n\n\t// ICMPv6OptPrefixInfo provides hosts with on-link prefixes and prefixes\n\t// for Address Autoconfiguration. The Prefix Information option appears in\n\t// Router Advertisement packets and MUST be silently ignored for other\n\t// messages.\n\tICMPv6OptPrefixInfo\n\n\t// ICMPv6OptRedirectedHeader is used in Redirect messages and contains all\n\t// or part of the packet that is being redirected.\n\tICMPv6OptRedirectedHeader\n\n\t// ICMPv6OptMTU is used in Router Advertisement messages to ensure that all\n\t// nodes on a link use the same MTU value in those cases where the link MTU\n\t// is not well known. This option MUST be silently ignored for other\n\t// Neighbor Discovery messages.\n\tICMPv6OptMTU\n)\n\n// ICMPv6Echo represents the structure of a ping.\ntype ICMPv6Echo struct {\n\tBaseLayer\n\tIdentifier uint16\n\tSeqNumber  uint16\n}\n\n// ICMPv6RouterSolicitation is sent by hosts to find routers.\ntype ICMPv6RouterSolicitation struct {\n\tBaseLayer\n\tOptions ICMPv6Options\n}\n\n// ICMPv6RouterAdvertisement is sent by routers in response to Solicitation.\ntype ICMPv6RouterAdvertisement struct {\n\tBaseLayer\n\tHopLimit       uint8\n\tFlags          uint8\n\tRouterLifetime uint16\n\tReachableTime  uint32\n\tRetransTimer   uint32\n\tOptions        ICMPv6Options\n}\n\n// ICMPv6NeighborSolicitation is sent to request the link-layer address of a\n// target node.\ntype ICMPv6NeighborSolicitation struct {\n\tBaseLayer\n\tTargetAddress net.IP\n\tOptions       ICMPv6Options\n}\n\n// ICMPv6NeighborAdvertisement is sent by nodes in response to Solicitation.\ntype ICMPv6NeighborAdvertisement struct {\n\tBaseLayer\n\tFlags         uint8\n\tTargetAddress net.IP\n\tOptions       ICMPv6Options\n}\n\n// ICMPv6Redirect is sent by routers to inform hosts of a better first-hop node\n// on the path to a destination.\ntype ICMPv6Redirect struct {\n\tBaseLayer\n\tTargetAddress      net.IP\n\tDestinationAddress net.IP\n\tOptions            ICMPv6Options\n}\n\n// ICMPv6Option contains the type and data for a single option.\ntype ICMPv6Option struct {\n\tType ICMPv6Opt\n\tData []byte\n}\n\n// ICMPv6Options is a slice of ICMPv6Option.\ntype ICMPv6Options []ICMPv6Option\n\nfunc (i ICMPv6Opt) String() string {\n\tswitch i {\n\tcase ICMPv6OptSourceAddress:\n\t\treturn \"SourceAddress\"\n\tcase ICMPv6OptTargetAddress:\n\t\treturn \"TargetAddress\"\n\tcase ICMPv6OptPrefixInfo:\n\t\treturn \"PrefixInfo\"\n\tcase ICMPv6OptRedirectedHeader:\n\t\treturn \"RedirectedHeader\"\n\tcase ICMPv6OptMTU:\n\t\treturn \"MTU\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"Unknown(%d)\", i)\n\t}\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (i *ICMPv6Echo) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeICMPv6Echo\n}\n\n// LayerType returns LayerTypeICMPv6Echo.\nfunc (i *ICMPv6Echo) LayerType() gopacket.LayerType {\n\treturn LayerTypeICMPv6Echo\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (i *ICMPv6Echo) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (i *ICMPv6Echo) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 4 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"ICMP layer less then 4 bytes for ICMPv6 Echo\")\n\t}\n\ti.Identifier = binary.BigEndian.Uint16(data[0:2])\n\ti.SeqNumber = binary.BigEndian.Uint16(data[2:4])\n\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (i *ICMPv6Echo) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbuf, err := b.PrependBytes(4)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbinary.BigEndian.PutUint16(buf, i.Identifier)\n\tbinary.BigEndian.PutUint16(buf[2:], i.SeqNumber)\n\treturn nil\n}\n\n// LayerType returns LayerTypeICMPv6.\nfunc (i *ICMPv6RouterSolicitation) LayerType() gopacket.LayerType {\n\treturn LayerTypeICMPv6RouterSolicitation\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (i *ICMPv6RouterSolicitation) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (i *ICMPv6RouterSolicitation) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\t// first 4 bytes are reserved followed by options\n\tif len(data) < 4 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"ICMP layer less then 4 bytes for ICMPv6 router solicitation\")\n\t}\n\n\t// truncate old options\n\ti.Options = i.Options[:0]\n\n\treturn i.Options.DecodeFromBytes(data[4:], df)\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (i *ICMPv6RouterSolicitation) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tif err := i.Options.SerializeTo(b, opts); err != nil {\n\t\treturn err\n\t}\n\n\tbuf, err := b.PrependBytes(4)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcopy(buf, lotsOfZeros[:4])\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (i *ICMPv6RouterSolicitation) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeICMPv6RouterSolicitation\n}\n\n// LayerType returns LayerTypeICMPv6RouterAdvertisement.\nfunc (i *ICMPv6RouterAdvertisement) LayerType() gopacket.LayerType {\n\treturn LayerTypeICMPv6RouterAdvertisement\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (i *ICMPv6RouterAdvertisement) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (i *ICMPv6RouterAdvertisement) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 12 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"ICMP layer less then 12 bytes for ICMPv6 router advertisement\")\n\t}\n\n\ti.HopLimit = uint8(data[0])\n\t// M, O bit followed by 6 reserved bits\n\ti.Flags = uint8(data[1])\n\ti.RouterLifetime = binary.BigEndian.Uint16(data[2:4])\n\ti.ReachableTime = binary.BigEndian.Uint32(data[4:8])\n\ti.RetransTimer = binary.BigEndian.Uint32(data[8:12])\n\ti.BaseLayer = BaseLayer{data, nil} // assume no payload\n\n\t// truncate old options\n\ti.Options = i.Options[:0]\n\n\treturn i.Options.DecodeFromBytes(data[12:], df)\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (i *ICMPv6RouterAdvertisement) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tif err := i.Options.SerializeTo(b, opts); err != nil {\n\t\treturn err\n\t}\n\n\tbuf, err := b.PrependBytes(12)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbuf[0] = byte(i.HopLimit)\n\tbuf[1] = byte(i.Flags)\n\tbinary.BigEndian.PutUint16(buf[2:], i.RouterLifetime)\n\tbinary.BigEndian.PutUint32(buf[4:], i.ReachableTime)\n\tbinary.BigEndian.PutUint32(buf[8:], i.RetransTimer)\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (i *ICMPv6RouterAdvertisement) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeICMPv6RouterAdvertisement\n}\n\n// ManagedAddressConfig is true when addresses are available via DHCPv6. If\n// set, the OtherConfig flag is redundant.\nfunc (i *ICMPv6RouterAdvertisement) ManagedAddressConfig() bool {\n\treturn i.Flags&0x80 != 0\n}\n\n// OtherConfig is true when there is other configuration information available\n// via DHCPv6. For example, DNS-related information.\nfunc (i *ICMPv6RouterAdvertisement) OtherConfig() bool {\n\treturn i.Flags&0x40 != 0\n}\n\n// LayerType returns LayerTypeICMPv6NeighborSolicitation.\nfunc (i *ICMPv6NeighborSolicitation) LayerType() gopacket.LayerType {\n\treturn LayerTypeICMPv6NeighborSolicitation\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (i *ICMPv6NeighborSolicitation) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (i *ICMPv6NeighborSolicitation) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 20 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"ICMP layer less then 20 bytes for ICMPv6 neighbor solicitation\")\n\t}\n\n\ti.TargetAddress = net.IP(data[4:20])\n\ti.BaseLayer = BaseLayer{data, nil} // assume no payload\n\n\t// truncate old options\n\ti.Options = i.Options[:0]\n\n\treturn i.Options.DecodeFromBytes(data[20:], df)\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (i *ICMPv6NeighborSolicitation) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tif err := i.Options.SerializeTo(b, opts); err != nil {\n\t\treturn err\n\t}\n\n\tbuf, err := b.PrependBytes(20)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcopy(buf, lotsOfZeros[:4])\n\tcopy(buf[4:], i.TargetAddress)\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (i *ICMPv6NeighborSolicitation) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeICMPv6NeighborSolicitation\n}\n\n// LayerType returns LayerTypeICMPv6NeighborAdvertisement.\nfunc (i *ICMPv6NeighborAdvertisement) LayerType() gopacket.LayerType {\n\treturn LayerTypeICMPv6NeighborAdvertisement\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (i *ICMPv6NeighborAdvertisement) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (i *ICMPv6NeighborAdvertisement) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 20 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"ICMP layer less then 20 bytes for ICMPv6 neighbor advertisement\")\n\t}\n\n\ti.Flags = uint8(data[0])\n\ti.TargetAddress = net.IP(data[4:20])\n\ti.BaseLayer = BaseLayer{data, nil} // assume no payload\n\n\t// truncate old options\n\ti.Options = i.Options[:0]\n\n\treturn i.Options.DecodeFromBytes(data[20:], df)\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (i *ICMPv6NeighborAdvertisement) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tif err := i.Options.SerializeTo(b, opts); err != nil {\n\t\treturn err\n\t}\n\n\tbuf, err := b.PrependBytes(20)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbuf[0] = byte(i.Flags)\n\tcopy(buf[1:], lotsOfZeros[:3])\n\tcopy(buf[4:], i.TargetAddress)\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (i *ICMPv6NeighborAdvertisement) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeICMPv6NeighborAdvertisement\n}\n\n// Router indicates whether the sender is a router or not.\nfunc (i *ICMPv6NeighborAdvertisement) Router() bool {\n\treturn i.Flags&0x80 != 0\n}\n\n// Solicited indicates whether the advertisement was solicited or not.\nfunc (i *ICMPv6NeighborAdvertisement) Solicited() bool {\n\treturn i.Flags&0x40 != 0\n}\n\n// Override indicates whether the advertisement should Override an existing\n// cache entry.\nfunc (i *ICMPv6NeighborAdvertisement) Override() bool {\n\treturn i.Flags&0x20 != 0\n}\n\n// LayerType returns LayerTypeICMPv6Redirect.\nfunc (i *ICMPv6Redirect) LayerType() gopacket.LayerType {\n\treturn LayerTypeICMPv6Redirect\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (i *ICMPv6Redirect) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (i *ICMPv6Redirect) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 36 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"ICMP layer less then 36 bytes for ICMPv6 redirect\")\n\t}\n\n\ti.TargetAddress = net.IP(data[4:20])\n\ti.DestinationAddress = net.IP(data[20:36])\n\ti.BaseLayer = BaseLayer{data, nil} // assume no payload\n\n\t// truncate old options\n\ti.Options = i.Options[:0]\n\n\treturn i.Options.DecodeFromBytes(data[36:], df)\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (i *ICMPv6Redirect) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tif err := i.Options.SerializeTo(b, opts); err != nil {\n\t\treturn err\n\t}\n\n\tbuf, err := b.PrependBytes(36)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcopy(buf, lotsOfZeros[:4])\n\tcopy(buf[4:], i.TargetAddress)\n\tcopy(buf[20:], i.DestinationAddress)\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (i *ICMPv6Redirect) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeICMPv6Redirect\n}\n\nfunc (i ICMPv6Option) String() string {\n\thd := hex.EncodeToString(i.Data)\n\tif len(hd) > 0 {\n\t\thd = \" 0x\" + hd\n\t}\n\n\tswitch i.Type {\n\tcase ICMPv6OptSourceAddress, ICMPv6OptTargetAddress:\n\t\treturn fmt.Sprintf(\"ICMPv6Option(%s:%v)\",\n\t\t\ti.Type,\n\t\t\tnet.HardwareAddr(i.Data))\n\tcase ICMPv6OptPrefixInfo:\n\t\tif len(i.Data) == 30 {\n\t\t\tprefixLen := uint8(i.Data[0])\n\t\t\tonLink := (i.Data[1]&0x80 != 0)\n\t\t\tautonomous := (i.Data[1]&0x40 != 0)\n\t\t\tvalidLifetime := time.Duration(binary.BigEndian.Uint32(i.Data[2:6])) * time.Second\n\t\t\tpreferredLifetime := time.Duration(binary.BigEndian.Uint32(i.Data[6:10])) * time.Second\n\n\t\t\tprefix := net.IP(i.Data[14:])\n\n\t\t\treturn fmt.Sprintf(\"ICMPv6Option(%s:%v/%v:%t:%t:%v:%v)\",\n\t\t\t\ti.Type,\n\t\t\t\tprefix, prefixLen,\n\t\t\t\tonLink, autonomous,\n\t\t\t\tvalidLifetime, preferredLifetime)\n\t\t}\n\tcase ICMPv6OptRedirectedHeader:\n\t\t// could invoke IP decoder on data... probably best not to\n\t\tbreak\n\tcase ICMPv6OptMTU:\n\t\tif len(i.Data) == 6 {\n\t\t\treturn fmt.Sprintf(\"ICMPv6Option(%s:%v)\",\n\t\t\t\ti.Type,\n\t\t\t\tbinary.BigEndian.Uint32(i.Data[2:]))\n\t\t}\n\n\t}\n\treturn fmt.Sprintf(\"ICMPv6Option(%s:%s)\", i.Type, hd)\n}\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (i *ICMPv6Options) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tfor len(data) > 0 {\n\t\tif len(data) < 2 {\n\t\t\tdf.SetTruncated()\n\t\t\treturn errors.New(\"ICMP layer less then 2 bytes for ICMPv6 message option\")\n\t\t}\n\n\t\t// unit is 8 octets, convert to bytes\n\t\tlength := int(data[1]) * 8\n\n\t\tif length == 0 {\n\t\t\tdf.SetTruncated()\n\t\t\treturn errors.New(\"ICMPv6 message option with length 0\")\n\t\t}\n\n\t\tif len(data) < length {\n\t\t\tdf.SetTruncated()\n\t\t\treturn fmt.Errorf(\"ICMP layer only %v bytes for ICMPv6 message option with length %v\", len(data), length)\n\t\t}\n\n\t\to := ICMPv6Option{\n\t\t\tType: ICMPv6Opt(data[0]),\n\t\t\tData: data[2:length],\n\t\t}\n\n\t\t// chop off option we just consumed\n\t\tdata = data[length:]\n\n\t\t*i = append(*i, o)\n\t}\n\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (i *ICMPv6Options) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tfor _, opt := range []ICMPv6Option(*i) {\n\t\tlength := len(opt.Data) + 2\n\t\tbuf, err := b.PrependBytes(length)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tbuf[0] = byte(opt.Type)\n\t\tbuf[1] = byte(length / 8)\n\t\tcopy(buf[2:], opt.Data)\n\t}\n\n\treturn nil\n}\n\nfunc decodeICMPv6Echo(data []byte, p gopacket.PacketBuilder) error {\n\ti := &ICMPv6Echo{}\n\treturn decodingLayerDecoder(i, data, p)\n}\n\nfunc decodeICMPv6RouterSolicitation(data []byte, p gopacket.PacketBuilder) error {\n\ti := &ICMPv6RouterSolicitation{}\n\treturn decodingLayerDecoder(i, data, p)\n}\n\nfunc decodeICMPv6RouterAdvertisement(data []byte, p gopacket.PacketBuilder) error {\n\ti := &ICMPv6RouterAdvertisement{}\n\treturn decodingLayerDecoder(i, data, p)\n}\n\nfunc decodeICMPv6NeighborSolicitation(data []byte, p gopacket.PacketBuilder) error {\n\ti := &ICMPv6NeighborSolicitation{}\n\treturn decodingLayerDecoder(i, data, p)\n}\n\nfunc decodeICMPv6NeighborAdvertisement(data []byte, p gopacket.PacketBuilder) error {\n\ti := &ICMPv6NeighborAdvertisement{}\n\treturn decodingLayerDecoder(i, data, p)\n}\n\nfunc decodeICMPv6Redirect(data []byte, p gopacket.PacketBuilder) error {\n\ti := &ICMPv6Redirect{}\n\treturn decodingLayerDecoder(i, data, p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/igmp.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n// Copyright 2009-2011 Andreas Krennmair. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/google/gopacket\"\n)\n\ntype IGMPType uint8\n\nconst (\n\tIGMPMembershipQuery    IGMPType = 0x11 // General or group specific query\n\tIGMPMembershipReportV1 IGMPType = 0x12 // Version 1 Membership Report\n\tIGMPMembershipReportV2 IGMPType = 0x16 // Version 2 Membership Report\n\tIGMPLeaveGroup         IGMPType = 0x17 // Leave Group\n\tIGMPMembershipReportV3 IGMPType = 0x22 // Version 3 Membership Report\n)\n\n// String conversions for IGMP message types\nfunc (i IGMPType) String() string {\n\tswitch i {\n\tcase IGMPMembershipQuery:\n\t\treturn \"IGMP Membership Query\"\n\tcase IGMPMembershipReportV1:\n\t\treturn \"IGMPv1 Membership Report\"\n\tcase IGMPMembershipReportV2:\n\t\treturn \"IGMPv2 Membership Report\"\n\tcase IGMPMembershipReportV3:\n\t\treturn \"IGMPv3 Membership Report\"\n\tcase IGMPLeaveGroup:\n\t\treturn \"Leave Group\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\ntype IGMPv3GroupRecordType uint8\n\nconst (\n\tIGMPIsIn  IGMPv3GroupRecordType = 0x01 // Type MODE_IS_INCLUDE, source addresses x\n\tIGMPIsEx  IGMPv3GroupRecordType = 0x02 // Type MODE_IS_EXCLUDE, source addresses x\n\tIGMPToIn  IGMPv3GroupRecordType = 0x03 // Type CHANGE_TO_INCLUDE_MODE, source addresses x\n\tIGMPToEx  IGMPv3GroupRecordType = 0x04 // Type CHANGE_TO_EXCLUDE_MODE, source addresses x\n\tIGMPAllow IGMPv3GroupRecordType = 0x05 // Type ALLOW_NEW_SOURCES, source addresses x\n\tIGMPBlock IGMPv3GroupRecordType = 0x06 // Type BLOCK_OLD_SOURCES, source addresses x\n)\n\nfunc (i IGMPv3GroupRecordType) String() string {\n\tswitch i {\n\tcase IGMPIsIn:\n\t\treturn \"MODE_IS_INCLUDE\"\n\tcase IGMPIsEx:\n\t\treturn \"MODE_IS_EXCLUDE\"\n\tcase IGMPToIn:\n\t\treturn \"CHANGE_TO_INCLUDE_MODE\"\n\tcase IGMPToEx:\n\t\treturn \"CHANGE_TO_EXCLUDE_MODE\"\n\tcase IGMPAllow:\n\t\treturn \"ALLOW_NEW_SOURCES\"\n\tcase IGMPBlock:\n\t\treturn \"BLOCK_OLD_SOURCES\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\n// IGMP represents an IGMPv3 message.\ntype IGMP struct {\n\tBaseLayer\n\tType                    IGMPType\n\tMaxResponseTime         time.Duration\n\tChecksum                uint16\n\tGroupAddress            net.IP\n\tSupressRouterProcessing bool\n\tRobustnessValue         uint8\n\tIntervalTime            time.Duration\n\tSourceAddresses         []net.IP\n\tNumberOfGroupRecords    uint16\n\tNumberOfSources         uint16\n\tGroupRecords            []IGMPv3GroupRecord\n\tVersion                 uint8 // IGMP protocol version\n}\n\n// IGMPv1or2 stores header details for an IGMPv1 or IGMPv2 packet.\n//\n//  0                   1                   2                   3\n//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |      Type     | Max Resp Time |           Checksum            |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |                         Group Address                         |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\ntype IGMPv1or2 struct {\n\tBaseLayer\n\tType            IGMPType      // IGMP message type\n\tMaxResponseTime time.Duration // meaningful only in Membership Query messages\n\tChecksum        uint16        // 16-bit checksum of entire ip payload\n\tGroupAddress    net.IP        // either 0 or an IP multicast address\n\tVersion         uint8\n}\n\n// decodeResponse dissects IGMPv1 or IGMPv2 packet.\nfunc (i *IGMPv1or2) decodeResponse(data []byte) error {\n\tif len(data) < 8 {\n\t\treturn errors.New(\"IGMP packet too small\")\n\t}\n\n\ti.MaxResponseTime = igmpTimeDecode(data[1])\n\ti.Checksum = binary.BigEndian.Uint16(data[2:4])\n\ti.GroupAddress = net.IP(data[4:8])\n\n\treturn nil\n}\n\n//  0                   1                   2                   3\n//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |  Type = 0x22  |    Reserved   |           Checksum            |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |           Reserved            |  Number of Group Records (M)  |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |                                                               |\n// .                        Group Record [1]                       .\n// |                                                               |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |                                                               |\n// .                        Group Record [2]                       .\n// |                                                               |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |                                                               |\n// .                        Group Record [M]                       .\n// |                                                               |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |  Record Type  |  Aux Data Len |     Number of Sources (N)     |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |                       Multicast Address                       |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |                       Source Address [1]                      |\n// +-                                                             -+\n// |                       Source Address [2]                      |\n// +-                                                             -+\n// |                       Source Address [N]                      |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |                                                               |\n// .                         Auxiliary Data                        .\n// |                                                               |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n// IGMPv3GroupRecord stores individual group records for a V3 Membership Report message.\ntype IGMPv3GroupRecord struct {\n\tType             IGMPv3GroupRecordType\n\tAuxDataLen       uint8 // this should always be 0 as per IGMPv3 spec.\n\tNumberOfSources  uint16\n\tMulticastAddress net.IP\n\tSourceAddresses  []net.IP\n\tAuxData          uint32 // NOT USED\n}\n\nfunc (i *IGMP) decodeIGMPv3MembershipReport(data []byte) error {\n\tif len(data) < 8 {\n\t\treturn errors.New(\"IGMPv3 Membership Report too small #1\")\n\t}\n\n\ti.Checksum = binary.BigEndian.Uint16(data[2:4])\n\ti.NumberOfGroupRecords = binary.BigEndian.Uint16(data[6:8])\n\n\trecordOffset := 8\n\tfor j := 0; j < int(i.NumberOfGroupRecords); j++ {\n\t\tif len(data) < recordOffset+8 {\n\t\t\treturn errors.New(\"IGMPv3 Membership Report too small #2\")\n\t\t}\n\n\t\tvar gr IGMPv3GroupRecord\n\t\tgr.Type = IGMPv3GroupRecordType(data[recordOffset])\n\t\tgr.AuxDataLen = data[recordOffset+1]\n\t\tgr.NumberOfSources = binary.BigEndian.Uint16(data[recordOffset+2 : recordOffset+4])\n\t\tgr.MulticastAddress = net.IP(data[recordOffset+4 : recordOffset+8])\n\n\t\tif len(data) < recordOffset+8+int(gr.NumberOfSources)*4 {\n\t\t\treturn errors.New(\"IGMPv3 Membership Report too small #3\")\n\t\t}\n\n\t\t// append source address records.\n\t\tfor i := 0; i < int(gr.NumberOfSources); i++ {\n\t\t\tsourceAddr := net.IP(data[recordOffset+8+i*4 : recordOffset+12+i*4])\n\t\t\tgr.SourceAddresses = append(gr.SourceAddresses, sourceAddr)\n\t\t}\n\n\t\ti.GroupRecords = append(i.GroupRecords, gr)\n\t\trecordOffset += 8 + 4*int(gr.NumberOfSources)\n\t}\n\treturn nil\n}\n\n//  0                   1                   2                   3\n//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |  Type = 0x11  | Max Resp Code |           Checksum            |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |                         Group Address                         |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// | Resv  |S| QRV |     QQIC      |     Number of Sources (N)     |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |                       Source Address [1]                      |\n// +-                                                             -+\n// |                       Source Address [2]                      |\n// +-                              .                              -+\n// |                       Source Address [N]                      |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//\n// decodeIGMPv3MembershipQuery parses the IGMPv3 message of type 0x11\nfunc (i *IGMP) decodeIGMPv3MembershipQuery(data []byte) error {\n\tif len(data) < 12 {\n\t\treturn errors.New(\"IGMPv3 Membership Query too small #1\")\n\t}\n\n\ti.MaxResponseTime = igmpTimeDecode(data[1])\n\ti.Checksum = binary.BigEndian.Uint16(data[2:4])\n\ti.SupressRouterProcessing = data[8]&0x8 != 0\n\ti.GroupAddress = net.IP(data[4:8])\n\ti.RobustnessValue = data[8] & 0x7\n\ti.IntervalTime = igmpTimeDecode(data[9])\n\ti.NumberOfSources = binary.BigEndian.Uint16(data[10:12])\n\n\tif len(data) < 12+int(i.NumberOfSources)*4 {\n\t\treturn errors.New(\"IGMPv3 Membership Query too small #2\")\n\t}\n\n\tfor j := 0; j < int(i.NumberOfSources); j++ {\n\t\ti.SourceAddresses = append(i.SourceAddresses, net.IP(data[12+j*4:16+j*4]))\n\t}\n\n\treturn nil\n}\n\n// igmpTimeDecode decodes the duration created by the given byte, using the\n// algorithm in http://www.rfc-base.org/txt/rfc-3376.txt section 4.1.1.\nfunc igmpTimeDecode(t uint8) time.Duration {\n\tif t&0x80 == 0 {\n\t\treturn time.Millisecond * 100 * time.Duration(t)\n\t}\n\tmant := (t & 0x70) >> 4\n\texp := t & 0x0F\n\treturn time.Millisecond * 100 * time.Duration((mant|0x10)<<(exp+3))\n}\n\n// LayerType returns LayerTypeIGMP for the V1,2,3 message protocol formats.\nfunc (i *IGMP) LayerType() gopacket.LayerType      { return LayerTypeIGMP }\nfunc (i *IGMPv1or2) LayerType() gopacket.LayerType { return LayerTypeIGMP }\n\nfunc (i *IGMPv1or2) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 8 {\n\t\treturn errors.New(\"IGMP Packet too small\")\n\t}\n\n\ti.Type = IGMPType(data[0])\n\ti.MaxResponseTime = igmpTimeDecode(data[1])\n\ti.Checksum = binary.BigEndian.Uint16(data[2:4])\n\ti.GroupAddress = net.IP(data[4:8])\n\n\treturn nil\n}\n\nfunc (i *IGMPv1or2) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypeZero\n}\n\nfunc (i *IGMPv1or2) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeIGMP\n}\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (i *IGMP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 1 {\n\t\treturn errors.New(\"IGMP packet is too small\")\n\t}\n\n\t// common IGMP header values between versions 1..3 of IGMP specification..\n\ti.Type = IGMPType(data[0])\n\n\tswitch i.Type {\n\tcase IGMPMembershipQuery:\n\t\ti.decodeIGMPv3MembershipQuery(data)\n\tcase IGMPMembershipReportV3:\n\t\ti.decodeIGMPv3MembershipReport(data)\n\tdefault:\n\t\treturn errors.New(\"unsupported IGMP type\")\n\t}\n\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (i *IGMP) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeIGMP\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (i *IGMP) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypeZero\n}\n\n// decodeIGMP will parse IGMP v1,2 or 3 protocols. Checks against the\n// IGMP type are performed against byte[0], logic then iniitalizes and\n// passes the appropriate struct (IGMP or IGMPv1or2) to\n// decodingLayerDecoder.\nfunc decodeIGMP(data []byte, p gopacket.PacketBuilder) error {\n\tif len(data) < 1 {\n\t\treturn errors.New(\"IGMP packet is too small\")\n\t}\n\n\t// byte 0 contains IGMP message type.\n\tswitch IGMPType(data[0]) {\n\tcase IGMPMembershipQuery:\n\t\t// IGMPv3 Membership Query payload is >= 12\n\t\tif len(data) >= 12 {\n\t\t\ti := &IGMP{Version: 3}\n\t\t\treturn decodingLayerDecoder(i, data, p)\n\t\t} else if len(data) == 8 {\n\t\t\ti := &IGMPv1or2{}\n\t\t\tif data[1] == 0x00 {\n\t\t\t\ti.Version = 1 // IGMPv1 has a query length of 8 and MaxResp = 0\n\t\t\t} else {\n\t\t\t\ti.Version = 2 // IGMPv2 has a query length of 8 and MaxResp != 0\n\t\t\t}\n\n\t\t\treturn decodingLayerDecoder(i, data, p)\n\t\t}\n\tcase IGMPMembershipReportV3:\n\t\ti := &IGMP{Version: 3}\n\t\treturn decodingLayerDecoder(i, data, p)\n\tcase IGMPMembershipReportV1:\n\t\ti := &IGMPv1or2{Version: 1}\n\t\treturn decodingLayerDecoder(i, data, p)\n\tcase IGMPLeaveGroup, IGMPMembershipReportV2:\n\t\t// leave group and Query Report v2 used in IGMPv2 only.\n\t\ti := &IGMPv1or2{Version: 2}\n\t\treturn decodingLayerDecoder(i, data, p)\n\tdefault:\n\t}\n\n\treturn errors.New(\"Unable to determine IGMP type.\")\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/ip4.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n// Copyright 2009-2011 Andreas Krennmair. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"strings\"\n\n\t\"github.com/google/gopacket\"\n)\n\ntype IPv4Flag uint8\n\nconst (\n\tIPv4EvilBit       IPv4Flag = 1 << 2 // http://tools.ietf.org/html/rfc3514 ;)\n\tIPv4DontFragment  IPv4Flag = 1 << 1\n\tIPv4MoreFragments IPv4Flag = 1 << 0\n)\n\nfunc (f IPv4Flag) String() string {\n\tvar s []string\n\tif f&IPv4EvilBit != 0 {\n\t\ts = append(s, \"Evil\")\n\t}\n\tif f&IPv4DontFragment != 0 {\n\t\ts = append(s, \"DF\")\n\t}\n\tif f&IPv4MoreFragments != 0 {\n\t\ts = append(s, \"MF\")\n\t}\n\treturn strings.Join(s, \"|\")\n}\n\n// IPv4 is the header of an IP packet.\ntype IPv4 struct {\n\tBaseLayer\n\tVersion    uint8\n\tIHL        uint8\n\tTOS        uint8\n\tLength     uint16\n\tId         uint16\n\tFlags      IPv4Flag\n\tFragOffset uint16\n\tTTL        uint8\n\tProtocol   IPProtocol\n\tChecksum   uint16\n\tSrcIP      net.IP\n\tDstIP      net.IP\n\tOptions    []IPv4Option\n\tPadding    []byte\n}\n\n// LayerType returns LayerTypeIPv4\nfunc (i *IPv4) LayerType() gopacket.LayerType { return LayerTypeIPv4 }\nfunc (i *IPv4) NetworkFlow() gopacket.Flow {\n\treturn gopacket.NewFlow(EndpointIPv4, i.SrcIP, i.DstIP)\n}\n\ntype IPv4Option struct {\n\tOptionType   uint8\n\tOptionLength uint8\n\tOptionData   []byte\n}\n\nfunc (i IPv4Option) String() string {\n\treturn fmt.Sprintf(\"IPv4Option(%v:%v)\", i.OptionType, i.OptionData)\n}\n\n// for the current ipv4 options, return the number of bytes (including\n// padding that the options used)\nfunc (ip *IPv4) getIPv4OptionSize() uint8 {\n\toptionSize := uint8(0)\n\tfor _, opt := range ip.Options {\n\t\tswitch opt.OptionType {\n\t\tcase 0:\n\t\t\t// this is the end of option lists\n\t\t\toptionSize++\n\t\tcase 1:\n\t\t\t// this is the padding\n\t\t\toptionSize++\n\t\tdefault:\n\t\t\toptionSize += opt.OptionLength\n\n\t\t}\n\t}\n\t// make sure the options are aligned to 32 bit boundary\n\tif (optionSize % 4) != 0 {\n\t\toptionSize += 4 - (optionSize % 4)\n\t}\n\treturn optionSize\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\nfunc (ip *IPv4) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\toptionLength := ip.getIPv4OptionSize()\n\tbytes, err := b.PrependBytes(20 + int(optionLength))\n\tif err != nil {\n\t\treturn err\n\t}\n\tif opts.FixLengths {\n\t\tip.IHL = 5 + (optionLength / 4)\n\t\tip.Length = uint16(len(b.Bytes()))\n\t}\n\tbytes[0] = (ip.Version << 4) | ip.IHL\n\tbytes[1] = ip.TOS\n\tbinary.BigEndian.PutUint16(bytes[2:], ip.Length)\n\tbinary.BigEndian.PutUint16(bytes[4:], ip.Id)\n\tbinary.BigEndian.PutUint16(bytes[6:], ip.flagsfrags())\n\tbytes[8] = ip.TTL\n\tbytes[9] = byte(ip.Protocol)\n\tif err := ip.AddressTo4(); err != nil {\n\t\treturn err\n\t}\n\tcopy(bytes[12:16], ip.SrcIP)\n\tcopy(bytes[16:20], ip.DstIP)\n\n\tcurLocation := 20\n\t// Now, we will encode the options\n\tfor _, opt := range ip.Options {\n\t\tswitch opt.OptionType {\n\t\tcase 0:\n\t\t\t// this is the end of option lists\n\t\t\tbytes[curLocation] = 0\n\t\t\tcurLocation++\n\t\tcase 1:\n\t\t\t// this is the padding\n\t\t\tbytes[curLocation] = 1\n\t\t\tcurLocation++\n\t\tdefault:\n\t\t\tbytes[curLocation] = opt.OptionType\n\t\t\tbytes[curLocation+1] = opt.OptionLength\n\n\t\t\t// sanity checking to protect us from buffer overrun\n\t\t\tif len(opt.OptionData) > int(opt.OptionLength-2) {\n\t\t\t\treturn errors.New(\"option length is smaller than length of option data\")\n\t\t\t}\n\t\t\tcopy(bytes[curLocation+2:curLocation+int(opt.OptionLength)], opt.OptionData)\n\t\t\tcurLocation += int(opt.OptionLength)\n\t\t}\n\t}\n\n\tif opts.ComputeChecksums {\n\t\tip.Checksum = checksum(bytes)\n\t}\n\tbinary.BigEndian.PutUint16(bytes[10:], ip.Checksum)\n\treturn nil\n}\n\nfunc checksum(bytes []byte) uint16 {\n\t// Clear checksum bytes\n\tbytes[10] = 0\n\tbytes[11] = 0\n\n\t// Compute checksum\n\tvar csum uint32\n\tfor i := 0; i < len(bytes); i += 2 {\n\t\tcsum += uint32(bytes[i]) << 8\n\t\tcsum += uint32(bytes[i+1])\n\t}\n\tfor {\n\t\t// Break when sum is less or equals to 0xFFFF\n\t\tif csum <= 65535 {\n\t\t\tbreak\n\t\t}\n\t\t// Add carry to the sum\n\t\tcsum = (csum >> 16) + uint32(uint16(csum))\n\t}\n\t// Flip all the bits\n\treturn ^uint16(csum)\n}\n\nfunc (ip *IPv4) flagsfrags() (ff uint16) {\n\tff |= uint16(ip.Flags) << 13\n\tff |= ip.FragOffset\n\treturn\n}\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (ip *IPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 20 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"Invalid ip4 header. Length %d less than 20\", len(data))\n\t}\n\tflagsfrags := binary.BigEndian.Uint16(data[6:8])\n\n\tip.Version = uint8(data[0]) >> 4\n\tip.IHL = uint8(data[0]) & 0x0F\n\tip.TOS = data[1]\n\tip.Length = binary.BigEndian.Uint16(data[2:4])\n\tip.Id = binary.BigEndian.Uint16(data[4:6])\n\tip.Flags = IPv4Flag(flagsfrags >> 13)\n\tip.FragOffset = flagsfrags & 0x1FFF\n\tip.TTL = data[8]\n\tip.Protocol = IPProtocol(data[9])\n\tip.Checksum = binary.BigEndian.Uint16(data[10:12])\n\tip.SrcIP = data[12:16]\n\tip.DstIP = data[16:20]\n\tip.Options = ip.Options[:0]\n\tip.Padding = nil\n\t// Set up an initial guess for contents/payload... we'll reset these soon.\n\tip.BaseLayer = BaseLayer{Contents: data}\n\n\t// This code is added for the following enviroment:\n\t// * Windows 10 with TSO option activated. ( tested on Hyper-V, RealTek ethernet driver )\n\tif ip.Length == 0 {\n\t\t// If using TSO(TCP Segmentation Offload), length is zero.\n\t\t// The actual packet length is the length of data.\n\t\tip.Length = uint16(len(data))\n\t}\n\n\tif ip.Length < 20 {\n\t\treturn fmt.Errorf(\"Invalid (too small) IP length (%d < 20)\", ip.Length)\n\t} else if ip.IHL < 5 {\n\t\treturn fmt.Errorf(\"Invalid (too small) IP header length (%d < 5)\", ip.IHL)\n\t} else if int(ip.IHL*4) > int(ip.Length) {\n\t\treturn fmt.Errorf(\"Invalid IP header length > IP length (%d > %d)\", ip.IHL, ip.Length)\n\t}\n\tif cmp := len(data) - int(ip.Length); cmp > 0 {\n\t\tdata = data[:ip.Length]\n\t} else if cmp < 0 {\n\t\tdf.SetTruncated()\n\t\tif int(ip.IHL)*4 > len(data) {\n\t\t\treturn errors.New(\"Not all IP header bytes available\")\n\t\t}\n\t}\n\tip.Contents = data[:ip.IHL*4]\n\tip.Payload = data[ip.IHL*4:]\n\t// From here on, data contains the header options.\n\tdata = data[20 : ip.IHL*4]\n\t// Pull out IP options\n\tfor len(data) > 0 {\n\t\tif ip.Options == nil {\n\t\t\t// Pre-allocate to avoid growing the slice too much.\n\t\t\tip.Options = make([]IPv4Option, 0, 4)\n\t\t}\n\t\topt := IPv4Option{OptionType: data[0]}\n\t\tswitch opt.OptionType {\n\t\tcase 0: // End of options\n\t\t\topt.OptionLength = 1\n\t\t\tip.Options = append(ip.Options, opt)\n\t\t\tip.Padding = data[1:]\n\t\t\treturn nil\n\t\tcase 1: // 1 byte padding\n\t\t\topt.OptionLength = 1\n\t\t\tdata = data[1:]\n\t\t\tip.Options = append(ip.Options, opt)\n\t\tdefault:\n\t\t\tif len(data) < 2 {\n\t\t\t\tdf.SetTruncated()\n\t\t\t\treturn fmt.Errorf(\"Invalid ip4 option length. Length %d less than 2\", len(data))\n\t\t\t}\n\t\t\topt.OptionLength = data[1]\n\t\t\tif len(data) < int(opt.OptionLength) {\n\t\t\t\tdf.SetTruncated()\n\t\t\t\treturn fmt.Errorf(\"IP option length exceeds remaining IP header size, option type %v length %v\", opt.OptionType, opt.OptionLength)\n\t\t\t}\n\t\t\tif opt.OptionLength <= 2 {\n\t\t\t\treturn fmt.Errorf(\"Invalid IP option type %v length %d. Must be greater than 2\", opt.OptionType, opt.OptionLength)\n\t\t\t}\n\t\t\topt.OptionData = data[2:opt.OptionLength]\n\t\t\tdata = data[opt.OptionLength:]\n\t\t\tip.Options = append(ip.Options, opt)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (i *IPv4) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeIPv4\n}\n\nfunc (i *IPv4) NextLayerType() gopacket.LayerType {\n\tif i.Flags&IPv4MoreFragments != 0 || i.FragOffset != 0 {\n\t\treturn gopacket.LayerTypeFragment\n\t}\n\treturn i.Protocol.LayerType()\n}\n\nfunc decodeIPv4(data []byte, p gopacket.PacketBuilder) error {\n\tip := &IPv4{}\n\terr := ip.DecodeFromBytes(data, p)\n\tp.AddLayer(ip)\n\tp.SetNetworkLayer(ip)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn p.NextDecoder(ip.NextLayerType())\n}\n\nfunc checkIPv4Address(addr net.IP) (net.IP, error) {\n\tif c := addr.To4(); c != nil {\n\t\treturn c, nil\n\t}\n\tif len(addr) == net.IPv6len {\n\t\treturn nil, errors.New(\"address is IPv6\")\n\t}\n\treturn nil, fmt.Errorf(\"wrong length of %d bytes instead of %d\", len(addr), net.IPv4len)\n}\n\nfunc (ip *IPv4) AddressTo4() error {\n\tvar src, dst net.IP\n\n\tif addr, err := checkIPv4Address(ip.SrcIP); err != nil {\n\t\treturn fmt.Errorf(\"Invalid source IPv4 address (%s)\", err)\n\t} else {\n\t\tsrc = addr\n\t}\n\tif addr, err := checkIPv4Address(ip.DstIP); err != nil {\n\t\treturn fmt.Errorf(\"Invalid destination IPv4 address (%s)\", err)\n\t} else {\n\t\tdst = addr\n\t}\n\tip.SrcIP = src\n\tip.DstIP = dst\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/ip6.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n// Copyright 2009-2011 Andreas Krennmair. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\n\t\"github.com/google/gopacket\"\n)\n\nconst (\n\t// IPv6HopByHopOptionJumbogram code as defined in RFC 2675\n\tIPv6HopByHopOptionJumbogram = 0xC2\n)\n\nconst (\n\tipv6MaxPayloadLength = 65535\n)\n\n// IPv6 is the layer for the IPv6 header.\ntype IPv6 struct {\n\t// http://www.networksorcery.com/enp/protocol/ipv6.htm\n\tBaseLayer\n\tVersion      uint8\n\tTrafficClass uint8\n\tFlowLabel    uint32\n\tLength       uint16\n\tNextHeader   IPProtocol\n\tHopLimit     uint8\n\tSrcIP        net.IP\n\tDstIP        net.IP\n\tHopByHop     *IPv6HopByHop\n\t// hbh will be pointed to by HopByHop if that layer exists.\n\thbh IPv6HopByHop\n}\n\n// LayerType returns LayerTypeIPv6\nfunc (ipv6 *IPv6) LayerType() gopacket.LayerType { return LayerTypeIPv6 }\n\n// NetworkFlow returns this new Flow (EndpointIPv6, SrcIP, DstIP)\nfunc (ipv6 *IPv6) NetworkFlow() gopacket.Flow {\n\treturn gopacket.NewFlow(EndpointIPv6, ipv6.SrcIP, ipv6.DstIP)\n}\n\n// Search for Jumbo Payload TLV in IPv6HopByHop and return (length, true) if found\nfunc getIPv6HopByHopJumboLength(hopopts *IPv6HopByHop) (uint32, bool, error) {\n\tvar tlv *IPv6HopByHopOption\n\n\tfor _, t := range hopopts.Options {\n\t\tif t.OptionType == IPv6HopByHopOptionJumbogram {\n\t\t\ttlv = t\n\t\t\tbreak\n\t\t}\n\t}\n\tif tlv == nil {\n\t\t// Not found\n\t\treturn 0, false, nil\n\t}\n\tif len(tlv.OptionData) != 4 {\n\t\treturn 0, false, errors.New(\"Jumbo length TLV data must have length 4\")\n\t}\n\tl := binary.BigEndian.Uint32(tlv.OptionData)\n\tif l <= ipv6MaxPayloadLength {\n\t\treturn 0, false, fmt.Errorf(\"Jumbo length cannot be less than %d\", ipv6MaxPayloadLength+1)\n\t}\n\t// Found\n\treturn l, true, nil\n}\n\n// Adds zero-valued Jumbo TLV to IPv6 header if it does not exist\n// (if necessary add hop-by-hop header)\nfunc addIPv6JumboOption(ip6 *IPv6) {\n\tvar tlv *IPv6HopByHopOption\n\n\tif ip6.HopByHop == nil {\n\t\t// Add IPv6 HopByHop\n\t\tip6.HopByHop = &IPv6HopByHop{}\n\t\tip6.HopByHop.NextHeader = ip6.NextHeader\n\t\tip6.HopByHop.HeaderLength = 0\n\t\tip6.NextHeader = IPProtocolIPv6HopByHop\n\t}\n\tfor _, t := range ip6.HopByHop.Options {\n\t\tif t.OptionType == IPv6HopByHopOptionJumbogram {\n\t\t\ttlv = t\n\t\t\tbreak\n\t\t}\n\t}\n\tif tlv == nil {\n\t\t// Add Jumbo TLV\n\t\ttlv = &IPv6HopByHopOption{}\n\t\tip6.HopByHop.Options = append(ip6.HopByHop.Options, tlv)\n\t}\n\ttlv.SetJumboLength(0)\n}\n\n// Set jumbo length in serialized IPv6 payload (starting with HopByHop header)\nfunc setIPv6PayloadJumboLength(hbh []byte) error {\n\tpLen := len(hbh)\n\tif pLen < 8 {\n\t\t//HopByHop is minimum 8 bytes\n\t\treturn fmt.Errorf(\"Invalid IPv6 payload (length %d)\", pLen)\n\t}\n\thbhLen := int((hbh[1] + 1) * 8)\n\tif hbhLen > pLen {\n\t\treturn fmt.Errorf(\"Invalid hop-by-hop length (length: %d, payload: %d\", hbhLen, pLen)\n\t}\n\toffset := 2 //start with options\n\tfor offset < hbhLen {\n\t\topt := hbh[offset]\n\t\tif opt == 0 {\n\t\t\t//Pad1\n\t\t\toffset++\n\t\t\tcontinue\n\t\t}\n\t\toptLen := int(hbh[offset+1])\n\t\tif opt == IPv6HopByHopOptionJumbogram {\n\t\t\tif optLen == 4 {\n\t\t\t\tbinary.BigEndian.PutUint32(hbh[offset+2:], uint32(pLen))\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"Jumbo TLV too short (%d bytes)\", optLen)\n\t\t}\n\t\toffset += 2 + optLen\n\t}\n\treturn errors.New(\"Jumbo TLV not found\")\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (ipv6 *IPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tvar jumbo bool\n\tvar err error\n\n\tpayload := b.Bytes()\n\tpLen := len(payload)\n\tif pLen > ipv6MaxPayloadLength {\n\t\tjumbo = true\n\t\tif opts.FixLengths {\n\t\t\t// We need to set the length later because the hop-by-hop header may\n\t\t\t// not exist or else need padding, so pLen may yet change\n\t\t\taddIPv6JumboOption(ipv6)\n\t\t} else if ipv6.HopByHop == nil {\n\t\t\treturn fmt.Errorf(\"Cannot fit payload length of %d into IPv6 packet\", pLen)\n\t\t} else {\n\t\t\t_, ok, err := getIPv6HopByHopJumboLength(ipv6.HopByHop)\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\treturn errors.New(\"Missing jumbo length hop-by-hop option\")\n\t\t\t}\n\t\t}\n\t}\n\n\thbhAlreadySerialized := false\n\tif ipv6.HopByHop != nil {\n\t\tfor _, l := range b.Layers() {\n\t\t\tif l == LayerTypeIPv6HopByHop {\n\t\t\t\thbhAlreadySerialized = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tif ipv6.HopByHop != nil && !hbhAlreadySerialized {\n\t\tif ipv6.NextHeader != IPProtocolIPv6HopByHop {\n\t\t\t// Just fix it instead of throwing an error\n\t\t\tipv6.NextHeader = IPProtocolIPv6HopByHop\n\t\t}\n\t\terr = ipv6.HopByHop.SerializeTo(b, opts)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tpayload = b.Bytes()\n\t\tpLen = len(payload)\n\t\tif opts.FixLengths && jumbo {\n\t\t\terr := setIPv6PayloadJumboLength(payload)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\tif !jumbo && pLen > ipv6MaxPayloadLength {\n\t\treturn errors.New(\"Cannot fit payload into IPv6 header\")\n\t}\n\tbytes, err := b.PrependBytes(40)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbytes[0] = (ipv6.Version << 4) | (ipv6.TrafficClass >> 4)\n\tbytes[1] = (ipv6.TrafficClass << 4) | uint8(ipv6.FlowLabel>>16)\n\tbinary.BigEndian.PutUint16(bytes[2:], uint16(ipv6.FlowLabel))\n\tif opts.FixLengths {\n\t\tif jumbo {\n\t\t\tipv6.Length = 0\n\t\t} else {\n\t\t\tipv6.Length = uint16(pLen)\n\t\t}\n\t}\n\tbinary.BigEndian.PutUint16(bytes[4:], ipv6.Length)\n\tbytes[6] = byte(ipv6.NextHeader)\n\tbytes[7] = byte(ipv6.HopLimit)\n\tif err := ipv6.AddressTo16(); err != nil {\n\t\treturn err\n\t}\n\tcopy(bytes[8:], ipv6.SrcIP)\n\tcopy(bytes[24:], ipv6.DstIP)\n\treturn nil\n}\n\n// DecodeFromBytes implementation according to gopacket.DecodingLayer\nfunc (ipv6 *IPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 40 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"Invalid ip6 header. Length %d less than 40\", len(data))\n\t}\n\tipv6.Version = uint8(data[0]) >> 4\n\tipv6.TrafficClass = uint8((binary.BigEndian.Uint16(data[0:2]) >> 4) & 0x00FF)\n\tipv6.FlowLabel = binary.BigEndian.Uint32(data[0:4]) & 0x000FFFFF\n\tipv6.Length = binary.BigEndian.Uint16(data[4:6])\n\tipv6.NextHeader = IPProtocol(data[6])\n\tipv6.HopLimit = data[7]\n\tipv6.SrcIP = data[8:24]\n\tipv6.DstIP = data[24:40]\n\tipv6.HopByHop = nil\n\tipv6.BaseLayer = BaseLayer{data[:40], data[40:]}\n\n\t// We treat a HopByHop IPv6 option as part of the IPv6 packet, since its\n\t// options are crucial for understanding what's actually happening per packet.\n\tif ipv6.NextHeader == IPProtocolIPv6HopByHop {\n\t\terr := ipv6.hbh.DecodeFromBytes(ipv6.Payload, df)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tipv6.HopByHop = &ipv6.hbh\n\t\tpEnd, jumbo, err := getIPv6HopByHopJumboLength(ipv6.HopByHop)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif jumbo && ipv6.Length == 0 {\n\t\t\tpEnd := int(pEnd)\n\t\t\tif pEnd > len(ipv6.Payload) {\n\t\t\t\tdf.SetTruncated()\n\t\t\t\tpEnd = len(ipv6.Payload)\n\t\t\t}\n\t\t\tipv6.Payload = ipv6.Payload[:pEnd]\n\t\t\treturn nil\n\t\t} else if jumbo && ipv6.Length != 0 {\n\t\t\treturn errors.New(\"IPv6 has jumbo length and IPv6 length is not 0\")\n\t\t} else if !jumbo && ipv6.Length == 0 {\n\t\t\treturn errors.New(\"IPv6 length 0, but HopByHop header does not have jumbogram option\")\n\t\t} else {\n\t\t\tipv6.Payload = ipv6.Payload[ipv6.hbh.ActualLength:]\n\t\t}\n\t}\n\n\tif ipv6.Length == 0 {\n\t\treturn fmt.Errorf(\"IPv6 length 0, but next header is %v, not HopByHop\", ipv6.NextHeader)\n\t}\n\n\tpEnd := int(ipv6.Length)\n\tif pEnd > len(ipv6.Payload) {\n\t\tdf.SetTruncated()\n\t\tpEnd = len(ipv6.Payload)\n\t}\n\tipv6.Payload = ipv6.Payload[:pEnd]\n\n\treturn nil\n}\n\n// CanDecode implementation according to gopacket.DecodingLayer\nfunc (ipv6 *IPv6) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeIPv6\n}\n\n// NextLayerType implementation according to gopacket.DecodingLayer\nfunc (ipv6 *IPv6) NextLayerType() gopacket.LayerType {\n\tif ipv6.HopByHop != nil {\n\t\treturn ipv6.HopByHop.NextHeader.LayerType()\n\t}\n\treturn ipv6.NextHeader.LayerType()\n}\n\nfunc decodeIPv6(data []byte, p gopacket.PacketBuilder) error {\n\tip6 := &IPv6{}\n\terr := ip6.DecodeFromBytes(data, p)\n\tp.AddLayer(ip6)\n\tp.SetNetworkLayer(ip6)\n\tif ip6.HopByHop != nil {\n\t\tp.AddLayer(ip6.HopByHop)\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn p.NextDecoder(ip6.NextLayerType())\n}\n\ntype ipv6HeaderTLVOption struct {\n\tOptionType, OptionLength uint8\n\tActualLength             int\n\tOptionData               []byte\n\tOptionAlignment          [2]uint8 // Xn+Y = [2]uint8{X, Y}\n}\n\nfunc (h *ipv6HeaderTLVOption) serializeTo(data []byte, fixLengths bool, dryrun bool) int {\n\tif fixLengths {\n\t\th.OptionLength = uint8(len(h.OptionData))\n\t}\n\tlength := int(h.OptionLength) + 2\n\tif !dryrun {\n\t\tdata[0] = h.OptionType\n\t\tdata[1] = h.OptionLength\n\t\tcopy(data[2:], h.OptionData)\n\t}\n\treturn length\n}\n\nfunc decodeIPv6HeaderTLVOption(data []byte, df gopacket.DecodeFeedback) (h *ipv6HeaderTLVOption, _ error) {\n\tif len(data) < 2 {\n\t\tdf.SetTruncated()\n\t\treturn nil, errors.New(\"IPv6 header option too small\")\n\t}\n\th = &ipv6HeaderTLVOption{}\n\tif data[0] == 0 {\n\t\th.ActualLength = 1\n\t\treturn\n\t}\n\th.OptionType = data[0]\n\th.OptionLength = data[1]\n\th.ActualLength = int(h.OptionLength) + 2\n\tif len(data) < h.ActualLength {\n\t\tdf.SetTruncated()\n\t\treturn nil, errors.New(\"IPv6 header TLV option too small\")\n\t}\n\th.OptionData = data[2:h.ActualLength]\n\treturn\n}\n\nfunc serializeTLVOptionPadding(data []byte, padLength int) {\n\tif padLength <= 0 {\n\t\treturn\n\t}\n\tif padLength == 1 {\n\t\tdata[0] = 0x0\n\t\treturn\n\t}\n\ttlvLength := uint8(padLength) - 2\n\tdata[0] = 0x1\n\tdata[1] = tlvLength\n\tif tlvLength != 0 {\n\t\tfor k := range data[2:] {\n\t\t\tdata[k+2] = 0x0\n\t\t}\n\t}\n\treturn\n}\n\n// If buf is 'nil' do a serialize dry run\nfunc serializeIPv6HeaderTLVOptions(buf []byte, options []*ipv6HeaderTLVOption, fixLengths bool) int {\n\tvar l int\n\n\tdryrun := buf == nil\n\tlength := 2\n\tfor _, opt := range options {\n\t\tif fixLengths {\n\t\t\tx := int(opt.OptionAlignment[0])\n\t\t\ty := int(opt.OptionAlignment[1])\n\t\t\tif x != 0 {\n\t\t\t\tn := length / x\n\t\t\t\toffset := x*n + y\n\t\t\t\tif offset < length {\n\t\t\t\t\toffset += x\n\t\t\t\t}\n\t\t\t\tif length != offset {\n\t\t\t\t\tpad := offset - length\n\t\t\t\t\tif !dryrun {\n\t\t\t\t\t\tserializeTLVOptionPadding(buf[length-2:], pad)\n\t\t\t\t\t}\n\t\t\t\t\tlength += pad\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif dryrun {\n\t\t\tl = opt.serializeTo(nil, fixLengths, true)\n\t\t} else {\n\t\t\tl = opt.serializeTo(buf[length-2:], fixLengths, false)\n\t\t}\n\t\tlength += l\n\t}\n\tif fixLengths {\n\t\tpad := length % 8\n\t\tif pad != 0 {\n\t\t\tif !dryrun {\n\t\t\t\tserializeTLVOptionPadding(buf[length-2:], pad)\n\t\t\t}\n\t\t\tlength += pad\n\t\t}\n\t}\n\treturn length - 2\n}\n\ntype ipv6ExtensionBase struct {\n\tBaseLayer\n\tNextHeader   IPProtocol\n\tHeaderLength uint8\n\tActualLength int\n}\n\nfunc decodeIPv6ExtensionBase(data []byte, df gopacket.DecodeFeedback) (i ipv6ExtensionBase, returnedErr error) {\n\tif len(data) < 2 {\n\t\tdf.SetTruncated()\n\t\treturn ipv6ExtensionBase{}, fmt.Errorf(\"Invalid ip6-extension header. Length %d less than 2\", len(data))\n\t}\n\ti.NextHeader = IPProtocol(data[0])\n\ti.HeaderLength = data[1]\n\ti.ActualLength = int(i.HeaderLength)*8 + 8\n\tif len(data) < i.ActualLength {\n\t\treturn ipv6ExtensionBase{}, fmt.Errorf(\"Invalid ip6-extension header. Length %d less than specified length %d\", len(data), i.ActualLength)\n\t}\n\ti.Contents = data[:i.ActualLength]\n\ti.Payload = data[i.ActualLength:]\n\treturn\n}\n\n// IPv6ExtensionSkipper is a DecodingLayer which decodes and ignores v6\n// extensions.  You can use it with a DecodingLayerParser to handle IPv6 stacks\n// which may or may not have extensions.\ntype IPv6ExtensionSkipper struct {\n\tNextHeader IPProtocol\n\tBaseLayer\n}\n\n// DecodeFromBytes implementation according to gopacket.DecodingLayer\nfunc (i *IPv6ExtensionSkipper) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\textension, err := decodeIPv6ExtensionBase(data, df)\n\tif err != nil {\n\t\treturn err\n\t}\n\ti.BaseLayer = BaseLayer{data[:extension.ActualLength], data[extension.ActualLength:]}\n\ti.NextHeader = extension.NextHeader\n\treturn nil\n}\n\n// CanDecode implementation according to gopacket.DecodingLayer\nfunc (i *IPv6ExtensionSkipper) CanDecode() gopacket.LayerClass {\n\treturn LayerClassIPv6Extension\n}\n\n// NextLayerType implementation according to gopacket.DecodingLayer\nfunc (i *IPv6ExtensionSkipper) NextLayerType() gopacket.LayerType {\n\treturn i.NextHeader.LayerType()\n}\n\n// IPv6HopByHopOption is a TLV option present in an IPv6 hop-by-hop extension.\ntype IPv6HopByHopOption ipv6HeaderTLVOption\n\n// IPv6HopByHop is the IPv6 hop-by-hop extension.\ntype IPv6HopByHop struct {\n\tipv6ExtensionBase\n\tOptions []*IPv6HopByHopOption\n}\n\n// LayerType returns LayerTypeIPv6HopByHop.\nfunc (i *IPv6HopByHop) LayerType() gopacket.LayerType { return LayerTypeIPv6HopByHop }\n\n// SerializeTo implementation according to gopacket.SerializableLayer\nfunc (i *IPv6HopByHop) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tvar bytes []byte\n\tvar err error\n\n\to := make([]*ipv6HeaderTLVOption, 0, len(i.Options))\n\tfor _, v := range i.Options {\n\t\to = append(o, (*ipv6HeaderTLVOption)(v))\n\t}\n\n\tl := serializeIPv6HeaderTLVOptions(nil, o, opts.FixLengths)\n\tbytes, err = b.PrependBytes(l)\n\tif err != nil {\n\t\treturn err\n\t}\n\tserializeIPv6HeaderTLVOptions(bytes, o, opts.FixLengths)\n\n\tlength := len(bytes) + 2\n\tif length%8 != 0 {\n\t\treturn errors.New(\"IPv6HopByHop actual length must be multiple of 8\")\n\t}\n\tbytes, err = b.PrependBytes(2)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbytes[0] = uint8(i.NextHeader)\n\tif opts.FixLengths {\n\t\ti.HeaderLength = uint8((length / 8) - 1)\n\t}\n\tbytes[1] = uint8(i.HeaderLength)\n\treturn nil\n}\n\n// DecodeFromBytes implementation according to gopacket.DecodingLayer\nfunc (i *IPv6HopByHop) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tvar err error\n\ti.ipv6ExtensionBase, err = decodeIPv6ExtensionBase(data, df)\n\tif err != nil {\n\t\treturn err\n\t}\n\ti.Options = i.Options[:0]\n\toffset := 2\n\tfor offset < i.ActualLength {\n\t\topt, err := decodeIPv6HeaderTLVOption(data[offset:], df)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\ti.Options = append(i.Options, (*IPv6HopByHopOption)(opt))\n\t\toffset += opt.ActualLength\n\t}\n\treturn nil\n}\n\nfunc decodeIPv6HopByHop(data []byte, p gopacket.PacketBuilder) error {\n\ti := &IPv6HopByHop{}\n\terr := i.DecodeFromBytes(data, p)\n\tp.AddLayer(i)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn p.NextDecoder(i.NextHeader)\n}\n\n// SetJumboLength adds the IPv6HopByHopOptionJumbogram with the given length\nfunc (o *IPv6HopByHopOption) SetJumboLength(len uint32) {\n\to.OptionType = IPv6HopByHopOptionJumbogram\n\to.OptionLength = 4\n\to.ActualLength = 6\n\tif o.OptionData == nil {\n\t\to.OptionData = make([]byte, 4)\n\t}\n\tbinary.BigEndian.PutUint32(o.OptionData, len)\n\to.OptionAlignment = [2]uint8{4, 2}\n}\n\n// IPv6Routing is the IPv6 routing extension.\ntype IPv6Routing struct {\n\tipv6ExtensionBase\n\tRoutingType  uint8\n\tSegmentsLeft uint8\n\t// This segment is supposed to be zero according to RFC2460, the second set of\n\t// 4 bytes in the extension.\n\tReserved []byte\n\t// SourceRoutingIPs is the set of IPv6 addresses requested for source routing,\n\t// set only if RoutingType == 0.\n\tSourceRoutingIPs []net.IP\n}\n\n// LayerType returns LayerTypeIPv6Routing.\nfunc (i *IPv6Routing) LayerType() gopacket.LayerType { return LayerTypeIPv6Routing }\n\nfunc decodeIPv6Routing(data []byte, p gopacket.PacketBuilder) error {\n\tbase, err := decodeIPv6ExtensionBase(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\ti := &IPv6Routing{\n\t\tipv6ExtensionBase: base,\n\t\tRoutingType:       data[2],\n\t\tSegmentsLeft:      data[3],\n\t\tReserved:          data[4:8],\n\t}\n\tswitch i.RoutingType {\n\tcase 0: // Source routing\n\t\tif (i.ActualLength-8)%16 != 0 {\n\t\t\treturn fmt.Errorf(\"Invalid IPv6 source routing, length of type 0 packet %d\", i.ActualLength)\n\t\t}\n\t\tfor d := i.Contents[8:]; len(d) >= 16; d = d[16:] {\n\t\t\ti.SourceRoutingIPs = append(i.SourceRoutingIPs, net.IP(d[:16]))\n\t\t}\n\tdefault:\n\t\treturn fmt.Errorf(\"Unknown IPv6 routing header type %d\", i.RoutingType)\n\t}\n\tp.AddLayer(i)\n\treturn p.NextDecoder(i.NextHeader)\n}\n\n// IPv6Fragment is the IPv6 fragment header, used for packet\n// fragmentation/defragmentation.\ntype IPv6Fragment struct {\n\tBaseLayer\n\tNextHeader IPProtocol\n\t// Reserved1 is bits [8-16), from least to most significant, 0-indexed\n\tReserved1      uint8\n\tFragmentOffset uint16\n\t// Reserved2 is bits [29-31), from least to most significant, 0-indexed\n\tReserved2      uint8\n\tMoreFragments  bool\n\tIdentification uint32\n}\n\n// LayerType returns LayerTypeIPv6Fragment.\nfunc (i *IPv6Fragment) LayerType() gopacket.LayerType { return LayerTypeIPv6Fragment }\n\nfunc decodeIPv6Fragment(data []byte, p gopacket.PacketBuilder) error {\n\tif len(data) < 8 {\n\t\tp.SetTruncated()\n\t\treturn fmt.Errorf(\"Invalid ip6-fragment header. Length %d less than 8\", len(data))\n\t}\n\ti := &IPv6Fragment{\n\t\tBaseLayer:      BaseLayer{data[:8], data[8:]},\n\t\tNextHeader:     IPProtocol(data[0]),\n\t\tReserved1:      data[1],\n\t\tFragmentOffset: binary.BigEndian.Uint16(data[2:4]) >> 3,\n\t\tReserved2:      data[3] & 0x6 >> 1,\n\t\tMoreFragments:  data[3]&0x1 != 0,\n\t\tIdentification: binary.BigEndian.Uint32(data[4:8]),\n\t}\n\tp.AddLayer(i)\n\treturn p.NextDecoder(gopacket.DecodeFragment)\n}\n\n// IPv6DestinationOption is a TLV option present in an IPv6 destination options extension.\ntype IPv6DestinationOption ipv6HeaderTLVOption\n\n// IPv6Destination is the IPv6 destination options header.\ntype IPv6Destination struct {\n\tipv6ExtensionBase\n\tOptions []*IPv6DestinationOption\n}\n\n// LayerType returns LayerTypeIPv6Destination.\nfunc (i *IPv6Destination) LayerType() gopacket.LayerType { return LayerTypeIPv6Destination }\n\n// DecodeFromBytes implementation according to gopacket.DecodingLayer\nfunc (i *IPv6Destination) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tvar err error\n\ti.ipv6ExtensionBase, err = decodeIPv6ExtensionBase(data, df)\n\tif err != nil {\n\t\treturn err\n\t}\n\toffset := 2\n\tfor offset < i.ActualLength {\n\t\topt, err := decodeIPv6HeaderTLVOption(data[offset:], df)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\ti.Options = append(i.Options, (*IPv6DestinationOption)(opt))\n\t\toffset += opt.ActualLength\n\t}\n\treturn nil\n}\n\nfunc decodeIPv6Destination(data []byte, p gopacket.PacketBuilder) error {\n\ti := &IPv6Destination{}\n\terr := i.DecodeFromBytes(data, p)\n\tp.AddLayer(i)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn p.NextDecoder(i.NextHeader)\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (i *IPv6Destination) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tvar bytes []byte\n\tvar err error\n\n\to := make([]*ipv6HeaderTLVOption, 0, len(i.Options))\n\tfor _, v := range i.Options {\n\t\to = append(o, (*ipv6HeaderTLVOption)(v))\n\t}\n\n\tl := serializeIPv6HeaderTLVOptions(nil, o, opts.FixLengths)\n\tbytes, err = b.PrependBytes(l)\n\tif err != nil {\n\t\treturn err\n\t}\n\tserializeIPv6HeaderTLVOptions(bytes, o, opts.FixLengths)\n\n\tlength := len(bytes) + 2\n\tif length%8 != 0 {\n\t\treturn errors.New(\"IPv6Destination actual length must be multiple of 8\")\n\t}\n\tbytes, err = b.PrependBytes(2)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbytes[0] = uint8(i.NextHeader)\n\tif opts.FixLengths {\n\t\ti.HeaderLength = uint8((length / 8) - 1)\n\t}\n\tbytes[1] = uint8(i.HeaderLength)\n\treturn nil\n}\n\nfunc checkIPv6Address(addr net.IP) error {\n\tif len(addr) == net.IPv6len {\n\t\treturn nil\n\t}\n\tif len(addr) == net.IPv4len {\n\t\treturn errors.New(\"address is IPv4\")\n\t}\n\treturn fmt.Errorf(\"wrong length of %d bytes instead of %d\", len(addr), net.IPv6len)\n}\n\n// AddressTo16 ensures IPv6.SrcIP and IPv6.DstIP are actually IPv6 addresses (i.e. 16 byte addresses)\nfunc (ipv6 *IPv6) AddressTo16() error {\n\tif err := checkIPv6Address(ipv6.SrcIP); err != nil {\n\t\treturn fmt.Errorf(\"Invalid source IPv6 address (%s)\", err)\n\t}\n\tif err := checkIPv6Address(ipv6.DstIP); err != nil {\n\t\treturn fmt.Errorf(\"Invalid destination IPv6 address (%s)\", err)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/ipsec.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"github.com/google/gopacket\"\n)\n\n// IPSecAH is the authentication header for IPv4/6 defined in\n// http://tools.ietf.org/html/rfc2402\ntype IPSecAH struct {\n\t// While the auth header can be used for both IPv4 and v6, its format is that of\n\t// an IPv6 extension (NextHeader, PayloadLength, etc...), so we use ipv6ExtensionBase\n\t// to build it.\n\tipv6ExtensionBase\n\tReserved           uint16\n\tSPI, Seq           uint32\n\tAuthenticationData []byte\n}\n\n// LayerType returns LayerTypeIPSecAH.\nfunc (i *IPSecAH) LayerType() gopacket.LayerType { return LayerTypeIPSecAH }\n\nfunc decodeIPSecAH(data []byte, p gopacket.PacketBuilder) error {\n\tif len(data) < 12 {\n\t\tp.SetTruncated()\n\t\treturn errors.New(\"IPSec AH packet less than 12 bytes\")\n\t}\n\ti := &IPSecAH{\n\t\tipv6ExtensionBase: ipv6ExtensionBase{\n\t\t\tNextHeader:   IPProtocol(data[0]),\n\t\t\tHeaderLength: data[1],\n\t\t},\n\t\tReserved: binary.BigEndian.Uint16(data[2:4]),\n\t\tSPI:      binary.BigEndian.Uint32(data[4:8]),\n\t\tSeq:      binary.BigEndian.Uint32(data[8:12]),\n\t}\n\ti.ActualLength = (int(i.HeaderLength) + 2) * 4\n\tif len(data) < i.ActualLength {\n\t\tp.SetTruncated()\n\t\treturn errors.New(\"Truncated AH packet < ActualLength\")\n\t}\n\ti.AuthenticationData = data[12:i.ActualLength]\n\ti.Contents = data[:i.ActualLength]\n\ti.Payload = data[i.ActualLength:]\n\tp.AddLayer(i)\n\treturn p.NextDecoder(i.NextHeader)\n}\n\n// IPSecESP is the encapsulating security payload defined in\n// http://tools.ietf.org/html/rfc2406\ntype IPSecESP struct {\n\tBaseLayer\n\tSPI, Seq uint32\n\t// Encrypted contains the encrypted set of bytes sent in an ESP\n\tEncrypted []byte\n}\n\n// LayerType returns LayerTypeIPSecESP.\nfunc (i *IPSecESP) LayerType() gopacket.LayerType { return LayerTypeIPSecESP }\n\nfunc decodeIPSecESP(data []byte, p gopacket.PacketBuilder) error {\n\ti := &IPSecESP{\n\t\tBaseLayer: BaseLayer{data, nil},\n\t\tSPI:       binary.BigEndian.Uint32(data[:4]),\n\t\tSeq:       binary.BigEndian.Uint32(data[4:8]),\n\t\tEncrypted: data[8:],\n\t}\n\tp.AddLayer(i)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/layertypes.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"github.com/google/gopacket\"\n)\n\nvar (\n\tLayerTypeARP                          = gopacket.RegisterLayerType(10, gopacket.LayerTypeMetadata{Name: \"ARP\", Decoder: gopacket.DecodeFunc(decodeARP)})\n\tLayerTypeCiscoDiscovery               = gopacket.RegisterLayerType(11, gopacket.LayerTypeMetadata{Name: \"CiscoDiscovery\", Decoder: gopacket.DecodeFunc(decodeCiscoDiscovery)})\n\tLayerTypeEthernetCTP                  = gopacket.RegisterLayerType(12, gopacket.LayerTypeMetadata{Name: \"EthernetCTP\", Decoder: gopacket.DecodeFunc(decodeEthernetCTP)})\n\tLayerTypeEthernetCTPForwardData       = gopacket.RegisterLayerType(13, gopacket.LayerTypeMetadata{Name: \"EthernetCTPForwardData\", Decoder: nil})\n\tLayerTypeEthernetCTPReply             = gopacket.RegisterLayerType(14, gopacket.LayerTypeMetadata{Name: \"EthernetCTPReply\", Decoder: nil})\n\tLayerTypeDot1Q                        = gopacket.RegisterLayerType(15, gopacket.LayerTypeMetadata{Name: \"Dot1Q\", Decoder: gopacket.DecodeFunc(decodeDot1Q)})\n\tLayerTypeEtherIP                      = gopacket.RegisterLayerType(16, gopacket.LayerTypeMetadata{Name: \"EtherIP\", Decoder: gopacket.DecodeFunc(decodeEtherIP)})\n\tLayerTypeEthernet                     = gopacket.RegisterLayerType(17, gopacket.LayerTypeMetadata{Name: \"Ethernet\", Decoder: gopacket.DecodeFunc(decodeEthernet)})\n\tLayerTypeGRE                          = gopacket.RegisterLayerType(18, gopacket.LayerTypeMetadata{Name: \"GRE\", Decoder: gopacket.DecodeFunc(decodeGRE)})\n\tLayerTypeICMPv4                       = gopacket.RegisterLayerType(19, gopacket.LayerTypeMetadata{Name: \"ICMPv4\", Decoder: gopacket.DecodeFunc(decodeICMPv4)})\n\tLayerTypeIPv4                         = gopacket.RegisterLayerType(20, gopacket.LayerTypeMetadata{Name: \"IPv4\", Decoder: gopacket.DecodeFunc(decodeIPv4)})\n\tLayerTypeIPv6                         = gopacket.RegisterLayerType(21, gopacket.LayerTypeMetadata{Name: \"IPv6\", Decoder: gopacket.DecodeFunc(decodeIPv6)})\n\tLayerTypeLLC                          = gopacket.RegisterLayerType(22, gopacket.LayerTypeMetadata{Name: \"LLC\", Decoder: gopacket.DecodeFunc(decodeLLC)})\n\tLayerTypeSNAP                         = gopacket.RegisterLayerType(23, gopacket.LayerTypeMetadata{Name: \"SNAP\", Decoder: gopacket.DecodeFunc(decodeSNAP)})\n\tLayerTypeMPLS                         = gopacket.RegisterLayerType(24, gopacket.LayerTypeMetadata{Name: \"MPLS\", Decoder: gopacket.DecodeFunc(decodeMPLS)})\n\tLayerTypePPP                          = gopacket.RegisterLayerType(25, gopacket.LayerTypeMetadata{Name: \"PPP\", Decoder: gopacket.DecodeFunc(decodePPP)})\n\tLayerTypePPPoE                        = gopacket.RegisterLayerType(26, gopacket.LayerTypeMetadata{Name: \"PPPoE\", Decoder: gopacket.DecodeFunc(decodePPPoE)})\n\tLayerTypeRUDP                         = gopacket.RegisterLayerType(27, gopacket.LayerTypeMetadata{Name: \"RUDP\", Decoder: gopacket.DecodeFunc(decodeRUDP)})\n\tLayerTypeSCTP                         = gopacket.RegisterLayerType(28, gopacket.LayerTypeMetadata{Name: \"SCTP\", Decoder: gopacket.DecodeFunc(decodeSCTP)})\n\tLayerTypeSCTPUnknownChunkType         = gopacket.RegisterLayerType(29, gopacket.LayerTypeMetadata{Name: \"SCTPUnknownChunkType\", Decoder: nil})\n\tLayerTypeSCTPData                     = gopacket.RegisterLayerType(30, gopacket.LayerTypeMetadata{Name: \"SCTPData\", Decoder: nil})\n\tLayerTypeSCTPInit                     = gopacket.RegisterLayerType(31, gopacket.LayerTypeMetadata{Name: \"SCTPInit\", Decoder: nil})\n\tLayerTypeSCTPSack                     = gopacket.RegisterLayerType(32, gopacket.LayerTypeMetadata{Name: \"SCTPSack\", Decoder: nil})\n\tLayerTypeSCTPHeartbeat                = gopacket.RegisterLayerType(33, gopacket.LayerTypeMetadata{Name: \"SCTPHeartbeat\", Decoder: nil})\n\tLayerTypeSCTPError                    = gopacket.RegisterLayerType(34, gopacket.LayerTypeMetadata{Name: \"SCTPError\", Decoder: nil})\n\tLayerTypeSCTPShutdown                 = gopacket.RegisterLayerType(35, gopacket.LayerTypeMetadata{Name: \"SCTPShutdown\", Decoder: nil})\n\tLayerTypeSCTPShutdownAck              = gopacket.RegisterLayerType(36, gopacket.LayerTypeMetadata{Name: \"SCTPShutdownAck\", Decoder: nil})\n\tLayerTypeSCTPCookieEcho               = gopacket.RegisterLayerType(37, gopacket.LayerTypeMetadata{Name: \"SCTPCookieEcho\", Decoder: nil})\n\tLayerTypeSCTPEmptyLayer               = gopacket.RegisterLayerType(38, gopacket.LayerTypeMetadata{Name: \"SCTPEmptyLayer\", Decoder: nil})\n\tLayerTypeSCTPInitAck                  = gopacket.RegisterLayerType(39, gopacket.LayerTypeMetadata{Name: \"SCTPInitAck\", Decoder: nil})\n\tLayerTypeSCTPHeartbeatAck             = gopacket.RegisterLayerType(40, gopacket.LayerTypeMetadata{Name: \"SCTPHeartbeatAck\", Decoder: nil})\n\tLayerTypeSCTPAbort                    = gopacket.RegisterLayerType(41, gopacket.LayerTypeMetadata{Name: \"SCTPAbort\", Decoder: nil})\n\tLayerTypeSCTPShutdownComplete         = gopacket.RegisterLayerType(42, gopacket.LayerTypeMetadata{Name: \"SCTPShutdownComplete\", Decoder: nil})\n\tLayerTypeSCTPCookieAck                = gopacket.RegisterLayerType(43, gopacket.LayerTypeMetadata{Name: \"SCTPCookieAck\", Decoder: nil})\n\tLayerTypeTCP                          = gopacket.RegisterLayerType(44, gopacket.LayerTypeMetadata{Name: \"TCP\", Decoder: gopacket.DecodeFunc(decodeTCP)})\n\tLayerTypeUDP                          = gopacket.RegisterLayerType(45, gopacket.LayerTypeMetadata{Name: \"UDP\", Decoder: gopacket.DecodeFunc(decodeUDP)})\n\tLayerTypeIPv6HopByHop                 = gopacket.RegisterLayerType(46, gopacket.LayerTypeMetadata{Name: \"IPv6HopByHop\", Decoder: gopacket.DecodeFunc(decodeIPv6HopByHop)})\n\tLayerTypeIPv6Routing                  = gopacket.RegisterLayerType(47, gopacket.LayerTypeMetadata{Name: \"IPv6Routing\", Decoder: gopacket.DecodeFunc(decodeIPv6Routing)})\n\tLayerTypeIPv6Fragment                 = gopacket.RegisterLayerType(48, gopacket.LayerTypeMetadata{Name: \"IPv6Fragment\", Decoder: gopacket.DecodeFunc(decodeIPv6Fragment)})\n\tLayerTypeIPv6Destination              = gopacket.RegisterLayerType(49, gopacket.LayerTypeMetadata{Name: \"IPv6Destination\", Decoder: gopacket.DecodeFunc(decodeIPv6Destination)})\n\tLayerTypeIPSecAH                      = gopacket.RegisterLayerType(50, gopacket.LayerTypeMetadata{Name: \"IPSecAH\", Decoder: gopacket.DecodeFunc(decodeIPSecAH)})\n\tLayerTypeIPSecESP                     = gopacket.RegisterLayerType(51, gopacket.LayerTypeMetadata{Name: \"IPSecESP\", Decoder: gopacket.DecodeFunc(decodeIPSecESP)})\n\tLayerTypeUDPLite                      = gopacket.RegisterLayerType(52, gopacket.LayerTypeMetadata{Name: \"UDPLite\", Decoder: gopacket.DecodeFunc(decodeUDPLite)})\n\tLayerTypeFDDI                         = gopacket.RegisterLayerType(53, gopacket.LayerTypeMetadata{Name: \"FDDI\", Decoder: gopacket.DecodeFunc(decodeFDDI)})\n\tLayerTypeLoopback                     = gopacket.RegisterLayerType(54, gopacket.LayerTypeMetadata{Name: \"Loopback\", Decoder: gopacket.DecodeFunc(decodeLoopback)})\n\tLayerTypeEAP                          = gopacket.RegisterLayerType(55, gopacket.LayerTypeMetadata{Name: \"EAP\", Decoder: gopacket.DecodeFunc(decodeEAP)})\n\tLayerTypeEAPOL                        = gopacket.RegisterLayerType(56, gopacket.LayerTypeMetadata{Name: \"EAPOL\", Decoder: gopacket.DecodeFunc(decodeEAPOL)})\n\tLayerTypeICMPv6                       = gopacket.RegisterLayerType(57, gopacket.LayerTypeMetadata{Name: \"ICMPv6\", Decoder: gopacket.DecodeFunc(decodeICMPv6)})\n\tLayerTypeLinkLayerDiscovery           = gopacket.RegisterLayerType(58, gopacket.LayerTypeMetadata{Name: \"LinkLayerDiscovery\", Decoder: gopacket.DecodeFunc(decodeLinkLayerDiscovery)})\n\tLayerTypeCiscoDiscoveryInfo           = gopacket.RegisterLayerType(59, gopacket.LayerTypeMetadata{Name: \"CiscoDiscoveryInfo\", Decoder: gopacket.DecodeFunc(decodeCiscoDiscoveryInfo)})\n\tLayerTypeLinkLayerDiscoveryInfo       = gopacket.RegisterLayerType(60, gopacket.LayerTypeMetadata{Name: \"LinkLayerDiscoveryInfo\", Decoder: nil})\n\tLayerTypeNortelDiscovery              = gopacket.RegisterLayerType(61, gopacket.LayerTypeMetadata{Name: \"NortelDiscovery\", Decoder: gopacket.DecodeFunc(decodeNortelDiscovery)})\n\tLayerTypeIGMP                         = gopacket.RegisterLayerType(62, gopacket.LayerTypeMetadata{Name: \"IGMP\", Decoder: gopacket.DecodeFunc(decodeIGMP)})\n\tLayerTypePFLog                        = gopacket.RegisterLayerType(63, gopacket.LayerTypeMetadata{Name: \"PFLog\", Decoder: gopacket.DecodeFunc(decodePFLog)})\n\tLayerTypeRadioTap                     = gopacket.RegisterLayerType(64, gopacket.LayerTypeMetadata{Name: \"RadioTap\", Decoder: gopacket.DecodeFunc(decodeRadioTap)})\n\tLayerTypeDot11                        = gopacket.RegisterLayerType(65, gopacket.LayerTypeMetadata{Name: \"Dot11\", Decoder: gopacket.DecodeFunc(decodeDot11)})\n\tLayerTypeDot11Ctrl                    = gopacket.RegisterLayerType(66, gopacket.LayerTypeMetadata{Name: \"Dot11Ctrl\", Decoder: gopacket.DecodeFunc(decodeDot11Ctrl)})\n\tLayerTypeDot11Data                    = gopacket.RegisterLayerType(67, gopacket.LayerTypeMetadata{Name: \"Dot11Data\", Decoder: gopacket.DecodeFunc(decodeDot11Data)})\n\tLayerTypeDot11DataCFAck               = gopacket.RegisterLayerType(68, gopacket.LayerTypeMetadata{Name: \"Dot11DataCFAck\", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAck)})\n\tLayerTypeDot11DataCFPoll              = gopacket.RegisterLayerType(69, gopacket.LayerTypeMetadata{Name: \"Dot11DataCFPoll\", Decoder: gopacket.DecodeFunc(decodeDot11DataCFPoll)})\n\tLayerTypeDot11DataCFAckPoll           = gopacket.RegisterLayerType(70, gopacket.LayerTypeMetadata{Name: \"Dot11DataCFAckPoll\", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAckPoll)})\n\tLayerTypeDot11DataNull                = gopacket.RegisterLayerType(71, gopacket.LayerTypeMetadata{Name: \"Dot11DataNull\", Decoder: gopacket.DecodeFunc(decodeDot11DataNull)})\n\tLayerTypeDot11DataCFAckNoData         = gopacket.RegisterLayerType(72, gopacket.LayerTypeMetadata{Name: \"Dot11DataCFAck\", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAck)})\n\tLayerTypeDot11DataCFPollNoData        = gopacket.RegisterLayerType(73, gopacket.LayerTypeMetadata{Name: \"Dot11DataCFPoll\", Decoder: gopacket.DecodeFunc(decodeDot11DataCFPoll)})\n\tLayerTypeDot11DataCFAckPollNoData     = gopacket.RegisterLayerType(74, gopacket.LayerTypeMetadata{Name: \"Dot11DataCFAckPoll\", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAckPoll)})\n\tLayerTypeDot11DataQOSData             = gopacket.RegisterLayerType(75, gopacket.LayerTypeMetadata{Name: \"Dot11DataQOSData\", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSData)})\n\tLayerTypeDot11DataQOSDataCFAck        = gopacket.RegisterLayerType(76, gopacket.LayerTypeMetadata{Name: \"Dot11DataQOSDataCFAck\", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAck)})\n\tLayerTypeDot11DataQOSDataCFPoll       = gopacket.RegisterLayerType(77, gopacket.LayerTypeMetadata{Name: \"Dot11DataQOSDataCFPoll\", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFPoll)})\n\tLayerTypeDot11DataQOSDataCFAckPoll    = gopacket.RegisterLayerType(78, gopacket.LayerTypeMetadata{Name: \"Dot11DataQOSDataCFAckPoll\", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAckPoll)})\n\tLayerTypeDot11DataQOSNull             = gopacket.RegisterLayerType(79, gopacket.LayerTypeMetadata{Name: \"Dot11DataQOSNull\", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSNull)})\n\tLayerTypeDot11DataQOSCFPollNoData     = gopacket.RegisterLayerType(80, gopacket.LayerTypeMetadata{Name: \"Dot11DataQOSCFPoll\", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSCFPollNoData)})\n\tLayerTypeDot11DataQOSCFAckPollNoData  = gopacket.RegisterLayerType(81, gopacket.LayerTypeMetadata{Name: \"Dot11DataQOSCFAckPoll\", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSCFAckPollNoData)})\n\tLayerTypeDot11InformationElement      = gopacket.RegisterLayerType(82, gopacket.LayerTypeMetadata{Name: \"Dot11InformationElement\", Decoder: gopacket.DecodeFunc(decodeDot11InformationElement)})\n\tLayerTypeDot11CtrlCTS                 = gopacket.RegisterLayerType(83, gopacket.LayerTypeMetadata{Name: \"Dot11CtrlCTS\", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCTS)})\n\tLayerTypeDot11CtrlRTS                 = gopacket.RegisterLayerType(84, gopacket.LayerTypeMetadata{Name: \"Dot11CtrlRTS\", Decoder: gopacket.DecodeFunc(decodeDot11CtrlRTS)})\n\tLayerTypeDot11CtrlBlockAckReq         = gopacket.RegisterLayerType(85, gopacket.LayerTypeMetadata{Name: \"Dot11CtrlBlockAckReq\", Decoder: gopacket.DecodeFunc(decodeDot11CtrlBlockAckReq)})\n\tLayerTypeDot11CtrlBlockAck            = gopacket.RegisterLayerType(86, gopacket.LayerTypeMetadata{Name: \"Dot11CtrlBlockAck\", Decoder: gopacket.DecodeFunc(decodeDot11CtrlBlockAck)})\n\tLayerTypeDot11CtrlPowersavePoll       = gopacket.RegisterLayerType(87, gopacket.LayerTypeMetadata{Name: \"Dot11CtrlPowersavePoll\", Decoder: gopacket.DecodeFunc(decodeDot11CtrlPowersavePoll)})\n\tLayerTypeDot11CtrlAck                 = gopacket.RegisterLayerType(88, gopacket.LayerTypeMetadata{Name: \"Dot11CtrlAck\", Decoder: gopacket.DecodeFunc(decodeDot11CtrlAck)})\n\tLayerTypeDot11CtrlCFEnd               = gopacket.RegisterLayerType(89, gopacket.LayerTypeMetadata{Name: \"Dot11CtrlCFEnd\", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCFEnd)})\n\tLayerTypeDot11CtrlCFEndAck            = gopacket.RegisterLayerType(90, gopacket.LayerTypeMetadata{Name: \"Dot11CtrlCFEndAck\", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCFEndAck)})\n\tLayerTypeDot11MgmtAssociationReq      = gopacket.RegisterLayerType(91, gopacket.LayerTypeMetadata{Name: \"Dot11MgmtAssociationReq\", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAssociationReq)})\n\tLayerTypeDot11MgmtAssociationResp     = gopacket.RegisterLayerType(92, gopacket.LayerTypeMetadata{Name: \"Dot11MgmtAssociationResp\", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAssociationResp)})\n\tLayerTypeDot11MgmtReassociationReq    = gopacket.RegisterLayerType(93, gopacket.LayerTypeMetadata{Name: \"Dot11MgmtReassociationReq\", Decoder: gopacket.DecodeFunc(decodeDot11MgmtReassociationReq)})\n\tLayerTypeDot11MgmtReassociationResp   = gopacket.RegisterLayerType(94, gopacket.LayerTypeMetadata{Name: \"Dot11MgmtReassociationResp\", Decoder: gopacket.DecodeFunc(decodeDot11MgmtReassociationResp)})\n\tLayerTypeDot11MgmtProbeReq            = gopacket.RegisterLayerType(95, gopacket.LayerTypeMetadata{Name: \"Dot11MgmtProbeReq\", Decoder: gopacket.DecodeFunc(decodeDot11MgmtProbeReq)})\n\tLayerTypeDot11MgmtProbeResp           = gopacket.RegisterLayerType(96, gopacket.LayerTypeMetadata{Name: \"Dot11MgmtProbeResp\", Decoder: gopacket.DecodeFunc(decodeDot11MgmtProbeResp)})\n\tLayerTypeDot11MgmtMeasurementPilot    = gopacket.RegisterLayerType(97, gopacket.LayerTypeMetadata{Name: \"Dot11MgmtMeasurementPilot\", Decoder: gopacket.DecodeFunc(decodeDot11MgmtMeasurementPilot)})\n\tLayerTypeDot11MgmtBeacon              = gopacket.RegisterLayerType(98, gopacket.LayerTypeMetadata{Name: \"Dot11MgmtBeacon\", Decoder: gopacket.DecodeFunc(decodeDot11MgmtBeacon)})\n\tLayerTypeDot11MgmtATIM                = gopacket.RegisterLayerType(99, gopacket.LayerTypeMetadata{Name: \"Dot11MgmtATIM\", Decoder: gopacket.DecodeFunc(decodeDot11MgmtATIM)})\n\tLayerTypeDot11MgmtDisassociation      = gopacket.RegisterLayerType(100, gopacket.LayerTypeMetadata{Name: \"Dot11MgmtDisassociation\", Decoder: gopacket.DecodeFunc(decodeDot11MgmtDisassociation)})\n\tLayerTypeDot11MgmtAuthentication      = gopacket.RegisterLayerType(101, gopacket.LayerTypeMetadata{Name: \"Dot11MgmtAuthentication\", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAuthentication)})\n\tLayerTypeDot11MgmtDeauthentication    = gopacket.RegisterLayerType(102, gopacket.LayerTypeMetadata{Name: \"Dot11MgmtDeauthentication\", Decoder: gopacket.DecodeFunc(decodeDot11MgmtDeauthentication)})\n\tLayerTypeDot11MgmtAction              = gopacket.RegisterLayerType(103, gopacket.LayerTypeMetadata{Name: \"Dot11MgmtAction\", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAction)})\n\tLayerTypeDot11MgmtActionNoAck         = gopacket.RegisterLayerType(104, gopacket.LayerTypeMetadata{Name: \"Dot11MgmtActionNoAck\", Decoder: gopacket.DecodeFunc(decodeDot11MgmtActionNoAck)})\n\tLayerTypeDot11MgmtArubaWLAN           = gopacket.RegisterLayerType(105, gopacket.LayerTypeMetadata{Name: \"Dot11MgmtArubaWLAN\", Decoder: gopacket.DecodeFunc(decodeDot11MgmtArubaWLAN)})\n\tLayerTypeDot11WEP                     = gopacket.RegisterLayerType(106, gopacket.LayerTypeMetadata{Name: \"Dot11WEP\", Decoder: gopacket.DecodeFunc(decodeDot11WEP)})\n\tLayerTypeDNS                          = gopacket.RegisterLayerType(107, gopacket.LayerTypeMetadata{Name: \"DNS\", Decoder: gopacket.DecodeFunc(decodeDNS)})\n\tLayerTypeUSB                          = gopacket.RegisterLayerType(108, gopacket.LayerTypeMetadata{Name: \"USB\", Decoder: gopacket.DecodeFunc(decodeUSB)})\n\tLayerTypeUSBRequestBlockSetup         = gopacket.RegisterLayerType(109, gopacket.LayerTypeMetadata{Name: \"USBRequestBlockSetup\", Decoder: gopacket.DecodeFunc(decodeUSBRequestBlockSetup)})\n\tLayerTypeUSBControl                   = gopacket.RegisterLayerType(110, gopacket.LayerTypeMetadata{Name: \"USBControl\", Decoder: gopacket.DecodeFunc(decodeUSBControl)})\n\tLayerTypeUSBInterrupt                 = gopacket.RegisterLayerType(111, gopacket.LayerTypeMetadata{Name: \"USBInterrupt\", Decoder: gopacket.DecodeFunc(decodeUSBInterrupt)})\n\tLayerTypeUSBBulk                      = gopacket.RegisterLayerType(112, gopacket.LayerTypeMetadata{Name: \"USBBulk\", Decoder: gopacket.DecodeFunc(decodeUSBBulk)})\n\tLayerTypeLinuxSLL                     = gopacket.RegisterLayerType(113, gopacket.LayerTypeMetadata{Name: \"Linux SLL\", Decoder: gopacket.DecodeFunc(decodeLinuxSLL)})\n\tLayerTypeSFlow                        = gopacket.RegisterLayerType(114, gopacket.LayerTypeMetadata{Name: \"SFlow\", Decoder: gopacket.DecodeFunc(decodeSFlow)})\n\tLayerTypePrismHeader                  = gopacket.RegisterLayerType(115, gopacket.LayerTypeMetadata{Name: \"Prism monitor mode header\", Decoder: gopacket.DecodeFunc(decodePrismHeader)})\n\tLayerTypeVXLAN                        = gopacket.RegisterLayerType(116, gopacket.LayerTypeMetadata{Name: \"VXLAN\", Decoder: gopacket.DecodeFunc(decodeVXLAN)})\n\tLayerTypeNTP                          = gopacket.RegisterLayerType(117, gopacket.LayerTypeMetadata{Name: \"NTP\", Decoder: gopacket.DecodeFunc(decodeNTP)})\n\tLayerTypeDHCPv4                       = gopacket.RegisterLayerType(118, gopacket.LayerTypeMetadata{Name: \"DHCPv4\", Decoder: gopacket.DecodeFunc(decodeDHCPv4)})\n\tLayerTypeVRRP                         = gopacket.RegisterLayerType(119, gopacket.LayerTypeMetadata{Name: \"VRRP\", Decoder: gopacket.DecodeFunc(decodeVRRP)})\n\tLayerTypeGeneve                       = gopacket.RegisterLayerType(120, gopacket.LayerTypeMetadata{Name: \"Geneve\", Decoder: gopacket.DecodeFunc(decodeGeneve)})\n\tLayerTypeSTP                          = gopacket.RegisterLayerType(121, gopacket.LayerTypeMetadata{Name: \"STP\", Decoder: gopacket.DecodeFunc(decodeSTP)})\n\tLayerTypeBFD                          = gopacket.RegisterLayerType(122, gopacket.LayerTypeMetadata{Name: \"BFD\", Decoder: gopacket.DecodeFunc(decodeBFD)})\n\tLayerTypeOSPF                         = gopacket.RegisterLayerType(123, gopacket.LayerTypeMetadata{Name: \"OSPF\", Decoder: gopacket.DecodeFunc(decodeOSPF)})\n\tLayerTypeICMPv6RouterSolicitation     = gopacket.RegisterLayerType(124, gopacket.LayerTypeMetadata{Name: \"ICMPv6RouterSolicitation\", Decoder: gopacket.DecodeFunc(decodeICMPv6RouterSolicitation)})\n\tLayerTypeICMPv6RouterAdvertisement    = gopacket.RegisterLayerType(125, gopacket.LayerTypeMetadata{Name: \"ICMPv6RouterAdvertisement\", Decoder: gopacket.DecodeFunc(decodeICMPv6RouterAdvertisement)})\n\tLayerTypeICMPv6NeighborSolicitation   = gopacket.RegisterLayerType(126, gopacket.LayerTypeMetadata{Name: \"ICMPv6NeighborSolicitation\", Decoder: gopacket.DecodeFunc(decodeICMPv6NeighborSolicitation)})\n\tLayerTypeICMPv6NeighborAdvertisement  = gopacket.RegisterLayerType(127, gopacket.LayerTypeMetadata{Name: \"ICMPv6NeighborAdvertisement\", Decoder: gopacket.DecodeFunc(decodeICMPv6NeighborAdvertisement)})\n\tLayerTypeICMPv6Redirect               = gopacket.RegisterLayerType(128, gopacket.LayerTypeMetadata{Name: \"ICMPv6Redirect\", Decoder: gopacket.DecodeFunc(decodeICMPv6Redirect)})\n\tLayerTypeGTPv1U                       = gopacket.RegisterLayerType(129, gopacket.LayerTypeMetadata{Name: \"GTPv1U\", Decoder: gopacket.DecodeFunc(decodeGTPv1u)})\n\tLayerTypeEAPOLKey                     = gopacket.RegisterLayerType(130, gopacket.LayerTypeMetadata{Name: \"EAPOLKey\", Decoder: gopacket.DecodeFunc(decodeEAPOLKey)})\n\tLayerTypeLCM                          = gopacket.RegisterLayerType(131, gopacket.LayerTypeMetadata{Name: \"LCM\", Decoder: gopacket.DecodeFunc(decodeLCM)})\n\tLayerTypeICMPv6Echo                   = gopacket.RegisterLayerType(132, gopacket.LayerTypeMetadata{Name: \"ICMPv6Echo\", Decoder: gopacket.DecodeFunc(decodeICMPv6Echo)})\n\tLayerTypeSIP                          = gopacket.RegisterLayerType(133, gopacket.LayerTypeMetadata{Name: \"SIP\", Decoder: gopacket.DecodeFunc(decodeSIP)})\n\tLayerTypeDHCPv6                       = gopacket.RegisterLayerType(134, gopacket.LayerTypeMetadata{Name: \"DHCPv6\", Decoder: gopacket.DecodeFunc(decodeDHCPv6)})\n\tLayerTypeMLDv1MulticastListenerReport = gopacket.RegisterLayerType(135, gopacket.LayerTypeMetadata{Name: \"MLDv1MulticastListenerReport\", Decoder: gopacket.DecodeFunc(decodeMLDv1MulticastListenerReport)})\n\tLayerTypeMLDv1MulticastListenerDone   = gopacket.RegisterLayerType(136, gopacket.LayerTypeMetadata{Name: \"MLDv1MulticastListenerDone\", Decoder: gopacket.DecodeFunc(decodeMLDv1MulticastListenerDone)})\n\tLayerTypeMLDv1MulticastListenerQuery  = gopacket.RegisterLayerType(137, gopacket.LayerTypeMetadata{Name: \"MLDv1MulticastListenerQuery\", Decoder: gopacket.DecodeFunc(decodeMLDv1MulticastListenerQuery)})\n\tLayerTypeMLDv2MulticastListenerReport = gopacket.RegisterLayerType(138, gopacket.LayerTypeMetadata{Name: \"MLDv2MulticastListenerReport\", Decoder: gopacket.DecodeFunc(decodeMLDv2MulticastListenerReport)})\n\tLayerTypeMLDv2MulticastListenerQuery  = gopacket.RegisterLayerType(139, gopacket.LayerTypeMetadata{Name: \"MLDv2MulticastListenerQuery\", Decoder: gopacket.DecodeFunc(decodeMLDv2MulticastListenerQuery)})\n\tLayerTypeTLS                          = gopacket.RegisterLayerType(140, gopacket.LayerTypeMetadata{Name: \"TLS\", Decoder: gopacket.DecodeFunc(decodeTLS)})\n\tLayerTypeModbusTCP                    = gopacket.RegisterLayerType(141, gopacket.LayerTypeMetadata{Name: \"ModbusTCP\", Decoder: gopacket.DecodeFunc(decodeModbusTCP)})\n\tLayerTypeRMCP                         = gopacket.RegisterLayerType(142, gopacket.LayerTypeMetadata{Name: \"RMCP\", Decoder: gopacket.DecodeFunc(decodeRMCP)})\n\tLayerTypeASF                          = gopacket.RegisterLayerType(143, gopacket.LayerTypeMetadata{Name: \"ASF\", Decoder: gopacket.DecodeFunc(decodeASF)})\n\tLayerTypeASFPresencePong              = gopacket.RegisterLayerType(144, gopacket.LayerTypeMetadata{Name: \"ASFPresencePong\", Decoder: gopacket.DecodeFunc(decodeASFPresencePong)})\n\tLayerTypeERSPANII                     = gopacket.RegisterLayerType(145, gopacket.LayerTypeMetadata{Name: \"ERSPAN Type II\", Decoder: gopacket.DecodeFunc(decodeERSPANII)})\n\tLayerTypeRADIUS                       = gopacket.RegisterLayerType(146, gopacket.LayerTypeMetadata{Name: \"RADIUS\", Decoder: gopacket.DecodeFunc(decodeRADIUS)})\n)\n\nvar (\n\t// LayerClassIPNetwork contains TCP/IP network layer types.\n\tLayerClassIPNetwork = gopacket.NewLayerClass([]gopacket.LayerType{\n\t\tLayerTypeIPv4,\n\t\tLayerTypeIPv6,\n\t})\n\t// LayerClassIPTransport contains TCP/IP transport layer types.\n\tLayerClassIPTransport = gopacket.NewLayerClass([]gopacket.LayerType{\n\t\tLayerTypeTCP,\n\t\tLayerTypeUDP,\n\t\tLayerTypeSCTP,\n\t})\n\t// LayerClassIPControl contains TCP/IP control protocols.\n\tLayerClassIPControl = gopacket.NewLayerClass([]gopacket.LayerType{\n\t\tLayerTypeICMPv4,\n\t\tLayerTypeICMPv6,\n\t})\n\t// LayerClassSCTPChunk contains SCTP chunk types (not the top-level SCTP\n\t// layer).\n\tLayerClassSCTPChunk = gopacket.NewLayerClass([]gopacket.LayerType{\n\t\tLayerTypeSCTPUnknownChunkType,\n\t\tLayerTypeSCTPData,\n\t\tLayerTypeSCTPInit,\n\t\tLayerTypeSCTPSack,\n\t\tLayerTypeSCTPHeartbeat,\n\t\tLayerTypeSCTPError,\n\t\tLayerTypeSCTPShutdown,\n\t\tLayerTypeSCTPShutdownAck,\n\t\tLayerTypeSCTPCookieEcho,\n\t\tLayerTypeSCTPEmptyLayer,\n\t\tLayerTypeSCTPInitAck,\n\t\tLayerTypeSCTPHeartbeatAck,\n\t\tLayerTypeSCTPAbort,\n\t\tLayerTypeSCTPShutdownComplete,\n\t\tLayerTypeSCTPCookieAck,\n\t})\n\t// LayerClassIPv6Extension contains IPv6 extension headers.\n\tLayerClassIPv6Extension = gopacket.NewLayerClass([]gopacket.LayerType{\n\t\tLayerTypeIPv6HopByHop,\n\t\tLayerTypeIPv6Routing,\n\t\tLayerTypeIPv6Fragment,\n\t\tLayerTypeIPv6Destination,\n\t})\n\tLayerClassIPSec = gopacket.NewLayerClass([]gopacket.LayerType{\n\t\tLayerTypeIPSecAH,\n\t\tLayerTypeIPSecESP,\n\t})\n\t// LayerClassICMPv6NDP contains ICMPv6 neighbor discovery protocol\n\t// messages.\n\tLayerClassICMPv6NDP = gopacket.NewLayerClass([]gopacket.LayerType{\n\t\tLayerTypeICMPv6RouterSolicitation,\n\t\tLayerTypeICMPv6RouterAdvertisement,\n\t\tLayerTypeICMPv6NeighborSolicitation,\n\t\tLayerTypeICMPv6NeighborAdvertisement,\n\t\tLayerTypeICMPv6Redirect,\n\t})\n\t// LayerClassMLDv1 contains multicast listener discovery protocol\n\tLayerClassMLDv1 = gopacket.NewLayerClass([]gopacket.LayerType{\n\t\tLayerTypeMLDv1MulticastListenerQuery,\n\t\tLayerTypeMLDv1MulticastListenerReport,\n\t\tLayerTypeMLDv1MulticastListenerDone,\n\t})\n\t// LayerClassMLDv2 contains multicast listener discovery protocol v2\n\tLayerClassMLDv2 = gopacket.NewLayerClass([]gopacket.LayerType{\n\t\tLayerTypeMLDv1MulticastListenerReport,\n\t\tLayerTypeMLDv1MulticastListenerDone,\n\t\tLayerTypeMLDv2MulticastListenerReport,\n\t\tLayerTypeMLDv1MulticastListenerQuery,\n\t\tLayerTypeMLDv2MulticastListenerQuery,\n\t})\n)\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/lcm.go",
    "content": "// Copyright 2018 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/google/gopacket\"\n)\n\nconst (\n\t// LCMShortHeaderMagic is the LCM small message header magic number\n\tLCMShortHeaderMagic uint32 = 0x4c433032\n\t// LCMFragmentedHeaderMagic is the LCM fragmented message header magic number\n\tLCMFragmentedHeaderMagic uint32 = 0x4c433033\n)\n\n// LCM (Lightweight Communications and Marshalling) is a set of libraries and\n// tools for message passing and data marshalling, targeted at real-time systems\n// where high-bandwidth and low latency are critical. It provides a\n// publish/subscribe message passing model and automatic\n// marshalling/unmarshalling code generation with bindings for applications in a\n// variety of programming languages.\n//\n// References\n//   https://lcm-proj.github.io/\n//   https://github.com/lcm-proj/lcm\ntype LCM struct {\n\t// Common (short & fragmented header) fields\n\tMagic          uint32\n\tSequenceNumber uint32\n\t// Fragmented header only fields\n\tPayloadSize    uint32\n\tFragmentOffset uint32\n\tFragmentNumber uint16\n\tTotalFragments uint16\n\t// Common field\n\tChannelName string\n\t// Gopacket helper fields\n\tFragmented  bool\n\tfingerprint LCMFingerprint\n\tcontents    []byte\n\tpayload     []byte\n}\n\n// LCMFingerprint is the type of a LCM fingerprint.\ntype LCMFingerprint uint64\n\nvar (\n\t// lcmLayerTypes contains a map of all LCM fingerprints that we support and\n\t// their LayerType\n\tlcmLayerTypes  = map[LCMFingerprint]gopacket.LayerType{}\n\tlayerTypeIndex = 1001\n)\n\n// RegisterLCMLayerType allows users to register decoders for the underlying\n// LCM payload. This is done based on the fingerprint that every LCM message\n// contains and which identifies it uniquely. If num is not the zero value it\n// will be used when registering with RegisterLayerType towards gopacket,\n// otherwise an incremental value starting from 1001 will be used.\nfunc RegisterLCMLayerType(num int, name string, fingerprint LCMFingerprint,\n\tdecoder gopacket.Decoder) gopacket.LayerType {\n\tmetadata := gopacket.LayerTypeMetadata{Name: name, Decoder: decoder}\n\n\tif num == 0 {\n\t\tnum = layerTypeIndex\n\t\tlayerTypeIndex++\n\t}\n\n\tlcmLayerTypes[fingerprint] = gopacket.RegisterLayerType(num, metadata)\n\n\treturn lcmLayerTypes[fingerprint]\n}\n\n// SupportedLCMFingerprints returns a slice of all LCM fingerprints that has\n// been registered so far.\nfunc SupportedLCMFingerprints() []LCMFingerprint {\n\tfingerprints := make([]LCMFingerprint, 0, len(lcmLayerTypes))\n\tfor fp := range lcmLayerTypes {\n\t\tfingerprints = append(fingerprints, fp)\n\t}\n\treturn fingerprints\n}\n\n// GetLCMLayerType returns the underlying LCM message's LayerType.\n// This LayerType has to be registered by using RegisterLCMLayerType.\nfunc GetLCMLayerType(fingerprint LCMFingerprint) gopacket.LayerType {\n\tlayerType, ok := lcmLayerTypes[fingerprint]\n\tif !ok {\n\t\treturn gopacket.LayerTypePayload\n\t}\n\n\treturn layerType\n}\n\nfunc decodeLCM(data []byte, p gopacket.PacketBuilder) error {\n\tlcm := &LCM{}\n\n\terr := lcm.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tp.AddLayer(lcm)\n\tp.SetApplicationLayer(lcm)\n\n\treturn p.NextDecoder(lcm.NextLayerType())\n}\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (lcm *LCM) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 8 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"LCM < 8 bytes\")\n\t}\n\toffset := 0\n\n\tlcm.Magic = binary.BigEndian.Uint32(data[offset:4])\n\toffset += 4\n\n\tif lcm.Magic != LCMShortHeaderMagic && lcm.Magic != LCMFragmentedHeaderMagic {\n\t\treturn fmt.Errorf(\"Received LCM header magic %v does not match know \"+\n\t\t\t\"LCM magic numbers. Dropping packet.\", lcm.Magic)\n\t}\n\n\tlcm.SequenceNumber = binary.BigEndian.Uint32(data[offset:8])\n\toffset += 4\n\n\tif lcm.Magic == LCMFragmentedHeaderMagic {\n\t\tlcm.Fragmented = true\n\n\t\tlcm.PayloadSize = binary.BigEndian.Uint32(data[offset : offset+4])\n\t\toffset += 4\n\n\t\tlcm.FragmentOffset = binary.BigEndian.Uint32(data[offset : offset+4])\n\t\toffset += 4\n\n\t\tlcm.FragmentNumber = binary.BigEndian.Uint16(data[offset : offset+2])\n\t\toffset += 2\n\n\t\tlcm.TotalFragments = binary.BigEndian.Uint16(data[offset : offset+2])\n\t\toffset += 2\n\t} else {\n\t\tlcm.Fragmented = false\n\t}\n\n\tif !lcm.Fragmented || (lcm.Fragmented && lcm.FragmentNumber == 0) {\n\t\tbuffer := make([]byte, 0)\n\t\tfor _, b := range data[offset:] {\n\t\t\toffset++\n\n\t\t\tif b == 0 {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tbuffer = append(buffer, b)\n\t\t}\n\n\t\tlcm.ChannelName = string(buffer)\n\t}\n\n\tlcm.fingerprint = LCMFingerprint(\n\t\tbinary.BigEndian.Uint64(data[offset : offset+8]))\n\n\tlcm.contents = data[:offset]\n\tlcm.payload = data[offset:]\n\n\treturn nil\n}\n\n// CanDecode returns a set of layers that LCM objects can decode.\n// As LCM objects can only decode the LCM layer, we just return that layer.\nfunc (lcm LCM) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeLCM\n}\n\n// NextLayerType specifies the LCM payload layer type following this header.\n// As LCM packets are serialized structs with uniq fingerprints for each uniq\n// combination of data types, lookup of correct layer type is based on that\n// fingerprint.\nfunc (lcm LCM) NextLayerType() gopacket.LayerType {\n\tif !lcm.Fragmented || (lcm.Fragmented && lcm.FragmentNumber == 0) {\n\t\treturn GetLCMLayerType(lcm.fingerprint)\n\t}\n\n\treturn gopacket.LayerTypeFragment\n}\n\n// LayerType returns LayerTypeLCM\nfunc (lcm LCM) LayerType() gopacket.LayerType {\n\treturn LayerTypeLCM\n}\n\n// LayerContents returns the contents of the LCM header.\nfunc (lcm LCM) LayerContents() []byte {\n\treturn lcm.contents\n}\n\n// LayerPayload returns the payload following this LCM header.\nfunc (lcm LCM) LayerPayload() []byte {\n\treturn lcm.payload\n}\n\n// Payload returns the payload following this LCM header.\nfunc (lcm LCM) Payload() []byte {\n\treturn lcm.LayerPayload()\n}\n\n// Fingerprint returns the LCM fingerprint of the underlying message.\nfunc (lcm LCM) Fingerprint() LCMFingerprint {\n\treturn lcm.fingerprint\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/linux_sll.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\n\t\"github.com/google/gopacket\"\n)\n\ntype LinuxSLLPacketType uint16\n\nconst (\n\tLinuxSLLPacketTypeHost      LinuxSLLPacketType = 0 // To us\n\tLinuxSLLPacketTypeBroadcast LinuxSLLPacketType = 1 // To all\n\tLinuxSLLPacketTypeMulticast LinuxSLLPacketType = 2 // To group\n\tLinuxSLLPacketTypeOtherhost LinuxSLLPacketType = 3 // To someone else\n\tLinuxSLLPacketTypeOutgoing  LinuxSLLPacketType = 4 // Outgoing of any type\n\t// These ones are invisible by user level\n\tLinuxSLLPacketTypeLoopback  LinuxSLLPacketType = 5 // MC/BRD frame looped back\n\tLinuxSLLPacketTypeFastroute LinuxSLLPacketType = 6 // Fastrouted frame\n)\n\nfunc (l LinuxSLLPacketType) String() string {\n\tswitch l {\n\tcase LinuxSLLPacketTypeHost:\n\t\treturn \"host\"\n\tcase LinuxSLLPacketTypeBroadcast:\n\t\treturn \"broadcast\"\n\tcase LinuxSLLPacketTypeMulticast:\n\t\treturn \"multicast\"\n\tcase LinuxSLLPacketTypeOtherhost:\n\t\treturn \"otherhost\"\n\tcase LinuxSLLPacketTypeOutgoing:\n\t\treturn \"outgoing\"\n\tcase LinuxSLLPacketTypeLoopback:\n\t\treturn \"loopback\"\n\tcase LinuxSLLPacketTypeFastroute:\n\t\treturn \"fastroute\"\n\t}\n\treturn fmt.Sprintf(\"Unknown(%d)\", int(l))\n}\n\ntype LinuxSLL struct {\n\tBaseLayer\n\tPacketType   LinuxSLLPacketType\n\tAddrLen      uint16\n\tAddr         net.HardwareAddr\n\tEthernetType EthernetType\n\tAddrType     uint16\n}\n\n// LayerType returns LayerTypeLinuxSLL.\nfunc (sll *LinuxSLL) LayerType() gopacket.LayerType { return LayerTypeLinuxSLL }\n\nfunc (sll *LinuxSLL) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeLinuxSLL\n}\n\nfunc (sll *LinuxSLL) LinkFlow() gopacket.Flow {\n\treturn gopacket.NewFlow(EndpointMAC, sll.Addr, nil)\n}\n\nfunc (sll *LinuxSLL) NextLayerType() gopacket.LayerType {\n\treturn sll.EthernetType.LayerType()\n}\n\nfunc (sll *LinuxSLL) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 16 {\n\t\treturn errors.New(\"Linux SLL packet too small\")\n\t}\n\tsll.PacketType = LinuxSLLPacketType(binary.BigEndian.Uint16(data[0:2]))\n\tsll.AddrType = binary.BigEndian.Uint16(data[2:4])\n\tsll.AddrLen = binary.BigEndian.Uint16(data[4:6])\n\n\tsll.Addr = net.HardwareAddr(data[6 : sll.AddrLen+6])\n\tsll.EthernetType = EthernetType(binary.BigEndian.Uint16(data[14:16]))\n\tsll.BaseLayer = BaseLayer{data[:16], data[16:]}\n\n\treturn nil\n}\n\nfunc decodeLinuxSLL(data []byte, p gopacket.PacketBuilder) error {\n\tsll := &LinuxSLL{}\n\tif err := sll.DecodeFromBytes(data, p); err != nil {\n\t\treturn err\n\t}\n\tp.AddLayer(sll)\n\tp.SetLinkLayer(sll)\n\treturn p.NextDecoder(sll.EthernetType)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/llc.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// LLC is the layer used for 802.2 Logical Link Control headers.\n// See http://standards.ieee.org/getieee802/download/802.2-1998.pdf\ntype LLC struct {\n\tBaseLayer\n\tDSAP    uint8\n\tIG      bool // true means group, false means individual\n\tSSAP    uint8\n\tCR      bool // true means response, false means command\n\tControl uint16\n}\n\n// LayerType returns gopacket.LayerTypeLLC.\nfunc (l *LLC) LayerType() gopacket.LayerType { return LayerTypeLLC }\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (l *LLC) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 3 {\n\t\treturn errors.New(\"LLC header too small\")\n\t}\n\tl.DSAP = data[0] & 0xFE\n\tl.IG = data[0]&0x1 != 0\n\tl.SSAP = data[1] & 0xFE\n\tl.CR = data[1]&0x1 != 0\n\tl.Control = uint16(data[2])\n\n\tif l.Control&0x1 == 0 || l.Control&0x3 == 0x1 {\n\t\tif len(data) < 4 {\n\t\t\treturn errors.New(\"LLC header too small\")\n\t\t}\n\t\tl.Control = l.Control<<8 | uint16(data[3])\n\t\tl.Contents = data[:4]\n\t\tl.Payload = data[4:]\n\t} else {\n\t\tl.Contents = data[:3]\n\t\tl.Payload = data[3:]\n\t}\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (l *LLC) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeLLC\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (l *LLC) NextLayerType() gopacket.LayerType {\n\tswitch {\n\tcase l.DSAP == 0xAA && l.SSAP == 0xAA:\n\t\treturn LayerTypeSNAP\n\tcase l.DSAP == 0x42 && l.SSAP == 0x42:\n\t\treturn LayerTypeSTP\n\t}\n\treturn gopacket.LayerTypeZero // Not implemented\n}\n\n// SNAP is used inside LLC.  See\n// http://standards.ieee.org/getieee802/download/802-2001.pdf.\n// From http://en.wikipedia.org/wiki/Subnetwork_Access_Protocol:\n//  \"[T]he Subnetwork Access Protocol (SNAP) is a mechanism for multiplexing,\n//  on networks using IEEE 802.2 LLC, more protocols than can be distinguished\n//  by the 8-bit 802.2 Service Access Point (SAP) fields.\"\ntype SNAP struct {\n\tBaseLayer\n\tOrganizationalCode []byte\n\tType               EthernetType\n}\n\n// LayerType returns gopacket.LayerTypeSNAP.\nfunc (s *SNAP) LayerType() gopacket.LayerType { return LayerTypeSNAP }\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (s *SNAP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 5 {\n\t\treturn errors.New(\"SNAP header too small\")\n\t}\n\ts.OrganizationalCode = data[:3]\n\ts.Type = EthernetType(binary.BigEndian.Uint16(data[3:5]))\n\ts.BaseLayer = BaseLayer{data[:5], data[5:]}\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (s *SNAP) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeSNAP\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (s *SNAP) NextLayerType() gopacket.LayerType {\n\t// See BUG(gconnel) in decodeSNAP\n\treturn s.Type.LayerType()\n}\n\nfunc decodeLLC(data []byte, p gopacket.PacketBuilder) error {\n\tl := &LLC{}\n\terr := l.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\tp.AddLayer(l)\n\treturn p.NextDecoder(l.NextLayerType())\n}\n\nfunc decodeSNAP(data []byte, p gopacket.PacketBuilder) error {\n\ts := &SNAP{}\n\terr := s.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\tp.AddLayer(s)\n\t// BUG(gconnell):  When decoding SNAP, we treat the SNAP type as an Ethernet\n\t// type.  This may not actually be an ethernet type in all cases,\n\t// depending on the organizational code.  Right now, we don't check.\n\treturn p.NextDecoder(s.Type)\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (l *LLC) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tvar igFlag, crFlag byte\n\tvar length int\n\n\tif l.Control&0xFF00 != 0 {\n\t\tlength = 4\n\t} else {\n\t\tlength = 3\n\t}\n\n\tif l.DSAP&0x1 != 0 {\n\t\treturn errors.New(\"DSAP value invalid, should not include IG flag bit\")\n\t}\n\n\tif l.SSAP&0x1 != 0 {\n\t\treturn errors.New(\"SSAP value invalid, should not include CR flag bit\")\n\t}\n\n\tif buf, err := b.PrependBytes(length); err != nil {\n\t\treturn err\n\t} else {\n\t\tigFlag = 0\n\t\tif l.IG {\n\t\t\tigFlag = 0x1\n\t\t}\n\n\t\tcrFlag = 0\n\t\tif l.CR {\n\t\t\tcrFlag = 0x1\n\t\t}\n\n\t\tbuf[0] = l.DSAP + igFlag\n\t\tbuf[1] = l.SSAP + crFlag\n\n\t\tif length == 4 {\n\t\t\tbuf[2] = uint8(l.Control >> 8)\n\t\t\tbuf[3] = uint8(l.Control)\n\t\t} else {\n\t\t\tbuf[2] = uint8(l.Control)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (s *SNAP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tif buf, err := b.PrependBytes(5); err != nil {\n\t\treturn err\n\t} else {\n\t\tbuf[0] = s.OrganizationalCode[0]\n\t\tbuf[1] = s.OrganizationalCode[1]\n\t\tbuf[2] = s.OrganizationalCode[2]\n\t\tbinary.BigEndian.PutUint16(buf[3:5], uint16(s.Type))\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/lldp.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// LLDPTLVType is the type of each TLV value in a LinkLayerDiscovery packet.\ntype LLDPTLVType byte\n\nconst (\n\tLLDPTLVEnd             LLDPTLVType = 0\n\tLLDPTLVChassisID       LLDPTLVType = 1\n\tLLDPTLVPortID          LLDPTLVType = 2\n\tLLDPTLVTTL             LLDPTLVType = 3\n\tLLDPTLVPortDescription LLDPTLVType = 4\n\tLLDPTLVSysName         LLDPTLVType = 5\n\tLLDPTLVSysDescription  LLDPTLVType = 6\n\tLLDPTLVSysCapabilities LLDPTLVType = 7\n\tLLDPTLVMgmtAddress     LLDPTLVType = 8\n\tLLDPTLVOrgSpecific     LLDPTLVType = 127\n)\n\n// LinkLayerDiscoveryValue is a TLV value inside a LinkLayerDiscovery packet layer.\ntype LinkLayerDiscoveryValue struct {\n\tType   LLDPTLVType\n\tLength uint16\n\tValue  []byte\n}\n\nfunc (c *LinkLayerDiscoveryValue) len() int {\n\treturn 0\n}\n\n// LLDPChassisIDSubType specifies the value type for a single LLDPChassisID.ID\ntype LLDPChassisIDSubType byte\n\n// LLDP Chassis Types\nconst (\n\tLLDPChassisIDSubTypeReserved    LLDPChassisIDSubType = 0\n\tLLDPChassisIDSubTypeChassisComp LLDPChassisIDSubType = 1\n\tLLDPChassisIDSubtypeIfaceAlias  LLDPChassisIDSubType = 2\n\tLLDPChassisIDSubTypePortComp    LLDPChassisIDSubType = 3\n\tLLDPChassisIDSubTypeMACAddr     LLDPChassisIDSubType = 4\n\tLLDPChassisIDSubTypeNetworkAddr LLDPChassisIDSubType = 5\n\tLLDPChassisIDSubtypeIfaceName   LLDPChassisIDSubType = 6\n\tLLDPChassisIDSubTypeLocal       LLDPChassisIDSubType = 7\n)\n\ntype LLDPChassisID struct {\n\tSubtype LLDPChassisIDSubType\n\tID      []byte\n}\n\nfunc (c *LLDPChassisID) serialize() []byte {\n\n\tvar buf = make([]byte, c.serializedLen())\n\tidLen := uint16(LLDPTLVChassisID)<<9 | uint16(len(c.ID)+1) //id should take 7 bits, length should take 9 bits, +1 for subtype\n\tbinary.BigEndian.PutUint16(buf[0:2], idLen)\n\tbuf[2] = byte(c.Subtype)\n\tcopy(buf[3:], c.ID)\n\treturn buf\n}\n\nfunc (c *LLDPChassisID) serializedLen() int {\n\treturn len(c.ID) + 3 // +2 for id and length, +1 for subtype\n}\n\n// LLDPPortIDSubType specifies the value type for a single LLDPPortID.ID\ntype LLDPPortIDSubType byte\n\n// LLDP PortID types\nconst (\n\tLLDPPortIDSubtypeReserved       LLDPPortIDSubType = 0\n\tLLDPPortIDSubtypeIfaceAlias     LLDPPortIDSubType = 1\n\tLLDPPortIDSubtypePortComp       LLDPPortIDSubType = 2\n\tLLDPPortIDSubtypeMACAddr        LLDPPortIDSubType = 3\n\tLLDPPortIDSubtypeNetworkAddr    LLDPPortIDSubType = 4\n\tLLDPPortIDSubtypeIfaceName      LLDPPortIDSubType = 5\n\tLLDPPortIDSubtypeAgentCircuitID LLDPPortIDSubType = 6\n\tLLDPPortIDSubtypeLocal          LLDPPortIDSubType = 7\n)\n\ntype LLDPPortID struct {\n\tSubtype LLDPPortIDSubType\n\tID      []byte\n}\n\nfunc (c *LLDPPortID) serialize() []byte {\n\n\tvar buf = make([]byte, c.serializedLen())\n\tidLen := uint16(LLDPTLVPortID)<<9 | uint16(len(c.ID)+1) //id should take 7 bits, length should take 9 bits, +1 for subtype\n\tbinary.BigEndian.PutUint16(buf[0:2], idLen)\n\tbuf[2] = byte(c.Subtype)\n\tcopy(buf[3:], c.ID)\n\treturn buf\n}\n\nfunc (c *LLDPPortID) serializedLen() int {\n\treturn len(c.ID) + 3 // +2 for id and length, +1 for subtype\n}\n\n// LinkLayerDiscovery is a packet layer containing the LinkLayer Discovery Protocol.\n// See http:http://standards.ieee.org/getieee802/download/802.1AB-2009.pdf\n// ChassisID, PortID and TTL are mandatory TLV's. Other values can be decoded\n// with DecodeValues()\ntype LinkLayerDiscovery struct {\n\tBaseLayer\n\tChassisID LLDPChassisID\n\tPortID    LLDPPortID\n\tTTL       uint16\n\tValues    []LinkLayerDiscoveryValue\n}\n\ntype IEEEOUI uint32\n\n// http://standards.ieee.org/develop/regauth/oui/oui.txt\nconst (\n\tIEEEOUI8021     IEEEOUI = 0x0080c2\n\tIEEEOUI8023     IEEEOUI = 0x00120f\n\tIEEEOUI80211    IEEEOUI = 0x000fac\n\tIEEEOUI8021Qbg  IEEEOUI = 0x0013BF\n\tIEEEOUICisco2   IEEEOUI = 0x000142\n\tIEEEOUIMedia    IEEEOUI = 0x0012bb // TR-41\n\tIEEEOUIProfinet IEEEOUI = 0x000ecf\n\tIEEEOUIDCBX     IEEEOUI = 0x001b21\n)\n\n// LLDPOrgSpecificTLV is an Organisation-specific TLV\ntype LLDPOrgSpecificTLV struct {\n\tOUI     IEEEOUI\n\tSubType uint8\n\tInfo    []byte\n}\n\n// LLDPCapabilities Types\nconst (\n\tLLDPCapsOther       uint16 = 1 << 0\n\tLLDPCapsRepeater    uint16 = 1 << 1\n\tLLDPCapsBridge      uint16 = 1 << 2\n\tLLDPCapsWLANAP      uint16 = 1 << 3\n\tLLDPCapsRouter      uint16 = 1 << 4\n\tLLDPCapsPhone       uint16 = 1 << 5\n\tLLDPCapsDocSis      uint16 = 1 << 6\n\tLLDPCapsStationOnly uint16 = 1 << 7\n\tLLDPCapsCVLAN       uint16 = 1 << 8\n\tLLDPCapsSVLAN       uint16 = 1 << 9\n\tLLDPCapsTmpr        uint16 = 1 << 10\n)\n\n// LLDPCapabilities represents the capabilities of a device\ntype LLDPCapabilities struct {\n\tOther       bool\n\tRepeater    bool\n\tBridge      bool\n\tWLANAP      bool\n\tRouter      bool\n\tPhone       bool\n\tDocSis      bool\n\tStationOnly bool\n\tCVLAN       bool\n\tSVLAN       bool\n\tTMPR        bool\n}\n\ntype LLDPSysCapabilities struct {\n\tSystemCap  LLDPCapabilities\n\tEnabledCap LLDPCapabilities\n}\n\ntype IANAAddressFamily byte\n\n// LLDP Management Address Subtypes\n// http://www.iana.org/assignments/address-family-numbers/address-family-numbers.xml\nconst (\n\tIANAAddressFamilyReserved IANAAddressFamily = 0\n\tIANAAddressFamilyIPV4     IANAAddressFamily = 1\n\tIANAAddressFamilyIPV6     IANAAddressFamily = 2\n\tIANAAddressFamilyNSAP     IANAAddressFamily = 3\n\tIANAAddressFamilyHDLC     IANAAddressFamily = 4\n\tIANAAddressFamilyBBN1822  IANAAddressFamily = 5\n\tIANAAddressFamily802      IANAAddressFamily = 6\n\tIANAAddressFamilyE163     IANAAddressFamily = 7\n\tIANAAddressFamilyE164     IANAAddressFamily = 8\n\tIANAAddressFamilyF69      IANAAddressFamily = 9\n\tIANAAddressFamilyX121     IANAAddressFamily = 10\n\tIANAAddressFamilyIPX      IANAAddressFamily = 11\n\tIANAAddressFamilyAtalk    IANAAddressFamily = 12\n\tIANAAddressFamilyDecnet   IANAAddressFamily = 13\n\tIANAAddressFamilyBanyan   IANAAddressFamily = 14\n\tIANAAddressFamilyE164NSAP IANAAddressFamily = 15\n\tIANAAddressFamilyDNS      IANAAddressFamily = 16\n\tIANAAddressFamilyDistname IANAAddressFamily = 17\n\tIANAAddressFamilyASNumber IANAAddressFamily = 18\n\tIANAAddressFamilyXTPIPV4  IANAAddressFamily = 19\n\tIANAAddressFamilyXTPIPV6  IANAAddressFamily = 20\n\tIANAAddressFamilyXTP      IANAAddressFamily = 21\n\tIANAAddressFamilyFcWWPN   IANAAddressFamily = 22\n\tIANAAddressFamilyFcWWNN   IANAAddressFamily = 23\n\tIANAAddressFamilyGWID     IANAAddressFamily = 24\n\tIANAAddressFamilyL2VPN    IANAAddressFamily = 25\n)\n\ntype LLDPInterfaceSubtype byte\n\n// LLDP Interface Subtypes\nconst (\n\tLLDPInterfaceSubtypeUnknown LLDPInterfaceSubtype = 1\n\tLLDPInterfaceSubtypeifIndex LLDPInterfaceSubtype = 2\n\tLLDPInterfaceSubtypeSysPort LLDPInterfaceSubtype = 3\n)\n\ntype LLDPMgmtAddress struct {\n\tSubtype          IANAAddressFamily\n\tAddress          []byte\n\tInterfaceSubtype LLDPInterfaceSubtype\n\tInterfaceNumber  uint32\n\tOID              string\n}\n\n// LinkLayerDiscoveryInfo represents the decoded details for a set of LinkLayerDiscoveryValues\n// Organisation-specific TLV's can be decoded using the various Decode() methods\ntype LinkLayerDiscoveryInfo struct {\n\tBaseLayer\n\tPortDescription string\n\tSysName         string\n\tSysDescription  string\n\tSysCapabilities LLDPSysCapabilities\n\tMgmtAddress     LLDPMgmtAddress\n\tOrgTLVs         []LLDPOrgSpecificTLV      // Private TLVs\n\tUnknown         []LinkLayerDiscoveryValue // undecoded TLVs\n}\n\n/// IEEE 802.1 TLV Subtypes\nconst (\n\tLLDP8021SubtypePortVLANID       uint8 = 1\n\tLLDP8021SubtypeProtocolVLANID   uint8 = 2\n\tLLDP8021SubtypeVLANName         uint8 = 3\n\tLLDP8021SubtypeProtocolIdentity uint8 = 4\n\tLLDP8021SubtypeVDIUsageDigest   uint8 = 5\n\tLLDP8021SubtypeManagementVID    uint8 = 6\n\tLLDP8021SubtypeLinkAggregation  uint8 = 7\n)\n\n// VLAN Port Protocol ID options\nconst (\n\tLLDPProtocolVLANIDCapability byte = 1 << 1\n\tLLDPProtocolVLANIDStatus     byte = 1 << 2\n)\n\ntype PortProtocolVLANID struct {\n\tSupported bool\n\tEnabled   bool\n\tID        uint16\n}\n\ntype VLANName struct {\n\tID   uint16\n\tName string\n}\n\ntype ProtocolIdentity []byte\n\n// LACP options\nconst (\n\tLLDPAggregationCapability byte = 1 << 0\n\tLLDPAggregationStatus     byte = 1 << 1\n)\n\n// IEEE 802 Link Aggregation parameters\ntype LLDPLinkAggregation struct {\n\tSupported bool\n\tEnabled   bool\n\tPortID    uint32\n}\n\n// LLDPInfo8021 represents the information carried in 802.1 Org-specific TLVs\ntype LLDPInfo8021 struct {\n\tPVID               uint16\n\tPPVIDs             []PortProtocolVLANID\n\tVLANNames          []VLANName\n\tProtocolIdentities []ProtocolIdentity\n\tVIDUsageDigest     uint32\n\tManagementVID      uint16\n\tLinkAggregation    LLDPLinkAggregation\n}\n\n// IEEE 802.3 TLV Subtypes\nconst (\n\tLLDP8023SubtypeMACPHY          uint8 = 1\n\tLLDP8023SubtypeMDIPower        uint8 = 2\n\tLLDP8023SubtypeLinkAggregation uint8 = 3\n\tLLDP8023SubtypeMTU             uint8 = 4\n)\n\n// MACPHY options\nconst (\n\tLLDPMACPHYCapability byte = 1 << 0\n\tLLDPMACPHYStatus     byte = 1 << 1\n)\n\n// From IANA-MAU-MIB (introduced by RFC 4836) - dot3MauType\nconst (\n\tLLDPMAUTypeUnknown         uint16 = 0\n\tLLDPMAUTypeAUI             uint16 = 1\n\tLLDPMAUType10Base5         uint16 = 2\n\tLLDPMAUTypeFOIRL           uint16 = 3\n\tLLDPMAUType10Base2         uint16 = 4\n\tLLDPMAUType10BaseT         uint16 = 5\n\tLLDPMAUType10BaseFP        uint16 = 6\n\tLLDPMAUType10BaseFB        uint16 = 7\n\tLLDPMAUType10BaseFL        uint16 = 8\n\tLLDPMAUType10BROAD36       uint16 = 9\n\tLLDPMAUType10BaseT_HD      uint16 = 10\n\tLLDPMAUType10BaseT_FD      uint16 = 11\n\tLLDPMAUType10BaseFL_HD     uint16 = 12\n\tLLDPMAUType10BaseFL_FD     uint16 = 13\n\tLLDPMAUType100BaseT4       uint16 = 14\n\tLLDPMAUType100BaseTX_HD    uint16 = 15\n\tLLDPMAUType100BaseTX_FD    uint16 = 16\n\tLLDPMAUType100BaseFX_HD    uint16 = 17\n\tLLDPMAUType100BaseFX_FD    uint16 = 18\n\tLLDPMAUType100BaseT2_HD    uint16 = 19\n\tLLDPMAUType100BaseT2_FD    uint16 = 20\n\tLLDPMAUType1000BaseX_HD    uint16 = 21\n\tLLDPMAUType1000BaseX_FD    uint16 = 22\n\tLLDPMAUType1000BaseLX_HD   uint16 = 23\n\tLLDPMAUType1000BaseLX_FD   uint16 = 24\n\tLLDPMAUType1000BaseSX_HD   uint16 = 25\n\tLLDPMAUType1000BaseSX_FD   uint16 = 26\n\tLLDPMAUType1000BaseCX_HD   uint16 = 27\n\tLLDPMAUType1000BaseCX_FD   uint16 = 28\n\tLLDPMAUType1000BaseT_HD    uint16 = 29\n\tLLDPMAUType1000BaseT_FD    uint16 = 30\n\tLLDPMAUType10GBaseX        uint16 = 31\n\tLLDPMAUType10GBaseLX4      uint16 = 32\n\tLLDPMAUType10GBaseR        uint16 = 33\n\tLLDPMAUType10GBaseER       uint16 = 34\n\tLLDPMAUType10GBaseLR       uint16 = 35\n\tLLDPMAUType10GBaseSR       uint16 = 36\n\tLLDPMAUType10GBaseW        uint16 = 37\n\tLLDPMAUType10GBaseEW       uint16 = 38\n\tLLDPMAUType10GBaseLW       uint16 = 39\n\tLLDPMAUType10GBaseSW       uint16 = 40\n\tLLDPMAUType10GBaseCX4      uint16 = 41\n\tLLDPMAUType2BaseTL         uint16 = 42\n\tLLDPMAUType10PASS_TS       uint16 = 43\n\tLLDPMAUType100BaseBX10D    uint16 = 44\n\tLLDPMAUType100BaseBX10U    uint16 = 45\n\tLLDPMAUType100BaseLX10     uint16 = 46\n\tLLDPMAUType1000BaseBX10D   uint16 = 47\n\tLLDPMAUType1000BaseBX10U   uint16 = 48\n\tLLDPMAUType1000BaseLX10    uint16 = 49\n\tLLDPMAUType1000BasePX10D   uint16 = 50\n\tLLDPMAUType1000BasePX10U   uint16 = 51\n\tLLDPMAUType1000BasePX20D   uint16 = 52\n\tLLDPMAUType1000BasePX20U   uint16 = 53\n\tLLDPMAUType10GBaseT        uint16 = 54\n\tLLDPMAUType10GBaseLRM      uint16 = 55\n\tLLDPMAUType1000BaseKX      uint16 = 56\n\tLLDPMAUType10GBaseKX4      uint16 = 57\n\tLLDPMAUType10GBaseKR       uint16 = 58\n\tLLDPMAUType10_1GBasePRX_D1 uint16 = 59\n\tLLDPMAUType10_1GBasePRX_D2 uint16 = 60\n\tLLDPMAUType10_1GBasePRX_D3 uint16 = 61\n\tLLDPMAUType10_1GBasePRX_U1 uint16 = 62\n\tLLDPMAUType10_1GBasePRX_U2 uint16 = 63\n\tLLDPMAUType10_1GBasePRX_U3 uint16 = 64\n\tLLDPMAUType10GBasePR_D1    uint16 = 65\n\tLLDPMAUType10GBasePR_D2    uint16 = 66\n\tLLDPMAUType10GBasePR_D3    uint16 = 67\n\tLLDPMAUType10GBasePR_U1    uint16 = 68\n\tLLDPMAUType10GBasePR_U3    uint16 = 69\n)\n\n// From RFC 3636 - ifMauAutoNegCapAdvertisedBits\nconst (\n\tLLDPMAUPMDOther        uint16 = 1 << 15\n\tLLDPMAUPMD10BaseT      uint16 = 1 << 14\n\tLLDPMAUPMD10BaseT_FD   uint16 = 1 << 13\n\tLLDPMAUPMD100BaseT4    uint16 = 1 << 12\n\tLLDPMAUPMD100BaseTX    uint16 = 1 << 11\n\tLLDPMAUPMD100BaseTX_FD uint16 = 1 << 10\n\tLLDPMAUPMD100BaseT2    uint16 = 1 << 9\n\tLLDPMAUPMD100BaseT2_FD uint16 = 1 << 8\n\tLLDPMAUPMDFDXPAUSE     uint16 = 1 << 7\n\tLLDPMAUPMDFDXAPAUSE    uint16 = 1 << 6\n\tLLDPMAUPMDFDXSPAUSE    uint16 = 1 << 5\n\tLLDPMAUPMDFDXBPAUSE    uint16 = 1 << 4\n\tLLDPMAUPMD1000BaseX    uint16 = 1 << 3\n\tLLDPMAUPMD1000BaseX_FD uint16 = 1 << 2\n\tLLDPMAUPMD1000BaseT    uint16 = 1 << 1\n\tLLDPMAUPMD1000BaseT_FD uint16 = 1 << 0\n)\n\n// Inverted ifMauAutoNegCapAdvertisedBits if required\n// (Some manufacturers misinterpreted the spec -\n// see https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=1455)\nconst (\n\tLLDPMAUPMDOtherInv        uint16 = 1 << 0\n\tLLDPMAUPMD10BaseTInv      uint16 = 1 << 1\n\tLLDPMAUPMD10BaseT_FDInv   uint16 = 1 << 2\n\tLLDPMAUPMD100BaseT4Inv    uint16 = 1 << 3\n\tLLDPMAUPMD100BaseTXInv    uint16 = 1 << 4\n\tLLDPMAUPMD100BaseTX_FDInv uint16 = 1 << 5\n\tLLDPMAUPMD100BaseT2Inv    uint16 = 1 << 6\n\tLLDPMAUPMD100BaseT2_FDInv uint16 = 1 << 7\n\tLLDPMAUPMDFDXPAUSEInv     uint16 = 1 << 8\n\tLLDPMAUPMDFDXAPAUSEInv    uint16 = 1 << 9\n\tLLDPMAUPMDFDXSPAUSEInv    uint16 = 1 << 10\n\tLLDPMAUPMDFDXBPAUSEInv    uint16 = 1 << 11\n\tLLDPMAUPMD1000BaseXInv    uint16 = 1 << 12\n\tLLDPMAUPMD1000BaseX_FDInv uint16 = 1 << 13\n\tLLDPMAUPMD1000BaseTInv    uint16 = 1 << 14\n\tLLDPMAUPMD1000BaseT_FDInv uint16 = 1 << 15\n)\n\ntype LLDPMACPHYConfigStatus struct {\n\tAutoNegSupported  bool\n\tAutoNegEnabled    bool\n\tAutoNegCapability uint16\n\tMAUType           uint16\n}\n\n// MDI Power options\nconst (\n\tLLDPMDIPowerPortClass    byte = 1 << 0\n\tLLDPMDIPowerCapability   byte = 1 << 1\n\tLLDPMDIPowerStatus       byte = 1 << 2\n\tLLDPMDIPowerPairsAbility byte = 1 << 3\n)\n\ntype LLDPPowerType byte\n\ntype LLDPPowerSource byte\n\ntype LLDPPowerPriority byte\n\nconst (\n\tLLDPPowerPriorityUnknown LLDPPowerPriority = 0\n\tLLDPPowerPriorityMedium  LLDPPowerPriority = 1\n\tLLDPPowerPriorityHigh    LLDPPowerPriority = 2\n\tLLDPPowerPriorityLow     LLDPPowerPriority = 3\n)\n\ntype LLDPPowerViaMDI8023 struct {\n\tPortClassPSE    bool // false = PD\n\tPSESupported    bool\n\tPSEEnabled      bool\n\tPSEPairsAbility bool\n\tPSEPowerPair    uint8\n\tPSEClass        uint8\n\tType            LLDPPowerType\n\tSource          LLDPPowerSource\n\tPriority        LLDPPowerPriority\n\tRequested       uint16 // 1-510 Watts\n\tAllocated       uint16 // 1-510 Watts\n}\n\n// LLDPInfo8023 represents the information carried in 802.3 Org-specific TLVs\ntype LLDPInfo8023 struct {\n\tMACPHYConfigStatus LLDPMACPHYConfigStatus\n\tPowerViaMDI        LLDPPowerViaMDI8023\n\tLinkAggregation    LLDPLinkAggregation\n\tMTU                uint16\n}\n\n// IEEE 802.1Qbg TLV Subtypes\nconst (\n\tLLDP8021QbgEVB   uint8 = 0\n\tLLDP8021QbgCDCP  uint8 = 1\n\tLLDP8021QbgVDP   uint8 = 2\n\tLLDP8021QbgEVB22 uint8 = 13\n)\n\n// LLDPEVBCapabilities Types\nconst (\n\tLLDPEVBCapsSTD uint16 = 1 << 7\n\tLLDPEVBCapsRR  uint16 = 1 << 6\n\tLLDPEVBCapsRTE uint16 = 1 << 2\n\tLLDPEVBCapsECP uint16 = 1 << 1\n\tLLDPEVBCapsVDP uint16 = 1 << 0\n)\n\n// LLDPEVBCapabilities represents the EVB capabilities of a device\ntype LLDPEVBCapabilities struct {\n\tStandardBridging            bool\n\tReflectiveRelay             bool\n\tRetransmissionTimerExponent bool\n\tEdgeControlProtocol         bool\n\tVSIDiscoveryProtocol        bool\n}\n\ntype LLDPEVBSettings struct {\n\tSupported      LLDPEVBCapabilities\n\tEnabled        LLDPEVBCapabilities\n\tSupportedVSIs  uint16\n\tConfiguredVSIs uint16\n\tRTEExponent    uint8\n}\n\n// LLDPInfo8021Qbg represents the information carried in 802.1Qbg Org-specific TLVs\ntype LLDPInfo8021Qbg struct {\n\tEVBSettings LLDPEVBSettings\n}\n\ntype LLDPMediaSubtype uint8\n\n// Media TLV Subtypes\nconst (\n\tLLDPMediaTypeCapabilities LLDPMediaSubtype = 1\n\tLLDPMediaTypeNetwork      LLDPMediaSubtype = 2\n\tLLDPMediaTypeLocation     LLDPMediaSubtype = 3\n\tLLDPMediaTypePower        LLDPMediaSubtype = 4\n\tLLDPMediaTypeHardware     LLDPMediaSubtype = 5\n\tLLDPMediaTypeFirmware     LLDPMediaSubtype = 6\n\tLLDPMediaTypeSoftware     LLDPMediaSubtype = 7\n\tLLDPMediaTypeSerial       LLDPMediaSubtype = 8\n\tLLDPMediaTypeManufacturer LLDPMediaSubtype = 9\n\tLLDPMediaTypeModel        LLDPMediaSubtype = 10\n\tLLDPMediaTypeAssetID      LLDPMediaSubtype = 11\n)\n\ntype LLDPMediaClass uint8\n\n// Media Class Values\nconst (\n\tLLDPMediaClassUndefined   LLDPMediaClass = 0\n\tLLDPMediaClassEndpointI   LLDPMediaClass = 1\n\tLLDPMediaClassEndpointII  LLDPMediaClass = 2\n\tLLDPMediaClassEndpointIII LLDPMediaClass = 3\n\tLLDPMediaClassNetwork     LLDPMediaClass = 4\n)\n\n// LLDPMediaCapabilities Types\nconst (\n\tLLDPMediaCapsLLDP      uint16 = 1 << 0\n\tLLDPMediaCapsNetwork   uint16 = 1 << 1\n\tLLDPMediaCapsLocation  uint16 = 1 << 2\n\tLLDPMediaCapsPowerPSE  uint16 = 1 << 3\n\tLLDPMediaCapsPowerPD   uint16 = 1 << 4\n\tLLDPMediaCapsInventory uint16 = 1 << 5\n)\n\n// LLDPMediaCapabilities represents the LLDP Media capabilities of a device\ntype LLDPMediaCapabilities struct {\n\tCapabilities  bool\n\tNetworkPolicy bool\n\tLocation      bool\n\tPowerPSE      bool\n\tPowerPD       bool\n\tInventory     bool\n\tClass         LLDPMediaClass\n}\n\ntype LLDPApplicationType uint8\n\nconst (\n\tLLDPAppTypeReserved            LLDPApplicationType = 0\n\tLLDPAppTypeVoice               LLDPApplicationType = 1\n\tLLDPappTypeVoiceSignaling      LLDPApplicationType = 2\n\tLLDPappTypeGuestVoice          LLDPApplicationType = 3\n\tLLDPappTypeGuestVoiceSignaling LLDPApplicationType = 4\n\tLLDPappTypeSoftphoneVoice      LLDPApplicationType = 5\n\tLLDPappTypeVideoConferencing   LLDPApplicationType = 6\n\tLLDPappTypeStreamingVideo      LLDPApplicationType = 7\n\tLLDPappTypeVideoSignaling      LLDPApplicationType = 8\n)\n\ntype LLDPNetworkPolicy struct {\n\tApplicationType LLDPApplicationType\n\tDefined         bool\n\tTagged          bool\n\tVLANId          uint16\n\tL2Priority      uint16\n\tDSCPValue       uint8\n}\n\ntype LLDPLocationFormat uint8\n\nconst (\n\tLLDPLocationFormatInvalid    LLDPLocationFormat = 0\n\tLLDPLocationFormatCoordinate LLDPLocationFormat = 1\n\tLLDPLocationFormatAddress    LLDPLocationFormat = 2\n\tLLDPLocationFormatECS        LLDPLocationFormat = 3\n)\n\ntype LLDPLocationAddressWhat uint8\n\nconst (\n\tLLDPLocationAddressWhatDHCP    LLDPLocationAddressWhat = 0\n\tLLDPLocationAddressWhatNetwork LLDPLocationAddressWhat = 1\n\tLLDPLocationAddressWhatClient  LLDPLocationAddressWhat = 2\n)\n\ntype LLDPLocationAddressType uint8\n\nconst (\n\tLLDPLocationAddressTypeLanguage       LLDPLocationAddressType = 0\n\tLLDPLocationAddressTypeNational       LLDPLocationAddressType = 1\n\tLLDPLocationAddressTypeCounty         LLDPLocationAddressType = 2\n\tLLDPLocationAddressTypeCity           LLDPLocationAddressType = 3\n\tLLDPLocationAddressTypeCityDivision   LLDPLocationAddressType = 4\n\tLLDPLocationAddressTypeNeighborhood   LLDPLocationAddressType = 5\n\tLLDPLocationAddressTypeStreet         LLDPLocationAddressType = 6\n\tLLDPLocationAddressTypeLeadingStreet  LLDPLocationAddressType = 16\n\tLLDPLocationAddressTypeTrailingStreet LLDPLocationAddressType = 17\n\tLLDPLocationAddressTypeStreetSuffix   LLDPLocationAddressType = 18\n\tLLDPLocationAddressTypeHouseNum       LLDPLocationAddressType = 19\n\tLLDPLocationAddressTypeHouseSuffix    LLDPLocationAddressType = 20\n\tLLDPLocationAddressTypeLandmark       LLDPLocationAddressType = 21\n\tLLDPLocationAddressTypeAdditional     LLDPLocationAddressType = 22\n\tLLDPLocationAddressTypeName           LLDPLocationAddressType = 23\n\tLLDPLocationAddressTypePostal         LLDPLocationAddressType = 24\n\tLLDPLocationAddressTypeBuilding       LLDPLocationAddressType = 25\n\tLLDPLocationAddressTypeUnit           LLDPLocationAddressType = 26\n\tLLDPLocationAddressTypeFloor          LLDPLocationAddressType = 27\n\tLLDPLocationAddressTypeRoom           LLDPLocationAddressType = 28\n\tLLDPLocationAddressTypePlace          LLDPLocationAddressType = 29\n\tLLDPLocationAddressTypeScript         LLDPLocationAddressType = 128\n)\n\ntype LLDPLocationCoordinate struct {\n\tLatitudeResolution  uint8\n\tLatitude            uint64\n\tLongitudeResolution uint8\n\tLongitude           uint64\n\tAltitudeType        uint8\n\tAltitudeResolution  uint16\n\tAltitude            uint32\n\tDatum               uint8\n}\n\ntype LLDPLocationAddressLine struct {\n\tType  LLDPLocationAddressType\n\tValue string\n}\n\ntype LLDPLocationAddress struct {\n\tWhat         LLDPLocationAddressWhat\n\tCountryCode  string\n\tAddressLines []LLDPLocationAddressLine\n}\n\ntype LLDPLocationECS struct {\n\tELIN string\n}\n\n// LLDP represents a physical location.\n// Only one of the embedded types will contain values, depending on Format.\ntype LLDPLocation struct {\n\tFormat     LLDPLocationFormat\n\tCoordinate LLDPLocationCoordinate\n\tAddress    LLDPLocationAddress\n\tECS        LLDPLocationECS\n}\n\ntype LLDPPowerViaMDI struct {\n\tType     LLDPPowerType\n\tSource   LLDPPowerSource\n\tPriority LLDPPowerPriority\n\tValue    uint16\n}\n\n// LLDPInfoMedia represents the information carried in TR-41 Org-specific TLVs\ntype LLDPInfoMedia struct {\n\tMediaCapabilities LLDPMediaCapabilities\n\tNetworkPolicy     LLDPNetworkPolicy\n\tLocation          LLDPLocation\n\tPowerViaMDI       LLDPPowerViaMDI\n\tHardwareRevision  string\n\tFirmwareRevision  string\n\tSoftwareRevision  string\n\tSerialNumber      string\n\tManufacturer      string\n\tModel             string\n\tAssetID           string\n}\n\ntype LLDPCisco2Subtype uint8\n\n// Cisco2 TLV Subtypes\nconst (\n\tLLDPCisco2PowerViaMDI LLDPCisco2Subtype = 1\n)\n\nconst (\n\tLLDPCiscoPSESupport   uint8 = 1 << 0\n\tLLDPCiscoArchShared   uint8 = 1 << 1\n\tLLDPCiscoPDSparePair  uint8 = 1 << 2\n\tLLDPCiscoPSESparePair uint8 = 1 << 3\n)\n\n// LLDPInfoCisco2 represents the information carried in Cisco Org-specific TLVs\ntype LLDPInfoCisco2 struct {\n\tPSEFourWirePoESupported       bool\n\tPDSparePairArchitectureShared bool\n\tPDRequestSparePairPoEOn       bool\n\tPSESparePairPoEOn             bool\n}\n\n// Profinet Subtypes\ntype LLDPProfinetSubtype uint8\n\nconst (\n\tLLDPProfinetPNIODelay         LLDPProfinetSubtype = 1\n\tLLDPProfinetPNIOPortStatus    LLDPProfinetSubtype = 2\n\tLLDPProfinetPNIOMRPPortStatus LLDPProfinetSubtype = 4\n\tLLDPProfinetPNIOChassisMAC    LLDPProfinetSubtype = 5\n\tLLDPProfinetPNIOPTCPStatus    LLDPProfinetSubtype = 6\n)\n\ntype LLDPPNIODelay struct {\n\tRXLocal    uint32\n\tRXRemote   uint32\n\tTXLocal    uint32\n\tTXRemote   uint32\n\tCableLocal uint32\n}\n\ntype LLDPPNIOPortStatus struct {\n\tClass2 uint16\n\tClass3 uint16\n}\n\ntype LLDPPNIOMRPPortStatus struct {\n\tUUID   []byte\n\tStatus uint16\n}\n\ntype LLDPPNIOPTCPStatus struct {\n\tMasterAddress     []byte\n\tSubdomainUUID     []byte\n\tIRDataUUID        []byte\n\tPeriodValid       bool\n\tPeriodLength      uint32\n\tRedPeriodValid    bool\n\tRedPeriodBegin    uint32\n\tOrangePeriodValid bool\n\tOrangePeriodBegin uint32\n\tGreenPeriodValid  bool\n\tGreenPeriodBegin  uint32\n}\n\n// LLDPInfoProfinet represents the information carried in Profinet Org-specific TLVs\ntype LLDPInfoProfinet struct {\n\tPNIODelay         LLDPPNIODelay\n\tPNIOPortStatus    LLDPPNIOPortStatus\n\tPNIOMRPPortStatus LLDPPNIOMRPPortStatus\n\tChassisMAC        []byte\n\tPNIOPTCPStatus    LLDPPNIOPTCPStatus\n}\n\n// LayerType returns gopacket.LayerTypeLinkLayerDiscovery.\nfunc (c *LinkLayerDiscovery) LayerType() gopacket.LayerType {\n\treturn LayerTypeLinkLayerDiscovery\n}\n\n// SerializeTo serializes LLDP packet to bytes and writes on SerializeBuffer.\nfunc (c *LinkLayerDiscovery) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tchassIDLen := c.ChassisID.serializedLen()\n\tportIDLen := c.PortID.serializedLen()\n\tvb, err := b.AppendBytes(chassIDLen + portIDLen + 4) // +4 for TTL\n\tif err != nil {\n\t\treturn err\n\t}\n\tcopy(vb[:chassIDLen], c.ChassisID.serialize())\n\tcopy(vb[chassIDLen:], c.PortID.serialize())\n\tttlIDLen := uint16(LLDPTLVTTL)<<9 | uint16(2)\n\tbinary.BigEndian.PutUint16(vb[chassIDLen+portIDLen:], ttlIDLen)\n\tbinary.BigEndian.PutUint16(vb[chassIDLen+portIDLen+2:], c.TTL)\n\n\tfor _, v := range c.Values {\n\t\tvb, err := b.AppendBytes(int(v.Length) + 2) // +2 for TLV type and length; 1 byte for subtype is included in v.Value\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tidLen := ((uint16(v.Type) << 9) | v.Length)\n\t\tbinary.BigEndian.PutUint16(vb[0:2], idLen)\n\t\tcopy(vb[2:], v.Value)\n\t}\n\n\tvb, err = b.AppendBytes(2) // End Tlv, 2 bytes\n\tif err != nil {\n\t\treturn err\n\t}\n\tbinary.BigEndian.PutUint16(vb[len(vb)-2:], uint16(0)) //End tlv, 2 bytes, all zero\n\treturn nil\n\n}\n\nfunc decodeLinkLayerDiscovery(data []byte, p gopacket.PacketBuilder) error {\n\tvar vals []LinkLayerDiscoveryValue\n\tvData := data[0:]\n\tfor len(vData) > 0 {\n\t\tif len(vData) < 2 {\n\t\t\tp.SetTruncated()\n\t\t\treturn errors.New(\"LLDP vdata < 2 bytes\")\n\t\t}\n\t\tnbit := vData[0] & 0x01\n\t\tt := LLDPTLVType(vData[0] >> 1)\n\t\tval := LinkLayerDiscoveryValue{Type: t, Length: uint16(nbit)<<8 + uint16(vData[1])}\n\t\tif val.Length > 0 {\n\t\t\tif len(vData) < int(val.Length+2) {\n\t\t\t\tp.SetTruncated()\n\t\t\t\treturn fmt.Errorf(\"LLDP VData < %d bytes\", val.Length+2)\n\t\t\t}\n\t\t\tval.Value = vData[2 : val.Length+2]\n\t\t}\n\t\tvals = append(vals, val)\n\t\tif t == LLDPTLVEnd {\n\t\t\tbreak\n\t\t}\n\t\tif len(vData) < int(2+val.Length) {\n\t\t\treturn errors.New(\"Malformed LinkLayerDiscovery Header\")\n\t\t}\n\t\tvData = vData[2+val.Length:]\n\t}\n\tif len(vals) < 4 {\n\t\treturn errors.New(\"Missing mandatory LinkLayerDiscovery TLV\")\n\t}\n\tc := &LinkLayerDiscovery{}\n\tgotEnd := false\n\tfor _, v := range vals {\n\t\tswitch v.Type {\n\t\tcase LLDPTLVEnd:\n\t\t\tgotEnd = true\n\t\tcase LLDPTLVChassisID:\n\t\t\tif len(v.Value) < 2 {\n\t\t\t\treturn errors.New(\"Malformed LinkLayerDiscovery ChassisID TLV\")\n\t\t\t}\n\t\t\tc.ChassisID.Subtype = LLDPChassisIDSubType(v.Value[0])\n\t\t\tc.ChassisID.ID = v.Value[1:]\n\t\tcase LLDPTLVPortID:\n\t\t\tif len(v.Value) < 2 {\n\t\t\t\treturn errors.New(\"Malformed LinkLayerDiscovery PortID TLV\")\n\t\t\t}\n\t\t\tc.PortID.Subtype = LLDPPortIDSubType(v.Value[0])\n\t\t\tc.PortID.ID = v.Value[1:]\n\t\tcase LLDPTLVTTL:\n\t\t\tif len(v.Value) < 2 {\n\t\t\t\treturn errors.New(\"Malformed LinkLayerDiscovery TTL TLV\")\n\t\t\t}\n\t\t\tc.TTL = binary.BigEndian.Uint16(v.Value[0:2])\n\t\tdefault:\n\t\t\tc.Values = append(c.Values, v)\n\t\t}\n\t}\n\tif c.ChassisID.Subtype == 0 || c.PortID.Subtype == 0 || !gotEnd {\n\t\treturn errors.New(\"Missing mandatory LinkLayerDiscovery TLV\")\n\t}\n\tc.Contents = data\n\tp.AddLayer(c)\n\n\tinfo := &LinkLayerDiscoveryInfo{}\n\tp.AddLayer(info)\n\tfor _, v := range c.Values {\n\t\tswitch v.Type {\n\t\tcase LLDPTLVPortDescription:\n\t\t\tinfo.PortDescription = string(v.Value)\n\t\tcase LLDPTLVSysName:\n\t\t\tinfo.SysName = string(v.Value)\n\t\tcase LLDPTLVSysDescription:\n\t\t\tinfo.SysDescription = string(v.Value)\n\t\tcase LLDPTLVSysCapabilities:\n\t\t\tif err := checkLLDPTLVLen(v, 4); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.SysCapabilities.SystemCap = getCapabilities(binary.BigEndian.Uint16(v.Value[0:2]))\n\t\t\tinfo.SysCapabilities.EnabledCap = getCapabilities(binary.BigEndian.Uint16(v.Value[2:4]))\n\t\tcase LLDPTLVMgmtAddress:\n\t\t\tif err := checkLLDPTLVLen(v, 9); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tmlen := v.Value[0]\n\t\t\tif err := checkLLDPTLVLen(v, int(mlen+7)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.MgmtAddress.Subtype = IANAAddressFamily(v.Value[1])\n\t\t\tinfo.MgmtAddress.Address = v.Value[2 : mlen+1]\n\t\t\tinfo.MgmtAddress.InterfaceSubtype = LLDPInterfaceSubtype(v.Value[mlen+1])\n\t\t\tinfo.MgmtAddress.InterfaceNumber = binary.BigEndian.Uint32(v.Value[mlen+2 : mlen+6])\n\t\t\tolen := v.Value[mlen+6]\n\t\t\tif err := checkLLDPTLVLen(v, int(mlen+7+olen)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.MgmtAddress.OID = string(v.Value[mlen+7 : mlen+7+olen])\n\t\tcase LLDPTLVOrgSpecific:\n\t\t\tif err := checkLLDPTLVLen(v, 4); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tinfo.OrgTLVs = append(info.OrgTLVs, LLDPOrgSpecificTLV{IEEEOUI(binary.BigEndian.Uint32(append([]byte{byte(0)}, v.Value[0:3]...))), uint8(v.Value[3]), v.Value[4:]})\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (l *LinkLayerDiscoveryInfo) Decode8021() (info LLDPInfo8021, err error) {\n\tfor _, o := range l.OrgTLVs {\n\t\tif o.OUI != IEEEOUI8021 {\n\t\t\tcontinue\n\t\t}\n\t\tswitch o.SubType {\n\t\tcase LLDP8021SubtypePortVLANID:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 2); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tinfo.PVID = binary.BigEndian.Uint16(o.Info[0:2])\n\t\tcase LLDP8021SubtypeProtocolVLANID:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 3); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsup := (o.Info[0]&LLDPProtocolVLANIDCapability > 0)\n\t\t\ten := (o.Info[0]&LLDPProtocolVLANIDStatus > 0)\n\t\t\tid := binary.BigEndian.Uint16(o.Info[1:3])\n\t\t\tinfo.PPVIDs = append(info.PPVIDs, PortProtocolVLANID{sup, en, id})\n\t\tcase LLDP8021SubtypeVLANName:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 2); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tid := binary.BigEndian.Uint16(o.Info[0:2])\n\t\t\tinfo.VLANNames = append(info.VLANNames, VLANName{id, string(o.Info[3:])})\n\t\tcase LLDP8021SubtypeProtocolIdentity:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 1); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tl := int(o.Info[0])\n\t\t\tif l > 0 {\n\t\t\t\tinfo.ProtocolIdentities = append(info.ProtocolIdentities, o.Info[1:1+l])\n\t\t\t}\n\t\tcase LLDP8021SubtypeVDIUsageDigest:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 4); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tinfo.VIDUsageDigest = binary.BigEndian.Uint32(o.Info[0:4])\n\t\tcase LLDP8021SubtypeManagementVID:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 2); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tinfo.ManagementVID = binary.BigEndian.Uint16(o.Info[0:2])\n\t\tcase LLDP8021SubtypeLinkAggregation:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 5); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsup := (o.Info[0]&LLDPAggregationCapability > 0)\n\t\t\ten := (o.Info[0]&LLDPAggregationStatus > 0)\n\t\t\tinfo.LinkAggregation = LLDPLinkAggregation{sup, en, binary.BigEndian.Uint32(o.Info[1:5])}\n\t\t}\n\t}\n\treturn\n}\n\nfunc (l *LinkLayerDiscoveryInfo) Decode8023() (info LLDPInfo8023, err error) {\n\tfor _, o := range l.OrgTLVs {\n\t\tif o.OUI != IEEEOUI8023 {\n\t\t\tcontinue\n\t\t}\n\t\tswitch o.SubType {\n\t\tcase LLDP8023SubtypeMACPHY:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 5); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsup := (o.Info[0]&LLDPMACPHYCapability > 0)\n\t\t\ten := (o.Info[0]&LLDPMACPHYStatus > 0)\n\t\t\tca := binary.BigEndian.Uint16(o.Info[1:3])\n\t\t\tmau := binary.BigEndian.Uint16(o.Info[3:5])\n\t\t\tinfo.MACPHYConfigStatus = LLDPMACPHYConfigStatus{sup, en, ca, mau}\n\t\tcase LLDP8023SubtypeMDIPower:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 3); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tinfo.PowerViaMDI.PortClassPSE = (o.Info[0]&LLDPMDIPowerPortClass > 0)\n\t\t\tinfo.PowerViaMDI.PSESupported = (o.Info[0]&LLDPMDIPowerCapability > 0)\n\t\t\tinfo.PowerViaMDI.PSEEnabled = (o.Info[0]&LLDPMDIPowerStatus > 0)\n\t\t\tinfo.PowerViaMDI.PSEPairsAbility = (o.Info[0]&LLDPMDIPowerPairsAbility > 0)\n\t\t\tinfo.PowerViaMDI.PSEPowerPair = uint8(o.Info[1])\n\t\t\tinfo.PowerViaMDI.PSEClass = uint8(o.Info[2])\n\t\t\tif len(o.Info) >= 7 {\n\t\t\t\tinfo.PowerViaMDI.Type = LLDPPowerType((o.Info[3] & 0xc0) >> 6)\n\t\t\t\tinfo.PowerViaMDI.Source = LLDPPowerSource((o.Info[3] & 0x30) >> 4)\n\t\t\t\tif info.PowerViaMDI.Type == 1 || info.PowerViaMDI.Type == 3 {\n\t\t\t\t\tinfo.PowerViaMDI.Source += 128 // For Stringify purposes\n\t\t\t\t}\n\t\t\t\tinfo.PowerViaMDI.Priority = LLDPPowerPriority(o.Info[3] & 0x0f)\n\t\t\t\tinfo.PowerViaMDI.Requested = binary.BigEndian.Uint16(o.Info[4:6])\n\t\t\t\tinfo.PowerViaMDI.Allocated = binary.BigEndian.Uint16(o.Info[6:8])\n\t\t\t}\n\t\tcase LLDP8023SubtypeLinkAggregation:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 5); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsup := (o.Info[0]&LLDPAggregationCapability > 0)\n\t\t\ten := (o.Info[0]&LLDPAggregationStatus > 0)\n\t\t\tinfo.LinkAggregation = LLDPLinkAggregation{sup, en, binary.BigEndian.Uint32(o.Info[1:5])}\n\t\tcase LLDP8023SubtypeMTU:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 2); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tinfo.MTU = binary.BigEndian.Uint16(o.Info[0:2])\n\t\t}\n\t}\n\treturn\n}\n\nfunc (l *LinkLayerDiscoveryInfo) Decode8021Qbg() (info LLDPInfo8021Qbg, err error) {\n\tfor _, o := range l.OrgTLVs {\n\t\tif o.OUI != IEEEOUI8021Qbg {\n\t\t\tcontinue\n\t\t}\n\t\tswitch o.SubType {\n\t\tcase LLDP8021QbgEVB:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 9); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tinfo.EVBSettings.Supported = getEVBCapabilities(binary.BigEndian.Uint16(o.Info[0:2]))\n\t\t\tinfo.EVBSettings.Enabled = getEVBCapabilities(binary.BigEndian.Uint16(o.Info[2:4]))\n\t\t\tinfo.EVBSettings.SupportedVSIs = binary.BigEndian.Uint16(o.Info[4:6])\n\t\t\tinfo.EVBSettings.ConfiguredVSIs = binary.BigEndian.Uint16(o.Info[6:8])\n\t\t\tinfo.EVBSettings.RTEExponent = uint8(o.Info[8])\n\t\t}\n\t}\n\treturn\n}\n\nfunc (l *LinkLayerDiscoveryInfo) DecodeMedia() (info LLDPInfoMedia, err error) {\n\tfor _, o := range l.OrgTLVs {\n\t\tif o.OUI != IEEEOUIMedia {\n\t\t\tcontinue\n\t\t}\n\t\tswitch LLDPMediaSubtype(o.SubType) {\n\t\tcase LLDPMediaTypeCapabilities:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 3); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tb := binary.BigEndian.Uint16(o.Info[0:2])\n\t\t\tinfo.MediaCapabilities.Capabilities = (b & LLDPMediaCapsLLDP) > 0\n\t\t\tinfo.MediaCapabilities.NetworkPolicy = (b & LLDPMediaCapsNetwork) > 0\n\t\t\tinfo.MediaCapabilities.Location = (b & LLDPMediaCapsLocation) > 0\n\t\t\tinfo.MediaCapabilities.PowerPSE = (b & LLDPMediaCapsPowerPSE) > 0\n\t\t\tinfo.MediaCapabilities.PowerPD = (b & LLDPMediaCapsPowerPD) > 0\n\t\t\tinfo.MediaCapabilities.Inventory = (b & LLDPMediaCapsInventory) > 0\n\t\t\tinfo.MediaCapabilities.Class = LLDPMediaClass(o.Info[2])\n\t\tcase LLDPMediaTypeNetwork:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 4); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tinfo.NetworkPolicy.ApplicationType = LLDPApplicationType(o.Info[0])\n\t\t\tb := binary.BigEndian.Uint16(o.Info[1:3])\n\t\t\tinfo.NetworkPolicy.Defined = (b & 0x8000) == 0\n\t\t\tinfo.NetworkPolicy.Tagged = (b & 0x4000) > 0\n\t\t\tinfo.NetworkPolicy.VLANId = (b & 0x1ffe) >> 1\n\t\t\tb = binary.BigEndian.Uint16(o.Info[2:4])\n\t\t\tinfo.NetworkPolicy.L2Priority = (b & 0x01c0) >> 6\n\t\t\tinfo.NetworkPolicy.DSCPValue = uint8(o.Info[3] & 0x3f)\n\t\tcase LLDPMediaTypeLocation:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 1); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tinfo.Location.Format = LLDPLocationFormat(o.Info[0])\n\t\t\to.Info = o.Info[1:]\n\t\t\tswitch info.Location.Format {\n\t\t\tcase LLDPLocationFormatCoordinate:\n\t\t\t\tif err = checkLLDPOrgSpecificLen(o, 16); err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tinfo.Location.Coordinate.LatitudeResolution = uint8(o.Info[0]&0xfc) >> 2\n\t\t\t\tb := binary.BigEndian.Uint64(o.Info[0:8])\n\t\t\t\tinfo.Location.Coordinate.Latitude = (b & 0x03ffffffff000000) >> 24\n\t\t\t\tinfo.Location.Coordinate.LongitudeResolution = uint8(o.Info[5]&0xfc) >> 2\n\t\t\t\tb = binary.BigEndian.Uint64(o.Info[5:13])\n\t\t\t\tinfo.Location.Coordinate.Longitude = (b & 0x03ffffffff000000) >> 24\n\t\t\t\tinfo.Location.Coordinate.AltitudeType = uint8((o.Info[10] & 0x30) >> 4)\n\t\t\t\tb1 := binary.BigEndian.Uint16(o.Info[10:12])\n\t\t\t\tinfo.Location.Coordinate.AltitudeResolution = (b1 & 0xfc0) >> 6\n\t\t\t\tb2 := binary.BigEndian.Uint32(o.Info[11:15])\n\t\t\t\tinfo.Location.Coordinate.Altitude = b2 & 0x3fffffff\n\t\t\t\tinfo.Location.Coordinate.Datum = uint8(o.Info[15])\n\t\t\tcase LLDPLocationFormatAddress:\n\t\t\t\tif err = checkLLDPOrgSpecificLen(o, 3); err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t//ll := uint8(o.Info[0])\n\t\t\t\tinfo.Location.Address.What = LLDPLocationAddressWhat(o.Info[1])\n\t\t\t\tinfo.Location.Address.CountryCode = string(o.Info[2:4])\n\t\t\t\tdata := o.Info[4:]\n\t\t\t\tfor len(data) > 1 {\n\t\t\t\t\taType := LLDPLocationAddressType(data[0])\n\t\t\t\t\taLen := int(data[1])\n\t\t\t\t\tif len(data) >= aLen+2 {\n\t\t\t\t\t\tinfo.Location.Address.AddressLines = append(info.Location.Address.AddressLines, LLDPLocationAddressLine{aType, string(data[2 : aLen+2])})\n\t\t\t\t\t\tdata = data[aLen+2:]\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tcase LLDPLocationFormatECS:\n\t\t\t\tinfo.Location.ECS.ELIN = string(o.Info)\n\t\t\t}\n\t\tcase LLDPMediaTypePower:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 3); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tinfo.PowerViaMDI.Type = LLDPPowerType((o.Info[0] & 0xc0) >> 6)\n\t\t\tinfo.PowerViaMDI.Source = LLDPPowerSource((o.Info[0] & 0x30) >> 4)\n\t\t\tif info.PowerViaMDI.Type == 1 || info.PowerViaMDI.Type == 3 {\n\t\t\t\tinfo.PowerViaMDI.Source += 128 // For Stringify purposes\n\t\t\t}\n\t\t\tinfo.PowerViaMDI.Priority = LLDPPowerPriority(o.Info[0] & 0x0f)\n\t\t\tinfo.PowerViaMDI.Value = binary.BigEndian.Uint16(o.Info[1:3]) * 100 // 0 to 102.3 w, 0.1W increments\n\t\tcase LLDPMediaTypeHardware:\n\t\t\tinfo.HardwareRevision = string(o.Info)\n\t\tcase LLDPMediaTypeFirmware:\n\t\t\tinfo.FirmwareRevision = string(o.Info)\n\t\tcase LLDPMediaTypeSoftware:\n\t\t\tinfo.SoftwareRevision = string(o.Info)\n\t\tcase LLDPMediaTypeSerial:\n\t\t\tinfo.SerialNumber = string(o.Info)\n\t\tcase LLDPMediaTypeManufacturer:\n\t\t\tinfo.Manufacturer = string(o.Info)\n\t\tcase LLDPMediaTypeModel:\n\t\t\tinfo.Model = string(o.Info)\n\t\tcase LLDPMediaTypeAssetID:\n\t\t\tinfo.AssetID = string(o.Info)\n\t\t}\n\t}\n\treturn\n}\n\nfunc (l *LinkLayerDiscoveryInfo) DecodeCisco2() (info LLDPInfoCisco2, err error) {\n\tfor _, o := range l.OrgTLVs {\n\t\tif o.OUI != IEEEOUICisco2 {\n\t\t\tcontinue\n\t\t}\n\t\tswitch LLDPCisco2Subtype(o.SubType) {\n\t\tcase LLDPCisco2PowerViaMDI:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 1); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tinfo.PSEFourWirePoESupported = (o.Info[0] & LLDPCiscoPSESupport) > 0\n\t\t\tinfo.PDSparePairArchitectureShared = (o.Info[0] & LLDPCiscoArchShared) > 0\n\t\t\tinfo.PDRequestSparePairPoEOn = (o.Info[0] & LLDPCiscoPDSparePair) > 0\n\t\t\tinfo.PSESparePairPoEOn = (o.Info[0] & LLDPCiscoPSESparePair) > 0\n\t\t}\n\t}\n\treturn\n}\n\nfunc (l *LinkLayerDiscoveryInfo) DecodeProfinet() (info LLDPInfoProfinet, err error) {\n\tfor _, o := range l.OrgTLVs {\n\t\tif o.OUI != IEEEOUIProfinet {\n\t\t\tcontinue\n\t\t}\n\t\tswitch LLDPProfinetSubtype(o.SubType) {\n\t\tcase LLDPProfinetPNIODelay:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 20); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tinfo.PNIODelay.RXLocal = binary.BigEndian.Uint32(o.Info[0:4])\n\t\t\tinfo.PNIODelay.RXRemote = binary.BigEndian.Uint32(o.Info[4:8])\n\t\t\tinfo.PNIODelay.TXLocal = binary.BigEndian.Uint32(o.Info[8:12])\n\t\t\tinfo.PNIODelay.TXRemote = binary.BigEndian.Uint32(o.Info[12:16])\n\t\t\tinfo.PNIODelay.CableLocal = binary.BigEndian.Uint32(o.Info[16:20])\n\t\tcase LLDPProfinetPNIOPortStatus:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 4); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tinfo.PNIOPortStatus.Class2 = binary.BigEndian.Uint16(o.Info[0:2])\n\t\t\tinfo.PNIOPortStatus.Class3 = binary.BigEndian.Uint16(o.Info[2:4])\n\t\tcase LLDPProfinetPNIOMRPPortStatus:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 18); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tinfo.PNIOMRPPortStatus.UUID = o.Info[0:16]\n\t\t\tinfo.PNIOMRPPortStatus.Status = binary.BigEndian.Uint16(o.Info[16:18])\n\t\tcase LLDPProfinetPNIOChassisMAC:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 6); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tinfo.ChassisMAC = o.Info[0:6]\n\t\tcase LLDPProfinetPNIOPTCPStatus:\n\t\t\tif err = checkLLDPOrgSpecificLen(o, 54); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tinfo.PNIOPTCPStatus.MasterAddress = o.Info[0:6]\n\t\t\tinfo.PNIOPTCPStatus.SubdomainUUID = o.Info[6:22]\n\t\t\tinfo.PNIOPTCPStatus.IRDataUUID = o.Info[22:38]\n\t\t\tb := binary.BigEndian.Uint32(o.Info[38:42])\n\t\t\tinfo.PNIOPTCPStatus.PeriodValid = (b & 0x80000000) > 0\n\t\t\tinfo.PNIOPTCPStatus.PeriodLength = b & 0x7fffffff\n\t\t\tb = binary.BigEndian.Uint32(o.Info[42:46])\n\t\t\tinfo.PNIOPTCPStatus.RedPeriodValid = (b & 0x80000000) > 0\n\t\t\tinfo.PNIOPTCPStatus.RedPeriodBegin = b & 0x7fffffff\n\t\t\tb = binary.BigEndian.Uint32(o.Info[46:50])\n\t\t\tinfo.PNIOPTCPStatus.OrangePeriodValid = (b & 0x80000000) > 0\n\t\t\tinfo.PNIOPTCPStatus.OrangePeriodBegin = b & 0x7fffffff\n\t\t\tb = binary.BigEndian.Uint32(o.Info[50:54])\n\t\t\tinfo.PNIOPTCPStatus.GreenPeriodValid = (b & 0x80000000) > 0\n\t\t\tinfo.PNIOPTCPStatus.GreenPeriodBegin = b & 0x7fffffff\n\t\t}\n\t}\n\treturn\n}\n\n// LayerType returns gopacket.LayerTypeLinkLayerDiscoveryInfo.\nfunc (c *LinkLayerDiscoveryInfo) LayerType() gopacket.LayerType {\n\treturn LayerTypeLinkLayerDiscoveryInfo\n}\n\nfunc getCapabilities(v uint16) (c LLDPCapabilities) {\n\tc.Other = (v&LLDPCapsOther > 0)\n\tc.Repeater = (v&LLDPCapsRepeater > 0)\n\tc.Bridge = (v&LLDPCapsBridge > 0)\n\tc.WLANAP = (v&LLDPCapsWLANAP > 0)\n\tc.Router = (v&LLDPCapsRouter > 0)\n\tc.Phone = (v&LLDPCapsPhone > 0)\n\tc.DocSis = (v&LLDPCapsDocSis > 0)\n\tc.StationOnly = (v&LLDPCapsStationOnly > 0)\n\tc.CVLAN = (v&LLDPCapsCVLAN > 0)\n\tc.SVLAN = (v&LLDPCapsSVLAN > 0)\n\tc.TMPR = (v&LLDPCapsTmpr > 0)\n\treturn\n}\n\nfunc getEVBCapabilities(v uint16) (c LLDPEVBCapabilities) {\n\tc.StandardBridging = (v & LLDPEVBCapsSTD) > 0\n\tc.StandardBridging = (v & LLDPEVBCapsSTD) > 0\n\tc.ReflectiveRelay = (v & LLDPEVBCapsRR) > 0\n\tc.RetransmissionTimerExponent = (v & LLDPEVBCapsRTE) > 0\n\tc.EdgeControlProtocol = (v & LLDPEVBCapsECP) > 0\n\tc.VSIDiscoveryProtocol = (v & LLDPEVBCapsVDP) > 0\n\treturn\n}\n\nfunc (t LLDPTLVType) String() (s string) {\n\tswitch t {\n\tcase LLDPTLVEnd:\n\t\ts = \"TLV End\"\n\tcase LLDPTLVChassisID:\n\t\ts = \"Chassis ID\"\n\tcase LLDPTLVPortID:\n\t\ts = \"Port ID\"\n\tcase LLDPTLVTTL:\n\t\ts = \"TTL\"\n\tcase LLDPTLVPortDescription:\n\t\ts = \"Port Description\"\n\tcase LLDPTLVSysName:\n\t\ts = \"System Name\"\n\tcase LLDPTLVSysDescription:\n\t\ts = \"System Description\"\n\tcase LLDPTLVSysCapabilities:\n\t\ts = \"System Capabilities\"\n\tcase LLDPTLVMgmtAddress:\n\t\ts = \"Management Address\"\n\tcase LLDPTLVOrgSpecific:\n\t\ts = \"Organisation Specific\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc (t LLDPChassisIDSubType) String() (s string) {\n\tswitch t {\n\tcase LLDPChassisIDSubTypeReserved:\n\t\ts = \"Reserved\"\n\tcase LLDPChassisIDSubTypeChassisComp:\n\t\ts = \"Chassis Component\"\n\tcase LLDPChassisIDSubtypeIfaceAlias:\n\t\ts = \"Interface Alias\"\n\tcase LLDPChassisIDSubTypePortComp:\n\t\ts = \"Port Component\"\n\tcase LLDPChassisIDSubTypeMACAddr:\n\t\ts = \"MAC Address\"\n\tcase LLDPChassisIDSubTypeNetworkAddr:\n\t\ts = \"Network Address\"\n\tcase LLDPChassisIDSubtypeIfaceName:\n\t\ts = \"Interface Name\"\n\tcase LLDPChassisIDSubTypeLocal:\n\t\ts = \"Local\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc (t LLDPPortIDSubType) String() (s string) {\n\tswitch t {\n\tcase LLDPPortIDSubtypeReserved:\n\t\ts = \"Reserved\"\n\tcase LLDPPortIDSubtypeIfaceAlias:\n\t\ts = \"Interface Alias\"\n\tcase LLDPPortIDSubtypePortComp:\n\t\ts = \"Port Component\"\n\tcase LLDPPortIDSubtypeMACAddr:\n\t\ts = \"MAC Address\"\n\tcase LLDPPortIDSubtypeNetworkAddr:\n\t\ts = \"Network Address\"\n\tcase LLDPPortIDSubtypeIfaceName:\n\t\ts = \"Interface Name\"\n\tcase LLDPPortIDSubtypeAgentCircuitID:\n\t\ts = \"Agent Circuit ID\"\n\tcase LLDPPortIDSubtypeLocal:\n\t\ts = \"Local\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc (t IANAAddressFamily) String() (s string) {\n\tswitch t {\n\tcase IANAAddressFamilyReserved:\n\t\ts = \"Reserved\"\n\tcase IANAAddressFamilyIPV4:\n\t\ts = \"IPv4\"\n\tcase IANAAddressFamilyIPV6:\n\t\ts = \"IPv6\"\n\tcase IANAAddressFamilyNSAP:\n\t\ts = \"NSAP\"\n\tcase IANAAddressFamilyHDLC:\n\t\ts = \"HDLC\"\n\tcase IANAAddressFamilyBBN1822:\n\t\ts = \"BBN 1822\"\n\tcase IANAAddressFamily802:\n\t\ts = \"802 media plus Ethernet 'canonical format'\"\n\tcase IANAAddressFamilyE163:\n\t\ts = \"E.163\"\n\tcase IANAAddressFamilyE164:\n\t\ts = \"E.164 (SMDS, Frame Relay, ATM)\"\n\tcase IANAAddressFamilyF69:\n\t\ts = \"F.69 (Telex)\"\n\tcase IANAAddressFamilyX121:\n\t\ts = \"X.121, X.25, Frame Relay\"\n\tcase IANAAddressFamilyIPX:\n\t\ts = \"IPX\"\n\tcase IANAAddressFamilyAtalk:\n\t\ts = \"Appletalk\"\n\tcase IANAAddressFamilyDecnet:\n\t\ts = \"Decnet IV\"\n\tcase IANAAddressFamilyBanyan:\n\t\ts = \"Banyan Vines\"\n\tcase IANAAddressFamilyE164NSAP:\n\t\ts = \"E.164 with NSAP format subaddress\"\n\tcase IANAAddressFamilyDNS:\n\t\ts = \"DNS\"\n\tcase IANAAddressFamilyDistname:\n\t\ts = \"Distinguished Name\"\n\tcase IANAAddressFamilyASNumber:\n\t\ts = \"AS Number\"\n\tcase IANAAddressFamilyXTPIPV4:\n\t\ts = \"XTP over IP version 4\"\n\tcase IANAAddressFamilyXTPIPV6:\n\t\ts = \"XTP over IP version 6\"\n\tcase IANAAddressFamilyXTP:\n\t\ts = \"XTP native mode XTP\"\n\tcase IANAAddressFamilyFcWWPN:\n\t\ts = \"Fibre Channel World-Wide Port Name\"\n\tcase IANAAddressFamilyFcWWNN:\n\t\ts = \"Fibre Channel World-Wide Node Name\"\n\tcase IANAAddressFamilyGWID:\n\t\ts = \"GWID\"\n\tcase IANAAddressFamilyL2VPN:\n\t\ts = \"AFI for Layer 2 VPN\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc (t LLDPInterfaceSubtype) String() (s string) {\n\tswitch t {\n\tcase LLDPInterfaceSubtypeUnknown:\n\t\ts = \"Unknown\"\n\tcase LLDPInterfaceSubtypeifIndex:\n\t\ts = \"IfIndex\"\n\tcase LLDPInterfaceSubtypeSysPort:\n\t\ts = \"System Port Number\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc (t LLDPPowerType) String() (s string) {\n\tswitch t {\n\tcase 0:\n\t\ts = \"Type 2 PSE Device\"\n\tcase 1:\n\t\ts = \"Type 2 PD Device\"\n\tcase 2:\n\t\ts = \"Type 1 PSE Device\"\n\tcase 3:\n\t\ts = \"Type 1 PD Device\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc (t LLDPPowerSource) String() (s string) {\n\tswitch t {\n\t// PD Device\n\tcase 0:\n\t\ts = \"Unknown\"\n\tcase 1:\n\t\ts = \"PSE\"\n\tcase 2:\n\t\ts = \"Local\"\n\tcase 3:\n\t\ts = \"PSE and Local\"\n\t// PSE Device  (Actual value  + 128)\n\tcase 128:\n\t\ts = \"Unknown\"\n\tcase 129:\n\t\ts = \"Primary Power Source\"\n\tcase 130:\n\t\ts = \"Backup Power Source\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc (t LLDPPowerPriority) String() (s string) {\n\tswitch t {\n\tcase 0:\n\t\ts = \"Unknown\"\n\tcase 1:\n\t\ts = \"Critical\"\n\tcase 2:\n\t\ts = \"High\"\n\tcase 3:\n\t\ts = \"Low\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc (t LLDPMediaSubtype) String() (s string) {\n\tswitch t {\n\tcase LLDPMediaTypeCapabilities:\n\t\ts = \"Media Capabilities \"\n\tcase LLDPMediaTypeNetwork:\n\t\ts = \"Network Policy\"\n\tcase LLDPMediaTypeLocation:\n\t\ts = \"Location Identification\"\n\tcase LLDPMediaTypePower:\n\t\ts = \"Extended Power-via-MDI\"\n\tcase LLDPMediaTypeHardware:\n\t\ts = \"Hardware Revision\"\n\tcase LLDPMediaTypeFirmware:\n\t\ts = \"Firmware Revision\"\n\tcase LLDPMediaTypeSoftware:\n\t\ts = \"Software Revision\"\n\tcase LLDPMediaTypeSerial:\n\t\ts = \"Serial Number\"\n\tcase LLDPMediaTypeManufacturer:\n\t\ts = \"Manufacturer\"\n\tcase LLDPMediaTypeModel:\n\t\ts = \"Model\"\n\tcase LLDPMediaTypeAssetID:\n\t\ts = \"Asset ID\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc (t LLDPMediaClass) String() (s string) {\n\tswitch t {\n\tcase LLDPMediaClassUndefined:\n\t\ts = \"Undefined\"\n\tcase LLDPMediaClassEndpointI:\n\t\ts = \"Endpoint Class I\"\n\tcase LLDPMediaClassEndpointII:\n\t\ts = \"Endpoint Class II\"\n\tcase LLDPMediaClassEndpointIII:\n\t\ts = \"Endpoint Class III\"\n\tcase LLDPMediaClassNetwork:\n\t\ts = \"Network connectivity \"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc (t LLDPApplicationType) String() (s string) {\n\tswitch t {\n\tcase LLDPAppTypeReserved:\n\t\ts = \"Reserved\"\n\tcase LLDPAppTypeVoice:\n\t\ts = \"Voice\"\n\tcase LLDPappTypeVoiceSignaling:\n\t\ts = \"Voice Signaling\"\n\tcase LLDPappTypeGuestVoice:\n\t\ts = \"Guest Voice\"\n\tcase LLDPappTypeGuestVoiceSignaling:\n\t\ts = \"Guest Voice Signaling\"\n\tcase LLDPappTypeSoftphoneVoice:\n\t\ts = \"Softphone Voice\"\n\tcase LLDPappTypeVideoConferencing:\n\t\ts = \"Video Conferencing\"\n\tcase LLDPappTypeStreamingVideo:\n\t\ts = \"Streaming Video\"\n\tcase LLDPappTypeVideoSignaling:\n\t\ts = \"Video Signaling\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc (t LLDPLocationFormat) String() (s string) {\n\tswitch t {\n\tcase LLDPLocationFormatInvalid:\n\t\ts = \"Invalid\"\n\tcase LLDPLocationFormatCoordinate:\n\t\ts = \"Coordinate-based LCI\"\n\tcase LLDPLocationFormatAddress:\n\t\ts = \"Address-based LCO\"\n\tcase LLDPLocationFormatECS:\n\t\ts = \"ECS ELIN\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc (t LLDPLocationAddressType) String() (s string) {\n\tswitch t {\n\tcase LLDPLocationAddressTypeLanguage:\n\t\ts = \"Language\"\n\tcase LLDPLocationAddressTypeNational:\n\t\ts = \"National subdivisions (province, state, etc)\"\n\tcase LLDPLocationAddressTypeCounty:\n\t\ts = \"County, parish, district\"\n\tcase LLDPLocationAddressTypeCity:\n\t\ts = \"City, township\"\n\tcase LLDPLocationAddressTypeCityDivision:\n\t\ts = \"City division, borough, ward\"\n\tcase LLDPLocationAddressTypeNeighborhood:\n\t\ts = \"Neighborhood, block\"\n\tcase LLDPLocationAddressTypeStreet:\n\t\ts = \"Street\"\n\tcase LLDPLocationAddressTypeLeadingStreet:\n\t\ts = \"Leading street direction\"\n\tcase LLDPLocationAddressTypeTrailingStreet:\n\t\ts = \"Trailing street suffix\"\n\tcase LLDPLocationAddressTypeStreetSuffix:\n\t\ts = \"Street suffix\"\n\tcase LLDPLocationAddressTypeHouseNum:\n\t\ts = \"House number\"\n\tcase LLDPLocationAddressTypeHouseSuffix:\n\t\ts = \"House number suffix\"\n\tcase LLDPLocationAddressTypeLandmark:\n\t\ts = \"Landmark or vanity address\"\n\tcase LLDPLocationAddressTypeAdditional:\n\t\ts = \"Additional location information\"\n\tcase LLDPLocationAddressTypeName:\n\t\ts = \"Name\"\n\tcase LLDPLocationAddressTypePostal:\n\t\ts = \"Postal/ZIP code\"\n\tcase LLDPLocationAddressTypeBuilding:\n\t\ts = \"Building\"\n\tcase LLDPLocationAddressTypeUnit:\n\t\ts = \"Unit\"\n\tcase LLDPLocationAddressTypeFloor:\n\t\ts = \"Floor\"\n\tcase LLDPLocationAddressTypeRoom:\n\t\ts = \"Room number\"\n\tcase LLDPLocationAddressTypePlace:\n\t\ts = \"Place type\"\n\tcase LLDPLocationAddressTypeScript:\n\t\ts = \"Script\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc checkLLDPTLVLen(v LinkLayerDiscoveryValue, l int) (err error) {\n\tif len(v.Value) < l {\n\t\terr = fmt.Errorf(\"Invalid TLV %v length %d (wanted mimimum %v\", v.Type, len(v.Value), l)\n\t}\n\treturn\n}\n\nfunc checkLLDPOrgSpecificLen(o LLDPOrgSpecificTLV, l int) (err error) {\n\tif len(o.Info) < l {\n\t\terr = fmt.Errorf(\"Invalid Org Specific TLV %v length %d (wanted minimum %v)\", o.SubType, len(o.Info), l)\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/loopback.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// Loopback contains the header for loopback encapsulation.  This header is\n// used by both BSD and OpenBSD style loopback decoding (pcap's DLT_NULL\n// and DLT_LOOP, respectively).\ntype Loopback struct {\n\tBaseLayer\n\tFamily ProtocolFamily\n}\n\n// LayerType returns LayerTypeLoopback.\nfunc (l *Loopback) LayerType() gopacket.LayerType { return LayerTypeLoopback }\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (l *Loopback) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 4 {\n\t\treturn errors.New(\"Loopback packet too small\")\n\t}\n\n\t// The protocol could be either big-endian or little-endian, we're\n\t// not sure.  But we're PRETTY sure that the value is less than\n\t// 256, so we can check the first two bytes.\n\tvar prot uint32\n\tif data[0] == 0 && data[1] == 0 {\n\t\tprot = binary.BigEndian.Uint32(data[:4])\n\t} else {\n\t\tprot = binary.LittleEndian.Uint32(data[:4])\n\t}\n\tif prot > 0xFF {\n\t\treturn fmt.Errorf(\"Invalid loopback protocol %q\", data[:4])\n\t}\n\n\tl.Family = ProtocolFamily(prot)\n\tl.BaseLayer = BaseLayer{data[:4], data[4:]}\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (l *Loopback) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeLoopback\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (l *Loopback) NextLayerType() gopacket.LayerType {\n\treturn l.Family.LayerType()\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\nfunc (l *Loopback) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbytes, err := b.PrependBytes(4)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbinary.LittleEndian.PutUint32(bytes, uint32(l.Family))\n\treturn nil\n}\n\nfunc decodeLoopback(data []byte, p gopacket.PacketBuilder) error {\n\tl := Loopback{}\n\tif err := l.DecodeFromBytes(data, gopacket.NilDecodeFeedback); err != nil {\n\t\treturn err\n\t}\n\tp.AddLayer(&l)\n\treturn p.NextDecoder(l.Family)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/mldv1.go",
    "content": "// Copyright 2018 GoPacket Authors. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// MLDv1Message represents the common structure of all MLDv1 messages\ntype MLDv1Message struct {\n\tBaseLayer\n\t// 3.4. Maximum Response Delay\n\tMaximumResponseDelay time.Duration\n\t// 3.6. Multicast Address\n\t// Zero in general query\n\t// Specific IPv6 multicast address otherwise\n\tMulticastAddress net.IP\n}\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (m *MLDv1Message) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 20 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"ICMP layer less than 20 bytes for Multicast Listener Query Message V1\")\n\t}\n\n\tm.MaximumResponseDelay = time.Duration(binary.BigEndian.Uint16(data[0:2])) * time.Millisecond\n\t// data[2:4] is reserved and not used in mldv1\n\tm.MulticastAddress = data[4:20]\n\n\treturn nil\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (*MLDv1Message) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypeZero\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (m *MLDv1Message) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbuf, err := b.PrependBytes(20)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif m.MaximumResponseDelay < 0 {\n\t\treturn errors.New(\"maximum response delay must not be negative\")\n\t}\n\tdms := m.MaximumResponseDelay / time.Millisecond\n\tif dms > math.MaxUint16 {\n\t\treturn fmt.Errorf(\"maximum response delay %dms is more than the allowed 65535ms\", dms)\n\t}\n\tbinary.BigEndian.PutUint16(buf[0:2], uint16(dms))\n\n\tcopy(buf[2:4], []byte{0x0, 0x0})\n\n\tma16 := m.MulticastAddress.To16()\n\tif ma16 == nil {\n\t\treturn fmt.Errorf(\"invalid multicast address '%s'\", m.MulticastAddress)\n\t}\n\tcopy(buf[4:20], ma16)\n\n\treturn nil\n}\n\n// Sums this layer up nicely formatted\nfunc (m *MLDv1Message) String() string {\n\treturn fmt.Sprintf(\n\t\t\"Maximum Response Delay: %dms, Multicast Address: %s\",\n\t\tm.MaximumResponseDelay/time.Millisecond,\n\t\tm.MulticastAddress)\n}\n\n// MLDv1MulticastListenerQueryMessage are sent by the router to determine\n// whether there are multicast listeners on the link.\n// https://tools.ietf.org/html/rfc2710 Page 5\ntype MLDv1MulticastListenerQueryMessage struct {\n\tMLDv1Message\n}\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (m *MLDv1MulticastListenerQueryMessage) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\terr := m.MLDv1Message.DecodeFromBytes(data, df)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif len(data) > 20 {\n\t\tm.Payload = data[20:]\n\t}\n\n\treturn nil\n}\n\n// LayerType returns LayerTypeMLDv1MulticastListenerQuery.\nfunc (*MLDv1MulticastListenerQueryMessage) LayerType() gopacket.LayerType {\n\treturn LayerTypeMLDv1MulticastListenerQuery\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (*MLDv1MulticastListenerQueryMessage) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeMLDv1MulticastListenerQuery\n}\n\n// IsGeneralQuery is true when this is a general query.\n// In a Query message, the Multicast Address field is set to zero when\n// sending a General Query.\n// https://tools.ietf.org/html/rfc2710#section-3.6\nfunc (m *MLDv1MulticastListenerQueryMessage) IsGeneralQuery() bool {\n\treturn net.IPv6zero.Equal(m.MulticastAddress)\n}\n\n// IsSpecificQuery is true when this is not a general query.\n// In a Query message, the Multicast Address field is set to a specific\n// IPv6 multicast address when sending a Multicast-Address-Specific Query.\n// https://tools.ietf.org/html/rfc2710#section-3.6\nfunc (m *MLDv1MulticastListenerQueryMessage) IsSpecificQuery() bool {\n\treturn !m.IsGeneralQuery()\n}\n\n// MLDv1MulticastListenerReportMessage is sent by a client listening on\n// a specific multicast address to indicate that it is (still) listening\n// on the specific multicast address.\n// https://tools.ietf.org/html/rfc2710 Page 6\ntype MLDv1MulticastListenerReportMessage struct {\n\tMLDv1Message\n}\n\n// LayerType returns LayerTypeMLDv1MulticastListenerReport.\nfunc (*MLDv1MulticastListenerReportMessage) LayerType() gopacket.LayerType {\n\treturn LayerTypeMLDv1MulticastListenerReport\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (*MLDv1MulticastListenerReportMessage) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeMLDv1MulticastListenerReport\n}\n\n// MLDv1MulticastListenerDoneMessage should be sent by a client when it ceases\n// to listen to a multicast address on an interface.\n// https://tools.ietf.org/html/rfc2710 Page 7\ntype MLDv1MulticastListenerDoneMessage struct {\n\tMLDv1Message\n}\n\n// LayerType returns LayerTypeMLDv1MulticastListenerDone.\nfunc (*MLDv1MulticastListenerDoneMessage) LayerType() gopacket.LayerType {\n\treturn LayerTypeMLDv1MulticastListenerDone\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (*MLDv1MulticastListenerDoneMessage) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeMLDv1MulticastListenerDone\n}\n\nfunc decodeMLDv1MulticastListenerReport(data []byte, p gopacket.PacketBuilder) error {\n\tm := &MLDv1MulticastListenerReportMessage{}\n\treturn decodingLayerDecoder(m, data, p)\n}\n\nfunc decodeMLDv1MulticastListenerQuery(data []byte, p gopacket.PacketBuilder) error {\n\tm := &MLDv1MulticastListenerQueryMessage{}\n\treturn decodingLayerDecoder(m, data, p)\n}\n\nfunc decodeMLDv1MulticastListenerDone(data []byte, p gopacket.PacketBuilder) error {\n\tm := &MLDv1MulticastListenerDoneMessage{}\n\treturn decodingLayerDecoder(m, data, p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/mldv2.go",
    "content": "// Copyright 2018 GoPacket Authors. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/google/gopacket\"\n)\n\nconst (\n\t// S Flag bit is 1\n\tmldv2STrue uint8 = 0x8\n\n\t// S Flag value mask\n\t//   mldv2STrue & mldv2SMask == mldv2STrue  // true\n\t//          0x1 & mldv2SMask == mldv2STrue  // true\n\t//          0x0 & mldv2SMask == mldv2STrue  // false\n\tmldv2SMask uint8 = 0x8\n\n\t// QRV value mask\n\tmldv2QRVMask uint8 = 0x7\n)\n\n// MLDv2MulticastListenerQueryMessage are sent by multicast routers to query the\n// multicast listening state of neighboring interfaces.\n// https://tools.ietf.org/html/rfc3810#section-5.1\n//\n// Some information, like Maximum Response Code and Multicast Address are in the\n// previous layer LayerTypeMLDv1MulticastListenerQuery\ntype MLDv2MulticastListenerQueryMessage struct {\n\tBaseLayer\n\t// 5.1.3. Maximum Response Delay COde\n\tMaximumResponseCode uint16\n\t// 5.1.5. Multicast Address\n\t// Zero in general query\n\t// Specific IPv6 multicast address otherwise\n\tMulticastAddress net.IP\n\t// 5.1.7. S Flag (Suppress Router-Side Processing)\n\tSuppressRoutersideProcessing bool\n\t// 5.1.8. QRV (Querier's Robustness Variable)\n\tQueriersRobustnessVariable uint8\n\t// 5.1.9. QQIC (Querier's Query Interval Code)\n\tQueriersQueryIntervalCode uint8\n\t// 5.1.10. Number of Sources (N)\n\tNumberOfSources uint16\n\t// 5.1.11 Source Address [i]\n\tSourceAddresses []net.IP\n}\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (m *MLDv2MulticastListenerQueryMessage) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 24 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"ICMP layer less than 24 bytes for Multicast Listener Query Message V2\")\n\t}\n\n\tm.MaximumResponseCode = binary.BigEndian.Uint16(data[0:2])\n\t// ignore data[2:4] as per https://tools.ietf.org/html/rfc3810#section-5.1.4\n\tm.MulticastAddress = data[4:20]\n\tm.SuppressRoutersideProcessing = (data[20] & mldv2SMask) == mldv2STrue\n\tm.QueriersRobustnessVariable = data[20] & mldv2QRVMask\n\tm.QueriersQueryIntervalCode = data[21]\n\n\tm.NumberOfSources = binary.BigEndian.Uint16(data[22:24])\n\n\tvar end int\n\tfor i := uint16(0); i < m.NumberOfSources; i++ {\n\t\tbegin := 24 + (int(i) * 16)\n\t\tend = begin + 16\n\n\t\tif end > len(data) {\n\t\t\tdf.SetTruncated()\n\t\t\treturn fmt.Errorf(\"ICMP layer less than %d bytes for Multicast Listener Query Message V2\", end)\n\t\t}\n\n\t\tm.SourceAddresses = append(m.SourceAddresses, data[begin:end])\n\t}\n\n\treturn nil\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (*MLDv2MulticastListenerQueryMessage) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypeZero\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (m *MLDv2MulticastListenerQueryMessage) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tif err := m.serializeSourceAddressesTo(b, opts); err != nil {\n\t\treturn err\n\t}\n\n\tbuf, err := b.PrependBytes(24)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbinary.BigEndian.PutUint16(buf[0:2], m.MaximumResponseCode)\n\tcopy(buf[2:4], []byte{0x00, 0x00}) // set reserved bytes to zero\n\n\tma16 := m.MulticastAddress.To16()\n\tif ma16 == nil {\n\t\treturn fmt.Errorf(\"invalid MulticastAddress '%s'\", m.MulticastAddress)\n\t}\n\tcopy(buf[4:20], ma16)\n\n\tbyte20 := m.QueriersRobustnessVariable & mldv2QRVMask\n\tif m.SuppressRoutersideProcessing {\n\t\tbyte20 |= mldv2STrue\n\t} else {\n\t\tbyte20 &= ^mldv2STrue // the complement of mldv2STrue\n\t}\n\tbyte20 &= 0x0F // set reserved bits to zero\n\tbuf[20] = byte20\n\n\tbinary.BigEndian.PutUint16(buf[22:24], m.NumberOfSources)\n\tbuf[21] = m.QueriersQueryIntervalCode\n\n\treturn nil\n}\n\n// writes each source address to the buffer preserving the order\nfunc (m *MLDv2MulticastListenerQueryMessage) serializeSourceAddressesTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tnumberOfSourceAddresses := len(m.SourceAddresses)\n\tif numberOfSourceAddresses > math.MaxUint16 {\n\t\treturn fmt.Errorf(\n\t\t\t\"there are more than %d source addresses, but 65535 is the maximum number of supported addresses\",\n\t\t\tnumberOfSourceAddresses)\n\t}\n\n\tif opts.FixLengths {\n\t\tm.NumberOfSources = uint16(numberOfSourceAddresses)\n\t}\n\n\tlastSAIdx := numberOfSourceAddresses - 1\n\tfor k := range m.SourceAddresses {\n\t\ti := lastSAIdx - k // reverse order\n\n\t\tbuf, err := b.PrependBytes(16)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tsa16 := m.SourceAddresses[i].To16()\n\t\tif sa16 == nil {\n\t\t\treturn fmt.Errorf(\"invalid source address [%d] '%s'\", i, m.SourceAddresses[i])\n\t\t}\n\t\tcopy(buf[0:16], sa16)\n\t}\n\n\treturn nil\n}\n\n// String sums this layer up nicely formatted\nfunc (m *MLDv2MulticastListenerQueryMessage) String() string {\n\treturn fmt.Sprintf(\n\t\t\"Maximum Response Code: %#x (%dms), Multicast Address: %s, Suppress Routerside Processing: %t, QRV: %#x, QQIC: %#x (%ds), Number of Source Address: %d (actual: %d), Source Addresses: %s\",\n\t\tm.MaximumResponseCode,\n\t\tm.MaximumResponseDelay(),\n\t\tm.MulticastAddress,\n\t\tm.SuppressRoutersideProcessing,\n\t\tm.QueriersRobustnessVariable,\n\t\tm.QueriersQueryIntervalCode,\n\t\tm.QQI()/time.Second,\n\t\tm.NumberOfSources,\n\t\tlen(m.SourceAddresses),\n\t\tm.SourceAddresses)\n}\n\n// LayerType returns LayerTypeMLDv2MulticastListenerQuery.\nfunc (*MLDv2MulticastListenerQueryMessage) LayerType() gopacket.LayerType {\n\treturn LayerTypeMLDv2MulticastListenerQuery\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (*MLDv2MulticastListenerQueryMessage) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeMLDv2MulticastListenerQuery\n}\n\n// QQI calculates the Querier's Query Interval based on the QQIC\n// according to https://tools.ietf.org/html/rfc3810#section-5.1.9\nfunc (m *MLDv2MulticastListenerQueryMessage) QQI() time.Duration {\n\tdata := m.QueriersQueryIntervalCode\n\tif data < 128 {\n\t\treturn time.Second * time.Duration(data)\n\t}\n\n\texp := uint16(data) & 0x70 >> 4\n\tmant := uint16(data) & 0x0F\n\treturn time.Second * time.Duration(mant|0x1000<<(exp+3))\n}\n\n// SetQQI calculates and updates the Querier's Query Interval Code (QQIC)\n// according to https://tools.ietf.org/html/rfc3810#section-5.1.9\nfunc (m *MLDv2MulticastListenerQueryMessage) SetQQI(d time.Duration) error {\n\tif d < 0 {\n\t\tm.QueriersQueryIntervalCode = 0\n\t\treturn errors.New(\"QQI duration is negative\")\n\t}\n\n\tif d == 0 {\n\t\tm.QueriersQueryIntervalCode = 0\n\t\treturn nil\n\t}\n\n\tdms := d / time.Second\n\tif dms < 128 {\n\t\tm.QueriersQueryIntervalCode = uint8(dms)\n\t}\n\n\tif dms > 31744 { // mant=0xF, exp=0x7\n\t\tm.QueriersQueryIntervalCode = 0xFF\n\t\treturn fmt.Errorf(\"QQI duration %ds is, maximum allowed is 31744s\", dms)\n\t}\n\n\tvalue := uint16(dms) // ok, because 31744 < math.MaxUint16\n\texp := uint8(7)\n\tfor mask := uint16(0x4000); exp > 0; exp-- {\n\t\tif mask&value != 0 {\n\t\t\tbreak\n\t\t}\n\n\t\tmask >>= 1\n\t}\n\n\tmant := uint8(0x000F & (value >> (exp + 3)))\n\tsig := uint8(0x10)\n\tm.QueriersQueryIntervalCode = sig | exp<<4 | mant\n\n\treturn nil\n}\n\n// MaximumResponseDelay returns the Maximum Response Delay based on the\n// Maximum Response Code according to\n// https://tools.ietf.org/html/rfc3810#section-5.1.3\nfunc (m *MLDv2MulticastListenerQueryMessage) MaximumResponseDelay() time.Duration {\n\tif m.MaximumResponseCode < 0x8000 {\n\t\treturn time.Duration(m.MaximumResponseCode)\n\t}\n\n\texp := m.MaximumResponseCode & 0x7000 >> 12\n\tmant := m.MaximumResponseCode & 0x0FFF\n\n\treturn time.Millisecond * time.Duration(mant|0x1000<<(exp+3))\n}\n\n// SetMLDv2MaximumResponseDelay updates the Maximum Response Code according to\n// https://tools.ietf.org/html/rfc3810#section-5.1.3\nfunc (m *MLDv2MulticastListenerQueryMessage) SetMLDv2MaximumResponseDelay(d time.Duration) error {\n\tif d == 0 {\n\t\tm.MaximumResponseCode = 0\n\t\treturn nil\n\t}\n\n\tif d < 0 {\n\t\treturn errors.New(\"maximum response delay must not be negative\")\n\t}\n\n\tdms := d / time.Millisecond\n\n\tif dms < 32768 {\n\t\tm.MaximumResponseCode = uint16(dms)\n\t}\n\n\tif dms > 4193280 { // mant=0xFFF, exp=0x7\n\t\treturn fmt.Errorf(\"maximum response delay %dms is bigger the than maximum of 4193280ms\", dms)\n\t}\n\n\tvalue := uint32(dms) // ok, because 4193280 < math.MaxUint32\n\texp := uint8(7)\n\tfor mask := uint32(0x40000000); exp > 0; exp-- {\n\t\tif mask&value != 0 {\n\t\t\tbreak\n\t\t}\n\n\t\tmask >>= 1\n\t}\n\n\tmant := uint16(0x00000FFF & (value >> (exp + 3)))\n\tsig := uint16(0x1000)\n\tm.MaximumResponseCode = sig | uint16(exp)<<12 | mant\n\treturn nil\n}\n\n// MLDv2MulticastListenerReportMessage is sent by an IP node to report the\n// current multicast listening state, or changes therein.\n// https://tools.ietf.org/html/rfc3810#section-5.2\ntype MLDv2MulticastListenerReportMessage struct {\n\tBaseLayer\n\t// 5.2.3. Nr of Mcast Address Records\n\tNumberOfMulticastAddressRecords uint16\n\t// 5.2.4. Multicast Address Record [i]\n\tMulticastAddressRecords []MLDv2MulticastAddressRecord\n}\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (m *MLDv2MulticastListenerReportMessage) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 4 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"ICMP layer less than 4 bytes for Multicast Listener Report Message V2\")\n\t}\n\n\t// ignore data[0:2] as per RFC\n\t// https://tools.ietf.org/html/rfc3810#section-5.2.1\n\tm.NumberOfMulticastAddressRecords = binary.BigEndian.Uint16(data[2:4])\n\n\tbegin := 4\n\tfor i := uint16(0); i < m.NumberOfMulticastAddressRecords; i++ {\n\t\tmar := MLDv2MulticastAddressRecord{}\n\t\tread, err := mar.decode(data[begin:], df)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tm.MulticastAddressRecords = append(m.MulticastAddressRecords, mar)\n\n\t\tbegin += read\n\t}\n\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (m *MLDv2MulticastListenerReportMessage) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tlastItemIdx := len(m.MulticastAddressRecords) - 1\n\tfor k := range m.MulticastAddressRecords {\n\t\ti := lastItemIdx - k // reverse order\n\n\t\terr := m.MulticastAddressRecords[i].serializeTo(b, opts)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif opts.FixLengths {\n\t\tnumberOfMAR := len(m.MulticastAddressRecords)\n\t\tif numberOfMAR > math.MaxUint16 {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"%d multicast address records added, but the maximum is 65535\",\n\t\t\t\tnumberOfMAR)\n\t\t}\n\n\t\tm.NumberOfMulticastAddressRecords = uint16(numberOfMAR)\n\t}\n\n\tbuf, err := b.PrependBytes(4)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcopy(buf[0:2], []byte{0x0, 0x0})\n\tbinary.BigEndian.PutUint16(buf[2:4], m.NumberOfMulticastAddressRecords)\n\treturn nil\n}\n\n// Sums this layer up nicely formatted\nfunc (m *MLDv2MulticastListenerReportMessage) String() string {\n\treturn fmt.Sprintf(\n\t\t\"Number of Mcast Addr Records: %d (actual %d), Multicast Address Records: %+v\",\n\t\tm.NumberOfMulticastAddressRecords,\n\t\tlen(m.MulticastAddressRecords),\n\t\tm.MulticastAddressRecords)\n}\n\n// LayerType returns LayerTypeMLDv2MulticastListenerQuery.\nfunc (*MLDv2MulticastListenerReportMessage) LayerType() gopacket.LayerType {\n\treturn LayerTypeMLDv2MulticastListenerReport\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (*MLDv2MulticastListenerReportMessage) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeMLDv2MulticastListenerReport\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (*MLDv2MulticastListenerReportMessage) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\n// MLDv2MulticastAddressRecordType holds the type of a\n// Multicast Address Record, according to\n// https://tools.ietf.org/html/rfc3810#section-5.2.5 and\n// https://tools.ietf.org/html/rfc3810#section-5.2.12\ntype MLDv2MulticastAddressRecordType uint8\n\nconst (\n\t// MLDv2MulticastAddressRecordTypeModeIsIncluded stands for\n\t// MODE_IS_INCLUDE - indicates that the interface has a filter\n\t// mode of INCLUDE for the specified multicast address.\n\tMLDv2MulticastAddressRecordTypeModeIsIncluded MLDv2MulticastAddressRecordType = 1\n\t// MLDv2MulticastAddressRecordTypeModeIsExcluded stands for\n\t// MODE_IS_EXCLUDE - indicates that the interface has a filter\n\t// mode of EXCLUDE for the specified multicast address.\n\tMLDv2MulticastAddressRecordTypeModeIsExcluded MLDv2MulticastAddressRecordType = 2\n\t// MLDv2MulticastAddressRecordTypeChangeToIncludeMode stands for\n\t// CHANGE_TO_INCLUDE_MODE - indicates that the interface has\n\t// changed to INCLUDE filter mode for the specified multicast\n\t// address.\n\tMLDv2MulticastAddressRecordTypeChangeToIncludeMode MLDv2MulticastAddressRecordType = 3\n\t// MLDv2MulticastAddressRecordTypeChangeToExcludeMode stands for\n\t// CHANGE_TO_EXCLUDE_MODE - indicates that the interface has\n\t// changed to EXCLUDE filter mode for the specified multicast\n\t// address\n\tMLDv2MulticastAddressRecordTypeChangeToExcludeMode MLDv2MulticastAddressRecordType = 4\n\t// MLDv2MulticastAddressRecordTypeAllowNewSources stands for\n\t// ALLOW_NEW_SOURCES - indicates that the Source Address [i]\n\t// fields in this Multicast Address Record contain a list of\n\t// the additional sources that the node wishes to listen to,\n\t// for packets sent to the specified multicast address.\n\tMLDv2MulticastAddressRecordTypeAllowNewSources MLDv2MulticastAddressRecordType = 5\n\t// MLDv2MulticastAddressRecordTypeBlockOldSources stands for\n\t// BLOCK_OLD_SOURCES - indicates that the Source Address [i]\n\t// fields in this Multicast Address Record contain a list of\n\t// the sources that the node no longer wishes to listen to,\n\t// for packets sent to the specified multicast address.\n\tMLDv2MulticastAddressRecordTypeBlockOldSources MLDv2MulticastAddressRecordType = 6\n)\n\n// Human readable record types\n// Naming follows https://tools.ietf.org/html/rfc3810#section-5.2.12\nfunc (m MLDv2MulticastAddressRecordType) String() string {\n\tswitch m {\n\tcase MLDv2MulticastAddressRecordTypeModeIsIncluded:\n\t\treturn \"MODE_IS_INCLUDE\"\n\tcase MLDv2MulticastAddressRecordTypeModeIsExcluded:\n\t\treturn \"MODE_IS_EXCLUDE\"\n\tcase MLDv2MulticastAddressRecordTypeChangeToIncludeMode:\n\t\treturn \"CHANGE_TO_INCLUDE_MODE\"\n\tcase MLDv2MulticastAddressRecordTypeChangeToExcludeMode:\n\t\treturn \"CHANGE_TO_EXCLUDE_MODE\"\n\tcase MLDv2MulticastAddressRecordTypeAllowNewSources:\n\t\treturn \"ALLOW_NEW_SOURCES\"\n\tcase MLDv2MulticastAddressRecordTypeBlockOldSources:\n\t\treturn \"BLOCK_OLD_SOURCES\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"UNKNOWN(%d)\", m)\n\t}\n}\n\n// MLDv2MulticastAddressRecord contains information on the sender listening to a\n// single multicast address on the interface the report is sent.\n// https://tools.ietf.org/html/rfc3810#section-5.2.4\ntype MLDv2MulticastAddressRecord struct {\n\t// 5.2.5. Record Type\n\tRecordType MLDv2MulticastAddressRecordType\n\t// 5.2.6. Auxiliary Data Length (number of 32-bit words)\n\tAuxDataLen uint8\n\t// 5.2.7. Number Of Sources (N)\n\tN uint16\n\t// 5.2.8. Multicast Address\n\tMulticastAddress net.IP\n\t// 5.2.9 Source Address [i]\n\tSourceAddresses []net.IP\n\t// 5.2.10 Auxiliary Data\n\tAuxiliaryData []byte\n}\n\n// decodes a multicast address record from bytes\nfunc (m *MLDv2MulticastAddressRecord) decode(data []byte, df gopacket.DecodeFeedback) (int, error) {\n\tif len(data) < 20 {\n\t\tdf.SetTruncated()\n\t\treturn 0, errors.New(\n\t\t\t\"Multicast Listener Report Message V2 layer less than 4 bytes for Multicast Address Record\")\n\t}\n\n\tm.RecordType = MLDv2MulticastAddressRecordType(data[0])\n\tm.AuxDataLen = data[1]\n\tm.N = binary.BigEndian.Uint16(data[2:4])\n\tm.MulticastAddress = data[4:20]\n\n\tfor i := uint16(0); i < m.N; i++ {\n\t\tbegin := 20 + (int(i) * 16)\n\t\tend := begin + 16\n\n\t\tif len(data) < end {\n\t\t\tdf.SetTruncated()\n\t\t\treturn begin, fmt.Errorf(\n\t\t\t\t\"Multicast Listener Report Message V2 layer less than %d bytes for Multicast Address Record\", end)\n\t\t}\n\n\t\tm.SourceAddresses = append(m.SourceAddresses, data[begin:end])\n\t}\n\n\texpectedLengthWithouAuxData := 20 + (int(m.N) * 16)\n\texpectedTotalLength := (int(m.AuxDataLen) * 4) + expectedLengthWithouAuxData // *4 because AuxDataLen are 32bit words\n\tif len(data) < expectedTotalLength {\n\t\treturn expectedLengthWithouAuxData, fmt.Errorf(\n\t\t\t\"Multicast Listener Report Message V2 layer less than %d bytes for Multicast Address Record\",\n\t\t\texpectedLengthWithouAuxData)\n\t}\n\n\tm.AuxiliaryData = data[expectedLengthWithouAuxData:expectedTotalLength]\n\n\treturn expectedTotalLength, nil\n}\n\n// String sums this layer up nicely formatted\nfunc (m *MLDv2MulticastAddressRecord) String() string {\n\treturn fmt.Sprintf(\n\t\t\"RecordType: %d (%s), AuxDataLen: %d [32-bit words], N: %d, Multicast Address: %s, SourceAddresses: %s, Auxiliary Data: %#x\",\n\t\tm.RecordType,\n\t\tm.RecordType.String(),\n\t\tm.AuxDataLen,\n\t\tm.N,\n\t\tm.MulticastAddress.To16(),\n\t\tm.SourceAddresses,\n\t\tm.AuxiliaryData)\n}\n\n// serializes a multicast address record\nfunc (m *MLDv2MulticastAddressRecord) serializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tif err := m.serializeAuxiliaryDataTo(b, opts); err != nil {\n\t\treturn err\n\t}\n\n\tif err := m.serializeSourceAddressesTo(b, opts); err != nil {\n\t\treturn err\n\t}\n\n\tbuf, err := b.PrependBytes(20)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbuf[0] = uint8(m.RecordType)\n\tbuf[1] = m.AuxDataLen\n\tbinary.BigEndian.PutUint16(buf[2:4], m.N)\n\n\tma16 := m.MulticastAddress.To16()\n\tif ma16 == nil {\n\t\treturn fmt.Errorf(\"invalid multicast address '%s'\", m.MulticastAddress)\n\t}\n\tcopy(buf[4:20], ma16)\n\n\treturn nil\n}\n\n// serializes the auxiliary data of a multicast address record\nfunc (m *MLDv2MulticastAddressRecord) serializeAuxiliaryDataTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tif remainder := len(m.AuxiliaryData) % 4; remainder != 0 {\n\t\tzeroWord := []byte{0x0, 0x0, 0x0, 0x0}\n\t\tm.AuxiliaryData = append(m.AuxiliaryData, zeroWord[:remainder]...)\n\t}\n\n\tif opts.FixLengths {\n\t\tauxDataLen := len(m.AuxiliaryData) / 4\n\n\t\tif auxDataLen > math.MaxUint8 {\n\t\t\treturn fmt.Errorf(\"auxilary data is %d 32-bit words, but the maximum is 255 32-bit words\", auxDataLen)\n\t\t}\n\n\t\tm.AuxDataLen = uint8(auxDataLen)\n\t}\n\n\tbuf, err := b.PrependBytes(len(m.AuxiliaryData))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcopy(buf, m.AuxiliaryData)\n\treturn nil\n}\n\n// serializes the source addresses of a multicast address record preserving the order\nfunc (m *MLDv2MulticastAddressRecord) serializeSourceAddressesTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tif opts.FixLengths {\n\t\tnumberOfSourceAddresses := len(m.SourceAddresses)\n\n\t\tif numberOfSourceAddresses > math.MaxUint16 {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"%d source addresses added, but the maximum is 65535\",\n\t\t\t\tnumberOfSourceAddresses)\n\t\t}\n\n\t\tm.N = uint16(numberOfSourceAddresses)\n\t}\n\n\tlastItemIdx := len(m.SourceAddresses) - 1\n\tfor k := range m.SourceAddresses {\n\t\ti := lastItemIdx - k // reverse order\n\n\t\tbuf, err := b.PrependBytes(16)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tsa16 := m.SourceAddresses[i].To16()\n\t\tif sa16 == nil {\n\t\t\treturn fmt.Errorf(\"invalid source address [%d] '%s'\", i, m.SourceAddresses[i])\n\t\t}\n\t\tcopy(buf, sa16)\n\t}\n\n\treturn nil\n}\n\nfunc decodeMLDv2MulticastListenerReport(data []byte, p gopacket.PacketBuilder) error {\n\tm := &MLDv2MulticastListenerReportMessage{}\n\treturn decodingLayerDecoder(m, data, p)\n}\n\nfunc decodeMLDv2MulticastListenerQuery(data []byte, p gopacket.PacketBuilder) error {\n\tm := &MLDv2MulticastListenerQueryMessage{}\n\treturn decodingLayerDecoder(m, data, p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/modbustcp.go",
    "content": "// Copyright 2018, The GoPacket Authors, All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n//\n//******************************************************************************\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"github.com/google/gopacket\"\n)\n\n//******************************************************************************\n//\n// ModbusTCP Decoding Layer\n// ------------------------------------------\n// This file provides a GoPacket decoding layer for ModbusTCP.\n//\n//******************************************************************************\n\nconst mbapRecordSizeInBytes int = 7\nconst modbusPDUMinimumRecordSizeInBytes int = 2\nconst modbusPDUMaximumRecordSizeInBytes int = 253\n\n// ModbusProtocol type\ntype ModbusProtocol uint16\n\n// ModbusProtocol known values.\nconst (\n\tModbusProtocolModbus ModbusProtocol = 0\n)\n\nfunc (mp ModbusProtocol) String() string {\n\tswitch mp {\n\tdefault:\n\t\treturn \"Unknown\"\n\tcase ModbusProtocolModbus:\n\t\treturn \"Modbus\"\n\t}\n}\n\n//******************************************************************************\n\n// ModbusTCP Type\n// --------\n// Type ModbusTCP implements the DecodingLayer interface. Each ModbusTCP object\n// represents in a structured form the MODBUS Application Protocol header (MBAP) record present as the TCP\n// payload in an ModbusTCP TCP packet.\n//\ntype ModbusTCP struct {\n\tBaseLayer // Stores the packet bytes and payload (Modbus PDU) bytes .\n\n\tTransactionIdentifier uint16         // Identification of a MODBUS Request/Response transaction\n\tProtocolIdentifier    ModbusProtocol // It is used for intra-system multiplexing\n\tLength                uint16         // Number of following bytes (includes 1 byte for UnitIdentifier + Modbus data length\n\tUnitIdentifier        uint8          // Identification of a remote slave connected on a serial line or on other buses\n}\n\n//******************************************************************************\n\n// LayerType returns the layer type of the ModbusTCP object, which is LayerTypeModbusTCP.\nfunc (d *ModbusTCP) LayerType() gopacket.LayerType {\n\treturn LayerTypeModbusTCP\n}\n\n//******************************************************************************\n\n// decodeModbusTCP analyses a byte slice and attempts to decode it as an ModbusTCP\n// record of a TCP packet.\n//\n// If it succeeds, it loads p with information about the packet and returns nil.\n// If it fails, it returns an error (non nil).\n//\n// This function is employed in layertypes.go to register the ModbusTCP layer.\nfunc decodeModbusTCP(data []byte, p gopacket.PacketBuilder) error {\n\n\t// Attempt to decode the byte slice.\n\td := &ModbusTCP{}\n\terr := d.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// If the decoding worked, add the layer to the packet and set it\n\t// as the application layer too, if there isn't already one.\n\tp.AddLayer(d)\n\tp.SetApplicationLayer(d)\n\n\treturn p.NextDecoder(d.NextLayerType())\n\n}\n\n//******************************************************************************\n\n// DecodeFromBytes analyses a byte slice and attempts to decode it as an ModbusTCP\n// record of a TCP packet.\n//\n// Upon succeeds, it loads the ModbusTCP object with information about the packet\n// and returns nil.\n// Upon failure, it returns an error (non nil).\nfunc (d *ModbusTCP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\n\t// If the data block is too short to be a MBAP record, then return an error.\n\tif len(data) < mbapRecordSizeInBytes+modbusPDUMinimumRecordSizeInBytes {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"ModbusTCP packet too short\")\n\t}\n\n\tif len(data) > mbapRecordSizeInBytes+modbusPDUMaximumRecordSizeInBytes {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"ModbusTCP packet too long\")\n\t}\n\n\t// ModbusTCP type embeds type BaseLayer which contains two fields:\n\t//    Contents is supposed to contain the bytes of the data at this level (MPBA).\n\t//    Payload is supposed to contain the payload of this level (PDU).\n\td.BaseLayer = BaseLayer{Contents: data[:mbapRecordSizeInBytes], Payload: data[mbapRecordSizeInBytes:len(data)]}\n\n\t// Extract the fields from the block of bytes.\n\t// The fields can just be copied in big endian order.\n\td.TransactionIdentifier = binary.BigEndian.Uint16(data[:2])\n\td.ProtocolIdentifier = ModbusProtocol(binary.BigEndian.Uint16(data[2:4]))\n\td.Length = binary.BigEndian.Uint16(data[4:6])\n\n\t// Length should have the size of the payload plus one byte (size of UnitIdentifier)\n\tif d.Length != uint16(len(d.BaseLayer.Payload)+1) {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"ModbusTCP packet with wrong field value (Length)\")\n\t}\n\td.UnitIdentifier = uint8(data[6])\n\n\treturn nil\n}\n\n//******************************************************************************\n\n// NextLayerType returns the layer type of the ModbusTCP payload, which is LayerTypePayload.\nfunc (d *ModbusTCP) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\n//******************************************************************************\n\n// Payload returns Modbus Protocol Data Unit (PDU) composed by Function Code and Data, it is carried within ModbusTCP packets\nfunc (d *ModbusTCP) Payload() []byte {\n\treturn d.BaseLayer.Payload\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/mpls.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"github.com/google/gopacket\"\n)\n\n// MPLS is the MPLS packet header.\ntype MPLS struct {\n\tBaseLayer\n\tLabel        uint32\n\tTrafficClass uint8\n\tStackBottom  bool\n\tTTL          uint8\n}\n\n// LayerType returns gopacket.LayerTypeMPLS.\nfunc (m *MPLS) LayerType() gopacket.LayerType { return LayerTypeMPLS }\n\n// ProtocolGuessingDecoder attempts to guess the protocol of the bytes it's\n// given, then decode the packet accordingly.  Its algorithm for guessing is:\n//  If the packet starts with byte 0x45-0x4F: IPv4\n//  If the packet starts with byte 0x60-0x6F: IPv6\n//  Otherwise:  Error\n// See draft-hsmit-isis-aal5mux-00.txt for more detail on this approach.\ntype ProtocolGuessingDecoder struct{}\n\nfunc (ProtocolGuessingDecoder) Decode(data []byte, p gopacket.PacketBuilder) error {\n\tswitch data[0] {\n\t// 0x40 | header_len, where header_len is at least 5.\n\tcase 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f:\n\t\treturn decodeIPv4(data, p)\n\t\t// IPv6 can start with any byte whose first 4 bits are 0x6.\n\tcase 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f:\n\t\treturn decodeIPv6(data, p)\n\t}\n\treturn errors.New(\"Unable to guess protocol of packet data\")\n}\n\n// MPLSPayloadDecoder is the decoder used to data encapsulated by each MPLS\n// layer.  MPLS contains no type information, so we have to explicitly decide\n// which decoder to use.  This is initially set to ProtocolGuessingDecoder, our\n// simple attempt at guessing protocols based on the first few bytes of data\n// available to us.  However, if you know that in your environment MPLS always\n// encapsulates a specific protocol, you may reset this.\nvar MPLSPayloadDecoder gopacket.Decoder = ProtocolGuessingDecoder{}\n\nfunc decodeMPLS(data []byte, p gopacket.PacketBuilder) error {\n\tdecoded := binary.BigEndian.Uint32(data[:4])\n\tmpls := &MPLS{\n\t\tLabel:        decoded >> 12,\n\t\tTrafficClass: uint8(decoded>>9) & 0x7,\n\t\tStackBottom:  decoded&0x100 != 0,\n\t\tTTL:          uint8(decoded),\n\t\tBaseLayer:    BaseLayer{data[:4], data[4:]},\n\t}\n\tp.AddLayer(mpls)\n\tif mpls.StackBottom {\n\t\treturn p.NextDecoder(MPLSPayloadDecoder)\n\t}\n\treturn p.NextDecoder(gopacket.DecodeFunc(decodeMPLS))\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (m *MPLS) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbytes, err := b.PrependBytes(4)\n\tif err != nil {\n\t\treturn err\n\t}\n\tencoded := m.Label << 12\n\tencoded |= uint32(m.TrafficClass) << 9\n\tencoded |= uint32(m.TTL)\n\tif m.StackBottom {\n\t\tencoded |= 0x100\n\t}\n\tbinary.BigEndian.PutUint32(bytes, encoded)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/ndp.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\n// Enum types courtesy of...\n// http://anonsvn.wireshark.org/wireshark/trunk/epan/dissectors/packet-ndp.c\n\npackage layers\n\nimport (\n\t\"fmt\"\n\t\"github.com/google/gopacket\"\n\t\"net\"\n)\n\ntype NDPChassisType uint8\n\n// Nortel Chassis Types\nconst (\n\tNDPChassisother                                       NDPChassisType = 1\n\tNDPChassis3000                                        NDPChassisType = 2\n\tNDPChassis3030                                        NDPChassisType = 3\n\tNDPChassis2310                                        NDPChassisType = 4\n\tNDPChassis2810                                        NDPChassisType = 5\n\tNDPChassis2912                                        NDPChassisType = 6\n\tNDPChassis2914                                        NDPChassisType = 7\n\tNDPChassis271x                                        NDPChassisType = 8\n\tNDPChassis2813                                        NDPChassisType = 9\n\tNDPChassis2814                                        NDPChassisType = 10\n\tNDPChassis2915                                        NDPChassisType = 11\n\tNDPChassis5000                                        NDPChassisType = 12\n\tNDPChassis2813SA                                      NDPChassisType = 13\n\tNDPChassis2814SA                                      NDPChassisType = 14\n\tNDPChassis810M                                        NDPChassisType = 15\n\tNDPChassisEthercell                                   NDPChassisType = 16\n\tNDPChassis5005                                        NDPChassisType = 17\n\tNDPChassisAlcatelEWC                                  NDPChassisType = 18\n\tNDPChassis2715SA                                      NDPChassisType = 20\n\tNDPChassis2486                                        NDPChassisType = 21\n\tNDPChassis28000series                                 NDPChassisType = 22\n\tNDPChassis23000series                                 NDPChassisType = 23\n\tNDPChassis5DN00xseries                                NDPChassisType = 24\n\tNDPChassisBayStackEthernet                            NDPChassisType = 25\n\tNDPChassis23100series                                 NDPChassisType = 26\n\tNDPChassis100BaseTHub                                 NDPChassisType = 27\n\tNDPChassis3000FastEthernet                            NDPChassisType = 28\n\tNDPChassisOrionSwitch                                 NDPChassisType = 29\n\tNDPChassisDDS                                         NDPChassisType = 31\n\tNDPChassisCentillion6slot                             NDPChassisType = 32\n\tNDPChassisCentillion12slot                            NDPChassisType = 33\n\tNDPChassisCentillion1slot                             NDPChassisType = 34\n\tNDPChassisBayStack301                                 NDPChassisType = 35\n\tNDPChassisBayStackTokenRingHub                        NDPChassisType = 36\n\tNDPChassisFVCMultimediaSwitch                         NDPChassisType = 37\n\tNDPChassisSwitchNode                                  NDPChassisType = 38\n\tNDPChassisBayStack302Switch                           NDPChassisType = 39\n\tNDPChassisBayStack350Switch                           NDPChassisType = 40\n\tNDPChassisBayStack150EthernetHub                      NDPChassisType = 41\n\tNDPChassisCentillion50NSwitch                         NDPChassisType = 42\n\tNDPChassisCentillion50TSwitch                         NDPChassisType = 43\n\tNDPChassisBayStack303304Switches                      NDPChassisType = 44\n\tNDPChassisBayStack200EthernetHub                      NDPChassisType = 45\n\tNDPChassisBayStack25010100EthernetHub                 NDPChassisType = 46\n\tNDPChassisBayStack450101001000Switches                NDPChassisType = 48\n\tNDPChassisBayStack41010100Switches                    NDPChassisType = 49\n\tNDPChassisPassport1200L3Switch                        NDPChassisType = 50\n\tNDPChassisPassport1250L3Switch                        NDPChassisType = 51\n\tNDPChassisPassport1100L3Switch                        NDPChassisType = 52\n\tNDPChassisPassport1150L3Switch                        NDPChassisType = 53\n\tNDPChassisPassport1050L3Switch                        NDPChassisType = 54\n\tNDPChassisPassport1051L3Switch                        NDPChassisType = 55\n\tNDPChassisPassport8610L3Switch                        NDPChassisType = 56\n\tNDPChassisPassport8606L3Switch                        NDPChassisType = 57\n\tNDPChassisPassport8010                                NDPChassisType = 58\n\tNDPChassisPassport8006                                NDPChassisType = 59\n\tNDPChassisBayStack670wirelessaccesspoint              NDPChassisType = 60\n\tNDPChassisPassport740                                 NDPChassisType = 61\n\tNDPChassisPassport750                                 NDPChassisType = 62\n\tNDPChassisPassport790                                 NDPChassisType = 63\n\tNDPChassisBusinessPolicySwitch200010100Switches       NDPChassisType = 64\n\tNDPChassisPassport8110L2Switch                        NDPChassisType = 65\n\tNDPChassisPassport8106L2Switch                        NDPChassisType = 66\n\tNDPChassisBayStack3580GigSwitch                       NDPChassisType = 67\n\tNDPChassisBayStack10PowerSupplyUnit                   NDPChassisType = 68\n\tNDPChassisBayStack42010100Switch                      NDPChassisType = 69\n\tNDPChassisOPTeraMetro1200EthernetServiceModule        NDPChassisType = 70\n\tNDPChassisOPTera8010co                                NDPChassisType = 71\n\tNDPChassisOPTera8610coL3Switch                        NDPChassisType = 72\n\tNDPChassisOPTera8110coL2Switch                        NDPChassisType = 73\n\tNDPChassisOPTera8003                                  NDPChassisType = 74\n\tNDPChassisOPTera8603L3Switch                          NDPChassisType = 75\n\tNDPChassisOPTera8103L2Switch                          NDPChassisType = 76\n\tNDPChassisBayStack380101001000Switch                  NDPChassisType = 77\n\tNDPChassisEthernetSwitch47048T                        NDPChassisType = 78\n\tNDPChassisOPTeraMetro1450EthernetServiceModule        NDPChassisType = 79\n\tNDPChassisOPTeraMetro1400EthernetServiceModule        NDPChassisType = 80\n\tNDPChassisAlteonSwitchFamily                          NDPChassisType = 81\n\tNDPChassisEthernetSwitch46024TPWR                     NDPChassisType = 82\n\tNDPChassisOPTeraMetro8010OPML2Switch                  NDPChassisType = 83\n\tNDPChassisOPTeraMetro8010coOPML2Switch                NDPChassisType = 84\n\tNDPChassisOPTeraMetro8006OPML2Switch                  NDPChassisType = 85\n\tNDPChassisOPTeraMetro8003OPML2Switch                  NDPChassisType = 86\n\tNDPChassisAlteon180e                                  NDPChassisType = 87\n\tNDPChassisAlteonAD3                                   NDPChassisType = 88\n\tNDPChassisAlteon184                                   NDPChassisType = 89\n\tNDPChassisAlteonAD4                                   NDPChassisType = 90\n\tNDPChassisPassport1424L3Switch                        NDPChassisType = 91\n\tNDPChassisPassport1648L3Switch                        NDPChassisType = 92\n\tNDPChassisPassport1612L3Switch                        NDPChassisType = 93\n\tNDPChassisPassport1624L3Switch                        NDPChassisType = 94\n\tNDPChassisBayStack38024FFiber1000Switch               NDPChassisType = 95\n\tNDPChassisEthernetRoutingSwitch551024T                NDPChassisType = 96\n\tNDPChassisEthernetRoutingSwitch551048T                NDPChassisType = 97\n\tNDPChassisEthernetSwitch47024T                        NDPChassisType = 98\n\tNDPChassisNortelNetworksWirelessLANAccessPoint2220    NDPChassisType = 99\n\tNDPChassisPassportRBS2402L3Switch                     NDPChassisType = 100\n\tNDPChassisAlteonApplicationSwitch2424                 NDPChassisType = 101\n\tNDPChassisAlteonApplicationSwitch2224                 NDPChassisType = 102\n\tNDPChassisAlteonApplicationSwitch2208                 NDPChassisType = 103\n\tNDPChassisAlteonApplicationSwitch2216                 NDPChassisType = 104\n\tNDPChassisAlteonApplicationSwitch3408                 NDPChassisType = 105\n\tNDPChassisAlteonApplicationSwitch3416                 NDPChassisType = 106\n\tNDPChassisNortelNetworksWirelessLANSecuritySwitch2250 NDPChassisType = 107\n\tNDPChassisEthernetSwitch42548T                        NDPChassisType = 108\n\tNDPChassisEthernetSwitch42524T                        NDPChassisType = 109\n\tNDPChassisNortelNetworksWirelessLANAccessPoint2221    NDPChassisType = 110\n\tNDPChassisNortelMetroEthernetServiceUnit24TSPFswitch  NDPChassisType = 111\n\tNDPChassisNortelMetroEthernetServiceUnit24TLXDCswitch NDPChassisType = 112\n\tNDPChassisPassport830010slotchassis                   NDPChassisType = 113\n\tNDPChassisPassport83006slotchassis                    NDPChassisType = 114\n\tNDPChassisEthernetRoutingSwitch552024TPWR             NDPChassisType = 115\n\tNDPChassisEthernetRoutingSwitch552048TPWR             NDPChassisType = 116\n\tNDPChassisNortelNetworksVPNGateway3050                NDPChassisType = 117\n\tNDPChassisAlteonSSL31010100                           NDPChassisType = 118\n\tNDPChassisAlteonSSL31010100Fiber                      NDPChassisType = 119\n\tNDPChassisAlteonSSL31010100FIPS                       NDPChassisType = 120\n\tNDPChassisAlteonSSL410101001000                       NDPChassisType = 121\n\tNDPChassisAlteonSSL410101001000Fiber                  NDPChassisType = 122\n\tNDPChassisAlteonApplicationSwitch2424SSL              NDPChassisType = 123\n\tNDPChassisEthernetSwitch32524T                        NDPChassisType = 124\n\tNDPChassisEthernetSwitch32524G                        NDPChassisType = 125\n\tNDPChassisNortelNetworksWirelessLANAccessPoint2225    NDPChassisType = 126\n\tNDPChassisNortelNetworksWirelessLANSecuritySwitch2270 NDPChassisType = 127\n\tNDPChassis24portEthernetSwitch47024TPWR               NDPChassisType = 128\n\tNDPChassis48portEthernetSwitch47048TPWR               NDPChassisType = 129\n\tNDPChassisEthernetRoutingSwitch553024TFD              NDPChassisType = 130\n\tNDPChassisEthernetSwitch351024T                       NDPChassisType = 131\n\tNDPChassisNortelMetroEthernetServiceUnit12GACL3Switch NDPChassisType = 132\n\tNDPChassisNortelMetroEthernetServiceUnit12GDCL3Switch NDPChassisType = 133\n\tNDPChassisNortelSecureAccessSwitch                    NDPChassisType = 134\n\tNDPChassisNortelNetworksVPNGateway3070                NDPChassisType = 135\n\tNDPChassisOPTeraMetro3500                             NDPChassisType = 136\n\tNDPChassisSMBBES101024T                               NDPChassisType = 137\n\tNDPChassisSMBBES101048T                               NDPChassisType = 138\n\tNDPChassisSMBBES102024TPWR                            NDPChassisType = 139\n\tNDPChassisSMBBES102048TPWR                            NDPChassisType = 140\n\tNDPChassisSMBBES201024T                               NDPChassisType = 141\n\tNDPChassisSMBBES201048T                               NDPChassisType = 142\n\tNDPChassisSMBBES202024TPWR                            NDPChassisType = 143\n\tNDPChassisSMBBES202048TPWR                            NDPChassisType = 144\n\tNDPChassisSMBBES11024T                                NDPChassisType = 145\n\tNDPChassisSMBBES11048T                                NDPChassisType = 146\n\tNDPChassisSMBBES12024TPWR                             NDPChassisType = 147\n\tNDPChassisSMBBES12048TPWR                             NDPChassisType = 148\n\tNDPChassisSMBBES21024T                                NDPChassisType = 149\n\tNDPChassisSMBBES21048T                                NDPChassisType = 150\n\tNDPChassisSMBBES22024TPWR                             NDPChassisType = 151\n\tNDPChassisSMBBES22048TPWR                             NDPChassisType = 152\n\tNDPChassisOME6500                                     NDPChassisType = 153\n\tNDPChassisEthernetRoutingSwitch4548GT                 NDPChassisType = 154\n\tNDPChassisEthernetRoutingSwitch4548GTPWR              NDPChassisType = 155\n\tNDPChassisEthernetRoutingSwitch4550T                  NDPChassisType = 156\n\tNDPChassisEthernetRoutingSwitch4550TPWR               NDPChassisType = 157\n\tNDPChassisEthernetRoutingSwitch4526FX                 NDPChassisType = 158\n\tNDPChassisEthernetRoutingSwitch250026T                NDPChassisType = 159\n\tNDPChassisEthernetRoutingSwitch250026TPWR             NDPChassisType = 160\n\tNDPChassisEthernetRoutingSwitch250050T                NDPChassisType = 161\n\tNDPChassisEthernetRoutingSwitch250050TPWR             NDPChassisType = 162\n)\n\ntype NDPBackplaneType uint8\n\n// Nortel Backplane Types\nconst (\n\tNDPBackplaneOther                                       NDPBackplaneType = 1\n\tNDPBackplaneEthernet                                    NDPBackplaneType = 2\n\tNDPBackplaneEthernetTokenring                           NDPBackplaneType = 3\n\tNDPBackplaneEthernetFDDI                                NDPBackplaneType = 4\n\tNDPBackplaneEthernetTokenringFDDI                       NDPBackplaneType = 5\n\tNDPBackplaneEthernetTokenringRedundantPower             NDPBackplaneType = 6\n\tNDPBackplaneEthernetTokenringFDDIRedundantPower         NDPBackplaneType = 7\n\tNDPBackplaneTokenRing                                   NDPBackplaneType = 8\n\tNDPBackplaneEthernetTokenringFastEthernet               NDPBackplaneType = 9\n\tNDPBackplaneEthernetFastEthernet                        NDPBackplaneType = 10\n\tNDPBackplaneEthernetTokenringFastEthernetRedundantPower NDPBackplaneType = 11\n\tNDPBackplaneEthernetFastEthernetGigabitEthernet         NDPBackplaneType = 12\n)\n\ntype NDPState uint8\n\n// Device State\nconst (\n\tNDPStateTopology  NDPState = 1\n\tNDPStateHeartbeat NDPState = 2\n\tNDPStateNew       NDPState = 3\n)\n\n// NortelDiscovery is a packet layer containing the Nortel Discovery Protocol.\ntype NortelDiscovery struct {\n\tBaseLayer\n\tIPAddress net.IP\n\tSegmentID []byte\n\tChassis   NDPChassisType\n\tBackplane NDPBackplaneType\n\tState     NDPState\n\tNumLinks  uint8\n}\n\n// LayerType returns gopacket.LayerTypeNortelDiscovery.\nfunc (c *NortelDiscovery) LayerType() gopacket.LayerType {\n\treturn LayerTypeNortelDiscovery\n}\n\nfunc decodeNortelDiscovery(data []byte, p gopacket.PacketBuilder) error {\n\tc := &NortelDiscovery{}\n\tif len(data) < 11 {\n\t\treturn fmt.Errorf(\"Invalid NortelDiscovery packet length %d\", len(data))\n\t}\n\tc.IPAddress = data[0:4]\n\tc.SegmentID = data[4:7]\n\tc.Chassis = NDPChassisType(data[7])\n\tc.Backplane = NDPBackplaneType(data[8])\n\tc.State = NDPState(data[9])\n\tc.NumLinks = uint8(data[10])\n\tp.AddLayer(c)\n\treturn nil\n}\n\nfunc (t NDPChassisType) String() (s string) {\n\tswitch t {\n\tcase NDPChassisother:\n\t\ts = \"other\"\n\tcase NDPChassis3000:\n\t\ts = \"3000\"\n\tcase NDPChassis3030:\n\t\ts = \"3030\"\n\tcase NDPChassis2310:\n\t\ts = \"2310\"\n\tcase NDPChassis2810:\n\t\ts = \"2810\"\n\tcase NDPChassis2912:\n\t\ts = \"2912\"\n\tcase NDPChassis2914:\n\t\ts = \"2914\"\n\tcase NDPChassis271x:\n\t\ts = \"271x\"\n\tcase NDPChassis2813:\n\t\ts = \"2813\"\n\tcase NDPChassis2814:\n\t\ts = \"2814\"\n\tcase NDPChassis2915:\n\t\ts = \"2915\"\n\tcase NDPChassis5000:\n\t\ts = \"5000\"\n\tcase NDPChassis2813SA:\n\t\ts = \"2813SA\"\n\tcase NDPChassis2814SA:\n\t\ts = \"2814SA\"\n\tcase NDPChassis810M:\n\t\ts = \"810M\"\n\tcase NDPChassisEthercell:\n\t\ts = \"Ethercell\"\n\tcase NDPChassis5005:\n\t\ts = \"5005\"\n\tcase NDPChassisAlcatelEWC:\n\t\ts = \"Alcatel Ethernet workgroup conc.\"\n\tcase NDPChassis2715SA:\n\t\ts = \"2715SA\"\n\tcase NDPChassis2486:\n\t\ts = \"2486\"\n\tcase NDPChassis28000series:\n\t\ts = \"28000 series\"\n\tcase NDPChassis23000series:\n\t\ts = \"23000 series\"\n\tcase NDPChassis5DN00xseries:\n\t\ts = \"5DN00x series\"\n\tcase NDPChassisBayStackEthernet:\n\t\ts = \"BayStack Ethernet\"\n\tcase NDPChassis23100series:\n\t\ts = \"23100 series\"\n\tcase NDPChassis100BaseTHub:\n\t\ts = \"100Base-T Hub\"\n\tcase NDPChassis3000FastEthernet:\n\t\ts = \"3000 Fast Ethernet\"\n\tcase NDPChassisOrionSwitch:\n\t\ts = \"Orion switch\"\n\tcase NDPChassisDDS:\n\t\ts = \"DDS\"\n\tcase NDPChassisCentillion6slot:\n\t\ts = \"Centillion (6 slot)\"\n\tcase NDPChassisCentillion12slot:\n\t\ts = \"Centillion (12 slot)\"\n\tcase NDPChassisCentillion1slot:\n\t\ts = \"Centillion (1 slot)\"\n\tcase NDPChassisBayStack301:\n\t\ts = \"BayStack 301\"\n\tcase NDPChassisBayStackTokenRingHub:\n\t\ts = \"BayStack TokenRing Hub\"\n\tcase NDPChassisFVCMultimediaSwitch:\n\t\ts = \"FVC Multimedia Switch\"\n\tcase NDPChassisSwitchNode:\n\t\ts = \"Switch Node\"\n\tcase NDPChassisBayStack302Switch:\n\t\ts = \"BayStack 302 Switch\"\n\tcase NDPChassisBayStack350Switch:\n\t\ts = \"BayStack 350 Switch\"\n\tcase NDPChassisBayStack150EthernetHub:\n\t\ts = \"BayStack 150 Ethernet Hub\"\n\tcase NDPChassisCentillion50NSwitch:\n\t\ts = \"Centillion 50N switch\"\n\tcase NDPChassisCentillion50TSwitch:\n\t\ts = \"Centillion 50T switch\"\n\tcase NDPChassisBayStack303304Switches:\n\t\ts = \"BayStack 303 and 304 Switches\"\n\tcase NDPChassisBayStack200EthernetHub:\n\t\ts = \"BayStack 200 Ethernet Hub\"\n\tcase NDPChassisBayStack25010100EthernetHub:\n\t\ts = \"BayStack 250 10/100 Ethernet Hub\"\n\tcase NDPChassisBayStack450101001000Switches:\n\t\ts = \"BayStack 450 10/100/1000 Switches\"\n\tcase NDPChassisBayStack41010100Switches:\n\t\ts = \"BayStack 410 10/100 Switches\"\n\tcase NDPChassisPassport1200L3Switch:\n\t\ts = \"Passport 1200 L3 Switch\"\n\tcase NDPChassisPassport1250L3Switch:\n\t\ts = \"Passport 1250 L3 Switch\"\n\tcase NDPChassisPassport1100L3Switch:\n\t\ts = \"Passport 1100 L3 Switch\"\n\tcase NDPChassisPassport1150L3Switch:\n\t\ts = \"Passport 1150 L3 Switch\"\n\tcase NDPChassisPassport1050L3Switch:\n\t\ts = \"Passport 1050 L3 Switch\"\n\tcase NDPChassisPassport1051L3Switch:\n\t\ts = \"Passport 1051 L3 Switch\"\n\tcase NDPChassisPassport8610L3Switch:\n\t\ts = \"Passport 8610 L3 Switch\"\n\tcase NDPChassisPassport8606L3Switch:\n\t\ts = \"Passport 8606 L3 Switch\"\n\tcase NDPChassisPassport8010:\n\t\ts = \"Passport 8010\"\n\tcase NDPChassisPassport8006:\n\t\ts = \"Passport 8006\"\n\tcase NDPChassisBayStack670wirelessaccesspoint:\n\t\ts = \"BayStack 670 wireless access point\"\n\tcase NDPChassisPassport740:\n\t\ts = \"Passport 740\"\n\tcase NDPChassisPassport750:\n\t\ts = \"Passport 750\"\n\tcase NDPChassisPassport790:\n\t\ts = \"Passport 790\"\n\tcase NDPChassisBusinessPolicySwitch200010100Switches:\n\t\ts = \"Business Policy Switch 2000 10/100 Switches\"\n\tcase NDPChassisPassport8110L2Switch:\n\t\ts = \"Passport 8110 L2 Switch\"\n\tcase NDPChassisPassport8106L2Switch:\n\t\ts = \"Passport 8106 L2 Switch\"\n\tcase NDPChassisBayStack3580GigSwitch:\n\t\ts = \"BayStack 3580 Gig Switch\"\n\tcase NDPChassisBayStack10PowerSupplyUnit:\n\t\ts = \"BayStack 10 Power Supply Unit\"\n\tcase NDPChassisBayStack42010100Switch:\n\t\ts = \"BayStack 420 10/100 Switch\"\n\tcase NDPChassisOPTeraMetro1200EthernetServiceModule:\n\t\ts = \"OPTera Metro 1200 Ethernet Service Module\"\n\tcase NDPChassisOPTera8010co:\n\t\ts = \"OPTera 8010co\"\n\tcase NDPChassisOPTera8610coL3Switch:\n\t\ts = \"OPTera 8610co L3 switch\"\n\tcase NDPChassisOPTera8110coL2Switch:\n\t\ts = \"OPTera 8110co L2 switch\"\n\tcase NDPChassisOPTera8003:\n\t\ts = \"OPTera 8003\"\n\tcase NDPChassisOPTera8603L3Switch:\n\t\ts = \"OPTera 8603 L3 switch\"\n\tcase NDPChassisOPTera8103L2Switch:\n\t\ts = \"OPTera 8103 L2 switch\"\n\tcase NDPChassisBayStack380101001000Switch:\n\t\ts = \"BayStack 380 10/100/1000 Switch\"\n\tcase NDPChassisEthernetSwitch47048T:\n\t\ts = \"Ethernet Switch 470-48T\"\n\tcase NDPChassisOPTeraMetro1450EthernetServiceModule:\n\t\ts = \"OPTera Metro 1450 Ethernet Service Module\"\n\tcase NDPChassisOPTeraMetro1400EthernetServiceModule:\n\t\ts = \"OPTera Metro 1400 Ethernet Service Module\"\n\tcase NDPChassisAlteonSwitchFamily:\n\t\ts = \"Alteon Switch Family\"\n\tcase NDPChassisEthernetSwitch46024TPWR:\n\t\ts = \"Ethernet Switch 460-24T-PWR\"\n\tcase NDPChassisOPTeraMetro8010OPML2Switch:\n\t\ts = \"OPTera Metro 8010 OPM L2 Switch\"\n\tcase NDPChassisOPTeraMetro8010coOPML2Switch:\n\t\ts = \"OPTera Metro 8010co OPM L2 Switch\"\n\tcase NDPChassisOPTeraMetro8006OPML2Switch:\n\t\ts = \"OPTera Metro 8006 OPM L2 Switch\"\n\tcase NDPChassisOPTeraMetro8003OPML2Switch:\n\t\ts = \"OPTera Metro 8003 OPM L2 Switch\"\n\tcase NDPChassisAlteon180e:\n\t\ts = \"Alteon 180e\"\n\tcase NDPChassisAlteonAD3:\n\t\ts = \"Alteon AD3\"\n\tcase NDPChassisAlteon184:\n\t\ts = \"Alteon 184\"\n\tcase NDPChassisAlteonAD4:\n\t\ts = \"Alteon AD4\"\n\tcase NDPChassisPassport1424L3Switch:\n\t\ts = \"Passport 1424 L3 switch\"\n\tcase NDPChassisPassport1648L3Switch:\n\t\ts = \"Passport 1648 L3 switch\"\n\tcase NDPChassisPassport1612L3Switch:\n\t\ts = \"Passport 1612 L3 switch\"\n\tcase NDPChassisPassport1624L3Switch:\n\t\ts = \"Passport 1624 L3 switch\"\n\tcase NDPChassisBayStack38024FFiber1000Switch:\n\t\ts = \"BayStack 380-24F Fiber 1000 Switch\"\n\tcase NDPChassisEthernetRoutingSwitch551024T:\n\t\ts = \"Ethernet Routing Switch 5510-24T\"\n\tcase NDPChassisEthernetRoutingSwitch551048T:\n\t\ts = \"Ethernet Routing Switch 5510-48T\"\n\tcase NDPChassisEthernetSwitch47024T:\n\t\ts = \"Ethernet Switch 470-24T\"\n\tcase NDPChassisNortelNetworksWirelessLANAccessPoint2220:\n\t\ts = \"Nortel Networks Wireless LAN Access Point 2220\"\n\tcase NDPChassisPassportRBS2402L3Switch:\n\t\ts = \"Passport RBS 2402 L3 switch\"\n\tcase NDPChassisAlteonApplicationSwitch2424:\n\t\ts = \"Alteon Application Switch 2424\"\n\tcase NDPChassisAlteonApplicationSwitch2224:\n\t\ts = \"Alteon Application Switch 2224\"\n\tcase NDPChassisAlteonApplicationSwitch2208:\n\t\ts = \"Alteon Application Switch 2208\"\n\tcase NDPChassisAlteonApplicationSwitch2216:\n\t\ts = \"Alteon Application Switch 2216\"\n\tcase NDPChassisAlteonApplicationSwitch3408:\n\t\ts = \"Alteon Application Switch 3408\"\n\tcase NDPChassisAlteonApplicationSwitch3416:\n\t\ts = \"Alteon Application Switch 3416\"\n\tcase NDPChassisNortelNetworksWirelessLANSecuritySwitch2250:\n\t\ts = \"Nortel Networks Wireless LAN SecuritySwitch 2250\"\n\tcase NDPChassisEthernetSwitch42548T:\n\t\ts = \"Ethernet Switch 425-48T\"\n\tcase NDPChassisEthernetSwitch42524T:\n\t\ts = \"Ethernet Switch 425-24T\"\n\tcase NDPChassisNortelNetworksWirelessLANAccessPoint2221:\n\t\ts = \"Nortel Networks Wireless LAN Access Point 2221\"\n\tcase NDPChassisNortelMetroEthernetServiceUnit24TSPFswitch:\n\t\ts = \"Nortel Metro Ethernet Service Unit 24-T SPF switch\"\n\tcase NDPChassisNortelMetroEthernetServiceUnit24TLXDCswitch:\n\t\ts = \" Nortel Metro Ethernet Service Unit 24-T LX DC switch\"\n\tcase NDPChassisPassport830010slotchassis:\n\t\ts = \"Passport 8300 10-slot chassis\"\n\tcase NDPChassisPassport83006slotchassis:\n\t\ts = \"Passport 8300 6-slot chassis\"\n\tcase NDPChassisEthernetRoutingSwitch552024TPWR:\n\t\ts = \"Ethernet Routing Switch 5520-24T-PWR\"\n\tcase NDPChassisEthernetRoutingSwitch552048TPWR:\n\t\ts = \"Ethernet Routing Switch 5520-48T-PWR\"\n\tcase NDPChassisNortelNetworksVPNGateway3050:\n\t\ts = \"Nortel Networks VPN Gateway 3050\"\n\tcase NDPChassisAlteonSSL31010100:\n\t\ts = \"Alteon SSL 310 10/100\"\n\tcase NDPChassisAlteonSSL31010100Fiber:\n\t\ts = \"Alteon SSL 310 10/100 Fiber\"\n\tcase NDPChassisAlteonSSL31010100FIPS:\n\t\ts = \"Alteon SSL 310 10/100 FIPS\"\n\tcase NDPChassisAlteonSSL410101001000:\n\t\ts = \"Alteon SSL 410 10/100/1000\"\n\tcase NDPChassisAlteonSSL410101001000Fiber:\n\t\ts = \"Alteon SSL 410 10/100/1000 Fiber\"\n\tcase NDPChassisAlteonApplicationSwitch2424SSL:\n\t\ts = \"Alteon Application Switch 2424-SSL\"\n\tcase NDPChassisEthernetSwitch32524T:\n\t\ts = \"Ethernet Switch 325-24T\"\n\tcase NDPChassisEthernetSwitch32524G:\n\t\ts = \"Ethernet Switch 325-24G\"\n\tcase NDPChassisNortelNetworksWirelessLANAccessPoint2225:\n\t\ts = \"Nortel Networks Wireless LAN Access Point 2225\"\n\tcase NDPChassisNortelNetworksWirelessLANSecuritySwitch2270:\n\t\ts = \"Nortel Networks Wireless LAN SecuritySwitch 2270\"\n\tcase NDPChassis24portEthernetSwitch47024TPWR:\n\t\ts = \"24-port Ethernet Switch 470-24T-PWR\"\n\tcase NDPChassis48portEthernetSwitch47048TPWR:\n\t\ts = \"48-port Ethernet Switch 470-48T-PWR\"\n\tcase NDPChassisEthernetRoutingSwitch553024TFD:\n\t\ts = \"Ethernet Routing Switch 5530-24TFD\"\n\tcase NDPChassisEthernetSwitch351024T:\n\t\ts = \"Ethernet Switch 3510-24T\"\n\tcase NDPChassisNortelMetroEthernetServiceUnit12GACL3Switch:\n\t\ts = \"Nortel Metro Ethernet Service Unit 12G AC L3 switch\"\n\tcase NDPChassisNortelMetroEthernetServiceUnit12GDCL3Switch:\n\t\ts = \"Nortel Metro Ethernet Service Unit 12G DC L3 switch\"\n\tcase NDPChassisNortelSecureAccessSwitch:\n\t\ts = \"Nortel Secure Access Switch\"\n\tcase NDPChassisNortelNetworksVPNGateway3070:\n\t\ts = \"Nortel Networks VPN Gateway 3070\"\n\tcase NDPChassisOPTeraMetro3500:\n\t\ts = \"OPTera Metro 3500\"\n\tcase NDPChassisSMBBES101024T:\n\t\ts = \"SMB BES 1010 24T\"\n\tcase NDPChassisSMBBES101048T:\n\t\ts = \"SMB BES 1010 48T\"\n\tcase NDPChassisSMBBES102024TPWR:\n\t\ts = \"SMB BES 1020 24T PWR\"\n\tcase NDPChassisSMBBES102048TPWR:\n\t\ts = \"SMB BES 1020 48T PWR\"\n\tcase NDPChassisSMBBES201024T:\n\t\ts = \"SMB BES 2010 24T\"\n\tcase NDPChassisSMBBES201048T:\n\t\ts = \"SMB BES 2010 48T\"\n\tcase NDPChassisSMBBES202024TPWR:\n\t\ts = \"SMB BES 2020 24T PWR\"\n\tcase NDPChassisSMBBES202048TPWR:\n\t\ts = \"SMB BES 2020 48T PWR\"\n\tcase NDPChassisSMBBES11024T:\n\t\ts = \"SMB BES 110 24T\"\n\tcase NDPChassisSMBBES11048T:\n\t\ts = \"SMB BES 110 48T\"\n\tcase NDPChassisSMBBES12024TPWR:\n\t\ts = \"SMB BES 120 24T PWR\"\n\tcase NDPChassisSMBBES12048TPWR:\n\t\ts = \"SMB BES 120 48T PWR\"\n\tcase NDPChassisSMBBES21024T:\n\t\ts = \"SMB BES 210 24T\"\n\tcase NDPChassisSMBBES21048T:\n\t\ts = \"SMB BES 210 48T\"\n\tcase NDPChassisSMBBES22024TPWR:\n\t\ts = \"SMB BES 220 24T PWR\"\n\tcase NDPChassisSMBBES22048TPWR:\n\t\ts = \"SMB BES 220 48T PWR\"\n\tcase NDPChassisOME6500:\n\t\ts = \"OME 6500\"\n\tcase NDPChassisEthernetRoutingSwitch4548GT:\n\t\ts = \"Ethernet Routing Switch 4548GT\"\n\tcase NDPChassisEthernetRoutingSwitch4548GTPWR:\n\t\ts = \"Ethernet Routing Switch 4548GT-PWR\"\n\tcase NDPChassisEthernetRoutingSwitch4550T:\n\t\ts = \"Ethernet Routing Switch 4550T\"\n\tcase NDPChassisEthernetRoutingSwitch4550TPWR:\n\t\ts = \"Ethernet Routing Switch 4550T-PWR\"\n\tcase NDPChassisEthernetRoutingSwitch4526FX:\n\t\ts = \"Ethernet Routing Switch 4526FX\"\n\tcase NDPChassisEthernetRoutingSwitch250026T:\n\t\ts = \"Ethernet Routing Switch 2500-26T\"\n\tcase NDPChassisEthernetRoutingSwitch250026TPWR:\n\t\ts = \"Ethernet Routing Switch 2500-26T-PWR\"\n\tcase NDPChassisEthernetRoutingSwitch250050T:\n\t\ts = \"Ethernet Routing Switch 2500-50T\"\n\tcase NDPChassisEthernetRoutingSwitch250050TPWR:\n\t\ts = \"Ethernet Routing Switch 2500-50T-PWR\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc (t NDPBackplaneType) String() (s string) {\n\tswitch t {\n\tcase NDPBackplaneOther:\n\t\ts = \"Other\"\n\tcase NDPBackplaneEthernet:\n\t\ts = \"Ethernet\"\n\tcase NDPBackplaneEthernetTokenring:\n\t\ts = \"Ethernet and Tokenring\"\n\tcase NDPBackplaneEthernetFDDI:\n\t\ts = \"Ethernet and FDDI\"\n\tcase NDPBackplaneEthernetTokenringFDDI:\n\t\ts = \"Ethernet, Tokenring and FDDI\"\n\tcase NDPBackplaneEthernetTokenringRedundantPower:\n\t\ts = \"Ethernet and Tokenring with redundant power\"\n\tcase NDPBackplaneEthernetTokenringFDDIRedundantPower:\n\t\ts = \"Ethernet, Tokenring, FDDI with redundant power\"\n\tcase NDPBackplaneTokenRing:\n\t\ts = \"Token Ring\"\n\tcase NDPBackplaneEthernetTokenringFastEthernet:\n\t\ts = \"Ethernet, Tokenring and Fast Ethernet\"\n\tcase NDPBackplaneEthernetFastEthernet:\n\t\ts = \"Ethernet and Fast Ethernet\"\n\tcase NDPBackplaneEthernetTokenringFastEthernetRedundantPower:\n\t\ts = \"Ethernet, Tokenring, Fast Ethernet with redundant power\"\n\tcase NDPBackplaneEthernetFastEthernetGigabitEthernet:\n\t\ts = \"Ethernet, Fast Ethernet and Gigabit Ethernet\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n\nfunc (t NDPState) String() (s string) {\n\tswitch t {\n\tcase NDPStateTopology:\n\t\ts = \"Topology Change\"\n\tcase NDPStateHeartbeat:\n\t\ts = \"Heartbeat\"\n\tcase NDPStateNew:\n\t\ts = \"New\"\n\tdefault:\n\t\ts = \"Unknown\"\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/ntp.go",
    "content": "// Copyright 2016 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n//\n//******************************************************************************\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\n\t\"github.com/google/gopacket\"\n)\n\n//******************************************************************************\n//\n// Network Time Protocol (NTP) Decoding Layer\n// ------------------------------------------\n// This file provides a GoPacket decoding layer for NTP.\n//\n//******************************************************************************\n//\n// About The Network Time Protocol (NTP)\n// -------------------------------------\n// NTP is a protocol that enables computers on the internet to set their\n// clocks to the correct time (or to a time that is acceptably close to the\n// correct time). NTP runs on top of UDP.\n//\n// There have been a series of versions of the NTP protocol. The latest\n// version is V4 and is specified in RFC 5905:\n//     http://www.ietf.org/rfc/rfc5905.txt\n//\n//******************************************************************************\n//\n// References\n// ----------\n//\n// Wikipedia's NTP entry:\n//     https://en.wikipedia.org/wiki/Network_Time_Protocol\n//     This is the best place to get an overview of NTP.\n//\n// Network Time Protocol Home Website:\n//     http://www.ntp.org/\n//     This appears to be the official website of NTP.\n//\n// List of current NTP Protocol RFCs:\n//     http://www.ntp.org/rfc.html\n//\n// RFC 958: \"Network Time Protocol (NTP)\" (1985)\n//     https://tools.ietf.org/html/rfc958\n//     This is the original NTP specification.\n//\n// RFC 1305: \"Network Time Protocol (Version 3) Specification, Implementation and Analysis\" (1992)\n//     https://tools.ietf.org/html/rfc1305\n//     The protocol was updated in 1992 yielding NTP V3.\n//\n// RFC 5905: \"Network Time Protocol Version 4: Protocol and Algorithms Specification\" (2010)\n//     https://www.ietf.org/rfc/rfc5905.txt\n//     The protocol was updated in 2010 yielding NTP V4.\n//     V4 is backwards compatible with all previous versions of NTP.\n//\n// RFC 5906: \"Network Time Protocol Version 4: Autokey Specification\"\n//     https://tools.ietf.org/html/rfc5906\n//     This document addresses the security of the NTP protocol\n//     and is probably not relevant to this package.\n//\n// RFC 5907: \"Definitions of Managed Objects for Network Time Protocol Version 4 (NTPv4)\"\n//     https://tools.ietf.org/html/rfc5907\n//     This document addresses the management of NTP servers and\n//     is probably not relevant to this package.\n//\n// RFC 5908: \"Network Time Protocol (NTP) Server Option for DHCPv6\"\n//     https://tools.ietf.org/html/rfc5908\n//     This document addresses the use of NTP in DHCPv6 and is\n//     probably not relevant to this package.\n//\n// \"Let's make a NTP Client in C\"\n//     https://lettier.github.io/posts/2016-04-26-lets-make-a-ntp-client-in-c.html\n//     This web page contains useful information about the details of NTP,\n//     including an NTP record struture in C, and C code.\n//\n// \"NTP Packet Header (NTP Reference Implementation) (Computer Network Time Synchronization)\"\n//     http://what-when-how.com/computer-network-time-synchronization/\n//        ntp-packet-header-ntp-reference-implementation-computer-network-time-synchronization/\n//     This web page contains useful information on the details of NTP.\n//\n// \"Technical information - NTP Data Packet\"\n//     https://www.meinbergglobal.com/english/info/ntp-packet.htm\n//     This page has a helpful diagram of an NTP V4 packet.\n//\n//******************************************************************************\n//\n// Obsolete References\n// -------------------\n//\n// RFC 1119: \"RFC-1119 \"Network Time Protocol (Version 2) Specification and Implementation\" (1989)\n//     https://tools.ietf.org/html/rfc1119\n//     Version 2 was drafted in 1989.\n//     It is unclear whether V2 was ever implememented or whether the\n//     ideas ended up in V3 (which was implemented in 1992).\n//\n// RFC 1361: \"Simple Network Time Protocol (SNTP)\"\n//     https://tools.ietf.org/html/rfc1361\n//     This document is obsoleted by RFC 1769 and is included only for completeness.\n//\n// RFC 1769: \"Simple Network Time Protocol (SNTP)\"\n//     https://tools.ietf.org/html/rfc1769\n//     This document is obsoleted by RFC 2030 and RFC 4330 and is included only for completeness.\n//\n// RFC 2030: \"Simple Network Time Protocol (SNTP) Version 4 for IPv4, IPv6 and OSI\"\n//     https://tools.ietf.org/html/rfc2030\n//     This document is obsoleted by RFC 4330 and is included only for completeness.\n//\n// RFC 4330: \"Simple Network Time Protocol (SNTP) Version 4 for IPv4, IPv6 and OSI\"\n//     https://tools.ietf.org/html/rfc4330\n//     This document is obsoleted by RFC 5905 and is included only for completeness.\n//\n//******************************************************************************\n//\n// Endian And Bit Numbering Issues\n// -------------------------------\n//\n// Endian and bit numbering issues can be confusing. Here is some\n// clarification:\n//\n//    ENDIAN: Values are sent big endian.\n//    https://en.wikipedia.org/wiki/Endianness\n//\n//    BIT NUMBERING: Bits are numbered 0 upwards from the most significant\n//    bit to the least significant bit. This means that if there is a 32-bit\n//    value, the most significant bit is called bit 0 and the least\n//    significant bit is called bit 31.\n//\n// See RFC 791 Appendix B for more discussion.\n//\n//******************************************************************************\n//\n// NTP V3 and V4 Packet Format\n// ---------------------------\n// NTP packets are UDP packets whose payload contains an NTP record.\n//\n// The NTP RFC defines the format of the NTP record.\n//\n// There have been four versions of the protocol:\n//\n//    V1 in 1985\n//    V2 in 1989\n//    V3 in 1992\n//    V4 in 2010\n//\n// It is clear that V1 and V2 are obsolete, and there is no need to\n// cater for these formats.\n//\n// V3 and V4 essentially use the same format, with V4 adding some optional\n// fields on the end. So this package supports the V3 and V4 formats.\n//\n// The current version of NTP (NTP V4)'s RFC (V4 - RFC 5905) contains\n// the following diagram for the NTP record format:\n\n//      0                   1                   2                   3\n//      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |LI | VN  |Mode |    Stratum    |     Poll      |   Precision   |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                         Root Delay                            |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                         Root Dispersion                       |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                          Reference ID                         |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                                                               |\n//     +                     Reference Timestamp (64)                  +\n//     |                                                               |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                                                               |\n//     +                      Origin Timestamp (64)                    +\n//     |                                                               |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                                                               |\n//     +                      Receive Timestamp (64)                   +\n//     |                                                               |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                                                               |\n//     +                      Transmit Timestamp (64)                  +\n//     |                                                               |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                                                               |\n//     .                                                               .\n//     .                    Extension Field 1 (variable)               .\n//     .                                                               .\n//     |                                                               |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                                                               |\n//     .                                                               .\n//     .                    Extension Field 2 (variable)               .\n//     .                                                               .\n//     |                                                               |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                          Key Identifier                       |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     |                                                               |\n//     |                            dgst (128)                         |\n//     |                                                               |\n//     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n//     From http://www.ietf.org/rfc/rfc5905.txt\n//\n// The fields \"Extension Field 1 (variable)\" and later are optional fields,\n// and so we can set a minimum NTP record size of 48 bytes.\n//\nconst ntpMinimumRecordSizeInBytes int = 48\n\n//******************************************************************************\n\n// NTP Type\n// --------\n// Type NTP implements the DecodingLayer interface. Each NTP object\n// represents in a structured form the NTP record present as the UDP\n// payload in an NTP UDP packet.\n//\n\ntype NTPLeapIndicator uint8\ntype NTPVersion uint8\ntype NTPMode uint8\ntype NTPStratum uint8\ntype NTPLog2Seconds int8\ntype NTPFixed16Seconds uint32\ntype NTPReferenceID uint32\ntype NTPTimestamp uint64\n\ntype NTP struct {\n\tBaseLayer // Stores the packet bytes and payload bytes.\n\n\tLeapIndicator      NTPLeapIndicator  // [0,3]. Indicates whether leap second(s) is to be added.\n\tVersion            NTPVersion        // [0,7]. Version of the NTP protocol.\n\tMode               NTPMode           // [0,7]. Mode.\n\tStratum            NTPStratum        // [0,255]. Stratum of time server in the server tree.\n\tPoll               NTPLog2Seconds    // [-128,127]. The maximum interval between successive messages, in log2 seconds.\n\tPrecision          NTPLog2Seconds    // [-128,127]. The precision of the system clock, in log2 seconds.\n\tRootDelay          NTPFixed16Seconds // [0,2^32-1]. Total round trip delay to the reference clock in seconds times 2^16.\n\tRootDispersion     NTPFixed16Seconds // [0,2^32-1]. Total dispersion to the reference clock, in seconds times 2^16.\n\tReferenceID        NTPReferenceID    // ID code of reference clock [0,2^32-1].\n\tReferenceTimestamp NTPTimestamp      // Most recent timestamp from the reference clock.\n\tOriginTimestamp    NTPTimestamp      // Local time when request was sent from local host.\n\tReceiveTimestamp   NTPTimestamp      // Local time (on server) that request arrived at server host.\n\tTransmitTimestamp  NTPTimestamp      // Local time (on server) that request departed server host.\n\n\t// FIX: This package should analyse the extension fields and represent the extension fields too.\n\tExtensionBytes []byte // Just put extensions in a byte slice.\n}\n\n//******************************************************************************\n\n// LayerType returns the layer type of the NTP object, which is LayerTypeNTP.\nfunc (d *NTP) LayerType() gopacket.LayerType {\n\treturn LayerTypeNTP\n}\n\n//******************************************************************************\n\n// decodeNTP analyses a byte slice and attempts to decode it as an NTP\n// record of a UDP packet.\n//\n// If it succeeds, it loads p with information about the packet and returns nil.\n// If it fails, it returns an error (non nil).\n//\n// This function is employed in layertypes.go to register the NTP layer.\nfunc decodeNTP(data []byte, p gopacket.PacketBuilder) error {\n\n\t// Attempt to decode the byte slice.\n\td := &NTP{}\n\terr := d.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// If the decoding worked, add the layer to the packet and set it\n\t// as the application layer too, if there isn't already one.\n\tp.AddLayer(d)\n\tp.SetApplicationLayer(d)\n\n\treturn nil\n}\n\n//******************************************************************************\n\n// DecodeFromBytes analyses a byte slice and attempts to decode it as an NTP\n// record of a UDP packet.\n//\n// Upon succeeds, it loads the NTP object with information about the packet\n// and returns nil.\n// Upon failure, it returns an error (non nil).\nfunc (d *NTP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\n\t// If the data block is too short to be a NTP record, then return an error.\n\tif len(data) < ntpMinimumRecordSizeInBytes {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"NTP packet too short\")\n\t}\n\n\t// RFC 5905 does not appear to define a maximum NTP record length.\n\t// The protocol allows \"extension fields\" to be included in the record,\n\t// and states about these fields:\"\n\t//\n\t//     \"While the minimum field length containing required fields is\n\t//      four words (16 octets), a maximum field length remains to be\n\t//      established.\"\n\t//\n\t// For this reason, the packet length is not checked here for being too long.\n\n\t// NTP type embeds type BaseLayer which contains two fields:\n\t//    Contents is supposed to contain the bytes of the data at this level.\n\t//    Payload is supposed to contain the payload of this level.\n\t// Here we set the baselayer to be the bytes of the NTP record.\n\td.BaseLayer = BaseLayer{Contents: data[:len(data)]}\n\n\t// Extract the fields from the block of bytes.\n\t// To make sense of this, refer to the packet diagram\n\t// above and the section on endian conventions.\n\n\t// The first few fields are all packed into the first 32 bits. Unpack them.\n\tf := data[0]\n\td.LeapIndicator = NTPLeapIndicator((f & 0xC0) >> 6)\n\td.Version = NTPVersion((f & 0x38) >> 3)\n\td.Mode = NTPMode(f & 0x07)\n\td.Stratum = NTPStratum(data[1])\n\td.Poll = NTPLog2Seconds(data[2])\n\td.Precision = NTPLog2Seconds(data[3])\n\n\t// The remaining fields can just be copied in big endian order.\n\td.RootDelay = NTPFixed16Seconds(binary.BigEndian.Uint32(data[4:8]))\n\td.RootDispersion = NTPFixed16Seconds(binary.BigEndian.Uint32(data[8:12]))\n\td.ReferenceID = NTPReferenceID(binary.BigEndian.Uint32(data[12:16]))\n\td.ReferenceTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[16:24]))\n\td.OriginTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[24:32]))\n\td.ReceiveTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[32:40]))\n\td.TransmitTimestamp = NTPTimestamp(binary.BigEndian.Uint64(data[40:48]))\n\n\t// This layer does not attempt to analyse the extension bytes.\n\t// But if there are any, we'd like the user to know. So we just\n\t// place them all in an ExtensionBytes field.\n\td.ExtensionBytes = data[48:]\n\n\t// Return no error.\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (d *NTP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tdata, err := b.PrependBytes(ntpMinimumRecordSizeInBytes)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Pack the first few fields into the first 32 bits.\n\th := uint8(0)\n\th |= (uint8(d.LeapIndicator) << 6) & 0xC0\n\th |= (uint8(d.Version) << 3) & 0x38\n\th |= (uint8(d.Mode)) & 0x07\n\tdata[0] = byte(h)\n\tdata[1] = byte(d.Stratum)\n\tdata[2] = byte(d.Poll)\n\tdata[3] = byte(d.Precision)\n\n\t// The remaining fields can just be copied in big endian order.\n\tbinary.BigEndian.PutUint32(data[4:8], uint32(d.RootDelay))\n\tbinary.BigEndian.PutUint32(data[8:12], uint32(d.RootDispersion))\n\tbinary.BigEndian.PutUint32(data[12:16], uint32(d.ReferenceID))\n\tbinary.BigEndian.PutUint64(data[16:24], uint64(d.ReferenceTimestamp))\n\tbinary.BigEndian.PutUint64(data[24:32], uint64(d.OriginTimestamp))\n\tbinary.BigEndian.PutUint64(data[32:40], uint64(d.ReceiveTimestamp))\n\tbinary.BigEndian.PutUint64(data[40:48], uint64(d.TransmitTimestamp))\n\n\tex, err := b.AppendBytes(len(d.ExtensionBytes))\n\tif err != nil {\n\t\treturn err\n\t}\n\tcopy(ex, d.ExtensionBytes)\n\n\treturn nil\n}\n\n//******************************************************************************\n\n// CanDecode returns a set of layers that NTP objects can decode.\n// As NTP objects can only decide the NTP layer, we can return just that layer.\n// Apparently a single layer type implements LayerClass.\nfunc (d *NTP) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeNTP\n}\n\n//******************************************************************************\n\n// NextLayerType specifies the next layer that GoPacket should attempt to\n// analyse after this (NTP) layer. As NTP packets do not contain any payload\n// bytes, there are no further layers to analyse.\nfunc (d *NTP) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypeZero\n}\n\n//******************************************************************************\n\n// NTP packets do not carry any data payload, so the empty byte slice is retured.\n// In Go, a nil slice is functionally identical to an empty slice, so we\n// return nil to avoid a heap allocation.\nfunc (d *NTP) Payload() []byte {\n\treturn nil\n}\n\n//******************************************************************************\n//*                            End Of NTP File                                 *\n//******************************************************************************\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/ospf.go",
    "content": "// Copyright 2017 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// OSPFType denotes what kind of OSPF type it is\ntype OSPFType uint8\n\n// Potential values for OSPF.Type.\nconst (\n\tOSPFHello                   OSPFType = 1\n\tOSPFDatabaseDescription     OSPFType = 2\n\tOSPFLinkStateRequest        OSPFType = 3\n\tOSPFLinkStateUpdate         OSPFType = 4\n\tOSPFLinkStateAcknowledgment OSPFType = 5\n)\n\n// LSA Function Codes for LSAheader.LSType\nconst (\n\tRouterLSAtypeV2         = 0x1\n\tRouterLSAtype           = 0x2001\n\tNetworkLSAtypeV2        = 0x2\n\tNetworkLSAtype          = 0x2002\n\tSummaryLSANetworktypeV2 = 0x3\n\tInterAreaPrefixLSAtype  = 0x2003\n\tSummaryLSAASBRtypeV2    = 0x4\n\tInterAreaRouterLSAtype  = 0x2004\n\tASExternalLSAtypeV2     = 0x5\n\tASExternalLSAtype       = 0x4005\n\tNSSALSAtype             = 0x2007\n\tNSSALSAtypeV2           = 0x7\n\tLinkLSAtype             = 0x0008\n\tIntraAreaPrefixLSAtype  = 0x2009\n)\n\n// String conversions for OSPFType\nfunc (i OSPFType) String() string {\n\tswitch i {\n\tcase OSPFHello:\n\t\treturn \"Hello\"\n\tcase OSPFDatabaseDescription:\n\t\treturn \"Database Description\"\n\tcase OSPFLinkStateRequest:\n\t\treturn \"Link State Request\"\n\tcase OSPFLinkStateUpdate:\n\t\treturn \"Link State Update\"\n\tcase OSPFLinkStateAcknowledgment:\n\t\treturn \"Link State Acknowledgment\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\n// Prefix extends IntraAreaPrefixLSA\ntype Prefix struct {\n\tPrefixLength  uint8\n\tPrefixOptions uint8\n\tMetric        uint16\n\tAddressPrefix []byte\n}\n\n// IntraAreaPrefixLSA is the struct from RFC 5340  A.4.10.\ntype IntraAreaPrefixLSA struct {\n\tNumOfPrefixes  uint16\n\tRefLSType      uint16\n\tRefLinkStateID uint32\n\tRefAdvRouter   uint32\n\tPrefixes       []Prefix\n}\n\n// LinkLSA is the struct from RFC 5340  A.4.9.\ntype LinkLSA struct {\n\tRtrPriority      uint8\n\tOptions          uint32\n\tLinkLocalAddress []byte\n\tNumOfPrefixes    uint32\n\tPrefixes         []Prefix\n}\n\n// ASExternalLSAV2 is the struct from RFC 2328  A.4.5.\ntype ASExternalLSAV2 struct {\n\tNetworkMask       uint32\n\tExternalBit       uint8\n\tMetric            uint32\n\tForwardingAddress uint32\n\tExternalRouteTag  uint32\n}\n\n// ASExternalLSA is the struct from RFC 5340  A.4.7.\ntype ASExternalLSA struct {\n\tFlags             uint8\n\tMetric            uint32\n\tPrefixLength      uint8\n\tPrefixOptions     uint8\n\tRefLSType         uint16\n\tAddressPrefix     []byte\n\tForwardingAddress []byte\n\tExternalRouteTag  uint32\n\tRefLinkStateID    uint32\n}\n\n// InterAreaRouterLSA is the struct from RFC 5340  A.4.6.\ntype InterAreaRouterLSA struct {\n\tOptions             uint32\n\tMetric              uint32\n\tDestinationRouterID uint32\n}\n\n// InterAreaPrefixLSA is the struct from RFC 5340  A.4.5.\ntype InterAreaPrefixLSA struct {\n\tMetric        uint32\n\tPrefixLength  uint8\n\tPrefixOptions uint8\n\tAddressPrefix []byte\n}\n\n// NetworkLSA is the struct from RFC 5340  A.4.4.\ntype NetworkLSA struct {\n\tOptions        uint32\n\tAttachedRouter []uint32\n}\n\n// NetworkLSAV2 is the struct from RFC 2328  A.4.3.\ntype NetworkLSAV2 struct {\n\tNetworkMask    uint32\n\tAttachedRouter []uint32\n}\n\n// RouterV2 extends RouterLSAV2\ntype RouterV2 struct {\n\tType     uint8\n\tLinkID   uint32\n\tLinkData uint32\n\tMetric   uint16\n}\n\n// RouterLSAV2 is the struct from RFC 2328  A.4.2.\ntype RouterLSAV2 struct {\n\tFlags   uint8\n\tLinks   uint16\n\tRouters []RouterV2\n}\n\n// Router extends RouterLSA\ntype Router struct {\n\tType                uint8\n\tMetric              uint16\n\tInterfaceID         uint32\n\tNeighborInterfaceID uint32\n\tNeighborRouterID    uint32\n}\n\n// RouterLSA is the struct from RFC 5340  A.4.3.\ntype RouterLSA struct {\n\tFlags   uint8\n\tOptions uint32\n\tRouters []Router\n}\n\n// LSAheader is the struct from RFC 5340  A.4.2 and RFC 2328 A.4.1.\ntype LSAheader struct {\n\tLSAge       uint16\n\tLSType      uint16\n\tLinkStateID uint32\n\tAdvRouter   uint32\n\tLSSeqNumber uint32\n\tLSChecksum  uint16\n\tLength      uint16\n\tLSOptions   uint8\n}\n\n// LSA links LSAheader with the structs from RFC 5340  A.4.\ntype LSA struct {\n\tLSAheader\n\tContent interface{}\n}\n\n// LSUpdate is the struct from RFC 5340  A.3.5.\ntype LSUpdate struct {\n\tNumOfLSAs uint32\n\tLSAs      []LSA\n}\n\n// LSReq is the struct from RFC 5340  A.3.4.\ntype LSReq struct {\n\tLSType    uint16\n\tLSID      uint32\n\tAdvRouter uint32\n}\n\n// DbDescPkg is the struct from RFC 5340  A.3.3.\ntype DbDescPkg struct {\n\tOptions      uint32\n\tInterfaceMTU uint16\n\tFlags        uint16\n\tDDSeqNumber  uint32\n\tLSAinfo      []LSAheader\n}\n\n// HelloPkg  is the struct from RFC 5340  A.3.2.\ntype HelloPkg struct {\n\tInterfaceID              uint32\n\tRtrPriority              uint8\n\tOptions                  uint32\n\tHelloInterval            uint16\n\tRouterDeadInterval       uint32\n\tDesignatedRouterID       uint32\n\tBackupDesignatedRouterID uint32\n\tNeighborID               []uint32\n}\n\n// HelloPkgV2 extends the HelloPkg struct with OSPFv2 information\ntype HelloPkgV2 struct {\n\tHelloPkg\n\tNetworkMask uint32\n}\n\n// OSPF is a basic OSPF packet header with common fields of Version 2 and Version 3.\ntype OSPF struct {\n\tVersion      uint8\n\tType         OSPFType\n\tPacketLength uint16\n\tRouterID     uint32\n\tAreaID       uint32\n\tChecksum     uint16\n\tContent      interface{}\n}\n\n//OSPFv2 extend the OSPF head with version 2 specific fields\ntype OSPFv2 struct {\n\tBaseLayer\n\tOSPF\n\tAuType         uint16\n\tAuthentication uint64\n}\n\n// OSPFv3 extend the OSPF head with version 3 specific fields\ntype OSPFv3 struct {\n\tBaseLayer\n\tOSPF\n\tInstance uint8\n\tReserved uint8\n}\n\n// getLSAsv2 parses the LSA information from the packet for OSPFv2\nfunc getLSAsv2(num uint32, data []byte) ([]LSA, error) {\n\tvar lsas []LSA\n\tvar i uint32 = 0\n\tvar offset uint32 = 0\n\tfor ; i < num; i++ {\n\t\tlstype := uint16(data[offset+3])\n\t\tlsalength := binary.BigEndian.Uint16(data[offset+18 : offset+20])\n\t\tcontent, err := extractLSAInformation(lstype, lsalength, data[offset:])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"Could not extract Link State type.\")\n\t\t}\n\t\tlsa := LSA{\n\t\t\tLSAheader: LSAheader{\n\t\t\t\tLSAge:       binary.BigEndian.Uint16(data[offset : offset+2]),\n\t\t\t\tLSOptions:   data[offset+2],\n\t\t\t\tLSType:      lstype,\n\t\t\t\tLinkStateID: binary.BigEndian.Uint32(data[offset+4 : offset+8]),\n\t\t\t\tAdvRouter:   binary.BigEndian.Uint32(data[offset+8 : offset+12]),\n\t\t\t\tLSSeqNumber: binary.BigEndian.Uint32(data[offset+12 : offset+16]),\n\t\t\t\tLSChecksum:  binary.BigEndian.Uint16(data[offset+16 : offset+18]),\n\t\t\t\tLength:      lsalength,\n\t\t\t},\n\t\t\tContent: content,\n\t\t}\n\t\tlsas = append(lsas, lsa)\n\t\toffset += uint32(lsalength)\n\t}\n\treturn lsas, nil\n}\n\n// extractLSAInformation extracts all the LSA information\nfunc extractLSAInformation(lstype, lsalength uint16, data []byte) (interface{}, error) {\n\tif lsalength < 20 {\n\t\treturn nil, fmt.Errorf(\"Link State header length %v too short, %v required\", lsalength, 20)\n\t}\n\tif len(data) < int(lsalength) {\n\t\treturn nil, fmt.Errorf(\"Link State header length %v too short, %v required\", len(data), lsalength)\n\t}\n\tvar content interface{}\n\tswitch lstype {\n\tcase RouterLSAtypeV2:\n\t\tvar routers []RouterV2\n\t\tvar j uint32\n\t\tfor j = 24; j < uint32(lsalength); j += 12 {\n\t\t\tif len(data) < int(j+12) {\n\t\t\t\treturn nil, errors.New(\"LSAtypeV2 too small\")\n\t\t\t}\n\t\t\trouter := RouterV2{\n\t\t\t\tLinkID:   binary.BigEndian.Uint32(data[j : j+4]),\n\t\t\t\tLinkData: binary.BigEndian.Uint32(data[j+4 : j+8]),\n\t\t\t\tType:     uint8(data[j+8]),\n\t\t\t\tMetric:   binary.BigEndian.Uint16(data[j+10 : j+12]),\n\t\t\t}\n\t\t\trouters = append(routers, router)\n\t\t}\n\t\tif len(data) < 24 {\n\t\t\treturn nil, errors.New(\"LSAtypeV2 too small\")\n\t\t}\n\t\tlinks := binary.BigEndian.Uint16(data[22:24])\n\t\tcontent = RouterLSAV2{\n\t\t\tFlags:   data[20],\n\t\t\tLinks:   links,\n\t\t\tRouters: routers,\n\t\t}\n\tcase NSSALSAtypeV2:\n\t\tfallthrough\n\tcase ASExternalLSAtypeV2:\n\t\tcontent = ASExternalLSAV2{\n\t\t\tNetworkMask:       binary.BigEndian.Uint32(data[20:24]),\n\t\t\tExternalBit:       data[24] & 0x80,\n\t\t\tMetric:            binary.BigEndian.Uint32(data[24:28]) & 0x00FFFFFF,\n\t\t\tForwardingAddress: binary.BigEndian.Uint32(data[28:32]),\n\t\t\tExternalRouteTag:  binary.BigEndian.Uint32(data[32:36]),\n\t\t}\n\tcase NetworkLSAtypeV2:\n\t\tvar routers []uint32\n\t\tvar j uint32\n\t\tfor j = 24; j < uint32(lsalength); j += 4 {\n\t\t\trouters = append(routers, binary.BigEndian.Uint32(data[j:j+4]))\n\t\t}\n\t\tcontent = NetworkLSAV2{\n\t\t\tNetworkMask:    binary.BigEndian.Uint32(data[20:24]),\n\t\t\tAttachedRouter: routers,\n\t\t}\n\tcase RouterLSAtype:\n\t\tvar routers []Router\n\t\tvar j uint32\n\t\tfor j = 24; j < uint32(lsalength); j += 16 {\n\t\t\trouter := Router{\n\t\t\t\tType:                uint8(data[j]),\n\t\t\t\tMetric:              binary.BigEndian.Uint16(data[j+2 : j+4]),\n\t\t\t\tInterfaceID:         binary.BigEndian.Uint32(data[j+4 : j+8]),\n\t\t\t\tNeighborInterfaceID: binary.BigEndian.Uint32(data[j+8 : j+12]),\n\t\t\t\tNeighborRouterID:    binary.BigEndian.Uint32(data[j+12 : j+16]),\n\t\t\t}\n\t\t\trouters = append(routers, router)\n\t\t}\n\t\tcontent = RouterLSA{\n\t\t\tFlags:   uint8(data[20]),\n\t\t\tOptions: binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,\n\t\t\tRouters: routers,\n\t\t}\n\tcase NetworkLSAtype:\n\t\tvar routers []uint32\n\t\tvar j uint32\n\t\tfor j = 24; j < uint32(lsalength); j += 4 {\n\t\t\trouters = append(routers, binary.BigEndian.Uint32(data[j:j+4]))\n\t\t}\n\t\tcontent = NetworkLSA{\n\t\t\tOptions:        binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,\n\t\t\tAttachedRouter: routers,\n\t\t}\n\tcase InterAreaPrefixLSAtype:\n\t\tcontent = InterAreaPrefixLSA{\n\t\t\tMetric:        binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,\n\t\t\tPrefixLength:  uint8(data[24]),\n\t\t\tPrefixOptions: uint8(data[25]),\n\t\t\tAddressPrefix: data[28:uint32(lsalength)],\n\t\t}\n\tcase InterAreaRouterLSAtype:\n\t\tcontent = InterAreaRouterLSA{\n\t\t\tOptions:             binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,\n\t\t\tMetric:              binary.BigEndian.Uint32(data[24:28]) & 0x00FFFFFF,\n\t\t\tDestinationRouterID: binary.BigEndian.Uint32(data[28:32]),\n\t\t}\n\tcase ASExternalLSAtype:\n\t\tfallthrough\n\tcase NSSALSAtype:\n\t\tflags := uint8(data[20])\n\t\tprefixLen := uint8(data[24]) / 8\n\t\tvar forwardingAddress []byte\n\t\tif (flags & 0x02) == 0x02 {\n\t\t\tforwardingAddress = data[28+uint32(prefixLen) : 28+uint32(prefixLen)+16]\n\t\t}\n\t\tcontent = ASExternalLSA{\n\t\t\tFlags:             flags,\n\t\t\tMetric:            binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,\n\t\t\tPrefixLength:      prefixLen,\n\t\t\tPrefixOptions:     uint8(data[25]),\n\t\t\tRefLSType:         binary.BigEndian.Uint16(data[26:28]),\n\t\t\tAddressPrefix:     data[28 : 28+uint32(prefixLen)],\n\t\t\tForwardingAddress: forwardingAddress,\n\t\t}\n\tcase LinkLSAtype:\n\t\tvar prefixes []Prefix\n\t\tvar prefixOffset uint32 = 44\n\t\tvar j uint32\n\t\tnumOfPrefixes := binary.BigEndian.Uint32(data[40:44])\n\t\tfor j = 0; j < numOfPrefixes; j++ {\n\t\t\tprefixLen := uint8(data[prefixOffset])\n\t\t\tprefix := Prefix{\n\t\t\t\tPrefixLength:  prefixLen,\n\t\t\t\tPrefixOptions: uint8(data[prefixOffset+1]),\n\t\t\t\tAddressPrefix: data[prefixOffset+4 : prefixOffset+4+uint32(prefixLen)/8],\n\t\t\t}\n\t\t\tprefixes = append(prefixes, prefix)\n\t\t\tprefixOffset = prefixOffset + 4 + uint32(prefixLen)/8\n\t\t}\n\t\tcontent = LinkLSA{\n\t\t\tRtrPriority:      uint8(data[20]),\n\t\t\tOptions:          binary.BigEndian.Uint32(data[20:24]) & 0x00FFFFFF,\n\t\t\tLinkLocalAddress: data[24:40],\n\t\t\tNumOfPrefixes:    numOfPrefixes,\n\t\t\tPrefixes:         prefixes,\n\t\t}\n\tcase IntraAreaPrefixLSAtype:\n\t\tvar prefixes []Prefix\n\t\tvar prefixOffset uint32 = 32\n\t\tvar j uint16\n\t\tnumOfPrefixes := binary.BigEndian.Uint16(data[20:22])\n\t\tfor j = 0; j < numOfPrefixes; j++ {\n\t\t\tprefixLen := uint8(data[prefixOffset])\n\t\t\tprefix := Prefix{\n\t\t\t\tPrefixLength:  prefixLen,\n\t\t\t\tPrefixOptions: uint8(data[prefixOffset+1]),\n\t\t\t\tMetric:        binary.BigEndian.Uint16(data[prefixOffset+2 : prefixOffset+4]),\n\t\t\t\tAddressPrefix: data[prefixOffset+4 : prefixOffset+4+uint32(prefixLen)/8],\n\t\t\t}\n\t\t\tprefixes = append(prefixes, prefix)\n\t\t\tprefixOffset = prefixOffset + 4 + uint32(prefixLen)\n\t\t}\n\t\tcontent = IntraAreaPrefixLSA{\n\t\t\tNumOfPrefixes:  numOfPrefixes,\n\t\t\tRefLSType:      binary.BigEndian.Uint16(data[22:24]),\n\t\t\tRefLinkStateID: binary.BigEndian.Uint32(data[24:28]),\n\t\t\tRefAdvRouter:   binary.BigEndian.Uint32(data[28:32]),\n\t\t\tPrefixes:       prefixes,\n\t\t}\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"Unknown Link State type.\")\n\t}\n\treturn content, nil\n}\n\n// getLSAs parses the LSA information from the packet for OSPFv3\nfunc getLSAs(num uint32, data []byte) ([]LSA, error) {\n\tvar lsas []LSA\n\tvar i uint32 = 0\n\tvar offset uint32 = 0\n\tfor ; i < num; i++ {\n\t\tvar content interface{}\n\t\tlstype := binary.BigEndian.Uint16(data[offset+2 : offset+4])\n\t\tlsalength := binary.BigEndian.Uint16(data[offset+18 : offset+20])\n\n\t\tcontent, err := extractLSAInformation(lstype, lsalength, data[offset:])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"Could not extract Link State type.\")\n\t\t}\n\t\tlsa := LSA{\n\t\t\tLSAheader: LSAheader{\n\t\t\t\tLSAge:       binary.BigEndian.Uint16(data[offset : offset+2]),\n\t\t\t\tLSType:      lstype,\n\t\t\t\tLinkStateID: binary.BigEndian.Uint32(data[offset+4 : offset+8]),\n\t\t\t\tAdvRouter:   binary.BigEndian.Uint32(data[offset+8 : offset+12]),\n\t\t\t\tLSSeqNumber: binary.BigEndian.Uint32(data[offset+12 : offset+16]),\n\t\t\t\tLSChecksum:  binary.BigEndian.Uint16(data[offset+16 : offset+18]),\n\t\t\t\tLength:      lsalength,\n\t\t\t},\n\t\t\tContent: content,\n\t\t}\n\t\tlsas = append(lsas, lsa)\n\t\toffset += uint32(lsalength)\n\t}\n\treturn lsas, nil\n}\n\n// DecodeFromBytes decodes the given bytes into the OSPF layer.\nfunc (ospf *OSPFv2) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 24 {\n\t\treturn fmt.Errorf(\"Packet too smal for OSPF Version 2\")\n\t}\n\n\tospf.Version = uint8(data[0])\n\tospf.Type = OSPFType(data[1])\n\tospf.PacketLength = binary.BigEndian.Uint16(data[2:4])\n\tospf.RouterID = binary.BigEndian.Uint32(data[4:8])\n\tospf.AreaID = binary.BigEndian.Uint32(data[8:12])\n\tospf.Checksum = binary.BigEndian.Uint16(data[12:14])\n\tospf.AuType = binary.BigEndian.Uint16(data[14:16])\n\tospf.Authentication = binary.BigEndian.Uint64(data[16:24])\n\n\tswitch ospf.Type {\n\tcase OSPFHello:\n\t\tvar neighbors []uint32\n\t\tfor i := 44; uint16(i+4) <= ospf.PacketLength; i += 4 {\n\t\t\tneighbors = append(neighbors, binary.BigEndian.Uint32(data[i:i+4]))\n\t\t}\n\t\tospf.Content = HelloPkgV2{\n\t\t\tNetworkMask: binary.BigEndian.Uint32(data[24:28]),\n\t\t\tHelloPkg: HelloPkg{\n\t\t\t\tHelloInterval:            binary.BigEndian.Uint16(data[28:30]),\n\t\t\t\tOptions:                  uint32(data[30]),\n\t\t\t\tRtrPriority:              uint8(data[31]),\n\t\t\t\tRouterDeadInterval:       binary.BigEndian.Uint32(data[32:36]),\n\t\t\t\tDesignatedRouterID:       binary.BigEndian.Uint32(data[36:40]),\n\t\t\t\tBackupDesignatedRouterID: binary.BigEndian.Uint32(data[40:44]),\n\t\t\t\tNeighborID:               neighbors,\n\t\t\t},\n\t\t}\n\tcase OSPFDatabaseDescription:\n\t\tvar lsas []LSAheader\n\t\tfor i := 32; uint16(i+20) <= ospf.PacketLength; i += 20 {\n\t\t\tlsa := LSAheader{\n\t\t\t\tLSAge:       binary.BigEndian.Uint16(data[i : i+2]),\n\t\t\t\tLSType:      binary.BigEndian.Uint16(data[i+2 : i+4]),\n\t\t\t\tLinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]),\n\t\t\t\tAdvRouter:   binary.BigEndian.Uint32(data[i+8 : i+12]),\n\t\t\t\tLSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]),\n\t\t\t\tLSChecksum:  binary.BigEndian.Uint16(data[i+16 : i+18]),\n\t\t\t\tLength:      binary.BigEndian.Uint16(data[i+18 : i+20]),\n\t\t\t}\n\t\t\tlsas = append(lsas, lsa)\n\t\t}\n\t\tospf.Content = DbDescPkg{\n\t\t\tInterfaceMTU: binary.BigEndian.Uint16(data[24:26]),\n\t\t\tOptions:      uint32(data[26]),\n\t\t\tFlags:        uint16(data[27]),\n\t\t\tDDSeqNumber:  binary.BigEndian.Uint32(data[28:32]),\n\t\t\tLSAinfo:      lsas,\n\t\t}\n\tcase OSPFLinkStateRequest:\n\t\tvar lsrs []LSReq\n\t\tfor i := 24; uint16(i+12) <= ospf.PacketLength; i += 12 {\n\t\t\tlsr := LSReq{\n\t\t\t\tLSType:    binary.BigEndian.Uint16(data[i+2 : i+4]),\n\t\t\t\tLSID:      binary.BigEndian.Uint32(data[i+4 : i+8]),\n\t\t\t\tAdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),\n\t\t\t}\n\t\t\tlsrs = append(lsrs, lsr)\n\t\t}\n\t\tospf.Content = lsrs\n\tcase OSPFLinkStateUpdate:\n\t\tnum := binary.BigEndian.Uint32(data[24:28])\n\n\t\tlsas, err := getLSAsv2(num, data[28:])\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"Cannot parse Link State Update packet: %v\", err)\n\t\t}\n\t\tospf.Content = LSUpdate{\n\t\t\tNumOfLSAs: num,\n\t\t\tLSAs:      lsas,\n\t\t}\n\tcase OSPFLinkStateAcknowledgment:\n\t\tvar lsas []LSAheader\n\t\tfor i := 24; uint16(i+20) <= ospf.PacketLength; i += 20 {\n\t\t\tlsa := LSAheader{\n\t\t\t\tLSAge:       binary.BigEndian.Uint16(data[i : i+2]),\n\t\t\t\tLSOptions:   data[i+2],\n\t\t\t\tLSType:      uint16(data[i+3]),\n\t\t\t\tLinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]),\n\t\t\t\tAdvRouter:   binary.BigEndian.Uint32(data[i+8 : i+12]),\n\t\t\t\tLSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]),\n\t\t\t\tLSChecksum:  binary.BigEndian.Uint16(data[i+16 : i+18]),\n\t\t\t\tLength:      binary.BigEndian.Uint16(data[i+18 : i+20]),\n\t\t\t}\n\t\t\tlsas = append(lsas, lsa)\n\t\t}\n\t\tospf.Content = lsas\n\t}\n\treturn nil\n}\n\n// DecodeFromBytes decodes the given bytes into the OSPF layer.\nfunc (ospf *OSPFv3) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\n\tif len(data) < 16 {\n\t\treturn fmt.Errorf(\"Packet too smal for OSPF Version 3\")\n\t}\n\n\tospf.Version = uint8(data[0])\n\tospf.Type = OSPFType(data[1])\n\tospf.PacketLength = binary.BigEndian.Uint16(data[2:4])\n\tospf.RouterID = binary.BigEndian.Uint32(data[4:8])\n\tospf.AreaID = binary.BigEndian.Uint32(data[8:12])\n\tospf.Checksum = binary.BigEndian.Uint16(data[12:14])\n\tospf.Instance = uint8(data[14])\n\tospf.Reserved = uint8(data[15])\n\n\tswitch ospf.Type {\n\tcase OSPFHello:\n\t\tvar neighbors []uint32\n\t\tfor i := 36; uint16(i+4) <= ospf.PacketLength; i += 4 {\n\t\t\tneighbors = append(neighbors, binary.BigEndian.Uint32(data[i:i+4]))\n\t\t}\n\t\tospf.Content = HelloPkg{\n\t\t\tInterfaceID:              binary.BigEndian.Uint32(data[16:20]),\n\t\t\tRtrPriority:              uint8(data[20]),\n\t\t\tOptions:                  binary.BigEndian.Uint32(data[21:25]) >> 8,\n\t\t\tHelloInterval:            binary.BigEndian.Uint16(data[24:26]),\n\t\t\tRouterDeadInterval:       uint32(binary.BigEndian.Uint16(data[26:28])),\n\t\t\tDesignatedRouterID:       binary.BigEndian.Uint32(data[28:32]),\n\t\t\tBackupDesignatedRouterID: binary.BigEndian.Uint32(data[32:36]),\n\t\t\tNeighborID:               neighbors,\n\t\t}\n\tcase OSPFDatabaseDescription:\n\t\tvar lsas []LSAheader\n\t\tfor i := 28; uint16(i+20) <= ospf.PacketLength; i += 20 {\n\t\t\tlsa := LSAheader{\n\t\t\t\tLSAge:       binary.BigEndian.Uint16(data[i : i+2]),\n\t\t\t\tLSType:      binary.BigEndian.Uint16(data[i+2 : i+4]),\n\t\t\t\tLinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]),\n\t\t\t\tAdvRouter:   binary.BigEndian.Uint32(data[i+8 : i+12]),\n\t\t\t\tLSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]),\n\t\t\t\tLSChecksum:  binary.BigEndian.Uint16(data[i+16 : i+18]),\n\t\t\t\tLength:      binary.BigEndian.Uint16(data[i+18 : i+20]),\n\t\t\t}\n\t\t\tlsas = append(lsas, lsa)\n\t\t}\n\t\tospf.Content = DbDescPkg{\n\t\t\tOptions:      binary.BigEndian.Uint32(data[16:20]) & 0x00FFFFFF,\n\t\t\tInterfaceMTU: binary.BigEndian.Uint16(data[20:22]),\n\t\t\tFlags:        binary.BigEndian.Uint16(data[22:24]),\n\t\t\tDDSeqNumber:  binary.BigEndian.Uint32(data[24:28]),\n\t\t\tLSAinfo:      lsas,\n\t\t}\n\tcase OSPFLinkStateRequest:\n\t\tvar lsrs []LSReq\n\t\tfor i := 16; uint16(i+12) <= ospf.PacketLength; i += 12 {\n\t\t\tlsr := LSReq{\n\t\t\t\tLSType:    binary.BigEndian.Uint16(data[i+2 : i+4]),\n\t\t\t\tLSID:      binary.BigEndian.Uint32(data[i+4 : i+8]),\n\t\t\t\tAdvRouter: binary.BigEndian.Uint32(data[i+8 : i+12]),\n\t\t\t}\n\t\t\tlsrs = append(lsrs, lsr)\n\t\t}\n\t\tospf.Content = lsrs\n\tcase OSPFLinkStateUpdate:\n\t\tnum := binary.BigEndian.Uint32(data[16:20])\n\t\tlsas, err := getLSAs(num, data[20:])\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"Cannot parse Link State Update packet: %v\", err)\n\t\t}\n\t\tospf.Content = LSUpdate{\n\t\t\tNumOfLSAs: num,\n\t\t\tLSAs:      lsas,\n\t\t}\n\n\tcase OSPFLinkStateAcknowledgment:\n\t\tvar lsas []LSAheader\n\t\tfor i := 16; uint16(i+20) <= ospf.PacketLength; i += 20 {\n\t\t\tlsa := LSAheader{\n\t\t\t\tLSAge:       binary.BigEndian.Uint16(data[i : i+2]),\n\t\t\t\tLSType:      binary.BigEndian.Uint16(data[i+2 : i+4]),\n\t\t\t\tLinkStateID: binary.BigEndian.Uint32(data[i+4 : i+8]),\n\t\t\t\tAdvRouter:   binary.BigEndian.Uint32(data[i+8 : i+12]),\n\t\t\t\tLSSeqNumber: binary.BigEndian.Uint32(data[i+12 : i+16]),\n\t\t\t\tLSChecksum:  binary.BigEndian.Uint16(data[i+16 : i+18]),\n\t\t\t\tLength:      binary.BigEndian.Uint16(data[i+18 : i+20]),\n\t\t\t}\n\t\t\tlsas = append(lsas, lsa)\n\t\t}\n\t\tospf.Content = lsas\n\tdefault:\n\t}\n\n\treturn nil\n}\n\n// LayerType returns LayerTypeOSPF\nfunc (ospf *OSPFv2) LayerType() gopacket.LayerType {\n\treturn LayerTypeOSPF\n}\nfunc (ospf *OSPFv3) LayerType() gopacket.LayerType {\n\treturn LayerTypeOSPF\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (ospf *OSPFv2) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypeZero\n}\nfunc (ospf *OSPFv3) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypeZero\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (ospf *OSPFv2) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeOSPF\n}\nfunc (ospf *OSPFv3) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeOSPF\n}\n\nfunc decodeOSPF(data []byte, p gopacket.PacketBuilder) error {\n\tif len(data) < 14 {\n\t\treturn fmt.Errorf(\"Packet too smal for OSPF\")\n\t}\n\n\tswitch uint8(data[0]) {\n\tcase 2:\n\t\tospf := &OSPFv2{}\n\t\treturn decodingLayerDecoder(ospf, data, p)\n\tcase 3:\n\t\tospf := &OSPFv3{}\n\t\treturn decodingLayerDecoder(ospf, data, p)\n\tdefault:\n\t}\n\n\treturn fmt.Errorf(\"Unable to determine OSPF type.\")\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/pflog.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/google/gopacket\"\n)\n\ntype PFDirection uint8\n\nconst (\n\tPFDirectionInOut PFDirection = 0\n\tPFDirectionIn    PFDirection = 1\n\tPFDirectionOut   PFDirection = 2\n)\n\n// PFLog provides the layer for 'pf' packet-filter logging, as described at\n// http://www.freebsd.org/cgi/man.cgi?query=pflog&sektion=4\ntype PFLog struct {\n\tBaseLayer\n\tLength              uint8\n\tFamily              ProtocolFamily\n\tAction, Reason      uint8\n\tIFName, Ruleset     []byte\n\tRuleNum, SubruleNum uint32\n\tUID                 uint32\n\tPID                 int32\n\tRuleUID             uint32\n\tRulePID             int32\n\tDirection           PFDirection\n\t// The remainder is padding\n}\n\nfunc (pf *PFLog) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 60 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"PFLog data less than 60 bytes\")\n\t}\n\tpf.Length = data[0]\n\tpf.Family = ProtocolFamily(data[1])\n\tpf.Action = data[2]\n\tpf.Reason = data[3]\n\tpf.IFName = data[4:20]\n\tpf.Ruleset = data[20:36]\n\tpf.RuleNum = binary.BigEndian.Uint32(data[36:40])\n\tpf.SubruleNum = binary.BigEndian.Uint32(data[40:44])\n\tpf.UID = binary.BigEndian.Uint32(data[44:48])\n\tpf.PID = int32(binary.BigEndian.Uint32(data[48:52]))\n\tpf.RuleUID = binary.BigEndian.Uint32(data[52:56])\n\tpf.RulePID = int32(binary.BigEndian.Uint32(data[56:60]))\n\tpf.Direction = PFDirection(data[60])\n\tif pf.Length%4 != 1 {\n\t\treturn errors.New(\"PFLog header length should be 3 less than multiple of 4\")\n\t}\n\tactualLength := int(pf.Length) + 3\n\tif len(data) < actualLength {\n\t\treturn fmt.Errorf(\"PFLog data size < %d\", actualLength)\n\t}\n\tpf.Contents = data[:actualLength]\n\tpf.Payload = data[actualLength:]\n\treturn nil\n}\n\n// LayerType returns layers.LayerTypePFLog\nfunc (pf *PFLog) LayerType() gopacket.LayerType { return LayerTypePFLog }\n\nfunc (pf *PFLog) CanDecode() gopacket.LayerClass { return LayerTypePFLog }\n\nfunc (pf *PFLog) NextLayerType() gopacket.LayerType {\n\treturn pf.Family.LayerType()\n}\n\nfunc decodePFLog(data []byte, p gopacket.PacketBuilder) error {\n\tpf := &PFLog{}\n\treturn decodingLayerDecoder(pf, data, p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/ports.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// TCPPort is a port in a TCP layer.\ntype TCPPort uint16\n\n// UDPPort is a port in a UDP layer.\ntype UDPPort uint16\n\n// RUDPPort is a port in a RUDP layer.\ntype RUDPPort uint8\n\n// SCTPPort is a port in a SCTP layer.\ntype SCTPPort uint16\n\n// UDPLitePort is a port in a UDPLite layer.\ntype UDPLitePort uint16\n\n// RUDPPortNames contains the string names for all RUDP ports.\nvar RUDPPortNames = map[RUDPPort]string{}\n\n// UDPLitePortNames contains the string names for all UDPLite ports.\nvar UDPLitePortNames = map[UDPLitePort]string{}\n\n// {TCP,UDP,SCTP}PortNames can be found in iana_ports.go\n\n// String returns the port as \"number(name)\" if there's a well-known port name,\n// or just \"number\" if there isn't.  Well-known names are stored in\n// TCPPortNames.\nfunc (a TCPPort) String() string {\n\tif name, ok := TCPPortNames[a]; ok {\n\t\treturn fmt.Sprintf(\"%d(%s)\", a, name)\n\t}\n\treturn strconv.Itoa(int(a))\n}\n\n// LayerType returns a LayerType that would be able to decode the\n// application payload. It uses some well-known ports such as 53 for\n// DNS.\n//\n// Returns gopacket.LayerTypePayload for unknown/unsupported port numbers.\nfunc (a TCPPort) LayerType() gopacket.LayerType {\n\tlt := tcpPortLayerType[uint16(a)]\n\tif lt != 0 {\n\t\treturn lt\n\t}\n\treturn gopacket.LayerTypePayload\n}\n\nvar tcpPortLayerType = [65536]gopacket.LayerType{\n\t53:   LayerTypeDNS,\n\t443:  LayerTypeTLS,       // https\n\t502:  LayerTypeModbusTCP, // modbustcp\n\t636:  LayerTypeTLS,       // ldaps\n\t989:  LayerTypeTLS,       // ftps-data\n\t990:  LayerTypeTLS,       // ftps\n\t992:  LayerTypeTLS,       // telnets\n\t993:  LayerTypeTLS,       // imaps\n\t994:  LayerTypeTLS,       // ircs\n\t995:  LayerTypeTLS,       // pop3s\n\t5061: LayerTypeTLS,       // ips\n}\n\n// RegisterTCPPortLayerType creates a new mapping between a TCPPort\n// and an underlaying LayerType.\nfunc RegisterTCPPortLayerType(port TCPPort, layerType gopacket.LayerType) {\n\ttcpPortLayerType[port] = layerType\n}\n\n// String returns the port as \"number(name)\" if there's a well-known port name,\n// or just \"number\" if there isn't.  Well-known names are stored in\n// UDPPortNames.\nfunc (a UDPPort) String() string {\n\tif name, ok := UDPPortNames[a]; ok {\n\t\treturn fmt.Sprintf(\"%d(%s)\", a, name)\n\t}\n\treturn strconv.Itoa(int(a))\n}\n\n// LayerType returns a LayerType that would be able to decode the\n// application payload. It uses some well-known ports such as 53 for\n// DNS.\n//\n// Returns gopacket.LayerTypePayload for unknown/unsupported port numbers.\nfunc (a UDPPort) LayerType() gopacket.LayerType {\n\tlt := udpPortLayerType[uint16(a)]\n\tif lt != 0 {\n\t\treturn lt\n\t}\n\treturn gopacket.LayerTypePayload\n}\n\nvar udpPortLayerType = [65536]gopacket.LayerType{\n\t53:   LayerTypeDNS,\n\t123:  LayerTypeNTP,\n\t4789: LayerTypeVXLAN,\n\t67:   LayerTypeDHCPv4,\n\t68:   LayerTypeDHCPv4,\n\t546:  LayerTypeDHCPv6,\n\t547:  LayerTypeDHCPv6,\n\t5060: LayerTypeSIP,\n\t6343: LayerTypeSFlow,\n\t6081: LayerTypeGeneve,\n\t3784: LayerTypeBFD,\n\t2152: LayerTypeGTPv1U,\n\t623:  LayerTypeRMCP,\n\t1812: LayerTypeRADIUS,\n}\n\n// RegisterUDPPortLayerType creates a new mapping between a UDPPort\n// and an underlaying LayerType.\nfunc RegisterUDPPortLayerType(port UDPPort, layerType gopacket.LayerType) {\n\tudpPortLayerType[port] = layerType\n}\n\n// String returns the port as \"number(name)\" if there's a well-known port name,\n// or just \"number\" if there isn't.  Well-known names are stored in\n// RUDPPortNames.\nfunc (a RUDPPort) String() string {\n\tif name, ok := RUDPPortNames[a]; ok {\n\t\treturn fmt.Sprintf(\"%d(%s)\", a, name)\n\t}\n\treturn strconv.Itoa(int(a))\n}\n\n// String returns the port as \"number(name)\" if there's a well-known port name,\n// or just \"number\" if there isn't.  Well-known names are stored in\n// SCTPPortNames.\nfunc (a SCTPPort) String() string {\n\tif name, ok := SCTPPortNames[a]; ok {\n\t\treturn fmt.Sprintf(\"%d(%s)\", a, name)\n\t}\n\treturn strconv.Itoa(int(a))\n}\n\n// String returns the port as \"number(name)\" if there's a well-known port name,\n// or just \"number\" if there isn't.  Well-known names are stored in\n// UDPLitePortNames.\nfunc (a UDPLitePort) String() string {\n\tif name, ok := UDPLitePortNames[a]; ok {\n\t\treturn fmt.Sprintf(\"%d(%s)\", a, name)\n\t}\n\treturn strconv.Itoa(int(a))\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/ppp.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"github.com/google/gopacket\"\n)\n\n// PPP is the layer for PPP encapsulation headers.\ntype PPP struct {\n\tBaseLayer\n\tPPPType       PPPType\n\tHasPPTPHeader bool\n}\n\n// PPPEndpoint is a singleton endpoint for PPP.  Since there is no actual\n// addressing for the two ends of a PPP connection, we use a singleton value\n// named 'point' for each endpoint.\nvar PPPEndpoint = gopacket.NewEndpoint(EndpointPPP, nil)\n\n// PPPFlow is a singleton flow for PPP.  Since there is no actual addressing for\n// the two ends of a PPP connection, we use a singleton value to represent the\n// flow for all PPP connections.\nvar PPPFlow = gopacket.NewFlow(EndpointPPP, nil, nil)\n\n// LayerType returns LayerTypePPP\nfunc (p *PPP) LayerType() gopacket.LayerType { return LayerTypePPP }\n\n// LinkFlow returns PPPFlow.\nfunc (p *PPP) LinkFlow() gopacket.Flow { return PPPFlow }\n\nfunc decodePPP(data []byte, p gopacket.PacketBuilder) error {\n\tppp := &PPP{}\n\toffset := 0\n\tif data[0] == 0xff && data[1] == 0x03 {\n\t\toffset = 2\n\t\tppp.HasPPTPHeader = true\n\t}\n\tif data[offset]&0x1 == 0 {\n\t\tif data[offset+1]&0x1 == 0 {\n\t\t\treturn errors.New(\"PPP has invalid type\")\n\t\t}\n\t\tppp.PPPType = PPPType(binary.BigEndian.Uint16(data[offset : offset+2]))\n\t\tppp.Contents = data[offset : offset+2]\n\t\tppp.Payload = data[offset+2:]\n\t} else {\n\t\tppp.PPPType = PPPType(data[offset])\n\t\tppp.Contents = data[offset : offset+1]\n\t\tppp.Payload = data[offset+1:]\n\t}\n\tp.AddLayer(ppp)\n\tp.SetLinkLayer(ppp)\n\treturn p.NextDecoder(ppp.PPPType)\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (p *PPP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tif p.PPPType&0x100 == 0 {\n\t\tbytes, err := b.PrependBytes(2)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tbinary.BigEndian.PutUint16(bytes, uint16(p.PPPType))\n\t} else {\n\t\tbytes, err := b.PrependBytes(1)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tbytes[0] = uint8(p.PPPType)\n\t}\n\tif p.HasPPTPHeader {\n\t\tbytes, err := b.PrependBytes(2)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tbytes[0] = 0xff\n\t\tbytes[1] = 0x03\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/pppoe.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"github.com/google/gopacket\"\n)\n\n// PPPoE is the layer for PPPoE encapsulation headers.\ntype PPPoE struct {\n\tBaseLayer\n\tVersion   uint8\n\tType      uint8\n\tCode      PPPoECode\n\tSessionId uint16\n\tLength    uint16\n}\n\n// LayerType returns gopacket.LayerTypePPPoE.\nfunc (p *PPPoE) LayerType() gopacket.LayerType {\n\treturn LayerTypePPPoE\n}\n\n// decodePPPoE decodes the PPPoE header (see http://tools.ietf.org/html/rfc2516).\nfunc decodePPPoE(data []byte, p gopacket.PacketBuilder) error {\n\tpppoe := &PPPoE{\n\t\tVersion:   data[0] >> 4,\n\t\tType:      data[0] & 0x0F,\n\t\tCode:      PPPoECode(data[1]),\n\t\tSessionId: binary.BigEndian.Uint16(data[2:4]),\n\t\tLength:    binary.BigEndian.Uint16(data[4:6]),\n\t}\n\tpppoe.BaseLayer = BaseLayer{data[:6], data[6 : 6+pppoe.Length]}\n\tp.AddLayer(pppoe)\n\treturn p.NextDecoder(pppoe.Code)\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (p *PPPoE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tpayload := b.Bytes()\n\tbytes, err := b.PrependBytes(6)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbytes[0] = (p.Version << 4) | p.Type\n\tbytes[1] = byte(p.Code)\n\tbinary.BigEndian.PutUint16(bytes[2:], p.SessionId)\n\tif opts.FixLengths {\n\t\tp.Length = uint16(len(payload))\n\t}\n\tbinary.BigEndian.PutUint16(bytes[4:], p.Length)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/prism.go",
    "content": "// Copyright 2015 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\n// http://www.tcpdump.org/linktypes/LINKTYPE_IEEE802_11_PRISM.html\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\n\t\"github.com/google/gopacket\"\n)\n\nfunc decodePrismValue(data []byte, pv *PrismValue) {\n\tpv.DID = PrismDID(binary.LittleEndian.Uint32(data[0:4]))\n\tpv.Status = binary.LittleEndian.Uint16(data[4:6])\n\tpv.Length = binary.LittleEndian.Uint16(data[6:8])\n\tpv.Data = data[8 : 8+pv.Length]\n}\n\ntype PrismDID uint32\n\nconst (\n\tPrismDIDType1HostTime                  PrismDID = 0x10044\n\tPrismDIDType2HostTime                  PrismDID = 0x01041\n\tPrismDIDType1MACTime                   PrismDID = 0x20044\n\tPrismDIDType2MACTime                   PrismDID = 0x02041\n\tPrismDIDType1Channel                   PrismDID = 0x30044\n\tPrismDIDType2Channel                   PrismDID = 0x03041\n\tPrismDIDType1RSSI                      PrismDID = 0x40044\n\tPrismDIDType2RSSI                      PrismDID = 0x04041\n\tPrismDIDType1SignalQuality             PrismDID = 0x50044\n\tPrismDIDType2SignalQuality             PrismDID = 0x05041\n\tPrismDIDType1Signal                    PrismDID = 0x60044\n\tPrismDIDType2Signal                    PrismDID = 0x06041\n\tPrismDIDType1Noise                     PrismDID = 0x70044\n\tPrismDIDType2Noise                     PrismDID = 0x07041\n\tPrismDIDType1Rate                      PrismDID = 0x80044\n\tPrismDIDType2Rate                      PrismDID = 0x08041\n\tPrismDIDType1TransmittedFrameIndicator PrismDID = 0x90044\n\tPrismDIDType2TransmittedFrameIndicator PrismDID = 0x09041\n\tPrismDIDType1FrameLength               PrismDID = 0xA0044\n\tPrismDIDType2FrameLength               PrismDID = 0x0A041\n)\n\nconst (\n\tPrismType1MessageCode uint16 = 0x00000044\n\tPrismType2MessageCode uint16 = 0x00000041\n)\n\nfunc (p PrismDID) String() string {\n\tdids := map[PrismDID]string{\n\t\tPrismDIDType1HostTime:                  \"Host Time\",\n\t\tPrismDIDType2HostTime:                  \"Host Time\",\n\t\tPrismDIDType1MACTime:                   \"MAC Time\",\n\t\tPrismDIDType2MACTime:                   \"MAC Time\",\n\t\tPrismDIDType1Channel:                   \"Channel\",\n\t\tPrismDIDType2Channel:                   \"Channel\",\n\t\tPrismDIDType1RSSI:                      \"RSSI\",\n\t\tPrismDIDType2RSSI:                      \"RSSI\",\n\t\tPrismDIDType1SignalQuality:             \"Signal Quality\",\n\t\tPrismDIDType2SignalQuality:             \"Signal Quality\",\n\t\tPrismDIDType1Signal:                    \"Signal\",\n\t\tPrismDIDType2Signal:                    \"Signal\",\n\t\tPrismDIDType1Noise:                     \"Noise\",\n\t\tPrismDIDType2Noise:                     \"Noise\",\n\t\tPrismDIDType1Rate:                      \"Rate\",\n\t\tPrismDIDType2Rate:                      \"Rate\",\n\t\tPrismDIDType1TransmittedFrameIndicator: \"Transmitted Frame Indicator\",\n\t\tPrismDIDType2TransmittedFrameIndicator: \"Transmitted Frame Indicator\",\n\t\tPrismDIDType1FrameLength:               \"Frame Length\",\n\t\tPrismDIDType2FrameLength:               \"Frame Length\",\n\t}\n\n\tif str, ok := dids[p]; ok {\n\t\treturn str\n\t}\n\n\treturn \"Unknown DID\"\n}\n\ntype PrismValue struct {\n\tDID    PrismDID\n\tStatus uint16\n\tLength uint16\n\tData   []byte\n}\n\nfunc (pv *PrismValue) IsSupplied() bool {\n\treturn pv.Status == 1\n}\n\nvar ErrPrismExpectedMoreData = errors.New(\"Expected more data.\")\nvar ErrPrismInvalidCode = errors.New(\"Invalid header code.\")\n\nfunc decodePrismHeader(data []byte, p gopacket.PacketBuilder) error {\n\td := &PrismHeader{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\ntype PrismHeader struct {\n\tBaseLayer\n\tCode       uint16\n\tLength     uint16\n\tDeviceName string\n\tValues     []PrismValue\n}\n\nfunc (m *PrismHeader) LayerType() gopacket.LayerType { return LayerTypePrismHeader }\n\nfunc (m *PrismHeader) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tm.Code = binary.LittleEndian.Uint16(data[0:4])\n\tm.Length = binary.LittleEndian.Uint16(data[4:8])\n\tm.DeviceName = string(data[8:24])\n\tm.BaseLayer = BaseLayer{Contents: data[:m.Length], Payload: data[m.Length:len(data)]}\n\n\tswitch m.Code {\n\tcase PrismType1MessageCode:\n\t\tfallthrough\n\tcase PrismType2MessageCode:\n\t\t// valid message code\n\tdefault:\n\t\treturn ErrPrismInvalidCode\n\t}\n\n\toffset := uint16(24)\n\n\tm.Values = make([]PrismValue, (m.Length-offset)/12)\n\tfor i := 0; i < len(m.Values); i++ {\n\t\tdecodePrismValue(data[offset:offset+12], &m.Values[i])\n\t\toffset += 12\n\t}\n\n\tif offset != m.Length {\n\t\treturn ErrPrismExpectedMoreData\n\t}\n\n\treturn nil\n}\n\nfunc (m *PrismHeader) CanDecode() gopacket.LayerClass    { return LayerTypePrismHeader }\nfunc (m *PrismHeader) NextLayerType() gopacket.LayerType { return LayerTypeDot11 }\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/radiotap.go",
    "content": "// Copyright 2014 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"hash/crc32\"\n\t\"strings\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// align calculates the number of bytes needed to align with the width\n// on the offset, returning the number of bytes we need to skip to\n// align to the offset (width).\nfunc align(offset uint16, width uint16) uint16 {\n\treturn ((((offset) + ((width) - 1)) & (^((width) - 1))) - offset)\n}\n\ntype RadioTapPresent uint32\n\nconst (\n\tRadioTapPresentTSFT RadioTapPresent = 1 << iota\n\tRadioTapPresentFlags\n\tRadioTapPresentRate\n\tRadioTapPresentChannel\n\tRadioTapPresentFHSS\n\tRadioTapPresentDBMAntennaSignal\n\tRadioTapPresentDBMAntennaNoise\n\tRadioTapPresentLockQuality\n\tRadioTapPresentTxAttenuation\n\tRadioTapPresentDBTxAttenuation\n\tRadioTapPresentDBMTxPower\n\tRadioTapPresentAntenna\n\tRadioTapPresentDBAntennaSignal\n\tRadioTapPresentDBAntennaNoise\n\tRadioTapPresentRxFlags\n\tRadioTapPresentTxFlags\n\tRadioTapPresentRtsRetries\n\tRadioTapPresentDataRetries\n\t_\n\tRadioTapPresentMCS\n\tRadioTapPresentAMPDUStatus\n\tRadioTapPresentVHT\n\tRadioTapPresentEXT RadioTapPresent = 1 << 31\n)\n\nfunc (r RadioTapPresent) TSFT() bool {\n\treturn r&RadioTapPresentTSFT != 0\n}\nfunc (r RadioTapPresent) Flags() bool {\n\treturn r&RadioTapPresentFlags != 0\n}\nfunc (r RadioTapPresent) Rate() bool {\n\treturn r&RadioTapPresentRate != 0\n}\nfunc (r RadioTapPresent) Channel() bool {\n\treturn r&RadioTapPresentChannel != 0\n}\nfunc (r RadioTapPresent) FHSS() bool {\n\treturn r&RadioTapPresentFHSS != 0\n}\nfunc (r RadioTapPresent) DBMAntennaSignal() bool {\n\treturn r&RadioTapPresentDBMAntennaSignal != 0\n}\nfunc (r RadioTapPresent) DBMAntennaNoise() bool {\n\treturn r&RadioTapPresentDBMAntennaNoise != 0\n}\nfunc (r RadioTapPresent) LockQuality() bool {\n\treturn r&RadioTapPresentLockQuality != 0\n}\nfunc (r RadioTapPresent) TxAttenuation() bool {\n\treturn r&RadioTapPresentTxAttenuation != 0\n}\nfunc (r RadioTapPresent) DBTxAttenuation() bool {\n\treturn r&RadioTapPresentDBTxAttenuation != 0\n}\nfunc (r RadioTapPresent) DBMTxPower() bool {\n\treturn r&RadioTapPresentDBMTxPower != 0\n}\nfunc (r RadioTapPresent) Antenna() bool {\n\treturn r&RadioTapPresentAntenna != 0\n}\nfunc (r RadioTapPresent) DBAntennaSignal() bool {\n\treturn r&RadioTapPresentDBAntennaSignal != 0\n}\nfunc (r RadioTapPresent) DBAntennaNoise() bool {\n\treturn r&RadioTapPresentDBAntennaNoise != 0\n}\nfunc (r RadioTapPresent) RxFlags() bool {\n\treturn r&RadioTapPresentRxFlags != 0\n}\nfunc (r RadioTapPresent) TxFlags() bool {\n\treturn r&RadioTapPresentTxFlags != 0\n}\nfunc (r RadioTapPresent) RtsRetries() bool {\n\treturn r&RadioTapPresentRtsRetries != 0\n}\nfunc (r RadioTapPresent) DataRetries() bool {\n\treturn r&RadioTapPresentDataRetries != 0\n}\nfunc (r RadioTapPresent) MCS() bool {\n\treturn r&RadioTapPresentMCS != 0\n}\nfunc (r RadioTapPresent) AMPDUStatus() bool {\n\treturn r&RadioTapPresentAMPDUStatus != 0\n}\nfunc (r RadioTapPresent) VHT() bool {\n\treturn r&RadioTapPresentVHT != 0\n}\nfunc (r RadioTapPresent) EXT() bool {\n\treturn r&RadioTapPresentEXT != 0\n}\n\ntype RadioTapChannelFlags uint16\n\nconst (\n\tRadioTapChannelFlagsTurbo   RadioTapChannelFlags = 0x0010 // Turbo channel\n\tRadioTapChannelFlagsCCK     RadioTapChannelFlags = 0x0020 // CCK channel\n\tRadioTapChannelFlagsOFDM    RadioTapChannelFlags = 0x0040 // OFDM channel\n\tRadioTapChannelFlagsGhz2    RadioTapChannelFlags = 0x0080 // 2 GHz spectrum channel.\n\tRadioTapChannelFlagsGhz5    RadioTapChannelFlags = 0x0100 // 5 GHz spectrum channel\n\tRadioTapChannelFlagsPassive RadioTapChannelFlags = 0x0200 // Only passive scan allowed\n\tRadioTapChannelFlagsDynamic RadioTapChannelFlags = 0x0400 // Dynamic CCK-OFDM channel\n\tRadioTapChannelFlagsGFSK    RadioTapChannelFlags = 0x0800 // GFSK channel (FHSS PHY)\n)\n\nfunc (r RadioTapChannelFlags) Turbo() bool {\n\treturn r&RadioTapChannelFlagsTurbo != 0\n}\nfunc (r RadioTapChannelFlags) CCK() bool {\n\treturn r&RadioTapChannelFlagsCCK != 0\n}\nfunc (r RadioTapChannelFlags) OFDM() bool {\n\treturn r&RadioTapChannelFlagsOFDM != 0\n}\nfunc (r RadioTapChannelFlags) Ghz2() bool {\n\treturn r&RadioTapChannelFlagsGhz2 != 0\n}\nfunc (r RadioTapChannelFlags) Ghz5() bool {\n\treturn r&RadioTapChannelFlagsGhz5 != 0\n}\nfunc (r RadioTapChannelFlags) Passive() bool {\n\treturn r&RadioTapChannelFlagsPassive != 0\n}\nfunc (r RadioTapChannelFlags) Dynamic() bool {\n\treturn r&RadioTapChannelFlagsDynamic != 0\n}\nfunc (r RadioTapChannelFlags) GFSK() bool {\n\treturn r&RadioTapChannelFlagsGFSK != 0\n}\n\n// String provides a human readable string for RadioTapChannelFlags.\n// This string is possibly subject to change over time; if you're storing this\n// persistently, you should probably store the RadioTapChannelFlags value, not its string.\nfunc (a RadioTapChannelFlags) String() string {\n\tvar out bytes.Buffer\n\tif a.Turbo() {\n\t\tout.WriteString(\"Turbo,\")\n\t}\n\tif a.CCK() {\n\t\tout.WriteString(\"CCK,\")\n\t}\n\tif a.OFDM() {\n\t\tout.WriteString(\"OFDM,\")\n\t}\n\tif a.Ghz2() {\n\t\tout.WriteString(\"Ghz2,\")\n\t}\n\tif a.Ghz5() {\n\t\tout.WriteString(\"Ghz5,\")\n\t}\n\tif a.Passive() {\n\t\tout.WriteString(\"Passive,\")\n\t}\n\tif a.Dynamic() {\n\t\tout.WriteString(\"Dynamic,\")\n\t}\n\tif a.GFSK() {\n\t\tout.WriteString(\"GFSK,\")\n\t}\n\n\tif length := out.Len(); length > 0 {\n\t\treturn string(out.Bytes()[:length-1]) // strip final comma\n\t}\n\treturn \"\"\n}\n\ntype RadioTapFlags uint8\n\nconst (\n\tRadioTapFlagsCFP           RadioTapFlags = 1 << iota // sent/received during CFP\n\tRadioTapFlagsShortPreamble                           // sent/received * with short * preamble\n\tRadioTapFlagsWEP                                     // sent/received * with WEP encryption\n\tRadioTapFlagsFrag                                    // sent/received * with fragmentation\n\tRadioTapFlagsFCS                                     // frame includes FCS\n\tRadioTapFlagsDatapad                                 // frame has padding between * 802.11 header and payload * (to 32-bit boundary)\n\tRadioTapFlagsBadFCS                                  // does not pass FCS check\n\tRadioTapFlagsShortGI                                 // HT short GI\n)\n\nfunc (r RadioTapFlags) CFP() bool {\n\treturn r&RadioTapFlagsCFP != 0\n}\nfunc (r RadioTapFlags) ShortPreamble() bool {\n\treturn r&RadioTapFlagsShortPreamble != 0\n}\nfunc (r RadioTapFlags) WEP() bool {\n\treturn r&RadioTapFlagsWEP != 0\n}\nfunc (r RadioTapFlags) Frag() bool {\n\treturn r&RadioTapFlagsFrag != 0\n}\nfunc (r RadioTapFlags) FCS() bool {\n\treturn r&RadioTapFlagsFCS != 0\n}\nfunc (r RadioTapFlags) Datapad() bool {\n\treturn r&RadioTapFlagsDatapad != 0\n}\nfunc (r RadioTapFlags) BadFCS() bool {\n\treturn r&RadioTapFlagsBadFCS != 0\n}\nfunc (r RadioTapFlags) ShortGI() bool {\n\treturn r&RadioTapFlagsShortGI != 0\n}\n\n// String provides a human readable string for RadioTapFlags.\n// This string is possibly subject to change over time; if you're storing this\n// persistently, you should probably store the RadioTapFlags value, not its string.\nfunc (a RadioTapFlags) String() string {\n\tvar out bytes.Buffer\n\tif a.CFP() {\n\t\tout.WriteString(\"CFP,\")\n\t}\n\tif a.ShortPreamble() {\n\t\tout.WriteString(\"SHORT-PREAMBLE,\")\n\t}\n\tif a.WEP() {\n\t\tout.WriteString(\"WEP,\")\n\t}\n\tif a.Frag() {\n\t\tout.WriteString(\"FRAG,\")\n\t}\n\tif a.FCS() {\n\t\tout.WriteString(\"FCS,\")\n\t}\n\tif a.Datapad() {\n\t\tout.WriteString(\"DATAPAD,\")\n\t}\n\tif a.ShortGI() {\n\t\tout.WriteString(\"SHORT-GI,\")\n\t}\n\n\tif length := out.Len(); length > 0 {\n\t\treturn string(out.Bytes()[:length-1]) // strip final comma\n\t}\n\treturn \"\"\n}\n\ntype RadioTapRate uint8\n\nfunc (a RadioTapRate) String() string {\n\treturn fmt.Sprintf(\"%v Mb/s\", 0.5*float32(a))\n}\n\ntype RadioTapChannelFrequency uint16\n\nfunc (a RadioTapChannelFrequency) String() string {\n\treturn fmt.Sprintf(\"%d MHz\", a)\n}\n\ntype RadioTapRxFlags uint16\n\nconst (\n\tRadioTapRxFlagsBadPlcp RadioTapRxFlags = 0x0002\n)\n\nfunc (self RadioTapRxFlags) BadPlcp() bool {\n\treturn self&RadioTapRxFlagsBadPlcp != 0\n}\n\nfunc (self RadioTapRxFlags) String() string {\n\tif self.BadPlcp() {\n\t\treturn \"BADPLCP\"\n\t}\n\treturn \"\"\n}\n\ntype RadioTapTxFlags uint16\n\nconst (\n\tRadioTapTxFlagsFail RadioTapTxFlags = 1 << iota\n\tRadioTapTxFlagsCTS\n\tRadioTapTxFlagsRTS\n\tRadioTapTxFlagsNoACK\n)\n\nfunc (self RadioTapTxFlags) Fail() bool  { return self&RadioTapTxFlagsFail != 0 }\nfunc (self RadioTapTxFlags) CTS() bool   { return self&RadioTapTxFlagsCTS != 0 }\nfunc (self RadioTapTxFlags) RTS() bool   { return self&RadioTapTxFlagsRTS != 0 }\nfunc (self RadioTapTxFlags) NoACK() bool { return self&RadioTapTxFlagsNoACK != 0 }\n\nfunc (self RadioTapTxFlags) String() string {\n\tvar tokens []string\n\tif self.Fail() {\n\t\ttokens = append(tokens, \"Fail\")\n\t}\n\tif self.CTS() {\n\t\ttokens = append(tokens, \"CTS\")\n\t}\n\tif self.RTS() {\n\t\ttokens = append(tokens, \"RTS\")\n\t}\n\tif self.NoACK() {\n\t\ttokens = append(tokens, \"NoACK\")\n\t}\n\treturn strings.Join(tokens, \",\")\n}\n\ntype RadioTapMCS struct {\n\tKnown RadioTapMCSKnown\n\tFlags RadioTapMCSFlags\n\tMCS   uint8\n}\n\nfunc (self RadioTapMCS) String() string {\n\tvar tokens []string\n\tif self.Known.Bandwidth() {\n\t\ttoken := \"?\"\n\t\tswitch self.Flags.Bandwidth() {\n\t\tcase 0:\n\t\t\ttoken = \"20\"\n\t\tcase 1:\n\t\t\ttoken = \"40\"\n\t\tcase 2:\n\t\t\ttoken = \"40(20L)\"\n\t\tcase 3:\n\t\t\ttoken = \"40(20U)\"\n\t\t}\n\t\ttokens = append(tokens, token)\n\t}\n\tif self.Known.MCSIndex() {\n\t\ttokens = append(tokens, fmt.Sprintf(\"MCSIndex#%d\", self.MCS))\n\t}\n\tif self.Known.GuardInterval() {\n\t\tif self.Flags.ShortGI() {\n\t\t\ttokens = append(tokens, fmt.Sprintf(\"shortGI\"))\n\t\t} else {\n\t\t\ttokens = append(tokens, fmt.Sprintf(\"longGI\"))\n\t\t}\n\t}\n\tif self.Known.HTFormat() {\n\t\tif self.Flags.Greenfield() {\n\t\t\ttokens = append(tokens, fmt.Sprintf(\"HT-greenfield\"))\n\t\t} else {\n\t\t\ttokens = append(tokens, fmt.Sprintf(\"HT-mixed\"))\n\t\t}\n\t}\n\tif self.Known.FECType() {\n\t\tif self.Flags.FECLDPC() {\n\t\t\ttokens = append(tokens, fmt.Sprintf(\"LDPC\"))\n\t\t} else {\n\t\t\ttokens = append(tokens, fmt.Sprintf(\"BCC\"))\n\t\t}\n\t}\n\tif self.Known.STBC() {\n\t\ttokens = append(tokens, fmt.Sprintf(\"STBC#%d\", self.Flags.STBC()))\n\t}\n\tif self.Known.NESS() {\n\t\tnum := 0\n\t\tif self.Known.NESS1() {\n\t\t\tnum |= 0x02\n\t\t}\n\t\tif self.Flags.NESS0() {\n\t\t\tnum |= 0x01\n\t\t}\n\t\ttokens = append(tokens, fmt.Sprintf(\"num-of-ESS#%d\", num))\n\t}\n\treturn strings.Join(tokens, \",\")\n}\n\ntype RadioTapMCSKnown uint8\n\nconst (\n\tRadioTapMCSKnownBandwidth RadioTapMCSKnown = 1 << iota\n\tRadioTapMCSKnownMCSIndex\n\tRadioTapMCSKnownGuardInterval\n\tRadioTapMCSKnownHTFormat\n\tRadioTapMCSKnownFECType\n\tRadioTapMCSKnownSTBC\n\tRadioTapMCSKnownNESS\n\tRadioTapMCSKnownNESS1\n)\n\nfunc (self RadioTapMCSKnown) Bandwidth() bool     { return self&RadioTapMCSKnownBandwidth != 0 }\nfunc (self RadioTapMCSKnown) MCSIndex() bool      { return self&RadioTapMCSKnownMCSIndex != 0 }\nfunc (self RadioTapMCSKnown) GuardInterval() bool { return self&RadioTapMCSKnownGuardInterval != 0 }\nfunc (self RadioTapMCSKnown) HTFormat() bool      { return self&RadioTapMCSKnownHTFormat != 0 }\nfunc (self RadioTapMCSKnown) FECType() bool       { return self&RadioTapMCSKnownFECType != 0 }\nfunc (self RadioTapMCSKnown) STBC() bool          { return self&RadioTapMCSKnownSTBC != 0 }\nfunc (self RadioTapMCSKnown) NESS() bool          { return self&RadioTapMCSKnownNESS != 0 }\nfunc (self RadioTapMCSKnown) NESS1() bool         { return self&RadioTapMCSKnownNESS1 != 0 }\n\ntype RadioTapMCSFlags uint8\n\nconst (\n\tRadioTapMCSFlagsBandwidthMask RadioTapMCSFlags = 0x03\n\tRadioTapMCSFlagsShortGI                        = 0x04\n\tRadioTapMCSFlagsGreenfield                     = 0x08\n\tRadioTapMCSFlagsFECLDPC                        = 0x10\n\tRadioTapMCSFlagsSTBCMask                       = 0x60\n\tRadioTapMCSFlagsNESS0                          = 0x80\n)\n\nfunc (self RadioTapMCSFlags) Bandwidth() int {\n\treturn int(self & RadioTapMCSFlagsBandwidthMask)\n}\nfunc (self RadioTapMCSFlags) ShortGI() bool    { return self&RadioTapMCSFlagsShortGI != 0 }\nfunc (self RadioTapMCSFlags) Greenfield() bool { return self&RadioTapMCSFlagsGreenfield != 0 }\nfunc (self RadioTapMCSFlags) FECLDPC() bool    { return self&RadioTapMCSFlagsFECLDPC != 0 }\nfunc (self RadioTapMCSFlags) STBC() int {\n\treturn int(self&RadioTapMCSFlagsSTBCMask) >> 5\n}\nfunc (self RadioTapMCSFlags) NESS0() bool { return self&RadioTapMCSFlagsNESS0 != 0 }\n\ntype RadioTapAMPDUStatus struct {\n\tReference uint32\n\tFlags     RadioTapAMPDUStatusFlags\n\tCRC       uint8\n}\n\nfunc (self RadioTapAMPDUStatus) String() string {\n\ttokens := []string{\n\t\tfmt.Sprintf(\"ref#%x\", self.Reference),\n\t}\n\tif self.Flags.ReportZerolen() && self.Flags.IsZerolen() {\n\t\ttokens = append(tokens, fmt.Sprintf(\"zero-length\"))\n\t}\n\tif self.Flags.LastKnown() && self.Flags.IsLast() {\n\t\ttokens = append(tokens, \"last\")\n\t}\n\tif self.Flags.DelimCRCErr() {\n\t\ttokens = append(tokens, \"delimiter CRC error\")\n\t}\n\tif self.Flags.DelimCRCKnown() {\n\t\ttokens = append(tokens, fmt.Sprintf(\"delimiter-CRC=%02x\", self.CRC))\n\t}\n\treturn strings.Join(tokens, \",\")\n}\n\ntype RadioTapAMPDUStatusFlags uint16\n\nconst (\n\tRadioTapAMPDUStatusFlagsReportZerolen RadioTapAMPDUStatusFlags = 1 << iota\n\tRadioTapAMPDUIsZerolen\n\tRadioTapAMPDULastKnown\n\tRadioTapAMPDUIsLast\n\tRadioTapAMPDUDelimCRCErr\n\tRadioTapAMPDUDelimCRCKnown\n)\n\nfunc (self RadioTapAMPDUStatusFlags) ReportZerolen() bool {\n\treturn self&RadioTapAMPDUStatusFlagsReportZerolen != 0\n}\nfunc (self RadioTapAMPDUStatusFlags) IsZerolen() bool   { return self&RadioTapAMPDUIsZerolen != 0 }\nfunc (self RadioTapAMPDUStatusFlags) LastKnown() bool   { return self&RadioTapAMPDULastKnown != 0 }\nfunc (self RadioTapAMPDUStatusFlags) IsLast() bool      { return self&RadioTapAMPDUIsLast != 0 }\nfunc (self RadioTapAMPDUStatusFlags) DelimCRCErr() bool { return self&RadioTapAMPDUDelimCRCErr != 0 }\nfunc (self RadioTapAMPDUStatusFlags) DelimCRCKnown() bool {\n\treturn self&RadioTapAMPDUDelimCRCKnown != 0\n}\n\ntype RadioTapVHT struct {\n\tKnown      RadioTapVHTKnown\n\tFlags      RadioTapVHTFlags\n\tBandwidth  uint8\n\tMCSNSS     [4]RadioTapVHTMCSNSS\n\tCoding     uint8\n\tGroupId    uint8\n\tPartialAID uint16\n}\n\nfunc (self RadioTapVHT) String() string {\n\tvar tokens []string\n\tif self.Known.STBC() {\n\t\tif self.Flags.STBC() {\n\t\t\ttokens = append(tokens, \"STBC\")\n\t\t} else {\n\t\t\ttokens = append(tokens, \"no STBC\")\n\t\t}\n\t}\n\tif self.Known.TXOPPSNotAllowed() {\n\t\tif self.Flags.TXOPPSNotAllowed() {\n\t\t\ttokens = append(tokens, \"TXOP doze not allowed\")\n\t\t} else {\n\t\t\ttokens = append(tokens, \"TXOP doze allowed\")\n\t\t}\n\t}\n\tif self.Known.GI() {\n\t\tif self.Flags.SGI() {\n\t\t\ttokens = append(tokens, \"short GI\")\n\t\t} else {\n\t\t\ttokens = append(tokens, \"long GI\")\n\t\t}\n\t}\n\tif self.Known.SGINSYMDisambiguation() {\n\t\tif self.Flags.SGINSYMMod() {\n\t\t\ttokens = append(tokens, \"NSYM mod 10=9\")\n\t\t} else {\n\t\t\ttokens = append(tokens, \"NSYM mod 10!=9 or no short GI\")\n\t\t}\n\t}\n\tif self.Known.LDPCExtraOFDMSymbol() {\n\t\tif self.Flags.LDPCExtraOFDMSymbol() {\n\t\t\ttokens = append(tokens, \"LDPC extra OFDM symbols\")\n\t\t} else {\n\t\t\ttokens = append(tokens, \"no LDPC extra OFDM symbols\")\n\t\t}\n\t}\n\tif self.Known.Beamformed() {\n\t\tif self.Flags.Beamformed() {\n\t\t\ttokens = append(tokens, \"beamformed\")\n\t\t} else {\n\t\t\ttokens = append(tokens, \"no beamformed\")\n\t\t}\n\t}\n\tif self.Known.Bandwidth() {\n\t\ttoken := \"?\"\n\t\tswitch self.Bandwidth & 0x1f {\n\t\tcase 0:\n\t\t\ttoken = \"20\"\n\t\tcase 1:\n\t\t\ttoken = \"40\"\n\t\tcase 2:\n\t\t\ttoken = \"40(20L)\"\n\t\tcase 3:\n\t\t\ttoken = \"40(20U)\"\n\t\tcase 4:\n\t\t\ttoken = \"80\"\n\t\tcase 5:\n\t\t\ttoken = \"80(40L)\"\n\t\tcase 6:\n\t\t\ttoken = \"80(40U)\"\n\t\tcase 7:\n\t\t\ttoken = \"80(20LL)\"\n\t\tcase 8:\n\t\t\ttoken = \"80(20LU)\"\n\t\tcase 9:\n\t\t\ttoken = \"80(20UL)\"\n\t\tcase 10:\n\t\t\ttoken = \"80(20UU)\"\n\t\tcase 11:\n\t\t\ttoken = \"160\"\n\t\tcase 12:\n\t\t\ttoken = \"160(80L)\"\n\t\tcase 13:\n\t\t\ttoken = \"160(80U)\"\n\t\tcase 14:\n\t\t\ttoken = \"160(40LL)\"\n\t\tcase 15:\n\t\t\ttoken = \"160(40LU)\"\n\t\tcase 16:\n\t\t\ttoken = \"160(40UL)\"\n\t\tcase 17:\n\t\t\ttoken = \"160(40UU)\"\n\t\tcase 18:\n\t\t\ttoken = \"160(20LLL)\"\n\t\tcase 19:\n\t\t\ttoken = \"160(20LLU)\"\n\t\tcase 20:\n\t\t\ttoken = \"160(20LUL)\"\n\t\tcase 21:\n\t\t\ttoken = \"160(20LUU)\"\n\t\tcase 22:\n\t\t\ttoken = \"160(20ULL)\"\n\t\tcase 23:\n\t\t\ttoken = \"160(20ULU)\"\n\t\tcase 24:\n\t\t\ttoken = \"160(20UUL)\"\n\t\tcase 25:\n\t\t\ttoken = \"160(20UUU)\"\n\t\t}\n\t\ttokens = append(tokens, token)\n\t}\n\tfor i, MCSNSS := range self.MCSNSS {\n\t\tif MCSNSS.Present() {\n\t\t\tfec := \"?\"\n\t\t\tswitch self.Coding & (1 << uint8(i)) {\n\t\t\tcase 0:\n\t\t\t\tfec = \"BCC\"\n\t\t\tcase 1:\n\t\t\t\tfec = \"LDPC\"\n\t\t\t}\n\t\t\ttokens = append(tokens, fmt.Sprintf(\"user%d(%s,%s)\", i, MCSNSS.String(), fec))\n\t\t}\n\t}\n\tif self.Known.GroupId() {\n\t\ttokens = append(tokens,\n\t\t\tfmt.Sprintf(\"group=%d\", self.GroupId))\n\t}\n\tif self.Known.PartialAID() {\n\t\ttokens = append(tokens,\n\t\t\tfmt.Sprintf(\"partial-AID=%d\", self.PartialAID))\n\t}\n\treturn strings.Join(tokens, \",\")\n}\n\ntype RadioTapVHTKnown uint16\n\nconst (\n\tRadioTapVHTKnownSTBC RadioTapVHTKnown = 1 << iota\n\tRadioTapVHTKnownTXOPPSNotAllowed\n\tRadioTapVHTKnownGI\n\tRadioTapVHTKnownSGINSYMDisambiguation\n\tRadioTapVHTKnownLDPCExtraOFDMSymbol\n\tRadioTapVHTKnownBeamformed\n\tRadioTapVHTKnownBandwidth\n\tRadioTapVHTKnownGroupId\n\tRadioTapVHTKnownPartialAID\n)\n\nfunc (self RadioTapVHTKnown) STBC() bool { return self&RadioTapVHTKnownSTBC != 0 }\nfunc (self RadioTapVHTKnown) TXOPPSNotAllowed() bool {\n\treturn self&RadioTapVHTKnownTXOPPSNotAllowed != 0\n}\nfunc (self RadioTapVHTKnown) GI() bool { return self&RadioTapVHTKnownGI != 0 }\nfunc (self RadioTapVHTKnown) SGINSYMDisambiguation() bool {\n\treturn self&RadioTapVHTKnownSGINSYMDisambiguation != 0\n}\nfunc (self RadioTapVHTKnown) LDPCExtraOFDMSymbol() bool {\n\treturn self&RadioTapVHTKnownLDPCExtraOFDMSymbol != 0\n}\nfunc (self RadioTapVHTKnown) Beamformed() bool { return self&RadioTapVHTKnownBeamformed != 0 }\nfunc (self RadioTapVHTKnown) Bandwidth() bool  { return self&RadioTapVHTKnownBandwidth != 0 }\nfunc (self RadioTapVHTKnown) GroupId() bool    { return self&RadioTapVHTKnownGroupId != 0 }\nfunc (self RadioTapVHTKnown) PartialAID() bool { return self&RadioTapVHTKnownPartialAID != 0 }\n\ntype RadioTapVHTFlags uint8\n\nconst (\n\tRadioTapVHTFlagsSTBC RadioTapVHTFlags = 1 << iota\n\tRadioTapVHTFlagsTXOPPSNotAllowed\n\tRadioTapVHTFlagsSGI\n\tRadioTapVHTFlagsSGINSYMMod\n\tRadioTapVHTFlagsLDPCExtraOFDMSymbol\n\tRadioTapVHTFlagsBeamformed\n)\n\nfunc (self RadioTapVHTFlags) STBC() bool { return self&RadioTapVHTFlagsSTBC != 0 }\nfunc (self RadioTapVHTFlags) TXOPPSNotAllowed() bool {\n\treturn self&RadioTapVHTFlagsTXOPPSNotAllowed != 0\n}\nfunc (self RadioTapVHTFlags) SGI() bool        { return self&RadioTapVHTFlagsSGI != 0 }\nfunc (self RadioTapVHTFlags) SGINSYMMod() bool { return self&RadioTapVHTFlagsSGINSYMMod != 0 }\nfunc (self RadioTapVHTFlags) LDPCExtraOFDMSymbol() bool {\n\treturn self&RadioTapVHTFlagsLDPCExtraOFDMSymbol != 0\n}\nfunc (self RadioTapVHTFlags) Beamformed() bool { return self&RadioTapVHTFlagsBeamformed != 0 }\n\ntype RadioTapVHTMCSNSS uint8\n\nfunc (self RadioTapVHTMCSNSS) Present() bool {\n\treturn self&0x0F != 0\n}\n\nfunc (self RadioTapVHTMCSNSS) String() string {\n\treturn fmt.Sprintf(\"NSS#%dMCS#%d\", uint32(self&0xf), uint32(self>>4))\n}\n\nfunc decodeRadioTap(data []byte, p gopacket.PacketBuilder) error {\n\td := &RadioTap{}\n\t// TODO: Should we set LinkLayer here? And implement LinkFlow\n\treturn decodingLayerDecoder(d, data, p)\n}\n\ntype RadioTap struct {\n\tBaseLayer\n\n\t// Version 0. Only increases for drastic changes, introduction of compatible new fields does not count.\n\tVersion uint8\n\t// Length of the whole header in bytes, including it_version, it_pad, it_len, and data fields.\n\tLength uint16\n\t// Present is a bitmap telling which fields are present. Set bit 31 (0x80000000) to extend the bitmap by another 32 bits. Additional extensions are made by setting bit 31.\n\tPresent RadioTapPresent\n\t// TSFT: value in microseconds of the MAC's 64-bit 802.11 Time Synchronization Function timer when the first bit of the MPDU arrived at the MAC. For received frames, only.\n\tTSFT  uint64\n\tFlags RadioTapFlags\n\t// Rate Tx/Rx data rate\n\tRate RadioTapRate\n\t// ChannelFrequency Tx/Rx frequency in MHz, followed by flags\n\tChannelFrequency RadioTapChannelFrequency\n\tChannelFlags     RadioTapChannelFlags\n\t// FHSS For frequency-hopping radios, the hop set (first byte) and pattern (second byte).\n\tFHSS uint16\n\t// DBMAntennaSignal RF signal power at the antenna, decibel difference from one milliwatt.\n\tDBMAntennaSignal int8\n\t// DBMAntennaNoise RF noise power at the antenna, decibel difference from one milliwatt.\n\tDBMAntennaNoise int8\n\t// LockQuality Quality of Barker code lock. Unitless. Monotonically nondecreasing with \"better\" lock strength. Called \"Signal Quality\" in datasheets.\n\tLockQuality uint16\n\t// TxAttenuation Transmit power expressed as unitless distance from max power set at factory calibration.  0 is max power. Monotonically nondecreasing with lower power levels.\n\tTxAttenuation uint16\n\t// DBTxAttenuation Transmit power expressed as decibel distance from max power set at factory calibration.  0 is max power.  Monotonically nondecreasing with lower power levels.\n\tDBTxAttenuation uint16\n\t// DBMTxPower Transmit power expressed as dBm (decibels from a 1 milliwatt reference). This is the absolute power level measured at the antenna port.\n\tDBMTxPower int8\n\t// Antenna Unitless indication of the Rx/Tx antenna for this packet. The first antenna is antenna 0.\n\tAntenna uint8\n\t// DBAntennaSignal RF signal power at the antenna, decibel difference from an arbitrary, fixed reference.\n\tDBAntennaSignal uint8\n\t// DBAntennaNoise RF noise power at the antenna, decibel difference from an arbitrary, fixed reference point.\n\tDBAntennaNoise uint8\n\t//\n\tRxFlags     RadioTapRxFlags\n\tTxFlags     RadioTapTxFlags\n\tRtsRetries  uint8\n\tDataRetries uint8\n\tMCS         RadioTapMCS\n\tAMPDUStatus RadioTapAMPDUStatus\n\tVHT         RadioTapVHT\n}\n\nfunc (m *RadioTap) LayerType() gopacket.LayerType { return LayerTypeRadioTap }\n\nfunc (m *RadioTap) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 8 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"RadioTap too small\")\n\t}\n\tm.Version = uint8(data[0])\n\tm.Length = binary.LittleEndian.Uint16(data[2:4])\n\tm.Present = RadioTapPresent(binary.LittleEndian.Uint32(data[4:8]))\n\n\toffset := uint16(4)\n\n\tfor (binary.LittleEndian.Uint32(data[offset:offset+4]) & 0x80000000) != 0 {\n\t\t// This parser only handles standard radiotap namespace,\n\t\t// and expects all fields are packed in the first it_present.\n\t\t// Extended bitmap will be just ignored.\n\t\toffset += 4\n\t}\n\toffset += 4 // skip the bitmap\n\n\tif m.Present.TSFT() {\n\t\toffset += align(offset, 8)\n\t\tm.TSFT = binary.LittleEndian.Uint64(data[offset : offset+8])\n\t\toffset += 8\n\t}\n\tif m.Present.Flags() {\n\t\tm.Flags = RadioTapFlags(data[offset])\n\t\toffset++\n\t}\n\tif m.Present.Rate() {\n\t\tm.Rate = RadioTapRate(data[offset])\n\t\toffset++\n\t}\n\tif m.Present.Channel() {\n\t\toffset += align(offset, 2)\n\t\tm.ChannelFrequency = RadioTapChannelFrequency(binary.LittleEndian.Uint16(data[offset : offset+2]))\n\t\toffset += 2\n\t\tm.ChannelFlags = RadioTapChannelFlags(binary.LittleEndian.Uint16(data[offset : offset+2]))\n\t\toffset += 2\n\t}\n\tif m.Present.FHSS() {\n\t\tm.FHSS = binary.LittleEndian.Uint16(data[offset : offset+2])\n\t\toffset += 2\n\t}\n\tif m.Present.DBMAntennaSignal() {\n\t\tm.DBMAntennaSignal = int8(data[offset])\n\t\toffset++\n\t}\n\tif m.Present.DBMAntennaNoise() {\n\t\tm.DBMAntennaNoise = int8(data[offset])\n\t\toffset++\n\t}\n\tif m.Present.LockQuality() {\n\t\toffset += align(offset, 2)\n\t\tm.LockQuality = binary.LittleEndian.Uint16(data[offset : offset+2])\n\t\toffset += 2\n\t}\n\tif m.Present.TxAttenuation() {\n\t\toffset += align(offset, 2)\n\t\tm.TxAttenuation = binary.LittleEndian.Uint16(data[offset : offset+2])\n\t\toffset += 2\n\t}\n\tif m.Present.DBTxAttenuation() {\n\t\toffset += align(offset, 2)\n\t\tm.DBTxAttenuation = binary.LittleEndian.Uint16(data[offset : offset+2])\n\t\toffset += 2\n\t}\n\tif m.Present.DBMTxPower() {\n\t\tm.DBMTxPower = int8(data[offset])\n\t\toffset++\n\t}\n\tif m.Present.Antenna() {\n\t\tm.Antenna = uint8(data[offset])\n\t\toffset++\n\t}\n\tif m.Present.DBAntennaSignal() {\n\t\tm.DBAntennaSignal = uint8(data[offset])\n\t\toffset++\n\t}\n\tif m.Present.DBAntennaNoise() {\n\t\tm.DBAntennaNoise = uint8(data[offset])\n\t\toffset++\n\t}\n\tif m.Present.RxFlags() {\n\t\toffset += align(offset, 2)\n\t\tm.RxFlags = RadioTapRxFlags(binary.LittleEndian.Uint16(data[offset:]))\n\t\toffset += 2\n\t}\n\tif m.Present.TxFlags() {\n\t\toffset += align(offset, 2)\n\t\tm.TxFlags = RadioTapTxFlags(binary.LittleEndian.Uint16(data[offset:]))\n\t\toffset += 2\n\t}\n\tif m.Present.RtsRetries() {\n\t\tm.RtsRetries = uint8(data[offset])\n\t\toffset++\n\t}\n\tif m.Present.DataRetries() {\n\t\tm.DataRetries = uint8(data[offset])\n\t\toffset++\n\t}\n\tif m.Present.MCS() {\n\t\tm.MCS = RadioTapMCS{\n\t\t\tRadioTapMCSKnown(data[offset]),\n\t\t\tRadioTapMCSFlags(data[offset+1]),\n\t\t\tuint8(data[offset+2]),\n\t\t}\n\t\toffset += 3\n\t}\n\tif m.Present.AMPDUStatus() {\n\t\toffset += align(offset, 4)\n\t\tm.AMPDUStatus = RadioTapAMPDUStatus{\n\t\t\tReference: binary.LittleEndian.Uint32(data[offset:]),\n\t\t\tFlags:     RadioTapAMPDUStatusFlags(binary.LittleEndian.Uint16(data[offset+4:])),\n\t\t\tCRC:       uint8(data[offset+6]),\n\t\t}\n\t\toffset += 8\n\t}\n\tif m.Present.VHT() {\n\t\toffset += align(offset, 2)\n\t\tm.VHT = RadioTapVHT{\n\t\t\tKnown:     RadioTapVHTKnown(binary.LittleEndian.Uint16(data[offset:])),\n\t\t\tFlags:     RadioTapVHTFlags(data[offset+2]),\n\t\t\tBandwidth: uint8(data[offset+3]),\n\t\t\tMCSNSS: [4]RadioTapVHTMCSNSS{\n\t\t\t\tRadioTapVHTMCSNSS(data[offset+4]),\n\t\t\t\tRadioTapVHTMCSNSS(data[offset+5]),\n\t\t\t\tRadioTapVHTMCSNSS(data[offset+6]),\n\t\t\t\tRadioTapVHTMCSNSS(data[offset+7]),\n\t\t\t},\n\t\t\tCoding:     uint8(data[offset+8]),\n\t\t\tGroupId:    uint8(data[offset+9]),\n\t\t\tPartialAID: binary.LittleEndian.Uint16(data[offset+10:]),\n\t\t}\n\t\toffset += 12\n\t}\n\n\tpayload := data[m.Length:]\n\n\t// Remove non standard padding used by some Wi-Fi drivers\n\tif m.Flags.Datapad() &&\n\t\tpayload[0]&0xC == 0x8 { //&& // Data frame\n\t\theadlen := 24\n\t\tif payload[0]&0x8C == 0x88 { // QoS\n\t\t\theadlen += 2\n\t\t}\n\t\tif payload[1]&0x3 == 0x3 { // 4 addresses\n\t\t\theadlen += 2\n\t\t}\n\t\tif headlen%4 == 2 {\n\t\t\tpayload = append(payload[:headlen], payload[headlen+2:len(payload)]...)\n\t\t}\n\t}\n\n\tif !m.Flags.FCS() {\n\t\t// Dot11.DecodeFromBytes() expects FCS present and performs a hard chop on the checksum\n\t\t// If a user is handing in subslices or packets from a buffered stream, the capacity of the slice\n\t\t// may extend beyond the len, rather than expecting callers to enforce cap==len on every packet\n\t\t// we take the hit in this one case and do a reallocation.  If the user DOES enforce cap==len\n\t\t// then the reallocation will happen anyway on the append.  This is requried because the append\n\t\t// write to the memory directly after the payload if there is sufficient capacity, which callers\n\t\t// may not expect.\n\t\treallocPayload := make([]byte, len(payload)+4)\n\t\tcopy(reallocPayload[0:len(payload)], payload)\n\t\th := crc32.NewIEEE()\n\t\th.Write(payload)\n\t\tbinary.LittleEndian.PutUint32(reallocPayload[len(payload):], h.Sum32())\n\t\tpayload = reallocPayload\n\t}\n\tm.BaseLayer = BaseLayer{Contents: data[:m.Length], Payload: payload}\n\n\treturn nil\n}\n\nfunc (m RadioTap) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbuf := make([]byte, 1024)\n\n\tbuf[0] = m.Version\n\tbuf[1] = 0\n\n\tbinary.LittleEndian.PutUint32(buf[4:8], uint32(m.Present))\n\n\toffset := uint16(4)\n\n\tfor (binary.LittleEndian.Uint32(buf[offset:offset+4]) & 0x80000000) != 0 {\n\t\toffset += 4\n\t}\n\n\toffset += 4\n\n\tif m.Present.TSFT() {\n\t\toffset += align(offset, 8)\n\t\tbinary.LittleEndian.PutUint64(buf[offset:offset+8], m.TSFT)\n\t\toffset += 8\n\t}\n\n\tif m.Present.Flags() {\n\t\tbuf[offset] = uint8(m.Flags)\n\t\toffset++\n\t}\n\n\tif m.Present.Rate() {\n\t\tbuf[offset] = uint8(m.Rate)\n\t\toffset++\n\t}\n\n\tif m.Present.Channel() {\n\t\toffset += align(offset, 2)\n\t\tbinary.LittleEndian.PutUint16(buf[offset:offset+2], uint16(m.ChannelFrequency))\n\t\toffset += 2\n\t\tbinary.LittleEndian.PutUint16(buf[offset:offset+2], uint16(m.ChannelFlags))\n\t\toffset += 2\n\t}\n\n\tif m.Present.FHSS() {\n\t\tbinary.LittleEndian.PutUint16(buf[offset:offset+2], m.FHSS)\n\t\toffset += 2\n\t}\n\n\tif m.Present.DBMAntennaSignal() {\n\t\tbuf[offset] = byte(m.DBMAntennaSignal)\n\t\toffset++\n\t}\n\n\tif m.Present.DBMAntennaNoise() {\n\t\tbuf[offset] = byte(m.DBMAntennaNoise)\n\t\toffset++\n\t}\n\n\tif m.Present.LockQuality() {\n\t\toffset += align(offset, 2)\n\t\tbinary.LittleEndian.PutUint16(buf[offset:offset+2], m.LockQuality)\n\t\toffset += 2\n\t}\n\n\tif m.Present.TxAttenuation() {\n\t\toffset += align(offset, 2)\n\t\tbinary.LittleEndian.PutUint16(buf[offset:offset+2], m.TxAttenuation)\n\t\toffset += 2\n\t}\n\n\tif m.Present.DBTxAttenuation() {\n\t\toffset += align(offset, 2)\n\t\tbinary.LittleEndian.PutUint16(buf[offset:offset+2], m.DBTxAttenuation)\n\t\toffset += 2\n\t}\n\n\tif m.Present.DBMTxPower() {\n\t\tbuf[offset] = byte(m.DBMTxPower)\n\t\toffset++\n\t}\n\n\tif m.Present.Antenna() {\n\t\tbuf[offset] = uint8(m.Antenna)\n\t\toffset++\n\t}\n\n\tif m.Present.DBAntennaSignal() {\n\t\tbuf[offset] = uint8(m.DBAntennaSignal)\n\t\toffset++\n\t}\n\n\tif m.Present.DBAntennaNoise() {\n\t\tbuf[offset] = uint8(m.DBAntennaNoise)\n\t\toffset++\n\t}\n\n\tif m.Present.RxFlags() {\n\t\toffset += align(offset, 2)\n\t\tbinary.LittleEndian.PutUint16(buf[offset:offset+2], uint16(m.RxFlags))\n\t\toffset += 2\n\t}\n\n\tif m.Present.TxFlags() {\n\t\toffset += align(offset, 2)\n\t\tbinary.LittleEndian.PutUint16(buf[offset:offset+2], uint16(m.TxFlags))\n\t\toffset += 2\n\t}\n\n\tif m.Present.RtsRetries() {\n\t\tbuf[offset] = m.RtsRetries\n\t\toffset++\n\t}\n\n\tif m.Present.DataRetries() {\n\t\tbuf[offset] = m.DataRetries\n\t\toffset++\n\t}\n\n\tif m.Present.MCS() {\n\t\tbuf[offset] = uint8(m.MCS.Known)\n\t\tbuf[offset+1] = uint8(m.MCS.Flags)\n\t\tbuf[offset+2] = uint8(m.MCS.MCS)\n\n\t\toffset += 3\n\t}\n\n\tif m.Present.AMPDUStatus() {\n\t\toffset += align(offset, 4)\n\n\t\tbinary.LittleEndian.PutUint32(buf[offset:offset+4], m.AMPDUStatus.Reference)\n\t\tbinary.LittleEndian.PutUint16(buf[offset+4:offset+6], uint16(m.AMPDUStatus.Flags))\n\n\t\tbuf[offset+6] = m.AMPDUStatus.CRC\n\n\t\toffset += 8\n\t}\n\n\tif m.Present.VHT() {\n\t\toffset += align(offset, 2)\n\n\t\tbinary.LittleEndian.PutUint16(buf[offset:], uint16(m.VHT.Known))\n\n\t\tbuf[offset+2] = uint8(m.VHT.Flags)\n\t\tbuf[offset+3] = uint8(m.VHT.Bandwidth)\n\t\tbuf[offset+4] = uint8(m.VHT.MCSNSS[0])\n\t\tbuf[offset+5] = uint8(m.VHT.MCSNSS[1])\n\t\tbuf[offset+6] = uint8(m.VHT.MCSNSS[2])\n\t\tbuf[offset+7] = uint8(m.VHT.MCSNSS[3])\n\t\tbuf[offset+8] = uint8(m.VHT.Coding)\n\t\tbuf[offset+9] = uint8(m.VHT.GroupId)\n\n\t\tbinary.LittleEndian.PutUint16(buf[offset+10:offset+12], m.VHT.PartialAID)\n\n\t\toffset += 12\n\t}\n\n\tpacketBuf, err := b.PrependBytes(int(offset))\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif opts.FixLengths {\n\t\tm.Length = offset\n\t}\n\n\tbinary.LittleEndian.PutUint16(buf[2:4], m.Length)\n\n\tcopy(packetBuf, buf)\n\n\treturn nil\n}\n\nfunc (m *RadioTap) CanDecode() gopacket.LayerClass    { return LayerTypeRadioTap }\nfunc (m *RadioTap) NextLayerType() gopacket.LayerType { return LayerTypeDot11 }\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/radius.go",
    "content": "// Copyright 2020 The GoPacket Authors. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license that can be found\n// in the LICENSE file in the root of the source tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\n\t\"github.com/google/gopacket\"\n)\n\nconst (\n\t// RFC 2865 3.  Packet Format\n\t// `The minimum length is 20 and maximum length is 4096.`\n\tradiusMinimumRecordSizeInBytes int = 20\n\tradiusMaximumRecordSizeInBytes int = 4096\n\n\t// RFC 2865 5.  Attributes\n\t// `The Length field is one octet, and indicates the length of this Attribute including the Type, Length and Value fields.`\n\t// `The Value field is zero or more octets and contains information specific to the Attribute.`\n\tradiusAttributesMinimumRecordSizeInBytes int = 2\n)\n\n// RADIUS represents a Remote Authentication Dial In User Service layer.\ntype RADIUS struct {\n\tBaseLayer\n\n\tCode          RADIUSCode\n\tIdentifier    RADIUSIdentifier\n\tLength        RADIUSLength\n\tAuthenticator RADIUSAuthenticator\n\tAttributes    []RADIUSAttribute\n}\n\n// RADIUSCode represents packet type.\ntype RADIUSCode uint8\n\n// constants that define RADIUSCode.\nconst (\n\tRADIUSCodeAccessRequest      RADIUSCode = 1   // RFC2865 3.  Packet Format\n\tRADIUSCodeAccessAccept       RADIUSCode = 2   // RFC2865 3.  Packet Format\n\tRADIUSCodeAccessReject       RADIUSCode = 3   // RFC2865 3.  Packet Format\n\tRADIUSCodeAccountingRequest  RADIUSCode = 4   // RFC2865 3.  Packet Format\n\tRADIUSCodeAccountingResponse RADIUSCode = 5   // RFC2865 3.  Packet Format\n\tRADIUSCodeAccessChallenge    RADIUSCode = 11  // RFC2865 3.  Packet Format\n\tRADIUSCodeStatusServer       RADIUSCode = 12  // RFC2865 3.  Packet Format (experimental)\n\tRADIUSCodeStatusClient       RADIUSCode = 13  // RFC2865 3.  Packet Format (experimental)\n\tRADIUSCodeReserved           RADIUSCode = 255 // RFC2865 3.  Packet Format\n)\n\n// String returns a string version of a RADIUSCode.\nfunc (t RADIUSCode) String() (s string) {\n\tswitch t {\n\tcase RADIUSCodeAccessRequest:\n\t\ts = \"Access-Request\"\n\tcase RADIUSCodeAccessAccept:\n\t\ts = \"Access-Accept\"\n\tcase RADIUSCodeAccessReject:\n\t\ts = \"Access-Reject\"\n\tcase RADIUSCodeAccountingRequest:\n\t\ts = \"Accounting-Request\"\n\tcase RADIUSCodeAccountingResponse:\n\t\ts = \"Accounting-Response\"\n\tcase RADIUSCodeAccessChallenge:\n\t\ts = \"Access-Challenge\"\n\tcase RADIUSCodeStatusServer:\n\t\ts = \"Status-Server\"\n\tcase RADIUSCodeStatusClient:\n\t\ts = \"Status-Client\"\n\tcase RADIUSCodeReserved:\n\t\ts = \"Reserved\"\n\tdefault:\n\t\ts = fmt.Sprintf(\"Unknown(%d)\", t)\n\t}\n\treturn\n}\n\n// RADIUSIdentifier represents packet identifier.\ntype RADIUSIdentifier uint8\n\n// RADIUSLength represents packet length.\ntype RADIUSLength uint16\n\n// RADIUSAuthenticator represents authenticator.\ntype RADIUSAuthenticator [16]byte\n\n// RADIUSAttribute represents attributes.\ntype RADIUSAttribute struct {\n\tType   RADIUSAttributeType\n\tLength RADIUSAttributeLength\n\tValue  RADIUSAttributeValue\n}\n\n// RADIUSAttributeType represents attribute type.\ntype RADIUSAttributeType uint8\n\n// constants that define RADIUSAttributeType.\nconst (\n\tRADIUSAttributeTypeUserName               RADIUSAttributeType = 1  // RFC2865  5.1.  User-Name\n\tRADIUSAttributeTypeUserPassword           RADIUSAttributeType = 2  // RFC2865  5.2.  User-Password\n\tRADIUSAttributeTypeCHAPPassword           RADIUSAttributeType = 3  // RFC2865  5.3.  CHAP-Password\n\tRADIUSAttributeTypeNASIPAddress           RADIUSAttributeType = 4  // RFC2865  5.4.  NAS-IP-Address\n\tRADIUSAttributeTypeNASPort                RADIUSAttributeType = 5  // RFC2865  5.5.  NAS-Port\n\tRADIUSAttributeTypeServiceType            RADIUSAttributeType = 6  // RFC2865  5.6.  Service-Type\n\tRADIUSAttributeTypeFramedProtocol         RADIUSAttributeType = 7  // RFC2865  5.7.  Framed-Protocol\n\tRADIUSAttributeTypeFramedIPAddress        RADIUSAttributeType = 8  // RFC2865  5.8.  Framed-IP-Address\n\tRADIUSAttributeTypeFramedIPNetmask        RADIUSAttributeType = 9  // RFC2865  5.9.  Framed-IP-Netmask\n\tRADIUSAttributeTypeFramedRouting          RADIUSAttributeType = 10 // RFC2865 5.10.  Framed-Routing\n\tRADIUSAttributeTypeFilterId               RADIUSAttributeType = 11 // RFC2865 5.11.  Filter-Id\n\tRADIUSAttributeTypeFramedMTU              RADIUSAttributeType = 12 // RFC2865 5.12.  Framed-MTU\n\tRADIUSAttributeTypeFramedCompression      RADIUSAttributeType = 13 // RFC2865 5.13.  Framed-Compression\n\tRADIUSAttributeTypeLoginIPHost            RADIUSAttributeType = 14 // RFC2865 5.14.  Login-IP-Host\n\tRADIUSAttributeTypeLoginService           RADIUSAttributeType = 15 // RFC2865 5.15.  Login-Service\n\tRADIUSAttributeTypeLoginTCPPort           RADIUSAttributeType = 16 // RFC2865 5.16.  Login-TCP-Port\n\tRADIUSAttributeTypeReplyMessage           RADIUSAttributeType = 18 // RFC2865 5.18.  Reply-Message\n\tRADIUSAttributeTypeCallbackNumber         RADIUSAttributeType = 19 // RFC2865 5.19.  Callback-Number\n\tRADIUSAttributeTypeCallbackId             RADIUSAttributeType = 20 // RFC2865 5.20.  Callback-Id\n\tRADIUSAttributeTypeFramedRoute            RADIUSAttributeType = 22 // RFC2865 5.22.  Framed-Route\n\tRADIUSAttributeTypeFramedIPXNetwork       RADIUSAttributeType = 23 // RFC2865 5.23.  Framed-IPX-Network\n\tRADIUSAttributeTypeState                  RADIUSAttributeType = 24 // RFC2865 5.24.  State\n\tRADIUSAttributeTypeClass                  RADIUSAttributeType = 25 // RFC2865 5.25.  Class\n\tRADIUSAttributeTypeVendorSpecific         RADIUSAttributeType = 26 // RFC2865 5.26.  Vendor-Specific\n\tRADIUSAttributeTypeSessionTimeout         RADIUSAttributeType = 27 // RFC2865 5.27.  Session-Timeout\n\tRADIUSAttributeTypeIdleTimeout            RADIUSAttributeType = 28 // RFC2865 5.28.  Idle-Timeout\n\tRADIUSAttributeTypeTerminationAction      RADIUSAttributeType = 29 // RFC2865 5.29.  Termination-Action\n\tRADIUSAttributeTypeCalledStationId        RADIUSAttributeType = 30 // RFC2865 5.30.  Called-Station-Id\n\tRADIUSAttributeTypeCallingStationId       RADIUSAttributeType = 31 // RFC2865 5.31.  Calling-Station-Id\n\tRADIUSAttributeTypeNASIdentifier          RADIUSAttributeType = 32 // RFC2865 5.32.  NAS-Identifier\n\tRADIUSAttributeTypeProxyState             RADIUSAttributeType = 33 // RFC2865 5.33.  Proxy-State\n\tRADIUSAttributeTypeLoginLATService        RADIUSAttributeType = 34 // RFC2865 5.34.  Login-LAT-Service\n\tRADIUSAttributeTypeLoginLATNode           RADIUSAttributeType = 35 // RFC2865 5.35.  Login-LAT-Node\n\tRADIUSAttributeTypeLoginLATGroup          RADIUSAttributeType = 36 // RFC2865 5.36.  Login-LAT-Group\n\tRADIUSAttributeTypeFramedAppleTalkLink    RADIUSAttributeType = 37 // RFC2865 5.37.  Framed-AppleTalk-Link\n\tRADIUSAttributeTypeFramedAppleTalkNetwork RADIUSAttributeType = 38 // RFC2865 5.38.  Framed-AppleTalk-Network\n\tRADIUSAttributeTypeFramedAppleTalkZone    RADIUSAttributeType = 39 // RFC2865 5.39.  Framed-AppleTalk-Zone\n\tRADIUSAttributeTypeAcctStatusType         RADIUSAttributeType = 40 // RFC2866  5.1.  Acct-Status-Type\n\tRADIUSAttributeTypeAcctDelayTime          RADIUSAttributeType = 41 // RFC2866  5.2.  Acct-Delay-Time\n\tRADIUSAttributeTypeAcctInputOctets        RADIUSAttributeType = 42 // RFC2866  5.3.  Acct-Input-Octets\n\tRADIUSAttributeTypeAcctOutputOctets       RADIUSAttributeType = 43 // RFC2866  5.4.  Acct-Output-Octets\n\tRADIUSAttributeTypeAcctSessionId          RADIUSAttributeType = 44 // RFC2866  5.5.  Acct-Session-Id\n\tRADIUSAttributeTypeAcctAuthentic          RADIUSAttributeType = 45 // RFC2866  5.6.  Acct-Authentic\n\tRADIUSAttributeTypeAcctSessionTime        RADIUSAttributeType = 46 // RFC2866  5.7.  Acct-Session-Time\n\tRADIUSAttributeTypeAcctInputPackets       RADIUSAttributeType = 47 // RFC2866  5.8.  Acct-Input-Packets\n\tRADIUSAttributeTypeAcctOutputPackets      RADIUSAttributeType = 48 // RFC2866  5.9.  Acct-Output-Packets\n\tRADIUSAttributeTypeAcctTerminateCause     RADIUSAttributeType = 49 // RFC2866 5.10.  Acct-Terminate-Cause\n\tRADIUSAttributeTypeAcctMultiSessionId     RADIUSAttributeType = 50 // RFC2866 5.11.  Acct-Multi-Session-Id\n\tRADIUSAttributeTypeAcctLinkCount          RADIUSAttributeType = 51 // RFC2866 5.12.  Acct-Link-Count\n\tRADIUSAttributeTypeAcctInputGigawords     RADIUSAttributeType = 52 // RFC2869  5.1.  Acct-Input-Gigawords\n\tRADIUSAttributeTypeAcctOutputGigawords    RADIUSAttributeType = 53 // RFC2869  5.2.  Acct-Output-Gigawords\n\tRADIUSAttributeTypeEventTimestamp         RADIUSAttributeType = 55 // RFC2869  5.3.  Event-Timestamp\n\tRADIUSAttributeTypeCHAPChallenge          RADIUSAttributeType = 60 // RFC2865 5.40.  CHAP-Challenge\n\tRADIUSAttributeTypeNASPortType            RADIUSAttributeType = 61 // RFC2865 5.41.  NAS-Port-Type\n\tRADIUSAttributeTypePortLimit              RADIUSAttributeType = 62 // RFC2865 5.42.  Port-Limit\n\tRADIUSAttributeTypeLoginLATPort           RADIUSAttributeType = 63 // RFC2865 5.43.  Login-LAT-Port\n\tRADIUSAttributeTypeTunnelType             RADIUSAttributeType = 64 // RFC2868  3.1.  Tunnel-Type\n\tRADIUSAttributeTypeTunnelMediumType       RADIUSAttributeType = 65 // RFC2868  3.2.  Tunnel-Medium-Type\n\tRADIUSAttributeTypeTunnelClientEndpoint   RADIUSAttributeType = 66 // RFC2868  3.3.  Tunnel-Client-Endpoint\n\tRADIUSAttributeTypeTunnelServerEndpoint   RADIUSAttributeType = 67 // RFC2868  3.4.  Tunnel-Server-Endpoint\n\tRADIUSAttributeTypeAcctTunnelConnection   RADIUSAttributeType = 68 // RFC2867  4.1.  Acct-Tunnel-Connection\n\tRADIUSAttributeTypeTunnelPassword         RADIUSAttributeType = 69 // RFC2868  3.5.  Tunnel-Password\n\tRADIUSAttributeTypeARAPPassword           RADIUSAttributeType = 70 // RFC2869  5.4.  ARAP-Password\n\tRADIUSAttributeTypeARAPFeatures           RADIUSAttributeType = 71 // RFC2869  5.5.  ARAP-Features\n\tRADIUSAttributeTypeARAPZoneAccess         RADIUSAttributeType = 72 // RFC2869  5.6.  ARAP-Zone-Access\n\tRADIUSAttributeTypeARAPSecurity           RADIUSAttributeType = 73 // RFC2869  5.7.  ARAP-Security\n\tRADIUSAttributeTypeARAPSecurityData       RADIUSAttributeType = 74 // RFC2869  5.8.  ARAP-Security-Data\n\tRADIUSAttributeTypePasswordRetry          RADIUSAttributeType = 75 // RFC2869  5.9.  Password-Retry\n\tRADIUSAttributeTypePrompt                 RADIUSAttributeType = 76 // RFC2869 5.10.  Prompt\n\tRADIUSAttributeTypeConnectInfo            RADIUSAttributeType = 77 // RFC2869 5.11.  Connect-Info\n\tRADIUSAttributeTypeConfigurationToken     RADIUSAttributeType = 78 // RFC2869 5.12.  Configuration-Token\n\tRADIUSAttributeTypeEAPMessage             RADIUSAttributeType = 79 // RFC2869 5.13.  EAP-Message\n\tRADIUSAttributeTypeMessageAuthenticator   RADIUSAttributeType = 80 // RFC2869 5.14.  Message-Authenticator\n\tRADIUSAttributeTypeTunnelPrivateGroupID   RADIUSAttributeType = 81 // RFC2868  3.6.  Tunnel-Private-Group-ID\n\tRADIUSAttributeTypeTunnelAssignmentID     RADIUSAttributeType = 82 // RFC2868  3.7.  Tunnel-Assignment-ID\n\tRADIUSAttributeTypeTunnelPreference       RADIUSAttributeType = 83 // RFC2868  3.8.  Tunnel-Preference\n\tRADIUSAttributeTypeARAPChallengeResponse  RADIUSAttributeType = 84 // RFC2869 5.15.  ARAP-Challenge-Response\n\tRADIUSAttributeTypeAcctInterimInterval    RADIUSAttributeType = 85 // RFC2869 5.16.  Acct-Interim-Interval\n\tRADIUSAttributeTypeAcctTunnelPacketsLost  RADIUSAttributeType = 86 // RFC2867  4.2.  Acct-Tunnel-Packets-Lost\n\tRADIUSAttributeTypeNASPortId              RADIUSAttributeType = 87 // RFC2869 5.17.  NAS-Port-Id\n\tRADIUSAttributeTypeFramedPool             RADIUSAttributeType = 88 // RFC2869 5.18.  Framed-Pool\n\tRADIUSAttributeTypeTunnelClientAuthID     RADIUSAttributeType = 90 // RFC2868  3.9.  Tunnel-Client-Auth-ID\n\tRADIUSAttributeTypeTunnelServerAuthID     RADIUSAttributeType = 91 // RFC2868 3.10.  Tunnel-Server-Auth-ID\n)\n\n// RADIUSAttributeType represents attribute length.\ntype RADIUSAttributeLength uint8\n\n// RADIUSAttributeType represents attribute value.\ntype RADIUSAttributeValue []byte\n\n// String returns a string version of a RADIUSAttributeType.\nfunc (t RADIUSAttributeType) String() (s string) {\n\tswitch t {\n\tcase RADIUSAttributeTypeUserName:\n\t\ts = \"User-Name\"\n\tcase RADIUSAttributeTypeUserPassword:\n\t\ts = \"User-Password\"\n\tcase RADIUSAttributeTypeCHAPPassword:\n\t\ts = \"CHAP-Password\"\n\tcase RADIUSAttributeTypeNASIPAddress:\n\t\ts = \"NAS-IP-Address\"\n\tcase RADIUSAttributeTypeNASPort:\n\t\ts = \"NAS-Port\"\n\tcase RADIUSAttributeTypeServiceType:\n\t\ts = \"Service-Type\"\n\tcase RADIUSAttributeTypeFramedProtocol:\n\t\ts = \"Framed-Protocol\"\n\tcase RADIUSAttributeTypeFramedIPAddress:\n\t\ts = \"Framed-IP-Address\"\n\tcase RADIUSAttributeTypeFramedIPNetmask:\n\t\ts = \"Framed-IP-Netmask\"\n\tcase RADIUSAttributeTypeFramedRouting:\n\t\ts = \"Framed-Routing\"\n\tcase RADIUSAttributeTypeFilterId:\n\t\ts = \"Filter-Id\"\n\tcase RADIUSAttributeTypeFramedMTU:\n\t\ts = \"Framed-MTU\"\n\tcase RADIUSAttributeTypeFramedCompression:\n\t\ts = \"Framed-Compression\"\n\tcase RADIUSAttributeTypeLoginIPHost:\n\t\ts = \"Login-IP-Host\"\n\tcase RADIUSAttributeTypeLoginService:\n\t\ts = \"Login-Service\"\n\tcase RADIUSAttributeTypeLoginTCPPort:\n\t\ts = \"Login-TCP-Port\"\n\tcase RADIUSAttributeTypeReplyMessage:\n\t\ts = \"Reply-Message\"\n\tcase RADIUSAttributeTypeCallbackNumber:\n\t\ts = \"Callback-Number\"\n\tcase RADIUSAttributeTypeCallbackId:\n\t\ts = \"Callback-Id\"\n\tcase RADIUSAttributeTypeFramedRoute:\n\t\ts = \"Framed-Route\"\n\tcase RADIUSAttributeTypeFramedIPXNetwork:\n\t\ts = \"Framed-IPX-Network\"\n\tcase RADIUSAttributeTypeState:\n\t\ts = \"State\"\n\tcase RADIUSAttributeTypeClass:\n\t\ts = \"Class\"\n\tcase RADIUSAttributeTypeVendorSpecific:\n\t\ts = \"Vendor-Specific\"\n\tcase RADIUSAttributeTypeSessionTimeout:\n\t\ts = \"Session-Timeout\"\n\tcase RADIUSAttributeTypeIdleTimeout:\n\t\ts = \"Idle-Timeout\"\n\tcase RADIUSAttributeTypeTerminationAction:\n\t\ts = \"Termination-Action\"\n\tcase RADIUSAttributeTypeCalledStationId:\n\t\ts = \"Called-Station-Id\"\n\tcase RADIUSAttributeTypeCallingStationId:\n\t\ts = \"Calling-Station-Id\"\n\tcase RADIUSAttributeTypeNASIdentifier:\n\t\ts = \"NAS-Identifier\"\n\tcase RADIUSAttributeTypeProxyState:\n\t\ts = \"Proxy-State\"\n\tcase RADIUSAttributeTypeLoginLATService:\n\t\ts = \"Login-LAT-Service\"\n\tcase RADIUSAttributeTypeLoginLATNode:\n\t\ts = \"Login-LAT-Node\"\n\tcase RADIUSAttributeTypeLoginLATGroup:\n\t\ts = \"Login-LAT-Group\"\n\tcase RADIUSAttributeTypeFramedAppleTalkLink:\n\t\ts = \"Framed-AppleTalk-Link\"\n\tcase RADIUSAttributeTypeFramedAppleTalkNetwork:\n\t\ts = \"Framed-AppleTalk-Network\"\n\tcase RADIUSAttributeTypeFramedAppleTalkZone:\n\t\ts = \"Framed-AppleTalk-Zone\"\n\tcase RADIUSAttributeTypeAcctStatusType:\n\t\ts = \"Acct-Status-Type\"\n\tcase RADIUSAttributeTypeAcctDelayTime:\n\t\ts = \"Acct-Delay-Time\"\n\tcase RADIUSAttributeTypeAcctInputOctets:\n\t\ts = \"Acct-Input-Octets\"\n\tcase RADIUSAttributeTypeAcctOutputOctets:\n\t\ts = \"Acct-Output-Octets\"\n\tcase RADIUSAttributeTypeAcctSessionId:\n\t\ts = \"Acct-Session-Id\"\n\tcase RADIUSAttributeTypeAcctAuthentic:\n\t\ts = \"Acct-Authentic\"\n\tcase RADIUSAttributeTypeAcctSessionTime:\n\t\ts = \"Acct-Session-Time\"\n\tcase RADIUSAttributeTypeAcctInputPackets:\n\t\ts = \"Acct-Input-Packets\"\n\tcase RADIUSAttributeTypeAcctOutputPackets:\n\t\ts = \"Acct-Output-Packets\"\n\tcase RADIUSAttributeTypeAcctTerminateCause:\n\t\ts = \"Acct-Terminate-Cause\"\n\tcase RADIUSAttributeTypeAcctMultiSessionId:\n\t\ts = \"Acct-Multi-Session-Id\"\n\tcase RADIUSAttributeTypeAcctLinkCount:\n\t\ts = \"Acct-Link-Count\"\n\tcase RADIUSAttributeTypeAcctInputGigawords:\n\t\ts = \"Acct-Input-Gigawords\"\n\tcase RADIUSAttributeTypeAcctOutputGigawords:\n\t\ts = \"Acct-Output-Gigawords\"\n\tcase RADIUSAttributeTypeEventTimestamp:\n\t\ts = \"Event-Timestamp\"\n\tcase RADIUSAttributeTypeCHAPChallenge:\n\t\ts = \"CHAP-Challenge\"\n\tcase RADIUSAttributeTypeNASPortType:\n\t\ts = \"NAS-Port-Type\"\n\tcase RADIUSAttributeTypePortLimit:\n\t\ts = \"Port-Limit\"\n\tcase RADIUSAttributeTypeLoginLATPort:\n\t\ts = \"Login-LAT-Port\"\n\tcase RADIUSAttributeTypeTunnelType:\n\t\ts = \"Tunnel-Type\"\n\tcase RADIUSAttributeTypeTunnelMediumType:\n\t\ts = \"Tunnel-Medium-Type\"\n\tcase RADIUSAttributeTypeTunnelClientEndpoint:\n\t\ts = \"Tunnel-Client-Endpoint\"\n\tcase RADIUSAttributeTypeTunnelServerEndpoint:\n\t\ts = \"Tunnel-Server-Endpoint\"\n\tcase RADIUSAttributeTypeAcctTunnelConnection:\n\t\ts = \"Acct-Tunnel-Connection\"\n\tcase RADIUSAttributeTypeTunnelPassword:\n\t\ts = \"Tunnel-Password\"\n\tcase RADIUSAttributeTypeARAPPassword:\n\t\ts = \"ARAP-Password\"\n\tcase RADIUSAttributeTypeARAPFeatures:\n\t\ts = \"ARAP-Features\"\n\tcase RADIUSAttributeTypeARAPZoneAccess:\n\t\ts = \"ARAP-Zone-Access\"\n\tcase RADIUSAttributeTypeARAPSecurity:\n\t\ts = \"ARAP-Security\"\n\tcase RADIUSAttributeTypeARAPSecurityData:\n\t\ts = \"ARAP-Security-Data\"\n\tcase RADIUSAttributeTypePasswordRetry:\n\t\ts = \"Password-Retry\"\n\tcase RADIUSAttributeTypePrompt:\n\t\ts = \"Prompt\"\n\tcase RADIUSAttributeTypeConnectInfo:\n\t\ts = \"Connect-Info\"\n\tcase RADIUSAttributeTypeConfigurationToken:\n\t\ts = \"Configuration-Token\"\n\tcase RADIUSAttributeTypeEAPMessage:\n\t\ts = \"EAP-Message\"\n\tcase RADIUSAttributeTypeMessageAuthenticator:\n\t\ts = \"Message-Authenticator\"\n\tcase RADIUSAttributeTypeTunnelPrivateGroupID:\n\t\ts = \"Tunnel-Private-Group-ID\"\n\tcase RADIUSAttributeTypeTunnelAssignmentID:\n\t\ts = \"Tunnel-Assignment-ID\"\n\tcase RADIUSAttributeTypeTunnelPreference:\n\t\ts = \"Tunnel-Preference\"\n\tcase RADIUSAttributeTypeARAPChallengeResponse:\n\t\ts = \"ARAP-Challenge-Response\"\n\tcase RADIUSAttributeTypeAcctInterimInterval:\n\t\ts = \"Acct-Interim-Interval\"\n\tcase RADIUSAttributeTypeAcctTunnelPacketsLost:\n\t\ts = \"Acct-Tunnel-Packets-Lost\"\n\tcase RADIUSAttributeTypeNASPortId:\n\t\ts = \"NAS-Port-Id\"\n\tcase RADIUSAttributeTypeFramedPool:\n\t\ts = \"Framed-Pool\"\n\tcase RADIUSAttributeTypeTunnelClientAuthID:\n\t\ts = \"Tunnel-Client-Auth-ID\"\n\tcase RADIUSAttributeTypeTunnelServerAuthID:\n\t\ts = \"Tunnel-Server-Auth-ID\"\n\tdefault:\n\t\ts = fmt.Sprintf(\"Unknown(%d)\", t)\n\t}\n\treturn\n}\n\n// Len returns the length of a RADIUS packet.\nfunc (radius *RADIUS) Len() (int, error) {\n\tn := radiusMinimumRecordSizeInBytes\n\tfor _, v := range radius.Attributes {\n\t\talen, err := attributeValueLength(v.Value)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tn += int(alen) + 2 // Added Type and Length\n\t}\n\treturn n, nil\n}\n\n// LayerType returns LayerTypeRADIUS.\nfunc (radius *RADIUS) LayerType() gopacket.LayerType {\n\treturn LayerTypeRADIUS\n}\n\n// DecodeFromBytes decodes the given bytes into this layer.\nfunc (radius *RADIUS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) > radiusMaximumRecordSizeInBytes {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"RADIUS length %d too big\", len(data))\n\t}\n\n\tif len(data) < radiusMinimumRecordSizeInBytes {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"RADIUS length %d too short\", len(data))\n\t}\n\n\tradius.BaseLayer = BaseLayer{Contents: data}\n\n\tradius.Code = RADIUSCode(data[0])\n\tradius.Identifier = RADIUSIdentifier(data[1])\n\tradius.Length = RADIUSLength(binary.BigEndian.Uint16(data[2:4]))\n\n\tif int(radius.Length) > radiusMaximumRecordSizeInBytes {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"RADIUS length %d too big\", radius.Length)\n\t}\n\n\tif int(radius.Length) < radiusMinimumRecordSizeInBytes {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"RADIUS length %d too short\", radius.Length)\n\t}\n\n\t// RFC 2865 3.  Packet Format\n\t// `If the packet is shorter than the Length field indicates, it MUST be silently discarded.`\n\tif int(radius.Length) > len(data) {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"RADIUS length %d too big\", radius.Length)\n\t}\n\n\t// RFC 2865 3.  Packet Format\n\t// `Octets outside the range of the Length field MUST be treated as padding and ignored on reception.`\n\tif int(radius.Length) < len(data) {\n\t\tdf.SetTruncated()\n\t\tdata = data[:radius.Length]\n\t}\n\n\tcopy(radius.Authenticator[:], data[4:20])\n\n\tif len(data) == radiusMinimumRecordSizeInBytes {\n\t\treturn nil\n\t}\n\n\tpos := radiusMinimumRecordSizeInBytes\n\tfor {\n\t\tif len(data) == pos {\n\t\t\tbreak\n\t\t}\n\n\t\tif len(data[pos:]) < radiusAttributesMinimumRecordSizeInBytes {\n\t\t\tdf.SetTruncated()\n\t\t\treturn fmt.Errorf(\"RADIUS attributes length %d too short\", len(data[pos:]))\n\t\t}\n\n\t\tattr := RADIUSAttribute{}\n\t\tattr.Type = RADIUSAttributeType(data[pos])\n\t\tattr.Length = RADIUSAttributeLength(data[pos+1])\n\n\t\tif int(attr.Length) > len(data[pos:]) {\n\t\t\tdf.SetTruncated()\n\t\t\treturn fmt.Errorf(\"RADIUS attributes length %d too big\", attr.Length)\n\t\t}\n\n\t\tif int(attr.Length) < radiusAttributesMinimumRecordSizeInBytes {\n\t\t\tdf.SetTruncated()\n\t\t\treturn fmt.Errorf(\"RADIUS attributes length %d too short\", attr.Length)\n\t\t}\n\n\t\tif int(attr.Length) > radiusAttributesMinimumRecordSizeInBytes {\n\t\t\tattr.Value = make([]byte, attr.Length-2)\n\t\t\tcopy(attr.Value[:], data[pos+2:pos+int(attr.Length)])\n\t\t\tradius.Attributes = append(radius.Attributes, attr)\n\t\t}\n\n\t\tpos += int(attr.Length)\n\t}\n\n\tfor _, v := range radius.Attributes {\n\t\tif v.Type == RADIUSAttributeTypeEAPMessage {\n\t\t\tradius.BaseLayer.Payload = append(radius.BaseLayer.Payload, v.Value...)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (radius *RADIUS) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tplen, err := radius.Len()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif opts.FixLengths {\n\t\tradius.Length = RADIUSLength(plen)\n\t}\n\n\tdata, err := b.PrependBytes(plen)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdata[0] = byte(radius.Code)\n\tdata[1] = byte(radius.Identifier)\n\tbinary.BigEndian.PutUint16(data[2:], uint16(radius.Length))\n\tcopy(data[4:20], radius.Authenticator[:])\n\n\tpos := radiusMinimumRecordSizeInBytes\n\tfor _, v := range radius.Attributes {\n\t\tif opts.FixLengths {\n\t\t\tv.Length, err = attributeValueLength(v.Value)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tdata[pos] = byte(v.Type)\n\t\tdata[pos+1] = byte(v.Length)\n\t\tcopy(data[pos+2:], v.Value[:])\n\n\t\tpos += len(v.Value) + 2 // Added Type and Length\n\t}\n\n\treturn nil\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode.\nfunc (radius *RADIUS) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeRADIUS\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer.\nfunc (radius *RADIUS) NextLayerType() gopacket.LayerType {\n\tif len(radius.BaseLayer.Payload) > 0 {\n\t\treturn LayerTypeEAP\n\t} else {\n\t\treturn gopacket.LayerTypeZero\n\t}\n}\n\n// Payload returns the EAP Type-Data for EAP-Message attributes.\nfunc (radius *RADIUS) Payload() []byte {\n\treturn radius.BaseLayer.Payload\n}\n\nfunc decodeRADIUS(data []byte, p gopacket.PacketBuilder) error {\n\tradius := &RADIUS{}\n\terr := radius.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\tp.AddLayer(radius)\n\tp.SetApplicationLayer(radius)\n\tnext := radius.NextLayerType()\n\tif next == gopacket.LayerTypeZero {\n\t\treturn nil\n\t}\n\treturn p.NextDecoder(next)\n}\n\nfunc attributeValueLength(v []byte) (RADIUSAttributeLength, error) {\n\tn := len(v)\n\tif n > 255 {\n\t\treturn 0, fmt.Errorf(\"RADIUS attribute value length %d too long\", n)\n\t} else {\n\t\treturn RADIUSAttributeLength(n), nil\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/rmcp.go",
    "content": "// Copyright 2019 The GoPacket Authors. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license that can be found\n// in the LICENSE file in the root of the source tree.\n\npackage layers\n\n// This file implements the ASF-RMCP header specified in section 3.2.2.2 of\n// https://www.dmtf.org/sites/default/files/standards/documents/DSP0136.pdf\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// RMCPClass is the class of a RMCP layer's payload, e.g. ASF or IPMI. This is a\n// 4-bit unsigned int on the wire; all but 6 (ASF), 7 (IPMI) and 8 (OEM-defined)\n// are currently reserved.\ntype RMCPClass uint8\n\n// LayerType returns the payload layer type corresponding to a RMCP class.\nfunc (c RMCPClass) LayerType() gopacket.LayerType {\n\tif lt := rmcpClassLayerTypes[uint8(c)]; lt != 0 {\n\t\treturn lt\n\t}\n\treturn gopacket.LayerTypePayload\n}\n\nfunc (c RMCPClass) String() string {\n\treturn fmt.Sprintf(\"%v(%v)\", uint8(c), c.LayerType())\n}\n\nconst (\n\t// RMCPVersion1 identifies RMCP v1.0 in the Version header field. Lower\n\t// values are considered legacy, while higher values are reserved by the\n\t// specification.\n\tRMCPVersion1 uint8 = 0x06\n\n\t// RMCPNormal indicates a \"normal\" message, i.e. not an acknowledgement.\n\tRMCPNormal uint8 = 0\n\n\t// RMCPAck indicates a message is acknowledging a received normal message.\n\tRMCPAck uint8 = 1 << 7\n\n\t// RMCPClassASF identifies an RMCP message as containing an ASF-RMCP\n\t// payload.\n\tRMCPClassASF RMCPClass = 0x06\n\n\t// RMCPClassIPMI identifies an RMCP message as containing an IPMI payload.\n\tRMCPClassIPMI RMCPClass = 0x07\n\n\t// RMCPClassOEM identifies an RMCP message as containing an OEM-defined\n\t// payload.\n\tRMCPClassOEM RMCPClass = 0x08\n)\n\nvar (\n\trmcpClassLayerTypes = [16]gopacket.LayerType{\n\t\tRMCPClassASF: LayerTypeASF,\n\t\t// RMCPClassIPMI is to implement; RMCPClassOEM is deliberately not\n\t\t// implemented, so we return LayerTypePayload\n\t}\n)\n\n// RegisterRMCPLayerType allows specifying that the payload of a RMCP packet of\n// a certain class should processed by the provided layer type. This overrides\n// any existing registrations, including defaults.\nfunc RegisterRMCPLayerType(c RMCPClass, l gopacket.LayerType) {\n\trmcpClassLayerTypes[c] = l\n}\n\n// RMCP describes the format of an RMCP header, which forms a UDP payload. See\n// section 3.2.2.2.\ntype RMCP struct {\n\tBaseLayer\n\n\t// Version identifies the version of the RMCP header. 0x06 indicates RMCP\n\t// v1.0; lower values are legacy, higher values are reserved.\n\tVersion uint8\n\n\t// Sequence is the sequence number assicated with the message. Note that\n\t// this rolls over to 0 after 254, not 255. Seq num 255 indicates the\n\t// receiver must not send an ACK.\n\tSequence uint8\n\n\t// Ack indicates whether this packet is an acknowledgement. If it is, the\n\t// payload will be empty.\n\tAck bool\n\n\t// Class idicates the structure of the payload. There are only 2^4 valid\n\t// values, however there is no uint4 data type. N.B. the Ack bit has been\n\t// split off into another field. The most significant 4 bits of this field\n\t// will always be 0.\n\tClass RMCPClass\n}\n\n// LayerType returns LayerTypeRMCP. It partially satisfies Layer and\n// SerializableLayer.\nfunc (*RMCP) LayerType() gopacket.LayerType {\n\treturn LayerTypeRMCP\n}\n\n// CanDecode returns LayerTypeRMCP. It partially satisfies DecodingLayer.\nfunc (r *RMCP) CanDecode() gopacket.LayerClass {\n\treturn r.LayerType()\n}\n\n// DecodeFromBytes makes the layer represent the provided bytes. It partially\n// satisfies DecodingLayer.\nfunc (r *RMCP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 4 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"invalid RMCP header, length %v less than 4\",\n\t\t\tlen(data))\n\t}\n\n\tr.BaseLayer.Contents = data[:4]\n\tr.BaseLayer.Payload = data[4:]\n\n\tr.Version = uint8(data[0])\n\t// 1 byte reserved\n\tr.Sequence = uint8(data[2])\n\tr.Ack = data[3]&RMCPAck != 0\n\tr.Class = RMCPClass(data[3] & 0xF)\n\treturn nil\n}\n\n// NextLayerType returns the data layer of this RMCP layer. This partially\n// satisfies DecodingLayer.\nfunc (r *RMCP) NextLayerType() gopacket.LayerType {\n\treturn r.Class.LayerType()\n}\n\n// Payload returns the data layer. It partially satisfies ApplicationLayer.\nfunc (r *RMCP) Payload() []byte {\n\treturn r.BaseLayer.Payload\n}\n\n// SerializeTo writes the serialized fom of this layer into the SerializeBuffer,\n// partially satisfying SerializableLayer.\nfunc (r *RMCP) SerializeTo(b gopacket.SerializeBuffer, _ gopacket.SerializeOptions) error {\n\t// The IPMI v1.5 spec contains a pad byte for frame sizes of certain lengths\n\t// to work around issues in LAN chips. This is no longer necessary as of\n\t// IPMI v2.0 (renamed to \"legacy pad\") so we do not attempt to add it. The\n\t// same approach is taken by FreeIPMI:\n\t// http://git.savannah.gnu.org/cgit/freeipmi.git/tree/libfreeipmi/interface/ipmi-lan-interface.c?id=b5ffcd38317daf42074458879f4c55ba6804a595#n836\n\tbytes, err := b.PrependBytes(4)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbytes[0] = r.Version\n\tbytes[1] = 0x00\n\tbytes[2] = r.Sequence\n\tbytes[3] = bool2uint8(r.Ack)<<7 | uint8(r.Class) // thanks, BFD layer\n\treturn nil\n}\n\n// decodeRMCP decodes the byte slice into an RMCP type, and sets the application\n// layer to it.\nfunc decodeRMCP(data []byte, p gopacket.PacketBuilder) error {\n\trmcp := &RMCP{}\n\terr := rmcp.DecodeFromBytes(data, p)\n\tp.AddLayer(rmcp)\n\tp.SetApplicationLayer(rmcp)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn p.NextDecoder(rmcp.NextLayerType())\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/rudp.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"github.com/google/gopacket\"\n)\n\ntype RUDP struct {\n\tBaseLayer\n\tSYN, ACK, EACK, RST, NUL bool\n\tVersion                  uint8\n\tHeaderLength             uint8\n\tSrcPort, DstPort         RUDPPort\n\tDataLength               uint16\n\tSeq, Ack, Checksum       uint32\n\tVariableHeaderArea       []byte\n\t// RUDPHeaderSyn contains SYN information for the RUDP packet,\n\t// if the SYN flag is set\n\t*RUDPHeaderSYN\n\t// RUDPHeaderEack contains EACK information for the RUDP packet,\n\t// if the EACK flag is set.\n\t*RUDPHeaderEACK\n}\n\ntype RUDPHeaderSYN struct {\n\tMaxOutstandingSegments, MaxSegmentSize, OptionFlags uint16\n}\n\ntype RUDPHeaderEACK struct {\n\tSeqsReceivedOK []uint32\n}\n\n// LayerType returns gopacket.LayerTypeRUDP.\nfunc (r *RUDP) LayerType() gopacket.LayerType { return LayerTypeRUDP }\n\nfunc decodeRUDP(data []byte, p gopacket.PacketBuilder) error {\n\tr := &RUDP{\n\t\tSYN:          data[0]&0x80 != 0,\n\t\tACK:          data[0]&0x40 != 0,\n\t\tEACK:         data[0]&0x20 != 0,\n\t\tRST:          data[0]&0x10 != 0,\n\t\tNUL:          data[0]&0x08 != 0,\n\t\tVersion:      data[0] & 0x3,\n\t\tHeaderLength: data[1],\n\t\tSrcPort:      RUDPPort(data[2]),\n\t\tDstPort:      RUDPPort(data[3]),\n\t\tDataLength:   binary.BigEndian.Uint16(data[4:6]),\n\t\tSeq:          binary.BigEndian.Uint32(data[6:10]),\n\t\tAck:          binary.BigEndian.Uint32(data[10:14]),\n\t\tChecksum:     binary.BigEndian.Uint32(data[14:18]),\n\t}\n\tif r.HeaderLength < 9 {\n\t\treturn fmt.Errorf(\"RUDP packet with too-short header length %d\", r.HeaderLength)\n\t}\n\thlen := int(r.HeaderLength) * 2\n\tr.Contents = data[:hlen]\n\tr.Payload = data[hlen : hlen+int(r.DataLength)]\n\tr.VariableHeaderArea = data[18:hlen]\n\theaderData := r.VariableHeaderArea\n\tswitch {\n\tcase r.SYN:\n\t\tif len(headerData) != 6 {\n\t\t\treturn fmt.Errorf(\"RUDP packet invalid SYN header length: %d\", len(headerData))\n\t\t}\n\t\tr.RUDPHeaderSYN = &RUDPHeaderSYN{\n\t\t\tMaxOutstandingSegments: binary.BigEndian.Uint16(headerData[:2]),\n\t\t\tMaxSegmentSize:         binary.BigEndian.Uint16(headerData[2:4]),\n\t\t\tOptionFlags:            binary.BigEndian.Uint16(headerData[4:6]),\n\t\t}\n\tcase r.EACK:\n\t\tif len(headerData)%4 != 0 {\n\t\t\treturn fmt.Errorf(\"RUDP packet invalid EACK header length: %d\", len(headerData))\n\t\t}\n\t\tr.RUDPHeaderEACK = &RUDPHeaderEACK{make([]uint32, len(headerData)/4)}\n\t\tfor i := 0; i < len(headerData); i += 4 {\n\t\t\tr.SeqsReceivedOK[i/4] = binary.BigEndian.Uint32(headerData[i : i+4])\n\t\t}\n\t}\n\tp.AddLayer(r)\n\tp.SetTransportLayer(r)\n\treturn p.NextDecoder(gopacket.LayerTypePayload)\n}\n\nfunc (r *RUDP) TransportFlow() gopacket.Flow {\n\treturn gopacket.NewFlow(EndpointRUDPPort, []byte{byte(r.SrcPort)}, []byte{byte(r.DstPort)})\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/sctp.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"hash/crc32\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// SCTP contains information on the top level of an SCTP packet.\ntype SCTP struct {\n\tBaseLayer\n\tSrcPort, DstPort SCTPPort\n\tVerificationTag  uint32\n\tChecksum         uint32\n\tsPort, dPort     []byte\n}\n\n// LayerType returns gopacket.LayerTypeSCTP\nfunc (s *SCTP) LayerType() gopacket.LayerType { return LayerTypeSCTP }\n\nfunc decodeSCTP(data []byte, p gopacket.PacketBuilder) error {\n\tsctp := &SCTP{}\n\terr := sctp.DecodeFromBytes(data, p)\n\tp.AddLayer(sctp)\n\tp.SetTransportLayer(sctp)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn p.NextDecoder(sctpChunkTypePrefixDecoder)\n}\n\nvar sctpChunkTypePrefixDecoder = gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix)\n\n// TransportFlow returns a flow based on the source and destination SCTP port.\nfunc (s *SCTP) TransportFlow() gopacket.Flow {\n\treturn gopacket.NewFlow(EndpointSCTPPort, s.sPort, s.dPort)\n}\n\nfunc decodeWithSCTPChunkTypePrefix(data []byte, p gopacket.PacketBuilder) error {\n\tchunkType := SCTPChunkType(data[0])\n\treturn chunkType.Decode(data, p)\n}\n\n// SerializeTo is for gopacket.SerializableLayer.\nfunc (s SCTP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbytes, err := b.PrependBytes(12)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbinary.BigEndian.PutUint16(bytes[0:2], uint16(s.SrcPort))\n\tbinary.BigEndian.PutUint16(bytes[2:4], uint16(s.DstPort))\n\tbinary.BigEndian.PutUint32(bytes[4:8], s.VerificationTag)\n\tif opts.ComputeChecksums {\n\t\t// Note:  MakeTable(Castagnoli) actually only creates the table once, then\n\t\t// passes back a singleton on every other call, so this shouldn't cause\n\t\t// excessive memory allocation.\n\t\tbinary.LittleEndian.PutUint32(bytes[8:12], crc32.Checksum(b.Bytes(), crc32.MakeTable(crc32.Castagnoli)))\n\t}\n\treturn nil\n}\n\nfunc (sctp *SCTP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 12 {\n\t\treturn errors.New(\"Invalid SCTP common header length\")\n\t}\n\tsctp.SrcPort = SCTPPort(binary.BigEndian.Uint16(data[:2]))\n\tsctp.sPort = data[:2]\n\tsctp.DstPort = SCTPPort(binary.BigEndian.Uint16(data[2:4]))\n\tsctp.dPort = data[2:4]\n\tsctp.VerificationTag = binary.BigEndian.Uint32(data[4:8])\n\tsctp.Checksum = binary.BigEndian.Uint32(data[8:12])\n\tsctp.BaseLayer = BaseLayer{data[:12], data[12:]}\n\n\treturn nil\n}\n\nfunc (t *SCTP) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeSCTP\n}\n\nfunc (t *SCTP) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\n// SCTPChunk contains the common fields in all SCTP chunks.\ntype SCTPChunk struct {\n\tBaseLayer\n\tType   SCTPChunkType\n\tFlags  uint8\n\tLength uint16\n\t// ActualLength is the total length of an SCTP chunk, including padding.\n\t// SCTP chunks start and end on 4-byte boundaries.  So if a chunk has a length\n\t// of 18, it means that it has data up to and including byte 18, then padding\n\t// up to the next 4-byte boundary, 20.  In this case, Length would be 18, and\n\t// ActualLength would be 20.\n\tActualLength int\n}\n\nfunc roundUpToNearest4(i int) int {\n\tif i%4 == 0 {\n\t\treturn i\n\t}\n\treturn i + 4 - (i % 4)\n}\n\nfunc decodeSCTPChunk(data []byte) (SCTPChunk, error) {\n\tlength := binary.BigEndian.Uint16(data[2:4])\n\tif length < 4 {\n\t\treturn SCTPChunk{}, errors.New(\"invalid SCTP chunk length\")\n\t}\n\tactual := roundUpToNearest4(int(length))\n\tct := SCTPChunkType(data[0])\n\n\t// For SCTP Data, use a separate layer for the payload\n\tdelta := 0\n\tif ct == SCTPChunkTypeData {\n\t\tdelta = int(actual) - int(length)\n\t\tactual = 16\n\t}\n\n\treturn SCTPChunk{\n\t\tType:         ct,\n\t\tFlags:        data[1],\n\t\tLength:       length,\n\t\tActualLength: actual,\n\t\tBaseLayer:    BaseLayer{data[:actual], data[actual : len(data)-delta]},\n\t}, nil\n}\n\n// SCTPParameter is a TLV parameter inside a SCTPChunk.\ntype SCTPParameter struct {\n\tType         uint16\n\tLength       uint16\n\tActualLength int\n\tValue        []byte\n}\n\nfunc decodeSCTPParameter(data []byte) SCTPParameter {\n\tlength := binary.BigEndian.Uint16(data[2:4])\n\treturn SCTPParameter{\n\t\tType:         binary.BigEndian.Uint16(data[0:2]),\n\t\tLength:       length,\n\t\tValue:        data[4:length],\n\t\tActualLength: roundUpToNearest4(int(length)),\n\t}\n}\n\nfunc (p SCTPParameter) Bytes() []byte {\n\tlength := 4 + len(p.Value)\n\tdata := make([]byte, roundUpToNearest4(length))\n\tbinary.BigEndian.PutUint16(data[0:2], p.Type)\n\tbinary.BigEndian.PutUint16(data[2:4], uint16(length))\n\tcopy(data[4:], p.Value)\n\treturn data\n}\n\n// SCTPUnknownChunkType is the layer type returned when we don't recognize the\n// chunk type.  Since there's a length in a known location, we can skip over\n// it even if we don't know what it is, and continue parsing the rest of the\n// chunks.  This chunk is stored as an ErrorLayer in the packet.\ntype SCTPUnknownChunkType struct {\n\tSCTPChunk\n\tbytes []byte\n}\n\nfunc decodeSCTPChunkTypeUnknown(data []byte, p gopacket.PacketBuilder) error {\n\tchunk, err := decodeSCTPChunk(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\tsc := &SCTPUnknownChunkType{SCTPChunk: chunk}\n\tsc.bytes = data[:sc.ActualLength]\n\tp.AddLayer(sc)\n\tp.SetErrorLayer(sc)\n\treturn p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))\n}\n\n// SerializeTo is for gopacket.SerializableLayer.\nfunc (s SCTPUnknownChunkType) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbytes, err := b.PrependBytes(s.ActualLength)\n\tif err != nil {\n\t\treturn err\n\t}\n\tcopy(bytes, s.bytes)\n\treturn nil\n}\n\n// LayerType returns gopacket.LayerTypeSCTPUnknownChunkType.\nfunc (s *SCTPUnknownChunkType) LayerType() gopacket.LayerType { return LayerTypeSCTPUnknownChunkType }\n\n// Payload returns all bytes in this header, including the decoded Type, Length,\n// and Flags.\nfunc (s *SCTPUnknownChunkType) Payload() []byte { return s.bytes }\n\n// Error implements ErrorLayer.\nfunc (s *SCTPUnknownChunkType) Error() error {\n\treturn fmt.Errorf(\"No decode method available for SCTP chunk type %s\", s.Type)\n}\n\n// SCTPData is the SCTP Data chunk layer.\ntype SCTPData struct {\n\tSCTPChunk\n\tUnordered, BeginFragment, EndFragment bool\n\tTSN                                   uint32\n\tStreamId                              uint16\n\tStreamSequence                        uint16\n\tPayloadProtocol                       SCTPPayloadProtocol\n}\n\n// LayerType returns gopacket.LayerTypeSCTPData.\nfunc (s *SCTPData) LayerType() gopacket.LayerType { return LayerTypeSCTPData }\n\n// SCTPPayloadProtocol represents a payload protocol\ntype SCTPPayloadProtocol uint32\n\n// SCTPPayloadProtocol constonts from http://www.iana.org/assignments/sctp-parameters/sctp-parameters.xhtml\nconst (\n\tSCTPProtocolReserved  SCTPPayloadProtocol = 0\n\tSCTPPayloadUIA                            = 1\n\tSCTPPayloadM2UA                           = 2\n\tSCTPPayloadM3UA                           = 3\n\tSCTPPayloadSUA                            = 4\n\tSCTPPayloadM2PA                           = 5\n\tSCTPPayloadV5UA                           = 6\n\tSCTPPayloadH248                           = 7\n\tSCTPPayloadBICC                           = 8\n\tSCTPPayloadTALI                           = 9\n\tSCTPPayloadDUA                            = 10\n\tSCTPPayloadASAP                           = 11\n\tSCTPPayloadENRP                           = 12\n\tSCTPPayloadH323                           = 13\n\tSCTPPayloadQIPC                           = 14\n\tSCTPPayloadSIMCO                          = 15\n\tSCTPPayloadDDPSegment                     = 16\n\tSCTPPayloadDDPStream                      = 17\n\tSCTPPayloadS1AP                           = 18\n)\n\nfunc (p SCTPPayloadProtocol) String() string {\n\tswitch p {\n\tcase SCTPProtocolReserved:\n\t\treturn \"Reserved\"\n\tcase SCTPPayloadUIA:\n\t\treturn \"UIA\"\n\tcase SCTPPayloadM2UA:\n\t\treturn \"M2UA\"\n\tcase SCTPPayloadM3UA:\n\t\treturn \"M3UA\"\n\tcase SCTPPayloadSUA:\n\t\treturn \"SUA\"\n\tcase SCTPPayloadM2PA:\n\t\treturn \"M2PA\"\n\tcase SCTPPayloadV5UA:\n\t\treturn \"V5UA\"\n\tcase SCTPPayloadH248:\n\t\treturn \"H.248\"\n\tcase SCTPPayloadBICC:\n\t\treturn \"BICC\"\n\tcase SCTPPayloadTALI:\n\t\treturn \"TALI\"\n\tcase SCTPPayloadDUA:\n\t\treturn \"DUA\"\n\tcase SCTPPayloadASAP:\n\t\treturn \"ASAP\"\n\tcase SCTPPayloadENRP:\n\t\treturn \"ENRP\"\n\tcase SCTPPayloadH323:\n\t\treturn \"H.323\"\n\tcase SCTPPayloadQIPC:\n\t\treturn \"QIPC\"\n\tcase SCTPPayloadSIMCO:\n\t\treturn \"SIMCO\"\n\tcase SCTPPayloadDDPSegment:\n\t\treturn \"DDPSegment\"\n\tcase SCTPPayloadDDPStream:\n\t\treturn \"DDPStream\"\n\tcase SCTPPayloadS1AP:\n\t\treturn \"S1AP\"\n\t}\n\treturn fmt.Sprintf(\"Unknown(%d)\", p)\n}\n\nfunc decodeSCTPData(data []byte, p gopacket.PacketBuilder) error {\n\tchunk, err := decodeSCTPChunk(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\tsc := &SCTPData{\n\t\tSCTPChunk:       chunk,\n\t\tUnordered:       data[1]&0x4 != 0,\n\t\tBeginFragment:   data[1]&0x2 != 0,\n\t\tEndFragment:     data[1]&0x1 != 0,\n\t\tTSN:             binary.BigEndian.Uint32(data[4:8]),\n\t\tStreamId:        binary.BigEndian.Uint16(data[8:10]),\n\t\tStreamSequence:  binary.BigEndian.Uint16(data[10:12]),\n\t\tPayloadProtocol: SCTPPayloadProtocol(binary.BigEndian.Uint32(data[12:16])),\n\t}\n\t// Length is the length in bytes of the data, INCLUDING the 16-byte header.\n\tp.AddLayer(sc)\n\treturn p.NextDecoder(gopacket.LayerTypePayload)\n}\n\n// SerializeTo is for gopacket.SerializableLayer.\nfunc (sc SCTPData) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tpayload := b.Bytes()\n\t// Pad the payload to a 32 bit boundary\n\tif rem := len(payload) % 4; rem != 0 {\n\t\tb.AppendBytes(4 - rem)\n\t}\n\tlength := 16\n\tbytes, err := b.PrependBytes(length)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbytes[0] = uint8(sc.Type)\n\tflags := uint8(0)\n\tif sc.Unordered {\n\t\tflags |= 0x4\n\t}\n\tif sc.BeginFragment {\n\t\tflags |= 0x2\n\t}\n\tif sc.EndFragment {\n\t\tflags |= 0x1\n\t}\n\tbytes[1] = flags\n\tbinary.BigEndian.PutUint16(bytes[2:4], uint16(length+len(payload)))\n\tbinary.BigEndian.PutUint32(bytes[4:8], sc.TSN)\n\tbinary.BigEndian.PutUint16(bytes[8:10], sc.StreamId)\n\tbinary.BigEndian.PutUint16(bytes[10:12], sc.StreamSequence)\n\tbinary.BigEndian.PutUint32(bytes[12:16], uint32(sc.PayloadProtocol))\n\treturn nil\n}\n\n// SCTPInitParameter is a parameter for an SCTP Init or InitAck packet.\ntype SCTPInitParameter SCTPParameter\n\n// SCTPInit is used as the return value for both SCTPInit and SCTPInitAck\n// messages.\ntype SCTPInit struct {\n\tSCTPChunk\n\tInitiateTag                     uint32\n\tAdvertisedReceiverWindowCredit  uint32\n\tOutboundStreams, InboundStreams uint16\n\tInitialTSN                      uint32\n\tParameters                      []SCTPInitParameter\n}\n\n// LayerType returns either gopacket.LayerTypeSCTPInit or gopacket.LayerTypeSCTPInitAck.\nfunc (sc *SCTPInit) LayerType() gopacket.LayerType {\n\tif sc.Type == SCTPChunkTypeInitAck {\n\t\treturn LayerTypeSCTPInitAck\n\t}\n\t// sc.Type == SCTPChunkTypeInit\n\treturn LayerTypeSCTPInit\n}\n\nfunc decodeSCTPInit(data []byte, p gopacket.PacketBuilder) error {\n\tchunk, err := decodeSCTPChunk(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\tsc := &SCTPInit{\n\t\tSCTPChunk:                      chunk,\n\t\tInitiateTag:                    binary.BigEndian.Uint32(data[4:8]),\n\t\tAdvertisedReceiverWindowCredit: binary.BigEndian.Uint32(data[8:12]),\n\t\tOutboundStreams:                binary.BigEndian.Uint16(data[12:14]),\n\t\tInboundStreams:                 binary.BigEndian.Uint16(data[14:16]),\n\t\tInitialTSN:                     binary.BigEndian.Uint32(data[16:20]),\n\t}\n\tparamData := data[20:sc.ActualLength]\n\tfor len(paramData) > 0 {\n\t\tp := SCTPInitParameter(decodeSCTPParameter(paramData))\n\t\tparamData = paramData[p.ActualLength:]\n\t\tsc.Parameters = append(sc.Parameters, p)\n\t}\n\tp.AddLayer(sc)\n\treturn p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))\n}\n\n// SerializeTo is for gopacket.SerializableLayer.\nfunc (sc SCTPInit) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tvar payload []byte\n\tfor _, param := range sc.Parameters {\n\t\tpayload = append(payload, SCTPParameter(param).Bytes()...)\n\t}\n\tlength := 20 + len(payload)\n\tbytes, err := b.PrependBytes(roundUpToNearest4(length))\n\tif err != nil {\n\t\treturn err\n\t}\n\tbytes[0] = uint8(sc.Type)\n\tbytes[1] = sc.Flags\n\tbinary.BigEndian.PutUint16(bytes[2:4], uint16(length))\n\tbinary.BigEndian.PutUint32(bytes[4:8], sc.InitiateTag)\n\tbinary.BigEndian.PutUint32(bytes[8:12], sc.AdvertisedReceiverWindowCredit)\n\tbinary.BigEndian.PutUint16(bytes[12:14], sc.OutboundStreams)\n\tbinary.BigEndian.PutUint16(bytes[14:16], sc.InboundStreams)\n\tbinary.BigEndian.PutUint32(bytes[16:20], sc.InitialTSN)\n\tcopy(bytes[20:], payload)\n\treturn nil\n}\n\n// SCTPSack is the SCTP Selective ACK chunk layer.\ntype SCTPSack struct {\n\tSCTPChunk\n\tCumulativeTSNAck               uint32\n\tAdvertisedReceiverWindowCredit uint32\n\tNumGapACKs, NumDuplicateTSNs   uint16\n\tGapACKs                        []uint16\n\tDuplicateTSNs                  []uint32\n}\n\n// LayerType return LayerTypeSCTPSack\nfunc (sc *SCTPSack) LayerType() gopacket.LayerType {\n\treturn LayerTypeSCTPSack\n}\n\nfunc decodeSCTPSack(data []byte, p gopacket.PacketBuilder) error {\n\tchunk, err := decodeSCTPChunk(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\tsc := &SCTPSack{\n\t\tSCTPChunk:                      chunk,\n\t\tCumulativeTSNAck:               binary.BigEndian.Uint32(data[4:8]),\n\t\tAdvertisedReceiverWindowCredit: binary.BigEndian.Uint32(data[8:12]),\n\t\tNumGapACKs:                     binary.BigEndian.Uint16(data[12:14]),\n\t\tNumDuplicateTSNs:               binary.BigEndian.Uint16(data[14:16]),\n\t}\n\t// We maximize gapAcks and dupTSNs here so we're not allocating tons\n\t// of memory based on a user-controlable field.  Our maximums are not exact,\n\t// but should give us sane defaults... we'll still hit slice boundaries and\n\t// fail if the user-supplied values are too high (in the for loops below), but\n\t// the amount of memory we'll have allocated because of that should be small\n\t// (< sc.ActualLength)\n\tgapAcks := sc.SCTPChunk.ActualLength / 2\n\tdupTSNs := (sc.SCTPChunk.ActualLength - gapAcks*2) / 4\n\tif gapAcks > int(sc.NumGapACKs) {\n\t\tgapAcks = int(sc.NumGapACKs)\n\t}\n\tif dupTSNs > int(sc.NumDuplicateTSNs) {\n\t\tdupTSNs = int(sc.NumDuplicateTSNs)\n\t}\n\tsc.GapACKs = make([]uint16, 0, gapAcks)\n\tsc.DuplicateTSNs = make([]uint32, 0, dupTSNs)\n\tbytesRemaining := data[16:]\n\tfor i := 0; i < int(sc.NumGapACKs); i++ {\n\t\tsc.GapACKs = append(sc.GapACKs, binary.BigEndian.Uint16(bytesRemaining[:2]))\n\t\tbytesRemaining = bytesRemaining[2:]\n\t}\n\tfor i := 0; i < int(sc.NumDuplicateTSNs); i++ {\n\t\tsc.DuplicateTSNs = append(sc.DuplicateTSNs, binary.BigEndian.Uint32(bytesRemaining[:4]))\n\t\tbytesRemaining = bytesRemaining[4:]\n\t}\n\tp.AddLayer(sc)\n\treturn p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))\n}\n\n// SerializeTo is for gopacket.SerializableLayer.\nfunc (sc SCTPSack) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tlength := 16 + 2*len(sc.GapACKs) + 4*len(sc.DuplicateTSNs)\n\tbytes, err := b.PrependBytes(roundUpToNearest4(length))\n\tif err != nil {\n\t\treturn err\n\t}\n\tbytes[0] = uint8(sc.Type)\n\tbytes[1] = sc.Flags\n\tbinary.BigEndian.PutUint16(bytes[2:4], uint16(length))\n\tbinary.BigEndian.PutUint32(bytes[4:8], sc.CumulativeTSNAck)\n\tbinary.BigEndian.PutUint32(bytes[8:12], sc.AdvertisedReceiverWindowCredit)\n\tbinary.BigEndian.PutUint16(bytes[12:14], uint16(len(sc.GapACKs)))\n\tbinary.BigEndian.PutUint16(bytes[14:16], uint16(len(sc.DuplicateTSNs)))\n\tfor i, v := range sc.GapACKs {\n\t\tbinary.BigEndian.PutUint16(bytes[16+i*2:], v)\n\t}\n\toffset := 16 + 2*len(sc.GapACKs)\n\tfor i, v := range sc.DuplicateTSNs {\n\t\tbinary.BigEndian.PutUint32(bytes[offset+i*4:], v)\n\t}\n\treturn nil\n}\n\n// SCTPHeartbeatParameter is the parameter type used by SCTP heartbeat and\n// heartbeat ack layers.\ntype SCTPHeartbeatParameter SCTPParameter\n\n// SCTPHeartbeat is the SCTP heartbeat layer, also used for heatbeat ack.\ntype SCTPHeartbeat struct {\n\tSCTPChunk\n\tParameters []SCTPHeartbeatParameter\n}\n\n// LayerType returns gopacket.LayerTypeSCTPHeartbeat.\nfunc (sc *SCTPHeartbeat) LayerType() gopacket.LayerType {\n\tif sc.Type == SCTPChunkTypeHeartbeatAck {\n\t\treturn LayerTypeSCTPHeartbeatAck\n\t}\n\t// sc.Type == SCTPChunkTypeHeartbeat\n\treturn LayerTypeSCTPHeartbeat\n}\n\nfunc decodeSCTPHeartbeat(data []byte, p gopacket.PacketBuilder) error {\n\tchunk, err := decodeSCTPChunk(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\tsc := &SCTPHeartbeat{\n\t\tSCTPChunk: chunk,\n\t}\n\tparamData := data[4:sc.Length]\n\tfor len(paramData) > 0 {\n\t\tp := SCTPHeartbeatParameter(decodeSCTPParameter(paramData))\n\t\tparamData = paramData[p.ActualLength:]\n\t\tsc.Parameters = append(sc.Parameters, p)\n\t}\n\tp.AddLayer(sc)\n\treturn p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))\n}\n\n// SerializeTo is for gopacket.SerializableLayer.\nfunc (sc SCTPHeartbeat) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tvar payload []byte\n\tfor _, param := range sc.Parameters {\n\t\tpayload = append(payload, SCTPParameter(param).Bytes()...)\n\t}\n\tlength := 4 + len(payload)\n\n\tbytes, err := b.PrependBytes(roundUpToNearest4(length))\n\tif err != nil {\n\t\treturn err\n\t}\n\tbytes[0] = uint8(sc.Type)\n\tbytes[1] = sc.Flags\n\tbinary.BigEndian.PutUint16(bytes[2:4], uint16(length))\n\tcopy(bytes[4:], payload)\n\treturn nil\n}\n\n// SCTPErrorParameter is the parameter type used by SCTP Abort and Error layers.\ntype SCTPErrorParameter SCTPParameter\n\n// SCTPError is the SCTP error layer, also used for SCTP aborts.\ntype SCTPError struct {\n\tSCTPChunk\n\tParameters []SCTPErrorParameter\n}\n\n// LayerType returns LayerTypeSCTPAbort or LayerTypeSCTPError.\nfunc (sc *SCTPError) LayerType() gopacket.LayerType {\n\tif sc.Type == SCTPChunkTypeAbort {\n\t\treturn LayerTypeSCTPAbort\n\t}\n\t// sc.Type == SCTPChunkTypeError\n\treturn LayerTypeSCTPError\n}\n\nfunc decodeSCTPError(data []byte, p gopacket.PacketBuilder) error {\n\t// remarkably similar to decodeSCTPHeartbeat ;)\n\tchunk, err := decodeSCTPChunk(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\tsc := &SCTPError{\n\t\tSCTPChunk: chunk,\n\t}\n\tparamData := data[4:sc.Length]\n\tfor len(paramData) > 0 {\n\t\tp := SCTPErrorParameter(decodeSCTPParameter(paramData))\n\t\tparamData = paramData[p.ActualLength:]\n\t\tsc.Parameters = append(sc.Parameters, p)\n\t}\n\tp.AddLayer(sc)\n\treturn p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))\n}\n\n// SerializeTo is for gopacket.SerializableLayer.\nfunc (sc SCTPError) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tvar payload []byte\n\tfor _, param := range sc.Parameters {\n\t\tpayload = append(payload, SCTPParameter(param).Bytes()...)\n\t}\n\tlength := 4 + len(payload)\n\n\tbytes, err := b.PrependBytes(roundUpToNearest4(length))\n\tif err != nil {\n\t\treturn err\n\t}\n\tbytes[0] = uint8(sc.Type)\n\tbytes[1] = sc.Flags\n\tbinary.BigEndian.PutUint16(bytes[2:4], uint16(length))\n\tcopy(bytes[4:], payload)\n\treturn nil\n}\n\n// SCTPShutdown is the SCTP shutdown layer.\ntype SCTPShutdown struct {\n\tSCTPChunk\n\tCumulativeTSNAck uint32\n}\n\n// LayerType returns gopacket.LayerTypeSCTPShutdown.\nfunc (sc *SCTPShutdown) LayerType() gopacket.LayerType { return LayerTypeSCTPShutdown }\n\nfunc decodeSCTPShutdown(data []byte, p gopacket.PacketBuilder) error {\n\tchunk, err := decodeSCTPChunk(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\tsc := &SCTPShutdown{\n\t\tSCTPChunk:        chunk,\n\t\tCumulativeTSNAck: binary.BigEndian.Uint32(data[4:8]),\n\t}\n\tp.AddLayer(sc)\n\treturn p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))\n}\n\n// SerializeTo is for gopacket.SerializableLayer.\nfunc (sc SCTPShutdown) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbytes, err := b.PrependBytes(8)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbytes[0] = uint8(sc.Type)\n\tbytes[1] = sc.Flags\n\tbinary.BigEndian.PutUint16(bytes[2:4], 8)\n\tbinary.BigEndian.PutUint32(bytes[4:8], sc.CumulativeTSNAck)\n\treturn nil\n}\n\n// SCTPShutdownAck is the SCTP shutdown layer.\ntype SCTPShutdownAck struct {\n\tSCTPChunk\n}\n\n// LayerType returns gopacket.LayerTypeSCTPShutdownAck.\nfunc (sc *SCTPShutdownAck) LayerType() gopacket.LayerType { return LayerTypeSCTPShutdownAck }\n\nfunc decodeSCTPShutdownAck(data []byte, p gopacket.PacketBuilder) error {\n\tchunk, err := decodeSCTPChunk(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\tsc := &SCTPShutdownAck{\n\t\tSCTPChunk: chunk,\n\t}\n\tp.AddLayer(sc)\n\treturn p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))\n}\n\n// SerializeTo is for gopacket.SerializableLayer.\nfunc (sc SCTPShutdownAck) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbytes, err := b.PrependBytes(4)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbytes[0] = uint8(sc.Type)\n\tbytes[1] = sc.Flags\n\tbinary.BigEndian.PutUint16(bytes[2:4], 4)\n\treturn nil\n}\n\n// SCTPCookieEcho is the SCTP Cookie Echo layer.\ntype SCTPCookieEcho struct {\n\tSCTPChunk\n\tCookie []byte\n}\n\n// LayerType returns gopacket.LayerTypeSCTPCookieEcho.\nfunc (sc *SCTPCookieEcho) LayerType() gopacket.LayerType { return LayerTypeSCTPCookieEcho }\n\nfunc decodeSCTPCookieEcho(data []byte, p gopacket.PacketBuilder) error {\n\tchunk, err := decodeSCTPChunk(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\tsc := &SCTPCookieEcho{\n\t\tSCTPChunk: chunk,\n\t}\n\tsc.Cookie = data[4:sc.Length]\n\tp.AddLayer(sc)\n\treturn p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))\n}\n\n// SerializeTo is for gopacket.SerializableLayer.\nfunc (sc SCTPCookieEcho) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tlength := 4 + len(sc.Cookie)\n\tbytes, err := b.PrependBytes(roundUpToNearest4(length))\n\tif err != nil {\n\t\treturn err\n\t}\n\tbytes[0] = uint8(sc.Type)\n\tbytes[1] = sc.Flags\n\tbinary.BigEndian.PutUint16(bytes[2:4], uint16(length))\n\tcopy(bytes[4:], sc.Cookie)\n\treturn nil\n}\n\n// This struct is used by all empty SCTP chunks (currently CookieAck and\n// ShutdownComplete).\ntype SCTPEmptyLayer struct {\n\tSCTPChunk\n}\n\n// LayerType returns either gopacket.LayerTypeSCTPShutdownComplete or\n// LayerTypeSCTPCookieAck.\nfunc (sc *SCTPEmptyLayer) LayerType() gopacket.LayerType {\n\tif sc.Type == SCTPChunkTypeShutdownComplete {\n\t\treturn LayerTypeSCTPShutdownComplete\n\t}\n\t// sc.Type == SCTPChunkTypeCookieAck\n\treturn LayerTypeSCTPCookieAck\n}\n\nfunc decodeSCTPEmptyLayer(data []byte, p gopacket.PacketBuilder) error {\n\tchunk, err := decodeSCTPChunk(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\tsc := &SCTPEmptyLayer{\n\t\tSCTPChunk: chunk,\n\t}\n\tp.AddLayer(sc)\n\treturn p.NextDecoder(gopacket.DecodeFunc(decodeWithSCTPChunkTypePrefix))\n}\n\n// SerializeTo is for gopacket.SerializableLayer.\nfunc (sc SCTPEmptyLayer) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbytes, err := b.PrependBytes(4)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbytes[0] = uint8(sc.Type)\n\tbytes[1] = sc.Flags\n\tbinary.BigEndian.PutUint16(bytes[2:4], 4)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/sflow.go",
    "content": "// Copyright 2014 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\n/*\nThis layer decodes SFlow version 5 datagrams.\n\nThe specification can be found here: http://sflow.org/sflow_version_5.txt\n\nAdditional developer information about sflow can be found at:\nhttp://sflow.org/developers/specifications.php\n\nAnd SFlow in general:\nhttp://sflow.org/index.php\n\nTwo forms of sample data are defined: compact and expanded. The\nSpecification has this to say:\n\n    Compact and expand forms of counter and flow samples are defined.\n    An agent must not mix compact/expanded encodings.  If an agent\n    will never use ifIndex numbers >= 2^24 then it must use compact\n    encodings for all interfaces.  Otherwise the expanded formats must\n    be used for all interfaces.\n\nThis decoder only supports the compact form, because that is the only\none for which data was available.\n\nThe datagram is composed of one or more samples of type flow or counter,\nand each sample is composed of one or more records describing the sample.\nA sample is a single instance of sampled inforamtion, and each record in\nthe sample gives additional / supplimentary information about the sample.\n\nThe following sample record types are supported:\n\n\tRaw Packet Header\n\topaque = flow_data; enterprise = 0; format = 1\n\n\tExtended Switch Data\n\topaque = flow_data; enterprise = 0; format = 1001\n\n\tExtended Router Data\n\topaque = flow_data; enterprise = 0; format = 1002\n\n\tExtended Gateway Data\n\topaque = flow_data; enterprise = 0; format = 1003\n\n\tExtended User Data\n\topaque = flow_data; enterprise = 0; format = 1004\n\n\tExtended URL Data\n\topaque = flow_data; enterprise = 0; format = 1005\n\nThe following types of counter records are supported:\n\n\tGeneric Interface Counters - see RFC 2233\n\topaque = counter_data; enterprise = 0; format = 1\n\n\tEthernet Interface Counters - see RFC 2358\n\topaque = counter_data; enterprise = 0; format = 2\n\nSFlow is encoded using XDR (RFC4506). There are a few places\nwhere the standard 4-byte fields are partitioned into two\nbitfields of different lengths. I'm not sure why the designers\nchose to pack together two values like this in some places, and\nin others they use the entire 4-byte value to store a number that\nwill never be more than a few bits. In any case, there are a couple\nof types defined to handle the decoding of these bitfields, and\nthat's why they're there. */\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// SFlowRecord holds both flow sample records and counter sample records.\n// A Record is the structure that actually holds the sampled data\n// and / or counters.\ntype SFlowRecord interface {\n}\n\n// SFlowDataSource encodes a 2-bit SFlowSourceFormat in its most significant\n// 2 bits, and an SFlowSourceValue in its least significant 30 bits.\n// These types and values define the meaning of the inteface information\n// presented in the sample metadata.\ntype SFlowDataSource int32\n\nfunc (sdc SFlowDataSource) decode() (SFlowSourceFormat, SFlowSourceValue) {\n\tleftField := sdc >> 30\n\trightField := uint32(0x3FFFFFFF) & uint32(sdc)\n\treturn SFlowSourceFormat(leftField), SFlowSourceValue(rightField)\n}\n\ntype SFlowDataSourceExpanded struct {\n\tSourceIDClass SFlowSourceFormat\n\tSourceIDIndex SFlowSourceValue\n}\n\nfunc (sdce SFlowDataSourceExpanded) decode() (SFlowSourceFormat, SFlowSourceValue) {\n\tleftField := sdce.SourceIDClass >> 30\n\trightField := uint32(0x3FFFFFFF) & uint32(sdce.SourceIDIndex)\n\treturn SFlowSourceFormat(leftField), SFlowSourceValue(rightField)\n}\n\ntype SFlowSourceFormat uint32\n\ntype SFlowSourceValue uint32\n\nconst (\n\tSFlowTypeSingleInterface      SFlowSourceFormat = 0\n\tSFlowTypePacketDiscarded      SFlowSourceFormat = 1\n\tSFlowTypeMultipleDestinations SFlowSourceFormat = 2\n)\n\nfunc (sdf SFlowSourceFormat) String() string {\n\tswitch sdf {\n\tcase SFlowTypeSingleInterface:\n\t\treturn \"Single Interface\"\n\tcase SFlowTypePacketDiscarded:\n\t\treturn \"Packet Discarded\"\n\tcase SFlowTypeMultipleDestinations:\n\t\treturn \"Multiple Destinations\"\n\tdefault:\n\t\treturn \"UNKNOWN\"\n\t}\n}\n\nfunc decodeSFlow(data []byte, p gopacket.PacketBuilder) error {\n\ts := &SFlowDatagram{}\n\terr := s.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\tp.AddLayer(s)\n\tp.SetApplicationLayer(s)\n\treturn nil\n}\n\n// SFlowDatagram is the outermost container which holds some basic information\n// about the reporting agent, and holds at least one sample record\ntype SFlowDatagram struct {\n\tBaseLayer\n\n\tDatagramVersion uint32\n\tAgentAddress    net.IP\n\tSubAgentID      uint32\n\tSequenceNumber  uint32\n\tAgentUptime     uint32\n\tSampleCount     uint32\n\tFlowSamples     []SFlowFlowSample\n\tCounterSamples  []SFlowCounterSample\n}\n\n// An SFlow  datagram's outer container has the following\n// structure:\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |           int sFlow version (2|4|5)           |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |   int IP version of the Agent (1=v4|2=v6)     |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  /    Agent IP address (v4=4byte|v6=16byte)      /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |               int sub agent id                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |         int datagram sequence number          |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |            int switch uptime in ms            |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |          int n samples in datagram            |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  /                  n samples                    /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\n// SFlowDataFormat encodes the EnterpriseID in the most\n// significant 12 bits, and the SampleType in the least significant\n// 20 bits.\ntype SFlowDataFormat uint32\n\nfunc (sdf SFlowDataFormat) decode() (SFlowEnterpriseID, SFlowSampleType) {\n\tleftField := sdf >> 12\n\trightField := uint32(0xFFF) & uint32(sdf)\n\treturn SFlowEnterpriseID(leftField), SFlowSampleType(rightField)\n}\n\n// SFlowEnterpriseID is used to differentiate between the\n// official SFlow standard, and other, vendor-specific\n// types of flow data. (Similiar to SNMP's enterprise MIB\n// OIDs) Only the office SFlow Enterprise ID is decoded\n// here.\ntype SFlowEnterpriseID uint32\n\nconst (\n\tSFlowStandard SFlowEnterpriseID = 0\n)\n\nfunc (eid SFlowEnterpriseID) String() string {\n\tswitch eid {\n\tcase SFlowStandard:\n\t\treturn \"Standard SFlow\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\nfunc (eid SFlowEnterpriseID) GetType() SFlowEnterpriseID {\n\treturn SFlowStandard\n}\n\n// SFlowSampleType specifies the type of sample. Only flow samples\n// and counter samples are supported\ntype SFlowSampleType uint32\n\nconst (\n\tSFlowTypeFlowSample            SFlowSampleType = 1\n\tSFlowTypeCounterSample         SFlowSampleType = 2\n\tSFlowTypeExpandedFlowSample    SFlowSampleType = 3\n\tSFlowTypeExpandedCounterSample SFlowSampleType = 4\n)\n\nfunc (st SFlowSampleType) GetType() SFlowSampleType {\n\tswitch st {\n\tcase SFlowTypeFlowSample:\n\t\treturn SFlowTypeFlowSample\n\tcase SFlowTypeCounterSample:\n\t\treturn SFlowTypeCounterSample\n\tcase SFlowTypeExpandedFlowSample:\n\t\treturn SFlowTypeExpandedFlowSample\n\tcase SFlowTypeExpandedCounterSample:\n\t\treturn SFlowTypeExpandedCounterSample\n\tdefault:\n\t\tpanic(\"Invalid Sample Type\")\n\t}\n}\n\nfunc (st SFlowSampleType) String() string {\n\tswitch st {\n\tcase SFlowTypeFlowSample:\n\t\treturn \"Flow Sample\"\n\tcase SFlowTypeCounterSample:\n\t\treturn \"Counter Sample\"\n\tcase SFlowTypeExpandedFlowSample:\n\t\treturn \"Expanded Flow Sample\"\n\tcase SFlowTypeExpandedCounterSample:\n\t\treturn \"Expanded Counter Sample\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\nfunc (s *SFlowDatagram) LayerType() gopacket.LayerType { return LayerTypeSFlow }\n\nfunc (d *SFlowDatagram) Payload() []byte { return nil }\n\nfunc (d *SFlowDatagram) CanDecode() gopacket.LayerClass { return LayerTypeSFlow }\n\nfunc (d *SFlowDatagram) NextLayerType() gopacket.LayerType { return gopacket.LayerTypePayload }\n\n// SFlowIPType determines what form the IP address being decoded will\n// take. This is an XDR union type allowing for both IPv4 and IPv6\ntype SFlowIPType uint32\n\nconst (\n\tSFlowIPv4 SFlowIPType = 1\n\tSFlowIPv6 SFlowIPType = 2\n)\n\nfunc (s SFlowIPType) String() string {\n\tswitch s {\n\tcase SFlowIPv4:\n\t\treturn \"IPv4\"\n\tcase SFlowIPv6:\n\t\treturn \"IPv6\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\nfunc (s SFlowIPType) Length() int {\n\tswitch s {\n\tcase SFlowIPv4:\n\t\treturn 4\n\tcase SFlowIPv6:\n\t\treturn 16\n\tdefault:\n\t\treturn 0\n\t}\n}\n\nfunc (s *SFlowDatagram) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tvar agentAddressType SFlowIPType\n\n\tdata, s.DatagramVersion = data[4:], binary.BigEndian.Uint32(data[:4])\n\tdata, agentAddressType = data[4:], SFlowIPType(binary.BigEndian.Uint32(data[:4]))\n\tdata, s.AgentAddress = data[agentAddressType.Length():], data[:agentAddressType.Length()]\n\tdata, s.SubAgentID = data[4:], binary.BigEndian.Uint32(data[:4])\n\tdata, s.SequenceNumber = data[4:], binary.BigEndian.Uint32(data[:4])\n\tdata, s.AgentUptime = data[4:], binary.BigEndian.Uint32(data[:4])\n\tdata, s.SampleCount = data[4:], binary.BigEndian.Uint32(data[:4])\n\n\tif s.SampleCount < 1 {\n\t\treturn fmt.Errorf(\"SFlow Datagram has invalid sample length: %d\", s.SampleCount)\n\t}\n\tfor i := uint32(0); i < s.SampleCount; i++ {\n\t\tsdf := SFlowDataFormat(binary.BigEndian.Uint32(data[:4]))\n\t\t_, sampleType := sdf.decode()\n\t\tswitch sampleType {\n\t\tcase SFlowTypeFlowSample:\n\t\t\tif flowSample, err := decodeFlowSample(&data, false); err == nil {\n\t\t\t\ts.FlowSamples = append(s.FlowSamples, flowSample)\n\t\t\t} else {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase SFlowTypeCounterSample:\n\t\t\tif counterSample, err := decodeCounterSample(&data, false); err == nil {\n\t\t\t\ts.CounterSamples = append(s.CounterSamples, counterSample)\n\t\t\t} else {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase SFlowTypeExpandedFlowSample:\n\t\t\tif flowSample, err := decodeFlowSample(&data, true); err == nil {\n\t\t\t\ts.FlowSamples = append(s.FlowSamples, flowSample)\n\t\t\t} else {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase SFlowTypeExpandedCounterSample:\n\t\t\tif counterSample, err := decodeCounterSample(&data, true); err == nil {\n\t\t\t\ts.CounterSamples = append(s.CounterSamples, counterSample)\n\t\t\t} else {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"Unsupported SFlow sample type %d\", sampleType)\n\t\t}\n\t}\n\treturn nil\n}\n\n// SFlowFlowSample represents a sampled packet and contains\n// one or more records describing the packet\ntype SFlowFlowSample struct {\n\tEnterpriseID          SFlowEnterpriseID\n\tFormat                SFlowSampleType\n\tSampleLength          uint32\n\tSequenceNumber        uint32\n\tSourceIDClass         SFlowSourceFormat\n\tSourceIDIndex         SFlowSourceValue\n\tSamplingRate          uint32\n\tSamplePool            uint32\n\tDropped               uint32\n\tInputInterfaceFormat  uint32\n\tInputInterface        uint32\n\tOutputInterfaceFormat uint32\n\tOutputInterface       uint32\n\tRecordCount           uint32\n\tRecords               []SFlowRecord\n}\n\n// Flow samples have the following structure. Note\n// the bit fields to encode the Enterprise ID and the\n// Flow record format: type 1\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  sample length                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |          int sample sequence number           |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |id type |       src id index value             |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |               int sampling rate               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                int sample pool                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    int drops                  |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                 int input ifIndex             |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                int output ifIndex             |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |               int number of records           |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  /                   flow records                /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\n// Flow samples have the following structure.\n// Flow record format: type 3\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  sample length                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |          int sample sequence number           |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |               int src id type                 |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |             int src id index value            |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |               int sampling rate               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                int sample pool                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    int drops                  |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |           int input interface format          |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |           int input interface value           |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |           int output interface format         |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |           int output interface value          |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |               int number of records           |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  /                   flow records                /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\ntype SFlowFlowDataFormat uint32\n\nfunc (fdf SFlowFlowDataFormat) decode() (SFlowEnterpriseID, SFlowFlowRecordType) {\n\tleftField := fdf >> 12\n\trightField := uint32(0xFFF) & uint32(fdf)\n\treturn SFlowEnterpriseID(leftField), SFlowFlowRecordType(rightField)\n}\n\nfunc (fs SFlowFlowSample) GetRecords() []SFlowRecord {\n\treturn fs.Records\n}\n\nfunc (fs SFlowFlowSample) GetType() SFlowSampleType {\n\treturn SFlowTypeFlowSample\n}\n\nfunc skipRecord(data *[]byte) {\n\trecordLength := int(binary.BigEndian.Uint32((*data)[4:]))\n\t*data = (*data)[(recordLength+((4-recordLength)%4))+8:]\n}\n\nfunc decodeFlowSample(data *[]byte, expanded bool) (SFlowFlowSample, error) {\n\ts := SFlowFlowSample{}\n\tvar sdf SFlowDataFormat\n\t*data, sdf = (*data)[4:], SFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\tvar sdc SFlowDataSource\n\n\ts.EnterpriseID, s.Format = sdf.decode()\n\tif len(*data) < 4 {\n\t\treturn SFlowFlowSample{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, s.SampleLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif len(*data) < 4 {\n\t\treturn SFlowFlowSample{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, s.SequenceNumber = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif expanded {\n\t\tif len(*data) < 4 {\n\t\t\treturn SFlowFlowSample{}, errors.New(\"ethernet counters too small\")\n\t\t}\n\t\t*data, s.SourceIDClass = (*data)[4:], SFlowSourceFormat(binary.BigEndian.Uint32((*data)[:4]))\n\t\tif len(*data) < 4 {\n\t\t\treturn SFlowFlowSample{}, errors.New(\"ethernet counters too small\")\n\t\t}\n\t\t*data, s.SourceIDIndex = (*data)[4:], SFlowSourceValue(binary.BigEndian.Uint32((*data)[:4]))\n\t} else {\n\t\tif len(*data) < 4 {\n\t\t\treturn SFlowFlowSample{}, errors.New(\"ethernet counters too small\")\n\t\t}\n\t\t*data, sdc = (*data)[4:], SFlowDataSource(binary.BigEndian.Uint32((*data)[:4]))\n\t\ts.SourceIDClass, s.SourceIDIndex = sdc.decode()\n\t}\n\tif len(*data) < 4 {\n\t\treturn SFlowFlowSample{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, s.SamplingRate = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif len(*data) < 4 {\n\t\treturn SFlowFlowSample{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, s.SamplePool = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif len(*data) < 4 {\n\t\treturn SFlowFlowSample{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, s.Dropped = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\n\tif expanded {\n\t\tif len(*data) < 4 {\n\t\t\treturn SFlowFlowSample{}, errors.New(\"ethernet counters too small\")\n\t\t}\n\t\t*data, s.InputInterfaceFormat = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t\tif len(*data) < 4 {\n\t\t\treturn SFlowFlowSample{}, errors.New(\"ethernet counters too small\")\n\t\t}\n\t\t*data, s.InputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t\tif len(*data) < 4 {\n\t\t\treturn SFlowFlowSample{}, errors.New(\"ethernet counters too small\")\n\t\t}\n\t\t*data, s.OutputInterfaceFormat = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t\tif len(*data) < 4 {\n\t\t\treturn SFlowFlowSample{}, errors.New(\"ethernet counters too small\")\n\t\t}\n\t\t*data, s.OutputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t} else {\n\t\tif len(*data) < 4 {\n\t\t\treturn SFlowFlowSample{}, errors.New(\"ethernet counters too small\")\n\t\t}\n\t\t*data, s.InputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t\tif len(*data) < 4 {\n\t\t\treturn SFlowFlowSample{}, errors.New(\"ethernet counters too small\")\n\t\t}\n\t\t*data, s.OutputInterface = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t}\n\tif len(*data) < 4 {\n\t\treturn SFlowFlowSample{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, s.RecordCount = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\n\tfor i := uint32(0); i < s.RecordCount; i++ {\n\t\trdf := SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\t\tenterpriseID, flowRecordType := rdf.decode()\n\n\t\t// Try to decode when EnterpriseID is 0 signaling\n\t\t// default sflow structs are used according specification\n\t\t// Unexpected behavior detected for e.g. with pmacct\n\t\tif enterpriseID == 0 {\n\t\t\tswitch flowRecordType {\n\t\t\tcase SFlowTypeRawPacketFlow:\n\t\t\t\tif record, err := decodeRawPacketFlowRecord(data); err == nil {\n\t\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t\t} else {\n\t\t\t\t\treturn s, err\n\t\t\t\t}\n\t\t\tcase SFlowTypeExtendedUserFlow:\n\t\t\t\tif record, err := decodeExtendedUserFlow(data); err == nil {\n\t\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t\t} else {\n\t\t\t\t\treturn s, err\n\t\t\t\t}\n\t\t\tcase SFlowTypeExtendedUrlFlow:\n\t\t\t\tif record, err := decodeExtendedURLRecord(data); err == nil {\n\t\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t\t} else {\n\t\t\t\t\treturn s, err\n\t\t\t\t}\n\t\t\tcase SFlowTypeExtendedSwitchFlow:\n\t\t\t\tif record, err := decodeExtendedSwitchFlowRecord(data); err == nil {\n\t\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t\t} else {\n\t\t\t\t\treturn s, err\n\t\t\t\t}\n\t\t\tcase SFlowTypeExtendedRouterFlow:\n\t\t\t\tif record, err := decodeExtendedRouterFlowRecord(data); err == nil {\n\t\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t\t} else {\n\t\t\t\t\treturn s, err\n\t\t\t\t}\n\t\t\tcase SFlowTypeExtendedGatewayFlow:\n\t\t\t\tif record, err := decodeExtendedGatewayFlowRecord(data); err == nil {\n\t\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t\t} else {\n\t\t\t\t\treturn s, err\n\t\t\t\t}\n\t\t\tcase SFlowTypeEthernetFrameFlow:\n\t\t\t\tif record, err := decodeEthernetFrameFlowRecord(data); err == nil {\n\t\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t\t} else {\n\t\t\t\t\treturn s, err\n\t\t\t\t}\n\t\t\tcase SFlowTypeIpv4Flow:\n\t\t\t\tif record, err := decodeSFlowIpv4Record(data); err == nil {\n\t\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t\t} else {\n\t\t\t\t\treturn s, err\n\t\t\t\t}\n\t\t\tcase SFlowTypeIpv6Flow:\n\t\t\t\tif record, err := decodeSFlowIpv6Record(data); err == nil {\n\t\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t\t} else {\n\t\t\t\t\treturn s, err\n\t\t\t\t}\n\t\t\tcase SFlowTypeExtendedMlpsFlow:\n\t\t\t\t// TODO\n\t\t\t\tskipRecord(data)\n\t\t\t\treturn s, errors.New(\"skipping TypeExtendedMlpsFlow\")\n\t\t\tcase SFlowTypeExtendedNatFlow:\n\t\t\t\t// TODO\n\t\t\t\tskipRecord(data)\n\t\t\t\treturn s, errors.New(\"skipping TypeExtendedNatFlow\")\n\t\t\tcase SFlowTypeExtendedMlpsTunnelFlow:\n\t\t\t\t// TODO\n\t\t\t\tskipRecord(data)\n\t\t\t\treturn s, errors.New(\"skipping TypeExtendedMlpsTunnelFlow\")\n\t\t\tcase SFlowTypeExtendedMlpsVcFlow:\n\t\t\t\t// TODO\n\t\t\t\tskipRecord(data)\n\t\t\t\treturn s, errors.New(\"skipping TypeExtendedMlpsVcFlow\")\n\t\t\tcase SFlowTypeExtendedMlpsFecFlow:\n\t\t\t\t// TODO\n\t\t\t\tskipRecord(data)\n\t\t\t\treturn s, errors.New(\"skipping TypeExtendedMlpsFecFlow\")\n\t\t\tcase SFlowTypeExtendedMlpsLvpFecFlow:\n\t\t\t\t// TODO\n\t\t\t\tskipRecord(data)\n\t\t\t\treturn s, errors.New(\"skipping TypeExtendedMlpsLvpFecFlow\")\n\t\t\tcase SFlowTypeExtendedVlanFlow:\n\t\t\t\t// TODO\n\t\t\t\tskipRecord(data)\n\t\t\t\treturn s, errors.New(\"skipping TypeExtendedVlanFlow\")\n\t\t\tcase SFlowTypeExtendedIpv4TunnelEgressFlow:\n\t\t\t\tif record, err := decodeExtendedIpv4TunnelEgress(data); err == nil {\n\t\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t\t} else {\n\t\t\t\t\treturn s, err\n\t\t\t\t}\n\t\t\tcase SFlowTypeExtendedIpv4TunnelIngressFlow:\n\t\t\t\tif record, err := decodeExtendedIpv4TunnelIngress(data); err == nil {\n\t\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t\t} else {\n\t\t\t\t\treturn s, err\n\t\t\t\t}\n\t\t\tcase SFlowTypeExtendedIpv6TunnelEgressFlow:\n\t\t\t\tif record, err := decodeExtendedIpv6TunnelEgress(data); err == nil {\n\t\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t\t} else {\n\t\t\t\t\treturn s, err\n\t\t\t\t}\n\t\t\tcase SFlowTypeExtendedIpv6TunnelIngressFlow:\n\t\t\t\tif record, err := decodeExtendedIpv6TunnelIngress(data); err == nil {\n\t\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t\t} else {\n\t\t\t\t\treturn s, err\n\t\t\t\t}\n\t\t\tcase SFlowTypeExtendedDecapsulateEgressFlow:\n\t\t\t\tif record, err := decodeExtendedDecapsulateEgress(data); err == nil {\n\t\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t\t} else {\n\t\t\t\t\treturn s, err\n\t\t\t\t}\n\t\t\tcase SFlowTypeExtendedDecapsulateIngressFlow:\n\t\t\t\tif record, err := decodeExtendedDecapsulateIngress(data); err == nil {\n\t\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t\t} else {\n\t\t\t\t\treturn s, err\n\t\t\t\t}\n\t\t\tcase SFlowTypeExtendedVniEgressFlow:\n\t\t\t\tif record, err := decodeExtendedVniEgress(data); err == nil {\n\t\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t\t} else {\n\t\t\t\t\treturn s, err\n\t\t\t\t}\n\t\t\tcase SFlowTypeExtendedVniIngressFlow:\n\t\t\t\tif record, err := decodeExtendedVniIngress(data); err == nil {\n\t\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t\t} else {\n\t\t\t\t\treturn s, err\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn s, fmt.Errorf(\"Unsupported flow record type: %d\", flowRecordType)\n\t\t\t}\n\t\t} else {\n\t\t\tskipRecord(data)\n\t\t}\n\t}\n\treturn s, nil\n}\n\n// Counter samples report information about various counter\n// objects. Typically these are items like IfInOctets, or\n// CPU / Memory stats, etc. SFlow will report these at regular\n// intervals as configured on the agent. If one were sufficiently\n// industrious, this could be used to replace the typical\n// SNMP polling used for such things.\ntype SFlowCounterSample struct {\n\tEnterpriseID   SFlowEnterpriseID\n\tFormat         SFlowSampleType\n\tSampleLength   uint32\n\tSequenceNumber uint32\n\tSourceIDClass  SFlowSourceFormat\n\tSourceIDIndex  SFlowSourceValue\n\tRecordCount    uint32\n\tRecords        []SFlowRecord\n}\n\n// Counter samples have the following structure:\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |          int sample sequence number           |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |id type |       src id index value             |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |               int number of records           |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  /                counter records                /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\ntype SFlowCounterDataFormat uint32\n\nfunc (cdf SFlowCounterDataFormat) decode() (SFlowEnterpriseID, SFlowCounterRecordType) {\n\tleftField := cdf >> 12\n\trightField := uint32(0xFFF) & uint32(cdf)\n\treturn SFlowEnterpriseID(leftField), SFlowCounterRecordType(rightField)\n}\n\n// GetRecords will return a slice of interface types\n// representing records. A type switch can be used to\n// get at the underlying SFlowCounterRecordType.\nfunc (cs SFlowCounterSample) GetRecords() []SFlowRecord {\n\treturn cs.Records\n}\n\n// GetType will report the type of sample. Only the\n// compact form of counter samples is supported\nfunc (cs SFlowCounterSample) GetType() SFlowSampleType {\n\treturn SFlowTypeCounterSample\n}\n\ntype SFlowCounterRecordType uint32\n\nconst (\n\tSFlowTypeGenericInterfaceCounters   SFlowCounterRecordType = 1\n\tSFlowTypeEthernetInterfaceCounters  SFlowCounterRecordType = 2\n\tSFlowTypeTokenRingInterfaceCounters SFlowCounterRecordType = 3\n\tSFlowType100BaseVGInterfaceCounters SFlowCounterRecordType = 4\n\tSFlowTypeVLANCounters               SFlowCounterRecordType = 5\n\tSFlowTypeLACPCounters               SFlowCounterRecordType = 7\n\tSFlowTypeProcessorCounters          SFlowCounterRecordType = 1001\n\tSFlowTypeOpenflowPortCounters       SFlowCounterRecordType = 1004\n\tSFlowTypePORTNAMECounters           SFlowCounterRecordType = 1005\n\tSFLowTypeAPPRESOURCESCounters       SFlowCounterRecordType = 2203\n\tSFlowTypeOVSDPCounters              SFlowCounterRecordType = 2207\n)\n\nfunc (cr SFlowCounterRecordType) String() string {\n\tswitch cr {\n\tcase SFlowTypeGenericInterfaceCounters:\n\t\treturn \"Generic Interface Counters\"\n\tcase SFlowTypeEthernetInterfaceCounters:\n\t\treturn \"Ethernet Interface Counters\"\n\tcase SFlowTypeTokenRingInterfaceCounters:\n\t\treturn \"Token Ring Interface Counters\"\n\tcase SFlowType100BaseVGInterfaceCounters:\n\t\treturn \"100BaseVG Interface Counters\"\n\tcase SFlowTypeVLANCounters:\n\t\treturn \"VLAN Counters\"\n\tcase SFlowTypeLACPCounters:\n\t\treturn \"LACP Counters\"\n\tcase SFlowTypeProcessorCounters:\n\t\treturn \"Processor Counters\"\n\tcase SFlowTypeOpenflowPortCounters:\n\t\treturn \"Openflow Port Counters\"\n\tcase SFlowTypePORTNAMECounters:\n\t\treturn \"PORT NAME Counters\"\n\tcase SFLowTypeAPPRESOURCESCounters:\n\t\treturn \"App Resources Counters\"\n\tcase SFlowTypeOVSDPCounters:\n\t\treturn \"OVSDP Counters\"\n\tdefault:\n\t\treturn \"\"\n\n\t}\n}\n\nfunc decodeCounterSample(data *[]byte, expanded bool) (SFlowCounterSample, error) {\n\ts := SFlowCounterSample{}\n\tvar sdc SFlowDataSource\n\tvar sdce SFlowDataSourceExpanded\n\tvar sdf SFlowDataFormat\n\n\t*data, sdf = (*data)[4:], SFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\ts.EnterpriseID, s.Format = sdf.decode()\n\t*data, s.SampleLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, s.SequenceNumber = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif expanded {\n\t\t*data, sdce = (*data)[8:], SFlowDataSourceExpanded{SFlowSourceFormat(binary.BigEndian.Uint32((*data)[:4])), SFlowSourceValue(binary.BigEndian.Uint32((*data)[4:8]))}\n\t\ts.SourceIDClass, s.SourceIDIndex = sdce.decode()\n\t} else {\n\t\t*data, sdc = (*data)[4:], SFlowDataSource(binary.BigEndian.Uint32((*data)[:4]))\n\t\ts.SourceIDClass, s.SourceIDIndex = sdc.decode()\n\t}\n\t*data, s.RecordCount = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\n\tfor i := uint32(0); i < s.RecordCount; i++ {\n\t\tcdf := SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\t\t_, counterRecordType := cdf.decode()\n\t\tswitch counterRecordType {\n\t\tcase SFlowTypeGenericInterfaceCounters:\n\t\t\tif record, err := decodeGenericInterfaceCounters(data); err == nil {\n\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t} else {\n\t\t\t\treturn s, err\n\t\t\t}\n\t\tcase SFlowTypeEthernetInterfaceCounters:\n\t\t\tif record, err := decodeEthernetCounters(data); err == nil {\n\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t} else {\n\t\t\t\treturn s, err\n\t\t\t}\n\t\tcase SFlowTypeTokenRingInterfaceCounters:\n\t\t\tskipRecord(data)\n\t\t\treturn s, errors.New(\"skipping TypeTokenRingInterfaceCounters\")\n\t\tcase SFlowType100BaseVGInterfaceCounters:\n\t\t\tskipRecord(data)\n\t\t\treturn s, errors.New(\"skipping Type100BaseVGInterfaceCounters\")\n\t\tcase SFlowTypeVLANCounters:\n\t\t\tif record, err := decodeVLANCounters(data); err == nil {\n\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t} else {\n\t\t\t\treturn s, err\n\t\t\t}\n\t\tcase SFlowTypeLACPCounters:\n\t\t\tif record, err := decodeLACPCounters(data); err == nil {\n\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t} else {\n\t\t\t\treturn s, err\n\t\t\t}\n\t\tcase SFlowTypeProcessorCounters:\n\t\t\tif record, err := decodeProcessorCounters(data); err == nil {\n\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t} else {\n\t\t\t\treturn s, err\n\t\t\t}\n\t\tcase SFlowTypeOpenflowPortCounters:\n\t\t\tif record, err := decodeOpenflowportCounters(data); err == nil {\n\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t} else {\n\t\t\t\treturn s, err\n\t\t\t}\n\t\tcase SFlowTypePORTNAMECounters:\n\t\t\tif record, err := decodePortnameCounters(data); err == nil {\n\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t} else {\n\t\t\t\treturn s, err\n\t\t\t}\n\t\tcase SFLowTypeAPPRESOURCESCounters:\n\t\t\tif record, err := decodeAppresourcesCounters(data); err == nil {\n\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t} else {\n\t\t\t\treturn s, err\n\t\t\t}\n\t\tcase SFlowTypeOVSDPCounters:\n\t\t\tif record, err := decodeOVSDPCounters(data); err == nil {\n\t\t\t\ts.Records = append(s.Records, record)\n\t\t\t} else {\n\t\t\t\treturn s, err\n\t\t\t}\n\t\tdefault:\n\t\t\treturn s, fmt.Errorf(\"Invalid counter record type: %d\", counterRecordType)\n\t\t}\n\t}\n\treturn s, nil\n}\n\n// SFlowBaseFlowRecord holds the fields common to all records\n// of type SFlowFlowRecordType\ntype SFlowBaseFlowRecord struct {\n\tEnterpriseID   SFlowEnterpriseID\n\tFormat         SFlowFlowRecordType\n\tFlowDataLength uint32\n}\n\nfunc (bfr SFlowBaseFlowRecord) GetType() SFlowFlowRecordType {\n\treturn bfr.Format\n}\n\n// SFlowFlowRecordType denotes what kind of Flow Record is\n// represented. See RFC 3176\ntype SFlowFlowRecordType uint32\n\nconst (\n\tSFlowTypeRawPacketFlow                  SFlowFlowRecordType = 1\n\tSFlowTypeEthernetFrameFlow              SFlowFlowRecordType = 2\n\tSFlowTypeIpv4Flow                       SFlowFlowRecordType = 3\n\tSFlowTypeIpv6Flow                       SFlowFlowRecordType = 4\n\tSFlowTypeExtendedSwitchFlow             SFlowFlowRecordType = 1001\n\tSFlowTypeExtendedRouterFlow             SFlowFlowRecordType = 1002\n\tSFlowTypeExtendedGatewayFlow            SFlowFlowRecordType = 1003\n\tSFlowTypeExtendedUserFlow               SFlowFlowRecordType = 1004\n\tSFlowTypeExtendedUrlFlow                SFlowFlowRecordType = 1005\n\tSFlowTypeExtendedMlpsFlow               SFlowFlowRecordType = 1006\n\tSFlowTypeExtendedNatFlow                SFlowFlowRecordType = 1007\n\tSFlowTypeExtendedMlpsTunnelFlow         SFlowFlowRecordType = 1008\n\tSFlowTypeExtendedMlpsVcFlow             SFlowFlowRecordType = 1009\n\tSFlowTypeExtendedMlpsFecFlow            SFlowFlowRecordType = 1010\n\tSFlowTypeExtendedMlpsLvpFecFlow         SFlowFlowRecordType = 1011\n\tSFlowTypeExtendedVlanFlow               SFlowFlowRecordType = 1012\n\tSFlowTypeExtendedIpv4TunnelEgressFlow   SFlowFlowRecordType = 1023\n\tSFlowTypeExtendedIpv4TunnelIngressFlow  SFlowFlowRecordType = 1024\n\tSFlowTypeExtendedIpv6TunnelEgressFlow   SFlowFlowRecordType = 1025\n\tSFlowTypeExtendedIpv6TunnelIngressFlow  SFlowFlowRecordType = 1026\n\tSFlowTypeExtendedDecapsulateEgressFlow  SFlowFlowRecordType = 1027\n\tSFlowTypeExtendedDecapsulateIngressFlow SFlowFlowRecordType = 1028\n\tSFlowTypeExtendedVniEgressFlow          SFlowFlowRecordType = 1029\n\tSFlowTypeExtendedVniIngressFlow         SFlowFlowRecordType = 1030\n)\n\nfunc (rt SFlowFlowRecordType) String() string {\n\tswitch rt {\n\tcase SFlowTypeRawPacketFlow:\n\t\treturn \"Raw Packet Flow Record\"\n\tcase SFlowTypeEthernetFrameFlow:\n\t\treturn \"Ethernet Frame Flow Record\"\n\tcase SFlowTypeIpv4Flow:\n\t\treturn \"IPv4 Flow Record\"\n\tcase SFlowTypeIpv6Flow:\n\t\treturn \"IPv6 Flow Record\"\n\tcase SFlowTypeExtendedSwitchFlow:\n\t\treturn \"Extended Switch Flow Record\"\n\tcase SFlowTypeExtendedRouterFlow:\n\t\treturn \"Extended Router Flow Record\"\n\tcase SFlowTypeExtendedGatewayFlow:\n\t\treturn \"Extended Gateway Flow Record\"\n\tcase SFlowTypeExtendedUserFlow:\n\t\treturn \"Extended User Flow Record\"\n\tcase SFlowTypeExtendedUrlFlow:\n\t\treturn \"Extended URL Flow Record\"\n\tcase SFlowTypeExtendedMlpsFlow:\n\t\treturn \"Extended MPLS Flow Record\"\n\tcase SFlowTypeExtendedNatFlow:\n\t\treturn \"Extended NAT Flow Record\"\n\tcase SFlowTypeExtendedMlpsTunnelFlow:\n\t\treturn \"Extended MPLS Tunnel Flow Record\"\n\tcase SFlowTypeExtendedMlpsVcFlow:\n\t\treturn \"Extended MPLS VC Flow Record\"\n\tcase SFlowTypeExtendedMlpsFecFlow:\n\t\treturn \"Extended MPLS FEC Flow Record\"\n\tcase SFlowTypeExtendedMlpsLvpFecFlow:\n\t\treturn \"Extended MPLS LVP FEC Flow Record\"\n\tcase SFlowTypeExtendedVlanFlow:\n\t\treturn \"Extended VLAN Flow Record\"\n\tcase SFlowTypeExtendedIpv4TunnelEgressFlow:\n\t\treturn \"Extended IPv4 Tunnel Egress Record\"\n\tcase SFlowTypeExtendedIpv4TunnelIngressFlow:\n\t\treturn \"Extended IPv4 Tunnel Ingress Record\"\n\tcase SFlowTypeExtendedIpv6TunnelEgressFlow:\n\t\treturn \"Extended IPv6 Tunnel Egress Record\"\n\tcase SFlowTypeExtendedIpv6TunnelIngressFlow:\n\t\treturn \"Extended IPv6 Tunnel Ingress Record\"\n\tcase SFlowTypeExtendedDecapsulateEgressFlow:\n\t\treturn \"Extended Decapsulate Egress Record\"\n\tcase SFlowTypeExtendedDecapsulateIngressFlow:\n\t\treturn \"Extended Decapsulate Ingress Record\"\n\tcase SFlowTypeExtendedVniEgressFlow:\n\t\treturn \"Extended VNI Ingress Record\"\n\tcase SFlowTypeExtendedVniIngressFlow:\n\t\treturn \"Extended VNI Ingress Record\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\n// SFlowRawPacketFlowRecords hold information about a sampled\n// packet grabbed as it transited the agent. This is\n// perhaps the most useful and interesting record type,\n// as it holds the headers of the sampled packet and\n// can be used to build up a complete picture of the\n// traffic patterns on a network.\n//\n// The raw packet header is sent back into gopacket for\n// decoding, and the resulting gopackt.Packet is stored\n// in the Header member\ntype SFlowRawPacketFlowRecord struct {\n\tSFlowBaseFlowRecord\n\tHeaderProtocol SFlowRawHeaderProtocol\n\tFrameLength    uint32\n\tPayloadRemoved uint32\n\tHeaderLength   uint32\n\tHeader         gopacket.Packet\n}\n\n// Raw packet record types have the following structure:\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  record length                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                 Header Protocol               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                 Frame Length                  |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                 Payload Removed               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                 Header Length                 |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  \\                     Header                    \\\n//  \\                                               \\\n//  \\                                               \\\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\ntype SFlowRawHeaderProtocol uint32\n\nconst (\n\tSFlowProtoEthernet   SFlowRawHeaderProtocol = 1\n\tSFlowProtoISO88024   SFlowRawHeaderProtocol = 2\n\tSFlowProtoISO88025   SFlowRawHeaderProtocol = 3\n\tSFlowProtoFDDI       SFlowRawHeaderProtocol = 4\n\tSFlowProtoFrameRelay SFlowRawHeaderProtocol = 5\n\tSFlowProtoX25        SFlowRawHeaderProtocol = 6\n\tSFlowProtoPPP        SFlowRawHeaderProtocol = 7\n\tSFlowProtoSMDS       SFlowRawHeaderProtocol = 8\n\tSFlowProtoAAL5       SFlowRawHeaderProtocol = 9\n\tSFlowProtoAAL5_IP    SFlowRawHeaderProtocol = 10 /* e.g. Cisco AAL5 mux */\n\tSFlowProtoIPv4       SFlowRawHeaderProtocol = 11\n\tSFlowProtoIPv6       SFlowRawHeaderProtocol = 12\n\tSFlowProtoMPLS       SFlowRawHeaderProtocol = 13\n\tSFlowProtoPOS        SFlowRawHeaderProtocol = 14 /* RFC 1662, 2615 */\n)\n\nfunc (sfhp SFlowRawHeaderProtocol) String() string {\n\tswitch sfhp {\n\tcase SFlowProtoEthernet:\n\t\treturn \"ETHERNET-ISO88023\"\n\tcase SFlowProtoISO88024:\n\t\treturn \"ISO88024-TOKENBUS\"\n\tcase SFlowProtoISO88025:\n\t\treturn \"ISO88025-TOKENRING\"\n\tcase SFlowProtoFDDI:\n\t\treturn \"FDDI\"\n\tcase SFlowProtoFrameRelay:\n\t\treturn \"FRAME-RELAY\"\n\tcase SFlowProtoX25:\n\t\treturn \"X25\"\n\tcase SFlowProtoPPP:\n\t\treturn \"PPP\"\n\tcase SFlowProtoSMDS:\n\t\treturn \"SMDS\"\n\tcase SFlowProtoAAL5:\n\t\treturn \"AAL5\"\n\tcase SFlowProtoAAL5_IP:\n\t\treturn \"AAL5-IP\"\n\tcase SFlowProtoIPv4:\n\t\treturn \"IPv4\"\n\tcase SFlowProtoIPv6:\n\t\treturn \"IPv6\"\n\tcase SFlowProtoMPLS:\n\t\treturn \"MPLS\"\n\tcase SFlowProtoPOS:\n\t\treturn \"POS\"\n\t}\n\treturn \"UNKNOWN\"\n}\n\nfunc decodeRawPacketFlowRecord(data *[]byte) (SFlowRawPacketFlowRecord, error) {\n\trec := SFlowRawPacketFlowRecord{}\n\theader := []byte{}\n\tvar fdf SFlowFlowDataFormat\n\n\t*data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\trec.EnterpriseID, rec.Format = fdf.decode()\n\t*data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, rec.HeaderProtocol = (*data)[4:], SFlowRawHeaderProtocol(binary.BigEndian.Uint32((*data)[:4]))\n\t*data, rec.FrameLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, rec.PayloadRemoved = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, rec.HeaderLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\theaderLenWithPadding := int(rec.HeaderLength + ((4 - rec.HeaderLength) % 4))\n\t*data, header = (*data)[headerLenWithPadding:], (*data)[:headerLenWithPadding]\n\trec.Header = gopacket.NewPacket(header, LayerTypeEthernet, gopacket.Default)\n\treturn rec, nil\n}\n\n// SFlowExtendedSwitchFlowRecord give additional information\n// about the sampled packet if it's available. It's mainly\n// useful for getting at the incoming and outgoing VLANs\n// An agent may or may not provide this information.\ntype SFlowExtendedSwitchFlowRecord struct {\n\tSFlowBaseFlowRecord\n\tIncomingVLAN         uint32\n\tIncomingVLANPriority uint32\n\tOutgoingVLAN         uint32\n\tOutgoingVLANPriority uint32\n}\n\n// Extended switch records have the following structure:\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  record length                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                   Incoming VLAN               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                Incoming VLAN Priority         |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                   Outgoing VLAN               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                Outgoing VLAN Priority         |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\nfunc decodeExtendedSwitchFlowRecord(data *[]byte) (SFlowExtendedSwitchFlowRecord, error) {\n\tes := SFlowExtendedSwitchFlowRecord{}\n\tvar fdf SFlowFlowDataFormat\n\n\t*data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\tes.EnterpriseID, es.Format = fdf.decode()\n\t*data, es.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, es.IncomingVLAN = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, es.IncomingVLANPriority = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, es.OutgoingVLAN = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, es.OutgoingVLANPriority = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\treturn es, nil\n}\n\n// SFlowExtendedRouterFlowRecord gives additional information\n// about the layer 3 routing information used to forward\n// the packet\ntype SFlowExtendedRouterFlowRecord struct {\n\tSFlowBaseFlowRecord\n\tNextHop                net.IP\n\tNextHopSourceMask      uint32\n\tNextHopDestinationMask uint32\n}\n\n// Extended router records have the following structure:\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  record length                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |   IP version of next hop router (1=v4|2=v6)   |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  /     Next Hop address (v4=4byte|v6=16byte)     /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |              Next Hop Source Mask             |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |              Next Hop Destination Mask        |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\nfunc decodeExtendedRouterFlowRecord(data *[]byte) (SFlowExtendedRouterFlowRecord, error) {\n\ter := SFlowExtendedRouterFlowRecord{}\n\tvar fdf SFlowFlowDataFormat\n\tvar extendedRouterAddressType SFlowIPType\n\n\t*data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\ter.EnterpriseID, er.Format = fdf.decode()\n\t*data, er.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, extendedRouterAddressType = (*data)[4:], SFlowIPType(binary.BigEndian.Uint32((*data)[:4]))\n\t*data, er.NextHop = (*data)[extendedRouterAddressType.Length():], (*data)[:extendedRouterAddressType.Length()]\n\t*data, er.NextHopSourceMask = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, er.NextHopDestinationMask = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\treturn er, nil\n}\n\n// SFlowExtendedGatewayFlowRecord describes information treasured by\n// nework engineers everywhere: AS path information listing which\n// BGP peer sent the packet, and various other BGP related info.\n// This information is vital because it gives a picture of how much\n// traffic is being sent from / received by various BGP peers.\n\n// Extended gateway records have the following structure:\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  record length                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |   IP version of next hop router (1=v4|2=v6)   |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  /     Next Hop address (v4=4byte|v6=16byte)     /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                       AS                      |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  Source AS                    |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    Peer AS                    |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  AS Path Count                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  /                AS Path / Sequence             /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  /                   Communities                 /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    Local Pref                 |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\n// AS Path / Sequence:\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |     AS Source Type (Path=1 / Sequence=2)      |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |              Path / Sequence length           |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  /              Path / Sequence Members          /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\n// Communities:\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                communitiy length              |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  /              communitiy Members               /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\ntype SFlowExtendedGatewayFlowRecord struct {\n\tSFlowBaseFlowRecord\n\tNextHop     net.IP\n\tAS          uint32\n\tSourceAS    uint32\n\tPeerAS      uint32\n\tASPathCount uint32\n\tASPath      []SFlowASDestination\n\tCommunities []uint32\n\tLocalPref   uint32\n}\n\ntype SFlowASPathType uint32\n\nconst (\n\tSFlowASSet      SFlowASPathType = 1\n\tSFlowASSequence SFlowASPathType = 2\n)\n\nfunc (apt SFlowASPathType) String() string {\n\tswitch apt {\n\tcase SFlowASSet:\n\t\treturn \"AS Set\"\n\tcase SFlowASSequence:\n\t\treturn \"AS Sequence\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\ntype SFlowASDestination struct {\n\tType    SFlowASPathType\n\tCount   uint32\n\tMembers []uint32\n}\n\nfunc (asd SFlowASDestination) String() string {\n\tswitch asd.Type {\n\tcase SFlowASSet:\n\t\treturn fmt.Sprint(\"AS Set:\", asd.Members)\n\tcase SFlowASSequence:\n\t\treturn fmt.Sprint(\"AS Sequence:\", asd.Members)\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\nfunc (ad *SFlowASDestination) decodePath(data *[]byte) {\n\t*data, ad.Type = (*data)[4:], SFlowASPathType(binary.BigEndian.Uint32((*data)[:4]))\n\t*data, ad.Count = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tad.Members = make([]uint32, ad.Count)\n\tfor i := uint32(0); i < ad.Count; i++ {\n\t\tvar member uint32\n\t\t*data, member = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t\tad.Members[i] = member\n\t}\n}\n\nfunc decodeExtendedGatewayFlowRecord(data *[]byte) (SFlowExtendedGatewayFlowRecord, error) {\n\teg := SFlowExtendedGatewayFlowRecord{}\n\tvar fdf SFlowFlowDataFormat\n\tvar extendedGatewayAddressType SFlowIPType\n\tvar communitiesLength uint32\n\tvar community uint32\n\n\t*data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\teg.EnterpriseID, eg.Format = fdf.decode()\n\t*data, eg.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, extendedGatewayAddressType = (*data)[4:], SFlowIPType(binary.BigEndian.Uint32((*data)[:4]))\n\t*data, eg.NextHop = (*data)[extendedGatewayAddressType.Length():], (*data)[:extendedGatewayAddressType.Length()]\n\t*data, eg.AS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, eg.SourceAS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, eg.PeerAS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, eg.ASPathCount = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tfor i := uint32(0); i < eg.ASPathCount; i++ {\n\t\tasPath := SFlowASDestination{}\n\t\tasPath.decodePath(data)\n\t\teg.ASPath = append(eg.ASPath, asPath)\n\t}\n\t*data, communitiesLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\teg.Communities = make([]uint32, communitiesLength)\n\tfor j := uint32(0); j < communitiesLength; j++ {\n\t\t*data, community = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t\teg.Communities[j] = community\n\t}\n\t*data, eg.LocalPref = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\treturn eg, nil\n}\n\n// **************************************************\n//  Extended URL Flow Record\n// **************************************************\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  record length                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                   direction                   |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                      URL                      |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                      Host                     |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\ntype SFlowURLDirection uint32\n\nconst (\n\tSFlowURLsrc SFlowURLDirection = 1\n\tSFlowURLdst SFlowURLDirection = 2\n)\n\nfunc (urld SFlowURLDirection) String() string {\n\tswitch urld {\n\tcase SFlowURLsrc:\n\t\treturn \"Source address is the server\"\n\tcase SFlowURLdst:\n\t\treturn \"Destination address is the server\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\ntype SFlowExtendedURLRecord struct {\n\tSFlowBaseFlowRecord\n\tDirection SFlowURLDirection\n\tURL       string\n\tHost      string\n}\n\nfunc decodeExtendedURLRecord(data *[]byte) (SFlowExtendedURLRecord, error) {\n\teur := SFlowExtendedURLRecord{}\n\tvar fdf SFlowFlowDataFormat\n\tvar urlLen uint32\n\tvar urlLenWithPad int\n\tvar hostLen uint32\n\tvar hostLenWithPad int\n\tvar urlBytes []byte\n\tvar hostBytes []byte\n\n\t*data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\teur.EnterpriseID, eur.Format = fdf.decode()\n\t*data, eur.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, eur.Direction = (*data)[4:], SFlowURLDirection(binary.BigEndian.Uint32((*data)[:4]))\n\t*data, urlLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\turlLenWithPad = int(urlLen + ((4 - urlLen) % 4))\n\t*data, urlBytes = (*data)[urlLenWithPad:], (*data)[:urlLenWithPad]\n\teur.URL = string(urlBytes[:urlLen])\n\t*data, hostLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\thostLenWithPad = int(hostLen + ((4 - hostLen) % 4))\n\t*data, hostBytes = (*data)[hostLenWithPad:], (*data)[:hostLenWithPad]\n\teur.Host = string(hostBytes[:hostLen])\n\treturn eur, nil\n}\n\n// **************************************************\n//  Extended User Flow Record\n// **************************************************\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  record length                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                Source Character Set           |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                 Source User Id                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |              Destination Character Set        |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |               Destination User ID             |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\ntype SFlowExtendedUserFlow struct {\n\tSFlowBaseFlowRecord\n\tSourceCharSet      SFlowCharSet\n\tSourceUserID       string\n\tDestinationCharSet SFlowCharSet\n\tDestinationUserID  string\n}\n\ntype SFlowCharSet uint32\n\nconst (\n\tSFlowCSunknown                 SFlowCharSet = 2\n\tSFlowCSASCII                   SFlowCharSet = 3\n\tSFlowCSISOLatin1               SFlowCharSet = 4\n\tSFlowCSISOLatin2               SFlowCharSet = 5\n\tSFlowCSISOLatin3               SFlowCharSet = 6\n\tSFlowCSISOLatin4               SFlowCharSet = 7\n\tSFlowCSISOLatinCyrillic        SFlowCharSet = 8\n\tSFlowCSISOLatinArabic          SFlowCharSet = 9\n\tSFlowCSISOLatinGreek           SFlowCharSet = 10\n\tSFlowCSISOLatinHebrew          SFlowCharSet = 11\n\tSFlowCSISOLatin5               SFlowCharSet = 12\n\tSFlowCSISOLatin6               SFlowCharSet = 13\n\tSFlowCSISOTextComm             SFlowCharSet = 14\n\tSFlowCSHalfWidthKatakana       SFlowCharSet = 15\n\tSFlowCSJISEncoding             SFlowCharSet = 16\n\tSFlowCSShiftJIS                SFlowCharSet = 17\n\tSFlowCSEUCPkdFmtJapanese       SFlowCharSet = 18\n\tSFlowCSEUCFixWidJapanese       SFlowCharSet = 19\n\tSFlowCSISO4UnitedKingdom       SFlowCharSet = 20\n\tSFlowCSISO11SwedishForNames    SFlowCharSet = 21\n\tSFlowCSISO15Italian            SFlowCharSet = 22\n\tSFlowCSISO17Spanish            SFlowCharSet = 23\n\tSFlowCSISO21German             SFlowCharSet = 24\n\tSFlowCSISO60DanishNorwegian    SFlowCharSet = 25\n\tSFlowCSISO69French             SFlowCharSet = 26\n\tSFlowCSISO10646UTF1            SFlowCharSet = 27\n\tSFlowCSISO646basic1983         SFlowCharSet = 28\n\tSFlowCSINVARIANT               SFlowCharSet = 29\n\tSFlowCSISO2IntlRefVersion      SFlowCharSet = 30\n\tSFlowCSNATSSEFI                SFlowCharSet = 31\n\tSFlowCSNATSSEFIADD             SFlowCharSet = 32\n\tSFlowCSNATSDANO                SFlowCharSet = 33\n\tSFlowCSNATSDANOADD             SFlowCharSet = 34\n\tSFlowCSISO10Swedish            SFlowCharSet = 35\n\tSFlowCSKSC56011987             SFlowCharSet = 36\n\tSFlowCSISO2022KR               SFlowCharSet = 37\n\tSFlowCSEUCKR                   SFlowCharSet = 38\n\tSFlowCSISO2022JP               SFlowCharSet = 39\n\tSFlowCSISO2022JP2              SFlowCharSet = 40\n\tSFlowCSISO13JISC6220jp         SFlowCharSet = 41\n\tSFlowCSISO14JISC6220ro         SFlowCharSet = 42\n\tSFlowCSISO16Portuguese         SFlowCharSet = 43\n\tSFlowCSISO18Greek7Old          SFlowCharSet = 44\n\tSFlowCSISO19LatinGreek         SFlowCharSet = 45\n\tSFlowCSISO25French             SFlowCharSet = 46\n\tSFlowCSISO27LatinGreek1        SFlowCharSet = 47\n\tSFlowCSISO5427Cyrillic         SFlowCharSet = 48\n\tSFlowCSISO42JISC62261978       SFlowCharSet = 49\n\tSFlowCSISO47BSViewdata         SFlowCharSet = 50\n\tSFlowCSISO49INIS               SFlowCharSet = 51\n\tSFlowCSISO50INIS8              SFlowCharSet = 52\n\tSFlowCSISO51INISCyrillic       SFlowCharSet = 53\n\tSFlowCSISO54271981             SFlowCharSet = 54\n\tSFlowCSISO5428Greek            SFlowCharSet = 55\n\tSFlowCSISO57GB1988             SFlowCharSet = 56\n\tSFlowCSISO58GB231280           SFlowCharSet = 57\n\tSFlowCSISO61Norwegian2         SFlowCharSet = 58\n\tSFlowCSISO70VideotexSupp1      SFlowCharSet = 59\n\tSFlowCSISO84Portuguese2        SFlowCharSet = 60\n\tSFlowCSISO85Spanish2           SFlowCharSet = 61\n\tSFlowCSISO86Hungarian          SFlowCharSet = 62\n\tSFlowCSISO87JISX0208           SFlowCharSet = 63\n\tSFlowCSISO88Greek7             SFlowCharSet = 64\n\tSFlowCSISO89ASMO449            SFlowCharSet = 65\n\tSFlowCSISO90                   SFlowCharSet = 66\n\tSFlowCSISO91JISC62291984a      SFlowCharSet = 67\n\tSFlowCSISO92JISC62991984b      SFlowCharSet = 68\n\tSFlowCSISO93JIS62291984badd    SFlowCharSet = 69\n\tSFlowCSISO94JIS62291984hand    SFlowCharSet = 70\n\tSFlowCSISO95JIS62291984handadd SFlowCharSet = 71\n\tSFlowCSISO96JISC62291984kana   SFlowCharSet = 72\n\tSFlowCSISO2033                 SFlowCharSet = 73\n\tSFlowCSISO99NAPLPS             SFlowCharSet = 74\n\tSFlowCSISO102T617bit           SFlowCharSet = 75\n\tSFlowCSISO103T618bit           SFlowCharSet = 76\n\tSFlowCSISO111ECMACyrillic      SFlowCharSet = 77\n\tSFlowCSa71                     SFlowCharSet = 78\n\tSFlowCSa72                     SFlowCharSet = 79\n\tSFlowCSISO123CSAZ24341985gr    SFlowCharSet = 80\n\tSFlowCSISO88596E               SFlowCharSet = 81\n\tSFlowCSISO88596I               SFlowCharSet = 82\n\tSFlowCSISO128T101G2            SFlowCharSet = 83\n\tSFlowCSISO88598E               SFlowCharSet = 84\n\tSFlowCSISO88598I               SFlowCharSet = 85\n\tSFlowCSISO139CSN369103         SFlowCharSet = 86\n\tSFlowCSISO141JUSIB1002         SFlowCharSet = 87\n\tSFlowCSISO143IECP271           SFlowCharSet = 88\n\tSFlowCSISO146Serbian           SFlowCharSet = 89\n\tSFlowCSISO147Macedonian        SFlowCharSet = 90\n\tSFlowCSISO150                  SFlowCharSet = 91\n\tSFlowCSISO151Cuba              SFlowCharSet = 92\n\tSFlowCSISO6937Add              SFlowCharSet = 93\n\tSFlowCSISO153GOST1976874       SFlowCharSet = 94\n\tSFlowCSISO8859Supp             SFlowCharSet = 95\n\tSFlowCSISO10367Box             SFlowCharSet = 96\n\tSFlowCSISO158Lap               SFlowCharSet = 97\n\tSFlowCSISO159JISX02121990      SFlowCharSet = 98\n\tSFlowCSISO646Danish            SFlowCharSet = 99\n\tSFlowCSUSDK                    SFlowCharSet = 100\n\tSFlowCSDKUS                    SFlowCharSet = 101\n\tSFlowCSKSC5636                 SFlowCharSet = 102\n\tSFlowCSUnicode11UTF7           SFlowCharSet = 103\n\tSFlowCSISO2022CN               SFlowCharSet = 104\n\tSFlowCSISO2022CNEXT            SFlowCharSet = 105\n\tSFlowCSUTF8                    SFlowCharSet = 106\n\tSFlowCSISO885913               SFlowCharSet = 109\n\tSFlowCSISO885914               SFlowCharSet = 110\n\tSFlowCSISO885915               SFlowCharSet = 111\n\tSFlowCSISO885916               SFlowCharSet = 112\n\tSFlowCSGBK                     SFlowCharSet = 113\n\tSFlowCSGB18030                 SFlowCharSet = 114\n\tSFlowCSOSDEBCDICDF0415         SFlowCharSet = 115\n\tSFlowCSOSDEBCDICDF03IRV        SFlowCharSet = 116\n\tSFlowCSOSDEBCDICDF041          SFlowCharSet = 117\n\tSFlowCSISO115481               SFlowCharSet = 118\n\tSFlowCSKZ1048                  SFlowCharSet = 119\n\tSFlowCSUnicode                 SFlowCharSet = 1000\n\tSFlowCSUCS4                    SFlowCharSet = 1001\n\tSFlowCSUnicodeASCII            SFlowCharSet = 1002\n\tSFlowCSUnicodeLatin1           SFlowCharSet = 1003\n\tSFlowCSUnicodeJapanese         SFlowCharSet = 1004\n\tSFlowCSUnicodeIBM1261          SFlowCharSet = 1005\n\tSFlowCSUnicodeIBM1268          SFlowCharSet = 1006\n\tSFlowCSUnicodeIBM1276          SFlowCharSet = 1007\n\tSFlowCSUnicodeIBM1264          SFlowCharSet = 1008\n\tSFlowCSUnicodeIBM1265          SFlowCharSet = 1009\n\tSFlowCSUnicode11               SFlowCharSet = 1010\n\tSFlowCSSCSU                    SFlowCharSet = 1011\n\tSFlowCSUTF7                    SFlowCharSet = 1012\n\tSFlowCSUTF16BE                 SFlowCharSet = 1013\n\tSFlowCSUTF16LE                 SFlowCharSet = 1014\n\tSFlowCSUTF16                   SFlowCharSet = 1015\n\tSFlowCSCESU8                   SFlowCharSet = 1016\n\tSFlowCSUTF32                   SFlowCharSet = 1017\n\tSFlowCSUTF32BE                 SFlowCharSet = 1018\n\tSFlowCSUTF32LE                 SFlowCharSet = 1019\n\tSFlowCSBOCU1                   SFlowCharSet = 1020\n\tSFlowCSWindows30Latin1         SFlowCharSet = 2000\n\tSFlowCSWindows31Latin1         SFlowCharSet = 2001\n\tSFlowCSWindows31Latin2         SFlowCharSet = 2002\n\tSFlowCSWindows31Latin5         SFlowCharSet = 2003\n\tSFlowCSHPRoman8                SFlowCharSet = 2004\n\tSFlowCSAdobeStandardEncoding   SFlowCharSet = 2005\n\tSFlowCSVenturaUS               SFlowCharSet = 2006\n\tSFlowCSVenturaInternational    SFlowCharSet = 2007\n\tSFlowCSDECMCS                  SFlowCharSet = 2008\n\tSFlowCSPC850Multilingual       SFlowCharSet = 2009\n\tSFlowCSPCp852                  SFlowCharSet = 2010\n\tSFlowCSPC8CodePage437          SFlowCharSet = 2011\n\tSFlowCSPC8DanishNorwegian      SFlowCharSet = 2012\n\tSFlowCSPC862LatinHebrew        SFlowCharSet = 2013\n\tSFlowCSPC8Turkish              SFlowCharSet = 2014\n\tSFlowCSIBMSymbols              SFlowCharSet = 2015\n\tSFlowCSIBMThai                 SFlowCharSet = 2016\n\tSFlowCSHPLegal                 SFlowCharSet = 2017\n\tSFlowCSHPPiFont                SFlowCharSet = 2018\n\tSFlowCSHPMath8                 SFlowCharSet = 2019\n\tSFlowCSHPPSMath                SFlowCharSet = 2020\n\tSFlowCSHPDesktop               SFlowCharSet = 2021\n\tSFlowCSVenturaMath             SFlowCharSet = 2022\n\tSFlowCSMicrosoftPublishing     SFlowCharSet = 2023\n\tSFlowCSWindows31J              SFlowCharSet = 2024\n\tSFlowCSGB2312                  SFlowCharSet = 2025\n\tSFlowCSBig5                    SFlowCharSet = 2026\n\tSFlowCSMacintosh               SFlowCharSet = 2027\n\tSFlowCSIBM037                  SFlowCharSet = 2028\n\tSFlowCSIBM038                  SFlowCharSet = 2029\n\tSFlowCSIBM273                  SFlowCharSet = 2030\n\tSFlowCSIBM274                  SFlowCharSet = 2031\n\tSFlowCSIBM275                  SFlowCharSet = 2032\n\tSFlowCSIBM277                  SFlowCharSet = 2033\n\tSFlowCSIBM278                  SFlowCharSet = 2034\n\tSFlowCSIBM280                  SFlowCharSet = 2035\n\tSFlowCSIBM281                  SFlowCharSet = 2036\n\tSFlowCSIBM284                  SFlowCharSet = 2037\n\tSFlowCSIBM285                  SFlowCharSet = 2038\n\tSFlowCSIBM290                  SFlowCharSet = 2039\n\tSFlowCSIBM297                  SFlowCharSet = 2040\n\tSFlowCSIBM420                  SFlowCharSet = 2041\n\tSFlowCSIBM423                  SFlowCharSet = 2042\n\tSFlowCSIBM424                  SFlowCharSet = 2043\n\tSFlowCSIBM500                  SFlowCharSet = 2044\n\tSFlowCSIBM851                  SFlowCharSet = 2045\n\tSFlowCSIBM855                  SFlowCharSet = 2046\n\tSFlowCSIBM857                  SFlowCharSet = 2047\n\tSFlowCSIBM860                  SFlowCharSet = 2048\n\tSFlowCSIBM861                  SFlowCharSet = 2049\n\tSFlowCSIBM863                  SFlowCharSet = 2050\n\tSFlowCSIBM864                  SFlowCharSet = 2051\n\tSFlowCSIBM865                  SFlowCharSet = 2052\n\tSFlowCSIBM868                  SFlowCharSet = 2053\n\tSFlowCSIBM869                  SFlowCharSet = 2054\n\tSFlowCSIBM870                  SFlowCharSet = 2055\n\tSFlowCSIBM871                  SFlowCharSet = 2056\n\tSFlowCSIBM880                  SFlowCharSet = 2057\n\tSFlowCSIBM891                  SFlowCharSet = 2058\n\tSFlowCSIBM903                  SFlowCharSet = 2059\n\tSFlowCSIBBM904                 SFlowCharSet = 2060\n\tSFlowCSIBM905                  SFlowCharSet = 2061\n\tSFlowCSIBM918                  SFlowCharSet = 2062\n\tSFlowCSIBM1026                 SFlowCharSet = 2063\n\tSFlowCSIBMEBCDICATDE           SFlowCharSet = 2064\n\tSFlowCSEBCDICATDEA             SFlowCharSet = 2065\n\tSFlowCSEBCDICCAFR              SFlowCharSet = 2066\n\tSFlowCSEBCDICDKNO              SFlowCharSet = 2067\n\tSFlowCSEBCDICDKNOA             SFlowCharSet = 2068\n\tSFlowCSEBCDICFISE              SFlowCharSet = 2069\n\tSFlowCSEBCDICFISEA             SFlowCharSet = 2070\n\tSFlowCSEBCDICFR                SFlowCharSet = 2071\n\tSFlowCSEBCDICIT                SFlowCharSet = 2072\n\tSFlowCSEBCDICPT                SFlowCharSet = 2073\n\tSFlowCSEBCDICES                SFlowCharSet = 2074\n\tSFlowCSEBCDICESA               SFlowCharSet = 2075\n\tSFlowCSEBCDICESS               SFlowCharSet = 2076\n\tSFlowCSEBCDICUK                SFlowCharSet = 2077\n\tSFlowCSEBCDICUS                SFlowCharSet = 2078\n\tSFlowCSUnknown8BiT             SFlowCharSet = 2079\n\tSFlowCSMnemonic                SFlowCharSet = 2080\n\tSFlowCSMnem                    SFlowCharSet = 2081\n\tSFlowCSVISCII                  SFlowCharSet = 2082\n\tSFlowCSVIQR                    SFlowCharSet = 2083\n\tSFlowCSKOI8R                   SFlowCharSet = 2084\n\tSFlowCSHZGB2312                SFlowCharSet = 2085\n\tSFlowCSIBM866                  SFlowCharSet = 2086\n\tSFlowCSPC775Baltic             SFlowCharSet = 2087\n\tSFlowCSKOI8U                   SFlowCharSet = 2088\n\tSFlowCSIBM00858                SFlowCharSet = 2089\n\tSFlowCSIBM00924                SFlowCharSet = 2090\n\tSFlowCSIBM01140                SFlowCharSet = 2091\n\tSFlowCSIBM01141                SFlowCharSet = 2092\n\tSFlowCSIBM01142                SFlowCharSet = 2093\n\tSFlowCSIBM01143                SFlowCharSet = 2094\n\tSFlowCSIBM01144                SFlowCharSet = 2095\n\tSFlowCSIBM01145                SFlowCharSet = 2096\n\tSFlowCSIBM01146                SFlowCharSet = 2097\n\tSFlowCSIBM01147                SFlowCharSet = 2098\n\tSFlowCSIBM01148                SFlowCharSet = 2099\n\tSFlowCSIBM01149                SFlowCharSet = 2100\n\tSFlowCSBig5HKSCS               SFlowCharSet = 2101\n\tSFlowCSIBM1047                 SFlowCharSet = 2102\n\tSFlowCSPTCP154                 SFlowCharSet = 2103\n\tSFlowCSAmiga1251               SFlowCharSet = 2104\n\tSFlowCSKOI7switched            SFlowCharSet = 2105\n\tSFlowCSBRF                     SFlowCharSet = 2106\n\tSFlowCSTSCII                   SFlowCharSet = 2107\n\tSFlowCSCP51932                 SFlowCharSet = 2108\n\tSFlowCSWindows874              SFlowCharSet = 2109\n\tSFlowCSWindows1250             SFlowCharSet = 2250\n\tSFlowCSWindows1251             SFlowCharSet = 2251\n\tSFlowCSWindows1252             SFlowCharSet = 2252\n\tSFlowCSWindows1253             SFlowCharSet = 2253\n\tSFlowCSWindows1254             SFlowCharSet = 2254\n\tSFlowCSWindows1255             SFlowCharSet = 2255\n\tSFlowCSWindows1256             SFlowCharSet = 2256\n\tSFlowCSWindows1257             SFlowCharSet = 2257\n\tSFlowCSWindows1258             SFlowCharSet = 2258\n\tSFlowCSTIS620                  SFlowCharSet = 2259\n\tSFlowCS50220                   SFlowCharSet = 2260\n\tSFlowCSreserved                SFlowCharSet = 3000\n)\n\nfunc decodeExtendedUserFlow(data *[]byte) (SFlowExtendedUserFlow, error) {\n\teu := SFlowExtendedUserFlow{}\n\tvar fdf SFlowFlowDataFormat\n\tvar srcUserLen uint32\n\tvar srcUserLenWithPad int\n\tvar srcUserBytes []byte\n\tvar dstUserLen uint32\n\tvar dstUserLenWithPad int\n\tvar dstUserBytes []byte\n\n\t*data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\teu.EnterpriseID, eu.Format = fdf.decode()\n\t*data, eu.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, eu.SourceCharSet = (*data)[4:], SFlowCharSet(binary.BigEndian.Uint32((*data)[:4]))\n\t*data, srcUserLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tsrcUserLenWithPad = int(srcUserLen + ((4 - srcUserLen) % 4))\n\t*data, srcUserBytes = (*data)[srcUserLenWithPad:], (*data)[:srcUserLenWithPad]\n\teu.SourceUserID = string(srcUserBytes[:srcUserLen])\n\t*data, eu.DestinationCharSet = (*data)[4:], SFlowCharSet(binary.BigEndian.Uint32((*data)[:4]))\n\t*data, dstUserLen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tdstUserLenWithPad = int(dstUserLen + ((4 - dstUserLen) % 4))\n\t*data, dstUserBytes = (*data)[dstUserLenWithPad:], (*data)[:dstUserLenWithPad]\n\teu.DestinationUserID = string(dstUserBytes[:dstUserLen])\n\treturn eu, nil\n}\n\n// **************************************************\n//  Packet IP version 4 Record\n// **************************************************\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                     Length                    |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    Protocol                   |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  Source IPv4                  |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                Destination IPv4               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                   Source Port                 |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                Destionation Port              |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                   TCP Flags                   |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                      TOS                      |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\ntype SFlowIpv4Record struct {\n\t// The length of the IP packet excluding ower layer encapsulations\n\tLength uint32\n\t// IP Protocol type (for example, TCP = 6, UDP = 17)\n\tProtocol uint32\n\t// Source IP Address\n\tIPSrc net.IP\n\t// Destination IP Address\n\tIPDst net.IP\n\t// TCP/UDP source port number or equivalent\n\tPortSrc uint32\n\t// TCP/UDP destination port number or equivalent\n\tPortDst uint32\n\t// TCP flags\n\tTCPFlags uint32\n\t// IP type of service\n\tTOS uint32\n}\n\nfunc decodeSFlowIpv4Record(data *[]byte) (SFlowIpv4Record, error) {\n\tsi := SFlowIpv4Record{}\n\n\t*data, si.Length = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, si.Protocol = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, si.IPSrc = (*data)[4:], net.IP((*data)[:4])\n\t*data, si.IPDst = (*data)[4:], net.IP((*data)[:4])\n\t*data, si.PortSrc = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, si.PortDst = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, si.TCPFlags = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, si.TOS = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\n\treturn si, nil\n}\n\n// **************************************************\n//  Packet IP version 6 Record\n// **************************************************\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                     Length                    |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    Protocol                   |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  Source IPv4                  |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                Destination IPv4               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                   Source Port                 |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                Destionation Port              |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                   TCP Flags                   |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    Priority                   |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\ntype SFlowIpv6Record struct {\n\t// The length of the IP packet excluding ower layer encapsulations\n\tLength uint32\n\t// IP Protocol type (for example, TCP = 6, UDP = 17)\n\tProtocol uint32\n\t// Source IP Address\n\tIPSrc net.IP\n\t// Destination IP Address\n\tIPDst net.IP\n\t// TCP/UDP source port number or equivalent\n\tPortSrc uint32\n\t// TCP/UDP destination port number or equivalent\n\tPortDst uint32\n\t// TCP flags\n\tTCPFlags uint32\n\t// IP priority\n\tPriority uint32\n}\n\nfunc decodeSFlowIpv6Record(data *[]byte) (SFlowIpv6Record, error) {\n\tsi := SFlowIpv6Record{}\n\n\t*data, si.Length = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, si.Protocol = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, si.IPSrc = (*data)[16:], net.IP((*data)[:16])\n\t*data, si.IPDst = (*data)[16:], net.IP((*data)[:16])\n\t*data, si.PortSrc = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, si.PortDst = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, si.TCPFlags = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, si.Priority = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\n\treturn si, nil\n}\n\n// **************************************************\n//  Extended IPv4 Tunnel Egress\n// **************************************************\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  record length                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  /           Packet IP version 4 Record          /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\ntype SFlowExtendedIpv4TunnelEgressRecord struct {\n\tSFlowBaseFlowRecord\n\tSFlowIpv4Record SFlowIpv4Record\n}\n\nfunc decodeExtendedIpv4TunnelEgress(data *[]byte) (SFlowExtendedIpv4TunnelEgressRecord, error) {\n\trec := SFlowExtendedIpv4TunnelEgressRecord{}\n\tvar fdf SFlowFlowDataFormat\n\n\t*data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\trec.EnterpriseID, rec.Format = fdf.decode()\n\t*data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\trec.SFlowIpv4Record, _ = decodeSFlowIpv4Record(data)\n\n\treturn rec, nil\n}\n\n// **************************************************\n//  Extended IPv4 Tunnel Ingress\n// **************************************************\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  record length                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  /           Packet IP version 4 Record          /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\ntype SFlowExtendedIpv4TunnelIngressRecord struct {\n\tSFlowBaseFlowRecord\n\tSFlowIpv4Record SFlowIpv4Record\n}\n\nfunc decodeExtendedIpv4TunnelIngress(data *[]byte) (SFlowExtendedIpv4TunnelIngressRecord, error) {\n\trec := SFlowExtendedIpv4TunnelIngressRecord{}\n\tvar fdf SFlowFlowDataFormat\n\n\t*data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\trec.EnterpriseID, rec.Format = fdf.decode()\n\t*data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\trec.SFlowIpv4Record, _ = decodeSFlowIpv4Record(data)\n\n\treturn rec, nil\n}\n\n// **************************************************\n//  Extended IPv6 Tunnel Egress\n// **************************************************\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  record length                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  /           Packet IP version 6 Record          /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\ntype SFlowExtendedIpv6TunnelEgressRecord struct {\n\tSFlowBaseFlowRecord\n\tSFlowIpv6Record\n}\n\nfunc decodeExtendedIpv6TunnelEgress(data *[]byte) (SFlowExtendedIpv6TunnelEgressRecord, error) {\n\trec := SFlowExtendedIpv6TunnelEgressRecord{}\n\tvar fdf SFlowFlowDataFormat\n\n\t*data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\trec.EnterpriseID, rec.Format = fdf.decode()\n\t*data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\trec.SFlowIpv6Record, _ = decodeSFlowIpv6Record(data)\n\n\treturn rec, nil\n}\n\n// **************************************************\n//  Extended IPv6 Tunnel Ingress\n// **************************************************\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  record length                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  /           Packet IP version 6 Record          /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\ntype SFlowExtendedIpv6TunnelIngressRecord struct {\n\tSFlowBaseFlowRecord\n\tSFlowIpv6Record\n}\n\nfunc decodeExtendedIpv6TunnelIngress(data *[]byte) (SFlowExtendedIpv6TunnelIngressRecord, error) {\n\trec := SFlowExtendedIpv6TunnelIngressRecord{}\n\tvar fdf SFlowFlowDataFormat\n\n\t*data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\trec.EnterpriseID, rec.Format = fdf.decode()\n\t*data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\trec.SFlowIpv6Record, _ = decodeSFlowIpv6Record(data)\n\n\treturn rec, nil\n}\n\n// **************************************************\n//  Extended Decapsulate Egress\n// **************************************************\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  record length                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |               Inner Header Offset             |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\ntype SFlowExtendedDecapsulateEgressRecord struct {\n\tSFlowBaseFlowRecord\n\tInnerHeaderOffset uint32\n}\n\nfunc decodeExtendedDecapsulateEgress(data *[]byte) (SFlowExtendedDecapsulateEgressRecord, error) {\n\trec := SFlowExtendedDecapsulateEgressRecord{}\n\tvar fdf SFlowFlowDataFormat\n\n\t*data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\trec.EnterpriseID, rec.Format = fdf.decode()\n\t*data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, rec.InnerHeaderOffset = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\n\treturn rec, nil\n}\n\n// **************************************************\n//  Extended Decapsulate Ingress\n// **************************************************\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  record length                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |               Inner Header Offset             |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\ntype SFlowExtendedDecapsulateIngressRecord struct {\n\tSFlowBaseFlowRecord\n\tInnerHeaderOffset uint32\n}\n\nfunc decodeExtendedDecapsulateIngress(data *[]byte) (SFlowExtendedDecapsulateIngressRecord, error) {\n\trec := SFlowExtendedDecapsulateIngressRecord{}\n\tvar fdf SFlowFlowDataFormat\n\n\t*data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\trec.EnterpriseID, rec.Format = fdf.decode()\n\t*data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, rec.InnerHeaderOffset = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\n\treturn rec, nil\n}\n\n// **************************************************\n//  Extended VNI Egress\n// **************************************************\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  record length                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                       VNI                     |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\ntype SFlowExtendedVniEgressRecord struct {\n\tSFlowBaseFlowRecord\n\tVNI uint32\n}\n\nfunc decodeExtendedVniEgress(data *[]byte) (SFlowExtendedVniEgressRecord, error) {\n\trec := SFlowExtendedVniEgressRecord{}\n\tvar fdf SFlowFlowDataFormat\n\n\t*data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\trec.EnterpriseID, rec.Format = fdf.decode()\n\t*data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, rec.VNI = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\n\treturn rec, nil\n}\n\n// **************************************************\n//  Extended VNI Ingress\n// **************************************************\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  record length                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                       VNI                     |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\ntype SFlowExtendedVniIngressRecord struct {\n\tSFlowBaseFlowRecord\n\tVNI uint32\n}\n\nfunc decodeExtendedVniIngress(data *[]byte) (SFlowExtendedVniIngressRecord, error) {\n\trec := SFlowExtendedVniIngressRecord{}\n\tvar fdf SFlowFlowDataFormat\n\n\t*data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\trec.EnterpriseID, rec.Format = fdf.decode()\n\t*data, rec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, rec.VNI = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\n\treturn rec, nil\n}\n\n// **************************************************\n//  Counter Record\n// **************************************************\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  counter length               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  /                   counter data                /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\ntype SFlowBaseCounterRecord struct {\n\tEnterpriseID   SFlowEnterpriseID\n\tFormat         SFlowCounterRecordType\n\tFlowDataLength uint32\n}\n\nfunc (bcr SFlowBaseCounterRecord) GetType() SFlowCounterRecordType {\n\tswitch bcr.Format {\n\tcase SFlowTypeGenericInterfaceCounters:\n\t\treturn SFlowTypeGenericInterfaceCounters\n\tcase SFlowTypeEthernetInterfaceCounters:\n\t\treturn SFlowTypeEthernetInterfaceCounters\n\tcase SFlowTypeTokenRingInterfaceCounters:\n\t\treturn SFlowTypeTokenRingInterfaceCounters\n\tcase SFlowType100BaseVGInterfaceCounters:\n\t\treturn SFlowType100BaseVGInterfaceCounters\n\tcase SFlowTypeVLANCounters:\n\t\treturn SFlowTypeVLANCounters\n\tcase SFlowTypeLACPCounters:\n\t\treturn SFlowTypeLACPCounters\n\tcase SFlowTypeProcessorCounters:\n\t\treturn SFlowTypeProcessorCounters\n\tcase SFlowTypeOpenflowPortCounters:\n\t\treturn SFlowTypeOpenflowPortCounters\n\tcase SFlowTypePORTNAMECounters:\n\t\treturn SFlowTypePORTNAMECounters\n\tcase SFLowTypeAPPRESOURCESCounters:\n\t\treturn SFLowTypeAPPRESOURCESCounters\n\tcase SFlowTypeOVSDPCounters:\n\t\treturn SFlowTypeOVSDPCounters\n\t}\n\tunrecognized := fmt.Sprint(\"Unrecognized counter record type:\", bcr.Format)\n\tpanic(unrecognized)\n}\n\n// **************************************************\n//  Counter Record\n// **************************************************\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  counter length               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    IfIndex                    |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    IfType                     |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                   IfSpeed                     |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                   IfDirection                 |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    IfStatus                   |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                   IFInOctets                  |\n//  |                                               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                   IfInUcastPkts               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  IfInMulticastPkts            |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  IfInBroadcastPkts            |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    IfInDiscards               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    InInErrors                 |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  IfInUnknownProtos            |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                   IfOutOctets                 |\n//  |                                               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                   IfOutUcastPkts              |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  IfOutMulticastPkts           |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  IfOutBroadcastPkts           |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                   IfOutDiscards               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    IfOUtErrors                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                 IfPromiscouousMode            |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\ntype SFlowGenericInterfaceCounters struct {\n\tSFlowBaseCounterRecord\n\tIfIndex            uint32\n\tIfType             uint32\n\tIfSpeed            uint64\n\tIfDirection        uint32\n\tIfStatus           uint32\n\tIfInOctets         uint64\n\tIfInUcastPkts      uint32\n\tIfInMulticastPkts  uint32\n\tIfInBroadcastPkts  uint32\n\tIfInDiscards       uint32\n\tIfInErrors         uint32\n\tIfInUnknownProtos  uint32\n\tIfOutOctets        uint64\n\tIfOutUcastPkts     uint32\n\tIfOutMulticastPkts uint32\n\tIfOutBroadcastPkts uint32\n\tIfOutDiscards      uint32\n\tIfOutErrors        uint32\n\tIfPromiscuousMode  uint32\n}\n\nfunc decodeGenericInterfaceCounters(data *[]byte) (SFlowGenericInterfaceCounters, error) {\n\tgic := SFlowGenericInterfaceCounters{}\n\tvar cdf SFlowCounterDataFormat\n\n\t*data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\tgic.EnterpriseID, gic.Format = cdf.decode()\n\t*data, gic.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, gic.IfIndex = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, gic.IfType = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, gic.IfSpeed = (*data)[8:], binary.BigEndian.Uint64((*data)[:8])\n\t*data, gic.IfDirection = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, gic.IfStatus = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, gic.IfInOctets = (*data)[8:], binary.BigEndian.Uint64((*data)[:8])\n\t*data, gic.IfInUcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, gic.IfInMulticastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, gic.IfInBroadcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, gic.IfInDiscards = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, gic.IfInErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, gic.IfInUnknownProtos = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, gic.IfOutOctets = (*data)[8:], binary.BigEndian.Uint64((*data)[:8])\n\t*data, gic.IfOutUcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, gic.IfOutMulticastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, gic.IfOutBroadcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, gic.IfOutDiscards = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, gic.IfOutErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, gic.IfPromiscuousMode = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\treturn gic, nil\n}\n\n// **************************************************\n//  Counter Record\n// **************************************************\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  counter length               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  /                   counter data                /\n//  /                                               /\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\ntype SFlowEthernetCounters struct {\n\tSFlowBaseCounterRecord\n\tAlignmentErrors           uint32\n\tFCSErrors                 uint32\n\tSingleCollisionFrames     uint32\n\tMultipleCollisionFrames   uint32\n\tSQETestErrors             uint32\n\tDeferredTransmissions     uint32\n\tLateCollisions            uint32\n\tExcessiveCollisions       uint32\n\tInternalMacTransmitErrors uint32\n\tCarrierSenseErrors        uint32\n\tFrameTooLongs             uint32\n\tInternalMacReceiveErrors  uint32\n\tSymbolErrors              uint32\n}\n\nfunc decodeEthernetCounters(data *[]byte) (SFlowEthernetCounters, error) {\n\tec := SFlowEthernetCounters{}\n\tvar cdf SFlowCounterDataFormat\n\n\t*data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\tec.EnterpriseID, ec.Format = cdf.decode()\n\tif len(*data) < 4 {\n\t\treturn SFlowEthernetCounters{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, ec.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif len(*data) < 4 {\n\t\treturn SFlowEthernetCounters{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, ec.AlignmentErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif len(*data) < 4 {\n\t\treturn SFlowEthernetCounters{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, ec.FCSErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif len(*data) < 4 {\n\t\treturn SFlowEthernetCounters{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, ec.SingleCollisionFrames = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif len(*data) < 4 {\n\t\treturn SFlowEthernetCounters{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, ec.MultipleCollisionFrames = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif len(*data) < 4 {\n\t\treturn SFlowEthernetCounters{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, ec.SQETestErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif len(*data) < 4 {\n\t\treturn SFlowEthernetCounters{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, ec.DeferredTransmissions = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif len(*data) < 4 {\n\t\treturn SFlowEthernetCounters{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, ec.LateCollisions = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif len(*data) < 4 {\n\t\treturn SFlowEthernetCounters{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, ec.ExcessiveCollisions = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif len(*data) < 4 {\n\t\treturn SFlowEthernetCounters{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, ec.InternalMacTransmitErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif len(*data) < 4 {\n\t\treturn SFlowEthernetCounters{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, ec.CarrierSenseErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif len(*data) < 4 {\n\t\treturn SFlowEthernetCounters{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, ec.FrameTooLongs = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif len(*data) < 4 {\n\t\treturn SFlowEthernetCounters{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, ec.InternalMacReceiveErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tif len(*data) < 4 {\n\t\treturn SFlowEthernetCounters{}, errors.New(\"ethernet counters too small\")\n\t}\n\t*data, ec.SymbolErrors = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\treturn ec, nil\n}\n\n// VLAN Counter\n\ntype SFlowVLANCounters struct {\n\tSFlowBaseCounterRecord\n\tVlanID        uint32\n\tOctets        uint64\n\tUcastPkts     uint32\n\tMulticastPkts uint32\n\tBroadcastPkts uint32\n\tDiscards      uint32\n}\n\nfunc decodeVLANCounters(data *[]byte) (SFlowVLANCounters, error) {\n\tvc := SFlowVLANCounters{}\n\tvar cdf SFlowCounterDataFormat\n\n\t*data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\tvc.EnterpriseID, vc.Format = cdf.decode()\n\tvc.EnterpriseID, vc.Format = cdf.decode()\n\t*data, vc.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, vc.VlanID = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, vc.Octets = (*data)[8:], binary.BigEndian.Uint64((*data)[:8])\n\t*data, vc.UcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, vc.MulticastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, vc.BroadcastPkts = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, vc.Discards = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\treturn vc, nil\n}\n\n//SFLLACPportState  :  SFlow LACP Port State (All(4) - 32 bit)\ntype SFLLACPPortState struct {\n\tPortStateAll uint32\n}\n\n//LACPcounters  :  LACP SFlow Counters  ( 64 Bytes )\ntype SFlowLACPCounters struct {\n\tSFlowBaseCounterRecord\n\tActorSystemID        net.HardwareAddr\n\tPartnerSystemID      net.HardwareAddr\n\tAttachedAggID        uint32\n\tLacpPortState        SFLLACPPortState\n\tLACPDUsRx            uint32\n\tMarkerPDUsRx         uint32\n\tMarkerResponsePDUsRx uint32\n\tUnknownRx            uint32\n\tIllegalRx            uint32\n\tLACPDUsTx            uint32\n\tMarkerPDUsTx         uint32\n\tMarkerResponsePDUsTx uint32\n}\n\nfunc decodeLACPCounters(data *[]byte) (SFlowLACPCounters, error) {\n\tla := SFlowLACPCounters{}\n\tvar cdf SFlowCounterDataFormat\n\n\t*data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\tla.EnterpriseID, la.Format = cdf.decode()\n\t*data, la.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, la.ActorSystemID = (*data)[6:], (*data)[:6]\n\t*data = (*data)[2:] // remove padding\n\t*data, la.PartnerSystemID = (*data)[6:], (*data)[:6]\n\t*data = (*data)[2:] //remove padding\n\t*data, la.AttachedAggID = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, la.LacpPortState.PortStateAll = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, la.LACPDUsRx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, la.MarkerPDUsRx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, la.MarkerResponsePDUsRx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, la.UnknownRx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, la.IllegalRx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, la.LACPDUsTx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, la.MarkerPDUsTx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, la.MarkerResponsePDUsTx = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\n\treturn la, nil\n\n}\n\n// **************************************************\n//  Processor Counter Record\n// **************************************************\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  counter length               |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    FiveSecCpu                 |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    OneMinCpu                  |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    GiveMinCpu                 |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                   TotalMemory                 |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                    FreeMemory                 |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\ntype SFlowProcessorCounters struct {\n\tSFlowBaseCounterRecord\n\tFiveSecCpu  uint32 // 5 second average CPU utilization\n\tOneMinCpu   uint32 // 1 minute average CPU utilization\n\tFiveMinCpu  uint32 // 5 minute average CPU utilization\n\tTotalMemory uint64 // total memory (in bytes)\n\tFreeMemory  uint64 // free memory (in bytes)\n}\n\nfunc decodeProcessorCounters(data *[]byte) (SFlowProcessorCounters, error) {\n\tpc := SFlowProcessorCounters{}\n\tvar cdf SFlowCounterDataFormat\n\tvar high32, low32 uint32\n\n\t*data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\tpc.EnterpriseID, pc.Format = cdf.decode()\n\t*data, pc.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\n\t*data, pc.FiveSecCpu = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, pc.OneMinCpu = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, pc.FiveMinCpu = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, high32 = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, low32 = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tpc.TotalMemory = (uint64(high32) << 32) + uint64(low32)\n\t*data, high32 = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, low32 = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tpc.FreeMemory = (uint64(high32)) + uint64(low32)\n\n\treturn pc, nil\n}\n\n// SFlowEthernetFrameFlowRecord give additional information\n// about the sampled packet if it's available.\n// An agent may or may not provide this information.\ntype SFlowEthernetFrameFlowRecord struct {\n\tSFlowBaseFlowRecord\n\tFrameLength uint32\n\tSrcMac      net.HardwareAddr\n\tDstMac      net.HardwareAddr\n\tType        uint32\n}\n\n// Ethernet frame flow records have the following structure:\n\n//  0                      15                      31\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |      20 bit Interprise (0)     |12 bit format |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                  record length                |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |                Source Mac Address             |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |             Destination Mac Address           |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n//  |               Ethernet Packet Type            |\n//  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+\n\nfunc decodeEthernetFrameFlowRecord(data *[]byte) (SFlowEthernetFrameFlowRecord, error) {\n\tes := SFlowEthernetFrameFlowRecord{}\n\tvar fdf SFlowFlowDataFormat\n\n\t*data, fdf = (*data)[4:], SFlowFlowDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\tes.EnterpriseID, es.Format = fdf.decode()\n\t*data, es.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\n\t*data, es.FrameLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, es.SrcMac = (*data)[8:], net.HardwareAddr((*data)[:6])\n\t*data, es.DstMac = (*data)[8:], net.HardwareAddr((*data)[:6])\n\t*data, es.Type = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\treturn es, nil\n}\n\n//SFlowOpenflowPortCounters  :  OVS-Sflow OpenFlow Port Counter  ( 20 Bytes )\ntype SFlowOpenflowPortCounters struct {\n\tSFlowBaseCounterRecord\n\tDatapathID uint64\n\tPortNo     uint32\n}\n\nfunc decodeOpenflowportCounters(data *[]byte) (SFlowOpenflowPortCounters, error) {\n\tofp := SFlowOpenflowPortCounters{}\n\tvar cdf SFlowCounterDataFormat\n\n\t*data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\tofp.EnterpriseID, ofp.Format = cdf.decode()\n\t*data, ofp.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, ofp.DatapathID = (*data)[8:], binary.BigEndian.Uint64((*data)[:8])\n\t*data, ofp.PortNo = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\n\treturn ofp, nil\n}\n\n//SFlowAppresourcesCounters  :  OVS_Sflow App Resources Counter ( 48 Bytes )\ntype SFlowAppresourcesCounters struct {\n\tSFlowBaseCounterRecord\n\tUserTime   uint32\n\tSystemTime uint32\n\tMemUsed    uint64\n\tMemMax     uint64\n\tFdOpen     uint32\n\tFdMax      uint32\n\tConnOpen   uint32\n\tConnMax    uint32\n}\n\nfunc decodeAppresourcesCounters(data *[]byte) (SFlowAppresourcesCounters, error) {\n\tapp := SFlowAppresourcesCounters{}\n\tvar cdf SFlowCounterDataFormat\n\n\t*data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\tapp.EnterpriseID, app.Format = cdf.decode()\n\t*data, app.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, app.UserTime = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, app.SystemTime = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, app.MemUsed = (*data)[8:], binary.BigEndian.Uint64((*data)[:8])\n\t*data, app.MemMax = (*data)[8:], binary.BigEndian.Uint64((*data)[:8])\n\t*data, app.FdOpen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, app.FdMax = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, app.ConnOpen = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, app.ConnMax = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\n\treturn app, nil\n}\n\n//SFlowOVSDPCounters  :  OVS-Sflow DataPath Counter  ( 32 Bytes )\ntype SFlowOVSDPCounters struct {\n\tSFlowBaseCounterRecord\n\tNHit     uint32\n\tNMissed  uint32\n\tNLost    uint32\n\tNMaskHit uint32\n\tNFlows   uint32\n\tNMasks   uint32\n}\n\nfunc decodeOVSDPCounters(data *[]byte) (SFlowOVSDPCounters, error) {\n\tdp := SFlowOVSDPCounters{}\n\tvar cdf SFlowCounterDataFormat\n\n\t*data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\tdp.EnterpriseID, dp.Format = cdf.decode()\n\t*data, dp.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, dp.NHit = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, dp.NMissed = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, dp.NLost = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, dp.NMaskHit = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, dp.NFlows = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\t*data, dp.NMasks = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\n\treturn dp, nil\n}\n\n//SFlowPORTNAME  :  OVS-Sflow PORTNAME Counter Sampletype ( 20 Bytes )\ntype SFlowPORTNAME struct {\n\tSFlowBaseCounterRecord\n\tLen uint32\n\tStr string\n}\n\nfunc decodeString(data *[]byte) (len uint32, str string) {\n\t*data, len = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tstr = string((*data)[:len])\n\tif (len % 4) != 0 {\n\t\tlen += 4 - len%4\n\t}\n\t*data = (*data)[len:]\n\treturn\n}\n\nfunc decodePortnameCounters(data *[]byte) (SFlowPORTNAME, error) {\n\tpn := SFlowPORTNAME{}\n\tvar cdf SFlowCounterDataFormat\n\n\t*data, cdf = (*data)[4:], SFlowCounterDataFormat(binary.BigEndian.Uint32((*data)[:4]))\n\tpn.EnterpriseID, pn.Format = cdf.decode()\n\t*data, pn.FlowDataLength = (*data)[4:], binary.BigEndian.Uint32((*data)[:4])\n\tpn.Len, pn.Str = decodeString(data)\n\n\treturn pn, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/sip.go",
    "content": "// Copyright 2017 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// SIPVersion defines the different versions of the SIP Protocol\ntype SIPVersion uint8\n\n// Represents all the versions of SIP protocol\nconst (\n\tSIPVersion1 SIPVersion = 1\n\tSIPVersion2 SIPVersion = 2\n)\n\nfunc (sv SIPVersion) String() string {\n\tswitch sv {\n\tdefault:\n\t\t// Defaulting to SIP/2.0\n\t\treturn \"SIP/2.0\"\n\tcase SIPVersion1:\n\t\treturn \"SIP/1.0\"\n\tcase SIPVersion2:\n\t\treturn \"SIP/2.0\"\n\t}\n}\n\n// GetSIPVersion is used to get SIP version constant\nfunc GetSIPVersion(version string) (SIPVersion, error) {\n\tswitch strings.ToUpper(version) {\n\tcase \"SIP/1.0\":\n\t\treturn SIPVersion1, nil\n\tcase \"SIP/2.0\":\n\t\treturn SIPVersion2, nil\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"Unknown SIP version: '%s'\", version)\n\n\t}\n}\n\n// SIPMethod defines the different methods of the SIP Protocol\n// defined in the different RFC's\ntype SIPMethod uint16\n\n// Here are all the SIP methods\nconst (\n\tSIPMethodInvite    SIPMethod = 1  // INVITE\t[RFC3261]\n\tSIPMethodAck       SIPMethod = 2  // ACK\t[RFC3261]\n\tSIPMethodBye       SIPMethod = 3  // BYE\t[RFC3261]\n\tSIPMethodCancel    SIPMethod = 4  // CANCEL\t[RFC3261]\n\tSIPMethodOptions   SIPMethod = 5  // OPTIONS\t[RFC3261]\n\tSIPMethodRegister  SIPMethod = 6  // REGISTER\t[RFC3261]\n\tSIPMethodPrack     SIPMethod = 7  // PRACK\t[RFC3262]\n\tSIPMethodSubscribe SIPMethod = 8  // SUBSCRIBE\t[RFC6665]\n\tSIPMethodNotify    SIPMethod = 9  // NOTIFY\t[RFC6665]\n\tSIPMethodPublish   SIPMethod = 10 // PUBLISH\t[RFC3903]\n\tSIPMethodInfo      SIPMethod = 11 // INFO\t[RFC6086]\n\tSIPMethodRefer     SIPMethod = 12 // REFER\t[RFC3515]\n\tSIPMethodMessage   SIPMethod = 13 // MESSAGE\t[RFC3428]\n\tSIPMethodUpdate    SIPMethod = 14 // UPDATE\t[RFC3311]\n\tSIPMethodPing      SIPMethod = 15 // PING\t[https://tools.ietf.org/html/draft-fwmiller-ping-03]\n)\n\nfunc (sm SIPMethod) String() string {\n\tswitch sm {\n\tdefault:\n\t\treturn \"Unknown method\"\n\tcase SIPMethodInvite:\n\t\treturn \"INVITE\"\n\tcase SIPMethodAck:\n\t\treturn \"ACK\"\n\tcase SIPMethodBye:\n\t\treturn \"BYE\"\n\tcase SIPMethodCancel:\n\t\treturn \"CANCEL\"\n\tcase SIPMethodOptions:\n\t\treturn \"OPTIONS\"\n\tcase SIPMethodRegister:\n\t\treturn \"REGISTER\"\n\tcase SIPMethodPrack:\n\t\treturn \"PRACK\"\n\tcase SIPMethodSubscribe:\n\t\treturn \"SUBSCRIBE\"\n\tcase SIPMethodNotify:\n\t\treturn \"NOTIFY\"\n\tcase SIPMethodPublish:\n\t\treturn \"PUBLISH\"\n\tcase SIPMethodInfo:\n\t\treturn \"INFO\"\n\tcase SIPMethodRefer:\n\t\treturn \"REFER\"\n\tcase SIPMethodMessage:\n\t\treturn \"MESSAGE\"\n\tcase SIPMethodUpdate:\n\t\treturn \"UPDATE\"\n\tcase SIPMethodPing:\n\t\treturn \"PING\"\n\t}\n}\n\n// GetSIPMethod returns the constant of a SIP method\n// from its string\nfunc GetSIPMethod(method string) (SIPMethod, error) {\n\tswitch strings.ToUpper(method) {\n\tcase \"INVITE\":\n\t\treturn SIPMethodInvite, nil\n\tcase \"ACK\":\n\t\treturn SIPMethodAck, nil\n\tcase \"BYE\":\n\t\treturn SIPMethodBye, nil\n\tcase \"CANCEL\":\n\t\treturn SIPMethodCancel, nil\n\tcase \"OPTIONS\":\n\t\treturn SIPMethodOptions, nil\n\tcase \"REGISTER\":\n\t\treturn SIPMethodRegister, nil\n\tcase \"PRACK\":\n\t\treturn SIPMethodPrack, nil\n\tcase \"SUBSCRIBE\":\n\t\treturn SIPMethodSubscribe, nil\n\tcase \"NOTIFY\":\n\t\treturn SIPMethodNotify, nil\n\tcase \"PUBLISH\":\n\t\treturn SIPMethodPublish, nil\n\tcase \"INFO\":\n\t\treturn SIPMethodInfo, nil\n\tcase \"REFER\":\n\t\treturn SIPMethodRefer, nil\n\tcase \"MESSAGE\":\n\t\treturn SIPMethodMessage, nil\n\tcase \"UPDATE\":\n\t\treturn SIPMethodUpdate, nil\n\tcase \"PING\":\n\t\treturn SIPMethodPing, nil\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"Unknown SIP method: '%s'\", method)\n\t}\n}\n\n// Here is a correspondance between long header names and short\n// as defined in rfc3261 in section 20\nvar compactSipHeadersCorrespondance = map[string]string{\n\t\"accept-contact\":      \"a\",\n\t\"allow-events\":        \"u\",\n\t\"call-id\":             \"i\",\n\t\"contact\":             \"m\",\n\t\"content-encoding\":    \"e\",\n\t\"content-length\":      \"l\",\n\t\"content-type\":        \"c\",\n\t\"event\":               \"o\",\n\t\"from\":                \"f\",\n\t\"identity\":            \"y\",\n\t\"refer-to\":            \"r\",\n\t\"referred-by\":         \"b\",\n\t\"reject-contact\":      \"j\",\n\t\"request-disposition\": \"d\",\n\t\"session-expires\":     \"x\",\n\t\"subject\":             \"s\",\n\t\"supported\":           \"k\",\n\t\"to\":                  \"t\",\n\t\"via\":                 \"v\",\n}\n\n// SIP object will contains information about decoded SIP packet.\n// -> The SIP Version\n// -> The SIP Headers (in a map[string][]string because of multiple headers with the same name\n// -> The SIP Method\n// -> The SIP Response code (if it's a response)\n// -> The SIP Status line (if it's a response)\n// You can easily know the type of the packet with the IsResponse boolean\n//\ntype SIP struct {\n\tBaseLayer\n\n\t// Base information\n\tVersion SIPVersion\n\tMethod  SIPMethod\n\tHeaders map[string][]string\n\n\t// Request\n\tRequestURI string\n\n\t// Response\n\tIsResponse     bool\n\tResponseCode   int\n\tResponseStatus string\n\n\t// Private fields\n\tcseq             int64\n\tcontentLength    int64\n\tlastHeaderParsed string\n}\n\n// decodeSIP decodes the byte slice into a SIP type. It also\n// setups the application Layer in PacketBuilder.\nfunc decodeSIP(data []byte, p gopacket.PacketBuilder) error {\n\ts := NewSIP()\n\terr := s.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\tp.AddLayer(s)\n\tp.SetApplicationLayer(s)\n\treturn nil\n}\n\n// NewSIP instantiates a new empty SIP object\nfunc NewSIP() *SIP {\n\ts := new(SIP)\n\ts.Headers = make(map[string][]string)\n\treturn s\n}\n\n// LayerType returns gopacket.LayerTypeSIP.\nfunc (s *SIP) LayerType() gopacket.LayerType {\n\treturn LayerTypeSIP\n}\n\n// Payload returns the base layer payload\nfunc (s *SIP) Payload() []byte {\n\treturn s.BaseLayer.Payload\n}\n\n// CanDecode returns the set of layer types that this DecodingLayer can decode\nfunc (s *SIP) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeSIP\n}\n\n// NextLayerType returns the layer type contained by this DecodingLayer\nfunc (s *SIP) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\n// DecodeFromBytes decodes the slice into the SIP struct.\nfunc (s *SIP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\t// Init some vars for parsing follow-up\n\tvar countLines int\n\tvar line []byte\n\tvar err error\n\tvar offset int\n\n\t// Iterate on all lines of the SIP Headers\n\t// and stop when we reach the SDP (aka when the new line\n\t// is at index 0 of the remaining packet)\n\tbuffer := bytes.NewBuffer(data)\n\n\tfor {\n\n\t\t// Read next line\n\t\tline, err = buffer.ReadBytes(byte('\\n'))\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tif len(bytes.Trim(line, \"\\r\\n\")) > 0 {\n\t\t\t\t\tdf.SetTruncated()\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t} else {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\toffset += len(line)\n\n\t\t// Trim the new line delimiters\n\t\tline = bytes.Trim(line, \"\\r\\n\")\n\n\t\t// Empty line, we hit Body\n\t\tif len(line) == 0 {\n\t\t\tbreak\n\t\t}\n\n\t\t// First line is the SIP request/response line\n\t\t// Other lines are headers\n\t\tif countLines == 0 {\n\t\t\terr = s.ParseFirstLine(line)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t} else {\n\t\t\terr = s.ParseHeader(line)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tcountLines++\n\t}\n\ts.BaseLayer = BaseLayer{Contents: data[:offset], Payload: data[offset:]}\n\n\treturn nil\n}\n\n// ParseFirstLine will compute the first line of a SIP packet.\n// The first line will tell us if it's a request or a response.\n//\n// Examples of first line of SIP Prococol :\n//\n// \tRequest \t: INVITE bob@example.com SIP/2.0\n// \tResponse \t: SIP/2.0 200 OK\n// \tResponse\t: SIP/2.0 501 Not Implemented\n//\nfunc (s *SIP) ParseFirstLine(firstLine []byte) error {\n\n\tvar err error\n\n\t// Splits line by space\n\tsplits := strings.SplitN(string(firstLine), \" \", 3)\n\n\t// We must have at least 3 parts\n\tif len(splits) < 3 {\n\t\treturn fmt.Errorf(\"invalid first SIP line: '%s'\", string(firstLine))\n\t}\n\n\t// Determine the SIP packet type\n\tif strings.HasPrefix(splits[0], \"SIP\") {\n\n\t\t// --> Response\n\t\ts.IsResponse = true\n\n\t\t// Validate SIP Version\n\t\ts.Version, err = GetSIPVersion(splits[0])\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Compute code\n\t\ts.ResponseCode, err = strconv.Atoi(splits[1])\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Compute status line\n\t\ts.ResponseStatus = splits[2]\n\n\t} else {\n\n\t\t// --> Request\n\n\t\t// Validate method\n\t\ts.Method, err = GetSIPMethod(splits[0])\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\ts.RequestURI = splits[1]\n\n\t\t// Validate SIP Version\n\t\ts.Version, err = GetSIPVersion(splits[2])\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// ParseHeader will parse a SIP Header\n// SIP Headers are quite simple, there are colon separated name and value\n// Headers can be spread over multiple lines\n//\n// Examples of header :\n//\n//  CSeq: 1 REGISTER\n//  Via: SIP/2.0/UDP there.com:5060\n//  Authorization:Digest username=\"UserB\",\n//\t  realm=\"MCI WorldCom SIP\",\n//    nonce=\"1cec4341ae6cbe5a359ea9c8e88df84f\", opaque=\"\",\n//    uri=\"sip:ss2.wcom.com\", response=\"71ba27c64bd01de719686aa4590d5824\"\n//\nfunc (s *SIP) ParseHeader(header []byte) (err error) {\n\n\t// Ignore empty headers\n\tif len(header) == 0 {\n\t\treturn\n\t}\n\n\t// Check if this is the following of last header\n\t// RFC 3261 - 7.3.1 - Header Field Format specify that following lines of\n\t// multiline headers must begin by SP or TAB\n\tif header[0] == '\\t' || header[0] == ' ' {\n\n\t\theader = bytes.TrimSpace(header)\n\t\ts.Headers[s.lastHeaderParsed][len(s.Headers[s.lastHeaderParsed])-1] += fmt.Sprintf(\" %s\", string(header))\n\t\treturn\n\t}\n\n\t// Find the ':' to separate header name and value\n\tindex := bytes.Index(header, []byte(\":\"))\n\tif index >= 0 {\n\n\t\theaderName := strings.ToLower(string(bytes.Trim(header[:index], \" \")))\n\t\theaderValue := string(bytes.Trim(header[index+1:], \" \"))\n\n\t\t// Add header to object\n\t\ts.Headers[headerName] = append(s.Headers[headerName], headerValue)\n\t\ts.lastHeaderParsed = headerName\n\n\t\t// Compute specific headers\n\t\terr = s.ParseSpecificHeaders(headerName, headerValue)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// ParseSpecificHeaders will parse some specific key values from\n// specific headers like CSeq or Content-Length integer values\nfunc (s *SIP) ParseSpecificHeaders(headerName string, headerValue string) (err error) {\n\n\tswitch headerName {\n\tcase \"cseq\":\n\n\t\t// CSeq header value is formatted like that :\n\t\t// CSeq: 123 INVITE\n\t\t// We split the value to parse Cseq integer value, and method\n\t\tsplits := strings.Split(headerValue, \" \")\n\t\tif len(splits) > 1 {\n\n\t\t\t// Parse Cseq\n\t\t\ts.cseq, err = strconv.ParseInt(splits[0], 10, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// Validate method\n\t\t\tif s.IsResponse {\n\t\t\t\ts.Method, err = GetSIPMethod(splits[1])\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\t}\n\n\tcase \"content-length\":\n\n\t\t// Parse Content-Length\n\t\ts.contentLength, err = strconv.ParseInt(headerValue, 10, 64)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// GetAllHeaders will return the full headers of the\n// current SIP packets in a map[string][]string\nfunc (s *SIP) GetAllHeaders() map[string][]string {\n\treturn s.Headers\n}\n\n// GetHeader will return all the headers with\n// the specified name.\nfunc (s *SIP) GetHeader(headerName string) []string {\n\theaderName = strings.ToLower(headerName)\n\th := make([]string, 0)\n\tif _, ok := s.Headers[headerName]; ok {\n\t\treturn s.Headers[headerName]\n\t}\n\tcompactHeader := compactSipHeadersCorrespondance[headerName]\n\tif _, ok := s.Headers[compactHeader]; ok {\n\t\treturn s.Headers[compactHeader]\n\t}\n\treturn h\n}\n\n// GetFirstHeader will return the first header with\n// the specified name. If the current SIP packet has multiple\n// headers with the same name, it returns the first.\nfunc (s *SIP) GetFirstHeader(headerName string) string {\n\theaders := s.GetHeader(headerName)\n\tif len(headers) > 0 {\n\t\treturn headers[0]\n\t}\n\treturn \"\"\n}\n\n//\n// Some handy getters for most used SIP headers\n//\n\n// GetAuthorization will return the Authorization\n// header of the current SIP packet\nfunc (s *SIP) GetAuthorization() string {\n\treturn s.GetFirstHeader(\"Authorization\")\n}\n\n// GetFrom will return the From\n// header of the current SIP packet\nfunc (s *SIP) GetFrom() string {\n\treturn s.GetFirstHeader(\"From\")\n}\n\n// GetTo will return the To\n// header of the current SIP packet\nfunc (s *SIP) GetTo() string {\n\treturn s.GetFirstHeader(\"To\")\n}\n\n// GetContact will return the Contact\n// header of the current SIP packet\nfunc (s *SIP) GetContact() string {\n\treturn s.GetFirstHeader(\"Contact\")\n}\n\n// GetCallID will return the Call-ID\n// header of the current SIP packet\nfunc (s *SIP) GetCallID() string {\n\treturn s.GetFirstHeader(\"Call-ID\")\n}\n\n// GetUserAgent will return the User-Agent\n// header of the current SIP packet\nfunc (s *SIP) GetUserAgent() string {\n\treturn s.GetFirstHeader(\"User-Agent\")\n}\n\n// GetContentLength will return the parsed integer\n// Content-Length header of the current SIP packet\nfunc (s *SIP) GetContentLength() int64 {\n\treturn s.contentLength\n}\n\n// GetCSeq will return the parsed integer CSeq header\n// header of the current SIP packet\nfunc (s *SIP) GetCSeq() int64 {\n\treturn s.cseq\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/stp.go",
    "content": "// Copyright 2017 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"github.com/google/gopacket\"\n)\n\n// STP decode spanning tree protocol packets to transport BPDU (bridge protocol data unit) message.\ntype STP struct {\n\tBaseLayer\n}\n\n// LayerType returns gopacket.LayerTypeSTP.\nfunc (s *STP) LayerType() gopacket.LayerType { return LayerTypeSTP }\n\nfunc decodeSTP(data []byte, p gopacket.PacketBuilder) error {\n\tstp := &STP{}\n\tstp.Contents = data[:]\n\t// TODO:  parse the STP protocol into actual subfields.\n\tp.AddLayer(stp)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/tcp.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n// Copyright 2009-2011 Andreas Krennmair. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// TCP is the layer for TCP headers.\ntype TCP struct {\n\tBaseLayer\n\tSrcPort, DstPort                           TCPPort\n\tSeq                                        uint32\n\tAck                                        uint32\n\tDataOffset                                 uint8\n\tFIN, SYN, RST, PSH, ACK, URG, ECE, CWR, NS bool\n\tWindow                                     uint16\n\tChecksum                                   uint16\n\tUrgent                                     uint16\n\tsPort, dPort                               []byte\n\tOptions                                    []TCPOption\n\tPadding                                    []byte\n\topts                                       [4]TCPOption\n\ttcpipchecksum\n}\n\n// TCPOptionKind represents a TCP option code.\ntype TCPOptionKind uint8\n\nconst (\n\tTCPOptionKindEndList                         = 0\n\tTCPOptionKindNop                             = 1\n\tTCPOptionKindMSS                             = 2  // len = 4\n\tTCPOptionKindWindowScale                     = 3  // len = 3\n\tTCPOptionKindSACKPermitted                   = 4  // len = 2\n\tTCPOptionKindSACK                            = 5  // len = n\n\tTCPOptionKindEcho                            = 6  // len = 6, obsolete\n\tTCPOptionKindEchoReply                       = 7  // len = 6, obsolete\n\tTCPOptionKindTimestamps                      = 8  // len = 10\n\tTCPOptionKindPartialOrderConnectionPermitted = 9  // len = 2, obsolete\n\tTCPOptionKindPartialOrderServiceProfile      = 10 // len = 3, obsolete\n\tTCPOptionKindCC                              = 11 // obsolete\n\tTCPOptionKindCCNew                           = 12 // obsolete\n\tTCPOptionKindCCEcho                          = 13 // obsolete\n\tTCPOptionKindAltChecksum                     = 14 // len = 3, obsolete\n\tTCPOptionKindAltChecksumData                 = 15 // len = n, obsolete\n)\n\nfunc (k TCPOptionKind) String() string {\n\tswitch k {\n\tcase TCPOptionKindEndList:\n\t\treturn \"EndList\"\n\tcase TCPOptionKindNop:\n\t\treturn \"NOP\"\n\tcase TCPOptionKindMSS:\n\t\treturn \"MSS\"\n\tcase TCPOptionKindWindowScale:\n\t\treturn \"WindowScale\"\n\tcase TCPOptionKindSACKPermitted:\n\t\treturn \"SACKPermitted\"\n\tcase TCPOptionKindSACK:\n\t\treturn \"SACK\"\n\tcase TCPOptionKindEcho:\n\t\treturn \"Echo\"\n\tcase TCPOptionKindEchoReply:\n\t\treturn \"EchoReply\"\n\tcase TCPOptionKindTimestamps:\n\t\treturn \"Timestamps\"\n\tcase TCPOptionKindPartialOrderConnectionPermitted:\n\t\treturn \"PartialOrderConnectionPermitted\"\n\tcase TCPOptionKindPartialOrderServiceProfile:\n\t\treturn \"PartialOrderServiceProfile\"\n\tcase TCPOptionKindCC:\n\t\treturn \"CC\"\n\tcase TCPOptionKindCCNew:\n\t\treturn \"CCNew\"\n\tcase TCPOptionKindCCEcho:\n\t\treturn \"CCEcho\"\n\tcase TCPOptionKindAltChecksum:\n\t\treturn \"AltChecksum\"\n\tcase TCPOptionKindAltChecksumData:\n\t\treturn \"AltChecksumData\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"Unknown(%d)\", k)\n\t}\n}\n\ntype TCPOption struct {\n\tOptionType   TCPOptionKind\n\tOptionLength uint8\n\tOptionData   []byte\n}\n\nfunc (t TCPOption) String() string {\n\thd := hex.EncodeToString(t.OptionData)\n\tif len(hd) > 0 {\n\t\thd = \" 0x\" + hd\n\t}\n\tswitch t.OptionType {\n\tcase TCPOptionKindMSS:\n\t\tif len(t.OptionData) >= 2 {\n\t\t\treturn fmt.Sprintf(\"TCPOption(%s:%v%s)\",\n\t\t\t\tt.OptionType,\n\t\t\t\tbinary.BigEndian.Uint16(t.OptionData),\n\t\t\t\thd)\n\t\t}\n\n\tcase TCPOptionKindTimestamps:\n\t\tif len(t.OptionData) == 8 {\n\t\t\treturn fmt.Sprintf(\"TCPOption(%s:%v/%v%s)\",\n\t\t\t\tt.OptionType,\n\t\t\t\tbinary.BigEndian.Uint32(t.OptionData[:4]),\n\t\t\t\tbinary.BigEndian.Uint32(t.OptionData[4:8]),\n\t\t\t\thd)\n\t\t}\n\t}\n\treturn fmt.Sprintf(\"TCPOption(%s:%s)\", t.OptionType, hd)\n}\n\n// LayerType returns gopacket.LayerTypeTCP\nfunc (t *TCP) LayerType() gopacket.LayerType { return LayerTypeTCP }\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (t *TCP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tvar optionLength int\n\tfor _, o := range t.Options {\n\t\tswitch o.OptionType {\n\t\tcase 0, 1:\n\t\t\toptionLength += 1\n\t\tdefault:\n\t\t\toptionLength += 2 + len(o.OptionData)\n\t\t}\n\t}\n\tif opts.FixLengths {\n\t\tif rem := optionLength % 4; rem != 0 {\n\t\t\tt.Padding = lotsOfZeros[:4-rem]\n\t\t}\n\t\tt.DataOffset = uint8((len(t.Padding) + optionLength + 20) / 4)\n\t}\n\tbytes, err := b.PrependBytes(20 + optionLength + len(t.Padding))\n\tif err != nil {\n\t\treturn err\n\t}\n\tbinary.BigEndian.PutUint16(bytes, uint16(t.SrcPort))\n\tbinary.BigEndian.PutUint16(bytes[2:], uint16(t.DstPort))\n\tbinary.BigEndian.PutUint32(bytes[4:], t.Seq)\n\tbinary.BigEndian.PutUint32(bytes[8:], t.Ack)\n\tbinary.BigEndian.PutUint16(bytes[12:], t.flagsAndOffset())\n\tbinary.BigEndian.PutUint16(bytes[14:], t.Window)\n\tbinary.BigEndian.PutUint16(bytes[18:], t.Urgent)\n\tstart := 20\n\tfor _, o := range t.Options {\n\t\tbytes[start] = byte(o.OptionType)\n\t\tswitch o.OptionType {\n\t\tcase 0, 1:\n\t\t\tstart++\n\t\tdefault:\n\t\t\tif opts.FixLengths {\n\t\t\t\to.OptionLength = uint8(len(o.OptionData) + 2)\n\t\t\t}\n\t\t\tbytes[start+1] = o.OptionLength\n\t\t\tcopy(bytes[start+2:start+len(o.OptionData)+2], o.OptionData)\n\t\t\tstart += len(o.OptionData) + 2\n\t\t}\n\t}\n\tcopy(bytes[start:], t.Padding)\n\tif opts.ComputeChecksums {\n\t\t// zero out checksum bytes in current serialization.\n\t\tbytes[16] = 0\n\t\tbytes[17] = 0\n\t\tcsum, err := t.computeChecksum(b.Bytes(), IPProtocolTCP)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tt.Checksum = csum\n\t}\n\tbinary.BigEndian.PutUint16(bytes[16:], t.Checksum)\n\treturn nil\n}\n\nfunc (t *TCP) ComputeChecksum() (uint16, error) {\n\treturn t.computeChecksum(append(t.Contents, t.Payload...), IPProtocolTCP)\n}\n\nfunc (t *TCP) flagsAndOffset() uint16 {\n\tf := uint16(t.DataOffset) << 12\n\tif t.FIN {\n\t\tf |= 0x0001\n\t}\n\tif t.SYN {\n\t\tf |= 0x0002\n\t}\n\tif t.RST {\n\t\tf |= 0x0004\n\t}\n\tif t.PSH {\n\t\tf |= 0x0008\n\t}\n\tif t.ACK {\n\t\tf |= 0x0010\n\t}\n\tif t.URG {\n\t\tf |= 0x0020\n\t}\n\tif t.ECE {\n\t\tf |= 0x0040\n\t}\n\tif t.CWR {\n\t\tf |= 0x0080\n\t}\n\tif t.NS {\n\t\tf |= 0x0100\n\t}\n\treturn f\n}\n\nfunc (tcp *TCP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 20 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"Invalid TCP header. Length %d less than 20\", len(data))\n\t}\n\ttcp.SrcPort = TCPPort(binary.BigEndian.Uint16(data[0:2]))\n\ttcp.sPort = data[0:2]\n\ttcp.DstPort = TCPPort(binary.BigEndian.Uint16(data[2:4]))\n\ttcp.dPort = data[2:4]\n\ttcp.Seq = binary.BigEndian.Uint32(data[4:8])\n\ttcp.Ack = binary.BigEndian.Uint32(data[8:12])\n\ttcp.DataOffset = data[12] >> 4\n\ttcp.FIN = data[13]&0x01 != 0\n\ttcp.SYN = data[13]&0x02 != 0\n\ttcp.RST = data[13]&0x04 != 0\n\ttcp.PSH = data[13]&0x08 != 0\n\ttcp.ACK = data[13]&0x10 != 0\n\ttcp.URG = data[13]&0x20 != 0\n\ttcp.ECE = data[13]&0x40 != 0\n\ttcp.CWR = data[13]&0x80 != 0\n\ttcp.NS = data[12]&0x01 != 0\n\ttcp.Window = binary.BigEndian.Uint16(data[14:16])\n\ttcp.Checksum = binary.BigEndian.Uint16(data[16:18])\n\ttcp.Urgent = binary.BigEndian.Uint16(data[18:20])\n\tif tcp.Options == nil {\n\t\t// Pre-allocate to avoid allocating a slice.\n\t\ttcp.Options = tcp.opts[:0]\n\t} else {\n\t\ttcp.Options = tcp.Options[:0]\n\t}\n\ttcp.Padding = tcp.Padding[:0]\n\tif tcp.DataOffset < 5 {\n\t\treturn fmt.Errorf(\"Invalid TCP data offset %d < 5\", tcp.DataOffset)\n\t}\n\tdataStart := int(tcp.DataOffset) * 4\n\tif dataStart > len(data) {\n\t\tdf.SetTruncated()\n\t\ttcp.Payload = nil\n\t\ttcp.Contents = data\n\t\treturn errors.New(\"TCP data offset greater than packet length\")\n\t}\n\ttcp.Contents = data[:dataStart]\n\ttcp.Payload = data[dataStart:]\n\t// From here on, data points just to the header options.\n\tdata = data[20:dataStart]\nOPTIONS:\n\tfor len(data) > 0 {\n\t\ttcp.Options = append(tcp.Options, TCPOption{OptionType: TCPOptionKind(data[0])})\n\t\topt := &tcp.Options[len(tcp.Options)-1]\n\t\tswitch opt.OptionType {\n\t\tcase TCPOptionKindEndList: // End of options\n\t\t\topt.OptionLength = 1\n\t\t\ttcp.Padding = data[1:]\n\t\t\tbreak OPTIONS\n\t\tcase TCPOptionKindNop: // 1 byte padding\n\t\t\topt.OptionLength = 1\n\t\tdefault:\n\t\t\tif len(data) < 2 {\n\t\t\t\tdf.SetTruncated()\n\t\t\t\treturn fmt.Errorf(\"Invalid TCP option length. Length %d less than 2\", len(data))\n\t\t\t}\n\t\t\topt.OptionLength = data[1]\n\t\t\tif opt.OptionLength < 2 {\n\t\t\t\treturn fmt.Errorf(\"Invalid TCP option length %d < 2\", opt.OptionLength)\n\t\t\t} else if int(opt.OptionLength) > len(data) {\n\t\t\t\tdf.SetTruncated()\n\t\t\t\treturn fmt.Errorf(\"Invalid TCP option length %d exceeds remaining %d bytes\", opt.OptionLength, len(data))\n\t\t\t}\n\t\t\topt.OptionData = data[2:opt.OptionLength]\n\t\t}\n\t\tdata = data[opt.OptionLength:]\n\t}\n\treturn nil\n}\n\nfunc (t *TCP) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeTCP\n}\n\nfunc (t *TCP) NextLayerType() gopacket.LayerType {\n\tlt := t.DstPort.LayerType()\n\tif lt == gopacket.LayerTypePayload {\n\t\tlt = t.SrcPort.LayerType()\n\t}\n\treturn lt\n}\n\nfunc decodeTCP(data []byte, p gopacket.PacketBuilder) error {\n\ttcp := &TCP{}\n\terr := tcp.DecodeFromBytes(data, p)\n\tp.AddLayer(tcp)\n\tp.SetTransportLayer(tcp)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif p.DecodeOptions().DecodeStreamsAsDatagrams {\n\t\treturn p.NextDecoder(tcp.NextLayerType())\n\t} else {\n\t\treturn p.NextDecoder(gopacket.LayerTypePayload)\n\t}\n}\n\nfunc (t *TCP) TransportFlow() gopacket.Flow {\n\treturn gopacket.NewFlow(EndpointTCPPort, t.sPort, t.dPort)\n}\n\n// For testing only\nfunc (t *TCP) SetInternalPortsForTesting() {\n\tt.sPort = make([]byte, 2)\n\tt.dPort = make([]byte, 2)\n\tbinary.BigEndian.PutUint16(t.sPort, uint16(t.SrcPort))\n\tbinary.BigEndian.PutUint16(t.dPort, uint16(t.DstPort))\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/tcpip.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n// Copyright 2009-2011 Andreas Krennmair. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// Checksum computation for TCP/UDP.\ntype tcpipchecksum struct {\n\tpseudoheader tcpipPseudoHeader\n}\n\ntype tcpipPseudoHeader interface {\n\tpseudoheaderChecksum() (uint32, error)\n}\n\nfunc (ip *IPv4) pseudoheaderChecksum() (csum uint32, err error) {\n\tif err := ip.AddressTo4(); err != nil {\n\t\treturn 0, err\n\t}\n\tcsum += (uint32(ip.SrcIP[0]) + uint32(ip.SrcIP[2])) << 8\n\tcsum += uint32(ip.SrcIP[1]) + uint32(ip.SrcIP[3])\n\tcsum += (uint32(ip.DstIP[0]) + uint32(ip.DstIP[2])) << 8\n\tcsum += uint32(ip.DstIP[1]) + uint32(ip.DstIP[3])\n\treturn csum, nil\n}\n\nfunc (ip *IPv6) pseudoheaderChecksum() (csum uint32, err error) {\n\tif err := ip.AddressTo16(); err != nil {\n\t\treturn 0, err\n\t}\n\tfor i := 0; i < 16; i += 2 {\n\t\tcsum += uint32(ip.SrcIP[i]) << 8\n\t\tcsum += uint32(ip.SrcIP[i+1])\n\t\tcsum += uint32(ip.DstIP[i]) << 8\n\t\tcsum += uint32(ip.DstIP[i+1])\n\t}\n\treturn csum, nil\n}\n\n// Calculate the TCP/IP checksum defined in rfc1071.  The passed-in csum is any\n// initial checksum data that's already been computed.\nfunc tcpipChecksum(data []byte, csum uint32) uint16 {\n\t// to handle odd lengths, we loop to length - 1, incrementing by 2, then\n\t// handle the last byte specifically by checking against the original\n\t// length.\n\tlength := len(data) - 1\n\tfor i := 0; i < length; i += 2 {\n\t\t// For our test packet, doing this manually is about 25% faster\n\t\t// (740 ns vs. 1000ns) than doing it by calling binary.BigEndian.Uint16.\n\t\tcsum += uint32(data[i]) << 8\n\t\tcsum += uint32(data[i+1])\n\t}\n\tif len(data)%2 == 1 {\n\t\tcsum += uint32(data[length]) << 8\n\t}\n\tfor csum > 0xffff {\n\t\tcsum = (csum >> 16) + (csum & 0xffff)\n\t}\n\treturn ^uint16(csum)\n}\n\n// computeChecksum computes a TCP or UDP checksum.  headerAndPayload is the\n// serialized TCP or UDP header plus its payload, with the checksum zero'd\n// out. headerProtocol is the IP protocol number of the upper-layer header.\nfunc (c *tcpipchecksum) computeChecksum(headerAndPayload []byte, headerProtocol IPProtocol) (uint16, error) {\n\tif c.pseudoheader == nil {\n\t\treturn 0, errors.New(\"TCP/IP layer 4 checksum cannot be computed without network layer... call SetNetworkLayerForChecksum to set which layer to use\")\n\t}\n\tlength := uint32(len(headerAndPayload))\n\tcsum, err := c.pseudoheader.pseudoheaderChecksum()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tcsum += uint32(headerProtocol)\n\tcsum += length & 0xffff\n\tcsum += length >> 16\n\treturn tcpipChecksum(headerAndPayload, csum), nil\n}\n\n// SetNetworkLayerForChecksum tells this layer which network layer is wrapping it.\n// This is needed for computing the checksum when serializing, since TCP/IP transport\n// layer checksums depends on fields in the IPv4 or IPv6 layer that contains it.\n// The passed in layer must be an *IPv4 or *IPv6.\nfunc (i *tcpipchecksum) SetNetworkLayerForChecksum(l gopacket.NetworkLayer) error {\n\tswitch v := l.(type) {\n\tcase *IPv4:\n\t\ti.pseudoheader = v\n\tcase *IPv6:\n\t\ti.pseudoheader = v\n\tdefault:\n\t\treturn fmt.Errorf(\"cannot use layer type %v for tcp checksum network layer\", l.LayerType())\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/test_creator.py",
    "content": "#!/usr/bin/python\n# Copyright 2012 Google, Inc. All rights reserved.\n\n\"\"\"TestCreator creates test templates from pcap files.\"\"\"\n\nimport argparse\nimport base64\nimport glob\nimport re\nimport string\nimport subprocess\nimport sys\n\n\nclass Packet(object):\n  \"\"\"Helper class encapsulating packet from a pcap file.\"\"\"\n\n  def __init__(self, packet_lines):\n    self.packet_lines = packet_lines\n    self.data = self._DecodeText(packet_lines)\n\n  @classmethod\n  def _DecodeText(cls, packet_lines):\n    packet_bytes = []\n    # First line is timestamp and stuff, skip it.\n    # Format: 0x0010:  0000 0020 3aff 3ffe 0000 0000 0000 0000  ....:.?.........\n\n    for line in packet_lines[1:]:\n      m = re.match(r'\\s+0x[a-f\\d]+:\\s+((?:[\\da-f]{2,4}\\s)*)', line, re.IGNORECASE)\n      if m is None: continue\n      for hexpart in m.group(1).split():\n        packet_bytes.append(base64.b16decode(hexpart.upper()))\n    return ''.join(packet_bytes)\n\n  def Test(self, name, link_type):\n    \"\"\"Yields a test using this packet, as a set of lines.\"\"\"\n    yield '// testPacket%s is the packet:' % name\n    for line in self.packet_lines:\n      yield '//   ' + line\n    yield 'var testPacket%s = []byte{' % name\n    data = list(self.data)\n    while data:\n      linebytes, data = data[:16], data[16:]\n      yield ''.join(['\\t'] + ['0x%02x, ' % ord(c) for c in linebytes])\n    yield '}'\n    yield 'func TestPacket%s(t *testing.T) {' % name\n    yield '\\tp := gopacket.NewPacket(testPacket%s, LinkType%s, gopacket.Default)' % (name, link_type)\n    yield '\\tif p.ErrorLayer() != nil {'\n    yield '\\t\\tt.Error(\"Failed to decode packet:\", p.ErrorLayer().Error())'\n    yield '\\t}'\n    yield '\\tcheckLayers(p, []gopacket.LayerType{LayerType%s, FILL_ME_IN_WITH_ACTUAL_LAYERS}, t)' % link_type\n    yield '}'\n    yield 'func BenchmarkDecodePacket%s(b *testing.B) {' % name\n    yield '\\tfor i := 0; i < b.N; i++ {'\n    yield '\\t\\tgopacket.NewPacket(testPacket%s, LinkType%s, gopacket.NoCopy)' % (name, link_type)\n    yield '\\t}'\n    yield '}'\n\n\n\ndef GetTcpdumpOutput(filename):\n  \"\"\"Runs tcpdump on the given file, returning output as string.\"\"\"\n  return subprocess.check_output(\n      ['tcpdump', '-XX', '-s', '0', '-n', '-r', filename])\n\n\ndef TcpdumpOutputToPackets(output):\n  \"\"\"Reads a pcap file with TCPDump, yielding Packet objects.\"\"\"\n  pdata = []\n  for line in output.splitlines():\n    if line[0] not in string.whitespace and pdata:\n      yield Packet(pdata)\n      pdata = []\n    pdata.append(line)\n  if pdata:\n    yield Packet(pdata)\n\n\ndef main():\n  class CustomHelpFormatter(argparse.ArgumentDefaultsHelpFormatter):\n    def _format_usage(self, usage, actions, groups, prefix=None):\n      header =('TestCreator creates gopacket tests using a pcap file.\\n\\n'\n               'Tests are written to standard out... they can then be \\n'\n               'copied into the file of your choice and modified as \\n'\n               'you see.\\n\\n')\n      return header + argparse.ArgumentDefaultsHelpFormatter._format_usage(\n        self, usage, actions, groups, prefix)\n\n  parser = argparse.ArgumentParser(formatter_class=CustomHelpFormatter)\n  parser.add_argument('--link_type', default='Ethernet', help='the link type (default: %(default)s)')\n  parser.add_argument('--name', default='Packet%d', help='the layer type, must have \"%d\" inside it')\n  parser.add_argument('files', metavar='file.pcap', type=str, nargs='+', help='the files to process')\n\n  args = parser.parse_args()\n\n  for arg in args.files:\n    for path in glob.glob(arg):\n      for i, packet in enumerate(TcpdumpOutputToPackets(GetTcpdumpOutput(path))):\n        print '\\n'.join(packet.Test(\n          args.name % i, args.link_type))\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/tls.go",
    "content": "// Copyright 2018 The GoPacket Authors. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// TLSType defines the type of data after the TLS Record\ntype TLSType uint8\n\n// TLSType known values.\nconst (\n\tTLSChangeCipherSpec TLSType = 20\n\tTLSAlert            TLSType = 21\n\tTLSHandshake        TLSType = 22\n\tTLSApplicationData  TLSType = 23\n\tTLSUnknown          TLSType = 255\n)\n\n// String shows the register type nicely formatted\nfunc (tt TLSType) String() string {\n\tswitch tt {\n\tdefault:\n\t\treturn \"Unknown\"\n\tcase TLSChangeCipherSpec:\n\t\treturn \"Change Cipher Spec\"\n\tcase TLSAlert:\n\t\treturn \"Alert\"\n\tcase TLSHandshake:\n\t\treturn \"Handshake\"\n\tcase TLSApplicationData:\n\t\treturn \"Application Data\"\n\t}\n}\n\n// TLSVersion represents the TLS version in numeric format\ntype TLSVersion uint16\n\n// Strings shows the TLS version nicely formatted\nfunc (tv TLSVersion) String() string {\n\tswitch tv {\n\tdefault:\n\t\treturn \"Unknown\"\n\tcase 0x0200:\n\t\treturn \"SSL 2.0\"\n\tcase 0x0300:\n\t\treturn \"SSL 3.0\"\n\tcase 0x0301:\n\t\treturn \"TLS 1.0\"\n\tcase 0x0302:\n\t\treturn \"TLS 1.1\"\n\tcase 0x0303:\n\t\treturn \"TLS 1.2\"\n\tcase 0x0304:\n\t\treturn \"TLS 1.3\"\n\t}\n}\n\n// TLS is specified in RFC 5246\n//\n//  TLS Record Protocol\n//  0  1  2  3  4  5  6  7  8\n//  +--+--+--+--+--+--+--+--+\n//  |     Content Type      |\n//  +--+--+--+--+--+--+--+--+\n//  |    Version (major)    |\n//  +--+--+--+--+--+--+--+--+\n//  |    Version (minor)    |\n//  +--+--+--+--+--+--+--+--+\n//  |        Length         |\n//  +--+--+--+--+--+--+--+--+\n//  |        Length         |\n//  +--+--+--+--+--+--+--+--+\n\n// TLS is actually a slide of TLSrecord structures\ntype TLS struct {\n\tBaseLayer\n\n\t// TLS Records\n\tChangeCipherSpec []TLSChangeCipherSpecRecord\n\tHandshake        []TLSHandshakeRecord\n\tAppData          []TLSAppDataRecord\n\tAlert            []TLSAlertRecord\n}\n\n// TLSRecordHeader contains all the information that each TLS Record types should have\ntype TLSRecordHeader struct {\n\tContentType TLSType\n\tVersion     TLSVersion\n\tLength      uint16\n}\n\n// LayerType returns gopacket.LayerTypeTLS.\nfunc (t *TLS) LayerType() gopacket.LayerType { return LayerTypeTLS }\n\n// decodeTLS decodes the byte slice into a TLS type. It also\n// setups the application Layer in PacketBuilder.\nfunc decodeTLS(data []byte, p gopacket.PacketBuilder) error {\n\tt := &TLS{}\n\terr := t.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\tp.AddLayer(t)\n\tp.SetApplicationLayer(t)\n\treturn nil\n}\n\n// DecodeFromBytes decodes the slice into the TLS struct.\nfunc (t *TLS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tt.BaseLayer.Contents = data\n\tt.BaseLayer.Payload = nil\n\n\tt.ChangeCipherSpec = t.ChangeCipherSpec[:0]\n\tt.Handshake = t.Handshake[:0]\n\tt.AppData = t.AppData[:0]\n\tt.Alert = t.Alert[:0]\n\n\treturn t.decodeTLSRecords(data, df)\n}\n\nfunc (t *TLS) decodeTLSRecords(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 5 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"TLS record too short\")\n\t}\n\n\t// since there are no further layers, the baselayer's content is\n\t// pointing to this layer\n\t// TODO: Consider removing this\n\tt.BaseLayer = BaseLayer{Contents: data[:len(data)]}\n\n\tvar h TLSRecordHeader\n\th.ContentType = TLSType(data[0])\n\th.Version = TLSVersion(binary.BigEndian.Uint16(data[1:3]))\n\th.Length = binary.BigEndian.Uint16(data[3:5])\n\n\tif h.ContentType.String() == \"Unknown\" {\n\t\treturn errors.New(\"Unknown TLS record type\")\n\t}\n\n\thl := 5 // header length\n\ttl := hl + int(h.Length)\n\tif len(data) < tl {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"TLS packet length mismatch\")\n\t}\n\n\tswitch h.ContentType {\n\tdefault:\n\t\treturn errors.New(\"Unknown TLS record type\")\n\tcase TLSChangeCipherSpec:\n\t\tvar r TLSChangeCipherSpecRecord\n\t\te := r.decodeFromBytes(h, data[hl:tl], df)\n\t\tif e != nil {\n\t\t\treturn e\n\t\t}\n\t\tt.ChangeCipherSpec = append(t.ChangeCipherSpec, r)\n\tcase TLSAlert:\n\t\tvar r TLSAlertRecord\n\t\te := r.decodeFromBytes(h, data[hl:tl], df)\n\t\tif e != nil {\n\t\t\treturn e\n\t\t}\n\t\tt.Alert = append(t.Alert, r)\n\tcase TLSHandshake:\n\t\tvar r TLSHandshakeRecord\n\t\te := r.decodeFromBytes(h, data[hl:tl], df)\n\t\tif e != nil {\n\t\t\treturn e\n\t\t}\n\t\tt.Handshake = append(t.Handshake, r)\n\tcase TLSApplicationData:\n\t\tvar r TLSAppDataRecord\n\t\te := r.decodeFromBytes(h, data[hl:tl], df)\n\t\tif e != nil {\n\t\t\treturn e\n\t\t}\n\t\tt.AppData = append(t.AppData, r)\n\t}\n\n\tif len(data) == tl {\n\t\treturn nil\n\t}\n\treturn t.decodeTLSRecords(data[tl:len(data)], df)\n}\n\n// CanDecode implements gopacket.DecodingLayer.\nfunc (t *TLS) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeTLS\n}\n\n// NextLayerType implements gopacket.DecodingLayer.\nfunc (t *TLS) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypeZero\n}\n\n// Payload returns nil, since TLS encrypted payload is inside TLSAppDataRecord\nfunc (t *TLS) Payload() []byte {\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\nfunc (t *TLS) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\ttotalLength := 0\n\tfor _, record := range t.ChangeCipherSpec {\n\t\tif opts.FixLengths {\n\t\t\trecord.Length = 1\n\t\t}\n\t\ttotalLength += 5 + 1 // length of header + record\n\t}\n\tfor range t.Handshake {\n\t\ttotalLength += 5\n\t\t// TODO\n\t}\n\tfor _, record := range t.AppData {\n\t\tif opts.FixLengths {\n\t\t\trecord.Length = uint16(len(record.Payload))\n\t\t}\n\t\ttotalLength += 5 + len(record.Payload)\n\t}\n\tfor _, record := range t.Alert {\n\t\tif len(record.EncryptedMsg) == 0 {\n\t\t\tif opts.FixLengths {\n\t\t\t\trecord.Length = 2\n\t\t\t}\n\t\t\ttotalLength += 5 + 2\n\t\t} else {\n\t\t\tif opts.FixLengths {\n\t\t\t\trecord.Length = uint16(len(record.EncryptedMsg))\n\t\t\t}\n\t\t\ttotalLength += 5 + len(record.EncryptedMsg)\n\t\t}\n\t}\n\tdata, err := b.PrependBytes(totalLength)\n\tif err != nil {\n\t\treturn err\n\t}\n\toff := 0\n\tfor _, record := range t.ChangeCipherSpec {\n\t\toff = encodeHeader(record.TLSRecordHeader, data, off)\n\t\tdata[off] = byte(record.Message)\n\t\toff++\n\t}\n\tfor _, record := range t.Handshake {\n\t\toff = encodeHeader(record.TLSRecordHeader, data, off)\n\t\t// TODO\n\t}\n\tfor _, record := range t.AppData {\n\t\toff = encodeHeader(record.TLSRecordHeader, data, off)\n\t\tcopy(data[off:], record.Payload)\n\t\toff += len(record.Payload)\n\t}\n\tfor _, record := range t.Alert {\n\t\toff = encodeHeader(record.TLSRecordHeader, data, off)\n\t\tif len(record.EncryptedMsg) == 0 {\n\t\t\tdata[off] = byte(record.Level)\n\t\t\tdata[off+1] = byte(record.Description)\n\t\t\toff += 2\n\t\t} else {\n\t\t\tcopy(data[off:], record.EncryptedMsg)\n\t\t\toff += len(record.EncryptedMsg)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc encodeHeader(header TLSRecordHeader, data []byte, offset int) int {\n\tdata[offset] = byte(header.ContentType)\n\tbinary.BigEndian.PutUint16(data[offset+1:], uint16(header.Version))\n\tbinary.BigEndian.PutUint16(data[offset+3:], header.Length)\n\n\treturn offset + 5\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/tls_alert.go",
    "content": "// Copyright 2018 The GoPacket Authors. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// TLSAlertLevel defines the alert level data type\ntype TLSAlertLevel uint8\n\n// TLSAlertDescr defines the alert descrption data type\ntype TLSAlertDescr uint8\n\nconst (\n\tTLSAlertWarning      TLSAlertLevel = 1\n\tTLSAlertFatal        TLSAlertLevel = 2\n\tTLSAlertUnknownLevel TLSAlertLevel = 255\n\n\tTLSAlertCloseNotify               TLSAlertDescr = 0\n\tTLSAlertUnexpectedMessage         TLSAlertDescr = 10\n\tTLSAlertBadRecordMac              TLSAlertDescr = 20\n\tTLSAlertDecryptionFailedRESERVED  TLSAlertDescr = 21\n\tTLSAlertRecordOverflow            TLSAlertDescr = 22\n\tTLSAlertDecompressionFailure      TLSAlertDescr = 30\n\tTLSAlertHandshakeFailure          TLSAlertDescr = 40\n\tTLSAlertNoCertificateRESERVED     TLSAlertDescr = 41\n\tTLSAlertBadCertificate            TLSAlertDescr = 42\n\tTLSAlertUnsupportedCertificate    TLSAlertDescr = 43\n\tTLSAlertCertificateRevoked        TLSAlertDescr = 44\n\tTLSAlertCertificateExpired        TLSAlertDescr = 45\n\tTLSAlertCertificateUnknown        TLSAlertDescr = 46\n\tTLSAlertIllegalParameter          TLSAlertDescr = 47\n\tTLSAlertUnknownCa                 TLSAlertDescr = 48\n\tTLSAlertAccessDenied              TLSAlertDescr = 49\n\tTLSAlertDecodeError               TLSAlertDescr = 50\n\tTLSAlertDecryptError              TLSAlertDescr = 51\n\tTLSAlertExportRestrictionRESERVED TLSAlertDescr = 60\n\tTLSAlertProtocolVersion           TLSAlertDescr = 70\n\tTLSAlertInsufficientSecurity      TLSAlertDescr = 71\n\tTLSAlertInternalError             TLSAlertDescr = 80\n\tTLSAlertUserCanceled              TLSAlertDescr = 90\n\tTLSAlertNoRenegotiation           TLSAlertDescr = 100\n\tTLSAlertUnsupportedExtension      TLSAlertDescr = 110\n\tTLSAlertUnknownDescription        TLSAlertDescr = 255\n)\n\n//  TLS Alert\n//  0  1  2  3  4  5  6  7  8\n//  +--+--+--+--+--+--+--+--+\n//  |         Level         |\n//  +--+--+--+--+--+--+--+--+\n//  |      Description      |\n//  +--+--+--+--+--+--+--+--+\n\n// TLSAlertRecord contains all the information that each Alert Record type should have\ntype TLSAlertRecord struct {\n\tTLSRecordHeader\n\n\tLevel       TLSAlertLevel\n\tDescription TLSAlertDescr\n\n\tEncryptedMsg []byte\n}\n\n// DecodeFromBytes decodes the slice into the TLS struct.\nfunc (t *TLSAlertRecord) decodeFromBytes(h TLSRecordHeader, data []byte, df gopacket.DecodeFeedback) error {\n\t// TLS Record Header\n\tt.ContentType = h.ContentType\n\tt.Version = h.Version\n\tt.Length = h.Length\n\n\tif len(data) < 2 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"TLS Alert packet too short\")\n\t}\n\n\tif t.Length == 2 {\n\t\tt.Level = TLSAlertLevel(data[0])\n\t\tt.Description = TLSAlertDescr(data[1])\n\t} else {\n\t\tt.Level = TLSAlertUnknownLevel\n\t\tt.Description = TLSAlertUnknownDescription\n\t\tt.EncryptedMsg = data\n\t}\n\n\treturn nil\n}\n\n// Strings shows the TLS alert level nicely formatted\nfunc (al TLSAlertLevel) String() string {\n\tswitch al {\n\tdefault:\n\t\treturn fmt.Sprintf(\"Unknown(%d)\", al)\n\tcase TLSAlertWarning:\n\t\treturn \"Warning\"\n\tcase TLSAlertFatal:\n\t\treturn \"Fatal\"\n\t}\n}\n\n// Strings shows the TLS alert description nicely formatted\nfunc (ad TLSAlertDescr) String() string {\n\tswitch ad {\n\tdefault:\n\t\treturn \"Unknown\"\n\tcase TLSAlertCloseNotify:\n\t\treturn \"close_notify\"\n\tcase TLSAlertUnexpectedMessage:\n\t\treturn \"unexpected_message\"\n\tcase TLSAlertBadRecordMac:\n\t\treturn \"bad_record_mac\"\n\tcase TLSAlertDecryptionFailedRESERVED:\n\t\treturn \"decryption_failed_RESERVED\"\n\tcase TLSAlertRecordOverflow:\n\t\treturn \"record_overflow\"\n\tcase TLSAlertDecompressionFailure:\n\t\treturn \"decompression_failure\"\n\tcase TLSAlertHandshakeFailure:\n\t\treturn \"handshake_failure\"\n\tcase TLSAlertNoCertificateRESERVED:\n\t\treturn \"no_certificate_RESERVED\"\n\tcase TLSAlertBadCertificate:\n\t\treturn \"bad_certificate\"\n\tcase TLSAlertUnsupportedCertificate:\n\t\treturn \"unsupported_certificate\"\n\tcase TLSAlertCertificateRevoked:\n\t\treturn \"certificate_revoked\"\n\tcase TLSAlertCertificateExpired:\n\t\treturn \"certificate_expired\"\n\tcase TLSAlertCertificateUnknown:\n\t\treturn \"certificate_unknown\"\n\tcase TLSAlertIllegalParameter:\n\t\treturn \"illegal_parameter\"\n\tcase TLSAlertUnknownCa:\n\t\treturn \"unknown_ca\"\n\tcase TLSAlertAccessDenied:\n\t\treturn \"access_denied\"\n\tcase TLSAlertDecodeError:\n\t\treturn \"decode_error\"\n\tcase TLSAlertDecryptError:\n\t\treturn \"decrypt_error\"\n\tcase TLSAlertExportRestrictionRESERVED:\n\t\treturn \"export_restriction_RESERVED\"\n\tcase TLSAlertProtocolVersion:\n\t\treturn \"protocol_version\"\n\tcase TLSAlertInsufficientSecurity:\n\t\treturn \"insufficient_security\"\n\tcase TLSAlertInternalError:\n\t\treturn \"internal_error\"\n\tcase TLSAlertUserCanceled:\n\t\treturn \"user_canceled\"\n\tcase TLSAlertNoRenegotiation:\n\t\treturn \"no_renegotiation\"\n\tcase TLSAlertUnsupportedExtension:\n\t\treturn \"unsupported_extension\"\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/tls_appdata.go",
    "content": "// Copyright 2018 The GoPacket Authors. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"errors\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// TLSAppDataRecord contains all the information that each AppData Record types should have\ntype TLSAppDataRecord struct {\n\tTLSRecordHeader\n\tPayload []byte\n}\n\n// DecodeFromBytes decodes the slice into the TLS struct.\nfunc (t *TLSAppDataRecord) decodeFromBytes(h TLSRecordHeader, data []byte, df gopacket.DecodeFeedback) error {\n\t// TLS Record Header\n\tt.ContentType = h.ContentType\n\tt.Version = h.Version\n\tt.Length = h.Length\n\n\tif len(data) != int(t.Length) {\n\t\treturn errors.New(\"TLS Application Data length mismatch\")\n\t}\n\n\tt.Payload = data\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/tls_cipherspec.go",
    "content": "// Copyright 2018 The GoPacket Authors. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"errors\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// TLSchangeCipherSpec defines the message value inside ChangeCipherSpec Record\ntype TLSchangeCipherSpec uint8\n\nconst (\n\tTLSChangecipherspecMessage TLSchangeCipherSpec = 1\n\tTLSChangecipherspecUnknown TLSchangeCipherSpec = 255\n)\n\n//  TLS Change Cipher Spec\n//  0  1  2  3  4  5  6  7  8\n//  +--+--+--+--+--+--+--+--+\n//  |        Message        |\n//  +--+--+--+--+--+--+--+--+\n\n// TLSChangeCipherSpecRecord defines the type of data inside ChangeCipherSpec Record\ntype TLSChangeCipherSpecRecord struct {\n\tTLSRecordHeader\n\n\tMessage TLSchangeCipherSpec\n}\n\n// DecodeFromBytes decodes the slice into the TLS struct.\nfunc (t *TLSChangeCipherSpecRecord) decodeFromBytes(h TLSRecordHeader, data []byte, df gopacket.DecodeFeedback) error {\n\t// TLS Record Header\n\tt.ContentType = h.ContentType\n\tt.Version = h.Version\n\tt.Length = h.Length\n\n\tif len(data) != 1 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"TLS Change Cipher Spec record incorrect length\")\n\t}\n\n\tt.Message = TLSchangeCipherSpec(data[0])\n\tif t.Message != TLSChangecipherspecMessage {\n\t\tt.Message = TLSChangecipherspecUnknown\n\t}\n\n\treturn nil\n}\n\n// String shows the message value nicely formatted\nfunc (ccs TLSchangeCipherSpec) String() string {\n\tswitch ccs {\n\tdefault:\n\t\treturn \"Unknown\"\n\tcase TLSChangecipherspecMessage:\n\t\treturn \"Change Cipher Spec Message\"\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/tls_handshake.go",
    "content": "// Copyright 2018 The GoPacket Authors. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"github.com/google/gopacket\"\n)\n\n// TLSHandshakeRecord defines the structure of a Handshare Record\ntype TLSHandshakeRecord struct {\n\tTLSRecordHeader\n}\n\n// DecodeFromBytes decodes the slice into the TLS struct.\nfunc (t *TLSHandshakeRecord) decodeFromBytes(h TLSRecordHeader, data []byte, df gopacket.DecodeFeedback) error {\n\t// TLS Record Header\n\tt.ContentType = h.ContentType\n\tt.Version = h.Version\n\tt.Length = h.Length\n\n\t// TODO\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/udp.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n// Copyright 2009-2011 Andreas Krennmair. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\n\t\"github.com/google/gopacket\"\n)\n\n// UDP is the layer for UDP headers.\ntype UDP struct {\n\tBaseLayer\n\tSrcPort, DstPort UDPPort\n\tLength           uint16\n\tChecksum         uint16\n\tsPort, dPort     []byte\n\ttcpipchecksum\n}\n\n// LayerType returns gopacket.LayerTypeUDP\nfunc (u *UDP) LayerType() gopacket.LayerType { return LayerTypeUDP }\n\nfunc (udp *UDP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 8 {\n\t\tdf.SetTruncated()\n\t\treturn fmt.Errorf(\"Invalid UDP header. Length %d less than 8\", len(data))\n\t}\n\tudp.SrcPort = UDPPort(binary.BigEndian.Uint16(data[0:2]))\n\tudp.sPort = data[0:2]\n\tudp.DstPort = UDPPort(binary.BigEndian.Uint16(data[2:4]))\n\tudp.dPort = data[2:4]\n\tudp.Length = binary.BigEndian.Uint16(data[4:6])\n\tudp.Checksum = binary.BigEndian.Uint16(data[6:8])\n\tudp.BaseLayer = BaseLayer{Contents: data[:8]}\n\tswitch {\n\tcase udp.Length >= 8:\n\t\thlen := int(udp.Length)\n\t\tif hlen > len(data) {\n\t\t\tdf.SetTruncated()\n\t\t\thlen = len(data)\n\t\t}\n\t\tudp.Payload = data[8:hlen]\n\tcase udp.Length == 0: // Jumbogram, use entire rest of data\n\t\tudp.Payload = data[8:]\n\tdefault:\n\t\treturn fmt.Errorf(\"UDP packet too small: %d bytes\", udp.Length)\n\t}\n\treturn nil\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (u *UDP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tvar jumbo bool\n\n\tpayload := b.Bytes()\n\tif _, ok := u.pseudoheader.(*IPv6); ok {\n\t\tif len(payload)+8 > 65535 {\n\t\t\tjumbo = true\n\t\t}\n\t}\n\tbytes, err := b.PrependBytes(8)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbinary.BigEndian.PutUint16(bytes, uint16(u.SrcPort))\n\tbinary.BigEndian.PutUint16(bytes[2:], uint16(u.DstPort))\n\tif opts.FixLengths {\n\t\tif jumbo {\n\t\t\tu.Length = 0\n\t\t} else {\n\t\t\tu.Length = uint16(len(payload)) + 8\n\t\t}\n\t}\n\tbinary.BigEndian.PutUint16(bytes[4:], u.Length)\n\tif opts.ComputeChecksums {\n\t\t// zero out checksum bytes\n\t\tbytes[6] = 0\n\t\tbytes[7] = 0\n\t\tcsum, err := u.computeChecksum(b.Bytes(), IPProtocolUDP)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tu.Checksum = csum\n\t}\n\tbinary.BigEndian.PutUint16(bytes[6:], u.Checksum)\n\treturn nil\n}\n\nfunc (u *UDP) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeUDP\n}\n\n// NextLayerType use the destination port to select the\n// right next decoder. It tries first to decode via the\n// destination port, then the source port.\nfunc (u *UDP) NextLayerType() gopacket.LayerType {\n\tif lt := u.DstPort.LayerType(); lt != gopacket.LayerTypePayload {\n\t\treturn lt\n\t}\n\treturn u.SrcPort.LayerType()\n}\n\nfunc decodeUDP(data []byte, p gopacket.PacketBuilder) error {\n\tudp := &UDP{}\n\terr := udp.DecodeFromBytes(data, p)\n\tp.AddLayer(udp)\n\tp.SetTransportLayer(udp)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn p.NextDecoder(udp.NextLayerType())\n}\n\nfunc (u *UDP) TransportFlow() gopacket.Flow {\n\treturn gopacket.NewFlow(EndpointUDPPort, u.sPort, u.dPort)\n}\n\n// For testing only\nfunc (u *UDP) SetInternalPortsForTesting() {\n\tu.sPort = make([]byte, 2)\n\tu.dPort = make([]byte, 2)\n\tbinary.BigEndian.PutUint16(u.sPort, uint16(u.SrcPort))\n\tbinary.BigEndian.PutUint16(u.dPort, uint16(u.DstPort))\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/udplite.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n// Copyright 2009-2011 Andreas Krennmair. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"github.com/google/gopacket\"\n)\n\n// UDPLite is the layer for UDP-Lite headers (rfc 3828).\ntype UDPLite struct {\n\tBaseLayer\n\tSrcPort, DstPort UDPLitePort\n\tChecksumCoverage uint16\n\tChecksum         uint16\n\tsPort, dPort     []byte\n}\n\n// LayerType returns gopacket.LayerTypeUDPLite\nfunc (u *UDPLite) LayerType() gopacket.LayerType { return LayerTypeUDPLite }\n\nfunc decodeUDPLite(data []byte, p gopacket.PacketBuilder) error {\n\tudp := &UDPLite{\n\t\tSrcPort:          UDPLitePort(binary.BigEndian.Uint16(data[0:2])),\n\t\tsPort:            data[0:2],\n\t\tDstPort:          UDPLitePort(binary.BigEndian.Uint16(data[2:4])),\n\t\tdPort:            data[2:4],\n\t\tChecksumCoverage: binary.BigEndian.Uint16(data[4:6]),\n\t\tChecksum:         binary.BigEndian.Uint16(data[6:8]),\n\t\tBaseLayer:        BaseLayer{data[:8], data[8:]},\n\t}\n\tp.AddLayer(udp)\n\tp.SetTransportLayer(udp)\n\treturn p.NextDecoder(gopacket.LayerTypePayload)\n}\n\nfunc (u *UDPLite) TransportFlow() gopacket.Flow {\n\treturn gopacket.NewFlow(EndpointUDPLitePort, u.sPort, u.dPort)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/usb.go",
    "content": "// Copyright 2014 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"github.com/google/gopacket\"\n)\n\ntype USBEventType uint8\n\nconst (\n\tUSBEventTypeSubmit   USBEventType = 'S'\n\tUSBEventTypeComplete USBEventType = 'C'\n\tUSBEventTypeError    USBEventType = 'E'\n)\n\nfunc (a USBEventType) String() string {\n\tswitch a {\n\tcase USBEventTypeSubmit:\n\t\treturn \"SUBMIT\"\n\tcase USBEventTypeComplete:\n\t\treturn \"COMPLETE\"\n\tcase USBEventTypeError:\n\t\treturn \"ERROR\"\n\tdefault:\n\t\treturn \"Unknown event type\"\n\t}\n}\n\ntype USBRequestBlockSetupRequest uint8\n\nconst (\n\tUSBRequestBlockSetupRequestGetStatus        USBRequestBlockSetupRequest = 0x00\n\tUSBRequestBlockSetupRequestClearFeature     USBRequestBlockSetupRequest = 0x01\n\tUSBRequestBlockSetupRequestSetFeature       USBRequestBlockSetupRequest = 0x03\n\tUSBRequestBlockSetupRequestSetAddress       USBRequestBlockSetupRequest = 0x05\n\tUSBRequestBlockSetupRequestGetDescriptor    USBRequestBlockSetupRequest = 0x06\n\tUSBRequestBlockSetupRequestSetDescriptor    USBRequestBlockSetupRequest = 0x07\n\tUSBRequestBlockSetupRequestGetConfiguration USBRequestBlockSetupRequest = 0x08\n\tUSBRequestBlockSetupRequestSetConfiguration USBRequestBlockSetupRequest = 0x09\n\tUSBRequestBlockSetupRequestSetIdle          USBRequestBlockSetupRequest = 0x0a\n)\n\nfunc (a USBRequestBlockSetupRequest) String() string {\n\tswitch a {\n\tcase USBRequestBlockSetupRequestGetStatus:\n\t\treturn \"GET_STATUS\"\n\tcase USBRequestBlockSetupRequestClearFeature:\n\t\treturn \"CLEAR_FEATURE\"\n\tcase USBRequestBlockSetupRequestSetFeature:\n\t\treturn \"SET_FEATURE\"\n\tcase USBRequestBlockSetupRequestSetAddress:\n\t\treturn \"SET_ADDRESS\"\n\tcase USBRequestBlockSetupRequestGetDescriptor:\n\t\treturn \"GET_DESCRIPTOR\"\n\tcase USBRequestBlockSetupRequestSetDescriptor:\n\t\treturn \"SET_DESCRIPTOR\"\n\tcase USBRequestBlockSetupRequestGetConfiguration:\n\t\treturn \"GET_CONFIGURATION\"\n\tcase USBRequestBlockSetupRequestSetConfiguration:\n\t\treturn \"SET_CONFIGURATION\"\n\tcase USBRequestBlockSetupRequestSetIdle:\n\t\treturn \"SET_IDLE\"\n\tdefault:\n\t\treturn \"UNKNOWN\"\n\t}\n}\n\ntype USBTransportType uint8\n\nconst (\n\tUSBTransportTypeTransferIn  USBTransportType = 0x80 // Indicates send or receive\n\tUSBTransportTypeIsochronous USBTransportType = 0x00 // Isochronous transfers occur continuously and periodically. They typically contain time sensitive information, such as an audio or video stream.\n\tUSBTransportTypeInterrupt   USBTransportType = 0x01 // Interrupt transfers are typically non-periodic, small device \"initiated\" communication requiring bounded latency, such as pointing devices or keyboards.\n\tUSBTransportTypeControl     USBTransportType = 0x02 // Control transfers are typically used for command and status operations.\n\tUSBTransportTypeBulk        USBTransportType = 0x03 // Bulk transfers can be used for large bursty data, using all remaining available bandwidth, no guarantees on bandwidth or latency, such as file transfers.\n)\n\ntype USBDirectionType uint8\n\nconst (\n\tUSBDirectionTypeUnknown USBDirectionType = iota\n\tUSBDirectionTypeIn\n\tUSBDirectionTypeOut\n)\n\nfunc (a USBDirectionType) String() string {\n\tswitch a {\n\tcase USBDirectionTypeIn:\n\t\treturn \"In\"\n\tcase USBDirectionTypeOut:\n\t\treturn \"Out\"\n\tdefault:\n\t\treturn \"Unknown direction type\"\n\t}\n}\n\n// The reference at http://www.beyondlogic.org/usbnutshell/usb1.shtml contains more information about the protocol.\ntype USB struct {\n\tBaseLayer\n\tID             uint64\n\tEventType      USBEventType\n\tTransferType   USBTransportType\n\tDirection      USBDirectionType\n\tEndpointNumber uint8\n\tDeviceAddress  uint8\n\tBusID          uint16\n\tTimestampSec   int64\n\tTimestampUsec  int32\n\tSetup          bool\n\tData           bool\n\tStatus         int32\n\tUrbLength      uint32\n\tUrbDataLength  uint32\n\n\tUrbInterval            uint32\n\tUrbStartFrame          uint32\n\tUrbCopyOfTransferFlags uint32\n\tIsoNumDesc             uint32\n}\n\nfunc (u *USB) LayerType() gopacket.LayerType { return LayerTypeUSB }\n\nfunc (m *USB) NextLayerType() gopacket.LayerType {\n\tif m.Setup {\n\t\treturn LayerTypeUSBRequestBlockSetup\n\t} else if m.Data {\n\t}\n\n\treturn m.TransferType.LayerType()\n}\n\nfunc decodeUSB(data []byte, p gopacket.PacketBuilder) error {\n\td := &USB{}\n\n\treturn decodingLayerDecoder(d, data, p)\n}\n\nfunc (m *USB) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 40 {\n\t\tdf.SetTruncated()\n\t\treturn errors.New(\"USB < 40 bytes\")\n\t}\n\tm.ID = binary.LittleEndian.Uint64(data[0:8])\n\tm.EventType = USBEventType(data[8])\n\tm.TransferType = USBTransportType(data[9])\n\n\tm.EndpointNumber = data[10] & 0x7f\n\tif data[10]&uint8(USBTransportTypeTransferIn) > 0 {\n\t\tm.Direction = USBDirectionTypeIn\n\t} else {\n\t\tm.Direction = USBDirectionTypeOut\n\t}\n\n\tm.DeviceAddress = data[11]\n\tm.BusID = binary.LittleEndian.Uint16(data[12:14])\n\n\tif uint(data[14]) == 0 {\n\t\tm.Setup = true\n\t}\n\n\tif uint(data[15]) == 0 {\n\t\tm.Data = true\n\t}\n\n\tm.TimestampSec = int64(binary.LittleEndian.Uint64(data[16:24]))\n\tm.TimestampUsec = int32(binary.LittleEndian.Uint32(data[24:28]))\n\tm.Status = int32(binary.LittleEndian.Uint32(data[28:32]))\n\tm.UrbLength = binary.LittleEndian.Uint32(data[32:36])\n\tm.UrbDataLength = binary.LittleEndian.Uint32(data[36:40])\n\n\tm.Contents = data[:40]\n\tm.Payload = data[40:]\n\n\tif m.Setup {\n\t\tm.Payload = data[40:]\n\t} else if m.Data {\n\t\tm.Payload = data[uint32(len(data))-m.UrbDataLength:]\n\t}\n\n\t// if 64 bit, dissect_linux_usb_pseudo_header_ext\n\tif false {\n\t\tm.UrbInterval = binary.LittleEndian.Uint32(data[40:44])\n\t\tm.UrbStartFrame = binary.LittleEndian.Uint32(data[44:48])\n\t\tm.UrbDataLength = binary.LittleEndian.Uint32(data[48:52])\n\t\tm.IsoNumDesc = binary.LittleEndian.Uint32(data[52:56])\n\t\tm.Contents = data[:56]\n\t\tm.Payload = data[56:]\n\t}\n\n\t// crc5 or crc16\n\t// eop (end of packet)\n\n\treturn nil\n}\n\ntype USBRequestBlockSetup struct {\n\tBaseLayer\n\tRequestType uint8\n\tRequest     USBRequestBlockSetupRequest\n\tValue       uint16\n\tIndex       uint16\n\tLength      uint16\n}\n\nfunc (u *USBRequestBlockSetup) LayerType() gopacket.LayerType { return LayerTypeUSBRequestBlockSetup }\n\nfunc (m *USBRequestBlockSetup) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\nfunc (m *USBRequestBlockSetup) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tm.RequestType = data[0]\n\tm.Request = USBRequestBlockSetupRequest(data[1])\n\tm.Value = binary.LittleEndian.Uint16(data[2:4])\n\tm.Index = binary.LittleEndian.Uint16(data[4:6])\n\tm.Length = binary.LittleEndian.Uint16(data[6:8])\n\tm.Contents = data[:8]\n\tm.Payload = data[8:]\n\treturn nil\n}\n\nfunc decodeUSBRequestBlockSetup(data []byte, p gopacket.PacketBuilder) error {\n\td := &USBRequestBlockSetup{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\ntype USBControl struct {\n\tBaseLayer\n}\n\nfunc (u *USBControl) LayerType() gopacket.LayerType { return LayerTypeUSBControl }\n\nfunc (m *USBControl) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\nfunc (m *USBControl) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tm.Contents = data\n\treturn nil\n}\n\nfunc decodeUSBControl(data []byte, p gopacket.PacketBuilder) error {\n\td := &USBControl{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\ntype USBInterrupt struct {\n\tBaseLayer\n}\n\nfunc (u *USBInterrupt) LayerType() gopacket.LayerType { return LayerTypeUSBInterrupt }\n\nfunc (m *USBInterrupt) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\nfunc (m *USBInterrupt) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tm.Contents = data\n\treturn nil\n}\n\nfunc decodeUSBInterrupt(data []byte, p gopacket.PacketBuilder) error {\n\td := &USBInterrupt{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n\ntype USBBulk struct {\n\tBaseLayer\n}\n\nfunc (u *USBBulk) LayerType() gopacket.LayerType { return LayerTypeUSBBulk }\n\nfunc (m *USBBulk) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypePayload\n}\n\nfunc (m *USBBulk) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tm.Contents = data\n\treturn nil\n}\n\nfunc decodeUSBBulk(data []byte, p gopacket.PacketBuilder) error {\n\td := &USBBulk{}\n\treturn decodingLayerDecoder(d, data, p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/vrrp.go",
    "content": "// Copyright 2016 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"net\"\n\n\t\"github.com/google/gopacket\"\n)\n\n/*\n\tThis layer provides decoding for Virtual Router Redundancy Protocol (VRRP) v2.\n\thttps://tools.ietf.org/html/rfc3768#section-5\n    0                   1                   2                   3\n    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |Version| Type  | Virtual Rtr ID|   Priority    | Count IP Addrs|\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |   Auth Type   |   Adver Int   |          Checksum             |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                         IP Address (1)                        |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                            .                                  |\n   |                            .                                  |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                         IP Address (n)                        |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                     Authentication Data (1)                   |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n   |                     Authentication Data (2)                   |\n   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n*/\n\ntype VRRPv2Type uint8\ntype VRRPv2AuthType uint8\n\nconst (\n\tVRRPv2Advertisement VRRPv2Type = 0x01 // router advertisement\n)\n\n// String conversions for VRRP message types\nfunc (v VRRPv2Type) String() string {\n\tswitch v {\n\tcase VRRPv2Advertisement:\n\t\treturn \"VRRPv2 Advertisement\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\nconst (\n\tVRRPv2AuthNoAuth    VRRPv2AuthType = 0x00 // No Authentication\n\tVRRPv2AuthReserved1 VRRPv2AuthType = 0x01 // Reserved field 1\n\tVRRPv2AuthReserved2 VRRPv2AuthType = 0x02 // Reserved field 2\n)\n\nfunc (v VRRPv2AuthType) String() string {\n\tswitch v {\n\tcase VRRPv2AuthNoAuth:\n\t\treturn \"No Authentication\"\n\tcase VRRPv2AuthReserved1:\n\t\treturn \"Reserved\"\n\tcase VRRPv2AuthReserved2:\n\t\treturn \"Reserved\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\n// VRRPv2 represents an VRRP v2 message.\ntype VRRPv2 struct {\n\tBaseLayer\n\tVersion      uint8          // The version field specifies the VRRP protocol version of this packet (v2)\n\tType         VRRPv2Type     // The type field specifies the type of this VRRP packet.  The only type defined in v2 is ADVERTISEMENT\n\tVirtualRtrID uint8          // identifies the virtual router this packet is reporting status for\n\tPriority     uint8          // specifies the sending VRRP router's priority for the virtual router (100 = default)\n\tCountIPAddr  uint8          // The number of IP addresses contained in this VRRP advertisement.\n\tAuthType     VRRPv2AuthType // identifies the authentication method being utilized\n\tAdverInt     uint8          // The Advertisement interval indicates the time interval (in seconds) between ADVERTISEMENTS.  The default is 1 second\n\tChecksum     uint16         // used to detect data corruption in the VRRP message.\n\tIPAddress    []net.IP       // one or more IP addresses associated with the virtual router. Specified in the CountIPAddr field.\n}\n\n// LayerType returns LayerTypeVRRP for VRRP v2 message.\nfunc (v *VRRPv2) LayerType() gopacket.LayerType { return LayerTypeVRRP }\n\nfunc (v *VRRPv2) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\n\tv.BaseLayer = BaseLayer{Contents: data[:len(data)]}\n\tv.Version = data[0] >> 4 // high nibble == VRRP version. We're expecting v2\n\n\tv.Type = VRRPv2Type(data[0] & 0x0F) // low nibble == VRRP type. Expecting 1 (advertisement)\n\tif v.Type != 1 {\n\t\t// rfc3768: A packet with unknown type MUST be discarded.\n\t\treturn errors.New(\"Unrecognized VRRPv2 type field.\")\n\t}\n\n\tv.VirtualRtrID = data[1]\n\tv.Priority = data[2]\n\n\tv.CountIPAddr = data[3]\n\tif v.CountIPAddr < 1 {\n\t\treturn errors.New(\"VRRPv2 number of IP addresses is not valid.\")\n\t}\n\n\tv.AuthType = VRRPv2AuthType(data[4])\n\tv.AdverInt = uint8(data[5])\n\tv.Checksum = binary.BigEndian.Uint16(data[6:8])\n\n\t// populate the IPAddress field. The number of addresses is specified in the v.CountIPAddr field\n\t// offset references the starting byte containing the list of ip addresses\n\toffset := 8\n\tfor i := uint8(0); i < v.CountIPAddr; i++ {\n\t\tv.IPAddress = append(v.IPAddress, data[offset:offset+4])\n\t\toffset += 4\n\t}\n\n\t//\tany trailing packets here may be authentication data and *should* be ignored in v2 as per RFC\n\t//\n\t//\t\t\t5.3.10.  Authentication Data\n\t//\n\t//\t\t\tThe authentication string is currently only used to maintain\n\t//\t\t\tbackwards compatibility with RFC 2338.  It SHOULD be set to zero on\n\t//\t   \t\ttransmission and ignored on reception.\n\treturn nil\n}\n\n// CanDecode specifies the layer type in which we are attempting to unwrap.\nfunc (v *VRRPv2) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeVRRP\n}\n\n// NextLayerType specifies the next layer that should be decoded. VRRP does not contain any further payload, so we set to 0\nfunc (v *VRRPv2) NextLayerType() gopacket.LayerType {\n\treturn gopacket.LayerTypeZero\n}\n\n// The VRRP packet does not include payload data. Setting byte slice to nil\nfunc (v *VRRPv2) Payload() []byte {\n\treturn nil\n}\n\n// decodeVRRP will parse VRRP v2\nfunc decodeVRRP(data []byte, p gopacket.PacketBuilder) error {\n\tif len(data) < 8 {\n\t\treturn errors.New(\"Not a valid VRRP packet. Packet length is too small.\")\n\t}\n\tv := &VRRPv2{}\n\treturn decodingLayerDecoder(v, data, p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers/vxlan.go",
    "content": "// Copyright 2016 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage layers\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/google/gopacket\"\n)\n\n//  VXLAN is specifed in RFC 7348 https://tools.ietf.org/html/rfc7348\n//  G, D, A, Group Policy ID from https://tools.ietf.org/html/draft-smith-vxlan-group-policy-00\n//  0                   1                   2                   3\n//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n//  0             8               16              24              32\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |G|R|R|R|I|R|R|R|R|D|R|R|A|R|R|R|       Group Policy ID         |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |     24 bit VXLAN Network Identifier           |   Reserved    |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n// VXLAN is a VXLAN packet header\ntype VXLAN struct {\n\tBaseLayer\n\tValidIDFlag      bool   // 'I' bit per RFC 7348\n\tVNI              uint32 // 'VXLAN Network Identifier' 24 bits per RFC 7348\n\tGBPExtension     bool   // 'G' bit per Group Policy https://tools.ietf.org/html/draft-smith-vxlan-group-policy-00\n\tGBPDontLearn     bool   // 'D' bit per Group Policy\n\tGBPApplied       bool   // 'A' bit per Group Policy\n\tGBPGroupPolicyID uint16 // 'Group Policy ID' 16 bits per Group Policy\n}\n\n// LayerType returns LayerTypeVXLAN\nfunc (vx *VXLAN) LayerType() gopacket.LayerType { return LayerTypeVXLAN }\n\n// CanDecode returns the layer type this DecodingLayer can decode\nfunc (vx *VXLAN) CanDecode() gopacket.LayerClass {\n\treturn LayerTypeVXLAN\n}\n\n// NextLayerType retuns the next layer we should see after vxlan\nfunc (vx *VXLAN) NextLayerType() gopacket.LayerType {\n\treturn LayerTypeEthernet\n}\n\n// DecodeFromBytes takes a byte buffer and decodes\nfunc (vx *VXLAN) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {\n\tif len(data) < 8 {\n\t\treturn errors.New(\"vxlan packet too small\")\n\t}\n\t// VNI is a 24bit number, Uint32 requires 32 bits\n\tvar buf [4]byte\n\tcopy(buf[1:], data[4:7])\n\n\t// RFC 7348 https://tools.ietf.org/html/rfc7348\n\tvx.ValidIDFlag = data[0]&0x08 > 0        // 'I' bit per RFC7348\n\tvx.VNI = binary.BigEndian.Uint32(buf[:]) // VXLAN Network Identifier per RFC7348\n\n\t// Group Based Policy https://tools.ietf.org/html/draft-smith-vxlan-group-policy-00\n\tvx.GBPExtension = data[0]&0x80 > 0                       // 'G' bit per the group policy draft\n\tvx.GBPDontLearn = data[1]&0x40 > 0                       // 'D' bit - the egress VTEP MUST NOT learn the source address of the encapsulated frame.\n\tvx.GBPApplied = data[1]&0x80 > 0                         // 'A' bit - indicates that the group policy has already been applied to this packet.\n\tvx.GBPGroupPolicyID = binary.BigEndian.Uint16(data[2:4]) // Policy ID as per the group policy draft\n\n\t// Layer information\n\tconst vxlanLength = 8\n\tvx.Contents = data[:vxlanLength]\n\tvx.Payload = data[vxlanLength:]\n\n\treturn nil\n\n}\n\nfunc decodeVXLAN(data []byte, p gopacket.PacketBuilder) error {\n\tvx := &VXLAN{}\n\terr := vx.DecodeFromBytes(data, p)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tp.AddLayer(vx)\n\treturn p.NextDecoder(LinkTypeEthernet)\n}\n\n// SerializeTo writes the serialized form of this layer into the\n// SerializationBuffer, implementing gopacket.SerializableLayer.\n// See the docs for gopacket.SerializableLayer for more info.\nfunc (vx *VXLAN) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {\n\tbytes, err := b.PrependBytes(8)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// PrependBytes does not guarantee that bytes are zeroed.  Setting flags via OR requires that they start off at zero\n\tbytes[0] = 0\n\tbytes[1] = 0\n\n\tif vx.ValidIDFlag {\n\t\tbytes[0] |= 0x08\n\t}\n\tif vx.GBPExtension {\n\t\tbytes[0] |= 0x80\n\t}\n\tif vx.GBPDontLearn {\n\t\tbytes[1] |= 0x40\n\t}\n\tif vx.GBPApplied {\n\t\tbytes[1] |= 0x80\n\t}\n\n\tbinary.BigEndian.PutUint16(bytes[2:4], vx.GBPGroupPolicyID)\n\tif vx.VNI >= 1<<24 {\n\t\treturn fmt.Errorf(\"Virtual Network Identifier = %x exceeds max for 24-bit uint\", vx.VNI)\n\t}\n\tbinary.BigEndian.PutUint32(bytes[4:8], vx.VNI<<8)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layers_decoder.go",
    "content": "// Copyright 2019 The GoPacket Authors. All rights reserved.\n\npackage gopacket\n\n// Created by gen.go, don't edit manually\n// Generated at 2019-06-18 11:37:31.308731293 +0600 +06 m=+0.000842599\n\n// LayersDecoder returns DecodingLayerFunc for specified\n// DecodingLayerContainer, LayerType value to start decoding with and\n// some DecodeFeedback.\nfunc LayersDecoder(dl DecodingLayerContainer, first LayerType, df DecodeFeedback) DecodingLayerFunc {\n\tfirstDec, ok := dl.Decoder(first)\n\tif !ok {\n\t\treturn func([]byte, *[]LayerType) (LayerType, error) {\n\t\t\treturn first, nil\n\t\t}\n\t}\n\tif dlc, ok := dl.(DecodingLayerSparse); ok {\n\t\treturn func(data []byte, decoded *[]LayerType) (LayerType, error) {\n\t\t\t*decoded = (*decoded)[:0] // Truncated decoded layers.\n\t\t\ttyp := first\n\t\t\tdecoder := firstDec\n\t\t\tfor {\n\t\t\t\tif err := decoder.DecodeFromBytes(data, df); err != nil {\n\t\t\t\t\treturn LayerTypeZero, err\n\t\t\t\t}\n\t\t\t\t*decoded = append(*decoded, typ)\n\t\t\t\ttyp = decoder.NextLayerType()\n\t\t\t\tif data = decoder.LayerPayload(); len(data) == 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif decoder, ok = dlc.Decoder(typ); !ok {\n\t\t\t\t\treturn typ, nil\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn LayerTypeZero, nil\n\t\t}\n\t}\n\tif dlc, ok := dl.(DecodingLayerArray); ok {\n\t\treturn func(data []byte, decoded *[]LayerType) (LayerType, error) {\n\t\t\t*decoded = (*decoded)[:0] // Truncated decoded layers.\n\t\t\ttyp := first\n\t\t\tdecoder := firstDec\n\t\t\tfor {\n\t\t\t\tif err := decoder.DecodeFromBytes(data, df); err != nil {\n\t\t\t\t\treturn LayerTypeZero, err\n\t\t\t\t}\n\t\t\t\t*decoded = append(*decoded, typ)\n\t\t\t\ttyp = decoder.NextLayerType()\n\t\t\t\tif data = decoder.LayerPayload(); len(data) == 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif decoder, ok = dlc.Decoder(typ); !ok {\n\t\t\t\t\treturn typ, nil\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn LayerTypeZero, nil\n\t\t}\n\t}\n\tif dlc, ok := dl.(DecodingLayerMap); ok {\n\t\treturn func(data []byte, decoded *[]LayerType) (LayerType, error) {\n\t\t\t*decoded = (*decoded)[:0] // Truncated decoded layers.\n\t\t\ttyp := first\n\t\t\tdecoder := firstDec\n\t\t\tfor {\n\t\t\t\tif err := decoder.DecodeFromBytes(data, df); err != nil {\n\t\t\t\t\treturn LayerTypeZero, err\n\t\t\t\t}\n\t\t\t\t*decoded = append(*decoded, typ)\n\t\t\t\ttyp = decoder.NextLayerType()\n\t\t\t\tif data = decoder.LayerPayload(); len(data) == 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif decoder, ok = dlc.Decoder(typ); !ok {\n\t\t\t\t\treturn typ, nil\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn LayerTypeZero, nil\n\t\t}\n\t}\n\tdlc := dl\n\treturn func(data []byte, decoded *[]LayerType) (LayerType, error) {\n\t\t*decoded = (*decoded)[:0] // Truncated decoded layers.\n\t\ttyp := first\n\t\tdecoder := firstDec\n\t\tfor {\n\t\t\tif err := decoder.DecodeFromBytes(data, df); err != nil {\n\t\t\t\treturn LayerTypeZero, err\n\t\t\t}\n\t\t\t*decoded = append(*decoded, typ)\n\t\t\ttyp = decoder.NextLayerType()\n\t\t\tif data = decoder.LayerPayload(); len(data) == 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif decoder, ok = dlc.Decoder(typ); !ok {\n\t\t\t\treturn typ, nil\n\t\t\t}\n\t\t}\n\t\treturn LayerTypeZero, nil\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/layertype.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage gopacket\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n)\n\n// LayerType is a unique identifier for each type of layer.  This enumeration\n// does not match with any externally available numbering scheme... it's solely\n// usable/useful within this library as a means for requesting layer types\n// (see Packet.Layer) and determining which types of layers have been decoded.\n//\n// New LayerTypes may be created by calling gopacket.RegisterLayerType.\ntype LayerType int64\n\n// LayerTypeMetadata contains metadata associated with each LayerType.\ntype LayerTypeMetadata struct {\n\t// Name is the string returned by each layer type's String method.\n\tName string\n\t// Decoder is the decoder to use when the layer type is passed in as a\n\t// Decoder.\n\tDecoder Decoder\n}\n\ntype layerTypeMetadata struct {\n\tinUse bool\n\tLayerTypeMetadata\n}\n\n// DecodersByLayerName maps layer names to decoders for those layers.\n// This allows users to specify decoders by name to a program and have that\n// program pick the correct decoder accordingly.\nvar DecodersByLayerName = map[string]Decoder{}\n\nconst maxLayerType = 2000\n\nvar ltMeta [maxLayerType]layerTypeMetadata\nvar ltMetaMap = map[LayerType]layerTypeMetadata{}\n\n// RegisterLayerType creates a new layer type and registers it globally.\n// The number passed in must be unique, or a runtime panic will occur.  Numbers\n// 0-999 are reserved for the gopacket library.  Numbers 1000-1999 should be\n// used for common application-specific types, and are very fast.  Any other\n// number (negative or >= 2000) may be used for uncommon application-specific\n// types, and are somewhat slower (they require a map lookup over an array\n// index).\nfunc RegisterLayerType(num int, meta LayerTypeMetadata) LayerType {\n\tif 0 <= num && num < maxLayerType {\n\t\tif ltMeta[num].inUse {\n\t\t\tpanic(\"Layer type already exists\")\n\t\t}\n\t} else {\n\t\tif ltMetaMap[LayerType(num)].inUse {\n\t\t\tpanic(\"Layer type already exists\")\n\t\t}\n\t}\n\treturn OverrideLayerType(num, meta)\n}\n\n// OverrideLayerType acts like RegisterLayerType, except that if the layer type\n// has already been registered, it overrides the metadata with the passed-in\n// metadata intead of panicing.\nfunc OverrideLayerType(num int, meta LayerTypeMetadata) LayerType {\n\tif 0 <= num && num < maxLayerType {\n\t\tltMeta[num] = layerTypeMetadata{\n\t\t\tinUse:             true,\n\t\t\tLayerTypeMetadata: meta,\n\t\t}\n\t} else {\n\t\tltMetaMap[LayerType(num)] = layerTypeMetadata{\n\t\t\tinUse:             true,\n\t\t\tLayerTypeMetadata: meta,\n\t\t}\n\t}\n\tDecodersByLayerName[meta.Name] = meta.Decoder\n\treturn LayerType(num)\n}\n\n// Decode decodes the given data using the decoder registered with the layer\n// type.\nfunc (t LayerType) Decode(data []byte, c PacketBuilder) error {\n\tvar d Decoder\n\tif 0 <= int(t) && int(t) < maxLayerType {\n\t\td = ltMeta[int(t)].Decoder\n\t} else {\n\t\td = ltMetaMap[t].Decoder\n\t}\n\tif d != nil {\n\t\treturn d.Decode(data, c)\n\t}\n\treturn fmt.Errorf(\"Layer type %v has no associated decoder\", t)\n}\n\n// String returns the string associated with this layer type.\nfunc (t LayerType) String() (s string) {\n\tif 0 <= int(t) && int(t) < maxLayerType {\n\t\ts = ltMeta[int(t)].Name\n\t} else {\n\t\ts = ltMetaMap[t].Name\n\t}\n\tif s == \"\" {\n\t\ts = strconv.Itoa(int(t))\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/packet.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage gopacket\n\nimport (\n\t\"bytes\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"reflect\"\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n)\n\n// CaptureInfo provides standardized information about a packet captured off\n// the wire or read from a file.\ntype CaptureInfo struct {\n\t// Timestamp is the time the packet was captured, if that is known.\n\tTimestamp time.Time\n\t// CaptureLength is the total number of bytes read off of the wire.\n\tCaptureLength int\n\t// Length is the size of the original packet.  Should always be >=\n\t// CaptureLength.\n\tLength int\n\t// InterfaceIndex\n\tInterfaceIndex int\n\t// The packet source can place ancillary data of various types here.\n\t// For example, the afpacket source can report the VLAN of captured\n\t// packets this way.\n\tAncillaryData []interface{}\n}\n\n// PacketMetadata contains metadata for a packet.\ntype PacketMetadata struct {\n\tCaptureInfo\n\t// Truncated is true if packet decoding logic detects that there are fewer\n\t// bytes in the packet than are detailed in various headers (for example, if\n\t// the number of bytes in the IPv4 contents/payload is less than IPv4.Length).\n\t// This is also set automatically for packets captured off the wire if\n\t// CaptureInfo.CaptureLength < CaptureInfo.Length.\n\tTruncated bool\n}\n\n// Packet is the primary object used by gopacket.  Packets are created by a\n// Decoder's Decode call.  A packet is made up of a set of Data, which\n// is broken into a number of Layers as it is decoded.\ntype Packet interface {\n\t//// Functions for outputting the packet as a human-readable string:\n\t//// ------------------------------------------------------------------\n\t// String returns a human-readable string representation of the packet.\n\t// It uses LayerString on each layer to output the layer.\n\tString() string\n\t// Dump returns a verbose human-readable string representation of the packet,\n\t// including a hex dump of all layers.  It uses LayerDump on each layer to\n\t// output the layer.\n\tDump() string\n\n\t//// Functions for accessing arbitrary packet layers:\n\t//// ------------------------------------------------------------------\n\t// Layers returns all layers in this packet, computing them as necessary\n\tLayers() []Layer\n\t// Layer returns the first layer in this packet of the given type, or nil\n\tLayer(LayerType) Layer\n\t// LayerClass returns the first layer in this packet of the given class,\n\t// or nil.\n\tLayerClass(LayerClass) Layer\n\n\t//// Functions for accessing specific types of packet layers.  These functions\n\t//// return the first layer of each type found within the packet.\n\t//// ------------------------------------------------------------------\n\t// LinkLayer returns the first link layer in the packet\n\tLinkLayer() LinkLayer\n\t// NetworkLayer returns the first network layer in the packet\n\tNetworkLayer() NetworkLayer\n\t// TransportLayer returns the first transport layer in the packet\n\tTransportLayer() TransportLayer\n\t// ApplicationLayer returns the first application layer in the packet\n\tApplicationLayer() ApplicationLayer\n\t// ErrorLayer is particularly useful, since it returns nil if the packet\n\t// was fully decoded successfully, and non-nil if an error was encountered\n\t// in decoding and the packet was only partially decoded.  Thus, its output\n\t// can be used to determine if the entire packet was able to be decoded.\n\tErrorLayer() ErrorLayer\n\n\t//// Functions for accessing data specific to the packet:\n\t//// ------------------------------------------------------------------\n\t// Data returns the set of bytes that make up this entire packet.\n\tData() []byte\n\t// Metadata returns packet metadata associated with this packet.\n\tMetadata() *PacketMetadata\n}\n\n// packet contains all the information we need to fulfill the Packet interface,\n// and its two \"subclasses\" (yes, no such thing in Go, bear with me),\n// eagerPacket and lazyPacket, provide eager and lazy decoding logic around the\n// various functions needed to access this information.\ntype packet struct {\n\t// data contains the entire packet data for a packet\n\tdata []byte\n\t// initialLayers is space for an initial set of layers already created inside\n\t// the packet.\n\tinitialLayers [6]Layer\n\t// layers contains each layer we've already decoded\n\tlayers []Layer\n\t// last is the last layer added to the packet\n\tlast Layer\n\t// metadata is the PacketMetadata for this packet\n\tmetadata PacketMetadata\n\n\tdecodeOptions DecodeOptions\n\n\t// Pointers to the various important layers\n\tlink        LinkLayer\n\tnetwork     NetworkLayer\n\ttransport   TransportLayer\n\tapplication ApplicationLayer\n\tfailure     ErrorLayer\n}\n\nfunc (p *packet) SetTruncated() {\n\tp.metadata.Truncated = true\n}\n\nfunc (p *packet) SetLinkLayer(l LinkLayer) {\n\tif p.link == nil {\n\t\tp.link = l\n\t}\n}\n\nfunc (p *packet) SetNetworkLayer(l NetworkLayer) {\n\tif p.network == nil {\n\t\tp.network = l\n\t}\n}\n\nfunc (p *packet) SetTransportLayer(l TransportLayer) {\n\tif p.transport == nil {\n\t\tp.transport = l\n\t}\n}\n\nfunc (p *packet) SetApplicationLayer(l ApplicationLayer) {\n\tif p.application == nil {\n\t\tp.application = l\n\t}\n}\n\nfunc (p *packet) SetErrorLayer(l ErrorLayer) {\n\tif p.failure == nil {\n\t\tp.failure = l\n\t}\n}\n\nfunc (p *packet) AddLayer(l Layer) {\n\tp.layers = append(p.layers, l)\n\tp.last = l\n}\n\nfunc (p *packet) DumpPacketData() {\n\tfmt.Fprint(os.Stderr, p.packetDump())\n\tos.Stderr.Sync()\n}\n\nfunc (p *packet) Metadata() *PacketMetadata {\n\treturn &p.metadata\n}\n\nfunc (p *packet) Data() []byte {\n\treturn p.data\n}\n\nfunc (p *packet) DecodeOptions() *DecodeOptions {\n\treturn &p.decodeOptions\n}\n\nfunc (p *packet) addFinalDecodeError(err error, stack []byte) {\n\tfail := &DecodeFailure{err: err, stack: stack}\n\tif p.last == nil {\n\t\tfail.data = p.data\n\t} else {\n\t\tfail.data = p.last.LayerPayload()\n\t}\n\tp.AddLayer(fail)\n\tp.SetErrorLayer(fail)\n}\n\nfunc (p *packet) recoverDecodeError() {\n\tif !p.decodeOptions.SkipDecodeRecovery {\n\t\tif r := recover(); r != nil {\n\t\t\tp.addFinalDecodeError(fmt.Errorf(\"%v\", r), debug.Stack())\n\t\t}\n\t}\n}\n\n// LayerString outputs an individual layer as a string.  The layer is output\n// in a single line, with no trailing newline.  This function is specifically\n// designed to do the right thing for most layers... it follows the following\n// rules:\n//  * If the Layer has a String function, just output that.\n//  * Otherwise, output all exported fields in the layer, recursing into\n//    exported slices and structs.\n// NOTE:  This is NOT THE SAME AS fmt's \"%#v\".  %#v will output both exported\n// and unexported fields... many times packet layers contain unexported stuff\n// that would just mess up the output of the layer, see for example the\n// Payload layer and it's internal 'data' field, which contains a large byte\n// array that would really mess up formatting.\nfunc LayerString(l Layer) string {\n\treturn fmt.Sprintf(\"%v\\t%s\", l.LayerType(), layerString(reflect.ValueOf(l), false, false))\n}\n\n// Dumper dumps verbose information on a value.  If a layer type implements\n// Dumper, then its LayerDump() string will include the results in its output.\ntype Dumper interface {\n\tDump() string\n}\n\n// LayerDump outputs a very verbose string representation of a layer.  Its\n// output is a concatenation of LayerString(l) and hex.Dump(l.LayerContents()).\n// It contains newlines and ends with a newline.\nfunc LayerDump(l Layer) string {\n\tvar b bytes.Buffer\n\tb.WriteString(LayerString(l))\n\tb.WriteByte('\\n')\n\tif d, ok := l.(Dumper); ok {\n\t\tdump := d.Dump()\n\t\tif dump != \"\" {\n\t\t\tb.WriteString(dump)\n\t\t\tif dump[len(dump)-1] != '\\n' {\n\t\t\t\tb.WriteByte('\\n')\n\t\t\t}\n\t\t}\n\t}\n\tb.WriteString(hex.Dump(l.LayerContents()))\n\treturn b.String()\n}\n\n// layerString outputs, recursively, a layer in a \"smart\" way.  See docs for\n// LayerString for more details.\n//\n// Params:\n//   i - value to write out\n//   anonymous:  if we're currently recursing an anonymous member of a struct\n//   writeSpace:  if we've already written a value in a struct, and need to\n//     write a space before writing more.  This happens when we write various\n//     anonymous values, and need to keep writing more.\nfunc layerString(v reflect.Value, anonymous bool, writeSpace bool) string {\n\t// Let String() functions take precedence.\n\tif v.CanInterface() {\n\t\tif s, ok := v.Interface().(fmt.Stringer); ok {\n\t\t\treturn s.String()\n\t\t}\n\t}\n\t// Reflect, and spit out all the exported fields as key=value.\n\tswitch v.Type().Kind() {\n\tcase reflect.Interface, reflect.Ptr:\n\t\tif v.IsNil() {\n\t\t\treturn \"nil\"\n\t\t}\n\t\tr := v.Elem()\n\t\treturn layerString(r, anonymous, writeSpace)\n\tcase reflect.Struct:\n\t\tvar b bytes.Buffer\n\t\ttyp := v.Type()\n\t\tif !anonymous {\n\t\t\tb.WriteByte('{')\n\t\t}\n\t\tfor i := 0; i < v.NumField(); i++ {\n\t\t\t// Check if this is upper-case.\n\t\t\tftype := typ.Field(i)\n\t\t\tf := v.Field(i)\n\t\t\tif ftype.Anonymous {\n\t\t\t\tanonStr := layerString(f, true, writeSpace)\n\t\t\t\twriteSpace = writeSpace || anonStr != \"\"\n\t\t\t\tb.WriteString(anonStr)\n\t\t\t} else if ftype.PkgPath == \"\" { // exported\n\t\t\t\tif writeSpace {\n\t\t\t\t\tb.WriteByte(' ')\n\t\t\t\t}\n\t\t\t\twriteSpace = true\n\t\t\t\tfmt.Fprintf(&b, \"%s=%s\", typ.Field(i).Name, layerString(f, false, writeSpace))\n\t\t\t}\n\t\t}\n\t\tif !anonymous {\n\t\t\tb.WriteByte('}')\n\t\t}\n\t\treturn b.String()\n\tcase reflect.Slice:\n\t\tvar b bytes.Buffer\n\t\tb.WriteByte('[')\n\t\tif v.Len() > 4 {\n\t\t\tfmt.Fprintf(&b, \"..%d..\", v.Len())\n\t\t} else {\n\t\t\tfor j := 0; j < v.Len(); j++ {\n\t\t\t\tif j != 0 {\n\t\t\t\t\tb.WriteString(\", \")\n\t\t\t\t}\n\t\t\t\tb.WriteString(layerString(v.Index(j), false, false))\n\t\t\t}\n\t\t}\n\t\tb.WriteByte(']')\n\t\treturn b.String()\n\t}\n\treturn fmt.Sprintf(\"%v\", v.Interface())\n}\n\nconst (\n\tlongBytesLength = 128\n)\n\n// LongBytesGoString returns a string representation of the byte slice shortened\n// using the format '<type>{<truncated slice> ... (<n> bytes)}' if it\n// exceeds a predetermined length. Can be used to avoid filling the display with\n// very long byte strings.\nfunc LongBytesGoString(buf []byte) string {\n\tif len(buf) < longBytesLength {\n\t\treturn fmt.Sprintf(\"%#v\", buf)\n\t}\n\ts := fmt.Sprintf(\"%#v\", buf[:longBytesLength-1])\n\ts = strings.TrimSuffix(s, \"}\")\n\treturn fmt.Sprintf(\"%s ... (%d bytes)}\", s, len(buf))\n}\n\nfunc baseLayerString(value reflect.Value) string {\n\tt := value.Type()\n\tcontent := value.Field(0)\n\tc := make([]byte, content.Len())\n\tfor i := range c {\n\t\tc[i] = byte(content.Index(i).Uint())\n\t}\n\tpayload := value.Field(1)\n\tp := make([]byte, payload.Len())\n\tfor i := range p {\n\t\tp[i] = byte(payload.Index(i).Uint())\n\t}\n\treturn fmt.Sprintf(\"%s{Contents:%s, Payload:%s}\", t.String(),\n\t\tLongBytesGoString(c),\n\t\tLongBytesGoString(p))\n}\n\nfunc layerGoString(i interface{}, b *bytes.Buffer) {\n\tif s, ok := i.(fmt.GoStringer); ok {\n\t\tb.WriteString(s.GoString())\n\t\treturn\n\t}\n\n\tvar v reflect.Value\n\tvar ok bool\n\tif v, ok = i.(reflect.Value); !ok {\n\t\tv = reflect.ValueOf(i)\n\t}\n\tswitch v.Kind() {\n\tcase reflect.Ptr, reflect.Interface:\n\t\tif v.Kind() == reflect.Ptr {\n\t\t\tb.WriteByte('&')\n\t\t}\n\t\tlayerGoString(v.Elem().Interface(), b)\n\tcase reflect.Struct:\n\t\tt := v.Type()\n\t\tb.WriteString(t.String())\n\t\tb.WriteByte('{')\n\t\tfor i := 0; i < v.NumField(); i++ {\n\t\t\tif i > 0 {\n\t\t\t\tb.WriteString(\", \")\n\t\t\t}\n\t\t\tif t.Field(i).Name == \"BaseLayer\" {\n\t\t\t\tfmt.Fprintf(b, \"BaseLayer:%s\", baseLayerString(v.Field(i)))\n\t\t\t} else if v.Field(i).Kind() == reflect.Struct {\n\t\t\t\tfmt.Fprintf(b, \"%s:\", t.Field(i).Name)\n\t\t\t\tlayerGoString(v.Field(i), b)\n\t\t\t} else if v.Field(i).Kind() == reflect.Ptr {\n\t\t\t\tb.WriteByte('&')\n\t\t\t\tlayerGoString(v.Field(i), b)\n\t\t\t} else {\n\t\t\t\tfmt.Fprintf(b, \"%s:%#v\", t.Field(i).Name, v.Field(i))\n\t\t\t}\n\t\t}\n\t\tb.WriteByte('}')\n\tdefault:\n\t\tfmt.Fprintf(b, \"%#v\", i)\n\t}\n}\n\n// LayerGoString returns a representation of the layer in Go syntax,\n// taking care to shorten \"very long\" BaseLayer byte slices\nfunc LayerGoString(l Layer) string {\n\tb := new(bytes.Buffer)\n\tlayerGoString(l, b)\n\treturn b.String()\n}\n\nfunc (p *packet) packetString() string {\n\tvar b bytes.Buffer\n\tfmt.Fprintf(&b, \"PACKET: %d bytes\", len(p.Data()))\n\tif p.metadata.Truncated {\n\t\tb.WriteString(\", truncated\")\n\t}\n\tif p.metadata.Length > 0 {\n\t\tfmt.Fprintf(&b, \", wire length %d cap length %d\", p.metadata.Length, p.metadata.CaptureLength)\n\t}\n\tif !p.metadata.Timestamp.IsZero() {\n\t\tfmt.Fprintf(&b, \" @ %v\", p.metadata.Timestamp)\n\t}\n\tb.WriteByte('\\n')\n\tfor i, l := range p.layers {\n\t\tfmt.Fprintf(&b, \"- Layer %d (%02d bytes) = %s\\n\", i+1, len(l.LayerContents()), LayerString(l))\n\t}\n\treturn b.String()\n}\n\nfunc (p *packet) packetDump() string {\n\tvar b bytes.Buffer\n\tfmt.Fprintf(&b, \"-- FULL PACKET DATA (%d bytes) ------------------------------------\\n%s\", len(p.data), hex.Dump(p.data))\n\tfor i, l := range p.layers {\n\t\tfmt.Fprintf(&b, \"--- Layer %d ---\\n%s\", i+1, LayerDump(l))\n\t}\n\treturn b.String()\n}\n\n// eagerPacket is a packet implementation that does eager decoding.  Upon\n// initial construction, it decodes all the layers it can from packet data.\n// eagerPacket implements Packet and PacketBuilder.\ntype eagerPacket struct {\n\tpacket\n}\n\nvar errNilDecoder = errors.New(\"NextDecoder passed nil decoder, probably an unsupported decode type\")\n\nfunc (p *eagerPacket) NextDecoder(next Decoder) error {\n\tif next == nil {\n\t\treturn errNilDecoder\n\t}\n\tif p.last == nil {\n\t\treturn errors.New(\"NextDecoder called, but no layers added yet\")\n\t}\n\td := p.last.LayerPayload()\n\tif len(d) == 0 {\n\t\treturn nil\n\t}\n\t// Since we're eager, immediately call the next decoder.\n\treturn next.Decode(d, p)\n}\nfunc (p *eagerPacket) initialDecode(dec Decoder) {\n\tdefer p.recoverDecodeError()\n\terr := dec.Decode(p.data, p)\n\tif err != nil {\n\t\tp.addFinalDecodeError(err, nil)\n\t}\n}\nfunc (p *eagerPacket) LinkLayer() LinkLayer {\n\treturn p.link\n}\nfunc (p *eagerPacket) NetworkLayer() NetworkLayer {\n\treturn p.network\n}\nfunc (p *eagerPacket) TransportLayer() TransportLayer {\n\treturn p.transport\n}\nfunc (p *eagerPacket) ApplicationLayer() ApplicationLayer {\n\treturn p.application\n}\nfunc (p *eagerPacket) ErrorLayer() ErrorLayer {\n\treturn p.failure\n}\nfunc (p *eagerPacket) Layers() []Layer {\n\treturn p.layers\n}\nfunc (p *eagerPacket) Layer(t LayerType) Layer {\n\tfor _, l := range p.layers {\n\t\tif l.LayerType() == t {\n\t\t\treturn l\n\t\t}\n\t}\n\treturn nil\n}\nfunc (p *eagerPacket) LayerClass(lc LayerClass) Layer {\n\tfor _, l := range p.layers {\n\t\tif lc.Contains(l.LayerType()) {\n\t\t\treturn l\n\t\t}\n\t}\n\treturn nil\n}\nfunc (p *eagerPacket) String() string { return p.packetString() }\nfunc (p *eagerPacket) Dump() string   { return p.packetDump() }\n\n// lazyPacket does lazy decoding on its packet data.  On construction it does\n// no initial decoding.  For each function call, it decodes only as many layers\n// as are necessary to compute the return value for that function.\n// lazyPacket implements Packet and PacketBuilder.\ntype lazyPacket struct {\n\tpacket\n\tnext Decoder\n}\n\nfunc (p *lazyPacket) NextDecoder(next Decoder) error {\n\tif next == nil {\n\t\treturn errNilDecoder\n\t}\n\tp.next = next\n\treturn nil\n}\nfunc (p *lazyPacket) decodeNextLayer() {\n\tif p.next == nil {\n\t\treturn\n\t}\n\td := p.data\n\tif p.last != nil {\n\t\td = p.last.LayerPayload()\n\t}\n\tnext := p.next\n\tp.next = nil\n\t// We've just set p.next to nil, so if we see we have no data, this should be\n\t// the final call we get to decodeNextLayer if we return here.\n\tif len(d) == 0 {\n\t\treturn\n\t}\n\tdefer p.recoverDecodeError()\n\terr := next.Decode(d, p)\n\tif err != nil {\n\t\tp.addFinalDecodeError(err, nil)\n\t}\n}\nfunc (p *lazyPacket) LinkLayer() LinkLayer {\n\tfor p.link == nil && p.next != nil {\n\t\tp.decodeNextLayer()\n\t}\n\treturn p.link\n}\nfunc (p *lazyPacket) NetworkLayer() NetworkLayer {\n\tfor p.network == nil && p.next != nil {\n\t\tp.decodeNextLayer()\n\t}\n\treturn p.network\n}\nfunc (p *lazyPacket) TransportLayer() TransportLayer {\n\tfor p.transport == nil && p.next != nil {\n\t\tp.decodeNextLayer()\n\t}\n\treturn p.transport\n}\nfunc (p *lazyPacket) ApplicationLayer() ApplicationLayer {\n\tfor p.application == nil && p.next != nil {\n\t\tp.decodeNextLayer()\n\t}\n\treturn p.application\n}\nfunc (p *lazyPacket) ErrorLayer() ErrorLayer {\n\tfor p.failure == nil && p.next != nil {\n\t\tp.decodeNextLayer()\n\t}\n\treturn p.failure\n}\nfunc (p *lazyPacket) Layers() []Layer {\n\tfor p.next != nil {\n\t\tp.decodeNextLayer()\n\t}\n\treturn p.layers\n}\nfunc (p *lazyPacket) Layer(t LayerType) Layer {\n\tfor _, l := range p.layers {\n\t\tif l.LayerType() == t {\n\t\t\treturn l\n\t\t}\n\t}\n\tnumLayers := len(p.layers)\n\tfor p.next != nil {\n\t\tp.decodeNextLayer()\n\t\tfor _, l := range p.layers[numLayers:] {\n\t\t\tif l.LayerType() == t {\n\t\t\t\treturn l\n\t\t\t}\n\t\t}\n\t\tnumLayers = len(p.layers)\n\t}\n\treturn nil\n}\nfunc (p *lazyPacket) LayerClass(lc LayerClass) Layer {\n\tfor _, l := range p.layers {\n\t\tif lc.Contains(l.LayerType()) {\n\t\t\treturn l\n\t\t}\n\t}\n\tnumLayers := len(p.layers)\n\tfor p.next != nil {\n\t\tp.decodeNextLayer()\n\t\tfor _, l := range p.layers[numLayers:] {\n\t\t\tif lc.Contains(l.LayerType()) {\n\t\t\t\treturn l\n\t\t\t}\n\t\t}\n\t\tnumLayers = len(p.layers)\n\t}\n\treturn nil\n}\nfunc (p *lazyPacket) String() string { p.Layers(); return p.packetString() }\nfunc (p *lazyPacket) Dump() string   { p.Layers(); return p.packetDump() }\n\n// DecodeOptions tells gopacket how to decode a packet.\ntype DecodeOptions struct {\n\t// Lazy decoding decodes the minimum number of layers needed to return data\n\t// for a packet at each function call.  Be careful using this with concurrent\n\t// packet processors, as each call to packet.* could mutate the packet, and\n\t// two concurrent function calls could interact poorly.\n\tLazy bool\n\t// NoCopy decoding doesn't copy its input buffer into storage that's owned by\n\t// the packet.  If you can guarantee that the bytes underlying the slice\n\t// passed into NewPacket aren't going to be modified, this can be faster.  If\n\t// there's any chance that those bytes WILL be changed, this will invalidate\n\t// your packets.\n\tNoCopy bool\n\t// SkipDecodeRecovery skips over panic recovery during packet decoding.\n\t// Normally, when packets decode, if a panic occurs, that panic is captured\n\t// by a recover(), and a DecodeFailure layer is added to the packet detailing\n\t// the issue.  If this flag is set, panics are instead allowed to continue up\n\t// the stack.\n\tSkipDecodeRecovery bool\n\t// DecodeStreamsAsDatagrams enables routing of application-level layers in the TCP\n\t// decoder. If true, we should try to decode layers after TCP in single packets.\n\t// This is disabled by default because the reassembly package drives the decoding\n\t// of TCP payload data after reassembly.\n\tDecodeStreamsAsDatagrams bool\n}\n\n// Default decoding provides the safest (but slowest) method for decoding\n// packets.  It eagerly processes all layers (so it's concurrency-safe) and it\n// copies its input buffer upon creation of the packet (so the packet remains\n// valid if the underlying slice is modified.  Both of these take time,\n// though, so beware.  If you can guarantee that the packet will only be used\n// by one goroutine at a time, set Lazy decoding.  If you can guarantee that\n// the underlying slice won't change, set NoCopy decoding.\nvar Default = DecodeOptions{}\n\n// Lazy is a DecodeOptions with just Lazy set.\nvar Lazy = DecodeOptions{Lazy: true}\n\n// NoCopy is a DecodeOptions with just NoCopy set.\nvar NoCopy = DecodeOptions{NoCopy: true}\n\n// DecodeStreamsAsDatagrams is a DecodeOptions with just DecodeStreamsAsDatagrams set.\nvar DecodeStreamsAsDatagrams = DecodeOptions{DecodeStreamsAsDatagrams: true}\n\n// NewPacket creates a new Packet object from a set of bytes.  The\n// firstLayerDecoder tells it how to interpret the first layer from the bytes,\n// future layers will be generated from that first layer automatically.\nfunc NewPacket(data []byte, firstLayerDecoder Decoder, options DecodeOptions) Packet {\n\tif !options.NoCopy {\n\t\tdataCopy := make([]byte, len(data))\n\t\tcopy(dataCopy, data)\n\t\tdata = dataCopy\n\t}\n\tif options.Lazy {\n\t\tp := &lazyPacket{\n\t\t\tpacket: packet{data: data, decodeOptions: options},\n\t\t\tnext:   firstLayerDecoder,\n\t\t}\n\t\tp.layers = p.initialLayers[:0]\n\t\t// Crazy craziness:\n\t\t// If the following return statemet is REMOVED, and Lazy is FALSE, then\n\t\t// eager packet processing becomes 17% FASTER.  No, there is no logical\n\t\t// explanation for this.  However, it's such a hacky micro-optimization that\n\t\t// we really can't rely on it.  It appears to have to do with the size the\n\t\t// compiler guesses for this function's stack space, since one symptom is\n\t\t// that with the return statement in place, we more than double calls to\n\t\t// runtime.morestack/runtime.lessstack.  We'll hope the compiler gets better\n\t\t// over time and we get this optimization for free.  Until then, we'll have\n\t\t// to live with slower packet processing.\n\t\treturn p\n\t}\n\tp := &eagerPacket{\n\t\tpacket: packet{data: data, decodeOptions: options},\n\t}\n\tp.layers = p.initialLayers[:0]\n\tp.initialDecode(firstLayerDecoder)\n\treturn p\n}\n\n// PacketDataSource is an interface for some source of packet data.  Users may\n// create their own implementations, or use the existing implementations in\n// gopacket/pcap (libpcap, allows reading from live interfaces or from\n// pcap files) or gopacket/pfring (PF_RING, allows reading from live\n// interfaces).\ntype PacketDataSource interface {\n\t// ReadPacketData returns the next packet available from this data source.\n\t// It returns:\n\t//  data:  The bytes of an individual packet.\n\t//  ci:  Metadata about the capture\n\t//  err:  An error encountered while reading packet data.  If err != nil,\n\t//    then data/ci will be ignored.\n\tReadPacketData() (data []byte, ci CaptureInfo, err error)\n}\n\n// ConcatFinitePacketDataSources returns a PacketDataSource that wraps a set\n// of internal PacketDataSources, each of which will stop with io.EOF after\n// reading a finite number of packets.  The returned PacketDataSource will\n// return all packets from the first finite source, followed by all packets from\n// the second, etc.  Once all finite sources have returned io.EOF, the returned\n// source will as well.\nfunc ConcatFinitePacketDataSources(pds ...PacketDataSource) PacketDataSource {\n\tc := concat(pds)\n\treturn &c\n}\n\ntype concat []PacketDataSource\n\nfunc (c *concat) ReadPacketData() (data []byte, ci CaptureInfo, err error) {\n\tfor len(*c) > 0 {\n\t\tdata, ci, err = (*c)[0].ReadPacketData()\n\t\tif err == io.EOF {\n\t\t\t*c = (*c)[1:]\n\t\t\tcontinue\n\t\t}\n\t\treturn\n\t}\n\treturn nil, CaptureInfo{}, io.EOF\n}\n\n// ZeroCopyPacketDataSource is an interface to pull packet data from sources\n// that allow data to be returned without copying to a user-controlled buffer.\n// It's very similar to PacketDataSource, except that the caller must be more\n// careful in how the returned buffer is handled.\ntype ZeroCopyPacketDataSource interface {\n\t// ZeroCopyReadPacketData returns the next packet available from this data source.\n\t// It returns:\n\t//  data:  The bytes of an individual packet.  Unlike with\n\t//    PacketDataSource's ReadPacketData, the slice returned here points\n\t//    to a buffer owned by the data source.  In particular, the bytes in\n\t//    this buffer may be changed by future calls to\n\t//    ZeroCopyReadPacketData.  Do not use the returned buffer after\n\t//    subsequent ZeroCopyReadPacketData calls.\n\t//  ci:  Metadata about the capture\n\t//  err:  An error encountered while reading packet data.  If err != nil,\n\t//    then data/ci will be ignored.\n\tZeroCopyReadPacketData() (data []byte, ci CaptureInfo, err error)\n}\n\n// PacketSource reads in packets from a PacketDataSource, decodes them, and\n// returns them.\n//\n// There are currently two different methods for reading packets in through\n// a PacketSource:\n//\n// Reading With Packets Function\n//\n// This method is the most convenient and easiest to code, but lacks\n// flexibility.  Packets returns a 'chan Packet', then asynchronously writes\n// packets into that channel.  Packets uses a blocking channel, and closes\n// it if an io.EOF is returned by the underlying PacketDataSource.  All other\n// PacketDataSource errors are ignored and discarded.\n//  for packet := range packetSource.Packets() {\n//    ...\n//  }\n//\n// Reading With NextPacket Function\n//\n// This method is the most flexible, and exposes errors that may be\n// encountered by the underlying PacketDataSource.  It's also the fastest\n// in a tight loop, since it doesn't have the overhead of a channel\n// read/write.  However, it requires the user to handle errors, most\n// importantly the io.EOF error in cases where packets are being read from\n// a file.\n//  for {\n//    packet, err := packetSource.NextPacket()\n//    if err == io.EOF {\n//      break\n//    } else if err != nil {\n//      log.Println(\"Error:\", err)\n//      continue\n//    }\n//    handlePacket(packet)  // Do something with each packet.\n//  }\ntype PacketSource struct {\n\tsource  PacketDataSource\n\tdecoder Decoder\n\t// DecodeOptions is the set of options to use for decoding each piece\n\t// of packet data.  This can/should be changed by the user to reflect the\n\t// way packets should be decoded.\n\tDecodeOptions\n\tc chan Packet\n}\n\n// NewPacketSource creates a packet data source.\nfunc NewPacketSource(source PacketDataSource, decoder Decoder) *PacketSource {\n\treturn &PacketSource{\n\t\tsource:  source,\n\t\tdecoder: decoder,\n\t}\n}\n\n// NextPacket returns the next decoded packet from the PacketSource.  On error,\n// it returns a nil packet and a non-nil error.\nfunc (p *PacketSource) NextPacket() (Packet, error) {\n\tdata, ci, err := p.source.ReadPacketData()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpacket := NewPacket(data, p.decoder, p.DecodeOptions)\n\tm := packet.Metadata()\n\tm.CaptureInfo = ci\n\tm.Truncated = m.Truncated || ci.CaptureLength < ci.Length\n\treturn packet, nil\n}\n\n// packetsToChannel reads in all packets from the packet source and sends them\n// to the given channel. This routine terminates when a non-temporary error\n// is returned by NextPacket().\nfunc (p *PacketSource) packetsToChannel() {\n\tdefer close(p.c)\n\tfor {\n\t\tpacket, err := p.NextPacket()\n\t\tif err == nil {\n\t\t\tp.c <- packet\n\t\t\tcontinue\n\t\t}\n\n\t\t// Immediately retry for temporary network errors\n\t\tif nerr, ok := err.(net.Error); ok && nerr.Temporary() {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Immediately retry for EAGAIN\n\t\tif err == syscall.EAGAIN {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Immediately break for known unrecoverable errors\n\t\tif err == io.EOF || err == io.ErrUnexpectedEOF ||\n\t\t\terr == io.ErrNoProgress || err == io.ErrClosedPipe || err == io.ErrShortBuffer ||\n\t\t\terr == syscall.EBADF ||\n\t\t\tstrings.Contains(err.Error(), \"use of closed file\") {\n\t\t\tbreak\n\t\t}\n\n\t\t// Sleep briefly and try again\n\t\ttime.Sleep(time.Millisecond * time.Duration(5))\n\t}\n}\n\n// Packets returns a channel of packets, allowing easy iterating over\n// packets.  Packets will be asynchronously read in from the underlying\n// PacketDataSource and written to the returned channel.  If the underlying\n// PacketDataSource returns an io.EOF error, the channel will be closed.\n// If any other error is encountered, it is ignored.\n//\n//  for packet := range packetSource.Packets() {\n//    handlePacket(packet)  // Do something with each packet.\n//  }\n//\n// If called more than once, returns the same channel.\nfunc (p *PacketSource) Packets() chan Packet {\n\tif p.c == nil {\n\t\tp.c = make(chan Packet, 1000)\n\t\tgo p.packetsToChannel()\n\t}\n\treturn p.c\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/parser.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage gopacket\n\nimport (\n\t\"fmt\"\n)\n\n// A container for single LayerType->DecodingLayer mapping.\ntype decodingLayerElem struct {\n\ttyp LayerType\n\tdec DecodingLayer\n}\n\n// DecodingLayer is an interface for packet layers that can decode themselves.\n//\n// The important part of DecodingLayer is that they decode themselves in-place.\n// Calling DecodeFromBytes on a DecodingLayer totally resets the entire layer to\n// the new state defined by the data passed in.  A returned error leaves the\n// DecodingLayer in an unknown intermediate state, thus its fields should not be\n// trusted.\n//\n// Because the DecodingLayer is resetting its own fields, a call to\n// DecodeFromBytes should normally not require any memory allocation.\ntype DecodingLayer interface {\n\t// DecodeFromBytes resets the internal state of this layer to the state\n\t// defined by the passed-in bytes.  Slices in the DecodingLayer may\n\t// reference the passed-in data, so care should be taken to copy it\n\t// first should later modification of data be required before the\n\t// DecodingLayer is discarded.\n\tDecodeFromBytes(data []byte, df DecodeFeedback) error\n\t// CanDecode returns the set of LayerTypes this DecodingLayer can\n\t// decode.  For Layers that are also DecodingLayers, this will most\n\t// often be that Layer's LayerType().\n\tCanDecode() LayerClass\n\t// NextLayerType returns the LayerType which should be used to decode\n\t// the LayerPayload.\n\tNextLayerType() LayerType\n\t// LayerPayload is the set of bytes remaining to decode after a call to\n\t// DecodeFromBytes.\n\tLayerPayload() []byte\n}\n\n// DecodingLayerFunc decodes given packet and stores decoded LayerType\n// values into specified slice. Returns either first encountered\n// unsupported LayerType value or decoding error. In case of success,\n// returns (LayerTypeZero, nil).\ntype DecodingLayerFunc func([]byte, *[]LayerType) (LayerType, error)\n\n// DecodingLayerContainer stores all DecodingLayer-s and serves as a\n// searching tool for DecodingLayerParser.\ntype DecodingLayerContainer interface {\n\t// Put adds new DecodingLayer to container. The new instance of\n\t// the same DecodingLayerContainer is returned so it may be\n\t// implemented as a value receiver.\n\tPut(DecodingLayer) DecodingLayerContainer\n\t// Decoder returns DecodingLayer to decode given LayerType and\n\t// true if it was found. If no decoder found, return false.\n\tDecoder(LayerType) (DecodingLayer, bool)\n\t// LayersDecoder returns DecodingLayerFunc which decodes given\n\t// packet, starting with specified LayerType and DecodeFeedback.\n\tLayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc\n}\n\n// DecodingLayerSparse is a sparse array-based implementation of\n// DecodingLayerContainer. Each DecodingLayer is addressed in an\n// allocated slice by LayerType value itself. Though this is the\n// fastest container it may be memory-consuming if used with big\n// LayerType values.\ntype DecodingLayerSparse []DecodingLayer\n\n// Put implements DecodingLayerContainer interface.\nfunc (dl DecodingLayerSparse) Put(d DecodingLayer) DecodingLayerContainer {\n\tmaxLayerType := LayerType(len(dl) - 1)\n\tfor _, typ := range d.CanDecode().LayerTypes() {\n\t\tif typ > maxLayerType {\n\t\t\tmaxLayerType = typ\n\t\t}\n\t}\n\n\tif extra := maxLayerType - LayerType(len(dl)) + 1; extra > 0 {\n\t\tdl = append(dl, make([]DecodingLayer, extra)...)\n\t}\n\n\tfor _, typ := range d.CanDecode().LayerTypes() {\n\t\tdl[typ] = d\n\t}\n\treturn dl\n}\n\n// LayersDecoder implements DecodingLayerContainer interface.\nfunc (dl DecodingLayerSparse) LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc {\n\treturn LayersDecoder(dl, first, df)\n}\n\n// Decoder implements DecodingLayerContainer interface.\nfunc (dl DecodingLayerSparse) Decoder(typ LayerType) (DecodingLayer, bool) {\n\tif int64(typ) < int64(len(dl)) {\n\t\tdecoder := dl[typ]\n\t\treturn decoder, decoder != nil\n\t}\n\treturn nil, false\n}\n\n// DecodingLayerArray is an array-based implementation of\n// DecodingLayerContainer. Each DecodingLayer is searched linearly in\n// an allocated slice in one-by-one fashion.\ntype DecodingLayerArray []decodingLayerElem\n\n// Put implements DecodingLayerContainer interface.\nfunc (dl DecodingLayerArray) Put(d DecodingLayer) DecodingLayerContainer {\nTYPES:\n\tfor _, typ := range d.CanDecode().LayerTypes() {\n\t\tfor i := range dl {\n\t\t\tif dl[i].typ == typ {\n\t\t\t\tdl[i].dec = d\n\t\t\t\tcontinue TYPES\n\t\t\t}\n\t\t}\n\t\tdl = append(dl, decodingLayerElem{typ, d})\n\t}\n\treturn dl\n}\n\n// Decoder implements DecodingLayerContainer interface.\nfunc (dl DecodingLayerArray) Decoder(typ LayerType) (DecodingLayer, bool) {\n\tfor i := range dl {\n\t\tif dl[i].typ == typ {\n\t\t\treturn dl[i].dec, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// LayersDecoder implements DecodingLayerContainer interface.\nfunc (dl DecodingLayerArray) LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc {\n\treturn LayersDecoder(dl, first, df)\n}\n\n// DecodingLayerMap is an map-based implementation of\n// DecodingLayerContainer. Each DecodingLayer is searched in a map\n// hashed by LayerType value.\ntype DecodingLayerMap map[LayerType]DecodingLayer\n\n// Put implements DecodingLayerContainer interface.\nfunc (dl DecodingLayerMap) Put(d DecodingLayer) DecodingLayerContainer {\n\tfor _, typ := range d.CanDecode().LayerTypes() {\n\t\tif dl == nil {\n\t\t\tdl = make(map[LayerType]DecodingLayer)\n\t\t}\n\t\tdl[typ] = d\n\t}\n\treturn dl\n}\n\n// Decoder implements DecodingLayerContainer interface.\nfunc (dl DecodingLayerMap) Decoder(typ LayerType) (DecodingLayer, bool) {\n\td, ok := dl[typ]\n\treturn d, ok\n}\n\n// LayersDecoder implements DecodingLayerContainer interface.\nfunc (dl DecodingLayerMap) LayersDecoder(first LayerType, df DecodeFeedback) DecodingLayerFunc {\n\treturn LayersDecoder(dl, first, df)\n}\n\n// Static code check.\nvar (\n\t_ = []DecodingLayerContainer{\n\t\tDecodingLayerSparse(nil),\n\t\tDecodingLayerMap(nil),\n\t\tDecodingLayerArray(nil),\n\t}\n)\n\n// DecodingLayerParser parses a given set of layer types.  See DecodeLayers for\n// more information on how DecodingLayerParser should be used.\ntype DecodingLayerParser struct {\n\t// DecodingLayerParserOptions is the set of options available to the\n\t// user to define the parser's behavior.\n\tDecodingLayerParserOptions\n\tdlc   DecodingLayerContainer\n\tfirst LayerType\n\tdf    DecodeFeedback\n\n\tdecodeFunc DecodingLayerFunc\n\n\t// Truncated is set when a decode layer detects that the packet has been\n\t// truncated.\n\tTruncated bool\n}\n\n// AddDecodingLayer adds a decoding layer to the parser.  This adds support for\n// the decoding layer's CanDecode layers to the parser... should they be\n// encountered, they'll be parsed.\nfunc (l *DecodingLayerParser) AddDecodingLayer(d DecodingLayer) {\n\tl.SetDecodingLayerContainer(l.dlc.Put(d))\n}\n\n// SetTruncated is used by DecodingLayers to set the Truncated boolean in the\n// DecodingLayerParser.  Users should simply read Truncated after calling\n// DecodeLayers.\nfunc (l *DecodingLayerParser) SetTruncated() {\n\tl.Truncated = true\n}\n\n// NewDecodingLayerParser creates a new DecodingLayerParser and adds in all\n// of the given DecodingLayers with AddDecodingLayer.\n//\n// Each call to DecodeLayers will attempt to decode the given bytes first by\n// treating them as a 'first'-type layer, then by using NextLayerType on\n// subsequently decoded layers to find the next relevant decoder.  Should a\n// deoder not be available for the layer type returned by NextLayerType,\n// decoding will stop.\n//\n// NewDecodingLayerParser uses DecodingLayerMap container by\n// default.\nfunc NewDecodingLayerParser(first LayerType, decoders ...DecodingLayer) *DecodingLayerParser {\n\tdlp := &DecodingLayerParser{first: first}\n\tdlp.df = dlp // Cast this once to the interface\n\t// default container\n\tdlc := DecodingLayerContainer(DecodingLayerMap(make(map[LayerType]DecodingLayer)))\n\tfor _, d := range decoders {\n\t\tdlc = dlc.Put(d)\n\t}\n\n\tdlp.SetDecodingLayerContainer(dlc)\n\treturn dlp\n}\n\n// SetDecodingLayerContainer specifies container with decoders. This\n// call replaces all decoders already registered in given instance of\n// DecodingLayerParser.\nfunc (l *DecodingLayerParser) SetDecodingLayerContainer(dlc DecodingLayerContainer) {\n\tl.dlc = dlc\n\tl.decodeFunc = l.dlc.LayersDecoder(l.first, l.df)\n}\n\n// DecodeLayers decodes as many layers as possible from the given data.  It\n// initially treats the data as layer type 'typ', then uses NextLayerType on\n// each subsequent decoded layer until it gets to a layer type it doesn't know\n// how to parse.\n//\n// For each layer successfully decoded, DecodeLayers appends the layer type to\n// the decoded slice.  DecodeLayers truncates the 'decoded' slice initially, so\n// there's no need to empty it yourself.\n//\n// This decoding method is about an order of magnitude faster than packet\n// decoding, because it only decodes known layers that have already been\n// allocated.  This means it doesn't need to allocate each layer it returns...\n// instead it overwrites the layers that already exist.\n//\n// Example usage:\n//    func main() {\n//      var eth layers.Ethernet\n//      var ip4 layers.IPv4\n//      var ip6 layers.IPv6\n//      var tcp layers.TCP\n//      var udp layers.UDP\n//      var payload gopacket.Payload\n//      parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, &eth, &ip4, &ip6, &tcp, &udp, &payload)\n//      var source gopacket.PacketDataSource = getMyDataSource()\n//      decodedLayers := make([]gopacket.LayerType, 0, 10)\n//      for {\n//        data, _, err := source.ReadPacketData()\n//        if err != nil {\n//          fmt.Println(\"Error reading packet data: \", err)\n//          continue\n//        }\n//        fmt.Println(\"Decoding packet\")\n//        err = parser.DecodeLayers(data, &decodedLayers)\n//        for _, typ := range decodedLayers {\n//          fmt.Println(\"  Successfully decoded layer type\", typ)\n//          switch typ {\n//            case layers.LayerTypeEthernet:\n//              fmt.Println(\"    Eth \", eth.SrcMAC, eth.DstMAC)\n//            case layers.LayerTypeIPv4:\n//              fmt.Println(\"    IP4 \", ip4.SrcIP, ip4.DstIP)\n//            case layers.LayerTypeIPv6:\n//              fmt.Println(\"    IP6 \", ip6.SrcIP, ip6.DstIP)\n//            case layers.LayerTypeTCP:\n//              fmt.Println(\"    TCP \", tcp.SrcPort, tcp.DstPort)\n//            case layers.LayerTypeUDP:\n//              fmt.Println(\"    UDP \", udp.SrcPort, udp.DstPort)\n//          }\n//        }\n//        if decodedLayers.Truncated {\n//          fmt.Println(\"  Packet has been truncated\")\n//        }\n//        if err != nil {\n//          fmt.Println(\"  Error encountered:\", err)\n//        }\n//      }\n//    }\n//\n// If DecodeLayers is unable to decode the next layer type, it will return the\n// error UnsupportedLayerType.\nfunc (l *DecodingLayerParser) DecodeLayers(data []byte, decoded *[]LayerType) (err error) {\n\tl.Truncated = false\n\tif !l.IgnorePanic {\n\t\tdefer panicToError(&err)\n\t}\n\ttyp, err := l.decodeFunc(data, decoded)\n\tif typ != LayerTypeZero {\n\t\t// no decoder\n\t\tif l.IgnoreUnsupported {\n\t\t\treturn nil\n\t\t}\n\t\treturn UnsupportedLayerType(typ)\n\t}\n\treturn err\n}\n\n// UnsupportedLayerType is returned by DecodingLayerParser if DecodeLayers\n// encounters a layer type that the DecodingLayerParser has no decoder for.\ntype UnsupportedLayerType LayerType\n\n// Error implements the error interface, returning a string to say that the\n// given layer type is unsupported.\nfunc (e UnsupportedLayerType) Error() string {\n\treturn fmt.Sprintf(\"No decoder for layer type %v\", LayerType(e))\n}\n\nfunc panicToError(e *error) {\n\tif r := recover(); r != nil {\n\t\t*e = fmt.Errorf(\"panic: %v\", r)\n\t}\n}\n\n// DecodingLayerParserOptions provides options to affect the behavior of a given\n// DecodingLayerParser.\ntype DecodingLayerParserOptions struct {\n\t// IgnorePanic determines whether a DecodingLayerParser should stop\n\t// panics on its own (by returning them as an error from DecodeLayers)\n\t// or should allow them to raise up the stack.  Handling errors does add\n\t// latency to the process of decoding layers, but is much safer for\n\t// callers.  IgnorePanic defaults to false, thus if the caller does\n\t// nothing decode panics will be returned as errors.\n\tIgnorePanic bool\n\t// IgnoreUnsupported will stop parsing and return a nil error when it\n\t// encounters a layer it doesn't have a parser for, instead of returning an\n\t// UnsupportedLayerType error.  If this is true, it's up to the caller to make\n\t// sure that all expected layers have been parsed (by checking the decoded\n\t// slice).\n\tIgnoreUnsupported bool\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/time.go",
    "content": "// Copyright 2018 The GoPacket Authors. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage gopacket\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"time\"\n)\n\n// TimestampResolution represents the resolution of timestamps in Base^Exponent.\ntype TimestampResolution struct {\n\tBase, Exponent int\n}\n\nfunc (t TimestampResolution) String() string {\n\treturn fmt.Sprintf(\"%d^%d\", t.Base, t.Exponent)\n}\n\n// ToDuration returns the smallest representable time difference as a time.Duration\nfunc (t TimestampResolution) ToDuration() time.Duration {\n\tif t.Base == 0 {\n\t\treturn 0\n\t}\n\tif t.Exponent == 0 {\n\t\treturn time.Second\n\t}\n\tswitch t.Base {\n\tcase 10:\n\t\treturn time.Duration(math.Pow10(t.Exponent + 9))\n\tcase 2:\n\t\tif t.Exponent < 0 {\n\t\t\treturn time.Second >> uint(-t.Exponent)\n\t\t}\n\t\treturn time.Second << uint(t.Exponent)\n\tdefault:\n\t\t// this might loose precision\n\t\treturn time.Duration(float64(time.Second) * math.Pow(float64(t.Base), float64(t.Exponent)))\n\t}\n}\n\n// TimestampResolutionInvalid represents an invalid timestamp resolution\nvar TimestampResolutionInvalid = TimestampResolution{}\n\n// TimestampResolutionMillisecond is a resolution of 10^-3s\nvar TimestampResolutionMillisecond = TimestampResolution{10, -3}\n\n// TimestampResolutionMicrosecond is a resolution of 10^-6s\nvar TimestampResolutionMicrosecond = TimestampResolution{10, -6}\n\n// TimestampResolutionNanosecond is a resolution of 10^-9s\nvar TimestampResolutionNanosecond = TimestampResolution{10, -9}\n\n// TimestampResolutionNTP is the resolution of NTP timestamps which is 2^-32 ≈ 233 picoseconds\nvar TimestampResolutionNTP = TimestampResolution{2, -32}\n\n// TimestampResolutionCaptureInfo is the resolution used in CaptureInfo, which his currently nanosecond\nvar TimestampResolutionCaptureInfo = TimestampResolutionNanosecond\n\n// PacketSourceResolution is an interface for packet data sources that\n// support reporting the timestamp resolution of the aqcuired timestamps.\n// Returned timestamps will always have NanosecondTimestampResolution due\n// to the use of time.Time, but scaling might have occured if acquired\n// timestamps have a different resolution.\ntype PacketSourceResolution interface {\n\t// Resolution returns the timestamp resolution of acquired timestamps before scaling to NanosecondTimestampResolution.\n\tResolution() TimestampResolution\n}\n"
  },
  {
    "path": "vendor/github.com/google/gopacket/writer.go",
    "content": "// Copyright 2012 Google, Inc. All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license\n// that can be found in the LICENSE file in the root of the source\n// tree.\n\npackage gopacket\n\nimport (\n\t\"fmt\"\n)\n\n// SerializableLayer allows its implementations to be written out as a set of bytes,\n// so those bytes may be sent on the wire or otherwise used by the caller.\n// SerializableLayer is implemented by certain Layer types, and can be encoded to\n// bytes using the LayerWriter object.\ntype SerializableLayer interface {\n\t// SerializeTo writes this layer to a slice, growing that slice if necessary\n\t// to make it fit the layer's data.\n\t//  Args:\n\t//   b:  SerializeBuffer to write this layer on to.  When called, b.Bytes()\n\t//     is the payload this layer should wrap, if any.  Note that this\n\t//     layer can either prepend itself (common), append itself\n\t//     (uncommon), or both (sometimes padding or footers are required at\n\t//     the end of packet data). It's also possible (though probably very\n\t//     rarely needed) to overwrite any bytes in the current payload.\n\t//     After this call, b.Bytes() should return the byte encoding of\n\t//     this layer wrapping the original b.Bytes() payload.\n\t//   opts:  options to use while writing out data.\n\t//  Returns:\n\t//   error if a problem was encountered during encoding.  If an error is\n\t//   returned, the bytes in data should be considered invalidated, and\n\t//   not used.\n\t//\n\t// SerializeTo calls SHOULD entirely ignore LayerContents and\n\t// LayerPayload.  It just serializes based on struct fields, neither\n\t// modifying nor using contents/payload.\n\tSerializeTo(b SerializeBuffer, opts SerializeOptions) error\n\t// LayerType returns the type of the layer that is being serialized to the buffer\n\tLayerType() LayerType\n}\n\n// SerializeOptions provides options for behaviors that SerializableLayers may want to\n// implement.\ntype SerializeOptions struct {\n\t// FixLengths determines whether, during serialization, layers should fix\n\t// the values for any length field that depends on the payload.\n\tFixLengths bool\n\t// ComputeChecksums determines whether, during serialization, layers\n\t// should recompute checksums based on their payloads.\n\tComputeChecksums bool\n}\n\n// SerializeBuffer is a helper used by gopacket for writing out packet layers.\n// SerializeBuffer starts off as an empty []byte.  Subsequent calls to PrependBytes\n// return byte slices before the current Bytes(), AppendBytes returns byte\n// slices after.\n//\n// Byte slices returned by PrependBytes/AppendBytes are NOT zero'd out, so if\n// you want to make sure they're all zeros, set them as such.\n//\n// SerializeBuffer is specifically designed to handle packet writing, where unlike\n// with normal writes it's easier to start writing at the inner-most layer and\n// work out, meaning that we often need to prepend bytes.  This runs counter to\n// typical writes to byte slices using append(), where we only write at the end\n// of the buffer.\n//\n// It can be reused via Clear.  Note, however, that a Clear call will invalidate the\n// byte slices returned by any previous Bytes() call (the same buffer is\n// reused).\n//\n//  1) Reusing a write buffer is generally much faster than creating a new one,\n//     and with the default implementation it avoids additional memory allocations.\n//  2) If a byte slice from a previous Bytes() call will continue to be used,\n//     it's better to create a new SerializeBuffer.\n//\n// The Clear method is specifically designed to minimize memory allocations for\n// similar later workloads on the SerializeBuffer.  IE: if you make a set of\n// Prepend/Append calls, then clear, then make the same calls with the same\n// sizes, the second round (and all future similar rounds) shouldn't allocate\n// any new memory.\ntype SerializeBuffer interface {\n\t// Bytes returns the contiguous set of bytes collected so far by Prepend/Append\n\t// calls.  The slice returned by Bytes will be modified by future Clear calls,\n\t// so if you're planning on clearing this SerializeBuffer, you may want to copy\n\t// Bytes somewhere safe first.\n\tBytes() []byte\n\t// PrependBytes returns a set of bytes which prepends the current bytes in this\n\t// buffer.  These bytes start in an indeterminate state, so they should be\n\t// overwritten by the caller.  The caller must only call PrependBytes if they\n\t// know they're going to immediately overwrite all bytes returned.\n\tPrependBytes(num int) ([]byte, error)\n\t// AppendBytes returns a set of bytes which appends the current bytes in this\n\t// buffer.  These bytes start in an indeterminate state, so they should be\n\t// overwritten by the caller.  The caller must only call AppendBytes if they\n\t// know they're going to immediately overwrite all bytes returned.\n\tAppendBytes(num int) ([]byte, error)\n\t// Clear resets the SerializeBuffer to a new, empty buffer.  After a call to clear,\n\t// the byte slice returned by any previous call to Bytes() for this buffer\n\t// should be considered invalidated.\n\tClear() error\n\t// Layers returns all the Layers that have been successfully serialized into this buffer\n\t// already.\n\tLayers() []LayerType\n\t// PushLayer adds the current Layer to the list of Layers that have been serialized\n\t// into this buffer.\n\tPushLayer(LayerType)\n}\n\ntype serializeBuffer struct {\n\tdata                []byte\n\tstart               int\n\tprepended, appended int\n\tlayers              []LayerType\n}\n\n// NewSerializeBuffer creates a new instance of the default implementation of\n// the SerializeBuffer interface.\nfunc NewSerializeBuffer() SerializeBuffer {\n\treturn &serializeBuffer{}\n}\n\n// NewSerializeBufferExpectedSize creates a new buffer for serialization, optimized for an\n// expected number of bytes prepended/appended.  This tends to decrease the\n// number of memory allocations made by the buffer during writes.\nfunc NewSerializeBufferExpectedSize(expectedPrependLength, expectedAppendLength int) SerializeBuffer {\n\treturn &serializeBuffer{\n\t\tdata:      make([]byte, expectedPrependLength, expectedPrependLength+expectedAppendLength),\n\t\tstart:     expectedPrependLength,\n\t\tprepended: expectedPrependLength,\n\t\tappended:  expectedAppendLength,\n\t}\n}\n\nfunc (w *serializeBuffer) Bytes() []byte {\n\treturn w.data[w.start:]\n}\n\nfunc (w *serializeBuffer) PrependBytes(num int) ([]byte, error) {\n\tif num < 0 {\n\t\tpanic(\"num < 0\")\n\t}\n\tif w.start < num {\n\t\ttoPrepend := w.prepended\n\t\tif toPrepend < num {\n\t\t\ttoPrepend = num\n\t\t}\n\t\tw.prepended += toPrepend\n\t\tlength := cap(w.data) + toPrepend\n\t\tnewData := make([]byte, length)\n\t\tnewStart := w.start + toPrepend\n\t\tcopy(newData[newStart:], w.data[w.start:])\n\t\tw.start = newStart\n\t\tw.data = newData[:toPrepend+len(w.data)]\n\t}\n\tw.start -= num\n\treturn w.data[w.start : w.start+num], nil\n}\n\nfunc (w *serializeBuffer) AppendBytes(num int) ([]byte, error) {\n\tif num < 0 {\n\t\tpanic(\"num < 0\")\n\t}\n\tinitialLength := len(w.data)\n\tif cap(w.data)-initialLength < num {\n\t\ttoAppend := w.appended\n\t\tif toAppend < num {\n\t\t\ttoAppend = num\n\t\t}\n\t\tw.appended += toAppend\n\t\tnewData := make([]byte, cap(w.data)+toAppend)\n\t\tcopy(newData[w.start:], w.data[w.start:])\n\t\tw.data = newData[:initialLength]\n\t}\n\t// Grow the buffer.  We know it'll be under capacity given above.\n\tw.data = w.data[:initialLength+num]\n\treturn w.data[initialLength:], nil\n}\n\nfunc (w *serializeBuffer) Clear() error {\n\tw.start = w.prepended\n\tw.data = w.data[:w.start]\n\tw.layers = w.layers[:0]\n\treturn nil\n}\n\nfunc (w *serializeBuffer) Layers() []LayerType {\n\treturn w.layers\n}\n\nfunc (w *serializeBuffer) PushLayer(l LayerType) {\n\tw.layers = append(w.layers, l)\n}\n\n// SerializeLayers clears the given write buffer, then writes all layers into it so\n// they correctly wrap each other.  Note that by clearing the buffer, it\n// invalidates all slices previously returned by w.Bytes()\n//\n// Example:\n//   buf := gopacket.NewSerializeBuffer()\n//   opts := gopacket.SerializeOptions{}\n//   gopacket.SerializeLayers(buf, opts, a, b, c)\n//   firstPayload := buf.Bytes()  // contains byte representation of a(b(c))\n//   gopacket.SerializeLayers(buf, opts, d, e, f)\n//   secondPayload := buf.Bytes()  // contains byte representation of d(e(f)). firstPayload is now invalidated, since the SerializeLayers call Clears buf.\nfunc SerializeLayers(w SerializeBuffer, opts SerializeOptions, layers ...SerializableLayer) error {\n\tw.Clear()\n\tfor i := len(layers) - 1; i >= 0; i-- {\n\t\tlayer := layers[i]\n\t\terr := layer.SerializeTo(w, opts)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tw.PushLayer(layer.LayerType())\n\t}\n\treturn nil\n}\n\n// SerializePacket is a convenience function that calls SerializeLayers\n// on packet's Layers().\n// It returns an error if one of the packet layers is not a SerializableLayer.\nfunc SerializePacket(buf SerializeBuffer, opts SerializeOptions, packet Packet) error {\n\tsls := []SerializableLayer{}\n\tfor _, layer := range packet.Layers() {\n\t\tsl, ok := layer.(SerializableLayer)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"layer %s is not serializable\", layer.LayerType().String())\n\t\t}\n\t\tsls = append(sls, sl)\n\t}\n\treturn SerializeLayers(buf, opts, sls...)\n}\n"
  },
  {
    "path": "vendor/github.com/google/pprof/AUTHORS",
    "content": "# This is the official list of pprof authors for copyright purposes.\n# This file is distinct from the CONTRIBUTORS files.\n# See the latter for an explanation.\n# Names should be added to this file as:\n# Name or Organization <email address>\n# The email address is not required for organizations.\nGoogle Inc."
  },
  {
    "path": "vendor/github.com/google/pprof/CONTRIBUTORS",
    "content": "# People who have agreed to one of the CLAs and can contribute patches.\n# The AUTHORS file lists the copyright holders; this file\n# lists people.  For example, Google employees are listed here\n# but not in AUTHORS, because Google holds the copyright.\n#\n# https://developers.google.com/open-source/cla/individual\n# https://developers.google.com/open-source/cla/corporate\n#\n# Names should be added to this file as:\n#     Name <email address>\nRaul Silvera <rsilvera@google.com>\nTipp Moseley <tipp@google.com>\nHyoun Kyu Cho <netforce@google.com>\nMartin Spier <spiermar@gmail.com>\nTaco de Wolff <tacodewolff@gmail.com>\nAndrew Hunter <andrewhhunter@gmail.com>\n"
  },
  {
    "path": "vendor/github.com/google/pprof/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/github.com/google/pprof/profile/encode.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage profile\n\nimport (\n\t\"errors\"\n\t\"sort\"\n\t\"strings\"\n)\n\nfunc (p *Profile) decoder() []decoder {\n\treturn profileDecoder\n}\n\n// preEncode populates the unexported fields to be used by encode\n// (with suffix X) from the corresponding exported fields. The\n// exported fields are cleared up to facilitate testing.\nfunc (p *Profile) preEncode() {\n\tstrings := make(map[string]int)\n\taddString(strings, \"\")\n\n\tfor _, st := range p.SampleType {\n\t\tst.typeX = addString(strings, st.Type)\n\t\tst.unitX = addString(strings, st.Unit)\n\t}\n\n\tfor _, s := range p.Sample {\n\t\ts.labelX = nil\n\t\tvar keys []string\n\t\tfor k := range s.Label {\n\t\t\tkeys = append(keys, k)\n\t\t}\n\t\tsort.Strings(keys)\n\t\tfor _, k := range keys {\n\t\t\tvs := s.Label[k]\n\t\t\tfor _, v := range vs {\n\t\t\t\ts.labelX = append(s.labelX,\n\t\t\t\t\tlabel{\n\t\t\t\t\t\tkeyX: addString(strings, k),\n\t\t\t\t\t\tstrX: addString(strings, v),\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\tvar numKeys []string\n\t\tfor k := range s.NumLabel {\n\t\t\tnumKeys = append(numKeys, k)\n\t\t}\n\t\tsort.Strings(numKeys)\n\t\tfor _, k := range numKeys {\n\t\t\tkeyX := addString(strings, k)\n\t\t\tvs := s.NumLabel[k]\n\t\t\tunits := s.NumUnit[k]\n\t\t\tfor i, v := range vs {\n\t\t\t\tvar unitX int64\n\t\t\t\tif len(units) != 0 {\n\t\t\t\t\tunitX = addString(strings, units[i])\n\t\t\t\t}\n\t\t\t\ts.labelX = append(s.labelX,\n\t\t\t\t\tlabel{\n\t\t\t\t\t\tkeyX:  keyX,\n\t\t\t\t\t\tnumX:  v,\n\t\t\t\t\t\tunitX: unitX,\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\ts.locationIDX = make([]uint64, len(s.Location))\n\t\tfor i, loc := range s.Location {\n\t\t\ts.locationIDX[i] = loc.ID\n\t\t}\n\t}\n\n\tfor _, m := range p.Mapping {\n\t\tm.fileX = addString(strings, m.File)\n\t\tm.buildIDX = addString(strings, m.BuildID)\n\t}\n\n\tfor _, l := range p.Location {\n\t\tfor i, ln := range l.Line {\n\t\t\tif ln.Function != nil {\n\t\t\t\tl.Line[i].functionIDX = ln.Function.ID\n\t\t\t} else {\n\t\t\t\tl.Line[i].functionIDX = 0\n\t\t\t}\n\t\t}\n\t\tif l.Mapping != nil {\n\t\t\tl.mappingIDX = l.Mapping.ID\n\t\t} else {\n\t\t\tl.mappingIDX = 0\n\t\t}\n\t}\n\tfor _, f := range p.Function {\n\t\tf.nameX = addString(strings, f.Name)\n\t\tf.systemNameX = addString(strings, f.SystemName)\n\t\tf.filenameX = addString(strings, f.Filename)\n\t}\n\n\tp.dropFramesX = addString(strings, p.DropFrames)\n\tp.keepFramesX = addString(strings, p.KeepFrames)\n\n\tif pt := p.PeriodType; pt != nil {\n\t\tpt.typeX = addString(strings, pt.Type)\n\t\tpt.unitX = addString(strings, pt.Unit)\n\t}\n\n\tp.commentX = nil\n\tfor _, c := range p.Comments {\n\t\tp.commentX = append(p.commentX, addString(strings, c))\n\t}\n\n\tp.defaultSampleTypeX = addString(strings, p.DefaultSampleType)\n\tp.docURLX = addString(strings, p.DocURL)\n\n\tp.stringTable = make([]string, len(strings))\n\tfor s, i := range strings {\n\t\tp.stringTable[i] = s\n\t}\n}\n\nfunc (p *Profile) encode(b *buffer) {\n\tfor _, x := range p.SampleType {\n\t\tencodeMessage(b, 1, x)\n\t}\n\tfor _, x := range p.Sample {\n\t\tencodeMessage(b, 2, x)\n\t}\n\tfor _, x := range p.Mapping {\n\t\tencodeMessage(b, 3, x)\n\t}\n\tfor _, x := range p.Location {\n\t\tencodeMessage(b, 4, x)\n\t}\n\tfor _, x := range p.Function {\n\t\tencodeMessage(b, 5, x)\n\t}\n\tencodeStrings(b, 6, p.stringTable)\n\tencodeInt64Opt(b, 7, p.dropFramesX)\n\tencodeInt64Opt(b, 8, p.keepFramesX)\n\tencodeInt64Opt(b, 9, p.TimeNanos)\n\tencodeInt64Opt(b, 10, p.DurationNanos)\n\tif pt := p.PeriodType; pt != nil && (pt.typeX != 0 || pt.unitX != 0) {\n\t\tencodeMessage(b, 11, p.PeriodType)\n\t}\n\tencodeInt64Opt(b, 12, p.Period)\n\tencodeInt64s(b, 13, p.commentX)\n\tencodeInt64(b, 14, p.defaultSampleTypeX)\n\tencodeInt64Opt(b, 15, p.docURLX)\n}\n\nvar profileDecoder = []decoder{\n\tnil, // 0\n\t// repeated ValueType sample_type = 1\n\tfunc(b *buffer, m message) error {\n\t\tx := new(ValueType)\n\t\tpp := m.(*Profile)\n\t\tpp.SampleType = append(pp.SampleType, x)\n\t\treturn decodeMessage(b, x)\n\t},\n\t// repeated Sample sample = 2\n\tfunc(b *buffer, m message) error {\n\t\tx := new(Sample)\n\t\tpp := m.(*Profile)\n\t\tpp.Sample = append(pp.Sample, x)\n\t\treturn decodeMessage(b, x)\n\t},\n\t// repeated Mapping mapping = 3\n\tfunc(b *buffer, m message) error {\n\t\tx := new(Mapping)\n\t\tpp := m.(*Profile)\n\t\tpp.Mapping = append(pp.Mapping, x)\n\t\treturn decodeMessage(b, x)\n\t},\n\t// repeated Location location = 4\n\tfunc(b *buffer, m message) error {\n\t\tx := new(Location)\n\t\tx.Line = b.tmpLines[:0] // Use shared space temporarily\n\t\tpp := m.(*Profile)\n\t\tpp.Location = append(pp.Location, x)\n\t\terr := decodeMessage(b, x)\n\t\tb.tmpLines = x.Line[:0]\n\t\t// Copy to shrink size and detach from shared space.\n\t\tx.Line = append([]Line(nil), x.Line...)\n\t\treturn err\n\t},\n\t// repeated Function function = 5\n\tfunc(b *buffer, m message) error {\n\t\tx := new(Function)\n\t\tpp := m.(*Profile)\n\t\tpp.Function = append(pp.Function, x)\n\t\treturn decodeMessage(b, x)\n\t},\n\t// repeated string string_table = 6\n\tfunc(b *buffer, m message) error {\n\t\terr := decodeStrings(b, &m.(*Profile).stringTable)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif m.(*Profile).stringTable[0] != \"\" {\n\t\t\treturn errors.New(\"string_table[0] must be ''\")\n\t\t}\n\t\treturn nil\n\t},\n\t// int64 drop_frames = 7\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).dropFramesX) },\n\t// int64 keep_frames = 8\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).keepFramesX) },\n\t// int64 time_nanos = 9\n\tfunc(b *buffer, m message) error {\n\t\tif m.(*Profile).TimeNanos != 0 {\n\t\t\treturn errConcatProfile\n\t\t}\n\t\treturn decodeInt64(b, &m.(*Profile).TimeNanos)\n\t},\n\t// int64 duration_nanos = 10\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).DurationNanos) },\n\t// ValueType period_type = 11\n\tfunc(b *buffer, m message) error {\n\t\tx := new(ValueType)\n\t\tpp := m.(*Profile)\n\t\tpp.PeriodType = x\n\t\treturn decodeMessage(b, x)\n\t},\n\t// int64 period = 12\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).Period) },\n\t// repeated int64 comment = 13\n\tfunc(b *buffer, m message) error { return decodeInt64s(b, &m.(*Profile).commentX) },\n\t// int64 defaultSampleType = 14\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).defaultSampleTypeX) },\n\t// string doc_link = 15;\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).docURLX) },\n}\n\n// postDecode takes the unexported fields populated by decode (with\n// suffix X) and populates the corresponding exported fields.\n// The unexported fields are cleared up to facilitate testing.\nfunc (p *Profile) postDecode() error {\n\tvar err error\n\tmappings := make(map[uint64]*Mapping, len(p.Mapping))\n\tmappingIds := make([]*Mapping, len(p.Mapping)+1)\n\tfor _, m := range p.Mapping {\n\t\tm.File, err = getString(p.stringTable, &m.fileX, err)\n\t\tm.BuildID, err = getString(p.stringTable, &m.buildIDX, err)\n\t\tif m.ID < uint64(len(mappingIds)) {\n\t\t\tmappingIds[m.ID] = m\n\t\t} else {\n\t\t\tmappings[m.ID] = m\n\t\t}\n\n\t\t// If this a main linux kernel mapping with a relocation symbol suffix\n\t\t// (\"[kernel.kallsyms]_text\"), extract said suffix.\n\t\t// It is fairly hacky to handle at this level, but the alternatives appear even worse.\n\t\tconst prefix = \"[kernel.kallsyms]\"\n\t\tif strings.HasPrefix(m.File, prefix) {\n\t\t\tm.KernelRelocationSymbol = m.File[len(prefix):]\n\t\t}\n\t}\n\n\tfunctions := make(map[uint64]*Function, len(p.Function))\n\tfunctionIds := make([]*Function, len(p.Function)+1)\n\tfor _, f := range p.Function {\n\t\tf.Name, err = getString(p.stringTable, &f.nameX, err)\n\t\tf.SystemName, err = getString(p.stringTable, &f.systemNameX, err)\n\t\tf.Filename, err = getString(p.stringTable, &f.filenameX, err)\n\t\tif f.ID < uint64(len(functionIds)) {\n\t\t\tfunctionIds[f.ID] = f\n\t\t} else {\n\t\t\tfunctions[f.ID] = f\n\t\t}\n\t}\n\n\tlocations := make(map[uint64]*Location, len(p.Location))\n\tlocationIds := make([]*Location, len(p.Location)+1)\n\tfor _, l := range p.Location {\n\t\tif id := l.mappingIDX; id < uint64(len(mappingIds)) {\n\t\t\tl.Mapping = mappingIds[id]\n\t\t} else {\n\t\t\tl.Mapping = mappings[id]\n\t\t}\n\t\tl.mappingIDX = 0\n\t\tfor i, ln := range l.Line {\n\t\t\tif id := ln.functionIDX; id != 0 {\n\t\t\t\tl.Line[i].functionIDX = 0\n\t\t\t\tif id < uint64(len(functionIds)) {\n\t\t\t\t\tl.Line[i].Function = functionIds[id]\n\t\t\t\t} else {\n\t\t\t\t\tl.Line[i].Function = functions[id]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif l.ID < uint64(len(locationIds)) {\n\t\t\tlocationIds[l.ID] = l\n\t\t} else {\n\t\t\tlocations[l.ID] = l\n\t\t}\n\t}\n\n\tfor _, st := range p.SampleType {\n\t\tst.Type, err = getString(p.stringTable, &st.typeX, err)\n\t\tst.Unit, err = getString(p.stringTable, &st.unitX, err)\n\t}\n\n\t// Pre-allocate space for all locations.\n\tnumLocations := 0\n\tfor _, s := range p.Sample {\n\t\tnumLocations += len(s.locationIDX)\n\t}\n\tlocBuffer := make([]*Location, numLocations)\n\n\tfor _, s := range p.Sample {\n\t\tif len(s.labelX) > 0 {\n\t\t\tlabels := make(map[string][]string, len(s.labelX))\n\t\t\tnumLabels := make(map[string][]int64, len(s.labelX))\n\t\t\tnumUnits := make(map[string][]string, len(s.labelX))\n\t\t\tfor _, l := range s.labelX {\n\t\t\t\tvar key, value string\n\t\t\t\tkey, err = getString(p.stringTable, &l.keyX, err)\n\t\t\t\tif l.strX != 0 {\n\t\t\t\t\tvalue, err = getString(p.stringTable, &l.strX, err)\n\t\t\t\t\tlabels[key] = append(labels[key], value)\n\t\t\t\t} else if l.numX != 0 || l.unitX != 0 {\n\t\t\t\t\tnumValues := numLabels[key]\n\t\t\t\t\tunits := numUnits[key]\n\t\t\t\t\tif l.unitX != 0 {\n\t\t\t\t\t\tvar unit string\n\t\t\t\t\t\tunit, err = getString(p.stringTable, &l.unitX, err)\n\t\t\t\t\t\tunits = padStringArray(units, len(numValues))\n\t\t\t\t\t\tnumUnits[key] = append(units, unit)\n\t\t\t\t\t}\n\t\t\t\t\tnumLabels[key] = append(numLabels[key], l.numX)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(labels) > 0 {\n\t\t\t\ts.Label = labels\n\t\t\t}\n\t\t\tif len(numLabels) > 0 {\n\t\t\t\ts.NumLabel = numLabels\n\t\t\t\tfor key, units := range numUnits {\n\t\t\t\t\tif len(units) > 0 {\n\t\t\t\t\t\tnumUnits[key] = padStringArray(units, len(numLabels[key]))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ts.NumUnit = numUnits\n\t\t\t}\n\t\t}\n\n\t\ts.Location = locBuffer[:len(s.locationIDX)]\n\t\tlocBuffer = locBuffer[len(s.locationIDX):]\n\t\tfor i, lid := range s.locationIDX {\n\t\t\tif lid < uint64(len(locationIds)) {\n\t\t\t\ts.Location[i] = locationIds[lid]\n\t\t\t} else {\n\t\t\t\ts.Location[i] = locations[lid]\n\t\t\t}\n\t\t}\n\t\ts.locationIDX = nil\n\t}\n\n\tp.DropFrames, err = getString(p.stringTable, &p.dropFramesX, err)\n\tp.KeepFrames, err = getString(p.stringTable, &p.keepFramesX, err)\n\n\tif pt := p.PeriodType; pt == nil {\n\t\tp.PeriodType = &ValueType{}\n\t}\n\n\tif pt := p.PeriodType; pt != nil {\n\t\tpt.Type, err = getString(p.stringTable, &pt.typeX, err)\n\t\tpt.Unit, err = getString(p.stringTable, &pt.unitX, err)\n\t}\n\n\tfor _, i := range p.commentX {\n\t\tvar c string\n\t\tc, err = getString(p.stringTable, &i, err)\n\t\tp.Comments = append(p.Comments, c)\n\t}\n\n\tp.commentX = nil\n\tp.DefaultSampleType, err = getString(p.stringTable, &p.defaultSampleTypeX, err)\n\tp.DocURL, err = getString(p.stringTable, &p.docURLX, err)\n\tp.stringTable = nil\n\treturn err\n}\n\n// padStringArray pads arr with enough empty strings to make arr\n// length l when arr's length is less than l.\nfunc padStringArray(arr []string, l int) []string {\n\tif l <= len(arr) {\n\t\treturn arr\n\t}\n\treturn append(arr, make([]string, l-len(arr))...)\n}\n\nfunc (p *ValueType) decoder() []decoder {\n\treturn valueTypeDecoder\n}\n\nfunc (p *ValueType) encode(b *buffer) {\n\tencodeInt64Opt(b, 1, p.typeX)\n\tencodeInt64Opt(b, 2, p.unitX)\n}\n\nvar valueTypeDecoder = []decoder{\n\tnil, // 0\n\t// optional int64 type = 1\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).typeX) },\n\t// optional int64 unit = 2\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).unitX) },\n}\n\nfunc (p *Sample) decoder() []decoder {\n\treturn sampleDecoder\n}\n\nfunc (p *Sample) encode(b *buffer) {\n\tencodeUint64s(b, 1, p.locationIDX)\n\tencodeInt64s(b, 2, p.Value)\n\tfor _, x := range p.labelX {\n\t\tencodeMessage(b, 3, x)\n\t}\n}\n\nvar sampleDecoder = []decoder{\n\tnil, // 0\n\t// repeated uint64 location = 1\n\tfunc(b *buffer, m message) error { return decodeUint64s(b, &m.(*Sample).locationIDX) },\n\t// repeated int64 value = 2\n\tfunc(b *buffer, m message) error { return decodeInt64s(b, &m.(*Sample).Value) },\n\t// repeated Label label = 3\n\tfunc(b *buffer, m message) error {\n\t\ts := m.(*Sample)\n\t\tn := len(s.labelX)\n\t\ts.labelX = append(s.labelX, label{})\n\t\treturn decodeMessage(b, &s.labelX[n])\n\t},\n}\n\nfunc (p label) decoder() []decoder {\n\treturn labelDecoder\n}\n\nfunc (p label) encode(b *buffer) {\n\tencodeInt64Opt(b, 1, p.keyX)\n\tencodeInt64Opt(b, 2, p.strX)\n\tencodeInt64Opt(b, 3, p.numX)\n\tencodeInt64Opt(b, 4, p.unitX)\n}\n\nvar labelDecoder = []decoder{\n\tnil, // 0\n\t// optional int64 key = 1\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*label).keyX) },\n\t// optional int64 str = 2\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*label).strX) },\n\t// optional int64 num = 3\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*label).numX) },\n\t// optional int64 num = 4\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*label).unitX) },\n}\n\nfunc (p *Mapping) decoder() []decoder {\n\treturn mappingDecoder\n}\n\nfunc (p *Mapping) encode(b *buffer) {\n\tencodeUint64Opt(b, 1, p.ID)\n\tencodeUint64Opt(b, 2, p.Start)\n\tencodeUint64Opt(b, 3, p.Limit)\n\tencodeUint64Opt(b, 4, p.Offset)\n\tencodeInt64Opt(b, 5, p.fileX)\n\tencodeInt64Opt(b, 6, p.buildIDX)\n\tencodeBoolOpt(b, 7, p.HasFunctions)\n\tencodeBoolOpt(b, 8, p.HasFilenames)\n\tencodeBoolOpt(b, 9, p.HasLineNumbers)\n\tencodeBoolOpt(b, 10, p.HasInlineFrames)\n}\n\nvar mappingDecoder = []decoder{\n\tnil, // 0\n\tfunc(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).ID) },            // optional uint64 id = 1\n\tfunc(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Start) },         // optional uint64 memory_offset = 2\n\tfunc(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Limit) },         // optional uint64 memory_limit = 3\n\tfunc(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Offset) },        // optional uint64 file_offset = 4\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).fileX) },          // optional int64 filename = 5\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).buildIDX) },       // optional int64 build_id = 6\n\tfunc(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFunctions) },    // optional bool has_functions = 7\n\tfunc(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFilenames) },    // optional bool has_filenames = 8\n\tfunc(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasLineNumbers) },  // optional bool has_line_numbers = 9\n\tfunc(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasInlineFrames) }, // optional bool has_inline_frames = 10\n}\n\nfunc (p *Location) decoder() []decoder {\n\treturn locationDecoder\n}\n\nfunc (p *Location) encode(b *buffer) {\n\tencodeUint64Opt(b, 1, p.ID)\n\tencodeUint64Opt(b, 2, p.mappingIDX)\n\tencodeUint64Opt(b, 3, p.Address)\n\tfor i := range p.Line {\n\t\tencodeMessage(b, 4, &p.Line[i])\n\t}\n\tencodeBoolOpt(b, 5, p.IsFolded)\n}\n\nvar locationDecoder = []decoder{\n\tnil, // 0\n\tfunc(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).ID) },         // optional uint64 id = 1;\n\tfunc(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).mappingIDX) }, // optional uint64 mapping_id = 2;\n\tfunc(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).Address) },    // optional uint64 address = 3;\n\tfunc(b *buffer, m message) error { // repeated Line line = 4\n\t\tpp := m.(*Location)\n\t\tn := len(pp.Line)\n\t\tpp.Line = append(pp.Line, Line{})\n\t\treturn decodeMessage(b, &pp.Line[n])\n\t},\n\tfunc(b *buffer, m message) error { return decodeBool(b, &m.(*Location).IsFolded) }, // optional bool is_folded = 5;\n}\n\nfunc (p *Line) decoder() []decoder {\n\treturn lineDecoder\n}\n\nfunc (p *Line) encode(b *buffer) {\n\tencodeUint64Opt(b, 1, p.functionIDX)\n\tencodeInt64Opt(b, 2, p.Line)\n\tencodeInt64Opt(b, 3, p.Column)\n}\n\nvar lineDecoder = []decoder{\n\tnil, // 0\n\t// optional uint64 function_id = 1\n\tfunc(b *buffer, m message) error { return decodeUint64(b, &m.(*Line).functionIDX) },\n\t// optional int64 line = 2\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*Line).Line) },\n\t// optional int64 column = 3\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*Line).Column) },\n}\n\nfunc (p *Function) decoder() []decoder {\n\treturn functionDecoder\n}\n\nfunc (p *Function) encode(b *buffer) {\n\tencodeUint64Opt(b, 1, p.ID)\n\tencodeInt64Opt(b, 2, p.nameX)\n\tencodeInt64Opt(b, 3, p.systemNameX)\n\tencodeInt64Opt(b, 4, p.filenameX)\n\tencodeInt64Opt(b, 5, p.StartLine)\n}\n\nvar functionDecoder = []decoder{\n\tnil, // 0\n\t// optional uint64 id = 1\n\tfunc(b *buffer, m message) error { return decodeUint64(b, &m.(*Function).ID) },\n\t// optional int64 function_name = 2\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).nameX) },\n\t// optional int64 function_system_name = 3\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).systemNameX) },\n\t// repeated int64 filename = 4\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).filenameX) },\n\t// optional int64 start_line = 5\n\tfunc(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).StartLine) },\n}\n\nfunc addString(strings map[string]int, s string) int64 {\n\ti, ok := strings[s]\n\tif !ok {\n\t\ti = len(strings)\n\t\tstrings[s] = i\n\t}\n\treturn int64(i)\n}\n\nfunc getString(strings []string, strng *int64, err error) (string, error) {\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\ts := int(*strng)\n\tif s < 0 || s >= len(strings) {\n\t\treturn \"\", errMalformed\n\t}\n\t*strng = 0\n\treturn strings[s], nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/pprof/profile/filter.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage profile\n\n// Implements methods to filter samples from profiles.\n\nimport \"regexp\"\n\n// FilterSamplesByName filters the samples in a profile and only keeps\n// samples where at least one frame matches focus but none match ignore.\n// Returns true is the corresponding regexp matched at least one sample.\nfunc (p *Profile) FilterSamplesByName(focus, ignore, hide, show *regexp.Regexp) (fm, im, hm, hnm bool) {\n\tif focus == nil && ignore == nil && hide == nil && show == nil {\n\t\tfm = true // Missing focus implies a match\n\t\treturn\n\t}\n\tfocusOrIgnore := make(map[uint64]bool)\n\thidden := make(map[uint64]bool)\n\tfor _, l := range p.Location {\n\t\tif ignore != nil && l.matchesName(ignore) {\n\t\t\tim = true\n\t\t\tfocusOrIgnore[l.ID] = false\n\t\t} else if focus == nil || l.matchesName(focus) {\n\t\t\tfm = true\n\t\t\tfocusOrIgnore[l.ID] = true\n\t\t}\n\n\t\tif hide != nil && l.matchesName(hide) {\n\t\t\thm = true\n\t\t\tl.Line = l.unmatchedLines(hide)\n\t\t\tif len(l.Line) == 0 {\n\t\t\t\thidden[l.ID] = true\n\t\t\t}\n\t\t}\n\t\tif show != nil {\n\t\t\tl.Line = l.matchedLines(show)\n\t\t\tif len(l.Line) == 0 {\n\t\t\t\thidden[l.ID] = true\n\t\t\t} else {\n\t\t\t\thnm = true\n\t\t\t}\n\t\t}\n\t}\n\n\ts := make([]*Sample, 0, len(p.Sample))\n\tfor _, sample := range p.Sample {\n\t\tif focusedAndNotIgnored(sample.Location, focusOrIgnore) {\n\t\t\tif len(hidden) > 0 {\n\t\t\t\tvar locs []*Location\n\t\t\t\tfor _, loc := range sample.Location {\n\t\t\t\t\tif !hidden[loc.ID] {\n\t\t\t\t\t\tlocs = append(locs, loc)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif len(locs) == 0 {\n\t\t\t\t\t// Remove sample with no locations (by not adding it to s).\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tsample.Location = locs\n\t\t\t}\n\t\t\ts = append(s, sample)\n\t\t}\n\t}\n\tp.Sample = s\n\n\treturn\n}\n\n// ShowFrom drops all stack frames above the highest matching frame and returns\n// whether a match was found. If showFrom is nil it returns false and does not\n// modify the profile.\n//\n// Example: consider a sample with frames [A, B, C, B], where A is the root.\n// ShowFrom(nil) returns false and has frames [A, B, C, B].\n// ShowFrom(A) returns true and has frames [A, B, C, B].\n// ShowFrom(B) returns true and has frames [B, C, B].\n// ShowFrom(C) returns true and has frames [C, B].\n// ShowFrom(D) returns false and drops the sample because no frames remain.\nfunc (p *Profile) ShowFrom(showFrom *regexp.Regexp) (matched bool) {\n\tif showFrom == nil {\n\t\treturn false\n\t}\n\t// showFromLocs stores location IDs that matched ShowFrom.\n\tshowFromLocs := make(map[uint64]bool)\n\t// Apply to locations.\n\tfor _, loc := range p.Location {\n\t\tif filterShowFromLocation(loc, showFrom) {\n\t\t\tshowFromLocs[loc.ID] = true\n\t\t\tmatched = true\n\t\t}\n\t}\n\t// For all samples, strip locations after the highest matching one.\n\ts := make([]*Sample, 0, len(p.Sample))\n\tfor _, sample := range p.Sample {\n\t\tfor i := len(sample.Location) - 1; i >= 0; i-- {\n\t\t\tif showFromLocs[sample.Location[i].ID] {\n\t\t\t\tsample.Location = sample.Location[:i+1]\n\t\t\t\ts = append(s, sample)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tp.Sample = s\n\treturn matched\n}\n\n// filterShowFromLocation tests a showFrom regex against a location, removes\n// lines after the last match and returns whether a match was found. If the\n// mapping is matched, then all lines are kept.\nfunc filterShowFromLocation(loc *Location, showFrom *regexp.Regexp) bool {\n\tif m := loc.Mapping; m != nil && showFrom.MatchString(m.File) {\n\t\treturn true\n\t}\n\tif i := loc.lastMatchedLineIndex(showFrom); i >= 0 {\n\t\tloc.Line = loc.Line[:i+1]\n\t\treturn true\n\t}\n\treturn false\n}\n\n// lastMatchedLineIndex returns the index of the last line that matches a regex,\n// or -1 if no match is found.\nfunc (loc *Location) lastMatchedLineIndex(re *regexp.Regexp) int {\n\tfor i := len(loc.Line) - 1; i >= 0; i-- {\n\t\tif fn := loc.Line[i].Function; fn != nil {\n\t\t\tif re.MatchString(fn.Name) || re.MatchString(fn.Filename) {\n\t\t\t\treturn i\n\t\t\t}\n\t\t}\n\t}\n\treturn -1\n}\n\n// FilterTagsByName filters the tags in a profile and only keeps\n// tags that match show and not hide.\nfunc (p *Profile) FilterTagsByName(show, hide *regexp.Regexp) (sm, hm bool) {\n\tmatchRemove := func(name string) bool {\n\t\tmatchShow := show == nil || show.MatchString(name)\n\t\tmatchHide := hide != nil && hide.MatchString(name)\n\n\t\tif matchShow {\n\t\t\tsm = true\n\t\t}\n\t\tif matchHide {\n\t\t\thm = true\n\t\t}\n\t\treturn !matchShow || matchHide\n\t}\n\tfor _, s := range p.Sample {\n\t\tfor lab := range s.Label {\n\t\t\tif matchRemove(lab) {\n\t\t\t\tdelete(s.Label, lab)\n\t\t\t}\n\t\t}\n\t\tfor lab := range s.NumLabel {\n\t\t\tif matchRemove(lab) {\n\t\t\t\tdelete(s.NumLabel, lab)\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\n// matchesName returns whether the location matches the regular\n// expression. It checks any available function names, file names, and\n// mapping object filename.\nfunc (loc *Location) matchesName(re *regexp.Regexp) bool {\n\tfor _, ln := range loc.Line {\n\t\tif fn := ln.Function; fn != nil {\n\t\t\tif re.MatchString(fn.Name) || re.MatchString(fn.Filename) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\tif m := loc.Mapping; m != nil && re.MatchString(m.File) {\n\t\treturn true\n\t}\n\treturn false\n}\n\n// unmatchedLines returns the lines in the location that do not match\n// the regular expression.\nfunc (loc *Location) unmatchedLines(re *regexp.Regexp) []Line {\n\tif m := loc.Mapping; m != nil && re.MatchString(m.File) {\n\t\treturn nil\n\t}\n\tvar lines []Line\n\tfor _, ln := range loc.Line {\n\t\tif fn := ln.Function; fn != nil {\n\t\t\tif re.MatchString(fn.Name) || re.MatchString(fn.Filename) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tlines = append(lines, ln)\n\t}\n\treturn lines\n}\n\n// matchedLines returns the lines in the location that match\n// the regular expression.\nfunc (loc *Location) matchedLines(re *regexp.Regexp) []Line {\n\tif m := loc.Mapping; m != nil && re.MatchString(m.File) {\n\t\treturn loc.Line\n\t}\n\tvar lines []Line\n\tfor _, ln := range loc.Line {\n\t\tif fn := ln.Function; fn != nil {\n\t\t\tif !re.MatchString(fn.Name) && !re.MatchString(fn.Filename) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tlines = append(lines, ln)\n\t}\n\treturn lines\n}\n\n// focusedAndNotIgnored looks up a slice of ids against a map of\n// focused/ignored locations. The map only contains locations that are\n// explicitly focused or ignored. Returns whether there is at least\n// one focused location but no ignored locations.\nfunc focusedAndNotIgnored(locs []*Location, m map[uint64]bool) bool {\n\tvar f bool\n\tfor _, loc := range locs {\n\t\tif focus, focusOrIgnore := m[loc.ID]; focusOrIgnore {\n\t\t\tif focus {\n\t\t\t\t// Found focused location. Must keep searching in case there\n\t\t\t\t// is an ignored one as well.\n\t\t\t\tf = true\n\t\t\t} else {\n\t\t\t\t// Found ignored location. Can return false right away.\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn f\n}\n\n// TagMatch selects tags for filtering\ntype TagMatch func(s *Sample) bool\n\n// FilterSamplesByTag removes all samples from the profile, except\n// those that match focus and do not match the ignore regular\n// expression.\nfunc (p *Profile) FilterSamplesByTag(focus, ignore TagMatch) (fm, im bool) {\n\tsamples := make([]*Sample, 0, len(p.Sample))\n\tfor _, s := range p.Sample {\n\t\tfocused, ignored := true, false\n\t\tif focus != nil {\n\t\t\tfocused = focus(s)\n\t\t}\n\t\tif ignore != nil {\n\t\t\tignored = ignore(s)\n\t\t}\n\t\tfm = fm || focused\n\t\tim = im || ignored\n\t\tif focused && !ignored {\n\t\t\tsamples = append(samples, s)\n\t\t}\n\t}\n\tp.Sample = samples\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/google/pprof/profile/index.go",
    "content": "// Copyright 2016 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage profile\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// SampleIndexByName returns the appropriate index for a value of sample index.\n// If numeric, it returns the number, otherwise it looks up the text in the\n// profile sample types.\nfunc (p *Profile) SampleIndexByName(sampleIndex string) (int, error) {\n\tif sampleIndex == \"\" {\n\t\tif dst := p.DefaultSampleType; dst != \"\" {\n\t\t\tfor i, t := range sampleTypes(p) {\n\t\t\t\tif t == dst {\n\t\t\t\t\treturn i, nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// By default select the last sample value\n\t\treturn len(p.SampleType) - 1, nil\n\t}\n\tif i, err := strconv.Atoi(sampleIndex); err == nil {\n\t\tif i < 0 || i >= len(p.SampleType) {\n\t\t\treturn 0, fmt.Errorf(\"sample_index %s is outside the range [0..%d]\", sampleIndex, len(p.SampleType)-1)\n\t\t}\n\t\treturn i, nil\n\t}\n\n\t// Remove the inuse_ prefix to support legacy pprof options\n\t// \"inuse_space\" and \"inuse_objects\" for profiles containing types\n\t// \"space\" and \"objects\".\n\tnoInuse := strings.TrimPrefix(sampleIndex, \"inuse_\")\n\tfor i, t := range p.SampleType {\n\t\tif t.Type == sampleIndex || t.Type == noInuse {\n\t\t\treturn i, nil\n\t\t}\n\t}\n\n\treturn 0, fmt.Errorf(\"sample_index %q must be one of: %v\", sampleIndex, sampleTypes(p))\n}\n\nfunc sampleTypes(p *Profile) []string {\n\ttypes := make([]string, len(p.SampleType))\n\tfor i, t := range p.SampleType {\n\t\ttypes[i] = t.Type\n\t}\n\treturn types\n}\n"
  },
  {
    "path": "vendor/github.com/google/pprof/profile/legacy_java_profile.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// This file implements parsers to convert java legacy profiles into\n// the profile.proto format.\n\npackage profile\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nvar (\n\tattributeRx            = regexp.MustCompile(`([\\w ]+)=([\\w ]+)`)\n\tjavaSampleRx           = regexp.MustCompile(` *(\\d+) +(\\d+) +@ +([ x0-9a-f]*)`)\n\tjavaLocationRx         = regexp.MustCompile(`^\\s*0x([[:xdigit:]]+)\\s+(.*)\\s*$`)\n\tjavaLocationFileLineRx = regexp.MustCompile(`^(.*)\\s+\\((.+):(-?[[:digit:]]+)\\)$`)\n\tjavaLocationPathRx     = regexp.MustCompile(`^(.*)\\s+\\((.*)\\)$`)\n)\n\n// javaCPUProfile returns a new Profile from profilez data.\n// b is the profile bytes after the header, period is the profiling\n// period, and parse is a function to parse 8-byte chunks from the\n// profile in its native endianness.\nfunc javaCPUProfile(b []byte, period int64, parse func(b []byte) (uint64, []byte)) (*Profile, error) {\n\tp := &Profile{\n\t\tPeriod:     period * 1000,\n\t\tPeriodType: &ValueType{Type: \"cpu\", Unit: \"nanoseconds\"},\n\t\tSampleType: []*ValueType{{Type: \"samples\", Unit: \"count\"}, {Type: \"cpu\", Unit: \"nanoseconds\"}},\n\t}\n\tvar err error\n\tvar locs map[uint64]*Location\n\tif b, locs, err = parseCPUSamples(b, parse, false, p); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err = parseJavaLocations(b, locs, p); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Strip out addresses for better merge.\n\tif err = p.Aggregate(true, true, true, true, false, false); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn p, nil\n}\n\n// parseJavaProfile returns a new profile from heapz or contentionz\n// data. b is the profile bytes after the header.\nfunc parseJavaProfile(b []byte) (*Profile, error) {\n\th := bytes.SplitAfterN(b, []byte(\"\\n\"), 2)\n\tif len(h) < 2 {\n\t\treturn nil, errUnrecognized\n\t}\n\n\tp := &Profile{\n\t\tPeriodType: &ValueType{},\n\t}\n\theader := string(bytes.TrimSpace(h[0]))\n\n\tvar err error\n\tvar pType string\n\tswitch header {\n\tcase \"--- heapz 1 ---\":\n\t\tpType = \"heap\"\n\tcase \"--- contentionz 1 ---\":\n\t\tpType = \"contention\"\n\tdefault:\n\t\treturn nil, errUnrecognized\n\t}\n\n\tif b, err = parseJavaHeader(pType, h[1], p); err != nil {\n\t\treturn nil, err\n\t}\n\tvar locs map[uint64]*Location\n\tif b, locs, err = parseJavaSamples(pType, b, p); err != nil {\n\t\treturn nil, err\n\t}\n\tif err = parseJavaLocations(b, locs, p); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Strip out addresses for better merge.\n\tif err = p.Aggregate(true, true, true, true, false, false); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn p, nil\n}\n\n// parseJavaHeader parses the attribute section on a java profile and\n// populates a profile. Returns the remainder of the buffer after all\n// attributes.\nfunc parseJavaHeader(pType string, b []byte, p *Profile) ([]byte, error) {\n\tnextNewLine := bytes.IndexByte(b, byte('\\n'))\n\tfor nextNewLine != -1 {\n\t\tline := string(bytes.TrimSpace(b[0:nextNewLine]))\n\t\tif line != \"\" {\n\t\t\th := attributeRx.FindStringSubmatch(line)\n\t\t\tif h == nil {\n\t\t\t\t// Not a valid attribute, exit.\n\t\t\t\treturn b, nil\n\t\t\t}\n\n\t\t\tattribute, value := strings.TrimSpace(h[1]), strings.TrimSpace(h[2])\n\t\t\tvar err error\n\t\t\tswitch pType + \"/\" + attribute {\n\t\t\tcase \"heap/format\", \"cpu/format\", \"contention/format\":\n\t\t\t\tif value != \"java\" {\n\t\t\t\t\treturn nil, errUnrecognized\n\t\t\t\t}\n\t\t\tcase \"heap/resolution\":\n\t\t\t\tp.SampleType = []*ValueType{\n\t\t\t\t\t{Type: \"inuse_objects\", Unit: \"count\"},\n\t\t\t\t\t{Type: \"inuse_space\", Unit: value},\n\t\t\t\t}\n\t\t\tcase \"contention/resolution\":\n\t\t\t\tp.SampleType = []*ValueType{\n\t\t\t\t\t{Type: \"contentions\", Unit: \"count\"},\n\t\t\t\t\t{Type: \"delay\", Unit: value},\n\t\t\t\t}\n\t\t\tcase \"contention/sampling period\":\n\t\t\t\tp.PeriodType = &ValueType{\n\t\t\t\t\tType: \"contentions\", Unit: \"count\",\n\t\t\t\t}\n\t\t\t\tif p.Period, err = strconv.ParseInt(value, 0, 64); err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"failed to parse attribute %s: %v\", line, err)\n\t\t\t\t}\n\t\t\tcase \"contention/ms since reset\":\n\t\t\t\tmillis, err := strconv.ParseInt(value, 0, 64)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"failed to parse attribute %s: %v\", line, err)\n\t\t\t\t}\n\t\t\t\tp.DurationNanos = millis * 1000 * 1000\n\t\t\tdefault:\n\t\t\t\treturn nil, errUnrecognized\n\t\t\t}\n\t\t}\n\t\t// Grab next line.\n\t\tb = b[nextNewLine+1:]\n\t\tnextNewLine = bytes.IndexByte(b, byte('\\n'))\n\t}\n\treturn b, nil\n}\n\n// parseJavaSamples parses the samples from a java profile and\n// populates the Samples in a profile. Returns the remainder of the\n// buffer after the samples.\nfunc parseJavaSamples(pType string, b []byte, p *Profile) ([]byte, map[uint64]*Location, error) {\n\tnextNewLine := bytes.IndexByte(b, byte('\\n'))\n\tlocs := make(map[uint64]*Location)\n\tfor nextNewLine != -1 {\n\t\tline := string(bytes.TrimSpace(b[0:nextNewLine]))\n\t\tif line != \"\" {\n\t\t\tsample := javaSampleRx.FindStringSubmatch(line)\n\t\t\tif sample == nil {\n\t\t\t\t// Not a valid sample, exit.\n\t\t\t\treturn b, locs, nil\n\t\t\t}\n\n\t\t\t// Java profiles have data/fields inverted compared to other\n\t\t\t// profile types.\n\t\t\tvar err error\n\t\t\tvalue1, value2, value3 := sample[2], sample[1], sample[3]\n\t\t\taddrs, err := parseHexAddresses(value3)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, nil, fmt.Errorf(\"malformed sample: %s: %v\", line, err)\n\t\t\t}\n\n\t\t\tvar sloc []*Location\n\t\t\tfor _, addr := range addrs {\n\t\t\t\tloc := locs[addr]\n\t\t\t\tif locs[addr] == nil {\n\t\t\t\t\tloc = &Location{\n\t\t\t\t\t\tAddress: addr,\n\t\t\t\t\t}\n\t\t\t\t\tp.Location = append(p.Location, loc)\n\t\t\t\t\tlocs[addr] = loc\n\t\t\t\t}\n\t\t\t\tsloc = append(sloc, loc)\n\t\t\t}\n\t\t\ts := &Sample{\n\t\t\t\tValue:    make([]int64, 2),\n\t\t\t\tLocation: sloc,\n\t\t\t}\n\n\t\t\tif s.Value[0], err = strconv.ParseInt(value1, 0, 64); err != nil {\n\t\t\t\treturn nil, nil, fmt.Errorf(\"parsing sample %s: %v\", line, err)\n\t\t\t}\n\t\t\tif s.Value[1], err = strconv.ParseInt(value2, 0, 64); err != nil {\n\t\t\t\treturn nil, nil, fmt.Errorf(\"parsing sample %s: %v\", line, err)\n\t\t\t}\n\n\t\t\tswitch pType {\n\t\t\tcase \"heap\":\n\t\t\t\tconst javaHeapzSamplingRate = 524288 // 512K\n\t\t\t\tif s.Value[0] == 0 {\n\t\t\t\t\treturn nil, nil, fmt.Errorf(\"parsing sample %s: second value must be non-zero\", line)\n\t\t\t\t}\n\t\t\t\ts.NumLabel = map[string][]int64{\"bytes\": {s.Value[1] / s.Value[0]}}\n\t\t\t\ts.Value[0], s.Value[1] = scaleHeapSample(s.Value[0], s.Value[1], javaHeapzSamplingRate)\n\t\t\tcase \"contention\":\n\t\t\t\tif period := p.Period; period != 0 {\n\t\t\t\t\ts.Value[0] = s.Value[0] * p.Period\n\t\t\t\t\ts.Value[1] = s.Value[1] * p.Period\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.Sample = append(p.Sample, s)\n\t\t}\n\t\t// Grab next line.\n\t\tb = b[nextNewLine+1:]\n\t\tnextNewLine = bytes.IndexByte(b, byte('\\n'))\n\t}\n\treturn b, locs, nil\n}\n\n// parseJavaLocations parses the location information in a java\n// profile and populates the Locations in a profile. It uses the\n// location addresses from the profile as both the ID of each\n// location.\nfunc parseJavaLocations(b []byte, locs map[uint64]*Location, p *Profile) error {\n\tr := bytes.NewBuffer(b)\n\tfns := make(map[string]*Function)\n\tfor {\n\t\tline, err := r.ReadString('\\n')\n\t\tif err != nil {\n\t\t\tif err != io.EOF {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif line == \"\" {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif line = strings.TrimSpace(line); line == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tjloc := javaLocationRx.FindStringSubmatch(line)\n\t\tif len(jloc) != 3 {\n\t\t\tcontinue\n\t\t}\n\t\taddr, err := strconv.ParseUint(jloc[1], 16, 64)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"parsing sample %s: %v\", line, err)\n\t\t}\n\t\tloc := locs[addr]\n\t\tif loc == nil {\n\t\t\t// Unused/unseen\n\t\t\tcontinue\n\t\t}\n\t\tvar lineFunc, lineFile string\n\t\tvar lineNo int64\n\n\t\tif fileLine := javaLocationFileLineRx.FindStringSubmatch(jloc[2]); len(fileLine) == 4 {\n\t\t\t// Found a line of the form: \"function (file:line)\"\n\t\t\tlineFunc, lineFile = fileLine[1], fileLine[2]\n\t\t\tif n, err := strconv.ParseInt(fileLine[3], 10, 64); err == nil && n > 0 {\n\t\t\t\tlineNo = n\n\t\t\t}\n\t\t} else if filePath := javaLocationPathRx.FindStringSubmatch(jloc[2]); len(filePath) == 3 {\n\t\t\t// If there's not a file:line, it's a shared library path.\n\t\t\t// The path isn't interesting, so just give the .so.\n\t\t\tlineFunc, lineFile = filePath[1], filepath.Base(filePath[2])\n\t\t} else if strings.Contains(jloc[2], \"generated stub/JIT\") {\n\t\t\tlineFunc = \"STUB\"\n\t\t} else {\n\t\t\t// Treat whole line as the function name. This is used by the\n\t\t\t// java agent for internal states such as \"GC\" or \"VM\".\n\t\t\tlineFunc = jloc[2]\n\t\t}\n\t\tfn := fns[lineFunc]\n\n\t\tif fn == nil {\n\t\t\tfn = &Function{\n\t\t\t\tName:       lineFunc,\n\t\t\t\tSystemName: lineFunc,\n\t\t\t\tFilename:   lineFile,\n\t\t\t}\n\t\t\tfns[lineFunc] = fn\n\t\t\tp.Function = append(p.Function, fn)\n\t\t}\n\t\tloc.Line = []Line{\n\t\t\t{\n\t\t\t\tFunction: fn,\n\t\t\t\tLine:     lineNo,\n\t\t\t},\n\t\t}\n\t\tloc.Address = 0\n\t}\n\n\tp.remapLocationIDs()\n\tp.remapFunctionIDs()\n\tp.remapMappingIDs()\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/pprof/profile/legacy_profile.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// This file implements parsers to convert legacy profiles into the\n// profile.proto format.\n\npackage profile\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nvar (\n\tcountStartRE = regexp.MustCompile(`\\A(\\S+) profile: total \\d+\\z`)\n\tcountRE      = regexp.MustCompile(`\\A(\\d+) @(( 0x[0-9a-f]+)+)\\z`)\n\n\theapHeaderRE = regexp.MustCompile(`heap profile: *(\\d+): *(\\d+) *\\[ *(\\d+): *(\\d+) *\\] *@ *(heap[_a-z0-9]*)/?(\\d*)`)\n\theapSampleRE = regexp.MustCompile(`(-?\\d+): *(-?\\d+) *\\[ *(\\d+): *(\\d+) *] @([ x0-9a-f]*)`)\n\n\tcontentionSampleRE = regexp.MustCompile(`(\\d+) *(\\d+) @([ x0-9a-f]*)`)\n\n\thexNumberRE = regexp.MustCompile(`0x[0-9a-f]+`)\n\n\tgrowthHeaderRE = regexp.MustCompile(`heap profile: *(\\d+): *(\\d+) *\\[ *(\\d+): *(\\d+) *\\] @ growthz?`)\n\n\tfragmentationHeaderRE = regexp.MustCompile(`heap profile: *(\\d+): *(\\d+) *\\[ *(\\d+): *(\\d+) *\\] @ fragmentationz?`)\n\n\tthreadzStartRE = regexp.MustCompile(`--- threadz \\d+ ---`)\n\tthreadStartRE  = regexp.MustCompile(`--- Thread ([[:xdigit:]]+) \\(name: (.*)/(\\d+)\\) stack: ---`)\n\n\t// Regular expressions to parse process mappings. Support the format used by Linux /proc/.../maps and other tools.\n\t// Recommended format:\n\t// Start   End     object file name     offset(optional)   linker build id\n\t// 0x40000-0x80000 /path/to/binary      (@FF00)            abc123456\n\tspaceDigits = `\\s+[[:digit:]]+`\n\thexPair     = `\\s+[[:xdigit:]]+:[[:xdigit:]]+`\n\toSpace      = `\\s*`\n\t// Capturing expressions.\n\tcHex           = `(?:0x)?([[:xdigit:]]+)`\n\tcHexRange      = `\\s*` + cHex + `[\\s-]?` + oSpace + cHex + `:?`\n\tcSpaceString   = `(?:\\s+(\\S+))?`\n\tcSpaceHex      = `(?:\\s+([[:xdigit:]]+))?`\n\tcSpaceAtOffset = `(?:\\s+\\(@([[:xdigit:]]+)\\))?`\n\tcPerm          = `(?:\\s+([-rwxp]+))?`\n\n\tprocMapsRE  = regexp.MustCompile(`^` + cHexRange + cPerm + cSpaceHex + hexPair + spaceDigits + cSpaceString)\n\tbriefMapsRE = regexp.MustCompile(`^` + cHexRange + cPerm + cSpaceString + cSpaceAtOffset + cSpaceHex)\n\n\t// Regular expression to parse log data, of the form:\n\t// ... file:line] msg...\n\tlogInfoRE = regexp.MustCompile(`^[^\\[\\]]+:[0-9]+]\\s`)\n)\n\nfunc isSpaceOrComment(line string) bool {\n\ttrimmed := strings.TrimSpace(line)\n\treturn len(trimmed) == 0 || trimmed[0] == '#'\n}\n\n// parseGoCount parses a Go count profile (e.g., threadcreate or\n// goroutine) and returns a new Profile.\nfunc parseGoCount(b []byte) (*Profile, error) {\n\ts := bufio.NewScanner(bytes.NewBuffer(b))\n\t// Skip comments at the beginning of the file.\n\tfor s.Scan() && isSpaceOrComment(s.Text()) {\n\t}\n\tif err := s.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\tm := countStartRE.FindStringSubmatch(s.Text())\n\tif m == nil {\n\t\treturn nil, errUnrecognized\n\t}\n\tprofileType := m[1]\n\tp := &Profile{\n\t\tPeriodType: &ValueType{Type: profileType, Unit: \"count\"},\n\t\tPeriod:     1,\n\t\tSampleType: []*ValueType{{Type: profileType, Unit: \"count\"}},\n\t}\n\tlocations := make(map[uint64]*Location)\n\tfor s.Scan() {\n\t\tline := s.Text()\n\t\tif isSpaceOrComment(line) {\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(line, \"---\") {\n\t\t\tbreak\n\t\t}\n\t\tm := countRE.FindStringSubmatch(line)\n\t\tif m == nil {\n\t\t\treturn nil, errMalformed\n\t\t}\n\t\tn, err := strconv.ParseInt(m[1], 0, 64)\n\t\tif err != nil {\n\t\t\treturn nil, errMalformed\n\t\t}\n\t\tfields := strings.Fields(m[2])\n\t\tlocs := make([]*Location, 0, len(fields))\n\t\tfor _, stk := range fields {\n\t\t\taddr, err := strconv.ParseUint(stk, 0, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, errMalformed\n\t\t\t}\n\t\t\t// Adjust all frames by -1 to land on top of the call instruction.\n\t\t\taddr--\n\t\t\tloc := locations[addr]\n\t\t\tif loc == nil {\n\t\t\t\tloc = &Location{\n\t\t\t\t\tAddress: addr,\n\t\t\t\t}\n\t\t\t\tlocations[addr] = loc\n\t\t\t\tp.Location = append(p.Location, loc)\n\t\t\t}\n\t\t\tlocs = append(locs, loc)\n\t\t}\n\t\tp.Sample = append(p.Sample, &Sample{\n\t\t\tLocation: locs,\n\t\t\tValue:    []int64{n},\n\t\t})\n\t}\n\tif err := s.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := parseAdditionalSections(s, p); err != nil {\n\t\treturn nil, err\n\t}\n\treturn p, nil\n}\n\n// remapLocationIDs ensures there is a location for each address\n// referenced by a sample, and remaps the samples to point to the new\n// location ids.\nfunc (p *Profile) remapLocationIDs() {\n\tseen := make(map[*Location]bool, len(p.Location))\n\tvar locs []*Location\n\n\tfor _, s := range p.Sample {\n\t\tfor _, l := range s.Location {\n\t\t\tif seen[l] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tl.ID = uint64(len(locs) + 1)\n\t\t\tlocs = append(locs, l)\n\t\t\tseen[l] = true\n\t\t}\n\t}\n\tp.Location = locs\n}\n\nfunc (p *Profile) remapFunctionIDs() {\n\tseen := make(map[*Function]bool, len(p.Function))\n\tvar fns []*Function\n\n\tfor _, l := range p.Location {\n\t\tfor _, ln := range l.Line {\n\t\t\tfn := ln.Function\n\t\t\tif fn == nil || seen[fn] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfn.ID = uint64(len(fns) + 1)\n\t\t\tfns = append(fns, fn)\n\t\t\tseen[fn] = true\n\t\t}\n\t}\n\tp.Function = fns\n}\n\n// remapMappingIDs matches location addresses with existing mappings\n// and updates them appropriately. This is O(N*M), if this ever shows\n// up as a bottleneck, evaluate sorting the mappings and doing a\n// binary search, which would make it O(N*log(M)).\nfunc (p *Profile) remapMappingIDs() {\n\t// Some profile handlers will incorrectly set regions for the main\n\t// executable if its section is remapped. Fix them through heuristics.\n\n\tif len(p.Mapping) > 0 {\n\t\t// Remove the initial mapping if named '/anon_hugepage' and has a\n\t\t// consecutive adjacent mapping.\n\t\tif m := p.Mapping[0]; strings.HasPrefix(m.File, \"/anon_hugepage\") {\n\t\t\tif len(p.Mapping) > 1 && m.Limit == p.Mapping[1].Start {\n\t\t\t\tp.Mapping = p.Mapping[1:]\n\t\t\t}\n\t\t}\n\t}\n\n\t// Subtract the offset from the start of the main mapping if it\n\t// ends up at a recognizable start address.\n\tif len(p.Mapping) > 0 {\n\t\tconst expectedStart = 0x400000\n\t\tif m := p.Mapping[0]; m.Start-m.Offset == expectedStart {\n\t\t\tm.Start = expectedStart\n\t\t\tm.Offset = 0\n\t\t}\n\t}\n\n\t// Associate each location with an address to the corresponding\n\t// mapping. Create fake mapping if a suitable one isn't found.\n\tvar fake *Mapping\nnextLocation:\n\tfor _, l := range p.Location {\n\t\ta := l.Address\n\t\tif l.Mapping != nil || a == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, m := range p.Mapping {\n\t\t\tif m.Start <= a && a < m.Limit {\n\t\t\t\tl.Mapping = m\n\t\t\t\tcontinue nextLocation\n\t\t\t}\n\t\t}\n\t\t// Work around legacy handlers failing to encode the first\n\t\t// part of mappings split into adjacent ranges.\n\t\tfor _, m := range p.Mapping {\n\t\t\tif m.Offset != 0 && m.Start-m.Offset <= a && a < m.Start {\n\t\t\t\tm.Start -= m.Offset\n\t\t\t\tm.Offset = 0\n\t\t\t\tl.Mapping = m\n\t\t\t\tcontinue nextLocation\n\t\t\t}\n\t\t}\n\t\t// If there is still no mapping, create a fake one.\n\t\t// This is important for the Go legacy handler, which produced\n\t\t// no mappings.\n\t\tif fake == nil {\n\t\t\tfake = &Mapping{\n\t\t\t\tID:    1,\n\t\t\t\tLimit: ^uint64(0),\n\t\t\t}\n\t\t\tp.Mapping = append(p.Mapping, fake)\n\t\t}\n\t\tl.Mapping = fake\n\t}\n\n\t// Reset all mapping IDs.\n\tfor i, m := range p.Mapping {\n\t\tm.ID = uint64(i + 1)\n\t}\n}\n\nvar cpuInts = []func([]byte) (uint64, []byte){\n\tget32l,\n\tget32b,\n\tget64l,\n\tget64b,\n}\n\nfunc get32l(b []byte) (uint64, []byte) {\n\tif len(b) < 4 {\n\t\treturn 0, nil\n\t}\n\treturn uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24, b[4:]\n}\n\nfunc get32b(b []byte) (uint64, []byte) {\n\tif len(b) < 4 {\n\t\treturn 0, nil\n\t}\n\treturn uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24, b[4:]\n}\n\nfunc get64l(b []byte) (uint64, []byte) {\n\tif len(b) < 8 {\n\t\treturn 0, nil\n\t}\n\treturn uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56, b[8:]\n}\n\nfunc get64b(b []byte) (uint64, []byte) {\n\tif len(b) < 8 {\n\t\treturn 0, nil\n\t}\n\treturn uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56, b[8:]\n}\n\n// parseCPU parses a profilez legacy profile and returns a newly\n// populated Profile.\n//\n// The general format for profilez samples is a sequence of words in\n// binary format. The first words are a header with the following data:\n//\n//\t1st word -- 0\n//\t2nd word -- 3\n//\t3rd word -- 0 if a c++ application, 1 if a java application.\n//\t4th word -- Sampling period (in microseconds).\n//\t5th word -- Padding.\nfunc parseCPU(b []byte) (*Profile, error) {\n\tvar parse func([]byte) (uint64, []byte)\n\tvar n1, n2, n3, n4, n5 uint64\n\tfor _, parse = range cpuInts {\n\t\tvar tmp []byte\n\t\tn1, tmp = parse(b)\n\t\tn2, tmp = parse(tmp)\n\t\tn3, tmp = parse(tmp)\n\t\tn4, tmp = parse(tmp)\n\t\tn5, tmp = parse(tmp)\n\n\t\tif tmp != nil && n1 == 0 && n2 == 3 && n3 == 0 && n4 > 0 && n5 == 0 {\n\t\t\tb = tmp\n\t\t\treturn cpuProfile(b, int64(n4), parse)\n\t\t}\n\t\tif tmp != nil && n1 == 0 && n2 == 3 && n3 == 1 && n4 > 0 && n5 == 0 {\n\t\t\tb = tmp\n\t\t\treturn javaCPUProfile(b, int64(n4), parse)\n\t\t}\n\t}\n\treturn nil, errUnrecognized\n}\n\n// cpuProfile returns a new Profile from C++ profilez data.\n// b is the profile bytes after the header, period is the profiling\n// period, and parse is a function to parse 8-byte chunks from the\n// profile in its native endianness.\nfunc cpuProfile(b []byte, period int64, parse func(b []byte) (uint64, []byte)) (*Profile, error) {\n\tp := &Profile{\n\t\tPeriod:     period * 1000,\n\t\tPeriodType: &ValueType{Type: \"cpu\", Unit: \"nanoseconds\"},\n\t\tSampleType: []*ValueType{\n\t\t\t{Type: \"samples\", Unit: \"count\"},\n\t\t\t{Type: \"cpu\", Unit: \"nanoseconds\"},\n\t\t},\n\t}\n\tvar err error\n\tif b, _, err = parseCPUSamples(b, parse, true, p); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// If *most* samples have the same second-to-the-bottom frame, it\n\t// strongly suggests that it is an uninteresting artifact of\n\t// measurement -- a stack frame pushed by the signal handler. The\n\t// bottom frame is always correct as it is picked up from the signal\n\t// structure, not the stack. Check if this is the case and if so,\n\t// remove.\n\n\t// Remove up to two frames.\n\tmaxiter := 2\n\t// Allow one different sample for this many samples with the same\n\t// second-to-last frame.\n\tsimilarSamples := 32\n\tmargin := len(p.Sample) / similarSamples\n\n\tfor iter := 0; iter < maxiter; iter++ {\n\t\taddr1 := make(map[uint64]int)\n\t\tfor _, s := range p.Sample {\n\t\t\tif len(s.Location) > 1 {\n\t\t\t\ta := s.Location[1].Address\n\t\t\t\taddr1[a] = addr1[a] + 1\n\t\t\t}\n\t\t}\n\n\t\tfor id1, count := range addr1 {\n\t\t\tif count >= len(p.Sample)-margin {\n\t\t\t\t// Found uninteresting frame, strip it out from all samples\n\t\t\t\tfor _, s := range p.Sample {\n\t\t\t\t\tif len(s.Location) > 1 && s.Location[1].Address == id1 {\n\t\t\t\t\t\ts.Location = append(s.Location[:1], s.Location[2:]...)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tif err := p.ParseMemoryMap(bytes.NewBuffer(b)); err != nil {\n\t\treturn nil, err\n\t}\n\n\tcleanupDuplicateLocations(p)\n\treturn p, nil\n}\n\nfunc cleanupDuplicateLocations(p *Profile) {\n\t// The profile handler may duplicate the leaf frame, because it gets\n\t// its address both from stack unwinding and from the signal\n\t// context. Detect this and delete the duplicate, which has been\n\t// adjusted by -1. The leaf address should not be adjusted as it is\n\t// not a call.\n\tfor _, s := range p.Sample {\n\t\tif len(s.Location) > 1 && s.Location[0].Address == s.Location[1].Address+1 {\n\t\t\ts.Location = append(s.Location[:1], s.Location[2:]...)\n\t\t}\n\t}\n}\n\n// parseCPUSamples parses a collection of profilez samples from a\n// profile.\n//\n// profilez samples are a repeated sequence of stack frames of the\n// form:\n//\n//\t1st word -- The number of times this stack was encountered.\n//\t2nd word -- The size of the stack (StackSize).\n//\t3rd word -- The first address on the stack.\n//\t...\n//\tStackSize + 2 -- The last address on the stack\n//\n// The last stack trace is of the form:\n//\n//\t1st word -- 0\n//\t2nd word -- 1\n//\t3rd word -- 0\n//\n// Addresses from stack traces may point to the next instruction after\n// each call. Optionally adjust by -1 to land somewhere on the actual\n// call (except for the leaf, which is not a call).\nfunc parseCPUSamples(b []byte, parse func(b []byte) (uint64, []byte), adjust bool, p *Profile) ([]byte, map[uint64]*Location, error) {\n\tlocs := make(map[uint64]*Location)\n\tfor len(b) > 0 {\n\t\tvar count, nstk uint64\n\t\tcount, b = parse(b)\n\t\tnstk, b = parse(b)\n\t\tif b == nil || nstk > uint64(len(b)/4) {\n\t\t\treturn nil, nil, errUnrecognized\n\t\t}\n\t\tvar sloc []*Location\n\t\taddrs := make([]uint64, nstk)\n\t\tfor i := 0; i < int(nstk); i++ {\n\t\t\taddrs[i], b = parse(b)\n\t\t}\n\n\t\tif count == 0 && nstk == 1 && addrs[0] == 0 {\n\t\t\t// End of data marker\n\t\t\tbreak\n\t\t}\n\t\tfor i, addr := range addrs {\n\t\t\tif adjust && i > 0 {\n\t\t\t\taddr--\n\t\t\t}\n\t\t\tloc := locs[addr]\n\t\t\tif loc == nil {\n\t\t\t\tloc = &Location{\n\t\t\t\t\tAddress: addr,\n\t\t\t\t}\n\t\t\t\tlocs[addr] = loc\n\t\t\t\tp.Location = append(p.Location, loc)\n\t\t\t}\n\t\t\tsloc = append(sloc, loc)\n\t\t}\n\t\tp.Sample = append(p.Sample,\n\t\t\t&Sample{\n\t\t\t\tValue:    []int64{int64(count), int64(count) * p.Period},\n\t\t\t\tLocation: sloc,\n\t\t\t})\n\t}\n\t// Reached the end without finding the EOD marker.\n\treturn b, locs, nil\n}\n\n// parseHeap parses a heapz legacy or a growthz profile and\n// returns a newly populated Profile.\nfunc parseHeap(b []byte) (p *Profile, err error) {\n\ts := bufio.NewScanner(bytes.NewBuffer(b))\n\tif !s.Scan() {\n\t\tif err := s.Err(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn nil, errUnrecognized\n\t}\n\tp = &Profile{}\n\n\tsampling := \"\"\n\thasAlloc := false\n\n\tline := s.Text()\n\tp.PeriodType = &ValueType{Type: \"space\", Unit: \"bytes\"}\n\tif header := heapHeaderRE.FindStringSubmatch(line); header != nil {\n\t\tsampling, p.Period, hasAlloc, err = parseHeapHeader(line)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else if header = growthHeaderRE.FindStringSubmatch(line); header != nil {\n\t\tp.Period = 1\n\t} else if header = fragmentationHeaderRE.FindStringSubmatch(line); header != nil {\n\t\tp.Period = 1\n\t} else {\n\t\treturn nil, errUnrecognized\n\t}\n\n\tif hasAlloc {\n\t\t// Put alloc before inuse so that default pprof selection\n\t\t// will prefer inuse_space.\n\t\tp.SampleType = []*ValueType{\n\t\t\t{Type: \"alloc_objects\", Unit: \"count\"},\n\t\t\t{Type: \"alloc_space\", Unit: \"bytes\"},\n\t\t\t{Type: \"inuse_objects\", Unit: \"count\"},\n\t\t\t{Type: \"inuse_space\", Unit: \"bytes\"},\n\t\t}\n\t} else {\n\t\tp.SampleType = []*ValueType{\n\t\t\t{Type: \"objects\", Unit: \"count\"},\n\t\t\t{Type: \"space\", Unit: \"bytes\"},\n\t\t}\n\t}\n\n\tlocs := make(map[uint64]*Location)\n\tfor s.Scan() {\n\t\tline := strings.TrimSpace(s.Text())\n\n\t\tif isSpaceOrComment(line) {\n\t\t\tcontinue\n\t\t}\n\n\t\tif isMemoryMapSentinel(line) {\n\t\t\tbreak\n\t\t}\n\n\t\tvalue, blocksize, addrs, err := parseHeapSample(line, p.Period, sampling, hasAlloc)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tvar sloc []*Location\n\t\tfor _, addr := range addrs {\n\t\t\t// Addresses from stack traces point to the next instruction after\n\t\t\t// each call. Adjust by -1 to land somewhere on the actual call.\n\t\t\taddr--\n\t\t\tloc := locs[addr]\n\t\t\tif locs[addr] == nil {\n\t\t\t\tloc = &Location{\n\t\t\t\t\tAddress: addr,\n\t\t\t\t}\n\t\t\t\tp.Location = append(p.Location, loc)\n\t\t\t\tlocs[addr] = loc\n\t\t\t}\n\t\t\tsloc = append(sloc, loc)\n\t\t}\n\n\t\tp.Sample = append(p.Sample, &Sample{\n\t\t\tValue:    value,\n\t\t\tLocation: sloc,\n\t\t\tNumLabel: map[string][]int64{\"bytes\": {blocksize}},\n\t\t})\n\t}\n\tif err := s.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := parseAdditionalSections(s, p); err != nil {\n\t\treturn nil, err\n\t}\n\treturn p, nil\n}\n\nfunc parseHeapHeader(line string) (sampling string, period int64, hasAlloc bool, err error) {\n\theader := heapHeaderRE.FindStringSubmatch(line)\n\tif header == nil {\n\t\treturn \"\", 0, false, errUnrecognized\n\t}\n\n\tif len(header[6]) > 0 {\n\t\tif period, err = strconv.ParseInt(header[6], 10, 64); err != nil {\n\t\t\treturn \"\", 0, false, errUnrecognized\n\t\t}\n\t}\n\n\tif (header[3] != header[1] && header[3] != \"0\") || (header[4] != header[2] && header[4] != \"0\") {\n\t\thasAlloc = true\n\t}\n\n\tswitch header[5] {\n\tcase \"heapz_v2\", \"heap_v2\":\n\t\treturn \"v2\", period, hasAlloc, nil\n\tcase \"heapprofile\":\n\t\treturn \"\", 1, hasAlloc, nil\n\tcase \"heap\":\n\t\treturn \"v2\", period / 2, hasAlloc, nil\n\tdefault:\n\t\treturn \"\", 0, false, errUnrecognized\n\t}\n}\n\n// parseHeapSample parses a single row from a heap profile into a new Sample.\nfunc parseHeapSample(line string, rate int64, sampling string, includeAlloc bool) (value []int64, blocksize int64, addrs []uint64, err error) {\n\tsampleData := heapSampleRE.FindStringSubmatch(line)\n\tif len(sampleData) != 6 {\n\t\treturn nil, 0, nil, fmt.Errorf(\"unexpected number of sample values: got %d, want 6\", len(sampleData))\n\t}\n\n\t// This is a local-scoped helper function to avoid needing to pass\n\t// around rate, sampling and many return parameters.\n\taddValues := func(countString, sizeString string, label string) error {\n\t\tcount, err := strconv.ParseInt(countString, 10, 64)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"malformed sample: %s: %v\", line, err)\n\t\t}\n\t\tsize, err := strconv.ParseInt(sizeString, 10, 64)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"malformed sample: %s: %v\", line, err)\n\t\t}\n\t\tif count == 0 && size != 0 {\n\t\t\treturn fmt.Errorf(\"%s count was 0 but %s bytes was %d\", label, label, size)\n\t\t}\n\t\tif count != 0 {\n\t\t\tblocksize = size / count\n\t\t\tif sampling == \"v2\" {\n\t\t\t\tcount, size = scaleHeapSample(count, size, rate)\n\t\t\t}\n\t\t}\n\t\tvalue = append(value, count, size)\n\t\treturn nil\n\t}\n\n\tif includeAlloc {\n\t\tif err := addValues(sampleData[3], sampleData[4], \"allocation\"); err != nil {\n\t\t\treturn nil, 0, nil, err\n\t\t}\n\t}\n\n\tif err := addValues(sampleData[1], sampleData[2], \"inuse\"); err != nil {\n\t\treturn nil, 0, nil, err\n\t}\n\n\taddrs, err = parseHexAddresses(sampleData[5])\n\tif err != nil {\n\t\treturn nil, 0, nil, fmt.Errorf(\"malformed sample: %s: %v\", line, err)\n\t}\n\n\treturn value, blocksize, addrs, nil\n}\n\n// parseHexAddresses extracts hex numbers from a string, attempts to convert\n// each to an unsigned 64-bit number and returns the resulting numbers as a\n// slice, or an error if the string contains hex numbers which are too large to\n// handle (which means a malformed profile).\nfunc parseHexAddresses(s string) ([]uint64, error) {\n\thexStrings := hexNumberRE.FindAllString(s, -1)\n\tvar addrs []uint64\n\tfor _, s := range hexStrings {\n\t\tif addr, err := strconv.ParseUint(s, 0, 64); err == nil {\n\t\t\taddrs = append(addrs, addr)\n\t\t} else {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse as hex 64-bit number: %s\", s)\n\t\t}\n\t}\n\treturn addrs, nil\n}\n\n// scaleHeapSample adjusts the data from a heapz Sample to\n// account for its probability of appearing in the collected\n// data. heapz profiles are a sampling of the memory allocations\n// requests in a program. We estimate the unsampled value by dividing\n// each collected sample by its probability of appearing in the\n// profile. heapz v2 profiles rely on a poisson process to determine\n// which samples to collect, based on the desired average collection\n// rate R. The probability of a sample of size S to appear in that\n// profile is 1-exp(-S/R).\nfunc scaleHeapSample(count, size, rate int64) (int64, int64) {\n\tif count == 0 || size == 0 {\n\t\treturn 0, 0\n\t}\n\n\tif rate <= 1 {\n\t\t// if rate==1 all samples were collected so no adjustment is needed.\n\t\t// if rate<1 treat as unknown and skip scaling.\n\t\treturn count, size\n\t}\n\n\tavgSize := float64(size) / float64(count)\n\tscale := 1 / (1 - math.Exp(-avgSize/float64(rate)))\n\n\treturn int64(float64(count) * scale), int64(float64(size) * scale)\n}\n\n// parseContention parses a mutex or contention profile. There are 2 cases:\n// \"--- contentionz \" for legacy C++ profiles (and backwards compatibility)\n// \"--- mutex:\" or \"--- contention:\" for profiles generated by the Go runtime.\nfunc parseContention(b []byte) (*Profile, error) {\n\ts := bufio.NewScanner(bytes.NewBuffer(b))\n\tif !s.Scan() {\n\t\tif err := s.Err(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn nil, errUnrecognized\n\t}\n\n\tswitch l := s.Text(); {\n\tcase strings.HasPrefix(l, \"--- contentionz \"):\n\tcase strings.HasPrefix(l, \"--- mutex:\"):\n\tcase strings.HasPrefix(l, \"--- contention:\"):\n\tdefault:\n\t\treturn nil, errUnrecognized\n\t}\n\n\tp := &Profile{\n\t\tPeriodType: &ValueType{Type: \"contentions\", Unit: \"count\"},\n\t\tPeriod:     1,\n\t\tSampleType: []*ValueType{\n\t\t\t{Type: \"contentions\", Unit: \"count\"},\n\t\t\t{Type: \"delay\", Unit: \"nanoseconds\"},\n\t\t},\n\t}\n\n\tvar cpuHz int64\n\t// Parse text of the form \"attribute = value\" before the samples.\n\tconst delimiter = \"=\"\n\tfor s.Scan() {\n\t\tline := s.Text()\n\t\tif line = strings.TrimSpace(line); isSpaceOrComment(line) {\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(line, \"---\") {\n\t\t\tbreak\n\t\t}\n\t\tattr := strings.SplitN(line, delimiter, 2)\n\t\tif len(attr) != 2 {\n\t\t\tbreak\n\t\t}\n\t\tkey, val := strings.TrimSpace(attr[0]), strings.TrimSpace(attr[1])\n\t\tvar err error\n\t\tswitch key {\n\t\tcase \"cycles/second\":\n\t\t\tif cpuHz, err = strconv.ParseInt(val, 0, 64); err != nil {\n\t\t\t\treturn nil, errUnrecognized\n\t\t\t}\n\t\tcase \"sampling period\":\n\t\t\tif p.Period, err = strconv.ParseInt(val, 0, 64); err != nil {\n\t\t\t\treturn nil, errUnrecognized\n\t\t\t}\n\t\tcase \"ms since reset\":\n\t\t\tms, err := strconv.ParseInt(val, 0, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, errUnrecognized\n\t\t\t}\n\t\t\tp.DurationNanos = ms * 1000 * 1000\n\t\tcase \"format\":\n\t\t\t// CPP contentionz profiles don't have format.\n\t\t\treturn nil, errUnrecognized\n\t\tcase \"resolution\":\n\t\t\t// CPP contentionz profiles don't have resolution.\n\t\t\treturn nil, errUnrecognized\n\t\tcase \"discarded samples\":\n\t\tdefault:\n\t\t\treturn nil, errUnrecognized\n\t\t}\n\t}\n\tif err := s.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocs := make(map[uint64]*Location)\n\tfor {\n\t\tline := strings.TrimSpace(s.Text())\n\t\tif strings.HasPrefix(line, \"---\") {\n\t\t\tbreak\n\t\t}\n\t\tif !isSpaceOrComment(line) {\n\t\t\tvalue, addrs, err := parseContentionSample(line, p.Period, cpuHz)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tvar sloc []*Location\n\t\t\tfor _, addr := range addrs {\n\t\t\t\t// Addresses from stack traces point to the next instruction after\n\t\t\t\t// each call. Adjust by -1 to land somewhere on the actual call.\n\t\t\t\taddr--\n\t\t\t\tloc := locs[addr]\n\t\t\t\tif locs[addr] == nil {\n\t\t\t\t\tloc = &Location{\n\t\t\t\t\t\tAddress: addr,\n\t\t\t\t\t}\n\t\t\t\t\tp.Location = append(p.Location, loc)\n\t\t\t\t\tlocs[addr] = loc\n\t\t\t\t}\n\t\t\t\tsloc = append(sloc, loc)\n\t\t\t}\n\t\t\tp.Sample = append(p.Sample, &Sample{\n\t\t\t\tValue:    value,\n\t\t\t\tLocation: sloc,\n\t\t\t})\n\t\t}\n\t\tif !s.Scan() {\n\t\t\tbreak\n\t\t}\n\t}\n\tif err := s.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := parseAdditionalSections(s, p); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn p, nil\n}\n\n// parseContentionSample parses a single row from a contention profile\n// into a new Sample.\nfunc parseContentionSample(line string, period, cpuHz int64) (value []int64, addrs []uint64, err error) {\n\tsampleData := contentionSampleRE.FindStringSubmatch(line)\n\tif sampleData == nil {\n\t\treturn nil, nil, errUnrecognized\n\t}\n\n\tv1, err := strconv.ParseInt(sampleData[1], 10, 64)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"malformed sample: %s: %v\", line, err)\n\t}\n\tv2, err := strconv.ParseInt(sampleData[2], 10, 64)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"malformed sample: %s: %v\", line, err)\n\t}\n\n\t// Unsample values if period and cpuHz are available.\n\t// - Delays are scaled to cycles and then to nanoseconds.\n\t// - Contentions are scaled to cycles.\n\tif period > 0 {\n\t\tif cpuHz > 0 {\n\t\t\tcpuGHz := float64(cpuHz) / 1e9\n\t\t\tv1 = int64(float64(v1) * float64(period) / cpuGHz)\n\t\t}\n\t\tv2 = v2 * period\n\t}\n\n\tvalue = []int64{v2, v1}\n\taddrs, err = parseHexAddresses(sampleData[3])\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"malformed sample: %s: %v\", line, err)\n\t}\n\n\treturn value, addrs, nil\n}\n\n// parseThread parses a Threadz profile and returns a new Profile.\nfunc parseThread(b []byte) (*Profile, error) {\n\ts := bufio.NewScanner(bytes.NewBuffer(b))\n\t// Skip past comments and empty lines seeking a real header.\n\tfor s.Scan() && isSpaceOrComment(s.Text()) {\n\t}\n\n\tline := s.Text()\n\tif m := threadzStartRE.FindStringSubmatch(line); m != nil {\n\t\t// Advance over initial comments until first stack trace.\n\t\tfor s.Scan() {\n\t\t\tif line = s.Text(); isMemoryMapSentinel(line) || strings.HasPrefix(line, \"-\") {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t} else if t := threadStartRE.FindStringSubmatch(line); len(t) != 4 {\n\t\treturn nil, errUnrecognized\n\t}\n\n\tp := &Profile{\n\t\tSampleType: []*ValueType{{Type: \"thread\", Unit: \"count\"}},\n\t\tPeriodType: &ValueType{Type: \"thread\", Unit: \"count\"},\n\t\tPeriod:     1,\n\t}\n\n\tlocs := make(map[uint64]*Location)\n\t// Recognize each thread and populate profile samples.\n\tfor !isMemoryMapSentinel(line) {\n\t\tif strings.HasPrefix(line, \"---- no stack trace for\") {\n\t\t\tbreak\n\t\t}\n\t\tif t := threadStartRE.FindStringSubmatch(line); len(t) != 4 {\n\t\t\treturn nil, errUnrecognized\n\t\t}\n\n\t\tvar addrs []uint64\n\t\tvar err error\n\t\tline, addrs, err = parseThreadSample(s)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif len(addrs) == 0 {\n\t\t\t// We got a --same as previous threads--. Bump counters.\n\t\t\tif len(p.Sample) > 0 {\n\t\t\t\ts := p.Sample[len(p.Sample)-1]\n\t\t\t\ts.Value[0]++\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tvar sloc []*Location\n\t\tfor i, addr := range addrs {\n\t\t\t// Addresses from stack traces point to the next instruction after\n\t\t\t// each call. Adjust by -1 to land somewhere on the actual call\n\t\t\t// (except for the leaf, which is not a call).\n\t\t\tif i > 0 {\n\t\t\t\taddr--\n\t\t\t}\n\t\t\tloc := locs[addr]\n\t\t\tif locs[addr] == nil {\n\t\t\t\tloc = &Location{\n\t\t\t\t\tAddress: addr,\n\t\t\t\t}\n\t\t\t\tp.Location = append(p.Location, loc)\n\t\t\t\tlocs[addr] = loc\n\t\t\t}\n\t\t\tsloc = append(sloc, loc)\n\t\t}\n\n\t\tp.Sample = append(p.Sample, &Sample{\n\t\t\tValue:    []int64{1},\n\t\t\tLocation: sloc,\n\t\t})\n\t}\n\n\tif err := parseAdditionalSections(s, p); err != nil {\n\t\treturn nil, err\n\t}\n\n\tcleanupDuplicateLocations(p)\n\treturn p, nil\n}\n\n// parseThreadSample parses a symbolized or unsymbolized stack trace.\n// Returns the first line after the traceback, the sample (or nil if\n// it hits a 'same-as-previous' marker) and an error.\nfunc parseThreadSample(s *bufio.Scanner) (nextl string, addrs []uint64, err error) {\n\tvar line string\n\tsameAsPrevious := false\n\tfor s.Scan() {\n\t\tline = strings.TrimSpace(s.Text())\n\t\tif line == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tif strings.HasPrefix(line, \"---\") {\n\t\t\tbreak\n\t\t}\n\t\tif strings.Contains(line, \"same as previous thread\") {\n\t\t\tsameAsPrevious = true\n\t\t\tcontinue\n\t\t}\n\n\t\tcurAddrs, err := parseHexAddresses(line)\n\t\tif err != nil {\n\t\t\treturn \"\", nil, fmt.Errorf(\"malformed sample: %s: %v\", line, err)\n\t\t}\n\t\taddrs = append(addrs, curAddrs...)\n\t}\n\tif err := s.Err(); err != nil {\n\t\treturn \"\", nil, err\n\t}\n\tif sameAsPrevious {\n\t\treturn line, nil, nil\n\t}\n\treturn line, addrs, nil\n}\n\n// parseAdditionalSections parses any additional sections in the\n// profile, ignoring any unrecognized sections.\nfunc parseAdditionalSections(s *bufio.Scanner, p *Profile) error {\n\tfor !isMemoryMapSentinel(s.Text()) && s.Scan() {\n\t}\n\tif err := s.Err(); err != nil {\n\t\treturn err\n\t}\n\treturn p.ParseMemoryMapFromScanner(s)\n}\n\n// ParseProcMaps parses a memory map in the format of /proc/self/maps.\n// ParseMemoryMap should be called after setting on a profile to\n// associate locations to the corresponding mapping based on their\n// address.\nfunc ParseProcMaps(rd io.Reader) ([]*Mapping, error) {\n\ts := bufio.NewScanner(rd)\n\treturn parseProcMapsFromScanner(s)\n}\n\nfunc parseProcMapsFromScanner(s *bufio.Scanner) ([]*Mapping, error) {\n\tvar mapping []*Mapping\n\n\tvar attrs []string\n\tconst delimiter = \"=\"\n\tr := strings.NewReplacer()\n\tfor s.Scan() {\n\t\tline := r.Replace(removeLoggingInfo(s.Text()))\n\t\tm, err := parseMappingEntry(line)\n\t\tif err != nil {\n\t\t\tif err == errUnrecognized {\n\t\t\t\t// Recognize assignments of the form: attr=value, and replace\n\t\t\t\t// $attr with value on subsequent mappings.\n\t\t\t\tif attr := strings.SplitN(line, delimiter, 2); len(attr) == 2 {\n\t\t\t\t\tattrs = append(attrs, \"$\"+strings.TrimSpace(attr[0]), strings.TrimSpace(attr[1]))\n\t\t\t\t\tr = strings.NewReplacer(attrs...)\n\t\t\t\t}\n\t\t\t\t// Ignore any unrecognized entries\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn nil, err\n\t\t}\n\t\tif m == nil {\n\t\t\tcontinue\n\t\t}\n\t\tmapping = append(mapping, m)\n\t}\n\tif err := s.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn mapping, nil\n}\n\n// removeLoggingInfo detects and removes log prefix entries generated\n// by the glog package. If no logging prefix is detected, the string\n// is returned unmodified.\nfunc removeLoggingInfo(line string) string {\n\tif match := logInfoRE.FindStringIndex(line); match != nil {\n\t\treturn line[match[1]:]\n\t}\n\treturn line\n}\n\n// ParseMemoryMap parses a memory map in the format of\n// /proc/self/maps, and overrides the mappings in the current profile.\n// It renumbers the samples and locations in the profile correspondingly.\nfunc (p *Profile) ParseMemoryMap(rd io.Reader) error {\n\treturn p.ParseMemoryMapFromScanner(bufio.NewScanner(rd))\n}\n\n// ParseMemoryMapFromScanner parses a memory map in the format of\n// /proc/self/maps or a variety of legacy format, and overrides the\n// mappings in the current profile.  It renumbers the samples and\n// locations in the profile correspondingly.\nfunc (p *Profile) ParseMemoryMapFromScanner(s *bufio.Scanner) error {\n\tmapping, err := parseProcMapsFromScanner(s)\n\tif err != nil {\n\t\treturn err\n\t}\n\tp.Mapping = append(p.Mapping, mapping...)\n\tp.massageMappings()\n\tp.remapLocationIDs()\n\tp.remapFunctionIDs()\n\tp.remapMappingIDs()\n\treturn nil\n}\n\nfunc parseMappingEntry(l string) (*Mapping, error) {\n\tvar start, end, perm, file, offset, buildID string\n\tif me := procMapsRE.FindStringSubmatch(l); len(me) == 6 {\n\t\tstart, end, perm, offset, file = me[1], me[2], me[3], me[4], me[5]\n\t} else if me := briefMapsRE.FindStringSubmatch(l); len(me) == 7 {\n\t\tstart, end, perm, file, offset, buildID = me[1], me[2], me[3], me[4], me[5], me[6]\n\t} else {\n\t\treturn nil, errUnrecognized\n\t}\n\n\tvar err error\n\tmapping := &Mapping{\n\t\tFile:    file,\n\t\tBuildID: buildID,\n\t}\n\tif perm != \"\" && !strings.Contains(perm, \"x\") {\n\t\t// Skip non-executable entries.\n\t\treturn nil, nil\n\t}\n\tif mapping.Start, err = strconv.ParseUint(start, 16, 64); err != nil {\n\t\treturn nil, errUnrecognized\n\t}\n\tif mapping.Limit, err = strconv.ParseUint(end, 16, 64); err != nil {\n\t\treturn nil, errUnrecognized\n\t}\n\tif offset != \"\" {\n\t\tif mapping.Offset, err = strconv.ParseUint(offset, 16, 64); err != nil {\n\t\t\treturn nil, errUnrecognized\n\t\t}\n\t}\n\treturn mapping, nil\n}\n\nvar memoryMapSentinels = []string{\n\t\"--- Memory map: ---\",\n\t\"MAPPED_LIBRARIES:\",\n}\n\n// isMemoryMapSentinel returns true if the string contains one of the\n// known sentinels for memory map information.\nfunc isMemoryMapSentinel(line string) bool {\n\tfor _, s := range memoryMapSentinels {\n\t\tif strings.Contains(line, s) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (p *Profile) addLegacyFrameInfo() {\n\tswitch {\n\tcase isProfileType(p, heapzSampleTypes):\n\t\tp.DropFrames, p.KeepFrames = allocRxStr, allocSkipRxStr\n\tcase isProfileType(p, contentionzSampleTypes):\n\t\tp.DropFrames, p.KeepFrames = lockRxStr, \"\"\n\tdefault:\n\t\tp.DropFrames, p.KeepFrames = cpuProfilerRxStr, \"\"\n\t}\n}\n\nvar heapzSampleTypes = [][]string{\n\t{\"allocations\", \"size\"}, // early Go pprof profiles\n\t{\"objects\", \"space\"},\n\t{\"inuse_objects\", \"inuse_space\"},\n\t{\"alloc_objects\", \"alloc_space\"},\n\t{\"alloc_objects\", \"alloc_space\", \"inuse_objects\", \"inuse_space\"}, // Go pprof legacy profiles\n}\nvar contentionzSampleTypes = [][]string{\n\t{\"contentions\", \"delay\"},\n}\n\nfunc isProfileType(p *Profile, types [][]string) bool {\n\tst := p.SampleType\nnextType:\n\tfor _, t := range types {\n\t\tif len(st) != len(t) {\n\t\t\tcontinue\n\t\t}\n\n\t\tfor i := range st {\n\t\t\tif st[i].Type != t[i] {\n\t\t\t\tcontinue nextType\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\treturn false\n}\n\nvar allocRxStr = strings.Join([]string{\n\t// POSIX entry points.\n\t`calloc`,\n\t`cfree`,\n\t`malloc`,\n\t`free`,\n\t`memalign`,\n\t`do_memalign`,\n\t`(__)?posix_memalign`,\n\t`pvalloc`,\n\t`valloc`,\n\t`realloc`,\n\n\t// TC malloc.\n\t`tcmalloc::.*`,\n\t`tc_calloc`,\n\t`tc_cfree`,\n\t`tc_malloc`,\n\t`tc_free`,\n\t`tc_memalign`,\n\t`tc_posix_memalign`,\n\t`tc_pvalloc`,\n\t`tc_valloc`,\n\t`tc_realloc`,\n\t`tc_new`,\n\t`tc_delete`,\n\t`tc_newarray`,\n\t`tc_deletearray`,\n\t`tc_new_nothrow`,\n\t`tc_newarray_nothrow`,\n\n\t// Memory-allocation routines on OS X.\n\t`malloc_zone_malloc`,\n\t`malloc_zone_calloc`,\n\t`malloc_zone_valloc`,\n\t`malloc_zone_realloc`,\n\t`malloc_zone_memalign`,\n\t`malloc_zone_free`,\n\n\t// Go runtime\n\t`runtime\\..*`,\n\n\t// Other misc. memory allocation routines\n\t`BaseArena::.*`,\n\t`(::)?do_malloc_no_errno`,\n\t`(::)?do_malloc_pages`,\n\t`(::)?do_malloc`,\n\t`DoSampledAllocation`,\n\t`MallocedMemBlock::MallocedMemBlock`,\n\t`_M_allocate`,\n\t`__builtin_(vec_)?delete`,\n\t`__builtin_(vec_)?new`,\n\t`__gnu_cxx::new_allocator::allocate`,\n\t`__libc_malloc`,\n\t`__malloc_alloc_template::allocate`,\n\t`allocate`,\n\t`cpp_alloc`,\n\t`operator new(\\[\\])?`,\n\t`simple_alloc::allocate`,\n}, `|`)\n\nvar allocSkipRxStr = strings.Join([]string{\n\t// Preserve Go runtime frames that appear in the middle/bottom of\n\t// the stack.\n\t`runtime\\.panic`,\n\t`runtime\\.reflectcall`,\n\t`runtime\\.call[0-9]*`,\n}, `|`)\n\nvar cpuProfilerRxStr = strings.Join([]string{\n\t`ProfileData::Add`,\n\t`ProfileData::prof_handler`,\n\t`CpuProfiler::prof_handler`,\n\t`__pthread_sighandler`,\n\t`__restore`,\n}, `|`)\n\nvar lockRxStr = strings.Join([]string{\n\t`RecordLockProfileData`,\n\t`(base::)?RecordLockProfileData.*`,\n\t`(base::)?SubmitMutexProfileData.*`,\n\t`(base::)?SubmitSpinLockProfileData.*`,\n\t`(base::Mutex::)?AwaitCommon.*`,\n\t`(base::Mutex::)?Unlock.*`,\n\t`(base::Mutex::)?UnlockSlow.*`,\n\t`(base::Mutex::)?ReaderUnlock.*`,\n\t`(base::MutexLock::)?~MutexLock.*`,\n\t`(Mutex::)?AwaitCommon.*`,\n\t`(Mutex::)?Unlock.*`,\n\t`(Mutex::)?UnlockSlow.*`,\n\t`(Mutex::)?ReaderUnlock.*`,\n\t`(MutexLock::)?~MutexLock.*`,\n\t`(SpinLock::)?Unlock.*`,\n\t`(SpinLock::)?SlowUnlock.*`,\n\t`(SpinLockHolder::)?~SpinLockHolder.*`,\n}, `|`)\n"
  },
  {
    "path": "vendor/github.com/google/pprof/profile/merge.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage profile\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Compact performs garbage collection on a profile to remove any\n// unreferenced fields. This is useful to reduce the size of a profile\n// after samples or locations have been removed.\nfunc (p *Profile) Compact() *Profile {\n\tp, _ = Merge([]*Profile{p})\n\treturn p\n}\n\n// Merge merges all the profiles in profs into a single Profile.\n// Returns a new profile independent of the input profiles. The merged\n// profile is compacted to eliminate unused samples, locations,\n// functions and mappings. Profiles must have identical profile sample\n// and period types or the merge will fail. profile.Period of the\n// resulting profile will be the maximum of all profiles, and\n// profile.TimeNanos will be the earliest nonzero one. Merges are\n// associative with the caveat of the first profile having some\n// specialization in how headers are combined. There may be other\n// subtleties now or in the future regarding associativity.\nfunc Merge(srcs []*Profile) (*Profile, error) {\n\tif len(srcs) == 0 {\n\t\treturn nil, fmt.Errorf(\"no profiles to merge\")\n\t}\n\tp, err := combineHeaders(srcs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tpm := &profileMerger{\n\t\tp:         p,\n\t\tsamples:   make(map[sampleKey]*Sample, len(srcs[0].Sample)),\n\t\tlocations: make(map[locationKey]*Location, len(srcs[0].Location)),\n\t\tfunctions: make(map[functionKey]*Function, len(srcs[0].Function)),\n\t\tmappings:  make(map[mappingKey]*Mapping, len(srcs[0].Mapping)),\n\t}\n\n\tfor _, src := range srcs {\n\t\t// Clear the profile-specific hash tables\n\t\tpm.locationsByID = makeLocationIDMap(len(src.Location))\n\t\tpm.functionsByID = make(map[uint64]*Function, len(src.Function))\n\t\tpm.mappingsByID = make(map[uint64]mapInfo, len(src.Mapping))\n\n\t\tif len(pm.mappings) == 0 && len(src.Mapping) > 0 {\n\t\t\t// The Mapping list has the property that the first mapping\n\t\t\t// represents the main binary. Take the first Mapping we see,\n\t\t\t// otherwise the operations below will add mappings in an\n\t\t\t// arbitrary order.\n\t\t\tpm.mapMapping(src.Mapping[0])\n\t\t}\n\n\t\tfor _, s := range src.Sample {\n\t\t\tif !isZeroSample(s) {\n\t\t\t\tpm.mapSample(s)\n\t\t\t}\n\t\t}\n\t}\n\n\tfor _, s := range p.Sample {\n\t\tif isZeroSample(s) {\n\t\t\t// If there are any zero samples, re-merge the profile to GC\n\t\t\t// them.\n\t\t\treturn Merge([]*Profile{p})\n\t\t}\n\t}\n\n\treturn p, nil\n}\n\n// Normalize normalizes the source profile by multiplying each value in profile by the\n// ratio of the sum of the base profile's values of that sample type to the sum of the\n// source profile's value of that sample type.\nfunc (p *Profile) Normalize(pb *Profile) error {\n\n\tif err := p.compatible(pb); err != nil {\n\t\treturn err\n\t}\n\n\tbaseVals := make([]int64, len(p.SampleType))\n\tfor _, s := range pb.Sample {\n\t\tfor i, v := range s.Value {\n\t\t\tbaseVals[i] += v\n\t\t}\n\t}\n\n\tsrcVals := make([]int64, len(p.SampleType))\n\tfor _, s := range p.Sample {\n\t\tfor i, v := range s.Value {\n\t\t\tsrcVals[i] += v\n\t\t}\n\t}\n\n\tnormScale := make([]float64, len(baseVals))\n\tfor i := range baseVals {\n\t\tif srcVals[i] == 0 {\n\t\t\tnormScale[i] = 0.0\n\t\t} else {\n\t\t\tnormScale[i] = float64(baseVals[i]) / float64(srcVals[i])\n\t\t}\n\t}\n\tp.ScaleN(normScale)\n\treturn nil\n}\n\nfunc isZeroSample(s *Sample) bool {\n\tfor _, v := range s.Value {\n\t\tif v != 0 {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\ntype profileMerger struct {\n\tp *Profile\n\n\t// Memoization tables within a profile.\n\tlocationsByID locationIDMap\n\tfunctionsByID map[uint64]*Function\n\tmappingsByID  map[uint64]mapInfo\n\n\t// Memoization tables for profile entities.\n\tsamples   map[sampleKey]*Sample\n\tlocations map[locationKey]*Location\n\tfunctions map[functionKey]*Function\n\tmappings  map[mappingKey]*Mapping\n}\n\ntype mapInfo struct {\n\tm      *Mapping\n\toffset int64\n}\n\nfunc (pm *profileMerger) mapSample(src *Sample) *Sample {\n\t// Check memoization table\n\tk := pm.sampleKey(src)\n\tif ss, ok := pm.samples[k]; ok {\n\t\tfor i, v := range src.Value {\n\t\t\tss.Value[i] += v\n\t\t}\n\t\treturn ss\n\t}\n\n\t// Make new sample.\n\ts := &Sample{\n\t\tLocation: make([]*Location, len(src.Location)),\n\t\tValue:    make([]int64, len(src.Value)),\n\t\tLabel:    make(map[string][]string, len(src.Label)),\n\t\tNumLabel: make(map[string][]int64, len(src.NumLabel)),\n\t\tNumUnit:  make(map[string][]string, len(src.NumLabel)),\n\t}\n\tfor i, l := range src.Location {\n\t\ts.Location[i] = pm.mapLocation(l)\n\t}\n\tfor k, v := range src.Label {\n\t\tvv := make([]string, len(v))\n\t\tcopy(vv, v)\n\t\ts.Label[k] = vv\n\t}\n\tfor k, v := range src.NumLabel {\n\t\tu := src.NumUnit[k]\n\t\tvv := make([]int64, len(v))\n\t\tuu := make([]string, len(u))\n\t\tcopy(vv, v)\n\t\tcopy(uu, u)\n\t\ts.NumLabel[k] = vv\n\t\ts.NumUnit[k] = uu\n\t}\n\tcopy(s.Value, src.Value)\n\tpm.samples[k] = s\n\tpm.p.Sample = append(pm.p.Sample, s)\n\treturn s\n}\n\nfunc (pm *profileMerger) sampleKey(sample *Sample) sampleKey {\n\t// Accumulate contents into a string.\n\tvar buf strings.Builder\n\tbuf.Grow(64) // Heuristic to avoid extra allocs\n\n\t// encode a number\n\tputNumber := func(v uint64) {\n\t\tvar num [binary.MaxVarintLen64]byte\n\t\tn := binary.PutUvarint(num[:], v)\n\t\tbuf.Write(num[:n])\n\t}\n\n\t// encode a string prefixed with its length.\n\tputDelimitedString := func(s string) {\n\t\tputNumber(uint64(len(s)))\n\t\tbuf.WriteString(s)\n\t}\n\n\tfor _, l := range sample.Location {\n\t\t// Get the location in the merged profile, which may have a different ID.\n\t\tif loc := pm.mapLocation(l); loc != nil {\n\t\t\tputNumber(loc.ID)\n\t\t}\n\t}\n\tputNumber(0) // Delimiter\n\n\tfor _, l := range sortedKeys1(sample.Label) {\n\t\tputDelimitedString(l)\n\t\tvalues := sample.Label[l]\n\t\tputNumber(uint64(len(values)))\n\t\tfor _, v := range values {\n\t\t\tputDelimitedString(v)\n\t\t}\n\t}\n\n\tfor _, l := range sortedKeys2(sample.NumLabel) {\n\t\tputDelimitedString(l)\n\t\tvalues := sample.NumLabel[l]\n\t\tputNumber(uint64(len(values)))\n\t\tfor _, v := range values {\n\t\t\tputNumber(uint64(v))\n\t\t}\n\t\tunits := sample.NumUnit[l]\n\t\tputNumber(uint64(len(units)))\n\t\tfor _, v := range units {\n\t\t\tputDelimitedString(v)\n\t\t}\n\t}\n\n\treturn sampleKey(buf.String())\n}\n\ntype sampleKey string\n\n// sortedKeys1 returns the sorted keys found in a string->[]string map.\n//\n// Note: this is currently non-generic since github pprof runs golint,\n// which does not support generics. When that issue is fixed, it can\n// be merged with sortedKeys2 and made into a generic function.\nfunc sortedKeys1(m map[string][]string) []string {\n\tif len(m) == 0 {\n\t\treturn nil\n\t}\n\tkeys := make([]string, 0, len(m))\n\tfor k := range m {\n\t\tkeys = append(keys, k)\n\t}\n\tsort.Strings(keys)\n\treturn keys\n}\n\n// sortedKeys2 returns the sorted keys found in a string->[]int64 map.\n//\n// Note: this is currently non-generic since github pprof runs golint,\n// which does not support generics. When that issue is fixed, it can\n// be merged with sortedKeys1 and made into a generic function.\nfunc sortedKeys2(m map[string][]int64) []string {\n\tif len(m) == 0 {\n\t\treturn nil\n\t}\n\tkeys := make([]string, 0, len(m))\n\tfor k := range m {\n\t\tkeys = append(keys, k)\n\t}\n\tsort.Strings(keys)\n\treturn keys\n}\n\nfunc (pm *profileMerger) mapLocation(src *Location) *Location {\n\tif src == nil {\n\t\treturn nil\n\t}\n\n\tif l := pm.locationsByID.get(src.ID); l != nil {\n\t\treturn l\n\t}\n\n\tmi := pm.mapMapping(src.Mapping)\n\tl := &Location{\n\t\tID:       uint64(len(pm.p.Location) + 1),\n\t\tMapping:  mi.m,\n\t\tAddress:  uint64(int64(src.Address) + mi.offset),\n\t\tLine:     make([]Line, len(src.Line)),\n\t\tIsFolded: src.IsFolded,\n\t}\n\tfor i, ln := range src.Line {\n\t\tl.Line[i] = pm.mapLine(ln)\n\t}\n\t// Check memoization table. Must be done on the remapped location to\n\t// account for the remapped mapping ID.\n\tk := l.key()\n\tif ll, ok := pm.locations[k]; ok {\n\t\tpm.locationsByID.set(src.ID, ll)\n\t\treturn ll\n\t}\n\tpm.locationsByID.set(src.ID, l)\n\tpm.locations[k] = l\n\tpm.p.Location = append(pm.p.Location, l)\n\treturn l\n}\n\n// key generates locationKey to be used as a key for maps.\nfunc (l *Location) key() locationKey {\n\tkey := locationKey{\n\t\taddr:     l.Address,\n\t\tisFolded: l.IsFolded,\n\t}\n\tif l.Mapping != nil {\n\t\t// Normalizes address to handle address space randomization.\n\t\tkey.addr -= l.Mapping.Start\n\t\tkey.mappingID = l.Mapping.ID\n\t}\n\tlines := make([]string, len(l.Line)*3)\n\tfor i, line := range l.Line {\n\t\tif line.Function != nil {\n\t\t\tlines[i*2] = strconv.FormatUint(line.Function.ID, 16)\n\t\t}\n\t\tlines[i*2+1] = strconv.FormatInt(line.Line, 16)\n\t\tlines[i*2+2] = strconv.FormatInt(line.Column, 16)\n\t}\n\tkey.lines = strings.Join(lines, \"|\")\n\treturn key\n}\n\ntype locationKey struct {\n\taddr, mappingID uint64\n\tlines           string\n\tisFolded        bool\n}\n\nfunc (pm *profileMerger) mapMapping(src *Mapping) mapInfo {\n\tif src == nil {\n\t\treturn mapInfo{}\n\t}\n\n\tif mi, ok := pm.mappingsByID[src.ID]; ok {\n\t\treturn mi\n\t}\n\n\t// Check memoization tables.\n\tmk := src.key()\n\tif m, ok := pm.mappings[mk]; ok {\n\t\tmi := mapInfo{m, int64(m.Start) - int64(src.Start)}\n\t\tpm.mappingsByID[src.ID] = mi\n\t\treturn mi\n\t}\n\tm := &Mapping{\n\t\tID:                     uint64(len(pm.p.Mapping) + 1),\n\t\tStart:                  src.Start,\n\t\tLimit:                  src.Limit,\n\t\tOffset:                 src.Offset,\n\t\tFile:                   src.File,\n\t\tKernelRelocationSymbol: src.KernelRelocationSymbol,\n\t\tBuildID:                src.BuildID,\n\t\tHasFunctions:           src.HasFunctions,\n\t\tHasFilenames:           src.HasFilenames,\n\t\tHasLineNumbers:         src.HasLineNumbers,\n\t\tHasInlineFrames:        src.HasInlineFrames,\n\t}\n\tpm.p.Mapping = append(pm.p.Mapping, m)\n\n\t// Update memoization tables.\n\tpm.mappings[mk] = m\n\tmi := mapInfo{m, 0}\n\tpm.mappingsByID[src.ID] = mi\n\treturn mi\n}\n\n// key generates encoded strings of Mapping to be used as a key for\n// maps.\nfunc (m *Mapping) key() mappingKey {\n\t// Normalize addresses to handle address space randomization.\n\t// Round up to next 4K boundary to avoid minor discrepancies.\n\tconst mapsizeRounding = 0x1000\n\n\tsize := m.Limit - m.Start\n\tsize = size + mapsizeRounding - 1\n\tsize = size - (size % mapsizeRounding)\n\tkey := mappingKey{\n\t\tsize:   size,\n\t\toffset: m.Offset,\n\t}\n\n\tswitch {\n\tcase m.BuildID != \"\":\n\t\tkey.buildIDOrFile = m.BuildID\n\tcase m.File != \"\":\n\t\tkey.buildIDOrFile = m.File\n\tdefault:\n\t\t// A mapping containing neither build ID nor file name is a fake mapping. A\n\t\t// key with empty buildIDOrFile is used for fake mappings so that they are\n\t\t// treated as the same mapping during merging.\n\t}\n\treturn key\n}\n\ntype mappingKey struct {\n\tsize, offset  uint64\n\tbuildIDOrFile string\n}\n\nfunc (pm *profileMerger) mapLine(src Line) Line {\n\tln := Line{\n\t\tFunction: pm.mapFunction(src.Function),\n\t\tLine:     src.Line,\n\t\tColumn:   src.Column,\n\t}\n\treturn ln\n}\n\nfunc (pm *profileMerger) mapFunction(src *Function) *Function {\n\tif src == nil {\n\t\treturn nil\n\t}\n\tif f, ok := pm.functionsByID[src.ID]; ok {\n\t\treturn f\n\t}\n\tk := src.key()\n\tif f, ok := pm.functions[k]; ok {\n\t\tpm.functionsByID[src.ID] = f\n\t\treturn f\n\t}\n\tf := &Function{\n\t\tID:         uint64(len(pm.p.Function) + 1),\n\t\tName:       src.Name,\n\t\tSystemName: src.SystemName,\n\t\tFilename:   src.Filename,\n\t\tStartLine:  src.StartLine,\n\t}\n\tpm.functions[k] = f\n\tpm.functionsByID[src.ID] = f\n\tpm.p.Function = append(pm.p.Function, f)\n\treturn f\n}\n\n// key generates a struct to be used as a key for maps.\nfunc (f *Function) key() functionKey {\n\treturn functionKey{\n\t\tf.StartLine,\n\t\tf.Name,\n\t\tf.SystemName,\n\t\tf.Filename,\n\t}\n}\n\ntype functionKey struct {\n\tstartLine                  int64\n\tname, systemName, fileName string\n}\n\n// combineHeaders checks that all profiles can be merged and returns\n// their combined profile.\nfunc combineHeaders(srcs []*Profile) (*Profile, error) {\n\tfor _, s := range srcs[1:] {\n\t\tif err := srcs[0].compatible(s); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tvar timeNanos, durationNanos, period int64\n\tvar comments []string\n\tseenComments := map[string]bool{}\n\tvar docURL string\n\tvar defaultSampleType string\n\tfor _, s := range srcs {\n\t\tif timeNanos == 0 || s.TimeNanos < timeNanos {\n\t\t\ttimeNanos = s.TimeNanos\n\t\t}\n\t\tdurationNanos += s.DurationNanos\n\t\tif period == 0 || period < s.Period {\n\t\t\tperiod = s.Period\n\t\t}\n\t\tfor _, c := range s.Comments {\n\t\t\tif seen := seenComments[c]; !seen {\n\t\t\t\tcomments = append(comments, c)\n\t\t\t\tseenComments[c] = true\n\t\t\t}\n\t\t}\n\t\tif defaultSampleType == \"\" {\n\t\t\tdefaultSampleType = s.DefaultSampleType\n\t\t}\n\t\tif docURL == \"\" {\n\t\t\tdocURL = s.DocURL\n\t\t}\n\t}\n\n\tp := &Profile{\n\t\tSampleType: make([]*ValueType, len(srcs[0].SampleType)),\n\n\t\tDropFrames: srcs[0].DropFrames,\n\t\tKeepFrames: srcs[0].KeepFrames,\n\n\t\tTimeNanos:     timeNanos,\n\t\tDurationNanos: durationNanos,\n\t\tPeriodType:    srcs[0].PeriodType,\n\t\tPeriod:        period,\n\n\t\tComments:          comments,\n\t\tDefaultSampleType: defaultSampleType,\n\t\tDocURL:            docURL,\n\t}\n\tcopy(p.SampleType, srcs[0].SampleType)\n\treturn p, nil\n}\n\n// compatible determines if two profiles can be compared/merged.\n// returns nil if the profiles are compatible; otherwise an error with\n// details on the incompatibility.\nfunc (p *Profile) compatible(pb *Profile) error {\n\tif !equalValueType(p.PeriodType, pb.PeriodType) {\n\t\treturn fmt.Errorf(\"incompatible period types %v and %v\", p.PeriodType, pb.PeriodType)\n\t}\n\n\tif len(p.SampleType) != len(pb.SampleType) {\n\t\treturn fmt.Errorf(\"incompatible sample types %v and %v\", p.SampleType, pb.SampleType)\n\t}\n\n\tfor i := range p.SampleType {\n\t\tif !equalValueType(p.SampleType[i], pb.SampleType[i]) {\n\t\t\treturn fmt.Errorf(\"incompatible sample types %v and %v\", p.SampleType, pb.SampleType)\n\t\t}\n\t}\n\treturn nil\n}\n\n// equalValueType returns true if the two value types are semantically\n// equal. It ignores the internal fields used during encode/decode.\nfunc equalValueType(st1, st2 *ValueType) bool {\n\treturn st1.Type == st2.Type && st1.Unit == st2.Unit\n}\n\n// locationIDMap is like a map[uint64]*Location, but provides efficiency for\n// ids that are densely numbered, which is often the case.\ntype locationIDMap struct {\n\tdense  []*Location          // indexed by id for id < len(dense)\n\tsparse map[uint64]*Location // indexed by id for id >= len(dense)\n}\n\nfunc makeLocationIDMap(n int) locationIDMap {\n\treturn locationIDMap{\n\t\tdense:  make([]*Location, n),\n\t\tsparse: map[uint64]*Location{},\n\t}\n}\n\nfunc (lm locationIDMap) get(id uint64) *Location {\n\tif id < uint64(len(lm.dense)) {\n\t\treturn lm.dense[int(id)]\n\t}\n\treturn lm.sparse[id]\n}\n\nfunc (lm locationIDMap) set(id uint64, loc *Location) {\n\tif id < uint64(len(lm.dense)) {\n\t\tlm.dense[id] = loc\n\t\treturn\n\t}\n\tlm.sparse[id] = loc\n}\n\n// CompatibilizeSampleTypes makes profiles compatible to be compared/merged. It\n// keeps sample types that appear in all profiles only and drops/reorders the\n// sample types as necessary.\n//\n// In the case of sample types order is not the same for given profiles the\n// order is derived from the first profile.\n//\n// Profiles are modified in-place.\n//\n// It returns an error if the sample type's intersection is empty.\nfunc CompatibilizeSampleTypes(ps []*Profile) error {\n\tsTypes := commonSampleTypes(ps)\n\tif len(sTypes) == 0 {\n\t\treturn fmt.Errorf(\"profiles have empty common sample type list\")\n\t}\n\tfor _, p := range ps {\n\t\tif err := compatibilizeSampleTypes(p, sTypes); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// commonSampleTypes returns sample types that appear in all profiles in the\n// order how they ordered in the first profile.\nfunc commonSampleTypes(ps []*Profile) []string {\n\tif len(ps) == 0 {\n\t\treturn nil\n\t}\n\tsTypes := map[string]int{}\n\tfor _, p := range ps {\n\t\tfor _, st := range p.SampleType {\n\t\t\tsTypes[st.Type]++\n\t\t}\n\t}\n\tvar res []string\n\tfor _, st := range ps[0].SampleType {\n\t\tif sTypes[st.Type] == len(ps) {\n\t\t\tres = append(res, st.Type)\n\t\t}\n\t}\n\treturn res\n}\n\n// compatibilizeSampleTypes drops sample types that are not present in sTypes\n// list and reorder them if needed.\n//\n// It sets DefaultSampleType to sType[0] if it is not in sType list.\n//\n// It assumes that all sample types from the sTypes list are present in the\n// given profile otherwise it returns an error.\nfunc compatibilizeSampleTypes(p *Profile, sTypes []string) error {\n\tif len(sTypes) == 0 {\n\t\treturn fmt.Errorf(\"sample type list is empty\")\n\t}\n\tdefaultSampleType := sTypes[0]\n\treMap, needToModify := make([]int, len(sTypes)), false\n\tfor i, st := range sTypes {\n\t\tif st == p.DefaultSampleType {\n\t\t\tdefaultSampleType = p.DefaultSampleType\n\t\t}\n\t\tidx := searchValueType(p.SampleType, st)\n\t\tif idx < 0 {\n\t\t\treturn fmt.Errorf(\"%q sample type is not found in profile\", st)\n\t\t}\n\t\treMap[i] = idx\n\t\tif idx != i {\n\t\t\tneedToModify = true\n\t\t}\n\t}\n\tif !needToModify && len(sTypes) == len(p.SampleType) {\n\t\treturn nil\n\t}\n\tp.DefaultSampleType = defaultSampleType\n\toldSampleTypes := p.SampleType\n\tp.SampleType = make([]*ValueType, len(sTypes))\n\tfor i, idx := range reMap {\n\t\tp.SampleType[i] = oldSampleTypes[idx]\n\t}\n\tvalues := make([]int64, len(sTypes))\n\tfor _, s := range p.Sample {\n\t\tfor i, idx := range reMap {\n\t\t\tvalues[i] = s.Value[idx]\n\t\t}\n\t\ts.Value = s.Value[:len(values)]\n\t\tcopy(s.Value, values)\n\t}\n\treturn nil\n}\n\nfunc searchValueType(vts []*ValueType, s string) int {\n\tfor i, vt := range vts {\n\t\tif vt.Type == s {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn -1\n}\n"
  },
  {
    "path": "vendor/github.com/google/pprof/profile/profile.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Package profile provides a representation of profile.proto and\n// methods to encode/decode profiles in this format.\npackage profile\n\nimport (\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\n// Profile is an in-memory representation of profile.proto.\ntype Profile struct {\n\tSampleType        []*ValueType\n\tDefaultSampleType string\n\tSample            []*Sample\n\tMapping           []*Mapping\n\tLocation          []*Location\n\tFunction          []*Function\n\tComments          []string\n\tDocURL            string\n\n\tDropFrames string\n\tKeepFrames string\n\n\tTimeNanos     int64\n\tDurationNanos int64\n\tPeriodType    *ValueType\n\tPeriod        int64\n\n\t// The following fields are modified during encoding and copying,\n\t// so are protected by a Mutex.\n\tencodeMu sync.Mutex\n\n\tcommentX           []int64\n\tdocURLX            int64\n\tdropFramesX        int64\n\tkeepFramesX        int64\n\tstringTable        []string\n\tdefaultSampleTypeX int64\n}\n\n// ValueType corresponds to Profile.ValueType\ntype ValueType struct {\n\tType string // cpu, wall, inuse_space, etc\n\tUnit string // seconds, nanoseconds, bytes, etc\n\n\ttypeX int64\n\tunitX int64\n}\n\n// Sample corresponds to Profile.Sample\ntype Sample struct {\n\tLocation []*Location\n\tValue    []int64\n\t// Label is a per-label-key map to values for string labels.\n\t//\n\t// In general, having multiple values for the given label key is strongly\n\t// discouraged - see docs for the sample label field in profile.proto.  The\n\t// main reason this unlikely state is tracked here is to make the\n\t// decoding->encoding roundtrip not lossy. But we expect that the value\n\t// slices present in this map are always of length 1.\n\tLabel map[string][]string\n\t// NumLabel is a per-label-key map to values for numeric labels. See a note\n\t// above on handling multiple values for a label.\n\tNumLabel map[string][]int64\n\t// NumUnit is a per-label-key map to the unit names of corresponding numeric\n\t// label values. The unit info may be missing even if the label is in\n\t// NumLabel, see the docs in profile.proto for details. When the value is\n\t// slice is present and not nil, its length must be equal to the length of\n\t// the corresponding value slice in NumLabel.\n\tNumUnit map[string][]string\n\n\tlocationIDX []uint64\n\tlabelX      []label\n}\n\n// label corresponds to Profile.Label\ntype label struct {\n\tkeyX int64\n\t// Exactly one of the two following values must be set\n\tstrX int64\n\tnumX int64 // Integer value for this label\n\t// can be set if numX has value\n\tunitX int64\n}\n\n// Mapping corresponds to Profile.Mapping\ntype Mapping struct {\n\tID              uint64\n\tStart           uint64\n\tLimit           uint64\n\tOffset          uint64\n\tFile            string\n\tBuildID         string\n\tHasFunctions    bool\n\tHasFilenames    bool\n\tHasLineNumbers  bool\n\tHasInlineFrames bool\n\n\tfileX    int64\n\tbuildIDX int64\n\n\t// Name of the kernel relocation symbol (\"_text\" or \"_stext\"), extracted from File.\n\t// For linux kernel mappings generated by some tools, correct symbolization depends\n\t// on knowing which of the two possible relocation symbols was used for `Start`.\n\t// This is given to us as a suffix in `File` (e.g. \"[kernel.kallsyms]_stext\").\n\t//\n\t// Note, this public field is not persisted in the proto. For the purposes of\n\t// copying / merging / hashing profiles, it is considered subsumed by `File`.\n\tKernelRelocationSymbol string\n}\n\n// Location corresponds to Profile.Location\ntype Location struct {\n\tID       uint64\n\tMapping  *Mapping\n\tAddress  uint64\n\tLine     []Line\n\tIsFolded bool\n\n\tmappingIDX uint64\n}\n\n// Line corresponds to Profile.Line\ntype Line struct {\n\tFunction *Function\n\tLine     int64\n\tColumn   int64\n\n\tfunctionIDX uint64\n}\n\n// Function corresponds to Profile.Function\ntype Function struct {\n\tID         uint64\n\tName       string\n\tSystemName string\n\tFilename   string\n\tStartLine  int64\n\n\tnameX       int64\n\tsystemNameX int64\n\tfilenameX   int64\n}\n\n// Parse parses a profile and checks for its validity. The input\n// may be a gzip-compressed encoded protobuf or one of many legacy\n// profile formats which may be unsupported in the future.\nfunc Parse(r io.Reader) (*Profile, error) {\n\tdata, err := io.ReadAll(r)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ParseData(data)\n}\n\n// ParseData parses a profile from a buffer and checks for its\n// validity.\nfunc ParseData(data []byte) (*Profile, error) {\n\tvar p *Profile\n\tvar err error\n\tif len(data) >= 2 && data[0] == 0x1f && data[1] == 0x8b {\n\t\tgz, err := gzip.NewReader(bytes.NewBuffer(data))\n\t\tif err == nil {\n\t\t\tdata, err = io.ReadAll(gz)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"decompressing profile: %v\", err)\n\t\t}\n\t}\n\tif p, err = ParseUncompressed(data); err != nil && err != errNoData && err != errConcatProfile {\n\t\tp, err = parseLegacy(data)\n\t}\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parsing profile: %v\", err)\n\t}\n\n\tif err := p.CheckValid(); err != nil {\n\t\treturn nil, fmt.Errorf(\"malformed profile: %v\", err)\n\t}\n\treturn p, nil\n}\n\nvar errUnrecognized = fmt.Errorf(\"unrecognized profile format\")\nvar errMalformed = fmt.Errorf(\"malformed profile format\")\nvar errNoData = fmt.Errorf(\"empty input file\")\nvar errConcatProfile = fmt.Errorf(\"concatenated profiles detected\")\n\nfunc parseLegacy(data []byte) (*Profile, error) {\n\tparsers := []func([]byte) (*Profile, error){\n\t\tparseCPU,\n\t\tparseHeap,\n\t\tparseGoCount, // goroutine, threadcreate\n\t\tparseThread,\n\t\tparseContention,\n\t\tparseJavaProfile,\n\t}\n\n\tfor _, parser := range parsers {\n\t\tp, err := parser(data)\n\t\tif err == nil {\n\t\t\tp.addLegacyFrameInfo()\n\t\t\treturn p, nil\n\t\t}\n\t\tif err != errUnrecognized {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn nil, errUnrecognized\n}\n\n// ParseUncompressed parses an uncompressed protobuf into a profile.\nfunc ParseUncompressed(data []byte) (*Profile, error) {\n\tif len(data) == 0 {\n\t\treturn nil, errNoData\n\t}\n\tp := &Profile{}\n\tif err := unmarshal(data, p); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := p.postDecode(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn p, nil\n}\n\nvar libRx = regexp.MustCompile(`([.]so$|[.]so[._][0-9]+)`)\n\n// massageMappings applies heuristic-based changes to the profile\n// mappings to account for quirks of some environments.\nfunc (p *Profile) massageMappings() {\n\t// Merge adjacent regions with matching names, checking that the offsets match\n\tif len(p.Mapping) > 1 {\n\t\tmappings := []*Mapping{p.Mapping[0]}\n\t\tfor _, m := range p.Mapping[1:] {\n\t\t\tlm := mappings[len(mappings)-1]\n\t\t\tif adjacent(lm, m) {\n\t\t\t\tlm.Limit = m.Limit\n\t\t\t\tif m.File != \"\" {\n\t\t\t\t\tlm.File = m.File\n\t\t\t\t}\n\t\t\t\tif m.BuildID != \"\" {\n\t\t\t\t\tlm.BuildID = m.BuildID\n\t\t\t\t}\n\t\t\t\tp.updateLocationMapping(m, lm)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tmappings = append(mappings, m)\n\t\t}\n\t\tp.Mapping = mappings\n\t}\n\n\t// Use heuristics to identify main binary and move it to the top of the list of mappings\n\tfor i, m := range p.Mapping {\n\t\tfile := strings.TrimSpace(strings.Replace(m.File, \"(deleted)\", \"\", -1))\n\t\tif len(file) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tif len(libRx.FindStringSubmatch(file)) > 0 {\n\t\t\tcontinue\n\t\t}\n\t\tif file[0] == '[' {\n\t\t\tcontinue\n\t\t}\n\t\t// Swap what we guess is main to position 0.\n\t\tp.Mapping[0], p.Mapping[i] = p.Mapping[i], p.Mapping[0]\n\t\tbreak\n\t}\n\n\t// Keep the mapping IDs neatly sorted\n\tfor i, m := range p.Mapping {\n\t\tm.ID = uint64(i + 1)\n\t}\n}\n\n// adjacent returns whether two mapping entries represent the same\n// mapping that has been split into two. Check that their addresses are adjacent,\n// and if the offsets match, if they are available.\nfunc adjacent(m1, m2 *Mapping) bool {\n\tif m1.File != \"\" && m2.File != \"\" {\n\t\tif m1.File != m2.File {\n\t\t\treturn false\n\t\t}\n\t}\n\tif m1.BuildID != \"\" && m2.BuildID != \"\" {\n\t\tif m1.BuildID != m2.BuildID {\n\t\t\treturn false\n\t\t}\n\t}\n\tif m1.Limit != m2.Start {\n\t\treturn false\n\t}\n\tif m1.Offset != 0 && m2.Offset != 0 {\n\t\toffset := m1.Offset + (m1.Limit - m1.Start)\n\t\tif offset != m2.Offset {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (p *Profile) updateLocationMapping(from, to *Mapping) {\n\tfor _, l := range p.Location {\n\t\tif l.Mapping == from {\n\t\t\tl.Mapping = to\n\t\t}\n\t}\n}\n\nfunc serialize(p *Profile) []byte {\n\tp.encodeMu.Lock()\n\tp.preEncode()\n\tb := marshal(p)\n\tp.encodeMu.Unlock()\n\treturn b\n}\n\n// Write writes the profile as a gzip-compressed marshaled protobuf.\nfunc (p *Profile) Write(w io.Writer) error {\n\tzw := gzip.NewWriter(w)\n\tdefer zw.Close()\n\t_, err := zw.Write(serialize(p))\n\treturn err\n}\n\n// WriteUncompressed writes the profile as a marshaled protobuf.\nfunc (p *Profile) WriteUncompressed(w io.Writer) error {\n\t_, err := w.Write(serialize(p))\n\treturn err\n}\n\n// CheckValid tests whether the profile is valid. Checks include, but are\n// not limited to:\n//   - len(Profile.Sample[n].value) == len(Profile.value_unit)\n//   - Sample.id has a corresponding Profile.Location\nfunc (p *Profile) CheckValid() error {\n\t// Check that sample values are consistent\n\tsampleLen := len(p.SampleType)\n\tif sampleLen == 0 && len(p.Sample) != 0 {\n\t\treturn fmt.Errorf(\"missing sample type information\")\n\t}\n\tfor _, s := range p.Sample {\n\t\tif s == nil {\n\t\t\treturn fmt.Errorf(\"profile has nil sample\")\n\t\t}\n\t\tif len(s.Value) != sampleLen {\n\t\t\treturn fmt.Errorf(\"mismatch: sample has %d values vs. %d types\", len(s.Value), len(p.SampleType))\n\t\t}\n\t\tfor _, l := range s.Location {\n\t\t\tif l == nil {\n\t\t\t\treturn fmt.Errorf(\"sample has nil location\")\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check that all mappings/locations/functions are in the tables\n\t// Check that there are no duplicate ids\n\tmappings := make(map[uint64]*Mapping, len(p.Mapping))\n\tfor _, m := range p.Mapping {\n\t\tif m == nil {\n\t\t\treturn fmt.Errorf(\"profile has nil mapping\")\n\t\t}\n\t\tif m.ID == 0 {\n\t\t\treturn fmt.Errorf(\"found mapping with reserved ID=0\")\n\t\t}\n\t\tif mappings[m.ID] != nil {\n\t\t\treturn fmt.Errorf(\"multiple mappings with same id: %d\", m.ID)\n\t\t}\n\t\tmappings[m.ID] = m\n\t}\n\tfunctions := make(map[uint64]*Function, len(p.Function))\n\tfor _, f := range p.Function {\n\t\tif f == nil {\n\t\t\treturn fmt.Errorf(\"profile has nil function\")\n\t\t}\n\t\tif f.ID == 0 {\n\t\t\treturn fmt.Errorf(\"found function with reserved ID=0\")\n\t\t}\n\t\tif functions[f.ID] != nil {\n\t\t\treturn fmt.Errorf(\"multiple functions with same id: %d\", f.ID)\n\t\t}\n\t\tfunctions[f.ID] = f\n\t}\n\tlocations := make(map[uint64]*Location, len(p.Location))\n\tfor _, l := range p.Location {\n\t\tif l == nil {\n\t\t\treturn fmt.Errorf(\"profile has nil location\")\n\t\t}\n\t\tif l.ID == 0 {\n\t\t\treturn fmt.Errorf(\"found location with reserved id=0\")\n\t\t}\n\t\tif locations[l.ID] != nil {\n\t\t\treturn fmt.Errorf(\"multiple locations with same id: %d\", l.ID)\n\t\t}\n\t\tlocations[l.ID] = l\n\t\tif m := l.Mapping; m != nil {\n\t\t\tif m.ID == 0 || mappings[m.ID] != m {\n\t\t\t\treturn fmt.Errorf(\"inconsistent mapping %p: %d\", m, m.ID)\n\t\t\t}\n\t\t}\n\t\tfor _, ln := range l.Line {\n\t\t\tf := ln.Function\n\t\t\tif f == nil {\n\t\t\t\treturn fmt.Errorf(\"location id: %d has a line with nil function\", l.ID)\n\t\t\t}\n\t\t\tif f.ID == 0 || functions[f.ID] != f {\n\t\t\t\treturn fmt.Errorf(\"inconsistent function %p: %d\", f, f.ID)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// Aggregate merges the locations in the profile into equivalence\n// classes preserving the request attributes. It also updates the\n// samples to point to the merged locations.\nfunc (p *Profile) Aggregate(inlineFrame, function, filename, linenumber, columnnumber, address bool) error {\n\tfor _, m := range p.Mapping {\n\t\tm.HasInlineFrames = m.HasInlineFrames && inlineFrame\n\t\tm.HasFunctions = m.HasFunctions && function\n\t\tm.HasFilenames = m.HasFilenames && filename\n\t\tm.HasLineNumbers = m.HasLineNumbers && linenumber\n\t}\n\n\t// Aggregate functions\n\tif !function || !filename {\n\t\tfor _, f := range p.Function {\n\t\t\tif !function {\n\t\t\t\tf.Name = \"\"\n\t\t\t\tf.SystemName = \"\"\n\t\t\t}\n\t\t\tif !filename {\n\t\t\t\tf.Filename = \"\"\n\t\t\t}\n\t\t}\n\t}\n\n\t// Aggregate locations\n\tif !inlineFrame || !address || !linenumber || !columnnumber {\n\t\tfor _, l := range p.Location {\n\t\t\tif !inlineFrame && len(l.Line) > 1 {\n\t\t\t\tl.Line = l.Line[len(l.Line)-1:]\n\t\t\t}\n\t\t\tif !linenumber {\n\t\t\t\tfor i := range l.Line {\n\t\t\t\t\tl.Line[i].Line = 0\n\t\t\t\t\tl.Line[i].Column = 0\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !columnnumber {\n\t\t\t\tfor i := range l.Line {\n\t\t\t\t\tl.Line[i].Column = 0\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !address {\n\t\t\t\tl.Address = 0\n\t\t\t}\n\t\t}\n\t}\n\n\treturn p.CheckValid()\n}\n\n// NumLabelUnits returns a map of numeric label keys to the units\n// associated with those keys and a map of those keys to any units\n// that were encountered but not used.\n// Unit for a given key is the first encountered unit for that key. If multiple\n// units are encountered for values paired with a particular key, then the first\n// unit encountered is used and all other units are returned in sorted order\n// in map of ignored units.\n// If no units are encountered for a particular key, the unit is then inferred\n// based on the key.\nfunc (p *Profile) NumLabelUnits() (map[string]string, map[string][]string) {\n\tnumLabelUnits := map[string]string{}\n\tignoredUnits := map[string]map[string]bool{}\n\tencounteredKeys := map[string]bool{}\n\n\t// Determine units based on numeric tags for each sample.\n\tfor _, s := range p.Sample {\n\t\tfor k := range s.NumLabel {\n\t\t\tencounteredKeys[k] = true\n\t\t\tfor _, unit := range s.NumUnit[k] {\n\t\t\t\tif unit == \"\" {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif wantUnit, ok := numLabelUnits[k]; !ok {\n\t\t\t\t\tnumLabelUnits[k] = unit\n\t\t\t\t} else if wantUnit != unit {\n\t\t\t\t\tif v, ok := ignoredUnits[k]; ok {\n\t\t\t\t\t\tv[unit] = true\n\t\t\t\t\t} else {\n\t\t\t\t\t\tignoredUnits[k] = map[string]bool{unit: true}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// Infer units for keys without any units associated with\n\t// numeric tag values.\n\tfor key := range encounteredKeys {\n\t\tunit := numLabelUnits[key]\n\t\tif unit == \"\" {\n\t\t\tswitch key {\n\t\t\tcase \"alignment\", \"request\":\n\t\t\t\tnumLabelUnits[key] = \"bytes\"\n\t\t\tdefault:\n\t\t\t\tnumLabelUnits[key] = key\n\t\t\t}\n\t\t}\n\t}\n\n\t// Copy ignored units into more readable format\n\tunitsIgnored := make(map[string][]string, len(ignoredUnits))\n\tfor key, values := range ignoredUnits {\n\t\tunits := make([]string, len(values))\n\t\ti := 0\n\t\tfor unit := range values {\n\t\t\tunits[i] = unit\n\t\t\ti++\n\t\t}\n\t\tsort.Strings(units)\n\t\tunitsIgnored[key] = units\n\t}\n\n\treturn numLabelUnits, unitsIgnored\n}\n\n// String dumps a text representation of a profile. Intended mainly\n// for debugging purposes.\nfunc (p *Profile) String() string {\n\tss := make([]string, 0, len(p.Comments)+len(p.Sample)+len(p.Mapping)+len(p.Location))\n\tfor _, c := range p.Comments {\n\t\tss = append(ss, \"Comment: \"+c)\n\t}\n\tif url := p.DocURL; url != \"\" {\n\t\tss = append(ss, fmt.Sprintf(\"Doc: %s\", url))\n\t}\n\tif pt := p.PeriodType; pt != nil {\n\t\tss = append(ss, fmt.Sprintf(\"PeriodType: %s %s\", pt.Type, pt.Unit))\n\t}\n\tss = append(ss, fmt.Sprintf(\"Period: %d\", p.Period))\n\tif p.TimeNanos != 0 {\n\t\tss = append(ss, fmt.Sprintf(\"Time: %v\", time.Unix(0, p.TimeNanos)))\n\t}\n\tif p.DurationNanos != 0 {\n\t\tss = append(ss, fmt.Sprintf(\"Duration: %.4v\", time.Duration(p.DurationNanos)))\n\t}\n\n\tss = append(ss, \"Samples:\")\n\tvar sh1 string\n\tfor _, s := range p.SampleType {\n\t\tdflt := \"\"\n\t\tif s.Type == p.DefaultSampleType {\n\t\t\tdflt = \"[dflt]\"\n\t\t}\n\t\tsh1 = sh1 + fmt.Sprintf(\"%s/%s%s \", s.Type, s.Unit, dflt)\n\t}\n\tss = append(ss, strings.TrimSpace(sh1))\n\tfor _, s := range p.Sample {\n\t\tss = append(ss, s.string())\n\t}\n\n\tss = append(ss, \"Locations\")\n\tfor _, l := range p.Location {\n\t\tss = append(ss, l.string())\n\t}\n\n\tss = append(ss, \"Mappings\")\n\tfor _, m := range p.Mapping {\n\t\tss = append(ss, m.string())\n\t}\n\n\treturn strings.Join(ss, \"\\n\") + \"\\n\"\n}\n\n// string dumps a text representation of a mapping. Intended mainly\n// for debugging purposes.\nfunc (m *Mapping) string() string {\n\tbits := \"\"\n\tif m.HasFunctions {\n\t\tbits = bits + \"[FN]\"\n\t}\n\tif m.HasFilenames {\n\t\tbits = bits + \"[FL]\"\n\t}\n\tif m.HasLineNumbers {\n\t\tbits = bits + \"[LN]\"\n\t}\n\tif m.HasInlineFrames {\n\t\tbits = bits + \"[IN]\"\n\t}\n\treturn fmt.Sprintf(\"%d: %#x/%#x/%#x %s %s %s\",\n\t\tm.ID,\n\t\tm.Start, m.Limit, m.Offset,\n\t\tm.File,\n\t\tm.BuildID,\n\t\tbits)\n}\n\n// string dumps a text representation of a location. Intended mainly\n// for debugging purposes.\nfunc (l *Location) string() string {\n\tss := []string{}\n\tlocStr := fmt.Sprintf(\"%6d: %#x \", l.ID, l.Address)\n\tif m := l.Mapping; m != nil {\n\t\tlocStr = locStr + fmt.Sprintf(\"M=%d \", m.ID)\n\t}\n\tif l.IsFolded {\n\t\tlocStr = locStr + \"[F] \"\n\t}\n\tif len(l.Line) == 0 {\n\t\tss = append(ss, locStr)\n\t}\n\tfor li := range l.Line {\n\t\tlnStr := \"??\"\n\t\tif fn := l.Line[li].Function; fn != nil {\n\t\t\tlnStr = fmt.Sprintf(\"%s %s:%d:%d s=%d\",\n\t\t\t\tfn.Name,\n\t\t\t\tfn.Filename,\n\t\t\t\tl.Line[li].Line,\n\t\t\t\tl.Line[li].Column,\n\t\t\t\tfn.StartLine)\n\t\t\tif fn.Name != fn.SystemName {\n\t\t\t\tlnStr = lnStr + \"(\" + fn.SystemName + \")\"\n\t\t\t}\n\t\t}\n\t\tss = append(ss, locStr+lnStr)\n\t\t// Do not print location details past the first line\n\t\tlocStr = \"             \"\n\t}\n\treturn strings.Join(ss, \"\\n\")\n}\n\n// string dumps a text representation of a sample. Intended mainly\n// for debugging purposes.\nfunc (s *Sample) string() string {\n\tss := []string{}\n\tvar sv string\n\tfor _, v := range s.Value {\n\t\tsv = fmt.Sprintf(\"%s %10d\", sv, v)\n\t}\n\tsv = sv + \": \"\n\tfor _, l := range s.Location {\n\t\tsv = sv + fmt.Sprintf(\"%d \", l.ID)\n\t}\n\tss = append(ss, sv)\n\tconst labelHeader = \"                \"\n\tif len(s.Label) > 0 {\n\t\tss = append(ss, labelHeader+labelsToString(s.Label))\n\t}\n\tif len(s.NumLabel) > 0 {\n\t\tss = append(ss, labelHeader+numLabelsToString(s.NumLabel, s.NumUnit))\n\t}\n\treturn strings.Join(ss, \"\\n\")\n}\n\n// labelsToString returns a string representation of a\n// map representing labels.\nfunc labelsToString(labels map[string][]string) string {\n\tls := []string{}\n\tfor k, v := range labels {\n\t\tls = append(ls, fmt.Sprintf(\"%s:%v\", k, v))\n\t}\n\tsort.Strings(ls)\n\treturn strings.Join(ls, \" \")\n}\n\n// numLabelsToString returns a string representation of a map\n// representing numeric labels.\nfunc numLabelsToString(numLabels map[string][]int64, numUnits map[string][]string) string {\n\tls := []string{}\n\tfor k, v := range numLabels {\n\t\tunits := numUnits[k]\n\t\tvar labelString string\n\t\tif len(units) == len(v) {\n\t\t\tvalues := make([]string, len(v))\n\t\t\tfor i, vv := range v {\n\t\t\t\tvalues[i] = fmt.Sprintf(\"%d %s\", vv, units[i])\n\t\t\t}\n\t\t\tlabelString = fmt.Sprintf(\"%s:%v\", k, values)\n\t\t} else {\n\t\t\tlabelString = fmt.Sprintf(\"%s:%v\", k, v)\n\t\t}\n\t\tls = append(ls, labelString)\n\t}\n\tsort.Strings(ls)\n\treturn strings.Join(ls, \" \")\n}\n\n// SetLabel sets the specified key to the specified value for all samples in the\n// profile.\nfunc (p *Profile) SetLabel(key string, value []string) {\n\tfor _, sample := range p.Sample {\n\t\tif sample.Label == nil {\n\t\t\tsample.Label = map[string][]string{key: value}\n\t\t} else {\n\t\t\tsample.Label[key] = value\n\t\t}\n\t}\n}\n\n// RemoveLabel removes all labels associated with the specified key for all\n// samples in the profile.\nfunc (p *Profile) RemoveLabel(key string) {\n\tfor _, sample := range p.Sample {\n\t\tdelete(sample.Label, key)\n\t}\n}\n\n// HasLabel returns true if a sample has a label with indicated key and value.\nfunc (s *Sample) HasLabel(key, value string) bool {\n\tfor _, v := range s.Label[key] {\n\t\tif v == value {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// SetNumLabel sets the specified key to the specified value for all samples in the\n// profile. \"unit\" is a slice that describes the units that each corresponding member\n// of \"values\" is measured in (e.g. bytes or seconds).  If there is no relevant\n// unit for a given value, that member of \"unit\" should be the empty string.\n// \"unit\" must either have the same length as \"value\", or be nil.\nfunc (p *Profile) SetNumLabel(key string, value []int64, unit []string) {\n\tfor _, sample := range p.Sample {\n\t\tif sample.NumLabel == nil {\n\t\t\tsample.NumLabel = map[string][]int64{key: value}\n\t\t} else {\n\t\t\tsample.NumLabel[key] = value\n\t\t}\n\t\tif sample.NumUnit == nil {\n\t\t\tsample.NumUnit = map[string][]string{key: unit}\n\t\t} else {\n\t\t\tsample.NumUnit[key] = unit\n\t\t}\n\t}\n}\n\n// RemoveNumLabel removes all numerical labels associated with the specified key for all\n// samples in the profile.\nfunc (p *Profile) RemoveNumLabel(key string) {\n\tfor _, sample := range p.Sample {\n\t\tdelete(sample.NumLabel, key)\n\t\tdelete(sample.NumUnit, key)\n\t}\n}\n\n// DiffBaseSample returns true if a sample belongs to the diff base and false\n// otherwise.\nfunc (s *Sample) DiffBaseSample() bool {\n\treturn s.HasLabel(\"pprof::base\", \"true\")\n}\n\n// Scale multiplies all sample values in a profile by a constant and keeps\n// only samples that have at least one non-zero value.\nfunc (p *Profile) Scale(ratio float64) {\n\tif ratio == 1 {\n\t\treturn\n\t}\n\tratios := make([]float64, len(p.SampleType))\n\tfor i := range p.SampleType {\n\t\tratios[i] = ratio\n\t}\n\tp.ScaleN(ratios)\n}\n\n// ScaleN multiplies each sample values in a sample by a different amount\n// and keeps only samples that have at least one non-zero value.\nfunc (p *Profile) ScaleN(ratios []float64) error {\n\tif len(p.SampleType) != len(ratios) {\n\t\treturn fmt.Errorf(\"mismatched scale ratios, got %d, want %d\", len(ratios), len(p.SampleType))\n\t}\n\tallOnes := true\n\tfor _, r := range ratios {\n\t\tif r != 1 {\n\t\t\tallOnes = false\n\t\t\tbreak\n\t\t}\n\t}\n\tif allOnes {\n\t\treturn nil\n\t}\n\tfillIdx := 0\n\tfor _, s := range p.Sample {\n\t\tkeepSample := false\n\t\tfor i, v := range s.Value {\n\t\t\tif ratios[i] != 1 {\n\t\t\t\tval := int64(math.Round(float64(v) * ratios[i]))\n\t\t\t\ts.Value[i] = val\n\t\t\t\tkeepSample = keepSample || val != 0\n\t\t\t}\n\t\t}\n\t\tif keepSample {\n\t\t\tp.Sample[fillIdx] = s\n\t\t\tfillIdx++\n\t\t}\n\t}\n\tp.Sample = p.Sample[:fillIdx]\n\treturn nil\n}\n\n// HasFunctions determines if all locations in this profile have\n// symbolized function information.\nfunc (p *Profile) HasFunctions() bool {\n\tfor _, l := range p.Location {\n\t\tif l.Mapping != nil && !l.Mapping.HasFunctions {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// HasFileLines determines if all locations in this profile have\n// symbolized file and line number information.\nfunc (p *Profile) HasFileLines() bool {\n\tfor _, l := range p.Location {\n\t\tif l.Mapping != nil && (!l.Mapping.HasFilenames || !l.Mapping.HasLineNumbers) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Unsymbolizable returns true if a mapping points to a binary for which\n// locations can't be symbolized in principle, at least now. Examples are\n// \"[vdso]\", \"[vsyscall]\" and some others, see the code.\nfunc (m *Mapping) Unsymbolizable() bool {\n\tname := filepath.Base(m.File)\n\treturn strings.HasPrefix(name, \"[\") || strings.HasPrefix(name, \"linux-vdso\") || strings.HasPrefix(m.File, \"/dev/dri/\") || m.File == \"//anon\"\n}\n\n// Copy makes a fully independent copy of a profile.\nfunc (p *Profile) Copy() *Profile {\n\tpp := &Profile{}\n\tif err := unmarshal(serialize(p), pp); err != nil {\n\t\tpanic(err)\n\t}\n\tif err := pp.postDecode(); err != nil {\n\t\tpanic(err)\n\t}\n\n\treturn pp\n}\n"
  },
  {
    "path": "vendor/github.com/google/pprof/profile/proto.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// This file is a simple protocol buffer encoder and decoder.\n// The format is described at\n// https://developers.google.com/protocol-buffers/docs/encoding\n//\n// A protocol message must implement the message interface:\n//   decoder() []decoder\n//   encode(*buffer)\n//\n// The decode method returns a slice indexed by field number that gives the\n// function to decode that field.\n// The encode method encodes its receiver into the given buffer.\n//\n// The two methods are simple enough to be implemented by hand rather than\n// by using a protocol compiler.\n//\n// See profile.go for examples of messages implementing this interface.\n//\n// There is no support for groups, message sets, or \"has\" bits.\n\npackage profile\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\ntype buffer struct {\n\tfield    int // field tag\n\ttyp      int // proto wire type code for field\n\tu64      uint64\n\tdata     []byte\n\ttmp      [16]byte\n\ttmpLines []Line // temporary storage used while decoding \"repeated Line\".\n}\n\ntype decoder func(*buffer, message) error\n\ntype message interface {\n\tdecoder() []decoder\n\tencode(*buffer)\n}\n\nfunc marshal(m message) []byte {\n\tvar b buffer\n\tm.encode(&b)\n\treturn b.data\n}\n\nfunc encodeVarint(b *buffer, x uint64) {\n\tfor x >= 128 {\n\t\tb.data = append(b.data, byte(x)|0x80)\n\t\tx >>= 7\n\t}\n\tb.data = append(b.data, byte(x))\n}\n\nfunc encodeLength(b *buffer, tag int, len int) {\n\tencodeVarint(b, uint64(tag)<<3|2)\n\tencodeVarint(b, uint64(len))\n}\n\nfunc encodeUint64(b *buffer, tag int, x uint64) {\n\t// append varint to b.data\n\tencodeVarint(b, uint64(tag)<<3)\n\tencodeVarint(b, x)\n}\n\nfunc encodeUint64s(b *buffer, tag int, x []uint64) {\n\tif len(x) > 2 {\n\t\t// Use packed encoding\n\t\tn1 := len(b.data)\n\t\tfor _, u := range x {\n\t\t\tencodeVarint(b, u)\n\t\t}\n\t\tn2 := len(b.data)\n\t\tencodeLength(b, tag, n2-n1)\n\t\tn3 := len(b.data)\n\t\tcopy(b.tmp[:], b.data[n2:n3])\n\t\tcopy(b.data[n1+(n3-n2):], b.data[n1:n2])\n\t\tcopy(b.data[n1:], b.tmp[:n3-n2])\n\t\treturn\n\t}\n\tfor _, u := range x {\n\t\tencodeUint64(b, tag, u)\n\t}\n}\n\nfunc encodeUint64Opt(b *buffer, tag int, x uint64) {\n\tif x == 0 {\n\t\treturn\n\t}\n\tencodeUint64(b, tag, x)\n}\n\nfunc encodeInt64(b *buffer, tag int, x int64) {\n\tu := uint64(x)\n\tencodeUint64(b, tag, u)\n}\n\nfunc encodeInt64s(b *buffer, tag int, x []int64) {\n\tif len(x) > 2 {\n\t\t// Use packed encoding\n\t\tn1 := len(b.data)\n\t\tfor _, u := range x {\n\t\t\tencodeVarint(b, uint64(u))\n\t\t}\n\t\tn2 := len(b.data)\n\t\tencodeLength(b, tag, n2-n1)\n\t\tn3 := len(b.data)\n\t\tcopy(b.tmp[:], b.data[n2:n3])\n\t\tcopy(b.data[n1+(n3-n2):], b.data[n1:n2])\n\t\tcopy(b.data[n1:], b.tmp[:n3-n2])\n\t\treturn\n\t}\n\tfor _, u := range x {\n\t\tencodeInt64(b, tag, u)\n\t}\n}\n\nfunc encodeInt64Opt(b *buffer, tag int, x int64) {\n\tif x == 0 {\n\t\treturn\n\t}\n\tencodeInt64(b, tag, x)\n}\n\nfunc encodeString(b *buffer, tag int, x string) {\n\tencodeLength(b, tag, len(x))\n\tb.data = append(b.data, x...)\n}\n\nfunc encodeStrings(b *buffer, tag int, x []string) {\n\tfor _, s := range x {\n\t\tencodeString(b, tag, s)\n\t}\n}\n\nfunc encodeBool(b *buffer, tag int, x bool) {\n\tif x {\n\t\tencodeUint64(b, tag, 1)\n\t} else {\n\t\tencodeUint64(b, tag, 0)\n\t}\n}\n\nfunc encodeBoolOpt(b *buffer, tag int, x bool) {\n\tif x {\n\t\tencodeBool(b, tag, x)\n\t}\n}\n\nfunc encodeMessage(b *buffer, tag int, m message) {\n\tn1 := len(b.data)\n\tm.encode(b)\n\tn2 := len(b.data)\n\tencodeLength(b, tag, n2-n1)\n\tn3 := len(b.data)\n\tcopy(b.tmp[:], b.data[n2:n3])\n\tcopy(b.data[n1+(n3-n2):], b.data[n1:n2])\n\tcopy(b.data[n1:], b.tmp[:n3-n2])\n}\n\nfunc unmarshal(data []byte, m message) (err error) {\n\tb := buffer{data: data, typ: 2}\n\treturn decodeMessage(&b, m)\n}\n\nfunc le64(p []byte) uint64 {\n\treturn uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 | uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56\n}\n\nfunc le32(p []byte) uint32 {\n\treturn uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24\n}\n\nfunc decodeVarint(data []byte) (uint64, []byte, error) {\n\tvar u uint64\n\tfor i := 0; ; i++ {\n\t\tif i >= 10 || i >= len(data) {\n\t\t\treturn 0, nil, errors.New(\"bad varint\")\n\t\t}\n\t\tu |= uint64(data[i]&0x7F) << uint(7*i)\n\t\tif data[i]&0x80 == 0 {\n\t\t\treturn u, data[i+1:], nil\n\t\t}\n\t}\n}\n\nfunc decodeField(b *buffer, data []byte) ([]byte, error) {\n\tx, data, err := decodeVarint(data)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tb.field = int(x >> 3)\n\tb.typ = int(x & 7)\n\tb.data = nil\n\tb.u64 = 0\n\tswitch b.typ {\n\tcase 0:\n\t\tb.u64, data, err = decodeVarint(data)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\tcase 1:\n\t\tif len(data) < 8 {\n\t\t\treturn nil, errors.New(\"not enough data\")\n\t\t}\n\t\tb.u64 = le64(data[:8])\n\t\tdata = data[8:]\n\tcase 2:\n\t\tvar n uint64\n\t\tn, data, err = decodeVarint(data)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif n > uint64(len(data)) {\n\t\t\treturn nil, errors.New(\"too much data\")\n\t\t}\n\t\tb.data = data[:n]\n\t\tdata = data[n:]\n\tcase 5:\n\t\tif len(data) < 4 {\n\t\t\treturn nil, errors.New(\"not enough data\")\n\t\t}\n\t\tb.u64 = uint64(le32(data[:4]))\n\t\tdata = data[4:]\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown wire type: %d\", b.typ)\n\t}\n\n\treturn data, nil\n}\n\nfunc checkType(b *buffer, typ int) error {\n\tif b.typ != typ {\n\t\treturn errors.New(\"type mismatch\")\n\t}\n\treturn nil\n}\n\nfunc decodeMessage(b *buffer, m message) error {\n\tif err := checkType(b, 2); err != nil {\n\t\treturn err\n\t}\n\tdec := m.decoder()\n\tdata := b.data\n\tfor len(data) > 0 {\n\t\t// pull varint field# + type\n\t\tvar err error\n\t\tdata, err = decodeField(b, data)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif b.field >= len(dec) || dec[b.field] == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif err := dec[b.field](b, m); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc decodeInt64(b *buffer, x *int64) error {\n\tif err := checkType(b, 0); err != nil {\n\t\treturn err\n\t}\n\t*x = int64(b.u64)\n\treturn nil\n}\n\nfunc decodeInt64s(b *buffer, x *[]int64) error {\n\tif b.typ == 2 {\n\t\t// Packed encoding\n\t\tdata := b.data\n\t\tfor len(data) > 0 {\n\t\t\tvar u uint64\n\t\t\tvar err error\n\n\t\t\tif u, data, err = decodeVarint(data); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\t*x = append(*x, int64(u))\n\t\t}\n\t\treturn nil\n\t}\n\tvar i int64\n\tif err := decodeInt64(b, &i); err != nil {\n\t\treturn err\n\t}\n\t*x = append(*x, i)\n\treturn nil\n}\n\nfunc decodeUint64(b *buffer, x *uint64) error {\n\tif err := checkType(b, 0); err != nil {\n\t\treturn err\n\t}\n\t*x = b.u64\n\treturn nil\n}\n\nfunc decodeUint64s(b *buffer, x *[]uint64) error {\n\tif b.typ == 2 {\n\t\tdata := b.data\n\t\t// Packed encoding\n\t\tfor len(data) > 0 {\n\t\t\tvar u uint64\n\t\t\tvar err error\n\n\t\t\tif u, data, err = decodeVarint(data); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\t*x = append(*x, u)\n\t\t}\n\t\treturn nil\n\t}\n\tvar u uint64\n\tif err := decodeUint64(b, &u); err != nil {\n\t\treturn err\n\t}\n\t*x = append(*x, u)\n\treturn nil\n}\n\nfunc decodeString(b *buffer, x *string) error {\n\tif err := checkType(b, 2); err != nil {\n\t\treturn err\n\t}\n\t*x = string(b.data)\n\treturn nil\n}\n\nfunc decodeStrings(b *buffer, x *[]string) error {\n\tvar s string\n\tif err := decodeString(b, &s); err != nil {\n\t\treturn err\n\t}\n\t*x = append(*x, s)\n\treturn nil\n}\n\nfunc decodeBool(b *buffer, x *bool) error {\n\tif err := checkType(b, 0); err != nil {\n\t\treturn err\n\t}\n\tif int64(b.u64) == 0 {\n\t\t*x = false\n\t} else {\n\t\t*x = true\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/pprof/profile/prune.go",
    "content": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Implements methods to remove frames from profiles.\n\npackage profile\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n)\n\nvar (\n\treservedNames = []string{\"(anonymous namespace)\", \"operator()\"}\n\tbracketRx     = func() *regexp.Regexp {\n\t\tvar quotedNames []string\n\t\tfor _, name := range append(reservedNames, \"(\") {\n\t\t\tquotedNames = append(quotedNames, regexp.QuoteMeta(name))\n\t\t}\n\t\treturn regexp.MustCompile(strings.Join(quotedNames, \"|\"))\n\t}()\n)\n\n// simplifyFunc does some primitive simplification of function names.\nfunc simplifyFunc(f string) string {\n\t// Account for leading '.' on the PPC ELF v1 ABI.\n\tfuncName := strings.TrimPrefix(f, \".\")\n\t// Account for unsimplified names -- try  to remove the argument list by trimming\n\t// starting from the first '(', but skipping reserved names that have '('.\n\tfor _, ind := range bracketRx.FindAllStringSubmatchIndex(funcName, -1) {\n\t\tfoundReserved := false\n\t\tfor _, res := range reservedNames {\n\t\t\tif funcName[ind[0]:ind[1]] == res {\n\t\t\t\tfoundReserved = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !foundReserved {\n\t\t\tfuncName = funcName[:ind[0]]\n\t\t\tbreak\n\t\t}\n\t}\n\treturn funcName\n}\n\n// Prune removes all nodes beneath a node matching dropRx, and not\n// matching keepRx. If the root node of a Sample matches, the sample\n// will have an empty stack.\nfunc (p *Profile) Prune(dropRx, keepRx *regexp.Regexp) {\n\tprune := make(map[uint64]bool)\n\tpruneBeneath := make(map[uint64]bool)\n\n\t// simplifyFunc can be expensive, so cache results.\n\t// Note that the same function name can be encountered many times due\n\t// different lines and addresses in the same function.\n\tpruneCache := map[string]bool{} // Map from function to whether or not to prune\n\tpruneFromHere := func(s string) bool {\n\t\tif r, ok := pruneCache[s]; ok {\n\t\t\treturn r\n\t\t}\n\t\tfuncName := simplifyFunc(s)\n\t\tif dropRx.MatchString(funcName) {\n\t\t\tif keepRx == nil || !keepRx.MatchString(funcName) {\n\t\t\t\tpruneCache[s] = true\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\tpruneCache[s] = false\n\t\treturn false\n\t}\n\n\tfor _, loc := range p.Location {\n\t\tvar i int\n\t\tfor i = len(loc.Line) - 1; i >= 0; i-- {\n\t\t\tif fn := loc.Line[i].Function; fn != nil && fn.Name != \"\" {\n\t\t\t\tif pruneFromHere(fn.Name) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif i >= 0 {\n\t\t\t// Found matching entry to prune.\n\t\t\tpruneBeneath[loc.ID] = true\n\n\t\t\t// Remove the matching location.\n\t\t\tif i == len(loc.Line)-1 {\n\t\t\t\t// Matched the top entry: prune the whole location.\n\t\t\t\tprune[loc.ID] = true\n\t\t\t} else {\n\t\t\t\tloc.Line = loc.Line[i+1:]\n\t\t\t}\n\t\t}\n\t}\n\n\t// Prune locs from each Sample\n\tfor _, sample := range p.Sample {\n\t\t// Scan from the root to the leaves to find the prune location.\n\t\t// Do not prune frames before the first user frame, to avoid\n\t\t// pruning everything.\n\t\tfoundUser := false\n\t\tfor i := len(sample.Location) - 1; i >= 0; i-- {\n\t\t\tid := sample.Location[i].ID\n\t\t\tif !prune[id] && !pruneBeneath[id] {\n\t\t\t\tfoundUser = true\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif !foundUser {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif prune[id] {\n\t\t\t\tsample.Location = sample.Location[i+1:]\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif pruneBeneath[id] {\n\t\t\t\tsample.Location = sample.Location[i:]\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n\n// RemoveUninteresting prunes and elides profiles using built-in\n// tables of uninteresting function names.\nfunc (p *Profile) RemoveUninteresting() error {\n\tvar keep, drop *regexp.Regexp\n\tvar err error\n\n\tif p.DropFrames != \"\" {\n\t\tif drop, err = regexp.Compile(\"^(\" + p.DropFrames + \")$\"); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to compile regexp %s: %v\", p.DropFrames, err)\n\t\t}\n\t\tif p.KeepFrames != \"\" {\n\t\t\tif keep, err = regexp.Compile(\"^(\" + p.KeepFrames + \")$\"); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to compile regexp %s: %v\", p.KeepFrames, err)\n\t\t\t}\n\t\t}\n\t\tp.Prune(drop, keep)\n\t}\n\treturn nil\n}\n\n// PruneFrom removes all nodes beneath the lowest node matching dropRx, not including itself.\n//\n// Please see the example below to understand this method as well as\n// the difference from Prune method.\n//\n// A sample contains Location of [A,B,C,B,D] where D is the top frame and there's no inline.\n//\n// PruneFrom(A) returns [A,B,C,B,D] because there's no node beneath A.\n// Prune(A, nil) returns [B,C,B,D] by removing A itself.\n//\n// PruneFrom(B) returns [B,C,B,D] by removing all nodes beneath the first B when scanning from the bottom.\n// Prune(B, nil) returns [D] because a matching node is found by scanning from the root.\nfunc (p *Profile) PruneFrom(dropRx *regexp.Regexp) {\n\tpruneBeneath := make(map[uint64]bool)\n\n\tfor _, loc := range p.Location {\n\t\tfor i := 0; i < len(loc.Line); i++ {\n\t\t\tif fn := loc.Line[i].Function; fn != nil && fn.Name != \"\" {\n\t\t\t\tfuncName := simplifyFunc(fn.Name)\n\t\t\t\tif dropRx.MatchString(funcName) {\n\t\t\t\t\t// Found matching entry to prune.\n\t\t\t\t\tpruneBeneath[loc.ID] = true\n\t\t\t\t\tloc.Line = loc.Line[i:]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Prune locs from each Sample\n\tfor _, sample := range p.Sample {\n\t\t// Scan from the bottom leaf to the root to find the prune location.\n\t\tfor i, loc := range sample.Location {\n\t\t\tif pruneBeneath[loc.ID] {\n\t\t\t\tsample.Location = sample.Location[i:]\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/CHANGELOG.md",
    "content": "# Changelog\n\n## [1.6.0](https://github.com/google/uuid/compare/v1.5.0...v1.6.0) (2024-01-16)\n\n\n### Features\n\n* add Max UUID constant ([#149](https://github.com/google/uuid/issues/149)) ([c58770e](https://github.com/google/uuid/commit/c58770eb495f55fe2ced6284f93c5158a62e53e3))\n\n\n### Bug Fixes\n\n* fix typo in version 7 uuid documentation ([#153](https://github.com/google/uuid/issues/153)) ([016b199](https://github.com/google/uuid/commit/016b199544692f745ffc8867b914129ecb47ef06))\n* Monotonicity in UUIDv7 ([#150](https://github.com/google/uuid/issues/150)) ([a2b2b32](https://github.com/google/uuid/commit/a2b2b32373ff0b1a312b7fdf6d38a977099698a6))\n\n## [1.5.0](https://github.com/google/uuid/compare/v1.4.0...v1.5.0) (2023-12-12)\n\n\n### Features\n\n* Validate UUID without creating new UUID ([#141](https://github.com/google/uuid/issues/141)) ([9ee7366](https://github.com/google/uuid/commit/9ee7366e66c9ad96bab89139418a713dc584ae29))\n\n## [1.4.0](https://github.com/google/uuid/compare/v1.3.1...v1.4.0) (2023-10-26)\n\n\n### Features\n\n* UUIDs slice type with Strings() convenience method ([#133](https://github.com/google/uuid/issues/133)) ([cd5fbbd](https://github.com/google/uuid/commit/cd5fbbdd02f3e3467ac18940e07e062be1f864b4))\n\n### Fixes\n\n* Clarify that Parse's job is to parse but not necessarily validate strings. (Documents current behavior)\n\n## [1.3.1](https://github.com/google/uuid/compare/v1.3.0...v1.3.1) (2023-08-18)\n\n\n### Bug Fixes\n\n* Use .EqualFold() to parse urn prefixed UUIDs ([#118](https://github.com/google/uuid/issues/118)) ([574e687](https://github.com/google/uuid/commit/574e6874943741fb99d41764c705173ada5293f0))\n\n## Changelog\n"
  },
  {
    "path": "vendor/github.com/google/uuid/CONTRIBUTING.md",
    "content": "# How to contribute\n\nWe definitely welcome patches and contribution to this project!\n\n### Tips\n\nCommits must be formatted according to the [Conventional Commits Specification](https://www.conventionalcommits.org).\n\nAlways try to include a test case! If it is not possible or not necessary,\nplease explain why in the pull request description.\n\n### Releasing\n\nCommits that would precipitate a SemVer change, as described in the Conventional\nCommits Specification, will trigger [`release-please`](https://github.com/google-github-actions/release-please-action)\nto create a release candidate pull request. Once submitted, `release-please`\nwill create a release.\n\nFor tips on how to work with `release-please`, see its documentation.\n\n### Legal requirements\n\nIn order to protect both you and ourselves, you will need to sign the\n[Contributor License Agreement](https://cla.developers.google.com/clas).\n\nYou may have already signed it for other Google projects.\n"
  },
  {
    "path": "vendor/github.com/google/uuid/CONTRIBUTORS",
    "content": "Paul Borman <borman@google.com>\nbmatsuo\nshawnps\ntheory\njboverfelt\ndsymonds\ncd1\nwallclockbuilder\ndansouza\n"
  },
  {
    "path": "vendor/github.com/google/uuid/LICENSE",
    "content": "Copyright (c) 2009,2014 Google Inc. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(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": "vendor/github.com/google/uuid/README.md",
    "content": "# uuid\nThe uuid package generates and inspects UUIDs based on\n[RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122)\nand DCE 1.1: Authentication and Security Services. \n\nThis package is based on the github.com/pborman/uuid package (previously named\ncode.google.com/p/go-uuid).  It differs from these earlier packages in that\na UUID is a 16 byte array rather than a byte slice.  One loss due to this\nchange is the ability to represent an invalid UUID (vs a NIL UUID).\n\n###### Install\n```sh\ngo get github.com/google/uuid\n```\n\n###### Documentation \n[![Go Reference](https://pkg.go.dev/badge/github.com/google/uuid.svg)](https://pkg.go.dev/github.com/google/uuid)\n\nFull `go doc` style documentation for the package can be viewed online without\ninstalling this package by using the GoDoc site here: \nhttp://pkg.go.dev/github.com/google/uuid\n"
  },
  {
    "path": "vendor/github.com/google/uuid/dce.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"os\"\n)\n\n// A Domain represents a Version 2 domain\ntype Domain byte\n\n// Domain constants for DCE Security (Version 2) UUIDs.\nconst (\n\tPerson = Domain(0)\n\tGroup  = Domain(1)\n\tOrg    = Domain(2)\n)\n\n// NewDCESecurity returns a DCE Security (Version 2) UUID.\n//\n// The domain should be one of Person, Group or Org.\n// On a POSIX system the id should be the users UID for the Person\n// domain and the users GID for the Group.  The meaning of id for\n// the domain Org or on non-POSIX systems is site defined.\n//\n// For a given domain/id pair the same token may be returned for up to\n// 7 minutes and 10 seconds.\nfunc NewDCESecurity(domain Domain, id uint32) (UUID, error) {\n\tuuid, err := NewUUID()\n\tif err == nil {\n\t\tuuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2\n\t\tuuid[9] = byte(domain)\n\t\tbinary.BigEndian.PutUint32(uuid[0:], id)\n\t}\n\treturn uuid, err\n}\n\n// NewDCEPerson returns a DCE Security (Version 2) UUID in the person\n// domain with the id returned by os.Getuid.\n//\n//  NewDCESecurity(Person, uint32(os.Getuid()))\nfunc NewDCEPerson() (UUID, error) {\n\treturn NewDCESecurity(Person, uint32(os.Getuid()))\n}\n\n// NewDCEGroup returns a DCE Security (Version 2) UUID in the group\n// domain with the id returned by os.Getgid.\n//\n//  NewDCESecurity(Group, uint32(os.Getgid()))\nfunc NewDCEGroup() (UUID, error) {\n\treturn NewDCESecurity(Group, uint32(os.Getgid()))\n}\n\n// Domain returns the domain for a Version 2 UUID.  Domains are only defined\n// for Version 2 UUIDs.\nfunc (uuid UUID) Domain() Domain {\n\treturn Domain(uuid[9])\n}\n\n// ID returns the id for a Version 2 UUID. IDs are only defined for Version 2\n// UUIDs.\nfunc (uuid UUID) ID() uint32 {\n\treturn binary.BigEndian.Uint32(uuid[0:4])\n}\n\nfunc (d Domain) String() string {\n\tswitch d {\n\tcase Person:\n\t\treturn \"Person\"\n\tcase Group:\n\t\treturn \"Group\"\n\tcase Org:\n\t\treturn \"Org\"\n\t}\n\treturn fmt.Sprintf(\"Domain%d\", int(d))\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/doc.go",
    "content": "// Copyright 2016 Google Inc.  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\n// Package uuid generates and inspects UUIDs.\n//\n// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security\n// Services.\n//\n// A UUID is a 16 byte (128 bit) array.  UUIDs may be used as keys to\n// maps or compared directly.\npackage uuid\n"
  },
  {
    "path": "vendor/github.com/google/uuid/hash.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport (\n\t\"crypto/md5\"\n\t\"crypto/sha1\"\n\t\"hash\"\n)\n\n// Well known namespace IDs and UUIDs\nvar (\n\tNameSpaceDNS  = Must(Parse(\"6ba7b810-9dad-11d1-80b4-00c04fd430c8\"))\n\tNameSpaceURL  = Must(Parse(\"6ba7b811-9dad-11d1-80b4-00c04fd430c8\"))\n\tNameSpaceOID  = Must(Parse(\"6ba7b812-9dad-11d1-80b4-00c04fd430c8\"))\n\tNameSpaceX500 = Must(Parse(\"6ba7b814-9dad-11d1-80b4-00c04fd430c8\"))\n\tNil           UUID // empty UUID, all zeros\n\n\t// The Max UUID is special form of UUID that is specified to have all 128 bits set to 1.\n\tMax = UUID{\n\t\t0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n\t\t0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n\t}\n)\n\n// NewHash returns a new UUID derived from the hash of space concatenated with\n// data generated by h.  The hash should be at least 16 byte in length.  The\n// first 16 bytes of the hash are used to form the UUID.  The version of the\n// UUID will be the lower 4 bits of version.  NewHash is used to implement\n// NewMD5 and NewSHA1.\nfunc NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {\n\th.Reset()\n\th.Write(space[:]) //nolint:errcheck\n\th.Write(data)     //nolint:errcheck\n\ts := h.Sum(nil)\n\tvar uuid UUID\n\tcopy(uuid[:], s)\n\tuuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4)\n\tuuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant\n\treturn uuid\n}\n\n// NewMD5 returns a new MD5 (Version 3) UUID based on the\n// supplied name space and data.  It is the same as calling:\n//\n//  NewHash(md5.New(), space, data, 3)\nfunc NewMD5(space UUID, data []byte) UUID {\n\treturn NewHash(md5.New(), space, data, 3)\n}\n\n// NewSHA1 returns a new SHA1 (Version 5) UUID based on the\n// supplied name space and data.  It is the same as calling:\n//\n//  NewHash(sha1.New(), space, data, 5)\nfunc NewSHA1(space UUID, data []byte) UUID {\n\treturn NewHash(sha1.New(), space, data, 5)\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/marshal.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport \"fmt\"\n\n// MarshalText implements encoding.TextMarshaler.\nfunc (uuid UUID) MarshalText() ([]byte, error) {\n\tvar js [36]byte\n\tencodeHex(js[:], uuid)\n\treturn js[:], nil\n}\n\n// UnmarshalText implements encoding.TextUnmarshaler.\nfunc (uuid *UUID) UnmarshalText(data []byte) error {\n\tid, err := ParseBytes(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*uuid = id\n\treturn nil\n}\n\n// MarshalBinary implements encoding.BinaryMarshaler.\nfunc (uuid UUID) MarshalBinary() ([]byte, error) {\n\treturn uuid[:], nil\n}\n\n// UnmarshalBinary implements encoding.BinaryUnmarshaler.\nfunc (uuid *UUID) UnmarshalBinary(data []byte) error {\n\tif len(data) != 16 {\n\t\treturn fmt.Errorf(\"invalid UUID (got %d bytes)\", len(data))\n\t}\n\tcopy(uuid[:], data)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/node.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport (\n\t\"sync\"\n)\n\nvar (\n\tnodeMu sync.Mutex\n\tifname string  // name of interface being used\n\tnodeID [6]byte // hardware for version 1 UUIDs\n\tzeroID [6]byte // nodeID with only 0's\n)\n\n// NodeInterface returns the name of the interface from which the NodeID was\n// derived.  The interface \"user\" is returned if the NodeID was set by\n// SetNodeID.\nfunc NodeInterface() string {\n\tdefer nodeMu.Unlock()\n\tnodeMu.Lock()\n\treturn ifname\n}\n\n// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs.\n// If name is \"\" then the first usable interface found will be used or a random\n// Node ID will be generated.  If a named interface cannot be found then false\n// is returned.\n//\n// SetNodeInterface never fails when name is \"\".\nfunc SetNodeInterface(name string) bool {\n\tdefer nodeMu.Unlock()\n\tnodeMu.Lock()\n\treturn setNodeInterface(name)\n}\n\nfunc setNodeInterface(name string) bool {\n\tiname, addr := getHardwareInterface(name) // null implementation for js\n\tif iname != \"\" && addr != nil {\n\t\tifname = iname\n\t\tcopy(nodeID[:], addr)\n\t\treturn true\n\t}\n\n\t// We found no interfaces with a valid hardware address.  If name\n\t// does not specify a specific interface generate a random Node ID\n\t// (section 4.1.6)\n\tif name == \"\" {\n\t\tifname = \"random\"\n\t\trandomBits(nodeID[:])\n\t\treturn true\n\t}\n\treturn false\n}\n\n// NodeID returns a slice of a copy of the current Node ID, setting the Node ID\n// if not already set.\nfunc NodeID() []byte {\n\tdefer nodeMu.Unlock()\n\tnodeMu.Lock()\n\tif nodeID == zeroID {\n\t\tsetNodeInterface(\"\")\n\t}\n\tnid := nodeID\n\treturn nid[:]\n}\n\n// SetNodeID sets the Node ID to be used for Version 1 UUIDs.  The first 6 bytes\n// of id are used.  If id is less than 6 bytes then false is returned and the\n// Node ID is not set.\nfunc SetNodeID(id []byte) bool {\n\tif len(id) < 6 {\n\t\treturn false\n\t}\n\tdefer nodeMu.Unlock()\n\tnodeMu.Lock()\n\tcopy(nodeID[:], id)\n\tifname = \"user\"\n\treturn true\n}\n\n// NodeID returns the 6 byte node id encoded in uuid.  It returns nil if uuid is\n// not valid.  The NodeID is only well defined for version 1 and 2 UUIDs.\nfunc (uuid UUID) NodeID() []byte {\n\tvar node [6]byte\n\tcopy(node[:], uuid[10:])\n\treturn node[:]\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/node_js.go",
    "content": "// Copyright 2017 Google Inc.  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\n// +build js\n\npackage uuid\n\n// getHardwareInterface returns nil values for the JS version of the code.\n// This removes the \"net\" dependency, because it is not used in the browser.\n// Using the \"net\" library inflates the size of the transpiled JS code by 673k bytes.\nfunc getHardwareInterface(name string) (string, []byte) { return \"\", nil }\n"
  },
  {
    "path": "vendor/github.com/google/uuid/node_net.go",
    "content": "// Copyright 2017 Google Inc.  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\n// +build !js\n\npackage uuid\n\nimport \"net\"\n\nvar interfaces []net.Interface // cached list of interfaces\n\n// getHardwareInterface returns the name and hardware address of interface name.\n// If name is \"\" then the name and hardware address of one of the system's\n// interfaces is returned.  If no interfaces are found (name does not exist or\n// there are no interfaces) then \"\", nil is returned.\n//\n// Only addresses of at least 6 bytes are returned.\nfunc getHardwareInterface(name string) (string, []byte) {\n\tif interfaces == nil {\n\t\tvar err error\n\t\tinterfaces, err = net.Interfaces()\n\t\tif err != nil {\n\t\t\treturn \"\", nil\n\t\t}\n\t}\n\tfor _, ifs := range interfaces {\n\t\tif len(ifs.HardwareAddr) >= 6 && (name == \"\" || name == ifs.Name) {\n\t\t\treturn ifs.Name, ifs.HardwareAddr\n\t\t}\n\t}\n\treturn \"\", nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/null.go",
    "content": "// Copyright 2021 Google Inc.  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 uuid\n\nimport (\n\t\"bytes\"\n\t\"database/sql/driver\"\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\nvar jsonNull = []byte(\"null\")\n\n// NullUUID represents a UUID that may be null.\n// NullUUID implements the SQL driver.Scanner interface so\n// it can be used as a scan destination:\n//\n//  var u uuid.NullUUID\n//  err := db.QueryRow(\"SELECT name FROM foo WHERE id=?\", id).Scan(&u)\n//  ...\n//  if u.Valid {\n//     // use u.UUID\n//  } else {\n//     // NULL value\n//  }\n//\ntype NullUUID struct {\n\tUUID  UUID\n\tValid bool // Valid is true if UUID is not NULL\n}\n\n// Scan implements the SQL driver.Scanner interface.\nfunc (nu *NullUUID) Scan(value interface{}) error {\n\tif value == nil {\n\t\tnu.UUID, nu.Valid = Nil, false\n\t\treturn nil\n\t}\n\n\terr := nu.UUID.Scan(value)\n\tif err != nil {\n\t\tnu.Valid = false\n\t\treturn err\n\t}\n\n\tnu.Valid = true\n\treturn nil\n}\n\n// Value implements the driver Valuer interface.\nfunc (nu NullUUID) Value() (driver.Value, error) {\n\tif !nu.Valid {\n\t\treturn nil, nil\n\t}\n\t// Delegate to UUID Value function\n\treturn nu.UUID.Value()\n}\n\n// MarshalBinary implements encoding.BinaryMarshaler.\nfunc (nu NullUUID) MarshalBinary() ([]byte, error) {\n\tif nu.Valid {\n\t\treturn nu.UUID[:], nil\n\t}\n\n\treturn []byte(nil), nil\n}\n\n// UnmarshalBinary implements encoding.BinaryUnmarshaler.\nfunc (nu *NullUUID) UnmarshalBinary(data []byte) error {\n\tif len(data) != 16 {\n\t\treturn fmt.Errorf(\"invalid UUID (got %d bytes)\", len(data))\n\t}\n\tcopy(nu.UUID[:], data)\n\tnu.Valid = true\n\treturn nil\n}\n\n// MarshalText implements encoding.TextMarshaler.\nfunc (nu NullUUID) MarshalText() ([]byte, error) {\n\tif nu.Valid {\n\t\treturn nu.UUID.MarshalText()\n\t}\n\n\treturn jsonNull, nil\n}\n\n// UnmarshalText implements encoding.TextUnmarshaler.\nfunc (nu *NullUUID) UnmarshalText(data []byte) error {\n\tid, err := ParseBytes(data)\n\tif err != nil {\n\t\tnu.Valid = false\n\t\treturn err\n\t}\n\tnu.UUID = id\n\tnu.Valid = true\n\treturn nil\n}\n\n// MarshalJSON implements json.Marshaler.\nfunc (nu NullUUID) MarshalJSON() ([]byte, error) {\n\tif nu.Valid {\n\t\treturn json.Marshal(nu.UUID)\n\t}\n\n\treturn jsonNull, nil\n}\n\n// UnmarshalJSON implements json.Unmarshaler.\nfunc (nu *NullUUID) UnmarshalJSON(data []byte) error {\n\tif bytes.Equal(data, jsonNull) {\n\t\t*nu = NullUUID{}\n\t\treturn nil // valid null UUID\n\t}\n\terr := json.Unmarshal(data, &nu.UUID)\n\tnu.Valid = err == nil\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/sql.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport (\n\t\"database/sql/driver\"\n\t\"fmt\"\n)\n\n// Scan implements sql.Scanner so UUIDs can be read from databases transparently.\n// Currently, database types that map to string and []byte are supported. Please\n// consult database-specific driver documentation for matching types.\nfunc (uuid *UUID) Scan(src interface{}) error {\n\tswitch src := src.(type) {\n\tcase nil:\n\t\treturn nil\n\n\tcase string:\n\t\t// if an empty UUID comes from a table, we return a null UUID\n\t\tif src == \"\" {\n\t\t\treturn nil\n\t\t}\n\n\t\t// see Parse for required string format\n\t\tu, err := Parse(src)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"Scan: %v\", err)\n\t\t}\n\n\t\t*uuid = u\n\n\tcase []byte:\n\t\t// if an empty UUID comes from a table, we return a null UUID\n\t\tif len(src) == 0 {\n\t\t\treturn nil\n\t\t}\n\n\t\t// assumes a simple slice of bytes if 16 bytes\n\t\t// otherwise attempts to parse\n\t\tif len(src) != 16 {\n\t\t\treturn uuid.Scan(string(src))\n\t\t}\n\t\tcopy((*uuid)[:], src)\n\n\tdefault:\n\t\treturn fmt.Errorf(\"Scan: unable to scan type %T into UUID\", src)\n\t}\n\n\treturn nil\n}\n\n// Value implements sql.Valuer so that UUIDs can be written to databases\n// transparently. Currently, UUIDs map to strings. Please consult\n// database-specific driver documentation for matching types.\nfunc (uuid UUID) Value() (driver.Value, error) {\n\treturn uuid.String(), nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/time.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport (\n\t\"encoding/binary\"\n\t\"sync\"\n\t\"time\"\n)\n\n// A Time represents a time as the number of 100's of nanoseconds since 15 Oct\n// 1582.\ntype Time int64\n\nconst (\n\tlillian    = 2299160          // Julian day of 15 Oct 1582\n\tunix       = 2440587          // Julian day of 1 Jan 1970\n\tepoch      = unix - lillian   // Days between epochs\n\tg1582      = epoch * 86400    // seconds between epochs\n\tg1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs\n)\n\nvar (\n\ttimeMu   sync.Mutex\n\tlasttime uint64 // last time we returned\n\tclockSeq uint16 // clock sequence for this run\n\n\ttimeNow = time.Now // for testing\n)\n\n// UnixTime converts t the number of seconds and nanoseconds using the Unix\n// epoch of 1 Jan 1970.\nfunc (t Time) UnixTime() (sec, nsec int64) {\n\tsec = int64(t - g1582ns100)\n\tnsec = (sec % 10000000) * 100\n\tsec /= 10000000\n\treturn sec, nsec\n}\n\n// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and\n// clock sequence as well as adjusting the clock sequence as needed.  An error\n// is returned if the current time cannot be determined.\nfunc GetTime() (Time, uint16, error) {\n\tdefer timeMu.Unlock()\n\ttimeMu.Lock()\n\treturn getTime()\n}\n\nfunc getTime() (Time, uint16, error) {\n\tt := timeNow()\n\n\t// If we don't have a clock sequence already, set one.\n\tif clockSeq == 0 {\n\t\tsetClockSequence(-1)\n\t}\n\tnow := uint64(t.UnixNano()/100) + g1582ns100\n\n\t// If time has gone backwards with this clock sequence then we\n\t// increment the clock sequence\n\tif now <= lasttime {\n\t\tclockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000\n\t}\n\tlasttime = now\n\treturn Time(now), clockSeq, nil\n}\n\n// ClockSequence returns the current clock sequence, generating one if not\n// already set.  The clock sequence is only used for Version 1 UUIDs.\n//\n// The uuid package does not use global static storage for the clock sequence or\n// the last time a UUID was generated.  Unless SetClockSequence is used, a new\n// random clock sequence is generated the first time a clock sequence is\n// requested by ClockSequence, GetTime, or NewUUID.  (section 4.2.1.1)\nfunc ClockSequence() int {\n\tdefer timeMu.Unlock()\n\ttimeMu.Lock()\n\treturn clockSequence()\n}\n\nfunc clockSequence() int {\n\tif clockSeq == 0 {\n\t\tsetClockSequence(-1)\n\t}\n\treturn int(clockSeq & 0x3fff)\n}\n\n// SetClockSequence sets the clock sequence to the lower 14 bits of seq.  Setting to\n// -1 causes a new sequence to be generated.\nfunc SetClockSequence(seq int) {\n\tdefer timeMu.Unlock()\n\ttimeMu.Lock()\n\tsetClockSequence(seq)\n}\n\nfunc setClockSequence(seq int) {\n\tif seq == -1 {\n\t\tvar b [2]byte\n\t\trandomBits(b[:]) // clock sequence\n\t\tseq = int(b[0])<<8 | int(b[1])\n\t}\n\toldSeq := clockSeq\n\tclockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant\n\tif oldSeq != clockSeq {\n\t\tlasttime = 0\n\t}\n}\n\n// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in\n// uuid.  The time is only defined for version 1, 2, 6 and 7 UUIDs.\nfunc (uuid UUID) Time() Time {\n\tvar t Time\n\tswitch uuid.Version() {\n\tcase 6:\n\t\ttime := binary.BigEndian.Uint64(uuid[:8]) // Ignore uuid[6] version b0110\n\t\tt = Time(time)\n\tcase 7:\n\t\ttime := binary.BigEndian.Uint64(uuid[:8])\n\t\tt = Time((time>>16)*10000 + g1582ns100)\n\tdefault: // forward compatible\n\t\ttime := int64(binary.BigEndian.Uint32(uuid[0:4]))\n\t\ttime |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32\n\t\ttime |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48\n\t\tt = Time(time)\n\t}\n\treturn t\n}\n\n// ClockSequence returns the clock sequence encoded in uuid.\n// The clock sequence is only well defined for version 1 and 2 UUIDs.\nfunc (uuid UUID) ClockSequence() int {\n\treturn int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/util.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport (\n\t\"io\"\n)\n\n// randomBits completely fills slice b with random data.\nfunc randomBits(b []byte) {\n\tif _, err := io.ReadFull(rander, b); err != nil {\n\t\tpanic(err.Error()) // rand should never fail\n\t}\n}\n\n// xvalues returns the value of a byte as a hexadecimal digit or 255.\nvar xvalues = [256]byte{\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,\n\t255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n}\n\n// xtob converts hex characters x1 and x2 into a byte.\nfunc xtob(x1, x2 byte) (byte, bool) {\n\tb1 := xvalues[x1]\n\tb2 := xvalues[x2]\n\treturn (b1 << 4) | b2, b1 != 255 && b2 != 255\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/uuid.go",
    "content": "// Copyright 2018 Google Inc.  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 uuid\n\nimport (\n\t\"bytes\"\n\t\"crypto/rand\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\t\"sync\"\n)\n\n// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC\n// 4122.\ntype UUID [16]byte\n\n// A Version represents a UUID's version.\ntype Version byte\n\n// A Variant represents a UUID's variant.\ntype Variant byte\n\n// Constants returned by Variant.\nconst (\n\tInvalid   = Variant(iota) // Invalid UUID\n\tRFC4122                   // The variant specified in RFC4122\n\tReserved                  // Reserved, NCS backward compatibility.\n\tMicrosoft                 // Reserved, Microsoft Corporation backward compatibility.\n\tFuture                    // Reserved for future definition.\n)\n\nconst randPoolSize = 16 * 16\n\nvar (\n\trander      = rand.Reader // random function\n\tpoolEnabled = false\n\tpoolMu      sync.Mutex\n\tpoolPos     = randPoolSize     // protected with poolMu\n\tpool        [randPoolSize]byte // protected with poolMu\n)\n\ntype invalidLengthError struct{ len int }\n\nfunc (err invalidLengthError) Error() string {\n\treturn fmt.Sprintf(\"invalid UUID length: %d\", err.len)\n}\n\n// IsInvalidLengthError is matcher function for custom error invalidLengthError\nfunc IsInvalidLengthError(err error) bool {\n\t_, ok := err.(invalidLengthError)\n\treturn ok\n}\n\n// Parse decodes s into a UUID or returns an error if it cannot be parsed.  Both\n// the standard UUID forms defined in RFC 4122\n// (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and\n// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) are decoded.  In addition,\n// Parse accepts non-standard strings such as the raw hex encoding\n// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx and 38 byte \"Microsoft style\" encodings,\n// e.g.  {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}.  Only the middle 36 bytes are\n// examined in the latter case.  Parse should not be used to validate strings as\n// it parses non-standard encodings as indicated above.\nfunc Parse(s string) (UUID, error) {\n\tvar uuid UUID\n\tswitch len(s) {\n\t// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\tcase 36:\n\n\t// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\tcase 36 + 9:\n\t\tif !strings.EqualFold(s[:9], \"urn:uuid:\") {\n\t\t\treturn uuid, fmt.Errorf(\"invalid urn prefix: %q\", s[:9])\n\t\t}\n\t\ts = s[9:]\n\n\t// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\n\tcase 36 + 2:\n\t\ts = s[1:]\n\n\t// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n\tcase 32:\n\t\tvar ok bool\n\t\tfor i := range uuid {\n\t\t\tuuid[i], ok = xtob(s[i*2], s[i*2+1])\n\t\t\tif !ok {\n\t\t\t\treturn uuid, errors.New(\"invalid UUID format\")\n\t\t\t}\n\t\t}\n\t\treturn uuid, nil\n\tdefault:\n\t\treturn uuid, invalidLengthError{len(s)}\n\t}\n\t// s is now at least 36 bytes long\n\t// it must be of the form  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\tif s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {\n\t\treturn uuid, errors.New(\"invalid UUID format\")\n\t}\n\tfor i, x := range [16]int{\n\t\t0, 2, 4, 6,\n\t\t9, 11,\n\t\t14, 16,\n\t\t19, 21,\n\t\t24, 26, 28, 30, 32, 34,\n\t} {\n\t\tv, ok := xtob(s[x], s[x+1])\n\t\tif !ok {\n\t\t\treturn uuid, errors.New(\"invalid UUID format\")\n\t\t}\n\t\tuuid[i] = v\n\t}\n\treturn uuid, nil\n}\n\n// ParseBytes is like Parse, except it parses a byte slice instead of a string.\nfunc ParseBytes(b []byte) (UUID, error) {\n\tvar uuid UUID\n\tswitch len(b) {\n\tcase 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\tcase 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\t\tif !bytes.EqualFold(b[:9], []byte(\"urn:uuid:\")) {\n\t\t\treturn uuid, fmt.Errorf(\"invalid urn prefix: %q\", b[:9])\n\t\t}\n\t\tb = b[9:]\n\tcase 36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\n\t\tb = b[1:]\n\tcase 32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n\t\tvar ok bool\n\t\tfor i := 0; i < 32; i += 2 {\n\t\t\tuuid[i/2], ok = xtob(b[i], b[i+1])\n\t\t\tif !ok {\n\t\t\t\treturn uuid, errors.New(\"invalid UUID format\")\n\t\t\t}\n\t\t}\n\t\treturn uuid, nil\n\tdefault:\n\t\treturn uuid, invalidLengthError{len(b)}\n\t}\n\t// s is now at least 36 bytes long\n\t// it must be of the form  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\tif b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' {\n\t\treturn uuid, errors.New(\"invalid UUID format\")\n\t}\n\tfor i, x := range [16]int{\n\t\t0, 2, 4, 6,\n\t\t9, 11,\n\t\t14, 16,\n\t\t19, 21,\n\t\t24, 26, 28, 30, 32, 34,\n\t} {\n\t\tv, ok := xtob(b[x], b[x+1])\n\t\tif !ok {\n\t\t\treturn uuid, errors.New(\"invalid UUID format\")\n\t\t}\n\t\tuuid[i] = v\n\t}\n\treturn uuid, nil\n}\n\n// MustParse is like Parse but panics if the string cannot be parsed.\n// It simplifies safe initialization of global variables holding compiled UUIDs.\nfunc MustParse(s string) UUID {\n\tuuid, err := Parse(s)\n\tif err != nil {\n\t\tpanic(`uuid: Parse(` + s + `): ` + err.Error())\n\t}\n\treturn uuid\n}\n\n// FromBytes creates a new UUID from a byte slice. Returns an error if the slice\n// does not have a length of 16. The bytes are copied from the slice.\nfunc FromBytes(b []byte) (uuid UUID, err error) {\n\terr = uuid.UnmarshalBinary(b)\n\treturn uuid, err\n}\n\n// Must returns uuid if err is nil and panics otherwise.\nfunc Must(uuid UUID, err error) UUID {\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn uuid\n}\n\n// Validate returns an error if s is not a properly formatted UUID in one of the following formats:\n//   xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n//   urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n//   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n//   {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\n// It returns an error if the format is invalid, otherwise nil.\nfunc Validate(s string) error {\n\tswitch len(s) {\n\t// Standard UUID format\n\tcase 36:\n\n\t// UUID with \"urn:uuid:\" prefix\n\tcase 36 + 9:\n\t\tif !strings.EqualFold(s[:9], \"urn:uuid:\") {\n\t\t\treturn fmt.Errorf(\"invalid urn prefix: %q\", s[:9])\n\t\t}\n\t\ts = s[9:]\n\n\t// UUID enclosed in braces\n\tcase 36 + 2:\n\t\tif s[0] != '{' || s[len(s)-1] != '}' {\n\t\t\treturn fmt.Errorf(\"invalid bracketed UUID format\")\n\t\t}\n\t\ts = s[1 : len(s)-1]\n\n\t// UUID without hyphens\n\tcase 32:\n\t\tfor i := 0; i < len(s); i += 2 {\n\t\t\t_, ok := xtob(s[i], s[i+1])\n\t\t\tif !ok {\n\t\t\t\treturn errors.New(\"invalid UUID format\")\n\t\t\t}\n\t\t}\n\n\tdefault:\n\t\treturn invalidLengthError{len(s)}\n\t}\n\n\t// Check for standard UUID format\n\tif len(s) == 36 {\n\t\tif s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {\n\t\t\treturn errors.New(\"invalid UUID format\")\n\t\t}\n\t\tfor _, x := range []int{0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34} {\n\t\t\tif _, ok := xtob(s[x], s[x+1]); !ok {\n\t\t\t\treturn errors.New(\"invalid UUID format\")\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n// , or \"\" if uuid is invalid.\nfunc (uuid UUID) String() string {\n\tvar buf [36]byte\n\tencodeHex(buf[:], uuid)\n\treturn string(buf[:])\n}\n\n// URN returns the RFC 2141 URN form of uuid,\n// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,  or \"\" if uuid is invalid.\nfunc (uuid UUID) URN() string {\n\tvar buf [36 + 9]byte\n\tcopy(buf[:], \"urn:uuid:\")\n\tencodeHex(buf[9:], uuid)\n\treturn string(buf[:])\n}\n\nfunc encodeHex(dst []byte, uuid UUID) {\n\thex.Encode(dst, uuid[:4])\n\tdst[8] = '-'\n\thex.Encode(dst[9:13], uuid[4:6])\n\tdst[13] = '-'\n\thex.Encode(dst[14:18], uuid[6:8])\n\tdst[18] = '-'\n\thex.Encode(dst[19:23], uuid[8:10])\n\tdst[23] = '-'\n\thex.Encode(dst[24:], uuid[10:])\n}\n\n// Variant returns the variant encoded in uuid.\nfunc (uuid UUID) Variant() Variant {\n\tswitch {\n\tcase (uuid[8] & 0xc0) == 0x80:\n\t\treturn RFC4122\n\tcase (uuid[8] & 0xe0) == 0xc0:\n\t\treturn Microsoft\n\tcase (uuid[8] & 0xe0) == 0xe0:\n\t\treturn Future\n\tdefault:\n\t\treturn Reserved\n\t}\n}\n\n// Version returns the version of uuid.\nfunc (uuid UUID) Version() Version {\n\treturn Version(uuid[6] >> 4)\n}\n\nfunc (v Version) String() string {\n\tif v > 15 {\n\t\treturn fmt.Sprintf(\"BAD_VERSION_%d\", v)\n\t}\n\treturn fmt.Sprintf(\"VERSION_%d\", v)\n}\n\nfunc (v Variant) String() string {\n\tswitch v {\n\tcase RFC4122:\n\t\treturn \"RFC4122\"\n\tcase Reserved:\n\t\treturn \"Reserved\"\n\tcase Microsoft:\n\t\treturn \"Microsoft\"\n\tcase Future:\n\t\treturn \"Future\"\n\tcase Invalid:\n\t\treturn \"Invalid\"\n\t}\n\treturn fmt.Sprintf(\"BadVariant%d\", int(v))\n}\n\n// SetRand sets the random number generator to r, which implements io.Reader.\n// If r.Read returns an error when the package requests random data then\n// a panic will be issued.\n//\n// Calling SetRand with nil sets the random number generator to the default\n// generator.\nfunc SetRand(r io.Reader) {\n\tif r == nil {\n\t\trander = rand.Reader\n\t\treturn\n\t}\n\trander = r\n}\n\n// EnableRandPool enables internal randomness pool used for Random\n// (Version 4) UUID generation. The pool contains random bytes read from\n// the random number generator on demand in batches. Enabling the pool\n// may improve the UUID generation throughput significantly.\n//\n// Since the pool is stored on the Go heap, this feature may be a bad fit\n// for security sensitive applications.\n//\n// Both EnableRandPool and DisableRandPool are not thread-safe and should\n// only be called when there is no possibility that New or any other\n// UUID Version 4 generation function will be called concurrently.\nfunc EnableRandPool() {\n\tpoolEnabled = true\n}\n\n// DisableRandPool disables the randomness pool if it was previously\n// enabled with EnableRandPool.\n//\n// Both EnableRandPool and DisableRandPool are not thread-safe and should\n// only be called when there is no possibility that New or any other\n// UUID Version 4 generation function will be called concurrently.\nfunc DisableRandPool() {\n\tpoolEnabled = false\n\tdefer poolMu.Unlock()\n\tpoolMu.Lock()\n\tpoolPos = randPoolSize\n}\n\n// UUIDs is a slice of UUID types.\ntype UUIDs []UUID\n\n// Strings returns a string slice containing the string form of each UUID in uuids.\nfunc (uuids UUIDs) Strings() []string {\n\tvar uuidStrs = make([]string, len(uuids))\n\tfor i, uuid := range uuids {\n\t\tuuidStrs[i] = uuid.String()\n\t}\n\treturn uuidStrs\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/version1.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport (\n\t\"encoding/binary\"\n)\n\n// NewUUID returns a Version 1 UUID based on the current NodeID and clock\n// sequence, and the current time.  If the NodeID has not been set by SetNodeID\n// or SetNodeInterface then it will be set automatically.  If the NodeID cannot\n// be set NewUUID returns nil.  If clock sequence has not been set by\n// SetClockSequence then it will be set automatically.  If GetTime fails to\n// return the current NewUUID returns nil and an error.\n//\n// In most cases, New should be used.\nfunc NewUUID() (UUID, error) {\n\tvar uuid UUID\n\tnow, seq, err := GetTime()\n\tif err != nil {\n\t\treturn uuid, err\n\t}\n\n\ttimeLow := uint32(now & 0xffffffff)\n\ttimeMid := uint16((now >> 32) & 0xffff)\n\ttimeHi := uint16((now >> 48) & 0x0fff)\n\ttimeHi |= 0x1000 // Version 1\n\n\tbinary.BigEndian.PutUint32(uuid[0:], timeLow)\n\tbinary.BigEndian.PutUint16(uuid[4:], timeMid)\n\tbinary.BigEndian.PutUint16(uuid[6:], timeHi)\n\tbinary.BigEndian.PutUint16(uuid[8:], seq)\n\n\tnodeMu.Lock()\n\tif nodeID == zeroID {\n\t\tsetNodeInterface(\"\")\n\t}\n\tcopy(uuid[10:], nodeID[:])\n\tnodeMu.Unlock()\n\n\treturn uuid, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/version4.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport \"io\"\n\n// New creates a new random UUID or panics.  New is equivalent to\n// the expression\n//\n//    uuid.Must(uuid.NewRandom())\nfunc New() UUID {\n\treturn Must(NewRandom())\n}\n\n// NewString creates a new random UUID and returns it as a string or panics.\n// NewString is equivalent to the expression\n//\n//    uuid.New().String()\nfunc NewString() string {\n\treturn Must(NewRandom()).String()\n}\n\n// NewRandom returns a Random (Version 4) UUID.\n//\n// The strength of the UUIDs is based on the strength of the crypto/rand\n// package.\n//\n// Uses the randomness pool if it was enabled with EnableRandPool.\n//\n// A note about uniqueness derived from the UUID Wikipedia entry:\n//\n//  Randomly generated UUIDs have 122 random bits.  One's annual risk of being\n//  hit by a meteorite is estimated to be one chance in 17 billion, that\n//  means the probability is about 0.00000000006 (6 × 10−11),\n//  equivalent to the odds of creating a few tens of trillions of UUIDs in a\n//  year and having one duplicate.\nfunc NewRandom() (UUID, error) {\n\tif !poolEnabled {\n\t\treturn NewRandomFromReader(rander)\n\t}\n\treturn newRandomFromPool()\n}\n\n// NewRandomFromReader returns a UUID based on bytes read from a given io.Reader.\nfunc NewRandomFromReader(r io.Reader) (UUID, error) {\n\tvar uuid UUID\n\t_, err := io.ReadFull(r, uuid[:])\n\tif err != nil {\n\t\treturn Nil, err\n\t}\n\tuuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4\n\tuuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10\n\treturn uuid, nil\n}\n\nfunc newRandomFromPool() (UUID, error) {\n\tvar uuid UUID\n\tpoolMu.Lock()\n\tif poolPos == randPoolSize {\n\t\t_, err := io.ReadFull(rander, pool[:])\n\t\tif err != nil {\n\t\t\tpoolMu.Unlock()\n\t\t\treturn Nil, err\n\t\t}\n\t\tpoolPos = 0\n\t}\n\tcopy(uuid[:], pool[poolPos:(poolPos+16)])\n\tpoolPos += 16\n\tpoolMu.Unlock()\n\n\tuuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4\n\tuuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10\n\treturn uuid, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/version6.go",
    "content": "// Copyright 2023 Google Inc.  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 uuid\n\nimport \"encoding/binary\"\n\n// UUID version 6 is a field-compatible version of UUIDv1, reordered for improved DB locality.\n// It is expected that UUIDv6 will primarily be used in contexts where there are existing v1 UUIDs.\n// Systems that do not involve legacy UUIDv1 SHOULD consider using UUIDv7 instead.\n//\n// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#uuidv6\n//\n// NewV6 returns a Version 6 UUID based on the current NodeID and clock\n// sequence, and the current time. If the NodeID has not been set by SetNodeID\n// or SetNodeInterface then it will be set automatically. If the NodeID cannot\n// be set NewV6 set NodeID is random bits automatically . If clock sequence has not been set by\n// SetClockSequence then it will be set automatically. If GetTime fails to\n// return the current NewV6 returns Nil and an error.\nfunc NewV6() (UUID, error) {\n\tvar uuid UUID\n\tnow, seq, err := GetTime()\n\tif err != nil {\n\t\treturn uuid, err\n\t}\n\n\t/*\n\t    0                   1                   2                   3\n\t    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n\t   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\t   |                           time_high                           |\n\t   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\t   |           time_mid            |      time_low_and_version     |\n\t   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\t   |clk_seq_hi_res |  clk_seq_low  |         node (0-1)            |\n\t   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\t   |                         node (2-5)                            |\n\t   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\t*/\n\n\tbinary.BigEndian.PutUint64(uuid[0:], uint64(now))\n\tbinary.BigEndian.PutUint16(uuid[8:], seq)\n\n\tuuid[6] = 0x60 | (uuid[6] & 0x0F)\n\tuuid[8] = 0x80 | (uuid[8] & 0x3F)\n\n\tnodeMu.Lock()\n\tif nodeID == zeroID {\n\t\tsetNodeInterface(\"\")\n\t}\n\tcopy(uuid[10:], nodeID[:])\n\tnodeMu.Unlock()\n\n\treturn uuid, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/version7.go",
    "content": "// Copyright 2023 Google Inc.  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 uuid\n\nimport (\n\t\"io\"\n)\n\n// UUID version 7 features a time-ordered value field derived from the widely\n// implemented and well known Unix Epoch timestamp source,\n// the number of milliseconds seconds since midnight 1 Jan 1970 UTC, leap seconds excluded.\n// As well as improved entropy characteristics over versions 1 or 6.\n//\n// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#name-uuid-version-7\n//\n// Implementations SHOULD utilize UUID version 7 over UUID version 1 and 6 if possible.\n//\n// NewV7 returns a Version 7 UUID based on the current time(Unix Epoch).\n// Uses the randomness pool if it was enabled with EnableRandPool.\n// On error, NewV7 returns Nil and an error\nfunc NewV7() (UUID, error) {\n\tuuid, err := NewRandom()\n\tif err != nil {\n\t\treturn uuid, err\n\t}\n\tmakeV7(uuid[:])\n\treturn uuid, nil\n}\n\n// NewV7FromReader returns a Version 7 UUID based on the current time(Unix Epoch).\n// it use NewRandomFromReader fill random bits.\n// On error, NewV7FromReader returns Nil and an error.\nfunc NewV7FromReader(r io.Reader) (UUID, error) {\n\tuuid, err := NewRandomFromReader(r)\n\tif err != nil {\n\t\treturn uuid, err\n\t}\n\n\tmakeV7(uuid[:])\n\treturn uuid, nil\n}\n\n// makeV7 fill 48 bits time (uuid[0] - uuid[5]), set version b0111 (uuid[6])\n// uuid[8] already has the right version number (Variant is 10)\n// see function NewV7 and NewV7FromReader\nfunc makeV7(uuid []byte) {\n\t/*\n\t\t 0                   1                   2                   3\n\t\t 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\t\t|                           unix_ts_ms                          |\n\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\t\t|          unix_ts_ms           |  ver  |  rand_a (12 bit seq)  |\n\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\t\t|var|                        rand_b                             |\n\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\t\t|                            rand_b                             |\n\t\t+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\t*/\n\t_ = uuid[15] // bounds check\n\n\tt, s := getV7Time()\n\n\tuuid[0] = byte(t >> 40)\n\tuuid[1] = byte(t >> 32)\n\tuuid[2] = byte(t >> 24)\n\tuuid[3] = byte(t >> 16)\n\tuuid[4] = byte(t >> 8)\n\tuuid[5] = byte(t)\n\n\tuuid[6] = 0x70 | (0x0F & byte(s>>8))\n\tuuid[7] = byte(s)\n}\n\n// lastV7time is the last time we returned stored as:\n//\n//\t52 bits of time in milliseconds since epoch\n//\t12 bits of (fractional nanoseconds) >> 8\nvar lastV7time int64\n\nconst nanoPerMilli = 1000000\n\n// getV7Time returns the time in milliseconds and nanoseconds / 256.\n// The returned (milli << 12 + seq) is guarenteed to be greater than\n// (milli << 12 + seq) returned by any previous call to getV7Time.\nfunc getV7Time() (milli, seq int64) {\n\ttimeMu.Lock()\n\tdefer timeMu.Unlock()\n\n\tnano := timeNow().UnixNano()\n\tmilli = nano / nanoPerMilli\n\t// Sequence number is between 0 and 3906 (nanoPerMilli>>8)\n\tseq = (nano - milli*nanoPerMilli) >> 8\n\tnow := milli<<12 + seq\n\tif now <= lastV7time {\n\t\tnow = lastV7time + 1\n\t\tmilli = now >> 12\n\t\tseq = now & 0xfff\n\t}\n\tlastV7time = now\n\treturn milli, seq\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/.gitignore",
    "content": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n\n.idea/\n*.iml\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/AUTHORS",
    "content": "# This is the official list of Gorilla WebSocket authors for copyright\n# purposes.\n#\n# Please keep the list sorted.\n\nGary Burd <gary@beagledreams.com>\nGoogle LLC (https://opensource.google.com/)\nJoachim Bauch <mail@joachim-bauch.de>\n\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/LICENSE",
    "content": "Copyright (c) 2013 The Gorilla WebSocket Authors. All 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\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES 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": "vendor/github.com/gorilla/websocket/README.md",
    "content": "# Gorilla WebSocket\n\n[![GoDoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket)\n[![CircleCI](https://circleci.com/gh/gorilla/websocket.svg?style=svg)](https://circleci.com/gh/gorilla/websocket)\n\nGorilla WebSocket is a [Go](http://golang.org/) implementation of the\n[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol.\n\n\n---\n\n⚠️ **[The Gorilla WebSocket Package is looking for a new maintainer](https://github.com/gorilla/websocket/issues/370)**\n\n---\n\n### Documentation\n\n* [API Reference](https://pkg.go.dev/github.com/gorilla/websocket?tab=doc)\n* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat)\n* [Command example](https://github.com/gorilla/websocket/tree/master/examples/command)\n* [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo)\n* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch)\n\n### Status\n\nThe Gorilla WebSocket package provides a complete and tested implementation of\nthe [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The\npackage API is stable.\n\n### Installation\n\n    go get github.com/gorilla/websocket\n\n### Protocol Compliance\n\nThe Gorilla WebSocket package passes the server tests in the [Autobahn Test\nSuite](https://github.com/crossbario/autobahn-testsuite) using the application in the [examples/autobahn\nsubdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn).\n\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/client.go",
    "content": "// Copyright 2013 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptrace\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n)\n\n// ErrBadHandshake is returned when the server response to opening handshake is\n// invalid.\nvar ErrBadHandshake = errors.New(\"websocket: bad handshake\")\n\nvar errInvalidCompression = errors.New(\"websocket: invalid compression negotiation\")\n\n// NewClient creates a new client connection using the given net connection.\n// The URL u specifies the host and request URI. Use requestHeader to specify\n// the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies\n// (Cookie). Use the response.Header to get the selected subprotocol\n// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).\n//\n// If the WebSocket handshake fails, ErrBadHandshake is returned along with a\n// non-nil *http.Response so that callers can handle redirects, authentication,\n// etc.\n//\n// Deprecated: Use Dialer instead.\nfunc NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) {\n\td := Dialer{\n\t\tReadBufferSize:  readBufSize,\n\t\tWriteBufferSize: writeBufSize,\n\t\tNetDial: func(net, addr string) (net.Conn, error) {\n\t\t\treturn netConn, nil\n\t\t},\n\t}\n\treturn d.Dial(u.String(), requestHeader)\n}\n\n// A Dialer contains options for connecting to WebSocket server.\n//\n// It is safe to call Dialer's methods concurrently.\ntype Dialer struct {\n\t// NetDial specifies the dial function for creating TCP connections. If\n\t// NetDial is nil, net.Dial is used.\n\tNetDial func(network, addr string) (net.Conn, error)\n\n\t// NetDialContext specifies the dial function for creating TCP connections. If\n\t// NetDialContext is nil, NetDial is used.\n\tNetDialContext func(ctx context.Context, network, addr string) (net.Conn, error)\n\n\t// NetDialTLSContext specifies the dial function for creating TLS/TCP connections. If\n\t// NetDialTLSContext is nil, NetDialContext is used.\n\t// If NetDialTLSContext is set, Dial assumes the TLS handshake is done there and\n\t// TLSClientConfig is ignored.\n\tNetDialTLSContext func(ctx context.Context, network, addr string) (net.Conn, error)\n\n\t// Proxy specifies a function to return a proxy for a given\n\t// Request. If the function returns a non-nil error, the\n\t// request is aborted with the provided error.\n\t// If Proxy is nil or returns a nil *URL, no proxy is used.\n\tProxy func(*http.Request) (*url.URL, error)\n\n\t// TLSClientConfig specifies the TLS configuration to use with tls.Client.\n\t// If nil, the default configuration is used.\n\t// If either NetDialTLS or NetDialTLSContext are set, Dial assumes the TLS handshake\n\t// is done there and TLSClientConfig is ignored.\n\tTLSClientConfig *tls.Config\n\n\t// HandshakeTimeout specifies the duration for the handshake to complete.\n\tHandshakeTimeout time.Duration\n\n\t// ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes. If a buffer\n\t// size is zero, then a useful default size is used. The I/O buffer sizes\n\t// do not limit the size of the messages that can be sent or received.\n\tReadBufferSize, WriteBufferSize int\n\n\t// WriteBufferPool is a pool of buffers for write operations. If the value\n\t// is not set, then write buffers are allocated to the connection for the\n\t// lifetime of the connection.\n\t//\n\t// A pool is most useful when the application has a modest volume of writes\n\t// across a large number of connections.\n\t//\n\t// Applications should use a single pool for each unique value of\n\t// WriteBufferSize.\n\tWriteBufferPool BufferPool\n\n\t// Subprotocols specifies the client's requested subprotocols.\n\tSubprotocols []string\n\n\t// EnableCompression specifies if the client should attempt to negotiate\n\t// per message compression (RFC 7692). Setting this value to true does not\n\t// guarantee that compression will be supported. Currently only \"no context\n\t// takeover\" modes are supported.\n\tEnableCompression bool\n\n\t// Jar specifies the cookie jar.\n\t// If Jar is nil, cookies are not sent in requests and ignored\n\t// in responses.\n\tJar http.CookieJar\n}\n\n// Dial creates a new client connection by calling DialContext with a background context.\nfunc (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {\n\treturn d.DialContext(context.Background(), urlStr, requestHeader)\n}\n\nvar errMalformedURL = errors.New(\"malformed ws or wss URL\")\n\nfunc hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) {\n\thostPort = u.Host\n\thostNoPort = u.Host\n\tif i := strings.LastIndex(u.Host, \":\"); i > strings.LastIndex(u.Host, \"]\") {\n\t\thostNoPort = hostNoPort[:i]\n\t} else {\n\t\tswitch u.Scheme {\n\t\tcase \"wss\":\n\t\t\thostPort += \":443\"\n\t\tcase \"https\":\n\t\t\thostPort += \":443\"\n\t\tdefault:\n\t\t\thostPort += \":80\"\n\t\t}\n\t}\n\treturn hostPort, hostNoPort\n}\n\n// DefaultDialer is a dialer with all fields set to the default values.\nvar DefaultDialer = &Dialer{\n\tProxy:            http.ProxyFromEnvironment,\n\tHandshakeTimeout: 45 * time.Second,\n}\n\n// nilDialer is dialer to use when receiver is nil.\nvar nilDialer = *DefaultDialer\n\n// DialContext creates a new client connection. Use requestHeader to specify the\n// origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie).\n// Use the response.Header to get the selected subprotocol\n// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).\n//\n// The context will be used in the request and in the Dialer.\n//\n// If the WebSocket handshake fails, ErrBadHandshake is returned along with a\n// non-nil *http.Response so that callers can handle redirects, authentication,\n// etcetera. The response body may not contain the entire response and does not\n// need to be closed by the application.\nfunc (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {\n\tif d == nil {\n\t\td = &nilDialer\n\t}\n\n\tchallengeKey, err := generateChallengeKey()\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tu, err := url.Parse(urlStr)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tswitch u.Scheme {\n\tcase \"ws\":\n\t\tu.Scheme = \"http\"\n\tcase \"wss\":\n\t\tu.Scheme = \"https\"\n\tdefault:\n\t\treturn nil, nil, errMalformedURL\n\t}\n\n\tif u.User != nil {\n\t\t// User name and password are not allowed in websocket URIs.\n\t\treturn nil, nil, errMalformedURL\n\t}\n\n\treq := &http.Request{\n\t\tMethod:     http.MethodGet,\n\t\tURL:        u,\n\t\tProto:      \"HTTP/1.1\",\n\t\tProtoMajor: 1,\n\t\tProtoMinor: 1,\n\t\tHeader:     make(http.Header),\n\t\tHost:       u.Host,\n\t}\n\treq = req.WithContext(ctx)\n\n\t// Set the cookies present in the cookie jar of the dialer\n\tif d.Jar != nil {\n\t\tfor _, cookie := range d.Jar.Cookies(u) {\n\t\t\treq.AddCookie(cookie)\n\t\t}\n\t}\n\n\t// Set the request headers using the capitalization for names and values in\n\t// RFC examples. Although the capitalization shouldn't matter, there are\n\t// servers that depend on it. The Header.Set method is not used because the\n\t// method canonicalizes the header names.\n\treq.Header[\"Upgrade\"] = []string{\"websocket\"}\n\treq.Header[\"Connection\"] = []string{\"Upgrade\"}\n\treq.Header[\"Sec-WebSocket-Key\"] = []string{challengeKey}\n\treq.Header[\"Sec-WebSocket-Version\"] = []string{\"13\"}\n\tif len(d.Subprotocols) > 0 {\n\t\treq.Header[\"Sec-WebSocket-Protocol\"] = []string{strings.Join(d.Subprotocols, \", \")}\n\t}\n\tfor k, vs := range requestHeader {\n\t\tswitch {\n\t\tcase k == \"Host\":\n\t\t\tif len(vs) > 0 {\n\t\t\t\treq.Host = vs[0]\n\t\t\t}\n\t\tcase k == \"Upgrade\" ||\n\t\t\tk == \"Connection\" ||\n\t\t\tk == \"Sec-Websocket-Key\" ||\n\t\t\tk == \"Sec-Websocket-Version\" ||\n\t\t\tk == \"Sec-Websocket-Extensions\" ||\n\t\t\t(k == \"Sec-Websocket-Protocol\" && len(d.Subprotocols) > 0):\n\t\t\treturn nil, nil, errors.New(\"websocket: duplicate header not allowed: \" + k)\n\t\tcase k == \"Sec-Websocket-Protocol\":\n\t\t\treq.Header[\"Sec-WebSocket-Protocol\"] = vs\n\t\tdefault:\n\t\t\treq.Header[k] = vs\n\t\t}\n\t}\n\n\tif d.EnableCompression {\n\t\treq.Header[\"Sec-WebSocket-Extensions\"] = []string{\"permessage-deflate; server_no_context_takeover; client_no_context_takeover\"}\n\t}\n\n\tif d.HandshakeTimeout != 0 {\n\t\tvar cancel func()\n\t\tctx, cancel = context.WithTimeout(ctx, d.HandshakeTimeout)\n\t\tdefer cancel()\n\t}\n\n\t// Get network dial function.\n\tvar netDial func(network, add string) (net.Conn, error)\n\n\tswitch u.Scheme {\n\tcase \"http\":\n\t\tif d.NetDialContext != nil {\n\t\t\tnetDial = func(network, addr string) (net.Conn, error) {\n\t\t\t\treturn d.NetDialContext(ctx, network, addr)\n\t\t\t}\n\t\t} else if d.NetDial != nil {\n\t\t\tnetDial = d.NetDial\n\t\t}\n\tcase \"https\":\n\t\tif d.NetDialTLSContext != nil {\n\t\t\tnetDial = func(network, addr string) (net.Conn, error) {\n\t\t\t\treturn d.NetDialTLSContext(ctx, network, addr)\n\t\t\t}\n\t\t} else if d.NetDialContext != nil {\n\t\t\tnetDial = func(network, addr string) (net.Conn, error) {\n\t\t\t\treturn d.NetDialContext(ctx, network, addr)\n\t\t\t}\n\t\t} else if d.NetDial != nil {\n\t\t\tnetDial = d.NetDial\n\t\t}\n\tdefault:\n\t\treturn nil, nil, errMalformedURL\n\t}\n\n\tif netDial == nil {\n\t\tnetDialer := &net.Dialer{}\n\t\tnetDial = func(network, addr string) (net.Conn, error) {\n\t\t\treturn netDialer.DialContext(ctx, network, addr)\n\t\t}\n\t}\n\n\t// If needed, wrap the dial function to set the connection deadline.\n\tif deadline, ok := ctx.Deadline(); ok {\n\t\tforwardDial := netDial\n\t\tnetDial = func(network, addr string) (net.Conn, error) {\n\t\t\tc, err := forwardDial(network, addr)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\terr = c.SetDeadline(deadline)\n\t\t\tif err != nil {\n\t\t\t\tc.Close()\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn c, nil\n\t\t}\n\t}\n\n\t// If needed, wrap the dial function to connect through a proxy.\n\tif d.Proxy != nil {\n\t\tproxyURL, err := d.Proxy(req)\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t\tif proxyURL != nil {\n\t\t\tdialer, err := proxy_FromURL(proxyURL, netDialerFunc(netDial))\n\t\t\tif err != nil {\n\t\t\t\treturn nil, nil, err\n\t\t\t}\n\t\t\tnetDial = dialer.Dial\n\t\t}\n\t}\n\n\thostPort, hostNoPort := hostPortNoPort(u)\n\ttrace := httptrace.ContextClientTrace(ctx)\n\tif trace != nil && trace.GetConn != nil {\n\t\ttrace.GetConn(hostPort)\n\t}\n\n\tnetConn, err := netDial(\"tcp\", hostPort)\n\tif trace != nil && trace.GotConn != nil {\n\t\ttrace.GotConn(httptrace.GotConnInfo{\n\t\t\tConn: netConn,\n\t\t})\n\t}\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tdefer func() {\n\t\tif netConn != nil {\n\t\t\tnetConn.Close()\n\t\t}\n\t}()\n\n\tif u.Scheme == \"https\" && d.NetDialTLSContext == nil {\n\t\t// If NetDialTLSContext is set, assume that the TLS handshake has already been done\n\n\t\tcfg := cloneTLSConfig(d.TLSClientConfig)\n\t\tif cfg.ServerName == \"\" {\n\t\t\tcfg.ServerName = hostNoPort\n\t\t}\n\t\ttlsConn := tls.Client(netConn, cfg)\n\t\tnetConn = tlsConn\n\n\t\tif trace != nil && trace.TLSHandshakeStart != nil {\n\t\t\ttrace.TLSHandshakeStart()\n\t\t}\n\t\terr := doHandshake(ctx, tlsConn, cfg)\n\t\tif trace != nil && trace.TLSHandshakeDone != nil {\n\t\t\ttrace.TLSHandshakeDone(tlsConn.ConnectionState(), err)\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t}\n\n\tconn := newConn(netConn, false, d.ReadBufferSize, d.WriteBufferSize, d.WriteBufferPool, nil, nil)\n\n\tif err := req.Write(netConn); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tif trace != nil && trace.GotFirstResponseByte != nil {\n\t\tif peek, err := conn.br.Peek(1); err == nil && len(peek) == 1 {\n\t\t\ttrace.GotFirstResponseByte()\n\t\t}\n\t}\n\n\tresp, err := http.ReadResponse(conn.br, req)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tif d.Jar != nil {\n\t\tif rc := resp.Cookies(); len(rc) > 0 {\n\t\t\td.Jar.SetCookies(u, rc)\n\t\t}\n\t}\n\n\tif resp.StatusCode != 101 ||\n\t\t!tokenListContainsValue(resp.Header, \"Upgrade\", \"websocket\") ||\n\t\t!tokenListContainsValue(resp.Header, \"Connection\", \"upgrade\") ||\n\t\tresp.Header.Get(\"Sec-Websocket-Accept\") != computeAcceptKey(challengeKey) {\n\t\t// Before closing the network connection on return from this\n\t\t// function, slurp up some of the response to aid application\n\t\t// debugging.\n\t\tbuf := make([]byte, 1024)\n\t\tn, _ := io.ReadFull(resp.Body, buf)\n\t\tresp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n]))\n\t\treturn nil, resp, ErrBadHandshake\n\t}\n\n\tfor _, ext := range parseExtensions(resp.Header) {\n\t\tif ext[\"\"] != \"permessage-deflate\" {\n\t\t\tcontinue\n\t\t}\n\t\t_, snct := ext[\"server_no_context_takeover\"]\n\t\t_, cnct := ext[\"client_no_context_takeover\"]\n\t\tif !snct || !cnct {\n\t\t\treturn nil, resp, errInvalidCompression\n\t\t}\n\t\tconn.newCompressionWriter = compressNoContextTakeover\n\t\tconn.newDecompressionReader = decompressNoContextTakeover\n\t\tbreak\n\t}\n\n\tresp.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))\n\tconn.subprotocol = resp.Header.Get(\"Sec-Websocket-Protocol\")\n\n\tnetConn.SetDeadline(time.Time{})\n\tnetConn = nil // to avoid close in defer.\n\treturn conn, resp, nil\n}\n\nfunc cloneTLSConfig(cfg *tls.Config) *tls.Config {\n\tif cfg == nil {\n\t\treturn &tls.Config{}\n\t}\n\treturn cfg.Clone()\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/compression.go",
    "content": "// Copyright 2017 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"compress/flate\"\n\t\"errors\"\n\t\"io\"\n\t\"strings\"\n\t\"sync\"\n)\n\nconst (\n\tminCompressionLevel     = -2 // flate.HuffmanOnly not defined in Go < 1.6\n\tmaxCompressionLevel     = flate.BestCompression\n\tdefaultCompressionLevel = 1\n)\n\nvar (\n\tflateWriterPools [maxCompressionLevel - minCompressionLevel + 1]sync.Pool\n\tflateReaderPool  = sync.Pool{New: func() interface{} {\n\t\treturn flate.NewReader(nil)\n\t}}\n)\n\nfunc decompressNoContextTakeover(r io.Reader) io.ReadCloser {\n\tconst tail =\n\t// Add four bytes as specified in RFC\n\t\"\\x00\\x00\\xff\\xff\" +\n\t\t// Add final block to squelch unexpected EOF error from flate reader.\n\t\t\"\\x01\\x00\\x00\\xff\\xff\"\n\n\tfr, _ := flateReaderPool.Get().(io.ReadCloser)\n\tfr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil)\n\treturn &flateReadWrapper{fr}\n}\n\nfunc isValidCompressionLevel(level int) bool {\n\treturn minCompressionLevel <= level && level <= maxCompressionLevel\n}\n\nfunc compressNoContextTakeover(w io.WriteCloser, level int) io.WriteCloser {\n\tp := &flateWriterPools[level-minCompressionLevel]\n\ttw := &truncWriter{w: w}\n\tfw, _ := p.Get().(*flate.Writer)\n\tif fw == nil {\n\t\tfw, _ = flate.NewWriter(tw, level)\n\t} else {\n\t\tfw.Reset(tw)\n\t}\n\treturn &flateWriteWrapper{fw: fw, tw: tw, p: p}\n}\n\n// truncWriter is an io.Writer that writes all but the last four bytes of the\n// stream to another io.Writer.\ntype truncWriter struct {\n\tw io.WriteCloser\n\tn int\n\tp [4]byte\n}\n\nfunc (w *truncWriter) Write(p []byte) (int, error) {\n\tn := 0\n\n\t// fill buffer first for simplicity.\n\tif w.n < len(w.p) {\n\t\tn = copy(w.p[w.n:], p)\n\t\tp = p[n:]\n\t\tw.n += n\n\t\tif len(p) == 0 {\n\t\t\treturn n, nil\n\t\t}\n\t}\n\n\tm := len(p)\n\tif m > len(w.p) {\n\t\tm = len(w.p)\n\t}\n\n\tif nn, err := w.w.Write(w.p[:m]); err != nil {\n\t\treturn n + nn, err\n\t}\n\n\tcopy(w.p[:], w.p[m:])\n\tcopy(w.p[len(w.p)-m:], p[len(p)-m:])\n\tnn, err := w.w.Write(p[:len(p)-m])\n\treturn n + nn, err\n}\n\ntype flateWriteWrapper struct {\n\tfw *flate.Writer\n\ttw *truncWriter\n\tp  *sync.Pool\n}\n\nfunc (w *flateWriteWrapper) Write(p []byte) (int, error) {\n\tif w.fw == nil {\n\t\treturn 0, errWriteClosed\n\t}\n\treturn w.fw.Write(p)\n}\n\nfunc (w *flateWriteWrapper) Close() error {\n\tif w.fw == nil {\n\t\treturn errWriteClosed\n\t}\n\terr1 := w.fw.Flush()\n\tw.p.Put(w.fw)\n\tw.fw = nil\n\tif w.tw.p != [4]byte{0, 0, 0xff, 0xff} {\n\t\treturn errors.New(\"websocket: internal error, unexpected bytes at end of flate stream\")\n\t}\n\terr2 := w.tw.w.Close()\n\tif err1 != nil {\n\t\treturn err1\n\t}\n\treturn err2\n}\n\ntype flateReadWrapper struct {\n\tfr io.ReadCloser\n}\n\nfunc (r *flateReadWrapper) Read(p []byte) (int, error) {\n\tif r.fr == nil {\n\t\treturn 0, io.ErrClosedPipe\n\t}\n\tn, err := r.fr.Read(p)\n\tif err == io.EOF {\n\t\t// Preemptively place the reader back in the pool. This helps with\n\t\t// scenarios where the application does not call NextReader() soon after\n\t\t// this final read.\n\t\tr.Close()\n\t}\n\treturn n, err\n}\n\nfunc (r *flateReadWrapper) Close() error {\n\tif r.fr == nil {\n\t\treturn io.ErrClosedPipe\n\t}\n\terr := r.fr.Close()\n\tflateReaderPool.Put(r.fr)\n\tr.fr = nil\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/conn.go",
    "content": "// Copyright 2013 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"bufio\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"math/rand\"\n\t\"net\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\t\"unicode/utf8\"\n)\n\nconst (\n\t// Frame header byte 0 bits from Section 5.2 of RFC 6455\n\tfinalBit = 1 << 7\n\trsv1Bit  = 1 << 6\n\trsv2Bit  = 1 << 5\n\trsv3Bit  = 1 << 4\n\n\t// Frame header byte 1 bits from Section 5.2 of RFC 6455\n\tmaskBit = 1 << 7\n\n\tmaxFrameHeaderSize         = 2 + 8 + 4 // Fixed header + length + mask\n\tmaxControlFramePayloadSize = 125\n\n\twriteWait = time.Second\n\n\tdefaultReadBufferSize  = 4096\n\tdefaultWriteBufferSize = 4096\n\n\tcontinuationFrame = 0\n\tnoFrame           = -1\n)\n\n// Close codes defined in RFC 6455, section 11.7.\nconst (\n\tCloseNormalClosure           = 1000\n\tCloseGoingAway               = 1001\n\tCloseProtocolError           = 1002\n\tCloseUnsupportedData         = 1003\n\tCloseNoStatusReceived        = 1005\n\tCloseAbnormalClosure         = 1006\n\tCloseInvalidFramePayloadData = 1007\n\tClosePolicyViolation         = 1008\n\tCloseMessageTooBig           = 1009\n\tCloseMandatoryExtension      = 1010\n\tCloseInternalServerErr       = 1011\n\tCloseServiceRestart          = 1012\n\tCloseTryAgainLater           = 1013\n\tCloseTLSHandshake            = 1015\n)\n\n// The message types are defined in RFC 6455, section 11.8.\nconst (\n\t// TextMessage denotes a text data message. The text message payload is\n\t// interpreted as UTF-8 encoded text data.\n\tTextMessage = 1\n\n\t// BinaryMessage denotes a binary data message.\n\tBinaryMessage = 2\n\n\t// CloseMessage denotes a close control message. The optional message\n\t// payload contains a numeric code and text. Use the FormatCloseMessage\n\t// function to format a close message payload.\n\tCloseMessage = 8\n\n\t// PingMessage denotes a ping control message. The optional message payload\n\t// is UTF-8 encoded text.\n\tPingMessage = 9\n\n\t// PongMessage denotes a pong control message. The optional message payload\n\t// is UTF-8 encoded text.\n\tPongMessage = 10\n)\n\n// ErrCloseSent is returned when the application writes a message to the\n// connection after sending a close message.\nvar ErrCloseSent = errors.New(\"websocket: close sent\")\n\n// ErrReadLimit is returned when reading a message that is larger than the\n// read limit set for the connection.\nvar ErrReadLimit = errors.New(\"websocket: read limit exceeded\")\n\n// netError satisfies the net Error interface.\ntype netError struct {\n\tmsg       string\n\ttemporary bool\n\ttimeout   bool\n}\n\nfunc (e *netError) Error() string   { return e.msg }\nfunc (e *netError) Temporary() bool { return e.temporary }\nfunc (e *netError) Timeout() bool   { return e.timeout }\n\n// CloseError represents a close message.\ntype CloseError struct {\n\t// Code is defined in RFC 6455, section 11.7.\n\tCode int\n\n\t// Text is the optional text payload.\n\tText string\n}\n\nfunc (e *CloseError) Error() string {\n\ts := []byte(\"websocket: close \")\n\ts = strconv.AppendInt(s, int64(e.Code), 10)\n\tswitch e.Code {\n\tcase CloseNormalClosure:\n\t\ts = append(s, \" (normal)\"...)\n\tcase CloseGoingAway:\n\t\ts = append(s, \" (going away)\"...)\n\tcase CloseProtocolError:\n\t\ts = append(s, \" (protocol error)\"...)\n\tcase CloseUnsupportedData:\n\t\ts = append(s, \" (unsupported data)\"...)\n\tcase CloseNoStatusReceived:\n\t\ts = append(s, \" (no status)\"...)\n\tcase CloseAbnormalClosure:\n\t\ts = append(s, \" (abnormal closure)\"...)\n\tcase CloseInvalidFramePayloadData:\n\t\ts = append(s, \" (invalid payload data)\"...)\n\tcase ClosePolicyViolation:\n\t\ts = append(s, \" (policy violation)\"...)\n\tcase CloseMessageTooBig:\n\t\ts = append(s, \" (message too big)\"...)\n\tcase CloseMandatoryExtension:\n\t\ts = append(s, \" (mandatory extension missing)\"...)\n\tcase CloseInternalServerErr:\n\t\ts = append(s, \" (internal server error)\"...)\n\tcase CloseTLSHandshake:\n\t\ts = append(s, \" (TLS handshake error)\"...)\n\t}\n\tif e.Text != \"\" {\n\t\ts = append(s, \": \"...)\n\t\ts = append(s, e.Text...)\n\t}\n\treturn string(s)\n}\n\n// IsCloseError returns boolean indicating whether the error is a *CloseError\n// with one of the specified codes.\nfunc IsCloseError(err error, codes ...int) bool {\n\tif e, ok := err.(*CloseError); ok {\n\t\tfor _, code := range codes {\n\t\t\tif e.Code == code {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\n// IsUnexpectedCloseError returns boolean indicating whether the error is a\n// *CloseError with a code not in the list of expected codes.\nfunc IsUnexpectedCloseError(err error, expectedCodes ...int) bool {\n\tif e, ok := err.(*CloseError); ok {\n\t\tfor _, code := range expectedCodes {\n\t\t\tif e.Code == code {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\treturn false\n}\n\nvar (\n\terrWriteTimeout        = &netError{msg: \"websocket: write timeout\", timeout: true, temporary: true}\n\terrUnexpectedEOF       = &CloseError{Code: CloseAbnormalClosure, Text: io.ErrUnexpectedEOF.Error()}\n\terrBadWriteOpCode      = errors.New(\"websocket: bad write message type\")\n\terrWriteClosed         = errors.New(\"websocket: write closed\")\n\terrInvalidControlFrame = errors.New(\"websocket: invalid control frame\")\n)\n\nfunc newMaskKey() [4]byte {\n\tn := rand.Uint32()\n\treturn [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)}\n}\n\nfunc hideTempErr(err error) error {\n\tif e, ok := err.(net.Error); ok && e.Temporary() {\n\t\terr = &netError{msg: e.Error(), timeout: e.Timeout()}\n\t}\n\treturn err\n}\n\nfunc isControl(frameType int) bool {\n\treturn frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage\n}\n\nfunc isData(frameType int) bool {\n\treturn frameType == TextMessage || frameType == BinaryMessage\n}\n\nvar validReceivedCloseCodes = map[int]bool{\n\t// see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number\n\n\tCloseNormalClosure:           true,\n\tCloseGoingAway:               true,\n\tCloseProtocolError:           true,\n\tCloseUnsupportedData:         true,\n\tCloseNoStatusReceived:        false,\n\tCloseAbnormalClosure:         false,\n\tCloseInvalidFramePayloadData: true,\n\tClosePolicyViolation:         true,\n\tCloseMessageTooBig:           true,\n\tCloseMandatoryExtension:      true,\n\tCloseInternalServerErr:       true,\n\tCloseServiceRestart:          true,\n\tCloseTryAgainLater:           true,\n\tCloseTLSHandshake:            false,\n}\n\nfunc isValidReceivedCloseCode(code int) bool {\n\treturn validReceivedCloseCodes[code] || (code >= 3000 && code <= 4999)\n}\n\n// BufferPool represents a pool of buffers. The *sync.Pool type satisfies this\n// interface.  The type of the value stored in a pool is not specified.\ntype BufferPool interface {\n\t// Get gets a value from the pool or returns nil if the pool is empty.\n\tGet() interface{}\n\t// Put adds a value to the pool.\n\tPut(interface{})\n}\n\n// writePoolData is the type added to the write buffer pool. This wrapper is\n// used to prevent applications from peeking at and depending on the values\n// added to the pool.\ntype writePoolData struct{ buf []byte }\n\n// The Conn type represents a WebSocket connection.\ntype Conn struct {\n\tconn        net.Conn\n\tisServer    bool\n\tsubprotocol string\n\n\t// Write fields\n\tmu            chan struct{} // used as mutex to protect write to conn\n\twriteBuf      []byte        // frame is constructed in this buffer.\n\twritePool     BufferPool\n\twriteBufSize  int\n\twriteDeadline time.Time\n\twriter        io.WriteCloser // the current writer returned to the application\n\tisWriting     bool           // for best-effort concurrent write detection\n\n\twriteErrMu sync.Mutex\n\twriteErr   error\n\n\tenableWriteCompression bool\n\tcompressionLevel       int\n\tnewCompressionWriter   func(io.WriteCloser, int) io.WriteCloser\n\n\t// Read fields\n\treader  io.ReadCloser // the current reader returned to the application\n\treadErr error\n\tbr      *bufio.Reader\n\t// bytes remaining in current frame.\n\t// set setReadRemaining to safely update this value and prevent overflow\n\treadRemaining int64\n\treadFinal     bool  // true the current message has more frames.\n\treadLength    int64 // Message size.\n\treadLimit     int64 // Maximum message size.\n\treadMaskPos   int\n\treadMaskKey   [4]byte\n\thandlePong    func(string) error\n\thandlePing    func(string) error\n\thandleClose   func(int, string) error\n\treadErrCount  int\n\tmessageReader *messageReader // the current low-level reader\n\n\treadDecompress         bool // whether last read frame had RSV1 set\n\tnewDecompressionReader func(io.Reader) io.ReadCloser\n}\n\nfunc newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int, writeBufferPool BufferPool, br *bufio.Reader, writeBuf []byte) *Conn {\n\n\tif br == nil {\n\t\tif readBufferSize == 0 {\n\t\t\treadBufferSize = defaultReadBufferSize\n\t\t} else if readBufferSize < maxControlFramePayloadSize {\n\t\t\t// must be large enough for control frame\n\t\t\treadBufferSize = maxControlFramePayloadSize\n\t\t}\n\t\tbr = bufio.NewReaderSize(conn, readBufferSize)\n\t}\n\n\tif writeBufferSize <= 0 {\n\t\twriteBufferSize = defaultWriteBufferSize\n\t}\n\twriteBufferSize += maxFrameHeaderSize\n\n\tif writeBuf == nil && writeBufferPool == nil {\n\t\twriteBuf = make([]byte, writeBufferSize)\n\t}\n\n\tmu := make(chan struct{}, 1)\n\tmu <- struct{}{}\n\tc := &Conn{\n\t\tisServer:               isServer,\n\t\tbr:                     br,\n\t\tconn:                   conn,\n\t\tmu:                     mu,\n\t\treadFinal:              true,\n\t\twriteBuf:               writeBuf,\n\t\twritePool:              writeBufferPool,\n\t\twriteBufSize:           writeBufferSize,\n\t\tenableWriteCompression: true,\n\t\tcompressionLevel:       defaultCompressionLevel,\n\t}\n\tc.SetCloseHandler(nil)\n\tc.SetPingHandler(nil)\n\tc.SetPongHandler(nil)\n\treturn c\n}\n\n// setReadRemaining tracks the number of bytes remaining on the connection. If n\n// overflows, an ErrReadLimit is returned.\nfunc (c *Conn) setReadRemaining(n int64) error {\n\tif n < 0 {\n\t\treturn ErrReadLimit\n\t}\n\n\tc.readRemaining = n\n\treturn nil\n}\n\n// Subprotocol returns the negotiated protocol for the connection.\nfunc (c *Conn) Subprotocol() string {\n\treturn c.subprotocol\n}\n\n// Close closes the underlying network connection without sending or waiting\n// for a close message.\nfunc (c *Conn) Close() error {\n\treturn c.conn.Close()\n}\n\n// LocalAddr returns the local network address.\nfunc (c *Conn) LocalAddr() net.Addr {\n\treturn c.conn.LocalAddr()\n}\n\n// RemoteAddr returns the remote network address.\nfunc (c *Conn) RemoteAddr() net.Addr {\n\treturn c.conn.RemoteAddr()\n}\n\n// Write methods\n\nfunc (c *Conn) writeFatal(err error) error {\n\terr = hideTempErr(err)\n\tc.writeErrMu.Lock()\n\tif c.writeErr == nil {\n\t\tc.writeErr = err\n\t}\n\tc.writeErrMu.Unlock()\n\treturn err\n}\n\nfunc (c *Conn) read(n int) ([]byte, error) {\n\tp, err := c.br.Peek(n)\n\tif err == io.EOF {\n\t\terr = errUnexpectedEOF\n\t}\n\tc.br.Discard(len(p))\n\treturn p, err\n}\n\nfunc (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error {\n\t<-c.mu\n\tdefer func() { c.mu <- struct{}{} }()\n\n\tc.writeErrMu.Lock()\n\terr := c.writeErr\n\tc.writeErrMu.Unlock()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tc.conn.SetWriteDeadline(deadline)\n\tif len(buf1) == 0 {\n\t\t_, err = c.conn.Write(buf0)\n\t} else {\n\t\terr = c.writeBufs(buf0, buf1)\n\t}\n\tif err != nil {\n\t\treturn c.writeFatal(err)\n\t}\n\tif frameType == CloseMessage {\n\t\tc.writeFatal(ErrCloseSent)\n\t}\n\treturn nil\n}\n\nfunc (c *Conn) writeBufs(bufs ...[]byte) error {\n\tb := net.Buffers(bufs)\n\t_, err := b.WriteTo(c.conn)\n\treturn err\n}\n\n// WriteControl writes a control message with the given deadline. The allowed\n// message types are CloseMessage, PingMessage and PongMessage.\nfunc (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error {\n\tif !isControl(messageType) {\n\t\treturn errBadWriteOpCode\n\t}\n\tif len(data) > maxControlFramePayloadSize {\n\t\treturn errInvalidControlFrame\n\t}\n\n\tb0 := byte(messageType) | finalBit\n\tb1 := byte(len(data))\n\tif !c.isServer {\n\t\tb1 |= maskBit\n\t}\n\n\tbuf := make([]byte, 0, maxFrameHeaderSize+maxControlFramePayloadSize)\n\tbuf = append(buf, b0, b1)\n\n\tif c.isServer {\n\t\tbuf = append(buf, data...)\n\t} else {\n\t\tkey := newMaskKey()\n\t\tbuf = append(buf, key[:]...)\n\t\tbuf = append(buf, data...)\n\t\tmaskBytes(key, 0, buf[6:])\n\t}\n\n\td := 1000 * time.Hour\n\tif !deadline.IsZero() {\n\t\td = deadline.Sub(time.Now())\n\t\tif d < 0 {\n\t\t\treturn errWriteTimeout\n\t\t}\n\t}\n\n\ttimer := time.NewTimer(d)\n\tselect {\n\tcase <-c.mu:\n\t\ttimer.Stop()\n\tcase <-timer.C:\n\t\treturn errWriteTimeout\n\t}\n\tdefer func() { c.mu <- struct{}{} }()\n\n\tc.writeErrMu.Lock()\n\terr := c.writeErr\n\tc.writeErrMu.Unlock()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tc.conn.SetWriteDeadline(deadline)\n\t_, err = c.conn.Write(buf)\n\tif err != nil {\n\t\treturn c.writeFatal(err)\n\t}\n\tif messageType == CloseMessage {\n\t\tc.writeFatal(ErrCloseSent)\n\t}\n\treturn err\n}\n\n// beginMessage prepares a connection and message writer for a new message.\nfunc (c *Conn) beginMessage(mw *messageWriter, messageType int) error {\n\t// Close previous writer if not already closed by the application. It's\n\t// probably better to return an error in this situation, but we cannot\n\t// change this without breaking existing applications.\n\tif c.writer != nil {\n\t\tc.writer.Close()\n\t\tc.writer = nil\n\t}\n\n\tif !isControl(messageType) && !isData(messageType) {\n\t\treturn errBadWriteOpCode\n\t}\n\n\tc.writeErrMu.Lock()\n\terr := c.writeErr\n\tc.writeErrMu.Unlock()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tmw.c = c\n\tmw.frameType = messageType\n\tmw.pos = maxFrameHeaderSize\n\n\tif c.writeBuf == nil {\n\t\twpd, ok := c.writePool.Get().(writePoolData)\n\t\tif ok {\n\t\t\tc.writeBuf = wpd.buf\n\t\t} else {\n\t\t\tc.writeBuf = make([]byte, c.writeBufSize)\n\t\t}\n\t}\n\treturn nil\n}\n\n// NextWriter returns a writer for the next message to send. The writer's Close\n// method flushes the complete message to the network.\n//\n// There can be at most one open writer on a connection. NextWriter closes the\n// previous writer if the application has not already done so.\n//\n// All message types (TextMessage, BinaryMessage, CloseMessage, PingMessage and\n// PongMessage) are supported.\nfunc (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) {\n\tvar mw messageWriter\n\tif err := c.beginMessage(&mw, messageType); err != nil {\n\t\treturn nil, err\n\t}\n\tc.writer = &mw\n\tif c.newCompressionWriter != nil && c.enableWriteCompression && isData(messageType) {\n\t\tw := c.newCompressionWriter(c.writer, c.compressionLevel)\n\t\tmw.compress = true\n\t\tc.writer = w\n\t}\n\treturn c.writer, nil\n}\n\ntype messageWriter struct {\n\tc         *Conn\n\tcompress  bool // whether next call to flushFrame should set RSV1\n\tpos       int  // end of data in writeBuf.\n\tframeType int  // type of the current frame.\n\terr       error\n}\n\nfunc (w *messageWriter) endMessage(err error) error {\n\tif w.err != nil {\n\t\treturn err\n\t}\n\tc := w.c\n\tw.err = err\n\tc.writer = nil\n\tif c.writePool != nil {\n\t\tc.writePool.Put(writePoolData{buf: c.writeBuf})\n\t\tc.writeBuf = nil\n\t}\n\treturn err\n}\n\n// flushFrame writes buffered data and extra as a frame to the network. The\n// final argument indicates that this is the last frame in the message.\nfunc (w *messageWriter) flushFrame(final bool, extra []byte) error {\n\tc := w.c\n\tlength := w.pos - maxFrameHeaderSize + len(extra)\n\n\t// Check for invalid control frames.\n\tif isControl(w.frameType) &&\n\t\t(!final || length > maxControlFramePayloadSize) {\n\t\treturn w.endMessage(errInvalidControlFrame)\n\t}\n\n\tb0 := byte(w.frameType)\n\tif final {\n\t\tb0 |= finalBit\n\t}\n\tif w.compress {\n\t\tb0 |= rsv1Bit\n\t}\n\tw.compress = false\n\n\tb1 := byte(0)\n\tif !c.isServer {\n\t\tb1 |= maskBit\n\t}\n\n\t// Assume that the frame starts at beginning of c.writeBuf.\n\tframePos := 0\n\tif c.isServer {\n\t\t// Adjust up if mask not included in the header.\n\t\tframePos = 4\n\t}\n\n\tswitch {\n\tcase length >= 65536:\n\t\tc.writeBuf[framePos] = b0\n\t\tc.writeBuf[framePos+1] = b1 | 127\n\t\tbinary.BigEndian.PutUint64(c.writeBuf[framePos+2:], uint64(length))\n\tcase length > 125:\n\t\tframePos += 6\n\t\tc.writeBuf[framePos] = b0\n\t\tc.writeBuf[framePos+1] = b1 | 126\n\t\tbinary.BigEndian.PutUint16(c.writeBuf[framePos+2:], uint16(length))\n\tdefault:\n\t\tframePos += 8\n\t\tc.writeBuf[framePos] = b0\n\t\tc.writeBuf[framePos+1] = b1 | byte(length)\n\t}\n\n\tif !c.isServer {\n\t\tkey := newMaskKey()\n\t\tcopy(c.writeBuf[maxFrameHeaderSize-4:], key[:])\n\t\tmaskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:w.pos])\n\t\tif len(extra) > 0 {\n\t\t\treturn w.endMessage(c.writeFatal(errors.New(\"websocket: internal error, extra used in client mode\")))\n\t\t}\n\t}\n\n\t// Write the buffers to the connection with best-effort detection of\n\t// concurrent writes. See the concurrency section in the package\n\t// documentation for more info.\n\n\tif c.isWriting {\n\t\tpanic(\"concurrent write to websocket connection\")\n\t}\n\tc.isWriting = true\n\n\terr := c.write(w.frameType, c.writeDeadline, c.writeBuf[framePos:w.pos], extra)\n\n\tif !c.isWriting {\n\t\tpanic(\"concurrent write to websocket connection\")\n\t}\n\tc.isWriting = false\n\n\tif err != nil {\n\t\treturn w.endMessage(err)\n\t}\n\n\tif final {\n\t\tw.endMessage(errWriteClosed)\n\t\treturn nil\n\t}\n\n\t// Setup for next frame.\n\tw.pos = maxFrameHeaderSize\n\tw.frameType = continuationFrame\n\treturn nil\n}\n\nfunc (w *messageWriter) ncopy(max int) (int, error) {\n\tn := len(w.c.writeBuf) - w.pos\n\tif n <= 0 {\n\t\tif err := w.flushFrame(false, nil); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tn = len(w.c.writeBuf) - w.pos\n\t}\n\tif n > max {\n\t\tn = max\n\t}\n\treturn n, nil\n}\n\nfunc (w *messageWriter) Write(p []byte) (int, error) {\n\tif w.err != nil {\n\t\treturn 0, w.err\n\t}\n\n\tif len(p) > 2*len(w.c.writeBuf) && w.c.isServer {\n\t\t// Don't buffer large messages.\n\t\terr := w.flushFrame(false, p)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn len(p), nil\n\t}\n\n\tnn := len(p)\n\tfor len(p) > 0 {\n\t\tn, err := w.ncopy(len(p))\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tcopy(w.c.writeBuf[w.pos:], p[:n])\n\t\tw.pos += n\n\t\tp = p[n:]\n\t}\n\treturn nn, nil\n}\n\nfunc (w *messageWriter) WriteString(p string) (int, error) {\n\tif w.err != nil {\n\t\treturn 0, w.err\n\t}\n\n\tnn := len(p)\n\tfor len(p) > 0 {\n\t\tn, err := w.ncopy(len(p))\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tcopy(w.c.writeBuf[w.pos:], p[:n])\n\t\tw.pos += n\n\t\tp = p[n:]\n\t}\n\treturn nn, nil\n}\n\nfunc (w *messageWriter) ReadFrom(r io.Reader) (nn int64, err error) {\n\tif w.err != nil {\n\t\treturn 0, w.err\n\t}\n\tfor {\n\t\tif w.pos == len(w.c.writeBuf) {\n\t\t\terr = w.flushFrame(false, nil)\n\t\t\tif err != nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tvar n int\n\t\tn, err = r.Read(w.c.writeBuf[w.pos:])\n\t\tw.pos += n\n\t\tnn += int64(n)\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\terr = nil\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\treturn nn, err\n}\n\nfunc (w *messageWriter) Close() error {\n\tif w.err != nil {\n\t\treturn w.err\n\t}\n\treturn w.flushFrame(true, nil)\n}\n\n// WritePreparedMessage writes prepared message into connection.\nfunc (c *Conn) WritePreparedMessage(pm *PreparedMessage) error {\n\tframeType, frameData, err := pm.frame(prepareKey{\n\t\tisServer:         c.isServer,\n\t\tcompress:         c.newCompressionWriter != nil && c.enableWriteCompression && isData(pm.messageType),\n\t\tcompressionLevel: c.compressionLevel,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\tif c.isWriting {\n\t\tpanic(\"concurrent write to websocket connection\")\n\t}\n\tc.isWriting = true\n\terr = c.write(frameType, c.writeDeadline, frameData, nil)\n\tif !c.isWriting {\n\t\tpanic(\"concurrent write to websocket connection\")\n\t}\n\tc.isWriting = false\n\treturn err\n}\n\n// WriteMessage is a helper method for getting a writer using NextWriter,\n// writing the message and closing the writer.\nfunc (c *Conn) WriteMessage(messageType int, data []byte) error {\n\n\tif c.isServer && (c.newCompressionWriter == nil || !c.enableWriteCompression) {\n\t\t// Fast path with no allocations and single frame.\n\n\t\tvar mw messageWriter\n\t\tif err := c.beginMessage(&mw, messageType); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tn := copy(c.writeBuf[mw.pos:], data)\n\t\tmw.pos += n\n\t\tdata = data[n:]\n\t\treturn mw.flushFrame(true, data)\n\t}\n\n\tw, err := c.NextWriter(messageType)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif _, err = w.Write(data); err != nil {\n\t\treturn err\n\t}\n\treturn w.Close()\n}\n\n// SetWriteDeadline sets the write deadline on the underlying network\n// connection. After a write has timed out, the websocket state is corrupt and\n// all future writes will return an error. A zero value for t means writes will\n// not time out.\nfunc (c *Conn) SetWriteDeadline(t time.Time) error {\n\tc.writeDeadline = t\n\treturn nil\n}\n\n// Read methods\n\nfunc (c *Conn) advanceFrame() (int, error) {\n\t// 1. Skip remainder of previous frame.\n\n\tif c.readRemaining > 0 {\n\t\tif _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\t}\n\n\t// 2. Read and parse first two bytes of frame header.\n\t// To aid debugging, collect and report all errors in the first two bytes\n\t// of the header.\n\n\tvar errors []string\n\n\tp, err := c.read(2)\n\tif err != nil {\n\t\treturn noFrame, err\n\t}\n\n\tframeType := int(p[0] & 0xf)\n\tfinal := p[0]&finalBit != 0\n\trsv1 := p[0]&rsv1Bit != 0\n\trsv2 := p[0]&rsv2Bit != 0\n\trsv3 := p[0]&rsv3Bit != 0\n\tmask := p[1]&maskBit != 0\n\tc.setReadRemaining(int64(p[1] & 0x7f))\n\n\tc.readDecompress = false\n\tif rsv1 {\n\t\tif c.newDecompressionReader != nil {\n\t\t\tc.readDecompress = true\n\t\t} else {\n\t\t\terrors = append(errors, \"RSV1 set\")\n\t\t}\n\t}\n\n\tif rsv2 {\n\t\terrors = append(errors, \"RSV2 set\")\n\t}\n\n\tif rsv3 {\n\t\terrors = append(errors, \"RSV3 set\")\n\t}\n\n\tswitch frameType {\n\tcase CloseMessage, PingMessage, PongMessage:\n\t\tif c.readRemaining > maxControlFramePayloadSize {\n\t\t\terrors = append(errors, \"len > 125 for control\")\n\t\t}\n\t\tif !final {\n\t\t\terrors = append(errors, \"FIN not set on control\")\n\t\t}\n\tcase TextMessage, BinaryMessage:\n\t\tif !c.readFinal {\n\t\t\terrors = append(errors, \"data before FIN\")\n\t\t}\n\t\tc.readFinal = final\n\tcase continuationFrame:\n\t\tif c.readFinal {\n\t\t\terrors = append(errors, \"continuation after FIN\")\n\t\t}\n\t\tc.readFinal = final\n\tdefault:\n\t\terrors = append(errors, \"bad opcode \"+strconv.Itoa(frameType))\n\t}\n\n\tif mask != c.isServer {\n\t\terrors = append(errors, \"bad MASK\")\n\t}\n\n\tif len(errors) > 0 {\n\t\treturn noFrame, c.handleProtocolError(strings.Join(errors, \", \"))\n\t}\n\n\t// 3. Read and parse frame length as per\n\t// https://tools.ietf.org/html/rfc6455#section-5.2\n\t//\n\t// The length of the \"Payload data\", in bytes: if 0-125, that is the payload\n\t// length.\n\t// - If 126, the following 2 bytes interpreted as a 16-bit unsigned\n\t// integer are the payload length.\n\t// - If 127, the following 8 bytes interpreted as\n\t// a 64-bit unsigned integer (the most significant bit MUST be 0) are the\n\t// payload length. Multibyte length quantities are expressed in network byte\n\t// order.\n\n\tswitch c.readRemaining {\n\tcase 126:\n\t\tp, err := c.read(2)\n\t\tif err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\n\t\tif err := c.setReadRemaining(int64(binary.BigEndian.Uint16(p))); err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\tcase 127:\n\t\tp, err := c.read(8)\n\t\tif err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\n\t\tif err := c.setReadRemaining(int64(binary.BigEndian.Uint64(p))); err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\t}\n\n\t// 4. Handle frame masking.\n\n\tif mask {\n\t\tc.readMaskPos = 0\n\t\tp, err := c.read(len(c.readMaskKey))\n\t\tif err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\t\tcopy(c.readMaskKey[:], p)\n\t}\n\n\t// 5. For text and binary messages, enforce read limit and return.\n\n\tif frameType == continuationFrame || frameType == TextMessage || frameType == BinaryMessage {\n\n\t\tc.readLength += c.readRemaining\n\t\t// Don't allow readLength to overflow in the presence of a large readRemaining\n\t\t// counter.\n\t\tif c.readLength < 0 {\n\t\t\treturn noFrame, ErrReadLimit\n\t\t}\n\n\t\tif c.readLimit > 0 && c.readLength > c.readLimit {\n\t\t\tc.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, \"\"), time.Now().Add(writeWait))\n\t\t\treturn noFrame, ErrReadLimit\n\t\t}\n\n\t\treturn frameType, nil\n\t}\n\n\t// 6. Read control frame payload.\n\n\tvar payload []byte\n\tif c.readRemaining > 0 {\n\t\tpayload, err = c.read(int(c.readRemaining))\n\t\tc.setReadRemaining(0)\n\t\tif err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\t\tif c.isServer {\n\t\t\tmaskBytes(c.readMaskKey, 0, payload)\n\t\t}\n\t}\n\n\t// 7. Process control frame payload.\n\n\tswitch frameType {\n\tcase PongMessage:\n\t\tif err := c.handlePong(string(payload)); err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\tcase PingMessage:\n\t\tif err := c.handlePing(string(payload)); err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\tcase CloseMessage:\n\t\tcloseCode := CloseNoStatusReceived\n\t\tcloseText := \"\"\n\t\tif len(payload) >= 2 {\n\t\t\tcloseCode = int(binary.BigEndian.Uint16(payload))\n\t\t\tif !isValidReceivedCloseCode(closeCode) {\n\t\t\t\treturn noFrame, c.handleProtocolError(\"bad close code \" + strconv.Itoa(closeCode))\n\t\t\t}\n\t\t\tcloseText = string(payload[2:])\n\t\t\tif !utf8.ValidString(closeText) {\n\t\t\t\treturn noFrame, c.handleProtocolError(\"invalid utf8 payload in close frame\")\n\t\t\t}\n\t\t}\n\t\tif err := c.handleClose(closeCode, closeText); err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\t\treturn noFrame, &CloseError{Code: closeCode, Text: closeText}\n\t}\n\n\treturn frameType, nil\n}\n\nfunc (c *Conn) handleProtocolError(message string) error {\n\tdata := FormatCloseMessage(CloseProtocolError, message)\n\tif len(data) > maxControlFramePayloadSize {\n\t\tdata = data[:maxControlFramePayloadSize]\n\t}\n\tc.WriteControl(CloseMessage, data, time.Now().Add(writeWait))\n\treturn errors.New(\"websocket: \" + message)\n}\n\n// NextReader returns the next data message received from the peer. The\n// returned messageType is either TextMessage or BinaryMessage.\n//\n// There can be at most one open reader on a connection. NextReader discards\n// the previous message if the application has not already consumed it.\n//\n// Applications must break out of the application's read loop when this method\n// returns a non-nil error value. Errors returned from this method are\n// permanent. Once this method returns a non-nil error, all subsequent calls to\n// this method return the same error.\nfunc (c *Conn) NextReader() (messageType int, r io.Reader, err error) {\n\t// Close previous reader, only relevant for decompression.\n\tif c.reader != nil {\n\t\tc.reader.Close()\n\t\tc.reader = nil\n\t}\n\n\tc.messageReader = nil\n\tc.readLength = 0\n\n\tfor c.readErr == nil {\n\t\tframeType, err := c.advanceFrame()\n\t\tif err != nil {\n\t\t\tc.readErr = hideTempErr(err)\n\t\t\tbreak\n\t\t}\n\n\t\tif frameType == TextMessage || frameType == BinaryMessage {\n\t\t\tc.messageReader = &messageReader{c}\n\t\t\tc.reader = c.messageReader\n\t\t\tif c.readDecompress {\n\t\t\t\tc.reader = c.newDecompressionReader(c.reader)\n\t\t\t}\n\t\t\treturn frameType, c.reader, nil\n\t\t}\n\t}\n\n\t// Applications that do handle the error returned from this method spin in\n\t// tight loop on connection failure. To help application developers detect\n\t// this error, panic on repeated reads to the failed connection.\n\tc.readErrCount++\n\tif c.readErrCount >= 1000 {\n\t\tpanic(\"repeated read on failed websocket connection\")\n\t}\n\n\treturn noFrame, nil, c.readErr\n}\n\ntype messageReader struct{ c *Conn }\n\nfunc (r *messageReader) Read(b []byte) (int, error) {\n\tc := r.c\n\tif c.messageReader != r {\n\t\treturn 0, io.EOF\n\t}\n\n\tfor c.readErr == nil {\n\n\t\tif c.readRemaining > 0 {\n\t\t\tif int64(len(b)) > c.readRemaining {\n\t\t\t\tb = b[:c.readRemaining]\n\t\t\t}\n\t\t\tn, err := c.br.Read(b)\n\t\t\tc.readErr = hideTempErr(err)\n\t\t\tif c.isServer {\n\t\t\t\tc.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n])\n\t\t\t}\n\t\t\trem := c.readRemaining\n\t\t\trem -= int64(n)\n\t\t\tc.setReadRemaining(rem)\n\t\t\tif c.readRemaining > 0 && c.readErr == io.EOF {\n\t\t\t\tc.readErr = errUnexpectedEOF\n\t\t\t}\n\t\t\treturn n, c.readErr\n\t\t}\n\n\t\tif c.readFinal {\n\t\t\tc.messageReader = nil\n\t\t\treturn 0, io.EOF\n\t\t}\n\n\t\tframeType, err := c.advanceFrame()\n\t\tswitch {\n\t\tcase err != nil:\n\t\t\tc.readErr = hideTempErr(err)\n\t\tcase frameType == TextMessage || frameType == BinaryMessage:\n\t\t\tc.readErr = errors.New(\"websocket: internal error, unexpected text or binary in Reader\")\n\t\t}\n\t}\n\n\terr := c.readErr\n\tif err == io.EOF && c.messageReader == r {\n\t\terr = errUnexpectedEOF\n\t}\n\treturn 0, err\n}\n\nfunc (r *messageReader) Close() error {\n\treturn nil\n}\n\n// ReadMessage is a helper method for getting a reader using NextReader and\n// reading from that reader to a buffer.\nfunc (c *Conn) ReadMessage() (messageType int, p []byte, err error) {\n\tvar r io.Reader\n\tmessageType, r, err = c.NextReader()\n\tif err != nil {\n\t\treturn messageType, nil, err\n\t}\n\tp, err = ioutil.ReadAll(r)\n\treturn messageType, p, err\n}\n\n// SetReadDeadline sets the read deadline on the underlying network connection.\n// After a read has timed out, the websocket connection state is corrupt and\n// all future reads will return an error. A zero value for t means reads will\n// not time out.\nfunc (c *Conn) SetReadDeadline(t time.Time) error {\n\treturn c.conn.SetReadDeadline(t)\n}\n\n// SetReadLimit sets the maximum size in bytes for a message read from the peer. If a\n// message exceeds the limit, the connection sends a close message to the peer\n// and returns ErrReadLimit to the application.\nfunc (c *Conn) SetReadLimit(limit int64) {\n\tc.readLimit = limit\n}\n\n// CloseHandler returns the current close handler\nfunc (c *Conn) CloseHandler() func(code int, text string) error {\n\treturn c.handleClose\n}\n\n// SetCloseHandler sets the handler for close messages received from the peer.\n// The code argument to h is the received close code or CloseNoStatusReceived\n// if the close message is empty. The default close handler sends a close\n// message back to the peer.\n//\n// The handler function is called from the NextReader, ReadMessage and message\n// reader Read methods. The application must read the connection to process\n// close messages as described in the section on Control Messages above.\n//\n// The connection read methods return a CloseError when a close message is\n// received. Most applications should handle close messages as part of their\n// normal error handling. Applications should only set a close handler when the\n// application must perform some action before sending a close message back to\n// the peer.\nfunc (c *Conn) SetCloseHandler(h func(code int, text string) error) {\n\tif h == nil {\n\t\th = func(code int, text string) error {\n\t\t\tmessage := FormatCloseMessage(code, \"\")\n\t\t\tc.WriteControl(CloseMessage, message, time.Now().Add(writeWait))\n\t\t\treturn nil\n\t\t}\n\t}\n\tc.handleClose = h\n}\n\n// PingHandler returns the current ping handler\nfunc (c *Conn) PingHandler() func(appData string) error {\n\treturn c.handlePing\n}\n\n// SetPingHandler sets the handler for ping messages received from the peer.\n// The appData argument to h is the PING message application data. The default\n// ping handler sends a pong to the peer.\n//\n// The handler function is called from the NextReader, ReadMessage and message\n// reader Read methods. The application must read the connection to process\n// ping messages as described in the section on Control Messages above.\nfunc (c *Conn) SetPingHandler(h func(appData string) error) {\n\tif h == nil {\n\t\th = func(message string) error {\n\t\t\terr := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait))\n\t\t\tif err == ErrCloseSent {\n\t\t\t\treturn nil\n\t\t\t} else if e, ok := err.(net.Error); ok && e.Temporary() {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t}\n\tc.handlePing = h\n}\n\n// PongHandler returns the current pong handler\nfunc (c *Conn) PongHandler() func(appData string) error {\n\treturn c.handlePong\n}\n\n// SetPongHandler sets the handler for pong messages received from the peer.\n// The appData argument to h is the PONG message application data. The default\n// pong handler does nothing.\n//\n// The handler function is called from the NextReader, ReadMessage and message\n// reader Read methods. The application must read the connection to process\n// pong messages as described in the section on Control Messages above.\nfunc (c *Conn) SetPongHandler(h func(appData string) error) {\n\tif h == nil {\n\t\th = func(string) error { return nil }\n\t}\n\tc.handlePong = h\n}\n\n// UnderlyingConn returns the internal net.Conn. This can be used to further\n// modifications to connection specific flags.\nfunc (c *Conn) UnderlyingConn() net.Conn {\n\treturn c.conn\n}\n\n// EnableWriteCompression enables and disables write compression of\n// subsequent text and binary messages. This function is a noop if\n// compression was not negotiated with the peer.\nfunc (c *Conn) EnableWriteCompression(enable bool) {\n\tc.enableWriteCompression = enable\n}\n\n// SetCompressionLevel sets the flate compression level for subsequent text and\n// binary messages. This function is a noop if compression was not negotiated\n// with the peer. See the compress/flate package for a description of\n// compression levels.\nfunc (c *Conn) SetCompressionLevel(level int) error {\n\tif !isValidCompressionLevel(level) {\n\t\treturn errors.New(\"websocket: invalid compression level\")\n\t}\n\tc.compressionLevel = level\n\treturn nil\n}\n\n// FormatCloseMessage formats closeCode and text as a WebSocket close message.\n// An empty message is returned for code CloseNoStatusReceived.\nfunc FormatCloseMessage(closeCode int, text string) []byte {\n\tif closeCode == CloseNoStatusReceived {\n\t\t// Return empty message because it's illegal to send\n\t\t// CloseNoStatusReceived. Return non-nil value in case application\n\t\t// checks for nil.\n\t\treturn []byte{}\n\t}\n\tbuf := make([]byte, 2+len(text))\n\tbinary.BigEndian.PutUint16(buf, uint16(closeCode))\n\tcopy(buf[2:], text)\n\treturn buf\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/doc.go",
    "content": "// Copyright 2013 The Gorilla WebSocket 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\n// Package websocket implements the WebSocket protocol defined in RFC 6455.\n//\n// Overview\n//\n// The Conn type represents a WebSocket connection. A server application calls\n// the Upgrader.Upgrade method from an HTTP request handler to get a *Conn:\n//\n//  var upgrader = websocket.Upgrader{\n//      ReadBufferSize:  1024,\n//      WriteBufferSize: 1024,\n//  }\n//\n//  func handler(w http.ResponseWriter, r *http.Request) {\n//      conn, err := upgrader.Upgrade(w, r, nil)\n//      if err != nil {\n//          log.Println(err)\n//          return\n//      }\n//      ... Use conn to send and receive messages.\n//  }\n//\n// Call the connection's WriteMessage and ReadMessage methods to send and\n// receive messages as a slice of bytes. This snippet of code shows how to echo\n// messages using these methods:\n//\n//  for {\n//      messageType, p, err := conn.ReadMessage()\n//      if err != nil {\n//          log.Println(err)\n//          return\n//      }\n//      if err := conn.WriteMessage(messageType, p); err != nil {\n//          log.Println(err)\n//          return\n//      }\n//  }\n//\n// In above snippet of code, p is a []byte and messageType is an int with value\n// websocket.BinaryMessage or websocket.TextMessage.\n//\n// An application can also send and receive messages using the io.WriteCloser\n// and io.Reader interfaces. To send a message, call the connection NextWriter\n// method to get an io.WriteCloser, write the message to the writer and close\n// the writer when done. To receive a message, call the connection NextReader\n// method to get an io.Reader and read until io.EOF is returned. This snippet\n// shows how to echo messages using the NextWriter and NextReader methods:\n//\n//  for {\n//      messageType, r, err := conn.NextReader()\n//      if err != nil {\n//          return\n//      }\n//      w, err := conn.NextWriter(messageType)\n//      if err != nil {\n//          return err\n//      }\n//      if _, err := io.Copy(w, r); err != nil {\n//          return err\n//      }\n//      if err := w.Close(); err != nil {\n//          return err\n//      }\n//  }\n//\n// Data Messages\n//\n// The WebSocket protocol distinguishes between text and binary data messages.\n// Text messages are interpreted as UTF-8 encoded text. The interpretation of\n// binary messages is left to the application.\n//\n// This package uses the TextMessage and BinaryMessage integer constants to\n// identify the two data message types. The ReadMessage and NextReader methods\n// return the type of the received message. The messageType argument to the\n// WriteMessage and NextWriter methods specifies the type of a sent message.\n//\n// It is the application's responsibility to ensure that text messages are\n// valid UTF-8 encoded text.\n//\n// Control Messages\n//\n// The WebSocket protocol defines three types of control messages: close, ping\n// and pong. Call the connection WriteControl, WriteMessage or NextWriter\n// methods to send a control message to the peer.\n//\n// Connections handle received close messages by calling the handler function\n// set with the SetCloseHandler method and by returning a *CloseError from the\n// NextReader, ReadMessage or the message Read method. The default close\n// handler sends a close message to the peer.\n//\n// Connections handle received ping messages by calling the handler function\n// set with the SetPingHandler method. The default ping handler sends a pong\n// message to the peer.\n//\n// Connections handle received pong messages by calling the handler function\n// set with the SetPongHandler method. The default pong handler does nothing.\n// If an application sends ping messages, then the application should set a\n// pong handler to receive the corresponding pong.\n//\n// The control message handler functions are called from the NextReader,\n// ReadMessage and message reader Read methods. The default close and ping\n// handlers can block these methods for a short time when the handler writes to\n// the connection.\n//\n// The application must read the connection to process close, ping and pong\n// messages sent from the peer. If the application is not otherwise interested\n// in messages from the peer, then the application should start a goroutine to\n// read and discard messages from the peer. A simple example is:\n//\n//  func readLoop(c *websocket.Conn) {\n//      for {\n//          if _, _, err := c.NextReader(); err != nil {\n//              c.Close()\n//              break\n//          }\n//      }\n//  }\n//\n// Concurrency\n//\n// Connections support one concurrent reader and one concurrent writer.\n//\n// Applications are responsible for ensuring that no more than one goroutine\n// calls the write methods (NextWriter, SetWriteDeadline, WriteMessage,\n// WriteJSON, EnableWriteCompression, SetCompressionLevel) concurrently and\n// that no more than one goroutine calls the read methods (NextReader,\n// SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler)\n// concurrently.\n//\n// The Close and WriteControl methods can be called concurrently with all other\n// methods.\n//\n// Origin Considerations\n//\n// Web browsers allow Javascript applications to open a WebSocket connection to\n// any host. It's up to the server to enforce an origin policy using the Origin\n// request header sent by the browser.\n//\n// The Upgrader calls the function specified in the CheckOrigin field to check\n// the origin. If the CheckOrigin function returns false, then the Upgrade\n// method fails the WebSocket handshake with HTTP status 403.\n//\n// If the CheckOrigin field is nil, then the Upgrader uses a safe default: fail\n// the handshake if the Origin request header is present and the Origin host is\n// not equal to the Host request header.\n//\n// The deprecated package-level Upgrade function does not perform origin\n// checking. The application is responsible for checking the Origin header\n// before calling the Upgrade function.\n//\n// Buffers\n//\n// Connections buffer network input and output to reduce the number\n// of system calls when reading or writing messages.\n//\n// Write buffers are also used for constructing WebSocket frames. See RFC 6455,\n// Section 5 for a discussion of message framing. A WebSocket frame header is\n// written to the network each time a write buffer is flushed to the network.\n// Decreasing the size of the write buffer can increase the amount of framing\n// overhead on the connection.\n//\n// The buffer sizes in bytes are specified by the ReadBufferSize and\n// WriteBufferSize fields in the Dialer and Upgrader. The Dialer uses a default\n// size of 4096 when a buffer size field is set to zero. The Upgrader reuses\n// buffers created by the HTTP server when a buffer size field is set to zero.\n// The HTTP server buffers have a size of 4096 at the time of this writing.\n//\n// The buffer sizes do not limit the size of a message that can be read or\n// written by a connection.\n//\n// Buffers are held for the lifetime of the connection by default. If the\n// Dialer or Upgrader WriteBufferPool field is set, then a connection holds the\n// write buffer only when writing a message.\n//\n// Applications should tune the buffer sizes to balance memory use and\n// performance. Increasing the buffer size uses more memory, but can reduce the\n// number of system calls to read or write the network. In the case of writing,\n// increasing the buffer size can reduce the number of frame headers written to\n// the network.\n//\n// Some guidelines for setting buffer parameters are:\n//\n// Limit the buffer sizes to the maximum expected message size. Buffers larger\n// than the largest message do not provide any benefit.\n//\n// Depending on the distribution of message sizes, setting the buffer size to\n// a value less than the maximum expected message size can greatly reduce memory\n// use with a small impact on performance. Here's an example: If 99% of the\n// messages are smaller than 256 bytes and the maximum message size is 512\n// bytes, then a buffer size of 256 bytes will result in 1.01 more system calls\n// than a buffer size of 512 bytes. The memory savings is 50%.\n//\n// A write buffer pool is useful when the application has a modest number\n// writes over a large number of connections. when buffers are pooled, a larger\n// buffer size has a reduced impact on total memory use and has the benefit of\n// reducing system calls and frame overhead.\n//\n// Compression EXPERIMENTAL\n//\n// Per message compression extensions (RFC 7692) are experimentally supported\n// by this package in a limited capacity. Setting the EnableCompression option\n// to true in Dialer or Upgrader will attempt to negotiate per message deflate\n// support.\n//\n//  var upgrader = websocket.Upgrader{\n//      EnableCompression: true,\n//  }\n//\n// If compression was successfully negotiated with the connection's peer, any\n// message received in compressed form will be automatically decompressed.\n// All Read methods will return uncompressed bytes.\n//\n// Per message compression of messages written to a connection can be enabled\n// or disabled by calling the corresponding Conn method:\n//\n//  conn.EnableWriteCompression(false)\n//\n// Currently this package does not support compression with \"context takeover\".\n// This means that messages must be compressed and decompressed in isolation,\n// without retaining sliding window or dictionary state across messages. For\n// more details refer to RFC 7692.\n//\n// Use of compression is experimental and may result in decreased performance.\npackage websocket\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/join.go",
    "content": "// Copyright 2019 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"io\"\n\t\"strings\"\n)\n\n// JoinMessages concatenates received messages to create a single io.Reader.\n// The string term is appended to each message. The returned reader does not\n// support concurrent calls to the Read method.\nfunc JoinMessages(c *Conn, term string) io.Reader {\n\treturn &joinReader{c: c, term: term}\n}\n\ntype joinReader struct {\n\tc    *Conn\n\tterm string\n\tr    io.Reader\n}\n\nfunc (r *joinReader) Read(p []byte) (int, error) {\n\tif r.r == nil {\n\t\tvar err error\n\t\t_, r.r, err = r.c.NextReader()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tif r.term != \"\" {\n\t\t\tr.r = io.MultiReader(r.r, strings.NewReader(r.term))\n\t\t}\n\t}\n\tn, err := r.r.Read(p)\n\tif err == io.EOF {\n\t\terr = nil\n\t\tr.r = nil\n\t}\n\treturn n, err\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/json.go",
    "content": "// Copyright 2013 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"encoding/json\"\n\t\"io\"\n)\n\n// WriteJSON writes the JSON encoding of v as a message.\n//\n// Deprecated: Use c.WriteJSON instead.\nfunc WriteJSON(c *Conn, v interface{}) error {\n\treturn c.WriteJSON(v)\n}\n\n// WriteJSON writes the JSON encoding of v as a message.\n//\n// See the documentation for encoding/json Marshal for details about the\n// conversion of Go values to JSON.\nfunc (c *Conn) WriteJSON(v interface{}) error {\n\tw, err := c.NextWriter(TextMessage)\n\tif err != nil {\n\t\treturn err\n\t}\n\terr1 := json.NewEncoder(w).Encode(v)\n\terr2 := w.Close()\n\tif err1 != nil {\n\t\treturn err1\n\t}\n\treturn err2\n}\n\n// ReadJSON reads the next JSON-encoded message from the connection and stores\n// it in the value pointed to by v.\n//\n// Deprecated: Use c.ReadJSON instead.\nfunc ReadJSON(c *Conn, v interface{}) error {\n\treturn c.ReadJSON(v)\n}\n\n// ReadJSON reads the next JSON-encoded message from the connection and stores\n// it in the value pointed to by v.\n//\n// See the documentation for the encoding/json Unmarshal function for details\n// about the conversion of JSON to a Go value.\nfunc (c *Conn) ReadJSON(v interface{}) error {\n\t_, r, err := c.NextReader()\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = json.NewDecoder(r).Decode(v)\n\tif err == io.EOF {\n\t\t// One value is expected in the message.\n\t\terr = io.ErrUnexpectedEOF\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/mask.go",
    "content": "// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.  Use of\n// this source code is governed by a BSD-style license that can be found in the\n// LICENSE file.\n\n//go:build !appengine\n// +build !appengine\n\npackage websocket\n\nimport \"unsafe\"\n\nconst wordSize = int(unsafe.Sizeof(uintptr(0)))\n\nfunc maskBytes(key [4]byte, pos int, b []byte) int {\n\t// Mask one byte at a time for small buffers.\n\tif len(b) < 2*wordSize {\n\t\tfor i := range b {\n\t\t\tb[i] ^= key[pos&3]\n\t\t\tpos++\n\t\t}\n\t\treturn pos & 3\n\t}\n\n\t// Mask one byte at a time to word boundary.\n\tif n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 {\n\t\tn = wordSize - n\n\t\tfor i := range b[:n] {\n\t\t\tb[i] ^= key[pos&3]\n\t\t\tpos++\n\t\t}\n\t\tb = b[n:]\n\t}\n\n\t// Create aligned word size key.\n\tvar k [wordSize]byte\n\tfor i := range k {\n\t\tk[i] = key[(pos+i)&3]\n\t}\n\tkw := *(*uintptr)(unsafe.Pointer(&k))\n\n\t// Mask one word at a time.\n\tn := (len(b) / wordSize) * wordSize\n\tfor i := 0; i < n; i += wordSize {\n\t\t*(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw\n\t}\n\n\t// Mask one byte at a time for remaining bytes.\n\tb = b[n:]\n\tfor i := range b {\n\t\tb[i] ^= key[pos&3]\n\t\tpos++\n\t}\n\n\treturn pos & 3\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/mask_safe.go",
    "content": "// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.  Use of\n// this source code is governed by a BSD-style license that can be found in the\n// LICENSE file.\n\n//go:build appengine\n// +build appengine\n\npackage websocket\n\nfunc maskBytes(key [4]byte, pos int, b []byte) int {\n\tfor i := range b {\n\t\tb[i] ^= key[pos&3]\n\t\tpos++\n\t}\n\treturn pos & 3\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/prepared.go",
    "content": "// Copyright 2017 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"bytes\"\n\t\"net\"\n\t\"sync\"\n\t\"time\"\n)\n\n// PreparedMessage caches on the wire representations of a message payload.\n// Use PreparedMessage to efficiently send a message payload to multiple\n// connections. PreparedMessage is especially useful when compression is used\n// because the CPU and memory expensive compression operation can be executed\n// once for a given set of compression options.\ntype PreparedMessage struct {\n\tmessageType int\n\tdata        []byte\n\tmu          sync.Mutex\n\tframes      map[prepareKey]*preparedFrame\n}\n\n// prepareKey defines a unique set of options to cache prepared frames in PreparedMessage.\ntype prepareKey struct {\n\tisServer         bool\n\tcompress         bool\n\tcompressionLevel int\n}\n\n// preparedFrame contains data in wire representation.\ntype preparedFrame struct {\n\tonce sync.Once\n\tdata []byte\n}\n\n// NewPreparedMessage returns an initialized PreparedMessage. You can then send\n// it to connection using WritePreparedMessage method. Valid wire\n// representation will be calculated lazily only once for a set of current\n// connection options.\nfunc NewPreparedMessage(messageType int, data []byte) (*PreparedMessage, error) {\n\tpm := &PreparedMessage{\n\t\tmessageType: messageType,\n\t\tframes:      make(map[prepareKey]*preparedFrame),\n\t\tdata:        data,\n\t}\n\n\t// Prepare a plain server frame.\n\t_, frameData, err := pm.frame(prepareKey{isServer: true, compress: false})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// To protect against caller modifying the data argument, remember the data\n\t// copied to the plain server frame.\n\tpm.data = frameData[len(frameData)-len(data):]\n\treturn pm, nil\n}\n\nfunc (pm *PreparedMessage) frame(key prepareKey) (int, []byte, error) {\n\tpm.mu.Lock()\n\tframe, ok := pm.frames[key]\n\tif !ok {\n\t\tframe = &preparedFrame{}\n\t\tpm.frames[key] = frame\n\t}\n\tpm.mu.Unlock()\n\n\tvar err error\n\tframe.once.Do(func() {\n\t\t// Prepare a frame using a 'fake' connection.\n\t\t// TODO: Refactor code in conn.go to allow more direct construction of\n\t\t// the frame.\n\t\tmu := make(chan struct{}, 1)\n\t\tmu <- struct{}{}\n\t\tvar nc prepareConn\n\t\tc := &Conn{\n\t\t\tconn:                   &nc,\n\t\t\tmu:                     mu,\n\t\t\tisServer:               key.isServer,\n\t\t\tcompressionLevel:       key.compressionLevel,\n\t\t\tenableWriteCompression: true,\n\t\t\twriteBuf:               make([]byte, defaultWriteBufferSize+maxFrameHeaderSize),\n\t\t}\n\t\tif key.compress {\n\t\t\tc.newCompressionWriter = compressNoContextTakeover\n\t\t}\n\t\terr = c.WriteMessage(pm.messageType, pm.data)\n\t\tframe.data = nc.buf.Bytes()\n\t})\n\treturn pm.messageType, frame.data, err\n}\n\ntype prepareConn struct {\n\tbuf bytes.Buffer\n\tnet.Conn\n}\n\nfunc (pc *prepareConn) Write(p []byte) (int, error)        { return pc.buf.Write(p) }\nfunc (pc *prepareConn) SetWriteDeadline(t time.Time) error { return nil }\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/proxy.go",
    "content": "// Copyright 2017 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"bufio\"\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\ntype netDialerFunc func(network, addr string) (net.Conn, error)\n\nfunc (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) {\n\treturn fn(network, addr)\n}\n\nfunc init() {\n\tproxy_RegisterDialerType(\"http\", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) {\n\t\treturn &httpProxyDialer{proxyURL: proxyURL, forwardDial: forwardDialer.Dial}, nil\n\t})\n}\n\ntype httpProxyDialer struct {\n\tproxyURL    *url.URL\n\tforwardDial func(network, addr string) (net.Conn, error)\n}\n\nfunc (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) {\n\thostPort, _ := hostPortNoPort(hpd.proxyURL)\n\tconn, err := hpd.forwardDial(network, hostPort)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tconnectHeader := make(http.Header)\n\tif user := hpd.proxyURL.User; user != nil {\n\t\tproxyUser := user.Username()\n\t\tif proxyPassword, passwordSet := user.Password(); passwordSet {\n\t\t\tcredential := base64.StdEncoding.EncodeToString([]byte(proxyUser + \":\" + proxyPassword))\n\t\t\tconnectHeader.Set(\"Proxy-Authorization\", \"Basic \"+credential)\n\t\t}\n\t}\n\n\tconnectReq := &http.Request{\n\t\tMethod: http.MethodConnect,\n\t\tURL:    &url.URL{Opaque: addr},\n\t\tHost:   addr,\n\t\tHeader: connectHeader,\n\t}\n\n\tif err := connectReq.Write(conn); err != nil {\n\t\tconn.Close()\n\t\treturn nil, err\n\t}\n\n\t// Read response. It's OK to use and discard buffered reader here becaue\n\t// the remote server does not speak until spoken to.\n\tbr := bufio.NewReader(conn)\n\tresp, err := http.ReadResponse(br, connectReq)\n\tif err != nil {\n\t\tconn.Close()\n\t\treturn nil, err\n\t}\n\n\tif resp.StatusCode != 200 {\n\t\tconn.Close()\n\t\tf := strings.SplitN(resp.Status, \" \", 2)\n\t\treturn nil, errors.New(f[1])\n\t}\n\treturn conn, nil\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/server.go",
    "content": "// Copyright 2013 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n)\n\n// HandshakeError describes an error with the handshake from the peer.\ntype HandshakeError struct {\n\tmessage string\n}\n\nfunc (e HandshakeError) Error() string { return e.message }\n\n// Upgrader specifies parameters for upgrading an HTTP connection to a\n// WebSocket connection.\n//\n// It is safe to call Upgrader's methods concurrently.\ntype Upgrader struct {\n\t// HandshakeTimeout specifies the duration for the handshake to complete.\n\tHandshakeTimeout time.Duration\n\n\t// ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes. If a buffer\n\t// size is zero, then buffers allocated by the HTTP server are used. The\n\t// I/O buffer sizes do not limit the size of the messages that can be sent\n\t// or received.\n\tReadBufferSize, WriteBufferSize int\n\n\t// WriteBufferPool is a pool of buffers for write operations. If the value\n\t// is not set, then write buffers are allocated to the connection for the\n\t// lifetime of the connection.\n\t//\n\t// A pool is most useful when the application has a modest volume of writes\n\t// across a large number of connections.\n\t//\n\t// Applications should use a single pool for each unique value of\n\t// WriteBufferSize.\n\tWriteBufferPool BufferPool\n\n\t// Subprotocols specifies the server's supported protocols in order of\n\t// preference. If this field is not nil, then the Upgrade method negotiates a\n\t// subprotocol by selecting the first match in this list with a protocol\n\t// requested by the client. If there's no match, then no protocol is\n\t// negotiated (the Sec-Websocket-Protocol header is not included in the\n\t// handshake response).\n\tSubprotocols []string\n\n\t// Error specifies the function for generating HTTP error responses. If Error\n\t// is nil, then http.Error is used to generate the HTTP response.\n\tError func(w http.ResponseWriter, r *http.Request, status int, reason error)\n\n\t// CheckOrigin returns true if the request Origin header is acceptable. If\n\t// CheckOrigin is nil, then a safe default is used: return false if the\n\t// Origin request header is present and the origin host is not equal to\n\t// request Host header.\n\t//\n\t// A CheckOrigin function should carefully validate the request origin to\n\t// prevent cross-site request forgery.\n\tCheckOrigin func(r *http.Request) bool\n\n\t// EnableCompression specify if the server should attempt to negotiate per\n\t// message compression (RFC 7692). Setting this value to true does not\n\t// guarantee that compression will be supported. Currently only \"no context\n\t// takeover\" modes are supported.\n\tEnableCompression bool\n}\n\nfunc (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status int, reason string) (*Conn, error) {\n\terr := HandshakeError{reason}\n\tif u.Error != nil {\n\t\tu.Error(w, r, status, err)\n\t} else {\n\t\tw.Header().Set(\"Sec-Websocket-Version\", \"13\")\n\t\thttp.Error(w, http.StatusText(status), status)\n\t}\n\treturn nil, err\n}\n\n// checkSameOrigin returns true if the origin is not set or is equal to the request host.\nfunc checkSameOrigin(r *http.Request) bool {\n\torigin := r.Header[\"Origin\"]\n\tif len(origin) == 0 {\n\t\treturn true\n\t}\n\tu, err := url.Parse(origin[0])\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn equalASCIIFold(u.Host, r.Host)\n}\n\nfunc (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header) string {\n\tif u.Subprotocols != nil {\n\t\tclientProtocols := Subprotocols(r)\n\t\tfor _, serverProtocol := range u.Subprotocols {\n\t\t\tfor _, clientProtocol := range clientProtocols {\n\t\t\t\tif clientProtocol == serverProtocol {\n\t\t\t\t\treturn clientProtocol\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if responseHeader != nil {\n\t\treturn responseHeader.Get(\"Sec-Websocket-Protocol\")\n\t}\n\treturn \"\"\n}\n\n// Upgrade upgrades the HTTP server connection to the WebSocket protocol.\n//\n// The responseHeader is included in the response to the client's upgrade\n// request. Use the responseHeader to specify cookies (Set-Cookie). To specify\n// subprotocols supported by the server, set Upgrader.Subprotocols directly.\n//\n// If the upgrade fails, then Upgrade replies to the client with an HTTP error\n// response.\nfunc (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) {\n\tconst badHandshake = \"websocket: the client is not using the websocket protocol: \"\n\n\tif !tokenListContainsValue(r.Header, \"Connection\", \"upgrade\") {\n\t\treturn u.returnError(w, r, http.StatusBadRequest, badHandshake+\"'upgrade' token not found in 'Connection' header\")\n\t}\n\n\tif !tokenListContainsValue(r.Header, \"Upgrade\", \"websocket\") {\n\t\treturn u.returnError(w, r, http.StatusBadRequest, badHandshake+\"'websocket' token not found in 'Upgrade' header\")\n\t}\n\n\tif r.Method != http.MethodGet {\n\t\treturn u.returnError(w, r, http.StatusMethodNotAllowed, badHandshake+\"request method is not GET\")\n\t}\n\n\tif !tokenListContainsValue(r.Header, \"Sec-Websocket-Version\", \"13\") {\n\t\treturn u.returnError(w, r, http.StatusBadRequest, \"websocket: unsupported version: 13 not found in 'Sec-Websocket-Version' header\")\n\t}\n\n\tif _, ok := responseHeader[\"Sec-Websocket-Extensions\"]; ok {\n\t\treturn u.returnError(w, r, http.StatusInternalServerError, \"websocket: application specific 'Sec-WebSocket-Extensions' headers are unsupported\")\n\t}\n\n\tcheckOrigin := u.CheckOrigin\n\tif checkOrigin == nil {\n\t\tcheckOrigin = checkSameOrigin\n\t}\n\tif !checkOrigin(r) {\n\t\treturn u.returnError(w, r, http.StatusForbidden, \"websocket: request origin not allowed by Upgrader.CheckOrigin\")\n\t}\n\n\tchallengeKey := r.Header.Get(\"Sec-Websocket-Key\")\n\tif challengeKey == \"\" {\n\t\treturn u.returnError(w, r, http.StatusBadRequest, \"websocket: not a websocket handshake: 'Sec-WebSocket-Key' header is missing or blank\")\n\t}\n\n\tsubprotocol := u.selectSubprotocol(r, responseHeader)\n\n\t// Negotiate PMCE\n\tvar compress bool\n\tif u.EnableCompression {\n\t\tfor _, ext := range parseExtensions(r.Header) {\n\t\t\tif ext[\"\"] != \"permessage-deflate\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcompress = true\n\t\t\tbreak\n\t\t}\n\t}\n\n\th, ok := w.(http.Hijacker)\n\tif !ok {\n\t\treturn u.returnError(w, r, http.StatusInternalServerError, \"websocket: response does not implement http.Hijacker\")\n\t}\n\tvar brw *bufio.ReadWriter\n\tnetConn, brw, err := h.Hijack()\n\tif err != nil {\n\t\treturn u.returnError(w, r, http.StatusInternalServerError, err.Error())\n\t}\n\n\tif brw.Reader.Buffered() > 0 {\n\t\tnetConn.Close()\n\t\treturn nil, errors.New(\"websocket: client sent data before handshake is complete\")\n\t}\n\n\tvar br *bufio.Reader\n\tif u.ReadBufferSize == 0 && bufioReaderSize(netConn, brw.Reader) > 256 {\n\t\t// Reuse hijacked buffered reader as connection reader.\n\t\tbr = brw.Reader\n\t}\n\n\tbuf := bufioWriterBuffer(netConn, brw.Writer)\n\n\tvar writeBuf []byte\n\tif u.WriteBufferPool == nil && u.WriteBufferSize == 0 && len(buf) >= maxFrameHeaderSize+256 {\n\t\t// Reuse hijacked write buffer as connection buffer.\n\t\twriteBuf = buf\n\t}\n\n\tc := newConn(netConn, true, u.ReadBufferSize, u.WriteBufferSize, u.WriteBufferPool, br, writeBuf)\n\tc.subprotocol = subprotocol\n\n\tif compress {\n\t\tc.newCompressionWriter = compressNoContextTakeover\n\t\tc.newDecompressionReader = decompressNoContextTakeover\n\t}\n\n\t// Use larger of hijacked buffer and connection write buffer for header.\n\tp := buf\n\tif len(c.writeBuf) > len(p) {\n\t\tp = c.writeBuf\n\t}\n\tp = p[:0]\n\n\tp = append(p, \"HTTP/1.1 101 Switching Protocols\\r\\nUpgrade: websocket\\r\\nConnection: Upgrade\\r\\nSec-WebSocket-Accept: \"...)\n\tp = append(p, computeAcceptKey(challengeKey)...)\n\tp = append(p, \"\\r\\n\"...)\n\tif c.subprotocol != \"\" {\n\t\tp = append(p, \"Sec-WebSocket-Protocol: \"...)\n\t\tp = append(p, c.subprotocol...)\n\t\tp = append(p, \"\\r\\n\"...)\n\t}\n\tif compress {\n\t\tp = append(p, \"Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\\r\\n\"...)\n\t}\n\tfor k, vs := range responseHeader {\n\t\tif k == \"Sec-Websocket-Protocol\" {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, v := range vs {\n\t\t\tp = append(p, k...)\n\t\t\tp = append(p, \": \"...)\n\t\t\tfor i := 0; i < len(v); i++ {\n\t\t\t\tb := v[i]\n\t\t\t\tif b <= 31 {\n\t\t\t\t\t// prevent response splitting.\n\t\t\t\t\tb = ' '\n\t\t\t\t}\n\t\t\t\tp = append(p, b)\n\t\t\t}\n\t\t\tp = append(p, \"\\r\\n\"...)\n\t\t}\n\t}\n\tp = append(p, \"\\r\\n\"...)\n\n\t// Clear deadlines set by HTTP server.\n\tnetConn.SetDeadline(time.Time{})\n\n\tif u.HandshakeTimeout > 0 {\n\t\tnetConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout))\n\t}\n\tif _, err = netConn.Write(p); err != nil {\n\t\tnetConn.Close()\n\t\treturn nil, err\n\t}\n\tif u.HandshakeTimeout > 0 {\n\t\tnetConn.SetWriteDeadline(time.Time{})\n\t}\n\n\treturn c, nil\n}\n\n// Upgrade upgrades the HTTP server connection to the WebSocket protocol.\n//\n// Deprecated: Use websocket.Upgrader instead.\n//\n// Upgrade does not perform origin checking. The application is responsible for\n// checking the Origin header before calling Upgrade. An example implementation\n// of the same origin policy check is:\n//\n//\tif req.Header.Get(\"Origin\") != \"http://\"+req.Host {\n//\t\thttp.Error(w, \"Origin not allowed\", http.StatusForbidden)\n//\t\treturn\n//\t}\n//\n// If the endpoint supports subprotocols, then the application is responsible\n// for negotiating the protocol used on the connection. Use the Subprotocols()\n// function to get the subprotocols requested by the client. Use the\n// Sec-Websocket-Protocol response header to specify the subprotocol selected\n// by the application.\n//\n// The responseHeader is included in the response to the client's upgrade\n// request. Use the responseHeader to specify cookies (Set-Cookie) and the\n// negotiated subprotocol (Sec-Websocket-Protocol).\n//\n// The connection buffers IO to the underlying network connection. The\n// readBufSize and writeBufSize parameters specify the size of the buffers to\n// use. Messages can be larger than the buffers.\n//\n// If the request is not a valid WebSocket handshake, then Upgrade returns an\n// error of type HandshakeError. Applications should handle this error by\n// replying to the client with an HTTP error response.\nfunc Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header, readBufSize, writeBufSize int) (*Conn, error) {\n\tu := Upgrader{ReadBufferSize: readBufSize, WriteBufferSize: writeBufSize}\n\tu.Error = func(w http.ResponseWriter, r *http.Request, status int, reason error) {\n\t\t// don't return errors to maintain backwards compatibility\n\t}\n\tu.CheckOrigin = func(r *http.Request) bool {\n\t\t// allow all connections by default\n\t\treturn true\n\t}\n\treturn u.Upgrade(w, r, responseHeader)\n}\n\n// Subprotocols returns the subprotocols requested by the client in the\n// Sec-Websocket-Protocol header.\nfunc Subprotocols(r *http.Request) []string {\n\th := strings.TrimSpace(r.Header.Get(\"Sec-Websocket-Protocol\"))\n\tif h == \"\" {\n\t\treturn nil\n\t}\n\tprotocols := strings.Split(h, \",\")\n\tfor i := range protocols {\n\t\tprotocols[i] = strings.TrimSpace(protocols[i])\n\t}\n\treturn protocols\n}\n\n// IsWebSocketUpgrade returns true if the client requested upgrade to the\n// WebSocket protocol.\nfunc IsWebSocketUpgrade(r *http.Request) bool {\n\treturn tokenListContainsValue(r.Header, \"Connection\", \"upgrade\") &&\n\t\ttokenListContainsValue(r.Header, \"Upgrade\", \"websocket\")\n}\n\n// bufioReaderSize size returns the size of a bufio.Reader.\nfunc bufioReaderSize(originalReader io.Reader, br *bufio.Reader) int {\n\t// This code assumes that peek on a reset reader returns\n\t// bufio.Reader.buf[:0].\n\t// TODO: Use bufio.Reader.Size() after Go 1.10\n\tbr.Reset(originalReader)\n\tif p, err := br.Peek(0); err == nil {\n\t\treturn cap(p)\n\t}\n\treturn 0\n}\n\n// writeHook is an io.Writer that records the last slice passed to it vio\n// io.Writer.Write.\ntype writeHook struct {\n\tp []byte\n}\n\nfunc (wh *writeHook) Write(p []byte) (int, error) {\n\twh.p = p\n\treturn len(p), nil\n}\n\n// bufioWriterBuffer grabs the buffer from a bufio.Writer.\nfunc bufioWriterBuffer(originalWriter io.Writer, bw *bufio.Writer) []byte {\n\t// This code assumes that bufio.Writer.buf[:1] is passed to the\n\t// bufio.Writer's underlying writer.\n\tvar wh writeHook\n\tbw.Reset(&wh)\n\tbw.WriteByte(0)\n\tbw.Flush()\n\n\tbw.Reset(originalWriter)\n\n\treturn wh.p[:cap(wh.p)]\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/tls_handshake.go",
    "content": "//go:build go1.17\n// +build go1.17\n\npackage websocket\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n)\n\nfunc doHandshake(ctx context.Context, tlsConn *tls.Conn, cfg *tls.Config) error {\n\tif err := tlsConn.HandshakeContext(ctx); err != nil {\n\t\treturn err\n\t}\n\tif !cfg.InsecureSkipVerify {\n\t\tif err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/tls_handshake_116.go",
    "content": "//go:build !go1.17\n// +build !go1.17\n\npackage websocket\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n)\n\nfunc doHandshake(ctx context.Context, tlsConn *tls.Conn, cfg *tls.Config) error {\n\tif err := tlsConn.Handshake(); err != nil {\n\t\treturn err\n\t}\n\tif !cfg.InsecureSkipVerify {\n\t\tif err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/util.go",
    "content": "// Copyright 2013 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/sha1\"\n\t\"encoding/base64\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\nvar keyGUID = []byte(\"258EAFA5-E914-47DA-95CA-C5AB0DC85B11\")\n\nfunc computeAcceptKey(challengeKey string) string {\n\th := sha1.New()\n\th.Write([]byte(challengeKey))\n\th.Write(keyGUID)\n\treturn base64.StdEncoding.EncodeToString(h.Sum(nil))\n}\n\nfunc generateChallengeKey() (string, error) {\n\tp := make([]byte, 16)\n\tif _, err := io.ReadFull(rand.Reader, p); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn base64.StdEncoding.EncodeToString(p), nil\n}\n\n// Token octets per RFC 2616.\nvar isTokenOctet = [256]bool{\n\t'!':  true,\n\t'#':  true,\n\t'$':  true,\n\t'%':  true,\n\t'&':  true,\n\t'\\'': true,\n\t'*':  true,\n\t'+':  true,\n\t'-':  true,\n\t'.':  true,\n\t'0':  true,\n\t'1':  true,\n\t'2':  true,\n\t'3':  true,\n\t'4':  true,\n\t'5':  true,\n\t'6':  true,\n\t'7':  true,\n\t'8':  true,\n\t'9':  true,\n\t'A':  true,\n\t'B':  true,\n\t'C':  true,\n\t'D':  true,\n\t'E':  true,\n\t'F':  true,\n\t'G':  true,\n\t'H':  true,\n\t'I':  true,\n\t'J':  true,\n\t'K':  true,\n\t'L':  true,\n\t'M':  true,\n\t'N':  true,\n\t'O':  true,\n\t'P':  true,\n\t'Q':  true,\n\t'R':  true,\n\t'S':  true,\n\t'T':  true,\n\t'U':  true,\n\t'W':  true,\n\t'V':  true,\n\t'X':  true,\n\t'Y':  true,\n\t'Z':  true,\n\t'^':  true,\n\t'_':  true,\n\t'`':  true,\n\t'a':  true,\n\t'b':  true,\n\t'c':  true,\n\t'd':  true,\n\t'e':  true,\n\t'f':  true,\n\t'g':  true,\n\t'h':  true,\n\t'i':  true,\n\t'j':  true,\n\t'k':  true,\n\t'l':  true,\n\t'm':  true,\n\t'n':  true,\n\t'o':  true,\n\t'p':  true,\n\t'q':  true,\n\t'r':  true,\n\t's':  true,\n\t't':  true,\n\t'u':  true,\n\t'v':  true,\n\t'w':  true,\n\t'x':  true,\n\t'y':  true,\n\t'z':  true,\n\t'|':  true,\n\t'~':  true,\n}\n\n// skipSpace returns a slice of the string s with all leading RFC 2616 linear\n// whitespace removed.\nfunc skipSpace(s string) (rest string) {\n\ti := 0\n\tfor ; i < len(s); i++ {\n\t\tif b := s[i]; b != ' ' && b != '\\t' {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn s[i:]\n}\n\n// nextToken returns the leading RFC 2616 token of s and the string following\n// the token.\nfunc nextToken(s string) (token, rest string) {\n\ti := 0\n\tfor ; i < len(s); i++ {\n\t\tif !isTokenOctet[s[i]] {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn s[:i], s[i:]\n}\n\n// nextTokenOrQuoted returns the leading token or quoted string per RFC 2616\n// and the string following the token or quoted string.\nfunc nextTokenOrQuoted(s string) (value string, rest string) {\n\tif !strings.HasPrefix(s, \"\\\"\") {\n\t\treturn nextToken(s)\n\t}\n\ts = s[1:]\n\tfor i := 0; i < len(s); i++ {\n\t\tswitch s[i] {\n\t\tcase '\"':\n\t\t\treturn s[:i], s[i+1:]\n\t\tcase '\\\\':\n\t\t\tp := make([]byte, len(s)-1)\n\t\t\tj := copy(p, s[:i])\n\t\t\tescape := true\n\t\t\tfor i = i + 1; i < len(s); i++ {\n\t\t\t\tb := s[i]\n\t\t\t\tswitch {\n\t\t\t\tcase escape:\n\t\t\t\t\tescape = false\n\t\t\t\t\tp[j] = b\n\t\t\t\t\tj++\n\t\t\t\tcase b == '\\\\':\n\t\t\t\t\tescape = true\n\t\t\t\tcase b == '\"':\n\t\t\t\t\treturn string(p[:j]), s[i+1:]\n\t\t\t\tdefault:\n\t\t\t\t\tp[j] = b\n\t\t\t\t\tj++\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn \"\", \"\"\n\t\t}\n\t}\n\treturn \"\", \"\"\n}\n\n// equalASCIIFold returns true if s is equal to t with ASCII case folding as\n// defined in RFC 4790.\nfunc equalASCIIFold(s, t string) bool {\n\tfor s != \"\" && t != \"\" {\n\t\tsr, size := utf8.DecodeRuneInString(s)\n\t\ts = s[size:]\n\t\ttr, size := utf8.DecodeRuneInString(t)\n\t\tt = t[size:]\n\t\tif sr == tr {\n\t\t\tcontinue\n\t\t}\n\t\tif 'A' <= sr && sr <= 'Z' {\n\t\t\tsr = sr + 'a' - 'A'\n\t\t}\n\t\tif 'A' <= tr && tr <= 'Z' {\n\t\t\ttr = tr + 'a' - 'A'\n\t\t}\n\t\tif sr != tr {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn s == t\n}\n\n// tokenListContainsValue returns true if the 1#token header with the given\n// name contains a token equal to value with ASCII case folding.\nfunc tokenListContainsValue(header http.Header, name string, value string) bool {\nheaders:\n\tfor _, s := range header[name] {\n\t\tfor {\n\t\t\tvar t string\n\t\t\tt, s = nextToken(skipSpace(s))\n\t\t\tif t == \"\" {\n\t\t\t\tcontinue headers\n\t\t\t}\n\t\t\ts = skipSpace(s)\n\t\t\tif s != \"\" && s[0] != ',' {\n\t\t\t\tcontinue headers\n\t\t\t}\n\t\t\tif equalASCIIFold(t, value) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif s == \"\" {\n\t\t\t\tcontinue headers\n\t\t\t}\n\t\t\ts = s[1:]\n\t\t}\n\t}\n\treturn false\n}\n\n// parseExtensions parses WebSocket extensions from a header.\nfunc parseExtensions(header http.Header) []map[string]string {\n\t// From RFC 6455:\n\t//\n\t//  Sec-WebSocket-Extensions = extension-list\n\t//  extension-list = 1#extension\n\t//  extension = extension-token *( \";\" extension-param )\n\t//  extension-token = registered-token\n\t//  registered-token = token\n\t//  extension-param = token [ \"=\" (token | quoted-string) ]\n\t//     ;When using the quoted-string syntax variant, the value\n\t//     ;after quoted-string unescaping MUST conform to the\n\t//     ;'token' ABNF.\n\n\tvar result []map[string]string\nheaders:\n\tfor _, s := range header[\"Sec-Websocket-Extensions\"] {\n\t\tfor {\n\t\t\tvar t string\n\t\t\tt, s = nextToken(skipSpace(s))\n\t\t\tif t == \"\" {\n\t\t\t\tcontinue headers\n\t\t\t}\n\t\t\text := map[string]string{\"\": t}\n\t\t\tfor {\n\t\t\t\ts = skipSpace(s)\n\t\t\t\tif !strings.HasPrefix(s, \";\") {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tvar k string\n\t\t\t\tk, s = nextToken(skipSpace(s[1:]))\n\t\t\t\tif k == \"\" {\n\t\t\t\t\tcontinue headers\n\t\t\t\t}\n\t\t\t\ts = skipSpace(s)\n\t\t\t\tvar v string\n\t\t\t\tif strings.HasPrefix(s, \"=\") {\n\t\t\t\t\tv, s = nextTokenOrQuoted(skipSpace(s[1:]))\n\t\t\t\t\ts = skipSpace(s)\n\t\t\t\t}\n\t\t\t\tif s != \"\" && s[0] != ',' && s[0] != ';' {\n\t\t\t\t\tcontinue headers\n\t\t\t\t}\n\t\t\t\text[k] = v\n\t\t\t}\n\t\t\tif s != \"\" && s[0] != ',' {\n\t\t\t\tcontinue headers\n\t\t\t}\n\t\t\tresult = append(result, ext)\n\t\t\tif s == \"\" {\n\t\t\t\tcontinue headers\n\t\t\t}\n\t\t\ts = s[1:]\n\t\t}\n\t}\n\treturn result\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/x_net_proxy.go",
    "content": "// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.\n//go:generate bundle -o x_net_proxy.go golang.org/x/net/proxy\n\n// Package proxy provides support for a variety of protocols to proxy network\n// data.\n//\n\npackage websocket\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n\t\"net/url\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n)\n\ntype proxy_direct struct{}\n\n// Direct is a direct proxy: one that makes network connections directly.\nvar proxy_Direct = proxy_direct{}\n\nfunc (proxy_direct) Dial(network, addr string) (net.Conn, error) {\n\treturn net.Dial(network, addr)\n}\n\n// A PerHost directs connections to a default Dialer unless the host name\n// requested matches one of a number of exceptions.\ntype proxy_PerHost struct {\n\tdef, bypass proxy_Dialer\n\n\tbypassNetworks []*net.IPNet\n\tbypassIPs      []net.IP\n\tbypassZones    []string\n\tbypassHosts    []string\n}\n\n// NewPerHost returns a PerHost Dialer that directs connections to either\n// defaultDialer or bypass, depending on whether the connection matches one of\n// the configured rules.\nfunc proxy_NewPerHost(defaultDialer, bypass proxy_Dialer) *proxy_PerHost {\n\treturn &proxy_PerHost{\n\t\tdef:    defaultDialer,\n\t\tbypass: bypass,\n\t}\n}\n\n// Dial connects to the address addr on the given network through either\n// defaultDialer or bypass.\nfunc (p *proxy_PerHost) Dial(network, addr string) (c net.Conn, err error) {\n\thost, _, err := net.SplitHostPort(addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn p.dialerForRequest(host).Dial(network, addr)\n}\n\nfunc (p *proxy_PerHost) dialerForRequest(host string) proxy_Dialer {\n\tif ip := net.ParseIP(host); ip != nil {\n\t\tfor _, net := range p.bypassNetworks {\n\t\t\tif net.Contains(ip) {\n\t\t\t\treturn p.bypass\n\t\t\t}\n\t\t}\n\t\tfor _, bypassIP := range p.bypassIPs {\n\t\t\tif bypassIP.Equal(ip) {\n\t\t\t\treturn p.bypass\n\t\t\t}\n\t\t}\n\t\treturn p.def\n\t}\n\n\tfor _, zone := range p.bypassZones {\n\t\tif strings.HasSuffix(host, zone) {\n\t\t\treturn p.bypass\n\t\t}\n\t\tif host == zone[1:] {\n\t\t\t// For a zone \".example.com\", we match \"example.com\"\n\t\t\t// too.\n\t\t\treturn p.bypass\n\t\t}\n\t}\n\tfor _, bypassHost := range p.bypassHosts {\n\t\tif bypassHost == host {\n\t\t\treturn p.bypass\n\t\t}\n\t}\n\treturn p.def\n}\n\n// AddFromString parses a string that contains comma-separated values\n// specifying hosts that should use the bypass proxy. Each value is either an\n// IP address, a CIDR range, a zone (*.example.com) or a host name\n// (localhost). A best effort is made to parse the string and errors are\n// ignored.\nfunc (p *proxy_PerHost) AddFromString(s string) {\n\thosts := strings.Split(s, \",\")\n\tfor _, host := range hosts {\n\t\thost = strings.TrimSpace(host)\n\t\tif len(host) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tif strings.Contains(host, \"/\") {\n\t\t\t// We assume that it's a CIDR address like 127.0.0.0/8\n\t\t\tif _, net, err := net.ParseCIDR(host); err == nil {\n\t\t\t\tp.AddNetwork(net)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif ip := net.ParseIP(host); ip != nil {\n\t\t\tp.AddIP(ip)\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(host, \"*.\") {\n\t\t\tp.AddZone(host[1:])\n\t\t\tcontinue\n\t\t}\n\t\tp.AddHost(host)\n\t}\n}\n\n// AddIP specifies an IP address that will use the bypass proxy. Note that\n// this will only take effect if a literal IP address is dialed. A connection\n// to a named host will never match an IP.\nfunc (p *proxy_PerHost) AddIP(ip net.IP) {\n\tp.bypassIPs = append(p.bypassIPs, ip)\n}\n\n// AddNetwork specifies an IP range that will use the bypass proxy. Note that\n// this will only take effect if a literal IP address is dialed. A connection\n// to a named host will never match.\nfunc (p *proxy_PerHost) AddNetwork(net *net.IPNet) {\n\tp.bypassNetworks = append(p.bypassNetworks, net)\n}\n\n// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of\n// \"example.com\" matches \"example.com\" and all of its subdomains.\nfunc (p *proxy_PerHost) AddZone(zone string) {\n\tif strings.HasSuffix(zone, \".\") {\n\t\tzone = zone[:len(zone)-1]\n\t}\n\tif !strings.HasPrefix(zone, \".\") {\n\t\tzone = \".\" + zone\n\t}\n\tp.bypassZones = append(p.bypassZones, zone)\n}\n\n// AddHost specifies a host name that will use the bypass proxy.\nfunc (p *proxy_PerHost) AddHost(host string) {\n\tif strings.HasSuffix(host, \".\") {\n\t\thost = host[:len(host)-1]\n\t}\n\tp.bypassHosts = append(p.bypassHosts, host)\n}\n\n// A Dialer is a means to establish a connection.\ntype proxy_Dialer interface {\n\t// Dial connects to the given address via the proxy.\n\tDial(network, addr string) (c net.Conn, err error)\n}\n\n// Auth contains authentication parameters that specific Dialers may require.\ntype proxy_Auth struct {\n\tUser, Password string\n}\n\n// FromEnvironment returns the dialer specified by the proxy related variables in\n// the environment.\nfunc proxy_FromEnvironment() proxy_Dialer {\n\tallProxy := proxy_allProxyEnv.Get()\n\tif len(allProxy) == 0 {\n\t\treturn proxy_Direct\n\t}\n\n\tproxyURL, err := url.Parse(allProxy)\n\tif err != nil {\n\t\treturn proxy_Direct\n\t}\n\tproxy, err := proxy_FromURL(proxyURL, proxy_Direct)\n\tif err != nil {\n\t\treturn proxy_Direct\n\t}\n\n\tnoProxy := proxy_noProxyEnv.Get()\n\tif len(noProxy) == 0 {\n\t\treturn proxy\n\t}\n\n\tperHost := proxy_NewPerHost(proxy, proxy_Direct)\n\tperHost.AddFromString(noProxy)\n\treturn perHost\n}\n\n// proxySchemes is a map from URL schemes to a function that creates a Dialer\n// from a URL with such a scheme.\nvar proxy_proxySchemes map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error)\n\n// RegisterDialerType takes a URL scheme and a function to generate Dialers from\n// a URL with that scheme and a forwarding Dialer. Registered schemes are used\n// by FromURL.\nfunc proxy_RegisterDialerType(scheme string, f func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) {\n\tif proxy_proxySchemes == nil {\n\t\tproxy_proxySchemes = make(map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error))\n\t}\n\tproxy_proxySchemes[scheme] = f\n}\n\n// FromURL returns a Dialer given a URL specification and an underlying\n// Dialer for it to make network requests.\nfunc proxy_FromURL(u *url.URL, forward proxy_Dialer) (proxy_Dialer, error) {\n\tvar auth *proxy_Auth\n\tif u.User != nil {\n\t\tauth = new(proxy_Auth)\n\t\tauth.User = u.User.Username()\n\t\tif p, ok := u.User.Password(); ok {\n\t\t\tauth.Password = p\n\t\t}\n\t}\n\n\tswitch u.Scheme {\n\tcase \"socks5\":\n\t\treturn proxy_SOCKS5(\"tcp\", u.Host, auth, forward)\n\t}\n\n\t// If the scheme doesn't match any of the built-in schemes, see if it\n\t// was registered by another package.\n\tif proxy_proxySchemes != nil {\n\t\tif f, ok := proxy_proxySchemes[u.Scheme]; ok {\n\t\t\treturn f(u, forward)\n\t\t}\n\t}\n\n\treturn nil, errors.New(\"proxy: unknown scheme: \" + u.Scheme)\n}\n\nvar (\n\tproxy_allProxyEnv = &proxy_envOnce{\n\t\tnames: []string{\"ALL_PROXY\", \"all_proxy\"},\n\t}\n\tproxy_noProxyEnv = &proxy_envOnce{\n\t\tnames: []string{\"NO_PROXY\", \"no_proxy\"},\n\t}\n)\n\n// envOnce looks up an environment variable (optionally by multiple\n// names) once. It mitigates expensive lookups on some platforms\n// (e.g. Windows).\n// (Borrowed from net/http/transport.go)\ntype proxy_envOnce struct {\n\tnames []string\n\tonce  sync.Once\n\tval   string\n}\n\nfunc (e *proxy_envOnce) Get() string {\n\te.once.Do(e.init)\n\treturn e.val\n}\n\nfunc (e *proxy_envOnce) init() {\n\tfor _, n := range e.names {\n\t\te.val = os.Getenv(n)\n\t\tif e.val != \"\" {\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address\n// with an optional username and password. See RFC 1928 and RFC 1929.\nfunc proxy_SOCKS5(network, addr string, auth *proxy_Auth, forward proxy_Dialer) (proxy_Dialer, error) {\n\ts := &proxy_socks5{\n\t\tnetwork: network,\n\t\taddr:    addr,\n\t\tforward: forward,\n\t}\n\tif auth != nil {\n\t\ts.user = auth.User\n\t\ts.password = auth.Password\n\t}\n\n\treturn s, nil\n}\n\ntype proxy_socks5 struct {\n\tuser, password string\n\tnetwork, addr  string\n\tforward        proxy_Dialer\n}\n\nconst proxy_socks5Version = 5\n\nconst (\n\tproxy_socks5AuthNone     = 0\n\tproxy_socks5AuthPassword = 2\n)\n\nconst proxy_socks5Connect = 1\n\nconst (\n\tproxy_socks5IP4    = 1\n\tproxy_socks5Domain = 3\n\tproxy_socks5IP6    = 4\n)\n\nvar proxy_socks5Errors = []string{\n\t\"\",\n\t\"general failure\",\n\t\"connection forbidden\",\n\t\"network unreachable\",\n\t\"host unreachable\",\n\t\"connection refused\",\n\t\"TTL expired\",\n\t\"command not supported\",\n\t\"address type not supported\",\n}\n\n// Dial connects to the address addr on the given network via the SOCKS5 proxy.\nfunc (s *proxy_socks5) Dial(network, addr string) (net.Conn, error) {\n\tswitch network {\n\tcase \"tcp\", \"tcp6\", \"tcp4\":\n\tdefault:\n\t\treturn nil, errors.New(\"proxy: no support for SOCKS5 proxy connections of type \" + network)\n\t}\n\n\tconn, err := s.forward.Dial(s.network, s.addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := s.connect(conn, addr); err != nil {\n\t\tconn.Close()\n\t\treturn nil, err\n\t}\n\treturn conn, nil\n}\n\n// connect takes an existing connection to a socks5 proxy server,\n// and commands the server to extend that connection to target,\n// which must be a canonical address with a host and port.\nfunc (s *proxy_socks5) connect(conn net.Conn, target string) error {\n\thost, portStr, err := net.SplitHostPort(target)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tport, err := strconv.Atoi(portStr)\n\tif err != nil {\n\t\treturn errors.New(\"proxy: failed to parse port number: \" + portStr)\n\t}\n\tif port < 1 || port > 0xffff {\n\t\treturn errors.New(\"proxy: port number out of range: \" + portStr)\n\t}\n\n\t// the size here is just an estimate\n\tbuf := make([]byte, 0, 6+len(host))\n\n\tbuf = append(buf, proxy_socks5Version)\n\tif len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 {\n\t\tbuf = append(buf, 2 /* num auth methods */, proxy_socks5AuthNone, proxy_socks5AuthPassword)\n\t} else {\n\t\tbuf = append(buf, 1 /* num auth methods */, proxy_socks5AuthNone)\n\t}\n\n\tif _, err := conn.Write(buf); err != nil {\n\t\treturn errors.New(\"proxy: failed to write greeting to SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t}\n\n\tif _, err := io.ReadFull(conn, buf[:2]); err != nil {\n\t\treturn errors.New(\"proxy: failed to read greeting from SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t}\n\tif buf[0] != 5 {\n\t\treturn errors.New(\"proxy: SOCKS5 proxy at \" + s.addr + \" has unexpected version \" + strconv.Itoa(int(buf[0])))\n\t}\n\tif buf[1] == 0xff {\n\t\treturn errors.New(\"proxy: SOCKS5 proxy at \" + s.addr + \" requires authentication\")\n\t}\n\n\t// See RFC 1929\n\tif buf[1] == proxy_socks5AuthPassword {\n\t\tbuf = buf[:0]\n\t\tbuf = append(buf, 1 /* password protocol version */)\n\t\tbuf = append(buf, uint8(len(s.user)))\n\t\tbuf = append(buf, s.user...)\n\t\tbuf = append(buf, uint8(len(s.password)))\n\t\tbuf = append(buf, s.password...)\n\n\t\tif _, err := conn.Write(buf); err != nil {\n\t\t\treturn errors.New(\"proxy: failed to write authentication request to SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t\t}\n\n\t\tif _, err := io.ReadFull(conn, buf[:2]); err != nil {\n\t\t\treturn errors.New(\"proxy: failed to read authentication reply from SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t\t}\n\n\t\tif buf[1] != 0 {\n\t\t\treturn errors.New(\"proxy: SOCKS5 proxy at \" + s.addr + \" rejected username/password\")\n\t\t}\n\t}\n\n\tbuf = buf[:0]\n\tbuf = append(buf, proxy_socks5Version, proxy_socks5Connect, 0 /* reserved */)\n\n\tif ip := net.ParseIP(host); ip != nil {\n\t\tif ip4 := ip.To4(); ip4 != nil {\n\t\t\tbuf = append(buf, proxy_socks5IP4)\n\t\t\tip = ip4\n\t\t} else {\n\t\t\tbuf = append(buf, proxy_socks5IP6)\n\t\t}\n\t\tbuf = append(buf, ip...)\n\t} else {\n\t\tif len(host) > 255 {\n\t\t\treturn errors.New(\"proxy: destination host name too long: \" + host)\n\t\t}\n\t\tbuf = append(buf, proxy_socks5Domain)\n\t\tbuf = append(buf, byte(len(host)))\n\t\tbuf = append(buf, host...)\n\t}\n\tbuf = append(buf, byte(port>>8), byte(port))\n\n\tif _, err := conn.Write(buf); err != nil {\n\t\treturn errors.New(\"proxy: failed to write connect request to SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t}\n\n\tif _, err := io.ReadFull(conn, buf[:4]); err != nil {\n\t\treturn errors.New(\"proxy: failed to read connect reply from SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t}\n\n\tfailure := \"unknown error\"\n\tif int(buf[1]) < len(proxy_socks5Errors) {\n\t\tfailure = proxy_socks5Errors[buf[1]]\n\t}\n\n\tif len(failure) > 0 {\n\t\treturn errors.New(\"proxy: SOCKS5 proxy at \" + s.addr + \" failed to connect: \" + failure)\n\t}\n\n\tbytesToDiscard := 0\n\tswitch buf[3] {\n\tcase proxy_socks5IP4:\n\t\tbytesToDiscard = net.IPv4len\n\tcase proxy_socks5IP6:\n\t\tbytesToDiscard = net.IPv6len\n\tcase proxy_socks5Domain:\n\t\t_, err := io.ReadFull(conn, buf[:1])\n\t\tif err != nil {\n\t\t\treturn errors.New(\"proxy: failed to read domain length from SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t\t}\n\t\tbytesToDiscard = int(buf[0])\n\tdefault:\n\t\treturn errors.New(\"proxy: got unknown address type \" + strconv.Itoa(int(buf[3])) + \" from SOCKS5 proxy at \" + s.addr)\n\t}\n\n\tif cap(buf) < bytesToDiscard {\n\t\tbuf = make([]byte, bytesToDiscard)\n\t} else {\n\t\tbuf = buf[:bytesToDiscard]\n\t}\n\tif _, err := io.ReadFull(conn, buf); err != nil {\n\t\treturn errors.New(\"proxy: failed to read address from SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t}\n\n\t// Also need to discard the port number\n\tif _, err := io.ReadFull(conn, buf[:2]); err != nil {\n\t\treturn errors.New(\"proxy: failed to read port from SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/LICENSE",
    "content": "Copyright (c) 2015, Gengo, Inc.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright notice,\n      this 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 Gengo, Inc. nor the names of its\n      contributors may be used to endorse or promote products derived from this\n      software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\nANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/BUILD.bazel",
    "content": "load(\"@io_bazel_rules_go//go:def.bzl\", \"go_library\", \"go_test\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ngo_library(\n    name = \"httprule\",\n    srcs = [\n        \"compile.go\",\n        \"parse.go\",\n        \"types.go\",\n    ],\n    importpath = \"github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule\",\n    deps = [\"//utilities\"],\n)\n\ngo_test(\n    name = \"httprule_test\",\n    size = \"small\",\n    srcs = [\n        \"compile_test.go\",\n        \"parse_test.go\",\n        \"types_test.go\",\n    ],\n    embed = [\":httprule\"],\n    deps = [\n        \"//utilities\",\n        \"@org_golang_google_grpc//grpclog\",\n    ],\n)\n\nalias(\n    name = \"go_default_library\",\n    actual = \":httprule\",\n    visibility = [\"//:__subpackages__\"],\n)\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/compile.go",
    "content": "package httprule\n\nimport (\n\t\"github.com/grpc-ecosystem/grpc-gateway/v2/utilities\"\n)\n\nconst (\n\topcodeVersion = 1\n)\n\n// Template is a compiled representation of path templates.\ntype Template struct {\n\t// Version is the version number of the format.\n\tVersion int\n\t// OpCodes is a sequence of operations.\n\tOpCodes []int\n\t// Pool is a constant pool\n\tPool []string\n\t// Verb is a VERB part in the template.\n\tVerb string\n\t// Fields is a list of field paths bound in this template.\n\tFields []string\n\t// Original template (example: /v1/a_bit_of_everything)\n\tTemplate string\n}\n\n// Compiler compiles utilities representation of path templates into marshallable operations.\n// They can be unmarshalled by runtime.NewPattern.\ntype Compiler interface {\n\tCompile() Template\n}\n\ntype op struct {\n\t// code is the opcode of the operation\n\tcode utilities.OpCode\n\n\t// str is a string operand of the code.\n\t// num is ignored if str is not empty.\n\tstr string\n\n\t// num is a numeric operand of the code.\n\tnum int\n}\n\nfunc (w wildcard) compile() []op {\n\treturn []op{\n\t\t{code: utilities.OpPush},\n\t}\n}\n\nfunc (w deepWildcard) compile() []op {\n\treturn []op{\n\t\t{code: utilities.OpPushM},\n\t}\n}\n\nfunc (l literal) compile() []op {\n\treturn []op{\n\t\t{\n\t\t\tcode: utilities.OpLitPush,\n\t\t\tstr:  string(l),\n\t\t},\n\t}\n}\n\nfunc (v variable) compile() []op {\n\tvar ops []op\n\tfor _, s := range v.segments {\n\t\tops = append(ops, s.compile()...)\n\t}\n\tops = append(ops, op{\n\t\tcode: utilities.OpConcatN,\n\t\tnum:  len(v.segments),\n\t}, op{\n\t\tcode: utilities.OpCapture,\n\t\tstr:  v.path,\n\t})\n\n\treturn ops\n}\n\nfunc (t template) Compile() Template {\n\tvar rawOps []op\n\tfor _, s := range t.segments {\n\t\trawOps = append(rawOps, s.compile()...)\n\t}\n\n\tvar (\n\t\tops    []int\n\t\tpool   []string\n\t\tfields []string\n\t)\n\tconsts := make(map[string]int)\n\tfor _, op := range rawOps {\n\t\tops = append(ops, int(op.code))\n\t\tif op.str == \"\" {\n\t\t\tops = append(ops, op.num)\n\t\t} else {\n\t\t\t// eof segment literal represents the \"/\" path pattern\n\t\t\tif op.str == eof {\n\t\t\t\top.str = \"\"\n\t\t\t}\n\t\t\tif _, ok := consts[op.str]; !ok {\n\t\t\t\tconsts[op.str] = len(pool)\n\t\t\t\tpool = append(pool, op.str)\n\t\t\t}\n\t\t\tops = append(ops, consts[op.str])\n\t\t}\n\t\tif op.code == utilities.OpCapture {\n\t\t\tfields = append(fields, op.str)\n\t\t}\n\t}\n\treturn Template{\n\t\tVersion:  opcodeVersion,\n\t\tOpCodes:  ops,\n\t\tPool:     pool,\n\t\tVerb:     t.verb,\n\t\tFields:   fields,\n\t\tTemplate: t.template,\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/fuzz.go",
    "content": "//go:build gofuzz\n// +build gofuzz\n\npackage httprule\n\nfunc Fuzz(data []byte) int {\n\tif _, err := Parse(string(data)); err != nil {\n\t\treturn 0\n\t}\n\treturn 0\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/parse.go",
    "content": "package httprule\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n)\n\n// InvalidTemplateError indicates that the path template is not valid.\ntype InvalidTemplateError struct {\n\ttmpl string\n\tmsg  string\n}\n\nfunc (e InvalidTemplateError) Error() string {\n\treturn fmt.Sprintf(\"%s: %s\", e.msg, e.tmpl)\n}\n\n// Parse parses the string representation of path template\nfunc Parse(tmpl string) (Compiler, error) {\n\tif !strings.HasPrefix(tmpl, \"/\") {\n\t\treturn template{}, InvalidTemplateError{tmpl: tmpl, msg: \"no leading /\"}\n\t}\n\ttokens, verb := tokenize(tmpl[1:])\n\n\tp := parser{tokens: tokens}\n\tsegs, err := p.topLevelSegments()\n\tif err != nil {\n\t\treturn template{}, InvalidTemplateError{tmpl: tmpl, msg: err.Error()}\n\t}\n\n\treturn template{\n\t\tsegments: segs,\n\t\tverb:     verb,\n\t\ttemplate: tmpl,\n\t}, nil\n}\n\nfunc tokenize(path string) (tokens []string, verb string) {\n\tif path == \"\" {\n\t\treturn []string{eof}, \"\"\n\t}\n\n\tconst (\n\t\tinit = iota\n\t\tfield\n\t\tnested\n\t)\n\tst := init\n\tfor path != \"\" {\n\t\tvar idx int\n\t\tswitch st {\n\t\tcase init:\n\t\t\tidx = strings.IndexAny(path, \"/{\")\n\t\tcase field:\n\t\t\tidx = strings.IndexAny(path, \".=}\")\n\t\tcase nested:\n\t\t\tidx = strings.IndexAny(path, \"/}\")\n\t\t}\n\t\tif idx < 0 {\n\t\t\ttokens = append(tokens, path)\n\t\t\tbreak\n\t\t}\n\t\tswitch r := path[idx]; r {\n\t\tcase '/', '.':\n\t\tcase '{':\n\t\t\tst = field\n\t\tcase '=':\n\t\t\tst = nested\n\t\tcase '}':\n\t\t\tst = init\n\t\t}\n\t\tif idx == 0 {\n\t\t\ttokens = append(tokens, path[idx:idx+1])\n\t\t} else {\n\t\t\ttokens = append(tokens, path[:idx], path[idx:idx+1])\n\t\t}\n\t\tpath = path[idx+1:]\n\t}\n\n\tl := len(tokens)\n\t// See\n\t// https://github.com/grpc-ecosystem/grpc-gateway/pull/1947#issuecomment-774523693 ;\n\t// although normal and backwards-compat logic here is to use the last index\n\t// of a colon, if the final segment is a variable followed by a colon, the\n\t// part following the colon must be a verb. Hence if the previous token is\n\t// an end var marker, we switch the index we're looking for to Index instead\n\t// of LastIndex, so that we correctly grab the remaining part of the path as\n\t// the verb.\n\tvar penultimateTokenIsEndVar bool\n\tswitch l {\n\tcase 0, 1:\n\t\t// Not enough to be variable so skip this logic and don't result in an\n\t\t// invalid index\n\tdefault:\n\t\tpenultimateTokenIsEndVar = tokens[l-2] == \"}\"\n\t}\n\tt := tokens[l-1]\n\tvar idx int\n\tif penultimateTokenIsEndVar {\n\t\tidx = strings.Index(t, \":\")\n\t} else {\n\t\tidx = strings.LastIndex(t, \":\")\n\t}\n\tif idx == 0 {\n\t\ttokens, verb = tokens[:l-1], t[1:]\n\t} else if idx > 0 {\n\t\ttokens[l-1], verb = t[:idx], t[idx+1:]\n\t}\n\ttokens = append(tokens, eof)\n\treturn tokens, verb\n}\n\n// parser is a parser of the template syntax defined in github.com/googleapis/googleapis/google/api/http.proto.\ntype parser struct {\n\ttokens   []string\n\taccepted []string\n}\n\n// topLevelSegments is the target of this parser.\nfunc (p *parser) topLevelSegments() ([]segment, error) {\n\tif _, err := p.accept(typeEOF); err == nil {\n\t\tp.tokens = p.tokens[:0]\n\t\treturn []segment{literal(eof)}, nil\n\t}\n\tsegs, err := p.segments()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif _, err := p.accept(typeEOF); err != nil {\n\t\treturn nil, fmt.Errorf(\"unexpected token %q after segments %q\", p.tokens[0], strings.Join(p.accepted, \"\"))\n\t}\n\treturn segs, nil\n}\n\nfunc (p *parser) segments() ([]segment, error) {\n\ts, err := p.segment()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsegs := []segment{s}\n\tfor {\n\t\tif _, err := p.accept(\"/\"); err != nil {\n\t\t\treturn segs, nil\n\t\t}\n\t\ts, err := p.segment()\n\t\tif err != nil {\n\t\t\treturn segs, err\n\t\t}\n\t\tsegs = append(segs, s)\n\t}\n}\n\nfunc (p *parser) segment() (segment, error) {\n\tif _, err := p.accept(\"*\"); err == nil {\n\t\treturn wildcard{}, nil\n\t}\n\tif _, err := p.accept(\"**\"); err == nil {\n\t\treturn deepWildcard{}, nil\n\t}\n\tif l, err := p.literal(); err == nil {\n\t\treturn l, nil\n\t}\n\n\tv, err := p.variable()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"segment neither wildcards, literal or variable: %w\", err)\n\t}\n\treturn v, nil\n}\n\nfunc (p *parser) literal() (segment, error) {\n\tlit, err := p.accept(typeLiteral)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn literal(lit), nil\n}\n\nfunc (p *parser) variable() (segment, error) {\n\tif _, err := p.accept(\"{\"); err != nil {\n\t\treturn nil, err\n\t}\n\n\tpath, err := p.fieldPath()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar segs []segment\n\tif _, err := p.accept(\"=\"); err == nil {\n\t\tsegs, err = p.segments()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid segment in variable %q: %w\", path, err)\n\t\t}\n\t} else {\n\t\tsegs = []segment{wildcard{}}\n\t}\n\n\tif _, err := p.accept(\"}\"); err != nil {\n\t\treturn nil, fmt.Errorf(\"unterminated variable segment: %s\", path)\n\t}\n\treturn variable{\n\t\tpath:     path,\n\t\tsegments: segs,\n\t}, nil\n}\n\nfunc (p *parser) fieldPath() (string, error) {\n\tc, err := p.accept(typeIdent)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tcomponents := []string{c}\n\tfor {\n\t\tif _, err := p.accept(\".\"); err != nil {\n\t\t\treturn strings.Join(components, \".\"), nil\n\t\t}\n\t\tc, err := p.accept(typeIdent)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"invalid field path component: %w\", err)\n\t\t}\n\t\tcomponents = append(components, c)\n\t}\n}\n\n// A termType is a type of terminal symbols.\ntype termType string\n\n// These constants define some of valid values of termType.\n// They improve readability of parse functions.\n//\n// You can also use \"/\", \"*\", \"**\", \".\" or \"=\" as valid values.\nconst (\n\ttypeIdent   = termType(\"ident\")\n\ttypeLiteral = termType(\"literal\")\n\ttypeEOF     = termType(\"$\")\n)\n\n// eof is the terminal symbol which always appears at the end of token sequence.\nconst eof = \"\\u0000\"\n\n// accept tries to accept a token in \"p\".\n// This function consumes a token and returns it if it matches to the specified \"term\".\n// If it doesn't match, the function does not consume any tokens and return an error.\nfunc (p *parser) accept(term termType) (string, error) {\n\tt := p.tokens[0]\n\tswitch term {\n\tcase \"/\", \"*\", \"**\", \".\", \"=\", \"{\", \"}\":\n\t\tif t != string(term) && t != \"/\" {\n\t\t\treturn \"\", fmt.Errorf(\"expected %q but got %q\", term, t)\n\t\t}\n\tcase typeEOF:\n\t\tif t != eof {\n\t\t\treturn \"\", fmt.Errorf(\"expected EOF but got %q\", t)\n\t\t}\n\tcase typeIdent:\n\t\tif err := expectIdent(t); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\tcase typeLiteral:\n\t\tif err := expectPChars(t); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\tdefault:\n\t\treturn \"\", fmt.Errorf(\"unknown termType %q\", term)\n\t}\n\tp.tokens = p.tokens[1:]\n\tp.accepted = append(p.accepted, t)\n\treturn t, nil\n}\n\n// expectPChars determines if \"t\" consists of only pchars defined in RFC3986.\n//\n// https://www.ietf.org/rfc/rfc3986.txt, P.49\n//\n//\tpchar         = unreserved / pct-encoded / sub-delims / \":\" / \"@\"\n//\tunreserved    = ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\n//\tsub-delims    = \"!\" / \"$\" / \"&\" / \"'\" / \"(\" / \")\"\n//\t              / \"*\" / \"+\" / \",\" / \";\" / \"=\"\n//\tpct-encoded   = \"%\" HEXDIG HEXDIG\nfunc expectPChars(t string) error {\n\tconst (\n\t\tinit = iota\n\t\tpct1\n\t\tpct2\n\t)\n\tst := init\n\tfor _, r := range t {\n\t\tif st != init {\n\t\t\tif !isHexDigit(r) {\n\t\t\t\treturn fmt.Errorf(\"invalid hexdigit: %c(%U)\", r, r)\n\t\t\t}\n\t\t\tswitch st {\n\t\t\tcase pct1:\n\t\t\t\tst = pct2\n\t\t\tcase pct2:\n\t\t\t\tst = init\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// unreserved\n\t\tswitch {\n\t\tcase 'A' <= r && r <= 'Z':\n\t\t\tcontinue\n\t\tcase 'a' <= r && r <= 'z':\n\t\t\tcontinue\n\t\tcase '0' <= r && r <= '9':\n\t\t\tcontinue\n\t\t}\n\t\tswitch r {\n\t\tcase '-', '.', '_', '~':\n\t\t\t// unreserved\n\t\tcase '!', '$', '&', '\\'', '(', ')', '*', '+', ',', ';', '=':\n\t\t\t// sub-delims\n\t\tcase ':', '@':\n\t\t\t// rest of pchar\n\t\tcase '%':\n\t\t\t// pct-encoded\n\t\t\tst = pct1\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"invalid character in path segment: %q(%U)\", r, r)\n\t\t}\n\t}\n\tif st != init {\n\t\treturn fmt.Errorf(\"invalid percent-encoding in %q\", t)\n\t}\n\treturn nil\n}\n\n// expectIdent determines if \"ident\" is a valid identifier in .proto schema ([[:alpha:]_][[:alphanum:]_]*).\nfunc expectIdent(ident string) error {\n\tif ident == \"\" {\n\t\treturn errors.New(\"empty identifier\")\n\t}\n\tfor pos, r := range ident {\n\t\tswitch {\n\t\tcase '0' <= r && r <= '9':\n\t\t\tif pos == 0 {\n\t\t\t\treturn fmt.Errorf(\"identifier starting with digit: %s\", ident)\n\t\t\t}\n\t\t\tcontinue\n\t\tcase 'A' <= r && r <= 'Z':\n\t\t\tcontinue\n\t\tcase 'a' <= r && r <= 'z':\n\t\t\tcontinue\n\t\tcase r == '_':\n\t\t\tcontinue\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"invalid character %q(%U) in identifier: %s\", r, r, ident)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc isHexDigit(r rune) bool {\n\tswitch {\n\tcase '0' <= r && r <= '9':\n\t\treturn true\n\tcase 'A' <= r && r <= 'F':\n\t\treturn true\n\tcase 'a' <= r && r <= 'f':\n\t\treturn true\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule/types.go",
    "content": "package httprule\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype template struct {\n\tsegments []segment\n\tverb     string\n\ttemplate string\n}\n\ntype segment interface {\n\tfmt.Stringer\n\tcompile() (ops []op)\n}\n\ntype wildcard struct{}\n\ntype deepWildcard struct{}\n\ntype literal string\n\ntype variable struct {\n\tpath     string\n\tsegments []segment\n}\n\nfunc (wildcard) String() string {\n\treturn \"*\"\n}\n\nfunc (deepWildcard) String() string {\n\treturn \"**\"\n}\n\nfunc (l literal) String() string {\n\treturn string(l)\n}\n\nfunc (v variable) String() string {\n\tvar segs []string\n\tfor _, s := range v.segments {\n\t\tsegs = append(segs, s.String())\n\t}\n\treturn fmt.Sprintf(\"{%s=%s}\", v.path, strings.Join(segs, \"/\"))\n}\n\nfunc (t template) String() string {\n\tvar segs []string\n\tfor _, s := range t.segments {\n\t\tsegs = append(segs, s.String())\n\t}\n\tstr := strings.Join(segs, \"/\")\n\tif t.verb != \"\" {\n\t\tstr = fmt.Sprintf(\"%s:%s\", str, t.verb)\n\t}\n\treturn \"/\" + str\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/BUILD.bazel",
    "content": "load(\"@io_bazel_rules_go//go:def.bzl\", \"go_library\", \"go_test\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ngo_library(\n    name = \"runtime\",\n    srcs = [\n        \"context.go\",\n        \"convert.go\",\n        \"doc.go\",\n        \"errors.go\",\n        \"fieldmask.go\",\n        \"handler.go\",\n        \"marshal_httpbodyproto.go\",\n        \"marshal_json.go\",\n        \"marshal_jsonpb.go\",\n        \"marshal_proto.go\",\n        \"marshaler.go\",\n        \"marshaler_registry.go\",\n        \"mux.go\",\n        \"pattern.go\",\n        \"proto2_convert.go\",\n        \"query.go\",\n    ],\n    importpath = \"github.com/grpc-ecosystem/grpc-gateway/v2/runtime\",\n    deps = [\n        \"//internal/httprule\",\n        \"//utilities\",\n        \"@org_golang_google_genproto_googleapis_api//httpbody\",\n        \"@org_golang_google_grpc//codes\",\n        \"@org_golang_google_grpc//grpclog\",\n        \"@org_golang_google_grpc//health/grpc_health_v1\",\n        \"@org_golang_google_grpc//metadata\",\n        \"@org_golang_google_grpc//status\",\n        \"@org_golang_google_protobuf//encoding/protojson\",\n        \"@org_golang_google_protobuf//proto\",\n        \"@org_golang_google_protobuf//reflect/protoreflect\",\n        \"@org_golang_google_protobuf//reflect/protoregistry\",\n        \"@org_golang_google_protobuf//types/known/durationpb\",\n        \"@org_golang_google_protobuf//types/known/fieldmaskpb\",\n        \"@org_golang_google_protobuf//types/known/structpb\",\n        \"@org_golang_google_protobuf//types/known/timestamppb\",\n        \"@org_golang_google_protobuf//types/known/wrapperspb\",\n    ],\n)\n\ngo_test(\n    name = \"runtime_test\",\n    size = \"small\",\n    srcs = [\n        \"context_test.go\",\n        \"convert_test.go\",\n        \"errors_test.go\",\n        \"fieldmask_test.go\",\n        \"handler_test.go\",\n        \"marshal_httpbodyproto_test.go\",\n        \"marshal_json_test.go\",\n        \"marshal_jsonpb_test.go\",\n        \"marshal_proto_test.go\",\n        \"marshaler_registry_test.go\",\n        \"mux_internal_test.go\",\n        \"mux_test.go\",\n        \"pattern_test.go\",\n        \"query_fuzz_test.go\",\n        \"query_test.go\",\n    ],\n    embed = [\":runtime\"],\n    deps = [\n        \"//runtime/internal/examplepb\",\n        \"//utilities\",\n        \"@com_github_google_go_cmp//cmp\",\n        \"@com_github_google_go_cmp//cmp/cmpopts\",\n        \"@org_golang_google_genproto_googleapis_api//httpbody\",\n        \"@org_golang_google_genproto_googleapis_rpc//errdetails\",\n        \"@org_golang_google_genproto_googleapis_rpc//status\",\n        \"@org_golang_google_grpc//:grpc\",\n        \"@org_golang_google_grpc//codes\",\n        \"@org_golang_google_grpc//health/grpc_health_v1\",\n        \"@org_golang_google_grpc//metadata\",\n        \"@org_golang_google_grpc//status\",\n        \"@org_golang_google_protobuf//encoding/protojson\",\n        \"@org_golang_google_protobuf//proto\",\n        \"@org_golang_google_protobuf//testing/protocmp\",\n        \"@org_golang_google_protobuf//types/known/durationpb\",\n        \"@org_golang_google_protobuf//types/known/emptypb\",\n        \"@org_golang_google_protobuf//types/known/fieldmaskpb\",\n        \"@org_golang_google_protobuf//types/known/structpb\",\n        \"@org_golang_google_protobuf//types/known/timestamppb\",\n        \"@org_golang_google_protobuf//types/known/wrapperspb\",\n    ],\n)\n\nalias(\n    name = \"go_default_library\",\n    actual = \":runtime\",\n    visibility = [\"//visibility:public\"],\n)\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/context.go",
    "content": "package runtime\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/textproto\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/grpclog\"\n\t\"google.golang.org/grpc/metadata\"\n\t\"google.golang.org/grpc/status\"\n)\n\n// MetadataHeaderPrefix is the http prefix that represents custom metadata\n// parameters to or from a gRPC call.\nconst MetadataHeaderPrefix = \"Grpc-Metadata-\"\n\n// MetadataPrefix is prepended to permanent HTTP header keys (as specified\n// by the IANA) when added to the gRPC context.\nconst MetadataPrefix = \"grpcgateway-\"\n\n// MetadataTrailerPrefix is prepended to gRPC metadata as it is converted to\n// HTTP headers in a response handled by grpc-gateway\nconst MetadataTrailerPrefix = \"Grpc-Trailer-\"\n\nconst metadataGrpcTimeout = \"Grpc-Timeout\"\nconst metadataHeaderBinarySuffix = \"-Bin\"\n\nconst xForwardedFor = \"X-Forwarded-For\"\nconst xForwardedHost = \"X-Forwarded-Host\"\n\n// DefaultContextTimeout is used for gRPC call context.WithTimeout whenever a Grpc-Timeout inbound\n// header isn't present. If the value is 0 the sent `context` will not have a timeout.\nvar DefaultContextTimeout = 0 * time.Second\n\n// malformedHTTPHeaders lists the headers that the gRPC server may reject outright as malformed.\n// See https://github.com/grpc/grpc-go/pull/4803#issuecomment-986093310 for more context.\nvar malformedHTTPHeaders = map[string]struct{}{\n\t\"connection\": {},\n}\n\ntype (\n\trpcMethodKey       struct{}\n\thttpPathPatternKey struct{}\n\thttpPatternKey     struct{}\n\n\tAnnotateContextOption func(ctx context.Context) context.Context\n)\n\nfunc WithHTTPPathPattern(pattern string) AnnotateContextOption {\n\treturn func(ctx context.Context) context.Context {\n\t\treturn withHTTPPathPattern(ctx, pattern)\n\t}\n}\n\nfunc decodeBinHeader(v string) ([]byte, error) {\n\tif len(v)%4 == 0 {\n\t\t// Input was padded, or padding was not necessary.\n\t\treturn base64.StdEncoding.DecodeString(v)\n\t}\n\treturn base64.RawStdEncoding.DecodeString(v)\n}\n\n/*\nAnnotateContext adds context information such as metadata from the request.\n\nAt a minimum, the RemoteAddr is included in the fashion of \"X-Forwarded-For\",\nexcept that the forwarded destination is not another HTTP service but rather\na gRPC service.\n*/\nfunc AnnotateContext(ctx context.Context, mux *ServeMux, req *http.Request, rpcMethodName string, options ...AnnotateContextOption) (context.Context, error) {\n\tctx, md, err := annotateContext(ctx, mux, req, rpcMethodName, options...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif md == nil {\n\t\treturn ctx, nil\n\t}\n\n\treturn metadata.NewOutgoingContext(ctx, md), nil\n}\n\n// AnnotateIncomingContext adds context information such as metadata from the request.\n// Attach metadata as incoming context.\nfunc AnnotateIncomingContext(ctx context.Context, mux *ServeMux, req *http.Request, rpcMethodName string, options ...AnnotateContextOption) (context.Context, error) {\n\tctx, md, err := annotateContext(ctx, mux, req, rpcMethodName, options...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif md == nil {\n\t\treturn ctx, nil\n\t}\n\n\treturn metadata.NewIncomingContext(ctx, md), nil\n}\n\nfunc isValidGRPCMetadataKey(key string) bool {\n\t// Must be a valid gRPC \"Header-Name\" as defined here:\n\t//   https://github.com/grpc/grpc/blob/4b05dc88b724214d0c725c8e7442cbc7a61b1374/doc/PROTOCOL-HTTP2.md\n\t// This means 0-9 a-z _ - .\n\t// Only lowercase letters are valid in the wire protocol, but the client library will normalize\n\t// uppercase ASCII to lowercase, so uppercase ASCII is also acceptable.\n\tbytes := []byte(key) // gRPC validates strings on the byte level, not Unicode.\n\tfor _, ch := range bytes {\n\t\tvalidLowercaseLetter := ch >= 'a' && ch <= 'z'\n\t\tvalidUppercaseLetter := ch >= 'A' && ch <= 'Z'\n\t\tvalidDigit := ch >= '0' && ch <= '9'\n\t\tvalidOther := ch == '.' || ch == '-' || ch == '_'\n\t\tif !validLowercaseLetter && !validUppercaseLetter && !validDigit && !validOther {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc isValidGRPCMetadataTextValue(textValue string) bool {\n\t// Must be a valid gRPC \"ASCII-Value\" as defined here:\n\t//   https://github.com/grpc/grpc/blob/4b05dc88b724214d0c725c8e7442cbc7a61b1374/doc/PROTOCOL-HTTP2.md\n\t// This means printable ASCII (including/plus spaces); 0x20 to 0x7E inclusive.\n\tbytes := []byte(textValue) // gRPC validates strings on the byte level, not Unicode.\n\tfor _, ch := range bytes {\n\t\tif ch < 0x20 || ch > 0x7E {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc annotateContext(ctx context.Context, mux *ServeMux, req *http.Request, rpcMethodName string, options ...AnnotateContextOption) (context.Context, metadata.MD, error) {\n\tctx = withRPCMethod(ctx, rpcMethodName)\n\tfor _, o := range options {\n\t\tctx = o(ctx)\n\t}\n\ttimeout := DefaultContextTimeout\n\tif tm := req.Header.Get(metadataGrpcTimeout); tm != \"\" {\n\t\tvar err error\n\t\ttimeout, err = timeoutDecode(tm)\n\t\tif err != nil {\n\t\t\treturn nil, nil, status.Errorf(codes.InvalidArgument, \"invalid grpc-timeout: %s\", tm)\n\t\t}\n\t}\n\tvar pairs []string\n\tfor key, vals := range req.Header {\n\t\tkey = textproto.CanonicalMIMEHeaderKey(key)\n\t\tswitch key {\n\t\tcase xForwardedFor, xForwardedHost:\n\t\t\t// Handled separately below\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, val := range vals {\n\t\t\t// For backwards-compatibility, pass through 'authorization' header with no prefix.\n\t\t\tif key == \"Authorization\" {\n\t\t\t\tpairs = append(pairs, \"authorization\", val)\n\t\t\t}\n\t\t\tif h, ok := mux.incomingHeaderMatcher(key); ok {\n\t\t\t\tif !isValidGRPCMetadataKey(h) {\n\t\t\t\t\tgrpclog.Errorf(\"HTTP header name %q is not valid as gRPC metadata key; skipping\", h)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\t// Handles \"-bin\" metadata in grpc, since grpc will do another base64\n\t\t\t\t// encode before sending to server, we need to decode it first.\n\t\t\t\tif strings.HasSuffix(key, metadataHeaderBinarySuffix) {\n\t\t\t\t\tb, err := decodeBinHeader(val)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, nil, status.Errorf(codes.InvalidArgument, \"invalid binary header %s: %s\", key, err)\n\t\t\t\t\t}\n\n\t\t\t\t\tval = string(b)\n\t\t\t\t} else if !isValidGRPCMetadataTextValue(val) {\n\t\t\t\t\tgrpclog.Errorf(\"Value of HTTP header %q contains non-ASCII value (not valid as gRPC metadata): skipping\", h)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tpairs = append(pairs, h, val)\n\t\t\t}\n\t\t}\n\t}\n\tif host := req.Header.Get(xForwardedHost); host != \"\" {\n\t\tpairs = append(pairs, strings.ToLower(xForwardedHost), host)\n\t} else if req.Host != \"\" {\n\t\tpairs = append(pairs, strings.ToLower(xForwardedHost), req.Host)\n\t}\n\n\txff := req.Header.Values(xForwardedFor)\n\tif addr := req.RemoteAddr; addr != \"\" {\n\t\tif remoteIP, _, err := net.SplitHostPort(addr); err == nil {\n\t\t\txff = append(xff, remoteIP)\n\t\t}\n\t}\n\tif len(xff) > 0 {\n\t\tpairs = append(pairs, strings.ToLower(xForwardedFor), strings.Join(xff, \", \"))\n\t}\n\n\tif timeout != 0 {\n\t\tctx, _ = context.WithTimeout(ctx, timeout)\n\t}\n\tif len(pairs) == 0 {\n\t\treturn ctx, nil, nil\n\t}\n\tmd := metadata.Pairs(pairs...)\n\tfor _, mda := range mux.metadataAnnotators {\n\t\tmd = metadata.Join(md, mda(ctx, req))\n\t}\n\treturn ctx, md, nil\n}\n\n// ServerMetadata consists of metadata sent from gRPC server.\ntype ServerMetadata struct {\n\tHeaderMD  metadata.MD\n\tTrailerMD metadata.MD\n}\n\ntype serverMetadataKey struct{}\n\n// NewServerMetadataContext creates a new context with ServerMetadata\nfunc NewServerMetadataContext(ctx context.Context, md ServerMetadata) context.Context {\n\tif ctx == nil {\n\t\tctx = context.Background()\n\t}\n\treturn context.WithValue(ctx, serverMetadataKey{}, md)\n}\n\n// ServerMetadataFromContext returns the ServerMetadata in ctx\nfunc ServerMetadataFromContext(ctx context.Context) (md ServerMetadata, ok bool) {\n\tif ctx == nil {\n\t\treturn md, false\n\t}\n\tmd, ok = ctx.Value(serverMetadataKey{}).(ServerMetadata)\n\treturn\n}\n\n// ServerTransportStream implements grpc.ServerTransportStream.\n// It should only be used by the generated files to support grpc.SendHeader\n// outside of gRPC server use.\ntype ServerTransportStream struct {\n\tmu      sync.Mutex\n\theader  metadata.MD\n\ttrailer metadata.MD\n}\n\n// Method returns the method for the stream.\nfunc (s *ServerTransportStream) Method() string {\n\treturn \"\"\n}\n\n// Header returns the header metadata of the stream.\nfunc (s *ServerTransportStream) Header() metadata.MD {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.header.Copy()\n}\n\n// SetHeader sets the header metadata.\nfunc (s *ServerTransportStream) SetHeader(md metadata.MD) error {\n\tif md.Len() == 0 {\n\t\treturn nil\n\t}\n\n\ts.mu.Lock()\n\ts.header = metadata.Join(s.header, md)\n\ts.mu.Unlock()\n\treturn nil\n}\n\n// SendHeader sets the header metadata.\nfunc (s *ServerTransportStream) SendHeader(md metadata.MD) error {\n\treturn s.SetHeader(md)\n}\n\n// Trailer returns the cached trailer metadata.\nfunc (s *ServerTransportStream) Trailer() metadata.MD {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.trailer.Copy()\n}\n\n// SetTrailer sets the trailer metadata.\nfunc (s *ServerTransportStream) SetTrailer(md metadata.MD) error {\n\tif md.Len() == 0 {\n\t\treturn nil\n\t}\n\n\ts.mu.Lock()\n\ts.trailer = metadata.Join(s.trailer, md)\n\ts.mu.Unlock()\n\treturn nil\n}\n\nfunc timeoutDecode(s string) (time.Duration, error) {\n\tsize := len(s)\n\tif size < 2 {\n\t\treturn 0, fmt.Errorf(\"timeout string is too short: %q\", s)\n\t}\n\td, ok := timeoutUnitToDuration(s[size-1])\n\tif !ok {\n\t\treturn 0, fmt.Errorf(\"timeout unit is not recognized: %q\", s)\n\t}\n\tt, err := strconv.ParseInt(s[:size-1], 10, 64)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn d * time.Duration(t), nil\n}\n\nfunc timeoutUnitToDuration(u uint8) (d time.Duration, ok bool) {\n\tswitch u {\n\tcase 'H':\n\t\treturn time.Hour, true\n\tcase 'M':\n\t\treturn time.Minute, true\n\tcase 'S':\n\t\treturn time.Second, true\n\tcase 'm':\n\t\treturn time.Millisecond, true\n\tcase 'u':\n\t\treturn time.Microsecond, true\n\tcase 'n':\n\t\treturn time.Nanosecond, true\n\tdefault:\n\t\treturn\n\t}\n}\n\n// isPermanentHTTPHeader checks whether hdr belongs to the list of\n// permanent request headers maintained by IANA.\n// http://www.iana.org/assignments/message-headers/message-headers.xml\nfunc isPermanentHTTPHeader(hdr string) bool {\n\tswitch hdr {\n\tcase\n\t\t\"Accept\",\n\t\t\"Accept-Charset\",\n\t\t\"Accept-Language\",\n\t\t\"Accept-Ranges\",\n\t\t\"Authorization\",\n\t\t\"Cache-Control\",\n\t\t\"Content-Type\",\n\t\t\"Cookie\",\n\t\t\"Date\",\n\t\t\"Expect\",\n\t\t\"From\",\n\t\t\"Host\",\n\t\t\"If-Match\",\n\t\t\"If-Modified-Since\",\n\t\t\"If-None-Match\",\n\t\t\"If-Schedule-Tag-Match\",\n\t\t\"If-Unmodified-Since\",\n\t\t\"Max-Forwards\",\n\t\t\"Origin\",\n\t\t\"Pragma\",\n\t\t\"Referer\",\n\t\t\"User-Agent\",\n\t\t\"Via\",\n\t\t\"Warning\":\n\t\treturn true\n\t}\n\treturn false\n}\n\n// isMalformedHTTPHeader checks whether header belongs to the list of\n// \"malformed headers\" and would be rejected by the gRPC server.\nfunc isMalformedHTTPHeader(header string) bool {\n\t_, isMalformed := malformedHTTPHeaders[strings.ToLower(header)]\n\treturn isMalformed\n}\n\n// RPCMethod returns the method string for the server context. The returned\n// string is in the format of \"/package.service/method\".\nfunc RPCMethod(ctx context.Context) (string, bool) {\n\tm := ctx.Value(rpcMethodKey{})\n\tif m == nil {\n\t\treturn \"\", false\n\t}\n\tms, ok := m.(string)\n\tif !ok {\n\t\treturn \"\", false\n\t}\n\treturn ms, true\n}\n\nfunc withRPCMethod(ctx context.Context, rpcMethodName string) context.Context {\n\treturn context.WithValue(ctx, rpcMethodKey{}, rpcMethodName)\n}\n\n// HTTPPathPattern returns the HTTP path pattern string relating to the HTTP handler, if one exists.\n// The format of the returned string is defined by the google.api.http path template type.\nfunc HTTPPathPattern(ctx context.Context) (string, bool) {\n\tm := ctx.Value(httpPathPatternKey{})\n\tif m == nil {\n\t\treturn \"\", false\n\t}\n\tms, ok := m.(string)\n\tif !ok {\n\t\treturn \"\", false\n\t}\n\treturn ms, true\n}\n\nfunc withHTTPPathPattern(ctx context.Context, httpPathPattern string) context.Context {\n\treturn context.WithValue(ctx, httpPathPatternKey{}, httpPathPattern)\n}\n\n// HTTPPattern returns the HTTP path pattern struct relating to the HTTP handler, if one exists.\nfunc HTTPPattern(ctx context.Context) (Pattern, bool) {\n\tv, ok := ctx.Value(httpPatternKey{}).(Pattern)\n\treturn v, ok\n}\n\nfunc withHTTPPattern(ctx context.Context, httpPattern Pattern) context.Context {\n\treturn context.WithValue(ctx, httpPatternKey{}, httpPattern)\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/convert.go",
    "content": "package runtime\n\nimport (\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"google.golang.org/protobuf/encoding/protojson\"\n\t\"google.golang.org/protobuf/types/known/durationpb\"\n\t\"google.golang.org/protobuf/types/known/timestamppb\"\n\t\"google.golang.org/protobuf/types/known/wrapperspb\"\n)\n\n// String just returns the given string.\n// It is just for compatibility to other types.\nfunc String(val string) (string, error) {\n\treturn val, nil\n}\n\n// StringSlice converts 'val' where individual strings are separated by\n// 'sep' into a string slice.\nfunc StringSlice(val, sep string) ([]string, error) {\n\treturn strings.Split(val, sep), nil\n}\n\n// Bool converts the given string representation of a boolean value into bool.\nfunc Bool(val string) (bool, error) {\n\treturn strconv.ParseBool(val)\n}\n\n// BoolSlice converts 'val' where individual booleans are separated by\n// 'sep' into a bool slice.\nfunc BoolSlice(val, sep string) ([]bool, error) {\n\ts := strings.Split(val, sep)\n\tvalues := make([]bool, len(s))\n\tfor i, v := range s {\n\t\tvalue, err := Bool(v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalues[i] = value\n\t}\n\treturn values, nil\n}\n\n// Float64 converts the given string representation into representation of a floating point number into float64.\nfunc Float64(val string) (float64, error) {\n\treturn strconv.ParseFloat(val, 64)\n}\n\n// Float64Slice converts 'val' where individual floating point numbers are separated by\n// 'sep' into a float64 slice.\nfunc Float64Slice(val, sep string) ([]float64, error) {\n\ts := strings.Split(val, sep)\n\tvalues := make([]float64, len(s))\n\tfor i, v := range s {\n\t\tvalue, err := Float64(v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalues[i] = value\n\t}\n\treturn values, nil\n}\n\n// Float32 converts the given string representation of a floating point number into float32.\nfunc Float32(val string) (float32, error) {\n\tf, err := strconv.ParseFloat(val, 32)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn float32(f), nil\n}\n\n// Float32Slice converts 'val' where individual floating point numbers are separated by\n// 'sep' into a float32 slice.\nfunc Float32Slice(val, sep string) ([]float32, error) {\n\ts := strings.Split(val, sep)\n\tvalues := make([]float32, len(s))\n\tfor i, v := range s {\n\t\tvalue, err := Float32(v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalues[i] = value\n\t}\n\treturn values, nil\n}\n\n// Int64 converts the given string representation of an integer into int64.\nfunc Int64(val string) (int64, error) {\n\treturn strconv.ParseInt(val, 0, 64)\n}\n\n// Int64Slice converts 'val' where individual integers are separated by\n// 'sep' into an int64 slice.\nfunc Int64Slice(val, sep string) ([]int64, error) {\n\ts := strings.Split(val, sep)\n\tvalues := make([]int64, len(s))\n\tfor i, v := range s {\n\t\tvalue, err := Int64(v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalues[i] = value\n\t}\n\treturn values, nil\n}\n\n// Int32 converts the given string representation of an integer into int32.\nfunc Int32(val string) (int32, error) {\n\ti, err := strconv.ParseInt(val, 0, 32)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn int32(i), nil\n}\n\n// Int32Slice converts 'val' where individual integers are separated by\n// 'sep' into an int32 slice.\nfunc Int32Slice(val, sep string) ([]int32, error) {\n\ts := strings.Split(val, sep)\n\tvalues := make([]int32, len(s))\n\tfor i, v := range s {\n\t\tvalue, err := Int32(v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalues[i] = value\n\t}\n\treturn values, nil\n}\n\n// Uint64 converts the given string representation of an integer into uint64.\nfunc Uint64(val string) (uint64, error) {\n\treturn strconv.ParseUint(val, 0, 64)\n}\n\n// Uint64Slice converts 'val' where individual integers are separated by\n// 'sep' into a uint64 slice.\nfunc Uint64Slice(val, sep string) ([]uint64, error) {\n\ts := strings.Split(val, sep)\n\tvalues := make([]uint64, len(s))\n\tfor i, v := range s {\n\t\tvalue, err := Uint64(v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalues[i] = value\n\t}\n\treturn values, nil\n}\n\n// Uint32 converts the given string representation of an integer into uint32.\nfunc Uint32(val string) (uint32, error) {\n\ti, err := strconv.ParseUint(val, 0, 32)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn uint32(i), nil\n}\n\n// Uint32Slice converts 'val' where individual integers are separated by\n// 'sep' into a uint32 slice.\nfunc Uint32Slice(val, sep string) ([]uint32, error) {\n\ts := strings.Split(val, sep)\n\tvalues := make([]uint32, len(s))\n\tfor i, v := range s {\n\t\tvalue, err := Uint32(v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalues[i] = value\n\t}\n\treturn values, nil\n}\n\n// Bytes converts the given string representation of a byte sequence into a slice of bytes\n// A bytes sequence is encoded in URL-safe base64 without padding\nfunc Bytes(val string) ([]byte, error) {\n\tb, err := base64.StdEncoding.DecodeString(val)\n\tif err != nil {\n\t\tb, err = base64.URLEncoding.DecodeString(val)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn b, nil\n}\n\n// BytesSlice converts 'val' where individual bytes sequences, encoded in URL-safe\n// base64 without padding, are separated by 'sep' into a slice of byte slices.\nfunc BytesSlice(val, sep string) ([][]byte, error) {\n\ts := strings.Split(val, sep)\n\tvalues := make([][]byte, len(s))\n\tfor i, v := range s {\n\t\tvalue, err := Bytes(v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalues[i] = value\n\t}\n\treturn values, nil\n}\n\n// Timestamp converts the given RFC3339 formatted string into a timestamp.Timestamp.\nfunc Timestamp(val string) (*timestamppb.Timestamp, error) {\n\tvar r timestamppb.Timestamp\n\tval = strconv.Quote(strings.Trim(val, `\"`))\n\tunmarshaler := &protojson.UnmarshalOptions{}\n\tif err := unmarshaler.Unmarshal([]byte(val), &r); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &r, nil\n}\n\n// Duration converts the given string into a timestamp.Duration.\nfunc Duration(val string) (*durationpb.Duration, error) {\n\tvar r durationpb.Duration\n\tval = strconv.Quote(strings.Trim(val, `\"`))\n\tunmarshaler := &protojson.UnmarshalOptions{}\n\tif err := unmarshaler.Unmarshal([]byte(val), &r); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &r, nil\n}\n\n// Enum converts the given string into an int32 that should be type casted into the\n// correct enum proto type.\nfunc Enum(val string, enumValMap map[string]int32) (int32, error) {\n\te, ok := enumValMap[val]\n\tif ok {\n\t\treturn e, nil\n\t}\n\n\ti, err := Int32(val)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"%s is not valid\", val)\n\t}\n\tfor _, v := range enumValMap {\n\t\tif v == i {\n\t\t\treturn i, nil\n\t\t}\n\t}\n\treturn 0, fmt.Errorf(\"%s is not valid\", val)\n}\n\n// EnumSlice converts 'val' where individual enums are separated by 'sep'\n// into a int32 slice. Each individual int32 should be type casted into the\n// correct enum proto type.\nfunc EnumSlice(val, sep string, enumValMap map[string]int32) ([]int32, error) {\n\ts := strings.Split(val, sep)\n\tvalues := make([]int32, len(s))\n\tfor i, v := range s {\n\t\tvalue, err := Enum(v, enumValMap)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalues[i] = value\n\t}\n\treturn values, nil\n}\n\n// Support for google.protobuf.wrappers on top of primitive types\n\n// StringValue well-known type support as wrapper around string type\nfunc StringValue(val string) (*wrapperspb.StringValue, error) {\n\treturn wrapperspb.String(val), nil\n}\n\n// FloatValue well-known type support as wrapper around float32 type\nfunc FloatValue(val string) (*wrapperspb.FloatValue, error) {\n\tparsedVal, err := Float32(val)\n\treturn wrapperspb.Float(parsedVal), err\n}\n\n// DoubleValue well-known type support as wrapper around float64 type\nfunc DoubleValue(val string) (*wrapperspb.DoubleValue, error) {\n\tparsedVal, err := Float64(val)\n\treturn wrapperspb.Double(parsedVal), err\n}\n\n// BoolValue well-known type support as wrapper around bool type\nfunc BoolValue(val string) (*wrapperspb.BoolValue, error) {\n\tparsedVal, err := Bool(val)\n\treturn wrapperspb.Bool(parsedVal), err\n}\n\n// Int32Value well-known type support as wrapper around int32 type\nfunc Int32Value(val string) (*wrapperspb.Int32Value, error) {\n\tparsedVal, err := Int32(val)\n\treturn wrapperspb.Int32(parsedVal), err\n}\n\n// UInt32Value well-known type support as wrapper around uint32 type\nfunc UInt32Value(val string) (*wrapperspb.UInt32Value, error) {\n\tparsedVal, err := Uint32(val)\n\treturn wrapperspb.UInt32(parsedVal), err\n}\n\n// Int64Value well-known type support as wrapper around int64 type\nfunc Int64Value(val string) (*wrapperspb.Int64Value, error) {\n\tparsedVal, err := Int64(val)\n\treturn wrapperspb.Int64(parsedVal), err\n}\n\n// UInt64Value well-known type support as wrapper around uint64 type\nfunc UInt64Value(val string) (*wrapperspb.UInt64Value, error) {\n\tparsedVal, err := Uint64(val)\n\treturn wrapperspb.UInt64(parsedVal), err\n}\n\n// BytesValue well-known type support as wrapper around bytes[] type\nfunc BytesValue(val string) (*wrapperspb.BytesValue, error) {\n\tparsedVal, err := Bytes(val)\n\treturn wrapperspb.Bytes(parsedVal), err\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/doc.go",
    "content": "/*\nPackage runtime contains runtime helper functions used by\nservers which protoc-gen-grpc-gateway generates.\n*/\npackage runtime\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/errors.go",
    "content": "package runtime\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"net/http\"\n\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/grpclog\"\n\t\"google.golang.org/grpc/status\"\n)\n\n// ErrorHandlerFunc is the signature used to configure error handling.\ntype ErrorHandlerFunc func(context.Context, *ServeMux, Marshaler, http.ResponseWriter, *http.Request, error)\n\n// StreamErrorHandlerFunc is the signature used to configure stream error handling.\ntype StreamErrorHandlerFunc func(context.Context, error) *status.Status\n\n// RoutingErrorHandlerFunc is the signature used to configure error handling for routing errors.\ntype RoutingErrorHandlerFunc func(context.Context, *ServeMux, Marshaler, http.ResponseWriter, *http.Request, int)\n\n// HTTPStatusError is the error to use when needing to provide a different HTTP status code for an error\n// passed to the DefaultRoutingErrorHandler.\ntype HTTPStatusError struct {\n\tHTTPStatus int\n\tErr        error\n}\n\nfunc (e *HTTPStatusError) Error() string {\n\treturn e.Err.Error()\n}\n\n// HTTPStatusFromCode converts a gRPC error code into the corresponding HTTP response status.\n// See: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto\nfunc HTTPStatusFromCode(code codes.Code) int {\n\tswitch code {\n\tcase codes.OK:\n\t\treturn http.StatusOK\n\tcase codes.Canceled:\n\t\treturn 499\n\tcase codes.Unknown:\n\t\treturn http.StatusInternalServerError\n\tcase codes.InvalidArgument:\n\t\treturn http.StatusBadRequest\n\tcase codes.DeadlineExceeded:\n\t\treturn http.StatusGatewayTimeout\n\tcase codes.NotFound:\n\t\treturn http.StatusNotFound\n\tcase codes.AlreadyExists:\n\t\treturn http.StatusConflict\n\tcase codes.PermissionDenied:\n\t\treturn http.StatusForbidden\n\tcase codes.Unauthenticated:\n\t\treturn http.StatusUnauthorized\n\tcase codes.ResourceExhausted:\n\t\treturn http.StatusTooManyRequests\n\tcase codes.FailedPrecondition:\n\t\t// Note, this deliberately doesn't translate to the similarly named '412 Precondition Failed' HTTP response status.\n\t\treturn http.StatusBadRequest\n\tcase codes.Aborted:\n\t\treturn http.StatusConflict\n\tcase codes.OutOfRange:\n\t\treturn http.StatusBadRequest\n\tcase codes.Unimplemented:\n\t\treturn http.StatusNotImplemented\n\tcase codes.Internal:\n\t\treturn http.StatusInternalServerError\n\tcase codes.Unavailable:\n\t\treturn http.StatusServiceUnavailable\n\tcase codes.DataLoss:\n\t\treturn http.StatusInternalServerError\n\tdefault:\n\t\tgrpclog.Warningf(\"Unknown gRPC error code: %v\", code)\n\t\treturn http.StatusInternalServerError\n\t}\n}\n\n// HTTPError uses the mux-configured error handler.\nfunc HTTPError(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, err error) {\n\tmux.errorHandler(ctx, mux, marshaler, w, r, err)\n}\n\n// HTTPStreamError uses the mux-configured stream error handler to notify error to the client without closing the connection.\nfunc HTTPStreamError(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, err error) {\n\tst := mux.streamErrorHandler(ctx, err)\n\tmsg := errorChunk(st)\n\tbuf, err := marshaler.Marshal(msg)\n\tif err != nil {\n\t\tgrpclog.Errorf(\"Failed to marshal an error: %v\", err)\n\t\treturn\n\t}\n\tif _, err := w.Write(buf); err != nil {\n\t\tgrpclog.Errorf(\"Failed to notify error to client: %v\", err)\n\t\treturn\n\t}\n}\n\n// DefaultHTTPErrorHandler is the default error handler.\n// If \"err\" is a gRPC Status, the function replies with the status code mapped by HTTPStatusFromCode.\n// If \"err\" is a HTTPStatusError, the function replies with the status code provide by that struct. This is\n// intended to allow passing through of specific statuses via the function set via WithRoutingErrorHandler\n// for the ServeMux constructor to handle edge cases which the standard mappings in HTTPStatusFromCode\n// are insufficient for.\n// If otherwise, it replies with http.StatusInternalServerError.\n//\n// The response body written by this function is a Status message marshaled by the Marshaler.\nfunc DefaultHTTPErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, err error) {\n\t// return Internal when Marshal failed\n\tconst fallback = `{\"code\": 13, \"message\": \"failed to marshal error message\"}`\n\tconst fallbackRewriter = `{\"code\": 13, \"message\": \"failed to rewrite error message\"}`\n\n\tvar customStatus *HTTPStatusError\n\tif errors.As(err, &customStatus) {\n\t\terr = customStatus.Err\n\t}\n\n\ts := status.Convert(err)\n\n\tw.Header().Del(\"Trailer\")\n\tw.Header().Del(\"Transfer-Encoding\")\n\n\trespRw, err := mux.forwardResponseRewriter(ctx, s.Proto())\n\tif err != nil {\n\t\tgrpclog.Errorf(\"Failed to rewrite error message %q: %v\", s, err)\n\t\tw.WriteHeader(http.StatusInternalServerError)\n\t\tif _, err := io.WriteString(w, fallbackRewriter); err != nil {\n\t\t\tgrpclog.Errorf(\"Failed to write response: %v\", err)\n\t\t}\n\t\treturn\n\t}\n\n\tcontentType := marshaler.ContentType(respRw)\n\tw.Header().Set(\"Content-Type\", contentType)\n\n\tif s.Code() == codes.Unauthenticated {\n\t\tw.Header().Set(\"WWW-Authenticate\", s.Message())\n\t}\n\n\tbuf, merr := marshaler.Marshal(respRw)\n\tif merr != nil {\n\t\tgrpclog.Errorf(\"Failed to marshal error message %q: %v\", s, merr)\n\t\tw.WriteHeader(http.StatusInternalServerError)\n\t\tif _, err := io.WriteString(w, fallback); err != nil {\n\t\t\tgrpclog.Errorf(\"Failed to write response: %v\", err)\n\t\t}\n\t\treturn\n\t}\n\n\tmd, ok := ServerMetadataFromContext(ctx)\n\tif ok {\n\t\thandleForwardResponseServerMetadata(w, mux, md)\n\n\t\t// RFC 7230 https://tools.ietf.org/html/rfc7230#section-4.1.2\n\t\t// Unless the request includes a TE header field indicating \"trailers\"\n\t\t// is acceptable, as described in Section 4.3, a server SHOULD NOT\n\t\t// generate trailer fields that it believes are necessary for the user\n\t\t// agent to receive.\n\t\tdoForwardTrailers := requestAcceptsTrailers(r)\n\n\t\tif doForwardTrailers {\n\t\t\thandleForwardResponseTrailerHeader(w, mux, md)\n\t\t\tw.Header().Set(\"Transfer-Encoding\", \"chunked\")\n\t\t}\n\t}\n\n\tst := HTTPStatusFromCode(s.Code())\n\tif customStatus != nil {\n\t\tst = customStatus.HTTPStatus\n\t}\n\n\tw.WriteHeader(st)\n\tif _, err := w.Write(buf); err != nil {\n\t\tgrpclog.Errorf(\"Failed to write response: %v\", err)\n\t}\n\n\tif ok && requestAcceptsTrailers(r) {\n\t\thandleForwardResponseTrailer(w, mux, md)\n\t}\n}\n\nfunc DefaultStreamErrorHandler(_ context.Context, err error) *status.Status {\n\treturn status.Convert(err)\n}\n\n// DefaultRoutingErrorHandler is our default handler for routing errors.\n// By default http error codes mapped on the following error codes:\n//\n//\tNotFound -> grpc.NotFound\n//\tStatusBadRequest -> grpc.InvalidArgument\n//\tMethodNotAllowed -> grpc.Unimplemented\n//\tOther -> grpc.Internal, method is not expecting to be called for anything else\nfunc DefaultRoutingErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, r *http.Request, httpStatus int) {\n\tsterr := status.Error(codes.Internal, \"Unexpected routing error\")\n\tswitch httpStatus {\n\tcase http.StatusBadRequest:\n\t\tsterr = status.Error(codes.InvalidArgument, http.StatusText(httpStatus))\n\tcase http.StatusMethodNotAllowed:\n\t\tsterr = status.Error(codes.Unimplemented, http.StatusText(httpStatus))\n\tcase http.StatusNotFound:\n\t\tsterr = status.Error(codes.NotFound, http.StatusText(httpStatus))\n\t}\n\tmux.errorHandler(ctx, mux, marshaler, w, r, sterr)\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/fieldmask.go",
    "content": "package runtime\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"sort\"\n\n\t\"google.golang.org/protobuf/proto\"\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n\tfield_mask \"google.golang.org/protobuf/types/known/fieldmaskpb\"\n)\n\nfunc getFieldByName(fields protoreflect.FieldDescriptors, name string) protoreflect.FieldDescriptor {\n\tfd := fields.ByName(protoreflect.Name(name))\n\tif fd != nil {\n\t\treturn fd\n\t}\n\n\treturn fields.ByJSONName(name)\n}\n\n// FieldMaskFromRequestBody creates a FieldMask printing all complete paths from the JSON body.\nfunc FieldMaskFromRequestBody(r io.Reader, msg proto.Message) (*field_mask.FieldMask, error) {\n\tfm := &field_mask.FieldMask{}\n\tvar root interface{}\n\n\tif err := json.NewDecoder(r).Decode(&root); err != nil {\n\t\tif errors.Is(err, io.EOF) {\n\t\t\treturn fm, nil\n\t\t}\n\t\treturn nil, err\n\t}\n\n\tqueue := []fieldMaskPathItem{{node: root, msg: msg.ProtoReflect()}}\n\tfor len(queue) > 0 {\n\t\t// dequeue an item\n\t\titem := queue[0]\n\t\tqueue = queue[1:]\n\n\t\tm, ok := item.node.(map[string]interface{})\n\t\tswitch {\n\t\tcase ok && len(m) > 0:\n\t\t\t// if the item is an object, then enqueue all of its children\n\t\t\tfor k, v := range m {\n\t\t\t\tif item.msg == nil {\n\t\t\t\t\treturn nil, errors.New(\"JSON structure did not match request type\")\n\t\t\t\t}\n\n\t\t\t\tfd := getFieldByName(item.msg.Descriptor().Fields(), k)\n\t\t\t\tif fd == nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"could not find field %q in %q\", k, item.msg.Descriptor().FullName())\n\t\t\t\t}\n\n\t\t\t\tif isDynamicProtoMessage(fd.Message()) {\n\t\t\t\t\tfor _, p := range buildPathsBlindly(string(fd.FullName().Name()), v) {\n\t\t\t\t\t\tnewPath := p\n\t\t\t\t\t\tif item.path != \"\" {\n\t\t\t\t\t\t\tnewPath = item.path + \".\" + newPath\n\t\t\t\t\t\t}\n\t\t\t\t\t\tqueue = append(queue, fieldMaskPathItem{path: newPath})\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif isProtobufAnyMessage(fd.Message()) && !fd.IsList() {\n\t\t\t\t\t_, hasTypeField := v.(map[string]interface{})[\"@type\"]\n\t\t\t\t\tif hasTypeField {\n\t\t\t\t\t\tqueue = append(queue, fieldMaskPathItem{path: k})\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn nil, fmt.Errorf(\"could not find field @type in %q in message %q\", k, item.msg.Descriptor().FullName())\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tchild := fieldMaskPathItem{\n\t\t\t\t\tnode: v,\n\t\t\t\t}\n\t\t\t\tif item.path == \"\" {\n\t\t\t\t\tchild.path = string(fd.FullName().Name())\n\t\t\t\t} else {\n\t\t\t\t\tchild.path = item.path + \".\" + string(fd.FullName().Name())\n\t\t\t\t}\n\n\t\t\t\tswitch {\n\t\t\t\tcase fd.IsList(), fd.IsMap():\n\t\t\t\t\t// As per: https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/field_mask.proto#L85-L86\n\t\t\t\t\t// Do not recurse into repeated fields. The repeated field goes on the end of the path and we stop.\n\t\t\t\t\tfm.Paths = append(fm.Paths, child.path)\n\t\t\t\tcase fd.Message() != nil:\n\t\t\t\t\tchild.msg = item.msg.Get(fd).Message()\n\t\t\t\t\tfallthrough\n\t\t\t\tdefault:\n\t\t\t\t\tqueue = append(queue, child)\n\t\t\t\t}\n\t\t\t}\n\t\tcase ok && len(m) == 0:\n\t\t\tfallthrough\n\t\tcase len(item.path) > 0:\n\t\t\t// otherwise, it's a leaf node so print its path\n\t\t\tfm.Paths = append(fm.Paths, item.path)\n\t\t}\n\t}\n\n\t// Sort for deterministic output in the presence\n\t// of repeated fields.\n\tsort.Strings(fm.Paths)\n\n\treturn fm, nil\n}\n\nfunc isProtobufAnyMessage(md protoreflect.MessageDescriptor) bool {\n\treturn md != nil && (md.FullName() == \"google.protobuf.Any\")\n}\n\nfunc isDynamicProtoMessage(md protoreflect.MessageDescriptor) bool {\n\treturn md != nil && (md.FullName() == \"google.protobuf.Struct\" || md.FullName() == \"google.protobuf.Value\")\n}\n\n// buildPathsBlindly does not attempt to match proto field names to the\n// json value keys.  Instead it relies completely on the structure of\n// the unmarshalled json contained within in.\n// Returns a slice containing all subpaths with the root at the\n// passed in name and json value.\nfunc buildPathsBlindly(name string, in interface{}) []string {\n\tm, ok := in.(map[string]interface{})\n\tif !ok {\n\t\treturn []string{name}\n\t}\n\n\tvar paths []string\n\tqueue := []fieldMaskPathItem{{path: name, node: m}}\n\tfor len(queue) > 0 {\n\t\tcur := queue[0]\n\t\tqueue = queue[1:]\n\n\t\tm, ok := cur.node.(map[string]interface{})\n\t\tif !ok {\n\t\t\t// This should never happen since we should always check that we only add\n\t\t\t// nodes of type map[string]interface{} to the queue.\n\t\t\tcontinue\n\t\t}\n\t\tfor k, v := range m {\n\t\t\tif mi, ok := v.(map[string]interface{}); ok {\n\t\t\t\tqueue = append(queue, fieldMaskPathItem{path: cur.path + \".\" + k, node: mi})\n\t\t\t} else {\n\t\t\t\t// This is not a struct, so there are no more levels to descend.\n\t\t\t\tcurPath := cur.path + \".\" + k\n\t\t\t\tpaths = append(paths, curPath)\n\t\t\t}\n\t\t}\n\t}\n\treturn paths\n}\n\n// fieldMaskPathItem stores an in-progress deconstruction of a path for a fieldmask\ntype fieldMaskPathItem struct {\n\t// the list of prior fields leading up to node connected by dots\n\tpath string\n\n\t// a generic decoded json object the current item to inspect for further path extraction\n\tnode interface{}\n\n\t// parent message\n\tmsg protoreflect.Message\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/handler.go",
    "content": "package runtime\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/textproto\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"google.golang.org/genproto/googleapis/api/httpbody\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/grpclog\"\n\t\"google.golang.org/grpc/status\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\n// ForwardResponseStream forwards the stream from gRPC server to REST client.\nfunc ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, recv func() (proto.Message, error), opts ...func(context.Context, http.ResponseWriter, proto.Message) error) {\n\trc := http.NewResponseController(w)\n\tmd, ok := ServerMetadataFromContext(ctx)\n\tif !ok {\n\t\tgrpclog.Error(\"Failed to extract ServerMetadata from context\")\n\t\thttp.Error(w, \"unexpected error\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\thandleForwardResponseServerMetadata(w, mux, md)\n\n\tw.Header().Set(\"Transfer-Encoding\", \"chunked\")\n\tif err := handleForwardResponseOptions(ctx, w, nil, opts); err != nil {\n\t\tHTTPError(ctx, mux, marshaler, w, req, err)\n\t\treturn\n\t}\n\n\tvar delimiter []byte\n\tif d, ok := marshaler.(Delimited); ok {\n\t\tdelimiter = d.Delimiter()\n\t} else {\n\t\tdelimiter = []byte(\"\\n\")\n\t}\n\n\tvar wroteHeader bool\n\tfor {\n\t\tresp, err := recv()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\treturn\n\t\t}\n\t\tif err != nil {\n\t\t\thandleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err, delimiter)\n\t\t\treturn\n\t\t}\n\t\tif err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil {\n\t\t\thandleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err, delimiter)\n\t\t\treturn\n\t\t}\n\n\t\trespRw, err := mux.forwardResponseRewriter(ctx, resp)\n\t\tif err != nil {\n\t\t\tgrpclog.Errorf(\"Rewrite error: %v\", err)\n\t\t\thandleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err, delimiter)\n\t\t\treturn\n\t\t}\n\n\t\tif !wroteHeader {\n\t\t\tvar contentType string\n\t\t\tif sct, ok := marshaler.(StreamContentType); ok {\n\t\t\t\tcontentType = sct.StreamContentType(respRw)\n\t\t\t} else {\n\t\t\t\tcontentType = marshaler.ContentType(respRw)\n\t\t\t}\n\t\t\tw.Header().Set(\"Content-Type\", contentType)\n\t\t}\n\n\t\tvar buf []byte\n\t\thttpBody, isHTTPBody := respRw.(*httpbody.HttpBody)\n\t\tswitch {\n\t\tcase respRw == nil:\n\t\t\tbuf, err = marshaler.Marshal(errorChunk(status.New(codes.Internal, \"empty response\")))\n\t\tcase isHTTPBody:\n\t\t\tbuf = httpBody.GetData()\n\t\tdefault:\n\t\t\tresult := map[string]interface{}{\"result\": respRw}\n\t\t\tif rb, ok := respRw.(responseBody); ok {\n\t\t\t\tresult[\"result\"] = rb.XXX_ResponseBody()\n\t\t\t}\n\n\t\t\tbuf, err = marshaler.Marshal(result)\n\t\t}\n\n\t\tif err != nil {\n\t\t\tgrpclog.Errorf(\"Failed to marshal response chunk: %v\", err)\n\t\t\thandleForwardResponseStreamError(ctx, wroteHeader, marshaler, w, req, mux, err, delimiter)\n\t\t\treturn\n\t\t}\n\t\tif _, err := w.Write(buf); err != nil {\n\t\t\tgrpclog.Errorf(\"Failed to send response chunk: %v\", err)\n\t\t\treturn\n\t\t}\n\t\twroteHeader = true\n\t\tif _, err := w.Write(delimiter); err != nil {\n\t\t\tgrpclog.Errorf(\"Failed to send delimiter chunk: %v\", err)\n\t\t\treturn\n\t\t}\n\t\terr = rc.Flush()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, http.ErrNotSupported) {\n\t\t\t\tgrpclog.Errorf(\"Flush not supported in %T\", w)\n\t\t\t\thttp.Error(w, \"unexpected type of web server\", http.StatusInternalServerError)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tgrpclog.Errorf(\"Failed to flush response to client: %v\", err)\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc handleForwardResponseServerMetadata(w http.ResponseWriter, mux *ServeMux, md ServerMetadata) {\n\tfor k, vs := range md.HeaderMD {\n\t\tif h, ok := mux.outgoingHeaderMatcher(k); ok {\n\t\t\tfor _, v := range vs {\n\t\t\t\tw.Header().Add(h, v)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc handleForwardResponseTrailerHeader(w http.ResponseWriter, mux *ServeMux, md ServerMetadata) {\n\tfor k := range md.TrailerMD {\n\t\tif h, ok := mux.outgoingTrailerMatcher(k); ok {\n\t\t\tw.Header().Add(\"Trailer\", textproto.CanonicalMIMEHeaderKey(h))\n\t\t}\n\t}\n}\n\nfunc handleForwardResponseTrailer(w http.ResponseWriter, mux *ServeMux, md ServerMetadata) {\n\tfor k, vs := range md.TrailerMD {\n\t\tif h, ok := mux.outgoingTrailerMatcher(k); ok {\n\t\t\tfor _, v := range vs {\n\t\t\t\tw.Header().Add(h, v)\n\t\t\t}\n\t\t}\n\t}\n}\n\n// responseBody interface contains method for getting field for marshaling to the response body\n// this method is generated for response struct from the value of `response_body` in the `google.api.HttpRule`\ntype responseBody interface {\n\tXXX_ResponseBody() interface{}\n}\n\n// ForwardResponseMessage forwards the message \"resp\" from gRPC server to REST client.\nfunc ForwardResponseMessage(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, resp proto.Message, opts ...func(context.Context, http.ResponseWriter, proto.Message) error) {\n\tmd, ok := ServerMetadataFromContext(ctx)\n\tif ok {\n\t\thandleForwardResponseServerMetadata(w, mux, md)\n\t}\n\n\t// RFC 7230 https://tools.ietf.org/html/rfc7230#section-4.1.2\n\t// Unless the request includes a TE header field indicating \"trailers\"\n\t// is acceptable, as described in Section 4.3, a server SHOULD NOT\n\t// generate trailer fields that it believes are necessary for the user\n\t// agent to receive.\n\tdoForwardTrailers := requestAcceptsTrailers(req)\n\n\tif ok && doForwardTrailers {\n\t\thandleForwardResponseTrailerHeader(w, mux, md)\n\t\tw.Header().Set(\"Transfer-Encoding\", \"chunked\")\n\t}\n\n\tcontentType := marshaler.ContentType(resp)\n\tw.Header().Set(\"Content-Type\", contentType)\n\n\tif err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil {\n\t\tHTTPError(ctx, mux, marshaler, w, req, err)\n\t\treturn\n\t}\n\trespRw, err := mux.forwardResponseRewriter(ctx, resp)\n\tif err != nil {\n\t\tgrpclog.Errorf(\"Rewrite error: %v\", err)\n\t\tHTTPError(ctx, mux, marshaler, w, req, err)\n\t\treturn\n\t}\n\tvar buf []byte\n\tif rb, ok := respRw.(responseBody); ok {\n\t\tbuf, err = marshaler.Marshal(rb.XXX_ResponseBody())\n\t} else {\n\t\tbuf, err = marshaler.Marshal(respRw)\n\t}\n\tif err != nil {\n\t\tgrpclog.Errorf(\"Marshal error: %v\", err)\n\t\tHTTPError(ctx, mux, marshaler, w, req, err)\n\t\treturn\n\t}\n\n\tif !doForwardTrailers && mux.writeContentLength {\n\t\tw.Header().Set(\"Content-Length\", strconv.Itoa(len(buf)))\n\t}\n\n\tif _, err = w.Write(buf); err != nil && !errors.Is(err, http.ErrBodyNotAllowed) {\n\t\tgrpclog.Errorf(\"Failed to write response: %v\", err)\n\t}\n\n\tif ok && doForwardTrailers {\n\t\thandleForwardResponseTrailer(w, mux, md)\n\t}\n}\n\nfunc requestAcceptsTrailers(req *http.Request) bool {\n\tte := req.Header.Get(\"TE\")\n\treturn strings.Contains(strings.ToLower(te), \"trailers\")\n}\n\nfunc handleForwardResponseOptions(ctx context.Context, w http.ResponseWriter, resp proto.Message, opts []func(context.Context, http.ResponseWriter, proto.Message) error) error {\n\tif len(opts) == 0 {\n\t\treturn nil\n\t}\n\tfor _, opt := range opts {\n\t\tif err := opt(ctx, w, resp); err != nil {\n\t\t\treturn fmt.Errorf(\"error handling ForwardResponseOptions: %w\", err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc handleForwardResponseStreamError(ctx context.Context, wroteHeader bool, marshaler Marshaler, w http.ResponseWriter, req *http.Request, mux *ServeMux, err error, delimiter []byte) {\n\tst := mux.streamErrorHandler(ctx, err)\n\tmsg := errorChunk(st)\n\tif !wroteHeader {\n\t\tw.Header().Set(\"Content-Type\", marshaler.ContentType(msg))\n\t\tw.WriteHeader(HTTPStatusFromCode(st.Code()))\n\t}\n\tbuf, err := marshaler.Marshal(msg)\n\tif err != nil {\n\t\tgrpclog.Errorf(\"Failed to marshal an error: %v\", err)\n\t\treturn\n\t}\n\tif _, err := w.Write(buf); err != nil {\n\t\tgrpclog.Errorf(\"Failed to notify error to client: %v\", err)\n\t\treturn\n\t}\n\tif _, err := w.Write(delimiter); err != nil {\n\t\tgrpclog.Errorf(\"Failed to send delimiter chunk: %v\", err)\n\t\treturn\n\t}\n}\n\nfunc errorChunk(st *status.Status) map[string]proto.Message {\n\treturn map[string]proto.Message{\"error\": st.Proto()}\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_httpbodyproto.go",
    "content": "package runtime\n\nimport (\n\t\"google.golang.org/genproto/googleapis/api/httpbody\"\n)\n\n// HTTPBodyMarshaler is a Marshaler which supports marshaling of a\n// google.api.HttpBody message as the full response body if it is\n// the actual message used as the response. If not, then this will\n// simply fallback to the Marshaler specified as its default Marshaler.\ntype HTTPBodyMarshaler struct {\n\tMarshaler\n}\n\n// ContentType returns its specified content type in case v is a\n// google.api.HttpBody message, otherwise it will fall back to the default Marshalers\n// content type.\nfunc (h *HTTPBodyMarshaler) ContentType(v interface{}) string {\n\tif httpBody, ok := v.(*httpbody.HttpBody); ok {\n\t\treturn httpBody.GetContentType()\n\t}\n\treturn h.Marshaler.ContentType(v)\n}\n\n// Marshal marshals \"v\" by returning the body bytes if v is a\n// google.api.HttpBody message, otherwise it falls back to the default Marshaler.\nfunc (h *HTTPBodyMarshaler) Marshal(v interface{}) ([]byte, error) {\n\tif httpBody, ok := v.(*httpbody.HttpBody); ok {\n\t\treturn httpBody.GetData(), nil\n\t}\n\treturn h.Marshaler.Marshal(v)\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_json.go",
    "content": "package runtime\n\nimport (\n\t\"encoding/json\"\n\t\"io\"\n)\n\n// JSONBuiltin is a Marshaler which marshals/unmarshals into/from JSON\n// with the standard \"encoding/json\" package of Golang.\n// Although it is generally faster for simple proto messages than JSONPb,\n// it does not support advanced features of protobuf, e.g. map, oneof, ....\n//\n// The NewEncoder and NewDecoder types return *json.Encoder and\n// *json.Decoder respectively.\ntype JSONBuiltin struct{}\n\n// ContentType always Returns \"application/json\".\nfunc (*JSONBuiltin) ContentType(_ interface{}) string {\n\treturn \"application/json\"\n}\n\n// Marshal marshals \"v\" into JSON\nfunc (j *JSONBuiltin) Marshal(v interface{}) ([]byte, error) {\n\treturn json.Marshal(v)\n}\n\n// MarshalIndent is like Marshal but applies Indent to format the output\nfunc (j *JSONBuiltin) MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {\n\treturn json.MarshalIndent(v, prefix, indent)\n}\n\n// Unmarshal unmarshals JSON data into \"v\".\nfunc (j *JSONBuiltin) Unmarshal(data []byte, v interface{}) error {\n\treturn json.Unmarshal(data, v)\n}\n\n// NewDecoder returns a Decoder which reads JSON stream from \"r\".\nfunc (j *JSONBuiltin) NewDecoder(r io.Reader) Decoder {\n\treturn json.NewDecoder(r)\n}\n\n// NewEncoder returns an Encoder which writes JSON stream into \"w\".\nfunc (j *JSONBuiltin) NewEncoder(w io.Writer) Encoder {\n\treturn json.NewEncoder(w)\n}\n\n// Delimiter for newline encoded JSON streams.\nfunc (j *JSONBuiltin) Delimiter() []byte {\n\treturn []byte(\"\\n\")\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_jsonpb.go",
    "content": "package runtime\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\t\"strconv\"\n\n\t\"google.golang.org/protobuf/encoding/protojson\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\n// JSONPb is a Marshaler which marshals/unmarshals into/from JSON\n// with the \"google.golang.org/protobuf/encoding/protojson\" marshaler.\n// It supports the full functionality of protobuf unlike JSONBuiltin.\n//\n// The NewDecoder method returns a DecoderWrapper, so the underlying\n// *json.Decoder methods can be used.\ntype JSONPb struct {\n\tprotojson.MarshalOptions\n\tprotojson.UnmarshalOptions\n}\n\n// ContentType always returns \"application/json\".\nfunc (*JSONPb) ContentType(_ interface{}) string {\n\treturn \"application/json\"\n}\n\n// Marshal marshals \"v\" into JSON.\nfunc (j *JSONPb) Marshal(v interface{}) ([]byte, error) {\n\tvar buf bytes.Buffer\n\tif err := j.marshalTo(&buf, v); err != nil {\n\t\treturn nil, err\n\t}\n\treturn buf.Bytes(), nil\n}\n\nfunc (j *JSONPb) marshalTo(w io.Writer, v interface{}) error {\n\tp, ok := v.(proto.Message)\n\tif !ok {\n\t\tbuf, err := j.marshalNonProtoField(v)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif j.Indent != \"\" {\n\t\t\tb := &bytes.Buffer{}\n\t\t\tif err := json.Indent(b, buf, \"\", j.Indent); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tbuf = b.Bytes()\n\t\t}\n\t\t_, err = w.Write(buf)\n\t\treturn err\n\t}\n\n\tb, err := j.MarshalOptions.Marshal(p)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_, err = w.Write(b)\n\treturn err\n}\n\nvar (\n\t// protoMessageType is stored to prevent constant lookup of the same type at runtime.\n\tprotoMessageType = reflect.TypeOf((*proto.Message)(nil)).Elem()\n)\n\n// marshalNonProto marshals a non-message field of a protobuf message.\n// This function does not correctly marshal arbitrary data structures into JSON,\n// it is only capable of marshaling non-message field values of protobuf,\n// i.e. primitive types, enums; pointers to primitives or enums; maps from\n// integer/string types to primitives/enums/pointers to messages.\nfunc (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) {\n\tif v == nil {\n\t\treturn []byte(\"null\"), nil\n\t}\n\trv := reflect.ValueOf(v)\n\tfor rv.Kind() == reflect.Ptr {\n\t\tif rv.IsNil() {\n\t\t\treturn []byte(\"null\"), nil\n\t\t}\n\t\trv = rv.Elem()\n\t}\n\n\tif rv.Kind() == reflect.Slice {\n\t\tif rv.IsNil() {\n\t\t\tif j.EmitUnpopulated {\n\t\t\t\treturn []byte(\"[]\"), nil\n\t\t\t}\n\t\t\treturn []byte(\"null\"), nil\n\t\t}\n\n\t\tif rv.Type().Elem().Implements(protoMessageType) {\n\t\t\tvar buf bytes.Buffer\n\t\t\tif err := buf.WriteByte('['); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tfor i := 0; i < rv.Len(); i++ {\n\t\t\t\tif i != 0 {\n\t\t\t\t\tif err := buf.WriteByte(','); err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif err := j.marshalTo(&buf, rv.Index(i).Interface().(proto.Message)); err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t}\n\t\t\tif err := buf.WriteByte(']'); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\treturn buf.Bytes(), nil\n\t\t}\n\n\t\tif rv.Type().Elem().Implements(typeProtoEnum) {\n\t\t\tvar buf bytes.Buffer\n\t\t\tif err := buf.WriteByte('['); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tfor i := 0; i < rv.Len(); i++ {\n\t\t\t\tif i != 0 {\n\t\t\t\t\tif err := buf.WriteByte(','); err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvar err error\n\t\t\t\tif j.UseEnumNumbers {\n\t\t\t\t\t_, err = buf.WriteString(strconv.FormatInt(rv.Index(i).Int(), 10))\n\t\t\t\t} else {\n\t\t\t\t\t_, err = buf.WriteString(\"\\\"\" + rv.Index(i).Interface().(protoEnum).String() + \"\\\"\")\n\t\t\t\t}\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t}\n\t\t\tif err := buf.WriteByte(']'); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\treturn buf.Bytes(), nil\n\t\t}\n\t}\n\n\tif rv.Kind() == reflect.Map {\n\t\tm := make(map[string]*json.RawMessage)\n\t\tfor _, k := range rv.MapKeys() {\n\t\t\tbuf, err := j.Marshal(rv.MapIndex(k).Interface())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tm[fmt.Sprintf(\"%v\", k.Interface())] = (*json.RawMessage)(&buf)\n\t\t}\n\t\treturn json.Marshal(m)\n\t}\n\tif enum, ok := rv.Interface().(protoEnum); ok && !j.UseEnumNumbers {\n\t\treturn json.Marshal(enum.String())\n\t}\n\treturn json.Marshal(rv.Interface())\n}\n\n// Unmarshal unmarshals JSON \"data\" into \"v\"\nfunc (j *JSONPb) Unmarshal(data []byte, v interface{}) error {\n\treturn unmarshalJSONPb(data, j.UnmarshalOptions, v)\n}\n\n// NewDecoder returns a Decoder which reads JSON stream from \"r\".\nfunc (j *JSONPb) NewDecoder(r io.Reader) Decoder {\n\td := json.NewDecoder(r)\n\treturn DecoderWrapper{\n\t\tDecoder:          d,\n\t\tUnmarshalOptions: j.UnmarshalOptions,\n\t}\n}\n\n// DecoderWrapper is a wrapper around a *json.Decoder that adds\n// support for protos to the Decode method.\ntype DecoderWrapper struct {\n\t*json.Decoder\n\tprotojson.UnmarshalOptions\n}\n\n// Decode wraps the embedded decoder's Decode method to support\n// protos using a jsonpb.Unmarshaler.\nfunc (d DecoderWrapper) Decode(v interface{}) error {\n\treturn decodeJSONPb(d.Decoder, d.UnmarshalOptions, v)\n}\n\n// NewEncoder returns an Encoder which writes JSON stream into \"w\".\nfunc (j *JSONPb) NewEncoder(w io.Writer) Encoder {\n\treturn EncoderFunc(func(v interface{}) error {\n\t\tif err := j.marshalTo(w, v); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// mimic json.Encoder by adding a newline (makes output\n\t\t// easier to read when it contains multiple encoded items)\n\t\t_, err := w.Write(j.Delimiter())\n\t\treturn err\n\t})\n}\n\nfunc unmarshalJSONPb(data []byte, unmarshaler protojson.UnmarshalOptions, v interface{}) error {\n\td := json.NewDecoder(bytes.NewReader(data))\n\treturn decodeJSONPb(d, unmarshaler, v)\n}\n\nfunc decodeJSONPb(d *json.Decoder, unmarshaler protojson.UnmarshalOptions, v interface{}) error {\n\tp, ok := v.(proto.Message)\n\tif !ok {\n\t\treturn decodeNonProtoField(d, unmarshaler, v)\n\t}\n\n\t// Decode into bytes for marshalling\n\tvar b json.RawMessage\n\tif err := d.Decode(&b); err != nil {\n\t\treturn err\n\t}\n\n\treturn unmarshaler.Unmarshal([]byte(b), p)\n}\n\nfunc decodeNonProtoField(d *json.Decoder, unmarshaler protojson.UnmarshalOptions, v interface{}) error {\n\trv := reflect.ValueOf(v)\n\tif rv.Kind() != reflect.Ptr {\n\t\treturn fmt.Errorf(\"%T is not a pointer\", v)\n\t}\n\tfor rv.Kind() == reflect.Ptr {\n\t\tif rv.IsNil() {\n\t\t\trv.Set(reflect.New(rv.Type().Elem()))\n\t\t}\n\t\tif rv.Type().ConvertibleTo(typeProtoMessage) {\n\t\t\t// Decode into bytes for marshalling\n\t\t\tvar b json.RawMessage\n\t\t\tif err := d.Decode(&b); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\treturn unmarshaler.Unmarshal([]byte(b), rv.Interface().(proto.Message))\n\t\t}\n\t\trv = rv.Elem()\n\t}\n\tif rv.Kind() == reflect.Map {\n\t\tif rv.IsNil() {\n\t\t\trv.Set(reflect.MakeMap(rv.Type()))\n\t\t}\n\t\tconv, ok := convFromType[rv.Type().Key().Kind()]\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"unsupported type of map field key: %v\", rv.Type().Key())\n\t\t}\n\n\t\tm := make(map[string]*json.RawMessage)\n\t\tif err := d.Decode(&m); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfor k, v := range m {\n\t\t\tresult := conv.Call([]reflect.Value{reflect.ValueOf(k)})\n\t\t\tif err := result[1].Interface(); err != nil {\n\t\t\t\treturn err.(error)\n\t\t\t}\n\t\t\tbk := result[0]\n\t\t\tbv := reflect.New(rv.Type().Elem())\n\t\t\tif v == nil {\n\t\t\t\tnull := json.RawMessage(\"null\")\n\t\t\t\tv = &null\n\t\t\t}\n\t\t\tif err := unmarshalJSONPb([]byte(*v), unmarshaler, bv.Interface()); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\trv.SetMapIndex(bk, bv.Elem())\n\t\t}\n\t\treturn nil\n\t}\n\tif rv.Kind() == reflect.Slice {\n\t\tif rv.Type().Elem().Kind() == reflect.Uint8 {\n\t\t\tvar sl []byte\n\t\t\tif err := d.Decode(&sl); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif sl != nil {\n\t\t\t\trv.SetBytes(sl)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\tvar sl []json.RawMessage\n\t\tif err := d.Decode(&sl); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif sl != nil {\n\t\t\trv.Set(reflect.MakeSlice(rv.Type(), 0, 0))\n\t\t}\n\t\tfor _, item := range sl {\n\t\t\tbv := reflect.New(rv.Type().Elem())\n\t\t\tif err := unmarshalJSONPb([]byte(item), unmarshaler, bv.Interface()); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\trv.Set(reflect.Append(rv, bv.Elem()))\n\t\t}\n\t\treturn nil\n\t}\n\tif _, ok := rv.Interface().(protoEnum); ok {\n\t\tvar repr interface{}\n\t\tif err := d.Decode(&repr); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tswitch v := repr.(type) {\n\t\tcase string:\n\t\t\t// TODO(yugui) Should use proto.StructProperties?\n\t\t\treturn fmt.Errorf(\"unmarshaling of symbolic enum %q not supported: %T\", repr, rv.Interface())\n\t\tcase float64:\n\t\t\trv.Set(reflect.ValueOf(int32(v)).Convert(rv.Type()))\n\t\t\treturn nil\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"cannot assign %#v into Go type %T\", repr, rv.Interface())\n\t\t}\n\t}\n\treturn d.Decode(v)\n}\n\ntype protoEnum interface {\n\tfmt.Stringer\n\tEnumDescriptor() ([]byte, []int)\n}\n\nvar typeProtoEnum = reflect.TypeOf((*protoEnum)(nil)).Elem()\n\nvar typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem()\n\n// Delimiter for newline encoded JSON streams.\nfunc (j *JSONPb) Delimiter() []byte {\n\treturn []byte(\"\\n\")\n}\n\nvar (\n\tconvFromType = map[reflect.Kind]reflect.Value{\n\t\treflect.String:  reflect.ValueOf(String),\n\t\treflect.Bool:    reflect.ValueOf(Bool),\n\t\treflect.Float64: reflect.ValueOf(Float64),\n\t\treflect.Float32: reflect.ValueOf(Float32),\n\t\treflect.Int64:   reflect.ValueOf(Int64),\n\t\treflect.Int32:   reflect.ValueOf(Int32),\n\t\treflect.Uint64:  reflect.ValueOf(Uint64),\n\t\treflect.Uint32:  reflect.ValueOf(Uint32),\n\t\treflect.Slice:   reflect.ValueOf(Bytes),\n\t}\n)\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshal_proto.go",
    "content": "package runtime\n\nimport (\n\t\"errors\"\n\t\"io\"\n\n\t\"google.golang.org/protobuf/proto\"\n)\n\n// ProtoMarshaller is a Marshaller which marshals/unmarshals into/from serialize proto bytes\ntype ProtoMarshaller struct{}\n\n// ContentType always returns \"application/octet-stream\".\nfunc (*ProtoMarshaller) ContentType(_ interface{}) string {\n\treturn \"application/octet-stream\"\n}\n\n// Marshal marshals \"value\" into Proto\nfunc (*ProtoMarshaller) Marshal(value interface{}) ([]byte, error) {\n\tmessage, ok := value.(proto.Message)\n\tif !ok {\n\t\treturn nil, errors.New(\"unable to marshal non proto field\")\n\t}\n\treturn proto.Marshal(message)\n}\n\n// Unmarshal unmarshals proto \"data\" into \"value\"\nfunc (*ProtoMarshaller) Unmarshal(data []byte, value interface{}) error {\n\tmessage, ok := value.(proto.Message)\n\tif !ok {\n\t\treturn errors.New(\"unable to unmarshal non proto field\")\n\t}\n\treturn proto.Unmarshal(data, message)\n}\n\n// NewDecoder returns a Decoder which reads proto stream from \"reader\".\nfunc (marshaller *ProtoMarshaller) NewDecoder(reader io.Reader) Decoder {\n\treturn DecoderFunc(func(value interface{}) error {\n\t\tbuffer, err := io.ReadAll(reader)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn marshaller.Unmarshal(buffer, value)\n\t})\n}\n\n// NewEncoder returns an Encoder which writes proto stream into \"writer\".\nfunc (marshaller *ProtoMarshaller) NewEncoder(writer io.Writer) Encoder {\n\treturn EncoderFunc(func(value interface{}) error {\n\t\tbuffer, err := marshaller.Marshal(value)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err := writer.Write(buffer); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn nil\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshaler.go",
    "content": "package runtime\n\nimport (\n\t\"io\"\n)\n\n// Marshaler defines a conversion between byte sequence and gRPC payloads / fields.\ntype Marshaler interface {\n\t// Marshal marshals \"v\" into byte sequence.\n\tMarshal(v interface{}) ([]byte, error)\n\t// Unmarshal unmarshals \"data\" into \"v\".\n\t// \"v\" must be a pointer value.\n\tUnmarshal(data []byte, v interface{}) error\n\t// NewDecoder returns a Decoder which reads byte sequence from \"r\".\n\tNewDecoder(r io.Reader) Decoder\n\t// NewEncoder returns an Encoder which writes bytes sequence into \"w\".\n\tNewEncoder(w io.Writer) Encoder\n\t// ContentType returns the Content-Type which this marshaler is responsible for.\n\t// The parameter describes the type which is being marshalled, which can sometimes\n\t// affect the content type returned.\n\tContentType(v interface{}) string\n}\n\n// Decoder decodes a byte sequence\ntype Decoder interface {\n\tDecode(v interface{}) error\n}\n\n// Encoder encodes gRPC payloads / fields into byte sequence.\ntype Encoder interface {\n\tEncode(v interface{}) error\n}\n\n// DecoderFunc adapts an decoder function into Decoder.\ntype DecoderFunc func(v interface{}) error\n\n// Decode delegates invocations to the underlying function itself.\nfunc (f DecoderFunc) Decode(v interface{}) error { return f(v) }\n\n// EncoderFunc adapts an encoder function into Encoder\ntype EncoderFunc func(v interface{}) error\n\n// Encode delegates invocations to the underlying function itself.\nfunc (f EncoderFunc) Encode(v interface{}) error { return f(v) }\n\n// Delimited defines the streaming delimiter.\ntype Delimited interface {\n\t// Delimiter returns the record separator for the stream.\n\tDelimiter() []byte\n}\n\n// StreamContentType defines the streaming content type.\ntype StreamContentType interface {\n\t// StreamContentType returns the content type for a stream. This shares the\n\t// same behaviour as for `Marshaler.ContentType`, but is called, if present,\n\t// in the case of a streamed response.\n\tStreamContentType(v interface{}) string\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/marshaler_registry.go",
    "content": "package runtime\n\nimport (\n\t\"errors\"\n\t\"mime\"\n\t\"net/http\"\n\n\t\"google.golang.org/grpc/grpclog\"\n\t\"google.golang.org/protobuf/encoding/protojson\"\n)\n\n// MIMEWildcard is the fallback MIME type used for requests which do not match\n// a registered MIME type.\nconst MIMEWildcard = \"*\"\n\nvar (\n\tacceptHeader      = http.CanonicalHeaderKey(\"Accept\")\n\tcontentTypeHeader = http.CanonicalHeaderKey(\"Content-Type\")\n\n\tdefaultMarshaler = &HTTPBodyMarshaler{\n\t\tMarshaler: &JSONPb{\n\t\t\tMarshalOptions: protojson.MarshalOptions{\n\t\t\t\tEmitUnpopulated: true,\n\t\t\t},\n\t\t\tUnmarshalOptions: protojson.UnmarshalOptions{\n\t\t\t\tDiscardUnknown: true,\n\t\t\t},\n\t\t},\n\t}\n)\n\n// MarshalerForRequest returns the inbound/outbound marshalers for this request.\n// It checks the registry on the ServeMux for the MIME type set by the Content-Type header.\n// If it isn't set (or the request Content-Type is empty), checks for \"*\".\n// If there are multiple Content-Type headers set, choose the first one that it can\n// exactly match in the registry.\n// Otherwise, it follows the above logic for \"*\"/InboundMarshaler/OutboundMarshaler.\nfunc MarshalerForRequest(mux *ServeMux, r *http.Request) (inbound Marshaler, outbound Marshaler) {\n\tfor _, acceptVal := range r.Header[acceptHeader] {\n\t\tif m, ok := mux.marshalers.mimeMap[acceptVal]; ok {\n\t\t\toutbound = m\n\t\t\tbreak\n\t\t}\n\t}\n\n\tfor _, contentTypeVal := range r.Header[contentTypeHeader] {\n\t\tcontentType, _, err := mime.ParseMediaType(contentTypeVal)\n\t\tif err != nil {\n\t\t\tgrpclog.Errorf(\"Failed to parse Content-Type %s: %v\", contentTypeVal, err)\n\t\t\tcontinue\n\t\t}\n\t\tif m, ok := mux.marshalers.mimeMap[contentType]; ok {\n\t\t\tinbound = m\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif inbound == nil {\n\t\tinbound = mux.marshalers.mimeMap[MIMEWildcard]\n\t}\n\tif outbound == nil {\n\t\toutbound = inbound\n\t}\n\n\treturn inbound, outbound\n}\n\n// marshalerRegistry is a mapping from MIME types to Marshalers.\ntype marshalerRegistry struct {\n\tmimeMap map[string]Marshaler\n}\n\n// add adds a marshaler for a case-sensitive MIME type string (\"*\" to match any\n// MIME type).\nfunc (m marshalerRegistry) add(mime string, marshaler Marshaler) error {\n\tif len(mime) == 0 {\n\t\treturn errors.New(\"empty MIME type\")\n\t}\n\n\tm.mimeMap[mime] = marshaler\n\n\treturn nil\n}\n\n// makeMarshalerMIMERegistry returns a new registry of marshalers.\n// It allows for a mapping of case-sensitive Content-Type MIME type string to runtime.Marshaler interfaces.\n//\n// For example, you could allow the client to specify the use of the runtime.JSONPb marshaler\n// with an \"application/jsonpb\" Content-Type and the use of the runtime.JSONBuiltin marshaler\n// with an \"application/json\" Content-Type.\n// \"*\" can be used to match any Content-Type.\n// This can be attached to a ServerMux with the marshaler option.\nfunc makeMarshalerMIMERegistry() marshalerRegistry {\n\treturn marshalerRegistry{\n\t\tmimeMap: map[string]Marshaler{\n\t\t\tMIMEWildcard: defaultMarshaler,\n\t\t},\n\t}\n}\n\n// WithMarshalerOption returns a ServeMuxOption which associates inbound and outbound\n// Marshalers to a MIME type in mux.\nfunc WithMarshalerOption(mime string, marshaler Marshaler) ServeMuxOption {\n\treturn func(mux *ServeMux) {\n\t\tif err := mux.marshalers.add(mime, marshaler); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/mux.go",
    "content": "package runtime\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/textproto\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/grpclog\"\n\t\"google.golang.org/grpc/health/grpc_health_v1\"\n\t\"google.golang.org/grpc/metadata\"\n\t\"google.golang.org/grpc/status\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\n// UnescapingMode defines the behavior of ServeMux when unescaping path parameters.\ntype UnescapingMode int\n\nconst (\n\t// UnescapingModeLegacy is the default V2 behavior, which escapes the entire\n\t// path string before doing any routing.\n\tUnescapingModeLegacy UnescapingMode = iota\n\n\t// UnescapingModeAllExceptReserved unescapes all path parameters except RFC 6570\n\t// reserved characters.\n\tUnescapingModeAllExceptReserved\n\n\t// UnescapingModeAllExceptSlash unescapes URL path parameters except path\n\t// separators, which will be left as \"%2F\".\n\tUnescapingModeAllExceptSlash\n\n\t// UnescapingModeAllCharacters unescapes all URL path parameters.\n\tUnescapingModeAllCharacters\n\n\t// UnescapingModeDefault is the default escaping type.\n\t// TODO(v3): default this to UnescapingModeAllExceptReserved per grpc-httpjson-transcoding's\n\t// reference implementation\n\tUnescapingModeDefault = UnescapingModeLegacy\n)\n\nvar encodedPathSplitter = regexp.MustCompile(\"(/|%2F)\")\n\n// A HandlerFunc handles a specific pair of path pattern and HTTP method.\ntype HandlerFunc func(w http.ResponseWriter, r *http.Request, pathParams map[string]string)\n\n// A Middleware handler wraps another HandlerFunc to do some pre- and/or post-processing of the request. This is used as an alternative to gRPC interceptors when using the direct-to-implementation\n// registration methods. It is generally recommended to use gRPC client or server interceptors instead\n// where possible.\ntype Middleware func(HandlerFunc) HandlerFunc\n\n// ServeMux is a request multiplexer for grpc-gateway.\n// It matches http requests to patterns and invokes the corresponding handler.\ntype ServeMux struct {\n\t// handlers maps HTTP method to a list of handlers.\n\thandlers                  map[string][]handler\n\tmiddlewares               []Middleware\n\tforwardResponseOptions    []func(context.Context, http.ResponseWriter, proto.Message) error\n\tforwardResponseRewriter   ForwardResponseRewriter\n\tmarshalers                marshalerRegistry\n\tincomingHeaderMatcher     HeaderMatcherFunc\n\toutgoingHeaderMatcher     HeaderMatcherFunc\n\toutgoingTrailerMatcher    HeaderMatcherFunc\n\tmetadataAnnotators        []func(context.Context, *http.Request) metadata.MD\n\terrorHandler              ErrorHandlerFunc\n\tstreamErrorHandler        StreamErrorHandlerFunc\n\troutingErrorHandler       RoutingErrorHandlerFunc\n\tdisablePathLengthFallback bool\n\tunescapingMode            UnescapingMode\n\twriteContentLength        bool\n}\n\n// ServeMuxOption is an option that can be given to a ServeMux on construction.\ntype ServeMuxOption func(*ServeMux)\n\n// ForwardResponseRewriter is the signature of a function that is capable of rewriting messages\n// before they are forwarded in a unary, stream, or error response.\ntype ForwardResponseRewriter func(ctx context.Context, response proto.Message) (any, error)\n\n// WithForwardResponseRewriter returns a ServeMuxOption that allows for implementers to insert logic\n// that can rewrite the final response before it is forwarded.\n//\n// The response rewriter function is called during unary message forwarding, stream message\n// forwarding and when errors are being forwarded.\n//\n// NOTE: Using this option will likely make what is generated by `protoc-gen-openapiv2` incorrect.\n// Since this option involves making runtime changes to the response shape or type.\nfunc WithForwardResponseRewriter(fwdResponseRewriter ForwardResponseRewriter) ServeMuxOption {\n\treturn func(sm *ServeMux) {\n\t\tsm.forwardResponseRewriter = fwdResponseRewriter\n\t}\n}\n\n// WithForwardResponseOption returns a ServeMuxOption representing the forwardResponseOption.\n//\n// forwardResponseOption is an option that will be called on the relevant context.Context,\n// http.ResponseWriter, and proto.Message before every forwarded response.\n//\n// The message may be nil in the case where just a header is being sent.\nfunc WithForwardResponseOption(forwardResponseOption func(context.Context, http.ResponseWriter, proto.Message) error) ServeMuxOption {\n\treturn func(serveMux *ServeMux) {\n\t\tserveMux.forwardResponseOptions = append(serveMux.forwardResponseOptions, forwardResponseOption)\n\t}\n}\n\n// WithUnescapingMode sets the escaping type. See the definitions of UnescapingMode\n// for more information.\nfunc WithUnescapingMode(mode UnescapingMode) ServeMuxOption {\n\treturn func(serveMux *ServeMux) {\n\t\tserveMux.unescapingMode = mode\n\t}\n}\n\n// WithMiddlewares sets server middleware for all handlers. This is useful as an alternative to gRPC\n// interceptors when using the direct-to-implementation registration methods and cannot rely\n// on gRPC interceptors. It's recommended to use gRPC interceptors instead if possible.\nfunc WithMiddlewares(middlewares ...Middleware) ServeMuxOption {\n\treturn func(serveMux *ServeMux) {\n\t\tserveMux.middlewares = append(serveMux.middlewares, middlewares...)\n\t}\n}\n\n// SetQueryParameterParser sets the query parameter parser, used to populate message from query parameters.\n// Configuring this will mean the generated OpenAPI output is no longer correct, and it should be\n// done with careful consideration.\nfunc SetQueryParameterParser(queryParameterParser QueryParameterParser) ServeMuxOption {\n\treturn func(serveMux *ServeMux) {\n\t\tcurrentQueryParser = queryParameterParser\n\t}\n}\n\n// HeaderMatcherFunc checks whether a header key should be forwarded to/from gRPC context.\ntype HeaderMatcherFunc func(string) (string, bool)\n\n// DefaultHeaderMatcher is used to pass http request headers to/from gRPC context. This adds permanent HTTP header\n// keys (as specified by the IANA, e.g: Accept, Cookie, Host) to the gRPC metadata with the grpcgateway- prefix. If you want to know which headers are considered permanent, you can view the isPermanentHTTPHeader function.\n// HTTP headers that start with 'Grpc-Metadata-' are mapped to gRPC metadata after removing the prefix 'Grpc-Metadata-'.\n// Other headers are not added to the gRPC metadata.\nfunc DefaultHeaderMatcher(key string) (string, bool) {\n\tswitch key = textproto.CanonicalMIMEHeaderKey(key); {\n\tcase isPermanentHTTPHeader(key):\n\t\treturn MetadataPrefix + key, true\n\tcase strings.HasPrefix(key, MetadataHeaderPrefix):\n\t\treturn key[len(MetadataHeaderPrefix):], true\n\t}\n\treturn \"\", false\n}\n\nfunc defaultOutgoingHeaderMatcher(key string) (string, bool) {\n\treturn fmt.Sprintf(\"%s%s\", MetadataHeaderPrefix, key), true\n}\n\nfunc defaultOutgoingTrailerMatcher(key string) (string, bool) {\n\treturn fmt.Sprintf(\"%s%s\", MetadataTrailerPrefix, key), true\n}\n\n// WithIncomingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for incoming request to gateway.\n//\n// This matcher will be called with each header in http.Request. If matcher returns true, that header will be\n// passed to gRPC context. To transform the header before passing to gRPC context, matcher should return the modified header.\nfunc WithIncomingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption {\n\tfor _, header := range fn.matchedMalformedHeaders() {\n\t\tgrpclog.Warningf(\"The configured forwarding filter would allow %q to be sent to the gRPC server, which will likely cause errors. See https://github.com/grpc/grpc-go/pull/4803#issuecomment-986093310 for more information.\", header)\n\t}\n\n\treturn func(mux *ServeMux) {\n\t\tmux.incomingHeaderMatcher = fn\n\t}\n}\n\n// matchedMalformedHeaders returns the malformed headers that would be forwarded to gRPC server.\nfunc (fn HeaderMatcherFunc) matchedMalformedHeaders() []string {\n\tif fn == nil {\n\t\treturn nil\n\t}\n\theaders := make([]string, 0)\n\tfor header := range malformedHTTPHeaders {\n\t\tout, accept := fn(header)\n\t\tif accept && isMalformedHTTPHeader(out) {\n\t\t\theaders = append(headers, out)\n\t\t}\n\t}\n\treturn headers\n}\n\n// WithOutgoingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for outgoing response from gateway.\n//\n// This matcher will be called with each header in response header metadata. If matcher returns true, that header will be\n// passed to http response returned from gateway. To transform the header before passing to response,\n// matcher should return the modified header.\nfunc WithOutgoingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption {\n\treturn func(mux *ServeMux) {\n\t\tmux.outgoingHeaderMatcher = fn\n\t}\n}\n\n// WithOutgoingTrailerMatcher returns a ServeMuxOption representing a headerMatcher for outgoing response from gateway.\n//\n// This matcher will be called with each header in response trailer metadata. If matcher returns true, that header will be\n// passed to http response returned from gateway. To transform the header before passing to response,\n// matcher should return the modified header.\nfunc WithOutgoingTrailerMatcher(fn HeaderMatcherFunc) ServeMuxOption {\n\treturn func(mux *ServeMux) {\n\t\tmux.outgoingTrailerMatcher = fn\n\t}\n}\n\n// WithMetadata returns a ServeMuxOption for passing metadata to a gRPC context.\n//\n// This can be used by services that need to read from http.Request and modify gRPC context. A common use case\n// is reading token from cookie and adding it in gRPC context.\nfunc WithMetadata(annotator func(context.Context, *http.Request) metadata.MD) ServeMuxOption {\n\treturn func(serveMux *ServeMux) {\n\t\tserveMux.metadataAnnotators = append(serveMux.metadataAnnotators, annotator)\n\t}\n}\n\n// WithErrorHandler returns a ServeMuxOption for configuring a custom error handler.\n//\n// This can be used to configure a custom error response.\nfunc WithErrorHandler(fn ErrorHandlerFunc) ServeMuxOption {\n\treturn func(serveMux *ServeMux) {\n\t\tserveMux.errorHandler = fn\n\t}\n}\n\n// WithStreamErrorHandler returns a ServeMuxOption that will use the given custom stream\n// error handler, which allows for customizing the error trailer for server-streaming\n// calls.\n//\n// For stream errors that occur before any response has been written, the mux's\n// ErrorHandler will be invoked. However, once data has been written, the errors must\n// be handled differently: they must be included in the response body. The response body's\n// final message will include the error details returned by the stream error handler.\nfunc WithStreamErrorHandler(fn StreamErrorHandlerFunc) ServeMuxOption {\n\treturn func(serveMux *ServeMux) {\n\t\tserveMux.streamErrorHandler = fn\n\t}\n}\n\n// WithRoutingErrorHandler returns a ServeMuxOption for configuring a custom error handler to  handle http routing errors.\n//\n// Method called for errors which can happen before gRPC route selected or executed.\n// The following error codes: StatusMethodNotAllowed StatusNotFound StatusBadRequest\nfunc WithRoutingErrorHandler(fn RoutingErrorHandlerFunc) ServeMuxOption {\n\treturn func(serveMux *ServeMux) {\n\t\tserveMux.routingErrorHandler = fn\n\t}\n}\n\n// WithDisablePathLengthFallback returns a ServeMuxOption for disable path length fallback.\nfunc WithDisablePathLengthFallback() ServeMuxOption {\n\treturn func(serveMux *ServeMux) {\n\t\tserveMux.disablePathLengthFallback = true\n\t}\n}\n\n// WithWriteContentLength returns a ServeMuxOption to enable writing content length on non-streaming responses\nfunc WithWriteContentLength() ServeMuxOption {\n\treturn func(serveMux *ServeMux) {\n\t\tserveMux.writeContentLength = true\n\t}\n}\n\n// WithHealthEndpointAt returns a ServeMuxOption that will add an endpoint to the created ServeMux at the path specified by endpointPath.\n// When called the handler will forward the request to the upstream grpc service health check (defined in the\n// gRPC Health Checking Protocol).\n//\n// See here https://grpc-ecosystem.github.io/grpc-gateway/docs/operations/health_check/ for more information on how\n// to setup the protocol in the grpc server.\n//\n// If you define a service as query parameter, this will also be forwarded as service in the HealthCheckRequest.\nfunc WithHealthEndpointAt(healthCheckClient grpc_health_v1.HealthClient, endpointPath string) ServeMuxOption {\n\treturn func(s *ServeMux) {\n\t\t// error can be ignored since pattern is definitely valid\n\t\t_ = s.HandlePath(\n\t\t\thttp.MethodGet, endpointPath, func(w http.ResponseWriter, r *http.Request, _ map[string]string,\n\t\t\t) {\n\t\t\t\t_, outboundMarshaler := MarshalerForRequest(s, r)\n\n\t\t\t\tresp, err := healthCheckClient.Check(r.Context(), &grpc_health_v1.HealthCheckRequest{\n\t\t\t\t\tService: r.URL.Query().Get(\"service\"),\n\t\t\t\t})\n\t\t\t\tif err != nil {\n\t\t\t\t\ts.errorHandler(r.Context(), s, outboundMarshaler, w, r, err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tw.Header().Set(\"Content-Type\", \"application/json\")\n\n\t\t\t\tif resp.GetStatus() != grpc_health_v1.HealthCheckResponse_SERVING {\n\t\t\t\t\tswitch resp.GetStatus() {\n\t\t\t\t\tcase grpc_health_v1.HealthCheckResponse_NOT_SERVING, grpc_health_v1.HealthCheckResponse_UNKNOWN:\n\t\t\t\t\t\terr = status.Error(codes.Unavailable, resp.String())\n\t\t\t\t\tcase grpc_health_v1.HealthCheckResponse_SERVICE_UNKNOWN:\n\t\t\t\t\t\terr = status.Error(codes.NotFound, resp.String())\n\t\t\t\t\t}\n\n\t\t\t\t\ts.errorHandler(r.Context(), s, outboundMarshaler, w, r, err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t_ = outboundMarshaler.NewEncoder(w).Encode(resp)\n\t\t\t})\n\t}\n}\n\n// WithHealthzEndpoint returns a ServeMuxOption that will add a /healthz endpoint to the created ServeMux.\n//\n// See WithHealthEndpointAt for the general implementation.\nfunc WithHealthzEndpoint(healthCheckClient grpc_health_v1.HealthClient) ServeMuxOption {\n\treturn WithHealthEndpointAt(healthCheckClient, \"/healthz\")\n}\n\n// NewServeMux returns a new ServeMux whose internal mapping is empty.\nfunc NewServeMux(opts ...ServeMuxOption) *ServeMux {\n\tserveMux := &ServeMux{\n\t\thandlers:                make(map[string][]handler),\n\t\tforwardResponseOptions:  make([]func(context.Context, http.ResponseWriter, proto.Message) error, 0),\n\t\tforwardResponseRewriter: func(ctx context.Context, response proto.Message) (any, error) { return response, nil },\n\t\tmarshalers:              makeMarshalerMIMERegistry(),\n\t\terrorHandler:            DefaultHTTPErrorHandler,\n\t\tstreamErrorHandler:      DefaultStreamErrorHandler,\n\t\troutingErrorHandler:     DefaultRoutingErrorHandler,\n\t\tunescapingMode:          UnescapingModeDefault,\n\t}\n\n\tfor _, opt := range opts {\n\t\topt(serveMux)\n\t}\n\n\tif serveMux.incomingHeaderMatcher == nil {\n\t\tserveMux.incomingHeaderMatcher = DefaultHeaderMatcher\n\t}\n\tif serveMux.outgoingHeaderMatcher == nil {\n\t\tserveMux.outgoingHeaderMatcher = defaultOutgoingHeaderMatcher\n\t}\n\tif serveMux.outgoingTrailerMatcher == nil {\n\t\tserveMux.outgoingTrailerMatcher = defaultOutgoingTrailerMatcher\n\t}\n\n\treturn serveMux\n}\n\n// Handle associates \"h\" to the pair of HTTP method and path pattern.\nfunc (s *ServeMux) Handle(meth string, pat Pattern, h HandlerFunc) {\n\tif len(s.middlewares) > 0 {\n\t\th = chainMiddlewares(s.middlewares)(h)\n\t}\n\ts.handlers[meth] = append([]handler{{pat: pat, h: h}}, s.handlers[meth]...)\n}\n\n// HandlePath allows users to configure custom path handlers.\n// refer: https://grpc-ecosystem.github.io/grpc-gateway/docs/operations/inject_router/\nfunc (s *ServeMux) HandlePath(meth string, pathPattern string, h HandlerFunc) error {\n\tcompiler, err := httprule.Parse(pathPattern)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parsing path pattern: %w\", err)\n\t}\n\ttp := compiler.Compile()\n\tpattern, err := NewPattern(tp.Version, tp.OpCodes, tp.Pool, tp.Verb)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"creating new pattern: %w\", err)\n\t}\n\ts.Handle(meth, pattern, h)\n\treturn nil\n}\n\n// ServeHTTP dispatches the request to the first handler whose pattern matches to r.Method and r.URL.Path.\nfunc (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tctx := r.Context()\n\n\tpath := r.URL.Path\n\tif !strings.HasPrefix(path, \"/\") {\n\t\t_, outboundMarshaler := MarshalerForRequest(s, r)\n\t\ts.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusBadRequest)\n\t\treturn\n\t}\n\n\t// TODO(v3): remove UnescapingModeLegacy\n\tif s.unescapingMode != UnescapingModeLegacy && r.URL.RawPath != \"\" {\n\t\tpath = r.URL.RawPath\n\t}\n\n\tif override := r.Header.Get(\"X-HTTP-Method-Override\"); override != \"\" && s.isPathLengthFallback(r) {\n\t\tif err := r.ParseForm(); err != nil {\n\t\t\t_, outboundMarshaler := MarshalerForRequest(s, r)\n\t\t\tsterr := status.Error(codes.InvalidArgument, err.Error())\n\t\t\ts.errorHandler(ctx, s, outboundMarshaler, w, r, sterr)\n\t\t\treturn\n\t\t}\n\t\tr.Method = strings.ToUpper(override)\n\t}\n\n\tvar pathComponents []string\n\t// since in UnescapeModeLegacy, the URL will already have been fully unescaped, if we also split on \"%2F\"\n\t// in this escaping mode we would be double unescaping but in UnescapingModeAllCharacters, we still do as the\n\t// path is the RawPath (i.e. unescaped). That does mean that the behavior of this function will change its default\n\t// behavior when the UnescapingModeDefault gets changed from UnescapingModeLegacy to UnescapingModeAllExceptReserved\n\tif s.unescapingMode == UnescapingModeAllCharacters {\n\t\tpathComponents = encodedPathSplitter.Split(path[1:], -1)\n\t} else {\n\t\tpathComponents = strings.Split(path[1:], \"/\")\n\t}\n\n\tlastPathComponent := pathComponents[len(pathComponents)-1]\n\n\tfor _, h := range s.handlers[r.Method] {\n\t\t// If the pattern has a verb, explicitly look for a suffix in the last\n\t\t// component that matches a colon plus the verb. This allows us to\n\t\t// handle some cases that otherwise can't be correctly handled by the\n\t\t// former LastIndex case, such as when the verb literal itself contains\n\t\t// a colon. This should work for all cases that have run through the\n\t\t// parser because we know what verb we're looking for, however, there\n\t\t// are still some cases that the parser itself cannot disambiguate. See\n\t\t// the comment there if interested.\n\n\t\tvar verb string\n\t\tpatVerb := h.pat.Verb()\n\n\t\tidx := -1\n\t\tif patVerb != \"\" && strings.HasSuffix(lastPathComponent, \":\"+patVerb) {\n\t\t\tidx = len(lastPathComponent) - len(patVerb) - 1\n\t\t}\n\t\tif idx == 0 {\n\t\t\t_, outboundMarshaler := MarshalerForRequest(s, r)\n\t\t\ts.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusNotFound)\n\t\t\treturn\n\t\t}\n\n\t\tcomps := make([]string, len(pathComponents))\n\t\tcopy(comps, pathComponents)\n\n\t\tif idx > 0 {\n\t\t\tcomps[len(comps)-1], verb = lastPathComponent[:idx], lastPathComponent[idx+1:]\n\t\t}\n\n\t\tpathParams, err := h.pat.MatchAndEscape(comps, verb, s.unescapingMode)\n\t\tif err != nil {\n\t\t\tvar mse MalformedSequenceError\n\t\t\tif ok := errors.As(err, &mse); ok {\n\t\t\t\t_, outboundMarshaler := MarshalerForRequest(s, r)\n\t\t\t\ts.errorHandler(ctx, s, outboundMarshaler, w, r, &HTTPStatusError{\n\t\t\t\t\tHTTPStatus: http.StatusBadRequest,\n\t\t\t\t\tErr:        mse,\n\t\t\t\t})\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\ts.handleHandler(h, w, r, pathParams)\n\t\treturn\n\t}\n\n\t// if no handler has found for the request, lookup for other methods\n\t// to handle POST -> GET fallback if the request is subject to path\n\t// length fallback.\n\t// Note we are not eagerly checking the request here as we want to return the\n\t// right HTTP status code, and we need to process the fallback candidates in\n\t// order to do that.\n\tfor m, handlers := range s.handlers {\n\t\tif m == r.Method {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, h := range handlers {\n\t\t\tvar verb string\n\t\t\tpatVerb := h.pat.Verb()\n\n\t\t\tidx := -1\n\t\t\tif patVerb != \"\" && strings.HasSuffix(lastPathComponent, \":\"+patVerb) {\n\t\t\t\tidx = len(lastPathComponent) - len(patVerb) - 1\n\t\t\t}\n\n\t\t\tcomps := make([]string, len(pathComponents))\n\t\t\tcopy(comps, pathComponents)\n\n\t\t\tif idx > 0 {\n\t\t\t\tcomps[len(comps)-1], verb = lastPathComponent[:idx], lastPathComponent[idx+1:]\n\t\t\t}\n\n\t\t\tpathParams, err := h.pat.MatchAndEscape(comps, verb, s.unescapingMode)\n\t\t\tif err != nil {\n\t\t\t\tvar mse MalformedSequenceError\n\t\t\t\tif ok := errors.As(err, &mse); ok {\n\t\t\t\t\t_, outboundMarshaler := MarshalerForRequest(s, r)\n\t\t\t\t\ts.errorHandler(ctx, s, outboundMarshaler, w, r, &HTTPStatusError{\n\t\t\t\t\t\tHTTPStatus: http.StatusBadRequest,\n\t\t\t\t\t\tErr:        mse,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// X-HTTP-Method-Override is optional. Always allow fallback to POST.\n\t\t\t// Also, only consider POST -> GET fallbacks, and avoid falling back to\n\t\t\t// potentially dangerous operations like DELETE.\n\t\t\tif s.isPathLengthFallback(r) && m == http.MethodGet {\n\t\t\t\tif err := r.ParseForm(); err != nil {\n\t\t\t\t\t_, outboundMarshaler := MarshalerForRequest(s, r)\n\t\t\t\t\tsterr := status.Error(codes.InvalidArgument, err.Error())\n\t\t\t\t\ts.errorHandler(ctx, s, outboundMarshaler, w, r, sterr)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\ts.handleHandler(h, w, r, pathParams)\n\t\t\t\treturn\n\t\t\t}\n\t\t\t_, outboundMarshaler := MarshalerForRequest(s, r)\n\t\t\ts.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusMethodNotAllowed)\n\t\t\treturn\n\t\t}\n\t}\n\n\t_, outboundMarshaler := MarshalerForRequest(s, r)\n\ts.routingErrorHandler(ctx, s, outboundMarshaler, w, r, http.StatusNotFound)\n}\n\n// GetForwardResponseOptions returns the ForwardResponseOptions associated with this ServeMux.\nfunc (s *ServeMux) GetForwardResponseOptions() []func(context.Context, http.ResponseWriter, proto.Message) error {\n\treturn s.forwardResponseOptions\n}\n\nfunc (s *ServeMux) isPathLengthFallback(r *http.Request) bool {\n\treturn !s.disablePathLengthFallback && r.Method == \"POST\" && r.Header.Get(\"Content-Type\") == \"application/x-www-form-urlencoded\"\n}\n\ntype handler struct {\n\tpat Pattern\n\th   HandlerFunc\n}\n\nfunc (s *ServeMux) handleHandler(h handler, w http.ResponseWriter, r *http.Request, pathParams map[string]string) {\n\th.h(w, r.WithContext(withHTTPPattern(r.Context(), h.pat)), pathParams)\n}\n\nfunc chainMiddlewares(mws []Middleware) Middleware {\n\treturn func(next HandlerFunc) HandlerFunc {\n\t\tfor i := len(mws); i > 0; i-- {\n\t\t\tnext = mws[i-1](next)\n\t\t}\n\t\treturn next\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/pattern.go",
    "content": "package runtime\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/grpc-ecosystem/grpc-gateway/v2/utilities\"\n\t\"google.golang.org/grpc/grpclog\"\n)\n\nvar (\n\t// ErrNotMatch indicates that the given HTTP request path does not match to the pattern.\n\tErrNotMatch = errors.New(\"not match to the path pattern\")\n\t// ErrInvalidPattern indicates that the given definition of Pattern is not valid.\n\tErrInvalidPattern = errors.New(\"invalid pattern\")\n)\n\ntype MalformedSequenceError string\n\nfunc (e MalformedSequenceError) Error() string {\n\treturn \"malformed path escape \" + strconv.Quote(string(e))\n}\n\ntype op struct {\n\tcode    utilities.OpCode\n\toperand int\n}\n\n// Pattern is a template pattern of http request paths defined in\n// https://github.com/googleapis/googleapis/blob/master/google/api/http.proto\ntype Pattern struct {\n\t// ops is a list of operations\n\tops []op\n\t// pool is a constant pool indexed by the operands or vars.\n\tpool []string\n\t// vars is a list of variables names to be bound by this pattern\n\tvars []string\n\t// stacksize is the max depth of the stack\n\tstacksize int\n\t// tailLen is the length of the fixed-size segments after a deep wildcard\n\ttailLen int\n\t// verb is the VERB part of the path pattern. It is empty if the pattern does not have VERB part.\n\tverb string\n}\n\n// NewPattern returns a new Pattern from the given definition values.\n// \"ops\" is a sequence of op codes. \"pool\" is a constant pool.\n// \"verb\" is the verb part of the pattern. It is empty if the pattern does not have the part.\n// \"version\" must be 1 for now.\n// It returns an error if the given definition is invalid.\nfunc NewPattern(version int, ops []int, pool []string, verb string) (Pattern, error) {\n\tif version != 1 {\n\t\tgrpclog.Errorf(\"unsupported version: %d\", version)\n\t\treturn Pattern{}, ErrInvalidPattern\n\t}\n\n\tl := len(ops)\n\tif l%2 != 0 {\n\t\tgrpclog.Errorf(\"odd number of ops codes: %d\", l)\n\t\treturn Pattern{}, ErrInvalidPattern\n\t}\n\n\tvar (\n\t\ttypedOps        []op\n\t\tstack, maxstack int\n\t\ttailLen         int\n\t\tpushMSeen       bool\n\t\tvars            []string\n\t)\n\tfor i := 0; i < l; i += 2 {\n\t\top := op{code: utilities.OpCode(ops[i]), operand: ops[i+1]}\n\t\tswitch op.code {\n\t\tcase utilities.OpNop:\n\t\t\tcontinue\n\t\tcase utilities.OpPush:\n\t\t\tif pushMSeen {\n\t\t\t\ttailLen++\n\t\t\t}\n\t\t\tstack++\n\t\tcase utilities.OpPushM:\n\t\t\tif pushMSeen {\n\t\t\t\tgrpclog.Error(\"pushM appears twice\")\n\t\t\t\treturn Pattern{}, ErrInvalidPattern\n\t\t\t}\n\t\t\tpushMSeen = true\n\t\t\tstack++\n\t\tcase utilities.OpLitPush:\n\t\t\tif op.operand < 0 || len(pool) <= op.operand {\n\t\t\t\tgrpclog.Errorf(\"negative literal index: %d\", op.operand)\n\t\t\t\treturn Pattern{}, ErrInvalidPattern\n\t\t\t}\n\t\t\tif pushMSeen {\n\t\t\t\ttailLen++\n\t\t\t}\n\t\t\tstack++\n\t\tcase utilities.OpConcatN:\n\t\t\tif op.operand <= 0 {\n\t\t\t\tgrpclog.Errorf(\"negative concat size: %d\", op.operand)\n\t\t\t\treturn Pattern{}, ErrInvalidPattern\n\t\t\t}\n\t\t\tstack -= op.operand\n\t\t\tif stack < 0 {\n\t\t\t\tgrpclog.Error(\"stack underflow\")\n\t\t\t\treturn Pattern{}, ErrInvalidPattern\n\t\t\t}\n\t\t\tstack++\n\t\tcase utilities.OpCapture:\n\t\t\tif op.operand < 0 || len(pool) <= op.operand {\n\t\t\t\tgrpclog.Errorf(\"variable name index out of bound: %d\", op.operand)\n\t\t\t\treturn Pattern{}, ErrInvalidPattern\n\t\t\t}\n\t\t\tv := pool[op.operand]\n\t\t\top.operand = len(vars)\n\t\t\tvars = append(vars, v)\n\t\t\tstack--\n\t\t\tif stack < 0 {\n\t\t\t\tgrpclog.Error(\"stack underflow\")\n\t\t\t\treturn Pattern{}, ErrInvalidPattern\n\t\t\t}\n\t\tdefault:\n\t\t\tgrpclog.Errorf(\"invalid opcode: %d\", op.code)\n\t\t\treturn Pattern{}, ErrInvalidPattern\n\t\t}\n\n\t\tif maxstack < stack {\n\t\t\tmaxstack = stack\n\t\t}\n\t\ttypedOps = append(typedOps, op)\n\t}\n\treturn Pattern{\n\t\tops:       typedOps,\n\t\tpool:      pool,\n\t\tvars:      vars,\n\t\tstacksize: maxstack,\n\t\ttailLen:   tailLen,\n\t\tverb:      verb,\n\t}, nil\n}\n\n// MustPattern is a helper function which makes it easier to call NewPattern in variable initialization.\nfunc MustPattern(p Pattern, err error) Pattern {\n\tif err != nil {\n\t\tgrpclog.Fatalf(\"Pattern initialization failed: %v\", err)\n\t}\n\treturn p\n}\n\n// MatchAndEscape examines components to determine if they match to a Pattern.\n// MatchAndEscape will return an error if no Patterns matched or if a pattern\n// matched but contained malformed escape sequences. If successful, the function\n// returns a mapping from field paths to their captured values.\nfunc (p Pattern) MatchAndEscape(components []string, verb string, unescapingMode UnescapingMode) (map[string]string, error) {\n\tif p.verb != verb {\n\t\tif p.verb != \"\" {\n\t\t\treturn nil, ErrNotMatch\n\t\t}\n\t\tif len(components) == 0 {\n\t\t\tcomponents = []string{\":\" + verb}\n\t\t} else {\n\t\t\tcomponents = append([]string{}, components...)\n\t\t\tcomponents[len(components)-1] += \":\" + verb\n\t\t}\n\t}\n\n\tvar pos int\n\tstack := make([]string, 0, p.stacksize)\n\tcaptured := make([]string, len(p.vars))\n\tl := len(components)\n\tfor _, op := range p.ops {\n\t\tvar err error\n\n\t\tswitch op.code {\n\t\tcase utilities.OpNop:\n\t\t\tcontinue\n\t\tcase utilities.OpPush, utilities.OpLitPush:\n\t\t\tif pos >= l {\n\t\t\t\treturn nil, ErrNotMatch\n\t\t\t}\n\t\t\tc := components[pos]\n\t\t\tif op.code == utilities.OpLitPush {\n\t\t\t\tif lit := p.pool[op.operand]; c != lit {\n\t\t\t\t\treturn nil, ErrNotMatch\n\t\t\t\t}\n\t\t\t} else if op.code == utilities.OpPush {\n\t\t\t\tif c, err = unescape(c, unescapingMode, false); err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t}\n\t\t\tstack = append(stack, c)\n\t\t\tpos++\n\t\tcase utilities.OpPushM:\n\t\t\tend := len(components)\n\t\t\tif end < pos+p.tailLen {\n\t\t\t\treturn nil, ErrNotMatch\n\t\t\t}\n\t\t\tend -= p.tailLen\n\t\t\tc := strings.Join(components[pos:end], \"/\")\n\t\t\tif c, err = unescape(c, unescapingMode, true); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tstack = append(stack, c)\n\t\t\tpos = end\n\t\tcase utilities.OpConcatN:\n\t\t\tn := op.operand\n\t\t\tl := len(stack) - n\n\t\t\tstack = append(stack[:l], strings.Join(stack[l:], \"/\"))\n\t\tcase utilities.OpCapture:\n\t\t\tn := len(stack) - 1\n\t\t\tcaptured[op.operand] = stack[n]\n\t\t\tstack = stack[:n]\n\t\t}\n\t}\n\tif pos < l {\n\t\treturn nil, ErrNotMatch\n\t}\n\tbindings := make(map[string]string)\n\tfor i, val := range captured {\n\t\tbindings[p.vars[i]] = val\n\t}\n\treturn bindings, nil\n}\n\n// MatchAndEscape examines components to determine if they match to a Pattern.\n// It will never perform per-component unescaping (see: UnescapingModeLegacy).\n// MatchAndEscape will return an error if no Patterns matched. If successful,\n// the function returns a mapping from field paths to their captured values.\n//\n// Deprecated: Use MatchAndEscape.\nfunc (p Pattern) Match(components []string, verb string) (map[string]string, error) {\n\treturn p.MatchAndEscape(components, verb, UnescapingModeDefault)\n}\n\n// Verb returns the verb part of the Pattern.\nfunc (p Pattern) Verb() string { return p.verb }\n\nfunc (p Pattern) String() string {\n\tvar stack []string\n\tfor _, op := range p.ops {\n\t\tswitch op.code {\n\t\tcase utilities.OpNop:\n\t\t\tcontinue\n\t\tcase utilities.OpPush:\n\t\t\tstack = append(stack, \"*\")\n\t\tcase utilities.OpLitPush:\n\t\t\tstack = append(stack, p.pool[op.operand])\n\t\tcase utilities.OpPushM:\n\t\t\tstack = append(stack, \"**\")\n\t\tcase utilities.OpConcatN:\n\t\t\tn := op.operand\n\t\t\tl := len(stack) - n\n\t\t\tstack = append(stack[:l], strings.Join(stack[l:], \"/\"))\n\t\tcase utilities.OpCapture:\n\t\t\tn := len(stack) - 1\n\t\t\tstack[n] = fmt.Sprintf(\"{%s=%s}\", p.vars[op.operand], stack[n])\n\t\t}\n\t}\n\tsegs := strings.Join(stack, \"/\")\n\tif p.verb != \"\" {\n\t\treturn fmt.Sprintf(\"/%s:%s\", segs, p.verb)\n\t}\n\treturn \"/\" + segs\n}\n\n/*\n * The following code is adopted and modified from Go's standard library\n * and carries the attached license.\n *\n *     Copyright 2009 The Go 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 */\n\n// ishex returns whether or not the given byte is a valid hex character\nfunc ishex(c byte) bool {\n\tswitch {\n\tcase '0' <= c && c <= '9':\n\t\treturn true\n\tcase 'a' <= c && c <= 'f':\n\t\treturn true\n\tcase 'A' <= c && c <= 'F':\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc isRFC6570Reserved(c byte) bool {\n\tswitch c {\n\tcase '!', '#', '$', '&', '\\'', '(', ')', '*',\n\t\t'+', ',', '/', ':', ';', '=', '?', '@', '[', ']':\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// unhex converts a hex point to the bit representation\nfunc unhex(c byte) byte {\n\tswitch {\n\tcase '0' <= c && c <= '9':\n\t\treturn c - '0'\n\tcase 'a' <= c && c <= 'f':\n\t\treturn c - 'a' + 10\n\tcase 'A' <= c && c <= 'F':\n\t\treturn c - 'A' + 10\n\t}\n\treturn 0\n}\n\n// shouldUnescapeWithMode returns true if the character is escapable with the\n// given mode\nfunc shouldUnescapeWithMode(c byte, mode UnescapingMode) bool {\n\tswitch mode {\n\tcase UnescapingModeAllExceptReserved:\n\t\tif isRFC6570Reserved(c) {\n\t\t\treturn false\n\t\t}\n\tcase UnescapingModeAllExceptSlash:\n\t\tif c == '/' {\n\t\t\treturn false\n\t\t}\n\tcase UnescapingModeAllCharacters:\n\t\treturn true\n\t}\n\treturn true\n}\n\n// unescape unescapes a path string using the provided mode\nfunc unescape(s string, mode UnescapingMode, multisegment bool) (string, error) {\n\t// TODO(v3): remove UnescapingModeLegacy\n\tif mode == UnescapingModeLegacy {\n\t\treturn s, nil\n\t}\n\n\tif !multisegment {\n\t\tmode = UnescapingModeAllCharacters\n\t}\n\n\t// Count %, check that they're well-formed.\n\tn := 0\n\tfor i := 0; i < len(s); {\n\t\tif s[i] == '%' {\n\t\t\tn++\n\t\t\tif i+2 >= len(s) || !ishex(s[i+1]) || !ishex(s[i+2]) {\n\t\t\t\ts = s[i:]\n\t\t\t\tif len(s) > 3 {\n\t\t\t\t\ts = s[:3]\n\t\t\t\t}\n\n\t\t\t\treturn \"\", MalformedSequenceError(s)\n\t\t\t}\n\t\t\ti += 3\n\t\t} else {\n\t\t\ti++\n\t\t}\n\t}\n\n\tif n == 0 {\n\t\treturn s, nil\n\t}\n\n\tvar t strings.Builder\n\tt.Grow(len(s))\n\tfor i := 0; i < len(s); i++ {\n\t\tswitch s[i] {\n\t\tcase '%':\n\t\t\tc := unhex(s[i+1])<<4 | unhex(s[i+2])\n\t\t\tif shouldUnescapeWithMode(c, mode) {\n\t\t\t\tt.WriteByte(c)\n\t\t\t\ti += 2\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfallthrough\n\t\tdefault:\n\t\t\tt.WriteByte(s[i])\n\t\t}\n\t}\n\n\treturn t.String(), nil\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/proto2_convert.go",
    "content": "package runtime\n\nimport (\n\t\"google.golang.org/protobuf/proto\"\n)\n\n// StringP returns a pointer to a string whose pointee is same as the given string value.\nfunc StringP(val string) (*string, error) {\n\treturn proto.String(val), nil\n}\n\n// BoolP parses the given string representation of a boolean value,\n// and returns a pointer to a bool whose value is same as the parsed value.\nfunc BoolP(val string) (*bool, error) {\n\tb, err := Bool(val)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn proto.Bool(b), nil\n}\n\n// Float64P parses the given string representation of a floating point number,\n// and returns a pointer to a float64 whose value is same as the parsed number.\nfunc Float64P(val string) (*float64, error) {\n\tf, err := Float64(val)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn proto.Float64(f), nil\n}\n\n// Float32P parses the given string representation of a floating point number,\n// and returns a pointer to a float32 whose value is same as the parsed number.\nfunc Float32P(val string) (*float32, error) {\n\tf, err := Float32(val)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn proto.Float32(f), nil\n}\n\n// Int64P parses the given string representation of an integer\n// and returns a pointer to an int64 whose value is same as the parsed integer.\nfunc Int64P(val string) (*int64, error) {\n\ti, err := Int64(val)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn proto.Int64(i), nil\n}\n\n// Int32P parses the given string representation of an integer\n// and returns a pointer to an int32 whose value is same as the parsed integer.\nfunc Int32P(val string) (*int32, error) {\n\ti, err := Int32(val)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn proto.Int32(i), err\n}\n\n// Uint64P parses the given string representation of an integer\n// and returns a pointer to a uint64 whose value is same as the parsed integer.\nfunc Uint64P(val string) (*uint64, error) {\n\ti, err := Uint64(val)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn proto.Uint64(i), err\n}\n\n// Uint32P parses the given string representation of an integer\n// and returns a pointer to a uint32 whose value is same as the parsed integer.\nfunc Uint32P(val string) (*uint32, error) {\n\ti, err := Uint32(val)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn proto.Uint32(i), err\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/query.go",
    "content": "package runtime\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/grpc-ecosystem/grpc-gateway/v2/utilities\"\n\t\"google.golang.org/grpc/grpclog\"\n\t\"google.golang.org/protobuf/encoding/protojson\"\n\t\"google.golang.org/protobuf/proto\"\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n\t\"google.golang.org/protobuf/reflect/protoregistry\"\n\t\"google.golang.org/protobuf/types/known/durationpb\"\n\tfield_mask \"google.golang.org/protobuf/types/known/fieldmaskpb\"\n\t\"google.golang.org/protobuf/types/known/structpb\"\n\t\"google.golang.org/protobuf/types/known/timestamppb\"\n\t\"google.golang.org/protobuf/types/known/wrapperspb\"\n)\n\nvar valuesKeyRegexp = regexp.MustCompile(`^(.*)\\[(.*)\\]$`)\n\nvar currentQueryParser QueryParameterParser = &DefaultQueryParser{}\n\n// QueryParameterParser defines interface for all query parameter parsers\ntype QueryParameterParser interface {\n\tParse(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error\n}\n\n// PopulateQueryParameters parses query parameters\n// into \"msg\" using current query parser\nfunc PopulateQueryParameters(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error {\n\treturn currentQueryParser.Parse(msg, values, filter)\n}\n\n// DefaultQueryParser is a QueryParameterParser which implements the default\n// query parameters parsing behavior.\n//\n// See https://github.com/grpc-ecosystem/grpc-gateway/issues/2632 for more context.\ntype DefaultQueryParser struct{}\n\n// Parse populates \"values\" into \"msg\".\n// A value is ignored if its key starts with one of the elements in \"filter\".\nfunc (*DefaultQueryParser) Parse(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error {\n\tfor key, values := range values {\n\t\tif match := valuesKeyRegexp.FindStringSubmatch(key); len(match) == 3 {\n\t\t\tkey = match[1]\n\t\t\tvalues = append([]string{match[2]}, values...)\n\t\t}\n\n\t\tmsgValue := msg.ProtoReflect()\n\t\tfieldPath := normalizeFieldPath(msgValue, strings.Split(key, \".\"))\n\t\tif filter.HasCommonPrefix(fieldPath) {\n\t\t\tcontinue\n\t\t}\n\t\tif err := populateFieldValueFromPath(msgValue, fieldPath, values); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// PopulateFieldFromPath sets a value in a nested Protobuf structure.\nfunc PopulateFieldFromPath(msg proto.Message, fieldPathString string, value string) error {\n\tfieldPath := strings.Split(fieldPathString, \".\")\n\treturn populateFieldValueFromPath(msg.ProtoReflect(), fieldPath, []string{value})\n}\n\nfunc normalizeFieldPath(msgValue protoreflect.Message, fieldPath []string) []string {\n\tnewFieldPath := make([]string, 0, len(fieldPath))\n\tfor i, fieldName := range fieldPath {\n\t\tfields := msgValue.Descriptor().Fields()\n\t\tfieldDesc := fields.ByTextName(fieldName)\n\t\tif fieldDesc == nil {\n\t\t\tfieldDesc = fields.ByJSONName(fieldName)\n\t\t}\n\t\tif fieldDesc == nil {\n\t\t\t// return initial field path values if no matching  message field was found\n\t\t\treturn fieldPath\n\t\t}\n\n\t\tnewFieldPath = append(newFieldPath, string(fieldDesc.Name()))\n\n\t\t// If this is the last element, we're done\n\t\tif i == len(fieldPath)-1 {\n\t\t\tbreak\n\t\t}\n\n\t\t// Only singular message fields are allowed\n\t\tif fieldDesc.Message() == nil || fieldDesc.Cardinality() == protoreflect.Repeated {\n\t\t\treturn fieldPath\n\t\t}\n\n\t\t// Get the nested message\n\t\tmsgValue = msgValue.Get(fieldDesc).Message()\n\t}\n\n\treturn newFieldPath\n}\n\nfunc populateFieldValueFromPath(msgValue protoreflect.Message, fieldPath []string, values []string) error {\n\tif len(fieldPath) < 1 {\n\t\treturn errors.New(\"no field path\")\n\t}\n\tif len(values) < 1 {\n\t\treturn errors.New(\"no value provided\")\n\t}\n\n\tvar fieldDescriptor protoreflect.FieldDescriptor\n\tfor i, fieldName := range fieldPath {\n\t\tfields := msgValue.Descriptor().Fields()\n\n\t\t// Get field by name\n\t\tfieldDescriptor = fields.ByName(protoreflect.Name(fieldName))\n\t\tif fieldDescriptor == nil {\n\t\t\tfieldDescriptor = fields.ByJSONName(fieldName)\n\t\t\tif fieldDescriptor == nil {\n\t\t\t\t// We're not returning an error here because this could just be\n\t\t\t\t// an extra query parameter that isn't part of the request.\n\t\t\t\tgrpclog.Infof(\"field not found in %q: %q\", msgValue.Descriptor().FullName(), strings.Join(fieldPath, \".\"))\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\n\t\t// Check if oneof already set\n\t\tif of := fieldDescriptor.ContainingOneof(); of != nil && !of.IsSynthetic() {\n\t\t\tif f := msgValue.WhichOneof(of); f != nil {\n\t\t\t\tif fieldDescriptor.Message() == nil || fieldDescriptor.FullName() != f.FullName() {\n\t\t\t\t\treturn fmt.Errorf(\"field already set for oneof %q\", of.FullName().Name())\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If this is the last element, we're done\n\t\tif i == len(fieldPath)-1 {\n\t\t\tbreak\n\t\t}\n\n\t\t// Only singular message fields are allowed\n\t\tif fieldDescriptor.Message() == nil || fieldDescriptor.Cardinality() == protoreflect.Repeated {\n\t\t\treturn fmt.Errorf(\"invalid path: %q is not a message\", fieldName)\n\t\t}\n\n\t\t// Get the nested message\n\t\tmsgValue = msgValue.Mutable(fieldDescriptor).Message()\n\t}\n\n\tswitch {\n\tcase fieldDescriptor.IsList():\n\t\treturn populateRepeatedField(fieldDescriptor, msgValue.Mutable(fieldDescriptor).List(), values)\n\tcase fieldDescriptor.IsMap():\n\t\treturn populateMapField(fieldDescriptor, msgValue.Mutable(fieldDescriptor).Map(), values)\n\t}\n\n\tif len(values) > 1 {\n\t\treturn fmt.Errorf(\"too many values for field %q: %s\", fieldDescriptor.FullName().Name(), strings.Join(values, \", \"))\n\t}\n\n\treturn populateField(fieldDescriptor, msgValue, values[0])\n}\n\nfunc populateField(fieldDescriptor protoreflect.FieldDescriptor, msgValue protoreflect.Message, value string) error {\n\tv, err := parseField(fieldDescriptor, value)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parsing field %q: %w\", fieldDescriptor.FullName().Name(), err)\n\t}\n\n\tmsgValue.Set(fieldDescriptor, v)\n\treturn nil\n}\n\nfunc populateRepeatedField(fieldDescriptor protoreflect.FieldDescriptor, list protoreflect.List, values []string) error {\n\tfor _, value := range values {\n\t\tv, err := parseField(fieldDescriptor, value)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"parsing list %q: %w\", fieldDescriptor.FullName().Name(), err)\n\t\t}\n\t\tlist.Append(v)\n\t}\n\n\treturn nil\n}\n\nfunc populateMapField(fieldDescriptor protoreflect.FieldDescriptor, mp protoreflect.Map, values []string) error {\n\tif len(values) != 2 {\n\t\treturn fmt.Errorf(\"more than one value provided for key %q in map %q\", values[0], fieldDescriptor.FullName())\n\t}\n\n\tkey, err := parseField(fieldDescriptor.MapKey(), values[0])\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parsing map key %q: %w\", fieldDescriptor.FullName().Name(), err)\n\t}\n\n\tvalue, err := parseField(fieldDescriptor.MapValue(), values[1])\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parsing map value %q: %w\", fieldDescriptor.FullName().Name(), err)\n\t}\n\n\tmp.Set(key.MapKey(), value)\n\n\treturn nil\n}\n\nfunc parseField(fieldDescriptor protoreflect.FieldDescriptor, value string) (protoreflect.Value, error) {\n\tswitch fieldDescriptor.Kind() {\n\tcase protoreflect.BoolKind:\n\t\tv, err := strconv.ParseBool(value)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\treturn protoreflect.ValueOfBool(v), nil\n\tcase protoreflect.EnumKind:\n\t\tenum, err := protoregistry.GlobalTypes.FindEnumByName(fieldDescriptor.Enum().FullName())\n\t\tif err != nil {\n\t\t\tif errors.Is(err, protoregistry.NotFound) {\n\t\t\t\treturn protoreflect.Value{}, fmt.Errorf(\"enum %q is not registered\", fieldDescriptor.Enum().FullName())\n\t\t\t}\n\t\t\treturn protoreflect.Value{}, fmt.Errorf(\"failed to look up enum: %w\", err)\n\t\t}\n\t\t// Look for enum by name\n\t\tv := enum.Descriptor().Values().ByName(protoreflect.Name(value))\n\t\tif v == nil {\n\t\t\ti, err := strconv.Atoi(value)\n\t\t\tif err != nil {\n\t\t\t\treturn protoreflect.Value{}, fmt.Errorf(\"%q is not a valid value\", value)\n\t\t\t}\n\t\t\t// Look for enum by number\n\t\t\tif v = enum.Descriptor().Values().ByNumber(protoreflect.EnumNumber(i)); v == nil {\n\t\t\t\treturn protoreflect.Value{}, fmt.Errorf(\"%q is not a valid value\", value)\n\t\t\t}\n\t\t}\n\t\treturn protoreflect.ValueOfEnum(v.Number()), nil\n\tcase protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:\n\t\tv, err := strconv.ParseInt(value, 10, 32)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\treturn protoreflect.ValueOfInt32(int32(v)), nil\n\tcase protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:\n\t\tv, err := strconv.ParseInt(value, 10, 64)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\treturn protoreflect.ValueOfInt64(v), nil\n\tcase protoreflect.Uint32Kind, protoreflect.Fixed32Kind:\n\t\tv, err := strconv.ParseUint(value, 10, 32)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\treturn protoreflect.ValueOfUint32(uint32(v)), nil\n\tcase protoreflect.Uint64Kind, protoreflect.Fixed64Kind:\n\t\tv, err := strconv.ParseUint(value, 10, 64)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\treturn protoreflect.ValueOfUint64(v), nil\n\tcase protoreflect.FloatKind:\n\t\tv, err := strconv.ParseFloat(value, 32)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\treturn protoreflect.ValueOfFloat32(float32(v)), nil\n\tcase protoreflect.DoubleKind:\n\t\tv, err := strconv.ParseFloat(value, 64)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\treturn protoreflect.ValueOfFloat64(v), nil\n\tcase protoreflect.StringKind:\n\t\treturn protoreflect.ValueOfString(value), nil\n\tcase protoreflect.BytesKind:\n\t\tv, err := Bytes(value)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\treturn protoreflect.ValueOfBytes(v), nil\n\tcase protoreflect.MessageKind, protoreflect.GroupKind:\n\t\treturn parseMessage(fieldDescriptor.Message(), value)\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unknown field kind: %v\", fieldDescriptor.Kind()))\n\t}\n}\n\nfunc parseMessage(msgDescriptor protoreflect.MessageDescriptor, value string) (protoreflect.Value, error) {\n\tvar msg proto.Message\n\tswitch msgDescriptor.FullName() {\n\tcase \"google.protobuf.Timestamp\":\n\t\tt, err := time.Parse(time.RFC3339Nano, value)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\ttimestamp := timestamppb.New(t)\n\t\tif ok := timestamp.IsValid(); !ok {\n\t\t\treturn protoreflect.Value{}, fmt.Errorf(\"%s before 0001-01-01\", value)\n\t\t}\n\t\tmsg = timestamp\n\tcase \"google.protobuf.Duration\":\n\t\td, err := time.ParseDuration(value)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\tmsg = durationpb.New(d)\n\tcase \"google.protobuf.DoubleValue\":\n\t\tv, err := strconv.ParseFloat(value, 64)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\tmsg = wrapperspb.Double(v)\n\tcase \"google.protobuf.FloatValue\":\n\t\tv, err := strconv.ParseFloat(value, 32)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\tmsg = wrapperspb.Float(float32(v))\n\tcase \"google.protobuf.Int64Value\":\n\t\tv, err := strconv.ParseInt(value, 10, 64)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\tmsg = wrapperspb.Int64(v)\n\tcase \"google.protobuf.Int32Value\":\n\t\tv, err := strconv.ParseInt(value, 10, 32)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\tmsg = wrapperspb.Int32(int32(v))\n\tcase \"google.protobuf.UInt64Value\":\n\t\tv, err := strconv.ParseUint(value, 10, 64)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\tmsg = wrapperspb.UInt64(v)\n\tcase \"google.protobuf.UInt32Value\":\n\t\tv, err := strconv.ParseUint(value, 10, 32)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\tmsg = wrapperspb.UInt32(uint32(v))\n\tcase \"google.protobuf.BoolValue\":\n\t\tv, err := strconv.ParseBool(value)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\tmsg = wrapperspb.Bool(v)\n\tcase \"google.protobuf.StringValue\":\n\t\tmsg = wrapperspb.String(value)\n\tcase \"google.protobuf.BytesValue\":\n\t\tv, err := Bytes(value)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\tmsg = wrapperspb.Bytes(v)\n\tcase \"google.protobuf.FieldMask\":\n\t\tfm := &field_mask.FieldMask{}\n\t\tfm.Paths = append(fm.Paths, strings.Split(value, \",\")...)\n\t\tmsg = fm\n\tcase \"google.protobuf.Value\":\n\t\tvar v structpb.Value\n\t\tif err := protojson.Unmarshal([]byte(value), &v); err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\tmsg = &v\n\tcase \"google.protobuf.Struct\":\n\t\tvar v structpb.Struct\n\t\tif err := protojson.Unmarshal([]byte(value), &v); err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\tmsg = &v\n\tdefault:\n\t\treturn protoreflect.Value{}, fmt.Errorf(\"unsupported message type: %q\", string(msgDescriptor.FullName()))\n\t}\n\n\treturn protoreflect.ValueOfMessage(msg.ProtoReflect()), nil\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/BUILD.bazel",
    "content": "load(\"@io_bazel_rules_go//go:def.bzl\", \"go_library\", \"go_test\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ngo_library(\n    name = \"utilities\",\n    srcs = [\n        \"doc.go\",\n        \"pattern.go\",\n        \"readerfactory.go\",\n        \"string_array_flag.go\",\n        \"trie.go\",\n    ],\n    importpath = \"github.com/grpc-ecosystem/grpc-gateway/v2/utilities\",\n)\n\ngo_test(\n    name = \"utilities_test\",\n    size = \"small\",\n    srcs = [\n        \"string_array_flag_test.go\",\n        \"trie_test.go\",\n    ],\n    deps = [\":utilities\"],\n)\n\nalias(\n    name = \"go_default_library\",\n    actual = \":utilities\",\n    visibility = [\"//visibility:public\"],\n)\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/doc.go",
    "content": "// Package utilities provides members for internal use in grpc-gateway.\npackage utilities\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/pattern.go",
    "content": "package utilities\n\n// OpCode is an opcode of compiled path patterns.\ntype OpCode int\n\n// These constants are the valid values of OpCode.\nconst (\n\t// OpNop does nothing\n\tOpNop = OpCode(iota)\n\t// OpPush pushes a component to stack\n\tOpPush\n\t// OpLitPush pushes a component to stack if it matches to the literal\n\tOpLitPush\n\t// OpPushM concatenates the remaining components and pushes it to stack\n\tOpPushM\n\t// OpConcatN pops N items from stack, concatenates them and pushes it back to stack\n\tOpConcatN\n\t// OpCapture pops an item and binds it to the variable\n\tOpCapture\n\t// OpEnd is the least positive invalid opcode.\n\tOpEnd\n)\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/readerfactory.go",
    "content": "package utilities\n\nimport (\n\t\"bytes\"\n\t\"io\"\n)\n\n// IOReaderFactory takes in an io.Reader and returns a function that will allow you to create a new reader that begins\n// at the start of the stream\nfunc IOReaderFactory(r io.Reader) (func() io.Reader, error) {\n\tb, err := io.ReadAll(r)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn func() io.Reader {\n\t\treturn bytes.NewReader(b)\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/string_array_flag.go",
    "content": "package utilities\n\nimport (\n\t\"flag\"\n\t\"strings\"\n)\n\n// flagInterface is a cut down interface to `flag`\ntype flagInterface interface {\n\tVar(value flag.Value, name string, usage string)\n}\n\n// StringArrayFlag defines a flag with the specified name and usage string.\n// The return value is the address of a `StringArrayFlags` variable that stores the repeated values of the flag.\nfunc StringArrayFlag(f flagInterface, name string, usage string) *StringArrayFlags {\n\tvalue := &StringArrayFlags{}\n\tf.Var(value, name, usage)\n\treturn value\n}\n\n// StringArrayFlags is a wrapper of `[]string` to provider an interface for `flag.Var`\ntype StringArrayFlags []string\n\n// String returns a string representation of `StringArrayFlags`\nfunc (i *StringArrayFlags) String() string {\n\treturn strings.Join(*i, \",\")\n}\n\n// Set appends a value to `StringArrayFlags`\nfunc (i *StringArrayFlags) Set(value string) error {\n\t*i = append(*i, value)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/grpc-ecosystem/grpc-gateway/v2/utilities/trie.go",
    "content": "package utilities\n\nimport (\n\t\"sort\"\n)\n\n// DoubleArray is a Double Array implementation of trie on sequences of strings.\ntype DoubleArray struct {\n\t// Encoding keeps an encoding from string to int\n\tEncoding map[string]int\n\t// Base is the base array of Double Array\n\tBase []int\n\t// Check is the check array of Double Array\n\tCheck []int\n}\n\n// NewDoubleArray builds a DoubleArray from a set of sequences of strings.\nfunc NewDoubleArray(seqs [][]string) *DoubleArray {\n\tda := &DoubleArray{Encoding: make(map[string]int)}\n\tif len(seqs) == 0 {\n\t\treturn da\n\t}\n\n\tencoded := registerTokens(da, seqs)\n\tsort.Sort(byLex(encoded))\n\n\troot := node{row: -1, col: -1, left: 0, right: len(encoded)}\n\taddSeqs(da, encoded, 0, root)\n\n\tfor i := len(da.Base); i > 0; i-- {\n\t\tif da.Check[i-1] != 0 {\n\t\t\tda.Base = da.Base[:i]\n\t\t\tda.Check = da.Check[:i]\n\t\t\tbreak\n\t\t}\n\t}\n\treturn da\n}\n\nfunc registerTokens(da *DoubleArray, seqs [][]string) [][]int {\n\tvar result [][]int\n\tfor _, seq := range seqs {\n\t\tencoded := make([]int, 0, len(seq))\n\t\tfor _, token := range seq {\n\t\t\tif _, ok := da.Encoding[token]; !ok {\n\t\t\t\tda.Encoding[token] = len(da.Encoding)\n\t\t\t}\n\t\t\tencoded = append(encoded, da.Encoding[token])\n\t\t}\n\t\tresult = append(result, encoded)\n\t}\n\tfor i := range result {\n\t\tresult[i] = append(result[i], len(da.Encoding))\n\t}\n\treturn result\n}\n\ntype node struct {\n\trow, col    int\n\tleft, right int\n}\n\nfunc (n node) value(seqs [][]int) int {\n\treturn seqs[n.row][n.col]\n}\n\nfunc (n node) children(seqs [][]int) []*node {\n\tvar result []*node\n\tlastVal := int(-1)\n\tlast := new(node)\n\tfor i := n.left; i < n.right; i++ {\n\t\tif lastVal == seqs[i][n.col+1] {\n\t\t\tcontinue\n\t\t}\n\t\tlast.right = i\n\t\tlast = &node{\n\t\t\trow:  i,\n\t\t\tcol:  n.col + 1,\n\t\t\tleft: i,\n\t\t}\n\t\tresult = append(result, last)\n\t}\n\tlast.right = n.right\n\treturn result\n}\n\nfunc addSeqs(da *DoubleArray, seqs [][]int, pos int, n node) {\n\tensureSize(da, pos)\n\n\tchildren := n.children(seqs)\n\tvar i int\n\tfor i = 1; ; i++ {\n\t\tok := func() bool {\n\t\t\tfor _, child := range children {\n\t\t\t\tcode := child.value(seqs)\n\t\t\t\tj := i + code\n\t\t\t\tensureSize(da, j)\n\t\t\t\tif da.Check[j] != 0 {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true\n\t\t}()\n\t\tif ok {\n\t\t\tbreak\n\t\t}\n\t}\n\tda.Base[pos] = i\n\tfor _, child := range children {\n\t\tcode := child.value(seqs)\n\t\tj := i + code\n\t\tda.Check[j] = pos + 1\n\t}\n\tterminator := len(da.Encoding)\n\tfor _, child := range children {\n\t\tcode := child.value(seqs)\n\t\tif code == terminator {\n\t\t\tcontinue\n\t\t}\n\t\tj := i + code\n\t\taddSeqs(da, seqs, j, *child)\n\t}\n}\n\nfunc ensureSize(da *DoubleArray, i int) {\n\tfor i >= len(da.Base) {\n\t\tda.Base = append(da.Base, make([]int, len(da.Base)+1)...)\n\t\tda.Check = append(da.Check, make([]int, len(da.Check)+1)...)\n\t}\n}\n\ntype byLex [][]int\n\nfunc (l byLex) Len() int      { return len(l) }\nfunc (l byLex) Swap(i, j int) { l[i], l[j] = l[j], l[i] }\nfunc (l byLex) Less(i, j int) bool {\n\tsi := l[i]\n\tsj := l[j]\n\tvar k int\n\tfor k = 0; k < len(si) && k < len(sj); k++ {\n\t\tif si[k] < sj[k] {\n\t\t\treturn true\n\t\t}\n\t\tif si[k] > sj[k] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn k < len(sj)\n}\n\n// HasCommonPrefix determines if any sequence in the DoubleArray is a prefix of the given sequence.\nfunc (da *DoubleArray) HasCommonPrefix(seq []string) bool {\n\tif len(da.Base) == 0 {\n\t\treturn false\n\t}\n\n\tvar i int\n\tfor _, t := range seq {\n\t\tcode, ok := da.Encoding[t]\n\t\tif !ok {\n\t\t\tbreak\n\t\t}\n\t\tj := da.Base[i] + code\n\t\tif len(da.Check) <= j || da.Check[j] != i+1 {\n\t\t\tbreak\n\t\t}\n\t\ti = j\n\t}\n\tj := da.Base[i] + len(da.Encoding)\n\tif len(da.Check) <= j || da.Check[j] != i+1 {\n\t\treturn false\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/LICENSE",
    "content": "Copyright (c) 2012 The Go Authors. All rights reserved.\nCopyright (c) 2019 Klaus Post. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(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\n------------------\n\nFiles: gzhttp/*\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2016-2017 The New York Times Company\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n------------------\n\nFiles: s2/cmd/internal/readahead/*\n\nThe MIT License (MIT)\n\nCopyright (c) 2015 Klaus Post\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n---------------------\nFiles: snappy/*\nFiles: internal/snapref/*\n\nCopyright (c) 2011 The Snappy-Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(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\n-----------------\n\nFiles: s2/cmd/internal/filepathx/*\n\nCopyright 2016 The filepathx Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/deflate.go",
    "content": "// Copyright 2009 The Go Authors. All rights reserved.\n// Copyright (c) 2015 Klaus Post\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage flate\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n)\n\nconst (\n\tNoCompression      = 0\n\tBestSpeed          = 1\n\tBestCompression    = 9\n\tDefaultCompression = -1\n\n\t// HuffmanOnly disables Lempel-Ziv match searching and only performs Huffman\n\t// entropy encoding. This mode is useful in compressing data that has\n\t// already been compressed with an LZ style algorithm (e.g. Snappy or LZ4)\n\t// that lacks an entropy encoder. Compression gains are achieved when\n\t// certain bytes in the input stream occur more frequently than others.\n\t//\n\t// Note that HuffmanOnly produces a compressed output that is\n\t// RFC 1951 compliant. That is, any valid DEFLATE decompressor will\n\t// continue to be able to decompress this output.\n\tHuffmanOnly         = -2\n\tConstantCompression = HuffmanOnly // compatibility alias.\n\n\tlogWindowSize    = 15\n\twindowSize       = 1 << logWindowSize\n\twindowMask       = windowSize - 1\n\tlogMaxOffsetSize = 15  // Standard DEFLATE\n\tminMatchLength   = 4   // The smallest match that the compressor looks for\n\tmaxMatchLength   = 258 // The longest match for the compressor\n\tminOffsetSize    = 1   // The shortest offset that makes any sense\n\n\t// The maximum number of tokens we will encode at the time.\n\t// Smaller sizes usually creates less optimal blocks.\n\t// Bigger can make context switching slow.\n\t// We use this for levels 7-9, so we make it big.\n\tmaxFlateBlockTokens = 1 << 15\n\tmaxStoreBlockSize   = 65535\n\thashBits            = 17 // After 17 performance degrades\n\thashSize            = 1 << hashBits\n\thashMask            = (1 << hashBits) - 1\n\thashShift           = (hashBits + minMatchLength - 1) / minMatchLength\n\tmaxHashOffset       = 1 << 28\n\n\tskipNever = math.MaxInt32\n\n\tdebugDeflate = false\n)\n\ntype compressionLevel struct {\n\tgood, lazy, nice, chain, fastSkipHashing, level int\n}\n\n// Compression levels have been rebalanced from zlib deflate defaults\n// to give a bigger spread in speed and compression.\n// See https://blog.klauspost.com/rebalancing-deflate-compression-levels/\nvar levels = []compressionLevel{\n\t{}, // 0\n\t// Level 1-6 uses specialized algorithm - values not used\n\t{0, 0, 0, 0, 0, 1},\n\t{0, 0, 0, 0, 0, 2},\n\t{0, 0, 0, 0, 0, 3},\n\t{0, 0, 0, 0, 0, 4},\n\t{0, 0, 0, 0, 0, 5},\n\t{0, 0, 0, 0, 0, 6},\n\t// Levels 7-9 use increasingly more lazy matching\n\t// and increasingly stringent conditions for \"good enough\".\n\t{8, 12, 16, 24, skipNever, 7},\n\t{16, 30, 40, 64, skipNever, 8},\n\t{32, 258, 258, 1024, skipNever, 9},\n}\n\n// advancedState contains state for the advanced levels, with bigger hash tables, etc.\ntype advancedState struct {\n\t// deflate state\n\tlength         int\n\toffset         int\n\tmaxInsertIndex int\n\tchainHead      int\n\thashOffset     int\n\n\tii uint16 // position of last match, intended to overflow to reset.\n\n\t// input window: unprocessed data is window[index:windowEnd]\n\tindex     int\n\thashMatch [maxMatchLength + minMatchLength]uint32\n\n\t// Input hash chains\n\t// hashHead[hashValue] contains the largest inputIndex with the specified hash value\n\t// If hashHead[hashValue] is within the current window, then\n\t// hashPrev[hashHead[hashValue] & windowMask] contains the previous index\n\t// with the same hash value.\n\thashHead [hashSize]uint32\n\thashPrev [windowSize]uint32\n}\n\ntype compressor struct {\n\tcompressionLevel\n\n\th *huffmanEncoder\n\tw *huffmanBitWriter\n\n\t// compression algorithm\n\tfill func(*compressor, []byte) int // copy data to window\n\tstep func(*compressor)             // process window\n\n\twindow     []byte\n\twindowEnd  int\n\tblockStart int // window index where current tokens start\n\terr        error\n\n\t// queued output tokens\n\ttokens tokens\n\tfast   fastEnc\n\tstate  *advancedState\n\n\tsync          bool // requesting flush\n\tbyteAvailable bool // if true, still need to process window[index-1].\n}\n\nfunc (d *compressor) fillDeflate(b []byte) int {\n\ts := d.state\n\tif s.index >= 2*windowSize-(minMatchLength+maxMatchLength) {\n\t\t// shift the window by windowSize\n\t\t//copy(d.window[:], d.window[windowSize:2*windowSize])\n\t\t*(*[windowSize]byte)(d.window) = *(*[windowSize]byte)(d.window[windowSize:])\n\t\ts.index -= windowSize\n\t\td.windowEnd -= windowSize\n\t\tif d.blockStart >= windowSize {\n\t\t\td.blockStart -= windowSize\n\t\t} else {\n\t\t\td.blockStart = math.MaxInt32\n\t\t}\n\t\ts.hashOffset += windowSize\n\t\tif s.hashOffset > maxHashOffset {\n\t\t\tdelta := s.hashOffset - 1\n\t\t\ts.hashOffset -= delta\n\t\t\ts.chainHead -= delta\n\t\t\t// Iterate over slices instead of arrays to avoid copying\n\t\t\t// the entire table onto the stack (Issue #18625).\n\t\t\tfor i, v := range s.hashPrev[:] {\n\t\t\t\tif int(v) > delta {\n\t\t\t\t\ts.hashPrev[i] = uint32(int(v) - delta)\n\t\t\t\t} else {\n\t\t\t\t\ts.hashPrev[i] = 0\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor i, v := range s.hashHead[:] {\n\t\t\t\tif int(v) > delta {\n\t\t\t\t\ts.hashHead[i] = uint32(int(v) - delta)\n\t\t\t\t} else {\n\t\t\t\t\ts.hashHead[i] = 0\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tn := copy(d.window[d.windowEnd:], b)\n\td.windowEnd += n\n\treturn n\n}\n\nfunc (d *compressor) writeBlock(tok *tokens, index int, eof bool) error {\n\tif index > 0 || eof {\n\t\tvar window []byte\n\t\tif d.blockStart <= index {\n\t\t\twindow = d.window[d.blockStart:index]\n\t\t}\n\t\td.blockStart = index\n\t\t//d.w.writeBlock(tok, eof, window)\n\t\td.w.writeBlockDynamic(tok, eof, window, d.sync)\n\t\treturn d.w.err\n\t}\n\treturn nil\n}\n\n// writeBlockSkip writes the current block and uses the number of tokens\n// to determine if the block should be stored on no matches, or\n// only huffman encoded.\nfunc (d *compressor) writeBlockSkip(tok *tokens, index int, eof bool) error {\n\tif index > 0 || eof {\n\t\tif d.blockStart <= index {\n\t\t\twindow := d.window[d.blockStart:index]\n\t\t\t// If we removed less than a 64th of all literals\n\t\t\t// we huffman compress the block.\n\t\t\tif int(tok.n) > len(window)-int(tok.n>>6) {\n\t\t\t\td.w.writeBlockHuff(eof, window, d.sync)\n\t\t\t} else {\n\t\t\t\t// Write a dynamic huffman block.\n\t\t\t\td.w.writeBlockDynamic(tok, eof, window, d.sync)\n\t\t\t}\n\t\t} else {\n\t\t\td.w.writeBlock(tok, eof, nil)\n\t\t}\n\t\td.blockStart = index\n\t\treturn d.w.err\n\t}\n\treturn nil\n}\n\n// fillWindow will fill the current window with the supplied\n// dictionary and calculate all hashes.\n// This is much faster than doing a full encode.\n// Should only be used after a start/reset.\nfunc (d *compressor) fillWindow(b []byte) {\n\t// Do not fill window if we are in store-only or huffman mode.\n\tif d.level <= 0 && d.level > -MinCustomWindowSize {\n\t\treturn\n\t}\n\tif d.fast != nil {\n\t\t// encode the last data, but discard the result\n\t\tif len(b) > maxMatchOffset {\n\t\t\tb = b[len(b)-maxMatchOffset:]\n\t\t}\n\t\td.fast.Encode(&d.tokens, b)\n\t\td.tokens.Reset()\n\t\treturn\n\t}\n\ts := d.state\n\t// If we are given too much, cut it.\n\tif len(b) > windowSize {\n\t\tb = b[len(b)-windowSize:]\n\t}\n\t// Add all to window.\n\tn := copy(d.window[d.windowEnd:], b)\n\n\t// Calculate 256 hashes at the time (more L1 cache hits)\n\tloops := (n + 256 - minMatchLength) / 256\n\tfor j := 0; j < loops; j++ {\n\t\tstartindex := j * 256\n\t\tend := startindex + 256 + minMatchLength - 1\n\t\tif end > n {\n\t\t\tend = n\n\t\t}\n\t\ttocheck := d.window[startindex:end]\n\t\tdstSize := len(tocheck) - minMatchLength + 1\n\n\t\tif dstSize <= 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tdst := s.hashMatch[:dstSize]\n\t\tbulkHash4(tocheck, dst)\n\t\tvar newH uint32\n\t\tfor i, val := range dst {\n\t\t\tdi := i + startindex\n\t\t\tnewH = val & hashMask\n\t\t\t// Get previous value with the same hash.\n\t\t\t// Our chain should point to the previous value.\n\t\t\ts.hashPrev[di&windowMask] = s.hashHead[newH]\n\t\t\t// Set the head of the hash chain to us.\n\t\t\ts.hashHead[newH] = uint32(di + s.hashOffset)\n\t\t}\n\t}\n\t// Update window information.\n\td.windowEnd += n\n\ts.index = n\n}\n\n// Try to find a match starting at index whose length is greater than prevSize.\n// We only look at chainCount possibilities before giving up.\n// pos = s.index, prevHead = s.chainHead-s.hashOffset, prevLength=minMatchLength-1, lookahead\nfunc (d *compressor) findMatch(pos int, prevHead int, lookahead int) (length, offset int, ok bool) {\n\tminMatchLook := maxMatchLength\n\tif lookahead < minMatchLook {\n\t\tminMatchLook = lookahead\n\t}\n\n\twin := d.window[0 : pos+minMatchLook]\n\n\t// We quit when we get a match that's at least nice long\n\tnice := len(win) - pos\n\tif d.nice < nice {\n\t\tnice = d.nice\n\t}\n\n\t// If we've got a match that's good enough, only look in 1/4 the chain.\n\ttries := d.chain\n\tlength = minMatchLength - 1\n\n\twEnd := win[pos+length]\n\twPos := win[pos:]\n\tminIndex := pos - windowSize\n\tif minIndex < 0 {\n\t\tminIndex = 0\n\t}\n\toffset = 0\n\n\tif d.chain < 100 {\n\t\tfor i := prevHead; tries > 0; tries-- {\n\t\t\tif wEnd == win[i+length] {\n\t\t\t\tn := matchLen(win[i:i+minMatchLook], wPos)\n\t\t\t\tif n > length {\n\t\t\t\t\tlength = n\n\t\t\t\t\toffset = pos - i\n\t\t\t\t\tok = true\n\t\t\t\t\tif n >= nice {\n\t\t\t\t\t\t// The match is good enough that we don't try to find a better one.\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\twEnd = win[pos+n]\n\t\t\t\t}\n\t\t\t}\n\t\t\tif i <= minIndex {\n\t\t\t\t// hashPrev[i & windowMask] has already been overwritten, so stop now.\n\t\t\t\tbreak\n\t\t\t}\n\t\t\ti = int(d.state.hashPrev[i&windowMask]) - d.state.hashOffset\n\t\t\tif i < minIndex {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\treturn\n\t}\n\n\t// Minimum gain to accept a match.\n\tcGain := 4\n\n\t// Some like it higher (CSV), some like it lower (JSON)\n\tconst baseCost = 3\n\t// Base is 4 bytes at with an additional cost.\n\t// Matches must be better than this.\n\n\tfor i := prevHead; tries > 0; tries-- {\n\t\tif wEnd == win[i+length] {\n\t\t\tn := matchLen(win[i:i+minMatchLook], wPos)\n\t\t\tif n > length {\n\t\t\t\t// Calculate gain. Estimate\n\t\t\t\tnewGain := d.h.bitLengthRaw(wPos[:n]) - int(offsetExtraBits[offsetCode(uint32(pos-i))]) - baseCost - int(lengthExtraBits[lengthCodes[(n-3)&255]])\n\n\t\t\t\t//fmt.Println(\"gain:\", newGain, \"prev:\", cGain, \"raw:\", d.h.bitLengthRaw(wPos[:n]), \"this-len:\", n, \"prev-len:\", length)\n\t\t\t\tif newGain > cGain {\n\t\t\t\t\tlength = n\n\t\t\t\t\toffset = pos - i\n\t\t\t\t\tcGain = newGain\n\t\t\t\t\tok = true\n\t\t\t\t\tif n >= nice {\n\t\t\t\t\t\t// The match is good enough that we don't try to find a better one.\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\twEnd = win[pos+n]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif i <= minIndex {\n\t\t\t// hashPrev[i & windowMask] has already been overwritten, so stop now.\n\t\t\tbreak\n\t\t}\n\t\ti = int(d.state.hashPrev[i&windowMask]) - d.state.hashOffset\n\t\tif i < minIndex {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn\n}\n\nfunc (d *compressor) writeStoredBlock(buf []byte) error {\n\tif d.w.writeStoredHeader(len(buf), false); d.w.err != nil {\n\t\treturn d.w.err\n\t}\n\td.w.writeBytes(buf)\n\treturn d.w.err\n}\n\n// hash4 returns a hash representation of the first 4 bytes\n// of the supplied slice.\n// The caller must ensure that len(b) >= 4.\nfunc hash4(b []byte) uint32 {\n\treturn hash4u(binary.LittleEndian.Uint32(b), hashBits)\n}\n\n// hash4 returns the hash of u to fit in a hash table with h bits.\n// Preferably h should be a constant and should always be <32.\nfunc hash4u(u uint32, h uint8) uint32 {\n\treturn (u * prime4bytes) >> (32 - h)\n}\n\n// bulkHash4 will compute hashes using the same\n// algorithm as hash4\nfunc bulkHash4(b []byte, dst []uint32) {\n\tif len(b) < 4 {\n\t\treturn\n\t}\n\thb := binary.LittleEndian.Uint32(b)\n\n\tdst[0] = hash4u(hb, hashBits)\n\tend := len(b) - 4 + 1\n\tfor i := 1; i < end; i++ {\n\t\thb = (hb >> 8) | uint32(b[i+3])<<24\n\t\tdst[i] = hash4u(hb, hashBits)\n\t}\n}\n\nfunc (d *compressor) initDeflate() {\n\td.window = make([]byte, 2*windowSize)\n\td.byteAvailable = false\n\td.err = nil\n\tif d.state == nil {\n\t\treturn\n\t}\n\ts := d.state\n\ts.index = 0\n\ts.hashOffset = 1\n\ts.length = minMatchLength - 1\n\ts.offset = 0\n\ts.chainHead = -1\n}\n\n// deflateLazy is the same as deflate, but with d.fastSkipHashing == skipNever,\n// meaning it always has lazy matching on.\nfunc (d *compressor) deflateLazy() {\n\ts := d.state\n\t// Sanity enables additional runtime tests.\n\t// It's intended to be used during development\n\t// to supplement the currently ad-hoc unit tests.\n\tconst sanity = debugDeflate\n\n\tif d.windowEnd-s.index < minMatchLength+maxMatchLength && !d.sync {\n\t\treturn\n\t}\n\tif d.windowEnd != s.index && d.chain > 100 {\n\t\t// Get literal huffman coder.\n\t\tif d.h == nil {\n\t\t\td.h = newHuffmanEncoder(maxFlateBlockTokens)\n\t\t}\n\t\tvar tmp [256]uint16\n\t\tfor _, v := range d.window[s.index:d.windowEnd] {\n\t\t\ttmp[v]++\n\t\t}\n\t\td.h.generate(tmp[:], 15)\n\t}\n\n\ts.maxInsertIndex = d.windowEnd - (minMatchLength - 1)\n\n\tfor {\n\t\tif sanity && s.index > d.windowEnd {\n\t\t\tpanic(\"index > windowEnd\")\n\t\t}\n\t\tlookahead := d.windowEnd - s.index\n\t\tif lookahead < minMatchLength+maxMatchLength {\n\t\t\tif !d.sync {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif sanity && s.index > d.windowEnd {\n\t\t\t\tpanic(\"index > windowEnd\")\n\t\t\t}\n\t\t\tif lookahead == 0 {\n\t\t\t\t// Flush current output block if any.\n\t\t\t\tif d.byteAvailable {\n\t\t\t\t\t// There is still one pending token that needs to be flushed\n\t\t\t\t\td.tokens.AddLiteral(d.window[s.index-1])\n\t\t\t\t\td.byteAvailable = false\n\t\t\t\t}\n\t\t\t\tif d.tokens.n > 0 {\n\t\t\t\t\tif d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\td.tokens.Reset()\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tif s.index < s.maxInsertIndex {\n\t\t\t// Update the hash\n\t\t\thash := hash4(d.window[s.index:])\n\t\t\tch := s.hashHead[hash]\n\t\t\ts.chainHead = int(ch)\n\t\t\ts.hashPrev[s.index&windowMask] = ch\n\t\t\ts.hashHead[hash] = uint32(s.index + s.hashOffset)\n\t\t}\n\t\tprevLength := s.length\n\t\tprevOffset := s.offset\n\t\ts.length = minMatchLength - 1\n\t\ts.offset = 0\n\t\tminIndex := s.index - windowSize\n\t\tif minIndex < 0 {\n\t\t\tminIndex = 0\n\t\t}\n\n\t\tif s.chainHead-s.hashOffset >= minIndex && lookahead > prevLength && prevLength < d.lazy {\n\t\t\tif newLength, newOffset, ok := d.findMatch(s.index, s.chainHead-s.hashOffset, lookahead); ok {\n\t\t\t\ts.length = newLength\n\t\t\t\ts.offset = newOffset\n\t\t\t}\n\t\t}\n\n\t\tif prevLength >= minMatchLength && s.length <= prevLength {\n\t\t\t// No better match, but check for better match at end...\n\t\t\t//\n\t\t\t// Skip forward a number of bytes.\n\t\t\t// Offset of 2 seems to yield best results. 3 is sometimes better.\n\t\t\tconst checkOff = 2\n\n\t\t\t// Check all, except full length\n\t\t\tif prevLength < maxMatchLength-checkOff {\n\t\t\t\tprevIndex := s.index - 1\n\t\t\t\tif prevIndex+prevLength < s.maxInsertIndex {\n\t\t\t\t\tend := lookahead\n\t\t\t\t\tif lookahead > maxMatchLength+checkOff {\n\t\t\t\t\t\tend = maxMatchLength + checkOff\n\t\t\t\t\t}\n\t\t\t\t\tend += prevIndex\n\n\t\t\t\t\t// Hash at match end.\n\t\t\t\t\th := hash4(d.window[prevIndex+prevLength:])\n\t\t\t\t\tch2 := int(s.hashHead[h]) - s.hashOffset - prevLength\n\t\t\t\t\tif prevIndex-ch2 != prevOffset && ch2 > minIndex+checkOff {\n\t\t\t\t\t\tlength := matchLen(d.window[prevIndex+checkOff:end], d.window[ch2+checkOff:])\n\t\t\t\t\t\t// It seems like a pure length metric is best.\n\t\t\t\t\t\tif length > prevLength {\n\t\t\t\t\t\t\tprevLength = length\n\t\t\t\t\t\t\tprevOffset = prevIndex - ch2\n\n\t\t\t\t\t\t\t// Extend back...\n\t\t\t\t\t\t\tfor i := checkOff - 1; i >= 0; i-- {\n\t\t\t\t\t\t\t\tif prevLength >= maxMatchLength || d.window[prevIndex+i] != d.window[ch2+i] {\n\t\t\t\t\t\t\t\t\t// Emit tokens we \"owe\"\n\t\t\t\t\t\t\t\t\tfor j := 0; j <= i; j++ {\n\t\t\t\t\t\t\t\t\t\td.tokens.AddLiteral(d.window[prevIndex+j])\n\t\t\t\t\t\t\t\t\t\tif d.tokens.n == maxFlateBlockTokens {\n\t\t\t\t\t\t\t\t\t\t\t// The block includes the current character\n\t\t\t\t\t\t\t\t\t\t\tif d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil {\n\t\t\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\td.tokens.Reset()\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\ts.index++\n\t\t\t\t\t\t\t\t\t\tif s.index < s.maxInsertIndex {\n\t\t\t\t\t\t\t\t\t\t\th := hash4(d.window[s.index:])\n\t\t\t\t\t\t\t\t\t\t\tch := s.hashHead[h]\n\t\t\t\t\t\t\t\t\t\t\ts.chainHead = int(ch)\n\t\t\t\t\t\t\t\t\t\t\ts.hashPrev[s.index&windowMask] = ch\n\t\t\t\t\t\t\t\t\t\t\ts.hashHead[h] = uint32(s.index + s.hashOffset)\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\tbreak\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tprevLength++\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if false {\n\t\t\t\t\t\t\t// Check one further ahead.\n\t\t\t\t\t\t\t// Only rarely better, disabled for now.\n\t\t\t\t\t\t\tprevIndex++\n\t\t\t\t\t\t\th := hash4(d.window[prevIndex+prevLength:])\n\t\t\t\t\t\t\tch2 := int(s.hashHead[h]) - s.hashOffset - prevLength\n\t\t\t\t\t\t\tif prevIndex-ch2 != prevOffset && ch2 > minIndex+checkOff {\n\t\t\t\t\t\t\t\tlength := matchLen(d.window[prevIndex+checkOff:end], d.window[ch2+checkOff:])\n\t\t\t\t\t\t\t\t// It seems like a pure length metric is best.\n\t\t\t\t\t\t\t\tif length > prevLength+checkOff {\n\t\t\t\t\t\t\t\t\tprevLength = length\n\t\t\t\t\t\t\t\t\tprevOffset = prevIndex - ch2\n\t\t\t\t\t\t\t\t\tprevIndex--\n\n\t\t\t\t\t\t\t\t\t// Extend back...\n\t\t\t\t\t\t\t\t\tfor i := checkOff; i >= 0; i-- {\n\t\t\t\t\t\t\t\t\t\tif prevLength >= maxMatchLength || d.window[prevIndex+i] != d.window[ch2+i-1] {\n\t\t\t\t\t\t\t\t\t\t\t// Emit tokens we \"owe\"\n\t\t\t\t\t\t\t\t\t\t\tfor j := 0; j <= i; j++ {\n\t\t\t\t\t\t\t\t\t\t\t\td.tokens.AddLiteral(d.window[prevIndex+j])\n\t\t\t\t\t\t\t\t\t\t\t\tif d.tokens.n == maxFlateBlockTokens {\n\t\t\t\t\t\t\t\t\t\t\t\t\t// The block includes the current character\n\t\t\t\t\t\t\t\t\t\t\t\t\tif d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\td.tokens.Reset()\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\ts.index++\n\t\t\t\t\t\t\t\t\t\t\t\tif s.index < s.maxInsertIndex {\n\t\t\t\t\t\t\t\t\t\t\t\t\th := hash4(d.window[s.index:])\n\t\t\t\t\t\t\t\t\t\t\t\t\tch := s.hashHead[h]\n\t\t\t\t\t\t\t\t\t\t\t\t\ts.chainHead = int(ch)\n\t\t\t\t\t\t\t\t\t\t\t\t\ts.hashPrev[s.index&windowMask] = ch\n\t\t\t\t\t\t\t\t\t\t\t\t\ts.hashHead[h] = uint32(s.index + s.hashOffset)\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\tbreak\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tprevLength++\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}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// There was a match at the previous step, and the current match is\n\t\t\t// not better. Output the previous match.\n\t\t\td.tokens.AddMatch(uint32(prevLength-3), uint32(prevOffset-minOffsetSize))\n\n\t\t\t// Insert in the hash table all strings up to the end of the match.\n\t\t\t// index and index-1 are already inserted. If there is not enough\n\t\t\t// lookahead, the last two strings are not inserted into the hash\n\t\t\t// table.\n\t\t\tnewIndex := s.index + prevLength - 1\n\t\t\t// Calculate missing hashes\n\t\t\tend := newIndex\n\t\t\tif end > s.maxInsertIndex {\n\t\t\t\tend = s.maxInsertIndex\n\t\t\t}\n\t\t\tend += minMatchLength - 1\n\t\t\tstartindex := s.index + 1\n\t\t\tif startindex > s.maxInsertIndex {\n\t\t\t\tstartindex = s.maxInsertIndex\n\t\t\t}\n\t\t\ttocheck := d.window[startindex:end]\n\t\t\tdstSize := len(tocheck) - minMatchLength + 1\n\t\t\tif dstSize > 0 {\n\t\t\t\tdst := s.hashMatch[:dstSize]\n\t\t\t\tbulkHash4(tocheck, dst)\n\t\t\t\tvar newH uint32\n\t\t\t\tfor i, val := range dst {\n\t\t\t\t\tdi := i + startindex\n\t\t\t\t\tnewH = val & hashMask\n\t\t\t\t\t// Get previous value with the same hash.\n\t\t\t\t\t// Our chain should point to the previous value.\n\t\t\t\t\ts.hashPrev[di&windowMask] = s.hashHead[newH]\n\t\t\t\t\t// Set the head of the hash chain to us.\n\t\t\t\t\ts.hashHead[newH] = uint32(di + s.hashOffset)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ts.index = newIndex\n\t\t\td.byteAvailable = false\n\t\t\ts.length = minMatchLength - 1\n\t\t\tif d.tokens.n == maxFlateBlockTokens {\n\t\t\t\t// The block includes the current character\n\t\t\t\tif d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\td.tokens.Reset()\n\t\t\t}\n\t\t\ts.ii = 0\n\t\t} else {\n\t\t\t// Reset, if we got a match this run.\n\t\t\tif s.length >= minMatchLength {\n\t\t\t\ts.ii = 0\n\t\t\t}\n\t\t\t// We have a byte waiting. Emit it.\n\t\t\tif d.byteAvailable {\n\t\t\t\ts.ii++\n\t\t\t\td.tokens.AddLiteral(d.window[s.index-1])\n\t\t\t\tif d.tokens.n == maxFlateBlockTokens {\n\t\t\t\t\tif d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\td.tokens.Reset()\n\t\t\t\t}\n\t\t\t\ts.index++\n\n\t\t\t\t// If we have a long run of no matches, skip additional bytes\n\t\t\t\t// Resets when s.ii overflows after 64KB.\n\t\t\t\tif n := int(s.ii) - d.chain; n > 0 {\n\t\t\t\t\tn = 1 + int(n>>6)\n\t\t\t\t\tfor j := 0; j < n; j++ {\n\t\t\t\t\t\tif s.index >= d.windowEnd-1 {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\td.tokens.AddLiteral(d.window[s.index-1])\n\t\t\t\t\t\tif d.tokens.n == maxFlateBlockTokens {\n\t\t\t\t\t\t\tif d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil {\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\td.tokens.Reset()\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Index...\n\t\t\t\t\t\tif s.index < s.maxInsertIndex {\n\t\t\t\t\t\t\th := hash4(d.window[s.index:])\n\t\t\t\t\t\t\tch := s.hashHead[h]\n\t\t\t\t\t\t\ts.chainHead = int(ch)\n\t\t\t\t\t\t\ts.hashPrev[s.index&windowMask] = ch\n\t\t\t\t\t\t\ts.hashHead[h] = uint32(s.index + s.hashOffset)\n\t\t\t\t\t\t}\n\t\t\t\t\t\ts.index++\n\t\t\t\t\t}\n\t\t\t\t\t// Flush last byte\n\t\t\t\t\td.tokens.AddLiteral(d.window[s.index-1])\n\t\t\t\t\td.byteAvailable = false\n\t\t\t\t\t// s.length = minMatchLength - 1 // not needed, since s.ii is reset above, so it should never be > minMatchLength\n\t\t\t\t\tif d.tokens.n == maxFlateBlockTokens {\n\t\t\t\t\t\tif d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil {\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\td.tokens.Reset()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ts.index++\n\t\t\t\td.byteAvailable = true\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (d *compressor) store() {\n\tif d.windowEnd > 0 && (d.windowEnd == maxStoreBlockSize || d.sync) {\n\t\td.err = d.writeStoredBlock(d.window[:d.windowEnd])\n\t\td.windowEnd = 0\n\t}\n}\n\n// fillWindow will fill the buffer with data for huffman-only compression.\n// The number of bytes copied is returned.\nfunc (d *compressor) fillBlock(b []byte) int {\n\tn := copy(d.window[d.windowEnd:], b)\n\td.windowEnd += n\n\treturn n\n}\n\n// storeHuff will compress and store the currently added data,\n// if enough has been accumulated or we at the end of the stream.\n// Any error that occurred will be in d.err\nfunc (d *compressor) storeHuff() {\n\tif d.windowEnd < len(d.window) && !d.sync || d.windowEnd == 0 {\n\t\treturn\n\t}\n\td.w.writeBlockHuff(false, d.window[:d.windowEnd], d.sync)\n\td.err = d.w.err\n\td.windowEnd = 0\n}\n\n// storeFast will compress and store the currently added data,\n// if enough has been accumulated or we at the end of the stream.\n// Any error that occurred will be in d.err\nfunc (d *compressor) storeFast() {\n\t// We only compress if we have maxStoreBlockSize.\n\tif d.windowEnd < len(d.window) {\n\t\tif !d.sync {\n\t\t\treturn\n\t\t}\n\t\t// Handle extremely small sizes.\n\t\tif d.windowEnd < 128 {\n\t\t\tif d.windowEnd == 0 {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif d.windowEnd <= 32 {\n\t\t\t\td.err = d.writeStoredBlock(d.window[:d.windowEnd])\n\t\t\t} else {\n\t\t\t\td.w.writeBlockHuff(false, d.window[:d.windowEnd], true)\n\t\t\t\td.err = d.w.err\n\t\t\t}\n\t\t\td.tokens.Reset()\n\t\t\td.windowEnd = 0\n\t\t\td.fast.Reset()\n\t\t\treturn\n\t\t}\n\t}\n\n\td.fast.Encode(&d.tokens, d.window[:d.windowEnd])\n\t// If we made zero matches, store the block as is.\n\tif d.tokens.n == 0 {\n\t\td.err = d.writeStoredBlock(d.window[:d.windowEnd])\n\t\t// If we removed less than 1/16th, huffman compress the block.\n\t} else if int(d.tokens.n) > d.windowEnd-(d.windowEnd>>4) {\n\t\td.w.writeBlockHuff(false, d.window[:d.windowEnd], d.sync)\n\t\td.err = d.w.err\n\t} else {\n\t\td.w.writeBlockDynamic(&d.tokens, false, d.window[:d.windowEnd], d.sync)\n\t\td.err = d.w.err\n\t}\n\td.tokens.Reset()\n\td.windowEnd = 0\n}\n\n// write will add input byte to the stream.\n// Unless an error occurs all bytes will be consumed.\nfunc (d *compressor) write(b []byte) (n int, err error) {\n\tif d.err != nil {\n\t\treturn 0, d.err\n\t}\n\tn = len(b)\n\tfor len(b) > 0 {\n\t\tif d.windowEnd == len(d.window) || d.sync {\n\t\t\td.step(d)\n\t\t}\n\t\tb = b[d.fill(d, b):]\n\t\tif d.err != nil {\n\t\t\treturn 0, d.err\n\t\t}\n\t}\n\treturn n, d.err\n}\n\nfunc (d *compressor) syncFlush() error {\n\td.sync = true\n\tif d.err != nil {\n\t\treturn d.err\n\t}\n\td.step(d)\n\tif d.err == nil {\n\t\td.w.writeStoredHeader(0, false)\n\t\td.w.flush()\n\t\td.err = d.w.err\n\t}\n\td.sync = false\n\treturn d.err\n}\n\nfunc (d *compressor) init(w io.Writer, level int) (err error) {\n\td.w = newHuffmanBitWriter(w)\n\n\tswitch {\n\tcase level == NoCompression:\n\t\td.window = make([]byte, maxStoreBlockSize)\n\t\td.fill = (*compressor).fillBlock\n\t\td.step = (*compressor).store\n\tcase level == ConstantCompression:\n\t\td.w.logNewTablePenalty = 10\n\t\td.window = make([]byte, 32<<10)\n\t\td.fill = (*compressor).fillBlock\n\t\td.step = (*compressor).storeHuff\n\tcase level == DefaultCompression:\n\t\tlevel = 5\n\t\tfallthrough\n\tcase level >= 1 && level <= 6:\n\t\td.w.logNewTablePenalty = 7\n\t\td.fast = newFastEnc(level)\n\t\td.window = make([]byte, maxStoreBlockSize)\n\t\td.fill = (*compressor).fillBlock\n\t\td.step = (*compressor).storeFast\n\tcase 7 <= level && level <= 9:\n\t\td.w.logNewTablePenalty = 8\n\t\td.state = &advancedState{}\n\t\td.compressionLevel = levels[level]\n\t\td.initDeflate()\n\t\td.fill = (*compressor).fillDeflate\n\t\td.step = (*compressor).deflateLazy\n\tcase -level >= MinCustomWindowSize && -level <= MaxCustomWindowSize:\n\t\td.w.logNewTablePenalty = 7\n\t\td.fast = &fastEncL5Window{maxOffset: int32(-level), cur: maxStoreBlockSize}\n\t\td.window = make([]byte, maxStoreBlockSize)\n\t\td.fill = (*compressor).fillBlock\n\t\td.step = (*compressor).storeFast\n\tdefault:\n\t\treturn fmt.Errorf(\"flate: invalid compression level %d: want value in range [-2, 9]\", level)\n\t}\n\td.level = level\n\treturn nil\n}\n\n// reset the state of the compressor.\nfunc (d *compressor) reset(w io.Writer) {\n\td.w.reset(w)\n\td.sync = false\n\td.err = nil\n\t// We only need to reset a few things for Snappy.\n\tif d.fast != nil {\n\t\td.fast.Reset()\n\t\td.windowEnd = 0\n\t\td.tokens.Reset()\n\t\treturn\n\t}\n\tswitch d.compressionLevel.chain {\n\tcase 0:\n\t\t// level was NoCompression or ConstantCompression.\n\t\td.windowEnd = 0\n\tdefault:\n\t\ts := d.state\n\t\ts.chainHead = -1\n\t\tfor i := range s.hashHead {\n\t\t\ts.hashHead[i] = 0\n\t\t}\n\t\tfor i := range s.hashPrev {\n\t\t\ts.hashPrev[i] = 0\n\t\t}\n\t\ts.hashOffset = 1\n\t\ts.index, d.windowEnd = 0, 0\n\t\td.blockStart, d.byteAvailable = 0, false\n\t\td.tokens.Reset()\n\t\ts.length = minMatchLength - 1\n\t\ts.offset = 0\n\t\ts.ii = 0\n\t\ts.maxInsertIndex = 0\n\t}\n}\n\nfunc (d *compressor) close() error {\n\tif d.err != nil {\n\t\treturn d.err\n\t}\n\td.sync = true\n\td.step(d)\n\tif d.err != nil {\n\t\treturn d.err\n\t}\n\tif d.w.writeStoredHeader(0, true); d.w.err != nil {\n\t\treturn d.w.err\n\t}\n\td.w.flush()\n\td.w.reset(nil)\n\treturn d.w.err\n}\n\n// NewWriter returns a new Writer compressing data at the given level.\n// Following zlib, levels range from 1 (BestSpeed) to 9 (BestCompression);\n// higher levels typically run slower but compress more.\n// Level 0 (NoCompression) does not attempt any compression; it only adds the\n// necessary DEFLATE framing.\n// Level -1 (DefaultCompression) uses the default compression level.\n// Level -2 (ConstantCompression) will use Huffman compression only, giving\n// a very fast compression for all types of input, but sacrificing considerable\n// compression efficiency.\n//\n// If level is in the range [-2, 9] then the error returned will be nil.\n// Otherwise the error returned will be non-nil.\nfunc NewWriter(w io.Writer, level int) (*Writer, error) {\n\tvar dw Writer\n\tif err := dw.d.init(w, level); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &dw, nil\n}\n\n// NewWriterDict is like NewWriter but initializes the new\n// Writer with a preset dictionary.  The returned Writer behaves\n// as if the dictionary had been written to it without producing\n// any compressed output.  The compressed data written to w\n// can only be decompressed by a Reader initialized with the\n// same dictionary.\nfunc NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error) {\n\tzw, err := NewWriter(w, level)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tzw.d.fillWindow(dict)\n\tzw.dict = append(zw.dict, dict...) // duplicate dictionary for Reset method.\n\treturn zw, err\n}\n\n// MinCustomWindowSize is the minimum window size that can be sent to NewWriterWindow.\nconst MinCustomWindowSize = 32\n\n// MaxCustomWindowSize is the maximum custom window that can be sent to NewWriterWindow.\nconst MaxCustomWindowSize = windowSize\n\n// NewWriterWindow returns a new Writer compressing data with a custom window size.\n// windowSize must be from MinCustomWindowSize to MaxCustomWindowSize.\nfunc NewWriterWindow(w io.Writer, windowSize int) (*Writer, error) {\n\tif windowSize < MinCustomWindowSize {\n\t\treturn nil, errors.New(\"flate: requested window size less than MinWindowSize\")\n\t}\n\tif windowSize > MaxCustomWindowSize {\n\t\treturn nil, errors.New(\"flate: requested window size bigger than MaxCustomWindowSize\")\n\t}\n\tvar dw Writer\n\tif err := dw.d.init(w, -windowSize); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &dw, nil\n}\n\n// A Writer takes data written to it and writes the compressed\n// form of that data to an underlying writer (see NewWriter).\ntype Writer struct {\n\td    compressor\n\tdict []byte\n}\n\n// Write writes data to w, which will eventually write the\n// compressed form of data to its underlying writer.\nfunc (w *Writer) Write(data []byte) (n int, err error) {\n\treturn w.d.write(data)\n}\n\n// Flush flushes any pending data to the underlying writer.\n// It is useful mainly in compressed network protocols, to ensure that\n// a remote reader has enough data to reconstruct a packet.\n// Flush does not return until the data has been written.\n// Calling Flush when there is no pending data still causes the Writer\n// to emit a sync marker of at least 4 bytes.\n// If the underlying writer returns an error, Flush returns that error.\n//\n// In the terminology of the zlib library, Flush is equivalent to Z_SYNC_FLUSH.\nfunc (w *Writer) Flush() error {\n\t// For more about flushing:\n\t// http://www.bolet.org/~pornin/deflate-flush.html\n\treturn w.d.syncFlush()\n}\n\n// Close flushes and closes the writer.\nfunc (w *Writer) Close() error {\n\treturn w.d.close()\n}\n\n// Reset discards the writer's state and makes it equivalent to\n// the result of NewWriter or NewWriterDict called with dst\n// and w's level and dictionary.\nfunc (w *Writer) Reset(dst io.Writer) {\n\tif len(w.dict) > 0 {\n\t\t// w was created with NewWriterDict\n\t\tw.d.reset(dst)\n\t\tif dst != nil {\n\t\t\tw.d.fillWindow(w.dict)\n\t\t}\n\t} else {\n\t\t// w was created with NewWriter\n\t\tw.d.reset(dst)\n\t}\n}\n\n// ResetDict discards the writer's state and makes it equivalent to\n// the result of NewWriter or NewWriterDict called with dst\n// and w's level, but sets a specific dictionary.\nfunc (w *Writer) ResetDict(dst io.Writer, dict []byte) {\n\tw.dict = dict\n\tw.d.reset(dst)\n\tw.d.fillWindow(w.dict)\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/dict_decoder.go",
    "content": "// Copyright 2016 The Go 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 flate\n\n// dictDecoder implements the LZ77 sliding dictionary as used in decompression.\n// LZ77 decompresses data through sequences of two forms of commands:\n//\n//   - Literal insertions: Runs of one or more symbols are inserted into the data\n//     stream as is. This is accomplished through the writeByte method for a\n//     single symbol, or combinations of writeSlice/writeMark for multiple symbols.\n//     Any valid stream must start with a literal insertion if no preset dictionary\n//     is used.\n//\n//   - Backward copies: Runs of one or more symbols are copied from previously\n//     emitted data. Backward copies come as the tuple (dist, length) where dist\n//     determines how far back in the stream to copy from and length determines how\n//     many bytes to copy. Note that it is valid for the length to be greater than\n//     the distance. Since LZ77 uses forward copies, that situation is used to\n//     perform a form of run-length encoding on repeated runs of symbols.\n//     The writeCopy and tryWriteCopy are used to implement this command.\n//\n// For performance reasons, this implementation performs little to no sanity\n// checks about the arguments. As such, the invariants documented for each\n// method call must be respected.\ntype dictDecoder struct {\n\thist []byte // Sliding window history\n\n\t// Invariant: 0 <= rdPos <= wrPos <= len(hist)\n\twrPos int  // Current output position in buffer\n\trdPos int  // Have emitted hist[:rdPos] already\n\tfull  bool // Has a full window length been written yet?\n}\n\n// init initializes dictDecoder to have a sliding window dictionary of the given\n// size. If a preset dict is provided, it will initialize the dictionary with\n// the contents of dict.\nfunc (dd *dictDecoder) init(size int, dict []byte) {\n\t*dd = dictDecoder{hist: dd.hist}\n\n\tif cap(dd.hist) < size {\n\t\tdd.hist = make([]byte, size)\n\t}\n\tdd.hist = dd.hist[:size]\n\n\tif len(dict) > len(dd.hist) {\n\t\tdict = dict[len(dict)-len(dd.hist):]\n\t}\n\tdd.wrPos = copy(dd.hist, dict)\n\tif dd.wrPos == len(dd.hist) {\n\t\tdd.wrPos = 0\n\t\tdd.full = true\n\t}\n\tdd.rdPos = dd.wrPos\n}\n\n// histSize reports the total amount of historical data in the dictionary.\nfunc (dd *dictDecoder) histSize() int {\n\tif dd.full {\n\t\treturn len(dd.hist)\n\t}\n\treturn dd.wrPos\n}\n\n// availRead reports the number of bytes that can be flushed by readFlush.\nfunc (dd *dictDecoder) availRead() int {\n\treturn dd.wrPos - dd.rdPos\n}\n\n// availWrite reports the available amount of output buffer space.\nfunc (dd *dictDecoder) availWrite() int {\n\treturn len(dd.hist) - dd.wrPos\n}\n\n// writeSlice returns a slice of the available buffer to write data to.\n//\n// This invariant will be kept: len(s) <= availWrite()\nfunc (dd *dictDecoder) writeSlice() []byte {\n\treturn dd.hist[dd.wrPos:]\n}\n\n// writeMark advances the writer pointer by cnt.\n//\n// This invariant must be kept: 0 <= cnt <= availWrite()\nfunc (dd *dictDecoder) writeMark(cnt int) {\n\tdd.wrPos += cnt\n}\n\n// writeByte writes a single byte to the dictionary.\n//\n// This invariant must be kept: 0 < availWrite()\nfunc (dd *dictDecoder) writeByte(c byte) {\n\tdd.hist[dd.wrPos] = c\n\tdd.wrPos++\n}\n\n// writeCopy copies a string at a given (dist, length) to the output.\n// This returns the number of bytes copied and may be less than the requested\n// length if the available space in the output buffer is too small.\n//\n// This invariant must be kept: 0 < dist <= histSize()\nfunc (dd *dictDecoder) writeCopy(dist, length int) int {\n\tdstBase := dd.wrPos\n\tdstPos := dstBase\n\tsrcPos := dstPos - dist\n\tendPos := dstPos + length\n\tif endPos > len(dd.hist) {\n\t\tendPos = len(dd.hist)\n\t}\n\n\t// Copy non-overlapping section after destination position.\n\t//\n\t// This section is non-overlapping in that the copy length for this section\n\t// is always less than or equal to the backwards distance. This can occur\n\t// if a distance refers to data that wraps-around in the buffer.\n\t// Thus, a backwards copy is performed here; that is, the exact bytes in\n\t// the source prior to the copy is placed in the destination.\n\tif srcPos < 0 {\n\t\tsrcPos += len(dd.hist)\n\t\tdstPos += copy(dd.hist[dstPos:endPos], dd.hist[srcPos:])\n\t\tsrcPos = 0\n\t}\n\n\t// Copy possibly overlapping section before destination position.\n\t//\n\t// This section can overlap if the copy length for this section is larger\n\t// than the backwards distance. This is allowed by LZ77 so that repeated\n\t// strings can be succinctly represented using (dist, length) pairs.\n\t// Thus, a forwards copy is performed here; that is, the bytes copied is\n\t// possibly dependent on the resulting bytes in the destination as the copy\n\t// progresses along. This is functionally equivalent to the following:\n\t//\n\t//\tfor i := 0; i < endPos-dstPos; i++ {\n\t//\t\tdd.hist[dstPos+i] = dd.hist[srcPos+i]\n\t//\t}\n\t//\tdstPos = endPos\n\t//\n\tfor dstPos < endPos {\n\t\tdstPos += copy(dd.hist[dstPos:endPos], dd.hist[srcPos:dstPos])\n\t}\n\n\tdd.wrPos = dstPos\n\treturn dstPos - dstBase\n}\n\n// tryWriteCopy tries to copy a string at a given (distance, length) to the\n// output. This specialized version is optimized for short distances.\n//\n// This method is designed to be inlined for performance reasons.\n//\n// This invariant must be kept: 0 < dist <= histSize()\nfunc (dd *dictDecoder) tryWriteCopy(dist, length int) int {\n\tdstPos := dd.wrPos\n\tendPos := dstPos + length\n\tif dstPos < dist || endPos > len(dd.hist) {\n\t\treturn 0\n\t}\n\tdstBase := dstPos\n\tsrcPos := dstPos - dist\n\n\t// Copy possibly overlapping section before destination position.\nloop:\n\tdstPos += copy(dd.hist[dstPos:endPos], dd.hist[srcPos:dstPos])\n\tif dstPos < endPos {\n\t\tgoto loop // Avoid for-loop so that this function can be inlined\n\t}\n\n\tdd.wrPos = dstPos\n\treturn dstPos - dstBase\n}\n\n// readFlush returns a slice of the historical buffer that is ready to be\n// emitted to the user. The data returned by readFlush must be fully consumed\n// before calling any other dictDecoder methods.\nfunc (dd *dictDecoder) readFlush() []byte {\n\ttoRead := dd.hist[dd.rdPos:dd.wrPos]\n\tdd.rdPos = dd.wrPos\n\tif dd.wrPos == len(dd.hist) {\n\t\tdd.wrPos, dd.rdPos = 0, 0\n\t\tdd.full = true\n\t}\n\treturn toRead\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/fast_encoder.go",
    "content": "// Copyright 2011 The Snappy-Go Authors. All rights reserved.\n// Modified for deflate by Klaus Post (c) 2015.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage flate\n\nimport (\n\t\"fmt\"\n\t\"math/bits\"\n\n\t\"github.com/klauspost/compress/internal/le\"\n)\n\ntype fastEnc interface {\n\tEncode(dst *tokens, src []byte)\n\tReset()\n}\n\nfunc newFastEnc(level int) fastEnc {\n\tswitch level {\n\tcase 1:\n\t\treturn &fastEncL1{fastGen: fastGen{cur: maxStoreBlockSize}}\n\tcase 2:\n\t\treturn &fastEncL2{fastGen: fastGen{cur: maxStoreBlockSize}}\n\tcase 3:\n\t\treturn &fastEncL3{fastGen: fastGen{cur: maxStoreBlockSize}}\n\tcase 4:\n\t\treturn &fastEncL4{fastGen: fastGen{cur: maxStoreBlockSize}}\n\tcase 5:\n\t\treturn &fastEncL5{fastGen: fastGen{cur: maxStoreBlockSize}}\n\tcase 6:\n\t\treturn &fastEncL6{fastGen: fastGen{cur: maxStoreBlockSize}}\n\tdefault:\n\t\tpanic(\"invalid level specified\")\n\t}\n}\n\nconst (\n\ttableBits       = 15             // Bits used in the table\n\ttableSize       = 1 << tableBits // Size of the table\n\ttableShift      = 32 - tableBits // Right-shift to get the tableBits most significant bits of a uint32.\n\tbaseMatchOffset = 1              // The smallest match offset\n\tbaseMatchLength = 3              // The smallest match length per the RFC section 3.2.5\n\tmaxMatchOffset  = 1 << 15        // The largest match offset\n\n\tbTableBits   = 17                                               // Bits used in the big tables\n\tbTableSize   = 1 << bTableBits                                  // Size of the table\n\tallocHistory = maxStoreBlockSize * 5                            // Size to preallocate for history.\n\tbufferReset  = (1 << 31) - allocHistory - maxStoreBlockSize - 1 // Reset the buffer offset when reaching this.\n)\n\nconst (\n\tprime3bytes = 506832829\n\tprime4bytes = 2654435761\n\tprime5bytes = 889523592379\n\tprime6bytes = 227718039650203\n\tprime7bytes = 58295818150454627\n\tprime8bytes = 0xcf1bbcdcb7a56463\n)\n\nfunc load3232(b []byte, i int32) uint32 {\n\treturn le.Load32(b, i)\n}\n\nfunc load6432(b []byte, i int32) uint64 {\n\treturn le.Load64(b, i)\n}\n\ntype tableEntry struct {\n\toffset int32\n}\n\n// fastGen maintains the table for matches,\n// and the previous byte block for level 2.\n// This is the generic implementation.\ntype fastGen struct {\n\thist []byte\n\tcur  int32\n}\n\nfunc (e *fastGen) addBlock(src []byte) int32 {\n\t// check if we have space already\n\tif len(e.hist)+len(src) > cap(e.hist) {\n\t\tif cap(e.hist) == 0 {\n\t\t\te.hist = make([]byte, 0, allocHistory)\n\t\t} else {\n\t\t\tif cap(e.hist) < maxMatchOffset*2 {\n\t\t\t\tpanic(\"unexpected buffer size\")\n\t\t\t}\n\t\t\t// Move down\n\t\t\toffset := int32(len(e.hist)) - maxMatchOffset\n\t\t\t// copy(e.hist[0:maxMatchOffset], e.hist[offset:])\n\t\t\t*(*[maxMatchOffset]byte)(e.hist) = *(*[maxMatchOffset]byte)(e.hist[offset:])\n\t\t\te.cur += offset\n\t\t\te.hist = e.hist[:maxMatchOffset]\n\t\t}\n\t}\n\ts := int32(len(e.hist))\n\te.hist = append(e.hist, src...)\n\treturn s\n}\n\ntype tableEntryPrev struct {\n\tCur  tableEntry\n\tPrev tableEntry\n}\n\n// hash7 returns the hash of the lowest 7 bytes of u to fit in a hash table with h bits.\n// Preferably h should be a constant and should always be <64.\nfunc hash7(u uint64, h uint8) uint32 {\n\treturn uint32(((u << (64 - 56)) * prime7bytes) >> ((64 - h) & reg8SizeMask64))\n}\n\n// hashLen returns a hash of the lowest mls bytes of with length output bits.\n// mls must be >=3 and <=8. Any other value will return hash for 4 bytes.\n// length should always be < 32.\n// Preferably length and mls should be a constant for inlining.\nfunc hashLen(u uint64, length, mls uint8) uint32 {\n\tswitch mls {\n\tcase 3:\n\t\treturn (uint32(u<<8) * prime3bytes) >> (32 - length)\n\tcase 5:\n\t\treturn uint32(((u << (64 - 40)) * prime5bytes) >> (64 - length))\n\tcase 6:\n\t\treturn uint32(((u << (64 - 48)) * prime6bytes) >> (64 - length))\n\tcase 7:\n\t\treturn uint32(((u << (64 - 56)) * prime7bytes) >> (64 - length))\n\tcase 8:\n\t\treturn uint32((u * prime8bytes) >> (64 - length))\n\tdefault:\n\t\treturn (uint32(u) * prime4bytes) >> (32 - length)\n\t}\n}\n\n// matchlen will return the match length between offsets and t in src.\n// The maximum length returned is maxMatchLength - 4.\n// It is assumed that s > t, that t >=0 and s < len(src).\nfunc (e *fastGen) matchlen(s, t int, src []byte) int32 {\n\tif debugDeflate {\n\t\tif t >= s {\n\t\t\tpanic(fmt.Sprint(\"t >=s:\", t, s))\n\t\t}\n\t\tif int(s) >= len(src) {\n\t\t\tpanic(fmt.Sprint(\"s >= len(src):\", s, len(src)))\n\t\t}\n\t\tif t < 0 {\n\t\t\tpanic(fmt.Sprint(\"t < 0:\", t))\n\t\t}\n\t\tif s-t > maxMatchOffset {\n\t\t\tpanic(fmt.Sprint(s, \"-\", t, \"(\", s-t, \") > maxMatchLength (\", maxMatchOffset, \")\"))\n\t\t}\n\t}\n\ts1 := min(s+maxMatchLength-4, len(src))\n\tleft := s1 - s\n\tn := int32(0)\n\tfor left >= 8 {\n\t\tdiff := le.Load64(src, s) ^ le.Load64(src, t)\n\t\tif diff != 0 {\n\t\t\treturn n + int32(bits.TrailingZeros64(diff)>>3)\n\t\t}\n\t\ts += 8\n\t\tt += 8\n\t\tn += 8\n\t\tleft -= 8\n\t}\n\n\ta := src[s:s1]\n\tb := src[t:]\n\tfor i := range a {\n\t\tif a[i] != b[i] {\n\t\t\tbreak\n\t\t}\n\t\tn++\n\t}\n\treturn n\n}\n\n// matchlenLong will return the match length between offsets and t in src.\n// It is assumed that s > t, that t >=0 and s < len(src).\nfunc (e *fastGen) matchlenLong(s, t int, src []byte) int32 {\n\tif debugDeflate {\n\t\tif t >= s {\n\t\t\tpanic(fmt.Sprint(\"t >=s:\", t, s))\n\t\t}\n\t\tif int(s) >= len(src) {\n\t\t\tpanic(fmt.Sprint(\"s >= len(src):\", s, len(src)))\n\t\t}\n\t\tif t < 0 {\n\t\t\tpanic(fmt.Sprint(\"t < 0:\", t))\n\t\t}\n\t\tif s-t > maxMatchOffset {\n\t\t\tpanic(fmt.Sprint(s, \"-\", t, \"(\", s-t, \") > maxMatchLength (\", maxMatchOffset, \")\"))\n\t\t}\n\t}\n\t// Extend the match to be as long as possible.\n\tleft := len(src) - s\n\tn := int32(0)\n\tfor left >= 8 {\n\t\tdiff := le.Load64(src, s) ^ le.Load64(src, t)\n\t\tif diff != 0 {\n\t\t\treturn n + int32(bits.TrailingZeros64(diff)>>3)\n\t\t}\n\t\ts += 8\n\t\tt += 8\n\t\tn += 8\n\t\tleft -= 8\n\t}\n\n\ta := src[s:]\n\tb := src[t:]\n\tfor i := range a {\n\t\tif a[i] != b[i] {\n\t\t\tbreak\n\t\t}\n\t\tn++\n\t}\n\treturn n\n}\n\n// Reset the encoding table.\nfunc (e *fastGen) Reset() {\n\tif cap(e.hist) < allocHistory {\n\t\te.hist = make([]byte, 0, allocHistory)\n\t}\n\t// We offset current position so everything will be out of reach.\n\t// If we are above the buffer reset it will be cleared anyway since len(hist) == 0.\n\tif e.cur <= bufferReset {\n\t\te.cur += maxMatchOffset + int32(len(e.hist))\n\t}\n\te.hist = e.hist[:0]\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go",
    "content": "// Copyright 2009 The Go 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 flate\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\n\t\"github.com/klauspost/compress/internal/le\"\n)\n\nconst (\n\t// The largest offset code.\n\toffsetCodeCount = 30\n\n\t// The special code used to mark the end of a block.\n\tendBlockMarker = 256\n\n\t// The first length code.\n\tlengthCodesStart = 257\n\n\t// The number of codegen codes.\n\tcodegenCodeCount = 19\n\tbadCode          = 255\n\n\t// maxPredefinedTokens is the maximum number of tokens\n\t// where we check if fixed size is smaller.\n\tmaxPredefinedTokens = 250\n\n\t// bufferFlushSize indicates the buffer size\n\t// after which bytes are flushed to the writer.\n\t// Should preferably be a multiple of 6, since\n\t// we accumulate 6 bytes between writes to the buffer.\n\tbufferFlushSize = 246\n)\n\n// Minimum length code that emits bits.\nconst lengthExtraBitsMinCode = 8\n\n// The number of extra bits needed by length code X - LENGTH_CODES_START.\nvar lengthExtraBits = [32]uint8{\n\t/* 257 */ 0, 0, 0,\n\t/* 260 */ 0, 0, 0, 0, 0, 1, 1, 1, 1, 2,\n\t/* 270 */ 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,\n\t/* 280 */ 4, 5, 5, 5, 5, 0,\n}\n\n// The length indicated by length code X - LENGTH_CODES_START.\nvar lengthBase = [32]uint8{\n\t0, 1, 2, 3, 4, 5, 6, 7, 8, 10,\n\t12, 14, 16, 20, 24, 28, 32, 40, 48, 56,\n\t64, 80, 96, 112, 128, 160, 192, 224, 255,\n}\n\n// Minimum offset code that emits bits.\nconst offsetExtraBitsMinCode = 4\n\n// offset code word extra bits.\nvar offsetExtraBits = [32]int8{\n\t0, 0, 0, 0, 1, 1, 2, 2, 3, 3,\n\t4, 4, 5, 5, 6, 6, 7, 7, 8, 8,\n\t9, 9, 10, 10, 11, 11, 12, 12, 13, 13,\n\t/* extended window */\n\t14, 14,\n}\n\nvar offsetCombined = [32]uint32{}\n\nfunc init() {\n\tvar offsetBase = [32]uint32{\n\t\t/* normal deflate */\n\t\t0x000000, 0x000001, 0x000002, 0x000003, 0x000004,\n\t\t0x000006, 0x000008, 0x00000c, 0x000010, 0x000018,\n\t\t0x000020, 0x000030, 0x000040, 0x000060, 0x000080,\n\t\t0x0000c0, 0x000100, 0x000180, 0x000200, 0x000300,\n\t\t0x000400, 0x000600, 0x000800, 0x000c00, 0x001000,\n\t\t0x001800, 0x002000, 0x003000, 0x004000, 0x006000,\n\n\t\t/* extended window */\n\t\t0x008000, 0x00c000,\n\t}\n\n\tfor i := range offsetCombined[:] {\n\t\t// Don't use extended window values...\n\t\tif offsetExtraBits[i] == 0 || offsetBase[i] > 0x006000 {\n\t\t\tcontinue\n\t\t}\n\t\toffsetCombined[i] = uint32(offsetExtraBits[i]) | (offsetBase[i] << 8)\n\t}\n}\n\n// The odd order in which the codegen code sizes are written.\nvar codegenOrder = []uint32{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}\n\ntype huffmanBitWriter struct {\n\t// writer is the underlying writer.\n\t// Do not use it directly; use the write method, which ensures\n\t// that Write errors are sticky.\n\twriter io.Writer\n\n\t// Data waiting to be written is bytes[0:nbytes]\n\t// and then the low nbits of bits.\n\tbits            uint64\n\tnbits           uint8\n\tnbytes          uint8\n\tlastHuffMan     bool\n\tliteralEncoding *huffmanEncoder\n\ttmpLitEncoding  *huffmanEncoder\n\toffsetEncoding  *huffmanEncoder\n\tcodegenEncoding *huffmanEncoder\n\terr             error\n\tlastHeader      int\n\t// Set between 0 (reused block can be up to 2x the size)\n\tlogNewTablePenalty uint\n\tbytes              [256 + 8]byte\n\tliteralFreq        [lengthCodesStart + 32]uint16\n\toffsetFreq         [32]uint16\n\tcodegenFreq        [codegenCodeCount]uint16\n\n\t// codegen must have an extra space for the final symbol.\n\tcodegen [literalCount + offsetCodeCount + 1]uint8\n}\n\n// Huffman reuse.\n//\n// The huffmanBitWriter supports reusing huffman tables and thereby combining block sections.\n//\n// This is controlled by several variables:\n//\n// If lastHeader is non-zero the Huffman table can be reused.\n// This also indicates that a Huffman table has been generated that can output all\n// possible symbols.\n// It also indicates that an EOB has not yet been emitted, so if a new tabel is generated\n// an EOB with the previous table must be written.\n//\n// If lastHuffMan is set, a table for outputting literals has been generated and offsets are invalid.\n//\n// An incoming block estimates the output size of a new table using a 'fresh' by calculating the\n// optimal size and adding a penalty in 'logNewTablePenalty'.\n// A Huffman table is not optimal, which is why we add a penalty, and generating a new table\n// is slower both for compression and decompression.\n\nfunc newHuffmanBitWriter(w io.Writer) *huffmanBitWriter {\n\treturn &huffmanBitWriter{\n\t\twriter:          w,\n\t\tliteralEncoding: newHuffmanEncoder(literalCount),\n\t\ttmpLitEncoding:  newHuffmanEncoder(literalCount),\n\t\tcodegenEncoding: newHuffmanEncoder(codegenCodeCount),\n\t\toffsetEncoding:  newHuffmanEncoder(offsetCodeCount),\n\t}\n}\n\nfunc (w *huffmanBitWriter) reset(writer io.Writer) {\n\tw.writer = writer\n\tw.bits, w.nbits, w.nbytes, w.err = 0, 0, 0, nil\n\tw.lastHeader = 0\n\tw.lastHuffMan = false\n}\n\nfunc (w *huffmanBitWriter) canReuse(t *tokens) (ok bool) {\n\ta := t.offHist[:offsetCodeCount]\n\tb := w.offsetEncoding.codes\n\tb = b[:len(a)]\n\tfor i, v := range a {\n\t\tif v != 0 && b[i].zero() {\n\t\t\treturn false\n\t\t}\n\t}\n\n\ta = t.extraHist[:literalCount-256]\n\tb = w.literalEncoding.codes[256:literalCount]\n\tb = b[:len(a)]\n\tfor i, v := range a {\n\t\tif v != 0 && b[i].zero() {\n\t\t\treturn false\n\t\t}\n\t}\n\n\ta = t.litHist[:256]\n\tb = w.literalEncoding.codes[:len(a)]\n\tfor i, v := range a {\n\t\tif v != 0 && b[i].zero() {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (w *huffmanBitWriter) flush() {\n\tif w.err != nil {\n\t\tw.nbits = 0\n\t\treturn\n\t}\n\tif w.lastHeader > 0 {\n\t\t// We owe an EOB\n\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\tw.lastHeader = 0\n\t}\n\tn := w.nbytes\n\tfor w.nbits != 0 {\n\t\tw.bytes[n] = byte(w.bits)\n\t\tw.bits >>= 8\n\t\tif w.nbits > 8 { // Avoid underflow\n\t\t\tw.nbits -= 8\n\t\t} else {\n\t\t\tw.nbits = 0\n\t\t}\n\t\tn++\n\t}\n\tw.bits = 0\n\tw.write(w.bytes[:n])\n\tw.nbytes = 0\n}\n\nfunc (w *huffmanBitWriter) write(b []byte) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\t_, w.err = w.writer.Write(b)\n}\n\nfunc (w *huffmanBitWriter) writeBits(b int32, nb uint8) {\n\tw.bits |= uint64(b) << (w.nbits & 63)\n\tw.nbits += nb\n\tif w.nbits >= 48 {\n\t\tw.writeOutBits()\n\t}\n}\n\nfunc (w *huffmanBitWriter) writeBytes(bytes []byte) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\tn := w.nbytes\n\tif w.nbits&7 != 0 {\n\t\tw.err = InternalError(\"writeBytes with unfinished bits\")\n\t\treturn\n\t}\n\tfor w.nbits != 0 {\n\t\tw.bytes[n] = byte(w.bits)\n\t\tw.bits >>= 8\n\t\tw.nbits -= 8\n\t\tn++\n\t}\n\tif n != 0 {\n\t\tw.write(w.bytes[:n])\n\t}\n\tw.nbytes = 0\n\tw.write(bytes)\n}\n\n// RFC 1951 3.2.7 specifies a special run-length encoding for specifying\n// the literal and offset lengths arrays (which are concatenated into a single\n// array).  This method generates that run-length encoding.\n//\n// The result is written into the codegen array, and the frequencies\n// of each code is written into the codegenFreq array.\n// Codes 0-15 are single byte codes. Codes 16-18 are followed by additional\n// information. Code badCode is an end marker\n//\n//\tnumLiterals      The number of literals in literalEncoding\n//\tnumOffsets       The number of offsets in offsetEncoding\n//\tlitenc, offenc   The literal and offset encoder to use\nfunc (w *huffmanBitWriter) generateCodegen(numLiterals int, numOffsets int, litEnc, offEnc *huffmanEncoder) {\n\tfor i := range w.codegenFreq {\n\t\tw.codegenFreq[i] = 0\n\t}\n\t// Note that we are using codegen both as a temporary variable for holding\n\t// a copy of the frequencies, and as the place where we put the result.\n\t// This is fine because the output is always shorter than the input used\n\t// so far.\n\tcodegen := w.codegen[:] // cache\n\t// Copy the concatenated code sizes to codegen. Put a marker at the end.\n\tcgnl := codegen[:numLiterals]\n\tfor i := range cgnl {\n\t\tcgnl[i] = litEnc.codes[i].len()\n\t}\n\n\tcgnl = codegen[numLiterals : numLiterals+numOffsets]\n\tfor i := range cgnl {\n\t\tcgnl[i] = offEnc.codes[i].len()\n\t}\n\tcodegen[numLiterals+numOffsets] = badCode\n\n\tsize := codegen[0]\n\tcount := 1\n\toutIndex := 0\n\tfor inIndex := 1; size != badCode; inIndex++ {\n\t\t// INVARIANT: We have seen \"count\" copies of size that have not yet\n\t\t// had output generated for them.\n\t\tnextSize := codegen[inIndex]\n\t\tif nextSize == size {\n\t\t\tcount++\n\t\t\tcontinue\n\t\t}\n\t\t// We need to generate codegen indicating \"count\" of size.\n\t\tif size != 0 {\n\t\t\tcodegen[outIndex] = size\n\t\t\toutIndex++\n\t\t\tw.codegenFreq[size]++\n\t\t\tcount--\n\t\t\tfor count >= 3 {\n\t\t\t\tn := 6\n\t\t\t\tif n > count {\n\t\t\t\t\tn = count\n\t\t\t\t}\n\t\t\t\tcodegen[outIndex] = 16\n\t\t\t\toutIndex++\n\t\t\t\tcodegen[outIndex] = uint8(n - 3)\n\t\t\t\toutIndex++\n\t\t\t\tw.codegenFreq[16]++\n\t\t\t\tcount -= n\n\t\t\t}\n\t\t} else {\n\t\t\tfor count >= 11 {\n\t\t\t\tn := 138\n\t\t\t\tif n > count {\n\t\t\t\t\tn = count\n\t\t\t\t}\n\t\t\t\tcodegen[outIndex] = 18\n\t\t\t\toutIndex++\n\t\t\t\tcodegen[outIndex] = uint8(n - 11)\n\t\t\t\toutIndex++\n\t\t\t\tw.codegenFreq[18]++\n\t\t\t\tcount -= n\n\t\t\t}\n\t\t\tif count >= 3 {\n\t\t\t\t// count >= 3 && count <= 10\n\t\t\t\tcodegen[outIndex] = 17\n\t\t\t\toutIndex++\n\t\t\t\tcodegen[outIndex] = uint8(count - 3)\n\t\t\t\toutIndex++\n\t\t\t\tw.codegenFreq[17]++\n\t\t\t\tcount = 0\n\t\t\t}\n\t\t}\n\t\tcount--\n\t\tfor ; count >= 0; count-- {\n\t\t\tcodegen[outIndex] = size\n\t\t\toutIndex++\n\t\t\tw.codegenFreq[size]++\n\t\t}\n\t\t// Set up invariant for next time through the loop.\n\t\tsize = nextSize\n\t\tcount = 1\n\t}\n\t// Marker indicating the end of the codegen.\n\tcodegen[outIndex] = badCode\n}\n\nfunc (w *huffmanBitWriter) codegens() int {\n\tnumCodegens := len(w.codegenFreq)\n\tfor numCodegens > 4 && w.codegenFreq[codegenOrder[numCodegens-1]] == 0 {\n\t\tnumCodegens--\n\t}\n\treturn numCodegens\n}\n\nfunc (w *huffmanBitWriter) headerSize() (size, numCodegens int) {\n\tnumCodegens = len(w.codegenFreq)\n\tfor numCodegens > 4 && w.codegenFreq[codegenOrder[numCodegens-1]] == 0 {\n\t\tnumCodegens--\n\t}\n\treturn 3 + 5 + 5 + 4 + (3 * numCodegens) +\n\t\tw.codegenEncoding.bitLength(w.codegenFreq[:]) +\n\t\tint(w.codegenFreq[16])*2 +\n\t\tint(w.codegenFreq[17])*3 +\n\t\tint(w.codegenFreq[18])*7, numCodegens\n}\n\n// dynamicSize returns the size of dynamically encoded data in bits.\nfunc (w *huffmanBitWriter) dynamicReuseSize(litEnc, offEnc *huffmanEncoder) (size int) {\n\tsize = litEnc.bitLength(w.literalFreq[:]) +\n\t\toffEnc.bitLength(w.offsetFreq[:])\n\treturn size\n}\n\n// dynamicSize returns the size of dynamically encoded data in bits.\nfunc (w *huffmanBitWriter) dynamicSize(litEnc, offEnc *huffmanEncoder, extraBits int) (size, numCodegens int) {\n\theader, numCodegens := w.headerSize()\n\tsize = header +\n\t\tlitEnc.bitLength(w.literalFreq[:]) +\n\t\toffEnc.bitLength(w.offsetFreq[:]) +\n\t\textraBits\n\treturn size, numCodegens\n}\n\n// extraBitSize will return the number of bits that will be written\n// as \"extra\" bits on matches.\nfunc (w *huffmanBitWriter) extraBitSize() int {\n\ttotal := 0\n\tfor i, n := range w.literalFreq[257:literalCount] {\n\t\ttotal += int(n) * int(lengthExtraBits[i&31])\n\t}\n\tfor i, n := range w.offsetFreq[:offsetCodeCount] {\n\t\ttotal += int(n) * int(offsetExtraBits[i&31])\n\t}\n\treturn total\n}\n\n// fixedSize returns the size of dynamically encoded data in bits.\nfunc (w *huffmanBitWriter) fixedSize(extraBits int) int {\n\treturn 3 +\n\t\tfixedLiteralEncoding.bitLength(w.literalFreq[:]) +\n\t\tfixedOffsetEncoding.bitLength(w.offsetFreq[:]) +\n\t\textraBits\n}\n\n// storedSize calculates the stored size, including header.\n// The function returns the size in bits and whether the block\n// fits inside a single block.\nfunc (w *huffmanBitWriter) storedSize(in []byte) (int, bool) {\n\tif in == nil {\n\t\treturn 0, false\n\t}\n\tif len(in) <= maxStoreBlockSize {\n\t\treturn (len(in) + 5) * 8, true\n\t}\n\treturn 0, false\n}\n\nfunc (w *huffmanBitWriter) writeCode(c hcode) {\n\t// The function does not get inlined if we \"& 63\" the shift.\n\tw.bits |= c.code64() << (w.nbits & 63)\n\tw.nbits += c.len()\n\tif w.nbits >= 48 {\n\t\tw.writeOutBits()\n\t}\n}\n\n// writeOutBits will write bits to the buffer.\nfunc (w *huffmanBitWriter) writeOutBits() {\n\tbits := w.bits\n\tw.bits >>= 48\n\tw.nbits -= 48\n\tn := w.nbytes\n\n\t// We over-write, but faster...\n\tle.Store64(w.bytes[n:], bits)\n\tn += 6\n\n\tif n >= bufferFlushSize {\n\t\tif w.err != nil {\n\t\t\tn = 0\n\t\t\treturn\n\t\t}\n\t\tw.write(w.bytes[:n])\n\t\tn = 0\n\t}\n\n\tw.nbytes = n\n}\n\n// Write the header of a dynamic Huffman block to the output stream.\n//\n//\tnumLiterals  The number of literals specified in codegen\n//\tnumOffsets   The number of offsets specified in codegen\n//\tnumCodegens  The number of codegens used in codegen\nfunc (w *huffmanBitWriter) writeDynamicHeader(numLiterals int, numOffsets int, numCodegens int, isEof bool) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\tvar firstBits int32 = 4\n\tif isEof {\n\t\tfirstBits = 5\n\t}\n\tw.writeBits(firstBits, 3)\n\tw.writeBits(int32(numLiterals-257), 5)\n\tw.writeBits(int32(numOffsets-1), 5)\n\tw.writeBits(int32(numCodegens-4), 4)\n\n\tfor i := 0; i < numCodegens; i++ {\n\t\tvalue := uint(w.codegenEncoding.codes[codegenOrder[i]].len())\n\t\tw.writeBits(int32(value), 3)\n\t}\n\n\ti := 0\n\tfor {\n\t\tvar codeWord = uint32(w.codegen[i])\n\t\ti++\n\t\tif codeWord == badCode {\n\t\t\tbreak\n\t\t}\n\t\tw.writeCode(w.codegenEncoding.codes[codeWord])\n\n\t\tswitch codeWord {\n\t\tcase 16:\n\t\t\tw.writeBits(int32(w.codegen[i]), 2)\n\t\t\ti++\n\t\tcase 17:\n\t\t\tw.writeBits(int32(w.codegen[i]), 3)\n\t\t\ti++\n\t\tcase 18:\n\t\t\tw.writeBits(int32(w.codegen[i]), 7)\n\t\t\ti++\n\t\t}\n\t}\n}\n\n// writeStoredHeader will write a stored header.\n// If the stored block is only used for EOF,\n// it is replaced with a fixed huffman block.\nfunc (w *huffmanBitWriter) writeStoredHeader(length int, isEof bool) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\tif w.lastHeader > 0 {\n\t\t// We owe an EOB\n\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\tw.lastHeader = 0\n\t}\n\n\t// To write EOF, use a fixed encoding block. 10 bits instead of 5 bytes.\n\tif length == 0 && isEof {\n\t\tw.writeFixedHeader(isEof)\n\t\t// EOB: 7 bits, value: 0\n\t\tw.writeBits(0, 7)\n\t\tw.flush()\n\t\treturn\n\t}\n\n\tvar flag int32\n\tif isEof {\n\t\tflag = 1\n\t}\n\tw.writeBits(flag, 3)\n\tw.flush()\n\tw.writeBits(int32(length), 16)\n\tw.writeBits(int32(^uint16(length)), 16)\n}\n\nfunc (w *huffmanBitWriter) writeFixedHeader(isEof bool) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\tif w.lastHeader > 0 {\n\t\t// We owe an EOB\n\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\tw.lastHeader = 0\n\t}\n\n\t// Indicate that we are a fixed Huffman block\n\tvar value int32 = 2\n\tif isEof {\n\t\tvalue = 3\n\t}\n\tw.writeBits(value, 3)\n}\n\n// writeBlock will write a block of tokens with the smallest encoding.\n// The original input can be supplied, and if the huffman encoded data\n// is larger than the original bytes, the data will be written as a\n// stored block.\n// If the input is nil, the tokens will always be Huffman encoded.\nfunc (w *huffmanBitWriter) writeBlock(tokens *tokens, eof bool, input []byte) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\n\ttokens.AddEOB()\n\tif w.lastHeader > 0 {\n\t\t// We owe an EOB\n\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\tw.lastHeader = 0\n\t}\n\tnumLiterals, numOffsets := w.indexTokens(tokens, false)\n\tw.generate()\n\tvar extraBits int\n\tstoredSize, storable := w.storedSize(input)\n\tif storable {\n\t\textraBits = w.extraBitSize()\n\t}\n\n\t// Figure out smallest code.\n\t// Fixed Huffman baseline.\n\tvar literalEncoding = fixedLiteralEncoding\n\tvar offsetEncoding = fixedOffsetEncoding\n\tvar size = math.MaxInt32\n\tif tokens.n < maxPredefinedTokens {\n\t\tsize = w.fixedSize(extraBits)\n\t}\n\n\t// Dynamic Huffman?\n\tvar numCodegens int\n\n\t// Generate codegen and codegenFrequencies, which indicates how to encode\n\t// the literalEncoding and the offsetEncoding.\n\tw.generateCodegen(numLiterals, numOffsets, w.literalEncoding, w.offsetEncoding)\n\tw.codegenEncoding.generate(w.codegenFreq[:], 7)\n\tdynamicSize, numCodegens := w.dynamicSize(w.literalEncoding, w.offsetEncoding, extraBits)\n\n\tif dynamicSize < size {\n\t\tsize = dynamicSize\n\t\tliteralEncoding = w.literalEncoding\n\t\toffsetEncoding = w.offsetEncoding\n\t}\n\n\t// Stored bytes?\n\tif storable && storedSize <= size {\n\t\tw.writeStoredHeader(len(input), eof)\n\t\tw.writeBytes(input)\n\t\treturn\n\t}\n\n\t// Huffman.\n\tif literalEncoding == fixedLiteralEncoding {\n\t\tw.writeFixedHeader(eof)\n\t} else {\n\t\tw.writeDynamicHeader(numLiterals, numOffsets, numCodegens, eof)\n\t}\n\n\t// Write the tokens.\n\tw.writeTokens(tokens.Slice(), literalEncoding.codes, offsetEncoding.codes)\n}\n\n// writeBlockDynamic encodes a block using a dynamic Huffman table.\n// This should be used if the symbols used have a disproportionate\n// histogram distribution.\n// If input is supplied and the compression savings are below 1/16th of the\n// input size the block is stored.\nfunc (w *huffmanBitWriter) writeBlockDynamic(tokens *tokens, eof bool, input []byte, sync bool) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\n\tsync = sync || eof\n\tif sync {\n\t\ttokens.AddEOB()\n\t}\n\n\t// We cannot reuse pure huffman table, and must mark as EOF.\n\tif (w.lastHuffMan || eof) && w.lastHeader > 0 {\n\t\t// We will not try to reuse.\n\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\tw.lastHeader = 0\n\t\tw.lastHuffMan = false\n\t}\n\n\t// fillReuse enables filling of empty values.\n\t// This will make encodings always reusable without testing.\n\t// However, this does not appear to benefit on most cases.\n\tconst fillReuse = false\n\n\t// Check if we can reuse...\n\tif !fillReuse && w.lastHeader > 0 && !w.canReuse(tokens) {\n\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\tw.lastHeader = 0\n\t}\n\n\tnumLiterals, numOffsets := w.indexTokens(tokens, !sync)\n\textraBits := 0\n\tssize, storable := w.storedSize(input)\n\n\tconst usePrefs = true\n\tif storable || w.lastHeader > 0 {\n\t\textraBits = w.extraBitSize()\n\t}\n\n\tvar size int\n\n\t// Check if we should reuse.\n\tif w.lastHeader > 0 {\n\t\t// Estimate size for using a new table.\n\t\t// Use the previous header size as the best estimate.\n\t\tnewSize := w.lastHeader + tokens.EstimatedBits()\n\t\tnewSize += int(w.literalEncoding.codes[endBlockMarker].len()) + newSize>>w.logNewTablePenalty\n\n\t\t// The estimated size is calculated as an optimal table.\n\t\t// We add a penalty to make it more realistic and re-use a bit more.\n\t\treuseSize := w.dynamicReuseSize(w.literalEncoding, w.offsetEncoding) + extraBits\n\n\t\t// Check if a new table is better.\n\t\tif newSize < reuseSize {\n\t\t\t// Write the EOB we owe.\n\t\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\t\tsize = newSize\n\t\t\tw.lastHeader = 0\n\t\t} else {\n\t\t\tsize = reuseSize\n\t\t}\n\n\t\tif tokens.n < maxPredefinedTokens {\n\t\t\tif preSize := w.fixedSize(extraBits) + 7; usePrefs && preSize < size {\n\t\t\t\t// Check if we get a reasonable size decrease.\n\t\t\t\tif storable && ssize <= size {\n\t\t\t\t\tw.writeStoredHeader(len(input), eof)\n\t\t\t\t\tw.writeBytes(input)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tw.writeFixedHeader(eof)\n\t\t\t\tif !sync {\n\t\t\t\t\ttokens.AddEOB()\n\t\t\t\t}\n\t\t\t\tw.writeTokens(tokens.Slice(), fixedLiteralEncoding.codes, fixedOffsetEncoding.codes)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\t// Check if we get a reasonable size decrease.\n\t\tif storable && ssize <= size {\n\t\t\tw.writeStoredHeader(len(input), eof)\n\t\t\tw.writeBytes(input)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// We want a new block/table\n\tif w.lastHeader == 0 {\n\t\tif fillReuse && !sync {\n\t\t\tw.fillTokens()\n\t\t\tnumLiterals, numOffsets = maxNumLit, maxNumDist\n\t\t} else {\n\t\t\tw.literalFreq[endBlockMarker] = 1\n\t\t}\n\n\t\tw.generate()\n\t\t// Generate codegen and codegenFrequencies, which indicates how to encode\n\t\t// the literalEncoding and the offsetEncoding.\n\t\tw.generateCodegen(numLiterals, numOffsets, w.literalEncoding, w.offsetEncoding)\n\t\tw.codegenEncoding.generate(w.codegenFreq[:], 7)\n\n\t\tvar numCodegens int\n\t\tif fillReuse && !sync {\n\t\t\t// Reindex for accurate size...\n\t\t\tw.indexTokens(tokens, true)\n\t\t}\n\t\tsize, numCodegens = w.dynamicSize(w.literalEncoding, w.offsetEncoding, extraBits)\n\n\t\t// Store predefined, if we don't get a reasonable improvement.\n\t\tif tokens.n < maxPredefinedTokens {\n\t\t\tif preSize := w.fixedSize(extraBits); usePrefs && preSize <= size {\n\t\t\t\t// Store bytes, if we don't get an improvement.\n\t\t\t\tif storable && ssize <= preSize {\n\t\t\t\t\tw.writeStoredHeader(len(input), eof)\n\t\t\t\t\tw.writeBytes(input)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tw.writeFixedHeader(eof)\n\t\t\t\tif !sync {\n\t\t\t\t\ttokens.AddEOB()\n\t\t\t\t}\n\t\t\t\tw.writeTokens(tokens.Slice(), fixedLiteralEncoding.codes, fixedOffsetEncoding.codes)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif storable && ssize <= size {\n\t\t\t// Store bytes, if we don't get an improvement.\n\t\t\tw.writeStoredHeader(len(input), eof)\n\t\t\tw.writeBytes(input)\n\t\t\treturn\n\t\t}\n\n\t\t// Write Huffman table.\n\t\tw.writeDynamicHeader(numLiterals, numOffsets, numCodegens, eof)\n\t\tif !sync {\n\t\t\tw.lastHeader, _ = w.headerSize()\n\t\t}\n\t\tw.lastHuffMan = false\n\t}\n\n\tif sync {\n\t\tw.lastHeader = 0\n\t}\n\t// Write the tokens.\n\tw.writeTokens(tokens.Slice(), w.literalEncoding.codes, w.offsetEncoding.codes)\n}\n\nfunc (w *huffmanBitWriter) fillTokens() {\n\tfor i, v := range w.literalFreq[:literalCount] {\n\t\tif v == 0 {\n\t\t\tw.literalFreq[i] = 1\n\t\t}\n\t}\n\tfor i, v := range w.offsetFreq[:offsetCodeCount] {\n\t\tif v == 0 {\n\t\t\tw.offsetFreq[i] = 1\n\t\t}\n\t}\n}\n\n// indexTokens indexes a slice of tokens, and updates\n// literalFreq and offsetFreq, and generates literalEncoding\n// and offsetEncoding.\n// The number of literal and offset tokens is returned.\nfunc (w *huffmanBitWriter) indexTokens(t *tokens, filled bool) (numLiterals, numOffsets int) {\n\t//copy(w.literalFreq[:], t.litHist[:])\n\t*(*[256]uint16)(w.literalFreq[:]) = t.litHist\n\t//copy(w.literalFreq[256:], t.extraHist[:])\n\t*(*[32]uint16)(w.literalFreq[256:]) = t.extraHist\n\tw.offsetFreq = t.offHist\n\n\tif t.n == 0 {\n\t\treturn\n\t}\n\tif filled {\n\t\treturn maxNumLit, maxNumDist\n\t}\n\t// get the number of literals\n\tnumLiterals = len(w.literalFreq)\n\tfor w.literalFreq[numLiterals-1] == 0 {\n\t\tnumLiterals--\n\t}\n\t// get the number of offsets\n\tnumOffsets = len(w.offsetFreq)\n\tfor numOffsets > 0 && w.offsetFreq[numOffsets-1] == 0 {\n\t\tnumOffsets--\n\t}\n\tif numOffsets == 0 {\n\t\t// We haven't found a single match. If we want to go with the dynamic encoding,\n\t\t// we should count at least one offset to be sure that the offset huffman tree could be encoded.\n\t\tw.offsetFreq[0] = 1\n\t\tnumOffsets = 1\n\t}\n\treturn\n}\n\nfunc (w *huffmanBitWriter) generate() {\n\tw.literalEncoding.generate(w.literalFreq[:literalCount], 15)\n\tw.offsetEncoding.generate(w.offsetFreq[:offsetCodeCount], 15)\n}\n\n// writeTokens writes a slice of tokens to the output.\n// codes for literal and offset encoding must be supplied.\nfunc (w *huffmanBitWriter) writeTokens(tokens []token, leCodes, oeCodes []hcode) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\tif len(tokens) == 0 {\n\t\treturn\n\t}\n\n\t// Only last token should be endBlockMarker.\n\tvar deferEOB bool\n\tif tokens[len(tokens)-1] == endBlockMarker {\n\t\ttokens = tokens[:len(tokens)-1]\n\t\tdeferEOB = true\n\t}\n\n\t// Create slices up to the next power of two to avoid bounds checks.\n\tlits := leCodes[:256]\n\toffs := oeCodes[:32]\n\tlengths := leCodes[lengthCodesStart:]\n\tlengths = lengths[:32]\n\n\t// Go 1.16 LOVES having these on stack.\n\tbits, nbits, nbytes := w.bits, w.nbits, w.nbytes\n\n\tfor _, t := range tokens {\n\t\tif t < 256 {\n\t\t\t//w.writeCode(lits[t.literal()])\n\t\t\tc := lits[t]\n\t\t\tbits |= c.code64() << (nbits & 63)\n\t\t\tnbits += c.len()\n\t\t\tif nbits >= 48 {\n\t\t\t\tle.Store64(w.bytes[nbytes:], bits)\n\t\t\t\t//*(*uint64)(unsafe.Pointer(&w.bytes[nbytes])) = bits\n\t\t\t\tbits >>= 48\n\t\t\t\tnbits -= 48\n\t\t\t\tnbytes += 6\n\t\t\t\tif nbytes >= bufferFlushSize {\n\t\t\t\t\tif w.err != nil {\n\t\t\t\t\t\tnbytes = 0\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\t_, w.err = w.writer.Write(w.bytes[:nbytes])\n\t\t\t\t\tnbytes = 0\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// Write the length\n\t\tlength := t.length()\n\t\tlengthCode := lengthCode(length) & 31\n\t\tif false {\n\t\t\tw.writeCode(lengths[lengthCode])\n\t\t} else {\n\t\t\t// inlined\n\t\t\tc := lengths[lengthCode]\n\t\t\tbits |= c.code64() << (nbits & 63)\n\t\t\tnbits += c.len()\n\t\t\tif nbits >= 48 {\n\t\t\t\tle.Store64(w.bytes[nbytes:], bits)\n\t\t\t\t//*(*uint64)(unsafe.Pointer(&w.bytes[nbytes])) = bits\n\t\t\t\tbits >>= 48\n\t\t\t\tnbits -= 48\n\t\t\t\tnbytes += 6\n\t\t\t\tif nbytes >= bufferFlushSize {\n\t\t\t\t\tif w.err != nil {\n\t\t\t\t\t\tnbytes = 0\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\t_, w.err = w.writer.Write(w.bytes[:nbytes])\n\t\t\t\t\tnbytes = 0\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif lengthCode >= lengthExtraBitsMinCode {\n\t\t\textraLengthBits := lengthExtraBits[lengthCode]\n\t\t\t//w.writeBits(extraLength, extraLengthBits)\n\t\t\textraLength := int32(length - lengthBase[lengthCode])\n\t\t\tbits |= uint64(extraLength) << (nbits & 63)\n\t\t\tnbits += extraLengthBits\n\t\t\tif nbits >= 48 {\n\t\t\t\tle.Store64(w.bytes[nbytes:], bits)\n\t\t\t\t//*(*uint64)(unsafe.Pointer(&w.bytes[nbytes])) = bits\n\t\t\t\tbits >>= 48\n\t\t\t\tnbits -= 48\n\t\t\t\tnbytes += 6\n\t\t\t\tif nbytes >= bufferFlushSize {\n\t\t\t\t\tif w.err != nil {\n\t\t\t\t\t\tnbytes = 0\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\t_, w.err = w.writer.Write(w.bytes[:nbytes])\n\t\t\t\t\tnbytes = 0\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Write the offset\n\t\toffset := t.offset()\n\t\toffsetCode := (offset >> 16) & 31\n\t\tif false {\n\t\t\tw.writeCode(offs[offsetCode])\n\t\t} else {\n\t\t\t// inlined\n\t\t\tc := offs[offsetCode]\n\t\t\tbits |= c.code64() << (nbits & 63)\n\t\t\tnbits += c.len()\n\t\t\tif nbits >= 48 {\n\t\t\t\tle.Store64(w.bytes[nbytes:], bits)\n\t\t\t\t//*(*uint64)(unsafe.Pointer(&w.bytes[nbytes])) = bits\n\t\t\t\tbits >>= 48\n\t\t\t\tnbits -= 48\n\t\t\t\tnbytes += 6\n\t\t\t\tif nbytes >= bufferFlushSize {\n\t\t\t\t\tif w.err != nil {\n\t\t\t\t\t\tnbytes = 0\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\t_, w.err = w.writer.Write(w.bytes[:nbytes])\n\t\t\t\t\tnbytes = 0\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif offsetCode >= offsetExtraBitsMinCode {\n\t\t\toffsetComb := offsetCombined[offsetCode]\n\t\t\t//w.writeBits(extraOffset, extraOffsetBits)\n\t\t\tbits |= uint64((offset-(offsetComb>>8))&matchOffsetOnlyMask) << (nbits & 63)\n\t\t\tnbits += uint8(offsetComb)\n\t\t\tif nbits >= 48 {\n\t\t\t\tle.Store64(w.bytes[nbytes:], bits)\n\t\t\t\t//*(*uint64)(unsafe.Pointer(&w.bytes[nbytes])) = bits\n\t\t\t\tbits >>= 48\n\t\t\t\tnbits -= 48\n\t\t\t\tnbytes += 6\n\t\t\t\tif nbytes >= bufferFlushSize {\n\t\t\t\t\tif w.err != nil {\n\t\t\t\t\t\tnbytes = 0\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\t_, w.err = w.writer.Write(w.bytes[:nbytes])\n\t\t\t\t\tnbytes = 0\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// Restore...\n\tw.bits, w.nbits, w.nbytes = bits, nbits, nbytes\n\n\tif deferEOB {\n\t\tw.writeCode(leCodes[endBlockMarker])\n\t}\n}\n\n// huffOffset is a static offset encoder used for huffman only encoding.\n// It can be reused since we will not be encoding offset values.\nvar huffOffset *huffmanEncoder\n\nfunc init() {\n\tw := newHuffmanBitWriter(nil)\n\tw.offsetFreq[0] = 1\n\thuffOffset = newHuffmanEncoder(offsetCodeCount)\n\thuffOffset.generate(w.offsetFreq[:offsetCodeCount], 15)\n}\n\n// writeBlockHuff encodes a block of bytes as either\n// Huffman encoded literals or uncompressed bytes if the\n// results only gains very little from compression.\nfunc (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte, sync bool) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\n\t// Clear histogram\n\tfor i := range w.literalFreq[:] {\n\t\tw.literalFreq[i] = 0\n\t}\n\tif !w.lastHuffMan {\n\t\tfor i := range w.offsetFreq[:] {\n\t\t\tw.offsetFreq[i] = 0\n\t\t}\n\t}\n\n\tconst numLiterals = endBlockMarker + 1\n\tconst numOffsets = 1\n\n\t// Add everything as literals\n\t// We have to estimate the header size.\n\t// Assume header is around 70 bytes:\n\t// https://stackoverflow.com/a/25454430\n\tconst guessHeaderSizeBits = 70 * 8\n\thistogram(input, w.literalFreq[:numLiterals])\n\tssize, storable := w.storedSize(input)\n\tif storable && len(input) > 1024 {\n\t\t// Quick check for incompressible content.\n\t\tabs := float64(0)\n\t\tavg := float64(len(input)) / 256\n\t\tmax := float64(len(input) * 2)\n\t\tfor _, v := range w.literalFreq[:256] {\n\t\t\tdiff := float64(v) - avg\n\t\t\tabs += diff * diff\n\t\t\tif abs > max {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif abs < max {\n\t\t\tif debugDeflate {\n\t\t\t\tfmt.Println(\"stored\", abs, \"<\", max)\n\t\t\t}\n\t\t\t// No chance we can compress this...\n\t\t\tw.writeStoredHeader(len(input), eof)\n\t\t\tw.writeBytes(input)\n\t\t\treturn\n\t\t}\n\t}\n\tw.literalFreq[endBlockMarker] = 1\n\tw.tmpLitEncoding.generate(w.literalFreq[:numLiterals], 15)\n\testBits := w.tmpLitEncoding.canReuseBits(w.literalFreq[:numLiterals])\n\tif estBits < math.MaxInt32 {\n\t\testBits += w.lastHeader\n\t\tif w.lastHeader == 0 {\n\t\t\testBits += guessHeaderSizeBits\n\t\t}\n\t\testBits += estBits >> w.logNewTablePenalty\n\t}\n\n\t// Store bytes, if we don't get a reasonable improvement.\n\tif storable && ssize <= estBits {\n\t\tif debugDeflate {\n\t\t\tfmt.Println(\"stored,\", ssize, \"<=\", estBits)\n\t\t}\n\t\tw.writeStoredHeader(len(input), eof)\n\t\tw.writeBytes(input)\n\t\treturn\n\t}\n\n\tif w.lastHeader > 0 {\n\t\treuseSize := w.literalEncoding.canReuseBits(w.literalFreq[:256])\n\n\t\tif estBits < reuseSize {\n\t\t\tif debugDeflate {\n\t\t\t\tfmt.Println(\"NOT reusing, reuse:\", reuseSize/8, \"> new:\", estBits/8, \"header est:\", w.lastHeader/8, \"bytes\")\n\t\t\t}\n\t\t\t// We owe an EOB\n\t\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\t\tw.lastHeader = 0\n\t\t} else if debugDeflate {\n\t\t\tfmt.Println(\"reusing, reuse:\", reuseSize/8, \"> new:\", estBits/8, \"- header est:\", w.lastHeader/8)\n\t\t}\n\t}\n\n\tcount := 0\n\tif w.lastHeader == 0 {\n\t\t// Use the temp encoding, so swap.\n\t\tw.literalEncoding, w.tmpLitEncoding = w.tmpLitEncoding, w.literalEncoding\n\t\t// Generate codegen and codegenFrequencies, which indicates how to encode\n\t\t// the literalEncoding and the offsetEncoding.\n\t\tw.generateCodegen(numLiterals, numOffsets, w.literalEncoding, huffOffset)\n\t\tw.codegenEncoding.generate(w.codegenFreq[:], 7)\n\t\tnumCodegens := w.codegens()\n\n\t\t// Huffman.\n\t\tw.writeDynamicHeader(numLiterals, numOffsets, numCodegens, eof)\n\t\tw.lastHuffMan = true\n\t\tw.lastHeader, _ = w.headerSize()\n\t\tif debugDeflate {\n\t\t\tcount += w.lastHeader\n\t\t\tfmt.Println(\"header:\", count/8)\n\t\t}\n\t}\n\n\tencoding := w.literalEncoding.codes[:256]\n\t// Go 1.16 LOVES having these on stack. At least 1.5x the speed.\n\tbits, nbits, nbytes := w.bits, w.nbits, w.nbytes\n\n\tif debugDeflate {\n\t\tcount -= int(nbytes)*8 + int(nbits)\n\t}\n\t// Unroll, write 3 codes/loop.\n\t// Fastest number of unrolls.\n\tfor len(input) > 3 {\n\t\t// We must have at least 48 bits free.\n\t\tif nbits >= 8 {\n\t\t\tn := nbits >> 3\n\t\t\tle.Store64(w.bytes[nbytes:], bits)\n\t\t\tbits >>= (n * 8) & 63\n\t\t\tnbits -= n * 8\n\t\t\tnbytes += n\n\t\t}\n\t\tif nbytes >= bufferFlushSize {\n\t\t\tif w.err != nil {\n\t\t\t\tnbytes = 0\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif debugDeflate {\n\t\t\t\tcount += int(nbytes) * 8\n\t\t\t}\n\t\t\t_, w.err = w.writer.Write(w.bytes[:nbytes])\n\t\t\tnbytes = 0\n\t\t}\n\t\ta, b := encoding[input[0]], encoding[input[1]]\n\t\tbits |= a.code64() << (nbits & 63)\n\t\tbits |= b.code64() << ((nbits + a.len()) & 63)\n\t\tc := encoding[input[2]]\n\t\tnbits += b.len() + a.len()\n\t\tbits |= c.code64() << (nbits & 63)\n\t\tnbits += c.len()\n\t\tinput = input[3:]\n\t}\n\n\t// Remaining...\n\tfor _, t := range input {\n\t\tif nbits >= 48 {\n\t\t\tle.Store64(w.bytes[nbytes:], bits)\n\t\t\t//*(*uint64)(unsafe.Pointer(&w.bytes[nbytes])) = bits\n\t\t\tbits >>= 48\n\t\t\tnbits -= 48\n\t\t\tnbytes += 6\n\t\t\tif nbytes >= bufferFlushSize {\n\t\t\t\tif w.err != nil {\n\t\t\t\t\tnbytes = 0\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif debugDeflate {\n\t\t\t\t\tcount += int(nbytes) * 8\n\t\t\t\t}\n\t\t\t\t_, w.err = w.writer.Write(w.bytes[:nbytes])\n\t\t\t\tnbytes = 0\n\t\t\t}\n\t\t}\n\t\t// Bitwriting inlined, ~30% speedup\n\t\tc := encoding[t]\n\t\tbits |= c.code64() << (nbits & 63)\n\n\t\tnbits += c.len()\n\t\tif debugDeflate {\n\t\t\tcount += int(c.len())\n\t\t}\n\t}\n\t// Restore...\n\tw.bits, w.nbits, w.nbytes = bits, nbits, nbytes\n\n\tif debugDeflate {\n\t\tnb := count + int(nbytes)*8 + int(nbits)\n\t\tfmt.Println(\"wrote\", nb, \"bits,\", nb/8, \"bytes.\")\n\t}\n\t// Flush if needed to have space.\n\tif w.nbits >= 48 {\n\t\tw.writeOutBits()\n\t}\n\n\tif eof || sync {\n\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\tw.lastHeader = 0\n\t\tw.lastHuffMan = false\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/huffman_code.go",
    "content": "// Copyright 2009 The Go 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 flate\n\nimport (\n\t\"math\"\n\t\"math/bits\"\n)\n\nconst (\n\tmaxBitsLimit = 16\n\t// number of valid literals\n\tliteralCount = 286\n)\n\n// hcode is a huffman code with a bit code and bit length.\ntype hcode uint32\n\nfunc (h hcode) len() uint8 {\n\treturn uint8(h)\n}\n\nfunc (h hcode) code64() uint64 {\n\treturn uint64(h >> 8)\n}\n\nfunc (h hcode) zero() bool {\n\treturn h == 0\n}\n\ntype huffmanEncoder struct {\n\tcodes    []hcode\n\tbitCount [17]int32\n\n\t// Allocate a reusable buffer with the longest possible frequency table.\n\t// Possible lengths are codegenCodeCount, offsetCodeCount and literalCount.\n\t// The largest of these is literalCount, so we allocate for that case.\n\tfreqcache [literalCount + 1]literalNode\n}\n\ntype literalNode struct {\n\tliteral uint16\n\tfreq    uint16\n}\n\n// A levelInfo describes the state of the constructed tree for a given depth.\ntype levelInfo struct {\n\t// Our level.  for better printing\n\tlevel int32\n\n\t// The frequency of the last node at this level\n\tlastFreq int32\n\n\t// The frequency of the next character to add to this level\n\tnextCharFreq int32\n\n\t// The frequency of the next pair (from level below) to add to this level.\n\t// Only valid if the \"needed\" value of the next lower level is 0.\n\tnextPairFreq int32\n\n\t// The number of chains remaining to generate for this level before moving\n\t// up to the next level\n\tneeded int32\n}\n\n// set sets the code and length of an hcode.\nfunc (h *hcode) set(code uint16, length uint8) {\n\t*h = hcode(length) | (hcode(code) << 8)\n}\n\nfunc newhcode(code uint16, length uint8) hcode {\n\treturn hcode(length) | (hcode(code) << 8)\n}\n\nfunc reverseBits(number uint16, bitLength byte) uint16 {\n\treturn bits.Reverse16(number << ((16 - bitLength) & 15))\n}\n\nfunc maxNode() literalNode { return literalNode{math.MaxUint16, math.MaxUint16} }\n\nfunc newHuffmanEncoder(size int) *huffmanEncoder {\n\t// Make capacity to next power of two.\n\tc := uint(bits.Len32(uint32(size - 1)))\n\treturn &huffmanEncoder{codes: make([]hcode, size, 1<<c)}\n}\n\n// Generates a HuffmanCode corresponding to the fixed literal table\nfunc generateFixedLiteralEncoding() *huffmanEncoder {\n\th := newHuffmanEncoder(literalCount)\n\tcodes := h.codes\n\tvar ch uint16\n\tfor ch = 0; ch < literalCount; ch++ {\n\t\tvar bits uint16\n\t\tvar size uint8\n\t\tswitch {\n\t\tcase ch < 144:\n\t\t\t// size 8, 000110000  .. 10111111\n\t\t\tbits = ch + 48\n\t\t\tsize = 8\n\t\tcase ch < 256:\n\t\t\t// size 9, 110010000 .. 111111111\n\t\t\tbits = ch + 400 - 144\n\t\t\tsize = 9\n\t\tcase ch < 280:\n\t\t\t// size 7, 0000000 .. 0010111\n\t\t\tbits = ch - 256\n\t\t\tsize = 7\n\t\tdefault:\n\t\t\t// size 8, 11000000 .. 11000111\n\t\t\tbits = ch + 192 - 280\n\t\t\tsize = 8\n\t\t}\n\t\tcodes[ch] = newhcode(reverseBits(bits, size), size)\n\t}\n\treturn h\n}\n\nfunc generateFixedOffsetEncoding() *huffmanEncoder {\n\th := newHuffmanEncoder(30)\n\tcodes := h.codes\n\tfor ch := range codes {\n\t\tcodes[ch] = newhcode(reverseBits(uint16(ch), 5), 5)\n\t}\n\treturn h\n}\n\nvar fixedLiteralEncoding = generateFixedLiteralEncoding()\nvar fixedOffsetEncoding = generateFixedOffsetEncoding()\n\nfunc (h *huffmanEncoder) bitLength(freq []uint16) int {\n\tvar total int\n\tfor i, f := range freq {\n\t\tif f != 0 {\n\t\t\ttotal += int(f) * int(h.codes[i].len())\n\t\t}\n\t}\n\treturn total\n}\n\nfunc (h *huffmanEncoder) bitLengthRaw(b []byte) int {\n\tvar total int\n\tfor _, f := range b {\n\t\ttotal += int(h.codes[f].len())\n\t}\n\treturn total\n}\n\n// canReuseBits returns the number of bits or math.MaxInt32 if the encoder cannot be reused.\nfunc (h *huffmanEncoder) canReuseBits(freq []uint16) int {\n\tvar total int\n\tfor i, f := range freq {\n\t\tif f != 0 {\n\t\t\tcode := h.codes[i]\n\t\t\tif code.zero() {\n\t\t\t\treturn math.MaxInt32\n\t\t\t}\n\t\t\ttotal += int(f) * int(code.len())\n\t\t}\n\t}\n\treturn total\n}\n\n// Return the number of literals assigned to each bit size in the Huffman encoding\n//\n// This method is only called when list.length >= 3\n// The cases of 0, 1, and 2 literals are handled by special case code.\n//\n// list  An array of the literals with non-zero frequencies\n//\n//\tand their associated frequencies. The array is in order of increasing\n//\tfrequency, and has as its last element a special element with frequency\n//\tMaxInt32\n//\n// maxBits     The maximum number of bits that should be used to encode any literal.\n//\n//\tMust be less than 16.\n//\n// return      An integer array in which array[i] indicates the number of literals\n//\n//\tthat should be encoded in i bits.\nfunc (h *huffmanEncoder) bitCounts(list []literalNode, maxBits int32) []int32 {\n\tif maxBits >= maxBitsLimit {\n\t\tpanic(\"flate: maxBits too large\")\n\t}\n\tn := int32(len(list))\n\tlist = list[0 : n+1]\n\tlist[n] = maxNode()\n\n\t// The tree can't have greater depth than n - 1, no matter what. This\n\t// saves a little bit of work in some small cases\n\tif maxBits > n-1 {\n\t\tmaxBits = n - 1\n\t}\n\n\t// Create information about each of the levels.\n\t// A bogus \"Level 0\" whose sole purpose is so that\n\t// level1.prev.needed==0.  This makes level1.nextPairFreq\n\t// be a legitimate value that never gets chosen.\n\tvar levels [maxBitsLimit]levelInfo\n\t// leafCounts[i] counts the number of literals at the left\n\t// of ancestors of the rightmost node at level i.\n\t// leafCounts[i][j] is the number of literals at the left\n\t// of the level j ancestor.\n\tvar leafCounts [maxBitsLimit][maxBitsLimit]int32\n\n\t// Descending to only have 1 bounds check.\n\tl2f := int32(list[2].freq)\n\tl1f := int32(list[1].freq)\n\tl0f := int32(list[0].freq) + int32(list[1].freq)\n\n\tfor level := int32(1); level <= maxBits; level++ {\n\t\t// For every level, the first two items are the first two characters.\n\t\t// We initialize the levels as if we had already figured this out.\n\t\tlevels[level] = levelInfo{\n\t\t\tlevel:        level,\n\t\t\tlastFreq:     l1f,\n\t\t\tnextCharFreq: l2f,\n\t\t\tnextPairFreq: l0f,\n\t\t}\n\t\tleafCounts[level][level] = 2\n\t\tif level == 1 {\n\t\t\tlevels[level].nextPairFreq = math.MaxInt32\n\t\t}\n\t}\n\n\t// We need a total of 2*n - 2 items at top level and have already generated 2.\n\tlevels[maxBits].needed = 2*n - 4\n\n\tlevel := uint32(maxBits)\n\tfor level < 16 {\n\t\tl := &levels[level]\n\t\tif l.nextPairFreq == math.MaxInt32 && l.nextCharFreq == math.MaxInt32 {\n\t\t\t// We've run out of both leafs and pairs.\n\t\t\t// End all calculations for this level.\n\t\t\t// To make sure we never come back to this level or any lower level,\n\t\t\t// set nextPairFreq impossibly large.\n\t\t\tl.needed = 0\n\t\t\tlevels[level+1].nextPairFreq = math.MaxInt32\n\t\t\tlevel++\n\t\t\tcontinue\n\t\t}\n\n\t\tprevFreq := l.lastFreq\n\t\tif l.nextCharFreq < l.nextPairFreq {\n\t\t\t// The next item on this row is a leaf node.\n\t\t\tn := leafCounts[level][level] + 1\n\t\t\tl.lastFreq = l.nextCharFreq\n\t\t\t// Lower leafCounts are the same of the previous node.\n\t\t\tleafCounts[level][level] = n\n\t\t\te := list[n]\n\t\t\tif e.literal < math.MaxUint16 {\n\t\t\t\tl.nextCharFreq = int32(e.freq)\n\t\t\t} else {\n\t\t\t\tl.nextCharFreq = math.MaxInt32\n\t\t\t}\n\t\t} else {\n\t\t\t// The next item on this row is a pair from the previous row.\n\t\t\t// nextPairFreq isn't valid until we generate two\n\t\t\t// more values in the level below\n\t\t\tl.lastFreq = l.nextPairFreq\n\t\t\t// Take leaf counts from the lower level, except counts[level] remains the same.\n\t\t\tif true {\n\t\t\t\tsave := leafCounts[level][level]\n\t\t\t\tleafCounts[level] = leafCounts[level-1]\n\t\t\t\tleafCounts[level][level] = save\n\t\t\t} else {\n\t\t\t\tcopy(leafCounts[level][:level], leafCounts[level-1][:level])\n\t\t\t}\n\t\t\tlevels[l.level-1].needed = 2\n\t\t}\n\n\t\tif l.needed--; l.needed == 0 {\n\t\t\t// We've done everything we need to do for this level.\n\t\t\t// Continue calculating one level up. Fill in nextPairFreq\n\t\t\t// of that level with the sum of the two nodes we've just calculated on\n\t\t\t// this level.\n\t\t\tif l.level == maxBits {\n\t\t\t\t// All done!\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tlevels[l.level+1].nextPairFreq = prevFreq + l.lastFreq\n\t\t\tlevel++\n\t\t} else {\n\t\t\t// If we stole from below, move down temporarily to replenish it.\n\t\t\tfor levels[level-1].needed > 0 {\n\t\t\t\tlevel--\n\t\t\t}\n\t\t}\n\t}\n\n\t// Somethings is wrong if at the end, the top level is null or hasn't used\n\t// all of the leaves.\n\tif leafCounts[maxBits][maxBits] != n {\n\t\tpanic(\"leafCounts[maxBits][maxBits] != n\")\n\t}\n\n\tbitCount := h.bitCount[:maxBits+1]\n\tbits := 1\n\tcounts := &leafCounts[maxBits]\n\tfor level := maxBits; level > 0; level-- {\n\t\t// chain.leafCount gives the number of literals requiring at least \"bits\"\n\t\t// bits to encode.\n\t\tbitCount[bits] = counts[level] - counts[level-1]\n\t\tbits++\n\t}\n\treturn bitCount\n}\n\n// Look at the leaves and assign them a bit count and an encoding as specified\n// in RFC 1951 3.2.2\nfunc (h *huffmanEncoder) assignEncodingAndSize(bitCount []int32, list []literalNode) {\n\tcode := uint16(0)\n\tfor n, bits := range bitCount {\n\t\tcode <<= 1\n\t\tif n == 0 || bits == 0 {\n\t\t\tcontinue\n\t\t}\n\t\t// The literals list[len(list)-bits] .. list[len(list)-bits]\n\t\t// are encoded using \"bits\" bits, and get the values\n\t\t// code, code + 1, ....  The code values are\n\t\t// assigned in literal order (not frequency order).\n\t\tchunk := list[len(list)-int(bits):]\n\n\t\tsortByLiteral(chunk)\n\t\tfor _, node := range chunk {\n\t\t\th.codes[node.literal] = newhcode(reverseBits(code, uint8(n)), uint8(n))\n\t\t\tcode++\n\t\t}\n\t\tlist = list[0 : len(list)-int(bits)]\n\t}\n}\n\n// Update this Huffman Code object to be the minimum code for the specified frequency count.\n//\n// freq  An array of frequencies, in which frequency[i] gives the frequency of literal i.\n// maxBits  The maximum number of bits to use for any literal.\nfunc (h *huffmanEncoder) generate(freq []uint16, maxBits int32) {\n\tlist := h.freqcache[:len(freq)+1]\n\tcodes := h.codes[:len(freq)]\n\t// Number of non-zero literals\n\tcount := 0\n\t// Set list to be the set of all non-zero literals and their frequencies\n\tfor i, f := range freq {\n\t\tif f != 0 {\n\t\t\tlist[count] = literalNode{uint16(i), f}\n\t\t\tcount++\n\t\t} else {\n\t\t\tcodes[i] = 0\n\t\t}\n\t}\n\tlist[count] = literalNode{}\n\n\tlist = list[:count]\n\tif count <= 2 {\n\t\t// Handle the small cases here, because they are awkward for the general case code. With\n\t\t// two or fewer literals, everything has bit length 1.\n\t\tfor i, node := range list {\n\t\t\t// \"list\" is in order of increasing literal value.\n\t\t\th.codes[node.literal].set(uint16(i), 1)\n\t\t}\n\t\treturn\n\t}\n\tsortByFreq(list)\n\n\t// Get the number of literals for each bit count\n\tbitCount := h.bitCounts(list, maxBits)\n\t// And do the assignment\n\th.assignEncodingAndSize(bitCount, list)\n}\n\n// atLeastOne clamps the result between 1 and 15.\nfunc atLeastOne(v float32) float32 {\n\tif v < 1 {\n\t\treturn 1\n\t}\n\tif v > 15 {\n\t\treturn 15\n\t}\n\treturn v\n}\n\nfunc histogram(b []byte, h []uint16) {\n\tif true && len(b) >= 8<<10 {\n\t\t// Split for bigger inputs\n\t\thistogramSplit(b, h)\n\t} else {\n\t\th = h[:256]\n\t\tfor _, t := range b {\n\t\t\th[t]++\n\t\t}\n\t}\n}\n\nfunc histogramSplit(b []byte, h []uint16) {\n\t// Tested, and slightly faster than 2-way.\n\t// Writing to separate arrays and combining is also slightly slower.\n\th = h[:256]\n\tfor len(b)&3 != 0 {\n\t\th[b[0]]++\n\t\tb = b[1:]\n\t}\n\tn := len(b) / 4\n\tx, y, z, w := b[:n], b[n:], b[n+n:], b[n+n+n:]\n\ty, z, w = y[:len(x)], z[:len(x)], w[:len(x)]\n\tfor i, t := range x {\n\t\tv0 := &h[t]\n\t\tv1 := &h[y[i]]\n\t\tv3 := &h[w[i]]\n\t\tv2 := &h[z[i]]\n\t\t*v0++\n\t\t*v1++\n\t\t*v2++\n\t\t*v3++\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/huffman_sortByFreq.go",
    "content": "// Copyright 2009 The Go 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 flate\n\n// Sort sorts data.\n// It makes one call to data.Len to determine n, and O(n*log(n)) calls to\n// data.Less and data.Swap. The sort is not guaranteed to be stable.\nfunc sortByFreq(data []literalNode) {\n\tn := len(data)\n\tquickSortByFreq(data, 0, n, maxDepth(n))\n}\n\nfunc quickSortByFreq(data []literalNode, a, b, maxDepth int) {\n\tfor b-a > 12 { // Use ShellSort for slices <= 12 elements\n\t\tif maxDepth == 0 {\n\t\t\theapSort(data, a, b)\n\t\t\treturn\n\t\t}\n\t\tmaxDepth--\n\t\tmlo, mhi := doPivotByFreq(data, a, b)\n\t\t// Avoiding recursion on the larger subproblem guarantees\n\t\t// a stack depth of at most lg(b-a).\n\t\tif mlo-a < b-mhi {\n\t\t\tquickSortByFreq(data, a, mlo, maxDepth)\n\t\t\ta = mhi // i.e., quickSortByFreq(data, mhi, b)\n\t\t} else {\n\t\t\tquickSortByFreq(data, mhi, b, maxDepth)\n\t\t\tb = mlo // i.e., quickSortByFreq(data, a, mlo)\n\t\t}\n\t}\n\tif b-a > 1 {\n\t\t// Do ShellSort pass with gap 6\n\t\t// It could be written in this simplified form cause b-a <= 12\n\t\tfor i := a + 6; i < b; i++ {\n\t\t\tif data[i].freq == data[i-6].freq && data[i].literal < data[i-6].literal || data[i].freq < data[i-6].freq {\n\t\t\t\tdata[i], data[i-6] = data[i-6], data[i]\n\t\t\t}\n\t\t}\n\t\tinsertionSortByFreq(data, a, b)\n\t}\n}\n\nfunc doPivotByFreq(data []literalNode, lo, hi int) (midlo, midhi int) {\n\tm := int(uint(lo+hi) >> 1) // Written like this to avoid integer overflow.\n\tif hi-lo > 40 {\n\t\t// Tukey's ``Ninther,'' median of three medians of three.\n\t\ts := (hi - lo) / 8\n\t\tmedianOfThreeSortByFreq(data, lo, lo+s, lo+2*s)\n\t\tmedianOfThreeSortByFreq(data, m, m-s, m+s)\n\t\tmedianOfThreeSortByFreq(data, hi-1, hi-1-s, hi-1-2*s)\n\t}\n\tmedianOfThreeSortByFreq(data, lo, m, hi-1)\n\n\t// Invariants are:\n\t//\tdata[lo] = pivot (set up by ChoosePivot)\n\t//\tdata[lo < i < a] < pivot\n\t//\tdata[a <= i < b] <= pivot\n\t//\tdata[b <= i < c] unexamined\n\t//\tdata[c <= i < hi-1] > pivot\n\t//\tdata[hi-1] >= pivot\n\tpivot := lo\n\ta, c := lo+1, hi-1\n\n\tfor ; a < c && (data[a].freq == data[pivot].freq && data[a].literal < data[pivot].literal || data[a].freq < data[pivot].freq); a++ {\n\t}\n\tb := a\n\tfor {\n\t\tfor ; b < c && (data[pivot].freq == data[b].freq && data[pivot].literal > data[b].literal || data[pivot].freq > data[b].freq); b++ { // data[b] <= pivot\n\t\t}\n\t\tfor ; b < c && (data[pivot].freq == data[c-1].freq && data[pivot].literal < data[c-1].literal || data[pivot].freq < data[c-1].freq); c-- { // data[c-1] > pivot\n\t\t}\n\t\tif b >= c {\n\t\t\tbreak\n\t\t}\n\t\t// data[b] > pivot; data[c-1] <= pivot\n\t\tdata[b], data[c-1] = data[c-1], data[b]\n\t\tb++\n\t\tc--\n\t}\n\t// If hi-c<3 then there are duplicates (by property of median of nine).\n\t// Let's be a bit more conservative, and set border to 5.\n\tprotect := hi-c < 5\n\tif !protect && hi-c < (hi-lo)/4 {\n\t\t// Lets test some points for equality to pivot\n\t\tdups := 0\n\t\tif data[pivot].freq == data[hi-1].freq && data[pivot].literal > data[hi-1].literal || data[pivot].freq > data[hi-1].freq { // data[hi-1] = pivot\n\t\t\tdata[c], data[hi-1] = data[hi-1], data[c]\n\t\t\tc++\n\t\t\tdups++\n\t\t}\n\t\tif data[b-1].freq == data[pivot].freq && data[b-1].literal > data[pivot].literal || data[b-1].freq > data[pivot].freq { // data[b-1] = pivot\n\t\t\tb--\n\t\t\tdups++\n\t\t}\n\t\t// m-lo = (hi-lo)/2 > 6\n\t\t// b-lo > (hi-lo)*3/4-1 > 8\n\t\t// ==> m < b ==> data[m] <= pivot\n\t\tif data[m].freq == data[pivot].freq && data[m].literal > data[pivot].literal || data[m].freq > data[pivot].freq { // data[m] = pivot\n\t\t\tdata[m], data[b-1] = data[b-1], data[m]\n\t\t\tb--\n\t\t\tdups++\n\t\t}\n\t\t// if at least 2 points are equal to pivot, assume skewed distribution\n\t\tprotect = dups > 1\n\t}\n\tif protect {\n\t\t// Protect against a lot of duplicates\n\t\t// Add invariant:\n\t\t//\tdata[a <= i < b] unexamined\n\t\t//\tdata[b <= i < c] = pivot\n\t\tfor {\n\t\t\tfor ; a < b && (data[b-1].freq == data[pivot].freq && data[b-1].literal > data[pivot].literal || data[b-1].freq > data[pivot].freq); b-- { // data[b] == pivot\n\t\t\t}\n\t\t\tfor ; a < b && (data[a].freq == data[pivot].freq && data[a].literal < data[pivot].literal || data[a].freq < data[pivot].freq); a++ { // data[a] < pivot\n\t\t\t}\n\t\t\tif a >= b {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t// data[a] == pivot; data[b-1] < pivot\n\t\t\tdata[a], data[b-1] = data[b-1], data[a]\n\t\t\ta++\n\t\t\tb--\n\t\t}\n\t}\n\t// Swap pivot into middle\n\tdata[pivot], data[b-1] = data[b-1], data[pivot]\n\treturn b - 1, c\n}\n\n// Insertion sort\nfunc insertionSortByFreq(data []literalNode, a, b int) {\n\tfor i := a + 1; i < b; i++ {\n\t\tfor j := i; j > a && (data[j].freq == data[j-1].freq && data[j].literal < data[j-1].literal || data[j].freq < data[j-1].freq); j-- {\n\t\t\tdata[j], data[j-1] = data[j-1], data[j]\n\t\t}\n\t}\n}\n\n// quickSortByFreq, loosely following Bentley and McIlroy,\n// ``Engineering a Sort Function,'' SP&E November 1993.\n\n// medianOfThreeSortByFreq moves the median of the three values data[m0], data[m1], data[m2] into data[m1].\nfunc medianOfThreeSortByFreq(data []literalNode, m1, m0, m2 int) {\n\t// sort 3 elements\n\tif data[m1].freq == data[m0].freq && data[m1].literal < data[m0].literal || data[m1].freq < data[m0].freq {\n\t\tdata[m1], data[m0] = data[m0], data[m1]\n\t}\n\t// data[m0] <= data[m1]\n\tif data[m2].freq == data[m1].freq && data[m2].literal < data[m1].literal || data[m2].freq < data[m1].freq {\n\t\tdata[m2], data[m1] = data[m1], data[m2]\n\t\t// data[m0] <= data[m2] && data[m1] < data[m2]\n\t\tif data[m1].freq == data[m0].freq && data[m1].literal < data[m0].literal || data[m1].freq < data[m0].freq {\n\t\t\tdata[m1], data[m0] = data[m0], data[m1]\n\t\t}\n\t}\n\t// now data[m0] <= data[m1] <= data[m2]\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/huffman_sortByLiteral.go",
    "content": "// Copyright 2009 The Go 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 flate\n\n// Sort sorts data.\n// It makes one call to data.Len to determine n, and O(n*log(n)) calls to\n// data.Less and data.Swap. The sort is not guaranteed to be stable.\nfunc sortByLiteral(data []literalNode) {\n\tn := len(data)\n\tquickSort(data, 0, n, maxDepth(n))\n}\n\nfunc quickSort(data []literalNode, a, b, maxDepth int) {\n\tfor b-a > 12 { // Use ShellSort for slices <= 12 elements\n\t\tif maxDepth == 0 {\n\t\t\theapSort(data, a, b)\n\t\t\treturn\n\t\t}\n\t\tmaxDepth--\n\t\tmlo, mhi := doPivot(data, a, b)\n\t\t// Avoiding recursion on the larger subproblem guarantees\n\t\t// a stack depth of at most lg(b-a).\n\t\tif mlo-a < b-mhi {\n\t\t\tquickSort(data, a, mlo, maxDepth)\n\t\t\ta = mhi // i.e., quickSort(data, mhi, b)\n\t\t} else {\n\t\t\tquickSort(data, mhi, b, maxDepth)\n\t\t\tb = mlo // i.e., quickSort(data, a, mlo)\n\t\t}\n\t}\n\tif b-a > 1 {\n\t\t// Do ShellSort pass with gap 6\n\t\t// It could be written in this simplified form cause b-a <= 12\n\t\tfor i := a + 6; i < b; i++ {\n\t\t\tif data[i].literal < data[i-6].literal {\n\t\t\t\tdata[i], data[i-6] = data[i-6], data[i]\n\t\t\t}\n\t\t}\n\t\tinsertionSort(data, a, b)\n\t}\n}\nfunc heapSort(data []literalNode, a, b int) {\n\tfirst := a\n\tlo := 0\n\thi := b - a\n\n\t// Build heap with greatest element at top.\n\tfor i := (hi - 1) / 2; i >= 0; i-- {\n\t\tsiftDown(data, i, hi, first)\n\t}\n\n\t// Pop elements, largest first, into end of data.\n\tfor i := hi - 1; i >= 0; i-- {\n\t\tdata[first], data[first+i] = data[first+i], data[first]\n\t\tsiftDown(data, lo, i, first)\n\t}\n}\n\n// siftDown implements the heap property on data[lo, hi).\n// first is an offset into the array where the root of the heap lies.\nfunc siftDown(data []literalNode, lo, hi, first int) {\n\troot := lo\n\tfor {\n\t\tchild := 2*root + 1\n\t\tif child >= hi {\n\t\t\tbreak\n\t\t}\n\t\tif child+1 < hi && data[first+child].literal < data[first+child+1].literal {\n\t\t\tchild++\n\t\t}\n\t\tif data[first+root].literal > data[first+child].literal {\n\t\t\treturn\n\t\t}\n\t\tdata[first+root], data[first+child] = data[first+child], data[first+root]\n\t\troot = child\n\t}\n}\nfunc doPivot(data []literalNode, lo, hi int) (midlo, midhi int) {\n\tm := int(uint(lo+hi) >> 1) // Written like this to avoid integer overflow.\n\tif hi-lo > 40 {\n\t\t// Tukey's ``Ninther,'' median of three medians of three.\n\t\ts := (hi - lo) / 8\n\t\tmedianOfThree(data, lo, lo+s, lo+2*s)\n\t\tmedianOfThree(data, m, m-s, m+s)\n\t\tmedianOfThree(data, hi-1, hi-1-s, hi-1-2*s)\n\t}\n\tmedianOfThree(data, lo, m, hi-1)\n\n\t// Invariants are:\n\t//\tdata[lo] = pivot (set up by ChoosePivot)\n\t//\tdata[lo < i < a] < pivot\n\t//\tdata[a <= i < b] <= pivot\n\t//\tdata[b <= i < c] unexamined\n\t//\tdata[c <= i < hi-1] > pivot\n\t//\tdata[hi-1] >= pivot\n\tpivot := lo\n\ta, c := lo+1, hi-1\n\n\tfor ; a < c && data[a].literal < data[pivot].literal; a++ {\n\t}\n\tb := a\n\tfor {\n\t\tfor ; b < c && data[pivot].literal > data[b].literal; b++ { // data[b] <= pivot\n\t\t}\n\t\tfor ; b < c && data[pivot].literal < data[c-1].literal; c-- { // data[c-1] > pivot\n\t\t}\n\t\tif b >= c {\n\t\t\tbreak\n\t\t}\n\t\t// data[b] > pivot; data[c-1] <= pivot\n\t\tdata[b], data[c-1] = data[c-1], data[b]\n\t\tb++\n\t\tc--\n\t}\n\t// If hi-c<3 then there are duplicates (by property of median of nine).\n\t// Let's be a bit more conservative, and set border to 5.\n\tprotect := hi-c < 5\n\tif !protect && hi-c < (hi-lo)/4 {\n\t\t// Lets test some points for equality to pivot\n\t\tdups := 0\n\t\tif data[pivot].literal > data[hi-1].literal { // data[hi-1] = pivot\n\t\t\tdata[c], data[hi-1] = data[hi-1], data[c]\n\t\t\tc++\n\t\t\tdups++\n\t\t}\n\t\tif data[b-1].literal > data[pivot].literal { // data[b-1] = pivot\n\t\t\tb--\n\t\t\tdups++\n\t\t}\n\t\t// m-lo = (hi-lo)/2 > 6\n\t\t// b-lo > (hi-lo)*3/4-1 > 8\n\t\t// ==> m < b ==> data[m] <= pivot\n\t\tif data[m].literal > data[pivot].literal { // data[m] = pivot\n\t\t\tdata[m], data[b-1] = data[b-1], data[m]\n\t\t\tb--\n\t\t\tdups++\n\t\t}\n\t\t// if at least 2 points are equal to pivot, assume skewed distribution\n\t\tprotect = dups > 1\n\t}\n\tif protect {\n\t\t// Protect against a lot of duplicates\n\t\t// Add invariant:\n\t\t//\tdata[a <= i < b] unexamined\n\t\t//\tdata[b <= i < c] = pivot\n\t\tfor {\n\t\t\tfor ; a < b && data[b-1].literal > data[pivot].literal; b-- { // data[b] == pivot\n\t\t\t}\n\t\t\tfor ; a < b && data[a].literal < data[pivot].literal; a++ { // data[a] < pivot\n\t\t\t}\n\t\t\tif a >= b {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t// data[a] == pivot; data[b-1] < pivot\n\t\t\tdata[a], data[b-1] = data[b-1], data[a]\n\t\t\ta++\n\t\t\tb--\n\t\t}\n\t}\n\t// Swap pivot into middle\n\tdata[pivot], data[b-1] = data[b-1], data[pivot]\n\treturn b - 1, c\n}\n\n// Insertion sort\nfunc insertionSort(data []literalNode, a, b int) {\n\tfor i := a + 1; i < b; i++ {\n\t\tfor j := i; j > a && data[j].literal < data[j-1].literal; j-- {\n\t\t\tdata[j], data[j-1] = data[j-1], data[j]\n\t\t}\n\t}\n}\n\n// maxDepth returns a threshold at which quicksort should switch\n// to heapsort. It returns 2*ceil(lg(n+1)).\nfunc maxDepth(n int) int {\n\tvar depth int\n\tfor i := n; i > 0; i >>= 1 {\n\t\tdepth++\n\t}\n\treturn depth * 2\n}\n\n// medianOfThree moves the median of the three values data[m0], data[m1], data[m2] into data[m1].\nfunc medianOfThree(data []literalNode, m1, m0, m2 int) {\n\t// sort 3 elements\n\tif data[m1].literal < data[m0].literal {\n\t\tdata[m1], data[m0] = data[m0], data[m1]\n\t}\n\t// data[m0] <= data[m1]\n\tif data[m2].literal < data[m1].literal {\n\t\tdata[m2], data[m1] = data[m1], data[m2]\n\t\t// data[m0] <= data[m2] && data[m1] < data[m2]\n\t\tif data[m1].literal < data[m0].literal {\n\t\t\tdata[m1], data[m0] = data[m0], data[m1]\n\t\t}\n\t}\n\t// now data[m0] <= data[m1] <= data[m2]\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/inflate.go",
    "content": "// Copyright 2009 The Go 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\n// Package flate implements the DEFLATE compressed data format, described in\n// RFC 1951.  The gzip and zlib packages implement access to DEFLATE-based file\n// formats.\npackage flate\n\nimport (\n\t\"bufio\"\n\t\"compress/flate\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/bits\"\n\t\"sync\"\n)\n\nconst (\n\tmaxCodeLen     = 16 // max length of Huffman code\n\tmaxCodeLenMask = 15 // mask for max length of Huffman code\n\t// The next three numbers come from the RFC section 3.2.7, with the\n\t// additional proviso in section 3.2.5 which implies that distance codes\n\t// 30 and 31 should never occur in compressed data.\n\tmaxNumLit  = 286\n\tmaxNumDist = 30\n\tnumCodes   = 19 // number of codes in Huffman meta-code\n\n\tdebugDecode = false\n)\n\n// Value of length - 3 and extra bits.\ntype lengthExtra struct {\n\tlength, extra uint8\n}\n\nvar decCodeToLen = [32]lengthExtra{{length: 0x0, extra: 0x0}, {length: 0x1, extra: 0x0}, {length: 0x2, extra: 0x0}, {length: 0x3, extra: 0x0}, {length: 0x4, extra: 0x0}, {length: 0x5, extra: 0x0}, {length: 0x6, extra: 0x0}, {length: 0x7, extra: 0x0}, {length: 0x8, extra: 0x1}, {length: 0xa, extra: 0x1}, {length: 0xc, extra: 0x1}, {length: 0xe, extra: 0x1}, {length: 0x10, extra: 0x2}, {length: 0x14, extra: 0x2}, {length: 0x18, extra: 0x2}, {length: 0x1c, extra: 0x2}, {length: 0x20, extra: 0x3}, {length: 0x28, extra: 0x3}, {length: 0x30, extra: 0x3}, {length: 0x38, extra: 0x3}, {length: 0x40, extra: 0x4}, {length: 0x50, extra: 0x4}, {length: 0x60, extra: 0x4}, {length: 0x70, extra: 0x4}, {length: 0x80, extra: 0x5}, {length: 0xa0, extra: 0x5}, {length: 0xc0, extra: 0x5}, {length: 0xe0, extra: 0x5}, {length: 0xff, extra: 0x0}, {length: 0x0, extra: 0x0}, {length: 0x0, extra: 0x0}, {length: 0x0, extra: 0x0}}\n\nvar bitMask32 = [32]uint32{\n\t0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF,\n\t0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF,\n\t0x1ffff, 0x3ffff, 0x7FFFF, 0xfFFFF, 0x1fFFFF, 0x3fFFFF, 0x7fFFFF, 0xffFFFF,\n\t0x1ffFFFF, 0x3ffFFFF, 0x7ffFFFF, 0xfffFFFF, 0x1fffFFFF, 0x3fffFFFF, 0x7fffFFFF,\n} // up to 32 bits\n\n// Initialize the fixedHuffmanDecoder only once upon first use.\nvar fixedOnce sync.Once\nvar fixedHuffmanDecoder huffmanDecoder\n\n// A CorruptInputError reports the presence of corrupt input at a given offset.\ntype CorruptInputError = flate.CorruptInputError\n\n// An InternalError reports an error in the flate code itself.\ntype InternalError string\n\nfunc (e InternalError) Error() string { return \"flate: internal error: \" + string(e) }\n\n// A ReadError reports an error encountered while reading input.\n//\n// Deprecated: No longer returned.\ntype ReadError = flate.ReadError\n\n// A WriteError reports an error encountered while writing output.\n//\n// Deprecated: No longer returned.\ntype WriteError = flate.WriteError\n\n// Resetter resets a ReadCloser returned by NewReader or NewReaderDict to\n// to switch to a new underlying Reader. This permits reusing a ReadCloser\n// instead of allocating a new one.\ntype Resetter interface {\n\t// Reset discards any buffered data and resets the Resetter as if it was\n\t// newly initialized with the given reader.\n\tReset(r io.Reader, dict []byte) error\n}\n\n// The data structure for decoding Huffman tables is based on that of\n// zlib. There is a lookup table of a fixed bit width (huffmanChunkBits),\n// For codes smaller than the table width, there are multiple entries\n// (each combination of trailing bits has the same value). For codes\n// larger than the table width, the table contains a link to an overflow\n// table. The width of each entry in the link table is the maximum code\n// size minus the chunk width.\n//\n// Note that you can do a lookup in the table even without all bits\n// filled. Since the extra bits are zero, and the DEFLATE Huffman codes\n// have the property that shorter codes come before longer ones, the\n// bit length estimate in the result is a lower bound on the actual\n// number of bits.\n//\n// See the following:\n//\thttp://www.gzip.org/algorithm.txt\n\n// chunk & 15 is number of bits\n// chunk >> 4 is value, including table link\n\nconst (\n\thuffmanChunkBits  = 9\n\thuffmanNumChunks  = 1 << huffmanChunkBits\n\thuffmanCountMask  = 15\n\thuffmanValueShift = 4\n)\n\ntype huffmanDecoder struct {\n\tmaxRead  int                       // the maximum number of bits we can read and not overread\n\tchunks   *[huffmanNumChunks]uint16 // chunks as described above\n\tlinks    [][]uint16                // overflow links\n\tlinkMask uint32                    // mask the width of the link table\n}\n\n// Initialize Huffman decoding tables from array of code lengths.\n// Following this function, h is guaranteed to be initialized into a complete\n// tree (i.e., neither over-subscribed nor under-subscribed). The exception is a\n// degenerate case where the tree has only a single symbol with length 1. Empty\n// trees are permitted.\nfunc (h *huffmanDecoder) init(lengths []int) bool {\n\t// Sanity enables additional runtime tests during Huffman\n\t// table construction. It's intended to be used during\n\t// development to supplement the currently ad-hoc unit tests.\n\tconst sanity = false\n\n\tif h.chunks == nil {\n\t\th.chunks = new([huffmanNumChunks]uint16)\n\t}\n\n\tif h.maxRead != 0 {\n\t\t*h = huffmanDecoder{chunks: h.chunks, links: h.links}\n\t}\n\n\t// Count number of codes of each length,\n\t// compute maxRead and max length.\n\tvar count [maxCodeLen]int\n\tvar min, max int\n\tfor _, n := range lengths {\n\t\tif n == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tif min == 0 || n < min {\n\t\t\tmin = n\n\t\t}\n\t\tif n > max {\n\t\t\tmax = n\n\t\t}\n\t\tcount[n&maxCodeLenMask]++\n\t}\n\n\t// Empty tree. The decompressor.huffSym function will fail later if the tree\n\t// is used. Technically, an empty tree is only valid for the HDIST tree and\n\t// not the HCLEN and HLIT tree. However, a stream with an empty HCLEN tree\n\t// is guaranteed to fail since it will attempt to use the tree to decode the\n\t// codes for the HLIT and HDIST trees. Similarly, an empty HLIT tree is\n\t// guaranteed to fail later since the compressed data section must be\n\t// composed of at least one symbol (the end-of-block marker).\n\tif max == 0 {\n\t\treturn true\n\t}\n\n\tcode := 0\n\tvar nextcode [maxCodeLen]int\n\tfor i := min; i <= max; i++ {\n\t\tcode <<= 1\n\t\tnextcode[i&maxCodeLenMask] = code\n\t\tcode += count[i&maxCodeLenMask]\n\t}\n\n\t// Check that the coding is complete (i.e., that we've\n\t// assigned all 2-to-the-max possible bit sequences).\n\t// Exception: To be compatible with zlib, we also need to\n\t// accept degenerate single-code codings. See also\n\t// TestDegenerateHuffmanCoding.\n\tif code != 1<<uint(max) && !(code == 1 && max == 1) {\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"coding failed, code, max:\", code, max, code == 1<<uint(max), code == 1 && max == 1, \"(one should be true)\")\n\t\t}\n\t\treturn false\n\t}\n\n\th.maxRead = min\n\n\tchunks := h.chunks[:]\n\tfor i := range chunks {\n\t\tchunks[i] = 0\n\t}\n\n\tif max > huffmanChunkBits {\n\t\tnumLinks := 1 << (uint(max) - huffmanChunkBits)\n\t\th.linkMask = uint32(numLinks - 1)\n\n\t\t// create link tables\n\t\tlink := nextcode[huffmanChunkBits+1] >> 1\n\t\tif cap(h.links) < huffmanNumChunks-link {\n\t\t\th.links = make([][]uint16, huffmanNumChunks-link)\n\t\t} else {\n\t\t\th.links = h.links[:huffmanNumChunks-link]\n\t\t}\n\t\tfor j := uint(link); j < huffmanNumChunks; j++ {\n\t\t\treverse := int(bits.Reverse16(uint16(j)))\n\t\t\treverse >>= uint(16 - huffmanChunkBits)\n\t\t\toff := j - uint(link)\n\t\t\tif sanity && h.chunks[reverse] != 0 {\n\t\t\t\tpanic(\"impossible: overwriting existing chunk\")\n\t\t\t}\n\t\t\th.chunks[reverse] = uint16(off<<huffmanValueShift | (huffmanChunkBits + 1))\n\t\t\tif cap(h.links[off]) < numLinks {\n\t\t\t\th.links[off] = make([]uint16, numLinks)\n\t\t\t} else {\n\t\t\t\th.links[off] = h.links[off][:numLinks]\n\t\t\t}\n\t\t}\n\t} else {\n\t\th.links = h.links[:0]\n\t}\n\n\tfor i, n := range lengths {\n\t\tif n == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tcode := nextcode[n]\n\t\tnextcode[n]++\n\t\tchunk := uint16(i<<huffmanValueShift | n)\n\t\treverse := int(bits.Reverse16(uint16(code)))\n\t\treverse >>= uint(16 - n)\n\t\tif n <= huffmanChunkBits {\n\t\t\tfor off := reverse; off < len(h.chunks); off += 1 << uint(n) {\n\t\t\t\t// We should never need to overwrite\n\t\t\t\t// an existing chunk. Also, 0 is\n\t\t\t\t// never a valid chunk, because the\n\t\t\t\t// lower 4 \"count\" bits should be\n\t\t\t\t// between 1 and 15.\n\t\t\t\tif sanity && h.chunks[off] != 0 {\n\t\t\t\t\tpanic(\"impossible: overwriting existing chunk\")\n\t\t\t\t}\n\t\t\t\th.chunks[off] = chunk\n\t\t\t}\n\t\t} else {\n\t\t\tj := reverse & (huffmanNumChunks - 1)\n\t\t\tif sanity && h.chunks[j]&huffmanCountMask != huffmanChunkBits+1 {\n\t\t\t\t// Longer codes should have been\n\t\t\t\t// associated with a link table above.\n\t\t\t\tpanic(\"impossible: not an indirect chunk\")\n\t\t\t}\n\t\t\tvalue := h.chunks[j] >> huffmanValueShift\n\t\t\tlinktab := h.links[value]\n\t\t\treverse >>= huffmanChunkBits\n\t\t\tfor off := reverse; off < len(linktab); off += 1 << uint(n-huffmanChunkBits) {\n\t\t\t\tif sanity && linktab[off] != 0 {\n\t\t\t\t\tpanic(\"impossible: overwriting existing chunk\")\n\t\t\t\t}\n\t\t\t\tlinktab[off] = chunk\n\t\t\t}\n\t\t}\n\t}\n\n\tif sanity {\n\t\t// Above we've sanity checked that we never overwrote\n\t\t// an existing entry. Here we additionally check that\n\t\t// we filled the tables completely.\n\t\tfor i, chunk := range h.chunks {\n\t\t\tif chunk == 0 {\n\t\t\t\t// As an exception, in the degenerate\n\t\t\t\t// single-code case, we allow odd\n\t\t\t\t// chunks to be missing.\n\t\t\t\tif code == 1 && i%2 == 1 {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tpanic(\"impossible: missing chunk\")\n\t\t\t}\n\t\t}\n\t\tfor _, linktab := range h.links {\n\t\t\tfor _, chunk := range linktab {\n\t\t\t\tif chunk == 0 {\n\t\t\t\t\tpanic(\"impossible: missing chunk\")\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true\n}\n\n// Reader is the actual read interface needed by NewReader.\n// If the passed in io.Reader does not also have ReadByte,\n// the NewReader will introduce its own buffering.\ntype Reader interface {\n\tio.Reader\n\tio.ByteReader\n}\n\ntype step uint8\n\nconst (\n\tcopyData step = iota + 1\n\tnextBlock\n\thuffmanBytesBuffer\n\thuffmanBytesReader\n\thuffmanBufioReader\n\thuffmanStringsReader\n\thuffmanGenericReader\n)\n\n// flushMode tells decompressor when to return data\ntype flushMode uint8\n\nconst (\n\tsyncFlush    flushMode = iota // return data after sync flush block\n\tpartialFlush                  // return data after each block\n)\n\n// Decompress state.\ntype decompressor struct {\n\t// Input source.\n\tr       Reader\n\troffset int64\n\n\t// Huffman decoders for literal/length, distance.\n\th1, h2 huffmanDecoder\n\n\t// Length arrays used to define Huffman codes.\n\tbits     *[maxNumLit + maxNumDist]int\n\tcodebits *[numCodes]int\n\n\t// Output history, buffer.\n\tdict dictDecoder\n\n\t// Next step in the decompression,\n\t// and decompression state.\n\tstep      step\n\tstepState int\n\terr       error\n\ttoRead    []byte\n\thl, hd    *huffmanDecoder\n\tcopyLen   int\n\tcopyDist  int\n\n\t// Temporary buffer (avoids repeated allocation).\n\tbuf [4]byte\n\n\t// Input bits, in top of b.\n\tb uint32\n\n\tnb    uint\n\tfinal bool\n\n\tflushMode flushMode\n}\n\nfunc (f *decompressor) nextBlock() {\n\tfor f.nb < 1+2 {\n\t\tif f.err = f.moreBits(); f.err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\tf.final = f.b&1 == 1\n\tf.b >>= 1\n\ttyp := f.b & 3\n\tf.b >>= 2\n\tf.nb -= 1 + 2\n\tswitch typ {\n\tcase 0:\n\t\tf.dataBlock()\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"stored block\")\n\t\t}\n\tcase 1:\n\t\t// compressed, fixed Huffman tables\n\t\tf.hl = &fixedHuffmanDecoder\n\t\tf.hd = nil\n\t\tf.huffmanBlockDecoder()\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"predefinied huffman block\")\n\t\t}\n\tcase 2:\n\t\t// compressed, dynamic Huffman tables\n\t\tif f.err = f.readHuffman(); f.err != nil {\n\t\t\tbreak\n\t\t}\n\t\tf.hl = &f.h1\n\t\tf.hd = &f.h2\n\t\tf.huffmanBlockDecoder()\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"dynamic huffman block\")\n\t\t}\n\tdefault:\n\t\t// 3 is reserved.\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"reserved data block encountered\")\n\t\t}\n\t\tf.err = CorruptInputError(f.roffset)\n\t}\n}\n\nfunc (f *decompressor) Read(b []byte) (int, error) {\n\tfor {\n\t\tif len(f.toRead) > 0 {\n\t\t\tn := copy(b, f.toRead)\n\t\t\tf.toRead = f.toRead[n:]\n\t\t\tif len(f.toRead) == 0 {\n\t\t\t\treturn n, f.err\n\t\t\t}\n\t\t\treturn n, nil\n\t\t}\n\t\tif f.err != nil {\n\t\t\treturn 0, f.err\n\t\t}\n\n\t\tf.doStep()\n\n\t\tif f.err != nil && len(f.toRead) == 0 {\n\t\t\tf.toRead = f.dict.readFlush() // Flush what's left in case of error\n\t\t}\n\t}\n}\n\n// WriteTo implements the io.WriteTo interface for io.Copy and friends.\nfunc (f *decompressor) WriteTo(w io.Writer) (int64, error) {\n\ttotal := int64(0)\n\tflushed := false\n\tfor {\n\t\tif len(f.toRead) > 0 {\n\t\t\tn, err := w.Write(f.toRead)\n\t\t\ttotal += int64(n)\n\t\t\tif err != nil {\n\t\t\t\tf.err = err\n\t\t\t\treturn total, err\n\t\t\t}\n\t\t\tif n != len(f.toRead) {\n\t\t\t\treturn total, io.ErrShortWrite\n\t\t\t}\n\t\t\tf.toRead = f.toRead[:0]\n\t\t}\n\t\tif f.err != nil && flushed {\n\t\t\tif f.err == io.EOF {\n\t\t\t\treturn total, nil\n\t\t\t}\n\t\t\treturn total, f.err\n\t\t}\n\t\tif f.err == nil {\n\t\t\tf.doStep()\n\t\t}\n\t\tif len(f.toRead) == 0 && f.err != nil && !flushed {\n\t\t\tf.toRead = f.dict.readFlush() // Flush what's left in case of error\n\t\t\tflushed = true\n\t\t}\n\t}\n}\n\nfunc (f *decompressor) Close() error {\n\tif f.err == io.EOF {\n\t\treturn nil\n\t}\n\treturn f.err\n}\n\n// RFC 1951 section 3.2.7.\n// Compression with dynamic Huffman codes\n\nvar codeOrder = [...]int{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}\n\nfunc (f *decompressor) readHuffman() error {\n\t// HLIT[5], HDIST[5], HCLEN[4].\n\tfor f.nb < 5+5+4 {\n\t\tif err := f.moreBits(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tnlit := int(f.b&0x1F) + 257\n\tif nlit > maxNumLit {\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"nlit > maxNumLit\", nlit)\n\t\t}\n\t\treturn CorruptInputError(f.roffset)\n\t}\n\tf.b >>= 5\n\tndist := int(f.b&0x1F) + 1\n\tif ndist > maxNumDist {\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"ndist > maxNumDist\", ndist)\n\t\t}\n\t\treturn CorruptInputError(f.roffset)\n\t}\n\tf.b >>= 5\n\tnclen := int(f.b&0xF) + 4\n\t// numCodes is 19, so nclen is always valid.\n\tf.b >>= 4\n\tf.nb -= 5 + 5 + 4\n\n\t// (HCLEN+4)*3 bits: code lengths in the magic codeOrder order.\n\tfor i := 0; i < nclen; i++ {\n\t\tfor f.nb < 3 {\n\t\t\tif err := f.moreBits(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tf.codebits[codeOrder[i]] = int(f.b & 0x7)\n\t\tf.b >>= 3\n\t\tf.nb -= 3\n\t}\n\tfor i := nclen; i < len(codeOrder); i++ {\n\t\tf.codebits[codeOrder[i]] = 0\n\t}\n\tif !f.h1.init(f.codebits[0:]) {\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"init codebits failed\")\n\t\t}\n\t\treturn CorruptInputError(f.roffset)\n\t}\n\n\t// HLIT + 257 code lengths, HDIST + 1 code lengths,\n\t// using the code length Huffman code.\n\tfor i, n := 0, nlit+ndist; i < n; {\n\t\tx, err := f.huffSym(&f.h1)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif x < 16 {\n\t\t\t// Actual length.\n\t\t\tf.bits[i] = x\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\t\t// Repeat previous length or zero.\n\t\tvar rep int\n\t\tvar nb uint\n\t\tvar b int\n\t\tswitch x {\n\t\tdefault:\n\t\t\treturn InternalError(\"unexpected length code\")\n\t\tcase 16:\n\t\t\trep = 3\n\t\t\tnb = 2\n\t\t\tif i == 0 {\n\t\t\t\tif debugDecode {\n\t\t\t\t\tfmt.Println(\"i==0\")\n\t\t\t\t}\n\t\t\t\treturn CorruptInputError(f.roffset)\n\t\t\t}\n\t\t\tb = f.bits[i-1]\n\t\tcase 17:\n\t\t\trep = 3\n\t\t\tnb = 3\n\t\t\tb = 0\n\t\tcase 18:\n\t\t\trep = 11\n\t\t\tnb = 7\n\t\t\tb = 0\n\t\t}\n\t\tfor f.nb < nb {\n\t\t\tif err := f.moreBits(); err != nil {\n\t\t\t\tif debugDecode {\n\t\t\t\t\tfmt.Println(\"morebits:\", err)\n\t\t\t\t}\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\trep += int(f.b & uint32(1<<(nb&regSizeMaskUint32)-1))\n\t\tf.b >>= nb & regSizeMaskUint32\n\t\tf.nb -= nb\n\t\tif i+rep > n {\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"i+rep > n\", i, rep, n)\n\t\t\t}\n\t\t\treturn CorruptInputError(f.roffset)\n\t\t}\n\t\tfor j := 0; j < rep; j++ {\n\t\t\tf.bits[i] = b\n\t\t\ti++\n\t\t}\n\t}\n\n\tif !f.h1.init(f.bits[0:nlit]) || !f.h2.init(f.bits[nlit:nlit+ndist]) {\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"init2 failed\")\n\t\t}\n\t\treturn CorruptInputError(f.roffset)\n\t}\n\n\t// As an optimization, we can initialize the maxRead bits to read at a time\n\t// for the HLIT tree to the length of the EOB marker since we know that\n\t// every block must terminate with one. This preserves the property that\n\t// we never read any extra bytes after the end of the DEFLATE stream.\n\tif f.h1.maxRead < f.bits[endBlockMarker] {\n\t\tf.h1.maxRead = f.bits[endBlockMarker]\n\t}\n\tif !f.final {\n\t\t// If not the final block, the smallest block possible is\n\t\t// a predefined table, BTYPE=01, with a single EOB marker.\n\t\t// This will take up 3 + 7 bits.\n\t\tf.h1.maxRead += 10\n\t}\n\n\treturn nil\n}\n\n// Copy a single uncompressed data block from input to output.\nfunc (f *decompressor) dataBlock() {\n\t// Uncompressed.\n\t// Discard current half-byte.\n\tleft := (f.nb) & 7\n\tf.nb -= left\n\tf.b >>= left\n\n\toffBytes := f.nb >> 3\n\t// Unfilled values will be overwritten.\n\tf.buf[0] = uint8(f.b)\n\tf.buf[1] = uint8(f.b >> 8)\n\tf.buf[2] = uint8(f.b >> 16)\n\tf.buf[3] = uint8(f.b >> 24)\n\n\tf.roffset += int64(offBytes)\n\tf.nb, f.b = 0, 0\n\n\t// Length then ones-complement of length.\n\tnr, err := io.ReadFull(f.r, f.buf[offBytes:4])\n\tf.roffset += int64(nr)\n\tif err != nil {\n\t\tf.err = noEOF(err)\n\t\treturn\n\t}\n\tn := uint16(f.buf[0]) | uint16(f.buf[1])<<8\n\tnn := uint16(f.buf[2]) | uint16(f.buf[3])<<8\n\tif nn != ^n {\n\t\tif debugDecode {\n\t\t\tncomp := ^n\n\t\t\tfmt.Println(\"uint16(nn) != uint16(^n)\", nn, ncomp)\n\t\t}\n\t\tf.err = CorruptInputError(f.roffset)\n\t\treturn\n\t}\n\n\tif n == 0 {\n\t\tif f.flushMode == syncFlush {\n\t\t\tf.toRead = f.dict.readFlush()\n\t\t}\n\n\t\tf.finishBlock()\n\t\treturn\n\t}\n\n\tf.copyLen = int(n)\n\tf.copyData()\n}\n\n// copyData copies f.copyLen bytes from the underlying reader into f.hist.\n// It pauses for reads when f.hist is full.\nfunc (f *decompressor) copyData() {\n\tbuf := f.dict.writeSlice()\n\tif len(buf) > f.copyLen {\n\t\tbuf = buf[:f.copyLen]\n\t}\n\n\tcnt, err := io.ReadFull(f.r, buf)\n\tf.roffset += int64(cnt)\n\tf.copyLen -= cnt\n\tf.dict.writeMark(cnt)\n\tif err != nil {\n\t\tf.err = noEOF(err)\n\t\treturn\n\t}\n\n\tif f.dict.availWrite() == 0 || f.copyLen > 0 {\n\t\tf.toRead = f.dict.readFlush()\n\t\tf.step = copyData\n\t\treturn\n\t}\n\tf.finishBlock()\n}\n\nfunc (f *decompressor) finishBlock() {\n\tif f.final {\n\t\tif f.dict.availRead() > 0 {\n\t\t\tf.toRead = f.dict.readFlush()\n\t\t}\n\n\t\tf.err = io.EOF\n\t} else if f.flushMode == partialFlush && f.dict.availRead() > 0 {\n\t\tf.toRead = f.dict.readFlush()\n\t}\n\n\tf.step = nextBlock\n}\n\nfunc (f *decompressor) doStep() {\n\tswitch f.step {\n\tcase copyData:\n\t\tf.copyData()\n\tcase nextBlock:\n\t\tf.nextBlock()\n\tcase huffmanBytesBuffer:\n\t\tf.huffmanBytesBuffer()\n\tcase huffmanBytesReader:\n\t\tf.huffmanBytesReader()\n\tcase huffmanBufioReader:\n\t\tf.huffmanBufioReader()\n\tcase huffmanStringsReader:\n\t\tf.huffmanStringsReader()\n\tcase huffmanGenericReader:\n\t\tf.huffmanGenericReader()\n\tdefault:\n\t\tpanic(\"BUG: unexpected step state\")\n\t}\n}\n\n// noEOF returns err, unless err == io.EOF, in which case it returns io.ErrUnexpectedEOF.\nfunc noEOF(e error) error {\n\tif e == io.EOF {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\treturn e\n}\n\nfunc (f *decompressor) moreBits() error {\n\tc, err := f.r.ReadByte()\n\tif err != nil {\n\t\treturn noEOF(err)\n\t}\n\tf.roffset++\n\tf.b |= uint32(c) << (f.nb & regSizeMaskUint32)\n\tf.nb += 8\n\treturn nil\n}\n\n// Read the next Huffman-encoded symbol from f according to h.\nfunc (f *decompressor) huffSym(h *huffmanDecoder) (int, error) {\n\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t// with single element, huffSym must error on these two edge cases. In both\n\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t// satisfy the n == 0 check below.\n\tn := uint(h.maxRead)\n\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t// inline call to moreBits and reassign b,nb back to f on return.\n\tnb, b := f.nb, f.b\n\tfor {\n\t\tfor nb < n {\n\t\t\tc, err := f.r.ReadByte()\n\t\t\tif err != nil {\n\t\t\t\tf.b = b\n\t\t\t\tf.nb = nb\n\t\t\t\treturn 0, noEOF(err)\n\t\t\t}\n\t\t\tf.roffset++\n\t\t\tb |= uint32(c) << (nb & regSizeMaskUint32)\n\t\t\tnb += 8\n\t\t}\n\t\tchunk := h.chunks[b&(huffmanNumChunks-1)]\n\t\tn = uint(chunk & huffmanCountMask)\n\t\tif n > huffmanChunkBits {\n\t\t\tchunk = h.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&h.linkMask]\n\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t}\n\t\tif n <= nb {\n\t\t\tif n == 0 {\n\t\t\t\tf.b = b\n\t\t\t\tf.nb = nb\n\t\t\t\tif debugDecode {\n\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t}\n\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\treturn 0, f.err\n\t\t\t}\n\t\t\tf.b = b >> (n & regSizeMaskUint32)\n\t\t\tf.nb = nb - n\n\t\t\treturn int(chunk >> huffmanValueShift), nil\n\t\t}\n\t}\n}\n\nfunc makeReader(r io.Reader) Reader {\n\tif rr, ok := r.(Reader); ok {\n\t\treturn rr\n\t}\n\treturn bufio.NewReader(r)\n}\n\nfunc fixedHuffmanDecoderInit() {\n\tfixedOnce.Do(func() {\n\t\t// These come from the RFC section 3.2.6.\n\t\tvar bits [288]int\n\t\tfor i := 0; i < 144; i++ {\n\t\t\tbits[i] = 8\n\t\t}\n\t\tfor i := 144; i < 256; i++ {\n\t\t\tbits[i] = 9\n\t\t}\n\t\tfor i := 256; i < 280; i++ {\n\t\t\tbits[i] = 7\n\t\t}\n\t\tfor i := 280; i < 288; i++ {\n\t\t\tbits[i] = 8\n\t\t}\n\t\tfixedHuffmanDecoder.init(bits[:])\n\t})\n}\n\nfunc (f *decompressor) Reset(r io.Reader, dict []byte) error {\n\t*f = decompressor{\n\t\tr:        makeReader(r),\n\t\tbits:     f.bits,\n\t\tcodebits: f.codebits,\n\t\th1:       f.h1,\n\t\th2:       f.h2,\n\t\tdict:     f.dict,\n\t\tstep:     nextBlock,\n\t}\n\tf.dict.init(maxMatchOffset, dict)\n\treturn nil\n}\n\ntype ReaderOpt func(*decompressor)\n\n// WithPartialBlock tells decompressor to return after each block,\n// so it can read data written with partial flush\nfunc WithPartialBlock() ReaderOpt {\n\treturn func(f *decompressor) {\n\t\tf.flushMode = partialFlush\n\t}\n}\n\n// WithDict initializes the reader with a preset dictionary\nfunc WithDict(dict []byte) ReaderOpt {\n\treturn func(f *decompressor) {\n\t\tf.dict.init(maxMatchOffset, dict)\n\t}\n}\n\n// NewReaderOpts returns new reader with provided options\nfunc NewReaderOpts(r io.Reader, opts ...ReaderOpt) io.ReadCloser {\n\tfixedHuffmanDecoderInit()\n\n\tvar f decompressor\n\tf.r = makeReader(r)\n\tf.bits = new([maxNumLit + maxNumDist]int)\n\tf.codebits = new([numCodes]int)\n\tf.step = nextBlock\n\tf.dict.init(maxMatchOffset, nil)\n\n\tfor _, opt := range opts {\n\t\topt(&f)\n\t}\n\n\treturn &f\n}\n\n// NewReader returns a new ReadCloser that can be used\n// to read the uncompressed version of r.\n// If r does not also implement io.ByteReader,\n// the decompressor may read more data than necessary from r.\n// It is the caller's responsibility to call Close on the ReadCloser\n// when finished reading.\n//\n// The ReadCloser returned by NewReader also implements Resetter.\nfunc NewReader(r io.Reader) io.ReadCloser {\n\treturn NewReaderOpts(r)\n}\n\n// NewReaderDict is like NewReader but initializes the reader\n// with a preset dictionary. The returned Reader behaves as if\n// the uncompressed data stream started with the given dictionary,\n// which has already been read. NewReaderDict is typically used\n// to read data compressed by NewWriterDict.\n//\n// The ReadCloser returned by NewReader also implements Resetter.\nfunc NewReaderDict(r io.Reader, dict []byte) io.ReadCloser {\n\treturn NewReaderOpts(r, WithDict(dict))\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/inflate_gen.go",
    "content": "// Code generated by go generate gen_inflate.go. DO NOT EDIT.\n\npackage flate\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"math/bits\"\n\t\"strings\"\n)\n\n// Decode a single Huffman block from f.\n// hl and hd are the Huffman states for the lit/length values\n// and the distance values, respectively. If hd == nil, using the\n// fixed distance encoding associated with fixed Huffman blocks.\nfunc (f *decompressor) huffmanBytesBuffer() {\n\tconst (\n\t\tstateInit = iota // Zero value must be stateInit\n\t\tstateDict\n\t)\n\tfr := f.r.(*bytes.Buffer)\n\n\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t// inline call to moreBits and reassign b,nb back to f on return.\n\tfnb, fb, dict := f.nb, f.b, &f.dict\n\n\tswitch f.stepState {\n\tcase stateInit:\n\t\tgoto readLiteral\n\tcase stateDict:\n\t\tgoto copyHistory\n\t}\n\nreadLiteral:\n\t// Read literal and/or (length, distance) according to RFC section 3.2.3.\n\t{\n\t\tvar v int\n\t\t{\n\t\t\t// Inlined v, err := f.huffSym(f.hl)\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hl.maxRead)\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hl.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hl.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hl.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tv = int(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar length int\n\t\tswitch {\n\t\tcase v < 256:\n\t\t\tdict.writeByte(byte(v))\n\t\t\tif dict.availWrite() == 0 {\n\t\t\t\tf.toRead = dict.readFlush()\n\t\t\t\tf.step = huffmanBytesBuffer\n\t\t\t\tf.stepState = stateInit\n\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\treturn\n\t\t\t}\n\t\t\tgoto readLiteral\n\t\tcase v == 256:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tf.finishBlock()\n\t\t\treturn\n\t\t// otherwise, reference to older data\n\t\tcase v < 265:\n\t\t\tlength = v - (257 - 3)\n\t\tcase v < maxNumLit:\n\t\t\tval := decCodeToLen[(v - 257)]\n\t\t\tlength = int(val.length) + 3\n\t\t\tn := uint(val.extra)\n\t\t\tfor fnb < n {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits n>0:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tlength += int(fb & bitMask32[n])\n\t\t\tfb >>= n & regSizeMaskUint32\n\t\t\tfnb -= n\n\t\tdefault:\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(v, \">= maxNumLit\")\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\n\t\tvar dist uint32\n\t\tif f.hd == nil {\n\t\t\tfor fnb < 5 {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<5:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tdist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3)))\n\t\t\tfb >>= 5\n\t\t\tfnb -= 5\n\t\t} else {\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hd.maxRead)\n\t\t\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t\t\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t\t\t// inline call to moreBits and reassign b,nb back to f on return.\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hd.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hd.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hd.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tdist = uint32(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tswitch {\n\t\tcase dist < 4:\n\t\t\tdist++\n\t\tcase dist < maxNumDist:\n\t\t\tnb := uint(dist-2) >> 1\n\t\t\t// have 1 bit in bottom of dist, need nb more.\n\t\t\textra := (dist & 1) << (nb & regSizeMaskUint32)\n\t\t\tfor fnb < nb {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<nb:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\textra |= fb & bitMask32[nb]\n\t\t\tfb >>= nb & regSizeMaskUint32\n\t\t\tfnb -= nb\n\t\t\tdist = 1<<((nb+1)&regSizeMaskUint32) + 1 + extra\n\t\t\t// slower: dist = bitMask32[nb+1] + 2 + extra\n\t\tdefault:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist too big:\", dist, maxNumDist)\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\t// No check on length; encoding can be prescient.\n\t\tif dist > uint32(dict.histSize()) {\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist > dict.histSize():\", dist, dict.histSize())\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\tf.copyLen, f.copyDist = length, int(dist)\n\t\tgoto copyHistory\n\t}\n\ncopyHistory:\n\t// Perform a backwards copy according to RFC section 3.2.3.\n\t{\n\t\tcnt := dict.tryWriteCopy(f.copyDist, f.copyLen)\n\t\tif cnt == 0 {\n\t\t\tcnt = dict.writeCopy(f.copyDist, f.copyLen)\n\t\t}\n\t\tf.copyLen -= cnt\n\n\t\tif dict.availWrite() == 0 || f.copyLen > 0 {\n\t\t\tf.toRead = dict.readFlush()\n\t\t\tf.step = huffmanBytesBuffer // We need to continue this work\n\t\t\tf.stepState = stateDict\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\t\tgoto readLiteral\n\t}\n\t// Not reached\n}\n\n// Decode a single Huffman block from f.\n// hl and hd are the Huffman states for the lit/length values\n// and the distance values, respectively. If hd == nil, using the\n// fixed distance encoding associated with fixed Huffman blocks.\nfunc (f *decompressor) huffmanBytesReader() {\n\tconst (\n\t\tstateInit = iota // Zero value must be stateInit\n\t\tstateDict\n\t)\n\tfr := f.r.(*bytes.Reader)\n\n\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t// inline call to moreBits and reassign b,nb back to f on return.\n\tfnb, fb, dict := f.nb, f.b, &f.dict\n\n\tswitch f.stepState {\n\tcase stateInit:\n\t\tgoto readLiteral\n\tcase stateDict:\n\t\tgoto copyHistory\n\t}\n\nreadLiteral:\n\t// Read literal and/or (length, distance) according to RFC section 3.2.3.\n\t{\n\t\tvar v int\n\t\t{\n\t\t\t// Inlined v, err := f.huffSym(f.hl)\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hl.maxRead)\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hl.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hl.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hl.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tv = int(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar length int\n\t\tswitch {\n\t\tcase v < 256:\n\t\t\tdict.writeByte(byte(v))\n\t\t\tif dict.availWrite() == 0 {\n\t\t\t\tf.toRead = dict.readFlush()\n\t\t\t\tf.step = huffmanBytesReader\n\t\t\t\tf.stepState = stateInit\n\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\treturn\n\t\t\t}\n\t\t\tgoto readLiteral\n\t\tcase v == 256:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tf.finishBlock()\n\t\t\treturn\n\t\t// otherwise, reference to older data\n\t\tcase v < 265:\n\t\t\tlength = v - (257 - 3)\n\t\tcase v < maxNumLit:\n\t\t\tval := decCodeToLen[(v - 257)]\n\t\t\tlength = int(val.length) + 3\n\t\t\tn := uint(val.extra)\n\t\t\tfor fnb < n {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits n>0:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tlength += int(fb & bitMask32[n])\n\t\t\tfb >>= n & regSizeMaskUint32\n\t\t\tfnb -= n\n\t\tdefault:\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(v, \">= maxNumLit\")\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\n\t\tvar dist uint32\n\t\tif f.hd == nil {\n\t\t\tfor fnb < 5 {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<5:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tdist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3)))\n\t\t\tfb >>= 5\n\t\t\tfnb -= 5\n\t\t} else {\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hd.maxRead)\n\t\t\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t\t\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t\t\t// inline call to moreBits and reassign b,nb back to f on return.\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hd.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hd.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hd.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tdist = uint32(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tswitch {\n\t\tcase dist < 4:\n\t\t\tdist++\n\t\tcase dist < maxNumDist:\n\t\t\tnb := uint(dist-2) >> 1\n\t\t\t// have 1 bit in bottom of dist, need nb more.\n\t\t\textra := (dist & 1) << (nb & regSizeMaskUint32)\n\t\t\tfor fnb < nb {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<nb:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\textra |= fb & bitMask32[nb]\n\t\t\tfb >>= nb & regSizeMaskUint32\n\t\t\tfnb -= nb\n\t\t\tdist = 1<<((nb+1)&regSizeMaskUint32) + 1 + extra\n\t\t\t// slower: dist = bitMask32[nb+1] + 2 + extra\n\t\tdefault:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist too big:\", dist, maxNumDist)\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\t// No check on length; encoding can be prescient.\n\t\tif dist > uint32(dict.histSize()) {\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist > dict.histSize():\", dist, dict.histSize())\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\tf.copyLen, f.copyDist = length, int(dist)\n\t\tgoto copyHistory\n\t}\n\ncopyHistory:\n\t// Perform a backwards copy according to RFC section 3.2.3.\n\t{\n\t\tcnt := dict.tryWriteCopy(f.copyDist, f.copyLen)\n\t\tif cnt == 0 {\n\t\t\tcnt = dict.writeCopy(f.copyDist, f.copyLen)\n\t\t}\n\t\tf.copyLen -= cnt\n\n\t\tif dict.availWrite() == 0 || f.copyLen > 0 {\n\t\t\tf.toRead = dict.readFlush()\n\t\t\tf.step = huffmanBytesReader // We need to continue this work\n\t\t\tf.stepState = stateDict\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\t\tgoto readLiteral\n\t}\n\t// Not reached\n}\n\n// Decode a single Huffman block from f.\n// hl and hd are the Huffman states for the lit/length values\n// and the distance values, respectively. If hd == nil, using the\n// fixed distance encoding associated with fixed Huffman blocks.\nfunc (f *decompressor) huffmanBufioReader() {\n\tconst (\n\t\tstateInit = iota // Zero value must be stateInit\n\t\tstateDict\n\t)\n\tfr := f.r.(*bufio.Reader)\n\n\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t// inline call to moreBits and reassign b,nb back to f on return.\n\tfnb, fb, dict := f.nb, f.b, &f.dict\n\n\tswitch f.stepState {\n\tcase stateInit:\n\t\tgoto readLiteral\n\tcase stateDict:\n\t\tgoto copyHistory\n\t}\n\nreadLiteral:\n\t// Read literal and/or (length, distance) according to RFC section 3.2.3.\n\t{\n\t\tvar v int\n\t\t{\n\t\t\t// Inlined v, err := f.huffSym(f.hl)\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hl.maxRead)\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hl.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hl.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hl.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tv = int(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar length int\n\t\tswitch {\n\t\tcase v < 256:\n\t\t\tdict.writeByte(byte(v))\n\t\t\tif dict.availWrite() == 0 {\n\t\t\t\tf.toRead = dict.readFlush()\n\t\t\t\tf.step = huffmanBufioReader\n\t\t\t\tf.stepState = stateInit\n\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\treturn\n\t\t\t}\n\t\t\tgoto readLiteral\n\t\tcase v == 256:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tf.finishBlock()\n\t\t\treturn\n\t\t// otherwise, reference to older data\n\t\tcase v < 265:\n\t\t\tlength = v - (257 - 3)\n\t\tcase v < maxNumLit:\n\t\t\tval := decCodeToLen[(v - 257)]\n\t\t\tlength = int(val.length) + 3\n\t\t\tn := uint(val.extra)\n\t\t\tfor fnb < n {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits n>0:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tlength += int(fb & bitMask32[n])\n\t\t\tfb >>= n & regSizeMaskUint32\n\t\t\tfnb -= n\n\t\tdefault:\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(v, \">= maxNumLit\")\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\n\t\tvar dist uint32\n\t\tif f.hd == nil {\n\t\t\tfor fnb < 5 {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<5:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tdist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3)))\n\t\t\tfb >>= 5\n\t\t\tfnb -= 5\n\t\t} else {\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hd.maxRead)\n\t\t\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t\t\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t\t\t// inline call to moreBits and reassign b,nb back to f on return.\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hd.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hd.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hd.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tdist = uint32(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tswitch {\n\t\tcase dist < 4:\n\t\t\tdist++\n\t\tcase dist < maxNumDist:\n\t\t\tnb := uint(dist-2) >> 1\n\t\t\t// have 1 bit in bottom of dist, need nb more.\n\t\t\textra := (dist & 1) << (nb & regSizeMaskUint32)\n\t\t\tfor fnb < nb {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<nb:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\textra |= fb & bitMask32[nb]\n\t\t\tfb >>= nb & regSizeMaskUint32\n\t\t\tfnb -= nb\n\t\t\tdist = 1<<((nb+1)&regSizeMaskUint32) + 1 + extra\n\t\t\t// slower: dist = bitMask32[nb+1] + 2 + extra\n\t\tdefault:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist too big:\", dist, maxNumDist)\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\t// No check on length; encoding can be prescient.\n\t\tif dist > uint32(dict.histSize()) {\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist > dict.histSize():\", dist, dict.histSize())\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\tf.copyLen, f.copyDist = length, int(dist)\n\t\tgoto copyHistory\n\t}\n\ncopyHistory:\n\t// Perform a backwards copy according to RFC section 3.2.3.\n\t{\n\t\tcnt := dict.tryWriteCopy(f.copyDist, f.copyLen)\n\t\tif cnt == 0 {\n\t\t\tcnt = dict.writeCopy(f.copyDist, f.copyLen)\n\t\t}\n\t\tf.copyLen -= cnt\n\n\t\tif dict.availWrite() == 0 || f.copyLen > 0 {\n\t\t\tf.toRead = dict.readFlush()\n\t\t\tf.step = huffmanBufioReader // We need to continue this work\n\t\t\tf.stepState = stateDict\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\t\tgoto readLiteral\n\t}\n\t// Not reached\n}\n\n// Decode a single Huffman block from f.\n// hl and hd are the Huffman states for the lit/length values\n// and the distance values, respectively. If hd == nil, using the\n// fixed distance encoding associated with fixed Huffman blocks.\nfunc (f *decompressor) huffmanStringsReader() {\n\tconst (\n\t\tstateInit = iota // Zero value must be stateInit\n\t\tstateDict\n\t)\n\tfr := f.r.(*strings.Reader)\n\n\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t// inline call to moreBits and reassign b,nb back to f on return.\n\tfnb, fb, dict := f.nb, f.b, &f.dict\n\n\tswitch f.stepState {\n\tcase stateInit:\n\t\tgoto readLiteral\n\tcase stateDict:\n\t\tgoto copyHistory\n\t}\n\nreadLiteral:\n\t// Read literal and/or (length, distance) according to RFC section 3.2.3.\n\t{\n\t\tvar v int\n\t\t{\n\t\t\t// Inlined v, err := f.huffSym(f.hl)\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hl.maxRead)\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hl.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hl.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hl.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tv = int(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar length int\n\t\tswitch {\n\t\tcase v < 256:\n\t\t\tdict.writeByte(byte(v))\n\t\t\tif dict.availWrite() == 0 {\n\t\t\t\tf.toRead = dict.readFlush()\n\t\t\t\tf.step = huffmanStringsReader\n\t\t\t\tf.stepState = stateInit\n\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\treturn\n\t\t\t}\n\t\t\tgoto readLiteral\n\t\tcase v == 256:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tf.finishBlock()\n\t\t\treturn\n\t\t// otherwise, reference to older data\n\t\tcase v < 265:\n\t\t\tlength = v - (257 - 3)\n\t\tcase v < maxNumLit:\n\t\t\tval := decCodeToLen[(v - 257)]\n\t\t\tlength = int(val.length) + 3\n\t\t\tn := uint(val.extra)\n\t\t\tfor fnb < n {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits n>0:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tlength += int(fb & bitMask32[n])\n\t\t\tfb >>= n & regSizeMaskUint32\n\t\t\tfnb -= n\n\t\tdefault:\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(v, \">= maxNumLit\")\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\n\t\tvar dist uint32\n\t\tif f.hd == nil {\n\t\t\tfor fnb < 5 {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<5:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tdist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3)))\n\t\t\tfb >>= 5\n\t\t\tfnb -= 5\n\t\t} else {\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hd.maxRead)\n\t\t\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t\t\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t\t\t// inline call to moreBits and reassign b,nb back to f on return.\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hd.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hd.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hd.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tdist = uint32(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tswitch {\n\t\tcase dist < 4:\n\t\t\tdist++\n\t\tcase dist < maxNumDist:\n\t\t\tnb := uint(dist-2) >> 1\n\t\t\t// have 1 bit in bottom of dist, need nb more.\n\t\t\textra := (dist & 1) << (nb & regSizeMaskUint32)\n\t\t\tfor fnb < nb {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<nb:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\textra |= fb & bitMask32[nb]\n\t\t\tfb >>= nb & regSizeMaskUint32\n\t\t\tfnb -= nb\n\t\t\tdist = 1<<((nb+1)&regSizeMaskUint32) + 1 + extra\n\t\t\t// slower: dist = bitMask32[nb+1] + 2 + extra\n\t\tdefault:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist too big:\", dist, maxNumDist)\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\t// No check on length; encoding can be prescient.\n\t\tif dist > uint32(dict.histSize()) {\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist > dict.histSize():\", dist, dict.histSize())\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\tf.copyLen, f.copyDist = length, int(dist)\n\t\tgoto copyHistory\n\t}\n\ncopyHistory:\n\t// Perform a backwards copy according to RFC section 3.2.3.\n\t{\n\t\tcnt := dict.tryWriteCopy(f.copyDist, f.copyLen)\n\t\tif cnt == 0 {\n\t\t\tcnt = dict.writeCopy(f.copyDist, f.copyLen)\n\t\t}\n\t\tf.copyLen -= cnt\n\n\t\tif dict.availWrite() == 0 || f.copyLen > 0 {\n\t\t\tf.toRead = dict.readFlush()\n\t\t\tf.step = huffmanStringsReader // We need to continue this work\n\t\t\tf.stepState = stateDict\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\t\tgoto readLiteral\n\t}\n\t// Not reached\n}\n\n// Decode a single Huffman block from f.\n// hl and hd are the Huffman states for the lit/length values\n// and the distance values, respectively. If hd == nil, using the\n// fixed distance encoding associated with fixed Huffman blocks.\nfunc (f *decompressor) huffmanGenericReader() {\n\tconst (\n\t\tstateInit = iota // Zero value must be stateInit\n\t\tstateDict\n\t)\n\tfr := f.r.(Reader)\n\n\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t// inline call to moreBits and reassign b,nb back to f on return.\n\tfnb, fb, dict := f.nb, f.b, &f.dict\n\n\tswitch f.stepState {\n\tcase stateInit:\n\t\tgoto readLiteral\n\tcase stateDict:\n\t\tgoto copyHistory\n\t}\n\nreadLiteral:\n\t// Read literal and/or (length, distance) according to RFC section 3.2.3.\n\t{\n\t\tvar v int\n\t\t{\n\t\t\t// Inlined v, err := f.huffSym(f.hl)\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hl.maxRead)\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hl.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hl.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hl.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tv = int(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar length int\n\t\tswitch {\n\t\tcase v < 256:\n\t\t\tdict.writeByte(byte(v))\n\t\t\tif dict.availWrite() == 0 {\n\t\t\t\tf.toRead = dict.readFlush()\n\t\t\t\tf.step = huffmanGenericReader\n\t\t\t\tf.stepState = stateInit\n\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\treturn\n\t\t\t}\n\t\t\tgoto readLiteral\n\t\tcase v == 256:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tf.finishBlock()\n\t\t\treturn\n\t\t// otherwise, reference to older data\n\t\tcase v < 265:\n\t\t\tlength = v - (257 - 3)\n\t\tcase v < maxNumLit:\n\t\t\tval := decCodeToLen[(v - 257)]\n\t\t\tlength = int(val.length) + 3\n\t\t\tn := uint(val.extra)\n\t\t\tfor fnb < n {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits n>0:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tlength += int(fb & bitMask32[n])\n\t\t\tfb >>= n & regSizeMaskUint32\n\t\t\tfnb -= n\n\t\tdefault:\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(v, \">= maxNumLit\")\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\n\t\tvar dist uint32\n\t\tif f.hd == nil {\n\t\t\tfor fnb < 5 {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<5:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tdist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3)))\n\t\t\tfb >>= 5\n\t\t\tfnb -= 5\n\t\t} else {\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hd.maxRead)\n\t\t\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t\t\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t\t\t// inline call to moreBits and reassign b,nb back to f on return.\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hd.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hd.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hd.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tdist = uint32(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tswitch {\n\t\tcase dist < 4:\n\t\t\tdist++\n\t\tcase dist < maxNumDist:\n\t\t\tnb := uint(dist-2) >> 1\n\t\t\t// have 1 bit in bottom of dist, need nb more.\n\t\t\textra := (dist & 1) << (nb & regSizeMaskUint32)\n\t\t\tfor fnb < nb {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<nb:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\textra |= fb & bitMask32[nb]\n\t\t\tfb >>= nb & regSizeMaskUint32\n\t\t\tfnb -= nb\n\t\t\tdist = 1<<((nb+1)&regSizeMaskUint32) + 1 + extra\n\t\t\t// slower: dist = bitMask32[nb+1] + 2 + extra\n\t\tdefault:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist too big:\", dist, maxNumDist)\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\t// No check on length; encoding can be prescient.\n\t\tif dist > uint32(dict.histSize()) {\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist > dict.histSize():\", dist, dict.histSize())\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\tf.copyLen, f.copyDist = length, int(dist)\n\t\tgoto copyHistory\n\t}\n\ncopyHistory:\n\t// Perform a backwards copy according to RFC section 3.2.3.\n\t{\n\t\tcnt := dict.tryWriteCopy(f.copyDist, f.copyLen)\n\t\tif cnt == 0 {\n\t\t\tcnt = dict.writeCopy(f.copyDist, f.copyLen)\n\t\t}\n\t\tf.copyLen -= cnt\n\n\t\tif dict.availWrite() == 0 || f.copyLen > 0 {\n\t\t\tf.toRead = dict.readFlush()\n\t\t\tf.step = huffmanGenericReader // We need to continue this work\n\t\t\tf.stepState = stateDict\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\t\tgoto readLiteral\n\t}\n\t// Not reached\n}\n\nfunc (f *decompressor) huffmanBlockDecoder() {\n\tswitch f.r.(type) {\n\tcase *bytes.Buffer:\n\t\tf.huffmanBytesBuffer()\n\tcase *bytes.Reader:\n\t\tf.huffmanBytesReader()\n\tcase *bufio.Reader:\n\t\tf.huffmanBufioReader()\n\tcase *strings.Reader:\n\t\tf.huffmanStringsReader()\n\tcase Reader:\n\t\tf.huffmanGenericReader()\n\tdefault:\n\t\tf.huffmanGenericReader()\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/level1.go",
    "content": "package flate\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/klauspost/compress/internal/le\"\n)\n\n// fastGen maintains the table for matches,\n// and the previous byte block for level 2.\n// This is the generic implementation.\ntype fastEncL1 struct {\n\tfastGen\n\ttable [tableSize]tableEntry\n}\n\n// EncodeL1 uses a similar algorithm to level 1\nfunc (e *fastEncL1) Encode(dst *tokens, src []byte) {\n\tconst (\n\t\tinputMargin            = 12 - 1\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t\thashBytes              = 5\n\t)\n\tif debugDeflate && e.cur < 0 {\n\t\tpanic(fmt.Sprint(\"e.cur < 0: \", e.cur))\n\t}\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= bufferReset {\n\t\tif len(e.hist) == 0 {\n\t\t\tfor i := range e.table[:] {\n\t\t\t\te.table[i] = tableEntry{}\n\t\t\t}\n\t\t\te.cur = maxMatchOffset\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - maxMatchOffset\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v <= minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\te.cur = maxMatchOffset\n\t}\n\n\ts := e.addBlock(src)\n\n\t// This check isn't in the Snappy implementation, but there, the caller\n\t// instead of the callee handles this case.\n\tif len(src) < minNonLiteralBlockSize {\n\t\t// We do not fill the token table.\n\t\t// This will be picked up by caller.\n\t\tdst.n = uint16(len(src))\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tnextEmit := s\n\n\t// sLimit is when to stop looking for offset/length copies. The inputMargin\n\t// lets us use a fast path for emitLiteral in the main loop, while we are\n\t// looking for copies.\n\tsLimit := int32(len(src) - inputMargin)\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tcv := load6432(src, s)\n\n\tfor {\n\t\tconst skipLog = 5\n\t\tconst doEvery = 2\n\n\t\tnextS := s\n\t\tvar candidate tableEntry\n\t\tvar t int32\n\t\tfor {\n\t\t\tnextHash := hashLen(cv, tableBits, hashBytes)\n\t\t\tcandidate = e.table[nextHash]\n\t\t\tnextS = s + doEvery + (s-nextEmit)>>skipLog\n\t\t\tif nextS > sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\n\t\t\tnow := load6432(src, nextS)\n\t\t\te.table[nextHash] = tableEntry{offset: s + e.cur}\n\t\t\tnextHash = hashLen(now, tableBits, hashBytes)\n\t\t\tt = candidate.offset - e.cur\n\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, t) {\n\t\t\t\te.table[nextHash] = tableEntry{offset: nextS + e.cur}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Do one right away...\n\t\t\tcv = now\n\t\t\ts = nextS\n\t\t\tnextS++\n\t\t\tcandidate = e.table[nextHash]\n\t\t\tnow >>= 8\n\t\t\te.table[nextHash] = tableEntry{offset: s + e.cur}\n\n\t\t\tt = candidate.offset - e.cur\n\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, t) {\n\t\t\t\te.table[nextHash] = tableEntry{offset: nextS + e.cur}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcv = now\n\t\t\ts = nextS\n\t\t}\n\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes\n\t\t// match. But, prior to the match, src[nextEmit:s] are unmatched. Emit\n\t\t// them as literal bytes.\n\t\tfor {\n\t\t\t// Invariant: we have a 4-byte match at s, and no need to emit any\n\t\t\t// literal bytes prior to s.\n\n\t\t\t// Extend the 4-byte match as long as possible.\n\t\t\tl := e.matchlenLong(int(s+4), int(t+4), src) + 4\n\n\t\t\t// Extend backwards\n\t\t\tfor t > 0 && s > nextEmit && le.Load8(src, t-1) == le.Load8(src, s-1) {\n\t\t\t\ts--\n\t\t\t\tt--\n\t\t\t\tl++\n\t\t\t}\n\t\t\tif nextEmit < s {\n\t\t\t\tif false {\n\t\t\t\t\temitLiteral(dst, src[nextEmit:s])\n\t\t\t\t} else {\n\t\t\t\t\tfor _, v := range src[nextEmit:s] {\n\t\t\t\t\t\tdst.tokens[dst.n] = token(v)\n\t\t\t\t\t\tdst.litHist[v]++\n\t\t\t\t\t\tdst.n++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Save the match found\n\t\t\tif false {\n\t\t\t\tdst.AddMatchLong(l, uint32(s-t-baseMatchOffset))\n\t\t\t} else {\n\t\t\t\t// Inlined...\n\t\t\t\txoffset := uint32(s - t - baseMatchOffset)\n\t\t\t\txlength := l\n\t\t\t\toc := offsetCode(xoffset)\n\t\t\t\txoffset |= oc << 16\n\t\t\t\tfor xlength > 0 {\n\t\t\t\t\txl := xlength\n\t\t\t\t\tif xl > 258 {\n\t\t\t\t\t\tif xl > 258+baseMatchLength {\n\t\t\t\t\t\t\txl = 258\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\txl = 258 - baseMatchLength\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\txlength -= xl\n\t\t\t\t\txl -= baseMatchLength\n\t\t\t\t\tdst.extraHist[lengthCodes1[uint8(xl)]]++\n\t\t\t\t\tdst.offHist[oc]++\n\t\t\t\t\tdst.tokens[dst.n] = token(matchType | uint32(xl)<<lengthShift | xoffset)\n\t\t\t\t\tdst.n++\n\t\t\t\t}\n\t\t\t}\n\t\t\ts += l\n\t\t\tnextEmit = s\n\t\t\tif nextS >= s {\n\t\t\t\ts = nextS + 1\n\t\t\t}\n\t\t\tif s >= sLimit {\n\t\t\t\t// Index first pair after match end.\n\t\t\t\tif int(s+l+8) < len(src) {\n\t\t\t\t\tcv := load6432(src, s)\n\t\t\t\t\te.table[hashLen(cv, tableBits, hashBytes)] = tableEntry{offset: s + e.cur}\n\t\t\t\t}\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\n\t\t\t// We could immediately start working at s now, but to improve\n\t\t\t// compression we first update the hash table at s-2 and at s. If\n\t\t\t// another emitCopy is not our next move, also calculate nextHash\n\t\t\t// at s+1. At least on GOARCH=amd64, these three hash calculations\n\t\t\t// are faster as one load64 call (with some shifts) instead of\n\t\t\t// three load32 calls.\n\t\t\tx := load6432(src, s-2)\n\t\t\to := e.cur + s - 2\n\t\t\tprevHash := hashLen(x, tableBits, hashBytes)\n\t\t\te.table[prevHash] = tableEntry{offset: o}\n\t\t\tx >>= 16\n\t\t\tcurrHash := hashLen(x, tableBits, hashBytes)\n\t\t\tcandidate = e.table[currHash]\n\t\t\te.table[currHash] = tableEntry{offset: o + 2}\n\n\t\t\tt = candidate.offset - e.cur\n\t\t\tif s-t > maxMatchOffset || uint32(x) != load3232(src, t) {\n\t\t\t\tcv = x >> 8\n\t\t\t\ts++\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\nemitRemainder:\n\tif int(nextEmit) < len(src) {\n\t\t// If nothing was added, don't encode literals.\n\t\tif dst.n == 0 {\n\t\t\treturn\n\t\t}\n\t\temitLiteral(dst, src[nextEmit:])\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/level2.go",
    "content": "package flate\n\nimport \"fmt\"\n\n// fastGen maintains the table for matches,\n// and the previous byte block for level 2.\n// This is the generic implementation.\ntype fastEncL2 struct {\n\tfastGen\n\ttable [bTableSize]tableEntry\n}\n\n// EncodeL2 uses a similar algorithm to level 1, but is capable\n// of matching across blocks giving better compression at a small slowdown.\nfunc (e *fastEncL2) Encode(dst *tokens, src []byte) {\n\tconst (\n\t\tinputMargin            = 12 - 1\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t\thashBytes              = 5\n\t)\n\n\tif debugDeflate && e.cur < 0 {\n\t\tpanic(fmt.Sprint(\"e.cur < 0: \", e.cur))\n\t}\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= bufferReset {\n\t\tif len(e.hist) == 0 {\n\t\t\tfor i := range e.table[:] {\n\t\t\t\te.table[i] = tableEntry{}\n\t\t\t}\n\t\t\te.cur = maxMatchOffset\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - maxMatchOffset\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v <= minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\te.cur = maxMatchOffset\n\t}\n\n\ts := e.addBlock(src)\n\n\t// This check isn't in the Snappy implementation, but there, the caller\n\t// instead of the callee handles this case.\n\tif len(src) < minNonLiteralBlockSize {\n\t\t// We do not fill the token table.\n\t\t// This will be picked up by caller.\n\t\tdst.n = uint16(len(src))\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tnextEmit := s\n\n\t// sLimit is when to stop looking for offset/length copies. The inputMargin\n\t// lets us use a fast path for emitLiteral in the main loop, while we are\n\t// looking for copies.\n\tsLimit := int32(len(src) - inputMargin)\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tcv := load6432(src, s)\n\tfor {\n\t\t// When should we start skipping if we haven't found matches in a long while.\n\t\tconst skipLog = 5\n\t\tconst doEvery = 2\n\n\t\tnextS := s\n\t\tvar candidate tableEntry\n\t\tfor {\n\t\t\tnextHash := hashLen(cv, bTableBits, hashBytes)\n\t\t\ts = nextS\n\t\t\tnextS = s + doEvery + (s-nextEmit)>>skipLog\n\t\t\tif nextS > sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\t\t\tcandidate = e.table[nextHash]\n\t\t\tnow := load6432(src, nextS)\n\t\t\te.table[nextHash] = tableEntry{offset: s + e.cur}\n\t\t\tnextHash = hashLen(now, bTableBits, hashBytes)\n\n\t\t\toffset := s - (candidate.offset - e.cur)\n\t\t\tif offset < maxMatchOffset && uint32(cv) == load3232(src, candidate.offset-e.cur) {\n\t\t\t\te.table[nextHash] = tableEntry{offset: nextS + e.cur}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Do one right away...\n\t\t\tcv = now\n\t\t\ts = nextS\n\t\t\tnextS++\n\t\t\tcandidate = e.table[nextHash]\n\t\t\tnow >>= 8\n\t\t\te.table[nextHash] = tableEntry{offset: s + e.cur}\n\n\t\t\toffset = s - (candidate.offset - e.cur)\n\t\t\tif offset < maxMatchOffset && uint32(cv) == load3232(src, candidate.offset-e.cur) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcv = now\n\t\t}\n\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes\n\t\t// match. But, prior to the match, src[nextEmit:s] are unmatched. Emit\n\t\t// them as literal bytes.\n\n\t\t// Call emitCopy, and then see if another emitCopy could be our next\n\t\t// move. Repeat until we find no match for the input immediately after\n\t\t// what was consumed by the last emitCopy call.\n\t\t//\n\t\t// If we exit this loop normally then we need to call emitLiteral next,\n\t\t// though we don't yet know how big the literal will be. We handle that\n\t\t// by proceeding to the next iteration of the main loop. We also can\n\t\t// exit this loop via goto if we get close to exhausting the input.\n\t\tfor {\n\t\t\t// Invariant: we have a 4-byte match at s, and no need to emit any\n\t\t\t// literal bytes prior to s.\n\n\t\t\t// Extend the 4-byte match as long as possible.\n\t\t\tt := candidate.offset - e.cur\n\t\t\tl := e.matchlenLong(int(s+4), int(t+4), src) + 4\n\n\t\t\t// Extend backwards\n\t\t\tfor t > 0 && s > nextEmit && src[t-1] == src[s-1] {\n\t\t\t\ts--\n\t\t\t\tt--\n\t\t\t\tl++\n\t\t\t}\n\t\t\tif nextEmit < s {\n\t\t\t\tif false {\n\t\t\t\t\temitLiteral(dst, src[nextEmit:s])\n\t\t\t\t} else {\n\t\t\t\t\tfor _, v := range src[nextEmit:s] {\n\t\t\t\t\t\tdst.tokens[dst.n] = token(v)\n\t\t\t\t\t\tdst.litHist[v]++\n\t\t\t\t\t\tdst.n++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdst.AddMatchLong(l, uint32(s-t-baseMatchOffset))\n\t\t\ts += l\n\t\t\tnextEmit = s\n\t\t\tif nextS >= s {\n\t\t\t\ts = nextS + 1\n\t\t\t}\n\n\t\t\tif s >= sLimit {\n\t\t\t\t// Index first pair after match end.\n\t\t\t\tif int(s+l+8) < len(src) {\n\t\t\t\t\tcv := load6432(src, s)\n\t\t\t\t\te.table[hashLen(cv, bTableBits, hashBytes)] = tableEntry{offset: s + e.cur}\n\t\t\t\t}\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\n\t\t\t// Store every second hash in-between, but offset by 1.\n\t\t\tfor i := s - l + 2; i < s-5; i += 7 {\n\t\t\t\tx := load6432(src, i)\n\t\t\t\tnextHash := hashLen(x, bTableBits, hashBytes)\n\t\t\t\te.table[nextHash] = tableEntry{offset: e.cur + i}\n\t\t\t\t// Skip one\n\t\t\t\tx >>= 16\n\t\t\t\tnextHash = hashLen(x, bTableBits, hashBytes)\n\t\t\t\te.table[nextHash] = tableEntry{offset: e.cur + i + 2}\n\t\t\t\t// Skip one\n\t\t\t\tx >>= 16\n\t\t\t\tnextHash = hashLen(x, bTableBits, hashBytes)\n\t\t\t\te.table[nextHash] = tableEntry{offset: e.cur + i + 4}\n\t\t\t}\n\n\t\t\t// We could immediately start working at s now, but to improve\n\t\t\t// compression we first update the hash table at s-2 to s. If\n\t\t\t// another emitCopy is not our next move, also calculate nextHash\n\t\t\t// at s+1. At least on GOARCH=amd64, these three hash calculations\n\t\t\t// are faster as one load64 call (with some shifts) instead of\n\t\t\t// three load32 calls.\n\t\t\tx := load6432(src, s-2)\n\t\t\to := e.cur + s - 2\n\t\t\tprevHash := hashLen(x, bTableBits, hashBytes)\n\t\t\tprevHash2 := hashLen(x>>8, bTableBits, hashBytes)\n\t\t\te.table[prevHash] = tableEntry{offset: o}\n\t\t\te.table[prevHash2] = tableEntry{offset: o + 1}\n\t\t\tcurrHash := hashLen(x>>16, bTableBits, hashBytes)\n\t\t\tcandidate = e.table[currHash]\n\t\t\te.table[currHash] = tableEntry{offset: o + 2}\n\n\t\t\toffset := s - (candidate.offset - e.cur)\n\t\t\tif offset > maxMatchOffset || uint32(x>>16) != load3232(src, candidate.offset-e.cur) {\n\t\t\t\tcv = x >> 24\n\t\t\t\ts++\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\nemitRemainder:\n\tif int(nextEmit) < len(src) {\n\t\t// If nothing was added, don't encode literals.\n\t\tif dst.n == 0 {\n\t\t\treturn\n\t\t}\n\n\t\temitLiteral(dst, src[nextEmit:])\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/level3.go",
    "content": "package flate\n\nimport \"fmt\"\n\n// fastEncL3\ntype fastEncL3 struct {\n\tfastGen\n\ttable [1 << 16]tableEntryPrev\n}\n\n// Encode uses a similar algorithm to level 2, will check up to two candidates.\nfunc (e *fastEncL3) Encode(dst *tokens, src []byte) {\n\tconst (\n\t\tinputMargin            = 12 - 1\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t\ttableBits              = 16\n\t\ttableSize              = 1 << tableBits\n\t\thashBytes              = 5\n\t)\n\n\tif debugDeflate && e.cur < 0 {\n\t\tpanic(fmt.Sprint(\"e.cur < 0: \", e.cur))\n\t}\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= bufferReset {\n\t\tif len(e.hist) == 0 {\n\t\t\tfor i := range e.table[:] {\n\t\t\t\te.table[i] = tableEntryPrev{}\n\t\t\t}\n\t\t\te.cur = maxMatchOffset\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - maxMatchOffset\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i]\n\t\t\tif v.Cur.offset <= minOff {\n\t\t\t\tv.Cur.offset = 0\n\t\t\t} else {\n\t\t\t\tv.Cur.offset = v.Cur.offset - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\tif v.Prev.offset <= minOff {\n\t\t\t\tv.Prev.offset = 0\n\t\t\t} else {\n\t\t\t\tv.Prev.offset = v.Prev.offset - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\te.table[i] = v\n\t\t}\n\t\te.cur = maxMatchOffset\n\t}\n\n\ts := e.addBlock(src)\n\n\t// Skip if too small.\n\tif len(src) < minNonLiteralBlockSize {\n\t\t// We do not fill the token table.\n\t\t// This will be picked up by caller.\n\t\tdst.n = uint16(len(src))\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tnextEmit := s\n\n\t// sLimit is when to stop looking for offset/length copies. The inputMargin\n\t// lets us use a fast path for emitLiteral in the main loop, while we are\n\t// looking for copies.\n\tsLimit := int32(len(src) - inputMargin)\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tcv := load6432(src, s)\n\tfor {\n\t\tconst skipLog = 7\n\t\tnextS := s\n\t\tvar candidate tableEntry\n\t\tfor {\n\t\t\tnextHash := hashLen(cv, tableBits, hashBytes)\n\t\t\ts = nextS\n\t\t\tnextS = s + 1 + (s-nextEmit)>>skipLog\n\t\t\tif nextS > sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\t\t\tcandidates := e.table[nextHash]\n\t\t\tnow := load6432(src, nextS)\n\n\t\t\t// Safe offset distance until s + 4...\n\t\t\tminOffset := e.cur + s - (maxMatchOffset - 4)\n\t\t\te.table[nextHash] = tableEntryPrev{Prev: candidates.Cur, Cur: tableEntry{offset: s + e.cur}}\n\n\t\t\t// Check both candidates\n\t\t\tcandidate = candidates.Cur\n\t\t\tif candidate.offset < minOffset {\n\t\t\t\tcv = now\n\t\t\t\t// Previous will also be invalid, we have nothing.\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif uint32(cv) == load3232(src, candidate.offset-e.cur) {\n\t\t\t\tif candidates.Prev.offset < minOffset || uint32(cv) != load3232(src, candidates.Prev.offset-e.cur) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\t// Both match and are valid, pick longest.\n\t\t\t\toffset := s - (candidate.offset - e.cur)\n\t\t\t\to2 := s - (candidates.Prev.offset - e.cur)\n\t\t\t\tl1, l2 := matchLen(src[s+4:], src[s-offset+4:]), matchLen(src[s+4:], src[s-o2+4:])\n\t\t\t\tif l2 > l1 {\n\t\t\t\t\tcandidate = candidates.Prev\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t} else {\n\t\t\t\t// We only check if value mismatches.\n\t\t\t\t// Offset will always be invalid in other cases.\n\t\t\t\tcandidate = candidates.Prev\n\t\t\t\tif candidate.offset > minOffset && uint32(cv) == load3232(src, candidate.offset-e.cur) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tcv = now\n\t\t}\n\n\t\t// Call emitCopy, and then see if another emitCopy could be our next\n\t\t// move. Repeat until we find no match for the input immediately after\n\t\t// what was consumed by the last emitCopy call.\n\t\t//\n\t\t// If we exit this loop normally then we need to call emitLiteral next,\n\t\t// though we don't yet know how big the literal will be. We handle that\n\t\t// by proceeding to the next iteration of the main loop. We also can\n\t\t// exit this loop via goto if we get close to exhausting the input.\n\t\tfor {\n\t\t\t// Invariant: we have a 4-byte match at s, and no need to emit any\n\t\t\t// literal bytes prior to s.\n\n\t\t\t// Extend the 4-byte match as long as possible.\n\t\t\t//\n\t\t\tt := candidate.offset - e.cur\n\t\t\tl := e.matchlenLong(int(s+4), int(t+4), src) + 4\n\n\t\t\t// Extend backwards\n\t\t\tfor t > 0 && s > nextEmit && src[t-1] == src[s-1] {\n\t\t\t\ts--\n\t\t\t\tt--\n\t\t\t\tl++\n\t\t\t}\n\t\t\tif nextEmit < s {\n\t\t\t\tif false {\n\t\t\t\t\temitLiteral(dst, src[nextEmit:s])\n\t\t\t\t} else {\n\t\t\t\t\tfor _, v := range src[nextEmit:s] {\n\t\t\t\t\t\tdst.tokens[dst.n] = token(v)\n\t\t\t\t\t\tdst.litHist[v]++\n\t\t\t\t\t\tdst.n++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdst.AddMatchLong(l, uint32(s-t-baseMatchOffset))\n\t\t\ts += l\n\t\t\tnextEmit = s\n\t\t\tif nextS >= s {\n\t\t\t\ts = nextS + 1\n\t\t\t}\n\n\t\t\tif s >= sLimit {\n\t\t\t\tt += l\n\t\t\t\t// Index first pair after match end.\n\t\t\t\tif int(t+8) < len(src) && t > 0 {\n\t\t\t\t\tcv = load6432(src, t)\n\t\t\t\t\tnextHash := hashLen(cv, tableBits, hashBytes)\n\t\t\t\t\te.table[nextHash] = tableEntryPrev{\n\t\t\t\t\t\tPrev: e.table[nextHash].Cur,\n\t\t\t\t\t\tCur:  tableEntry{offset: e.cur + t},\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\n\t\t\t// Store every 5th hash in-between.\n\t\t\tfor i := s - l + 2; i < s-5; i += 6 {\n\t\t\t\tnextHash := hashLen(load6432(src, i), tableBits, hashBytes)\n\t\t\t\te.table[nextHash] = tableEntryPrev{\n\t\t\t\t\tPrev: e.table[nextHash].Cur,\n\t\t\t\t\tCur:  tableEntry{offset: e.cur + i}}\n\t\t\t}\n\t\t\t// We could immediately start working at s now, but to improve\n\t\t\t// compression we first update the hash table at s-2 to s.\n\t\t\tx := load6432(src, s-2)\n\t\t\tprevHash := hashLen(x, tableBits, hashBytes)\n\n\t\t\te.table[prevHash] = tableEntryPrev{\n\t\t\t\tPrev: e.table[prevHash].Cur,\n\t\t\t\tCur:  tableEntry{offset: e.cur + s - 2},\n\t\t\t}\n\t\t\tx >>= 8\n\t\t\tprevHash = hashLen(x, tableBits, hashBytes)\n\n\t\t\te.table[prevHash] = tableEntryPrev{\n\t\t\t\tPrev: e.table[prevHash].Cur,\n\t\t\t\tCur:  tableEntry{offset: e.cur + s - 1},\n\t\t\t}\n\t\t\tx >>= 8\n\t\t\tcurrHash := hashLen(x, tableBits, hashBytes)\n\t\t\tcandidates := e.table[currHash]\n\t\t\tcv = x\n\t\t\te.table[currHash] = tableEntryPrev{\n\t\t\t\tPrev: candidates.Cur,\n\t\t\t\tCur:  tableEntry{offset: s + e.cur},\n\t\t\t}\n\n\t\t\t// Check both candidates\n\t\t\tcandidate = candidates.Cur\n\t\t\tminOffset := e.cur + s - (maxMatchOffset - 4)\n\n\t\t\tif candidate.offset > minOffset {\n\t\t\t\tif uint32(cv) == load3232(src, candidate.offset-e.cur) {\n\t\t\t\t\t// Found a match...\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tcandidate = candidates.Prev\n\t\t\t\tif candidate.offset > minOffset && uint32(cv) == load3232(src, candidate.offset-e.cur) {\n\t\t\t\t\t// Match at prev...\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tcv = x >> 8\n\t\t\ts++\n\t\t\tbreak\n\t\t}\n\t}\n\nemitRemainder:\n\tif int(nextEmit) < len(src) {\n\t\t// If nothing was added, don't encode literals.\n\t\tif dst.n == 0 {\n\t\t\treturn\n\t\t}\n\n\t\temitLiteral(dst, src[nextEmit:])\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/level4.go",
    "content": "package flate\n\nimport \"fmt\"\n\ntype fastEncL4 struct {\n\tfastGen\n\ttable  [tableSize]tableEntry\n\tbTable [tableSize]tableEntry\n}\n\nfunc (e *fastEncL4) Encode(dst *tokens, src []byte) {\n\tconst (\n\t\tinputMargin            = 12 - 1\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t\thashShortBytes         = 4\n\t)\n\tif debugDeflate && e.cur < 0 {\n\t\tpanic(fmt.Sprint(\"e.cur < 0: \", e.cur))\n\t}\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= bufferReset {\n\t\tif len(e.hist) == 0 {\n\t\t\tfor i := range e.table[:] {\n\t\t\t\te.table[i] = tableEntry{}\n\t\t\t}\n\t\t\tfor i := range e.bTable[:] {\n\t\t\t\te.bTable[i] = tableEntry{}\n\t\t\t}\n\t\t\te.cur = maxMatchOffset\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - maxMatchOffset\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v <= minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\tfor i := range e.bTable[:] {\n\t\t\tv := e.bTable[i].offset\n\t\t\tif v <= minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\te.bTable[i].offset = v\n\t\t}\n\t\te.cur = maxMatchOffset\n\t}\n\n\ts := e.addBlock(src)\n\n\t// This check isn't in the Snappy implementation, but there, the caller\n\t// instead of the callee handles this case.\n\tif len(src) < minNonLiteralBlockSize {\n\t\t// We do not fill the token table.\n\t\t// This will be picked up by caller.\n\t\tdst.n = uint16(len(src))\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tnextEmit := s\n\n\t// sLimit is when to stop looking for offset/length copies. The inputMargin\n\t// lets us use a fast path for emitLiteral in the main loop, while we are\n\t// looking for copies.\n\tsLimit := int32(len(src) - inputMargin)\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tcv := load6432(src, s)\n\tfor {\n\t\tconst skipLog = 6\n\t\tconst doEvery = 1\n\n\t\tnextS := s\n\t\tvar t int32\n\t\tfor {\n\t\t\tnextHashS := hashLen(cv, tableBits, hashShortBytes)\n\t\t\tnextHashL := hash7(cv, tableBits)\n\n\t\t\ts = nextS\n\t\t\tnextS = s + doEvery + (s-nextEmit)>>skipLog\n\t\t\tif nextS > sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\t\t\t// Fetch a short+long candidate\n\t\t\tsCandidate := e.table[nextHashS]\n\t\t\tlCandidate := e.bTable[nextHashL]\n\t\t\tnext := load6432(src, nextS)\n\t\t\tentry := tableEntry{offset: s + e.cur}\n\t\t\te.table[nextHashS] = entry\n\t\t\te.bTable[nextHashL] = entry\n\n\t\t\tt = lCandidate.offset - e.cur\n\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, t) {\n\t\t\t\t// We got a long match. Use that.\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tt = sCandidate.offset - e.cur\n\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, t) {\n\t\t\t\t// Found a 4 match...\n\t\t\t\tlCandidate = e.bTable[hash7(next, tableBits)]\n\n\t\t\t\t// If the next long is a candidate, check if we should use that instead...\n\t\t\t\tlOff := lCandidate.offset - e.cur\n\t\t\t\tif nextS-lOff < maxMatchOffset && load3232(src, lOff) == uint32(next) {\n\t\t\t\t\tl1, l2 := matchLen(src[s+4:], src[t+4:]), matchLen(src[nextS+4:], src[nextS-lOff+4:])\n\t\t\t\t\tif l2 > l1 {\n\t\t\t\t\t\ts = nextS\n\t\t\t\t\t\tt = lCandidate.offset - e.cur\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcv = next\n\t\t}\n\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes\n\t\t// match. But, prior to the match, src[nextEmit:s] are unmatched. Emit\n\t\t// them as literal bytes.\n\n\t\t// Extend the 4-byte match as long as possible.\n\t\tl := e.matchlenLong(int(s+4), int(t+4), src) + 4\n\n\t\t// Extend backwards\n\t\tfor t > 0 && s > nextEmit && src[t-1] == src[s-1] {\n\t\t\ts--\n\t\t\tt--\n\t\t\tl++\n\t\t}\n\t\tif nextEmit < s {\n\t\t\tif false {\n\t\t\t\temitLiteral(dst, src[nextEmit:s])\n\t\t\t} else {\n\t\t\t\tfor _, v := range src[nextEmit:s] {\n\t\t\t\t\tdst.tokens[dst.n] = token(v)\n\t\t\t\t\tdst.litHist[v]++\n\t\t\t\t\tdst.n++\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif debugDeflate {\n\t\t\tif t >= s {\n\t\t\t\tpanic(\"s-t\")\n\t\t\t}\n\t\t\tif (s - t) > maxMatchOffset {\n\t\t\t\tpanic(fmt.Sprintln(\"mmo\", t))\n\t\t\t}\n\t\t\tif l < baseMatchLength {\n\t\t\t\tpanic(\"bml\")\n\t\t\t}\n\t\t}\n\n\t\tdst.AddMatchLong(l, uint32(s-t-baseMatchOffset))\n\t\ts += l\n\t\tnextEmit = s\n\t\tif nextS >= s {\n\t\t\ts = nextS + 1\n\t\t}\n\n\t\tif s >= sLimit {\n\t\t\t// Index first pair after match end.\n\t\t\tif int(s+8) < len(src) {\n\t\t\t\tcv := load6432(src, s)\n\t\t\t\te.table[hashLen(cv, tableBits, hashShortBytes)] = tableEntry{offset: s + e.cur}\n\t\t\t\te.bTable[hash7(cv, tableBits)] = tableEntry{offset: s + e.cur}\n\t\t\t}\n\t\t\tgoto emitRemainder\n\t\t}\n\n\t\t// Store every 3rd hash in-between\n\t\tif true {\n\t\t\ti := nextS\n\t\t\tif i < s-1 {\n\t\t\t\tcv := load6432(src, i)\n\t\t\t\tt := tableEntry{offset: i + e.cur}\n\t\t\t\tt2 := tableEntry{offset: t.offset + 1}\n\t\t\t\te.bTable[hash7(cv, tableBits)] = t\n\t\t\t\te.bTable[hash7(cv>>8, tableBits)] = t2\n\t\t\t\te.table[hashLen(cv>>8, tableBits, hashShortBytes)] = t2\n\n\t\t\t\ti += 3\n\t\t\t\tfor ; i < s-1; i += 3 {\n\t\t\t\t\tcv := load6432(src, i)\n\t\t\t\t\tt := tableEntry{offset: i + e.cur}\n\t\t\t\t\tt2 := tableEntry{offset: t.offset + 1}\n\t\t\t\t\te.bTable[hash7(cv, tableBits)] = t\n\t\t\t\t\te.bTable[hash7(cv>>8, tableBits)] = t2\n\t\t\t\t\te.table[hashLen(cv>>8, tableBits, hashShortBytes)] = t2\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// We could immediately start working at s now, but to improve\n\t\t// compression we first update the hash table at s-1 and at s.\n\t\tx := load6432(src, s-1)\n\t\to := e.cur + s - 1\n\t\tprevHashS := hashLen(x, tableBits, hashShortBytes)\n\t\tprevHashL := hash7(x, tableBits)\n\t\te.table[prevHashS] = tableEntry{offset: o}\n\t\te.bTable[prevHashL] = tableEntry{offset: o}\n\t\tcv = x >> 8\n\t}\n\nemitRemainder:\n\tif int(nextEmit) < len(src) {\n\t\t// If nothing was added, don't encode literals.\n\t\tif dst.n == 0 {\n\t\t\treturn\n\t\t}\n\n\t\temitLiteral(dst, src[nextEmit:])\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/level5.go",
    "content": "package flate\n\nimport \"fmt\"\n\ntype fastEncL5 struct {\n\tfastGen\n\ttable  [tableSize]tableEntry\n\tbTable [tableSize]tableEntryPrev\n}\n\nfunc (e *fastEncL5) Encode(dst *tokens, src []byte) {\n\tconst (\n\t\tinputMargin            = 12 - 1\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t\thashShortBytes         = 4\n\t)\n\tif debugDeflate && e.cur < 0 {\n\t\tpanic(fmt.Sprint(\"e.cur < 0: \", e.cur))\n\t}\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= bufferReset {\n\t\tif len(e.hist) == 0 {\n\t\t\tfor i := range e.table[:] {\n\t\t\t\te.table[i] = tableEntry{}\n\t\t\t}\n\t\t\tfor i := range e.bTable[:] {\n\t\t\t\te.bTable[i] = tableEntryPrev{}\n\t\t\t}\n\t\t\te.cur = maxMatchOffset\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - maxMatchOffset\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v <= minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\tfor i := range e.bTable[:] {\n\t\t\tv := e.bTable[i]\n\t\t\tif v.Cur.offset <= minOff {\n\t\t\t\tv.Cur.offset = 0\n\t\t\t\tv.Prev.offset = 0\n\t\t\t} else {\n\t\t\t\tv.Cur.offset = v.Cur.offset - e.cur + maxMatchOffset\n\t\t\t\tif v.Prev.offset <= minOff {\n\t\t\t\t\tv.Prev.offset = 0\n\t\t\t\t} else {\n\t\t\t\t\tv.Prev.offset = v.Prev.offset - e.cur + maxMatchOffset\n\t\t\t\t}\n\t\t\t}\n\t\t\te.bTable[i] = v\n\t\t}\n\t\te.cur = maxMatchOffset\n\t}\n\n\ts := e.addBlock(src)\n\n\t// This check isn't in the Snappy implementation, but there, the caller\n\t// instead of the callee handles this case.\n\tif len(src) < minNonLiteralBlockSize {\n\t\t// We do not fill the token table.\n\t\t// This will be picked up by caller.\n\t\tdst.n = uint16(len(src))\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tnextEmit := s\n\n\t// sLimit is when to stop looking for offset/length copies. The inputMargin\n\t// lets us use a fast path for emitLiteral in the main loop, while we are\n\t// looking for copies.\n\tsLimit := int32(len(src) - inputMargin)\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tcv := load6432(src, s)\n\tfor {\n\t\tconst skipLog = 6\n\t\tconst doEvery = 1\n\n\t\tnextS := s\n\t\tvar l int32\n\t\tvar t int32\n\t\tfor {\n\t\t\tnextHashS := hashLen(cv, tableBits, hashShortBytes)\n\t\t\tnextHashL := hash7(cv, tableBits)\n\n\t\t\ts = nextS\n\t\t\tnextS = s + doEvery + (s-nextEmit)>>skipLog\n\t\t\tif nextS > sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\t\t\t// Fetch a short+long candidate\n\t\t\tsCandidate := e.table[nextHashS]\n\t\t\tlCandidate := e.bTable[nextHashL]\n\t\t\tnext := load6432(src, nextS)\n\t\t\tentry := tableEntry{offset: s + e.cur}\n\t\t\te.table[nextHashS] = entry\n\t\t\teLong := &e.bTable[nextHashL]\n\t\t\teLong.Cur, eLong.Prev = entry, eLong.Cur\n\n\t\t\tnextHashS = hashLen(next, tableBits, hashShortBytes)\n\t\t\tnextHashL = hash7(next, tableBits)\n\n\t\t\tt = lCandidate.Cur.offset - e.cur\n\t\t\tif s-t < maxMatchOffset {\n\t\t\t\tif uint32(cv) == load3232(src, t) {\n\t\t\t\t\t// Store the next match\n\t\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\n\t\t\t\t\tt2 := lCandidate.Prev.offset - e.cur\n\t\t\t\t\tif s-t2 < maxMatchOffset && uint32(cv) == load3232(src, t2) {\n\t\t\t\t\t\tl = e.matchlen(int(s+4), int(t+4), src) + 4\n\t\t\t\t\t\tml1 := e.matchlen(int(s+4), int(t2+4), src) + 4\n\t\t\t\t\t\tif ml1 > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\tl = ml1\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tt = lCandidate.Prev.offset - e.cur\n\t\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, t) {\n\t\t\t\t\t// Store the next match\n\t\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tt = sCandidate.offset - e.cur\n\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, t) {\n\t\t\t\t// Found a 4 match...\n\t\t\t\tl = e.matchlen(int(s+4), int(t+4), src) + 4\n\t\t\t\tlCandidate = e.bTable[nextHashL]\n\t\t\t\t// Store the next match\n\n\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\n\t\t\t\t// If the next long is a candidate, use that...\n\t\t\t\tt2 := lCandidate.Cur.offset - e.cur\n\t\t\t\tif nextS-t2 < maxMatchOffset {\n\t\t\t\t\tif load3232(src, t2) == uint32(next) {\n\t\t\t\t\t\tml := e.matchlen(int(nextS+4), int(t2+4), src) + 4\n\t\t\t\t\t\tif ml > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\ts = nextS\n\t\t\t\t\t\t\tl = ml\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// If the previous long is a candidate, use that...\n\t\t\t\t\tt2 = lCandidate.Prev.offset - e.cur\n\t\t\t\t\tif nextS-t2 < maxMatchOffset && load3232(src, t2) == uint32(next) {\n\t\t\t\t\t\tml := e.matchlen(int(nextS+4), int(t2+4), src) + 4\n\t\t\t\t\t\tif ml > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\ts = nextS\n\t\t\t\t\t\t\tl = ml\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcv = next\n\t\t}\n\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes\n\t\t// match. But, prior to the match, src[nextEmit:s] are unmatched. Emit\n\t\t// them as literal bytes.\n\n\t\tif l == 0 {\n\t\t\t// Extend the 4-byte match as long as possible.\n\t\t\tl = e.matchlenLong(int(s+4), int(t+4), src) + 4\n\t\t} else if l == maxMatchLength {\n\t\t\tl += e.matchlenLong(int(s+l), int(t+l), src)\n\t\t}\n\n\t\t// Try to locate a better match by checking the end of best match...\n\t\tif sAt := s + l; l < 30 && sAt < sLimit {\n\t\t\t// Allow some bytes at the beginning to mismatch.\n\t\t\t// Sweet spot is 2/3 bytes depending on input.\n\t\t\t// 3 is only a little better when it is but sometimes a lot worse.\n\t\t\t// The skipped bytes are tested in Extend backwards,\n\t\t\t// and still picked up as part of the match if they do.\n\t\t\tconst skipBeginning = 2\n\t\t\teLong := e.bTable[hash7(load6432(src, sAt), tableBits)].Cur.offset\n\t\t\tt2 := eLong - e.cur - l + skipBeginning\n\t\t\ts2 := s + skipBeginning\n\t\t\toff := s2 - t2\n\t\t\tif t2 >= 0 && off < maxMatchOffset && off > 0 {\n\t\t\t\tif l2 := e.matchlenLong(int(s2), int(t2), src); l2 > l {\n\t\t\t\t\tt = t2\n\t\t\t\t\tl = l2\n\t\t\t\t\ts = s2\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Extend backwards\n\t\tfor t > 0 && s > nextEmit && src[t-1] == src[s-1] {\n\t\t\ts--\n\t\t\tt--\n\t\t\tl++\n\t\t}\n\t\tif nextEmit < s {\n\t\t\tif false {\n\t\t\t\temitLiteral(dst, src[nextEmit:s])\n\t\t\t} else {\n\t\t\t\tfor _, v := range src[nextEmit:s] {\n\t\t\t\t\tdst.tokens[dst.n] = token(v)\n\t\t\t\t\tdst.litHist[v]++\n\t\t\t\t\tdst.n++\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif debugDeflate {\n\t\t\tif t >= s {\n\t\t\t\tpanic(fmt.Sprintln(\"s-t\", s, t))\n\t\t\t}\n\t\t\tif (s - t) > maxMatchOffset {\n\t\t\t\tpanic(fmt.Sprintln(\"mmo\", s-t))\n\t\t\t}\n\t\t\tif l < baseMatchLength {\n\t\t\t\tpanic(\"bml\")\n\t\t\t}\n\t\t}\n\n\t\tdst.AddMatchLong(l, uint32(s-t-baseMatchOffset))\n\t\ts += l\n\t\tnextEmit = s\n\t\tif nextS >= s {\n\t\t\ts = nextS + 1\n\t\t}\n\n\t\tif s >= sLimit {\n\t\t\tgoto emitRemainder\n\t\t}\n\n\t\t// Store every 3rd hash in-between.\n\t\tif true {\n\t\t\tconst hashEvery = 3\n\t\t\ti := s - l + 1\n\t\t\tif i < s-1 {\n\t\t\t\tcv := load6432(src, i)\n\t\t\t\tt := tableEntry{offset: i + e.cur}\n\t\t\t\te.table[hashLen(cv, tableBits, hashShortBytes)] = t\n\t\t\t\teLong := &e.bTable[hash7(cv, tableBits)]\n\t\t\t\teLong.Cur, eLong.Prev = t, eLong.Cur\n\n\t\t\t\t// Do an long at i+1\n\t\t\t\tcv >>= 8\n\t\t\t\tt = tableEntry{offset: t.offset + 1}\n\t\t\t\teLong = &e.bTable[hash7(cv, tableBits)]\n\t\t\t\teLong.Cur, eLong.Prev = t, eLong.Cur\n\n\t\t\t\t// We only have enough bits for a short entry at i+2\n\t\t\t\tcv >>= 8\n\t\t\t\tt = tableEntry{offset: t.offset + 1}\n\t\t\t\te.table[hashLen(cv, tableBits, hashShortBytes)] = t\n\n\t\t\t\t// Skip one - otherwise we risk hitting 's'\n\t\t\t\ti += 4\n\t\t\t\tfor ; i < s-1; i += hashEvery {\n\t\t\t\t\tcv := load6432(src, i)\n\t\t\t\t\tt := tableEntry{offset: i + e.cur}\n\t\t\t\t\tt2 := tableEntry{offset: t.offset + 1}\n\t\t\t\t\teLong := &e.bTable[hash7(cv, tableBits)]\n\t\t\t\t\teLong.Cur, eLong.Prev = t, eLong.Cur\n\t\t\t\t\te.table[hashLen(cv>>8, tableBits, hashShortBytes)] = t2\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// We could immediately start working at s now, but to improve\n\t\t// compression we first update the hash table at s-1 and at s.\n\t\tx := load6432(src, s-1)\n\t\to := e.cur + s - 1\n\t\tprevHashS := hashLen(x, tableBits, hashShortBytes)\n\t\tprevHashL := hash7(x, tableBits)\n\t\te.table[prevHashS] = tableEntry{offset: o}\n\t\teLong := &e.bTable[prevHashL]\n\t\teLong.Cur, eLong.Prev = tableEntry{offset: o}, eLong.Cur\n\t\tcv = x >> 8\n\t}\n\nemitRemainder:\n\tif int(nextEmit) < len(src) {\n\t\t// If nothing was added, don't encode literals.\n\t\tif dst.n == 0 {\n\t\t\treturn\n\t\t}\n\n\t\temitLiteral(dst, src[nextEmit:])\n\t}\n}\n\n// fastEncL5Window is a level 5 encoder,\n// but with a custom window size.\ntype fastEncL5Window struct {\n\thist      []byte\n\tcur       int32\n\tmaxOffset int32\n\ttable     [tableSize]tableEntry\n\tbTable    [tableSize]tableEntryPrev\n}\n\nfunc (e *fastEncL5Window) Encode(dst *tokens, src []byte) {\n\tconst (\n\t\tinputMargin            = 12 - 1\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t\thashShortBytes         = 4\n\t)\n\tmaxMatchOffset := e.maxOffset\n\tif debugDeflate && e.cur < 0 {\n\t\tpanic(fmt.Sprint(\"e.cur < 0: \", e.cur))\n\t}\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= bufferReset {\n\t\tif len(e.hist) == 0 {\n\t\t\tfor i := range e.table[:] {\n\t\t\t\te.table[i] = tableEntry{}\n\t\t\t}\n\t\t\tfor i := range e.bTable[:] {\n\t\t\t\te.bTable[i] = tableEntryPrev{}\n\t\t\t}\n\t\t\te.cur = maxMatchOffset\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - maxMatchOffset\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v <= minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\tfor i := range e.bTable[:] {\n\t\t\tv := e.bTable[i]\n\t\t\tif v.Cur.offset <= minOff {\n\t\t\t\tv.Cur.offset = 0\n\t\t\t\tv.Prev.offset = 0\n\t\t\t} else {\n\t\t\t\tv.Cur.offset = v.Cur.offset - e.cur + maxMatchOffset\n\t\t\t\tif v.Prev.offset <= minOff {\n\t\t\t\t\tv.Prev.offset = 0\n\t\t\t\t} else {\n\t\t\t\t\tv.Prev.offset = v.Prev.offset - e.cur + maxMatchOffset\n\t\t\t\t}\n\t\t\t}\n\t\t\te.bTable[i] = v\n\t\t}\n\t\te.cur = maxMatchOffset\n\t}\n\n\ts := e.addBlock(src)\n\n\t// This check isn't in the Snappy implementation, but there, the caller\n\t// instead of the callee handles this case.\n\tif len(src) < minNonLiteralBlockSize {\n\t\t// We do not fill the token table.\n\t\t// This will be picked up by caller.\n\t\tdst.n = uint16(len(src))\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tnextEmit := s\n\n\t// sLimit is when to stop looking for offset/length copies. The inputMargin\n\t// lets us use a fast path for emitLiteral in the main loop, while we are\n\t// looking for copies.\n\tsLimit := int32(len(src) - inputMargin)\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tcv := load6432(src, s)\n\tfor {\n\t\tconst skipLog = 6\n\t\tconst doEvery = 1\n\n\t\tnextS := s\n\t\tvar l int32\n\t\tvar t int32\n\t\tfor {\n\t\t\tnextHashS := hashLen(cv, tableBits, hashShortBytes)\n\t\t\tnextHashL := hash7(cv, tableBits)\n\n\t\t\ts = nextS\n\t\t\tnextS = s + doEvery + (s-nextEmit)>>skipLog\n\t\t\tif nextS > sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\t\t\t// Fetch a short+long candidate\n\t\t\tsCandidate := e.table[nextHashS]\n\t\t\tlCandidate := e.bTable[nextHashL]\n\t\t\tnext := load6432(src, nextS)\n\t\t\tentry := tableEntry{offset: s + e.cur}\n\t\t\te.table[nextHashS] = entry\n\t\t\teLong := &e.bTable[nextHashL]\n\t\t\teLong.Cur, eLong.Prev = entry, eLong.Cur\n\n\t\t\tnextHashS = hashLen(next, tableBits, hashShortBytes)\n\t\t\tnextHashL = hash7(next, tableBits)\n\n\t\t\tt = lCandidate.Cur.offset - e.cur\n\t\t\tif s-t < maxMatchOffset {\n\t\t\t\tif uint32(cv) == load3232(src, t) {\n\t\t\t\t\t// Store the next match\n\t\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\n\t\t\t\t\tt2 := lCandidate.Prev.offset - e.cur\n\t\t\t\t\tif s-t2 < maxMatchOffset && uint32(cv) == load3232(src, t2) {\n\t\t\t\t\t\tl = e.matchlen(s+4, t+4, src) + 4\n\t\t\t\t\t\tml1 := e.matchlen(s+4, t2+4, src) + 4\n\t\t\t\t\t\tif ml1 > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\tl = ml1\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tt = lCandidate.Prev.offset - e.cur\n\t\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, t) {\n\t\t\t\t\t// Store the next match\n\t\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tt = sCandidate.offset - e.cur\n\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, t) {\n\t\t\t\t// Found a 4 match...\n\t\t\t\tl = e.matchlen(s+4, t+4, src) + 4\n\t\t\t\tlCandidate = e.bTable[nextHashL]\n\t\t\t\t// Store the next match\n\n\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\n\t\t\t\t// If the next long is a candidate, use that...\n\t\t\t\tt2 := lCandidate.Cur.offset - e.cur\n\t\t\t\tif nextS-t2 < maxMatchOffset {\n\t\t\t\t\tif load3232(src, t2) == uint32(next) {\n\t\t\t\t\t\tml := e.matchlen(nextS+4, t2+4, src) + 4\n\t\t\t\t\t\tif ml > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\ts = nextS\n\t\t\t\t\t\t\tl = ml\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// If the previous long is a candidate, use that...\n\t\t\t\t\tt2 = lCandidate.Prev.offset - e.cur\n\t\t\t\t\tif nextS-t2 < maxMatchOffset && load3232(src, t2) == uint32(next) {\n\t\t\t\t\t\tml := e.matchlen(nextS+4, t2+4, src) + 4\n\t\t\t\t\t\tif ml > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\ts = nextS\n\t\t\t\t\t\t\tl = ml\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcv = next\n\t\t}\n\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes\n\t\t// match. But, prior to the match, src[nextEmit:s] are unmatched. Emit\n\t\t// them as literal bytes.\n\n\t\tif l == 0 {\n\t\t\t// Extend the 4-byte match as long as possible.\n\t\t\tl = e.matchlenLong(s+4, t+4, src) + 4\n\t\t} else if l == maxMatchLength {\n\t\t\tl += e.matchlenLong(s+l, t+l, src)\n\t\t}\n\n\t\t// Try to locate a better match by checking the end of best match...\n\t\tif sAt := s + l; l < 30 && sAt < sLimit {\n\t\t\t// Allow some bytes at the beginning to mismatch.\n\t\t\t// Sweet spot is 2/3 bytes depending on input.\n\t\t\t// 3 is only a little better when it is but sometimes a lot worse.\n\t\t\t// The skipped bytes are tested in Extend backwards,\n\t\t\t// and still picked up as part of the match if they do.\n\t\t\tconst skipBeginning = 2\n\t\t\teLong := e.bTable[hash7(load6432(src, sAt), tableBits)].Cur.offset\n\t\t\tt2 := eLong - e.cur - l + skipBeginning\n\t\t\ts2 := s + skipBeginning\n\t\t\toff := s2 - t2\n\t\t\tif t2 >= 0 && off < maxMatchOffset && off > 0 {\n\t\t\t\tif l2 := e.matchlenLong(s2, t2, src); l2 > l {\n\t\t\t\t\tt = t2\n\t\t\t\t\tl = l2\n\t\t\t\t\ts = s2\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Extend backwards\n\t\tfor t > 0 && s > nextEmit && src[t-1] == src[s-1] {\n\t\t\ts--\n\t\t\tt--\n\t\t\tl++\n\t\t}\n\t\tif nextEmit < s {\n\t\t\tif false {\n\t\t\t\temitLiteral(dst, src[nextEmit:s])\n\t\t\t} else {\n\t\t\t\tfor _, v := range src[nextEmit:s] {\n\t\t\t\t\tdst.tokens[dst.n] = token(v)\n\t\t\t\t\tdst.litHist[v]++\n\t\t\t\t\tdst.n++\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif debugDeflate {\n\t\t\tif t >= s {\n\t\t\t\tpanic(fmt.Sprintln(\"s-t\", s, t))\n\t\t\t}\n\t\t\tif (s - t) > maxMatchOffset {\n\t\t\t\tpanic(fmt.Sprintln(\"mmo\", s-t))\n\t\t\t}\n\t\t\tif l < baseMatchLength {\n\t\t\t\tpanic(\"bml\")\n\t\t\t}\n\t\t}\n\n\t\tdst.AddMatchLong(l, uint32(s-t-baseMatchOffset))\n\t\ts += l\n\t\tnextEmit = s\n\t\tif nextS >= s {\n\t\t\ts = nextS + 1\n\t\t}\n\n\t\tif s >= sLimit {\n\t\t\tgoto emitRemainder\n\t\t}\n\n\t\t// Store every 3rd hash in-between.\n\t\tif true {\n\t\t\tconst hashEvery = 3\n\t\t\ti := s - l + 1\n\t\t\tif i < s-1 {\n\t\t\t\tcv := load6432(src, i)\n\t\t\t\tt := tableEntry{offset: i + e.cur}\n\t\t\t\te.table[hashLen(cv, tableBits, hashShortBytes)] = t\n\t\t\t\teLong := &e.bTable[hash7(cv, tableBits)]\n\t\t\t\teLong.Cur, eLong.Prev = t, eLong.Cur\n\n\t\t\t\t// Do an long at i+1\n\t\t\t\tcv >>= 8\n\t\t\t\tt = tableEntry{offset: t.offset + 1}\n\t\t\t\teLong = &e.bTable[hash7(cv, tableBits)]\n\t\t\t\teLong.Cur, eLong.Prev = t, eLong.Cur\n\n\t\t\t\t// We only have enough bits for a short entry at i+2\n\t\t\t\tcv >>= 8\n\t\t\t\tt = tableEntry{offset: t.offset + 1}\n\t\t\t\te.table[hashLen(cv, tableBits, hashShortBytes)] = t\n\n\t\t\t\t// Skip one - otherwise we risk hitting 's'\n\t\t\t\ti += 4\n\t\t\t\tfor ; i < s-1; i += hashEvery {\n\t\t\t\t\tcv := load6432(src, i)\n\t\t\t\t\tt := tableEntry{offset: i + e.cur}\n\t\t\t\t\tt2 := tableEntry{offset: t.offset + 1}\n\t\t\t\t\teLong := &e.bTable[hash7(cv, tableBits)]\n\t\t\t\t\teLong.Cur, eLong.Prev = t, eLong.Cur\n\t\t\t\t\te.table[hashLen(cv>>8, tableBits, hashShortBytes)] = t2\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// We could immediately start working at s now, but to improve\n\t\t// compression we first update the hash table at s-1 and at s.\n\t\tx := load6432(src, s-1)\n\t\to := e.cur + s - 1\n\t\tprevHashS := hashLen(x, tableBits, hashShortBytes)\n\t\tprevHashL := hash7(x, tableBits)\n\t\te.table[prevHashS] = tableEntry{offset: o}\n\t\teLong := &e.bTable[prevHashL]\n\t\teLong.Cur, eLong.Prev = tableEntry{offset: o}, eLong.Cur\n\t\tcv = x >> 8\n\t}\n\nemitRemainder:\n\tif int(nextEmit) < len(src) {\n\t\t// If nothing was added, don't encode literals.\n\t\tif dst.n == 0 {\n\t\t\treturn\n\t\t}\n\n\t\temitLiteral(dst, src[nextEmit:])\n\t}\n}\n\n// Reset the encoding table.\nfunc (e *fastEncL5Window) Reset() {\n\t// We keep the same allocs, since we are compressing the same block sizes.\n\tif cap(e.hist) < allocHistory {\n\t\te.hist = make([]byte, 0, allocHistory)\n\t}\n\n\t// We offset current position so everything will be out of reach.\n\t// If we are above the buffer reset it will be cleared anyway since len(hist) == 0.\n\tif e.cur <= int32(bufferReset) {\n\t\te.cur += e.maxOffset + int32(len(e.hist))\n\t}\n\te.hist = e.hist[:0]\n}\n\nfunc (e *fastEncL5Window) addBlock(src []byte) int32 {\n\t// check if we have space already\n\tmaxMatchOffset := e.maxOffset\n\n\tif len(e.hist)+len(src) > cap(e.hist) {\n\t\tif cap(e.hist) == 0 {\n\t\t\te.hist = make([]byte, 0, allocHistory)\n\t\t} else {\n\t\t\tif cap(e.hist) < int(maxMatchOffset*2) {\n\t\t\t\tpanic(\"unexpected buffer size\")\n\t\t\t}\n\t\t\t// Move down\n\t\t\toffset := int32(len(e.hist)) - maxMatchOffset\n\t\t\tcopy(e.hist[0:maxMatchOffset], e.hist[offset:])\n\t\t\te.cur += offset\n\t\t\te.hist = e.hist[:maxMatchOffset]\n\t\t}\n\t}\n\ts := int32(len(e.hist))\n\te.hist = append(e.hist, src...)\n\treturn s\n}\n\n// matchlen will return the match length between offsets and t in src.\n// The maximum length returned is maxMatchLength - 4.\n// It is assumed that s > t, that t >=0 and s < len(src).\nfunc (e *fastEncL5Window) matchlen(s, t int32, src []byte) int32 {\n\tif debugDecode {\n\t\tif t >= s {\n\t\t\tpanic(fmt.Sprint(\"t >=s:\", t, s))\n\t\t}\n\t\tif int(s) >= len(src) {\n\t\t\tpanic(fmt.Sprint(\"s >= len(src):\", s, len(src)))\n\t\t}\n\t\tif t < 0 {\n\t\t\tpanic(fmt.Sprint(\"t < 0:\", t))\n\t\t}\n\t\tif s-t > e.maxOffset {\n\t\t\tpanic(fmt.Sprint(s, \"-\", t, \"(\", s-t, \") > maxMatchLength (\", maxMatchOffset, \")\"))\n\t\t}\n\t}\n\ts1 := int(s) + maxMatchLength - 4\n\tif s1 > len(src) {\n\t\ts1 = len(src)\n\t}\n\n\t// Extend the match to be as long as possible.\n\treturn int32(matchLen(src[s:s1], src[t:]))\n}\n\n// matchlenLong will return the match length between offsets and t in src.\n// It is assumed that s > t, that t >=0 and s < len(src).\nfunc (e *fastEncL5Window) matchlenLong(s, t int32, src []byte) int32 {\n\tif debugDeflate {\n\t\tif t >= s {\n\t\t\tpanic(fmt.Sprint(\"t >=s:\", t, s))\n\t\t}\n\t\tif int(s) >= len(src) {\n\t\t\tpanic(fmt.Sprint(\"s >= len(src):\", s, len(src)))\n\t\t}\n\t\tif t < 0 {\n\t\t\tpanic(fmt.Sprint(\"t < 0:\", t))\n\t\t}\n\t\tif s-t > e.maxOffset {\n\t\t\tpanic(fmt.Sprint(s, \"-\", t, \"(\", s-t, \") > maxMatchLength (\", maxMatchOffset, \")\"))\n\t\t}\n\t}\n\t// Extend the match to be as long as possible.\n\treturn int32(matchLen(src[s:], src[t:]))\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/level6.go",
    "content": "package flate\n\nimport \"fmt\"\n\ntype fastEncL6 struct {\n\tfastGen\n\ttable  [tableSize]tableEntry\n\tbTable [tableSize]tableEntryPrev\n}\n\nfunc (e *fastEncL6) Encode(dst *tokens, src []byte) {\n\tconst (\n\t\tinputMargin            = 12 - 1\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t\thashShortBytes         = 4\n\t)\n\tif debugDeflate && e.cur < 0 {\n\t\tpanic(fmt.Sprint(\"e.cur < 0: \", e.cur))\n\t}\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= bufferReset {\n\t\tif len(e.hist) == 0 {\n\t\t\tfor i := range e.table[:] {\n\t\t\t\te.table[i] = tableEntry{}\n\t\t\t}\n\t\t\tfor i := range e.bTable[:] {\n\t\t\t\te.bTable[i] = tableEntryPrev{}\n\t\t\t}\n\t\t\te.cur = maxMatchOffset\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - maxMatchOffset\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v <= minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\tfor i := range e.bTable[:] {\n\t\t\tv := e.bTable[i]\n\t\t\tif v.Cur.offset <= minOff {\n\t\t\t\tv.Cur.offset = 0\n\t\t\t\tv.Prev.offset = 0\n\t\t\t} else {\n\t\t\t\tv.Cur.offset = v.Cur.offset - e.cur + maxMatchOffset\n\t\t\t\tif v.Prev.offset <= minOff {\n\t\t\t\t\tv.Prev.offset = 0\n\t\t\t\t} else {\n\t\t\t\t\tv.Prev.offset = v.Prev.offset - e.cur + maxMatchOffset\n\t\t\t\t}\n\t\t\t}\n\t\t\te.bTable[i] = v\n\t\t}\n\t\te.cur = maxMatchOffset\n\t}\n\n\ts := e.addBlock(src)\n\n\t// This check isn't in the Snappy implementation, but there, the caller\n\t// instead of the callee handles this case.\n\tif len(src) < minNonLiteralBlockSize {\n\t\t// We do not fill the token table.\n\t\t// This will be picked up by caller.\n\t\tdst.n = uint16(len(src))\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tnextEmit := s\n\n\t// sLimit is when to stop looking for offset/length copies. The inputMargin\n\t// lets us use a fast path for emitLiteral in the main loop, while we are\n\t// looking for copies.\n\tsLimit := int32(len(src) - inputMargin)\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tcv := load6432(src, s)\n\t// Repeat MUST be > 1 and within range\n\trepeat := int32(1)\n\tfor {\n\t\tconst skipLog = 7\n\t\tconst doEvery = 1\n\n\t\tnextS := s\n\t\tvar l int32\n\t\tvar t int32\n\t\tfor {\n\t\t\tnextHashS := hashLen(cv, tableBits, hashShortBytes)\n\t\t\tnextHashL := hash7(cv, tableBits)\n\t\t\ts = nextS\n\t\t\tnextS = s + doEvery + (s-nextEmit)>>skipLog\n\t\t\tif nextS > sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\t\t\t// Fetch a short+long candidate\n\t\t\tsCandidate := e.table[nextHashS]\n\t\t\tlCandidate := e.bTable[nextHashL]\n\t\t\tnext := load6432(src, nextS)\n\t\t\tentry := tableEntry{offset: s + e.cur}\n\t\t\te.table[nextHashS] = entry\n\t\t\teLong := &e.bTable[nextHashL]\n\t\t\teLong.Cur, eLong.Prev = entry, eLong.Cur\n\n\t\t\t// Calculate hashes of 'next'\n\t\t\tnextHashS = hashLen(next, tableBits, hashShortBytes)\n\t\t\tnextHashL = hash7(next, tableBits)\n\n\t\t\tt = lCandidate.Cur.offset - e.cur\n\t\t\tif s-t < maxMatchOffset {\n\t\t\t\tif uint32(cv) == load3232(src, t) {\n\t\t\t\t\t// Long candidate matches at least 4 bytes.\n\n\t\t\t\t\t// Store the next match\n\t\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\n\t\t\t\t\t// Check the previous long candidate as well.\n\t\t\t\t\tt2 := lCandidate.Prev.offset - e.cur\n\t\t\t\t\tif s-t2 < maxMatchOffset && uint32(cv) == load3232(src, t2) {\n\t\t\t\t\t\tl = e.matchlen(int(s+4), int(t+4), src) + 4\n\t\t\t\t\t\tml1 := e.matchlen(int(s+4), int(t2+4), src) + 4\n\t\t\t\t\t\tif ml1 > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\tl = ml1\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\t// Current value did not match, but check if previous long value does.\n\t\t\t\tt = lCandidate.Prev.offset - e.cur\n\t\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, t) {\n\t\t\t\t\t// Store the next match\n\t\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tt = sCandidate.offset - e.cur\n\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, t) {\n\t\t\t\t// Found a 4 match...\n\t\t\t\tl = e.matchlen(int(s+4), int(t+4), src) + 4\n\n\t\t\t\t// Look up next long candidate (at nextS)\n\t\t\t\tlCandidate = e.bTable[nextHashL]\n\n\t\t\t\t// Store the next match\n\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\n\t\t\t\t// Check repeat at s + repOff\n\t\t\t\tconst repOff = 1\n\t\t\t\tt2 := s - repeat + repOff\n\t\t\t\tif load3232(src, t2) == uint32(cv>>(8*repOff)) {\n\t\t\t\t\tml := e.matchlen(int(s+4+repOff), int(t2+4), src) + 4\n\t\t\t\t\tif ml > l {\n\t\t\t\t\t\tt = t2\n\t\t\t\t\t\tl = ml\n\t\t\t\t\t\ts += repOff\n\t\t\t\t\t\t// Not worth checking more.\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If the next long is a candidate, use that...\n\t\t\t\tt2 = lCandidate.Cur.offset - e.cur\n\t\t\t\tif nextS-t2 < maxMatchOffset {\n\t\t\t\t\tif load3232(src, t2) == uint32(next) {\n\t\t\t\t\t\tml := e.matchlen(int(nextS+4), int(t2+4), src) + 4\n\t\t\t\t\t\tif ml > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\ts = nextS\n\t\t\t\t\t\t\tl = ml\n\t\t\t\t\t\t\t// This is ok, but check previous as well.\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// If the previous long is a candidate, use that...\n\t\t\t\t\tt2 = lCandidate.Prev.offset - e.cur\n\t\t\t\t\tif nextS-t2 < maxMatchOffset && load3232(src, t2) == uint32(next) {\n\t\t\t\t\t\tml := e.matchlen(int(nextS+4), int(t2+4), src) + 4\n\t\t\t\t\t\tif ml > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\ts = nextS\n\t\t\t\t\t\t\tl = ml\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcv = next\n\t\t}\n\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes\n\t\t// match. But, prior to the match, src[nextEmit:s] are unmatched. Emit\n\t\t// them as literal bytes.\n\n\t\t// Extend the 4-byte match as long as possible.\n\t\tif l == 0 {\n\t\t\tl = e.matchlenLong(int(s+4), int(t+4), src) + 4\n\t\t} else if l == maxMatchLength {\n\t\t\tl += e.matchlenLong(int(s+l), int(t+l), src)\n\t\t}\n\n\t\t// Try to locate a better match by checking the end-of-match...\n\t\tif sAt := s + l; sAt < sLimit {\n\t\t\t// Allow some bytes at the beginning to mismatch.\n\t\t\t// Sweet spot is 2/3 bytes depending on input.\n\t\t\t// 3 is only a little better when it is but sometimes a lot worse.\n\t\t\t// The skipped bytes are tested in Extend backwards,\n\t\t\t// and still picked up as part of the match if they do.\n\t\t\tconst skipBeginning = 2\n\t\t\teLong := &e.bTable[hash7(load6432(src, sAt), tableBits)]\n\t\t\t// Test current\n\t\t\tt2 := eLong.Cur.offset - e.cur - l + skipBeginning\n\t\t\ts2 := s + skipBeginning\n\t\t\toff := s2 - t2\n\t\t\tif off < maxMatchOffset {\n\t\t\t\tif off > 0 && t2 >= 0 {\n\t\t\t\t\tif l2 := e.matchlenLong(int(s2), int(t2), src); l2 > l {\n\t\t\t\t\t\tt = t2\n\t\t\t\t\t\tl = l2\n\t\t\t\t\t\ts = s2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Test next:\n\t\t\t\tt2 = eLong.Prev.offset - e.cur - l + skipBeginning\n\t\t\t\toff := s2 - t2\n\t\t\t\tif off > 0 && off < maxMatchOffset && t2 >= 0 {\n\t\t\t\t\tif l2 := e.matchlenLong(int(s2), int(t2), src); l2 > l {\n\t\t\t\t\t\tt = t2\n\t\t\t\t\t\tl = l2\n\t\t\t\t\t\ts = s2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Extend backwards\n\t\tfor t > 0 && s > nextEmit && src[t-1] == src[s-1] {\n\t\t\ts--\n\t\t\tt--\n\t\t\tl++\n\t\t}\n\t\tif nextEmit < s {\n\t\t\tif false {\n\t\t\t\temitLiteral(dst, src[nextEmit:s])\n\t\t\t} else {\n\t\t\t\tfor _, v := range src[nextEmit:s] {\n\t\t\t\t\tdst.tokens[dst.n] = token(v)\n\t\t\t\t\tdst.litHist[v]++\n\t\t\t\t\tdst.n++\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif false {\n\t\t\tif t >= s {\n\t\t\t\tpanic(fmt.Sprintln(\"s-t\", s, t))\n\t\t\t}\n\t\t\tif (s - t) > maxMatchOffset {\n\t\t\t\tpanic(fmt.Sprintln(\"mmo\", s-t))\n\t\t\t}\n\t\t\tif l < baseMatchLength {\n\t\t\t\tpanic(\"bml\")\n\t\t\t}\n\t\t}\n\n\t\tdst.AddMatchLong(l, uint32(s-t-baseMatchOffset))\n\t\trepeat = s - t\n\t\ts += l\n\t\tnextEmit = s\n\t\tif nextS >= s {\n\t\t\ts = nextS + 1\n\t\t}\n\n\t\tif s >= sLimit {\n\t\t\t// Index after match end.\n\t\t\tfor i := nextS + 1; i < int32(len(src))-8; i += 2 {\n\t\t\t\tcv := load6432(src, i)\n\t\t\t\te.table[hashLen(cv, tableBits, hashShortBytes)] = tableEntry{offset: i + e.cur}\n\t\t\t\teLong := &e.bTable[hash7(cv, tableBits)]\n\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: i + e.cur}, eLong.Cur\n\t\t\t}\n\t\t\tgoto emitRemainder\n\t\t}\n\n\t\t// Store every long hash in-between and every second short.\n\t\tif true {\n\t\t\tfor i := nextS + 1; i < s-1; i += 2 {\n\t\t\t\tcv := load6432(src, i)\n\t\t\t\tt := tableEntry{offset: i + e.cur}\n\t\t\t\tt2 := tableEntry{offset: t.offset + 1}\n\t\t\t\teLong := &e.bTable[hash7(cv, tableBits)]\n\t\t\t\teLong2 := &e.bTable[hash7(cv>>8, tableBits)]\n\t\t\t\te.table[hashLen(cv, tableBits, hashShortBytes)] = t\n\t\t\t\teLong.Cur, eLong.Prev = t, eLong.Cur\n\t\t\t\teLong2.Cur, eLong2.Prev = t2, eLong2.Cur\n\t\t\t}\n\t\t}\n\n\t\t// We could immediately start working at s now, but to improve\n\t\t// compression we first update the hash table at s-1 and at s.\n\t\tcv = load6432(src, s)\n\t}\n\nemitRemainder:\n\tif int(nextEmit) < len(src) {\n\t\t// If nothing was added, don't encode literals.\n\t\tif dst.n == 0 {\n\t\t\treturn\n\t\t}\n\n\t\temitLiteral(dst, src[nextEmit:])\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/matchlen_generic.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n\npackage flate\n\nimport (\n\t\"math/bits\"\n\n\t\"github.com/klauspost/compress/internal/le\"\n)\n\n// matchLen returns the maximum common prefix length of a and b.\n// a must be the shortest of the two.\nfunc matchLen(a, b []byte) (n int) {\n\tleft := len(a)\n\tfor left >= 8 {\n\t\tdiff := le.Load64(a, n) ^ le.Load64(b, n)\n\t\tif diff != 0 {\n\t\t\treturn n + bits.TrailingZeros64(diff)>>3\n\t\t}\n\t\tn += 8\n\t\tleft -= 8\n\t}\n\n\ta = a[n:]\n\tb = b[n:]\n\tfor i := range a {\n\t\tif a[i] != b[i] {\n\t\t\tbreak\n\t\t}\n\t\tn++\n\t}\n\treturn n\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/regmask_amd64.go",
    "content": "package flate\n\nconst (\n\t// Masks for shifts with register sizes of the shift value.\n\t// This can be used to work around the x86 design of shifting by mod register size.\n\t// It can be used when a variable shift is always smaller than the register size.\n\n\t// reg8SizeMaskX - shift value is 8 bits, shifted is X\n\treg8SizeMask8  = 7\n\treg8SizeMask16 = 15\n\treg8SizeMask32 = 31\n\treg8SizeMask64 = 63\n\n\t// reg16SizeMaskX - shift value is 16 bits, shifted is X\n\treg16SizeMask8  = reg8SizeMask8\n\treg16SizeMask16 = reg8SizeMask16\n\treg16SizeMask32 = reg8SizeMask32\n\treg16SizeMask64 = reg8SizeMask64\n\n\t// reg32SizeMaskX - shift value is 32 bits, shifted is X\n\treg32SizeMask8  = reg8SizeMask8\n\treg32SizeMask16 = reg8SizeMask16\n\treg32SizeMask32 = reg8SizeMask32\n\treg32SizeMask64 = reg8SizeMask64\n\n\t// reg64SizeMaskX - shift value is 64 bits, shifted is X\n\treg64SizeMask8  = reg8SizeMask8\n\treg64SizeMask16 = reg8SizeMask16\n\treg64SizeMask32 = reg8SizeMask32\n\treg64SizeMask64 = reg8SizeMask64\n\n\t// regSizeMaskUintX - shift value is uint, shifted is X\n\tregSizeMaskUint8  = reg8SizeMask8\n\tregSizeMaskUint16 = reg8SizeMask16\n\tregSizeMaskUint32 = reg8SizeMask32\n\tregSizeMaskUint64 = reg8SizeMask64\n)\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/regmask_other.go",
    "content": "//go:build !amd64\n// +build !amd64\n\npackage flate\n\nconst (\n\t// Masks for shifts with register sizes of the shift value.\n\t// This can be used to work around the x86 design of shifting by mod register size.\n\t// It can be used when a variable shift is always smaller than the register size.\n\n\t// reg8SizeMaskX - shift value is 8 bits, shifted is X\n\treg8SizeMask8  = 0xff\n\treg8SizeMask16 = 0xff\n\treg8SizeMask32 = 0xff\n\treg8SizeMask64 = 0xff\n\n\t// reg16SizeMaskX - shift value is 16 bits, shifted is X\n\treg16SizeMask8  = 0xffff\n\treg16SizeMask16 = 0xffff\n\treg16SizeMask32 = 0xffff\n\treg16SizeMask64 = 0xffff\n\n\t// reg32SizeMaskX - shift value is 32 bits, shifted is X\n\treg32SizeMask8  = 0xffffffff\n\treg32SizeMask16 = 0xffffffff\n\treg32SizeMask32 = 0xffffffff\n\treg32SizeMask64 = 0xffffffff\n\n\t// reg64SizeMaskX - shift value is 64 bits, shifted is X\n\treg64SizeMask8  = 0xffffffffffffffff\n\treg64SizeMask16 = 0xffffffffffffffff\n\treg64SizeMask32 = 0xffffffffffffffff\n\treg64SizeMask64 = 0xffffffffffffffff\n\n\t// regSizeMaskUintX - shift value is uint, shifted is X\n\tregSizeMaskUint8  = ^uint(0)\n\tregSizeMaskUint16 = ^uint(0)\n\tregSizeMaskUint32 = ^uint(0)\n\tregSizeMaskUint64 = ^uint(0)\n)\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/stateless.go",
    "content": "package flate\n\nimport (\n\t\"io\"\n\t\"math\"\n\t\"sync\"\n\n\t\"github.com/klauspost/compress/internal/le\"\n)\n\nconst (\n\tmaxStatelessBlock = math.MaxInt16\n\t// dictionary will be taken from maxStatelessBlock, so limit it.\n\tmaxStatelessDict = 8 << 10\n\n\tslTableBits  = 13\n\tslTableSize  = 1 << slTableBits\n\tslTableShift = 32 - slTableBits\n)\n\ntype statelessWriter struct {\n\tdst    io.Writer\n\tclosed bool\n}\n\nfunc (s *statelessWriter) Close() error {\n\tif s.closed {\n\t\treturn nil\n\t}\n\ts.closed = true\n\t// Emit EOF block\n\treturn StatelessDeflate(s.dst, nil, true, nil)\n}\n\nfunc (s *statelessWriter) Write(p []byte) (n int, err error) {\n\terr = StatelessDeflate(s.dst, p, false, nil)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn len(p), nil\n}\n\nfunc (s *statelessWriter) Reset(w io.Writer) {\n\ts.dst = w\n\ts.closed = false\n}\n\n// NewStatelessWriter will do compression but without maintaining any state\n// between Write calls.\n// There will be no memory kept between Write calls,\n// but compression and speed will be suboptimal.\n// Because of this, the size of actual Write calls will affect output size.\nfunc NewStatelessWriter(dst io.Writer) io.WriteCloser {\n\treturn &statelessWriter{dst: dst}\n}\n\n// bitWriterPool contains bit writers that can be reused.\nvar bitWriterPool = sync.Pool{\n\tNew: func() interface{} {\n\t\treturn newHuffmanBitWriter(nil)\n\t},\n}\n\n// StatelessDeflate allows compressing directly to a Writer without retaining state.\n// When returning everything will be flushed.\n// Up to 8KB of an optional dictionary can be given which is presumed to precede the block.\n// Longer dictionaries will be truncated and will still produce valid output.\n// Sending nil dictionary is perfectly fine.\nfunc StatelessDeflate(out io.Writer, in []byte, eof bool, dict []byte) error {\n\tvar dst tokens\n\tbw := bitWriterPool.Get().(*huffmanBitWriter)\n\tbw.reset(out)\n\tdefer func() {\n\t\t// don't keep a reference to our output\n\t\tbw.reset(nil)\n\t\tbitWriterPool.Put(bw)\n\t}()\n\tif eof && len(in) == 0 {\n\t\t// Just write an EOF block.\n\t\t// Could be faster...\n\t\tbw.writeStoredHeader(0, true)\n\t\tbw.flush()\n\t\treturn bw.err\n\t}\n\n\t// Truncate dict\n\tif len(dict) > maxStatelessDict {\n\t\tdict = dict[len(dict)-maxStatelessDict:]\n\t}\n\n\t// For subsequent loops, keep shallow dict reference to avoid alloc+copy.\n\tvar inDict []byte\n\n\tfor len(in) > 0 {\n\t\ttodo := in\n\t\tif len(inDict) > 0 {\n\t\t\tif len(todo) > maxStatelessBlock-maxStatelessDict {\n\t\t\t\ttodo = todo[:maxStatelessBlock-maxStatelessDict]\n\t\t\t}\n\t\t} else if len(todo) > maxStatelessBlock-len(dict) {\n\t\t\ttodo = todo[:maxStatelessBlock-len(dict)]\n\t\t}\n\t\tinOrg := in\n\t\tin = in[len(todo):]\n\t\tuncompressed := todo\n\t\tif len(dict) > 0 {\n\t\t\t// combine dict and source\n\t\t\tbufLen := len(todo) + len(dict)\n\t\t\tcombined := make([]byte, bufLen)\n\t\t\tcopy(combined, dict)\n\t\t\tcopy(combined[len(dict):], todo)\n\t\t\ttodo = combined\n\t\t}\n\t\t// Compress\n\t\tif len(inDict) == 0 {\n\t\t\tstatelessEnc(&dst, todo, int16(len(dict)))\n\t\t} else {\n\t\t\tstatelessEnc(&dst, inDict[:maxStatelessDict+len(todo)], maxStatelessDict)\n\t\t}\n\t\tisEof := eof && len(in) == 0\n\n\t\tif dst.n == 0 {\n\t\t\tbw.writeStoredHeader(len(uncompressed), isEof)\n\t\t\tif bw.err != nil {\n\t\t\t\treturn bw.err\n\t\t\t}\n\t\t\tbw.writeBytes(uncompressed)\n\t\t} else if int(dst.n) > len(uncompressed)-len(uncompressed)>>4 {\n\t\t\t// If we removed less than 1/16th, huffman compress the block.\n\t\t\tbw.writeBlockHuff(isEof, uncompressed, len(in) == 0)\n\t\t} else {\n\t\t\tbw.writeBlockDynamic(&dst, isEof, uncompressed, len(in) == 0)\n\t\t}\n\t\tif len(in) > 0 {\n\t\t\t// Retain a dict if we have more\n\t\t\tinDict = inOrg[len(uncompressed)-maxStatelessDict:]\n\t\t\tdict = nil\n\t\t\tdst.Reset()\n\t\t}\n\t\tif bw.err != nil {\n\t\t\treturn bw.err\n\t\t}\n\t}\n\tif !eof {\n\t\t// Align, only a stored block can do that.\n\t\tbw.writeStoredHeader(0, false)\n\t}\n\tbw.flush()\n\treturn bw.err\n}\n\nfunc hashSL(u uint32) uint32 {\n\treturn (u * 0x1e35a7bd) >> slTableShift\n}\n\nfunc load3216(b []byte, i int16) uint32 {\n\treturn le.Load32(b, i)\n}\n\nfunc load6416(b []byte, i int16) uint64 {\n\treturn le.Load64(b, i)\n}\n\nfunc statelessEnc(dst *tokens, src []byte, startAt int16) {\n\tconst (\n\t\tinputMargin            = 12 - 1\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t)\n\n\ttype tableEntry struct {\n\t\toffset int16\n\t}\n\n\tvar table [slTableSize]tableEntry\n\n\t// This check isn't in the Snappy implementation, but there, the caller\n\t// instead of the callee handles this case.\n\tif len(src)-int(startAt) < minNonLiteralBlockSize {\n\t\t// We do not fill the token table.\n\t\t// This will be picked up by caller.\n\t\tdst.n = 0\n\t\treturn\n\t}\n\t// Index until startAt\n\tif startAt > 0 {\n\t\tcv := load3232(src, 0)\n\t\tfor i := int16(0); i < startAt; i++ {\n\t\t\ttable[hashSL(cv)] = tableEntry{offset: i}\n\t\t\tcv = (cv >> 8) | (uint32(src[i+4]) << 24)\n\t\t}\n\t}\n\n\ts := startAt + 1\n\tnextEmit := startAt\n\t// sLimit is when to stop looking for offset/length copies. The inputMargin\n\t// lets us use a fast path for emitLiteral in the main loop, while we are\n\t// looking for copies.\n\tsLimit := int16(len(src) - inputMargin)\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tcv := load3216(src, s)\n\n\tfor {\n\t\tconst skipLog = 5\n\t\tconst doEvery = 2\n\n\t\tnextS := s\n\t\tvar candidate tableEntry\n\t\tfor {\n\t\t\tnextHash := hashSL(cv)\n\t\t\tcandidate = table[nextHash]\n\t\t\tnextS = s + doEvery + (s-nextEmit)>>skipLog\n\t\t\tif nextS > sLimit || nextS <= 0 {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\n\t\t\tnow := load6416(src, nextS)\n\t\t\ttable[nextHash] = tableEntry{offset: s}\n\t\t\tnextHash = hashSL(uint32(now))\n\n\t\t\tif cv == load3216(src, candidate.offset) {\n\t\t\t\ttable[nextHash] = tableEntry{offset: nextS}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Do one right away...\n\t\t\tcv = uint32(now)\n\t\t\ts = nextS\n\t\t\tnextS++\n\t\t\tcandidate = table[nextHash]\n\t\t\tnow >>= 8\n\t\t\ttable[nextHash] = tableEntry{offset: s}\n\n\t\t\tif cv == load3216(src, candidate.offset) {\n\t\t\t\ttable[nextHash] = tableEntry{offset: nextS}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcv = uint32(now)\n\t\t\ts = nextS\n\t\t}\n\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes\n\t\t// match. But, prior to the match, src[nextEmit:s] are unmatched. Emit\n\t\t// them as literal bytes.\n\t\tfor {\n\t\t\t// Invariant: we have a 4-byte match at s, and no need to emit any\n\t\t\t// literal bytes prior to s.\n\n\t\t\t// Extend the 4-byte match as long as possible.\n\t\t\tt := candidate.offset\n\t\t\tl := int16(matchLen(src[s+4:], src[t+4:]) + 4)\n\n\t\t\t// Extend backwards\n\t\t\tfor t > 0 && s > nextEmit && src[t-1] == src[s-1] {\n\t\t\t\ts--\n\t\t\t\tt--\n\t\t\t\tl++\n\t\t\t}\n\t\t\tif nextEmit < s {\n\t\t\t\tif false {\n\t\t\t\t\temitLiteral(dst, src[nextEmit:s])\n\t\t\t\t} else {\n\t\t\t\t\tfor _, v := range src[nextEmit:s] {\n\t\t\t\t\t\tdst.tokens[dst.n] = token(v)\n\t\t\t\t\t\tdst.litHist[v]++\n\t\t\t\t\t\tdst.n++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Save the match found\n\t\t\tdst.AddMatchLong(int32(l), uint32(s-t-baseMatchOffset))\n\t\t\ts += l\n\t\t\tnextEmit = s\n\t\t\tif nextS >= s {\n\t\t\t\ts = nextS + 1\n\t\t\t}\n\t\t\tif s >= sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\n\t\t\t// We could immediately start working at s now, but to improve\n\t\t\t// compression we first update the hash table at s-2 and at s. If\n\t\t\t// another emitCopy is not our next move, also calculate nextHash\n\t\t\t// at s+1. At least on GOARCH=amd64, these three hash calculations\n\t\t\t// are faster as one load64 call (with some shifts) instead of\n\t\t\t// three load32 calls.\n\t\t\tx := load6416(src, s-2)\n\t\t\to := s - 2\n\t\t\tprevHash := hashSL(uint32(x))\n\t\t\ttable[prevHash] = tableEntry{offset: o}\n\t\t\tx >>= 16\n\t\t\tcurrHash := hashSL(uint32(x))\n\t\t\tcandidate = table[currHash]\n\t\t\ttable[currHash] = tableEntry{offset: o + 2}\n\n\t\t\tif uint32(x) != load3216(src, candidate.offset) {\n\t\t\t\tcv = uint32(x >> 8)\n\t\t\t\ts++\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\nemitRemainder:\n\tif int(nextEmit) < len(src) {\n\t\t// If nothing was added, don't encode literals.\n\t\tif dst.n == 0 {\n\t\t\treturn\n\t\t}\n\t\temitLiteral(dst, src[nextEmit:])\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/token.go",
    "content": "// Copyright 2009 The Go 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 flate\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n)\n\nconst (\n\t// bits 0-16  \txoffset = offset - MIN_OFFSET_SIZE, or literal - 16 bits\n\t// bits 16-22\toffsetcode - 5 bits\n\t// bits 22-30   xlength = length - MIN_MATCH_LENGTH - 8 bits\n\t// bits 30-32   type   0 = literal  1=EOF  2=Match   3=Unused - 2 bits\n\tlengthShift         = 22\n\toffsetMask          = 1<<lengthShift - 1\n\ttypeMask            = 3 << 30\n\tliteralType         = 0 << 30\n\tmatchType           = 1 << 30\n\tmatchOffsetOnlyMask = 0xffff\n)\n\n// The length code for length X (MIN_MATCH_LENGTH <= X <= MAX_MATCH_LENGTH)\n// is lengthCodes[length - MIN_MATCH_LENGTH]\nvar lengthCodes = [256]uint8{\n\t0, 1, 2, 3, 4, 5, 6, 7, 8, 8,\n\t9, 9, 10, 10, 11, 11, 12, 12, 12, 12,\n\t13, 13, 13, 13, 14, 14, 14, 14, 15, 15,\n\t15, 15, 16, 16, 16, 16, 16, 16, 16, 16,\n\t17, 17, 17, 17, 17, 17, 17, 17, 18, 18,\n\t18, 18, 18, 18, 18, 18, 19, 19, 19, 19,\n\t19, 19, 19, 19, 20, 20, 20, 20, 20, 20,\n\t20, 20, 20, 20, 20, 20, 20, 20, 20, 20,\n\t21, 21, 21, 21, 21, 21, 21, 21, 21, 21,\n\t21, 21, 21, 21, 21, 21, 22, 22, 22, 22,\n\t22, 22, 22, 22, 22, 22, 22, 22, 22, 22,\n\t22, 22, 23, 23, 23, 23, 23, 23, 23, 23,\n\t23, 23, 23, 23, 23, 23, 23, 23, 24, 24,\n\t24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n\t24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n\t24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n\t25, 25, 26, 26, 26, 26, 26, 26, 26, 26,\n\t26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n\t26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n\t26, 26, 26, 26, 27, 27, 27, 27, 27, 27,\n\t27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n\t27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n\t27, 27, 27, 27, 27, 28,\n}\n\n// lengthCodes1 is length codes, but starting at 1.\nvar lengthCodes1 = [256]uint8{\n\t1, 2, 3, 4, 5, 6, 7, 8, 9, 9,\n\t10, 10, 11, 11, 12, 12, 13, 13, 13, 13,\n\t14, 14, 14, 14, 15, 15, 15, 15, 16, 16,\n\t16, 16, 17, 17, 17, 17, 17, 17, 17, 17,\n\t18, 18, 18, 18, 18, 18, 18, 18, 19, 19,\n\t19, 19, 19, 19, 19, 19, 20, 20, 20, 20,\n\t20, 20, 20, 20, 21, 21, 21, 21, 21, 21,\n\t21, 21, 21, 21, 21, 21, 21, 21, 21, 21,\n\t22, 22, 22, 22, 22, 22, 22, 22, 22, 22,\n\t22, 22, 22, 22, 22, 22, 23, 23, 23, 23,\n\t23, 23, 23, 23, 23, 23, 23, 23, 23, 23,\n\t23, 23, 24, 24, 24, 24, 24, 24, 24, 24,\n\t24, 24, 24, 24, 24, 24, 24, 24, 25, 25,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n\t26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n\t26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n\t26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n\t26, 26, 27, 27, 27, 27, 27, 27, 27, 27,\n\t27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n\t27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n\t27, 27, 27, 27, 28, 28, 28, 28, 28, 28,\n\t28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n\t28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n\t28, 28, 28, 28, 28, 29,\n}\n\nvar offsetCodes = [256]uint32{\n\t0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,\n\t8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n}\n\n// offsetCodes14 are offsetCodes, but with 14 added.\nvar offsetCodes14 = [256]uint32{\n\t14, 15, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21,\n\t22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,\n\t24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n\t26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n\t26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n\t27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n\t27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n\t28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n\t28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n\t28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n\t28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n\t29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n\t29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n\t29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n\t29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n}\n\ntype token uint32\n\ntype tokens struct {\n\textraHist [32]uint16  // codes 256->maxnumlit\n\toffHist   [32]uint16  // offset codes\n\tlitHist   [256]uint16 // codes 0->255\n\tnFilled   int\n\tn         uint16 // Must be able to contain maxStoreBlockSize\n\ttokens    [maxStoreBlockSize + 1]token\n}\n\nfunc (t *tokens) Reset() {\n\tif t.n == 0 {\n\t\treturn\n\t}\n\tt.n = 0\n\tt.nFilled = 0\n\tfor i := range t.litHist[:] {\n\t\tt.litHist[i] = 0\n\t}\n\tfor i := range t.extraHist[:] {\n\t\tt.extraHist[i] = 0\n\t}\n\tfor i := range t.offHist[:] {\n\t\tt.offHist[i] = 0\n\t}\n}\n\nfunc (t *tokens) Fill() {\n\tif t.n == 0 {\n\t\treturn\n\t}\n\tfor i, v := range t.litHist[:] {\n\t\tif v == 0 {\n\t\t\tt.litHist[i] = 1\n\t\t\tt.nFilled++\n\t\t}\n\t}\n\tfor i, v := range t.extraHist[:literalCount-256] {\n\t\tif v == 0 {\n\t\t\tt.nFilled++\n\t\t\tt.extraHist[i] = 1\n\t\t}\n\t}\n\tfor i, v := range t.offHist[:offsetCodeCount] {\n\t\tif v == 0 {\n\t\t\tt.offHist[i] = 1\n\t\t}\n\t}\n}\n\nfunc indexTokens(in []token) tokens {\n\tvar t tokens\n\tt.indexTokens(in)\n\treturn t\n}\n\nfunc (t *tokens) indexTokens(in []token) {\n\tt.Reset()\n\tfor _, tok := range in {\n\t\tif tok < matchType {\n\t\t\tt.AddLiteral(tok.literal())\n\t\t\tcontinue\n\t\t}\n\t\tt.AddMatch(uint32(tok.length()), tok.offset()&matchOffsetOnlyMask)\n\t}\n}\n\n// emitLiteral writes a literal chunk and returns the number of bytes written.\nfunc emitLiteral(dst *tokens, lit []byte) {\n\tfor _, v := range lit {\n\t\tdst.tokens[dst.n] = token(v)\n\t\tdst.litHist[v]++\n\t\tdst.n++\n\t}\n}\n\nfunc (t *tokens) AddLiteral(lit byte) {\n\tt.tokens[t.n] = token(lit)\n\tt.litHist[lit]++\n\tt.n++\n}\n\n// from https://stackoverflow.com/a/28730362\nfunc mFastLog2(val float32) float32 {\n\tux := int32(math.Float32bits(val))\n\tlog2 := (float32)(((ux >> 23) & 255) - 128)\n\tux &= -0x7f800001\n\tux += 127 << 23\n\tuval := math.Float32frombits(uint32(ux))\n\tlog2 += ((-0.34484843)*uval+2.02466578)*uval - 0.67487759\n\treturn log2\n}\n\n// EstimatedBits will return an minimum size estimated by an *optimal*\n// compression of the block.\n// The size of the block\nfunc (t *tokens) EstimatedBits() int {\n\tshannon := float32(0)\n\tbits := int(0)\n\tnMatches := 0\n\ttotal := int(t.n) + t.nFilled\n\tif total > 0 {\n\t\tinvTotal := 1.0 / float32(total)\n\t\tfor _, v := range t.litHist[:] {\n\t\t\tif v > 0 {\n\t\t\t\tn := float32(v)\n\t\t\t\tshannon += atLeastOne(-mFastLog2(n*invTotal)) * n\n\t\t\t}\n\t\t}\n\t\t// Just add 15 for EOB\n\t\tshannon += 15\n\t\tfor i, v := range t.extraHist[1 : literalCount-256] {\n\t\t\tif v > 0 {\n\t\t\t\tn := float32(v)\n\t\t\t\tshannon += atLeastOne(-mFastLog2(n*invTotal)) * n\n\t\t\t\tbits += int(lengthExtraBits[i&31]) * int(v)\n\t\t\t\tnMatches += int(v)\n\t\t\t}\n\t\t}\n\t}\n\tif nMatches > 0 {\n\t\tinvTotal := 1.0 / float32(nMatches)\n\t\tfor i, v := range t.offHist[:offsetCodeCount] {\n\t\t\tif v > 0 {\n\t\t\t\tn := float32(v)\n\t\t\t\tshannon += atLeastOne(-mFastLog2(n*invTotal)) * n\n\t\t\t\tbits += int(offsetExtraBits[i&31]) * int(v)\n\t\t\t}\n\t\t}\n\t}\n\treturn int(shannon) + bits\n}\n\n// AddMatch adds a match to the tokens.\n// This function is very sensitive to inlining and right on the border.\nfunc (t *tokens) AddMatch(xlength uint32, xoffset uint32) {\n\tif debugDeflate {\n\t\tif xlength >= maxMatchLength+baseMatchLength {\n\t\t\tpanic(fmt.Errorf(\"invalid length: %v\", xlength))\n\t\t}\n\t\tif xoffset >= maxMatchOffset+baseMatchOffset {\n\t\t\tpanic(fmt.Errorf(\"invalid offset: %v\", xoffset))\n\t\t}\n\t}\n\toCode := offsetCode(xoffset)\n\txoffset |= oCode << 16\n\n\tt.extraHist[lengthCodes1[uint8(xlength)]]++\n\tt.offHist[oCode&31]++\n\tt.tokens[t.n] = token(matchType | xlength<<lengthShift | xoffset)\n\tt.n++\n}\n\n// AddMatchLong adds a match to the tokens, potentially longer than max match length.\n// Length should NOT have the base subtracted, only offset should.\nfunc (t *tokens) AddMatchLong(xlength int32, xoffset uint32) {\n\tif debugDeflate {\n\t\tif xoffset >= maxMatchOffset+baseMatchOffset {\n\t\t\tpanic(fmt.Errorf(\"invalid offset: %v\", xoffset))\n\t\t}\n\t}\n\toc := offsetCode(xoffset)\n\txoffset |= oc << 16\n\tfor xlength > 0 {\n\t\txl := xlength\n\t\tif xl > 258 {\n\t\t\t// We need to have at least baseMatchLength left over for next loop.\n\t\t\tif xl > 258+baseMatchLength {\n\t\t\t\txl = 258\n\t\t\t} else {\n\t\t\t\txl = 258 - baseMatchLength\n\t\t\t}\n\t\t}\n\t\txlength -= xl\n\t\txl -= baseMatchLength\n\t\tt.extraHist[lengthCodes1[uint8(xl)]]++\n\t\tt.offHist[oc&31]++\n\t\tt.tokens[t.n] = token(matchType | uint32(xl)<<lengthShift | xoffset)\n\t\tt.n++\n\t}\n}\n\nfunc (t *tokens) AddEOB() {\n\tt.tokens[t.n] = token(endBlockMarker)\n\tt.extraHist[0]++\n\tt.n++\n}\n\nfunc (t *tokens) Slice() []token {\n\treturn t.tokens[:t.n]\n}\n\n// VarInt returns the tokens as varint encoded bytes.\nfunc (t *tokens) VarInt() []byte {\n\tvar b = make([]byte, binary.MaxVarintLen32*int(t.n))\n\tvar off int\n\tfor _, v := range t.tokens[:t.n] {\n\t\toff += binary.PutUvarint(b[off:], uint64(v))\n\t}\n\treturn b[:off]\n}\n\n// FromVarInt restores t to the varint encoded tokens provided.\n// Any data in t is removed.\nfunc (t *tokens) FromVarInt(b []byte) error {\n\tvar buf = bytes.NewReader(b)\n\tvar toks []token\n\tfor {\n\t\tr, err := binary.ReadUvarint(buf)\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\ttoks = append(toks, token(r))\n\t}\n\tt.indexTokens(toks)\n\treturn nil\n}\n\n// Returns the type of a token\nfunc (t token) typ() uint32 { return uint32(t) & typeMask }\n\n// Returns the literal of a literal token\nfunc (t token) literal() uint8 { return uint8(t) }\n\n// Returns the extra offset of a match token\nfunc (t token) offset() uint32 { return uint32(t) & offsetMask }\n\nfunc (t token) length() uint8 { return uint8(t >> lengthShift) }\n\n// Convert length to code.\nfunc lengthCode(len uint8) uint8 { return lengthCodes[len] }\n\n// Returns the offset code corresponding to a specific offset\nfunc offsetCode(off uint32) uint32 {\n\tif false {\n\t\tif off < uint32(len(offsetCodes)) {\n\t\t\treturn offsetCodes[off&255]\n\t\t} else if off>>7 < uint32(len(offsetCodes)) {\n\t\t\treturn offsetCodes[(off>>7)&255] + 14\n\t\t} else {\n\t\t\treturn offsetCodes[(off>>14)&255] + 28\n\t\t}\n\t}\n\tif off < uint32(len(offsetCodes)) {\n\t\treturn offsetCodes[uint8(off)]\n\t}\n\treturn offsetCodes14[uint8(off>>7)]\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/internal/le/le.go",
    "content": "package le\n\ntype Indexer interface {\n\tint | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/internal/le/unsafe_disabled.go",
    "content": "//go:build !(amd64 || arm64 || ppc64le || riscv64) || nounsafe || purego || appengine\n\npackage le\n\nimport (\n\t\"encoding/binary\"\n)\n\n// Load8 will load from b at index i.\nfunc Load8[I Indexer](b []byte, i I) byte {\n\treturn b[i]\n}\n\n// Load16 will load from b at index i.\nfunc Load16[I Indexer](b []byte, i I) uint16 {\n\treturn binary.LittleEndian.Uint16(b[i:])\n}\n\n// Load32 will load from b at index i.\nfunc Load32[I Indexer](b []byte, i I) uint32 {\n\treturn binary.LittleEndian.Uint32(b[i:])\n}\n\n// Load64 will load from b at index i.\nfunc Load64[I Indexer](b []byte, i I) uint64 {\n\treturn binary.LittleEndian.Uint64(b[i:])\n}\n\n// Store16 will store v at b.\nfunc Store16(b []byte, v uint16) {\n\tbinary.LittleEndian.PutUint16(b, v)\n}\n\n// Store32 will store v at b.\nfunc Store32(b []byte, v uint32) {\n\tbinary.LittleEndian.PutUint32(b, v)\n}\n\n// Store64 will store v at b.\nfunc Store64(b []byte, v uint64) {\n\tbinary.LittleEndian.PutUint64(b, v)\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/internal/le/unsafe_enabled.go",
    "content": "// We enable 64 bit LE platforms:\n\n//go:build (amd64 || arm64 || ppc64le || riscv64) && !nounsafe && !purego && !appengine\n\npackage le\n\nimport (\n\t\"unsafe\"\n)\n\n// Load8 will load from b at index i.\nfunc Load8[I Indexer](b []byte, i I) byte {\n\t//return binary.LittleEndian.Uint16(b[i:])\n\t//return *(*uint16)(unsafe.Pointer(&b[i]))\n\treturn *(*byte)(unsafe.Add(unsafe.Pointer(unsafe.SliceData(b)), i))\n}\n\n// Load16 will load from b at index i.\nfunc Load16[I Indexer](b []byte, i I) uint16 {\n\t//return binary.LittleEndian.Uint16(b[i:])\n\t//return *(*uint16)(unsafe.Pointer(&b[i]))\n\treturn *(*uint16)(unsafe.Add(unsafe.Pointer(unsafe.SliceData(b)), i))\n}\n\n// Load32 will load from b at index i.\nfunc Load32[I Indexer](b []byte, i I) uint32 {\n\t//return binary.LittleEndian.Uint32(b[i:])\n\t//return *(*uint32)(unsafe.Pointer(&b[i]))\n\treturn *(*uint32)(unsafe.Add(unsafe.Pointer(unsafe.SliceData(b)), i))\n}\n\n// Load64 will load from b at index i.\nfunc Load64[I Indexer](b []byte, i I) uint64 {\n\t//return binary.LittleEndian.Uint64(b[i:])\n\t//return *(*uint64)(unsafe.Pointer(&b[i]))\n\treturn *(*uint64)(unsafe.Add(unsafe.Pointer(unsafe.SliceData(b)), i))\n}\n\n// Store16 will store v at b.\nfunc Store16(b []byte, v uint16) {\n\t//binary.LittleEndian.PutUint16(b, v)\n\t*(*uint16)(unsafe.Pointer(unsafe.SliceData(b))) = v\n}\n\n// Store32 will store v at b.\nfunc Store32(b []byte, v uint32) {\n\t//binary.LittleEndian.PutUint32(b, v)\n\t*(*uint32)(unsafe.Pointer(unsafe.SliceData(b))) = v\n}\n\n// Store64 will store v at b.\nfunc Store64(b []byte, v uint64) {\n\t//binary.LittleEndian.PutUint64(b, v)\n\t*(*uint64)(unsafe.Pointer(unsafe.SliceData(b))) = v\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-colorable/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2016 Yasuhiro Matsumoto\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": "vendor/github.com/mattn/go-colorable/README.md",
    "content": "# go-colorable\n\n[![Build Status](https://github.com/mattn/go-colorable/workflows/test/badge.svg)](https://github.com/mattn/go-colorable/actions?query=workflow%3Atest)\n[![Codecov](https://codecov.io/gh/mattn/go-colorable/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-colorable)\n[![GoDoc](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable)\n[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable)\n\nColorable writer for windows.\n\nFor example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.)\nThis package is possible to handle escape sequence for ansi color on windows.\n\n## Too Bad!\n\n![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png)\n\n\n## So Good!\n\n![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png)\n\n## Usage\n\n```go\nlogrus.SetFormatter(&logrus.TextFormatter{ForceColors: true})\nlogrus.SetOutput(colorable.NewColorableStdout())\n\nlogrus.Info(\"succeeded\")\nlogrus.Warn(\"not correct\")\nlogrus.Error(\"something error\")\nlogrus.Fatal(\"panic\")\n```\n\nYou can compile above code on non-windows OSs.\n\n## Installation\n\n```\n$ go get github.com/mattn/go-colorable\n```\n\n# License\n\nMIT\n\n# Author\n\nYasuhiro Matsumoto (a.k.a mattn)\n"
  },
  {
    "path": "vendor/github.com/mattn/go-colorable/colorable_appengine.go",
    "content": "//go:build appengine\n// +build appengine\n\npackage colorable\n\nimport (\n\t\"io\"\n\t\"os\"\n\n\t_ \"github.com/mattn/go-isatty\"\n)\n\n// NewColorable returns new instance of Writer which handles escape sequence.\nfunc NewColorable(file *os.File) io.Writer {\n\tif file == nil {\n\t\tpanic(\"nil passed instead of *os.File to NewColorable()\")\n\t}\n\n\treturn file\n}\n\n// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.\nfunc NewColorableStdout() io.Writer {\n\treturn os.Stdout\n}\n\n// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.\nfunc NewColorableStderr() io.Writer {\n\treturn os.Stderr\n}\n\n// EnableColorsStdout enable colors if possible.\nfunc EnableColorsStdout(enabled *bool) func() {\n\tif enabled != nil {\n\t\t*enabled = true\n\t}\n\treturn func() {}\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-colorable/colorable_others.go",
    "content": "//go:build !windows && !appengine\n// +build !windows,!appengine\n\npackage colorable\n\nimport (\n\t\"io\"\n\t\"os\"\n\n\t_ \"github.com/mattn/go-isatty\"\n)\n\n// NewColorable returns new instance of Writer which handles escape sequence.\nfunc NewColorable(file *os.File) io.Writer {\n\tif file == nil {\n\t\tpanic(\"nil passed instead of *os.File to NewColorable()\")\n\t}\n\n\treturn file\n}\n\n// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.\nfunc NewColorableStdout() io.Writer {\n\treturn os.Stdout\n}\n\n// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.\nfunc NewColorableStderr() io.Writer {\n\treturn os.Stderr\n}\n\n// EnableColorsStdout enable colors if possible.\nfunc EnableColorsStdout(enabled *bool) func() {\n\tif enabled != nil {\n\t\t*enabled = true\n\t}\n\treturn func() {}\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-colorable/colorable_windows.go",
    "content": "//go:build windows && !appengine\n// +build windows,!appengine\n\npackage colorable\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"math\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"github.com/mattn/go-isatty\"\n)\n\nconst (\n\tforegroundBlue      = 0x1\n\tforegroundGreen     = 0x2\n\tforegroundRed       = 0x4\n\tforegroundIntensity = 0x8\n\tforegroundMask      = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity)\n\tbackgroundBlue      = 0x10\n\tbackgroundGreen     = 0x20\n\tbackgroundRed       = 0x40\n\tbackgroundIntensity = 0x80\n\tbackgroundMask      = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity)\n\tcommonLvbUnderscore = 0x8000\n\n\tcENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4\n)\n\nconst (\n\tgenericRead  = 0x80000000\n\tgenericWrite = 0x40000000\n)\n\nconst (\n\tconsoleTextmodeBuffer = 0x1\n)\n\ntype wchar uint16\ntype short int16\ntype dword uint32\ntype word uint16\n\ntype coord struct {\n\tx short\n\ty short\n}\n\ntype smallRect struct {\n\tleft   short\n\ttop    short\n\tright  short\n\tbottom short\n}\n\ntype consoleScreenBufferInfo struct {\n\tsize              coord\n\tcursorPosition    coord\n\tattributes        word\n\twindow            smallRect\n\tmaximumWindowSize coord\n}\n\ntype consoleCursorInfo struct {\n\tsize    dword\n\tvisible int32\n}\n\nvar (\n\tkernel32                       = syscall.NewLazyDLL(\"kernel32.dll\")\n\tprocGetConsoleScreenBufferInfo = kernel32.NewProc(\"GetConsoleScreenBufferInfo\")\n\tprocSetConsoleTextAttribute    = kernel32.NewProc(\"SetConsoleTextAttribute\")\n\tprocSetConsoleCursorPosition   = kernel32.NewProc(\"SetConsoleCursorPosition\")\n\tprocFillConsoleOutputCharacter = kernel32.NewProc(\"FillConsoleOutputCharacterW\")\n\tprocFillConsoleOutputAttribute = kernel32.NewProc(\"FillConsoleOutputAttribute\")\n\tprocGetConsoleCursorInfo       = kernel32.NewProc(\"GetConsoleCursorInfo\")\n\tprocSetConsoleCursorInfo       = kernel32.NewProc(\"SetConsoleCursorInfo\")\n\tprocSetConsoleTitle            = kernel32.NewProc(\"SetConsoleTitleW\")\n\tprocGetConsoleMode             = kernel32.NewProc(\"GetConsoleMode\")\n\tprocSetConsoleMode             = kernel32.NewProc(\"SetConsoleMode\")\n\tprocCreateConsoleScreenBuffer  = kernel32.NewProc(\"CreateConsoleScreenBuffer\")\n)\n\n// Writer provides colorable Writer to the console\ntype Writer struct {\n\tout       io.Writer\n\thandle    syscall.Handle\n\talthandle syscall.Handle\n\toldattr   word\n\toldpos    coord\n\trest      bytes.Buffer\n\tmutex     sync.Mutex\n}\n\n// NewColorable returns new instance of Writer which handles escape sequence from File.\nfunc NewColorable(file *os.File) io.Writer {\n\tif file == nil {\n\t\tpanic(\"nil passed instead of *os.File to NewColorable()\")\n\t}\n\n\tif isatty.IsTerminal(file.Fd()) {\n\t\tvar mode uint32\n\t\tif r, _, _ := procGetConsoleMode.Call(file.Fd(), uintptr(unsafe.Pointer(&mode))); r != 0 && mode&cENABLE_VIRTUAL_TERMINAL_PROCESSING != 0 {\n\t\t\treturn file\n\t\t}\n\t\tvar csbi consoleScreenBufferInfo\n\t\thandle := syscall.Handle(file.Fd())\n\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\treturn &Writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}}\n\t}\n\treturn file\n}\n\n// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.\nfunc NewColorableStdout() io.Writer {\n\treturn NewColorable(os.Stdout)\n}\n\n// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.\nfunc NewColorableStderr() io.Writer {\n\treturn NewColorable(os.Stderr)\n}\n\nvar color256 = map[int]int{\n\t0:   0x000000,\n\t1:   0x800000,\n\t2:   0x008000,\n\t3:   0x808000,\n\t4:   0x000080,\n\t5:   0x800080,\n\t6:   0x008080,\n\t7:   0xc0c0c0,\n\t8:   0x808080,\n\t9:   0xff0000,\n\t10:  0x00ff00,\n\t11:  0xffff00,\n\t12:  0x0000ff,\n\t13:  0xff00ff,\n\t14:  0x00ffff,\n\t15:  0xffffff,\n\t16:  0x000000,\n\t17:  0x00005f,\n\t18:  0x000087,\n\t19:  0x0000af,\n\t20:  0x0000d7,\n\t21:  0x0000ff,\n\t22:  0x005f00,\n\t23:  0x005f5f,\n\t24:  0x005f87,\n\t25:  0x005faf,\n\t26:  0x005fd7,\n\t27:  0x005fff,\n\t28:  0x008700,\n\t29:  0x00875f,\n\t30:  0x008787,\n\t31:  0x0087af,\n\t32:  0x0087d7,\n\t33:  0x0087ff,\n\t34:  0x00af00,\n\t35:  0x00af5f,\n\t36:  0x00af87,\n\t37:  0x00afaf,\n\t38:  0x00afd7,\n\t39:  0x00afff,\n\t40:  0x00d700,\n\t41:  0x00d75f,\n\t42:  0x00d787,\n\t43:  0x00d7af,\n\t44:  0x00d7d7,\n\t45:  0x00d7ff,\n\t46:  0x00ff00,\n\t47:  0x00ff5f,\n\t48:  0x00ff87,\n\t49:  0x00ffaf,\n\t50:  0x00ffd7,\n\t51:  0x00ffff,\n\t52:  0x5f0000,\n\t53:  0x5f005f,\n\t54:  0x5f0087,\n\t55:  0x5f00af,\n\t56:  0x5f00d7,\n\t57:  0x5f00ff,\n\t58:  0x5f5f00,\n\t59:  0x5f5f5f,\n\t60:  0x5f5f87,\n\t61:  0x5f5faf,\n\t62:  0x5f5fd7,\n\t63:  0x5f5fff,\n\t64:  0x5f8700,\n\t65:  0x5f875f,\n\t66:  0x5f8787,\n\t67:  0x5f87af,\n\t68:  0x5f87d7,\n\t69:  0x5f87ff,\n\t70:  0x5faf00,\n\t71:  0x5faf5f,\n\t72:  0x5faf87,\n\t73:  0x5fafaf,\n\t74:  0x5fafd7,\n\t75:  0x5fafff,\n\t76:  0x5fd700,\n\t77:  0x5fd75f,\n\t78:  0x5fd787,\n\t79:  0x5fd7af,\n\t80:  0x5fd7d7,\n\t81:  0x5fd7ff,\n\t82:  0x5fff00,\n\t83:  0x5fff5f,\n\t84:  0x5fff87,\n\t85:  0x5fffaf,\n\t86:  0x5fffd7,\n\t87:  0x5fffff,\n\t88:  0x870000,\n\t89:  0x87005f,\n\t90:  0x870087,\n\t91:  0x8700af,\n\t92:  0x8700d7,\n\t93:  0x8700ff,\n\t94:  0x875f00,\n\t95:  0x875f5f,\n\t96:  0x875f87,\n\t97:  0x875faf,\n\t98:  0x875fd7,\n\t99:  0x875fff,\n\t100: 0x878700,\n\t101: 0x87875f,\n\t102: 0x878787,\n\t103: 0x8787af,\n\t104: 0x8787d7,\n\t105: 0x8787ff,\n\t106: 0x87af00,\n\t107: 0x87af5f,\n\t108: 0x87af87,\n\t109: 0x87afaf,\n\t110: 0x87afd7,\n\t111: 0x87afff,\n\t112: 0x87d700,\n\t113: 0x87d75f,\n\t114: 0x87d787,\n\t115: 0x87d7af,\n\t116: 0x87d7d7,\n\t117: 0x87d7ff,\n\t118: 0x87ff00,\n\t119: 0x87ff5f,\n\t120: 0x87ff87,\n\t121: 0x87ffaf,\n\t122: 0x87ffd7,\n\t123: 0x87ffff,\n\t124: 0xaf0000,\n\t125: 0xaf005f,\n\t126: 0xaf0087,\n\t127: 0xaf00af,\n\t128: 0xaf00d7,\n\t129: 0xaf00ff,\n\t130: 0xaf5f00,\n\t131: 0xaf5f5f,\n\t132: 0xaf5f87,\n\t133: 0xaf5faf,\n\t134: 0xaf5fd7,\n\t135: 0xaf5fff,\n\t136: 0xaf8700,\n\t137: 0xaf875f,\n\t138: 0xaf8787,\n\t139: 0xaf87af,\n\t140: 0xaf87d7,\n\t141: 0xaf87ff,\n\t142: 0xafaf00,\n\t143: 0xafaf5f,\n\t144: 0xafaf87,\n\t145: 0xafafaf,\n\t146: 0xafafd7,\n\t147: 0xafafff,\n\t148: 0xafd700,\n\t149: 0xafd75f,\n\t150: 0xafd787,\n\t151: 0xafd7af,\n\t152: 0xafd7d7,\n\t153: 0xafd7ff,\n\t154: 0xafff00,\n\t155: 0xafff5f,\n\t156: 0xafff87,\n\t157: 0xafffaf,\n\t158: 0xafffd7,\n\t159: 0xafffff,\n\t160: 0xd70000,\n\t161: 0xd7005f,\n\t162: 0xd70087,\n\t163: 0xd700af,\n\t164: 0xd700d7,\n\t165: 0xd700ff,\n\t166: 0xd75f00,\n\t167: 0xd75f5f,\n\t168: 0xd75f87,\n\t169: 0xd75faf,\n\t170: 0xd75fd7,\n\t171: 0xd75fff,\n\t172: 0xd78700,\n\t173: 0xd7875f,\n\t174: 0xd78787,\n\t175: 0xd787af,\n\t176: 0xd787d7,\n\t177: 0xd787ff,\n\t178: 0xd7af00,\n\t179: 0xd7af5f,\n\t180: 0xd7af87,\n\t181: 0xd7afaf,\n\t182: 0xd7afd7,\n\t183: 0xd7afff,\n\t184: 0xd7d700,\n\t185: 0xd7d75f,\n\t186: 0xd7d787,\n\t187: 0xd7d7af,\n\t188: 0xd7d7d7,\n\t189: 0xd7d7ff,\n\t190: 0xd7ff00,\n\t191: 0xd7ff5f,\n\t192: 0xd7ff87,\n\t193: 0xd7ffaf,\n\t194: 0xd7ffd7,\n\t195: 0xd7ffff,\n\t196: 0xff0000,\n\t197: 0xff005f,\n\t198: 0xff0087,\n\t199: 0xff00af,\n\t200: 0xff00d7,\n\t201: 0xff00ff,\n\t202: 0xff5f00,\n\t203: 0xff5f5f,\n\t204: 0xff5f87,\n\t205: 0xff5faf,\n\t206: 0xff5fd7,\n\t207: 0xff5fff,\n\t208: 0xff8700,\n\t209: 0xff875f,\n\t210: 0xff8787,\n\t211: 0xff87af,\n\t212: 0xff87d7,\n\t213: 0xff87ff,\n\t214: 0xffaf00,\n\t215: 0xffaf5f,\n\t216: 0xffaf87,\n\t217: 0xffafaf,\n\t218: 0xffafd7,\n\t219: 0xffafff,\n\t220: 0xffd700,\n\t221: 0xffd75f,\n\t222: 0xffd787,\n\t223: 0xffd7af,\n\t224: 0xffd7d7,\n\t225: 0xffd7ff,\n\t226: 0xffff00,\n\t227: 0xffff5f,\n\t228: 0xffff87,\n\t229: 0xffffaf,\n\t230: 0xffffd7,\n\t231: 0xffffff,\n\t232: 0x080808,\n\t233: 0x121212,\n\t234: 0x1c1c1c,\n\t235: 0x262626,\n\t236: 0x303030,\n\t237: 0x3a3a3a,\n\t238: 0x444444,\n\t239: 0x4e4e4e,\n\t240: 0x585858,\n\t241: 0x626262,\n\t242: 0x6c6c6c,\n\t243: 0x767676,\n\t244: 0x808080,\n\t245: 0x8a8a8a,\n\t246: 0x949494,\n\t247: 0x9e9e9e,\n\t248: 0xa8a8a8,\n\t249: 0xb2b2b2,\n\t250: 0xbcbcbc,\n\t251: 0xc6c6c6,\n\t252: 0xd0d0d0,\n\t253: 0xdadada,\n\t254: 0xe4e4e4,\n\t255: 0xeeeeee,\n}\n\n// `\\033]0;TITLESTR\\007`\nfunc doTitleSequence(er *bytes.Reader) error {\n\tvar c byte\n\tvar err error\n\n\tc, err = er.ReadByte()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif c != '0' && c != '2' {\n\t\treturn nil\n\t}\n\tc, err = er.ReadByte()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif c != ';' {\n\t\treturn nil\n\t}\n\ttitle := make([]byte, 0, 80)\n\tfor {\n\t\tc, err = er.ReadByte()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif c == 0x07 || c == '\\n' {\n\t\t\tbreak\n\t\t}\n\t\ttitle = append(title, c)\n\t}\n\tif len(title) > 0 {\n\t\ttitle8, err := syscall.UTF16PtrFromString(string(title))\n\t\tif err == nil {\n\t\t\tprocSetConsoleTitle.Call(uintptr(unsafe.Pointer(title8)))\n\t\t}\n\t}\n\treturn nil\n}\n\n// returns Atoi(s) unless s == \"\" in which case it returns def\nfunc atoiWithDefault(s string, def int) (int, error) {\n\tif s == \"\" {\n\t\treturn def, nil\n\t}\n\treturn strconv.Atoi(s)\n}\n\n// Write writes data on console\nfunc (w *Writer) Write(data []byte) (n int, err error) {\n\tw.mutex.Lock()\n\tdefer w.mutex.Unlock()\n\tvar csbi consoleScreenBufferInfo\n\tprocGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))\n\n\thandle := w.handle\n\n\tvar er *bytes.Reader\n\tif w.rest.Len() > 0 {\n\t\tvar rest bytes.Buffer\n\t\tw.rest.WriteTo(&rest)\n\t\tw.rest.Reset()\n\t\trest.Write(data)\n\t\ter = bytes.NewReader(rest.Bytes())\n\t} else {\n\t\ter = bytes.NewReader(data)\n\t}\n\tvar plaintext bytes.Buffer\nloop:\n\tfor {\n\t\tc1, err := er.ReadByte()\n\t\tif err != nil {\n\t\t\tplaintext.WriteTo(w.out)\n\t\t\tbreak loop\n\t\t}\n\t\tif c1 != 0x1b {\n\t\t\tplaintext.WriteByte(c1)\n\t\t\tcontinue\n\t\t}\n\t\t_, err = plaintext.WriteTo(w.out)\n\t\tif err != nil {\n\t\t\tbreak loop\n\t\t}\n\t\tc2, err := er.ReadByte()\n\t\tif err != nil {\n\t\t\tbreak loop\n\t\t}\n\n\t\tswitch c2 {\n\t\tcase '>':\n\t\t\tcontinue\n\t\tcase ']':\n\t\t\tw.rest.WriteByte(c1)\n\t\t\tw.rest.WriteByte(c2)\n\t\t\ter.WriteTo(&w.rest)\n\t\t\tif bytes.IndexByte(w.rest.Bytes(), 0x07) == -1 {\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\ter = bytes.NewReader(w.rest.Bytes()[2:])\n\t\t\terr := doTitleSequence(er)\n\t\t\tif err != nil {\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tw.rest.Reset()\n\t\t\tcontinue\n\t\t// https://github.com/mattn/go-colorable/issues/27\n\t\tcase '7':\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tw.oldpos = csbi.cursorPosition\n\t\t\tcontinue\n\t\tcase '8':\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos)))\n\t\t\tcontinue\n\t\tcase 0x5b:\n\t\t\t// execute part after switch\n\t\tdefault:\n\t\t\tcontinue\n\t\t}\n\n\t\tw.rest.WriteByte(c1)\n\t\tw.rest.WriteByte(c2)\n\t\ter.WriteTo(&w.rest)\n\n\t\tvar buf bytes.Buffer\n\t\tvar m byte\n\t\tfor i, c := range w.rest.Bytes()[2:] {\n\t\t\tif ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {\n\t\t\t\tm = c\n\t\t\t\ter = bytes.NewReader(w.rest.Bytes()[2+i+1:])\n\t\t\t\tw.rest.Reset()\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tbuf.Write([]byte(string(c)))\n\t\t}\n\t\tif m == 0 {\n\t\t\tbreak loop\n\t\t}\n\n\t\tswitch m {\n\t\tcase 'A':\n\t\t\tn, err = atoiWithDefault(buf.String(), 1)\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.y -= short(n)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'B':\n\t\t\tn, err = atoiWithDefault(buf.String(), 1)\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.y += short(n)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'C':\n\t\t\tn, err = atoiWithDefault(buf.String(), 1)\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.x += short(n)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'D':\n\t\t\tn, err = atoiWithDefault(buf.String(), 1)\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.x -= short(n)\n\t\t\tif csbi.cursorPosition.x < 0 {\n\t\t\t\tcsbi.cursorPosition.x = 0\n\t\t\t}\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'E':\n\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.x = 0\n\t\t\tcsbi.cursorPosition.y += short(n)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'F':\n\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.x = 0\n\t\t\tcsbi.cursorPosition.y -= short(n)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'G':\n\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif n < 1 {\n\t\t\t\tn = 1\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.x = short(n - 1)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'H', 'f':\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tif buf.Len() > 0 {\n\t\t\t\ttoken := strings.Split(buf.String(), \";\")\n\t\t\t\tswitch len(token) {\n\t\t\t\tcase 1:\n\t\t\t\t\tn1, err := strconv.Atoi(token[0])\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tcsbi.cursorPosition.y = short(n1 - 1)\n\t\t\t\tcase 2:\n\t\t\t\t\tn1, err := strconv.Atoi(token[0])\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tn2, err := strconv.Atoi(token[1])\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tcsbi.cursorPosition.x = short(n2 - 1)\n\t\t\t\t\tcsbi.cursorPosition.y = short(n1 - 1)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcsbi.cursorPosition.y = 0\n\t\t\t}\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'J':\n\t\t\tn := 0\n\t\t\tif buf.Len() > 0 {\n\t\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\t\tif err != nil {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar count, written dword\n\t\t\tvar cursor coord\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tswitch n {\n\t\t\tcase 0:\n\t\t\t\tcursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}\n\t\t\t\tcount = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*dword(csbi.size.x)\n\t\t\tcase 1:\n\t\t\t\tcursor = coord{x: csbi.window.left, y: csbi.window.top}\n\t\t\t\tcount = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.window.top-csbi.cursorPosition.y)*dword(csbi.size.x)\n\t\t\tcase 2:\n\t\t\t\tcursor = coord{x: csbi.window.left, y: csbi.window.top}\n\t\t\t\tcount = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*dword(csbi.size.x)\n\t\t\t}\n\t\t\tprocFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))\n\t\t\tprocFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))\n\t\tcase 'K':\n\t\t\tn := 0\n\t\t\tif buf.Len() > 0 {\n\t\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\t\tif err != nil {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tvar cursor coord\n\t\t\tvar count, written dword\n\t\t\tswitch n {\n\t\t\tcase 0:\n\t\t\t\tcursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}\n\t\t\t\tcount = dword(csbi.size.x - csbi.cursorPosition.x)\n\t\t\tcase 1:\n\t\t\t\tcursor = coord{x: csbi.window.left, y: csbi.cursorPosition.y}\n\t\t\t\tcount = dword(csbi.size.x - csbi.cursorPosition.x)\n\t\t\tcase 2:\n\t\t\t\tcursor = coord{x: csbi.window.left, y: csbi.cursorPosition.y}\n\t\t\t\tcount = dword(csbi.size.x)\n\t\t\t}\n\t\t\tprocFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))\n\t\t\tprocFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))\n\t\tcase 'X':\n\t\t\tn := 0\n\t\t\tif buf.Len() > 0 {\n\t\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\t\tif err != nil {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tvar cursor coord\n\t\t\tvar written dword\n\t\t\tcursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}\n\t\t\tprocFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))\n\t\t\tprocFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))\n\t\tcase 'm':\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tattr := csbi.attributes\n\t\t\tcs := buf.String()\n\t\t\tif cs == \"\" {\n\t\t\t\tprocSetConsoleTextAttribute.Call(uintptr(handle), uintptr(w.oldattr))\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ttoken := strings.Split(cs, \";\")\n\t\t\tfor i := 0; i < len(token); i++ {\n\t\t\t\tns := token[i]\n\t\t\t\tif n, err = strconv.Atoi(ns); err == nil {\n\t\t\t\t\tswitch {\n\t\t\t\t\tcase n == 0 || n == 100:\n\t\t\t\t\t\tattr = w.oldattr\n\t\t\t\t\tcase n == 4:\n\t\t\t\t\t\tattr |= commonLvbUnderscore\n\t\t\t\t\tcase (1 <= n && n <= 3) || n == 5:\n\t\t\t\t\t\tattr |= foregroundIntensity\n\t\t\t\t\tcase n == 7 || n == 27:\n\t\t\t\t\t\tattr =\n\t\t\t\t\t\t\t(attr &^ (foregroundMask | backgroundMask)) |\n\t\t\t\t\t\t\t\t((attr & foregroundMask) << 4) |\n\t\t\t\t\t\t\t\t((attr & backgroundMask) >> 4)\n\t\t\t\t\tcase n == 22:\n\t\t\t\t\t\tattr &^= foregroundIntensity\n\t\t\t\t\tcase n == 24:\n\t\t\t\t\t\tattr &^= commonLvbUnderscore\n\t\t\t\t\tcase 30 <= n && n <= 37:\n\t\t\t\t\t\tattr &= backgroundMask\n\t\t\t\t\t\tif (n-30)&1 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundRed\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-30)&2 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundGreen\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-30)&4 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundBlue\n\t\t\t\t\t\t}\n\t\t\t\t\tcase n == 38: // set foreground color.\n\t\t\t\t\t\tif i < len(token)-2 && (token[i+1] == \"5\" || token[i+1] == \"05\") {\n\t\t\t\t\t\t\tif n256, err := strconv.Atoi(token[i+2]); err == nil {\n\t\t\t\t\t\t\t\tif n256foreAttr == nil {\n\t\t\t\t\t\t\t\t\tn256setup()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tattr &= backgroundMask\n\t\t\t\t\t\t\t\tattr |= n256foreAttr[n256%len(n256foreAttr)]\n\t\t\t\t\t\t\t\ti += 2\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if len(token) == 5 && token[i+1] == \"2\" {\n\t\t\t\t\t\t\tvar r, g, b int\n\t\t\t\t\t\t\tr, _ = strconv.Atoi(token[i+2])\n\t\t\t\t\t\t\tg, _ = strconv.Atoi(token[i+3])\n\t\t\t\t\t\t\tb, _ = strconv.Atoi(token[i+4])\n\t\t\t\t\t\t\ti += 4\n\t\t\t\t\t\t\tif r > 127 {\n\t\t\t\t\t\t\t\tattr |= foregroundRed\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif g > 127 {\n\t\t\t\t\t\t\t\tattr |= foregroundGreen\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif b > 127 {\n\t\t\t\t\t\t\t\tattr |= foregroundBlue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tattr = attr & (w.oldattr & backgroundMask)\n\t\t\t\t\t\t}\n\t\t\t\t\tcase n == 39: // reset foreground color.\n\t\t\t\t\t\tattr &= backgroundMask\n\t\t\t\t\t\tattr |= w.oldattr & foregroundMask\n\t\t\t\t\tcase 40 <= n && n <= 47:\n\t\t\t\t\t\tattr &= foregroundMask\n\t\t\t\t\t\tif (n-40)&1 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundRed\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-40)&2 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundGreen\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-40)&4 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundBlue\n\t\t\t\t\t\t}\n\t\t\t\t\tcase n == 48: // set background color.\n\t\t\t\t\t\tif i < len(token)-2 && token[i+1] == \"5\" {\n\t\t\t\t\t\t\tif n256, err := strconv.Atoi(token[i+2]); err == nil {\n\t\t\t\t\t\t\t\tif n256backAttr == nil {\n\t\t\t\t\t\t\t\t\tn256setup()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tattr &= foregroundMask\n\t\t\t\t\t\t\t\tattr |= n256backAttr[n256%len(n256backAttr)]\n\t\t\t\t\t\t\t\ti += 2\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if len(token) == 5 && token[i+1] == \"2\" {\n\t\t\t\t\t\t\tvar r, g, b int\n\t\t\t\t\t\t\tr, _ = strconv.Atoi(token[i+2])\n\t\t\t\t\t\t\tg, _ = strconv.Atoi(token[i+3])\n\t\t\t\t\t\t\tb, _ = strconv.Atoi(token[i+4])\n\t\t\t\t\t\t\ti += 4\n\t\t\t\t\t\t\tif r > 127 {\n\t\t\t\t\t\t\t\tattr |= backgroundRed\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif g > 127 {\n\t\t\t\t\t\t\t\tattr |= backgroundGreen\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif b > 127 {\n\t\t\t\t\t\t\t\tattr |= backgroundBlue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tattr = attr & (w.oldattr & foregroundMask)\n\t\t\t\t\t\t}\n\t\t\t\t\tcase n == 49: // reset foreground color.\n\t\t\t\t\t\tattr &= foregroundMask\n\t\t\t\t\t\tattr |= w.oldattr & backgroundMask\n\t\t\t\t\tcase 90 <= n && n <= 97:\n\t\t\t\t\t\tattr = (attr & backgroundMask)\n\t\t\t\t\t\tattr |= foregroundIntensity\n\t\t\t\t\t\tif (n-90)&1 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundRed\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-90)&2 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundGreen\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-90)&4 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundBlue\n\t\t\t\t\t\t}\n\t\t\t\t\tcase 100 <= n && n <= 107:\n\t\t\t\t\t\tattr = (attr & foregroundMask)\n\t\t\t\t\t\tattr |= backgroundIntensity\n\t\t\t\t\t\tif (n-100)&1 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundRed\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-100)&2 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundGreen\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-100)&4 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundBlue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tprocSetConsoleTextAttribute.Call(uintptr(handle), uintptr(attr))\n\t\t\t\t}\n\t\t\t}\n\t\tcase 'h':\n\t\t\tvar ci consoleCursorInfo\n\t\t\tcs := buf.String()\n\t\t\tif cs == \"5>\" {\n\t\t\t\tprocGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))\n\t\t\t\tci.visible = 0\n\t\t\t\tprocSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))\n\t\t\t} else if cs == \"?25\" {\n\t\t\t\tprocGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))\n\t\t\t\tci.visible = 1\n\t\t\t\tprocSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))\n\t\t\t} else if cs == \"?1049\" {\n\t\t\t\tif w.althandle == 0 {\n\t\t\t\t\th, _, _ := procCreateConsoleScreenBuffer.Call(uintptr(genericRead|genericWrite), 0, 0, uintptr(consoleTextmodeBuffer), 0, 0)\n\t\t\t\t\tw.althandle = syscall.Handle(h)\n\t\t\t\t\tif w.althandle != 0 {\n\t\t\t\t\t\thandle = w.althandle\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase 'l':\n\t\t\tvar ci consoleCursorInfo\n\t\t\tcs := buf.String()\n\t\t\tif cs == \"5>\" {\n\t\t\t\tprocGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))\n\t\t\t\tci.visible = 1\n\t\t\t\tprocSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))\n\t\t\t} else if cs == \"?25\" {\n\t\t\t\tprocGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))\n\t\t\t\tci.visible = 0\n\t\t\t\tprocSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))\n\t\t\t} else if cs == \"?1049\" {\n\t\t\t\tif w.althandle != 0 {\n\t\t\t\t\tsyscall.CloseHandle(w.althandle)\n\t\t\t\t\tw.althandle = 0\n\t\t\t\t\thandle = w.handle\n\t\t\t\t}\n\t\t\t}\n\t\tcase 's':\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tw.oldpos = csbi.cursorPosition\n\t\tcase 'u':\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos)))\n\t\t}\n\t}\n\n\treturn len(data), nil\n}\n\ntype consoleColor struct {\n\trgb       int\n\tred       bool\n\tgreen     bool\n\tblue      bool\n\tintensity bool\n}\n\nfunc (c consoleColor) foregroundAttr() (attr word) {\n\tif c.red {\n\t\tattr |= foregroundRed\n\t}\n\tif c.green {\n\t\tattr |= foregroundGreen\n\t}\n\tif c.blue {\n\t\tattr |= foregroundBlue\n\t}\n\tif c.intensity {\n\t\tattr |= foregroundIntensity\n\t}\n\treturn\n}\n\nfunc (c consoleColor) backgroundAttr() (attr word) {\n\tif c.red {\n\t\tattr |= backgroundRed\n\t}\n\tif c.green {\n\t\tattr |= backgroundGreen\n\t}\n\tif c.blue {\n\t\tattr |= backgroundBlue\n\t}\n\tif c.intensity {\n\t\tattr |= backgroundIntensity\n\t}\n\treturn\n}\n\nvar color16 = []consoleColor{\n\t{0x000000, false, false, false, false},\n\t{0x000080, false, false, true, false},\n\t{0x008000, false, true, false, false},\n\t{0x008080, false, true, true, false},\n\t{0x800000, true, false, false, false},\n\t{0x800080, true, false, true, false},\n\t{0x808000, true, true, false, false},\n\t{0xc0c0c0, true, true, true, false},\n\t{0x808080, false, false, false, true},\n\t{0x0000ff, false, false, true, true},\n\t{0x00ff00, false, true, false, true},\n\t{0x00ffff, false, true, true, true},\n\t{0xff0000, true, false, false, true},\n\t{0xff00ff, true, false, true, true},\n\t{0xffff00, true, true, false, true},\n\t{0xffffff, true, true, true, true},\n}\n\ntype hsv struct {\n\th, s, v float32\n}\n\nfunc (a hsv) dist(b hsv) float32 {\n\tdh := a.h - b.h\n\tswitch {\n\tcase dh > 0.5:\n\t\tdh = 1 - dh\n\tcase dh < -0.5:\n\t\tdh = -1 - dh\n\t}\n\tds := a.s - b.s\n\tdv := a.v - b.v\n\treturn float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv)))\n}\n\nfunc toHSV(rgb int) hsv {\n\tr, g, b := float32((rgb&0xFF0000)>>16)/256.0,\n\t\tfloat32((rgb&0x00FF00)>>8)/256.0,\n\t\tfloat32(rgb&0x0000FF)/256.0\n\tmin, max := minmax3f(r, g, b)\n\th := max - min\n\tif h > 0 {\n\t\tif max == r {\n\t\t\th = (g - b) / h\n\t\t\tif h < 0 {\n\t\t\t\th += 6\n\t\t\t}\n\t\t} else if max == g {\n\t\t\th = 2 + (b-r)/h\n\t\t} else {\n\t\t\th = 4 + (r-g)/h\n\t\t}\n\t}\n\th /= 6.0\n\ts := max - min\n\tif max != 0 {\n\t\ts /= max\n\t}\n\tv := max\n\treturn hsv{h: h, s: s, v: v}\n}\n\ntype hsvTable []hsv\n\nfunc toHSVTable(rgbTable []consoleColor) hsvTable {\n\tt := make(hsvTable, len(rgbTable))\n\tfor i, c := range rgbTable {\n\t\tt[i] = toHSV(c.rgb)\n\t}\n\treturn t\n}\n\nfunc (t hsvTable) find(rgb int) consoleColor {\n\thsv := toHSV(rgb)\n\tn := 7\n\tl := float32(5.0)\n\tfor i, p := range t {\n\t\td := hsv.dist(p)\n\t\tif d < l {\n\t\t\tl, n = d, i\n\t\t}\n\t}\n\treturn color16[n]\n}\n\nfunc minmax3f(a, b, c float32) (min, max float32) {\n\tif a < b {\n\t\tif b < c {\n\t\t\treturn a, c\n\t\t} else if a < c {\n\t\t\treturn a, b\n\t\t} else {\n\t\t\treturn c, b\n\t\t}\n\t} else {\n\t\tif a < c {\n\t\t\treturn b, c\n\t\t} else if b < c {\n\t\t\treturn b, a\n\t\t} else {\n\t\t\treturn c, a\n\t\t}\n\t}\n}\n\nvar n256foreAttr []word\nvar n256backAttr []word\n\nfunc n256setup() {\n\tn256foreAttr = make([]word, 256)\n\tn256backAttr = make([]word, 256)\n\tt := toHSVTable(color16)\n\tfor i, rgb := range color256 {\n\t\tc := t.find(rgb)\n\t\tn256foreAttr[i] = c.foregroundAttr()\n\t\tn256backAttr[i] = c.backgroundAttr()\n\t}\n}\n\n// EnableColorsStdout enable colors if possible.\nfunc EnableColorsStdout(enabled *bool) func() {\n\tvar mode uint32\n\th := os.Stdout.Fd()\n\tif r, _, _ := procGetConsoleMode.Call(h, uintptr(unsafe.Pointer(&mode))); r != 0 {\n\t\tif r, _, _ = procSetConsoleMode.Call(h, uintptr(mode|cENABLE_VIRTUAL_TERMINAL_PROCESSING)); r != 0 {\n\t\t\tif enabled != nil {\n\t\t\t\t*enabled = true\n\t\t\t}\n\t\t\treturn func() {\n\t\t\t\tprocSetConsoleMode.Call(h, uintptr(mode))\n\t\t\t}\n\t\t}\n\t}\n\tif enabled != nil {\n\t\t*enabled = true\n\t}\n\treturn func() {}\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-colorable/go.test.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\necho \"\" > coverage.txt\n\nfor d in $(go list ./... | grep -v vendor); do\n    go test -race -coverprofile=profile.out -covermode=atomic \"$d\"\n    if [ -f profile.out ]; then\n        cat profile.out >> coverage.txt\n        rm profile.out\n    fi\ndone\n"
  },
  {
    "path": "vendor/github.com/mattn/go-colorable/noncolorable.go",
    "content": "package colorable\n\nimport (\n\t\"bytes\"\n\t\"io\"\n)\n\n// NonColorable holds writer but removes escape sequence.\ntype NonColorable struct {\n\tout io.Writer\n}\n\n// NewNonColorable returns new instance of Writer which removes escape sequence from Writer.\nfunc NewNonColorable(w io.Writer) io.Writer {\n\treturn &NonColorable{out: w}\n}\n\n// Write writes data on console\nfunc (w *NonColorable) Write(data []byte) (n int, err error) {\n\ter := bytes.NewReader(data)\n\tvar plaintext bytes.Buffer\nloop:\n\tfor {\n\t\tc1, err := er.ReadByte()\n\t\tif err != nil {\n\t\t\tplaintext.WriteTo(w.out)\n\t\t\tbreak loop\n\t\t}\n\t\tif c1 != 0x1b {\n\t\t\tplaintext.WriteByte(c1)\n\t\t\tcontinue\n\t\t}\n\t\t_, err = plaintext.WriteTo(w.out)\n\t\tif err != nil {\n\t\t\tbreak loop\n\t\t}\n\t\tc2, err := er.ReadByte()\n\t\tif err != nil {\n\t\t\tbreak loop\n\t\t}\n\t\tif c2 != 0x5b {\n\t\t\tcontinue\n\t\t}\n\n\t\tfor {\n\t\t\tc, err := er.ReadByte()\n\t\t\tif err != nil {\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tif ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\treturn len(data), nil\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/LICENSE",
    "content": "Copyright (c) Yasuhiro MATSUMOTO <mattn.jp@gmail.com>\n\nMIT License (Expat)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/README.md",
    "content": "# go-isatty\n\n[![Godoc Reference](https://godoc.org/github.com/mattn/go-isatty?status.svg)](http://godoc.org/github.com/mattn/go-isatty)\n[![Codecov](https://codecov.io/gh/mattn/go-isatty/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-isatty)\n[![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master)\n[![Go Report Card](https://goreportcard.com/badge/mattn/go-isatty)](https://goreportcard.com/report/mattn/go-isatty)\n\nisatty for golang\n\n## Usage\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/mattn/go-isatty\"\n\t\"os\"\n)\n\nfunc main() {\n\tif isatty.IsTerminal(os.Stdout.Fd()) {\n\t\tfmt.Println(\"Is Terminal\")\n\t} else if isatty.IsCygwinTerminal(os.Stdout.Fd()) {\n\t\tfmt.Println(\"Is Cygwin/MSYS2 Terminal\")\n\t} else {\n\t\tfmt.Println(\"Is Not Terminal\")\n\t}\n}\n```\n\n## Installation\n\n```\n$ go get github.com/mattn/go-isatty\n```\n\n## License\n\nMIT\n\n## Author\n\nYasuhiro Matsumoto (a.k.a mattn)\n\n## Thanks\n\n* k-takata: base idea for IsCygwinTerminal\n\n    https://github.com/k-takata/go-iscygpty\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/doc.go",
    "content": "// Package isatty implements interface to isatty\npackage isatty\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/go.test.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\necho \"\" > coverage.txt\n\nfor d in $(go list ./... | grep -v vendor); do\n    go test -race -coverprofile=profile.out -covermode=atomic \"$d\"\n    if [ -f profile.out ]; then\n        cat profile.out >> coverage.txt\n        rm profile.out\n    fi\ndone\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/isatty_bsd.go",
    "content": "//go:build (darwin || freebsd || openbsd || netbsd || dragonfly || hurd) && !appengine && !tinygo\n// +build darwin freebsd openbsd netbsd dragonfly hurd\n// +build !appengine\n// +build !tinygo\n\npackage isatty\n\nimport \"golang.org/x/sys/unix\"\n\n// IsTerminal return true if the file descriptor is terminal.\nfunc IsTerminal(fd uintptr) bool {\n\t_, err := unix.IoctlGetTermios(int(fd), unix.TIOCGETA)\n\treturn err == nil\n}\n\n// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2\n// terminal. This is also always false on this environment.\nfunc IsCygwinTerminal(fd uintptr) bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/isatty_others.go",
    "content": "//go:build (appengine || js || nacl || tinygo || wasm) && !windows\n// +build appengine js nacl tinygo wasm\n// +build !windows\n\npackage isatty\n\n// IsTerminal returns true if the file descriptor is terminal which\n// is always false on js and appengine classic which is a sandboxed PaaS.\nfunc IsTerminal(fd uintptr) bool {\n\treturn false\n}\n\n// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2\n// terminal. This is also always false on this environment.\nfunc IsCygwinTerminal(fd uintptr) bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/isatty_plan9.go",
    "content": "//go:build plan9\n// +build plan9\n\npackage isatty\n\nimport (\n\t\"syscall\"\n)\n\n// IsTerminal returns true if the given file descriptor is a terminal.\nfunc IsTerminal(fd uintptr) bool {\n\tpath, err := syscall.Fd2path(int(fd))\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn path == \"/dev/cons\" || path == \"/mnt/term/dev/cons\"\n}\n\n// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2\n// terminal. This is also always false on this environment.\nfunc IsCygwinTerminal(fd uintptr) bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/isatty_solaris.go",
    "content": "//go:build solaris && !appengine\n// +build solaris,!appengine\n\npackage isatty\n\nimport (\n\t\"golang.org/x/sys/unix\"\n)\n\n// IsTerminal returns true if the given file descriptor is a terminal.\n// see: https://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libc/port/gen/isatty.c\nfunc IsTerminal(fd uintptr) bool {\n\t_, err := unix.IoctlGetTermio(int(fd), unix.TCGETA)\n\treturn err == nil\n}\n\n// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2\n// terminal. This is also always false on this environment.\nfunc IsCygwinTerminal(fd uintptr) bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/isatty_tcgets.go",
    "content": "//go:build (linux || aix || zos) && !appengine && !tinygo\n// +build linux aix zos\n// +build !appengine\n// +build !tinygo\n\npackage isatty\n\nimport \"golang.org/x/sys/unix\"\n\n// IsTerminal return true if the file descriptor is terminal.\nfunc IsTerminal(fd uintptr) bool {\n\t_, err := unix.IoctlGetTermios(int(fd), unix.TCGETS)\n\treturn err == nil\n}\n\n// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2\n// terminal. This is also always false on this environment.\nfunc IsCygwinTerminal(fd uintptr) bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/isatty_windows.go",
    "content": "//go:build windows && !appengine\n// +build windows,!appengine\n\npackage isatty\n\nimport (\n\t\"errors\"\n\t\"strings\"\n\t\"syscall\"\n\t\"unicode/utf16\"\n\t\"unsafe\"\n)\n\nconst (\n\tobjectNameInfo uintptr = 1\n\tfileNameInfo           = 2\n\tfileTypePipe           = 3\n)\n\nvar (\n\tkernel32                         = syscall.NewLazyDLL(\"kernel32.dll\")\n\tntdll                            = syscall.NewLazyDLL(\"ntdll.dll\")\n\tprocGetConsoleMode               = kernel32.NewProc(\"GetConsoleMode\")\n\tprocGetFileInformationByHandleEx = kernel32.NewProc(\"GetFileInformationByHandleEx\")\n\tprocGetFileType                  = kernel32.NewProc(\"GetFileType\")\n\tprocNtQueryObject                = ntdll.NewProc(\"NtQueryObject\")\n)\n\nfunc init() {\n\t// Check if GetFileInformationByHandleEx is available.\n\tif procGetFileInformationByHandleEx.Find() != nil {\n\t\tprocGetFileInformationByHandleEx = nil\n\t}\n}\n\n// IsTerminal return true if the file descriptor is terminal.\nfunc IsTerminal(fd uintptr) bool {\n\tvar st uint32\n\tr, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0)\n\treturn r != 0 && e == 0\n}\n\n// Check pipe name is used for cygwin/msys2 pty.\n// Cygwin/MSYS2 PTY has a name like:\n//   \\{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master\nfunc isCygwinPipeName(name string) bool {\n\ttoken := strings.Split(name, \"-\")\n\tif len(token) < 5 {\n\t\treturn false\n\t}\n\n\tif token[0] != `\\msys` &&\n\t\ttoken[0] != `\\cygwin` &&\n\t\ttoken[0] != `\\Device\\NamedPipe\\msys` &&\n\t\ttoken[0] != `\\Device\\NamedPipe\\cygwin` {\n\t\treturn false\n\t}\n\n\tif token[1] == \"\" {\n\t\treturn false\n\t}\n\n\tif !strings.HasPrefix(token[2], \"pty\") {\n\t\treturn false\n\t}\n\n\tif token[3] != `from` && token[3] != `to` {\n\t\treturn false\n\t}\n\n\tif token[4] != \"master\" {\n\t\treturn false\n\t}\n\n\treturn true\n}\n\n// getFileNameByHandle use the undocomented ntdll NtQueryObject to get file full name from file handler\n// since GetFileInformationByHandleEx is not available under windows Vista and still some old fashion\n// guys are using Windows XP, this is a workaround for those guys, it will also work on system from\n// Windows vista to 10\n// see https://stackoverflow.com/a/18792477 for details\nfunc getFileNameByHandle(fd uintptr) (string, error) {\n\tif procNtQueryObject == nil {\n\t\treturn \"\", errors.New(\"ntdll.dll: NtQueryObject not supported\")\n\t}\n\n\tvar buf [4 + syscall.MAX_PATH]uint16\n\tvar result int\n\tr, _, e := syscall.Syscall6(procNtQueryObject.Addr(), 5,\n\t\tfd, objectNameInfo, uintptr(unsafe.Pointer(&buf)), uintptr(2*len(buf)), uintptr(unsafe.Pointer(&result)), 0)\n\tif r != 0 {\n\t\treturn \"\", e\n\t}\n\treturn string(utf16.Decode(buf[4 : 4+buf[0]/2])), nil\n}\n\n// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2\n// terminal.\nfunc IsCygwinTerminal(fd uintptr) bool {\n\tif procGetFileInformationByHandleEx == nil {\n\t\tname, err := getFileNameByHandle(fd)\n\t\tif err != nil {\n\t\t\treturn false\n\t\t}\n\t\treturn isCygwinPipeName(name)\n\t}\n\n\t// Cygwin/msys's pty is a pipe.\n\tft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0)\n\tif ft != fileTypePipe || e != 0 {\n\t\treturn false\n\t}\n\n\tvar buf [2 + syscall.MAX_PATH]uint16\n\tr, _, e := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(),\n\t\t4, fd, fileNameInfo, uintptr(unsafe.Pointer(&buf)),\n\t\tuintptr(len(buf)*2), 0, 0)\n\tif r == 0 || e != 0 {\n\t\treturn false\n\t}\n\n\tl := *(*uint32)(unsafe.Pointer(&buf))\n\treturn isCygwinPipeName(string(utf16.Decode(buf[2 : 2+l/2])))\n}\n"
  },
  {
    "path": "vendor/github.com/mitchellh/go-homedir/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013 Mitchell Hashimoto\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/mitchellh/go-homedir/README.md",
    "content": "# go-homedir\n\nThis is a Go library for detecting the user's home directory without\nthe use of cgo, so the library can be used in cross-compilation environments.\n\nUsage is incredibly simple, just call `homedir.Dir()` to get the home directory\nfor a user, and `homedir.Expand()` to expand the `~` in a path to the home\ndirectory.\n\n**Why not just use `os/user`?** The built-in `os/user` package requires\ncgo on Darwin systems. This means that any Go code that uses that package\ncannot cross compile. But 99% of the time the use for `os/user` is just to\nretrieve the home directory, which we can do for the current user without\ncgo. This library does that, enabling cross-compilation.\n"
  },
  {
    "path": "vendor/github.com/mitchellh/go-homedir/homedir.go",
    "content": "package homedir\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n)\n\n// DisableCache will disable caching of the home directory. Caching is enabled\n// by default.\nvar DisableCache bool\n\nvar homedirCache string\nvar cacheLock sync.RWMutex\n\n// Dir returns the home directory for the executing user.\n//\n// This uses an OS-specific method for discovering the home directory.\n// An error is returned if a home directory cannot be detected.\nfunc Dir() (string, error) {\n\tif !DisableCache {\n\t\tcacheLock.RLock()\n\t\tcached := homedirCache\n\t\tcacheLock.RUnlock()\n\t\tif cached != \"\" {\n\t\t\treturn cached, nil\n\t\t}\n\t}\n\n\tcacheLock.Lock()\n\tdefer cacheLock.Unlock()\n\n\tvar result string\n\tvar err error\n\tif runtime.GOOS == \"windows\" {\n\t\tresult, err = dirWindows()\n\t} else {\n\t\t// Unix-like system, so just assume Unix\n\t\tresult, err = dirUnix()\n\t}\n\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\thomedirCache = result\n\treturn result, nil\n}\n\n// Expand expands the path to include the home directory if the path\n// is prefixed with `~`. If it isn't prefixed with `~`, the path is\n// returned as-is.\nfunc Expand(path string) (string, error) {\n\tif len(path) == 0 {\n\t\treturn path, nil\n\t}\n\n\tif path[0] != '~' {\n\t\treturn path, nil\n\t}\n\n\tif len(path) > 1 && path[1] != '/' && path[1] != '\\\\' {\n\t\treturn \"\", errors.New(\"cannot expand user-specific home dir\")\n\t}\n\n\tdir, err := Dir()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn filepath.Join(dir, path[1:]), nil\n}\n\n// Reset clears the cache, forcing the next call to Dir to re-detect\n// the home directory. This generally never has to be called, but can be\n// useful in tests if you're modifying the home directory via the HOME\n// env var or something.\nfunc Reset() {\n\tcacheLock.Lock()\n\tdefer cacheLock.Unlock()\n\thomedirCache = \"\"\n}\n\nfunc dirUnix() (string, error) {\n\thomeEnv := \"HOME\"\n\tif runtime.GOOS == \"plan9\" {\n\t\t// On plan9, env vars are lowercase.\n\t\thomeEnv = \"home\"\n\t}\n\n\t// First prefer the HOME environmental variable\n\tif home := os.Getenv(homeEnv); home != \"\" {\n\t\treturn home, nil\n\t}\n\n\tvar stdout bytes.Buffer\n\n\t// If that fails, try OS specific commands\n\tif runtime.GOOS == \"darwin\" {\n\t\tcmd := exec.Command(\"sh\", \"-c\", `dscl -q . -read /Users/\"$(whoami)\" NFSHomeDirectory | sed 's/^[^ ]*: //'`)\n\t\tcmd.Stdout = &stdout\n\t\tif err := cmd.Run(); err == nil {\n\t\t\tresult := strings.TrimSpace(stdout.String())\n\t\t\tif result != \"\" {\n\t\t\t\treturn result, nil\n\t\t\t}\n\t\t}\n\t} else {\n\t\tcmd := exec.Command(\"getent\", \"passwd\", strconv.Itoa(os.Getuid()))\n\t\tcmd.Stdout = &stdout\n\t\tif err := cmd.Run(); err != nil {\n\t\t\t// If the error is ErrNotFound, we ignore it. Otherwise, return it.\n\t\t\tif err != exec.ErrNotFound {\n\t\t\t\treturn \"\", err\n\t\t\t}\n\t\t} else {\n\t\t\tif passwd := strings.TrimSpace(stdout.String()); passwd != \"\" {\n\t\t\t\t// username:password:uid:gid:gecos:home:shell\n\t\t\t\tpasswdParts := strings.SplitN(passwd, \":\", 7)\n\t\t\t\tif len(passwdParts) > 5 {\n\t\t\t\t\treturn passwdParts[5], nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// If all else fails, try the shell\n\tstdout.Reset()\n\tcmd := exec.Command(\"sh\", \"-c\", \"cd && pwd\")\n\tcmd.Stdout = &stdout\n\tif err := cmd.Run(); err != nil {\n\t\treturn \"\", err\n\t}\n\n\tresult := strings.TrimSpace(stdout.String())\n\tif result == \"\" {\n\t\treturn \"\", errors.New(\"blank output when reading home directory\")\n\t}\n\n\treturn result, nil\n}\n\nfunc dirWindows() (string, error) {\n\t// First prefer the HOME environmental variable\n\tif home := os.Getenv(\"HOME\"); home != \"\" {\n\t\treturn home, nil\n\t}\n\n\t// Prefer standard environment variable USERPROFILE\n\tif home := os.Getenv(\"USERPROFILE\"); home != \"\" {\n\t\treturn home, nil\n\t}\n\n\tdrive := os.Getenv(\"HOMEDRIVE\")\n\tpath := os.Getenv(\"HOMEPATH\")\n\thome := drive + path\n\tif drive == \"\" || path == \"\" {\n\t\treturn \"\", errors.New(\"HOMEDRIVE, HOMEPATH, or USERPROFILE are blank\")\n\t}\n\n\treturn home, nil\n}\n"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/.gitignore",
    "content": "/coverage.txt\n"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/.travis.yml",
    "content": "language: go\n\ngo:\n  - 1.8.x\n  - 1.x\n\nbefore_install:\n  - go get -t -v ./...\n\nscript:\n  - ./test.sh\n\nafter_success:\n  - bash <(curl -s https://codecov.io/bash)\n"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/README.md",
    "content": "# concurrent\n\n[![Sourcegraph](https://sourcegraph.com/github.com/modern-go/concurrent/-/badge.svg)](https://sourcegraph.com/github.com/modern-go/concurrent?badge)\n[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/modern-go/concurrent)\n[![Build Status](https://travis-ci.org/modern-go/concurrent.svg?branch=master)](https://travis-ci.org/modern-go/concurrent)\n[![codecov](https://codecov.io/gh/modern-go/concurrent/branch/master/graph/badge.svg)](https://codecov.io/gh/modern-go/concurrent)\n[![rcard](https://goreportcard.com/badge/github.com/modern-go/concurrent)](https://goreportcard.com/report/github.com/modern-go/concurrent)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://raw.githubusercontent.com/modern-go/concurrent/master/LICENSE)\n\n* concurrent.Map: backport sync.Map for go below 1.9\n* concurrent.Executor: goroutine with explicit ownership and cancellable\n\n# concurrent.Map\n\nbecause sync.Map is only available in go 1.9, we can use concurrent.Map to make code portable\n\n```go\nm := concurrent.NewMap()\nm.Store(\"hello\", \"world\")\nelem, found := m.Load(\"hello\")\n// elem will be \"world\"\n// found will be true\n```\n\n# concurrent.Executor\n\n```go\nexecutor := concurrent.NewUnboundedExecutor()\nexecutor.Go(func(ctx context.Context) {\n    everyMillisecond := time.NewTicker(time.Millisecond)\n    for {\n        select {\n        case <-ctx.Done():\n            fmt.Println(\"goroutine exited\")\n            return\n        case <-everyMillisecond.C:\n            // do something\n        }\n    }\n})\ntime.Sleep(time.Second)\nexecutor.StopAndWaitForever()\nfmt.Println(\"executor stopped\")\n```\n\nattach goroutine to executor instance, so that we can\n\n* cancel it by stop the executor with Stop/StopAndWait/StopAndWaitForever\n* handle panic by callback: the default behavior will no longer crash your application"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/executor.go",
    "content": "package concurrent\n\nimport \"context\"\n\n// Executor replace go keyword to start a new goroutine\n// the goroutine should cancel itself if the context passed in has been cancelled\n// the goroutine started by the executor, is owned by the executor\n// we can cancel all executors owned by the executor just by stop the executor itself\n// however Executor interface does not Stop method, the one starting and owning executor\n// should use the concrete type of executor, instead of this interface.\ntype Executor interface {\n\t// Go starts a new goroutine controlled by the context\n\tGo(handler func(ctx context.Context))\n}\n"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/go_above_19.go",
    "content": "//+build go1.9\n\npackage concurrent\n\nimport \"sync\"\n\n// Map is a wrapper for sync.Map introduced in go1.9\ntype Map struct {\n\tsync.Map\n}\n\n// NewMap creates a thread safe Map\nfunc NewMap() *Map {\n\treturn &Map{}\n}\n"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/go_below_19.go",
    "content": "//+build !go1.9\n\npackage concurrent\n\nimport \"sync\"\n\n// Map implements a thread safe map for go version below 1.9 using mutex\ntype Map struct {\n\tlock sync.RWMutex\n\tdata map[interface{}]interface{}\n}\n\n// NewMap creates a thread safe map\nfunc NewMap() *Map {\n\treturn &Map{\n\t\tdata: make(map[interface{}]interface{}, 32),\n\t}\n}\n\n// Load is same as sync.Map Load\nfunc (m *Map) Load(key interface{}) (elem interface{}, found bool) {\n\tm.lock.RLock()\n\telem, found = m.data[key]\n\tm.lock.RUnlock()\n\treturn\n}\n\n// Load is same as sync.Map Store\nfunc (m *Map) Store(key interface{}, elem interface{}) {\n\tm.lock.Lock()\n\tm.data[key] = elem\n\tm.lock.Unlock()\n}\n"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/log.go",
    "content": "package concurrent\n\nimport (\n\t\"os\"\n\t\"log\"\n\t\"io/ioutil\"\n)\n\n// ErrorLogger is used to print out error, can be set to writer other than stderr\nvar ErrorLogger = log.New(os.Stderr, \"\", 0)\n\n// InfoLogger is used to print informational message, default to off\nvar InfoLogger = log.New(ioutil.Discard, \"\", 0)"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/test.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\necho \"\" > coverage.txt\n\nfor d in $(go list ./... | grep -v vendor); do\n    go test -coverprofile=profile.out -coverpkg=github.com/modern-go/concurrent $d\n    if [ -f profile.out ]; then\n        cat profile.out >> coverage.txt\n        rm profile.out\n    fi\ndone\n"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/unbounded_executor.go",
    "content": "package concurrent\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"runtime\"\n\t\"runtime/debug\"\n\t\"sync\"\n\t\"time\"\n\t\"reflect\"\n)\n\n// HandlePanic logs goroutine panic by default\nvar HandlePanic = func(recovered interface{}, funcName string) {\n\tErrorLogger.Println(fmt.Sprintf(\"%s panic: %v\", funcName, recovered))\n\tErrorLogger.Println(string(debug.Stack()))\n}\n\n// UnboundedExecutor is a executor without limits on counts of alive goroutines\n// it tracks the goroutine started by it, and can cancel them when shutdown\ntype UnboundedExecutor struct {\n\tctx                   context.Context\n\tcancel                context.CancelFunc\n\tactiveGoroutinesMutex *sync.Mutex\n\tactiveGoroutines      map[string]int\n\tHandlePanic           func(recovered interface{}, funcName string)\n}\n\n// GlobalUnboundedExecutor has the life cycle of the program itself\n// any goroutine want to be shutdown before main exit can be started from this executor\n// GlobalUnboundedExecutor expects the main function to call stop\n// it does not magically knows the main function exits\nvar GlobalUnboundedExecutor = NewUnboundedExecutor()\n\n// NewUnboundedExecutor creates a new UnboundedExecutor,\n// UnboundedExecutor can not be created by &UnboundedExecutor{}\n// HandlePanic can be set with a callback to override global HandlePanic\nfunc NewUnboundedExecutor() *UnboundedExecutor {\n\tctx, cancel := context.WithCancel(context.TODO())\n\treturn &UnboundedExecutor{\n\t\tctx:                   ctx,\n\t\tcancel:                cancel,\n\t\tactiveGoroutinesMutex: &sync.Mutex{},\n\t\tactiveGoroutines:      map[string]int{},\n\t}\n}\n\n// Go starts a new goroutine and tracks its lifecycle.\n// Panic will be recovered and logged automatically, except for StopSignal\nfunc (executor *UnboundedExecutor) Go(handler func(ctx context.Context)) {\n\tpc := reflect.ValueOf(handler).Pointer()\n\tf := runtime.FuncForPC(pc)\n\tfuncName := f.Name()\n\tfile, line := f.FileLine(pc)\n\texecutor.activeGoroutinesMutex.Lock()\n\tdefer executor.activeGoroutinesMutex.Unlock()\n\tstartFrom := fmt.Sprintf(\"%s:%d\", file, line)\n\texecutor.activeGoroutines[startFrom] += 1\n\tgo func() {\n\t\tdefer func() {\n\t\t\trecovered := recover()\n\t\t\t// if you want to quit a goroutine without trigger HandlePanic\n\t\t\t// use runtime.Goexit() to quit\n\t\t\tif recovered != nil {\n\t\t\t\tif executor.HandlePanic == nil {\n\t\t\t\t\tHandlePanic(recovered, funcName)\n\t\t\t\t} else {\n\t\t\t\t\texecutor.HandlePanic(recovered, funcName)\n\t\t\t\t}\n\t\t\t}\n\t\t\texecutor.activeGoroutinesMutex.Lock()\n\t\t\texecutor.activeGoroutines[startFrom] -= 1\n\t\t\texecutor.activeGoroutinesMutex.Unlock()\n\t\t}()\n\t\thandler(executor.ctx)\n\t}()\n}\n\n// Stop cancel all goroutines started by this executor without wait\nfunc (executor *UnboundedExecutor) Stop() {\n\texecutor.cancel()\n}\n\n// StopAndWaitForever cancel all goroutines started by this executor and\n// wait until all goroutines exited\nfunc (executor *UnboundedExecutor) StopAndWaitForever() {\n\texecutor.StopAndWait(context.Background())\n}\n\n// StopAndWait cancel all goroutines started by this executor and wait.\n// Wait can be cancelled by the context passed in.\nfunc (executor *UnboundedExecutor) StopAndWait(ctx context.Context) {\n\texecutor.cancel()\n\tfor {\n\t\toneHundredMilliseconds := time.NewTimer(time.Millisecond * 100)\n\t\tselect {\n\t\tcase <-oneHundredMilliseconds.C:\n\t\t\tif executor.checkNoActiveGoroutines() {\n\t\t\t\treturn\n\t\t\t}\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (executor *UnboundedExecutor) checkNoActiveGoroutines() bool {\n\texecutor.activeGoroutinesMutex.Lock()\n\tdefer executor.activeGoroutinesMutex.Unlock()\n\tfor startFrom, count := range executor.activeGoroutines {\n\t\tif count > 0 {\n\t\t\tInfoLogger.Println(\"UnboundedExecutor is still waiting goroutines to quit\",\n\t\t\t\t\"startFrom\", startFrom,\n\t\t\t\t\"count\", count)\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/munnerz/goautoneg/LICENSE",
    "content": "Copyright (c) 2011, Open Knowledge Foundation Ltd.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n    Redistributions of source code must retain the above copyright\n    notice, this list of conditions and the following disclaimer.\n\n    Redistributions in binary form must reproduce the above copyright\n    notice, this list of conditions and the following disclaimer in\n    the documentation and/or other materials provided with the\n    distribution.\n\n    Neither the name of the Open Knowledge Foundation Ltd. nor the\n    names of its contributors may be used to endorse or promote\n    products derived from this software without specific prior written\n    permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(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": "vendor/github.com/munnerz/goautoneg/Makefile",
    "content": "include $(GOROOT)/src/Make.inc\n\nTARG=bitbucket.org/ww/goautoneg\nGOFILES=autoneg.go\n\ninclude $(GOROOT)/src/Make.pkg\n\nformat:\n\tgofmt -w *.go\n\ndocs:\n\tgomake clean\n\tgodoc ${TARG} > README.txt\n"
  },
  {
    "path": "vendor/github.com/munnerz/goautoneg/README.txt",
    "content": "PACKAGE\n\npackage goautoneg\nimport \"bitbucket.org/ww/goautoneg\"\n\nHTTP Content-Type Autonegotiation.\n\nThe functions in this package implement the behaviour specified in\nhttp://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html\n\nCopyright (c) 2011, Open Knowledge Foundation Ltd.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n    Redistributions of source code must retain the above copyright\n    notice, this list of conditions and the following disclaimer.\n\n    Redistributions in binary form must reproduce the above copyright\n    notice, this list of conditions and the following disclaimer in\n    the documentation and/or other materials provided with the\n    distribution.\n\n    Neither the name of the Open Knowledge Foundation Ltd. nor the\n    names of its contributors may be used to endorse or promote\n    products derived from this software without specific prior written\n    permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(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\n\nFUNCTIONS\n\nfunc Negotiate(header string, alternatives []string) (content_type string)\nNegotiate the most appropriate content_type given the accept header\nand a list of alternatives.\n\nfunc ParseAccept(header string) (accept []Accept)\nParse an Accept Header string returning a sorted list\nof clauses\n\n\nTYPES\n\ntype Accept struct {\n    Type, SubType string\n    Q             float32\n    Params        map[string]string\n}\nStructure to represent a clause in an HTTP Accept Header\n\n\nSUBDIRECTORIES\n\n\t.hg\n"
  },
  {
    "path": "vendor/github.com/munnerz/goautoneg/autoneg.go",
    "content": "/*\nHTTP Content-Type Autonegotiation.\n\nThe functions in this package implement the behaviour specified in\nhttp://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html\n\nCopyright (c) 2011, Open Knowledge Foundation Ltd.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n    Redistributions of source code must retain the above copyright\n    notice, this list of conditions and the following disclaimer.\n\n    Redistributions in binary form must reproduce the above copyright\n    notice, this list of conditions and the following disclaimer in\n    the documentation and/or other materials provided with the\n    distribution.\n\n    Neither the name of the Open Knowledge Foundation Ltd. nor the\n    names of its contributors may be used to endorse or promote\n    products derived from this software without specific prior written\n    permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(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*/\n\npackage goautoneg\n\nimport (\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Structure to represent a clause in an HTTP Accept Header\ntype Accept struct {\n\tType, SubType string\n\tQ             float64\n\tParams        map[string]string\n}\n\n// acceptSlice is defined to implement sort interface.\ntype acceptSlice []Accept\n\nfunc (slice acceptSlice) Len() int {\n\treturn len(slice)\n}\n\nfunc (slice acceptSlice) Less(i, j int) bool {\n\tai, aj := slice[i], slice[j]\n\tif ai.Q > aj.Q {\n\t\treturn true\n\t}\n\tif ai.Type != \"*\" && aj.Type == \"*\" {\n\t\treturn true\n\t}\n\tif ai.SubType != \"*\" && aj.SubType == \"*\" {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (slice acceptSlice) Swap(i, j int) {\n\tslice[i], slice[j] = slice[j], slice[i]\n}\n\nfunc stringTrimSpaceCutset(r rune) bool {\n\treturn r == ' '\n}\n\nfunc nextSplitElement(s, sep string) (item string, remaining string) {\n\tif index := strings.Index(s, sep); index != -1 {\n\t\treturn s[:index], s[index+1:]\n\t}\n\treturn s, \"\"\n}\n\n// Parse an Accept Header string returning a sorted list\n// of clauses\nfunc ParseAccept(header string) acceptSlice {\n\tpartsCount := 0\n\tremaining := header\n\tfor len(remaining) > 0 {\n\t\tpartsCount++\n\t\t_, remaining = nextSplitElement(remaining, \",\")\n\t}\n\taccept := make(acceptSlice, 0, partsCount)\n\n\tremaining = header\n\tvar part string\n\tfor len(remaining) > 0 {\n\t\tpart, remaining = nextSplitElement(remaining, \",\")\n\t\tpart = strings.TrimFunc(part, stringTrimSpaceCutset)\n\n\t\ta := Accept{\n\t\t\tQ: 1.0,\n\t\t}\n\n\t\tsp, remainingPart := nextSplitElement(part, \";\")\n\n\t\tsp0, spRemaining := nextSplitElement(sp, \"/\")\n\t\ta.Type = strings.TrimFunc(sp0, stringTrimSpaceCutset)\n\n\t\tswitch {\n\t\tcase len(spRemaining) == 0:\n\t\t\tif a.Type == \"*\" {\n\t\t\t\ta.SubType = \"*\"\n\t\t\t} else {\n\t\t\t\tcontinue\n\t\t\t}\n\t\tdefault:\n\t\t\tvar sp1 string\n\t\t\tsp1, spRemaining = nextSplitElement(spRemaining, \"/\")\n\t\t\tif len(spRemaining) > 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ta.SubType = strings.TrimFunc(sp1, stringTrimSpaceCutset)\n\t\t}\n\n\t\tif len(remainingPart) == 0 {\n\t\t\taccept = append(accept, a)\n\t\t\tcontinue\n\t\t}\n\n\t\ta.Params = make(map[string]string)\n\t\tfor len(remainingPart) > 0 {\n\t\t\tsp, remainingPart = nextSplitElement(remainingPart, \";\")\n\t\t\tsp0, spRemaining = nextSplitElement(sp, \"=\")\n\t\t\tif len(spRemaining) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tvar sp1 string\n\t\t\tsp1, spRemaining = nextSplitElement(spRemaining, \"=\")\n\t\t\tif len(spRemaining) != 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ttoken := strings.TrimFunc(sp0, stringTrimSpaceCutset)\n\t\t\tif token == \"q\" {\n\t\t\t\ta.Q, _ = strconv.ParseFloat(sp1, 32)\n\t\t\t} else {\n\t\t\t\ta.Params[token] = strings.TrimFunc(sp1, stringTrimSpaceCutset)\n\t\t\t}\n\t\t}\n\n\t\taccept = append(accept, a)\n\t}\n\n\tsort.Sort(accept)\n\treturn accept\n}\n\n// Negotiate the most appropriate content_type given the accept header\n// and a list of alternatives.\nfunc Negotiate(header string, alternatives []string) (content_type string) {\n\tasp := make([][]string, 0, len(alternatives))\n\tfor _, ctype := range alternatives {\n\t\tasp = append(asp, strings.SplitN(ctype, \"/\", 2))\n\t}\n\tfor _, clause := range ParseAccept(header) {\n\t\tfor i, ctsp := range asp {\n\t\t\tif clause.Type == ctsp[0] && clause.SubType == ctsp[1] {\n\t\t\t\tcontent_type = alternatives[i]\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif clause.Type == ctsp[0] && clause.SubType == \"*\" {\n\t\t\t\tcontent_type = alternatives[i]\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif clause.Type == \"*\" && clause.SubType == \"*\" {\n\t\t\t\tcontent_type = alternatives[i]\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/LICENSE",
    "content": "Copyright (c) 2013-2014 Onsi Fakhouri\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/config/deprecated.go",
    "content": "package config\n\n// GinkgoConfigType has been deprecated and its equivalent now lives in\n// the types package.  You can no longer access Ginkgo configuration from the config\n// package.  Instead use the DSL's GinkgoConfiguration() function to get copies of the\n// current configuration\n//\n// GinkgoConfigType is still here so custom V1 reporters do not result in a compilation error\n// It will be removed in a future minor release of Ginkgo\ntype GinkgoConfigType = DeprecatedGinkgoConfigType\ntype DeprecatedGinkgoConfigType struct {\n\tRandomSeed         int64\n\tRandomizeAllSpecs  bool\n\tRegexScansFilePath bool\n\tFocusStrings       []string\n\tSkipStrings        []string\n\tSkipMeasurements   bool\n\tFailOnPending      bool\n\tFailFast           bool\n\tFlakeAttempts      int\n\tEmitSpecProgress   bool\n\tDryRun             bool\n\tDebugParallel      bool\n\n\tParallelNode  int\n\tParallelTotal int\n\tSyncHost      string\n\tStreamHost    string\n}\n\n// DefaultReporterConfigType has been deprecated and its equivalent now lives in\n// the types package.  You can no longer access Ginkgo configuration from the config\n// package.  Instead use the DSL's GinkgoConfiguration() function to get copies of the\n// current configuration\n//\n// DefaultReporterConfigType is still here so custom V1 reporters do not result in a compilation error\n// It will be removed in a future minor release of Ginkgo\ntype DefaultReporterConfigType = DeprecatedDefaultReporterConfigType\ntype DeprecatedDefaultReporterConfigType struct {\n\tNoColor           bool\n\tSlowSpecThreshold float64\n\tNoisyPendings     bool\n\tNoisySkippings    bool\n\tSuccinct          bool\n\tVerbose           bool\n\tFullTrace         bool\n\tReportPassed      bool\n\tReportFile        string\n}\n\n// Sadly there is no way to gracefully deprecate access to these global config variables.\n// Users who need access to Ginkgo's configuration should use the DSL's GinkgoConfiguration() method\n// These new unwieldy type names exist to give users a hint when they try to compile and the compilation fails\ntype GinkgoConfigIsNoLongerAccessibleFromTheConfigPackageUseTheDSLsGinkgoConfigurationFunctionInstead struct{}\n\n// Sadly there is no way to gracefully deprecate access to these global config variables.\n// Users who need access to Ginkgo's configuration should use the DSL's GinkgoConfiguration() method\n// These new unwieldy type names exist to give users a hint when they try to compile and the compilation fails\nvar GinkgoConfig = GinkgoConfigIsNoLongerAccessibleFromTheConfigPackageUseTheDSLsGinkgoConfigurationFunctionInstead{}\n\n// Sadly there is no way to gracefully deprecate access to these global config variables.\n// Users who need access to Ginkgo's configuration should use the DSL's GinkgoConfiguration() method\n// These new unwieldy type names exist to give users a hint when they try to compile and the compilation fails\ntype DefaultReporterConfigIsNoLongerAccessibleFromTheConfigPackageUseTheDSLsGinkgoConfigurationFunctionInstead struct{}\n\n// Sadly there is no way to gracefully deprecate access to these global config variables.\n// Users who need access to Ginkgo's configuration should use the DSL's GinkgoConfiguration() method\n// These new unwieldy type names exist to give users a hint when they try to compile and the compilation fails\nvar DefaultReporterConfig = DefaultReporterConfigIsNoLongerAccessibleFromTheConfigPackageUseTheDSLsGinkgoConfigurationFunctionInstead{}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/formatter/colorable_others.go",
    "content": "// +build !windows\n\n/*\nThese packages are used for colorize on Windows and contributed by mattn.jp@gmail.com\n\n  * go-colorable: <https://github.com/mattn/go-colorable>\n  * go-isatty: <https://github.com/mattn/go-isatty>\n\nThe MIT License (MIT)\n\nCopyright (c) 2016 Yasuhiro Matsumoto\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\npackage formatter\n\nimport (\n\t\"io\"\n\t\"os\"\n)\n\nfunc newColorable(file *os.File) io.Writer {\n\treturn file\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/formatter/colorable_windows.go",
    "content": "/*\nThese packages are used for colorize on Windows and contributed by mattn.jp@gmail.com\n\n  * go-colorable: <https://github.com/mattn/go-colorable>\n  * go-isatty: <https://github.com/mattn/go-isatty>\n\nThe MIT License (MIT)\n\nCopyright (c) 2016 Yasuhiro Matsumoto\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\npackage formatter\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nvar (\n\tkernel32                       = syscall.NewLazyDLL(\"kernel32.dll\")\n\tprocGetConsoleScreenBufferInfo = kernel32.NewProc(\"GetConsoleScreenBufferInfo\")\n\tprocSetConsoleTextAttribute    = kernel32.NewProc(\"SetConsoleTextAttribute\")\n\tprocSetConsoleCursorPosition   = kernel32.NewProc(\"SetConsoleCursorPosition\")\n\tprocFillConsoleOutputCharacter = kernel32.NewProc(\"FillConsoleOutputCharacterW\")\n\tprocFillConsoleOutputAttribute = kernel32.NewProc(\"FillConsoleOutputAttribute\")\n\tprocGetConsoleMode             = kernel32.NewProc(\"GetConsoleMode\")\n)\n\nfunc isTerminal(fd uintptr) bool {\n\tvar st uint32\n\tr, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0)\n\treturn r != 0 && e == 0\n}\n\nconst (\n\tforegroundBlue      = 0x1\n\tforegroundGreen     = 0x2\n\tforegroundRed       = 0x4\n\tforegroundIntensity = 0x8\n\tforegroundMask      = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity)\n\tbackgroundBlue      = 0x10\n\tbackgroundGreen     = 0x20\n\tbackgroundRed       = 0x40\n\tbackgroundIntensity = 0x80\n\tbackgroundMask      = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity)\n)\n\ntype wchar uint16\ntype short int16\ntype dword uint32\ntype word uint16\n\ntype coord struct {\n\tx short\n\ty short\n}\n\ntype smallRect struct {\n\tleft   short\n\ttop    short\n\tright  short\n\tbottom short\n}\n\ntype consoleScreenBufferInfo struct {\n\tsize              coord\n\tcursorPosition    coord\n\tattributes        word\n\twindow            smallRect\n\tmaximumWindowSize coord\n}\n\ntype writer struct {\n\tout     io.Writer\n\thandle  syscall.Handle\n\tlastbuf bytes.Buffer\n\toldattr word\n}\n\nfunc newColorable(file *os.File) io.Writer {\n\tif file == nil {\n\t\tpanic(\"nil passed instead of *os.File to NewColorable()\")\n\t}\n\n\tif isTerminal(file.Fd()) {\n\t\tvar csbi consoleScreenBufferInfo\n\t\thandle := syscall.Handle(file.Fd())\n\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\treturn &writer{out: file, handle: handle, oldattr: csbi.attributes}\n\t} else {\n\t\treturn file\n\t}\n}\n\nvar color256 = map[int]int{\n\t0:   0x000000,\n\t1:   0x800000,\n\t2:   0x008000,\n\t3:   0x808000,\n\t4:   0x000080,\n\t5:   0x800080,\n\t6:   0x008080,\n\t7:   0xc0c0c0,\n\t8:   0x808080,\n\t9:   0xff0000,\n\t10:  0x00ff00,\n\t11:  0xffff00,\n\t12:  0x0000ff,\n\t13:  0xff00ff,\n\t14:  0x00ffff,\n\t15:  0xffffff,\n\t16:  0x000000,\n\t17:  0x00005f,\n\t18:  0x000087,\n\t19:  0x0000af,\n\t20:  0x0000d7,\n\t21:  0x0000ff,\n\t22:  0x005f00,\n\t23:  0x005f5f,\n\t24:  0x005f87,\n\t25:  0x005faf,\n\t26:  0x005fd7,\n\t27:  0x005fff,\n\t28:  0x008700,\n\t29:  0x00875f,\n\t30:  0x008787,\n\t31:  0x0087af,\n\t32:  0x0087d7,\n\t33:  0x0087ff,\n\t34:  0x00af00,\n\t35:  0x00af5f,\n\t36:  0x00af87,\n\t37:  0x00afaf,\n\t38:  0x00afd7,\n\t39:  0x00afff,\n\t40:  0x00d700,\n\t41:  0x00d75f,\n\t42:  0x00d787,\n\t43:  0x00d7af,\n\t44:  0x00d7d7,\n\t45:  0x00d7ff,\n\t46:  0x00ff00,\n\t47:  0x00ff5f,\n\t48:  0x00ff87,\n\t49:  0x00ffaf,\n\t50:  0x00ffd7,\n\t51:  0x00ffff,\n\t52:  0x5f0000,\n\t53:  0x5f005f,\n\t54:  0x5f0087,\n\t55:  0x5f00af,\n\t56:  0x5f00d7,\n\t57:  0x5f00ff,\n\t58:  0x5f5f00,\n\t59:  0x5f5f5f,\n\t60:  0x5f5f87,\n\t61:  0x5f5faf,\n\t62:  0x5f5fd7,\n\t63:  0x5f5fff,\n\t64:  0x5f8700,\n\t65:  0x5f875f,\n\t66:  0x5f8787,\n\t67:  0x5f87af,\n\t68:  0x5f87d7,\n\t69:  0x5f87ff,\n\t70:  0x5faf00,\n\t71:  0x5faf5f,\n\t72:  0x5faf87,\n\t73:  0x5fafaf,\n\t74:  0x5fafd7,\n\t75:  0x5fafff,\n\t76:  0x5fd700,\n\t77:  0x5fd75f,\n\t78:  0x5fd787,\n\t79:  0x5fd7af,\n\t80:  0x5fd7d7,\n\t81:  0x5fd7ff,\n\t82:  0x5fff00,\n\t83:  0x5fff5f,\n\t84:  0x5fff87,\n\t85:  0x5fffaf,\n\t86:  0x5fffd7,\n\t87:  0x5fffff,\n\t88:  0x870000,\n\t89:  0x87005f,\n\t90:  0x870087,\n\t91:  0x8700af,\n\t92:  0x8700d7,\n\t93:  0x8700ff,\n\t94:  0x875f00,\n\t95:  0x875f5f,\n\t96:  0x875f87,\n\t97:  0x875faf,\n\t98:  0x875fd7,\n\t99:  0x875fff,\n\t100: 0x878700,\n\t101: 0x87875f,\n\t102: 0x878787,\n\t103: 0x8787af,\n\t104: 0x8787d7,\n\t105: 0x8787ff,\n\t106: 0x87af00,\n\t107: 0x87af5f,\n\t108: 0x87af87,\n\t109: 0x87afaf,\n\t110: 0x87afd7,\n\t111: 0x87afff,\n\t112: 0x87d700,\n\t113: 0x87d75f,\n\t114: 0x87d787,\n\t115: 0x87d7af,\n\t116: 0x87d7d7,\n\t117: 0x87d7ff,\n\t118: 0x87ff00,\n\t119: 0x87ff5f,\n\t120: 0x87ff87,\n\t121: 0x87ffaf,\n\t122: 0x87ffd7,\n\t123: 0x87ffff,\n\t124: 0xaf0000,\n\t125: 0xaf005f,\n\t126: 0xaf0087,\n\t127: 0xaf00af,\n\t128: 0xaf00d7,\n\t129: 0xaf00ff,\n\t130: 0xaf5f00,\n\t131: 0xaf5f5f,\n\t132: 0xaf5f87,\n\t133: 0xaf5faf,\n\t134: 0xaf5fd7,\n\t135: 0xaf5fff,\n\t136: 0xaf8700,\n\t137: 0xaf875f,\n\t138: 0xaf8787,\n\t139: 0xaf87af,\n\t140: 0xaf87d7,\n\t141: 0xaf87ff,\n\t142: 0xafaf00,\n\t143: 0xafaf5f,\n\t144: 0xafaf87,\n\t145: 0xafafaf,\n\t146: 0xafafd7,\n\t147: 0xafafff,\n\t148: 0xafd700,\n\t149: 0xafd75f,\n\t150: 0xafd787,\n\t151: 0xafd7af,\n\t152: 0xafd7d7,\n\t153: 0xafd7ff,\n\t154: 0xafff00,\n\t155: 0xafff5f,\n\t156: 0xafff87,\n\t157: 0xafffaf,\n\t158: 0xafffd7,\n\t159: 0xafffff,\n\t160: 0xd70000,\n\t161: 0xd7005f,\n\t162: 0xd70087,\n\t163: 0xd700af,\n\t164: 0xd700d7,\n\t165: 0xd700ff,\n\t166: 0xd75f00,\n\t167: 0xd75f5f,\n\t168: 0xd75f87,\n\t169: 0xd75faf,\n\t170: 0xd75fd7,\n\t171: 0xd75fff,\n\t172: 0xd78700,\n\t173: 0xd7875f,\n\t174: 0xd78787,\n\t175: 0xd787af,\n\t176: 0xd787d7,\n\t177: 0xd787ff,\n\t178: 0xd7af00,\n\t179: 0xd7af5f,\n\t180: 0xd7af87,\n\t181: 0xd7afaf,\n\t182: 0xd7afd7,\n\t183: 0xd7afff,\n\t184: 0xd7d700,\n\t185: 0xd7d75f,\n\t186: 0xd7d787,\n\t187: 0xd7d7af,\n\t188: 0xd7d7d7,\n\t189: 0xd7d7ff,\n\t190: 0xd7ff00,\n\t191: 0xd7ff5f,\n\t192: 0xd7ff87,\n\t193: 0xd7ffaf,\n\t194: 0xd7ffd7,\n\t195: 0xd7ffff,\n\t196: 0xff0000,\n\t197: 0xff005f,\n\t198: 0xff0087,\n\t199: 0xff00af,\n\t200: 0xff00d7,\n\t201: 0xff00ff,\n\t202: 0xff5f00,\n\t203: 0xff5f5f,\n\t204: 0xff5f87,\n\t205: 0xff5faf,\n\t206: 0xff5fd7,\n\t207: 0xff5fff,\n\t208: 0xff8700,\n\t209: 0xff875f,\n\t210: 0xff8787,\n\t211: 0xff87af,\n\t212: 0xff87d7,\n\t213: 0xff87ff,\n\t214: 0xffaf00,\n\t215: 0xffaf5f,\n\t216: 0xffaf87,\n\t217: 0xffafaf,\n\t218: 0xffafd7,\n\t219: 0xffafff,\n\t220: 0xffd700,\n\t221: 0xffd75f,\n\t222: 0xffd787,\n\t223: 0xffd7af,\n\t224: 0xffd7d7,\n\t225: 0xffd7ff,\n\t226: 0xffff00,\n\t227: 0xffff5f,\n\t228: 0xffff87,\n\t229: 0xffffaf,\n\t230: 0xffffd7,\n\t231: 0xffffff,\n\t232: 0x080808,\n\t233: 0x121212,\n\t234: 0x1c1c1c,\n\t235: 0x262626,\n\t236: 0x303030,\n\t237: 0x3a3a3a,\n\t238: 0x444444,\n\t239: 0x4e4e4e,\n\t240: 0x585858,\n\t241: 0x626262,\n\t242: 0x6c6c6c,\n\t243: 0x767676,\n\t244: 0x808080,\n\t245: 0x8a8a8a,\n\t246: 0x949494,\n\t247: 0x9e9e9e,\n\t248: 0xa8a8a8,\n\t249: 0xb2b2b2,\n\t250: 0xbcbcbc,\n\t251: 0xc6c6c6,\n\t252: 0xd0d0d0,\n\t253: 0xdadada,\n\t254: 0xe4e4e4,\n\t255: 0xeeeeee,\n}\n\nfunc (w *writer) Write(data []byte) (n int, err error) {\n\tvar csbi consoleScreenBufferInfo\n\tprocGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))\n\n\ter := bytes.NewBuffer(data)\nloop:\n\tfor {\n\t\tr1, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))\n\t\tif r1 == 0 {\n\t\t\tbreak loop\n\t\t}\n\n\t\tc1, _, err := er.ReadRune()\n\t\tif err != nil {\n\t\t\tbreak loop\n\t\t}\n\t\tif c1 != 0x1b {\n\t\t\tfmt.Fprint(w.out, string(c1))\n\t\t\tcontinue\n\t\t}\n\t\tc2, _, err := er.ReadRune()\n\t\tif err != nil {\n\t\t\tw.lastbuf.WriteRune(c1)\n\t\t\tbreak loop\n\t\t}\n\t\tif c2 != 0x5b {\n\t\t\tw.lastbuf.WriteRune(c1)\n\t\t\tw.lastbuf.WriteRune(c2)\n\t\t\tcontinue\n\t\t}\n\n\t\tvar buf bytes.Buffer\n\t\tvar m rune\n\t\tfor {\n\t\t\tc, _, err := er.ReadRune()\n\t\t\tif err != nil {\n\t\t\t\tw.lastbuf.WriteRune(c1)\n\t\t\t\tw.lastbuf.WriteRune(c2)\n\t\t\t\tw.lastbuf.Write(buf.Bytes())\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tif ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {\n\t\t\t\tm = c\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tbuf.Write([]byte(string(c)))\n\t\t}\n\n\t\tvar csbi consoleScreenBufferInfo\n\t\tswitch m {\n\t\tcase 'A':\n\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.y -= short(n)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'B':\n\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.y += short(n)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'C':\n\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.x -= short(n)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'D':\n\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif n, err = strconv.Atoi(buf.String()); err == nil {\n\t\t\t\tvar csbi consoleScreenBufferInfo\n\t\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\t\tcsbi.cursorPosition.x += short(n)\n\t\t\t\tprocSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\t\t}\n\t\tcase 'E':\n\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.x = 0\n\t\t\tcsbi.cursorPosition.y += short(n)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'F':\n\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.x = 0\n\t\t\tcsbi.cursorPosition.y -= short(n)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'G':\n\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.x = short(n)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'H':\n\t\t\ttoken := strings.Split(buf.String(), \";\")\n\t\t\tif len(token) != 2 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tn1, err := strconv.Atoi(token[0])\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tn2, err := strconv.Atoi(token[1])\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcsbi.cursorPosition.x = short(n2)\n\t\t\tcsbi.cursorPosition.x = short(n1)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'J':\n\t\t\tn, err := strconv.Atoi(buf.String())\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tvar cursor coord\n\t\t\tswitch n {\n\t\t\tcase 0:\n\t\t\t\tcursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}\n\t\t\tcase 1:\n\t\t\t\tcursor = coord{x: csbi.window.left, y: csbi.window.top}\n\t\t\tcase 2:\n\t\t\t\tcursor = coord{x: csbi.window.left, y: csbi.window.top}\n\t\t\t}\n\t\t\tvar count, written dword\n\t\t\tcount = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x)\n\t\t\tprocFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))\n\t\t\tprocFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))\n\t\tcase 'K':\n\t\t\tn, err := strconv.Atoi(buf.String())\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tvar cursor coord\n\t\t\tswitch n {\n\t\t\tcase 0:\n\t\t\t\tcursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}\n\t\t\tcase 1:\n\t\t\t\tcursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y}\n\t\t\tcase 2:\n\t\t\t\tcursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y}\n\t\t\t}\n\t\t\tvar count, written dword\n\t\t\tcount = dword(csbi.size.x - csbi.cursorPosition.x)\n\t\t\tprocFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))\n\t\t\tprocFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))\n\t\tcase 'm':\n\t\t\tattr := csbi.attributes\n\t\t\tcs := buf.String()\n\t\t\tif cs == \"\" {\n\t\t\t\tprocSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.oldattr))\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ttoken := strings.Split(cs, \";\")\n\t\t\tfor i := 0; i < len(token); i += 1 {\n\t\t\t\tns := token[i]\n\t\t\t\tif n, err = strconv.Atoi(ns); err == nil {\n\t\t\t\t\tswitch {\n\t\t\t\t\tcase n == 0 || n == 100:\n\t\t\t\t\t\tattr = w.oldattr\n\t\t\t\t\tcase 1 <= n && n <= 5:\n\t\t\t\t\t\tattr |= foregroundIntensity\n\t\t\t\t\tcase n == 7:\n\t\t\t\t\t\tattr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)\n\t\t\t\t\tcase 22 == n || n == 25 || n == 25:\n\t\t\t\t\t\tattr |= foregroundIntensity\n\t\t\t\t\tcase n == 27:\n\t\t\t\t\t\tattr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4)\n\t\t\t\t\tcase 30 <= n && n <= 37:\n\t\t\t\t\t\tattr = (attr & backgroundMask)\n\t\t\t\t\t\tif (n-30)&1 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundRed\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-30)&2 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundGreen\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-30)&4 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundBlue\n\t\t\t\t\t\t}\n\t\t\t\t\tcase n == 38: // set foreground color.\n\t\t\t\t\t\tif i < len(token)-2 && (token[i+1] == \"5\" || token[i+1] == \"05\") {\n\t\t\t\t\t\t\tif n256, err := strconv.Atoi(token[i+2]); err == nil {\n\t\t\t\t\t\t\t\tif n256foreAttr == nil {\n\t\t\t\t\t\t\t\t\tn256setup()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tattr &= backgroundMask\n\t\t\t\t\t\t\t\tattr |= n256foreAttr[n256]\n\t\t\t\t\t\t\t\ti += 2\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tattr = attr & (w.oldattr & backgroundMask)\n\t\t\t\t\t\t}\n\t\t\t\t\tcase n == 39: // reset foreground color.\n\t\t\t\t\t\tattr &= backgroundMask\n\t\t\t\t\t\tattr |= w.oldattr & foregroundMask\n\t\t\t\t\tcase 40 <= n && n <= 47:\n\t\t\t\t\t\tattr = (attr & foregroundMask)\n\t\t\t\t\t\tif (n-40)&1 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundRed\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-40)&2 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundGreen\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-40)&4 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundBlue\n\t\t\t\t\t\t}\n\t\t\t\t\tcase n == 48: // set background color.\n\t\t\t\t\t\tif i < len(token)-2 && token[i+1] == \"5\" {\n\t\t\t\t\t\t\tif n256, err := strconv.Atoi(token[i+2]); err == nil {\n\t\t\t\t\t\t\t\tif n256backAttr == nil {\n\t\t\t\t\t\t\t\t\tn256setup()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tattr &= foregroundMask\n\t\t\t\t\t\t\t\tattr |= n256backAttr[n256]\n\t\t\t\t\t\t\t\ti += 2\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tattr = attr & (w.oldattr & foregroundMask)\n\t\t\t\t\t\t}\n\t\t\t\t\tcase n == 49: // reset foreground color.\n\t\t\t\t\t\tattr &= foregroundMask\n\t\t\t\t\t\tattr |= w.oldattr & backgroundMask\n\t\t\t\t\tcase 90 <= n && n <= 97:\n\t\t\t\t\t\tattr = (attr & backgroundMask)\n\t\t\t\t\t\tattr |= foregroundIntensity\n\t\t\t\t\t\tif (n-90)&1 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundRed\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-90)&2 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundGreen\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-90)&4 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundBlue\n\t\t\t\t\t\t}\n\t\t\t\t\tcase 100 <= n && n <= 107:\n\t\t\t\t\t\tattr = (attr & foregroundMask)\n\t\t\t\t\t\tattr |= backgroundIntensity\n\t\t\t\t\t\tif (n-100)&1 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundRed\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-100)&2 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundGreen\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-100)&4 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundBlue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tprocSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn len(data) - w.lastbuf.Len(), nil\n}\n\ntype consoleColor struct {\n\trgb       int\n\tred       bool\n\tgreen     bool\n\tblue      bool\n\tintensity bool\n}\n\nfunc (c consoleColor) foregroundAttr() (attr word) {\n\tif c.red {\n\t\tattr |= foregroundRed\n\t}\n\tif c.green {\n\t\tattr |= foregroundGreen\n\t}\n\tif c.blue {\n\t\tattr |= foregroundBlue\n\t}\n\tif c.intensity {\n\t\tattr |= foregroundIntensity\n\t}\n\treturn\n}\n\nfunc (c consoleColor) backgroundAttr() (attr word) {\n\tif c.red {\n\t\tattr |= backgroundRed\n\t}\n\tif c.green {\n\t\tattr |= backgroundGreen\n\t}\n\tif c.blue {\n\t\tattr |= backgroundBlue\n\t}\n\tif c.intensity {\n\t\tattr |= backgroundIntensity\n\t}\n\treturn\n}\n\nvar color16 = []consoleColor{\n\tconsoleColor{0x000000, false, false, false, false},\n\tconsoleColor{0x000080, false, false, true, false},\n\tconsoleColor{0x008000, false, true, false, false},\n\tconsoleColor{0x008080, false, true, true, false},\n\tconsoleColor{0x800000, true, false, false, false},\n\tconsoleColor{0x800080, true, false, true, false},\n\tconsoleColor{0x808000, true, true, false, false},\n\tconsoleColor{0xc0c0c0, true, true, true, false},\n\tconsoleColor{0x808080, false, false, false, true},\n\tconsoleColor{0x0000ff, false, false, true, true},\n\tconsoleColor{0x00ff00, false, true, false, true},\n\tconsoleColor{0x00ffff, false, true, true, true},\n\tconsoleColor{0xff0000, true, false, false, true},\n\tconsoleColor{0xff00ff, true, false, true, true},\n\tconsoleColor{0xffff00, true, true, false, true},\n\tconsoleColor{0xffffff, true, true, true, true},\n}\n\ntype hsv struct {\n\th, s, v float32\n}\n\nfunc (a hsv) dist(b hsv) float32 {\n\tdh := a.h - b.h\n\tswitch {\n\tcase dh > 0.5:\n\t\tdh = 1 - dh\n\tcase dh < -0.5:\n\t\tdh = -1 - dh\n\t}\n\tds := a.s - b.s\n\tdv := a.v - b.v\n\treturn float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv)))\n}\n\nfunc toHSV(rgb int) hsv {\n\tr, g, b := float32((rgb&0xFF0000)>>16)/256.0,\n\t\tfloat32((rgb&0x00FF00)>>8)/256.0,\n\t\tfloat32(rgb&0x0000FF)/256.0\n\tmin, max := minmax3f(r, g, b)\n\th := max - min\n\tif h > 0 {\n\t\tif max == r {\n\t\t\th = (g - b) / h\n\t\t\tif h < 0 {\n\t\t\t\th += 6\n\t\t\t}\n\t\t} else if max == g {\n\t\t\th = 2 + (b-r)/h\n\t\t} else {\n\t\t\th = 4 + (r-g)/h\n\t\t}\n\t}\n\th /= 6.0\n\ts := max - min\n\tif max != 0 {\n\t\ts /= max\n\t}\n\tv := max\n\treturn hsv{h: h, s: s, v: v}\n}\n\ntype hsvTable []hsv\n\nfunc toHSVTable(rgbTable []consoleColor) hsvTable {\n\tt := make(hsvTable, len(rgbTable))\n\tfor i, c := range rgbTable {\n\t\tt[i] = toHSV(c.rgb)\n\t}\n\treturn t\n}\n\nfunc (t hsvTable) find(rgb int) consoleColor {\n\thsv := toHSV(rgb)\n\tn := 7\n\tl := float32(5.0)\n\tfor i, p := range t {\n\t\td := hsv.dist(p)\n\t\tif d < l {\n\t\t\tl, n = d, i\n\t\t}\n\t}\n\treturn color16[n]\n}\n\nfunc minmax3f(a, b, c float32) (min, max float32) {\n\tif a < b {\n\t\tif b < c {\n\t\t\treturn a, c\n\t\t} else if a < c {\n\t\t\treturn a, b\n\t\t} else {\n\t\t\treturn c, b\n\t\t}\n\t} else {\n\t\tif a < c {\n\t\t\treturn b, c\n\t\t} else if b < c {\n\t\t\treturn b, a\n\t\t} else {\n\t\t\treturn c, a\n\t\t}\n\t}\n}\n\nvar n256foreAttr []word\nvar n256backAttr []word\n\nfunc n256setup() {\n\tn256foreAttr = make([]word, 256)\n\tn256backAttr = make([]word, 256)\n\tt := toHSVTable(color16)\n\tfor i, rgb := range color256 {\n\t\tc := t.find(rgb)\n\t\tn256foreAttr[i] = c.foregroundAttr()\n\t\tn256backAttr[i] = c.backgroundAttr()\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/formatter/formatter.go",
    "content": "package formatter\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// ColorableStdOut and ColorableStdErr enable color output support on Windows\nvar ColorableStdOut = newColorable(os.Stdout)\nvar ColorableStdErr = newColorable(os.Stderr)\n\nconst COLS = 80\n\ntype ColorMode uint8\n\nconst (\n\tColorModeNone ColorMode = iota\n\tColorModeTerminal\n\tColorModePassthrough\n)\n\nvar SingletonFormatter = New(ColorModeTerminal)\n\nfunc F(format string, args ...any) string {\n\treturn SingletonFormatter.F(format, args...)\n}\n\nfunc Fi(indentation uint, format string, args ...any) string {\n\treturn SingletonFormatter.Fi(indentation, format, args...)\n}\n\nfunc Fiw(indentation uint, maxWidth uint, format string, args ...any) string {\n\treturn SingletonFormatter.Fiw(indentation, maxWidth, format, args...)\n}\n\ntype Formatter struct {\n\tColorMode                ColorMode\n\tcolors                   map[string]string\n\tstyleRe                  *regexp.Regexp\n\tpreserveColorStylingTags bool\n}\n\nfunc NewWithNoColorBool(noColor bool) Formatter {\n\tif noColor {\n\t\treturn New(ColorModeNone)\n\t}\n\treturn New(ColorModeTerminal)\n}\n\nfunc New(colorMode ColorMode) Formatter {\n\tcolorAliases := map[string]int{\n\t\t\"black\":   0,\n\t\t\"red\":     1,\n\t\t\"green\":   2,\n\t\t\"yellow\":  3,\n\t\t\"blue\":    4,\n\t\t\"magenta\": 5,\n\t\t\"cyan\":    6,\n\t\t\"white\":   7,\n\t}\n\tfor colorAlias, n := range colorAliases {\n\t\tcolorAliases[fmt.Sprintf(\"bright-%s\", colorAlias)] = n + 8\n\t}\n\n\tgetColor := func(color, defaultEscapeCode string) string {\n\t\tcolor = strings.ToUpper(strings.ReplaceAll(color, \"-\", \"_\"))\n\t\tenvVar := fmt.Sprintf(\"GINKGO_CLI_COLOR_%s\", color)\n\t\tenvVarColor := os.Getenv(envVar)\n\t\tif envVarColor == \"\" {\n\t\t\treturn defaultEscapeCode\n\t\t}\n\t\tif colorCode, ok := colorAliases[envVarColor]; ok {\n\t\t\treturn fmt.Sprintf(\"\\x1b[38;5;%dm\", colorCode)\n\t\t}\n\t\tcolorCode, err := strconv.Atoi(envVarColor)\n\t\tif err != nil || colorCode < 0 || colorCode > 255 {\n\t\t\treturn defaultEscapeCode\n\t\t}\n\t\treturn fmt.Sprintf(\"\\x1b[38;5;%dm\", colorCode)\n\t}\n\n\tif _, noColor := os.LookupEnv(\"GINKGO_NO_COLOR\"); noColor {\n\t\tcolorMode = ColorModeNone\n\t}\n\n\tf := Formatter{\n\t\tColorMode: colorMode,\n\t\tcolors: map[string]string{\n\t\t\t\"/\":         \"\\x1b[0m\",\n\t\t\t\"bold\":      \"\\x1b[1m\",\n\t\t\t\"underline\": \"\\x1b[4m\",\n\n\t\t\t\"red\":          getColor(\"red\", \"\\x1b[38;5;9m\"),\n\t\t\t\"orange\":       getColor(\"orange\", \"\\x1b[38;5;214m\"),\n\t\t\t\"coral\":        getColor(\"coral\", \"\\x1b[38;5;204m\"),\n\t\t\t\"magenta\":      getColor(\"magenta\", \"\\x1b[38;5;13m\"),\n\t\t\t\"green\":        getColor(\"green\", \"\\x1b[38;5;10m\"),\n\t\t\t\"dark-green\":   getColor(\"dark-green\", \"\\x1b[38;5;28m\"),\n\t\t\t\"yellow\":       getColor(\"yellow\", \"\\x1b[38;5;11m\"),\n\t\t\t\"light-yellow\": getColor(\"light-yellow\", \"\\x1b[38;5;228m\"),\n\t\t\t\"cyan\":         getColor(\"cyan\", \"\\x1b[38;5;14m\"),\n\t\t\t\"gray\":         getColor(\"gray\", \"\\x1b[38;5;243m\"),\n\t\t\t\"light-gray\":   getColor(\"light-gray\", \"\\x1b[38;5;246m\"),\n\t\t\t\"blue\":         getColor(\"blue\", \"\\x1b[38;5;12m\"),\n\t\t},\n\t}\n\tcolors := []string{}\n\tfor color := range f.colors {\n\t\tcolors = append(colors, color)\n\t}\n\tf.styleRe = regexp.MustCompile(\"{{(\" + strings.Join(colors, \"|\") + \")}}\")\n\treturn f\n}\n\nfunc (f Formatter) F(format string, args ...any) string {\n\treturn f.Fi(0, format, args...)\n}\n\nfunc (f Formatter) Fi(indentation uint, format string, args ...any) string {\n\treturn f.Fiw(indentation, 0, format, args...)\n}\n\nfunc (f Formatter) Fiw(indentation uint, maxWidth uint, format string, args ...any) string {\n\tout := f.style(format)\n\tif len(args) > 0 {\n\t\tout = fmt.Sprintf(out, args...)\n\t}\n\n\tif indentation == 0 && maxWidth == 0 {\n\t\treturn out\n\t}\n\n\tlines := strings.Split(out, \"\\n\")\n\n\tif maxWidth != 0 {\n\t\toutLines := []string{}\n\n\t\tmaxWidth = maxWidth - indentation*2\n\t\tfor _, line := range lines {\n\t\t\tif f.length(line) <= maxWidth {\n\t\t\t\toutLines = append(outLines, line)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\twords := strings.Split(line, \" \")\n\t\t\toutWords := []string{words[0]}\n\t\t\tlength := uint(f.length(words[0]))\n\t\t\tfor _, word := range words[1:] {\n\t\t\t\twordLength := f.length(word)\n\t\t\t\tif length+wordLength+1 <= maxWidth {\n\t\t\t\t\tlength += wordLength + 1\n\t\t\t\t\toutWords = append(outWords, word)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\toutLines = append(outLines, strings.Join(outWords, \" \"))\n\t\t\t\toutWords = []string{word}\n\t\t\t\tlength = wordLength\n\t\t\t}\n\t\t\tif len(outWords) > 0 {\n\t\t\t\toutLines = append(outLines, strings.Join(outWords, \" \"))\n\t\t\t}\n\t\t}\n\n\t\tlines = outLines\n\t}\n\n\tif indentation == 0 {\n\t\treturn strings.Join(lines, \"\\n\")\n\t}\n\n\tpadding := strings.Repeat(\"  \", int(indentation))\n\tfor i := range lines {\n\t\tif lines[i] != \"\" {\n\t\t\tlines[i] = padding + lines[i]\n\t\t}\n\t}\n\n\treturn strings.Join(lines, \"\\n\")\n}\n\nfunc (f Formatter) length(styled string) uint {\n\tn := uint(0)\n\tinStyle := false\n\tfor _, b := range styled {\n\t\tif inStyle {\n\t\t\tif b == 'm' {\n\t\t\t\tinStyle = false\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif b == '\\x1b' {\n\t\t\tinStyle = true\n\t\t\tcontinue\n\t\t}\n\t\tn += 1\n\t}\n\treturn n\n}\n\nfunc (f Formatter) CycleJoin(elements []string, joiner string, cycle []string) string {\n\tif len(elements) == 0 {\n\t\treturn \"\"\n\t}\n\tn := len(cycle)\n\tout := \"\"\n\tfor i, text := range elements {\n\t\tout += cycle[i%n] + text\n\t\tif i < len(elements)-1 {\n\t\t\tout += joiner\n\t\t}\n\t}\n\tout += \"{{/}}\"\n\treturn f.style(out)\n}\n\nfunc (f Formatter) style(s string) string {\n\tswitch f.ColorMode {\n\tcase ColorModeNone:\n\t\treturn f.styleRe.ReplaceAllString(s, \"\")\n\tcase ColorModePassthrough:\n\t\treturn s\n\tcase ColorModeTerminal:\n\t\treturn f.styleRe.ReplaceAllStringFunc(s, func(match string) string {\n\t\t\tif out, ok := f.colors[strings.Trim(match, \"{}\")]; ok {\n\t\t\t\treturn out\n\t\t\t}\n\t\t\treturn match\n\t\t})\n\t}\n\n\treturn \"\"\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/build/build_command.go",
    "content": "package build\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\n\t\"github.com/onsi/ginkgo/v2/ginkgo/command\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/internal\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\nfunc BuildBuildCommand() command.Command {\n\tvar cliConfig = types.NewDefaultCLIConfig()\n\tvar goFlagsConfig = types.NewDefaultGoFlagsConfig()\n\n\tflags, err := types.BuildBuildCommandFlagSet(&cliConfig, &goFlagsConfig)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treturn command.Command{\n\t\tName:     \"build\",\n\t\tFlags:    flags,\n\t\tUsage:    \"ginkgo build <FLAGS> <PACKAGES>\",\n\t\tShortDoc: \"Build the passed in <PACKAGES> (or the package in the current directory if left blank).\",\n\t\tDocLink:  \"precompiling-suites\",\n\t\tCommand: func(args []string, _ []string) {\n\t\t\tvar errors []error\n\t\t\tcliConfig, goFlagsConfig, errors = types.VetAndInitializeCLIAndGoConfig(cliConfig, goFlagsConfig)\n\t\t\tcommand.AbortIfErrors(\"Ginkgo detected configuration issues:\", errors)\n\n\t\t\tbuildSpecs(args, cliConfig, goFlagsConfig)\n\t\t},\n\t}\n}\n\nfunc buildSpecs(args []string, cliConfig types.CLIConfig, goFlagsConfig types.GoFlagsConfig) {\n\tsuites := internal.FindSuites(args, cliConfig, false).WithoutState(internal.TestSuiteStateSkippedByFilter)\n\tif len(suites) == 0 {\n\t\tcommand.AbortWith(\"Found no test suites\")\n\t}\n\n\tinternal.VerifyCLIAndFrameworkVersion(suites)\n\n\topc := internal.NewOrderedParallelCompiler(cliConfig.ComputedNumCompilers())\n\topc.StartCompiling(suites, goFlagsConfig, true)\n\n\tfor {\n\t\tsuiteIdx, suite := opc.Next()\n\t\tif suiteIdx >= len(suites) {\n\t\t\tbreak\n\t\t}\n\t\tsuites[suiteIdx] = suite\n\t\tif suite.State.Is(internal.TestSuiteStateFailedToCompile) {\n\t\t\tfmt.Println(suite.CompilationError.Error())\n\t\t} else {\n\t\t\tvar testBinPath string\n\t\t\tif len(goFlagsConfig.O) != 0 {\n\t\t\t\tstat, err := os.Stat(goFlagsConfig.O)\n\t\t\t\tif err != nil {\n\t\t\t\t\tpanic(err)\n\t\t\t\t}\n\t\t\t\tif stat.IsDir() {\n\t\t\t\t\ttestBinPath = goFlagsConfig.O + \"/\" + suite.PackageName + \".test\"\n\t\t\t\t} else {\n\t\t\t\t\ttestBinPath = goFlagsConfig.O\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(testBinPath) == 0 {\n\t\t\t\ttestBinPath = path.Join(suite.Path, suite.PackageName+\".test\")\n\t\t\t}\n\t\t\tfmt.Printf(\"Compiled %s\\n\", testBinPath)\n\t\t}\n\t}\n\n\tif suites.CountWithState(internal.TestSuiteStateFailedToCompile) > 0 {\n\t\tcommand.AbortWith(\"Failed to compile all tests\")\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/command/abort.go",
    "content": "package command\n\nimport \"fmt\"\n\ntype AbortDetails struct {\n\tExitCode  int\n\tError     error\n\tEmitUsage bool\n}\n\nfunc Abort(details AbortDetails) {\n\tpanic(details)\n}\n\nfunc AbortGracefullyWith(format string, args ...any) {\n\tAbort(AbortDetails{\n\t\tExitCode:  0,\n\t\tError:     fmt.Errorf(format, args...),\n\t\tEmitUsage: false,\n\t})\n}\n\nfunc AbortWith(format string, args ...any) {\n\tAbort(AbortDetails{\n\t\tExitCode:  1,\n\t\tError:     fmt.Errorf(format, args...),\n\t\tEmitUsage: false,\n\t})\n}\n\nfunc AbortWithUsage(format string, args ...any) {\n\tAbort(AbortDetails{\n\t\tExitCode:  1,\n\t\tError:     fmt.Errorf(format, args...),\n\t\tEmitUsage: true,\n\t})\n}\n\nfunc AbortIfError(preamble string, err error) {\n\tif err != nil {\n\t\tAbort(AbortDetails{\n\t\t\tExitCode:  1,\n\t\t\tError:     fmt.Errorf(\"%s\\n%s\", preamble, err.Error()),\n\t\t\tEmitUsage: false,\n\t\t})\n\t}\n}\n\nfunc AbortIfErrors(preamble string, errors []error) {\n\tif len(errors) > 0 {\n\t\tout := \"\"\n\t\tfor _, err := range errors {\n\t\t\tout += err.Error()\n\t\t}\n\t\tAbort(AbortDetails{\n\t\t\tExitCode:  1,\n\t\t\tError:     fmt.Errorf(\"%s\\n%s\", preamble, out),\n\t\t\tEmitUsage: false,\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/command/command.go",
    "content": "package command\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/onsi/ginkgo/v2/formatter\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\ntype Command struct {\n\tName          string\n\tFlags         types.GinkgoFlagSet\n\tUsage         string\n\tShortDoc      string\n\tDocumentation string\n\tDocLink       string\n\tCommand       func(args []string, additionalArgs []string)\n}\n\nfunc (c Command) Run(args []string, additionalArgs []string) {\n\targs, err := c.Flags.Parse(args)\n\tif err != nil {\n\t\tAbortWithUsage(err.Error())\n\t}\n\tfor _, arg := range args {\n\t\tif len(arg) > 1 && strings.HasPrefix(arg, \"-\") {\n\t\t\tAbortWith(types.GinkgoErrors.FlagAfterPositionalParameter().Error())\n\t\t}\n\t}\n\tc.Command(args, additionalArgs)\n}\n\nfunc (c Command) EmitUsage(writer io.Writer) {\n\tfmt.Fprintln(writer, formatter.F(\"{{bold}}\"+c.Usage+\"{{/}}\"))\n\tfmt.Fprintln(writer, formatter.F(\"{{gray}}%s{{/}}\", strings.Repeat(\"-\", len(c.Usage))))\n\tif c.ShortDoc != \"\" {\n\t\tfmt.Fprintln(writer, formatter.Fiw(0, formatter.COLS, c.ShortDoc))\n\t\tfmt.Fprintln(writer, \"\")\n\t}\n\tif c.Documentation != \"\" {\n\t\tfmt.Fprintln(writer, formatter.Fiw(0, formatter.COLS, c.Documentation))\n\t\tfmt.Fprintln(writer, \"\")\n\t}\n\tif c.DocLink != \"\" {\n\t\tfmt.Fprintln(writer, formatter.Fi(0, \"{{bold}}Learn more at:{{/}} {{cyan}}{{underline}}http://onsi.github.io/ginkgo/#%s{{/}}\", c.DocLink))\n\t\tfmt.Fprintln(writer, \"\")\n\t}\n\tflagUsage := c.Flags.Usage()\n\tif flagUsage != \"\" {\n\t\tfmt.Fprintf(writer, formatter.F(flagUsage))\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go",
    "content": "package command\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/onsi/ginkgo/v2/formatter\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\ntype Program struct {\n\tName               string\n\tHeading            string\n\tCommands           []Command\n\tDefaultCommand     Command\n\tDeprecatedCommands []DeprecatedCommand\n\n\t//For testing - leave as nil in production\n\tOutWriter io.Writer\n\tErrWriter io.Writer\n\tExiter    func(code int)\n}\n\ntype DeprecatedCommand struct {\n\tName        string\n\tDeprecation types.Deprecation\n}\n\nfunc (p Program) RunAndExit(osArgs []string) {\n\tvar command Command\n\tdeprecationTracker := types.NewDeprecationTracker()\n\tif p.Exiter == nil {\n\t\tp.Exiter = os.Exit\n\t}\n\tif p.OutWriter == nil {\n\t\tp.OutWriter = formatter.ColorableStdOut\n\t}\n\tif p.ErrWriter == nil {\n\t\tp.ErrWriter = formatter.ColorableStdErr\n\t}\n\n\tdefer func() {\n\t\texitCode := 0\n\n\t\tif r := recover(); r != nil {\n\t\t\tdetails, ok := r.(AbortDetails)\n\t\t\tif !ok {\n\t\t\t\tpanic(r)\n\t\t\t}\n\n\t\t\tif details.Error != nil {\n\t\t\t\tfmt.Fprintln(p.ErrWriter, formatter.F(\"{{red}}{{bold}}%s %s{{/}} {{red}}failed{{/}}\", p.Name, command.Name))\n\t\t\t\tfmt.Fprintln(p.ErrWriter, formatter.Fi(1, details.Error.Error()))\n\t\t\t}\n\t\t\tif details.EmitUsage {\n\t\t\t\tif details.Error != nil {\n\t\t\t\t\tfmt.Fprintln(p.ErrWriter, \"\")\n\t\t\t\t}\n\t\t\t\tcommand.EmitUsage(p.ErrWriter)\n\t\t\t}\n\t\t\texitCode = details.ExitCode\n\t\t}\n\n\t\tcommand.Flags.ValidateDeprecations(deprecationTracker)\n\t\tif deprecationTracker.DidTrackDeprecations() {\n\t\t\tfmt.Fprintln(p.ErrWriter, deprecationTracker.DeprecationsReport())\n\t\t}\n\t\tp.Exiter(exitCode)\n\t}()\n\n\targs, additionalArgs := []string{}, []string{}\n\n\tfoundDelimiter := false\n\tfor _, arg := range osArgs[1:] {\n\t\tif !foundDelimiter {\n\t\t\tif arg == \"--\" {\n\t\t\t\tfoundDelimiter = true\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tif foundDelimiter {\n\t\t\tadditionalArgs = append(additionalArgs, arg)\n\t\t} else {\n\t\t\targs = append(args, arg)\n\t\t}\n\t}\n\n\tcommand = p.DefaultCommand\n\tif len(args) > 0 {\n\t\tp.handleHelpRequestsAndExit(p.OutWriter, args)\n\t\tif command.Name == args[0] {\n\t\t\targs = args[1:]\n\t\t} else {\n\t\t\tfor _, deprecatedCommand := range p.DeprecatedCommands {\n\t\t\t\tif deprecatedCommand.Name == args[0] {\n\t\t\t\t\tdeprecationTracker.TrackDeprecation(deprecatedCommand.Deprecation)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor _, tryCommand := range p.Commands {\n\t\t\t\tif tryCommand.Name == args[0] {\n\t\t\t\t\tcommand, args = tryCommand, args[1:]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tcommand.Run(args, additionalArgs)\n}\n\nfunc (p Program) handleHelpRequestsAndExit(writer io.Writer, args []string) {\n\tif len(args) == 0 {\n\t\treturn\n\t}\n\n\tmatchesHelpFlag := func(args ...string) bool {\n\t\tfor _, arg := range args {\n\t\t\tif arg == \"--help\" || arg == \"-help\" || arg == \"-h\" || arg == \"--h\" {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\tif len(args) == 1 {\n\t\tif args[0] == \"help\" || matchesHelpFlag(args[0]) {\n\t\t\tp.EmitUsage(writer)\n\t\t\tAbort(AbortDetails{})\n\t\t}\n\t} else {\n\t\tvar name string\n\t\tif args[0] == \"help\" || matchesHelpFlag(args[0]) {\n\t\t\tname = args[1]\n\t\t} else if matchesHelpFlag(args[1:]...) {\n\t\t\tname = args[0]\n\t\t} else {\n\t\t\treturn\n\t\t}\n\n\t\tif p.DefaultCommand.Name == name || p.Name == name {\n\t\t\tp.DefaultCommand.EmitUsage(writer)\n\t\t\tAbort(AbortDetails{})\n\t\t}\n\t\tfor _, command := range p.Commands {\n\t\t\tif command.Name == name {\n\t\t\t\tcommand.EmitUsage(writer)\n\t\t\t\tAbort(AbortDetails{})\n\t\t\t}\n\t\t}\n\n\t\tfmt.Fprintln(writer, formatter.F(\"{{red}}Unknown Command: {{bold}}%s{{/}}\", name))\n\t\tfmt.Fprintln(writer, \"\")\n\t\tp.EmitUsage(writer)\n\t\tAbort(AbortDetails{ExitCode: 1})\n\t}\n}\n\nfunc (p Program) EmitUsage(writer io.Writer) {\n\tfmt.Fprintln(writer, formatter.F(p.Heading))\n\tfmt.Fprintln(writer, formatter.F(\"{{gray}}%s{{/}}\", strings.Repeat(\"-\", len(p.Heading))))\n\tfmt.Fprintln(writer, formatter.F(\"For usage information for a command, run {{bold}}%s help COMMAND{{/}}.\", p.Name))\n\tfmt.Fprintln(writer, formatter.F(\"For usage information for the default command, run {{bold}}%s help %s{{/}} or {{bold}}%s help %s{{/}}.\", p.Name, p.Name, p.Name, p.DefaultCommand.Name))\n\tfmt.Fprintln(writer, \"\")\n\tfmt.Fprintln(writer, formatter.F(\"The following commands are available:\"))\n\n\tfmt.Fprintln(writer, formatter.Fi(1, \"{{bold}}%s{{/}} or %s {{bold}}%s{{/}} - {{gray}}%s{{/}}\", p.Name, p.Name, p.DefaultCommand.Name, p.DefaultCommand.Usage))\n\tif p.DefaultCommand.ShortDoc != \"\" {\n\t\tfmt.Fprintln(writer, formatter.Fi(2, p.DefaultCommand.ShortDoc))\n\t}\n\n\tfor _, command := range p.Commands {\n\t\tfmt.Fprintln(writer, formatter.Fi(1, \"{{bold}}%s{{/}} - {{gray}}%s{{/}}\", command.Name, command.Usage))\n\t\tif command.ShortDoc != \"\" {\n\t\t\tfmt.Fprintln(writer, formatter.Fi(2, command.ShortDoc))\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/boostrap_templates.go",
    "content": "package generators\n\nvar bootstrapText = `package {{.Package}}\n\nimport (\n\t\"testing\"\n\n\t{{.GinkgoImport}}\n\t{{.GomegaImport}}\n)\n\nfunc Test{{.FormattedName}}(t *testing.T) {\n\t{{.GomegaPackage}}RegisterFailHandler({{.GinkgoPackage}}Fail)\n\t{{.GinkgoPackage}}RunSpecs(t, \"{{.FormattedName}} Suite\")\n}\n`\n\nvar agoutiBootstrapText = `package {{.Package}}\n\nimport (\n\t\"testing\"\n\n\t{{.GinkgoImport}}\n\t{{.GomegaImport}}\n\t\"github.com/sclevine/agouti\"\n)\n\nfunc Test{{.FormattedName}}(t *testing.T) {\n\t{{.GomegaPackage}}RegisterFailHandler({{.GinkgoPackage}}Fail)\n\t{{.GinkgoPackage}}RunSpecs(t, \"{{.FormattedName}} Suite\")\n}\n\nvar agoutiDriver *agouti.WebDriver\n\nvar _ = {{.GinkgoPackage}}BeforeSuite(func() {\n\t// Choose a WebDriver:\n\n\tagoutiDriver = agouti.PhantomJS()\n\t// agoutiDriver = agouti.Selenium()\n\t// agoutiDriver = agouti.ChromeDriver()\n\n\t{{.GomegaPackage}}Expect(agoutiDriver.Start()).To({{.GomegaPackage}}Succeed())\n})\n\nvar _ = {{.GinkgoPackage}}AfterSuite(func() {\n\t{{.GomegaPackage}}Expect(agoutiDriver.Stop()).To({{.GomegaPackage}}Succeed())\n})\n`\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/bootstrap_command.go",
    "content": "package generators\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"text/template\"\n\n\tsprig \"github.com/go-task/slim-sprig/v3\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/command\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/internal\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\nfunc BuildBootstrapCommand() command.Command {\n\tconf := GeneratorsConfig{}\n\tflags, err := types.NewGinkgoFlagSet(\n\t\ttypes.GinkgoFlags{\n\t\t\t{Name: \"agouti\", KeyPath: \"Agouti\",\n\t\t\t\tUsage: \"If set, bootstrap will generate a bootstrap file for writing Agouti tests\"},\n\t\t\t{Name: \"nodot\", KeyPath: \"NoDot\",\n\t\t\t\tUsage: \"If set, bootstrap will generate a bootstrap test file that does not dot-import ginkgo and gomega\"},\n\t\t\t{Name: \"internal\", KeyPath: \"Internal\",\n\t\t\t\tUsage: \"If set, bootstrap will generate a bootstrap test file that uses the regular package name (i.e. `package X`, not `package X_test`)\"},\n\t\t\t{Name: \"template\", KeyPath: \"CustomTemplate\",\n\t\t\t\tUsageArgument: \"template-file\",\n\t\t\t\tUsage:         \"If specified, generate will use the contents of the file passed as the bootstrap template\"},\n\t\t\t{Name: \"template-data\", KeyPath: \"CustomTemplateData\",\n\t\t\t\tUsageArgument: \"template-data-file\",\n\t\t\t\tUsage:         \"If specified, generate will use the contents of the file passed as data to be rendered in the bootstrap template\"},\n\t\t},\n\t\t&conf,\n\t\ttypes.GinkgoFlagSections{},\n\t)\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treturn command.Command{\n\t\tName:     \"bootstrap\",\n\t\tUsage:    \"ginkgo bootstrap\",\n\t\tShortDoc: \"Bootstrap a test suite for the current package\",\n\t\tDocumentation: `Tests written in Ginkgo and Gomega require a small amount of boilerplate to hook into Go's testing infrastructure.\n\n{{bold}}ginkgo bootstrap{{/}} generates this boilerplate for you in a file named X_suite_test.go where X is the name of the package under test.`,\n\t\tDocLink: \"generators\",\n\t\tFlags:   flags,\n\t\tCommand: func(_ []string, _ []string) {\n\t\t\tgenerateBootstrap(conf)\n\t\t},\n\t}\n}\n\ntype bootstrapData struct {\n\tPackage       string\n\tFormattedName string\n\n\tGinkgoImport  string\n\tGomegaImport  string\n\tGinkgoPackage string\n\tGomegaPackage string\n\tCustomData    map[string]any\n}\n\nfunc generateBootstrap(conf GeneratorsConfig) {\n\tpackageName, bootstrapFilePrefix, formattedName := getPackageAndFormattedName()\n\n\tdata := bootstrapData{\n\t\tPackage:       determinePackageName(packageName, conf.Internal),\n\t\tFormattedName: formattedName,\n\n\t\tGinkgoImport:  `. \"github.com/onsi/ginkgo/v2\"`,\n\t\tGomegaImport:  `. \"github.com/onsi/gomega\"`,\n\t\tGinkgoPackage: \"\",\n\t\tGomegaPackage: \"\",\n\t}\n\n\tif conf.NoDot {\n\t\tdata.GinkgoImport = `\"github.com/onsi/ginkgo/v2\"`\n\t\tdata.GomegaImport = `\"github.com/onsi/gomega\"`\n\t\tdata.GinkgoPackage = `ginkgo.`\n\t\tdata.GomegaPackage = `gomega.`\n\t}\n\n\ttargetFile := fmt.Sprintf(\"%s_suite_test.go\", bootstrapFilePrefix)\n\tif internal.FileExists(targetFile) {\n\t\tcommand.AbortWith(\"{{bold}}%s{{/}} already exists\", targetFile)\n\t} else {\n\t\tfmt.Printf(\"Generating ginkgo test suite bootstrap for %s in:\\n\\t%s\\n\", packageName, targetFile)\n\t}\n\n\tf, err := os.Create(targetFile)\n\tcommand.AbortIfError(\"Failed to create file:\", err)\n\tdefer f.Close()\n\n\tvar templateText string\n\tif conf.CustomTemplate != \"\" {\n\t\ttpl, err := os.ReadFile(conf.CustomTemplate)\n\t\tcommand.AbortIfError(\"Failed to read custom bootstrap file:\", err)\n\t\ttemplateText = string(tpl)\n\t\tif conf.CustomTemplateData != \"\" {\n\t\t\tvar tplCustomDataMap map[string]any\n\t\t\ttplCustomData, err := os.ReadFile(conf.CustomTemplateData)\n\t\t\tcommand.AbortIfError(\"Failed to read custom boostrap data file:\", err)\n\t\t\tif !json.Valid([]byte(tplCustomData)) {\n\t\t\t\tcommand.AbortWith(\"Invalid JSON object in custom data file.\")\n\t\t\t}\n\t\t\t//create map from the custom template data\n\t\t\tjson.Unmarshal(tplCustomData, &tplCustomDataMap)\n\t\t\tdata.CustomData = tplCustomDataMap\n\t\t}\n\t} else if conf.Agouti {\n\t\ttemplateText = agoutiBootstrapText\n\t} else {\n\t\ttemplateText = bootstrapText\n\t}\n\n\t//Setting the option to explicitly fail if template is rendered trying to access missing key\n\tbootstrapTemplate, err := template.New(\"bootstrap\").Funcs(sprig.TxtFuncMap()).Option(\"missingkey=error\").Parse(templateText)\n\tcommand.AbortIfError(\"Failed to parse bootstrap template:\", err)\n\n\tbuf := &bytes.Buffer{}\n\t//Being explicit about failing sooner during template rendering\n\t//when accessing custom data rather than during the go fmt command\n\terr = bootstrapTemplate.Execute(buf, data)\n\tcommand.AbortIfError(\"Failed to render bootstrap template:\", err)\n\n\tbuf.WriteTo(f)\n\n\tinternal.GoFmt(targetFile)\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generate_command.go",
    "content": "package generators\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\t\"text/template\"\n\n\tsprig \"github.com/go-task/slim-sprig/v3\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/command\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/internal\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\nfunc BuildGenerateCommand() command.Command {\n\tconf := GeneratorsConfig{}\n\tflags, err := types.NewGinkgoFlagSet(\n\t\ttypes.GinkgoFlags{\n\t\t\t{Name: \"agouti\", KeyPath: \"Agouti\",\n\t\t\t\tUsage: \"If set, generate will create a test file for writing Agouti tests\"},\n\t\t\t{Name: \"nodot\", KeyPath: \"NoDot\",\n\t\t\t\tUsage: \"If set, generate will create a test file that does not dot-import ginkgo and gomega\"},\n\t\t\t{Name: \"internal\", KeyPath: \"Internal\",\n\t\t\t\tUsage: \"If set, generate will create a test file that uses the regular package name (i.e. `package X`, not `package X_test`)\"},\n\t\t\t{Name: \"template\", KeyPath: \"CustomTemplate\",\n\t\t\t\tUsageArgument: \"template-file\",\n\t\t\t\tUsage:         \"If specified, generate will use the contents of the file passed as the test file template\"},\n\t\t\t{Name: \"template-data\", KeyPath: \"CustomTemplateData\",\n\t\t\t\tUsageArgument: \"template-data-file\",\n\t\t\t\tUsage:         \"If specified, generate will use the contents of the file passed as data to be rendered in the test file template\"},\n\t\t\t{Name: \"tags\", KeyPath: \"Tags\",\n\t\t\t\tUsageArgument: \"build-tags\",\n\t\t\t\tUsage:         \"If specified, generate will create a test file that uses the given build tags (i.e. `--tags e2e,!unit` will add `//go:build e2e,!unit`)\"},\n\t\t},\n\t\t&conf,\n\t\ttypes.GinkgoFlagSections{},\n\t)\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treturn command.Command{\n\t\tName:     \"generate\",\n\t\tUsage:    \"ginkgo generate <filename(s)>\",\n\t\tShortDoc: \"Generate a test file named <filename>_test.go\",\n\t\tDocumentation: `If the optional <filename> argument is omitted, a file named after the package in the current directory will be created.\n\nYou can pass multiple <filename(s)> to generate multiple files simultaneously.  The resulting files are named <filename>_test.go.\n\nYou can also pass a <filename> of the form \"file.go\" and generate will emit \"file_test.go\".`,\n\t\tDocLink: \"generators\",\n\t\tFlags:   flags,\n\t\tCommand: func(args []string, _ []string) {\n\t\t\tgenerateTestFiles(conf, args)\n\t\t},\n\t}\n}\n\ntype specData struct {\n\tBuildTags         string\n\tPackage           string\n\tSubject           string\n\tPackageImportPath string\n\tImportPackage     bool\n\n\tGinkgoImport  string\n\tGomegaImport  string\n\tGinkgoPackage string\n\tGomegaPackage string\n\tCustomData    map[string]any\n}\n\nfunc generateTestFiles(conf GeneratorsConfig, args []string) {\n\tsubjects := args\n\tif len(subjects) == 0 {\n\t\tsubjects = []string{\"\"}\n\t}\n\tfor _, subject := range subjects {\n\t\tgenerateTestFileForSubject(subject, conf)\n\t}\n}\n\nfunc generateTestFileForSubject(subject string, conf GeneratorsConfig) {\n\tpackageName, specFilePrefix, formattedName := getPackageAndFormattedName()\n\tif subject != \"\" {\n\t\tspecFilePrefix = formatSubject(subject)\n\t\tformattedName = prettifyName(specFilePrefix)\n\t}\n\n\tif conf.Internal {\n\t\tspecFilePrefix = specFilePrefix + \"_internal\"\n\t}\n\n\tdata := specData{\n\t\tBuildTags:         getBuildTags(conf.Tags),\n\t\tPackage:           determinePackageName(packageName, conf.Internal),\n\t\tSubject:           formattedName,\n\t\tPackageImportPath: getPackageImportPath(),\n\t\tImportPackage:     !conf.Internal,\n\n\t\tGinkgoImport:  `. \"github.com/onsi/ginkgo/v2\"`,\n\t\tGomegaImport:  `. \"github.com/onsi/gomega\"`,\n\t\tGinkgoPackage: \"\",\n\t\tGomegaPackage: \"\",\n\t}\n\n\tif conf.NoDot {\n\t\tdata.GinkgoImport = `\"github.com/onsi/ginkgo/v2\"`\n\t\tdata.GomegaImport = `\"github.com/onsi/gomega\"`\n\t\tdata.GinkgoPackage = `ginkgo.`\n\t\tdata.GomegaPackage = `gomega.`\n\t}\n\n\ttargetFile := fmt.Sprintf(\"%s_test.go\", specFilePrefix)\n\tif internal.FileExists(targetFile) {\n\t\tcommand.AbortWith(\"{{bold}}%s{{/}} already exists\", targetFile)\n\t} else {\n\t\tfmt.Printf(\"Generating ginkgo test for %s in:\\n  %s\\n\", data.Subject, targetFile)\n\t}\n\n\tf, err := os.Create(targetFile)\n\tcommand.AbortIfError(\"Failed to create test file:\", err)\n\tdefer f.Close()\n\n\tvar templateText string\n\tif conf.CustomTemplate != \"\" {\n\t\ttpl, err := os.ReadFile(conf.CustomTemplate)\n\t\tcommand.AbortIfError(\"Failed to read custom template file:\", err)\n\t\ttemplateText = string(tpl)\n\t\tif conf.CustomTemplateData != \"\" {\n\t\t\tvar tplCustomDataMap map[string]any\n\t\t\ttplCustomData, err := os.ReadFile(conf.CustomTemplateData)\n\t\t\tcommand.AbortIfError(\"Failed to read custom template data file:\", err)\n\t\t\tif !json.Valid([]byte(tplCustomData)) {\n\t\t\t\tcommand.AbortWith(\"Invalid JSON object in custom data file.\")\n\t\t\t}\n\t\t\t//create map from the custom template data\n\t\t\tjson.Unmarshal(tplCustomData, &tplCustomDataMap)\n\t\t\tdata.CustomData = tplCustomDataMap\n\t\t}\n\t} else if conf.Agouti {\n\t\ttemplateText = agoutiSpecText\n\t} else {\n\t\ttemplateText = specText\n\t}\n\n\t//Setting the option to explicitly fail if template is rendered trying to access missing key\n\tspecTemplate, err := template.New(\"spec\").Funcs(sprig.TxtFuncMap()).Option(\"missingkey=error\").Parse(templateText)\n\tcommand.AbortIfError(\"Failed to read parse test template:\", err)\n\n\t//Being explicit about failing sooner during template rendering\n\t//when accessing custom data rather than during the go fmt command\n\terr = specTemplate.Execute(f, data)\n\tcommand.AbortIfError(\"Failed to render bootstrap template:\", err)\n\tinternal.GoFmt(targetFile)\n}\n\nfunc formatSubject(name string) string {\n\tname = strings.ReplaceAll(name, \"-\", \"_\")\n\tname = strings.ReplaceAll(name, \" \", \"_\")\n\tname = strings.Split(name, \".go\")[0]\n\tname = strings.Split(name, \"_test\")[0]\n\treturn name\n}\n\n// moduleName returns module name from go.mod from given module root directory\nfunc moduleName(modRoot string) string {\n\tmodFile, err := os.Open(filepath.Join(modRoot, \"go.mod\"))\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\tdefer modFile.Close()\n\n\tmod := make([]byte, 128)\n\t_, err = modFile.Read(mod)\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\n\tslashSlash := []byte(\"//\")\n\tmoduleStr := []byte(\"module\")\n\n\tfor len(mod) > 0 {\n\t\tline := mod\n\t\tmod = nil\n\t\tif i := bytes.IndexByte(line, '\\n'); i >= 0 {\n\t\t\tline, mod = line[:i], line[i+1:]\n\t\t}\n\t\tif i := bytes.Index(line, slashSlash); i >= 0 {\n\t\t\tline = line[:i]\n\t\t}\n\t\tline = bytes.TrimSpace(line)\n\t\tif !bytes.HasPrefix(line, moduleStr) {\n\t\t\tcontinue\n\t\t}\n\t\tline = line[len(moduleStr):]\n\t\tn := len(line)\n\t\tline = bytes.TrimSpace(line)\n\t\tif len(line) == n || len(line) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tif line[0] == '\"' || line[0] == '`' {\n\t\t\tp, err := strconv.Unquote(string(line))\n\t\t\tif err != nil {\n\t\t\t\treturn \"\" // malformed quoted string or multiline module path\n\t\t\t}\n\t\t\treturn p\n\t\t}\n\n\t\treturn string(line)\n\t}\n\n\treturn \"\" // missing module path\n}\n\nfunc findModuleRoot(dir string) (root string) {\n\tdir = filepath.Clean(dir)\n\n\t// Look for enclosing go.mod.\n\tfor {\n\t\tif fi, err := os.Stat(filepath.Join(dir, \"go.mod\")); err == nil && !fi.IsDir() {\n\t\t\treturn dir\n\t\t}\n\t\td := filepath.Dir(dir)\n\t\tif d == dir {\n\t\t\tbreak\n\t\t}\n\t\tdir = d\n\t}\n\treturn \"\"\n}\n\nfunc getPackageImportPath() string {\n\tworkingDir, err := os.Getwd()\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\n\tsep := string(filepath.Separator)\n\n\t// Try go.mod file first\n\tmodRoot := findModuleRoot(workingDir)\n\tif modRoot != \"\" {\n\t\tmodName := moduleName(modRoot)\n\t\tif modName != \"\" {\n\t\t\tcd := strings.ReplaceAll(workingDir, modRoot, \"\")\n\t\t\tcd = strings.ReplaceAll(cd, sep, \"/\")\n\t\t\treturn modName + cd\n\t\t}\n\t}\n\n\t// Fallback to GOPATH structure\n\tpaths := strings.Split(workingDir, sep+\"src\"+sep)\n\tif len(paths) == 1 {\n\t\tfmt.Printf(\"\\nCouldn't identify package import path.\\n\\n\\tginkgo generate\\n\\nMust be run within a package directory under $GOPATH/src/...\\nYou're going to have to change UNKNOWN_PACKAGE_PATH in the generated file...\\n\\n\")\n\t\treturn \"UNKNOWN_PACKAGE_PATH\"\n\t}\n\treturn filepath.ToSlash(paths[len(paths)-1])\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generate_templates.go",
    "content": "package generators\n\nvar specText = `{{.BuildTags}}\npackage {{.Package}}\n\nimport (\n\t{{.GinkgoImport}}\n\t{{.GomegaImport}}\n\n\t{{if .ImportPackage}}\"{{.PackageImportPath}}\"{{end}}\n)\n\nvar _ = {{.GinkgoPackage}}Describe(\"{{.Subject}}\", func() {\n\n})\n`\n\nvar agoutiSpecText = `{{.BuildTags}}\npackage {{.Package}}\n\nimport (\n\t{{.GinkgoImport}}\n\t{{.GomegaImport}}\n\t\"github.com/sclevine/agouti\"\n\t. \"github.com/sclevine/agouti/matchers\"\n\n\t{{if .ImportPackage}}\"{{.PackageImportPath}}\"{{end}}\n)\n\nvar _ = {{.GinkgoPackage}}Describe(\"{{.Subject}}\", func() {\n\tvar page *agouti.Page\n\n\t{{.GinkgoPackage}}BeforeEach(func() {\n\t\tvar err error\n\t\tpage, err = agoutiDriver.NewPage()\n\t\t{{.GomegaPackage}}Expect(err).NotTo({{.GomegaPackage}}HaveOccurred())\n\t})\n\n\t{{.GinkgoPackage}}AfterEach(func() {\n\t\t{{.GomegaPackage}}Expect(page.Destroy()).To({{.GomegaPackage}}Succeed())\n\t})\n})\n`\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/generators/generators_common.go",
    "content": "package generators\n\nimport (\n\t\"fmt\"\n\t\"go/build\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/onsi/ginkgo/v2/ginkgo/command\"\n)\n\ntype GeneratorsConfig struct {\n\tAgouti, NoDot, Internal bool\n\tCustomTemplate          string\n\tCustomTemplateData      string\n\tTags                    string\n}\n\nfunc getPackageAndFormattedName() (string, string, string) {\n\tpath, err := os.Getwd()\n\tcommand.AbortIfError(\"Could not get current working directory:\", err)\n\n\tdirName := strings.ReplaceAll(filepath.Base(path), \"-\", \"_\")\n\tdirName = strings.ReplaceAll(dirName, \" \", \"_\")\n\n\tpkg, err := build.ImportDir(path, 0)\n\tpackageName := pkg.Name\n\tif err != nil {\n\t\tpackageName = ensureLegalPackageName(dirName)\n\t}\n\n\tformattedName := prettifyName(filepath.Base(path))\n\treturn packageName, dirName, formattedName\n}\n\nfunc ensureLegalPackageName(name string) string {\n\tif name == \"_\" {\n\t\treturn \"underscore\"\n\t}\n\tif len(name) == 0 {\n\t\treturn \"empty\"\n\t}\n\tn, isDigitErr := strconv.Atoi(string(name[0]))\n\tif isDigitErr == nil {\n\t\treturn []string{\"zero\", \"one\", \"two\", \"three\", \"four\", \"five\", \"six\", \"seven\", \"eight\", \"nine\"}[n] + name[1:]\n\t}\n\treturn name\n}\n\nfunc prettifyName(name string) string {\n\tname = strings.ReplaceAll(name, \"-\", \" \")\n\tname = strings.ReplaceAll(name, \"_\", \" \")\n\tname = strings.Title(name)\n\tname = strings.ReplaceAll(name, \" \", \"\")\n\treturn name\n}\n\nfunc determinePackageName(name string, internal bool) string {\n\tif internal {\n\t\treturn name\n\t}\n\n\treturn name + \"_test\"\n}\n\n// getBuildTags returns the resultant string to be added.\n// If the input string is not empty, then returns a `//go:build {}` string,\n// otherwise returns an empty string.\nfunc getBuildTags(tags string) string {\n\tif tags != \"\" {\n\t\treturn fmt.Sprintf(\"//go:build %s\\n\", tags)\n\t}\n\treturn \"\"\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/compile.go",
    "content": "package internal\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\nfunc CompileSuite(suite TestSuite, goFlagsConfig types.GoFlagsConfig, preserveSymbols bool) TestSuite {\n\tif suite.PathToCompiledTest != \"\" {\n\t\treturn suite\n\t}\n\n\tsuite.CompilationError = nil\n\n\tpath, err := filepath.Abs(filepath.Join(suite.Path, suite.PackageName+\".test\"))\n\tif err != nil {\n\t\tsuite.State = TestSuiteStateFailedToCompile\n\t\tsuite.CompilationError = fmt.Errorf(\"Failed to compute compilation target path:\\n%s\", err.Error())\n\t\treturn suite\n\t}\n\n\tif len(goFlagsConfig.O) > 0 {\n\t\tuserDefinedPath, err := filepath.Abs(goFlagsConfig.O)\n\t\tif err != nil {\n\t\t\tsuite.State = TestSuiteStateFailedToCompile\n\t\t\tsuite.CompilationError = fmt.Errorf(\"Failed to compute compilation target path %s:\\n%s\", goFlagsConfig.O, err.Error())\n\t\t\treturn suite\n\t\t}\n\t\tpath = userDefinedPath\n\t}\n\n\tgoFlagsConfig.O = path\n\n\tginkgoInvocationPath, _ := os.Getwd()\n\tginkgoInvocationPath, _ = filepath.Abs(ginkgoInvocationPath)\n\tpackagePath := suite.AbsPath()\n\tpathToInvocationPath, err := filepath.Rel(packagePath, ginkgoInvocationPath)\n\tif err != nil {\n\t\tsuite.State = TestSuiteStateFailedToCompile\n\t\tsuite.CompilationError = fmt.Errorf(\"Failed to get relative path from package to the current working directory:\\n%s\", err.Error())\n\t\treturn suite\n\t}\n\targs, err := types.GenerateGoTestCompileArgs(goFlagsConfig, \"./\", pathToInvocationPath, preserveSymbols)\n\tif err != nil {\n\t\tsuite.State = TestSuiteStateFailedToCompile\n\t\tsuite.CompilationError = fmt.Errorf(\"Failed to generate go test compile flags:\\n%s\", err.Error())\n\t\treturn suite\n\t}\n\n\tcmd := exec.Command(\"go\", args...)\n\tcmd.Dir = suite.Path\n\toutput, err := cmd.CombinedOutput()\n\tif err != nil {\n\t\tif len(output) > 0 {\n\t\t\tsuite.State = TestSuiteStateFailedToCompile\n\t\t\tsuite.CompilationError = fmt.Errorf(\"Failed to compile %s:\\n\\n%s\", suite.PackageName, output)\n\t\t} else {\n\t\t\tsuite.State = TestSuiteStateFailedToCompile\n\t\t\tsuite.CompilationError = fmt.Errorf(\"Failed to compile %s\\n%s\", suite.PackageName, err.Error())\n\t\t}\n\t\treturn suite\n\t}\n\n\tif strings.Contains(string(output), \"[no test files]\") {\n\t\tsuite.State = TestSuiteStateSkippedDueToEmptyCompilation\n\t\treturn suite\n\t}\n\n\tif len(output) > 0 {\n\t\tfmt.Println(string(output))\n\t}\n\n\tif !FileExists(path) {\n\t\tsuite.State = TestSuiteStateFailedToCompile\n\t\tsuite.CompilationError = fmt.Errorf(\"Failed to compile %s:\\nOutput file %s could not be found\", suite.PackageName, path)\n\t\treturn suite\n\t}\n\n\tsuite.State = TestSuiteStateCompiled\n\tsuite.PathToCompiledTest = path\n\treturn suite\n}\n\nfunc Cleanup(goFlagsConfig types.GoFlagsConfig, suites ...TestSuite) {\n\tif goFlagsConfig.BinaryMustBePreserved() {\n\t\treturn\n\t}\n\tfor _, suite := range suites {\n\t\tif !suite.Precompiled {\n\t\t\tos.Remove(suite.PathToCompiledTest)\n\t\t}\n\t}\n}\n\ntype parallelSuiteBundle struct {\n\tsuite    TestSuite\n\tcompiled chan TestSuite\n}\n\ntype OrderedParallelCompiler struct {\n\tmutex        *sync.Mutex\n\tstopped      bool\n\tnumCompilers int\n\n\tidx                int\n\tnumSuites          int\n\tcompletionChannels []chan TestSuite\n}\n\nfunc NewOrderedParallelCompiler(numCompilers int) *OrderedParallelCompiler {\n\treturn &OrderedParallelCompiler{\n\t\tmutex:        &sync.Mutex{},\n\t\tnumCompilers: numCompilers,\n\t}\n}\n\nfunc (opc *OrderedParallelCompiler) StartCompiling(suites TestSuites, goFlagsConfig types.GoFlagsConfig, preserveSymbols bool) {\n\topc.stopped = false\n\topc.idx = 0\n\topc.numSuites = len(suites)\n\topc.completionChannels = make([]chan TestSuite, opc.numSuites)\n\n\ttoCompile := make(chan parallelSuiteBundle, opc.numCompilers)\n\tfor compiler := 0; compiler < opc.numCompilers; compiler++ {\n\t\tgo func() {\n\t\t\tfor bundle := range toCompile {\n\t\t\t\tc, suite := bundle.compiled, bundle.suite\n\t\t\t\topc.mutex.Lock()\n\t\t\t\tstopped := opc.stopped\n\t\t\t\topc.mutex.Unlock()\n\t\t\t\tif !stopped {\n\t\t\t\t\tsuite = CompileSuite(suite, goFlagsConfig, preserveSymbols)\n\t\t\t\t}\n\t\t\t\tc <- suite\n\t\t\t}\n\t\t}()\n\t}\n\n\tfor idx, suite := range suites {\n\t\topc.completionChannels[idx] = make(chan TestSuite, 1)\n\t\ttoCompile <- parallelSuiteBundle{suite, opc.completionChannels[idx]}\n\t\tif idx == 0 { //compile first suite serially\n\t\t\tsuite = <-opc.completionChannels[0]\n\t\t\topc.completionChannels[0] <- suite\n\t\t}\n\t}\n\n\tclose(toCompile)\n}\n\nfunc (opc *OrderedParallelCompiler) Next() (int, TestSuite) {\n\tif opc.idx >= opc.numSuites {\n\t\treturn opc.numSuites, TestSuite{}\n\t}\n\n\tidx := opc.idx\n\tsuite := <-opc.completionChannels[idx]\n\topc.idx = opc.idx + 1\n\n\treturn idx, suite\n}\n\nfunc (opc *OrderedParallelCompiler) StopAndDrain() {\n\topc.mutex.Lock()\n\topc.stopped = true\n\topc.mutex.Unlock()\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/gocovmerge.go",
    "content": "// Copyright (c) 2015, Wade Simmons\n// All rights reserved.\n\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are met:\n\n// 1. Redistributions of source code must retain the above copyright notice, this\n//    list of conditions and the following disclaimer.\n// 2. 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// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\n// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Package gocovmerge takes the results from multiple `go test -coverprofile`\n// runs and merges them into one profile\n\n// this file was originally taken from the gocovmerge project\n// see also: https://go.shabbyrobe.org/gocovmerge\npackage internal\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"sort\"\n\n\t\"golang.org/x/tools/cover\"\n)\n\nfunc AddCoverProfile(profiles []*cover.Profile, p *cover.Profile) []*cover.Profile {\n\ti := sort.Search(len(profiles), func(i int) bool { return profiles[i].FileName >= p.FileName })\n\tif i < len(profiles) && profiles[i].FileName == p.FileName {\n\t\tMergeCoverProfiles(profiles[i], p)\n\t} else {\n\t\tprofiles = append(profiles, nil)\n\t\tcopy(profiles[i+1:], profiles[i:])\n\t\tprofiles[i] = p\n\t}\n\treturn profiles\n}\n\nfunc DumpCoverProfiles(profiles []*cover.Profile, out io.Writer) error {\n\tif len(profiles) == 0 {\n\t\treturn nil\n\t}\n\tif _, err := fmt.Fprintf(out, \"mode: %s\\n\", profiles[0].Mode); err != nil {\n\t\treturn err\n\t}\n\tfor _, p := range profiles {\n\t\tfor _, b := range p.Blocks {\n\t\t\tif _, err := fmt.Fprintf(out, \"%s:%d.%d,%d.%d %d %d\\n\", p.FileName, b.StartLine, b.StartCol, b.EndLine, b.EndCol, b.NumStmt, b.Count); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc MergeCoverProfiles(into *cover.Profile, merge *cover.Profile) error {\n\tif into.Mode != merge.Mode {\n\t\treturn fmt.Errorf(\"cannot merge profiles with different modes\")\n\t}\n\t// Since the blocks are sorted, we can keep track of where the last block\n\t// was inserted and only look at the blocks after that as targets for merge\n\tstartIndex := 0\n\tfor _, b := range merge.Blocks {\n\t\tvar err error\n\t\tstartIndex, err = mergeProfileBlock(into, b, startIndex)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc mergeProfileBlock(p *cover.Profile, pb cover.ProfileBlock, startIndex int) (int, error) {\n\tsortFunc := func(i int) bool {\n\t\tpi := p.Blocks[i+startIndex]\n\t\treturn pi.StartLine >= pb.StartLine && (pi.StartLine != pb.StartLine || pi.StartCol >= pb.StartCol)\n\t}\n\n\ti := 0\n\tif !sortFunc(i) {\n\t\ti = sort.Search(len(p.Blocks)-startIndex, sortFunc)\n\t}\n\n\ti += startIndex\n\tif i < len(p.Blocks) && p.Blocks[i].StartLine == pb.StartLine && p.Blocks[i].StartCol == pb.StartCol {\n\t\tif p.Blocks[i].EndLine != pb.EndLine || p.Blocks[i].EndCol != pb.EndCol {\n\t\t\treturn i, fmt.Errorf(\"gocovmerge: overlapping merge %v %v %v\", p.FileName, p.Blocks[i], pb)\n\t\t}\n\t\tswitch p.Mode {\n\t\tcase \"set\":\n\t\t\tp.Blocks[i].Count |= pb.Count\n\t\tcase \"count\", \"atomic\":\n\t\t\tp.Blocks[i].Count += pb.Count\n\t\tdefault:\n\t\t\treturn i, fmt.Errorf(\"gocovmerge: unsupported covermode '%s'\", p.Mode)\n\t\t}\n\n\t} else {\n\t\tif i > 0 {\n\t\t\tpa := p.Blocks[i-1]\n\t\t\tif pa.EndLine >= pb.EndLine && (pa.EndLine != pb.EndLine || pa.EndCol > pb.EndCol) {\n\t\t\t\treturn i, fmt.Errorf(\"gocovmerge: overlap before %v %v %v\", p.FileName, pa, pb)\n\t\t\t}\n\t\t}\n\t\tif i < len(p.Blocks)-1 {\n\t\t\tpa := p.Blocks[i+1]\n\t\t\tif pa.StartLine <= pb.StartLine && (pa.StartLine != pb.StartLine || pa.StartCol < pb.StartCol) {\n\t\t\t\treturn i, fmt.Errorf(\"gocovmerge: overlap after %v %v %v\", p.FileName, pa, pb)\n\t\t\t}\n\t\t}\n\t\tp.Blocks = append(p.Blocks, cover.ProfileBlock{})\n\t\tcopy(p.Blocks[i+1:], p.Blocks[i:])\n\t\tp.Blocks[i] = pb\n\t}\n\n\treturn i + 1, nil\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/profiles_and_reports.go",
    "content": "package internal\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strconv\"\n\n\t\"github.com/google/pprof/profile\"\n\t\"github.com/onsi/ginkgo/v2/reporters\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n\t\"golang.org/x/tools/cover\"\n)\n\nfunc AbsPathForGeneratedAsset(assetName string, suite TestSuite, cliConfig types.CLIConfig, process int) string {\n\tsuffix := \"\"\n\tif process != 0 {\n\t\tsuffix = fmt.Sprintf(\".%d\", process)\n\t}\n\tif cliConfig.OutputDir == \"\" {\n\t\treturn filepath.Join(suite.AbsPath(), assetName+suffix)\n\t}\n\toutputDir, _ := filepath.Abs(cliConfig.OutputDir)\n\treturn filepath.Join(outputDir, suite.NamespacedName()+\"_\"+assetName+suffix)\n}\n\nfunc FinalizeProfilesAndReportsForSuites(suites TestSuites, cliConfig types.CLIConfig, suiteConfig types.SuiteConfig, reporterConfig types.ReporterConfig, goFlagsConfig types.GoFlagsConfig) ([]string, error) {\n\tmessages := []string{}\n\tsuitesWithProfiles := suites.WithState(TestSuiteStatePassed, TestSuiteStateFailed) //anything else won't have actually run and generated a profile\n\n\t// merge cover profiles if need be\n\tif goFlagsConfig.Cover && !cliConfig.KeepSeparateCoverprofiles {\n\t\tcoverProfiles := []string{}\n\t\tfor _, suite := range suitesWithProfiles {\n\t\t\tif !suite.HasProgrammaticFocus {\n\t\t\t\tcoverProfiles = append(coverProfiles, AbsPathForGeneratedAsset(goFlagsConfig.CoverProfile, suite, cliConfig, 0))\n\t\t\t}\n\t\t}\n\n\t\tif len(coverProfiles) > 0 {\n\t\t\tdst := goFlagsConfig.CoverProfile\n\t\t\tif cliConfig.OutputDir != \"\" {\n\t\t\t\tdst = filepath.Join(cliConfig.OutputDir, goFlagsConfig.CoverProfile)\n\t\t\t}\n\t\t\terr := MergeAndCleanupCoverProfiles(coverProfiles, dst)\n\t\t\tif err != nil {\n\t\t\t\treturn messages, err\n\t\t\t}\n\t\t\tcoverage, err := GetCoverageFromCoverProfile(dst)\n\t\t\tif err != nil {\n\t\t\t\treturn messages, err\n\t\t\t}\n\t\t\tif coverage == 0 {\n\t\t\t\tmessages = append(messages, \"composite coverage: [no statements]\")\n\t\t\t} else if suitesWithProfiles.AnyHaveProgrammaticFocus() {\n\t\t\t\tmessages = append(messages, fmt.Sprintf(\"composite coverage: %.1f%% of statements however some suites did not contribute because they included programatically focused specs\", coverage))\n\t\t\t} else {\n\t\t\t\tmessages = append(messages, fmt.Sprintf(\"composite coverage: %.1f%% of statements\", coverage))\n\t\t\t}\n\t\t} else {\n\t\t\tmessages = append(messages, \"no composite coverage computed: all suites included programatically focused specs\")\n\t\t}\n\t}\n\n\t// copy binaries if need be\n\tfor _, suite := range suitesWithProfiles {\n\t\tif goFlagsConfig.BinaryMustBePreserved() && cliConfig.OutputDir != \"\" {\n\t\t\tsrc := suite.PathToCompiledTest\n\t\t\tdst := filepath.Join(cliConfig.OutputDir, suite.NamespacedName()+\".test\")\n\t\t\tif suite.Precompiled {\n\t\t\t\tif err := CopyFile(src, dst); err != nil {\n\t\t\t\t\treturn messages, err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif err := os.Rename(src, dst); err != nil {\n\t\t\t\t\treturn messages, err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\ttype reportFormat struct {\n\t\tReportName   string\n\t\tGenerateFunc func(types.Report, string) error\n\t\tMergeFunc    func([]string, string) ([]string, error)\n\t}\n\treportFormats := []reportFormat{}\n\tif reporterConfig.JSONReport != \"\" {\n\t\treportFormats = append(reportFormats, reportFormat{ReportName: reporterConfig.JSONReport, GenerateFunc: reporters.GenerateJSONReport, MergeFunc: reporters.MergeAndCleanupJSONReports})\n\t}\n\tif reporterConfig.JUnitReport != \"\" {\n\t\treportFormats = append(reportFormats, reportFormat{ReportName: reporterConfig.JUnitReport, GenerateFunc: reporters.GenerateJUnitReport, MergeFunc: reporters.MergeAndCleanupJUnitReports})\n\t}\n\tif reporterConfig.TeamcityReport != \"\" {\n\t\treportFormats = append(reportFormats, reportFormat{ReportName: reporterConfig.TeamcityReport, GenerateFunc: reporters.GenerateTeamcityReport, MergeFunc: reporters.MergeAndCleanupTeamcityReports})\n\t}\n\n\t// Generate reports for suites that failed to run\n\treportableSuites := suites.ThatAreGinkgoSuites()\n\tfor _, suite := range reportableSuites.WithState(TestSuiteStateFailedToCompile, TestSuiteStateFailedDueToTimeout, TestSuiteStateSkippedDueToPriorFailures, TestSuiteStateSkippedDueToEmptyCompilation) {\n\t\treport := types.Report{\n\t\t\tSuitePath:      suite.AbsPath(),\n\t\t\tSuiteConfig:    suiteConfig,\n\t\t\tSuiteSucceeded: false,\n\t\t}\n\t\tswitch suite.State {\n\t\tcase TestSuiteStateFailedToCompile:\n\t\t\treport.SpecialSuiteFailureReasons = append(report.SpecialSuiteFailureReasons, suite.CompilationError.Error())\n\t\tcase TestSuiteStateFailedDueToTimeout:\n\t\t\treport.SpecialSuiteFailureReasons = append(report.SpecialSuiteFailureReasons, TIMEOUT_ELAPSED_FAILURE_REASON)\n\t\tcase TestSuiteStateSkippedDueToPriorFailures:\n\t\t\treport.SpecialSuiteFailureReasons = append(report.SpecialSuiteFailureReasons, PRIOR_FAILURES_FAILURE_REASON)\n\t\tcase TestSuiteStateSkippedDueToEmptyCompilation:\n\t\t\treport.SpecialSuiteFailureReasons = append(report.SpecialSuiteFailureReasons, EMPTY_SKIP_FAILURE_REASON)\n\t\t\treport.SuiteSucceeded = true\n\t\t}\n\n\t\tfor _, format := range reportFormats {\n\t\t\tformat.GenerateFunc(report, AbsPathForGeneratedAsset(format.ReportName, suite, cliConfig, 0))\n\t\t}\n\t}\n\n\t// Merge reports unless we've been asked to keep them separate\n\tif !cliConfig.KeepSeparateReports {\n\t\tfor _, format := range reportFormats {\n\t\t\treports := []string{}\n\t\t\tfor _, suite := range reportableSuites {\n\t\t\t\treports = append(reports, AbsPathForGeneratedAsset(format.ReportName, suite, cliConfig, 0))\n\t\t\t}\n\t\t\tdst := format.ReportName\n\t\t\tif cliConfig.OutputDir != \"\" {\n\t\t\t\tdst = filepath.Join(cliConfig.OutputDir, format.ReportName)\n\t\t\t}\n\t\t\tmergeMessages, err := format.MergeFunc(reports, dst)\n\t\t\tmessages = append(messages, mergeMessages...)\n\t\t\tif err != nil {\n\t\t\t\treturn messages, err\n\t\t\t}\n\t\t}\n\t}\n\n\treturn messages, nil\n}\n\n// loads each profile, merges them, deletes them, stores them in destination\nfunc MergeAndCleanupCoverProfiles(profiles []string, destination string) error {\n\tvar merged []*cover.Profile\n\tfor _, file := range profiles {\n\t\tparsedProfiles, err := cover.ParseProfiles(file)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tos.Remove(file)\n\t\tfor _, p := range parsedProfiles {\n\t\t\tmerged = AddCoverProfile(merged, p)\n\t\t}\n\t}\n\tdst, err := os.OpenFile(destination, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer dst.Close()\n\terr = DumpCoverProfiles(merged, dst)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc GetCoverageFromCoverProfile(profile string) (float64, error) {\n\tcmd := exec.Command(\"go\", \"tool\", \"cover\", \"-func\", profile)\n\toutput, err := cmd.CombinedOutput()\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"Could not process Coverprofile %s: %s - %s\", profile, err.Error(), string(output))\n\t}\n\tre := regexp.MustCompile(`total:\\s*\\(statements\\)\\s*(\\d*\\.\\d*)\\%`)\n\tmatches := re.FindStringSubmatch(string(output))\n\tif matches == nil {\n\t\treturn 0, fmt.Errorf(\"Could not parse Coverprofile to compute coverage percentage\")\n\t}\n\tcoverageString := matches[1]\n\tcoverage, err := strconv.ParseFloat(coverageString, 64)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"Could not parse Coverprofile to compute coverage percentage: %s\", err.Error())\n\t}\n\n\treturn coverage, nil\n}\n\nfunc MergeProfiles(profilePaths []string, destination string) error {\n\tprofiles := []*profile.Profile{}\n\tfor _, profilePath := range profilePaths {\n\t\tproFile, err := os.Open(profilePath)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"Could not open profile: %s\\n%s\", profilePath, err.Error())\n\t\t}\n\t\tprof, err := profile.Parse(proFile)\n\t\t_ = proFile.Close()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"Could not parse profile: %s\\n%s\", profilePath, err.Error())\n\t\t}\n\t\tprofiles = append(profiles, prof)\n\t\tos.Remove(profilePath)\n\t}\n\n\tmergedProfile, err := profile.Merge(profiles)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Could not merge profiles:\\n%s\", err.Error())\n\t}\n\n\toutFile, err := os.Create(destination)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Could not create merged profile %s:\\n%s\", destination, err.Error())\n\t}\n\terr = mergedProfile.Write(outFile)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Could not write merged profile %s:\\n%s\", destination, err.Error())\n\t}\n\terr = outFile.Close()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Could not close merged profile %s:\\n%s\", destination, err.Error())\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/run.go",
    "content": "package internal\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/onsi/ginkgo/v2/formatter\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/command\"\n\t\"github.com/onsi/ginkgo/v2/internal/parallel_support\"\n\t\"github.com/onsi/ginkgo/v2/reporters\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\nfunc RunCompiledSuite(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig types.ReporterConfig, cliConfig types.CLIConfig, goFlagsConfig types.GoFlagsConfig, additionalArgs []string) TestSuite {\n\tsuite.State = TestSuiteStateFailed\n\tsuite.HasProgrammaticFocus = false\n\n\tif suite.PathToCompiledTest == \"\" {\n\t\treturn suite\n\t}\n\n\tif suite.IsGinkgo && cliConfig.ComputedProcs() > 1 {\n\t\tsuite = runParallel(suite, ginkgoConfig, reporterConfig, cliConfig, goFlagsConfig, additionalArgs)\n\t} else if suite.IsGinkgo {\n\t\tsuite = runSerial(suite, ginkgoConfig, reporterConfig, cliConfig, goFlagsConfig, additionalArgs)\n\t} else {\n\t\tsuite = runGoTest(suite, cliConfig, goFlagsConfig)\n\t}\n\trunAfterRunHook(cliConfig.AfterRunHook, reporterConfig.NoColor, suite)\n\treturn suite\n}\n\nfunc buildAndStartCommand(suite TestSuite, args []string, pipeToStdout bool) (*exec.Cmd, *bytes.Buffer) {\n\tbuf := &bytes.Buffer{}\n\tcmd := exec.Command(suite.PathToCompiledTest, args...)\n\tcmd.Dir = suite.Path\n\tif pipeToStdout {\n\t\tcmd.Stderr = io.MultiWriter(os.Stdout, buf)\n\t\tcmd.Stdout = os.Stdout\n\t} else {\n\t\tcmd.Stderr = buf\n\t\tcmd.Stdout = buf\n\t}\n\terr := cmd.Start()\n\tcommand.AbortIfError(\"Failed to start test suite\", err)\n\n\treturn cmd, buf\n}\n\nfunc checkForNoTestsWarning(buf *bytes.Buffer) bool {\n\tif strings.Contains(buf.String(), \"warning: no tests to run\") {\n\t\tfmt.Fprintf(os.Stderr, `Found no test suites, did you forget to run \"ginkgo bootstrap\"?`)\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc runGoTest(suite TestSuite, cliConfig types.CLIConfig, goFlagsConfig types.GoFlagsConfig) TestSuite {\n\t// As we run the go test from the suite directory, make sure the cover profile is absolute\n\t// and placed into the expected output directory when one is configured.\n\tif goFlagsConfig.Cover && !filepath.IsAbs(goFlagsConfig.CoverProfile) {\n\t\tgoFlagsConfig.CoverProfile = AbsPathForGeneratedAsset(goFlagsConfig.CoverProfile, suite, cliConfig, 0)\n\t}\n\n\targs, err := types.GenerateGoTestRunArgs(goFlagsConfig)\n\tcommand.AbortIfError(\"Failed to generate test run arguments\", err)\n\tcmd, buf := buildAndStartCommand(suite, args, true)\n\n\tcmd.Wait()\n\n\texitStatus := cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()\n\tpassed := (exitStatus == 0) || (exitStatus == types.GINKGO_FOCUS_EXIT_CODE)\n\tpassed = !(checkForNoTestsWarning(buf) && cliConfig.RequireSuite) && passed\n\tif passed {\n\t\tsuite.State = TestSuiteStatePassed\n\t} else {\n\t\tsuite.State = TestSuiteStateFailed\n\t}\n\n\treturn suite\n}\n\nfunc runSerial(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig types.ReporterConfig, cliConfig types.CLIConfig, goFlagsConfig types.GoFlagsConfig, additionalArgs []string) TestSuite {\n\tif goFlagsConfig.Cover {\n\t\tgoFlagsConfig.CoverProfile = AbsPathForGeneratedAsset(goFlagsConfig.CoverProfile, suite, cliConfig, 0)\n\t}\n\tif goFlagsConfig.BlockProfile != \"\" {\n\t\tgoFlagsConfig.BlockProfile = AbsPathForGeneratedAsset(goFlagsConfig.BlockProfile, suite, cliConfig, 0)\n\t}\n\tif goFlagsConfig.CPUProfile != \"\" {\n\t\tgoFlagsConfig.CPUProfile = AbsPathForGeneratedAsset(goFlagsConfig.CPUProfile, suite, cliConfig, 0)\n\t}\n\tif goFlagsConfig.MemProfile != \"\" {\n\t\tgoFlagsConfig.MemProfile = AbsPathForGeneratedAsset(goFlagsConfig.MemProfile, suite, cliConfig, 0)\n\t}\n\tif goFlagsConfig.MutexProfile != \"\" {\n\t\tgoFlagsConfig.MutexProfile = AbsPathForGeneratedAsset(goFlagsConfig.MutexProfile, suite, cliConfig, 0)\n\t}\n\tif reporterConfig.JSONReport != \"\" {\n\t\treporterConfig.JSONReport = AbsPathForGeneratedAsset(reporterConfig.JSONReport, suite, cliConfig, 0)\n\t}\n\tif reporterConfig.JUnitReport != \"\" {\n\t\treporterConfig.JUnitReport = AbsPathForGeneratedAsset(reporterConfig.JUnitReport, suite, cliConfig, 0)\n\t}\n\tif reporterConfig.TeamcityReport != \"\" {\n\t\treporterConfig.TeamcityReport = AbsPathForGeneratedAsset(reporterConfig.TeamcityReport, suite, cliConfig, 0)\n\t}\n\n\targs, err := types.GenerateGinkgoTestRunArgs(ginkgoConfig, reporterConfig, goFlagsConfig)\n\tcommand.AbortIfError(\"Failed to generate test run arguments\", err)\n\targs = append([]string{\"--test.timeout=0\"}, args...)\n\targs = append(args, additionalArgs...)\n\n\tcmd, buf := buildAndStartCommand(suite, args, true)\n\n\tcmd.Wait()\n\n\texitStatus := cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()\n\tsuite.HasProgrammaticFocus = (exitStatus == types.GINKGO_FOCUS_EXIT_CODE)\n\tpassed := (exitStatus == 0) || (exitStatus == types.GINKGO_FOCUS_EXIT_CODE)\n\tpassed = !(checkForNoTestsWarning(buf) && cliConfig.RequireSuite) && passed\n\tif passed {\n\t\tsuite.State = TestSuiteStatePassed\n\t} else {\n\t\tsuite.State = TestSuiteStateFailed\n\t}\n\n\tif suite.HasProgrammaticFocus {\n\t\tif goFlagsConfig.Cover {\n\t\t\tfmt.Fprintln(os.Stdout, \"coverage: no coverfile was generated because specs are programmatically focused\")\n\t\t}\n\t\tif goFlagsConfig.BlockProfile != \"\" {\n\t\t\tfmt.Fprintln(os.Stdout, \"no block profile was generated because specs are programmatically focused\")\n\t\t}\n\t\tif goFlagsConfig.CPUProfile != \"\" {\n\t\t\tfmt.Fprintln(os.Stdout, \"no cpu profile was generated because specs are programmatically focused\")\n\t\t}\n\t\tif goFlagsConfig.MemProfile != \"\" {\n\t\t\tfmt.Fprintln(os.Stdout, \"no mem profile was generated because specs are programmatically focused\")\n\t\t}\n\t\tif goFlagsConfig.MutexProfile != \"\" {\n\t\t\tfmt.Fprintln(os.Stdout, \"no mutex profile was generated because specs are programmatically focused\")\n\t\t}\n\t}\n\n\treturn suite\n}\n\nfunc runParallel(suite TestSuite, ginkgoConfig types.SuiteConfig, reporterConfig types.ReporterConfig, cliConfig types.CLIConfig, goFlagsConfig types.GoFlagsConfig, additionalArgs []string) TestSuite {\n\ttype procResult struct {\n\t\tpassed               bool\n\t\thasProgrammaticFocus bool\n\t}\n\n\tnumProcs := cliConfig.ComputedProcs()\n\tprocOutput := make([]*bytes.Buffer, numProcs)\n\tcoverProfiles := []string{}\n\n\tblockProfiles := []string{}\n\tcpuProfiles := []string{}\n\tmemProfiles := []string{}\n\tmutexProfiles := []string{}\n\n\tprocResults := make(chan procResult)\n\n\tserver, err := parallel_support.NewServer(numProcs, reporters.NewDefaultReporter(reporterConfig, formatter.ColorableStdOut))\n\tcommand.AbortIfError(\"Failed to start parallel spec server\", err)\n\tserver.Start()\n\tdefer server.Close()\n\n\tif reporterConfig.JSONReport != \"\" {\n\t\treporterConfig.JSONReport = AbsPathForGeneratedAsset(reporterConfig.JSONReport, suite, cliConfig, 0)\n\t}\n\tif reporterConfig.JUnitReport != \"\" {\n\t\treporterConfig.JUnitReport = AbsPathForGeneratedAsset(reporterConfig.JUnitReport, suite, cliConfig, 0)\n\t}\n\tif reporterConfig.TeamcityReport != \"\" {\n\t\treporterConfig.TeamcityReport = AbsPathForGeneratedAsset(reporterConfig.TeamcityReport, suite, cliConfig, 0)\n\t}\n\n\tfor proc := 1; proc <= numProcs; proc++ {\n\t\tprocGinkgoConfig := ginkgoConfig\n\t\tprocGinkgoConfig.ParallelProcess, procGinkgoConfig.ParallelTotal, procGinkgoConfig.ParallelHost = proc, numProcs, server.Address()\n\n\t\tprocGoFlagsConfig := goFlagsConfig\n\t\tif goFlagsConfig.Cover {\n\t\t\tprocGoFlagsConfig.CoverProfile = AbsPathForGeneratedAsset(goFlagsConfig.CoverProfile, suite, cliConfig, proc)\n\t\t\tcoverProfiles = append(coverProfiles, procGoFlagsConfig.CoverProfile)\n\t\t}\n\t\tif goFlagsConfig.BlockProfile != \"\" {\n\t\t\tprocGoFlagsConfig.BlockProfile = AbsPathForGeneratedAsset(goFlagsConfig.BlockProfile, suite, cliConfig, proc)\n\t\t\tblockProfiles = append(blockProfiles, procGoFlagsConfig.BlockProfile)\n\t\t}\n\t\tif goFlagsConfig.CPUProfile != \"\" {\n\t\t\tprocGoFlagsConfig.CPUProfile = AbsPathForGeneratedAsset(goFlagsConfig.CPUProfile, suite, cliConfig, proc)\n\t\t\tcpuProfiles = append(cpuProfiles, procGoFlagsConfig.CPUProfile)\n\t\t}\n\t\tif goFlagsConfig.MemProfile != \"\" {\n\t\t\tprocGoFlagsConfig.MemProfile = AbsPathForGeneratedAsset(goFlagsConfig.MemProfile, suite, cliConfig, proc)\n\t\t\tmemProfiles = append(memProfiles, procGoFlagsConfig.MemProfile)\n\t\t}\n\t\tif goFlagsConfig.MutexProfile != \"\" {\n\t\t\tprocGoFlagsConfig.MutexProfile = AbsPathForGeneratedAsset(goFlagsConfig.MutexProfile, suite, cliConfig, proc)\n\t\t\tmutexProfiles = append(mutexProfiles, procGoFlagsConfig.MutexProfile)\n\t\t}\n\n\t\targs, err := types.GenerateGinkgoTestRunArgs(procGinkgoConfig, reporterConfig, procGoFlagsConfig)\n\t\tcommand.AbortIfError(\"Failed to generate test run arguments\", err)\n\t\targs = append([]string{\"--test.timeout=0\"}, args...)\n\t\targs = append(args, additionalArgs...)\n\n\t\tcmd, buf := buildAndStartCommand(suite, args, false)\n\t\tprocOutput[proc-1] = buf\n\t\tserver.RegisterAlive(proc, func() bool { return cmd.ProcessState == nil || !cmd.ProcessState.Exited() })\n\n\t\tgo func() {\n\t\t\tcmd.Wait()\n\t\t\texitStatus := cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()\n\t\t\tprocResults <- procResult{\n\t\t\t\tpassed:               (exitStatus == 0) || (exitStatus == types.GINKGO_FOCUS_EXIT_CODE),\n\t\t\t\thasProgrammaticFocus: exitStatus == types.GINKGO_FOCUS_EXIT_CODE,\n\t\t\t}\n\t\t}()\n\t}\n\n\tpassed := true\n\tfor proc := 1; proc <= cliConfig.ComputedProcs(); proc++ {\n\t\tresult := <-procResults\n\t\tpassed = passed && result.passed\n\t\tsuite.HasProgrammaticFocus = suite.HasProgrammaticFocus || result.hasProgrammaticFocus\n\t}\n\tif passed {\n\t\tsuite.State = TestSuiteStatePassed\n\t} else {\n\t\tsuite.State = TestSuiteStateFailed\n\t}\n\n\tselect {\n\tcase <-server.GetSuiteDone():\n\t\tfmt.Println(\"\")\n\tcase <-time.After(time.Second):\n\t\t//one of the nodes never finished reporting to the server.  Something must have gone wrong.\n\t\tfmt.Fprint(formatter.ColorableStdErr, formatter.F(\"\\n{{bold}}{{red}}Ginkgo timed out waiting for all parallel procs to report back{{/}}\\n\"))\n\t\tfmt.Fprint(formatter.ColorableStdErr, formatter.F(\"{{gray}}Test suite:{{/}} %s (%s)\\n\\n\", suite.PackageName, suite.Path))\n\t\tfmt.Fprint(formatter.ColorableStdErr, formatter.Fiw(0, formatter.COLS, \"This occurs if a parallel process exits before it reports its results to the Ginkgo CLI.  The CLI will now print out all the stdout/stderr output it's collected from the running processes.  However you may not see anything useful in these logs because the individual test processes usually intercept output to stdout/stderr in order to capture it in the spec reports.\\n\\nYou may want to try rerunning your test suite with {{light-gray}}--output-interceptor-mode=none{{/}} to see additional output here and debug your suite.\\n\"))\n\t\tfmt.Fprintln(formatter.ColorableStdErr, \"  \")\n\t\tfor proc := 1; proc <= cliConfig.ComputedProcs(); proc++ {\n\t\t\tfmt.Fprintf(formatter.ColorableStdErr, formatter.F(\"{{bold}}Output from proc %d:{{/}}\\n\", proc))\n\t\t\tfmt.Fprintln(os.Stderr, formatter.Fi(1, \"%s\", procOutput[proc-1].String()))\n\t\t}\n\t\tfmt.Fprintf(os.Stderr, \"** End **\")\n\t}\n\n\tfor proc := 1; proc <= cliConfig.ComputedProcs(); proc++ {\n\t\toutput := procOutput[proc-1].String()\n\t\tif proc == 1 && checkForNoTestsWarning(procOutput[0]) && cliConfig.RequireSuite {\n\t\t\tsuite.State = TestSuiteStateFailed\n\t\t}\n\t\tif strings.Contains(output, \"deprecated Ginkgo functionality\") {\n\t\t\tfmt.Fprintln(os.Stderr, output)\n\t\t}\n\t}\n\n\tif len(coverProfiles) > 0 {\n\t\tif suite.HasProgrammaticFocus {\n\t\t\tfmt.Fprintln(os.Stdout, \"coverage: no coverfile was generated because specs are programmatically focused\")\n\t\t} else {\n\t\t\tcoverProfile := AbsPathForGeneratedAsset(goFlagsConfig.CoverProfile, suite, cliConfig, 0)\n\t\t\terr := MergeAndCleanupCoverProfiles(coverProfiles, coverProfile)\n\t\t\tcommand.AbortIfError(\"Failed to combine cover profiles\", err)\n\n\t\t\tcoverage, err := GetCoverageFromCoverProfile(coverProfile)\n\t\t\tcommand.AbortIfError(\"Failed to compute coverage\", err)\n\t\t\tif coverage == 0 {\n\t\t\t\tfmt.Fprintln(os.Stdout, \"coverage: [no statements]\")\n\t\t\t} else {\n\t\t\t\tfmt.Fprintf(os.Stdout, \"coverage: %.1f%% of statements\\n\", coverage)\n\t\t\t}\n\t\t}\n\t}\n\tif len(blockProfiles) > 0 {\n\t\tif suite.HasProgrammaticFocus {\n\t\t\tfmt.Fprintln(os.Stdout, \"no block profile was generated because specs are programmatically focused\")\n\t\t} else {\n\t\t\tblockProfile := AbsPathForGeneratedAsset(goFlagsConfig.BlockProfile, suite, cliConfig, 0)\n\t\t\terr := MergeProfiles(blockProfiles, blockProfile)\n\t\t\tcommand.AbortIfError(\"Failed to combine blockprofiles\", err)\n\t\t}\n\t}\n\tif len(cpuProfiles) > 0 {\n\t\tif suite.HasProgrammaticFocus {\n\t\t\tfmt.Fprintln(os.Stdout, \"no cpu profile was generated because specs are programmatically focused\")\n\t\t} else {\n\t\t\tcpuProfile := AbsPathForGeneratedAsset(goFlagsConfig.CPUProfile, suite, cliConfig, 0)\n\t\t\terr := MergeProfiles(cpuProfiles, cpuProfile)\n\t\t\tcommand.AbortIfError(\"Failed to combine cpuprofiles\", err)\n\t\t}\n\t}\n\tif len(memProfiles) > 0 {\n\t\tif suite.HasProgrammaticFocus {\n\t\t\tfmt.Fprintln(os.Stdout, \"no mem profile was generated because specs are programmatically focused\")\n\t\t} else {\n\t\t\tmemProfile := AbsPathForGeneratedAsset(goFlagsConfig.MemProfile, suite, cliConfig, 0)\n\t\t\terr := MergeProfiles(memProfiles, memProfile)\n\t\t\tcommand.AbortIfError(\"Failed to combine memprofiles\", err)\n\t\t}\n\t}\n\tif len(mutexProfiles) > 0 {\n\t\tif suite.HasProgrammaticFocus {\n\t\t\tfmt.Fprintln(os.Stdout, \"no mutex profile was generated because specs are programmatically focused\")\n\t\t} else {\n\t\t\tmutexProfile := AbsPathForGeneratedAsset(goFlagsConfig.MutexProfile, suite, cliConfig, 0)\n\t\t\terr := MergeProfiles(mutexProfiles, mutexProfile)\n\t\t\tcommand.AbortIfError(\"Failed to combine mutexprofiles\", err)\n\t\t}\n\t}\n\n\treturn suite\n}\n\nfunc runAfterRunHook(command string, noColor bool, suite TestSuite) {\n\tif command == \"\" {\n\t\treturn\n\t}\n\tf := formatter.NewWithNoColorBool(noColor)\n\n\t// Allow for string replacement to pass input to the command\n\tpassed := \"[FAIL]\"\n\tif suite.State.Is(TestSuiteStatePassed) {\n\t\tpassed = \"[PASS]\"\n\t}\n\tcommand = strings.ReplaceAll(command, \"(ginkgo-suite-passed)\", passed)\n\tcommand = strings.ReplaceAll(command, \"(ginkgo-suite-name)\", suite.PackageName)\n\n\t// Must break command into parts\n\tsplitArgs := regexp.MustCompile(`'.+'|\".+\"|\\S+`)\n\tparts := splitArgs.FindAllString(command, -1)\n\n\toutput, err := exec.Command(parts[0], parts[1:]...).CombinedOutput()\n\tif err != nil {\n\t\tfmt.Fprintln(formatter.ColorableStdOut, f.Fi(0, \"{{red}}{{bold}}After-run-hook failed:{{/}}\"))\n\t\tfmt.Fprintln(formatter.ColorableStdOut, f.Fi(1, \"{{red}}%s{{/}}\", output))\n\t} else {\n\t\tfmt.Fprintln(formatter.ColorableStdOut, f.Fi(0, \"{{green}}{{bold}}After-run-hook succeeded:{{/}}\"))\n\t\tfmt.Fprintln(formatter.ColorableStdOut, f.Fi(1, \"{{green}}%s{{/}}\", output))\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/test_suite.go",
    "content": "package internal\n\nimport (\n\t\"errors\"\n\t\"math/rand\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"strings\"\n\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\nconst TIMEOUT_ELAPSED_FAILURE_REASON = \"Suite did not run because the timeout elapsed\"\nconst PRIOR_FAILURES_FAILURE_REASON = \"Suite did not run because prior suites failed and --keep-going is not set\"\nconst EMPTY_SKIP_FAILURE_REASON = \"Suite did not run go test reported that no test files were found\"\n\ntype TestSuiteState uint\n\nconst (\n\tTestSuiteStateInvalid TestSuiteState = iota\n\n\tTestSuiteStateUncompiled\n\tTestSuiteStateCompiled\n\n\tTestSuiteStatePassed\n\n\tTestSuiteStateSkippedDueToEmptyCompilation\n\tTestSuiteStateSkippedByFilter\n\tTestSuiteStateSkippedDueToPriorFailures\n\n\tTestSuiteStateFailed\n\tTestSuiteStateFailedDueToTimeout\n\tTestSuiteStateFailedToCompile\n)\n\nvar TestSuiteStateFailureStates = []TestSuiteState{TestSuiteStateFailed, TestSuiteStateFailedDueToTimeout, TestSuiteStateFailedToCompile}\n\nfunc (state TestSuiteState) Is(states ...TestSuiteState) bool {\n\tfor _, suiteState := range states {\n\t\tif suiteState == state {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\ntype TestSuite struct {\n\tPath        string\n\tPackageName string\n\tIsGinkgo    bool\n\n\tPrecompiled        bool\n\tPathToCompiledTest string\n\tCompilationError   error\n\n\tHasProgrammaticFocus bool\n\tState                TestSuiteState\n}\n\nfunc (ts TestSuite) AbsPath() string {\n\tpath, _ := filepath.Abs(ts.Path)\n\treturn path\n}\n\nfunc (ts TestSuite) NamespacedName() string {\n\tname := relPath(ts.Path)\n\tname = strings.TrimLeft(name, \".\"+string(filepath.Separator))\n\tname = strings.ReplaceAll(name, string(filepath.Separator), \"_\")\n\tname = strings.ReplaceAll(name, \" \", \"_\")\n\tif name == \"\" {\n\t\treturn ts.PackageName\n\t}\n\treturn name\n}\n\ntype TestSuites []TestSuite\n\nfunc (ts TestSuites) AnyHaveProgrammaticFocus() bool {\n\tfor _, suite := range ts {\n\t\tif suite.HasProgrammaticFocus {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc (ts TestSuites) ThatAreGinkgoSuites() TestSuites {\n\tout := TestSuites{}\n\tfor _, suite := range ts {\n\t\tif suite.IsGinkgo {\n\t\t\tout = append(out, suite)\n\t\t}\n\t}\n\treturn out\n}\n\nfunc (ts TestSuites) CountWithState(states ...TestSuiteState) int {\n\tn := 0\n\tfor _, suite := range ts {\n\t\tif suite.State.Is(states...) {\n\t\t\tn += 1\n\t\t}\n\t}\n\n\treturn n\n}\n\nfunc (ts TestSuites) WithState(states ...TestSuiteState) TestSuites {\n\tout := TestSuites{}\n\tfor _, suite := range ts {\n\t\tif suite.State.Is(states...) {\n\t\t\tout = append(out, suite)\n\t\t}\n\t}\n\n\treturn out\n}\n\nfunc (ts TestSuites) WithoutState(states ...TestSuiteState) TestSuites {\n\tout := TestSuites{}\n\tfor _, suite := range ts {\n\t\tif !suite.State.Is(states...) {\n\t\t\tout = append(out, suite)\n\t\t}\n\t}\n\n\treturn out\n}\n\nfunc (ts TestSuites) ShuffledCopy(seed int64) TestSuites {\n\tout := make(TestSuites, len(ts))\n\tpermutation := rand.New(rand.NewSource(seed)).Perm(len(ts))\n\tfor i, j := range permutation {\n\t\tout[i] = ts[j]\n\t}\n\treturn out\n}\n\nfunc FindSuites(args []string, cliConfig types.CLIConfig, allowPrecompiled bool) TestSuites {\n\tsuites := TestSuites{}\n\n\tif len(args) > 0 {\n\t\tfor _, arg := range args {\n\t\t\tif allowPrecompiled {\n\t\t\t\tsuite, err := precompiledTestSuite(arg)\n\t\t\t\tif err == nil {\n\t\t\t\t\tsuites = append(suites, suite)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\trecurseForSuite := cliConfig.Recurse\n\t\t\tif strings.HasSuffix(arg, \"/...\") && arg != \"/...\" {\n\t\t\t\targ = arg[:len(arg)-4]\n\t\t\t\trecurseForSuite = true\n\t\t\t}\n\t\t\tsuites = append(suites, suitesInDir(arg, recurseForSuite)...)\n\t\t}\n\t} else {\n\t\tsuites = suitesInDir(\".\", cliConfig.Recurse)\n\t}\n\n\tif cliConfig.SkipPackage != \"\" {\n\t\tskipFilters := strings.Split(cliConfig.SkipPackage, \",\")\n\t\tfor idx := range suites {\n\t\t\tfor _, skipFilter := range skipFilters {\n\t\t\t\tif strings.Contains(suites[idx].Path, skipFilter) {\n\t\t\t\t\tsuites[idx].State = TestSuiteStateSkippedByFilter\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn suites\n}\n\nfunc precompiledTestSuite(path string) (TestSuite, error) {\n\tinfo, err := os.Stat(path)\n\tif err != nil {\n\t\treturn TestSuite{}, err\n\t}\n\n\tif info.IsDir() {\n\t\treturn TestSuite{}, errors.New(\"this is a directory, not a file\")\n\t}\n\n\tif filepath.Ext(path) != \".test\" && filepath.Ext(path) != \".exe\" {\n\t\treturn TestSuite{}, errors.New(\"this is not a .test binary\")\n\t}\n\n\tif filepath.Ext(path) == \".test\" && runtime.GOOS != \"windows\" && info.Mode()&0111 == 0 {\n\t\treturn TestSuite{}, errors.New(\"this is not executable\")\n\t}\n\n\tdir := relPath(filepath.Dir(path))\n\tpackageName := strings.TrimSuffix(filepath.Base(path), \".exe\")\n\tpackageName = strings.TrimSuffix(packageName, \".test\")\n\n\tpath, err = filepath.Abs(path)\n\tif err != nil {\n\t\treturn TestSuite{}, err\n\t}\n\n\treturn TestSuite{\n\t\tPath:               dir,\n\t\tPackageName:        packageName,\n\t\tIsGinkgo:           true,\n\t\tPrecompiled:        true,\n\t\tPathToCompiledTest: path,\n\t\tState:              TestSuiteStateCompiled,\n\t}, nil\n}\n\nfunc suitesInDir(dir string, recurse bool) TestSuites {\n\tsuites := TestSuites{}\n\n\tif path.Base(dir) == \"vendor\" {\n\t\treturn suites\n\t}\n\n\tfiles, _ := os.ReadDir(dir)\n\tre := regexp.MustCompile(`^[^._].*_test\\.go$`)\n\tfor _, file := range files {\n\t\tif !file.IsDir() && re.MatchString(file.Name()) {\n\t\t\tsuite := TestSuite{\n\t\t\t\tPath:        relPath(dir),\n\t\t\t\tPackageName: packageNameForSuite(dir),\n\t\t\t\tIsGinkgo:    filesHaveGinkgoSuite(dir, files),\n\t\t\t\tState:       TestSuiteStateUncompiled,\n\t\t\t}\n\t\t\tsuites = append(suites, suite)\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif recurse {\n\t\tre = regexp.MustCompile(`^[._]`)\n\t\tfor _, file := range files {\n\t\t\tif file.IsDir() && !re.MatchString(file.Name()) {\n\t\t\t\tsuites = append(suites, suitesInDir(dir+\"/\"+file.Name(), recurse)...)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn suites\n}\n\nfunc relPath(dir string) string {\n\tdir, _ = filepath.Abs(dir)\n\tcwd, _ := os.Getwd()\n\tdir, _ = filepath.Rel(cwd, filepath.Clean(dir))\n\n\tif string(dir[0]) != \".\" {\n\t\tdir = \".\" + string(filepath.Separator) + dir\n\t}\n\n\treturn dir\n}\n\nfunc packageNameForSuite(dir string) string {\n\tpath, _ := filepath.Abs(dir)\n\treturn filepath.Base(path)\n}\n\nfunc filesHaveGinkgoSuite(dir string, files []os.DirEntry) bool {\n\treTestFile := regexp.MustCompile(`_test\\.go$`)\n\treGinkgo := regexp.MustCompile(`package ginkgo|\\/ginkgo\"|\\/ginkgo\\/v2\"|\\/ginkgo\\/v2/dsl/`)\n\n\tfor _, file := range files {\n\t\tif !file.IsDir() && reTestFile.MatchString(file.Name()) {\n\t\t\tcontents, _ := os.ReadFile(dir + \"/\" + file.Name())\n\t\t\tif reGinkgo.Match(contents) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/utils.go",
    "content": "package internal\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\n\t\"github.com/onsi/ginkgo/v2/formatter\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/command\"\n)\n\nfunc FileExists(path string) bool {\n\t_, err := os.Stat(path)\n\treturn err == nil\n}\n\nfunc CopyFile(src string, dest string) error {\n\tsrcFile, err := os.Open(src)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tsrcStat, err := srcFile.Stat()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif _, err := os.Stat(dest); err == nil {\n\t\tos.Remove(dest)\n\t}\n\n\tdestFile, err := os.OpenFile(dest, os.O_WRONLY|os.O_CREATE, srcStat.Mode())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_, err = io.Copy(destFile, srcFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := srcFile.Close(); err != nil {\n\t\treturn err\n\t}\n\treturn destFile.Close()\n}\n\nfunc GoFmt(path string) {\n\tout, err := exec.Command(\"go\", \"fmt\", path).CombinedOutput()\n\tif err != nil {\n\t\tcommand.AbortIfError(fmt.Sprintf(\"Could not fmt:\\n%s\\n\", string(out)), err)\n\t}\n}\n\nfunc PluralizedWord(singular, plural string, count int) string {\n\tif count == 1 {\n\t\treturn singular\n\t}\n\treturn plural\n}\n\nfunc FailedSuitesReport(suites TestSuites, f formatter.Formatter) string {\n\tout := \"\"\n\tout += \"There were failures detected in the following suites:\\n\"\n\n\tmaxPackageNameLength := 0\n\tfor _, suite := range suites.WithState(TestSuiteStateFailureStates...) {\n\t\tif len(suite.PackageName) > maxPackageNameLength {\n\t\t\tmaxPackageNameLength = len(suite.PackageName)\n\t\t}\n\t}\n\n\tpackageNameFormatter := fmt.Sprintf(\"%%%ds\", maxPackageNameLength)\n\tfor _, suite := range suites {\n\t\tswitch suite.State {\n\t\tcase TestSuiteStateFailed:\n\t\t\tout += f.Fi(1, \"{{red}}\"+packageNameFormatter+\" {{gray}}%s{{/}}\\n\", suite.PackageName, suite.Path)\n\t\tcase TestSuiteStateFailedToCompile:\n\t\t\tout += f.Fi(1, \"{{red}}\"+packageNameFormatter+\" {{gray}}%s {{magenta}}[Compilation failure]{{/}}\\n\", suite.PackageName, suite.Path)\n\t\tcase TestSuiteStateFailedDueToTimeout:\n\t\t\tout += f.Fi(1, \"{{red}}\"+packageNameFormatter+\" {{gray}}%s {{orange}}[%s]{{/}}\\n\", suite.PackageName, suite.Path, TIMEOUT_ELAPSED_FAILURE_REASON)\n\t\t}\n\t}\n\treturn out\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/internal/verify_version.go",
    "content": "package internal\n\nimport (\n\t\"fmt\"\n\t\"os/exec\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/onsi/ginkgo/v2/formatter\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\nvar versiorRe = regexp.MustCompile(`v(\\d+\\.\\d+\\.\\d+)`)\n\nfunc VerifyCLIAndFrameworkVersion(suites TestSuites) {\n\tcliVersion := types.VERSION\n\tmismatches := map[string][]string{}\n\n\tfor _, suite := range suites {\n\t\tcmd := exec.Command(\"go\", \"list\", \"-m\", \"github.com/onsi/ginkgo/v2\")\n\t\tcmd.Dir = suite.Path\n\t\toutput, err := cmd.CombinedOutput()\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tcomponents := strings.Split(string(output), \" \")\n\t\tif len(components) != 2 {\n\t\t\tcontinue\n\t\t}\n\t\tmatches := versiorRe.FindStringSubmatch(components[1])\n\t\tif matches == nil || len(matches) != 2 {\n\t\t\tcontinue\n\t\t}\n\t\tlibraryVersion := matches[1]\n\t\tif cliVersion != libraryVersion {\n\t\t\tmismatches[libraryVersion] = append(mismatches[libraryVersion], suite.PackageName)\n\t\t}\n\t}\n\n\tif len(mismatches) == 0 {\n\t\treturn\n\t}\n\n\tfmt.Println(formatter.F(\"{{red}}{{bold}}Ginkgo detected a version mismatch between the Ginkgo CLI and the version of Ginkgo imported by your packages:{{/}}\"))\n\n\tfmt.Println(formatter.Fi(1, \"Ginkgo CLI Version:\"))\n\tfmt.Println(formatter.Fi(2, \"{{bold}}%s{{/}}\", cliVersion))\n\tfmt.Println(formatter.Fi(1, \"Mismatched package versions found:\"))\n\tfor version, packages := range mismatches {\n\t\tfmt.Println(formatter.Fi(2, \"{{bold}}%s{{/}} used by %s\", version, strings.Join(packages, \", \")))\n\t}\n\tfmt.Println(\"\")\n\tfmt.Println(formatter.Fiw(1, formatter.COLS, \"{{gray}}Ginkgo will continue to attempt to run but you may see errors (including flag parsing errors) and should either update your go.mod or your version of the Ginkgo CLI to match.\\n\\nTo install the matching version of the CLI run\\n  {{bold}}go install github.com/onsi/ginkgo/v2/ginkgo{{/}}{{gray}}\\nfrom a path that contains a go.mod file.  Alternatively you can use\\n  {{bold}}go run github.com/onsi/ginkgo/v2/ginkgo{{/}}{{gray}}\\nfrom a path that contains a go.mod file to invoke the matching version of the Ginkgo CLI.\\n\\nIf you are attempting to test multiple packages that each have a different version of the Ginkgo library with a single Ginkgo CLI that is currently unsupported.\\n{{/}}\"))\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/labels/labels_command.go",
    "content": "package labels\n\nimport (\n\t\"fmt\"\n\t\"go/ast\"\n\t\"go/parser\"\n\t\"go/token\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/onsi/ginkgo/v2/ginkgo/command\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/internal\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n\t\"golang.org/x/tools/go/ast/inspector\"\n)\n\nfunc BuildLabelsCommand() command.Command {\n\tvar cliConfig = types.NewDefaultCLIConfig()\n\n\tflags, err := types.BuildLabelsCommandFlagSet(&cliConfig)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treturn command.Command{\n\t\tName:     \"labels\",\n\t\tUsage:    \"ginkgo labels <FLAGS> <PACKAGES>\",\n\t\tFlags:    flags,\n\t\tShortDoc: \"List labels detected in the passed-in packages (or the package in the current directory if left blank).\",\n\t\tDocLink:  \"spec-labels\",\n\t\tCommand: func(args []string, _ []string) {\n\t\t\tListLabels(args, cliConfig)\n\t\t},\n\t}\n}\n\nfunc ListLabels(args []string, cliConfig types.CLIConfig) {\n\tsuites := internal.FindSuites(args, cliConfig, false).WithoutState(internal.TestSuiteStateSkippedByFilter)\n\tif len(suites) == 0 {\n\t\tcommand.AbortWith(\"Found no test suites\")\n\t}\n\tfor _, suite := range suites {\n\t\tlabels := fetchLabelsFromPackage(suite.Path)\n\t\tif len(labels) == 0 {\n\t\t\tfmt.Printf(\"%s: No labels found\\n\", suite.PackageName)\n\t\t} else {\n\t\t\tfmt.Printf(\"%s: [%s]\\n\", suite.PackageName, strings.Join(labels, \", \"))\n\t\t}\n\t}\n}\n\nfunc fetchLabelsFromPackage(packagePath string) []string {\n\tfset := token.NewFileSet()\n\tparsedPackages, err := parser.ParseDir(fset, packagePath, nil, 0)\n\tcommand.AbortIfError(\"Failed to parse package source:\", err)\n\n\tfiles := []*ast.File{}\n\thasTestPackage := false\n\tfor key, pkg := range parsedPackages {\n\t\tif strings.HasSuffix(key, \"_test\") {\n\t\t\thasTestPackage = true\n\t\t\tfor _, file := range pkg.Files {\n\t\t\t\tfiles = append(files, file)\n\t\t\t}\n\t\t}\n\t}\n\tif !hasTestPackage {\n\t\tfor _, pkg := range parsedPackages {\n\t\t\tfor _, file := range pkg.Files {\n\t\t\t\tfiles = append(files, file)\n\t\t\t}\n\t\t}\n\t}\n\n\tseen := map[string]bool{}\n\tlabels := []string{}\n\tispr := inspector.New(files)\n\tispr.Preorder([]ast.Node{&ast.CallExpr{}}, func(n ast.Node) {\n\t\tpotentialLabels := fetchLabels(n.(*ast.CallExpr))\n\t\tfor _, label := range potentialLabels {\n\t\t\tif !seen[label] {\n\t\t\t\tseen[label] = true\n\t\t\t\tlabels = append(labels, strconv.Quote(label))\n\t\t\t}\n\t\t}\n\t})\n\n\tsort.Strings(labels)\n\treturn labels\n}\n\nfunc fetchLabels(callExpr *ast.CallExpr) []string {\n\tout := []string{}\n\tswitch expr := callExpr.Fun.(type) {\n\tcase *ast.Ident:\n\t\tif expr.Name != \"Label\" {\n\t\t\treturn out\n\t\t}\n\tcase *ast.SelectorExpr:\n\t\tif expr.Sel.Name != \"Label\" {\n\t\t\treturn out\n\t\t}\n\tdefault:\n\t\treturn out\n\t}\n\tfor _, arg := range callExpr.Args {\n\t\tswitch expr := arg.(type) {\n\t\tcase *ast.BasicLit:\n\t\t\tif expr.Kind == token.STRING {\n\t\t\t\tunquoted, err := strconv.Unquote(expr.Value)\n\t\t\t\tif err != nil {\n\t\t\t\t\tunquoted = expr.Value\n\t\t\t\t}\n\t\t\t\tvalidated, err := types.ValidateAndCleanupLabel(unquoted, types.CodeLocation{})\n\t\t\t\tif err == nil {\n\t\t\t\t\tout = append(out, validated)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn out\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t_ \"go.uber.org/automaxprocs\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/build\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/command\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/generators\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/labels\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/outline\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/run\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/unfocus\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/watch\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\nvar program command.Program\n\nfunc GenerateCommands() []command.Command {\n\treturn []command.Command{\n\t\twatch.BuildWatchCommand(),\n\t\tbuild.BuildBuildCommand(),\n\t\tgenerators.BuildBootstrapCommand(),\n\t\tgenerators.BuildGenerateCommand(),\n\t\tlabels.BuildLabelsCommand(),\n\t\toutline.BuildOutlineCommand(),\n\t\tunfocus.BuildUnfocusCommand(),\n\t\tBuildVersionCommand(),\n\t}\n}\n\nfunc main() {\n\tprogram = command.Program{\n\t\tName:           \"ginkgo\",\n\t\tHeading:        fmt.Sprintf(\"Ginkgo Version %s\", types.VERSION),\n\t\tCommands:       GenerateCommands(),\n\t\tDefaultCommand: run.BuildRunCommand(),\n\t\tDeprecatedCommands: []command.DeprecatedCommand{\n\t\t\t{Name: \"convert\", Deprecation: types.Deprecations.Convert()},\n\t\t\t{Name: \"blur\", Deprecation: types.Deprecations.Blur()},\n\t\t\t{Name: \"nodot\", Deprecation: types.Deprecations.Nodot()},\n\t\t},\n\t}\n\n\tprogram.RunAndExit(os.Args)\n}\n\nfunc BuildVersionCommand() command.Command {\n\treturn command.Command{\n\t\tName:     \"version\",\n\t\tUsage:    \"ginkgo version\",\n\t\tShortDoc: \"Print Ginkgo's version\",\n\t\tCommand: func(_ []string, _ []string) {\n\t\t\tfmt.Printf(\"Ginkgo Version %s\\n\", types.VERSION)\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go",
    "content": "package outline\n\nimport (\n\t\"go/ast\"\n\t\"go/token\"\n\t\"strconv\"\n\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\nconst (\n\t// undefinedTextAlt is used if the spec/container text cannot be derived\n\tundefinedTextAlt = \"undefined\"\n)\n\n// ginkgoMetadata holds useful bits of information for every entry in the outline\ntype ginkgoMetadata struct {\n\t// Name is the spec or container function name, e.g. `Describe` or `It`\n\tName string `json:\"name\"`\n\n\t// Text is the `text` argument passed to specs, and some containers\n\tText string `json:\"text\"`\n\n\t// Start is the position of first character of the spec or container block\n\tStart int `json:\"start\"`\n\n\t// End is the position of first character immediately after the spec or container block\n\tEnd int `json:\"end\"`\n\n\tSpec    bool     `json:\"spec\"`\n\tFocused bool     `json:\"focused\"`\n\tPending bool     `json:\"pending\"`\n\tLabels  []string `json:\"labels\"`\n}\n\n// ginkgoNode is used to construct the outline as a tree\ntype ginkgoNode struct {\n\tginkgoMetadata\n\tNodes []*ginkgoNode `json:\"nodes\"`\n}\n\ntype walkFunc func(n *ginkgoNode)\n\nfunc (n *ginkgoNode) PreOrder(f walkFunc) {\n\tf(n)\n\tfor _, m := range n.Nodes {\n\t\tm.PreOrder(f)\n\t}\n}\n\nfunc (n *ginkgoNode) PostOrder(f walkFunc) {\n\tfor _, m := range n.Nodes {\n\t\tm.PostOrder(f)\n\t}\n\tf(n)\n}\n\nfunc (n *ginkgoNode) Walk(pre, post walkFunc) {\n\tpre(n)\n\tfor _, m := range n.Nodes {\n\t\tm.Walk(pre, post)\n\t}\n\tpost(n)\n}\n\n// PropagateInheritedProperties propagates the Pending and Focused properties\n// through the subtree rooted at n.\nfunc (n *ginkgoNode) PropagateInheritedProperties() {\n\tn.PreOrder(func(thisNode *ginkgoNode) {\n\t\tfor _, descendantNode := range thisNode.Nodes {\n\t\t\tif thisNode.Pending {\n\t\t\t\tdescendantNode.Pending = true\n\t\t\t\tdescendantNode.Focused = false\n\t\t\t}\n\t\t\tif thisNode.Focused && !descendantNode.Pending {\n\t\t\t\tdescendantNode.Focused = true\n\t\t\t}\n\t\t}\n\t})\n}\n\n// BackpropagateUnfocus propagates the Focused property through the subtree\n// rooted at n. It applies the rule described in the Ginkgo docs:\n// > Nested programmatically focused specs follow a simple rule: if a\n// > leaf-node is marked focused, any of its ancestor nodes that are marked\n// > focus will be unfocused.\nfunc (n *ginkgoNode) BackpropagateUnfocus() {\n\tfocusedSpecInSubtreeStack := []bool{}\n\tn.PostOrder(func(thisNode *ginkgoNode) {\n\t\tif thisNode.Spec {\n\t\t\tfocusedSpecInSubtreeStack = append(focusedSpecInSubtreeStack, thisNode.Focused)\n\t\t\treturn\n\t\t}\n\t\tfocusedSpecInSubtree := false\n\t\tfor range thisNode.Nodes {\n\t\t\tfocusedSpecInSubtree = focusedSpecInSubtree || focusedSpecInSubtreeStack[len(focusedSpecInSubtreeStack)-1]\n\t\t\tfocusedSpecInSubtreeStack = focusedSpecInSubtreeStack[0 : len(focusedSpecInSubtreeStack)-1]\n\t\t}\n\t\tfocusedSpecInSubtreeStack = append(focusedSpecInSubtreeStack, focusedSpecInSubtree)\n\t\tif focusedSpecInSubtree {\n\t\t\tthisNode.Focused = false\n\t\t}\n\t})\n\n}\n\nfunc packageAndIdentNamesFromCallExpr(ce *ast.CallExpr) (string, string, bool) {\n\tswitch ex := ce.Fun.(type) {\n\tcase *ast.Ident:\n\t\treturn \"\", ex.Name, true\n\tcase *ast.SelectorExpr:\n\t\tpkgID, ok := ex.X.(*ast.Ident)\n\t\tif !ok {\n\t\t\treturn \"\", \"\", false\n\t\t}\n\t\t// A package identifier is top-level, so Obj must be nil\n\t\tif pkgID.Obj != nil {\n\t\t\treturn \"\", \"\", false\n\t\t}\n\t\tif ex.Sel == nil {\n\t\t\treturn \"\", \"\", false\n\t\t}\n\t\treturn pkgID.Name, ex.Sel.Name, true\n\tdefault:\n\t\treturn \"\", \"\", false\n\t}\n}\n\n// absoluteOffsetsForNode derives the absolute character offsets of the node start and\n// end positions.\nfunc absoluteOffsetsForNode(fset *token.FileSet, n ast.Node) (start, end int) {\n\treturn fset.PositionFor(n.Pos(), false).Offset, fset.PositionFor(n.End(), false).Offset\n}\n\n// ginkgoNodeFromCallExpr derives an outline entry from a go AST subtree\n// corresponding to a Ginkgo container or spec.\nfunc ginkgoNodeFromCallExpr(fset *token.FileSet, ce *ast.CallExpr, ginkgoPackageName *string) (*ginkgoNode, bool) {\n\tpackageName, identName, ok := packageAndIdentNamesFromCallExpr(ce)\n\tif !ok {\n\t\treturn nil, false\n\t}\n\n\tn := ginkgoNode{}\n\tn.Name = identName\n\tn.Start, n.End = absoluteOffsetsForNode(fset, ce)\n\tn.Nodes = make([]*ginkgoNode, 0)\n\tswitch identName {\n\tcase \"It\", \"Specify\", \"Entry\":\n\t\tn.Spec = true\n\t\tn.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)\n\t\tn.Labels = labelFromCallExpr(ce)\n\t\tn.Pending = pendingFromCallExpr(ce)\n\t\treturn &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName\n\tcase \"FIt\", \"FSpecify\", \"FEntry\":\n\t\tn.Spec = true\n\t\tn.Focused = true\n\t\tn.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)\n\t\tn.Labels = labelFromCallExpr(ce)\n\t\treturn &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName\n\tcase \"PIt\", \"PSpecify\", \"XIt\", \"XSpecify\", \"PEntry\", \"XEntry\":\n\t\tn.Spec = true\n\t\tn.Pending = true\n\t\tn.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)\n\t\tn.Labels = labelFromCallExpr(ce)\n\t\treturn &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName\n\tcase \"Context\", \"Describe\", \"When\", \"DescribeTable\":\n\t\tn.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)\n\t\tn.Labels = labelFromCallExpr(ce)\n\t\tn.Pending = pendingFromCallExpr(ce)\n\t\treturn &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName\n\tcase \"FContext\", \"FDescribe\", \"FWhen\", \"FDescribeTable\":\n\t\tn.Focused = true\n\t\tn.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)\n\t\tn.Labels = labelFromCallExpr(ce)\n\t\treturn &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName\n\tcase \"PContext\", \"PDescribe\", \"PWhen\", \"XContext\", \"XDescribe\", \"XWhen\", \"PDescribeTable\", \"XDescribeTable\":\n\t\tn.Pending = true\n\t\tn.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)\n\t\tn.Labels = labelFromCallExpr(ce)\n\t\treturn &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName\n\tcase \"By\":\n\t\tn.Text = textOrAltFromCallExpr(ce, undefinedTextAlt)\n\t\treturn &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName\n\tcase \"AfterEach\", \"BeforeEach\":\n\t\treturn &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName\n\tcase \"JustAfterEach\", \"JustBeforeEach\":\n\t\treturn &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName\n\tcase \"AfterSuite\", \"BeforeSuite\":\n\t\treturn &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName\n\tcase \"SynchronizedAfterSuite\", \"SynchronizedBeforeSuite\":\n\t\treturn &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName\n\tdefault:\n\t\treturn nil, false\n\t}\n}\n\n// textOrAltFromCallExpr tries to derive the \"text\" of a Ginkgo spec or\n// container. If it cannot derive it, it returns the alt text.\nfunc textOrAltFromCallExpr(ce *ast.CallExpr, alt string) string {\n\ttext, defined := textFromCallExpr(ce)\n\tif !defined {\n\t\treturn alt\n\t}\n\treturn text\n}\n\n// textFromCallExpr tries to derive the \"text\" of a Ginkgo spec or container. If\n// it cannot derive it, it returns false.\nfunc textFromCallExpr(ce *ast.CallExpr) (string, bool) {\n\tif len(ce.Args) < 1 {\n\t\treturn \"\", false\n\t}\n\ttext, ok := ce.Args[0].(*ast.BasicLit)\n\tif !ok {\n\t\treturn \"\", false\n\t}\n\tswitch text.Kind {\n\tcase token.CHAR, token.STRING:\n\t\t// For token.CHAR and token.STRING, Value is quoted\n\t\tunquoted, err := strconv.Unquote(text.Value)\n\t\tif err != nil {\n\t\t\t// If unquoting fails, just use the raw Value\n\t\t\treturn text.Value, true\n\t\t}\n\t\treturn unquoted, true\n\tdefault:\n\t\treturn text.Value, true\n\t}\n}\n\nfunc labelFromCallExpr(ce *ast.CallExpr) []string {\n\n\tlabels := []string{}\n\tif len(ce.Args) < 2 {\n\t\treturn labels\n\t}\n\n\tfor _, arg := range ce.Args[1:] {\n\t\tswitch expr := arg.(type) {\n\t\tcase *ast.CallExpr:\n\t\t\tid, ok := expr.Fun.(*ast.Ident)\n\t\t\tif !ok {\n\t\t\t\t// to skip over cases where the expr.Fun. is actually *ast.SelectorExpr\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif id.Name == \"Label\" {\n\t\t\t\tls := extractLabels(expr)\n\t\t\t\tlabels = append(labels, ls...)\n\t\t\t}\n\t\t}\n\t}\n\treturn labels\n}\n\nfunc extractLabels(expr *ast.CallExpr) []string {\n\tout := []string{}\n\tfor _, arg := range expr.Args {\n\t\tswitch expr := arg.(type) {\n\t\tcase *ast.BasicLit:\n\t\t\tif expr.Kind == token.STRING {\n\t\t\t\tunquoted, err := strconv.Unquote(expr.Value)\n\t\t\t\tif err != nil {\n\t\t\t\t\tunquoted = expr.Value\n\t\t\t\t}\n\t\t\t\tvalidated, err := types.ValidateAndCleanupLabel(unquoted, types.CodeLocation{})\n\t\t\t\tif err == nil {\n\t\t\t\t\tout = append(out, validated)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn out\n}\n\nfunc pendingFromCallExpr(ce *ast.CallExpr) bool {\n\n\tpending := false\n\tif len(ce.Args) < 2 {\n\t\treturn pending\n\t}\n\n\tfor _, arg := range ce.Args[1:] {\n\t\tswitch expr := arg.(type) {\n\t\tcase *ast.CallExpr:\n\t\t\tid, ok := expr.Fun.(*ast.Ident)\n\t\t\tif !ok {\n\t\t\t\t// to skip over cases where the expr.Fun. is actually *ast.SelectorExpr\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif id.Name == \"Pending\" {\n\t\t\t\tpending = true\n\t\t\t}\n\t\tcase *ast.Ident:\n\t\t\tif expr.Name == \"Pending\" {\n\t\t\t\tpending = true\n\t\t\t}\n\t\t}\n\t}\n\treturn pending\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/import.go",
    "content": "// Copyright 2013 The Go 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\n// Most of the required functions were available in the\n// \"golang.org/x/tools/go/ast/astutil\" package, but not exported.\n// They were copied from https://github.com/golang/tools/blob/2b0845dc783e36ae26d683f4915a5840ef01ab0f/go/ast/astutil/imports.go\n\npackage outline\n\nimport (\n\t\"go/ast\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// packageNameForImport returns the package name for the package. If the package\n// is not imported, it returns nil. \"Package name\" refers to `pkgname` in the\n// call expression `pkgname.ExportedIdentifier`. Examples:\n// (import path not found) -> nil\n// \"import example.com/pkg/foo\" -> \"foo\"\n// \"import fooalias example.com/pkg/foo\" -> \"fooalias\"\n// \"import . example.com/pkg/foo\" -> \"\"\nfunc packageNameForImport(f *ast.File, path string) *string {\n\tspec := importSpec(f, path)\n\tif spec == nil {\n\t\treturn nil\n\t}\n\tname := spec.Name.String()\n\tif name == \"<nil>\" {\n\t\tname = \"ginkgo\"\n\t}\n\tif name == \".\" {\n\t\tname = \"\"\n\t}\n\treturn &name\n}\n\n// importSpec returns the import spec if f imports path,\n// or nil otherwise.\nfunc importSpec(f *ast.File, path string) *ast.ImportSpec {\n\tfor _, s := range f.Imports {\n\t\tif strings.HasPrefix(importPath(s), path) {\n\t\t\treturn s\n\t\t}\n\t}\n\treturn nil\n}\n\n// importPath returns the unquoted import path of s,\n// or \"\" if the path is not properly quoted.\nfunc importPath(s *ast.ImportSpec) string {\n\tt, err := strconv.Unquote(s.Path.Value)\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\treturn t\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go",
    "content": "package outline\n\nimport (\n\t\"bytes\"\n\t\"encoding/csv\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"go/ast\"\n\t\"go/token\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"golang.org/x/tools/go/ast/inspector\"\n)\n\nconst (\n\t// ginkgoImportPath is the well-known ginkgo import path\n\tginkgoImportPath = \"github.com/onsi/ginkgo/v2\"\n)\n\n// FromASTFile returns an outline for a Ginkgo test source file\nfunc FromASTFile(fset *token.FileSet, src *ast.File) (*outline, error) {\n\tginkgoPackageName := packageNameForImport(src, ginkgoImportPath)\n\tif ginkgoPackageName == nil {\n\t\treturn nil, fmt.Errorf(\"file does not import %q\", ginkgoImportPath)\n\t}\n\n\troot := ginkgoNode{}\n\tstack := []*ginkgoNode{&root}\n\tispr := inspector.New([]*ast.File{src})\n\tispr.Nodes([]ast.Node{(*ast.CallExpr)(nil)}, func(node ast.Node, push bool) bool {\n\t\tif push {\n\t\t\t// Pre-order traversal\n\t\t\tce, ok := node.(*ast.CallExpr)\n\t\t\tif !ok {\n\t\t\t\t// Because `Nodes` calls this function only when the node is an\n\t\t\t\t// ast.CallExpr, this should never happen\n\t\t\t\tpanic(fmt.Errorf(\"node starting at %d, ending at %d is not an *ast.CallExpr\", node.Pos(), node.End()))\n\t\t\t}\n\t\t\tgn, ok := ginkgoNodeFromCallExpr(fset, ce, ginkgoPackageName)\n\t\t\tif !ok {\n\t\t\t\t// Node is not a Ginkgo spec or container, continue\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tparent := stack[len(stack)-1]\n\t\t\tparent.Nodes = append(parent.Nodes, gn)\n\t\t\tstack = append(stack, gn)\n\t\t\treturn true\n\t\t}\n\t\t// Post-order traversal\n\t\tstart, end := absoluteOffsetsForNode(fset, node)\n\t\tlastVisitedGinkgoNode := stack[len(stack)-1]\n\t\tif start != lastVisitedGinkgoNode.Start || end != lastVisitedGinkgoNode.End {\n\t\t\t// Node is not a Ginkgo spec or container, so it was not pushed onto the stack, continue\n\t\t\treturn true\n\t\t}\n\t\tstack = stack[0 : len(stack)-1]\n\t\treturn true\n\t})\n\tif len(root.Nodes) == 0 {\n\t\treturn &outline{[]*ginkgoNode{}}, nil\n\t}\n\n\t// Derive the final focused property for all nodes. This must be done\n\t// _before_ propagating the inherited focused property.\n\troot.BackpropagateUnfocus()\n\t// Now, propagate inherited properties, including focused and pending.\n\troot.PropagateInheritedProperties()\n\n\treturn &outline{root.Nodes}, nil\n}\n\ntype outline struct {\n\tNodes []*ginkgoNode `json:\"nodes\"`\n}\n\nfunc (o *outline) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(o.Nodes)\n}\n\n// String returns a CSV-formatted outline. Spec or container are output in\n// depth-first order.\nfunc (o *outline) String() string {\n\treturn o.StringIndent(0)\n}\n\n// StringIndent returns a CSV-formated outline, but every line is indented by\n// one 'width' of spaces for every level of nesting.\nfunc (o *outline) StringIndent(width int) string {\n\tvar b bytes.Buffer\n\tb.WriteString(\"Name,Text,Start,End,Spec,Focused,Pending,Labels\\n\")\n\n\tcsvWriter := csv.NewWriter(&b)\n\n\tcurrentIndent := 0\n\tpre := func(n *ginkgoNode) {\n\t\tb.WriteString(fmt.Sprintf(\"%*s\", currentIndent, \"\"))\n\t\tvar labels string\n\t\tif len(n.Labels) == 1 {\n\t\t\tlabels = n.Labels[0]\n\t\t} else {\n\t\t\tlabels = strings.Join(n.Labels, \", \")\n\t\t}\n\n\t\trow := []string{\n\t\t\tn.Name,\n\t\t\tn.Text,\n\t\t\tstrconv.Itoa(n.Start),\n\t\t\tstrconv.Itoa(n.End),\n\t\t\tstrconv.FormatBool(n.Spec),\n\t\t\tstrconv.FormatBool(n.Focused),\n\t\t\tstrconv.FormatBool(n.Pending),\n\t\t\tlabels,\n\t\t}\n\t\tcsvWriter.Write(row)\n\n\t\t// Ensure we write to `b' before the next `b.WriteString()', which might be adding indentation\n\t\tcsvWriter.Flush()\n\n\t\tcurrentIndent += width\n\t}\n\tpost := func(n *ginkgoNode) {\n\t\tcurrentIndent -= width\n\t}\n\tfor _, n := range o.Nodes {\n\t\tn.Walk(pre, post)\n\t}\n\n\treturn b.String()\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline_command.go",
    "content": "package outline\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"go/parser\"\n\t\"go/token\"\n\t\"os\"\n\n\t\"github.com/onsi/ginkgo/v2/ginkgo/command\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\nconst (\n\t// indentWidth is the width used by the 'indent' output\n\tindentWidth = 4\n\t// stdinAlias is a portable alias for stdin. This convention is used in\n\t// other CLIs, e.g., kubectl.\n\tstdinAlias   = \"-\"\n\tusageCommand = \"ginkgo outline <filename>\"\n)\n\ntype outlineConfig struct {\n\tFormat string\n}\n\nfunc BuildOutlineCommand() command.Command {\n\tconf := outlineConfig{\n\t\tFormat: \"csv\",\n\t}\n\tflags, err := types.NewGinkgoFlagSet(\n\t\ttypes.GinkgoFlags{\n\t\t\t{Name: \"format\", KeyPath: \"Format\",\n\t\t\t\tUsage:             \"Format of outline\",\n\t\t\t\tUsageArgument:     \"one of 'csv', 'indent', or 'json'\",\n\t\t\t\tUsageDefaultValue: conf.Format,\n\t\t\t},\n\t\t},\n\t\t&conf,\n\t\ttypes.GinkgoFlagSections{},\n\t)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treturn command.Command{\n\t\tName:          \"outline\",\n\t\tUsage:         \"ginkgo outline <filename>\",\n\t\tShortDoc:      \"Create an outline of Ginkgo symbols for a file\",\n\t\tDocumentation: \"To read from stdin, use: `ginkgo outline -`\",\n\t\tDocLink:       \"creating-an-outline-of-specs\",\n\t\tFlags:         flags,\n\t\tCommand: func(args []string, _ []string) {\n\t\t\toutlineFile(args, conf.Format)\n\t\t},\n\t}\n}\n\nfunc outlineFile(args []string, format string) {\n\tif len(args) != 1 {\n\t\tcommand.AbortWithUsage(\"outline expects exactly one argument\")\n\t}\n\n\tfilename := args[0]\n\tvar src *os.File\n\tif filename == stdinAlias {\n\t\tsrc = os.Stdin\n\t} else {\n\t\tvar err error\n\t\tsrc, err = os.Open(filename)\n\t\tcommand.AbortIfError(\"Failed to open file:\", err)\n\t}\n\n\tfset := token.NewFileSet()\n\n\tparsedSrc, err := parser.ParseFile(fset, filename, src, 0)\n\tcommand.AbortIfError(\"Failed to parse source:\", err)\n\n\to, err := FromASTFile(fset, parsedSrc)\n\tcommand.AbortIfError(\"Failed to create outline:\", err)\n\n\tvar oerr error\n\tswitch format {\n\tcase \"csv\":\n\t\t_, oerr = fmt.Print(o)\n\tcase \"indent\":\n\t\t_, oerr = fmt.Print(o.StringIndent(indentWidth))\n\tcase \"json\":\n\t\tb, err := json.Marshal(o)\n\t\tif err != nil {\n\t\t\tprintln(fmt.Sprintf(\"error marshalling to json: %s\", err))\n\t\t}\n\t\t_, oerr = fmt.Println(string(b))\n\tdefault:\n\t\tcommand.AbortWith(\"Format %s not accepted\", format)\n\t}\n\tcommand.AbortIfError(\"Failed to write outline:\", oerr)\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go",
    "content": "package run\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/onsi/ginkgo/v2/formatter\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/command\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/internal\"\n\t\"github.com/onsi/ginkgo/v2/internal/interrupt_handler\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\nfunc BuildRunCommand() command.Command {\n\tvar suiteConfig = types.NewDefaultSuiteConfig()\n\tvar reporterConfig = types.NewDefaultReporterConfig()\n\tvar cliConfig = types.NewDefaultCLIConfig()\n\tvar goFlagsConfig = types.NewDefaultGoFlagsConfig()\n\n\tflags, err := types.BuildRunCommandFlagSet(&suiteConfig, &reporterConfig, &cliConfig, &goFlagsConfig)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tinterruptHandler := interrupt_handler.NewInterruptHandler(nil)\n\tinterrupt_handler.SwallowSigQuit()\n\n\treturn command.Command{\n\t\tName:          \"run\",\n\t\tFlags:         flags,\n\t\tUsage:         \"ginkgo run <FLAGS> <PACKAGES> -- <PASS-THROUGHS>\",\n\t\tShortDoc:      \"Run the tests in the passed in <PACKAGES> (or the package in the current directory if left blank)\",\n\t\tDocumentation: \"Any arguments after -- will be passed to the test.\",\n\t\tDocLink:       \"running-tests\",\n\t\tCommand: func(args []string, additionalArgs []string) {\n\t\t\tvar errors []error\n\t\t\tcliConfig, goFlagsConfig, errors = types.VetAndInitializeCLIAndGoConfig(cliConfig, goFlagsConfig)\n\t\t\tcommand.AbortIfErrors(\"Ginkgo detected configuration issues:\", errors)\n\n\t\t\trunner := &SpecRunner{\n\t\t\t\tcliConfig:      cliConfig,\n\t\t\t\tgoFlagsConfig:  goFlagsConfig,\n\t\t\t\tsuiteConfig:    suiteConfig,\n\t\t\t\treporterConfig: reporterConfig,\n\t\t\t\tflags:          flags,\n\n\t\t\t\tinterruptHandler: interruptHandler,\n\t\t\t}\n\n\t\t\trunner.RunSpecs(args, additionalArgs)\n\t\t},\n\t}\n}\n\ntype SpecRunner struct {\n\tsuiteConfig    types.SuiteConfig\n\treporterConfig types.ReporterConfig\n\tcliConfig      types.CLIConfig\n\tgoFlagsConfig  types.GoFlagsConfig\n\tflags          types.GinkgoFlagSet\n\n\tinterruptHandler *interrupt_handler.InterruptHandler\n}\n\nfunc (r *SpecRunner) RunSpecs(args []string, additionalArgs []string) {\n\tsuites := internal.FindSuites(args, r.cliConfig, true)\n\tskippedSuites := suites.WithState(internal.TestSuiteStateSkippedByFilter)\n\tsuites = suites.WithoutState(internal.TestSuiteStateSkippedByFilter)\n\n\tinternal.VerifyCLIAndFrameworkVersion(suites)\n\n\tif len(skippedSuites) > 0 {\n\t\tfmt.Println(\"Will skip:\")\n\t\tfor _, skippedSuite := range skippedSuites {\n\t\t\tfmt.Println(\"  \" + skippedSuite.Path)\n\t\t}\n\t}\n\n\tif len(skippedSuites) > 0 && len(suites) == 0 {\n\t\tcommand.AbortGracefullyWith(\"All tests skipped! Exiting...\")\n\t}\n\n\tif len(suites) == 0 {\n\t\tcommand.AbortWith(\"Found no test suites\")\n\t}\n\n\tif len(suites) > 1 && !r.flags.WasSet(\"succinct\") && r.reporterConfig.Verbosity().LT(types.VerbosityLevelVerbose) {\n\t\tr.reporterConfig.Succinct = true\n\t}\n\n\tt := time.Now()\n\tvar endTime time.Time\n\tif r.suiteConfig.Timeout > 0 {\n\t\tendTime = t.Add(r.suiteConfig.Timeout)\n\t}\n\n\titeration := 0\nOUTER_LOOP:\n\tfor {\n\t\tif !r.flags.WasSet(\"seed\") {\n\t\t\tr.suiteConfig.RandomSeed = time.Now().Unix()\n\t\t}\n\t\tif r.cliConfig.RandomizeSuites && len(suites) > 1 {\n\t\t\tsuites = suites.ShuffledCopy(r.suiteConfig.RandomSeed)\n\t\t}\n\n\t\topc := internal.NewOrderedParallelCompiler(r.cliConfig.ComputedNumCompilers())\n\t\topc.StartCompiling(suites, r.goFlagsConfig, false)\n\n\tSUITE_LOOP:\n\t\tfor {\n\t\t\tsuiteIdx, suite := opc.Next()\n\t\t\tif suiteIdx >= len(suites) {\n\t\t\t\tbreak SUITE_LOOP\n\t\t\t}\n\t\t\tsuites[suiteIdx] = suite\n\n\t\t\tif r.interruptHandler.Status().Interrupted() {\n\t\t\t\topc.StopAndDrain()\n\t\t\t\tbreak OUTER_LOOP\n\t\t\t}\n\n\t\t\tif suites[suiteIdx].State.Is(internal.TestSuiteStateSkippedDueToEmptyCompilation) {\n\t\t\t\tfmt.Printf(\"Skipping %s (no test files)\\n\", suite.Path)\n\t\t\t\tcontinue SUITE_LOOP\n\t\t\t}\n\n\t\t\tif suites[suiteIdx].State.Is(internal.TestSuiteStateFailedToCompile) {\n\t\t\t\tfmt.Println(suites[suiteIdx].CompilationError.Error())\n\t\t\t\tif !r.cliConfig.KeepGoing {\n\t\t\t\t\topc.StopAndDrain()\n\t\t\t\t}\n\t\t\t\tcontinue SUITE_LOOP\n\t\t\t}\n\n\t\t\tif suites.CountWithState(internal.TestSuiteStateFailureStates...) > 0 && !r.cliConfig.KeepGoing {\n\t\t\t\tsuites[suiteIdx].State = internal.TestSuiteStateSkippedDueToPriorFailures\n\t\t\t\topc.StopAndDrain()\n\t\t\t\tcontinue SUITE_LOOP\n\t\t\t}\n\n\t\t\tif !endTime.IsZero() {\n\t\t\t\tr.suiteConfig.Timeout = time.Until(endTime)\n\t\t\t\tif r.suiteConfig.Timeout <= 0 {\n\t\t\t\t\tsuites[suiteIdx].State = internal.TestSuiteStateFailedDueToTimeout\n\t\t\t\t\topc.StopAndDrain()\n\t\t\t\t\tcontinue SUITE_LOOP\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsuites[suiteIdx] = internal.RunCompiledSuite(suites[suiteIdx], r.suiteConfig, r.reporterConfig, r.cliConfig, r.goFlagsConfig, additionalArgs)\n\t\t}\n\n\t\tif suites.CountWithState(internal.TestSuiteStateFailureStates...) > 0 {\n\t\t\tif iteration > 0 {\n\t\t\t\tfmt.Printf(\"\\nTests failed on attempt #%d\\n\\n\", iteration+1)\n\t\t\t}\n\t\t\tbreak OUTER_LOOP\n\t\t}\n\n\t\tif r.cliConfig.UntilItFails {\n\t\t\tfmt.Printf(\"\\nAll tests passed...\\nWill keep running them until they fail.\\nThis was attempt #%d\\n%s\\n\", iteration+1, orcMessage(iteration+1))\n\t\t} else if r.cliConfig.Repeat > 0 && iteration < r.cliConfig.Repeat {\n\t\t\tfmt.Printf(\"\\nAll tests passed...\\nThis was attempt %d of %d.\\n\", iteration+1, r.cliConfig.Repeat+1)\n\t\t} else {\n\t\t\tbreak OUTER_LOOP\n\t\t}\n\t\titeration += 1\n\t}\n\n\tinternal.Cleanup(r.goFlagsConfig, suites...)\n\n\tmessages, err := internal.FinalizeProfilesAndReportsForSuites(suites, r.cliConfig, r.suiteConfig, r.reporterConfig, r.goFlagsConfig)\n\tcommand.AbortIfError(\"could not finalize profiles:\", err)\n\tfor _, message := range messages {\n\t\tfmt.Println(message)\n\t}\n\n\tfmt.Printf(\"\\nGinkgo ran %d %s in %s\\n\", len(suites), internal.PluralizedWord(\"suite\", \"suites\", len(suites)), time.Since(t))\n\n\tif suites.CountWithState(internal.TestSuiteStateFailureStates...) == 0 {\n\t\tif suites.AnyHaveProgrammaticFocus() && strings.TrimSpace(os.Getenv(\"GINKGO_EDITOR_INTEGRATION\")) == \"\" {\n\t\t\tfmt.Printf(\"Test Suite Passed\\n\")\n\t\t\tfmt.Printf(\"Detected Programmatic Focus - setting exit status to %d\\n\", types.GINKGO_FOCUS_EXIT_CODE)\n\t\t\tcommand.Abort(command.AbortDetails{ExitCode: types.GINKGO_FOCUS_EXIT_CODE})\n\t\t} else {\n\t\t\tfmt.Printf(\"Test Suite Passed\\n\")\n\t\t\tcommand.Abort(command.AbortDetails{})\n\t\t}\n\t} else {\n\t\tfmt.Fprintln(formatter.ColorableStdOut, \"\")\n\t\tif len(suites) > 1 && suites.CountWithState(internal.TestSuiteStateFailureStates...) > 0 {\n\t\t\tfmt.Fprintln(formatter.ColorableStdOut,\n\t\t\t\tinternal.FailedSuitesReport(suites, formatter.NewWithNoColorBool(r.reporterConfig.NoColor)))\n\t\t}\n\t\tfmt.Printf(\"Test Suite Failed\\n\")\n\t\tcommand.Abort(command.AbortDetails{ExitCode: 1})\n\t}\n}\n\nfunc orcMessage(iteration int) string {\n\tif iteration < 10 {\n\t\treturn \"\"\n\t} else if iteration < 30 {\n\t\treturn []string{\n\t\t\t\"If at first you succeed...\",\n\t\t\t\"...try, try again.\",\n\t\t\t\"Looking good!\",\n\t\t\t\"Still good...\",\n\t\t\t\"I think your tests are fine....\",\n\t\t\t\"Yep, still passing\",\n\t\t\t\"Oh boy, here I go testin' again!\",\n\t\t\t\"Even the gophers are getting bored\",\n\t\t\t\"Did you try -race?\",\n\t\t\t\"Maybe you should stop now?\",\n\t\t\t\"I'm getting tired...\",\n\t\t\t\"What if I just made you a sandwich?\",\n\t\t\t\"Hit ^C, hit ^C, please hit ^C\",\n\t\t\t\"Make it stop. Please!\",\n\t\t\t\"Come on!  Enough is enough!\",\n\t\t\t\"Dave, this conversation can serve no purpose anymore. Goodbye.\",\n\t\t\t\"Just what do you think you're doing, Dave? \",\n\t\t\t\"I, Sisyphus\",\n\t\t\t\"Insanity: doing the same thing over and over again and expecting different results. -Einstein\",\n\t\t\t\"I guess Einstein never tried to churn butter\",\n\t\t}[iteration-10] + \"\\n\"\n\t} else {\n\t\treturn \"No, seriously... you can probably stop now.\\n\"\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/unfocus/unfocus_command.go",
    "content": "package unfocus\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"go/ast\"\n\t\"go/parser\"\n\t\"go/token\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/onsi/ginkgo/v2/ginkgo/command\"\n)\n\nfunc BuildUnfocusCommand() command.Command {\n\treturn command.Command{\n\t\tName:     \"unfocus\",\n\t\tUsage:    \"ginkgo unfocus\",\n\t\tShortDoc: \"Recursively unfocus any focused tests under the current directory\",\n\t\tDocLink:  \"filtering-specs\",\n\t\tCommand: func(_ []string, _ []string) {\n\t\t\tunfocusSpecs()\n\t\t},\n\t}\n}\n\nfunc unfocusSpecs() {\n\tfmt.Println(\"Scanning for focus...\")\n\n\tgoFiles := make(chan string)\n\tgo func() {\n\t\tunfocusDir(goFiles, \".\")\n\t\tclose(goFiles)\n\t}()\n\n\tconst workers = 10\n\twg := sync.WaitGroup{}\n\twg.Add(workers)\n\n\tfor i := 0; i < workers; i++ {\n\t\tgo func() {\n\t\t\tfor path := range goFiles {\n\t\t\t\tunfocusFile(path)\n\t\t\t}\n\t\t\twg.Done()\n\t\t}()\n\t}\n\n\twg.Wait()\n}\n\nfunc unfocusDir(goFiles chan string, path string) {\n\tfiles, err := os.ReadDir(path)\n\tif err != nil {\n\t\tfmt.Println(err.Error())\n\t\treturn\n\t}\n\n\tfor _, f := range files {\n\t\tswitch {\n\t\tcase f.IsDir() && shouldProcessDir(f.Name()):\n\t\t\tunfocusDir(goFiles, filepath.Join(path, f.Name()))\n\t\tcase !f.IsDir() && shouldProcessFile(f.Name()):\n\t\t\tgoFiles <- filepath.Join(path, f.Name())\n\t\t}\n\t}\n}\n\nfunc shouldProcessDir(basename string) bool {\n\treturn basename != \"vendor\" && !strings.HasPrefix(basename, \".\")\n}\n\nfunc shouldProcessFile(basename string) bool {\n\treturn strings.HasSuffix(basename, \".go\")\n}\n\nfunc unfocusFile(path string) {\n\tdata, err := os.ReadFile(path)\n\tif err != nil {\n\t\tfmt.Printf(\"error reading file '%s': %s\\n\", path, err.Error())\n\t\treturn\n\t}\n\n\tast, err := parser.ParseFile(token.NewFileSet(), path, bytes.NewReader(data), parser.ParseComments)\n\tif err != nil {\n\t\tfmt.Printf(\"error parsing file '%s': %s\\n\", path, err.Error())\n\t\treturn\n\t}\n\n\teliminations := scanForFocus(ast)\n\tif len(eliminations) == 0 {\n\t\treturn\n\t}\n\n\tfmt.Printf(\"...updating %s\\n\", path)\n\tbackup, err := writeBackup(path, data)\n\tif err != nil {\n\t\tfmt.Printf(\"error creating backup file: %s\\n\", err.Error())\n\t\treturn\n\t}\n\n\tif err := updateFile(path, data, eliminations); err != nil {\n\t\tfmt.Printf(\"error writing file '%s': %s\\n\", path, err.Error())\n\t\treturn\n\t}\n\n\tos.Remove(backup)\n}\n\nfunc writeBackup(path string, data []byte) (string, error) {\n\tt, err := os.CreateTemp(filepath.Dir(path), filepath.Base(path))\n\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error creating temporary file: %w\", err)\n\t}\n\tdefer t.Close()\n\n\tif _, err := io.Copy(t, bytes.NewReader(data)); err != nil {\n\t\treturn \"\", fmt.Errorf(\"error writing to temporary file: %w\", err)\n\t}\n\n\treturn t.Name(), nil\n}\n\nfunc updateFile(path string, data []byte, eliminations [][]int64) error {\n\tto, err := os.Create(path)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error opening file for writing '%s': %w\\n\", path, err)\n\t}\n\tdefer to.Close()\n\n\tfrom := bytes.NewReader(data)\n\tvar cursor int64\n\tfor _, eliminationRange := range eliminations {\n\t\tpositionToEliminate, lengthToEliminate := eliminationRange[0]-1, eliminationRange[1]\n\t\tif _, err := io.CopyN(to, from, positionToEliminate-cursor); err != nil {\n\t\t\treturn fmt.Errorf(\"error copying data: %w\", err)\n\t\t}\n\n\t\tcursor = positionToEliminate + lengthToEliminate\n\n\t\tif _, err := from.Seek(lengthToEliminate, io.SeekCurrent); err != nil {\n\t\t\treturn fmt.Errorf(\"error seeking to position in buffer: %w\", err)\n\t\t}\n\t}\n\n\tif _, err := io.Copy(to, from); err != nil {\n\t\treturn fmt.Errorf(\"error copying end data: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc scanForFocus(file *ast.File) (eliminations [][]int64) {\n\tast.Inspect(file, func(n ast.Node) bool {\n\t\tif c, ok := n.(*ast.CallExpr); ok {\n\t\t\tif i, ok := c.Fun.(*ast.Ident); ok {\n\t\t\t\tif isFocus(i.Name) {\n\t\t\t\t\teliminations = append(eliminations, []int64{int64(i.Pos()), 1})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif i, ok := n.(*ast.Ident); ok {\n\t\t\tif i.Name == \"Focus\" {\n\t\t\t\teliminations = append(eliminations, []int64{int64(i.Pos()), 6})\n\t\t\t}\n\t\t}\n\n\t\treturn true\n\t})\n\n\treturn eliminations\n}\n\nfunc isFocus(name string) bool {\n\tswitch name {\n\tcase \"FDescribe\", \"FContext\", \"FIt\", \"FDescribeTable\", \"FEntry\", \"FSpecify\", \"FWhen\":\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/delta.go",
    "content": "package watch\n\nimport \"sort\"\n\ntype Delta struct {\n\tModifiedPackages []string\n\n\tNewSuites      []*Suite\n\tRemovedSuites  []*Suite\n\tmodifiedSuites []*Suite\n}\n\ntype DescendingByDelta []*Suite\n\nfunc (a DescendingByDelta) Len() int           { return len(a) }\nfunc (a DescendingByDelta) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }\nfunc (a DescendingByDelta) Less(i, j int) bool { return a[i].Delta() > a[j].Delta() }\n\nfunc (d Delta) ModifiedSuites() []*Suite {\n\tsort.Sort(DescendingByDelta(d.modifiedSuites))\n\treturn d.modifiedSuites\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/delta_tracker.go",
    "content": "package watch\n\nimport (\n\t\"fmt\"\n\n\t\"regexp\"\n\n\t\"github.com/onsi/ginkgo/v2/ginkgo/internal\"\n)\n\ntype SuiteErrors map[internal.TestSuite]error\n\ntype DeltaTracker struct {\n\tmaxDepth      int\n\twatchRegExp   *regexp.Regexp\n\tsuites        map[string]*Suite\n\tpackageHashes *PackageHashes\n}\n\nfunc NewDeltaTracker(maxDepth int, watchRegExp *regexp.Regexp) *DeltaTracker {\n\treturn &DeltaTracker{\n\t\tmaxDepth:      maxDepth,\n\t\twatchRegExp:   watchRegExp,\n\t\tpackageHashes: NewPackageHashes(watchRegExp),\n\t\tsuites:        map[string]*Suite{},\n\t}\n}\n\nfunc (d *DeltaTracker) Delta(suites internal.TestSuites) (delta Delta, errors SuiteErrors) {\n\terrors = SuiteErrors{}\n\tdelta.ModifiedPackages = d.packageHashes.CheckForChanges()\n\n\tprovidedSuitePaths := map[string]bool{}\n\tfor _, suite := range suites {\n\t\tprovidedSuitePaths[suite.Path] = true\n\t}\n\n\td.packageHashes.StartTrackingUsage()\n\n\tfor _, suite := range d.suites {\n\t\tif providedSuitePaths[suite.Suite.Path] {\n\t\t\tif suite.Delta() > 0 {\n\t\t\t\tdelta.modifiedSuites = append(delta.modifiedSuites, suite)\n\t\t\t}\n\t\t} else {\n\t\t\tdelta.RemovedSuites = append(delta.RemovedSuites, suite)\n\t\t}\n\t}\n\n\td.packageHashes.StopTrackingUsageAndPrune()\n\n\tfor _, suite := range suites {\n\t\t_, ok := d.suites[suite.Path]\n\t\tif !ok {\n\t\t\ts, err := NewSuite(suite, d.maxDepth, d.packageHashes)\n\t\t\tif err != nil {\n\t\t\t\terrors[suite] = err\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\td.suites[suite.Path] = s\n\t\t\tdelta.NewSuites = append(delta.NewSuites, s)\n\t\t}\n\t}\n\n\treturn delta, errors\n}\n\nfunc (d *DeltaTracker) WillRun(suite internal.TestSuite) error {\n\ts, ok := d.suites[suite.Path]\n\tif !ok {\n\t\treturn fmt.Errorf(\"unknown suite %s\", suite.Path)\n\t}\n\n\treturn s.MarkAsRunAndRecomputedDependencies(d.maxDepth)\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/dependencies.go",
    "content": "package watch\n\nimport (\n\t\"go/build\"\n\t\"regexp\"\n)\n\nvar ginkgoAndGomegaFilter = regexp.MustCompile(`github\\.com/onsi/ginkgo|github\\.com/onsi/gomega`)\nvar ginkgoIntegrationTestFilter = regexp.MustCompile(`github\\.com/onsi/ginkgo/integration`) //allow us to integration test this thing\n\ntype Dependencies struct {\n\tdeps map[string]int\n}\n\nfunc NewDependencies(path string, maxDepth int) (Dependencies, error) {\n\td := Dependencies{\n\t\tdeps: map[string]int{},\n\t}\n\n\tif maxDepth == 0 {\n\t\treturn d, nil\n\t}\n\n\terr := d.seedWithDepsForPackageAtPath(path)\n\tif err != nil {\n\t\treturn d, err\n\t}\n\n\tfor depth := 1; depth < maxDepth; depth++ {\n\t\tn := len(d.deps)\n\t\td.addDepsForDepth(depth)\n\t\tif n == len(d.deps) {\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn d, nil\n}\n\nfunc (d Dependencies) Dependencies() map[string]int {\n\treturn d.deps\n}\n\nfunc (d Dependencies) seedWithDepsForPackageAtPath(path string) error {\n\tpkg, err := build.ImportDir(path, 0)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\td.resolveAndAdd(pkg.Imports, 1)\n\td.resolveAndAdd(pkg.TestImports, 1)\n\td.resolveAndAdd(pkg.XTestImports, 1)\n\n\tdelete(d.deps, pkg.Dir)\n\treturn nil\n}\n\nfunc (d Dependencies) addDepsForDepth(depth int) {\n\tfor dep, depDepth := range d.deps {\n\t\tif depDepth == depth {\n\t\t\td.addDepsForDep(dep, depth+1)\n\t\t}\n\t}\n}\n\nfunc (d Dependencies) addDepsForDep(dep string, depth int) {\n\tpkg, err := build.ImportDir(dep, 0)\n\tif err != nil {\n\t\tprintln(err.Error())\n\t\treturn\n\t}\n\td.resolveAndAdd(pkg.Imports, depth)\n}\n\nfunc (d Dependencies) resolveAndAdd(deps []string, depth int) {\n\tfor _, dep := range deps {\n\t\tpkg, err := build.Import(dep, \".\", 0)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tif !pkg.Goroot && (!ginkgoAndGomegaFilter.MatchString(pkg.Dir) || ginkgoIntegrationTestFilter.MatchString(pkg.Dir)) {\n\t\t\td.addDepIfNotPresent(pkg.Dir, depth)\n\t\t}\n\t}\n}\n\nfunc (d Dependencies) addDepIfNotPresent(dep string, depth int) {\n\t_, ok := d.deps[dep]\n\tif !ok {\n\t\td.deps[dep] = depth\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/package_hash.go",
    "content": "package watch\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"strings\"\n\t\"time\"\n)\n\nvar goTestRegExp = regexp.MustCompile(`_test\\.go$`)\n\ntype PackageHash struct {\n\tCodeModifiedTime time.Time\n\tTestModifiedTime time.Time\n\tDeleted          bool\n\n\tpath        string\n\tcodeHash    string\n\ttestHash    string\n\twatchRegExp *regexp.Regexp\n}\n\nfunc NewPackageHash(path string, watchRegExp *regexp.Regexp) *PackageHash {\n\tp := &PackageHash{\n\t\tpath:        path,\n\t\twatchRegExp: watchRegExp,\n\t}\n\n\tp.codeHash, _, p.testHash, _, p.Deleted = p.computeHashes()\n\n\treturn p\n}\n\nfunc (p *PackageHash) CheckForChanges() bool {\n\tcodeHash, codeModifiedTime, testHash, testModifiedTime, deleted := p.computeHashes()\n\n\tif deleted {\n\t\tif !p.Deleted {\n\t\t\tt := time.Now()\n\t\t\tp.CodeModifiedTime = t\n\t\t\tp.TestModifiedTime = t\n\t\t}\n\t\tp.Deleted = true\n\t\treturn true\n\t}\n\n\tmodified := false\n\tp.Deleted = false\n\n\tif p.codeHash != codeHash {\n\t\tp.CodeModifiedTime = codeModifiedTime\n\t\tmodified = true\n\t}\n\tif p.testHash != testHash {\n\t\tp.TestModifiedTime = testModifiedTime\n\t\tmodified = true\n\t}\n\n\tp.codeHash = codeHash\n\tp.testHash = testHash\n\treturn modified\n}\n\nfunc (p *PackageHash) computeHashes() (codeHash string, codeModifiedTime time.Time, testHash string, testModifiedTime time.Time, deleted bool) {\n\tentries, err := os.ReadDir(p.path)\n\n\tif err != nil {\n\t\tdeleted = true\n\t\treturn\n\t}\n\n\tfor _, entry := range entries {\n\t\tif entry.IsDir() {\n\t\t\tcontinue\n\t\t}\n\n\t\tinfo, err := entry.Info()\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tif isHiddenFile(info) {\n\t\t\tcontinue\n\t\t}\n\n\t\tif goTestRegExp.MatchString(info.Name()) {\n\t\t\ttestHash += p.hashForFileInfo(info)\n\t\t\tif info.ModTime().After(testModifiedTime) {\n\t\t\t\ttestModifiedTime = info.ModTime()\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif p.watchRegExp.MatchString(info.Name()) {\n\t\t\tcodeHash += p.hashForFileInfo(info)\n\t\t\tif info.ModTime().After(codeModifiedTime) {\n\t\t\t\tcodeModifiedTime = info.ModTime()\n\t\t\t}\n\t\t}\n\t}\n\n\ttestHash += codeHash\n\tif codeModifiedTime.After(testModifiedTime) {\n\t\ttestModifiedTime = codeModifiedTime\n\t}\n\n\treturn\n}\n\nfunc isHiddenFile(info os.FileInfo) bool {\n\treturn strings.HasPrefix(info.Name(), \".\") || strings.HasPrefix(info.Name(), \"_\")\n}\n\nfunc (p *PackageHash) hashForFileInfo(info os.FileInfo) string {\n\treturn fmt.Sprintf(\"%s_%d_%d\", info.Name(), info.Size(), info.ModTime().UnixNano())\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/package_hashes.go",
    "content": "package watch\n\nimport (\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"sync\"\n)\n\ntype PackageHashes struct {\n\tPackageHashes map[string]*PackageHash\n\tusedPaths     map[string]bool\n\twatchRegExp   *regexp.Regexp\n\tlock          *sync.Mutex\n}\n\nfunc NewPackageHashes(watchRegExp *regexp.Regexp) *PackageHashes {\n\treturn &PackageHashes{\n\t\tPackageHashes: map[string]*PackageHash{},\n\t\tusedPaths:     nil,\n\t\twatchRegExp:   watchRegExp,\n\t\tlock:          &sync.Mutex{},\n\t}\n}\n\nfunc (p *PackageHashes) CheckForChanges() []string {\n\tp.lock.Lock()\n\tdefer p.lock.Unlock()\n\n\tmodified := []string{}\n\n\tfor _, packageHash := range p.PackageHashes {\n\t\tif packageHash.CheckForChanges() {\n\t\t\tmodified = append(modified, packageHash.path)\n\t\t}\n\t}\n\n\treturn modified\n}\n\nfunc (p *PackageHashes) Add(path string) *PackageHash {\n\tp.lock.Lock()\n\tdefer p.lock.Unlock()\n\n\tpath, _ = filepath.Abs(path)\n\t_, ok := p.PackageHashes[path]\n\tif !ok {\n\t\tp.PackageHashes[path] = NewPackageHash(path, p.watchRegExp)\n\t}\n\n\tif p.usedPaths != nil {\n\t\tp.usedPaths[path] = true\n\t}\n\treturn p.PackageHashes[path]\n}\n\nfunc (p *PackageHashes) Get(path string) *PackageHash {\n\tp.lock.Lock()\n\tdefer p.lock.Unlock()\n\n\tpath, _ = filepath.Abs(path)\n\tif p.usedPaths != nil {\n\t\tp.usedPaths[path] = true\n\t}\n\treturn p.PackageHashes[path]\n}\n\nfunc (p *PackageHashes) StartTrackingUsage() {\n\tp.lock.Lock()\n\tdefer p.lock.Unlock()\n\n\tp.usedPaths = map[string]bool{}\n}\n\nfunc (p *PackageHashes) StopTrackingUsageAndPrune() {\n\tp.lock.Lock()\n\tdefer p.lock.Unlock()\n\n\tfor path := range p.PackageHashes {\n\t\tif !p.usedPaths[path] {\n\t\t\tdelete(p.PackageHashes, path)\n\t\t}\n\t}\n\n\tp.usedPaths = nil\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/suite.go",
    "content": "package watch\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"time\"\n\n\t\"github.com/onsi/ginkgo/v2/ginkgo/internal\"\n)\n\ntype Suite struct {\n\tSuite        internal.TestSuite\n\tRunTime      time.Time\n\tDependencies Dependencies\n\n\tsharedPackageHashes *PackageHashes\n}\n\nfunc NewSuite(suite internal.TestSuite, maxDepth int, sharedPackageHashes *PackageHashes) (*Suite, error) {\n\tdeps, err := NewDependencies(suite.Path, maxDepth)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsharedPackageHashes.Add(suite.Path)\n\tfor dep := range deps.Dependencies() {\n\t\tsharedPackageHashes.Add(dep)\n\t}\n\n\treturn &Suite{\n\t\tSuite:        suite,\n\t\tDependencies: deps,\n\n\t\tsharedPackageHashes: sharedPackageHashes,\n\t}, nil\n}\n\nfunc (s *Suite) Delta() float64 {\n\tdelta := s.delta(s.Suite.Path, true, 0) * 1000\n\tfor dep, depth := range s.Dependencies.Dependencies() {\n\t\tdelta += s.delta(dep, false, depth)\n\t}\n\treturn delta\n}\n\nfunc (s *Suite) MarkAsRunAndRecomputedDependencies(maxDepth int) error {\n\ts.RunTime = time.Now()\n\n\tdeps, err := NewDependencies(s.Suite.Path, maxDepth)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ts.sharedPackageHashes.Add(s.Suite.Path)\n\tfor dep := range deps.Dependencies() {\n\t\ts.sharedPackageHashes.Add(dep)\n\t}\n\n\ts.Dependencies = deps\n\n\treturn nil\n}\n\nfunc (s *Suite) Description() string {\n\tnumDeps := len(s.Dependencies.Dependencies())\n\tpluralizer := \"ies\"\n\tif numDeps == 1 {\n\t\tpluralizer = \"y\"\n\t}\n\treturn fmt.Sprintf(\"%s [%d dependenc%s]\", s.Suite.Path, numDeps, pluralizer)\n}\n\nfunc (s *Suite) delta(packagePath string, includeTests bool, depth int) float64 {\n\treturn math.Max(float64(s.dt(packagePath, includeTests)), 0) / float64(depth+1)\n}\n\nfunc (s *Suite) dt(packagePath string, includeTests bool) time.Duration {\n\tpackageHash := s.sharedPackageHashes.Get(packagePath)\n\tvar modifiedTime time.Time\n\tif includeTests {\n\t\tmodifiedTime = packageHash.TestModifiedTime\n\t} else {\n\t\tmodifiedTime = packageHash.CodeModifiedTime\n\t}\n\n\treturn modifiedTime.Sub(s.RunTime)\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go",
    "content": "package watch\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"time\"\n\n\t\"github.com/onsi/ginkgo/v2/formatter\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/command\"\n\t\"github.com/onsi/ginkgo/v2/ginkgo/internal\"\n\t\"github.com/onsi/ginkgo/v2/internal/interrupt_handler\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\nfunc BuildWatchCommand() command.Command {\n\tvar suiteConfig = types.NewDefaultSuiteConfig()\n\tvar reporterConfig = types.NewDefaultReporterConfig()\n\tvar cliConfig = types.NewDefaultCLIConfig()\n\tvar goFlagsConfig = types.NewDefaultGoFlagsConfig()\n\n\tflags, err := types.BuildWatchCommandFlagSet(&suiteConfig, &reporterConfig, &cliConfig, &goFlagsConfig)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tinterruptHandler := interrupt_handler.NewInterruptHandler(nil)\n\tinterrupt_handler.SwallowSigQuit()\n\n\treturn command.Command{\n\t\tName:          \"watch\",\n\t\tFlags:         flags,\n\t\tUsage:         \"ginkgo watch <FLAGS> <PACKAGES> -- <PASS-THROUGHS>\",\n\t\tShortDoc:      \"Watch the passed in <PACKAGES> and runs their tests whenever changes occur.\",\n\t\tDocumentation: \"Any arguments after -- will be passed to the test.\",\n\t\tDocLink:       \"watching-for-changes\",\n\t\tCommand: func(args []string, additionalArgs []string) {\n\t\t\tvar errors []error\n\t\t\tcliConfig, goFlagsConfig, errors = types.VetAndInitializeCLIAndGoConfig(cliConfig, goFlagsConfig)\n\t\t\tcommand.AbortIfErrors(\"Ginkgo detected configuration issues:\", errors)\n\n\t\t\twatcher := &SpecWatcher{\n\t\t\t\tcliConfig:      cliConfig,\n\t\t\t\tgoFlagsConfig:  goFlagsConfig,\n\t\t\t\tsuiteConfig:    suiteConfig,\n\t\t\t\treporterConfig: reporterConfig,\n\t\t\t\tflags:          flags,\n\n\t\t\t\tinterruptHandler: interruptHandler,\n\t\t\t}\n\n\t\t\twatcher.WatchSpecs(args, additionalArgs)\n\t\t},\n\t}\n}\n\ntype SpecWatcher struct {\n\tsuiteConfig    types.SuiteConfig\n\treporterConfig types.ReporterConfig\n\tcliConfig      types.CLIConfig\n\tgoFlagsConfig  types.GoFlagsConfig\n\tflags          types.GinkgoFlagSet\n\n\tinterruptHandler *interrupt_handler.InterruptHandler\n}\n\nfunc (w *SpecWatcher) WatchSpecs(args []string, additionalArgs []string) {\n\tsuites := internal.FindSuites(args, w.cliConfig, false).WithoutState(internal.TestSuiteStateSkippedByFilter)\n\n\tinternal.VerifyCLIAndFrameworkVersion(suites)\n\n\tif len(suites) == 0 {\n\t\tcommand.AbortWith(\"Found no test suites\")\n\t}\n\n\tfmt.Printf(\"Identified %d test %s.  Locating dependencies to a depth of %d (this may take a while)...\\n\", len(suites), internal.PluralizedWord(\"suite\", \"suites\", len(suites)), w.cliConfig.Depth)\n\tdeltaTracker := NewDeltaTracker(w.cliConfig.Depth, regexp.MustCompile(w.cliConfig.WatchRegExp))\n\tdelta, errors := deltaTracker.Delta(suites)\n\n\tfmt.Printf(\"Watching %d %s:\\n\", len(delta.NewSuites), internal.PluralizedWord(\"suite\", \"suites\", len(delta.NewSuites)))\n\tfor _, suite := range delta.NewSuites {\n\t\tfmt.Println(\"  \" + suite.Description())\n\t}\n\n\tfor suite, err := range errors {\n\t\tfmt.Printf(\"Failed to watch %s: %s\\n\", suite.PackageName, err)\n\t}\n\n\tif len(suites) == 1 {\n\t\tw.updateSeed()\n\t\tw.compileAndRun(suites[0], additionalArgs)\n\t}\n\n\tticker := time.NewTicker(time.Second)\n\n\tfor {\n\t\tselect {\n\t\tcase <-ticker.C:\n\t\t\tsuites := internal.FindSuites(args, w.cliConfig, false).WithoutState(internal.TestSuiteStateSkippedByFilter)\n\t\t\tdelta, _ := deltaTracker.Delta(suites)\n\t\t\tcoloredStream := formatter.ColorableStdOut\n\n\t\t\tsuites = internal.TestSuites{}\n\n\t\t\tif len(delta.NewSuites) > 0 {\n\t\t\t\tfmt.Fprintln(coloredStream, formatter.F(\"{{green}}Detected %d new %s:{{/}}\", len(delta.NewSuites), internal.PluralizedWord(\"suite\", \"suites\", len(delta.NewSuites))))\n\t\t\t\tfor _, suite := range delta.NewSuites {\n\t\t\t\t\tsuites = append(suites, suite.Suite)\n\t\t\t\t\tfmt.Fprintln(coloredStream, formatter.Fi(1, \"%s\", suite.Description()))\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmodifiedSuites := delta.ModifiedSuites()\n\t\t\tif len(modifiedSuites) > 0 {\n\t\t\t\tfmt.Fprintln(coloredStream, formatter.F(\"{{green}}Detected changes in:{{/}}\"))\n\t\t\t\tfor _, pkg := range delta.ModifiedPackages {\n\t\t\t\t\tfmt.Fprintln(coloredStream, formatter.Fi(1, \"%s\", pkg))\n\t\t\t\t}\n\t\t\t\tfmt.Fprintln(coloredStream, formatter.F(\"{{green}}Will run %d %s:{{/}}\", len(modifiedSuites), internal.PluralizedWord(\"suite\", \"suites\", len(modifiedSuites))))\n\t\t\t\tfor _, suite := range modifiedSuites {\n\t\t\t\t\tsuites = append(suites, suite.Suite)\n\t\t\t\t\tfmt.Fprintln(coloredStream, formatter.Fi(1, \"%s\", suite.Description()))\n\t\t\t\t}\n\t\t\t\tfmt.Fprintln(coloredStream, \"\")\n\t\t\t}\n\n\t\t\tif len(suites) == 0 {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tw.updateSeed()\n\t\t\tw.computeSuccinctMode(len(suites))\n\t\t\tfor idx := range suites {\n\t\t\t\tif w.interruptHandler.Status().Interrupted() {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tdeltaTracker.WillRun(suites[idx])\n\t\t\t\tsuites[idx] = w.compileAndRun(suites[idx], additionalArgs)\n\t\t\t}\n\t\t\tcolor := \"{{green}}\"\n\t\t\tif suites.CountWithState(internal.TestSuiteStateFailureStates...) > 0 {\n\t\t\t\tcolor = \"{{red}}\"\n\t\t\t}\n\t\t\tfmt.Fprintln(coloredStream, formatter.F(color+\"\\nDone.  Resuming watch...{{/}}\"))\n\n\t\t\tmessages, err := internal.FinalizeProfilesAndReportsForSuites(suites, w.cliConfig, w.suiteConfig, w.reporterConfig, w.goFlagsConfig)\n\t\t\tcommand.AbortIfError(\"could not finalize profiles:\", err)\n\t\t\tfor _, message := range messages {\n\t\t\t\tfmt.Println(message)\n\t\t\t}\n\t\tcase <-w.interruptHandler.Status().Channel:\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (w *SpecWatcher) compileAndRun(suite internal.TestSuite, additionalArgs []string) internal.TestSuite {\n\tsuite = internal.CompileSuite(suite, w.goFlagsConfig, false)\n\tif suite.State.Is(internal.TestSuiteStateFailedToCompile) {\n\t\tfmt.Println(suite.CompilationError.Error())\n\t\treturn suite\n\t}\n\tif w.interruptHandler.Status().Interrupted() {\n\t\treturn suite\n\t}\n\tsuite = internal.RunCompiledSuite(suite, w.suiteConfig, w.reporterConfig, w.cliConfig, w.goFlagsConfig, additionalArgs)\n\tinternal.Cleanup(w.goFlagsConfig, suite)\n\treturn suite\n}\n\nfunc (w *SpecWatcher) computeSuccinctMode(numSuites int) {\n\tif w.reporterConfig.Verbosity().GTE(types.VerbosityLevelVerbose) {\n\t\tw.reporterConfig.Succinct = false\n\t\treturn\n\t}\n\n\tif w.flags.WasSet(\"succinct\") {\n\t\treturn\n\t}\n\n\tif numSuites == 1 {\n\t\tw.reporterConfig.Succinct = false\n\t}\n\n\tif numSuites > 1 {\n\t\tw.reporterConfig.Succinct = true\n\t}\n}\n\nfunc (w *SpecWatcher) updateSeed() {\n\tif !w.flags.WasSet(\"seed\") {\n\t\tw.suiteConfig.RandomSeed = time.Now().Unix()\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/interrupt_handler.go",
    "content": "package interrupt_handler\n\nimport (\n\t\"os\"\n\t\"os/signal\"\n\t\"sync\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/onsi/ginkgo/v2/internal/parallel_support\"\n)\n\nvar ABORT_POLLING_INTERVAL = 500 * time.Millisecond\n\ntype InterruptCause uint\n\nconst (\n\tInterruptCauseInvalid InterruptCause = iota\n\tInterruptCauseSignal\n\tInterruptCauseAbortByOtherProcess\n)\n\ntype InterruptLevel uint\n\nconst (\n\tInterruptLevelUninterrupted InterruptLevel = iota\n\tInterruptLevelCleanupAndReport\n\tInterruptLevelReportOnly\n\tInterruptLevelBailOut\n)\n\nfunc (ic InterruptCause) String() string {\n\tswitch ic {\n\tcase InterruptCauseSignal:\n\t\treturn \"Interrupted by User\"\n\tcase InterruptCauseAbortByOtherProcess:\n\t\treturn \"Interrupted by Other Ginkgo Process\"\n\t}\n\treturn \"INVALID_INTERRUPT_CAUSE\"\n}\n\ntype InterruptStatus struct {\n\tChannel chan any\n\tLevel   InterruptLevel\n\tCause   InterruptCause\n}\n\nfunc (s InterruptStatus) Interrupted() bool {\n\treturn s.Level != InterruptLevelUninterrupted\n}\n\nfunc (s InterruptStatus) Message() string {\n\treturn s.Cause.String()\n}\n\nfunc (s InterruptStatus) ShouldIncludeProgressReport() bool {\n\treturn s.Cause != InterruptCauseAbortByOtherProcess\n}\n\ntype InterruptHandlerInterface interface {\n\tStatus() InterruptStatus\n}\n\ntype InterruptHandler struct {\n\tc                 chan any\n\tlock              *sync.Mutex\n\tlevel             InterruptLevel\n\tcause             InterruptCause\n\tclient            parallel_support.Client\n\tstop              chan any\n\tsignals           []os.Signal\n\trequestAbortCheck chan any\n}\n\nfunc NewInterruptHandler(client parallel_support.Client, signals ...os.Signal) *InterruptHandler {\n\tif len(signals) == 0 {\n\t\tsignals = []os.Signal{os.Interrupt, syscall.SIGTERM}\n\t}\n\thandler := &InterruptHandler{\n\t\tc:                 make(chan any),\n\t\tlock:              &sync.Mutex{},\n\t\tstop:              make(chan any),\n\t\trequestAbortCheck: make(chan any),\n\t\tclient:            client,\n\t\tsignals:           signals,\n\t}\n\thandler.registerForInterrupts()\n\treturn handler\n}\n\nfunc (handler *InterruptHandler) Stop() {\n\tclose(handler.stop)\n}\n\nfunc (handler *InterruptHandler) registerForInterrupts() {\n\t// os signal handling\n\tsignalChannel := make(chan os.Signal, 1)\n\tsignal.Notify(signalChannel, handler.signals...)\n\n\t// cross-process abort handling\n\tvar abortChannel chan any\n\tif handler.client != nil {\n\t\tabortChannel = make(chan any)\n\t\tgo func() {\n\t\t\tpollTicker := time.NewTicker(ABORT_POLLING_INTERVAL)\n\t\t\tfor {\n\t\t\t\tselect {\n\t\t\t\tcase <-pollTicker.C:\n\t\t\t\t\tif handler.client.ShouldAbort() {\n\t\t\t\t\t\tclose(abortChannel)\n\t\t\t\t\t\tpollTicker.Stop()\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\tcase <-handler.requestAbortCheck:\n\t\t\t\t\tif handler.client.ShouldAbort() {\n\t\t\t\t\t\tclose(abortChannel)\n\t\t\t\t\t\tpollTicker.Stop()\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\tcase <-handler.stop:\n\t\t\t\t\tpollTicker.Stop()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\t}\n\n\tgo func(abortChannel chan any) {\n\t\tvar interruptCause InterruptCause\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-signalChannel:\n\t\t\t\tinterruptCause = InterruptCauseSignal\n\t\t\tcase <-abortChannel:\n\t\t\t\tinterruptCause = InterruptCauseAbortByOtherProcess\n\t\t\tcase <-handler.stop:\n\t\t\t\tsignal.Stop(signalChannel)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tabortChannel = nil\n\n\t\t\thandler.lock.Lock()\n\t\t\toldLevel := handler.level\n\t\t\thandler.cause = interruptCause\n\t\t\tif handler.level == InterruptLevelUninterrupted {\n\t\t\t\thandler.level = InterruptLevelCleanupAndReport\n\t\t\t} else if handler.level == InterruptLevelCleanupAndReport {\n\t\t\t\thandler.level = InterruptLevelReportOnly\n\t\t\t} else if handler.level == InterruptLevelReportOnly {\n\t\t\t\thandler.level = InterruptLevelBailOut\n\t\t\t}\n\t\t\tif handler.level != oldLevel {\n\t\t\t\tclose(handler.c)\n\t\t\t\thandler.c = make(chan any)\n\t\t\t}\n\t\t\thandler.lock.Unlock()\n\t\t}\n\t}(abortChannel)\n}\n\nfunc (handler *InterruptHandler) Status() InterruptStatus {\n\thandler.lock.Lock()\n\tstatus := InterruptStatus{\n\t\tLevel:   handler.level,\n\t\tChannel: handler.c,\n\t\tCause:   handler.cause,\n\t}\n\thandler.lock.Unlock()\n\n\tif handler.client != nil && handler.client.ShouldAbort() && !status.Interrupted() {\n\t\tclose(handler.requestAbortCheck)\n\t\t<-status.Channel\n\t\treturn handler.Status()\n\t}\n\n\treturn status\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/sigquit_swallower_unix.go",
    "content": "//go:build freebsd || openbsd || netbsd || dragonfly || darwin || linux || solaris\n// +build freebsd openbsd netbsd dragonfly darwin linux solaris\n\npackage interrupt_handler\n\nimport (\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n)\n\nfunc SwallowSigQuit() {\n\tc := make(chan os.Signal, 1024)\n\tsignal.Notify(c, syscall.SIGQUIT)\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/internal/interrupt_handler/sigquit_swallower_windows.go",
    "content": "//go:build windows\n// +build windows\n\npackage interrupt_handler\n\nfunc SwallowSigQuit() {\n\t//noop\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/client_server.go",
    "content": "package parallel_support\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/onsi/ginkgo/v2/reporters\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\ntype BeforeSuiteState struct {\n\tData  []byte\n\tState types.SpecState\n}\n\ntype ParallelIndexCounter struct {\n\tIndex int\n}\n\nvar ErrorGone = fmt.Errorf(\"gone\")\nvar ErrorFailed = fmt.Errorf(\"failed\")\nvar ErrorEarly = fmt.Errorf(\"early\")\n\nvar POLLING_INTERVAL = 50 * time.Millisecond\n\ntype Server interface {\n\tStart()\n\tClose()\n\tAddress() string\n\tRegisterAlive(node int, alive func() bool)\n\tGetSuiteDone() chan any\n\tGetOutputDestination() io.Writer\n\tSetOutputDestination(io.Writer)\n}\n\ntype Client interface {\n\tConnect() bool\n\tClose() error\n\n\tPostSuiteWillBegin(report types.Report) error\n\tPostDidRun(report types.SpecReport) error\n\tPostSuiteDidEnd(report types.Report) error\n\tPostReportBeforeSuiteCompleted(state types.SpecState) error\n\tBlockUntilReportBeforeSuiteCompleted() (types.SpecState, error)\n\tPostSynchronizedBeforeSuiteCompleted(state types.SpecState, data []byte) error\n\tBlockUntilSynchronizedBeforeSuiteData() (types.SpecState, []byte, error)\n\tBlockUntilNonprimaryProcsHaveFinished() error\n\tBlockUntilAggregatedNonprimaryProcsReport() (types.Report, error)\n\tFetchNextCounter() (int, error)\n\tPostAbort() error\n\tShouldAbort() bool\n\tPostEmitProgressReport(report types.ProgressReport) error\n\tWrite(p []byte) (int, error)\n}\n\nfunc NewServer(parallelTotal int, reporter reporters.Reporter) (Server, error) {\n\tif os.Getenv(\"GINKGO_PARALLEL_PROTOCOL\") == \"HTTP\" {\n\t\treturn newHttpServer(parallelTotal, reporter)\n\t} else {\n\t\treturn newRPCServer(parallelTotal, reporter)\n\t}\n}\n\nfunc NewClient(serverHost string) Client {\n\tif os.Getenv(\"GINKGO_PARALLEL_PROTOCOL\") == \"HTTP\" {\n\t\treturn newHttpClient(serverHost)\n\t} else {\n\t\treturn newRPCClient(serverHost)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_client.go",
    "content": "package parallel_support\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\ntype httpClient struct {\n\tserverHost string\n}\n\nfunc newHttpClient(serverHost string) *httpClient {\n\treturn &httpClient{\n\t\tserverHost: serverHost,\n\t}\n}\n\nfunc (client *httpClient) Connect() bool {\n\tresp, err := http.Get(client.serverHost + \"/up\")\n\tif err != nil {\n\t\treturn false\n\t}\n\tresp.Body.Close()\n\treturn resp.StatusCode == http.StatusOK\n}\n\nfunc (client *httpClient) Close() error {\n\treturn nil\n}\n\nfunc (client *httpClient) post(path string, data any) error {\n\tvar body io.Reader\n\tif data != nil {\n\t\tencoded, err := json.Marshal(data)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tbody = bytes.NewBuffer(encoded)\n\t}\n\tresp, err := http.Post(client.serverHost+path, \"application/json\", body)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"received unexpected status code %d\", resp.StatusCode)\n\t}\n\treturn nil\n}\n\nfunc (client *httpClient) poll(path string, data any) error {\n\tfor {\n\t\tresp, err := http.Get(client.serverHost + path)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif resp.StatusCode == http.StatusTooEarly {\n\t\t\tresp.Body.Close()\n\t\t\ttime.Sleep(POLLING_INTERVAL)\n\t\t\tcontinue\n\t\t}\n\t\tdefer resp.Body.Close()\n\t\tif resp.StatusCode == http.StatusGone {\n\t\t\treturn ErrorGone\n\t\t}\n\t\tif resp.StatusCode == http.StatusFailedDependency {\n\t\t\treturn ErrorFailed\n\t\t}\n\t\tif resp.StatusCode != http.StatusOK {\n\t\t\treturn fmt.Errorf(\"received unexpected status code %d\", resp.StatusCode)\n\t\t}\n\t\tif data != nil {\n\t\t\treturn json.NewDecoder(resp.Body).Decode(data)\n\t\t}\n\t\treturn nil\n\t}\n}\n\nfunc (client *httpClient) PostSuiteWillBegin(report types.Report) error {\n\treturn client.post(\"/suite-will-begin\", report)\n}\n\nfunc (client *httpClient) PostDidRun(report types.SpecReport) error {\n\treturn client.post(\"/did-run\", report)\n}\n\nfunc (client *httpClient) PostSuiteDidEnd(report types.Report) error {\n\treturn client.post(\"/suite-did-end\", report)\n}\n\nfunc (client *httpClient) PostEmitProgressReport(report types.ProgressReport) error {\n\treturn client.post(\"/progress-report\", report)\n}\n\nfunc (client *httpClient) PostReportBeforeSuiteCompleted(state types.SpecState) error {\n\treturn client.post(\"/report-before-suite-completed\", state)\n}\n\nfunc (client *httpClient) BlockUntilReportBeforeSuiteCompleted() (types.SpecState, error) {\n\tvar state types.SpecState\n\terr := client.poll(\"/report-before-suite-state\", &state)\n\tif err == ErrorGone {\n\t\treturn types.SpecStateFailed, nil\n\t}\n\treturn state, err\n}\n\nfunc (client *httpClient) PostSynchronizedBeforeSuiteCompleted(state types.SpecState, data []byte) error {\n\tbeforeSuiteState := BeforeSuiteState{\n\t\tState: state,\n\t\tData:  data,\n\t}\n\treturn client.post(\"/before-suite-completed\", beforeSuiteState)\n}\n\nfunc (client *httpClient) BlockUntilSynchronizedBeforeSuiteData() (types.SpecState, []byte, error) {\n\tvar beforeSuiteState BeforeSuiteState\n\terr := client.poll(\"/before-suite-state\", &beforeSuiteState)\n\tif err == ErrorGone {\n\t\treturn types.SpecStateInvalid, nil, types.GinkgoErrors.SynchronizedBeforeSuiteDisappearedOnProc1()\n\t}\n\treturn beforeSuiteState.State, beforeSuiteState.Data, err\n}\n\nfunc (client *httpClient) BlockUntilNonprimaryProcsHaveFinished() error {\n\treturn client.poll(\"/have-nonprimary-procs-finished\", nil)\n}\n\nfunc (client *httpClient) BlockUntilAggregatedNonprimaryProcsReport() (types.Report, error) {\n\tvar report types.Report\n\terr := client.poll(\"/aggregated-nonprimary-procs-report\", &report)\n\tif err == ErrorGone {\n\t\treturn types.Report{}, types.GinkgoErrors.AggregatedReportUnavailableDueToNodeDisappearing()\n\t}\n\treturn report, err\n}\n\nfunc (client *httpClient) FetchNextCounter() (int, error) {\n\tvar counter ParallelIndexCounter\n\terr := client.poll(\"/counter\", &counter)\n\treturn counter.Index, err\n}\n\nfunc (client *httpClient) PostAbort() error {\n\treturn client.post(\"/abort\", nil)\n}\n\nfunc (client *httpClient) ShouldAbort() bool {\n\terr := client.poll(\"/abort\", nil)\n\treturn err == ErrorGone\n}\n\nfunc (client *httpClient) Write(p []byte) (int, error) {\n\tresp, err := http.Post(client.serverHost+\"/emit-output\", \"text/plain;charset=UTF-8 \", bytes.NewReader(p))\n\tresp.Body.Close()\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn 0, fmt.Errorf(\"failed to emit output\")\n\t}\n\treturn len(p), err\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/http_server.go",
    "content": "/*\n\nThe remote package provides the pieces to allow Ginkgo test suites to report to remote listeners.\nThis is used, primarily, to enable streaming parallel test output but has, in principal, broader applications (e.g. streaming test output to a browser).\n\n*/\n\npackage parallel_support\n\nimport (\n\t\"encoding/json\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\n\t\"github.com/onsi/ginkgo/v2/reporters\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\n/*\nhttpServer spins up on an automatically selected port and listens for communication from the forwarding reporter.\nIt then forwards that communication to attached reporters.\n*/\ntype httpServer struct {\n\tlistener net.Listener\n\thandler  *ServerHandler\n}\n\n// Create a new server, automatically selecting a port\nfunc newHttpServer(parallelTotal int, reporter reporters.Reporter) (*httpServer, error) {\n\tlistener, err := net.Listen(\"tcp\", \"127.0.0.1:0\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &httpServer{\n\t\tlistener: listener,\n\t\thandler:  newServerHandler(parallelTotal, reporter),\n\t}, nil\n}\n\n// Start the server.  You don't need to `go s.Start()`, just `s.Start()`\nfunc (server *httpServer) Start() {\n\thttpServer := &http.Server{}\n\tmux := http.NewServeMux()\n\thttpServer.Handler = mux\n\n\t//streaming endpoints\n\tmux.HandleFunc(\"/suite-will-begin\", server.specSuiteWillBegin)\n\tmux.HandleFunc(\"/did-run\", server.didRun)\n\tmux.HandleFunc(\"/suite-did-end\", server.specSuiteDidEnd)\n\tmux.HandleFunc(\"/emit-output\", server.emitOutput)\n\tmux.HandleFunc(\"/progress-report\", server.emitProgressReport)\n\n\t//synchronization endpoints\n\tmux.HandleFunc(\"/report-before-suite-completed\", server.handleReportBeforeSuiteCompleted)\n\tmux.HandleFunc(\"/report-before-suite-state\", server.handleReportBeforeSuiteState)\n\tmux.HandleFunc(\"/before-suite-completed\", server.handleBeforeSuiteCompleted)\n\tmux.HandleFunc(\"/before-suite-state\", server.handleBeforeSuiteState)\n\tmux.HandleFunc(\"/have-nonprimary-procs-finished\", server.handleHaveNonprimaryProcsFinished)\n\tmux.HandleFunc(\"/aggregated-nonprimary-procs-report\", server.handleAggregatedNonprimaryProcsReport)\n\tmux.HandleFunc(\"/counter\", server.handleCounter)\n\tmux.HandleFunc(\"/up\", server.handleUp)\n\tmux.HandleFunc(\"/abort\", server.handleAbort)\n\n\tgo httpServer.Serve(server.listener)\n}\n\n// Stop the server\nfunc (server *httpServer) Close() {\n\tserver.listener.Close()\n}\n\n// The address the server can be reached it.  Pass this into the `ForwardingReporter`.\nfunc (server *httpServer) Address() string {\n\treturn \"http://\" + server.listener.Addr().String()\n}\n\nfunc (server *httpServer) GetSuiteDone() chan any {\n\treturn server.handler.done\n}\n\nfunc (server *httpServer) GetOutputDestination() io.Writer {\n\treturn server.handler.outputDestination\n}\n\nfunc (server *httpServer) SetOutputDestination(w io.Writer) {\n\tserver.handler.outputDestination = w\n}\n\nfunc (server *httpServer) RegisterAlive(node int, alive func() bool) {\n\tserver.handler.registerAlive(node, alive)\n}\n\n//\n// Streaming Endpoints\n//\n\n// The server will forward all received messages to Ginkgo reporters registered with `RegisterReporters`\nfunc (server *httpServer) decode(writer http.ResponseWriter, request *http.Request, object any) bool {\n\tdefer request.Body.Close()\n\tif json.NewDecoder(request.Body).Decode(object) != nil {\n\t\twriter.WriteHeader(http.StatusBadRequest)\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (server *httpServer) handleError(err error, writer http.ResponseWriter) bool {\n\tif err == nil {\n\t\treturn false\n\t}\n\tswitch err {\n\tcase ErrorEarly:\n\t\twriter.WriteHeader(http.StatusTooEarly)\n\tcase ErrorGone:\n\t\twriter.WriteHeader(http.StatusGone)\n\tcase ErrorFailed:\n\t\twriter.WriteHeader(http.StatusFailedDependency)\n\tdefault:\n\t\twriter.WriteHeader(http.StatusInternalServerError)\n\t}\n\treturn true\n}\n\nfunc (server *httpServer) specSuiteWillBegin(writer http.ResponseWriter, request *http.Request) {\n\tvar report types.Report\n\tif !server.decode(writer, request, &report) {\n\t\treturn\n\t}\n\n\tserver.handleError(server.handler.SpecSuiteWillBegin(report, voidReceiver), writer)\n}\n\nfunc (server *httpServer) didRun(writer http.ResponseWriter, request *http.Request) {\n\tvar report types.SpecReport\n\tif !server.decode(writer, request, &report) {\n\t\treturn\n\t}\n\n\tserver.handleError(server.handler.DidRun(report, voidReceiver), writer)\n}\n\nfunc (server *httpServer) specSuiteDidEnd(writer http.ResponseWriter, request *http.Request) {\n\tvar report types.Report\n\tif !server.decode(writer, request, &report) {\n\t\treturn\n\t}\n\tserver.handleError(server.handler.SpecSuiteDidEnd(report, voidReceiver), writer)\n}\n\nfunc (server *httpServer) emitOutput(writer http.ResponseWriter, request *http.Request) {\n\toutput, err := io.ReadAll(request.Body)\n\tif err != nil {\n\t\twriter.WriteHeader(http.StatusInternalServerError)\n\t\treturn\n\t}\n\tvar n int\n\tserver.handleError(server.handler.EmitOutput(output, &n), writer)\n}\n\nfunc (server *httpServer) emitProgressReport(writer http.ResponseWriter, request *http.Request) {\n\tvar report types.ProgressReport\n\tif !server.decode(writer, request, &report) {\n\t\treturn\n\t}\n\tserver.handleError(server.handler.EmitProgressReport(report, voidReceiver), writer)\n}\n\nfunc (server *httpServer) handleReportBeforeSuiteCompleted(writer http.ResponseWriter, request *http.Request) {\n\tvar state types.SpecState\n\tif !server.decode(writer, request, &state) {\n\t\treturn\n\t}\n\n\tserver.handleError(server.handler.ReportBeforeSuiteCompleted(state, voidReceiver), writer)\n}\n\nfunc (server *httpServer) handleReportBeforeSuiteState(writer http.ResponseWriter, request *http.Request) {\n\tvar state types.SpecState\n\tif server.handleError(server.handler.ReportBeforeSuiteState(voidSender, &state), writer) {\n\t\treturn\n\t}\n\tjson.NewEncoder(writer).Encode(state)\n}\n\nfunc (server *httpServer) handleBeforeSuiteCompleted(writer http.ResponseWriter, request *http.Request) {\n\tvar beforeSuiteState BeforeSuiteState\n\tif !server.decode(writer, request, &beforeSuiteState) {\n\t\treturn\n\t}\n\n\tserver.handleError(server.handler.BeforeSuiteCompleted(beforeSuiteState, voidReceiver), writer)\n}\n\nfunc (server *httpServer) handleBeforeSuiteState(writer http.ResponseWriter, request *http.Request) {\n\tvar beforeSuiteState BeforeSuiteState\n\tif server.handleError(server.handler.BeforeSuiteState(voidSender, &beforeSuiteState), writer) {\n\t\treturn\n\t}\n\tjson.NewEncoder(writer).Encode(beforeSuiteState)\n}\n\nfunc (server *httpServer) handleHaveNonprimaryProcsFinished(writer http.ResponseWriter, request *http.Request) {\n\tif server.handleError(server.handler.HaveNonprimaryProcsFinished(voidSender, voidReceiver), writer) {\n\t\treturn\n\t}\n\twriter.WriteHeader(http.StatusOK)\n}\n\nfunc (server *httpServer) handleAggregatedNonprimaryProcsReport(writer http.ResponseWriter, request *http.Request) {\n\tvar aggregatedReport types.Report\n\tif server.handleError(server.handler.AggregatedNonprimaryProcsReport(voidSender, &aggregatedReport), writer) {\n\t\treturn\n\t}\n\tjson.NewEncoder(writer).Encode(aggregatedReport)\n}\n\nfunc (server *httpServer) handleCounter(writer http.ResponseWriter, request *http.Request) {\n\tvar n int\n\tif server.handleError(server.handler.Counter(voidSender, &n), writer) {\n\t\treturn\n\t}\n\tjson.NewEncoder(writer).Encode(ParallelIndexCounter{Index: n})\n}\n\nfunc (server *httpServer) handleUp(writer http.ResponseWriter, request *http.Request) {\n\twriter.WriteHeader(http.StatusOK)\n}\n\nfunc (server *httpServer) handleAbort(writer http.ResponseWriter, request *http.Request) {\n\tif request.Method == \"GET\" {\n\t\tvar shouldAbort bool\n\t\tserver.handler.ShouldAbort(voidSender, &shouldAbort)\n\t\tif shouldAbort {\n\t\t\twriter.WriteHeader(http.StatusGone)\n\t\t} else {\n\t\t\twriter.WriteHeader(http.StatusOK)\n\t\t}\n\t} else {\n\t\tserver.handler.Abort(voidSender, voidReceiver)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_client.go",
    "content": "package parallel_support\n\nimport (\n\t\"net/rpc\"\n\t\"time\"\n\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\ntype rpcClient struct {\n\tserverHost string\n\tclient     *rpc.Client\n}\n\nfunc newRPCClient(serverHost string) *rpcClient {\n\treturn &rpcClient{\n\t\tserverHost: serverHost,\n\t}\n}\n\nfunc (client *rpcClient) Connect() bool {\n\tvar err error\n\tif client.client != nil {\n\t\treturn true\n\t}\n\tclient.client, err = rpc.DialHTTPPath(\"tcp\", client.serverHost, \"/\")\n\tif err != nil {\n\t\tclient.client = nil\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (client *rpcClient) Close() error {\n\treturn client.client.Close()\n}\n\nfunc (client *rpcClient) poll(method string, data any) error {\n\tfor {\n\t\terr := client.client.Call(method, voidSender, data)\n\t\tif err == nil {\n\t\t\treturn nil\n\t\t}\n\t\tswitch err.Error() {\n\t\tcase ErrorEarly.Error():\n\t\t\ttime.Sleep(POLLING_INTERVAL)\n\t\tcase ErrorGone.Error():\n\t\t\treturn ErrorGone\n\t\tcase ErrorFailed.Error():\n\t\t\treturn ErrorFailed\n\t\tdefault:\n\t\t\treturn err\n\t\t}\n\t}\n}\n\nfunc (client *rpcClient) PostSuiteWillBegin(report types.Report) error {\n\treturn client.client.Call(\"Server.SpecSuiteWillBegin\", report, voidReceiver)\n}\n\nfunc (client *rpcClient) PostDidRun(report types.SpecReport) error {\n\treturn client.client.Call(\"Server.DidRun\", report, voidReceiver)\n}\n\nfunc (client *rpcClient) PostSuiteDidEnd(report types.Report) error {\n\treturn client.client.Call(\"Server.SpecSuiteDidEnd\", report, voidReceiver)\n}\n\nfunc (client *rpcClient) Write(p []byte) (int, error) {\n\tvar n int\n\terr := client.client.Call(\"Server.EmitOutput\", p, &n)\n\treturn n, err\n}\n\nfunc (client *rpcClient) PostEmitProgressReport(report types.ProgressReport) error {\n\treturn client.client.Call(\"Server.EmitProgressReport\", report, voidReceiver)\n}\n\nfunc (client *rpcClient) PostReportBeforeSuiteCompleted(state types.SpecState) error {\n\treturn client.client.Call(\"Server.ReportBeforeSuiteCompleted\", state, voidReceiver)\n}\n\nfunc (client *rpcClient) BlockUntilReportBeforeSuiteCompleted() (types.SpecState, error) {\n\tvar state types.SpecState\n\terr := client.poll(\"Server.ReportBeforeSuiteState\", &state)\n\tif err == ErrorGone {\n\t\treturn types.SpecStateFailed, nil\n\t}\n\treturn state, err\n}\n\nfunc (client *rpcClient) PostSynchronizedBeforeSuiteCompleted(state types.SpecState, data []byte) error {\n\tbeforeSuiteState := BeforeSuiteState{\n\t\tState: state,\n\t\tData:  data,\n\t}\n\treturn client.client.Call(\"Server.BeforeSuiteCompleted\", beforeSuiteState, voidReceiver)\n}\n\nfunc (client *rpcClient) BlockUntilSynchronizedBeforeSuiteData() (types.SpecState, []byte, error) {\n\tvar beforeSuiteState BeforeSuiteState\n\terr := client.poll(\"Server.BeforeSuiteState\", &beforeSuiteState)\n\tif err == ErrorGone {\n\t\treturn types.SpecStateInvalid, nil, types.GinkgoErrors.SynchronizedBeforeSuiteDisappearedOnProc1()\n\t}\n\treturn beforeSuiteState.State, beforeSuiteState.Data, err\n}\n\nfunc (client *rpcClient) BlockUntilNonprimaryProcsHaveFinished() error {\n\treturn client.poll(\"Server.HaveNonprimaryProcsFinished\", voidReceiver)\n}\n\nfunc (client *rpcClient) BlockUntilAggregatedNonprimaryProcsReport() (types.Report, error) {\n\tvar report types.Report\n\terr := client.poll(\"Server.AggregatedNonprimaryProcsReport\", &report)\n\tif err == ErrorGone {\n\t\treturn types.Report{}, types.GinkgoErrors.AggregatedReportUnavailableDueToNodeDisappearing()\n\t}\n\treturn report, err\n}\n\nfunc (client *rpcClient) FetchNextCounter() (int, error) {\n\tvar counter int\n\terr := client.client.Call(\"Server.Counter\", voidSender, &counter)\n\treturn counter, err\n}\n\nfunc (client *rpcClient) PostAbort() error {\n\treturn client.client.Call(\"Server.Abort\", voidSender, voidReceiver)\n}\n\nfunc (client *rpcClient) ShouldAbort() bool {\n\tvar shouldAbort bool\n\tclient.client.Call(\"Server.ShouldAbort\", voidSender, &shouldAbort)\n\treturn shouldAbort\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/rpc_server.go",
    "content": "/*\n\nThe remote package provides the pieces to allow Ginkgo test suites to report to remote listeners.\nThis is used, primarily, to enable streaming parallel test output but has, in principal, broader applications (e.g. streaming test output to a browser).\n\n*/\n\npackage parallel_support\n\nimport (\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/rpc\"\n\n\t\"github.com/onsi/ginkgo/v2/reporters\"\n)\n\n/*\nRPCServer spins up on an automatically selected port and listens for communication from the forwarding reporter.\nIt then forwards that communication to attached reporters.\n*/\ntype RPCServer struct {\n\tlistener net.Listener\n\thandler  *ServerHandler\n}\n\n// Create a new server, automatically selecting a port\nfunc newRPCServer(parallelTotal int, reporter reporters.Reporter) (*RPCServer, error) {\n\tlistener, err := net.Listen(\"tcp\", \"127.0.0.1:0\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &RPCServer{\n\t\tlistener: listener,\n\t\thandler:  newServerHandler(parallelTotal, reporter),\n\t}, nil\n}\n\n// Start the server.  You don't need to `go s.Start()`, just `s.Start()`\nfunc (server *RPCServer) Start() {\n\trpcServer := rpc.NewServer()\n\trpcServer.RegisterName(\"Server\", server.handler) //register the handler's methods as the server\n\n\thttpServer := &http.Server{}\n\thttpServer.Handler = rpcServer\n\n\tgo httpServer.Serve(server.listener)\n}\n\n// Stop the server\nfunc (server *RPCServer) Close() {\n\tserver.listener.Close()\n}\n\n// The address the server can be reached it.  Pass this into the `ForwardingReporter`.\nfunc (server *RPCServer) Address() string {\n\treturn server.listener.Addr().String()\n}\n\nfunc (server *RPCServer) GetSuiteDone() chan any {\n\treturn server.handler.done\n}\n\nfunc (server *RPCServer) GetOutputDestination() io.Writer {\n\treturn server.handler.outputDestination\n}\n\nfunc (server *RPCServer) SetOutputDestination(w io.Writer) {\n\tserver.handler.outputDestination = w\n}\n\nfunc (server *RPCServer) RegisterAlive(node int, alive func() bool) {\n\tserver.handler.registerAlive(node, alive)\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/internal/parallel_support/server_handler.go",
    "content": "package parallel_support\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"sync\"\n\n\t\"github.com/onsi/ginkgo/v2/reporters\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\ntype Void struct{}\n\nvar voidReceiver *Void = &Void{}\nvar voidSender Void\n\n// ServerHandler is an RPC-compatible handler that is shared between the http server and the rpc server.\n// It handles all the business logic to avoid duplication between the two servers\n\ntype ServerHandler struct {\n\tdone                   chan any\n\toutputDestination      io.Writer\n\treporter               reporters.Reporter\n\talives                 []func() bool\n\tlock                   *sync.Mutex\n\tbeforeSuiteState       BeforeSuiteState\n\treportBeforeSuiteState types.SpecState\n\tparallelTotal          int\n\tcounter                int\n\tcounterLock            *sync.Mutex\n\tshouldAbort            bool\n\n\tnumSuiteDidBegins int\n\tnumSuiteDidEnds   int\n\taggregatedReport  types.Report\n\treportHoldingArea []types.SpecReport\n}\n\nfunc newServerHandler(parallelTotal int, reporter reporters.Reporter) *ServerHandler {\n\treturn &ServerHandler{\n\t\treporter:         reporter,\n\t\tlock:             &sync.Mutex{},\n\t\tcounterLock:      &sync.Mutex{},\n\t\talives:           make([]func() bool, parallelTotal),\n\t\tbeforeSuiteState: BeforeSuiteState{Data: nil, State: types.SpecStateInvalid},\n\n\t\tparallelTotal:     parallelTotal,\n\t\toutputDestination: os.Stdout,\n\t\tdone:              make(chan any),\n\t}\n}\n\nfunc (handler *ServerHandler) SpecSuiteWillBegin(report types.Report, _ *Void) error {\n\thandler.lock.Lock()\n\tdefer handler.lock.Unlock()\n\n\thandler.numSuiteDidBegins += 1\n\n\t// all summaries are identical, so it's fine to simply emit the last one of these\n\tif handler.numSuiteDidBegins == handler.parallelTotal {\n\t\thandler.reporter.SuiteWillBegin(report)\n\n\t\tfor _, summary := range handler.reportHoldingArea {\n\t\t\thandler.reporter.WillRun(summary)\n\t\t\thandler.reporter.DidRun(summary)\n\t\t}\n\n\t\thandler.reportHoldingArea = nil\n\t}\n\n\treturn nil\n}\n\nfunc (handler *ServerHandler) DidRun(report types.SpecReport, _ *Void) error {\n\thandler.lock.Lock()\n\tdefer handler.lock.Unlock()\n\n\tif handler.numSuiteDidBegins == handler.parallelTotal {\n\t\thandler.reporter.WillRun(report)\n\t\thandler.reporter.DidRun(report)\n\t} else {\n\t\thandler.reportHoldingArea = append(handler.reportHoldingArea, report)\n\t}\n\n\treturn nil\n}\n\nfunc (handler *ServerHandler) SpecSuiteDidEnd(report types.Report, _ *Void) error {\n\thandler.lock.Lock()\n\tdefer handler.lock.Unlock()\n\n\thandler.numSuiteDidEnds += 1\n\tif handler.numSuiteDidEnds == 1 {\n\t\thandler.aggregatedReport = report\n\t} else {\n\t\thandler.aggregatedReport = handler.aggregatedReport.Add(report)\n\t}\n\n\tif handler.numSuiteDidEnds == handler.parallelTotal {\n\t\thandler.reporter.SuiteDidEnd(handler.aggregatedReport)\n\t\tclose(handler.done)\n\t}\n\n\treturn nil\n}\n\nfunc (handler *ServerHandler) EmitOutput(output []byte, n *int) error {\n\tvar err error\n\t*n, err = handler.outputDestination.Write(output)\n\treturn err\n}\n\nfunc (handler *ServerHandler) EmitProgressReport(report types.ProgressReport, _ *Void) error {\n\thandler.lock.Lock()\n\tdefer handler.lock.Unlock()\n\thandler.reporter.EmitProgressReport(report)\n\treturn nil\n}\n\nfunc (handler *ServerHandler) registerAlive(proc int, alive func() bool) {\n\thandler.lock.Lock()\n\tdefer handler.lock.Unlock()\n\thandler.alives[proc-1] = alive\n}\n\nfunc (handler *ServerHandler) procIsAlive(proc int) bool {\n\thandler.lock.Lock()\n\tdefer handler.lock.Unlock()\n\talive := handler.alives[proc-1]\n\tif alive == nil {\n\t\treturn true\n\t}\n\treturn alive()\n}\n\nfunc (handler *ServerHandler) haveNonprimaryProcsFinished() bool {\n\tfor i := 2; i <= handler.parallelTotal; i++ {\n\t\tif handler.procIsAlive(i) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (handler *ServerHandler) ReportBeforeSuiteCompleted(reportBeforeSuiteState types.SpecState, _ *Void) error {\n\thandler.lock.Lock()\n\tdefer handler.lock.Unlock()\n\thandler.reportBeforeSuiteState = reportBeforeSuiteState\n\n\treturn nil\n}\n\nfunc (handler *ServerHandler) ReportBeforeSuiteState(_ Void, reportBeforeSuiteState *types.SpecState) error {\n\tproc1IsAlive := handler.procIsAlive(1)\n\thandler.lock.Lock()\n\tdefer handler.lock.Unlock()\n\tif handler.reportBeforeSuiteState == types.SpecStateInvalid {\n\t\tif proc1IsAlive {\n\t\t\treturn ErrorEarly\n\t\t} else {\n\t\t\treturn ErrorGone\n\t\t}\n\t}\n\t*reportBeforeSuiteState = handler.reportBeforeSuiteState\n\treturn nil\n}\n\nfunc (handler *ServerHandler) BeforeSuiteCompleted(beforeSuiteState BeforeSuiteState, _ *Void) error {\n\thandler.lock.Lock()\n\tdefer handler.lock.Unlock()\n\thandler.beforeSuiteState = beforeSuiteState\n\n\treturn nil\n}\n\nfunc (handler *ServerHandler) BeforeSuiteState(_ Void, beforeSuiteState *BeforeSuiteState) error {\n\tproc1IsAlive := handler.procIsAlive(1)\n\thandler.lock.Lock()\n\tdefer handler.lock.Unlock()\n\tif handler.beforeSuiteState.State == types.SpecStateInvalid {\n\t\tif proc1IsAlive {\n\t\t\treturn ErrorEarly\n\t\t} else {\n\t\t\treturn ErrorGone\n\t\t}\n\t}\n\t*beforeSuiteState = handler.beforeSuiteState\n\treturn nil\n}\n\nfunc (handler *ServerHandler) HaveNonprimaryProcsFinished(_ Void, _ *Void) error {\n\tif handler.haveNonprimaryProcsFinished() {\n\t\treturn nil\n\t} else {\n\t\treturn ErrorEarly\n\t}\n}\n\nfunc (handler *ServerHandler) AggregatedNonprimaryProcsReport(_ Void, report *types.Report) error {\n\tif handler.haveNonprimaryProcsFinished() {\n\t\thandler.lock.Lock()\n\t\tdefer handler.lock.Unlock()\n\t\tif handler.numSuiteDidEnds == handler.parallelTotal-1 {\n\t\t\t*report = handler.aggregatedReport\n\t\t\treturn nil\n\t\t} else {\n\t\t\treturn ErrorGone\n\t\t}\n\t} else {\n\t\treturn ErrorEarly\n\t}\n}\n\nfunc (handler *ServerHandler) Counter(_ Void, counter *int) error {\n\thandler.counterLock.Lock()\n\tdefer handler.counterLock.Unlock()\n\t*counter = handler.counter\n\thandler.counter++\n\treturn nil\n}\n\nfunc (handler *ServerHandler) Abort(_ Void, _ *Void) error {\n\thandler.lock.Lock()\n\tdefer handler.lock.Unlock()\n\thandler.shouldAbort = true\n\treturn nil\n}\n\nfunc (handler *ServerHandler) ShouldAbort(_ Void, shouldAbort *bool) error {\n\thandler.lock.Lock()\n\tdefer handler.lock.Unlock()\n\t*shouldAbort = handler.shouldAbort\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go",
    "content": "/*\nGinkgo's Default Reporter\n\nA number of command line flags are available to tweak Ginkgo's default output.\n\nThese are documented [here](http://onsi.github.io/ginkgo/#running_tests)\n*/\npackage reporters\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"runtime\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/onsi/ginkgo/v2/formatter\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\ntype DefaultReporter struct {\n\tconf   types.ReporterConfig\n\twriter io.Writer\n\n\t// managing the emission stream\n\tlastCharWasNewline       bool\n\tlastEmissionWasDelimiter bool\n\n\t// rendering\n\tspecDenoter  string\n\tretryDenoter string\n\tformatter    formatter.Formatter\n\n\trunningInParallel bool\n\tlock              *sync.Mutex\n}\n\nfunc NewDefaultReporterUnderTest(conf types.ReporterConfig, writer io.Writer) *DefaultReporter {\n\treporter := NewDefaultReporter(conf, writer)\n\treporter.formatter = formatter.New(formatter.ColorModePassthrough)\n\n\treturn reporter\n}\n\nfunc NewDefaultReporter(conf types.ReporterConfig, writer io.Writer) *DefaultReporter {\n\treporter := &DefaultReporter{\n\t\tconf:   conf,\n\t\twriter: writer,\n\n\t\tlastCharWasNewline:       true,\n\t\tlastEmissionWasDelimiter: false,\n\n\t\tspecDenoter:  \"•\",\n\t\tretryDenoter: \"↺\",\n\t\tformatter:    formatter.NewWithNoColorBool(conf.NoColor),\n\t\tlock:         &sync.Mutex{},\n\t}\n\tif runtime.GOOS == \"windows\" {\n\t\treporter.specDenoter = \"+\"\n\t\treporter.retryDenoter = \"R\"\n\t}\n\n\treturn reporter\n}\n\n/* The Reporter Interface */\n\nfunc (r *DefaultReporter) SuiteWillBegin(report types.Report) {\n\tif r.conf.Verbosity().Is(types.VerbosityLevelSuccinct) {\n\t\tr.emit(r.f(\"[%d] {{bold}}%s{{/}} \", report.SuiteConfig.RandomSeed, report.SuiteDescription))\n\t\tif len(report.SuiteLabels) > 0 {\n\t\t\tr.emit(r.f(\"{{coral}}[%s]{{/}} \", strings.Join(report.SuiteLabels, \", \")))\n\t\t}\n\t\tr.emit(r.f(\"- %d/%d specs \", report.PreRunStats.SpecsThatWillRun, report.PreRunStats.TotalSpecs))\n\t\tif report.SuiteConfig.ParallelTotal > 1 {\n\t\t\tr.emit(r.f(\"- %d procs \", report.SuiteConfig.ParallelTotal))\n\t\t}\n\t} else {\n\t\tbanner := r.f(\"Running Suite: %s - %s\", report.SuiteDescription, report.SuitePath)\n\t\tr.emitBlock(banner)\n\t\tbannerWidth := len(banner)\n\t\tif len(report.SuiteLabels) > 0 {\n\t\t\tlabels := strings.Join(report.SuiteLabels, \", \")\n\t\t\tr.emitBlock(r.f(\"{{coral}}[%s]{{/}} \", labels))\n\t\t\tif len(labels)+2 > bannerWidth {\n\t\t\t\tbannerWidth = len(labels) + 2\n\t\t\t}\n\t\t}\n\t\tr.emitBlock(strings.Repeat(\"=\", bannerWidth))\n\n\t\tout := r.f(\"Random Seed: {{bold}}%d{{/}}\", report.SuiteConfig.RandomSeed)\n\t\tif report.SuiteConfig.RandomizeAllSpecs {\n\t\t\tout += r.f(\" - will randomize all specs\")\n\t\t}\n\t\tr.emitBlock(out)\n\t\tr.emit(\"\\n\")\n\t\tr.emitBlock(r.f(\"Will run {{bold}}%d{{/}} of {{bold}}%d{{/}} specs\", report.PreRunStats.SpecsThatWillRun, report.PreRunStats.TotalSpecs))\n\t\tif report.SuiteConfig.ParallelTotal > 1 {\n\t\t\tr.emitBlock(r.f(\"Running in parallel across {{bold}}%d{{/}} processes\", report.SuiteConfig.ParallelTotal))\n\t\t}\n\t}\n}\n\nfunc (r *DefaultReporter) SuiteDidEnd(report types.Report) {\n\tfailures := report.SpecReports.WithState(types.SpecStateFailureStates)\n\tif len(failures) > 0 {\n\t\tr.emitBlock(\"\\n\")\n\t\tif len(failures) > 1 {\n\t\t\tr.emitBlock(r.f(\"{{red}}{{bold}}Summarizing %d Failures:{{/}}\", len(failures)))\n\t\t} else {\n\t\t\tr.emitBlock(r.f(\"{{red}}{{bold}}Summarizing 1 Failure:{{/}}\"))\n\t\t}\n\t\tfor _, specReport := range failures {\n\t\t\thighlightColor, heading := \"{{red}}\", \"[FAIL]\"\n\t\t\tswitch specReport.State {\n\t\t\tcase types.SpecStatePanicked:\n\t\t\t\thighlightColor, heading = \"{{magenta}}\", \"[PANICKED!]\"\n\t\t\tcase types.SpecStateAborted:\n\t\t\t\thighlightColor, heading = \"{{coral}}\", \"[ABORTED]\"\n\t\t\tcase types.SpecStateTimedout:\n\t\t\t\thighlightColor, heading = \"{{orange}}\", \"[TIMEDOUT]\"\n\t\t\tcase types.SpecStateInterrupted:\n\t\t\t\thighlightColor, heading = \"{{orange}}\", \"[INTERRUPTED]\"\n\t\t\t}\n\t\t\tlocationBlock := r.codeLocationBlock(specReport, highlightColor, false, true)\n\t\t\tr.emitBlock(r.fi(1, highlightColor+\"%s{{/}} %s\", heading, locationBlock))\n\t\t}\n\t}\n\n\t//summarize the suite\n\tif r.conf.Verbosity().Is(types.VerbosityLevelSuccinct) && report.SuiteSucceeded {\n\t\tr.emit(r.f(\" {{green}}SUCCESS!{{/}} %s \", report.RunTime))\n\t\treturn\n\t}\n\n\tr.emitBlock(\"\\n\")\n\tcolor, status := \"{{green}}{{bold}}\", \"SUCCESS!\"\n\tif !report.SuiteSucceeded {\n\t\tcolor, status = \"{{red}}{{bold}}\", \"FAIL!\"\n\t}\n\n\tspecs := report.SpecReports.WithLeafNodeType(types.NodeTypeIt) //exclude any suite setup nodes\n\tr.emitBlock(r.f(color+\"Ran %d of %d Specs in %.3f seconds{{/}}\",\n\t\tspecs.CountWithState(types.SpecStatePassed)+specs.CountWithState(types.SpecStateFailureStates),\n\t\treport.PreRunStats.TotalSpecs,\n\t\treport.RunTime.Seconds()),\n\t)\n\n\tswitch len(report.SpecialSuiteFailureReasons) {\n\tcase 0:\n\t\tr.emit(r.f(color+\"%s{{/}} -- \", status))\n\tcase 1:\n\t\tr.emit(r.f(color+\"%s - %s{{/}} -- \", status, report.SpecialSuiteFailureReasons[0]))\n\tdefault:\n\t\tr.emitBlock(r.f(color+\"%s - %s{{/}}\\n\", status, strings.Join(report.SpecialSuiteFailureReasons, \", \")))\n\t}\n\n\tif len(specs) == 0 && report.SpecReports.WithLeafNodeType(types.NodeTypeBeforeSuite|types.NodeTypeSynchronizedBeforeSuite).CountWithState(types.SpecStateFailureStates) > 0 {\n\t\tr.emit(r.f(\"{{cyan}}{{bold}}A BeforeSuite node failed so all tests were skipped.{{/}}\\n\"))\n\t} else {\n\t\tr.emit(r.f(\"{{green}}{{bold}}%d Passed{{/}} | \", specs.CountWithState(types.SpecStatePassed)))\n\t\tr.emit(r.f(\"{{red}}{{bold}}%d Failed{{/}} | \", specs.CountWithState(types.SpecStateFailureStates)))\n\t\tif specs.CountOfFlakedSpecs() > 0 {\n\t\t\tr.emit(r.f(\"{{light-yellow}}{{bold}}%d Flaked{{/}} | \", specs.CountOfFlakedSpecs()))\n\t\t}\n\t\tif specs.CountOfRepeatedSpecs() > 0 {\n\t\t\tr.emit(r.f(\"{{light-yellow}}{{bold}}%d Repeated{{/}} | \", specs.CountOfRepeatedSpecs()))\n\t\t}\n\t\tr.emit(r.f(\"{{yellow}}{{bold}}%d Pending{{/}} | \", specs.CountWithState(types.SpecStatePending)))\n\t\tr.emit(r.f(\"{{cyan}}{{bold}}%d Skipped{{/}}\\n\", specs.CountWithState(types.SpecStateSkipped)))\n\t}\n}\n\nfunc (r *DefaultReporter) WillRun(report types.SpecReport) {\n\tv := r.conf.Verbosity()\n\tif v.LT(types.VerbosityLevelVerbose) || report.State.Is(types.SpecStatePending|types.SpecStateSkipped) || report.RunningInParallel {\n\t\treturn\n\t}\n\n\tr.emitDelimiter(0)\n\tr.emitBlock(r.f(r.codeLocationBlock(report, \"{{/}}\", v.Is(types.VerbosityLevelVeryVerbose), false)))\n}\n\nfunc (r *DefaultReporter) wrapTextBlock(sectionName string, fn func()) {\n\tr.emitBlock(\"\\n\")\n\tif r.conf.GithubOutput {\n\t\tr.emitBlock(r.fi(1, \"::group::%s\", sectionName))\n\t} else {\n\t\tr.emitBlock(r.fi(1, \"{{gray}}%s >>{{/}}\", sectionName))\n\t}\n\tfn()\n\tif r.conf.GithubOutput {\n\t\tr.emitBlock(r.fi(1, \"::endgroup::\"))\n\t} else {\n\t\tr.emitBlock(r.fi(1, \"{{gray}}<< %s{{/}}\", sectionName))\n\t}\n\n}\n\nfunc (r *DefaultReporter) DidRun(report types.SpecReport) {\n\tv := r.conf.Verbosity()\n\tinParallel := report.RunningInParallel\n\n\t//should we completely omit this spec?\n\tif report.State.Is(types.SpecStateSkipped) && r.conf.SilenceSkips {\n\t\treturn\n\t}\n\n\theader := r.specDenoter\n\tif report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {\n\t\theader = fmt.Sprintf(\"[%s]\", report.LeafNodeType)\n\t}\n\thighlightColor := r.highlightColorForState(report.State)\n\n\t// have we already been streaming the timeline?\n\ttimelineHasBeenStreaming := v.GTE(types.VerbosityLevelVerbose) && !inParallel\n\n\t// should we show the timeline?\n\tvar timeline types.Timeline\n\tshowTimeline := !timelineHasBeenStreaming && (v.GTE(types.VerbosityLevelVerbose) || report.Failed())\n\tif showTimeline {\n\t\ttimeline = report.Timeline().WithoutHiddenReportEntries()\n\t\tkeepVeryVerboseSpecEvents := v.Is(types.VerbosityLevelVeryVerbose) ||\n\t\t\t(v.Is(types.VerbosityLevelVerbose) && r.conf.ShowNodeEvents) ||\n\t\t\t(report.Failed() && r.conf.ShowNodeEvents)\n\t\tif !keepVeryVerboseSpecEvents {\n\t\t\ttimeline = timeline.WithoutVeryVerboseSpecEvents()\n\t\t}\n\t\tif len(timeline) == 0 && report.CapturedGinkgoWriterOutput == \"\" {\n\t\t\t// the timeline is completely empty - don't show it\n\t\t\tshowTimeline = false\n\t\t}\n\t\tif v.LT(types.VerbosityLevelVeryVerbose) && report.CapturedGinkgoWriterOutput == \"\" && len(timeline) > 0 {\n\t\t\t//if we aren't -vv and the timeline only has a single failure, don't show it as it will appear at the end of the report\n\t\t\tfailure, isFailure := timeline[0].(types.Failure)\n\t\t\tif isFailure && (len(timeline) == 1 || (len(timeline) == 2 && failure.AdditionalFailure != nil)) {\n\t\t\t\tshowTimeline = false\n\t\t\t}\n\t\t}\n\t}\n\n\t// should we have a separate section for always-visible reports?\n\tshowSeparateVisibilityAlwaysReportsSection := !timelineHasBeenStreaming && !showTimeline && report.ReportEntries.HasVisibility(types.ReportEntryVisibilityAlways)\n\n\t// should we have a separate section for captured stdout/stderr\n\tshowSeparateStdSection := inParallel && (report.CapturedStdOutErr != \"\")\n\n\t// given all that - do we have any actual content to show? or are we a single denoter in a stream?\n\treportHasContent := v.Is(types.VerbosityLevelVeryVerbose) || showTimeline || showSeparateVisibilityAlwaysReportsSection || showSeparateStdSection || report.Failed() || (v.Is(types.VerbosityLevelVerbose) && !report.State.Is(types.SpecStateSkipped))\n\n\t// should we show a runtime?\n\tincludeRuntime := !report.State.Is(types.SpecStateSkipped|types.SpecStatePending) || (report.State.Is(types.SpecStateSkipped) && report.Failure.Message != \"\")\n\n\t// should we show the codelocation block?\n\tshowCodeLocation := !timelineHasBeenStreaming || !report.State.Is(types.SpecStatePassed)\n\n\tswitch report.State {\n\tcase types.SpecStatePassed:\n\t\tif report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) && !reportHasContent {\n\t\t\treturn\n\t\t}\n\t\tif report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {\n\t\t\theader = fmt.Sprintf(\"%s PASSED\", header)\n\t\t}\n\t\tif report.NumAttempts > 1 && report.MaxFlakeAttempts > 1 {\n\t\t\theader, reportHasContent = fmt.Sprintf(\"%s [FLAKEY TEST - TOOK %d ATTEMPTS TO PASS]\", r.retryDenoter, report.NumAttempts), true\n\t\t}\n\tcase types.SpecStatePending:\n\t\theader = \"P\"\n\t\tif v.GT(types.VerbosityLevelSuccinct) {\n\t\t\theader, reportHasContent = \"P [PENDING]\", true\n\t\t}\n\tcase types.SpecStateSkipped:\n\t\theader = \"S\"\n\t\tif v.Is(types.VerbosityLevelVeryVerbose) || (v.Is(types.VerbosityLevelVerbose) && report.Failure.Message != \"\") {\n\t\t\theader, reportHasContent = \"S [SKIPPED]\", true\n\t\t}\n\tdefault:\n\t\theader = fmt.Sprintf(\"%s [%s]\", header, r.humanReadableState(report.State))\n\t\tif report.MaxMustPassRepeatedly > 1 {\n\t\t\theader = fmt.Sprintf(\"%s DURING REPETITION #%d\", header, report.NumAttempts)\n\t\t}\n\t}\n\n\t// If we have no content to show, just emit the header and return\n\tif !reportHasContent {\n\t\tr.emit(r.f(highlightColor + header + \"{{/}}\"))\n\t\tif r.conf.ForceNewlines {\n\t\t\tr.emit(\"\\n\")\n\t\t}\n\t\treturn\n\t}\n\n\tif includeRuntime {\n\t\theader = r.f(\"%s [%.3f seconds]\", header, report.RunTime.Seconds())\n\t}\n\n\t// Emit header\n\tif !timelineHasBeenStreaming {\n\t\tr.emitDelimiter(0)\n\t}\n\tr.emitBlock(r.f(highlightColor + header + \"{{/}}\"))\n\tif showCodeLocation {\n\t\tr.emitBlock(r.codeLocationBlock(report, highlightColor, v.Is(types.VerbosityLevelVeryVerbose), false))\n\t}\n\n\t//Emit Stdout/Stderr Output\n\tif showSeparateStdSection {\n\t\tr.wrapTextBlock(\"Captured StdOut/StdErr Output\", func() {\n\t\t\tr.emitBlock(r.fi(1, \"%s\", report.CapturedStdOutErr))\n\t\t})\n\t}\n\n\tif showSeparateVisibilityAlwaysReportsSection {\n\t\tr.wrapTextBlock(\"Report Entries\", func() {\n\t\t\tfor _, entry := range report.ReportEntries.WithVisibility(types.ReportEntryVisibilityAlways) {\n\t\t\t\tr.emitReportEntry(1, entry)\n\t\t\t}\n\t\t})\n\t}\n\n\tif showTimeline {\n\t\tr.wrapTextBlock(\"Timeline\", func() {\n\t\t\tr.emitTimeline(1, report, timeline)\n\t\t})\n\t}\n\n\t// Emit Failure Message\n\tif !report.Failure.IsZero() && !v.Is(types.VerbosityLevelVeryVerbose) {\n\t\tr.emitBlock(\"\\n\")\n\t\tr.emitFailure(1, report.State, report.Failure, true)\n\t\tif len(report.AdditionalFailures) > 0 {\n\t\t\tr.emitBlock(r.fi(1, \"\\nThere were {{bold}}{{red}}additional failures{{/}} detected.  To view them in detail run {{bold}}ginkgo -vv{{/}}\"))\n\t\t}\n\t}\n\n\tr.emitDelimiter(0)\n}\n\nfunc (r *DefaultReporter) highlightColorForState(state types.SpecState) string {\n\tswitch state {\n\tcase types.SpecStatePassed:\n\t\treturn \"{{green}}\"\n\tcase types.SpecStatePending:\n\t\treturn \"{{yellow}}\"\n\tcase types.SpecStateSkipped:\n\t\treturn \"{{cyan}}\"\n\tcase types.SpecStateFailed:\n\t\treturn \"{{red}}\"\n\tcase types.SpecStateTimedout:\n\t\treturn \"{{orange}}\"\n\tcase types.SpecStatePanicked:\n\t\treturn \"{{magenta}}\"\n\tcase types.SpecStateInterrupted:\n\t\treturn \"{{orange}}\"\n\tcase types.SpecStateAborted:\n\t\treturn \"{{coral}}\"\n\tdefault:\n\t\treturn \"{{gray}}\"\n\t}\n}\n\nfunc (r *DefaultReporter) humanReadableState(state types.SpecState) string {\n\treturn strings.ToUpper(state.String())\n}\n\nfunc (r *DefaultReporter) emitTimeline(indent uint, report types.SpecReport, timeline types.Timeline) {\n\tisVeryVerbose := r.conf.Verbosity().Is(types.VerbosityLevelVeryVerbose)\n\tgw := report.CapturedGinkgoWriterOutput\n\tcursor := 0\n\tfor _, entry := range timeline {\n\t\ttl := entry.GetTimelineLocation()\n\t\tif tl.Offset < len(gw) {\n\t\t\tr.emit(r.fi(indent, \"%s\", gw[cursor:tl.Offset]))\n\t\t\tcursor = tl.Offset\n\t\t} else if cursor < len(gw) {\n\t\t\tr.emit(r.fi(indent, \"%s\", gw[cursor:]))\n\t\t\tcursor = len(gw)\n\t\t}\n\t\tswitch x := entry.(type) {\n\t\tcase types.Failure:\n\t\t\tif isVeryVerbose {\n\t\t\t\tr.emitFailure(indent, report.State, x, false)\n\t\t\t} else {\n\t\t\t\tr.emitShortFailure(indent, report.State, x)\n\t\t\t}\n\t\tcase types.AdditionalFailure:\n\t\t\tif isVeryVerbose {\n\t\t\t\tr.emitFailure(indent, x.State, x.Failure, true)\n\t\t\t} else {\n\t\t\t\tr.emitShortFailure(indent, x.State, x.Failure)\n\t\t\t}\n\t\tcase types.ReportEntry:\n\t\t\tr.emitReportEntry(indent, x)\n\t\tcase types.ProgressReport:\n\t\t\tr.emitProgressReport(indent, false, x)\n\t\tcase types.SpecEvent:\n\t\t\tif isVeryVerbose || !x.IsOnlyVisibleAtVeryVerbose() || r.conf.ShowNodeEvents {\n\t\t\t\tr.emitSpecEvent(indent, x, isVeryVerbose)\n\t\t\t}\n\t\t}\n\t}\n\tif cursor < len(gw) {\n\t\tr.emit(r.fi(indent, \"%s\", gw[cursor:]))\n\t}\n}\n\nfunc (r *DefaultReporter) EmitFailure(state types.SpecState, failure types.Failure) {\n\tif r.conf.Verbosity().Is(types.VerbosityLevelVerbose) {\n\t\tr.emitShortFailure(1, state, failure)\n\t} else if r.conf.Verbosity().Is(types.VerbosityLevelVeryVerbose) {\n\t\tr.emitFailure(1, state, failure, true)\n\t}\n}\n\nfunc (r *DefaultReporter) emitShortFailure(indent uint, state types.SpecState, failure types.Failure) {\n\tr.emitBlock(r.fi(indent, r.highlightColorForState(state)+\"[%s]{{/}} in [%s] - %s {{gray}}@ %s{{/}}\",\n\t\tr.humanReadableState(state),\n\t\tfailure.FailureNodeType,\n\t\tfailure.Location,\n\t\tfailure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT),\n\t))\n}\n\nfunc (r *DefaultReporter) emitFailure(indent uint, state types.SpecState, failure types.Failure, includeAdditionalFailure bool) {\n\thighlightColor := r.highlightColorForState(state)\n\tr.emitBlock(r.fi(indent, highlightColor+\"[%s] %s{{/}}\", r.humanReadableState(state), failure.Message))\n\tif r.conf.GithubOutput {\n\t\tlevel := \"error\"\n\t\tif state.Is(types.SpecStateSkipped) {\n\t\t\tlevel = \"notice\"\n\t\t}\n\t\tr.emitBlock(r.fi(indent, \"::%s file=%s,line=%d::%s %s\", level, failure.Location.FileName, failure.Location.LineNumber, failure.FailureNodeType, failure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT)))\n\t} else {\n\t\tr.emitBlock(r.fi(indent, highlightColor+\"In {{bold}}[%s]{{/}}\"+highlightColor+\" at: {{bold}}%s{{/}} {{gray}}@ %s{{/}}\\n\", failure.FailureNodeType, failure.Location, failure.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT)))\n\t}\n\tif failure.ForwardedPanic != \"\" {\n\t\tr.emitBlock(\"\\n\")\n\t\tr.emitBlock(r.fi(indent, highlightColor+\"%s{{/}}\", failure.ForwardedPanic))\n\t}\n\n\tif r.conf.FullTrace || failure.ForwardedPanic != \"\" {\n\t\tr.emitBlock(\"\\n\")\n\t\tr.emitBlock(r.fi(indent, highlightColor+\"Full Stack Trace{{/}}\"))\n\t\tr.emitBlock(r.fi(indent+1, \"%s\", failure.Location.FullStackTrace))\n\t}\n\n\tif !failure.ProgressReport.IsZero() {\n\t\tr.emitBlock(\"\\n\")\n\t\tr.emitProgressReport(indent, false, failure.ProgressReport)\n\t}\n\n\tif failure.AdditionalFailure != nil && includeAdditionalFailure {\n\t\tr.emitBlock(\"\\n\")\n\t\tr.emitFailure(indent, failure.AdditionalFailure.State, failure.AdditionalFailure.Failure, true)\n\t}\n}\n\nfunc (r *DefaultReporter) EmitProgressReport(report types.ProgressReport) {\n\tr.emitDelimiter(1)\n\n\tif report.RunningInParallel {\n\t\tr.emit(r.fi(1, \"{{coral}}Progress Report for Ginkgo Process #{{bold}}%d{{/}}\\n\", report.ParallelProcess))\n\t}\n\tshouldEmitGW := report.RunningInParallel || r.conf.Verbosity().LT(types.VerbosityLevelVerbose)\n\tr.emitProgressReport(1, shouldEmitGW, report)\n\tr.emitDelimiter(1)\n}\n\nfunc (r *DefaultReporter) emitProgressReport(indent uint, emitGinkgoWriterOutput bool, report types.ProgressReport) {\n\tif report.Message != \"\" {\n\t\tr.emitBlock(r.fi(indent, report.Message+\"\\n\"))\n\t\tindent += 1\n\t}\n\tif report.LeafNodeText != \"\" {\n\t\tsubjectIndent := indent\n\t\tif len(report.ContainerHierarchyTexts) > 0 {\n\t\t\tr.emit(r.fi(indent, r.cycleJoin(report.ContainerHierarchyTexts, \" \")))\n\t\t\tr.emit(\" \")\n\t\t\tsubjectIndent = 0\n\t\t}\n\t\tr.emit(r.fi(subjectIndent, \"{{bold}}{{orange}}%s{{/}} (Spec Runtime: %s)\\n\", report.LeafNodeText, report.Time().Sub(report.SpecStartTime).Round(time.Millisecond)))\n\t\tr.emit(r.fi(indent+1, \"{{gray}}%s{{/}}\\n\", report.LeafNodeLocation))\n\t\tindent += 1\n\t}\n\tif report.CurrentNodeType != types.NodeTypeInvalid {\n\t\tr.emit(r.fi(indent, \"In {{bold}}{{orange}}[%s]{{/}}\", report.CurrentNodeType))\n\t\tif report.CurrentNodeText != \"\" && !report.CurrentNodeType.Is(types.NodeTypeIt) {\n\t\t\tr.emit(r.f(\" {{bold}}{{orange}}%s{{/}}\", report.CurrentNodeText))\n\t\t}\n\n\t\tr.emit(r.f(\" (Node Runtime: %s)\\n\", report.Time().Sub(report.CurrentNodeStartTime).Round(time.Millisecond)))\n\t\tr.emit(r.fi(indent+1, \"{{gray}}%s{{/}}\\n\", report.CurrentNodeLocation))\n\t\tindent += 1\n\t}\n\tif report.CurrentStepText != \"\" {\n\t\tr.emit(r.fi(indent, \"At {{bold}}{{orange}}[By Step] %s{{/}} (Step Runtime: %s)\\n\", report.CurrentStepText, report.Time().Sub(report.CurrentStepStartTime).Round(time.Millisecond)))\n\t\tr.emit(r.fi(indent+1, \"{{gray}}%s{{/}}\\n\", report.CurrentStepLocation))\n\t\tindent += 1\n\t}\n\n\tif indent > 0 {\n\t\tindent -= 1\n\t}\n\n\tif emitGinkgoWriterOutput && report.CapturedGinkgoWriterOutput != \"\" {\n\t\tr.emit(\"\\n\")\n\t\tr.emitBlock(r.fi(indent, \"{{gray}}Begin Captured GinkgoWriter Output >>{{/}}\"))\n\t\tlimit, lines := 10, strings.Split(report.CapturedGinkgoWriterOutput, \"\\n\")\n\t\tif len(lines) <= limit {\n\t\t\tr.emitBlock(r.fi(indent+1, \"%s\", report.CapturedGinkgoWriterOutput))\n\t\t} else {\n\t\t\tr.emitBlock(r.fi(indent+1, \"{{gray}}...{{/}}\"))\n\t\t\tfor _, line := range lines[len(lines)-limit-1:] {\n\t\t\t\tr.emitBlock(r.fi(indent+1, \"%s\", line))\n\t\t\t}\n\t\t}\n\t\tr.emitBlock(r.fi(indent, \"{{gray}}<< End Captured GinkgoWriter Output{{/}}\"))\n\t}\n\n\tif !report.SpecGoroutine().IsZero() {\n\t\tr.emit(\"\\n\")\n\t\tr.emit(r.fi(indent, \"{{bold}}{{underline}}Spec Goroutine{{/}}\\n\"))\n\t\tr.emitGoroutines(indent, report.SpecGoroutine())\n\t}\n\n\tif len(report.AdditionalReports) > 0 {\n\t\tr.emit(\"\\n\")\n\t\tr.emitBlock(r.fi(indent, \"{{gray}}Begin Additional Progress Reports >>{{/}}\"))\n\t\tfor i, additionalReport := range report.AdditionalReports {\n\t\t\tr.emit(r.fi(indent+1, additionalReport))\n\t\t\tif i < len(report.AdditionalReports)-1 {\n\t\t\t\tr.emitBlock(r.fi(indent+1, \"{{gray}}%s{{/}}\", strings.Repeat(\"-\", 10)))\n\t\t\t}\n\t\t}\n\t\tr.emitBlock(r.fi(indent, \"{{gray}}<< End Additional Progress Reports{{/}}\"))\n\t}\n\n\thighlightedGoroutines := report.HighlightedGoroutines()\n\tif len(highlightedGoroutines) > 0 {\n\t\tr.emit(\"\\n\")\n\t\tr.emit(r.fi(indent, \"{{bold}}{{underline}}Goroutines of Interest{{/}}\\n\"))\n\t\tr.emitGoroutines(indent, highlightedGoroutines...)\n\t}\n\n\totherGoroutines := report.OtherGoroutines()\n\tif len(otherGoroutines) > 0 {\n\t\tr.emit(\"\\n\")\n\t\tr.emit(r.fi(indent, \"{{gray}}{{bold}}{{underline}}Other Goroutines{{/}}\\n\"))\n\t\tr.emitGoroutines(indent, otherGoroutines...)\n\t}\n}\n\nfunc (r *DefaultReporter) EmitReportEntry(entry types.ReportEntry) {\n\tif r.conf.Verbosity().LT(types.VerbosityLevelVerbose) || entry.Visibility == types.ReportEntryVisibilityNever {\n\t\treturn\n\t}\n\tr.emitReportEntry(1, entry)\n}\n\nfunc (r *DefaultReporter) emitReportEntry(indent uint, entry types.ReportEntry) {\n\tr.emitBlock(r.fi(indent, \"{{bold}}\"+entry.Name+\"{{gray}} \"+fmt.Sprintf(\"- %s @ %s{{/}}\", entry.Location, entry.Time.Format(types.GINKGO_TIME_FORMAT))))\n\tif representation := entry.StringRepresentation(); representation != \"\" {\n\t\tr.emitBlock(r.fi(indent+1, representation))\n\t}\n}\n\nfunc (r *DefaultReporter) EmitSpecEvent(event types.SpecEvent) {\n\tv := r.conf.Verbosity()\n\tif v.Is(types.VerbosityLevelVeryVerbose) || (v.Is(types.VerbosityLevelVerbose) && (r.conf.ShowNodeEvents || !event.IsOnlyVisibleAtVeryVerbose())) {\n\t\tr.emitSpecEvent(1, event, r.conf.Verbosity().Is(types.VerbosityLevelVeryVerbose))\n\t}\n}\n\nfunc (r *DefaultReporter) emitSpecEvent(indent uint, event types.SpecEvent, includeLocation bool) {\n\tlocation := \"\"\n\tif includeLocation {\n\t\tlocation = fmt.Sprintf(\"- %s \", event.CodeLocation.String())\n\t}\n\tswitch event.SpecEventType {\n\tcase types.SpecEventInvalid:\n\t\treturn\n\tcase types.SpecEventByStart:\n\t\tr.emitBlock(r.fi(indent, \"{{bold}}STEP:{{/}} %s {{gray}}%s@ %s{{/}}\", event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT)))\n\tcase types.SpecEventByEnd:\n\t\tr.emitBlock(r.fi(indent, \"{{bold}}END STEP:{{/}} %s {{gray}}%s@ %s (%s){{/}}\", event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT), event.Duration.Round(time.Millisecond)))\n\tcase types.SpecEventNodeStart:\n\t\tr.emitBlock(r.fi(indent, \"> Enter {{bold}}[%s]{{/}} %s {{gray}}%s@ %s{{/}}\", event.NodeType.String(), event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT)))\n\tcase types.SpecEventNodeEnd:\n\t\tr.emitBlock(r.fi(indent, \"< Exit {{bold}}[%s]{{/}} %s {{gray}}%s@ %s (%s){{/}}\", event.NodeType.String(), event.Message, location, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT), event.Duration.Round(time.Millisecond)))\n\tcase types.SpecEventSpecRepeat:\n\t\tr.emitBlock(r.fi(indent, \"\\n{{bold}}Attempt #%d {{green}}Passed{{/}}{{bold}}.  Repeating %s{{/}} {{gray}}@ %s{{/}}\\n\\n\", event.Attempt, r.retryDenoter, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT)))\n\tcase types.SpecEventSpecRetry:\n\t\tr.emitBlock(r.fi(indent, \"\\n{{bold}}Attempt #%d {{red}}Failed{{/}}{{bold}}.  Retrying %s{{/}} {{gray}}@ %s{{/}}\\n\\n\", event.Attempt, r.retryDenoter, event.TimelineLocation.Time.Format(types.GINKGO_TIME_FORMAT)))\n\t}\n}\n\nfunc (r *DefaultReporter) emitGoroutines(indent uint, goroutines ...types.Goroutine) {\n\tfor idx, g := range goroutines {\n\t\tcolor := \"{{gray}}\"\n\t\tif g.HasHighlights() {\n\t\t\tcolor = \"{{orange}}\"\n\t\t}\n\t\tr.emit(r.fi(indent, color+\"goroutine %d [%s]{{/}}\\n\", g.ID, g.State))\n\t\tfor _, fc := range g.Stack {\n\t\t\tif fc.Highlight {\n\t\t\t\tr.emit(r.fi(indent, color+\"{{bold}}> %s{{/}}\\n\", fc.Function))\n\t\t\t\tr.emit(r.fi(indent+2, color+\"{{bold}}%s:%d{{/}}\\n\", fc.Filename, fc.Line))\n\t\t\t\tr.emitSource(indent+3, fc)\n\t\t\t} else {\n\t\t\t\tr.emit(r.fi(indent+1, \"{{gray}}%s{{/}}\\n\", fc.Function))\n\t\t\t\tr.emit(r.fi(indent+2, \"{{gray}}%s:%d{{/}}\\n\", fc.Filename, fc.Line))\n\t\t\t}\n\t\t}\n\n\t\tif idx+1 < len(goroutines) {\n\t\t\tr.emit(\"\\n\")\n\t\t}\n\t}\n}\n\nfunc (r *DefaultReporter) emitSource(indent uint, fc types.FunctionCall) {\n\tlines := fc.Source\n\tif len(lines) == 0 {\n\t\treturn\n\t}\n\n\tlTrim := 100000\n\tfor _, line := range lines {\n\t\tlTrimLine := len(line) - len(strings.TrimLeft(line, \" \\t\"))\n\t\tif lTrimLine < lTrim && len(line) > 0 {\n\t\t\tlTrim = lTrimLine\n\t\t}\n\t}\n\tif lTrim == 100000 {\n\t\tlTrim = 0\n\t}\n\n\tfor idx, line := range lines {\n\t\tif len(line) > lTrim {\n\t\t\tline = line[lTrim:]\n\t\t}\n\t\tif idx == fc.SourceHighlight {\n\t\t\tr.emit(r.fi(indent, \"{{bold}}{{orange}}> %s{{/}}\\n\", line))\n\t\t} else {\n\t\t\tr.emit(r.fi(indent, \"| %s\\n\", line))\n\t\t}\n\t}\n}\n\n/* Emitting to the writer */\nfunc (r *DefaultReporter) emit(s string) {\n\tr._emit(s, false, false)\n}\n\nfunc (r *DefaultReporter) emitBlock(s string) {\n\tr._emit(s, true, false)\n}\n\nfunc (r *DefaultReporter) emitDelimiter(indent uint) {\n\tr._emit(r.fi(indent, \"{{gray}}%s{{/}}\", strings.Repeat(\"-\", 30)), true, true)\n}\n\n// a bit ugly - but we're trying to minimize locking on this hot codepath\nfunc (r *DefaultReporter) _emit(s string, block bool, isDelimiter bool) {\n\tif len(s) == 0 {\n\t\treturn\n\t}\n\tr.lock.Lock()\n\tdefer r.lock.Unlock()\n\tif isDelimiter && r.lastEmissionWasDelimiter {\n\t\treturn\n\t}\n\tif block && !r.lastCharWasNewline {\n\t\tr.writer.Write([]byte(\"\\n\"))\n\t}\n\tr.lastCharWasNewline = (s[len(s)-1:] == \"\\n\")\n\tr.writer.Write([]byte(s))\n\tif block && !r.lastCharWasNewline {\n\t\tr.writer.Write([]byte(\"\\n\"))\n\t\tr.lastCharWasNewline = true\n\t}\n\tr.lastEmissionWasDelimiter = isDelimiter\n}\n\n/* Rendering text */\nfunc (r *DefaultReporter) f(format string, args ...any) string {\n\treturn r.formatter.F(format, args...)\n}\n\nfunc (r *DefaultReporter) fi(indentation uint, format string, args ...any) string {\n\treturn r.formatter.Fi(indentation, format, args...)\n}\n\nfunc (r *DefaultReporter) cycleJoin(elements []string, joiner string) string {\n\treturn r.formatter.CycleJoin(elements, joiner, []string{\"{{/}}\", \"{{gray}}\"})\n}\n\nfunc (r *DefaultReporter) codeLocationBlock(report types.SpecReport, highlightColor string, veryVerbose bool, usePreciseFailureLocation bool) string {\n\ttexts, locations, labels := []string{}, []types.CodeLocation{}, [][]string{}\n\ttexts, locations, labels = append(texts, report.ContainerHierarchyTexts...), append(locations, report.ContainerHierarchyLocations...), append(labels, report.ContainerHierarchyLabels...)\n\n\tif report.LeafNodeType.Is(types.NodeTypesForSuiteLevelNodes) {\n\t\ttexts = append(texts, r.f(\"[%s] %s\", report.LeafNodeType, report.LeafNodeText))\n\t} else {\n\t\ttexts = append(texts, r.f(report.LeafNodeText))\n\t}\n\tlabels = append(labels, report.LeafNodeLabels)\n\tlocations = append(locations, report.LeafNodeLocation)\n\n\tfailureLocation := report.Failure.FailureNodeLocation\n\tif usePreciseFailureLocation {\n\t\tfailureLocation = report.Failure.Location\n\t}\n\n\thighlightIndex := -1\n\tswitch report.Failure.FailureNodeContext {\n\tcase types.FailureNodeAtTopLevel:\n\t\ttexts = append([]string{fmt.Sprintf(\"TOP-LEVEL [%s]\", report.Failure.FailureNodeType)}, texts...)\n\t\tlocations = append([]types.CodeLocation{failureLocation}, locations...)\n\t\tlabels = append([][]string{{}}, labels...)\n\t\thighlightIndex = 0\n\tcase types.FailureNodeInContainer:\n\t\ti := report.Failure.FailureNodeContainerIndex\n\t\ttexts[i] = fmt.Sprintf(\"%s [%s]\", texts[i], report.Failure.FailureNodeType)\n\t\tlocations[i] = failureLocation\n\t\thighlightIndex = i\n\tcase types.FailureNodeIsLeafNode:\n\t\ti := len(texts) - 1\n\t\ttexts[i] = fmt.Sprintf(\"[%s] %s\", report.LeafNodeType, report.LeafNodeText)\n\t\tlocations[i] = failureLocation\n\t\thighlightIndex = i\n\tdefault:\n\t\t//there is no failure, so we highlight the leaf ndoe\n\t\thighlightIndex = len(texts) - 1\n\t}\n\n\tout := \"\"\n\tif veryVerbose {\n\t\tfor i := range texts {\n\t\t\tif i == highlightIndex {\n\t\t\t\tout += r.fi(uint(i), highlightColor+\"{{bold}}%s{{/}}\", texts[i])\n\t\t\t} else {\n\t\t\t\tout += r.fi(uint(i), \"%s\", texts[i])\n\t\t\t}\n\t\t\tif len(labels[i]) > 0 {\n\t\t\t\tout += r.f(\" {{coral}}[%s]{{/}}\", strings.Join(labels[i], \", \"))\n\t\t\t}\n\t\t\tout += \"\\n\"\n\t\t\tout += r.fi(uint(i), \"{{gray}}%s{{/}}\\n\", locations[i])\n\t\t}\n\t} else {\n\t\tfor i := range texts {\n\t\t\tstyle := \"{{/}}\"\n\t\t\tif i%2 == 1 {\n\t\t\t\tstyle = \"{{gray}}\"\n\t\t\t}\n\t\t\tif i == highlightIndex {\n\t\t\t\tstyle = highlightColor + \"{{bold}}\"\n\t\t\t}\n\t\t\tout += r.f(style+\"%s\", texts[i])\n\t\t\tif i < len(texts)-1 {\n\t\t\t\tout += \" \"\n\t\t\t} else {\n\t\t\t\tout += r.f(\"{{/}}\")\n\t\t\t}\n\t\t}\n\t\tflattenedLabels := report.Labels()\n\t\tif len(flattenedLabels) > 0 {\n\t\t\tout += r.f(\" {{coral}}[%s]{{/}}\", strings.Join(flattenedLabels, \", \"))\n\t\t}\n\t\tout += \"\\n\"\n\t\tif usePreciseFailureLocation {\n\t\t\tout += r.f(\"{{gray}}%s{{/}}\", failureLocation)\n\t\t} else {\n\t\t\tleafLocation := locations[len(locations)-1]\n\t\t\tif (report.Failure.FailureNodeLocation != types.CodeLocation{}) && (report.Failure.FailureNodeLocation != leafLocation) {\n\t\t\t\tout += r.fi(1, highlightColor+\"[%s]{{/}} {{gray}}%s{{/}}\\n\", report.Failure.FailureNodeType, report.Failure.FailureNodeLocation)\n\t\t\t\tout += r.fi(1, \"{{gray}}[%s] %s{{/}}\", report.LeafNodeType, leafLocation)\n\t\t\t} else {\n\t\t\t\tout += r.f(\"{{gray}}%s{{/}}\", leafLocation)\n\t\t\t}\n\t\t}\n\n\t}\n\treturn out\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/reporters/deprecated_reporter.go",
    "content": "package reporters\n\nimport (\n\t\"github.com/onsi/ginkgo/v2/config\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\n// Deprecated: DeprecatedReporter was how Ginkgo V1 provided support for CustomReporters\n// this has been removed in V2.\n// Please read the documentation at:\n// https://onsi.github.io/ginkgo/MIGRATING_TO_V2#removed-custom-reporters\n// for Ginkgo's new behavior and for a migration path.\ntype DeprecatedReporter interface {\n\tSuiteWillBegin(config config.GinkgoConfigType, summary *types.SuiteSummary)\n\tBeforeSuiteDidRun(setupSummary *types.SetupSummary)\n\tSpecWillRun(specSummary *types.SpecSummary)\n\tSpecDidComplete(specSummary *types.SpecSummary)\n\tAfterSuiteDidRun(setupSummary *types.SetupSummary)\n\tSuiteDidEnd(summary *types.SuiteSummary)\n}\n\n// ReportViaDeprecatedReporter takes a V1 custom reporter and a V2 report and\n// calls the custom reporter's methods with appropriately transformed data from the V2 report.\n//\n// ReportViaDeprecatedReporter should be called in a `ReportAfterSuite()`\n//\n// Deprecated: ReportViaDeprecatedReporter method exists to help developer bridge between deprecated V1 functionality and the new\n// reporting support in V2.  It will be removed in a future minor version of Ginkgo.\nfunc ReportViaDeprecatedReporter(reporter DeprecatedReporter, report types.Report) {\n\tconf := config.DeprecatedGinkgoConfigType{\n\t\tRandomSeed:        report.SuiteConfig.RandomSeed,\n\t\tRandomizeAllSpecs: report.SuiteConfig.RandomizeAllSpecs,\n\t\tFocusStrings:      report.SuiteConfig.FocusStrings,\n\t\tSkipStrings:       report.SuiteConfig.SkipStrings,\n\t\tFailOnPending:     report.SuiteConfig.FailOnPending,\n\t\tFailFast:          report.SuiteConfig.FailFast,\n\t\tFlakeAttempts:     report.SuiteConfig.FlakeAttempts,\n\t\tEmitSpecProgress:  false,\n\t\tDryRun:            report.SuiteConfig.DryRun,\n\t\tParallelNode:      report.SuiteConfig.ParallelProcess,\n\t\tParallelTotal:     report.SuiteConfig.ParallelTotal,\n\t\tSyncHost:          report.SuiteConfig.ParallelHost,\n\t\tStreamHost:        report.SuiteConfig.ParallelHost,\n\t}\n\n\tsummary := &types.DeprecatedSuiteSummary{\n\t\tSuiteDescription: report.SuiteDescription,\n\t\tSuiteID:          report.SuitePath,\n\n\t\tNumberOfSpecsBeforeParallelization: report.PreRunStats.TotalSpecs,\n\t\tNumberOfTotalSpecs:                 report.PreRunStats.TotalSpecs,\n\t\tNumberOfSpecsThatWillBeRun:         report.PreRunStats.SpecsThatWillRun,\n\t}\n\n\treporter.SuiteWillBegin(conf, summary)\n\n\tfor _, spec := range report.SpecReports {\n\t\tswitch spec.LeafNodeType {\n\t\tcase types.NodeTypeBeforeSuite, types.NodeTypeSynchronizedBeforeSuite:\n\t\t\tsetupSummary := &types.DeprecatedSetupSummary{\n\t\t\t\tComponentType:  spec.LeafNodeType,\n\t\t\t\tCodeLocation:   spec.LeafNodeLocation,\n\t\t\t\tState:          spec.State,\n\t\t\t\tRunTime:        spec.RunTime,\n\t\t\t\tFailure:        failureFor(spec),\n\t\t\t\tCapturedOutput: spec.CombinedOutput(),\n\t\t\t\tSuiteID:        report.SuitePath,\n\t\t\t}\n\t\t\treporter.BeforeSuiteDidRun(setupSummary)\n\t\tcase types.NodeTypeAfterSuite, types.NodeTypeSynchronizedAfterSuite:\n\t\t\tsetupSummary := &types.DeprecatedSetupSummary{\n\t\t\t\tComponentType:  spec.LeafNodeType,\n\t\t\t\tCodeLocation:   spec.LeafNodeLocation,\n\t\t\t\tState:          spec.State,\n\t\t\t\tRunTime:        spec.RunTime,\n\t\t\t\tFailure:        failureFor(spec),\n\t\t\t\tCapturedOutput: spec.CombinedOutput(),\n\t\t\t\tSuiteID:        report.SuitePath,\n\t\t\t}\n\t\t\treporter.AfterSuiteDidRun(setupSummary)\n\t\tcase types.NodeTypeIt:\n\t\t\tcomponentTexts, componentCodeLocations := []string{}, []types.CodeLocation{}\n\t\t\tcomponentTexts = append(componentTexts, spec.ContainerHierarchyTexts...)\n\t\t\tcomponentCodeLocations = append(componentCodeLocations, spec.ContainerHierarchyLocations...)\n\t\t\tcomponentTexts = append(componentTexts, spec.LeafNodeText)\n\t\t\tcomponentCodeLocations = append(componentCodeLocations, spec.LeafNodeLocation)\n\n\t\t\tspecSummary := &types.DeprecatedSpecSummary{\n\t\t\t\tComponentTexts:         componentTexts,\n\t\t\t\tComponentCodeLocations: componentCodeLocations,\n\t\t\t\tState:                  spec.State,\n\t\t\t\tRunTime:                spec.RunTime,\n\t\t\t\tFailure:                failureFor(spec),\n\t\t\t\tNumberOfSamples:        spec.NumAttempts,\n\t\t\t\tCapturedOutput:         spec.CombinedOutput(),\n\t\t\t\tSuiteID:                report.SuitePath,\n\t\t\t}\n\t\t\treporter.SpecWillRun(specSummary)\n\t\t\treporter.SpecDidComplete(specSummary)\n\n\t\t\tswitch spec.State {\n\t\t\tcase types.SpecStatePending:\n\t\t\t\tsummary.NumberOfPendingSpecs += 1\n\t\t\tcase types.SpecStateSkipped:\n\t\t\t\tsummary.NumberOfSkippedSpecs += 1\n\t\t\tcase types.SpecStateFailed, types.SpecStatePanicked, types.SpecStateInterrupted:\n\t\t\t\tsummary.NumberOfFailedSpecs += 1\n\t\t\tcase types.SpecStatePassed:\n\t\t\t\tsummary.NumberOfPassedSpecs += 1\n\t\t\t\tif spec.NumAttempts > 1 {\n\t\t\t\t\tsummary.NumberOfFlakedSpecs += 1\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tsummary.SuiteSucceeded = report.SuiteSucceeded\n\tsummary.RunTime = report.RunTime\n\n\treporter.SuiteDidEnd(summary)\n}\n\nfunc failureFor(spec types.SpecReport) types.DeprecatedSpecFailure {\n\tif spec.Failure.IsZero() {\n\t\treturn types.DeprecatedSpecFailure{}\n\t}\n\n\tindex := 0\n\tswitch spec.Failure.FailureNodeContext {\n\tcase types.FailureNodeInContainer:\n\t\tindex = spec.Failure.FailureNodeContainerIndex\n\tcase types.FailureNodeAtTopLevel:\n\t\tindex = -1\n\tcase types.FailureNodeIsLeafNode:\n\t\tindex = len(spec.ContainerHierarchyTexts) - 1\n\t\tif spec.LeafNodeText != \"\" {\n\t\t\tindex += 1\n\t\t}\n\t}\n\n\treturn types.DeprecatedSpecFailure{\n\t\tMessage:               spec.Failure.Message,\n\t\tLocation:              spec.Failure.Location,\n\t\tForwardedPanic:        spec.Failure.ForwardedPanic,\n\t\tComponentIndex:        index,\n\t\tComponentType:         spec.Failure.FailureNodeType,\n\t\tComponentCodeLocation: spec.Failure.FailureNodeLocation,\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/reporters/json_report.go",
    "content": "package reporters\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\n// GenerateJSONReport produces a JSON-formatted report at the passed in destination\nfunc GenerateJSONReport(report types.Report, destination string) error {\n\tif err := os.MkdirAll(path.Dir(destination), 0770); err != nil {\n\t\treturn err\n\t}\n\tf, err := os.Create(destination)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer f.Close()\n\tenc := json.NewEncoder(f)\n\tenc.SetIndent(\"\", \"  \")\n\terr = enc.Encode([]types.Report{\n\t\treport,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// MergeJSONReports produces a single JSON-formatted report at the passed in destination by merging the JSON-formatted reports provided in sources\n// It skips over reports that fail to decode but reports on them via the returned messages []string\nfunc MergeAndCleanupJSONReports(sources []string, destination string) ([]string, error) {\n\tmessages := []string{}\n\tallReports := []types.Report{}\n\tfor _, source := range sources {\n\t\treports := []types.Report{}\n\t\tdata, err := os.ReadFile(source)\n\t\tif err != nil {\n\t\t\tmessages = append(messages, fmt.Sprintf(\"Could not open %s:\\n%s\", source, err.Error()))\n\t\t\tcontinue\n\t\t}\n\t\terr = json.Unmarshal(data, &reports)\n\t\tif err != nil {\n\t\t\tmessages = append(messages, fmt.Sprintf(\"Could not decode %s:\\n%s\", source, err.Error()))\n\t\t\tcontinue\n\t\t}\n\t\tos.Remove(source)\n\t\tallReports = append(allReports, reports...)\n\t}\n\n\tif err := os.MkdirAll(path.Dir(destination), 0770); err != nil {\n\t\treturn messages, err\n\t}\n\tf, err := os.Create(destination)\n\tif err != nil {\n\t\treturn messages, err\n\t}\n\tdefer f.Close()\n\tenc := json.NewEncoder(f)\n\tenc.SetIndent(\"\", \"  \")\n\terr = enc.Encode(allReports)\n\tif err != nil {\n\t\treturn messages, err\n\t}\n\treturn messages, nil\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/reporters/junit_report.go",
    "content": "/*\n\nJUnit XML Reporter for Ginkgo\n\nFor usage instructions: http://onsi.github.io/ginkgo/#generating_junit_xml_output\n\nThe schema used for the generated JUnit xml file was adapted from https://llg.cubic.org/docs/junit/\n\n*/\n\npackage reporters\n\nimport (\n\t\"encoding/xml\"\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/onsi/ginkgo/v2/config\"\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\ntype JunitReportConfig struct {\n\t// Spec States for which no timeline should be emitted for system-err\n\t// set this to types.SpecStatePassed|types.SpecStateSkipped|types.SpecStatePending to only match failing specs\n\tOmitTimelinesForSpecState types.SpecState\n\n\t// Enable OmitFailureMessageAttr to prevent failure messages appearing in the \"message\" attribute of the Failure and Error tags\n\tOmitFailureMessageAttr bool\n\n\t//Enable OmitCapturedStdOutErr to prevent captured stdout/stderr appearing in system-out\n\tOmitCapturedStdOutErr bool\n\n\t// Enable OmitSpecLabels to prevent labels from appearing in the spec name\n\tOmitSpecLabels bool\n\n\t// Enable OmitLeafNodeType to prevent the spec leaf node type from appearing in the spec name\n\tOmitLeafNodeType bool\n\n\t// Enable OmitSuiteSetupNodes to prevent the creation of testcase entries for setup nodes\n\tOmitSuiteSetupNodes bool\n}\n\ntype JUnitTestSuites struct {\n\tXMLName xml.Name `xml:\"testsuites\"`\n\t// Tests maps onto the total number of specs in all test suites (this includes any suite nodes such as BeforeSuite)\n\tTests int `xml:\"tests,attr\"`\n\t// Disabled maps onto specs that are pending and/or skipped\n\tDisabled int `xml:\"disabled,attr\"`\n\t// Errors maps onto specs that panicked or were interrupted\n\tErrors int `xml:\"errors,attr\"`\n\t// Failures maps onto specs that failed\n\tFailures int `xml:\"failures,attr\"`\n\t// Time is the time in seconds to execute all test suites\n\tTime float64 `xml:\"time,attr\"`\n\n\t//The set of all test suites\n\tTestSuites []JUnitTestSuite `xml:\"testsuite\"`\n}\n\ntype JUnitTestSuite struct {\n\t// Name maps onto the description of the test suite - maps onto Report.SuiteDescription\n\tName string `xml:\"name,attr\"`\n\t// Package maps onto the absolute path to the test suite - maps onto Report.SuitePath\n\tPackage string `xml:\"package,attr\"`\n\t// Tests maps onto the total number of specs in the test suite (this includes any suite nodes such as BeforeSuite)\n\tTests int `xml:\"tests,attr\"`\n\t// Disabled maps onto specs that are pending\n\tDisabled int `xml:\"disabled,attr\"`\n\t// Skiped maps onto specs that are skipped\n\tSkipped int `xml:\"skipped,attr\"`\n\t// Errors maps onto specs that panicked or were interrupted\n\tErrors int `xml:\"errors,attr\"`\n\t// Failures maps onto specs that failed\n\tFailures int `xml:\"failures,attr\"`\n\t// Time is the time in seconds to execute all the test suite - maps onto Report.RunTime\n\tTime float64 `xml:\"time,attr\"`\n\t// Timestamp is the ISO 8601 formatted start-time of the suite - maps onto Report.StartTime\n\tTimestamp string `xml:\"timestamp,attr\"`\n\n\t//Properties captures the information stored in the rest of the Report type (including SuiteConfig) as key-value pairs\n\tProperties JUnitProperties `xml:\"properties\"`\n\n\t//TestCases capture the individual specs\n\tTestCases []JUnitTestCase `xml:\"testcase\"`\n}\n\ntype JUnitProperties struct {\n\tProperties []JUnitProperty `xml:\"property\"`\n}\n\nfunc (jup JUnitProperties) WithName(name string) string {\n\tfor _, property := range jup.Properties {\n\t\tif property.Name == name {\n\t\t\treturn property.Value\n\t\t}\n\t}\n\treturn \"\"\n}\n\ntype JUnitProperty struct {\n\tName  string `xml:\"name,attr\"`\n\tValue string `xml:\"value,attr\"`\n}\n\nvar ownerRE = regexp.MustCompile(`(?i)^owner:(.*)$`)\n\ntype JUnitTestCase struct {\n\t// Name maps onto the full text of the spec - equivalent to \"[SpecReport.LeafNodeType] SpecReport.FullText()\"\n\tName string `xml:\"name,attr\"`\n\t// Classname maps onto the name of the test suite - equivalent to Report.SuiteDescription\n\tClassname string `xml:\"classname,attr\"`\n\t// Status maps onto the string representation of SpecReport.State\n\tStatus string `xml:\"status,attr\"`\n\t// Time is the time in seconds to execute the spec - maps onto SpecReport.RunTime\n\tTime float64 `xml:\"time,attr\"`\n\t// Owner is the owner the spec - is set if a label matching Label(\"owner:X\") is provided.  The last matching label is used as the owner, thereby allowing specs to override owners specified in container nodes.\n\tOwner string `xml:\"owner,attr,omitempty\"`\n\t//Skipped is populated with a message if the test was skipped or pending\n\tSkipped *JUnitSkipped `xml:\"skipped,omitempty\"`\n\t//Error is populated if the test panicked or was interrupted\n\tError *JUnitError `xml:\"error,omitempty\"`\n\t//Failure is populated if the test failed\n\tFailure *JUnitFailure `xml:\"failure,omitempty\"`\n\t//SystemOut maps onto any captured stdout/stderr output - maps onto SpecReport.CapturedStdOutErr\n\tSystemOut string `xml:\"system-out,omitempty\"`\n\t//SystemOut maps onto any captured GinkgoWriter output - maps onto SpecReport.CapturedGinkgoWriterOutput\n\tSystemErr string `xml:\"system-err,omitempty\"`\n}\n\ntype JUnitSkipped struct {\n\t// Message maps onto \"pending\" if the test was marked pending, \"skipped\" if the test was marked skipped, and \"skipped - REASON\" if the user called Skip(REASON)\n\tMessage string `xml:\"message,attr\"`\n}\n\ntype JUnitError struct {\n\t//Message maps onto the panic/exception thrown - equivalent to SpecReport.Failure.ForwardedPanic - or to \"interrupted\"\n\tMessage string `xml:\"message,attr\"`\n\t//Type is one of \"panicked\" or \"interrupted\"\n\tType string `xml:\"type,attr\"`\n\t//Description maps onto the captured stack trace for a panic, or the failure message for an interrupt which will include the dump of running goroutines\n\tDescription string `xml:\",chardata\"`\n}\n\ntype JUnitFailure struct {\n\t//Message maps onto the failure message - equivalent to SpecReport.Failure.Message\n\tMessage string `xml:\"message,attr\"`\n\t//Type is \"failed\"\n\tType string `xml:\"type,attr\"`\n\t//Description maps onto the location and stack trace of the failure\n\tDescription string `xml:\",chardata\"`\n}\n\nfunc GenerateJUnitReport(report types.Report, dst string) error {\n\treturn GenerateJUnitReportWithConfig(report, dst, JunitReportConfig{})\n}\n\nfunc GenerateJUnitReportWithConfig(report types.Report, dst string, config JunitReportConfig) error {\n\tsuite := JUnitTestSuite{\n\t\tName:      report.SuiteDescription,\n\t\tPackage:   report.SuitePath,\n\t\tTime:      report.RunTime.Seconds(),\n\t\tTimestamp: report.StartTime.Format(\"2006-01-02T15:04:05\"),\n\t\tProperties: JUnitProperties{\n\t\t\tProperties: []JUnitProperty{\n\t\t\t\t{\"SuiteSucceeded\", fmt.Sprintf(\"%t\", report.SuiteSucceeded)},\n\t\t\t\t{\"SuiteHasProgrammaticFocus\", fmt.Sprintf(\"%t\", report.SuiteHasProgrammaticFocus)},\n\t\t\t\t{\"SpecialSuiteFailureReason\", strings.Join(report.SpecialSuiteFailureReasons, \",\")},\n\t\t\t\t{\"SuiteLabels\", fmt.Sprintf(\"[%s]\", strings.Join(report.SuiteLabels, \",\"))},\n\t\t\t\t{\"RandomSeed\", fmt.Sprintf(\"%d\", report.SuiteConfig.RandomSeed)},\n\t\t\t\t{\"RandomizeAllSpecs\", fmt.Sprintf(\"%t\", report.SuiteConfig.RandomizeAllSpecs)},\n\t\t\t\t{\"LabelFilter\", report.SuiteConfig.LabelFilter},\n\t\t\t\t{\"FocusStrings\", strings.Join(report.SuiteConfig.FocusStrings, \",\")},\n\t\t\t\t{\"SkipStrings\", strings.Join(report.SuiteConfig.SkipStrings, \",\")},\n\t\t\t\t{\"FocusFiles\", strings.Join(report.SuiteConfig.FocusFiles, \";\")},\n\t\t\t\t{\"SkipFiles\", strings.Join(report.SuiteConfig.SkipFiles, \";\")},\n\t\t\t\t{\"FailOnPending\", fmt.Sprintf(\"%t\", report.SuiteConfig.FailOnPending)},\n\t\t\t\t{\"FailOnEmpty\", fmt.Sprintf(\"%t\", report.SuiteConfig.FailOnEmpty)},\n\t\t\t\t{\"FailFast\", fmt.Sprintf(\"%t\", report.SuiteConfig.FailFast)},\n\t\t\t\t{\"FlakeAttempts\", fmt.Sprintf(\"%d\", report.SuiteConfig.FlakeAttempts)},\n\t\t\t\t{\"DryRun\", fmt.Sprintf(\"%t\", report.SuiteConfig.DryRun)},\n\t\t\t\t{\"ParallelTotal\", fmt.Sprintf(\"%d\", report.SuiteConfig.ParallelTotal)},\n\t\t\t\t{\"OutputInterceptorMode\", report.SuiteConfig.OutputInterceptorMode},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, spec := range report.SpecReports {\n\t\tif config.OmitSuiteSetupNodes && spec.LeafNodeType != types.NodeTypeIt {\n\t\t\tcontinue\n\t\t}\n\t\tname := fmt.Sprintf(\"[%s]\", spec.LeafNodeType)\n\t\tif config.OmitLeafNodeType {\n\t\t\tname = \"\"\n\t\t}\n\t\tif spec.FullText() != \"\" {\n\t\t\tname = name + \" \" + spec.FullText()\n\t\t}\n\t\tlabels := spec.Labels()\n\t\tif len(labels) > 0 && !config.OmitSpecLabels {\n\t\t\tname = name + \" [\" + strings.Join(labels, \", \") + \"]\"\n\t\t}\n\t\towner := \"\"\n\t\tfor _, label := range labels {\n\t\t\tif matches := ownerRE.FindStringSubmatch(label); len(matches) == 2 {\n\t\t\t\towner = matches[1]\n\t\t\t}\n\t\t}\n\t\tname = strings.TrimSpace(name)\n\n\t\ttest := JUnitTestCase{\n\t\t\tName:      name,\n\t\t\tClassname: report.SuiteDescription,\n\t\t\tStatus:    spec.State.String(),\n\t\t\tTime:      spec.RunTime.Seconds(),\n\t\t\tOwner:     owner,\n\t\t}\n\t\tif !spec.State.Is(config.OmitTimelinesForSpecState) {\n\t\t\ttest.SystemErr = systemErrForUnstructuredReporters(spec)\n\t\t}\n\t\tif !config.OmitCapturedStdOutErr {\n\t\t\ttest.SystemOut = systemOutForUnstructuredReporters(spec)\n\t\t}\n\t\tsuite.Tests += 1\n\n\t\tswitch spec.State {\n\t\tcase types.SpecStateSkipped:\n\t\t\tmessage := \"skipped\"\n\t\t\tif spec.Failure.Message != \"\" {\n\t\t\t\tmessage += \" - \" + spec.Failure.Message\n\t\t\t}\n\t\t\ttest.Skipped = &JUnitSkipped{Message: message}\n\t\t\tsuite.Skipped += 1\n\t\tcase types.SpecStatePending:\n\t\t\ttest.Skipped = &JUnitSkipped{Message: \"pending\"}\n\t\t\tsuite.Disabled += 1\n\t\tcase types.SpecStateFailed:\n\t\t\ttest.Failure = &JUnitFailure{\n\t\t\t\tMessage:     spec.Failure.Message,\n\t\t\t\tType:        \"failed\",\n\t\t\t\tDescription: failureDescriptionForUnstructuredReporters(spec),\n\t\t\t}\n\t\t\tif config.OmitFailureMessageAttr {\n\t\t\t\ttest.Failure.Message = \"\"\n\t\t\t}\n\t\t\tsuite.Failures += 1\n\t\tcase types.SpecStateTimedout:\n\t\t\ttest.Failure = &JUnitFailure{\n\t\t\t\tMessage:     spec.Failure.Message,\n\t\t\t\tType:        \"timedout\",\n\t\t\t\tDescription: failureDescriptionForUnstructuredReporters(spec),\n\t\t\t}\n\t\t\tif config.OmitFailureMessageAttr {\n\t\t\t\ttest.Failure.Message = \"\"\n\t\t\t}\n\t\t\tsuite.Failures += 1\n\t\tcase types.SpecStateInterrupted:\n\t\t\ttest.Error = &JUnitError{\n\t\t\t\tMessage:     spec.Failure.Message,\n\t\t\t\tType:        \"interrupted\",\n\t\t\t\tDescription: failureDescriptionForUnstructuredReporters(spec),\n\t\t\t}\n\t\t\tif config.OmitFailureMessageAttr {\n\t\t\t\ttest.Error.Message = \"\"\n\t\t\t}\n\t\t\tsuite.Errors += 1\n\t\tcase types.SpecStateAborted:\n\t\t\ttest.Failure = &JUnitFailure{\n\t\t\t\tMessage:     spec.Failure.Message,\n\t\t\t\tType:        \"aborted\",\n\t\t\t\tDescription: failureDescriptionForUnstructuredReporters(spec),\n\t\t\t}\n\t\t\tif config.OmitFailureMessageAttr {\n\t\t\t\ttest.Failure.Message = \"\"\n\t\t\t}\n\t\t\tsuite.Errors += 1\n\t\tcase types.SpecStatePanicked:\n\t\t\ttest.Error = &JUnitError{\n\t\t\t\tMessage:     spec.Failure.ForwardedPanic,\n\t\t\t\tType:        \"panicked\",\n\t\t\t\tDescription: failureDescriptionForUnstructuredReporters(spec),\n\t\t\t}\n\t\t\tif config.OmitFailureMessageAttr {\n\t\t\t\ttest.Error.Message = \"\"\n\t\t\t}\n\t\t\tsuite.Errors += 1\n\t\t}\n\n\t\tsuite.TestCases = append(suite.TestCases, test)\n\t}\n\n\tjunitReport := JUnitTestSuites{\n\t\tTests:      suite.Tests,\n\t\tDisabled:   suite.Disabled + suite.Skipped,\n\t\tErrors:     suite.Errors,\n\t\tFailures:   suite.Failures,\n\t\tTime:       suite.Time,\n\t\tTestSuites: []JUnitTestSuite{suite},\n\t}\n\n\tif err := os.MkdirAll(path.Dir(dst), 0770); err != nil {\n\t\treturn err\n\t}\n\tf, err := os.Create(dst)\n\tif err != nil {\n\t\treturn err\n\t}\n\tf.WriteString(xml.Header)\n\tencoder := xml.NewEncoder(f)\n\tencoder.Indent(\"  \", \"    \")\n\tencoder.Encode(junitReport)\n\n\treturn f.Close()\n}\n\nfunc MergeAndCleanupJUnitReports(sources []string, dst string) ([]string, error) {\n\tmessages := []string{}\n\tmergedReport := JUnitTestSuites{}\n\tfor _, source := range sources {\n\t\treport := JUnitTestSuites{}\n\t\tf, err := os.Open(source)\n\t\tif err != nil {\n\t\t\tmessages = append(messages, fmt.Sprintf(\"Could not open %s:\\n%s\", source, err.Error()))\n\t\t\tcontinue\n\t\t}\n\t\terr = xml.NewDecoder(f).Decode(&report)\n\t\t_ = f.Close()\n\t\tif err != nil {\n\t\t\tmessages = append(messages, fmt.Sprintf(\"Could not decode %s:\\n%s\", source, err.Error()))\n\t\t\tcontinue\n\t\t}\n\t\tos.Remove(source)\n\n\t\tmergedReport.Tests += report.Tests\n\t\tmergedReport.Disabled += report.Disabled\n\t\tmergedReport.Errors += report.Errors\n\t\tmergedReport.Failures += report.Failures\n\t\tmergedReport.Time += report.Time\n\t\tmergedReport.TestSuites = append(mergedReport.TestSuites, report.TestSuites...)\n\t}\n\n\tif err := os.MkdirAll(path.Dir(dst), 0770); err != nil {\n\t\treturn messages, err\n\t}\n\tf, err := os.Create(dst)\n\tif err != nil {\n\t\treturn messages, err\n\t}\n\tf.WriteString(xml.Header)\n\tencoder := xml.NewEncoder(f)\n\tencoder.Indent(\"  \", \"    \")\n\tencoder.Encode(mergedReport)\n\n\treturn messages, f.Close()\n}\n\nfunc failureDescriptionForUnstructuredReporters(spec types.SpecReport) string {\n\tout := &strings.Builder{}\n\tNewDefaultReporter(types.ReporterConfig{NoColor: true, VeryVerbose: true}, out).emitFailure(0, spec.State, spec.Failure, true)\n\tif len(spec.AdditionalFailures) > 0 {\n\t\tout.WriteString(\"\\nThere were additional failures detected after the initial failure. These are visible in the timeline\\n\")\n\t}\n\treturn out.String()\n}\n\nfunc systemErrForUnstructuredReporters(spec types.SpecReport) string {\n\treturn RenderTimeline(spec, true)\n}\n\nfunc RenderTimeline(spec types.SpecReport, noColor bool) string {\n\tout := &strings.Builder{}\n\tNewDefaultReporter(types.ReporterConfig{NoColor: noColor, VeryVerbose: true}, out).emitTimeline(0, spec, spec.Timeline())\n\treturn out.String()\n}\n\nfunc systemOutForUnstructuredReporters(spec types.SpecReport) string {\n\treturn spec.CapturedStdOutErr\n}\n\n// Deprecated JUnitReporter (so folks can still compile their suites)\ntype JUnitReporter struct{}\n\nfunc NewJUnitReporter(_ string) *JUnitReporter                                                  { return &JUnitReporter{} }\nfunc (reporter *JUnitReporter) SuiteWillBegin(_ config.GinkgoConfigType, _ *types.SuiteSummary) {}\nfunc (reporter *JUnitReporter) BeforeSuiteDidRun(_ *types.SetupSummary)                         {}\nfunc (reporter *JUnitReporter) SpecWillRun(_ *types.SpecSummary)                                {}\nfunc (reporter *JUnitReporter) SpecDidComplete(_ *types.SpecSummary)                            {}\nfunc (reporter *JUnitReporter) AfterSuiteDidRun(_ *types.SetupSummary)                          {}\nfunc (reporter *JUnitReporter) SuiteDidEnd(_ *types.SuiteSummary)                               {}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/reporters/reporter.go",
    "content": "package reporters\n\nimport (\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\ntype Reporter interface {\n\tSuiteWillBegin(report types.Report)\n\tWillRun(report types.SpecReport)\n\tDidRun(report types.SpecReport)\n\tSuiteDidEnd(report types.Report)\n\n\t//Timeline emission\n\tEmitFailure(state types.SpecState, failure types.Failure)\n\tEmitProgressReport(progressReport types.ProgressReport)\n\tEmitReportEntry(entry types.ReportEntry)\n\tEmitSpecEvent(event types.SpecEvent)\n}\n\ntype NoopReporter struct{}\n\nfunc (n NoopReporter) SuiteWillBegin(report types.Report)                       {}\nfunc (n NoopReporter) WillRun(report types.SpecReport)                          {}\nfunc (n NoopReporter) DidRun(report types.SpecReport)                           {}\nfunc (n NoopReporter) SuiteDidEnd(report types.Report)                          {}\nfunc (n NoopReporter) EmitFailure(state types.SpecState, failure types.Failure) {}\nfunc (n NoopReporter) EmitProgressReport(progressReport types.ProgressReport)   {}\nfunc (n NoopReporter) EmitReportEntry(entry types.ReportEntry)                  {}\nfunc (n NoopReporter) EmitSpecEvent(event types.SpecEvent)                      {}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/reporters/teamcity_report.go",
    "content": "/*\n\nTeamCity Reporter for Ginkgo\n\nMakes use of TeamCity's support for Service Messages\nhttp://confluence.jetbrains.com/display/TCD7/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ReportingTests\n*/\n\npackage reporters\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"strings\"\n\n\t\"github.com/onsi/ginkgo/v2/types\"\n)\n\nfunc tcEscape(s string) string {\n\ts = strings.ReplaceAll(s, \"|\", \"||\")\n\ts = strings.ReplaceAll(s, \"'\", \"|'\")\n\ts = strings.ReplaceAll(s, \"\\n\", \"|n\")\n\ts = strings.ReplaceAll(s, \"\\r\", \"|r\")\n\ts = strings.ReplaceAll(s, \"[\", \"|[\")\n\ts = strings.ReplaceAll(s, \"]\", \"|]\")\n\treturn s\n}\n\nfunc GenerateTeamcityReport(report types.Report, dst string) error {\n\tif err := os.MkdirAll(path.Dir(dst), 0770); err != nil {\n\t\treturn err\n\t}\n\tf, err := os.Create(dst)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tname := report.SuiteDescription\n\tlabels := report.SuiteLabels\n\tif len(labels) > 0 {\n\t\tname = name + \" [\" + strings.Join(labels, \", \") + \"]\"\n\t}\n\tfmt.Fprintf(f, \"##teamcity[testSuiteStarted name='%s']\\n\", tcEscape(name))\n\tfor _, spec := range report.SpecReports {\n\t\tname := fmt.Sprintf(\"[%s]\", spec.LeafNodeType)\n\t\tif spec.FullText() != \"\" {\n\t\t\tname = name + \" \" + spec.FullText()\n\t\t}\n\t\tlabels := spec.Labels()\n\t\tif len(labels) > 0 {\n\t\t\tname = name + \" [\" + strings.Join(labels, \", \") + \"]\"\n\t\t}\n\n\t\tname = tcEscape(name)\n\t\tfmt.Fprintf(f, \"##teamcity[testStarted name='%s']\\n\", name)\n\t\tswitch spec.State {\n\t\tcase types.SpecStatePending:\n\t\t\tfmt.Fprintf(f, \"##teamcity[testIgnored name='%s' message='pending']\\n\", name)\n\t\tcase types.SpecStateSkipped:\n\t\t\tmessage := \"skipped\"\n\t\t\tif spec.Failure.Message != \"\" {\n\t\t\t\tmessage += \" - \" + spec.Failure.Message\n\t\t\t}\n\t\t\tfmt.Fprintf(f, \"##teamcity[testIgnored name='%s' message='%s']\\n\", name, tcEscape(message))\n\t\tcase types.SpecStateFailed:\n\t\t\tdetails := failureDescriptionForUnstructuredReporters(spec)\n\t\t\tfmt.Fprintf(f, \"##teamcity[testFailed name='%s' message='failed - %s' details='%s']\\n\", name, tcEscape(spec.Failure.Message), tcEscape(details))\n\t\tcase types.SpecStatePanicked:\n\t\t\tdetails := failureDescriptionForUnstructuredReporters(spec)\n\t\t\tfmt.Fprintf(f, \"##teamcity[testFailed name='%s' message='panicked - %s' details='%s']\\n\", name, tcEscape(spec.Failure.ForwardedPanic), tcEscape(details))\n\t\tcase types.SpecStateTimedout:\n\t\t\tdetails := failureDescriptionForUnstructuredReporters(spec)\n\t\t\tfmt.Fprintf(f, \"##teamcity[testFailed name='%s' message='timedout - %s' details='%s']\\n\", name, tcEscape(spec.Failure.Message), tcEscape(details))\n\t\tcase types.SpecStateInterrupted:\n\t\t\tdetails := failureDescriptionForUnstructuredReporters(spec)\n\t\t\tfmt.Fprintf(f, \"##teamcity[testFailed name='%s' message='interrupted - %s' details='%s']\\n\", name, tcEscape(spec.Failure.Message), tcEscape(details))\n\t\tcase types.SpecStateAborted:\n\t\t\tdetails := failureDescriptionForUnstructuredReporters(spec)\n\t\t\tfmt.Fprintf(f, \"##teamcity[testFailed name='%s' message='aborted - %s' details='%s']\\n\", name, tcEscape(spec.Failure.Message), tcEscape(details))\n\t\t}\n\n\t\tfmt.Fprintf(f, \"##teamcity[testStdOut name='%s' out='%s']\\n\", name, tcEscape(systemOutForUnstructuredReporters(spec)))\n\t\tfmt.Fprintf(f, \"##teamcity[testStdErr name='%s' out='%s']\\n\", name, tcEscape(systemErrForUnstructuredReporters(spec)))\n\t\tfmt.Fprintf(f, \"##teamcity[testFinished name='%s' duration='%d']\\n\", name, int(spec.RunTime.Seconds()*1000.0))\n\t}\n\tfmt.Fprintf(f, \"##teamcity[testSuiteFinished name='%s']\\n\", tcEscape(report.SuiteDescription))\n\n\treturn f.Close()\n}\n\nfunc MergeAndCleanupTeamcityReports(sources []string, dst string) ([]string, error) {\n\tmessages := []string{}\n\tmerged := []byte{}\n\tfor _, source := range sources {\n\t\tdata, err := os.ReadFile(source)\n\t\tif err != nil {\n\t\t\tmessages = append(messages, fmt.Sprintf(\"Could not open %s:\\n%s\", source, err.Error()))\n\t\t\tcontinue\n\t\t}\n\t\tos.Remove(source)\n\t\tmerged = append(merged, data...)\n\t}\n\treturn messages, os.WriteFile(dst, merged, 0666)\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/types/code_location.go",
    "content": "package types\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"sync\"\n)\n\ntype CodeLocation struct {\n\tFileName       string `json:\",omitempty\"`\n\tLineNumber     int    `json:\",omitempty\"`\n\tFullStackTrace string `json:\",omitempty\"`\n\tCustomMessage  string `json:\",omitempty\"`\n}\n\nfunc (codeLocation CodeLocation) String() string {\n\tif codeLocation.CustomMessage != \"\" {\n\t\treturn codeLocation.CustomMessage\n\t}\n\treturn fmt.Sprintf(\"%s:%d\", codeLocation.FileName, codeLocation.LineNumber)\n}\n\nfunc (codeLocation CodeLocation) ContentsOfLine() string {\n\tif codeLocation.CustomMessage != \"\" {\n\t\treturn \"\"\n\t}\n\tcontents, err := os.ReadFile(codeLocation.FileName)\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\tlines := strings.Split(string(contents), \"\\n\")\n\tif len(lines) < codeLocation.LineNumber {\n\t\treturn \"\"\n\t}\n\treturn lines[codeLocation.LineNumber-1]\n}\n\ntype codeLocationLocator struct {\n\tpcs     map[uintptr]bool\n\thelpers map[string]bool\n\tlock    *sync.Mutex\n}\n\nfunc (c *codeLocationLocator) addHelper(pc uintptr) {\n\tc.lock.Lock()\n\tdefer c.lock.Unlock()\n\n\tif c.pcs[pc] {\n\t\treturn\n\t}\n\tc.lock.Unlock()\n\tf := runtime.FuncForPC(pc)\n\tc.lock.Lock()\n\tif f == nil {\n\t\treturn\n\t}\n\tc.helpers[f.Name()] = true\n\tc.pcs[pc] = true\n}\n\nfunc (c *codeLocationLocator) hasHelper(name string) bool {\n\tc.lock.Lock()\n\tdefer c.lock.Unlock()\n\treturn c.helpers[name]\n}\n\nfunc (c *codeLocationLocator) getCodeLocation(skip int) CodeLocation {\n\tpc := make([]uintptr, 40)\n\tn := runtime.Callers(skip+2, pc)\n\tif n == 0 {\n\t\treturn CodeLocation{}\n\t}\n\tpc = pc[:n]\n\tframes := runtime.CallersFrames(pc)\n\tfor {\n\t\tframe, more := frames.Next()\n\t\tif !c.hasHelper(frame.Function) {\n\t\t\treturn CodeLocation{FileName: frame.File, LineNumber: frame.Line}\n\t\t}\n\t\tif !more {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn CodeLocation{}\n}\n\nvar clLocator = &codeLocationLocator{\n\tpcs:     map[uintptr]bool{},\n\thelpers: map[string]bool{},\n\tlock:    &sync.Mutex{},\n}\n\n// MarkAsHelper is used by GinkgoHelper to mark the caller (appropriately offset by skip)as a helper.  You can use this directly if you need to provide an optional `skip` to mark functions further up the call stack as helpers.\nfunc MarkAsHelper(optionalSkip ...int) {\n\tskip := 1\n\tif len(optionalSkip) > 0 {\n\t\tskip += optionalSkip[0]\n\t}\n\tpc, _, _, ok := runtime.Caller(skip)\n\tif ok {\n\t\tclLocator.addHelper(pc)\n\t}\n}\n\nfunc NewCustomCodeLocation(message string) CodeLocation {\n\treturn CodeLocation{\n\t\tCustomMessage: message,\n\t}\n}\n\nfunc NewCodeLocation(skip int) CodeLocation {\n\treturn clLocator.getCodeLocation(skip + 1)\n}\n\nfunc NewCodeLocationWithStackTrace(skip int) CodeLocation {\n\tcl := clLocator.getCodeLocation(skip + 1)\n\tcl.FullStackTrace = PruneStack(string(debug.Stack()), skip+1)\n\treturn cl\n}\n\n// PruneStack removes references to functions that are internal to Ginkgo\n// and the Go runtime from a stack string and a certain number of stack entries\n// at the beginning of the stack. The stack string has the format\n// as returned by runtime/debug.Stack. The leading goroutine information is\n// optional and always removed if present. Beware that runtime/debug.Stack\n// adds itself as first entry, so typically skip must be >= 1 to remove that\n// entry.\nfunc PruneStack(fullStackTrace string, skip int) string {\n\tstack := strings.Split(fullStackTrace, \"\\n\")\n\t// Ensure that the even entries are the method names and the\n\t// odd entries the source code information.\n\tif len(stack) > 0 && strings.HasPrefix(stack[0], \"goroutine \") {\n\t\t// Ignore \"goroutine 29 [running]:\" line.\n\t\tstack = stack[1:]\n\t}\n\t// The \"+1\" is for skipping over the initial entry, which is\n\t// runtime/debug.Stack() itself.\n\tif len(stack) > 2*(skip+1) {\n\t\tstack = stack[2*(skip+1):]\n\t}\n\tprunedStack := []string{}\n\tif os.Getenv(\"GINKGO_PRUNE_STACK\") == \"FALSE\" {\n\t\tprunedStack = stack\n\t} else {\n\t\tre := regexp.MustCompile(`\\/ginkgo\\/|\\/pkg\\/testing\\/|\\/pkg\\/runtime\\/`)\n\t\tfor i := 0; i < len(stack)/2; i++ {\n\t\t\t// We filter out based on the source code file name.\n\t\t\tif !re.MatchString(stack[i*2+1]) {\n\t\t\t\tprunedStack = append(prunedStack, stack[i*2])\n\t\t\t\tprunedStack = append(prunedStack, stack[i*2+1])\n\t\t\t}\n\t\t}\n\t}\n\treturn strings.Join(prunedStack, \"\\n\")\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/types/config.go",
    "content": "/*\nGinkgo accepts a number of configuration options.\nThese are documented [here](http://onsi.github.io/ginkgo/#the-ginkgo-cli)\n*/\n\npackage types\n\nimport (\n\t\"flag\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\n// Configuration controlling how an individual test suite is run\ntype SuiteConfig struct {\n\tRandomSeed            int64\n\tRandomizeAllSpecs     bool\n\tFocusStrings          []string\n\tSkipStrings           []string\n\tFocusFiles            []string\n\tSkipFiles             []string\n\tLabelFilter           string\n\tFailOnPending         bool\n\tFailOnEmpty           bool\n\tFailFast              bool\n\tFlakeAttempts         int\n\tMustPassRepeatedly    int\n\tDryRun                bool\n\tPollProgressAfter     time.Duration\n\tPollProgressInterval  time.Duration\n\tTimeout               time.Duration\n\tEmitSpecProgress      bool // this is deprecated but its removal is causing compile issue for some users that were setting it manually\n\tOutputInterceptorMode string\n\tSourceRoots           []string\n\tGracePeriod           time.Duration\n\n\tParallelProcess int\n\tParallelTotal   int\n\tParallelHost    string\n}\n\nfunc NewDefaultSuiteConfig() SuiteConfig {\n\treturn SuiteConfig{\n\t\tRandomSeed:      time.Now().Unix(),\n\t\tTimeout:         time.Hour,\n\t\tParallelProcess: 1,\n\t\tParallelTotal:   1,\n\t\tGracePeriod:     30 * time.Second,\n\t}\n}\n\ntype VerbosityLevel uint\n\nconst (\n\tVerbosityLevelSuccinct VerbosityLevel = iota\n\tVerbosityLevelNormal\n\tVerbosityLevelVerbose\n\tVerbosityLevelVeryVerbose\n)\n\nfunc (vl VerbosityLevel) GT(comp VerbosityLevel) bool {\n\treturn vl > comp\n}\n\nfunc (vl VerbosityLevel) GTE(comp VerbosityLevel) bool {\n\treturn vl >= comp\n}\n\nfunc (vl VerbosityLevel) Is(comp VerbosityLevel) bool {\n\treturn vl == comp\n}\n\nfunc (vl VerbosityLevel) LTE(comp VerbosityLevel) bool {\n\treturn vl <= comp\n}\n\nfunc (vl VerbosityLevel) LT(comp VerbosityLevel) bool {\n\treturn vl < comp\n}\n\n// Configuration for Ginkgo's reporter\ntype ReporterConfig struct {\n\tNoColor        bool\n\tSuccinct       bool\n\tVerbose        bool\n\tVeryVerbose    bool\n\tFullTrace      bool\n\tShowNodeEvents bool\n\tGithubOutput   bool\n\tSilenceSkips   bool\n\tForceNewlines  bool\n\n\tJSONReport     string\n\tJUnitReport    string\n\tTeamcityReport string\n}\n\nfunc (rc ReporterConfig) Verbosity() VerbosityLevel {\n\tif rc.Succinct {\n\t\treturn VerbosityLevelSuccinct\n\t} else if rc.Verbose {\n\t\treturn VerbosityLevelVerbose\n\t} else if rc.VeryVerbose {\n\t\treturn VerbosityLevelVeryVerbose\n\t}\n\treturn VerbosityLevelNormal\n}\n\nfunc (rc ReporterConfig) WillGenerateReport() bool {\n\treturn rc.JSONReport != \"\" || rc.JUnitReport != \"\" || rc.TeamcityReport != \"\"\n}\n\nfunc NewDefaultReporterConfig() ReporterConfig {\n\treturn ReporterConfig{}\n}\n\n// Configuration for the Ginkgo CLI\ntype CLIConfig struct {\n\t//for build, run, and watch\n\tRecurse      bool\n\tSkipPackage  string\n\tRequireSuite bool\n\tNumCompilers int\n\n\t//for run and watch only\n\tProcs                     int\n\tParallel                  bool\n\tAfterRunHook              string\n\tOutputDir                 string\n\tKeepSeparateCoverprofiles bool\n\tKeepSeparateReports       bool\n\n\t//for run only\n\tKeepGoing       bool\n\tUntilItFails    bool\n\tRepeat          int\n\tRandomizeSuites bool\n\n\t//for watch only\n\tDepth       int\n\tWatchRegExp string\n}\n\nfunc NewDefaultCLIConfig() CLIConfig {\n\treturn CLIConfig{\n\t\tDepth:       1,\n\t\tWatchRegExp: `\\.go$`,\n\t}\n}\n\nfunc (g CLIConfig) ComputedProcs() int {\n\tif g.Procs > 0 {\n\t\treturn g.Procs\n\t}\n\n\tn := 1\n\tif g.Parallel {\n\t\tn = runtime.GOMAXPROCS(-1)\n\t\tif n > 4 {\n\t\t\tn = n - 1\n\t\t}\n\t}\n\treturn n\n}\n\nfunc (g CLIConfig) ComputedNumCompilers() int {\n\tif g.NumCompilers > 0 {\n\t\treturn g.NumCompilers\n\t}\n\n\treturn runtime.GOMAXPROCS(-1)\n}\n\n// Configuration for the Ginkgo CLI capturing available go flags\n// A subset of Go flags are exposed by Ginkgo.  Some are available at compile time (e.g. ginkgo build) and others only at run time (e.g. ginkgo run - which has both build and run time flags).\n// More details can be found at:\n// https://docs.google.com/spreadsheets/d/1zkp-DS4hU4sAJl5eHh1UmgwxCPQhf3s5a8fbiOI8tJU/\ntype GoFlagsConfig struct {\n\t//build-time flags for code-and-performance analysis\n\tRace      bool\n\tCover     bool\n\tCoverMode string\n\tCoverPkg  string\n\tVet       string\n\n\t//run-time flags for code-and-performance analysis\n\tBlockProfile         string\n\tBlockProfileRate     int\n\tCoverProfile         string\n\tCPUProfile           string\n\tMemProfile           string\n\tMemProfileRate       int\n\tMutexProfile         string\n\tMutexProfileFraction int\n\tTrace                string\n\n\t//build-time flags for building\n\tA             bool\n\tASMFlags      string\n\tBuildMode     string\n\tBuildVCS      bool\n\tCompiler      string\n\tGCCGoFlags    string\n\tGCFlags       string\n\tInstallSuffix string\n\tLDFlags       string\n\tLinkShared    bool\n\tMod           string\n\tN             bool\n\tModFile       string\n\tModCacheRW    bool\n\tMSan          bool\n\tPkgDir        string\n\tTags          string\n\tTrimPath      bool\n\tToolExec      string\n\tWork          bool\n\tX             bool\n\tO             string\n}\n\nfunc NewDefaultGoFlagsConfig() GoFlagsConfig {\n\treturn GoFlagsConfig{}\n}\n\nfunc (g GoFlagsConfig) BinaryMustBePreserved() bool {\n\treturn g.BlockProfile != \"\" || g.CPUProfile != \"\" || g.MemProfile != \"\" || g.MutexProfile != \"\"\n}\n\nfunc (g GoFlagsConfig) NeedsSymbols() bool {\n\treturn g.BinaryMustBePreserved()\n}\n\n// Configuration that were deprecated in 2.0\ntype deprecatedConfig struct {\n\tDebugParallel                   bool\n\tNoisySkippings                  bool\n\tNoisyPendings                   bool\n\tRegexScansFilePath              bool\n\tSlowSpecThresholdWithFLoatUnits float64\n\tStream                          bool\n\tNotify                          bool\n\tEmitSpecProgress                bool\n\tSlowSpecThreshold               time.Duration\n\tAlwaysEmitGinkgoWriter          bool\n}\n\n// Flags\n\n// Flags sections used by both the CLI and the Ginkgo test process\nvar FlagSections = GinkgoFlagSections{\n\t{Key: \"multiple-suites\", Style: \"{{dark-green}}\", Heading: \"Running Multiple Test Suites\"},\n\t{Key: \"order\", Style: \"{{green}}\", Heading: \"Controlling Test Order\"},\n\t{Key: \"parallel\", Style: \"{{yellow}}\", Heading: \"Controlling Test Parallelism\"},\n\t{Key: \"low-level-parallel\", Style: \"{{yellow}}\", Heading: \"Controlling Test Parallelism\",\n\t\tDescription: \"These are set by the Ginkgo CLI, {{red}}{{bold}}do not set them manually{{/}} via go test.\\nUse ginkgo -p or ginkgo -procs=N instead.\"},\n\t{Key: \"filter\", Style: \"{{cyan}}\", Heading: \"Filtering Tests\"},\n\t{Key: \"failure\", Style: \"{{red}}\", Heading: \"Failure Handling\"},\n\t{Key: \"output\", Style: \"{{magenta}}\", Heading: \"Controlling Output Formatting\"},\n\t{Key: \"code-and-coverage-analysis\", Style: \"{{orange}}\", Heading: \"Code and Coverage Analysis\",\n\t\tDescription: \"When generating a cover files, please pass a filename {{bold}}not{{/}} a path.  To specify a different directory use {{magenta}}--output-dir{{/}}.\",\n\t},\n\t{Key: \"performance-analysis\", Style: \"{{coral}}\", Heading: \"Performance Analysis\",\n\t\tDescription: \"When generating profile files, please pass filenames {{bold}}not{{/}} a path.  Ginkgo will generate a profile file with the given name in the package's directory.  To specify a different directory use {{magenta}}--output-dir{{/}}.\",\n\t},\n\t{Key: \"debug\", Style: \"{{blue}}\", Heading: \"Debugging Tests\",\n\t\tDescription: \"In addition to these flags, Ginkgo supports a few debugging environment variables.  To change the parallel server protocol set {{blue}}GINKGO_PARALLEL_PROTOCOL{{/}} to {{bold}}HTTP{{/}}.  To avoid pruning callstacks set {{blue}}GINKGO_PRUNE_STACK{{/}} to {{bold}}FALSE{{/}}.\"},\n\t{Key: \"watch\", Style: \"{{light-yellow}}\", Heading: \"Controlling Ginkgo Watch\"},\n\t{Key: \"misc\", Style: \"{{light-gray}}\", Heading: \"Miscellaneous\"},\n\t{Key: \"go-build\", Style: \"{{light-gray}}\", Heading: \"Go Build Flags\", Succinct: true,\n\t\tDescription: \"These flags are inherited from go build.  Run {{bold}}ginkgo help build{{/}} for more detailed flag documentation.\"},\n}\n\n// SuiteConfigFlags provides flags for the Ginkgo test process, and CLI\nvar SuiteConfigFlags = GinkgoFlags{\n\t{KeyPath: \"S.RandomSeed\", Name: \"seed\", SectionKey: \"order\", UsageDefaultValue: \"randomly generated by Ginkgo\",\n\t\tUsage: \"The seed used to randomize the spec suite.\", AlwaysExport: true},\n\t{KeyPath: \"S.RandomizeAllSpecs\", Name: \"randomize-all\", SectionKey: \"order\", DeprecatedName: \"randomizeAllSpecs\", DeprecatedDocLink: \"changed-command-line-flags\",\n\t\tUsage: \"If set, ginkgo will randomize all specs together.  By default, ginkgo only randomizes the top level Describe, Context and When containers.\"},\n\n\t{KeyPath: \"S.FailOnPending\", Name: \"fail-on-pending\", SectionKey: \"failure\", DeprecatedName: \"failOnPending\", DeprecatedDocLink: \"changed-command-line-flags\",\n\t\tUsage: \"If set, ginkgo will mark the test suite as failed if any specs are pending.\"},\n\t{KeyPath: \"S.FailFast\", Name: \"fail-fast\", SectionKey: \"failure\", DeprecatedName: \"failFast\", DeprecatedDocLink: \"changed-command-line-flags\",\n\t\tUsage: \"If set, ginkgo will stop running a test suite after a failure occurs.\"},\n\t{KeyPath: \"S.FlakeAttempts\", Name: \"flake-attempts\", SectionKey: \"failure\", UsageDefaultValue: \"0 - failed tests are not retried\", DeprecatedName: \"flakeAttempts\", DeprecatedDocLink: \"changed-command-line-flags\",\n\t\tUsage: \"Make up to this many attempts to run each spec. If any of the attempts succeed, the suite will not be failed.\"},\n\t{KeyPath: \"S.FailOnEmpty\", Name: \"fail-on-empty\", SectionKey: \"failure\",\n\t\tUsage: \"If set, ginkgo will mark the test suite as failed if no specs are run.\"},\n\n\t{KeyPath: \"S.DryRun\", Name: \"dry-run\", SectionKey: \"debug\", DeprecatedName: \"dryRun\", DeprecatedDocLink: \"changed-command-line-flags\",\n\t\tUsage: \"If set, ginkgo will walk the test hierarchy without actually running anything.  Best paired with -v.\"},\n\t{KeyPath: \"S.PollProgressAfter\", Name: \"poll-progress-after\", SectionKey: \"debug\", UsageDefaultValue: \"0\",\n\t\tUsage: \"Emit node progress reports periodically if node hasn't completed after this duration.\"},\n\t{KeyPath: \"S.PollProgressInterval\", Name: \"poll-progress-interval\", SectionKey: \"debug\", UsageDefaultValue: \"10s\",\n\t\tUsage: \"The rate at which to emit node progress reports after poll-progress-after has elapsed.\"},\n\t{KeyPath: \"S.SourceRoots\", Name: \"source-root\", SectionKey: \"debug\",\n\t\tUsage: \"The location to look for source code when generating progress reports.  You can pass multiple --source-root flags.\"},\n\t{KeyPath: \"S.Timeout\", Name: \"timeout\", SectionKey: \"debug\", UsageDefaultValue: \"1h\",\n\t\tUsage: \"Test suite fails if it does not complete within the specified timeout.\"},\n\t{KeyPath: \"S.GracePeriod\", Name: \"grace-period\", SectionKey: \"debug\", UsageDefaultValue: \"30s\",\n\t\tUsage: \"When interrupted, Ginkgo will wait for GracePeriod for the current running node to exit before moving on to the next one.\"},\n\t{KeyPath: \"S.OutputInterceptorMode\", Name: \"output-interceptor-mode\", SectionKey: \"debug\", UsageArgument: \"dup, swap, or none\",\n\t\tUsage: \"If set, ginkgo will use the specified output interception strategy when running in parallel.  Defaults to dup on unix and swap on windows.\"},\n\n\t{KeyPath: \"S.LabelFilter\", Name: \"label-filter\", SectionKey: \"filter\", UsageArgument: \"expression\",\n\t\tUsage: \"If set, ginkgo will only run specs with labels that match the label-filter.  The passed-in expression can include boolean operations (!, &&, ||, ','), groupings via '()', and regular expressions '/regexp/'.  e.g. '(cat || dog) && !fruit'\"},\n\t{KeyPath: \"S.FocusStrings\", Name: \"focus\", SectionKey: \"filter\",\n\t\tUsage: \"If set, ginkgo will only run specs that match this regular expression. Can be specified multiple times, values are ORed.\"},\n\t{KeyPath: \"S.SkipStrings\", Name: \"skip\", SectionKey: \"filter\",\n\t\tUsage: \"If set, ginkgo will only run specs that do not match this regular expression. Can be specified multiple times, values are ORed.\"},\n\t{KeyPath: \"S.FocusFiles\", Name: \"focus-file\", SectionKey: \"filter\", UsageArgument: \"file (regexp) | file:line | file:lineA-lineB | file:line,line,line\",\n\t\tUsage: \"If set, ginkgo will only run specs in matching files. Can be specified multiple times, values are ORed.\"},\n\t{KeyPath: \"S.SkipFiles\", Name: \"skip-file\", SectionKey: \"filter\", UsageArgument: \"file (regexp) | file:line | file:lineA-lineB | file:line,line,line\",\n\t\tUsage: \"If set, ginkgo will skip specs in matching files. Can be specified multiple times, values are ORed.\"},\n\n\t{KeyPath: \"D.RegexScansFilePath\", DeprecatedName: \"regexScansFilePath\", DeprecatedDocLink: \"removed--regexscansfilepath\", DeprecatedVersion: \"2.0.0\"},\n\t{KeyPath: \"D.DebugParallel\", DeprecatedName: \"debug\", DeprecatedDocLink: \"removed--debug\", DeprecatedVersion: \"2.0.0\"},\n\t{KeyPath: \"D.EmitSpecProgress\", DeprecatedName: \"progress\", SectionKey: \"debug\",\n\t\tDeprecatedVersion: \"2.5.0\", Usage: \".  The functionality provided by --progress was confusing and is no longer needed.  Use --show-node-events instead to see node entry and exit events included in the timeline of failed and verbose specs.  Or you can run with -vv to always see all node events.  Lastly, --poll-progress-after and the PollProgressAfter decorator now provide a better mechanism for debugging specs that tend to get stuck.\"},\n}\n\n// ParallelConfigFlags provides flags for the Ginkgo test process (not the CLI)\nvar ParallelConfigFlags = GinkgoFlags{\n\t{KeyPath: \"S.ParallelProcess\", Name: \"parallel.process\", SectionKey: \"low-level-parallel\", UsageDefaultValue: \"1\",\n\t\tUsage: \"This worker process's (one-indexed) process number.  For running specs in parallel.\"},\n\t{KeyPath: \"S.ParallelTotal\", Name: \"parallel.total\", SectionKey: \"low-level-parallel\", UsageDefaultValue: \"1\",\n\t\tUsage: \"The total number of worker processes.  For running specs in parallel.\"},\n\t{KeyPath: \"S.ParallelHost\", Name: \"parallel.host\", SectionKey: \"low-level-parallel\", UsageDefaultValue: \"set by Ginkgo CLI\",\n\t\tUsage: \"The address for the server that will synchronize the processes.\"},\n}\n\n// ReporterConfigFlags provides flags for the Ginkgo test process, and CLI\nvar ReporterConfigFlags = GinkgoFlags{\n\t{KeyPath: \"R.NoColor\", Name: \"no-color\", SectionKey: \"output\", DeprecatedName: \"noColor\", DeprecatedDocLink: \"changed-command-line-flags\",\n\t\tUsage: \"If set, suppress color output in default reporter.  You can also set the environment variable GINKGO_NO_COLOR=TRUE\"},\n\t{KeyPath: \"R.Verbose\", Name: \"v\", SectionKey: \"output\",\n\t\tUsage: \"If set, emits more output including GinkgoWriter contents.\"},\n\t{KeyPath: \"R.VeryVerbose\", Name: \"vv\", SectionKey: \"output\",\n\t\tUsage: \"If set, emits with maximal verbosity - includes skipped and pending tests.\"},\n\t{KeyPath: \"R.Succinct\", Name: \"succinct\", SectionKey: \"output\",\n\t\tUsage: \"If set, default reporter prints out a very succinct report\"},\n\t{KeyPath: \"R.FullTrace\", Name: \"trace\", SectionKey: \"output\",\n\t\tUsage: \"If set, default reporter prints out the full stack trace when a failure occurs\"},\n\t{KeyPath: \"R.ShowNodeEvents\", Name: \"show-node-events\", SectionKey: \"output\",\n\t\tUsage: \"If set, default reporter prints node > Enter and < Exit events when specs fail\"},\n\t{KeyPath: \"R.GithubOutput\", Name: \"github-output\", SectionKey: \"output\",\n\t\tUsage: \"If set, default reporter prints easier to manage output in Github Actions.\"},\n\t{KeyPath: \"R.SilenceSkips\", Name: \"silence-skips\", SectionKey: \"output\",\n\t\tUsage: \"If set, default reporter will not print out skipped tests.\"},\n\t{KeyPath: \"R.ForceNewlines\", Name: \"force-newlines\", SectionKey: \"output\",\n\t\tUsage: \"If set, default reporter will ensure a newline appears after each test.\"},\n\n\t{KeyPath: \"R.JSONReport\", Name: \"json-report\", UsageArgument: \"filename.json\", SectionKey: \"output\",\n\t\tUsage: \"If set, Ginkgo will generate a JSON-formatted test report at the specified location.\"},\n\t{KeyPath: \"R.JUnitReport\", Name: \"junit-report\", UsageArgument: \"filename.xml\", SectionKey: \"output\", DeprecatedName: \"reportFile\", DeprecatedDocLink: \"improved-reporting-infrastructure\",\n\t\tUsage: \"If set, Ginkgo will generate a conformant junit test report in the specified file.\"},\n\t{KeyPath: \"R.TeamcityReport\", Name: \"teamcity-report\", UsageArgument: \"filename\", SectionKey: \"output\",\n\t\tUsage: \"If set, Ginkgo will generate a Teamcity-formatted test report at the specified location.\"},\n\n\t{KeyPath: \"D.SlowSpecThresholdWithFLoatUnits\", DeprecatedName: \"slowSpecThreshold\", DeprecatedDocLink: \"changed--slowspecthreshold\",\n\t\tUsage: \"use --slow-spec-threshold instead and pass in a duration string (e.g. '5s', not '5.0')\"},\n\t{KeyPath: \"D.NoisyPendings\", DeprecatedName: \"noisyPendings\", DeprecatedDocLink: \"removed--noisypendings-and--noisyskippings\", DeprecatedVersion: \"2.0.0\"},\n\t{KeyPath: \"D.NoisySkippings\", DeprecatedName: \"noisySkippings\", DeprecatedDocLink: \"removed--noisypendings-and--noisyskippings\", DeprecatedVersion: \"2.0.0\"},\n\t{KeyPath: \"D.SlowSpecThreshold\", DeprecatedName: \"slow-spec-threshold\", SectionKey: \"output\", Usage: \"--slow-spec-threshold has been deprecated and will be removed in a future version of Ginkgo.  This feature has proved to be more noisy than useful.  You can use --poll-progress-after, instead, to get more actionable feedback about potentially slow specs and understand where they might be getting stuck.\", DeprecatedVersion: \"2.5.0\"},\n\t{KeyPath: \"D.AlwaysEmitGinkgoWriter\", DeprecatedName: \"always-emit-ginkgo-writer\", SectionKey: \"output\", Usage: \" - use -v instead, or one of Ginkgo's machine-readable report formats to get GinkgoWriter output for passing specs.\"},\n}\n\n// BuildTestSuiteFlagSet attaches to the CommandLine flagset and provides flags for the Ginkgo test process\nfunc BuildTestSuiteFlagSet(suiteConfig *SuiteConfig, reporterConfig *ReporterConfig) (GinkgoFlagSet, error) {\n\tflags := SuiteConfigFlags.CopyAppend(ParallelConfigFlags...).CopyAppend(ReporterConfigFlags...)\n\tflags = flags.WithPrefix(\"ginkgo\")\n\tbindings := map[string]any{\n\t\t\"S\": suiteConfig,\n\t\t\"R\": reporterConfig,\n\t\t\"D\": &deprecatedConfig{},\n\t}\n\textraGoFlagsSection := GinkgoFlagSection{Style: \"{{gray}}\", Heading: \"Go test flags\"}\n\n\treturn NewAttachedGinkgoFlagSet(flag.CommandLine, flags, bindings, FlagSections, extraGoFlagsSection)\n}\n\n// VetConfig validates that the Ginkgo test process' configuration is sound\nfunc VetConfig(flagSet GinkgoFlagSet, suiteConfig SuiteConfig, reporterConfig ReporterConfig) []error {\n\terrors := []error{}\n\n\tif flagSet.WasSet(\"count\") || flagSet.WasSet(\"test.count\") {\n\t\tflag := flagSet.Lookup(\"count\")\n\t\tif flag == nil {\n\t\t\tflag = flagSet.Lookup(\"test.count\")\n\t\t}\n\t\tcount, err := strconv.Atoi(flag.Value.String())\n\t\tif err != nil || count != 1 {\n\t\t\terrors = append(errors, GinkgoErrors.InvalidGoFlagCount())\n\t\t}\n\t}\n\n\tif flagSet.WasSet(\"parallel\") || flagSet.WasSet(\"test.parallel\") {\n\t\terrors = append(errors, GinkgoErrors.InvalidGoFlagParallel())\n\t}\n\n\tif suiteConfig.ParallelTotal < 1 {\n\t\terrors = append(errors, GinkgoErrors.InvalidParallelTotalConfiguration())\n\t}\n\n\tif suiteConfig.ParallelProcess > suiteConfig.ParallelTotal || suiteConfig.ParallelProcess < 1 {\n\t\terrors = append(errors, GinkgoErrors.InvalidParallelProcessConfiguration())\n\t}\n\n\tif suiteConfig.ParallelTotal > 1 && suiteConfig.ParallelHost == \"\" {\n\t\terrors = append(errors, GinkgoErrors.MissingParallelHostConfiguration())\n\t}\n\n\tif suiteConfig.DryRun && suiteConfig.ParallelTotal > 1 {\n\t\terrors = append(errors, GinkgoErrors.DryRunInParallelConfiguration())\n\t}\n\n\tif suiteConfig.GracePeriod <= 0 {\n\t\terrors = append(errors, GinkgoErrors.GracePeriodCannotBeZero())\n\t}\n\n\tif len(suiteConfig.FocusFiles) > 0 {\n\t\t_, err := ParseFileFilters(suiteConfig.FocusFiles)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\n\tif len(suiteConfig.SkipFiles) > 0 {\n\t\t_, err := ParseFileFilters(suiteConfig.SkipFiles)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\n\tif suiteConfig.LabelFilter != \"\" {\n\t\t_, err := ParseLabelFilter(suiteConfig.LabelFilter)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\n\tswitch strings.ToLower(suiteConfig.OutputInterceptorMode) {\n\tcase \"\", \"dup\", \"swap\", \"none\":\n\tdefault:\n\t\terrors = append(errors, GinkgoErrors.InvalidOutputInterceptorModeConfiguration(suiteConfig.OutputInterceptorMode))\n\t}\n\n\tnumVerbosity := 0\n\tfor _, v := range []bool{reporterConfig.Succinct, reporterConfig.Verbose, reporterConfig.VeryVerbose} {\n\t\tif v {\n\t\t\tnumVerbosity++\n\t\t}\n\t}\n\tif numVerbosity > 1 {\n\t\terrors = append(errors, GinkgoErrors.ConflictingVerbosityConfiguration())\n\t}\n\n\treturn errors\n}\n\n// GinkgoCLISharedFlags provides flags shared by the Ginkgo CLI's build, watch, and run commands\nvar GinkgoCLISharedFlags = GinkgoFlags{\n\t{KeyPath: \"C.Recurse\", Name: \"r\", SectionKey: \"multiple-suites\",\n\t\tUsage: \"If set, ginkgo finds and runs test suites under the current directory recursively.\"},\n\t{KeyPath: \"C.SkipPackage\", Name: \"skip-package\", SectionKey: \"multiple-suites\", DeprecatedName: \"skipPackage\", DeprecatedDocLink: \"changed-command-line-flags\",\n\t\tUsageArgument: \"comma-separated list of packages\",\n\t\tUsage:         \"A comma-separated list of package names to be skipped.  If any part of the package's path matches, that package is ignored.\"},\n\t{KeyPath: \"C.RequireSuite\", Name: \"require-suite\", SectionKey: \"failure\", DeprecatedName: \"requireSuite\", DeprecatedDocLink: \"changed-command-line-flags\",\n\t\tUsage: \"If set, Ginkgo fails if there are ginkgo tests in a directory but no invocation of RunSpecs.\"},\n\t{KeyPath: \"C.NumCompilers\", Name: \"compilers\", SectionKey: \"multiple-suites\", UsageDefaultValue: \"0 (will autodetect)\",\n\t\tUsage: \"When running multiple packages, the number of concurrent compilations to perform.\"},\n}\n\n// GinkgoCLIRunAndWatchFlags provides flags shared by the Ginkgo CLI's build and watch commands (but not run)\nvar GinkgoCLIRunAndWatchFlags = GinkgoFlags{\n\t{KeyPath: \"C.Procs\", Name: \"procs\", SectionKey: \"parallel\", UsageDefaultValue: \"1 (run in series)\",\n\t\tUsage: \"The number of parallel test nodes to run.\"},\n\t{KeyPath: \"C.Procs\", Name: \"nodes\", SectionKey: \"parallel\", UsageDefaultValue: \"1 (run in series)\",\n\t\tUsage: \"--nodes is an alias for --procs\"},\n\t{KeyPath: \"C.Parallel\", Name: \"p\", SectionKey: \"parallel\",\n\t\tUsage: \"If set, ginkgo will run in parallel with an auto-detected number of nodes.\"},\n\t{KeyPath: \"C.AfterRunHook\", Name: \"after-run-hook\", SectionKey: \"misc\", DeprecatedName: \"afterSuiteHook\", DeprecatedDocLink: \"changed-command-line-flags\",\n\t\tUsage: \"Command to run when a test suite completes.\"},\n\t{KeyPath: \"C.OutputDir\", Name: \"output-dir\", SectionKey: \"output\", UsageArgument: \"directory\", DeprecatedName: \"outputdir\", DeprecatedDocLink: \"improved-profiling-support\",\n\t\tUsage: \"A location to place all generated profiles and reports.\"},\n\t{KeyPath: \"C.KeepSeparateCoverprofiles\", Name: \"keep-separate-coverprofiles\", SectionKey: \"code-and-coverage-analysis\",\n\t\tUsage: \"If set, Ginkgo does not merge coverprofiles into one monolithic coverprofile.  The coverprofiles will remain in their respective package directories or in -output-dir if set.\"},\n\t{KeyPath: \"C.KeepSeparateReports\", Name: \"keep-separate-reports\", SectionKey: \"output\",\n\t\tUsage: \"If set, Ginkgo does not merge per-suite reports (e.g. -json-report) into one monolithic report for the entire testrun.  The reports will remain in their respective package directories or in -output-dir if set.\"},\n\n\t{KeyPath: \"D.Stream\", DeprecatedName: \"stream\", DeprecatedDocLink: \"removed--stream\", DeprecatedVersion: \"2.0.0\"},\n\t{KeyPath: \"D.Notify\", DeprecatedName: \"notify\", DeprecatedDocLink: \"removed--notify\", DeprecatedVersion: \"2.0.0\"},\n}\n\n// GinkgoCLIRunFlags provides flags for Ginkgo CLI's run command that aren't shared by any other commands\nvar GinkgoCLIRunFlags = GinkgoFlags{\n\t{KeyPath: \"C.KeepGoing\", Name: \"keep-going\", SectionKey: \"multiple-suites\", DeprecatedName: \"keepGoing\", DeprecatedDocLink: \"changed-command-line-flags\",\n\t\tUsage: \"If set, failures from earlier test suites do not prevent later test suites from running.\"},\n\t{KeyPath: \"C.UntilItFails\", Name: \"until-it-fails\", SectionKey: \"debug\", DeprecatedName: \"untilItFails\", DeprecatedDocLink: \"changed-command-line-flags\",\n\t\tUsage: \"If set, ginkgo will keep rerunning test suites until a failure occurs.\"},\n\t{KeyPath: \"C.Repeat\", Name: \"repeat\", SectionKey: \"debug\", UsageArgument: \"n\", UsageDefaultValue: \"0 - i.e. no repetition, run only once\",\n\t\tUsage: \"The number of times to re-run a test-suite.  Useful for debugging flaky tests.  If set to N the suite will be run N+1 times and will be required to pass each time.\"},\n\t{KeyPath: \"C.RandomizeSuites\", Name: \"randomize-suites\", SectionKey: \"order\", DeprecatedName: \"randomizeSuites\", DeprecatedDocLink: \"changed-command-line-flags\",\n\t\tUsage: \"If set, ginkgo will randomize the order in which test suites run.\"},\n}\n\n// GinkgoCLIRunFlags provides flags for Ginkgo CLI's watch command that aren't shared by any other commands\nvar GinkgoCLIWatchFlags = GinkgoFlags{\n\t{KeyPath: \"C.Depth\", Name: \"depth\", SectionKey: \"watch\",\n\t\tUsage: \"Ginkgo will watch dependencies down to this depth in the dependency tree.\"},\n\t{KeyPath: \"C.WatchRegExp\", Name: \"watch-regexp\", SectionKey: \"watch\", DeprecatedName: \"watchRegExp\", DeprecatedDocLink: \"changed-command-line-flags\",\n\t\tUsageArgument:     \"Regular Expression\",\n\t\tUsageDefaultValue: `\\.go$`,\n\t\tUsage:             \"Only files matching this regular expression will be watched for changes.\"},\n}\n\n// GoBuildFlags provides flags for the Ginkgo CLI build, run, and watch commands that capture go's build-time flags.  These are passed to go test -c by the ginkgo CLI\nvar GoBuildFlags = GinkgoFlags{\n\t{KeyPath: \"Go.Race\", Name: \"race\", SectionKey: \"code-and-coverage-analysis\",\n\t\tUsage: \"enable data race detection. Supported on linux/amd64, linux/ppc64le, linux/arm64, linux/s390x, freebsd/amd64, netbsd/amd64, darwin/amd64, darwin/arm64, and windows/amd64.\"},\n\t{KeyPath: \"Go.Vet\", Name: \"vet\", UsageArgument: \"list\", SectionKey: \"code-and-coverage-analysis\",\n\t\tUsage: `Configure the invocation of \"go vet\" during \"go test\" to use the comma-separated list of vet checks.  If list is empty (by explicitly passing --vet=\"\"), \"go test\" runs \"go vet\" with a curated list of checks believed to be always worth addressing.  If list is \"off\", \"go test\" does not run \"go vet\" at all.  Available checks can be found by running 'go doc cmd/vet'`},\n\t{KeyPath: \"Go.Cover\", Name: \"cover\", SectionKey: \"code-and-coverage-analysis\",\n\t\tUsage: \"Enable coverage analysis.\tNote that because coverage works by annotating the source code before compilation, compilation and test failures with coverage enabled may report line numbers that don't correspond to the original sources.\"},\n\t{KeyPath: \"Go.CoverMode\", Name: \"covermode\", UsageArgument: \"set,count,atomic\", SectionKey: \"code-and-coverage-analysis\",\n\t\tUsage: `Set the mode for coverage analysis for the package[s] being tested. 'set': does this statement run? 'count': how many times does this statement run? 'atomic': like count, but correct in multithreaded tests and more expensive (must use atomic with -race). Sets -cover`},\n\t{KeyPath: \"Go.CoverPkg\", Name: \"coverpkg\", UsageArgument: \"pattern1,pattern2,pattern3\", SectionKey: \"code-and-coverage-analysis\",\n\t\tUsage: \"Apply coverage analysis in each test to packages matching the patterns. \tThe default is for each test to analyze only the package being tested. See 'go help packages' for a description of package patterns. Sets -cover.\"},\n\n\t{KeyPath: \"Go.A\", Name: \"a\", SectionKey: \"go-build\",\n\t\tUsage: \"force rebuilding of packages that are already up-to-date.\"},\n\t{KeyPath: \"Go.ASMFlags\", Name: \"asmflags\", UsageArgument: \"'[pattern=]arg list'\", SectionKey: \"go-build\",\n\t\tUsage: \"arguments to pass on each go tool asm invocation.\"},\n\t{KeyPath: \"Go.BuildMode\", Name: \"buildmode\", UsageArgument: \"mode\", SectionKey: \"go-build\",\n\t\tUsage: \"build mode to use. See 'go help buildmode' for more.\"},\n\t{KeyPath: \"Go.BuildVCS\", Name: \"buildvcs\", SectionKey: \"go-build\",\n\t\tUsage: \"adds version control information.\"},\n\t{KeyPath: \"Go.Compiler\", Name: \"compiler\", UsageArgument: \"name\", SectionKey: \"go-build\",\n\t\tUsage: \"name of compiler to use, as in runtime.Compiler (gccgo or gc).\"},\n\t{KeyPath: \"Go.GCCGoFlags\", Name: \"gccgoflags\", UsageArgument: \"'[pattern=]arg list'\", SectionKey: \"go-build\",\n\t\tUsage: \"arguments to pass on each gccgo compiler/linker invocation.\"},\n\t{KeyPath: \"Go.GCFlags\", Name: \"gcflags\", UsageArgument: \"'[pattern=]arg list'\", SectionKey: \"go-build\",\n\t\tUsage: \"arguments to pass on each go tool compile invocation.\"},\n\t{KeyPath: \"Go.InstallSuffix\", Name: \"installsuffix\", SectionKey: \"go-build\",\n\t\tUsage: \"a suffix to use in the name of the package installation directory, in order to keep output separate from default builds. If using the -race flag, the install suffix is automatically set to raceor, if set explicitly, has _race appended to it. Likewise for the -msan flag.  Using a -buildmode option that requires non-default compile flags has a similar effect.\"},\n\t{KeyPath: \"Go.LDFlags\", Name: \"ldflags\", UsageArgument: \"'[pattern=]arg list'\", SectionKey: \"go-build\",\n\t\tUsage: \"arguments to pass on each go tool link invocation.\"},\n\t{KeyPath: \"Go.LinkShared\", Name: \"linkshared\", SectionKey: \"go-build\",\n\t\tUsage: \"build code that will be linked against shared libraries previously created with -buildmode=shared.\"},\n\t{KeyPath: \"Go.Mod\", Name: \"mod\", UsageArgument: \"mode (readonly, vendor, or mod)\", SectionKey: \"go-build\",\n\t\tUsage: \"module download mode to use: readonly, vendor, or mod.  See 'go help modules' for more.\"},\n\t{KeyPath: \"Go.ModCacheRW\", Name: \"modcacherw\", SectionKey: \"go-build\",\n\t\tUsage: \"leave newly-created directories in the module cache read-write instead of making them read-only.\"},\n\t{KeyPath: \"Go.ModFile\", Name: \"modfile\", UsageArgument: \"file\", SectionKey: \"go-build\",\n\t\tUsage: `in module aware mode, read (and possibly write) an alternate go.mod file instead of the one in the module root directory. A file named go.mod must still be present in order to determine the module root directory, but it is not accessed. When -modfile is specified, an alternate go.sum file is also used: its path is derived from the -modfile flag by trimming the \".mod\" extension and appending \".sum\".`},\n\t{KeyPath: \"Go.MSan\", Name: \"msan\", SectionKey: \"go-build\",\n\t\tUsage: \"enable interoperation with memory sanitizer. Supported only on linux/amd64, linux/arm64 and only with Clang/LLVM as the host C compiler. On linux/arm64, pie build mode will be used.\"},\n\t{KeyPath: \"Go.N\", Name: \"n\", SectionKey: \"go-build\",\n\t\tUsage: \"print the commands but do not run them.\"},\n\t{KeyPath: \"Go.PkgDir\", Name: \"pkgdir\", UsageArgument: \"dir\", SectionKey: \"go-build\",\n\t\tUsage: \"install and load all packages from dir instead of the usual locations. For example, when building with a non-standard configuration, use -pkgdir to keep generated packages in a separate location.\"},\n\t{KeyPath: \"Go.Tags\", Name: \"tags\", UsageArgument: \"tag,list\", SectionKey: \"go-build\",\n\t\tUsage: \"a comma-separated list of build tags to consider satisfied during the build. For more information about build tags, see the description of build constraints in the documentation for the go/build package. (Earlier versions of Go used a space-separated list, and that form is deprecated but still recognized.)\"},\n\t{KeyPath: \"Go.TrimPath\", Name: \"trimpath\", SectionKey: \"go-build\",\n\t\tUsage: `remove all file system paths from the resulting executable. Instead of absolute file system paths, the recorded file names will begin with either \"go\" (for the standard library), or a module path@version (when using modules), or a plain import path (when using GOPATH).`},\n\t{KeyPath: \"Go.ToolExec\", Name: \"toolexec\", UsageArgument: \"'cmd args'\", SectionKey: \"go-build\",\n\t\tUsage: \"a program to use to invoke toolchain programs like vet and asm. For example, instead of running asm, the go command will run cmd args /path/to/asm <arguments for asm>'.\"},\n\t{KeyPath: \"Go.Work\", Name: \"work\", SectionKey: \"go-build\",\n\t\tUsage: \"print the name of the temporary work directory and do not delete it when exiting.\"},\n\t{KeyPath: \"Go.X\", Name: \"x\", SectionKey: \"go-build\",\n\t\tUsage: \"print the commands.\"},\n\t{KeyPath: \"Go.O\", Name: \"o\", SectionKey: \"go-build\",\n\t\tUsage: \"output binary path (including name).\"},\n}\n\n// GoRunFlags provides flags for the Ginkgo CLI  run, and watch commands that capture go's run-time flags.  These are passed to the compiled test binary by the ginkgo CLI\nvar GoRunFlags = GinkgoFlags{\n\t{KeyPath: \"Go.CoverProfile\", Name: \"coverprofile\", UsageArgument: \"file\", SectionKey: \"code-and-coverage-analysis\",\n\t\tUsage: `Write a coverage profile to the file after all tests have passed. Sets -cover.  Must be passed a filename, not a path.  Use output-dir to control the location of the output.`},\n\t{KeyPath: \"Go.BlockProfile\", Name: \"blockprofile\", UsageArgument: \"file\", SectionKey: \"performance-analysis\",\n\t\tUsage: `Write a goroutine blocking profile to the specified file when all tests are complete. Preserves test binary.`},\n\t{KeyPath: \"Go.BlockProfileRate\", Name: \"blockprofilerate\", UsageArgument: \"rate\", SectionKey: \"performance-analysis\",\n\t\tUsage: `Control the detail provided in goroutine blocking profiles by calling runtime.SetBlockProfileRate with rate. See 'go doc runtime.SetBlockProfileRate'. The profiler aims to sample, on average, one blocking event every n nanoseconds the program spends blocked. By default, if -test.blockprofile is set without this flag, all blocking events are recorded, equivalent to -test.blockprofilerate=1.`},\n\t{KeyPath: \"Go.CPUProfile\", Name: \"cpuprofile\", UsageArgument: \"file\", SectionKey: \"performance-analysis\",\n\t\tUsage: `Write a CPU profile to the specified file before exiting. Preserves test binary.`},\n\t{KeyPath: \"Go.MemProfile\", Name: \"memprofile\", UsageArgument: \"file\", SectionKey: \"performance-analysis\",\n\t\tUsage: `Write an allocation profile to the file after all tests have passed. Preserves test binary.`},\n\t{KeyPath: \"Go.MemProfileRate\", Name: \"memprofilerate\", UsageArgument: \"rate\", SectionKey: \"performance-analysis\",\n\t\tUsage: `Enable more precise (and expensive) memory allocation profiles by setting runtime.MemProfileRate. See 'go doc runtime.MemProfileRate'. To profile all memory allocations, use -test.memprofilerate=1.`},\n\t{KeyPath: \"Go.MutexProfile\", Name: \"mutexprofile\", UsageArgument: \"file\", SectionKey: \"performance-analysis\",\n\t\tUsage: `Write a mutex contention profile to the specified file when all tests are complete. Preserves test binary.`},\n\t{KeyPath: \"Go.MutexProfileFraction\", Name: \"mutexprofilefraction\", UsageArgument: \"n\", SectionKey: \"performance-analysis\",\n\t\tUsage: `if >= 0, calls runtime.SetMutexProfileFraction()\tSample 1 in n stack traces of goroutines holding a contended mutex.`},\n\t{KeyPath: \"Go.Trace\", Name: \"execution-trace\", UsageArgument: \"file\", ExportAs: \"trace\", SectionKey: \"performance-analysis\",\n\t\tUsage: `Write an execution trace to the specified file before exiting.`},\n}\n\n// VetAndInitializeCLIAndGoConfig validates that the Ginkgo CLI's configuration is sound\n// It returns a potentially mutated copy of the config that rationalizes the configuration to ensure consistency for downstream consumers\nfunc VetAndInitializeCLIAndGoConfig(cliConfig CLIConfig, goFlagsConfig GoFlagsConfig) (CLIConfig, GoFlagsConfig, []error) {\n\terrors := []error{}\n\n\tif cliConfig.Repeat > 0 && cliConfig.UntilItFails {\n\t\terrors = append(errors, GinkgoErrors.BothRepeatAndUntilItFails())\n\t}\n\n\tif strings.ContainsRune(goFlagsConfig.CoverProfile, os.PathSeparator) {\n\t\terrors = append(errors, GinkgoErrors.ExpectFilenameNotPath(\"--coverprofile\", goFlagsConfig.CoverProfile))\n\t}\n\tif strings.ContainsRune(goFlagsConfig.CPUProfile, os.PathSeparator) {\n\t\terrors = append(errors, GinkgoErrors.ExpectFilenameNotPath(\"--cpuprofile\", goFlagsConfig.CPUProfile))\n\t}\n\tif strings.ContainsRune(goFlagsConfig.MemProfile, os.PathSeparator) {\n\t\terrors = append(errors, GinkgoErrors.ExpectFilenameNotPath(\"--memprofile\", goFlagsConfig.MemProfile))\n\t}\n\tif strings.ContainsRune(goFlagsConfig.BlockProfile, os.PathSeparator) {\n\t\terrors = append(errors, GinkgoErrors.ExpectFilenameNotPath(\"--blockprofile\", goFlagsConfig.BlockProfile))\n\t}\n\tif strings.ContainsRune(goFlagsConfig.MutexProfile, os.PathSeparator) {\n\t\terrors = append(errors, GinkgoErrors.ExpectFilenameNotPath(\"--mutexprofile\", goFlagsConfig.MutexProfile))\n\t}\n\n\t//initialize the output directory\n\tif cliConfig.OutputDir != \"\" {\n\t\terr := os.MkdirAll(cliConfig.OutputDir, 0777)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\n\t//ensure cover mode is configured appropriately\n\tif goFlagsConfig.CoverMode != \"\" || goFlagsConfig.CoverPkg != \"\" || goFlagsConfig.CoverProfile != \"\" {\n\t\tgoFlagsConfig.Cover = true\n\t}\n\tif goFlagsConfig.Cover && goFlagsConfig.CoverProfile == \"\" {\n\t\tgoFlagsConfig.CoverProfile = \"coverprofile.out\"\n\t}\n\n\treturn cliConfig, goFlagsConfig, errors\n}\n\n// GenerateGoTestCompileArgs is used by the Ginkgo CLI to generate command line arguments to pass to the go test -c command when compiling the test\nfunc GenerateGoTestCompileArgs(goFlagsConfig GoFlagsConfig, packageToBuild string, pathToInvocationPath string, preserveSymbols bool) ([]string, error) {\n\t// if the user has set the CoverProfile run-time flag make sure to set the build-time cover flag to make sure\n\t// the built test binary can generate a coverprofile\n\tif goFlagsConfig.CoverProfile != \"\" {\n\t\tgoFlagsConfig.Cover = true\n\t}\n\n\tif goFlagsConfig.CoverPkg != \"\" {\n\t\tcoverPkgs := strings.Split(goFlagsConfig.CoverPkg, \",\")\n\t\tadjustedCoverPkgs := make([]string, len(coverPkgs))\n\t\tfor i, coverPkg := range coverPkgs {\n\t\t\tcoverPkg = strings.Trim(coverPkg, \" \")\n\t\t\tif strings.HasPrefix(coverPkg, \"./\") {\n\t\t\t\t// this is a relative coverPkg - we need to reroot it\n\t\t\t\tadjustedCoverPkgs[i] = \"./\" + filepath.Join(pathToInvocationPath, strings.TrimPrefix(coverPkg, \"./\"))\n\t\t\t} else {\n\t\t\t\t// this is a package name - don't touch it\n\t\t\t\tadjustedCoverPkgs[i] = coverPkg\n\t\t\t}\n\t\t}\n\t\tgoFlagsConfig.CoverPkg = strings.Join(adjustedCoverPkgs, \",\")\n\t}\n\n\tif !goFlagsConfig.NeedsSymbols() && goFlagsConfig.LDFlags == \"\" && !preserveSymbols {\n\t\tgoFlagsConfig.LDFlags = \"-w -s\"\n\t}\n\n\targs := []string{\"test\", \"-c\", packageToBuild}\n\tgoArgs, err := GenerateFlagArgs(\n\t\tGoBuildFlags,\n\t\tmap[string]any{\n\t\t\t\"Go\": &goFlagsConfig,\n\t\t},\n\t)\n\n\tif err != nil {\n\t\treturn []string{}, err\n\t}\n\targs = append(args, goArgs...)\n\treturn args, nil\n}\n\n// GenerateGinkgoTestRunArgs is used by the Ginkgo CLI to generate command line arguments to pass to the compiled Ginkgo test binary\nfunc GenerateGinkgoTestRunArgs(suiteConfig SuiteConfig, reporterConfig ReporterConfig, goFlagsConfig GoFlagsConfig) ([]string, error) {\n\tvar flags GinkgoFlags\n\tflags = SuiteConfigFlags.WithPrefix(\"ginkgo\")\n\tflags = flags.CopyAppend(ParallelConfigFlags.WithPrefix(\"ginkgo\")...)\n\tflags = flags.CopyAppend(ReporterConfigFlags.WithPrefix(\"ginkgo\")...)\n\tflags = flags.CopyAppend(GoRunFlags.WithPrefix(\"test\")...)\n\tbindings := map[string]any{\n\t\t\"S\":  &suiteConfig,\n\t\t\"R\":  &reporterConfig,\n\t\t\"Go\": &goFlagsConfig,\n\t}\n\n\treturn GenerateFlagArgs(flags, bindings)\n}\n\n// GenerateGoTestRunArgs is used by the Ginkgo CLI to generate command line arguments to pass to the compiled non-Ginkgo test binary\nfunc GenerateGoTestRunArgs(goFlagsConfig GoFlagsConfig) ([]string, error) {\n\tflags := GoRunFlags.WithPrefix(\"test\")\n\tbindings := map[string]any{\n\t\t\"Go\": &goFlagsConfig,\n\t}\n\n\targs, err := GenerateFlagArgs(flags, bindings)\n\tif err != nil {\n\t\treturn args, err\n\t}\n\targs = append(args, \"--test.v\")\n\treturn args, nil\n}\n\n// BuildRunCommandFlagSet builds the FlagSet for the `ginkgo run` command\nfunc BuildRunCommandFlagSet(suiteConfig *SuiteConfig, reporterConfig *ReporterConfig, cliConfig *CLIConfig, goFlagsConfig *GoFlagsConfig) (GinkgoFlagSet, error) {\n\tflags := SuiteConfigFlags\n\tflags = flags.CopyAppend(ReporterConfigFlags...)\n\tflags = flags.CopyAppend(GinkgoCLISharedFlags...)\n\tflags = flags.CopyAppend(GinkgoCLIRunAndWatchFlags...)\n\tflags = flags.CopyAppend(GinkgoCLIRunFlags...)\n\tflags = flags.CopyAppend(GoBuildFlags...)\n\tflags = flags.CopyAppend(GoRunFlags...)\n\n\tbindings := map[string]any{\n\t\t\"S\":  suiteConfig,\n\t\t\"R\":  reporterConfig,\n\t\t\"C\":  cliConfig,\n\t\t\"Go\": goFlagsConfig,\n\t\t\"D\":  &deprecatedConfig{},\n\t}\n\n\treturn NewGinkgoFlagSet(flags, bindings, FlagSections)\n}\n\n// BuildWatchCommandFlagSet builds the FlagSet for the `ginkgo watch` command\nfunc BuildWatchCommandFlagSet(suiteConfig *SuiteConfig, reporterConfig *ReporterConfig, cliConfig *CLIConfig, goFlagsConfig *GoFlagsConfig) (GinkgoFlagSet, error) {\n\tflags := SuiteConfigFlags\n\tflags = flags.CopyAppend(ReporterConfigFlags...)\n\tflags = flags.CopyAppend(GinkgoCLISharedFlags...)\n\tflags = flags.CopyAppend(GinkgoCLIRunAndWatchFlags...)\n\tflags = flags.CopyAppend(GinkgoCLIWatchFlags...)\n\tflags = flags.CopyAppend(GoBuildFlags...)\n\tflags = flags.CopyAppend(GoRunFlags...)\n\n\tbindings := map[string]any{\n\t\t\"S\":  suiteConfig,\n\t\t\"R\":  reporterConfig,\n\t\t\"C\":  cliConfig,\n\t\t\"Go\": goFlagsConfig,\n\t\t\"D\":  &deprecatedConfig{},\n\t}\n\n\treturn NewGinkgoFlagSet(flags, bindings, FlagSections)\n}\n\n// BuildBuildCommandFlagSet builds the FlagSet for the `ginkgo build` command\nfunc BuildBuildCommandFlagSet(cliConfig *CLIConfig, goFlagsConfig *GoFlagsConfig) (GinkgoFlagSet, error) {\n\tflags := GinkgoCLISharedFlags\n\tflags = flags.CopyAppend(GoBuildFlags...)\n\n\tbindings := map[string]any{\n\t\t\"C\":  cliConfig,\n\t\t\"Go\": goFlagsConfig,\n\t\t\"D\":  &deprecatedConfig{},\n\t}\n\n\tflagSections := make(GinkgoFlagSections, len(FlagSections))\n\tcopy(flagSections, FlagSections)\n\tfor i := range flagSections {\n\t\tif flagSections[i].Key == \"multiple-suites\" {\n\t\t\tflagSections[i].Heading = \"Building Multiple Suites\"\n\t\t}\n\t\tif flagSections[i].Key == \"go-build\" {\n\t\t\tflagSections[i] = GinkgoFlagSection{Key: \"go-build\", Style: \"{{/}}\", Heading: \"Go Build Flags\",\n\t\t\t\tDescription: \"These flags are inherited from go build.\"}\n\t\t}\n\t}\n\n\treturn NewGinkgoFlagSet(flags, bindings, flagSections)\n}\n\nfunc BuildLabelsCommandFlagSet(cliConfig *CLIConfig) (GinkgoFlagSet, error) {\n\tflags := GinkgoCLISharedFlags.SubsetWithNames(\"r\", \"skip-package\")\n\n\tbindings := map[string]any{\n\t\t\"C\": cliConfig,\n\t}\n\n\tflagSections := make(GinkgoFlagSections, len(FlagSections))\n\tcopy(flagSections, FlagSections)\n\tfor i := range flagSections {\n\t\tif flagSections[i].Key == \"multiple-suites\" {\n\t\t\tflagSections[i].Heading = \"Fetching Labels from Multiple Suites\"\n\t\t}\n\t}\n\n\treturn NewGinkgoFlagSet(flags, bindings, flagSections)\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/types/deprecated_types.go",
    "content": "package types\n\nimport (\n\t\"strconv\"\n\t\"time\"\n)\n\n/*\n\tA set of deprecations to make the transition from v1 to v2 easier for users who have written custom reporters.\n*/\n\ntype SuiteSummary = DeprecatedSuiteSummary\ntype SetupSummary = DeprecatedSetupSummary\ntype SpecSummary = DeprecatedSpecSummary\ntype SpecMeasurement = DeprecatedSpecMeasurement\ntype SpecComponentType = NodeType\ntype SpecFailure = DeprecatedSpecFailure\n\nvar (\n\tSpecComponentTypeInvalid                 = NodeTypeInvalid\n\tSpecComponentTypeContainer               = NodeTypeContainer\n\tSpecComponentTypeIt                      = NodeTypeIt\n\tSpecComponentTypeBeforeEach              = NodeTypeBeforeEach\n\tSpecComponentTypeJustBeforeEach          = NodeTypeJustBeforeEach\n\tSpecComponentTypeAfterEach               = NodeTypeAfterEach\n\tSpecComponentTypeJustAfterEach           = NodeTypeJustAfterEach\n\tSpecComponentTypeBeforeSuite             = NodeTypeBeforeSuite\n\tSpecComponentTypeSynchronizedBeforeSuite = NodeTypeSynchronizedBeforeSuite\n\tSpecComponentTypeAfterSuite              = NodeTypeAfterSuite\n\tSpecComponentTypeSynchronizedAfterSuite  = NodeTypeSynchronizedAfterSuite\n)\n\ntype DeprecatedSuiteSummary struct {\n\tSuiteDescription string\n\tSuiteSucceeded   bool\n\tSuiteID          string\n\n\tNumberOfSpecsBeforeParallelization int\n\tNumberOfTotalSpecs                 int\n\tNumberOfSpecsThatWillBeRun         int\n\tNumberOfPendingSpecs               int\n\tNumberOfSkippedSpecs               int\n\tNumberOfPassedSpecs                int\n\tNumberOfFailedSpecs                int\n\tNumberOfFlakedSpecs                int\n\tRunTime                            time.Duration\n}\n\ntype DeprecatedSetupSummary struct {\n\tComponentType SpecComponentType\n\tCodeLocation  CodeLocation\n\n\tState   SpecState\n\tRunTime time.Duration\n\tFailure SpecFailure\n\n\tCapturedOutput string\n\tSuiteID        string\n}\n\ntype DeprecatedSpecSummary struct {\n\tComponentTexts         []string\n\tComponentCodeLocations []CodeLocation\n\n\tState           SpecState\n\tRunTime         time.Duration\n\tFailure         SpecFailure\n\tIsMeasurement   bool\n\tNumberOfSamples int\n\tMeasurements    map[string]*DeprecatedSpecMeasurement\n\n\tCapturedOutput string\n\tSuiteID        string\n}\n\nfunc (s DeprecatedSpecSummary) HasFailureState() bool {\n\treturn s.State.Is(SpecStateFailureStates)\n}\n\nfunc (s DeprecatedSpecSummary) TimedOut() bool {\n\treturn false\n}\n\nfunc (s DeprecatedSpecSummary) Panicked() bool {\n\treturn s.State == SpecStatePanicked\n}\n\nfunc (s DeprecatedSpecSummary) Failed() bool {\n\treturn s.State == SpecStateFailed\n}\n\nfunc (s DeprecatedSpecSummary) Passed() bool {\n\treturn s.State == SpecStatePassed\n}\n\nfunc (s DeprecatedSpecSummary) Skipped() bool {\n\treturn s.State == SpecStateSkipped\n}\n\nfunc (s DeprecatedSpecSummary) Pending() bool {\n\treturn s.State == SpecStatePending\n}\n\ntype DeprecatedSpecFailure struct {\n\tMessage        string\n\tLocation       CodeLocation\n\tForwardedPanic string\n\n\tComponentIndex        int\n\tComponentType         SpecComponentType\n\tComponentCodeLocation CodeLocation\n}\n\ntype DeprecatedSpecMeasurement struct {\n\tName  string\n\tInfo  any\n\tOrder int\n\n\tResults []float64\n\n\tSmallest     float64\n\tLargest      float64\n\tAverage      float64\n\tStdDeviation float64\n\n\tSmallestLabel string\n\tLargestLabel  string\n\tAverageLabel  string\n\tUnits         string\n\tPrecision     int\n}\n\nfunc (s DeprecatedSpecMeasurement) PrecisionFmt() string {\n\tif s.Precision == 0 {\n\t\treturn \"%f\"\n\t}\n\n\tstr := strconv.Itoa(s.Precision)\n\n\treturn \"%.\" + str + \"f\"\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/types/deprecation_support.go",
    "content": "package types\n\nimport (\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"unicode\"\n\n\t\"github.com/onsi/ginkgo/v2/formatter\"\n)\n\ntype Deprecation struct {\n\tMessage string\n\tDocLink string\n\tVersion string\n}\n\ntype deprecations struct{}\n\nvar Deprecations = deprecations{}\n\nfunc (d deprecations) CustomReporter() Deprecation {\n\treturn Deprecation{\n\t\tMessage: \"Support for custom reporters has been removed in V2.  Please read the documentation linked to below for Ginkgo's new behavior and for a migration path:\",\n\t\tDocLink: \"removed-custom-reporters\",\n\t\tVersion: \"1.16.0\",\n\t}\n}\n\nfunc (d deprecations) Async() Deprecation {\n\treturn Deprecation{\n\t\tMessage: \"You are passing a Done channel to a test node to test asynchronous behavior.  This is deprecated in Ginkgo V2.  Your test will run synchronously and the timeout will be ignored.\",\n\t\tDocLink: \"removed-async-testing\",\n\t\tVersion: \"1.16.0\",\n\t}\n}\n\nfunc (d deprecations) Measure() Deprecation {\n\treturn Deprecation{\n\t\tMessage: \"Measure is deprecated and has been removed from Ginkgo V2.  Any Measure tests in your spec will not run.  Please migrate to gomega/gmeasure.\",\n\t\tDocLink: \"removed-measure\",\n\t\tVersion: \"1.16.3\",\n\t}\n}\n\nfunc (d deprecations) ParallelNode() Deprecation {\n\treturn Deprecation{\n\t\tMessage: \"GinkgoParallelNode is deprecated and will be removed in Ginkgo V2.  Please use GinkgoParallelProcess instead.\",\n\t\tDocLink: \"renamed-ginkgoparallelnode\",\n\t\tVersion: \"1.16.4\",\n\t}\n}\n\nfunc (d deprecations) CurrentGinkgoTestDescription() Deprecation {\n\treturn Deprecation{\n\t\tMessage: \"CurrentGinkgoTestDescription() is deprecated in Ginkgo V2.  Use CurrentSpecReport() instead.\",\n\t\tDocLink: \"changed-currentginkgotestdescription\",\n\t\tVersion: \"1.16.0\",\n\t}\n}\n\nfunc (d deprecations) Convert() Deprecation {\n\treturn Deprecation{\n\t\tMessage: \"The convert command is deprecated in Ginkgo V2\",\n\t\tDocLink: \"removed-ginkgo-convert\",\n\t\tVersion: \"1.16.0\",\n\t}\n}\n\nfunc (d deprecations) Blur() Deprecation {\n\treturn Deprecation{\n\t\tMessage: \"The blur command is deprecated in Ginkgo V2.  Use 'ginkgo unfocus' instead.\",\n\t\tVersion: \"1.16.0\",\n\t}\n}\n\nfunc (d deprecations) Nodot() Deprecation {\n\treturn Deprecation{\n\t\tMessage: \"The nodot command is deprecated in Ginkgo V2.  Please either dot-import Ginkgo or use the package identifier in your code to references objects and types provided by Ginkgo and Gomega.\",\n\t\tDocLink: \"removed-ginkgo-nodot\",\n\t\tVersion: \"1.16.0\",\n\t}\n}\n\nfunc (d deprecations) SuppressProgressReporting() Deprecation {\n\treturn Deprecation{\n\t\tMessage: \"Improvements to how reporters emit timeline information means that SuppressProgressReporting is no longer necessary and has been deprecated.\",\n\t\tVersion: \"2.5.0\",\n\t}\n}\n\ntype DeprecationTracker struct {\n\tdeprecations map[Deprecation][]CodeLocation\n\tlock         *sync.Mutex\n}\n\nfunc NewDeprecationTracker() *DeprecationTracker {\n\treturn &DeprecationTracker{\n\t\tdeprecations: map[Deprecation][]CodeLocation{},\n\t\tlock:         &sync.Mutex{},\n\t}\n}\n\nfunc (d *DeprecationTracker) TrackDeprecation(deprecation Deprecation, cl ...CodeLocation) {\n\tackVersion := os.Getenv(\"ACK_GINKGO_DEPRECATIONS\")\n\tif deprecation.Version != \"\" && ackVersion != \"\" {\n\t\tack := ParseSemVer(ackVersion)\n\t\tversion := ParseSemVer(deprecation.Version)\n\t\tif ack.GreaterThanOrEqualTo(version) {\n\t\t\treturn\n\t\t}\n\t}\n\n\td.lock.Lock()\n\tdefer d.lock.Unlock()\n\tif len(cl) == 1 {\n\t\td.deprecations[deprecation] = append(d.deprecations[deprecation], cl[0])\n\t} else {\n\t\td.deprecations[deprecation] = []CodeLocation{}\n\t}\n}\n\nfunc (d *DeprecationTracker) DidTrackDeprecations() bool {\n\td.lock.Lock()\n\tdefer d.lock.Unlock()\n\treturn len(d.deprecations) > 0\n}\n\nfunc (d *DeprecationTracker) DeprecationsReport() string {\n\td.lock.Lock()\n\tdefer d.lock.Unlock()\n\tout := formatter.F(\"{{light-yellow}}You're using deprecated Ginkgo functionality:{{/}}\\n\")\n\tout += formatter.F(\"{{light-yellow}}============================================={{/}}\\n\")\n\tfor deprecation, locations := range d.deprecations {\n\t\tout += formatter.Fi(1, \"{{yellow}}\"+deprecation.Message+\"{{/}}\\n\")\n\t\tif deprecation.DocLink != \"\" {\n\t\t\tout += formatter.Fi(1, \"{{bold}}Learn more at:{{/}} {{cyan}}{{underline}}https://onsi.github.io/ginkgo/MIGRATING_TO_V2#%s{{/}}\\n\", deprecation.DocLink)\n\t\t}\n\t\tfor _, location := range locations {\n\t\t\tout += formatter.Fi(2, \"{{gray}}%s{{/}}\\n\", location)\n\t\t}\n\t}\n\tout += formatter.F(\"\\n{{gray}}To silence deprecations that can be silenced set the following environment variable:{{/}}\\n\")\n\tout += formatter.Fi(1, \"{{gray}}ACK_GINKGO_DEPRECATIONS=%s{{/}}\\n\", VERSION)\n\treturn out\n}\n\ntype SemVer struct {\n\tMajor int\n\tMinor int\n\tPatch int\n}\n\nfunc (s SemVer) GreaterThanOrEqualTo(o SemVer) bool {\n\treturn (s.Major > o.Major) ||\n\t\t(s.Major == o.Major && s.Minor > o.Minor) ||\n\t\t(s.Major == o.Major && s.Minor == o.Minor && s.Patch >= o.Patch)\n}\n\nfunc ParseSemVer(semver string) SemVer {\n\tout := SemVer{}\n\tsemver = strings.TrimFunc(semver, func(r rune) bool {\n\t\treturn !(unicode.IsNumber(r) || r == '.')\n\t})\n\tcomponents := strings.Split(semver, \".\")\n\tif len(components) > 0 {\n\t\tout.Major, _ = strconv.Atoi(components[0])\n\t}\n\tif len(components) > 1 {\n\t\tout.Minor, _ = strconv.Atoi(components[1])\n\t}\n\tif len(components) > 2 {\n\t\tout.Patch, _ = strconv.Atoi(components[2])\n\t}\n\treturn out\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/types/enum_support.go",
    "content": "package types\n\nimport \"encoding/json\"\n\ntype EnumSupport struct {\n\ttoString map[uint]string\n\ttoEnum   map[string]uint\n\tmaxEnum  uint\n}\n\nfunc NewEnumSupport(toString map[uint]string) EnumSupport {\n\ttoEnum, maxEnum := map[string]uint{}, uint(0)\n\tfor k, v := range toString {\n\t\ttoEnum[v] = k\n\t\tif maxEnum < k {\n\t\t\tmaxEnum = k\n\t\t}\n\t}\n\treturn EnumSupport{toString: toString, toEnum: toEnum, maxEnum: maxEnum}\n}\n\nfunc (es EnumSupport) String(e uint) string {\n\tif e > es.maxEnum {\n\t\treturn es.toString[0]\n\t}\n\treturn es.toString[e]\n}\n\nfunc (es EnumSupport) UnmarshJSON(b []byte) (uint, error) {\n\tvar dec string\n\tif err := json.Unmarshal(b, &dec); err != nil {\n\t\treturn 0, err\n\t}\n\tout := es.toEnum[dec] // if we miss we get 0 which is what we want anyway\n\treturn out, nil\n}\n\nfunc (es EnumSupport) MarshJSON(e uint) ([]byte, error) {\n\tif e == 0 || e > es.maxEnum {\n\t\treturn json.Marshal(nil)\n\t}\n\treturn json.Marshal(es.toString[e])\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/types/errors.go",
    "content": "package types\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"github.com/onsi/ginkgo/v2/formatter\"\n)\n\ntype GinkgoError struct {\n\tHeading      string\n\tMessage      string\n\tDocLink      string\n\tCodeLocation CodeLocation\n}\n\nfunc (g GinkgoError) Error() string {\n\tout := formatter.F(\"{{bold}}{{red}}%s{{/}}\\n\", g.Heading)\n\tif (g.CodeLocation != CodeLocation{}) {\n\t\tcontentsOfLine := strings.TrimLeft(g.CodeLocation.ContentsOfLine(), \"\\t \")\n\t\tif contentsOfLine != \"\" {\n\t\t\tout += formatter.F(\"{{light-gray}}%s{{/}}\\n\", contentsOfLine)\n\t\t}\n\t\tout += formatter.F(\"{{gray}}%s{{/}}\\n\", g.CodeLocation)\n\t}\n\tif g.Message != \"\" {\n\t\tout += formatter.Fiw(1, formatter.COLS, g.Message)\n\t\tout += \"\\n\\n\"\n\t}\n\tif g.DocLink != \"\" {\n\t\tout += formatter.Fiw(1, formatter.COLS, \"{{bold}}Learn more at:{{/}} {{cyan}}{{underline}}http://onsi.github.io/ginkgo/#%s{{/}}\\n\", g.DocLink)\n\t}\n\n\treturn out\n}\n\ntype ginkgoErrors struct{}\n\nvar GinkgoErrors = ginkgoErrors{}\n\nfunc (g ginkgoErrors) UncaughtGinkgoPanic(cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading: \"Your Test Panicked\",\n\t\tMessage: `When you, or your assertion library, calls Ginkgo's Fail(),\nGinkgo panics to prevent subsequent assertions from running.\n\nNormally Ginkgo rescues this panic so you shouldn't see it.\n\nHowever, if you make an assertion in a goroutine, Ginkgo can't capture the panic.\nTo circumvent this, you should call\n\n\tdefer GinkgoRecover()\n\nat the top of the goroutine that caused this panic.\n\nAlternatively, you may have made an assertion outside of a Ginkgo\nleaf node (e.g. in a container node or some out-of-band function) - please move your assertion to\nan appropriate Ginkgo node (e.g. a BeforeSuite, BeforeEach, It, etc...).`,\n\t\tDocLink:      \"mental-model-how-ginkgo-handles-failure\",\n\t\tCodeLocation: cl,\n\t}\n}\n\nfunc (g ginkgoErrors) RerunningSuite() error {\n\treturn GinkgoError{\n\t\tHeading: \"Rerunning Suite\",\n\t\tMessage: formatter.F(`It looks like you are calling RunSpecs more than once. Ginkgo does not support rerunning suites.  If you want to rerun a suite try {{bold}}ginkgo --repeat=N{{/}} or {{bold}}ginkgo --until-it-fails{{/}}`),\n\t\tDocLink: \"repeating-spec-runs-and-managing-flaky-specs\",\n\t}\n}\n\n/* Tree construction errors */\n\nfunc (g ginkgoErrors) PushingNodeInRunPhase(nodeType NodeType, cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading: \"Ginkgo detected an issue with your spec structure\",\n\t\tMessage: formatter.F(\n\t\t\t`It looks like you are trying to add a {{bold}}[%s]{{/}} node\nto the Ginkgo spec tree in a leaf node {{bold}}after{{/}} the specs started running.\n\nTo enable randomization and parallelization Ginkgo requires the spec tree\nto be fully constructed up front.  In practice, this means that you can\nonly create nodes like {{bold}}[%s]{{/}} at the top-level or within the\nbody of a {{bold}}Describe{{/}}, {{bold}}Context{{/}}, or {{bold}}When{{/}}.`, nodeType, nodeType),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"mental-model-how-ginkgo-traverses-the-spec-hierarchy\",\n\t}\n}\n\nfunc (g ginkgoErrors) CaughtPanicDuringABuildPhase(caughtPanic any, cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading: \"Assertion or Panic detected during tree construction\",\n\t\tMessage: formatter.F(\n\t\t\t`Ginkgo detected a panic while constructing the spec tree.\nYou may be trying to make an assertion in the body of a container node\n(i.e. {{bold}}Describe{{/}}, {{bold}}Context{{/}}, or {{bold}}When{{/}}).\n\nPlease ensure all assertions are inside leaf nodes such as {{bold}}BeforeEach{{/}},\n{{bold}}It{{/}}, etc.\n\n{{bold}}Here's the content of the panic that was caught:{{/}}\n%v`, caughtPanic),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"no-assertions-in-container-nodes\",\n\t}\n}\n\nfunc (g ginkgoErrors) SuiteNodeInNestedContext(nodeType NodeType, cl CodeLocation) error {\n\tdocLink := \"suite-setup-and-cleanup-beforesuite-and-aftersuite\"\n\tif nodeType.Is(NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite) {\n\t\tdocLink = \"reporting-nodes---reportbeforesuite-and-reportaftersuite\"\n\t}\n\n\treturn GinkgoError{\n\t\tHeading: \"Ginkgo detected an issue with your spec structure\",\n\t\tMessage: formatter.F(\n\t\t\t`It looks like you are trying to add a {{bold}}[%s]{{/}} node within a container node.\n\n{{bold}}%s{{/}} can only be called at the top level.`, nodeType, nodeType),\n\t\tCodeLocation: cl,\n\t\tDocLink:      docLink,\n\t}\n}\n\nfunc (g ginkgoErrors) SuiteNodeDuringRunPhase(nodeType NodeType, cl CodeLocation) error {\n\tdocLink := \"suite-setup-and-cleanup-beforesuite-and-aftersuite\"\n\tif nodeType.Is(NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite) {\n\t\tdocLink = \"reporting-nodes---reportbeforesuite-and-reportaftersuite\"\n\t}\n\n\treturn GinkgoError{\n\t\tHeading: \"Ginkgo detected an issue with your spec structure\",\n\t\tMessage: formatter.F(\n\t\t\t`It looks like you are trying to add a {{bold}}[%s]{{/}} node within a leaf node after the spec started running.\n\n{{bold}}%s{{/}} can only be called at the top level.`, nodeType, nodeType),\n\t\tCodeLocation: cl,\n\t\tDocLink:      docLink,\n\t}\n}\n\nfunc (g ginkgoErrors) MultipleBeforeSuiteNodes(nodeType NodeType, cl CodeLocation, earlierNodeType NodeType, earlierCodeLocation CodeLocation) error {\n\treturn ginkgoErrorMultipleSuiteNodes(\"setup\", nodeType, cl, earlierNodeType, earlierCodeLocation)\n}\n\nfunc (g ginkgoErrors) MultipleAfterSuiteNodes(nodeType NodeType, cl CodeLocation, earlierNodeType NodeType, earlierCodeLocation CodeLocation) error {\n\treturn ginkgoErrorMultipleSuiteNodes(\"teardown\", nodeType, cl, earlierNodeType, earlierCodeLocation)\n}\n\nfunc ginkgoErrorMultipleSuiteNodes(setupOrTeardown string, nodeType NodeType, cl CodeLocation, earlierNodeType NodeType, earlierCodeLocation CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading: \"Ginkgo detected an issue with your spec structure\",\n\t\tMessage: formatter.F(\n\t\t\t`It looks like you are trying to add a {{bold}}[%s]{{/}} node but\nyou already have a {{bold}}[%s]{{/}} node defined at: {{gray}}%s{{/}}.\n\nGinkgo only allows you to define one suite %s node.`, nodeType, earlierNodeType, earlierCodeLocation, setupOrTeardown),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"suite-setup-and-cleanup-beforesuite-and-aftersuite\",\n\t}\n}\n\n/* Decorator errors */\nfunc (g ginkgoErrors) InvalidDecoratorForNodeType(cl CodeLocation, nodeType NodeType, decorator string) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Invalid Decorator\",\n\t\tMessage:      formatter.F(`[%s] node cannot be passed a(n) '%s' decorator`, nodeType, decorator),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"node-decorators-overview\",\n\t}\n}\n\nfunc (g ginkgoErrors) InvalidDeclarationOfFocusedAndPending(cl CodeLocation, nodeType NodeType) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Invalid Combination of Decorators: Focused and Pending\",\n\t\tMessage:      formatter.F(`[%s] node was decorated with both Focus and Pending.  At most one is allowed.`, nodeType),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"node-decorators-overview\",\n\t}\n}\n\nfunc (g ginkgoErrors) InvalidDeclarationOfFlakeAttemptsAndMustPassRepeatedly(cl CodeLocation, nodeType NodeType) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Invalid Combination of Decorators: FlakeAttempts and MustPassRepeatedly\",\n\t\tMessage:      formatter.F(`[%s] node was decorated with both FlakeAttempts and MustPassRepeatedly. At most one is allowed.`, nodeType),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"node-decorators-overview\",\n\t}\n}\n\nfunc (g ginkgoErrors) UnknownDecorator(cl CodeLocation, nodeType NodeType, decorator any) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Unknown Decorator\",\n\t\tMessage:      formatter.F(`[%s] node was passed an unknown decorator: '%#v'`, nodeType, decorator),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"node-decorators-overview\",\n\t}\n}\n\nfunc (g ginkgoErrors) InvalidBodyTypeForContainer(t reflect.Type, cl CodeLocation, nodeType NodeType) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Invalid Function\",\n\t\tMessage:      formatter.F(`[%s] node must be passed {{bold}}func(){{/}} - i.e. functions that take nothing and return nothing.  You passed {{bold}}%s{{/}} instead.`, nodeType, t),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"node-decorators-overview\",\n\t}\n}\n\nfunc (g ginkgoErrors) InvalidBodyType(t reflect.Type, cl CodeLocation, nodeType NodeType) error {\n\tmustGet := \"{{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}\"\n\tif nodeType.Is(NodeTypeContainer) {\n\t\tmustGet = \"{{bold}}func(){{/}}\"\n\t}\n\treturn GinkgoError{\n\t\tHeading: \"Invalid Function\",\n\t\tMessage: formatter.F(`[%s] node must be passed `+mustGet+`.\nYou passed {{bold}}%s{{/}} instead.`, nodeType, t),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"node-decorators-overview\",\n\t}\n}\n\nfunc (g ginkgoErrors) InvalidBodyTypeForSynchronizedBeforeSuiteProc1(t reflect.Type, cl CodeLocation) error {\n\tmustGet := \"{{bold}}func() []byte{{/}}, {{bold}}func(ctx SpecContext) []byte{{/}}, or {{bold}}func(ctx context.Context) []byte{{/}}, {{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}\"\n\treturn GinkgoError{\n\t\tHeading: \"Invalid Function\",\n\t\tMessage: formatter.F(`[SynchronizedBeforeSuite] node must be passed `+mustGet+` for its first function.\nYou passed {{bold}}%s{{/}} instead.`, t),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"node-decorators-overview\",\n\t}\n}\n\nfunc (g ginkgoErrors) InvalidBodyTypeForSynchronizedBeforeSuiteAllProcs(t reflect.Type, cl CodeLocation) error {\n\tmustGet := \"{{bold}}func(){{/}}, {{bold}}func(ctx SpecContext){{/}}, or {{bold}}func(ctx context.Context){{/}}, {{bold}}func([]byte){{/}}, {{bold}}func(ctx SpecContext, []byte){{/}}, or {{bold}}func(ctx context.Context, []byte){{/}}\"\n\treturn GinkgoError{\n\t\tHeading: \"Invalid Function\",\n\t\tMessage: formatter.F(`[SynchronizedBeforeSuite] node must be passed `+mustGet+` for its second function.\nYou passed {{bold}}%s{{/}} instead.`, t),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"node-decorators-overview\",\n\t}\n}\n\nfunc (g ginkgoErrors) MultipleBodyFunctions(cl CodeLocation, nodeType NodeType) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Multiple Functions\",\n\t\tMessage:      formatter.F(`[%s] node must be passed a single function - but more than one was passed in.`, nodeType),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"node-decorators-overview\",\n\t}\n}\n\nfunc (g ginkgoErrors) MissingBodyFunction(cl CodeLocation, nodeType NodeType) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Missing Functions\",\n\t\tMessage:      formatter.F(`[%s] node must be passed a single function - but none was passed in.`, nodeType),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"node-decorators-overview\",\n\t}\n}\n\nfunc (g ginkgoErrors) InvalidTimeoutOrGracePeriodForNonContextNode(cl CodeLocation, nodeType NodeType) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Invalid NodeTimeout SpecTimeout, or GracePeriod\",\n\t\tMessage:      formatter.F(`[%s] was passed NodeTimeout, SpecTimeout, or GracePeriod but does not have a callback that accepts a {{bold}}SpecContext{{/}} or {{bold}}context.Context{{/}}.  You must accept a context to enable timeouts and grace periods`, nodeType),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"spec-timeouts-and-interruptible-nodes\",\n\t}\n}\n\nfunc (g ginkgoErrors) InvalidTimeoutOrGracePeriodForNonContextCleanupNode(cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Invalid NodeTimeout SpecTimeout, or GracePeriod\",\n\t\tMessage:      formatter.F(`[DeferCleanup] was passed NodeTimeout or GracePeriod but does not have a callback that accepts a {{bold}}SpecContext{{/}} or {{bold}}context.Context{{/}}.  You must accept a context to enable timeouts and grace periods`),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"spec-timeouts-and-interruptible-nodes\",\n\t}\n}\n\n/* Ordered Container errors */\nfunc (g ginkgoErrors) InvalidSerialNodeInNonSerialOrderedContainer(cl CodeLocation, nodeType NodeType) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Invalid Serial Node in Non-Serial Ordered Container\",\n\t\tMessage:      formatter.F(`[%s] node was decorated with Serial but occurs in an Ordered container that is not marked Serial.  Move the Serial decorator to the outer-most Ordered container to mark all ordered specs within the container as serial.`, nodeType),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"node-decorators-overview\",\n\t}\n}\n\nfunc (g ginkgoErrors) SetupNodeNotInOrderedContainer(cl CodeLocation, nodeType NodeType) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Setup Node not in Ordered Container\",\n\t\tMessage:      fmt.Sprintf(\"[%s] setup nodes must appear inside an Ordered container.  They cannot be nested within other containers, even containers in an ordered container.\", nodeType),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"ordered-containers\",\n\t}\n}\n\nfunc (g ginkgoErrors) InvalidContinueOnFailureDecoration(cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      \"ContinueOnFailure not decorating an outermost Ordered Container\",\n\t\tMessage:      \"ContinueOnFailure can only decorate an Ordered container, and this Ordered container must be the outermost Ordered container.\",\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"ordered-containers\",\n\t}\n}\n\n/* DeferCleanup errors */\nfunc (g ginkgoErrors) DeferCleanupInvalidFunction(cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      \"DeferCleanup requires a valid function\",\n\t\tMessage:      \"You must pass DeferCleanup a function to invoke.  This function must return zero or one values - if it does return, it must return an error.  The function can take arbitrarily many arguments and you should provide these to DeferCleanup to pass along to the function.\",\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"cleaning-up-our-cleanup-code-defercleanup\",\n\t}\n}\n\nfunc (g ginkgoErrors) PushingCleanupNodeDuringTreeConstruction(cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      \"DeferCleanup must be called inside a setup or subject node\",\n\t\tMessage:      \"You must call DeferCleanup inside a setup node (e.g. BeforeEach, BeforeSuite, AfterAll...) or a subject node (i.e. It).  You can't call DeferCleanup at the top-level or in a container node - use the After* family of setup nodes instead.\",\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"cleaning-up-our-cleanup-code-defercleanup\",\n\t}\n}\n\nfunc (g ginkgoErrors) PushingCleanupInReportingNode(cl CodeLocation, nodeType NodeType) error {\n\treturn GinkgoError{\n\t\tHeading:      fmt.Sprintf(\"DeferCleanup cannot be called in %s\", nodeType),\n\t\tMessage:      \"Please inline your cleanup code - Ginkgo won't run cleanup code after a Reporting node.\",\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"cleaning-up-our-cleanup-code-defercleanup\",\n\t}\n}\n\nfunc (g ginkgoErrors) PushingCleanupInCleanupNode(cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      \"DeferCleanup cannot be called in a DeferCleanup callback\",\n\t\tMessage:      \"Please inline your cleanup code - Ginkgo doesn't let you call DeferCleanup from within DeferCleanup\",\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"cleaning-up-our-cleanup-code-defercleanup\",\n\t}\n}\n\n/* ReportEntry errors */\nfunc (g ginkgoErrors) TooManyReportEntryValues(cl CodeLocation, arg any) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Too Many ReportEntry Values\",\n\t\tMessage:      formatter.F(`{{bold}}AddGinkgoReport{{/}} can only be given one value. Got unexpected value: %#v`, arg),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"attaching-data-to-reports\",\n\t}\n}\n\nfunc (g ginkgoErrors) AddReportEntryNotDuringRunPhase(cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Ginkgo detected an issue with your spec structure\",\n\t\tMessage:      formatter.F(`It looks like you are calling {{bold}}AddGinkgoReport{{/}} outside of a running spec.  Make sure you call {{bold}}AddGinkgoReport{{/}} inside a runnable node such as It or BeforeEach and not inside the body of a container such as Describe or Context.`),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"attaching-data-to-reports\",\n\t}\n}\n\n/* By errors */\nfunc (g ginkgoErrors) ByNotDuringRunPhase(cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Ginkgo detected an issue with your spec structure\",\n\t\tMessage:      formatter.F(`It looks like you are calling {{bold}}By{{/}} outside of a running spec.  Make sure you call {{bold}}By{{/}} inside a runnable node such as It or BeforeEach and not inside the body of a container such as Describe or Context.`),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"documenting-complex-specs-by\",\n\t}\n}\n\n/* FileFilter and SkipFilter errors */\nfunc (g ginkgoErrors) InvalidFileFilter(filter string) error {\n\treturn GinkgoError{\n\t\tHeading: \"Invalid File Filter\",\n\t\tMessage: fmt.Sprintf(`The provided file filter: \"%s\" is invalid.  File filters must have the format \"file\", \"file:lines\" where \"file\" is a regular expression that will match against the file path and lines is a comma-separated list of integers (e.g. file:1,5,7) or line-ranges (e.g. file:1-3,5-9) or both (e.g. file:1,5-9)`, filter),\n\t\tDocLink: \"filtering-specs\",\n\t}\n}\n\nfunc (g ginkgoErrors) InvalidFileFilterRegularExpression(filter string, err error) error {\n\treturn GinkgoError{\n\t\tHeading: \"Invalid File Filter Regular Expression\",\n\t\tMessage: fmt.Sprintf(`The provided file filter: \"%s\" included an invalid regular expression.  regexp.Compile error: %s`, filter, err),\n\t\tDocLink: \"filtering-specs\",\n\t}\n}\n\n/* Label Errors */\nfunc (g ginkgoErrors) SyntaxErrorParsingLabelFilter(input string, location int, error string) error {\n\tvar message string\n\tif location >= 0 {\n\t\tfor i, r := range input {\n\t\t\tif i == location {\n\t\t\t\tmessage += \"{{red}}{{bold}}{{underline}}\"\n\t\t\t}\n\t\t\tmessage += string(r)\n\t\t\tif i == location {\n\t\t\t\tmessage += \"{{/}}\"\n\t\t\t}\n\t\t}\n\t} else {\n\t\tmessage = input\n\t}\n\tmessage += \"\\n\" + error\n\treturn GinkgoError{\n\t\tHeading: \"Syntax Error Parsing Label Filter\",\n\t\tMessage: message,\n\t\tDocLink: \"spec-labels\",\n\t}\n}\n\nfunc (g ginkgoErrors) InvalidLabel(label string, cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Invalid Label\",\n\t\tMessage:      fmt.Sprintf(\"'%s' is an invalid label.  Labels cannot contain of the following characters: '&|!,()/'\", label),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"spec-labels\",\n\t}\n}\n\nfunc (g ginkgoErrors) InvalidEmptyLabel(cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Invalid Empty Label\",\n\t\tMessage:      \"Labels cannot be empty\",\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"spec-labels\",\n\t}\n}\n\n/* Table errors */\nfunc (g ginkgoErrors) MultipleEntryBodyFunctionsForTable(cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      \"DescribeTable passed multiple functions\",\n\t\tMessage:      \"It looks like you are passing multiple functions into DescribeTable.  Only one function can be passed in.  This function will be called for each Entry in the table.\",\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"table-specs\",\n\t}\n}\n\nfunc (g ginkgoErrors) InvalidEntryDescription(cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Invalid Entry description\",\n\t\tMessage:      \"Entry description functions must be a string, a function that accepts the entry parameters and returns a string, or nil.\",\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"table-specs\",\n\t}\n}\n\nfunc (g ginkgoErrors) MissingParametersForTableFunction(cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      \"No parameters have been passed to the Table Function\",\n\t\tMessage:      \"The Table Function expected at least 1 parameter\",\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"table-specs\",\n\t}\n}\n\nfunc (g ginkgoErrors) IncorrectParameterTypeForTable(i int, name string, cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      \"DescribeTable passed incorrect parameter type\",\n\t\tMessage:      fmt.Sprintf(\"Parameter #%d passed to DescribeTable is of incorrect type <%s>\", i, name),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"table-specs\",\n\t}\n}\n\nfunc (g ginkgoErrors) TooFewParametersToTableFunction(expected, actual int, kind string, cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      fmt.Sprintf(\"Too few parameters passed in to %s\", kind),\n\t\tMessage:      fmt.Sprintf(\"The %s expected %d parameters but you passed in %d\", kind, expected, actual),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"table-specs\",\n\t}\n}\n\nfunc (g ginkgoErrors) TooManyParametersToTableFunction(expected, actual int, kind string, cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      fmt.Sprintf(\"Too many parameters passed in to %s\", kind),\n\t\tMessage:      fmt.Sprintf(\"The %s expected %d parameters but you passed in %d\", kind, expected, actual),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"table-specs\",\n\t}\n}\n\nfunc (g ginkgoErrors) IncorrectParameterTypeToTableFunction(i int, expected, actual reflect.Type, kind string, cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      fmt.Sprintf(\"Incorrect parameters type passed to %s\", kind),\n\t\tMessage:      fmt.Sprintf(\"The %s expected parameter #%d to be of type <%s> but you passed in <%s>\", kind, i, expected, actual),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"table-specs\",\n\t}\n}\n\nfunc (g ginkgoErrors) IncorrectVariadicParameterTypeToTableFunction(expected, actual reflect.Type, kind string, cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      fmt.Sprintf(\"Incorrect parameters type passed to %s\", kind),\n\t\tMessage:      fmt.Sprintf(\"The %s expected its variadic parameters to be of type <%s> but you passed in <%s>\", kind, expected, actual),\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"table-specs\",\n\t}\n}\n\nfunc (g ginkgoErrors) ContextsCannotBeUsedInSubtreeTables(cl CodeLocation) error {\n\treturn GinkgoError{\n\t\tHeading:      \"Contexts cannot be used in subtree tables\",\n\t\tMessage:      \"You''ve defined a subtree body function that accepts a context but did not provide one in the table entry.  Ginkgo SpecContexts can only be passed in to subject and setup nodes - so if you are trying to implement a spec timeout you should request a context in the It function within your subtree body function, not in the subtree body function itself.\",\n\t\tCodeLocation: cl,\n\t\tDocLink:      \"table-specs\",\n\t}\n}\n\n/* Parallel Synchronization errors */\n\nfunc (g ginkgoErrors) AggregatedReportUnavailableDueToNodeDisappearing() error {\n\treturn GinkgoError{\n\t\tHeading: \"Test Report unavailable because a Ginkgo parallel process disappeared\",\n\t\tMessage: \"The aggregated report could not be fetched for a ReportAfterSuite node.  A Ginkgo parallel process disappeared before it could finish reporting.\",\n\t}\n}\n\nfunc (g ginkgoErrors) SynchronizedBeforeSuiteFailedOnProc1() error {\n\treturn GinkgoError{\n\t\tHeading: \"SynchronizedBeforeSuite failed on Ginkgo parallel process #1\",\n\t\tMessage: \"The first SynchronizedBeforeSuite function running on Ginkgo parallel process #1 failed.  This suite will now abort.\",\n\t}\n}\n\nfunc (g ginkgoErrors) SynchronizedBeforeSuiteDisappearedOnProc1() error {\n\treturn GinkgoError{\n\t\tHeading: \"Process #1 disappeared before SynchronizedBeforeSuite could report back\",\n\t\tMessage: \"Ginkgo parallel process #1 disappeared before the first SynchronizedBeforeSuite function completed.  This suite will now abort.\",\n\t}\n}\n\n/* Configuration errors */\n\nfunc (g ginkgoErrors) UnknownTypePassedToRunSpecs(value any) error {\n\treturn GinkgoError{\n\t\tHeading: \"Unknown Type passed to RunSpecs\",\n\t\tMessage: fmt.Sprintf(\"RunSpecs() accepts labels, and configuration of type types.SuiteConfig and/or types.ReporterConfig.\\n You passed in: %v\", value),\n\t}\n}\n\nvar sharedParallelErrorMessage = \"It looks like you are trying to run specs in parallel with go test.\\nThis is unsupported and you should use the ginkgo CLI instead.\"\n\nfunc (g ginkgoErrors) InvalidParallelTotalConfiguration() error {\n\treturn GinkgoError{\n\t\tHeading: \"-ginkgo.parallel.total must be >= 1\",\n\t\tMessage: sharedParallelErrorMessage,\n\t\tDocLink: \"spec-parallelization\",\n\t}\n}\n\nfunc (g ginkgoErrors) InvalidParallelProcessConfiguration() error {\n\treturn GinkgoError{\n\t\tHeading: \"-ginkgo.parallel.process is one-indexed and must be <= ginkgo.parallel.total\",\n\t\tMessage: sharedParallelErrorMessage,\n\t\tDocLink: \"spec-parallelization\",\n\t}\n}\n\nfunc (g ginkgoErrors) MissingParallelHostConfiguration() error {\n\treturn GinkgoError{\n\t\tHeading: \"-ginkgo.parallel.host is missing\",\n\t\tMessage: sharedParallelErrorMessage,\n\t\tDocLink: \"spec-parallelization\",\n\t}\n}\n\nfunc (g ginkgoErrors) UnreachableParallelHost(host string) error {\n\treturn GinkgoError{\n\t\tHeading: \"Could not reach ginkgo.parallel.host:\" + host,\n\t\tMessage: sharedParallelErrorMessage,\n\t\tDocLink: \"spec-parallelization\",\n\t}\n}\n\nfunc (g ginkgoErrors) DryRunInParallelConfiguration() error {\n\treturn GinkgoError{\n\t\tHeading: \"Ginkgo only performs -dryRun in serial mode.\",\n\t\tMessage: \"Please try running ginkgo -dryRun again, but without -p or -procs to ensure the suite is running in series.\",\n\t}\n}\n\nfunc (g ginkgoErrors) GracePeriodCannotBeZero() error {\n\treturn GinkgoError{\n\t\tHeading: \"Ginkgo requires a positive --grace-period.\",\n\t\tMessage: \"Please set --grace-period to a positive duration.  The default is 30s.\",\n\t}\n}\n\nfunc (g ginkgoErrors) ConflictingVerbosityConfiguration() error {\n\treturn GinkgoError{\n\t\tHeading: \"Conflicting reporter verbosity settings.\",\n\t\tMessage: \"You can't set more than one of -v, -vv and --succinct.  Please pick one!\",\n\t}\n}\n\nfunc (g ginkgoErrors) InvalidOutputInterceptorModeConfiguration(value string) error {\n\treturn GinkgoError{\n\t\tHeading: fmt.Sprintf(\"Invalid value '%s' for --output-interceptor-mode.\", value),\n\t\tMessage: \"You must choose one of 'dup', 'swap', or 'none'.\",\n\t}\n}\n\nfunc (g ginkgoErrors) InvalidGoFlagCount() error {\n\treturn GinkgoError{\n\t\tHeading: \"Use of go test -count\",\n\t\tMessage: \"Ginkgo does not support using go test -count to rerun suites.  Only -count=1 is allowed.  To repeat suite runs, please use the ginkgo cli and `ginkgo -until-it-fails` or `ginkgo -repeat=N`.\",\n\t}\n}\n\nfunc (g ginkgoErrors) InvalidGoFlagParallel() error {\n\treturn GinkgoError{\n\t\tHeading: \"Use of go test -parallel\",\n\t\tMessage: \"Go test's implementation of parallelization does not actually parallelize Ginkgo specs.  Please use the ginkgo cli and `ginkgo -p` or `ginkgo -procs=N` instead.\",\n\t}\n}\n\nfunc (g ginkgoErrors) BothRepeatAndUntilItFails() error {\n\treturn GinkgoError{\n\t\tHeading: \"--repeat and --until-it-fails are both set\",\n\t\tMessage: \"--until-it-fails directs Ginkgo to rerun specs indefinitely until they fail.  --repeat directs Ginkgo to rerun specs a set number of times.  You can't set both... which would you like?\",\n\t}\n}\n\nfunc (g ginkgoErrors) ExpectFilenameNotPath(flag string, path string) error {\n\treturn GinkgoError{\n\t\tHeading: fmt.Sprintf(\"%s expects a filename but was given a path: %s\", flag, path),\n\t\tMessage: fmt.Sprintf(\"%s takes a filename, not a path.  Use --output-dir to specify a directory to collect all test outputs.\", flag),\n\t}\n}\n\nfunc (g ginkgoErrors) FlagAfterPositionalParameter() error {\n\treturn GinkgoError{\n\t\tHeading: \"Malformed arguments - detected a flag after the package liste\",\n\t\tMessage: \"Make sure all flags appear {{bold}}after{{/}} the Ginkgo subcommand and {{bold}}before{{/}} your list of packages (or './...').\\n{{gray}}e.g. 'ginkgo run -p my_package' is valid but `ginkgo -p run my_package` is not.\\n{{gray}}e.g. 'ginkgo -p -vet=\\\"\\\" ./...' is valid but 'ginkgo -p ./... -vet=\\\"\\\"' is not{{/}}\",\n\t}\n}\n\n/* Stack-Trace parsing errors */\n\nfunc (g ginkgoErrors) FailedToParseStackTrace(message string) error {\n\treturn GinkgoError{\n\t\tHeading: \"Failed to Parse Stack Trace\",\n\t\tMessage: message,\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/types/file_filter.go",
    "content": "package types\n\nimport (\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc ParseFileFilters(filters []string) (FileFilters, error) {\n\tffs := FileFilters{}\n\tfor _, filter := range filters {\n\t\tff := FileFilter{}\n\t\tif filter == \"\" {\n\t\t\treturn nil, GinkgoErrors.InvalidFileFilter(filter)\n\t\t}\n\t\tcomponents := strings.Split(filter, \":\")\n\t\tif !(len(components) == 1 || len(components) == 2) {\n\t\t\treturn nil, GinkgoErrors.InvalidFileFilter(filter)\n\t\t}\n\n\t\tvar err error\n\t\tff.Filename, err = regexp.Compile(components[0])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif len(components) == 2 {\n\t\t\tlineFilters := strings.Split(components[1], \",\")\n\t\t\tfor _, lineFilter := range lineFilters {\n\t\t\t\tcomponents := strings.Split(lineFilter, \"-\")\n\t\t\t\tif len(components) == 1 {\n\t\t\t\t\tline, err := strconv.Atoi(strings.TrimSpace(components[0]))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, GinkgoErrors.InvalidFileFilter(filter)\n\t\t\t\t\t}\n\t\t\t\t\tff.LineFilters = append(ff.LineFilters, LineFilter{line, line + 1})\n\t\t\t\t} else if len(components) == 2 {\n\t\t\t\t\tline1, err := strconv.Atoi(strings.TrimSpace(components[0]))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, GinkgoErrors.InvalidFileFilter(filter)\n\t\t\t\t\t}\n\t\t\t\t\tline2, err := strconv.Atoi(strings.TrimSpace(components[1]))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, GinkgoErrors.InvalidFileFilter(filter)\n\t\t\t\t\t}\n\t\t\t\t\tff.LineFilters = append(ff.LineFilters, LineFilter{line1, line2})\n\t\t\t\t} else {\n\t\t\t\t\treturn nil, GinkgoErrors.InvalidFileFilter(filter)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tffs = append(ffs, ff)\n\t}\n\treturn ffs, nil\n}\n\ntype FileFilter struct {\n\tFilename    *regexp.Regexp\n\tLineFilters LineFilters\n}\n\nfunc (f FileFilter) Matches(locations []CodeLocation) bool {\n\tfor _, location := range locations {\n\t\tif f.Filename.MatchString(location.FileName) &&\n\t\t\tf.LineFilters.Matches(location.LineNumber) {\n\t\t\treturn true\n\t\t}\n\n\t}\n\treturn false\n}\n\ntype FileFilters []FileFilter\n\nfunc (ffs FileFilters) Matches(locations []CodeLocation) bool {\n\tfor _, ff := range ffs {\n\t\tif ff.Matches(locations) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\ntype LineFilter struct {\n\tMin int\n\tMax int\n}\n\nfunc (lf LineFilter) Matches(line int) bool {\n\treturn lf.Min <= line && line < lf.Max\n}\n\ntype LineFilters []LineFilter\n\nfunc (lfs LineFilters) Matches(line int) bool {\n\tif len(lfs) == 0 {\n\t\treturn true\n\t}\n\n\tfor _, lf := range lfs {\n\t\tif lf.Matches(line) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/types/flags.go",
    "content": "package types\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/onsi/ginkgo/v2/formatter\"\n)\n\ntype GinkgoFlag struct {\n\tName       string\n\tKeyPath    string\n\tSectionKey string\n\n\tUsage             string\n\tUsageArgument     string\n\tUsageDefaultValue string\n\n\tDeprecatedName    string\n\tDeprecatedDocLink string\n\tDeprecatedVersion string\n\n\tExportAs     string\n\tAlwaysExport bool\n}\n\ntype GinkgoFlags []GinkgoFlag\n\nfunc (f GinkgoFlags) CopyAppend(flags ...GinkgoFlag) GinkgoFlags {\n\tout := GinkgoFlags{}\n\tout = append(out, f...)\n\tout = append(out, flags...)\n\treturn out\n}\n\nfunc (f GinkgoFlags) WithPrefix(prefix string) GinkgoFlags {\n\tif prefix == \"\" {\n\t\treturn f\n\t}\n\tout := GinkgoFlags{}\n\tfor _, flag := range f {\n\t\tif flag.Name != \"\" {\n\t\t\tflag.Name = prefix + \".\" + flag.Name\n\t\t}\n\t\tif flag.DeprecatedName != \"\" {\n\t\t\tflag.DeprecatedName = prefix + \".\" + flag.DeprecatedName\n\t\t}\n\t\tif flag.ExportAs != \"\" {\n\t\t\tflag.ExportAs = prefix + \".\" + flag.ExportAs\n\t\t}\n\t\tout = append(out, flag)\n\t}\n\treturn out\n}\n\nfunc (f GinkgoFlags) SubsetWithNames(names ...string) GinkgoFlags {\n\tout := GinkgoFlags{}\n\tfor _, flag := range f {\n\t\tfor _, name := range names {\n\t\t\tif flag.Name == name {\n\t\t\t\tout = append(out, flag)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\treturn out\n}\n\ntype GinkgoFlagSection struct {\n\tKey         string\n\tStyle       string\n\tSuccinct    bool\n\tHeading     string\n\tDescription string\n}\n\ntype GinkgoFlagSections []GinkgoFlagSection\n\nfunc (gfs GinkgoFlagSections) Lookup(key string) (GinkgoFlagSection, bool) {\n\tfor _, section := range gfs {\n\t\tif section.Key == key {\n\t\t\treturn section, true\n\t\t}\n\t}\n\n\treturn GinkgoFlagSection{}, false\n}\n\ntype GinkgoFlagSet struct {\n\tflags    GinkgoFlags\n\tbindings any\n\n\tsections            GinkgoFlagSections\n\textraGoFlagsSection GinkgoFlagSection\n\n\tflagSet *flag.FlagSet\n}\n\n// Call NewGinkgoFlagSet to create GinkgoFlagSet that creates and binds to it's own *flag.FlagSet\nfunc NewGinkgoFlagSet(flags GinkgoFlags, bindings any, sections GinkgoFlagSections) (GinkgoFlagSet, error) {\n\treturn bindFlagSet(GinkgoFlagSet{\n\t\tflags:    flags,\n\t\tbindings: bindings,\n\t\tsections: sections,\n\t}, nil)\n}\n\n// Call NewGinkgoFlagSet to create GinkgoFlagSet that extends an existing *flag.FlagSet\nfunc NewAttachedGinkgoFlagSet(flagSet *flag.FlagSet, flags GinkgoFlags, bindings any, sections GinkgoFlagSections, extraGoFlagsSection GinkgoFlagSection) (GinkgoFlagSet, error) {\n\treturn bindFlagSet(GinkgoFlagSet{\n\t\tflags:               flags,\n\t\tbindings:            bindings,\n\t\tsections:            sections,\n\t\textraGoFlagsSection: extraGoFlagsSection,\n\t}, flagSet)\n}\n\nfunc bindFlagSet(f GinkgoFlagSet, flagSet *flag.FlagSet) (GinkgoFlagSet, error) {\n\tif flagSet == nil {\n\t\tf.flagSet = flag.NewFlagSet(\"\", flag.ContinueOnError)\n\t\t//suppress all output as Ginkgo is responsible for formatting usage\n\t\tf.flagSet.SetOutput(io.Discard)\n\t} else {\n\t\tf.flagSet = flagSet\n\t\t//we're piggybacking on an existing flagset (typically go test) so we have limited control\n\t\t//on user feedback\n\t\tf.flagSet.Usage = f.substituteUsage\n\t}\n\n\tfor _, flag := range f.flags {\n\t\tname := flag.Name\n\n\t\tdeprecatedUsage := \"[DEPRECATED]\"\n\t\tdeprecatedName := flag.DeprecatedName\n\t\tif name != \"\" {\n\t\t\tdeprecatedUsage = fmt.Sprintf(\"[DEPRECATED] use --%s instead\", name)\n\t\t} else if flag.Usage != \"\" {\n\t\t\tdeprecatedUsage += \" \" + flag.Usage\n\t\t}\n\n\t\tvalue, ok := valueAtKeyPath(f.bindings, flag.KeyPath)\n\t\tif !ok {\n\t\t\treturn GinkgoFlagSet{}, fmt.Errorf(\"could not load KeyPath: %s\", flag.KeyPath)\n\t\t}\n\n\t\tiface, addr := value.Interface(), value.Addr().Interface()\n\n\t\tswitch value.Type() {\n\t\tcase reflect.TypeOf(string(\"\")):\n\t\t\tif name != \"\" {\n\t\t\t\tf.flagSet.StringVar(addr.(*string), name, iface.(string), flag.Usage)\n\t\t\t}\n\t\t\tif deprecatedName != \"\" {\n\t\t\t\tf.flagSet.StringVar(addr.(*string), deprecatedName, iface.(string), deprecatedUsage)\n\t\t\t}\n\t\tcase reflect.TypeOf(int64(0)):\n\t\t\tif name != \"\" {\n\t\t\t\tf.flagSet.Int64Var(addr.(*int64), name, iface.(int64), flag.Usage)\n\t\t\t}\n\t\t\tif deprecatedName != \"\" {\n\t\t\t\tf.flagSet.Int64Var(addr.(*int64), deprecatedName, iface.(int64), deprecatedUsage)\n\t\t\t}\n\t\tcase reflect.TypeOf(float64(0)):\n\t\t\tif name != \"\" {\n\t\t\t\tf.flagSet.Float64Var(addr.(*float64), name, iface.(float64), flag.Usage)\n\t\t\t}\n\t\t\tif deprecatedName != \"\" {\n\t\t\t\tf.flagSet.Float64Var(addr.(*float64), deprecatedName, iface.(float64), deprecatedUsage)\n\t\t\t}\n\t\tcase reflect.TypeOf(int(0)):\n\t\t\tif name != \"\" {\n\t\t\t\tf.flagSet.IntVar(addr.(*int), name, iface.(int), flag.Usage)\n\t\t\t}\n\t\t\tif deprecatedName != \"\" {\n\t\t\t\tf.flagSet.IntVar(addr.(*int), deprecatedName, iface.(int), deprecatedUsage)\n\t\t\t}\n\t\tcase reflect.TypeOf(bool(true)):\n\t\t\tif name != \"\" {\n\t\t\t\tf.flagSet.BoolVar(addr.(*bool), name, iface.(bool), flag.Usage)\n\t\t\t}\n\t\t\tif deprecatedName != \"\" {\n\t\t\t\tf.flagSet.BoolVar(addr.(*bool), deprecatedName, iface.(bool), deprecatedUsage)\n\t\t\t}\n\t\tcase reflect.TypeOf(time.Duration(0)):\n\t\t\tif name != \"\" {\n\t\t\t\tf.flagSet.DurationVar(addr.(*time.Duration), name, iface.(time.Duration), flag.Usage)\n\t\t\t}\n\t\t\tif deprecatedName != \"\" {\n\t\t\t\tf.flagSet.DurationVar(addr.(*time.Duration), deprecatedName, iface.(time.Duration), deprecatedUsage)\n\t\t\t}\n\n\t\tcase reflect.TypeOf([]string{}):\n\t\t\tif name != \"\" {\n\t\t\t\tf.flagSet.Var(stringSliceVar{value}, name, flag.Usage)\n\t\t\t}\n\t\t\tif deprecatedName != \"\" {\n\t\t\t\tf.flagSet.Var(stringSliceVar{value}, deprecatedName, deprecatedUsage)\n\t\t\t}\n\t\tdefault:\n\t\t\treturn GinkgoFlagSet{}, fmt.Errorf(\"unsupported type %T\", iface)\n\t\t}\n\t}\n\n\treturn f, nil\n}\n\nfunc (f GinkgoFlagSet) IsZero() bool {\n\treturn f.flagSet == nil\n}\n\nfunc (f GinkgoFlagSet) WasSet(name string) bool {\n\tfound := false\n\tf.flagSet.Visit(func(f *flag.Flag) {\n\t\tif f.Name == name {\n\t\t\tfound = true\n\t\t}\n\t})\n\n\treturn found\n}\n\nfunc (f GinkgoFlagSet) Lookup(name string) *flag.Flag {\n\treturn f.flagSet.Lookup(name)\n}\n\nfunc (f GinkgoFlagSet) Parse(args []string) ([]string, error) {\n\tif f.IsZero() {\n\t\treturn args, nil\n\t}\n\terr := f.flagSet.Parse(args)\n\tif err != nil {\n\t\treturn []string{}, err\n\t}\n\treturn f.flagSet.Args(), nil\n}\n\nfunc (f GinkgoFlagSet) ValidateDeprecations(deprecationTracker *DeprecationTracker) {\n\tif f.IsZero() {\n\t\treturn\n\t}\n\tf.flagSet.Visit(func(flag *flag.Flag) {\n\t\tfor _, ginkgoFlag := range f.flags {\n\t\t\tif ginkgoFlag.DeprecatedName != \"\" && strings.HasSuffix(flag.Name, ginkgoFlag.DeprecatedName) {\n\t\t\t\tmessage := fmt.Sprintf(\"--%s is deprecated\", ginkgoFlag.DeprecatedName)\n\t\t\t\tif ginkgoFlag.Name != \"\" {\n\t\t\t\t\tmessage = fmt.Sprintf(\"--%s is deprecated, use --%s instead\", ginkgoFlag.DeprecatedName, ginkgoFlag.Name)\n\t\t\t\t} else if ginkgoFlag.Usage != \"\" {\n\t\t\t\t\tmessage += \" \" + ginkgoFlag.Usage\n\t\t\t\t}\n\n\t\t\t\tdeprecationTracker.TrackDeprecation(Deprecation{\n\t\t\t\t\tMessage: message,\n\t\t\t\t\tDocLink: ginkgoFlag.DeprecatedDocLink,\n\t\t\t\t\tVersion: ginkgoFlag.DeprecatedVersion,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunc (f GinkgoFlagSet) Usage() string {\n\tif f.IsZero() {\n\t\treturn \"\"\n\t}\n\tgroupedFlags := map[GinkgoFlagSection]GinkgoFlags{}\n\tungroupedFlags := GinkgoFlags{}\n\tmanagedFlags := map[string]bool{}\n\textraGoFlags := []*flag.Flag{}\n\n\tfor _, flag := range f.flags {\n\t\tmanagedFlags[flag.Name] = true\n\t\tmanagedFlags[flag.DeprecatedName] = true\n\n\t\tif flag.Name == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tsection, ok := f.sections.Lookup(flag.SectionKey)\n\t\tif ok {\n\t\t\tgroupedFlags[section] = append(groupedFlags[section], flag)\n\t\t} else {\n\t\t\tungroupedFlags = append(ungroupedFlags, flag)\n\t\t}\n\t}\n\n\tf.flagSet.VisitAll(func(flag *flag.Flag) {\n\t\tif !managedFlags[flag.Name] {\n\t\t\textraGoFlags = append(extraGoFlags, flag)\n\t\t}\n\t})\n\n\tout := \"\"\n\tfor _, section := range f.sections {\n\t\tflags := groupedFlags[section]\n\t\tif len(flags) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tout += f.usageForSection(section)\n\t\tif section.Succinct {\n\t\t\tsuccinctFlags := []string{}\n\t\t\tfor _, flag := range flags {\n\t\t\t\tif flag.Name != \"\" {\n\t\t\t\t\tsuccinctFlags = append(succinctFlags, fmt.Sprintf(\"--%s\", flag.Name))\n\t\t\t\t}\n\t\t\t}\n\t\t\tout += formatter.Fiw(1, formatter.COLS, section.Style+strings.Join(succinctFlags, \", \")+\"{{/}}\\n\")\n\t\t} else {\n\t\t\tfor _, flag := range flags {\n\t\t\t\tout += f.usageForFlag(flag, section.Style)\n\t\t\t}\n\t\t}\n\t\tout += \"\\n\"\n\t}\n\tif len(ungroupedFlags) > 0 {\n\t\tfor _, flag := range ungroupedFlags {\n\t\t\tout += f.usageForFlag(flag, \"\")\n\t\t}\n\t\tout += \"\\n\"\n\t}\n\tif len(extraGoFlags) > 0 {\n\t\tout += f.usageForSection(f.extraGoFlagsSection)\n\t\tfor _, goFlag := range extraGoFlags {\n\t\t\tout += f.usageForGoFlag(goFlag)\n\t\t}\n\t}\n\n\treturn out\n}\n\nfunc (f GinkgoFlagSet) substituteUsage() {\n\tfmt.Fprintln(f.flagSet.Output(), f.Usage())\n}\n\nfunc valueAtKeyPath(root any, keyPath string) (reflect.Value, bool) {\n\tif len(keyPath) == 0 {\n\t\treturn reflect.Value{}, false\n\t}\n\n\tval := reflect.ValueOf(root)\n\tcomponents := strings.Split(keyPath, \".\")\n\tfor _, component := range components {\n\t\tval = reflect.Indirect(val)\n\t\tswitch val.Kind() {\n\t\tcase reflect.Map:\n\t\t\tval = val.MapIndex(reflect.ValueOf(component))\n\t\t\tif val.Kind() == reflect.Interface {\n\t\t\t\tval = reflect.ValueOf(val.Interface())\n\t\t\t}\n\t\tcase reflect.Struct:\n\t\t\tval = val.FieldByName(component)\n\t\tdefault:\n\t\t\treturn reflect.Value{}, false\n\t\t}\n\t\tif (val == reflect.Value{}) {\n\t\t\treturn reflect.Value{}, false\n\t\t}\n\t}\n\n\treturn val, true\n}\n\nfunc (f GinkgoFlagSet) usageForSection(section GinkgoFlagSection) string {\n\tout := formatter.F(section.Style + \"{{bold}}{{underline}}\" + section.Heading + \"{{/}}\\n\")\n\tif section.Description != \"\" {\n\t\tout += formatter.Fiw(0, formatter.COLS, section.Description+\"\\n\")\n\t}\n\treturn out\n}\n\nfunc (f GinkgoFlagSet) usageForFlag(flag GinkgoFlag, style string) string {\n\targument := flag.UsageArgument\n\tdefValue := flag.UsageDefaultValue\n\tif argument == \"\" {\n\t\tvalue, _ := valueAtKeyPath(f.bindings, flag.KeyPath)\n\t\tswitch value.Type() {\n\t\tcase reflect.TypeOf(string(\"\")):\n\t\t\targument = \"string\"\n\t\tcase reflect.TypeOf(int64(0)), reflect.TypeOf(int(0)):\n\t\t\targument = \"int\"\n\t\tcase reflect.TypeOf(time.Duration(0)):\n\t\t\targument = \"duration\"\n\t\tcase reflect.TypeOf(float64(0)):\n\t\t\targument = \"float\"\n\t\tcase reflect.TypeOf([]string{}):\n\t\t\targument = \"string\"\n\t\t}\n\t}\n\tif argument != \"\" {\n\t\targument = \"[\" + argument + \"] \"\n\t}\n\tif defValue != \"\" {\n\t\tdefValue = fmt.Sprintf(\"(default: %s)\", defValue)\n\t}\n\thyphens := \"--\"\n\tif len(flag.Name) == 1 {\n\t\thyphens = \"-\"\n\t}\n\n\tout := formatter.Fi(1, style+\"%s%s{{/}} %s{{gray}}%s{{/}}\\n\", hyphens, flag.Name, argument, defValue)\n\tout += formatter.Fiw(2, formatter.COLS, \"{{light-gray}}%s{{/}}\\n\", flag.Usage)\n\treturn out\n}\n\nfunc (f GinkgoFlagSet) usageForGoFlag(goFlag *flag.Flag) string {\n\t//Taken directly from the flag package\n\tout := fmt.Sprintf(\"  -%s\", goFlag.Name)\n\tname, usage := flag.UnquoteUsage(goFlag)\n\tif len(name) > 0 {\n\t\tout += \" \" + name\n\t}\n\tif len(out) <= 4 {\n\t\tout += \"\\t\"\n\t} else {\n\t\tout += \"\\n    \\t\"\n\t}\n\tout += strings.ReplaceAll(usage, \"\\n\", \"\\n    \\t\")\n\tout += \"\\n\"\n\treturn out\n}\n\ntype stringSliceVar struct {\n\tslice reflect.Value\n}\n\nfunc (ssv stringSliceVar) String() string { return \"\" }\nfunc (ssv stringSliceVar) Set(s string) error {\n\tssv.slice.Set(reflect.AppendSlice(ssv.slice, reflect.ValueOf([]string{s})))\n\treturn nil\n}\n\n// given a set of GinkgoFlags and bindings, generate flag arguments suitable to be passed to an application with that set of flags configured.\nfunc GenerateFlagArgs(flags GinkgoFlags, bindings any) ([]string, error) {\n\tresult := []string{}\n\tfor _, flag := range flags {\n\t\tname := flag.ExportAs\n\t\tif name == \"\" {\n\t\t\tname = flag.Name\n\t\t}\n\t\tif name == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tvalue, ok := valueAtKeyPath(bindings, flag.KeyPath)\n\t\tif !ok {\n\t\t\treturn []string{}, fmt.Errorf(\"could not load KeyPath: %s\", flag.KeyPath)\n\t\t}\n\n\t\tiface := value.Interface()\n\t\tswitch value.Type() {\n\t\tcase reflect.TypeOf(string(\"\")):\n\t\t\tif iface.(string) != \"\" || flag.AlwaysExport {\n\t\t\t\tresult = append(result, fmt.Sprintf(\"--%s=%s\", name, iface))\n\t\t\t}\n\t\tcase reflect.TypeOf(int64(0)):\n\t\t\tif iface.(int64) != 0 || flag.AlwaysExport {\n\t\t\t\tresult = append(result, fmt.Sprintf(\"--%s=%d\", name, iface))\n\t\t\t}\n\t\tcase reflect.TypeOf(float64(0)):\n\t\t\tif iface.(float64) != 0 || flag.AlwaysExport {\n\t\t\t\tresult = append(result, fmt.Sprintf(\"--%s=%f\", name, iface))\n\t\t\t}\n\t\tcase reflect.TypeOf(int(0)):\n\t\t\tif iface.(int) != 0 || flag.AlwaysExport {\n\t\t\t\tresult = append(result, fmt.Sprintf(\"--%s=%d\", name, iface))\n\t\t\t}\n\t\tcase reflect.TypeOf(bool(true)):\n\t\t\tif iface.(bool) {\n\t\t\t\tresult = append(result, fmt.Sprintf(\"--%s\", name))\n\t\t\t}\n\t\tcase reflect.TypeOf(time.Duration(0)):\n\t\t\tif iface.(time.Duration) != time.Duration(0) || flag.AlwaysExport {\n\t\t\t\tresult = append(result, fmt.Sprintf(\"--%s=%s\", name, iface))\n\t\t\t}\n\n\t\tcase reflect.TypeOf([]string{}):\n\t\t\tstrings := iface.([]string)\n\t\t\tfor _, s := range strings {\n\t\t\t\tresult = append(result, fmt.Sprintf(\"--%s=%s\", name, s))\n\t\t\t}\n\t\tdefault:\n\t\t\treturn []string{}, fmt.Errorf(\"unsupported type %T\", iface)\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/types/label_filter.go",
    "content": "package types\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n)\n\nvar DEBUG_LABEL_FILTER_PARSING = false\n\ntype LabelFilter func([]string) bool\n\nfunc matchLabelAction(label string) LabelFilter {\n\texpected := strings.ToLower(label)\n\treturn func(labels []string) bool {\n\t\tfor i := range labels {\n\t\t\tif strings.ToLower(labels[i]) == expected {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n}\n\nfunc matchLabelRegexAction(regex *regexp.Regexp) LabelFilter {\n\treturn func(labels []string) bool {\n\t\tfor i := range labels {\n\t\t\tif regex.MatchString(labels[i]) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n}\n\nfunc notAction(filter LabelFilter) LabelFilter {\n\treturn func(labels []string) bool { return !filter(labels) }\n}\n\nfunc andAction(a, b LabelFilter) LabelFilter {\n\treturn func(labels []string) bool { return a(labels) && b(labels) }\n}\n\nfunc orAction(a, b LabelFilter) LabelFilter {\n\treturn func(labels []string) bool { return a(labels) || b(labels) }\n}\n\nfunc labelSetFor(key string, labels []string) map[string]bool {\n\tkey = strings.ToLower(strings.TrimSpace(key))\n\tout := map[string]bool{}\n\tfor _, label := range labels {\n\t\tcomponents := strings.SplitN(label, \":\", 2)\n\t\tif len(components) < 2 {\n\t\t\tcontinue\n\t\t}\n\t\tif key == strings.ToLower(strings.TrimSpace(components[0])) {\n\t\t\tout[strings.ToLower(strings.TrimSpace(components[1]))] = true\n\t\t}\n\t}\n\n\treturn out\n}\n\nfunc isEmptyLabelSetAction(key string) LabelFilter {\n\treturn func(labels []string) bool {\n\t\treturn len(labelSetFor(key, labels)) == 0\n\t}\n}\n\nfunc containsAnyLabelSetAction(key string, expectedValues []string) LabelFilter {\n\treturn func(labels []string) bool {\n\t\tset := labelSetFor(key, labels)\n\t\tfor _, value := range expectedValues {\n\t\t\tif set[value] {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n}\n\nfunc containsAllLabelSetAction(key string, expectedValues []string) LabelFilter {\n\treturn func(labels []string) bool {\n\t\tset := labelSetFor(key, labels)\n\t\tfor _, value := range expectedValues {\n\t\t\tif !set[value] {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n}\n\nfunc consistsOfLabelSetAction(key string, expectedValues []string) LabelFilter {\n\treturn func(labels []string) bool {\n\t\tset := labelSetFor(key, labels)\n\t\tif len(set) != len(expectedValues) {\n\t\t\treturn false\n\t\t}\n\t\tfor _, value := range expectedValues {\n\t\t\tif !set[value] {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n}\n\nfunc isSubsetOfLabelSetAction(key string, expectedValues []string) LabelFilter {\n\texpectedSet := map[string]bool{}\n\tfor _, value := range expectedValues {\n\t\texpectedSet[value] = true\n\t}\n\treturn func(labels []string) bool {\n\t\tset := labelSetFor(key, labels)\n\t\tfor value := range set {\n\t\t\tif !expectedSet[value] {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n}\n\ntype lfToken uint\n\nconst (\n\tlfTokenInvalid lfToken = iota\n\n\tlfTokenRoot\n\tlfTokenOpenGroup\n\tlfTokenCloseGroup\n\tlfTokenNot\n\tlfTokenAnd\n\tlfTokenOr\n\tlfTokenRegexp\n\tlfTokenLabel\n\tlfTokenSetKey\n\tlfTokenSetOperation\n\tlfTokenSetArgument\n\tlfTokenEOF\n)\n\nfunc (l lfToken) Precedence() int {\n\tswitch l {\n\tcase lfTokenRoot, lfTokenOpenGroup:\n\t\treturn 0\n\tcase lfTokenOr:\n\t\treturn 1\n\tcase lfTokenAnd:\n\t\treturn 2\n\tcase lfTokenNot:\n\t\treturn 3\n\tcase lfTokenSetOperation:\n\t\treturn 4\n\t}\n\treturn -1\n}\n\nfunc (l lfToken) String() string {\n\tswitch l {\n\tcase lfTokenRoot:\n\t\treturn \"ROOT\"\n\tcase lfTokenOpenGroup:\n\t\treturn \"(\"\n\tcase lfTokenCloseGroup:\n\t\treturn \")\"\n\tcase lfTokenNot:\n\t\treturn \"!\"\n\tcase lfTokenAnd:\n\t\treturn \"&&\"\n\tcase lfTokenOr:\n\t\treturn \"||\"\n\tcase lfTokenRegexp:\n\t\treturn \"/regexp/\"\n\tcase lfTokenLabel:\n\t\treturn \"label\"\n\tcase lfTokenSetKey:\n\t\treturn \"set_key\"\n\tcase lfTokenSetOperation:\n\t\treturn \"set_operation\"\n\tcase lfTokenSetArgument:\n\t\treturn \"set_argument\"\n\tcase lfTokenEOF:\n\t\treturn \"EOF\"\n\t}\n\treturn \"INVALID\"\n}\n\ntype treeNode struct {\n\ttoken    lfToken\n\tlocation int\n\tvalue    string\n\n\tparent    *treeNode\n\tleftNode  *treeNode\n\trightNode *treeNode\n}\n\nfunc (tn *treeNode) setRightNode(node *treeNode) {\n\ttn.rightNode = node\n\tnode.parent = tn\n}\n\nfunc (tn *treeNode) setLeftNode(node *treeNode) {\n\ttn.leftNode = node\n\tnode.parent = tn\n}\n\nfunc (tn *treeNode) firstAncestorWithPrecedenceLEQ(precedence int) *treeNode {\n\tif tn.token.Precedence() <= precedence {\n\t\treturn tn\n\t}\n\treturn tn.parent.firstAncestorWithPrecedenceLEQ(precedence)\n}\n\nfunc (tn *treeNode) firstUnmatchedOpenNode() *treeNode {\n\tif tn.token == lfTokenOpenGroup {\n\t\treturn tn\n\t}\n\tif tn.parent == nil {\n\t\treturn nil\n\t}\n\treturn tn.parent.firstUnmatchedOpenNode()\n}\n\nfunc (tn *treeNode) constructLabelFilter(input string) (LabelFilter, error) {\n\tswitch tn.token {\n\tcase lfTokenOpenGroup:\n\t\treturn nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, \"Mismatched '(' - could not find matching ')'.\")\n\tcase lfTokenLabel:\n\t\treturn matchLabelAction(tn.value), nil\n\tcase lfTokenRegexp:\n\t\tre, err := regexp.Compile(tn.value)\n\t\tif err != nil {\n\t\t\treturn nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, fmt.Sprintf(\"RegExp compilation error: %s\", err))\n\t\t}\n\t\treturn matchLabelRegexAction(re), nil\n\tcase lfTokenSetOperation:\n\t\ttokenSetOperation := strings.ToLower(tn.value)\n\t\tif tokenSetOperation == \"isempty\" {\n\t\t\treturn isEmptyLabelSetAction(tn.leftNode.value), nil\n\t\t}\n\t\tif tn.rightNode == nil {\n\t\t\treturn nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, fmt.Sprintf(\"Set operation '%s' is missing an argument.\", tn.value))\n\t\t}\n\n\t\trawValues := strings.Split(tn.rightNode.value, \",\")\n\t\tvalues := make([]string, len(rawValues))\n\t\tfor i := range rawValues {\n\t\t\tvalues[i] = strings.ToLower(strings.TrimSpace(rawValues[i]))\n\t\t\tif strings.ContainsAny(values[i], \"&|!,()/\") {\n\t\t\t\treturn nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.rightNode.location, fmt.Sprintf(\"Invalid label value '%s' in set operation argument.\", values[i]))\n\t\t\t} else if values[i] == \"\" {\n\t\t\t\treturn nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.rightNode.location, \"Empty label value in set operation argument.\")\n\t\t\t}\n\t\t}\n\t\tswitch tokenSetOperation {\n\t\tcase \"containsany\":\n\t\t\treturn containsAnyLabelSetAction(tn.leftNode.value, values), nil\n\t\tcase \"containsall\":\n\t\t\treturn containsAllLabelSetAction(tn.leftNode.value, values), nil\n\t\tcase \"consistsof\":\n\t\t\treturn consistsOfLabelSetAction(tn.leftNode.value, values), nil\n\t\tcase \"issubsetof\":\n\t\t\treturn isSubsetOfLabelSetAction(tn.leftNode.value, values), nil\n\t\t}\n\t}\n\n\tif tn.rightNode == nil {\n\t\treturn nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, -1, \"Unexpected EOF.\")\n\t}\n\trightLF, err := tn.rightNode.constructLabelFilter(input)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tswitch tn.token {\n\tcase lfTokenRoot, lfTokenCloseGroup:\n\t\treturn rightLF, nil\n\tcase lfTokenNot:\n\t\treturn notAction(rightLF), nil\n\t}\n\n\tif tn.leftNode == nil {\n\t\treturn nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, fmt.Sprintf(\"Malformed tree - '%s' is missing left operand.\", tn.token))\n\t}\n\tleftLF, err := tn.leftNode.constructLabelFilter(input)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tswitch tn.token {\n\tcase lfTokenAnd:\n\t\treturn andAction(leftLF, rightLF), nil\n\tcase lfTokenOr:\n\t\treturn orAction(leftLF, rightLF), nil\n\t}\n\n\treturn nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, fmt.Sprintf(\"Invalid token '%s'.\", tn.token))\n}\n\nfunc (tn *treeNode) tokenString() string {\n\tout := fmt.Sprintf(\"<%s\", tn.token)\n\tif tn.value != \"\" {\n\t\tout += \" | \" + tn.value\n\t}\n\tout += \">\"\n\treturn out\n}\n\nfunc (tn *treeNode) toString(indent int) string {\n\tout := tn.tokenString() + \"\\n\"\n\tif tn.leftNode != nil {\n\t\tout += fmt.Sprintf(\"%s  |_(L)_%s\", strings.Repeat(\" \", indent), tn.leftNode.toString(indent+1))\n\t}\n\tif tn.rightNode != nil {\n\t\tout += fmt.Sprintf(\"%s  |_(R)_%s\", strings.Repeat(\" \", indent), tn.rightNode.toString(indent+1))\n\t}\n\treturn out\n}\n\nvar validSetOperations = map[string]string{\n\t\"containsany\": \"containsAny\",\n\t\"containsall\": \"containsAll\",\n\t\"consistsof\":  \"consistsOf\",\n\t\"issubsetof\":  \"isSubsetOf\",\n\t\"isempty\":     \"isEmpty\",\n}\n\nfunc tokenize(input string) func() (*treeNode, error) {\n\tlastToken := lfTokenInvalid\n\tlastValue := \"\"\n\trunes, i := []rune(input), 0\n\n\tpeekIs := func(r rune) bool {\n\t\tif i+1 < len(runes) {\n\t\t\treturn runes[i+1] == r\n\t\t}\n\t\treturn false\n\t}\n\n\tconsumeUntil := func(cutset string) (string, int) {\n\t\tj := i\n\t\tfor ; j < len(runes); j++ {\n\t\t\tif strings.ContainsRune(cutset, runes[j]) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\treturn string(runes[i:j]), j - i\n\t}\n\n\treturn func() (*treeNode, error) {\n\t\tfor i < len(runes) && runes[i] == ' ' {\n\t\t\ti += 1\n\t\t}\n\n\t\tif i >= len(runes) {\n\t\t\treturn &treeNode{token: lfTokenEOF}, nil\n\t\t}\n\n\t\tnode := &treeNode{location: i}\n\t\tdefer func() {\n\t\t\tlastToken = node.token\n\t\t\tlastValue = node.value\n\t\t}()\n\n\t\tif lastToken == lfTokenSetKey {\n\t\t\t//we should get a valid set operation next\n\t\t\tvalue, n := consumeUntil(\" )\")\n\t\t\tif validSetOperations[strings.ToLower(value)] == \"\" {\n\t\t\t\treturn &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, fmt.Sprintf(\"Invalid set operation '%s'.\", value))\n\t\t\t}\n\t\t\ti += n\n\t\t\tnode.token, node.value = lfTokenSetOperation, value\n\t\t\treturn node, nil\n\t\t}\n\t\tif lastToken == lfTokenSetOperation {\n\t\t\t//we should get an argument next, if we aren't isempty\n\t\t\tvar arg = \"\"\n\t\t\torigI := i\n\t\t\tif runes[i] == '{' {\n\t\t\t\ti += 1\n\t\t\t\tvalue, n := consumeUntil(\"}\")\n\t\t\t\tif i+n >= len(runes) {\n\t\t\t\t\treturn &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i-1, \"Missing closing '}' in set operation argument?\")\n\t\t\t\t}\n\t\t\t\ti += n + 1\n\t\t\t\targ = value\n\t\t\t} else {\n\t\t\t\tvalue, n := consumeUntil(\"&|!,()/\")\n\t\t\t\ti += n\n\t\t\t\targ = strings.TrimSpace(value)\n\t\t\t}\n\t\t\tif strings.ToLower(lastValue) == \"isempty\" && arg != \"\" {\n\t\t\t\treturn &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, fmt.Sprintf(\"isEmpty does not take arguments, was passed '%s'.\", arg))\n\t\t\t}\n\t\t\tif arg == \"\" && strings.ToLower(lastValue) != \"isempty\" {\n\t\t\t\tif i < len(runes) && runes[i] == '/' {\n\t\t\t\t\treturn &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, \"Set operations do not support regular expressions.\")\n\t\t\t\t} else {\n\t\t\t\t\treturn &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, fmt.Sprintf(\"Set operation '%s' requires an argument.\", lastValue))\n\t\t\t\t}\n\t\t\t}\n\t\t\t// note that we sent an empty SetArgument token if we are isempty\n\t\t\tnode.token, node.value = lfTokenSetArgument, arg\n\t\t\treturn node, nil\n\t\t}\n\n\t\tswitch runes[i] {\n\t\tcase '&':\n\t\t\tif !peekIs('&') {\n\t\t\t\treturn &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, \"Invalid token '&'.  Did you mean '&&'?\")\n\t\t\t}\n\t\t\ti += 2\n\t\t\tnode.token = lfTokenAnd\n\t\tcase '|':\n\t\t\tif !peekIs('|') {\n\t\t\t\treturn &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, \"Invalid token '|'.  Did you mean '||'?\")\n\t\t\t}\n\t\t\ti += 2\n\t\t\tnode.token = lfTokenOr\n\t\tcase '!':\n\t\t\ti += 1\n\t\t\tnode.token = lfTokenNot\n\t\tcase ',':\n\t\t\ti += 1\n\t\t\tnode.token = lfTokenOr\n\t\tcase '(':\n\t\t\ti += 1\n\t\t\tnode.token = lfTokenOpenGroup\n\t\tcase ')':\n\t\t\ti += 1\n\t\t\tnode.token = lfTokenCloseGroup\n\t\tcase '/':\n\t\t\ti += 1\n\t\t\tvalue, n := consumeUntil(\"/\")\n\t\t\ti += n + 1\n\t\t\tnode.token, node.value = lfTokenRegexp, value\n\t\tdefault:\n\t\t\tvalue, n := consumeUntil(\"&|!,()/:\")\n\t\t\ti += n\n\t\t\tvalue = strings.TrimSpace(value)\n\n\t\t\t//are we the beginning of a set operation?\n\t\t\tif i < len(runes) && runes[i] == ':' {\n\t\t\t\tif peekIs(' ') {\n\t\t\t\t\tif value == \"\" {\n\t\t\t\t\t\treturn &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, \"Missing set key.\")\n\t\t\t\t\t}\n\t\t\t\t\ti += 1\n\t\t\t\t\t//we are the beginning of a set operation\n\t\t\t\t\tnode.token, node.value = lfTokenSetKey, value\n\t\t\t\t\treturn node, nil\n\t\t\t\t}\n\t\t\t\tadditionalValue, n := consumeUntil(\"&|!,()/\")\n\t\t\t\tadditionalValue = strings.TrimSpace(additionalValue)\n\t\t\t\tif additionalValue == \":\" {\n\t\t\t\t\treturn &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, \"Missing set operation.\")\n\t\t\t\t}\n\t\t\t\ti += n\n\t\t\t\tvalue += additionalValue\n\t\t\t}\n\n\t\t\tvalueToCheckForSetOperation := strings.ToLower(value)\n\t\t\tfor setOperation := range validSetOperations {\n\t\t\t\tidx := strings.Index(valueToCheckForSetOperation, \" \"+setOperation)\n\t\t\t\tif idx > 0 {\n\t\t\t\t\treturn &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i-n+idx+1, fmt.Sprintf(\"Looks like you are using the set operator '%s' but did not provide a set key.  Did you forget the ':'?\", validSetOperations[setOperation]))\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tnode.token, node.value = lfTokenLabel, strings.TrimSpace(value)\n\t\t}\n\t\treturn node, nil\n\t}\n}\n\nfunc MustParseLabelFilter(input string) LabelFilter {\n\tfilter, err := ParseLabelFilter(input)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn filter\n}\n\nfunc ParseLabelFilter(input string) (LabelFilter, error) {\n\tif DEBUG_LABEL_FILTER_PARSING {\n\t\tfmt.Println(\"\\n==============\")\n\t\tfmt.Println(\"Input: \", input)\n\t\tfmt.Print(\"Tokens: \")\n\t}\n\tif input == \"\" {\n\t\treturn func(_ []string) bool { return true }, nil\n\t}\n\tnextToken := tokenize(input)\n\n\troot := &treeNode{token: lfTokenRoot}\n\tcurrent := root\nLOOP:\n\tfor {\n\t\tnode, err := nextToken()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif DEBUG_LABEL_FILTER_PARSING {\n\t\t\tfmt.Print(node.tokenString() + \" \")\n\t\t}\n\n\t\tswitch node.token {\n\t\tcase lfTokenEOF:\n\t\t\tbreak LOOP\n\t\tcase lfTokenLabel, lfTokenRegexp, lfTokenSetKey:\n\t\t\tif current.rightNode != nil {\n\t\t\t\treturn nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, \"Found two adjacent labels.  You need an operator between them.\")\n\t\t\t}\n\t\t\tcurrent.setRightNode(node)\n\t\tcase lfTokenNot, lfTokenOpenGroup:\n\t\t\tif current.rightNode != nil {\n\t\t\t\treturn nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf(\"Invalid token '%s'.\", node.token))\n\t\t\t}\n\t\t\tcurrent.setRightNode(node)\n\t\t\tcurrent = node\n\t\tcase lfTokenAnd, lfTokenOr:\n\t\t\tif current.rightNode == nil {\n\t\t\t\treturn nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf(\"Operator '%s' missing left hand operand.\", node.token))\n\t\t\t}\n\t\t\tnodeToStealFrom := current.firstAncestorWithPrecedenceLEQ(node.token.Precedence())\n\t\t\tnode.setLeftNode(nodeToStealFrom.rightNode)\n\t\t\tnodeToStealFrom.setRightNode(node)\n\t\t\tcurrent = node\n\t\tcase lfTokenSetOperation:\n\t\t\tif current.rightNode == nil {\n\t\t\t\treturn nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf(\"Set operation '%s' missing left hand operand.\", node.value))\n\t\t\t}\n\t\t\tnode.setLeftNode(current.rightNode)\n\t\t\tcurrent.setRightNode(node)\n\t\t\tcurrent = node\n\t\tcase lfTokenSetArgument:\n\t\t\tif current.rightNode != nil {\n\t\t\t\treturn nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf(\"Unexpected set argument '%s'.\", node.token))\n\t\t\t}\n\t\t\tcurrent.setRightNode(node)\n\t\tcase lfTokenCloseGroup:\n\t\t\tfirstUnmatchedOpenNode := current.firstUnmatchedOpenNode()\n\t\t\tif firstUnmatchedOpenNode == nil {\n\t\t\t\treturn nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, \"Mismatched ')' - could not find matching '('.\")\n\t\t\t}\n\t\t\tif firstUnmatchedOpenNode == current && current.rightNode == nil {\n\t\t\t\treturn nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, \"Found empty '()' group.\")\n\t\t\t}\n\t\t\tfirstUnmatchedOpenNode.token = lfTokenCloseGroup //signify the group is now closed\n\t\t\tcurrent = firstUnmatchedOpenNode.parent\n\t\tdefault:\n\t\t\treturn nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf(\"Unknown token '%s'.\", node.token))\n\t\t}\n\t}\n\tif DEBUG_LABEL_FILTER_PARSING {\n\t\tfmt.Printf(\"\\n Tree:\\n%s\", root.toString(0))\n\t}\n\treturn root.constructLabelFilter(input)\n}\n\nfunc ValidateAndCleanupLabel(label string, cl CodeLocation) (string, error) {\n\tout := strings.TrimSpace(label)\n\tif out == \"\" {\n\t\treturn \"\", GinkgoErrors.InvalidEmptyLabel(cl)\n\t}\n\tif strings.ContainsAny(out, \"&|!,()/\") {\n\t\treturn \"\", GinkgoErrors.InvalidLabel(label, cl)\n\t}\n\tif out[0] == ':' {\n\t\treturn \"\", GinkgoErrors.InvalidLabel(label, cl)\n\t}\n\tif strings.Contains(out, \":\") {\n\t\tcomponents := strings.SplitN(out, \":\", 2)\n\t\tif len(components) < 2 || components[1] == \"\" {\n\t\t\treturn \"\", GinkgoErrors.InvalidLabel(label, cl)\n\t\t}\n\t}\n\treturn out, nil\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/types/report_entry.go",
    "content": "package types\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"time\"\n)\n\n// ReportEntryValue wraps a report entry's value ensuring it can be encoded and decoded safely into reports\n// and across the network connection when running in parallel\ntype ReportEntryValue struct {\n\traw            any //unexported to prevent gob from freaking out about unregistered structs\n\tAsJSON         string\n\tRepresentation string\n}\n\nfunc WrapEntryValue(value any) ReportEntryValue {\n\treturn ReportEntryValue{\n\t\traw: value,\n\t}\n}\n\nfunc (rev ReportEntryValue) GetRawValue() any {\n\treturn rev.raw\n}\n\nfunc (rev ReportEntryValue) String() string {\n\tif rev.raw == nil {\n\t\treturn \"\"\n\t}\n\tif colorableStringer, ok := rev.raw.(ColorableStringer); ok {\n\t\treturn colorableStringer.ColorableString()\n\t}\n\n\tif stringer, ok := rev.raw.(fmt.Stringer); ok {\n\t\treturn stringer.String()\n\t}\n\tif rev.Representation != \"\" {\n\t\treturn rev.Representation\n\t}\n\treturn fmt.Sprintf(\"%+v\", rev.raw)\n}\n\nfunc (rev ReportEntryValue) MarshalJSON() ([]byte, error) {\n\t//All this to capture the representation at encoding-time, not creating time\n\t//This way users can Report on pointers and get their final values at reporting-time\n\tout := struct {\n\t\tAsJSON         string\n\t\tRepresentation string\n\t}{\n\t\tRepresentation: rev.String(),\n\t}\n\tasJSON, err := json.Marshal(rev.raw)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tout.AsJSON = string(asJSON)\n\n\treturn json.Marshal(out)\n}\n\nfunc (rev *ReportEntryValue) UnmarshalJSON(data []byte) error {\n\tin := struct {\n\t\tAsJSON         string\n\t\tRepresentation string\n\t}{}\n\terr := json.Unmarshal(data, &in)\n\tif err != nil {\n\t\treturn err\n\t}\n\trev.AsJSON = in.AsJSON\n\trev.Representation = in.Representation\n\treturn json.Unmarshal([]byte(in.AsJSON), &(rev.raw))\n}\n\nfunc (rev ReportEntryValue) GobEncode() ([]byte, error) {\n\treturn rev.MarshalJSON()\n}\n\nfunc (rev *ReportEntryValue) GobDecode(data []byte) error {\n\treturn rev.UnmarshalJSON(data)\n}\n\n// ReportEntry captures information attached to `SpecReport` via `AddReportEntry`\ntype ReportEntry struct {\n\t// Visibility captures the visibility policy for this ReportEntry\n\tVisibility ReportEntryVisibility\n\t// Location captures the location of the AddReportEntry call\n\tLocation CodeLocation\n\n\tTime             time.Time //need this for backwards compatibility\n\tTimelineLocation TimelineLocation\n\n\t// Name captures the name of this report\n\tName string\n\t// Value captures the (optional) object passed into AddReportEntry - this can be\n\t// anything the user wants.  The value passed to AddReportEntry is wrapped in a ReportEntryValue to make\n\t// encoding/decoding the value easier.  To access the raw value call entry.GetRawValue()\n\tValue ReportEntryValue\n}\n\n// ColorableStringer is an interface that ReportEntry values can satisfy.  If they do then ColorableString() is used to generate their representation.\ntype ColorableStringer interface {\n\tColorableString() string\n}\n\n// StringRepresentation() returns the string representation of the value associated with the ReportEntry --\n// if value is nil, empty string is returned\n// if value is a `ColorableStringer` then `Value.ColorableString()` is returned\n// if value is a `fmt.Stringer` then `Value.String()` is returned\n// otherwise the value is formatted with \"%+v\"\nfunc (entry ReportEntry) StringRepresentation() string {\n\treturn entry.Value.String()\n}\n\n// GetRawValue returns the Value object that was passed to AddReportEntry\n// If called in-process this will be the same object that was passed into AddReportEntry.\n// If used from a rehydrated JSON file _or_ in a ReportAfterSuite when running in parallel this will be\n// a JSON-decoded {}interface.  If you want to reconstitute your original object you can decode the entry.Value.AsJSON\n// field yourself.\nfunc (entry ReportEntry) GetRawValue() any {\n\treturn entry.Value.GetRawValue()\n}\n\nfunc (entry ReportEntry) GetTimelineLocation() TimelineLocation {\n\treturn entry.TimelineLocation\n}\n\ntype ReportEntries []ReportEntry\n\nfunc (re ReportEntries) HasVisibility(visibilities ...ReportEntryVisibility) bool {\n\tfor _, entry := range re {\n\t\tif entry.Visibility.Is(visibilities...) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (re ReportEntries) WithVisibility(visibilities ...ReportEntryVisibility) ReportEntries {\n\tout := ReportEntries{}\n\n\tfor _, entry := range re {\n\t\tif entry.Visibility.Is(visibilities...) {\n\t\t\tout = append(out, entry)\n\t\t}\n\t}\n\n\treturn out\n}\n\n// ReportEntryVisibility governs the visibility of ReportEntries in Ginkgo's console reporter\ntype ReportEntryVisibility uint\n\nconst (\n\t// Always print out this ReportEntry\n\tReportEntryVisibilityAlways ReportEntryVisibility = iota\n\t// Only print out this ReportEntry if the spec fails or if the test is run with -v\n\tReportEntryVisibilityFailureOrVerbose\n\t// Never print out this ReportEntry (note that ReportEntrys are always encoded in machine readable reports (e.g. JSON, JUnit, etc.))\n\tReportEntryVisibilityNever\n)\n\nvar revEnumSupport = NewEnumSupport(map[uint]string{\n\tuint(ReportEntryVisibilityAlways):           \"always\",\n\tuint(ReportEntryVisibilityFailureOrVerbose): \"failure-or-verbose\",\n\tuint(ReportEntryVisibilityNever):            \"never\",\n})\n\nfunc (rev ReportEntryVisibility) String() string {\n\treturn revEnumSupport.String(uint(rev))\n}\nfunc (rev *ReportEntryVisibility) UnmarshalJSON(b []byte) error {\n\tout, err := revEnumSupport.UnmarshJSON(b)\n\t*rev = ReportEntryVisibility(out)\n\treturn err\n}\nfunc (rev ReportEntryVisibility) MarshalJSON() ([]byte, error) {\n\treturn revEnumSupport.MarshJSON(uint(rev))\n}\n\nfunc (v ReportEntryVisibility) Is(visibilities ...ReportEntryVisibility) bool {\n\tfor _, visibility := range visibilities {\n\t\tif v == visibility {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/types/types.go",
    "content": "package types\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n)\n\nconst GINKGO_FOCUS_EXIT_CODE = 197\n\nvar GINKGO_TIME_FORMAT = \"01/02/06 15:04:05.999\"\n\nfunc init() {\n\tif os.Getenv(\"GINKGO_TIME_FORMAT\") != \"\" {\n\t\tGINKGO_TIME_FORMAT = os.Getenv(\"GINKGO_TIME_FORMAT\")\n\t}\n}\n\n// Report captures information about a Ginkgo test run\ntype Report struct {\n\t//SuitePath captures the absolute path to the test suite\n\tSuitePath string\n\n\t//SuiteDescription captures the description string passed to the DSL's RunSpecs() function\n\tSuiteDescription string\n\n\t//SuiteLabels captures any labels attached to the suite by the DSL's RunSpecs() function\n\tSuiteLabels []string\n\n\t//SuiteSucceeded captures the success or failure status of the test run\n\t//If true, the test run is considered successful.\n\t//If false, the test run is considered unsuccessful\n\tSuiteSucceeded bool\n\n\t//SuiteHasProgrammaticFocus captures whether the test suite has a test or set of tests that are programmatically focused\n\t//(i.e an `FIt` or an `FDescribe`\n\tSuiteHasProgrammaticFocus bool\n\n\t//SpecialSuiteFailureReasons may contain special failure reasons\n\t//For example, a test suite might be considered \"failed\" even if none of the individual specs\n\t//have a failure state.  For example, if the user has configured --fail-on-pending the test suite\n\t//will have failed if there are pending tests even though all non-pending tests may have passed.  In such\n\t//cases, Ginkgo populates SpecialSuiteFailureReasons with a clear message indicating the reason for the failure.\n\t//SpecialSuiteFailureReasons is also populated if the test suite is interrupted by the user.\n\t//Since multiple special failure reasons can occur, this field is a slice.\n\tSpecialSuiteFailureReasons []string\n\n\t//PreRunStats contains a set of stats captured before the test run begins.  This is primarily used\n\t//by Ginkgo's reporter to tell the user how many specs are in the current suite (PreRunStats.TotalSpecs)\n\t//and how many it intends to run (PreRunStats.SpecsThatWillRun) after applying any relevant focus or skip filters.\n\tPreRunStats PreRunStats\n\n\t//StartTime and EndTime capture the start and end time of the test run\n\tStartTime time.Time\n\tEndTime   time.Time\n\n\t//RunTime captures the duration of the test run\n\tRunTime time.Duration\n\n\t//SuiteConfig captures the Ginkgo configuration governing this test run\n\t//SuiteConfig includes information necessary for reproducing an identical test run,\n\t//such as the random seed and any filters applied during the test run\n\tSuiteConfig SuiteConfig\n\n\t//SpecReports is a list of all SpecReports generated by this test run\n\t//It is empty when the SuiteReport is provided to ReportBeforeSuite\n\tSpecReports SpecReports\n}\n\n// PreRunStats contains a set of stats captured before the test run begins.  This is primarily used\n// by Ginkgo's reporter to tell the user how many specs are in the current suite (PreRunStats.TotalSpecs)\n// and how many it intends to run (PreRunStats.SpecsThatWillRun) after applying any relevant focus or skip filters.\ntype PreRunStats struct {\n\tTotalSpecs       int\n\tSpecsThatWillRun int\n}\n\n// Add is used by Ginkgo's parallel aggregation mechanisms to combine test run reports form individual parallel processes\n// to form a complete final report.\nfunc (report Report) Add(other Report) Report {\n\treport.SuiteSucceeded = report.SuiteSucceeded && other.SuiteSucceeded\n\n\tif other.StartTime.Before(report.StartTime) {\n\t\treport.StartTime = other.StartTime\n\t}\n\n\tif other.EndTime.After(report.EndTime) {\n\t\treport.EndTime = other.EndTime\n\t}\n\n\tspecialSuiteFailureReasons := []string{}\n\treasonsLookup := map[string]bool{}\n\tfor _, reasons := range [][]string{report.SpecialSuiteFailureReasons, other.SpecialSuiteFailureReasons} {\n\t\tfor _, reason := range reasons {\n\t\t\tif !reasonsLookup[reason] {\n\t\t\t\treasonsLookup[reason] = true\n\t\t\t\tspecialSuiteFailureReasons = append(specialSuiteFailureReasons, reason)\n\t\t\t}\n\t\t}\n\t}\n\treport.SpecialSuiteFailureReasons = specialSuiteFailureReasons\n\treport.RunTime = report.EndTime.Sub(report.StartTime)\n\n\treports := make(SpecReports, len(report.SpecReports)+len(other.SpecReports))\n\tcopy(reports, report.SpecReports)\n\toffset := len(report.SpecReports)\n\tfor i := range other.SpecReports {\n\t\treports[i+offset] = other.SpecReports[i]\n\t}\n\n\treport.SpecReports = reports\n\treturn report\n}\n\n// SpecReport captures information about a Ginkgo spec.\ntype SpecReport struct {\n\t// ContainerHierarchyTexts is a slice containing the text strings of\n\t// all Describe/Context/When containers in this spec's hierarchy.\n\tContainerHierarchyTexts []string\n\n\t// ContainerHierarchyLocations is a slice containing the CodeLocations of\n\t// all Describe/Context/When containers in this spec's hierarchy.\n\tContainerHierarchyLocations []CodeLocation\n\n\t// ContainerHierarchyLabels is a slice containing the labels of\n\t// all Describe/Context/When containers in this spec's hierarchy\n\tContainerHierarchyLabels [][]string\n\n\t// LeafNodeType, LeadNodeLocation, LeafNodeLabels and LeafNodeText capture the NodeType, CodeLocation, and text\n\t// of the Ginkgo node being tested (typically an NodeTypeIt node, though this can also be\n\t// one of the NodeTypesForSuiteLevelNodes node types)\n\tLeafNodeType     NodeType\n\tLeafNodeLocation CodeLocation\n\tLeafNodeLabels   []string\n\tLeafNodeText     string\n\n\t// State captures whether the spec has passed, failed, etc.\n\tState SpecState\n\n\t// IsSerial captures whether the spec has the Serial decorator\n\tIsSerial bool\n\n\t// IsInOrderedContainer captures whether the spec appears in an Ordered container\n\tIsInOrderedContainer bool\n\n\t// StartTime and EndTime capture the start and end time of the spec\n\tStartTime time.Time\n\tEndTime   time.Time\n\n\t// RunTime captures the duration of the spec\n\tRunTime time.Duration\n\n\t// ParallelProcess captures the parallel process that this spec ran on\n\tParallelProcess int\n\n\t// RunningInParallel captures whether this spec is part of a suite that ran in parallel\n\tRunningInParallel bool\n\n\t//Failure is populated if a spec has failed, panicked, been interrupted, or skipped by the user (e.g. calling Skip())\n\t//It includes detailed information about the Failure\n\tFailure Failure\n\n\t// NumAttempts captures the number of times this Spec was run.\n\t// Flakey specs can be retried with ginkgo --flake-attempts=N or the use of the FlakeAttempts decorator.\n\t// Repeated specs can be retried with the use of the MustPassRepeatedly decorator\n\tNumAttempts int\n\n\t// MaxFlakeAttempts captures whether the spec has been retried with ginkgo --flake-attempts=N or the use of the FlakeAttempts decorator.\n\tMaxFlakeAttempts int\n\n\t// MaxMustPassRepeatedly captures whether the spec has the MustPassRepeatedly decorator\n\tMaxMustPassRepeatedly int\n\n\t// CapturedGinkgoWriterOutput contains text printed to the GinkgoWriter\n\tCapturedGinkgoWriterOutput string\n\n\t// CapturedStdOutErr contains text printed to stdout/stderr (when running in parallel)\n\t// This is always empty when running in series or calling CurrentSpecReport()\n\t// It is used internally by Ginkgo's reporter\n\tCapturedStdOutErr string\n\n\t// ReportEntries contains any reports added via `AddReportEntry`\n\tReportEntries ReportEntries\n\n\t// ProgressReports contains any progress reports generated during this spec.  These can either be manually triggered, or automatically generated by Ginkgo via the PollProgressAfter() decorator\n\tProgressReports []ProgressReport\n\n\t// AdditionalFailures contains any failures that occurred after the initial spec failure.  These typically occur in cleanup nodes after the initial failure and are only emitted when running in verbose mode.\n\tAdditionalFailures []AdditionalFailure\n\n\t// SpecEvents capture additional events that occur during the spec run\n\tSpecEvents SpecEvents\n}\n\nfunc (report SpecReport) MarshalJSON() ([]byte, error) {\n\t//All this to avoid emitting an empty Failure struct in the JSON\n\tout := struct {\n\t\tContainerHierarchyTexts     []string\n\t\tContainerHierarchyLocations []CodeLocation\n\t\tContainerHierarchyLabels    [][]string\n\t\tLeafNodeType                NodeType\n\t\tLeafNodeLocation            CodeLocation\n\t\tLeafNodeLabels              []string\n\t\tLeafNodeText                string\n\t\tState                       SpecState\n\t\tStartTime                   time.Time\n\t\tEndTime                     time.Time\n\t\tRunTime                     time.Duration\n\t\tParallelProcess             int\n\t\tFailure                     *Failure `json:\",omitempty\"`\n\t\tNumAttempts                 int\n\t\tMaxFlakeAttempts            int\n\t\tMaxMustPassRepeatedly       int\n\t\tCapturedGinkgoWriterOutput  string              `json:\",omitempty\"`\n\t\tCapturedStdOutErr           string              `json:\",omitempty\"`\n\t\tReportEntries               ReportEntries       `json:\",omitempty\"`\n\t\tProgressReports             []ProgressReport    `json:\",omitempty\"`\n\t\tAdditionalFailures          []AdditionalFailure `json:\",omitempty\"`\n\t\tSpecEvents                  SpecEvents          `json:\",omitempty\"`\n\t}{\n\t\tContainerHierarchyTexts:     report.ContainerHierarchyTexts,\n\t\tContainerHierarchyLocations: report.ContainerHierarchyLocations,\n\t\tContainerHierarchyLabels:    report.ContainerHierarchyLabels,\n\t\tLeafNodeType:                report.LeafNodeType,\n\t\tLeafNodeLocation:            report.LeafNodeLocation,\n\t\tLeafNodeLabels:              report.LeafNodeLabels,\n\t\tLeafNodeText:                report.LeafNodeText,\n\t\tState:                       report.State,\n\t\tStartTime:                   report.StartTime,\n\t\tEndTime:                     report.EndTime,\n\t\tRunTime:                     report.RunTime,\n\t\tParallelProcess:             report.ParallelProcess,\n\t\tFailure:                     nil,\n\t\tReportEntries:               nil,\n\t\tNumAttempts:                 report.NumAttempts,\n\t\tMaxFlakeAttempts:            report.MaxFlakeAttempts,\n\t\tMaxMustPassRepeatedly:       report.MaxMustPassRepeatedly,\n\t\tCapturedGinkgoWriterOutput:  report.CapturedGinkgoWriterOutput,\n\t\tCapturedStdOutErr:           report.CapturedStdOutErr,\n\t}\n\n\tif !report.Failure.IsZero() {\n\t\tout.Failure = &(report.Failure)\n\t}\n\tif len(report.ReportEntries) > 0 {\n\t\tout.ReportEntries = report.ReportEntries\n\t}\n\tif len(report.ProgressReports) > 0 {\n\t\tout.ProgressReports = report.ProgressReports\n\t}\n\tif len(report.AdditionalFailures) > 0 {\n\t\tout.AdditionalFailures = report.AdditionalFailures\n\t}\n\tif len(report.SpecEvents) > 0 {\n\t\tout.SpecEvents = report.SpecEvents\n\t}\n\n\treturn json.Marshal(out)\n}\n\n// CombinedOutput returns a single string representation of both CapturedStdOutErr and CapturedGinkgoWriterOutput\n// Note that both are empty when using CurrentSpecReport() so CurrentSpecReport().CombinedOutput() will always be empty.\n// CombinedOutput() is used internally by Ginkgo's reporter.\nfunc (report SpecReport) CombinedOutput() string {\n\tif report.CapturedStdOutErr == \"\" {\n\t\treturn report.CapturedGinkgoWriterOutput\n\t}\n\tif report.CapturedGinkgoWriterOutput == \"\" {\n\t\treturn report.CapturedStdOutErr\n\t}\n\treturn report.CapturedStdOutErr + \"\\n\" + report.CapturedGinkgoWriterOutput\n}\n\n// Failed returns true if report.State is one of the SpecStateFailureStates\n// (SpecStateFailed, SpecStatePanicked, SpecStateinterrupted, SpecStateAborted)\nfunc (report SpecReport) Failed() bool {\n\treturn report.State.Is(SpecStateFailureStates)\n}\n\n// FullText returns a concatenation of all the report.ContainerHierarchyTexts and report.LeafNodeText\nfunc (report SpecReport) FullText() string {\n\ttexts := []string{}\n\ttexts = append(texts, report.ContainerHierarchyTexts...)\n\tif report.LeafNodeText != \"\" {\n\t\ttexts = append(texts, report.LeafNodeText)\n\t}\n\treturn strings.Join(texts, \" \")\n}\n\n// Labels returns a deduped set of all the spec's Labels.\nfunc (report SpecReport) Labels() []string {\n\tout := []string{}\n\tseen := map[string]bool{}\n\tfor _, labels := range report.ContainerHierarchyLabels {\n\t\tfor _, label := range labels {\n\t\t\tif !seen[label] {\n\t\t\t\tseen[label] = true\n\t\t\t\tout = append(out, label)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, label := range report.LeafNodeLabels {\n\t\tif !seen[label] {\n\t\t\tseen[label] = true\n\t\t\tout = append(out, label)\n\t\t}\n\t}\n\n\treturn out\n}\n\n// MatchesLabelFilter returns true if the spec satisfies the passed in label filter query\nfunc (report SpecReport) MatchesLabelFilter(query string) (bool, error) {\n\tfilter, err := ParseLabelFilter(query)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\treturn filter(report.Labels()), nil\n}\n\n// FileName() returns the name of the file containing the spec\nfunc (report SpecReport) FileName() string {\n\treturn report.LeafNodeLocation.FileName\n}\n\n// LineNumber() returns the line number of the leaf node\nfunc (report SpecReport) LineNumber() int {\n\treturn report.LeafNodeLocation.LineNumber\n}\n\n// FailureMessage() returns the failure message (or empty string if the test hasn't failed)\nfunc (report SpecReport) FailureMessage() string {\n\treturn report.Failure.Message\n}\n\n// FailureLocation() returns the location of the failure (or an empty CodeLocation if the test hasn't failed)\nfunc (report SpecReport) FailureLocation() CodeLocation {\n\treturn report.Failure.Location\n}\n\n// Timeline() returns a timeline view of the report\nfunc (report SpecReport) Timeline() Timeline {\n\ttimeline := Timeline{}\n\tif !report.Failure.IsZero() {\n\t\ttimeline = append(timeline, report.Failure)\n\t\tif report.Failure.AdditionalFailure != nil {\n\t\t\ttimeline = append(timeline, *(report.Failure.AdditionalFailure))\n\t\t}\n\t}\n\tfor _, additionalFailure := range report.AdditionalFailures {\n\t\ttimeline = append(timeline, additionalFailure)\n\t}\n\tfor _, reportEntry := range report.ReportEntries {\n\t\ttimeline = append(timeline, reportEntry)\n\t}\n\tfor _, progressReport := range report.ProgressReports {\n\t\ttimeline = append(timeline, progressReport)\n\t}\n\tfor _, specEvent := range report.SpecEvents {\n\t\ttimeline = append(timeline, specEvent)\n\t}\n\tsort.Sort(timeline)\n\treturn timeline\n}\n\ntype SpecReports []SpecReport\n\n// WithLeafNodeType returns the subset of SpecReports with LeafNodeType matching one of the requested NodeTypes\nfunc (reports SpecReports) WithLeafNodeType(nodeTypes NodeType) SpecReports {\n\tcount := 0\n\tfor i := range reports {\n\t\tif reports[i].LeafNodeType.Is(nodeTypes) {\n\t\t\tcount++\n\t\t}\n\t}\n\n\tout := make(SpecReports, count)\n\tj := 0\n\tfor i := range reports {\n\t\tif reports[i].LeafNodeType.Is(nodeTypes) {\n\t\t\tout[j] = reports[i]\n\t\t\tj++\n\t\t}\n\t}\n\treturn out\n}\n\n// WithState returns the subset of SpecReports with State matching one of the requested SpecStates\nfunc (reports SpecReports) WithState(states SpecState) SpecReports {\n\tcount := 0\n\tfor i := range reports {\n\t\tif reports[i].State.Is(states) {\n\t\t\tcount++\n\t\t}\n\t}\n\n\tout, j := make(SpecReports, count), 0\n\tfor i := range reports {\n\t\tif reports[i].State.Is(states) {\n\t\t\tout[j] = reports[i]\n\t\t\tj++\n\t\t}\n\t}\n\treturn out\n}\n\n// CountWithState returns the number of SpecReports with State matching one of the requested SpecStates\nfunc (reports SpecReports) CountWithState(states SpecState) int {\n\tn := 0\n\tfor i := range reports {\n\t\tif reports[i].State.Is(states) {\n\t\t\tn += 1\n\t\t}\n\t}\n\treturn n\n}\n\n// If the Spec passes, CountOfFlakedSpecs returns the number of SpecReports that failed after multiple attempts.\nfunc (reports SpecReports) CountOfFlakedSpecs() int {\n\tn := 0\n\tfor i := range reports {\n\t\tif reports[i].MaxFlakeAttempts > 1 && reports[i].State.Is(SpecStatePassed) && reports[i].NumAttempts > 1 {\n\t\t\tn += 1\n\t\t}\n\t}\n\treturn n\n}\n\n// If the Spec fails, CountOfRepeatedSpecs returns the number of SpecReports that passed after multiple attempts\nfunc (reports SpecReports) CountOfRepeatedSpecs() int {\n\tn := 0\n\tfor i := range reports {\n\t\tif reports[i].MaxMustPassRepeatedly > 1 && reports[i].State.Is(SpecStateFailureStates) && reports[i].NumAttempts > 1 {\n\t\t\tn += 1\n\t\t}\n\t}\n\treturn n\n}\n\n// TimelineLocation captures the location of an event in the spec's timeline\ntype TimelineLocation struct {\n\t//Offset is the offset (in bytes) of the event relative to the GinkgoWriter stream\n\tOffset int `json:\",omitempty\"`\n\n\t//Order is the order of the event with respect to other events.  The absolute value of Order\n\t//is irrelevant.  All that matters is that an event with a lower Order occurs before ane vent with a higher Order\n\tOrder int `json:\",omitempty\"`\n\n\tTime time.Time\n}\n\n// TimelineEvent represent an event on the timeline\n// consumers of Timeline will need to check the concrete type of each entry to determine how to handle it\ntype TimelineEvent interface {\n\tGetTimelineLocation() TimelineLocation\n}\n\ntype Timeline []TimelineEvent\n\nfunc (t Timeline) Len() int { return len(t) }\nfunc (t Timeline) Less(i, j int) bool {\n\treturn t[i].GetTimelineLocation().Order < t[j].GetTimelineLocation().Order\n}\nfunc (t Timeline) Swap(i, j int) { t[i], t[j] = t[j], t[i] }\nfunc (t Timeline) WithoutHiddenReportEntries() Timeline {\n\tout := Timeline{}\n\tfor _, event := range t {\n\t\tif reportEntry, isReportEntry := event.(ReportEntry); isReportEntry && reportEntry.Visibility == ReportEntryVisibilityNever {\n\t\t\tcontinue\n\t\t}\n\t\tout = append(out, event)\n\t}\n\treturn out\n}\n\nfunc (t Timeline) WithoutVeryVerboseSpecEvents() Timeline {\n\tout := Timeline{}\n\tfor _, event := range t {\n\t\tif specEvent, isSpecEvent := event.(SpecEvent); isSpecEvent && specEvent.IsOnlyVisibleAtVeryVerbose() {\n\t\t\tcontinue\n\t\t}\n\t\tout = append(out, event)\n\t}\n\treturn out\n}\n\n// Failure captures failure information for an individual test\ntype Failure struct {\n\t// Message - the failure message passed into Fail(...).  When using a matcher library\n\t// like Gomega, this will contain the failure message generated by Gomega.\n\t//\n\t// Message is also populated if the user has called Skip(...).\n\tMessage string\n\n\t// Location - the CodeLocation where the failure occurred\n\t// This CodeLocation will include a fully-populated StackTrace\n\tLocation CodeLocation\n\n\tTimelineLocation TimelineLocation\n\n\t// ForwardedPanic - if the failure represents a captured panic (i.e. Summary.State == SpecStatePanicked)\n\t// then ForwardedPanic will be populated with a string representation of the captured panic.\n\tForwardedPanic string `json:\",omitempty\"`\n\n\t// FailureNodeContext - one of three contexts describing the node in which the failure occurred:\n\t// FailureNodeIsLeafNode means the failure occurred in the leaf node of the associated SpecReport. None of the other FailureNode fields will be populated\n\t// FailureNodeAtTopLevel means the failure occurred in a non-leaf node that is defined at the top-level of the spec (i.e. not in a container). FailureNodeType and FailureNodeLocation will be populated.\n\t// FailureNodeInContainer means the failure occurred in a non-leaf node that is defined within a container.  FailureNodeType, FailureNodeLocation, and FailureNodeContainerIndex will be populated.\n\t//\n\t// FailureNodeType will contain the NodeType of the node in which the failure occurred.\n\t// FailureNodeLocation will contain the CodeLocation of the node in which the failure occurred.\n\t// If populated, FailureNodeContainerIndex will be the index into SpecReport.ContainerHierarchyTexts and SpecReport.ContainerHierarchyLocations that represents the parent container of the node in which the failure occurred.\n\tFailureNodeContext FailureNodeContext `json:\",omitempty\"`\n\n\tFailureNodeType NodeType `json:\",omitempty\"`\n\n\tFailureNodeLocation CodeLocation `json:\",omitempty\"`\n\n\tFailureNodeContainerIndex int `json:\",omitempty\"`\n\n\t//ProgressReport is populated if the spec was interrupted or timed out\n\tProgressReport ProgressReport `json:\",omitempty\"`\n\n\t//AdditionalFailure is non-nil if a follow-on failure occurred within the same node after the primary failure.  This only happens when a node has timed out or been interrupted.  In such cases the AdditionalFailure can include information about where/why the spec was stuck.\n\tAdditionalFailure *AdditionalFailure `json:\",omitempty\"`\n}\n\nfunc (f Failure) IsZero() bool {\n\treturn f.Message == \"\" && (f.Location == CodeLocation{})\n}\n\nfunc (f Failure) GetTimelineLocation() TimelineLocation {\n\treturn f.TimelineLocation\n}\n\n// FailureNodeContext captures the location context for the node containing the failing line of code\ntype FailureNodeContext uint\n\nconst (\n\tFailureNodeContextInvalid FailureNodeContext = iota\n\n\tFailureNodeIsLeafNode\n\tFailureNodeAtTopLevel\n\tFailureNodeInContainer\n)\n\nvar fncEnumSupport = NewEnumSupport(map[uint]string{\n\tuint(FailureNodeContextInvalid): \"INVALID FAILURE NODE CONTEXT\",\n\tuint(FailureNodeIsLeafNode):     \"leaf-node\",\n\tuint(FailureNodeAtTopLevel):     \"top-level\",\n\tuint(FailureNodeInContainer):    \"in-container\",\n})\n\nfunc (fnc FailureNodeContext) String() string {\n\treturn fncEnumSupport.String(uint(fnc))\n}\nfunc (fnc *FailureNodeContext) UnmarshalJSON(b []byte) error {\n\tout, err := fncEnumSupport.UnmarshJSON(b)\n\t*fnc = FailureNodeContext(out)\n\treturn err\n}\nfunc (fnc FailureNodeContext) MarshalJSON() ([]byte, error) {\n\treturn fncEnumSupport.MarshJSON(uint(fnc))\n}\n\n// AdditionalFailure capturs any additional failures that occur after the initial failure of a psec\n// these typically occur in clean up nodes after the spec has failed.\n// We can't simply use Failure as we want to track the SpecState to know what kind of failure this is\ntype AdditionalFailure struct {\n\tState   SpecState\n\tFailure Failure\n}\n\nfunc (f AdditionalFailure) GetTimelineLocation() TimelineLocation {\n\treturn f.Failure.TimelineLocation\n}\n\n// SpecState captures the state of a spec\n// To determine if a given `state` represents a failure state, use `state.Is(SpecStateFailureStates)`\ntype SpecState uint\n\nconst (\n\tSpecStateInvalid SpecState = 0\n\n\tSpecStatePending SpecState = 1 << iota\n\tSpecStateSkipped\n\tSpecStatePassed\n\tSpecStateFailed\n\tSpecStateAborted\n\tSpecStatePanicked\n\tSpecStateInterrupted\n\tSpecStateTimedout\n)\n\nvar ssEnumSupport = NewEnumSupport(map[uint]string{\n\tuint(SpecStateInvalid):     \"INVALID SPEC STATE\",\n\tuint(SpecStatePending):     \"pending\",\n\tuint(SpecStateSkipped):     \"skipped\",\n\tuint(SpecStatePassed):      \"passed\",\n\tuint(SpecStateFailed):      \"failed\",\n\tuint(SpecStateAborted):     \"aborted\",\n\tuint(SpecStatePanicked):    \"panicked\",\n\tuint(SpecStateInterrupted): \"interrupted\",\n\tuint(SpecStateTimedout):    \"timedout\",\n})\n\nfunc (ss SpecState) String() string {\n\treturn ssEnumSupport.String(uint(ss))\n}\nfunc (ss SpecState) GomegaString() string {\n\treturn ssEnumSupport.String(uint(ss))\n}\nfunc (ss *SpecState) UnmarshalJSON(b []byte) error {\n\tout, err := ssEnumSupport.UnmarshJSON(b)\n\t*ss = SpecState(out)\n\treturn err\n}\nfunc (ss SpecState) MarshalJSON() ([]byte, error) {\n\treturn ssEnumSupport.MarshJSON(uint(ss))\n}\n\nvar SpecStateFailureStates = SpecStateFailed | SpecStateTimedout | SpecStateAborted | SpecStatePanicked | SpecStateInterrupted\n\nfunc (ss SpecState) Is(states SpecState) bool {\n\treturn ss&states != 0\n}\n\n// ProgressReport captures the progress of the current spec.  It is, effectively, a structured Ginkgo-aware stack trace\ntype ProgressReport struct {\n\tMessage           string `json:\",omitempty\"`\n\tParallelProcess   int    `json:\",omitempty\"`\n\tRunningInParallel bool   `json:\",omitempty\"`\n\n\tContainerHierarchyTexts []string     `json:\",omitempty\"`\n\tLeafNodeText            string       `json:\",omitempty\"`\n\tLeafNodeLocation        CodeLocation `json:\",omitempty\"`\n\tSpecStartTime           time.Time    `json:\",omitempty\"`\n\n\tCurrentNodeType      NodeType     `json:\",omitempty\"`\n\tCurrentNodeText      string       `json:\",omitempty\"`\n\tCurrentNodeLocation  CodeLocation `json:\",omitempty\"`\n\tCurrentNodeStartTime time.Time    `json:\",omitempty\"`\n\n\tCurrentStepText      string       `json:\",omitempty\"`\n\tCurrentStepLocation  CodeLocation `json:\",omitempty\"`\n\tCurrentStepStartTime time.Time    `json:\",omitempty\"`\n\n\tAdditionalReports []string `json:\",omitempty\"`\n\n\tCapturedGinkgoWriterOutput string           `json:\",omitempty\"`\n\tTimelineLocation           TimelineLocation `json:\",omitempty\"`\n\n\tGoroutines []Goroutine `json:\",omitempty\"`\n}\n\nfunc (pr ProgressReport) IsZero() bool {\n\treturn pr.CurrentNodeType == NodeTypeInvalid\n}\n\nfunc (pr ProgressReport) Time() time.Time {\n\treturn pr.TimelineLocation.Time\n}\n\nfunc (pr ProgressReport) SpecGoroutine() Goroutine {\n\tfor _, goroutine := range pr.Goroutines {\n\t\tif goroutine.IsSpecGoroutine {\n\t\t\treturn goroutine\n\t\t}\n\t}\n\treturn Goroutine{}\n}\n\nfunc (pr ProgressReport) HighlightedGoroutines() []Goroutine {\n\tout := []Goroutine{}\n\tfor _, goroutine := range pr.Goroutines {\n\t\tif goroutine.IsSpecGoroutine || !goroutine.HasHighlights() {\n\t\t\tcontinue\n\t\t}\n\t\tout = append(out, goroutine)\n\t}\n\treturn out\n}\n\nfunc (pr ProgressReport) OtherGoroutines() []Goroutine {\n\tout := []Goroutine{}\n\tfor _, goroutine := range pr.Goroutines {\n\t\tif goroutine.IsSpecGoroutine || goroutine.HasHighlights() {\n\t\t\tcontinue\n\t\t}\n\t\tout = append(out, goroutine)\n\t}\n\treturn out\n}\n\nfunc (pr ProgressReport) WithoutCapturedGinkgoWriterOutput() ProgressReport {\n\tout := pr\n\tout.CapturedGinkgoWriterOutput = \"\"\n\treturn out\n}\n\nfunc (pr ProgressReport) WithoutOtherGoroutines() ProgressReport {\n\tout := pr\n\tfilteredGoroutines := []Goroutine{}\n\tfor _, goroutine := range pr.Goroutines {\n\t\tif goroutine.IsSpecGoroutine || goroutine.HasHighlights() {\n\t\t\tfilteredGoroutines = append(filteredGoroutines, goroutine)\n\t\t}\n\t}\n\tout.Goroutines = filteredGoroutines\n\treturn out\n}\n\nfunc (pr ProgressReport) GetTimelineLocation() TimelineLocation {\n\treturn pr.TimelineLocation\n}\n\ntype Goroutine struct {\n\tID              uint64\n\tState           string\n\tStack           []FunctionCall\n\tIsSpecGoroutine bool\n}\n\nfunc (g Goroutine) IsZero() bool {\n\treturn g.ID == 0\n}\n\nfunc (g Goroutine) HasHighlights() bool {\n\tfor _, fc := range g.Stack {\n\t\tif fc.Highlight {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\ntype FunctionCall struct {\n\tFunction        string\n\tFilename        string\n\tLine            int\n\tHighlight       bool     `json:\",omitempty\"`\n\tSource          []string `json:\",omitempty\"`\n\tSourceHighlight int      `json:\",omitempty\"`\n}\n\n// NodeType captures the type of a given Ginkgo Node\ntype NodeType uint\n\nconst (\n\tNodeTypeInvalid NodeType = 0\n\n\tNodeTypeContainer NodeType = 1 << iota\n\tNodeTypeIt\n\n\tNodeTypeBeforeEach\n\tNodeTypeJustBeforeEach\n\tNodeTypeAfterEach\n\tNodeTypeJustAfterEach\n\n\tNodeTypeBeforeAll\n\tNodeTypeAfterAll\n\n\tNodeTypeBeforeSuite\n\tNodeTypeSynchronizedBeforeSuite\n\tNodeTypeAfterSuite\n\tNodeTypeSynchronizedAfterSuite\n\n\tNodeTypeReportBeforeEach\n\tNodeTypeReportAfterEach\n\tNodeTypeReportBeforeSuite\n\tNodeTypeReportAfterSuite\n\n\tNodeTypeCleanupInvalid\n\tNodeTypeCleanupAfterEach\n\tNodeTypeCleanupAfterAll\n\tNodeTypeCleanupAfterSuite\n)\n\nvar NodeTypesForContainerAndIt = NodeTypeContainer | NodeTypeIt\nvar NodeTypesForSuiteLevelNodes = NodeTypeBeforeSuite | NodeTypeSynchronizedBeforeSuite | NodeTypeAfterSuite | NodeTypeSynchronizedAfterSuite | NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite | NodeTypeCleanupAfterSuite\nvar NodeTypesAllowedDuringCleanupInterrupt = NodeTypeAfterEach | NodeTypeJustAfterEach | NodeTypeAfterAll | NodeTypeAfterSuite | NodeTypeSynchronizedAfterSuite | NodeTypeCleanupAfterEach | NodeTypeCleanupAfterAll | NodeTypeCleanupAfterSuite\nvar NodeTypesAllowedDuringReportInterrupt = NodeTypeReportBeforeEach | NodeTypeReportAfterEach | NodeTypeReportBeforeSuite | NodeTypeReportAfterSuite\n\nvar ntEnumSupport = NewEnumSupport(map[uint]string{\n\tuint(NodeTypeInvalid):                 \"INVALID NODE TYPE\",\n\tuint(NodeTypeContainer):               \"Container\",\n\tuint(NodeTypeIt):                      \"It\",\n\tuint(NodeTypeBeforeEach):              \"BeforeEach\",\n\tuint(NodeTypeJustBeforeEach):          \"JustBeforeEach\",\n\tuint(NodeTypeAfterEach):               \"AfterEach\",\n\tuint(NodeTypeJustAfterEach):           \"JustAfterEach\",\n\tuint(NodeTypeBeforeAll):               \"BeforeAll\",\n\tuint(NodeTypeAfterAll):                \"AfterAll\",\n\tuint(NodeTypeBeforeSuite):             \"BeforeSuite\",\n\tuint(NodeTypeSynchronizedBeforeSuite): \"SynchronizedBeforeSuite\",\n\tuint(NodeTypeAfterSuite):              \"AfterSuite\",\n\tuint(NodeTypeSynchronizedAfterSuite):  \"SynchronizedAfterSuite\",\n\tuint(NodeTypeReportBeforeEach):        \"ReportBeforeEach\",\n\tuint(NodeTypeReportAfterEach):         \"ReportAfterEach\",\n\tuint(NodeTypeReportBeforeSuite):       \"ReportBeforeSuite\",\n\tuint(NodeTypeReportAfterSuite):        \"ReportAfterSuite\",\n\tuint(NodeTypeCleanupInvalid):          \"DeferCleanup\",\n\tuint(NodeTypeCleanupAfterEach):        \"DeferCleanup (Each)\",\n\tuint(NodeTypeCleanupAfterAll):         \"DeferCleanup (All)\",\n\tuint(NodeTypeCleanupAfterSuite):       \"DeferCleanup (Suite)\",\n})\n\nfunc (nt NodeType) String() string {\n\treturn ntEnumSupport.String(uint(nt))\n}\nfunc (nt *NodeType) UnmarshalJSON(b []byte) error {\n\tout, err := ntEnumSupport.UnmarshJSON(b)\n\t*nt = NodeType(out)\n\treturn err\n}\nfunc (nt NodeType) MarshalJSON() ([]byte, error) {\n\treturn ntEnumSupport.MarshJSON(uint(nt))\n}\n\nfunc (nt NodeType) Is(nodeTypes NodeType) bool {\n\treturn nt&nodeTypes != 0\n}\n\n/*\nSpecEvent captures a vareity of events that can occur when specs run.  See SpecEventType for the list of available events.\n*/\ntype SpecEvent struct {\n\tSpecEventType SpecEventType\n\n\tCodeLocation     CodeLocation\n\tTimelineLocation TimelineLocation\n\n\tMessage  string        `json:\",omitempty\"`\n\tDuration time.Duration `json:\",omitempty\"`\n\tNodeType NodeType      `json:\",omitempty\"`\n\tAttempt  int           `json:\",omitempty\"`\n}\n\nfunc (se SpecEvent) GetTimelineLocation() TimelineLocation {\n\treturn se.TimelineLocation\n}\n\nfunc (se SpecEvent) IsOnlyVisibleAtVeryVerbose() bool {\n\treturn se.SpecEventType.Is(SpecEventByEnd | SpecEventNodeStart | SpecEventNodeEnd)\n}\n\nfunc (se SpecEvent) GomegaString() string {\n\tout := &strings.Builder{}\n\tout.WriteString(\"[\" + se.SpecEventType.String() + \" SpecEvent] \")\n\tif se.Message != \"\" {\n\t\tout.WriteString(\"Message=\")\n\t\tout.WriteString(`\"` + se.Message + `\",`)\n\t}\n\tif se.Duration != 0 {\n\t\tout.WriteString(\"Duration=\" + se.Duration.String() + \",\")\n\t}\n\tif se.NodeType != NodeTypeInvalid {\n\t\tout.WriteString(\"NodeType=\" + se.NodeType.String() + \",\")\n\t}\n\tif se.Attempt != 0 {\n\t\tout.WriteString(fmt.Sprintf(\"Attempt=%d\", se.Attempt) + \",\")\n\t}\n\tout.WriteString(\"CL=\" + se.CodeLocation.String() + \",\")\n\tout.WriteString(fmt.Sprintf(\"TL.Offset=%d\", se.TimelineLocation.Offset))\n\n\treturn out.String()\n}\n\ntype SpecEvents []SpecEvent\n\nfunc (se SpecEvents) WithType(seType SpecEventType) SpecEvents {\n\tout := SpecEvents{}\n\tfor _, event := range se {\n\t\tif event.SpecEventType.Is(seType) {\n\t\t\tout = append(out, event)\n\t\t}\n\t}\n\treturn out\n}\n\ntype SpecEventType uint\n\nconst (\n\tSpecEventInvalid SpecEventType = 0\n\n\tSpecEventByStart SpecEventType = 1 << iota\n\tSpecEventByEnd\n\tSpecEventNodeStart\n\tSpecEventNodeEnd\n\tSpecEventSpecRepeat\n\tSpecEventSpecRetry\n)\n\nvar seEnumSupport = NewEnumSupport(map[uint]string{\n\tuint(SpecEventInvalid):    \"INVALID SPEC EVENT\",\n\tuint(SpecEventByStart):    \"By\",\n\tuint(SpecEventByEnd):      \"By (End)\",\n\tuint(SpecEventNodeStart):  \"Node\",\n\tuint(SpecEventNodeEnd):    \"Node (End)\",\n\tuint(SpecEventSpecRepeat): \"Repeat\",\n\tuint(SpecEventSpecRetry):  \"Retry\",\n})\n\nfunc (se SpecEventType) String() string {\n\treturn seEnumSupport.String(uint(se))\n}\nfunc (se *SpecEventType) UnmarshalJSON(b []byte) error {\n\tout, err := seEnumSupport.UnmarshJSON(b)\n\t*se = SpecEventType(out)\n\treturn err\n}\nfunc (se SpecEventType) MarshalJSON() ([]byte, error) {\n\treturn seEnumSupport.MarshJSON(uint(se))\n}\n\nfunc (se SpecEventType) Is(specEventTypes SpecEventType) bool {\n\treturn se&specEventTypes != 0\n}\n"
  },
  {
    "path": "vendor/github.com/onsi/ginkgo/v2/types/version.go",
    "content": "package types\n\nconst VERSION = \"2.23.4\"\n"
  },
  {
    "path": "vendor/github.com/pkg/errors/.gitignore",
    "content": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n*.test\n*.prof\n"
  },
  {
    "path": "vendor/github.com/pkg/errors/.travis.yml",
    "content": "language: go\ngo_import_path: github.com/pkg/errors\ngo:\n  - 1.11.x\n  - 1.12.x\n  - 1.13.x\n  - tip\n\nscript:\n  - make check\n"
  },
  {
    "path": "vendor/github.com/pkg/errors/LICENSE",
    "content": "Copyright (c) 2015, Dave Cheney <dave@cheney.net>\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\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": "vendor/github.com/pkg/errors/Makefile",
    "content": "PKGS := github.com/pkg/errors\nSRCDIRS := $(shell go list -f '{{.Dir}}' $(PKGS))\nGO := go\n\ncheck: test vet gofmt misspell unconvert staticcheck ineffassign unparam\n\ntest: \n\t$(GO) test $(PKGS)\n\nvet: | test\n\t$(GO) vet $(PKGS)\n\nstaticcheck:\n\t$(GO) get honnef.co/go/tools/cmd/staticcheck\n\tstaticcheck -checks all $(PKGS)\n\nmisspell:\n\t$(GO) get github.com/client9/misspell/cmd/misspell\n\tmisspell \\\n\t\t-locale GB \\\n\t\t-error \\\n\t\t*.md *.go\n\nunconvert:\n\t$(GO) get github.com/mdempsky/unconvert\n\tunconvert -v $(PKGS)\n\nineffassign:\n\t$(GO) get github.com/gordonklaus/ineffassign\n\tfind $(SRCDIRS) -name '*.go' | xargs ineffassign\n\npedantic: check errcheck\n\nunparam:\n\t$(GO) get mvdan.cc/unparam\n\tunparam ./...\n\nerrcheck:\n\t$(GO) get github.com/kisielk/errcheck\n\terrcheck $(PKGS)\n\ngofmt:  \n\t@echo Checking code is gofmted\n\t@test -z \"$(shell gofmt -s -l -d -e $(SRCDIRS) | tee /dev/stderr)\"\n"
  },
  {
    "path": "vendor/github.com/pkg/errors/README.md",
    "content": "# errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors) [![Sourcegraph](https://sourcegraph.com/github.com/pkg/errors/-/badge.svg)](https://sourcegraph.com/github.com/pkg/errors?badge)\n\nPackage errors provides simple error handling primitives.\n\n`go get github.com/pkg/errors`\n\nThe traditional error handling idiom in Go is roughly akin to\n```go\nif err != nil {\n        return err\n}\n```\nwhich applied recursively up the call stack results in error reports without context or debugging information. The errors package allows programmers to add context to the failure path in their code in a way that does not destroy the original value of the error.\n\n## Adding context to an error\n\nThe errors.Wrap function returns a new error that adds context to the original error. For example\n```go\n_, err := ioutil.ReadAll(r)\nif err != nil {\n        return errors.Wrap(err, \"read failed\")\n}\n```\n## Retrieving the cause of an error\n\nUsing `errors.Wrap` constructs a stack of errors, adding context to the preceding error. Depending on the nature of the error it may be necessary to reverse the operation of errors.Wrap to retrieve the original error for inspection. Any error value which implements this interface can be inspected by `errors.Cause`.\n```go\ntype causer interface {\n        Cause() error\n}\n```\n`errors.Cause` will recursively retrieve the topmost error which does not implement `causer`, which is assumed to be the original cause. For example:\n```go\nswitch err := errors.Cause(err).(type) {\ncase *MyError:\n        // handle specifically\ndefault:\n        // unknown error\n}\n```\n\n[Read the package documentation for more information](https://godoc.org/github.com/pkg/errors).\n\n## Roadmap\n\nWith the upcoming [Go2 error proposals](https://go.googlesource.com/proposal/+/master/design/go2draft.md) this package is moving into maintenance mode. The roadmap for a 1.0 release is as follows:\n\n- 0.9. Remove pre Go 1.9 and Go 1.10 support, address outstanding pull requests (if possible)\n- 1.0. Final release.\n\n## Contributing\n\nBecause of the Go2 errors changes, this package is not accepting proposals for new functionality. With that said, we welcome pull requests, bug fixes and issue reports. \n\nBefore sending a PR, please discuss your change by raising an issue.\n\n## License\n\nBSD-2-Clause\n"
  },
  {
    "path": "vendor/github.com/pkg/errors/appveyor.yml",
    "content": "version: build-{build}.{branch}\n\nclone_folder: C:\\gopath\\src\\github.com\\pkg\\errors\nshallow_clone: true # for startup speed\n\nenvironment:\n  GOPATH: C:\\gopath\n\nplatform:\n  - x64\n\n# http://www.appveyor.com/docs/installed-software\ninstall:\n  # some helpful output for debugging builds\n  - go version\n  - go env\n  # pre-installed MinGW at C:\\MinGW is 32bit only\n  # but MSYS2 at C:\\msys64 has mingw64\n  - set PATH=C:\\msys64\\mingw64\\bin;%PATH%\n  - gcc --version\n  - g++ --version\n\nbuild_script:\n  - go install -v ./...\n\ntest_script:\n  - set PATH=C:\\gopath\\bin;%PATH%\n  - go test -v ./...\n\n#artifacts:\n#  - path: '%GOPATH%\\bin\\*.exe'\ndeploy: off\n"
  },
  {
    "path": "vendor/github.com/pkg/errors/errors.go",
    "content": "// Package errors provides simple error handling primitives.\n//\n// The traditional error handling idiom in Go is roughly akin to\n//\n//     if err != nil {\n//             return err\n//     }\n//\n// which when applied recursively up the call stack results in error reports\n// without context or debugging information. The errors package allows\n// programmers to add context to the failure path in their code in a way\n// that does not destroy the original value of the error.\n//\n// Adding context to an error\n//\n// The errors.Wrap function returns a new error that adds context to the\n// original error by recording a stack trace at the point Wrap is called,\n// together with the supplied message. For example\n//\n//     _, err := ioutil.ReadAll(r)\n//     if err != nil {\n//             return errors.Wrap(err, \"read failed\")\n//     }\n//\n// If additional control is required, the errors.WithStack and\n// errors.WithMessage functions destructure errors.Wrap into its component\n// operations: annotating an error with a stack trace and with a message,\n// respectively.\n//\n// Retrieving the cause of an error\n//\n// Using errors.Wrap constructs a stack of errors, adding context to the\n// preceding error. Depending on the nature of the error it may be necessary\n// to reverse the operation of errors.Wrap to retrieve the original error\n// for inspection. Any error value which implements this interface\n//\n//     type causer interface {\n//             Cause() error\n//     }\n//\n// can be inspected by errors.Cause. errors.Cause will recursively retrieve\n// the topmost error that does not implement causer, which is assumed to be\n// the original cause. For example:\n//\n//     switch err := errors.Cause(err).(type) {\n//     case *MyError:\n//             // handle specifically\n//     default:\n//             // unknown error\n//     }\n//\n// Although the causer interface is not exported by this package, it is\n// considered a part of its stable public interface.\n//\n// Formatted printing of errors\n//\n// All error values returned from this package implement fmt.Formatter and can\n// be formatted by the fmt package. The following verbs are supported:\n//\n//     %s    print the error. If the error has a Cause it will be\n//           printed recursively.\n//     %v    see %s\n//     %+v   extended format. Each Frame of the error's StackTrace will\n//           be printed in detail.\n//\n// Retrieving the stack trace of an error or wrapper\n//\n// New, Errorf, Wrap, and Wrapf record a stack trace at the point they are\n// invoked. This information can be retrieved with the following interface:\n//\n//     type stackTracer interface {\n//             StackTrace() errors.StackTrace\n//     }\n//\n// The returned errors.StackTrace type is defined as\n//\n//     type StackTrace []Frame\n//\n// The Frame type represents a call site in the stack trace. Frame supports\n// the fmt.Formatter interface that can be used for printing information about\n// the stack trace of this error. For example:\n//\n//     if err, ok := err.(stackTracer); ok {\n//             for _, f := range err.StackTrace() {\n//                     fmt.Printf(\"%+s:%d\\n\", f, f)\n//             }\n//     }\n//\n// Although the stackTracer interface is not exported by this package, it is\n// considered a part of its stable public interface.\n//\n// See the documentation for Frame.Format for more details.\npackage errors\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n// New returns an error with the supplied message.\n// New also records the stack trace at the point it was called.\nfunc New(message string) error {\n\treturn &fundamental{\n\t\tmsg:   message,\n\t\tstack: callers(),\n\t}\n}\n\n// Errorf formats according to a format specifier and returns the string\n// as a value that satisfies error.\n// Errorf also records the stack trace at the point it was called.\nfunc Errorf(format string, args ...interface{}) error {\n\treturn &fundamental{\n\t\tmsg:   fmt.Sprintf(format, args...),\n\t\tstack: callers(),\n\t}\n}\n\n// fundamental is an error that has a message and a stack, but no caller.\ntype fundamental struct {\n\tmsg string\n\t*stack\n}\n\nfunc (f *fundamental) Error() string { return f.msg }\n\nfunc (f *fundamental) Format(s fmt.State, verb rune) {\n\tswitch verb {\n\tcase 'v':\n\t\tif s.Flag('+') {\n\t\t\tio.WriteString(s, f.msg)\n\t\t\tf.stack.Format(s, verb)\n\t\t\treturn\n\t\t}\n\t\tfallthrough\n\tcase 's':\n\t\tio.WriteString(s, f.msg)\n\tcase 'q':\n\t\tfmt.Fprintf(s, \"%q\", f.msg)\n\t}\n}\n\n// WithStack annotates err with a stack trace at the point WithStack was called.\n// If err is nil, WithStack returns nil.\nfunc WithStack(err error) error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\treturn &withStack{\n\t\terr,\n\t\tcallers(),\n\t}\n}\n\ntype withStack struct {\n\terror\n\t*stack\n}\n\nfunc (w *withStack) Cause() error { return w.error }\n\n// Unwrap provides compatibility for Go 1.13 error chains.\nfunc (w *withStack) Unwrap() error { return w.error }\n\nfunc (w *withStack) Format(s fmt.State, verb rune) {\n\tswitch verb {\n\tcase 'v':\n\t\tif s.Flag('+') {\n\t\t\tfmt.Fprintf(s, \"%+v\", w.Cause())\n\t\t\tw.stack.Format(s, verb)\n\t\t\treturn\n\t\t}\n\t\tfallthrough\n\tcase 's':\n\t\tio.WriteString(s, w.Error())\n\tcase 'q':\n\t\tfmt.Fprintf(s, \"%q\", w.Error())\n\t}\n}\n\n// Wrap returns an error annotating err with a stack trace\n// at the point Wrap is called, and the supplied message.\n// If err is nil, Wrap returns nil.\nfunc Wrap(err error, message string) error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\terr = &withMessage{\n\t\tcause: err,\n\t\tmsg:   message,\n\t}\n\treturn &withStack{\n\t\terr,\n\t\tcallers(),\n\t}\n}\n\n// Wrapf returns an error annotating err with a stack trace\n// at the point Wrapf is called, and the format specifier.\n// If err is nil, Wrapf returns nil.\nfunc Wrapf(err error, format string, args ...interface{}) error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\terr = &withMessage{\n\t\tcause: err,\n\t\tmsg:   fmt.Sprintf(format, args...),\n\t}\n\treturn &withStack{\n\t\terr,\n\t\tcallers(),\n\t}\n}\n\n// WithMessage annotates err with a new message.\n// If err is nil, WithMessage returns nil.\nfunc WithMessage(err error, message string) error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\treturn &withMessage{\n\t\tcause: err,\n\t\tmsg:   message,\n\t}\n}\n\n// WithMessagef annotates err with the format specifier.\n// If err is nil, WithMessagef returns nil.\nfunc WithMessagef(err error, format string, args ...interface{}) error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\treturn &withMessage{\n\t\tcause: err,\n\t\tmsg:   fmt.Sprintf(format, args...),\n\t}\n}\n\ntype withMessage struct {\n\tcause error\n\tmsg   string\n}\n\nfunc (w *withMessage) Error() string { return w.msg + \": \" + w.cause.Error() }\nfunc (w *withMessage) Cause() error  { return w.cause }\n\n// Unwrap provides compatibility for Go 1.13 error chains.\nfunc (w *withMessage) Unwrap() error { return w.cause }\n\nfunc (w *withMessage) Format(s fmt.State, verb rune) {\n\tswitch verb {\n\tcase 'v':\n\t\tif s.Flag('+') {\n\t\t\tfmt.Fprintf(s, \"%+v\\n\", w.Cause())\n\t\t\tio.WriteString(s, w.msg)\n\t\t\treturn\n\t\t}\n\t\tfallthrough\n\tcase 's', 'q':\n\t\tio.WriteString(s, w.Error())\n\t}\n}\n\n// Cause returns the underlying cause of the error, if possible.\n// An error value has a cause if it implements the following\n// interface:\n//\n//     type causer interface {\n//            Cause() error\n//     }\n//\n// If the error does not implement Cause, the original error will\n// be returned. If the error is nil, nil will be returned without further\n// investigation.\nfunc Cause(err error) error {\n\ttype causer interface {\n\t\tCause() error\n\t}\n\n\tfor err != nil {\n\t\tcause, ok := err.(causer)\n\t\tif !ok {\n\t\t\tbreak\n\t\t}\n\t\terr = cause.Cause()\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/errors/go113.go",
    "content": "// +build go1.13\n\npackage errors\n\nimport (\n\tstderrors \"errors\"\n)\n\n// Is reports whether any error in err's chain matches target.\n//\n// The chain consists of err itself followed by the sequence of errors obtained by\n// repeatedly calling Unwrap.\n//\n// An error is considered to match a target if it is equal to that target or if\n// it implements a method Is(error) bool such that Is(target) returns true.\nfunc Is(err, target error) bool { return stderrors.Is(err, target) }\n\n// As finds the first error in err's chain that matches target, and if so, sets\n// target to that error value and returns true.\n//\n// The chain consists of err itself followed by the sequence of errors obtained by\n// repeatedly calling Unwrap.\n//\n// An error matches target if the error's concrete value is assignable to the value\n// pointed to by target, or if the error has a method As(interface{}) bool such that\n// As(target) returns true. In the latter case, the As method is responsible for\n// setting target.\n//\n// As will panic if target is not a non-nil pointer to either a type that implements\n// error, or to any interface type. As returns false if err is nil.\nfunc As(err error, target interface{}) bool { return stderrors.As(err, target) }\n\n// Unwrap returns the result of calling the Unwrap method on err, if err's\n// type contains an Unwrap method returning error.\n// Otherwise, Unwrap returns nil.\nfunc Unwrap(err error) error {\n\treturn stderrors.Unwrap(err)\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/errors/stack.go",
    "content": "package errors\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"path\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Frame represents a program counter inside a stack frame.\n// For historical reasons if Frame is interpreted as a uintptr\n// its value represents the program counter + 1.\ntype Frame uintptr\n\n// pc returns the program counter for this frame;\n// multiple frames may have the same PC value.\nfunc (f Frame) pc() uintptr { return uintptr(f) - 1 }\n\n// file returns the full path to the file that contains the\n// function for this Frame's pc.\nfunc (f Frame) file() string {\n\tfn := runtime.FuncForPC(f.pc())\n\tif fn == nil {\n\t\treturn \"unknown\"\n\t}\n\tfile, _ := fn.FileLine(f.pc())\n\treturn file\n}\n\n// line returns the line number of source code of the\n// function for this Frame's pc.\nfunc (f Frame) line() int {\n\tfn := runtime.FuncForPC(f.pc())\n\tif fn == nil {\n\t\treturn 0\n\t}\n\t_, line := fn.FileLine(f.pc())\n\treturn line\n}\n\n// name returns the name of this function, if known.\nfunc (f Frame) name() string {\n\tfn := runtime.FuncForPC(f.pc())\n\tif fn == nil {\n\t\treturn \"unknown\"\n\t}\n\treturn fn.Name()\n}\n\n// Format formats the frame according to the fmt.Formatter interface.\n//\n//    %s    source file\n//    %d    source line\n//    %n    function name\n//    %v    equivalent to %s:%d\n//\n// Format accepts flags that alter the printing of some verbs, as follows:\n//\n//    %+s   function name and path of source file relative to the compile time\n//          GOPATH separated by \\n\\t (<funcname>\\n\\t<path>)\n//    %+v   equivalent to %+s:%d\nfunc (f Frame) Format(s fmt.State, verb rune) {\n\tswitch verb {\n\tcase 's':\n\t\tswitch {\n\t\tcase s.Flag('+'):\n\t\t\tio.WriteString(s, f.name())\n\t\t\tio.WriteString(s, \"\\n\\t\")\n\t\t\tio.WriteString(s, f.file())\n\t\tdefault:\n\t\t\tio.WriteString(s, path.Base(f.file()))\n\t\t}\n\tcase 'd':\n\t\tio.WriteString(s, strconv.Itoa(f.line()))\n\tcase 'n':\n\t\tio.WriteString(s, funcname(f.name()))\n\tcase 'v':\n\t\tf.Format(s, 's')\n\t\tio.WriteString(s, \":\")\n\t\tf.Format(s, 'd')\n\t}\n}\n\n// MarshalText formats a stacktrace Frame as a text string. The output is the\n// same as that of fmt.Sprintf(\"%+v\", f), but without newlines or tabs.\nfunc (f Frame) MarshalText() ([]byte, error) {\n\tname := f.name()\n\tif name == \"unknown\" {\n\t\treturn []byte(name), nil\n\t}\n\treturn []byte(fmt.Sprintf(\"%s %s:%d\", name, f.file(), f.line())), nil\n}\n\n// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).\ntype StackTrace []Frame\n\n// Format formats the stack of Frames according to the fmt.Formatter interface.\n//\n//    %s\tlists source files for each Frame in the stack\n//    %v\tlists the source file and line number for each Frame in the stack\n//\n// Format accepts flags that alter the printing of some verbs, as follows:\n//\n//    %+v   Prints filename, function, and line number for each Frame in the stack.\nfunc (st StackTrace) Format(s fmt.State, verb rune) {\n\tswitch verb {\n\tcase 'v':\n\t\tswitch {\n\t\tcase s.Flag('+'):\n\t\t\tfor _, f := range st {\n\t\t\t\tio.WriteString(s, \"\\n\")\n\t\t\t\tf.Format(s, verb)\n\t\t\t}\n\t\tcase s.Flag('#'):\n\t\t\tfmt.Fprintf(s, \"%#v\", []Frame(st))\n\t\tdefault:\n\t\t\tst.formatSlice(s, verb)\n\t\t}\n\tcase 's':\n\t\tst.formatSlice(s, verb)\n\t}\n}\n\n// formatSlice will format this StackTrace into the given buffer as a slice of\n// Frame, only valid when called with '%s' or '%v'.\nfunc (st StackTrace) formatSlice(s fmt.State, verb rune) {\n\tio.WriteString(s, \"[\")\n\tfor i, f := range st {\n\t\tif i > 0 {\n\t\t\tio.WriteString(s, \" \")\n\t\t}\n\t\tf.Format(s, verb)\n\t}\n\tio.WriteString(s, \"]\")\n}\n\n// stack represents a stack of program counters.\ntype stack []uintptr\n\nfunc (s *stack) Format(st fmt.State, verb rune) {\n\tswitch verb {\n\tcase 'v':\n\t\tswitch {\n\t\tcase st.Flag('+'):\n\t\t\tfor _, pc := range *s {\n\t\t\t\tf := Frame(pc)\n\t\t\t\tfmt.Fprintf(st, \"\\n%+v\", f)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (s *stack) StackTrace() StackTrace {\n\tf := make([]Frame, len(*s))\n\tfor i := 0; i < len(f); i++ {\n\t\tf[i] = Frame((*s)[i])\n\t}\n\treturn f\n}\n\nfunc callers() *stack {\n\tconst depth = 32\n\tvar pcs [depth]uintptr\n\tn := runtime.Callers(3, pcs[:])\n\tvar st stack = pcs[0:n]\n\treturn &st\n}\n\n// funcname removes the path prefix component of a function's name reported by func.Name().\nfunc funcname(name string) string {\n\ti := strings.LastIndex(name, \"/\")\n\tname = name[i+1:]\n\ti = strings.Index(name, \".\")\n\treturn name[i+1:]\n}\n"
  },
  {
    "path": "vendor/github.com/pmezard/go-difflib/LICENSE",
    "content": "Copyright (c) 2013, Patrick Mezard\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n    Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n    Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n    The names of its contributors may not be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\nIS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\nTO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\nPARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "vendor/github.com/pmezard/go-difflib/difflib/difflib.go",
    "content": "// Package difflib is a partial port of Python difflib module.\n//\n// It provides tools to compare sequences of strings and generate textual diffs.\n//\n// The following class and functions have been ported:\n//\n// - SequenceMatcher\n//\n// - unified_diff\n//\n// - context_diff\n//\n// Getting unified diffs was the main goal of the port. Keep in mind this code\n// is mostly suitable to output text differences in a human friendly way, there\n// are no guarantees generated diffs are consumable by patch(1).\npackage difflib\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n)\n\nfunc min(a, b int) int {\n\tif a < b {\n\t\treturn a\n\t}\n\treturn b\n}\n\nfunc max(a, b int) int {\n\tif a > b {\n\t\treturn a\n\t}\n\treturn b\n}\n\nfunc calculateRatio(matches, length int) float64 {\n\tif length > 0 {\n\t\treturn 2.0 * float64(matches) / float64(length)\n\t}\n\treturn 1.0\n}\n\ntype Match struct {\n\tA    int\n\tB    int\n\tSize int\n}\n\ntype OpCode struct {\n\tTag byte\n\tI1  int\n\tI2  int\n\tJ1  int\n\tJ2  int\n}\n\n// SequenceMatcher compares sequence of strings. The basic\n// algorithm predates, and is a little fancier than, an algorithm\n// published in the late 1980's by Ratcliff and Obershelp under the\n// hyperbolic name \"gestalt pattern matching\".  The basic idea is to find\n// the longest contiguous matching subsequence that contains no \"junk\"\n// elements (R-O doesn't address junk).  The same idea is then applied\n// recursively to the pieces of the sequences to the left and to the right\n// of the matching subsequence.  This does not yield minimal edit\n// sequences, but does tend to yield matches that \"look right\" to people.\n//\n// SequenceMatcher tries to compute a \"human-friendly diff\" between two\n// sequences.  Unlike e.g. UNIX(tm) diff, the fundamental notion is the\n// longest *contiguous* & junk-free matching subsequence.  That's what\n// catches peoples' eyes.  The Windows(tm) windiff has another interesting\n// notion, pairing up elements that appear uniquely in each sequence.\n// That, and the method here, appear to yield more intuitive difference\n// reports than does diff.  This method appears to be the least vulnerable\n// to synching up on blocks of \"junk lines\", though (like blank lines in\n// ordinary text files, or maybe \"<P>\" lines in HTML files).  That may be\n// because this is the only method of the 3 that has a *concept* of\n// \"junk\" <wink>.\n//\n// Timing:  Basic R-O is cubic time worst case and quadratic time expected\n// case.  SequenceMatcher is quadratic time for the worst case and has\n// expected-case behavior dependent in a complicated way on how many\n// elements the sequences have in common; best case time is linear.\ntype SequenceMatcher struct {\n\ta              []string\n\tb              []string\n\tb2j            map[string][]int\n\tIsJunk         func(string) bool\n\tautoJunk       bool\n\tbJunk          map[string]struct{}\n\tmatchingBlocks []Match\n\tfullBCount     map[string]int\n\tbPopular       map[string]struct{}\n\topCodes        []OpCode\n}\n\nfunc NewMatcher(a, b []string) *SequenceMatcher {\n\tm := SequenceMatcher{autoJunk: true}\n\tm.SetSeqs(a, b)\n\treturn &m\n}\n\nfunc NewMatcherWithJunk(a, b []string, autoJunk bool,\n\tisJunk func(string) bool) *SequenceMatcher {\n\n\tm := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk}\n\tm.SetSeqs(a, b)\n\treturn &m\n}\n\n// Set two sequences to be compared.\nfunc (m *SequenceMatcher) SetSeqs(a, b []string) {\n\tm.SetSeq1(a)\n\tm.SetSeq2(b)\n}\n\n// Set the first sequence to be compared. The second sequence to be compared is\n// not changed.\n//\n// SequenceMatcher computes and caches detailed information about the second\n// sequence, so if you want to compare one sequence S against many sequences,\n// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other\n// sequences.\n//\n// See also SetSeqs() and SetSeq2().\nfunc (m *SequenceMatcher) SetSeq1(a []string) {\n\tif &a == &m.a {\n\t\treturn\n\t}\n\tm.a = a\n\tm.matchingBlocks = nil\n\tm.opCodes = nil\n}\n\n// Set the second sequence to be compared. The first sequence to be compared is\n// not changed.\nfunc (m *SequenceMatcher) SetSeq2(b []string) {\n\tif &b == &m.b {\n\t\treturn\n\t}\n\tm.b = b\n\tm.matchingBlocks = nil\n\tm.opCodes = nil\n\tm.fullBCount = nil\n\tm.chainB()\n}\n\nfunc (m *SequenceMatcher) chainB() {\n\t// Populate line -> index mapping\n\tb2j := map[string][]int{}\n\tfor i, s := range m.b {\n\t\tindices := b2j[s]\n\t\tindices = append(indices, i)\n\t\tb2j[s] = indices\n\t}\n\n\t// Purge junk elements\n\tm.bJunk = map[string]struct{}{}\n\tif m.IsJunk != nil {\n\t\tjunk := m.bJunk\n\t\tfor s, _ := range b2j {\n\t\t\tif m.IsJunk(s) {\n\t\t\t\tjunk[s] = struct{}{}\n\t\t\t}\n\t\t}\n\t\tfor s, _ := range junk {\n\t\t\tdelete(b2j, s)\n\t\t}\n\t}\n\n\t// Purge remaining popular elements\n\tpopular := map[string]struct{}{}\n\tn := len(m.b)\n\tif m.autoJunk && n >= 200 {\n\t\tntest := n/100 + 1\n\t\tfor s, indices := range b2j {\n\t\t\tif len(indices) > ntest {\n\t\t\t\tpopular[s] = struct{}{}\n\t\t\t}\n\t\t}\n\t\tfor s, _ := range popular {\n\t\t\tdelete(b2j, s)\n\t\t}\n\t}\n\tm.bPopular = popular\n\tm.b2j = b2j\n}\n\nfunc (m *SequenceMatcher) isBJunk(s string) bool {\n\t_, ok := m.bJunk[s]\n\treturn ok\n}\n\n// Find longest matching block in a[alo:ahi] and b[blo:bhi].\n//\n// If IsJunk is not defined:\n//\n// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where\n//     alo <= i <= i+k <= ahi\n//     blo <= j <= j+k <= bhi\n// and for all (i',j',k') meeting those conditions,\n//     k >= k'\n//     i <= i'\n//     and if i == i', j <= j'\n//\n// In other words, of all maximal matching blocks, return one that\n// starts earliest in a, and of all those maximal matching blocks that\n// start earliest in a, return the one that starts earliest in b.\n//\n// If IsJunk is defined, first the longest matching block is\n// determined as above, but with the additional restriction that no\n// junk element appears in the block.  Then that block is extended as\n// far as possible by matching (only) junk elements on both sides.  So\n// the resulting block never matches on junk except as identical junk\n// happens to be adjacent to an \"interesting\" match.\n//\n// If no blocks match, return (alo, blo, 0).\nfunc (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match {\n\t// CAUTION:  stripping common prefix or suffix would be incorrect.\n\t// E.g.,\n\t//    ab\n\t//    acab\n\t// Longest matching block is \"ab\", but if common prefix is\n\t// stripped, it's \"a\" (tied with \"b\").  UNIX(tm) diff does so\n\t// strip, so ends up claiming that ab is changed to acab by\n\t// inserting \"ca\" in the middle.  That's minimal but unintuitive:\n\t// \"it's obvious\" that someone inserted \"ac\" at the front.\n\t// Windiff ends up at the same place as diff, but by pairing up\n\t// the unique 'b's and then matching the first two 'a's.\n\tbesti, bestj, bestsize := alo, blo, 0\n\n\t// find longest junk-free match\n\t// during an iteration of the loop, j2len[j] = length of longest\n\t// junk-free match ending with a[i-1] and b[j]\n\tj2len := map[int]int{}\n\tfor i := alo; i != ahi; i++ {\n\t\t// look at all instances of a[i] in b; note that because\n\t\t// b2j has no junk keys, the loop is skipped if a[i] is junk\n\t\tnewj2len := map[int]int{}\n\t\tfor _, j := range m.b2j[m.a[i]] {\n\t\t\t// a[i] matches b[j]\n\t\t\tif j < blo {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif j >= bhi {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tk := j2len[j-1] + 1\n\t\t\tnewj2len[j] = k\n\t\t\tif k > bestsize {\n\t\t\t\tbesti, bestj, bestsize = i-k+1, j-k+1, k\n\t\t\t}\n\t\t}\n\t\tj2len = newj2len\n\t}\n\n\t// Extend the best by non-junk elements on each end.  In particular,\n\t// \"popular\" non-junk elements aren't in b2j, which greatly speeds\n\t// the inner loop above, but also means \"the best\" match so far\n\t// doesn't contain any junk *or* popular non-junk elements.\n\tfor besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) &&\n\t\tm.a[besti-1] == m.b[bestj-1] {\n\t\tbesti, bestj, bestsize = besti-1, bestj-1, bestsize+1\n\t}\n\tfor besti+bestsize < ahi && bestj+bestsize < bhi &&\n\t\t!m.isBJunk(m.b[bestj+bestsize]) &&\n\t\tm.a[besti+bestsize] == m.b[bestj+bestsize] {\n\t\tbestsize += 1\n\t}\n\n\t// Now that we have a wholly interesting match (albeit possibly\n\t// empty!), we may as well suck up the matching junk on each\n\t// side of it too.  Can't think of a good reason not to, and it\n\t// saves post-processing the (possibly considerable) expense of\n\t// figuring out what to do with it.  In the case of an empty\n\t// interesting match, this is clearly the right thing to do,\n\t// because no other kind of match is possible in the regions.\n\tfor besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) &&\n\t\tm.a[besti-1] == m.b[bestj-1] {\n\t\tbesti, bestj, bestsize = besti-1, bestj-1, bestsize+1\n\t}\n\tfor besti+bestsize < ahi && bestj+bestsize < bhi &&\n\t\tm.isBJunk(m.b[bestj+bestsize]) &&\n\t\tm.a[besti+bestsize] == m.b[bestj+bestsize] {\n\t\tbestsize += 1\n\t}\n\n\treturn Match{A: besti, B: bestj, Size: bestsize}\n}\n\n// Return list of triples describing matching subsequences.\n//\n// Each triple is of the form (i, j, n), and means that\n// a[i:i+n] == b[j:j+n].  The triples are monotonically increasing in\n// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are\n// adjacent triples in the list, and the second is not the last triple in the\n// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe\n// adjacent equal blocks.\n//\n// The last triple is a dummy, (len(a), len(b), 0), and is the only\n// triple with n==0.\nfunc (m *SequenceMatcher) GetMatchingBlocks() []Match {\n\tif m.matchingBlocks != nil {\n\t\treturn m.matchingBlocks\n\t}\n\n\tvar matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match\n\tmatchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match {\n\t\tmatch := m.findLongestMatch(alo, ahi, blo, bhi)\n\t\ti, j, k := match.A, match.B, match.Size\n\t\tif match.Size > 0 {\n\t\t\tif alo < i && blo < j {\n\t\t\t\tmatched = matchBlocks(alo, i, blo, j, matched)\n\t\t\t}\n\t\t\tmatched = append(matched, match)\n\t\t\tif i+k < ahi && j+k < bhi {\n\t\t\t\tmatched = matchBlocks(i+k, ahi, j+k, bhi, matched)\n\t\t\t}\n\t\t}\n\t\treturn matched\n\t}\n\tmatched := matchBlocks(0, len(m.a), 0, len(m.b), nil)\n\n\t// It's possible that we have adjacent equal blocks in the\n\t// matching_blocks list now.\n\tnonAdjacent := []Match{}\n\ti1, j1, k1 := 0, 0, 0\n\tfor _, b := range matched {\n\t\t// Is this block adjacent to i1, j1, k1?\n\t\ti2, j2, k2 := b.A, b.B, b.Size\n\t\tif i1+k1 == i2 && j1+k1 == j2 {\n\t\t\t// Yes, so collapse them -- this just increases the length of\n\t\t\t// the first block by the length of the second, and the first\n\t\t\t// block so lengthened remains the block to compare against.\n\t\t\tk1 += k2\n\t\t} else {\n\t\t\t// Not adjacent.  Remember the first block (k1==0 means it's\n\t\t\t// the dummy we started with), and make the second block the\n\t\t\t// new block to compare against.\n\t\t\tif k1 > 0 {\n\t\t\t\tnonAdjacent = append(nonAdjacent, Match{i1, j1, k1})\n\t\t\t}\n\t\t\ti1, j1, k1 = i2, j2, k2\n\t\t}\n\t}\n\tif k1 > 0 {\n\t\tnonAdjacent = append(nonAdjacent, Match{i1, j1, k1})\n\t}\n\n\tnonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0})\n\tm.matchingBlocks = nonAdjacent\n\treturn m.matchingBlocks\n}\n\n// Return list of 5-tuples describing how to turn a into b.\n//\n// Each tuple is of the form (tag, i1, i2, j1, j2).  The first tuple\n// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the\n// tuple preceding it, and likewise for j1 == the previous j2.\n//\n// The tags are characters, with these meanings:\n//\n// 'r' (replace):  a[i1:i2] should be replaced by b[j1:j2]\n//\n// 'd' (delete):   a[i1:i2] should be deleted, j1==j2 in this case.\n//\n// 'i' (insert):   b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case.\n//\n// 'e' (equal):    a[i1:i2] == b[j1:j2]\nfunc (m *SequenceMatcher) GetOpCodes() []OpCode {\n\tif m.opCodes != nil {\n\t\treturn m.opCodes\n\t}\n\ti, j := 0, 0\n\tmatching := m.GetMatchingBlocks()\n\topCodes := make([]OpCode, 0, len(matching))\n\tfor _, m := range matching {\n\t\t//  invariant:  we've pumped out correct diffs to change\n\t\t//  a[:i] into b[:j], and the next matching block is\n\t\t//  a[ai:ai+size] == b[bj:bj+size]. So we need to pump\n\t\t//  out a diff to change a[i:ai] into b[j:bj], pump out\n\t\t//  the matching block, and move (i,j) beyond the match\n\t\tai, bj, size := m.A, m.B, m.Size\n\t\ttag := byte(0)\n\t\tif i < ai && j < bj {\n\t\t\ttag = 'r'\n\t\t} else if i < ai {\n\t\t\ttag = 'd'\n\t\t} else if j < bj {\n\t\t\ttag = 'i'\n\t\t}\n\t\tif tag > 0 {\n\t\t\topCodes = append(opCodes, OpCode{tag, i, ai, j, bj})\n\t\t}\n\t\ti, j = ai+size, bj+size\n\t\t// the list of matching blocks is terminated by a\n\t\t// sentinel with size 0\n\t\tif size > 0 {\n\t\t\topCodes = append(opCodes, OpCode{'e', ai, i, bj, j})\n\t\t}\n\t}\n\tm.opCodes = opCodes\n\treturn m.opCodes\n}\n\n// Isolate change clusters by eliminating ranges with no changes.\n//\n// Return a generator of groups with up to n lines of context.\n// Each group is in the same format as returned by GetOpCodes().\nfunc (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode {\n\tif n < 0 {\n\t\tn = 3\n\t}\n\tcodes := m.GetOpCodes()\n\tif len(codes) == 0 {\n\t\tcodes = []OpCode{OpCode{'e', 0, 1, 0, 1}}\n\t}\n\t// Fixup leading and trailing groups if they show no changes.\n\tif codes[0].Tag == 'e' {\n\t\tc := codes[0]\n\t\ti1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2\n\t\tcodes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2}\n\t}\n\tif codes[len(codes)-1].Tag == 'e' {\n\t\tc := codes[len(codes)-1]\n\t\ti1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2\n\t\tcodes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)}\n\t}\n\tnn := n + n\n\tgroups := [][]OpCode{}\n\tgroup := []OpCode{}\n\tfor _, c := range codes {\n\t\ti1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2\n\t\t// End the current group and start a new one whenever\n\t\t// there is a large range with no changes.\n\t\tif c.Tag == 'e' && i2-i1 > nn {\n\t\t\tgroup = append(group, OpCode{c.Tag, i1, min(i2, i1+n),\n\t\t\t\tj1, min(j2, j1+n)})\n\t\t\tgroups = append(groups, group)\n\t\t\tgroup = []OpCode{}\n\t\t\ti1, j1 = max(i1, i2-n), max(j1, j2-n)\n\t\t}\n\t\tgroup = append(group, OpCode{c.Tag, i1, i2, j1, j2})\n\t}\n\tif len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') {\n\t\tgroups = append(groups, group)\n\t}\n\treturn groups\n}\n\n// Return a measure of the sequences' similarity (float in [0,1]).\n//\n// Where T is the total number of elements in both sequences, and\n// M is the number of matches, this is 2.0*M / T.\n// Note that this is 1 if the sequences are identical, and 0 if\n// they have nothing in common.\n//\n// .Ratio() is expensive to compute if you haven't already computed\n// .GetMatchingBlocks() or .GetOpCodes(), in which case you may\n// want to try .QuickRatio() or .RealQuickRation() first to get an\n// upper bound.\nfunc (m *SequenceMatcher) Ratio() float64 {\n\tmatches := 0\n\tfor _, m := range m.GetMatchingBlocks() {\n\t\tmatches += m.Size\n\t}\n\treturn calculateRatio(matches, len(m.a)+len(m.b))\n}\n\n// Return an upper bound on ratio() relatively quickly.\n//\n// This isn't defined beyond that it is an upper bound on .Ratio(), and\n// is faster to compute.\nfunc (m *SequenceMatcher) QuickRatio() float64 {\n\t// viewing a and b as multisets, set matches to the cardinality\n\t// of their intersection; this counts the number of matches\n\t// without regard to order, so is clearly an upper bound\n\tif m.fullBCount == nil {\n\t\tm.fullBCount = map[string]int{}\n\t\tfor _, s := range m.b {\n\t\t\tm.fullBCount[s] = m.fullBCount[s] + 1\n\t\t}\n\t}\n\n\t// avail[x] is the number of times x appears in 'b' less the\n\t// number of times we've seen it in 'a' so far ... kinda\n\tavail := map[string]int{}\n\tmatches := 0\n\tfor _, s := range m.a {\n\t\tn, ok := avail[s]\n\t\tif !ok {\n\t\t\tn = m.fullBCount[s]\n\t\t}\n\t\tavail[s] = n - 1\n\t\tif n > 0 {\n\t\t\tmatches += 1\n\t\t}\n\t}\n\treturn calculateRatio(matches, len(m.a)+len(m.b))\n}\n\n// Return an upper bound on ratio() very quickly.\n//\n// This isn't defined beyond that it is an upper bound on .Ratio(), and\n// is faster to compute than either .Ratio() or .QuickRatio().\nfunc (m *SequenceMatcher) RealQuickRatio() float64 {\n\tla, lb := len(m.a), len(m.b)\n\treturn calculateRatio(min(la, lb), la+lb)\n}\n\n// Convert range to the \"ed\" format\nfunc formatRangeUnified(start, stop int) string {\n\t// Per the diff spec at http://www.unix.org/single_unix_specification/\n\tbeginning := start + 1 // lines start numbering with one\n\tlength := stop - start\n\tif length == 1 {\n\t\treturn fmt.Sprintf(\"%d\", beginning)\n\t}\n\tif length == 0 {\n\t\tbeginning -= 1 // empty ranges begin at line just before the range\n\t}\n\treturn fmt.Sprintf(\"%d,%d\", beginning, length)\n}\n\n// Unified diff parameters\ntype UnifiedDiff struct {\n\tA        []string // First sequence lines\n\tFromFile string   // First file name\n\tFromDate string   // First file time\n\tB        []string // Second sequence lines\n\tToFile   string   // Second file name\n\tToDate   string   // Second file time\n\tEol      string   // Headers end of line, defaults to LF\n\tContext  int      // Number of context lines\n}\n\n// Compare two sequences of lines; generate the delta as a unified diff.\n//\n// Unified diffs are a compact way of showing line changes and a few\n// lines of context.  The number of context lines is set by 'n' which\n// defaults to three.\n//\n// By default, the diff control lines (those with ---, +++, or @@) are\n// created with a trailing newline.  This is helpful so that inputs\n// created from file.readlines() result in diffs that are suitable for\n// file.writelines() since both the inputs and outputs have trailing\n// newlines.\n//\n// For inputs that do not have trailing newlines, set the lineterm\n// argument to \"\" so that the output will be uniformly newline free.\n//\n// The unidiff format normally has a header for filenames and modification\n// times.  Any or all of these may be specified using strings for\n// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.\n// The modification times are normally expressed in the ISO 8601 format.\nfunc WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error {\n\tbuf := bufio.NewWriter(writer)\n\tdefer buf.Flush()\n\twf := func(format string, args ...interface{}) error {\n\t\t_, err := buf.WriteString(fmt.Sprintf(format, args...))\n\t\treturn err\n\t}\n\tws := func(s string) error {\n\t\t_, err := buf.WriteString(s)\n\t\treturn err\n\t}\n\n\tif len(diff.Eol) == 0 {\n\t\tdiff.Eol = \"\\n\"\n\t}\n\n\tstarted := false\n\tm := NewMatcher(diff.A, diff.B)\n\tfor _, g := range m.GetGroupedOpCodes(diff.Context) {\n\t\tif !started {\n\t\t\tstarted = true\n\t\t\tfromDate := \"\"\n\t\t\tif len(diff.FromDate) > 0 {\n\t\t\t\tfromDate = \"\\t\" + diff.FromDate\n\t\t\t}\n\t\t\ttoDate := \"\"\n\t\t\tif len(diff.ToDate) > 0 {\n\t\t\t\ttoDate = \"\\t\" + diff.ToDate\n\t\t\t}\n\t\t\tif diff.FromFile != \"\" || diff.ToFile != \"\" {\n\t\t\t\terr := wf(\"--- %s%s%s\", diff.FromFile, fromDate, diff.Eol)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\terr = wf(\"+++ %s%s%s\", diff.ToFile, toDate, diff.Eol)\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\t}\n\t\tfirst, last := g[0], g[len(g)-1]\n\t\trange1 := formatRangeUnified(first.I1, last.I2)\n\t\trange2 := formatRangeUnified(first.J1, last.J2)\n\t\tif err := wf(\"@@ -%s +%s @@%s\", range1, range2, diff.Eol); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfor _, c := range g {\n\t\t\ti1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2\n\t\t\tif c.Tag == 'e' {\n\t\t\t\tfor _, line := range diff.A[i1:i2] {\n\t\t\t\t\tif err := ws(\" \" + line); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif c.Tag == 'r' || c.Tag == 'd' {\n\t\t\t\tfor _, line := range diff.A[i1:i2] {\n\t\t\t\t\tif err := ws(\"-\" + line); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif c.Tag == 'r' || c.Tag == 'i' {\n\t\t\t\tfor _, line := range diff.B[j1:j2] {\n\t\t\t\t\tif err := ws(\"+\" + line); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// Like WriteUnifiedDiff but returns the diff a string.\nfunc GetUnifiedDiffString(diff UnifiedDiff) (string, error) {\n\tw := &bytes.Buffer{}\n\terr := WriteUnifiedDiff(w, diff)\n\treturn string(w.Bytes()), err\n}\n\n// Convert range to the \"ed\" format.\nfunc formatRangeContext(start, stop int) string {\n\t// Per the diff spec at http://www.unix.org/single_unix_specification/\n\tbeginning := start + 1 // lines start numbering with one\n\tlength := stop - start\n\tif length == 0 {\n\t\tbeginning -= 1 // empty ranges begin at line just before the range\n\t}\n\tif length <= 1 {\n\t\treturn fmt.Sprintf(\"%d\", beginning)\n\t}\n\treturn fmt.Sprintf(\"%d,%d\", beginning, beginning+length-1)\n}\n\ntype ContextDiff UnifiedDiff\n\n// Compare two sequences of lines; generate the delta as a context diff.\n//\n// Context diffs are a compact way of showing line changes and a few\n// lines of context. The number of context lines is set by diff.Context\n// which defaults to three.\n//\n// By default, the diff control lines (those with *** or ---) are\n// created with a trailing newline.\n//\n// For inputs that do not have trailing newlines, set the diff.Eol\n// argument to \"\" so that the output will be uniformly newline free.\n//\n// The context diff format normally has a header for filenames and\n// modification times.  Any or all of these may be specified using\n// strings for diff.FromFile, diff.ToFile, diff.FromDate, diff.ToDate.\n// The modification times are normally expressed in the ISO 8601 format.\n// If not specified, the strings default to blanks.\nfunc WriteContextDiff(writer io.Writer, diff ContextDiff) error {\n\tbuf := bufio.NewWriter(writer)\n\tdefer buf.Flush()\n\tvar diffErr error\n\twf := func(format string, args ...interface{}) {\n\t\t_, err := buf.WriteString(fmt.Sprintf(format, args...))\n\t\tif diffErr == nil && err != nil {\n\t\t\tdiffErr = err\n\t\t}\n\t}\n\tws := func(s string) {\n\t\t_, err := buf.WriteString(s)\n\t\tif diffErr == nil && err != nil {\n\t\t\tdiffErr = err\n\t\t}\n\t}\n\n\tif len(diff.Eol) == 0 {\n\t\tdiff.Eol = \"\\n\"\n\t}\n\n\tprefix := map[byte]string{\n\t\t'i': \"+ \",\n\t\t'd': \"- \",\n\t\t'r': \"! \",\n\t\t'e': \"  \",\n\t}\n\n\tstarted := false\n\tm := NewMatcher(diff.A, diff.B)\n\tfor _, g := range m.GetGroupedOpCodes(diff.Context) {\n\t\tif !started {\n\t\t\tstarted = true\n\t\t\tfromDate := \"\"\n\t\t\tif len(diff.FromDate) > 0 {\n\t\t\t\tfromDate = \"\\t\" + diff.FromDate\n\t\t\t}\n\t\t\ttoDate := \"\"\n\t\t\tif len(diff.ToDate) > 0 {\n\t\t\t\ttoDate = \"\\t\" + diff.ToDate\n\t\t\t}\n\t\t\tif diff.FromFile != \"\" || diff.ToFile != \"\" {\n\t\t\t\twf(\"*** %s%s%s\", diff.FromFile, fromDate, diff.Eol)\n\t\t\t\twf(\"--- %s%s%s\", diff.ToFile, toDate, diff.Eol)\n\t\t\t}\n\t\t}\n\n\t\tfirst, last := g[0], g[len(g)-1]\n\t\tws(\"***************\" + diff.Eol)\n\n\t\trange1 := formatRangeContext(first.I1, last.I2)\n\t\twf(\"*** %s ****%s\", range1, diff.Eol)\n\t\tfor _, c := range g {\n\t\t\tif c.Tag == 'r' || c.Tag == 'd' {\n\t\t\t\tfor _, cc := range g {\n\t\t\t\t\tif cc.Tag == 'i' {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tfor _, line := range diff.A[cc.I1:cc.I2] {\n\t\t\t\t\t\tws(prefix[cc.Tag] + line)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\trange2 := formatRangeContext(first.J1, last.J2)\n\t\twf(\"--- %s ----%s\", range2, diff.Eol)\n\t\tfor _, c := range g {\n\t\t\tif c.Tag == 'r' || c.Tag == 'i' {\n\t\t\t\tfor _, cc := range g {\n\t\t\t\t\tif cc.Tag == 'd' {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tfor _, line := range diff.B[cc.J1:cc.J2] {\n\t\t\t\t\t\tws(prefix[cc.Tag] + line)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\treturn diffErr\n}\n\n// Like WriteContextDiff but returns the diff a string.\nfunc GetContextDiffString(diff ContextDiff) (string, error) {\n\tw := &bytes.Buffer{}\n\terr := WriteContextDiff(w, diff)\n\treturn string(w.Bytes()), err\n}\n\n// Split a string on \"\\n\" while preserving them. The output can be used\n// as input for UnifiedDiff and ContextDiff structures.\nfunc SplitLines(s string) []string {\n\tlines := strings.SplitAfter(s, \"\\n\")\n\tlines[len(lines)-1] += \"\\n\"\n\treturn lines\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/NOTICE",
    "content": "Prometheus instrumentation library for Go applications\nCopyright 2012-2015 The Prometheus Authors\n\nThis product includes software developed at\nSoundCloud Ltd. (http://soundcloud.com/).\n\n\nThe following components are included in this product:\n\nperks - a fork of https://github.com/bmizerany/perks\nhttps://github.com/beorn7/perks\nCopyright 2013-2015 Blake Mizerany, Björn Rabenstein\nSee https://github.com/beorn7/perks/blob/master/README.md for license details.\n\nGo support for Protocol Buffers - Google's data interchange format\nhttp://github.com/golang/protobuf/\nCopyright 2010 The Go Authors\nSee source code for license details.\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/LICENSE",
    "content": "Copyright (c) 2013 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(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": "vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header/header.go",
    "content": "// Copyright 2013 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\n// Package header provides functions for parsing HTTP headers.\npackage header\n\nimport (\n\t\"net/http\"\n\t\"strings\"\n)\n\n// Octet types from RFC 2616.\nvar octetTypes [256]octetType\n\ntype octetType byte\n\nconst (\n\tisToken octetType = 1 << iota\n\tisSpace\n)\n\nfunc init() {\n\t// OCTET      = <any 8-bit sequence of data>\n\t// CHAR       = <any US-ASCII character (octets 0 - 127)>\n\t// CTL        = <any US-ASCII control character (octets 0 - 31) and DEL (127)>\n\t// CR         = <US-ASCII CR, carriage return (13)>\n\t// LF         = <US-ASCII LF, linefeed (10)>\n\t// SP         = <US-ASCII SP, space (32)>\n\t// HT         = <US-ASCII HT, horizontal-tab (9)>\n\t// <\">        = <US-ASCII double-quote mark (34)>\n\t// CRLF       = CR LF\n\t// LWS        = [CRLF] 1*( SP | HT )\n\t// TEXT       = <any OCTET except CTLs, but including LWS>\n\t// separators = \"(\" | \")\" | \"<\" | \">\" | \"@\" | \",\" | \";\" | \":\" | \"\\\" | <\">\n\t//              | \"/\" | \"[\" | \"]\" | \"?\" | \"=\" | \"{\" | \"}\" | SP | HT\n\t// token      = 1*<any CHAR except CTLs or separators>\n\t// qdtext     = <any TEXT except <\">>\n\n\tfor c := 0; c < 256; c++ {\n\t\tvar t octetType\n\t\tisCtl := c <= 31 || c == 127\n\t\tisChar := 0 <= c && c <= 127\n\t\tisSeparator := strings.ContainsRune(\" \\t\\\"(),/:;<=>?@[]\\\\{}\", rune(c))\n\t\tif strings.ContainsRune(\" \\t\\r\\n\", rune(c)) {\n\t\t\tt |= isSpace\n\t\t}\n\t\tif isChar && !isCtl && !isSeparator {\n\t\t\tt |= isToken\n\t\t}\n\t\toctetTypes[c] = t\n\t}\n}\n\n// AcceptSpec describes an Accept* header.\ntype AcceptSpec struct {\n\tValue string\n\tQ     float64\n}\n\n// ParseAccept parses Accept* headers.\nfunc ParseAccept(header http.Header, key string) (specs []AcceptSpec) {\nloop:\n\tfor _, s := range header[key] {\n\t\tfor {\n\t\t\tvar spec AcceptSpec\n\t\t\tspec.Value, s = expectTokenSlash(s)\n\t\t\tif spec.Value == \"\" {\n\t\t\t\tcontinue loop\n\t\t\t}\n\t\t\tspec.Q = 1.0\n\t\t\ts = skipSpace(s)\n\t\t\tif strings.HasPrefix(s, \";\") {\n\t\t\t\ts = skipSpace(s[1:])\n\t\t\t\tif !strings.HasPrefix(s, \"q=\") {\n\t\t\t\t\tcontinue loop\n\t\t\t\t}\n\t\t\t\tspec.Q, s = expectQuality(s[2:])\n\t\t\t\tif spec.Q < 0.0 {\n\t\t\t\t\tcontinue loop\n\t\t\t\t}\n\t\t\t}\n\t\t\tspecs = append(specs, spec)\n\t\t\ts = skipSpace(s)\n\t\t\tif !strings.HasPrefix(s, \",\") {\n\t\t\t\tcontinue loop\n\t\t\t}\n\t\t\ts = skipSpace(s[1:])\n\t\t}\n\t}\n\treturn\n}\n\nfunc skipSpace(s string) (rest string) {\n\ti := 0\n\tfor ; i < len(s); i++ {\n\t\tif octetTypes[s[i]]&isSpace == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn s[i:]\n}\n\nfunc expectTokenSlash(s string) (token, rest string) {\n\ti := 0\n\tfor ; i < len(s); i++ {\n\t\tb := s[i]\n\t\tif (octetTypes[b]&isToken == 0) && b != '/' {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn s[:i], s[i:]\n}\n\nfunc expectQuality(s string) (q float64, rest string) {\n\tswitch {\n\tcase len(s) == 0:\n\t\treturn -1, \"\"\n\tcase s[0] == '0':\n\t\tq = 0\n\tcase s[0] == '1':\n\t\tq = 1\n\tdefault:\n\t\treturn -1, \"\"\n\t}\n\ts = s[1:]\n\tif !strings.HasPrefix(s, \".\") {\n\t\treturn q, s\n\t}\n\ts = s[1:]\n\ti := 0\n\tn := 0\n\td := 1\n\tfor ; i < len(s); i++ {\n\t\tb := s[i]\n\t\tif b < '0' || b > '9' {\n\t\t\tbreak\n\t\t}\n\t\tn = n*10 + int(b) - '0'\n\t\td *= 10\n\t}\n\treturn q + float64(n)/float64(d), s[i:]\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/negotiate.go",
    "content": "// Copyright 2013 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 httputil\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header\"\n)\n\n// NegotiateContentEncoding returns the best offered content encoding for the\n// request's Accept-Encoding header. If two offers match with equal weight and\n// then the offer earlier in the list is preferred. If no offers are\n// acceptable, then \"\" is returned.\nfunc NegotiateContentEncoding(r *http.Request, offers []string) string {\n\tbestOffer := \"identity\"\n\tbestQ := -1.0\n\tspecs := header.ParseAccept(r.Header, \"Accept-Encoding\")\n\tfor _, offer := range offers {\n\t\tfor _, spec := range specs {\n\t\t\tif spec.Q > bestQ &&\n\t\t\t\t(spec.Value == \"*\" || spec.Value == offer) {\n\t\t\t\tbestQ = spec.Q\n\t\t\t\tbestOffer = offer\n\t\t\t}\n\t\t}\n\t}\n\tif bestQ == 0 {\n\t\tbestOffer = \"\"\n\t}\n\treturn bestOffer\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/.gitignore",
    "content": "command-line-arguments.test\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/README.md",
    "content": "See [![Go Reference](https://pkg.go.dev/badge/github.com/prometheus/client_golang/prometheus.svg)](https://pkg.go.dev/github.com/prometheus/client_golang/prometheus).\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/build_info_collector.go",
    "content": "// Copyright 2021 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\nimport \"runtime/debug\"\n\n// NewBuildInfoCollector is the obsolete version of collectors.NewBuildInfoCollector.\n// See there for documentation.\n//\n// Deprecated: Use collectors.NewBuildInfoCollector instead.\nfunc NewBuildInfoCollector() Collector {\n\tpath, version, sum := \"unknown\", \"unknown\", \"unknown\"\n\tif bi, ok := debug.ReadBuildInfo(); ok {\n\t\tpath = bi.Main.Path\n\t\tversion = bi.Main.Version\n\t\tsum = bi.Main.Sum\n\t}\n\tc := &selfCollector{MustNewConstMetric(\n\t\tNewDesc(\n\t\t\t\"go_build_info\",\n\t\t\t\"Build information about the main Go module.\",\n\t\t\tnil, Labels{\"path\": path, \"version\": version, \"checksum\": sum},\n\t\t),\n\t\tGaugeValue, 1)}\n\tc.init(c.self)\n\treturn c\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/collector.go",
    "content": "// Copyright 2014 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\n// Collector is the interface implemented by anything that can be used by\n// Prometheus to collect metrics. A Collector has to be registered for\n// collection. See Registerer.Register.\n//\n// The stock metrics provided by this package (Gauge, Counter, Summary,\n// Histogram, Untyped) are also Collectors (which only ever collect one metric,\n// namely itself). An implementer of Collector may, however, collect multiple\n// metrics in a coordinated fashion and/or create metrics on the fly. Examples\n// for collectors already implemented in this library are the metric vectors\n// (i.e. collection of multiple instances of the same Metric but with different\n// label values) like GaugeVec or SummaryVec, and the ExpvarCollector.\ntype Collector interface {\n\t// Describe sends the super-set of all possible descriptors of metrics\n\t// collected by this Collector to the provided channel and returns once\n\t// the last descriptor has been sent. The sent descriptors fulfill the\n\t// consistency and uniqueness requirements described in the Desc\n\t// documentation.\n\t//\n\t// It is valid if one and the same Collector sends duplicate\n\t// descriptors. Those duplicates are simply ignored. However, two\n\t// different Collectors must not send duplicate descriptors.\n\t//\n\t// Sending no descriptor at all marks the Collector as “unchecked”,\n\t// i.e. no checks will be performed at registration time, and the\n\t// Collector may yield any Metric it sees fit in its Collect method.\n\t//\n\t// This method idempotently sends the same descriptors throughout the\n\t// lifetime of the Collector. It may be called concurrently and\n\t// therefore must be implemented in a concurrency safe way.\n\t//\n\t// If a Collector encounters an error while executing this method, it\n\t// must send an invalid descriptor (created with NewInvalidDesc) to\n\t// signal the error to the registry.\n\tDescribe(chan<- *Desc)\n\t// Collect is called by the Prometheus registry when collecting\n\t// metrics. The implementation sends each collected metric via the\n\t// provided channel and returns once the last metric has been sent. The\n\t// descriptor of each sent metric is one of those returned by Describe\n\t// (unless the Collector is unchecked, see above). Returned metrics that\n\t// share the same descriptor must differ in their variable label\n\t// values.\n\t//\n\t// This method may be called concurrently and must therefore be\n\t// implemented in a concurrency safe way. Blocking occurs at the expense\n\t// of total performance of rendering all registered metrics. Ideally,\n\t// Collector implementations support concurrent readers.\n\tCollect(chan<- Metric)\n}\n\n// DescribeByCollect is a helper to implement the Describe method of a custom\n// Collector. It collects the metrics from the provided Collector and sends\n// their descriptors to the provided channel.\n//\n// If a Collector collects the same metrics throughout its lifetime, its\n// Describe method can simply be implemented as:\n//\n//\tfunc (c customCollector) Describe(ch chan<- *Desc) {\n//\t\tDescribeByCollect(c, ch)\n//\t}\n//\n// However, this will not work if the metrics collected change dynamically over\n// the lifetime of the Collector in a way that their combined set of descriptors\n// changes as well. The shortcut implementation will then violate the contract\n// of the Describe method. If a Collector sometimes collects no metrics at all\n// (for example vectors like CounterVec, GaugeVec, etc., which only collect\n// metrics after a metric with a fully specified label set has been accessed),\n// it might even get registered as an unchecked Collector (cf. the Register\n// method of the Registerer interface). Hence, only use this shortcut\n// implementation of Describe if you are certain to fulfill the contract.\n//\n// The Collector example demonstrates a use of DescribeByCollect.\nfunc DescribeByCollect(c Collector, descs chan<- *Desc) {\n\tmetrics := make(chan Metric)\n\tgo func() {\n\t\tc.Collect(metrics)\n\t\tclose(metrics)\n\t}()\n\tfor m := range metrics {\n\t\tdescs <- m.Desc()\n\t}\n}\n\n// selfCollector implements Collector for a single Metric so that the Metric\n// collects itself. Add it as an anonymous field to a struct that implements\n// Metric, and call init with the Metric itself as an argument.\ntype selfCollector struct {\n\tself Metric\n}\n\n// init provides the selfCollector with a reference to the metric it is supposed\n// to collect. It is usually called within the factory function to create a\n// metric. See example.\nfunc (c *selfCollector) init(self Metric) {\n\tc.self = self\n}\n\n// Describe implements Collector.\nfunc (c *selfCollector) Describe(ch chan<- *Desc) {\n\tch <- c.self.Desc()\n}\n\n// Collect implements Collector.\nfunc (c *selfCollector) Collect(ch chan<- Metric) {\n\tch <- c.self\n}\n\n// collectorMetric is a metric that is also a collector.\n// Because of selfCollector, most (if not all) Metrics in\n// this package are also collectors.\ntype collectorMetric interface {\n\tMetric\n\tCollector\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/collectorfunc.go",
    "content": "// Copyright 2025 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\n// CollectorFunc is a convenient way to implement a Prometheus Collector\n// without interface boilerplate.\n// This implementation is based on DescribeByCollect method.\n// familiarize yourself to it before using.\ntype CollectorFunc func(chan<- Metric)\n\n// Collect calls the defined CollectorFunc function with the provided Metrics channel\nfunc (f CollectorFunc) Collect(ch chan<- Metric) {\n\tf(ch)\n}\n\n// Describe sends the descriptor information using DescribeByCollect\nfunc (f CollectorFunc) Describe(ch chan<- *Desc) {\n\tDescribeByCollect(f, ch)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/counter.go",
    "content": "// Copyright 2014 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\nimport (\n\t\"errors\"\n\t\"math\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\tdto \"github.com/prometheus/client_model/go\"\n\t\"google.golang.org/protobuf/types/known/timestamppb\"\n)\n\n// Counter is a Metric that represents a single numerical value that only ever\n// goes up. That implies that it cannot be used to count items whose number can\n// also go down, e.g. the number of currently running goroutines. Those\n// \"counters\" are represented by Gauges.\n//\n// A Counter is typically used to count requests served, tasks completed, errors\n// occurred, etc.\n//\n// To create Counter instances, use NewCounter.\ntype Counter interface {\n\tMetric\n\tCollector\n\n\t// Inc increments the counter by 1. Use Add to increment it by arbitrary\n\t// non-negative values.\n\tInc()\n\t// Add adds the given value to the counter. It panics if the value is <\n\t// 0.\n\tAdd(float64)\n}\n\n// ExemplarAdder is implemented by Counters that offer the option of adding a\n// value to the Counter together with an exemplar. Its AddWithExemplar method\n// works like the Add method of the Counter interface but also replaces the\n// currently saved exemplar (if any) with a new one, created from the provided\n// value, the current time as timestamp, and the provided labels. Empty Labels\n// will lead to a valid (label-less) exemplar. But if Labels is nil, the current\n// exemplar is left in place. AddWithExemplar panics if the value is < 0, if any\n// of the provided labels are invalid, or if the provided labels contain more\n// than 128 runes in total.\ntype ExemplarAdder interface {\n\tAddWithExemplar(value float64, exemplar Labels)\n}\n\n// CounterOpts is an alias for Opts. See there for doc comments.\ntype CounterOpts Opts\n\n// CounterVecOpts bundles the options to create a CounterVec metric.\n// It is mandatory to set CounterOpts, see there for mandatory fields. VariableLabels\n// is optional and can safely be left to its default value.\ntype CounterVecOpts struct {\n\tCounterOpts\n\n\t// VariableLabels are used to partition the metric vector by the given set\n\t// of labels. Each label value will be constrained with the optional Constraint\n\t// function, if provided.\n\tVariableLabels ConstrainableLabels\n}\n\n// NewCounter creates a new Counter based on the provided CounterOpts.\n//\n// The returned implementation also implements ExemplarAdder. It is safe to\n// perform the corresponding type assertion.\n//\n// The returned implementation tracks the counter value in two separate\n// variables, a float64 and a uint64. The latter is used to track calls of the\n// Inc method and calls of the Add method with a value that can be represented\n// as a uint64. This allows atomic increments of the counter with optimal\n// performance. (It is common to have an Inc call in very hot execution paths.)\n// Both internal tracking values are added up in the Write method. This has to\n// be taken into account when it comes to precision and overflow behavior.\nfunc NewCounter(opts CounterOpts) Counter {\n\tdesc := NewDesc(\n\t\tBuildFQName(opts.Namespace, opts.Subsystem, opts.Name),\n\t\topts.Help,\n\t\tnil,\n\t\topts.ConstLabels,\n\t)\n\tif opts.now == nil {\n\t\topts.now = time.Now\n\t}\n\tresult := &counter{desc: desc, labelPairs: desc.constLabelPairs, now: opts.now}\n\tresult.init(result) // Init self-collection.\n\tresult.createdTs = timestamppb.New(opts.now())\n\treturn result\n}\n\ntype counter struct {\n\t// valBits contains the bits of the represented float64 value, while\n\t// valInt stores values that are exact integers. Both have to go first\n\t// in the struct to guarantee alignment for atomic operations.\n\t// http://golang.org/pkg/sync/atomic/#pkg-note-BUG\n\tvalBits uint64\n\tvalInt  uint64\n\n\tselfCollector\n\tdesc *Desc\n\n\tcreatedTs  *timestamppb.Timestamp\n\tlabelPairs []*dto.LabelPair\n\texemplar   atomic.Value // Containing nil or a *dto.Exemplar.\n\n\t// now is for testing purposes, by default it's time.Now.\n\tnow func() time.Time\n}\n\nfunc (c *counter) Desc() *Desc {\n\treturn c.desc\n}\n\nfunc (c *counter) Add(v float64) {\n\tif v < 0 {\n\t\tpanic(errors.New(\"counter cannot decrease in value\"))\n\t}\n\n\tival := uint64(v)\n\tif float64(ival) == v {\n\t\tatomic.AddUint64(&c.valInt, ival)\n\t\treturn\n\t}\n\n\tfor {\n\t\toldBits := atomic.LoadUint64(&c.valBits)\n\t\tnewBits := math.Float64bits(math.Float64frombits(oldBits) + v)\n\t\tif atomic.CompareAndSwapUint64(&c.valBits, oldBits, newBits) {\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (c *counter) AddWithExemplar(v float64, e Labels) {\n\tc.Add(v)\n\tc.updateExemplar(v, e)\n}\n\nfunc (c *counter) Inc() {\n\tatomic.AddUint64(&c.valInt, 1)\n}\n\nfunc (c *counter) get() float64 {\n\tfval := math.Float64frombits(atomic.LoadUint64(&c.valBits))\n\tival := atomic.LoadUint64(&c.valInt)\n\treturn fval + float64(ival)\n}\n\nfunc (c *counter) Write(out *dto.Metric) error {\n\t// Read the Exemplar first and the value second. This is to avoid a race condition\n\t// where users see an exemplar for a not-yet-existing observation.\n\tvar exemplar *dto.Exemplar\n\tif e := c.exemplar.Load(); e != nil {\n\t\texemplar = e.(*dto.Exemplar)\n\t}\n\tval := c.get()\n\treturn populateMetric(CounterValue, val, c.labelPairs, exemplar, out, c.createdTs)\n}\n\nfunc (c *counter) updateExemplar(v float64, l Labels) {\n\tif l == nil {\n\t\treturn\n\t}\n\te, err := newExemplar(v, c.now(), l)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tc.exemplar.Store(e)\n}\n\n// CounterVec is a Collector that bundles a set of Counters that all share the\n// same Desc, but have different values for their variable labels. This is used\n// if you want to count the same thing partitioned by various dimensions\n// (e.g. number of HTTP requests, partitioned by response code and\n// method). Create instances with NewCounterVec.\ntype CounterVec struct {\n\t*MetricVec\n}\n\n// NewCounterVec creates a new CounterVec based on the provided CounterOpts and\n// partitioned by the given label names.\nfunc NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {\n\treturn V2.NewCounterVec(CounterVecOpts{\n\t\tCounterOpts:    opts,\n\t\tVariableLabels: UnconstrainedLabels(labelNames),\n\t})\n}\n\n// NewCounterVec creates a new CounterVec based on the provided CounterVecOpts.\nfunc (v2) NewCounterVec(opts CounterVecOpts) *CounterVec {\n\tdesc := V2.NewDesc(\n\t\tBuildFQName(opts.Namespace, opts.Subsystem, opts.Name),\n\t\topts.Help,\n\t\topts.VariableLabels,\n\t\topts.ConstLabels,\n\t)\n\tif opts.now == nil {\n\t\topts.now = time.Now\n\t}\n\treturn &CounterVec{\n\t\tMetricVec: NewMetricVec(desc, func(lvs ...string) Metric {\n\t\t\tif len(lvs) != len(desc.variableLabels.names) {\n\t\t\t\tpanic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, lvs))\n\t\t\t}\n\t\t\tresult := &counter{desc: desc, labelPairs: MakeLabelPairs(desc, lvs), now: opts.now}\n\t\t\tresult.init(result) // Init self-collection.\n\t\t\tresult.createdTs = timestamppb.New(opts.now())\n\t\t\treturn result\n\t\t}),\n\t}\n}\n\n// GetMetricWithLabelValues returns the Counter for the given slice of label\n// values (same order as the variable labels in Desc). If that combination of\n// label values is accessed for the first time, a new Counter is created.\n//\n// It is possible to call this method without using the returned Counter to only\n// create the new Counter but leave it at its starting value 0. See also the\n// SummaryVec example.\n//\n// Keeping the Counter for later use is possible (and should be considered if\n// performance is critical), but keep in mind that Reset, DeleteLabelValues and\n// Delete can be used to delete the Counter from the CounterVec. In that case,\n// the Counter will still exist, but it will not be exported anymore, even if a\n// Counter with the same label values is created later.\n//\n// An error is returned if the number of label values is not the same as the\n// number of variable labels in Desc (minus any curried labels).\n//\n// Note that for more than one label value, this method is prone to mistakes\n// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as\n// an alternative to avoid that type of mistake. For higher label numbers, the\n// latter has a much more readable (albeit more verbose) syntax, but it comes\n// with a performance overhead (for creating and processing the Labels map).\n// See also the GaugeVec example.\nfunc (v *CounterVec) GetMetricWithLabelValues(lvs ...string) (Counter, error) {\n\tmetric, err := v.MetricVec.GetMetricWithLabelValues(lvs...)\n\tif metric != nil {\n\t\treturn metric.(Counter), err\n\t}\n\treturn nil, err\n}\n\n// GetMetricWith returns the Counter for the given Labels map (the label names\n// must match those of the variable labels in Desc). If that label map is\n// accessed for the first time, a new Counter is created. Implications of\n// creating a Counter without using it and keeping the Counter for later use are\n// the same as for GetMetricWithLabelValues.\n//\n// An error is returned if the number and names of the Labels are inconsistent\n// with those of the variable labels in Desc (minus any curried labels).\n//\n// This method is used for the same purpose as\n// GetMetricWithLabelValues(...string). See there for pros and cons of the two\n// methods.\nfunc (v *CounterVec) GetMetricWith(labels Labels) (Counter, error) {\n\tmetric, err := v.MetricVec.GetMetricWith(labels)\n\tif metric != nil {\n\t\treturn metric.(Counter), err\n\t}\n\treturn nil, err\n}\n\n// WithLabelValues works as GetMetricWithLabelValues, but panics where\n// GetMetricWithLabelValues would have returned an error. Not returning an\n// error allows shortcuts like\n//\n//\tmyVec.WithLabelValues(\"404\", \"GET\").Add(42)\nfunc (v *CounterVec) WithLabelValues(lvs ...string) Counter {\n\tc, err := v.GetMetricWithLabelValues(lvs...)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn c\n}\n\n// With works as GetMetricWith, but panics where GetMetricWithLabels would have\n// returned an error. Not returning an error allows shortcuts like\n//\n//\tmyVec.With(prometheus.Labels{\"code\": \"404\", \"method\": \"GET\"}).Add(42)\nfunc (v *CounterVec) With(labels Labels) Counter {\n\tc, err := v.GetMetricWith(labels)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn c\n}\n\n// CurryWith returns a vector curried with the provided labels, i.e. the\n// returned vector has those labels pre-set for all labeled operations performed\n// on it. The cardinality of the curried vector is reduced accordingly. The\n// order of the remaining labels stays the same (just with the curried labels\n// taken out of the sequence – which is relevant for the\n// (GetMetric)WithLabelValues methods). It is possible to curry a curried\n// vector, but only with labels not yet used for currying before.\n//\n// The metrics contained in the CounterVec are shared between the curried and\n// uncurried vectors. They are just accessed differently. Curried and uncurried\n// vectors behave identically in terms of collection. Only one must be\n// registered with a given registry (usually the uncurried version). The Reset\n// method deletes all metrics, even if called on a curried vector.\nfunc (v *CounterVec) CurryWith(labels Labels) (*CounterVec, error) {\n\tvec, err := v.MetricVec.CurryWith(labels)\n\tif vec != nil {\n\t\treturn &CounterVec{vec}, err\n\t}\n\treturn nil, err\n}\n\n// MustCurryWith works as CurryWith but panics where CurryWith would have\n// returned an error.\nfunc (v *CounterVec) MustCurryWith(labels Labels) *CounterVec {\n\tvec, err := v.CurryWith(labels)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn vec\n}\n\n// CounterFunc is a Counter whose value is determined at collect time by calling a\n// provided function.\n//\n// To create CounterFunc instances, use NewCounterFunc.\ntype CounterFunc interface {\n\tMetric\n\tCollector\n}\n\n// NewCounterFunc creates a new CounterFunc based on the provided\n// CounterOpts. The value reported is determined by calling the given function\n// from within the Write method. Take into account that metric collection may\n// happen concurrently. If that results in concurrent calls to Write, like in\n// the case where a CounterFunc is directly registered with Prometheus, the\n// provided function must be concurrency-safe. The function should also honor\n// the contract for a Counter (values only go up, not down), but compliance will\n// not be checked.\n//\n// Check out the ExampleGaugeFunc examples for the similar GaugeFunc.\nfunc NewCounterFunc(opts CounterOpts, function func() float64) CounterFunc {\n\treturn newValueFunc(NewDesc(\n\t\tBuildFQName(opts.Namespace, opts.Subsystem, opts.Name),\n\t\topts.Help,\n\t\tnil,\n\t\topts.ConstLabels,\n\t), CounterValue, function)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/desc.go",
    "content": "// Copyright 2016 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/cespare/xxhash/v2\"\n\tdto \"github.com/prometheus/client_model/go\"\n\t\"github.com/prometheus/common/model\"\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/prometheus/client_golang/prometheus/internal\"\n)\n\n// Desc is the descriptor used by every Prometheus Metric. It is essentially\n// the immutable meta-data of a Metric. The normal Metric implementations\n// included in this package manage their Desc under the hood. Users only have to\n// deal with Desc if they use advanced features like the ExpvarCollector or\n// custom Collectors and Metrics.\n//\n// Descriptors registered with the same registry have to fulfill certain\n// consistency and uniqueness criteria if they share the same fully-qualified\n// name: They must have the same help string and the same label names (aka label\n// dimensions) in each, constLabels and variableLabels, but they must differ in\n// the values of the constLabels.\n//\n// Descriptors that share the same fully-qualified names and the same label\n// values of their constLabels are considered equal.\n//\n// Use NewDesc to create new Desc instances.\ntype Desc struct {\n\t// fqName has been built from Namespace, Subsystem, and Name.\n\tfqName string\n\t// help provides some helpful information about this metric.\n\thelp string\n\t// constLabelPairs contains precalculated DTO label pairs based on\n\t// the constant labels.\n\tconstLabelPairs []*dto.LabelPair\n\t// variableLabels contains names of labels and normalization function for\n\t// which the metric maintains variable values.\n\tvariableLabels *compiledLabels\n\t// id is a hash of the values of the ConstLabels and fqName. This\n\t// must be unique among all registered descriptors and can therefore be\n\t// used as an identifier of the descriptor.\n\tid uint64\n\t// dimHash is a hash of the label names (preset and variable) and the\n\t// Help string. Each Desc with the same fqName must have the same\n\t// dimHash.\n\tdimHash uint64\n\t// err is an error that occurred during construction. It is reported on\n\t// registration time.\n\terr error\n}\n\n// NewDesc allocates and initializes a new Desc. Errors are recorded in the Desc\n// and will be reported on registration time. variableLabels and constLabels can\n// be nil if no such labels should be set. fqName must not be empty.\n//\n// variableLabels only contain the label names. Their label values are variable\n// and therefore not part of the Desc. (They are managed within the Metric.)\n//\n// For constLabels, the label values are constant. Therefore, they are fully\n// specified in the Desc. See the Collector example for a usage pattern.\nfunc NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *Desc {\n\treturn V2.NewDesc(fqName, help, UnconstrainedLabels(variableLabels), constLabels)\n}\n\n// NewDesc allocates and initializes a new Desc. Errors are recorded in the Desc\n// and will be reported on registration time. variableLabels and constLabels can\n// be nil if no such labels should be set. fqName must not be empty.\n//\n// variableLabels only contain the label names and normalization functions. Their\n// label values are variable and therefore not part of the Desc. (They are managed\n// within the Metric.)\n//\n// For constLabels, the label values are constant. Therefore, they are fully\n// specified in the Desc. See the Collector example for a usage pattern.\nfunc (v2) NewDesc(fqName, help string, variableLabels ConstrainableLabels, constLabels Labels) *Desc {\n\td := &Desc{\n\t\tfqName:         fqName,\n\t\thelp:           help,\n\t\tvariableLabels: variableLabels.compile(),\n\t}\n\tif !model.IsValidMetricName(model.LabelValue(fqName)) {\n\t\td.err = fmt.Errorf(\"%q is not a valid metric name\", fqName)\n\t\treturn d\n\t}\n\t// labelValues contains the label values of const labels (in order of\n\t// their sorted label names) plus the fqName (at position 0).\n\tlabelValues := make([]string, 1, len(constLabels)+1)\n\tlabelValues[0] = fqName\n\tlabelNames := make([]string, 0, len(constLabels)+len(d.variableLabels.names))\n\tlabelNameSet := map[string]struct{}{}\n\t// First add only the const label names and sort them...\n\tfor labelName := range constLabels {\n\t\tif !checkLabelName(labelName) {\n\t\t\td.err = fmt.Errorf(\"%q is not a valid label name for metric %q\", labelName, fqName)\n\t\t\treturn d\n\t\t}\n\t\tlabelNames = append(labelNames, labelName)\n\t\tlabelNameSet[labelName] = struct{}{}\n\t}\n\tsort.Strings(labelNames)\n\t// ... so that we can now add const label values in the order of their names.\n\tfor _, labelName := range labelNames {\n\t\tlabelValues = append(labelValues, constLabels[labelName])\n\t}\n\t// Validate the const label values. They can't have a wrong cardinality, so\n\t// use in len(labelValues) as expectedNumberOfValues.\n\tif err := validateLabelValues(labelValues, len(labelValues)); err != nil {\n\t\td.err = err\n\t\treturn d\n\t}\n\t// Now add the variable label names, but prefix them with something that\n\t// cannot be in a regular label name. That prevents matching the label\n\t// dimension with a different mix between preset and variable labels.\n\tfor _, label := range d.variableLabels.names {\n\t\tif !checkLabelName(label) {\n\t\t\td.err = fmt.Errorf(\"%q is not a valid label name for metric %q\", label, fqName)\n\t\t\treturn d\n\t\t}\n\t\tlabelNames = append(labelNames, \"$\"+label)\n\t\tlabelNameSet[label] = struct{}{}\n\t}\n\tif len(labelNames) != len(labelNameSet) {\n\t\td.err = fmt.Errorf(\"duplicate label names in constant and variable labels for metric %q\", fqName)\n\t\treturn d\n\t}\n\n\txxh := xxhash.New()\n\tfor _, val := range labelValues {\n\t\txxh.WriteString(val)\n\t\txxh.Write(separatorByteSlice)\n\t}\n\td.id = xxh.Sum64()\n\t// Sort labelNames so that order doesn't matter for the hash.\n\tsort.Strings(labelNames)\n\t// Now hash together (in this order) the help string and the sorted\n\t// label names.\n\txxh.Reset()\n\txxh.WriteString(help)\n\txxh.Write(separatorByteSlice)\n\tfor _, labelName := range labelNames {\n\t\txxh.WriteString(labelName)\n\t\txxh.Write(separatorByteSlice)\n\t}\n\td.dimHash = xxh.Sum64()\n\n\td.constLabelPairs = make([]*dto.LabelPair, 0, len(constLabels))\n\tfor n, v := range constLabels {\n\t\td.constLabelPairs = append(d.constLabelPairs, &dto.LabelPair{\n\t\t\tName:  proto.String(n),\n\t\t\tValue: proto.String(v),\n\t\t})\n\t}\n\tsort.Sort(internal.LabelPairSorter(d.constLabelPairs))\n\treturn d\n}\n\n// NewInvalidDesc returns an invalid descriptor, i.e. a descriptor with the\n// provided error set. If a collector returning such a descriptor is registered,\n// registration will fail with the provided error. NewInvalidDesc can be used by\n// a Collector to signal inability to describe itself.\nfunc NewInvalidDesc(err error) *Desc {\n\treturn &Desc{\n\t\terr: err,\n\t}\n}\n\nfunc (d *Desc) String() string {\n\tlpStrings := make([]string, 0, len(d.constLabelPairs))\n\tfor _, lp := range d.constLabelPairs {\n\t\tlpStrings = append(\n\t\t\tlpStrings,\n\t\t\tfmt.Sprintf(\"%s=%q\", lp.GetName(), lp.GetValue()),\n\t\t)\n\t}\n\tvlStrings := []string{}\n\tif d.variableLabels != nil {\n\t\tvlStrings = make([]string, 0, len(d.variableLabels.names))\n\t\tfor _, vl := range d.variableLabels.names {\n\t\t\tif fn, ok := d.variableLabels.labelConstraints[vl]; ok && fn != nil {\n\t\t\t\tvlStrings = append(vlStrings, fmt.Sprintf(\"c(%s)\", vl))\n\t\t\t} else {\n\t\t\t\tvlStrings = append(vlStrings, vl)\n\t\t\t}\n\t\t}\n\t}\n\treturn fmt.Sprintf(\n\t\t\"Desc{fqName: %q, help: %q, constLabels: {%s}, variableLabels: {%s}}\",\n\t\td.fqName,\n\t\td.help,\n\t\tstrings.Join(lpStrings, \",\"),\n\t\tstrings.Join(vlStrings, \",\"),\n\t)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/doc.go",
    "content": "// Copyright 2014 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Package prometheus is the core instrumentation package. It provides metrics\n// primitives to instrument code for monitoring. It also offers a registry for\n// metrics. Sub-packages allow to expose the registered metrics via HTTP\n// (package promhttp) or push them to a Pushgateway (package push). There is\n// also a sub-package promauto, which provides metrics constructors with\n// automatic registration.\n//\n// All exported functions and methods are safe to be used concurrently unless\n// specified otherwise.\n//\n// # A Basic Example\n//\n// As a starting point, a very basic usage example:\n//\n//\tpackage main\n//\n//\timport (\n//\t\t\"log\"\n//\t\t\"net/http\"\n//\n//\t\t\"github.com/prometheus/client_golang/prometheus\"\n//\t\t\"github.com/prometheus/client_golang/prometheus/promhttp\"\n//\t)\n//\n//\ttype metrics struct {\n//\t\tcpuTemp  prometheus.Gauge\n//\t\thdFailures *prometheus.CounterVec\n//\t}\n//\n//\tfunc NewMetrics(reg prometheus.Registerer) *metrics {\n//\t\tm := &metrics{\n//\t\t\tcpuTemp: prometheus.NewGauge(prometheus.GaugeOpts{\n//\t\t\t\tName: \"cpu_temperature_celsius\",\n//\t\t\t\tHelp: \"Current temperature of the CPU.\",\n//\t\t\t}),\n//\t\t\thdFailures: prometheus.NewCounterVec(\n//\t\t\t\tprometheus.CounterOpts{\n//\t\t\t\t\tName: \"hd_errors_total\",\n//\t\t\t\t\tHelp: \"Number of hard-disk errors.\",\n//\t\t\t\t},\n//\t\t\t\t[]string{\"device\"},\n//\t\t\t),\n//\t\t}\n//\t\treg.MustRegister(m.cpuTemp)\n//\t\treg.MustRegister(m.hdFailures)\n//\t\treturn m\n//\t}\n//\n//\tfunc main() {\n//\t\t// Create a non-global registry.\n//\t\treg := prometheus.NewRegistry()\n//\n//\t\t// Create new metrics and register them using the custom registry.\n//\t\tm := NewMetrics(reg)\n//\t\t// Set values for the new created metrics.\n//\t\tm.cpuTemp.Set(65.3)\n//\t\tm.hdFailures.With(prometheus.Labels{\"device\":\"/dev/sda\"}).Inc()\n//\n//\t\t// Expose metrics and custom registry via an HTTP server\n//\t\t// using the HandleFor function. \"/metrics\" is the usual endpoint for that.\n//\t\thttp.Handle(\"/metrics\", promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: reg}))\n//\t\tlog.Fatal(http.ListenAndServe(\":8080\", nil))\n//\t}\n//\n// This is a complete program that exports two metrics, a Gauge and a Counter,\n// the latter with a label attached to turn it into a (one-dimensional) vector.\n// It register the metrics using a custom registry and exposes them via an HTTP server\n// on the /metrics endpoint.\n//\n// # Metrics\n//\n// The number of exported identifiers in this package might appear a bit\n// overwhelming. However, in addition to the basic plumbing shown in the example\n// above, you only need to understand the different metric types and their\n// vector versions for basic usage. Furthermore, if you are not concerned with\n// fine-grained control of when and how to register metrics with the registry,\n// have a look at the promauto package, which will effectively allow you to\n// ignore registration altogether in simple cases.\n//\n// Above, you have already touched the Counter and the Gauge. There are two more\n// advanced metric types: the Summary and Histogram. A more thorough description\n// of those four metric types can be found in the Prometheus docs:\n// https://prometheus.io/docs/concepts/metric_types/\n//\n// In addition to the fundamental metric types Gauge, Counter, Summary, and\n// Histogram, a very important part of the Prometheus data model is the\n// partitioning of samples along dimensions called labels, which results in\n// metric vectors. The fundamental types are GaugeVec, CounterVec, SummaryVec,\n// and HistogramVec.\n//\n// While only the fundamental metric types implement the Metric interface, both\n// the metrics and their vector versions implement the Collector interface. A\n// Collector manages the collection of a number of Metrics, but for convenience,\n// a Metric can also “collect itself”. Note that Gauge, Counter, Summary, and\n// Histogram are interfaces themselves while GaugeVec, CounterVec, SummaryVec,\n// and HistogramVec are not.\n//\n// To create instances of Metrics and their vector versions, you need a suitable\n// …Opts struct, i.e. GaugeOpts, CounterOpts, SummaryOpts, or HistogramOpts.\n//\n// # Custom Collectors and constant Metrics\n//\n// While you could create your own implementations of Metric, most likely you\n// will only ever implement the Collector interface on your own. At a first\n// glance, a custom Collector seems handy to bundle Metrics for common\n// registration (with the prime example of the different metric vectors above,\n// which bundle all the metrics of the same name but with different labels).\n//\n// There is a more involved use case, too: If you already have metrics\n// available, created outside of the Prometheus context, you don't need the\n// interface of the various Metric types. You essentially want to mirror the\n// existing numbers into Prometheus Metrics during collection. An own\n// implementation of the Collector interface is perfect for that. You can create\n// Metric instances “on the fly” using NewConstMetric, NewConstHistogram, and\n// NewConstSummary (and their respective Must… versions). NewConstMetric is used\n// for all metric types with just a float64 as their value: Counter, Gauge, and\n// a special “type” called Untyped. Use the latter if you are not sure if the\n// mirrored metric is a Counter or a Gauge. Creation of the Metric instance\n// happens in the Collect method. The Describe method has to return separate\n// Desc instances, representative of the “throw-away” metrics to be created\n// later.  NewDesc comes in handy to create those Desc instances. Alternatively,\n// you could return no Desc at all, which will mark the Collector “unchecked”.\n// No checks are performed at registration time, but metric consistency will\n// still be ensured at scrape time, i.e. any inconsistencies will lead to scrape\n// errors. Thus, with unchecked Collectors, the responsibility to not collect\n// metrics that lead to inconsistencies in the total scrape result lies with the\n// implementer of the Collector. While this is not a desirable state, it is\n// sometimes necessary. The typical use case is a situation where the exact\n// metrics to be returned by a Collector cannot be predicted at registration\n// time, but the implementer has sufficient knowledge of the whole system to\n// guarantee metric consistency.\n//\n// The Collector example illustrates the use case. You can also look at the\n// source code of the processCollector (mirroring process metrics), the\n// goCollector (mirroring Go metrics), or the expvarCollector (mirroring expvar\n// metrics) as examples that are used in this package itself.\n//\n// If you just need to call a function to get a single float value to collect as\n// a metric, GaugeFunc, CounterFunc, or UntypedFunc might be interesting\n// shortcuts.\n//\n// # Advanced Uses of the Registry\n//\n// While MustRegister is the by far most common way of registering a Collector,\n// sometimes you might want to handle the errors the registration might cause.\n// As suggested by the name, MustRegister panics if an error occurs. With the\n// Register function, the error is returned and can be handled.\n//\n// An error is returned if the registered Collector is incompatible or\n// inconsistent with already registered metrics. The registry aims for\n// consistency of the collected metrics according to the Prometheus data model.\n// Inconsistencies are ideally detected at registration time, not at collect\n// time. The former will usually be detected at start-up time of a program,\n// while the latter will only happen at scrape time, possibly not even on the\n// first scrape if the inconsistency only becomes relevant later. That is the\n// main reason why a Collector and a Metric have to describe themselves to the\n// registry.\n//\n// So far, everything we did operated on the so-called default registry, as it\n// can be found in the global DefaultRegisterer variable. With NewRegistry, you\n// can create a custom registry, or you can even implement the Registerer or\n// Gatherer interfaces yourself. The methods Register and Unregister work in the\n// same way on a custom registry as the global functions Register and Unregister\n// on the default registry.\n//\n// There are a number of uses for custom registries: You can use registries with\n// special properties, see NewPedanticRegistry. You can avoid global state, as\n// it is imposed by the DefaultRegisterer. You can use multiple registries at\n// the same time to expose different metrics in different ways.  You can use\n// separate registries for testing purposes.\n//\n// Also note that the DefaultRegisterer comes registered with a Collector for Go\n// runtime metrics (via NewGoCollector) and a Collector for process metrics (via\n// NewProcessCollector). With a custom registry, you are in control and decide\n// yourself about the Collectors to register.\n//\n// # HTTP Exposition\n//\n// The Registry implements the Gatherer interface. The caller of the Gather\n// method can then expose the gathered metrics in some way. Usually, the metrics\n// are served via HTTP on the /metrics endpoint. That's happening in the example\n// above. The tools to expose metrics via HTTP are in the promhttp sub-package.\n//\n// # Pushing to the Pushgateway\n//\n// Function for pushing to the Pushgateway can be found in the push sub-package.\n//\n// # Graphite Bridge\n//\n// Functions and examples to push metrics from a Gatherer to Graphite can be\n// found in the graphite sub-package.\n//\n// # Other Means of Exposition\n//\n// More ways of exposing metrics can easily be added by following the approaches\n// of the existing implementations.\npackage prometheus\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go",
    "content": "// Copyright 2014 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\nimport (\n\t\"encoding/json\"\n\t\"expvar\"\n)\n\ntype expvarCollector struct {\n\texports map[string]*Desc\n}\n\n// NewExpvarCollector is the obsolete version of collectors.NewExpvarCollector.\n// See there for documentation.\n//\n// Deprecated: Use collectors.NewExpvarCollector instead.\nfunc NewExpvarCollector(exports map[string]*Desc) Collector {\n\treturn &expvarCollector{\n\t\texports: exports,\n\t}\n}\n\n// Describe implements Collector.\nfunc (e *expvarCollector) Describe(ch chan<- *Desc) {\n\tfor _, desc := range e.exports {\n\t\tch <- desc\n\t}\n}\n\n// Collect implements Collector.\nfunc (e *expvarCollector) Collect(ch chan<- Metric) {\n\tfor name, desc := range e.exports {\n\t\tvar m Metric\n\t\texpVar := expvar.Get(name)\n\t\tif expVar == nil {\n\t\t\tcontinue\n\t\t}\n\t\tvar v interface{}\n\t\tlabels := make([]string, len(desc.variableLabels.names))\n\t\tif err := json.Unmarshal([]byte(expVar.String()), &v); err != nil {\n\t\t\tch <- NewInvalidMetric(desc, err)\n\t\t\tcontinue\n\t\t}\n\t\tvar processValue func(v interface{}, i int)\n\t\tprocessValue = func(v interface{}, i int) {\n\t\t\tif i >= len(labels) {\n\t\t\t\tcopiedLabels := append(make([]string, 0, len(labels)), labels...)\n\t\t\t\tswitch v := v.(type) {\n\t\t\t\tcase float64:\n\t\t\t\t\tm = MustNewConstMetric(desc, UntypedValue, v, copiedLabels...)\n\t\t\t\tcase bool:\n\t\t\t\t\tif v {\n\t\t\t\t\t\tm = MustNewConstMetric(desc, UntypedValue, 1, copiedLabels...)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tm = MustNewConstMetric(desc, UntypedValue, 0, copiedLabels...)\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tch <- m\n\t\t\t\treturn\n\t\t\t}\n\t\t\tvm, ok := v.(map[string]interface{})\n\t\t\tif !ok {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tfor lv, val := range vm {\n\t\t\t\tlabels[i] = lv\n\t\t\t\tprocessValue(val, i+1)\n\t\t\t}\n\t\t}\n\t\tprocessValue(v, 0)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/fnv.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\n// Inline and byte-free variant of hash/fnv's fnv64a.\n\nconst (\n\toffset64 = 14695981039346656037\n\tprime64  = 1099511628211\n)\n\n// hashNew initializies a new fnv64a hash value.\nfunc hashNew() uint64 {\n\treturn offset64\n}\n\n// hashAdd adds a string to a fnv64a hash value, returning the updated hash.\nfunc hashAdd(h uint64, s string) uint64 {\n\tfor i := 0; i < len(s); i++ {\n\t\th ^= uint64(s[i])\n\t\th *= prime64\n\t}\n\treturn h\n}\n\n// hashAddByte adds a byte to a fnv64a hash value, returning the updated hash.\nfunc hashAddByte(h uint64, b byte) uint64 {\n\th ^= uint64(b)\n\th *= prime64\n\treturn h\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/gauge.go",
    "content": "// Copyright 2014 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\nimport (\n\t\"math\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\tdto \"github.com/prometheus/client_model/go\"\n)\n\n// Gauge is a Metric that represents a single numerical value that can\n// arbitrarily go up and down.\n//\n// A Gauge is typically used for measured values like temperatures or current\n// memory usage, but also \"counts\" that can go up and down, like the number of\n// running goroutines.\n//\n// To create Gauge instances, use NewGauge.\ntype Gauge interface {\n\tMetric\n\tCollector\n\n\t// Set sets the Gauge to an arbitrary value.\n\tSet(float64)\n\t// Inc increments the Gauge by 1. Use Add to increment it by arbitrary\n\t// values.\n\tInc()\n\t// Dec decrements the Gauge by 1. Use Sub to decrement it by arbitrary\n\t// values.\n\tDec()\n\t// Add adds the given value to the Gauge. (The value can be negative,\n\t// resulting in a decrease of the Gauge.)\n\tAdd(float64)\n\t// Sub subtracts the given value from the Gauge. (The value can be\n\t// negative, resulting in an increase of the Gauge.)\n\tSub(float64)\n\n\t// SetToCurrentTime sets the Gauge to the current Unix time in seconds.\n\tSetToCurrentTime()\n}\n\n// GaugeOpts is an alias for Opts. See there for doc comments.\ntype GaugeOpts Opts\n\n// GaugeVecOpts bundles the options to create a GaugeVec metric.\n// It is mandatory to set GaugeOpts, see there for mandatory fields. VariableLabels\n// is optional and can safely be left to its default value.\ntype GaugeVecOpts struct {\n\tGaugeOpts\n\n\t// VariableLabels are used to partition the metric vector by the given set\n\t// of labels. Each label value will be constrained with the optional Constraint\n\t// function, if provided.\n\tVariableLabels ConstrainableLabels\n}\n\n// NewGauge creates a new Gauge based on the provided GaugeOpts.\n//\n// The returned implementation is optimized for a fast Set method. If you have a\n// choice for managing the value of a Gauge via Set vs. Inc/Dec/Add/Sub, pick\n// the former. For example, the Inc method of the returned Gauge is slower than\n// the Inc method of a Counter returned by NewCounter. This matches the typical\n// scenarios for Gauges and Counters, where the former tends to be Set-heavy and\n// the latter Inc-heavy.\nfunc NewGauge(opts GaugeOpts) Gauge {\n\tdesc := NewDesc(\n\t\tBuildFQName(opts.Namespace, opts.Subsystem, opts.Name),\n\t\topts.Help,\n\t\tnil,\n\t\topts.ConstLabels,\n\t)\n\tresult := &gauge{desc: desc, labelPairs: desc.constLabelPairs}\n\tresult.init(result) // Init self-collection.\n\treturn result\n}\n\ntype gauge struct {\n\t// valBits contains the bits of the represented float64 value. It has\n\t// to go first in the struct to guarantee alignment for atomic\n\t// operations.  http://golang.org/pkg/sync/atomic/#pkg-note-BUG\n\tvalBits uint64\n\n\tselfCollector\n\n\tdesc       *Desc\n\tlabelPairs []*dto.LabelPair\n}\n\nfunc (g *gauge) Desc() *Desc {\n\treturn g.desc\n}\n\nfunc (g *gauge) Set(val float64) {\n\tatomic.StoreUint64(&g.valBits, math.Float64bits(val))\n}\n\nfunc (g *gauge) SetToCurrentTime() {\n\tg.Set(float64(time.Now().UnixNano()) / 1e9)\n}\n\nfunc (g *gauge) Inc() {\n\tg.Add(1)\n}\n\nfunc (g *gauge) Dec() {\n\tg.Add(-1)\n}\n\nfunc (g *gauge) Add(val float64) {\n\tfor {\n\t\toldBits := atomic.LoadUint64(&g.valBits)\n\t\tnewBits := math.Float64bits(math.Float64frombits(oldBits) + val)\n\t\tif atomic.CompareAndSwapUint64(&g.valBits, oldBits, newBits) {\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (g *gauge) Sub(val float64) {\n\tg.Add(val * -1)\n}\n\nfunc (g *gauge) Write(out *dto.Metric) error {\n\tval := math.Float64frombits(atomic.LoadUint64(&g.valBits))\n\treturn populateMetric(GaugeValue, val, g.labelPairs, nil, out, nil)\n}\n\n// GaugeVec is a Collector that bundles a set of Gauges that all share the same\n// Desc, but have different values for their variable labels. This is used if\n// you want to count the same thing partitioned by various dimensions\n// (e.g. number of operations queued, partitioned by user and operation\n// type). Create instances with NewGaugeVec.\ntype GaugeVec struct {\n\t*MetricVec\n}\n\n// NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and\n// partitioned by the given label names.\nfunc NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {\n\treturn V2.NewGaugeVec(GaugeVecOpts{\n\t\tGaugeOpts:      opts,\n\t\tVariableLabels: UnconstrainedLabels(labelNames),\n\t})\n}\n\n// NewGaugeVec creates a new GaugeVec based on the provided GaugeVecOpts.\nfunc (v2) NewGaugeVec(opts GaugeVecOpts) *GaugeVec {\n\tdesc := V2.NewDesc(\n\t\tBuildFQName(opts.Namespace, opts.Subsystem, opts.Name),\n\t\topts.Help,\n\t\topts.VariableLabels,\n\t\topts.ConstLabels,\n\t)\n\treturn &GaugeVec{\n\t\tMetricVec: NewMetricVec(desc, func(lvs ...string) Metric {\n\t\t\tif len(lvs) != len(desc.variableLabels.names) {\n\t\t\t\tpanic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, lvs))\n\t\t\t}\n\t\t\tresult := &gauge{desc: desc, labelPairs: MakeLabelPairs(desc, lvs)}\n\t\t\tresult.init(result) // Init self-collection.\n\t\t\treturn result\n\t\t}),\n\t}\n}\n\n// GetMetricWithLabelValues returns the Gauge for the given slice of label\n// values (same order as the variable labels in Desc). If that combination of\n// label values is accessed for the first time, a new Gauge is created.\n//\n// It is possible to call this method without using the returned Gauge to only\n// create the new Gauge but leave it at its starting value 0. See also the\n// SummaryVec example.\n//\n// Keeping the Gauge for later use is possible (and should be considered if\n// performance is critical), but keep in mind that Reset, DeleteLabelValues and\n// Delete can be used to delete the Gauge from the GaugeVec. In that case, the\n// Gauge will still exist, but it will not be exported anymore, even if a\n// Gauge with the same label values is created later. See also the CounterVec\n// example.\n//\n// An error is returned if the number of label values is not the same as the\n// number of variable labels in Desc (minus any curried labels).\n//\n// Note that for more than one label value, this method is prone to mistakes\n// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as\n// an alternative to avoid that type of mistake. For higher label numbers, the\n// latter has a much more readable (albeit more verbose) syntax, but it comes\n// with a performance overhead (for creating and processing the Labels map).\nfunc (v *GaugeVec) GetMetricWithLabelValues(lvs ...string) (Gauge, error) {\n\tmetric, err := v.MetricVec.GetMetricWithLabelValues(lvs...)\n\tif metric != nil {\n\t\treturn metric.(Gauge), err\n\t}\n\treturn nil, err\n}\n\n// GetMetricWith returns the Gauge for the given Labels map (the label names\n// must match those of the variable labels in Desc). If that label map is\n// accessed for the first time, a new Gauge is created. Implications of\n// creating a Gauge without using it and keeping the Gauge for later use are\n// the same as for GetMetricWithLabelValues.\n//\n// An error is returned if the number and names of the Labels are inconsistent\n// with those of the variable labels in Desc (minus any curried labels).\n//\n// This method is used for the same purpose as\n// GetMetricWithLabelValues(...string). See there for pros and cons of the two\n// methods.\nfunc (v *GaugeVec) GetMetricWith(labels Labels) (Gauge, error) {\n\tmetric, err := v.MetricVec.GetMetricWith(labels)\n\tif metric != nil {\n\t\treturn metric.(Gauge), err\n\t}\n\treturn nil, err\n}\n\n// WithLabelValues works as GetMetricWithLabelValues, but panics where\n// GetMetricWithLabelValues would have returned an error. Not returning an\n// error allows shortcuts like\n//\n//\tmyVec.WithLabelValues(\"404\", \"GET\").Add(42)\nfunc (v *GaugeVec) WithLabelValues(lvs ...string) Gauge {\n\tg, err := v.GetMetricWithLabelValues(lvs...)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn g\n}\n\n// With works as GetMetricWith, but panics where GetMetricWithLabels would have\n// returned an error. Not returning an error allows shortcuts like\n//\n//\tmyVec.With(prometheus.Labels{\"code\": \"404\", \"method\": \"GET\"}).Add(42)\nfunc (v *GaugeVec) With(labels Labels) Gauge {\n\tg, err := v.GetMetricWith(labels)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn g\n}\n\n// CurryWith returns a vector curried with the provided labels, i.e. the\n// returned vector has those labels pre-set for all labeled operations performed\n// on it. The cardinality of the curried vector is reduced accordingly. The\n// order of the remaining labels stays the same (just with the curried labels\n// taken out of the sequence – which is relevant for the\n// (GetMetric)WithLabelValues methods). It is possible to curry a curried\n// vector, but only with labels not yet used for currying before.\n//\n// The metrics contained in the GaugeVec are shared between the curried and\n// uncurried vectors. They are just accessed differently. Curried and uncurried\n// vectors behave identically in terms of collection. Only one must be\n// registered with a given registry (usually the uncurried version). The Reset\n// method deletes all metrics, even if called on a curried vector.\nfunc (v *GaugeVec) CurryWith(labels Labels) (*GaugeVec, error) {\n\tvec, err := v.MetricVec.CurryWith(labels)\n\tif vec != nil {\n\t\treturn &GaugeVec{vec}, err\n\t}\n\treturn nil, err\n}\n\n// MustCurryWith works as CurryWith but panics where CurryWith would have\n// returned an error.\nfunc (v *GaugeVec) MustCurryWith(labels Labels) *GaugeVec {\n\tvec, err := v.CurryWith(labels)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn vec\n}\n\n// GaugeFunc is a Gauge whose value is determined at collect time by calling a\n// provided function.\n//\n// To create GaugeFunc instances, use NewGaugeFunc.\ntype GaugeFunc interface {\n\tMetric\n\tCollector\n}\n\n// NewGaugeFunc creates a new GaugeFunc based on the provided GaugeOpts. The\n// value reported is determined by calling the given function from within the\n// Write method. Take into account that metric collection may happen\n// concurrently. Therefore, it must be safe to call the provided function\n// concurrently.\n//\n// NewGaugeFunc is a good way to create an “info” style metric with a constant\n// value of 1. Example:\n// https://github.com/prometheus/common/blob/8558a5b7db3c84fa38b4766966059a7bd5bfa2ee/version/info.go#L36-L56\nfunc NewGaugeFunc(opts GaugeOpts, function func() float64) GaugeFunc {\n\treturn newValueFunc(NewDesc(\n\t\tBuildFQName(opts.Namespace, opts.Subsystem, opts.Name),\n\t\topts.Help,\n\t\tnil,\n\t\topts.ConstLabels,\n\t), GaugeValue, function)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/get_pid.go",
    "content": "// Copyright 2015 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build !js || wasm\n// +build !js wasm\n\npackage prometheus\n\nimport \"os\"\n\nfunc getPIDFn() func() (int, error) {\n\tpid := os.Getpid()\n\treturn func() (int, error) {\n\t\treturn pid, nil\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go",
    "content": "// Copyright 2015 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build js && !wasm\n// +build js,!wasm\n\npackage prometheus\n\nfunc getPIDFn() func() (int, error) {\n\treturn func() (int, error) {\n\t\treturn 1, nil\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/go_collector.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\nimport (\n\t\"runtime\"\n\t\"runtime/debug\"\n\t\"time\"\n)\n\n// goRuntimeMemStats provides the metrics initially provided by runtime.ReadMemStats.\n// From Go 1.17 those similar (and better) statistics are provided by runtime/metrics, so\n// while eval closure works on runtime.MemStats, the struct from Go 1.17+ is\n// populated using runtime/metrics. Those are the defaults we can't alter.\nfunc goRuntimeMemStats() memStatsMetrics {\n\treturn memStatsMetrics{\n\t\t{\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"alloc_bytes\"),\n\t\t\t\t\"Number of bytes allocated in heap and currently in use. Equals to /memory/classes/heap/objects:bytes.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.Alloc) },\n\t\t\tvalType: GaugeValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"alloc_bytes_total\"),\n\t\t\t\t\"Total number of bytes allocated in heap until now, even if released already. Equals to /gc/heap/allocs:bytes.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.TotalAlloc) },\n\t\t\tvalType: CounterValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"sys_bytes\"),\n\t\t\t\t\"Number of bytes obtained from system. Equals to /memory/classes/total:byte.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.Sys) },\n\t\t\tvalType: GaugeValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"mallocs_total\"),\n\t\t\t\t// TODO(bwplotka): We could add go_memstats_heap_objects, probably useful for discovery. Let's gather more feedback, kind of a waste of bytes for everybody for compatibility reasons to keep both, and we can't really rename/remove useful metric.\n\t\t\t\t\"Total number of heap objects allocated, both live and gc-ed. Semantically a counter version for go_memstats_heap_objects gauge. Equals to /gc/heap/allocs:objects + /gc/heap/tiny/allocs:objects.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.Mallocs) },\n\t\t\tvalType: CounterValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"frees_total\"),\n\t\t\t\t\"Total number of heap objects frees. Equals to /gc/heap/frees:objects + /gc/heap/tiny/allocs:objects.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.Frees) },\n\t\t\tvalType: CounterValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"heap_alloc_bytes\"),\n\t\t\t\t\"Number of heap bytes allocated and currently in use, same as go_memstats_alloc_bytes. Equals to /memory/classes/heap/objects:bytes.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.HeapAlloc) },\n\t\t\tvalType: GaugeValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"heap_sys_bytes\"),\n\t\t\t\t\"Number of heap bytes obtained from system. Equals to /memory/classes/heap/objects:bytes + /memory/classes/heap/unused:bytes + /memory/classes/heap/released:bytes + /memory/classes/heap/free:bytes.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.HeapSys) },\n\t\t\tvalType: GaugeValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"heap_idle_bytes\"),\n\t\t\t\t\"Number of heap bytes waiting to be used. Equals to /memory/classes/heap/released:bytes + /memory/classes/heap/free:bytes.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.HeapIdle) },\n\t\t\tvalType: GaugeValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"heap_inuse_bytes\"),\n\t\t\t\t\"Number of heap bytes that are in use. Equals to /memory/classes/heap/objects:bytes + /memory/classes/heap/unused:bytes\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.HeapInuse) },\n\t\t\tvalType: GaugeValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"heap_released_bytes\"),\n\t\t\t\t\"Number of heap bytes released to OS. Equals to /memory/classes/heap/released:bytes.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.HeapReleased) },\n\t\t\tvalType: GaugeValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"heap_objects\"),\n\t\t\t\t\"Number of currently allocated objects. Equals to /gc/heap/objects:objects.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.HeapObjects) },\n\t\t\tvalType: GaugeValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"stack_inuse_bytes\"),\n\t\t\t\t\"Number of bytes obtained from system for stack allocator in non-CGO environments. Equals to /memory/classes/heap/stacks:bytes.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.StackInuse) },\n\t\t\tvalType: GaugeValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"stack_sys_bytes\"),\n\t\t\t\t\"Number of bytes obtained from system for stack allocator. Equals to /memory/classes/heap/stacks:bytes + /memory/classes/os-stacks:bytes.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.StackSys) },\n\t\t\tvalType: GaugeValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"mspan_inuse_bytes\"),\n\t\t\t\t\"Number of bytes in use by mspan structures. Equals to /memory/classes/metadata/mspan/inuse:bytes.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.MSpanInuse) },\n\t\t\tvalType: GaugeValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"mspan_sys_bytes\"),\n\t\t\t\t\"Number of bytes used for mspan structures obtained from system. Equals to /memory/classes/metadata/mspan/inuse:bytes + /memory/classes/metadata/mspan/free:bytes.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.MSpanSys) },\n\t\t\tvalType: GaugeValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"mcache_inuse_bytes\"),\n\t\t\t\t\"Number of bytes in use by mcache structures. Equals to /memory/classes/metadata/mcache/inuse:bytes.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.MCacheInuse) },\n\t\t\tvalType: GaugeValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"mcache_sys_bytes\"),\n\t\t\t\t\"Number of bytes used for mcache structures obtained from system. Equals to /memory/classes/metadata/mcache/inuse:bytes + /memory/classes/metadata/mcache/free:bytes.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.MCacheSys) },\n\t\t\tvalType: GaugeValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"buck_hash_sys_bytes\"),\n\t\t\t\t\"Number of bytes used by the profiling bucket hash table. Equals to /memory/classes/profiling/buckets:bytes.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.BuckHashSys) },\n\t\t\tvalType: GaugeValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"gc_sys_bytes\"),\n\t\t\t\t\"Number of bytes used for garbage collection system metadata. Equals to /memory/classes/metadata/other:bytes.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.GCSys) },\n\t\t\tvalType: GaugeValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"other_sys_bytes\"),\n\t\t\t\t\"Number of bytes used for other system allocations. Equals to /memory/classes/other:bytes.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.OtherSys) },\n\t\t\tvalType: GaugeValue,\n\t\t}, {\n\t\t\tdesc: NewDesc(\n\t\t\t\tmemstatNamespace(\"next_gc_bytes\"),\n\t\t\t\t\"Number of heap bytes when next garbage collection will take place. Equals to /gc/heap/goal:bytes.\",\n\t\t\t\tnil, nil,\n\t\t\t),\n\t\t\teval:    func(ms *runtime.MemStats) float64 { return float64(ms.NextGC) },\n\t\t\tvalType: GaugeValue,\n\t\t},\n\t}\n}\n\ntype baseGoCollector struct {\n\tgoroutinesDesc *Desc\n\tthreadsDesc    *Desc\n\tgcDesc         *Desc\n\tgcLastTimeDesc *Desc\n\tgoInfoDesc     *Desc\n}\n\nfunc newBaseGoCollector() baseGoCollector {\n\treturn baseGoCollector{\n\t\tgoroutinesDesc: NewDesc(\n\t\t\t\"go_goroutines\",\n\t\t\t\"Number of goroutines that currently exist.\",\n\t\t\tnil, nil),\n\t\tthreadsDesc: NewDesc(\n\t\t\t\"go_threads\",\n\t\t\t\"Number of OS threads created.\",\n\t\t\tnil, nil),\n\t\tgcDesc: NewDesc(\n\t\t\t\"go_gc_duration_seconds\",\n\t\t\t\"A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles.\",\n\t\t\tnil, nil),\n\t\tgcLastTimeDesc: NewDesc(\n\t\t\t\"go_memstats_last_gc_time_seconds\",\n\t\t\t\"Number of seconds since 1970 of last garbage collection.\",\n\t\t\tnil, nil),\n\t\tgoInfoDesc: NewDesc(\n\t\t\t\"go_info\",\n\t\t\t\"Information about the Go environment.\",\n\t\t\tnil, Labels{\"version\": runtime.Version()}),\n\t}\n}\n\n// Describe returns all descriptions of the collector.\nfunc (c *baseGoCollector) Describe(ch chan<- *Desc) {\n\tch <- c.goroutinesDesc\n\tch <- c.threadsDesc\n\tch <- c.gcDesc\n\tch <- c.gcLastTimeDesc\n\tch <- c.goInfoDesc\n}\n\n// Collect returns the current state of all metrics of the collector.\nfunc (c *baseGoCollector) Collect(ch chan<- Metric) {\n\tch <- MustNewConstMetric(c.goroutinesDesc, GaugeValue, float64(runtime.NumGoroutine()))\n\n\tn := getRuntimeNumThreads()\n\tch <- MustNewConstMetric(c.threadsDesc, GaugeValue, n)\n\n\tvar stats debug.GCStats\n\tstats.PauseQuantiles = make([]time.Duration, 5)\n\tdebug.ReadGCStats(&stats)\n\n\tquantiles := make(map[float64]float64)\n\tfor idx, pq := range stats.PauseQuantiles[1:] {\n\t\tquantiles[float64(idx+1)/float64(len(stats.PauseQuantiles)-1)] = pq.Seconds()\n\t}\n\tquantiles[0.0] = stats.PauseQuantiles[0].Seconds()\n\tch <- MustNewConstSummary(c.gcDesc, uint64(stats.NumGC), stats.PauseTotal.Seconds(), quantiles)\n\tch <- MustNewConstMetric(c.gcLastTimeDesc, GaugeValue, float64(stats.LastGC.UnixNano())/1e9)\n\tch <- MustNewConstMetric(c.goInfoDesc, GaugeValue, 1)\n}\n\nfunc memstatNamespace(s string) string {\n\treturn \"go_memstats_\" + s\n}\n\n// memStatsMetrics provide description, evaluator, runtime/metrics name, and\n// value type for memstat metrics.\ntype memStatsMetrics []struct {\n\tdesc    *Desc\n\teval    func(*runtime.MemStats) float64\n\tvalType ValueType\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go",
    "content": "// Copyright 2021 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build !go1.17\n// +build !go1.17\n\npackage prometheus\n\nimport (\n\t\"runtime\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype goCollector struct {\n\tbase baseGoCollector\n\n\t// ms... are memstats related.\n\tmsLast          *runtime.MemStats // Previously collected memstats.\n\tmsLastTimestamp time.Time\n\tmsMtx           sync.Mutex // Protects msLast and msLastTimestamp.\n\tmsMetrics       memStatsMetrics\n\tmsRead          func(*runtime.MemStats) // For mocking in tests.\n\tmsMaxWait       time.Duration           // Wait time for fresh memstats.\n\tmsMaxAge        time.Duration           // Maximum allowed age of old memstats.\n}\n\n// NewGoCollector is the obsolete version of collectors.NewGoCollector.\n// See there for documentation.\n//\n// Deprecated: Use collectors.NewGoCollector instead.\nfunc NewGoCollector() Collector {\n\tmsMetrics := goRuntimeMemStats()\n\tmsMetrics = append(msMetrics, struct {\n\t\tdesc    *Desc\n\t\teval    func(*runtime.MemStats) float64\n\t\tvalType ValueType\n\t}{\n\t\t// This metric is omitted in Go1.17+, see https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034\n\t\tdesc: NewDesc(\n\t\t\tmemstatNamespace(\"gc_cpu_fraction\"),\n\t\t\t\"The fraction of this program's available CPU time used by the GC since the program started.\",\n\t\t\tnil, nil,\n\t\t),\n\t\teval:    func(ms *runtime.MemStats) float64 { return ms.GCCPUFraction },\n\t\tvalType: GaugeValue,\n\t})\n\treturn &goCollector{\n\t\tbase:      newBaseGoCollector(),\n\t\tmsLast:    &runtime.MemStats{},\n\t\tmsRead:    runtime.ReadMemStats,\n\t\tmsMaxWait: time.Second,\n\t\tmsMaxAge:  5 * time.Minute,\n\t\tmsMetrics: msMetrics,\n\t}\n}\n\n// Describe returns all descriptions of the collector.\nfunc (c *goCollector) Describe(ch chan<- *Desc) {\n\tc.base.Describe(ch)\n\tfor _, i := range c.msMetrics {\n\t\tch <- i.desc\n\t}\n}\n\n// Collect returns the current state of all metrics of the collector.\nfunc (c *goCollector) Collect(ch chan<- Metric) {\n\tvar (\n\t\tms   = &runtime.MemStats{}\n\t\tdone = make(chan struct{})\n\t)\n\t// Start reading memstats first as it might take a while.\n\tgo func() {\n\t\tc.msRead(ms)\n\t\tc.msMtx.Lock()\n\t\tc.msLast = ms\n\t\tc.msLastTimestamp = time.Now()\n\t\tc.msMtx.Unlock()\n\t\tclose(done)\n\t}()\n\n\t// Collect base non-memory metrics.\n\tc.base.Collect(ch)\n\n\ttimer := time.NewTimer(c.msMaxWait)\n\tselect {\n\tcase <-done: // Our own ReadMemStats succeeded in time. Use it.\n\t\ttimer.Stop() // Important for high collection frequencies to not pile up timers.\n\t\tc.msCollect(ch, ms)\n\t\treturn\n\tcase <-timer.C: // Time out, use last memstats if possible. Continue below.\n\t}\n\tc.msMtx.Lock()\n\tif time.Since(c.msLastTimestamp) < c.msMaxAge {\n\t\t// Last memstats are recent enough. Collect from them under the lock.\n\t\tc.msCollect(ch, c.msLast)\n\t\tc.msMtx.Unlock()\n\t\treturn\n\t}\n\t// If we are here, the last memstats are too old or don't exist. We have\n\t// to wait until our own ReadMemStats finally completes. For that to\n\t// happen, we have to release the lock.\n\tc.msMtx.Unlock()\n\t<-done\n\tc.msCollect(ch, ms)\n}\n\nfunc (c *goCollector) msCollect(ch chan<- Metric, ms *runtime.MemStats) {\n\tfor _, i := range c.msMetrics {\n\t\tch <- MustNewConstMetric(i.desc, i.valType, i.eval(ms))\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go",
    "content": "// Copyright 2021 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build go1.17\n// +build go1.17\n\npackage prometheus\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"runtime\"\n\t\"runtime/metrics\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/prometheus/client_golang/prometheus/internal\"\n\n\tdto \"github.com/prometheus/client_model/go\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\nconst (\n\t// constants for strings referenced more than once.\n\tgoGCHeapTinyAllocsObjects               = \"/gc/heap/tiny/allocs:objects\"\n\tgoGCHeapAllocsObjects                   = \"/gc/heap/allocs:objects\"\n\tgoGCHeapFreesObjects                    = \"/gc/heap/frees:objects\"\n\tgoGCHeapFreesBytes                      = \"/gc/heap/frees:bytes\"\n\tgoGCHeapAllocsBytes                     = \"/gc/heap/allocs:bytes\"\n\tgoGCHeapObjects                         = \"/gc/heap/objects:objects\"\n\tgoGCHeapGoalBytes                       = \"/gc/heap/goal:bytes\"\n\tgoMemoryClassesTotalBytes               = \"/memory/classes/total:bytes\"\n\tgoMemoryClassesHeapObjectsBytes         = \"/memory/classes/heap/objects:bytes\"\n\tgoMemoryClassesHeapUnusedBytes          = \"/memory/classes/heap/unused:bytes\"\n\tgoMemoryClassesHeapReleasedBytes        = \"/memory/classes/heap/released:bytes\"\n\tgoMemoryClassesHeapFreeBytes            = \"/memory/classes/heap/free:bytes\"\n\tgoMemoryClassesHeapStacksBytes          = \"/memory/classes/heap/stacks:bytes\"\n\tgoMemoryClassesOSStacksBytes            = \"/memory/classes/os-stacks:bytes\"\n\tgoMemoryClassesMetadataMSpanInuseBytes  = \"/memory/classes/metadata/mspan/inuse:bytes\"\n\tgoMemoryClassesMetadataMSPanFreeBytes   = \"/memory/classes/metadata/mspan/free:bytes\"\n\tgoMemoryClassesMetadataMCacheInuseBytes = \"/memory/classes/metadata/mcache/inuse:bytes\"\n\tgoMemoryClassesMetadataMCacheFreeBytes  = \"/memory/classes/metadata/mcache/free:bytes\"\n\tgoMemoryClassesProfilingBucketsBytes    = \"/memory/classes/profiling/buckets:bytes\"\n\tgoMemoryClassesMetadataOtherBytes       = \"/memory/classes/metadata/other:bytes\"\n\tgoMemoryClassesOtherBytes               = \"/memory/classes/other:bytes\"\n)\n\n// rmNamesForMemStatsMetrics represents runtime/metrics names required to populate goRuntimeMemStats from like logic.\nvar rmNamesForMemStatsMetrics = []string{\n\tgoGCHeapTinyAllocsObjects,\n\tgoGCHeapAllocsObjects,\n\tgoGCHeapFreesObjects,\n\tgoGCHeapAllocsBytes,\n\tgoGCHeapObjects,\n\tgoGCHeapGoalBytes,\n\tgoMemoryClassesTotalBytes,\n\tgoMemoryClassesHeapObjectsBytes,\n\tgoMemoryClassesHeapUnusedBytes,\n\tgoMemoryClassesHeapReleasedBytes,\n\tgoMemoryClassesHeapFreeBytes,\n\tgoMemoryClassesHeapStacksBytes,\n\tgoMemoryClassesOSStacksBytes,\n\tgoMemoryClassesMetadataMSpanInuseBytes,\n\tgoMemoryClassesMetadataMSPanFreeBytes,\n\tgoMemoryClassesMetadataMCacheInuseBytes,\n\tgoMemoryClassesMetadataMCacheFreeBytes,\n\tgoMemoryClassesProfilingBucketsBytes,\n\tgoMemoryClassesMetadataOtherBytes,\n\tgoMemoryClassesOtherBytes,\n}\n\nfunc bestEffortLookupRM(lookup []string) []metrics.Description {\n\tret := make([]metrics.Description, 0, len(lookup))\n\tfor _, rm := range metrics.All() {\n\t\tfor _, m := range lookup {\n\t\t\tif m == rm.Name {\n\t\t\t\tret = append(ret, rm)\n\t\t\t}\n\t\t}\n\t}\n\treturn ret\n}\n\ntype goCollector struct {\n\tbase baseGoCollector\n\n\t// mu protects updates to all fields ensuring a consistent\n\t// snapshot is always produced by Collect.\n\tmu sync.Mutex\n\n\t// Contains all samples that has to retrieved from runtime/metrics (not all of them will be exposed).\n\tsampleBuf []metrics.Sample\n\t// sampleMap allows lookup for MemStats metrics and runtime/metrics histograms for exact sums.\n\tsampleMap map[string]*metrics.Sample\n\n\t// rmExposedMetrics represents all runtime/metrics package metrics\n\t// that were configured to be exposed.\n\trmExposedMetrics     []collectorMetric\n\trmExactSumMapForHist map[string]string\n\n\t// With Go 1.17, the runtime/metrics package was introduced.\n\t// From that point on, metric names produced by the runtime/metrics\n\t// package could be generated from runtime/metrics names. However,\n\t// these differ from the old names for the same values.\n\t//\n\t// This field exists to export the same values under the old names\n\t// as well.\n\tmsMetrics        memStatsMetrics\n\tmsMetricsEnabled bool\n}\n\ntype rmMetricDesc struct {\n\tmetrics.Description\n}\n\nfunc matchRuntimeMetricsRules(rules []internal.GoCollectorRule) []rmMetricDesc {\n\tvar descs []rmMetricDesc\n\tfor _, d := range metrics.All() {\n\t\tvar (\n\t\t\tdeny = true\n\t\t\tdesc rmMetricDesc\n\t\t)\n\n\t\tfor _, r := range rules {\n\t\t\tif !r.Matcher.MatchString(d.Name) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tdeny = r.Deny\n\t\t}\n\t\tif deny {\n\t\t\tcontinue\n\t\t}\n\n\t\tdesc.Description = d\n\t\tdescs = append(descs, desc)\n\t}\n\treturn descs\n}\n\nfunc defaultGoCollectorOptions() internal.GoCollectorOptions {\n\treturn internal.GoCollectorOptions{\n\t\tRuntimeMetricSumForHist: map[string]string{\n\t\t\t\"/gc/heap/allocs-by-size:bytes\": goGCHeapAllocsBytes,\n\t\t\t\"/gc/heap/frees-by-size:bytes\":  goGCHeapFreesBytes,\n\t\t},\n\t\tRuntimeMetricRules: []internal.GoCollectorRule{\n\t\t\t// Recommended metrics we want by default from runtime/metrics.\n\t\t\t{Matcher: internal.GoCollectorDefaultRuntimeMetrics},\n\t\t},\n\t}\n}\n\n// NewGoCollector is the obsolete version of collectors.NewGoCollector.\n// See there for documentation.\n//\n// Deprecated: Use collectors.NewGoCollector instead.\nfunc NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector {\n\topt := defaultGoCollectorOptions()\n\tfor _, o := range opts {\n\t\to(&opt)\n\t}\n\n\texposedDescriptions := matchRuntimeMetricsRules(opt.RuntimeMetricRules)\n\n\t// Collect all histogram samples so that we can get their buckets.\n\t// The API guarantees that the buckets are always fixed for the lifetime\n\t// of the process.\n\tvar histograms []metrics.Sample\n\tfor _, d := range exposedDescriptions {\n\t\tif d.Kind == metrics.KindFloat64Histogram {\n\t\t\thistograms = append(histograms, metrics.Sample{Name: d.Name})\n\t\t}\n\t}\n\n\tif len(histograms) > 0 {\n\t\tmetrics.Read(histograms)\n\t}\n\n\tbucketsMap := make(map[string][]float64)\n\tfor i := range histograms {\n\t\tbucketsMap[histograms[i].Name] = histograms[i].Value.Float64Histogram().Buckets\n\t}\n\n\t// Generate a collector for each exposed runtime/metrics metric.\n\tmetricSet := make([]collectorMetric, 0, len(exposedDescriptions))\n\t// SampleBuf is used for reading from runtime/metrics.\n\t// We are assuming the largest case to have stable pointers for sampleMap purposes.\n\tsampleBuf := make([]metrics.Sample, 0, len(exposedDescriptions)+len(opt.RuntimeMetricSumForHist)+len(rmNamesForMemStatsMetrics))\n\tsampleMap := make(map[string]*metrics.Sample, len(exposedDescriptions))\n\tfor _, d := range exposedDescriptions {\n\t\tnamespace, subsystem, name, ok := internal.RuntimeMetricsToProm(&d.Description)\n\t\tif !ok {\n\t\t\t// Just ignore this metric; we can't do anything with it here.\n\t\t\t// If a user decides to use the latest version of Go, we don't want\n\t\t\t// to fail here. This condition is tested in TestExpectedRuntimeMetrics.\n\t\t\tcontinue\n\t\t}\n\t\thelp := attachOriginalName(d.Description.Description, d.Name)\n\n\t\tsampleBuf = append(sampleBuf, metrics.Sample{Name: d.Name})\n\t\tsampleMap[d.Name] = &sampleBuf[len(sampleBuf)-1]\n\n\t\tvar m collectorMetric\n\t\tif d.Kind == metrics.KindFloat64Histogram {\n\t\t\t_, hasSum := opt.RuntimeMetricSumForHist[d.Name]\n\t\t\tunit := d.Name[strings.IndexRune(d.Name, ':')+1:]\n\t\t\tm = newBatchHistogram(\n\t\t\t\tNewDesc(\n\t\t\t\t\tBuildFQName(namespace, subsystem, name),\n\t\t\t\t\thelp,\n\t\t\t\t\tnil,\n\t\t\t\t\tnil,\n\t\t\t\t),\n\t\t\t\tinternal.RuntimeMetricsBucketsForUnit(bucketsMap[d.Name], unit),\n\t\t\t\thasSum,\n\t\t\t)\n\t\t} else if d.Cumulative {\n\t\t\tm = NewCounter(CounterOpts{\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: subsystem,\n\t\t\t\tName:      name,\n\t\t\t\tHelp:      help,\n\t\t\t},\n\t\t\t)\n\t\t} else {\n\t\t\tm = NewGauge(GaugeOpts{\n\t\t\t\tNamespace: namespace,\n\t\t\t\tSubsystem: subsystem,\n\t\t\t\tName:      name,\n\t\t\t\tHelp:      help,\n\t\t\t})\n\t\t}\n\t\tmetricSet = append(metricSet, m)\n\t}\n\n\t// Add exact sum metrics to sampleBuf if not added before.\n\tfor _, h := range histograms {\n\t\tsumMetric, ok := opt.RuntimeMetricSumForHist[h.Name]\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\tif _, ok := sampleMap[sumMetric]; ok {\n\t\t\tcontinue\n\t\t}\n\t\tsampleBuf = append(sampleBuf, metrics.Sample{Name: sumMetric})\n\t\tsampleMap[sumMetric] = &sampleBuf[len(sampleBuf)-1]\n\t}\n\n\tvar (\n\t\tmsMetrics      memStatsMetrics\n\t\tmsDescriptions []metrics.Description\n\t)\n\n\tif !opt.DisableMemStatsLikeMetrics {\n\t\tmsMetrics = goRuntimeMemStats()\n\t\tmsDescriptions = bestEffortLookupRM(rmNamesForMemStatsMetrics)\n\n\t\t// Check if metric was not exposed before and if not, add to sampleBuf.\n\t\tfor _, mdDesc := range msDescriptions {\n\t\t\tif _, ok := sampleMap[mdDesc.Name]; ok {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tsampleBuf = append(sampleBuf, metrics.Sample{Name: mdDesc.Name})\n\t\t\tsampleMap[mdDesc.Name] = &sampleBuf[len(sampleBuf)-1]\n\t\t}\n\t}\n\n\treturn &goCollector{\n\t\tbase:                 newBaseGoCollector(),\n\t\tsampleBuf:            sampleBuf,\n\t\tsampleMap:            sampleMap,\n\t\trmExposedMetrics:     metricSet,\n\t\trmExactSumMapForHist: opt.RuntimeMetricSumForHist,\n\t\tmsMetrics:            msMetrics,\n\t\tmsMetricsEnabled:     !opt.DisableMemStatsLikeMetrics,\n\t}\n}\n\nfunc attachOriginalName(desc, origName string) string {\n\treturn fmt.Sprintf(\"%s Sourced from %s.\", desc, origName)\n}\n\n// Describe returns all descriptions of the collector.\nfunc (c *goCollector) Describe(ch chan<- *Desc) {\n\tc.base.Describe(ch)\n\tfor _, i := range c.msMetrics {\n\t\tch <- i.desc\n\t}\n\tfor _, m := range c.rmExposedMetrics {\n\t\tch <- m.Desc()\n\t}\n}\n\n// Collect returns the current state of all metrics of the collector.\nfunc (c *goCollector) Collect(ch chan<- Metric) {\n\t// Collect base non-memory metrics.\n\tc.base.Collect(ch)\n\n\tif len(c.sampleBuf) == 0 {\n\t\treturn\n\t}\n\n\t// Collect must be thread-safe, so prevent concurrent use of\n\t// sampleBuf elements. Just read into sampleBuf but write all the data\n\t// we get into our Metrics or MemStats.\n\t//\n\t// This lock also ensures that the Metrics we send out are all from\n\t// the same updates, ensuring their mutual consistency insofar as\n\t// is guaranteed by the runtime/metrics package.\n\t//\n\t// N.B. This locking is heavy-handed, but Collect is expected to be called\n\t// relatively infrequently. Also the core operation here, metrics.Read,\n\t// is fast (O(tens of microseconds)) so contention should certainly be\n\t// low, though channel operations and any allocations may add to that.\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\n\t// Populate runtime/metrics sample buffer.\n\tmetrics.Read(c.sampleBuf)\n\n\t// Collect all our runtime/metrics user chose to expose from sampleBuf (if any).\n\tfor i, metric := range c.rmExposedMetrics {\n\t\t// We created samples for exposed metrics first in order, so indexes match.\n\t\tsample := c.sampleBuf[i]\n\n\t\t// N.B. switch on concrete type because it's significantly more efficient\n\t\t// than checking for the Counter and Gauge interface implementations. In\n\t\t// this case, we control all the types here.\n\t\tswitch m := metric.(type) {\n\t\tcase *counter:\n\t\t\t// Guard against decreases. This should never happen, but a failure\n\t\t\t// to do so will result in a panic, which is a harsh consequence for\n\t\t\t// a metrics collection bug.\n\t\t\tv0, v1 := m.get(), unwrapScalarRMValue(sample.Value)\n\t\t\tif v1 > v0 {\n\t\t\t\tm.Add(unwrapScalarRMValue(sample.Value) - m.get())\n\t\t\t}\n\t\t\tm.Collect(ch)\n\t\tcase *gauge:\n\t\t\tm.Set(unwrapScalarRMValue(sample.Value))\n\t\t\tm.Collect(ch)\n\t\tcase *batchHistogram:\n\t\t\tm.update(sample.Value.Float64Histogram(), c.exactSumFor(sample.Name))\n\t\t\tm.Collect(ch)\n\t\tdefault:\n\t\t\tpanic(\"unexpected metric type\")\n\t\t}\n\t}\n\n\tif c.msMetricsEnabled {\n\t\t// ms is a dummy MemStats that we populate ourselves so that we can\n\t\t// populate the old metrics from it if goMemStatsCollection is enabled.\n\t\tvar ms runtime.MemStats\n\t\tmemStatsFromRM(&ms, c.sampleMap)\n\t\tfor _, i := range c.msMetrics {\n\t\t\tch <- MustNewConstMetric(i.desc, i.valType, i.eval(&ms))\n\t\t}\n\t}\n}\n\n// unwrapScalarRMValue unwraps a runtime/metrics value that is assumed\n// to be scalar and returns the equivalent float64 value. Panics if the\n// value is not scalar.\nfunc unwrapScalarRMValue(v metrics.Value) float64 {\n\tswitch v.Kind() {\n\tcase metrics.KindUint64:\n\t\treturn float64(v.Uint64())\n\tcase metrics.KindFloat64:\n\t\treturn v.Float64()\n\tcase metrics.KindBad:\n\t\t// Unsupported metric.\n\t\t//\n\t\t// This should never happen because we always populate our metric\n\t\t// set from the runtime/metrics package.\n\t\tpanic(\"unexpected bad kind metric\")\n\tdefault:\n\t\t// Unsupported metric kind.\n\t\t//\n\t\t// This should never happen because we check for this during initialization\n\t\t// and flag and filter metrics whose kinds we don't understand.\n\t\tpanic(fmt.Sprintf(\"unexpected unsupported metric: %v\", v.Kind()))\n\t}\n}\n\n// exactSumFor takes a runtime/metrics metric name (that is assumed to\n// be of kind KindFloat64Histogram) and returns its exact sum and whether\n// its exact sum exists.\n//\n// The runtime/metrics API for histograms doesn't currently expose exact\n// sums, but some of the other metrics are in fact exact sums of histograms.\nfunc (c *goCollector) exactSumFor(rmName string) float64 {\n\tsumName, ok := c.rmExactSumMapForHist[rmName]\n\tif !ok {\n\t\treturn 0\n\t}\n\ts, ok := c.sampleMap[sumName]\n\tif !ok {\n\t\treturn 0\n\t}\n\treturn unwrapScalarRMValue(s.Value)\n}\n\nfunc memStatsFromRM(ms *runtime.MemStats, rm map[string]*metrics.Sample) {\n\tlookupOrZero := func(name string) uint64 {\n\t\tif s, ok := rm[name]; ok {\n\t\t\treturn s.Value.Uint64()\n\t\t}\n\t\treturn 0\n\t}\n\n\t// Currently, MemStats adds tiny alloc count to both Mallocs AND Frees.\n\t// The reason for this is because MemStats couldn't be extended at the time\n\t// but there was a desire to have Mallocs at least be a little more representative,\n\t// while having Mallocs - Frees still represent a live object count.\n\t// Unfortunately, MemStats doesn't actually export a large allocation count,\n\t// so it's impossible to pull this number out directly.\n\ttinyAllocs := lookupOrZero(goGCHeapTinyAllocsObjects)\n\tms.Mallocs = lookupOrZero(goGCHeapAllocsObjects) + tinyAllocs\n\tms.Frees = lookupOrZero(goGCHeapFreesObjects) + tinyAllocs\n\n\tms.TotalAlloc = lookupOrZero(goGCHeapAllocsBytes)\n\tms.Sys = lookupOrZero(goMemoryClassesTotalBytes)\n\tms.Lookups = 0 // Already always zero.\n\tms.HeapAlloc = lookupOrZero(goMemoryClassesHeapObjectsBytes)\n\tms.Alloc = ms.HeapAlloc\n\tms.HeapInuse = ms.HeapAlloc + lookupOrZero(goMemoryClassesHeapUnusedBytes)\n\tms.HeapReleased = lookupOrZero(goMemoryClassesHeapReleasedBytes)\n\tms.HeapIdle = ms.HeapReleased + lookupOrZero(goMemoryClassesHeapFreeBytes)\n\tms.HeapSys = ms.HeapInuse + ms.HeapIdle\n\tms.HeapObjects = lookupOrZero(goGCHeapObjects)\n\tms.StackInuse = lookupOrZero(goMemoryClassesHeapStacksBytes)\n\tms.StackSys = ms.StackInuse + lookupOrZero(goMemoryClassesOSStacksBytes)\n\tms.MSpanInuse = lookupOrZero(goMemoryClassesMetadataMSpanInuseBytes)\n\tms.MSpanSys = ms.MSpanInuse + lookupOrZero(goMemoryClassesMetadataMSPanFreeBytes)\n\tms.MCacheInuse = lookupOrZero(goMemoryClassesMetadataMCacheInuseBytes)\n\tms.MCacheSys = ms.MCacheInuse + lookupOrZero(goMemoryClassesMetadataMCacheFreeBytes)\n\tms.BuckHashSys = lookupOrZero(goMemoryClassesProfilingBucketsBytes)\n\tms.GCSys = lookupOrZero(goMemoryClassesMetadataOtherBytes)\n\tms.OtherSys = lookupOrZero(goMemoryClassesOtherBytes)\n\tms.NextGC = lookupOrZero(goGCHeapGoalBytes)\n\n\t// N.B. GCCPUFraction is intentionally omitted. This metric is not useful,\n\t// and often misleading due to the fact that it's an average over the lifetime\n\t// of the process.\n\t// See https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034\n\t// for more details.\n\tms.GCCPUFraction = 0\n}\n\n// batchHistogram is a mutable histogram that is updated\n// in batches.\ntype batchHistogram struct {\n\tselfCollector\n\n\t// Static fields updated only once.\n\tdesc   *Desc\n\thasSum bool\n\n\t// Because this histogram operates in batches, it just uses a\n\t// single mutex for everything. updates are always serialized\n\t// but Write calls may operate concurrently with updates.\n\t// Contention between these two sources should be rare.\n\tmu      sync.Mutex\n\tbuckets []float64 // Inclusive lower bounds, like runtime/metrics.\n\tcounts  []uint64\n\tsum     float64 // Used if hasSum is true.\n}\n\n// newBatchHistogram creates a new batch histogram value with the given\n// Desc, buckets, and whether or not it has an exact sum available.\n//\n// buckets must always be from the runtime/metrics package, following\n// the same conventions.\nfunc newBatchHistogram(desc *Desc, buckets []float64, hasSum bool) *batchHistogram {\n\t// We need to remove -Inf values. runtime/metrics keeps them around.\n\t// But -Inf bucket should not be allowed for prometheus histograms.\n\tif buckets[0] == math.Inf(-1) {\n\t\tbuckets = buckets[1:]\n\t}\n\th := &batchHistogram{\n\t\tdesc:    desc,\n\t\tbuckets: buckets,\n\t\t// Because buckets follows runtime/metrics conventions, there's\n\t\t// 1 more value in the buckets list than there are buckets represented,\n\t\t// because in runtime/metrics, the bucket values represent *boundaries*,\n\t\t// and non-Inf boundaries are inclusive lower bounds for that bucket.\n\t\tcounts: make([]uint64, len(buckets)-1),\n\t\thasSum: hasSum,\n\t}\n\th.init(h)\n\treturn h\n}\n\n// update updates the batchHistogram from a runtime/metrics histogram.\n//\n// sum must be provided if the batchHistogram was created to have an exact sum.\n// h.buckets must be a strict subset of his.Buckets.\nfunc (h *batchHistogram) update(his *metrics.Float64Histogram, sum float64) {\n\tcounts, buckets := his.Counts, his.Buckets\n\n\th.mu.Lock()\n\tdefer h.mu.Unlock()\n\n\t// Clear buckets.\n\tfor i := range h.counts {\n\t\th.counts[i] = 0\n\t}\n\t// Copy and reduce buckets.\n\tvar j int\n\tfor i, count := range counts {\n\t\th.counts[j] += count\n\t\tif buckets[i+1] == h.buckets[j+1] {\n\t\t\tj++\n\t\t}\n\t}\n\tif h.hasSum {\n\t\th.sum = sum\n\t}\n}\n\nfunc (h *batchHistogram) Desc() *Desc {\n\treturn h.desc\n}\n\nfunc (h *batchHistogram) Write(out *dto.Metric) error {\n\th.mu.Lock()\n\tdefer h.mu.Unlock()\n\n\tsum := float64(0)\n\tif h.hasSum {\n\t\tsum = h.sum\n\t}\n\tdtoBuckets := make([]*dto.Bucket, 0, len(h.counts))\n\ttotalCount := uint64(0)\n\tfor i, count := range h.counts {\n\t\ttotalCount += count\n\t\tif !h.hasSum {\n\t\t\tif count != 0 {\n\t\t\t\t// N.B. This computed sum is an underestimate.\n\t\t\t\tsum += h.buckets[i] * float64(count)\n\t\t\t}\n\t\t}\n\n\t\t// Skip the +Inf bucket, but only for the bucket list.\n\t\t// It must still count for sum and totalCount.\n\t\tif math.IsInf(h.buckets[i+1], 1) {\n\t\t\tbreak\n\t\t}\n\t\t// Float64Histogram's upper bound is exclusive, so make it inclusive\n\t\t// by obtaining the next float64 value down, in order.\n\t\tupperBound := math.Nextafter(h.buckets[i+1], h.buckets[i])\n\t\tdtoBuckets = append(dtoBuckets, &dto.Bucket{\n\t\t\tCumulativeCount: proto.Uint64(totalCount),\n\t\t\tUpperBound:      proto.Float64(upperBound),\n\t\t})\n\t}\n\tout.Histogram = &dto.Histogram{\n\t\tBucket:      dtoBuckets,\n\t\tSampleCount: proto.Uint64(totalCount),\n\t\tSampleSum:   proto.Float64(sum),\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/histogram.go",
    "content": "// Copyright 2015 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"runtime\"\n\t\"sort\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\tdto \"github.com/prometheus/client_model/go\"\n\n\t\"google.golang.org/protobuf/proto\"\n\t\"google.golang.org/protobuf/types/known/timestamppb\"\n)\n\nconst (\n\tnativeHistogramSchemaMaximum = 8\n\tnativeHistogramSchemaMinimum = -4\n)\n\n// nativeHistogramBounds for the frac of observed values. Only relevant for\n// schema > 0. The position in the slice is the schema. (0 is never used, just\n// here for convenience of using the schema directly as the index.)\n//\n// TODO(beorn7): Currently, we do a binary search into these slices. There are\n// ways to turn it into a small number of simple array lookups. It probably only\n// matters for schema 5 and beyond, but should be investigated. See this comment\n// as a starting point:\n// https://github.com/open-telemetry/opentelemetry-specification/issues/1776#issuecomment-870164310\nvar nativeHistogramBounds = [][]float64{\n\t// Schema \"0\":\n\t{0.5},\n\t// Schema 1:\n\t{0.5, 0.7071067811865475},\n\t// Schema 2:\n\t{0.5, 0.5946035575013605, 0.7071067811865475, 0.8408964152537144},\n\t// Schema 3:\n\t{\n\t\t0.5, 0.5452538663326288, 0.5946035575013605, 0.6484197773255048,\n\t\t0.7071067811865475, 0.7711054127039704, 0.8408964152537144, 0.9170040432046711,\n\t},\n\t// Schema 4:\n\t{\n\t\t0.5, 0.5221368912137069, 0.5452538663326288, 0.5693943173783458,\n\t\t0.5946035575013605, 0.620928906036742, 0.6484197773255048, 0.6771277734684463,\n\t\t0.7071067811865475, 0.7384130729697496, 0.7711054127039704, 0.805245165974627,\n\t\t0.8408964152537144, 0.8781260801866495, 0.9170040432046711, 0.9576032806985735,\n\t},\n\t// Schema 5:\n\t{\n\t\t0.5, 0.5109485743270583, 0.5221368912137069, 0.5335702003384117,\n\t\t0.5452538663326288, 0.5571933712979462, 0.5693943173783458, 0.5818624293887887,\n\t\t0.5946035575013605, 0.6076236799902344, 0.620928906036742, 0.6345254785958666,\n\t\t0.6484197773255048, 0.6626183215798706, 0.6771277734684463, 0.6919549409819159,\n\t\t0.7071067811865475, 0.7225904034885232, 0.7384130729697496, 0.7545822137967112,\n\t\t0.7711054127039704, 0.7879904225539431, 0.805245165974627, 0.8228777390769823,\n\t\t0.8408964152537144, 0.8593096490612387, 0.8781260801866495, 0.8973545375015533,\n\t\t0.9170040432046711, 0.9370838170551498, 0.9576032806985735, 0.9785720620876999,\n\t},\n\t// Schema 6:\n\t{\n\t\t0.5, 0.5054446430258502, 0.5109485743270583, 0.5165124395106142,\n\t\t0.5221368912137069, 0.5278225891802786, 0.5335702003384117, 0.5393803988785598,\n\t\t0.5452538663326288, 0.5511912916539204, 0.5571933712979462, 0.5632608093041209,\n\t\t0.5693943173783458, 0.5755946149764913, 0.5818624293887887, 0.5881984958251406,\n\t\t0.5946035575013605, 0.6010783657263515, 0.6076236799902344, 0.6142402680534349,\n\t\t0.620928906036742, 0.6276903785123455, 0.6345254785958666, 0.6414350080393891,\n\t\t0.6484197773255048, 0.6554806057623822, 0.6626183215798706, 0.6698337620266515,\n\t\t0.6771277734684463, 0.6845012114872953, 0.6919549409819159, 0.6994898362691555,\n\t\t0.7071067811865475, 0.7148066691959849, 0.7225904034885232, 0.7304588970903234,\n\t\t0.7384130729697496, 0.7464538641456323, 0.7545822137967112, 0.762799075372269,\n\t\t0.7711054127039704, 0.7795022001189185, 0.7879904225539431, 0.7965710756711334,\n\t\t0.805245165974627, 0.8140137109286738, 0.8228777390769823, 0.8318382901633681,\n\t\t0.8408964152537144, 0.8500531768592616, 0.8593096490612387, 0.8686669176368529,\n\t\t0.8781260801866495, 0.8876882462632604, 0.8973545375015533, 0.9071260877501991,\n\t\t0.9170040432046711, 0.9269895625416926, 0.9370838170551498, 0.9472879907934827,\n\t\t0.9576032806985735, 0.9680308967461471, 0.9785720620876999, 0.9892280131939752,\n\t},\n\t// Schema 7:\n\t{\n\t\t0.5, 0.5027149505564014, 0.5054446430258502, 0.5081891574554764,\n\t\t0.5109485743270583, 0.5137229745593818, 0.5165124395106142, 0.5193170509806894,\n\t\t0.5221368912137069, 0.5249720429003435, 0.5278225891802786, 0.5306886136446309,\n\t\t0.5335702003384117, 0.5364674337629877, 0.5393803988785598, 0.5423091811066545,\n\t\t0.5452538663326288, 0.5482145409081883, 0.5511912916539204, 0.5541842058618393,\n\t\t0.5571933712979462, 0.5602188762048033, 0.5632608093041209, 0.5663192597993595,\n\t\t0.5693943173783458, 0.572486072215902, 0.5755946149764913, 0.5787200368168754,\n\t\t0.5818624293887887, 0.585021884841625, 0.5881984958251406, 0.5913923554921704,\n\t\t0.5946035575013605, 0.5978321960199137, 0.6010783657263515, 0.6043421618132907,\n\t\t0.6076236799902344, 0.6109230164863786, 0.6142402680534349, 0.6175755319684665,\n\t\t0.620928906036742, 0.6243004885946023, 0.6276903785123455, 0.6310986751971253,\n\t\t0.6345254785958666, 0.637970889198196, 0.6414350080393891, 0.6449179367033329,\n\t\t0.6484197773255048, 0.6519406325959679, 0.6554806057623822, 0.659039800633032,\n\t\t0.6626183215798706, 0.6662162735415805, 0.6698337620266515, 0.6734708931164728,\n\t\t0.6771277734684463, 0.6808045103191123, 0.6845012114872953, 0.688217985377265,\n\t\t0.6919549409819159, 0.6957121878859629, 0.6994898362691555, 0.7032879969095076,\n\t\t0.7071067811865475, 0.7109463010845827, 0.7148066691959849, 0.718687998724491,\n\t\t0.7225904034885232, 0.7265139979245261, 0.7304588970903234, 0.7344252166684908,\n\t\t0.7384130729697496, 0.7424225829363761, 0.7464538641456323, 0.7505070348132126,\n\t\t0.7545822137967112, 0.7586795205991071, 0.762799075372269, 0.7669409989204777,\n\t\t0.7711054127039704, 0.7752924388424999, 0.7795022001189185, 0.7837348199827764,\n\t\t0.7879904225539431, 0.7922691326262467, 0.7965710756711334, 0.8008963778413465,\n\t\t0.805245165974627, 0.8096175675974316, 0.8140137109286738, 0.8184337248834821,\n\t\t0.8228777390769823, 0.8273458838280969, 0.8318382901633681, 0.8363550898207981,\n\t\t0.8408964152537144, 0.8454623996346523, 0.8500531768592616, 0.8546688815502312,\n\t\t0.8593096490612387, 0.8639756154809185, 0.8686669176368529, 0.8733836930995842,\n\t\t0.8781260801866495, 0.8828942179666361, 0.8876882462632604, 0.8925083056594671,\n\t\t0.8973545375015533, 0.9022270839033115, 0.9071260877501991, 0.9120516927035263,\n\t\t0.9170040432046711, 0.9219832844793128, 0.9269895625416926, 0.9320230241988943,\n\t\t0.9370838170551498, 0.9421720895161669, 0.9472879907934827, 0.9524316709088368,\n\t\t0.9576032806985735, 0.9628029718180622, 0.9680308967461471, 0.9732872087896164,\n\t\t0.9785720620876999, 0.9838856116165875, 0.9892280131939752, 0.9945994234836328,\n\t},\n\t// Schema 8:\n\t{\n\t\t0.5, 0.5013556375251013, 0.5027149505564014, 0.5040779490592088,\n\t\t0.5054446430258502, 0.5068150424757447, 0.5081891574554764, 0.509566998038869,\n\t\t0.5109485743270583, 0.5123338964485679, 0.5137229745593818, 0.5151158188430205,\n\t\t0.5165124395106142, 0.5179128468009786, 0.5193170509806894, 0.520725062344158,\n\t\t0.5221368912137069, 0.5235525479396449, 0.5249720429003435, 0.526395386502313,\n\t\t0.5278225891802786, 0.5292536613972564, 0.5306886136446309, 0.5321274564422321,\n\t\t0.5335702003384117, 0.5350168559101208, 0.5364674337629877, 0.5379219445313954,\n\t\t0.5393803988785598, 0.5408428074966075, 0.5423091811066545, 0.5437795304588847,\n\t\t0.5452538663326288, 0.5467321995364429, 0.5482145409081883, 0.549700901315111,\n\t\t0.5511912916539204, 0.5526857228508706, 0.5541842058618393, 0.5556867516724088,\n\t\t0.5571933712979462, 0.5587040757836845, 0.5602188762048033, 0.5617377836665098,\n\t\t0.5632608093041209, 0.564787964283144, 0.5663192597993595, 0.5678547070789026,\n\t\t0.5693943173783458, 0.5709381019847808, 0.572486072215902, 0.5740382394200894,\n\t\t0.5755946149764913, 0.5771552102951081, 0.5787200368168754, 0.5802891060137493,\n\t\t0.5818624293887887, 0.5834400184762408, 0.585021884841625, 0.5866080400818185,\n\t\t0.5881984958251406, 0.5897932637314379, 0.5913923554921704, 0.5929957828304968,\n\t\t0.5946035575013605, 0.5962156912915756, 0.5978321960199137, 0.5994530835371903,\n\t\t0.6010783657263515, 0.6027080545025619, 0.6043421618132907, 0.6059806996384005,\n\t\t0.6076236799902344, 0.6092711149137041, 0.6109230164863786, 0.6125793968185725,\n\t\t0.6142402680534349, 0.6159056423670379, 0.6175755319684665, 0.6192499490999082,\n\t\t0.620928906036742, 0.622612415087629, 0.6243004885946023, 0.6259931389331581,\n\t\t0.6276903785123455, 0.6293922197748583, 0.6310986751971253, 0.6328097572894031,\n\t\t0.6345254785958666, 0.6362458516947014, 0.637970889198196, 0.6397006037528346,\n\t\t0.6414350080393891, 0.6431741147730128, 0.6449179367033329, 0.6466664866145447,\n\t\t0.6484197773255048, 0.6501778216898253, 0.6519406325959679, 0.6537082229673385,\n\t\t0.6554806057623822, 0.6572577939746774, 0.659039800633032, 0.6608266388015788,\n\t\t0.6626183215798706, 0.6644148621029772, 0.6662162735415805, 0.6680225691020727,\n\t\t0.6698337620266515, 0.6716498655934177, 0.6734708931164728, 0.6752968579460171,\n\t\t0.6771277734684463, 0.6789636531064505, 0.6808045103191123, 0.6826503586020058,\n\t\t0.6845012114872953, 0.6863570825438342, 0.688217985377265, 0.690083933630119,\n\t\t0.6919549409819159, 0.6938310211492645, 0.6957121878859629, 0.6975984549830999,\n\t\t0.6994898362691555, 0.7013863456101023, 0.7032879969095076, 0.7051948041086352,\n\t\t0.7071067811865475, 0.7090239421602076, 0.7109463010845827, 0.7128738720527471,\n\t\t0.7148066691959849, 0.7167447066838943, 0.718687998724491, 0.7206365595643126,\n\t\t0.7225904034885232, 0.7245495448210174, 0.7265139979245261, 0.7284837772007218,\n\t\t0.7304588970903234, 0.7324393720732029, 0.7344252166684908, 0.7364164454346837,\n\t\t0.7384130729697496, 0.7404151139112358, 0.7424225829363761, 0.7444354947621984,\n\t\t0.7464538641456323, 0.7484777058836176, 0.7505070348132126, 0.7525418658117031,\n\t\t0.7545822137967112, 0.7566280937263048, 0.7586795205991071, 0.7607365094544071,\n\t\t0.762799075372269, 0.7648672334736434, 0.7669409989204777, 0.7690203869158282,\n\t\t0.7711054127039704, 0.7731960915705107, 0.7752924388424999, 0.7773944698885442,\n\t\t0.7795022001189185, 0.7816156449856788, 0.7837348199827764, 0.7858597406461707,\n\t\t0.7879904225539431, 0.7901268813264122, 0.7922691326262467, 0.7944171921585818,\n\t\t0.7965710756711334, 0.7987307989543135, 0.8008963778413465, 0.8030678282083853,\n\t\t0.805245165974627, 0.8074284071024302, 0.8096175675974316, 0.8118126635086642,\n\t\t0.8140137109286738, 0.8162207259936375, 0.8184337248834821, 0.820652723822003,\n\t\t0.8228777390769823, 0.8251087869603088, 0.8273458838280969, 0.8295890460808079,\n\t\t0.8318382901633681, 0.8340936325652911, 0.8363550898207981, 0.8386226785089391,\n\t\t0.8408964152537144, 0.8431763167241966, 0.8454623996346523, 0.8477546807446661,\n\t\t0.8500531768592616, 0.8523579048290255, 0.8546688815502312, 0.8569861239649629,\n\t\t0.8593096490612387, 0.8616394738731368, 0.8639756154809185, 0.8663180910111553,\n\t\t0.8686669176368529, 0.871022112577578, 0.8733836930995842, 0.8757516765159389,\n\t\t0.8781260801866495, 0.8805069215187917, 0.8828942179666361, 0.8852879870317771,\n\t\t0.8876882462632604, 0.890095013257712, 0.8925083056594671, 0.8949281411607002,\n\t\t0.8973545375015533, 0.8997875124702672, 0.9022270839033115, 0.9046732696855155,\n\t\t0.9071260877501991, 0.909585556079304, 0.9120516927035263, 0.9145245157024483,\n\t\t0.9170040432046711, 0.9194902933879467, 0.9219832844793128, 0.9244830347552253,\n\t\t0.9269895625416926, 0.92950288621441, 0.9320230241988943, 0.9345499949706191,\n\t\t0.9370838170551498, 0.93962450902828, 0.9421720895161669, 0.9447265771954693,\n\t\t0.9472879907934827, 0.9498563490882775, 0.9524316709088368, 0.9550139751351947,\n\t\t0.9576032806985735, 0.9601996065815236, 0.9628029718180622, 0.9654133954938133,\n\t\t0.9680308967461471, 0.9706554947643201, 0.9732872087896164, 0.9759260581154889,\n\t\t0.9785720620876999, 0.9812252401044634, 0.9838856116165875, 0.9865531961276168,\n\t\t0.9892280131939752, 0.9919100824251095, 0.9945994234836328, 0.9972960560854698,\n\t},\n}\n\n// The nativeHistogramBounds above can be generated with the code below.\n//\n// TODO(beorn7): It's tempting to actually use `go generate` to generate the\n// code above. However, this could lead to slightly different numbers on\n// different architectures. We still need to come to terms if we are fine with\n// that, or if we might prefer to specify precise numbers in the standard.\n//\n// var nativeHistogramBounds [][]float64 = make([][]float64, 9)\n//\n// func init() {\n// \t// Populate nativeHistogramBounds.\n// \tnumBuckets := 1\n// \tfor i := range nativeHistogramBounds {\n// \t\tbounds := []float64{0.5}\n// \t\tfactor := math.Exp2(math.Exp2(float64(-i)))\n// \t\tfor j := 0; j < numBuckets-1; j++ {\n// \t\t\tvar bound float64\n// \t\t\tif (j+1)%2 == 0 {\n// \t\t\t\t// Use previously calculated value for increased precision.\n// \t\t\t\tbound = nativeHistogramBounds[i-1][j/2+1]\n// \t\t\t} else {\n// \t\t\t\tbound = bounds[j] * factor\n// \t\t\t}\n// \t\t\tbounds = append(bounds, bound)\n// \t\t}\n// \t\tnumBuckets *= 2\n// \t\tnativeHistogramBounds[i] = bounds\n// \t}\n// }\n\n// A Histogram counts individual observations from an event or sample stream in\n// configurable static buckets (or in dynamic sparse buckets as part of the\n// experimental Native Histograms, see below for more details). Similar to a\n// Summary, it also provides a sum of observations and an observation count.\n//\n// On the Prometheus server, quantiles can be calculated from a Histogram using\n// the histogram_quantile PromQL function.\n//\n// Note that Histograms, in contrast to Summaries, can be aggregated in PromQL\n// (see the documentation for detailed procedures). However, Histograms require\n// the user to pre-define suitable buckets, and they are in general less\n// accurate. (Both problems are addressed by the experimental Native\n// Histograms. To use them, configure a NativeHistogramBucketFactor in the\n// HistogramOpts. They also require a Prometheus server v2.40+ with the\n// corresponding feature flag enabled.)\n//\n// The Observe method of a Histogram has a very low performance overhead in\n// comparison with the Observe method of a Summary.\n//\n// To create Histogram instances, use NewHistogram.\ntype Histogram interface {\n\tMetric\n\tCollector\n\n\t// Observe adds a single observation to the histogram. Observations are\n\t// usually positive or zero. Negative observations are accepted but\n\t// prevent current versions of Prometheus from properly detecting\n\t// counter resets in the sum of observations. (The experimental Native\n\t// Histograms handle negative observations properly.) See\n\t// https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations\n\t// for details.\n\tObserve(float64)\n}\n\n// bucketLabel is used for the label that defines the upper bound of a\n// bucket of a histogram (\"le\" -> \"less or equal\").\nconst bucketLabel = \"le\"\n\n// DefBuckets are the default Histogram buckets. The default buckets are\n// tailored to broadly measure the response time (in seconds) of a network\n// service. Most likely, however, you will be required to define buckets\n// customized to your use case.\nvar DefBuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}\n\n// DefNativeHistogramZeroThreshold is the default value for\n// NativeHistogramZeroThreshold in the HistogramOpts.\n//\n// The value is 2^-128 (or 0.5*2^-127 in the actual IEEE 754 representation),\n// which is a bucket boundary at all possible resolutions.\nconst DefNativeHistogramZeroThreshold = 2.938735877055719e-39\n\n// NativeHistogramZeroThresholdZero can be used as NativeHistogramZeroThreshold\n// in the HistogramOpts to create a zero bucket of width zero, i.e. a zero\n// bucket that only receives observations of precisely zero.\nconst NativeHistogramZeroThresholdZero = -1\n\nvar errBucketLabelNotAllowed = fmt.Errorf(\n\t\"%q is not allowed as label name in histograms\", bucketLabel,\n)\n\n// LinearBuckets creates 'count' regular buckets, each 'width' wide, where the\n// lowest bucket has an upper bound of 'start'. The final +Inf bucket is not\n// counted and not included in the returned slice. The returned slice is meant\n// to be used for the Buckets field of HistogramOpts.\n//\n// The function panics if 'count' is zero or negative.\nfunc LinearBuckets(start, width float64, count int) []float64 {\n\tif count < 1 {\n\t\tpanic(\"LinearBuckets needs a positive count\")\n\t}\n\tbuckets := make([]float64, count)\n\tfor i := range buckets {\n\t\tbuckets[i] = start\n\t\tstart += width\n\t}\n\treturn buckets\n}\n\n// ExponentialBuckets creates 'count' regular buckets, where the lowest bucket\n// has an upper bound of 'start' and each following bucket's upper bound is\n// 'factor' times the previous bucket's upper bound. The final +Inf bucket is\n// not counted and not included in the returned slice. The returned slice is\n// meant to be used for the Buckets field of HistogramOpts.\n//\n// The function panics if 'count' is 0 or negative, if 'start' is 0 or negative,\n// or if 'factor' is less than or equal 1.\nfunc ExponentialBuckets(start, factor float64, count int) []float64 {\n\tif count < 1 {\n\t\tpanic(\"ExponentialBuckets needs a positive count\")\n\t}\n\tif start <= 0 {\n\t\tpanic(\"ExponentialBuckets needs a positive start value\")\n\t}\n\tif factor <= 1 {\n\t\tpanic(\"ExponentialBuckets needs a factor greater than 1\")\n\t}\n\tbuckets := make([]float64, count)\n\tfor i := range buckets {\n\t\tbuckets[i] = start\n\t\tstart *= factor\n\t}\n\treturn buckets\n}\n\n// ExponentialBucketsRange creates 'count' buckets, where the lowest bucket is\n// 'min' and the highest bucket is 'max'. The final +Inf bucket is not counted\n// and not included in the returned slice. The returned slice is meant to be\n// used for the Buckets field of HistogramOpts.\n//\n// The function panics if 'count' is 0 or negative, if 'min' is 0 or negative.\nfunc ExponentialBucketsRange(minBucket, maxBucket float64, count int) []float64 {\n\tif count < 1 {\n\t\tpanic(\"ExponentialBucketsRange count needs a positive count\")\n\t}\n\tif minBucket <= 0 {\n\t\tpanic(\"ExponentialBucketsRange min needs to be greater than 0\")\n\t}\n\n\t// Formula for exponential buckets.\n\t// max = min*growthFactor^(bucketCount-1)\n\n\t// We know max/min and highest bucket. Solve for growthFactor.\n\tgrowthFactor := math.Pow(maxBucket/minBucket, 1.0/float64(count-1))\n\n\t// Now that we know growthFactor, solve for each bucket.\n\tbuckets := make([]float64, count)\n\tfor i := 1; i <= count; i++ {\n\t\tbuckets[i-1] = minBucket * math.Pow(growthFactor, float64(i-1))\n\t}\n\treturn buckets\n}\n\n// HistogramOpts bundles the options for creating a Histogram metric. It is\n// mandatory to set Name to a non-empty string. All other fields are optional\n// and can safely be left at their zero value, although it is strongly\n// encouraged to set a Help string.\ntype HistogramOpts struct {\n\t// Namespace, Subsystem, and Name are components of the fully-qualified\n\t// name of the Histogram (created by joining these components with\n\t// \"_\"). Only Name is mandatory, the others merely help structuring the\n\t// name. Note that the fully-qualified name of the Histogram must be a\n\t// valid Prometheus metric name.\n\tNamespace string\n\tSubsystem string\n\tName      string\n\n\t// Help provides information about this Histogram.\n\t//\n\t// Metrics with the same fully-qualified name must have the same Help\n\t// string.\n\tHelp string\n\n\t// ConstLabels are used to attach fixed labels to this metric. Metrics\n\t// with the same fully-qualified name must have the same label names in\n\t// their ConstLabels.\n\t//\n\t// ConstLabels are only used rarely. In particular, do not use them to\n\t// attach the same labels to all your metrics. Those use cases are\n\t// better covered by target labels set by the scraping Prometheus\n\t// server, or by one specific metric (e.g. a build_info or a\n\t// machine_role metric). See also\n\t// https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels\n\tConstLabels Labels\n\n\t// Buckets defines the buckets into which observations are counted. Each\n\t// element in the slice is the upper inclusive bound of a bucket. The\n\t// values must be sorted in strictly increasing order. There is no need\n\t// to add a highest bucket with +Inf bound, it will be added\n\t// implicitly. If Buckets is left as nil or set to a slice of length\n\t// zero, it is replaced by default buckets. The default buckets are\n\t// DefBuckets if no buckets for a native histogram (see below) are used,\n\t// otherwise the default is no buckets. (In other words, if you want to\n\t// use both regular buckets and buckets for a native histogram, you have\n\t// to define the regular buckets here explicitly.)\n\tBuckets []float64\n\n\t// If NativeHistogramBucketFactor is greater than one, so-called sparse\n\t// buckets are used (in addition to the regular buckets, if defined\n\t// above). A Histogram with sparse buckets will be ingested as a Native\n\t// Histogram by a Prometheus server with that feature enabled (requires\n\t// Prometheus v2.40+). Sparse buckets are exponential buckets covering\n\t// the whole float64 range (with the exception of the “zero” bucket, see\n\t// NativeHistogramZeroThreshold below). From any one bucket to the next,\n\t// the width of the bucket grows by a constant\n\t// factor. NativeHistogramBucketFactor provides an upper bound for this\n\t// factor (exception see below). The smaller\n\t// NativeHistogramBucketFactor, the more buckets will be used and thus\n\t// the more costly the histogram will become. A generally good trade-off\n\t// between cost and accuracy is a value of 1.1 (each bucket is at most\n\t// 10% wider than the previous one), which will result in each power of\n\t// two divided into 8 buckets (e.g. there will be 8 buckets between 1\n\t// and 2, same as between 2 and 4, and 4 and 8, etc.).\n\t//\n\t// Details about the actually used factor: The factor is calculated as\n\t// 2^(2^-n), where n is an integer number between (and including) -4 and\n\t// 8. n is chosen so that the resulting factor is the largest that is\n\t// still smaller or equal to NativeHistogramBucketFactor. Note that the\n\t// smallest possible factor is therefore approx. 1.00271 (i.e. 2^(2^-8)\n\t// ). If NativeHistogramBucketFactor is greater than 1 but smaller than\n\t// 2^(2^-8), then the actually used factor is still 2^(2^-8) even though\n\t// it is larger than the provided NativeHistogramBucketFactor.\n\t//\n\t// NOTE: Native Histograms are still an experimental feature. Their\n\t// behavior might still change without a major version\n\t// bump. Subsequently, all NativeHistogram... options here might still\n\t// change their behavior or name (or might completely disappear) without\n\t// a major version bump.\n\tNativeHistogramBucketFactor float64\n\t// All observations with an absolute value of less or equal\n\t// NativeHistogramZeroThreshold are accumulated into a “zero” bucket.\n\t// For best results, this should be close to a bucket boundary. This is\n\t// usually the case if picking a power of two. If\n\t// NativeHistogramZeroThreshold is left at zero,\n\t// DefNativeHistogramZeroThreshold is used as the threshold. To\n\t// configure a zero bucket with an actual threshold of zero (i.e. only\n\t// observations of precisely zero will go into the zero bucket), set\n\t// NativeHistogramZeroThreshold to the NativeHistogramZeroThresholdZero\n\t// constant (or any negative float value).\n\tNativeHistogramZeroThreshold float64\n\n\t// The next three fields define a strategy to limit the number of\n\t// populated sparse buckets. If NativeHistogramMaxBucketNumber is left\n\t// at zero, the number of buckets is not limited. (Note that this might\n\t// lead to unbounded memory consumption if the values observed by the\n\t// Histogram are sufficiently wide-spread. In particular, this could be\n\t// used as a DoS attack vector. Where the observed values depend on\n\t// external inputs, it is highly recommended to set a\n\t// NativeHistogramMaxBucketNumber.) Once the set\n\t// NativeHistogramMaxBucketNumber is exceeded, the following strategy is\n\t// enacted:\n\t//  - First, if the last reset (or the creation) of the histogram is at\n\t//    least NativeHistogramMinResetDuration ago, then the whole\n\t//    histogram is reset to its initial state (including regular\n\t//    buckets).\n\t//  - If less time has passed, or if NativeHistogramMinResetDuration is\n\t//    zero, no reset is performed. Instead, the zero threshold is\n\t//    increased sufficiently to reduce the number of buckets to or below\n\t//    NativeHistogramMaxBucketNumber, but not to more than\n\t//    NativeHistogramMaxZeroThreshold. Thus, if\n\t//    NativeHistogramMaxZeroThreshold is already at or below the current\n\t//    zero threshold, nothing happens at this step.\n\t//  - After that, if the number of buckets still exceeds\n\t//    NativeHistogramMaxBucketNumber, the resolution of the histogram is\n\t//    reduced by doubling the width of the sparse buckets (up to a\n\t//    growth factor between one bucket to the next of 2^(2^4) = 65536,\n\t//    see above).\n\t//  - Any increased zero threshold or reduced resolution is reset back\n\t//    to their original values once NativeHistogramMinResetDuration has\n\t//    passed (since the last reset or the creation of the histogram).\n\tNativeHistogramMaxBucketNumber  uint32\n\tNativeHistogramMinResetDuration time.Duration\n\tNativeHistogramMaxZeroThreshold float64\n\n\t// NativeHistogramMaxExemplars limits the number of exemplars\n\t// that are kept in memory for each native histogram. If you leave it at\n\t// zero, a default value of 10 is used. If no exemplars should be kept specifically\n\t// for native histograms, set it to a negative value. (Scrapers can\n\t// still use the exemplars exposed for classic buckets, which are managed\n\t// independently.)\n\tNativeHistogramMaxExemplars int\n\t// NativeHistogramExemplarTTL is only checked once\n\t// NativeHistogramMaxExemplars is exceeded. In that case, the\n\t// oldest exemplar is removed if it is older than NativeHistogramExemplarTTL.\n\t// Otherwise, the older exemplar in the pair of exemplars that are closest\n\t// together (on an exponential scale) is removed.\n\t// If NativeHistogramExemplarTTL is left at its zero value, a default value of\n\t// 5m is used. To always delete the oldest exemplar, set it to a negative value.\n\tNativeHistogramExemplarTTL time.Duration\n\n\t// now is for testing purposes, by default it's time.Now.\n\tnow func() time.Time\n\n\t// afterFunc is for testing purposes, by default it's time.AfterFunc.\n\tafterFunc func(time.Duration, func()) *time.Timer\n}\n\n// HistogramVecOpts bundles the options to create a HistogramVec metric.\n// It is mandatory to set HistogramOpts, see there for mandatory fields. VariableLabels\n// is optional and can safely be left to its default value.\ntype HistogramVecOpts struct {\n\tHistogramOpts\n\n\t// VariableLabels are used to partition the metric vector by the given set\n\t// of labels. Each label value will be constrained with the optional Constraint\n\t// function, if provided.\n\tVariableLabels ConstrainableLabels\n}\n\n// NewHistogram creates a new Histogram based on the provided HistogramOpts. It\n// panics if the buckets in HistogramOpts are not in strictly increasing order.\n//\n// The returned implementation also implements ExemplarObserver. It is safe to\n// perform the corresponding type assertion. Exemplars are tracked separately\n// for each bucket.\nfunc NewHistogram(opts HistogramOpts) Histogram {\n\treturn newHistogram(\n\t\tNewDesc(\n\t\t\tBuildFQName(opts.Namespace, opts.Subsystem, opts.Name),\n\t\t\topts.Help,\n\t\t\tnil,\n\t\t\topts.ConstLabels,\n\t\t),\n\t\topts,\n\t)\n}\n\nfunc newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogram {\n\tif len(desc.variableLabels.names) != len(labelValues) {\n\t\tpanic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, labelValues))\n\t}\n\n\tfor _, n := range desc.variableLabels.names {\n\t\tif n == bucketLabel {\n\t\t\tpanic(errBucketLabelNotAllowed)\n\t\t}\n\t}\n\tfor _, lp := range desc.constLabelPairs {\n\t\tif lp.GetName() == bucketLabel {\n\t\t\tpanic(errBucketLabelNotAllowed)\n\t\t}\n\t}\n\n\tif opts.now == nil {\n\t\topts.now = time.Now\n\t}\n\tif opts.afterFunc == nil {\n\t\topts.afterFunc = time.AfterFunc\n\t}\n\n\th := &histogram{\n\t\tdesc:                            desc,\n\t\tupperBounds:                     opts.Buckets,\n\t\tlabelPairs:                      MakeLabelPairs(desc, labelValues),\n\t\tnativeHistogramMaxBuckets:       opts.NativeHistogramMaxBucketNumber,\n\t\tnativeHistogramMaxZeroThreshold: opts.NativeHistogramMaxZeroThreshold,\n\t\tnativeHistogramMinResetDuration: opts.NativeHistogramMinResetDuration,\n\t\tlastResetTime:                   opts.now(),\n\t\tnow:                             opts.now,\n\t\tafterFunc:                       opts.afterFunc,\n\t}\n\tif len(h.upperBounds) == 0 && opts.NativeHistogramBucketFactor <= 1 {\n\t\th.upperBounds = DefBuckets\n\t}\n\tif opts.NativeHistogramBucketFactor <= 1 {\n\t\th.nativeHistogramSchema = math.MinInt32 // To mark that there are no sparse buckets.\n\t} else {\n\t\tswitch {\n\t\tcase opts.NativeHistogramZeroThreshold > 0:\n\t\t\th.nativeHistogramZeroThreshold = opts.NativeHistogramZeroThreshold\n\t\tcase opts.NativeHistogramZeroThreshold == 0:\n\t\t\th.nativeHistogramZeroThreshold = DefNativeHistogramZeroThreshold\n\t\t} // Leave h.nativeHistogramZeroThreshold at 0 otherwise.\n\t\th.nativeHistogramSchema = pickSchema(opts.NativeHistogramBucketFactor)\n\t\th.nativeExemplars = makeNativeExemplars(opts.NativeHistogramExemplarTTL, opts.NativeHistogramMaxExemplars)\n\t}\n\tfor i, upperBound := range h.upperBounds {\n\t\tif i < len(h.upperBounds)-1 {\n\t\t\tif upperBound >= h.upperBounds[i+1] {\n\t\t\t\tpanic(fmt.Errorf(\n\t\t\t\t\t\"histogram buckets must be in increasing order: %f >= %f\",\n\t\t\t\t\tupperBound, h.upperBounds[i+1],\n\t\t\t\t))\n\t\t\t}\n\t\t} else {\n\t\t\tif math.IsInf(upperBound, +1) {\n\t\t\t\t// The +Inf bucket is implicit. Remove it here.\n\t\t\t\th.upperBounds = h.upperBounds[:i]\n\t\t\t}\n\t\t}\n\t}\n\t// Finally we know the final length of h.upperBounds and can make buckets\n\t// for both counts as well as exemplars:\n\th.counts[0] = &histogramCounts{buckets: make([]uint64, len(h.upperBounds))}\n\tatomic.StoreUint64(&h.counts[0].nativeHistogramZeroThresholdBits, math.Float64bits(h.nativeHistogramZeroThreshold))\n\tatomic.StoreInt32(&h.counts[0].nativeHistogramSchema, h.nativeHistogramSchema)\n\th.counts[1] = &histogramCounts{buckets: make([]uint64, len(h.upperBounds))}\n\tatomic.StoreUint64(&h.counts[1].nativeHistogramZeroThresholdBits, math.Float64bits(h.nativeHistogramZeroThreshold))\n\tatomic.StoreInt32(&h.counts[1].nativeHistogramSchema, h.nativeHistogramSchema)\n\th.exemplars = make([]atomic.Value, len(h.upperBounds)+1)\n\n\th.init(h) // Init self-collection.\n\treturn h\n}\n\ntype histogramCounts struct {\n\t// Order in this struct matters for the alignment required by atomic\n\t// operations, see http://golang.org/pkg/sync/atomic/#pkg-note-BUG\n\n\t// sumBits contains the bits of the float64 representing the sum of all\n\t// observations.\n\tsumBits uint64\n\tcount   uint64\n\n\t// nativeHistogramZeroBucket counts all (positive and negative)\n\t// observations in the zero bucket (with an absolute value less or equal\n\t// the current threshold, see next field.\n\tnativeHistogramZeroBucket uint64\n\t// nativeHistogramZeroThresholdBits is the bit pattern of the current\n\t// threshold for the zero bucket. It's initially equal to\n\t// nativeHistogramZeroThreshold but may change according to the bucket\n\t// count limitation strategy.\n\tnativeHistogramZeroThresholdBits uint64\n\t// nativeHistogramSchema may change over time according to the bucket\n\t// count limitation strategy and therefore has to be saved here.\n\tnativeHistogramSchema int32\n\t// Number of (positive and negative) sparse buckets.\n\tnativeHistogramBucketsNumber uint32\n\n\t// Regular buckets.\n\tbuckets []uint64\n\n\t// The sparse buckets for native histograms are implemented with a\n\t// sync.Map for now. A dedicated data structure will likely be more\n\t// efficient. There are separate maps for negative and positive\n\t// observations. The map's value is an *int64, counting observations in\n\t// that bucket. (Note that we don't use uint64 as an int64 won't\n\t// overflow in practice, and working with signed numbers from the\n\t// beginning simplifies the handling of deltas.) The map's key is the\n\t// index of the bucket according to the used\n\t// nativeHistogramSchema. Index 0 is for an upper bound of 1.\n\tnativeHistogramBucketsPositive, nativeHistogramBucketsNegative sync.Map\n}\n\n// observe manages the parts of observe that only affects\n// histogramCounts. doSparse is true if sparse buckets should be done,\n// too.\nfunc (hc *histogramCounts) observe(v float64, bucket int, doSparse bool) {\n\tif bucket < len(hc.buckets) {\n\t\tatomic.AddUint64(&hc.buckets[bucket], 1)\n\t}\n\tatomicAddFloat(&hc.sumBits, v)\n\tif doSparse && !math.IsNaN(v) {\n\t\tvar (\n\t\t\tkey                  int\n\t\t\tschema               = atomic.LoadInt32(&hc.nativeHistogramSchema)\n\t\t\tzeroThreshold        = math.Float64frombits(atomic.LoadUint64(&hc.nativeHistogramZeroThresholdBits))\n\t\t\tbucketCreated, isInf bool\n\t\t)\n\t\tif math.IsInf(v, 0) {\n\t\t\t// Pretend v is MaxFloat64 but later increment key by one.\n\t\t\tif math.IsInf(v, +1) {\n\t\t\t\tv = math.MaxFloat64\n\t\t\t} else {\n\t\t\t\tv = -math.MaxFloat64\n\t\t\t}\n\t\t\tisInf = true\n\t\t}\n\t\tfrac, exp := math.Frexp(math.Abs(v))\n\t\tif schema > 0 {\n\t\t\tbounds := nativeHistogramBounds[schema]\n\t\t\tkey = sort.SearchFloat64s(bounds, frac) + (exp-1)*len(bounds)\n\t\t} else {\n\t\t\tkey = exp\n\t\t\tif frac == 0.5 {\n\t\t\t\tkey--\n\t\t\t}\n\t\t\toffset := (1 << -schema) - 1\n\t\t\tkey = (key + offset) >> -schema\n\t\t}\n\t\tif isInf {\n\t\t\tkey++\n\t\t}\n\t\tswitch {\n\t\tcase v > zeroThreshold:\n\t\t\tbucketCreated = addToBucket(&hc.nativeHistogramBucketsPositive, key, 1)\n\t\tcase v < -zeroThreshold:\n\t\t\tbucketCreated = addToBucket(&hc.nativeHistogramBucketsNegative, key, 1)\n\t\tdefault:\n\t\t\tatomic.AddUint64(&hc.nativeHistogramZeroBucket, 1)\n\t\t}\n\t\tif bucketCreated {\n\t\t\tatomic.AddUint32(&hc.nativeHistogramBucketsNumber, 1)\n\t\t}\n\t}\n\t// Increment count last as we take it as a signal that the observation\n\t// is complete.\n\tatomic.AddUint64(&hc.count, 1)\n}\n\ntype histogram struct {\n\t// countAndHotIdx enables lock-free writes with use of atomic updates.\n\t// The most significant bit is the hot index [0 or 1] of the count field\n\t// below. Observe calls update the hot one. All remaining bits count the\n\t// number of Observe calls. Observe starts by incrementing this counter,\n\t// and finish by incrementing the count field in the respective\n\t// histogramCounts, as a marker for completion.\n\t//\n\t// Calls of the Write method (which are non-mutating reads from the\n\t// perspective of the histogram) swap the hot–cold under the writeMtx\n\t// lock. A cooldown is awaited (while locked) by comparing the number of\n\t// observations with the initiation count. Once they match, then the\n\t// last observation on the now cool one has completed. All cold fields must\n\t// be merged into the new hot before releasing writeMtx.\n\t//\n\t// Fields with atomic access first! See alignment constraint:\n\t// http://golang.org/pkg/sync/atomic/#pkg-note-BUG\n\tcountAndHotIdx uint64\n\n\tselfCollector\n\tdesc *Desc\n\n\t// Only used in the Write method and for sparse bucket management.\n\tmtx sync.Mutex\n\n\t// Two counts, one is \"hot\" for lock-free observations, the other is\n\t// \"cold\" for writing out a dto.Metric. It has to be an array of\n\t// pointers to guarantee 64bit alignment of the histogramCounts, see\n\t// http://golang.org/pkg/sync/atomic/#pkg-note-BUG.\n\tcounts [2]*histogramCounts\n\n\tupperBounds                     []float64\n\tlabelPairs                      []*dto.LabelPair\n\texemplars                       []atomic.Value // One more than buckets (to include +Inf), each a *dto.Exemplar.\n\tnativeHistogramSchema           int32          // The initial schema. Set to math.MinInt32 if no sparse buckets are used.\n\tnativeHistogramZeroThreshold    float64        // The initial zero threshold.\n\tnativeHistogramMaxZeroThreshold float64\n\tnativeHistogramMaxBuckets       uint32\n\tnativeHistogramMinResetDuration time.Duration\n\t// lastResetTime is protected by mtx. It is also used as created timestamp.\n\tlastResetTime time.Time\n\t// resetScheduled is protected by mtx. It is true if a reset is\n\t// scheduled for a later time (when nativeHistogramMinResetDuration has\n\t// passed).\n\tresetScheduled  bool\n\tnativeExemplars nativeExemplars\n\n\t// now is for testing purposes, by default it's time.Now.\n\tnow func() time.Time\n\n\t// afterFunc is for testing purposes, by default it's time.AfterFunc.\n\tafterFunc func(time.Duration, func()) *time.Timer\n}\n\nfunc (h *histogram) Desc() *Desc {\n\treturn h.desc\n}\n\nfunc (h *histogram) Observe(v float64) {\n\th.observe(v, h.findBucket(v))\n}\n\n// ObserveWithExemplar should not be called in a high-frequency setting\n// for a native histogram with configured exemplars. For this case,\n// the implementation isn't lock-free and might suffer from lock contention.\nfunc (h *histogram) ObserveWithExemplar(v float64, e Labels) {\n\ti := h.findBucket(v)\n\th.observe(v, i)\n\th.updateExemplar(v, i, e)\n}\n\nfunc (h *histogram) Write(out *dto.Metric) error {\n\t// For simplicity, we protect this whole method by a mutex. It is not in\n\t// the hot path, i.e. Observe is called much more often than Write. The\n\t// complication of making Write lock-free isn't worth it, if possible at\n\t// all.\n\th.mtx.Lock()\n\tdefer h.mtx.Unlock()\n\n\t// Adding 1<<63 switches the hot index (from 0 to 1 or from 1 to 0)\n\t// without touching the count bits. See the struct comments for a full\n\t// description of the algorithm.\n\tn := atomic.AddUint64(&h.countAndHotIdx, 1<<63)\n\t// count is contained unchanged in the lower 63 bits.\n\tcount := n & ((1 << 63) - 1)\n\t// The most significant bit tells us which counts is hot. The complement\n\t// is thus the cold one.\n\thotCounts := h.counts[n>>63]\n\tcoldCounts := h.counts[(^n)>>63]\n\n\twaitForCooldown(count, coldCounts)\n\n\this := &dto.Histogram{\n\t\tBucket:           make([]*dto.Bucket, len(h.upperBounds)),\n\t\tSampleCount:      proto.Uint64(count),\n\t\tSampleSum:        proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits))),\n\t\tCreatedTimestamp: timestamppb.New(h.lastResetTime),\n\t}\n\tout.Histogram = his\n\tout.Label = h.labelPairs\n\n\tvar cumCount uint64\n\tfor i, upperBound := range h.upperBounds {\n\t\tcumCount += atomic.LoadUint64(&coldCounts.buckets[i])\n\t\this.Bucket[i] = &dto.Bucket{\n\t\t\tCumulativeCount: proto.Uint64(cumCount),\n\t\t\tUpperBound:      proto.Float64(upperBound),\n\t\t}\n\t\tif e := h.exemplars[i].Load(); e != nil {\n\t\t\this.Bucket[i].Exemplar = e.(*dto.Exemplar)\n\t\t}\n\t}\n\t// If there is an exemplar for the +Inf bucket, we have to add that bucket explicitly.\n\tif e := h.exemplars[len(h.upperBounds)].Load(); e != nil {\n\t\tb := &dto.Bucket{\n\t\t\tCumulativeCount: proto.Uint64(count),\n\t\t\tUpperBound:      proto.Float64(math.Inf(1)),\n\t\t\tExemplar:        e.(*dto.Exemplar),\n\t\t}\n\t\this.Bucket = append(his.Bucket, b)\n\t}\n\tif h.nativeHistogramSchema > math.MinInt32 {\n\t\this.ZeroThreshold = proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.nativeHistogramZeroThresholdBits)))\n\t\this.Schema = proto.Int32(atomic.LoadInt32(&coldCounts.nativeHistogramSchema))\n\t\tzeroBucket := atomic.LoadUint64(&coldCounts.nativeHistogramZeroBucket)\n\n\t\tdefer func() {\n\t\t\tcoldCounts.nativeHistogramBucketsPositive.Range(addAndReset(&hotCounts.nativeHistogramBucketsPositive, &hotCounts.nativeHistogramBucketsNumber))\n\t\t\tcoldCounts.nativeHistogramBucketsNegative.Range(addAndReset(&hotCounts.nativeHistogramBucketsNegative, &hotCounts.nativeHistogramBucketsNumber))\n\t\t}()\n\n\t\this.ZeroCount = proto.Uint64(zeroBucket)\n\t\this.NegativeSpan, his.NegativeDelta = makeBuckets(&coldCounts.nativeHistogramBucketsNegative)\n\t\this.PositiveSpan, his.PositiveDelta = makeBuckets(&coldCounts.nativeHistogramBucketsPositive)\n\n\t\t// Add a no-op span to a histogram without observations and with\n\t\t// a zero threshold of zero. Otherwise, a native histogram would\n\t\t// look like a classic histogram to scrapers.\n\t\tif *his.ZeroThreshold == 0 && *his.ZeroCount == 0 && len(his.PositiveSpan) == 0 && len(his.NegativeSpan) == 0 {\n\t\t\this.PositiveSpan = []*dto.BucketSpan{{\n\t\t\t\tOffset: proto.Int32(0),\n\t\t\t\tLength: proto.Uint32(0),\n\t\t\t}}\n\t\t}\n\n\t\tif h.nativeExemplars.isEnabled() {\n\t\t\th.nativeExemplars.Lock()\n\t\t\this.Exemplars = append(his.Exemplars, h.nativeExemplars.exemplars...)\n\t\t\th.nativeExemplars.Unlock()\n\t\t}\n\n\t}\n\taddAndResetCounts(hotCounts, coldCounts)\n\treturn nil\n}\n\n// findBucket returns the index of the bucket for the provided value, or\n// len(h.upperBounds) for the +Inf bucket.\nfunc (h *histogram) findBucket(v float64) int {\n\tn := len(h.upperBounds)\n\tif n == 0 {\n\t\treturn 0\n\t}\n\n\t// Early exit: if v is less than or equal to the first upper bound, return 0\n\tif v <= h.upperBounds[0] {\n\t\treturn 0\n\t}\n\n\t// Early exit: if v is greater than the last upper bound, return len(h.upperBounds)\n\tif v > h.upperBounds[n-1] {\n\t\treturn n\n\t}\n\n\t// For small arrays, use simple linear search\n\t// \"magic number\" 35 is result of tests on couple different (AWS and baremetal) servers\n\t// see more details here: https://github.com/prometheus/client_golang/pull/1662\n\tif n < 35 {\n\t\tfor i, bound := range h.upperBounds {\n\t\t\tif v <= bound {\n\t\t\t\treturn i\n\t\t\t}\n\t\t}\n\t\t// If v is greater than all upper bounds, return len(h.upperBounds)\n\t\treturn n\n\t}\n\n\t// For larger arrays, use stdlib's binary search\n\treturn sort.SearchFloat64s(h.upperBounds, v)\n}\n\n// observe is the implementation for Observe without the findBucket part.\nfunc (h *histogram) observe(v float64, bucket int) {\n\t// Do not add to sparse buckets for NaN observations.\n\tdoSparse := h.nativeHistogramSchema > math.MinInt32 && !math.IsNaN(v)\n\t// We increment h.countAndHotIdx so that the counter in the lower\n\t// 63 bits gets incremented. At the same time, we get the new value\n\t// back, which we can use to find the currently-hot counts.\n\tn := atomic.AddUint64(&h.countAndHotIdx, 1)\n\thotCounts := h.counts[n>>63]\n\thotCounts.observe(v, bucket, doSparse)\n\tif doSparse {\n\t\th.limitBuckets(hotCounts, v, bucket)\n\t}\n}\n\n// limitBuckets applies a strategy to limit the number of populated sparse\n// buckets. It's generally best effort, and there are situations where the\n// number can go higher (if even the lowest resolution isn't enough to reduce\n// the number sufficiently, or if the provided counts aren't fully updated yet\n// by a concurrently happening Write call).\nfunc (h *histogram) limitBuckets(counts *histogramCounts, value float64, bucket int) {\n\tif h.nativeHistogramMaxBuckets == 0 {\n\t\treturn // No limit configured.\n\t}\n\tif h.nativeHistogramMaxBuckets >= atomic.LoadUint32(&counts.nativeHistogramBucketsNumber) {\n\t\treturn // Bucket limit not exceeded yet.\n\t}\n\n\th.mtx.Lock()\n\tdefer h.mtx.Unlock()\n\n\t// The hot counts might have been swapped just before we acquired the\n\t// lock. Re-fetch the hot counts first...\n\tn := atomic.LoadUint64(&h.countAndHotIdx)\n\thotIdx := n >> 63\n\tcoldIdx := (^n) >> 63\n\thotCounts := h.counts[hotIdx]\n\tcoldCounts := h.counts[coldIdx]\n\t// ...and then check again if we really have to reduce the bucket count.\n\tif h.nativeHistogramMaxBuckets >= atomic.LoadUint32(&hotCounts.nativeHistogramBucketsNumber) {\n\t\treturn // Bucket limit not exceeded after all.\n\t}\n\t// Try the various strategies in order.\n\tif h.maybeReset(hotCounts, coldCounts, coldIdx, value, bucket) {\n\t\treturn\n\t}\n\t// One of the other strategies will happen. To undo what they will do as\n\t// soon as enough time has passed to satisfy\n\t// h.nativeHistogramMinResetDuration, schedule a reset at the right time\n\t// if we haven't done so already.\n\tif h.nativeHistogramMinResetDuration > 0 && !h.resetScheduled {\n\t\th.resetScheduled = true\n\t\th.afterFunc(h.nativeHistogramMinResetDuration-h.now().Sub(h.lastResetTime), h.reset)\n\t}\n\n\tif h.maybeWidenZeroBucket(hotCounts, coldCounts) {\n\t\treturn\n\t}\n\th.doubleBucketWidth(hotCounts, coldCounts)\n}\n\n// maybeReset resets the whole histogram if at least\n// h.nativeHistogramMinResetDuration has been passed. It returns true if the\n// histogram has been reset. The caller must have locked h.mtx.\nfunc (h *histogram) maybeReset(\n\thot, cold *histogramCounts, coldIdx uint64, value float64, bucket int,\n) bool {\n\t// We are using the possibly mocked h.now() rather than\n\t// time.Since(h.lastResetTime) to enable testing.\n\tif h.nativeHistogramMinResetDuration == 0 || // No reset configured.\n\t\th.resetScheduled || // Do not interefere if a reset is already scheduled.\n\t\th.now().Sub(h.lastResetTime) < h.nativeHistogramMinResetDuration {\n\t\treturn false\n\t}\n\t// Completely reset coldCounts.\n\th.resetCounts(cold)\n\t// Repeat the latest observation to not lose it completely.\n\tcold.observe(value, bucket, true)\n\t// Make coldCounts the new hot counts while resetting countAndHotIdx.\n\tn := atomic.SwapUint64(&h.countAndHotIdx, (coldIdx<<63)+1)\n\tcount := n & ((1 << 63) - 1)\n\twaitForCooldown(count, hot)\n\t// Finally, reset the formerly hot counts, too.\n\th.resetCounts(hot)\n\th.lastResetTime = h.now()\n\treturn true\n}\n\n// reset resets the whole histogram. It locks h.mtx itself, i.e. it has to be\n// called without having locked h.mtx.\nfunc (h *histogram) reset() {\n\th.mtx.Lock()\n\tdefer h.mtx.Unlock()\n\n\tn := atomic.LoadUint64(&h.countAndHotIdx)\n\thotIdx := n >> 63\n\tcoldIdx := (^n) >> 63\n\thot := h.counts[hotIdx]\n\tcold := h.counts[coldIdx]\n\t// Completely reset coldCounts.\n\th.resetCounts(cold)\n\t// Make coldCounts the new hot counts while resetting countAndHotIdx.\n\tn = atomic.SwapUint64(&h.countAndHotIdx, coldIdx<<63)\n\tcount := n & ((1 << 63) - 1)\n\twaitForCooldown(count, hot)\n\t// Finally, reset the formerly hot counts, too.\n\th.resetCounts(hot)\n\th.lastResetTime = h.now()\n\th.resetScheduled = false\n}\n\n// maybeWidenZeroBucket widens the zero bucket until it includes the existing\n// buckets closest to the zero bucket (which could be two, if an equidistant\n// negative and a positive bucket exists, but usually it's only one bucket to be\n// merged into the new wider zero bucket). h.nativeHistogramMaxZeroThreshold\n// limits how far the zero bucket can be extended, and if that's not enough to\n// include an existing bucket, the method returns false. The caller must have\n// locked h.mtx.\nfunc (h *histogram) maybeWidenZeroBucket(hot, cold *histogramCounts) bool {\n\tcurrentZeroThreshold := math.Float64frombits(atomic.LoadUint64(&hot.nativeHistogramZeroThresholdBits))\n\tif currentZeroThreshold >= h.nativeHistogramMaxZeroThreshold {\n\t\treturn false\n\t}\n\t// Find the key of the bucket closest to zero.\n\tsmallestKey := findSmallestKey(&hot.nativeHistogramBucketsPositive)\n\tsmallestNegativeKey := findSmallestKey(&hot.nativeHistogramBucketsNegative)\n\tif smallestNegativeKey < smallestKey {\n\t\tsmallestKey = smallestNegativeKey\n\t}\n\tif smallestKey == math.MaxInt32 {\n\t\treturn false\n\t}\n\tnewZeroThreshold := getLe(smallestKey, atomic.LoadInt32(&hot.nativeHistogramSchema))\n\tif newZeroThreshold > h.nativeHistogramMaxZeroThreshold {\n\t\treturn false // New threshold would exceed the max threshold.\n\t}\n\tatomic.StoreUint64(&cold.nativeHistogramZeroThresholdBits, math.Float64bits(newZeroThreshold))\n\t// Remove applicable buckets.\n\tif _, loaded := cold.nativeHistogramBucketsNegative.LoadAndDelete(smallestKey); loaded {\n\t\tatomicDecUint32(&cold.nativeHistogramBucketsNumber)\n\t}\n\tif _, loaded := cold.nativeHistogramBucketsPositive.LoadAndDelete(smallestKey); loaded {\n\t\tatomicDecUint32(&cold.nativeHistogramBucketsNumber)\n\t}\n\t// Make cold counts the new hot counts.\n\tn := atomic.AddUint64(&h.countAndHotIdx, 1<<63)\n\tcount := n & ((1 << 63) - 1)\n\t// Swap the pointer names to represent the new roles and make\n\t// the rest less confusing.\n\thot, cold = cold, hot\n\twaitForCooldown(count, cold)\n\t// Add all the now cold counts to the new hot counts...\n\taddAndResetCounts(hot, cold)\n\t// ...adjust the new zero threshold in the cold counts, too...\n\tatomic.StoreUint64(&cold.nativeHistogramZeroThresholdBits, math.Float64bits(newZeroThreshold))\n\t// ...and then merge the newly deleted buckets into the wider zero\n\t// bucket.\n\tmergeAndDeleteOrAddAndReset := func(hotBuckets, coldBuckets *sync.Map) func(k, v interface{}) bool {\n\t\treturn func(k, v interface{}) bool {\n\t\t\tkey := k.(int)\n\t\t\tbucket := v.(*int64)\n\t\t\tif key == smallestKey {\n\t\t\t\t// Merge into hot zero bucket...\n\t\t\t\tatomic.AddUint64(&hot.nativeHistogramZeroBucket, uint64(atomic.LoadInt64(bucket)))\n\t\t\t\t// ...and delete from cold counts.\n\t\t\t\tcoldBuckets.Delete(key)\n\t\t\t\tatomicDecUint32(&cold.nativeHistogramBucketsNumber)\n\t\t\t} else {\n\t\t\t\t// Add to corresponding hot bucket...\n\t\t\t\tif addToBucket(hotBuckets, key, atomic.LoadInt64(bucket)) {\n\t\t\t\t\tatomic.AddUint32(&hot.nativeHistogramBucketsNumber, 1)\n\t\t\t\t}\n\t\t\t\t// ...and reset cold bucket.\n\t\t\t\tatomic.StoreInt64(bucket, 0)\n\t\t\t}\n\t\t\treturn true\n\t\t}\n\t}\n\n\tcold.nativeHistogramBucketsPositive.Range(mergeAndDeleteOrAddAndReset(&hot.nativeHistogramBucketsPositive, &cold.nativeHistogramBucketsPositive))\n\tcold.nativeHistogramBucketsNegative.Range(mergeAndDeleteOrAddAndReset(&hot.nativeHistogramBucketsNegative, &cold.nativeHistogramBucketsNegative))\n\treturn true\n}\n\n// doubleBucketWidth doubles the bucket width (by decrementing the schema\n// number). Note that very sparse buckets could lead to a low reduction of the\n// bucket count (or even no reduction at all). The method does nothing if the\n// schema is already -4.\nfunc (h *histogram) doubleBucketWidth(hot, cold *histogramCounts) {\n\tcoldSchema := atomic.LoadInt32(&cold.nativeHistogramSchema)\n\tif coldSchema == -4 {\n\t\treturn // Already at lowest resolution.\n\t}\n\tcoldSchema--\n\tatomic.StoreInt32(&cold.nativeHistogramSchema, coldSchema)\n\t// Play it simple and just delete all cold buckets.\n\tatomic.StoreUint32(&cold.nativeHistogramBucketsNumber, 0)\n\tdeleteSyncMap(&cold.nativeHistogramBucketsNegative)\n\tdeleteSyncMap(&cold.nativeHistogramBucketsPositive)\n\t// Make coldCounts the new hot counts.\n\tn := atomic.AddUint64(&h.countAndHotIdx, 1<<63)\n\tcount := n & ((1 << 63) - 1)\n\t// Swap the pointer names to represent the new roles and make\n\t// the rest less confusing.\n\thot, cold = cold, hot\n\twaitForCooldown(count, cold)\n\t// Add all the now cold counts to the new hot counts...\n\taddAndResetCounts(hot, cold)\n\t// ...adjust the schema in the cold counts, too...\n\tatomic.StoreInt32(&cold.nativeHistogramSchema, coldSchema)\n\t// ...and then merge the cold buckets into the wider hot buckets.\n\tmerge := func(hotBuckets *sync.Map) func(k, v interface{}) bool {\n\t\treturn func(k, v interface{}) bool {\n\t\t\tkey := k.(int)\n\t\t\tbucket := v.(*int64)\n\t\t\t// Adjust key to match the bucket to merge into.\n\t\t\tif key > 0 {\n\t\t\t\tkey++\n\t\t\t}\n\t\t\tkey /= 2\n\t\t\t// Add to corresponding hot bucket.\n\t\t\tif addToBucket(hotBuckets, key, atomic.LoadInt64(bucket)) {\n\t\t\t\tatomic.AddUint32(&hot.nativeHistogramBucketsNumber, 1)\n\t\t\t}\n\t\t\treturn true\n\t\t}\n\t}\n\n\tcold.nativeHistogramBucketsPositive.Range(merge(&hot.nativeHistogramBucketsPositive))\n\tcold.nativeHistogramBucketsNegative.Range(merge(&hot.nativeHistogramBucketsNegative))\n\t// Play it simple again and just delete all cold buckets.\n\tatomic.StoreUint32(&cold.nativeHistogramBucketsNumber, 0)\n\tdeleteSyncMap(&cold.nativeHistogramBucketsNegative)\n\tdeleteSyncMap(&cold.nativeHistogramBucketsPositive)\n}\n\nfunc (h *histogram) resetCounts(counts *histogramCounts) {\n\tatomic.StoreUint64(&counts.sumBits, 0)\n\tatomic.StoreUint64(&counts.count, 0)\n\tatomic.StoreUint64(&counts.nativeHistogramZeroBucket, 0)\n\tatomic.StoreUint64(&counts.nativeHistogramZeroThresholdBits, math.Float64bits(h.nativeHistogramZeroThreshold))\n\tatomic.StoreInt32(&counts.nativeHistogramSchema, h.nativeHistogramSchema)\n\tatomic.StoreUint32(&counts.nativeHistogramBucketsNumber, 0)\n\tfor i := range h.upperBounds {\n\t\tatomic.StoreUint64(&counts.buckets[i], 0)\n\t}\n\tdeleteSyncMap(&counts.nativeHistogramBucketsNegative)\n\tdeleteSyncMap(&counts.nativeHistogramBucketsPositive)\n}\n\n// updateExemplar replaces the exemplar for the provided classic bucket.\n// With empty labels, it's a no-op. It panics if any of the labels is invalid.\n// If histogram is native, the exemplar will be cached into nativeExemplars,\n// which has a limit, and will remove one exemplar when limit is reached.\nfunc (h *histogram) updateExemplar(v float64, bucket int, l Labels) {\n\tif l == nil {\n\t\treturn\n\t}\n\te, err := newExemplar(v, h.now(), l)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\th.exemplars[bucket].Store(e)\n\tdoSparse := h.nativeHistogramSchema > math.MinInt32 && !math.IsNaN(v)\n\tif doSparse {\n\t\th.nativeExemplars.addExemplar(e)\n\t}\n}\n\n// HistogramVec is a Collector that bundles a set of Histograms that all share the\n// same Desc, but have different values for their variable labels. This is used\n// if you want to count the same thing partitioned by various dimensions\n// (e.g. HTTP request latencies, partitioned by status code and method). Create\n// instances with NewHistogramVec.\ntype HistogramVec struct {\n\t*MetricVec\n}\n\n// NewHistogramVec creates a new HistogramVec based on the provided HistogramOpts and\n// partitioned by the given label names.\nfunc NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec {\n\treturn V2.NewHistogramVec(HistogramVecOpts{\n\t\tHistogramOpts:  opts,\n\t\tVariableLabels: UnconstrainedLabels(labelNames),\n\t})\n}\n\n// NewHistogramVec creates a new HistogramVec based on the provided HistogramVecOpts.\nfunc (v2) NewHistogramVec(opts HistogramVecOpts) *HistogramVec {\n\tdesc := V2.NewDesc(\n\t\tBuildFQName(opts.Namespace, opts.Subsystem, opts.Name),\n\t\topts.Help,\n\t\topts.VariableLabels,\n\t\topts.ConstLabels,\n\t)\n\treturn &HistogramVec{\n\t\tMetricVec: NewMetricVec(desc, func(lvs ...string) Metric {\n\t\t\treturn newHistogram(desc, opts.HistogramOpts, lvs...)\n\t\t}),\n\t}\n}\n\n// GetMetricWithLabelValues returns the Histogram for the given slice of label\n// values (same order as the variable labels in Desc). If that combination of\n// label values is accessed for the first time, a new Histogram is created.\n//\n// It is possible to call this method without using the returned Histogram to only\n// create the new Histogram but leave it at its starting value, a Histogram without\n// any observations.\n//\n// Keeping the Histogram for later use is possible (and should be considered if\n// performance is critical), but keep in mind that Reset, DeleteLabelValues and\n// Delete can be used to delete the Histogram from the HistogramVec. In that case, the\n// Histogram will still exist, but it will not be exported anymore, even if a\n// Histogram with the same label values is created later. See also the CounterVec\n// example.\n//\n// An error is returned if the number of label values is not the same as the\n// number of variable labels in Desc (minus any curried labels).\n//\n// Note that for more than one label value, this method is prone to mistakes\n// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as\n// an alternative to avoid that type of mistake. For higher label numbers, the\n// latter has a much more readable (albeit more verbose) syntax, but it comes\n// with a performance overhead (for creating and processing the Labels map).\n// See also the GaugeVec example.\nfunc (v *HistogramVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) {\n\tmetric, err := v.MetricVec.GetMetricWithLabelValues(lvs...)\n\tif metric != nil {\n\t\treturn metric.(Observer), err\n\t}\n\treturn nil, err\n}\n\n// GetMetricWith returns the Histogram for the given Labels map (the label names\n// must match those of the variable labels in Desc). If that label map is\n// accessed for the first time, a new Histogram is created. Implications of\n// creating a Histogram without using it and keeping the Histogram for later use\n// are the same as for GetMetricWithLabelValues.\n//\n// An error is returned if the number and names of the Labels are inconsistent\n// with those of the variable labels in Desc (minus any curried labels).\n//\n// This method is used for the same purpose as\n// GetMetricWithLabelValues(...string). See there for pros and cons of the two\n// methods.\nfunc (v *HistogramVec) GetMetricWith(labels Labels) (Observer, error) {\n\tmetric, err := v.MetricVec.GetMetricWith(labels)\n\tif metric != nil {\n\t\treturn metric.(Observer), err\n\t}\n\treturn nil, err\n}\n\n// WithLabelValues works as GetMetricWithLabelValues, but panics where\n// GetMetricWithLabelValues would have returned an error. Not returning an\n// error allows shortcuts like\n//\n//\tmyVec.WithLabelValues(\"404\", \"GET\").Observe(42.21)\nfunc (v *HistogramVec) WithLabelValues(lvs ...string) Observer {\n\th, err := v.GetMetricWithLabelValues(lvs...)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn h\n}\n\n// With works as GetMetricWith but panics where GetMetricWithLabels would have\n// returned an error. Not returning an error allows shortcuts like\n//\n//\tmyVec.With(prometheus.Labels{\"code\": \"404\", \"method\": \"GET\"}).Observe(42.21)\nfunc (v *HistogramVec) With(labels Labels) Observer {\n\th, err := v.GetMetricWith(labels)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn h\n}\n\n// CurryWith returns a vector curried with the provided labels, i.e. the\n// returned vector has those labels pre-set for all labeled operations performed\n// on it. The cardinality of the curried vector is reduced accordingly. The\n// order of the remaining labels stays the same (just with the curried labels\n// taken out of the sequence – which is relevant for the\n// (GetMetric)WithLabelValues methods). It is possible to curry a curried\n// vector, but only with labels not yet used for currying before.\n//\n// The metrics contained in the HistogramVec are shared between the curried and\n// uncurried vectors. They are just accessed differently. Curried and uncurried\n// vectors behave identically in terms of collection. Only one must be\n// registered with a given registry (usually the uncurried version). The Reset\n// method deletes all metrics, even if called on a curried vector.\nfunc (v *HistogramVec) CurryWith(labels Labels) (ObserverVec, error) {\n\tvec, err := v.MetricVec.CurryWith(labels)\n\tif vec != nil {\n\t\treturn &HistogramVec{vec}, err\n\t}\n\treturn nil, err\n}\n\n// MustCurryWith works as CurryWith but panics where CurryWith would have\n// returned an error.\nfunc (v *HistogramVec) MustCurryWith(labels Labels) ObserverVec {\n\tvec, err := v.CurryWith(labels)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn vec\n}\n\ntype constHistogram struct {\n\tdesc       *Desc\n\tcount      uint64\n\tsum        float64\n\tbuckets    map[float64]uint64\n\tlabelPairs []*dto.LabelPair\n\tcreatedTs  *timestamppb.Timestamp\n}\n\nfunc (h *constHistogram) Desc() *Desc {\n\treturn h.desc\n}\n\nfunc (h *constHistogram) Write(out *dto.Metric) error {\n\this := &dto.Histogram{\n\t\tCreatedTimestamp: h.createdTs,\n\t}\n\n\tbuckets := make([]*dto.Bucket, 0, len(h.buckets))\n\n\this.SampleCount = proto.Uint64(h.count)\n\this.SampleSum = proto.Float64(h.sum)\n\tfor upperBound, count := range h.buckets {\n\t\tbuckets = append(buckets, &dto.Bucket{\n\t\t\tCumulativeCount: proto.Uint64(count),\n\t\t\tUpperBound:      proto.Float64(upperBound),\n\t\t})\n\t}\n\n\tif len(buckets) > 0 {\n\t\tsort.Sort(buckSort(buckets))\n\t}\n\this.Bucket = buckets\n\n\tout.Histogram = his\n\tout.Label = h.labelPairs\n\n\treturn nil\n}\n\n// NewConstHistogram returns a metric representing a Prometheus histogram with\n// fixed values for the count, sum, and bucket counts. As those parameters\n// cannot be changed, the returned value does not implement the Histogram\n// interface (but only the Metric interface). Users of this package will not\n// have much use for it in regular operations. However, when implementing custom\n// Collectors, it is useful as a throw-away metric that is generated on the fly\n// to send it to Prometheus in the Collect method.\n//\n// buckets is a map of upper bounds to cumulative counts, excluding the +Inf\n// bucket. The +Inf bucket is implicit, and its value is equal to the provided count.\n//\n// NewConstHistogram returns an error if the length of labelValues is not\n// consistent with the variable labels in Desc or if Desc is invalid.\nfunc NewConstHistogram(\n\tdesc *Desc,\n\tcount uint64,\n\tsum float64,\n\tbuckets map[float64]uint64,\n\tlabelValues ...string,\n) (Metric, error) {\n\tif desc.err != nil {\n\t\treturn nil, desc.err\n\t}\n\tif err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &constHistogram{\n\t\tdesc:       desc,\n\t\tcount:      count,\n\t\tsum:        sum,\n\t\tbuckets:    buckets,\n\t\tlabelPairs: MakeLabelPairs(desc, labelValues),\n\t}, nil\n}\n\n// MustNewConstHistogram is a version of NewConstHistogram that panics where\n// NewConstHistogram would have returned an error.\nfunc MustNewConstHistogram(\n\tdesc *Desc,\n\tcount uint64,\n\tsum float64,\n\tbuckets map[float64]uint64,\n\tlabelValues ...string,\n) Metric {\n\tm, err := NewConstHistogram(desc, count, sum, buckets, labelValues...)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn m\n}\n\n// NewConstHistogramWithCreatedTimestamp does the same thing as NewConstHistogram but sets the created timestamp.\nfunc NewConstHistogramWithCreatedTimestamp(\n\tdesc *Desc,\n\tcount uint64,\n\tsum float64,\n\tbuckets map[float64]uint64,\n\tct time.Time,\n\tlabelValues ...string,\n) (Metric, error) {\n\tif desc.err != nil {\n\t\treturn nil, desc.err\n\t}\n\tif err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &constHistogram{\n\t\tdesc:       desc,\n\t\tcount:      count,\n\t\tsum:        sum,\n\t\tbuckets:    buckets,\n\t\tlabelPairs: MakeLabelPairs(desc, labelValues),\n\t\tcreatedTs:  timestamppb.New(ct),\n\t}, nil\n}\n\n// MustNewConstHistogramWithCreatedTimestamp is a version of NewConstHistogramWithCreatedTimestamp that panics where\n// NewConstHistogramWithCreatedTimestamp would have returned an error.\nfunc MustNewConstHistogramWithCreatedTimestamp(\n\tdesc *Desc,\n\tcount uint64,\n\tsum float64,\n\tbuckets map[float64]uint64,\n\tct time.Time,\n\tlabelValues ...string,\n) Metric {\n\tm, err := NewConstHistogramWithCreatedTimestamp(desc, count, sum, buckets, ct, labelValues...)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn m\n}\n\ntype buckSort []*dto.Bucket\n\nfunc (s buckSort) Len() int {\n\treturn len(s)\n}\n\nfunc (s buckSort) Swap(i, j int) {\n\ts[i], s[j] = s[j], s[i]\n}\n\nfunc (s buckSort) Less(i, j int) bool {\n\treturn s[i].GetUpperBound() < s[j].GetUpperBound()\n}\n\n// pickSchema returns the largest number n between -4 and 8 such that\n// 2^(2^-n) is less or equal the provided bucketFactor.\n//\n// Special cases:\n//   - bucketFactor <= 1: panics.\n//   - bucketFactor < 2^(2^-8) (but > 1): still returns 8.\nfunc pickSchema(bucketFactor float64) int32 {\n\tif bucketFactor <= 1 {\n\t\tpanic(fmt.Errorf(\"bucketFactor %f is <=1\", bucketFactor))\n\t}\n\tfloor := math.Floor(math.Log2(math.Log2(bucketFactor)))\n\tswitch {\n\tcase floor <= -8:\n\t\treturn nativeHistogramSchemaMaximum\n\tcase floor >= 4:\n\t\treturn nativeHistogramSchemaMinimum\n\tdefault:\n\t\treturn -int32(floor)\n\t}\n}\n\nfunc makeBuckets(buckets *sync.Map) ([]*dto.BucketSpan, []int64) {\n\tvar ii []int\n\tbuckets.Range(func(k, v interface{}) bool {\n\t\tii = append(ii, k.(int))\n\t\treturn true\n\t})\n\tsort.Ints(ii)\n\n\tif len(ii) == 0 {\n\t\treturn nil, nil\n\t}\n\n\tvar (\n\t\tspans     []*dto.BucketSpan\n\t\tdeltas    []int64\n\t\tprevCount int64\n\t\tnextI     int\n\t)\n\n\tappendDelta := func(count int64) {\n\t\t*spans[len(spans)-1].Length++\n\t\tdeltas = append(deltas, count-prevCount)\n\t\tprevCount = count\n\t}\n\n\tfor n, i := range ii {\n\t\tv, _ := buckets.Load(i)\n\t\tcount := atomic.LoadInt64(v.(*int64))\n\t\t// Multiple spans with only small gaps in between are probably\n\t\t// encoded more efficiently as one larger span with a few empty\n\t\t// buckets. Needs some research to find the sweet spot. For now,\n\t\t// we assume that gaps of one or two buckets should not create\n\t\t// a new span.\n\t\tiDelta := int32(i - nextI)\n\t\tif n == 0 || iDelta > 2 {\n\t\t\t// We have to create a new span, either because we are\n\t\t\t// at the very beginning, or because we have found a gap\n\t\t\t// of more than two buckets.\n\t\t\tspans = append(spans, &dto.BucketSpan{\n\t\t\t\tOffset: proto.Int32(iDelta),\n\t\t\t\tLength: proto.Uint32(0),\n\t\t\t})\n\t\t} else {\n\t\t\t// We have found a small gap (or no gap at all).\n\t\t\t// Insert empty buckets as needed.\n\t\t\tfor j := int32(0); j < iDelta; j++ {\n\t\t\t\tappendDelta(0)\n\t\t\t}\n\t\t}\n\t\tappendDelta(count)\n\t\tnextI = i + 1\n\t}\n\treturn spans, deltas\n}\n\n// addToBucket increments the sparse bucket at key by the provided amount. It\n// returns true if a new sparse bucket had to be created for that.\nfunc addToBucket(buckets *sync.Map, key int, increment int64) bool {\n\tif existingBucket, ok := buckets.Load(key); ok {\n\t\t// Fast path without allocation.\n\t\tatomic.AddInt64(existingBucket.(*int64), increment)\n\t\treturn false\n\t}\n\t// Bucket doesn't exist yet. Slow path allocating new counter.\n\tnewBucket := increment // TODO(beorn7): Check if this is sufficient to not let increment escape.\n\tif actualBucket, loaded := buckets.LoadOrStore(key, &newBucket); loaded {\n\t\t// The bucket was created concurrently in another goroutine.\n\t\t// Have to increment after all.\n\t\tatomic.AddInt64(actualBucket.(*int64), increment)\n\t\treturn false\n\t}\n\treturn true\n}\n\n// addAndReset returns a function to be used with sync.Map.Range of spare\n// buckets in coldCounts. It increments the buckets in the provided hotBuckets\n// according to the buckets ranged through. It then resets all buckets ranged\n// through to 0 (but leaves them in place so that they don't need to get\n// recreated on the next scrape).\nfunc addAndReset(hotBuckets *sync.Map, bucketNumber *uint32) func(k, v interface{}) bool {\n\treturn func(k, v interface{}) bool {\n\t\tbucket := v.(*int64)\n\t\tif addToBucket(hotBuckets, k.(int), atomic.LoadInt64(bucket)) {\n\t\t\tatomic.AddUint32(bucketNumber, 1)\n\t\t}\n\t\tatomic.StoreInt64(bucket, 0)\n\t\treturn true\n\t}\n}\n\nfunc deleteSyncMap(m *sync.Map) {\n\tm.Range(func(k, v interface{}) bool {\n\t\tm.Delete(k)\n\t\treturn true\n\t})\n}\n\nfunc findSmallestKey(m *sync.Map) int {\n\tresult := math.MaxInt32\n\tm.Range(func(k, v interface{}) bool {\n\t\tkey := k.(int)\n\t\tif key < result {\n\t\t\tresult = key\n\t\t}\n\t\treturn true\n\t})\n\treturn result\n}\n\nfunc getLe(key int, schema int32) float64 {\n\t// Here a bit of context about the behavior for the last bucket counting\n\t// regular numbers (called simply \"last bucket\" below) and the bucket\n\t// counting observations of ±Inf (called \"inf bucket\" below, with a key\n\t// one higher than that of the \"last bucket\"):\n\t//\n\t// If we apply the usual formula to the last bucket, its upper bound\n\t// would be calculated as +Inf. The reason is that the max possible\n\t// regular float64 number (math.MaxFloat64) doesn't coincide with one of\n\t// the calculated bucket boundaries. So the calculated boundary has to\n\t// be larger than math.MaxFloat64, and the only float64 larger than\n\t// math.MaxFloat64 is +Inf. However, we want to count actual\n\t// observations of ±Inf in the inf bucket. Therefore, we have to treat\n\t// the upper bound of the last bucket specially and set it to\n\t// math.MaxFloat64. (The upper bound of the inf bucket, with its key\n\t// being one higher than that of the last bucket, naturally comes out as\n\t// +Inf by the usual formula. So that's fine.)\n\t//\n\t// math.MaxFloat64 has a frac of 0.9999999999999999 and an exp of\n\t// 1024. If there were a float64 number following math.MaxFloat64, it\n\t// would have a frac of 1.0 and an exp of 1024, or equivalently a frac\n\t// of 0.5 and an exp of 1025. However, since frac must be smaller than\n\t// 1, and exp must be smaller than 1025, either representation overflows\n\t// a float64. (Which, in turn, is the reason that math.MaxFloat64 is the\n\t// largest possible float64. Q.E.D.) However, the formula for\n\t// calculating the upper bound from the idx and schema of the last\n\t// bucket results in precisely that. It is either frac=1.0 & exp=1024\n\t// (for schema < 0) or frac=0.5 & exp=1025 (for schema >=0). (This is,\n\t// by the way, a power of two where the exponent itself is a power of\n\t// two, 2¹⁰ in fact, which coinicides with a bucket boundary in all\n\t// schemas.) So these are the special cases we have to catch below.\n\tif schema < 0 {\n\t\texp := key << -schema\n\t\tif exp == 1024 {\n\t\t\t// This is the last bucket before the overflow bucket\n\t\t\t// (for ±Inf observations). Return math.MaxFloat64 as\n\t\t\t// explained above.\n\t\t\treturn math.MaxFloat64\n\t\t}\n\t\treturn math.Ldexp(1, exp)\n\t}\n\n\tfracIdx := key & ((1 << schema) - 1)\n\tfrac := nativeHistogramBounds[schema][fracIdx]\n\texp := (key >> schema) + 1\n\tif frac == 0.5 && exp == 1025 {\n\t\t// This is the last bucket before the overflow bucket (for ±Inf\n\t\t// observations). Return math.MaxFloat64 as explained above.\n\t\treturn math.MaxFloat64\n\t}\n\treturn math.Ldexp(frac, exp)\n}\n\n// waitForCooldown returns after the count field in the provided histogramCounts\n// has reached the provided count value.\nfunc waitForCooldown(count uint64, counts *histogramCounts) {\n\tfor count != atomic.LoadUint64(&counts.count) {\n\t\truntime.Gosched() // Let observations get work done.\n\t}\n}\n\n// atomicAddFloat adds the provided float atomically to another float\n// represented by the bit pattern the bits pointer is pointing to.\nfunc atomicAddFloat(bits *uint64, v float64) {\n\tfor {\n\t\tloadedBits := atomic.LoadUint64(bits)\n\t\tnewBits := math.Float64bits(math.Float64frombits(loadedBits) + v)\n\t\tif atomic.CompareAndSwapUint64(bits, loadedBits, newBits) {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n// atomicDecUint32 atomically decrements the uint32 p points to.  See\n// https://pkg.go.dev/sync/atomic#AddUint32 to understand how this is done.\nfunc atomicDecUint32(p *uint32) {\n\tatomic.AddUint32(p, ^uint32(0))\n}\n\n// addAndResetCounts adds certain fields (count, sum, conventional buckets, zero\n// bucket) from the cold counts to the corresponding fields in the hot\n// counts. Those fields are then reset to 0 in the cold counts.\nfunc addAndResetCounts(hot, cold *histogramCounts) {\n\tatomic.AddUint64(&hot.count, atomic.LoadUint64(&cold.count))\n\tatomic.StoreUint64(&cold.count, 0)\n\tcoldSum := math.Float64frombits(atomic.LoadUint64(&cold.sumBits))\n\tatomicAddFloat(&hot.sumBits, coldSum)\n\tatomic.StoreUint64(&cold.sumBits, 0)\n\tfor i := range hot.buckets {\n\t\tatomic.AddUint64(&hot.buckets[i], atomic.LoadUint64(&cold.buckets[i]))\n\t\tatomic.StoreUint64(&cold.buckets[i], 0)\n\t}\n\tatomic.AddUint64(&hot.nativeHistogramZeroBucket, atomic.LoadUint64(&cold.nativeHistogramZeroBucket))\n\tatomic.StoreUint64(&cold.nativeHistogramZeroBucket, 0)\n}\n\ntype nativeExemplars struct {\n\tsync.Mutex\n\n\t// Time-to-live for exemplars, it is set to -1 if exemplars are disabled, that is NativeHistogramMaxExemplars is below 0.\n\t// The ttl is used on insertion to remove an exemplar that is older than ttl, if present.\n\tttl time.Duration\n\n\texemplars []*dto.Exemplar\n}\n\nfunc (n *nativeExemplars) isEnabled() bool {\n\treturn n.ttl != -1\n}\n\nfunc makeNativeExemplars(ttl time.Duration, maxCount int) nativeExemplars {\n\tif ttl == 0 {\n\t\tttl = 5 * time.Minute\n\t}\n\n\tif maxCount == 0 {\n\t\tmaxCount = 10\n\t}\n\n\tif maxCount < 0 {\n\t\tmaxCount = 0\n\t\tttl = -1\n\t}\n\n\treturn nativeExemplars{\n\t\tttl:       ttl,\n\t\texemplars: make([]*dto.Exemplar, 0, maxCount),\n\t}\n}\n\nfunc (n *nativeExemplars) addExemplar(e *dto.Exemplar) {\n\tif !n.isEnabled() {\n\t\treturn\n\t}\n\n\tn.Lock()\n\tdefer n.Unlock()\n\n\t// When the number of exemplars has not yet exceeded or\n\t// is equal to cap(n.exemplars), then\n\t// insert the new exemplar directly.\n\tif len(n.exemplars) < cap(n.exemplars) {\n\t\tvar nIdx int\n\t\tfor nIdx = 0; nIdx < len(n.exemplars); nIdx++ {\n\t\t\tif *e.Value < *n.exemplars[nIdx].Value {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tn.exemplars = append(n.exemplars[:nIdx], append([]*dto.Exemplar{e}, n.exemplars[nIdx:]...)...)\n\t\treturn\n\t}\n\n\tif len(n.exemplars) == 1 {\n\t\t// When the number of exemplars is 1, then\n\t\t// replace the existing exemplar with the new exemplar.\n\t\tn.exemplars[0] = e\n\t\treturn\n\t}\n\t// From this point on, the number of exemplars is greater than 1.\n\n\t// When the number of exemplars exceeds the limit, remove one exemplar.\n\tvar (\n\t\tot    = time.Time{} // Oldest timestamp seen. Initial value doesn't matter as we replace it due to otIdx == -1 in the loop.\n\t\totIdx = -1          // Index of the exemplar with the oldest timestamp.\n\n\t\tmd = -1.0 // Logarithm of the delta of the closest pair of exemplars.\n\n\t\t// The insertion point of the new exemplar in the exemplars slice after insertion.\n\t\t// This is calculated purely based on the order of the exemplars by value.\n\t\t// nIdx == len(n.exemplars) means the new exemplar is to be inserted after the end.\n\t\tnIdx = -1\n\n\t\t// rIdx is ultimately the index for the exemplar that we are replacing with the new exemplar.\n\t\t// The aim is to keep a good spread of exemplars by value and not let them bunch up too much.\n\t\t// It is calculated in 3 steps:\n\t\t//   1. First we set rIdx to the index of the older exemplar within the closest pair by value.\n\t\t//      That is the following will be true (on log scale):\n\t\t//      either the exemplar pair on index (rIdx-1, rIdx) or (rIdx, rIdx+1) will have\n\t\t//      the closest values to each other from all pairs.\n\t\t//      For example, suppose the values are distributed like this:\n\t\t//        |-----------x-------------x----------------x----x-----|\n\t\t//                                                   ^--rIdx as this is older.\n\t\t//      Or like this:\n\t\t//        |-----------x-------------x----------------x----x-----|\n\t\t//                                                        ^--rIdx as this is older.\n\t\t//   2. If there is an exemplar that expired, then we simple reset rIdx to that index.\n\t\t//   3. We check if by inserting the new exemplar we would create a closer pair at\n\t\t//      (nIdx-1, nIdx) or (nIdx, nIdx+1) and set rIdx to nIdx-1 or nIdx accordingly to\n\t\t//      keep the spread of exemplars by value; otherwise we keep rIdx as it is.\n\t\trIdx = -1\n\t\tcLog float64 // Logarithm of the current exemplar.\n\t\tpLog float64 // Logarithm of the previous exemplar.\n\t)\n\n\tfor i, exemplar := range n.exemplars {\n\t\t// Find the exemplar with the oldest timestamp.\n\t\tif otIdx == -1 || exemplar.Timestamp.AsTime().Before(ot) {\n\t\t\tot = exemplar.Timestamp.AsTime()\n\t\t\totIdx = i\n\t\t}\n\n\t\t// Find the index at which to insert new the exemplar.\n\t\tif nIdx == -1 && *e.Value <= *exemplar.Value {\n\t\t\tnIdx = i\n\t\t}\n\n\t\t// Find the two closest exemplars and pick the one the with older timestamp.\n\t\tpLog = cLog\n\t\tcLog = math.Log(exemplar.GetValue())\n\t\tif i == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tdiff := math.Abs(cLog - pLog)\n\t\tif md == -1 || diff < md {\n\t\t\t// The closest exemplar pair is at index: i-1, i.\n\t\t\t// Choose the exemplar with the older timestamp for replacement.\n\t\t\tmd = diff\n\t\t\tif n.exemplars[i].Timestamp.AsTime().Before(n.exemplars[i-1].Timestamp.AsTime()) {\n\t\t\t\trIdx = i\n\t\t\t} else {\n\t\t\t\trIdx = i - 1\n\t\t\t}\n\t\t}\n\n\t}\n\n\t// If all existing exemplar are smaller than new exemplar,\n\t// then the exemplar should be inserted at the end.\n\tif nIdx == -1 {\n\t\tnIdx = len(n.exemplars)\n\t}\n\t// Here, we have the following relationships:\n\t// n.exemplars[nIdx-1].Value < e.Value (if nIdx > 0)\n\t// e.Value <= n.exemplars[nIdx].Value (if nIdx < len(n.exemplars))\n\n\tif otIdx != -1 && e.Timestamp.AsTime().Sub(ot) > n.ttl {\n\t\t// If the oldest exemplar has expired, then replace it with the new exemplar.\n\t\trIdx = otIdx\n\t} else {\n\t\t// In the previous for loop, when calculating the closest pair of exemplars,\n\t\t// we did not take into account the newly inserted exemplar.\n\t\t// So we need to calculate with the newly inserted exemplar again.\n\t\telog := math.Log(e.GetValue())\n\t\tif nIdx > 0 {\n\t\t\tdiff := math.Abs(elog - math.Log(n.exemplars[nIdx-1].GetValue()))\n\t\t\tif diff < md {\n\t\t\t\t// The value we are about to insert is closer to the previous exemplar at the insertion point than what we calculated before in rIdx.\n\t\t\t\t//                                            v--rIdx\n\t\t\t\t// |-----------x-n-----------x----------------x----x-----|\n\t\t\t\t//     nIdx-1--^ ^--new exemplar value\n\t\t\t\t// Do not make the spread worse, replace nIdx-1 and not rIdx.\n\t\t\t\tmd = diff\n\t\t\t\trIdx = nIdx - 1\n\t\t\t}\n\t\t}\n\t\tif nIdx < len(n.exemplars) {\n\t\t\tdiff := math.Abs(math.Log(n.exemplars[nIdx].GetValue()) - elog)\n\t\t\tif diff < md {\n\t\t\t\t// The value we are about to insert is closer to the next exemplar at the insertion point than what we calculated before in rIdx.\n\t\t\t\t//                                            v--rIdx\n\t\t\t\t// |-----------x-----------n-x----------------x----x-----|\n\t\t\t\t//     new exemplar value--^ ^--nIdx\n\t\t\t\t// Do not make the spread worse, replace nIdx-1 and not rIdx.\n\t\t\t\trIdx = nIdx\n\t\t\t}\n\t\t}\n\t}\n\n\t// Adjust the slice according to rIdx and nIdx.\n\tswitch {\n\tcase rIdx == nIdx:\n\t\tn.exemplars[nIdx] = e\n\tcase rIdx < nIdx:\n\t\tn.exemplars = append(n.exemplars[:rIdx], append(n.exemplars[rIdx+1:nIdx], append([]*dto.Exemplar{e}, n.exemplars[nIdx:]...)...)...)\n\tcase rIdx > nIdx:\n\t\tn.exemplars = append(n.exemplars[:nIdx], append([]*dto.Exemplar{e}, append(n.exemplars[nIdx:rIdx], n.exemplars[rIdx+1:]...)...)...)\n\t}\n}\n\ntype constNativeHistogram struct {\n\tdesc *Desc\n\tdto.Histogram\n\tlabelPairs []*dto.LabelPair\n}\n\nfunc validateCount(sum float64, count uint64, negativeBuckets, positiveBuckets map[int]int64, zeroBucket uint64) error {\n\tvar bucketPopulationSum int64\n\tfor _, v := range positiveBuckets {\n\t\tbucketPopulationSum += v\n\t}\n\tfor _, v := range negativeBuckets {\n\t\tbucketPopulationSum += v\n\t}\n\tbucketPopulationSum += int64(zeroBucket)\n\n\t// If the sum of observations is NaN, the number of observations must be greater or equal to the sum of all bucket counts.\n\t// Otherwise, the number of observations must be equal to the sum of all bucket counts .\n\n\tif math.IsNaN(sum) && bucketPopulationSum > int64(count) ||\n\t\t!math.IsNaN(sum) && bucketPopulationSum != int64(count) {\n\t\treturn errors.New(\"the sum of all bucket populations exceeds the count of observations\")\n\t}\n\treturn nil\n}\n\n// NewConstNativeHistogram returns a metric representing a Prometheus native histogram with\n// fixed values for the count, sum, and positive/negative/zero bucket counts. As those parameters\n// cannot be changed, the returned value does not implement the Histogram\n// interface (but only the Metric interface). Users of this package will not\n// have much use for it in regular operations. However, when implementing custom\n// OpenTelemetry Collectors, it is useful as a throw-away metric that is generated on the fly\n// to send it to Prometheus in the Collect method.\n//\n// zeroBucket counts all (positive and negative)\n// observations in the zero bucket (with an absolute value less or equal\n// the current threshold).\n// positiveBuckets and negativeBuckets are separate maps for negative and positive\n// observations. The map's value is an int64, counting observations in\n// that bucket. The map's key is the\n// index of the bucket according to the used\n// Schema. Index 0 is for an upper bound of 1 in positive buckets and for a lower bound of -1 in negative buckets.\n// NewConstNativeHistogram returns an error if\n//   - the length of labelValues is not consistent with the variable labels in Desc or if Desc is invalid.\n//   - the schema passed is not between 8 and -4\n//   - the sum of counts in all buckets including the zero bucket does not equal the count if sum is not NaN (or exceeds the count if sum is NaN)\n//\n// See https://opentelemetry.io/docs/specs/otel/compatibility/prometheus_and_openmetrics/#exponential-histograms for more details about the conversion from OTel to Prometheus.\nfunc NewConstNativeHistogram(\n\tdesc *Desc,\n\tcount uint64,\n\tsum float64,\n\tpositiveBuckets, negativeBuckets map[int]int64,\n\tzeroBucket uint64,\n\tschema int32,\n\tzeroThreshold float64,\n\tcreatedTimestamp time.Time,\n\tlabelValues ...string,\n) (Metric, error) {\n\tif desc.err != nil {\n\t\treturn nil, desc.err\n\t}\n\tif err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {\n\t\treturn nil, err\n\t}\n\tif schema > nativeHistogramSchemaMaximum || schema < nativeHistogramSchemaMinimum {\n\t\treturn nil, errors.New(\"invalid native histogram schema\")\n\t}\n\tif err := validateCount(sum, count, negativeBuckets, positiveBuckets, zeroBucket); err != nil {\n\t\treturn nil, err\n\t}\n\n\tNegativeSpan, NegativeDelta := makeBucketsFromMap(negativeBuckets)\n\tPositiveSpan, PositiveDelta := makeBucketsFromMap(positiveBuckets)\n\tret := &constNativeHistogram{\n\t\tdesc: desc,\n\t\tHistogram: dto.Histogram{\n\t\t\tCreatedTimestamp: timestamppb.New(createdTimestamp),\n\t\t\tSchema:           &schema,\n\t\t\tZeroThreshold:    &zeroThreshold,\n\t\t\tSampleCount:      &count,\n\t\t\tSampleSum:        &sum,\n\n\t\t\tNegativeSpan:  NegativeSpan,\n\t\t\tNegativeDelta: NegativeDelta,\n\n\t\t\tPositiveSpan:  PositiveSpan,\n\t\t\tPositiveDelta: PositiveDelta,\n\n\t\t\tZeroCount: proto.Uint64(zeroBucket),\n\t\t},\n\t\tlabelPairs: MakeLabelPairs(desc, labelValues),\n\t}\n\tif *ret.ZeroThreshold == 0 && *ret.ZeroCount == 0 && len(ret.PositiveSpan) == 0 && len(ret.NegativeSpan) == 0 {\n\t\tret.PositiveSpan = []*dto.BucketSpan{{\n\t\t\tOffset: proto.Int32(0),\n\t\t\tLength: proto.Uint32(0),\n\t\t}}\n\t}\n\treturn ret, nil\n}\n\n// MustNewConstNativeHistogram is a version of NewConstNativeHistogram that panics where\n// NewConstNativeHistogram would have returned an error.\nfunc MustNewConstNativeHistogram(\n\tdesc *Desc,\n\tcount uint64,\n\tsum float64,\n\tpositiveBuckets, negativeBuckets map[int]int64,\n\tzeroBucket uint64,\n\tnativeHistogramSchema int32,\n\tnativeHistogramZeroThreshold float64,\n\tcreatedTimestamp time.Time,\n\tlabelValues ...string,\n) Metric {\n\tnativehistogram, err := NewConstNativeHistogram(desc,\n\t\tcount,\n\t\tsum,\n\t\tpositiveBuckets,\n\t\tnegativeBuckets,\n\t\tzeroBucket,\n\t\tnativeHistogramSchema,\n\t\tnativeHistogramZeroThreshold,\n\t\tcreatedTimestamp,\n\t\tlabelValues...)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn nativehistogram\n}\n\nfunc (h *constNativeHistogram) Desc() *Desc {\n\treturn h.desc\n}\n\nfunc (h *constNativeHistogram) Write(out *dto.Metric) error {\n\tout.Histogram = &h.Histogram\n\tout.Label = h.labelPairs\n\treturn nil\n}\n\nfunc makeBucketsFromMap(buckets map[int]int64) ([]*dto.BucketSpan, []int64) {\n\tif len(buckets) == 0 {\n\t\treturn nil, nil\n\t}\n\tvar ii []int\n\tfor k := range buckets {\n\t\tii = append(ii, k)\n\t}\n\tsort.Ints(ii)\n\n\tvar (\n\t\tspans     []*dto.BucketSpan\n\t\tdeltas    []int64\n\t\tprevCount int64\n\t\tnextI     int\n\t)\n\n\tappendDelta := func(count int64) {\n\t\t*spans[len(spans)-1].Length++\n\t\tdeltas = append(deltas, count-prevCount)\n\t\tprevCount = count\n\t}\n\n\tfor n, i := range ii {\n\t\tcount := buckets[i]\n\t\t// Multiple spans with only small gaps in between are probably\n\t\t// encoded more efficiently as one larger span with a few empty\n\t\t// buckets. Needs some research to find the sweet spot. For now,\n\t\t// we assume that gaps of one or two buckets should not create\n\t\t// a new span.\n\t\tiDelta := int32(i - nextI)\n\t\tif n == 0 || iDelta > 2 {\n\t\t\t// We have to create a new span, either because we are\n\t\t\t// at the very beginning, or because we have found a gap\n\t\t\t// of more than two buckets.\n\t\t\tspans = append(spans, &dto.BucketSpan{\n\t\t\t\tOffset: proto.Int32(iDelta),\n\t\t\t\tLength: proto.Uint32(0),\n\t\t\t})\n\t\t} else {\n\t\t\t// We have found a small gap (or no gap at all).\n\t\t\t// Insert empty buckets as needed.\n\t\t\tfor j := int32(0); j < iDelta; j++ {\n\t\t\t\tappendDelta(0)\n\t\t\t}\n\t\t}\n\t\tappendDelta(count)\n\t\tnextI = i + 1\n\t}\n\treturn spans, deltas\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/internal/almost_equal.go",
    "content": "// Copyright (c) 2015 Björn Rabenstein\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n//\n// The code in this package is copy/paste to avoid a dependency. Hence this file\n// carries the copyright of the original repo.\n// https://github.com/beorn7/floats\npackage internal\n\nimport (\n\t\"math\"\n)\n\n// minNormalFloat64 is the smallest positive normal value of type float64.\nvar minNormalFloat64 = math.Float64frombits(0x0010000000000000)\n\n// AlmostEqualFloat64 returns true if a and b are equal within a relative error\n// of epsilon. See http://floating-point-gui.de/errors/comparison/ for the\n// details of the applied method.\nfunc AlmostEqualFloat64(a, b, epsilon float64) bool {\n\tif a == b {\n\t\treturn true\n\t}\n\tabsA := math.Abs(a)\n\tabsB := math.Abs(b)\n\tdiff := math.Abs(a - b)\n\tif a == 0 || b == 0 || absA+absB < minNormalFloat64 {\n\t\treturn diff < epsilon*minNormalFloat64\n\t}\n\treturn diff/math.Min(absA+absB, math.MaxFloat64) < epsilon\n}\n\n// AlmostEqualFloat64s is the slice form of AlmostEqualFloat64.\nfunc AlmostEqualFloat64s(a, b []float64, epsilon float64) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tfor i := range a {\n\t\tif !AlmostEqualFloat64(a[i], b[i], epsilon) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go",
    "content": "// Copyright 2022 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n// It provides tools to compare sequences of strings and generate textual diffs.\n//\n// Maintaining `GetUnifiedDiffString` here because original repository\n// (https://github.com/pmezard/go-difflib) is no longer maintained.\npackage internal\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc minInt(a, b int) int {\n\tif a < b {\n\t\treturn a\n\t}\n\treturn b\n}\n\nfunc maxInt(a, b int) int {\n\tif a > b {\n\t\treturn a\n\t}\n\treturn b\n}\n\nfunc calculateRatio(matches, length int) float64 {\n\tif length > 0 {\n\t\treturn 2.0 * float64(matches) / float64(length)\n\t}\n\treturn 1.0\n}\n\ntype Match struct {\n\tA    int\n\tB    int\n\tSize int\n}\n\ntype OpCode struct {\n\tTag byte\n\tI1  int\n\tI2  int\n\tJ1  int\n\tJ2  int\n}\n\n// SequenceMatcher compares sequence of strings. The basic\n// algorithm predates, and is a little fancier than, an algorithm\n// published in the late 1980's by Ratcliff and Obershelp under the\n// hyperbolic name \"gestalt pattern matching\".  The basic idea is to find\n// the longest contiguous matching subsequence that contains no \"junk\"\n// elements (R-O doesn't address junk).  The same idea is then applied\n// recursively to the pieces of the sequences to the left and to the right\n// of the matching subsequence.  This does not yield minimal edit\n// sequences, but does tend to yield matches that \"look right\" to people.\n//\n// SequenceMatcher tries to compute a \"human-friendly diff\" between two\n// sequences.  Unlike e.g. UNIX(tm) diff, the fundamental notion is the\n// longest *contiguous* & junk-free matching subsequence.  That's what\n// catches peoples' eyes.  The Windows(tm) windiff has another interesting\n// notion, pairing up elements that appear uniquely in each sequence.\n// That, and the method here, appear to yield more intuitive difference\n// reports than does diff.  This method appears to be the least vulnerable\n// to synching up on blocks of \"junk lines\", though (like blank lines in\n// ordinary text files, or maybe \"<P>\" lines in HTML files).  That may be\n// because this is the only method of the 3 that has a *concept* of\n// \"junk\" <wink>.\n//\n// Timing:  Basic R-O is cubic time worst case and quadratic time expected\n// case.  SequenceMatcher is quadratic time for the worst case and has\n// expected-case behavior dependent in a complicated way on how many\n// elements the sequences have in common; best case time is linear.\ntype SequenceMatcher struct {\n\ta              []string\n\tb              []string\n\tb2j            map[string][]int\n\tIsJunk         func(string) bool\n\tautoJunk       bool\n\tbJunk          map[string]struct{}\n\tmatchingBlocks []Match\n\tfullBCount     map[string]int\n\tbPopular       map[string]struct{}\n\topCodes        []OpCode\n}\n\nfunc NewMatcher(a, b []string) *SequenceMatcher {\n\tm := SequenceMatcher{autoJunk: true}\n\tm.SetSeqs(a, b)\n\treturn &m\n}\n\nfunc NewMatcherWithJunk(a, b []string, autoJunk bool,\n\tisJunk func(string) bool,\n) *SequenceMatcher {\n\tm := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk}\n\tm.SetSeqs(a, b)\n\treturn &m\n}\n\n// Set two sequences to be compared.\nfunc (m *SequenceMatcher) SetSeqs(a, b []string) {\n\tm.SetSeq1(a)\n\tm.SetSeq2(b)\n}\n\n// Set the first sequence to be compared. The second sequence to be compared is\n// not changed.\n//\n// SequenceMatcher computes and caches detailed information about the second\n// sequence, so if you want to compare one sequence S against many sequences,\n// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other\n// sequences.\n//\n// See also SetSeqs() and SetSeq2().\nfunc (m *SequenceMatcher) SetSeq1(a []string) {\n\tif &a == &m.a {\n\t\treturn\n\t}\n\tm.a = a\n\tm.matchingBlocks = nil\n\tm.opCodes = nil\n}\n\n// Set the second sequence to be compared. The first sequence to be compared is\n// not changed.\nfunc (m *SequenceMatcher) SetSeq2(b []string) {\n\tif &b == &m.b {\n\t\treturn\n\t}\n\tm.b = b\n\tm.matchingBlocks = nil\n\tm.opCodes = nil\n\tm.fullBCount = nil\n\tm.chainB()\n}\n\nfunc (m *SequenceMatcher) chainB() {\n\t// Populate line -> index mapping\n\tb2j := map[string][]int{}\n\tfor i, s := range m.b {\n\t\tindices := b2j[s]\n\t\tindices = append(indices, i)\n\t\tb2j[s] = indices\n\t}\n\n\t// Purge junk elements\n\tm.bJunk = map[string]struct{}{}\n\tif m.IsJunk != nil {\n\t\tjunk := m.bJunk\n\t\tfor s := range b2j {\n\t\t\tif m.IsJunk(s) {\n\t\t\t\tjunk[s] = struct{}{}\n\t\t\t}\n\t\t}\n\t\tfor s := range junk {\n\t\t\tdelete(b2j, s)\n\t\t}\n\t}\n\n\t// Purge remaining popular elements\n\tpopular := map[string]struct{}{}\n\tn := len(m.b)\n\tif m.autoJunk && n >= 200 {\n\t\tntest := n/100 + 1\n\t\tfor s, indices := range b2j {\n\t\t\tif len(indices) > ntest {\n\t\t\t\tpopular[s] = struct{}{}\n\t\t\t}\n\t\t}\n\t\tfor s := range popular {\n\t\t\tdelete(b2j, s)\n\t\t}\n\t}\n\tm.bPopular = popular\n\tm.b2j = b2j\n}\n\nfunc (m *SequenceMatcher) isBJunk(s string) bool {\n\t_, ok := m.bJunk[s]\n\treturn ok\n}\n\n// Find longest matching block in a[alo:ahi] and b[blo:bhi].\n//\n// If IsJunk is not defined:\n//\n// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where\n//\n//\talo <= i <= i+k <= ahi\n//\tblo <= j <= j+k <= bhi\n//\n// and for all (i',j',k') meeting those conditions,\n//\n//\tk >= k'\n//\ti <= i'\n//\tand if i == i', j <= j'\n//\n// In other words, of all maximal matching blocks, return one that\n// starts earliest in a, and of all those maximal matching blocks that\n// start earliest in a, return the one that starts earliest in b.\n//\n// If IsJunk is defined, first the longest matching block is\n// determined as above, but with the additional restriction that no\n// junk element appears in the block.  Then that block is extended as\n// far as possible by matching (only) junk elements on both sides.  So\n// the resulting block never matches on junk except as identical junk\n// happens to be adjacent to an \"interesting\" match.\n//\n// If no blocks match, return (alo, blo, 0).\nfunc (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match {\n\t// CAUTION:  stripping common prefix or suffix would be incorrect.\n\t// E.g.,\n\t//    ab\n\t//    acab\n\t// Longest matching block is \"ab\", but if common prefix is\n\t// stripped, it's \"a\" (tied with \"b\").  UNIX(tm) diff does so\n\t// strip, so ends up claiming that ab is changed to acab by\n\t// inserting \"ca\" in the middle.  That's minimal but unintuitive:\n\t// \"it's obvious\" that someone inserted \"ac\" at the front.\n\t// Windiff ends up at the same place as diff, but by pairing up\n\t// the unique 'b's and then matching the first two 'a's.\n\tbesti, bestj, bestsize := alo, blo, 0\n\n\t// find longest junk-free match\n\t// during an iteration of the loop, j2len[j] = length of longest\n\t// junk-free match ending with a[i-1] and b[j]\n\tj2len := map[int]int{}\n\tfor i := alo; i != ahi; i++ {\n\t\t// look at all instances of a[i] in b; note that because\n\t\t// b2j has no junk keys, the loop is skipped if a[i] is junk\n\t\tnewj2len := map[int]int{}\n\t\tfor _, j := range m.b2j[m.a[i]] {\n\t\t\t// a[i] matches b[j]\n\t\t\tif j < blo {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif j >= bhi {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tk := j2len[j-1] + 1\n\t\t\tnewj2len[j] = k\n\t\t\tif k > bestsize {\n\t\t\t\tbesti, bestj, bestsize = i-k+1, j-k+1, k\n\t\t\t}\n\t\t}\n\t\tj2len = newj2len\n\t}\n\n\t// Extend the best by non-junk elements on each end.  In particular,\n\t// \"popular\" non-junk elements aren't in b2j, which greatly speeds\n\t// the inner loop above, but also means \"the best\" match so far\n\t// doesn't contain any junk *or* popular non-junk elements.\n\tfor besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) &&\n\t\tm.a[besti-1] == m.b[bestj-1] {\n\t\tbesti, bestj, bestsize = besti-1, bestj-1, bestsize+1\n\t}\n\tfor besti+bestsize < ahi && bestj+bestsize < bhi &&\n\t\t!m.isBJunk(m.b[bestj+bestsize]) &&\n\t\tm.a[besti+bestsize] == m.b[bestj+bestsize] {\n\t\tbestsize++\n\t}\n\n\t// Now that we have a wholly interesting match (albeit possibly\n\t// empty!), we may as well suck up the matching junk on each\n\t// side of it too.  Can't think of a good reason not to, and it\n\t// saves post-processing the (possibly considerable) expense of\n\t// figuring out what to do with it.  In the case of an empty\n\t// interesting match, this is clearly the right thing to do,\n\t// because no other kind of match is possible in the regions.\n\tfor besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) &&\n\t\tm.a[besti-1] == m.b[bestj-1] {\n\t\tbesti, bestj, bestsize = besti-1, bestj-1, bestsize+1\n\t}\n\tfor besti+bestsize < ahi && bestj+bestsize < bhi &&\n\t\tm.isBJunk(m.b[bestj+bestsize]) &&\n\t\tm.a[besti+bestsize] == m.b[bestj+bestsize] {\n\t\tbestsize++\n\t}\n\n\treturn Match{A: besti, B: bestj, Size: bestsize}\n}\n\n// Return list of triples describing matching subsequences.\n//\n// Each triple is of the form (i, j, n), and means that\n// a[i:i+n] == b[j:j+n].  The triples are monotonically increasing in\n// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are\n// adjacent triples in the list, and the second is not the last triple in the\n// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe\n// adjacent equal blocks.\n//\n// The last triple is a dummy, (len(a), len(b), 0), and is the only\n// triple with n==0.\nfunc (m *SequenceMatcher) GetMatchingBlocks() []Match {\n\tif m.matchingBlocks != nil {\n\t\treturn m.matchingBlocks\n\t}\n\n\tvar matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match\n\tmatchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match {\n\t\tmatch := m.findLongestMatch(alo, ahi, blo, bhi)\n\t\ti, j, k := match.A, match.B, match.Size\n\t\tif match.Size > 0 {\n\t\t\tif alo < i && blo < j {\n\t\t\t\tmatched = matchBlocks(alo, i, blo, j, matched)\n\t\t\t}\n\t\t\tmatched = append(matched, match)\n\t\t\tif i+k < ahi && j+k < bhi {\n\t\t\t\tmatched = matchBlocks(i+k, ahi, j+k, bhi, matched)\n\t\t\t}\n\t\t}\n\t\treturn matched\n\t}\n\tmatched := matchBlocks(0, len(m.a), 0, len(m.b), nil)\n\n\t// It's possible that we have adjacent equal blocks in the\n\t// matching_blocks list now.\n\tnonAdjacent := []Match{}\n\ti1, j1, k1 := 0, 0, 0\n\tfor _, b := range matched {\n\t\t// Is this block adjacent to i1, j1, k1?\n\t\ti2, j2, k2 := b.A, b.B, b.Size\n\t\tif i1+k1 == i2 && j1+k1 == j2 {\n\t\t\t// Yes, so collapse them -- this just increases the length of\n\t\t\t// the first block by the length of the second, and the first\n\t\t\t// block so lengthened remains the block to compare against.\n\t\t\tk1 += k2\n\t\t} else {\n\t\t\t// Not adjacent.  Remember the first block (k1==0 means it's\n\t\t\t// the dummy we started with), and make the second block the\n\t\t\t// new block to compare against.\n\t\t\tif k1 > 0 {\n\t\t\t\tnonAdjacent = append(nonAdjacent, Match{i1, j1, k1})\n\t\t\t}\n\t\t\ti1, j1, k1 = i2, j2, k2\n\t\t}\n\t}\n\tif k1 > 0 {\n\t\tnonAdjacent = append(nonAdjacent, Match{i1, j1, k1})\n\t}\n\n\tnonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0})\n\tm.matchingBlocks = nonAdjacent\n\treturn m.matchingBlocks\n}\n\n// Return list of 5-tuples describing how to turn a into b.\n//\n// Each tuple is of the form (tag, i1, i2, j1, j2).  The first tuple\n// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the\n// tuple preceding it, and likewise for j1 == the previous j2.\n//\n// The tags are characters, with these meanings:\n//\n// 'r' (replace):  a[i1:i2] should be replaced by b[j1:j2]\n//\n// 'd' (delete):   a[i1:i2] should be deleted, j1==j2 in this case.\n//\n// 'i' (insert):   b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case.\n//\n// 'e' (equal):    a[i1:i2] == b[j1:j2]\nfunc (m *SequenceMatcher) GetOpCodes() []OpCode {\n\tif m.opCodes != nil {\n\t\treturn m.opCodes\n\t}\n\ti, j := 0, 0\n\tmatching := m.GetMatchingBlocks()\n\topCodes := make([]OpCode, 0, len(matching))\n\tfor _, m := range matching {\n\t\t//  invariant:  we've pumped out correct diffs to change\n\t\t//  a[:i] into b[:j], and the next matching block is\n\t\t//  a[ai:ai+size] == b[bj:bj+size]. So we need to pump\n\t\t//  out a diff to change a[i:ai] into b[j:bj], pump out\n\t\t//  the matching block, and move (i,j) beyond the match\n\t\tai, bj, size := m.A, m.B, m.Size\n\t\ttag := byte(0)\n\t\tif i < ai && j < bj {\n\t\t\ttag = 'r'\n\t\t} else if i < ai {\n\t\t\ttag = 'd'\n\t\t} else if j < bj {\n\t\t\ttag = 'i'\n\t\t}\n\t\tif tag > 0 {\n\t\t\topCodes = append(opCodes, OpCode{tag, i, ai, j, bj})\n\t\t}\n\t\ti, j = ai+size, bj+size\n\t\t// the list of matching blocks is terminated by a\n\t\t// sentinel with size 0\n\t\tif size > 0 {\n\t\t\topCodes = append(opCodes, OpCode{'e', ai, i, bj, j})\n\t\t}\n\t}\n\tm.opCodes = opCodes\n\treturn m.opCodes\n}\n\n// Isolate change clusters by eliminating ranges with no changes.\n//\n// Return a generator of groups with up to n lines of context.\n// Each group is in the same format as returned by GetOpCodes().\nfunc (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode {\n\tif n < 0 {\n\t\tn = 3\n\t}\n\tcodes := m.GetOpCodes()\n\tif len(codes) == 0 {\n\t\tcodes = []OpCode{{'e', 0, 1, 0, 1}}\n\t}\n\t// Fixup leading and trailing groups if they show no changes.\n\tif codes[0].Tag == 'e' {\n\t\tc := codes[0]\n\t\ti1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2\n\t\tcodes[0] = OpCode{c.Tag, maxInt(i1, i2-n), i2, maxInt(j1, j2-n), j2}\n\t}\n\tif codes[len(codes)-1].Tag == 'e' {\n\t\tc := codes[len(codes)-1]\n\t\ti1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2\n\t\tcodes[len(codes)-1] = OpCode{c.Tag, i1, minInt(i2, i1+n), j1, minInt(j2, j1+n)}\n\t}\n\tnn := n + n\n\tgroups := [][]OpCode{}\n\tgroup := []OpCode{}\n\tfor _, c := range codes {\n\t\ti1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2\n\t\t// End the current group and start a new one whenever\n\t\t// there is a large range with no changes.\n\t\tif c.Tag == 'e' && i2-i1 > nn {\n\t\t\tgroup = append(group, OpCode{\n\t\t\t\tc.Tag, i1, minInt(i2, i1+n),\n\t\t\t\tj1, minInt(j2, j1+n),\n\t\t\t})\n\t\t\tgroups = append(groups, group)\n\t\t\tgroup = []OpCode{}\n\t\t\ti1, j1 = maxInt(i1, i2-n), maxInt(j1, j2-n)\n\t\t}\n\t\tgroup = append(group, OpCode{c.Tag, i1, i2, j1, j2})\n\t}\n\tif len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') {\n\t\tgroups = append(groups, group)\n\t}\n\treturn groups\n}\n\n// Return a measure of the sequences' similarity (float in [0,1]).\n//\n// Where T is the total number of elements in both sequences, and\n// M is the number of matches, this is 2.0*M / T.\n// Note that this is 1 if the sequences are identical, and 0 if\n// they have nothing in common.\n//\n// .Ratio() is expensive to compute if you haven't already computed\n// .GetMatchingBlocks() or .GetOpCodes(), in which case you may\n// want to try .QuickRatio() or .RealQuickRation() first to get an\n// upper bound.\nfunc (m *SequenceMatcher) Ratio() float64 {\n\tmatches := 0\n\tfor _, m := range m.GetMatchingBlocks() {\n\t\tmatches += m.Size\n\t}\n\treturn calculateRatio(matches, len(m.a)+len(m.b))\n}\n\n// Return an upper bound on ratio() relatively quickly.\n//\n// This isn't defined beyond that it is an upper bound on .Ratio(), and\n// is faster to compute.\nfunc (m *SequenceMatcher) QuickRatio() float64 {\n\t// viewing a and b as multisets, set matches to the cardinality\n\t// of their intersection; this counts the number of matches\n\t// without regard to order, so is clearly an upper bound\n\tif m.fullBCount == nil {\n\t\tm.fullBCount = map[string]int{}\n\t\tfor _, s := range m.b {\n\t\t\tm.fullBCount[s]++\n\t\t}\n\t}\n\n\t// avail[x] is the number of times x appears in 'b' less the\n\t// number of times we've seen it in 'a' so far ... kinda\n\tavail := map[string]int{}\n\tmatches := 0\n\tfor _, s := range m.a {\n\t\tn, ok := avail[s]\n\t\tif !ok {\n\t\t\tn = m.fullBCount[s]\n\t\t}\n\t\tavail[s] = n - 1\n\t\tif n > 0 {\n\t\t\tmatches++\n\t\t}\n\t}\n\treturn calculateRatio(matches, len(m.a)+len(m.b))\n}\n\n// Return an upper bound on ratio() very quickly.\n//\n// This isn't defined beyond that it is an upper bound on .Ratio(), and\n// is faster to compute than either .Ratio() or .QuickRatio().\nfunc (m *SequenceMatcher) RealQuickRatio() float64 {\n\tla, lb := len(m.a), len(m.b)\n\treturn calculateRatio(minInt(la, lb), la+lb)\n}\n\n// Convert range to the \"ed\" format\nfunc formatRangeUnified(start, stop int) string {\n\t// Per the diff spec at http://www.unix.org/single_unix_specification/\n\tbeginning := start + 1 // lines start numbering with one\n\tlength := stop - start\n\tif length == 1 {\n\t\treturn strconv.Itoa(beginning)\n\t}\n\tif length == 0 {\n\t\tbeginning-- // empty ranges begin at line just before the range\n\t}\n\treturn fmt.Sprintf(\"%d,%d\", beginning, length)\n}\n\n// Unified diff parameters\ntype UnifiedDiff struct {\n\tA        []string // First sequence lines\n\tFromFile string   // First file name\n\tFromDate string   // First file time\n\tB        []string // Second sequence lines\n\tToFile   string   // Second file name\n\tToDate   string   // Second file time\n\tEol      string   // Headers end of line, defaults to LF\n\tContext  int      // Number of context lines\n}\n\n// Compare two sequences of lines; generate the delta as a unified diff.\n//\n// Unified diffs are a compact way of showing line changes and a few\n// lines of context.  The number of context lines is set by 'n' which\n// defaults to three.\n//\n// By default, the diff control lines (those with ---, +++, or @@) are\n// created with a trailing newline.  This is helpful so that inputs\n// created from file.readlines() result in diffs that are suitable for\n// file.writelines() since both the inputs and outputs have trailing\n// newlines.\n//\n// For inputs that do not have trailing newlines, set the lineterm\n// argument to \"\" so that the output will be uniformly newline free.\n//\n// The unidiff format normally has a header for filenames and modification\n// times.  Any or all of these may be specified using strings for\n// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.\n// The modification times are normally expressed in the ISO 8601 format.\nfunc WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error {\n\tbuf := bufio.NewWriter(writer)\n\tdefer buf.Flush()\n\twf := func(format string, args ...interface{}) error {\n\t\t_, err := buf.WriteString(fmt.Sprintf(format, args...))\n\t\treturn err\n\t}\n\tws := func(s string) error {\n\t\t_, err := buf.WriteString(s)\n\t\treturn err\n\t}\n\n\tif len(diff.Eol) == 0 {\n\t\tdiff.Eol = \"\\n\"\n\t}\n\n\tstarted := false\n\tm := NewMatcher(diff.A, diff.B)\n\tfor _, g := range m.GetGroupedOpCodes(diff.Context) {\n\t\tif !started {\n\t\t\tstarted = true\n\t\t\tfromDate := \"\"\n\t\t\tif len(diff.FromDate) > 0 {\n\t\t\t\tfromDate = \"\\t\" + diff.FromDate\n\t\t\t}\n\t\t\ttoDate := \"\"\n\t\t\tif len(diff.ToDate) > 0 {\n\t\t\t\ttoDate = \"\\t\" + diff.ToDate\n\t\t\t}\n\t\t\tif diff.FromFile != \"\" || diff.ToFile != \"\" {\n\t\t\t\terr := wf(\"--- %s%s%s\", diff.FromFile, fromDate, diff.Eol)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\terr = wf(\"+++ %s%s%s\", diff.ToFile, toDate, diff.Eol)\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\t}\n\t\tfirst, last := g[0], g[len(g)-1]\n\t\trange1 := formatRangeUnified(first.I1, last.I2)\n\t\trange2 := formatRangeUnified(first.J1, last.J2)\n\t\tif err := wf(\"@@ -%s +%s @@%s\", range1, range2, diff.Eol); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfor _, c := range g {\n\t\t\ti1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2\n\t\t\tif c.Tag == 'e' {\n\t\t\t\tfor _, line := range diff.A[i1:i2] {\n\t\t\t\t\tif err := ws(\" \" + line); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif c.Tag == 'r' || c.Tag == 'd' {\n\t\t\t\tfor _, line := range diff.A[i1:i2] {\n\t\t\t\t\tif err := ws(\"-\" + line); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif c.Tag == 'r' || c.Tag == 'i' {\n\t\t\t\tfor _, line := range diff.B[j1:j2] {\n\t\t\t\t\tif err := ws(\"+\" + line); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// Like WriteUnifiedDiff but returns the diff a string.\nfunc GetUnifiedDiffString(diff UnifiedDiff) (string, error) {\n\tw := &bytes.Buffer{}\n\terr := WriteUnifiedDiff(w, diff)\n\treturn w.String(), err\n}\n\n// Split a string on \"\\n\" while preserving them. The output can be used\n// as input for UnifiedDiff and ContextDiff structures.\nfunc SplitLines(s string) []string {\n\tlines := strings.SplitAfter(s, \"\\n\")\n\tlines[len(lines)-1] += \"\\n\"\n\treturn lines\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go",
    "content": "// Copyright 2021 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage internal\n\nimport \"regexp\"\n\ntype GoCollectorRule struct {\n\tMatcher *regexp.Regexp\n\tDeny    bool\n}\n\n// GoCollectorOptions should not be used be directly by anything, except `collectors` package.\n// Use it via collectors package instead. See issue\n// https://github.com/prometheus/client_golang/issues/1030.\n//\n// This is internal, so external users only can use it via `collector.WithGoCollector*` methods\ntype GoCollectorOptions struct {\n\tDisableMemStatsLikeMetrics bool\n\tRuntimeMetricSumForHist    map[string]string\n\tRuntimeMetricRules         []GoCollectorRule\n}\n\nvar GoCollectorDefaultRuntimeMetrics = regexp.MustCompile(`/gc/gogc:percent|/gc/gomemlimit:bytes|/sched/gomaxprocs:threads`)\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go",
    "content": "// Copyright 2021 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build go1.17\n// +build go1.17\n\npackage internal\n\nimport (\n\t\"math\"\n\t\"path\"\n\t\"runtime/metrics\"\n\t\"strings\"\n\n\t\"github.com/prometheus/common/model\"\n)\n\n// RuntimeMetricsToProm produces a Prometheus metric name from a runtime/metrics\n// metric description and validates whether the metric is suitable for integration\n// with Prometheus.\n//\n// Returns false if a name could not be produced, or if Prometheus does not understand\n// the runtime/metrics Kind.\n//\n// Note that the main reason a name couldn't be produced is if the runtime/metrics\n// package exports a name with characters outside the valid Prometheus metric name\n// character set. This is theoretically possible, but should never happen in practice.\n// Still, don't rely on it.\nfunc RuntimeMetricsToProm(d *metrics.Description) (string, string, string, bool) {\n\tnamespace := \"go\"\n\n\tcomp := strings.SplitN(d.Name, \":\", 2)\n\tkey := comp[0]\n\tunit := comp[1]\n\n\t// The last path element in the key is the name,\n\t// the rest is the subsystem.\n\tsubsystem := path.Dir(key[1:] /* remove leading / */)\n\tname := path.Base(key)\n\n\t// subsystem is translated by replacing all / and - with _.\n\tsubsystem = strings.ReplaceAll(subsystem, \"/\", \"_\")\n\tsubsystem = strings.ReplaceAll(subsystem, \"-\", \"_\")\n\n\t// unit is translated assuming that the unit contains no\n\t// non-ASCII characters.\n\tunit = strings.ReplaceAll(unit, \"-\", \"_\")\n\tunit = strings.ReplaceAll(unit, \"*\", \"_\")\n\tunit = strings.ReplaceAll(unit, \"/\", \"_per_\")\n\n\t// name has - replaced with _ and is concatenated with the unit and\n\t// other data.\n\tname = strings.ReplaceAll(name, \"-\", \"_\")\n\tname += \"_\" + unit\n\tif d.Cumulative && d.Kind != metrics.KindFloat64Histogram {\n\t\tname += \"_total\"\n\t}\n\n\t// Our current conversion moves to legacy naming, so use legacy validation.\n\tvalid := model.IsValidLegacyMetricName(namespace + \"_\" + subsystem + \"_\" + name)\n\tswitch d.Kind {\n\tcase metrics.KindUint64:\n\tcase metrics.KindFloat64:\n\tcase metrics.KindFloat64Histogram:\n\tdefault:\n\t\tvalid = false\n\t}\n\treturn namespace, subsystem, name, valid\n}\n\n// RuntimeMetricsBucketsForUnit takes a set of buckets obtained for a runtime/metrics histogram\n// type (so, lower-bound inclusive) and a unit from a runtime/metrics name, and produces\n// a reduced set of buckets. This function always removes any -Inf bucket as it's represented\n// as the bottom-most upper-bound inclusive bucket in Prometheus.\nfunc RuntimeMetricsBucketsForUnit(buckets []float64, unit string) []float64 {\n\tswitch unit {\n\tcase \"bytes\":\n\t\t// Re-bucket as powers of 2.\n\t\treturn reBucketExp(buckets, 2)\n\tcase \"seconds\":\n\t\t// Re-bucket as powers of 10 and then merge all buckets greater\n\t\t// than 1 second into the +Inf bucket.\n\t\tb := reBucketExp(buckets, 10)\n\t\tfor i := range b {\n\t\t\tif b[i] <= 1 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tb[i] = math.Inf(1)\n\t\t\tb = b[:i+1]\n\t\t\tbreak\n\t\t}\n\t\treturn b\n\t}\n\treturn buckets\n}\n\n// reBucketExp takes a list of bucket boundaries (lower bound inclusive) and\n// downsamples the buckets to those a multiple of base apart. The end result\n// is a roughly exponential (in many cases, perfectly exponential) bucketing\n// scheme.\nfunc reBucketExp(buckets []float64, base float64) []float64 {\n\tbucket := buckets[0]\n\tvar newBuckets []float64\n\t// We may see a -Inf here, in which case, add it and skip it\n\t// since we risk producing NaNs otherwise.\n\t//\n\t// We need to preserve -Inf values to maintain runtime/metrics\n\t// conventions. We'll strip it out later.\n\tif bucket == math.Inf(-1) {\n\t\tnewBuckets = append(newBuckets, bucket)\n\t\tbuckets = buckets[1:]\n\t\tbucket = buckets[0]\n\t}\n\t// From now on, bucket should always have a non-Inf value because\n\t// Infs are only ever at the ends of the bucket lists, so\n\t// arithmetic operations on it are non-NaN.\n\tfor i := 1; i < len(buckets); i++ {\n\t\tif bucket >= 0 && buckets[i] < bucket*base {\n\t\t\t// The next bucket we want to include is at least bucket*base.\n\t\t\tcontinue\n\t\t} else if bucket < 0 && buckets[i] < bucket/base {\n\t\t\t// In this case the bucket we're targeting is negative, and since\n\t\t\t// we're ascending through buckets here, we need to divide to get\n\t\t\t// closer to zero exponentially.\n\t\t\tcontinue\n\t\t}\n\t\t// The +Inf bucket will always be the last one, and we'll always\n\t\t// end up including it here because bucket\n\t\tnewBuckets = append(newBuckets, bucket)\n\t\tbucket = buckets[i]\n\t}\n\treturn append(newBuckets, bucket)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage internal\n\nimport (\n\t\"sort\"\n\n\tdto \"github.com/prometheus/client_model/go\"\n)\n\n// LabelPairSorter implements sort.Interface. It is used to sort a slice of\n// dto.LabelPair pointers.\ntype LabelPairSorter []*dto.LabelPair\n\nfunc (s LabelPairSorter) Len() int {\n\treturn len(s)\n}\n\nfunc (s LabelPairSorter) Swap(i, j int) {\n\ts[i], s[j] = s[j], s[i]\n}\n\nfunc (s LabelPairSorter) Less(i, j int) bool {\n\treturn s[i].GetName() < s[j].GetName()\n}\n\n// MetricSorter is a sortable slice of *dto.Metric.\ntype MetricSorter []*dto.Metric\n\nfunc (s MetricSorter) Len() int {\n\treturn len(s)\n}\n\nfunc (s MetricSorter) Swap(i, j int) {\n\ts[i], s[j] = s[j], s[i]\n}\n\nfunc (s MetricSorter) Less(i, j int) bool {\n\tif len(s[i].Label) != len(s[j].Label) {\n\t\t// This should not happen. The metrics are\n\t\t// inconsistent. However, we have to deal with the fact, as\n\t\t// people might use custom collectors or metric family injection\n\t\t// to create inconsistent metrics. So let's simply compare the\n\t\t// number of labels in this case. That will still yield\n\t\t// reproducible sorting.\n\t\treturn len(s[i].Label) < len(s[j].Label)\n\t}\n\tfor n, lp := range s[i].Label {\n\t\tvi := lp.GetValue()\n\t\tvj := s[j].Label[n].GetValue()\n\t\tif vi != vj {\n\t\t\treturn vi < vj\n\t\t}\n\t}\n\n\t// We should never arrive here. Multiple metrics with the same\n\t// label set in the same scrape will lead to undefined ingestion\n\t// behavior. However, as above, we have to provide stable sorting\n\t// here, even for inconsistent metrics. So sort equal metrics\n\t// by their timestamp, with missing timestamps (implying \"now\")\n\t// coming last.\n\tif s[i].TimestampMs == nil {\n\t\treturn false\n\t}\n\tif s[j].TimestampMs == nil {\n\t\treturn true\n\t}\n\treturn s[i].GetTimestampMs() < s[j].GetTimestampMs()\n}\n\n// NormalizeMetricFamilies returns a MetricFamily slice with empty\n// MetricFamilies pruned and the remaining MetricFamilies sorted by name within\n// the slice, with the contained Metrics sorted within each MetricFamily.\nfunc NormalizeMetricFamilies(metricFamiliesByName map[string]*dto.MetricFamily) []*dto.MetricFamily {\n\tfor _, mf := range metricFamiliesByName {\n\t\tsort.Sort(MetricSorter(mf.Metric))\n\t}\n\tnames := make([]string, 0, len(metricFamiliesByName))\n\tfor name, mf := range metricFamiliesByName {\n\t\tif len(mf.Metric) > 0 {\n\t\t\tnames = append(names, name)\n\t\t}\n\t}\n\tsort.Strings(names)\n\tresult := make([]*dto.MetricFamily, 0, len(names))\n\tfor _, name := range names {\n\t\tresult = append(result, metricFamiliesByName[name])\n\t}\n\treturn result\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/labels.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"github.com/prometheus/common/model\"\n)\n\n// Labels represents a collection of label name -> value mappings. This type is\n// commonly used with the With(Labels) and GetMetricWith(Labels) methods of\n// metric vector Collectors, e.g.:\n//\n//\tmyVec.With(Labels{\"code\": \"404\", \"method\": \"GET\"}).Add(42)\n//\n// The other use-case is the specification of constant label pairs in Opts or to\n// create a Desc.\ntype Labels map[string]string\n\n// LabelConstraint normalizes label values.\ntype LabelConstraint func(string) string\n\n// ConstrainedLabels represents a label name and its constrain function\n// to normalize label values. This type is commonly used when constructing\n// metric vector Collectors.\ntype ConstrainedLabel struct {\n\tName       string\n\tConstraint LabelConstraint\n}\n\n// ConstrainableLabels is an interface that allows creating of labels that can\n// be optionally constrained.\n//\n//\tprometheus.V2().NewCounterVec(CounterVecOpts{\n//\t  CounterOpts: {...}, // Usual CounterOpts fields\n//\t  VariableLabels: []ConstrainedLabels{\n//\t    {Name: \"A\"},\n//\t    {Name: \"B\", Constraint: func(v string) string { ... }},\n//\t  },\n//\t})\ntype ConstrainableLabels interface {\n\tcompile() *compiledLabels\n\tlabelNames() []string\n}\n\n// ConstrainedLabels represents a collection of label name -> constrain function\n// to normalize label values. This type is commonly used when constructing\n// metric vector Collectors.\ntype ConstrainedLabels []ConstrainedLabel\n\nfunc (cls ConstrainedLabels) compile() *compiledLabels {\n\tcompiled := &compiledLabels{\n\t\tnames:            make([]string, len(cls)),\n\t\tlabelConstraints: map[string]LabelConstraint{},\n\t}\n\n\tfor i, label := range cls {\n\t\tcompiled.names[i] = label.Name\n\t\tif label.Constraint != nil {\n\t\t\tcompiled.labelConstraints[label.Name] = label.Constraint\n\t\t}\n\t}\n\n\treturn compiled\n}\n\nfunc (cls ConstrainedLabels) labelNames() []string {\n\tnames := make([]string, len(cls))\n\tfor i, label := range cls {\n\t\tnames[i] = label.Name\n\t}\n\treturn names\n}\n\n// UnconstrainedLabels represents collection of label without any constraint on\n// their value. Thus, it is simply a collection of label names.\n//\n//\tUnconstrainedLabels([]string{ \"A\", \"B\" })\n//\n// is equivalent to\n//\n//\tConstrainedLabels {\n//\t  { Name: \"A\" },\n//\t  { Name: \"B\" },\n//\t}\ntype UnconstrainedLabels []string\n\nfunc (uls UnconstrainedLabels) compile() *compiledLabels {\n\treturn &compiledLabels{\n\t\tnames: uls,\n\t}\n}\n\nfunc (uls UnconstrainedLabels) labelNames() []string {\n\treturn uls\n}\n\ntype compiledLabels struct {\n\tnames            []string\n\tlabelConstraints map[string]LabelConstraint\n}\n\nfunc (cls *compiledLabels) compile() *compiledLabels {\n\treturn cls\n}\n\nfunc (cls *compiledLabels) labelNames() []string {\n\treturn cls.names\n}\n\nfunc (cls *compiledLabels) constrain(labelName, value string) string {\n\tif fn, ok := cls.labelConstraints[labelName]; ok && fn != nil {\n\t\treturn fn(value)\n\t}\n\treturn value\n}\n\n// reservedLabelPrefix is a prefix which is not legal in user-supplied\n// label names.\nconst reservedLabelPrefix = \"__\"\n\nvar errInconsistentCardinality = errors.New(\"inconsistent label cardinality\")\n\nfunc makeInconsistentCardinalityError(fqName string, labels, labelValues []string) error {\n\treturn fmt.Errorf(\n\t\t\"%w: %q has %d variable labels named %q but %d values %q were provided\",\n\t\terrInconsistentCardinality, fqName,\n\t\tlen(labels), labels,\n\t\tlen(labelValues), labelValues,\n\t)\n}\n\nfunc validateValuesInLabels(labels Labels, expectedNumberOfValues int) error {\n\tif len(labels) != expectedNumberOfValues {\n\t\treturn fmt.Errorf(\n\t\t\t\"%w: expected %d label values but got %d in %#v\",\n\t\t\terrInconsistentCardinality, expectedNumberOfValues,\n\t\t\tlen(labels), labels,\n\t\t)\n\t}\n\n\tfor name, val := range labels {\n\t\tif !utf8.ValidString(val) {\n\t\t\treturn fmt.Errorf(\"label %s: value %q is not valid UTF-8\", name, val)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc validateLabelValues(vals []string, expectedNumberOfValues int) error {\n\tif len(vals) != expectedNumberOfValues {\n\t\t// The call below makes vals escape, copy them to avoid that.\n\t\tvals := append([]string(nil), vals...)\n\t\treturn fmt.Errorf(\n\t\t\t\"%w: expected %d label values but got %d in %#v\",\n\t\t\terrInconsistentCardinality, expectedNumberOfValues,\n\t\t\tlen(vals), vals,\n\t\t)\n\t}\n\n\tfor _, val := range vals {\n\t\tif !utf8.ValidString(val) {\n\t\t\treturn fmt.Errorf(\"label value %q is not valid UTF-8\", val)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc checkLabelName(l string) bool {\n\treturn model.LabelName(l).IsValid() && !strings.HasPrefix(l, reservedLabelPrefix)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/metric.go",
    "content": "// Copyright 2014 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\nimport (\n\t\"errors\"\n\t\"math\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\tdto \"github.com/prometheus/client_model/go\"\n\t\"github.com/prometheus/common/model\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\nvar separatorByteSlice = []byte{model.SeparatorByte} // For convenient use with xxhash.\n\n// A Metric models a single sample value with its meta data being exported to\n// Prometheus. Implementations of Metric in this package are Gauge, Counter,\n// Histogram, Summary, and Untyped.\ntype Metric interface {\n\t// Desc returns the descriptor for the Metric. This method idempotently\n\t// returns the same descriptor throughout the lifetime of the\n\t// Metric. The returned descriptor is immutable by contract. A Metric\n\t// unable to describe itself must return an invalid descriptor (created\n\t// with NewInvalidDesc).\n\tDesc() *Desc\n\t// Write encodes the Metric into a \"Metric\" Protocol Buffer data\n\t// transmission object.\n\t//\n\t// Metric implementations must observe concurrency safety as reads of\n\t// this metric may occur at any time, and any blocking occurs at the\n\t// expense of total performance of rendering all registered\n\t// metrics. Ideally, Metric implementations should support concurrent\n\t// readers.\n\t//\n\t// While populating dto.Metric, it is the responsibility of the\n\t// implementation to ensure validity of the Metric protobuf (like valid\n\t// UTF-8 strings or syntactically valid metric and label names). It is\n\t// recommended to sort labels lexicographically. Callers of Write should\n\t// still make sure of sorting if they depend on it.\n\tWrite(*dto.Metric) error\n\t// TODO(beorn7): The original rationale of passing in a pre-allocated\n\t// dto.Metric protobuf to save allocations has disappeared. The\n\t// signature of this method should be changed to \"Write() (*dto.Metric,\n\t// error)\".\n}\n\n// Opts bundles the options for creating most Metric types. Each metric\n// implementation XXX has its own XXXOpts type, but in most cases, it is just\n// an alias of this type (which might change when the requirement arises.)\n//\n// It is mandatory to set Name to a non-empty string. All other fields are\n// optional and can safely be left at their zero value, although it is strongly\n// encouraged to set a Help string.\ntype Opts struct {\n\t// Namespace, Subsystem, and Name are components of the fully-qualified\n\t// name of the Metric (created by joining these components with\n\t// \"_\"). Only Name is mandatory, the others merely help structuring the\n\t// name. Note that the fully-qualified name of the metric must be a\n\t// valid Prometheus metric name.\n\tNamespace string\n\tSubsystem string\n\tName      string\n\n\t// Help provides information about this metric.\n\t//\n\t// Metrics with the same fully-qualified name must have the same Help\n\t// string.\n\tHelp string\n\n\t// ConstLabels are used to attach fixed labels to this metric. Metrics\n\t// with the same fully-qualified name must have the same label names in\n\t// their ConstLabels.\n\t//\n\t// ConstLabels are only used rarely. In particular, do not use them to\n\t// attach the same labels to all your metrics. Those use cases are\n\t// better covered by target labels set by the scraping Prometheus\n\t// server, or by one specific metric (e.g. a build_info or a\n\t// machine_role metric). See also\n\t// https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels\n\tConstLabels Labels\n\n\t// now is for testing purposes, by default it's time.Now.\n\tnow func() time.Time\n}\n\n// BuildFQName joins the given three name components by \"_\". Empty name\n// components are ignored. If the name parameter itself is empty, an empty\n// string is returned, no matter what. Metric implementations included in this\n// library use this function internally to generate the fully-qualified metric\n// name from the name component in their Opts. Users of the library will only\n// need this function if they implement their own Metric or instantiate a Desc\n// (with NewDesc) directly.\nfunc BuildFQName(namespace, subsystem, name string) string {\n\tif name == \"\" {\n\t\treturn \"\"\n\t}\n\n\tsb := strings.Builder{}\n\tsb.Grow(len(namespace) + len(subsystem) + len(name) + 2)\n\n\tif namespace != \"\" {\n\t\tsb.WriteString(namespace)\n\t\tsb.WriteString(\"_\")\n\t}\n\n\tif subsystem != \"\" {\n\t\tsb.WriteString(subsystem)\n\t\tsb.WriteString(\"_\")\n\t}\n\n\tsb.WriteString(name)\n\n\treturn sb.String()\n}\n\ntype invalidMetric struct {\n\tdesc *Desc\n\terr  error\n}\n\n// NewInvalidMetric returns a metric whose Write method always returns the\n// provided error. It is useful if a Collector finds itself unable to collect\n// a metric and wishes to report an error to the registry.\nfunc NewInvalidMetric(desc *Desc, err error) Metric {\n\treturn &invalidMetric{desc, err}\n}\n\nfunc (m *invalidMetric) Desc() *Desc { return m.desc }\n\nfunc (m *invalidMetric) Write(*dto.Metric) error { return m.err }\n\ntype timestampedMetric struct {\n\tMetric\n\tt time.Time\n}\n\nfunc (m timestampedMetric) Write(pb *dto.Metric) error {\n\te := m.Metric.Write(pb)\n\tpb.TimestampMs = proto.Int64(m.t.Unix()*1000 + int64(m.t.Nanosecond()/1000000))\n\treturn e\n}\n\n// NewMetricWithTimestamp returns a new Metric wrapping the provided Metric in a\n// way that it has an explicit timestamp set to the provided Time. This is only\n// useful in rare cases as the timestamp of a Prometheus metric should usually\n// be set by the Prometheus server during scraping. Exceptions include mirroring\n// metrics with given timestamps from other metric\n// sources.\n//\n// NewMetricWithTimestamp works best with MustNewConstMetric,\n// MustNewConstHistogram, and MustNewConstSummary, see example.\n//\n// Currently, the exposition formats used by Prometheus are limited to\n// millisecond resolution. Thus, the provided time will be rounded down to the\n// next full millisecond value.\nfunc NewMetricWithTimestamp(t time.Time, m Metric) Metric {\n\treturn timestampedMetric{Metric: m, t: t}\n}\n\ntype withExemplarsMetric struct {\n\tMetric\n\n\texemplars []*dto.Exemplar\n}\n\nfunc (m *withExemplarsMetric) Write(pb *dto.Metric) error {\n\tif err := m.Metric.Write(pb); err != nil {\n\t\treturn err\n\t}\n\n\tswitch {\n\tcase pb.Counter != nil:\n\t\tpb.Counter.Exemplar = m.exemplars[len(m.exemplars)-1]\n\tcase pb.Histogram != nil:\n\t\tfor _, e := range m.exemplars {\n\t\t\t// pb.Histogram.Bucket are sorted by UpperBound.\n\t\t\ti := sort.Search(len(pb.Histogram.Bucket), func(i int) bool {\n\t\t\t\treturn pb.Histogram.Bucket[i].GetUpperBound() >= e.GetValue()\n\t\t\t})\n\t\t\tif i < len(pb.Histogram.Bucket) {\n\t\t\t\tpb.Histogram.Bucket[i].Exemplar = e\n\t\t\t} else {\n\t\t\t\t// The +Inf bucket should be explicitly added if there is an exemplar for it, similar to non-const histogram logic in https://github.com/prometheus/client_golang/blob/main/prometheus/histogram.go#L357-L365.\n\t\t\t\tb := &dto.Bucket{\n\t\t\t\t\tCumulativeCount: proto.Uint64(pb.Histogram.GetSampleCount()),\n\t\t\t\t\tUpperBound:      proto.Float64(math.Inf(1)),\n\t\t\t\t\tExemplar:        e,\n\t\t\t\t}\n\t\t\t\tpb.Histogram.Bucket = append(pb.Histogram.Bucket, b)\n\t\t\t}\n\t\t}\n\tdefault:\n\t\t// TODO(bwplotka): Implement Gauge?\n\t\treturn errors.New(\"cannot inject exemplar into Gauge, Summary or Untyped\")\n\t}\n\n\treturn nil\n}\n\n// Exemplar is easier to use, user-facing representation of *dto.Exemplar.\ntype Exemplar struct {\n\tValue  float64\n\tLabels Labels\n\t// Optional.\n\t// Default value (time.Time{}) indicates its empty, which should be\n\t// understood as time.Now() time at the moment of creation of metric.\n\tTimestamp time.Time\n}\n\n// NewMetricWithExemplars returns a new Metric wrapping the provided Metric with given\n// exemplars. Exemplars are validated.\n//\n// Only last applicable exemplar is injected from the list.\n// For example for Counter it means last exemplar is injected.\n// For Histogram, it means last applicable exemplar for each bucket is injected.\n//\n// NewMetricWithExemplars works best with MustNewConstMetric and\n// MustNewConstHistogram, see example.\nfunc NewMetricWithExemplars(m Metric, exemplars ...Exemplar) (Metric, error) {\n\tif len(exemplars) == 0 {\n\t\treturn nil, errors.New(\"no exemplar was passed for NewMetricWithExemplars\")\n\t}\n\n\tvar (\n\t\tnow = time.Now()\n\t\texs = make([]*dto.Exemplar, len(exemplars))\n\t\terr error\n\t)\n\tfor i, e := range exemplars {\n\t\tts := e.Timestamp\n\t\tif ts.IsZero() {\n\t\t\tts = now\n\t\t}\n\t\texs[i], err = newExemplar(e.Value, ts, e.Labels)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn &withExemplarsMetric{Metric: m, exemplars: exs}, nil\n}\n\n// MustNewMetricWithExemplars is a version of NewMetricWithExemplars that panics where\n// NewMetricWithExemplars would have returned an error.\nfunc MustNewMetricWithExemplars(m Metric, exemplars ...Exemplar) Metric {\n\tret, err := NewMetricWithExemplars(m, exemplars...)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn ret\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/num_threads.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build !js || wasm\n// +build !js wasm\n\npackage prometheus\n\nimport \"runtime\"\n\n// getRuntimeNumThreads returns the number of open OS threads.\nfunc getRuntimeNumThreads() float64 {\n\tn, _ := runtime.ThreadCreateProfile(nil)\n\treturn float64(n)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build js && !wasm\n// +build js,!wasm\n\npackage prometheus\n\n// getRuntimeNumThreads returns the number of open OS threads.\nfunc getRuntimeNumThreads() float64 {\n\treturn 1\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/observer.go",
    "content": "// Copyright 2017 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\n// Observer is the interface that wraps the Observe method, which is used by\n// Histogram and Summary to add observations.\ntype Observer interface {\n\tObserve(float64)\n}\n\n// The ObserverFunc type is an adapter to allow the use of ordinary\n// functions as Observers. If f is a function with the appropriate\n// signature, ObserverFunc(f) is an Observer that calls f.\n//\n// This adapter is usually used in connection with the Timer type, and there are\n// two general use cases:\n//\n// The most common one is to use a Gauge as the Observer for a Timer.\n// See the \"Gauge\" Timer example.\n//\n// The more advanced use case is to create a function that dynamically decides\n// which Observer to use for observing the duration. See the \"Complex\" Timer\n// example.\ntype ObserverFunc func(float64)\n\n// Observe calls f(value). It implements Observer.\nfunc (f ObserverFunc) Observe(value float64) {\n\tf(value)\n}\n\n// ObserverVec is an interface implemented by `HistogramVec` and `SummaryVec`.\ntype ObserverVec interface {\n\tGetMetricWith(Labels) (Observer, error)\n\tGetMetricWithLabelValues(lvs ...string) (Observer, error)\n\tWith(Labels) Observer\n\tWithLabelValues(...string) Observer\n\tCurryWith(Labels) (ObserverVec, error)\n\tMustCurryWith(Labels) ObserverVec\n\n\tCollector\n}\n\n// ExemplarObserver is implemented by Observers that offer the option of\n// observing a value together with an exemplar. Its ObserveWithExemplar method\n// works like the Observe method of an Observer but also replaces the currently\n// saved exemplar (if any) with a new one, created from the provided value, the\n// current time as timestamp, and the provided Labels. Empty Labels will lead to\n// a valid (label-less) exemplar. But if Labels is nil, the current exemplar is\n// left in place. ObserveWithExemplar panics if any of the provided labels are\n// invalid or if the provided labels contain more than 128 runes in total.\ntype ExemplarObserver interface {\n\tObserveWithExemplar(value float64, exemplar Labels)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/process_collector.go",
    "content": "// Copyright 2015 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype processCollector struct {\n\tcollectFn         func(chan<- Metric)\n\tdescribeFn        func(chan<- *Desc)\n\tpidFn             func() (int, error)\n\treportErrors      bool\n\tcpuTotal          *Desc\n\topenFDs, maxFDs   *Desc\n\tvsize, maxVsize   *Desc\n\trss               *Desc\n\tstartTime         *Desc\n\tinBytes, outBytes *Desc\n}\n\n// ProcessCollectorOpts defines the behavior of a process metrics collector\n// created with NewProcessCollector.\ntype ProcessCollectorOpts struct {\n\t// PidFn returns the PID of the process the collector collects metrics\n\t// for. It is called upon each collection. By default, the PID of the\n\t// current process is used, as determined on construction time by\n\t// calling os.Getpid().\n\tPidFn func() (int, error)\n\t// If non-empty, each of the collected metrics is prefixed by the\n\t// provided string and an underscore (\"_\").\n\tNamespace string\n\t// If true, any error encountered during collection is reported as an\n\t// invalid metric (see NewInvalidMetric). Otherwise, errors are ignored\n\t// and the collected metrics will be incomplete. (Possibly, no metrics\n\t// will be collected at all.) While that's usually not desired, it is\n\t// appropriate for the common \"mix-in\" of process metrics, where process\n\t// metrics are nice to have, but failing to collect them should not\n\t// disrupt the collection of the remaining metrics.\n\tReportErrors bool\n}\n\n// NewProcessCollector is the obsolete version of collectors.NewProcessCollector.\n// See there for documentation.\n//\n// Deprecated: Use collectors.NewProcessCollector instead.\nfunc NewProcessCollector(opts ProcessCollectorOpts) Collector {\n\tns := \"\"\n\tif len(opts.Namespace) > 0 {\n\t\tns = opts.Namespace + \"_\"\n\t}\n\n\tc := &processCollector{\n\t\treportErrors: opts.ReportErrors,\n\t\tcpuTotal: NewDesc(\n\t\t\tns+\"process_cpu_seconds_total\",\n\t\t\t\"Total user and system CPU time spent in seconds.\",\n\t\t\tnil, nil,\n\t\t),\n\t\topenFDs: NewDesc(\n\t\t\tns+\"process_open_fds\",\n\t\t\t\"Number of open file descriptors.\",\n\t\t\tnil, nil,\n\t\t),\n\t\tmaxFDs: NewDesc(\n\t\t\tns+\"process_max_fds\",\n\t\t\t\"Maximum number of open file descriptors.\",\n\t\t\tnil, nil,\n\t\t),\n\t\tvsize: NewDesc(\n\t\t\tns+\"process_virtual_memory_bytes\",\n\t\t\t\"Virtual memory size in bytes.\",\n\t\t\tnil, nil,\n\t\t),\n\t\tmaxVsize: NewDesc(\n\t\t\tns+\"process_virtual_memory_max_bytes\",\n\t\t\t\"Maximum amount of virtual memory available in bytes.\",\n\t\t\tnil, nil,\n\t\t),\n\t\trss: NewDesc(\n\t\t\tns+\"process_resident_memory_bytes\",\n\t\t\t\"Resident memory size in bytes.\",\n\t\t\tnil, nil,\n\t\t),\n\t\tstartTime: NewDesc(\n\t\t\tns+\"process_start_time_seconds\",\n\t\t\t\"Start time of the process since unix epoch in seconds.\",\n\t\t\tnil, nil,\n\t\t),\n\t\tinBytes: NewDesc(\n\t\t\tns+\"process_network_receive_bytes_total\",\n\t\t\t\"Number of bytes received by the process over the network.\",\n\t\t\tnil, nil,\n\t\t),\n\t\toutBytes: NewDesc(\n\t\t\tns+\"process_network_transmit_bytes_total\",\n\t\t\t\"Number of bytes sent by the process over the network.\",\n\t\t\tnil, nil,\n\t\t),\n\t}\n\n\tif opts.PidFn == nil {\n\t\tc.pidFn = getPIDFn()\n\t} else {\n\t\tc.pidFn = opts.PidFn\n\t}\n\n\t// Set up process metric collection if supported by the runtime.\n\tif canCollectProcess() {\n\t\tc.collectFn = c.processCollect\n\t\tc.describeFn = c.describe\n\t} else {\n\t\tc.collectFn = c.errorCollectFn\n\t\tc.describeFn = c.errorDescribeFn\n\t}\n\n\treturn c\n}\n\nfunc (c *processCollector) errorCollectFn(ch chan<- Metric) {\n\tc.reportError(ch, nil, errors.New(\"process metrics not supported on this platform\"))\n}\n\nfunc (c *processCollector) errorDescribeFn(ch chan<- *Desc) {\n\tif c.reportErrors {\n\t\tch <- NewInvalidDesc(errors.New(\"process metrics not supported on this platform\"))\n\t}\n}\n\n// Collect returns the current state of all metrics of the collector.\nfunc (c *processCollector) Collect(ch chan<- Metric) {\n\tc.collectFn(ch)\n}\n\n// Describe returns all descriptions of the collector.\nfunc (c *processCollector) Describe(ch chan<- *Desc) {\n\tc.describeFn(ch)\n}\n\nfunc (c *processCollector) reportError(ch chan<- Metric, desc *Desc, err error) {\n\tif !c.reportErrors {\n\t\treturn\n\t}\n\tif desc == nil {\n\t\tdesc = NewInvalidDesc(err)\n\t}\n\tch <- NewInvalidMetric(desc, err)\n}\n\n// NewPidFileFn returns a function that retrieves a pid from the specified file.\n// It is meant to be used for the PidFn field in ProcessCollectorOpts.\nfunc NewPidFileFn(pidFilePath string) func() (int, error) {\n\treturn func() (int, error) {\n\t\tcontent, err := os.ReadFile(pidFilePath)\n\t\tif err != nil {\n\t\t\treturn 0, fmt.Errorf(\"can't read pid file %q: %w\", pidFilePath, err)\n\t\t}\n\t\tpid, err := strconv.Atoi(strings.TrimSpace(string(content)))\n\t\tif err != nil {\n\t\t\treturn 0, fmt.Errorf(\"can't parse pid file %q: %w\", pidFilePath, err)\n\t\t}\n\n\t\treturn pid, nil\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/process_collector_darwin.go",
    "content": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build darwin && !ios\n\npackage prometheus\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\n// notImplementedErr is returned by stub functions that replace cgo functions, when cgo\n// isn't available.\nvar notImplementedErr = errors.New(\"not implemented\")\n\ntype memoryInfo struct {\n\tvsize uint64 // Virtual memory size in bytes\n\trss   uint64 // Resident memory size in bytes\n}\n\nfunc canCollectProcess() bool {\n\treturn true\n}\n\nfunc getSoftLimit(which int) (uint64, error) {\n\trlimit := syscall.Rlimit{}\n\n\tif err := syscall.Getrlimit(which, &rlimit); err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn rlimit.Cur, nil\n}\n\nfunc getOpenFileCount() (float64, error) {\n\t// Alternately, the undocumented proc_pidinfo(PROC_PIDLISTFDS) can be used to\n\t// return a list of open fds, but that requires a way to call C APIs.  The\n\t// benefits, however, include fewer system calls and not failing when at the\n\t// open file soft limit.\n\n\tif dir, err := os.Open(\"/dev/fd\"); err != nil {\n\t\treturn 0.0, err\n\t} else {\n\t\tdefer dir.Close()\n\n\t\t// Avoid ReadDir(), as it calls stat(2) on each descriptor.  Not only is\n\t\t// that info not used, but KQUEUE descriptors fail stat(2), which causes\n\t\t// the whole method to fail.\n\t\tif names, err := dir.Readdirnames(0); err != nil {\n\t\t\treturn 0.0, err\n\t\t} else {\n\t\t\t// Subtract 1 to ignore the open /dev/fd descriptor above.\n\t\t\treturn float64(len(names) - 1), nil\n\t\t}\n\t}\n}\n\nfunc (c *processCollector) processCollect(ch chan<- Metric) {\n\tif procs, err := unix.SysctlKinfoProcSlice(\"kern.proc.pid\", os.Getpid()); err == nil {\n\t\tif len(procs) == 1 {\n\t\t\tstartTime := float64(procs[0].Proc.P_starttime.Nano() / 1e9)\n\t\t\tch <- MustNewConstMetric(c.startTime, GaugeValue, startTime)\n\t\t} else {\n\t\t\terr = fmt.Errorf(\"sysctl() returned %d proc structs (expected 1)\", len(procs))\n\t\t\tc.reportError(ch, c.startTime, err)\n\t\t}\n\t} else {\n\t\tc.reportError(ch, c.startTime, err)\n\t}\n\n\t// The proc structure returned by kern.proc.pid above has an Rusage member,\n\t// but it is not filled in, so it needs to be fetched by getrusage(2).  For\n\t// that call, the UTime, STime, and Maxrss members are filled out, but not\n\t// Ixrss, Idrss, or Isrss for the memory usage.  Memory stats will require\n\t// access to the C API to call task_info(TASK_BASIC_INFO).\n\trusage := unix.Rusage{}\n\n\tif err := unix.Getrusage(syscall.RUSAGE_SELF, &rusage); err == nil {\n\t\tcpuTime := time.Duration(rusage.Stime.Nano() + rusage.Utime.Nano()).Seconds()\n\t\tch <- MustNewConstMetric(c.cpuTotal, CounterValue, cpuTime)\n\t} else {\n\t\tc.reportError(ch, c.cpuTotal, err)\n\t}\n\n\tif memInfo, err := getMemory(); err == nil {\n\t\tch <- MustNewConstMetric(c.rss, GaugeValue, float64(memInfo.rss))\n\t\tch <- MustNewConstMetric(c.vsize, GaugeValue, float64(memInfo.vsize))\n\t} else if !errors.Is(err, notImplementedErr) {\n\t\t// Don't report an error when support is not compiled in.\n\t\tc.reportError(ch, c.rss, err)\n\t\tc.reportError(ch, c.vsize, err)\n\t}\n\n\tif fds, err := getOpenFileCount(); err == nil {\n\t\tch <- MustNewConstMetric(c.openFDs, GaugeValue, fds)\n\t} else {\n\t\tc.reportError(ch, c.openFDs, err)\n\t}\n\n\tif openFiles, err := getSoftLimit(syscall.RLIMIT_NOFILE); err == nil {\n\t\tch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(openFiles))\n\t} else {\n\t\tc.reportError(ch, c.maxFDs, err)\n\t}\n\n\tif addressSpace, err := getSoftLimit(syscall.RLIMIT_AS); err == nil {\n\t\tch <- MustNewConstMetric(c.maxVsize, GaugeValue, float64(addressSpace))\n\t} else {\n\t\tc.reportError(ch, c.maxVsize, err)\n\t}\n\n\t// TODO: socket(PF_SYSTEM) to fetch \"com.apple.network.statistics\" might\n\t//  be able to get the per-process network send/receive counts.\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.c",
    "content": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build darwin && !ios && cgo\n\n#include <mach/mach_init.h>\n#include <mach/task.h>\n#include <mach/mach_vm.h>\n\n// The compiler warns that mach/shared_memory_server.h is deprecated, and to use\n// mach/shared_region.h instead.  But that doesn't define\n// SHARED_DATA_REGION_SIZE or SHARED_TEXT_REGION_SIZE, so redefine them here and\n// avoid a warning message when running tests.\n#define GLOBAL_SHARED_TEXT_SEGMENT      0x90000000U\n#define SHARED_DATA_REGION_SIZE         0x10000000\n#define SHARED_TEXT_REGION_SIZE         0x10000000\n\n\nint get_memory_info(unsigned long long *rss, unsigned long long *vsize)\n{\n    // This is lightly adapted from how ps(1) obtains its memory info.\n    // https://github.com/apple-oss-distributions/adv_cmds/blob/8744084ea0ff41ca4bb96b0f9c22407d0e48e9b7/ps/tasks.c#L109\n\n    kern_return_t               error;\n    task_t                      task = MACH_PORT_NULL;\n    mach_task_basic_info_data_t info;\n    mach_msg_type_number_t      info_count = MACH_TASK_BASIC_INFO_COUNT;\n\n    error = task_info(\n                mach_task_self(),\n                MACH_TASK_BASIC_INFO,\n                (task_info_t) &info,\n                &info_count );\n\n    if( error != KERN_SUCCESS )\n    {\n        return error;\n    }\n\n    *rss   = info.resident_size;\n    *vsize = info.virtual_size;\n\n    {\n        vm_region_basic_info_data_64_t    b_info;\n        mach_vm_address_t                 address = GLOBAL_SHARED_TEXT_SEGMENT;\n        mach_vm_size_t                    size;\n        mach_port_t                       object_name;\n\n        /*\n         * try to determine if this task has the split libraries\n         * mapped in... if so, adjust its virtual size down by\n         * the 2 segments that are used for split libraries\n         */\n        info_count = VM_REGION_BASIC_INFO_COUNT_64;\n\n        error = mach_vm_region(\n                    mach_task_self(),\n                    &address,\n                    &size,\n                    VM_REGION_BASIC_INFO_64,\n                    (vm_region_info_t) &b_info,\n                    &info_count,\n                    &object_name);\n\n        if (error == KERN_SUCCESS) {\n            if (b_info.reserved && size == (SHARED_TEXT_REGION_SIZE) &&\n                *vsize > (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE)) {\n                    *vsize -= (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE);\n            }\n        }\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.go",
    "content": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build darwin && !ios && cgo\n\npackage prometheus\n\n/*\nint get_memory_info(unsigned long long *rss, unsigned long long *vs);\n*/\nimport \"C\"\nimport \"fmt\"\n\nfunc getMemory() (*memoryInfo, error) {\n\tvar rss, vsize C.ulonglong\n\n\tif err := C.get_memory_info(&rss, &vsize); err != 0 {\n\t\treturn nil, fmt.Errorf(\"task_info() failed with 0x%x\", int(err))\n\t}\n\n\treturn &memoryInfo{vsize: uint64(vsize), rss: uint64(rss)}, nil\n}\n\n// describe returns all descriptions of the collector for Darwin.\n// Ensure that this list of descriptors is kept in sync with the metrics collected\n// in the processCollect method. Any changes to the metrics in processCollect\n// (such as adding or removing metrics) should be reflected in this list of descriptors.\nfunc (c *processCollector) describe(ch chan<- *Desc) {\n\tch <- c.cpuTotal\n\tch <- c.openFDs\n\tch <- c.maxFDs\n\tch <- c.maxVsize\n\tch <- c.startTime\n\tch <- c.rss\n\tch <- c.vsize\n\n\t/* the process could be collected but not implemented yet\n\tch <- c.inBytes\n\tch <- c.outBytes\n\t*/\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_nocgo_darwin.go",
    "content": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build darwin && !ios && !cgo\n\npackage prometheus\n\nfunc getMemory() (*memoryInfo, error) {\n\treturn nil, notImplementedErr\n}\n\n// describe returns all descriptions of the collector for Darwin.\n// Ensure that this list of descriptors is kept in sync with the metrics collected\n// in the processCollect method. Any changes to the metrics in processCollect\n// (such as adding or removing metrics) should be reflected in this list of descriptors.\nfunc (c *processCollector) describe(ch chan<- *Desc) {\n\tch <- c.cpuTotal\n\tch <- c.openFDs\n\tch <- c.maxFDs\n\tch <- c.maxVsize\n\tch <- c.startTime\n\n\t/* the process could be collected but not implemented yet\n\tch <- c.rss\n\tch <- c.vsize\n\tch <- c.inBytes\n\tch <- c.outBytes\n\t*/\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/process_collector_not_supported.go",
    "content": "// Copyright 2023 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build wasip1 || js || ios\n// +build wasip1 js ios\n\npackage prometheus\n\nfunc canCollectProcess() bool {\n\treturn false\n}\n\nfunc (c *processCollector) processCollect(ch chan<- Metric) {\n\tc.errorCollectFn(ch)\n}\n\n// describe returns all descriptions of the collector for wasip1 and js.\n// Ensure that this list of descriptors is kept in sync with the metrics collected\n// in the processCollect method. Any changes to the metrics in processCollect\n// (such as adding or removing metrics) should be reflected in this list of descriptors.\nfunc (c *processCollector) describe(ch chan<- *Desc) {\n\tc.errorDescribeFn(ch)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/process_collector_procfsenabled.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build !windows && !js && !wasip1 && !darwin\n// +build !windows,!js,!wasip1,!darwin\n\npackage prometheus\n\nimport (\n\t\"github.com/prometheus/procfs\"\n)\n\nfunc canCollectProcess() bool {\n\t_, err := procfs.NewDefaultFS()\n\treturn err == nil\n}\n\nfunc (c *processCollector) processCollect(ch chan<- Metric) {\n\tpid, err := c.pidFn()\n\tif err != nil {\n\t\tc.reportError(ch, nil, err)\n\t\treturn\n\t}\n\n\tp, err := procfs.NewProc(pid)\n\tif err != nil {\n\t\tc.reportError(ch, nil, err)\n\t\treturn\n\t}\n\n\tif stat, err := p.Stat(); err == nil {\n\t\tch <- MustNewConstMetric(c.cpuTotal, CounterValue, stat.CPUTime())\n\t\tch <- MustNewConstMetric(c.vsize, GaugeValue, float64(stat.VirtualMemory()))\n\t\tch <- MustNewConstMetric(c.rss, GaugeValue, float64(stat.ResidentMemory()))\n\t\tif startTime, err := stat.StartTime(); err == nil {\n\t\t\tch <- MustNewConstMetric(c.startTime, GaugeValue, startTime)\n\t\t} else {\n\t\t\tc.reportError(ch, c.startTime, err)\n\t\t}\n\t} else {\n\t\tc.reportError(ch, nil, err)\n\t}\n\n\tif fds, err := p.FileDescriptorsLen(); err == nil {\n\t\tch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(fds))\n\t} else {\n\t\tc.reportError(ch, c.openFDs, err)\n\t}\n\n\tif limits, err := p.Limits(); err == nil {\n\t\tch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(limits.OpenFiles))\n\t\tch <- MustNewConstMetric(c.maxVsize, GaugeValue, float64(limits.AddressSpace))\n\t} else {\n\t\tc.reportError(ch, nil, err)\n\t}\n\n\tif netstat, err := p.Netstat(); err == nil {\n\t\tvar inOctets, outOctets float64\n\t\tif netstat.IpExt.InOctets != nil {\n\t\t\tinOctets = *netstat.IpExt.InOctets\n\t\t}\n\t\tif netstat.IpExt.OutOctets != nil {\n\t\t\toutOctets = *netstat.IpExt.OutOctets\n\t\t}\n\t\tch <- MustNewConstMetric(c.inBytes, CounterValue, inOctets)\n\t\tch <- MustNewConstMetric(c.outBytes, CounterValue, outOctets)\n\t} else {\n\t\tc.reportError(ch, nil, err)\n\t}\n}\n\n// describe returns all descriptions of the collector for others than windows, js, wasip1 and darwin.\n// Ensure that this list of descriptors is kept in sync with the metrics collected\n// in the processCollect method. Any changes to the metrics in processCollect\n// (such as adding or removing metrics) should be reflected in this list of descriptors.\nfunc (c *processCollector) describe(ch chan<- *Desc) {\n\tch <- c.cpuTotal\n\tch <- c.openFDs\n\tch <- c.maxFDs\n\tch <- c.vsize\n\tch <- c.maxVsize\n\tch <- c.rss\n\tch <- c.startTime\n\tch <- c.inBytes\n\tch <- c.outBytes\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\nfunc canCollectProcess() bool {\n\treturn true\n}\n\nvar (\n\tmodpsapi    = syscall.NewLazyDLL(\"psapi.dll\")\n\tmodkernel32 = syscall.NewLazyDLL(\"kernel32.dll\")\n\n\tprocGetProcessMemoryInfo  = modpsapi.NewProc(\"GetProcessMemoryInfo\")\n\tprocGetProcessHandleCount = modkernel32.NewProc(\"GetProcessHandleCount\")\n)\n\ntype processMemoryCounters struct {\n\t// System interface description\n\t// https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-process_memory_counters_ex\n\n\t// Refer to the Golang internal implementation\n\t// https://golang.org/src/internal/syscall/windows/psapi_windows.go\n\t_                          uint32\n\tPageFaultCount             uint32\n\tPeakWorkingSetSize         uintptr\n\tWorkingSetSize             uintptr\n\tQuotaPeakPagedPoolUsage    uintptr\n\tQuotaPagedPoolUsage        uintptr\n\tQuotaPeakNonPagedPoolUsage uintptr\n\tQuotaNonPagedPoolUsage     uintptr\n\tPagefileUsage              uintptr\n\tPeakPagefileUsage          uintptr\n\tPrivateUsage               uintptr\n}\n\nfunc getProcessMemoryInfo(handle windows.Handle) (processMemoryCounters, error) {\n\tmem := processMemoryCounters{}\n\tr1, _, err := procGetProcessMemoryInfo.Call(\n\t\tuintptr(handle),\n\t\tuintptr(unsafe.Pointer(&mem)),\n\t\tuintptr(unsafe.Sizeof(mem)),\n\t)\n\tif r1 != 1 {\n\t\treturn mem, err\n\t} else {\n\t\treturn mem, nil\n\t}\n}\n\nfunc getProcessHandleCount(handle windows.Handle) (uint32, error) {\n\tvar count uint32\n\tr1, _, err := procGetProcessHandleCount.Call(\n\t\tuintptr(handle),\n\t\tuintptr(unsafe.Pointer(&count)),\n\t)\n\tif r1 != 1 {\n\t\treturn 0, err\n\t} else {\n\t\treturn count, nil\n\t}\n}\n\nfunc (c *processCollector) processCollect(ch chan<- Metric) {\n\th := windows.CurrentProcess()\n\n\tvar startTime, exitTime, kernelTime, userTime windows.Filetime\n\terr := windows.GetProcessTimes(h, &startTime, &exitTime, &kernelTime, &userTime)\n\tif err != nil {\n\t\tc.reportError(ch, nil, err)\n\t\treturn\n\t}\n\tch <- MustNewConstMetric(c.startTime, GaugeValue, float64(startTime.Nanoseconds()/1e9))\n\tch <- MustNewConstMetric(c.cpuTotal, CounterValue, fileTimeToSeconds(kernelTime)+fileTimeToSeconds(userTime))\n\n\tmem, err := getProcessMemoryInfo(h)\n\tif err != nil {\n\t\tc.reportError(ch, nil, err)\n\t\treturn\n\t}\n\tch <- MustNewConstMetric(c.vsize, GaugeValue, float64(mem.PrivateUsage))\n\tch <- MustNewConstMetric(c.rss, GaugeValue, float64(mem.WorkingSetSize))\n\n\thandles, err := getProcessHandleCount(h)\n\tif err != nil {\n\t\tc.reportError(ch, nil, err)\n\t\treturn\n\t}\n\tch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(handles))\n\tch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(16*1024*1024)) // Windows has a hard-coded max limit, not per-process.\n}\n\n// describe returns all descriptions of the collector for windows.\n// Ensure that this list of descriptors is kept in sync with the metrics collected\n// in the processCollect method. Any changes to the metrics in processCollect\n// (such as adding or removing metrics) should be reflected in this list of descriptors.\nfunc (c *processCollector) describe(ch chan<- *Desc) {\n\tch <- c.cpuTotal\n\tch <- c.openFDs\n\tch <- c.maxFDs\n\tch <- c.vsize\n\tch <- c.rss\n\tch <- c.startTime\n}\n\nfunc fileTimeToSeconds(ft windows.Filetime) float64 {\n\treturn float64(uint64(ft.HighDateTime)<<32+uint64(ft.LowDateTime)) / 1e7\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/promauto/auto.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Package promauto provides alternative constructors for the fundamental\n// Prometheus metric types and their …Vec and …Func variants. The difference to\n// their counterparts in the prometheus package is that the promauto\n// constructors register the Collectors with a registry before returning them.\n// There are two sets of constructors. The constructors in the first set are\n// top-level functions, while the constructors in the other set are methods of\n// the Factory type. The top-level functions return Collectors registered with\n// the global registry (prometheus.DefaultRegisterer), while the methods return\n// Collectors registered with the registry the Factory was constructed with. All\n// constructors panic if the registration fails.\n//\n// The following example is a complete program to create a histogram of normally\n// distributed random numbers from the math/rand package:\n//\n//\tpackage main\n//\n//\timport (\n//\t\t\"math/rand\"\n//\t\t\"net/http\"\n//\n//\t\t\"github.com/prometheus/client_golang/prometheus\"\n//\t\t\"github.com/prometheus/client_golang/prometheus/promauto\"\n//\t\t\"github.com/prometheus/client_golang/prometheus/promhttp\"\n//\t)\n//\n//\tvar histogram = promauto.NewHistogram(prometheus.HistogramOpts{\n//\t\tName:    \"random_numbers\",\n//\t\tHelp:    \"A histogram of normally distributed random numbers.\",\n//\t\tBuckets: prometheus.LinearBuckets(-3, .1, 61),\n//\t})\n//\n//\tfunc Random() {\n//\t\tfor {\n//\t\t\thistogram.Observe(rand.NormFloat64())\n//\t\t}\n//\t}\n//\n//\tfunc main() {\n//\t\tgo Random()\n//\t\thttp.Handle(\"/metrics\", promhttp.Handler())\n//\t\thttp.ListenAndServe(\":1971\", nil)\n//\t}\n//\n// Prometheus's version of a minimal hello-world program:\n//\n//\tpackage main\n//\n//\timport (\n//\t\t\"fmt\"\n//\t\t\"net/http\"\n//\n//\t\t\"github.com/prometheus/client_golang/prometheus\"\n//\t\t\"github.com/prometheus/client_golang/prometheus/promauto\"\n//\t\t\"github.com/prometheus/client_golang/prometheus/promhttp\"\n//\t)\n//\n//\tfunc main() {\n//\t\thttp.Handle(\"/\", promhttp.InstrumentHandlerCounter(\n//\t\t\tpromauto.NewCounterVec(\n//\t\t\t\tprometheus.CounterOpts{\n//\t\t\t\t\tName: \"hello_requests_total\",\n//\t\t\t\t\tHelp: \"Total number of hello-world requests by HTTP code.\",\n//\t\t\t\t},\n//\t\t\t\t[]string{\"code\"},\n//\t\t\t),\n//\t\t\thttp.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n//\t\t\t\tfmt.Fprint(w, \"Hello, world!\")\n//\t\t\t}),\n//\t\t))\n//\t\thttp.Handle(\"/metrics\", promhttp.Handler())\n//\t\thttp.ListenAndServe(\":1971\", nil)\n//\t}\n//\n// A Factory is created with the With(prometheus.Registerer) function, which\n// enables two usage patterns. With(prometheus.Registerer) can be called once per\n// line:\n//\n//\tvar (\n//\t\treg           = prometheus.NewRegistry()\n//\t\trandomNumbers = promauto.With(reg).NewHistogram(prometheus.HistogramOpts{\n//\t\t\tName:    \"random_numbers\",\n//\t\t\tHelp:    \"A histogram of normally distributed random numbers.\",\n//\t\t\tBuckets: prometheus.LinearBuckets(-3, .1, 61),\n//\t\t})\n//\t\trequestCount = promauto.With(reg).NewCounterVec(\n//\t\t\tprometheus.CounterOpts{\n//\t\t\t\tName: \"http_requests_total\",\n//\t\t\t\tHelp: \"Total number of HTTP requests by status code and method.\",\n//\t\t\t},\n//\t\t\t[]string{\"code\", \"method\"},\n//\t\t)\n//\t)\n//\n// Or it can be used to create a Factory once to be used multiple times:\n//\n//\tvar (\n//\t\treg           = prometheus.NewRegistry()\n//\t\tfactory       = promauto.With(reg)\n//\t\trandomNumbers = factory.NewHistogram(prometheus.HistogramOpts{\n//\t\t\tName:    \"random_numbers\",\n//\t\t\tHelp:    \"A histogram of normally distributed random numbers.\",\n//\t\t\tBuckets: prometheus.LinearBuckets(-3, .1, 61),\n//\t\t})\n//\t\trequestCount = factory.NewCounterVec(\n//\t\t\tprometheus.CounterOpts{\n//\t\t\t\tName: \"http_requests_total\",\n//\t\t\t\tHelp: \"Total number of HTTP requests by status code and method.\",\n//\t\t\t},\n//\t\t\t[]string{\"code\", \"method\"},\n//\t\t)\n//\t)\n//\n// This appears very handy. So why are these constructors locked away in a\n// separate package?\n//\n// The main problem is that registration may fail, e.g. if a metric inconsistent\n// with or equal to the newly to be registered one is already registered.\n// Therefore, the Register method in the prometheus.Registerer interface returns\n// an error, and the same is the case for the top-level prometheus.Register\n// function that registers with the global registry. The prometheus package also\n// provides MustRegister versions for both. They panic if the registration\n// fails, and they clearly call this out by using the Must…  idiom. Panicking is\n// problematic in this case because it doesn't just happen on input provided by\n// the caller that is invalid on its own. Things are a bit more subtle here:\n// Metric creation and registration tend to be spread widely over the\n// codebase. It can easily happen that an incompatible metric is added to an\n// unrelated part of the code, and suddenly code that used to work perfectly\n// fine starts to panic (provided that the registration of the newly added\n// metric happens before the registration of the previously existing\n// metric). This may come as an even bigger surprise with the global registry,\n// where simply importing another package can trigger a panic (if the newly\n// imported package registers metrics in its init function). At least, in the\n// prometheus package, creation of metrics and other collectors is separate from\n// registration. You first create the metric, and then you decide explicitly if\n// you want to register it with a local or the global registry, and if you want\n// to handle the error or risk a panic. With the constructors in the promauto\n// package, registration is automatic, and if it fails, it will always\n// panic. Furthermore, the constructors will often be called in the var section\n// of a file, which means that panicking will happen as a side effect of merely\n// importing a package.\n//\n// A separate package allows conservative users to entirely ignore it. And\n// whoever wants to use it will do so explicitly, with an opportunity to read\n// this warning.\n//\n// Enjoy promauto responsibly!\npackage promauto\n\nimport \"github.com/prometheus/client_golang/prometheus\"\n\n// NewCounter works like the function of the same name in the prometheus package\n// but it automatically registers the Counter with the\n// prometheus.DefaultRegisterer. If the registration fails, NewCounter panics.\nfunc NewCounter(opts prometheus.CounterOpts) prometheus.Counter {\n\treturn With(prometheus.DefaultRegisterer).NewCounter(opts)\n}\n\n// NewCounterVec works like the function of the same name in the prometheus\n// package but it automatically registers the CounterVec with the\n// prometheus.DefaultRegisterer. If the registration fails, NewCounterVec\n// panics.\nfunc NewCounterVec(opts prometheus.CounterOpts, labelNames []string) *prometheus.CounterVec {\n\treturn With(prometheus.DefaultRegisterer).NewCounterVec(opts, labelNames)\n}\n\n// NewCounterFunc works like the function of the same name in the prometheus\n// package but it automatically registers the CounterFunc with the\n// prometheus.DefaultRegisterer. If the registration fails, NewCounterFunc\n// panics.\nfunc NewCounterFunc(opts prometheus.CounterOpts, function func() float64) prometheus.CounterFunc {\n\treturn With(prometheus.DefaultRegisterer).NewCounterFunc(opts, function)\n}\n\n// NewGauge works like the function of the same name in the prometheus package\n// but it automatically registers the Gauge with the\n// prometheus.DefaultRegisterer. If the registration fails, NewGauge panics.\nfunc NewGauge(opts prometheus.GaugeOpts) prometheus.Gauge {\n\treturn With(prometheus.DefaultRegisterer).NewGauge(opts)\n}\n\n// NewGaugeVec works like the function of the same name in the prometheus\n// package but it automatically registers the GaugeVec with the\n// prometheus.DefaultRegisterer. If the registration fails, NewGaugeVec panics.\nfunc NewGaugeVec(opts prometheus.GaugeOpts, labelNames []string) *prometheus.GaugeVec {\n\treturn With(prometheus.DefaultRegisterer).NewGaugeVec(opts, labelNames)\n}\n\n// NewGaugeFunc works like the function of the same name in the prometheus\n// package but it automatically registers the GaugeFunc with the\n// prometheus.DefaultRegisterer. If the registration fails, NewGaugeFunc panics.\nfunc NewGaugeFunc(opts prometheus.GaugeOpts, function func() float64) prometheus.GaugeFunc {\n\treturn With(prometheus.DefaultRegisterer).NewGaugeFunc(opts, function)\n}\n\n// NewSummary works like the function of the same name in the prometheus package\n// but it automatically registers the Summary with the\n// prometheus.DefaultRegisterer. If the registration fails, NewSummary panics.\nfunc NewSummary(opts prometheus.SummaryOpts) prometheus.Summary {\n\treturn With(prometheus.DefaultRegisterer).NewSummary(opts)\n}\n\n// NewSummaryVec works like the function of the same name in the prometheus\n// package but it automatically registers the SummaryVec with the\n// prometheus.DefaultRegisterer. If the registration fails, NewSummaryVec\n// panics.\nfunc NewSummaryVec(opts prometheus.SummaryOpts, labelNames []string) *prometheus.SummaryVec {\n\treturn With(prometheus.DefaultRegisterer).NewSummaryVec(opts, labelNames)\n}\n\n// NewHistogram works like the function of the same name in the prometheus\n// package but it automatically registers the Histogram with the\n// prometheus.DefaultRegisterer. If the registration fails, NewHistogram panics.\nfunc NewHistogram(opts prometheus.HistogramOpts) prometheus.Histogram {\n\treturn With(prometheus.DefaultRegisterer).NewHistogram(opts)\n}\n\n// NewHistogramVec works like the function of the same name in the prometheus\n// package but it automatically registers the HistogramVec with the\n// prometheus.DefaultRegisterer. If the registration fails, NewHistogramVec\n// panics.\nfunc NewHistogramVec(opts prometheus.HistogramOpts, labelNames []string) *prometheus.HistogramVec {\n\treturn With(prometheus.DefaultRegisterer).NewHistogramVec(opts, labelNames)\n}\n\n// NewUntypedFunc works like the function of the same name in the prometheus\n// package but it automatically registers the UntypedFunc with the\n// prometheus.DefaultRegisterer. If the registration fails, NewUntypedFunc\n// panics.\nfunc NewUntypedFunc(opts prometheus.UntypedOpts, function func() float64) prometheus.UntypedFunc {\n\treturn With(prometheus.DefaultRegisterer).NewUntypedFunc(opts, function)\n}\n\n// Factory provides factory methods to create Collectors that are automatically\n// registered with a Registerer. Create a Factory with the With function,\n// providing a Registerer to auto-register created Collectors with. The zero\n// value of a Factory creates Collectors that are not registered with any\n// Registerer. All methods of the Factory panic if the registration fails.\ntype Factory struct {\n\tr prometheus.Registerer\n}\n\n// With creates a Factory using the provided Registerer for registration of the\n// created Collectors. If the provided Registerer is nil, the returned Factory\n// creates Collectors that are not registered with any Registerer.\nfunc With(r prometheus.Registerer) Factory { return Factory{r} }\n\n// NewCounter works like the function of the same name in the prometheus package\n// but it automatically registers the Counter with the Factory's Registerer.\nfunc (f Factory) NewCounter(opts prometheus.CounterOpts) prometheus.Counter {\n\tc := prometheus.NewCounter(opts)\n\tif f.r != nil {\n\t\tf.r.MustRegister(c)\n\t}\n\treturn c\n}\n\n// NewCounterVec works like the function of the same name in the prometheus\n// package but it automatically registers the CounterVec with the Factory's\n// Registerer.\nfunc (f Factory) NewCounterVec(opts prometheus.CounterOpts, labelNames []string) *prometheus.CounterVec {\n\tc := prometheus.NewCounterVec(opts, labelNames)\n\tif f.r != nil {\n\t\tf.r.MustRegister(c)\n\t}\n\treturn c\n}\n\n// NewCounterFunc works like the function of the same name in the prometheus\n// package but it automatically registers the CounterFunc with the Factory's\n// Registerer.\nfunc (f Factory) NewCounterFunc(opts prometheus.CounterOpts, function func() float64) prometheus.CounterFunc {\n\tc := prometheus.NewCounterFunc(opts, function)\n\tif f.r != nil {\n\t\tf.r.MustRegister(c)\n\t}\n\treturn c\n}\n\n// NewGauge works like the function of the same name in the prometheus package\n// but it automatically registers the Gauge with the Factory's Registerer.\nfunc (f Factory) NewGauge(opts prometheus.GaugeOpts) prometheus.Gauge {\n\tg := prometheus.NewGauge(opts)\n\tif f.r != nil {\n\t\tf.r.MustRegister(g)\n\t}\n\treturn g\n}\n\n// NewGaugeVec works like the function of the same name in the prometheus\n// package but it automatically registers the GaugeVec with the Factory's\n// Registerer.\nfunc (f Factory) NewGaugeVec(opts prometheus.GaugeOpts, labelNames []string) *prometheus.GaugeVec {\n\tg := prometheus.NewGaugeVec(opts, labelNames)\n\tif f.r != nil {\n\t\tf.r.MustRegister(g)\n\t}\n\treturn g\n}\n\n// NewGaugeFunc works like the function of the same name in the prometheus\n// package but it automatically registers the GaugeFunc with the Factory's\n// Registerer.\nfunc (f Factory) NewGaugeFunc(opts prometheus.GaugeOpts, function func() float64) prometheus.GaugeFunc {\n\tg := prometheus.NewGaugeFunc(opts, function)\n\tif f.r != nil {\n\t\tf.r.MustRegister(g)\n\t}\n\treturn g\n}\n\n// NewSummary works like the function of the same name in the prometheus package\n// but it automatically registers the Summary with the Factory's Registerer.\nfunc (f Factory) NewSummary(opts prometheus.SummaryOpts) prometheus.Summary {\n\ts := prometheus.NewSummary(opts)\n\tif f.r != nil {\n\t\tf.r.MustRegister(s)\n\t}\n\treturn s\n}\n\n// NewSummaryVec works like the function of the same name in the prometheus\n// package but it automatically registers the SummaryVec with the Factory's\n// Registerer.\nfunc (f Factory) NewSummaryVec(opts prometheus.SummaryOpts, labelNames []string) *prometheus.SummaryVec {\n\ts := prometheus.NewSummaryVec(opts, labelNames)\n\tif f.r != nil {\n\t\tf.r.MustRegister(s)\n\t}\n\treturn s\n}\n\n// NewHistogram works like the function of the same name in the prometheus\n// package but it automatically registers the Histogram with the Factory's\n// Registerer.\nfunc (f Factory) NewHistogram(opts prometheus.HistogramOpts) prometheus.Histogram {\n\th := prometheus.NewHistogram(opts)\n\tif f.r != nil {\n\t\tf.r.MustRegister(h)\n\t}\n\treturn h\n}\n\n// NewHistogramVec works like the function of the same name in the prometheus\n// package but it automatically registers the HistogramVec with the Factory's\n// Registerer.\nfunc (f Factory) NewHistogramVec(opts prometheus.HistogramOpts, labelNames []string) *prometheus.HistogramVec {\n\th := prometheus.NewHistogramVec(opts, labelNames)\n\tif f.r != nil {\n\t\tf.r.MustRegister(h)\n\t}\n\treturn h\n}\n\n// NewUntypedFunc works like the function of the same name in the prometheus\n// package but it automatically registers the UntypedFunc with the Factory's\n// Registerer.\nfunc (f Factory) NewUntypedFunc(opts prometheus.UntypedOpts, function func() float64) prometheus.UntypedFunc {\n\tu := prometheus.NewUntypedFunc(opts, function)\n\tif f.r != nil {\n\t\tf.r.MustRegister(u)\n\t}\n\treturn u\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go",
    "content": "// Copyright 2017 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage promhttp\n\nimport (\n\t\"bufio\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n)\n\nconst (\n\tcloseNotifier = 1 << iota\n\tflusher\n\thijacker\n\treaderFrom\n\tpusher\n)\n\ntype delegator interface {\n\thttp.ResponseWriter\n\n\tStatus() int\n\tWritten() int64\n}\n\ntype responseWriterDelegator struct {\n\thttp.ResponseWriter\n\n\tstatus             int\n\twritten            int64\n\twroteHeader        bool\n\tobserveWriteHeader func(int)\n}\n\nfunc (r *responseWriterDelegator) Status() int {\n\treturn r.status\n}\n\nfunc (r *responseWriterDelegator) Written() int64 {\n\treturn r.written\n}\n\nfunc (r *responseWriterDelegator) WriteHeader(code int) {\n\tif r.observeWriteHeader != nil && !r.wroteHeader {\n\t\t// Only call observeWriteHeader for the 1st time. It's a bug if\n\t\t// WriteHeader is called more than once, but we want to protect\n\t\t// against it here. Note that we still delegate the WriteHeader\n\t\t// to the original ResponseWriter to not mask the bug from it.\n\t\tr.observeWriteHeader(code)\n\t}\n\tr.status = code\n\tr.wroteHeader = true\n\tr.ResponseWriter.WriteHeader(code)\n}\n\nfunc (r *responseWriterDelegator) Write(b []byte) (int, error) {\n\t// If applicable, call WriteHeader here so that observeWriteHeader is\n\t// handled appropriately.\n\tif !r.wroteHeader {\n\t\tr.WriteHeader(http.StatusOK)\n\t}\n\tn, err := r.ResponseWriter.Write(b)\n\tr.written += int64(n)\n\treturn n, err\n}\n\n// Unwrap lets http.ResponseController get the underlying http.ResponseWriter,\n// by implementing the [rwUnwrapper](https://cs.opensource.google/go/go/+/refs/tags/go1.21.4:src/net/http/responsecontroller.go;l=42-44) interface.\nfunc (r *responseWriterDelegator) Unwrap() http.ResponseWriter {\n\treturn r.ResponseWriter\n}\n\ntype (\n\tcloseNotifierDelegator struct{ *responseWriterDelegator }\n\tflusherDelegator       struct{ *responseWriterDelegator }\n\thijackerDelegator      struct{ *responseWriterDelegator }\n\treaderFromDelegator    struct{ *responseWriterDelegator }\n\tpusherDelegator        struct{ *responseWriterDelegator }\n)\n\nfunc (d closeNotifierDelegator) CloseNotify() <-chan bool {\n\t//nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users.\n\treturn d.ResponseWriter.(http.CloseNotifier).CloseNotify()\n}\n\nfunc (d flusherDelegator) Flush() {\n\t// If applicable, call WriteHeader here so that observeWriteHeader is\n\t// handled appropriately.\n\tif !d.wroteHeader {\n\t\td.WriteHeader(http.StatusOK)\n\t}\n\td.ResponseWriter.(http.Flusher).Flush()\n}\n\nfunc (d hijackerDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) {\n\treturn d.ResponseWriter.(http.Hijacker).Hijack()\n}\n\nfunc (d readerFromDelegator) ReadFrom(re io.Reader) (int64, error) {\n\t// If applicable, call WriteHeader here so that observeWriteHeader is\n\t// handled appropriately.\n\tif !d.wroteHeader {\n\t\td.WriteHeader(http.StatusOK)\n\t}\n\tn, err := d.ResponseWriter.(io.ReaderFrom).ReadFrom(re)\n\td.written += n\n\treturn n, err\n}\n\nfunc (d pusherDelegator) Push(target string, opts *http.PushOptions) error {\n\treturn d.ResponseWriter.(http.Pusher).Push(target, opts)\n}\n\nvar pickDelegator = make([]func(*responseWriterDelegator) delegator, 32)\n\nfunc init() {\n\t// TODO(beorn7): Code generation would help here.\n\tpickDelegator[0] = func(d *responseWriterDelegator) delegator { // 0\n\t\treturn d\n\t}\n\tpickDelegator[closeNotifier] = func(d *responseWriterDelegator) delegator { // 1\n\t\treturn closeNotifierDelegator{d}\n\t}\n\tpickDelegator[flusher] = func(d *responseWriterDelegator) delegator { // 2\n\t\treturn flusherDelegator{d}\n\t}\n\tpickDelegator[flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 3\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t}{d, flusherDelegator{d}, closeNotifierDelegator{d}}\n\t}\n\tpickDelegator[hijacker] = func(d *responseWriterDelegator) delegator { // 4\n\t\treturn hijackerDelegator{d}\n\t}\n\tpickDelegator[hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 5\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Hijacker\n\t\t\thttp.CloseNotifier\n\t\t}{d, hijackerDelegator{d}, closeNotifierDelegator{d}}\n\t}\n\tpickDelegator[hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 6\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Hijacker\n\t\t\thttp.Flusher\n\t\t}{d, hijackerDelegator{d}, flusherDelegator{d}}\n\t}\n\tpickDelegator[hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 7\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Hijacker\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t}{d, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}\n\t}\n\tpickDelegator[readerFrom] = func(d *responseWriterDelegator) delegator { // 8\n\t\treturn readerFromDelegator{d}\n\t}\n\tpickDelegator[readerFrom+closeNotifier] = func(d *responseWriterDelegator) delegator { // 9\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\tio.ReaderFrom\n\t\t\thttp.CloseNotifier\n\t\t}{d, readerFromDelegator{d}, closeNotifierDelegator{d}}\n\t}\n\tpickDelegator[readerFrom+flusher] = func(d *responseWriterDelegator) delegator { // 10\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\tio.ReaderFrom\n\t\t\thttp.Flusher\n\t\t}{d, readerFromDelegator{d}, flusherDelegator{d}}\n\t}\n\tpickDelegator[readerFrom+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 11\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\tio.ReaderFrom\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t}{d, readerFromDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}\n\t}\n\tpickDelegator[readerFrom+hijacker] = func(d *responseWriterDelegator) delegator { // 12\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\tio.ReaderFrom\n\t\t\thttp.Hijacker\n\t\t}{d, readerFromDelegator{d}, hijackerDelegator{d}}\n\t}\n\tpickDelegator[readerFrom+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 13\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\tio.ReaderFrom\n\t\t\thttp.Hijacker\n\t\t\thttp.CloseNotifier\n\t\t}{d, readerFromDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}}\n\t}\n\tpickDelegator[readerFrom+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 14\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\tio.ReaderFrom\n\t\t\thttp.Hijacker\n\t\t\thttp.Flusher\n\t\t}{d, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}}\n\t}\n\tpickDelegator[readerFrom+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 15\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\tio.ReaderFrom\n\t\t\thttp.Hijacker\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t}{d, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}\n\t}\n\tpickDelegator[pusher] = func(d *responseWriterDelegator) delegator { // 16\n\t\treturn pusherDelegator{d}\n\t}\n\tpickDelegator[pusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 17\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Pusher\n\t\t\thttp.CloseNotifier\n\t\t}{d, pusherDelegator{d}, closeNotifierDelegator{d}}\n\t}\n\tpickDelegator[pusher+flusher] = func(d *responseWriterDelegator) delegator { // 18\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Pusher\n\t\t\thttp.Flusher\n\t\t}{d, pusherDelegator{d}, flusherDelegator{d}}\n\t}\n\tpickDelegator[pusher+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 19\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Pusher\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t}{d, pusherDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}\n\t}\n\tpickDelegator[pusher+hijacker] = func(d *responseWriterDelegator) delegator { // 20\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Pusher\n\t\t\thttp.Hijacker\n\t\t}{d, pusherDelegator{d}, hijackerDelegator{d}}\n\t}\n\tpickDelegator[pusher+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 21\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Pusher\n\t\t\thttp.Hijacker\n\t\t\thttp.CloseNotifier\n\t\t}{d, pusherDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}}\n\t}\n\tpickDelegator[pusher+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 22\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Pusher\n\t\t\thttp.Hijacker\n\t\t\thttp.Flusher\n\t\t}{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}}\n\t}\n\tpickDelegator[pusher+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 23\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Pusher\n\t\t\thttp.Hijacker\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t}{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}\n\t}\n\tpickDelegator[pusher+readerFrom] = func(d *responseWriterDelegator) delegator { // 24\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Pusher\n\t\t\tio.ReaderFrom\n\t\t}{d, pusherDelegator{d}, readerFromDelegator{d}}\n\t}\n\tpickDelegator[pusher+readerFrom+closeNotifier] = func(d *responseWriterDelegator) delegator { // 25\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Pusher\n\t\t\tio.ReaderFrom\n\t\t\thttp.CloseNotifier\n\t\t}{d, pusherDelegator{d}, readerFromDelegator{d}, closeNotifierDelegator{d}}\n\t}\n\tpickDelegator[pusher+readerFrom+flusher] = func(d *responseWriterDelegator) delegator { // 26\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Pusher\n\t\t\tio.ReaderFrom\n\t\t\thttp.Flusher\n\t\t}{d, pusherDelegator{d}, readerFromDelegator{d}, flusherDelegator{d}}\n\t}\n\tpickDelegator[pusher+readerFrom+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 27\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Pusher\n\t\t\tio.ReaderFrom\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t}{d, pusherDelegator{d}, readerFromDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}\n\t}\n\tpickDelegator[pusher+readerFrom+hijacker] = func(d *responseWriterDelegator) delegator { // 28\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Pusher\n\t\t\tio.ReaderFrom\n\t\t\thttp.Hijacker\n\t\t}{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}}\n\t}\n\tpickDelegator[pusher+readerFrom+hijacker+closeNotifier] = func(d *responseWriterDelegator) delegator { // 29\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Pusher\n\t\t\tio.ReaderFrom\n\t\t\thttp.Hijacker\n\t\t\thttp.CloseNotifier\n\t\t}{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, closeNotifierDelegator{d}}\n\t}\n\tpickDelegator[pusher+readerFrom+hijacker+flusher] = func(d *responseWriterDelegator) delegator { // 30\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Pusher\n\t\t\tio.ReaderFrom\n\t\t\thttp.Hijacker\n\t\t\thttp.Flusher\n\t\t}{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}}\n\t}\n\tpickDelegator[pusher+readerFrom+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 31\n\t\treturn struct {\n\t\t\t*responseWriterDelegator\n\t\t\thttp.Pusher\n\t\t\tio.ReaderFrom\n\t\t\thttp.Hijacker\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t}{d, pusherDelegator{d}, readerFromDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}, closeNotifierDelegator{d}}\n\t}\n}\n\nfunc newDelegator(w http.ResponseWriter, observeWriteHeaderFunc func(int)) delegator {\n\td := &responseWriterDelegator{\n\t\tResponseWriter:     w,\n\t\tobserveWriteHeader: observeWriteHeaderFunc,\n\t}\n\n\tid := 0\n\t//nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users.\n\tif _, ok := w.(http.CloseNotifier); ok {\n\t\tid += closeNotifier\n\t}\n\tif _, ok := w.(http.Flusher); ok {\n\t\tid += flusher\n\t}\n\tif _, ok := w.(http.Hijacker); ok {\n\t\tid += hijacker\n\t}\n\tif _, ok := w.(io.ReaderFrom); ok {\n\t\tid += readerFrom\n\t}\n\tif _, ok := w.(http.Pusher); ok {\n\t\tid += pusher\n\t}\n\n\treturn pickDelegator[id](d)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go",
    "content": "// Copyright 2016 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Package promhttp provides tooling around HTTP servers and clients.\n//\n// First, the package allows the creation of http.Handler instances to expose\n// Prometheus metrics via HTTP. promhttp.Handler acts on the\n// prometheus.DefaultGatherer. With HandlerFor, you can create a handler for a\n// custom registry or anything that implements the Gatherer interface. It also\n// allows the creation of handlers that act differently on errors or allow to\n// log errors.\n//\n// Second, the package provides tooling to instrument instances of http.Handler\n// via middleware. Middleware wrappers follow the naming scheme\n// InstrumentHandlerX, where X describes the intended use of the middleware.\n// See each function's doc comment for specific details.\n//\n// Finally, the package allows for an http.RoundTripper to be instrumented via\n// middleware. Middleware wrappers follow the naming scheme\n// InstrumentRoundTripperX, where X describes the intended use of the\n// middleware. See each function's doc comment for specific details.\npackage promhttp\n\nimport (\n\t\"compress/gzip\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/prometheus/common/expfmt\"\n\n\t\"github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil\"\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"github.com/prometheus/client_golang/prometheus/promhttp/internal\"\n)\n\nconst (\n\tcontentTypeHeader      = \"Content-Type\"\n\tcontentEncodingHeader  = \"Content-Encoding\"\n\tacceptEncodingHeader   = \"Accept-Encoding\"\n\tprocessStartTimeHeader = \"Process-Start-Time-Unix\"\n)\n\n// Compression represents the content encodings handlers support for the HTTP\n// responses.\ntype Compression string\n\nconst (\n\tIdentity Compression = \"identity\"\n\tGzip     Compression = \"gzip\"\n\tZstd     Compression = \"zstd\"\n)\n\nfunc defaultCompressionFormats() []Compression {\n\tif internal.NewZstdWriter != nil {\n\t\treturn []Compression{Identity, Gzip, Zstd}\n\t} else {\n\t\treturn []Compression{Identity, Gzip}\n\t}\n}\n\nvar gzipPool = sync.Pool{\n\tNew: func() interface{} {\n\t\treturn gzip.NewWriter(nil)\n\t},\n}\n\n// Handler returns an http.Handler for the prometheus.DefaultGatherer, using\n// default HandlerOpts, i.e. it reports the first error as an HTTP error, it has\n// no error logging, and it applies compression if requested by the client.\n//\n// The returned http.Handler is already instrumented using the\n// InstrumentMetricHandler function and the prometheus.DefaultRegisterer. If you\n// create multiple http.Handlers by separate calls of the Handler function, the\n// metrics used for instrumentation will be shared between them, providing\n// global scrape counts.\n//\n// This function is meant to cover the bulk of basic use cases. If you are doing\n// anything that requires more customization (including using a non-default\n// Gatherer, different instrumentation, and non-default HandlerOpts), use the\n// HandlerFor function. See there for details.\nfunc Handler() http.Handler {\n\treturn InstrumentMetricHandler(\n\t\tprometheus.DefaultRegisterer, HandlerFor(prometheus.DefaultGatherer, HandlerOpts{}),\n\t)\n}\n\n// HandlerFor returns an uninstrumented http.Handler for the provided\n// Gatherer. The behavior of the Handler is defined by the provided\n// HandlerOpts. Thus, HandlerFor is useful to create http.Handlers for custom\n// Gatherers, with non-default HandlerOpts, and/or with custom (or no)\n// instrumentation. Use the InstrumentMetricHandler function to apply the same\n// kind of instrumentation as it is used by the Handler function.\nfunc HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {\n\treturn HandlerForTransactional(prometheus.ToTransactionalGatherer(reg), opts)\n}\n\n// HandlerForTransactional is like HandlerFor, but it uses transactional gather, which\n// can safely change in-place returned *dto.MetricFamily before call to `Gather` and after\n// call to `done` of that `Gather`.\nfunc HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerOpts) http.Handler {\n\tvar (\n\t\tinFlightSem chan struct{}\n\t\terrCnt      = prometheus.NewCounterVec(\n\t\t\tprometheus.CounterOpts{\n\t\t\t\tName: \"promhttp_metric_handler_errors_total\",\n\t\t\t\tHelp: \"Total number of internal errors encountered by the promhttp metric handler.\",\n\t\t\t},\n\t\t\t[]string{\"cause\"},\n\t\t)\n\t)\n\n\tif opts.MaxRequestsInFlight > 0 {\n\t\tinFlightSem = make(chan struct{}, opts.MaxRequestsInFlight)\n\t}\n\tif opts.Registry != nil {\n\t\t// Initialize all possibilities that can occur below.\n\t\terrCnt.WithLabelValues(\"gathering\")\n\t\terrCnt.WithLabelValues(\"encoding\")\n\t\tif err := opts.Registry.Register(errCnt); err != nil {\n\t\t\tare := &prometheus.AlreadyRegisteredError{}\n\t\t\tif errors.As(err, are) {\n\t\t\t\terrCnt = are.ExistingCollector.(*prometheus.CounterVec)\n\t\t\t} else {\n\t\t\t\tpanic(err)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Select compression formats to offer based on default or user choice.\n\tvar compressions []string\n\tif !opts.DisableCompression {\n\t\toffers := defaultCompressionFormats()\n\t\tif len(opts.OfferedCompressions) > 0 {\n\t\t\toffers = opts.OfferedCompressions\n\t\t}\n\t\tfor _, comp := range offers {\n\t\t\tcompressions = append(compressions, string(comp))\n\t\t}\n\t}\n\n\th := http.HandlerFunc(func(rsp http.ResponseWriter, req *http.Request) {\n\t\tif !opts.ProcessStartTime.IsZero() {\n\t\t\trsp.Header().Set(processStartTimeHeader, strconv.FormatInt(opts.ProcessStartTime.Unix(), 10))\n\t\t}\n\t\tif inFlightSem != nil {\n\t\t\tselect {\n\t\t\tcase inFlightSem <- struct{}{}: // All good, carry on.\n\t\t\t\tdefer func() { <-inFlightSem }()\n\t\t\tdefault:\n\t\t\t\thttp.Error(rsp, fmt.Sprintf(\n\t\t\t\t\t\"Limit of concurrent requests reached (%d), try again later.\", opts.MaxRequestsInFlight,\n\t\t\t\t), http.StatusServiceUnavailable)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tmfs, done, err := reg.Gather()\n\t\tdefer done()\n\t\tif err != nil {\n\t\t\tif opts.ErrorLog != nil {\n\t\t\t\topts.ErrorLog.Println(\"error gathering metrics:\", err)\n\t\t\t}\n\t\t\terrCnt.WithLabelValues(\"gathering\").Inc()\n\t\t\tswitch opts.ErrorHandling {\n\t\t\tcase PanicOnError:\n\t\t\t\tpanic(err)\n\t\t\tcase ContinueOnError:\n\t\t\t\tif len(mfs) == 0 {\n\t\t\t\t\t// Still report the error if no metrics have been gathered.\n\t\t\t\t\thttpError(rsp, err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\tcase HTTPErrorOnError:\n\t\t\t\thttpError(rsp, err)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tvar contentType expfmt.Format\n\t\tif opts.EnableOpenMetrics {\n\t\t\tcontentType = expfmt.NegotiateIncludingOpenMetrics(req.Header)\n\t\t} else {\n\t\t\tcontentType = expfmt.Negotiate(req.Header)\n\t\t}\n\t\trsp.Header().Set(contentTypeHeader, string(contentType))\n\n\t\tw, encodingHeader, closeWriter, err := negotiateEncodingWriter(req, rsp, compressions)\n\t\tif err != nil {\n\t\t\tif opts.ErrorLog != nil {\n\t\t\t\topts.ErrorLog.Println(\"error getting writer\", err)\n\t\t\t}\n\t\t\tw = io.Writer(rsp)\n\t\t\tencodingHeader = string(Identity)\n\t\t}\n\n\t\tdefer closeWriter()\n\n\t\t// Set Content-Encoding only when data is compressed\n\t\tif encodingHeader != string(Identity) {\n\t\t\trsp.Header().Set(contentEncodingHeader, encodingHeader)\n\t\t}\n\n\t\tvar enc expfmt.Encoder\n\t\tif opts.EnableOpenMetricsTextCreatedSamples {\n\t\t\tenc = expfmt.NewEncoder(w, contentType, expfmt.WithCreatedLines())\n\t\t} else {\n\t\t\tenc = expfmt.NewEncoder(w, contentType)\n\t\t}\n\n\t\t// handleError handles the error according to opts.ErrorHandling\n\t\t// and returns true if we have to abort after the handling.\n\t\thandleError := func(err error) bool {\n\t\t\tif err == nil {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif opts.ErrorLog != nil {\n\t\t\t\topts.ErrorLog.Println(\"error encoding and sending metric family:\", err)\n\t\t\t}\n\t\t\terrCnt.WithLabelValues(\"encoding\").Inc()\n\t\t\tswitch opts.ErrorHandling {\n\t\t\tcase PanicOnError:\n\t\t\t\tpanic(err)\n\t\t\tcase HTTPErrorOnError:\n\t\t\t\t// We cannot really send an HTTP error at this\n\t\t\t\t// point because we most likely have written\n\t\t\t\t// something to rsp already. But at least we can\n\t\t\t\t// stop sending.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\t// Do nothing in all other cases, including ContinueOnError.\n\t\t\treturn false\n\t\t}\n\n\t\tfor _, mf := range mfs {\n\t\t\tif handleError(enc.Encode(mf)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tif closer, ok := enc.(expfmt.Closer); ok {\n\t\t\t// This in particular takes care of the final \"# EOF\\n\" line for OpenMetrics.\n\t\t\tif handleError(closer.Close()) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t})\n\n\tif opts.Timeout <= 0 {\n\t\treturn h\n\t}\n\treturn http.TimeoutHandler(h, opts.Timeout, fmt.Sprintf(\n\t\t\"Exceeded configured timeout of %v.\\n\",\n\t\topts.Timeout,\n\t))\n}\n\n// InstrumentMetricHandler is usually used with an http.Handler returned by the\n// HandlerFor function. It instruments the provided http.Handler with two\n// metrics: A counter vector \"promhttp_metric_handler_requests_total\" to count\n// scrapes partitioned by HTTP status code, and a gauge\n// \"promhttp_metric_handler_requests_in_flight\" to track the number of\n// simultaneous scrapes. This function idempotently registers collectors for\n// both metrics with the provided Registerer. It panics if the registration\n// fails. The provided metrics are useful to see how many scrapes hit the\n// monitored target (which could be from different Prometheus servers or other\n// scrapers), and how often they overlap (which would result in more than one\n// scrape in flight at the same time). Note that the scrapes-in-flight gauge\n// will contain the scrape by which it is exposed, while the scrape counter will\n// only get incremented after the scrape is complete (as only then the status\n// code is known). For tracking scrape durations, use the\n// \"scrape_duration_seconds\" gauge created by the Prometheus server upon each\n// scrape.\nfunc InstrumentMetricHandler(reg prometheus.Registerer, handler http.Handler) http.Handler {\n\tcnt := prometheus.NewCounterVec(\n\t\tprometheus.CounterOpts{\n\t\t\tName: \"promhttp_metric_handler_requests_total\",\n\t\t\tHelp: \"Total number of scrapes by HTTP status code.\",\n\t\t},\n\t\t[]string{\"code\"},\n\t)\n\t// Initialize the most likely HTTP status codes.\n\tcnt.WithLabelValues(\"200\")\n\tcnt.WithLabelValues(\"500\")\n\tcnt.WithLabelValues(\"503\")\n\tif err := reg.Register(cnt); err != nil {\n\t\tare := &prometheus.AlreadyRegisteredError{}\n\t\tif errors.As(err, are) {\n\t\t\tcnt = are.ExistingCollector.(*prometheus.CounterVec)\n\t\t} else {\n\t\t\tpanic(err)\n\t\t}\n\t}\n\n\tgge := prometheus.NewGauge(prometheus.GaugeOpts{\n\t\tName: \"promhttp_metric_handler_requests_in_flight\",\n\t\tHelp: \"Current number of scrapes being served.\",\n\t})\n\tif err := reg.Register(gge); err != nil {\n\t\tare := &prometheus.AlreadyRegisteredError{}\n\t\tif errors.As(err, are) {\n\t\t\tgge = are.ExistingCollector.(prometheus.Gauge)\n\t\t} else {\n\t\t\tpanic(err)\n\t\t}\n\t}\n\n\treturn InstrumentHandlerCounter(cnt, InstrumentHandlerInFlight(gge, handler))\n}\n\n// HandlerErrorHandling defines how a Handler serving metrics will handle\n// errors.\ntype HandlerErrorHandling int\n\n// These constants cause handlers serving metrics to behave as described if\n// errors are encountered.\nconst (\n\t// Serve an HTTP status code 500 upon the first error\n\t// encountered. Report the error message in the body. Note that HTTP\n\t// errors cannot be served anymore once the beginning of a regular\n\t// payload has been sent. Thus, in the (unlikely) case that encoding the\n\t// payload into the negotiated wire format fails, serving the response\n\t// will simply be aborted. Set an ErrorLog in HandlerOpts to detect\n\t// those errors.\n\tHTTPErrorOnError HandlerErrorHandling = iota\n\t// Ignore errors and try to serve as many metrics as possible.  However,\n\t// if no metrics can be served, serve an HTTP status code 500 and the\n\t// last error message in the body. Only use this in deliberate \"best\n\t// effort\" metrics collection scenarios. In this case, it is highly\n\t// recommended to provide other means of detecting errors: By setting an\n\t// ErrorLog in HandlerOpts, the errors are logged. By providing a\n\t// Registry in HandlerOpts, the exposed metrics include an error counter\n\t// \"promhttp_metric_handler_errors_total\", which can be used for\n\t// alerts.\n\tContinueOnError\n\t// Panic upon the first error encountered (useful for \"crash only\" apps).\n\tPanicOnError\n)\n\n// Logger is the minimal interface HandlerOpts needs for logging. Note that\n// log.Logger from the standard library implements this interface, and it is\n// easy to implement by custom loggers, if they don't do so already anyway.\ntype Logger interface {\n\tPrintln(v ...interface{})\n}\n\n// HandlerOpts specifies options how to serve metrics via an http.Handler. The\n// zero value of HandlerOpts is a reasonable default.\ntype HandlerOpts struct {\n\t// ErrorLog specifies an optional Logger for errors collecting and\n\t// serving metrics. If nil, errors are not logged at all. Note that the\n\t// type of a reported error is often prometheus.MultiError, which\n\t// formats into a multi-line error string. If you want to avoid the\n\t// latter, create a Logger implementation that detects a\n\t// prometheus.MultiError and formats the contained errors into one line.\n\tErrorLog Logger\n\t// ErrorHandling defines how errors are handled. Note that errors are\n\t// logged regardless of the configured ErrorHandling provided ErrorLog\n\t// is not nil.\n\tErrorHandling HandlerErrorHandling\n\t// If Registry is not nil, it is used to register a metric\n\t// \"promhttp_metric_handler_errors_total\", partitioned by \"cause\". A\n\t// failed registration causes a panic. Note that this error counter is\n\t// different from the instrumentation you get from the various\n\t// InstrumentHandler... helpers. It counts errors that don't necessarily\n\t// result in a non-2xx HTTP status code. There are two typical cases:\n\t// (1) Encoding errors that only happen after streaming of the HTTP body\n\t// has already started (and the status code 200 has been sent). This\n\t// should only happen with custom collectors. (2) Collection errors with\n\t// no effect on the HTTP status code because ErrorHandling is set to\n\t// ContinueOnError.\n\tRegistry prometheus.Registerer\n\t// DisableCompression disables the response encoding (compression) and\n\t// encoding negotiation. If true, the handler will\n\t// never compress the response, even if requested\n\t// by the client and the OfferedCompressions field is set.\n\tDisableCompression bool\n\t// OfferedCompressions is a set of encodings (compressions) handler will\n\t// try to offer when negotiating with the client. This defaults to identity, gzip\n\t// and zstd.\n\t// NOTE: If handler can't agree with the client on the encodings or\n\t// unsupported or empty encodings are set in OfferedCompressions,\n\t// handler always fallbacks to no compression (identity), for\n\t// compatibility reasons. In such cases ErrorLog will be used if set.\n\tOfferedCompressions []Compression\n\t// The number of concurrent HTTP requests is limited to\n\t// MaxRequestsInFlight. Additional requests are responded to with 503\n\t// Service Unavailable and a suitable message in the body. If\n\t// MaxRequestsInFlight is 0 or negative, no limit is applied.\n\tMaxRequestsInFlight int\n\t// If handling a request takes longer than Timeout, it is responded to\n\t// with 503 ServiceUnavailable and a suitable Message. No timeout is\n\t// applied if Timeout is 0 or negative. Note that with the current\n\t// implementation, reaching the timeout simply ends the HTTP requests as\n\t// described above (and even that only if sending of the body hasn't\n\t// started yet), while the bulk work of gathering all the metrics keeps\n\t// running in the background (with the eventual result to be thrown\n\t// away). Until the implementation is improved, it is recommended to\n\t// implement a separate timeout in potentially slow Collectors.\n\tTimeout time.Duration\n\t// If true, the experimental OpenMetrics encoding is added to the\n\t// possible options during content negotiation. Note that Prometheus\n\t// 2.5.0+ will negotiate OpenMetrics as first priority. OpenMetrics is\n\t// the only way to transmit exemplars. However, the move to OpenMetrics\n\t// is not completely transparent. Most notably, the values of \"quantile\"\n\t// labels of Summaries and \"le\" labels of Histograms are formatted with\n\t// a trailing \".0\" if they would otherwise look like integer numbers\n\t// (which changes the identity of the resulting series on the Prometheus\n\t// server).\n\tEnableOpenMetrics bool\n\t// EnableOpenMetricsTextCreatedSamples specifies if this handler should add, extra, synthetic\n\t// Created Timestamps for counters, histograms and summaries, which for the current\n\t// version of OpenMetrics are defined as extra series with the same name and \"_created\"\n\t// suffix. See also the OpenMetrics specification for more details\n\t// https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#counter-1\n\t//\n\t// Created timestamps are used to improve the accuracy of reset detection,\n\t// but the way it's designed in OpenMetrics 1.0 it also dramatically increases cardinality\n\t// if the scraper does not handle those metrics correctly (converting to created timestamp\n\t// instead of leaving those series as-is). New OpenMetrics versions might improve\n\t// this situation.\n\t//\n\t// Prometheus introduced the feature flag 'created-timestamp-zero-ingestion'\n\t// in version 2.50.0 to handle this situation.\n\tEnableOpenMetricsTextCreatedSamples bool\n\t// ProcessStartTime allows setting process start timevalue that will be exposed\n\t// with \"Process-Start-Time-Unix\" response header along with the metrics\n\t// payload. This allow callers to have efficient transformations to cumulative\n\t// counters (e.g. OpenTelemetry) or generally _created timestamp estimation per\n\t// scrape target.\n\t// NOTE: This feature is experimental and not covered by OpenMetrics or Prometheus\n\t// exposition format.\n\tProcessStartTime time.Time\n}\n\n// httpError removes any content-encoding header and then calls http.Error with\n// the provided error and http.StatusInternalServerError. Error contents is\n// supposed to be uncompressed plain text. Same as with a plain http.Error, this\n// must not be called if the header or any payload has already been sent.\nfunc httpError(rsp http.ResponseWriter, err error) {\n\trsp.Header().Del(contentEncodingHeader)\n\thttp.Error(\n\t\trsp,\n\t\t\"An error has occurred while serving metrics:\\n\\n\"+err.Error(),\n\t\thttp.StatusInternalServerError,\n\t)\n}\n\n// negotiateEncodingWriter reads the Accept-Encoding header from a request and\n// selects the right compression based on an allow-list of supported\n// compressions. It returns a writer implementing the compression and an the\n// correct value that the caller can set in the response header.\nfunc negotiateEncodingWriter(r *http.Request, rw io.Writer, compressions []string) (_ io.Writer, encodingHeaderValue string, closeWriter func(), _ error) {\n\tif len(compressions) == 0 {\n\t\treturn rw, string(Identity), func() {}, nil\n\t}\n\n\t// TODO(mrueg): Replace internal/github.com/gddo once https://github.com/golang/go/issues/19307 is implemented.\n\tselected := httputil.NegotiateContentEncoding(r, compressions)\n\n\tswitch selected {\n\tcase \"zstd\":\n\t\tif internal.NewZstdWriter == nil {\n\t\t\t// The content encoding was not implemented yet.\n\t\t\treturn nil, \"\", func() {}, fmt.Errorf(\"content compression format not recognized: %s. Valid formats are: %s\", selected, defaultCompressionFormats())\n\t\t}\n\t\twriter, closeWriter, err := internal.NewZstdWriter(rw)\n\t\treturn writer, selected, closeWriter, err\n\tcase \"gzip\":\n\t\tgz := gzipPool.Get().(*gzip.Writer)\n\t\tgz.Reset(rw)\n\t\treturn gz, selected, func() { _ = gz.Close(); gzipPool.Put(gz) }, nil\n\tcase \"identity\":\n\t\t// This means the content is not compressed.\n\t\treturn rw, selected, func() {}, nil\n\tdefault:\n\t\t// The content encoding was not implemented yet.\n\t\treturn nil, \"\", func() {}, fmt.Errorf(\"content compression format not recognized: %s. Valid formats are: %s\", selected, defaultCompressionFormats())\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go",
    "content": "// Copyright 2017 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage promhttp\n\nimport (\n\t\"crypto/tls\"\n\t\"net/http\"\n\t\"net/http/httptrace\"\n\t\"time\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n)\n\n// The RoundTripperFunc type is an adapter to allow the use of ordinary\n// functions as RoundTrippers. If f is a function with the appropriate\n// signature, RountTripperFunc(f) is a RoundTripper that calls f.\ntype RoundTripperFunc func(req *http.Request) (*http.Response, error)\n\n// RoundTrip implements the RoundTripper interface.\nfunc (rt RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) {\n\treturn rt(r)\n}\n\n// InstrumentRoundTripperInFlight is a middleware that wraps the provided\n// http.RoundTripper. It sets the provided prometheus.Gauge to the number of\n// requests currently handled by the wrapped http.RoundTripper.\n//\n// See the example for ExampleInstrumentRoundTripperDuration for example usage.\nfunc InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripper) RoundTripperFunc {\n\treturn func(r *http.Request) (*http.Response, error) {\n\t\tgauge.Inc()\n\t\tdefer gauge.Dec()\n\t\treturn next.RoundTrip(r)\n\t}\n}\n\n// InstrumentRoundTripperCounter is a middleware that wraps the provided\n// http.RoundTripper to observe the request result with the provided CounterVec.\n// The CounterVec must have zero, one, or two non-const non-curried labels. For\n// those, the only allowed label names are \"code\" and \"method\". The function\n// panics otherwise. For the \"method\" label a predefined default label value set\n// is used to filter given values. Values besides predefined values will count\n// as `unknown` method.`WithExtraMethods` can be used to add more\n// methods to the set. Partitioning of the CounterVec happens by HTTP status code\n// and/or HTTP method if the respective instance label names are present in the\n// CounterVec. For unpartitioned counting, use a CounterVec with zero labels.\n//\n// If the wrapped RoundTripper panics or returns a non-nil error, the Counter\n// is not incremented.\n//\n// Use with WithExemplarFromContext to instrument the exemplars on the counter of requests.\n//\n// See the example for ExampleInstrumentRoundTripperDuration for example usage.\nfunc InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.RoundTripper, opts ...Option) RoundTripperFunc {\n\trtOpts := defaultOptions()\n\tfor _, o := range opts {\n\t\to.apply(rtOpts)\n\t}\n\n\t// Curry the counter with dynamic labels before checking the remaining labels.\n\tcode, method := checkLabels(counter.MustCurryWith(rtOpts.emptyDynamicLabels()))\n\n\treturn func(r *http.Request) (*http.Response, error) {\n\t\tresp, err := next.RoundTrip(r)\n\t\tif err == nil {\n\t\t\tl := labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)\n\t\t\tfor label, resolve := range rtOpts.extraLabelsFromCtx {\n\t\t\t\tl[label] = resolve(resp.Request.Context())\n\t\t\t}\n\t\t\taddWithExemplar(counter.With(l), 1, rtOpts.getExemplarFn(r.Context()))\n\t\t}\n\t\treturn resp, err\n\t}\n}\n\n// InstrumentRoundTripperDuration is a middleware that wraps the provided\n// http.RoundTripper to observe the request duration with the provided\n// ObserverVec.  The ObserverVec must have zero, one, or two non-const\n// non-curried labels. For those, the only allowed label names are \"code\" and\n// \"method\". The function panics otherwise. For the \"method\" label a predefined\n// default label value set is used to filter given values. Values besides\n// predefined values will count as `unknown` method. `WithExtraMethods`\n// can be used to add more methods to the set. The Observe method of the Observer\n// in the ObserverVec is called with the request duration in\n// seconds. Partitioning happens by HTTP status code and/or HTTP method if the\n// respective instance label names are present in the ObserverVec. For\n// unpartitioned observations, use an ObserverVec with zero labels. Note that\n// partitioning of Histograms is expensive and should be used judiciously.\n//\n// If the wrapped RoundTripper panics or returns a non-nil error, no values are\n// reported.\n//\n// Use with WithExemplarFromContext to instrument the exemplars on the duration histograms.\n//\n// Note that this method is only guaranteed to never observe negative durations\n// if used with Go1.9+.\nfunc InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundTripper, opts ...Option) RoundTripperFunc {\n\trtOpts := defaultOptions()\n\tfor _, o := range opts {\n\t\to.apply(rtOpts)\n\t}\n\n\t// Curry the observer with dynamic labels before checking the remaining labels.\n\tcode, method := checkLabels(obs.MustCurryWith(rtOpts.emptyDynamicLabels()))\n\n\treturn func(r *http.Request) (*http.Response, error) {\n\t\tstart := time.Now()\n\t\tresp, err := next.RoundTrip(r)\n\t\tif err == nil {\n\t\t\tl := labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)\n\t\t\tfor label, resolve := range rtOpts.extraLabelsFromCtx {\n\t\t\t\tl[label] = resolve(resp.Request.Context())\n\t\t\t}\n\t\t\tobserveWithExemplar(obs.With(l), time.Since(start).Seconds(), rtOpts.getExemplarFn(r.Context()))\n\t\t}\n\t\treturn resp, err\n\t}\n}\n\n// InstrumentTrace is used to offer flexibility in instrumenting the available\n// httptrace.ClientTrace hook functions. Each function is passed a float64\n// representing the time in seconds since the start of the http request. A user\n// may choose to use separately buckets Histograms, or implement custom\n// instance labels on a per function basis.\ntype InstrumentTrace struct {\n\tGotConn              func(float64)\n\tPutIdleConn          func(float64)\n\tGotFirstResponseByte func(float64)\n\tGot100Continue       func(float64)\n\tDNSStart             func(float64)\n\tDNSDone              func(float64)\n\tConnectStart         func(float64)\n\tConnectDone          func(float64)\n\tTLSHandshakeStart    func(float64)\n\tTLSHandshakeDone     func(float64)\n\tWroteHeaders         func(float64)\n\tWait100Continue      func(float64)\n\tWroteRequest         func(float64)\n}\n\n// InstrumentRoundTripperTrace is a middleware that wraps the provided\n// RoundTripper and reports times to hook functions provided in the\n// InstrumentTrace struct. Hook functions that are not present in the provided\n// InstrumentTrace struct are ignored. Times reported to the hook functions are\n// time since the start of the request. Only with Go1.9+, those times are\n// guaranteed to never be negative. (Earlier Go versions are not using a\n// monotonic clock.) Note that partitioning of Histograms is expensive and\n// should be used judiciously.\n//\n// For hook functions that receive an error as an argument, no observations are\n// made in the event of a non-nil error value.\n//\n// See the example for ExampleInstrumentRoundTripperDuration for example usage.\nfunc InstrumentRoundTripperTrace(it *InstrumentTrace, next http.RoundTripper) RoundTripperFunc {\n\treturn func(r *http.Request) (*http.Response, error) {\n\t\tstart := time.Now()\n\n\t\ttrace := &httptrace.ClientTrace{\n\t\t\tGotConn: func(_ httptrace.GotConnInfo) {\n\t\t\t\tif it.GotConn != nil {\n\t\t\t\t\tit.GotConn(time.Since(start).Seconds())\n\t\t\t\t}\n\t\t\t},\n\t\t\tPutIdleConn: func(err error) {\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif it.PutIdleConn != nil {\n\t\t\t\t\tit.PutIdleConn(time.Since(start).Seconds())\n\t\t\t\t}\n\t\t\t},\n\t\t\tDNSStart: func(_ httptrace.DNSStartInfo) {\n\t\t\t\tif it.DNSStart != nil {\n\t\t\t\t\tit.DNSStart(time.Since(start).Seconds())\n\t\t\t\t}\n\t\t\t},\n\t\t\tDNSDone: func(_ httptrace.DNSDoneInfo) {\n\t\t\t\tif it.DNSDone != nil {\n\t\t\t\t\tit.DNSDone(time.Since(start).Seconds())\n\t\t\t\t}\n\t\t\t},\n\t\t\tConnectStart: func(_, _ string) {\n\t\t\t\tif it.ConnectStart != nil {\n\t\t\t\t\tit.ConnectStart(time.Since(start).Seconds())\n\t\t\t\t}\n\t\t\t},\n\t\t\tConnectDone: func(_, _ string, err error) {\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif it.ConnectDone != nil {\n\t\t\t\t\tit.ConnectDone(time.Since(start).Seconds())\n\t\t\t\t}\n\t\t\t},\n\t\t\tGotFirstResponseByte: func() {\n\t\t\t\tif it.GotFirstResponseByte != nil {\n\t\t\t\t\tit.GotFirstResponseByte(time.Since(start).Seconds())\n\t\t\t\t}\n\t\t\t},\n\t\t\tGot100Continue: func() {\n\t\t\t\tif it.Got100Continue != nil {\n\t\t\t\t\tit.Got100Continue(time.Since(start).Seconds())\n\t\t\t\t}\n\t\t\t},\n\t\t\tTLSHandshakeStart: func() {\n\t\t\t\tif it.TLSHandshakeStart != nil {\n\t\t\t\t\tit.TLSHandshakeStart(time.Since(start).Seconds())\n\t\t\t\t}\n\t\t\t},\n\t\t\tTLSHandshakeDone: func(_ tls.ConnectionState, err error) {\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif it.TLSHandshakeDone != nil {\n\t\t\t\t\tit.TLSHandshakeDone(time.Since(start).Seconds())\n\t\t\t\t}\n\t\t\t},\n\t\t\tWroteHeaders: func() {\n\t\t\t\tif it.WroteHeaders != nil {\n\t\t\t\t\tit.WroteHeaders(time.Since(start).Seconds())\n\t\t\t\t}\n\t\t\t},\n\t\t\tWait100Continue: func() {\n\t\t\t\tif it.Wait100Continue != nil {\n\t\t\t\t\tit.Wait100Continue(time.Since(start).Seconds())\n\t\t\t\t}\n\t\t\t},\n\t\t\tWroteRequest: func(_ httptrace.WroteRequestInfo) {\n\t\t\t\tif it.WroteRequest != nil {\n\t\t\t\t\tit.WroteRequest(time.Since(start).Seconds())\n\t\t\t\t}\n\t\t\t},\n\t\t}\n\t\tr = r.WithContext(httptrace.WithClientTrace(r.Context(), trace))\n\n\t\treturn next.RoundTrip(r)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go",
    "content": "// Copyright 2017 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage promhttp\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\tdto \"github.com/prometheus/client_model/go\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n)\n\n// magicString is used for the hacky label test in checkLabels. Remove once fixed.\nconst magicString = \"zZgWfBxLqvG8kc8IMv3POi2Bb0tZI3vAnBx+gBaFi9FyPzB/CzKUer1yufDa\"\n\n// observeWithExemplar is a wrapper for [prometheus.ExemplarAdder.ExemplarObserver],\n// which falls back to [prometheus.Observer.Observe] if no labels are provided.\nfunc observeWithExemplar(obs prometheus.Observer, val float64, labels map[string]string) {\n\tif labels == nil {\n\t\tobs.Observe(val)\n\t\treturn\n\t}\n\tobs.(prometheus.ExemplarObserver).ObserveWithExemplar(val, labels)\n}\n\n// addWithExemplar is a wrapper for [prometheus.ExemplarAdder.AddWithExemplar],\n// which falls back to [prometheus.Counter.Add] if no labels are provided.\nfunc addWithExemplar(obs prometheus.Counter, val float64, labels map[string]string) {\n\tif labels == nil {\n\t\tobs.Add(val)\n\t\treturn\n\t}\n\tobs.(prometheus.ExemplarAdder).AddWithExemplar(val, labels)\n}\n\n// InstrumentHandlerInFlight is a middleware that wraps the provided\n// http.Handler. It sets the provided prometheus.Gauge to the number of\n// requests currently handled by the wrapped http.Handler.\n//\n// See the example for InstrumentHandlerDuration for example usage.\nfunc InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handler {\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tg.Inc()\n\t\tdefer g.Dec()\n\t\tnext.ServeHTTP(w, r)\n\t})\n}\n\n// InstrumentHandlerDuration is a middleware that wraps the provided\n// http.Handler to observe the request duration with the provided ObserverVec.\n// The ObserverVec must have valid metric and label names and must have zero,\n// one, or two non-const non-curried labels. For those, the only allowed label\n// names are \"code\" and \"method\". The function panics otherwise. For the \"method\"\n// label a predefined default label value set is used to filter given values.\n// Values besides predefined values will count as `unknown` method.\n// `WithExtraMethods` can be used to add more methods to the set. The Observe\n// method of the Observer in the ObserverVec is called with the request duration\n// in seconds. Partitioning happens by HTTP status code and/or HTTP method if\n// the respective instance label names are present in the ObserverVec. For\n// unpartitioned observations, use an ObserverVec with zero labels. Note that\n// partitioning of Histograms is expensive and should be used judiciously.\n//\n// If the wrapped Handler does not set a status code, a status code of 200 is assumed.\n//\n// If the wrapped Handler panics, no values are reported.\n//\n// Note that this method is only guaranteed to never observe negative durations\n// if used with Go1.9+.\nfunc InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {\n\thOpts := defaultOptions()\n\tfor _, o := range opts {\n\t\to.apply(hOpts)\n\t}\n\n\t// Curry the observer with dynamic labels before checking the remaining labels.\n\tcode, method := checkLabels(obs.MustCurryWith(hOpts.emptyDynamicLabels()))\n\n\tif code {\n\t\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\t\tnow := time.Now()\n\t\t\td := newDelegator(w, nil)\n\t\t\tnext.ServeHTTP(d, r)\n\n\t\t\tl := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)\n\t\t\tfor label, resolve := range hOpts.extraLabelsFromCtx {\n\t\t\t\tl[label] = resolve(r.Context())\n\t\t\t}\n\t\t\tobserveWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context()))\n\t\t}\n\t}\n\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\tnow := time.Now()\n\t\tnext.ServeHTTP(w, r)\n\t\tl := labels(code, method, r.Method, 0, hOpts.extraMethods...)\n\t\tfor label, resolve := range hOpts.extraLabelsFromCtx {\n\t\t\tl[label] = resolve(r.Context())\n\t\t}\n\t\tobserveWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context()))\n\t}\n}\n\n// InstrumentHandlerCounter is a middleware that wraps the provided http.Handler\n// to observe the request result with the provided CounterVec. The CounterVec\n// must have valid metric and label names and must have zero, one, or two\n// non-const non-curried labels. For those, the only allowed label names are\n// \"code\" and \"method\". The function panics otherwise. For the \"method\"\n// label a predefined default label value set is used to filter given values.\n// Values besides predefined values will count as `unknown` method.\n// `WithExtraMethods` can be used to add more methods to the set. Partitioning of the\n// CounterVec happens by HTTP status code and/or HTTP method if the respective\n// instance label names are present in the CounterVec. For unpartitioned\n// counting, use a CounterVec with zero labels.\n//\n// If the wrapped Handler does not set a status code, a status code of 200 is assumed.\n//\n// If the wrapped Handler panics, the Counter is not incremented.\n//\n// See the example for InstrumentHandlerDuration for example usage.\nfunc InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, opts ...Option) http.HandlerFunc {\n\thOpts := defaultOptions()\n\tfor _, o := range opts {\n\t\to.apply(hOpts)\n\t}\n\n\t// Curry the counter with dynamic labels before checking the remaining labels.\n\tcode, method := checkLabels(counter.MustCurryWith(hOpts.emptyDynamicLabels()))\n\n\tif code {\n\t\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\t\td := newDelegator(w, nil)\n\t\t\tnext.ServeHTTP(d, r)\n\n\t\t\tl := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)\n\t\t\tfor label, resolve := range hOpts.extraLabelsFromCtx {\n\t\t\t\tl[label] = resolve(r.Context())\n\t\t\t}\n\t\t\taddWithExemplar(counter.With(l), 1, hOpts.getExemplarFn(r.Context()))\n\t\t}\n\t}\n\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\tnext.ServeHTTP(w, r)\n\n\t\tl := labels(code, method, r.Method, 0, hOpts.extraMethods...)\n\t\tfor label, resolve := range hOpts.extraLabelsFromCtx {\n\t\t\tl[label] = resolve(r.Context())\n\t\t}\n\t\taddWithExemplar(counter.With(l), 1, hOpts.getExemplarFn(r.Context()))\n\t}\n}\n\n// InstrumentHandlerTimeToWriteHeader is a middleware that wraps the provided\n// http.Handler to observe with the provided ObserverVec the request duration\n// until the response headers are written. The ObserverVec must have valid\n// metric and label names and must have zero, one, or two non-const non-curried\n// labels. For those, the only allowed label names are \"code\" and \"method\". The\n// function panics otherwise. For the \"method\" label a predefined default label\n// value set is used to filter given values. Values besides predefined values\n// will count as `unknown` method.`WithExtraMethods` can be used to add more\n// methods to the set. The Observe method of the Observer in the\n// ObserverVec is called with the request duration in seconds. Partitioning\n// happens by HTTP status code and/or HTTP method if the respective instance\n// label names are present in the ObserverVec. For unpartitioned observations,\n// use an ObserverVec with zero labels. Note that partitioning of Histograms is\n// expensive and should be used judiciously.\n//\n// If the wrapped Handler panics before calling WriteHeader, no value is\n// reported.\n//\n// Note that this method is only guaranteed to never observe negative durations\n// if used with Go1.9+.\n//\n// See the example for InstrumentHandlerDuration for example usage.\nfunc InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {\n\thOpts := defaultOptions()\n\tfor _, o := range opts {\n\t\to.apply(hOpts)\n\t}\n\n\t// Curry the observer with dynamic labels before checking the remaining labels.\n\tcode, method := checkLabels(obs.MustCurryWith(hOpts.emptyDynamicLabels()))\n\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\tnow := time.Now()\n\t\td := newDelegator(w, func(status int) {\n\t\t\tl := labels(code, method, r.Method, status, hOpts.extraMethods...)\n\t\t\tfor label, resolve := range hOpts.extraLabelsFromCtx {\n\t\t\t\tl[label] = resolve(r.Context())\n\t\t\t}\n\t\t\tobserveWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context()))\n\t\t})\n\t\tnext.ServeHTTP(d, r)\n\t}\n}\n\n// InstrumentHandlerRequestSize is a middleware that wraps the provided\n// http.Handler to observe the request size with the provided ObserverVec. The\n// ObserverVec must have valid metric and label names and must have zero, one,\n// or two non-const non-curried labels. For those, the only allowed label names\n// are \"code\" and \"method\". The function panics otherwise. For the \"method\"\n// label a predefined default label value set is used to filter given values.\n// Values besides predefined values will count as `unknown` method.\n// `WithExtraMethods` can be used to add more methods to the set. The Observe\n// method of the Observer in the ObserverVec is called with the request size in\n// bytes. Partitioning happens by HTTP status code and/or HTTP method if the\n// respective instance label names are present in the ObserverVec. For\n// unpartitioned observations, use an ObserverVec with zero labels. Note that\n// partitioning of Histograms is expensive and should be used judiciously.\n//\n// If the wrapped Handler does not set a status code, a status code of 200 is assumed.\n//\n// If the wrapped Handler panics, no values are reported.\n//\n// See the example for InstrumentHandlerDuration for example usage.\nfunc InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {\n\thOpts := defaultOptions()\n\tfor _, o := range opts {\n\t\to.apply(hOpts)\n\t}\n\n\t// Curry the observer with dynamic labels before checking the remaining labels.\n\tcode, method := checkLabels(obs.MustCurryWith(hOpts.emptyDynamicLabels()))\n\n\tif code {\n\t\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\t\td := newDelegator(w, nil)\n\t\t\tnext.ServeHTTP(d, r)\n\t\t\tsize := computeApproximateRequestSize(r)\n\n\t\t\tl := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)\n\t\t\tfor label, resolve := range hOpts.extraLabelsFromCtx {\n\t\t\t\tl[label] = resolve(r.Context())\n\t\t\t}\n\t\t\tobserveWithExemplar(obs.With(l), float64(size), hOpts.getExemplarFn(r.Context()))\n\t\t}\n\t}\n\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\tnext.ServeHTTP(w, r)\n\t\tsize := computeApproximateRequestSize(r)\n\n\t\tl := labels(code, method, r.Method, 0, hOpts.extraMethods...)\n\t\tfor label, resolve := range hOpts.extraLabelsFromCtx {\n\t\t\tl[label] = resolve(r.Context())\n\t\t}\n\t\tobserveWithExemplar(obs.With(l), float64(size), hOpts.getExemplarFn(r.Context()))\n\t}\n}\n\n// InstrumentHandlerResponseSize is a middleware that wraps the provided\n// http.Handler to observe the response size with the provided ObserverVec. The\n// ObserverVec must have valid metric and label names and must have zero, one,\n// or two non-const non-curried labels. For those, the only allowed label names\n// are \"code\" and \"method\". The function panics otherwise. For the \"method\"\n// label a predefined default label value set is used to filter given values.\n// Values besides predefined values will count as `unknown` method.\n// `WithExtraMethods` can be used to add more methods to the set. The Observe\n// method of the Observer in the ObserverVec is called with the response size in\n// bytes. Partitioning happens by HTTP status code and/or HTTP method if the\n// respective instance label names are present in the ObserverVec. For\n// unpartitioned observations, use an ObserverVec with zero labels. Note that\n// partitioning of Histograms is expensive and should be used judiciously.\n//\n// If the wrapped Handler does not set a status code, a status code of 200 is assumed.\n//\n// If the wrapped Handler panics, no values are reported.\n//\n// See the example for InstrumentHandlerDuration for example usage.\nfunc InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.Handler {\n\thOpts := defaultOptions()\n\tfor _, o := range opts {\n\t\to.apply(hOpts)\n\t}\n\n\t// Curry the observer with dynamic labels before checking the remaining labels.\n\tcode, method := checkLabels(obs.MustCurryWith(hOpts.emptyDynamicLabels()))\n\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\td := newDelegator(w, nil)\n\t\tnext.ServeHTTP(d, r)\n\n\t\tl := labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)\n\t\tfor label, resolve := range hOpts.extraLabelsFromCtx {\n\t\t\tl[label] = resolve(r.Context())\n\t\t}\n\t\tobserveWithExemplar(obs.With(l), float64(d.Written()), hOpts.getExemplarFn(r.Context()))\n\t})\n}\n\n// checkLabels returns whether the provided Collector has a non-const,\n// non-curried label named \"code\" and/or \"method\". It panics if the provided\n// Collector does not have a Desc or has more than one Desc or its Desc is\n// invalid. It also panics if the Collector has any non-const, non-curried\n// labels that are not named \"code\" or \"method\".\nfunc checkLabels(c prometheus.Collector) (code, method bool) {\n\t// TODO(beorn7): Remove this hacky way to check for instance labels\n\t// once Descriptors can have their dimensionality queried.\n\tvar (\n\t\tdesc *prometheus.Desc\n\t\tm    prometheus.Metric\n\t\tpm   dto.Metric\n\t\tlvs  []string\n\t)\n\n\t// Get the Desc from the Collector.\n\tdescc := make(chan *prometheus.Desc, 1)\n\tc.Describe(descc)\n\n\tselect {\n\tcase desc = <-descc:\n\tdefault:\n\t\tpanic(\"no description provided by collector\")\n\t}\n\tselect {\n\tcase <-descc:\n\t\tpanic(\"more than one description provided by collector\")\n\tdefault:\n\t}\n\n\tclose(descc)\n\n\t// Make sure the Collector has a valid Desc by registering it with a\n\t// temporary registry.\n\tprometheus.NewRegistry().MustRegister(c)\n\n\t// Create a ConstMetric with the Desc. Since we don't know how many\n\t// variable labels there are, try for as long as it needs.\n\tfor err := errors.New(\"dummy\"); err != nil; lvs = append(lvs, magicString) {\n\t\tm, err = prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0, lvs...)\n\t}\n\n\t// Write out the metric into a proto message and look at the labels.\n\t// If the value is not the magicString, it is a constLabel, which doesn't interest us.\n\t// If the label is curried, it doesn't interest us.\n\t// In all other cases, only \"code\" or \"method\" is allowed.\n\tif err := m.Write(&pm); err != nil {\n\t\tpanic(\"error checking metric for labels\")\n\t}\n\tfor _, label := range pm.Label {\n\t\tname, value := label.GetName(), label.GetValue()\n\t\tif value != magicString || isLabelCurried(c, name) {\n\t\t\tcontinue\n\t\t}\n\t\tswitch name {\n\t\tcase \"code\":\n\t\t\tcode = true\n\t\tcase \"method\":\n\t\t\tmethod = true\n\t\tdefault:\n\t\t\tpanic(\"metric partitioned with non-supported labels\")\n\t\t}\n\t}\n\treturn\n}\n\nfunc isLabelCurried(c prometheus.Collector, label string) bool {\n\t// This is even hackier than the label test above.\n\t// We essentially try to curry again and see if it works.\n\t// But for that, we need to type-convert to the two\n\t// types we use here, ObserverVec or *CounterVec.\n\tswitch v := c.(type) {\n\tcase *prometheus.CounterVec:\n\t\tif _, err := v.CurryWith(prometheus.Labels{label: \"dummy\"}); err == nil {\n\t\t\treturn false\n\t\t}\n\tcase prometheus.ObserverVec:\n\t\tif _, err := v.CurryWith(prometheus.Labels{label: \"dummy\"}); err == nil {\n\t\t\treturn false\n\t\t}\n\tdefault:\n\t\tpanic(\"unsupported metric vec type\")\n\t}\n\treturn true\n}\n\nfunc labels(code, method bool, reqMethod string, status int, extraMethods ...string) prometheus.Labels {\n\tlabels := prometheus.Labels{}\n\n\tif !(code || method) {\n\t\treturn labels\n\t}\n\n\tif code {\n\t\tlabels[\"code\"] = sanitizeCode(status)\n\t}\n\tif method {\n\t\tlabels[\"method\"] = sanitizeMethod(reqMethod, extraMethods...)\n\t}\n\n\treturn labels\n}\n\nfunc computeApproximateRequestSize(r *http.Request) int {\n\ts := 0\n\tif r.URL != nil {\n\t\ts += len(r.URL.String())\n\t}\n\n\ts += len(r.Method)\n\ts += len(r.Proto)\n\tfor name, values := range r.Header {\n\t\ts += len(name)\n\t\tfor _, value := range values {\n\t\t\ts += len(value)\n\t\t}\n\t}\n\ts += len(r.Host)\n\n\t// N.B. r.Form and r.MultipartForm are assumed to be included in r.URL.\n\n\tif r.ContentLength != -1 {\n\t\ts += int(r.ContentLength)\n\t}\n\treturn s\n}\n\n// If the wrapped http.Handler has a known method, it will be sanitized and returned.\n// Otherwise, \"unknown\" will be returned. The known method list can be extended\n// as needed by using extraMethods parameter.\nfunc sanitizeMethod(m string, extraMethods ...string) string {\n\t// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods for\n\t// the methods chosen as default.\n\tswitch m {\n\tcase \"GET\", \"get\":\n\t\treturn \"get\"\n\tcase \"PUT\", \"put\":\n\t\treturn \"put\"\n\tcase \"HEAD\", \"head\":\n\t\treturn \"head\"\n\tcase \"POST\", \"post\":\n\t\treturn \"post\"\n\tcase \"DELETE\", \"delete\":\n\t\treturn \"delete\"\n\tcase \"CONNECT\", \"connect\":\n\t\treturn \"connect\"\n\tcase \"OPTIONS\", \"options\":\n\t\treturn \"options\"\n\tcase \"NOTIFY\", \"notify\":\n\t\treturn \"notify\"\n\tcase \"TRACE\", \"trace\":\n\t\treturn \"trace\"\n\tcase \"PATCH\", \"patch\":\n\t\treturn \"patch\"\n\tdefault:\n\t\tfor _, method := range extraMethods {\n\t\t\tif strings.EqualFold(m, method) {\n\t\t\t\treturn strings.ToLower(m)\n\t\t\t}\n\t\t}\n\t\treturn \"unknown\"\n\t}\n}\n\n// If the wrapped http.Handler has not set a status code, i.e. the value is\n// currently 0, sanitizeCode will return 200, for consistency with behavior in\n// the stdlib.\nfunc sanitizeCode(s int) string {\n\t// See for accepted codes https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml\n\tswitch s {\n\tcase 100:\n\t\treturn \"100\"\n\tcase 101:\n\t\treturn \"101\"\n\n\tcase 200, 0:\n\t\treturn \"200\"\n\tcase 201:\n\t\treturn \"201\"\n\tcase 202:\n\t\treturn \"202\"\n\tcase 203:\n\t\treturn \"203\"\n\tcase 204:\n\t\treturn \"204\"\n\tcase 205:\n\t\treturn \"205\"\n\tcase 206:\n\t\treturn \"206\"\n\n\tcase 300:\n\t\treturn \"300\"\n\tcase 301:\n\t\treturn \"301\"\n\tcase 302:\n\t\treturn \"302\"\n\tcase 304:\n\t\treturn \"304\"\n\tcase 305:\n\t\treturn \"305\"\n\tcase 307:\n\t\treturn \"307\"\n\n\tcase 400:\n\t\treturn \"400\"\n\tcase 401:\n\t\treturn \"401\"\n\tcase 402:\n\t\treturn \"402\"\n\tcase 403:\n\t\treturn \"403\"\n\tcase 404:\n\t\treturn \"404\"\n\tcase 405:\n\t\treturn \"405\"\n\tcase 406:\n\t\treturn \"406\"\n\tcase 407:\n\t\treturn \"407\"\n\tcase 408:\n\t\treturn \"408\"\n\tcase 409:\n\t\treturn \"409\"\n\tcase 410:\n\t\treturn \"410\"\n\tcase 411:\n\t\treturn \"411\"\n\tcase 412:\n\t\treturn \"412\"\n\tcase 413:\n\t\treturn \"413\"\n\tcase 414:\n\t\treturn \"414\"\n\tcase 415:\n\t\treturn \"415\"\n\tcase 416:\n\t\treturn \"416\"\n\tcase 417:\n\t\treturn \"417\"\n\tcase 418:\n\t\treturn \"418\"\n\n\tcase 500:\n\t\treturn \"500\"\n\tcase 501:\n\t\treturn \"501\"\n\tcase 502:\n\t\treturn \"502\"\n\tcase 503:\n\t\treturn \"503\"\n\tcase 504:\n\t\treturn \"504\"\n\tcase 505:\n\t\treturn \"505\"\n\n\tcase 428:\n\t\treturn \"428\"\n\tcase 429:\n\t\treturn \"429\"\n\tcase 431:\n\t\treturn \"431\"\n\tcase 511:\n\t\treturn \"511\"\n\n\tdefault:\n\t\tif s >= 100 && s <= 599 {\n\t\t\treturn strconv.Itoa(s)\n\t\t}\n\t\treturn \"unknown\"\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/promhttp/internal/compression.go",
    "content": "// Copyright 2025 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage internal\n\nimport (\n\t\"io\"\n)\n\n// NewZstdWriter enables zstd write support if non-nil.\nvar NewZstdWriter func(rw io.Writer) (_ io.Writer, closeWriter func(), _ error)\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go",
    "content": "// Copyright 2022 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage promhttp\n\nimport (\n\t\"context\"\n\n\t\"github.com/prometheus/client_golang/prometheus\"\n)\n\n// Option are used to configure both handler (middleware) or round tripper.\ntype Option interface {\n\tapply(*options)\n}\n\n// LabelValueFromCtx are used to compute the label value from request context.\n// Context can be filled with values from request through middleware.\ntype LabelValueFromCtx func(ctx context.Context) string\n\n// options store options for both a handler or round tripper.\ntype options struct {\n\textraMethods       []string\n\tgetExemplarFn      func(requestCtx context.Context) prometheus.Labels\n\textraLabelsFromCtx map[string]LabelValueFromCtx\n}\n\nfunc defaultOptions() *options {\n\treturn &options{\n\t\tgetExemplarFn:      func(ctx context.Context) prometheus.Labels { return nil },\n\t\textraLabelsFromCtx: map[string]LabelValueFromCtx{},\n\t}\n}\n\nfunc (o *options) emptyDynamicLabels() prometheus.Labels {\n\tlabels := prometheus.Labels{}\n\n\tfor label := range o.extraLabelsFromCtx {\n\t\tlabels[label] = \"\"\n\t}\n\n\treturn labels\n}\n\ntype optionApplyFunc func(*options)\n\nfunc (o optionApplyFunc) apply(opt *options) { o(opt) }\n\n// WithExtraMethods adds additional HTTP methods to the list of allowed methods.\n// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods for the default list.\n//\n// See the example for ExampleInstrumentHandlerWithExtraMethods for example usage.\nfunc WithExtraMethods(methods ...string) Option {\n\treturn optionApplyFunc(func(o *options) {\n\t\to.extraMethods = methods\n\t})\n}\n\n// WithExemplarFromContext allows to inject function that will get exemplar from context that will be put to counter and histogram metrics.\n// If the function returns nil labels or the metric does not support exemplars, no exemplar will be added (noop), but\n// metric will continue to observe/increment.\nfunc WithExemplarFromContext(getExemplarFn func(requestCtx context.Context) prometheus.Labels) Option {\n\treturn optionApplyFunc(func(o *options) {\n\t\to.getExemplarFn = getExemplarFn\n\t})\n}\n\n// WithLabelFromCtx registers a label for dynamic resolution with access to context.\n// See the example for ExampleInstrumentHandlerWithLabelResolver for example usage\nfunc WithLabelFromCtx(name string, valueFn LabelValueFromCtx) Option {\n\treturn optionApplyFunc(func(o *options) {\n\t\to.extraLabelsFromCtx[name] = valueFn\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/registry.go",
    "content": "// Copyright 2014 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"unicode/utf8\"\n\n\t\"github.com/prometheus/client_golang/prometheus/internal\"\n\n\t\"github.com/cespare/xxhash/v2\"\n\tdto \"github.com/prometheus/client_model/go\"\n\t\"github.com/prometheus/common/expfmt\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\nconst (\n\t// Capacity for the channel to collect metrics and descriptors.\n\tcapMetricChan = 1000\n\tcapDescChan   = 10\n)\n\n// DefaultRegisterer and DefaultGatherer are the implementations of the\n// Registerer and Gatherer interface a number of convenience functions in this\n// package act on. Initially, both variables point to the same Registry, which\n// has a process collector (currently on Linux only, see NewProcessCollector)\n// and a Go collector (see NewGoCollector, in particular the note about\n// stop-the-world implication with Go versions older than 1.9) already\n// registered. This approach to keep default instances as global state mirrors\n// the approach of other packages in the Go standard library. Note that there\n// are caveats. Change the variables with caution and only if you understand the\n// consequences. Users who want to avoid global state altogether should not use\n// the convenience functions and act on custom instances instead.\nvar (\n\tdefaultRegistry              = NewRegistry()\n\tDefaultRegisterer Registerer = defaultRegistry\n\tDefaultGatherer   Gatherer   = defaultRegistry\n)\n\nfunc init() {\n\tMustRegister(NewProcessCollector(ProcessCollectorOpts{}))\n\tMustRegister(NewGoCollector())\n}\n\n// NewRegistry creates a new vanilla Registry without any Collectors\n// pre-registered.\nfunc NewRegistry() *Registry {\n\treturn &Registry{\n\t\tcollectorsByID:  map[uint64]Collector{},\n\t\tdescIDs:         map[uint64]struct{}{},\n\t\tdimHashesByName: map[string]uint64{},\n\t}\n}\n\n// NewPedanticRegistry returns a registry that checks during collection if each\n// collected Metric is consistent with its reported Desc, and if the Desc has\n// actually been registered with the registry. Unchecked Collectors (those whose\n// Describe method does not yield any descriptors) are excluded from the check.\n//\n// Usually, a Registry will be happy as long as the union of all collected\n// Metrics is consistent and valid even if some metrics are not consistent with\n// their own Desc or a Desc provided by their registered Collector. Well-behaved\n// Collectors and Metrics will only provide consistent Descs. This Registry is\n// useful to test the implementation of Collectors and Metrics.\nfunc NewPedanticRegistry() *Registry {\n\tr := NewRegistry()\n\tr.pedanticChecksEnabled = true\n\treturn r\n}\n\n// Registerer is the interface for the part of a registry in charge of\n// registering and unregistering. Users of custom registries should use\n// Registerer as type for registration purposes (rather than the Registry type\n// directly). In that way, they are free to use custom Registerer implementation\n// (e.g. for testing purposes).\ntype Registerer interface {\n\t// Register registers a new Collector to be included in metrics\n\t// collection. It returns an error if the descriptors provided by the\n\t// Collector are invalid or if they — in combination with descriptors of\n\t// already registered Collectors — do not fulfill the consistency and\n\t// uniqueness criteria described in the documentation of metric.Desc.\n\t//\n\t// If the provided Collector is equal to a Collector already registered\n\t// (which includes the case of re-registering the same Collector), the\n\t// returned error is an instance of AlreadyRegisteredError, which\n\t// contains the previously registered Collector.\n\t//\n\t// A Collector whose Describe method does not yield any Desc is treated\n\t// as unchecked. Registration will always succeed. No check for\n\t// re-registering (see previous paragraph) is performed. Thus, the\n\t// caller is responsible for not double-registering the same unchecked\n\t// Collector, and for providing a Collector that will not cause\n\t// inconsistent metrics on collection. (This would lead to scrape\n\t// errors.)\n\tRegister(Collector) error\n\t// MustRegister works like Register but registers any number of\n\t// Collectors and panics upon the first registration that causes an\n\t// error.\n\tMustRegister(...Collector)\n\t// Unregister unregisters the Collector that equals the Collector passed\n\t// in as an argument.  (Two Collectors are considered equal if their\n\t// Describe method yields the same set of descriptors.) The function\n\t// returns whether a Collector was unregistered. Note that an unchecked\n\t// Collector cannot be unregistered (as its Describe method does not\n\t// yield any descriptor).\n\t//\n\t// Note that even after unregistering, it will not be possible to\n\t// register a new Collector that is inconsistent with the unregistered\n\t// Collector, e.g. a Collector collecting metrics with the same name but\n\t// a different help string. The rationale here is that the same registry\n\t// instance must only collect consistent metrics throughout its\n\t// lifetime.\n\tUnregister(Collector) bool\n}\n\n// Gatherer is the interface for the part of a registry in charge of gathering\n// the collected metrics into a number of MetricFamilies. The Gatherer interface\n// comes with the same general implication as described for the Registerer\n// interface.\ntype Gatherer interface {\n\t// Gather calls the Collect method of the registered Collectors and then\n\t// gathers the collected metrics into a lexicographically sorted slice\n\t// of uniquely named MetricFamily protobufs. Gather ensures that the\n\t// returned slice is valid and self-consistent so that it can be used\n\t// for valid exposition. As an exception to the strict consistency\n\t// requirements described for metric.Desc, Gather will tolerate\n\t// different sets of label names for metrics of the same metric family.\n\t//\n\t// Even if an error occurs, Gather attempts to gather as many metrics as\n\t// possible. Hence, if a non-nil error is returned, the returned\n\t// MetricFamily slice could be nil (in case of a fatal error that\n\t// prevented any meaningful metric collection) or contain a number of\n\t// MetricFamily protobufs, some of which might be incomplete, and some\n\t// might be missing altogether. The returned error (which might be a\n\t// MultiError) explains the details. Note that this is mostly useful for\n\t// debugging purposes. If the gathered protobufs are to be used for\n\t// exposition in actual monitoring, it is almost always better to not\n\t// expose an incomplete result and instead disregard the returned\n\t// MetricFamily protobufs in case the returned error is non-nil.\n\tGather() ([]*dto.MetricFamily, error)\n}\n\n// Register registers the provided Collector with the DefaultRegisterer.\n//\n// Register is a shortcut for DefaultRegisterer.Register(c). See there for more\n// details.\nfunc Register(c Collector) error {\n\treturn DefaultRegisterer.Register(c)\n}\n\n// MustRegister registers the provided Collectors with the DefaultRegisterer and\n// panics if any error occurs.\n//\n// MustRegister is a shortcut for DefaultRegisterer.MustRegister(cs...). See\n// there for more details.\nfunc MustRegister(cs ...Collector) {\n\tDefaultRegisterer.MustRegister(cs...)\n}\n\n// Unregister removes the registration of the provided Collector from the\n// DefaultRegisterer.\n//\n// Unregister is a shortcut for DefaultRegisterer.Unregister(c). See there for\n// more details.\nfunc Unregister(c Collector) bool {\n\treturn DefaultRegisterer.Unregister(c)\n}\n\n// GathererFunc turns a function into a Gatherer.\ntype GathererFunc func() ([]*dto.MetricFamily, error)\n\n// Gather implements Gatherer.\nfunc (gf GathererFunc) Gather() ([]*dto.MetricFamily, error) {\n\treturn gf()\n}\n\n// AlreadyRegisteredError is returned by the Register method if the Collector to\n// be registered has already been registered before, or a different Collector\n// that collects the same metrics has been registered before. Registration fails\n// in that case, but you can detect from the kind of error what has\n// happened. The error contains fields for the existing Collector and the\n// (rejected) new Collector that equals the existing one. This can be used to\n// find out if an equal Collector has been registered before and switch over to\n// using the old one, as demonstrated in the example.\ntype AlreadyRegisteredError struct {\n\tExistingCollector, NewCollector Collector\n}\n\nfunc (err AlreadyRegisteredError) Error() string {\n\treturn \"duplicate metrics collector registration attempted\"\n}\n\n// MultiError is a slice of errors implementing the error interface. It is used\n// by a Gatherer to report multiple errors during MetricFamily gathering.\ntype MultiError []error\n\n// Error formats the contained errors as a bullet point list, preceded by the\n// total number of errors. Note that this results in a multi-line string.\nfunc (errs MultiError) Error() string {\n\tif len(errs) == 0 {\n\t\treturn \"\"\n\t}\n\tbuf := &bytes.Buffer{}\n\tfmt.Fprintf(buf, \"%d error(s) occurred:\", len(errs))\n\tfor _, err := range errs {\n\t\tfmt.Fprintf(buf, \"\\n* %s\", err)\n\t}\n\treturn buf.String()\n}\n\n// Append appends the provided error if it is not nil.\nfunc (errs *MultiError) Append(err error) {\n\tif err != nil {\n\t\t*errs = append(*errs, err)\n\t}\n}\n\n// MaybeUnwrap returns nil if len(errs) is 0. It returns the first and only\n// contained error as error if len(errs is 1). In all other cases, it returns\n// the MultiError directly. This is helpful for returning a MultiError in a way\n// that only uses the MultiError if needed.\nfunc (errs MultiError) MaybeUnwrap() error {\n\tswitch len(errs) {\n\tcase 0:\n\t\treturn nil\n\tcase 1:\n\t\treturn errs[0]\n\tdefault:\n\t\treturn errs\n\t}\n}\n\n// Registry registers Prometheus collectors, collects their metrics, and gathers\n// them into MetricFamilies for exposition. It implements Registerer, Gatherer,\n// and Collector. The zero value is not usable. Create instances with\n// NewRegistry or NewPedanticRegistry.\n//\n// Registry implements Collector to allow it to be used for creating groups of\n// metrics. See the Grouping example for how this can be done.\ntype Registry struct {\n\tmtx                   sync.RWMutex\n\tcollectorsByID        map[uint64]Collector // ID is a hash of the descIDs.\n\tdescIDs               map[uint64]struct{}\n\tdimHashesByName       map[string]uint64\n\tuncheckedCollectors   []Collector\n\tpedanticChecksEnabled bool\n}\n\n// Register implements Registerer.\nfunc (r *Registry) Register(c Collector) error {\n\tvar (\n\t\tdescChan           = make(chan *Desc, capDescChan)\n\t\tnewDescIDs         = map[uint64]struct{}{}\n\t\tnewDimHashesByName = map[string]uint64{}\n\t\tcollectorID        uint64 // All desc IDs XOR'd together.\n\t\tduplicateDescErr   error\n\t)\n\tgo func() {\n\t\tc.Describe(descChan)\n\t\tclose(descChan)\n\t}()\n\tr.mtx.Lock()\n\tdefer func() {\n\t\t// Drain channel in case of premature return to not leak a goroutine.\n\t\tfor range descChan {\n\t\t}\n\t\tr.mtx.Unlock()\n\t}()\n\t// Conduct various tests...\n\tfor desc := range descChan {\n\n\t\t// Is the descriptor valid at all?\n\t\tif desc.err != nil {\n\t\t\treturn fmt.Errorf(\"descriptor %s is invalid: %w\", desc, desc.err)\n\t\t}\n\n\t\t// Is the descID unique?\n\t\t// (In other words: Is the fqName + constLabel combination unique?)\n\t\tif _, exists := r.descIDs[desc.id]; exists {\n\t\t\tduplicateDescErr = fmt.Errorf(\"descriptor %s already exists with the same fully-qualified name and const label values\", desc)\n\t\t}\n\t\t// If it is not a duplicate desc in this collector, XOR it to\n\t\t// the collectorID.  (We allow duplicate descs within the same\n\t\t// collector, but their existence must be a no-op.)\n\t\tif _, exists := newDescIDs[desc.id]; !exists {\n\t\t\tnewDescIDs[desc.id] = struct{}{}\n\t\t\tcollectorID ^= desc.id\n\t\t}\n\n\t\t// Are all the label names and the help string consistent with\n\t\t// previous descriptors of the same name?\n\t\t// First check existing descriptors...\n\t\tif dimHash, exists := r.dimHashesByName[desc.fqName]; exists {\n\t\t\tif dimHash != desc.dimHash {\n\t\t\t\treturn fmt.Errorf(\"a previously registered descriptor with the same fully-qualified name as %s has different label names or a different help string\", desc)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// ...then check the new descriptors already seen.\n\t\tif dimHash, exists := newDimHashesByName[desc.fqName]; exists {\n\t\t\tif dimHash != desc.dimHash {\n\t\t\t\treturn fmt.Errorf(\"descriptors reported by collector have inconsistent label names or help strings for the same fully-qualified name, offender is %s\", desc)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tnewDimHashesByName[desc.fqName] = desc.dimHash\n\t}\n\t// A Collector yielding no Desc at all is considered unchecked.\n\tif len(newDescIDs) == 0 {\n\t\tr.uncheckedCollectors = append(r.uncheckedCollectors, c)\n\t\treturn nil\n\t}\n\tif existing, exists := r.collectorsByID[collectorID]; exists {\n\t\tswitch e := existing.(type) {\n\t\tcase *wrappingCollector:\n\t\t\treturn AlreadyRegisteredError{\n\t\t\t\tExistingCollector: e.unwrapRecursively(),\n\t\t\t\tNewCollector:      c,\n\t\t\t}\n\t\tdefault:\n\t\t\treturn AlreadyRegisteredError{\n\t\t\t\tExistingCollector: e,\n\t\t\t\tNewCollector:      c,\n\t\t\t}\n\t\t}\n\t}\n\t// If the collectorID is new, but at least one of the descs existed\n\t// before, we are in trouble.\n\tif duplicateDescErr != nil {\n\t\treturn duplicateDescErr\n\t}\n\n\t// Only after all tests have passed, actually register.\n\tr.collectorsByID[collectorID] = c\n\tfor hash := range newDescIDs {\n\t\tr.descIDs[hash] = struct{}{}\n\t}\n\tfor name, dimHash := range newDimHashesByName {\n\t\tr.dimHashesByName[name] = dimHash\n\t}\n\treturn nil\n}\n\n// Unregister implements Registerer.\nfunc (r *Registry) Unregister(c Collector) bool {\n\tvar (\n\t\tdescChan    = make(chan *Desc, capDescChan)\n\t\tdescIDs     = map[uint64]struct{}{}\n\t\tcollectorID uint64 // All desc IDs XOR'd together.\n\t)\n\tgo func() {\n\t\tc.Describe(descChan)\n\t\tclose(descChan)\n\t}()\n\tfor desc := range descChan {\n\t\tif _, exists := descIDs[desc.id]; !exists {\n\t\t\tcollectorID ^= desc.id\n\t\t\tdescIDs[desc.id] = struct{}{}\n\t\t}\n\t}\n\n\tr.mtx.RLock()\n\tif _, exists := r.collectorsByID[collectorID]; !exists {\n\t\tr.mtx.RUnlock()\n\t\treturn false\n\t}\n\tr.mtx.RUnlock()\n\n\tr.mtx.Lock()\n\tdefer r.mtx.Unlock()\n\n\tdelete(r.collectorsByID, collectorID)\n\tfor id := range descIDs {\n\t\tdelete(r.descIDs, id)\n\t}\n\t// dimHashesByName is left untouched as those must be consistent\n\t// throughout the lifetime of a program.\n\treturn true\n}\n\n// MustRegister implements Registerer.\nfunc (r *Registry) MustRegister(cs ...Collector) {\n\tfor _, c := range cs {\n\t\tif err := r.Register(c); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n}\n\n// Gather implements Gatherer.\nfunc (r *Registry) Gather() ([]*dto.MetricFamily, error) {\n\tr.mtx.RLock()\n\n\tif len(r.collectorsByID) == 0 && len(r.uncheckedCollectors) == 0 {\n\t\t// Fast path.\n\t\tr.mtx.RUnlock()\n\t\treturn nil, nil\n\t}\n\n\tvar (\n\t\tcheckedMetricChan   = make(chan Metric, capMetricChan)\n\t\tuncheckedMetricChan = make(chan Metric, capMetricChan)\n\t\tmetricHashes        = map[uint64]struct{}{}\n\t\twg                  sync.WaitGroup\n\t\terrs                MultiError          // The collected errors to return in the end.\n\t\tregisteredDescIDs   map[uint64]struct{} // Only used for pedantic checks\n\t)\n\n\tgoroutineBudget := len(r.collectorsByID) + len(r.uncheckedCollectors)\n\tmetricFamiliesByName := make(map[string]*dto.MetricFamily, len(r.dimHashesByName))\n\tcheckedCollectors := make(chan Collector, len(r.collectorsByID))\n\tuncheckedCollectors := make(chan Collector, len(r.uncheckedCollectors))\n\tfor _, collector := range r.collectorsByID {\n\t\tcheckedCollectors <- collector\n\t}\n\tfor _, collector := range r.uncheckedCollectors {\n\t\tuncheckedCollectors <- collector\n\t}\n\t// In case pedantic checks are enabled, we have to copy the map before\n\t// giving up the RLock.\n\tif r.pedanticChecksEnabled {\n\t\tregisteredDescIDs = make(map[uint64]struct{}, len(r.descIDs))\n\t\tfor id := range r.descIDs {\n\t\t\tregisteredDescIDs[id] = struct{}{}\n\t\t}\n\t}\n\tr.mtx.RUnlock()\n\n\twg.Add(goroutineBudget)\n\n\tcollectWorker := func() {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase collector := <-checkedCollectors:\n\t\t\t\tcollector.Collect(checkedMetricChan)\n\t\t\tcase collector := <-uncheckedCollectors:\n\t\t\t\tcollector.Collect(uncheckedMetricChan)\n\t\t\tdefault:\n\t\t\t\treturn\n\t\t\t}\n\t\t\twg.Done()\n\t\t}\n\t}\n\n\t// Start the first worker now to make sure at least one is running.\n\tgo collectWorker()\n\tgoroutineBudget--\n\n\t// Close checkedMetricChan and uncheckedMetricChan once all collectors\n\t// are collected.\n\tgo func() {\n\t\twg.Wait()\n\t\tclose(checkedMetricChan)\n\t\tclose(uncheckedMetricChan)\n\t}()\n\n\t// Drain checkedMetricChan and uncheckedMetricChan in case of premature return.\n\tdefer func() {\n\t\tif checkedMetricChan != nil {\n\t\t\tfor range checkedMetricChan {\n\t\t\t}\n\t\t}\n\t\tif uncheckedMetricChan != nil {\n\t\t\tfor range uncheckedMetricChan {\n\t\t\t}\n\t\t}\n\t}()\n\n\t// Copy the channel references so we can nil them out later to remove\n\t// them from the select statements below.\n\tcmc := checkedMetricChan\n\tumc := uncheckedMetricChan\n\n\tfor {\n\t\tselect {\n\t\tcase metric, ok := <-cmc:\n\t\t\tif !ok {\n\t\t\t\tcmc = nil\n\t\t\t\tbreak\n\t\t\t}\n\t\t\terrs.Append(processMetric(\n\t\t\t\tmetric, metricFamiliesByName,\n\t\t\t\tmetricHashes,\n\t\t\t\tregisteredDescIDs,\n\t\t\t))\n\t\tcase metric, ok := <-umc:\n\t\t\tif !ok {\n\t\t\t\tumc = nil\n\t\t\t\tbreak\n\t\t\t}\n\t\t\terrs.Append(processMetric(\n\t\t\t\tmetric, metricFamiliesByName,\n\t\t\t\tmetricHashes,\n\t\t\t\tnil,\n\t\t\t))\n\t\tdefault:\n\t\t\tif goroutineBudget <= 0 || len(checkedCollectors)+len(uncheckedCollectors) == 0 {\n\t\t\t\t// All collectors are already being worked on or\n\t\t\t\t// we have already as many goroutines started as\n\t\t\t\t// there are collectors. Do the same as above,\n\t\t\t\t// just without the default.\n\t\t\t\tselect {\n\t\t\t\tcase metric, ok := <-cmc:\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\tcmc = nil\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\terrs.Append(processMetric(\n\t\t\t\t\t\tmetric, metricFamiliesByName,\n\t\t\t\t\t\tmetricHashes,\n\t\t\t\t\t\tregisteredDescIDs,\n\t\t\t\t\t))\n\t\t\t\tcase metric, ok := <-umc:\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\tumc = nil\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\terrs.Append(processMetric(\n\t\t\t\t\t\tmetric, metricFamiliesByName,\n\t\t\t\t\t\tmetricHashes,\n\t\t\t\t\t\tnil,\n\t\t\t\t\t))\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t// Start more workers.\n\t\t\tgo collectWorker()\n\t\t\tgoroutineBudget--\n\t\t\truntime.Gosched()\n\t\t}\n\t\t// Once both checkedMetricChan and uncheckedMetricChan are closed\n\t\t// and drained, the contraption above will nil out cmc and umc,\n\t\t// and then we can leave the collect loop here.\n\t\tif cmc == nil && umc == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn internal.NormalizeMetricFamilies(metricFamiliesByName), errs.MaybeUnwrap()\n}\n\n// Describe implements Collector.\nfunc (r *Registry) Describe(ch chan<- *Desc) {\n\tr.mtx.RLock()\n\tdefer r.mtx.RUnlock()\n\n\t// Only report the checked Collectors; unchecked collectors don't report any\n\t// Desc.\n\tfor _, c := range r.collectorsByID {\n\t\tc.Describe(ch)\n\t}\n}\n\n// Collect implements Collector.\nfunc (r *Registry) Collect(ch chan<- Metric) {\n\tr.mtx.RLock()\n\tdefer r.mtx.RUnlock()\n\n\tfor _, c := range r.collectorsByID {\n\t\tc.Collect(ch)\n\t}\n\tfor _, c := range r.uncheckedCollectors {\n\t\tc.Collect(ch)\n\t}\n}\n\n// WriteToTextfile calls Gather on the provided Gatherer, encodes the result in the\n// Prometheus text format, and writes it to a temporary file. Upon success, the\n// temporary file is renamed to the provided filename.\n//\n// This is intended for use with the textfile collector of the node exporter.\n// Note that the node exporter expects the filename to be suffixed with \".prom\".\nfunc WriteToTextfile(filename string, g Gatherer) error {\n\ttmp, err := os.CreateTemp(filepath.Dir(filename), filepath.Base(filename))\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer os.Remove(tmp.Name())\n\n\tmfs, err := g.Gather()\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor _, mf := range mfs {\n\t\tif _, err := expfmt.MetricFamilyToText(tmp, mf); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif err := tmp.Close(); err != nil {\n\t\treturn err\n\t}\n\n\tif err := os.Chmod(tmp.Name(), 0o644); err != nil {\n\t\treturn err\n\t}\n\treturn os.Rename(tmp.Name(), filename)\n}\n\n// processMetric is an internal helper method only used by the Gather method.\nfunc processMetric(\n\tmetric Metric,\n\tmetricFamiliesByName map[string]*dto.MetricFamily,\n\tmetricHashes map[uint64]struct{},\n\tregisteredDescIDs map[uint64]struct{},\n) error {\n\tdesc := metric.Desc()\n\t// Wrapped metrics collected by an unchecked Collector can have an\n\t// invalid Desc.\n\tif desc.err != nil {\n\t\treturn desc.err\n\t}\n\tdtoMetric := &dto.Metric{}\n\tif err := metric.Write(dtoMetric); err != nil {\n\t\treturn fmt.Errorf(\"error collecting metric %v: %w\", desc, err)\n\t}\n\tmetricFamily, ok := metricFamiliesByName[desc.fqName]\n\tif ok { // Existing name.\n\t\tif metricFamily.GetHelp() != desc.help {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"collected metric %s %s has help %q but should have %q\",\n\t\t\t\tdesc.fqName, dtoMetric, desc.help, metricFamily.GetHelp(),\n\t\t\t)\n\t\t}\n\t\t// TODO(beorn7): Simplify switch once Desc has type.\n\t\tswitch metricFamily.GetType() {\n\t\tcase dto.MetricType_COUNTER:\n\t\t\tif dtoMetric.Counter == nil {\n\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\"collected metric %s %s should be a Counter\",\n\t\t\t\t\tdesc.fqName, dtoMetric,\n\t\t\t\t)\n\t\t\t}\n\t\tcase dto.MetricType_GAUGE:\n\t\t\tif dtoMetric.Gauge == nil {\n\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\"collected metric %s %s should be a Gauge\",\n\t\t\t\t\tdesc.fqName, dtoMetric,\n\t\t\t\t)\n\t\t\t}\n\t\tcase dto.MetricType_SUMMARY:\n\t\t\tif dtoMetric.Summary == nil {\n\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\"collected metric %s %s should be a Summary\",\n\t\t\t\t\tdesc.fqName, dtoMetric,\n\t\t\t\t)\n\t\t\t}\n\t\tcase dto.MetricType_UNTYPED:\n\t\t\tif dtoMetric.Untyped == nil {\n\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\"collected metric %s %s should be Untyped\",\n\t\t\t\t\tdesc.fqName, dtoMetric,\n\t\t\t\t)\n\t\t\t}\n\t\tcase dto.MetricType_HISTOGRAM:\n\t\t\tif dtoMetric.Histogram == nil {\n\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\"collected metric %s %s should be a Histogram\",\n\t\t\t\t\tdesc.fqName, dtoMetric,\n\t\t\t\t)\n\t\t\t}\n\t\tdefault:\n\t\t\tpanic(\"encountered MetricFamily with invalid type\")\n\t\t}\n\t} else { // New name.\n\t\tmetricFamily = &dto.MetricFamily{}\n\t\tmetricFamily.Name = proto.String(desc.fqName)\n\t\tmetricFamily.Help = proto.String(desc.help)\n\t\t// TODO(beorn7): Simplify switch once Desc has type.\n\t\tswitch {\n\t\tcase dtoMetric.Gauge != nil:\n\t\t\tmetricFamily.Type = dto.MetricType_GAUGE.Enum()\n\t\tcase dtoMetric.Counter != nil:\n\t\t\tmetricFamily.Type = dto.MetricType_COUNTER.Enum()\n\t\tcase dtoMetric.Summary != nil:\n\t\t\tmetricFamily.Type = dto.MetricType_SUMMARY.Enum()\n\t\tcase dtoMetric.Untyped != nil:\n\t\t\tmetricFamily.Type = dto.MetricType_UNTYPED.Enum()\n\t\tcase dtoMetric.Histogram != nil:\n\t\t\tmetricFamily.Type = dto.MetricType_HISTOGRAM.Enum()\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"empty metric collected: %s\", dtoMetric)\n\t\t}\n\t\tif err := checkSuffixCollisions(metricFamily, metricFamiliesByName); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tmetricFamiliesByName[desc.fqName] = metricFamily\n\t}\n\tif err := checkMetricConsistency(metricFamily, dtoMetric, metricHashes); err != nil {\n\t\treturn err\n\t}\n\tif registeredDescIDs != nil {\n\t\t// Is the desc registered at all?\n\t\tif _, exist := registeredDescIDs[desc.id]; !exist {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"collected metric %s %s with unregistered descriptor %s\",\n\t\t\t\tmetricFamily.GetName(), dtoMetric, desc,\n\t\t\t)\n\t\t}\n\t\tif err := checkDescConsistency(metricFamily, dtoMetric, desc); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tmetricFamily.Metric = append(metricFamily.Metric, dtoMetric)\n\treturn nil\n}\n\n// Gatherers is a slice of Gatherer instances that implements the Gatherer\n// interface itself. Its Gather method calls Gather on all Gatherers in the\n// slice in order and returns the merged results. Errors returned from the\n// Gather calls are all returned in a flattened MultiError. Duplicate and\n// inconsistent Metrics are skipped (first occurrence in slice order wins) and\n// reported in the returned error.\n//\n// Gatherers can be used to merge the Gather results from multiple\n// Registries. It also provides a way to directly inject existing MetricFamily\n// protobufs into the gathering by creating a custom Gatherer with a Gather\n// method that simply returns the existing MetricFamily protobufs. Note that no\n// registration is involved (in contrast to Collector registration), so\n// obviously registration-time checks cannot happen. Any inconsistencies between\n// the gathered MetricFamilies are reported as errors by the Gather method, and\n// inconsistent Metrics are dropped. Invalid parts of the MetricFamilies\n// (e.g. syntactically invalid metric or label names) will go undetected.\ntype Gatherers []Gatherer\n\n// Gather implements Gatherer.\nfunc (gs Gatherers) Gather() ([]*dto.MetricFamily, error) {\n\tvar (\n\t\tmetricFamiliesByName = map[string]*dto.MetricFamily{}\n\t\tmetricHashes         = map[uint64]struct{}{}\n\t\terrs                 MultiError // The collected errors to return in the end.\n\t)\n\n\tfor i, g := range gs {\n\t\tmfs, err := g.Gather()\n\t\tif err != nil {\n\t\t\tmultiErr := MultiError{}\n\t\t\tif errors.As(err, &multiErr) {\n\t\t\t\tfor _, err := range multiErr {\n\t\t\t\t\terrs = append(errs, fmt.Errorf(\"[from Gatherer #%d] %w\", i+1, err))\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terrs = append(errs, fmt.Errorf(\"[from Gatherer #%d] %w\", i+1, err))\n\t\t\t}\n\t\t}\n\t\tfor _, mf := range mfs {\n\t\t\texistingMF, exists := metricFamiliesByName[mf.GetName()]\n\t\t\tif exists {\n\t\t\t\tif existingMF.GetHelp() != mf.GetHelp() {\n\t\t\t\t\terrs = append(errs, fmt.Errorf(\n\t\t\t\t\t\t\"gathered metric family %s has help %q but should have %q\",\n\t\t\t\t\t\tmf.GetName(), mf.GetHelp(), existingMF.GetHelp(),\n\t\t\t\t\t))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif existingMF.GetType() != mf.GetType() {\n\t\t\t\t\terrs = append(errs, fmt.Errorf(\n\t\t\t\t\t\t\"gathered metric family %s has type %s but should have %s\",\n\t\t\t\t\t\tmf.GetName(), mf.GetType(), existingMF.GetType(),\n\t\t\t\t\t))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\texistingMF = &dto.MetricFamily{}\n\t\t\t\texistingMF.Name = mf.Name\n\t\t\t\texistingMF.Help = mf.Help\n\t\t\t\texistingMF.Type = mf.Type\n\t\t\t\tif err := checkSuffixCollisions(existingMF, metricFamiliesByName); err != nil {\n\t\t\t\t\terrs = append(errs, err)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tmetricFamiliesByName[mf.GetName()] = existingMF\n\t\t\t}\n\t\t\tfor _, m := range mf.Metric {\n\t\t\t\tif err := checkMetricConsistency(existingMF, m, metricHashes); err != nil {\n\t\t\t\t\terrs = append(errs, err)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\texistingMF.Metric = append(existingMF.Metric, m)\n\t\t\t}\n\t\t}\n\t}\n\treturn internal.NormalizeMetricFamilies(metricFamiliesByName), errs.MaybeUnwrap()\n}\n\n// checkSuffixCollisions checks for collisions with the “magic” suffixes the\n// Prometheus text format and the internal metric representation of the\n// Prometheus server add while flattening Summaries and Histograms.\nfunc checkSuffixCollisions(mf *dto.MetricFamily, mfs map[string]*dto.MetricFamily) error {\n\tvar (\n\t\tnewName              = mf.GetName()\n\t\tnewType              = mf.GetType()\n\t\tnewNameWithoutSuffix = \"\"\n\t)\n\tswitch {\n\tcase strings.HasSuffix(newName, \"_count\"):\n\t\tnewNameWithoutSuffix = newName[:len(newName)-6]\n\tcase strings.HasSuffix(newName, \"_sum\"):\n\t\tnewNameWithoutSuffix = newName[:len(newName)-4]\n\tcase strings.HasSuffix(newName, \"_bucket\"):\n\t\tnewNameWithoutSuffix = newName[:len(newName)-7]\n\t}\n\tif newNameWithoutSuffix != \"\" {\n\t\tif existingMF, ok := mfs[newNameWithoutSuffix]; ok {\n\t\t\tswitch existingMF.GetType() {\n\t\t\tcase dto.MetricType_SUMMARY:\n\t\t\t\tif !strings.HasSuffix(newName, \"_bucket\") {\n\t\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\t\"collected metric named %q collides with previously collected summary named %q\",\n\t\t\t\t\t\tnewName, newNameWithoutSuffix,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\tcase dto.MetricType_HISTOGRAM:\n\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\"collected metric named %q collides with previously collected histogram named %q\",\n\t\t\t\t\tnewName, newNameWithoutSuffix,\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n\tif newType == dto.MetricType_SUMMARY || newType == dto.MetricType_HISTOGRAM {\n\t\tif _, ok := mfs[newName+\"_count\"]; ok {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"collected histogram or summary named %q collides with previously collected metric named %q\",\n\t\t\t\tnewName, newName+\"_count\",\n\t\t\t)\n\t\t}\n\t\tif _, ok := mfs[newName+\"_sum\"]; ok {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"collected histogram or summary named %q collides with previously collected metric named %q\",\n\t\t\t\tnewName, newName+\"_sum\",\n\t\t\t)\n\t\t}\n\t}\n\tif newType == dto.MetricType_HISTOGRAM {\n\t\tif _, ok := mfs[newName+\"_bucket\"]; ok {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"collected histogram named %q collides with previously collected metric named %q\",\n\t\t\t\tnewName, newName+\"_bucket\",\n\t\t\t)\n\t\t}\n\t}\n\treturn nil\n}\n\n// checkMetricConsistency checks if the provided Metric is consistent with the\n// provided MetricFamily. It also hashes the Metric labels and the MetricFamily\n// name. If the resulting hash is already in the provided metricHashes, an error\n// is returned. If not, it is added to metricHashes.\nfunc checkMetricConsistency(\n\tmetricFamily *dto.MetricFamily,\n\tdtoMetric *dto.Metric,\n\tmetricHashes map[uint64]struct{},\n) error {\n\tname := metricFamily.GetName()\n\n\t// Type consistency with metric family.\n\tif metricFamily.GetType() == dto.MetricType_GAUGE && dtoMetric.Gauge == nil ||\n\t\tmetricFamily.GetType() == dto.MetricType_COUNTER && dtoMetric.Counter == nil ||\n\t\tmetricFamily.GetType() == dto.MetricType_SUMMARY && dtoMetric.Summary == nil ||\n\t\tmetricFamily.GetType() == dto.MetricType_HISTOGRAM && dtoMetric.Histogram == nil ||\n\t\tmetricFamily.GetType() == dto.MetricType_UNTYPED && dtoMetric.Untyped == nil {\n\t\treturn fmt.Errorf(\n\t\t\t\"collected metric %q { %s} is not a %s\",\n\t\t\tname, dtoMetric, metricFamily.GetType(),\n\t\t)\n\t}\n\n\tpreviousLabelName := \"\"\n\tfor _, labelPair := range dtoMetric.GetLabel() {\n\t\tlabelName := labelPair.GetName()\n\t\tif labelName == previousLabelName {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"collected metric %q { %s} has two or more labels with the same name: %s\",\n\t\t\t\tname, dtoMetric, labelName,\n\t\t\t)\n\t\t}\n\t\tif !checkLabelName(labelName) {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"collected metric %q { %s} has a label with an invalid name: %s\",\n\t\t\t\tname, dtoMetric, labelName,\n\t\t\t)\n\t\t}\n\t\tif dtoMetric.Summary != nil && labelName == quantileLabel {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"collected metric %q { %s} must not have an explicit %q label\",\n\t\t\t\tname, dtoMetric, quantileLabel,\n\t\t\t)\n\t\t}\n\t\tif !utf8.ValidString(labelPair.GetValue()) {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"collected metric %q { %s} has a label named %q whose value is not utf8: %#v\",\n\t\t\t\tname, dtoMetric, labelName, labelPair.GetValue())\n\t\t}\n\t\tpreviousLabelName = labelName\n\t}\n\n\t// Is the metric unique (i.e. no other metric with the same name and the same labels)?\n\th := xxhash.New()\n\th.WriteString(name)\n\th.Write(separatorByteSlice)\n\t// Make sure label pairs are sorted. We depend on it for the consistency\n\t// check.\n\tif !sort.IsSorted(internal.LabelPairSorter(dtoMetric.Label)) {\n\t\t// We cannot sort dtoMetric.Label in place as it is immutable by contract.\n\t\tcopiedLabels := make([]*dto.LabelPair, len(dtoMetric.Label))\n\t\tcopy(copiedLabels, dtoMetric.Label)\n\t\tsort.Sort(internal.LabelPairSorter(copiedLabels))\n\t\tdtoMetric.Label = copiedLabels\n\t}\n\tfor _, lp := range dtoMetric.Label {\n\t\th.WriteString(lp.GetName())\n\t\th.Write(separatorByteSlice)\n\t\th.WriteString(lp.GetValue())\n\t\th.Write(separatorByteSlice)\n\t}\n\tif dtoMetric.TimestampMs != nil {\n\t\th.WriteString(strconv.FormatInt(*(dtoMetric.TimestampMs), 10))\n\t\th.Write(separatorByteSlice)\n\t}\n\thSum := h.Sum64()\n\tif _, exists := metricHashes[hSum]; exists {\n\t\treturn fmt.Errorf(\n\t\t\t\"collected metric %q { %s} was collected before with the same name and label values\",\n\t\t\tname, dtoMetric,\n\t\t)\n\t}\n\tmetricHashes[hSum] = struct{}{}\n\treturn nil\n}\n\nfunc checkDescConsistency(\n\tmetricFamily *dto.MetricFamily,\n\tdtoMetric *dto.Metric,\n\tdesc *Desc,\n) error {\n\t// Desc help consistency with metric family help.\n\tif metricFamily.GetHelp() != desc.help {\n\t\treturn fmt.Errorf(\n\t\t\t\"collected metric %s %s has help %q but should have %q\",\n\t\t\tmetricFamily.GetName(), dtoMetric, metricFamily.GetHelp(), desc.help,\n\t\t)\n\t}\n\n\t// Is the desc consistent with the content of the metric?\n\tlpsFromDesc := make([]*dto.LabelPair, len(desc.constLabelPairs), len(dtoMetric.Label))\n\tcopy(lpsFromDesc, desc.constLabelPairs)\n\tfor _, l := range desc.variableLabels.names {\n\t\tlpsFromDesc = append(lpsFromDesc, &dto.LabelPair{\n\t\t\tName: proto.String(l),\n\t\t})\n\t}\n\tif len(lpsFromDesc) != len(dtoMetric.Label) {\n\t\treturn fmt.Errorf(\n\t\t\t\"labels in collected metric %s %s are inconsistent with descriptor %s\",\n\t\t\tmetricFamily.GetName(), dtoMetric, desc,\n\t\t)\n\t}\n\tsort.Sort(internal.LabelPairSorter(lpsFromDesc))\n\tfor i, lpFromDesc := range lpsFromDesc {\n\t\tlpFromMetric := dtoMetric.Label[i]\n\t\tif lpFromDesc.GetName() != lpFromMetric.GetName() ||\n\t\t\tlpFromDesc.Value != nil && lpFromDesc.GetValue() != lpFromMetric.GetValue() {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"labels in collected metric %s %s are inconsistent with descriptor %s\",\n\t\t\t\tmetricFamily.GetName(), dtoMetric, desc,\n\t\t\t)\n\t\t}\n\t}\n\treturn nil\n}\n\nvar _ TransactionalGatherer = &MultiTRegistry{}\n\n// MultiTRegistry is a TransactionalGatherer that joins gathered metrics from multiple\n// transactional gatherers.\n//\n// It is caller responsibility to ensure two registries have mutually exclusive metric families,\n// no deduplication will happen.\ntype MultiTRegistry struct {\n\ttGatherers []TransactionalGatherer\n}\n\n// NewMultiTRegistry creates MultiTRegistry.\nfunc NewMultiTRegistry(tGatherers ...TransactionalGatherer) *MultiTRegistry {\n\treturn &MultiTRegistry{\n\t\ttGatherers: tGatherers,\n\t}\n}\n\n// Gather implements TransactionalGatherer interface.\nfunc (r *MultiTRegistry) Gather() (mfs []*dto.MetricFamily, done func(), err error) {\n\terrs := MultiError{}\n\n\tdFns := make([]func(), 0, len(r.tGatherers))\n\t// TODO(bwplotka): Implement concurrency for those?\n\tfor _, g := range r.tGatherers {\n\t\t// TODO(bwplotka): Check for duplicates?\n\t\tm, d, err := g.Gather()\n\t\terrs.Append(err)\n\n\t\tmfs = append(mfs, m...)\n\t\tdFns = append(dFns, d)\n\t}\n\n\t// TODO(bwplotka): Consider sort in place, given metric family in gather is sorted already.\n\tsort.Slice(mfs, func(i, j int) bool {\n\t\treturn *mfs[i].Name < *mfs[j].Name\n\t})\n\treturn mfs, func() {\n\t\tfor _, d := range dFns {\n\t\t\td()\n\t\t}\n\t}, errs.MaybeUnwrap()\n}\n\n// TransactionalGatherer represents transactional gatherer that can be triggered to notify gatherer that memory\n// used by metric family is no longer used by a caller. This allows implementations with cache.\ntype TransactionalGatherer interface {\n\t// Gather returns metrics in a lexicographically sorted slice\n\t// of uniquely named MetricFamily protobufs. Gather ensures that the\n\t// returned slice is valid and self-consistent so that it can be used\n\t// for valid exposition. As an exception to the strict consistency\n\t// requirements described for metric.Desc, Gather will tolerate\n\t// different sets of label names for metrics of the same metric family.\n\t//\n\t// Even if an error occurs, Gather attempts to gather as many metrics as\n\t// possible. Hence, if a non-nil error is returned, the returned\n\t// MetricFamily slice could be nil (in case of a fatal error that\n\t// prevented any meaningful metric collection) or contain a number of\n\t// MetricFamily protobufs, some of which might be incomplete, and some\n\t// might be missing altogether. The returned error (which might be a\n\t// MultiError) explains the details. Note that this is mostly useful for\n\t// debugging purposes. If the gathered protobufs are to be used for\n\t// exposition in actual monitoring, it is almost always better to not\n\t// expose an incomplete result and instead disregard the returned\n\t// MetricFamily protobufs in case the returned error is non-nil.\n\t//\n\t// Important: done is expected to be triggered (even if the error occurs!)\n\t// once caller does not need returned slice of dto.MetricFamily.\n\tGather() (_ []*dto.MetricFamily, done func(), err error)\n}\n\n// ToTransactionalGatherer transforms Gatherer to transactional one with noop as done function.\nfunc ToTransactionalGatherer(g Gatherer) TransactionalGatherer {\n\treturn &noTransactionGatherer{g: g}\n}\n\ntype noTransactionGatherer struct {\n\tg Gatherer\n}\n\n// Gather implements TransactionalGatherer interface.\nfunc (g *noTransactionGatherer) Gather() (_ []*dto.MetricFamily, done func(), err error) {\n\tmfs, err := g.g.Gather()\n\treturn mfs, func() {}, err\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/summary.go",
    "content": "// Copyright 2014 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"runtime\"\n\t\"sort\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\tdto \"github.com/prometheus/client_model/go\"\n\n\t\"github.com/beorn7/perks/quantile\"\n\t\"google.golang.org/protobuf/proto\"\n\t\"google.golang.org/protobuf/types/known/timestamppb\"\n)\n\n// quantileLabel is used for the label that defines the quantile in a\n// summary.\nconst quantileLabel = \"quantile\"\n\n// A Summary captures individual observations from an event or sample stream and\n// summarizes them in a manner similar to traditional summary statistics: 1. sum\n// of observations, 2. observation count, 3. rank estimations.\n//\n// A typical use-case is the observation of request latencies. By default, a\n// Summary provides the median, the 90th and the 99th percentile of the latency\n// as rank estimations. However, the default behavior will change in the\n// upcoming v1.0.0 of the library. There will be no rank estimations at all by\n// default. For a sane transition, it is recommended to set the desired rank\n// estimations explicitly.\n//\n// Note that the rank estimations cannot be aggregated in a meaningful way with\n// the Prometheus query language (i.e. you cannot average or add them). If you\n// need aggregatable quantiles (e.g. you want the 99th percentile latency of all\n// queries served across all instances of a service), consider the Histogram\n// metric type. See the Prometheus documentation for more details.\n//\n// To create Summary instances, use NewSummary.\ntype Summary interface {\n\tMetric\n\tCollector\n\n\t// Observe adds a single observation to the summary. Observations are\n\t// usually positive or zero. Negative observations are accepted but\n\t// prevent current versions of Prometheus from properly detecting\n\t// counter resets in the sum of observations. See\n\t// https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations\n\t// for details.\n\tObserve(float64)\n}\n\nvar errQuantileLabelNotAllowed = fmt.Errorf(\n\t\"%q is not allowed as label name in summaries\", quantileLabel,\n)\n\n// Default values for SummaryOpts.\nconst (\n\t// DefMaxAge is the default duration for which observations stay\n\t// relevant.\n\tDefMaxAge time.Duration = 10 * time.Minute\n\t// DefAgeBuckets is the default number of buckets used to calculate the\n\t// age of observations.\n\tDefAgeBuckets = 5\n\t// DefBufCap is the standard buffer size for collecting Summary observations.\n\tDefBufCap = 500\n)\n\n// SummaryOpts bundles the options for creating a Summary metric. It is\n// mandatory to set Name to a non-empty string. While all other fields are\n// optional and can safely be left at their zero value, it is recommended to set\n// a help string and to explicitly set the Objectives field to the desired value\n// as the default value will change in the upcoming v1.0.0 of the library.\ntype SummaryOpts struct {\n\t// Namespace, Subsystem, and Name are components of the fully-qualified\n\t// name of the Summary (created by joining these components with\n\t// \"_\"). Only Name is mandatory, the others merely help structuring the\n\t// name. Note that the fully-qualified name of the Summary must be a\n\t// valid Prometheus metric name.\n\tNamespace string\n\tSubsystem string\n\tName      string\n\n\t// Help provides information about this Summary.\n\t//\n\t// Metrics with the same fully-qualified name must have the same Help\n\t// string.\n\tHelp string\n\n\t// ConstLabels are used to attach fixed labels to this metric. Metrics\n\t// with the same fully-qualified name must have the same label names in\n\t// their ConstLabels.\n\t//\n\t// Due to the way a Summary is represented in the Prometheus text format\n\t// and how it is handled by the Prometheus server internally, “quantile”\n\t// is an illegal label name. Construction of a Summary or SummaryVec\n\t// will panic if this label name is used in ConstLabels.\n\t//\n\t// ConstLabels are only used rarely. In particular, do not use them to\n\t// attach the same labels to all your metrics. Those use cases are\n\t// better covered by target labels set by the scraping Prometheus\n\t// server, or by one specific metric (e.g. a build_info or a\n\t// machine_role metric). See also\n\t// https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels\n\tConstLabels Labels\n\n\t// Objectives defines the quantile rank estimates with their respective\n\t// absolute error. If Objectives[q] = e, then the value reported for q\n\t// will be the φ-quantile value for some φ between q-e and q+e.  The\n\t// default value is an empty map, resulting in a summary without\n\t// quantiles.\n\tObjectives map[float64]float64\n\n\t// MaxAge defines the duration for which an observation stays relevant\n\t// for the summary. Only applies to pre-calculated quantiles, does not\n\t// apply to _sum and _count. Must be positive. The default value is\n\t// DefMaxAge.\n\tMaxAge time.Duration\n\n\t// AgeBuckets is the number of buckets used to exclude observations that\n\t// are older than MaxAge from the summary. A higher number has a\n\t// resource penalty, so only increase it if the higher resolution is\n\t// really required. For very high observation rates, you might want to\n\t// reduce the number of age buckets. With only one age bucket, you will\n\t// effectively see a complete reset of the summary each time MaxAge has\n\t// passed. The default value is DefAgeBuckets.\n\tAgeBuckets uint32\n\n\t// BufCap defines the default sample stream buffer size.  The default\n\t// value of DefBufCap should suffice for most uses. If there is a need\n\t// to increase the value, a multiple of 500 is recommended (because that\n\t// is the internal buffer size of the underlying package\n\t// \"github.com/bmizerany/perks/quantile\").\n\tBufCap uint32\n\n\t// now is for testing purposes, by default it's time.Now.\n\tnow func() time.Time\n}\n\n// SummaryVecOpts bundles the options to create a SummaryVec metric.\n// It is mandatory to set SummaryOpts, see there for mandatory fields. VariableLabels\n// is optional and can safely be left to its default value.\ntype SummaryVecOpts struct {\n\tSummaryOpts\n\n\t// VariableLabels are used to partition the metric vector by the given set\n\t// of labels. Each label value will be constrained with the optional Constraint\n\t// function, if provided.\n\tVariableLabels ConstrainableLabels\n}\n\n// Problem with the sliding-window decay algorithm... The Merge method of\n// perk/quantile is actually not working as advertised - and it might be\n// unfixable, as the underlying algorithm is apparently not capable of merging\n// summaries in the first place. To avoid using Merge, we are currently adding\n// observations to _each_ age bucket, i.e. the effort to add a sample is\n// essentially multiplied by the number of age buckets. When rotating age\n// buckets, we empty the previous head stream. On scrape time, we simply take\n// the quantiles from the head stream (no merging required). Result: More effort\n// on observation time, less effort on scrape time, which is exactly the\n// opposite of what we try to accomplish, but at least the results are correct.\n//\n// The quite elegant previous contraption to merge the age buckets efficiently\n// on scrape time (see code up commit 6b9530d72ea715f0ba612c0120e6e09fbf1d49d0)\n// can't be used anymore.\n\n// NewSummary creates a new Summary based on the provided SummaryOpts.\nfunc NewSummary(opts SummaryOpts) Summary {\n\treturn newSummary(\n\t\tNewDesc(\n\t\t\tBuildFQName(opts.Namespace, opts.Subsystem, opts.Name),\n\t\t\topts.Help,\n\t\t\tnil,\n\t\t\topts.ConstLabels,\n\t\t),\n\t\topts,\n\t)\n}\n\nfunc newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {\n\tif len(desc.variableLabels.names) != len(labelValues) {\n\t\tpanic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, labelValues))\n\t}\n\n\tfor _, n := range desc.variableLabels.names {\n\t\tif n == quantileLabel {\n\t\t\tpanic(errQuantileLabelNotAllowed)\n\t\t}\n\t}\n\tfor _, lp := range desc.constLabelPairs {\n\t\tif lp.GetName() == quantileLabel {\n\t\t\tpanic(errQuantileLabelNotAllowed)\n\t\t}\n\t}\n\n\tif opts.Objectives == nil {\n\t\topts.Objectives = map[float64]float64{}\n\t}\n\n\tif opts.MaxAge < 0 {\n\t\tpanic(fmt.Errorf(\"illegal max age MaxAge=%v\", opts.MaxAge))\n\t}\n\tif opts.MaxAge == 0 {\n\t\topts.MaxAge = DefMaxAge\n\t}\n\n\tif opts.AgeBuckets == 0 {\n\t\topts.AgeBuckets = DefAgeBuckets\n\t}\n\n\tif opts.BufCap == 0 {\n\t\topts.BufCap = DefBufCap\n\t}\n\n\tif opts.now == nil {\n\t\topts.now = time.Now\n\t}\n\tif len(opts.Objectives) == 0 {\n\t\t// Use the lock-free implementation of a Summary without objectives.\n\t\ts := &noObjectivesSummary{\n\t\t\tdesc:       desc,\n\t\t\tlabelPairs: MakeLabelPairs(desc, labelValues),\n\t\t\tcounts:     [2]*summaryCounts{{}, {}},\n\t\t}\n\t\ts.init(s) // Init self-collection.\n\t\ts.createdTs = timestamppb.New(opts.now())\n\t\treturn s\n\t}\n\n\ts := &summary{\n\t\tdesc: desc,\n\t\tnow:  opts.now,\n\n\t\tobjectives:       opts.Objectives,\n\t\tsortedObjectives: make([]float64, 0, len(opts.Objectives)),\n\n\t\tlabelPairs: MakeLabelPairs(desc, labelValues),\n\n\t\thotBuf:         make([]float64, 0, opts.BufCap),\n\t\tcoldBuf:        make([]float64, 0, opts.BufCap),\n\t\tstreamDuration: opts.MaxAge / time.Duration(opts.AgeBuckets),\n\t}\n\ts.headStreamExpTime = opts.now().Add(s.streamDuration)\n\ts.hotBufExpTime = s.headStreamExpTime\n\n\tfor i := uint32(0); i < opts.AgeBuckets; i++ {\n\t\ts.streams = append(s.streams, s.newStream())\n\t}\n\ts.headStream = s.streams[0]\n\n\tfor qu := range s.objectives {\n\t\ts.sortedObjectives = append(s.sortedObjectives, qu)\n\t}\n\tsort.Float64s(s.sortedObjectives)\n\n\ts.init(s) // Init self-collection.\n\ts.createdTs = timestamppb.New(opts.now())\n\treturn s\n}\n\ntype summary struct {\n\tselfCollector\n\n\tbufMtx sync.Mutex // Protects hotBuf and hotBufExpTime.\n\tmtx    sync.Mutex // Protects every other moving part.\n\t// Lock bufMtx before mtx if both are needed.\n\n\tdesc *Desc\n\n\tnow func() time.Time\n\n\tobjectives       map[float64]float64\n\tsortedObjectives []float64\n\n\tlabelPairs []*dto.LabelPair\n\n\tsum float64\n\tcnt uint64\n\n\thotBuf, coldBuf []float64\n\n\tstreams                          []*quantile.Stream\n\tstreamDuration                   time.Duration\n\theadStream                       *quantile.Stream\n\theadStreamIdx                    int\n\theadStreamExpTime, hotBufExpTime time.Time\n\n\tcreatedTs *timestamppb.Timestamp\n}\n\nfunc (s *summary) Desc() *Desc {\n\treturn s.desc\n}\n\nfunc (s *summary) Observe(v float64) {\n\ts.bufMtx.Lock()\n\tdefer s.bufMtx.Unlock()\n\n\tnow := s.now()\n\tif now.After(s.hotBufExpTime) {\n\t\ts.asyncFlush(now)\n\t}\n\ts.hotBuf = append(s.hotBuf, v)\n\tif len(s.hotBuf) == cap(s.hotBuf) {\n\t\ts.asyncFlush(now)\n\t}\n}\n\nfunc (s *summary) Write(out *dto.Metric) error {\n\tsum := &dto.Summary{\n\t\tCreatedTimestamp: s.createdTs,\n\t}\n\tqs := make([]*dto.Quantile, 0, len(s.objectives))\n\n\ts.bufMtx.Lock()\n\ts.mtx.Lock()\n\t// Swap bufs even if hotBuf is empty to set new hotBufExpTime.\n\ts.swapBufs(s.now())\n\ts.bufMtx.Unlock()\n\n\ts.flushColdBuf()\n\tsum.SampleCount = proto.Uint64(s.cnt)\n\tsum.SampleSum = proto.Float64(s.sum)\n\n\tfor _, rank := range s.sortedObjectives {\n\t\tvar q float64\n\t\tif s.headStream.Count() == 0 {\n\t\t\tq = math.NaN()\n\t\t} else {\n\t\t\tq = s.headStream.Query(rank)\n\t\t}\n\t\tqs = append(qs, &dto.Quantile{\n\t\t\tQuantile: proto.Float64(rank),\n\t\t\tValue:    proto.Float64(q),\n\t\t})\n\t}\n\n\ts.mtx.Unlock()\n\n\tif len(qs) > 0 {\n\t\tsort.Sort(quantSort(qs))\n\t}\n\tsum.Quantile = qs\n\n\tout.Summary = sum\n\tout.Label = s.labelPairs\n\treturn nil\n}\n\nfunc (s *summary) newStream() *quantile.Stream {\n\treturn quantile.NewTargeted(s.objectives)\n}\n\n// asyncFlush needs bufMtx locked.\nfunc (s *summary) asyncFlush(now time.Time) {\n\ts.mtx.Lock()\n\ts.swapBufs(now)\n\n\t// Unblock the original goroutine that was responsible for the mutation\n\t// that triggered the compaction.  But hold onto the global non-buffer\n\t// state mutex until the operation finishes.\n\tgo func() {\n\t\ts.flushColdBuf()\n\t\ts.mtx.Unlock()\n\t}()\n}\n\n// rotateStreams needs mtx AND bufMtx locked.\nfunc (s *summary) maybeRotateStreams() {\n\tfor !s.hotBufExpTime.Equal(s.headStreamExpTime) {\n\t\ts.headStream.Reset()\n\t\ts.headStreamIdx++\n\t\tif s.headStreamIdx >= len(s.streams) {\n\t\t\ts.headStreamIdx = 0\n\t\t}\n\t\ts.headStream = s.streams[s.headStreamIdx]\n\t\ts.headStreamExpTime = s.headStreamExpTime.Add(s.streamDuration)\n\t}\n}\n\n// flushColdBuf needs mtx locked.\nfunc (s *summary) flushColdBuf() {\n\tfor _, v := range s.coldBuf {\n\t\tfor _, stream := range s.streams {\n\t\t\tstream.Insert(v)\n\t\t}\n\t\ts.cnt++\n\t\ts.sum += v\n\t}\n\ts.coldBuf = s.coldBuf[0:0]\n\ts.maybeRotateStreams()\n}\n\n// swapBufs needs mtx AND bufMtx locked, coldBuf must be empty.\nfunc (s *summary) swapBufs(now time.Time) {\n\tif len(s.coldBuf) != 0 {\n\t\tpanic(\"coldBuf is not empty\")\n\t}\n\ts.hotBuf, s.coldBuf = s.coldBuf, s.hotBuf\n\t// hotBuf is now empty and gets new expiration set.\n\tfor now.After(s.hotBufExpTime) {\n\t\ts.hotBufExpTime = s.hotBufExpTime.Add(s.streamDuration)\n\t}\n}\n\ntype summaryCounts struct {\n\t// sumBits contains the bits of the float64 representing the sum of all\n\t// observations. sumBits and count have to go first in the struct to\n\t// guarantee alignment for atomic operations.\n\t// http://golang.org/pkg/sync/atomic/#pkg-note-BUG\n\tsumBits uint64\n\tcount   uint64\n}\n\ntype noObjectivesSummary struct {\n\t// countAndHotIdx enables lock-free writes with use of atomic updates.\n\t// The most significant bit is the hot index [0 or 1] of the count field\n\t// below. Observe calls update the hot one. All remaining bits count the\n\t// number of Observe calls. Observe starts by incrementing this counter,\n\t// and finish by incrementing the count field in the respective\n\t// summaryCounts, as a marker for completion.\n\t//\n\t// Calls of the Write method (which are non-mutating reads from the\n\t// perspective of the summary) swap the hot–cold under the writeMtx\n\t// lock. A cooldown is awaited (while locked) by comparing the number of\n\t// observations with the initiation count. Once they match, then the\n\t// last observation on the now cool one has completed. All cool fields must\n\t// be merged into the new hot before releasing writeMtx.\n\n\t// Fields with atomic access first! See alignment constraint:\n\t// http://golang.org/pkg/sync/atomic/#pkg-note-BUG\n\tcountAndHotIdx uint64\n\n\tselfCollector\n\tdesc     *Desc\n\twriteMtx sync.Mutex // Only used in the Write method.\n\n\t// Two counts, one is \"hot\" for lock-free observations, the other is\n\t// \"cold\" for writing out a dto.Metric. It has to be an array of\n\t// pointers to guarantee 64bit alignment of the histogramCounts, see\n\t// http://golang.org/pkg/sync/atomic/#pkg-note-BUG.\n\tcounts [2]*summaryCounts\n\n\tlabelPairs []*dto.LabelPair\n\n\tcreatedTs *timestamppb.Timestamp\n}\n\nfunc (s *noObjectivesSummary) Desc() *Desc {\n\treturn s.desc\n}\n\nfunc (s *noObjectivesSummary) Observe(v float64) {\n\t// We increment h.countAndHotIdx so that the counter in the lower\n\t// 63 bits gets incremented. At the same time, we get the new value\n\t// back, which we can use to find the currently-hot counts.\n\tn := atomic.AddUint64(&s.countAndHotIdx, 1)\n\thotCounts := s.counts[n>>63]\n\n\tfor {\n\t\toldBits := atomic.LoadUint64(&hotCounts.sumBits)\n\t\tnewBits := math.Float64bits(math.Float64frombits(oldBits) + v)\n\t\tif atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) {\n\t\t\tbreak\n\t\t}\n\t}\n\t// Increment count last as we take it as a signal that the observation\n\t// is complete.\n\tatomic.AddUint64(&hotCounts.count, 1)\n}\n\nfunc (s *noObjectivesSummary) Write(out *dto.Metric) error {\n\t// For simplicity, we protect this whole method by a mutex. It is not in\n\t// the hot path, i.e. Observe is called much more often than Write. The\n\t// complication of making Write lock-free isn't worth it, if possible at\n\t// all.\n\ts.writeMtx.Lock()\n\tdefer s.writeMtx.Unlock()\n\n\t// Adding 1<<63 switches the hot index (from 0 to 1 or from 1 to 0)\n\t// without touching the count bits. See the struct comments for a full\n\t// description of the algorithm.\n\tn := atomic.AddUint64(&s.countAndHotIdx, 1<<63)\n\t// count is contained unchanged in the lower 63 bits.\n\tcount := n & ((1 << 63) - 1)\n\t// The most significant bit tells us which counts is hot. The complement\n\t// is thus the cold one.\n\thotCounts := s.counts[n>>63]\n\tcoldCounts := s.counts[(^n)>>63]\n\n\t// Await cooldown.\n\tfor count != atomic.LoadUint64(&coldCounts.count) {\n\t\truntime.Gosched() // Let observations get work done.\n\t}\n\n\tsum := &dto.Summary{\n\t\tSampleCount:      proto.Uint64(count),\n\t\tSampleSum:        proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits))),\n\t\tCreatedTimestamp: s.createdTs,\n\t}\n\n\tout.Summary = sum\n\tout.Label = s.labelPairs\n\n\t// Finally add all the cold counts to the new hot counts and reset the cold counts.\n\tatomic.AddUint64(&hotCounts.count, count)\n\tatomic.StoreUint64(&coldCounts.count, 0)\n\tfor {\n\t\toldBits := atomic.LoadUint64(&hotCounts.sumBits)\n\t\tnewBits := math.Float64bits(math.Float64frombits(oldBits) + sum.GetSampleSum())\n\t\tif atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) {\n\t\t\tatomic.StoreUint64(&coldCounts.sumBits, 0)\n\t\t\tbreak\n\t\t}\n\t}\n\treturn nil\n}\n\ntype quantSort []*dto.Quantile\n\nfunc (s quantSort) Len() int {\n\treturn len(s)\n}\n\nfunc (s quantSort) Swap(i, j int) {\n\ts[i], s[j] = s[j], s[i]\n}\n\nfunc (s quantSort) Less(i, j int) bool {\n\treturn s[i].GetQuantile() < s[j].GetQuantile()\n}\n\n// SummaryVec is a Collector that bundles a set of Summaries that all share the\n// same Desc, but have different values for their variable labels. This is used\n// if you want to count the same thing partitioned by various dimensions\n// (e.g. HTTP request latencies, partitioned by status code and method). Create\n// instances with NewSummaryVec.\ntype SummaryVec struct {\n\t*MetricVec\n}\n\n// NewSummaryVec creates a new SummaryVec based on the provided SummaryOpts and\n// partitioned by the given label names.\n//\n// Due to the way a Summary is represented in the Prometheus text format and how\n// it is handled by the Prometheus server internally, “quantile” is an illegal\n// label name. NewSummaryVec will panic if this label name is used.\nfunc NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec {\n\treturn V2.NewSummaryVec(SummaryVecOpts{\n\t\tSummaryOpts:    opts,\n\t\tVariableLabels: UnconstrainedLabels(labelNames),\n\t})\n}\n\n// NewSummaryVec creates a new SummaryVec based on the provided SummaryVecOpts.\nfunc (v2) NewSummaryVec(opts SummaryVecOpts) *SummaryVec {\n\tfor _, ln := range opts.VariableLabels.labelNames() {\n\t\tif ln == quantileLabel {\n\t\t\tpanic(errQuantileLabelNotAllowed)\n\t\t}\n\t}\n\tdesc := V2.NewDesc(\n\t\tBuildFQName(opts.Namespace, opts.Subsystem, opts.Name),\n\t\topts.Help,\n\t\topts.VariableLabels,\n\t\topts.ConstLabels,\n\t)\n\treturn &SummaryVec{\n\t\tMetricVec: NewMetricVec(desc, func(lvs ...string) Metric {\n\t\t\treturn newSummary(desc, opts.SummaryOpts, lvs...)\n\t\t}),\n\t}\n}\n\n// GetMetricWithLabelValues returns the Summary for the given slice of label\n// values (same order as the variable labels in Desc). If that combination of\n// label values is accessed for the first time, a new Summary is created.\n//\n// It is possible to call this method without using the returned Summary to only\n// create the new Summary but leave it at its starting value, a Summary without\n// any observations.\n//\n// Keeping the Summary for later use is possible (and should be considered if\n// performance is critical), but keep in mind that Reset, DeleteLabelValues and\n// Delete can be used to delete the Summary from the SummaryVec. In that case,\n// the Summary will still exist, but it will not be exported anymore, even if a\n// Summary with the same label values is created later. See also the CounterVec\n// example.\n//\n// An error is returned if the number of label values is not the same as the\n// number of variable labels in Desc (minus any curried labels).\n//\n// Note that for more than one label value, this method is prone to mistakes\n// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as\n// an alternative to avoid that type of mistake. For higher label numbers, the\n// latter has a much more readable (albeit more verbose) syntax, but it comes\n// with a performance overhead (for creating and processing the Labels map).\n// See also the GaugeVec example.\nfunc (v *SummaryVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) {\n\tmetric, err := v.MetricVec.GetMetricWithLabelValues(lvs...)\n\tif metric != nil {\n\t\treturn metric.(Observer), err\n\t}\n\treturn nil, err\n}\n\n// GetMetricWith returns the Summary for the given Labels map (the label names\n// must match those of the variable labels in Desc). If that label map is\n// accessed for the first time, a new Summary is created. Implications of\n// creating a Summary without using it and keeping the Summary for later use are\n// the same as for GetMetricWithLabelValues.\n//\n// An error is returned if the number and names of the Labels are inconsistent\n// with those of the variable labels in Desc (minus any curried labels).\n//\n// This method is used for the same purpose as\n// GetMetricWithLabelValues(...string). See there for pros and cons of the two\n// methods.\nfunc (v *SummaryVec) GetMetricWith(labels Labels) (Observer, error) {\n\tmetric, err := v.MetricVec.GetMetricWith(labels)\n\tif metric != nil {\n\t\treturn metric.(Observer), err\n\t}\n\treturn nil, err\n}\n\n// WithLabelValues works as GetMetricWithLabelValues, but panics where\n// GetMetricWithLabelValues would have returned an error. Not returning an\n// error allows shortcuts like\n//\n//\tmyVec.WithLabelValues(\"404\", \"GET\").Observe(42.21)\nfunc (v *SummaryVec) WithLabelValues(lvs ...string) Observer {\n\ts, err := v.GetMetricWithLabelValues(lvs...)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn s\n}\n\n// With works as GetMetricWith, but panics where GetMetricWithLabels would have\n// returned an error. Not returning an error allows shortcuts like\n//\n//\tmyVec.With(prometheus.Labels{\"code\": \"404\", \"method\": \"GET\"}).Observe(42.21)\nfunc (v *SummaryVec) With(labels Labels) Observer {\n\ts, err := v.GetMetricWith(labels)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn s\n}\n\n// CurryWith returns a vector curried with the provided labels, i.e. the\n// returned vector has those labels pre-set for all labeled operations performed\n// on it. The cardinality of the curried vector is reduced accordingly. The\n// order of the remaining labels stays the same (just with the curried labels\n// taken out of the sequence – which is relevant for the\n// (GetMetric)WithLabelValues methods). It is possible to curry a curried\n// vector, but only with labels not yet used for currying before.\n//\n// The metrics contained in the SummaryVec are shared between the curried and\n// uncurried vectors. They are just accessed differently. Curried and uncurried\n// vectors behave identically in terms of collection. Only one must be\n// registered with a given registry (usually the uncurried version). The Reset\n// method deletes all metrics, even if called on a curried vector.\nfunc (v *SummaryVec) CurryWith(labels Labels) (ObserverVec, error) {\n\tvec, err := v.MetricVec.CurryWith(labels)\n\tif vec != nil {\n\t\treturn &SummaryVec{vec}, err\n\t}\n\treturn nil, err\n}\n\n// MustCurryWith works as CurryWith but panics where CurryWith would have\n// returned an error.\nfunc (v *SummaryVec) MustCurryWith(labels Labels) ObserverVec {\n\tvec, err := v.CurryWith(labels)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn vec\n}\n\ntype constSummary struct {\n\tdesc       *Desc\n\tcount      uint64\n\tsum        float64\n\tquantiles  map[float64]float64\n\tlabelPairs []*dto.LabelPair\n\tcreatedTs  *timestamppb.Timestamp\n}\n\nfunc (s *constSummary) Desc() *Desc {\n\treturn s.desc\n}\n\nfunc (s *constSummary) Write(out *dto.Metric) error {\n\tsum := &dto.Summary{\n\t\tCreatedTimestamp: s.createdTs,\n\t}\n\tqs := make([]*dto.Quantile, 0, len(s.quantiles))\n\n\tsum.SampleCount = proto.Uint64(s.count)\n\tsum.SampleSum = proto.Float64(s.sum)\n\n\tfor rank, q := range s.quantiles {\n\t\tqs = append(qs, &dto.Quantile{\n\t\t\tQuantile: proto.Float64(rank),\n\t\t\tValue:    proto.Float64(q),\n\t\t})\n\t}\n\n\tif len(qs) > 0 {\n\t\tsort.Sort(quantSort(qs))\n\t}\n\tsum.Quantile = qs\n\n\tout.Summary = sum\n\tout.Label = s.labelPairs\n\n\treturn nil\n}\n\n// NewConstSummary returns a metric representing a Prometheus summary with fixed\n// values for the count, sum, and quantiles. As those parameters cannot be\n// changed, the returned value does not implement the Summary interface (but\n// only the Metric interface). Users of this package will not have much use for\n// it in regular operations. However, when implementing custom Collectors, it is\n// useful as a throw-away metric that is generated on the fly to send it to\n// Prometheus in the Collect method.\n//\n// quantiles maps ranks to quantile values. For example, a median latency of\n// 0.23s and a 99th percentile latency of 0.56s would be expressed as:\n//\n//\tmap[float64]float64{0.5: 0.23, 0.99: 0.56}\n//\n// NewConstSummary returns an error if the length of labelValues is not\n// consistent with the variable labels in Desc or if Desc is invalid.\nfunc NewConstSummary(\n\tdesc *Desc,\n\tcount uint64,\n\tsum float64,\n\tquantiles map[float64]float64,\n\tlabelValues ...string,\n) (Metric, error) {\n\tif desc.err != nil {\n\t\treturn nil, desc.err\n\t}\n\tif err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &constSummary{\n\t\tdesc:       desc,\n\t\tcount:      count,\n\t\tsum:        sum,\n\t\tquantiles:  quantiles,\n\t\tlabelPairs: MakeLabelPairs(desc, labelValues),\n\t}, nil\n}\n\n// MustNewConstSummary is a version of NewConstSummary that panics where\n// NewConstMetric would have returned an error.\nfunc MustNewConstSummary(\n\tdesc *Desc,\n\tcount uint64,\n\tsum float64,\n\tquantiles map[float64]float64,\n\tlabelValues ...string,\n) Metric {\n\tm, err := NewConstSummary(desc, count, sum, quantiles, labelValues...)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn m\n}\n\n// NewConstSummaryWithCreatedTimestamp does the same thing as NewConstSummary but sets the created timestamp.\nfunc NewConstSummaryWithCreatedTimestamp(\n\tdesc *Desc,\n\tcount uint64,\n\tsum float64,\n\tquantiles map[float64]float64,\n\tct time.Time,\n\tlabelValues ...string,\n) (Metric, error) {\n\tif desc.err != nil {\n\t\treturn nil, desc.err\n\t}\n\tif err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &constSummary{\n\t\tdesc:       desc,\n\t\tcount:      count,\n\t\tsum:        sum,\n\t\tquantiles:  quantiles,\n\t\tlabelPairs: MakeLabelPairs(desc, labelValues),\n\t\tcreatedTs:  timestamppb.New(ct),\n\t}, nil\n}\n\n// MustNewConstSummaryWithCreatedTimestamp is a version of NewConstSummaryWithCreatedTimestamp that panics where\n// NewConstSummaryWithCreatedTimestamp would have returned an error.\nfunc MustNewConstSummaryWithCreatedTimestamp(\n\tdesc *Desc,\n\tcount uint64,\n\tsum float64,\n\tquantiles map[float64]float64,\n\tct time.Time,\n\tlabelValues ...string,\n) Metric {\n\tm, err := NewConstSummaryWithCreatedTimestamp(desc, count, sum, quantiles, ct, labelValues...)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn m\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/timer.go",
    "content": "// Copyright 2016 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\nimport \"time\"\n\n// Timer is a helper type to time functions. Use NewTimer to create new\n// instances.\ntype Timer struct {\n\tbegin    time.Time\n\tobserver Observer\n}\n\n// NewTimer creates a new Timer. The provided Observer is used to observe a\n// duration in seconds. If the Observer implements ExemplarObserver, passing exemplar\n// later on will be also supported.\n// Timer is usually used to time a function call in the\n// following way:\n//\n//\tfunc TimeMe() {\n//\t    timer := NewTimer(myHistogram)\n//\t    defer timer.ObserveDuration()\n//\t    // Do actual work.\n//\t}\n//\n// or\n//\n//\tfunc TimeMeWithExemplar() {\n//\t\t    timer := NewTimer(myHistogram)\n//\t\t    defer timer.ObserveDurationWithExemplar(exemplar)\n//\t\t    // Do actual work.\n//\t\t}\nfunc NewTimer(o Observer) *Timer {\n\treturn &Timer{\n\t\tbegin:    time.Now(),\n\t\tobserver: o,\n\t}\n}\n\n// ObserveDuration records the duration passed since the Timer was created with\n// NewTimer. It calls the Observe method of the Observer provided during\n// construction with the duration in seconds as an argument. The observed\n// duration is also returned. ObserveDuration is usually called with a defer\n// statement.\n//\n// Note that this method is only guaranteed to never observe negative durations\n// if used with Go1.9+.\nfunc (t *Timer) ObserveDuration() time.Duration {\n\td := time.Since(t.begin)\n\tif t.observer != nil {\n\t\tt.observer.Observe(d.Seconds())\n\t}\n\treturn d\n}\n\n// ObserveDurationWithExemplar is like ObserveDuration, but it will also\n// observe exemplar with the duration unless exemplar is nil or provided Observer can't\n// be casted to ExemplarObserver.\nfunc (t *Timer) ObserveDurationWithExemplar(exemplar Labels) time.Duration {\n\td := time.Since(t.begin)\n\teo, ok := t.observer.(ExemplarObserver)\n\tif ok && exemplar != nil {\n\t\teo.ObserveWithExemplar(d.Seconds(), exemplar)\n\t\treturn d\n\t}\n\tif t.observer != nil {\n\t\tt.observer.Observe(d.Seconds())\n\t}\n\treturn d\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/untyped.go",
    "content": "// Copyright 2014 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\n// UntypedOpts is an alias for Opts. See there for doc comments.\ntype UntypedOpts Opts\n\n// UntypedFunc works like GaugeFunc but the collected metric is of type\n// \"Untyped\". UntypedFunc is useful to mirror an external metric of unknown\n// type.\n//\n// To create UntypedFunc instances, use NewUntypedFunc.\ntype UntypedFunc interface {\n\tMetric\n\tCollector\n}\n\n// NewUntypedFunc creates a new UntypedFunc based on the provided\n// UntypedOpts. The value reported is determined by calling the given function\n// from within the Write method. Take into account that metric collection may\n// happen concurrently. If that results in concurrent calls to Write, like in\n// the case where an UntypedFunc is directly registered with Prometheus, the\n// provided function must be concurrency-safe.\nfunc NewUntypedFunc(opts UntypedOpts, function func() float64) UntypedFunc {\n\treturn newValueFunc(NewDesc(\n\t\tBuildFQName(opts.Namespace, opts.Subsystem, opts.Name),\n\t\topts.Help,\n\t\tnil,\n\t\topts.ConstLabels,\n\t), UntypedValue, function)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/value.go",
    "content": "// Copyright 2014 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"sort\"\n\t\"time\"\n\t\"unicode/utf8\"\n\n\t\"github.com/prometheus/client_golang/prometheus/internal\"\n\n\tdto \"github.com/prometheus/client_model/go\"\n\t\"google.golang.org/protobuf/proto\"\n\t\"google.golang.org/protobuf/types/known/timestamppb\"\n)\n\n// ValueType is an enumeration of metric types that represent a simple value.\ntype ValueType int\n\n// Possible values for the ValueType enum. Use UntypedValue to mark a metric\n// with an unknown type.\nconst (\n\t_ ValueType = iota\n\tCounterValue\n\tGaugeValue\n\tUntypedValue\n)\n\nvar (\n\tCounterMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_COUNTER; return &d }()\n\tGaugeMetricTypePtr   = func() *dto.MetricType { d := dto.MetricType_GAUGE; return &d }()\n\tUntypedMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_UNTYPED; return &d }()\n)\n\nfunc (v ValueType) ToDTO() *dto.MetricType {\n\tswitch v {\n\tcase CounterValue:\n\t\treturn CounterMetricTypePtr\n\tcase GaugeValue:\n\t\treturn GaugeMetricTypePtr\n\tdefault:\n\t\treturn UntypedMetricTypePtr\n\t}\n}\n\n// valueFunc is a generic metric for simple values retrieved on collect time\n// from a function. It implements Metric and Collector. Its effective type is\n// determined by ValueType. This is a low-level building block used by the\n// library to back the implementations of CounterFunc, GaugeFunc, and\n// UntypedFunc.\ntype valueFunc struct {\n\tselfCollector\n\n\tdesc       *Desc\n\tvalType    ValueType\n\tfunction   func() float64\n\tlabelPairs []*dto.LabelPair\n}\n\n// newValueFunc returns a newly allocated valueFunc with the given Desc and\n// ValueType. The value reported is determined by calling the given function\n// from within the Write method. Take into account that metric collection may\n// happen concurrently. If that results in concurrent calls to Write, like in\n// the case where a valueFunc is directly registered with Prometheus, the\n// provided function must be concurrency-safe.\nfunc newValueFunc(desc *Desc, valueType ValueType, function func() float64) *valueFunc {\n\tresult := &valueFunc{\n\t\tdesc:       desc,\n\t\tvalType:    valueType,\n\t\tfunction:   function,\n\t\tlabelPairs: MakeLabelPairs(desc, nil),\n\t}\n\tresult.init(result)\n\treturn result\n}\n\nfunc (v *valueFunc) Desc() *Desc {\n\treturn v.desc\n}\n\nfunc (v *valueFunc) Write(out *dto.Metric) error {\n\treturn populateMetric(v.valType, v.function(), v.labelPairs, nil, out, nil)\n}\n\n// NewConstMetric returns a metric with one fixed value that cannot be\n// changed. Users of this package will not have much use for it in regular\n// operations. However, when implementing custom Collectors, it is useful as a\n// throw-away metric that is generated on the fly to send it to Prometheus in\n// the Collect method. NewConstMetric returns an error if the length of\n// labelValues is not consistent with the variable labels in Desc or if Desc is\n// invalid.\nfunc NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) (Metric, error) {\n\tif desc.err != nil {\n\t\treturn nil, desc.err\n\t}\n\tif err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {\n\t\treturn nil, err\n\t}\n\n\tmetric := &dto.Metric{}\n\tif err := populateMetric(valueType, value, MakeLabelPairs(desc, labelValues), nil, metric, nil); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &constMetric{\n\t\tdesc:   desc,\n\t\tmetric: metric,\n\t}, nil\n}\n\n// MustNewConstMetric is a version of NewConstMetric that panics where\n// NewConstMetric would have returned an error.\nfunc MustNewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) Metric {\n\tm, err := NewConstMetric(desc, valueType, value, labelValues...)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn m\n}\n\n// NewConstMetricWithCreatedTimestamp does the same thing as NewConstMetric, but generates Counters\n// with created timestamp set and returns an error for other metric types.\nfunc NewConstMetricWithCreatedTimestamp(desc *Desc, valueType ValueType, value float64, ct time.Time, labelValues ...string) (Metric, error) {\n\tif desc.err != nil {\n\t\treturn nil, desc.err\n\t}\n\tif err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {\n\t\treturn nil, err\n\t}\n\tswitch valueType {\n\tcase CounterValue:\n\t\tbreak\n\tdefault:\n\t\treturn nil, errors.New(\"created timestamps are only supported for counters\")\n\t}\n\n\tmetric := &dto.Metric{}\n\tif err := populateMetric(valueType, value, MakeLabelPairs(desc, labelValues), nil, metric, timestamppb.New(ct)); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &constMetric{\n\t\tdesc:   desc,\n\t\tmetric: metric,\n\t}, nil\n}\n\n// MustNewConstMetricWithCreatedTimestamp is a version of NewConstMetricWithCreatedTimestamp that panics where\n// NewConstMetricWithCreatedTimestamp would have returned an error.\nfunc MustNewConstMetricWithCreatedTimestamp(desc *Desc, valueType ValueType, value float64, ct time.Time, labelValues ...string) Metric {\n\tm, err := NewConstMetricWithCreatedTimestamp(desc, valueType, value, ct, labelValues...)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn m\n}\n\ntype constMetric struct {\n\tdesc   *Desc\n\tmetric *dto.Metric\n}\n\nfunc (m *constMetric) Desc() *Desc {\n\treturn m.desc\n}\n\nfunc (m *constMetric) Write(out *dto.Metric) error {\n\tout.Label = m.metric.Label\n\tout.Counter = m.metric.Counter\n\tout.Gauge = m.metric.Gauge\n\tout.Untyped = m.metric.Untyped\n\treturn nil\n}\n\nfunc populateMetric(\n\tt ValueType,\n\tv float64,\n\tlabelPairs []*dto.LabelPair,\n\te *dto.Exemplar,\n\tm *dto.Metric,\n\tct *timestamppb.Timestamp,\n) error {\n\tm.Label = labelPairs\n\tswitch t {\n\tcase CounterValue:\n\t\tm.Counter = &dto.Counter{Value: proto.Float64(v), Exemplar: e, CreatedTimestamp: ct}\n\tcase GaugeValue:\n\t\tm.Gauge = &dto.Gauge{Value: proto.Float64(v)}\n\tcase UntypedValue:\n\t\tm.Untyped = &dto.Untyped{Value: proto.Float64(v)}\n\tdefault:\n\t\treturn fmt.Errorf(\"encountered unknown type %v\", t)\n\t}\n\treturn nil\n}\n\n// MakeLabelPairs is a helper function to create protobuf LabelPairs from the\n// variable and constant labels in the provided Desc. The values for the\n// variable labels are defined by the labelValues slice, which must be in the\n// same order as the corresponding variable labels in the Desc.\n//\n// This function is only needed for custom Metric implementations. See MetricVec\n// example.\nfunc MakeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair {\n\ttotalLen := len(desc.variableLabels.names) + len(desc.constLabelPairs)\n\tif totalLen == 0 {\n\t\t// Super fast path.\n\t\treturn nil\n\t}\n\tif len(desc.variableLabels.names) == 0 {\n\t\t// Moderately fast path.\n\t\treturn desc.constLabelPairs\n\t}\n\tlabelPairs := make([]*dto.LabelPair, 0, totalLen)\n\tfor i, l := range desc.variableLabels.names {\n\t\tlabelPairs = append(labelPairs, &dto.LabelPair{\n\t\t\tName:  proto.String(l),\n\t\t\tValue: proto.String(labelValues[i]),\n\t\t})\n\t}\n\tlabelPairs = append(labelPairs, desc.constLabelPairs...)\n\tsort.Sort(internal.LabelPairSorter(labelPairs))\n\treturn labelPairs\n}\n\n// ExemplarMaxRunes is the max total number of runes allowed in exemplar labels.\nconst ExemplarMaxRunes = 128\n\n// newExemplar creates a new dto.Exemplar from the provided values. An error is\n// returned if any of the label names or values are invalid or if the total\n// number of runes in the label names and values exceeds ExemplarMaxRunes.\nfunc newExemplar(value float64, ts time.Time, l Labels) (*dto.Exemplar, error) {\n\te := &dto.Exemplar{}\n\te.Value = proto.Float64(value)\n\ttsProto := timestamppb.New(ts)\n\tif err := tsProto.CheckValid(); err != nil {\n\t\treturn nil, err\n\t}\n\te.Timestamp = tsProto\n\tlabelPairs := make([]*dto.LabelPair, 0, len(l))\n\tvar runes int\n\tfor name, value := range l {\n\t\tif !checkLabelName(name) {\n\t\t\treturn nil, fmt.Errorf(\"exemplar label name %q is invalid\", name)\n\t\t}\n\t\trunes += utf8.RuneCountInString(name)\n\t\tif !utf8.ValidString(value) {\n\t\t\treturn nil, fmt.Errorf(\"exemplar label value %q is not valid UTF-8\", value)\n\t\t}\n\t\trunes += utf8.RuneCountInString(value)\n\t\tlabelPairs = append(labelPairs, &dto.LabelPair{\n\t\t\tName:  proto.String(name),\n\t\t\tValue: proto.String(value),\n\t\t})\n\t}\n\tif runes > ExemplarMaxRunes {\n\t\treturn nil, fmt.Errorf(\"exemplar labels have %d runes, exceeding the limit of %d\", runes, ExemplarMaxRunes)\n\t}\n\te.Label = labelPairs\n\treturn e, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/vec.go",
    "content": "// Copyright 2014 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/prometheus/common/model\"\n)\n\n// MetricVec is a Collector to bundle metrics of the same name that differ in\n// their label values. MetricVec is not used directly but as a building block\n// for implementations of vectors of a given metric type, like GaugeVec,\n// CounterVec, SummaryVec, and HistogramVec. It is exported so that it can be\n// used for custom Metric implementations.\n//\n// To create a FooVec for custom Metric Foo, embed a pointer to MetricVec in\n// FooVec and initialize it with NewMetricVec. Implement wrappers for\n// GetMetricWithLabelValues and GetMetricWith that return (Foo, error) rather\n// than (Metric, error). Similarly, create a wrapper for CurryWith that returns\n// (*FooVec, error) rather than (*MetricVec, error). It is recommended to also\n// add the convenience methods WithLabelValues, With, and MustCurryWith, which\n// panic instead of returning errors. See also the MetricVec example.\ntype MetricVec struct {\n\t*metricMap\n\n\tcurry []curriedLabelValue\n\n\t// hashAdd and hashAddByte can be replaced for testing collision handling.\n\thashAdd     func(h uint64, s string) uint64\n\thashAddByte func(h uint64, b byte) uint64\n}\n\n// NewMetricVec returns an initialized metricVec.\nfunc NewMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *MetricVec {\n\treturn &MetricVec{\n\t\tmetricMap: &metricMap{\n\t\t\tmetrics:   map[uint64][]metricWithLabelValues{},\n\t\t\tdesc:      desc,\n\t\t\tnewMetric: newMetric,\n\t\t},\n\t\thashAdd:     hashAdd,\n\t\thashAddByte: hashAddByte,\n\t}\n}\n\n// DeleteLabelValues removes the metric where the variable labels are the same\n// as those passed in as labels (same order as the VariableLabels in Desc). It\n// returns true if a metric was deleted.\n//\n// It is not an error if the number of label values is not the same as the\n// number of VariableLabels in Desc. However, such inconsistent label count can\n// never match an actual metric, so the method will always return false in that\n// case.\n//\n// Note that for more than one label value, this method is prone to mistakes\n// caused by an incorrect order of arguments. Consider Delete(Labels) as an\n// alternative to avoid that type of mistake. For higher label numbers, the\n// latter has a much more readable (albeit more verbose) syntax, but it comes\n// with a performance overhead (for creating and processing the Labels map).\n// See also the CounterVec example.\nfunc (m *MetricVec) DeleteLabelValues(lvs ...string) bool {\n\tlvs = constrainLabelValues(m.desc, lvs, m.curry)\n\n\th, err := m.hashLabelValues(lvs)\n\tif err != nil {\n\t\treturn false\n\t}\n\n\treturn m.metricMap.deleteByHashWithLabelValues(h, lvs, m.curry)\n}\n\n// Delete deletes the metric where the variable labels are the same as those\n// passed in as labels. It returns true if a metric was deleted.\n//\n// It is not an error if the number and names of the Labels are inconsistent\n// with those of the VariableLabels in Desc. However, such inconsistent Labels\n// can never match an actual metric, so the method will always return false in\n// that case.\n//\n// This method is used for the same purpose as DeleteLabelValues(...string). See\n// there for pros and cons of the two methods.\nfunc (m *MetricVec) Delete(labels Labels) bool {\n\tlabels, closer := constrainLabels(m.desc, labels)\n\tdefer closer()\n\n\th, err := m.hashLabels(labels)\n\tif err != nil {\n\t\treturn false\n\t}\n\n\treturn m.metricMap.deleteByHashWithLabels(h, labels, m.curry)\n}\n\n// DeletePartialMatch deletes all metrics where the variable labels contain all of those\n// passed in as labels. The order of the labels does not matter.\n// It returns the number of metrics deleted.\n//\n// Note that curried labels will never be matched if deleting from the curried vector.\n// To match curried labels with DeletePartialMatch, it must be called on the base vector.\nfunc (m *MetricVec) DeletePartialMatch(labels Labels) int {\n\tlabels, closer := constrainLabels(m.desc, labels)\n\tdefer closer()\n\n\treturn m.metricMap.deleteByLabels(labels, m.curry)\n}\n\n// Without explicit forwarding of Describe, Collect, Reset, those methods won't\n// show up in GoDoc.\n\n// Describe implements Collector.\nfunc (m *MetricVec) Describe(ch chan<- *Desc) { m.metricMap.Describe(ch) }\n\n// Collect implements Collector.\nfunc (m *MetricVec) Collect(ch chan<- Metric) { m.metricMap.Collect(ch) }\n\n// Reset deletes all metrics in this vector.\nfunc (m *MetricVec) Reset() { m.metricMap.Reset() }\n\n// CurryWith returns a vector curried with the provided labels, i.e. the\n// returned vector has those labels pre-set for all labeled operations performed\n// on it. The cardinality of the curried vector is reduced accordingly. The\n// order of the remaining labels stays the same (just with the curried labels\n// taken out of the sequence – which is relevant for the\n// (GetMetric)WithLabelValues methods). It is possible to curry a curried\n// vector, but only with labels not yet used for currying before.\n//\n// The metrics contained in the MetricVec are shared between the curried and\n// uncurried vectors. They are just accessed differently. Curried and uncurried\n// vectors behave identically in terms of collection. Only one must be\n// registered with a given registry (usually the uncurried version). The Reset\n// method deletes all metrics, even if called on a curried vector.\n//\n// Note that CurryWith is usually not called directly but through a wrapper\n// around MetricVec, implementing a vector for a specific Metric\n// implementation, for example GaugeVec.\nfunc (m *MetricVec) CurryWith(labels Labels) (*MetricVec, error) {\n\tvar (\n\t\tnewCurry []curriedLabelValue\n\t\toldCurry = m.curry\n\t\tiCurry   int\n\t)\n\tfor i, labelName := range m.desc.variableLabels.names {\n\t\tval, ok := labels[labelName]\n\t\tif iCurry < len(oldCurry) && oldCurry[iCurry].index == i {\n\t\t\tif ok {\n\t\t\t\treturn nil, fmt.Errorf(\"label name %q is already curried\", labelName)\n\t\t\t}\n\t\t\tnewCurry = append(newCurry, oldCurry[iCurry])\n\t\t\tiCurry++\n\t\t} else {\n\t\t\tif !ok {\n\t\t\t\tcontinue // Label stays uncurried.\n\t\t\t}\n\t\t\tnewCurry = append(newCurry, curriedLabelValue{\n\t\t\t\ti,\n\t\t\t\tm.desc.variableLabels.constrain(labelName, val),\n\t\t\t})\n\t\t}\n\t}\n\tif l := len(oldCurry) + len(labels) - len(newCurry); l > 0 {\n\t\treturn nil, fmt.Errorf(\"%d unknown label(s) found during currying\", l)\n\t}\n\n\treturn &MetricVec{\n\t\tmetricMap:   m.metricMap,\n\t\tcurry:       newCurry,\n\t\thashAdd:     m.hashAdd,\n\t\thashAddByte: m.hashAddByte,\n\t}, nil\n}\n\n// GetMetricWithLabelValues returns the Metric for the given slice of label\n// values (same order as the variable labels in Desc). If that combination of\n// label values is accessed for the first time, a new Metric is created (by\n// calling the newMetric function provided during construction of the\n// MetricVec).\n//\n// It is possible to call this method without using the returned Metric to only\n// create the new Metric but leave it in its initial state.\n//\n// Keeping the Metric for later use is possible (and should be considered if\n// performance is critical), but keep in mind that Reset, DeleteLabelValues and\n// Delete can be used to delete the Metric from the MetricVec. In that case, the\n// Metric will still exist, but it will not be exported anymore, even if a\n// Metric with the same label values is created later.\n//\n// An error is returned if the number of label values is not the same as the\n// number of variable labels in Desc (minus any curried labels).\n//\n// Note that for more than one label value, this method is prone to mistakes\n// caused by an incorrect order of arguments. Consider GetMetricWith(Labels) as\n// an alternative to avoid that type of mistake. For higher label numbers, the\n// latter has a much more readable (albeit more verbose) syntax, but it comes\n// with a performance overhead (for creating and processing the Labels map).\n//\n// Note that GetMetricWithLabelValues is usually not called directly but through\n// a wrapper around MetricVec, implementing a vector for a specific Metric\n// implementation, for example GaugeVec.\nfunc (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) {\n\tlvs = constrainLabelValues(m.desc, lvs, m.curry)\n\th, err := m.hashLabelValues(lvs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn m.metricMap.getOrCreateMetricWithLabelValues(h, lvs, m.curry), nil\n}\n\n// GetMetricWith returns the Metric for the given Labels map (the label names\n// must match those of the variable labels in Desc). If that label map is\n// accessed for the first time, a new Metric is created. Implications of\n// creating a Metric without using it and keeping the Metric for later use\n// are the same as for GetMetricWithLabelValues.\n//\n// An error is returned if the number and names of the Labels are inconsistent\n// with those of the variable labels in Desc (minus any curried labels).\n//\n// This method is used for the same purpose as\n// GetMetricWithLabelValues(...string). See there for pros and cons of the two\n// methods.\n//\n// Note that GetMetricWith is usually not called directly but through a wrapper\n// around MetricVec, implementing a vector for a specific Metric implementation,\n// for example GaugeVec.\nfunc (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) {\n\tlabels, closer := constrainLabels(m.desc, labels)\n\tdefer closer()\n\n\th, err := m.hashLabels(labels)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn m.metricMap.getOrCreateMetricWithLabels(h, labels, m.curry), nil\n}\n\nfunc (m *MetricVec) hashLabelValues(vals []string) (uint64, error) {\n\tif err := validateLabelValues(vals, len(m.desc.variableLabels.names)-len(m.curry)); err != nil {\n\t\treturn 0, err\n\t}\n\n\tvar (\n\t\th             = hashNew()\n\t\tcurry         = m.curry\n\t\tiVals, iCurry int\n\t)\n\tfor i := 0; i < len(m.desc.variableLabels.names); i++ {\n\t\tif iCurry < len(curry) && curry[iCurry].index == i {\n\t\t\th = m.hashAdd(h, curry[iCurry].value)\n\t\t\tiCurry++\n\t\t} else {\n\t\t\th = m.hashAdd(h, vals[iVals])\n\t\t\tiVals++\n\t\t}\n\t\th = m.hashAddByte(h, model.SeparatorByte)\n\t}\n\treturn h, nil\n}\n\nfunc (m *MetricVec) hashLabels(labels Labels) (uint64, error) {\n\tif err := validateValuesInLabels(labels, len(m.desc.variableLabels.names)-len(m.curry)); err != nil {\n\t\treturn 0, err\n\t}\n\n\tvar (\n\t\th      = hashNew()\n\t\tcurry  = m.curry\n\t\tiCurry int\n\t)\n\tfor i, labelName := range m.desc.variableLabels.names {\n\t\tval, ok := labels[labelName]\n\t\tif iCurry < len(curry) && curry[iCurry].index == i {\n\t\t\tif ok {\n\t\t\t\treturn 0, fmt.Errorf(\"label name %q is already curried\", labelName)\n\t\t\t}\n\t\t\th = m.hashAdd(h, curry[iCurry].value)\n\t\t\tiCurry++\n\t\t} else {\n\t\t\tif !ok {\n\t\t\t\treturn 0, fmt.Errorf(\"label name %q missing in label map\", labelName)\n\t\t\t}\n\t\t\th = m.hashAdd(h, val)\n\t\t}\n\t\th = m.hashAddByte(h, model.SeparatorByte)\n\t}\n\treturn h, nil\n}\n\n// metricWithLabelValues provides the metric and its label values for\n// disambiguation on hash collision.\ntype metricWithLabelValues struct {\n\tvalues []string\n\tmetric Metric\n}\n\n// curriedLabelValue sets the curried value for a label at the given index.\ntype curriedLabelValue struct {\n\tindex int\n\tvalue string\n}\n\n// metricMap is a helper for metricVec and shared between differently curried\n// metricVecs.\ntype metricMap struct {\n\tmtx       sync.RWMutex // Protects metrics.\n\tmetrics   map[uint64][]metricWithLabelValues\n\tdesc      *Desc\n\tnewMetric func(labelValues ...string) Metric\n}\n\n// Describe implements Collector. It will send exactly one Desc to the provided\n// channel.\nfunc (m *metricMap) Describe(ch chan<- *Desc) {\n\tch <- m.desc\n}\n\n// Collect implements Collector.\nfunc (m *metricMap) Collect(ch chan<- Metric) {\n\tm.mtx.RLock()\n\tdefer m.mtx.RUnlock()\n\n\tfor _, metrics := range m.metrics {\n\t\tfor _, metric := range metrics {\n\t\t\tch <- metric.metric\n\t\t}\n\t}\n}\n\n// Reset deletes all metrics in this vector.\nfunc (m *metricMap) Reset() {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tfor h := range m.metrics {\n\t\tdelete(m.metrics, h)\n\t}\n}\n\n// deleteByHashWithLabelValues removes the metric from the hash bucket h. If\n// there are multiple matches in the bucket, use lvs to select a metric and\n// remove only that metric.\nfunc (m *metricMap) deleteByHashWithLabelValues(\n\th uint64, lvs []string, curry []curriedLabelValue,\n) bool {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tmetrics, ok := m.metrics[h]\n\tif !ok {\n\t\treturn false\n\t}\n\n\ti := findMetricWithLabelValues(metrics, lvs, curry)\n\tif i >= len(metrics) {\n\t\treturn false\n\t}\n\n\tif len(metrics) > 1 {\n\t\told := metrics\n\t\tm.metrics[h] = append(metrics[:i], metrics[i+1:]...)\n\t\told[len(old)-1] = metricWithLabelValues{}\n\t} else {\n\t\tdelete(m.metrics, h)\n\t}\n\treturn true\n}\n\n// deleteByHashWithLabels removes the metric from the hash bucket h. If there\n// are multiple matches in the bucket, use lvs to select a metric and remove\n// only that metric.\nfunc (m *metricMap) deleteByHashWithLabels(\n\th uint64, labels Labels, curry []curriedLabelValue,\n) bool {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tmetrics, ok := m.metrics[h]\n\tif !ok {\n\t\treturn false\n\t}\n\ti := findMetricWithLabels(m.desc, metrics, labels, curry)\n\tif i >= len(metrics) {\n\t\treturn false\n\t}\n\n\tif len(metrics) > 1 {\n\t\told := metrics\n\t\tm.metrics[h] = append(metrics[:i], metrics[i+1:]...)\n\t\told[len(old)-1] = metricWithLabelValues{}\n\t} else {\n\t\tdelete(m.metrics, h)\n\t}\n\treturn true\n}\n\n// deleteByLabels deletes a metric if the given labels are present in the metric.\nfunc (m *metricMap) deleteByLabels(labels Labels, curry []curriedLabelValue) int {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tvar numDeleted int\n\n\tfor h, metrics := range m.metrics {\n\t\ti := findMetricWithPartialLabels(m.desc, metrics, labels, curry)\n\t\tif i >= len(metrics) {\n\t\t\t// Didn't find matching labels in this metric slice.\n\t\t\tcontinue\n\t\t}\n\t\tdelete(m.metrics, h)\n\t\tnumDeleted++\n\t}\n\n\treturn numDeleted\n}\n\n// findMetricWithPartialLabel returns the index of the matching metric or\n// len(metrics) if not found.\nfunc findMetricWithPartialLabels(\n\tdesc *Desc, metrics []metricWithLabelValues, labels Labels, curry []curriedLabelValue,\n) int {\n\tfor i, metric := range metrics {\n\t\tif matchPartialLabels(desc, metric.values, labels, curry) {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn len(metrics)\n}\n\n// indexOf searches the given slice of strings for the target string and returns\n// the index or len(items) as well as a boolean whether the search succeeded.\nfunc indexOf(target string, items []string) (int, bool) {\n\tfor i, l := range items {\n\t\tif l == target {\n\t\t\treturn i, true\n\t\t}\n\t}\n\treturn len(items), false\n}\n\n// valueMatchesVariableOrCurriedValue determines if a value was previously curried,\n// and returns whether it matches either the \"base\" value or the curried value accordingly.\n// It also indicates whether the match is against a curried or uncurried value.\nfunc valueMatchesVariableOrCurriedValue(targetValue string, index int, values []string, curry []curriedLabelValue) (bool, bool) {\n\tfor _, curriedValue := range curry {\n\t\tif curriedValue.index == index {\n\t\t\t// This label was curried. See if the curried value matches our target.\n\t\t\treturn curriedValue.value == targetValue, true\n\t\t}\n\t}\n\t// This label was not curried. See if the current value matches our target label.\n\treturn values[index] == targetValue, false\n}\n\n// matchPartialLabels searches the current metric and returns whether all of the target label:value pairs are present.\nfunc matchPartialLabels(desc *Desc, values []string, labels Labels, curry []curriedLabelValue) bool {\n\tfor l, v := range labels {\n\t\t// Check if the target label exists in our metrics and get the index.\n\t\tvarLabelIndex, validLabel := indexOf(l, desc.variableLabels.names)\n\t\tif validLabel {\n\t\t\t// Check the value of that label against the target value.\n\t\t\t// We don't consider curried values in partial matches.\n\t\t\tmatches, curried := valueMatchesVariableOrCurriedValue(v, varLabelIndex, values, curry)\n\t\t\tif matches && !curried {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\treturn true\n}\n\n// getOrCreateMetricWithLabelValues retrieves the metric by hash and label value\n// or creates it and returns the new one.\n//\n// This function holds the mutex.\nfunc (m *metricMap) getOrCreateMetricWithLabelValues(\n\thash uint64, lvs []string, curry []curriedLabelValue,\n) Metric {\n\tm.mtx.RLock()\n\tmetric, ok := m.getMetricWithHashAndLabelValues(hash, lvs, curry)\n\tm.mtx.RUnlock()\n\tif ok {\n\t\treturn metric\n\t}\n\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\tmetric, ok = m.getMetricWithHashAndLabelValues(hash, lvs, curry)\n\tif !ok {\n\t\tinlinedLVs := inlineLabelValues(lvs, curry)\n\t\tmetric = m.newMetric(inlinedLVs...)\n\t\tm.metrics[hash] = append(m.metrics[hash], metricWithLabelValues{values: inlinedLVs, metric: metric})\n\t}\n\treturn metric\n}\n\n// getOrCreateMetricWithLabels retrieves the metric by hash and label value\n// or creates it and returns the new one.\n//\n// This function holds the mutex.\nfunc (m *metricMap) getOrCreateMetricWithLabels(\n\thash uint64, labels Labels, curry []curriedLabelValue,\n) Metric {\n\tm.mtx.RLock()\n\tmetric, ok := m.getMetricWithHashAndLabels(hash, labels, curry)\n\tm.mtx.RUnlock()\n\tif ok {\n\t\treturn metric\n\t}\n\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\tmetric, ok = m.getMetricWithHashAndLabels(hash, labels, curry)\n\tif !ok {\n\t\tlvs := extractLabelValues(m.desc, labels, curry)\n\t\tmetric = m.newMetric(lvs...)\n\t\tm.metrics[hash] = append(m.metrics[hash], metricWithLabelValues{values: lvs, metric: metric})\n\t}\n\treturn metric\n}\n\n// getMetricWithHashAndLabelValues gets a metric while handling possible\n// collisions in the hash space. Must be called while holding the read mutex.\nfunc (m *metricMap) getMetricWithHashAndLabelValues(\n\th uint64, lvs []string, curry []curriedLabelValue,\n) (Metric, bool) {\n\tmetrics, ok := m.metrics[h]\n\tif ok {\n\t\tif i := findMetricWithLabelValues(metrics, lvs, curry); i < len(metrics) {\n\t\t\treturn metrics[i].metric, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// getMetricWithHashAndLabels gets a metric while handling possible collisions in\n// the hash space. Must be called while holding read mutex.\nfunc (m *metricMap) getMetricWithHashAndLabels(\n\th uint64, labels Labels, curry []curriedLabelValue,\n) (Metric, bool) {\n\tmetrics, ok := m.metrics[h]\n\tif ok {\n\t\tif i := findMetricWithLabels(m.desc, metrics, labels, curry); i < len(metrics) {\n\t\t\treturn metrics[i].metric, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// findMetricWithLabelValues returns the index of the matching metric or\n// len(metrics) if not found.\nfunc findMetricWithLabelValues(\n\tmetrics []metricWithLabelValues, lvs []string, curry []curriedLabelValue,\n) int {\n\tfor i, metric := range metrics {\n\t\tif matchLabelValues(metric.values, lvs, curry) {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn len(metrics)\n}\n\n// findMetricWithLabels returns the index of the matching metric or len(metrics)\n// if not found.\nfunc findMetricWithLabels(\n\tdesc *Desc, metrics []metricWithLabelValues, labels Labels, curry []curriedLabelValue,\n) int {\n\tfor i, metric := range metrics {\n\t\tif matchLabels(desc, metric.values, labels, curry) {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn len(metrics)\n}\n\nfunc matchLabelValues(values, lvs []string, curry []curriedLabelValue) bool {\n\tif len(values) != len(lvs)+len(curry) {\n\t\treturn false\n\t}\n\tvar iLVs, iCurry int\n\tfor i, v := range values {\n\t\tif iCurry < len(curry) && curry[iCurry].index == i {\n\t\t\tif v != curry[iCurry].value {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tiCurry++\n\t\t\tcontinue\n\t\t}\n\t\tif v != lvs[iLVs] {\n\t\t\treturn false\n\t\t}\n\t\tiLVs++\n\t}\n\treturn true\n}\n\nfunc matchLabels(desc *Desc, values []string, labels Labels, curry []curriedLabelValue) bool {\n\tif len(values) != len(labels)+len(curry) {\n\t\treturn false\n\t}\n\tiCurry := 0\n\tfor i, k := range desc.variableLabels.names {\n\t\tif iCurry < len(curry) && curry[iCurry].index == i {\n\t\t\tif values[i] != curry[iCurry].value {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tiCurry++\n\t\t\tcontinue\n\t\t}\n\t\tif values[i] != labels[k] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc extractLabelValues(desc *Desc, labels Labels, curry []curriedLabelValue) []string {\n\tlabelValues := make([]string, len(labels)+len(curry))\n\tiCurry := 0\n\tfor i, k := range desc.variableLabels.names {\n\t\tif iCurry < len(curry) && curry[iCurry].index == i {\n\t\t\tlabelValues[i] = curry[iCurry].value\n\t\t\tiCurry++\n\t\t\tcontinue\n\t\t}\n\t\tlabelValues[i] = labels[k]\n\t}\n\treturn labelValues\n}\n\nfunc inlineLabelValues(lvs []string, curry []curriedLabelValue) []string {\n\tlabelValues := make([]string, len(lvs)+len(curry))\n\tvar iCurry, iLVs int\n\tfor i := range labelValues {\n\t\tif iCurry < len(curry) && curry[iCurry].index == i {\n\t\t\tlabelValues[i] = curry[iCurry].value\n\t\t\tiCurry++\n\t\t\tcontinue\n\t\t}\n\t\tlabelValues[i] = lvs[iLVs]\n\t\tiLVs++\n\t}\n\treturn labelValues\n}\n\nvar labelsPool = &sync.Pool{\n\tNew: func() interface{} {\n\t\treturn make(Labels)\n\t},\n}\n\nfunc constrainLabels(desc *Desc, labels Labels) (Labels, func()) {\n\tif len(desc.variableLabels.labelConstraints) == 0 {\n\t\t// Fast path when there's no constraints\n\t\treturn labels, func() {}\n\t}\n\n\tconstrainedLabels := labelsPool.Get().(Labels)\n\tfor l, v := range labels {\n\t\tconstrainedLabels[l] = desc.variableLabels.constrain(l, v)\n\t}\n\n\treturn constrainedLabels, func() {\n\t\tfor k := range constrainedLabels {\n\t\t\tdelete(constrainedLabels, k)\n\t\t}\n\t\tlabelsPool.Put(constrainedLabels)\n\t}\n}\n\nfunc constrainLabelValues(desc *Desc, lvs []string, curry []curriedLabelValue) []string {\n\tif len(desc.variableLabels.labelConstraints) == 0 {\n\t\t// Fast path when there's no constraints\n\t\treturn lvs\n\t}\n\n\tconstrainedValues := make([]string, len(lvs))\n\tvar iCurry, iLVs int\n\tfor i := 0; i < len(lvs)+len(curry); i++ {\n\t\tif iCurry < len(curry) && curry[iCurry].index == i {\n\t\t\tiCurry++\n\t\t\tcontinue\n\t\t}\n\n\t\tif i < len(desc.variableLabels.names) {\n\t\t\tconstrainedValues[iLVs] = desc.variableLabels.constrain(\n\t\t\t\tdesc.variableLabels.names[i],\n\t\t\t\tlvs[iLVs],\n\t\t\t)\n\t\t} else {\n\t\t\tconstrainedValues[iLVs] = lvs[iLVs]\n\t\t}\n\t\tiLVs++\n\t}\n\treturn constrainedValues\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/vnext.go",
    "content": "// Copyright 2022 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\ntype v2 struct{}\n\n// V2 is a struct that can be referenced to access experimental API that might\n// be present in v2 of client golang someday. It offers extended functionality\n// of v1 with slightly changed API. It is acceptable to use some pieces from v1\n// and e.g `prometheus.NewGauge` and some from v2 e.g. `prometheus.V2.NewDesc`\n// in the same codebase.\nvar V2 = v2{}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_golang/prometheus/wrap.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage prometheus\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\n\t\"github.com/prometheus/client_golang/prometheus/internal\"\n\n\tdto \"github.com/prometheus/client_model/go\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\n// WrapRegistererWith returns a Registerer wrapping the provided\n// Registerer. Collectors registered with the returned Registerer will be\n// registered with the wrapped Registerer in a modified way. The modified\n// Collector adds the provided Labels to all Metrics it collects (as\n// ConstLabels). The Metrics collected by the unmodified Collector must not\n// duplicate any of those labels. Wrapping a nil value is valid, resulting\n// in a no-op Registerer.\n//\n// WrapRegistererWith provides a way to add fixed labels to a subset of\n// Collectors. It should not be used to add fixed labels to all metrics\n// exposed. See also\n// https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels\n//\n// Conflicts between Collectors registered through the original Registerer with\n// Collectors registered through the wrapping Registerer will still be\n// detected. Any AlreadyRegisteredError returned by the Register method of\n// either Registerer will contain the ExistingCollector in the form it was\n// provided to the respective registry.\n//\n// The Collector example demonstrates a use of WrapRegistererWith.\nfunc WrapRegistererWith(labels Labels, reg Registerer) Registerer {\n\treturn &wrappingRegisterer{\n\t\twrappedRegisterer: reg,\n\t\tlabels:            labels,\n\t}\n}\n\n// WrapRegistererWithPrefix returns a Registerer wrapping the provided\n// Registerer. Collectors registered with the returned Registerer will be\n// registered with the wrapped Registerer in a modified way. The modified\n// Collector adds the provided prefix to the name of all Metrics it collects.\n// Wrapping a nil value is valid, resulting in a no-op Registerer.\n//\n// WrapRegistererWithPrefix is useful to have one place to prefix all metrics of\n// a sub-system. To make this work, register metrics of the sub-system with the\n// wrapping Registerer returned by WrapRegistererWithPrefix. It is rarely useful\n// to use the same prefix for all metrics exposed. In particular, do not prefix\n// metric names that are standardized across applications, as that would break\n// horizontal monitoring, for example the metrics provided by the Go collector\n// (see NewGoCollector) and the process collector (see NewProcessCollector). (In\n// fact, those metrics are already prefixed with “go_” or “process_”,\n// respectively.)\n//\n// Conflicts between Collectors registered through the original Registerer with\n// Collectors registered through the wrapping Registerer will still be\n// detected. Any AlreadyRegisteredError returned by the Register method of\n// either Registerer will contain the ExistingCollector in the form it was\n// provided to the respective registry.\nfunc WrapRegistererWithPrefix(prefix string, reg Registerer) Registerer {\n\treturn &wrappingRegisterer{\n\t\twrappedRegisterer: reg,\n\t\tprefix:            prefix,\n\t}\n}\n\ntype wrappingRegisterer struct {\n\twrappedRegisterer Registerer\n\tprefix            string\n\tlabels            Labels\n}\n\nfunc (r *wrappingRegisterer) Register(c Collector) error {\n\tif r.wrappedRegisterer == nil {\n\t\treturn nil\n\t}\n\treturn r.wrappedRegisterer.Register(&wrappingCollector{\n\t\twrappedCollector: c,\n\t\tprefix:           r.prefix,\n\t\tlabels:           r.labels,\n\t})\n}\n\nfunc (r *wrappingRegisterer) MustRegister(cs ...Collector) {\n\tif r.wrappedRegisterer == nil {\n\t\treturn\n\t}\n\tfor _, c := range cs {\n\t\tif err := r.Register(c); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n}\n\nfunc (r *wrappingRegisterer) Unregister(c Collector) bool {\n\tif r.wrappedRegisterer == nil {\n\t\treturn false\n\t}\n\treturn r.wrappedRegisterer.Unregister(&wrappingCollector{\n\t\twrappedCollector: c,\n\t\tprefix:           r.prefix,\n\t\tlabels:           r.labels,\n\t})\n}\n\ntype wrappingCollector struct {\n\twrappedCollector Collector\n\tprefix           string\n\tlabels           Labels\n}\n\nfunc (c *wrappingCollector) Collect(ch chan<- Metric) {\n\twrappedCh := make(chan Metric)\n\tgo func() {\n\t\tc.wrappedCollector.Collect(wrappedCh)\n\t\tclose(wrappedCh)\n\t}()\n\tfor m := range wrappedCh {\n\t\tch <- &wrappingMetric{\n\t\t\twrappedMetric: m,\n\t\t\tprefix:        c.prefix,\n\t\t\tlabels:        c.labels,\n\t\t}\n\t}\n}\n\nfunc (c *wrappingCollector) Describe(ch chan<- *Desc) {\n\twrappedCh := make(chan *Desc)\n\tgo func() {\n\t\tc.wrappedCollector.Describe(wrappedCh)\n\t\tclose(wrappedCh)\n\t}()\n\tfor desc := range wrappedCh {\n\t\tch <- wrapDesc(desc, c.prefix, c.labels)\n\t}\n}\n\nfunc (c *wrappingCollector) unwrapRecursively() Collector {\n\tswitch wc := c.wrappedCollector.(type) {\n\tcase *wrappingCollector:\n\t\treturn wc.unwrapRecursively()\n\tdefault:\n\t\treturn wc\n\t}\n}\n\ntype wrappingMetric struct {\n\twrappedMetric Metric\n\tprefix        string\n\tlabels        Labels\n}\n\nfunc (m *wrappingMetric) Desc() *Desc {\n\treturn wrapDesc(m.wrappedMetric.Desc(), m.prefix, m.labels)\n}\n\nfunc (m *wrappingMetric) Write(out *dto.Metric) error {\n\tif err := m.wrappedMetric.Write(out); err != nil {\n\t\treturn err\n\t}\n\tif len(m.labels) == 0 {\n\t\t// No wrapping labels.\n\t\treturn nil\n\t}\n\tfor ln, lv := range m.labels {\n\t\tout.Label = append(out.Label, &dto.LabelPair{\n\t\t\tName:  proto.String(ln),\n\t\t\tValue: proto.String(lv),\n\t\t})\n\t}\n\tsort.Sort(internal.LabelPairSorter(out.Label))\n\treturn nil\n}\n\nfunc wrapDesc(desc *Desc, prefix string, labels Labels) *Desc {\n\tconstLabels := Labels{}\n\tfor _, lp := range desc.constLabelPairs {\n\t\tconstLabels[*lp.Name] = *lp.Value\n\t}\n\tfor ln, lv := range labels {\n\t\tif _, alreadyUsed := constLabels[ln]; alreadyUsed {\n\t\t\treturn &Desc{\n\t\t\t\tfqName:          desc.fqName,\n\t\t\t\thelp:            desc.help,\n\t\t\t\tvariableLabels:  desc.variableLabels,\n\t\t\t\tconstLabelPairs: desc.constLabelPairs,\n\t\t\t\terr:             fmt.Errorf(\"attempted wrapping with already existing label name %q\", ln),\n\t\t\t}\n\t\t}\n\t\tconstLabels[ln] = lv\n\t}\n\t// NewDesc will do remaining validations.\n\tnewDesc := V2.NewDesc(prefix+desc.fqName, desc.help, desc.variableLabels, constLabels)\n\t// Propagate errors if there was any. This will override any errer\n\t// created by NewDesc above, i.e. earlier errors get precedence.\n\tif desc.err != nil {\n\t\tnewDesc.err = desc.err\n\t}\n\treturn newDesc\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_model/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_model/NOTICE",
    "content": "Data model artifacts for Prometheus.\nCopyright 2012-2015 The Prometheus Authors\n\nThis product includes software developed at\nSoundCloud Ltd. (http://soundcloud.com/).\n"
  },
  {
    "path": "vendor/github.com/prometheus/client_model/go/metrics.pb.go",
    "content": "// Copyright 2013 Prometheus Team\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.30.0\n// \tprotoc        v3.20.3\n// source: io/prometheus/client/metrics.proto\n\npackage io_prometheus_client\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\ttimestamppb \"google.golang.org/protobuf/types/known/timestamppb\"\n\treflect \"reflect\"\n\tsync \"sync\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\ntype MetricType int32\n\nconst (\n\t// COUNTER must use the Metric field \"counter\".\n\tMetricType_COUNTER MetricType = 0\n\t// GAUGE must use the Metric field \"gauge\".\n\tMetricType_GAUGE MetricType = 1\n\t// SUMMARY must use the Metric field \"summary\".\n\tMetricType_SUMMARY MetricType = 2\n\t// UNTYPED must use the Metric field \"untyped\".\n\tMetricType_UNTYPED MetricType = 3\n\t// HISTOGRAM must use the Metric field \"histogram\".\n\tMetricType_HISTOGRAM MetricType = 4\n\t// GAUGE_HISTOGRAM must use the Metric field \"histogram\".\n\tMetricType_GAUGE_HISTOGRAM MetricType = 5\n)\n\n// Enum value maps for MetricType.\nvar (\n\tMetricType_name = map[int32]string{\n\t\t0: \"COUNTER\",\n\t\t1: \"GAUGE\",\n\t\t2: \"SUMMARY\",\n\t\t3: \"UNTYPED\",\n\t\t4: \"HISTOGRAM\",\n\t\t5: \"GAUGE_HISTOGRAM\",\n\t}\n\tMetricType_value = map[string]int32{\n\t\t\"COUNTER\":         0,\n\t\t\"GAUGE\":           1,\n\t\t\"SUMMARY\":         2,\n\t\t\"UNTYPED\":         3,\n\t\t\"HISTOGRAM\":       4,\n\t\t\"GAUGE_HISTOGRAM\": 5,\n\t}\n)\n\nfunc (x MetricType) Enum() *MetricType {\n\tp := new(MetricType)\n\t*p = x\n\treturn p\n}\n\nfunc (x MetricType) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (MetricType) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_io_prometheus_client_metrics_proto_enumTypes[0].Descriptor()\n}\n\nfunc (MetricType) Type() protoreflect.EnumType {\n\treturn &file_io_prometheus_client_metrics_proto_enumTypes[0]\n}\n\nfunc (x MetricType) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Do not use.\nfunc (x *MetricType) UnmarshalJSON(b []byte) error {\n\tnum, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*x = MetricType(num)\n\treturn nil\n}\n\n// Deprecated: Use MetricType.Descriptor instead.\nfunc (MetricType) EnumDescriptor() ([]byte, []int) {\n\treturn file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{0}\n}\n\ntype LabelPair struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tName  *string `protobuf:\"bytes,1,opt,name=name\" json:\"name,omitempty\"`\n\tValue *string `protobuf:\"bytes,2,opt,name=value\" json:\"value,omitempty\"`\n}\n\nfunc (x *LabelPair) Reset() {\n\t*x = LabelPair{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *LabelPair) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*LabelPair) ProtoMessage() {}\n\nfunc (x *LabelPair) ProtoReflect() protoreflect.Message {\n\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[0]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use LabelPair.ProtoReflect.Descriptor instead.\nfunc (*LabelPair) Descriptor() ([]byte, []int) {\n\treturn file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *LabelPair) GetName() string {\n\tif x != nil && x.Name != nil {\n\t\treturn *x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *LabelPair) GetValue() string {\n\tif x != nil && x.Value != nil {\n\t\treturn *x.Value\n\t}\n\treturn \"\"\n}\n\ntype Gauge struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tValue *float64 `protobuf:\"fixed64,1,opt,name=value\" json:\"value,omitempty\"`\n}\n\nfunc (x *Gauge) Reset() {\n\t*x = Gauge{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[1]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Gauge) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Gauge) ProtoMessage() {}\n\nfunc (x *Gauge) ProtoReflect() protoreflect.Message {\n\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[1]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Gauge.ProtoReflect.Descriptor instead.\nfunc (*Gauge) Descriptor() ([]byte, []int) {\n\treturn file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Gauge) GetValue() float64 {\n\tif x != nil && x.Value != nil {\n\t\treturn *x.Value\n\t}\n\treturn 0\n}\n\ntype Counter struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tValue            *float64               `protobuf:\"fixed64,1,opt,name=value\" json:\"value,omitempty\"`\n\tExemplar         *Exemplar              `protobuf:\"bytes,2,opt,name=exemplar\" json:\"exemplar,omitempty\"`\n\tCreatedTimestamp *timestamppb.Timestamp `protobuf:\"bytes,3,opt,name=created_timestamp,json=createdTimestamp\" json:\"created_timestamp,omitempty\"`\n}\n\nfunc (x *Counter) Reset() {\n\t*x = Counter{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[2]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Counter) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Counter) ProtoMessage() {}\n\nfunc (x *Counter) ProtoReflect() protoreflect.Message {\n\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[2]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Counter.ProtoReflect.Descriptor instead.\nfunc (*Counter) Descriptor() ([]byte, []int) {\n\treturn file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *Counter) GetValue() float64 {\n\tif x != nil && x.Value != nil {\n\t\treturn *x.Value\n\t}\n\treturn 0\n}\n\nfunc (x *Counter) GetExemplar() *Exemplar {\n\tif x != nil {\n\t\treturn x.Exemplar\n\t}\n\treturn nil\n}\n\nfunc (x *Counter) GetCreatedTimestamp() *timestamppb.Timestamp {\n\tif x != nil {\n\t\treturn x.CreatedTimestamp\n\t}\n\treturn nil\n}\n\ntype Quantile struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tQuantile *float64 `protobuf:\"fixed64,1,opt,name=quantile\" json:\"quantile,omitempty\"`\n\tValue    *float64 `protobuf:\"fixed64,2,opt,name=value\" json:\"value,omitempty\"`\n}\n\nfunc (x *Quantile) Reset() {\n\t*x = Quantile{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[3]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Quantile) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Quantile) ProtoMessage() {}\n\nfunc (x *Quantile) ProtoReflect() protoreflect.Message {\n\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[3]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Quantile.ProtoReflect.Descriptor instead.\nfunc (*Quantile) Descriptor() ([]byte, []int) {\n\treturn file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *Quantile) GetQuantile() float64 {\n\tif x != nil && x.Quantile != nil {\n\t\treturn *x.Quantile\n\t}\n\treturn 0\n}\n\nfunc (x *Quantile) GetValue() float64 {\n\tif x != nil && x.Value != nil {\n\t\treturn *x.Value\n\t}\n\treturn 0\n}\n\ntype Summary struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tSampleCount      *uint64                `protobuf:\"varint,1,opt,name=sample_count,json=sampleCount\" json:\"sample_count,omitempty\"`\n\tSampleSum        *float64               `protobuf:\"fixed64,2,opt,name=sample_sum,json=sampleSum\" json:\"sample_sum,omitempty\"`\n\tQuantile         []*Quantile            `protobuf:\"bytes,3,rep,name=quantile\" json:\"quantile,omitempty\"`\n\tCreatedTimestamp *timestamppb.Timestamp `protobuf:\"bytes,4,opt,name=created_timestamp,json=createdTimestamp\" json:\"created_timestamp,omitempty\"`\n}\n\nfunc (x *Summary) Reset() {\n\t*x = Summary{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[4]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Summary) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Summary) ProtoMessage() {}\n\nfunc (x *Summary) ProtoReflect() protoreflect.Message {\n\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[4]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Summary.ProtoReflect.Descriptor instead.\nfunc (*Summary) Descriptor() ([]byte, []int) {\n\treturn file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *Summary) GetSampleCount() uint64 {\n\tif x != nil && x.SampleCount != nil {\n\t\treturn *x.SampleCount\n\t}\n\treturn 0\n}\n\nfunc (x *Summary) GetSampleSum() float64 {\n\tif x != nil && x.SampleSum != nil {\n\t\treturn *x.SampleSum\n\t}\n\treturn 0\n}\n\nfunc (x *Summary) GetQuantile() []*Quantile {\n\tif x != nil {\n\t\treturn x.Quantile\n\t}\n\treturn nil\n}\n\nfunc (x *Summary) GetCreatedTimestamp() *timestamppb.Timestamp {\n\tif x != nil {\n\t\treturn x.CreatedTimestamp\n\t}\n\treturn nil\n}\n\ntype Untyped struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tValue *float64 `protobuf:\"fixed64,1,opt,name=value\" json:\"value,omitempty\"`\n}\n\nfunc (x *Untyped) Reset() {\n\t*x = Untyped{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[5]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Untyped) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Untyped) ProtoMessage() {}\n\nfunc (x *Untyped) ProtoReflect() protoreflect.Message {\n\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[5]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Untyped.ProtoReflect.Descriptor instead.\nfunc (*Untyped) Descriptor() ([]byte, []int) {\n\treturn file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{5}\n}\n\nfunc (x *Untyped) GetValue() float64 {\n\tif x != nil && x.Value != nil {\n\t\treturn *x.Value\n\t}\n\treturn 0\n}\n\ntype Histogram struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tSampleCount      *uint64  `protobuf:\"varint,1,opt,name=sample_count,json=sampleCount\" json:\"sample_count,omitempty\"`\n\tSampleCountFloat *float64 `protobuf:\"fixed64,4,opt,name=sample_count_float,json=sampleCountFloat\" json:\"sample_count_float,omitempty\"` // Overrides sample_count if > 0.\n\tSampleSum        *float64 `protobuf:\"fixed64,2,opt,name=sample_sum,json=sampleSum\" json:\"sample_sum,omitempty\"`\n\t// Buckets for the conventional histogram.\n\tBucket           []*Bucket              `protobuf:\"bytes,3,rep,name=bucket\" json:\"bucket,omitempty\"` // Ordered in increasing order of upper_bound, +Inf bucket is optional.\n\tCreatedTimestamp *timestamppb.Timestamp `protobuf:\"bytes,15,opt,name=created_timestamp,json=createdTimestamp\" json:\"created_timestamp,omitempty\"`\n\t// schema defines the bucket schema. Currently, valid numbers are -4 <= n <= 8.\n\t// They are all for base-2 bucket schemas, where 1 is a bucket boundary in each case, and\n\t// then each power of two is divided into 2^n logarithmic buckets.\n\t// Or in other words, each bucket boundary is the previous boundary times 2^(2^-n).\n\t// In the future, more bucket schemas may be added using numbers < -4 or > 8.\n\tSchema         *int32   `protobuf:\"zigzag32,5,opt,name=schema\" json:\"schema,omitempty\"`\n\tZeroThreshold  *float64 `protobuf:\"fixed64,6,opt,name=zero_threshold,json=zeroThreshold\" json:\"zero_threshold,omitempty\"`      // Breadth of the zero bucket.\n\tZeroCount      *uint64  `protobuf:\"varint,7,opt,name=zero_count,json=zeroCount\" json:\"zero_count,omitempty\"`                   // Count in zero bucket.\n\tZeroCountFloat *float64 `protobuf:\"fixed64,8,opt,name=zero_count_float,json=zeroCountFloat\" json:\"zero_count_float,omitempty\"` // Overrides sb_zero_count if > 0.\n\t// Negative buckets for the native histogram.\n\tNegativeSpan []*BucketSpan `protobuf:\"bytes,9,rep,name=negative_span,json=negativeSpan\" json:\"negative_span,omitempty\"`\n\t// Use either \"negative_delta\" or \"negative_count\", the former for\n\t// regular histograms with integer counts, the latter for float\n\t// histograms.\n\tNegativeDelta []int64   `protobuf:\"zigzag64,10,rep,name=negative_delta,json=negativeDelta\" json:\"negative_delta,omitempty\"` // Count delta of each bucket compared to previous one (or to zero for 1st bucket).\n\tNegativeCount []float64 `protobuf:\"fixed64,11,rep,name=negative_count,json=negativeCount\" json:\"negative_count,omitempty\"`  // Absolute count of each bucket.\n\t// Positive buckets for the native histogram.\n\t// Use a no-op span (offset 0, length 0) for a native histogram without any\n\t// observations yet and with a zero_threshold of 0. Otherwise, it would be\n\t// indistinguishable from a classic histogram.\n\tPositiveSpan []*BucketSpan `protobuf:\"bytes,12,rep,name=positive_span,json=positiveSpan\" json:\"positive_span,omitempty\"`\n\t// Use either \"positive_delta\" or \"positive_count\", the former for\n\t// regular histograms with integer counts, the latter for float\n\t// histograms.\n\tPositiveDelta []int64   `protobuf:\"zigzag64,13,rep,name=positive_delta,json=positiveDelta\" json:\"positive_delta,omitempty\"` // Count delta of each bucket compared to previous one (or to zero for 1st bucket).\n\tPositiveCount []float64 `protobuf:\"fixed64,14,rep,name=positive_count,json=positiveCount\" json:\"positive_count,omitempty\"`  // Absolute count of each bucket.\n\t// Only used for native histograms. These exemplars MUST have a timestamp.\n\tExemplars []*Exemplar `protobuf:\"bytes,16,rep,name=exemplars\" json:\"exemplars,omitempty\"`\n}\n\nfunc (x *Histogram) Reset() {\n\t*x = Histogram{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[6]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Histogram) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Histogram) ProtoMessage() {}\n\nfunc (x *Histogram) ProtoReflect() protoreflect.Message {\n\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[6]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Histogram.ProtoReflect.Descriptor instead.\nfunc (*Histogram) Descriptor() ([]byte, []int) {\n\treturn file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{6}\n}\n\nfunc (x *Histogram) GetSampleCount() uint64 {\n\tif x != nil && x.SampleCount != nil {\n\t\treturn *x.SampleCount\n\t}\n\treturn 0\n}\n\nfunc (x *Histogram) GetSampleCountFloat() float64 {\n\tif x != nil && x.SampleCountFloat != nil {\n\t\treturn *x.SampleCountFloat\n\t}\n\treturn 0\n}\n\nfunc (x *Histogram) GetSampleSum() float64 {\n\tif x != nil && x.SampleSum != nil {\n\t\treturn *x.SampleSum\n\t}\n\treturn 0\n}\n\nfunc (x *Histogram) GetBucket() []*Bucket {\n\tif x != nil {\n\t\treturn x.Bucket\n\t}\n\treturn nil\n}\n\nfunc (x *Histogram) GetCreatedTimestamp() *timestamppb.Timestamp {\n\tif x != nil {\n\t\treturn x.CreatedTimestamp\n\t}\n\treturn nil\n}\n\nfunc (x *Histogram) GetSchema() int32 {\n\tif x != nil && x.Schema != nil {\n\t\treturn *x.Schema\n\t}\n\treturn 0\n}\n\nfunc (x *Histogram) GetZeroThreshold() float64 {\n\tif x != nil && x.ZeroThreshold != nil {\n\t\treturn *x.ZeroThreshold\n\t}\n\treturn 0\n}\n\nfunc (x *Histogram) GetZeroCount() uint64 {\n\tif x != nil && x.ZeroCount != nil {\n\t\treturn *x.ZeroCount\n\t}\n\treturn 0\n}\n\nfunc (x *Histogram) GetZeroCountFloat() float64 {\n\tif x != nil && x.ZeroCountFloat != nil {\n\t\treturn *x.ZeroCountFloat\n\t}\n\treturn 0\n}\n\nfunc (x *Histogram) GetNegativeSpan() []*BucketSpan {\n\tif x != nil {\n\t\treturn x.NegativeSpan\n\t}\n\treturn nil\n}\n\nfunc (x *Histogram) GetNegativeDelta() []int64 {\n\tif x != nil {\n\t\treturn x.NegativeDelta\n\t}\n\treturn nil\n}\n\nfunc (x *Histogram) GetNegativeCount() []float64 {\n\tif x != nil {\n\t\treturn x.NegativeCount\n\t}\n\treturn nil\n}\n\nfunc (x *Histogram) GetPositiveSpan() []*BucketSpan {\n\tif x != nil {\n\t\treturn x.PositiveSpan\n\t}\n\treturn nil\n}\n\nfunc (x *Histogram) GetPositiveDelta() []int64 {\n\tif x != nil {\n\t\treturn x.PositiveDelta\n\t}\n\treturn nil\n}\n\nfunc (x *Histogram) GetPositiveCount() []float64 {\n\tif x != nil {\n\t\treturn x.PositiveCount\n\t}\n\treturn nil\n}\n\nfunc (x *Histogram) GetExemplars() []*Exemplar {\n\tif x != nil {\n\t\treturn x.Exemplars\n\t}\n\treturn nil\n}\n\n// A Bucket of a conventional histogram, each of which is treated as\n// an individual counter-like time series by Prometheus.\ntype Bucket struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tCumulativeCount      *uint64   `protobuf:\"varint,1,opt,name=cumulative_count,json=cumulativeCount\" json:\"cumulative_count,omitempty\"`                   // Cumulative in increasing order.\n\tCumulativeCountFloat *float64  `protobuf:\"fixed64,4,opt,name=cumulative_count_float,json=cumulativeCountFloat\" json:\"cumulative_count_float,omitempty\"` // Overrides cumulative_count if > 0.\n\tUpperBound           *float64  `protobuf:\"fixed64,2,opt,name=upper_bound,json=upperBound\" json:\"upper_bound,omitempty\"`                                 // Inclusive.\n\tExemplar             *Exemplar `protobuf:\"bytes,3,opt,name=exemplar\" json:\"exemplar,omitempty\"`\n}\n\nfunc (x *Bucket) Reset() {\n\t*x = Bucket{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[7]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Bucket) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Bucket) ProtoMessage() {}\n\nfunc (x *Bucket) ProtoReflect() protoreflect.Message {\n\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[7]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Bucket.ProtoReflect.Descriptor instead.\nfunc (*Bucket) Descriptor() ([]byte, []int) {\n\treturn file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{7}\n}\n\nfunc (x *Bucket) GetCumulativeCount() uint64 {\n\tif x != nil && x.CumulativeCount != nil {\n\t\treturn *x.CumulativeCount\n\t}\n\treturn 0\n}\n\nfunc (x *Bucket) GetCumulativeCountFloat() float64 {\n\tif x != nil && x.CumulativeCountFloat != nil {\n\t\treturn *x.CumulativeCountFloat\n\t}\n\treturn 0\n}\n\nfunc (x *Bucket) GetUpperBound() float64 {\n\tif x != nil && x.UpperBound != nil {\n\t\treturn *x.UpperBound\n\t}\n\treturn 0\n}\n\nfunc (x *Bucket) GetExemplar() *Exemplar {\n\tif x != nil {\n\t\treturn x.Exemplar\n\t}\n\treturn nil\n}\n\n// A BucketSpan defines a number of consecutive buckets in a native\n// histogram with their offset. Logically, it would be more\n// straightforward to include the bucket counts in the Span. However,\n// the protobuf representation is more compact in the way the data is\n// structured here (with all the buckets in a single array separate\n// from the Spans).\ntype BucketSpan struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tOffset *int32  `protobuf:\"zigzag32,1,opt,name=offset\" json:\"offset,omitempty\"` // Gap to previous span, or starting point for 1st span (which can be negative).\n\tLength *uint32 `protobuf:\"varint,2,opt,name=length\" json:\"length,omitempty\"`   // Length of consecutive buckets.\n}\n\nfunc (x *BucketSpan) Reset() {\n\t*x = BucketSpan{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[8]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *BucketSpan) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*BucketSpan) ProtoMessage() {}\n\nfunc (x *BucketSpan) ProtoReflect() protoreflect.Message {\n\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[8]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use BucketSpan.ProtoReflect.Descriptor instead.\nfunc (*BucketSpan) Descriptor() ([]byte, []int) {\n\treturn file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{8}\n}\n\nfunc (x *BucketSpan) GetOffset() int32 {\n\tif x != nil && x.Offset != nil {\n\t\treturn *x.Offset\n\t}\n\treturn 0\n}\n\nfunc (x *BucketSpan) GetLength() uint32 {\n\tif x != nil && x.Length != nil {\n\t\treturn *x.Length\n\t}\n\treturn 0\n}\n\ntype Exemplar struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tLabel     []*LabelPair           `protobuf:\"bytes,1,rep,name=label\" json:\"label,omitempty\"`\n\tValue     *float64               `protobuf:\"fixed64,2,opt,name=value\" json:\"value,omitempty\"`\n\tTimestamp *timestamppb.Timestamp `protobuf:\"bytes,3,opt,name=timestamp\" json:\"timestamp,omitempty\"` // OpenMetrics-style.\n}\n\nfunc (x *Exemplar) Reset() {\n\t*x = Exemplar{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[9]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Exemplar) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Exemplar) ProtoMessage() {}\n\nfunc (x *Exemplar) ProtoReflect() protoreflect.Message {\n\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[9]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Exemplar.ProtoReflect.Descriptor instead.\nfunc (*Exemplar) Descriptor() ([]byte, []int) {\n\treturn file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{9}\n}\n\nfunc (x *Exemplar) GetLabel() []*LabelPair {\n\tif x != nil {\n\t\treturn x.Label\n\t}\n\treturn nil\n}\n\nfunc (x *Exemplar) GetValue() float64 {\n\tif x != nil && x.Value != nil {\n\t\treturn *x.Value\n\t}\n\treturn 0\n}\n\nfunc (x *Exemplar) GetTimestamp() *timestamppb.Timestamp {\n\tif x != nil {\n\t\treturn x.Timestamp\n\t}\n\treturn nil\n}\n\ntype Metric struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tLabel       []*LabelPair `protobuf:\"bytes,1,rep,name=label\" json:\"label,omitempty\"`\n\tGauge       *Gauge       `protobuf:\"bytes,2,opt,name=gauge\" json:\"gauge,omitempty\"`\n\tCounter     *Counter     `protobuf:\"bytes,3,opt,name=counter\" json:\"counter,omitempty\"`\n\tSummary     *Summary     `protobuf:\"bytes,4,opt,name=summary\" json:\"summary,omitempty\"`\n\tUntyped     *Untyped     `protobuf:\"bytes,5,opt,name=untyped\" json:\"untyped,omitempty\"`\n\tHistogram   *Histogram   `protobuf:\"bytes,7,opt,name=histogram\" json:\"histogram,omitempty\"`\n\tTimestampMs *int64       `protobuf:\"varint,6,opt,name=timestamp_ms,json=timestampMs\" json:\"timestamp_ms,omitempty\"`\n}\n\nfunc (x *Metric) Reset() {\n\t*x = Metric{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[10]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Metric) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Metric) ProtoMessage() {}\n\nfunc (x *Metric) ProtoReflect() protoreflect.Message {\n\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[10]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Metric.ProtoReflect.Descriptor instead.\nfunc (*Metric) Descriptor() ([]byte, []int) {\n\treturn file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{10}\n}\n\nfunc (x *Metric) GetLabel() []*LabelPair {\n\tif x != nil {\n\t\treturn x.Label\n\t}\n\treturn nil\n}\n\nfunc (x *Metric) GetGauge() *Gauge {\n\tif x != nil {\n\t\treturn x.Gauge\n\t}\n\treturn nil\n}\n\nfunc (x *Metric) GetCounter() *Counter {\n\tif x != nil {\n\t\treturn x.Counter\n\t}\n\treturn nil\n}\n\nfunc (x *Metric) GetSummary() *Summary {\n\tif x != nil {\n\t\treturn x.Summary\n\t}\n\treturn nil\n}\n\nfunc (x *Metric) GetUntyped() *Untyped {\n\tif x != nil {\n\t\treturn x.Untyped\n\t}\n\treturn nil\n}\n\nfunc (x *Metric) GetHistogram() *Histogram {\n\tif x != nil {\n\t\treturn x.Histogram\n\t}\n\treturn nil\n}\n\nfunc (x *Metric) GetTimestampMs() int64 {\n\tif x != nil && x.TimestampMs != nil {\n\t\treturn *x.TimestampMs\n\t}\n\treturn 0\n}\n\ntype MetricFamily struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tName   *string     `protobuf:\"bytes,1,opt,name=name\" json:\"name,omitempty\"`\n\tHelp   *string     `protobuf:\"bytes,2,opt,name=help\" json:\"help,omitempty\"`\n\tType   *MetricType `protobuf:\"varint,3,opt,name=type,enum=io.prometheus.client.MetricType\" json:\"type,omitempty\"`\n\tMetric []*Metric   `protobuf:\"bytes,4,rep,name=metric\" json:\"metric,omitempty\"`\n\tUnit   *string     `protobuf:\"bytes,5,opt,name=unit\" json:\"unit,omitempty\"`\n}\n\nfunc (x *MetricFamily) Reset() {\n\t*x = MetricFamily{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[11]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *MetricFamily) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*MetricFamily) ProtoMessage() {}\n\nfunc (x *MetricFamily) ProtoReflect() protoreflect.Message {\n\tmi := &file_io_prometheus_client_metrics_proto_msgTypes[11]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use MetricFamily.ProtoReflect.Descriptor instead.\nfunc (*MetricFamily) Descriptor() ([]byte, []int) {\n\treturn file_io_prometheus_client_metrics_proto_rawDescGZIP(), []int{11}\n}\n\nfunc (x *MetricFamily) GetName() string {\n\tif x != nil && x.Name != nil {\n\t\treturn *x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *MetricFamily) GetHelp() string {\n\tif x != nil && x.Help != nil {\n\t\treturn *x.Help\n\t}\n\treturn \"\"\n}\n\nfunc (x *MetricFamily) GetType() MetricType {\n\tif x != nil && x.Type != nil {\n\t\treturn *x.Type\n\t}\n\treturn MetricType_COUNTER\n}\n\nfunc (x *MetricFamily) GetMetric() []*Metric {\n\tif x != nil {\n\t\treturn x.Metric\n\t}\n\treturn nil\n}\n\nfunc (x *MetricFamily) GetUnit() string {\n\tif x != nil && x.Unit != nil {\n\t\treturn *x.Unit\n\t}\n\treturn \"\"\n}\n\nvar File_io_prometheus_client_metrics_proto protoreflect.FileDescriptor\n\nvar file_io_prometheus_client_metrics_proto_rawDesc = []byte{\n\t0x0a, 0x22, 0x69, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2f,\n\t0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x70,\n\t0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68,\n\t0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67,\n\t0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65,\n\t0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x35, 0x0a, 0x09, 0x4c,\n\t0x61, 0x62, 0x65, 0x6c, 0x50, 0x61, 0x69, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,\n\t0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05,\n\t0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c,\n\t0x75, 0x65, 0x22, 0x1d, 0x0a, 0x05, 0x47, 0x61, 0x75, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76,\n\t0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,\n\t0x65, 0x22, 0xa4, 0x01, 0x0a, 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x14, 0x0a,\n\t0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61,\n\t0x6c, 0x75, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x18,\n\t0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65,\n\t0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x78, 0x65,\n\t0x6d, 0x70, 0x6c, 0x61, 0x72, 0x52, 0x08, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x12,\n\t0x47, 0x0a, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73,\n\t0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f,\n\t0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d,\n\t0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x54,\n\t0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3c, 0x0a, 0x08, 0x51, 0x75, 0x61, 0x6e,\n\t0x74, 0x69, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65,\n\t0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65,\n\t0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52,\n\t0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xd0, 0x01, 0x0a, 0x07, 0x53, 0x75, 0x6d, 0x6d, 0x61,\n\t0x72, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75,\n\t0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65,\n\t0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f,\n\t0x73, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x73, 0x61, 0x6d, 0x70, 0x6c,\n\t0x65, 0x53, 0x75, 0x6d, 0x12, 0x3a, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65,\n\t0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d,\n\t0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x51, 0x75,\n\t0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x52, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65,\n\t0x12, 0x47, 0x0a, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65,\n\t0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,\n\t0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,\n\t0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,\n\t0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x1f, 0x0a, 0x07, 0x55, 0x6e, 0x74,\n\t0x79, 0x70, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20,\n\t0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xea, 0x05, 0x0a, 0x09, 0x48,\n\t0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x61, 0x6d, 0x70,\n\t0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b,\n\t0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x73,\n\t0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x66, 0x6c, 0x6f, 0x61,\n\t0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x10, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x43,\n\t0x6f, 0x75, 0x6e, 0x74, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x61, 0x6d,\n\t0x70, 0x6c, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x73,\n\t0x61, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x75, 0x6d, 0x12, 0x34, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b,\n\t0x65, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72,\n\t0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e,\n\t0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x47,\n\t0x0a, 0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,\n\t0x61, 0x6d, 0x70, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,\n\t0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,\n\t0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x54, 0x69,\n\t0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d,\n\t0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x11, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12,\n\t0x25, 0x0a, 0x0e, 0x7a, 0x65, 0x72, 0x6f, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c,\n\t0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0d, 0x7a, 0x65, 0x72, 0x6f, 0x54, 0x68, 0x72,\n\t0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x7a, 0x65, 0x72, 0x6f, 0x5f, 0x63,\n\t0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x7a, 0x65, 0x72, 0x6f,\n\t0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x7a, 0x65, 0x72, 0x6f, 0x5f, 0x63, 0x6f,\n\t0x75, 0x6e, 0x74, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x01, 0x52,\n\t0x0e, 0x7a, 0x65, 0x72, 0x6f, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x12,\n\t0x45, 0x0a, 0x0d, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x73, 0x70, 0x61, 0x6e,\n\t0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d,\n\t0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x42, 0x75,\n\t0x63, 0x6b, 0x65, 0x74, 0x53, 0x70, 0x61, 0x6e, 0x52, 0x0c, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69,\n\t0x76, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69,\n\t0x76, 0x65, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x12, 0x52, 0x0d,\n\t0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x44, 0x65, 0x6c, 0x74, 0x61, 0x12, 0x25, 0x0a,\n\t0x0e, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18,\n\t0x0b, 0x20, 0x03, 0x28, 0x01, 0x52, 0x0d, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x43,\n\t0x6f, 0x75, 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x0d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65,\n\t0x5f, 0x73, 0x70, 0x61, 0x6e, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x69, 0x6f,\n\t0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65,\n\t0x6e, 0x74, 0x2e, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x70, 0x61, 0x6e, 0x52, 0x0c, 0x70,\n\t0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x70,\n\t0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18, 0x0d, 0x20,\n\t0x03, 0x28, 0x12, 0x52, 0x0d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x44, 0x65, 0x6c,\n\t0x74, 0x61, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63,\n\t0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x01, 0x52, 0x0d, 0x70, 0x6f, 0x73, 0x69,\n\t0x74, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x09, 0x65, 0x78, 0x65,\n\t0x6d, 0x70, 0x6c, 0x61, 0x72, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69,\n\t0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69,\n\t0x65, 0x6e, 0x74, 0x2e, 0x45, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x52, 0x09, 0x65, 0x78,\n\t0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x73, 0x22, 0xc6, 0x01, 0x0a, 0x06, 0x42, 0x75, 0x63, 0x6b,\n\t0x65, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65,\n\t0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x63, 0x75,\n\t0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x34, 0x0a,\n\t0x16, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e,\n\t0x74, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x14, 0x63,\n\t0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x46, 0x6c,\n\t0x6f, 0x61, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x70, 0x70, 0x65, 0x72, 0x5f, 0x62, 0x6f, 0x75,\n\t0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0a, 0x75, 0x70, 0x70, 0x65, 0x72, 0x42,\n\t0x6f, 0x75, 0x6e, 0x64, 0x12, 0x3a, 0x0a, 0x08, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72,\n\t0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d,\n\t0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x78,\n\t0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x52, 0x08, 0x65, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72,\n\t0x22, 0x3c, 0x0a, 0x0a, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x70, 0x61, 0x6e, 0x12, 0x16,\n\t0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x11, 0x52, 0x06,\n\t0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68,\n\t0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x22, 0x91,\n\t0x01, 0x0a, 0x08, 0x45, 0x78, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x72, 0x12, 0x35, 0x0a, 0x05, 0x6c,\n\t0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x69, 0x6f, 0x2e,\n\t0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,\n\t0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x50, 0x61, 0x69, 0x72, 0x52, 0x05, 0x6c, 0x61, 0x62,\n\t0x65, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,\n\t0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65,\n\t0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,\n\t0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,\n\t0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,\n\t0x6d, 0x70, 0x22, 0xff, 0x02, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x35, 0x0a,\n\t0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x69,\n\t0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69,\n\t0x65, 0x6e, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x50, 0x61, 0x69, 0x72, 0x52, 0x05, 0x6c,\n\t0x61, 0x62, 0x65, 0x6c, 0x12, 0x31, 0x0a, 0x05, 0x67, 0x61, 0x75, 0x67, 0x65, 0x18, 0x02, 0x20,\n\t0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68,\n\t0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x47, 0x61, 0x75, 0x67, 0x65,\n\t0x52, 0x05, 0x67, 0x61, 0x75, 0x67, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74,\n\t0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72,\n\t0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e,\n\t0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72,\n\t0x12, 0x37, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28,\n\t0x0b, 0x32, 0x1d, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75,\n\t0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79,\n\t0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x37, 0x0a, 0x07, 0x75, 0x6e, 0x74,\n\t0x79, 0x70, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x69, 0x6f, 0x2e,\n\t0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e,\n\t0x74, 0x2e, 0x55, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x64, 0x52, 0x07, 0x75, 0x6e, 0x74, 0x79, 0x70,\n\t0x65, 0x64, 0x12, 0x3d, 0x0a, 0x09, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x18,\n\t0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65,\n\t0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x48, 0x69, 0x73,\n\t0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x52, 0x09, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61,\n\t0x6d, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x6d,\n\t0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,\n\t0x6d, 0x70, 0x4d, 0x73, 0x22, 0xb6, 0x01, 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x46,\n\t0x61, 0x6d, 0x69, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,\n\t0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x65, 0x6c,\n\t0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x65, 0x6c, 0x70, 0x12, 0x34, 0x0a,\n\t0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x69, 0x6f,\n\t0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65,\n\t0x6e, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74,\n\t0x79, 0x70, 0x65, 0x12, 0x34, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0x04, 0x20,\n\t0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68,\n\t0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69,\n\t0x63, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x6e, 0x69,\n\t0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x2a, 0x62, 0x0a,\n\t0x0a, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x43,\n\t0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x41, 0x55, 0x47,\n\t0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x4d, 0x4d, 0x41, 0x52, 0x59, 0x10, 0x02,\n\t0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x54, 0x59, 0x50, 0x45, 0x44, 0x10, 0x03, 0x12, 0x0d, 0x0a,\n\t0x09, 0x48, 0x49, 0x53, 0x54, 0x4f, 0x47, 0x52, 0x41, 0x4d, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f,\n\t0x47, 0x41, 0x55, 0x47, 0x45, 0x5f, 0x48, 0x49, 0x53, 0x54, 0x4f, 0x47, 0x52, 0x41, 0x4d, 0x10,\n\t0x05, 0x42, 0x52, 0x0a, 0x14, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65,\n\t0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75,\n\t0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73,\n\t0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2f, 0x67, 0x6f,\n\t0x3b, 0x69, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x5f, 0x63,\n\t0x6c, 0x69, 0x65, 0x6e, 0x74,\n}\n\nvar (\n\tfile_io_prometheus_client_metrics_proto_rawDescOnce sync.Once\n\tfile_io_prometheus_client_metrics_proto_rawDescData = file_io_prometheus_client_metrics_proto_rawDesc\n)\n\nfunc file_io_prometheus_client_metrics_proto_rawDescGZIP() []byte {\n\tfile_io_prometheus_client_metrics_proto_rawDescOnce.Do(func() {\n\t\tfile_io_prometheus_client_metrics_proto_rawDescData = protoimpl.X.CompressGZIP(file_io_prometheus_client_metrics_proto_rawDescData)\n\t})\n\treturn file_io_prometheus_client_metrics_proto_rawDescData\n}\n\nvar file_io_prometheus_client_metrics_proto_enumTypes = make([]protoimpl.EnumInfo, 1)\nvar file_io_prometheus_client_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 12)\nvar file_io_prometheus_client_metrics_proto_goTypes = []interface{}{\n\t(MetricType)(0),               // 0: io.prometheus.client.MetricType\n\t(*LabelPair)(nil),             // 1: io.prometheus.client.LabelPair\n\t(*Gauge)(nil),                 // 2: io.prometheus.client.Gauge\n\t(*Counter)(nil),               // 3: io.prometheus.client.Counter\n\t(*Quantile)(nil),              // 4: io.prometheus.client.Quantile\n\t(*Summary)(nil),               // 5: io.prometheus.client.Summary\n\t(*Untyped)(nil),               // 6: io.prometheus.client.Untyped\n\t(*Histogram)(nil),             // 7: io.prometheus.client.Histogram\n\t(*Bucket)(nil),                // 8: io.prometheus.client.Bucket\n\t(*BucketSpan)(nil),            // 9: io.prometheus.client.BucketSpan\n\t(*Exemplar)(nil),              // 10: io.prometheus.client.Exemplar\n\t(*Metric)(nil),                // 11: io.prometheus.client.Metric\n\t(*MetricFamily)(nil),          // 12: io.prometheus.client.MetricFamily\n\t(*timestamppb.Timestamp)(nil), // 13: google.protobuf.Timestamp\n}\nvar file_io_prometheus_client_metrics_proto_depIdxs = []int32{\n\t10, // 0: io.prometheus.client.Counter.exemplar:type_name -> io.prometheus.client.Exemplar\n\t13, // 1: io.prometheus.client.Counter.created_timestamp:type_name -> google.protobuf.Timestamp\n\t4,  // 2: io.prometheus.client.Summary.quantile:type_name -> io.prometheus.client.Quantile\n\t13, // 3: io.prometheus.client.Summary.created_timestamp:type_name -> google.protobuf.Timestamp\n\t8,  // 4: io.prometheus.client.Histogram.bucket:type_name -> io.prometheus.client.Bucket\n\t13, // 5: io.prometheus.client.Histogram.created_timestamp:type_name -> google.protobuf.Timestamp\n\t9,  // 6: io.prometheus.client.Histogram.negative_span:type_name -> io.prometheus.client.BucketSpan\n\t9,  // 7: io.prometheus.client.Histogram.positive_span:type_name -> io.prometheus.client.BucketSpan\n\t10, // 8: io.prometheus.client.Histogram.exemplars:type_name -> io.prometheus.client.Exemplar\n\t10, // 9: io.prometheus.client.Bucket.exemplar:type_name -> io.prometheus.client.Exemplar\n\t1,  // 10: io.prometheus.client.Exemplar.label:type_name -> io.prometheus.client.LabelPair\n\t13, // 11: io.prometheus.client.Exemplar.timestamp:type_name -> google.protobuf.Timestamp\n\t1,  // 12: io.prometheus.client.Metric.label:type_name -> io.prometheus.client.LabelPair\n\t2,  // 13: io.prometheus.client.Metric.gauge:type_name -> io.prometheus.client.Gauge\n\t3,  // 14: io.prometheus.client.Metric.counter:type_name -> io.prometheus.client.Counter\n\t5,  // 15: io.prometheus.client.Metric.summary:type_name -> io.prometheus.client.Summary\n\t6,  // 16: io.prometheus.client.Metric.untyped:type_name -> io.prometheus.client.Untyped\n\t7,  // 17: io.prometheus.client.Metric.histogram:type_name -> io.prometheus.client.Histogram\n\t0,  // 18: io.prometheus.client.MetricFamily.type:type_name -> io.prometheus.client.MetricType\n\t11, // 19: io.prometheus.client.MetricFamily.metric:type_name -> io.prometheus.client.Metric\n\t20, // [20:20] is the sub-list for method output_type\n\t20, // [20:20] is the sub-list for method input_type\n\t20, // [20:20] is the sub-list for extension type_name\n\t20, // [20:20] is the sub-list for extension extendee\n\t0,  // [0:20] is the sub-list for field type_name\n}\n\nfunc init() { file_io_prometheus_client_metrics_proto_init() }\nfunc file_io_prometheus_client_metrics_proto_init() {\n\tif File_io_prometheus_client_metrics_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_io_prometheus_client_metrics_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*LabelPair); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_io_prometheus_client_metrics_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Gauge); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_io_prometheus_client_metrics_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Counter); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_io_prometheus_client_metrics_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Quantile); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_io_prometheus_client_metrics_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Summary); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_io_prometheus_client_metrics_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Untyped); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_io_prometheus_client_metrics_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Histogram); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_io_prometheus_client_metrics_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Bucket); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_io_prometheus_client_metrics_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*BucketSpan); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_io_prometheus_client_metrics_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Exemplar); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_io_prometheus_client_metrics_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Metric); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_io_prometheus_client_metrics_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*MetricFamily); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: file_io_prometheus_client_metrics_proto_rawDesc,\n\t\t\tNumEnums:      1,\n\t\t\tNumMessages:   12,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_io_prometheus_client_metrics_proto_goTypes,\n\t\tDependencyIndexes: file_io_prometheus_client_metrics_proto_depIdxs,\n\t\tEnumInfos:         file_io_prometheus_client_metrics_proto_enumTypes,\n\t\tMessageInfos:      file_io_prometheus_client_metrics_proto_msgTypes,\n\t}.Build()\n\tFile_io_prometheus_client_metrics_proto = out.File\n\tfile_io_prometheus_client_metrics_proto_rawDesc = nil\n\tfile_io_prometheus_client_metrics_proto_goTypes = nil\n\tfile_io_prometheus_client_metrics_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/NOTICE",
    "content": "Common libraries shared by Prometheus Go components.\nCopyright 2015 The Prometheus Authors\n\nThis product includes software developed at\nSoundCloud Ltd. (http://soundcloud.com/).\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/expfmt/decode.go",
    "content": "// Copyright 2015 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage expfmt\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"mime\"\n\t\"net/http\"\n\n\tdto \"github.com/prometheus/client_model/go\"\n\t\"google.golang.org/protobuf/encoding/protodelim\"\n\n\t\"github.com/prometheus/common/model\"\n)\n\n// Decoder types decode an input stream into metric families.\ntype Decoder interface {\n\tDecode(*dto.MetricFamily) error\n}\n\n// DecodeOptions contains options used by the Decoder and in sample extraction.\ntype DecodeOptions struct {\n\t// Timestamp is added to each value from the stream that has no explicit timestamp set.\n\tTimestamp model.Time\n}\n\n// ResponseFormat extracts the correct format from a HTTP response header.\n// If no matching format can be found FormatUnknown is returned.\nfunc ResponseFormat(h http.Header) Format {\n\tct := h.Get(hdrContentType)\n\n\tmediatype, params, err := mime.ParseMediaType(ct)\n\tif err != nil {\n\t\treturn FmtUnknown\n\t}\n\n\tconst textType = \"text/plain\"\n\n\tswitch mediatype {\n\tcase ProtoType:\n\t\tif p, ok := params[\"proto\"]; ok && p != ProtoProtocol {\n\t\t\treturn FmtUnknown\n\t\t}\n\t\tif e, ok := params[\"encoding\"]; ok && e != \"delimited\" {\n\t\t\treturn FmtUnknown\n\t\t}\n\t\treturn FmtProtoDelim\n\n\tcase textType:\n\t\tif v, ok := params[\"version\"]; ok && v != TextVersion {\n\t\t\treturn FmtUnknown\n\t\t}\n\t\treturn FmtText\n\t}\n\n\treturn FmtUnknown\n}\n\n// NewDecoder returns a new decoder based on the given input format.\n// If the input format does not imply otherwise, a text format decoder is returned.\nfunc NewDecoder(r io.Reader, format Format) Decoder {\n\tswitch format.FormatType() {\n\tcase TypeProtoDelim:\n\t\treturn &protoDecoder{r: bufio.NewReader(r)}\n\t}\n\treturn &textDecoder{r: r}\n}\n\n// protoDecoder implements the Decoder interface for protocol buffers.\ntype protoDecoder struct {\n\tr protodelim.Reader\n}\n\n// Decode implements the Decoder interface.\nfunc (d *protoDecoder) Decode(v *dto.MetricFamily) error {\n\topts := protodelim.UnmarshalOptions{\n\t\tMaxSize: -1,\n\t}\n\tif err := opts.UnmarshalFrom(d.r, v); err != nil {\n\t\treturn err\n\t}\n\tif !model.IsValidMetricName(model.LabelValue(v.GetName())) {\n\t\treturn fmt.Errorf(\"invalid metric name %q\", v.GetName())\n\t}\n\tfor _, m := range v.GetMetric() {\n\t\tif m == nil {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, l := range m.GetLabel() {\n\t\t\tif l == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif !model.LabelValue(l.GetValue()).IsValid() {\n\t\t\t\treturn fmt.Errorf(\"invalid label value %q\", l.GetValue())\n\t\t\t}\n\t\t\tif !model.LabelName(l.GetName()).IsValid() {\n\t\t\t\treturn fmt.Errorf(\"invalid label name %q\", l.GetName())\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// textDecoder implements the Decoder interface for the text protocol.\ntype textDecoder struct {\n\tr    io.Reader\n\tfams map[string]*dto.MetricFamily\n\terr  error\n}\n\n// Decode implements the Decoder interface.\nfunc (d *textDecoder) Decode(v *dto.MetricFamily) error {\n\tif d.err == nil {\n\t\t// Read all metrics in one shot.\n\t\tvar p TextParser\n\t\td.fams, d.err = p.TextToMetricFamilies(d.r)\n\t\t// If we don't get an error, store io.EOF for the end.\n\t\tif d.err == nil {\n\t\t\td.err = io.EOF\n\t\t}\n\t}\n\t// Pick off one MetricFamily per Decode until there's nothing left.\n\tfor key, fam := range d.fams {\n\t\tv.Name = fam.Name\n\t\tv.Help = fam.Help\n\t\tv.Type = fam.Type\n\t\tv.Metric = fam.Metric\n\t\tdelete(d.fams, key)\n\t\treturn nil\n\t}\n\treturn d.err\n}\n\n// SampleDecoder wraps a Decoder to extract samples from the metric families\n// decoded by the wrapped Decoder.\ntype SampleDecoder struct {\n\tDec  Decoder\n\tOpts *DecodeOptions\n\n\tf dto.MetricFamily\n}\n\n// Decode calls the Decode method of the wrapped Decoder and then extracts the\n// samples from the decoded MetricFamily into the provided model.Vector.\nfunc (sd *SampleDecoder) Decode(s *model.Vector) error {\n\terr := sd.Dec.Decode(&sd.f)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*s, err = extractSamples(&sd.f, sd.Opts)\n\treturn err\n}\n\n// ExtractSamples builds a slice of samples from the provided metric\n// families. If an error occurs during sample extraction, it continues to\n// extract from the remaining metric families. The returned error is the last\n// error that has occurred.\nfunc ExtractSamples(o *DecodeOptions, fams ...*dto.MetricFamily) (model.Vector, error) {\n\tvar (\n\t\tall     model.Vector\n\t\tlastErr error\n\t)\n\tfor _, f := range fams {\n\t\tsome, err := extractSamples(f, o)\n\t\tif err != nil {\n\t\t\tlastErr = err\n\t\t\tcontinue\n\t\t}\n\t\tall = append(all, some...)\n\t}\n\treturn all, lastErr\n}\n\nfunc extractSamples(f *dto.MetricFamily, o *DecodeOptions) (model.Vector, error) {\n\tswitch f.GetType() {\n\tcase dto.MetricType_COUNTER:\n\t\treturn extractCounter(o, f), nil\n\tcase dto.MetricType_GAUGE:\n\t\treturn extractGauge(o, f), nil\n\tcase dto.MetricType_SUMMARY:\n\t\treturn extractSummary(o, f), nil\n\tcase dto.MetricType_UNTYPED:\n\t\treturn extractUntyped(o, f), nil\n\tcase dto.MetricType_HISTOGRAM:\n\t\treturn extractHistogram(o, f), nil\n\t}\n\treturn nil, fmt.Errorf(\"expfmt.extractSamples: unknown metric family type %v\", f.GetType())\n}\n\nfunc extractCounter(o *DecodeOptions, f *dto.MetricFamily) model.Vector {\n\tsamples := make(model.Vector, 0, len(f.Metric))\n\n\tfor _, m := range f.Metric {\n\t\tif m.Counter == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tlset := make(model.LabelSet, len(m.Label)+1)\n\t\tfor _, p := range m.Label {\n\t\t\tlset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())\n\t\t}\n\t\tlset[model.MetricNameLabel] = model.LabelValue(f.GetName())\n\n\t\tsmpl := &model.Sample{\n\t\t\tMetric: model.Metric(lset),\n\t\t\tValue:  model.SampleValue(m.Counter.GetValue()),\n\t\t}\n\n\t\tif m.TimestampMs != nil {\n\t\t\tsmpl.Timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000)\n\t\t} else {\n\t\t\tsmpl.Timestamp = o.Timestamp\n\t\t}\n\n\t\tsamples = append(samples, smpl)\n\t}\n\n\treturn samples\n}\n\nfunc extractGauge(o *DecodeOptions, f *dto.MetricFamily) model.Vector {\n\tsamples := make(model.Vector, 0, len(f.Metric))\n\n\tfor _, m := range f.Metric {\n\t\tif m.Gauge == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tlset := make(model.LabelSet, len(m.Label)+1)\n\t\tfor _, p := range m.Label {\n\t\t\tlset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())\n\t\t}\n\t\tlset[model.MetricNameLabel] = model.LabelValue(f.GetName())\n\n\t\tsmpl := &model.Sample{\n\t\t\tMetric: model.Metric(lset),\n\t\t\tValue:  model.SampleValue(m.Gauge.GetValue()),\n\t\t}\n\n\t\tif m.TimestampMs != nil {\n\t\t\tsmpl.Timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000)\n\t\t} else {\n\t\t\tsmpl.Timestamp = o.Timestamp\n\t\t}\n\n\t\tsamples = append(samples, smpl)\n\t}\n\n\treturn samples\n}\n\nfunc extractUntyped(o *DecodeOptions, f *dto.MetricFamily) model.Vector {\n\tsamples := make(model.Vector, 0, len(f.Metric))\n\n\tfor _, m := range f.Metric {\n\t\tif m.Untyped == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tlset := make(model.LabelSet, len(m.Label)+1)\n\t\tfor _, p := range m.Label {\n\t\t\tlset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())\n\t\t}\n\t\tlset[model.MetricNameLabel] = model.LabelValue(f.GetName())\n\n\t\tsmpl := &model.Sample{\n\t\t\tMetric: model.Metric(lset),\n\t\t\tValue:  model.SampleValue(m.Untyped.GetValue()),\n\t\t}\n\n\t\tif m.TimestampMs != nil {\n\t\t\tsmpl.Timestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000)\n\t\t} else {\n\t\t\tsmpl.Timestamp = o.Timestamp\n\t\t}\n\n\t\tsamples = append(samples, smpl)\n\t}\n\n\treturn samples\n}\n\nfunc extractSummary(o *DecodeOptions, f *dto.MetricFamily) model.Vector {\n\tsamples := make(model.Vector, 0, len(f.Metric))\n\n\tfor _, m := range f.Metric {\n\t\tif m.Summary == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\ttimestamp := o.Timestamp\n\t\tif m.TimestampMs != nil {\n\t\t\ttimestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000)\n\t\t}\n\n\t\tfor _, q := range m.Summary.Quantile {\n\t\t\tlset := make(model.LabelSet, len(m.Label)+2)\n\t\t\tfor _, p := range m.Label {\n\t\t\t\tlset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())\n\t\t\t}\n\t\t\t// BUG(matt): Update other names to \"quantile\".\n\t\t\tlset[model.LabelName(model.QuantileLabel)] = model.LabelValue(fmt.Sprint(q.GetQuantile()))\n\t\t\tlset[model.MetricNameLabel] = model.LabelValue(f.GetName())\n\n\t\t\tsamples = append(samples, &model.Sample{\n\t\t\t\tMetric:    model.Metric(lset),\n\t\t\t\tValue:     model.SampleValue(q.GetValue()),\n\t\t\t\tTimestamp: timestamp,\n\t\t\t})\n\t\t}\n\n\t\tlset := make(model.LabelSet, len(m.Label)+1)\n\t\tfor _, p := range m.Label {\n\t\t\tlset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())\n\t\t}\n\t\tlset[model.MetricNameLabel] = model.LabelValue(f.GetName() + \"_sum\")\n\n\t\tsamples = append(samples, &model.Sample{\n\t\t\tMetric:    model.Metric(lset),\n\t\t\tValue:     model.SampleValue(m.Summary.GetSampleSum()),\n\t\t\tTimestamp: timestamp,\n\t\t})\n\n\t\tlset = make(model.LabelSet, len(m.Label)+1)\n\t\tfor _, p := range m.Label {\n\t\t\tlset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())\n\t\t}\n\t\tlset[model.MetricNameLabel] = model.LabelValue(f.GetName() + \"_count\")\n\n\t\tsamples = append(samples, &model.Sample{\n\t\t\tMetric:    model.Metric(lset),\n\t\t\tValue:     model.SampleValue(m.Summary.GetSampleCount()),\n\t\t\tTimestamp: timestamp,\n\t\t})\n\t}\n\n\treturn samples\n}\n\nfunc extractHistogram(o *DecodeOptions, f *dto.MetricFamily) model.Vector {\n\tsamples := make(model.Vector, 0, len(f.Metric))\n\n\tfor _, m := range f.Metric {\n\t\tif m.Histogram == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\ttimestamp := o.Timestamp\n\t\tif m.TimestampMs != nil {\n\t\t\ttimestamp = model.TimeFromUnixNano(*m.TimestampMs * 1000000)\n\t\t}\n\n\t\tinfSeen := false\n\n\t\tfor _, q := range m.Histogram.Bucket {\n\t\t\tlset := make(model.LabelSet, len(m.Label)+2)\n\t\t\tfor _, p := range m.Label {\n\t\t\t\tlset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())\n\t\t\t}\n\t\t\tlset[model.LabelName(model.BucketLabel)] = model.LabelValue(fmt.Sprint(q.GetUpperBound()))\n\t\t\tlset[model.MetricNameLabel] = model.LabelValue(f.GetName() + \"_bucket\")\n\n\t\t\tif math.IsInf(q.GetUpperBound(), +1) {\n\t\t\t\tinfSeen = true\n\t\t\t}\n\n\t\t\tsamples = append(samples, &model.Sample{\n\t\t\t\tMetric:    model.Metric(lset),\n\t\t\t\tValue:     model.SampleValue(q.GetCumulativeCount()),\n\t\t\t\tTimestamp: timestamp,\n\t\t\t})\n\t\t}\n\n\t\tlset := make(model.LabelSet, len(m.Label)+1)\n\t\tfor _, p := range m.Label {\n\t\t\tlset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())\n\t\t}\n\t\tlset[model.MetricNameLabel] = model.LabelValue(f.GetName() + \"_sum\")\n\n\t\tsamples = append(samples, &model.Sample{\n\t\t\tMetric:    model.Metric(lset),\n\t\t\tValue:     model.SampleValue(m.Histogram.GetSampleSum()),\n\t\t\tTimestamp: timestamp,\n\t\t})\n\n\t\tlset = make(model.LabelSet, len(m.Label)+1)\n\t\tfor _, p := range m.Label {\n\t\t\tlset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())\n\t\t}\n\t\tlset[model.MetricNameLabel] = model.LabelValue(f.GetName() + \"_count\")\n\n\t\tcount := &model.Sample{\n\t\t\tMetric:    model.Metric(lset),\n\t\t\tValue:     model.SampleValue(m.Histogram.GetSampleCount()),\n\t\t\tTimestamp: timestamp,\n\t\t}\n\t\tsamples = append(samples, count)\n\n\t\tif !infSeen {\n\t\t\t// Append an infinity bucket sample.\n\t\t\tlset := make(model.LabelSet, len(m.Label)+2)\n\t\t\tfor _, p := range m.Label {\n\t\t\t\tlset[model.LabelName(p.GetName())] = model.LabelValue(p.GetValue())\n\t\t\t}\n\t\t\tlset[model.LabelName(model.BucketLabel)] = model.LabelValue(\"+Inf\")\n\t\t\tlset[model.MetricNameLabel] = model.LabelValue(f.GetName() + \"_bucket\")\n\n\t\t\tsamples = append(samples, &model.Sample{\n\t\t\t\tMetric:    model.Metric(lset),\n\t\t\t\tValue:     count.Value,\n\t\t\t\tTimestamp: timestamp,\n\t\t\t})\n\t\t}\n\t}\n\n\treturn samples\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/expfmt/encode.go",
    "content": "// Copyright 2015 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage expfmt\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\n\t\"google.golang.org/protobuf/encoding/protodelim\"\n\t\"google.golang.org/protobuf/encoding/prototext\"\n\n\t\"github.com/prometheus/common/model\"\n\n\t\"github.com/munnerz/goautoneg\"\n\n\tdto \"github.com/prometheus/client_model/go\"\n)\n\n// Encoder types encode metric families into an underlying wire protocol.\ntype Encoder interface {\n\tEncode(*dto.MetricFamily) error\n}\n\n// Closer is implemented by Encoders that need to be closed to finalize\n// encoding. (For example, OpenMetrics needs a final `# EOF` line.)\n//\n// Note that all Encoder implementations returned from this package implement\n// Closer, too, even if the Close call is a no-op. This happens in preparation\n// for adding a Close method to the Encoder interface directly in a (mildly\n// breaking) release in the future.\ntype Closer interface {\n\tClose() error\n}\n\ntype encoderCloser struct {\n\tencode func(*dto.MetricFamily) error\n\tclose  func() error\n}\n\nfunc (ec encoderCloser) Encode(v *dto.MetricFamily) error {\n\treturn ec.encode(v)\n}\n\nfunc (ec encoderCloser) Close() error {\n\treturn ec.close()\n}\n\n// Negotiate returns the Content-Type based on the given Accept header. If no\n// appropriate accepted type is found, FmtText is returned (which is the\n// Prometheus text format). This function will never negotiate FmtOpenMetrics,\n// as the support is still experimental. To include the option to negotiate\n// FmtOpenMetrics, use NegotiateOpenMetrics.\nfunc Negotiate(h http.Header) Format {\n\tescapingScheme := Format(fmt.Sprintf(\"; escaping=%s\", Format(model.NameEscapingScheme.String())))\n\tfor _, ac := range goautoneg.ParseAccept(h.Get(hdrAccept)) {\n\t\tif escapeParam := ac.Params[model.EscapingKey]; escapeParam != \"\" {\n\t\t\tswitch Format(escapeParam) {\n\t\t\tcase model.AllowUTF8, model.EscapeUnderscores, model.EscapeDots, model.EscapeValues:\n\t\t\t\tescapingScheme = Format(\"; escaping=\" + escapeParam)\n\t\t\tdefault:\n\t\t\t\t// If the escaping parameter is unknown, ignore it.\n\t\t\t}\n\t\t}\n\t\tver := ac.Params[\"version\"]\n\t\tif ac.Type+\"/\"+ac.SubType == ProtoType && ac.Params[\"proto\"] == ProtoProtocol {\n\t\t\tswitch ac.Params[\"encoding\"] {\n\t\t\tcase \"delimited\":\n\t\t\t\treturn FmtProtoDelim + escapingScheme\n\t\t\tcase \"text\":\n\t\t\t\treturn FmtProtoText + escapingScheme\n\t\t\tcase \"compact-text\":\n\t\t\t\treturn FmtProtoCompact + escapingScheme\n\t\t\t}\n\t\t}\n\t\tif ac.Type == \"text\" && ac.SubType == \"plain\" && (ver == TextVersion || ver == \"\") {\n\t\t\treturn FmtText + escapingScheme\n\t\t}\n\t}\n\treturn FmtText + escapingScheme\n}\n\n// NegotiateIncludingOpenMetrics works like Negotiate but includes\n// FmtOpenMetrics as an option for the result. Note that this function is\n// temporary and will disappear once FmtOpenMetrics is fully supported and as\n// such may be negotiated by the normal Negotiate function.\nfunc NegotiateIncludingOpenMetrics(h http.Header) Format {\n\tescapingScheme := Format(fmt.Sprintf(\"; escaping=%s\", Format(model.NameEscapingScheme.String())))\n\tfor _, ac := range goautoneg.ParseAccept(h.Get(hdrAccept)) {\n\t\tif escapeParam := ac.Params[model.EscapingKey]; escapeParam != \"\" {\n\t\t\tswitch Format(escapeParam) {\n\t\t\tcase model.AllowUTF8, model.EscapeUnderscores, model.EscapeDots, model.EscapeValues:\n\t\t\t\tescapingScheme = Format(\"; escaping=\" + escapeParam)\n\t\t\tdefault:\n\t\t\t\t// If the escaping parameter is unknown, ignore it.\n\t\t\t}\n\t\t}\n\t\tver := ac.Params[\"version\"]\n\t\tif ac.Type+\"/\"+ac.SubType == ProtoType && ac.Params[\"proto\"] == ProtoProtocol {\n\t\t\tswitch ac.Params[\"encoding\"] {\n\t\t\tcase \"delimited\":\n\t\t\t\treturn FmtProtoDelim + escapingScheme\n\t\t\tcase \"text\":\n\t\t\t\treturn FmtProtoText + escapingScheme\n\t\t\tcase \"compact-text\":\n\t\t\t\treturn FmtProtoCompact + escapingScheme\n\t\t\t}\n\t\t}\n\t\tif ac.Type == \"text\" && ac.SubType == \"plain\" && (ver == TextVersion || ver == \"\") {\n\t\t\treturn FmtText + escapingScheme\n\t\t}\n\t\tif ac.Type+\"/\"+ac.SubType == OpenMetricsType && (ver == OpenMetricsVersion_0_0_1 || ver == OpenMetricsVersion_1_0_0 || ver == \"\") {\n\t\t\tswitch ver {\n\t\t\tcase OpenMetricsVersion_1_0_0:\n\t\t\t\treturn FmtOpenMetrics_1_0_0 + escapingScheme\n\t\t\tdefault:\n\t\t\t\treturn FmtOpenMetrics_0_0_1 + escapingScheme\n\t\t\t}\n\t\t}\n\t}\n\treturn FmtText + escapingScheme\n}\n\n// NewEncoder returns a new encoder based on content type negotiation. All\n// Encoder implementations returned by NewEncoder also implement Closer, and\n// callers should always call the Close method. It is currently only required\n// for FmtOpenMetrics, but a future (breaking) release will add the Close method\n// to the Encoder interface directly. The current version of the Encoder\n// interface is kept for backwards compatibility.\n// In cases where the Format does not allow for UTF-8 names, the global\n// NameEscapingScheme will be applied.\n//\n// NewEncoder can be called with additional options to customize the OpenMetrics text output.\n// For example:\n// NewEncoder(w, FmtOpenMetrics_1_0_0, WithCreatedLines())\n//\n// Extra options are ignored for all other formats.\nfunc NewEncoder(w io.Writer, format Format, options ...EncoderOption) Encoder {\n\tescapingScheme := format.ToEscapingScheme()\n\n\tswitch format.FormatType() {\n\tcase TypeProtoDelim:\n\t\treturn encoderCloser{\n\t\t\tencode: func(v *dto.MetricFamily) error {\n\t\t\t\t_, err := protodelim.MarshalTo(w, v)\n\t\t\t\treturn err\n\t\t\t},\n\t\t\tclose: func() error { return nil },\n\t\t}\n\tcase TypeProtoCompact:\n\t\treturn encoderCloser{\n\t\t\tencode: func(v *dto.MetricFamily) error {\n\t\t\t\t_, err := fmt.Fprintln(w, model.EscapeMetricFamily(v, escapingScheme).String())\n\t\t\t\treturn err\n\t\t\t},\n\t\t\tclose: func() error { return nil },\n\t\t}\n\tcase TypeProtoText:\n\t\treturn encoderCloser{\n\t\t\tencode: func(v *dto.MetricFamily) error {\n\t\t\t\t_, err := fmt.Fprintln(w, prototext.Format(model.EscapeMetricFamily(v, escapingScheme)))\n\t\t\t\treturn err\n\t\t\t},\n\t\t\tclose: func() error { return nil },\n\t\t}\n\tcase TypeTextPlain:\n\t\treturn encoderCloser{\n\t\t\tencode: func(v *dto.MetricFamily) error {\n\t\t\t\t_, err := MetricFamilyToText(w, model.EscapeMetricFamily(v, escapingScheme))\n\t\t\t\treturn err\n\t\t\t},\n\t\t\tclose: func() error { return nil },\n\t\t}\n\tcase TypeOpenMetrics:\n\t\treturn encoderCloser{\n\t\t\tencode: func(v *dto.MetricFamily) error {\n\t\t\t\t_, err := MetricFamilyToOpenMetrics(w, model.EscapeMetricFamily(v, escapingScheme), options...)\n\t\t\t\treturn err\n\t\t\t},\n\t\t\tclose: func() error {\n\t\t\t\t_, err := FinalizeOpenMetrics(w)\n\t\t\t\treturn err\n\t\t\t},\n\t\t}\n\t}\n\tpanic(fmt.Errorf(\"expfmt.NewEncoder: unknown format %q\", format))\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/expfmt/expfmt.go",
    "content": "// Copyright 2015 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Package expfmt contains tools for reading and writing Prometheus metrics.\npackage expfmt\n\nimport (\n\t\"errors\"\n\t\"strings\"\n\n\t\"github.com/prometheus/common/model\"\n)\n\n// Format specifies the HTTP content type of the different wire protocols.\ntype Format string\n\n// Constants to assemble the Content-Type values for the different wire\n// protocols. The Content-Type strings here are all for the legacy exposition\n// formats, where valid characters for metric names and label names are limited.\n// Support for arbitrary UTF-8 characters in those names is already partially\n// implemented in this module (see model.ValidationScheme), but to actually use\n// it on the wire, new content-type strings will have to be agreed upon and\n// added here.\nconst (\n\tTextVersion   = \"0.0.4\"\n\tProtoType     = `application/vnd.google.protobuf`\n\tProtoProtocol = `io.prometheus.client.MetricFamily`\n\t// Deprecated: Use expfmt.NewFormat(expfmt.TypeProtoCompact) instead.\n\tProtoFmt                 = ProtoType + \"; proto=\" + ProtoProtocol + \";\"\n\tOpenMetricsType          = `application/openmetrics-text`\n\tOpenMetricsVersion_0_0_1 = \"0.0.1\"\n\tOpenMetricsVersion_1_0_0 = \"1.0.0\"\n\n\t// The Content-Type values for the different wire protocols. Do not do direct\n\t// comparisons to these constants, instead use the comparison functions.\n\t// Deprecated: Use expfmt.NewFormat(expfmt.TypeUnknown) instead.\n\tFmtUnknown Format = `<unknown>`\n\t// Deprecated: Use expfmt.NewFormat(expfmt.TypeTextPlain) instead.\n\tFmtText Format = `text/plain; version=` + TextVersion + `; charset=utf-8`\n\t// Deprecated: Use expfmt.NewFormat(expfmt.TypeProtoDelim) instead.\n\tFmtProtoDelim Format = ProtoFmt + ` encoding=delimited`\n\t// Deprecated: Use expfmt.NewFormat(expfmt.TypeProtoText) instead.\n\tFmtProtoText Format = ProtoFmt + ` encoding=text`\n\t// Deprecated: Use expfmt.NewFormat(expfmt.TypeProtoCompact) instead.\n\tFmtProtoCompact Format = ProtoFmt + ` encoding=compact-text`\n\t// Deprecated: Use expfmt.NewFormat(expfmt.TypeOpenMetrics) instead.\n\tFmtOpenMetrics_1_0_0 Format = OpenMetricsType + `; version=` + OpenMetricsVersion_1_0_0 + `; charset=utf-8`\n\t// Deprecated: Use expfmt.NewFormat(expfmt.TypeOpenMetrics) instead.\n\tFmtOpenMetrics_0_0_1 Format = OpenMetricsType + `; version=` + OpenMetricsVersion_0_0_1 + `; charset=utf-8`\n)\n\nconst (\n\thdrContentType = \"Content-Type\"\n\thdrAccept      = \"Accept\"\n)\n\n// FormatType is a Go enum representing the overall category for the given\n// Format. As the number of Format permutations increases, doing basic string\n// comparisons are not feasible, so this enum captures the most useful\n// high-level attribute of the Format string.\ntype FormatType int\n\nconst (\n\tTypeUnknown FormatType = iota\n\tTypeProtoCompact\n\tTypeProtoDelim\n\tTypeProtoText\n\tTypeTextPlain\n\tTypeOpenMetrics\n)\n\n// NewFormat generates a new Format from the type provided. Mostly used for\n// tests, most Formats should be generated as part of content negotiation in\n// encode.go. If a type has more than one version, the latest version will be\n// returned.\nfunc NewFormat(t FormatType) Format {\n\tswitch t {\n\tcase TypeProtoCompact:\n\t\treturn FmtProtoCompact\n\tcase TypeProtoDelim:\n\t\treturn FmtProtoDelim\n\tcase TypeProtoText:\n\t\treturn FmtProtoText\n\tcase TypeTextPlain:\n\t\treturn FmtText\n\tcase TypeOpenMetrics:\n\t\treturn FmtOpenMetrics_1_0_0\n\tdefault:\n\t\treturn FmtUnknown\n\t}\n}\n\n// NewOpenMetricsFormat generates a new OpenMetrics format matching the\n// specified version number.\nfunc NewOpenMetricsFormat(version string) (Format, error) {\n\tif version == OpenMetricsVersion_0_0_1 {\n\t\treturn FmtOpenMetrics_0_0_1, nil\n\t}\n\tif version == OpenMetricsVersion_1_0_0 {\n\t\treturn FmtOpenMetrics_1_0_0, nil\n\t}\n\treturn FmtUnknown, errors.New(\"unknown open metrics version string\")\n}\n\n// WithEscapingScheme returns a copy of Format with the specified escaping\n// scheme appended to the end. If an escaping scheme already exists it is\n// removed.\nfunc (f Format) WithEscapingScheme(s model.EscapingScheme) Format {\n\tvar terms []string\n\tfor _, p := range strings.Split(string(f), \";\") {\n\t\ttoks := strings.Split(p, \"=\")\n\t\tif len(toks) != 2 {\n\t\t\ttrimmed := strings.TrimSpace(p)\n\t\t\tif len(trimmed) > 0 {\n\t\t\t\tterms = append(terms, trimmed)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tkey := strings.TrimSpace(toks[0])\n\t\tif key != model.EscapingKey {\n\t\t\tterms = append(terms, strings.TrimSpace(p))\n\t\t}\n\t}\n\tterms = append(terms, model.EscapingKey+\"=\"+s.String())\n\treturn Format(strings.Join(terms, \"; \"))\n}\n\n// FormatType deduces an overall FormatType for the given format.\nfunc (f Format) FormatType() FormatType {\n\ttoks := strings.Split(string(f), \";\")\n\tparams := make(map[string]string)\n\tfor i, t := range toks {\n\t\tif i == 0 {\n\t\t\tcontinue\n\t\t}\n\t\targs := strings.Split(t, \"=\")\n\t\tif len(args) != 2 {\n\t\t\tcontinue\n\t\t}\n\t\tparams[strings.TrimSpace(args[0])] = strings.TrimSpace(args[1])\n\t}\n\n\tswitch strings.TrimSpace(toks[0]) {\n\tcase ProtoType:\n\t\tif params[\"proto\"] != ProtoProtocol {\n\t\t\treturn TypeUnknown\n\t\t}\n\t\tswitch params[\"encoding\"] {\n\t\tcase \"delimited\":\n\t\t\treturn TypeProtoDelim\n\t\tcase \"text\":\n\t\t\treturn TypeProtoText\n\t\tcase \"compact-text\":\n\t\t\treturn TypeProtoCompact\n\t\tdefault:\n\t\t\treturn TypeUnknown\n\t\t}\n\tcase OpenMetricsType:\n\t\tif params[\"charset\"] != \"utf-8\" {\n\t\t\treturn TypeUnknown\n\t\t}\n\t\treturn TypeOpenMetrics\n\tcase \"text/plain\":\n\t\tv, ok := params[\"version\"]\n\t\tif !ok {\n\t\t\treturn TypeTextPlain\n\t\t}\n\t\tif v == TextVersion {\n\t\t\treturn TypeTextPlain\n\t\t}\n\t\treturn TypeUnknown\n\tdefault:\n\t\treturn TypeUnknown\n\t}\n}\n\n// ToEscapingScheme returns an EscapingScheme depending on the Format. Iff the\n// Format contains a escaping=allow-utf-8 term, it will select NoEscaping. If a valid\n// \"escaping\" term exists, that will be used. Otherwise, the global default will\n// be returned.\nfunc (format Format) ToEscapingScheme() model.EscapingScheme {\n\tfor _, p := range strings.Split(string(format), \";\") {\n\t\ttoks := strings.Split(p, \"=\")\n\t\tif len(toks) != 2 {\n\t\t\tcontinue\n\t\t}\n\t\tkey, value := strings.TrimSpace(toks[0]), strings.TrimSpace(toks[1])\n\t\tif key == model.EscapingKey {\n\t\t\tscheme, err := model.ToEscapingScheme(value)\n\t\t\tif err != nil {\n\t\t\t\treturn model.NameEscapingScheme\n\t\t\t}\n\t\t\treturn scheme\n\t\t}\n\t}\n\treturn model.NameEscapingScheme\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/expfmt/fuzz.go",
    "content": "// Copyright 2014 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Build only when actually fuzzing\n//go:build gofuzz\n// +build gofuzz\n\npackage expfmt\n\nimport \"bytes\"\n\n// Fuzz text metric parser with with github.com/dvyukov/go-fuzz:\n//\n//\tgo-fuzz-build github.com/prometheus/common/expfmt\n//\tgo-fuzz -bin expfmt-fuzz.zip -workdir fuzz\n//\n// Further input samples should go in the folder fuzz/corpus.\nfunc Fuzz(in []byte) int {\n\tparser := TextParser{}\n\t_, err := parser.TextToMetricFamilies(bytes.NewReader(in))\n\n\tif err != nil {\n\t\treturn 0\n\t}\n\n\treturn 1\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/expfmt/openmetrics_create.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage expfmt\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"google.golang.org/protobuf/types/known/timestamppb\"\n\n\t\"github.com/prometheus/common/model\"\n\n\tdto \"github.com/prometheus/client_model/go\"\n)\n\ntype encoderOption struct {\n\twithCreatedLines bool\n\twithUnit         bool\n}\n\ntype EncoderOption func(*encoderOption)\n\n// WithCreatedLines is an EncoderOption that configures the OpenMetrics encoder\n// to include _created lines (See\n// https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#counter-1).\n// Created timestamps can improve the accuracy of series reset detection, but\n// come with a bandwidth cost.\n//\n// At the time of writing, created timestamp ingestion is still experimental in\n// Prometheus and need to be enabled with the feature-flag\n// `--feature-flag=created-timestamp-zero-ingestion`, and breaking changes are\n// still possible. Therefore, it is recommended to use this feature with caution.\nfunc WithCreatedLines() EncoderOption {\n\treturn func(t *encoderOption) {\n\t\tt.withCreatedLines = true\n\t}\n}\n\n// WithUnit is an EncoderOption enabling a set unit to be written to the output\n// and to be added to the metric name, if it's not there already, as a suffix.\n// Without opting in this way, the unit will not be added to the metric name and,\n// on top of that, the unit will not be passed onto the output, even if it\n// were declared in the *dto.MetricFamily struct, i.e. even if in.Unit !=nil.\nfunc WithUnit() EncoderOption {\n\treturn func(t *encoderOption) {\n\t\tt.withUnit = true\n\t}\n}\n\n// MetricFamilyToOpenMetrics converts a MetricFamily proto message into the\n// OpenMetrics text format and writes the resulting lines to 'out'. It returns\n// the number of bytes written and any error encountered. The output will have\n// the same order as the input, no further sorting is performed. Furthermore,\n// this function assumes the input is already sanitized and does not perform any\n// sanity checks. If the input contains duplicate metrics or invalid metric or\n// label names, the conversion will result in invalid text format output.\n//\n// If metric names conform to the legacy validation pattern, they will be placed\n// outside the brackets in the traditional way, like `foo{}`. If the metric name\n// fails the legacy validation check, it will be placed quoted inside the\n// brackets: `{\"foo\"}`. As stated above, the input is assumed to be santized and\n// no error will be thrown in this case.\n//\n// Similar to metric names, if label names conform to the legacy validation\n// pattern, they will be unquoted as normal, like `foo{bar=\"baz\"}`. If the label\n// name fails the legacy validation check, it will be quoted:\n// `foo{\"bar\"=\"baz\"}`. As stated above, the input is assumed to be santized and\n// no error will be thrown in this case.\n//\n// This function fulfills the type 'expfmt.encoder'.\n//\n// Note that OpenMetrics requires a final `# EOF` line. Since this function acts\n// on individual metric families, it is the responsibility of the caller to\n// append this line to 'out' once all metric families have been written.\n// Conveniently, this can be done by calling FinalizeOpenMetrics.\n//\n// The output should be fully OpenMetrics compliant. However, there are a few\n// missing features and peculiarities to avoid complications when switching from\n// Prometheus to OpenMetrics or vice versa:\n//\n//   - Counters are expected to have the `_total` suffix in their metric name. In\n//     the output, the suffix will be truncated from the `# TYPE`, `# HELP` and `# UNIT`\n//     lines. A counter with a missing `_total` suffix is not an error. However,\n//     its type will be set to `unknown` in that case to avoid invalid OpenMetrics\n//     output.\n//\n//   - According to the OM specs, the `# UNIT` line is optional, but if populated,\n//     the unit has to be present in the metric name as its suffix:\n//     (see https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#unit).\n//     However, in order to accommodate any potential scenario where such a change in the\n//     metric name is not desirable, the users are here given the choice of either explicitly\n//     opt in, in case they wish for the unit to be included in the output AND in the metric name\n//     as a suffix (see the description of the WithUnit function above),\n//     or not to opt in, in case they don't want for any of that to happen.\n//\n//   - No support for the following (optional) features: info type,\n//     stateset type, gaugehistogram type.\n//\n//   - The size of exemplar labels is not checked (i.e. it's possible to create\n//     exemplars that are larger than allowed by the OpenMetrics specification).\n//\n//   - The value of Counters is not checked. (OpenMetrics doesn't allow counters\n//     with a `NaN` value.)\nfunc MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily, options ...EncoderOption) (written int, err error) {\n\ttoOM := encoderOption{}\n\tfor _, option := range options {\n\t\toption(&toOM)\n\t}\n\n\tname := in.GetName()\n\tif name == \"\" {\n\t\treturn 0, fmt.Errorf(\"MetricFamily has no name: %s\", in)\n\t}\n\n\t// Try the interface upgrade. If it doesn't work, we'll use a\n\t// bufio.Writer from the sync.Pool.\n\tw, ok := out.(enhancedWriter)\n\tif !ok {\n\t\tb := bufPool.Get().(*bufio.Writer)\n\t\tb.Reset(out)\n\t\tw = b\n\t\tdefer func() {\n\t\t\tbErr := b.Flush()\n\t\t\tif err == nil {\n\t\t\t\terr = bErr\n\t\t\t}\n\t\t\tbufPool.Put(b)\n\t\t}()\n\t}\n\n\tvar (\n\t\tn             int\n\t\tmetricType    = in.GetType()\n\t\tcompliantName = name\n\t)\n\tif metricType == dto.MetricType_COUNTER && strings.HasSuffix(compliantName, \"_total\") {\n\t\tcompliantName = name[:len(name)-6]\n\t}\n\tif toOM.withUnit && in.Unit != nil && !strings.HasSuffix(compliantName, \"_\"+*in.Unit) {\n\t\tcompliantName = compliantName + \"_\" + *in.Unit\n\t}\n\n\t// Comments, first HELP, then TYPE.\n\tif in.Help != nil {\n\t\tn, err = w.WriteString(\"# HELP \")\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tn, err = writeName(w, compliantName)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\terr = w.WriteByte(' ')\n\t\twritten++\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tn, err = writeEscapedString(w, *in.Help, true)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\terr = w.WriteByte('\\n')\n\t\twritten++\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\tn, err = w.WriteString(\"# TYPE \")\n\twritten += n\n\tif err != nil {\n\t\treturn\n\t}\n\tn, err = writeName(w, compliantName)\n\twritten += n\n\tif err != nil {\n\t\treturn\n\t}\n\tswitch metricType {\n\tcase dto.MetricType_COUNTER:\n\t\tif strings.HasSuffix(name, \"_total\") {\n\t\t\tn, err = w.WriteString(\" counter\\n\")\n\t\t} else {\n\t\t\tn, err = w.WriteString(\" unknown\\n\")\n\t\t}\n\tcase dto.MetricType_GAUGE:\n\t\tn, err = w.WriteString(\" gauge\\n\")\n\tcase dto.MetricType_SUMMARY:\n\t\tn, err = w.WriteString(\" summary\\n\")\n\tcase dto.MetricType_UNTYPED:\n\t\tn, err = w.WriteString(\" unknown\\n\")\n\tcase dto.MetricType_HISTOGRAM:\n\t\tn, err = w.WriteString(\" histogram\\n\")\n\tdefault:\n\t\treturn written, fmt.Errorf(\"unknown metric type %s\", metricType.String())\n\t}\n\twritten += n\n\tif err != nil {\n\t\treturn\n\t}\n\tif toOM.withUnit && in.Unit != nil {\n\t\tn, err = w.WriteString(\"# UNIT \")\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tn, err = writeName(w, compliantName)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\n\t\terr = w.WriteByte(' ')\n\t\twritten++\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tn, err = writeEscapedString(w, *in.Unit, true)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\terr = w.WriteByte('\\n')\n\t\twritten++\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tvar createdTsBytesWritten int\n\n\t// Finally the samples, one line for each.\n\tif metricType == dto.MetricType_COUNTER && strings.HasSuffix(name, \"_total\") {\n\t\tcompliantName = compliantName + \"_total\"\n\t}\n\tfor _, metric := range in.Metric {\n\t\tswitch metricType {\n\t\tcase dto.MetricType_COUNTER:\n\t\t\tif metric.Counter == nil {\n\t\t\t\treturn written, fmt.Errorf(\n\t\t\t\t\t\"expected counter in metric %s %s\", compliantName, metric,\n\t\t\t\t)\n\t\t\t}\n\t\t\tn, err = writeOpenMetricsSample(\n\t\t\t\tw, compliantName, \"\", metric, \"\", 0,\n\t\t\t\tmetric.Counter.GetValue(), 0, false,\n\t\t\t\tmetric.Counter.Exemplar,\n\t\t\t)\n\t\t\tif toOM.withCreatedLines && metric.Counter.CreatedTimestamp != nil {\n\t\t\t\tcreatedTsBytesWritten, err = writeOpenMetricsCreated(w, compliantName, \"_total\", metric, \"\", 0, metric.Counter.GetCreatedTimestamp())\n\t\t\t\tn += createdTsBytesWritten\n\t\t\t}\n\t\tcase dto.MetricType_GAUGE:\n\t\t\tif metric.Gauge == nil {\n\t\t\t\treturn written, fmt.Errorf(\n\t\t\t\t\t\"expected gauge in metric %s %s\", compliantName, metric,\n\t\t\t\t)\n\t\t\t}\n\t\t\tn, err = writeOpenMetricsSample(\n\t\t\t\tw, compliantName, \"\", metric, \"\", 0,\n\t\t\t\tmetric.Gauge.GetValue(), 0, false,\n\t\t\t\tnil,\n\t\t\t)\n\t\tcase dto.MetricType_UNTYPED:\n\t\t\tif metric.Untyped == nil {\n\t\t\t\treturn written, fmt.Errorf(\n\t\t\t\t\t\"expected untyped in metric %s %s\", compliantName, metric,\n\t\t\t\t)\n\t\t\t}\n\t\t\tn, err = writeOpenMetricsSample(\n\t\t\t\tw, compliantName, \"\", metric, \"\", 0,\n\t\t\t\tmetric.Untyped.GetValue(), 0, false,\n\t\t\t\tnil,\n\t\t\t)\n\t\tcase dto.MetricType_SUMMARY:\n\t\t\tif metric.Summary == nil {\n\t\t\t\treturn written, fmt.Errorf(\n\t\t\t\t\t\"expected summary in metric %s %s\", compliantName, metric,\n\t\t\t\t)\n\t\t\t}\n\t\t\tfor _, q := range metric.Summary.Quantile {\n\t\t\t\tn, err = writeOpenMetricsSample(\n\t\t\t\t\tw, compliantName, \"\", metric,\n\t\t\t\t\tmodel.QuantileLabel, q.GetQuantile(),\n\t\t\t\t\tq.GetValue(), 0, false,\n\t\t\t\t\tnil,\n\t\t\t\t)\n\t\t\t\twritten += n\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\tn, err = writeOpenMetricsSample(\n\t\t\t\tw, compliantName, \"_sum\", metric, \"\", 0,\n\t\t\t\tmetric.Summary.GetSampleSum(), 0, false,\n\t\t\t\tnil,\n\t\t\t)\n\t\t\twritten += n\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tn, err = writeOpenMetricsSample(\n\t\t\t\tw, compliantName, \"_count\", metric, \"\", 0,\n\t\t\t\t0, metric.Summary.GetSampleCount(), true,\n\t\t\t\tnil,\n\t\t\t)\n\t\t\tif toOM.withCreatedLines && metric.Summary.CreatedTimestamp != nil {\n\t\t\t\tcreatedTsBytesWritten, err = writeOpenMetricsCreated(w, compliantName, \"\", metric, \"\", 0, metric.Summary.GetCreatedTimestamp())\n\t\t\t\tn += createdTsBytesWritten\n\t\t\t}\n\t\tcase dto.MetricType_HISTOGRAM:\n\t\t\tif metric.Histogram == nil {\n\t\t\t\treturn written, fmt.Errorf(\n\t\t\t\t\t\"expected histogram in metric %s %s\", compliantName, metric,\n\t\t\t\t)\n\t\t\t}\n\t\t\tinfSeen := false\n\t\t\tfor _, b := range metric.Histogram.Bucket {\n\t\t\t\tn, err = writeOpenMetricsSample(\n\t\t\t\t\tw, compliantName, \"_bucket\", metric,\n\t\t\t\t\tmodel.BucketLabel, b.GetUpperBound(),\n\t\t\t\t\t0, b.GetCumulativeCount(), true,\n\t\t\t\t\tb.Exemplar,\n\t\t\t\t)\n\t\t\t\twritten += n\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif math.IsInf(b.GetUpperBound(), +1) {\n\t\t\t\t\tinfSeen = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !infSeen {\n\t\t\t\tn, err = writeOpenMetricsSample(\n\t\t\t\t\tw, compliantName, \"_bucket\", metric,\n\t\t\t\t\tmodel.BucketLabel, math.Inf(+1),\n\t\t\t\t\t0, metric.Histogram.GetSampleCount(), true,\n\t\t\t\t\tnil,\n\t\t\t\t)\n\t\t\t\twritten += n\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\tn, err = writeOpenMetricsSample(\n\t\t\t\tw, compliantName, \"_sum\", metric, \"\", 0,\n\t\t\t\tmetric.Histogram.GetSampleSum(), 0, false,\n\t\t\t\tnil,\n\t\t\t)\n\t\t\twritten += n\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tn, err = writeOpenMetricsSample(\n\t\t\t\tw, compliantName, \"_count\", metric, \"\", 0,\n\t\t\t\t0, metric.Histogram.GetSampleCount(), true,\n\t\t\t\tnil,\n\t\t\t)\n\t\t\tif toOM.withCreatedLines && metric.Histogram.CreatedTimestamp != nil {\n\t\t\t\tcreatedTsBytesWritten, err = writeOpenMetricsCreated(w, compliantName, \"\", metric, \"\", 0, metric.Histogram.GetCreatedTimestamp())\n\t\t\t\tn += createdTsBytesWritten\n\t\t\t}\n\t\tdefault:\n\t\t\treturn written, fmt.Errorf(\n\t\t\t\t\"unexpected type in metric %s %s\", compliantName, metric,\n\t\t\t)\n\t\t}\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\treturn\n}\n\n// FinalizeOpenMetrics writes the final `# EOF\\n` line required by OpenMetrics.\nfunc FinalizeOpenMetrics(w io.Writer) (written int, err error) {\n\treturn w.Write([]byte(\"# EOF\\n\"))\n}\n\n// writeOpenMetricsSample writes a single sample in OpenMetrics text format to\n// w, given the metric name, the metric proto message itself, optionally an\n// additional label name with a float64 value (use empty string as label name if\n// not required), the value (optionally as float64 or uint64, determined by\n// useIntValue), and optionally an exemplar (use nil if not required). The\n// function returns the number of bytes written and any error encountered.\nfunc writeOpenMetricsSample(\n\tw enhancedWriter,\n\tname, suffix string,\n\tmetric *dto.Metric,\n\tadditionalLabelName string, additionalLabelValue float64,\n\tfloatValue float64, intValue uint64, useIntValue bool,\n\texemplar *dto.Exemplar,\n) (int, error) {\n\twritten := 0\n\tn, err := writeOpenMetricsNameAndLabelPairs(\n\t\tw, name+suffix, metric.Label, additionalLabelName, additionalLabelValue,\n\t)\n\twritten += n\n\tif err != nil {\n\t\treturn written, err\n\t}\n\terr = w.WriteByte(' ')\n\twritten++\n\tif err != nil {\n\t\treturn written, err\n\t}\n\tif useIntValue {\n\t\tn, err = writeUint(w, intValue)\n\t} else {\n\t\tn, err = writeOpenMetricsFloat(w, floatValue)\n\t}\n\twritten += n\n\tif err != nil {\n\t\treturn written, err\n\t}\n\tif metric.TimestampMs != nil {\n\t\terr = w.WriteByte(' ')\n\t\twritten++\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\t// TODO(beorn7): Format this directly without converting to a float first.\n\t\tn, err = writeOpenMetricsFloat(w, float64(*metric.TimestampMs)/1000)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t}\n\tif exemplar != nil && len(exemplar.Label) > 0 {\n\t\tn, err = writeExemplar(w, exemplar)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t}\n\terr = w.WriteByte('\\n')\n\twritten++\n\tif err != nil {\n\t\treturn written, err\n\t}\n\treturn written, nil\n}\n\n// writeOpenMetricsNameAndLabelPairs works like writeOpenMetricsSample but\n// formats the float in OpenMetrics style.\nfunc writeOpenMetricsNameAndLabelPairs(\n\tw enhancedWriter,\n\tname string,\n\tin []*dto.LabelPair,\n\tadditionalLabelName string, additionalLabelValue float64,\n) (int, error) {\n\tvar (\n\t\twritten            int\n\t\tseparator          byte = '{'\n\t\tmetricInsideBraces      = false\n\t)\n\n\tif name != \"\" {\n\t\t// If the name does not pass the legacy validity check, we must put the\n\t\t// metric name inside the braces, quoted.\n\t\tif !model.IsValidLegacyMetricName(name) {\n\t\t\tmetricInsideBraces = true\n\t\t\terr := w.WriteByte(separator)\n\t\t\twritten++\n\t\t\tif err != nil {\n\t\t\t\treturn written, err\n\t\t\t}\n\t\t\tseparator = ','\n\t\t}\n\n\t\tn, err := writeName(w, name)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t}\n\n\tif len(in) == 0 && additionalLabelName == \"\" {\n\t\tif metricInsideBraces {\n\t\t\terr := w.WriteByte('}')\n\t\t\twritten++\n\t\t\tif err != nil {\n\t\t\t\treturn written, err\n\t\t\t}\n\t\t}\n\t\treturn written, nil\n\t}\n\n\tfor _, lp := range in {\n\t\terr := w.WriteByte(separator)\n\t\twritten++\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\tn, err := writeName(w, lp.GetName())\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\tn, err = w.WriteString(`=\"`)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\tn, err = writeEscapedString(w, lp.GetValue(), true)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\terr = w.WriteByte('\"')\n\t\twritten++\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\tseparator = ','\n\t}\n\tif additionalLabelName != \"\" {\n\t\terr := w.WriteByte(separator)\n\t\twritten++\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\tn, err := w.WriteString(additionalLabelName)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\tn, err = w.WriteString(`=\"`)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\tn, err = writeOpenMetricsFloat(w, additionalLabelValue)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\terr = w.WriteByte('\"')\n\t\twritten++\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t}\n\terr := w.WriteByte('}')\n\twritten++\n\tif err != nil {\n\t\treturn written, err\n\t}\n\treturn written, nil\n}\n\n// writeOpenMetricsCreated writes the created timestamp for a single time series\n// following OpenMetrics text format to w, given the metric name, the metric proto\n// message itself, optionally a suffix to be removed, e.g. '_total' for counters,\n// an additional label name with a float64 value (use empty string as label name if\n// not required) and the timestamp that represents the created timestamp.\n// The function returns the number of bytes written and any error encountered.\nfunc writeOpenMetricsCreated(w enhancedWriter,\n\tname, suffixToTrim string, metric *dto.Metric,\n\tadditionalLabelName string, additionalLabelValue float64,\n\tcreatedTimestamp *timestamppb.Timestamp,\n) (int, error) {\n\twritten := 0\n\tn, err := writeOpenMetricsNameAndLabelPairs(\n\t\tw, strings.TrimSuffix(name, suffixToTrim)+\"_created\", metric.Label, additionalLabelName, additionalLabelValue,\n\t)\n\twritten += n\n\tif err != nil {\n\t\treturn written, err\n\t}\n\n\terr = w.WriteByte(' ')\n\twritten++\n\tif err != nil {\n\t\treturn written, err\n\t}\n\n\t// TODO(beorn7): Format this directly from components of ts to\n\t// avoid overflow/underflow and precision issues of the float\n\t// conversion.\n\tn, err = writeOpenMetricsFloat(w, float64(createdTimestamp.AsTime().UnixNano())/1e9)\n\twritten += n\n\tif err != nil {\n\t\treturn written, err\n\t}\n\n\terr = w.WriteByte('\\n')\n\twritten++\n\tif err != nil {\n\t\treturn written, err\n\t}\n\treturn written, nil\n}\n\n// writeExemplar writes the provided exemplar in OpenMetrics format to w. The\n// function returns the number of bytes written and any error encountered.\nfunc writeExemplar(w enhancedWriter, e *dto.Exemplar) (int, error) {\n\twritten := 0\n\tn, err := w.WriteString(\" # \")\n\twritten += n\n\tif err != nil {\n\t\treturn written, err\n\t}\n\tn, err = writeOpenMetricsNameAndLabelPairs(w, \"\", e.Label, \"\", 0)\n\twritten += n\n\tif err != nil {\n\t\treturn written, err\n\t}\n\terr = w.WriteByte(' ')\n\twritten++\n\tif err != nil {\n\t\treturn written, err\n\t}\n\tn, err = writeOpenMetricsFloat(w, e.GetValue())\n\twritten += n\n\tif err != nil {\n\t\treturn written, err\n\t}\n\tif e.Timestamp != nil {\n\t\terr = w.WriteByte(' ')\n\t\twritten++\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\terr = (*e).Timestamp.CheckValid()\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\tts := (*e).Timestamp.AsTime()\n\t\t// TODO(beorn7): Format this directly from components of ts to\n\t\t// avoid overflow/underflow and precision issues of the float\n\t\t// conversion.\n\t\tn, err = writeOpenMetricsFloat(w, float64(ts.UnixNano())/1e9)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t}\n\treturn written, nil\n}\n\n// writeOpenMetricsFloat works like writeFloat but appends \".0\" if the resulting\n// number would otherwise contain neither a \".\" nor an \"e\".\nfunc writeOpenMetricsFloat(w enhancedWriter, f float64) (int, error) {\n\tswitch {\n\tcase f == 1:\n\t\treturn w.WriteString(\"1.0\")\n\tcase f == 0:\n\t\treturn w.WriteString(\"0.0\")\n\tcase f == -1:\n\t\treturn w.WriteString(\"-1.0\")\n\tcase math.IsNaN(f):\n\t\treturn w.WriteString(\"NaN\")\n\tcase math.IsInf(f, +1):\n\t\treturn w.WriteString(\"+Inf\")\n\tcase math.IsInf(f, -1):\n\t\treturn w.WriteString(\"-Inf\")\n\tdefault:\n\t\tbp := numBufPool.Get().(*[]byte)\n\t\t*bp = strconv.AppendFloat((*bp)[:0], f, 'g', -1, 64)\n\t\tif !bytes.ContainsAny(*bp, \"e.\") {\n\t\t\t*bp = append(*bp, '.', '0')\n\t\t}\n\t\twritten, err := w.Write(*bp)\n\t\tnumBufPool.Put(bp)\n\t\treturn written, err\n\t}\n}\n\n// writeUint is like writeInt just for uint64.\nfunc writeUint(w enhancedWriter, u uint64) (int, error) {\n\tbp := numBufPool.Get().(*[]byte)\n\t*bp = strconv.AppendUint((*bp)[:0], u, 10)\n\twritten, err := w.Write(*bp)\n\tnumBufPool.Put(bp)\n\treturn written, err\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/expfmt/text_create.go",
    "content": "// Copyright 2014 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage expfmt\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/prometheus/common/model\"\n\n\tdto \"github.com/prometheus/client_model/go\"\n)\n\n// enhancedWriter has all the enhanced write functions needed here. bufio.Writer\n// implements it.\ntype enhancedWriter interface {\n\tio.Writer\n\tWriteRune(r rune) (n int, err error)\n\tWriteString(s string) (n int, err error)\n\tWriteByte(c byte) error\n}\n\nconst (\n\tinitialNumBufSize = 24\n)\n\nvar (\n\tbufPool = sync.Pool{\n\t\tNew: func() interface{} {\n\t\t\treturn bufio.NewWriter(io.Discard)\n\t\t},\n\t}\n\tnumBufPool = sync.Pool{\n\t\tNew: func() interface{} {\n\t\t\tb := make([]byte, 0, initialNumBufSize)\n\t\t\treturn &b\n\t\t},\n\t}\n)\n\n// MetricFamilyToText converts a MetricFamily proto message into text format and\n// writes the resulting lines to 'out'. It returns the number of bytes written\n// and any error encountered. The output will have the same order as the input,\n// no further sorting is performed. Furthermore, this function assumes the input\n// is already sanitized and does not perform any sanity checks. If the input\n// contains duplicate metrics or invalid metric or label names, the conversion\n// will result in invalid text format output.\n//\n// If metric names conform to the legacy validation pattern, they will be placed\n// outside the brackets in the traditional way, like `foo{}`. If the metric name\n// fails the legacy validation check, it will be placed quoted inside the\n// brackets: `{\"foo\"}`. As stated above, the input is assumed to be santized and\n// no error will be thrown in this case.\n//\n// Similar to metric names, if label names conform to the legacy validation\n// pattern, they will be unquoted as normal, like `foo{bar=\"baz\"}`. If the label\n// name fails the legacy validation check, it will be quoted:\n// `foo{\"bar\"=\"baz\"}`. As stated above, the input is assumed to be santized and\n// no error will be thrown in this case.\n//\n// This method fulfills the type 'prometheus.encoder'.\nfunc MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err error) {\n\t// Fail-fast checks.\n\tif len(in.Metric) == 0 {\n\t\treturn 0, fmt.Errorf(\"MetricFamily has no metrics: %s\", in)\n\t}\n\tname := in.GetName()\n\tif name == \"\" {\n\t\treturn 0, fmt.Errorf(\"MetricFamily has no name: %s\", in)\n\t}\n\n\t// Try the interface upgrade. If it doesn't work, we'll use a\n\t// bufio.Writer from the sync.Pool.\n\tw, ok := out.(enhancedWriter)\n\tif !ok {\n\t\tb := bufPool.Get().(*bufio.Writer)\n\t\tb.Reset(out)\n\t\tw = b\n\t\tdefer func() {\n\t\t\tbErr := b.Flush()\n\t\t\tif err == nil {\n\t\t\t\terr = bErr\n\t\t\t}\n\t\t\tbufPool.Put(b)\n\t\t}()\n\t}\n\n\tvar n int\n\n\t// Comments, first HELP, then TYPE.\n\tif in.Help != nil {\n\t\tn, err = w.WriteString(\"# HELP \")\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tn, err = writeName(w, name)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\terr = w.WriteByte(' ')\n\t\twritten++\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tn, err = writeEscapedString(w, *in.Help, false)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\terr = w.WriteByte('\\n')\n\t\twritten++\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\tn, err = w.WriteString(\"# TYPE \")\n\twritten += n\n\tif err != nil {\n\t\treturn\n\t}\n\tn, err = writeName(w, name)\n\twritten += n\n\tif err != nil {\n\t\treturn\n\t}\n\tmetricType := in.GetType()\n\tswitch metricType {\n\tcase dto.MetricType_COUNTER:\n\t\tn, err = w.WriteString(\" counter\\n\")\n\tcase dto.MetricType_GAUGE:\n\t\tn, err = w.WriteString(\" gauge\\n\")\n\tcase dto.MetricType_SUMMARY:\n\t\tn, err = w.WriteString(\" summary\\n\")\n\tcase dto.MetricType_UNTYPED:\n\t\tn, err = w.WriteString(\" untyped\\n\")\n\tcase dto.MetricType_HISTOGRAM:\n\t\tn, err = w.WriteString(\" histogram\\n\")\n\tdefault:\n\t\treturn written, fmt.Errorf(\"unknown metric type %s\", metricType.String())\n\t}\n\twritten += n\n\tif err != nil {\n\t\treturn\n\t}\n\n\t// Finally the samples, one line for each.\n\tfor _, metric := range in.Metric {\n\t\tswitch metricType {\n\t\tcase dto.MetricType_COUNTER:\n\t\t\tif metric.Counter == nil {\n\t\t\t\treturn written, fmt.Errorf(\n\t\t\t\t\t\"expected counter in metric %s %s\", name, metric,\n\t\t\t\t)\n\t\t\t}\n\t\t\tn, err = writeSample(\n\t\t\t\tw, name, \"\", metric, \"\", 0,\n\t\t\t\tmetric.Counter.GetValue(),\n\t\t\t)\n\t\tcase dto.MetricType_GAUGE:\n\t\t\tif metric.Gauge == nil {\n\t\t\t\treturn written, fmt.Errorf(\n\t\t\t\t\t\"expected gauge in metric %s %s\", name, metric,\n\t\t\t\t)\n\t\t\t}\n\t\t\tn, err = writeSample(\n\t\t\t\tw, name, \"\", metric, \"\", 0,\n\t\t\t\tmetric.Gauge.GetValue(),\n\t\t\t)\n\t\tcase dto.MetricType_UNTYPED:\n\t\t\tif metric.Untyped == nil {\n\t\t\t\treturn written, fmt.Errorf(\n\t\t\t\t\t\"expected untyped in metric %s %s\", name, metric,\n\t\t\t\t)\n\t\t\t}\n\t\t\tn, err = writeSample(\n\t\t\t\tw, name, \"\", metric, \"\", 0,\n\t\t\t\tmetric.Untyped.GetValue(),\n\t\t\t)\n\t\tcase dto.MetricType_SUMMARY:\n\t\t\tif metric.Summary == nil {\n\t\t\t\treturn written, fmt.Errorf(\n\t\t\t\t\t\"expected summary in metric %s %s\", name, metric,\n\t\t\t\t)\n\t\t\t}\n\t\t\tfor _, q := range metric.Summary.Quantile {\n\t\t\t\tn, err = writeSample(\n\t\t\t\t\tw, name, \"\", metric,\n\t\t\t\t\tmodel.QuantileLabel, q.GetQuantile(),\n\t\t\t\t\tq.GetValue(),\n\t\t\t\t)\n\t\t\t\twritten += n\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\tn, err = writeSample(\n\t\t\t\tw, name, \"_sum\", metric, \"\", 0,\n\t\t\t\tmetric.Summary.GetSampleSum(),\n\t\t\t)\n\t\t\twritten += n\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tn, err = writeSample(\n\t\t\t\tw, name, \"_count\", metric, \"\", 0,\n\t\t\t\tfloat64(metric.Summary.GetSampleCount()),\n\t\t\t)\n\t\tcase dto.MetricType_HISTOGRAM:\n\t\t\tif metric.Histogram == nil {\n\t\t\t\treturn written, fmt.Errorf(\n\t\t\t\t\t\"expected histogram in metric %s %s\", name, metric,\n\t\t\t\t)\n\t\t\t}\n\t\t\tinfSeen := false\n\t\t\tfor _, b := range metric.Histogram.Bucket {\n\t\t\t\tn, err = writeSample(\n\t\t\t\t\tw, name, \"_bucket\", metric,\n\t\t\t\t\tmodel.BucketLabel, b.GetUpperBound(),\n\t\t\t\t\tfloat64(b.GetCumulativeCount()),\n\t\t\t\t)\n\t\t\t\twritten += n\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif math.IsInf(b.GetUpperBound(), +1) {\n\t\t\t\t\tinfSeen = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !infSeen {\n\t\t\t\tn, err = writeSample(\n\t\t\t\t\tw, name, \"_bucket\", metric,\n\t\t\t\t\tmodel.BucketLabel, math.Inf(+1),\n\t\t\t\t\tfloat64(metric.Histogram.GetSampleCount()),\n\t\t\t\t)\n\t\t\t\twritten += n\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\tn, err = writeSample(\n\t\t\t\tw, name, \"_sum\", metric, \"\", 0,\n\t\t\t\tmetric.Histogram.GetSampleSum(),\n\t\t\t)\n\t\t\twritten += n\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tn, err = writeSample(\n\t\t\t\tw, name, \"_count\", metric, \"\", 0,\n\t\t\t\tfloat64(metric.Histogram.GetSampleCount()),\n\t\t\t)\n\t\tdefault:\n\t\t\treturn written, fmt.Errorf(\n\t\t\t\t\"unexpected type in metric %s %s\", name, metric,\n\t\t\t)\n\t\t}\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\treturn\n}\n\n// writeSample writes a single sample in text format to w, given the metric\n// name, the metric proto message itself, optionally an additional label name\n// with a float64 value (use empty string as label name if not required), and\n// the value. The function returns the number of bytes written and any error\n// encountered.\nfunc writeSample(\n\tw enhancedWriter,\n\tname, suffix string,\n\tmetric *dto.Metric,\n\tadditionalLabelName string, additionalLabelValue float64,\n\tvalue float64,\n) (int, error) {\n\twritten := 0\n\tn, err := writeNameAndLabelPairs(\n\t\tw, name+suffix, metric.Label, additionalLabelName, additionalLabelValue,\n\t)\n\twritten += n\n\tif err != nil {\n\t\treturn written, err\n\t}\n\terr = w.WriteByte(' ')\n\twritten++\n\tif err != nil {\n\t\treturn written, err\n\t}\n\tn, err = writeFloat(w, value)\n\twritten += n\n\tif err != nil {\n\t\treturn written, err\n\t}\n\tif metric.TimestampMs != nil {\n\t\terr = w.WriteByte(' ')\n\t\twritten++\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\tn, err = writeInt(w, *metric.TimestampMs)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t}\n\terr = w.WriteByte('\\n')\n\twritten++\n\tif err != nil {\n\t\treturn written, err\n\t}\n\treturn written, nil\n}\n\n// writeNameAndLabelPairs converts a slice of LabelPair proto messages plus the\n// explicitly given metric name and additional label pair into text formatted as\n// required by the text format and writes it to 'w'. An empty slice in\n// combination with an empty string 'additionalLabelName' results in nothing\n// being written. Otherwise, the label pairs are written, escaped as required by\n// the text format, and enclosed in '{...}'. The function returns the number of\n// bytes written and any error encountered. If the metric name is not\n// legacy-valid, it will be put inside the brackets as well. Legacy-invalid\n// label names will also be quoted.\nfunc writeNameAndLabelPairs(\n\tw enhancedWriter,\n\tname string,\n\tin []*dto.LabelPair,\n\tadditionalLabelName string, additionalLabelValue float64,\n) (int, error) {\n\tvar (\n\t\twritten            int\n\t\tseparator          byte = '{'\n\t\tmetricInsideBraces      = false\n\t)\n\n\tif name != \"\" {\n\t\t// If the name does not pass the legacy validity check, we must put the\n\t\t// metric name inside the braces.\n\t\tif !model.IsValidLegacyMetricName(name) {\n\t\t\tmetricInsideBraces = true\n\t\t\terr := w.WriteByte(separator)\n\t\t\twritten++\n\t\t\tif err != nil {\n\t\t\t\treturn written, err\n\t\t\t}\n\t\t\tseparator = ','\n\t\t}\n\t\tn, err := writeName(w, name)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t}\n\n\tif len(in) == 0 && additionalLabelName == \"\" {\n\t\tif metricInsideBraces {\n\t\t\terr := w.WriteByte('}')\n\t\t\twritten++\n\t\t\tif err != nil {\n\t\t\t\treturn written, err\n\t\t\t}\n\t\t}\n\t\treturn written, nil\n\t}\n\n\tfor _, lp := range in {\n\t\terr := w.WriteByte(separator)\n\t\twritten++\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\tn, err := writeName(w, lp.GetName())\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\tn, err = w.WriteString(`=\"`)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\tn, err = writeEscapedString(w, lp.GetValue(), true)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\terr = w.WriteByte('\"')\n\t\twritten++\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\tseparator = ','\n\t}\n\tif additionalLabelName != \"\" {\n\t\terr := w.WriteByte(separator)\n\t\twritten++\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\tn, err := w.WriteString(additionalLabelName)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\tn, err = w.WriteString(`=\"`)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\tn, err = writeFloat(w, additionalLabelValue)\n\t\twritten += n\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t\terr = w.WriteByte('\"')\n\t\twritten++\n\t\tif err != nil {\n\t\t\treturn written, err\n\t\t}\n\t}\n\terr := w.WriteByte('}')\n\twritten++\n\tif err != nil {\n\t\treturn written, err\n\t}\n\treturn written, nil\n}\n\n// writeEscapedString replaces '\\' by '\\\\', new line character by '\\n', and - if\n// includeDoubleQuote is true - '\"' by '\\\"'.\nvar (\n\tescaper       = strings.NewReplacer(\"\\\\\", `\\\\`, \"\\n\", `\\n`)\n\tquotedEscaper = strings.NewReplacer(\"\\\\\", `\\\\`, \"\\n\", `\\n`, \"\\\"\", `\\\"`)\n)\n\nfunc writeEscapedString(w enhancedWriter, v string, includeDoubleQuote bool) (int, error) {\n\tif includeDoubleQuote {\n\t\treturn quotedEscaper.WriteString(w, v)\n\t}\n\treturn escaper.WriteString(w, v)\n}\n\n// writeFloat is equivalent to fmt.Fprint with a float64 argument but hardcodes\n// a few common cases for increased efficiency. For non-hardcoded cases, it uses\n// strconv.AppendFloat to avoid allocations, similar to writeInt.\nfunc writeFloat(w enhancedWriter, f float64) (int, error) {\n\tswitch {\n\tcase f == 1:\n\t\treturn 1, w.WriteByte('1')\n\tcase f == 0:\n\t\treturn 1, w.WriteByte('0')\n\tcase f == -1:\n\t\treturn w.WriteString(\"-1\")\n\tcase math.IsNaN(f):\n\t\treturn w.WriteString(\"NaN\")\n\tcase math.IsInf(f, +1):\n\t\treturn w.WriteString(\"+Inf\")\n\tcase math.IsInf(f, -1):\n\t\treturn w.WriteString(\"-Inf\")\n\tdefault:\n\t\tbp := numBufPool.Get().(*[]byte)\n\t\t*bp = strconv.AppendFloat((*bp)[:0], f, 'g', -1, 64)\n\t\twritten, err := w.Write(*bp)\n\t\tnumBufPool.Put(bp)\n\t\treturn written, err\n\t}\n}\n\n// writeInt is equivalent to fmt.Fprint with an int64 argument but uses\n// strconv.AppendInt with a byte slice taken from a sync.Pool to avoid\n// allocations.\nfunc writeInt(w enhancedWriter, i int64) (int, error) {\n\tbp := numBufPool.Get().(*[]byte)\n\t*bp = strconv.AppendInt((*bp)[:0], i, 10)\n\twritten, err := w.Write(*bp)\n\tnumBufPool.Put(bp)\n\treturn written, err\n}\n\n// writeName writes a string as-is if it complies with the legacy naming\n// scheme, or escapes it in double quotes if not.\nfunc writeName(w enhancedWriter, name string) (int, error) {\n\tif model.IsValidLegacyMetricName(name) {\n\t\treturn w.WriteString(name)\n\t}\n\tvar written int\n\tvar err error\n\terr = w.WriteByte('\"')\n\twritten++\n\tif err != nil {\n\t\treturn written, err\n\t}\n\tvar n int\n\tn, err = writeEscapedString(w, name, true)\n\twritten += n\n\tif err != nil {\n\t\treturn written, err\n\t}\n\terr = w.WriteByte('\"')\n\twritten++\n\treturn written, err\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/expfmt/text_parse.go",
    "content": "// Copyright 2014 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage expfmt\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\tdto \"github.com/prometheus/client_model/go\"\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/prometheus/common/model\"\n)\n\n// A stateFn is a function that represents a state in a state machine. By\n// executing it, the state is progressed to the next state. The stateFn returns\n// another stateFn, which represents the new state. The end state is represented\n// by nil.\ntype stateFn func() stateFn\n\n// ParseError signals errors while parsing the simple and flat text-based\n// exchange format.\ntype ParseError struct {\n\tLine int\n\tMsg  string\n}\n\n// Error implements the error interface.\nfunc (e ParseError) Error() string {\n\treturn fmt.Sprintf(\"text format parsing error in line %d: %s\", e.Line, e.Msg)\n}\n\n// TextParser is used to parse the simple and flat text-based exchange format. Its\n// zero value is ready to use.\ntype TextParser struct {\n\tmetricFamiliesByName map[string]*dto.MetricFamily\n\tbuf                  *bufio.Reader // Where the parsed input is read through.\n\terr                  error         // Most recent error.\n\tlineCount            int           // Tracks the line count for error messages.\n\tcurrentByte          byte          // The most recent byte read.\n\tcurrentToken         bytes.Buffer  // Re-used each time a token has to be gathered from multiple bytes.\n\tcurrentMF            *dto.MetricFamily\n\tcurrentMetric        *dto.Metric\n\tcurrentLabelPair     *dto.LabelPair\n\tcurrentLabelPairs    []*dto.LabelPair // Temporarily stores label pairs while parsing a metric line.\n\n\t// The remaining member variables are only used for summaries/histograms.\n\tcurrentLabels map[string]string // All labels including '__name__' but excluding 'quantile'/'le'\n\t// Summary specific.\n\tsummaries       map[uint64]*dto.Metric // Key is created with LabelsToSignature.\n\tcurrentQuantile float64\n\t// Histogram specific.\n\thistograms    map[uint64]*dto.Metric // Key is created with LabelsToSignature.\n\tcurrentBucket float64\n\t// These tell us if the currently processed line ends on '_count' or\n\t// '_sum' respectively and belong to a summary/histogram, representing the sample\n\t// count and sum of that summary/histogram.\n\tcurrentIsSummaryCount, currentIsSummarySum     bool\n\tcurrentIsHistogramCount, currentIsHistogramSum bool\n\t// These indicate if the metric name from the current line being parsed is inside\n\t// braces and if that metric name was found respectively.\n\tcurrentMetricIsInsideBraces, currentMetricInsideBracesIsPresent bool\n}\n\n// TextToMetricFamilies reads 'in' as the simple and flat text-based exchange\n// format and creates MetricFamily proto messages. It returns the MetricFamily\n// proto messages in a map where the metric names are the keys, along with any\n// error encountered.\n//\n// If the input contains duplicate metrics (i.e. lines with the same metric name\n// and exactly the same label set), the resulting MetricFamily will contain\n// duplicate Metric proto messages. Similar is true for duplicate label\n// names. Checks for duplicates have to be performed separately, if required.\n// Also note that neither the metrics within each MetricFamily are sorted nor\n// the label pairs within each Metric. Sorting is not required for the most\n// frequent use of this method, which is sample ingestion in the Prometheus\n// server. However, for presentation purposes, you might want to sort the\n// metrics, and in some cases, you must sort the labels, e.g. for consumption by\n// the metric family injection hook of the Prometheus registry.\n//\n// Summaries and histograms are rather special beasts. You would probably not\n// use them in the simple text format anyway. This method can deal with\n// summaries and histograms if they are presented in exactly the way the\n// text.Create function creates them.\n//\n// This method must not be called concurrently. If you want to parse different\n// input concurrently, instantiate a separate Parser for each goroutine.\nfunc (p *TextParser) TextToMetricFamilies(in io.Reader) (map[string]*dto.MetricFamily, error) {\n\tp.reset(in)\n\tfor nextState := p.startOfLine; nextState != nil; nextState = nextState() {\n\t\t// Magic happens here...\n\t}\n\t// Get rid of empty metric families.\n\tfor k, mf := range p.metricFamiliesByName {\n\t\tif len(mf.GetMetric()) == 0 {\n\t\t\tdelete(p.metricFamiliesByName, k)\n\t\t}\n\t}\n\t// If p.err is io.EOF now, we have run into a premature end of the input\n\t// stream. Turn this error into something nicer and more\n\t// meaningful. (io.EOF is often used as a signal for the legitimate end\n\t// of an input stream.)\n\tif p.err != nil && errors.Is(p.err, io.EOF) {\n\t\tp.parseError(\"unexpected end of input stream\")\n\t}\n\treturn p.metricFamiliesByName, p.err\n}\n\nfunc (p *TextParser) reset(in io.Reader) {\n\tp.metricFamiliesByName = map[string]*dto.MetricFamily{}\n\tif p.buf == nil {\n\t\tp.buf = bufio.NewReader(in)\n\t} else {\n\t\tp.buf.Reset(in)\n\t}\n\tp.err = nil\n\tp.lineCount = 0\n\tif p.summaries == nil || len(p.summaries) > 0 {\n\t\tp.summaries = map[uint64]*dto.Metric{}\n\t}\n\tif p.histograms == nil || len(p.histograms) > 0 {\n\t\tp.histograms = map[uint64]*dto.Metric{}\n\t}\n\tp.currentQuantile = math.NaN()\n\tp.currentBucket = math.NaN()\n\tp.currentMF = nil\n}\n\n// startOfLine represents the state where the next byte read from p.buf is the\n// start of a line (or whitespace leading up to it).\nfunc (p *TextParser) startOfLine() stateFn {\n\tp.lineCount++\n\tp.currentMetricIsInsideBraces = false\n\tp.currentMetricInsideBracesIsPresent = false\n\tif p.skipBlankTab(); p.err != nil {\n\t\t// This is the only place that we expect to see io.EOF,\n\t\t// which is not an error but the signal that we are done.\n\t\t// Any other error that happens to align with the start of\n\t\t// a line is still an error.\n\t\tif errors.Is(p.err, io.EOF) {\n\t\t\tp.err = nil\n\t\t}\n\t\treturn nil\n\t}\n\tswitch p.currentByte {\n\tcase '#':\n\t\treturn p.startComment\n\tcase '\\n':\n\t\treturn p.startOfLine // Empty line, start the next one.\n\tcase '{':\n\t\tp.currentMetricIsInsideBraces = true\n\t\treturn p.readingLabels\n\t}\n\treturn p.readingMetricName\n}\n\n// startComment represents the state where the next byte read from p.buf is the\n// start of a comment (or whitespace leading up to it).\nfunc (p *TextParser) startComment() stateFn {\n\tif p.skipBlankTab(); p.err != nil {\n\t\treturn nil // Unexpected end of input.\n\t}\n\tif p.currentByte == '\\n' {\n\t\treturn p.startOfLine\n\t}\n\tif p.readTokenUntilWhitespace(); p.err != nil {\n\t\treturn nil // Unexpected end of input.\n\t}\n\t// If we have hit the end of line already, there is nothing left\n\t// to do. This is not considered a syntax error.\n\tif p.currentByte == '\\n' {\n\t\treturn p.startOfLine\n\t}\n\tkeyword := p.currentToken.String()\n\tif keyword != \"HELP\" && keyword != \"TYPE\" {\n\t\t// Generic comment, ignore by fast forwarding to end of line.\n\t\tfor p.currentByte != '\\n' {\n\t\t\tif p.currentByte, p.err = p.buf.ReadByte(); p.err != nil {\n\t\t\t\treturn nil // Unexpected end of input.\n\t\t\t}\n\t\t}\n\t\treturn p.startOfLine\n\t}\n\t// There is something. Next has to be a metric name.\n\tif p.skipBlankTab(); p.err != nil {\n\t\treturn nil // Unexpected end of input.\n\t}\n\tif p.readTokenAsMetricName(); p.err != nil {\n\t\treturn nil // Unexpected end of input.\n\t}\n\tif p.currentByte == '\\n' {\n\t\t// At the end of the line already.\n\t\t// Again, this is not considered a syntax error.\n\t\treturn p.startOfLine\n\t}\n\tif !isBlankOrTab(p.currentByte) {\n\t\tp.parseError(\"invalid metric name in comment\")\n\t\treturn nil\n\t}\n\tp.setOrCreateCurrentMF()\n\tif p.skipBlankTab(); p.err != nil {\n\t\treturn nil // Unexpected end of input.\n\t}\n\tif p.currentByte == '\\n' {\n\t\t// At the end of the line already.\n\t\t// Again, this is not considered a syntax error.\n\t\treturn p.startOfLine\n\t}\n\tswitch keyword {\n\tcase \"HELP\":\n\t\treturn p.readingHelp\n\tcase \"TYPE\":\n\t\treturn p.readingType\n\t}\n\tpanic(fmt.Sprintf(\"code error: unexpected keyword %q\", keyword))\n}\n\n// readingMetricName represents the state where the last byte read (now in\n// p.currentByte) is the first byte of a metric name.\nfunc (p *TextParser) readingMetricName() stateFn {\n\tif p.readTokenAsMetricName(); p.err != nil {\n\t\treturn nil\n\t}\n\tif p.currentToken.Len() == 0 {\n\t\tp.parseError(\"invalid metric name\")\n\t\treturn nil\n\t}\n\tp.setOrCreateCurrentMF()\n\t// Now is the time to fix the type if it hasn't happened yet.\n\tif p.currentMF.Type == nil {\n\t\tp.currentMF.Type = dto.MetricType_UNTYPED.Enum()\n\t}\n\tp.currentMetric = &dto.Metric{}\n\t// Do not append the newly created currentMetric to\n\t// currentMF.Metric right now. First wait if this is a summary,\n\t// and the metric exists already, which we can only know after\n\t// having read all the labels.\n\tif p.skipBlankTabIfCurrentBlankTab(); p.err != nil {\n\t\treturn nil // Unexpected end of input.\n\t}\n\treturn p.readingLabels\n}\n\n// readingLabels represents the state where the last byte read (now in\n// p.currentByte) is either the first byte of the label set (i.e. a '{'), or the\n// first byte of the value (otherwise).\nfunc (p *TextParser) readingLabels() stateFn {\n\t// Summaries/histograms are special. We have to reset the\n\t// currentLabels map, currentQuantile and currentBucket before starting to\n\t// read labels.\n\tif p.currentMF.GetType() == dto.MetricType_SUMMARY || p.currentMF.GetType() == dto.MetricType_HISTOGRAM {\n\t\tp.currentLabels = map[string]string{}\n\t\tp.currentLabels[string(model.MetricNameLabel)] = p.currentMF.GetName()\n\t\tp.currentQuantile = math.NaN()\n\t\tp.currentBucket = math.NaN()\n\t}\n\tif p.currentByte != '{' {\n\t\treturn p.readingValue\n\t}\n\treturn p.startLabelName\n}\n\n// startLabelName represents the state where the next byte read from p.buf is\n// the start of a label name (or whitespace leading up to it).\nfunc (p *TextParser) startLabelName() stateFn {\n\tif p.skipBlankTab(); p.err != nil {\n\t\treturn nil // Unexpected end of input.\n\t}\n\tif p.currentByte == '}' {\n\t\tp.currentMetric.Label = append(p.currentMetric.Label, p.currentLabelPairs...)\n\t\tp.currentLabelPairs = nil\n\t\tif p.skipBlankTab(); p.err != nil {\n\t\t\treturn nil // Unexpected end of input.\n\t\t}\n\t\treturn p.readingValue\n\t}\n\tif p.readTokenAsLabelName(); p.err != nil {\n\t\treturn nil // Unexpected end of input.\n\t}\n\tif p.currentToken.Len() == 0 {\n\t\tp.parseError(fmt.Sprintf(\"invalid label name for metric %q\", p.currentMF.GetName()))\n\t\treturn nil\n\t}\n\tif p.skipBlankTabIfCurrentBlankTab(); p.err != nil {\n\t\treturn nil // Unexpected end of input.\n\t}\n\tif p.currentByte != '=' {\n\t\tif p.currentMetricIsInsideBraces {\n\t\t\tif p.currentMetricInsideBracesIsPresent {\n\t\t\t\tp.parseError(fmt.Sprintf(\"multiple metric names for metric %q\", p.currentMF.GetName()))\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tswitch p.currentByte {\n\t\t\tcase ',':\n\t\t\t\tp.setOrCreateCurrentMF()\n\t\t\t\tif p.currentMF.Type == nil {\n\t\t\t\t\tp.currentMF.Type = dto.MetricType_UNTYPED.Enum()\n\t\t\t\t}\n\t\t\t\tp.currentMetric = &dto.Metric{}\n\t\t\t\tp.currentMetricInsideBracesIsPresent = true\n\t\t\t\treturn p.startLabelName\n\t\t\tcase '}':\n\t\t\t\tp.setOrCreateCurrentMF()\n\t\t\t\tif p.currentMF.Type == nil {\n\t\t\t\t\tp.currentMF.Type = dto.MetricType_UNTYPED.Enum()\n\t\t\t\t}\n\t\t\t\tp.currentMetric = &dto.Metric{}\n\t\t\t\tp.currentMetric.Label = append(p.currentMetric.Label, p.currentLabelPairs...)\n\t\t\t\tp.currentLabelPairs = nil\n\t\t\t\tif p.skipBlankTab(); p.err != nil {\n\t\t\t\t\treturn nil // Unexpected end of input.\n\t\t\t\t}\n\t\t\t\treturn p.readingValue\n\t\t\tdefault:\n\t\t\t\tp.parseError(fmt.Sprintf(\"unexpected end of metric name %q\", p.currentByte))\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tp.parseError(fmt.Sprintf(\"expected '=' after label name, found %q\", p.currentByte))\n\t\tp.currentLabelPairs = nil\n\t\treturn nil\n\t}\n\tp.currentLabelPair = &dto.LabelPair{Name: proto.String(p.currentToken.String())}\n\tif p.currentLabelPair.GetName() == string(model.MetricNameLabel) {\n\t\tp.parseError(fmt.Sprintf(\"label name %q is reserved\", model.MetricNameLabel))\n\t\treturn nil\n\t}\n\t// Special summary/histogram treatment. Don't add 'quantile' and 'le'\n\t// labels to 'real' labels.\n\tif (p.currentMF.GetType() != dto.MetricType_SUMMARY || p.currentLabelPair.GetName() != model.QuantileLabel) &&\n\t\t(p.currentMF.GetType() != dto.MetricType_HISTOGRAM || p.currentLabelPair.GetName() != model.BucketLabel) {\n\t\tp.currentLabelPairs = append(p.currentLabelPairs, p.currentLabelPair)\n\t}\n\t// Check for duplicate label names.\n\tlabels := make(map[string]struct{})\n\tfor _, l := range p.currentLabelPairs {\n\t\tlName := l.GetName()\n\t\tif _, exists := labels[lName]; !exists {\n\t\t\tlabels[lName] = struct{}{}\n\t\t} else {\n\t\t\tp.parseError(fmt.Sprintf(\"duplicate label names for metric %q\", p.currentMF.GetName()))\n\t\t\tp.currentLabelPairs = nil\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn p.startLabelValue\n}\n\n// startLabelValue represents the state where the next byte read from p.buf is\n// the start of a (quoted) label value (or whitespace leading up to it).\nfunc (p *TextParser) startLabelValue() stateFn {\n\tif p.skipBlankTab(); p.err != nil {\n\t\treturn nil // Unexpected end of input.\n\t}\n\tif p.currentByte != '\"' {\n\t\tp.parseError(fmt.Sprintf(\"expected '\\\"' at start of label value, found %q\", p.currentByte))\n\t\treturn nil\n\t}\n\tif p.readTokenAsLabelValue(); p.err != nil {\n\t\treturn nil\n\t}\n\tif !model.LabelValue(p.currentToken.String()).IsValid() {\n\t\tp.parseError(fmt.Sprintf(\"invalid label value %q\", p.currentToken.String()))\n\t\treturn nil\n\t}\n\tp.currentLabelPair.Value = proto.String(p.currentToken.String())\n\t// Special treatment of summaries:\n\t// - Quantile labels are special, will result in dto.Quantile later.\n\t// - Other labels have to be added to currentLabels for signature calculation.\n\tif p.currentMF.GetType() == dto.MetricType_SUMMARY {\n\t\tif p.currentLabelPair.GetName() == model.QuantileLabel {\n\t\t\tif p.currentQuantile, p.err = parseFloat(p.currentLabelPair.GetValue()); p.err != nil {\n\t\t\t\t// Create a more helpful error message.\n\t\t\t\tp.parseError(fmt.Sprintf(\"expected float as value for 'quantile' label, got %q\", p.currentLabelPair.GetValue()))\n\t\t\t\tp.currentLabelPairs = nil\n\t\t\t\treturn nil\n\t\t\t}\n\t\t} else {\n\t\t\tp.currentLabels[p.currentLabelPair.GetName()] = p.currentLabelPair.GetValue()\n\t\t}\n\t}\n\t// Similar special treatment of histograms.\n\tif p.currentMF.GetType() == dto.MetricType_HISTOGRAM {\n\t\tif p.currentLabelPair.GetName() == model.BucketLabel {\n\t\t\tif p.currentBucket, p.err = parseFloat(p.currentLabelPair.GetValue()); p.err != nil {\n\t\t\t\t// Create a more helpful error message.\n\t\t\t\tp.parseError(fmt.Sprintf(\"expected float as value for 'le' label, got %q\", p.currentLabelPair.GetValue()))\n\t\t\t\treturn nil\n\t\t\t}\n\t\t} else {\n\t\t\tp.currentLabels[p.currentLabelPair.GetName()] = p.currentLabelPair.GetValue()\n\t\t}\n\t}\n\tif p.skipBlankTab(); p.err != nil {\n\t\treturn nil // Unexpected end of input.\n\t}\n\tswitch p.currentByte {\n\tcase ',':\n\t\treturn p.startLabelName\n\n\tcase '}':\n\t\tif p.currentMF == nil {\n\t\t\tp.parseError(\"invalid metric name\")\n\t\t\treturn nil\n\t\t}\n\t\tp.currentMetric.Label = append(p.currentMetric.Label, p.currentLabelPairs...)\n\t\tp.currentLabelPairs = nil\n\t\tif p.skipBlankTab(); p.err != nil {\n\t\t\treturn nil // Unexpected end of input.\n\t\t}\n\t\treturn p.readingValue\n\tdefault:\n\t\tp.parseError(fmt.Sprintf(\"unexpected end of label value %q\", p.currentLabelPair.GetValue()))\n\t\tp.currentLabelPairs = nil\n\t\treturn nil\n\t}\n}\n\n// readingValue represents the state where the last byte read (now in\n// p.currentByte) is the first byte of the sample value (i.e. a float).\nfunc (p *TextParser) readingValue() stateFn {\n\t// When we are here, we have read all the labels, so for the\n\t// special case of a summary/histogram, we can finally find out\n\t// if the metric already exists.\n\tif p.currentMF.GetType() == dto.MetricType_SUMMARY {\n\t\tsignature := model.LabelsToSignature(p.currentLabels)\n\t\tif summary := p.summaries[signature]; summary != nil {\n\t\t\tp.currentMetric = summary\n\t\t} else {\n\t\t\tp.summaries[signature] = p.currentMetric\n\t\t\tp.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric)\n\t\t}\n\t} else if p.currentMF.GetType() == dto.MetricType_HISTOGRAM {\n\t\tsignature := model.LabelsToSignature(p.currentLabels)\n\t\tif histogram := p.histograms[signature]; histogram != nil {\n\t\t\tp.currentMetric = histogram\n\t\t} else {\n\t\t\tp.histograms[signature] = p.currentMetric\n\t\t\tp.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric)\n\t\t}\n\t} else {\n\t\tp.currentMF.Metric = append(p.currentMF.Metric, p.currentMetric)\n\t}\n\tif p.readTokenUntilWhitespace(); p.err != nil {\n\t\treturn nil // Unexpected end of input.\n\t}\n\tvalue, err := parseFloat(p.currentToken.String())\n\tif err != nil {\n\t\t// Create a more helpful error message.\n\t\tp.parseError(fmt.Sprintf(\"expected float as value, got %q\", p.currentToken.String()))\n\t\treturn nil\n\t}\n\tswitch p.currentMF.GetType() {\n\tcase dto.MetricType_COUNTER:\n\t\tp.currentMetric.Counter = &dto.Counter{Value: proto.Float64(value)}\n\tcase dto.MetricType_GAUGE:\n\t\tp.currentMetric.Gauge = &dto.Gauge{Value: proto.Float64(value)}\n\tcase dto.MetricType_UNTYPED:\n\t\tp.currentMetric.Untyped = &dto.Untyped{Value: proto.Float64(value)}\n\tcase dto.MetricType_SUMMARY:\n\t\t// *sigh*\n\t\tif p.currentMetric.Summary == nil {\n\t\t\tp.currentMetric.Summary = &dto.Summary{}\n\t\t}\n\t\tswitch {\n\t\tcase p.currentIsSummaryCount:\n\t\t\tp.currentMetric.Summary.SampleCount = proto.Uint64(uint64(value))\n\t\tcase p.currentIsSummarySum:\n\t\t\tp.currentMetric.Summary.SampleSum = proto.Float64(value)\n\t\tcase !math.IsNaN(p.currentQuantile):\n\t\t\tp.currentMetric.Summary.Quantile = append(\n\t\t\t\tp.currentMetric.Summary.Quantile,\n\t\t\t\t&dto.Quantile{\n\t\t\t\t\tQuantile: proto.Float64(p.currentQuantile),\n\t\t\t\t\tValue:    proto.Float64(value),\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\tcase dto.MetricType_HISTOGRAM:\n\t\t// *sigh*\n\t\tif p.currentMetric.Histogram == nil {\n\t\t\tp.currentMetric.Histogram = &dto.Histogram{}\n\t\t}\n\t\tswitch {\n\t\tcase p.currentIsHistogramCount:\n\t\t\tp.currentMetric.Histogram.SampleCount = proto.Uint64(uint64(value))\n\t\tcase p.currentIsHistogramSum:\n\t\t\tp.currentMetric.Histogram.SampleSum = proto.Float64(value)\n\t\tcase !math.IsNaN(p.currentBucket):\n\t\t\tp.currentMetric.Histogram.Bucket = append(\n\t\t\t\tp.currentMetric.Histogram.Bucket,\n\t\t\t\t&dto.Bucket{\n\t\t\t\t\tUpperBound:      proto.Float64(p.currentBucket),\n\t\t\t\t\tCumulativeCount: proto.Uint64(uint64(value)),\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\tdefault:\n\t\tp.err = fmt.Errorf(\"unexpected type for metric name %q\", p.currentMF.GetName())\n\t}\n\tif p.currentByte == '\\n' {\n\t\treturn p.startOfLine\n\t}\n\treturn p.startTimestamp\n}\n\n// startTimestamp represents the state where the next byte read from p.buf is\n// the start of the timestamp (or whitespace leading up to it).\nfunc (p *TextParser) startTimestamp() stateFn {\n\tif p.skipBlankTab(); p.err != nil {\n\t\treturn nil // Unexpected end of input.\n\t}\n\tif p.readTokenUntilWhitespace(); p.err != nil {\n\t\treturn nil // Unexpected end of input.\n\t}\n\ttimestamp, err := strconv.ParseInt(p.currentToken.String(), 10, 64)\n\tif err != nil {\n\t\t// Create a more helpful error message.\n\t\tp.parseError(fmt.Sprintf(\"expected integer as timestamp, got %q\", p.currentToken.String()))\n\t\treturn nil\n\t}\n\tp.currentMetric.TimestampMs = proto.Int64(timestamp)\n\tif p.readTokenUntilNewline(false); p.err != nil {\n\t\treturn nil // Unexpected end of input.\n\t}\n\tif p.currentToken.Len() > 0 {\n\t\tp.parseError(fmt.Sprintf(\"spurious string after timestamp: %q\", p.currentToken.String()))\n\t\treturn nil\n\t}\n\treturn p.startOfLine\n}\n\n// readingHelp represents the state where the last byte read (now in\n// p.currentByte) is the first byte of the docstring after 'HELP'.\nfunc (p *TextParser) readingHelp() stateFn {\n\tif p.currentMF.Help != nil {\n\t\tp.parseError(fmt.Sprintf(\"second HELP line for metric name %q\", p.currentMF.GetName()))\n\t\treturn nil\n\t}\n\t// Rest of line is the docstring.\n\tif p.readTokenUntilNewline(true); p.err != nil {\n\t\treturn nil // Unexpected end of input.\n\t}\n\tp.currentMF.Help = proto.String(p.currentToken.String())\n\treturn p.startOfLine\n}\n\n// readingType represents the state where the last byte read (now in\n// p.currentByte) is the first byte of the type hint after 'HELP'.\nfunc (p *TextParser) readingType() stateFn {\n\tif p.currentMF.Type != nil {\n\t\tp.parseError(fmt.Sprintf(\"second TYPE line for metric name %q, or TYPE reported after samples\", p.currentMF.GetName()))\n\t\treturn nil\n\t}\n\t// Rest of line is the type.\n\tif p.readTokenUntilNewline(false); p.err != nil {\n\t\treturn nil // Unexpected end of input.\n\t}\n\tmetricType, ok := dto.MetricType_value[strings.ToUpper(p.currentToken.String())]\n\tif !ok {\n\t\tp.parseError(fmt.Sprintf(\"unknown metric type %q\", p.currentToken.String()))\n\t\treturn nil\n\t}\n\tp.currentMF.Type = dto.MetricType(metricType).Enum()\n\treturn p.startOfLine\n}\n\n// parseError sets p.err to a ParseError at the current line with the given\n// message.\nfunc (p *TextParser) parseError(msg string) {\n\tp.err = ParseError{\n\t\tLine: p.lineCount,\n\t\tMsg:  msg,\n\t}\n}\n\n// skipBlankTab reads (and discards) bytes from p.buf until it encounters a byte\n// that is neither ' ' nor '\\t'. That byte is left in p.currentByte.\nfunc (p *TextParser) skipBlankTab() {\n\tfor {\n\t\tif p.currentByte, p.err = p.buf.ReadByte(); p.err != nil || !isBlankOrTab(p.currentByte) {\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// skipBlankTabIfCurrentBlankTab works exactly as skipBlankTab but doesn't do\n// anything if p.currentByte is neither ' ' nor '\\t'.\nfunc (p *TextParser) skipBlankTabIfCurrentBlankTab() {\n\tif isBlankOrTab(p.currentByte) {\n\t\tp.skipBlankTab()\n\t}\n}\n\n// readTokenUntilWhitespace copies bytes from p.buf into p.currentToken.  The\n// first byte considered is the byte already read (now in p.currentByte).  The\n// first whitespace byte encountered is still copied into p.currentByte, but not\n// into p.currentToken.\nfunc (p *TextParser) readTokenUntilWhitespace() {\n\tp.currentToken.Reset()\n\tfor p.err == nil && !isBlankOrTab(p.currentByte) && p.currentByte != '\\n' {\n\t\tp.currentToken.WriteByte(p.currentByte)\n\t\tp.currentByte, p.err = p.buf.ReadByte()\n\t}\n}\n\n// readTokenUntilNewline copies bytes from p.buf into p.currentToken.  The first\n// byte considered is the byte already read (now in p.currentByte).  The first\n// newline byte encountered is still copied into p.currentByte, but not into\n// p.currentToken. If recognizeEscapeSequence is true, two escape sequences are\n// recognized: '\\\\' translates into '\\', and '\\n' into a line-feed character.\n// All other escape sequences are invalid and cause an error.\nfunc (p *TextParser) readTokenUntilNewline(recognizeEscapeSequence bool) {\n\tp.currentToken.Reset()\n\tescaped := false\n\tfor p.err == nil {\n\t\tif recognizeEscapeSequence && escaped {\n\t\t\tswitch p.currentByte {\n\t\t\tcase '\\\\':\n\t\t\t\tp.currentToken.WriteByte(p.currentByte)\n\t\t\tcase 'n':\n\t\t\t\tp.currentToken.WriteByte('\\n')\n\t\t\tcase '\"':\n\t\t\t\tp.currentToken.WriteByte('\"')\n\t\t\tdefault:\n\t\t\t\tp.parseError(fmt.Sprintf(\"invalid escape sequence '\\\\%c'\", p.currentByte))\n\t\t\t\treturn\n\t\t\t}\n\t\t\tescaped = false\n\t\t} else {\n\t\t\tswitch p.currentByte {\n\t\t\tcase '\\n':\n\t\t\t\treturn\n\t\t\tcase '\\\\':\n\t\t\t\tescaped = true\n\t\t\tdefault:\n\t\t\t\tp.currentToken.WriteByte(p.currentByte)\n\t\t\t}\n\t\t}\n\t\tp.currentByte, p.err = p.buf.ReadByte()\n\t}\n}\n\n// readTokenAsMetricName copies a metric name from p.buf into p.currentToken.\n// The first byte considered is the byte already read (now in p.currentByte).\n// The first byte not part of a metric name is still copied into p.currentByte,\n// but not into p.currentToken.\nfunc (p *TextParser) readTokenAsMetricName() {\n\tp.currentToken.Reset()\n\t// A UTF-8 metric name must be quoted and may have escaped characters.\n\tquoted := false\n\tescaped := false\n\tif !isValidMetricNameStart(p.currentByte) {\n\t\treturn\n\t}\n\tfor p.err == nil {\n\t\tif escaped {\n\t\t\tswitch p.currentByte {\n\t\t\tcase '\\\\':\n\t\t\t\tp.currentToken.WriteByte(p.currentByte)\n\t\t\tcase 'n':\n\t\t\t\tp.currentToken.WriteByte('\\n')\n\t\t\tcase '\"':\n\t\t\t\tp.currentToken.WriteByte('\"')\n\t\t\tdefault:\n\t\t\t\tp.parseError(fmt.Sprintf(\"invalid escape sequence '\\\\%c'\", p.currentByte))\n\t\t\t\treturn\n\t\t\t}\n\t\t\tescaped = false\n\t\t} else {\n\t\t\tswitch p.currentByte {\n\t\t\tcase '\"':\n\t\t\t\tquoted = !quoted\n\t\t\t\tif !quoted {\n\t\t\t\t\tp.currentByte, p.err = p.buf.ReadByte()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\tcase '\\n':\n\t\t\t\tp.parseError(fmt.Sprintf(\"metric name %q contains unescaped new-line\", p.currentToken.String()))\n\t\t\t\treturn\n\t\t\tcase '\\\\':\n\t\t\t\tescaped = true\n\t\t\tdefault:\n\t\t\t\tp.currentToken.WriteByte(p.currentByte)\n\t\t\t}\n\t\t}\n\t\tp.currentByte, p.err = p.buf.ReadByte()\n\t\tif !isValidMetricNameContinuation(p.currentByte, quoted) || (!quoted && p.currentByte == ' ') {\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// readTokenAsLabelName copies a label name from p.buf into p.currentToken.\n// The first byte considered is the byte already read (now in p.currentByte).\n// The first byte not part of a label name is still copied into p.currentByte,\n// but not into p.currentToken.\nfunc (p *TextParser) readTokenAsLabelName() {\n\tp.currentToken.Reset()\n\t// A UTF-8 label name must be quoted and may have escaped characters.\n\tquoted := false\n\tescaped := false\n\tif !isValidLabelNameStart(p.currentByte) {\n\t\treturn\n\t}\n\tfor p.err == nil {\n\t\tif escaped {\n\t\t\tswitch p.currentByte {\n\t\t\tcase '\\\\':\n\t\t\t\tp.currentToken.WriteByte(p.currentByte)\n\t\t\tcase 'n':\n\t\t\t\tp.currentToken.WriteByte('\\n')\n\t\t\tcase '\"':\n\t\t\t\tp.currentToken.WriteByte('\"')\n\t\t\tdefault:\n\t\t\t\tp.parseError(fmt.Sprintf(\"invalid escape sequence '\\\\%c'\", p.currentByte))\n\t\t\t\treturn\n\t\t\t}\n\t\t\tescaped = false\n\t\t} else {\n\t\t\tswitch p.currentByte {\n\t\t\tcase '\"':\n\t\t\t\tquoted = !quoted\n\t\t\t\tif !quoted {\n\t\t\t\t\tp.currentByte, p.err = p.buf.ReadByte()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\tcase '\\n':\n\t\t\t\tp.parseError(fmt.Sprintf(\"label name %q contains unescaped new-line\", p.currentToken.String()))\n\t\t\t\treturn\n\t\t\tcase '\\\\':\n\t\t\t\tescaped = true\n\t\t\tdefault:\n\t\t\t\tp.currentToken.WriteByte(p.currentByte)\n\t\t\t}\n\t\t}\n\t\tp.currentByte, p.err = p.buf.ReadByte()\n\t\tif !isValidLabelNameContinuation(p.currentByte, quoted) || (!quoted && p.currentByte == '=') {\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// readTokenAsLabelValue copies a label value from p.buf into p.currentToken.\n// In contrast to the other 'readTokenAs...' functions, which start with the\n// last read byte in p.currentByte, this method ignores p.currentByte and starts\n// with reading a new byte from p.buf. The first byte not part of a label value\n// is still copied into p.currentByte, but not into p.currentToken.\nfunc (p *TextParser) readTokenAsLabelValue() {\n\tp.currentToken.Reset()\n\tescaped := false\n\tfor {\n\t\tif p.currentByte, p.err = p.buf.ReadByte(); p.err != nil {\n\t\t\treturn\n\t\t}\n\t\tif escaped {\n\t\t\tswitch p.currentByte {\n\t\t\tcase '\"', '\\\\':\n\t\t\t\tp.currentToken.WriteByte(p.currentByte)\n\t\t\tcase 'n':\n\t\t\t\tp.currentToken.WriteByte('\\n')\n\t\t\tdefault:\n\t\t\t\tp.parseError(fmt.Sprintf(\"invalid escape sequence '\\\\%c'\", p.currentByte))\n\t\t\t\tp.currentLabelPairs = nil\n\t\t\t\treturn\n\t\t\t}\n\t\t\tescaped = false\n\t\t\tcontinue\n\t\t}\n\t\tswitch p.currentByte {\n\t\tcase '\"':\n\t\t\treturn\n\t\tcase '\\n':\n\t\t\tp.parseError(fmt.Sprintf(\"label value %q contains unescaped new-line\", p.currentToken.String()))\n\t\t\treturn\n\t\tcase '\\\\':\n\t\t\tescaped = true\n\t\tdefault:\n\t\t\tp.currentToken.WriteByte(p.currentByte)\n\t\t}\n\t}\n}\n\nfunc (p *TextParser) setOrCreateCurrentMF() {\n\tp.currentIsSummaryCount = false\n\tp.currentIsSummarySum = false\n\tp.currentIsHistogramCount = false\n\tp.currentIsHistogramSum = false\n\tname := p.currentToken.String()\n\tif p.currentMF = p.metricFamiliesByName[name]; p.currentMF != nil {\n\t\treturn\n\t}\n\t// Try out if this is a _sum or _count for a summary/histogram.\n\tsummaryName := summaryMetricName(name)\n\tif p.currentMF = p.metricFamiliesByName[summaryName]; p.currentMF != nil {\n\t\tif p.currentMF.GetType() == dto.MetricType_SUMMARY {\n\t\t\tif isCount(name) {\n\t\t\t\tp.currentIsSummaryCount = true\n\t\t\t}\n\t\t\tif isSum(name) {\n\t\t\t\tp.currentIsSummarySum = true\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n\thistogramName := histogramMetricName(name)\n\tif p.currentMF = p.metricFamiliesByName[histogramName]; p.currentMF != nil {\n\t\tif p.currentMF.GetType() == dto.MetricType_HISTOGRAM {\n\t\t\tif isCount(name) {\n\t\t\t\tp.currentIsHistogramCount = true\n\t\t\t}\n\t\t\tif isSum(name) {\n\t\t\t\tp.currentIsHistogramSum = true\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n\tp.currentMF = &dto.MetricFamily{Name: proto.String(name)}\n\tp.metricFamiliesByName[name] = p.currentMF\n}\n\nfunc isValidLabelNameStart(b byte) bool {\n\treturn (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || b == '\"'\n}\n\nfunc isValidLabelNameContinuation(b byte, quoted bool) bool {\n\treturn isValidLabelNameStart(b) || (b >= '0' && b <= '9') || (quoted && utf8.ValidString(string(b)))\n}\n\nfunc isValidMetricNameStart(b byte) bool {\n\treturn isValidLabelNameStart(b) || b == ':'\n}\n\nfunc isValidMetricNameContinuation(b byte, quoted bool) bool {\n\treturn isValidLabelNameContinuation(b, quoted) || b == ':'\n}\n\nfunc isBlankOrTab(b byte) bool {\n\treturn b == ' ' || b == '\\t'\n}\n\nfunc isCount(name string) bool {\n\treturn len(name) > 6 && name[len(name)-6:] == \"_count\"\n}\n\nfunc isSum(name string) bool {\n\treturn len(name) > 4 && name[len(name)-4:] == \"_sum\"\n}\n\nfunc isBucket(name string) bool {\n\treturn len(name) > 7 && name[len(name)-7:] == \"_bucket\"\n}\n\nfunc summaryMetricName(name string) string {\n\tswitch {\n\tcase isCount(name):\n\t\treturn name[:len(name)-6]\n\tcase isSum(name):\n\t\treturn name[:len(name)-4]\n\tdefault:\n\t\treturn name\n\t}\n}\n\nfunc histogramMetricName(name string) string {\n\tswitch {\n\tcase isCount(name):\n\t\treturn name[:len(name)-6]\n\tcase isSum(name):\n\t\treturn name[:len(name)-4]\n\tcase isBucket(name):\n\t\treturn name[:len(name)-7]\n\tdefault:\n\t\treturn name\n\t}\n}\n\nfunc parseFloat(s string) (float64, error) {\n\tif strings.ContainsAny(s, \"pP_\") {\n\t\treturn 0, errors.New(\"unsupported character in float\")\n\t}\n\treturn strconv.ParseFloat(s, 64)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/model/alert.go",
    "content": "// Copyright 2013 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage model\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"time\"\n)\n\ntype AlertStatus string\n\nconst (\n\tAlertFiring   AlertStatus = \"firing\"\n\tAlertResolved AlertStatus = \"resolved\"\n)\n\n// Alert is a generic representation of an alert in the Prometheus eco-system.\ntype Alert struct {\n\t// Label value pairs for purpose of aggregation, matching, and disposition\n\t// dispatching. This must minimally include an \"alertname\" label.\n\tLabels LabelSet `json:\"labels\"`\n\n\t// Extra key/value information which does not define alert identity.\n\tAnnotations LabelSet `json:\"annotations\"`\n\n\t// The known time range for this alert. Both ends are optional.\n\tStartsAt     time.Time `json:\"startsAt,omitempty\"`\n\tEndsAt       time.Time `json:\"endsAt,omitempty\"`\n\tGeneratorURL string    `json:\"generatorURL\"`\n}\n\n// Name returns the name of the alert. It is equivalent to the \"alertname\" label.\nfunc (a *Alert) Name() string {\n\treturn string(a.Labels[AlertNameLabel])\n}\n\n// Fingerprint returns a unique hash for the alert. It is equivalent to\n// the fingerprint of the alert's label set.\nfunc (a *Alert) Fingerprint() Fingerprint {\n\treturn a.Labels.Fingerprint()\n}\n\nfunc (a *Alert) String() string {\n\ts := fmt.Sprintf(\"%s[%s]\", a.Name(), a.Fingerprint().String()[:7])\n\tif a.Resolved() {\n\t\treturn s + \"[resolved]\"\n\t}\n\treturn s + \"[active]\"\n}\n\n// Resolved returns true iff the activity interval ended in the past.\nfunc (a *Alert) Resolved() bool {\n\treturn a.ResolvedAt(time.Now())\n}\n\n// ResolvedAt returns true iff the activity interval ended before\n// the given timestamp.\nfunc (a *Alert) ResolvedAt(ts time.Time) bool {\n\tif a.EndsAt.IsZero() {\n\t\treturn false\n\t}\n\treturn !a.EndsAt.After(ts)\n}\n\n// Status returns the status of the alert.\nfunc (a *Alert) Status() AlertStatus {\n\treturn a.StatusAt(time.Now())\n}\n\n// StatusAt returns the status of the alert at the given timestamp.\nfunc (a *Alert) StatusAt(ts time.Time) AlertStatus {\n\tif a.ResolvedAt(ts) {\n\t\treturn AlertResolved\n\t}\n\treturn AlertFiring\n}\n\n// Validate checks whether the alert data is inconsistent.\nfunc (a *Alert) Validate() error {\n\tif a.StartsAt.IsZero() {\n\t\treturn errors.New(\"start time missing\")\n\t}\n\tif !a.EndsAt.IsZero() && a.EndsAt.Before(a.StartsAt) {\n\t\treturn errors.New(\"start time must be before end time\")\n\t}\n\tif err := a.Labels.Validate(); err != nil {\n\t\treturn fmt.Errorf(\"invalid label set: %w\", err)\n\t}\n\tif len(a.Labels) == 0 {\n\t\treturn errors.New(\"at least one label pair required\")\n\t}\n\tif err := a.Annotations.Validate(); err != nil {\n\t\treturn fmt.Errorf(\"invalid annotations: %w\", err)\n\t}\n\treturn nil\n}\n\n// Alert is a list of alerts that can be sorted in chronological order.\ntype Alerts []*Alert\n\nfunc (as Alerts) Len() int      { return len(as) }\nfunc (as Alerts) Swap(i, j int) { as[i], as[j] = as[j], as[i] }\n\nfunc (as Alerts) Less(i, j int) bool {\n\tif as[i].StartsAt.Before(as[j].StartsAt) {\n\t\treturn true\n\t}\n\tif as[i].EndsAt.Before(as[j].EndsAt) {\n\t\treturn true\n\t}\n\treturn as[i].Fingerprint() < as[j].Fingerprint()\n}\n\n// HasFiring returns true iff one of the alerts is not resolved.\nfunc (as Alerts) HasFiring() bool {\n\tfor _, a := range as {\n\t\tif !a.Resolved() {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// HasFiringAt returns true iff one of the alerts is not resolved\n// at the time ts.\nfunc (as Alerts) HasFiringAt(ts time.Time) bool {\n\tfor _, a := range as {\n\t\tif !a.ResolvedAt(ts) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Status returns StatusFiring iff at least one of the alerts is firing.\nfunc (as Alerts) Status() AlertStatus {\n\tif as.HasFiring() {\n\t\treturn AlertFiring\n\t}\n\treturn AlertResolved\n}\n\n// StatusAt returns StatusFiring iff at least one of the alerts is firing\n// at the time ts.\nfunc (as Alerts) StatusAt(ts time.Time) AlertStatus {\n\tif as.HasFiringAt(ts) {\n\t\treturn AlertFiring\n\t}\n\treturn AlertResolved\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/model/fingerprinting.go",
    "content": "// Copyright 2013 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage model\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n)\n\n// Fingerprint provides a hash-capable representation of a Metric.\n// For our purposes, FNV-1A 64-bit is used.\ntype Fingerprint uint64\n\n// FingerprintFromString transforms a string representation into a Fingerprint.\nfunc FingerprintFromString(s string) (Fingerprint, error) {\n\tnum, err := strconv.ParseUint(s, 16, 64)\n\treturn Fingerprint(num), err\n}\n\n// ParseFingerprint parses the input string into a fingerprint.\nfunc ParseFingerprint(s string) (Fingerprint, error) {\n\tnum, err := strconv.ParseUint(s, 16, 64)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn Fingerprint(num), nil\n}\n\nfunc (f Fingerprint) String() string {\n\treturn fmt.Sprintf(\"%016x\", uint64(f))\n}\n\n// Fingerprints represents a collection of Fingerprint subject to a given\n// natural sorting scheme. It implements sort.Interface.\ntype Fingerprints []Fingerprint\n\n// Len implements sort.Interface.\nfunc (f Fingerprints) Len() int {\n\treturn len(f)\n}\n\n// Less implements sort.Interface.\nfunc (f Fingerprints) Less(i, j int) bool {\n\treturn f[i] < f[j]\n}\n\n// Swap implements sort.Interface.\nfunc (f Fingerprints) Swap(i, j int) {\n\tf[i], f[j] = f[j], f[i]\n}\n\n// FingerprintSet is a set of Fingerprints.\ntype FingerprintSet map[Fingerprint]struct{}\n\n// Equal returns true if both sets contain the same elements (and not more).\nfunc (s FingerprintSet) Equal(o FingerprintSet) bool {\n\tif len(s) != len(o) {\n\t\treturn false\n\t}\n\n\tfor k := range s {\n\t\tif _, ok := o[k]; !ok {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\n// Intersection returns the elements contained in both sets.\nfunc (s FingerprintSet) Intersection(o FingerprintSet) FingerprintSet {\n\tmyLength, otherLength := len(s), len(o)\n\tif myLength == 0 || otherLength == 0 {\n\t\treturn FingerprintSet{}\n\t}\n\n\tsubSet := s\n\tsuperSet := o\n\n\tif otherLength < myLength {\n\t\tsubSet = o\n\t\tsuperSet = s\n\t}\n\n\tout := FingerprintSet{}\n\n\tfor k := range subSet {\n\t\tif _, ok := superSet[k]; ok {\n\t\t\tout[k] = struct{}{}\n\t\t}\n\t}\n\n\treturn out\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/model/fnv.go",
    "content": "// Copyright 2015 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage model\n\n// Inline and byte-free variant of hash/fnv's fnv64a.\n\nconst (\n\toffset64 = 14695981039346656037\n\tprime64  = 1099511628211\n)\n\n// hashNew initializes a new fnv64a hash value.\nfunc hashNew() uint64 {\n\treturn offset64\n}\n\n// hashAdd adds a string to a fnv64a hash value, returning the updated hash.\nfunc hashAdd(h uint64, s string) uint64 {\n\tfor i := 0; i < len(s); i++ {\n\t\th ^= uint64(s[i])\n\t\th *= prime64\n\t}\n\treturn h\n}\n\n// hashAddByte adds a byte to a fnv64a hash value, returning the updated hash.\nfunc hashAddByte(h uint64, b byte) uint64 {\n\th ^= uint64(b)\n\th *= prime64\n\treturn h\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/model/labels.go",
    "content": "// Copyright 2013 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage model\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\nconst (\n\t// AlertNameLabel is the name of the label containing the alert's name.\n\tAlertNameLabel = \"alertname\"\n\n\t// ExportedLabelPrefix is the prefix to prepend to the label names present in\n\t// exported metrics if a label of the same name is added by the server.\n\tExportedLabelPrefix = \"exported_\"\n\n\t// MetricNameLabel is the label name indicating the metric name of a\n\t// timeseries.\n\tMetricNameLabel = \"__name__\"\n\n\t// SchemeLabel is the name of the label that holds the scheme on which to\n\t// scrape a target.\n\tSchemeLabel = \"__scheme__\"\n\n\t// AddressLabel is the name of the label that holds the address of\n\t// a scrape target.\n\tAddressLabel = \"__address__\"\n\n\t// MetricsPathLabel is the name of the label that holds the path on which to\n\t// scrape a target.\n\tMetricsPathLabel = \"__metrics_path__\"\n\n\t// ScrapeIntervalLabel is the name of the label that holds the scrape interval\n\t// used to scrape a target.\n\tScrapeIntervalLabel = \"__scrape_interval__\"\n\n\t// ScrapeTimeoutLabel is the name of the label that holds the scrape\n\t// timeout used to scrape a target.\n\tScrapeTimeoutLabel = \"__scrape_timeout__\"\n\n\t// ReservedLabelPrefix is a prefix which is not legal in user-supplied\n\t// label names.\n\tReservedLabelPrefix = \"__\"\n\n\t// MetaLabelPrefix is a prefix for labels that provide meta information.\n\t// Labels with this prefix are used for intermediate label processing and\n\t// will not be attached to time series.\n\tMetaLabelPrefix = \"__meta_\"\n\n\t// TmpLabelPrefix is a prefix for temporary labels as part of relabelling.\n\t// Labels with this prefix are used for intermediate label processing and\n\t// will not be attached to time series. This is reserved for use in\n\t// Prometheus configuration files by users.\n\tTmpLabelPrefix = \"__tmp_\"\n\n\t// ParamLabelPrefix is a prefix for labels that provide URL parameters\n\t// used to scrape a target.\n\tParamLabelPrefix = \"__param_\"\n\n\t// JobLabel is the label name indicating the job from which a timeseries\n\t// was scraped.\n\tJobLabel = \"job\"\n\n\t// InstanceLabel is the label name used for the instance label.\n\tInstanceLabel = \"instance\"\n\n\t// BucketLabel is used for the label that defines the upper bound of a\n\t// bucket of a histogram (\"le\" -> \"less or equal\").\n\tBucketLabel = \"le\"\n\n\t// QuantileLabel is used for the label that defines the quantile in a\n\t// summary.\n\tQuantileLabel = \"quantile\"\n)\n\n// LabelNameRE is a regular expression matching valid label names. Note that the\n// IsValid method of LabelName performs the same check but faster than a match\n// with this regular expression.\nvar LabelNameRE = regexp.MustCompile(\"^[a-zA-Z_][a-zA-Z0-9_]*$\")\n\n// A LabelName is a key for a LabelSet or Metric.  It has a value associated\n// therewith.\ntype LabelName string\n\n// IsValid returns true iff the name matches the pattern of LabelNameRE when\n// NameValidationScheme is set to LegacyValidation, or valid UTF-8 if\n// NameValidationScheme is set to UTF8Validation.\nfunc (ln LabelName) IsValid() bool {\n\tif len(ln) == 0 {\n\t\treturn false\n\t}\n\tswitch NameValidationScheme {\n\tcase LegacyValidation:\n\t\treturn ln.IsValidLegacy()\n\tcase UTF8Validation:\n\t\treturn utf8.ValidString(string(ln))\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"Invalid name validation scheme requested: %d\", NameValidationScheme))\n\t}\n}\n\n// IsValidLegacy returns true iff name matches the pattern of LabelNameRE for\n// legacy names. It does not use LabelNameRE for the check but a much faster\n// hardcoded implementation.\nfunc (ln LabelName) IsValidLegacy() bool {\n\tif len(ln) == 0 {\n\t\treturn false\n\t}\n\tfor i, b := range ln {\n\t\t// TODO: Apply De Morgan's law. Make sure there are tests for this.\n\t\tif !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || (b >= '0' && b <= '9' && i > 0)) { //nolint:staticcheck\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// UnmarshalYAML implements the yaml.Unmarshaler interface.\nfunc (ln *LabelName) UnmarshalYAML(unmarshal func(interface{}) error) error {\n\tvar s string\n\tif err := unmarshal(&s); err != nil {\n\t\treturn err\n\t}\n\tif !LabelName(s).IsValid() {\n\t\treturn fmt.Errorf(\"%q is not a valid label name\", s)\n\t}\n\t*ln = LabelName(s)\n\treturn nil\n}\n\n// UnmarshalJSON implements the json.Unmarshaler interface.\nfunc (ln *LabelName) UnmarshalJSON(b []byte) error {\n\tvar s string\n\tif err := json.Unmarshal(b, &s); err != nil {\n\t\treturn err\n\t}\n\tif !LabelName(s).IsValid() {\n\t\treturn fmt.Errorf(\"%q is not a valid label name\", s)\n\t}\n\t*ln = LabelName(s)\n\treturn nil\n}\n\n// LabelNames is a sortable LabelName slice. In implements sort.Interface.\ntype LabelNames []LabelName\n\nfunc (l LabelNames) Len() int {\n\treturn len(l)\n}\n\nfunc (l LabelNames) Less(i, j int) bool {\n\treturn l[i] < l[j]\n}\n\nfunc (l LabelNames) Swap(i, j int) {\n\tl[i], l[j] = l[j], l[i]\n}\n\nfunc (l LabelNames) String() string {\n\tlabelStrings := make([]string, 0, len(l))\n\tfor _, label := range l {\n\t\tlabelStrings = append(labelStrings, string(label))\n\t}\n\treturn strings.Join(labelStrings, \", \")\n}\n\n// A LabelValue is an associated value for a LabelName.\ntype LabelValue string\n\n// IsValid returns true iff the string is a valid UTF-8.\nfunc (lv LabelValue) IsValid() bool {\n\treturn utf8.ValidString(string(lv))\n}\n\n// LabelValues is a sortable LabelValue slice. It implements sort.Interface.\ntype LabelValues []LabelValue\n\nfunc (l LabelValues) Len() int {\n\treturn len(l)\n}\n\nfunc (l LabelValues) Less(i, j int) bool {\n\treturn string(l[i]) < string(l[j])\n}\n\nfunc (l LabelValues) Swap(i, j int) {\n\tl[i], l[j] = l[j], l[i]\n}\n\n// LabelPair pairs a name with a value.\ntype LabelPair struct {\n\tName  LabelName\n\tValue LabelValue\n}\n\n// LabelPairs is a sortable slice of LabelPair pointers. It implements\n// sort.Interface.\ntype LabelPairs []*LabelPair\n\nfunc (l LabelPairs) Len() int {\n\treturn len(l)\n}\n\nfunc (l LabelPairs) Less(i, j int) bool {\n\tswitch {\n\tcase l[i].Name > l[j].Name:\n\t\treturn false\n\tcase l[i].Name < l[j].Name:\n\t\treturn true\n\tcase l[i].Value > l[j].Value:\n\t\treturn false\n\tcase l[i].Value < l[j].Value:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc (l LabelPairs) Swap(i, j int) {\n\tl[i], l[j] = l[j], l[i]\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/model/labelset.go",
    "content": "// Copyright 2013 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage model\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sort\"\n)\n\n// A LabelSet is a collection of LabelName and LabelValue pairs.  The LabelSet\n// may be fully-qualified down to the point where it may resolve to a single\n// Metric in the data store or not.  All operations that occur within the realm\n// of a LabelSet can emit a vector of Metric entities to which the LabelSet may\n// match.\ntype LabelSet map[LabelName]LabelValue\n\n// Validate checks whether all names and values in the label set\n// are valid.\nfunc (ls LabelSet) Validate() error {\n\tfor ln, lv := range ls {\n\t\tif !ln.IsValid() {\n\t\t\treturn fmt.Errorf(\"invalid name %q\", ln)\n\t\t}\n\t\tif !lv.IsValid() {\n\t\t\treturn fmt.Errorf(\"invalid value %q\", lv)\n\t\t}\n\t}\n\treturn nil\n}\n\n// Equal returns true iff both label sets have exactly the same key/value pairs.\nfunc (ls LabelSet) Equal(o LabelSet) bool {\n\tif len(ls) != len(o) {\n\t\treturn false\n\t}\n\tfor ln, lv := range ls {\n\t\tolv, ok := o[ln]\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\t\tif olv != lv {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Before compares the metrics, using the following criteria:\n//\n// If m has fewer labels than o, it is before o. If it has more, it is not.\n//\n// If the number of labels is the same, the superset of all label names is\n// sorted alphanumerically. The first differing label pair found in that order\n// determines the outcome: If the label does not exist at all in m, then m is\n// before o, and vice versa. Otherwise the label value is compared\n// alphanumerically.\n//\n// If m and o are equal, the method returns false.\nfunc (ls LabelSet) Before(o LabelSet) bool {\n\tif len(ls) < len(o) {\n\t\treturn true\n\t}\n\tif len(ls) > len(o) {\n\t\treturn false\n\t}\n\n\tlns := make(LabelNames, 0, len(ls)+len(o))\n\tfor ln := range ls {\n\t\tlns = append(lns, ln)\n\t}\n\tfor ln := range o {\n\t\tlns = append(lns, ln)\n\t}\n\t// It's probably not worth it to de-dup lns.\n\tsort.Sort(lns)\n\tfor _, ln := range lns {\n\t\tmlv, ok := ls[ln]\n\t\tif !ok {\n\t\t\treturn true\n\t\t}\n\t\tolv, ok := o[ln]\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\t\tif mlv < olv {\n\t\t\treturn true\n\t\t}\n\t\tif mlv > olv {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn false\n}\n\n// Clone returns a copy of the label set.\nfunc (ls LabelSet) Clone() LabelSet {\n\tlsn := make(LabelSet, len(ls))\n\tfor ln, lv := range ls {\n\t\tlsn[ln] = lv\n\t}\n\treturn lsn\n}\n\n// Merge is a helper function to non-destructively merge two label sets.\nfunc (l LabelSet) Merge(other LabelSet) LabelSet {\n\tresult := make(LabelSet, len(l))\n\n\tfor k, v := range l {\n\t\tresult[k] = v\n\t}\n\n\tfor k, v := range other {\n\t\tresult[k] = v\n\t}\n\n\treturn result\n}\n\n// Fingerprint returns the LabelSet's fingerprint.\nfunc (ls LabelSet) Fingerprint() Fingerprint {\n\treturn labelSetToFingerprint(ls)\n}\n\n// FastFingerprint returns the LabelSet's Fingerprint calculated by a faster hashing\n// algorithm, which is, however, more susceptible to hash collisions.\nfunc (ls LabelSet) FastFingerprint() Fingerprint {\n\treturn labelSetToFastFingerprint(ls)\n}\n\n// UnmarshalJSON implements the json.Unmarshaler interface.\nfunc (l *LabelSet) UnmarshalJSON(b []byte) error {\n\tvar m map[LabelName]LabelValue\n\tif err := json.Unmarshal(b, &m); err != nil {\n\t\treturn err\n\t}\n\t// encoding/json only unmarshals maps of the form map[string]T. It treats\n\t// LabelName as a string and does not call its UnmarshalJSON method.\n\t// Thus, we have to replicate the behavior here.\n\tfor ln := range m {\n\t\tif !ln.IsValid() {\n\t\t\treturn fmt.Errorf(\"%q is not a valid label name\", ln)\n\t\t}\n\t}\n\t*l = LabelSet(m)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/model/labelset_string.go",
    "content": "// Copyright 2024 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage model\n\nimport (\n\t\"bytes\"\n\t\"slices\"\n\t\"strconv\"\n)\n\n// String will look like `{foo=\"bar\", more=\"less\"}`. Names are sorted alphabetically.\nfunc (l LabelSet) String() string {\n\tvar lna [32]string // On stack to avoid memory allocation for sorting names.\n\tlabelNames := lna[:0]\n\tfor name := range l {\n\t\tlabelNames = append(labelNames, string(name))\n\t}\n\tslices.Sort(labelNames)\n\tvar bytea [1024]byte // On stack to avoid memory allocation while building the output.\n\tb := bytes.NewBuffer(bytea[:0])\n\tb.WriteByte('{')\n\tfor i, name := range labelNames {\n\t\tif i > 0 {\n\t\t\tb.WriteString(\", \")\n\t\t}\n\t\tb.WriteString(name)\n\t\tb.WriteByte('=')\n\t\tb.Write(strconv.AppendQuote(b.AvailableBuffer(), string(l[LabelName(name)])))\n\t}\n\tb.WriteByte('}')\n\treturn b.String()\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/model/metadata.go",
    "content": "// Copyright 2023 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage model\n\n// MetricType represents metric type values.\ntype MetricType string\n\nconst (\n\tMetricTypeCounter        = MetricType(\"counter\")\n\tMetricTypeGauge          = MetricType(\"gauge\")\n\tMetricTypeHistogram      = MetricType(\"histogram\")\n\tMetricTypeGaugeHistogram = MetricType(\"gaugehistogram\")\n\tMetricTypeSummary        = MetricType(\"summary\")\n\tMetricTypeInfo           = MetricType(\"info\")\n\tMetricTypeStateset       = MetricType(\"stateset\")\n\tMetricTypeUnknown        = MetricType(\"unknown\")\n)\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/model/metric.go",
    "content": "// Copyright 2013 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage model\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\tdto \"github.com/prometheus/client_model/go\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\nvar (\n\t// NameValidationScheme determines the global default method of the name\n\t// validation to be used by all calls to IsValidMetricName() and LabelName\n\t// IsValid().\n\t//\n\t// Deprecated: This variable should not be used and might be removed in the\n\t// far future. If you wish to stick to the legacy name validation use\n\t// `IsValidLegacyMetricName()` and `LabelName.IsValidLegacy()` methods\n\t// instead. This variable is here as an escape hatch for emergency cases,\n\t// given the recent change from `LegacyValidation` to `UTF8Validation`, e.g.,\n\t// to delay UTF-8 migrations in time or aid in debugging unforeseen results of\n\t// the change. In such a case, a temporary assignment to `LegacyValidation`\n\t// value in the `init()` function in your main.go or so, could be considered.\n\t//\n\t// Historically we opted for a global variable for feature gating different\n\t// validation schemes in operations that were not otherwise easily adjustable\n\t// (e.g. Labels yaml unmarshaling). That could have been a mistake, a separate\n\t// Labels structure or package might have been a better choice. Given the\n\t// change was made and many upgraded the common already, we live this as-is\n\t// with this warning and learning for the future.\n\tNameValidationScheme = UTF8Validation\n\n\t// NameEscapingScheme defines the default way that names will be escaped when\n\t// presented to systems that do not support UTF-8 names. If the Content-Type\n\t// \"escaping\" term is specified, that will override this value.\n\t// NameEscapingScheme should not be set to the NoEscaping value. That string\n\t// is used in content negotiation to indicate that a system supports UTF-8 and\n\t// has that feature enabled.\n\tNameEscapingScheme = UnderscoreEscaping\n)\n\n// ValidationScheme is a Go enum for determining how metric and label names will\n// be validated by this library.\ntype ValidationScheme int\n\nconst (\n\t// LegacyValidation is a setting that requires that all metric and label names\n\t// conform to the original Prometheus character requirements described by\n\t// MetricNameRE and LabelNameRE.\n\tLegacyValidation ValidationScheme = iota\n\n\t// UTF8Validation only requires that metric and label names be valid UTF-8\n\t// strings.\n\tUTF8Validation\n)\n\ntype EscapingScheme int\n\nconst (\n\t// NoEscaping indicates that a name will not be escaped. Unescaped names that\n\t// do not conform to the legacy validity check will use a new exposition\n\t// format syntax that will be officially standardized in future versions.\n\tNoEscaping EscapingScheme = iota\n\n\t// UnderscoreEscaping replaces all legacy-invalid characters with underscores.\n\tUnderscoreEscaping\n\n\t// DotsEscaping is similar to UnderscoreEscaping, except that dots are\n\t// converted to `_dot_` and pre-existing underscores are converted to `__`.\n\tDotsEscaping\n\n\t// ValueEncodingEscaping prepends the name with `U__` and replaces all invalid\n\t// characters with the unicode value, surrounded by underscores. Single\n\t// underscores are replaced with double underscores.\n\tValueEncodingEscaping\n)\n\nconst (\n\t// EscapingKey is the key in an Accept or Content-Type header that defines how\n\t// metric and label names that do not conform to the legacy character\n\t// requirements should be escaped when being scraped by a legacy prometheus\n\t// system. If a system does not explicitly pass an escaping parameter in the\n\t// Accept header, the default NameEscapingScheme will be used.\n\tEscapingKey = \"escaping\"\n\n\t// Possible values for Escaping Key:\n\tAllowUTF8         = \"allow-utf-8\" // No escaping required.\n\tEscapeUnderscores = \"underscores\"\n\tEscapeDots        = \"dots\"\n\tEscapeValues      = \"values\"\n)\n\n// MetricNameRE is a regular expression matching valid metric\n// names. Note that the IsValidMetricName function performs the same\n// check but faster than a match with this regular expression.\nvar MetricNameRE = regexp.MustCompile(`^[a-zA-Z_:][a-zA-Z0-9_:]*$`)\n\n// A Metric is similar to a LabelSet, but the key difference is that a Metric is\n// a singleton and refers to one and only one stream of samples.\ntype Metric LabelSet\n\n// Equal compares the metrics.\nfunc (m Metric) Equal(o Metric) bool {\n\treturn LabelSet(m).Equal(LabelSet(o))\n}\n\n// Before compares the metrics' underlying label sets.\nfunc (m Metric) Before(o Metric) bool {\n\treturn LabelSet(m).Before(LabelSet(o))\n}\n\n// Clone returns a copy of the Metric.\nfunc (m Metric) Clone() Metric {\n\tclone := make(Metric, len(m))\n\tfor k, v := range m {\n\t\tclone[k] = v\n\t}\n\treturn clone\n}\n\nfunc (m Metric) String() string {\n\tmetricName, hasName := m[MetricNameLabel]\n\tnumLabels := len(m) - 1\n\tif !hasName {\n\t\tnumLabels = len(m)\n\t}\n\tlabelStrings := make([]string, 0, numLabels)\n\tfor label, value := range m {\n\t\tif label != MetricNameLabel {\n\t\t\tlabelStrings = append(labelStrings, fmt.Sprintf(\"%s=%q\", label, value))\n\t\t}\n\t}\n\n\tswitch numLabels {\n\tcase 0:\n\t\tif hasName {\n\t\t\treturn string(metricName)\n\t\t}\n\t\treturn \"{}\"\n\tdefault:\n\t\tsort.Strings(labelStrings)\n\t\treturn fmt.Sprintf(\"%s{%s}\", metricName, strings.Join(labelStrings, \", \"))\n\t}\n}\n\n// Fingerprint returns a Metric's Fingerprint.\nfunc (m Metric) Fingerprint() Fingerprint {\n\treturn LabelSet(m).Fingerprint()\n}\n\n// FastFingerprint returns a Metric's Fingerprint calculated by a faster hashing\n// algorithm, which is, however, more susceptible to hash collisions.\nfunc (m Metric) FastFingerprint() Fingerprint {\n\treturn LabelSet(m).FastFingerprint()\n}\n\n// IsValidMetricName returns true iff name matches the pattern of MetricNameRE\n// for legacy names, and iff it's valid UTF-8 if the UTF8Validation scheme is\n// selected.\nfunc IsValidMetricName(n LabelValue) bool {\n\tswitch NameValidationScheme {\n\tcase LegacyValidation:\n\t\treturn IsValidLegacyMetricName(string(n))\n\tcase UTF8Validation:\n\t\tif len(n) == 0 {\n\t\t\treturn false\n\t\t}\n\t\treturn utf8.ValidString(string(n))\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"Invalid name validation scheme requested: %d\", NameValidationScheme))\n\t}\n}\n\n// IsValidLegacyMetricName is similar to IsValidMetricName but always uses the\n// legacy validation scheme regardless of the value of NameValidationScheme.\n// This function, however, does not use MetricNameRE for the check but a much\n// faster hardcoded implementation.\nfunc IsValidLegacyMetricName(n string) bool {\n\tif len(n) == 0 {\n\t\treturn false\n\t}\n\tfor i, b := range n {\n\t\tif !isValidLegacyRune(b, i) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// EscapeMetricFamily escapes the given metric names and labels with the given\n// escaping scheme. Returns a new object that uses the same pointers to fields\n// when possible and creates new escaped versions so as not to mutate the\n// input.\nfunc EscapeMetricFamily(v *dto.MetricFamily, scheme EscapingScheme) *dto.MetricFamily {\n\tif v == nil {\n\t\treturn nil\n\t}\n\n\tif scheme == NoEscaping {\n\t\treturn v\n\t}\n\n\tout := &dto.MetricFamily{\n\t\tHelp: v.Help,\n\t\tType: v.Type,\n\t\tUnit: v.Unit,\n\t}\n\n\t// If the name is nil, copy as-is, don't try to escape.\n\tif v.Name == nil || IsValidLegacyMetricName(v.GetName()) {\n\t\tout.Name = v.Name\n\t} else {\n\t\tout.Name = proto.String(EscapeName(v.GetName(), scheme))\n\t}\n\tfor _, m := range v.Metric {\n\t\tif !metricNeedsEscaping(m) {\n\t\t\tout.Metric = append(out.Metric, m)\n\t\t\tcontinue\n\t\t}\n\n\t\tescaped := &dto.Metric{\n\t\t\tGauge:       m.Gauge,\n\t\t\tCounter:     m.Counter,\n\t\t\tSummary:     m.Summary,\n\t\t\tUntyped:     m.Untyped,\n\t\t\tHistogram:   m.Histogram,\n\t\t\tTimestampMs: m.TimestampMs,\n\t\t}\n\n\t\tfor _, l := range m.Label {\n\t\t\tif l.GetName() == MetricNameLabel {\n\t\t\t\tif l.Value == nil || IsValidLegacyMetricName(l.GetValue()) {\n\t\t\t\t\tescaped.Label = append(escaped.Label, l)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tescaped.Label = append(escaped.Label, &dto.LabelPair{\n\t\t\t\t\tName:  proto.String(MetricNameLabel),\n\t\t\t\t\tValue: proto.String(EscapeName(l.GetValue(), scheme)),\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif l.Name == nil || IsValidLegacyMetricName(l.GetName()) {\n\t\t\t\tescaped.Label = append(escaped.Label, l)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tescaped.Label = append(escaped.Label, &dto.LabelPair{\n\t\t\t\tName:  proto.String(EscapeName(l.GetName(), scheme)),\n\t\t\t\tValue: l.Value,\n\t\t\t})\n\t\t}\n\t\tout.Metric = append(out.Metric, escaped)\n\t}\n\treturn out\n}\n\nfunc metricNeedsEscaping(m *dto.Metric) bool {\n\tfor _, l := range m.Label {\n\t\tif l.GetName() == MetricNameLabel && !IsValidLegacyMetricName(l.GetValue()) {\n\t\t\treturn true\n\t\t}\n\t\tif !IsValidLegacyMetricName(l.GetName()) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// EscapeName escapes the incoming name according to the provided escaping\n// scheme. Depending on the rules of escaping, this may cause no change in the\n// string that is returned. (Especially NoEscaping, which by definition is a\n// noop). This function does not do any validation of the name.\nfunc EscapeName(name string, scheme EscapingScheme) string {\n\tif len(name) == 0 {\n\t\treturn name\n\t}\n\tvar escaped strings.Builder\n\tswitch scheme {\n\tcase NoEscaping:\n\t\treturn name\n\tcase UnderscoreEscaping:\n\t\tif IsValidLegacyMetricName(name) {\n\t\t\treturn name\n\t\t}\n\t\tfor i, b := range name {\n\t\t\tif isValidLegacyRune(b, i) {\n\t\t\t\tescaped.WriteRune(b)\n\t\t\t} else {\n\t\t\t\tescaped.WriteRune('_')\n\t\t\t}\n\t\t}\n\t\treturn escaped.String()\n\tcase DotsEscaping:\n\t\t// Do not early return for legacy valid names, we still escape underscores.\n\t\tfor i, b := range name {\n\t\t\tif b == '_' {\n\t\t\t\tescaped.WriteString(\"__\")\n\t\t\t} else if b == '.' {\n\t\t\t\tescaped.WriteString(\"_dot_\")\n\t\t\t} else if isValidLegacyRune(b, i) {\n\t\t\t\tescaped.WriteRune(b)\n\t\t\t} else {\n\t\t\t\tescaped.WriteString(\"__\")\n\t\t\t}\n\t\t}\n\t\treturn escaped.String()\n\tcase ValueEncodingEscaping:\n\t\tif IsValidLegacyMetricName(name) {\n\t\t\treturn name\n\t\t}\n\t\tescaped.WriteString(\"U__\")\n\t\tfor i, b := range name {\n\t\t\tif b == '_' {\n\t\t\t\tescaped.WriteString(\"__\")\n\t\t\t} else if isValidLegacyRune(b, i) {\n\t\t\t\tescaped.WriteRune(b)\n\t\t\t} else if !utf8.ValidRune(b) {\n\t\t\t\tescaped.WriteString(\"_FFFD_\")\n\t\t\t} else {\n\t\t\t\tescaped.WriteRune('_')\n\t\t\t\tescaped.WriteString(strconv.FormatInt(int64(b), 16))\n\t\t\t\tescaped.WriteRune('_')\n\t\t\t}\n\t\t}\n\t\treturn escaped.String()\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"invalid escaping scheme %d\", scheme))\n\t}\n}\n\n// lower function taken from strconv.atoi\nfunc lower(c byte) byte {\n\treturn c | ('x' - 'X')\n}\n\n// UnescapeName unescapes the incoming name according to the provided escaping\n// scheme if possible. Some schemes are partially or totally non-roundtripable.\n// If any error is enountered, returns the original input.\nfunc UnescapeName(name string, scheme EscapingScheme) string {\n\tif len(name) == 0 {\n\t\treturn name\n\t}\n\tswitch scheme {\n\tcase NoEscaping:\n\t\treturn name\n\tcase UnderscoreEscaping:\n\t\t// It is not possible to unescape from underscore replacement.\n\t\treturn name\n\tcase DotsEscaping:\n\t\tname = strings.ReplaceAll(name, \"_dot_\", \".\")\n\t\tname = strings.ReplaceAll(name, \"__\", \"_\")\n\t\treturn name\n\tcase ValueEncodingEscaping:\n\t\tescapedName, found := strings.CutPrefix(name, \"U__\")\n\t\tif !found {\n\t\t\treturn name\n\t\t}\n\n\t\tvar unescaped strings.Builder\n\tTOP:\n\t\tfor i := 0; i < len(escapedName); i++ {\n\t\t\t// All non-underscores are treated normally.\n\t\t\tif escapedName[i] != '_' {\n\t\t\t\tunescaped.WriteByte(escapedName[i])\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ti++\n\t\t\tif i >= len(escapedName) {\n\t\t\t\treturn name\n\t\t\t}\n\t\t\t// A double underscore is a single underscore.\n\t\t\tif escapedName[i] == '_' {\n\t\t\t\tunescaped.WriteByte('_')\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// We think we are in a UTF-8 code, process it.\n\t\t\tvar utf8Val uint\n\t\t\tfor j := 0; i < len(escapedName); j++ {\n\t\t\t\t// This is too many characters for a utf8 value based on the MaxRune\n\t\t\t\t// value of '\\U0010FFFF'.\n\t\t\t\tif j >= 6 {\n\t\t\t\t\treturn name\n\t\t\t\t}\n\t\t\t\t// Found a closing underscore, convert to a rune, check validity, and append.\n\t\t\t\tif escapedName[i] == '_' {\n\t\t\t\t\tutf8Rune := rune(utf8Val)\n\t\t\t\t\tif !utf8.ValidRune(utf8Rune) {\n\t\t\t\t\t\treturn name\n\t\t\t\t\t}\n\t\t\t\t\tunescaped.WriteRune(utf8Rune)\n\t\t\t\t\tcontinue TOP\n\t\t\t\t}\n\t\t\t\tr := lower(escapedName[i])\n\t\t\t\tutf8Val *= 16\n\t\t\t\tif r >= '0' && r <= '9' {\n\t\t\t\t\tutf8Val += uint(r) - '0'\n\t\t\t\t} else if r >= 'a' && r <= 'f' {\n\t\t\t\t\tutf8Val += uint(r) - 'a' + 10\n\t\t\t\t} else {\n\t\t\t\t\treturn name\n\t\t\t\t}\n\t\t\t\ti++\n\t\t\t}\n\t\t\t// Didn't find closing underscore, invalid.\n\t\t\treturn name\n\t\t}\n\t\treturn unescaped.String()\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"invalid escaping scheme %d\", scheme))\n\t}\n}\n\nfunc isValidLegacyRune(b rune, i int) bool {\n\treturn (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || b == ':' || (b >= '0' && b <= '9' && i > 0)\n}\n\nfunc (e EscapingScheme) String() string {\n\tswitch e {\n\tcase NoEscaping:\n\t\treturn AllowUTF8\n\tcase UnderscoreEscaping:\n\t\treturn EscapeUnderscores\n\tcase DotsEscaping:\n\t\treturn EscapeDots\n\tcase ValueEncodingEscaping:\n\t\treturn EscapeValues\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unknown format scheme %d\", e))\n\t}\n}\n\nfunc ToEscapingScheme(s string) (EscapingScheme, error) {\n\tif s == \"\" {\n\t\treturn NoEscaping, errors.New(\"got empty string instead of escaping scheme\")\n\t}\n\tswitch s {\n\tcase AllowUTF8:\n\t\treturn NoEscaping, nil\n\tcase EscapeUnderscores:\n\t\treturn UnderscoreEscaping, nil\n\tcase EscapeDots:\n\t\treturn DotsEscaping, nil\n\tcase EscapeValues:\n\t\treturn ValueEncodingEscaping, nil\n\tdefault:\n\t\treturn NoEscaping, fmt.Errorf(\"unknown format scheme %s\", s)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/model/model.go",
    "content": "// Copyright 2013 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Package model contains common data structures that are shared across\n// Prometheus components and libraries.\npackage model\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/model/signature.go",
    "content": "// Copyright 2014 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage model\n\nimport (\n\t\"sort\"\n)\n\n// SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is\n// used to separate label names, label values, and other strings from each other\n// when calculating their combined hash value (aka signature aka fingerprint).\nconst SeparatorByte byte = 255\n\n// cache the signature of an empty label set.\nvar emptyLabelSignature = hashNew()\n\n// LabelsToSignature returns a quasi-unique signature (i.e., fingerprint) for a\n// given label set. (Collisions are possible but unlikely if the number of label\n// sets the function is applied to is small.)\nfunc LabelsToSignature(labels map[string]string) uint64 {\n\tif len(labels) == 0 {\n\t\treturn emptyLabelSignature\n\t}\n\n\tlabelNames := make([]string, 0, len(labels))\n\tfor labelName := range labels {\n\t\tlabelNames = append(labelNames, labelName)\n\t}\n\tsort.Strings(labelNames)\n\n\tsum := hashNew()\n\tfor _, labelName := range labelNames {\n\t\tsum = hashAdd(sum, labelName)\n\t\tsum = hashAddByte(sum, SeparatorByte)\n\t\tsum = hashAdd(sum, labels[labelName])\n\t\tsum = hashAddByte(sum, SeparatorByte)\n\t}\n\treturn sum\n}\n\n// labelSetToFingerprint works exactly as LabelsToSignature but takes a LabelSet as\n// parameter (rather than a label map) and returns a Fingerprint.\nfunc labelSetToFingerprint(ls LabelSet) Fingerprint {\n\tif len(ls) == 0 {\n\t\treturn Fingerprint(emptyLabelSignature)\n\t}\n\n\tlabelNames := make(LabelNames, 0, len(ls))\n\tfor labelName := range ls {\n\t\tlabelNames = append(labelNames, labelName)\n\t}\n\tsort.Sort(labelNames)\n\n\tsum := hashNew()\n\tfor _, labelName := range labelNames {\n\t\tsum = hashAdd(sum, string(labelName))\n\t\tsum = hashAddByte(sum, SeparatorByte)\n\t\tsum = hashAdd(sum, string(ls[labelName]))\n\t\tsum = hashAddByte(sum, SeparatorByte)\n\t}\n\treturn Fingerprint(sum)\n}\n\n// labelSetToFastFingerprint works similar to labelSetToFingerprint but uses a\n// faster and less allocation-heavy hash function, which is more susceptible to\n// create hash collisions. Therefore, collision detection should be applied.\nfunc labelSetToFastFingerprint(ls LabelSet) Fingerprint {\n\tif len(ls) == 0 {\n\t\treturn Fingerprint(emptyLabelSignature)\n\t}\n\n\tvar result uint64\n\tfor labelName, labelValue := range ls {\n\t\tsum := hashNew()\n\t\tsum = hashAdd(sum, string(labelName))\n\t\tsum = hashAddByte(sum, SeparatorByte)\n\t\tsum = hashAdd(sum, string(labelValue))\n\t\tresult ^= sum\n\t}\n\treturn Fingerprint(result)\n}\n\n// SignatureForLabels works like LabelsToSignature but takes a Metric as\n// parameter (rather than a label map) and only includes the labels with the\n// specified LabelNames into the signature calculation. The labels passed in\n// will be sorted by this function.\nfunc SignatureForLabels(m Metric, labels ...LabelName) uint64 {\n\tif len(labels) == 0 {\n\t\treturn emptyLabelSignature\n\t}\n\n\tsort.Sort(LabelNames(labels))\n\n\tsum := hashNew()\n\tfor _, label := range labels {\n\t\tsum = hashAdd(sum, string(label))\n\t\tsum = hashAddByte(sum, SeparatorByte)\n\t\tsum = hashAdd(sum, string(m[label]))\n\t\tsum = hashAddByte(sum, SeparatorByte)\n\t}\n\treturn sum\n}\n\n// SignatureWithoutLabels works like LabelsToSignature but takes a Metric as\n// parameter (rather than a label map) and excludes the labels with any of the\n// specified LabelNames from the signature calculation.\nfunc SignatureWithoutLabels(m Metric, labels map[LabelName]struct{}) uint64 {\n\tif len(m) == 0 {\n\t\treturn emptyLabelSignature\n\t}\n\n\tlabelNames := make(LabelNames, 0, len(m))\n\tfor labelName := range m {\n\t\tif _, exclude := labels[labelName]; !exclude {\n\t\t\tlabelNames = append(labelNames, labelName)\n\t\t}\n\t}\n\tif len(labelNames) == 0 {\n\t\treturn emptyLabelSignature\n\t}\n\tsort.Sort(labelNames)\n\n\tsum := hashNew()\n\tfor _, labelName := range labelNames {\n\t\tsum = hashAdd(sum, string(labelName))\n\t\tsum = hashAddByte(sum, SeparatorByte)\n\t\tsum = hashAdd(sum, string(m[labelName]))\n\t\tsum = hashAddByte(sum, SeparatorByte)\n\t}\n\treturn sum\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/model/silence.go",
    "content": "// Copyright 2015 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage model\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"time\"\n)\n\n// Matcher describes a matches the value of a given label.\ntype Matcher struct {\n\tName    LabelName `json:\"name\"`\n\tValue   string    `json:\"value\"`\n\tIsRegex bool      `json:\"isRegex\"`\n}\n\nfunc (m *Matcher) UnmarshalJSON(b []byte) error {\n\ttype plain Matcher\n\tif err := json.Unmarshal(b, (*plain)(m)); err != nil {\n\t\treturn err\n\t}\n\n\tif len(m.Name) == 0 {\n\t\treturn errors.New(\"label name in matcher must not be empty\")\n\t}\n\tif m.IsRegex {\n\t\tif _, err := regexp.Compile(m.Value); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// Validate returns true iff all fields of the matcher have valid values.\nfunc (m *Matcher) Validate() error {\n\tif !m.Name.IsValid() {\n\t\treturn fmt.Errorf(\"invalid name %q\", m.Name)\n\t}\n\tif m.IsRegex {\n\t\tif _, err := regexp.Compile(m.Value); err != nil {\n\t\t\treturn fmt.Errorf(\"invalid regular expression %q\", m.Value)\n\t\t}\n\t} else if !LabelValue(m.Value).IsValid() || len(m.Value) == 0 {\n\t\treturn fmt.Errorf(\"invalid value %q\", m.Value)\n\t}\n\treturn nil\n}\n\n// Silence defines the representation of a silence definition in the Prometheus\n// eco-system.\ntype Silence struct {\n\tID uint64 `json:\"id,omitempty\"`\n\n\tMatchers []*Matcher `json:\"matchers\"`\n\n\tStartsAt time.Time `json:\"startsAt\"`\n\tEndsAt   time.Time `json:\"endsAt\"`\n\n\tCreatedAt time.Time `json:\"createdAt,omitempty\"`\n\tCreatedBy string    `json:\"createdBy\"`\n\tComment   string    `json:\"comment,omitempty\"`\n}\n\n// Validate returns true iff all fields of the silence have valid values.\nfunc (s *Silence) Validate() error {\n\tif len(s.Matchers) == 0 {\n\t\treturn errors.New(\"at least one matcher required\")\n\t}\n\tfor _, m := range s.Matchers {\n\t\tif err := m.Validate(); err != nil {\n\t\t\treturn fmt.Errorf(\"invalid matcher: %w\", err)\n\t\t}\n\t}\n\tif s.StartsAt.IsZero() {\n\t\treturn errors.New(\"start time missing\")\n\t}\n\tif s.EndsAt.IsZero() {\n\t\treturn errors.New(\"end time missing\")\n\t}\n\tif s.EndsAt.Before(s.StartsAt) {\n\t\treturn errors.New(\"start time must be before end time\")\n\t}\n\tif s.CreatedBy == \"\" {\n\t\treturn errors.New(\"creator information missing\")\n\t}\n\tif s.Comment == \"\" {\n\t\treturn errors.New(\"comment missing\")\n\t}\n\tif s.CreatedAt.IsZero() {\n\t\treturn errors.New(\"creation timestamp missing\")\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/model/time.go",
    "content": "// Copyright 2013 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage model\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\nconst (\n\t// MinimumTick is the minimum supported time resolution. This has to be\n\t// at least time.Second in order for the code below to work.\n\tminimumTick = time.Millisecond\n\t// second is the Time duration equivalent to one second.\n\tsecond = int64(time.Second / minimumTick)\n\t// The number of nanoseconds per minimum tick.\n\tnanosPerTick = int64(minimumTick / time.Nanosecond)\n\n\t// Earliest is the earliest Time representable. Handy for\n\t// initializing a high watermark.\n\tEarliest = Time(math.MinInt64)\n\t// Latest is the latest Time representable. Handy for initializing\n\t// a low watermark.\n\tLatest = Time(math.MaxInt64)\n)\n\n// Time is the number of milliseconds since the epoch\n// (1970-01-01 00:00 UTC) excluding leap seconds.\ntype Time int64\n\n// Interval describes an interval between two timestamps.\ntype Interval struct {\n\tStart, End Time\n}\n\n// Now returns the current time as a Time.\nfunc Now() Time {\n\treturn TimeFromUnixNano(time.Now().UnixNano())\n}\n\n// TimeFromUnix returns the Time equivalent to the Unix Time t\n// provided in seconds.\nfunc TimeFromUnix(t int64) Time {\n\treturn Time(t * second)\n}\n\n// TimeFromUnixNano returns the Time equivalent to the Unix Time\n// t provided in nanoseconds.\nfunc TimeFromUnixNano(t int64) Time {\n\treturn Time(t / nanosPerTick)\n}\n\n// Equal reports whether two Times represent the same instant.\nfunc (t Time) Equal(o Time) bool {\n\treturn t == o\n}\n\n// Before reports whether the Time t is before o.\nfunc (t Time) Before(o Time) bool {\n\treturn t < o\n}\n\n// After reports whether the Time t is after o.\nfunc (t Time) After(o Time) bool {\n\treturn t > o\n}\n\n// Add returns the Time t + d.\nfunc (t Time) Add(d time.Duration) Time {\n\treturn t + Time(d/minimumTick)\n}\n\n// Sub returns the Duration t - o.\nfunc (t Time) Sub(o Time) time.Duration {\n\treturn time.Duration(t-o) * minimumTick\n}\n\n// Time returns the time.Time representation of t.\nfunc (t Time) Time() time.Time {\n\treturn time.Unix(int64(t)/second, (int64(t)%second)*nanosPerTick)\n}\n\n// Unix returns t as a Unix time, the number of seconds elapsed\n// since January 1, 1970 UTC.\nfunc (t Time) Unix() int64 {\n\treturn int64(t) / second\n}\n\n// UnixNano returns t as a Unix time, the number of nanoseconds elapsed\n// since January 1, 1970 UTC.\nfunc (t Time) UnixNano() int64 {\n\treturn int64(t) * nanosPerTick\n}\n\n// The number of digits after the dot.\nvar dotPrecision = int(math.Log10(float64(second)))\n\n// String returns a string representation of the Time.\nfunc (t Time) String() string {\n\treturn strconv.FormatFloat(float64(t)/float64(second), 'f', -1, 64)\n}\n\n// MarshalJSON implements the json.Marshaler interface.\nfunc (t Time) MarshalJSON() ([]byte, error) {\n\treturn []byte(t.String()), nil\n}\n\n// UnmarshalJSON implements the json.Unmarshaler interface.\nfunc (t *Time) UnmarshalJSON(b []byte) error {\n\tp := strings.Split(string(b), \".\")\n\tswitch len(p) {\n\tcase 1:\n\t\tv, err := strconv.ParseInt(string(p[0]), 10, 64)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t*t = Time(v * second)\n\n\tcase 2:\n\t\tv, err := strconv.ParseInt(string(p[0]), 10, 64)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tv *= second\n\n\t\tprec := dotPrecision - len(p[1])\n\t\tif prec < 0 {\n\t\t\tp[1] = p[1][:dotPrecision]\n\t\t} else if prec > 0 {\n\t\t\tp[1] = p[1] + strings.Repeat(\"0\", prec)\n\t\t}\n\n\t\tva, err := strconv.ParseInt(p[1], 10, 32)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// If the value was something like -0.1 the negative is lost in the\n\t\t// parsing because of the leading zero, this ensures that we capture it.\n\t\tif len(p[0]) > 0 && p[0][0] == '-' && v+va > 0 {\n\t\t\t*t = Time(v+va) * -1\n\t\t} else {\n\t\t\t*t = Time(v + va)\n\t\t}\n\n\tdefault:\n\t\treturn fmt.Errorf(\"invalid time %q\", string(b))\n\t}\n\treturn nil\n}\n\n// Duration wraps time.Duration. It is used to parse the custom duration format\n// from YAML.\n// This type should not propagate beyond the scope of input/output processing.\ntype Duration time.Duration\n\n// Set implements pflag/flag.Value\nfunc (d *Duration) Set(s string) error {\n\tvar err error\n\t*d, err = ParseDuration(s)\n\treturn err\n}\n\n// Type implements pflag.Value\nfunc (d *Duration) Type() string {\n\treturn \"duration\"\n}\n\nfunc isdigit(c byte) bool { return c >= '0' && c <= '9' }\n\n// Units are required to go in order from biggest to smallest.\n// This guards against confusion from \"1m1d\" being 1 minute + 1 day, not 1 month + 1 day.\nvar unitMap = map[string]struct {\n\tpos  int\n\tmult uint64\n}{\n\t\"ms\": {7, uint64(time.Millisecond)},\n\t\"s\":  {6, uint64(time.Second)},\n\t\"m\":  {5, uint64(time.Minute)},\n\t\"h\":  {4, uint64(time.Hour)},\n\t\"d\":  {3, uint64(24 * time.Hour)},\n\t\"w\":  {2, uint64(7 * 24 * time.Hour)},\n\t\"y\":  {1, uint64(365 * 24 * time.Hour)},\n}\n\n// ParseDuration parses a string into a time.Duration, assuming that a year\n// always has 365d, a week always has 7d, and a day always has 24h.\nfunc ParseDuration(s string) (Duration, error) {\n\tswitch s {\n\tcase \"0\":\n\t\t// Allow 0 without a unit.\n\t\treturn 0, nil\n\tcase \"\":\n\t\treturn 0, errors.New(\"empty duration string\")\n\t}\n\n\torig := s\n\tvar dur uint64\n\tlastUnitPos := 0\n\n\tfor s != \"\" {\n\t\tif !isdigit(s[0]) {\n\t\t\treturn 0, fmt.Errorf(\"not a valid duration string: %q\", orig)\n\t\t}\n\t\t// Consume [0-9]*\n\t\ti := 0\n\t\tfor ; i < len(s) && isdigit(s[i]); i++ {\n\t\t}\n\t\tv, err := strconv.ParseUint(s[:i], 10, 0)\n\t\tif err != nil {\n\t\t\treturn 0, fmt.Errorf(\"not a valid duration string: %q\", orig)\n\t\t}\n\t\ts = s[i:]\n\n\t\t// Consume unit.\n\t\tfor i = 0; i < len(s) && !isdigit(s[i]); i++ {\n\t\t}\n\t\tif i == 0 {\n\t\t\treturn 0, fmt.Errorf(\"not a valid duration string: %q\", orig)\n\t\t}\n\t\tu := s[:i]\n\t\ts = s[i:]\n\t\tunit, ok := unitMap[u]\n\t\tif !ok {\n\t\t\treturn 0, fmt.Errorf(\"unknown unit %q in duration %q\", u, orig)\n\t\t}\n\t\tif unit.pos <= lastUnitPos { // Units must go in order from biggest to smallest.\n\t\t\treturn 0, fmt.Errorf(\"not a valid duration string: %q\", orig)\n\t\t}\n\t\tlastUnitPos = unit.pos\n\t\t// Check if the provided duration overflows time.Duration (> ~ 290years).\n\t\tif v > 1<<63/unit.mult {\n\t\t\treturn 0, errors.New(\"duration out of range\")\n\t\t}\n\t\tdur += v * unit.mult\n\t\tif dur > 1<<63-1 {\n\t\t\treturn 0, errors.New(\"duration out of range\")\n\t\t}\n\t}\n\treturn Duration(dur), nil\n}\n\nfunc (d Duration) String() string {\n\tvar (\n\t\tms = int64(time.Duration(d) / time.Millisecond)\n\t\tr  = \"\"\n\t)\n\tif ms == 0 {\n\t\treturn \"0s\"\n\t}\n\n\tf := func(unit string, mult int64, exact bool) {\n\t\tif exact && ms%mult != 0 {\n\t\t\treturn\n\t\t}\n\t\tif v := ms / mult; v > 0 {\n\t\t\tr += fmt.Sprintf(\"%d%s\", v, unit)\n\t\t\tms -= v * mult\n\t\t}\n\t}\n\n\t// Only format years and weeks if the remainder is zero, as it is often\n\t// easier to read 90d than 12w6d.\n\tf(\"y\", 1000*60*60*24*365, true)\n\tf(\"w\", 1000*60*60*24*7, true)\n\n\tf(\"d\", 1000*60*60*24, false)\n\tf(\"h\", 1000*60*60, false)\n\tf(\"m\", 1000*60, false)\n\tf(\"s\", 1000, false)\n\tf(\"ms\", 1, false)\n\n\treturn r\n}\n\n// MarshalJSON implements the json.Marshaler interface.\nfunc (d Duration) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(d.String())\n}\n\n// UnmarshalJSON implements the json.Unmarshaler interface.\nfunc (d *Duration) UnmarshalJSON(bytes []byte) error {\n\tvar s string\n\tif err := json.Unmarshal(bytes, &s); err != nil {\n\t\treturn err\n\t}\n\tdur, err := ParseDuration(s)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*d = dur\n\treturn nil\n}\n\n// MarshalText implements the encoding.TextMarshaler interface.\nfunc (d *Duration) MarshalText() ([]byte, error) {\n\treturn []byte(d.String()), nil\n}\n\n// UnmarshalText implements the encoding.TextUnmarshaler interface.\nfunc (d *Duration) UnmarshalText(text []byte) error {\n\tvar err error\n\t*d, err = ParseDuration(string(text))\n\treturn err\n}\n\n// MarshalYAML implements the yaml.Marshaler interface.\nfunc (d Duration) MarshalYAML() (interface{}, error) {\n\treturn d.String(), nil\n}\n\n// UnmarshalYAML implements the yaml.Unmarshaler interface.\nfunc (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error {\n\tvar s string\n\tif err := unmarshal(&s); err != nil {\n\t\treturn err\n\t}\n\tdur, err := ParseDuration(s)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*d = dur\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/model/value.go",
    "content": "// Copyright 2013 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage model\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// ZeroSample is the pseudo zero-value of Sample used to signal a\n// non-existing sample. It is a Sample with timestamp Earliest, value 0.0,\n// and metric nil. Note that the natural zero value of Sample has a timestamp\n// of 0, which is possible to appear in a real Sample and thus not suitable\n// to signal a non-existing Sample.\nvar ZeroSample = Sample{Timestamp: Earliest}\n\n// Sample is a sample pair associated with a metric. A single sample must either\n// define Value or Histogram but not both. Histogram == nil implies the Value\n// field is used, otherwise it should be ignored.\ntype Sample struct {\n\tMetric    Metric           `json:\"metric\"`\n\tValue     SampleValue      `json:\"value\"`\n\tTimestamp Time             `json:\"timestamp\"`\n\tHistogram *SampleHistogram `json:\"histogram\"`\n}\n\n// Equal compares first the metrics, then the timestamp, then the value. The\n// semantics of value equality is defined by SampleValue.Equal.\nfunc (s *Sample) Equal(o *Sample) bool {\n\tif s == o {\n\t\treturn true\n\t}\n\n\tif !s.Metric.Equal(o.Metric) {\n\t\treturn false\n\t}\n\tif !s.Timestamp.Equal(o.Timestamp) {\n\t\treturn false\n\t}\n\tif s.Histogram != nil {\n\t\treturn s.Histogram.Equal(o.Histogram)\n\t}\n\treturn s.Value.Equal(o.Value)\n}\n\nfunc (s Sample) String() string {\n\tif s.Histogram != nil {\n\t\treturn fmt.Sprintf(\"%s => %s\", s.Metric, SampleHistogramPair{\n\t\t\tTimestamp: s.Timestamp,\n\t\t\tHistogram: s.Histogram,\n\t\t})\n\t}\n\treturn fmt.Sprintf(\"%s => %s\", s.Metric, SamplePair{\n\t\tTimestamp: s.Timestamp,\n\t\tValue:     s.Value,\n\t})\n}\n\n// MarshalJSON implements json.Marshaler.\nfunc (s Sample) MarshalJSON() ([]byte, error) {\n\tif s.Histogram != nil {\n\t\tv := struct {\n\t\t\tMetric    Metric              `json:\"metric\"`\n\t\t\tHistogram SampleHistogramPair `json:\"histogram\"`\n\t\t}{\n\t\t\tMetric: s.Metric,\n\t\t\tHistogram: SampleHistogramPair{\n\t\t\t\tTimestamp: s.Timestamp,\n\t\t\t\tHistogram: s.Histogram,\n\t\t\t},\n\t\t}\n\t\treturn json.Marshal(&v)\n\t}\n\tv := struct {\n\t\tMetric Metric     `json:\"metric\"`\n\t\tValue  SamplePair `json:\"value\"`\n\t}{\n\t\tMetric: s.Metric,\n\t\tValue: SamplePair{\n\t\t\tTimestamp: s.Timestamp,\n\t\t\tValue:     s.Value,\n\t\t},\n\t}\n\treturn json.Marshal(&v)\n}\n\n// UnmarshalJSON implements json.Unmarshaler.\nfunc (s *Sample) UnmarshalJSON(b []byte) error {\n\tv := struct {\n\t\tMetric    Metric              `json:\"metric\"`\n\t\tValue     SamplePair          `json:\"value\"`\n\t\tHistogram SampleHistogramPair `json:\"histogram\"`\n\t}{\n\t\tMetric: s.Metric,\n\t\tValue: SamplePair{\n\t\t\tTimestamp: s.Timestamp,\n\t\t\tValue:     s.Value,\n\t\t},\n\t\tHistogram: SampleHistogramPair{\n\t\t\tTimestamp: s.Timestamp,\n\t\t\tHistogram: s.Histogram,\n\t\t},\n\t}\n\n\tif err := json.Unmarshal(b, &v); err != nil {\n\t\treturn err\n\t}\n\n\ts.Metric = v.Metric\n\tif v.Histogram.Histogram != nil {\n\t\ts.Timestamp = v.Histogram.Timestamp\n\t\ts.Histogram = v.Histogram.Histogram\n\t} else {\n\t\ts.Timestamp = v.Value.Timestamp\n\t\ts.Value = v.Value.Value\n\t}\n\n\treturn nil\n}\n\n// Samples is a sortable Sample slice. It implements sort.Interface.\ntype Samples []*Sample\n\nfunc (s Samples) Len() int {\n\treturn len(s)\n}\n\n// Less compares first the metrics, then the timestamp.\nfunc (s Samples) Less(i, j int) bool {\n\tswitch {\n\tcase s[i].Metric.Before(s[j].Metric):\n\t\treturn true\n\tcase s[j].Metric.Before(s[i].Metric):\n\t\treturn false\n\tcase s[i].Timestamp.Before(s[j].Timestamp):\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc (s Samples) Swap(i, j int) {\n\ts[i], s[j] = s[j], s[i]\n}\n\n// Equal compares two sets of samples and returns true if they are equal.\nfunc (s Samples) Equal(o Samples) bool {\n\tif len(s) != len(o) {\n\t\treturn false\n\t}\n\n\tfor i, sample := range s {\n\t\tif !sample.Equal(o[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// SampleStream is a stream of Values belonging to an attached COWMetric.\ntype SampleStream struct {\n\tMetric     Metric                `json:\"metric\"`\n\tValues     []SamplePair          `json:\"values\"`\n\tHistograms []SampleHistogramPair `json:\"histograms\"`\n}\n\nfunc (ss SampleStream) String() string {\n\tvaluesLength := len(ss.Values)\n\tvals := make([]string, valuesLength+len(ss.Histograms))\n\tfor i, v := range ss.Values {\n\t\tvals[i] = v.String()\n\t}\n\tfor i, v := range ss.Histograms {\n\t\tvals[i+valuesLength] = v.String()\n\t}\n\treturn fmt.Sprintf(\"%s =>\\n%s\", ss.Metric, strings.Join(vals, \"\\n\"))\n}\n\nfunc (ss SampleStream) MarshalJSON() ([]byte, error) {\n\tif len(ss.Histograms) > 0 && len(ss.Values) > 0 {\n\t\tv := struct {\n\t\t\tMetric     Metric                `json:\"metric\"`\n\t\t\tValues     []SamplePair          `json:\"values\"`\n\t\t\tHistograms []SampleHistogramPair `json:\"histograms\"`\n\t\t}{\n\t\t\tMetric:     ss.Metric,\n\t\t\tValues:     ss.Values,\n\t\t\tHistograms: ss.Histograms,\n\t\t}\n\t\treturn json.Marshal(&v)\n\t} else if len(ss.Histograms) > 0 {\n\t\tv := struct {\n\t\t\tMetric     Metric                `json:\"metric\"`\n\t\t\tHistograms []SampleHistogramPair `json:\"histograms\"`\n\t\t}{\n\t\t\tMetric:     ss.Metric,\n\t\t\tHistograms: ss.Histograms,\n\t\t}\n\t\treturn json.Marshal(&v)\n\t} else {\n\t\tv := struct {\n\t\t\tMetric Metric       `json:\"metric\"`\n\t\t\tValues []SamplePair `json:\"values\"`\n\t\t}{\n\t\t\tMetric: ss.Metric,\n\t\t\tValues: ss.Values,\n\t\t}\n\t\treturn json.Marshal(&v)\n\t}\n}\n\nfunc (ss *SampleStream) UnmarshalJSON(b []byte) error {\n\tv := struct {\n\t\tMetric     Metric                `json:\"metric\"`\n\t\tValues     []SamplePair          `json:\"values\"`\n\t\tHistograms []SampleHistogramPair `json:\"histograms\"`\n\t}{\n\t\tMetric:     ss.Metric,\n\t\tValues:     ss.Values,\n\t\tHistograms: ss.Histograms,\n\t}\n\n\tif err := json.Unmarshal(b, &v); err != nil {\n\t\treturn err\n\t}\n\n\tss.Metric = v.Metric\n\tss.Values = v.Values\n\tss.Histograms = v.Histograms\n\n\treturn nil\n}\n\n// Scalar is a scalar value evaluated at the set timestamp.\ntype Scalar struct {\n\tValue     SampleValue `json:\"value\"`\n\tTimestamp Time        `json:\"timestamp\"`\n}\n\nfunc (s Scalar) String() string {\n\treturn fmt.Sprintf(\"scalar: %v @[%v]\", s.Value, s.Timestamp)\n}\n\n// MarshalJSON implements json.Marshaler.\nfunc (s Scalar) MarshalJSON() ([]byte, error) {\n\tv := strconv.FormatFloat(float64(s.Value), 'f', -1, 64)\n\treturn json.Marshal([...]interface{}{s.Timestamp, string(v)})\n}\n\n// UnmarshalJSON implements json.Unmarshaler.\nfunc (s *Scalar) UnmarshalJSON(b []byte) error {\n\tvar f string\n\tv := [...]interface{}{&s.Timestamp, &f}\n\n\tif err := json.Unmarshal(b, &v); err != nil {\n\t\treturn err\n\t}\n\n\tvalue, err := strconv.ParseFloat(f, 64)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error parsing sample value: %w\", err)\n\t}\n\ts.Value = SampleValue(value)\n\treturn nil\n}\n\n// String is a string value evaluated at the set timestamp.\ntype String struct {\n\tValue     string `json:\"value\"`\n\tTimestamp Time   `json:\"timestamp\"`\n}\n\nfunc (s *String) String() string {\n\treturn s.Value\n}\n\n// MarshalJSON implements json.Marshaler.\nfunc (s String) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal([]interface{}{s.Timestamp, s.Value})\n}\n\n// UnmarshalJSON implements json.Unmarshaler.\nfunc (s *String) UnmarshalJSON(b []byte) error {\n\tv := [...]interface{}{&s.Timestamp, &s.Value}\n\treturn json.Unmarshal(b, &v)\n}\n\n// Vector is basically only an alias for Samples, but the\n// contract is that in a Vector, all Samples have the same timestamp.\ntype Vector []*Sample\n\nfunc (vec Vector) String() string {\n\tentries := make([]string, len(vec))\n\tfor i, s := range vec {\n\t\tentries[i] = s.String()\n\t}\n\treturn strings.Join(entries, \"\\n\")\n}\n\nfunc (vec Vector) Len() int      { return len(vec) }\nfunc (vec Vector) Swap(i, j int) { vec[i], vec[j] = vec[j], vec[i] }\n\n// Less compares first the metrics, then the timestamp.\nfunc (vec Vector) Less(i, j int) bool {\n\tswitch {\n\tcase vec[i].Metric.Before(vec[j].Metric):\n\t\treturn true\n\tcase vec[j].Metric.Before(vec[i].Metric):\n\t\treturn false\n\tcase vec[i].Timestamp.Before(vec[j].Timestamp):\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// Equal compares two sets of samples and returns true if they are equal.\nfunc (vec Vector) Equal(o Vector) bool {\n\tif len(vec) != len(o) {\n\t\treturn false\n\t}\n\n\tfor i, sample := range vec {\n\t\tif !sample.Equal(o[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Matrix is a list of time series.\ntype Matrix []*SampleStream\n\nfunc (m Matrix) Len() int           { return len(m) }\nfunc (m Matrix) Less(i, j int) bool { return m[i].Metric.Before(m[j].Metric) }\nfunc (m Matrix) Swap(i, j int)      { m[i], m[j] = m[j], m[i] }\n\nfunc (mat Matrix) String() string {\n\tmatCp := make(Matrix, len(mat))\n\tcopy(matCp, mat)\n\tsort.Sort(matCp)\n\n\tstrs := make([]string, len(matCp))\n\n\tfor i, ss := range matCp {\n\t\tstrs[i] = ss.String()\n\t}\n\n\treturn strings.Join(strs, \"\\n\")\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/model/value_float.go",
    "content": "// Copyright 2013 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage model\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"strconv\"\n)\n\n// ZeroSamplePair is the pseudo zero-value of SamplePair used to signal a\n// non-existing sample pair. It is a SamplePair with timestamp Earliest and\n// value 0.0. Note that the natural zero value of SamplePair has a timestamp\n// of 0, which is possible to appear in a real SamplePair and thus not\n// suitable to signal a non-existing SamplePair.\nvar ZeroSamplePair = SamplePair{Timestamp: Earliest}\n\n// A SampleValue is a representation of a value for a given sample at a given\n// time.\ntype SampleValue float64\n\n// MarshalJSON implements json.Marshaler.\nfunc (v SampleValue) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.String())\n}\n\n// UnmarshalJSON implements json.Unmarshaler.\nfunc (v *SampleValue) UnmarshalJSON(b []byte) error {\n\tif len(b) < 2 || b[0] != '\"' || b[len(b)-1] != '\"' {\n\t\treturn errors.New(\"sample value must be a quoted string\")\n\t}\n\tf, err := strconv.ParseFloat(string(b[1:len(b)-1]), 64)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*v = SampleValue(f)\n\treturn nil\n}\n\n// Equal returns true if the value of v and o is equal or if both are NaN. Note\n// that v==o is false if both are NaN. If you want the conventional float\n// behavior, use == to compare two SampleValues.\nfunc (v SampleValue) Equal(o SampleValue) bool {\n\tif v == o {\n\t\treturn true\n\t}\n\treturn math.IsNaN(float64(v)) && math.IsNaN(float64(o))\n}\n\nfunc (v SampleValue) String() string {\n\treturn strconv.FormatFloat(float64(v), 'f', -1, 64)\n}\n\n// SamplePair pairs a SampleValue with a Timestamp.\ntype SamplePair struct {\n\tTimestamp Time\n\tValue     SampleValue\n}\n\nfunc (s SamplePair) MarshalJSON() ([]byte, error) {\n\tt, err := json.Marshal(s.Timestamp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tv, err := json.Marshal(s.Value)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn []byte(fmt.Sprintf(\"[%s,%s]\", t, v)), nil\n}\n\n// UnmarshalJSON implements json.Unmarshaler.\nfunc (s *SamplePair) UnmarshalJSON(b []byte) error {\n\tv := [...]json.Unmarshaler{&s.Timestamp, &s.Value}\n\treturn json.Unmarshal(b, &v)\n}\n\n// Equal returns true if this SamplePair and o have equal Values and equal\n// Timestamps. The semantics of Value equality is defined by SampleValue.Equal.\nfunc (s *SamplePair) Equal(o *SamplePair) bool {\n\treturn s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp))\n}\n\nfunc (s SamplePair) String() string {\n\treturn fmt.Sprintf(\"%s @[%s]\", s.Value, s.Timestamp)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/model/value_histogram.go",
    "content": "// Copyright 2013 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage model\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype FloatString float64\n\nfunc (v FloatString) String() string {\n\treturn strconv.FormatFloat(float64(v), 'f', -1, 64)\n}\n\nfunc (v FloatString) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.String())\n}\n\nfunc (v *FloatString) UnmarshalJSON(b []byte) error {\n\tif len(b) < 2 || b[0] != '\"' || b[len(b)-1] != '\"' {\n\t\treturn errors.New(\"float value must be a quoted string\")\n\t}\n\tf, err := strconv.ParseFloat(string(b[1:len(b)-1]), 64)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*v = FloatString(f)\n\treturn nil\n}\n\ntype HistogramBucket struct {\n\tBoundaries int32\n\tLower      FloatString\n\tUpper      FloatString\n\tCount      FloatString\n}\n\nfunc (s HistogramBucket) MarshalJSON() ([]byte, error) {\n\tb, err := json.Marshal(s.Boundaries)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tl, err := json.Marshal(s.Lower)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tu, err := json.Marshal(s.Upper)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tc, err := json.Marshal(s.Count)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn []byte(fmt.Sprintf(\"[%s,%s,%s,%s]\", b, l, u, c)), nil\n}\n\nfunc (s *HistogramBucket) UnmarshalJSON(buf []byte) error {\n\ttmp := []interface{}{&s.Boundaries, &s.Lower, &s.Upper, &s.Count}\n\twantLen := len(tmp)\n\tif err := json.Unmarshal(buf, &tmp); err != nil {\n\t\treturn err\n\t}\n\tif gotLen := len(tmp); gotLen != wantLen {\n\t\treturn fmt.Errorf(\"wrong number of fields: %d != %d\", gotLen, wantLen)\n\t}\n\treturn nil\n}\n\nfunc (s *HistogramBucket) Equal(o *HistogramBucket) bool {\n\treturn s == o || (s.Boundaries == o.Boundaries && s.Lower == o.Lower && s.Upper == o.Upper && s.Count == o.Count)\n}\n\nfunc (b HistogramBucket) String() string {\n\tvar sb strings.Builder\n\tlowerInclusive := b.Boundaries == 1 || b.Boundaries == 3\n\tupperInclusive := b.Boundaries == 0 || b.Boundaries == 3\n\tif lowerInclusive {\n\t\tsb.WriteRune('[')\n\t} else {\n\t\tsb.WriteRune('(')\n\t}\n\tfmt.Fprintf(&sb, \"%g,%g\", b.Lower, b.Upper)\n\tif upperInclusive {\n\t\tsb.WriteRune(']')\n\t} else {\n\t\tsb.WriteRune(')')\n\t}\n\tfmt.Fprintf(&sb, \":%v\", b.Count)\n\treturn sb.String()\n}\n\ntype HistogramBuckets []*HistogramBucket\n\nfunc (s HistogramBuckets) Equal(o HistogramBuckets) bool {\n\tif len(s) != len(o) {\n\t\treturn false\n\t}\n\n\tfor i, bucket := range s {\n\t\tif !bucket.Equal(o[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\ntype SampleHistogram struct {\n\tCount   FloatString      `json:\"count\"`\n\tSum     FloatString      `json:\"sum\"`\n\tBuckets HistogramBuckets `json:\"buckets\"`\n}\n\nfunc (s SampleHistogram) String() string {\n\treturn fmt.Sprintf(\"Count: %f, Sum: %f, Buckets: %v\", s.Count, s.Sum, s.Buckets)\n}\n\nfunc (s *SampleHistogram) Equal(o *SampleHistogram) bool {\n\treturn s == o || (s.Count == o.Count && s.Sum == o.Sum && s.Buckets.Equal(o.Buckets))\n}\n\ntype SampleHistogramPair struct {\n\tTimestamp Time\n\t// Histogram should never be nil, it's only stored as pointer for efficiency.\n\tHistogram *SampleHistogram\n}\n\nfunc (s SampleHistogramPair) MarshalJSON() ([]byte, error) {\n\tif s.Histogram == nil {\n\t\treturn nil, errors.New(\"histogram is nil\")\n\t}\n\tt, err := json.Marshal(s.Timestamp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tv, err := json.Marshal(s.Histogram)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn []byte(fmt.Sprintf(\"[%s,%s]\", t, v)), nil\n}\n\nfunc (s *SampleHistogramPair) UnmarshalJSON(buf []byte) error {\n\ttmp := []interface{}{&s.Timestamp, &s.Histogram}\n\twantLen := len(tmp)\n\tif err := json.Unmarshal(buf, &tmp); err != nil {\n\t\treturn err\n\t}\n\tif gotLen := len(tmp); gotLen != wantLen {\n\t\treturn fmt.Errorf(\"wrong number of fields: %d != %d\", gotLen, wantLen)\n\t}\n\tif s.Histogram == nil {\n\t\treturn errors.New(\"histogram is null\")\n\t}\n\treturn nil\n}\n\nfunc (s SampleHistogramPair) String() string {\n\treturn fmt.Sprintf(\"%s @[%s]\", s.Histogram, s.Timestamp)\n}\n\nfunc (s *SampleHistogramPair) Equal(o *SampleHistogramPair) bool {\n\treturn s == o || (s.Histogram.Equal(o.Histogram) && s.Timestamp.Equal(o.Timestamp))\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/common/model/value_type.go",
    "content": "// Copyright 2013 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage model\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// Value is a generic interface for values resulting from a query evaluation.\ntype Value interface {\n\tType() ValueType\n\tString() string\n}\n\nfunc (Matrix) Type() ValueType  { return ValMatrix }\nfunc (Vector) Type() ValueType  { return ValVector }\nfunc (*Scalar) Type() ValueType { return ValScalar }\nfunc (*String) Type() ValueType { return ValString }\n\ntype ValueType int\n\nconst (\n\tValNone ValueType = iota\n\tValScalar\n\tValVector\n\tValMatrix\n\tValString\n)\n\n// MarshalJSON implements json.Marshaler.\nfunc (et ValueType) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(et.String())\n}\n\nfunc (et *ValueType) UnmarshalJSON(b []byte) error {\n\tvar s string\n\tif err := json.Unmarshal(b, &s); err != nil {\n\t\treturn err\n\t}\n\tswitch s {\n\tcase \"<ValNone>\":\n\t\t*et = ValNone\n\tcase \"scalar\":\n\t\t*et = ValScalar\n\tcase \"vector\":\n\t\t*et = ValVector\n\tcase \"matrix\":\n\t\t*et = ValMatrix\n\tcase \"string\":\n\t\t*et = ValString\n\tdefault:\n\t\treturn fmt.Errorf(\"unknown value type %q\", s)\n\t}\n\treturn nil\n}\n\nfunc (e ValueType) String() string {\n\tswitch e {\n\tcase ValNone:\n\t\treturn \"<ValNone>\"\n\tcase ValScalar:\n\t\treturn \"scalar\"\n\tcase ValVector:\n\t\treturn \"vector\"\n\tcase ValMatrix:\n\t\treturn \"matrix\"\n\tcase ValString:\n\t\treturn \"string\"\n\t}\n\tpanic(\"ValueType.String: unhandled value type\")\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/.gitignore",
    "content": "/testdata/fixtures/\n/fixtures\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/.golangci.yml",
    "content": "---\nlinters:\n  enable:\n  - errcheck\n  - godot\n  - gosimple\n  - govet\n  - ineffassign\n  - misspell\n  - revive\n  - staticcheck\n  - testifylint\n  - unused\n\nlinter-settings:\n  godot:\n    capital: true\n    exclude:\n    # Ignore \"See: URL\"\n    - 'See:'\n  misspell:\n    locale: US\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/CODE_OF_CONDUCT.md",
    "content": "# Prometheus Community Code of Conduct\n\nPrometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md).\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/CONTRIBUTING.md",
    "content": "# Contributing\n\nPrometheus uses GitHub to manage reviews of pull requests.\n\n* If you are a new contributor see: [Steps to Contribute](#steps-to-contribute)\n\n* If you have a trivial fix or improvement, go ahead and create a pull request,\n  addressing (with `@...`) a suitable maintainer of this repository (see\n  [MAINTAINERS.md](MAINTAINERS.md)) in the description of the pull request.\n\n* If you plan to do something more involved, first discuss your ideas\n  on our [mailing list](https://groups.google.com/forum/?fromgroups#!forum/prometheus-developers).\n  This will avoid unnecessary work and surely give you and us a good deal\n  of inspiration. Also please see our [non-goals issue](https://github.com/prometheus/docs/issues/149) on areas that the Prometheus community doesn't plan to work on.\n\n* Relevant coding style guidelines are the [Go Code Review\n  Comments](https://code.google.com/p/go-wiki/wiki/CodeReviewComments)\n  and the _Formatting and style_ section of Peter Bourgon's [Go: Best\n  Practices for Production\n  Environments](https://peter.bourgon.org/go-in-production/#formatting-and-style).\n\n* Be sure to sign off on the [DCO](https://github.com/probot/dco#how-it-works)\n\n## Steps to Contribute\n\nShould you wish to work on an issue, please claim it first by commenting on the GitHub issue that you want to work on it. This is to prevent duplicated efforts from contributors on the same issue.\n\nPlease check the [`help-wanted`](https://github.com/prometheus/procfs/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) label to find issues that are good for getting started. If you have questions about one of the issues, with or without the tag, please comment on them and one of the maintainers will clarify it. For a quicker response, contact us over [IRC](https://prometheus.io/community).\n\nFor quickly compiling and testing your changes do:\n```\nmake test         # Make sure all the tests pass before you commit and push :)\n```\n\nWe use [`golangci-lint`](https://github.com/golangci/golangci-lint) for linting the code. If it reports an issue and you think that the warning needs to be disregarded or is a false-positive, you can add a special comment `//nolint:linter1[,linter2,...]` before the offending line. Use this sparingly though, fixing the code to comply with the linter's recommendation is in general the preferred course of action.\n\n## Pull Request Checklist\n\n* Branch from the master branch and, if needed, rebase to the current master branch before submitting your pull request. If it doesn't merge cleanly with master you may be asked to rebase your changes.\n\n* Commits should be as small as possible, while ensuring that each commit is correct independently (i.e., each commit should compile and pass tests).\n\n* If your patch is not getting reviewed or you need a specific person to review it, you can @-reply a reviewer asking for a review in the pull request or a comment, or you can ask for a review on IRC channel [#prometheus](https://webchat.freenode.net/?channels=#prometheus) on irc.freenode.net (for the easiest start, [join via Riot](https://riot.im/app/#/room/#prometheus:matrix.org)).\n\n* Add tests relevant to the fixed bug or new feature.\n\n## Dependency management\n\nThe Prometheus project uses [Go modules](https://golang.org/cmd/go/#hdr-Modules__module_versions__and_more) to manage dependencies on external packages. This requires a working Go environment with version 1.12 or greater installed.\n\nAll dependencies are vendored in the `vendor/` directory.\n\nTo add or update a new dependency, use the `go get` command:\n\n```bash\n# Pick the latest tagged release.\ngo get example.com/some/module/pkg\n\n# Pick a specific version.\ngo get example.com/some/module/pkg@vX.Y.Z\n```\n\nTidy up the `go.mod` and `go.sum` files and copy the new/updated dependency to the `vendor/` directory:\n\n\n```bash\n# The GO111MODULE variable can be omitted when the code isn't located in GOPATH.\nGO111MODULE=on go mod tidy\n\nGO111MODULE=on go mod vendor\n```\n\nYou have to commit the changes to `go.mod`, `go.sum` and the `vendor/` directory before submitting the pull request.\n\n\n## API Implementation Guidelines\n\n### Naming and Documentation\n\nPublic functions and structs should normally be named according to the file(s) being read and parsed.  For example, \nthe `fs.BuddyInfo()` function reads the file `/proc/buddyinfo`.  In addition, the godoc for each public function\nshould contain the path to the file(s) being read and a URL of the linux kernel documentation describing the file(s).\n\n### Reading vs. Parsing\n\nMost functionality in this library consists of reading files and then parsing the text into structured data.  In most\ncases reading and parsing should be separated into different functions/methods with a public `fs.Thing()` method and \na private `parseThing(r Reader)` function.  This provides a logical separation and allows parsing to be tested\ndirectly without the need to read from the filesystem.  Using a `Reader` argument is preferred over other data types\nsuch as `string` or `*File` because it provides the most flexibility regarding the data source.  When a set of files \nin a directory needs to be parsed, then a `path` string parameter to the parse function can be used instead.\n\n### /proc and /sys filesystem I/O \n\nThe `proc` and `sys` filesystems are pseudo file systems and work a bit differently from standard disk I/O.  \nMany of the files are changing continuously and the data being read can in some cases change between subsequent \nreads in the same file.  Also, most of the files are relatively small (less than a few KBs), and system calls\nto the `stat` function will often return the wrong size.  Therefore, for most files it's recommended to read the \nfull file in a single operation using an internal utility function called `util.ReadFileNoStat`.\nThis function is similar to `os.ReadFile`, but it avoids the system call to `stat` to get the current size of\nthe file.\n\nNote that parsing the file's contents can still be performed one line at a time.  This is done by first reading \nthe full file, and then using a scanner on the `[]byte` or `string` containing the data.\n\n```\n    data, err := util.ReadFileNoStat(\"/proc/cpuinfo\")\n    if err != nil {\n        return err\n    }\n    reader := bytes.NewReader(data)\n    scanner := bufio.NewScanner(reader)\n```\n\nThe `/sys` filesystem contains many very small files which contain only a single numeric or text value.  These files\ncan be read using an internal function called `util.SysReadFile` which is similar to `os.ReadFile` but does\nnot bother to check the size of the file before reading.\n```\n    data, err := util.SysReadFile(\"/sys/class/power_supply/BAT0/capacity\")\n```\n\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/MAINTAINERS.md",
    "content": "* Johannes 'fish' Ziemke <github@freigeist.org> @discordianfish\n* Paul Gier <paulgier@gmail.com> @pgier\n* Ben Kochie <superq@gmail.com> @SuperQ\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/Makefile",
    "content": "# Copyright 2018 The Prometheus Authors\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\ninclude Makefile.common\n\n%/.unpacked: %.ttar\n\t@echo \">> extracting fixtures $*\"\n\t./ttar -C $(dir $*) -x -f $*.ttar\n\ttouch $@\n\nfixtures: testdata/fixtures/.unpacked\n\nupdate_fixtures:\n\trm -vf testdata/fixtures/.unpacked\n\t./ttar -c -f testdata/fixtures.ttar -C testdata/ fixtures/\n\n.PHONY: build\nbuild:\n\n.PHONY: test\ntest: testdata/fixtures/.unpacked common-test\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/Makefile.common",
    "content": "# Copyright 2018 The Prometheus Authors\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\n# A common Makefile that includes rules to be reused in different prometheus projects.\n# !!! Open PRs only against the prometheus/prometheus/Makefile.common repository!\n\n# Example usage :\n# Create the main Makefile in the root project directory.\n# include Makefile.common\n# customTarget:\n# \t@echo \">> Running customTarget\"\n#\n\n# Ensure GOBIN is not set during build so that promu is installed to the correct path\nunexport GOBIN\n\nGO           ?= go\nGOFMT        ?= $(GO)fmt\nFIRST_GOPATH := $(firstword $(subst :, ,$(shell $(GO) env GOPATH)))\nGOOPTS       ?=\nGOHOSTOS     ?= $(shell $(GO) env GOHOSTOS)\nGOHOSTARCH   ?= $(shell $(GO) env GOHOSTARCH)\n\nGO_VERSION        ?= $(shell $(GO) version)\nGO_VERSION_NUMBER ?= $(word 3, $(GO_VERSION))\nPRE_GO_111        ?= $(shell echo $(GO_VERSION_NUMBER) | grep -E 'go1\\.(10|[0-9])\\.')\n\nPROMU        := $(FIRST_GOPATH)/bin/promu\npkgs          = ./...\n\nifeq (arm, $(GOHOSTARCH))\n\tGOHOSTARM ?= $(shell GOARM= $(GO) env GOARM)\n\tGO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH)v$(GOHOSTARM)\nelse\n\tGO_BUILD_PLATFORM ?= $(GOHOSTOS)-$(GOHOSTARCH)\nendif\n\nGOTEST := $(GO) test\nGOTEST_DIR :=\nifneq ($(CIRCLE_JOB),)\nifneq ($(shell command -v gotestsum 2> /dev/null),)\n\tGOTEST_DIR := test-results\n\tGOTEST := gotestsum --junitfile $(GOTEST_DIR)/unit-tests.xml --\nendif\nendif\n\nPROMU_VERSION ?= 0.17.0\nPROMU_URL     := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz\n\nSKIP_GOLANGCI_LINT :=\nGOLANGCI_LINT :=\nGOLANGCI_LINT_OPTS ?=\nGOLANGCI_LINT_VERSION ?= v1.59.0\n# golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64.\n# windows isn't included here because of the path separator being different.\nifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin))\n\tifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386 arm64))\n\t\t# If we're in CI and there is an Actions file, that means the linter\n\t\t# is being run in Actions, so we don't need to run it here.\n\t\tifneq (,$(SKIP_GOLANGCI_LINT))\n\t\t\tGOLANGCI_LINT :=\n\t\telse ifeq (,$(CIRCLE_JOB))\n\t\t\tGOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint\n\t\telse ifeq (,$(wildcard .github/workflows/golangci-lint.yml))\n\t\t\tGOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint\n\t\tendif\n\tendif\nendif\n\nPREFIX                  ?= $(shell pwd)\nBIN_DIR                 ?= $(shell pwd)\nDOCKER_IMAGE_TAG        ?= $(subst /,-,$(shell git rev-parse --abbrev-ref HEAD))\nDOCKERFILE_PATH         ?= ./Dockerfile\nDOCKERBUILD_CONTEXT     ?= ./\nDOCKER_REPO             ?= prom\n\nDOCKER_ARCHS            ?= amd64\n\nBUILD_DOCKER_ARCHS = $(addprefix common-docker-,$(DOCKER_ARCHS))\nPUBLISH_DOCKER_ARCHS = $(addprefix common-docker-publish-,$(DOCKER_ARCHS))\nTAG_DOCKER_ARCHS = $(addprefix common-docker-tag-latest-,$(DOCKER_ARCHS))\n\nSANITIZED_DOCKER_IMAGE_TAG := $(subst +,-,$(DOCKER_IMAGE_TAG))\n\nifeq ($(GOHOSTARCH),amd64)\n        ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux freebsd darwin windows))\n                # Only supported on amd64\n                test-flags := -race\n        endif\nendif\n\n# This rule is used to forward a target like \"build\" to \"common-build\".  This\n# allows a new \"build\" target to be defined in a Makefile which includes this\n# one and override \"common-build\" without override warnings.\n%: common-% ;\n\n.PHONY: common-all\ncommon-all: precheck style check_license lint yamllint unused build test\n\n.PHONY: common-style\ncommon-style:\n\t@echo \">> checking code style\"\n\t@fmtRes=$$($(GOFMT) -d $$(find . -path ./vendor -prune -o -name '*.go' -print)); \\\n\tif [ -n \"$${fmtRes}\" ]; then \\\n\t\techo \"gofmt checking failed!\"; echo \"$${fmtRes}\"; echo; \\\n\t\techo \"Please ensure you are using $$($(GO) version) for formatting code.\"; \\\n\t\texit 1; \\\n\tfi\n\n.PHONY: common-check_license\ncommon-check_license:\n\t@echo \">> checking license header\"\n\t@licRes=$$(for file in $$(find . -type f -iname '*.go' ! -path './vendor/*') ; do \\\n               awk 'NR<=3' $$file | grep -Eq \"(Copyright|generated|GENERATED)\" || echo $$file; \\\n       done); \\\n       if [ -n \"$${licRes}\" ]; then \\\n               echo \"license header checking failed:\"; echo \"$${licRes}\"; \\\n               exit 1; \\\n       fi\n\n.PHONY: common-deps\ncommon-deps:\n\t@echo \">> getting dependencies\"\n\t$(GO) mod download\n\n.PHONY: update-go-deps\nupdate-go-deps:\n\t@echo \">> updating Go dependencies\"\n\t@for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \\\n\t\t$(GO) get -d $$m; \\\n\tdone\n\t$(GO) mod tidy\n\n.PHONY: common-test-short\ncommon-test-short: $(GOTEST_DIR)\n\t@echo \">> running short tests\"\n\t$(GOTEST) -short $(GOOPTS) $(pkgs)\n\n.PHONY: common-test\ncommon-test: $(GOTEST_DIR)\n\t@echo \">> running all tests\"\n\t$(GOTEST) $(test-flags) $(GOOPTS) $(pkgs)\n\n$(GOTEST_DIR):\n\t@mkdir -p $@\n\n.PHONY: common-format\ncommon-format:\n\t@echo \">> formatting code\"\n\t$(GO) fmt $(pkgs)\n\n.PHONY: common-vet\ncommon-vet:\n\t@echo \">> vetting code\"\n\t$(GO) vet $(GOOPTS) $(pkgs)\n\n.PHONY: common-lint\ncommon-lint: $(GOLANGCI_LINT)\nifdef GOLANGCI_LINT\n\t@echo \">> running golangci-lint\"\n\t$(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs)\nendif\n\n.PHONY: common-lint-fix\ncommon-lint-fix: $(GOLANGCI_LINT)\nifdef GOLANGCI_LINT\n\t@echo \">> running golangci-lint fix\"\n\t$(GOLANGCI_LINT) run --fix $(GOLANGCI_LINT_OPTS) $(pkgs)\nendif\n\n.PHONY: common-yamllint\ncommon-yamllint:\n\t@echo \">> running yamllint on all YAML files in the repository\"\nifeq (, $(shell command -v yamllint 2> /dev/null))\n\t@echo \"yamllint not installed so skipping\"\nelse\n\tyamllint .\nendif\n\n# For backward-compatibility.\n.PHONY: common-staticcheck\ncommon-staticcheck: lint\n\n.PHONY: common-unused\ncommon-unused:\n\t@echo \">> running check for unused/missing packages in go.mod\"\n\t$(GO) mod tidy\n\t@git diff --exit-code -- go.sum go.mod\n\n.PHONY: common-build\ncommon-build: promu\n\t@echo \">> building binaries\"\n\t$(PROMU) build --prefix $(PREFIX) $(PROMU_BINARIES)\n\n.PHONY: common-tarball\ncommon-tarball: promu\n\t@echo \">> building release tarball\"\n\t$(PROMU) tarball --prefix $(PREFIX) $(BIN_DIR)\n\n.PHONY: common-docker-repo-name\ncommon-docker-repo-name:\n\t@echo \"$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)\"\n\n.PHONY: common-docker $(BUILD_DOCKER_ARCHS)\ncommon-docker: $(BUILD_DOCKER_ARCHS)\n$(BUILD_DOCKER_ARCHS): common-docker-%:\n\tdocker build -t \"$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)\" \\\n\t\t-f $(DOCKERFILE_PATH) \\\n\t\t--build-arg ARCH=\"$*\" \\\n\t\t--build-arg OS=\"linux\" \\\n\t\t$(DOCKERBUILD_CONTEXT)\n\n.PHONY: common-docker-publish $(PUBLISH_DOCKER_ARCHS)\ncommon-docker-publish: $(PUBLISH_DOCKER_ARCHS)\n$(PUBLISH_DOCKER_ARCHS): common-docker-publish-%:\n\tdocker push \"$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)\"\n\nDOCKER_MAJOR_VERSION_TAG = $(firstword $(subst ., ,$(shell cat VERSION)))\n.PHONY: common-docker-tag-latest $(TAG_DOCKER_ARCHS)\ncommon-docker-tag-latest: $(TAG_DOCKER_ARCHS)\n$(TAG_DOCKER_ARCHS): common-docker-tag-latest-%:\n\tdocker tag \"$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)\" \"$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:latest\"\n\tdocker tag \"$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:$(SANITIZED_DOCKER_IMAGE_TAG)\" \"$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$*:v$(DOCKER_MAJOR_VERSION_TAG)\"\n\n.PHONY: common-docker-manifest\ncommon-docker-manifest:\n\tDOCKER_CLI_EXPERIMENTAL=enabled docker manifest create -a \"$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)\" $(foreach ARCH,$(DOCKER_ARCHS),$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME)-linux-$(ARCH):$(SANITIZED_DOCKER_IMAGE_TAG))\n\tDOCKER_CLI_EXPERIMENTAL=enabled docker manifest push \"$(DOCKER_REPO)/$(DOCKER_IMAGE_NAME):$(SANITIZED_DOCKER_IMAGE_TAG)\"\n\n.PHONY: promu\npromu: $(PROMU)\n\n$(PROMU):\n\t$(eval PROMU_TMP := $(shell mktemp -d))\n\tcurl -s -L $(PROMU_URL) | tar -xvzf - -C $(PROMU_TMP)\n\tmkdir -p $(FIRST_GOPATH)/bin\n\tcp $(PROMU_TMP)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM)/promu $(FIRST_GOPATH)/bin/promu\n\trm -r $(PROMU_TMP)\n\n.PHONY: proto\nproto:\n\t@echo \">> generating code from proto files\"\n\t@./scripts/genproto.sh\n\nifdef GOLANGCI_LINT\n$(GOLANGCI_LINT):\n\tmkdir -p $(FIRST_GOPATH)/bin\n\tcurl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/$(GOLANGCI_LINT_VERSION)/install.sh \\\n\t\t| sed -e '/install -d/d' \\\n\t\t| sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION)\nendif\n\n.PHONY: precheck\nprecheck::\n\ndefine PRECHECK_COMMAND_template =\nprecheck:: $(1)_precheck\n\nPRECHECK_COMMAND_$(1) ?= $(1) $$(strip $$(PRECHECK_OPTIONS_$(1)))\n.PHONY: $(1)_precheck\n$(1)_precheck:\n\t@if ! $$(PRECHECK_COMMAND_$(1)) 1>/dev/null 2>&1; then \\\n\t\techo \"Execution of '$$(PRECHECK_COMMAND_$(1))' command failed. Is $(1) installed?\"; \\\n\t\texit 1; \\\n\tfi\nendef\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/NOTICE",
    "content": "procfs provides functions to retrieve system, kernel and process\nmetrics from the pseudo-filesystem proc.\n\nCopyright 2014-2015 The Prometheus Authors\n\nThis product includes software developed at\nSoundCloud Ltd. (http://soundcloud.com/).\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/README.md",
    "content": "# procfs\n\nThis package provides functions to retrieve system, kernel, and process\nmetrics from the pseudo-filesystems /proc and /sys.\n\n*WARNING*: This package is a work in progress. Its API may still break in\nbackwards-incompatible ways without warnings. Use it at your own risk.\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/prometheus/procfs.svg)](https://pkg.go.dev/github.com/prometheus/procfs)\n[![CircleCI](https://circleci.com/gh/prometheus/procfs/tree/master.svg?style=svg)](https://circleci.com/gh/prometheus/procfs/tree/master)\n[![Go Report Card](https://goreportcard.com/badge/github.com/prometheus/procfs)](https://goreportcard.com/report/github.com/prometheus/procfs)\n\n## Usage\n\nThe procfs library is organized by packages based on whether the gathered data is coming from\n/proc, /sys, or both.  Each package contains an `FS` type which represents the path to either /proc, \n/sys, or both.  For example, cpu statistics are gathered from\n`/proc/stat` and are available via the root procfs package.  First, the proc filesystem mount\npoint is initialized, and then the stat information is read.\n\n```go\nfs, err := procfs.NewFS(\"/proc\")\nstats, err := fs.Stat()\n```\n\nSome sub-packages such as `blockdevice`, require access to both the proc and sys filesystems.\n\n```go\n    fs, err := blockdevice.NewFS(\"/proc\", \"/sys\")\n    stats, err := fs.ProcDiskstats()\n```\n\n## Package Organization\n\nThe packages in this project are organized according to (1) whether the data comes from the `/proc` or\n`/sys` filesystem and (2) the type of information being retrieved.  For example, most process information\ncan be gathered from the functions in the root `procfs` package.  Information about block devices such as disk drives\nis available in the `blockdevices` sub-package.\n\n## Building and Testing\n\nThe procfs library is intended to be built as part of another application, so there are no distributable binaries.  \nHowever, most of the API includes unit tests which can be run with `make test`.\n\n### Updating Test Fixtures\n\nThe procfs library includes a set of test fixtures which include many example files from\nthe `/proc` and `/sys` filesystems.  These fixtures are included as a [ttar](https://github.com/ideaship/ttar) file\nwhich is extracted automatically during testing.  To add/update the test fixtures, first\nensure the `fixtures` directory is up to date by removing the existing directory and then\nextracting the ttar file using `make fixtures/.unpacked` or just `make test`.\n\n```bash\nrm -rf testdata/fixtures\nmake test\n```\n\nNext, make the required changes to the extracted files in the `fixtures` directory.  When\nthe changes are complete, run `make update_fixtures` to create a new `fixtures.ttar` file\nbased on the updated `fixtures` directory.  And finally, verify the changes using\n`git diff testdata/fixtures.ttar`.\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/SECURITY.md",
    "content": "# Reporting a security issue\n\nThe Prometheus security policy, including how to report vulnerabilities, can be\nfound here:\n\n<https://prometheus.io/docs/operating/security/>\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/arp.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Learned from include/uapi/linux/if_arp.h.\nconst (\n\t// completed entry (ha valid).\n\tATFComplete = 0x02\n\t// permanent entry.\n\tATFPermanent = 0x04\n\t// Publish entry.\n\tATFPublish = 0x08\n\t// Has requested trailers.\n\tATFUseTrailers = 0x10\n\t// Obsoleted: Want to use a netmask (only for proxy entries).\n\tATFNetmask = 0x20\n\t// Don't answer this addresses.\n\tATFDontPublish = 0x40\n)\n\n// ARPEntry contains a single row of the columnar data represented in\n// /proc/net/arp.\ntype ARPEntry struct {\n\t// IP address\n\tIPAddr net.IP\n\t// MAC address\n\tHWAddr net.HardwareAddr\n\t// Name of the device\n\tDevice string\n\t// Flags\n\tFlags byte\n}\n\n// GatherARPEntries retrieves all the ARP entries, parse the relevant columns,\n// and then return a slice of ARPEntry's.\nfunc (fs FS) GatherARPEntries() ([]ARPEntry, error) {\n\tdata, err := os.ReadFile(fs.proc.Path(\"net/arp\"))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: error reading arp %s: %w\", ErrFileRead, fs.proc.Path(\"net/arp\"), err)\n\t}\n\n\treturn parseARPEntries(data)\n}\n\nfunc parseARPEntries(data []byte) ([]ARPEntry, error) {\n\tlines := strings.Split(string(data), \"\\n\")\n\tentries := make([]ARPEntry, 0)\n\tvar err error\n\tconst (\n\t\texpectedDataWidth   = 6\n\t\texpectedHeaderWidth = 9\n\t)\n\tfor _, line := range lines {\n\t\tcolumns := strings.Fields(line)\n\t\twidth := len(columns)\n\n\t\tif width == expectedHeaderWidth || width == 0 {\n\t\t\tcontinue\n\t\t} else if width == expectedDataWidth {\n\t\t\tentry, err := parseARPEntry(columns)\n\t\t\tif err != nil {\n\t\t\t\treturn []ARPEntry{}, fmt.Errorf(\"%w: Failed to parse ARP entry: %v: %w\", ErrFileParse, entry, err)\n\t\t\t}\n\t\t\tentries = append(entries, entry)\n\t\t} else {\n\t\t\treturn []ARPEntry{}, fmt.Errorf(\"%w: %d columns found, but expected %d: %w\", ErrFileParse, width, expectedDataWidth, err)\n\t\t}\n\n\t}\n\n\treturn entries, err\n}\n\nfunc parseARPEntry(columns []string) (ARPEntry, error) {\n\tentry := ARPEntry{Device: columns[5]}\n\tip := net.ParseIP(columns[0])\n\tentry.IPAddr = ip\n\n\tif mac, err := net.ParseMAC(columns[3]); err == nil {\n\t\tentry.HWAddr = mac\n\t} else {\n\t\treturn ARPEntry{}, err\n\t}\n\n\tif flags, err := strconv.ParseUint(columns[2], 0, 8); err == nil {\n\t\tentry.Flags = byte(flags)\n\t} else {\n\t\treturn ARPEntry{}, err\n\t}\n\n\treturn entry, nil\n}\n\n// IsComplete returns true if ARP entry is marked with complete flag.\nfunc (entry *ARPEntry) IsComplete() bool {\n\treturn entry.Flags&ATFComplete != 0\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/buddyinfo.go",
    "content": "// Copyright 2017 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// A BuddyInfo is the details parsed from /proc/buddyinfo.\n// The data is comprised of an array of free fragments of each size.\n// The sizes are 2^n*PAGE_SIZE, where n is the array index.\ntype BuddyInfo struct {\n\tNode  string\n\tZone  string\n\tSizes []float64\n}\n\n// BuddyInfo reads the buddyinfo statistics from the specified `proc` filesystem.\nfunc (fs FS) BuddyInfo() ([]BuddyInfo, error) {\n\tfile, err := os.Open(fs.proc.Path(\"buddyinfo\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer file.Close()\n\n\treturn parseBuddyInfo(file)\n}\n\nfunc parseBuddyInfo(r io.Reader) ([]BuddyInfo, error) {\n\tvar (\n\t\tbuddyInfo   = []BuddyInfo{}\n\t\tscanner     = bufio.NewScanner(r)\n\t\tbucketCount = -1\n\t)\n\n\tfor scanner.Scan() {\n\t\tvar err error\n\t\tline := scanner.Text()\n\t\tparts := strings.Fields(line)\n\n\t\tif len(parts) < 4 {\n\t\t\treturn nil, fmt.Errorf(\"%w: Invalid number of fields, found: %v\", ErrFileParse, parts)\n\t\t}\n\n\t\tnode := strings.TrimSuffix(parts[1], \",\")\n\t\tzone := strings.TrimSuffix(parts[3], \",\")\n\t\tarraySize := len(parts[4:])\n\n\t\tif bucketCount == -1 {\n\t\t\tbucketCount = arraySize\n\t\t} else {\n\t\t\tif bucketCount != arraySize {\n\t\t\t\treturn nil, fmt.Errorf(\"%w: mismatch in number of buddyinfo buckets, previous count %d, new count %d\", ErrFileParse, bucketCount, arraySize)\n\t\t\t}\n\t\t}\n\n\t\tsizes := make([]float64, arraySize)\n\t\tfor i := 0; i < arraySize; i++ {\n\t\t\tsizes[i], err = strconv.ParseFloat(parts[i+4], 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"%w: Invalid valid in buddyinfo: %f: %w\", ErrFileParse, sizes[i], err)\n\t\t\t}\n\t\t}\n\n\t\tbuddyInfo = append(buddyInfo, BuddyInfo{node, zone, sizes})\n\t}\n\n\treturn buddyInfo, scanner.Err()\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/cmdline.go",
    "content": "// Copyright 2021 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// CmdLine returns the command line of the kernel.\nfunc (fs FS) CmdLine() ([]string, error) {\n\tdata, err := util.ReadFileNoStat(fs.proc.Path(\"cmdline\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn strings.Fields(string(data)), nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/cpuinfo.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n// +build linux\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// CPUInfo contains general information about a system CPU found in /proc/cpuinfo.\ntype CPUInfo struct {\n\tProcessor       uint\n\tVendorID        string\n\tCPUFamily       string\n\tModel           string\n\tModelName       string\n\tStepping        string\n\tMicrocode       string\n\tCPUMHz          float64\n\tCacheSize       string\n\tPhysicalID      string\n\tSiblings        uint\n\tCoreID          string\n\tCPUCores        uint\n\tAPICID          string\n\tInitialAPICID   string\n\tFPU             string\n\tFPUException    string\n\tCPUIDLevel      uint\n\tWP              string\n\tFlags           []string\n\tBugs            []string\n\tBogoMips        float64\n\tCLFlushSize     uint\n\tCacheAlignment  uint\n\tAddressSizes    string\n\tPowerManagement string\n}\n\nvar (\n\tcpuinfoClockRegexp          = regexp.MustCompile(`([\\d.]+)`)\n\tcpuinfoS390XProcessorRegexp = regexp.MustCompile(`^processor\\s+(\\d+):.*`)\n)\n\n// CPUInfo returns information about current system CPUs.\n// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt\nfunc (fs FS) CPUInfo() ([]CPUInfo, error) {\n\tdata, err := util.ReadFileNoStat(fs.proc.Path(\"cpuinfo\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn parseCPUInfo(data)\n}\n\nfunc parseCPUInfoX86(info []byte) ([]CPUInfo, error) {\n\tscanner := bufio.NewScanner(bytes.NewReader(info))\n\n\t// find the first \"processor\" line\n\tfirstLine := firstNonEmptyLine(scanner)\n\tif !strings.HasPrefix(firstLine, \"processor\") || !strings.Contains(firstLine, \":\") {\n\t\treturn nil, fmt.Errorf(\"%w: Cannot parse  line: %q\", ErrFileParse, firstLine)\n\t}\n\tfield := strings.SplitN(firstLine, \": \", 2)\n\tv, err := strconv.ParseUint(field[1], 0, 32)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfirstcpu := CPUInfo{Processor: uint(v)}\n\tcpuinfo := []CPUInfo{firstcpu}\n\ti := 0\n\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif !strings.Contains(line, \":\") {\n\t\t\tcontinue\n\t\t}\n\t\tfield := strings.SplitN(line, \": \", 2)\n\t\tswitch strings.TrimSpace(field[0]) {\n\t\tcase \"processor\":\n\t\t\tcpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor\n\t\t\ti++\n\t\t\tv, err := strconv.ParseUint(field[1], 0, 32)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcpuinfo[i].Processor = uint(v)\n\t\tcase \"vendor\", \"vendor_id\":\n\t\t\tcpuinfo[i].VendorID = field[1]\n\t\tcase \"cpu family\":\n\t\t\tcpuinfo[i].CPUFamily = field[1]\n\t\tcase \"model\":\n\t\t\tcpuinfo[i].Model = field[1]\n\t\tcase \"model name\":\n\t\t\tcpuinfo[i].ModelName = field[1]\n\t\tcase \"stepping\":\n\t\t\tcpuinfo[i].Stepping = field[1]\n\t\tcase \"microcode\":\n\t\t\tcpuinfo[i].Microcode = field[1]\n\t\tcase \"cpu MHz\":\n\t\t\tv, err := strconv.ParseFloat(field[1], 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcpuinfo[i].CPUMHz = v\n\t\tcase \"cache size\":\n\t\t\tcpuinfo[i].CacheSize = field[1]\n\t\tcase \"physical id\":\n\t\t\tcpuinfo[i].PhysicalID = field[1]\n\t\tcase \"siblings\":\n\t\t\tv, err := strconv.ParseUint(field[1], 0, 32)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcpuinfo[i].Siblings = uint(v)\n\t\tcase \"core id\":\n\t\t\tcpuinfo[i].CoreID = field[1]\n\t\tcase \"cpu cores\":\n\t\t\tv, err := strconv.ParseUint(field[1], 0, 32)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcpuinfo[i].CPUCores = uint(v)\n\t\tcase \"apicid\":\n\t\t\tcpuinfo[i].APICID = field[1]\n\t\tcase \"initial apicid\":\n\t\t\tcpuinfo[i].InitialAPICID = field[1]\n\t\tcase \"fpu\":\n\t\t\tcpuinfo[i].FPU = field[1]\n\t\tcase \"fpu_exception\":\n\t\t\tcpuinfo[i].FPUException = field[1]\n\t\tcase \"cpuid level\":\n\t\t\tv, err := strconv.ParseUint(field[1], 0, 32)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcpuinfo[i].CPUIDLevel = uint(v)\n\t\tcase \"wp\":\n\t\t\tcpuinfo[i].WP = field[1]\n\t\tcase \"flags\":\n\t\t\tcpuinfo[i].Flags = strings.Fields(field[1])\n\t\tcase \"bugs\":\n\t\t\tcpuinfo[i].Bugs = strings.Fields(field[1])\n\t\tcase \"bogomips\":\n\t\t\tv, err := strconv.ParseFloat(field[1], 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcpuinfo[i].BogoMips = v\n\t\tcase \"clflush size\":\n\t\t\tv, err := strconv.ParseUint(field[1], 0, 32)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcpuinfo[i].CLFlushSize = uint(v)\n\t\tcase \"cache_alignment\":\n\t\t\tv, err := strconv.ParseUint(field[1], 0, 32)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcpuinfo[i].CacheAlignment = uint(v)\n\t\tcase \"address sizes\":\n\t\t\tcpuinfo[i].AddressSizes = field[1]\n\t\tcase \"power management\":\n\t\t\tcpuinfo[i].PowerManagement = field[1]\n\t\t}\n\t}\n\treturn cpuinfo, nil\n}\n\nfunc parseCPUInfoARM(info []byte) ([]CPUInfo, error) {\n\tscanner := bufio.NewScanner(bytes.NewReader(info))\n\n\tfirstLine := firstNonEmptyLine(scanner)\n\tmatch, err := regexp.MatchString(\"^[Pp]rocessor\", firstLine)\n\tif !match || !strings.Contains(firstLine, \":\") {\n\t\treturn nil, fmt.Errorf(\"%w: Cannot parse line: %q: %w\", ErrFileParse, firstLine, err)\n\n\t}\n\tfield := strings.SplitN(firstLine, \": \", 2)\n\tcpuinfo := []CPUInfo{}\n\tfeaturesLine := \"\"\n\tcommonCPUInfo := CPUInfo{}\n\ti := 0\n\tif strings.TrimSpace(field[0]) == \"Processor\" {\n\t\tcommonCPUInfo = CPUInfo{ModelName: field[1]}\n\t\ti = -1\n\t} else {\n\t\tv, err := strconv.ParseUint(field[1], 0, 32)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfirstcpu := CPUInfo{Processor: uint(v)}\n\t\tcpuinfo = []CPUInfo{firstcpu}\n\t}\n\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif !strings.Contains(line, \":\") {\n\t\t\tcontinue\n\t\t}\n\t\tfield := strings.SplitN(line, \": \", 2)\n\t\tswitch strings.TrimSpace(field[0]) {\n\t\tcase \"processor\":\n\t\t\tcpuinfo = append(cpuinfo, commonCPUInfo) // start of the next processor\n\t\t\ti++\n\t\t\tv, err := strconv.ParseUint(field[1], 0, 32)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcpuinfo[i].Processor = uint(v)\n\t\tcase \"BogoMIPS\":\n\t\t\tif i == -1 {\n\t\t\t\tcpuinfo = append(cpuinfo, commonCPUInfo) // There is only one processor\n\t\t\t\ti++\n\t\t\t\tcpuinfo[i].Processor = 0\n\t\t\t}\n\t\t\tv, err := strconv.ParseFloat(field[1], 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcpuinfo[i].BogoMips = v\n\t\tcase \"Features\":\n\t\t\tfeaturesLine = line\n\t\tcase \"model name\":\n\t\t\tcpuinfo[i].ModelName = field[1]\n\t\t}\n\t}\n\tfields := strings.SplitN(featuresLine, \": \", 2)\n\tfor i := range cpuinfo {\n\t\tcpuinfo[i].Flags = strings.Fields(fields[1])\n\t}\n\treturn cpuinfo, nil\n\n}\n\nfunc parseCPUInfoS390X(info []byte) ([]CPUInfo, error) {\n\tscanner := bufio.NewScanner(bytes.NewReader(info))\n\n\tfirstLine := firstNonEmptyLine(scanner)\n\tif !strings.HasPrefix(firstLine, \"vendor_id\") || !strings.Contains(firstLine, \":\") {\n\t\treturn nil, fmt.Errorf(\"%w: Cannot parse line: %q\", ErrFileParse, firstLine)\n\t}\n\tfield := strings.SplitN(firstLine, \": \", 2)\n\tcpuinfo := []CPUInfo{}\n\tcommonCPUInfo := CPUInfo{VendorID: field[1]}\n\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif !strings.Contains(line, \":\") {\n\t\t\tcontinue\n\t\t}\n\t\tfield := strings.SplitN(line, \": \", 2)\n\t\tswitch strings.TrimSpace(field[0]) {\n\t\tcase \"bogomips per cpu\":\n\t\t\tv, err := strconv.ParseFloat(field[1], 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcommonCPUInfo.BogoMips = v\n\t\tcase \"features\":\n\t\t\tcommonCPUInfo.Flags = strings.Fields(field[1])\n\t\t}\n\t\tif strings.HasPrefix(line, \"processor\") {\n\t\t\tmatch := cpuinfoS390XProcessorRegexp.FindStringSubmatch(line)\n\t\t\tif len(match) < 2 {\n\t\t\t\treturn nil, fmt.Errorf(\"%w: %q\", ErrFileParse, firstLine)\n\t\t\t}\n\t\t\tcpu := commonCPUInfo\n\t\t\tv, err := strconv.ParseUint(match[1], 0, 32)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcpu.Processor = uint(v)\n\t\t\tcpuinfo = append(cpuinfo, cpu)\n\t\t}\n\t\tif strings.HasPrefix(line, \"cpu number\") {\n\t\t\tbreak\n\t\t}\n\t}\n\n\ti := 0\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif !strings.Contains(line, \":\") {\n\t\t\tcontinue\n\t\t}\n\t\tfield := strings.SplitN(line, \": \", 2)\n\t\tswitch strings.TrimSpace(field[0]) {\n\t\tcase \"cpu number\":\n\t\t\ti++\n\t\tcase \"cpu MHz dynamic\":\n\t\t\tclock := cpuinfoClockRegexp.FindString(strings.TrimSpace(field[1]))\n\t\t\tv, err := strconv.ParseFloat(clock, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcpuinfo[i].CPUMHz = v\n\t\tcase \"physical id\":\n\t\t\tcpuinfo[i].PhysicalID = field[1]\n\t\tcase \"core id\":\n\t\t\tcpuinfo[i].CoreID = field[1]\n\t\tcase \"cpu cores\":\n\t\t\tv, err := strconv.ParseUint(field[1], 0, 32)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcpuinfo[i].CPUCores = uint(v)\n\t\tcase \"siblings\":\n\t\t\tv, err := strconv.ParseUint(field[1], 0, 32)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcpuinfo[i].Siblings = uint(v)\n\t\t}\n\t}\n\n\treturn cpuinfo, nil\n}\n\nfunc parseCPUInfoMips(info []byte) ([]CPUInfo, error) {\n\tscanner := bufio.NewScanner(bytes.NewReader(info))\n\n\t// find the first \"processor\" line\n\tfirstLine := firstNonEmptyLine(scanner)\n\tif !strings.HasPrefix(firstLine, \"system type\") || !strings.Contains(firstLine, \":\") {\n\t\treturn nil, fmt.Errorf(\"%w: %q\", ErrFileParse, firstLine)\n\t}\n\tfield := strings.SplitN(firstLine, \": \", 2)\n\tcpuinfo := []CPUInfo{}\n\tsystemType := field[1]\n\n\ti := 0\n\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif !strings.Contains(line, \":\") {\n\t\t\tcontinue\n\t\t}\n\t\tfield := strings.SplitN(line, \": \", 2)\n\t\tswitch strings.TrimSpace(field[0]) {\n\t\tcase \"processor\":\n\t\t\tv, err := strconv.ParseUint(field[1], 0, 32)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\ti = int(v)\n\t\t\tcpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor\n\t\t\tcpuinfo[i].Processor = uint(v)\n\t\t\tcpuinfo[i].VendorID = systemType\n\t\tcase \"cpu model\":\n\t\t\tcpuinfo[i].ModelName = field[1]\n\t\tcase \"BogoMIPS\":\n\t\t\tv, err := strconv.ParseFloat(field[1], 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcpuinfo[i].BogoMips = v\n\t\t}\n\t}\n\treturn cpuinfo, nil\n}\n\nfunc parseCPUInfoLoong(info []byte) ([]CPUInfo, error) {\n\tscanner := bufio.NewScanner(bytes.NewReader(info))\n\t// find the first \"processor\" line\n\tfirstLine := firstNonEmptyLine(scanner)\n\tif !strings.HasPrefix(firstLine, \"system type\") || !strings.Contains(firstLine, \":\") {\n\t\treturn nil, fmt.Errorf(\"%w: %q\", ErrFileParse, firstLine)\n\t}\n\tfield := strings.SplitN(firstLine, \": \", 2)\n\tcpuinfo := []CPUInfo{}\n\tsystemType := field[1]\n\ti := 0\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif !strings.Contains(line, \":\") {\n\t\t\tcontinue\n\t\t}\n\t\tfield := strings.SplitN(line, \": \", 2)\n\t\tswitch strings.TrimSpace(field[0]) {\n\t\tcase \"processor\":\n\t\t\tv, err := strconv.ParseUint(field[1], 0, 32)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\ti = int(v)\n\t\t\tcpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor\n\t\t\tcpuinfo[i].Processor = uint(v)\n\t\t\tcpuinfo[i].VendorID = systemType\n\t\tcase \"CPU Family\":\n\t\t\tcpuinfo[i].CPUFamily = field[1]\n\t\tcase \"Model Name\":\n\t\t\tcpuinfo[i].ModelName = field[1]\n\t\t}\n\t}\n\treturn cpuinfo, nil\n}\n\nfunc parseCPUInfoPPC(info []byte) ([]CPUInfo, error) {\n\tscanner := bufio.NewScanner(bytes.NewReader(info))\n\n\tfirstLine := firstNonEmptyLine(scanner)\n\tif !strings.HasPrefix(firstLine, \"processor\") || !strings.Contains(firstLine, \":\") {\n\t\treturn nil, fmt.Errorf(\"%w: %q\", ErrFileParse, firstLine)\n\t}\n\tfield := strings.SplitN(firstLine, \": \", 2)\n\tv, err := strconv.ParseUint(field[1], 0, 32)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfirstcpu := CPUInfo{Processor: uint(v)}\n\tcpuinfo := []CPUInfo{firstcpu}\n\ti := 0\n\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif !strings.Contains(line, \":\") {\n\t\t\tcontinue\n\t\t}\n\t\tfield := strings.SplitN(line, \": \", 2)\n\t\tswitch strings.TrimSpace(field[0]) {\n\t\tcase \"processor\":\n\t\t\tcpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor\n\t\t\ti++\n\t\t\tv, err := strconv.ParseUint(field[1], 0, 32)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcpuinfo[i].Processor = uint(v)\n\t\tcase \"cpu\":\n\t\t\tcpuinfo[i].VendorID = field[1]\n\t\tcase \"clock\":\n\t\t\tclock := cpuinfoClockRegexp.FindString(strings.TrimSpace(field[1]))\n\t\t\tv, err := strconv.ParseFloat(clock, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcpuinfo[i].CPUMHz = v\n\t\t}\n\t}\n\treturn cpuinfo, nil\n}\n\nfunc parseCPUInfoRISCV(info []byte) ([]CPUInfo, error) {\n\tscanner := bufio.NewScanner(bytes.NewReader(info))\n\n\tfirstLine := firstNonEmptyLine(scanner)\n\tif !strings.HasPrefix(firstLine, \"processor\") || !strings.Contains(firstLine, \":\") {\n\t\treturn nil, fmt.Errorf(\"%w: %q\", ErrFileParse, firstLine)\n\t}\n\tfield := strings.SplitN(firstLine, \": \", 2)\n\tv, err := strconv.ParseUint(field[1], 0, 32)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfirstcpu := CPUInfo{Processor: uint(v)}\n\tcpuinfo := []CPUInfo{firstcpu}\n\ti := 0\n\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif !strings.Contains(line, \":\") {\n\t\t\tcontinue\n\t\t}\n\t\tfield := strings.SplitN(line, \": \", 2)\n\t\tswitch strings.TrimSpace(field[0]) {\n\t\tcase \"processor\":\n\t\t\tv, err := strconv.ParseUint(field[1], 0, 32)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\ti = int(v)\n\t\t\tcpuinfo = append(cpuinfo, CPUInfo{}) // start of the next processor\n\t\t\tcpuinfo[i].Processor = uint(v)\n\t\tcase \"hart\":\n\t\t\tcpuinfo[i].CoreID = field[1]\n\t\tcase \"isa\":\n\t\t\tcpuinfo[i].ModelName = field[1]\n\t\t}\n\t}\n\treturn cpuinfo, nil\n}\n\nfunc parseCPUInfoDummy(_ []byte) ([]CPUInfo, error) { // nolint:unused,deadcode\n\treturn nil, errors.New(\"not implemented\")\n}\n\n// firstNonEmptyLine advances the scanner to the first non-empty line\n// and returns the contents of that line.\nfunc firstNonEmptyLine(scanner *bufio.Scanner) string {\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif strings.TrimSpace(line) != \"\" {\n\t\t\treturn line\n\t\t}\n\t}\n\treturn \"\"\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/cpuinfo_armx.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux && (arm || arm64)\n// +build linux\n// +build arm arm64\n\npackage procfs\n\nvar parseCPUInfo = parseCPUInfoARM\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/cpuinfo_loong64.go",
    "content": "// Copyright 2022 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n// +build linux\n\npackage procfs\n\nvar parseCPUInfo = parseCPUInfoLoong\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux && (mips || mipsle || mips64 || mips64le)\n// +build linux\n// +build mips mipsle mips64 mips64le\n\npackage procfs\n\nvar parseCPUInfo = parseCPUInfoMips\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/cpuinfo_others.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux && !386 && !amd64 && !arm && !arm64 && !loong64 && !mips && !mips64 && !mips64le && !mipsle && !ppc64 && !ppc64le && !riscv64 && !s390x\n// +build linux,!386,!amd64,!arm,!arm64,!loong64,!mips,!mips64,!mips64le,!mipsle,!ppc64,!ppc64le,!riscv64,!s390x\n\npackage procfs\n\nvar parseCPUInfo = parseCPUInfoDummy\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux && (ppc64 || ppc64le)\n// +build linux\n// +build ppc64 ppc64le\n\npackage procfs\n\nvar parseCPUInfo = parseCPUInfoPPC\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux && (riscv || riscv64)\n// +build linux\n// +build riscv riscv64\n\npackage procfs\n\nvar parseCPUInfo = parseCPUInfoRISCV\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/cpuinfo_s390x.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux\n// +build linux\n\npackage procfs\n\nvar parseCPUInfo = parseCPUInfoS390X\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/cpuinfo_x86.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build linux && (386 || amd64)\n// +build linux\n// +build 386 amd64\n\npackage procfs\n\nvar parseCPUInfo = parseCPUInfoX86\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/crypto.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// Crypto holds info parsed from /proc/crypto.\ntype Crypto struct {\n\tAlignmask   *uint64\n\tAsync       bool\n\tBlocksize   *uint64\n\tChunksize   *uint64\n\tCtxsize     *uint64\n\tDigestsize  *uint64\n\tDriver      string\n\tGeniv       string\n\tInternal    string\n\tIvsize      *uint64\n\tMaxauthsize *uint64\n\tMaxKeysize  *uint64\n\tMinKeysize  *uint64\n\tModule      string\n\tName        string\n\tPriority    *int64\n\tRefcnt      *int64\n\tSeedsize    *uint64\n\tSelftest    string\n\tType        string\n\tWalksize    *uint64\n}\n\n// Crypto parses an crypto-file (/proc/crypto) and returns a slice of\n// structs containing the relevant info.  More information available here:\n// https://kernel.readthedocs.io/en/sphinx-samples/crypto-API.html\nfunc (fs FS) Crypto() ([]Crypto, error) {\n\tpath := fs.proc.Path(\"crypto\")\n\tb, err := util.ReadFileNoStat(path)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Cannot read file %v: %w\", ErrFileRead, b, err)\n\n\t}\n\n\tcrypto, err := parseCrypto(bytes.NewReader(b))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Cannot parse %v: %w\", ErrFileParse, crypto, err)\n\t}\n\n\treturn crypto, nil\n}\n\n// parseCrypto parses a /proc/crypto stream into Crypto elements.\nfunc parseCrypto(r io.Reader) ([]Crypto, error) {\n\tvar out []Crypto\n\n\ts := bufio.NewScanner(r)\n\tfor s.Scan() {\n\t\ttext := s.Text()\n\t\tswitch {\n\t\tcase strings.HasPrefix(text, \"name\"):\n\t\t\t// Each crypto element begins with its name.\n\t\t\tout = append(out, Crypto{})\n\t\tcase text == \"\":\n\t\t\tcontinue\n\t\t}\n\n\t\tkv := strings.Split(text, \":\")\n\t\tif len(kv) != 2 {\n\t\t\treturn nil, fmt.Errorf(\"%w: Cannot parse line: %q\", ErrFileParse, text)\n\t\t}\n\n\t\tk := strings.TrimSpace(kv[0])\n\t\tv := strings.TrimSpace(kv[1])\n\n\t\t// Parse the key/value pair into the currently focused element.\n\t\tc := &out[len(out)-1]\n\t\tif err := c.parseKV(k, v); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif err := s.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn out, nil\n}\n\n// parseKV parses a key/value pair into the appropriate field of c.\nfunc (c *Crypto) parseKV(k, v string) error {\n\tvp := util.NewValueParser(v)\n\n\tswitch k {\n\tcase \"async\":\n\t\t// Interpret literal yes as true.\n\t\tc.Async = v == \"yes\"\n\tcase \"blocksize\":\n\t\tc.Blocksize = vp.PUInt64()\n\tcase \"chunksize\":\n\t\tc.Chunksize = vp.PUInt64()\n\tcase \"digestsize\":\n\t\tc.Digestsize = vp.PUInt64()\n\tcase \"driver\":\n\t\tc.Driver = v\n\tcase \"geniv\":\n\t\tc.Geniv = v\n\tcase \"internal\":\n\t\tc.Internal = v\n\tcase \"ivsize\":\n\t\tc.Ivsize = vp.PUInt64()\n\tcase \"maxauthsize\":\n\t\tc.Maxauthsize = vp.PUInt64()\n\tcase \"max keysize\":\n\t\tc.MaxKeysize = vp.PUInt64()\n\tcase \"min keysize\":\n\t\tc.MinKeysize = vp.PUInt64()\n\tcase \"module\":\n\t\tc.Module = v\n\tcase \"name\":\n\t\tc.Name = v\n\tcase \"priority\":\n\t\tc.Priority = vp.PInt64()\n\tcase \"refcnt\":\n\t\tc.Refcnt = vp.PInt64()\n\tcase \"seedsize\":\n\t\tc.Seedsize = vp.PUInt64()\n\tcase \"selftest\":\n\t\tc.Selftest = v\n\tcase \"type\":\n\t\tc.Type = v\n\tcase \"walksize\":\n\t\tc.Walksize = vp.PUInt64()\n\t}\n\n\treturn vp.Err()\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/doc.go",
    "content": "// Copyright 2014 Prometheus Team\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Package procfs provides functions to retrieve system, kernel and process\n// metrics from the pseudo-filesystem proc.\n//\n// Example:\n//\n//\tpackage main\n//\n//\timport (\n//\t\t\"fmt\"\n//\t\t\"log\"\n//\n//\t\t\"github.com/prometheus/procfs\"\n//\t)\n//\n//\tfunc main() {\n//\t\tp, err := procfs.Self()\n//\t\tif err != nil {\n//\t\t\tlog.Fatalf(\"could not get process: %s\", err)\n//\t\t}\n//\n//\t\tstat, err := p.Stat()\n//\t\tif err != nil {\n//\t\t\tlog.Fatalf(\"could not get process stat: %s\", err)\n//\t\t}\n//\n//\t\tfmt.Printf(\"command:  %s\\n\", stat.Comm)\n//\t\tfmt.Printf(\"cpu time: %fs\\n\", stat.CPUTime())\n//\t\tfmt.Printf(\"vsize:    %dB\\n\", stat.VirtualMemory())\n//\t\tfmt.Printf(\"rss:      %dB\\n\", stat.ResidentMemory())\n//\t}\npackage procfs\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/fs.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"github.com/prometheus/procfs/internal/fs\"\n)\n\n// FS represents the pseudo-filesystem sys, which provides an interface to\n// kernel data structures.\ntype FS struct {\n\tproc   fs.FS\n\tisReal bool\n}\n\n// DefaultMountPoint is the common mount point of the proc filesystem.\nconst DefaultMountPoint = fs.DefaultProcMountPoint\n\n// NewDefaultFS returns a new proc FS mounted under the default proc mountPoint.\n// It will error if the mount point directory can't be read or is a file.\nfunc NewDefaultFS() (FS, error) {\n\treturn NewFS(DefaultMountPoint)\n}\n\n// NewFS returns a new proc FS mounted under the given proc mountPoint. It will error\n// if the mount point directory can't be read or is a file.\nfunc NewFS(mountPoint string) (FS, error) {\n\tfs, err := fs.NewFS(mountPoint)\n\tif err != nil {\n\t\treturn FS{}, err\n\t}\n\n\tisReal, err := isRealProc(mountPoint)\n\tif err != nil {\n\t\treturn FS{}, err\n\t}\n\n\treturn FS{fs, isReal}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/fs_statfs_notype.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build !freebsd && !linux\n// +build !freebsd,!linux\n\npackage procfs\n\n// isRealProc returns true on architectures that don't have a Type argument\n// in their Statfs_t struct\nfunc isRealProc(mountPoint string) (bool, error) {\n\treturn true, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/fs_statfs_type.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build freebsd || linux\n// +build freebsd linux\n\npackage procfs\n\nimport (\n\t\"syscall\"\n)\n\n// isRealProc determines whether supplied mountpoint is really a proc filesystem.\nfunc isRealProc(mountPoint string) (bool, error) {\n\tstat := syscall.Statfs_t{}\n\terr := syscall.Statfs(mountPoint, &stat)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\t// 0x9fa0 is PROC_SUPER_MAGIC: https://elixir.bootlin.com/linux/v6.1/source/include/uapi/linux/magic.h#L87\n\treturn stat.Type == 0x9fa0, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/fscache.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// Fscacheinfo represents fscache statistics.\ntype Fscacheinfo struct {\n\t// Number of index cookies allocated\n\tIndexCookiesAllocated uint64\n\t// data storage cookies allocated\n\tDataStorageCookiesAllocated uint64\n\t// Number of special cookies allocated\n\tSpecialCookiesAllocated uint64\n\t// Number of objects allocated\n\tObjectsAllocated uint64\n\t// Number of object allocation failures\n\tObjectAllocationsFailure uint64\n\t// Number of objects that reached the available state\n\tObjectsAvailable uint64\n\t// Number of objects that reached the dead state\n\tObjectsDead uint64\n\t// Number of objects that didn't have a coherency check\n\tObjectsWithoutCoherencyCheck uint64\n\t// Number of objects that passed a coherency check\n\tObjectsWithCoherencyCheck uint64\n\t// Number of objects that needed a coherency data update\n\tObjectsNeedCoherencyCheckUpdate uint64\n\t// Number of objects that were declared obsolete\n\tObjectsDeclaredObsolete uint64\n\t// Number of pages marked as being cached\n\tPagesMarkedAsBeingCached uint64\n\t// Number of uncache page requests seen\n\tUncachePagesRequestSeen uint64\n\t// Number of acquire cookie requests seen\n\tAcquireCookiesRequestSeen uint64\n\t// Number of acq reqs given a NULL parent\n\tAcquireRequestsWithNullParent uint64\n\t// Number of acq reqs rejected due to no cache available\n\tAcquireRequestsRejectedNoCacheAvailable uint64\n\t// Number of acq reqs succeeded\n\tAcquireRequestsSucceeded uint64\n\t// Number of acq reqs rejected due to error\n\tAcquireRequestsRejectedDueToError uint64\n\t// Number of acq reqs failed on ENOMEM\n\tAcquireRequestsFailedDueToEnomem uint64\n\t// Number of lookup calls made on cache backends\n\tLookupsNumber uint64\n\t// Number of negative lookups made\n\tLookupsNegative uint64\n\t// Number of positive lookups made\n\tLookupsPositive uint64\n\t// Number of objects created by lookup\n\tObjectsCreatedByLookup uint64\n\t// Number of lookups timed out and requeued\n\tLookupsTimedOutAndRequed uint64\n\tInvalidationsNumber      uint64\n\tInvalidationsRunning     uint64\n\t// Number of update cookie requests seen\n\tUpdateCookieRequestSeen uint64\n\t// Number of upd reqs given a NULL parent\n\tUpdateRequestsWithNullParent uint64\n\t// Number of upd reqs granted CPU time\n\tUpdateRequestsRunning uint64\n\t// Number of relinquish cookie requests seen\n\tRelinquishCookiesRequestSeen uint64\n\t// Number of rlq reqs given a NULL parent\n\tRelinquishCookiesWithNullParent uint64\n\t// Number of rlq reqs waited on completion of creation\n\tRelinquishRequestsWaitingCompleteCreation uint64\n\t// Relinqs rtr\n\tRelinquishRetries uint64\n\t// Number of attribute changed requests seen\n\tAttributeChangedRequestsSeen uint64\n\t// Number of attr changed requests queued\n\tAttributeChangedRequestsQueued uint64\n\t// Number of attr changed rejected -ENOBUFS\n\tAttributeChangedRejectDueToEnobufs uint64\n\t// Number of attr changed failed -ENOMEM\n\tAttributeChangedFailedDueToEnomem uint64\n\t// Number of attr changed ops given CPU time\n\tAttributeChangedOps uint64\n\t// Number of allocation requests seen\n\tAllocationRequestsSeen uint64\n\t// Number of successful alloc reqs\n\tAllocationOkRequests uint64\n\t// Number of alloc reqs that waited on lookup completion\n\tAllocationWaitingOnLookup uint64\n\t// Number of alloc reqs rejected -ENOBUFS\n\tAllocationsRejectedDueToEnobufs uint64\n\t// Number of alloc reqs aborted -ERESTARTSYS\n\tAllocationsAbortedDueToErestartsys uint64\n\t// Number of alloc reqs submitted\n\tAllocationOperationsSubmitted uint64\n\t// Number of alloc reqs waited for CPU time\n\tAllocationsWaitedForCPU uint64\n\t// Number of alloc reqs aborted due to object death\n\tAllocationsAbortedDueToObjectDeath uint64\n\t// Number of retrieval (read) requests seen\n\tRetrievalsReadRequests uint64\n\t// Number of successful retr reqs\n\tRetrievalsOk uint64\n\t// Number of retr reqs that waited on lookup completion\n\tRetrievalsWaitingLookupCompletion uint64\n\t// Number of retr reqs returned -ENODATA\n\tRetrievalsReturnedEnodata uint64\n\t// Number of retr reqs rejected -ENOBUFS\n\tRetrievalsRejectedDueToEnobufs uint64\n\t// Number of retr reqs aborted -ERESTARTSYS\n\tRetrievalsAbortedDueToErestartsys uint64\n\t// Number of retr reqs failed -ENOMEM\n\tRetrievalsFailedDueToEnomem uint64\n\t// Number of retr reqs submitted\n\tRetrievalsRequests uint64\n\t// Number of retr reqs waited for CPU time\n\tRetrievalsWaitingCPU uint64\n\t// Number of retr reqs aborted due to object death\n\tRetrievalsAbortedDueToObjectDeath uint64\n\t// Number of storage (write) requests seen\n\tStoreWriteRequests uint64\n\t// Number of successful store reqs\n\tStoreSuccessfulRequests uint64\n\t// Number of store reqs on a page already pending storage\n\tStoreRequestsOnPendingStorage uint64\n\t// Number of store reqs rejected -ENOBUFS\n\tStoreRequestsRejectedDueToEnobufs uint64\n\t// Number of store reqs failed -ENOMEM\n\tStoreRequestsFailedDueToEnomem uint64\n\t// Number of store reqs submitted\n\tStoreRequestsSubmitted uint64\n\t// Number of store reqs granted CPU time\n\tStoreRequestsRunning uint64\n\t// Number of pages given store req processing time\n\tStorePagesWithRequestsProcessing uint64\n\t// Number of store reqs deleted from tracking tree\n\tStoreRequestsDeleted uint64\n\t// Number of store reqs over store limit\n\tStoreRequestsOverStoreLimit uint64\n\t// Number of release reqs against pages with no pending store\n\tReleaseRequestsAgainstPagesWithNoPendingStorage uint64\n\t// Number of release reqs against pages stored by time lock granted\n\tReleaseRequestsAgainstPagesStoredByTimeLockGranted uint64\n\t// Number of release reqs ignored due to in-progress store\n\tReleaseRequestsIgnoredDueToInProgressStore uint64\n\t// Number of page stores cancelled due to release req\n\tPageStoresCancelledByReleaseRequests uint64\n\tVmscanWaiting                        uint64\n\t// Number of times async ops added to pending queues\n\tOpsPending uint64\n\t// Number of times async ops given CPU time\n\tOpsRunning uint64\n\t// Number of times async ops queued for processing\n\tOpsEnqueued uint64\n\t// Number of async ops cancelled\n\tOpsCancelled uint64\n\t// Number of async ops rejected due to object lookup/create failure\n\tOpsRejected uint64\n\t// Number of async ops initialised\n\tOpsInitialised uint64\n\t// Number of async ops queued for deferred release\n\tOpsDeferred uint64\n\t// Number of async ops released (should equal ini=N when idle)\n\tOpsReleased uint64\n\t// Number of deferred-release async ops garbage collected\n\tOpsGarbageCollected uint64\n\t// Number of in-progress alloc_object() cache ops\n\tCacheopAllocationsinProgress uint64\n\t// Number of in-progress lookup_object() cache ops\n\tCacheopLookupObjectInProgress uint64\n\t// Number of in-progress lookup_complete() cache ops\n\tCacheopLookupCompleteInPorgress uint64\n\t// Number of in-progress grab_object() cache ops\n\tCacheopGrabObjectInProgress uint64\n\tCacheopInvalidations        uint64\n\t// Number of in-progress update_object() cache ops\n\tCacheopUpdateObjectInProgress uint64\n\t// Number of in-progress drop_object() cache ops\n\tCacheopDropObjectInProgress uint64\n\t// Number of in-progress put_object() cache ops\n\tCacheopPutObjectInProgress uint64\n\t// Number of in-progress attr_changed() cache ops\n\tCacheopAttributeChangeInProgress uint64\n\t// Number of in-progress sync_cache() cache ops\n\tCacheopSyncCacheInProgress uint64\n\t// Number of in-progress read_or_alloc_page() cache ops\n\tCacheopReadOrAllocPageInProgress uint64\n\t// Number of in-progress read_or_alloc_pages() cache ops\n\tCacheopReadOrAllocPagesInProgress uint64\n\t// Number of in-progress allocate_page() cache ops\n\tCacheopAllocatePageInProgress uint64\n\t// Number of in-progress allocate_pages() cache ops\n\tCacheopAllocatePagesInProgress uint64\n\t// Number of in-progress write_page() cache ops\n\tCacheopWritePagesInProgress uint64\n\t// Number of in-progress uncache_page() cache ops\n\tCacheopUncachePagesInProgress uint64\n\t// Number of in-progress dissociate_pages() cache ops\n\tCacheopDissociatePagesInProgress uint64\n\t// Number of object lookups/creations rejected due to lack of space\n\tCacheevLookupsAndCreationsRejectedLackSpace uint64\n\t// Number of stale objects deleted\n\tCacheevStaleObjectsDeleted uint64\n\t// Number of objects retired when relinquished\n\tCacheevRetiredWhenReliquished uint64\n\t// Number of objects culled\n\tCacheevObjectsCulled uint64\n}\n\n// Fscacheinfo returns information about current fscache statistics.\n// See https://www.kernel.org/doc/Documentation/filesystems/caching/fscache.txt\nfunc (fs FS) Fscacheinfo() (Fscacheinfo, error) {\n\tb, err := util.ReadFileNoStat(fs.proc.Path(\"fs/fscache/stats\"))\n\tif err != nil {\n\t\treturn Fscacheinfo{}, err\n\t}\n\n\tm, err := parseFscacheinfo(bytes.NewReader(b))\n\tif err != nil {\n\t\treturn Fscacheinfo{}, fmt.Errorf(\"%w: Cannot parse %v: %w\", ErrFileParse, m, err)\n\t}\n\n\treturn *m, nil\n}\n\nfunc setFSCacheFields(fields []string, setFields ...*uint64) error {\n\tvar err error\n\tif len(fields) < len(setFields) {\n\t\treturn fmt.Errorf(\"%w: Expected %d, but got %d: %w\", ErrFileParse, len(setFields), len(fields), err)\n\t}\n\n\tfor i := range setFields {\n\t\t*setFields[i], err = strconv.ParseUint(strings.Split(fields[i], \"=\")[1], 0, 64)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc parseFscacheinfo(r io.Reader) (*Fscacheinfo, error) {\n\tvar m Fscacheinfo\n\ts := bufio.NewScanner(r)\n\tfor s.Scan() {\n\t\tfields := strings.Fields(s.Text())\n\t\tif len(fields) < 2 {\n\t\t\treturn nil, fmt.Errorf(\"%w: malformed Fscacheinfo line: %q\", ErrFileParse, s.Text())\n\t\t}\n\n\t\tswitch fields[0] {\n\t\tcase \"Cookies:\":\n\t\t\terr := setFSCacheFields(fields[1:], &m.IndexCookiesAllocated, &m.DataStorageCookiesAllocated,\n\t\t\t\t&m.SpecialCookiesAllocated)\n\t\t\tif err != nil {\n\t\t\t\treturn &m, err\n\t\t\t}\n\t\tcase \"Objects:\":\n\t\t\terr := setFSCacheFields(fields[1:], &m.ObjectsAllocated, &m.ObjectAllocationsFailure,\n\t\t\t\t&m.ObjectsAvailable, &m.ObjectsDead)\n\t\t\tif err != nil {\n\t\t\t\treturn &m, err\n\t\t\t}\n\t\tcase \"ChkAux\":\n\t\t\terr := setFSCacheFields(fields[2:], &m.ObjectsWithoutCoherencyCheck, &m.ObjectsWithCoherencyCheck,\n\t\t\t\t&m.ObjectsNeedCoherencyCheckUpdate, &m.ObjectsDeclaredObsolete)\n\t\t\tif err != nil {\n\t\t\t\treturn &m, err\n\t\t\t}\n\t\tcase \"Pages\":\n\t\t\terr := setFSCacheFields(fields[2:], &m.PagesMarkedAsBeingCached, &m.UncachePagesRequestSeen)\n\t\t\tif err != nil {\n\t\t\t\treturn &m, err\n\t\t\t}\n\t\tcase \"Acquire:\":\n\t\t\terr := setFSCacheFields(fields[1:], &m.AcquireCookiesRequestSeen, &m.AcquireRequestsWithNullParent,\n\t\t\t\t&m.AcquireRequestsRejectedNoCacheAvailable, &m.AcquireRequestsSucceeded, &m.AcquireRequestsRejectedDueToError,\n\t\t\t\t&m.AcquireRequestsFailedDueToEnomem)\n\t\t\tif err != nil {\n\t\t\t\treturn &m, err\n\t\t\t}\n\t\tcase \"Lookups:\":\n\t\t\terr := setFSCacheFields(fields[1:], &m.LookupsNumber, &m.LookupsNegative, &m.LookupsPositive,\n\t\t\t\t&m.ObjectsCreatedByLookup, &m.LookupsTimedOutAndRequed)\n\t\t\tif err != nil {\n\t\t\t\treturn &m, err\n\t\t\t}\n\t\tcase \"Invals\":\n\t\t\terr := setFSCacheFields(fields[2:], &m.InvalidationsNumber, &m.InvalidationsRunning)\n\t\t\tif err != nil {\n\t\t\t\treturn &m, err\n\t\t\t}\n\t\tcase \"Updates:\":\n\t\t\terr := setFSCacheFields(fields[1:], &m.UpdateCookieRequestSeen, &m.UpdateRequestsWithNullParent,\n\t\t\t\t&m.UpdateRequestsRunning)\n\t\t\tif err != nil {\n\t\t\t\treturn &m, err\n\t\t\t}\n\t\tcase \"Relinqs:\":\n\t\t\terr := setFSCacheFields(fields[1:], &m.RelinquishCookiesRequestSeen, &m.RelinquishCookiesWithNullParent,\n\t\t\t\t&m.RelinquishRequestsWaitingCompleteCreation, &m.RelinquishRetries)\n\t\t\tif err != nil {\n\t\t\t\treturn &m, err\n\t\t\t}\n\t\tcase \"AttrChg:\":\n\t\t\terr := setFSCacheFields(fields[1:], &m.AttributeChangedRequestsSeen, &m.AttributeChangedRequestsQueued,\n\t\t\t\t&m.AttributeChangedRejectDueToEnobufs, &m.AttributeChangedFailedDueToEnomem, &m.AttributeChangedOps)\n\t\t\tif err != nil {\n\t\t\t\treturn &m, err\n\t\t\t}\n\t\tcase \"Allocs\":\n\t\t\tif strings.Split(fields[2], \"=\")[0] == \"n\" {\n\t\t\t\terr := setFSCacheFields(fields[2:], &m.AllocationRequestsSeen, &m.AllocationOkRequests,\n\t\t\t\t\t&m.AllocationWaitingOnLookup, &m.AllocationsRejectedDueToEnobufs, &m.AllocationsAbortedDueToErestartsys)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn &m, err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terr := setFSCacheFields(fields[2:], &m.AllocationOperationsSubmitted, &m.AllocationsWaitedForCPU,\n\t\t\t\t\t&m.AllocationsAbortedDueToObjectDeath)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn &m, err\n\t\t\t\t}\n\t\t\t}\n\t\tcase \"Retrvls:\":\n\t\t\tif strings.Split(fields[1], \"=\")[0] == \"n\" {\n\t\t\t\terr := setFSCacheFields(fields[1:], &m.RetrievalsReadRequests, &m.RetrievalsOk, &m.RetrievalsWaitingLookupCompletion,\n\t\t\t\t\t&m.RetrievalsReturnedEnodata, &m.RetrievalsRejectedDueToEnobufs, &m.RetrievalsAbortedDueToErestartsys,\n\t\t\t\t\t&m.RetrievalsFailedDueToEnomem)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn &m, err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terr := setFSCacheFields(fields[1:], &m.RetrievalsRequests, &m.RetrievalsWaitingCPU, &m.RetrievalsAbortedDueToObjectDeath)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn &m, err\n\t\t\t\t}\n\t\t\t}\n\t\tcase \"Stores\":\n\t\t\tif strings.Split(fields[2], \"=\")[0] == \"n\" {\n\t\t\t\terr := setFSCacheFields(fields[2:], &m.StoreWriteRequests, &m.StoreSuccessfulRequests,\n\t\t\t\t\t&m.StoreRequestsOnPendingStorage, &m.StoreRequestsRejectedDueToEnobufs, &m.StoreRequestsFailedDueToEnomem)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn &m, err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terr := setFSCacheFields(fields[2:], &m.StoreRequestsSubmitted, &m.StoreRequestsRunning,\n\t\t\t\t\t&m.StorePagesWithRequestsProcessing, &m.StoreRequestsDeleted, &m.StoreRequestsOverStoreLimit)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn &m, err\n\t\t\t\t}\n\t\t\t}\n\t\tcase \"VmScan\":\n\t\t\terr := setFSCacheFields(fields[2:], &m.ReleaseRequestsAgainstPagesWithNoPendingStorage,\n\t\t\t\t&m.ReleaseRequestsAgainstPagesStoredByTimeLockGranted, &m.ReleaseRequestsIgnoredDueToInProgressStore,\n\t\t\t\t&m.PageStoresCancelledByReleaseRequests, &m.VmscanWaiting)\n\t\t\tif err != nil {\n\t\t\t\treturn &m, err\n\t\t\t}\n\t\tcase \"Ops\":\n\t\t\tif strings.Split(fields[2], \"=\")[0] == \"pend\" {\n\t\t\t\terr := setFSCacheFields(fields[2:], &m.OpsPending, &m.OpsRunning, &m.OpsEnqueued, &m.OpsCancelled, &m.OpsRejected)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn &m, err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terr := setFSCacheFields(fields[2:], &m.OpsInitialised, &m.OpsDeferred, &m.OpsReleased, &m.OpsGarbageCollected)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn &m, err\n\t\t\t\t}\n\t\t\t}\n\t\tcase \"CacheOp:\":\n\t\t\tif strings.Split(fields[1], \"=\")[0] == \"alo\" {\n\t\t\t\terr := setFSCacheFields(fields[1:], &m.CacheopAllocationsinProgress, &m.CacheopLookupObjectInProgress,\n\t\t\t\t\t&m.CacheopLookupCompleteInPorgress, &m.CacheopGrabObjectInProgress)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn &m, err\n\t\t\t\t}\n\t\t\t} else if strings.Split(fields[1], \"=\")[0] == \"inv\" {\n\t\t\t\terr := setFSCacheFields(fields[1:], &m.CacheopInvalidations, &m.CacheopUpdateObjectInProgress,\n\t\t\t\t\t&m.CacheopDropObjectInProgress, &m.CacheopPutObjectInProgress, &m.CacheopAttributeChangeInProgress,\n\t\t\t\t\t&m.CacheopSyncCacheInProgress)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn &m, err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terr := setFSCacheFields(fields[1:], &m.CacheopReadOrAllocPageInProgress, &m.CacheopReadOrAllocPagesInProgress,\n\t\t\t\t\t&m.CacheopAllocatePageInProgress, &m.CacheopAllocatePagesInProgress, &m.CacheopWritePagesInProgress,\n\t\t\t\t\t&m.CacheopUncachePagesInProgress, &m.CacheopDissociatePagesInProgress)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn &m, err\n\t\t\t\t}\n\t\t\t}\n\t\tcase \"CacheEv:\":\n\t\t\terr := setFSCacheFields(fields[1:], &m.CacheevLookupsAndCreationsRejectedLackSpace, &m.CacheevStaleObjectsDeleted,\n\t\t\t\t&m.CacheevRetiredWhenReliquished, &m.CacheevObjectsCulled)\n\t\t\tif err != nil {\n\t\t\t\treturn &m, err\n\t\t\t}\n\t\t}\n\t}\n\n\treturn &m, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/internal/fs/fs.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage fs\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n)\n\nconst (\n\t// DefaultProcMountPoint is the common mount point of the proc filesystem.\n\tDefaultProcMountPoint = \"/proc\"\n\n\t// DefaultSysMountPoint is the common mount point of the sys filesystem.\n\tDefaultSysMountPoint = \"/sys\"\n\n\t// DefaultConfigfsMountPoint is the common mount point of the configfs.\n\tDefaultConfigfsMountPoint = \"/sys/kernel/config\"\n)\n\n// FS represents a pseudo-filesystem, normally /proc or /sys, which provides an\n// interface to kernel data structures.\ntype FS string\n\n// NewFS returns a new FS mounted under the given mountPoint. It will error\n// if the mount point can't be read.\nfunc NewFS(mountPoint string) (FS, error) {\n\tinfo, err := os.Stat(mountPoint)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"could not read %q: %w\", mountPoint, err)\n\t}\n\tif !info.IsDir() {\n\t\treturn \"\", fmt.Errorf(\"mount point %q is not a directory\", mountPoint)\n\t}\n\n\treturn FS(mountPoint), nil\n}\n\n// Path appends the given path elements to the filesystem path, adding separators\n// as necessary.\nfunc (fs FS) Path(p ...string) string {\n\treturn filepath.Join(append([]string{string(fs)}, p...)...)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/internal/util/parse.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage util\n\nimport (\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// ParseUint32s parses a slice of strings into a slice of uint32s.\nfunc ParseUint32s(ss []string) ([]uint32, error) {\n\tus := make([]uint32, 0, len(ss))\n\tfor _, s := range ss {\n\t\tu, err := strconv.ParseUint(s, 10, 32)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tus = append(us, uint32(u))\n\t}\n\n\treturn us, nil\n}\n\n// ParseUint64s parses a slice of strings into a slice of uint64s.\nfunc ParseUint64s(ss []string) ([]uint64, error) {\n\tus := make([]uint64, 0, len(ss))\n\tfor _, s := range ss {\n\t\tu, err := strconv.ParseUint(s, 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tus = append(us, u)\n\t}\n\n\treturn us, nil\n}\n\n// ParsePInt64s parses a slice of strings into a slice of int64 pointers.\nfunc ParsePInt64s(ss []string) ([]*int64, error) {\n\tus := make([]*int64, 0, len(ss))\n\tfor _, s := range ss {\n\t\tu, err := strconv.ParseInt(s, 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tus = append(us, &u)\n\t}\n\n\treturn us, nil\n}\n\n// Parses a uint64 from given hex in string.\nfunc ParseHexUint64s(ss []string) ([]*uint64, error) {\n\tus := make([]*uint64, 0, len(ss))\n\tfor _, s := range ss {\n\t\tu, err := strconv.ParseUint(s, 16, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tus = append(us, &u)\n\t}\n\n\treturn us, nil\n}\n\n// ReadUintFromFile reads a file and attempts to parse a uint64 from it.\nfunc ReadUintFromFile(path string) (uint64, error) {\n\tdata, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn strconv.ParseUint(strings.TrimSpace(string(data)), 10, 64)\n}\n\n// ReadIntFromFile reads a file and attempts to parse a int64 from it.\nfunc ReadIntFromFile(path string) (int64, error) {\n\tdata, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64)\n}\n\n// ParseBool parses a string into a boolean pointer.\nfunc ParseBool(b string) *bool {\n\tvar truth bool\n\tswitch b {\n\tcase \"enabled\":\n\t\ttruth = true\n\tcase \"disabled\":\n\t\ttruth = false\n\tdefault:\n\t\treturn nil\n\t}\n\treturn &truth\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/internal/util/readfile.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage util\n\nimport (\n\t\"io\"\n\t\"os\"\n)\n\n// ReadFileNoStat uses io.ReadAll to read contents of entire file.\n// This is similar to os.ReadFile but without the call to os.Stat, because\n// many files in /proc and /sys report incorrect file sizes (either 0 or 4096).\n// Reads a max file size of 1024kB.  For files larger than this, a scanner\n// should be used.\nfunc ReadFileNoStat(filename string) ([]byte, error) {\n\tconst maxBufferSize = 1024 * 1024\n\n\tf, err := os.Open(filename)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer f.Close()\n\n\treader := io.LimitReader(f, maxBufferSize)\n\treturn io.ReadAll(reader)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build (linux || darwin) && !appengine\n// +build linux darwin\n// +build !appengine\n\npackage util\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"syscall\"\n)\n\n// SysReadFile is a simplified os.ReadFile that invokes syscall.Read directly.\n// https://github.com/prometheus/node_exporter/pull/728/files\n//\n// Note that this function will not read files larger than 128 bytes.\nfunc SysReadFile(file string) (string, error) {\n\tf, err := os.Open(file)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer f.Close()\n\n\t// On some machines, hwmon drivers are broken and return EAGAIN.  This causes\n\t// Go's os.ReadFile implementation to poll forever.\n\t//\n\t// Since we either want to read data or bail immediately, do the simplest\n\t// possible read using syscall directly.\n\tconst sysFileBufferSize = 128\n\tb := make([]byte, sysFileBufferSize)\n\tn, err := syscall.Read(int(f.Fd()), b)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn string(bytes.TrimSpace(b[:n])), nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build (linux && appengine) || (!linux && !darwin)\n// +build linux,appengine !linux,!darwin\n\npackage util\n\nimport (\n\t\"fmt\"\n)\n\n// SysReadFile is here implemented as a noop for builds that do not support\n// the read syscall. For example Windows, or Linux on Google App Engine.\nfunc SysReadFile(file string) (string, error) {\n\treturn \"\", fmt.Errorf(\"not supported on this platform\")\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/internal/util/valueparser.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage util\n\nimport (\n\t\"strconv\"\n)\n\n// TODO(mdlayher): util packages are an anti-pattern and this should be moved\n// somewhere else that is more focused in the future.\n\n// A ValueParser enables parsing a single string into a variety of data types\n// in a concise and safe way. The Err method must be invoked after invoking\n// any other methods to ensure a value was successfully parsed.\ntype ValueParser struct {\n\tv   string\n\terr error\n}\n\n// NewValueParser creates a ValueParser using the input string.\nfunc NewValueParser(v string) *ValueParser {\n\treturn &ValueParser{v: v}\n}\n\n// Int interprets the underlying value as an int and returns that value.\nfunc (vp *ValueParser) Int() int { return int(vp.int64()) }\n\n// PInt64 interprets the underlying value as an int64 and returns a pointer to\n// that value.\nfunc (vp *ValueParser) PInt64() *int64 {\n\tif vp.err != nil {\n\t\treturn nil\n\t}\n\n\tv := vp.int64()\n\treturn &v\n}\n\n// int64 interprets the underlying value as an int64 and returns that value.\n// TODO: export if/when necessary.\nfunc (vp *ValueParser) int64() int64 {\n\tif vp.err != nil {\n\t\treturn 0\n\t}\n\n\t// A base value of zero makes ParseInt infer the correct base using the\n\t// string's prefix, if any.\n\tconst base = 0\n\tv, err := strconv.ParseInt(vp.v, base, 64)\n\tif err != nil {\n\t\tvp.err = err\n\t\treturn 0\n\t}\n\n\treturn v\n}\n\n// PUInt64 interprets the underlying value as an uint64 and returns a pointer to\n// that value.\nfunc (vp *ValueParser) PUInt64() *uint64 {\n\tif vp.err != nil {\n\t\treturn nil\n\t}\n\n\t// A base value of zero makes ParseInt infer the correct base using the\n\t// string's prefix, if any.\n\tconst base = 0\n\tv, err := strconv.ParseUint(vp.v, base, 64)\n\tif err != nil {\n\t\tvp.err = err\n\t\treturn nil\n\t}\n\n\treturn &v\n}\n\n// Err returns the last error, if any, encountered by the ValueParser.\nfunc (vp *ValueParser) Err() error {\n\treturn vp.err\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/ipvs.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// IPVSStats holds IPVS statistics, as exposed by the kernel in `/proc/net/ip_vs_stats`.\ntype IPVSStats struct {\n\t// Total count of connections.\n\tConnections uint64\n\t// Total incoming packages processed.\n\tIncomingPackets uint64\n\t// Total outgoing packages processed.\n\tOutgoingPackets uint64\n\t// Total incoming traffic.\n\tIncomingBytes uint64\n\t// Total outgoing traffic.\n\tOutgoingBytes uint64\n}\n\n// IPVSBackendStatus holds current metrics of one virtual / real address pair.\ntype IPVSBackendStatus struct {\n\t// The local (virtual) IP address.\n\tLocalAddress net.IP\n\t// The remote (real) IP address.\n\tRemoteAddress net.IP\n\t// The local (virtual) port.\n\tLocalPort uint16\n\t// The remote (real) port.\n\tRemotePort uint16\n\t// The local firewall mark\n\tLocalMark string\n\t// The transport protocol (TCP, UDP).\n\tProto string\n\t// The current number of active connections for this virtual/real address pair.\n\tActiveConn uint64\n\t// The current number of inactive connections for this virtual/real address pair.\n\tInactConn uint64\n\t// The current weight of this virtual/real address pair.\n\tWeight uint64\n}\n\n// IPVSStats reads the IPVS statistics from the specified `proc` filesystem.\nfunc (fs FS) IPVSStats() (IPVSStats, error) {\n\tdata, err := util.ReadFileNoStat(fs.proc.Path(\"net/ip_vs_stats\"))\n\tif err != nil {\n\t\treturn IPVSStats{}, err\n\t}\n\n\treturn parseIPVSStats(bytes.NewReader(data))\n}\n\n// parseIPVSStats performs the actual parsing of `ip_vs_stats`.\nfunc parseIPVSStats(r io.Reader) (IPVSStats, error) {\n\tvar (\n\t\tstatContent []byte\n\t\tstatLines   []string\n\t\tstatFields  []string\n\t\tstats       IPVSStats\n\t)\n\n\tstatContent, err := io.ReadAll(r)\n\tif err != nil {\n\t\treturn IPVSStats{}, err\n\t}\n\n\tstatLines = strings.SplitN(string(statContent), \"\\n\", 4)\n\tif len(statLines) != 4 {\n\t\treturn IPVSStats{}, errors.New(\"ip_vs_stats corrupt: too short\")\n\t}\n\n\tstatFields = strings.Fields(statLines[2])\n\tif len(statFields) != 5 {\n\t\treturn IPVSStats{}, errors.New(\"ip_vs_stats corrupt: unexpected number of fields\")\n\t}\n\n\tstats.Connections, err = strconv.ParseUint(statFields[0], 16, 64)\n\tif err != nil {\n\t\treturn IPVSStats{}, err\n\t}\n\tstats.IncomingPackets, err = strconv.ParseUint(statFields[1], 16, 64)\n\tif err != nil {\n\t\treturn IPVSStats{}, err\n\t}\n\tstats.OutgoingPackets, err = strconv.ParseUint(statFields[2], 16, 64)\n\tif err != nil {\n\t\treturn IPVSStats{}, err\n\t}\n\tstats.IncomingBytes, err = strconv.ParseUint(statFields[3], 16, 64)\n\tif err != nil {\n\t\treturn IPVSStats{}, err\n\t}\n\tstats.OutgoingBytes, err = strconv.ParseUint(statFields[4], 16, 64)\n\tif err != nil {\n\t\treturn IPVSStats{}, err\n\t}\n\n\treturn stats, nil\n}\n\n// IPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem.\nfunc (fs FS) IPVSBackendStatus() ([]IPVSBackendStatus, error) {\n\tfile, err := os.Open(fs.proc.Path(\"net/ip_vs\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer file.Close()\n\n\treturn parseIPVSBackendStatus(file)\n}\n\nfunc parseIPVSBackendStatus(file io.Reader) ([]IPVSBackendStatus, error) {\n\tvar (\n\t\tstatus       []IPVSBackendStatus\n\t\tscanner      = bufio.NewScanner(file)\n\t\tproto        string\n\t\tlocalMark    string\n\t\tlocalAddress net.IP\n\t\tlocalPort    uint16\n\t\terr          error\n\t)\n\n\tfor scanner.Scan() {\n\t\tfields := strings.Fields(scanner.Text())\n\t\tif len(fields) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tswitch {\n\t\tcase fields[0] == \"IP\" || fields[0] == \"Prot\" || fields[1] == \"RemoteAddress:Port\":\n\t\t\tcontinue\n\t\tcase fields[0] == \"TCP\" || fields[0] == \"UDP\":\n\t\t\tif len(fields) < 2 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tproto = fields[0]\n\t\t\tlocalMark = \"\"\n\t\t\tlocalAddress, localPort, err = parseIPPort(fields[1])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\tcase fields[0] == \"FWM\":\n\t\t\tif len(fields) < 2 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tproto = fields[0]\n\t\t\tlocalMark = fields[1]\n\t\t\tlocalAddress = nil\n\t\t\tlocalPort = 0\n\t\tcase fields[0] == \"->\":\n\t\t\tif len(fields) < 6 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tremoteAddress, remotePort, err := parseIPPort(fields[1])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tweight, err := strconv.ParseUint(fields[3], 10, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tactiveConn, err := strconv.ParseUint(fields[4], 10, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tinactConn, err := strconv.ParseUint(fields[5], 10, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tstatus = append(status, IPVSBackendStatus{\n\t\t\t\tLocalAddress:  localAddress,\n\t\t\t\tLocalPort:     localPort,\n\t\t\t\tLocalMark:     localMark,\n\t\t\t\tRemoteAddress: remoteAddress,\n\t\t\t\tRemotePort:    remotePort,\n\t\t\t\tProto:         proto,\n\t\t\t\tWeight:        weight,\n\t\t\t\tActiveConn:    activeConn,\n\t\t\t\tInactConn:     inactConn,\n\t\t\t})\n\t\t}\n\t}\n\treturn status, nil\n}\n\nfunc parseIPPort(s string) (net.IP, uint16, error) {\n\tvar (\n\t\tip  net.IP\n\t\terr error\n\t)\n\n\tswitch len(s) {\n\tcase 13:\n\t\tip, err = hex.DecodeString(s[0:8])\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\tcase 46:\n\t\tip = net.ParseIP(s[1:40])\n\t\tif ip == nil {\n\t\t\treturn nil, 0, fmt.Errorf(\"%w: Invalid IPv6 addr %s: %w\", ErrFileParse, s[1:40], err)\n\t\t}\n\tdefault:\n\t\treturn nil, 0, fmt.Errorf(\"%w: Unexpected IP:Port %s: %w\", ErrFileParse, s, err)\n\t}\n\n\tportString := s[len(s)-4:]\n\tif len(portString) != 4 {\n\t\treturn nil, 0,\n\t\t\tfmt.Errorf(\"%w: Unexpected port string format %s: %w\", ErrFileParse, portString, err)\n\t}\n\tport, err := strconv.ParseUint(portString, 16, 16)\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\n\treturn ip, uint16(port), nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/kernel_random.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build !windows\n// +build !windows\n\npackage procfs\n\nimport (\n\t\"os\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// KernelRandom contains information about to the kernel's random number generator.\ntype KernelRandom struct {\n\t// EntropyAvaliable gives the available entropy, in bits.\n\tEntropyAvaliable *uint64\n\t// PoolSize gives the size of the entropy pool, in bits.\n\tPoolSize *uint64\n\t// URandomMinReseedSeconds is the number of seconds after which the DRNG will be reseeded.\n\tURandomMinReseedSeconds *uint64\n\t// WriteWakeupThreshold the number of bits of entropy below which we wake up processes\n\t// that do a select(2) or poll(2) for write access to /dev/random.\n\tWriteWakeupThreshold *uint64\n\t// ReadWakeupThreshold is the number of bits of entropy required for waking up processes that sleep\n\t// waiting for entropy from /dev/random.\n\tReadWakeupThreshold *uint64\n}\n\n// KernelRandom returns values from /proc/sys/kernel/random.\nfunc (fs FS) KernelRandom() (KernelRandom, error) {\n\trandom := KernelRandom{}\n\n\tfor file, p := range map[string]**uint64{\n\t\t\"entropy_avail\":           &random.EntropyAvaliable,\n\t\t\"poolsize\":                &random.PoolSize,\n\t\t\"urandom_min_reseed_secs\": &random.URandomMinReseedSeconds,\n\t\t\"write_wakeup_threshold\":  &random.WriteWakeupThreshold,\n\t\t\"read_wakeup_threshold\":   &random.ReadWakeupThreshold,\n\t} {\n\t\tval, err := util.ReadUintFromFile(fs.proc.Path(\"sys\", \"kernel\", \"random\", file))\n\t\tif os.IsNotExist(err) {\n\t\t\tcontinue\n\t\t}\n\t\tif err != nil {\n\t\t\treturn random, err\n\t\t}\n\t\t*p = &val\n\t}\n\n\treturn random, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/loadavg.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// LoadAvg represents an entry in /proc/loadavg.\ntype LoadAvg struct {\n\tLoad1  float64\n\tLoad5  float64\n\tLoad15 float64\n}\n\n// LoadAvg returns loadavg from /proc.\nfunc (fs FS) LoadAvg() (*LoadAvg, error) {\n\tpath := fs.proc.Path(\"loadavg\")\n\n\tdata, err := util.ReadFileNoStat(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn parseLoad(data)\n}\n\n// Parse /proc loadavg and return 1m, 5m and 15m.\nfunc parseLoad(loadavgBytes []byte) (*LoadAvg, error) {\n\tloads := make([]float64, 3)\n\tparts := strings.Fields(string(loadavgBytes))\n\tif len(parts) < 3 {\n\t\treturn nil, fmt.Errorf(\"%w: Malformed line %q\", ErrFileParse, string(loadavgBytes))\n\t}\n\n\tvar err error\n\tfor i, load := range parts[0:3] {\n\t\tloads[i], err = strconv.ParseFloat(load, 64)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: Cannot parse load: %f: %w\", ErrFileParse, loads[i], err)\n\t\t}\n\t}\n\treturn &LoadAvg{\n\t\tLoad1:  loads[0],\n\t\tLoad5:  loads[1],\n\t\tLoad15: loads[2],\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/mdstat.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nvar (\n\tstatusLineRE         = regexp.MustCompile(`(\\d+) blocks .*\\[(\\d+)/(\\d+)\\] \\[([U_]+)\\]`)\n\trecoveryLineBlocksRE = regexp.MustCompile(`\\((\\d+/\\d+)\\)`)\n\trecoveryLinePctRE    = regexp.MustCompile(`= (.+)%`)\n\trecoveryLineFinishRE = regexp.MustCompile(`finish=(.+)min`)\n\trecoveryLineSpeedRE  = regexp.MustCompile(`speed=(.+)[A-Z]`)\n\tcomponentDeviceRE    = regexp.MustCompile(`(.*)\\[\\d+\\]`)\n)\n\n// MDStat holds info parsed from /proc/mdstat.\ntype MDStat struct {\n\t// Name of the device.\n\tName string\n\t// activity-state of the device.\n\tActivityState string\n\t// Number of active disks.\n\tDisksActive int64\n\t// Total number of disks the device requires.\n\tDisksTotal int64\n\t// Number of failed disks.\n\tDisksFailed int64\n\t// Number of \"down\" disks. (the _ indicator in the status line)\n\tDisksDown int64\n\t// Spare disks in the device.\n\tDisksSpare int64\n\t// Number of blocks the device holds.\n\tBlocksTotal int64\n\t// Number of blocks on the device that are in sync.\n\tBlocksSynced int64\n\t// Number of blocks on the device that need to be synced.\n\tBlocksToBeSynced int64\n\t// progress percentage of current sync\n\tBlocksSyncedPct float64\n\t// estimated finishing time for current sync (in minutes)\n\tBlocksSyncedFinishTime float64\n\t// current sync speed (in Kilobytes/sec)\n\tBlocksSyncedSpeed float64\n\t// Name of md component devices\n\tDevices []string\n}\n\n// MDStat parses an mdstat-file (/proc/mdstat) and returns a slice of\n// structs containing the relevant info.  More information available here:\n// https://raid.wiki.kernel.org/index.php/Mdstat\nfunc (fs FS) MDStat() ([]MDStat, error) {\n\tdata, err := os.ReadFile(fs.proc.Path(\"mdstat\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tmdstat, err := parseMDStat(data)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Cannot parse %v: %w\", ErrFileParse, fs.proc.Path(\"mdstat\"), err)\n\t}\n\treturn mdstat, nil\n}\n\n// parseMDStat parses data from mdstat file (/proc/mdstat) and returns a slice of\n// structs containing the relevant info.\nfunc parseMDStat(mdStatData []byte) ([]MDStat, error) {\n\tmdStats := []MDStat{}\n\tlines := strings.Split(string(mdStatData), \"\\n\")\n\n\tfor i, line := range lines {\n\t\tif strings.TrimSpace(line) == \"\" || line[0] == ' ' ||\n\t\t\tstrings.HasPrefix(line, \"Personalities\") ||\n\t\t\tstrings.HasPrefix(line, \"unused\") {\n\t\t\tcontinue\n\t\t}\n\n\t\tdeviceFields := strings.Fields(line)\n\t\tif len(deviceFields) < 3 {\n\t\t\treturn nil, fmt.Errorf(\"%w: Expected 3+ lines, got %q\", ErrFileParse, line)\n\t\t}\n\t\tmdName := deviceFields[0] // mdx\n\t\tstate := deviceFields[2]  // active or inactive\n\n\t\tif len(lines) <= i+3 {\n\t\t\treturn nil, fmt.Errorf(\"%w: Too few lines for md device: %q\", ErrFileParse, mdName)\n\t\t}\n\n\t\t// Failed disks have the suffix (F) & Spare disks have the suffix (S).\n\t\tfail := int64(strings.Count(line, \"(F)\"))\n\t\tspare := int64(strings.Count(line, \"(S)\"))\n\t\tactive, total, down, size, err := evalStatusLine(lines[i], lines[i+1])\n\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: Cannot parse md device lines: %v: %w\", ErrFileParse, active, err)\n\t\t}\n\n\t\tsyncLineIdx := i + 2\n\t\tif strings.Contains(lines[i+2], \"bitmap\") { // skip bitmap line\n\t\t\tsyncLineIdx++\n\t\t}\n\n\t\t// If device is syncing at the moment, get the number of currently\n\t\t// synced bytes, otherwise that number equals the size of the device.\n\t\tblocksSynced := size\n\t\tblocksToBeSynced := size\n\t\tspeed := float64(0)\n\t\tfinish := float64(0)\n\t\tpct := float64(0)\n\t\trecovering := strings.Contains(lines[syncLineIdx], \"recovery\")\n\t\tresyncing := strings.Contains(lines[syncLineIdx], \"resync\")\n\t\tchecking := strings.Contains(lines[syncLineIdx], \"check\")\n\n\t\t// Append recovery and resyncing state info.\n\t\tif recovering || resyncing || checking {\n\t\t\tif recovering {\n\t\t\t\tstate = \"recovering\"\n\t\t\t} else if checking {\n\t\t\t\tstate = \"checking\"\n\t\t\t} else {\n\t\t\t\tstate = \"resyncing\"\n\t\t\t}\n\n\t\t\t// Handle case when resync=PENDING or resync=DELAYED.\n\t\t\tif strings.Contains(lines[syncLineIdx], \"PENDING\") ||\n\t\t\t\tstrings.Contains(lines[syncLineIdx], \"DELAYED\") {\n\t\t\t\tblocksSynced = 0\n\t\t\t} else {\n\t\t\t\tblocksSynced, blocksToBeSynced, pct, finish, speed, err = evalRecoveryLine(lines[syncLineIdx])\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"%w: Cannot parse sync line in md device: %q: %w\", ErrFileParse, mdName, err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tmdStats = append(mdStats, MDStat{\n\t\t\tName:                   mdName,\n\t\t\tActivityState:          state,\n\t\t\tDisksActive:            active,\n\t\t\tDisksFailed:            fail,\n\t\t\tDisksDown:              down,\n\t\t\tDisksSpare:             spare,\n\t\t\tDisksTotal:             total,\n\t\t\tBlocksTotal:            size,\n\t\t\tBlocksSynced:           blocksSynced,\n\t\t\tBlocksToBeSynced:       blocksToBeSynced,\n\t\t\tBlocksSyncedPct:        pct,\n\t\t\tBlocksSyncedFinishTime: finish,\n\t\t\tBlocksSyncedSpeed:      speed,\n\t\t\tDevices:                evalComponentDevices(deviceFields),\n\t\t})\n\t}\n\n\treturn mdStats, nil\n}\n\nfunc evalStatusLine(deviceLine, statusLine string) (active, total, down, size int64, err error) {\n\tstatusFields := strings.Fields(statusLine)\n\tif len(statusFields) < 1 {\n\t\treturn 0, 0, 0, 0, fmt.Errorf(\"%w: Unexpected statusline %q: %w\", ErrFileParse, statusLine, err)\n\t}\n\n\tsizeStr := statusFields[0]\n\tsize, err = strconv.ParseInt(sizeStr, 10, 64)\n\tif err != nil {\n\t\treturn 0, 0, 0, 0, fmt.Errorf(\"%w: Unexpected statusline %q: %w\", ErrFileParse, statusLine, err)\n\t}\n\n\tif strings.Contains(deviceLine, \"raid0\") || strings.Contains(deviceLine, \"linear\") {\n\t\t// In the device deviceLine, only disks have a number associated with them in [].\n\t\ttotal = int64(strings.Count(deviceLine, \"[\"))\n\t\treturn total, total, 0, size, nil\n\t}\n\n\tif strings.Contains(deviceLine, \"inactive\") {\n\t\treturn 0, 0, 0, size, nil\n\t}\n\n\tmatches := statusLineRE.FindStringSubmatch(statusLine)\n\tif len(matches) != 5 {\n\t\treturn 0, 0, 0, 0, fmt.Errorf(\"%w: Could not fild all substring matches %s: %w\", ErrFileParse, statusLine, err)\n\t}\n\n\ttotal, err = strconv.ParseInt(matches[2], 10, 64)\n\tif err != nil {\n\t\treturn 0, 0, 0, 0, fmt.Errorf(\"%w: Unexpected statusline %q: %w\", ErrFileParse, statusLine, err)\n\t}\n\n\tactive, err = strconv.ParseInt(matches[3], 10, 64)\n\tif err != nil {\n\t\treturn 0, 0, 0, 0, fmt.Errorf(\"%w: Unexpected active %d: %w\", ErrFileParse, active, err)\n\t}\n\tdown = int64(strings.Count(matches[4], \"_\"))\n\n\treturn active, total, down, size, nil\n}\n\nfunc evalRecoveryLine(recoveryLine string) (blocksSynced int64, blocksToBeSynced int64, pct float64, finish float64, speed float64, err error) {\n\tmatches := recoveryLineBlocksRE.FindStringSubmatch(recoveryLine)\n\tif len(matches) != 2 {\n\t\treturn 0, 0, 0, 0, 0, fmt.Errorf(\"%w: Unexpected recoveryLine blocks %s: %w\", ErrFileParse, recoveryLine, err)\n\t}\n\n\tblocks := strings.Split(matches[1], \"/\")\n\tblocksSynced, err = strconv.ParseInt(blocks[0], 10, 64)\n\tif err != nil {\n\t\treturn 0, 0, 0, 0, 0, fmt.Errorf(\"%w: Unable to parse recovery blocks synced %q: %w\", ErrFileParse, matches[1], err)\n\t}\n\n\tblocksToBeSynced, err = strconv.ParseInt(blocks[1], 10, 64)\n\tif err != nil {\n\t\treturn blocksSynced, 0, 0, 0, 0, fmt.Errorf(\"%w: Unable to parse recovery to be synced blocks %q: %w\", ErrFileParse, matches[2], err)\n\t}\n\n\t// Get percentage complete\n\tmatches = recoveryLinePctRE.FindStringSubmatch(recoveryLine)\n\tif len(matches) != 2 {\n\t\treturn blocksSynced, blocksToBeSynced, 0, 0, 0, fmt.Errorf(\"%w: Unexpected recoveryLine matching percentage %s\", ErrFileParse, recoveryLine)\n\t}\n\tpct, err = strconv.ParseFloat(strings.TrimSpace(matches[1]), 64)\n\tif err != nil {\n\t\treturn blocksSynced, blocksToBeSynced, 0, 0, 0, fmt.Errorf(\"%w: Error parsing float from recoveryLine %q\", ErrFileParse, recoveryLine)\n\t}\n\n\t// Get time expected left to complete\n\tmatches = recoveryLineFinishRE.FindStringSubmatch(recoveryLine)\n\tif len(matches) != 2 {\n\t\treturn blocksSynced, blocksToBeSynced, pct, 0, 0, fmt.Errorf(\"%w: Unexpected recoveryLine matching est. finish time: %s\", ErrFileParse, recoveryLine)\n\t}\n\tfinish, err = strconv.ParseFloat(matches[1], 64)\n\tif err != nil {\n\t\treturn blocksSynced, blocksToBeSynced, pct, 0, 0, fmt.Errorf(\"%w: Unable to parse float from recoveryLine: %q\", ErrFileParse, recoveryLine)\n\t}\n\n\t// Get recovery speed\n\tmatches = recoveryLineSpeedRE.FindStringSubmatch(recoveryLine)\n\tif len(matches) != 2 {\n\t\treturn blocksSynced, blocksToBeSynced, pct, finish, 0, fmt.Errorf(\"%w: Unexpected recoveryLine value: %s\", ErrFileParse, recoveryLine)\n\t}\n\tspeed, err = strconv.ParseFloat(matches[1], 64)\n\tif err != nil {\n\t\treturn blocksSynced, blocksToBeSynced, pct, finish, 0, fmt.Errorf(\"%w: Error parsing float from recoveryLine: %q: %w\", ErrFileParse, recoveryLine, err)\n\t}\n\n\treturn blocksSynced, blocksToBeSynced, pct, finish, speed, nil\n}\n\nfunc evalComponentDevices(deviceFields []string) []string {\n\tmdComponentDevices := make([]string, 0)\n\tif len(deviceFields) > 3 {\n\t\tfor _, field := range deviceFields[4:] {\n\t\t\tmatch := componentDeviceRE.FindStringSubmatch(field)\n\t\t\tif match == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tmdComponentDevices = append(mdComponentDevices, match[1])\n\t\t}\n\t}\n\n\treturn mdComponentDevices\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/meminfo.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// Meminfo represents memory statistics.\ntype Meminfo struct {\n\t// Total usable ram (i.e. physical ram minus a few reserved\n\t// bits and the kernel binary code)\n\tMemTotal *uint64\n\t// The sum of LowFree+HighFree\n\tMemFree *uint64\n\t// An estimate of how much memory is available for starting\n\t// new applications, without swapping. Calculated from\n\t// MemFree, SReclaimable, the size of the file LRU lists, and\n\t// the low watermarks in each zone.  The estimate takes into\n\t// account that the system needs some page cache to function\n\t// well, and that not all reclaimable slab will be\n\t// reclaimable, due to items being in use. The impact of those\n\t// factors will vary from system to system.\n\tMemAvailable *uint64\n\t// Relatively temporary storage for raw disk blocks shouldn't\n\t// get tremendously large (20MB or so)\n\tBuffers *uint64\n\tCached  *uint64\n\t// Memory that once was swapped out, is swapped back in but\n\t// still also is in the swapfile (if memory is needed it\n\t// doesn't need to be swapped out AGAIN because it is already\n\t// in the swapfile. This saves I/O)\n\tSwapCached *uint64\n\t// Memory that has been used more recently and usually not\n\t// reclaimed unless absolutely necessary.\n\tActive *uint64\n\t// Memory which has been less recently used.  It is more\n\t// eligible to be reclaimed for other purposes\n\tInactive     *uint64\n\tActiveAnon   *uint64\n\tInactiveAnon *uint64\n\tActiveFile   *uint64\n\tInactiveFile *uint64\n\tUnevictable  *uint64\n\tMlocked      *uint64\n\t// total amount of swap space available\n\tSwapTotal *uint64\n\t// Memory which has been evicted from RAM, and is temporarily\n\t// on the disk\n\tSwapFree *uint64\n\t// Memory which is waiting to get written back to the disk\n\tDirty *uint64\n\t// Memory which is actively being written back to the disk\n\tWriteback *uint64\n\t// Non-file backed pages mapped into userspace page tables\n\tAnonPages *uint64\n\t// files which have been mapped, such as libraries\n\tMapped *uint64\n\tShmem  *uint64\n\t// in-kernel data structures cache\n\tSlab *uint64\n\t// Part of Slab, that might be reclaimed, such as caches\n\tSReclaimable *uint64\n\t// Part of Slab, that cannot be reclaimed on memory pressure\n\tSUnreclaim  *uint64\n\tKernelStack *uint64\n\t// amount of memory dedicated to the lowest level of page\n\t// tables.\n\tPageTables *uint64\n\t// NFS pages sent to the server, but not yet committed to\n\t// stable storage\n\tNFSUnstable *uint64\n\t// Memory used for block device \"bounce buffers\"\n\tBounce *uint64\n\t// Memory used by FUSE for temporary writeback buffers\n\tWritebackTmp *uint64\n\t// Based on the overcommit ratio ('vm.overcommit_ratio'),\n\t// this is the total amount of  memory currently available to\n\t// be allocated on the system. This limit is only adhered to\n\t// if strict overcommit accounting is enabled (mode 2 in\n\t// 'vm.overcommit_memory').\n\t// The CommitLimit is calculated with the following formula:\n\t// CommitLimit = ([total RAM pages] - [total huge TLB pages]) *\n\t//                overcommit_ratio / 100 + [total swap pages]\n\t// For example, on a system with 1G of physical RAM and 7G\n\t// of swap with a `vm.overcommit_ratio` of 30 it would\n\t// yield a CommitLimit of 7.3G.\n\t// For more details, see the memory overcommit documentation\n\t// in vm/overcommit-accounting.\n\tCommitLimit *uint64\n\t// The amount of memory presently allocated on the system.\n\t// The committed memory is a sum of all of the memory which\n\t// has been allocated by processes, even if it has not been\n\t// \"used\" by them as of yet. A process which malloc()'s 1G\n\t// of memory, but only touches 300M of it will show up as\n\t// using 1G. This 1G is memory which has been \"committed\" to\n\t// by the VM and can be used at any time by the allocating\n\t// application. With strict overcommit enabled on the system\n\t// (mode 2 in 'vm.overcommit_memory'),allocations which would\n\t// exceed the CommitLimit (detailed above) will not be permitted.\n\t// This is useful if one needs to guarantee that processes will\n\t// not fail due to lack of memory once that memory has been\n\t// successfully allocated.\n\tCommittedAS *uint64\n\t// total size of vmalloc memory area\n\tVmallocTotal *uint64\n\t// amount of vmalloc area which is used\n\tVmallocUsed *uint64\n\t// largest contiguous block of vmalloc area which is free\n\tVmallocChunk      *uint64\n\tPercpu            *uint64\n\tHardwareCorrupted *uint64\n\tAnonHugePages     *uint64\n\tShmemHugePages    *uint64\n\tShmemPmdMapped    *uint64\n\tCmaTotal          *uint64\n\tCmaFree           *uint64\n\tHugePagesTotal    *uint64\n\tHugePagesFree     *uint64\n\tHugePagesRsvd     *uint64\n\tHugePagesSurp     *uint64\n\tHugepagesize      *uint64\n\tDirectMap4k       *uint64\n\tDirectMap2M       *uint64\n\tDirectMap1G       *uint64\n\n\t// The struct fields below are the byte-normalized counterparts to the\n\t// existing struct fields. Values are normalized using the optional\n\t// unit field in the meminfo line.\n\tMemTotalBytes          *uint64\n\tMemFreeBytes           *uint64\n\tMemAvailableBytes      *uint64\n\tBuffersBytes           *uint64\n\tCachedBytes            *uint64\n\tSwapCachedBytes        *uint64\n\tActiveBytes            *uint64\n\tInactiveBytes          *uint64\n\tActiveAnonBytes        *uint64\n\tInactiveAnonBytes      *uint64\n\tActiveFileBytes        *uint64\n\tInactiveFileBytes      *uint64\n\tUnevictableBytes       *uint64\n\tMlockedBytes           *uint64\n\tSwapTotalBytes         *uint64\n\tSwapFreeBytes          *uint64\n\tDirtyBytes             *uint64\n\tWritebackBytes         *uint64\n\tAnonPagesBytes         *uint64\n\tMappedBytes            *uint64\n\tShmemBytes             *uint64\n\tSlabBytes              *uint64\n\tSReclaimableBytes      *uint64\n\tSUnreclaimBytes        *uint64\n\tKernelStackBytes       *uint64\n\tPageTablesBytes        *uint64\n\tNFSUnstableBytes       *uint64\n\tBounceBytes            *uint64\n\tWritebackTmpBytes      *uint64\n\tCommitLimitBytes       *uint64\n\tCommittedASBytes       *uint64\n\tVmallocTotalBytes      *uint64\n\tVmallocUsedBytes       *uint64\n\tVmallocChunkBytes      *uint64\n\tPercpuBytes            *uint64\n\tHardwareCorruptedBytes *uint64\n\tAnonHugePagesBytes     *uint64\n\tShmemHugePagesBytes    *uint64\n\tShmemPmdMappedBytes    *uint64\n\tCmaTotalBytes          *uint64\n\tCmaFreeBytes           *uint64\n\tHugepagesizeBytes      *uint64\n\tDirectMap4kBytes       *uint64\n\tDirectMap2MBytes       *uint64\n\tDirectMap1GBytes       *uint64\n}\n\n// Meminfo returns an information about current kernel/system memory statistics.\n// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt\nfunc (fs FS) Meminfo() (Meminfo, error) {\n\tb, err := util.ReadFileNoStat(fs.proc.Path(\"meminfo\"))\n\tif err != nil {\n\t\treturn Meminfo{}, err\n\t}\n\n\tm, err := parseMemInfo(bytes.NewReader(b))\n\tif err != nil {\n\t\treturn Meminfo{}, fmt.Errorf(\"%w: %w\", ErrFileParse, err)\n\t}\n\n\treturn *m, nil\n}\n\nfunc parseMemInfo(r io.Reader) (*Meminfo, error) {\n\tvar m Meminfo\n\ts := bufio.NewScanner(r)\n\tfor s.Scan() {\n\t\tfields := strings.Fields(s.Text())\n\t\tvar val, valBytes uint64\n\n\t\tval, err := strconv.ParseUint(fields[1], 0, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tswitch len(fields) {\n\t\tcase 2:\n\t\t\t// No unit present, use the parsed the value as bytes directly.\n\t\t\tvalBytes = val\n\t\tcase 3:\n\t\t\t// Unit present in optional 3rd field, convert it to\n\t\t\t// bytes. The only unit supported within the Linux\n\t\t\t// kernel is `kB`.\n\t\t\tif fields[2] != \"kB\" {\n\t\t\t\treturn nil, fmt.Errorf(\"%w: Unsupported unit in optional 3rd field %q\", ErrFileParse, fields[2])\n\t\t\t}\n\n\t\t\tvalBytes = 1024 * val\n\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"%w: Malformed line %q\", ErrFileParse, s.Text())\n\t\t}\n\n\t\tswitch fields[0] {\n\t\tcase \"MemTotal:\":\n\t\t\tm.MemTotal = &val\n\t\t\tm.MemTotalBytes = &valBytes\n\t\tcase \"MemFree:\":\n\t\t\tm.MemFree = &val\n\t\t\tm.MemFreeBytes = &valBytes\n\t\tcase \"MemAvailable:\":\n\t\t\tm.MemAvailable = &val\n\t\t\tm.MemAvailableBytes = &valBytes\n\t\tcase \"Buffers:\":\n\t\t\tm.Buffers = &val\n\t\t\tm.BuffersBytes = &valBytes\n\t\tcase \"Cached:\":\n\t\t\tm.Cached = &val\n\t\t\tm.CachedBytes = &valBytes\n\t\tcase \"SwapCached:\":\n\t\t\tm.SwapCached = &val\n\t\t\tm.SwapCachedBytes = &valBytes\n\t\tcase \"Active:\":\n\t\t\tm.Active = &val\n\t\t\tm.ActiveBytes = &valBytes\n\t\tcase \"Inactive:\":\n\t\t\tm.Inactive = &val\n\t\t\tm.InactiveBytes = &valBytes\n\t\tcase \"Active(anon):\":\n\t\t\tm.ActiveAnon = &val\n\t\t\tm.ActiveAnonBytes = &valBytes\n\t\tcase \"Inactive(anon):\":\n\t\t\tm.InactiveAnon = &val\n\t\t\tm.InactiveAnonBytes = &valBytes\n\t\tcase \"Active(file):\":\n\t\t\tm.ActiveFile = &val\n\t\t\tm.ActiveFileBytes = &valBytes\n\t\tcase \"Inactive(file):\":\n\t\t\tm.InactiveFile = &val\n\t\t\tm.InactiveFileBytes = &valBytes\n\t\tcase \"Unevictable:\":\n\t\t\tm.Unevictable = &val\n\t\t\tm.UnevictableBytes = &valBytes\n\t\tcase \"Mlocked:\":\n\t\t\tm.Mlocked = &val\n\t\t\tm.MlockedBytes = &valBytes\n\t\tcase \"SwapTotal:\":\n\t\t\tm.SwapTotal = &val\n\t\t\tm.SwapTotalBytes = &valBytes\n\t\tcase \"SwapFree:\":\n\t\t\tm.SwapFree = &val\n\t\t\tm.SwapFreeBytes = &valBytes\n\t\tcase \"Dirty:\":\n\t\t\tm.Dirty = &val\n\t\t\tm.DirtyBytes = &valBytes\n\t\tcase \"Writeback:\":\n\t\t\tm.Writeback = &val\n\t\t\tm.WritebackBytes = &valBytes\n\t\tcase \"AnonPages:\":\n\t\t\tm.AnonPages = &val\n\t\t\tm.AnonPagesBytes = &valBytes\n\t\tcase \"Mapped:\":\n\t\t\tm.Mapped = &val\n\t\t\tm.MappedBytes = &valBytes\n\t\tcase \"Shmem:\":\n\t\t\tm.Shmem = &val\n\t\t\tm.ShmemBytes = &valBytes\n\t\tcase \"Slab:\":\n\t\t\tm.Slab = &val\n\t\t\tm.SlabBytes = &valBytes\n\t\tcase \"SReclaimable:\":\n\t\t\tm.SReclaimable = &val\n\t\t\tm.SReclaimableBytes = &valBytes\n\t\tcase \"SUnreclaim:\":\n\t\t\tm.SUnreclaim = &val\n\t\t\tm.SUnreclaimBytes = &valBytes\n\t\tcase \"KernelStack:\":\n\t\t\tm.KernelStack = &val\n\t\t\tm.KernelStackBytes = &valBytes\n\t\tcase \"PageTables:\":\n\t\t\tm.PageTables = &val\n\t\t\tm.PageTablesBytes = &valBytes\n\t\tcase \"NFS_Unstable:\":\n\t\t\tm.NFSUnstable = &val\n\t\t\tm.NFSUnstableBytes = &valBytes\n\t\tcase \"Bounce:\":\n\t\t\tm.Bounce = &val\n\t\t\tm.BounceBytes = &valBytes\n\t\tcase \"WritebackTmp:\":\n\t\t\tm.WritebackTmp = &val\n\t\t\tm.WritebackTmpBytes = &valBytes\n\t\tcase \"CommitLimit:\":\n\t\t\tm.CommitLimit = &val\n\t\t\tm.CommitLimitBytes = &valBytes\n\t\tcase \"Committed_AS:\":\n\t\t\tm.CommittedAS = &val\n\t\t\tm.CommittedASBytes = &valBytes\n\t\tcase \"VmallocTotal:\":\n\t\t\tm.VmallocTotal = &val\n\t\t\tm.VmallocTotalBytes = &valBytes\n\t\tcase \"VmallocUsed:\":\n\t\t\tm.VmallocUsed = &val\n\t\t\tm.VmallocUsedBytes = &valBytes\n\t\tcase \"VmallocChunk:\":\n\t\t\tm.VmallocChunk = &val\n\t\t\tm.VmallocChunkBytes = &valBytes\n\t\tcase \"Percpu:\":\n\t\t\tm.Percpu = &val\n\t\t\tm.PercpuBytes = &valBytes\n\t\tcase \"HardwareCorrupted:\":\n\t\t\tm.HardwareCorrupted = &val\n\t\t\tm.HardwareCorruptedBytes = &valBytes\n\t\tcase \"AnonHugePages:\":\n\t\t\tm.AnonHugePages = &val\n\t\t\tm.AnonHugePagesBytes = &valBytes\n\t\tcase \"ShmemHugePages:\":\n\t\t\tm.ShmemHugePages = &val\n\t\t\tm.ShmemHugePagesBytes = &valBytes\n\t\tcase \"ShmemPmdMapped:\":\n\t\t\tm.ShmemPmdMapped = &val\n\t\t\tm.ShmemPmdMappedBytes = &valBytes\n\t\tcase \"CmaTotal:\":\n\t\t\tm.CmaTotal = &val\n\t\t\tm.CmaTotalBytes = &valBytes\n\t\tcase \"CmaFree:\":\n\t\t\tm.CmaFree = &val\n\t\t\tm.CmaFreeBytes = &valBytes\n\t\tcase \"HugePages_Total:\":\n\t\t\tm.HugePagesTotal = &val\n\t\tcase \"HugePages_Free:\":\n\t\t\tm.HugePagesFree = &val\n\t\tcase \"HugePages_Rsvd:\":\n\t\t\tm.HugePagesRsvd = &val\n\t\tcase \"HugePages_Surp:\":\n\t\t\tm.HugePagesSurp = &val\n\t\tcase \"Hugepagesize:\":\n\t\t\tm.Hugepagesize = &val\n\t\t\tm.HugepagesizeBytes = &valBytes\n\t\tcase \"DirectMap4k:\":\n\t\t\tm.DirectMap4k = &val\n\t\t\tm.DirectMap4kBytes = &valBytes\n\t\tcase \"DirectMap2M:\":\n\t\t\tm.DirectMap2M = &val\n\t\t\tm.DirectMap2MBytes = &valBytes\n\t\tcase \"DirectMap1G:\":\n\t\t\tm.DirectMap1G = &val\n\t\t\tm.DirectMap1GBytes = &valBytes\n\t\t}\n\t}\n\n\treturn &m, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/mountinfo.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// A MountInfo is a type that describes the details, options\n// for each mount, parsed from /proc/self/mountinfo.\n// The fields described in each entry of /proc/self/mountinfo\n// is described in the following man page.\n// http://man7.org/linux/man-pages/man5/proc.5.html\ntype MountInfo struct {\n\t// Unique ID for the mount\n\tMountID int\n\t// The ID of the parent mount\n\tParentID int\n\t// The value of `st_dev` for the files on this FS\n\tMajorMinorVer string\n\t// The pathname of the directory in the FS that forms\n\t// the root for this mount\n\tRoot string\n\t// The pathname of the mount point relative to the root\n\tMountPoint string\n\t// Mount options\n\tOptions map[string]string\n\t// Zero or more optional fields\n\tOptionalFields map[string]string\n\t// The Filesystem type\n\tFSType string\n\t// FS specific information or \"none\"\n\tSource string\n\t// Superblock options\n\tSuperOptions map[string]string\n}\n\n// Reads each line of the mountinfo file, and returns a list of formatted MountInfo structs.\nfunc parseMountInfo(info []byte) ([]*MountInfo, error) {\n\tmounts := []*MountInfo{}\n\tscanner := bufio.NewScanner(bytes.NewReader(info))\n\tfor scanner.Scan() {\n\t\tmountString := scanner.Text()\n\t\tparsedMounts, err := parseMountInfoString(mountString)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmounts = append(mounts, parsedMounts)\n\t}\n\n\terr := scanner.Err()\n\treturn mounts, err\n}\n\n// Parses a mountinfo file line, and converts it to a MountInfo struct.\n// An important check here is to see if the hyphen separator, as if it does not exist,\n// it means that the line is malformed.\nfunc parseMountInfoString(mountString string) (*MountInfo, error) {\n\tvar err error\n\n\tmountInfo := strings.Split(mountString, \" \")\n\tmountInfoLength := len(mountInfo)\n\tif mountInfoLength < 10 {\n\t\treturn nil, fmt.Errorf(\"%w: Too few fields in mount string: %s\", ErrFileParse, mountString)\n\t}\n\n\tif mountInfo[mountInfoLength-4] != \"-\" {\n\t\treturn nil, fmt.Errorf(\"%w: couldn't find separator in expected field: %s\", ErrFileParse, mountInfo[mountInfoLength-4])\n\t}\n\n\tmount := &MountInfo{\n\t\tMajorMinorVer:  mountInfo[2],\n\t\tRoot:           mountInfo[3],\n\t\tMountPoint:     mountInfo[4],\n\t\tOptions:        mountOptionsParser(mountInfo[5]),\n\t\tOptionalFields: nil,\n\t\tFSType:         mountInfo[mountInfoLength-3],\n\t\tSource:         mountInfo[mountInfoLength-2],\n\t\tSuperOptions:   mountOptionsParser(mountInfo[mountInfoLength-1]),\n\t}\n\n\tmount.MountID, err = strconv.Atoi(mountInfo[0])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: mount ID: %q\", ErrFileParse, mount.MountID)\n\t}\n\tmount.ParentID, err = strconv.Atoi(mountInfo[1])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: parent ID: %q\", ErrFileParse, mount.ParentID)\n\t}\n\t// Has optional fields, which is a space separated list of values.\n\t// Example: shared:2 master:7\n\tif mountInfo[6] != \"\" {\n\t\tmount.OptionalFields, err = mountOptionsParseOptionalFields(mountInfo[6 : mountInfoLength-4])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: %w\", ErrFileParse, err)\n\t\t}\n\t}\n\treturn mount, nil\n}\n\n// mountOptionsIsValidField checks a string against a valid list of optional fields keys.\nfunc mountOptionsIsValidField(s string) bool {\n\tswitch s {\n\tcase\n\t\t\"shared\",\n\t\t\"master\",\n\t\t\"propagate_from\",\n\t\t\"unbindable\":\n\t\treturn true\n\t}\n\treturn false\n}\n\n// mountOptionsParseOptionalFields parses a list of optional fields strings into a double map of strings.\nfunc mountOptionsParseOptionalFields(o []string) (map[string]string, error) {\n\toptionalFields := make(map[string]string)\n\tfor _, field := range o {\n\t\toptionSplit := strings.SplitN(field, \":\", 2)\n\t\tvalue := \"\"\n\t\tif len(optionSplit) == 2 {\n\t\t\tvalue = optionSplit[1]\n\t\t}\n\t\tif mountOptionsIsValidField(optionSplit[0]) {\n\t\t\toptionalFields[optionSplit[0]] = value\n\t\t}\n\t}\n\treturn optionalFields, nil\n}\n\n// mountOptionsParser parses the mount options, superblock options.\nfunc mountOptionsParser(mountOptions string) map[string]string {\n\topts := make(map[string]string)\n\toptions := strings.Split(mountOptions, \",\")\n\tfor _, opt := range options {\n\t\tsplitOption := strings.Split(opt, \"=\")\n\t\tif len(splitOption) < 2 {\n\t\t\tkey := splitOption[0]\n\t\t\topts[key] = \"\"\n\t\t} else {\n\t\t\tkey, value := splitOption[0], splitOption[1]\n\t\t\topts[key] = value\n\t\t}\n\t}\n\treturn opts\n}\n\n// GetMounts retrieves mountinfo information from `/proc/self/mountinfo`.\nfunc GetMounts() ([]*MountInfo, error) {\n\tdata, err := util.ReadFileNoStat(\"/proc/self/mountinfo\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn parseMountInfo(data)\n}\n\n// GetProcMounts retrieves mountinfo information from a processes' `/proc/<pid>/mountinfo`.\nfunc GetProcMounts(pid int) ([]*MountInfo, error) {\n\tdata, err := util.ReadFileNoStat(fmt.Sprintf(\"/proc/%d/mountinfo\", pid))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn parseMountInfo(data)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/mountstats.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\n// While implementing parsing of /proc/[pid]/mountstats, this blog was used\n// heavily as a reference:\n//   https://utcc.utoronto.ca/~cks/space/blog/linux/NFSMountstatsIndex\n//\n// Special thanks to Chris Siebenmann for all of his posts explaining the\n// various statistics available for NFS.\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\n// Constants shared between multiple functions.\nconst (\n\tdeviceEntryLen = 8\n\n\tfieldBytesLen  = 8\n\tfieldEventsLen = 27\n\n\tstatVersion10 = \"1.0\"\n\tstatVersion11 = \"1.1\"\n\n\tfieldTransport10TCPLen = 10\n\tfieldTransport10UDPLen = 7\n\n\tfieldTransport11TCPLen = 13\n\tfieldTransport11UDPLen = 10\n\n\t// kernel version >= 4.14 MaxLen\n\t// See: https://elixir.bootlin.com/linux/v6.4.8/source/net/sunrpc/xprtrdma/xprt_rdma.h#L393\n\tfieldTransport11RDMAMaxLen = 28\n\n\t// kernel version <= 4.2 MinLen\n\t// See: https://elixir.bootlin.com/linux/v4.2.8/source/net/sunrpc/xprtrdma/xprt_rdma.h#L331\n\tfieldTransport11RDMAMinLen = 20\n)\n\n// A Mount is a device mount parsed from /proc/[pid]/mountstats.\ntype Mount struct {\n\t// Name of the device.\n\tDevice string\n\t// The mount point of the device.\n\tMount string\n\t// The filesystem type used by the device.\n\tType string\n\t// If available additional statistics related to this Mount.\n\t// Use a type assertion to determine if additional statistics are available.\n\tStats MountStats\n}\n\n// A MountStats is a type which contains detailed statistics for a specific\n// type of Mount.\ntype MountStats interface {\n\tmountStats()\n}\n\n// A MountStatsNFS is a MountStats implementation for NFSv3 and v4 mounts.\ntype MountStatsNFS struct {\n\t// The version of statistics provided.\n\tStatVersion string\n\t// The mount options of the NFS mount.\n\tOpts map[string]string\n\t// The age of the NFS mount.\n\tAge time.Duration\n\t// Statistics related to byte counters for various operations.\n\tBytes NFSBytesStats\n\t// Statistics related to various NFS event occurrences.\n\tEvents NFSEventsStats\n\t// Statistics broken down by filesystem operation.\n\tOperations []NFSOperationStats\n\t// Statistics about the NFS RPC transport.\n\tTransport []NFSTransportStats\n}\n\n// mountStats implements MountStats.\nfunc (m MountStatsNFS) mountStats() {}\n\n// A NFSBytesStats contains statistics about the number of bytes read and written\n// by an NFS client to and from an NFS server.\ntype NFSBytesStats struct {\n\t// Number of bytes read using the read() syscall.\n\tRead uint64\n\t// Number of bytes written using the write() syscall.\n\tWrite uint64\n\t// Number of bytes read using the read() syscall in O_DIRECT mode.\n\tDirectRead uint64\n\t// Number of bytes written using the write() syscall in O_DIRECT mode.\n\tDirectWrite uint64\n\t// Number of bytes read from the NFS server, in total.\n\tReadTotal uint64\n\t// Number of bytes written to the NFS server, in total.\n\tWriteTotal uint64\n\t// Number of pages read directly via mmap()'d files.\n\tReadPages uint64\n\t// Number of pages written directly via mmap()'d files.\n\tWritePages uint64\n}\n\n// A NFSEventsStats contains statistics about NFS event occurrences.\ntype NFSEventsStats struct {\n\t// Number of times cached inode attributes are re-validated from the server.\n\tInodeRevalidate uint64\n\t// Number of times cached dentry nodes are re-validated from the server.\n\tDnodeRevalidate uint64\n\t// Number of times an inode cache is cleared.\n\tDataInvalidate uint64\n\t// Number of times cached inode attributes are invalidated.\n\tAttributeInvalidate uint64\n\t// Number of times files or directories have been open()'d.\n\tVFSOpen uint64\n\t// Number of times a directory lookup has occurred.\n\tVFSLookup uint64\n\t// Number of times permissions have been checked.\n\tVFSAccess uint64\n\t// Number of updates (and potential writes) to pages.\n\tVFSUpdatePage uint64\n\t// Number of pages read directly via mmap()'d files.\n\tVFSReadPage uint64\n\t// Number of times a group of pages have been read.\n\tVFSReadPages uint64\n\t// Number of pages written directly via mmap()'d files.\n\tVFSWritePage uint64\n\t// Number of times a group of pages have been written.\n\tVFSWritePages uint64\n\t// Number of times directory entries have been read with getdents().\n\tVFSGetdents uint64\n\t// Number of times attributes have been set on inodes.\n\tVFSSetattr uint64\n\t// Number of pending writes that have been forcefully flushed to the server.\n\tVFSFlush uint64\n\t// Number of times fsync() has been called on directories and files.\n\tVFSFsync uint64\n\t// Number of times locking has been attempted on a file.\n\tVFSLock uint64\n\t// Number of times files have been closed and released.\n\tVFSFileRelease uint64\n\t// Unknown.  Possibly unused.\n\tCongestionWait uint64\n\t// Number of times files have been truncated.\n\tTruncation uint64\n\t// Number of times a file has been grown due to writes beyond its existing end.\n\tWriteExtension uint64\n\t// Number of times a file was removed while still open by another process.\n\tSillyRename uint64\n\t// Number of times the NFS server gave less data than expected while reading.\n\tShortRead uint64\n\t// Number of times the NFS server wrote less data than expected while writing.\n\tShortWrite uint64\n\t// Number of times the NFS server indicated EJUKEBOX; retrieving data from\n\t// offline storage.\n\tJukeboxDelay uint64\n\t// Number of NFS v4.1+ pNFS reads.\n\tPNFSRead uint64\n\t// Number of NFS v4.1+ pNFS writes.\n\tPNFSWrite uint64\n}\n\n// A NFSOperationStats contains statistics for a single operation.\ntype NFSOperationStats struct {\n\t// The name of the operation.\n\tOperation string\n\t// Number of requests performed for this operation.\n\tRequests uint64\n\t// Number of times an actual RPC request has been transmitted for this operation.\n\tTransmissions uint64\n\t// Number of times a request has had a major timeout.\n\tMajorTimeouts uint64\n\t// Number of bytes sent for this operation, including RPC headers and payload.\n\tBytesSent uint64\n\t// Number of bytes received for this operation, including RPC headers and payload.\n\tBytesReceived uint64\n\t// Duration all requests spent queued for transmission before they were sent.\n\tCumulativeQueueMilliseconds uint64\n\t// Duration it took to get a reply back after the request was transmitted.\n\tCumulativeTotalResponseMilliseconds uint64\n\t// Duration from when a request was enqueued to when it was completely handled.\n\tCumulativeTotalRequestMilliseconds uint64\n\t// The count of operations that complete with tk_status < 0.  These statuses usually indicate error conditions.\n\tErrors uint64\n}\n\n// A NFSTransportStats contains statistics for the NFS mount RPC requests and\n// responses.\ntype NFSTransportStats struct {\n\t// The transport protocol used for the NFS mount.\n\tProtocol string\n\t// The local port used for the NFS mount.\n\tPort uint64\n\t// Number of times the client has had to establish a connection from scratch\n\t// to the NFS server.\n\tBind uint64\n\t// Number of times the client has made a TCP connection to the NFS server.\n\tConnect uint64\n\t// Duration (in jiffies, a kernel internal unit of time) the NFS mount has\n\t// spent waiting for connections to the server to be established.\n\tConnectIdleTime uint64\n\t// Duration since the NFS mount last saw any RPC traffic.\n\tIdleTimeSeconds uint64\n\t// Number of RPC requests for this mount sent to the NFS server.\n\tSends uint64\n\t// Number of RPC responses for this mount received from the NFS server.\n\tReceives uint64\n\t// Number of times the NFS server sent a response with a transaction ID\n\t// unknown to this client.\n\tBadTransactionIDs uint64\n\t// A running counter, incremented on each request as the current difference\n\t// ebetween sends and receives.\n\tCumulativeActiveRequests uint64\n\t// A running counter, incremented on each request by the current backlog\n\t// queue size.\n\tCumulativeBacklog uint64\n\n\t// Stats below only available with stat version 1.1.\n\n\t// Maximum number of simultaneously active RPC requests ever used.\n\tMaximumRPCSlotsUsed uint64\n\t// A running counter, incremented on each request as the current size of the\n\t// sending queue.\n\tCumulativeSendingQueue uint64\n\t// A running counter, incremented on each request as the current size of the\n\t// pending queue.\n\tCumulativePendingQueue uint64\n\n\t// Stats below only available with stat version 1.1.\n\t// Transport over RDMA\n\n\t// accessed when sending a call\n\tReadChunkCount   uint64\n\tWriteChunkCount  uint64\n\tReplyChunkCount  uint64\n\tTotalRdmaRequest uint64\n\n\t// rarely accessed error counters\n\tPullupCopyCount      uint64\n\tHardwayRegisterCount uint64\n\tFailedMarshalCount   uint64\n\tBadReplyCount        uint64\n\tMrsRecovered         uint64\n\tMrsOrphaned          uint64\n\tMrsAllocated         uint64\n\tEmptySendctxQ        uint64\n\n\t// accessed when receiving a reply\n\tTotalRdmaReply    uint64\n\tFixupCopyCount    uint64\n\tReplyWaitsForSend uint64\n\tLocalInvNeeded    uint64\n\tNomsgCallCount    uint64\n\tBcallCount        uint64\n}\n\n// parseMountStats parses a /proc/[pid]/mountstats file and returns a slice\n// of Mount structures containing detailed information about each mount.\n// If available, statistics for each mount are parsed as well.\nfunc parseMountStats(r io.Reader) ([]*Mount, error) {\n\tconst (\n\t\tdevice            = \"device\"\n\t\tstatVersionPrefix = \"statvers=\"\n\n\t\tnfs3Type = \"nfs\"\n\t\tnfs4Type = \"nfs4\"\n\t)\n\n\tvar mounts []*Mount\n\n\ts := bufio.NewScanner(r)\n\tfor s.Scan() {\n\t\t// Only look for device entries in this function\n\t\tss := strings.Fields(string(s.Bytes()))\n\t\tif len(ss) == 0 || ss[0] != device {\n\t\t\tcontinue\n\t\t}\n\n\t\tm, err := parseMount(ss)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\t// Does this mount also possess statistics information?\n\t\tif len(ss) > deviceEntryLen {\n\t\t\t// Only NFSv3 and v4 are supported for parsing statistics\n\t\t\tif m.Type != nfs3Type && m.Type != nfs4Type {\n\t\t\t\treturn nil, fmt.Errorf(\"%w: Cannot parse MountStats for %q\", ErrFileParse, m.Type)\n\t\t\t}\n\n\t\t\tstatVersion := strings.TrimPrefix(ss[8], statVersionPrefix)\n\n\t\t\tstats, err := parseMountStatsNFS(s, statVersion)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tm.Stats = stats\n\t\t}\n\n\t\tmounts = append(mounts, m)\n\t}\n\n\treturn mounts, s.Err()\n}\n\n// parseMount parses an entry in /proc/[pid]/mountstats in the format:\n//\n//\tdevice [device] mounted on [mount] with fstype [type]\nfunc parseMount(ss []string) (*Mount, error) {\n\tif len(ss) < deviceEntryLen {\n\t\treturn nil, fmt.Errorf(\"%w: Invalid device %q\", ErrFileParse, ss)\n\t}\n\n\t// Check for specific words appearing at specific indices to ensure\n\t// the format is consistent with what we expect\n\tformat := []struct {\n\t\ti int\n\t\ts string\n\t}{\n\t\t{i: 0, s: \"device\"},\n\t\t{i: 2, s: \"mounted\"},\n\t\t{i: 3, s: \"on\"},\n\t\t{i: 5, s: \"with\"},\n\t\t{i: 6, s: \"fstype\"},\n\t}\n\n\tfor _, f := range format {\n\t\tif ss[f.i] != f.s {\n\t\t\treturn nil, fmt.Errorf(\"%w: Invalid device %q\", ErrFileParse, ss)\n\t\t}\n\t}\n\n\treturn &Mount{\n\t\tDevice: ss[1],\n\t\tMount:  ss[4],\n\t\tType:   ss[7],\n\t}, nil\n}\n\n// parseMountStatsNFS parses a MountStatsNFS by scanning additional information\n// related to NFS statistics.\nfunc parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, error) {\n\t// Field indicators for parsing specific types of data\n\tconst (\n\t\tfieldOpts       = \"opts:\"\n\t\tfieldAge        = \"age:\"\n\t\tfieldBytes      = \"bytes:\"\n\t\tfieldEvents     = \"events:\"\n\t\tfieldPerOpStats = \"per-op\"\n\t\tfieldTransport  = \"xprt:\"\n\t)\n\n\tstats := &MountStatsNFS{\n\t\tStatVersion: statVersion,\n\t}\n\n\tfor s.Scan() {\n\t\tss := strings.Fields(string(s.Bytes()))\n\t\tif len(ss) == 0 {\n\t\t\tbreak\n\t\t}\n\n\t\tswitch ss[0] {\n\t\tcase fieldOpts:\n\t\t\tif len(ss) < 2 {\n\t\t\t\treturn nil, fmt.Errorf(\"%w: Incomplete information for NFS stats: %v\", ErrFileParse, ss)\n\t\t\t}\n\t\t\tif stats.Opts == nil {\n\t\t\t\tstats.Opts = map[string]string{}\n\t\t\t}\n\t\t\tfor _, opt := range strings.Split(ss[1], \",\") {\n\t\t\t\tsplit := strings.Split(opt, \"=\")\n\t\t\t\tif len(split) == 2 {\n\t\t\t\t\tstats.Opts[split[0]] = split[1]\n\t\t\t\t} else {\n\t\t\t\t\tstats.Opts[opt] = \"\"\n\t\t\t\t}\n\t\t\t}\n\t\tcase fieldAge:\n\t\t\tif len(ss) < 2 {\n\t\t\t\treturn nil, fmt.Errorf(\"%w: Incomplete information for NFS stats: %v\", ErrFileParse, ss)\n\t\t\t}\n\t\t\t// Age integer is in seconds\n\t\t\td, err := time.ParseDuration(ss[1] + \"s\")\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tstats.Age = d\n\t\tcase fieldBytes:\n\t\t\tif len(ss) < 2 {\n\t\t\t\treturn nil, fmt.Errorf(\"%w: Incomplete information for NFS stats: %v\", ErrFileParse, ss)\n\t\t\t}\n\t\t\tbstats, err := parseNFSBytesStats(ss[1:])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tstats.Bytes = *bstats\n\t\tcase fieldEvents:\n\t\t\tif len(ss) < 2 {\n\t\t\t\treturn nil, fmt.Errorf(\"%w: Incomplete information for NFS events: %v\", ErrFileParse, ss)\n\t\t\t}\n\t\t\testats, err := parseNFSEventsStats(ss[1:])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tstats.Events = *estats\n\t\tcase fieldTransport:\n\t\t\tif len(ss) < 3 {\n\t\t\t\treturn nil, fmt.Errorf(\"%w: Incomplete information for NFS transport stats: %v\", ErrFileParse, ss)\n\t\t\t}\n\n\t\t\ttstats, err := parseNFSTransportStats(ss[1:], statVersion)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tstats.Transport = append(stats.Transport, *tstats)\n\t\t}\n\n\t\t// When encountering \"per-operation statistics\", we must break this\n\t\t// loop and parse them separately to ensure we can terminate parsing\n\t\t// before reaching another device entry; hence why this 'if' statement\n\t\t// is not just another switch case\n\t\tif ss[0] == fieldPerOpStats {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif err := s.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// NFS per-operation stats appear last before the next device entry\n\tperOpStats, err := parseNFSOperationStats(s)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tstats.Operations = perOpStats\n\n\treturn stats, nil\n}\n\n// parseNFSBytesStats parses a NFSBytesStats line using an input set of\n// integer fields.\nfunc parseNFSBytesStats(ss []string) (*NFSBytesStats, error) {\n\tif len(ss) != fieldBytesLen {\n\t\treturn nil, fmt.Errorf(\"%w: Invalid NFS bytes stats: %v\", ErrFileParse, ss)\n\t}\n\n\tns := make([]uint64, 0, fieldBytesLen)\n\tfor _, s := range ss {\n\t\tn, err := strconv.ParseUint(s, 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tns = append(ns, n)\n\t}\n\n\treturn &NFSBytesStats{\n\t\tRead:        ns[0],\n\t\tWrite:       ns[1],\n\t\tDirectRead:  ns[2],\n\t\tDirectWrite: ns[3],\n\t\tReadTotal:   ns[4],\n\t\tWriteTotal:  ns[5],\n\t\tReadPages:   ns[6],\n\t\tWritePages:  ns[7],\n\t}, nil\n}\n\n// parseNFSEventsStats parses a NFSEventsStats line using an input set of\n// integer fields.\nfunc parseNFSEventsStats(ss []string) (*NFSEventsStats, error) {\n\tif len(ss) != fieldEventsLen {\n\t\treturn nil, fmt.Errorf(\"%w: invalid NFS events stats: %v\", ErrFileParse, ss)\n\t}\n\n\tns := make([]uint64, 0, fieldEventsLen)\n\tfor _, s := range ss {\n\t\tn, err := strconv.ParseUint(s, 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tns = append(ns, n)\n\t}\n\n\treturn &NFSEventsStats{\n\t\tInodeRevalidate:     ns[0],\n\t\tDnodeRevalidate:     ns[1],\n\t\tDataInvalidate:      ns[2],\n\t\tAttributeInvalidate: ns[3],\n\t\tVFSOpen:             ns[4],\n\t\tVFSLookup:           ns[5],\n\t\tVFSAccess:           ns[6],\n\t\tVFSUpdatePage:       ns[7],\n\t\tVFSReadPage:         ns[8],\n\t\tVFSReadPages:        ns[9],\n\t\tVFSWritePage:        ns[10],\n\t\tVFSWritePages:       ns[11],\n\t\tVFSGetdents:         ns[12],\n\t\tVFSSetattr:          ns[13],\n\t\tVFSFlush:            ns[14],\n\t\tVFSFsync:            ns[15],\n\t\tVFSLock:             ns[16],\n\t\tVFSFileRelease:      ns[17],\n\t\tCongestionWait:      ns[18],\n\t\tTruncation:          ns[19],\n\t\tWriteExtension:      ns[20],\n\t\tSillyRename:         ns[21],\n\t\tShortRead:           ns[22],\n\t\tShortWrite:          ns[23],\n\t\tJukeboxDelay:        ns[24],\n\t\tPNFSRead:            ns[25],\n\t\tPNFSWrite:           ns[26],\n\t}, nil\n}\n\n// parseNFSOperationStats parses a slice of NFSOperationStats by scanning\n// additional information about per-operation statistics until an empty\n// line is reached.\nfunc parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {\n\tconst (\n\t\t// Minimum number of expected fields in each per-operation statistics set\n\t\tminFields = 9\n\t)\n\n\tvar ops []NFSOperationStats\n\n\tfor s.Scan() {\n\t\tss := strings.Fields(string(s.Bytes()))\n\t\tif len(ss) == 0 {\n\t\t\t// Must break when reading a blank line after per-operation stats to\n\t\t\t// enable top-level function to parse the next device entry\n\t\t\tbreak\n\t\t}\n\n\t\tif len(ss) < minFields {\n\t\t\treturn nil, fmt.Errorf(\"%w: invalid NFS per-operations stats: %v\", ErrFileParse, ss)\n\t\t}\n\n\t\t// Skip string operation name for integers\n\t\tns := make([]uint64, 0, minFields-1)\n\t\tfor _, st := range ss[1:] {\n\t\t\tn, err := strconv.ParseUint(st, 10, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tns = append(ns, n)\n\t\t}\n\t\topStats := NFSOperationStats{\n\t\t\tOperation:                           strings.TrimSuffix(ss[0], \":\"),\n\t\t\tRequests:                            ns[0],\n\t\t\tTransmissions:                       ns[1],\n\t\t\tMajorTimeouts:                       ns[2],\n\t\t\tBytesSent:                           ns[3],\n\t\t\tBytesReceived:                       ns[4],\n\t\t\tCumulativeQueueMilliseconds:         ns[5],\n\t\t\tCumulativeTotalResponseMilliseconds: ns[6],\n\t\t\tCumulativeTotalRequestMilliseconds:  ns[7],\n\t\t}\n\n\t\tif len(ns) > 8 {\n\t\t\topStats.Errors = ns[8]\n\t\t}\n\n\t\tops = append(ops, opStats)\n\t}\n\n\treturn ops, s.Err()\n}\n\n// parseNFSTransportStats parses a NFSTransportStats line using an input set of\n// integer fields matched to a specific stats version.\nfunc parseNFSTransportStats(ss []string, statVersion string) (*NFSTransportStats, error) {\n\t// Extract the protocol field. It is the only string value in the line\n\tprotocol := ss[0]\n\tss = ss[1:]\n\n\tswitch statVersion {\n\tcase statVersion10:\n\t\tvar expectedLength int\n\t\tif protocol == \"tcp\" {\n\t\t\texpectedLength = fieldTransport10TCPLen\n\t\t} else if protocol == \"udp\" {\n\t\t\texpectedLength = fieldTransport10UDPLen\n\t\t} else {\n\t\t\treturn nil, fmt.Errorf(\"%w: Invalid NFS protocol \\\"%s\\\" in stats 1.0 statement: %v\", ErrFileParse, protocol, ss)\n\t\t}\n\t\tif len(ss) != expectedLength {\n\t\t\treturn nil, fmt.Errorf(\"%w: Invalid NFS transport stats 1.0 statement: %v\", ErrFileParse, ss)\n\t\t}\n\tcase statVersion11:\n\t\tvar expectedLength int\n\t\tif protocol == \"tcp\" {\n\t\t\texpectedLength = fieldTransport11TCPLen\n\t\t} else if protocol == \"udp\" {\n\t\t\texpectedLength = fieldTransport11UDPLen\n\t\t} else if protocol == \"rdma\" {\n\t\t\texpectedLength = fieldTransport11RDMAMinLen\n\t\t} else {\n\t\t\treturn nil, fmt.Errorf(\"%w: invalid NFS protocol \\\"%s\\\" in stats 1.1 statement: %v\", ErrFileParse, protocol, ss)\n\t\t}\n\t\tif (len(ss) != expectedLength && (protocol == \"tcp\" || protocol == \"udp\")) ||\n\t\t\t(protocol == \"rdma\" && len(ss) < expectedLength) {\n\t\t\treturn nil, fmt.Errorf(\"%w: invalid NFS transport stats 1.1 statement: %v, protocol: %v\", ErrFileParse, ss, protocol)\n\t\t}\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"%w: Unrecognized NFS transport stats version: %q, protocol: %v\", ErrFileParse, statVersion, protocol)\n\t}\n\n\t// Allocate enough for v1.1 stats since zero value for v1.1 stats will be okay\n\t// in a v1.0 response. Since the stat length is bigger for TCP stats, we use\n\t// the TCP length here.\n\t//\n\t// Note: slice length must be set to length of v1.1 stats to avoid a panic when\n\t// only v1.0 stats are present.\n\t// See: https://github.com/prometheus/node_exporter/issues/571.\n\t//\n\t// Note: NFS Over RDMA slice length is fieldTransport11RDMAMaxLen\n\tns := make([]uint64, fieldTransport11RDMAMaxLen+3)\n\tfor i, s := range ss {\n\t\tn, err := strconv.ParseUint(s, 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tns[i] = n\n\t}\n\n\t// The fields differ depending on the transport protocol (TCP or UDP)\n\t// From https://utcc.utoronto.ca/%7Ecks/space/blog/linux/NFSMountstatsXprt\n\t//\n\t// For the udp RPC transport there is no connection count, connect idle time,\n\t// or idle time (fields #3, #4, and #5); all other fields are the same. So\n\t// we set them to 0 here.\n\tif protocol == \"udp\" {\n\t\tns = append(ns[:2], append(make([]uint64, 3), ns[2:]...)...)\n\t} else if protocol == \"tcp\" {\n\t\tns = append(ns[:fieldTransport11TCPLen], make([]uint64, fieldTransport11RDMAMaxLen-fieldTransport11TCPLen+3)...)\n\t} else if protocol == \"rdma\" {\n\t\tns = append(ns[:fieldTransport10TCPLen], append(make([]uint64, 3), ns[fieldTransport10TCPLen:]...)...)\n\t}\n\n\treturn &NFSTransportStats{\n\t\t// NFS xprt over tcp or udp\n\t\tProtocol:                 protocol,\n\t\tPort:                     ns[0],\n\t\tBind:                     ns[1],\n\t\tConnect:                  ns[2],\n\t\tConnectIdleTime:          ns[3],\n\t\tIdleTimeSeconds:          ns[4],\n\t\tSends:                    ns[5],\n\t\tReceives:                 ns[6],\n\t\tBadTransactionIDs:        ns[7],\n\t\tCumulativeActiveRequests: ns[8],\n\t\tCumulativeBacklog:        ns[9],\n\n\t\t// NFS xprt over tcp or udp\n\t\t// And statVersion 1.1\n\t\tMaximumRPCSlotsUsed:    ns[10],\n\t\tCumulativeSendingQueue: ns[11],\n\t\tCumulativePendingQueue: ns[12],\n\n\t\t// NFS xprt over rdma\n\t\t// And stat Version 1.1\n\t\tReadChunkCount:       ns[13],\n\t\tWriteChunkCount:      ns[14],\n\t\tReplyChunkCount:      ns[15],\n\t\tTotalRdmaRequest:     ns[16],\n\t\tPullupCopyCount:      ns[17],\n\t\tHardwayRegisterCount: ns[18],\n\t\tFailedMarshalCount:   ns[19],\n\t\tBadReplyCount:        ns[20],\n\t\tMrsRecovered:         ns[21],\n\t\tMrsOrphaned:          ns[22],\n\t\tMrsAllocated:         ns[23],\n\t\tEmptySendctxQ:        ns[24],\n\t\tTotalRdmaReply:       ns[25],\n\t\tFixupCopyCount:       ns[26],\n\t\tReplyWaitsForSend:    ns[27],\n\t\tLocalInvNeeded:       ns[28],\n\t\tNomsgCallCount:       ns[29],\n\t\tBcallCount:           ns[30],\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/net_conntrackstat.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// A ConntrackStatEntry represents one line from net/stat/nf_conntrack\n// and contains netfilter conntrack statistics at one CPU core.\ntype ConntrackStatEntry struct {\n\tEntries       uint64\n\tSearched      uint64\n\tFound         uint64\n\tNew           uint64\n\tInvalid       uint64\n\tIgnore        uint64\n\tDelete        uint64\n\tDeleteList    uint64\n\tInsert        uint64\n\tInsertFailed  uint64\n\tDrop          uint64\n\tEarlyDrop     uint64\n\tSearchRestart uint64\n}\n\n// ConntrackStat retrieves netfilter's conntrack statistics, split by CPU cores.\nfunc (fs FS) ConntrackStat() ([]ConntrackStatEntry, error) {\n\treturn readConntrackStat(fs.proc.Path(\"net\", \"stat\", \"nf_conntrack\"))\n}\n\n// Parses a slice of ConntrackStatEntries from the given filepath.\nfunc readConntrackStat(path string) ([]ConntrackStatEntry, error) {\n\t// This file is small and can be read with one syscall.\n\tb, err := util.ReadFileNoStat(path)\n\tif err != nil {\n\t\t// Do not wrap this error so the caller can detect os.IsNotExist and\n\t\t// similar conditions.\n\t\treturn nil, err\n\t}\n\n\tstat, err := parseConntrackStat(bytes.NewReader(b))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Cannot read file: %v: %w\", ErrFileRead, path, err)\n\t}\n\n\treturn stat, nil\n}\n\n// Reads the contents of a conntrack statistics file and parses a slice of ConntrackStatEntries.\nfunc parseConntrackStat(r io.Reader) ([]ConntrackStatEntry, error) {\n\tvar entries []ConntrackStatEntry\n\n\tscanner := bufio.NewScanner(r)\n\tscanner.Scan()\n\tfor scanner.Scan() {\n\t\tfields := strings.Fields(scanner.Text())\n\t\tconntrackEntry, err := parseConntrackStatEntry(fields)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tentries = append(entries, *conntrackEntry)\n\t}\n\n\treturn entries, nil\n}\n\n// Parses a ConntrackStatEntry from given array of fields.\nfunc parseConntrackStatEntry(fields []string) (*ConntrackStatEntry, error) {\n\tentries, err := util.ParseHexUint64s(fields)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Cannot parse entry: %d: %w\", ErrFileParse, entries, err)\n\t}\n\tnumEntries := len(entries)\n\tif numEntries < 16 || numEntries > 17 {\n\t\treturn nil,\n\t\t\tfmt.Errorf(\"%w: invalid conntrackstat entry, invalid number of fields: %d\", ErrFileParse, numEntries)\n\t}\n\n\tstats := &ConntrackStatEntry{\n\t\tEntries:      *entries[0],\n\t\tSearched:     *entries[1],\n\t\tFound:        *entries[2],\n\t\tNew:          *entries[3],\n\t\tInvalid:      *entries[4],\n\t\tIgnore:       *entries[5],\n\t\tDelete:       *entries[6],\n\t\tDeleteList:   *entries[7],\n\t\tInsert:       *entries[8],\n\t\tInsertFailed: *entries[9],\n\t\tDrop:         *entries[10],\n\t\tEarlyDrop:    *entries[11],\n\t}\n\n\t// Ignore missing search_restart on Linux < 2.6.35.\n\tif numEntries == 17 {\n\t\tstats.SearchRestart = *entries[16]\n\t}\n\n\treturn stats, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/net_dev.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"os\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// NetDevLine is single line parsed from /proc/net/dev or /proc/[pid]/net/dev.\ntype NetDevLine struct {\n\tName         string `json:\"name\"`          // The name of the interface.\n\tRxBytes      uint64 `json:\"rx_bytes\"`      // Cumulative count of bytes received.\n\tRxPackets    uint64 `json:\"rx_packets\"`    // Cumulative count of packets received.\n\tRxErrors     uint64 `json:\"rx_errors\"`     // Cumulative count of receive errors encountered.\n\tRxDropped    uint64 `json:\"rx_dropped\"`    // Cumulative count of packets dropped while receiving.\n\tRxFIFO       uint64 `json:\"rx_fifo\"`       // Cumulative count of FIFO buffer errors.\n\tRxFrame      uint64 `json:\"rx_frame\"`      // Cumulative count of packet framing errors.\n\tRxCompressed uint64 `json:\"rx_compressed\"` // Cumulative count of compressed packets received by the device driver.\n\tRxMulticast  uint64 `json:\"rx_multicast\"`  // Cumulative count of multicast frames received by the device driver.\n\tTxBytes      uint64 `json:\"tx_bytes\"`      // Cumulative count of bytes transmitted.\n\tTxPackets    uint64 `json:\"tx_packets\"`    // Cumulative count of packets transmitted.\n\tTxErrors     uint64 `json:\"tx_errors\"`     // Cumulative count of transmit errors encountered.\n\tTxDropped    uint64 `json:\"tx_dropped\"`    // Cumulative count of packets dropped while transmitting.\n\tTxFIFO       uint64 `json:\"tx_fifo\"`       // Cumulative count of FIFO buffer errors.\n\tTxCollisions uint64 `json:\"tx_collisions\"` // Cumulative count of collisions detected on the interface.\n\tTxCarrier    uint64 `json:\"tx_carrier\"`    // Cumulative count of carrier losses detected by the device driver.\n\tTxCompressed uint64 `json:\"tx_compressed\"` // Cumulative count of compressed packets transmitted by the device driver.\n}\n\n// NetDev is parsed from /proc/net/dev or /proc/[pid]/net/dev. The map keys\n// are interface names.\ntype NetDev map[string]NetDevLine\n\n// NetDev returns kernel/system statistics read from /proc/net/dev.\nfunc (fs FS) NetDev() (NetDev, error) {\n\treturn newNetDev(fs.proc.Path(\"net/dev\"))\n}\n\n// NetDev returns kernel/system statistics read from /proc/[pid]/net/dev.\nfunc (p Proc) NetDev() (NetDev, error) {\n\treturn newNetDev(p.path(\"net/dev\"))\n}\n\n// newNetDev creates a new NetDev from the contents of the given file.\nfunc newNetDev(file string) (NetDev, error) {\n\tf, err := os.Open(file)\n\tif err != nil {\n\t\treturn NetDev{}, err\n\t}\n\tdefer f.Close()\n\n\tnetDev := NetDev{}\n\ts := bufio.NewScanner(f)\n\tfor n := 0; s.Scan(); n++ {\n\t\t// Skip the 2 header lines.\n\t\tif n < 2 {\n\t\t\tcontinue\n\t\t}\n\n\t\tline, err := netDev.parseLine(s.Text())\n\t\tif err != nil {\n\t\t\treturn netDev, err\n\t\t}\n\n\t\tnetDev[line.Name] = *line\n\t}\n\n\treturn netDev, s.Err()\n}\n\n// parseLine parses a single line from the /proc/net/dev file. Header lines\n// must be filtered prior to calling this method.\nfunc (netDev NetDev) parseLine(rawLine string) (*NetDevLine, error) {\n\tidx := strings.LastIndex(rawLine, \":\")\n\tif idx == -1 {\n\t\treturn nil, errors.New(\"invalid net/dev line, missing colon\")\n\t}\n\tfields := strings.Fields(strings.TrimSpace(rawLine[idx+1:]))\n\n\tvar err error\n\tline := &NetDevLine{}\n\n\t// Interface Name\n\tline.Name = strings.TrimSpace(rawLine[:idx])\n\tif line.Name == \"\" {\n\t\treturn nil, errors.New(\"invalid net/dev line, empty interface name\")\n\t}\n\n\t// RX\n\tline.RxBytes, err = strconv.ParseUint(fields[0], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tline.RxPackets, err = strconv.ParseUint(fields[1], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tline.RxErrors, err = strconv.ParseUint(fields[2], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tline.RxDropped, err = strconv.ParseUint(fields[3], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tline.RxFIFO, err = strconv.ParseUint(fields[4], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tline.RxFrame, err = strconv.ParseUint(fields[5], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tline.RxCompressed, err = strconv.ParseUint(fields[6], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tline.RxMulticast, err = strconv.ParseUint(fields[7], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// TX\n\tline.TxBytes, err = strconv.ParseUint(fields[8], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tline.TxPackets, err = strconv.ParseUint(fields[9], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tline.TxErrors, err = strconv.ParseUint(fields[10], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tline.TxDropped, err = strconv.ParseUint(fields[11], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tline.TxFIFO, err = strconv.ParseUint(fields[12], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tline.TxCollisions, err = strconv.ParseUint(fields[13], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tline.TxCarrier, err = strconv.ParseUint(fields[14], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tline.TxCompressed, err = strconv.ParseUint(fields[15], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn line, nil\n}\n\n// Total aggregates the values across interfaces and returns a new NetDevLine.\n// The Name field will be a sorted comma separated list of interface names.\nfunc (netDev NetDev) Total() NetDevLine {\n\ttotal := NetDevLine{}\n\n\tnames := make([]string, 0, len(netDev))\n\tfor _, ifc := range netDev {\n\t\tnames = append(names, ifc.Name)\n\t\ttotal.RxBytes += ifc.RxBytes\n\t\ttotal.RxPackets += ifc.RxPackets\n\t\ttotal.RxErrors += ifc.RxErrors\n\t\ttotal.RxDropped += ifc.RxDropped\n\t\ttotal.RxFIFO += ifc.RxFIFO\n\t\ttotal.RxFrame += ifc.RxFrame\n\t\ttotal.RxCompressed += ifc.RxCompressed\n\t\ttotal.RxMulticast += ifc.RxMulticast\n\t\ttotal.TxBytes += ifc.TxBytes\n\t\ttotal.TxPackets += ifc.TxPackets\n\t\ttotal.TxErrors += ifc.TxErrors\n\t\ttotal.TxDropped += ifc.TxDropped\n\t\ttotal.TxFIFO += ifc.TxFIFO\n\t\ttotal.TxCollisions += ifc.TxCollisions\n\t\ttotal.TxCarrier += ifc.TxCarrier\n\t\ttotal.TxCompressed += ifc.TxCompressed\n\t}\n\tsort.Strings(names)\n\ttotal.Name = strings.Join(names, \", \")\n\n\treturn total\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/net_ip_socket.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nconst (\n\t// readLimit is used by io.LimitReader while reading the content of the\n\t// /proc/net/udp{,6} files. The number of lines inside such a file is dynamic\n\t// as each line represents a single used socket.\n\t// In theory, the number of available sockets is 65535 (2^16 - 1) per IP.\n\t// With e.g. 150 Byte per line and the maximum number of 65535,\n\t// the reader needs to handle 150 Byte * 65535 =~ 10 MB for a single IP.\n\treadLimit = 4294967296 // Byte -> 4 GiB\n)\n\n// This contains generic data structures for both udp and tcp sockets.\ntype (\n\t// NetIPSocket represents the contents of /proc/net/{t,u}dp{,6} file without the header.\n\tNetIPSocket []*netIPSocketLine\n\n\t// NetIPSocketSummary provides already computed values like the total queue lengths or\n\t// the total number of used sockets. In contrast to NetIPSocket it does not collect\n\t// the parsed lines into a slice.\n\tNetIPSocketSummary struct {\n\t\t// TxQueueLength shows the total queue length of all parsed tx_queue lengths.\n\t\tTxQueueLength uint64\n\t\t// RxQueueLength shows the total queue length of all parsed rx_queue lengths.\n\t\tRxQueueLength uint64\n\t\t// UsedSockets shows the total number of parsed lines representing the\n\t\t// number of used sockets.\n\t\tUsedSockets uint64\n\t\t// Drops shows the total number of dropped packets of all UPD sockets.\n\t\tDrops *uint64\n\t}\n\n\t// netIPSocketLine represents the fields parsed from a single line\n\t// in /proc/net/{t,u}dp{,6}. Fields which are not used by IPSocket are skipped.\n\t// Drops is non-nil for udp{,6}, but nil for tcp{,6}.\n\t// For the proc file format details, see https://linux.die.net/man/5/proc.\n\tnetIPSocketLine struct {\n\t\tSl        uint64\n\t\tLocalAddr net.IP\n\t\tLocalPort uint64\n\t\tRemAddr   net.IP\n\t\tRemPort   uint64\n\t\tSt        uint64\n\t\tTxQueue   uint64\n\t\tRxQueue   uint64\n\t\tUID       uint64\n\t\tInode     uint64\n\t\tDrops     *uint64\n\t}\n)\n\nfunc newNetIPSocket(file string) (NetIPSocket, error) {\n\tf, err := os.Open(file)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer f.Close()\n\n\tvar netIPSocket NetIPSocket\n\tisUDP := strings.Contains(file, \"udp\")\n\n\tlr := io.LimitReader(f, readLimit)\n\ts := bufio.NewScanner(lr)\n\ts.Scan() // skip first line with headers\n\tfor s.Scan() {\n\t\tfields := strings.Fields(s.Text())\n\t\tline, err := parseNetIPSocketLine(fields, isUDP)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tnetIPSocket = append(netIPSocket, line)\n\t}\n\tif err := s.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn netIPSocket, nil\n}\n\n// newNetIPSocketSummary creates a new NetIPSocket{,6} from the contents of the given file.\nfunc newNetIPSocketSummary(file string) (*NetIPSocketSummary, error) {\n\tf, err := os.Open(file)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer f.Close()\n\n\tvar netIPSocketSummary NetIPSocketSummary\n\tvar udpPacketDrops uint64\n\tisUDP := strings.Contains(file, \"udp\")\n\n\tlr := io.LimitReader(f, readLimit)\n\ts := bufio.NewScanner(lr)\n\ts.Scan() // skip first line with headers\n\tfor s.Scan() {\n\t\tfields := strings.Fields(s.Text())\n\t\tline, err := parseNetIPSocketLine(fields, isUDP)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tnetIPSocketSummary.TxQueueLength += line.TxQueue\n\t\tnetIPSocketSummary.RxQueueLength += line.RxQueue\n\t\tnetIPSocketSummary.UsedSockets++\n\t\tif isUDP {\n\t\t\tudpPacketDrops += *line.Drops\n\t\t\tnetIPSocketSummary.Drops = &udpPacketDrops\n\t\t}\n\t}\n\tif err := s.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &netIPSocketSummary, nil\n}\n\n// the /proc/net/{t,u}dp{,6} files are network byte order for ipv4 and for ipv6 the address is four words consisting of four bytes each. In each of those four words the four bytes are written in reverse order.\n\nfunc parseIP(hexIP string) (net.IP, error) {\n\tvar byteIP []byte\n\tbyteIP, err := hex.DecodeString(hexIP)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Cannot parse socket field in %q: %w\", ErrFileParse, hexIP, err)\n\t}\n\tswitch len(byteIP) {\n\tcase 4:\n\t\treturn net.IP{byteIP[3], byteIP[2], byteIP[1], byteIP[0]}, nil\n\tcase 16:\n\t\ti := net.IP{\n\t\t\tbyteIP[3], byteIP[2], byteIP[1], byteIP[0],\n\t\t\tbyteIP[7], byteIP[6], byteIP[5], byteIP[4],\n\t\t\tbyteIP[11], byteIP[10], byteIP[9], byteIP[8],\n\t\t\tbyteIP[15], byteIP[14], byteIP[13], byteIP[12],\n\t\t}\n\t\treturn i, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"%w: Unable to parse IP %s: %v\", ErrFileParse, hexIP, nil)\n\t}\n}\n\n// parseNetIPSocketLine parses a single line, represented by a list of fields.\nfunc parseNetIPSocketLine(fields []string, isUDP bool) (*netIPSocketLine, error) {\n\tline := &netIPSocketLine{}\n\tif len(fields) < 10 {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"%w: Less than 10 columns found %q\",\n\t\t\tErrFileParse,\n\t\t\tstrings.Join(fields, \" \"),\n\t\t)\n\t}\n\tvar err error // parse error\n\n\t// sl\n\ts := strings.Split(fields[0], \":\")\n\tif len(s) != 2 {\n\t\treturn nil, fmt.Errorf(\"%w: Unable to parse sl field in line %q\", ErrFileParse, fields[0])\n\t}\n\n\tif line.Sl, err = strconv.ParseUint(s[0], 0, 64); err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Unable to parse sl field in %q: %w\", ErrFileParse, line.Sl, err)\n\t}\n\t// local_address\n\tl := strings.Split(fields[1], \":\")\n\tif len(l) != 2 {\n\t\treturn nil, fmt.Errorf(\"%w: Unable to parse local_address field in %q\", ErrFileParse, fields[1])\n\t}\n\tif line.LocalAddr, err = parseIP(l[0]); err != nil {\n\t\treturn nil, err\n\t}\n\tif line.LocalPort, err = strconv.ParseUint(l[1], 16, 64); err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Unable to parse local_address port value line %q: %w\", ErrFileParse, line.LocalPort, err)\n\t}\n\n\t// remote_address\n\tr := strings.Split(fields[2], \":\")\n\tif len(r) != 2 {\n\t\treturn nil, fmt.Errorf(\"%w: Unable to parse rem_address field in %q\", ErrFileParse, fields[1])\n\t}\n\tif line.RemAddr, err = parseIP(r[0]); err != nil {\n\t\treturn nil, err\n\t}\n\tif line.RemPort, err = strconv.ParseUint(r[1], 16, 64); err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Cannot parse rem_address port value in %q: %w\", ErrFileParse, line.RemPort, err)\n\t}\n\n\t// st\n\tif line.St, err = strconv.ParseUint(fields[3], 16, 64); err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Cannot parse st value in %q: %w\", ErrFileParse, line.St, err)\n\t}\n\n\t// tx_queue and rx_queue\n\tq := strings.Split(fields[4], \":\")\n\tif len(q) != 2 {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"%w: Missing colon for tx/rx queues in socket line %q\",\n\t\t\tErrFileParse,\n\t\t\tfields[4],\n\t\t)\n\t}\n\tif line.TxQueue, err = strconv.ParseUint(q[0], 16, 64); err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Cannot parse tx_queue value in %q: %w\", ErrFileParse, line.TxQueue, err)\n\t}\n\tif line.RxQueue, err = strconv.ParseUint(q[1], 16, 64); err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Cannot parse trx_queue value in %q: %w\", ErrFileParse, line.RxQueue, err)\n\t}\n\n\t// uid\n\tif line.UID, err = strconv.ParseUint(fields[7], 0, 64); err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Cannot parse UID value in %q: %w\", ErrFileParse, line.UID, err)\n\t}\n\n\t// inode\n\tif line.Inode, err = strconv.ParseUint(fields[9], 0, 64); err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Cannot parse inode value in %q: %w\", ErrFileParse, line.Inode, err)\n\t}\n\n\t// drops\n\tif isUDP {\n\t\tdrops, err := strconv.ParseUint(fields[12], 0, 64)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: Cannot parse drops value in %q: %w\", ErrFileParse, drops, err)\n\t\t}\n\t\tline.Drops = &drops\n\t}\n\n\treturn line, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/net_protocols.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// NetProtocolStats stores the contents from /proc/net/protocols.\ntype NetProtocolStats map[string]NetProtocolStatLine\n\n// NetProtocolStatLine contains a single line parsed from /proc/net/protocols. We\n// only care about the first six columns as the rest are not likely to change\n// and only serve to provide a set of capabilities for each protocol.\ntype NetProtocolStatLine struct {\n\tName         string // 0 The name of the protocol\n\tSize         uint64 // 1 The size, in bytes, of a given protocol structure. e.g. sizeof(struct tcp_sock) or sizeof(struct unix_sock)\n\tSockets      int64  // 2 Number of sockets in use by this protocol\n\tMemory       int64  // 3 Number of 4KB pages allocated by all sockets of this protocol\n\tPressure     int    // 4 This is either yes, no, or NI (not implemented). For the sake of simplicity we treat NI as not experiencing memory pressure.\n\tMaxHeader    uint64 // 5 Protocol specific max header size\n\tSlab         bool   // 6 Indicates whether or not memory is allocated from the SLAB\n\tModuleName   string // 7 The name of the module that implemented this protocol or \"kernel\" if not from a module\n\tCapabilities NetProtocolCapabilities\n}\n\n// NetProtocolCapabilities contains a list of capabilities for each protocol.\ntype NetProtocolCapabilities struct {\n\tClose               bool // 8\n\tConnect             bool // 9\n\tDisconnect          bool // 10\n\tAccept              bool // 11\n\tIoCtl               bool // 12\n\tInit                bool // 13\n\tDestroy             bool // 14\n\tShutdown            bool // 15\n\tSetSockOpt          bool // 16\n\tGetSockOpt          bool // 17\n\tSendMsg             bool // 18\n\tRecvMsg             bool // 19\n\tSendPage            bool // 20\n\tBind                bool // 21\n\tBacklogRcv          bool // 22\n\tHash                bool // 23\n\tUnHash              bool // 24\n\tGetPort             bool // 25\n\tEnterMemoryPressure bool // 26\n}\n\n// NetProtocols reads stats from /proc/net/protocols and returns a map of\n// PortocolStatLine entries. As of this writing no official Linux Documentation\n// exists, however the source is fairly self-explanatory and the format seems\n// stable since its introduction in 2.6.12-rc2\n// Linux 2.6.12-rc2 - https://elixir.bootlin.com/linux/v2.6.12-rc2/source/net/core/sock.c#L1452\n// Linux 5.10 - https://elixir.bootlin.com/linux/v5.10.4/source/net/core/sock.c#L3586\nfunc (fs FS) NetProtocols() (NetProtocolStats, error) {\n\tdata, err := util.ReadFileNoStat(fs.proc.Path(\"net/protocols\"))\n\tif err != nil {\n\t\treturn NetProtocolStats{}, err\n\t}\n\treturn parseNetProtocols(bufio.NewScanner(bytes.NewReader(data)))\n}\n\nfunc parseNetProtocols(s *bufio.Scanner) (NetProtocolStats, error) {\n\tnps := NetProtocolStats{}\n\n\t// Skip the header line\n\ts.Scan()\n\n\tfor s.Scan() {\n\t\tline, err := nps.parseLine(s.Text())\n\t\tif err != nil {\n\t\t\treturn NetProtocolStats{}, err\n\t\t}\n\n\t\tnps[line.Name] = *line\n\t}\n\treturn nps, nil\n}\n\nfunc (ps NetProtocolStats) parseLine(rawLine string) (*NetProtocolStatLine, error) {\n\tline := &NetProtocolStatLine{Capabilities: NetProtocolCapabilities{}}\n\tvar err error\n\tconst enabled = \"yes\"\n\tconst disabled = \"no\"\n\n\tfields := strings.Fields(rawLine)\n\tline.Name = fields[0]\n\tline.Size, err = strconv.ParseUint(fields[1], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tline.Sockets, err = strconv.ParseInt(fields[2], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tline.Memory, err = strconv.ParseInt(fields[3], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif fields[4] == enabled {\n\t\tline.Pressure = 1\n\t} else if fields[4] == disabled {\n\t\tline.Pressure = 0\n\t} else {\n\t\tline.Pressure = -1\n\t}\n\tline.MaxHeader, err = strconv.ParseUint(fields[5], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif fields[6] == enabled {\n\t\tline.Slab = true\n\t} else if fields[6] == disabled {\n\t\tline.Slab = false\n\t} else {\n\t\treturn nil, fmt.Errorf(\"%w: capability for protocol: %s\", ErrFileParse, line.Name)\n\t}\n\tline.ModuleName = fields[7]\n\n\terr = line.Capabilities.parseCapabilities(fields[8:])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn line, nil\n}\n\nfunc (pc *NetProtocolCapabilities) parseCapabilities(capabilities []string) error {\n\t// The capabilities are all bools so we can loop over to map them\n\tcapabilityFields := [...]*bool{\n\t\t&pc.Close,\n\t\t&pc.Connect,\n\t\t&pc.Disconnect,\n\t\t&pc.Accept,\n\t\t&pc.IoCtl,\n\t\t&pc.Init,\n\t\t&pc.Destroy,\n\t\t&pc.Shutdown,\n\t\t&pc.SetSockOpt,\n\t\t&pc.GetSockOpt,\n\t\t&pc.SendMsg,\n\t\t&pc.RecvMsg,\n\t\t&pc.SendPage,\n\t\t&pc.Bind,\n\t\t&pc.BacklogRcv,\n\t\t&pc.Hash,\n\t\t&pc.UnHash,\n\t\t&pc.GetPort,\n\t\t&pc.EnterMemoryPressure,\n\t}\n\n\tfor i := 0; i < len(capabilities); i++ {\n\t\tif capabilities[i] == \"y\" {\n\t\t\t*capabilityFields[i] = true\n\t\t} else if capabilities[i] == \"n\" {\n\t\t\t*capabilityFields[i] = false\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"%w: capability block for protocol: position %d\", ErrFileParse, i)\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/net_route.go",
    "content": "// Copyright 2023 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\nconst (\n\tblackholeRepresentation string = \"*\"\n\tblackholeIfaceName      string = \"blackhole\"\n\trouteLineColumns        int    = 11\n)\n\n// A NetRouteLine represents one line from net/route.\ntype NetRouteLine struct {\n\tIface       string\n\tDestination uint32\n\tGateway     uint32\n\tFlags       uint32\n\tRefCnt      uint32\n\tUse         uint32\n\tMetric      uint32\n\tMask        uint32\n\tMTU         uint32\n\tWindow      uint32\n\tIRTT        uint32\n}\n\nfunc (fs FS) NetRoute() ([]NetRouteLine, error) {\n\treturn readNetRoute(fs.proc.Path(\"net\", \"route\"))\n}\n\nfunc readNetRoute(path string) ([]NetRouteLine, error) {\n\tb, err := util.ReadFileNoStat(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\troutelines, err := parseNetRoute(bytes.NewReader(b))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read net route from %s: %w\", path, err)\n\t}\n\treturn routelines, nil\n}\n\nfunc parseNetRoute(r io.Reader) ([]NetRouteLine, error) {\n\tvar routelines []NetRouteLine\n\n\tscanner := bufio.NewScanner(r)\n\tscanner.Scan()\n\tfor scanner.Scan() {\n\t\tfields := strings.Fields(scanner.Text())\n\t\trouteline, err := parseNetRouteLine(fields)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\troutelines = append(routelines, *routeline)\n\t}\n\treturn routelines, nil\n}\n\nfunc parseNetRouteLine(fields []string) (*NetRouteLine, error) {\n\tif len(fields) != routeLineColumns {\n\t\treturn nil, fmt.Errorf(\"invalid routeline, num of digits: %d\", len(fields))\n\t}\n\tiface := fields[0]\n\tif iface == blackholeRepresentation {\n\t\tiface = blackholeIfaceName\n\t}\n\tdestination, err := strconv.ParseUint(fields[1], 16, 32)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tgateway, err := strconv.ParseUint(fields[2], 16, 32)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tflags, err := strconv.ParseUint(fields[3], 10, 32)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\trefcnt, err := strconv.ParseUint(fields[4], 10, 32)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tuse, err := strconv.ParseUint(fields[5], 10, 32)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tmetric, err := strconv.ParseUint(fields[6], 10, 32)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tmask, err := strconv.ParseUint(fields[7], 16, 32)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tmtu, err := strconv.ParseUint(fields[8], 10, 32)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\twindow, err := strconv.ParseUint(fields[9], 10, 32)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tirtt, err := strconv.ParseUint(fields[10], 10, 32)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\trouteline := &NetRouteLine{\n\t\tIface:       iface,\n\t\tDestination: uint32(destination),\n\t\tGateway:     uint32(gateway),\n\t\tFlags:       uint32(flags),\n\t\tRefCnt:      uint32(refcnt),\n\t\tUse:         uint32(use),\n\t\tMetric:      uint32(metric),\n\t\tMask:        uint32(mask),\n\t\tMTU:         uint32(mtu),\n\t\tWindow:      uint32(window),\n\t\tIRTT:        uint32(irtt),\n\t}\n\treturn routeline, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/net_sockstat.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// A NetSockstat contains the output of /proc/net/sockstat{,6} for IPv4 or IPv6,\n// respectively.\ntype NetSockstat struct {\n\t// Used is non-nil for IPv4 sockstat results, but nil for IPv6.\n\tUsed      *int\n\tProtocols []NetSockstatProtocol\n}\n\n// A NetSockstatProtocol contains statistics about a given socket protocol.\n// Pointer fields indicate that the value may or may not be present on any\n// given protocol.\ntype NetSockstatProtocol struct {\n\tProtocol string\n\tInUse    int\n\tOrphan   *int\n\tTW       *int\n\tAlloc    *int\n\tMem      *int\n\tMemory   *int\n}\n\n// NetSockstat retrieves IPv4 socket statistics.\nfunc (fs FS) NetSockstat() (*NetSockstat, error) {\n\treturn readSockstat(fs.proc.Path(\"net\", \"sockstat\"))\n}\n\n// NetSockstat6 retrieves IPv6 socket statistics.\n//\n// If IPv6 is disabled on this kernel, the returned error can be checked with\n// os.IsNotExist.\nfunc (fs FS) NetSockstat6() (*NetSockstat, error) {\n\treturn readSockstat(fs.proc.Path(\"net\", \"sockstat6\"))\n}\n\n// readSockstat opens and parses a NetSockstat from the input file.\nfunc readSockstat(name string) (*NetSockstat, error) {\n\t// This file is small and can be read with one syscall.\n\tb, err := util.ReadFileNoStat(name)\n\tif err != nil {\n\t\t// Do not wrap this error so the caller can detect os.IsNotExist and\n\t\t// similar conditions.\n\t\treturn nil, err\n\t}\n\n\tstat, err := parseSockstat(bytes.NewReader(b))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: sockstats from %q: %w\", ErrFileRead, name, err)\n\t}\n\n\treturn stat, nil\n}\n\n// parseSockstat reads the contents of a sockstat file and parses a NetSockstat.\nfunc parseSockstat(r io.Reader) (*NetSockstat, error) {\n\tvar stat NetSockstat\n\ts := bufio.NewScanner(r)\n\tfor s.Scan() {\n\t\t// Expect a minimum of a protocol and one key/value pair.\n\t\tfields := strings.Split(s.Text(), \" \")\n\t\tif len(fields) < 3 {\n\t\t\treturn nil, fmt.Errorf(\"%w: Malformed sockstat line: %q\", ErrFileParse, s.Text())\n\t\t}\n\n\t\t// The remaining fields are key/value pairs.\n\t\tkvs, err := parseSockstatKVs(fields[1:])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: sockstat key/value pairs from %q: %w\", ErrFileParse, s.Text(), err)\n\t\t}\n\n\t\t// The first field is the protocol. We must trim its colon suffix.\n\t\tproto := strings.TrimSuffix(fields[0], \":\")\n\t\tswitch proto {\n\t\tcase \"sockets\":\n\t\t\t// Special case: IPv4 has a sockets \"used\" key/value pair that we\n\t\t\t// embed at the top level of the structure.\n\t\t\tused := kvs[\"used\"]\n\t\t\tstat.Used = &used\n\t\tdefault:\n\t\t\t// Parse all other lines as individual protocols.\n\t\t\tnsp := parseSockstatProtocol(kvs)\n\t\t\tnsp.Protocol = proto\n\t\t\tstat.Protocols = append(stat.Protocols, nsp)\n\t\t}\n\t}\n\n\tif err := s.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &stat, nil\n}\n\n// parseSockstatKVs parses a string slice into a map of key/value pairs.\nfunc parseSockstatKVs(kvs []string) (map[string]int, error) {\n\tif len(kvs)%2 != 0 {\n\t\treturn nil, fmt.Errorf(\"%w:: Odd number of fields in key/value pairs %q\", ErrFileParse, kvs)\n\t}\n\n\t// Iterate two values at a time to gather key/value pairs.\n\tout := make(map[string]int, len(kvs)/2)\n\tfor i := 0; i < len(kvs); i += 2 {\n\t\tvp := util.NewValueParser(kvs[i+1])\n\t\tout[kvs[i]] = vp.Int()\n\n\t\tif err := vp.Err(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn out, nil\n}\n\n// parseSockstatProtocol parses a NetSockstatProtocol from the input kvs map.\nfunc parseSockstatProtocol(kvs map[string]int) NetSockstatProtocol {\n\tvar nsp NetSockstatProtocol\n\tfor k, v := range kvs {\n\t\t// Capture the range variable to ensure we get unique pointers for\n\t\t// each of the optional fields.\n\t\tv := v\n\t\tswitch k {\n\t\tcase \"inuse\":\n\t\t\tnsp.InUse = v\n\t\tcase \"orphan\":\n\t\t\tnsp.Orphan = &v\n\t\tcase \"tw\":\n\t\t\tnsp.TW = &v\n\t\tcase \"alloc\":\n\t\t\tnsp.Alloc = &v\n\t\tcase \"mem\":\n\t\t\tnsp.Mem = &v\n\t\tcase \"memory\":\n\t\t\tnsp.Memory = &v\n\t\t}\n\t}\n\n\treturn nsp\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/net_softnet.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// For the proc file format details,\n// See:\n// * Linux 2.6.23 https://elixir.bootlin.com/linux/v2.6.23/source/net/core/dev.c#L2343\n// * Linux 2.6.39 https://elixir.bootlin.com/linux/v2.6.39/source/net/core/dev.c#L4086\n// * Linux 4.18 https://elixir.bootlin.com/linux/v4.18/source/net/core/net-procfs.c#L162\n// * Linux 5.14 https://elixir.bootlin.com/linux/v5.14/source/net/core/net-procfs.c#L169\n\n// SoftnetStat contains a single row of data from /proc/net/softnet_stat.\ntype SoftnetStat struct {\n\t// Number of processed packets.\n\tProcessed uint32\n\t// Number of dropped packets.\n\tDropped uint32\n\t// Number of times processing packets ran out of quota.\n\tTimeSqueezed uint32\n\t// Number of collision occur while obtaining device lock while transmitting.\n\tCPUCollision uint32\n\t// Number of times cpu woken up received_rps.\n\tReceivedRps uint32\n\t// number of times flow limit has been reached.\n\tFlowLimitCount uint32\n\t// Softnet backlog status.\n\tSoftnetBacklogLen uint32\n\t// CPU id owning this softnet_data.\n\tIndex uint32\n\t// softnet_data's Width.\n\tWidth int\n}\n\nvar softNetProcFile = \"net/softnet_stat\"\n\n// NetSoftnetStat reads data from /proc/net/softnet_stat.\nfunc (fs FS) NetSoftnetStat() ([]SoftnetStat, error) {\n\tb, err := util.ReadFileNoStat(fs.proc.Path(softNetProcFile))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tentries, err := parseSoftnet(bytes.NewReader(b))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: /proc/net/softnet_stat: %w\", ErrFileParse, err)\n\t}\n\n\treturn entries, nil\n}\n\nfunc parseSoftnet(r io.Reader) ([]SoftnetStat, error) {\n\tconst minColumns = 9\n\n\ts := bufio.NewScanner(r)\n\n\tvar stats []SoftnetStat\n\tcpuIndex := 0\n\tfor s.Scan() {\n\t\tcolumns := strings.Fields(s.Text())\n\t\twidth := len(columns)\n\t\tsoftnetStat := SoftnetStat{}\n\n\t\tif width < minColumns {\n\t\t\treturn nil, fmt.Errorf(\"%w: detected %d columns, but expected at least %d\", ErrFileParse, width, minColumns)\n\t\t}\n\n\t\t// Linux 2.6.23 https://elixir.bootlin.com/linux/v2.6.23/source/net/core/dev.c#L2347\n\t\tif width >= minColumns {\n\t\t\tus, err := parseHexUint32s(columns[0:9])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tsoftnetStat.Processed = us[0]\n\t\t\tsoftnetStat.Dropped = us[1]\n\t\t\tsoftnetStat.TimeSqueezed = us[2]\n\t\t\tsoftnetStat.CPUCollision = us[8]\n\t\t}\n\n\t\t// Linux 2.6.39 https://elixir.bootlin.com/linux/v2.6.39/source/net/core/dev.c#L4086\n\t\tif width >= 10 {\n\t\t\tus, err := parseHexUint32s(columns[9:10])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tsoftnetStat.ReceivedRps = us[0]\n\t\t}\n\n\t\t// Linux 4.18 https://elixir.bootlin.com/linux/v4.18/source/net/core/net-procfs.c#L162\n\t\tif width >= 11 {\n\t\t\tus, err := parseHexUint32s(columns[10:11])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tsoftnetStat.FlowLimitCount = us[0]\n\t\t}\n\n\t\t// Linux 5.14 https://elixir.bootlin.com/linux/v5.14/source/net/core/net-procfs.c#L169\n\t\tif width >= 13 {\n\t\t\tus, err := parseHexUint32s(columns[11:13])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tsoftnetStat.SoftnetBacklogLen = us[0]\n\t\t\tsoftnetStat.Index = us[1]\n\t\t} else {\n\t\t\t// For older kernels, create the Index based on the scan line number.\n\t\t\tsoftnetStat.Index = uint32(cpuIndex)\n\t\t}\n\t\tsoftnetStat.Width = width\n\t\tstats = append(stats, softnetStat)\n\t\tcpuIndex++\n\t}\n\n\treturn stats, nil\n}\n\nfunc parseHexUint32s(ss []string) ([]uint32, error) {\n\tus := make([]uint32, 0, len(ss))\n\tfor _, s := range ss {\n\t\tu, err := strconv.ParseUint(s, 16, 32)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tus = append(us, uint32(u))\n\t}\n\n\treturn us, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/net_tcp.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\ntype (\n\t// NetTCP represents the contents of /proc/net/tcp{,6} file without the header.\n\tNetTCP []*netIPSocketLine\n\n\t// NetTCPSummary provides already computed values like the total queue lengths or\n\t// the total number of used sockets. In contrast to NetTCP it does not collect\n\t// the parsed lines into a slice.\n\tNetTCPSummary NetIPSocketSummary\n)\n\n// NetTCP returns the IPv4 kernel/networking statistics for TCP datagrams\n// read from /proc/net/tcp.\nfunc (fs FS) NetTCP() (NetTCP, error) {\n\treturn newNetTCP(fs.proc.Path(\"net/tcp\"))\n}\n\n// NetTCP6 returns the IPv6 kernel/networking statistics for TCP datagrams\n// read from /proc/net/tcp6.\nfunc (fs FS) NetTCP6() (NetTCP, error) {\n\treturn newNetTCP(fs.proc.Path(\"net/tcp6\"))\n}\n\n// NetTCPSummary returns already computed statistics like the total queue lengths\n// for TCP datagrams read from /proc/net/tcp.\nfunc (fs FS) NetTCPSummary() (*NetTCPSummary, error) {\n\treturn newNetTCPSummary(fs.proc.Path(\"net/tcp\"))\n}\n\n// NetTCP6Summary returns already computed statistics like the total queue lengths\n// for TCP datagrams read from /proc/net/tcp6.\nfunc (fs FS) NetTCP6Summary() (*NetTCPSummary, error) {\n\treturn newNetTCPSummary(fs.proc.Path(\"net/tcp6\"))\n}\n\n// newNetTCP creates a new NetTCP{,6} from the contents of the given file.\nfunc newNetTCP(file string) (NetTCP, error) {\n\tn, err := newNetIPSocket(file)\n\tn1 := NetTCP(n)\n\treturn n1, err\n}\n\nfunc newNetTCPSummary(file string) (*NetTCPSummary, error) {\n\tn, err := newNetIPSocketSummary(file)\n\tif n == nil {\n\t\treturn nil, err\n\t}\n\tn1 := NetTCPSummary(*n)\n\treturn &n1, err\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/net_tls_stat.go",
    "content": "// Copyright 2023 Prometheus Team\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// TLSStat struct represents data in /proc/net/tls_stat.\n// See https://docs.kernel.org/networking/tls.html#statistics\ntype TLSStat struct {\n\t// number of TX sessions currently installed where host handles cryptography\n\tTLSCurrTxSw int\n\t// number of RX sessions currently installed where host handles cryptography\n\tTLSCurrRxSw int\n\t// number of TX sessions currently installed where NIC handles cryptography\n\tTLSCurrTxDevice int\n\t// number of RX sessions currently installed where NIC handles cryptography\n\tTLSCurrRxDevice int\n\t//number of TX sessions opened with host cryptography\n\tTLSTxSw int\n\t//number of RX sessions opened with host cryptography\n\tTLSRxSw int\n\t// number of TX sessions opened with NIC cryptography\n\tTLSTxDevice int\n\t// number of RX sessions opened with NIC cryptography\n\tTLSRxDevice int\n\t// record decryption failed (e.g. due to incorrect authentication tag)\n\tTLSDecryptError int\n\t//  number of RX resyncs sent to NICs handling cryptography\n\tTLSRxDeviceResync int\n\t// number of RX records which had to be re-decrypted due to TLS_RX_EXPECT_NO_PAD mis-prediction. Note that this counter will also increment for non-data records.\n\tTLSDecryptRetry int\n\t// number of data RX records which had to be re-decrypted due to TLS_RX_EXPECT_NO_PAD mis-prediction.\n\tTLSRxNoPadViolation int\n}\n\n// NewTLSStat reads the tls_stat statistics.\nfunc NewTLSStat() (TLSStat, error) {\n\tfs, err := NewFS(DefaultMountPoint)\n\tif err != nil {\n\t\treturn TLSStat{}, err\n\t}\n\n\treturn fs.NewTLSStat()\n}\n\n// NewTLSStat reads the tls_stat statistics.\nfunc (fs FS) NewTLSStat() (TLSStat, error) {\n\tfile, err := os.Open(fs.proc.Path(\"net/tls_stat\"))\n\tif err != nil {\n\t\treturn TLSStat{}, err\n\t}\n\tdefer file.Close()\n\n\tvar (\n\t\ttlsstat = TLSStat{}\n\t\ts       = bufio.NewScanner(file)\n\t)\n\n\tfor s.Scan() {\n\t\tfields := strings.Fields(s.Text())\n\n\t\tif len(fields) != 2 {\n\t\t\treturn TLSStat{}, fmt.Errorf(\"%w: %q line %q\", ErrFileParse, file.Name(), s.Text())\n\t\t}\n\n\t\tname := fields[0]\n\t\tvalue, err := strconv.Atoi(fields[1])\n\t\tif err != nil {\n\t\t\treturn TLSStat{}, err\n\t\t}\n\n\t\tswitch name {\n\t\tcase \"TlsCurrTxSw\":\n\t\t\ttlsstat.TLSCurrTxSw = value\n\t\tcase \"TlsCurrRxSw\":\n\t\t\ttlsstat.TLSCurrRxSw = value\n\t\tcase \"TlsCurrTxDevice\":\n\t\t\ttlsstat.TLSCurrTxDevice = value\n\t\tcase \"TlsCurrRxDevice\":\n\t\t\ttlsstat.TLSCurrRxDevice = value\n\t\tcase \"TlsTxSw\":\n\t\t\ttlsstat.TLSTxSw = value\n\t\tcase \"TlsRxSw\":\n\t\t\ttlsstat.TLSRxSw = value\n\t\tcase \"TlsTxDevice\":\n\t\t\ttlsstat.TLSTxDevice = value\n\t\tcase \"TlsRxDevice\":\n\t\t\ttlsstat.TLSRxDevice = value\n\t\tcase \"TlsDecryptError\":\n\t\t\ttlsstat.TLSDecryptError = value\n\t\tcase \"TlsRxDeviceResync\":\n\t\t\ttlsstat.TLSRxDeviceResync = value\n\t\tcase \"TlsDecryptRetry\":\n\t\t\ttlsstat.TLSDecryptRetry = value\n\t\tcase \"TlsRxNoPadViolation\":\n\t\t\ttlsstat.TLSRxNoPadViolation = value\n\t\t}\n\n\t}\n\n\treturn tlsstat, s.Err()\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/net_udp.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\ntype (\n\t// NetUDP represents the contents of /proc/net/udp{,6} file without the header.\n\tNetUDP []*netIPSocketLine\n\n\t// NetUDPSummary provides already computed values like the total queue lengths or\n\t// the total number of used sockets. In contrast to NetUDP it does not collect\n\t// the parsed lines into a slice.\n\tNetUDPSummary NetIPSocketSummary\n)\n\n// NetUDP returns the IPv4 kernel/networking statistics for UDP datagrams\n// read from /proc/net/udp.\nfunc (fs FS) NetUDP() (NetUDP, error) {\n\treturn newNetUDP(fs.proc.Path(\"net/udp\"))\n}\n\n// NetUDP6 returns the IPv6 kernel/networking statistics for UDP datagrams\n// read from /proc/net/udp6.\nfunc (fs FS) NetUDP6() (NetUDP, error) {\n\treturn newNetUDP(fs.proc.Path(\"net/udp6\"))\n}\n\n// NetUDPSummary returns already computed statistics like the total queue lengths\n// for UDP datagrams read from /proc/net/udp.\nfunc (fs FS) NetUDPSummary() (*NetUDPSummary, error) {\n\treturn newNetUDPSummary(fs.proc.Path(\"net/udp\"))\n}\n\n// NetUDP6Summary returns already computed statistics like the total queue lengths\n// for UDP datagrams read from /proc/net/udp6.\nfunc (fs FS) NetUDP6Summary() (*NetUDPSummary, error) {\n\treturn newNetUDPSummary(fs.proc.Path(\"net/udp6\"))\n}\n\n// newNetUDP creates a new NetUDP{,6} from the contents of the given file.\nfunc newNetUDP(file string) (NetUDP, error) {\n\tn, err := newNetIPSocket(file)\n\tn1 := NetUDP(n)\n\treturn n1, err\n}\n\nfunc newNetUDPSummary(file string) (*NetUDPSummary, error) {\n\tn, err := newNetIPSocketSummary(file)\n\tif n == nil {\n\t\treturn nil, err\n\t}\n\tn1 := NetUDPSummary(*n)\n\treturn &n1, err\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/net_unix.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// For the proc file format details,\n// see https://elixir.bootlin.com/linux/v4.17/source/net/unix/af_unix.c#L2815\n// and https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/net.h#L48.\n\n// Constants for the various /proc/net/unix enumerations.\n// TODO: match against x/sys/unix or similar?\nconst (\n\tnetUnixTypeStream    = 1\n\tnetUnixTypeDgram     = 2\n\tnetUnixTypeSeqpacket = 5\n\n\tnetUnixFlagDefault = 0\n\tnetUnixFlagListen  = 1 << 16\n\n\tnetUnixStateUnconnected  = 1\n\tnetUnixStateConnecting   = 2\n\tnetUnixStateConnected    = 3\n\tnetUnixStateDisconnected = 4\n)\n\n// NetUNIXType is the type of the type field.\ntype NetUNIXType uint64\n\n// NetUNIXFlags is the type of the flags field.\ntype NetUNIXFlags uint64\n\n// NetUNIXState is the type of the state field.\ntype NetUNIXState uint64\n\n// NetUNIXLine represents a line of /proc/net/unix.\ntype NetUNIXLine struct {\n\tKernelPtr string\n\tRefCount  uint64\n\tProtocol  uint64\n\tFlags     NetUNIXFlags\n\tType      NetUNIXType\n\tState     NetUNIXState\n\tInode     uint64\n\tPath      string\n}\n\n// NetUNIX holds the data read from /proc/net/unix.\ntype NetUNIX struct {\n\tRows []*NetUNIXLine\n}\n\n// NetUNIX returns data read from /proc/net/unix.\nfunc (fs FS) NetUNIX() (*NetUNIX, error) {\n\treturn readNetUNIX(fs.proc.Path(\"net/unix\"))\n}\n\n// readNetUNIX reads data in /proc/net/unix format from the specified file.\nfunc readNetUNIX(file string) (*NetUNIX, error) {\n\t// This file could be quite large and a streaming read is desirable versus\n\t// reading the entire contents at once.\n\tf, err := os.Open(file)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer f.Close()\n\n\treturn parseNetUNIX(f)\n}\n\n// parseNetUNIX creates a NetUnix structure from the incoming stream.\nfunc parseNetUNIX(r io.Reader) (*NetUNIX, error) {\n\t// Begin scanning by checking for the existence of Inode.\n\ts := bufio.NewScanner(r)\n\ts.Scan()\n\n\t// From the man page of proc(5), it does not contain an Inode field,\n\t// but in actually it exists. This code works for both cases.\n\thasInode := strings.Contains(s.Text(), \"Inode\")\n\n\t// Expect a minimum number of fields, but Inode and Path are optional:\n\t// Num       RefCount Protocol Flags    Type St Inode Path\n\tminFields := 6\n\tif hasInode {\n\t\tminFields++\n\t}\n\n\tvar nu NetUNIX\n\tfor s.Scan() {\n\t\tline := s.Text()\n\t\titem, err := nu.parseLine(line, hasInode, minFields)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: /proc/net/unix encountered data %q: %w\", ErrFileParse, line, err)\n\t\t}\n\n\t\tnu.Rows = append(nu.Rows, item)\n\t}\n\n\tif err := s.Err(); err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: /proc/net/unix encountered data: %w\", ErrFileParse, err)\n\t}\n\n\treturn &nu, nil\n}\n\nfunc (u *NetUNIX) parseLine(line string, hasInode bool, min int) (*NetUNIXLine, error) {\n\tfields := strings.Fields(line)\n\n\tl := len(fields)\n\tif l < min {\n\t\treturn nil, fmt.Errorf(\"%w: expected at least %d fields but got %d\", ErrFileParse, min, l)\n\t}\n\n\t// Field offsets are as follows:\n\t// Num       RefCount Protocol Flags    Type St Inode Path\n\n\tkernelPtr := strings.TrimSuffix(fields[0], \":\")\n\n\tusers, err := u.parseUsers(fields[1])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: ref count %q: %w\", ErrFileParse, fields[1], err)\n\t}\n\n\tflags, err := u.parseFlags(fields[3])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Unable to parse flags %q: %w\", ErrFileParse, fields[3], err)\n\t}\n\n\ttyp, err := u.parseType(fields[4])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Failed to parse type %q: %w\", ErrFileParse, fields[4], err)\n\t}\n\n\tstate, err := u.parseState(fields[5])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Failed to parse state %q: %w\", ErrFileParse, fields[5], err)\n\t}\n\n\tvar inode uint64\n\tif hasInode {\n\t\tinode, err = u.parseInode(fields[6])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w failed to parse inode %q: %w\", ErrFileParse, fields[6], err)\n\t\t}\n\t}\n\n\tn := &NetUNIXLine{\n\t\tKernelPtr: kernelPtr,\n\t\tRefCount:  users,\n\t\tType:      typ,\n\t\tFlags:     flags,\n\t\tState:     state,\n\t\tInode:     inode,\n\t}\n\n\t// Path field is optional.\n\tif l > min {\n\t\t// Path occurs at either index 6 or 7 depending on whether inode is\n\t\t// already present.\n\t\tpathIdx := 7\n\t\tif !hasInode {\n\t\t\tpathIdx--\n\t\t}\n\n\t\tn.Path = fields[pathIdx]\n\t}\n\n\treturn n, nil\n}\n\nfunc (u NetUNIX) parseUsers(s string) (uint64, error) {\n\treturn strconv.ParseUint(s, 16, 32)\n}\n\nfunc (u NetUNIX) parseType(s string) (NetUNIXType, error) {\n\ttyp, err := strconv.ParseUint(s, 16, 16)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn NetUNIXType(typ), nil\n}\n\nfunc (u NetUNIX) parseFlags(s string) (NetUNIXFlags, error) {\n\tflags, err := strconv.ParseUint(s, 16, 32)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn NetUNIXFlags(flags), nil\n}\n\nfunc (u NetUNIX) parseState(s string) (NetUNIXState, error) {\n\tst, err := strconv.ParseInt(s, 16, 8)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn NetUNIXState(st), nil\n}\n\nfunc (u NetUNIX) parseInode(s string) (uint64, error) {\n\treturn strconv.ParseUint(s, 10, 64)\n}\n\nfunc (t NetUNIXType) String() string {\n\tswitch t {\n\tcase netUnixTypeStream:\n\t\treturn \"stream\"\n\tcase netUnixTypeDgram:\n\t\treturn \"dgram\"\n\tcase netUnixTypeSeqpacket:\n\t\treturn \"seqpacket\"\n\t}\n\treturn \"unknown\"\n}\n\nfunc (f NetUNIXFlags) String() string {\n\tswitch f {\n\tcase netUnixFlagListen:\n\t\treturn \"listen\"\n\tdefault:\n\t\treturn \"default\"\n\t}\n}\n\nfunc (s NetUNIXState) String() string {\n\tswitch s {\n\tcase netUnixStateUnconnected:\n\t\treturn \"unconnected\"\n\tcase netUnixStateConnecting:\n\t\treturn \"connecting\"\n\tcase netUnixStateConnected:\n\t\treturn \"connected\"\n\tcase netUnixStateDisconnected:\n\t\treturn \"disconnected\"\n\t}\n\treturn \"unknown\"\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/net_wireless.go",
    "content": "// Copyright 2023 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// Wireless models the content of /proc/net/wireless.\ntype Wireless struct {\n\tName string\n\n\t// Status is the current 4-digit hex value status of the interface.\n\tStatus uint64\n\n\t// QualityLink is the link quality.\n\tQualityLink int\n\n\t// QualityLevel is the signal gain (dBm).\n\tQualityLevel int\n\n\t// QualityNoise is the signal noise baseline (dBm).\n\tQualityNoise int\n\n\t// DiscardedNwid is the number of discarded packets with wrong nwid/essid.\n\tDiscardedNwid int\n\n\t// DiscardedCrypt is the number of discarded packets with wrong code/decode (WEP).\n\tDiscardedCrypt int\n\n\t// DiscardedFrag is the number of discarded packets that can't perform MAC reassembly.\n\tDiscardedFrag int\n\n\t// DiscardedRetry is the number of discarded packets that reached max MAC retries.\n\tDiscardedRetry int\n\n\t// DiscardedMisc is the number of discarded packets for other reasons.\n\tDiscardedMisc int\n\n\t// MissedBeacon is the number of missed beacons/superframe.\n\tMissedBeacon int\n}\n\n// Wireless returns kernel wireless statistics.\nfunc (fs FS) Wireless() ([]*Wireless, error) {\n\tb, err := util.ReadFileNoStat(fs.proc.Path(\"net/wireless\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tm, err := parseWireless(bytes.NewReader(b))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: wireless: %w\", ErrFileParse, err)\n\t}\n\n\treturn m, nil\n}\n\n// parseWireless parses the contents of /proc/net/wireless.\n/*\nInter-| sta-|   Quality        |   Discarded packets               | Missed | WE\nface | tus | link level noise |  nwid  crypt   frag  retry   misc | beacon | 22\n eth1: 0000    5.  -256.  -10.       0      1      0     3      0        0\n eth2: 0000    5.  -256.  -20.       0      2      0     4      0        0\n*/\nfunc parseWireless(r io.Reader) ([]*Wireless, error) {\n\tvar (\n\t\tinterfaces []*Wireless\n\t\tscanner    = bufio.NewScanner(r)\n\t)\n\n\tfor n := 0; scanner.Scan(); n++ {\n\t\t// Skip the 2 header lines.\n\t\tif n < 2 {\n\t\t\tcontinue\n\t\t}\n\n\t\tline := scanner.Text()\n\n\t\tparts := strings.Split(line, \":\")\n\t\tif len(parts) != 2 {\n\t\t\treturn nil, fmt.Errorf(\"%w: expected 2 parts after splitting line by ':', got %d for line %q\", ErrFileParse, len(parts), line)\n\t\t}\n\n\t\tname := strings.TrimSpace(parts[0])\n\t\tstats := strings.Fields(parts[1])\n\n\t\tif len(stats) < 10 {\n\t\t\treturn nil, fmt.Errorf(\"%w: invalid number of fields in line %d, expected 10+, got %d: %q\", ErrFileParse, n, len(stats), line)\n\t\t}\n\n\t\tstatus, err := strconv.ParseUint(stats[0], 16, 16)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: invalid status in line %d: %q\", ErrFileParse, n, line)\n\t\t}\n\n\t\tqlink, err := strconv.Atoi(strings.TrimSuffix(stats[1], \".\"))\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: parse Quality:link as integer %q: %w\", ErrFileParse, qlink, err)\n\t\t}\n\n\t\tqlevel, err := strconv.Atoi(strings.TrimSuffix(stats[2], \".\"))\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: Quality:level as integer %q: %w\", ErrFileParse, qlevel, err)\n\t\t}\n\n\t\tqnoise, err := strconv.Atoi(strings.TrimSuffix(stats[3], \".\"))\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: Quality:noise as integer %q: %w\", ErrFileParse, qnoise, err)\n\t\t}\n\n\t\tdnwid, err := strconv.Atoi(stats[4])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: Discarded:nwid as integer %q: %w\", ErrFileParse, dnwid, err)\n\t\t}\n\n\t\tdcrypt, err := strconv.Atoi(stats[5])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: Discarded:crypt as integer %q: %w\", ErrFileParse, dcrypt, err)\n\t\t}\n\n\t\tdfrag, err := strconv.Atoi(stats[6])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: Discarded:frag as integer %q: %w\", ErrFileParse, dfrag, err)\n\t\t}\n\n\t\tdretry, err := strconv.Atoi(stats[7])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: Discarded:retry as integer %q: %w\", ErrFileParse, dretry, err)\n\t\t}\n\n\t\tdmisc, err := strconv.Atoi(stats[8])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: Discarded:misc as integer %q: %w\", ErrFileParse, dmisc, err)\n\t\t}\n\n\t\tmbeacon, err := strconv.Atoi(stats[9])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: Missed:beacon as integer %q: %w\", ErrFileParse, mbeacon, err)\n\t\t}\n\n\t\tw := &Wireless{\n\t\t\tName:           name,\n\t\t\tStatus:         status,\n\t\t\tQualityLink:    qlink,\n\t\t\tQualityLevel:   qlevel,\n\t\t\tQualityNoise:   qnoise,\n\t\t\tDiscardedNwid:  dnwid,\n\t\t\tDiscardedCrypt: dcrypt,\n\t\t\tDiscardedFrag:  dfrag,\n\t\t\tDiscardedRetry: dretry,\n\t\t\tDiscardedMisc:  dmisc,\n\t\t\tMissedBeacon:   mbeacon,\n\t\t}\n\n\t\tinterfaces = append(interfaces, w)\n\t}\n\n\tif err := scanner.Err(); err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Failed to scan /proc/net/wireless: %w\", ErrFileRead, err)\n\t}\n\n\treturn interfaces, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/net_xfrm.go",
    "content": "// Copyright 2017 Prometheus Team\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// XfrmStat models the contents of /proc/net/xfrm_stat.\ntype XfrmStat struct {\n\t// All errors which are not matched by other\n\tXfrmInError int\n\t// No buffer is left\n\tXfrmInBufferError int\n\t// Header Error\n\tXfrmInHdrError int\n\t// No state found\n\t// i.e. either inbound SPI, address, or IPSEC protocol at SA is wrong\n\tXfrmInNoStates int\n\t// Transformation protocol specific error\n\t// e.g. SA Key is wrong\n\tXfrmInStateProtoError int\n\t// Transformation mode specific error\n\tXfrmInStateModeError int\n\t// Sequence error\n\t// e.g. sequence number is out of window\n\tXfrmInStateSeqError int\n\t// State is expired\n\tXfrmInStateExpired int\n\t// State has mismatch option\n\t// e.g. UDP encapsulation type is mismatched\n\tXfrmInStateMismatch int\n\t// State is invalid\n\tXfrmInStateInvalid int\n\t// No matching template for states\n\t// e.g. Inbound SAs are correct but SP rule is wrong\n\tXfrmInTmplMismatch int\n\t// No policy is found for states\n\t// e.g. Inbound SAs are correct but no SP is found\n\tXfrmInNoPols int\n\t// Policy discards\n\tXfrmInPolBlock int\n\t// Policy error\n\tXfrmInPolError int\n\t// All errors which are not matched by others\n\tXfrmOutError int\n\t// Bundle generation error\n\tXfrmOutBundleGenError int\n\t// Bundle check error\n\tXfrmOutBundleCheckError int\n\t// No state was found\n\tXfrmOutNoStates int\n\t// Transformation protocol specific error\n\tXfrmOutStateProtoError int\n\t// Transportation mode specific error\n\tXfrmOutStateModeError int\n\t// Sequence error\n\t// i.e sequence number overflow\n\tXfrmOutStateSeqError int\n\t// State is expired\n\tXfrmOutStateExpired int\n\t// Policy discads\n\tXfrmOutPolBlock int\n\t// Policy is dead\n\tXfrmOutPolDead int\n\t// Policy Error\n\tXfrmOutPolError int\n\t// Forward routing of a packet is not allowed\n\tXfrmFwdHdrError int\n\t// State is invalid, perhaps expired\n\tXfrmOutStateInvalid int\n\t// State hasn’t been fully acquired before use\n\tXfrmAcquireError int\n}\n\n// NewXfrmStat reads the xfrm_stat statistics.\nfunc NewXfrmStat() (XfrmStat, error) {\n\tfs, err := NewFS(DefaultMountPoint)\n\tif err != nil {\n\t\treturn XfrmStat{}, err\n\t}\n\n\treturn fs.NewXfrmStat()\n}\n\n// NewXfrmStat reads the xfrm_stat statistics from the 'proc' filesystem.\nfunc (fs FS) NewXfrmStat() (XfrmStat, error) {\n\tfile, err := os.Open(fs.proc.Path(\"net/xfrm_stat\"))\n\tif err != nil {\n\t\treturn XfrmStat{}, err\n\t}\n\tdefer file.Close()\n\n\tvar (\n\t\tx = XfrmStat{}\n\t\ts = bufio.NewScanner(file)\n\t)\n\n\tfor s.Scan() {\n\t\tfields := strings.Fields(s.Text())\n\n\t\tif len(fields) != 2 {\n\t\t\treturn XfrmStat{}, fmt.Errorf(\"%w: %q line %q\", ErrFileParse, file.Name(), s.Text())\n\t\t}\n\n\t\tname := fields[0]\n\t\tvalue, err := strconv.Atoi(fields[1])\n\t\tif err != nil {\n\t\t\treturn XfrmStat{}, err\n\t\t}\n\n\t\tswitch name {\n\t\tcase \"XfrmInError\":\n\t\t\tx.XfrmInError = value\n\t\tcase \"XfrmInBufferError\":\n\t\t\tx.XfrmInBufferError = value\n\t\tcase \"XfrmInHdrError\":\n\t\t\tx.XfrmInHdrError = value\n\t\tcase \"XfrmInNoStates\":\n\t\t\tx.XfrmInNoStates = value\n\t\tcase \"XfrmInStateProtoError\":\n\t\t\tx.XfrmInStateProtoError = value\n\t\tcase \"XfrmInStateModeError\":\n\t\t\tx.XfrmInStateModeError = value\n\t\tcase \"XfrmInStateSeqError\":\n\t\t\tx.XfrmInStateSeqError = value\n\t\tcase \"XfrmInStateExpired\":\n\t\t\tx.XfrmInStateExpired = value\n\t\tcase \"XfrmInStateInvalid\":\n\t\t\tx.XfrmInStateInvalid = value\n\t\tcase \"XfrmInTmplMismatch\":\n\t\t\tx.XfrmInTmplMismatch = value\n\t\tcase \"XfrmInNoPols\":\n\t\t\tx.XfrmInNoPols = value\n\t\tcase \"XfrmInPolBlock\":\n\t\t\tx.XfrmInPolBlock = value\n\t\tcase \"XfrmInPolError\":\n\t\t\tx.XfrmInPolError = value\n\t\tcase \"XfrmOutError\":\n\t\t\tx.XfrmOutError = value\n\t\tcase \"XfrmInStateMismatch\":\n\t\t\tx.XfrmInStateMismatch = value\n\t\tcase \"XfrmOutBundleGenError\":\n\t\t\tx.XfrmOutBundleGenError = value\n\t\tcase \"XfrmOutBundleCheckError\":\n\t\t\tx.XfrmOutBundleCheckError = value\n\t\tcase \"XfrmOutNoStates\":\n\t\t\tx.XfrmOutNoStates = value\n\t\tcase \"XfrmOutStateProtoError\":\n\t\t\tx.XfrmOutStateProtoError = value\n\t\tcase \"XfrmOutStateModeError\":\n\t\t\tx.XfrmOutStateModeError = value\n\t\tcase \"XfrmOutStateSeqError\":\n\t\t\tx.XfrmOutStateSeqError = value\n\t\tcase \"XfrmOutStateExpired\":\n\t\t\tx.XfrmOutStateExpired = value\n\t\tcase \"XfrmOutPolBlock\":\n\t\t\tx.XfrmOutPolBlock = value\n\t\tcase \"XfrmOutPolDead\":\n\t\t\tx.XfrmOutPolDead = value\n\t\tcase \"XfrmOutPolError\":\n\t\t\tx.XfrmOutPolError = value\n\t\tcase \"XfrmFwdHdrError\":\n\t\t\tx.XfrmFwdHdrError = value\n\t\tcase \"XfrmOutStateInvalid\":\n\t\t\tx.XfrmOutStateInvalid = value\n\t\tcase \"XfrmAcquireError\":\n\t\t\tx.XfrmAcquireError = value\n\t\t}\n\n\t}\n\n\treturn x, s.Err()\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/netstat.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// NetStat contains statistics for all the counters from one file.\ntype NetStat struct {\n\tStats    map[string][]uint64\n\tFilename string\n}\n\n// NetStat retrieves stats from `/proc/net/stat/`.\nfunc (fs FS) NetStat() ([]NetStat, error) {\n\tstatFiles, err := filepath.Glob(fs.proc.Path(\"net/stat/*\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar netStatsTotal []NetStat\n\n\tfor _, filePath := range statFiles {\n\t\tprocNetstat, err := parseNetstat(filePath)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tprocNetstat.Filename = filepath.Base(filePath)\n\n\t\tnetStatsTotal = append(netStatsTotal, procNetstat)\n\t}\n\treturn netStatsTotal, nil\n}\n\n// parseNetstat parses the metrics from `/proc/net/stat/` file\n// and returns a NetStat structure.\nfunc parseNetstat(filePath string) (NetStat, error) {\n\tnetStat := NetStat{\n\t\tStats: make(map[string][]uint64),\n\t}\n\tfile, err := os.Open(filePath)\n\tif err != nil {\n\t\treturn netStat, err\n\t}\n\tdefer file.Close()\n\n\tscanner := bufio.NewScanner(file)\n\tscanner.Scan()\n\n\t// First string is always a header for stats\n\tvar headers []string\n\theaders = append(headers, strings.Fields(scanner.Text())...)\n\n\t// Other strings represent per-CPU counters\n\tfor scanner.Scan() {\n\t\tfor num, counter := range strings.Fields(scanner.Text()) {\n\t\t\tvalue, err := strconv.ParseUint(counter, 16, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn NetStat{}, err\n\t\t\t}\n\t\t\tnetStat.Stats[headers[num]] = append(netStat.Stats[headers[num]], value)\n\t\t}\n\t}\n\n\treturn netStat, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// Proc provides information about a running process.\ntype Proc struct {\n\t// The process ID.\n\tPID int\n\n\tfs FS\n}\n\n// Procs represents a list of Proc structs.\ntype Procs []Proc\n\nvar (\n\tErrFileParse  = errors.New(\"Error Parsing File\")\n\tErrFileRead   = errors.New(\"Error Reading File\")\n\tErrMountPoint = errors.New(\"Error Accessing Mount point\")\n)\n\nfunc (p Procs) Len() int           { return len(p) }\nfunc (p Procs) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }\nfunc (p Procs) Less(i, j int) bool { return p[i].PID < p[j].PID }\n\n// Self returns a process for the current process read via /proc/self.\nfunc Self() (Proc, error) {\n\tfs, err := NewFS(DefaultMountPoint)\n\tif err != nil || errors.Unwrap(err) == ErrMountPoint {\n\t\treturn Proc{}, err\n\t}\n\treturn fs.Self()\n}\n\n// NewProc returns a process for the given pid under /proc.\nfunc NewProc(pid int) (Proc, error) {\n\tfs, err := NewFS(DefaultMountPoint)\n\tif err != nil {\n\t\treturn Proc{}, err\n\t}\n\treturn fs.Proc(pid)\n}\n\n// AllProcs returns a list of all currently available processes under /proc.\nfunc AllProcs() (Procs, error) {\n\tfs, err := NewFS(DefaultMountPoint)\n\tif err != nil {\n\t\treturn Procs{}, err\n\t}\n\treturn fs.AllProcs()\n}\n\n// Self returns a process for the current process.\nfunc (fs FS) Self() (Proc, error) {\n\tp, err := os.Readlink(fs.proc.Path(\"self\"))\n\tif err != nil {\n\t\treturn Proc{}, err\n\t}\n\tpid, err := strconv.Atoi(strings.Replace(p, string(fs.proc), \"\", -1))\n\tif err != nil {\n\t\treturn Proc{}, err\n\t}\n\treturn fs.Proc(pid)\n}\n\n// NewProc returns a process for the given pid.\n//\n// Deprecated: Use fs.Proc() instead.\nfunc (fs FS) NewProc(pid int) (Proc, error) {\n\treturn fs.Proc(pid)\n}\n\n// Proc returns a process for the given pid.\nfunc (fs FS) Proc(pid int) (Proc, error) {\n\tif _, err := os.Stat(fs.proc.Path(strconv.Itoa(pid))); err != nil {\n\t\treturn Proc{}, err\n\t}\n\treturn Proc{PID: pid, fs: fs}, nil\n}\n\n// AllProcs returns a list of all currently available processes.\nfunc (fs FS) AllProcs() (Procs, error) {\n\td, err := os.Open(fs.proc.Path())\n\tif err != nil {\n\t\treturn Procs{}, err\n\t}\n\tdefer d.Close()\n\n\tnames, err := d.Readdirnames(-1)\n\tif err != nil {\n\t\treturn Procs{}, fmt.Errorf(\"%w: Cannot read file: %v: %w\", ErrFileRead, names, err)\n\t}\n\n\tp := Procs{}\n\tfor _, n := range names {\n\t\tpid, err := strconv.ParseInt(n, 10, 64)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tp = append(p, Proc{PID: int(pid), fs: fs})\n\t}\n\n\treturn p, nil\n}\n\n// CmdLine returns the command line of a process.\nfunc (p Proc) CmdLine() ([]string, error) {\n\tdata, err := util.ReadFileNoStat(p.path(\"cmdline\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif len(data) < 1 {\n\t\treturn []string{}, nil\n\t}\n\n\treturn strings.Split(string(bytes.TrimRight(data, \"\\x00\")), \"\\x00\"), nil\n}\n\n// Wchan returns the wchan (wait channel) of a process.\nfunc (p Proc) Wchan() (string, error) {\n\tf, err := os.Open(p.path(\"wchan\"))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer f.Close()\n\n\tdata, err := io.ReadAll(f)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\twchan := string(data)\n\tif wchan == \"\" || wchan == \"0\" {\n\t\treturn \"\", nil\n\t}\n\n\treturn wchan, nil\n}\n\n// Comm returns the command name of a process.\nfunc (p Proc) Comm() (string, error) {\n\tdata, err := util.ReadFileNoStat(p.path(\"comm\"))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn strings.TrimSpace(string(data)), nil\n}\n\n// Executable returns the absolute path of the executable command of a process.\nfunc (p Proc) Executable() (string, error) {\n\texe, err := os.Readlink(p.path(\"exe\"))\n\tif os.IsNotExist(err) {\n\t\treturn \"\", nil\n\t}\n\n\treturn exe, err\n}\n\n// Cwd returns the absolute path to the current working directory of the process.\nfunc (p Proc) Cwd() (string, error) {\n\twd, err := os.Readlink(p.path(\"cwd\"))\n\tif os.IsNotExist(err) {\n\t\treturn \"\", nil\n\t}\n\n\treturn wd, err\n}\n\n// RootDir returns the absolute path to the process's root directory (as set by chroot).\nfunc (p Proc) RootDir() (string, error) {\n\trdir, err := os.Readlink(p.path(\"root\"))\n\tif os.IsNotExist(err) {\n\t\treturn \"\", nil\n\t}\n\n\treturn rdir, err\n}\n\n// FileDescriptors returns the currently open file descriptors of a process.\nfunc (p Proc) FileDescriptors() ([]uintptr, error) {\n\tnames, err := p.fileDescriptors()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfds := make([]uintptr, len(names))\n\tfor i, n := range names {\n\t\tfd, err := strconv.ParseInt(n, 10, 32)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: Cannot parse line: %v: %w\", ErrFileParse, i, err)\n\t\t}\n\t\tfds[i] = uintptr(fd)\n\t}\n\n\treturn fds, nil\n}\n\n// FileDescriptorTargets returns the targets of all file descriptors of a process.\n// If a file descriptor is not a symlink to a file (like a socket), that value will be the empty string.\nfunc (p Proc) FileDescriptorTargets() ([]string, error) {\n\tnames, err := p.fileDescriptors()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttargets := make([]string, len(names))\n\n\tfor i, name := range names {\n\t\ttarget, err := os.Readlink(p.path(\"fd\", name))\n\t\tif err == nil {\n\t\t\ttargets[i] = target\n\t\t}\n\t}\n\n\treturn targets, nil\n}\n\n// FileDescriptorsLen returns the number of currently open file descriptors of\n// a process.\nfunc (p Proc) FileDescriptorsLen() (int, error) {\n\t// Use fast path if available (Linux v6.2): https://github.com/torvalds/linux/commit/f1f1f2569901\n\tif p.fs.isReal {\n\t\tstat, err := os.Stat(p.path(\"fd\"))\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\n\t\tsize := stat.Size()\n\t\tif size > 0 {\n\t\t\treturn int(size), nil\n\t\t}\n\t}\n\n\tfds, err := p.fileDescriptors()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn len(fds), nil\n}\n\n// MountStats retrieves statistics and configuration for mount points in a\n// process's namespace.\nfunc (p Proc) MountStats() ([]*Mount, error) {\n\tf, err := os.Open(p.path(\"mountstats\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer f.Close()\n\n\treturn parseMountStats(f)\n}\n\n// MountInfo retrieves mount information for mount points in a\n// process's namespace.\n// It supplies information missing in `/proc/self/mounts` and\n// fixes various other problems with that file too.\nfunc (p Proc) MountInfo() ([]*MountInfo, error) {\n\tdata, err := util.ReadFileNoStat(p.path(\"mountinfo\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn parseMountInfo(data)\n}\n\nfunc (p Proc) fileDescriptors() ([]string, error) {\n\td, err := os.Open(p.path(\"fd\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer d.Close()\n\n\tnames, err := d.Readdirnames(-1)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Cannot read file: %v: %w\", ErrFileRead, names, err)\n\t}\n\n\treturn names, nil\n}\n\nfunc (p Proc) path(pa ...string) string {\n\treturn p.fs.proc.Path(append([]string{strconv.Itoa(p.PID)}, pa...)...)\n}\n\n// FileDescriptorsInfo retrieves information about all file descriptors of\n// the process.\nfunc (p Proc) FileDescriptorsInfo() (ProcFDInfos, error) {\n\tnames, err := p.fileDescriptors()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar fdinfos ProcFDInfos\n\n\tfor _, n := range names {\n\t\tfdinfo, err := p.FDInfo(n)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tfdinfos = append(fdinfos, *fdinfo)\n\t}\n\n\treturn fdinfos, nil\n}\n\n// Schedstat returns task scheduling information for the process.\nfunc (p Proc) Schedstat() (ProcSchedstat, error) {\n\tcontents, err := os.ReadFile(p.path(\"schedstat\"))\n\tif err != nil {\n\t\treturn ProcSchedstat{}, err\n\t}\n\treturn parseProcSchedstat(string(contents))\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc_cgroup.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// Cgroup models one line from /proc/[pid]/cgroup. Each Cgroup struct describes the placement of a PID inside a\n// specific control hierarchy. The kernel has two cgroup APIs, v1 and v2. v1 has one hierarchy per available resource\n// controller, while v2 has one unified hierarchy shared by all controllers. Regardless of v1 or v2, all hierarchies\n// contain all running processes, so the question answerable with a Cgroup struct is 'where is this process in\n// this hierarchy' (where==what path on the specific cgroupfs). By prefixing this path with the mount point of\n// *this specific* hierarchy, you can locate the relevant pseudo-files needed to read/set the data for this PID\n// in this hierarchy\n//\n// Also see http://man7.org/linux/man-pages/man7/cgroups.7.html\ntype Cgroup struct {\n\t// HierarchyID that can be matched to a named hierarchy using /proc/cgroups. Cgroups V2 only has one\n\t// hierarchy, so HierarchyID is always 0. For cgroups v1 this is a unique ID number\n\tHierarchyID int\n\t// Controllers using this hierarchy of processes. Controllers are also known as subsystems. For\n\t// Cgroups V2 this may be empty, as all active controllers use the same hierarchy\n\tControllers []string\n\t// Path of this control group, relative to the mount point of the cgroupfs representing this specific\n\t// hierarchy\n\tPath string\n}\n\n// parseCgroupString parses each line of the /proc/[pid]/cgroup file\n// Line format is hierarchyID:[controller1,controller2]:path.\nfunc parseCgroupString(cgroupStr string) (*Cgroup, error) {\n\tvar err error\n\n\tfields := strings.SplitN(cgroupStr, \":\", 3)\n\tif len(fields) < 3 {\n\t\treturn nil, fmt.Errorf(\"%w: 3+ fields required, found %d fields in cgroup string: %s\", ErrFileParse, len(fields), cgroupStr)\n\t}\n\n\tcgroup := &Cgroup{\n\t\tPath:        fields[2],\n\t\tControllers: nil,\n\t}\n\tcgroup.HierarchyID, err = strconv.Atoi(fields[0])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: hierarchy ID: %q\", ErrFileParse, cgroup.HierarchyID)\n\t}\n\tif fields[1] != \"\" {\n\t\tssNames := strings.Split(fields[1], \",\")\n\t\tcgroup.Controllers = append(cgroup.Controllers, ssNames...)\n\t}\n\treturn cgroup, nil\n}\n\n// parseCgroups reads each line of the /proc/[pid]/cgroup file.\nfunc parseCgroups(data []byte) ([]Cgroup, error) {\n\tvar cgroups []Cgroup\n\tscanner := bufio.NewScanner(bytes.NewReader(data))\n\tfor scanner.Scan() {\n\t\tmountString := scanner.Text()\n\t\tparsedMounts, err := parseCgroupString(mountString)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcgroups = append(cgroups, *parsedMounts)\n\t}\n\n\terr := scanner.Err()\n\treturn cgroups, err\n}\n\n// Cgroups reads from /proc/<pid>/cgroups and returns a []*Cgroup struct locating this PID in each process\n// control hierarchy running on this system. On every system (v1 and v2), all hierarchies contain all processes,\n// so the len of the returned struct is equal to the number of active hierarchies on this system.\nfunc (p Proc) Cgroups() ([]Cgroup, error) {\n\tdata, err := util.ReadFileNoStat(p.path(\"cgroup\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn parseCgroups(data)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc_cgroups.go",
    "content": "// Copyright 2021 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// CgroupSummary models one line from /proc/cgroups.\n// This file contains information about the controllers that are compiled into the kernel.\n//\n// Also see http://man7.org/linux/man-pages/man7/cgroups.7.html\ntype CgroupSummary struct {\n\t// The name of the controller. controller is also known as subsystem.\n\tSubsysName string\n\t// The unique ID of the cgroup hierarchy on which this controller is mounted.\n\tHierarchy int\n\t// The number of control groups in this hierarchy using this controller.\n\tCgroups int\n\t// This field contains the value 1 if this controller is enabled, or 0 if it has been disabled\n\tEnabled int\n}\n\n// parseCgroupSummary parses each line of the /proc/cgroup file\n// Line format is `subsys_name\thierarchy\tnum_cgroups\tenabled`.\nfunc parseCgroupSummaryString(CgroupSummaryStr string) (*CgroupSummary, error) {\n\tvar err error\n\n\tfields := strings.Fields(CgroupSummaryStr)\n\t// require at least 4 fields\n\tif len(fields) < 4 {\n\t\treturn nil, fmt.Errorf(\"%w: 4+ fields required, found %d fields in cgroup info string: %s\", ErrFileParse, len(fields), CgroupSummaryStr)\n\t}\n\n\tCgroupSummary := &CgroupSummary{\n\t\tSubsysName: fields[0],\n\t}\n\tCgroupSummary.Hierarchy, err = strconv.Atoi(fields[1])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Unable to parse hierarchy ID from %q\", ErrFileParse, fields[1])\n\t}\n\tCgroupSummary.Cgroups, err = strconv.Atoi(fields[2])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Unable to parse Cgroup Num from %q\", ErrFileParse, fields[2])\n\t}\n\tCgroupSummary.Enabled, err = strconv.Atoi(fields[3])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: Unable to parse Enabled from %q\", ErrFileParse, fields[3])\n\t}\n\treturn CgroupSummary, nil\n}\n\n// parseCgroupSummary reads each line of the /proc/cgroup file.\nfunc parseCgroupSummary(data []byte) ([]CgroupSummary, error) {\n\tvar CgroupSummarys []CgroupSummary\n\tscanner := bufio.NewScanner(bytes.NewReader(data))\n\tfor scanner.Scan() {\n\t\tCgroupSummaryString := scanner.Text()\n\t\t// ignore comment lines\n\t\tif strings.HasPrefix(CgroupSummaryString, \"#\") {\n\t\t\tcontinue\n\t\t}\n\t\tCgroupSummary, err := parseCgroupSummaryString(CgroupSummaryString)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tCgroupSummarys = append(CgroupSummarys, *CgroupSummary)\n\t}\n\n\terr := scanner.Err()\n\treturn CgroupSummarys, err\n}\n\n// CgroupSummarys returns information about current /proc/cgroups.\nfunc (fs FS) CgroupSummarys() ([]CgroupSummary, error) {\n\tdata, err := util.ReadFileNoStat(fs.proc.Path(\"cgroups\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn parseCgroupSummary(data)\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc_environ.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// Environ reads process environments from `/proc/<pid>/environ`.\nfunc (p Proc) Environ() ([]string, error) {\n\tenvironments := make([]string, 0)\n\n\tdata, err := util.ReadFileNoStat(p.path(\"environ\"))\n\tif err != nil {\n\t\treturn environments, err\n\t}\n\n\tenvironments = strings.Split(string(data), \"\\000\")\n\tif len(environments) > 0 {\n\t\tenvironments = environments[:len(environments)-1]\n\t}\n\n\treturn environments, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc_fdinfo.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"regexp\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\nvar (\n\trPos          = regexp.MustCompile(`^pos:\\s+(\\d+)$`)\n\trFlags        = regexp.MustCompile(`^flags:\\s+(\\d+)$`)\n\trMntID        = regexp.MustCompile(`^mnt_id:\\s+(\\d+)$`)\n\trIno          = regexp.MustCompile(`^ino:\\s+(\\d+)$`)\n\trInotify      = regexp.MustCompile(`^inotify`)\n\trInotifyParts = regexp.MustCompile(`^inotify\\s+wd:([0-9a-f]+)\\s+ino:([0-9a-f]+)\\s+sdev:([0-9a-f]+)(?:\\s+mask:([0-9a-f]+))?`)\n)\n\n// ProcFDInfo contains represents file descriptor information.\ntype ProcFDInfo struct {\n\t// File descriptor\n\tFD string\n\t// File offset\n\tPos string\n\t// File access mode and status flags\n\tFlags string\n\t// Mount point ID\n\tMntID string\n\t// Inode number\n\tIno string\n\t// List of inotify lines (structured) in the fdinfo file (kernel 3.8+ only)\n\tInotifyInfos []InotifyInfo\n}\n\n// FDInfo constructor. On kernels older than 3.8, InotifyInfos will always be empty.\nfunc (p Proc) FDInfo(fd string) (*ProcFDInfo, error) {\n\tdata, err := util.ReadFileNoStat(p.path(\"fdinfo\", fd))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar text, pos, flags, mntid, ino string\n\tvar inotify []InotifyInfo\n\n\tscanner := bufio.NewScanner(bytes.NewReader(data))\n\tfor scanner.Scan() {\n\t\ttext = scanner.Text()\n\t\tif rPos.MatchString(text) {\n\t\t\tpos = rPos.FindStringSubmatch(text)[1]\n\t\t} else if rFlags.MatchString(text) {\n\t\t\tflags = rFlags.FindStringSubmatch(text)[1]\n\t\t} else if rMntID.MatchString(text) {\n\t\t\tmntid = rMntID.FindStringSubmatch(text)[1]\n\t\t} else if rIno.MatchString(text) {\n\t\t\tino = rIno.FindStringSubmatch(text)[1]\n\t\t} else if rInotify.MatchString(text) {\n\t\t\tnewInotify, err := parseInotifyInfo(text)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tinotify = append(inotify, *newInotify)\n\t\t}\n\t}\n\n\ti := &ProcFDInfo{\n\t\tFD:           fd,\n\t\tPos:          pos,\n\t\tFlags:        flags,\n\t\tMntID:        mntid,\n\t\tIno:          ino,\n\t\tInotifyInfos: inotify,\n\t}\n\n\treturn i, nil\n}\n\n// InotifyInfo represents a single inotify line in the fdinfo file.\ntype InotifyInfo struct {\n\t// Watch descriptor number\n\tWD string\n\t// Inode number\n\tIno string\n\t// Device ID\n\tSdev string\n\t// Mask of events being monitored\n\tMask string\n}\n\n// InotifyInfo constructor. Only available on kernel 3.8+.\nfunc parseInotifyInfo(line string) (*InotifyInfo, error) {\n\tm := rInotifyParts.FindStringSubmatch(line)\n\tif len(m) >= 4 {\n\t\tvar mask string\n\t\tif len(m) == 5 {\n\t\t\tmask = m[4]\n\t\t}\n\t\ti := &InotifyInfo{\n\t\t\tWD:   m[1],\n\t\t\tIno:  m[2],\n\t\t\tSdev: m[3],\n\t\t\tMask: mask,\n\t\t}\n\t\treturn i, nil\n\t}\n\treturn nil, fmt.Errorf(\"%w: invalid inode entry: %q\", ErrFileParse, line)\n}\n\n// ProcFDInfos represents a list of ProcFDInfo structs.\ntype ProcFDInfos []ProcFDInfo\n\nfunc (p ProcFDInfos) Len() int           { return len(p) }\nfunc (p ProcFDInfos) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }\nfunc (p ProcFDInfos) Less(i, j int) bool { return p[i].FD < p[j].FD }\n\n// InotifyWatchLen returns the total number of inotify watches.\nfunc (p ProcFDInfos) InotifyWatchLen() (int, error) {\n\tlength := 0\n\tfor _, f := range p {\n\t\tlength += len(f.InotifyInfos)\n\t}\n\n\treturn length, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc_interrupts.go",
    "content": "// Copyright 2022 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// Interrupt represents a single interrupt line.\ntype Interrupt struct {\n\t// Info is the type of interrupt.\n\tInfo string\n\t// Devices is the name of the device that is located at that IRQ\n\tDevices string\n\t// Values is the number of interrupts per CPU.\n\tValues []string\n}\n\n// Interrupts models the content of /proc/interrupts. Key is the IRQ number.\n// - https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/s2-proc-interrupts\n// - https://raspberrypi.stackexchange.com/questions/105802/explanation-of-proc-interrupts-output\ntype Interrupts map[string]Interrupt\n\n// Interrupts creates a new instance from a given Proc instance.\nfunc (p Proc) Interrupts() (Interrupts, error) {\n\tdata, err := util.ReadFileNoStat(p.path(\"interrupts\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn parseInterrupts(bytes.NewReader(data))\n}\n\nfunc parseInterrupts(r io.Reader) (Interrupts, error) {\n\tvar (\n\t\tinterrupts = Interrupts{}\n\t\tscanner    = bufio.NewScanner(r)\n\t)\n\n\tif !scanner.Scan() {\n\t\treturn nil, errors.New(\"interrupts empty\")\n\t}\n\tcpuNum := len(strings.Fields(scanner.Text())) // one header per cpu\n\n\tfor scanner.Scan() {\n\t\tparts := strings.Fields(scanner.Text())\n\t\tif len(parts) == 0 { // skip empty lines\n\t\t\tcontinue\n\t\t}\n\t\tif len(parts) < 2 {\n\t\t\treturn nil, fmt.Errorf(\"%w: Not enough fields in interrupts (expected 2+ fields but got %d): %s\", ErrFileParse, len(parts), parts)\n\t\t}\n\t\tintName := parts[0][:len(parts[0])-1] // remove trailing :\n\n\t\tif len(parts) == 2 {\n\t\t\tinterrupts[intName] = Interrupt{\n\t\t\t\tInfo:    \"\",\n\t\t\t\tDevices: \"\",\n\t\t\t\tValues: []string{\n\t\t\t\t\tparts[1],\n\t\t\t\t},\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tintr := Interrupt{\n\t\t\tValues: parts[1 : cpuNum+1],\n\t\t}\n\n\t\tif _, err := strconv.Atoi(intName); err == nil { // numeral interrupt\n\t\t\tintr.Info = parts[cpuNum+1]\n\t\t\tintr.Devices = strings.Join(parts[cpuNum+2:], \" \")\n\t\t} else {\n\t\t\tintr.Info = strings.Join(parts[cpuNum+1:], \" \")\n\t\t}\n\t\tinterrupts[intName] = intr\n\t}\n\n\treturn interrupts, scanner.Err()\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc_io.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// ProcIO models the content of /proc/<pid>/io.\ntype ProcIO struct {\n\t// Chars read.\n\tRChar uint64\n\t// Chars written.\n\tWChar uint64\n\t// Read syscalls.\n\tSyscR uint64\n\t// Write syscalls.\n\tSyscW uint64\n\t// Bytes read.\n\tReadBytes uint64\n\t// Bytes written.\n\tWriteBytes uint64\n\t// Bytes written, but taking into account truncation. See\n\t// Documentation/filesystems/proc.txt in the kernel sources for\n\t// detailed explanation.\n\tCancelledWriteBytes int64\n}\n\n// IO creates a new ProcIO instance from a given Proc instance.\nfunc (p Proc) IO() (ProcIO, error) {\n\tpio := ProcIO{}\n\n\tdata, err := util.ReadFileNoStat(p.path(\"io\"))\n\tif err != nil {\n\t\treturn pio, err\n\t}\n\n\tioFormat := \"rchar: %d\\nwchar: %d\\nsyscr: %d\\nsyscw: %d\\n\" +\n\t\t\"read_bytes: %d\\nwrite_bytes: %d\\n\" +\n\t\t\"cancelled_write_bytes: %d\\n\"\n\n\t_, err = fmt.Sscanf(string(data), ioFormat, &pio.RChar, &pio.WChar, &pio.SyscR,\n\t\t&pio.SyscW, &pio.ReadBytes, &pio.WriteBytes, &pio.CancelledWriteBytes)\n\n\treturn pio, err\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc_limits.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"strconv\"\n)\n\n// ProcLimits represents the soft limits for each of the process's resource\n// limits. For more information see getrlimit(2):\n// http://man7.org/linux/man-pages/man2/getrlimit.2.html.\ntype ProcLimits struct {\n\t// CPU time limit in seconds.\n\tCPUTime uint64\n\t// Maximum size of files that the process may create.\n\tFileSize uint64\n\t// Maximum size of the process's data segment (initialized data,\n\t// uninitialized data, and heap).\n\tDataSize uint64\n\t// Maximum size of the process stack in bytes.\n\tStackSize uint64\n\t// Maximum size of a core file.\n\tCoreFileSize uint64\n\t// Limit of the process's resident set in pages.\n\tResidentSet uint64\n\t// Maximum number of processes that can be created for the real user ID of\n\t// the calling process.\n\tProcesses uint64\n\t// Value one greater than the maximum file descriptor number that can be\n\t// opened by this process.\n\tOpenFiles uint64\n\t// Maximum number of bytes of memory that may be locked into RAM.\n\tLockedMemory uint64\n\t// Maximum size of the process's virtual memory address space in bytes.\n\tAddressSpace uint64\n\t// Limit on the combined number of flock(2) locks and fcntl(2) leases that\n\t// this process may establish.\n\tFileLocks uint64\n\t// Limit of signals that may be queued for the real user ID of the calling\n\t// process.\n\tPendingSignals uint64\n\t// Limit on the number of bytes that can be allocated for POSIX message\n\t// queues for the real user ID of the calling process.\n\tMsqqueueSize uint64\n\t// Limit of the nice priority set using setpriority(2) or nice(2).\n\tNicePriority uint64\n\t// Limit of the real-time priority set using sched_setscheduler(2) or\n\t// sched_setparam(2).\n\tRealtimePriority uint64\n\t// Limit (in microseconds) on the amount of CPU time that a process\n\t// scheduled under a real-time scheduling policy may consume without making\n\t// a blocking system call.\n\tRealtimeTimeout uint64\n}\n\nconst (\n\tlimitsFields    = 4\n\tlimitsUnlimited = \"unlimited\"\n)\n\nvar (\n\tlimitsMatch = regexp.MustCompile(`(Max \\w+\\s{0,1}?\\w*\\s{0,1}\\w*)\\s{2,}(\\w+)\\s+(\\w+)`)\n)\n\n// NewLimits returns the current soft limits of the process.\n//\n// Deprecated: Use p.Limits() instead.\nfunc (p Proc) NewLimits() (ProcLimits, error) {\n\treturn p.Limits()\n}\n\n// Limits returns the current soft limits of the process.\nfunc (p Proc) Limits() (ProcLimits, error) {\n\tf, err := os.Open(p.path(\"limits\"))\n\tif err != nil {\n\t\treturn ProcLimits{}, err\n\t}\n\tdefer f.Close()\n\n\tvar (\n\t\tl = ProcLimits{}\n\t\ts = bufio.NewScanner(f)\n\t)\n\n\ts.Scan() // Skip limits header\n\n\tfor s.Scan() {\n\t\t//fields := limitsMatch.Split(s.Text(), limitsFields)\n\t\tfields := limitsMatch.FindStringSubmatch(s.Text())\n\t\tif len(fields) != limitsFields {\n\t\t\treturn ProcLimits{}, fmt.Errorf(\"%w: couldn't parse %q line %q\", ErrFileParse, f.Name(), s.Text())\n\t\t}\n\n\t\tswitch fields[1] {\n\t\tcase \"Max cpu time\":\n\t\t\tl.CPUTime, err = parseUint(fields[2])\n\t\tcase \"Max file size\":\n\t\t\tl.FileSize, err = parseUint(fields[2])\n\t\tcase \"Max data size\":\n\t\t\tl.DataSize, err = parseUint(fields[2])\n\t\tcase \"Max stack size\":\n\t\t\tl.StackSize, err = parseUint(fields[2])\n\t\tcase \"Max core file size\":\n\t\t\tl.CoreFileSize, err = parseUint(fields[2])\n\t\tcase \"Max resident set\":\n\t\t\tl.ResidentSet, err = parseUint(fields[2])\n\t\tcase \"Max processes\":\n\t\t\tl.Processes, err = parseUint(fields[2])\n\t\tcase \"Max open files\":\n\t\t\tl.OpenFiles, err = parseUint(fields[2])\n\t\tcase \"Max locked memory\":\n\t\t\tl.LockedMemory, err = parseUint(fields[2])\n\t\tcase \"Max address space\":\n\t\t\tl.AddressSpace, err = parseUint(fields[2])\n\t\tcase \"Max file locks\":\n\t\t\tl.FileLocks, err = parseUint(fields[2])\n\t\tcase \"Max pending signals\":\n\t\t\tl.PendingSignals, err = parseUint(fields[2])\n\t\tcase \"Max msgqueue size\":\n\t\t\tl.MsqqueueSize, err = parseUint(fields[2])\n\t\tcase \"Max nice priority\":\n\t\t\tl.NicePriority, err = parseUint(fields[2])\n\t\tcase \"Max realtime priority\":\n\t\t\tl.RealtimePriority, err = parseUint(fields[2])\n\t\tcase \"Max realtime timeout\":\n\t\t\tl.RealtimeTimeout, err = parseUint(fields[2])\n\t\t}\n\t\tif err != nil {\n\t\t\treturn ProcLimits{}, err\n\t\t}\n\t}\n\n\treturn l, s.Err()\n}\n\nfunc parseUint(s string) (uint64, error) {\n\tif s == limitsUnlimited {\n\t\treturn 18446744073709551615, nil\n\t}\n\ti, err := strconv.ParseUint(s, 10, 64)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"%w: couldn't parse value %q: %w\", ErrFileParse, s, err)\n\t}\n\treturn i, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc_maps.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris) && !js\n// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris\n// +build !js\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\n// ProcMapPermissions contains permission settings read from `/proc/[pid]/maps`.\ntype ProcMapPermissions struct {\n\t// mapping has the [R]ead flag set\n\tRead bool\n\t// mapping has the [W]rite flag set\n\tWrite bool\n\t// mapping has the [X]ecutable flag set\n\tExecute bool\n\t// mapping has the [S]hared flag set\n\tShared bool\n\t// mapping is marked as [P]rivate (copy on write)\n\tPrivate bool\n}\n\n// ProcMap contains the process memory-mappings of the process\n// read from `/proc/[pid]/maps`.\ntype ProcMap struct {\n\t// The start address of current mapping.\n\tStartAddr uintptr\n\t// The end address of the current mapping\n\tEndAddr uintptr\n\t// The permissions for this mapping\n\tPerms *ProcMapPermissions\n\t// The current offset into the file/fd (e.g., shared libs)\n\tOffset int64\n\t// Device owner of this mapping (major:minor) in Mkdev format.\n\tDev uint64\n\t// The inode of the device above\n\tInode uint64\n\t// The file or psuedofile (or empty==anonymous)\n\tPathname string\n}\n\n// parseDevice parses the device token of a line and converts it to a dev_t\n// (mkdev) like structure.\nfunc parseDevice(s string) (uint64, error) {\n\ti := strings.Index(s, \":\")\n\tif i == -1 {\n\t\treturn 0, fmt.Errorf(\"%w: expected separator `:` in %s\", ErrFileParse, s)\n\t}\n\n\tmajor, err := strconv.ParseUint(s[0:i], 16, 0)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tminor, err := strconv.ParseUint(s[i+1:], 16, 0)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn unix.Mkdev(uint32(major), uint32(minor)), nil\n}\n\n// parseAddress converts a hex-string to a uintptr.\nfunc parseAddress(s string) (uintptr, error) {\n\ta, err := strconv.ParseUint(s, 16, 0)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn uintptr(a), nil\n}\n\n// parseAddresses parses the start-end address.\nfunc parseAddresses(s string) (uintptr, uintptr, error) {\n\tidx := strings.Index(s, \"-\")\n\tif idx == -1 {\n\t\treturn 0, 0, fmt.Errorf(\"%w: expected separator `-` in %s\", ErrFileParse, s)\n\t}\n\n\tsaddr, err := parseAddress(s[0:idx])\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\n\teaddr, err := parseAddress(s[idx+1:])\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\n\treturn saddr, eaddr, nil\n}\n\n// parsePermissions parses a token and returns any that are set.\nfunc parsePermissions(s string) (*ProcMapPermissions, error) {\n\tif len(s) < 4 {\n\t\treturn nil, fmt.Errorf(\"%w: invalid permissions token\", ErrFileParse)\n\t}\n\n\tperms := ProcMapPermissions{}\n\tfor _, ch := range s {\n\t\tswitch ch {\n\t\tcase 'r':\n\t\t\tperms.Read = true\n\t\tcase 'w':\n\t\t\tperms.Write = true\n\t\tcase 'x':\n\t\t\tperms.Execute = true\n\t\tcase 'p':\n\t\t\tperms.Private = true\n\t\tcase 's':\n\t\t\tperms.Shared = true\n\t\t}\n\t}\n\n\treturn &perms, nil\n}\n\n// parseProcMap will attempt to parse a single line within a proc/[pid]/maps\n// buffer.\nfunc parseProcMap(text string) (*ProcMap, error) {\n\tfields := strings.Fields(text)\n\tif len(fields) < 5 {\n\t\treturn nil, fmt.Errorf(\"%w: truncated procmap entry\", ErrFileParse)\n\t}\n\n\tsaddr, eaddr, err := parseAddresses(fields[0])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tperms, err := parsePermissions(fields[1])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\toffset, err := strconv.ParseInt(fields[2], 16, 0)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdevice, err := parseDevice(fields[3])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinode, err := strconv.ParseUint(fields[4], 10, 0)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tpathname := \"\"\n\n\tif len(fields) >= 5 {\n\t\tpathname = strings.Join(fields[5:], \" \")\n\t}\n\n\treturn &ProcMap{\n\t\tStartAddr: saddr,\n\t\tEndAddr:   eaddr,\n\t\tPerms:     perms,\n\t\tOffset:    offset,\n\t\tDev:       device,\n\t\tInode:     inode,\n\t\tPathname:  pathname,\n\t}, nil\n}\n\n// ProcMaps reads from /proc/[pid]/maps to get the memory-mappings of the\n// process.\nfunc (p Proc) ProcMaps() ([]*ProcMap, error) {\n\tfile, err := os.Open(p.path(\"maps\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer file.Close()\n\n\tmaps := []*ProcMap{}\n\tscan := bufio.NewScanner(file)\n\n\tfor scan.Scan() {\n\t\tm, err := parseProcMap(scan.Text())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tmaps = append(maps, m)\n\t}\n\n\treturn maps, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc_netstat.go",
    "content": "// Copyright 2022 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// ProcNetstat models the content of /proc/<pid>/net/netstat.\ntype ProcNetstat struct {\n\t// The process ID.\n\tPID int\n\tTcpExt\n\tIpExt\n}\n\ntype TcpExt struct { // nolint:revive\n\tSyncookiesSent            *float64\n\tSyncookiesRecv            *float64\n\tSyncookiesFailed          *float64\n\tEmbryonicRsts             *float64\n\tPruneCalled               *float64\n\tRcvPruned                 *float64\n\tOfoPruned                 *float64\n\tOutOfWindowIcmps          *float64\n\tLockDroppedIcmps          *float64\n\tArpFilter                 *float64\n\tTW                        *float64\n\tTWRecycled                *float64\n\tTWKilled                  *float64\n\tPAWSActive                *float64\n\tPAWSEstab                 *float64\n\tDelayedACKs               *float64\n\tDelayedACKLocked          *float64\n\tDelayedACKLost            *float64\n\tListenOverflows           *float64\n\tListenDrops               *float64\n\tTCPHPHits                 *float64\n\tTCPPureAcks               *float64\n\tTCPHPAcks                 *float64\n\tTCPRenoRecovery           *float64\n\tTCPSackRecovery           *float64\n\tTCPSACKReneging           *float64\n\tTCPSACKReorder            *float64\n\tTCPRenoReorder            *float64\n\tTCPTSReorder              *float64\n\tTCPFullUndo               *float64\n\tTCPPartialUndo            *float64\n\tTCPDSACKUndo              *float64\n\tTCPLossUndo               *float64\n\tTCPLostRetransmit         *float64\n\tTCPRenoFailures           *float64\n\tTCPSackFailures           *float64\n\tTCPLossFailures           *float64\n\tTCPFastRetrans            *float64\n\tTCPSlowStartRetrans       *float64\n\tTCPTimeouts               *float64\n\tTCPLossProbes             *float64\n\tTCPLossProbeRecovery      *float64\n\tTCPRenoRecoveryFail       *float64\n\tTCPSackRecoveryFail       *float64\n\tTCPRcvCollapsed           *float64\n\tTCPDSACKOldSent           *float64\n\tTCPDSACKOfoSent           *float64\n\tTCPDSACKRecv              *float64\n\tTCPDSACKOfoRecv           *float64\n\tTCPAbortOnData            *float64\n\tTCPAbortOnClose           *float64\n\tTCPAbortOnMemory          *float64\n\tTCPAbortOnTimeout         *float64\n\tTCPAbortOnLinger          *float64\n\tTCPAbortFailed            *float64\n\tTCPMemoryPressures        *float64\n\tTCPMemoryPressuresChrono  *float64\n\tTCPSACKDiscard            *float64\n\tTCPDSACKIgnoredOld        *float64\n\tTCPDSACKIgnoredNoUndo     *float64\n\tTCPSpuriousRTOs           *float64\n\tTCPMD5NotFound            *float64\n\tTCPMD5Unexpected          *float64\n\tTCPMD5Failure             *float64\n\tTCPSackShifted            *float64\n\tTCPSackMerged             *float64\n\tTCPSackShiftFallback      *float64\n\tTCPBacklogDrop            *float64\n\tPFMemallocDrop            *float64\n\tTCPMinTTLDrop             *float64\n\tTCPDeferAcceptDrop        *float64\n\tIPReversePathFilter       *float64\n\tTCPTimeWaitOverflow       *float64\n\tTCPReqQFullDoCookies      *float64\n\tTCPReqQFullDrop           *float64\n\tTCPRetransFail            *float64\n\tTCPRcvCoalesce            *float64\n\tTCPRcvQDrop               *float64\n\tTCPOFOQueue               *float64\n\tTCPOFODrop                *float64\n\tTCPOFOMerge               *float64\n\tTCPChallengeACK           *float64\n\tTCPSYNChallenge           *float64\n\tTCPFastOpenActive         *float64\n\tTCPFastOpenActiveFail     *float64\n\tTCPFastOpenPassive        *float64\n\tTCPFastOpenPassiveFail    *float64\n\tTCPFastOpenListenOverflow *float64\n\tTCPFastOpenCookieReqd     *float64\n\tTCPFastOpenBlackhole      *float64\n\tTCPSpuriousRtxHostQueues  *float64\n\tBusyPollRxPackets         *float64\n\tTCPAutoCorking            *float64\n\tTCPFromZeroWindowAdv      *float64\n\tTCPToZeroWindowAdv        *float64\n\tTCPWantZeroWindowAdv      *float64\n\tTCPSynRetrans             *float64\n\tTCPOrigDataSent           *float64\n\tTCPHystartTrainDetect     *float64\n\tTCPHystartTrainCwnd       *float64\n\tTCPHystartDelayDetect     *float64\n\tTCPHystartDelayCwnd       *float64\n\tTCPACKSkippedSynRecv      *float64\n\tTCPACKSkippedPAWS         *float64\n\tTCPACKSkippedSeq          *float64\n\tTCPACKSkippedFinWait2     *float64\n\tTCPACKSkippedTimeWait     *float64\n\tTCPACKSkippedChallenge    *float64\n\tTCPWinProbe               *float64\n\tTCPKeepAlive              *float64\n\tTCPMTUPFail               *float64\n\tTCPMTUPSuccess            *float64\n\tTCPWqueueTooBig           *float64\n}\n\ntype IpExt struct { // nolint:revive\n\tInNoRoutes      *float64\n\tInTruncatedPkts *float64\n\tInMcastPkts     *float64\n\tOutMcastPkts    *float64\n\tInBcastPkts     *float64\n\tOutBcastPkts    *float64\n\tInOctets        *float64\n\tOutOctets       *float64\n\tInMcastOctets   *float64\n\tOutMcastOctets  *float64\n\tInBcastOctets   *float64\n\tOutBcastOctets  *float64\n\tInCsumErrors    *float64\n\tInNoECTPkts     *float64\n\tInECT1Pkts      *float64\n\tInECT0Pkts      *float64\n\tInCEPkts        *float64\n\tReasmOverlaps   *float64\n}\n\nfunc (p Proc) Netstat() (ProcNetstat, error) {\n\tfilename := p.path(\"net/netstat\")\n\tdata, err := util.ReadFileNoStat(filename)\n\tif err != nil {\n\t\treturn ProcNetstat{PID: p.PID}, err\n\t}\n\tprocNetstat, err := parseProcNetstat(bytes.NewReader(data), filename)\n\tprocNetstat.PID = p.PID\n\treturn procNetstat, err\n}\n\n// parseProcNetstat parses the metrics from proc/<pid>/net/netstat file\n// and returns a ProcNetstat structure.\nfunc parseProcNetstat(r io.Reader, fileName string) (ProcNetstat, error) {\n\tvar (\n\t\tscanner     = bufio.NewScanner(r)\n\t\tprocNetstat = ProcNetstat{}\n\t)\n\n\tfor scanner.Scan() {\n\t\tnameParts := strings.Split(scanner.Text(), \" \")\n\t\tscanner.Scan()\n\t\tvalueParts := strings.Split(scanner.Text(), \" \")\n\t\t// Remove trailing :.\n\t\tprotocol := strings.TrimSuffix(nameParts[0], \":\")\n\t\tif len(nameParts) != len(valueParts) {\n\t\t\treturn procNetstat, fmt.Errorf(\"%w: mismatch field count mismatch in %s: %s\",\n\t\t\t\tErrFileParse, fileName, protocol)\n\t\t}\n\t\tfor i := 1; i < len(nameParts); i++ {\n\t\t\tvalue, err := strconv.ParseFloat(valueParts[i], 64)\n\t\t\tif err != nil {\n\t\t\t\treturn procNetstat, err\n\t\t\t}\n\t\t\tkey := nameParts[i]\n\n\t\t\tswitch protocol {\n\t\t\tcase \"TcpExt\":\n\t\t\t\tswitch key {\n\t\t\t\tcase \"SyncookiesSent\":\n\t\t\t\t\tprocNetstat.TcpExt.SyncookiesSent = &value\n\t\t\t\tcase \"SyncookiesRecv\":\n\t\t\t\t\tprocNetstat.TcpExt.SyncookiesRecv = &value\n\t\t\t\tcase \"SyncookiesFailed\":\n\t\t\t\t\tprocNetstat.TcpExt.SyncookiesFailed = &value\n\t\t\t\tcase \"EmbryonicRsts\":\n\t\t\t\t\tprocNetstat.TcpExt.EmbryonicRsts = &value\n\t\t\t\tcase \"PruneCalled\":\n\t\t\t\t\tprocNetstat.TcpExt.PruneCalled = &value\n\t\t\t\tcase \"RcvPruned\":\n\t\t\t\t\tprocNetstat.TcpExt.RcvPruned = &value\n\t\t\t\tcase \"OfoPruned\":\n\t\t\t\t\tprocNetstat.TcpExt.OfoPruned = &value\n\t\t\t\tcase \"OutOfWindowIcmps\":\n\t\t\t\t\tprocNetstat.TcpExt.OutOfWindowIcmps = &value\n\t\t\t\tcase \"LockDroppedIcmps\":\n\t\t\t\t\tprocNetstat.TcpExt.LockDroppedIcmps = &value\n\t\t\t\tcase \"ArpFilter\":\n\t\t\t\t\tprocNetstat.TcpExt.ArpFilter = &value\n\t\t\t\tcase \"TW\":\n\t\t\t\t\tprocNetstat.TcpExt.TW = &value\n\t\t\t\tcase \"TWRecycled\":\n\t\t\t\t\tprocNetstat.TcpExt.TWRecycled = &value\n\t\t\t\tcase \"TWKilled\":\n\t\t\t\t\tprocNetstat.TcpExt.TWKilled = &value\n\t\t\t\tcase \"PAWSActive\":\n\t\t\t\t\tprocNetstat.TcpExt.PAWSActive = &value\n\t\t\t\tcase \"PAWSEstab\":\n\t\t\t\t\tprocNetstat.TcpExt.PAWSEstab = &value\n\t\t\t\tcase \"DelayedACKs\":\n\t\t\t\t\tprocNetstat.TcpExt.DelayedACKs = &value\n\t\t\t\tcase \"DelayedACKLocked\":\n\t\t\t\t\tprocNetstat.TcpExt.DelayedACKLocked = &value\n\t\t\t\tcase \"DelayedACKLost\":\n\t\t\t\t\tprocNetstat.TcpExt.DelayedACKLost = &value\n\t\t\t\tcase \"ListenOverflows\":\n\t\t\t\t\tprocNetstat.TcpExt.ListenOverflows = &value\n\t\t\t\tcase \"ListenDrops\":\n\t\t\t\t\tprocNetstat.TcpExt.ListenDrops = &value\n\t\t\t\tcase \"TCPHPHits\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPHPHits = &value\n\t\t\t\tcase \"TCPPureAcks\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPPureAcks = &value\n\t\t\t\tcase \"TCPHPAcks\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPHPAcks = &value\n\t\t\t\tcase \"TCPRenoRecovery\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPRenoRecovery = &value\n\t\t\t\tcase \"TCPSackRecovery\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPSackRecovery = &value\n\t\t\t\tcase \"TCPSACKReneging\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPSACKReneging = &value\n\t\t\t\tcase \"TCPSACKReorder\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPSACKReorder = &value\n\t\t\t\tcase \"TCPRenoReorder\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPRenoReorder = &value\n\t\t\t\tcase \"TCPTSReorder\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPTSReorder = &value\n\t\t\t\tcase \"TCPFullUndo\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPFullUndo = &value\n\t\t\t\tcase \"TCPPartialUndo\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPPartialUndo = &value\n\t\t\t\tcase \"TCPDSACKUndo\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPDSACKUndo = &value\n\t\t\t\tcase \"TCPLossUndo\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPLossUndo = &value\n\t\t\t\tcase \"TCPLostRetransmit\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPLostRetransmit = &value\n\t\t\t\tcase \"TCPRenoFailures\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPRenoFailures = &value\n\t\t\t\tcase \"TCPSackFailures\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPSackFailures = &value\n\t\t\t\tcase \"TCPLossFailures\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPLossFailures = &value\n\t\t\t\tcase \"TCPFastRetrans\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPFastRetrans = &value\n\t\t\t\tcase \"TCPSlowStartRetrans\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPSlowStartRetrans = &value\n\t\t\t\tcase \"TCPTimeouts\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPTimeouts = &value\n\t\t\t\tcase \"TCPLossProbes\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPLossProbes = &value\n\t\t\t\tcase \"TCPLossProbeRecovery\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPLossProbeRecovery = &value\n\t\t\t\tcase \"TCPRenoRecoveryFail\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPRenoRecoveryFail = &value\n\t\t\t\tcase \"TCPSackRecoveryFail\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPSackRecoveryFail = &value\n\t\t\t\tcase \"TCPRcvCollapsed\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPRcvCollapsed = &value\n\t\t\t\tcase \"TCPDSACKOldSent\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPDSACKOldSent = &value\n\t\t\t\tcase \"TCPDSACKOfoSent\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPDSACKOfoSent = &value\n\t\t\t\tcase \"TCPDSACKRecv\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPDSACKRecv = &value\n\t\t\t\tcase \"TCPDSACKOfoRecv\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPDSACKOfoRecv = &value\n\t\t\t\tcase \"TCPAbortOnData\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPAbortOnData = &value\n\t\t\t\tcase \"TCPAbortOnClose\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPAbortOnClose = &value\n\t\t\t\tcase \"TCPDeferAcceptDrop\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPDeferAcceptDrop = &value\n\t\t\t\tcase \"IPReversePathFilter\":\n\t\t\t\t\tprocNetstat.TcpExt.IPReversePathFilter = &value\n\t\t\t\tcase \"TCPTimeWaitOverflow\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPTimeWaitOverflow = &value\n\t\t\t\tcase \"TCPReqQFullDoCookies\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPReqQFullDoCookies = &value\n\t\t\t\tcase \"TCPReqQFullDrop\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPReqQFullDrop = &value\n\t\t\t\tcase \"TCPRetransFail\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPRetransFail = &value\n\t\t\t\tcase \"TCPRcvCoalesce\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPRcvCoalesce = &value\n\t\t\t\tcase \"TCPRcvQDrop\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPRcvQDrop = &value\n\t\t\t\tcase \"TCPOFOQueue\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPOFOQueue = &value\n\t\t\t\tcase \"TCPOFODrop\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPOFODrop = &value\n\t\t\t\tcase \"TCPOFOMerge\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPOFOMerge = &value\n\t\t\t\tcase \"TCPChallengeACK\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPChallengeACK = &value\n\t\t\t\tcase \"TCPSYNChallenge\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPSYNChallenge = &value\n\t\t\t\tcase \"TCPFastOpenActive\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPFastOpenActive = &value\n\t\t\t\tcase \"TCPFastOpenActiveFail\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPFastOpenActiveFail = &value\n\t\t\t\tcase \"TCPFastOpenPassive\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPFastOpenPassive = &value\n\t\t\t\tcase \"TCPFastOpenPassiveFail\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPFastOpenPassiveFail = &value\n\t\t\t\tcase \"TCPFastOpenListenOverflow\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPFastOpenListenOverflow = &value\n\t\t\t\tcase \"TCPFastOpenCookieReqd\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPFastOpenCookieReqd = &value\n\t\t\t\tcase \"TCPFastOpenBlackhole\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPFastOpenBlackhole = &value\n\t\t\t\tcase \"TCPSpuriousRtxHostQueues\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPSpuriousRtxHostQueues = &value\n\t\t\t\tcase \"BusyPollRxPackets\":\n\t\t\t\t\tprocNetstat.TcpExt.BusyPollRxPackets = &value\n\t\t\t\tcase \"TCPAutoCorking\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPAutoCorking = &value\n\t\t\t\tcase \"TCPFromZeroWindowAdv\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPFromZeroWindowAdv = &value\n\t\t\t\tcase \"TCPToZeroWindowAdv\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPToZeroWindowAdv = &value\n\t\t\t\tcase \"TCPWantZeroWindowAdv\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPWantZeroWindowAdv = &value\n\t\t\t\tcase \"TCPSynRetrans\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPSynRetrans = &value\n\t\t\t\tcase \"TCPOrigDataSent\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPOrigDataSent = &value\n\t\t\t\tcase \"TCPHystartTrainDetect\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPHystartTrainDetect = &value\n\t\t\t\tcase \"TCPHystartTrainCwnd\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPHystartTrainCwnd = &value\n\t\t\t\tcase \"TCPHystartDelayDetect\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPHystartDelayDetect = &value\n\t\t\t\tcase \"TCPHystartDelayCwnd\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPHystartDelayCwnd = &value\n\t\t\t\tcase \"TCPACKSkippedSynRecv\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPACKSkippedSynRecv = &value\n\t\t\t\tcase \"TCPACKSkippedPAWS\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPACKSkippedPAWS = &value\n\t\t\t\tcase \"TCPACKSkippedSeq\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPACKSkippedSeq = &value\n\t\t\t\tcase \"TCPACKSkippedFinWait2\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPACKSkippedFinWait2 = &value\n\t\t\t\tcase \"TCPACKSkippedTimeWait\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPACKSkippedTimeWait = &value\n\t\t\t\tcase \"TCPACKSkippedChallenge\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPACKSkippedChallenge = &value\n\t\t\t\tcase \"TCPWinProbe\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPWinProbe = &value\n\t\t\t\tcase \"TCPKeepAlive\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPKeepAlive = &value\n\t\t\t\tcase \"TCPMTUPFail\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPMTUPFail = &value\n\t\t\t\tcase \"TCPMTUPSuccess\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPMTUPSuccess = &value\n\t\t\t\tcase \"TCPWqueueTooBig\":\n\t\t\t\t\tprocNetstat.TcpExt.TCPWqueueTooBig = &value\n\t\t\t\t}\n\t\t\tcase \"IpExt\":\n\t\t\t\tswitch key {\n\t\t\t\tcase \"InNoRoutes\":\n\t\t\t\t\tprocNetstat.IpExt.InNoRoutes = &value\n\t\t\t\tcase \"InTruncatedPkts\":\n\t\t\t\t\tprocNetstat.IpExt.InTruncatedPkts = &value\n\t\t\t\tcase \"InMcastPkts\":\n\t\t\t\t\tprocNetstat.IpExt.InMcastPkts = &value\n\t\t\t\tcase \"OutMcastPkts\":\n\t\t\t\t\tprocNetstat.IpExt.OutMcastPkts = &value\n\t\t\t\tcase \"InBcastPkts\":\n\t\t\t\t\tprocNetstat.IpExt.InBcastPkts = &value\n\t\t\t\tcase \"OutBcastPkts\":\n\t\t\t\t\tprocNetstat.IpExt.OutBcastPkts = &value\n\t\t\t\tcase \"InOctets\":\n\t\t\t\t\tprocNetstat.IpExt.InOctets = &value\n\t\t\t\tcase \"OutOctets\":\n\t\t\t\t\tprocNetstat.IpExt.OutOctets = &value\n\t\t\t\tcase \"InMcastOctets\":\n\t\t\t\t\tprocNetstat.IpExt.InMcastOctets = &value\n\t\t\t\tcase \"OutMcastOctets\":\n\t\t\t\t\tprocNetstat.IpExt.OutMcastOctets = &value\n\t\t\t\tcase \"InBcastOctets\":\n\t\t\t\t\tprocNetstat.IpExt.InBcastOctets = &value\n\t\t\t\tcase \"OutBcastOctets\":\n\t\t\t\t\tprocNetstat.IpExt.OutBcastOctets = &value\n\t\t\t\tcase \"InCsumErrors\":\n\t\t\t\t\tprocNetstat.IpExt.InCsumErrors = &value\n\t\t\t\tcase \"InNoECTPkts\":\n\t\t\t\t\tprocNetstat.IpExt.InNoECTPkts = &value\n\t\t\t\tcase \"InECT1Pkts\":\n\t\t\t\t\tprocNetstat.IpExt.InECT1Pkts = &value\n\t\t\t\tcase \"InECT0Pkts\":\n\t\t\t\t\tprocNetstat.IpExt.InECT0Pkts = &value\n\t\t\t\tcase \"InCEPkts\":\n\t\t\t\t\tprocNetstat.IpExt.InCEPkts = &value\n\t\t\t\tcase \"ReasmOverlaps\":\n\t\t\t\t\tprocNetstat.IpExt.ReasmOverlaps = &value\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn procNetstat, scanner.Err()\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc_ns.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Namespace represents a single namespace of a process.\ntype Namespace struct {\n\tType  string // Namespace type.\n\tInode uint32 // Inode number of the namespace. If two processes are in the same namespace their inodes will match.\n}\n\n// Namespaces contains all of the namespaces that the process is contained in.\ntype Namespaces map[string]Namespace\n\n// Namespaces reads from /proc/<pid>/ns/* to get the namespaces of which the\n// process is a member.\nfunc (p Proc) Namespaces() (Namespaces, error) {\n\td, err := os.Open(p.path(\"ns\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer d.Close()\n\n\tnames, err := d.Readdirnames(-1)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: failed to read contents of ns dir: %w\", ErrFileRead, err)\n\t}\n\n\tns := make(Namespaces, len(names))\n\tfor _, name := range names {\n\t\ttarget, err := os.Readlink(p.path(\"ns\", name))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tfields := strings.SplitN(target, \":\", 2)\n\t\tif len(fields) != 2 {\n\t\t\treturn nil, fmt.Errorf(\"%w: namespace type and inode from %q\", ErrFileParse, target)\n\t\t}\n\n\t\ttyp := fields[0]\n\t\tinode, err := strconv.ParseUint(strings.Trim(fields[1], \"[]\"), 10, 32)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: inode from %q: %w\", ErrFileParse, fields[1], err)\n\t\t}\n\n\t\tns[name] = Namespace{typ, uint32(inode)}\n\t}\n\n\treturn ns, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc_psi.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\n// The PSI / pressure interface is described at\n//   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/accounting/psi.txt\n// Each resource (cpu, io, memory, ...) is exposed as a single file.\n// Each file may contain up to two lines, one for \"some\" pressure and one for \"full\" pressure.\n// Each line contains several averages (over n seconds) and a total in µs.\n//\n// Example io pressure file:\n// > some avg10=0.06 avg60=0.21 avg300=0.99 total=8537362\n// > full avg10=0.00 avg60=0.13 avg300=0.96 total=8183134\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\nconst lineFormat = \"avg10=%f avg60=%f avg300=%f total=%d\"\n\n// PSILine is a single line of values as returned by `/proc/pressure/*`.\n//\n// The Avg entries are averages over n seconds, as a percentage.\n// The Total line is in microseconds.\ntype PSILine struct {\n\tAvg10  float64\n\tAvg60  float64\n\tAvg300 float64\n\tTotal  uint64\n}\n\n// PSIStats represent pressure stall information from /proc/pressure/*\n//\n// \"Some\" indicates the share of time in which at least some tasks are stalled.\n// \"Full\" indicates the share of time in which all non-idle tasks are stalled simultaneously.\ntype PSIStats struct {\n\tSome *PSILine\n\tFull *PSILine\n}\n\n// PSIStatsForResource reads pressure stall information for the specified\n// resource from /proc/pressure/<resource>. At time of writing this can be\n// either \"cpu\", \"memory\" or \"io\".\nfunc (fs FS) PSIStatsForResource(resource string) (PSIStats, error) {\n\tdata, err := util.ReadFileNoStat(fs.proc.Path(fmt.Sprintf(\"%s/%s\", \"pressure\", resource)))\n\tif err != nil {\n\t\treturn PSIStats{}, fmt.Errorf(\"%w: psi_stats: unavailable for %q: %w\", ErrFileRead, resource, err)\n\t}\n\n\treturn parsePSIStats(bytes.NewReader(data))\n}\n\n// parsePSIStats parses the specified file for pressure stall information.\nfunc parsePSIStats(r io.Reader) (PSIStats, error) {\n\tpsiStats := PSIStats{}\n\n\tscanner := bufio.NewScanner(r)\n\tfor scanner.Scan() {\n\t\tl := scanner.Text()\n\t\tprefix := strings.Split(l, \" \")[0]\n\t\tswitch prefix {\n\t\tcase \"some\":\n\t\t\tpsi := PSILine{}\n\t\t\t_, err := fmt.Sscanf(l, fmt.Sprintf(\"some %s\", lineFormat), &psi.Avg10, &psi.Avg60, &psi.Avg300, &psi.Total)\n\t\t\tif err != nil {\n\t\t\t\treturn PSIStats{}, err\n\t\t\t}\n\t\t\tpsiStats.Some = &psi\n\t\tcase \"full\":\n\t\t\tpsi := PSILine{}\n\t\t\t_, err := fmt.Sscanf(l, fmt.Sprintf(\"full %s\", lineFormat), &psi.Avg10, &psi.Avg60, &psi.Avg300, &psi.Total)\n\t\t\tif err != nil {\n\t\t\t\treturn PSIStats{}, err\n\t\t\t}\n\t\t\tpsiStats.Full = &psi\n\t\tdefault:\n\t\t\t// If we encounter a line with an unknown prefix, ignore it and move on\n\t\t\t// Should new measurement types be added in the future we'll simply ignore them instead\n\t\t\t// of erroring on retrieval\n\t\t\tcontinue\n\t\t}\n\t}\n\n\treturn psiStats, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc_smaps.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build !windows\n// +build !windows\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\nvar (\n\t// match the header line before each mapped zone in `/proc/pid/smaps`.\n\tprocSMapsHeaderLine = regexp.MustCompile(`^[a-f0-9].*$`)\n)\n\ntype ProcSMapsRollup struct {\n\t// Amount of the mapping that is currently resident in RAM.\n\tRss uint64\n\t// Process's proportional share of this mapping.\n\tPss uint64\n\t// Size in bytes of clean shared pages.\n\tSharedClean uint64\n\t// Size in bytes of dirty shared pages.\n\tSharedDirty uint64\n\t// Size in bytes of clean private pages.\n\tPrivateClean uint64\n\t// Size in bytes of dirty private pages.\n\tPrivateDirty uint64\n\t// Amount of memory currently marked as referenced or accessed.\n\tReferenced uint64\n\t// Amount of memory that does not belong to any file.\n\tAnonymous uint64\n\t// Amount would-be-anonymous memory currently on swap.\n\tSwap uint64\n\t// Process's proportional memory on swap.\n\tSwapPss uint64\n}\n\n// ProcSMapsRollup reads from /proc/[pid]/smaps_rollup to get summed memory information of the\n// process.\n//\n// If smaps_rollup does not exists (require kernel >= 4.15), the content of /proc/pid/smaps will\n// we read and summed.\nfunc (p Proc) ProcSMapsRollup() (ProcSMapsRollup, error) {\n\tdata, err := util.ReadFileNoStat(p.path(\"smaps_rollup\"))\n\tif err != nil && os.IsNotExist(err) {\n\t\treturn p.procSMapsRollupManual()\n\t}\n\tif err != nil {\n\t\treturn ProcSMapsRollup{}, err\n\t}\n\n\tlines := strings.Split(string(data), \"\\n\")\n\tsmaps := ProcSMapsRollup{}\n\n\t// skip first line which don't contains information we need\n\tlines = lines[1:]\n\tfor _, line := range lines {\n\t\tif line == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tif err := smaps.parseLine(line); err != nil {\n\t\t\treturn ProcSMapsRollup{}, err\n\t\t}\n\t}\n\n\treturn smaps, nil\n}\n\n// Read /proc/pid/smaps and do the roll-up in Go code.\nfunc (p Proc) procSMapsRollupManual() (ProcSMapsRollup, error) {\n\tfile, err := os.Open(p.path(\"smaps\"))\n\tif err != nil {\n\t\treturn ProcSMapsRollup{}, err\n\t}\n\tdefer file.Close()\n\n\tsmaps := ProcSMapsRollup{}\n\tscan := bufio.NewScanner(file)\n\n\tfor scan.Scan() {\n\t\tline := scan.Text()\n\n\t\tif procSMapsHeaderLine.MatchString(line) {\n\t\t\tcontinue\n\t\t}\n\n\t\tif err := smaps.parseLine(line); err != nil {\n\t\t\treturn ProcSMapsRollup{}, err\n\t\t}\n\t}\n\n\treturn smaps, nil\n}\n\nfunc (s *ProcSMapsRollup) parseLine(line string) error {\n\tkv := strings.SplitN(line, \":\", 2)\n\tif len(kv) != 2 {\n\t\tfmt.Println(line)\n\t\treturn errors.New(\"invalid net/dev line, missing colon\")\n\t}\n\n\tk := kv[0]\n\tif k == \"VmFlags\" {\n\t\treturn nil\n\t}\n\n\tv := strings.TrimSpace(kv[1])\n\tv = strings.TrimSuffix(v, \" kB\")\n\n\tvKBytes, err := strconv.ParseUint(v, 10, 64)\n\tif err != nil {\n\t\treturn err\n\t}\n\tvBytes := vKBytes * 1024\n\n\ts.addValue(k, vBytes)\n\n\treturn nil\n}\n\nfunc (s *ProcSMapsRollup) addValue(k string, vUintBytes uint64) {\n\tswitch k {\n\tcase \"Rss\":\n\t\ts.Rss += vUintBytes\n\tcase \"Pss\":\n\t\ts.Pss += vUintBytes\n\tcase \"Shared_Clean\":\n\t\ts.SharedClean += vUintBytes\n\tcase \"Shared_Dirty\":\n\t\ts.SharedDirty += vUintBytes\n\tcase \"Private_Clean\":\n\t\ts.PrivateClean += vUintBytes\n\tcase \"Private_Dirty\":\n\t\ts.PrivateDirty += vUintBytes\n\tcase \"Referenced\":\n\t\ts.Referenced += vUintBytes\n\tcase \"Anonymous\":\n\t\ts.Anonymous += vUintBytes\n\tcase \"Swap\":\n\t\ts.Swap += vUintBytes\n\tcase \"SwapPss\":\n\t\ts.SwapPss += vUintBytes\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc_snmp.go",
    "content": "// Copyright 2022 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// ProcSnmp models the content of /proc/<pid>/net/snmp.\ntype ProcSnmp struct {\n\t// The process ID.\n\tPID int\n\tIp\n\tIcmp\n\tIcmpMsg\n\tTcp\n\tUdp\n\tUdpLite\n}\n\ntype Ip struct { // nolint:revive\n\tForwarding      *float64\n\tDefaultTTL      *float64\n\tInReceives      *float64\n\tInHdrErrors     *float64\n\tInAddrErrors    *float64\n\tForwDatagrams   *float64\n\tInUnknownProtos *float64\n\tInDiscards      *float64\n\tInDelivers      *float64\n\tOutRequests     *float64\n\tOutDiscards     *float64\n\tOutNoRoutes     *float64\n\tReasmTimeout    *float64\n\tReasmReqds      *float64\n\tReasmOKs        *float64\n\tReasmFails      *float64\n\tFragOKs         *float64\n\tFragFails       *float64\n\tFragCreates     *float64\n}\n\ntype Icmp struct { // nolint:revive\n\tInMsgs           *float64\n\tInErrors         *float64\n\tInCsumErrors     *float64\n\tInDestUnreachs   *float64\n\tInTimeExcds      *float64\n\tInParmProbs      *float64\n\tInSrcQuenchs     *float64\n\tInRedirects      *float64\n\tInEchos          *float64\n\tInEchoReps       *float64\n\tInTimestamps     *float64\n\tInTimestampReps  *float64\n\tInAddrMasks      *float64\n\tInAddrMaskReps   *float64\n\tOutMsgs          *float64\n\tOutErrors        *float64\n\tOutDestUnreachs  *float64\n\tOutTimeExcds     *float64\n\tOutParmProbs     *float64\n\tOutSrcQuenchs    *float64\n\tOutRedirects     *float64\n\tOutEchos         *float64\n\tOutEchoReps      *float64\n\tOutTimestamps    *float64\n\tOutTimestampReps *float64\n\tOutAddrMasks     *float64\n\tOutAddrMaskReps  *float64\n}\n\ntype IcmpMsg struct {\n\tInType3  *float64\n\tOutType3 *float64\n}\n\ntype Tcp struct { // nolint:revive\n\tRtoAlgorithm *float64\n\tRtoMin       *float64\n\tRtoMax       *float64\n\tMaxConn      *float64\n\tActiveOpens  *float64\n\tPassiveOpens *float64\n\tAttemptFails *float64\n\tEstabResets  *float64\n\tCurrEstab    *float64\n\tInSegs       *float64\n\tOutSegs      *float64\n\tRetransSegs  *float64\n\tInErrs       *float64\n\tOutRsts      *float64\n\tInCsumErrors *float64\n}\n\ntype Udp struct { // nolint:revive\n\tInDatagrams  *float64\n\tNoPorts      *float64\n\tInErrors     *float64\n\tOutDatagrams *float64\n\tRcvbufErrors *float64\n\tSndbufErrors *float64\n\tInCsumErrors *float64\n\tIgnoredMulti *float64\n}\n\ntype UdpLite struct { // nolint:revive\n\tInDatagrams  *float64\n\tNoPorts      *float64\n\tInErrors     *float64\n\tOutDatagrams *float64\n\tRcvbufErrors *float64\n\tSndbufErrors *float64\n\tInCsumErrors *float64\n\tIgnoredMulti *float64\n}\n\nfunc (p Proc) Snmp() (ProcSnmp, error) {\n\tfilename := p.path(\"net/snmp\")\n\tdata, err := util.ReadFileNoStat(filename)\n\tif err != nil {\n\t\treturn ProcSnmp{PID: p.PID}, err\n\t}\n\tprocSnmp, err := parseSnmp(bytes.NewReader(data), filename)\n\tprocSnmp.PID = p.PID\n\treturn procSnmp, err\n}\n\n// parseSnmp parses the metrics from proc/<pid>/net/snmp file\n// and returns a map contains those metrics (e.g. {\"Ip\": {\"Forwarding\": 2}}).\nfunc parseSnmp(r io.Reader, fileName string) (ProcSnmp, error) {\n\tvar (\n\t\tscanner  = bufio.NewScanner(r)\n\t\tprocSnmp = ProcSnmp{}\n\t)\n\n\tfor scanner.Scan() {\n\t\tnameParts := strings.Split(scanner.Text(), \" \")\n\t\tscanner.Scan()\n\t\tvalueParts := strings.Split(scanner.Text(), \" \")\n\t\t// Remove trailing :.\n\t\tprotocol := strings.TrimSuffix(nameParts[0], \":\")\n\t\tif len(nameParts) != len(valueParts) {\n\t\t\treturn procSnmp, fmt.Errorf(\"%w: mismatch field count mismatch in %s: %s\",\n\t\t\t\tErrFileParse, fileName, protocol)\n\t\t}\n\t\tfor i := 1; i < len(nameParts); i++ {\n\t\t\tvalue, err := strconv.ParseFloat(valueParts[i], 64)\n\t\t\tif err != nil {\n\t\t\t\treturn procSnmp, err\n\t\t\t}\n\t\t\tkey := nameParts[i]\n\n\t\t\tswitch protocol {\n\t\t\tcase \"Ip\":\n\t\t\t\tswitch key {\n\t\t\t\tcase \"Forwarding\":\n\t\t\t\t\tprocSnmp.Ip.Forwarding = &value\n\t\t\t\tcase \"DefaultTTL\":\n\t\t\t\t\tprocSnmp.Ip.DefaultTTL = &value\n\t\t\t\tcase \"InReceives\":\n\t\t\t\t\tprocSnmp.Ip.InReceives = &value\n\t\t\t\tcase \"InHdrErrors\":\n\t\t\t\t\tprocSnmp.Ip.InHdrErrors = &value\n\t\t\t\tcase \"InAddrErrors\":\n\t\t\t\t\tprocSnmp.Ip.InAddrErrors = &value\n\t\t\t\tcase \"ForwDatagrams\":\n\t\t\t\t\tprocSnmp.Ip.ForwDatagrams = &value\n\t\t\t\tcase \"InUnknownProtos\":\n\t\t\t\t\tprocSnmp.Ip.InUnknownProtos = &value\n\t\t\t\tcase \"InDiscards\":\n\t\t\t\t\tprocSnmp.Ip.InDiscards = &value\n\t\t\t\tcase \"InDelivers\":\n\t\t\t\t\tprocSnmp.Ip.InDelivers = &value\n\t\t\t\tcase \"OutRequests\":\n\t\t\t\t\tprocSnmp.Ip.OutRequests = &value\n\t\t\t\tcase \"OutDiscards\":\n\t\t\t\t\tprocSnmp.Ip.OutDiscards = &value\n\t\t\t\tcase \"OutNoRoutes\":\n\t\t\t\t\tprocSnmp.Ip.OutNoRoutes = &value\n\t\t\t\tcase \"ReasmTimeout\":\n\t\t\t\t\tprocSnmp.Ip.ReasmTimeout = &value\n\t\t\t\tcase \"ReasmReqds\":\n\t\t\t\t\tprocSnmp.Ip.ReasmReqds = &value\n\t\t\t\tcase \"ReasmOKs\":\n\t\t\t\t\tprocSnmp.Ip.ReasmOKs = &value\n\t\t\t\tcase \"ReasmFails\":\n\t\t\t\t\tprocSnmp.Ip.ReasmFails = &value\n\t\t\t\tcase \"FragOKs\":\n\t\t\t\t\tprocSnmp.Ip.FragOKs = &value\n\t\t\t\tcase \"FragFails\":\n\t\t\t\t\tprocSnmp.Ip.FragFails = &value\n\t\t\t\tcase \"FragCreates\":\n\t\t\t\t\tprocSnmp.Ip.FragCreates = &value\n\t\t\t\t}\n\t\t\tcase \"Icmp\":\n\t\t\t\tswitch key {\n\t\t\t\tcase \"InMsgs\":\n\t\t\t\t\tprocSnmp.Icmp.InMsgs = &value\n\t\t\t\tcase \"InErrors\":\n\t\t\t\t\tprocSnmp.Icmp.InErrors = &value\n\t\t\t\tcase \"InCsumErrors\":\n\t\t\t\t\tprocSnmp.Icmp.InCsumErrors = &value\n\t\t\t\tcase \"InDestUnreachs\":\n\t\t\t\t\tprocSnmp.Icmp.InDestUnreachs = &value\n\t\t\t\tcase \"InTimeExcds\":\n\t\t\t\t\tprocSnmp.Icmp.InTimeExcds = &value\n\t\t\t\tcase \"InParmProbs\":\n\t\t\t\t\tprocSnmp.Icmp.InParmProbs = &value\n\t\t\t\tcase \"InSrcQuenchs\":\n\t\t\t\t\tprocSnmp.Icmp.InSrcQuenchs = &value\n\t\t\t\tcase \"InRedirects\":\n\t\t\t\t\tprocSnmp.Icmp.InRedirects = &value\n\t\t\t\tcase \"InEchos\":\n\t\t\t\t\tprocSnmp.Icmp.InEchos = &value\n\t\t\t\tcase \"InEchoReps\":\n\t\t\t\t\tprocSnmp.Icmp.InEchoReps = &value\n\t\t\t\tcase \"InTimestamps\":\n\t\t\t\t\tprocSnmp.Icmp.InTimestamps = &value\n\t\t\t\tcase \"InTimestampReps\":\n\t\t\t\t\tprocSnmp.Icmp.InTimestampReps = &value\n\t\t\t\tcase \"InAddrMasks\":\n\t\t\t\t\tprocSnmp.Icmp.InAddrMasks = &value\n\t\t\t\tcase \"InAddrMaskReps\":\n\t\t\t\t\tprocSnmp.Icmp.InAddrMaskReps = &value\n\t\t\t\tcase \"OutMsgs\":\n\t\t\t\t\tprocSnmp.Icmp.OutMsgs = &value\n\t\t\t\tcase \"OutErrors\":\n\t\t\t\t\tprocSnmp.Icmp.OutErrors = &value\n\t\t\t\tcase \"OutDestUnreachs\":\n\t\t\t\t\tprocSnmp.Icmp.OutDestUnreachs = &value\n\t\t\t\tcase \"OutTimeExcds\":\n\t\t\t\t\tprocSnmp.Icmp.OutTimeExcds = &value\n\t\t\t\tcase \"OutParmProbs\":\n\t\t\t\t\tprocSnmp.Icmp.OutParmProbs = &value\n\t\t\t\tcase \"OutSrcQuenchs\":\n\t\t\t\t\tprocSnmp.Icmp.OutSrcQuenchs = &value\n\t\t\t\tcase \"OutRedirects\":\n\t\t\t\t\tprocSnmp.Icmp.OutRedirects = &value\n\t\t\t\tcase \"OutEchos\":\n\t\t\t\t\tprocSnmp.Icmp.OutEchos = &value\n\t\t\t\tcase \"OutEchoReps\":\n\t\t\t\t\tprocSnmp.Icmp.OutEchoReps = &value\n\t\t\t\tcase \"OutTimestamps\":\n\t\t\t\t\tprocSnmp.Icmp.OutTimestamps = &value\n\t\t\t\tcase \"OutTimestampReps\":\n\t\t\t\t\tprocSnmp.Icmp.OutTimestampReps = &value\n\t\t\t\tcase \"OutAddrMasks\":\n\t\t\t\t\tprocSnmp.Icmp.OutAddrMasks = &value\n\t\t\t\tcase \"OutAddrMaskReps\":\n\t\t\t\t\tprocSnmp.Icmp.OutAddrMaskReps = &value\n\t\t\t\t}\n\t\t\tcase \"IcmpMsg\":\n\t\t\t\tswitch key {\n\t\t\t\tcase \"InType3\":\n\t\t\t\t\tprocSnmp.IcmpMsg.InType3 = &value\n\t\t\t\tcase \"OutType3\":\n\t\t\t\t\tprocSnmp.IcmpMsg.OutType3 = &value\n\t\t\t\t}\n\t\t\tcase \"Tcp\":\n\t\t\t\tswitch key {\n\t\t\t\tcase \"RtoAlgorithm\":\n\t\t\t\t\tprocSnmp.Tcp.RtoAlgorithm = &value\n\t\t\t\tcase \"RtoMin\":\n\t\t\t\t\tprocSnmp.Tcp.RtoMin = &value\n\t\t\t\tcase \"RtoMax\":\n\t\t\t\t\tprocSnmp.Tcp.RtoMax = &value\n\t\t\t\tcase \"MaxConn\":\n\t\t\t\t\tprocSnmp.Tcp.MaxConn = &value\n\t\t\t\tcase \"ActiveOpens\":\n\t\t\t\t\tprocSnmp.Tcp.ActiveOpens = &value\n\t\t\t\tcase \"PassiveOpens\":\n\t\t\t\t\tprocSnmp.Tcp.PassiveOpens = &value\n\t\t\t\tcase \"AttemptFails\":\n\t\t\t\t\tprocSnmp.Tcp.AttemptFails = &value\n\t\t\t\tcase \"EstabResets\":\n\t\t\t\t\tprocSnmp.Tcp.EstabResets = &value\n\t\t\t\tcase \"CurrEstab\":\n\t\t\t\t\tprocSnmp.Tcp.CurrEstab = &value\n\t\t\t\tcase \"InSegs\":\n\t\t\t\t\tprocSnmp.Tcp.InSegs = &value\n\t\t\t\tcase \"OutSegs\":\n\t\t\t\t\tprocSnmp.Tcp.OutSegs = &value\n\t\t\t\tcase \"RetransSegs\":\n\t\t\t\t\tprocSnmp.Tcp.RetransSegs = &value\n\t\t\t\tcase \"InErrs\":\n\t\t\t\t\tprocSnmp.Tcp.InErrs = &value\n\t\t\t\tcase \"OutRsts\":\n\t\t\t\t\tprocSnmp.Tcp.OutRsts = &value\n\t\t\t\tcase \"InCsumErrors\":\n\t\t\t\t\tprocSnmp.Tcp.InCsumErrors = &value\n\t\t\t\t}\n\t\t\tcase \"Udp\":\n\t\t\t\tswitch key {\n\t\t\t\tcase \"InDatagrams\":\n\t\t\t\t\tprocSnmp.Udp.InDatagrams = &value\n\t\t\t\tcase \"NoPorts\":\n\t\t\t\t\tprocSnmp.Udp.NoPorts = &value\n\t\t\t\tcase \"InErrors\":\n\t\t\t\t\tprocSnmp.Udp.InErrors = &value\n\t\t\t\tcase \"OutDatagrams\":\n\t\t\t\t\tprocSnmp.Udp.OutDatagrams = &value\n\t\t\t\tcase \"RcvbufErrors\":\n\t\t\t\t\tprocSnmp.Udp.RcvbufErrors = &value\n\t\t\t\tcase \"SndbufErrors\":\n\t\t\t\t\tprocSnmp.Udp.SndbufErrors = &value\n\t\t\t\tcase \"InCsumErrors\":\n\t\t\t\t\tprocSnmp.Udp.InCsumErrors = &value\n\t\t\t\tcase \"IgnoredMulti\":\n\t\t\t\t\tprocSnmp.Udp.IgnoredMulti = &value\n\t\t\t\t}\n\t\t\tcase \"UdpLite\":\n\t\t\t\tswitch key {\n\t\t\t\tcase \"InDatagrams\":\n\t\t\t\t\tprocSnmp.UdpLite.InDatagrams = &value\n\t\t\t\tcase \"NoPorts\":\n\t\t\t\t\tprocSnmp.UdpLite.NoPorts = &value\n\t\t\t\tcase \"InErrors\":\n\t\t\t\t\tprocSnmp.UdpLite.InErrors = &value\n\t\t\t\tcase \"OutDatagrams\":\n\t\t\t\t\tprocSnmp.UdpLite.OutDatagrams = &value\n\t\t\t\tcase \"RcvbufErrors\":\n\t\t\t\t\tprocSnmp.UdpLite.RcvbufErrors = &value\n\t\t\t\tcase \"SndbufErrors\":\n\t\t\t\t\tprocSnmp.UdpLite.SndbufErrors = &value\n\t\t\t\tcase \"InCsumErrors\":\n\t\t\t\t\tprocSnmp.UdpLite.InCsumErrors = &value\n\t\t\t\tcase \"IgnoredMulti\":\n\t\t\t\t\tprocSnmp.UdpLite.IgnoredMulti = &value\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn procSnmp, scanner.Err()\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc_snmp6.go",
    "content": "// Copyright 2022 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"errors\"\n\t\"io\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// ProcSnmp6 models the content of /proc/<pid>/net/snmp6.\ntype ProcSnmp6 struct {\n\t// The process ID.\n\tPID int\n\tIp6\n\tIcmp6\n\tUdp6\n\tUdpLite6\n}\n\ntype Ip6 struct { // nolint:revive\n\tInReceives       *float64\n\tInHdrErrors      *float64\n\tInTooBigErrors   *float64\n\tInNoRoutes       *float64\n\tInAddrErrors     *float64\n\tInUnknownProtos  *float64\n\tInTruncatedPkts  *float64\n\tInDiscards       *float64\n\tInDelivers       *float64\n\tOutForwDatagrams *float64\n\tOutRequests      *float64\n\tOutDiscards      *float64\n\tOutNoRoutes      *float64\n\tReasmTimeout     *float64\n\tReasmReqds       *float64\n\tReasmOKs         *float64\n\tReasmFails       *float64\n\tFragOKs          *float64\n\tFragFails        *float64\n\tFragCreates      *float64\n\tInMcastPkts      *float64\n\tOutMcastPkts     *float64\n\tInOctets         *float64\n\tOutOctets        *float64\n\tInMcastOctets    *float64\n\tOutMcastOctets   *float64\n\tInBcastOctets    *float64\n\tOutBcastOctets   *float64\n\tInNoECTPkts      *float64\n\tInECT1Pkts       *float64\n\tInECT0Pkts       *float64\n\tInCEPkts         *float64\n}\n\ntype Icmp6 struct {\n\tInMsgs                    *float64\n\tInErrors                  *float64\n\tOutMsgs                   *float64\n\tOutErrors                 *float64\n\tInCsumErrors              *float64\n\tInDestUnreachs            *float64\n\tInPktTooBigs              *float64\n\tInTimeExcds               *float64\n\tInParmProblems            *float64\n\tInEchos                   *float64\n\tInEchoReplies             *float64\n\tInGroupMembQueries        *float64\n\tInGroupMembResponses      *float64\n\tInGroupMembReductions     *float64\n\tInRouterSolicits          *float64\n\tInRouterAdvertisements    *float64\n\tInNeighborSolicits        *float64\n\tInNeighborAdvertisements  *float64\n\tInRedirects               *float64\n\tInMLDv2Reports            *float64\n\tOutDestUnreachs           *float64\n\tOutPktTooBigs             *float64\n\tOutTimeExcds              *float64\n\tOutParmProblems           *float64\n\tOutEchos                  *float64\n\tOutEchoReplies            *float64\n\tOutGroupMembQueries       *float64\n\tOutGroupMembResponses     *float64\n\tOutGroupMembReductions    *float64\n\tOutRouterSolicits         *float64\n\tOutRouterAdvertisements   *float64\n\tOutNeighborSolicits       *float64\n\tOutNeighborAdvertisements *float64\n\tOutRedirects              *float64\n\tOutMLDv2Reports           *float64\n\tInType1                   *float64\n\tInType134                 *float64\n\tInType135                 *float64\n\tInType136                 *float64\n\tInType143                 *float64\n\tOutType133                *float64\n\tOutType135                *float64\n\tOutType136                *float64\n\tOutType143                *float64\n}\n\ntype Udp6 struct { // nolint:revive\n\tInDatagrams  *float64\n\tNoPorts      *float64\n\tInErrors     *float64\n\tOutDatagrams *float64\n\tRcvbufErrors *float64\n\tSndbufErrors *float64\n\tInCsumErrors *float64\n\tIgnoredMulti *float64\n}\n\ntype UdpLite6 struct { // nolint:revive\n\tInDatagrams  *float64\n\tNoPorts      *float64\n\tInErrors     *float64\n\tOutDatagrams *float64\n\tRcvbufErrors *float64\n\tSndbufErrors *float64\n\tInCsumErrors *float64\n}\n\nfunc (p Proc) Snmp6() (ProcSnmp6, error) {\n\tfilename := p.path(\"net/snmp6\")\n\tdata, err := util.ReadFileNoStat(filename)\n\tif err != nil {\n\t\t// On systems with IPv6 disabled, this file won't exist.\n\t\t// Do nothing.\n\t\tif errors.Is(err, os.ErrNotExist) {\n\t\t\treturn ProcSnmp6{PID: p.PID}, nil\n\t\t}\n\n\t\treturn ProcSnmp6{PID: p.PID}, err\n\t}\n\n\tprocSnmp6, err := parseSNMP6Stats(bytes.NewReader(data))\n\tprocSnmp6.PID = p.PID\n\treturn procSnmp6, err\n}\n\n// parseSnmp6 parses the metrics from proc/<pid>/net/snmp6 file\n// and returns a map contains those metrics.\nfunc parseSNMP6Stats(r io.Reader) (ProcSnmp6, error) {\n\tvar (\n\t\tscanner   = bufio.NewScanner(r)\n\t\tprocSnmp6 = ProcSnmp6{}\n\t)\n\n\tfor scanner.Scan() {\n\t\tstat := strings.Fields(scanner.Text())\n\t\tif len(stat) < 2 {\n\t\t\tcontinue\n\t\t}\n\t\t// Expect to have \"6\" in metric name, skip line otherwise\n\t\tif sixIndex := strings.Index(stat[0], \"6\"); sixIndex != -1 {\n\t\t\tprotocol := stat[0][:sixIndex+1]\n\t\t\tkey := stat[0][sixIndex+1:]\n\t\t\tvalue, err := strconv.ParseFloat(stat[1], 64)\n\t\t\tif err != nil {\n\t\t\t\treturn procSnmp6, err\n\t\t\t}\n\n\t\t\tswitch protocol {\n\t\t\tcase \"Ip6\":\n\t\t\t\tswitch key {\n\t\t\t\tcase \"InReceives\":\n\t\t\t\t\tprocSnmp6.Ip6.InReceives = &value\n\t\t\t\tcase \"InHdrErrors\":\n\t\t\t\t\tprocSnmp6.Ip6.InHdrErrors = &value\n\t\t\t\tcase \"InTooBigErrors\":\n\t\t\t\t\tprocSnmp6.Ip6.InTooBigErrors = &value\n\t\t\t\tcase \"InNoRoutes\":\n\t\t\t\t\tprocSnmp6.Ip6.InNoRoutes = &value\n\t\t\t\tcase \"InAddrErrors\":\n\t\t\t\t\tprocSnmp6.Ip6.InAddrErrors = &value\n\t\t\t\tcase \"InUnknownProtos\":\n\t\t\t\t\tprocSnmp6.Ip6.InUnknownProtos = &value\n\t\t\t\tcase \"InTruncatedPkts\":\n\t\t\t\t\tprocSnmp6.Ip6.InTruncatedPkts = &value\n\t\t\t\tcase \"InDiscards\":\n\t\t\t\t\tprocSnmp6.Ip6.InDiscards = &value\n\t\t\t\tcase \"InDelivers\":\n\t\t\t\t\tprocSnmp6.Ip6.InDelivers = &value\n\t\t\t\tcase \"OutForwDatagrams\":\n\t\t\t\t\tprocSnmp6.Ip6.OutForwDatagrams = &value\n\t\t\t\tcase \"OutRequests\":\n\t\t\t\t\tprocSnmp6.Ip6.OutRequests = &value\n\t\t\t\tcase \"OutDiscards\":\n\t\t\t\t\tprocSnmp6.Ip6.OutDiscards = &value\n\t\t\t\tcase \"OutNoRoutes\":\n\t\t\t\t\tprocSnmp6.Ip6.OutNoRoutes = &value\n\t\t\t\tcase \"ReasmTimeout\":\n\t\t\t\t\tprocSnmp6.Ip6.ReasmTimeout = &value\n\t\t\t\tcase \"ReasmReqds\":\n\t\t\t\t\tprocSnmp6.Ip6.ReasmReqds = &value\n\t\t\t\tcase \"ReasmOKs\":\n\t\t\t\t\tprocSnmp6.Ip6.ReasmOKs = &value\n\t\t\t\tcase \"ReasmFails\":\n\t\t\t\t\tprocSnmp6.Ip6.ReasmFails = &value\n\t\t\t\tcase \"FragOKs\":\n\t\t\t\t\tprocSnmp6.Ip6.FragOKs = &value\n\t\t\t\tcase \"FragFails\":\n\t\t\t\t\tprocSnmp6.Ip6.FragFails = &value\n\t\t\t\tcase \"FragCreates\":\n\t\t\t\t\tprocSnmp6.Ip6.FragCreates = &value\n\t\t\t\tcase \"InMcastPkts\":\n\t\t\t\t\tprocSnmp6.Ip6.InMcastPkts = &value\n\t\t\t\tcase \"OutMcastPkts\":\n\t\t\t\t\tprocSnmp6.Ip6.OutMcastPkts = &value\n\t\t\t\tcase \"InOctets\":\n\t\t\t\t\tprocSnmp6.Ip6.InOctets = &value\n\t\t\t\tcase \"OutOctets\":\n\t\t\t\t\tprocSnmp6.Ip6.OutOctets = &value\n\t\t\t\tcase \"InMcastOctets\":\n\t\t\t\t\tprocSnmp6.Ip6.InMcastOctets = &value\n\t\t\t\tcase \"OutMcastOctets\":\n\t\t\t\t\tprocSnmp6.Ip6.OutMcastOctets = &value\n\t\t\t\tcase \"InBcastOctets\":\n\t\t\t\t\tprocSnmp6.Ip6.InBcastOctets = &value\n\t\t\t\tcase \"OutBcastOctets\":\n\t\t\t\t\tprocSnmp6.Ip6.OutBcastOctets = &value\n\t\t\t\tcase \"InNoECTPkts\":\n\t\t\t\t\tprocSnmp6.Ip6.InNoECTPkts = &value\n\t\t\t\tcase \"InECT1Pkts\":\n\t\t\t\t\tprocSnmp6.Ip6.InECT1Pkts = &value\n\t\t\t\tcase \"InECT0Pkts\":\n\t\t\t\t\tprocSnmp6.Ip6.InECT0Pkts = &value\n\t\t\t\tcase \"InCEPkts\":\n\t\t\t\t\tprocSnmp6.Ip6.InCEPkts = &value\n\n\t\t\t\t}\n\t\t\tcase \"Icmp6\":\n\t\t\t\tswitch key {\n\t\t\t\tcase \"InMsgs\":\n\t\t\t\t\tprocSnmp6.Icmp6.InMsgs = &value\n\t\t\t\tcase \"InErrors\":\n\t\t\t\t\tprocSnmp6.Icmp6.InErrors = &value\n\t\t\t\tcase \"OutMsgs\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutMsgs = &value\n\t\t\t\tcase \"OutErrors\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutErrors = &value\n\t\t\t\tcase \"InCsumErrors\":\n\t\t\t\t\tprocSnmp6.Icmp6.InCsumErrors = &value\n\t\t\t\tcase \"InDestUnreachs\":\n\t\t\t\t\tprocSnmp6.Icmp6.InDestUnreachs = &value\n\t\t\t\tcase \"InPktTooBigs\":\n\t\t\t\t\tprocSnmp6.Icmp6.InPktTooBigs = &value\n\t\t\t\tcase \"InTimeExcds\":\n\t\t\t\t\tprocSnmp6.Icmp6.InTimeExcds = &value\n\t\t\t\tcase \"InParmProblems\":\n\t\t\t\t\tprocSnmp6.Icmp6.InParmProblems = &value\n\t\t\t\tcase \"InEchos\":\n\t\t\t\t\tprocSnmp6.Icmp6.InEchos = &value\n\t\t\t\tcase \"InEchoReplies\":\n\t\t\t\t\tprocSnmp6.Icmp6.InEchoReplies = &value\n\t\t\t\tcase \"InGroupMembQueries\":\n\t\t\t\t\tprocSnmp6.Icmp6.InGroupMembQueries = &value\n\t\t\t\tcase \"InGroupMembResponses\":\n\t\t\t\t\tprocSnmp6.Icmp6.InGroupMembResponses = &value\n\t\t\t\tcase \"InGroupMembReductions\":\n\t\t\t\t\tprocSnmp6.Icmp6.InGroupMembReductions = &value\n\t\t\t\tcase \"InRouterSolicits\":\n\t\t\t\t\tprocSnmp6.Icmp6.InRouterSolicits = &value\n\t\t\t\tcase \"InRouterAdvertisements\":\n\t\t\t\t\tprocSnmp6.Icmp6.InRouterAdvertisements = &value\n\t\t\t\tcase \"InNeighborSolicits\":\n\t\t\t\t\tprocSnmp6.Icmp6.InNeighborSolicits = &value\n\t\t\t\tcase \"InNeighborAdvertisements\":\n\t\t\t\t\tprocSnmp6.Icmp6.InNeighborAdvertisements = &value\n\t\t\t\tcase \"InRedirects\":\n\t\t\t\t\tprocSnmp6.Icmp6.InRedirects = &value\n\t\t\t\tcase \"InMLDv2Reports\":\n\t\t\t\t\tprocSnmp6.Icmp6.InMLDv2Reports = &value\n\t\t\t\tcase \"OutDestUnreachs\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutDestUnreachs = &value\n\t\t\t\tcase \"OutPktTooBigs\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutPktTooBigs = &value\n\t\t\t\tcase \"OutTimeExcds\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutTimeExcds = &value\n\t\t\t\tcase \"OutParmProblems\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutParmProblems = &value\n\t\t\t\tcase \"OutEchos\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutEchos = &value\n\t\t\t\tcase \"OutEchoReplies\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutEchoReplies = &value\n\t\t\t\tcase \"OutGroupMembQueries\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutGroupMembQueries = &value\n\t\t\t\tcase \"OutGroupMembResponses\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutGroupMembResponses = &value\n\t\t\t\tcase \"OutGroupMembReductions\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutGroupMembReductions = &value\n\t\t\t\tcase \"OutRouterSolicits\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutRouterSolicits = &value\n\t\t\t\tcase \"OutRouterAdvertisements\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutRouterAdvertisements = &value\n\t\t\t\tcase \"OutNeighborSolicits\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutNeighborSolicits = &value\n\t\t\t\tcase \"OutNeighborAdvertisements\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutNeighborAdvertisements = &value\n\t\t\t\tcase \"OutRedirects\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutRedirects = &value\n\t\t\t\tcase \"OutMLDv2Reports\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutMLDv2Reports = &value\n\t\t\t\tcase \"InType1\":\n\t\t\t\t\tprocSnmp6.Icmp6.InType1 = &value\n\t\t\t\tcase \"InType134\":\n\t\t\t\t\tprocSnmp6.Icmp6.InType134 = &value\n\t\t\t\tcase \"InType135\":\n\t\t\t\t\tprocSnmp6.Icmp6.InType135 = &value\n\t\t\t\tcase \"InType136\":\n\t\t\t\t\tprocSnmp6.Icmp6.InType136 = &value\n\t\t\t\tcase \"InType143\":\n\t\t\t\t\tprocSnmp6.Icmp6.InType143 = &value\n\t\t\t\tcase \"OutType133\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutType133 = &value\n\t\t\t\tcase \"OutType135\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutType135 = &value\n\t\t\t\tcase \"OutType136\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutType136 = &value\n\t\t\t\tcase \"OutType143\":\n\t\t\t\t\tprocSnmp6.Icmp6.OutType143 = &value\n\t\t\t\t}\n\t\t\tcase \"Udp6\":\n\t\t\t\tswitch key {\n\t\t\t\tcase \"InDatagrams\":\n\t\t\t\t\tprocSnmp6.Udp6.InDatagrams = &value\n\t\t\t\tcase \"NoPorts\":\n\t\t\t\t\tprocSnmp6.Udp6.NoPorts = &value\n\t\t\t\tcase \"InErrors\":\n\t\t\t\t\tprocSnmp6.Udp6.InErrors = &value\n\t\t\t\tcase \"OutDatagrams\":\n\t\t\t\t\tprocSnmp6.Udp6.OutDatagrams = &value\n\t\t\t\tcase \"RcvbufErrors\":\n\t\t\t\t\tprocSnmp6.Udp6.RcvbufErrors = &value\n\t\t\t\tcase \"SndbufErrors\":\n\t\t\t\t\tprocSnmp6.Udp6.SndbufErrors = &value\n\t\t\t\tcase \"InCsumErrors\":\n\t\t\t\t\tprocSnmp6.Udp6.InCsumErrors = &value\n\t\t\t\tcase \"IgnoredMulti\":\n\t\t\t\t\tprocSnmp6.Udp6.IgnoredMulti = &value\n\t\t\t\t}\n\t\t\tcase \"UdpLite6\":\n\t\t\t\tswitch key {\n\t\t\t\tcase \"InDatagrams\":\n\t\t\t\t\tprocSnmp6.UdpLite6.InDatagrams = &value\n\t\t\t\tcase \"NoPorts\":\n\t\t\t\t\tprocSnmp6.UdpLite6.NoPorts = &value\n\t\t\t\tcase \"InErrors\":\n\t\t\t\t\tprocSnmp6.UdpLite6.InErrors = &value\n\t\t\t\tcase \"OutDatagrams\":\n\t\t\t\t\tprocSnmp6.UdpLite6.OutDatagrams = &value\n\t\t\t\tcase \"RcvbufErrors\":\n\t\t\t\t\tprocSnmp6.UdpLite6.RcvbufErrors = &value\n\t\t\t\tcase \"SndbufErrors\":\n\t\t\t\t\tprocSnmp6.UdpLite6.SndbufErrors = &value\n\t\t\t\tcase \"InCsumErrors\":\n\t\t\t\t\tprocSnmp6.UdpLite6.InCsumErrors = &value\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn procSnmp6, scanner.Err()\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc_stat.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// Originally, this USER_HZ value was dynamically retrieved via a sysconf call\n// which required cgo. However, that caused a lot of problems regarding\n// cross-compilation. Alternatives such as running a binary to determine the\n// value, or trying to derive it in some other way were all problematic.  After\n// much research it was determined that USER_HZ is actually hardcoded to 100 on\n// all Go-supported platforms as of the time of this writing. This is why we\n// decided to hardcode it here as well. It is not impossible that there could\n// be systems with exceptions, but they should be very exotic edge cases, and\n// in that case, the worst outcome will be two misreported metrics.\n//\n// See also the following discussions:\n//\n// - https://github.com/prometheus/node_exporter/issues/52\n// - https://github.com/prometheus/procfs/pull/2\n// - http://stackoverflow.com/questions/17410841/how-does-user-hz-solve-the-jiffy-scaling-issue\nconst userHZ = 100\n\n// ProcStat provides status information about the process,\n// read from /proc/[pid]/stat.\ntype ProcStat struct {\n\t// The process ID.\n\tPID int\n\t// The filename of the executable.\n\tComm string\n\t// The process state.\n\tState string\n\t// The PID of the parent of this process.\n\tPPID int\n\t// The process group ID of the process.\n\tPGRP int\n\t// The session ID of the process.\n\tSession int\n\t// The controlling terminal of the process.\n\tTTY int\n\t// The ID of the foreground process group of the controlling terminal of\n\t// the process.\n\tTPGID int\n\t// The kernel flags word of the process.\n\tFlags uint\n\t// The number of minor faults the process has made which have not required\n\t// loading a memory page from disk.\n\tMinFlt uint\n\t// The number of minor faults that the process's waited-for children have\n\t// made.\n\tCMinFlt uint\n\t// The number of major faults the process has made which have required\n\t// loading a memory page from disk.\n\tMajFlt uint\n\t// The number of major faults that the process's waited-for children have\n\t// made.\n\tCMajFlt uint\n\t// Amount of time that this process has been scheduled in user mode,\n\t// measured in clock ticks.\n\tUTime uint\n\t// Amount of time that this process has been scheduled in kernel mode,\n\t// measured in clock ticks.\n\tSTime uint\n\t// Amount of time that this process's waited-for children have been\n\t// scheduled in user mode, measured in clock ticks.\n\tCUTime int\n\t// Amount of time that this process's waited-for children have been\n\t// scheduled in kernel mode, measured in clock ticks.\n\tCSTime int\n\t// For processes running a real-time scheduling policy, this is the negated\n\t// scheduling priority, minus one.\n\tPriority int\n\t// The nice value, a value in the range 19 (low priority) to -20 (high\n\t// priority).\n\tNice int\n\t// Number of threads in this process.\n\tNumThreads int\n\t// The time the process started after system boot, the value is expressed\n\t// in clock ticks.\n\tStarttime uint64\n\t// Virtual memory size in bytes.\n\tVSize uint\n\t// Resident set size in pages.\n\tRSS int\n\t// Soft limit in bytes on the rss of the process.\n\tRSSLimit uint64\n\t// CPU number last executed on.\n\tProcessor uint\n\t// Real-time scheduling priority, a number in the range 1 to 99 for processes\n\t// scheduled under a real-time policy, or 0, for non-real-time processes.\n\tRTPriority uint\n\t// Scheduling policy.\n\tPolicy uint\n\t// Aggregated block I/O delays, measured in clock ticks (centiseconds).\n\tDelayAcctBlkIOTicks uint64\n\t// Guest time of the process (time spent running a virtual CPU for a guest\n\t// operating system), measured in clock ticks.\n\tGuestTime int\n\t// Guest time of the process's children, measured in clock ticks.\n\tCGuestTime int\n\n\tproc FS\n}\n\n// NewStat returns the current status information of the process.\n//\n// Deprecated: Use p.Stat() instead.\nfunc (p Proc) NewStat() (ProcStat, error) {\n\treturn p.Stat()\n}\n\n// Stat returns the current status information of the process.\nfunc (p Proc) Stat() (ProcStat, error) {\n\tdata, err := util.ReadFileNoStat(p.path(\"stat\"))\n\tif err != nil {\n\t\treturn ProcStat{}, err\n\t}\n\n\tvar (\n\t\tignoreInt64  int64\n\t\tignoreUint64 uint64\n\n\t\ts = ProcStat{PID: p.PID, proc: p.fs}\n\t\tl = bytes.Index(data, []byte(\"(\"))\n\t\tr = bytes.LastIndex(data, []byte(\")\"))\n\t)\n\n\tif l < 0 || r < 0 {\n\t\treturn ProcStat{}, fmt.Errorf(\"%w: unexpected format, couldn't extract comm %q\", ErrFileParse, data)\n\t}\n\n\ts.Comm = string(data[l+1 : r])\n\n\t// Check the following resources for the details about the particular stat\n\t// fields and their data types:\n\t// * https://man7.org/linux/man-pages/man5/proc.5.html\n\t// * https://man7.org/linux/man-pages/man3/scanf.3.html\n\t_, err = fmt.Fscan(\n\t\tbytes.NewBuffer(data[r+2:]),\n\t\t&s.State,\n\t\t&s.PPID,\n\t\t&s.PGRP,\n\t\t&s.Session,\n\t\t&s.TTY,\n\t\t&s.TPGID,\n\t\t&s.Flags,\n\t\t&s.MinFlt,\n\t\t&s.CMinFlt,\n\t\t&s.MajFlt,\n\t\t&s.CMajFlt,\n\t\t&s.UTime,\n\t\t&s.STime,\n\t\t&s.CUTime,\n\t\t&s.CSTime,\n\t\t&s.Priority,\n\t\t&s.Nice,\n\t\t&s.NumThreads,\n\t\t&ignoreInt64,\n\t\t&s.Starttime,\n\t\t&s.VSize,\n\t\t&s.RSS,\n\t\t&s.RSSLimit,\n\t\t&ignoreUint64,\n\t\t&ignoreUint64,\n\t\t&ignoreUint64,\n\t\t&ignoreUint64,\n\t\t&ignoreUint64,\n\t\t&ignoreUint64,\n\t\t&ignoreUint64,\n\t\t&ignoreUint64,\n\t\t&ignoreUint64,\n\t\t&ignoreUint64,\n\t\t&ignoreUint64,\n\t\t&ignoreUint64,\n\t\t&ignoreInt64,\n\t\t&s.Processor,\n\t\t&s.RTPriority,\n\t\t&s.Policy,\n\t\t&s.DelayAcctBlkIOTicks,\n\t\t&s.GuestTime,\n\t\t&s.CGuestTime,\n\t)\n\tif err != nil {\n\t\treturn ProcStat{}, err\n\t}\n\n\treturn s, nil\n}\n\n// VirtualMemory returns the virtual memory size in bytes.\nfunc (s ProcStat) VirtualMemory() uint {\n\treturn s.VSize\n}\n\n// ResidentMemory returns the resident memory size in bytes.\nfunc (s ProcStat) ResidentMemory() int {\n\treturn s.RSS * os.Getpagesize()\n}\n\n// StartTime returns the unix timestamp of the process in seconds.\nfunc (s ProcStat) StartTime() (float64, error) {\n\tstat, err := s.proc.Stat()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn float64(stat.BootTime) + (float64(s.Starttime) / userHZ), nil\n}\n\n// CPUTime returns the total CPU user and system time in seconds.\nfunc (s ProcStat) CPUTime() float64 {\n\treturn float64(s.UTime+s.STime) / userHZ\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc_status.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bytes\"\n\t\"math/bits\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// ProcStatus provides status information about the process,\n// read from /proc/[pid]/status.\ntype ProcStatus struct {\n\t// The process ID.\n\tPID int\n\t// The process name.\n\tName string\n\n\t// Thread group ID.\n\tTGID int\n\t// List of Pid namespace.\n\tNSpids []uint64\n\n\t// Peak virtual memory size.\n\tVmPeak uint64 // nolint:revive\n\t// Virtual memory size.\n\tVmSize uint64 // nolint:revive\n\t// Locked memory size.\n\tVmLck uint64 // nolint:revive\n\t// Pinned memory size.\n\tVmPin uint64 // nolint:revive\n\t// Peak resident set size.\n\tVmHWM uint64 // nolint:revive\n\t// Resident set size (sum of RssAnnon RssFile and RssShmem).\n\tVmRSS uint64 // nolint:revive\n\t// Size of resident anonymous memory.\n\tRssAnon uint64 // nolint:revive\n\t// Size of resident file mappings.\n\tRssFile uint64 // nolint:revive\n\t// Size of resident shared memory.\n\tRssShmem uint64 // nolint:revive\n\t// Size of data segments.\n\tVmData uint64 // nolint:revive\n\t// Size of stack segments.\n\tVmStk uint64 // nolint:revive\n\t// Size of text segments.\n\tVmExe uint64 // nolint:revive\n\t// Shared library code size.\n\tVmLib uint64 // nolint:revive\n\t// Page table entries size.\n\tVmPTE uint64 // nolint:revive\n\t// Size of second-level page tables.\n\tVmPMD uint64 // nolint:revive\n\t// Swapped-out virtual memory size by anonymous private.\n\tVmSwap uint64 // nolint:revive\n\t// Size of hugetlb memory portions\n\tHugetlbPages uint64\n\n\t// Number of voluntary context switches.\n\tVoluntaryCtxtSwitches uint64\n\t// Number of involuntary context switches.\n\tNonVoluntaryCtxtSwitches uint64\n\n\t// UIDs of the process (Real, effective, saved set, and filesystem UIDs)\n\tUIDs [4]uint64\n\t// GIDs of the process (Real, effective, saved set, and filesystem GIDs)\n\tGIDs [4]uint64\n\n\t// CpusAllowedList: List of cpu cores processes are allowed to run on.\n\tCpusAllowedList []uint64\n}\n\n// NewStatus returns the current status information of the process.\nfunc (p Proc) NewStatus() (ProcStatus, error) {\n\tdata, err := util.ReadFileNoStat(p.path(\"status\"))\n\tif err != nil {\n\t\treturn ProcStatus{}, err\n\t}\n\n\ts := ProcStatus{PID: p.PID}\n\n\tlines := strings.Split(string(data), \"\\n\")\n\tfor _, line := range lines {\n\t\tif !bytes.Contains([]byte(line), []byte(\":\")) {\n\t\t\tcontinue\n\t\t}\n\n\t\tkv := strings.SplitN(line, \":\", 2)\n\n\t\t// removes spaces\n\t\tk := strings.TrimSpace(kv[0])\n\t\tv := strings.TrimSpace(kv[1])\n\t\t// removes \"kB\"\n\t\tv = strings.TrimSuffix(v, \" kB\")\n\n\t\t// value to int when possible\n\t\t// we can skip error check here, 'cause vKBytes is not used when value is a string\n\t\tvKBytes, _ := strconv.ParseUint(v, 10, 64)\n\t\t// convert kB to B\n\t\tvBytes := vKBytes * 1024\n\n\t\terr = s.fillStatus(k, v, vKBytes, vBytes)\n\t\tif err != nil {\n\t\t\treturn ProcStatus{}, err\n\t\t}\n\t}\n\n\treturn s, nil\n}\n\nfunc (s *ProcStatus) fillStatus(k string, vString string, vUint uint64, vUintBytes uint64) error {\n\tswitch k {\n\tcase \"Tgid\":\n\t\ts.TGID = int(vUint)\n\tcase \"Name\":\n\t\ts.Name = vString\n\tcase \"Uid\":\n\t\tvar err error\n\t\tfor i, v := range strings.Split(vString, \"\\t\") {\n\t\t\ts.UIDs[i], err = strconv.ParseUint(v, 10, bits.UintSize)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\tcase \"Gid\":\n\t\tvar err error\n\t\tfor i, v := range strings.Split(vString, \"\\t\") {\n\t\t\ts.GIDs[i], err = strconv.ParseUint(v, 10, bits.UintSize)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\tcase \"NSpid\":\n\t\ts.NSpids = calcNSPidsList(vString)\n\tcase \"VmPeak\":\n\t\ts.VmPeak = vUintBytes\n\tcase \"VmSize\":\n\t\ts.VmSize = vUintBytes\n\tcase \"VmLck\":\n\t\ts.VmLck = vUintBytes\n\tcase \"VmPin\":\n\t\ts.VmPin = vUintBytes\n\tcase \"VmHWM\":\n\t\ts.VmHWM = vUintBytes\n\tcase \"VmRSS\":\n\t\ts.VmRSS = vUintBytes\n\tcase \"RssAnon\":\n\t\ts.RssAnon = vUintBytes\n\tcase \"RssFile\":\n\t\ts.RssFile = vUintBytes\n\tcase \"RssShmem\":\n\t\ts.RssShmem = vUintBytes\n\tcase \"VmData\":\n\t\ts.VmData = vUintBytes\n\tcase \"VmStk\":\n\t\ts.VmStk = vUintBytes\n\tcase \"VmExe\":\n\t\ts.VmExe = vUintBytes\n\tcase \"VmLib\":\n\t\ts.VmLib = vUintBytes\n\tcase \"VmPTE\":\n\t\ts.VmPTE = vUintBytes\n\tcase \"VmPMD\":\n\t\ts.VmPMD = vUintBytes\n\tcase \"VmSwap\":\n\t\ts.VmSwap = vUintBytes\n\tcase \"HugetlbPages\":\n\t\ts.HugetlbPages = vUintBytes\n\tcase \"voluntary_ctxt_switches\":\n\t\ts.VoluntaryCtxtSwitches = vUint\n\tcase \"nonvoluntary_ctxt_switches\":\n\t\ts.NonVoluntaryCtxtSwitches = vUint\n\tcase \"Cpus_allowed_list\":\n\t\ts.CpusAllowedList = calcCpusAllowedList(vString)\n\t}\n\n\treturn nil\n}\n\n// TotalCtxtSwitches returns the total context switch.\nfunc (s ProcStatus) TotalCtxtSwitches() uint64 {\n\treturn s.VoluntaryCtxtSwitches + s.NonVoluntaryCtxtSwitches\n}\n\nfunc calcCpusAllowedList(cpuString string) []uint64 {\n\ts := strings.Split(cpuString, \",\")\n\n\tvar g []uint64\n\n\tfor _, cpu := range s {\n\t\t// parse cpu ranges, example: 1-3=[1,2,3]\n\t\tif l := strings.Split(strings.TrimSpace(cpu), \"-\"); len(l) > 1 {\n\t\t\tstartCPU, _ := strconv.ParseUint(l[0], 10, 64)\n\t\t\tendCPU, _ := strconv.ParseUint(l[1], 10, 64)\n\n\t\t\tfor i := startCPU; i <= endCPU; i++ {\n\t\t\t\tg = append(g, i)\n\t\t\t}\n\t\t} else if len(l) == 1 {\n\t\t\tcpu, _ := strconv.ParseUint(l[0], 10, 64)\n\t\t\tg = append(g, cpu)\n\t\t}\n\n\t}\n\n\tsort.Slice(g, func(i, j int) bool { return g[i] < g[j] })\n\treturn g\n}\n\nfunc calcNSPidsList(nspidsString string) []uint64 {\n\ts := strings.Split(nspidsString, \" \")\n\tvar nspids []uint64\n\n\tfor _, nspid := range s {\n\t\tnspid, _ := strconv.ParseUint(nspid, 10, 64)\n\t\tif nspid == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tnspids = append(nspids, nspid)\n\t}\n\n\treturn nspids\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/proc_sys.go",
    "content": "// Copyright 2022 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\nfunc sysctlToPath(sysctl string) string {\n\treturn strings.Replace(sysctl, \".\", \"/\", -1)\n}\n\nfunc (fs FS) SysctlStrings(sysctl string) ([]string, error) {\n\tvalue, err := util.SysReadFile(fs.proc.Path(\"sys\", sysctlToPath(sysctl)))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn strings.Fields(value), nil\n\n}\n\nfunc (fs FS) SysctlInts(sysctl string) ([]int, error) {\n\tfields, err := fs.SysctlStrings(sysctl)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvalues := make([]int, len(fields))\n\tfor i, f := range fields {\n\t\tvp := util.NewValueParser(f)\n\t\tvalues[i] = vp.Int()\n\t\tif err := vp.Err(); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w: field %d in sysctl %s is not a valid int: %w\", ErrFileParse, i, sysctl, err)\n\t\t}\n\t}\n\treturn values, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/schedstat.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"os\"\n\t\"regexp\"\n\t\"strconv\"\n)\n\nvar (\n\tcpuLineRE  = regexp.MustCompile(`cpu(\\d+) (\\d+) (\\d+) (\\d+) (\\d+) (\\d+) (\\d+) (\\d+) (\\d+) (\\d+)`)\n\tprocLineRE = regexp.MustCompile(`(\\d+) (\\d+) (\\d+)`)\n)\n\n// Schedstat contains scheduler statistics from /proc/schedstat\n//\n// See\n// https://www.kernel.org/doc/Documentation/scheduler/sched-stats.txt\n// for a detailed description of what these numbers mean.\n//\n// Note the current kernel documentation claims some of the time units are in\n// jiffies when they are actually in nanoseconds since 2.6.23 with the\n// introduction of CFS. A fix to the documentation is pending. See\n// https://lore.kernel.org/patchwork/project/lkml/list/?series=403473\ntype Schedstat struct {\n\tCPUs []*SchedstatCPU\n}\n\n// SchedstatCPU contains the values from one \"cpu<N>\" line.\ntype SchedstatCPU struct {\n\tCPUNum string\n\n\tRunningNanoseconds uint64\n\tWaitingNanoseconds uint64\n\tRunTimeslices      uint64\n}\n\n// ProcSchedstat contains the values from `/proc/<pid>/schedstat`.\ntype ProcSchedstat struct {\n\tRunningNanoseconds uint64\n\tWaitingNanoseconds uint64\n\tRunTimeslices      uint64\n}\n\n// Schedstat reads data from `/proc/schedstat`.\nfunc (fs FS) Schedstat() (*Schedstat, error) {\n\tfile, err := os.Open(fs.proc.Path(\"schedstat\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer file.Close()\n\n\tstats := &Schedstat{}\n\tscanner := bufio.NewScanner(file)\n\n\tfor scanner.Scan() {\n\t\tmatch := cpuLineRE.FindStringSubmatch(scanner.Text())\n\t\tif match != nil {\n\t\t\tcpu := &SchedstatCPU{}\n\t\t\tcpu.CPUNum = match[1]\n\n\t\t\tcpu.RunningNanoseconds, err = strconv.ParseUint(match[8], 10, 64)\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tcpu.WaitingNanoseconds, err = strconv.ParseUint(match[9], 10, 64)\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tcpu.RunTimeslices, err = strconv.ParseUint(match[10], 10, 64)\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tstats.CPUs = append(stats.CPUs, cpu)\n\t\t}\n\t}\n\n\treturn stats, nil\n}\n\nfunc parseProcSchedstat(contents string) (ProcSchedstat, error) {\n\tvar (\n\t\tstats ProcSchedstat\n\t\terr   error\n\t)\n\tmatch := procLineRE.FindStringSubmatch(contents)\n\n\tif match != nil {\n\t\tstats.RunningNanoseconds, err = strconv.ParseUint(match[1], 10, 64)\n\t\tif err != nil {\n\t\t\treturn stats, err\n\t\t}\n\n\t\tstats.WaitingNanoseconds, err = strconv.ParseUint(match[2], 10, 64)\n\t\tif err != nil {\n\t\t\treturn stats, err\n\t\t}\n\n\t\tstats.RunTimeslices, err = strconv.ParseUint(match[3], 10, 64)\n\t\treturn stats, err\n\t}\n\n\treturn stats, errors.New(\"could not parse schedstat\")\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/slab.go",
    "content": "// Copyright 2020 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\nvar (\n\tslabSpace  = regexp.MustCompile(`\\s+`)\n\tslabVer    = regexp.MustCompile(`slabinfo -`)\n\tslabHeader = regexp.MustCompile(`# name`)\n)\n\n// Slab represents a slab pool in the kernel.\ntype Slab struct {\n\tName         string\n\tObjActive    int64\n\tObjNum       int64\n\tObjSize      int64\n\tObjPerSlab   int64\n\tPagesPerSlab int64\n\t// tunables\n\tLimit        int64\n\tBatch        int64\n\tSharedFactor int64\n\tSlabActive   int64\n\tSlabNum      int64\n\tSharedAvail  int64\n}\n\n// SlabInfo represents info for all slabs.\ntype SlabInfo struct {\n\tSlabs []*Slab\n}\n\nfunc shouldParseSlab(line string) bool {\n\tif slabVer.MatchString(line) {\n\t\treturn false\n\t}\n\tif slabHeader.MatchString(line) {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// parseV21SlabEntry is used to parse a line from /proc/slabinfo version 2.1.\nfunc parseV21SlabEntry(line string) (*Slab, error) {\n\t// First cleanup whitespace.\n\tl := slabSpace.ReplaceAllString(line, \" \")\n\ts := strings.Split(l, \" \")\n\tif len(s) != 16 {\n\t\treturn nil, fmt.Errorf(\"%w: unable to parse: %q\", ErrFileParse, line)\n\t}\n\tvar err error\n\ti := &Slab{Name: s[0]}\n\ti.ObjActive, err = strconv.ParseInt(s[1], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ti.ObjNum, err = strconv.ParseInt(s[2], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ti.ObjSize, err = strconv.ParseInt(s[3], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ti.ObjPerSlab, err = strconv.ParseInt(s[4], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ti.PagesPerSlab, err = strconv.ParseInt(s[5], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ti.Limit, err = strconv.ParseInt(s[8], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ti.Batch, err = strconv.ParseInt(s[9], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ti.SharedFactor, err = strconv.ParseInt(s[10], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ti.SlabActive, err = strconv.ParseInt(s[13], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ti.SlabNum, err = strconv.ParseInt(s[14], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ti.SharedAvail, err = strconv.ParseInt(s[15], 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn i, nil\n}\n\n// parseSlabInfo21 is used to parse a slabinfo 2.1 file.\nfunc parseSlabInfo21(r *bytes.Reader) (SlabInfo, error) {\n\tscanner := bufio.NewScanner(r)\n\ts := SlabInfo{Slabs: []*Slab{}}\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif !shouldParseSlab(line) {\n\t\t\tcontinue\n\t\t}\n\t\tslab, err := parseV21SlabEntry(line)\n\t\tif err != nil {\n\t\t\treturn s, err\n\t\t}\n\t\ts.Slabs = append(s.Slabs, slab)\n\t}\n\treturn s, nil\n}\n\n// SlabInfo reads data from `/proc/slabinfo`.\nfunc (fs FS) SlabInfo() (SlabInfo, error) {\n\t// TODO: Consider passing options to allow for parsing different\n\t// slabinfo versions. However, slabinfo 2.1 has been stable since\n\t// kernel 2.6.10 and later.\n\tdata, err := util.ReadFileNoStat(fs.proc.Path(\"slabinfo\"))\n\tif err != nil {\n\t\treturn SlabInfo{}, err\n\t}\n\n\treturn parseSlabInfo21(bytes.NewReader(data))\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/softirqs.go",
    "content": "// Copyright 2022 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// Softirqs represents the softirq statistics.\ntype Softirqs struct {\n\tHi      []uint64\n\tTimer   []uint64\n\tNetTx   []uint64\n\tNetRx   []uint64\n\tBlock   []uint64\n\tIRQPoll []uint64\n\tTasklet []uint64\n\tSched   []uint64\n\tHRTimer []uint64\n\tRCU     []uint64\n}\n\nfunc (fs FS) Softirqs() (Softirqs, error) {\n\tfileName := fs.proc.Path(\"softirqs\")\n\tdata, err := util.ReadFileNoStat(fileName)\n\tif err != nil {\n\t\treturn Softirqs{}, err\n\t}\n\n\treader := bytes.NewReader(data)\n\n\treturn parseSoftirqs(reader)\n}\n\nfunc parseSoftirqs(r io.Reader) (Softirqs, error) {\n\tvar (\n\t\tsoftirqs = Softirqs{}\n\t\tscanner  = bufio.NewScanner(r)\n\t)\n\n\tif !scanner.Scan() {\n\t\treturn Softirqs{}, fmt.Errorf(\"%w: softirqs empty\", ErrFileRead)\n\t}\n\n\tfor scanner.Scan() {\n\t\tparts := strings.Fields(scanner.Text())\n\t\tvar err error\n\n\t\t// require at least one cpu\n\t\tif len(parts) < 2 {\n\t\t\tcontinue\n\t\t}\n\t\tswitch {\n\t\tcase parts[0] == \"HI:\":\n\t\t\tperCPU := parts[1:]\n\t\t\tsoftirqs.Hi = make([]uint64, len(perCPU))\n\t\t\tfor i, count := range perCPU {\n\t\t\t\tif softirqs.Hi[i], err = strconv.ParseUint(count, 10, 64); err != nil {\n\t\t\t\t\treturn Softirqs{}, fmt.Errorf(\"%w: couldn't parse %q (HI%d): %w\", ErrFileParse, count, i, err)\n\t\t\t\t}\n\t\t\t}\n\t\tcase parts[0] == \"TIMER:\":\n\t\t\tperCPU := parts[1:]\n\t\t\tsoftirqs.Timer = make([]uint64, len(perCPU))\n\t\t\tfor i, count := range perCPU {\n\t\t\t\tif softirqs.Timer[i], err = strconv.ParseUint(count, 10, 64); err != nil {\n\t\t\t\t\treturn Softirqs{}, fmt.Errorf(\"%w: couldn't parse %q (TIMER%d): %w\", ErrFileParse, count, i, err)\n\t\t\t\t}\n\t\t\t}\n\t\tcase parts[0] == \"NET_TX:\":\n\t\t\tperCPU := parts[1:]\n\t\t\tsoftirqs.NetTx = make([]uint64, len(perCPU))\n\t\t\tfor i, count := range perCPU {\n\t\t\t\tif softirqs.NetTx[i], err = strconv.ParseUint(count, 10, 64); err != nil {\n\t\t\t\t\treturn Softirqs{}, fmt.Errorf(\"%w: couldn't parse %q (NET_TX%d): %w\", ErrFileParse, count, i, err)\n\t\t\t\t}\n\t\t\t}\n\t\tcase parts[0] == \"NET_RX:\":\n\t\t\tperCPU := parts[1:]\n\t\t\tsoftirqs.NetRx = make([]uint64, len(perCPU))\n\t\t\tfor i, count := range perCPU {\n\t\t\t\tif softirqs.NetRx[i], err = strconv.ParseUint(count, 10, 64); err != nil {\n\t\t\t\t\treturn Softirqs{}, fmt.Errorf(\"%w: couldn't parse %q (NET_RX%d): %w\", ErrFileParse, count, i, err)\n\t\t\t\t}\n\t\t\t}\n\t\tcase parts[0] == \"BLOCK:\":\n\t\t\tperCPU := parts[1:]\n\t\t\tsoftirqs.Block = make([]uint64, len(perCPU))\n\t\t\tfor i, count := range perCPU {\n\t\t\t\tif softirqs.Block[i], err = strconv.ParseUint(count, 10, 64); err != nil {\n\t\t\t\t\treturn Softirqs{}, fmt.Errorf(\"%w: couldn't parse %q (BLOCK%d): %w\", ErrFileParse, count, i, err)\n\t\t\t\t}\n\t\t\t}\n\t\tcase parts[0] == \"IRQ_POLL:\":\n\t\t\tperCPU := parts[1:]\n\t\t\tsoftirqs.IRQPoll = make([]uint64, len(perCPU))\n\t\t\tfor i, count := range perCPU {\n\t\t\t\tif softirqs.IRQPoll[i], err = strconv.ParseUint(count, 10, 64); err != nil {\n\t\t\t\t\treturn Softirqs{}, fmt.Errorf(\"%w: couldn't parse %q (IRQ_POLL%d): %w\", ErrFileParse, count, i, err)\n\t\t\t\t}\n\t\t\t}\n\t\tcase parts[0] == \"TASKLET:\":\n\t\t\tperCPU := parts[1:]\n\t\t\tsoftirqs.Tasklet = make([]uint64, len(perCPU))\n\t\t\tfor i, count := range perCPU {\n\t\t\t\tif softirqs.Tasklet[i], err = strconv.ParseUint(count, 10, 64); err != nil {\n\t\t\t\t\treturn Softirqs{}, fmt.Errorf(\"%w: couldn't parse %q (TASKLET%d): %w\", ErrFileParse, count, i, err)\n\t\t\t\t}\n\t\t\t}\n\t\tcase parts[0] == \"SCHED:\":\n\t\t\tperCPU := parts[1:]\n\t\t\tsoftirqs.Sched = make([]uint64, len(perCPU))\n\t\t\tfor i, count := range perCPU {\n\t\t\t\tif softirqs.Sched[i], err = strconv.ParseUint(count, 10, 64); err != nil {\n\t\t\t\t\treturn Softirqs{}, fmt.Errorf(\"%w: couldn't parse %q (SCHED%d): %w\", ErrFileParse, count, i, err)\n\t\t\t\t}\n\t\t\t}\n\t\tcase parts[0] == \"HRTIMER:\":\n\t\t\tperCPU := parts[1:]\n\t\t\tsoftirqs.HRTimer = make([]uint64, len(perCPU))\n\t\t\tfor i, count := range perCPU {\n\t\t\t\tif softirqs.HRTimer[i], err = strconv.ParseUint(count, 10, 64); err != nil {\n\t\t\t\t\treturn Softirqs{}, fmt.Errorf(\"%w: couldn't parse %q (HRTIMER%d): %w\", ErrFileParse, count, i, err)\n\t\t\t\t}\n\t\t\t}\n\t\tcase parts[0] == \"RCU:\":\n\t\t\tperCPU := parts[1:]\n\t\t\tsoftirqs.RCU = make([]uint64, len(perCPU))\n\t\t\tfor i, count := range perCPU {\n\t\t\t\tif softirqs.RCU[i], err = strconv.ParseUint(count, 10, 64); err != nil {\n\t\t\t\t\treturn Softirqs{}, fmt.Errorf(\"%w: couldn't parse %q (RCU%d): %w\", ErrFileParse, count, i, err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif err := scanner.Err(); err != nil {\n\t\treturn Softirqs{}, fmt.Errorf(\"%w: couldn't parse softirqs: %w\", ErrFileParse, err)\n\t}\n\n\treturn softirqs, scanner.Err()\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/stat.go",
    "content": "// Copyright 2018 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/fs\"\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// CPUStat shows how much time the cpu spend in various stages.\ntype CPUStat struct {\n\tUser      float64\n\tNice      float64\n\tSystem    float64\n\tIdle      float64\n\tIowait    float64\n\tIRQ       float64\n\tSoftIRQ   float64\n\tSteal     float64\n\tGuest     float64\n\tGuestNice float64\n}\n\n// SoftIRQStat represent the softirq statistics as exported in the procfs stat file.\n// A nice introduction can be found at https://0xax.gitbooks.io/linux-insides/content/interrupts/interrupts-9.html\n// It is possible to get per-cpu stats by reading `/proc/softirqs`.\ntype SoftIRQStat struct {\n\tHi          uint64\n\tTimer       uint64\n\tNetTx       uint64\n\tNetRx       uint64\n\tBlock       uint64\n\tBlockIoPoll uint64\n\tTasklet     uint64\n\tSched       uint64\n\tHrtimer     uint64\n\tRcu         uint64\n}\n\n// Stat represents kernel/system statistics.\ntype Stat struct {\n\t// Boot time in seconds since the Epoch.\n\tBootTime uint64\n\t// Summed up cpu statistics.\n\tCPUTotal CPUStat\n\t// Per-CPU statistics.\n\tCPU map[int64]CPUStat\n\t// Number of times interrupts were handled, which contains numbered and unnumbered IRQs.\n\tIRQTotal uint64\n\t// Number of times a numbered IRQ was triggered.\n\tIRQ []uint64\n\t// Number of times a context switch happened.\n\tContextSwitches uint64\n\t// Number of times a process was created.\n\tProcessCreated uint64\n\t// Number of processes currently running.\n\tProcessesRunning uint64\n\t// Number of processes currently blocked (waiting for IO).\n\tProcessesBlocked uint64\n\t// Number of times a softirq was scheduled.\n\tSoftIRQTotal uint64\n\t// Detailed softirq statistics.\n\tSoftIRQ SoftIRQStat\n}\n\n// Parse a cpu statistics line and returns the CPUStat struct plus the cpu id (or -1 for the overall sum).\nfunc parseCPUStat(line string) (CPUStat, int64, error) {\n\tcpuStat := CPUStat{}\n\tvar cpu string\n\n\tcount, err := fmt.Sscanf(line, \"%s %f %f %f %f %f %f %f %f %f %f\",\n\t\t&cpu,\n\t\t&cpuStat.User, &cpuStat.Nice, &cpuStat.System, &cpuStat.Idle,\n\t\t&cpuStat.Iowait, &cpuStat.IRQ, &cpuStat.SoftIRQ, &cpuStat.Steal,\n\t\t&cpuStat.Guest, &cpuStat.GuestNice)\n\n\tif err != nil && err != io.EOF {\n\t\treturn CPUStat{}, -1, fmt.Errorf(\"%w: couldn't parse %q (cpu): %w\", ErrFileParse, line, err)\n\t}\n\tif count == 0 {\n\t\treturn CPUStat{}, -1, fmt.Errorf(\"%w: couldn't parse %q (cpu): 0 elements parsed\", ErrFileParse, line)\n\t}\n\n\tcpuStat.User /= userHZ\n\tcpuStat.Nice /= userHZ\n\tcpuStat.System /= userHZ\n\tcpuStat.Idle /= userHZ\n\tcpuStat.Iowait /= userHZ\n\tcpuStat.IRQ /= userHZ\n\tcpuStat.SoftIRQ /= userHZ\n\tcpuStat.Steal /= userHZ\n\tcpuStat.Guest /= userHZ\n\tcpuStat.GuestNice /= userHZ\n\n\tif cpu == \"cpu\" {\n\t\treturn cpuStat, -1, nil\n\t}\n\n\tcpuID, err := strconv.ParseInt(cpu[3:], 10, 64)\n\tif err != nil {\n\t\treturn CPUStat{}, -1, fmt.Errorf(\"%w: couldn't parse %q (cpu/cpuid): %w\", ErrFileParse, line, err)\n\t}\n\n\treturn cpuStat, cpuID, nil\n}\n\n// Parse a softirq line.\nfunc parseSoftIRQStat(line string) (SoftIRQStat, uint64, error) {\n\tsoftIRQStat := SoftIRQStat{}\n\tvar total uint64\n\tvar prefix string\n\n\t_, err := fmt.Sscanf(line, \"%s %d %d %d %d %d %d %d %d %d %d %d\",\n\t\t&prefix, &total,\n\t\t&softIRQStat.Hi, &softIRQStat.Timer, &softIRQStat.NetTx, &softIRQStat.NetRx,\n\t\t&softIRQStat.Block, &softIRQStat.BlockIoPoll,\n\t\t&softIRQStat.Tasklet, &softIRQStat.Sched,\n\t\t&softIRQStat.Hrtimer, &softIRQStat.Rcu)\n\n\tif err != nil {\n\t\treturn SoftIRQStat{}, 0, fmt.Errorf(\"%w: couldn't parse %q (softirq): %w\", ErrFileParse, line, err)\n\t}\n\n\treturn softIRQStat, total, nil\n}\n\n// NewStat returns information about current cpu/process statistics.\n// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt\n//\n// Deprecated: Use fs.Stat() instead.\nfunc NewStat() (Stat, error) {\n\tfs, err := NewFS(fs.DefaultProcMountPoint)\n\tif err != nil {\n\t\treturn Stat{}, err\n\t}\n\treturn fs.Stat()\n}\n\n// NewStat returns information about current cpu/process statistics.\n// See: https://www.kernel.org/doc/Documentation/filesystems/proc.txt\n//\n// Deprecated: Use fs.Stat() instead.\nfunc (fs FS) NewStat() (Stat, error) {\n\treturn fs.Stat()\n}\n\n// Stat returns information about current cpu/process statistics.\n// See: https://www.kernel.org/doc/Documentation/filesystems/proc.txt\nfunc (fs FS) Stat() (Stat, error) {\n\tfileName := fs.proc.Path(\"stat\")\n\tdata, err := util.ReadFileNoStat(fileName)\n\tif err != nil {\n\t\treturn Stat{}, err\n\t}\n\tprocStat, err := parseStat(bytes.NewReader(data), fileName)\n\tif err != nil {\n\t\treturn Stat{}, err\n\t}\n\treturn procStat, nil\n}\n\n// parseStat parses the metrics from /proc/[pid]/stat.\nfunc parseStat(r io.Reader, fileName string) (Stat, error) {\n\tvar (\n\t\tscanner = bufio.NewScanner(r)\n\t\tstat    = Stat{\n\t\t\tCPU: make(map[int64]CPUStat),\n\t\t}\n\t\terr error\n\t)\n\n\t// Increase default scanner buffer to handle very long `intr` lines.\n\tbuf := make([]byte, 0, 8*1024)\n\tscanner.Buffer(buf, 1024*1024)\n\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tparts := strings.Fields(scanner.Text())\n\t\t// require at least <key> <value>\n\t\tif len(parts) < 2 {\n\t\t\tcontinue\n\t\t}\n\t\tswitch {\n\t\tcase parts[0] == \"btime\":\n\t\t\tif stat.BootTime, err = strconv.ParseUint(parts[1], 10, 64); err != nil {\n\t\t\t\treturn Stat{}, fmt.Errorf(\"%w: couldn't parse %q (btime): %w\", ErrFileParse, parts[1], err)\n\t\t\t}\n\t\tcase parts[0] == \"intr\":\n\t\t\tif stat.IRQTotal, err = strconv.ParseUint(parts[1], 10, 64); err != nil {\n\t\t\t\treturn Stat{}, fmt.Errorf(\"%w: couldn't parse %q (intr): %w\", ErrFileParse, parts[1], err)\n\t\t\t}\n\t\t\tnumberedIRQs := parts[2:]\n\t\t\tstat.IRQ = make([]uint64, len(numberedIRQs))\n\t\t\tfor i, count := range numberedIRQs {\n\t\t\t\tif stat.IRQ[i], err = strconv.ParseUint(count, 10, 64); err != nil {\n\t\t\t\t\treturn Stat{}, fmt.Errorf(\"%w: couldn't parse %q (intr%d): %w\", ErrFileParse, count, i, err)\n\t\t\t\t}\n\t\t\t}\n\t\tcase parts[0] == \"ctxt\":\n\t\t\tif stat.ContextSwitches, err = strconv.ParseUint(parts[1], 10, 64); err != nil {\n\t\t\t\treturn Stat{}, fmt.Errorf(\"%w: couldn't parse %q (ctxt): %w\", ErrFileParse, parts[1], err)\n\t\t\t}\n\t\tcase parts[0] == \"processes\":\n\t\t\tif stat.ProcessCreated, err = strconv.ParseUint(parts[1], 10, 64); err != nil {\n\t\t\t\treturn Stat{}, fmt.Errorf(\"%w: couldn't parse %q (processes): %w\", ErrFileParse, parts[1], err)\n\t\t\t}\n\t\tcase parts[0] == \"procs_running\":\n\t\t\tif stat.ProcessesRunning, err = strconv.ParseUint(parts[1], 10, 64); err != nil {\n\t\t\t\treturn Stat{}, fmt.Errorf(\"%w: couldn't parse %q (procs_running): %w\", ErrFileParse, parts[1], err)\n\t\t\t}\n\t\tcase parts[0] == \"procs_blocked\":\n\t\t\tif stat.ProcessesBlocked, err = strconv.ParseUint(parts[1], 10, 64); err != nil {\n\t\t\t\treturn Stat{}, fmt.Errorf(\"%w: couldn't parse %q (procs_blocked): %w\", ErrFileParse, parts[1], err)\n\t\t\t}\n\t\tcase parts[0] == \"softirq\":\n\t\t\tsoftIRQStats, total, err := parseSoftIRQStat(line)\n\t\t\tif err != nil {\n\t\t\t\treturn Stat{}, err\n\t\t\t}\n\t\t\tstat.SoftIRQTotal = total\n\t\t\tstat.SoftIRQ = softIRQStats\n\t\tcase strings.HasPrefix(parts[0], \"cpu\"):\n\t\t\tcpuStat, cpuID, err := parseCPUStat(line)\n\t\t\tif err != nil {\n\t\t\t\treturn Stat{}, err\n\t\t\t}\n\t\t\tif cpuID == -1 {\n\t\t\t\tstat.CPUTotal = cpuStat\n\t\t\t} else {\n\t\t\t\tstat.CPU[cpuID] = cpuStat\n\t\t\t}\n\t\t}\n\t}\n\n\tif err := scanner.Err(); err != nil {\n\t\treturn Stat{}, fmt.Errorf(\"%w: couldn't parse %q: %w\", ErrFileParse, fileName, err)\n\t}\n\n\treturn stat, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/swaps.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// Swap represents an entry in /proc/swaps.\ntype Swap struct {\n\tFilename string\n\tType     string\n\tSize     int\n\tUsed     int\n\tPriority int\n}\n\n// Swaps returns a slice of all configured swap devices on the system.\nfunc (fs FS) Swaps() ([]*Swap, error) {\n\tdata, err := util.ReadFileNoStat(fs.proc.Path(\"swaps\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn parseSwaps(data)\n}\n\nfunc parseSwaps(info []byte) ([]*Swap, error) {\n\tswaps := []*Swap{}\n\tscanner := bufio.NewScanner(bytes.NewReader(info))\n\tscanner.Scan() // ignore header line\n\tfor scanner.Scan() {\n\t\tswapString := scanner.Text()\n\t\tparsedSwap, err := parseSwapString(swapString)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tswaps = append(swaps, parsedSwap)\n\t}\n\n\terr := scanner.Err()\n\treturn swaps, err\n}\n\nfunc parseSwapString(swapString string) (*Swap, error) {\n\tvar err error\n\n\tswapFields := strings.Fields(swapString)\n\tswapLength := len(swapFields)\n\tif swapLength < 5 {\n\t\treturn nil, fmt.Errorf(\"%w: too few fields in swap string: %s\", ErrFileParse, swapString)\n\t}\n\n\tswap := &Swap{\n\t\tFilename: swapFields[0],\n\t\tType:     swapFields[1],\n\t}\n\n\tswap.Size, err = strconv.Atoi(swapFields[2])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: invalid swap size: %s: %w\", ErrFileParse, swapFields[2], err)\n\t}\n\tswap.Used, err = strconv.Atoi(swapFields[3])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: invalid swap used: %s: %w\", ErrFileParse, swapFields[3], err)\n\t}\n\tswap.Priority, err = strconv.Atoi(swapFields[4])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: invalid swap priority: %s: %w\", ErrFileParse, swapFields[4], err)\n\t}\n\n\treturn swap, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/thread.go",
    "content": "// Copyright 2022 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage procfs\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\n\tfsi \"github.com/prometheus/procfs/internal/fs\"\n)\n\n// Provide access to /proc/PID/task/TID files, for thread specific values. Since\n// such files have the same structure as /proc/PID/ ones, the data structures\n// and the parsers for the latter may be reused.\n\n// AllThreads returns a list of all currently available threads under /proc/PID.\nfunc AllThreads(pid int) (Procs, error) {\n\tfs, err := NewFS(DefaultMountPoint)\n\tif err != nil {\n\t\treturn Procs{}, err\n\t}\n\treturn fs.AllThreads(pid)\n}\n\n// AllThreads returns a list of all currently available threads for PID.\nfunc (fs FS) AllThreads(pid int) (Procs, error) {\n\ttaskPath := fs.proc.Path(strconv.Itoa(pid), \"task\")\n\td, err := os.Open(taskPath)\n\tif err != nil {\n\t\treturn Procs{}, err\n\t}\n\tdefer d.Close()\n\n\tnames, err := d.Readdirnames(-1)\n\tif err != nil {\n\t\treturn Procs{}, fmt.Errorf(\"%w: could not read %q: %w\", ErrFileRead, d.Name(), err)\n\t}\n\n\tt := Procs{}\n\tfor _, n := range names {\n\t\ttid, err := strconv.ParseInt(n, 10, 64)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tt = append(t, Proc{PID: int(tid), fs: FS{fsi.FS(taskPath), fs.isReal}})\n\t}\n\n\treturn t, nil\n}\n\n// Thread returns a process for a given PID, TID.\nfunc (fs FS) Thread(pid, tid int) (Proc, error) {\n\ttaskPath := fs.proc.Path(strconv.Itoa(pid), \"task\")\n\tif _, err := os.Stat(taskPath); err != nil {\n\t\treturn Proc{}, err\n\t}\n\treturn Proc{PID: tid, fs: FS{fsi.FS(taskPath), fs.isReal}}, nil\n}\n\n// Thread returns a process for a given TID of Proc.\nfunc (proc Proc) Thread(tid int) (Proc, error) {\n\ttfs := FS{fsi.FS(proc.path(\"task\")), proc.fs.isReal}\n\tif _, err := os.Stat(tfs.proc.Path(strconv.Itoa(tid))); err != nil {\n\t\treturn Proc{}, err\n\t}\n\treturn Proc{PID: tid, fs: tfs}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/ttar",
    "content": "#!/usr/bin/env bash\n\n# Purpose: plain text tar format\n# Limitations: - only suitable for text files, directories, and symlinks\n#              - stores only filename, content, and mode\n#              - not designed for untrusted input\n#\n# Note: must work with bash version 3.2 (macOS)\n\n# Copyright 2017 Roger Luethi\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nset -o errexit -o nounset\n\n# Sanitize environment (for instance, standard sorting of glob matches)\nexport LC_ALL=C\n\npath=\"\"\nCMD=\"\"\nARG_STRING=\"$*\"\n\n#------------------------------------------------------------------------------\n# Not all sed implementations can work on null bytes. In order to make ttar\n# work out of the box on macOS, use Python as a stream editor.\n\nUSE_PYTHON=0\n\nPYTHON_CREATE_FILTER=$(cat << 'PCF'\n#!/usr/bin/env python\n\nimport re\nimport sys\n\nfor line in sys.stdin:\n    line = re.sub(r'EOF', r'\\EOF', line)\n    line = re.sub(r'NULLBYTE', r'\\NULLBYTE', line)\n    line = re.sub('\\x00', r'NULLBYTE', line)\n    sys.stdout.write(line)\nPCF\n)\n\nPYTHON_EXTRACT_FILTER=$(cat << 'PEF'\n#!/usr/bin/env python\n\nimport re\nimport sys\n\nfor line in sys.stdin:\n    line = re.sub(r'(?<!\\\\)NULLBYTE', '\\x00', line)\n    line = re.sub(r'\\\\NULLBYTE', 'NULLBYTE', line)\n    line = re.sub(r'([^\\\\])EOF', r'\\1', line)\n    line = re.sub(r'\\\\EOF', 'EOF', line)\n    sys.stdout.write(line)\nPEF\n)\n\nfunction test_environment {\n    if [[ \"$(echo \"a\" | sed 's/a/\\x0/' | wc -c)\" -ne 2 ]]; then\n        echo \"WARNING sed unable to handle null bytes, using Python (slow).\"\n        if ! which python >/dev/null; then\n            echo \"ERROR Python not found. Aborting.\"\n            exit 2\n        fi\n        USE_PYTHON=1\n    fi\n}\n\n#------------------------------------------------------------------------------\n\nfunction usage {\n    bname=$(basename \"$0\")\n    cat << USAGE\nUsage:   $bname [-C <DIR>] -c -f <ARCHIVE> <FILE...> (create archive)\n         $bname            -t -f <ARCHIVE>           (list archive contents)\n         $bname [-C <DIR>] -x -f <ARCHIVE>           (extract archive)\n\nOptions:\n         -C <DIR>           (change directory)\n         -v                 (verbose)\n         --recursive-unlink (recursively delete existing directory if path\n                             collides with file or directory to extract)\n\nExample: Change to sysfs directory, create ttar file from fixtures directory\n         $bname -C sysfs -c -f sysfs/fixtures.ttar fixtures/\nUSAGE\nexit \"$1\"\n}\n\nfunction vecho {\n    if [ \"${VERBOSE:-}\" == \"yes\" ]; then\n        echo >&7 \"$@\"\n    fi\n}\n\nfunction set_cmd {\n    if [ -n \"$CMD\" ]; then\n        echo \"ERROR: more than one command given\"\n        echo\n        usage 2\n    fi\n    CMD=$1\n}\n\nunset VERBOSE\nunset RECURSIVE_UNLINK\n\nwhile getopts :cf:-:htxvC: opt; do\n    case $opt in\n        c)\n            set_cmd \"create\"\n            ;;\n        f)\n            ARCHIVE=$OPTARG\n            ;;\n        h)\n            usage 0\n            ;;\n        t)\n            set_cmd \"list\"\n            ;;\n        x)\n            set_cmd \"extract\"\n            ;;\n        v)\n            VERBOSE=yes\n            exec 7>&1\n            ;;\n        C)\n            CDIR=$OPTARG\n            ;;\n        -)\n            case $OPTARG in\n                recursive-unlink)\n                    RECURSIVE_UNLINK=\"yes\"\n                    ;;\n                *)\n                    echo -e \"Error: invalid option -$OPTARG\"\n                    echo\n                    usage 1\n                    ;;\n            esac\n            ;;\n        *)\n            echo >&2 \"ERROR: invalid option -$OPTARG\"\n            echo\n            usage 1\n            ;;\n    esac\ndone\n\n# Remove processed options from arguments\nshift $(( OPTIND - 1 ));\n\nif [ \"${CMD:-}\" == \"\" ]; then\n    echo >&2 \"ERROR: no command given\"\n    echo\n    usage 1\nelif [ \"${ARCHIVE:-}\" == \"\" ]; then\n    echo >&2 \"ERROR: no archive name given\"\n    echo\n    usage 1\nfi\n\nfunction list {\n    local path=\"\"\n    local size=0\n    local line_no=0\n    local ttar_file=$1\n    if [ -n \"${2:-}\" ]; then\n        echo >&2 \"ERROR: too many arguments.\"\n        echo\n        usage 1\n    fi\n    if [ ! -e \"$ttar_file\" ]; then\n        echo >&2 \"ERROR: file not found ($ttar_file)\"\n        echo\n        usage 1\n    fi\n    while read -r line; do\n        line_no=$(( line_no + 1 ))\n        if [ $size -gt 0 ]; then\n            size=$(( size - 1 ))\n            continue\n        fi\n        if [[ $line =~ ^Path:\\ (.*)$ ]]; then\n            path=${BASH_REMATCH[1]}\n        elif [[ $line =~ ^Lines:\\ (.*)$ ]]; then\n            size=${BASH_REMATCH[1]}\n            echo \"$path\"\n        elif [[ $line =~ ^Directory:\\ (.*)$ ]]; then\n            path=${BASH_REMATCH[1]}\n            echo \"$path/\"\n        elif [[ $line =~ ^SymlinkTo:\\ (.*)$ ]]; then\n            echo  \"$path -> ${BASH_REMATCH[1]}\"\n        fi\n    done < \"$ttar_file\"\n}\n\nfunction extract {\n    local path=\"\"\n    local size=0\n    local line_no=0\n    local ttar_file=$1\n    if [ -n \"${2:-}\" ]; then\n        echo >&2 \"ERROR: too many arguments.\"\n        echo\n        usage 1\n    fi\n    if [ ! -e \"$ttar_file\" ]; then\n        echo >&2 \"ERROR: file not found ($ttar_file)\"\n        echo\n        usage 1\n    fi\n    while IFS= read -r line; do\n        line_no=$(( line_no + 1 ))\n        local eof_without_newline\n        if [ \"$size\" -gt 0 ]; then\n            if [[ \"$line\" =~ [^\\\\]EOF ]]; then\n                # An EOF not preceded by a backslash indicates that the line\n                # does not end with a newline\n                eof_without_newline=1\n            else\n                eof_without_newline=0\n            fi\n            # Replace NULLBYTE with null byte if at beginning of line\n            # Replace NULLBYTE with null byte unless preceded by backslash\n            # Remove one backslash in front of NULLBYTE (if any)\n            # Remove EOF unless preceded by backslash\n            # Remove one backslash in front of EOF\n            if [ $USE_PYTHON -eq 1 ]; then\n                echo -n \"$line\" | python -c \"$PYTHON_EXTRACT_FILTER\" >> \"$path\"\n            else\n                # The repeated pattern makes up for sed's lack of negative\n                # lookbehind assertions (for consecutive null bytes).\n                echo -n \"$line\" | \\\n                    sed -e 's/^NULLBYTE/\\x0/g;\n                            s/\\([^\\\\]\\)NULLBYTE/\\1\\x0/g;\n                            s/\\([^\\\\]\\)NULLBYTE/\\1\\x0/g;\n                            s/\\\\NULLBYTE/NULLBYTE/g;\n                            s/\\([^\\\\]\\)EOF/\\1/g;\n                            s/\\\\EOF/EOF/g;\n                    ' >> \"$path\"\n            fi\n            if [[ \"$eof_without_newline\" -eq 0 ]]; then\n                echo >> \"$path\"\n            fi\n            size=$(( size - 1 ))\n            continue\n        fi\n        if [[ $line =~ ^Path:\\ (.*)$ ]]; then\n            path=${BASH_REMATCH[1]}\n            if [ -L \"$path\" ]; then\n                rm \"$path\"\n            elif [ -d \"$path\" ]; then\n                if [ \"${RECURSIVE_UNLINK:-}\" == \"yes\" ]; then\n                    rm -r \"$path\"\n                else\n                    # Safe because symlinks to directories are dealt with above\n                    rmdir \"$path\"\n                fi\n            elif [ -e \"$path\" ]; then\n                rm \"$path\"\n            fi\n        elif [[ $line =~ ^Lines:\\ (.*)$ ]]; then\n            size=${BASH_REMATCH[1]}\n            # Create file even if it is zero-length.\n            touch \"$path\"\n            vecho \"    $path\"\n        elif [[ $line =~ ^Mode:\\ (.*)$ ]]; then\n            mode=${BASH_REMATCH[1]}\n            chmod \"$mode\" \"$path\"\n            vecho \"$mode\"\n        elif [[ $line =~ ^Directory:\\ (.*)$ ]]; then\n            path=${BASH_REMATCH[1]}\n            mkdir -p \"$path\"\n            vecho \"    $path/\"\n        elif [[ $line =~ ^SymlinkTo:\\ (.*)$ ]]; then\n            ln -s \"${BASH_REMATCH[1]}\" \"$path\"\n            vecho \"    $path -> ${BASH_REMATCH[1]}\"\n        elif [[ $line =~ ^# ]]; then\n            # Ignore comments between files\n            continue\n        else\n            echo >&2 \"ERROR: Unknown keyword on line $line_no: $line\"\n            exit 1\n        fi\n    done < \"$ttar_file\"\n}\n\nfunction div {\n    echo \"# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\" \\\n         \"- - - - - -\"\n}\n\nfunction get_mode {\n    local mfile=$1\n    if [ -z \"${STAT_OPTION:-}\" ]; then\n        if stat -c '%a' \"$mfile\" >/dev/null 2>&1; then\n            # GNU stat\n            STAT_OPTION='-c'\n            STAT_FORMAT='%a'\n        else\n            # BSD stat\n            STAT_OPTION='-f'\n            # Octal output, user/group/other (omit file type, sticky bit)\n            STAT_FORMAT='%OLp'\n        fi\n    fi\n    stat \"${STAT_OPTION}\" \"${STAT_FORMAT}\" \"$mfile\"\n}\n\nfunction _create {\n    shopt -s nullglob\n    local mode\n    local eof_without_newline\n    while (( \"$#\" )); do\n        file=$1\n        if [ -L \"$file\" ]; then\n            echo \"Path: $file\"\n            symlinkTo=$(readlink \"$file\")\n            echo \"SymlinkTo: $symlinkTo\"\n            vecho \"    $file -> $symlinkTo\"\n            div\n        elif [ -d \"$file\" ]; then\n            # Strip trailing slash (if there is one)\n            file=${file%/}\n            echo \"Directory: $file\"\n            mode=$(get_mode \"$file\")\n            echo \"Mode: $mode\"\n            vecho \"$mode $file/\"\n            div\n            # Find all files and dirs, including hidden/dot files\n            for x in \"$file/\"{*,.[^.]*}; do\n                _create \"$x\"\n            done\n        elif [ -f \"$file\" ]; then\n            echo \"Path: $file\"\n            lines=$(wc -l \"$file\"|awk '{print $1}')\n            eof_without_newline=0\n            if [[ \"$(wc -c \"$file\"|awk '{print $1}')\" -gt 0 ]] && \\\n                    [[ \"$(tail -c 1 \"$file\" | wc -l)\" -eq 0 ]]; then\n                eof_without_newline=1\n                lines=$((lines+1))\n            fi\n            echo \"Lines: $lines\"\n            # Add backslash in front of EOF\n            # Add backslash in front of NULLBYTE\n            # Replace null byte with NULLBYTE\n            if [ $USE_PYTHON -eq 1 ]; then\n                < \"$file\" python -c \"$PYTHON_CREATE_FILTER\"\n            else\n                < \"$file\" \\\n                    sed 's/EOF/\\\\EOF/g;\n                            s/NULLBYTE/\\\\NULLBYTE/g;\n                            s/\\x0/NULLBYTE/g;\n                    '\n            fi\n            if [[ \"$eof_without_newline\" -eq 1 ]]; then\n                # Finish line with EOF to indicate that the original line did\n                # not end with a linefeed\n                echo \"EOF\"\n            fi\n            mode=$(get_mode \"$file\")\n            echo \"Mode: $mode\"\n            vecho \"$mode $file\"\n            div\n        else\n            echo >&2 \"ERROR: file not found ($file in $(pwd))\"\n            exit 2\n        fi\n        shift\n    done\n}\n\nfunction create {\n    ttar_file=$1\n    shift\n    if [ -z \"${1:-}\" ]; then\n        echo >&2 \"ERROR: missing arguments.\"\n        echo\n        usage 1\n    fi\n    if [ -e \"$ttar_file\" ]; then\n        rm \"$ttar_file\"\n    fi\n    exec > \"$ttar_file\"\n    echo \"# Archive created by ttar $ARG_STRING\"\n    _create \"$@\"\n}\n\ntest_environment\n\nif [ -n \"${CDIR:-}\" ]; then\n    if [[ \"$ARCHIVE\" != /* ]]; then\n        # Relative path: preserve the archive's location before changing\n        # directory\n        ARCHIVE=\"$(pwd)/$ARCHIVE\"\n    fi\n    cd \"$CDIR\"\nfi\n\n\"$CMD\" \"$ARCHIVE\" \"$@\"\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/vm.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build !windows\n// +build !windows\n\npackage procfs\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// The VM interface is described at\n//\n//\thttps://www.kernel.org/doc/Documentation/sysctl/vm.txt\n//\n// Each setting is exposed as a single file.\n// Each file contains one line with a single numerical value, except lowmem_reserve_ratio which holds an array\n// and numa_zonelist_order (deprecated) which is a string.\ntype VM struct {\n\tAdminReserveKbytes        *int64   // /proc/sys/vm/admin_reserve_kbytes\n\tBlockDump                 *int64   // /proc/sys/vm/block_dump\n\tCompactUnevictableAllowed *int64   // /proc/sys/vm/compact_unevictable_allowed\n\tDirtyBackgroundBytes      *int64   // /proc/sys/vm/dirty_background_bytes\n\tDirtyBackgroundRatio      *int64   // /proc/sys/vm/dirty_background_ratio\n\tDirtyBytes                *int64   // /proc/sys/vm/dirty_bytes\n\tDirtyExpireCentisecs      *int64   // /proc/sys/vm/dirty_expire_centisecs\n\tDirtyRatio                *int64   // /proc/sys/vm/dirty_ratio\n\tDirtytimeExpireSeconds    *int64   // /proc/sys/vm/dirtytime_expire_seconds\n\tDirtyWritebackCentisecs   *int64   // /proc/sys/vm/dirty_writeback_centisecs\n\tDropCaches                *int64   // /proc/sys/vm/drop_caches\n\tExtfragThreshold          *int64   // /proc/sys/vm/extfrag_threshold\n\tHugetlbShmGroup           *int64   // /proc/sys/vm/hugetlb_shm_group\n\tLaptopMode                *int64   // /proc/sys/vm/laptop_mode\n\tLegacyVaLayout            *int64   // /proc/sys/vm/legacy_va_layout\n\tLowmemReserveRatio        []*int64 // /proc/sys/vm/lowmem_reserve_ratio\n\tMaxMapCount               *int64   // /proc/sys/vm/max_map_count\n\tMemoryFailureEarlyKill    *int64   // /proc/sys/vm/memory_failure_early_kill\n\tMemoryFailureRecovery     *int64   // /proc/sys/vm/memory_failure_recovery\n\tMinFreeKbytes             *int64   // /proc/sys/vm/min_free_kbytes\n\tMinSlabRatio              *int64   // /proc/sys/vm/min_slab_ratio\n\tMinUnmappedRatio          *int64   // /proc/sys/vm/min_unmapped_ratio\n\tMmapMinAddr               *int64   // /proc/sys/vm/mmap_min_addr\n\tNrHugepages               *int64   // /proc/sys/vm/nr_hugepages\n\tNrHugepagesMempolicy      *int64   // /proc/sys/vm/nr_hugepages_mempolicy\n\tNrOvercommitHugepages     *int64   // /proc/sys/vm/nr_overcommit_hugepages\n\tNumaStat                  *int64   // /proc/sys/vm/numa_stat\n\tNumaZonelistOrder         string   // /proc/sys/vm/numa_zonelist_order\n\tOomDumpTasks              *int64   // /proc/sys/vm/oom_dump_tasks\n\tOomKillAllocatingTask     *int64   // /proc/sys/vm/oom_kill_allocating_task\n\tOvercommitKbytes          *int64   // /proc/sys/vm/overcommit_kbytes\n\tOvercommitMemory          *int64   // /proc/sys/vm/overcommit_memory\n\tOvercommitRatio           *int64   // /proc/sys/vm/overcommit_ratio\n\tPageCluster               *int64   // /proc/sys/vm/page-cluster\n\tPanicOnOom                *int64   // /proc/sys/vm/panic_on_oom\n\tPercpuPagelistFraction    *int64   // /proc/sys/vm/percpu_pagelist_fraction\n\tStatInterval              *int64   // /proc/sys/vm/stat_interval\n\tSwappiness                *int64   // /proc/sys/vm/swappiness\n\tUserReserveKbytes         *int64   // /proc/sys/vm/user_reserve_kbytes\n\tVfsCachePressure          *int64   // /proc/sys/vm/vfs_cache_pressure\n\tWatermarkBoostFactor      *int64   // /proc/sys/vm/watermark_boost_factor\n\tWatermarkScaleFactor      *int64   // /proc/sys/vm/watermark_scale_factor\n\tZoneReclaimMode           *int64   // /proc/sys/vm/zone_reclaim_mode\n}\n\n// VM reads the VM statistics from the specified `proc` filesystem.\nfunc (fs FS) VM() (*VM, error) {\n\tpath := fs.proc.Path(\"sys/vm\")\n\tfile, err := os.Stat(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif !file.Mode().IsDir() {\n\t\treturn nil, fmt.Errorf(\"%w: %s is not a directory\", ErrFileRead, path)\n\t}\n\n\tfiles, err := os.ReadDir(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar vm VM\n\tfor _, f := range files {\n\t\tif f.IsDir() {\n\t\t\tcontinue\n\t\t}\n\n\t\tname := filepath.Join(path, f.Name())\n\t\t// ignore errors on read, as there are some write only\n\t\t// in /proc/sys/vm\n\t\tvalue, err := util.SysReadFile(name)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tvp := util.NewValueParser(value)\n\n\t\tswitch f.Name() {\n\t\tcase \"admin_reserve_kbytes\":\n\t\t\tvm.AdminReserveKbytes = vp.PInt64()\n\t\tcase \"block_dump\":\n\t\t\tvm.BlockDump = vp.PInt64()\n\t\tcase \"compact_unevictable_allowed\":\n\t\t\tvm.CompactUnevictableAllowed = vp.PInt64()\n\t\tcase \"dirty_background_bytes\":\n\t\t\tvm.DirtyBackgroundBytes = vp.PInt64()\n\t\tcase \"dirty_background_ratio\":\n\t\t\tvm.DirtyBackgroundRatio = vp.PInt64()\n\t\tcase \"dirty_bytes\":\n\t\t\tvm.DirtyBytes = vp.PInt64()\n\t\tcase \"dirty_expire_centisecs\":\n\t\t\tvm.DirtyExpireCentisecs = vp.PInt64()\n\t\tcase \"dirty_ratio\":\n\t\t\tvm.DirtyRatio = vp.PInt64()\n\t\tcase \"dirtytime_expire_seconds\":\n\t\t\tvm.DirtytimeExpireSeconds = vp.PInt64()\n\t\tcase \"dirty_writeback_centisecs\":\n\t\t\tvm.DirtyWritebackCentisecs = vp.PInt64()\n\t\tcase \"drop_caches\":\n\t\t\tvm.DropCaches = vp.PInt64()\n\t\tcase \"extfrag_threshold\":\n\t\t\tvm.ExtfragThreshold = vp.PInt64()\n\t\tcase \"hugetlb_shm_group\":\n\t\t\tvm.HugetlbShmGroup = vp.PInt64()\n\t\tcase \"laptop_mode\":\n\t\t\tvm.LaptopMode = vp.PInt64()\n\t\tcase \"legacy_va_layout\":\n\t\t\tvm.LegacyVaLayout = vp.PInt64()\n\t\tcase \"lowmem_reserve_ratio\":\n\t\t\tstringSlice := strings.Fields(value)\n\t\t\tpint64Slice := make([]*int64, 0, len(stringSlice))\n\t\t\tfor _, value := range stringSlice {\n\t\t\t\tvp := util.NewValueParser(value)\n\t\t\t\tpint64Slice = append(pint64Slice, vp.PInt64())\n\t\t\t}\n\t\t\tvm.LowmemReserveRatio = pint64Slice\n\t\tcase \"max_map_count\":\n\t\t\tvm.MaxMapCount = vp.PInt64()\n\t\tcase \"memory_failure_early_kill\":\n\t\t\tvm.MemoryFailureEarlyKill = vp.PInt64()\n\t\tcase \"memory_failure_recovery\":\n\t\t\tvm.MemoryFailureRecovery = vp.PInt64()\n\t\tcase \"min_free_kbytes\":\n\t\t\tvm.MinFreeKbytes = vp.PInt64()\n\t\tcase \"min_slab_ratio\":\n\t\t\tvm.MinSlabRatio = vp.PInt64()\n\t\tcase \"min_unmapped_ratio\":\n\t\t\tvm.MinUnmappedRatio = vp.PInt64()\n\t\tcase \"mmap_min_addr\":\n\t\t\tvm.MmapMinAddr = vp.PInt64()\n\t\tcase \"nr_hugepages\":\n\t\t\tvm.NrHugepages = vp.PInt64()\n\t\tcase \"nr_hugepages_mempolicy\":\n\t\t\tvm.NrHugepagesMempolicy = vp.PInt64()\n\t\tcase \"nr_overcommit_hugepages\":\n\t\t\tvm.NrOvercommitHugepages = vp.PInt64()\n\t\tcase \"numa_stat\":\n\t\t\tvm.NumaStat = vp.PInt64()\n\t\tcase \"numa_zonelist_order\":\n\t\t\tvm.NumaZonelistOrder = value\n\t\tcase \"oom_dump_tasks\":\n\t\t\tvm.OomDumpTasks = vp.PInt64()\n\t\tcase \"oom_kill_allocating_task\":\n\t\t\tvm.OomKillAllocatingTask = vp.PInt64()\n\t\tcase \"overcommit_kbytes\":\n\t\t\tvm.OvercommitKbytes = vp.PInt64()\n\t\tcase \"overcommit_memory\":\n\t\t\tvm.OvercommitMemory = vp.PInt64()\n\t\tcase \"overcommit_ratio\":\n\t\t\tvm.OvercommitRatio = vp.PInt64()\n\t\tcase \"page-cluster\":\n\t\t\tvm.PageCluster = vp.PInt64()\n\t\tcase \"panic_on_oom\":\n\t\t\tvm.PanicOnOom = vp.PInt64()\n\t\tcase \"percpu_pagelist_fraction\":\n\t\t\tvm.PercpuPagelistFraction = vp.PInt64()\n\t\tcase \"stat_interval\":\n\t\t\tvm.StatInterval = vp.PInt64()\n\t\tcase \"swappiness\":\n\t\t\tvm.Swappiness = vp.PInt64()\n\t\tcase \"user_reserve_kbytes\":\n\t\t\tvm.UserReserveKbytes = vp.PInt64()\n\t\tcase \"vfs_cache_pressure\":\n\t\t\tvm.VfsCachePressure = vp.PInt64()\n\t\tcase \"watermark_boost_factor\":\n\t\t\tvm.WatermarkBoostFactor = vp.PInt64()\n\t\tcase \"watermark_scale_factor\":\n\t\t\tvm.WatermarkScaleFactor = vp.PInt64()\n\t\tcase \"zone_reclaim_mode\":\n\t\t\tvm.ZoneReclaimMode = vp.PInt64()\n\t\t}\n\t\tif err := vp.Err(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn &vm, nil\n}\n"
  },
  {
    "path": "vendor/github.com/prometheus/procfs/zoneinfo.go",
    "content": "// Copyright 2019 The Prometheus Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n//go:build !windows\n// +build !windows\n\npackage procfs\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/prometheus/procfs/internal/util\"\n)\n\n// Zoneinfo holds info parsed from /proc/zoneinfo.\ntype Zoneinfo struct {\n\tNode                       string\n\tZone                       string\n\tNrFreePages                *int64\n\tMin                        *int64\n\tLow                        *int64\n\tHigh                       *int64\n\tScanned                    *int64\n\tSpanned                    *int64\n\tPresent                    *int64\n\tManaged                    *int64\n\tNrActiveAnon               *int64\n\tNrInactiveAnon             *int64\n\tNrIsolatedAnon             *int64\n\tNrAnonPages                *int64\n\tNrAnonTransparentHugepages *int64\n\tNrActiveFile               *int64\n\tNrInactiveFile             *int64\n\tNrIsolatedFile             *int64\n\tNrFilePages                *int64\n\tNrSlabReclaimable          *int64\n\tNrSlabUnreclaimable        *int64\n\tNrMlockStack               *int64\n\tNrKernelStack              *int64\n\tNrMapped                   *int64\n\tNrDirty                    *int64\n\tNrWriteback                *int64\n\tNrUnevictable              *int64\n\tNrShmem                    *int64\n\tNrDirtied                  *int64\n\tNrWritten                  *int64\n\tNumaHit                    *int64\n\tNumaMiss                   *int64\n\tNumaForeign                *int64\n\tNumaInterleave             *int64\n\tNumaLocal                  *int64\n\tNumaOther                  *int64\n\tProtection                 []*int64\n}\n\nvar nodeZoneRE = regexp.MustCompile(`(\\d+), zone\\s+(\\w+)`)\n\n// Zoneinfo parses an zoneinfo-file (/proc/zoneinfo) and returns a slice of\n// structs containing the relevant info.  More information available here:\n// https://www.kernel.org/doc/Documentation/sysctl/vm.txt\nfunc (fs FS) Zoneinfo() ([]Zoneinfo, error) {\n\tdata, err := os.ReadFile(fs.proc.Path(\"zoneinfo\"))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: error reading zoneinfo %q: %w\", ErrFileRead, fs.proc.Path(\"zoneinfo\"), err)\n\t}\n\tzoneinfo, err := parseZoneinfo(data)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: error parsing zoneinfo %q: %w\", ErrFileParse, fs.proc.Path(\"zoneinfo\"), err)\n\t}\n\treturn zoneinfo, nil\n}\n\nfunc parseZoneinfo(zoneinfoData []byte) ([]Zoneinfo, error) {\n\n\tzoneinfo := []Zoneinfo{}\n\n\tzoneinfoBlocks := bytes.Split(zoneinfoData, []byte(\"\\nNode\"))\n\tfor _, block := range zoneinfoBlocks {\n\t\tvar zoneinfoElement Zoneinfo\n\t\tlines := strings.Split(string(block), \"\\n\")\n\t\tfor _, line := range lines {\n\n\t\t\tif nodeZone := nodeZoneRE.FindStringSubmatch(line); nodeZone != nil {\n\t\t\t\tzoneinfoElement.Node = nodeZone[1]\n\t\t\t\tzoneinfoElement.Zone = nodeZone[2]\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif strings.HasPrefix(strings.TrimSpace(line), \"per-node stats\") {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tparts := strings.Fields(strings.TrimSpace(line))\n\t\t\tif len(parts) < 2 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tvp := util.NewValueParser(parts[1])\n\t\t\tswitch parts[0] {\n\t\t\tcase \"nr_free_pages\":\n\t\t\t\tzoneinfoElement.NrFreePages = vp.PInt64()\n\t\t\tcase \"min\":\n\t\t\t\tzoneinfoElement.Min = vp.PInt64()\n\t\t\tcase \"low\":\n\t\t\t\tzoneinfoElement.Low = vp.PInt64()\n\t\t\tcase \"high\":\n\t\t\t\tzoneinfoElement.High = vp.PInt64()\n\t\t\tcase \"scanned\":\n\t\t\t\tzoneinfoElement.Scanned = vp.PInt64()\n\t\t\tcase \"spanned\":\n\t\t\t\tzoneinfoElement.Spanned = vp.PInt64()\n\t\t\tcase \"present\":\n\t\t\t\tzoneinfoElement.Present = vp.PInt64()\n\t\t\tcase \"managed\":\n\t\t\t\tzoneinfoElement.Managed = vp.PInt64()\n\t\t\tcase \"nr_active_anon\":\n\t\t\t\tzoneinfoElement.NrActiveAnon = vp.PInt64()\n\t\t\tcase \"nr_inactive_anon\":\n\t\t\t\tzoneinfoElement.NrInactiveAnon = vp.PInt64()\n\t\t\tcase \"nr_isolated_anon\":\n\t\t\t\tzoneinfoElement.NrIsolatedAnon = vp.PInt64()\n\t\t\tcase \"nr_anon_pages\":\n\t\t\t\tzoneinfoElement.NrAnonPages = vp.PInt64()\n\t\t\tcase \"nr_anon_transparent_hugepages\":\n\t\t\t\tzoneinfoElement.NrAnonTransparentHugepages = vp.PInt64()\n\t\t\tcase \"nr_active_file\":\n\t\t\t\tzoneinfoElement.NrActiveFile = vp.PInt64()\n\t\t\tcase \"nr_inactive_file\":\n\t\t\t\tzoneinfoElement.NrInactiveFile = vp.PInt64()\n\t\t\tcase \"nr_isolated_file\":\n\t\t\t\tzoneinfoElement.NrIsolatedFile = vp.PInt64()\n\t\t\tcase \"nr_file_pages\":\n\t\t\t\tzoneinfoElement.NrFilePages = vp.PInt64()\n\t\t\tcase \"nr_slab_reclaimable\":\n\t\t\t\tzoneinfoElement.NrSlabReclaimable = vp.PInt64()\n\t\t\tcase \"nr_slab_unreclaimable\":\n\t\t\t\tzoneinfoElement.NrSlabUnreclaimable = vp.PInt64()\n\t\t\tcase \"nr_mlock_stack\":\n\t\t\t\tzoneinfoElement.NrMlockStack = vp.PInt64()\n\t\t\tcase \"nr_kernel_stack\":\n\t\t\t\tzoneinfoElement.NrKernelStack = vp.PInt64()\n\t\t\tcase \"nr_mapped\":\n\t\t\t\tzoneinfoElement.NrMapped = vp.PInt64()\n\t\t\tcase \"nr_dirty\":\n\t\t\t\tzoneinfoElement.NrDirty = vp.PInt64()\n\t\t\tcase \"nr_writeback\":\n\t\t\t\tzoneinfoElement.NrWriteback = vp.PInt64()\n\t\t\tcase \"nr_unevictable\":\n\t\t\t\tzoneinfoElement.NrUnevictable = vp.PInt64()\n\t\t\tcase \"nr_shmem\":\n\t\t\t\tzoneinfoElement.NrShmem = vp.PInt64()\n\t\t\tcase \"nr_dirtied\":\n\t\t\t\tzoneinfoElement.NrDirtied = vp.PInt64()\n\t\t\tcase \"nr_written\":\n\t\t\t\tzoneinfoElement.NrWritten = vp.PInt64()\n\t\t\tcase \"numa_hit\":\n\t\t\t\tzoneinfoElement.NumaHit = vp.PInt64()\n\t\t\tcase \"numa_miss\":\n\t\t\t\tzoneinfoElement.NumaMiss = vp.PInt64()\n\t\t\tcase \"numa_foreign\":\n\t\t\t\tzoneinfoElement.NumaForeign = vp.PInt64()\n\t\t\tcase \"numa_interleave\":\n\t\t\t\tzoneinfoElement.NumaInterleave = vp.PInt64()\n\t\t\tcase \"numa_local\":\n\t\t\t\tzoneinfoElement.NumaLocal = vp.PInt64()\n\t\t\tcase \"numa_other\":\n\t\t\t\tzoneinfoElement.NumaOther = vp.PInt64()\n\t\t\tcase \"protection:\":\n\t\t\t\tprotectionParts := strings.Split(line, \":\")\n\t\t\t\tprotectionValues := strings.Replace(protectionParts[1], \"(\", \"\", 1)\n\t\t\t\tprotectionValues = strings.Replace(protectionValues, \")\", \"\", 1)\n\t\t\t\tprotectionValues = strings.TrimSpace(protectionValues)\n\t\t\t\tprotectionStringMap := strings.Split(protectionValues, \", \")\n\t\t\t\tval, err := util.ParsePInt64s(protectionStringMap)\n\t\t\t\tif err == nil {\n\t\t\t\t\tzoneinfoElement.Protection = val\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\tzoneinfo = append(zoneinfo, zoneinfoElement)\n\t}\n\treturn zoneinfo, nil\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/.gitignore",
    "content": "debug\ndebug.test\nmain\nmockgen_tmp.go\n*.qtr\n*.qlog\n*.sqlog\n*.txt\nrace.[0-9]*\n\nfuzzing/*/*.zip\nfuzzing/*/coverprofile\nfuzzing/*/crashers\nfuzzing/*/sonarprofile\nfuzzing/*/suppressions\nfuzzing/*/corpus/\n\ngomock_reflect_*/\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/.golangci.yml",
    "content": "version: \"2\"\nlinters:\n  default: none\n  enable:\n    - asciicheck\n    - copyloopvar\n    - depguard\n    - exhaustive\n    - govet\n    - ineffassign\n    - misspell\n    - prealloc\n    - staticcheck\n    - unconvert\n    - unparam\n    - unused\n  settings:\n    depguard:\n      rules:\n        random:\n          deny:\n            - pkg: \"math/rand$\"\n              desc: use math/rand/v2\n            - pkg: \"golang.org/x/exp/rand\"\n              desc: use math/rand/v2\n        quicvarint:\n          list-mode: strict\n          files:\n            - '**/github.com/quic-go/quic-go/quicvarint/*'\n            - '!$test'\n          allow:\n            - $gostd\n        rsa:\n          list-mode: original\n          deny:\n            - pkg: crypto/rsa\n              desc: \"use crypto/ed25519 instead\"\n    misspell:\n      ignore-rules:\n        - ect\n  exclusions:\n    generated: lax\n    presets:\n      - comments\n      - common-false-positives\n      - legacy\n      - std-error-handling\n    rules:\n      - linters:\n          - depguard\n        path: internal/qtls\n      - linters:\n          - exhaustive\n          - prealloc\n          - unparam\n        path: _test\\.go\n      - linters:\n          - staticcheck\n        path: _test\\.go\n        text: 'SA1029:' # inappropriate key in call to context.WithValue\n      # WebTransport still relies on the ConnectionTracingID and ConnectionTracingKey.\n      # See https://github.com/quic-go/quic-go/issues/4405 for more details.\n      - linters:\n          - staticcheck\n        paths:\n          - http3/\n          - integrationtests/self/http_test.go\n        text: 'SA1019:.+quic\\.ConnectionTracing(ID|Key)'\n    paths:\n      - internal/handshake/cipher_suite.go\n      - third_party$\n      - builtin$\n      - examples$\nformatters:\n  enable:\n    - gofmt\n    - gofumpt\n    - goimports\n  exclusions:\n    generated: lax\n    paths:\n      - internal/handshake/cipher_suite.go\n      - third_party$\n      - builtin$\n      - examples$\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/Changelog.md",
    "content": "# Changelog\n\n## v0.22.0 (2021-07-25)\n\n- Use `ReadBatch` to read multiple UDP packets from the socket with a single syscall\n- Add a config option (`Config.DisableVersionNegotiationPackets`) to disable sending of Version Negotiation packets\n- Drop support for QUIC draft versions 32 and 34\n- Remove the `RetireBugBackwardsCompatibilityMode`, which was intended to mitigate a bug when retiring connection IDs in quic-go in v0.17.2 and ealier\n\n## v0.21.2 (2021-07-15)\n\n- Update qtls (for Go 1.15, 1.16 and 1.17rc1) to include the fix for the crypto/tls panic (see https://groups.google.com/g/golang-dev/c/5LJ2V7rd-Ag/m/YGLHVBZ6AAAJ for details)\n\n## v0.21.0 (2021-06-01)\n\n- quic-go now supports RFC 9000!\n\n## v0.20.0 (2021-03-19)\n\n- Remove the `quic.Config.HandshakeTimeout`. Introduce a `quic.Config.HandshakeIdleTimeout`.\n\n## v0.17.1 (2020-06-20)\n\n- Supports QUIC WG draft-29.\n- Improve bundling of ACK frames (#2543).\n\n## v0.16.0 (2020-05-31)\n\n- Supports QUIC WG draft-28.\n\n## v0.15.0 (2020-03-01)\n\n- Supports QUIC WG draft-27.\n- Add support for 0-RTT.\n- Remove `Session.Close()`. Applications need to pass an application error code to the transport using `Session.CloseWithError()`.\n- Make the TLS Cipher Suites configurable (via `tls.Config.CipherSuites`).\n\n## v0.14.0 (2019-12-04)\n\n- Supports QUIC WG draft-24.\n\n## v0.13.0 (2019-11-05)\n\n- Supports QUIC WG draft-23.\n- Add an `EarlyListener` that allows sending of 0.5-RTT data.\n- Add a `TokenStore` to store address validation tokens.\n- Issue and use new connection IDs during a connection.\n\n## v0.12.0 (2019-08-05)\n\n- Implement HTTP/3.\n- Rename `quic.Cookie` to `quic.Token` and `quic.Config.AcceptCookie` to `quic.Config.AcceptToken`.\n- Distinguish between Retry tokens and tokens sent in NEW_TOKEN frames.\n- Enforce application protocol negotiation (via `tls.Config.NextProtos`).\n- Use a varint for error codes.\n- Add support for [quic-trace](https://github.com/google/quic-trace).\n- Add a context to `Listener.Accept`, `Session.Accept{Uni}Stream` and `Session.Open{Uni}StreamSync`.\n- Implement TLS key updates.\n\n## v0.11.0 (2019-04-05)\n\n- Drop support for gQUIC. For qQUIC support, please switch to the *gquic* branch.\n- Implement QUIC WG draft-19.\n- Use [qtls](https://github.com/marten-seemann/qtls) for TLS 1.3.\n- Return a `tls.ConnectionState` from `quic.Session.ConnectionState()`.\n- Remove the error return values from `quic.Stream.CancelRead()` and `quic.Stream.CancelWrite()`\n\n## v0.10.0 (2018-08-28)\n\n- Add support for QUIC 44, drop support for QUIC 42.\n\n## v0.9.0 (2018-08-15)\n\n- Add a `quic.Config` option for the length of the connection ID (for IETF QUIC).\n- Split Session.Close into one method for regular closing and one for closing with an error.\n\n## v0.8.0 (2018-06-26)\n\n- Add support for unidirectional streams (for IETF QUIC).\n- Add a `quic.Config` option for the maximum number of incoming streams.\n- Add support for QUIC 42 and 43.\n- Add dial functions that use a context.\n- Multiplex clients on a net.PacketConn, when using Dial(conn).\n\n## v0.7.0 (2018-02-03)\n\n- The lower boundary for packets included in ACKs is now derived, and the value sent in STOP_WAITING frames is ignored.\n- Remove `DialNonFWSecure` and `DialAddrNonFWSecure`.\n- Expose the `ConnectionState` in the `Session` (experimental API).\n- Implement packet pacing.\n\n## v0.6.0 (2017-12-12)\n\n- Add support for QUIC 39, drop support for QUIC 35 - 37\n- Added `quic.Config` options for maximal flow control windows\n- Add a `quic.Config` option for QUIC versions\n- Add a `quic.Config` option to request omission of the connection ID from a server\n- Add a `quic.Config` option to configure the source address validation\n- Add a `quic.Config` option to configure the handshake timeout\n- Add a `quic.Config` option to configure the idle timeout\n- Add a `quic.Config` option to configure keep-alive\n- Rename the STK to Cookie\n- Implement `net.Conn`-style deadlines for streams\n- Remove the `tls.Config` from the `quic.Config`. The `tls.Config` must now be passed to the `Dial` and `Listen` functions as a separate parameter. See the [Godoc](https://godoc.org/github.com/quic-go/quic-go) for details.\n- Changed the log level environment variable to only accept strings (\"DEBUG\", \"INFO\", \"ERROR\"), see [the wiki](https://github.com/quic-go/quic-go/wiki/Logging) for more details.\n- Rename the `h2quic.QuicRoundTripper` to `h2quic.RoundTripper`\n- Changed `h2quic.Server.Serve()` to accept a `net.PacketConn`\n- Drop support for Go 1.7 and 1.8.\n- Various bugfixes\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2016 the quic-go authors & Google, Inc.\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": "vendor/github.com/quic-go/quic-go/README.md",
    "content": "# A QUIC implementation in pure Go\n\n<img src=\"docs/quic.png\" width=303 height=124>\n\n[![Documentation](https://img.shields.io/badge/docs-quic--go.net-red?style=flat)](https://quic-go.net/docs/)\n[![PkgGoDev](https://pkg.go.dev/badge/github.com/quic-go/quic-go)](https://pkg.go.dev/github.com/quic-go/quic-go)\n[![Code Coverage](https://img.shields.io/codecov/c/github/quic-go/quic-go/master.svg?style=flat-square)](https://codecov.io/gh/quic-go/quic-go/)\n[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/quic-go.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:quic-go)\n\nquic-go is an implementation of the QUIC protocol ([RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000), [RFC 9001](https://datatracker.ietf.org/doc/html/rfc9001), [RFC 9002](https://datatracker.ietf.org/doc/html/rfc9002)) in Go. It has support for HTTP/3 ([RFC 9114](https://datatracker.ietf.org/doc/html/rfc9114)), including QPACK ([RFC 9204](https://datatracker.ietf.org/doc/html/rfc9204)) and HTTP Datagrams ([RFC 9297](https://datatracker.ietf.org/doc/html/rfc9297)).\n\nIn addition to these base RFCs, it also implements the following RFCs:\n\n* Unreliable Datagram Extension ([RFC 9221](https://datatracker.ietf.org/doc/html/rfc9221))\n* Datagram Packetization Layer Path MTU Discovery (DPLPMTUD, [RFC 8899](https://datatracker.ietf.org/doc/html/rfc8899))\n* QUIC Version 2 ([RFC 9369](https://datatracker.ietf.org/doc/html/rfc9369))\n* QUIC Event Logging using qlog ([draft-ietf-quic-qlog-main-schema](https://datatracker.ietf.org/doc/draft-ietf-quic-qlog-main-schema/) and [draft-ietf-quic-qlog-quic-events](https://datatracker.ietf.org/doc/draft-ietf-quic-qlog-quic-events/))\n\nSupport for WebTransport over HTTP/3 ([draft-ietf-webtrans-http3](https://datatracker.ietf.org/doc/draft-ietf-webtrans-http3/)) is implemented in [webtransport-go](https://github.com/quic-go/webtransport-go).\n\nDetailed documentation can be found on [quic-go.net](https://quic-go.net/docs/).\n\n## Projects using quic-go\n\n| Project                                                   | Description                                                                                                                                                       | Stars                                                                                               |\n| ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |\n| [AdGuardHome](https://github.com/AdguardTeam/AdGuardHome) | Free and open source, powerful network-wide ads & trackers blocking DNS server.                                                                                   | ![GitHub Repo stars](https://img.shields.io/github/stars/AdguardTeam/AdGuardHome?style=flat-square) |\n| [algernon](https://github.com/xyproto/algernon)           | Small self-contained pure-Go web server with Lua, Markdown, HTTP/2, QUIC, Redis and PostgreSQL support                                                            | ![GitHub Repo stars](https://img.shields.io/github/stars/xyproto/algernon?style=flat-square)        |\n| [caddy](https://github.com/caddyserver/caddy/)            | Fast, multi-platform web server with automatic HTTPS                                                                                                              | ![GitHub Repo stars](https://img.shields.io/github/stars/caddyserver/caddy?style=flat-square)       |\n| [cloudflared](https://github.com/cloudflare/cloudflared)  | A tunneling daemon that proxies traffic from the Cloudflare network to your origins                                                                               | ![GitHub Repo stars](https://img.shields.io/github/stars/cloudflare/cloudflared?style=flat-square)  |\n| [frp](https://github.com/fatedier/frp)                    | A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet                                                                   | ![GitHub Repo stars](https://img.shields.io/github/stars/fatedier/frp?style=flat-square)            |\n| [go-libp2p](https://github.com/libp2p/go-libp2p)          | libp2p implementation in Go, powering [Kubo](https://github.com/ipfs/kubo) (IPFS) and [Lotus](https://github.com/filecoin-project/lotus) (Filecoin), among others | ![GitHub Repo stars](https://img.shields.io/github/stars/libp2p/go-libp2p?style=flat-square)     |\n| [gost](https://github.com/go-gost/gost)                   | A simple security tunnel written in Go                                                                                                                        | ![GitHub Repo stars](https://img.shields.io/github/stars/go-gost/gost?style=flat-square)            |\n| [Hysteria](https://github.com/apernet/hysteria)           | A powerful, lightning fast and censorship resistant proxy                                                                                                         | ![GitHub Repo stars](https://img.shields.io/github/stars/apernet/hysteria?style=flat-square)        |\n| [Mercure](https://github.com/dunglas/mercure)             | An open, easy, fast, reliable and battery-efficient solution for real-time communications                                                                         | ![GitHub Repo stars](https://img.shields.io/github/stars/dunglas/mercure?style=flat-square)         |\n| [OONI Probe](https://github.com/ooni/probe-cli)           | Next generation OONI Probe. Library and CLI tool.                                                                                                                 | ![GitHub Repo stars](https://img.shields.io/github/stars/ooni/probe-cli?style=flat-square)          |\n| [reverst](https://github.com/flipt-io/reverst)            | Reverse Tunnels in Go over HTTP/3 and QUIC                                                                                                                        | ![GitHub Repo stars](https://img.shields.io/github/stars/flipt-io/reverst?style=flat-square) |\n| [RoadRunner](https://github.com/roadrunner-server/roadrunner) | High-performance PHP application server, process manager written in Go and powered with plugins | ![GitHub Repo stars](https://img.shields.io/github/stars/roadrunner-server/roadrunner?style=flat-square) |\n| [syncthing](https://github.com/syncthing/syncthing/)      | Open Source Continuous File Synchronization                                                                                                                       | ![GitHub Repo stars](https://img.shields.io/github/stars/syncthing/syncthing?style=flat-square)     |\n| [traefik](https://github.com/traefik/traefik)             | The Cloud Native Application Proxy                                                                                                                                | ![GitHub Repo stars](https://img.shields.io/github/stars/traefik/traefik?style=flat-square)         |\n| [v2ray-core](https://github.com/v2fly/v2ray-core)         | A platform for building proxies to bypass network restrictions                                                                                                    | ![GitHub Repo stars](https://img.shields.io/github/stars/v2fly/v2ray-core?style=flat-square)        |\n| [YoMo](https://github.com/yomorun/yomo)                   | Streaming Serverless Framework for Geo-distributed System                                                                                                         | ![GitHub Repo stars](https://img.shields.io/github/stars/yomorun/yomo?style=flat-square)            |\n\nIf you'd like to see your project added to this list, please send us a PR.\n\n## Release Policy\n\nquic-go always aims to support the latest two Go releases.\n\n## Contributing\n\nWe are always happy to welcome new contributors! We have a number of self-contained issues that are suitable for first-time contributors, they are tagged with [help wanted](https://github.com/quic-go/quic-go/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22). If you have any questions, please feel free to reach out by opening an issue or leaving a comment.\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/SECURITY.md",
    "content": "# Security Policy\n\nquic-go still in development. This means that there may be problems in our protocols,\nor there may be mistakes in our implementations.\nWe take security vulnerabilities very seriously. If you discover a security issue,\nplease bring it to our attention right away!\n\n## Reporting a Vulnerability\n\nIf you find a vulnerability that may affect live deployments -- for example, by exposing\na remote execution exploit -- please [**report privately**](https://github.com/quic-go/quic-go/security/advisories/new).\nPlease **DO NOT file a public issue**.\n\nIf the issue is an implementation weakness that cannot be immediately exploited or\nsomething not yet deployed, just discuss it openly.\n\n## Reporting a non security bug\n\nFor non-security bugs, please simply file a GitHub [issue](https://github.com/quic-go/quic-go/issues/new).\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/buffer_pool.go",
    "content": "package quic\n\nimport (\n\t\"sync\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\ntype packetBuffer struct {\n\tData []byte\n\n\t// refCount counts how many packets Data is used in.\n\t// It doesn't support concurrent use.\n\t// It is > 1 when used for coalesced packet.\n\trefCount int\n}\n\n// Split increases the refCount.\n// It must be called when a packet buffer is used for more than one packet,\n// e.g. when splitting coalesced packets.\nfunc (b *packetBuffer) Split() {\n\tb.refCount++\n}\n\n// Decrement decrements the reference counter.\n// It doesn't put the buffer back into the pool.\nfunc (b *packetBuffer) Decrement() {\n\tb.refCount--\n\tif b.refCount < 0 {\n\t\tpanic(\"negative packetBuffer refCount\")\n\t}\n}\n\n// MaybeRelease puts the packet buffer back into the pool,\n// if the reference counter already reached 0.\nfunc (b *packetBuffer) MaybeRelease() {\n\t// only put the packetBuffer back if it's not used any more\n\tif b.refCount == 0 {\n\t\tb.putBack()\n\t}\n}\n\n// Release puts back the packet buffer into the pool.\n// It should be called when processing is definitely finished.\nfunc (b *packetBuffer) Release() {\n\tb.Decrement()\n\tif b.refCount != 0 {\n\t\tpanic(\"packetBuffer refCount not zero\")\n\t}\n\tb.putBack()\n}\n\n// Len returns the length of Data\nfunc (b *packetBuffer) Len() protocol.ByteCount { return protocol.ByteCount(len(b.Data)) }\nfunc (b *packetBuffer) Cap() protocol.ByteCount { return protocol.ByteCount(cap(b.Data)) }\n\nfunc (b *packetBuffer) putBack() {\n\tif cap(b.Data) == protocol.MaxPacketBufferSize {\n\t\tbufferPool.Put(b)\n\t\treturn\n\t}\n\tif cap(b.Data) == protocol.MaxLargePacketBufferSize {\n\t\tlargeBufferPool.Put(b)\n\t\treturn\n\t}\n\tpanic(\"putPacketBuffer called with packet of wrong size!\")\n}\n\nvar bufferPool, largeBufferPool sync.Pool\n\nfunc getPacketBuffer() *packetBuffer {\n\tbuf := bufferPool.Get().(*packetBuffer)\n\tbuf.refCount = 1\n\tbuf.Data = buf.Data[:0]\n\treturn buf\n}\n\nfunc getLargePacketBuffer() *packetBuffer {\n\tbuf := largeBufferPool.Get().(*packetBuffer)\n\tbuf.refCount = 1\n\tbuf.Data = buf.Data[:0]\n\treturn buf\n}\n\nfunc init() {\n\tbufferPool.New = func() any {\n\t\treturn &packetBuffer{Data: make([]byte, 0, protocol.MaxPacketBufferSize)}\n\t}\n\tlargeBufferPool.New = func() any {\n\t\treturn &packetBuffer{Data: make([]byte, 0, protocol.MaxLargePacketBufferSize)}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/client.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"net\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\n// make it possible to mock connection ID for initial generation in the tests\nvar generateConnectionIDForInitial = protocol.GenerateConnectionIDForInitial\n\n// DialAddr establishes a new QUIC connection to a server.\n// It resolves the address, and then creates a new UDP connection to dial the QUIC server.\n// When the QUIC connection is closed, this UDP connection is closed.\n// See [Dial] for more details.\nfunc DialAddr(ctx context.Context, addr string, tlsConf *tls.Config, conf *Config) (Connection, error) {\n\tudpConn, err := net.ListenUDP(\"udp\", &net.UDPAddr{IP: net.IPv4zero, Port: 0})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tudpAddr, err := net.ResolveUDPAddr(\"udp\", addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttr, err := setupTransport(udpConn, tlsConf, true)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn tr.dial(ctx, udpAddr, addr, tlsConf, conf, false)\n}\n\n// DialAddrEarly establishes a new 0-RTT QUIC connection to a server.\n// See [DialAddr] for more details.\nfunc DialAddrEarly(ctx context.Context, addr string, tlsConf *tls.Config, conf *Config) (EarlyConnection, error) {\n\tudpConn, err := net.ListenUDP(\"udp\", &net.UDPAddr{IP: net.IPv4zero, Port: 0})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tudpAddr, err := net.ResolveUDPAddr(\"udp\", addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttr, err := setupTransport(udpConn, tlsConf, true)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tconn, err := tr.dial(ctx, udpAddr, addr, tlsConf, conf, true)\n\tif err != nil {\n\t\ttr.Close()\n\t\treturn nil, err\n\t}\n\treturn conn, nil\n}\n\n// DialEarly establishes a new 0-RTT QUIC connection to a server using a net.PacketConn.\n// See [Dial] for more details.\nfunc DialEarly(ctx context.Context, c net.PacketConn, addr net.Addr, tlsConf *tls.Config, conf *Config) (EarlyConnection, error) {\n\tdl, err := setupTransport(c, tlsConf, false)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tconn, err := dl.DialEarly(ctx, addr, tlsConf, conf)\n\tif err != nil {\n\t\tdl.Close()\n\t\treturn nil, err\n\t}\n\treturn conn, nil\n}\n\n// Dial establishes a new QUIC connection to a server using a net.PacketConn.\n// If the PacketConn satisfies the [OOBCapablePacketConn] interface (as a [net.UDPConn] does),\n// ECN and packet info support will be enabled. In this case, ReadMsgUDP and WriteMsgUDP\n// will be used instead of ReadFrom and WriteTo to read/write packets.\n// The tls.Config must define an application protocol (using NextProtos).\n//\n// This is a convenience function. More advanced use cases should instantiate a [Transport],\n// which offers configuration options for a more fine-grained control of the connection establishment,\n// including reusing the underlying UDP socket for multiple QUIC connections.\nfunc Dial(ctx context.Context, c net.PacketConn, addr net.Addr, tlsConf *tls.Config, conf *Config) (Connection, error) {\n\tdl, err := setupTransport(c, tlsConf, false)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tconn, err := dl.Dial(ctx, addr, tlsConf, conf)\n\tif err != nil {\n\t\tdl.Close()\n\t\treturn nil, err\n\t}\n\treturn conn, nil\n}\n\nfunc setupTransport(c net.PacketConn, tlsConf *tls.Config, createdPacketConn bool) (*Transport, error) {\n\tif tlsConf == nil {\n\t\treturn nil, errors.New(\"quic: tls.Config not set\")\n\t}\n\treturn &Transport{\n\t\tConn:        c,\n\t\tcreatedConn: createdPacketConn,\n\t\tisSingleUse: true,\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/closed_conn.go",
    "content": "package quic\n\nimport (\n\t\"math/bits\"\n\t\"net\"\n\t\"sync/atomic\"\n\n\t\"github.com/quic-go/quic-go/internal/utils\"\n)\n\n// A closedLocalConn is a connection that we closed locally.\n// When receiving packets for such a connection, we need to retransmit the packet containing the CONNECTION_CLOSE frame,\n// with an exponential backoff.\ntype closedLocalConn struct {\n\tcounter atomic.Uint32\n\tlogger  utils.Logger\n\n\tsendPacket func(net.Addr, packetInfo)\n}\n\nvar _ packetHandler = &closedLocalConn{}\n\n// newClosedLocalConn creates a new closedLocalConn and runs it.\nfunc newClosedLocalConn(sendPacket func(net.Addr, packetInfo), logger utils.Logger) packetHandler {\n\treturn &closedLocalConn{\n\t\tsendPacket: sendPacket,\n\t\tlogger:     logger,\n\t}\n}\n\nfunc (c *closedLocalConn) handlePacket(p receivedPacket) {\n\tn := c.counter.Add(1)\n\t// exponential backoff\n\t// only send a CONNECTION_CLOSE for the 1st, 2nd, 4th, 8th, 16th, ... packet arriving\n\tif bits.OnesCount32(n) != 1 {\n\t\treturn\n\t}\n\tc.logger.Debugf(\"Received %d packets after sending CONNECTION_CLOSE. Retransmitting.\", n)\n\tc.sendPacket(p.remoteAddr, p.info)\n}\n\nfunc (c *closedLocalConn) destroy(error)                              {}\nfunc (c *closedLocalConn) closeWithTransportError(TransportErrorCode) {}\n\n// A closedRemoteConn is a connection that was closed remotely.\n// For such a connection, we might receive reordered packets that were sent before the CONNECTION_CLOSE.\n// We can just ignore those packets.\ntype closedRemoteConn struct{}\n\nvar _ packetHandler = &closedRemoteConn{}\n\nfunc newClosedRemoteConn() packetHandler {\n\treturn &closedRemoteConn{}\n}\n\nfunc (c *closedRemoteConn) handlePacket(receivedPacket)                {}\nfunc (c *closedRemoteConn) destroy(error)                              {}\nfunc (c *closedRemoteConn) closeWithTransportError(TransportErrorCode) {}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/codecov.yml",
    "content": "coverage:\n  round: nearest\n  ignore:\n    - http3/gzip_reader.go\n    - interop/\n    - internal/handshake/cipher_suite.go\n    - internal/utils/linkedlist/linkedlist.go\n    - internal/testdata\n    - logging/connection_tracer_multiplexer.go\n    - logging/tracer_multiplexer.go\n    - testutils/\n    - fuzzing/\n    - metrics/\n  status:\n    project:\n      default:\n        threshold: 0.5\n    patch: false\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/config.go",
    "content": "package quic\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// Clone clones a Config.\nfunc (c *Config) Clone() *Config {\n\tcopy := *c\n\treturn &copy\n}\n\nfunc (c *Config) handshakeTimeout() time.Duration {\n\treturn 2 * c.HandshakeIdleTimeout\n}\n\nfunc (c *Config) maxRetryTokenAge() time.Duration {\n\treturn c.handshakeTimeout()\n}\n\nfunc validateConfig(config *Config) error {\n\tif config == nil {\n\t\treturn nil\n\t}\n\tconst maxStreams = 1 << 60\n\tif config.MaxIncomingStreams > maxStreams {\n\t\tconfig.MaxIncomingStreams = maxStreams\n\t}\n\tif config.MaxIncomingUniStreams > maxStreams {\n\t\tconfig.MaxIncomingUniStreams = maxStreams\n\t}\n\tif config.MaxStreamReceiveWindow > quicvarint.Max {\n\t\tconfig.MaxStreamReceiveWindow = quicvarint.Max\n\t}\n\tif config.MaxConnectionReceiveWindow > quicvarint.Max {\n\t\tconfig.MaxConnectionReceiveWindow = quicvarint.Max\n\t}\n\tif config.InitialPacketSize > 0 && config.InitialPacketSize < protocol.MinInitialPacketSize {\n\t\tconfig.InitialPacketSize = protocol.MinInitialPacketSize\n\t}\n\tif config.InitialPacketSize > protocol.MaxPacketBufferSize {\n\t\tconfig.InitialPacketSize = protocol.MaxPacketBufferSize\n\t}\n\t// check that all QUIC versions are actually supported\n\tfor _, v := range config.Versions {\n\t\tif !protocol.IsValidVersion(v) {\n\t\t\treturn fmt.Errorf(\"invalid QUIC version: %s\", v)\n\t\t}\n\t}\n\treturn nil\n}\n\n// populateConfig populates fields in the quic.Config with their default values, if none are set\n// it may be called with nil\nfunc populateConfig(config *Config) *Config {\n\tif config == nil {\n\t\tconfig = &Config{}\n\t}\n\tversions := config.Versions\n\tif len(versions) == 0 {\n\t\tversions = protocol.SupportedVersions\n\t}\n\thandshakeIdleTimeout := protocol.DefaultHandshakeIdleTimeout\n\tif config.HandshakeIdleTimeout != 0 {\n\t\thandshakeIdleTimeout = config.HandshakeIdleTimeout\n\t}\n\tidleTimeout := protocol.DefaultIdleTimeout\n\tif config.MaxIdleTimeout != 0 {\n\t\tidleTimeout = config.MaxIdleTimeout\n\t}\n\tinitialStreamReceiveWindow := config.InitialStreamReceiveWindow\n\tif initialStreamReceiveWindow == 0 {\n\t\tinitialStreamReceiveWindow = protocol.DefaultInitialMaxStreamData\n\t}\n\tmaxStreamReceiveWindow := config.MaxStreamReceiveWindow\n\tif maxStreamReceiveWindow == 0 {\n\t\tmaxStreamReceiveWindow = protocol.DefaultMaxReceiveStreamFlowControlWindow\n\t}\n\tinitialConnectionReceiveWindow := config.InitialConnectionReceiveWindow\n\tif initialConnectionReceiveWindow == 0 {\n\t\tinitialConnectionReceiveWindow = protocol.DefaultInitialMaxData\n\t}\n\tmaxConnectionReceiveWindow := config.MaxConnectionReceiveWindow\n\tif maxConnectionReceiveWindow == 0 {\n\t\tmaxConnectionReceiveWindow = protocol.DefaultMaxReceiveConnectionFlowControlWindow\n\t}\n\tmaxIncomingStreams := config.MaxIncomingStreams\n\tif maxIncomingStreams == 0 {\n\t\tmaxIncomingStreams = protocol.DefaultMaxIncomingStreams\n\t} else if maxIncomingStreams < 0 {\n\t\tmaxIncomingStreams = 0\n\t}\n\tmaxIncomingUniStreams := config.MaxIncomingUniStreams\n\tif maxIncomingUniStreams == 0 {\n\t\tmaxIncomingUniStreams = protocol.DefaultMaxIncomingUniStreams\n\t} else if maxIncomingUniStreams < 0 {\n\t\tmaxIncomingUniStreams = 0\n\t}\n\tinitialPacketSize := config.InitialPacketSize\n\tif initialPacketSize == 0 {\n\t\tinitialPacketSize = protocol.InitialPacketSize\n\t}\n\n\treturn &Config{\n\t\tGetConfigForClient:             config.GetConfigForClient,\n\t\tVersions:                       versions,\n\t\tHandshakeIdleTimeout:           handshakeIdleTimeout,\n\t\tMaxIdleTimeout:                 idleTimeout,\n\t\tKeepAlivePeriod:                config.KeepAlivePeriod,\n\t\tInitialStreamReceiveWindow:     initialStreamReceiveWindow,\n\t\tMaxStreamReceiveWindow:         maxStreamReceiveWindow,\n\t\tInitialConnectionReceiveWindow: initialConnectionReceiveWindow,\n\t\tMaxConnectionReceiveWindow:     maxConnectionReceiveWindow,\n\t\tAllowConnectionWindowIncrease:  config.AllowConnectionWindowIncrease,\n\t\tMaxIncomingStreams:             maxIncomingStreams,\n\t\tMaxIncomingUniStreams:          maxIncomingUniStreams,\n\t\tTokenStore:                     config.TokenStore,\n\t\tEnableDatagrams:                config.EnableDatagrams,\n\t\tInitialPacketSize:              initialPacketSize,\n\t\tDisablePathMTUDiscovery:        config.DisablePathMTUDiscovery,\n\t\tAllow0RTT:                      config.Allow0RTT,\n\t\tTracer:                         config.Tracer,\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/conn_id_generator.go",
    "content": "package quic\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\ntype connRunnerCallbacks struct {\n\tAddConnectionID    func(protocol.ConnectionID)\n\tRemoveConnectionID func(protocol.ConnectionID)\n\tRetireConnectionID func(protocol.ConnectionID)\n\tReplaceWithClosed  func([]protocol.ConnectionID, []byte)\n}\n\ntype connRunners map[transportID]connRunnerCallbacks\n\nfunc (cr connRunners) AddConnectionID(id protocol.ConnectionID) {\n\tfor _, c := range cr {\n\t\tc.AddConnectionID(id)\n\t}\n}\n\nfunc (cr connRunners) RemoveConnectionID(id protocol.ConnectionID) {\n\tfor _, c := range cr {\n\t\tc.RemoveConnectionID(id)\n\t}\n}\n\nfunc (cr connRunners) RetireConnectionID(id protocol.ConnectionID) {\n\tfor _, c := range cr {\n\t\tc.RetireConnectionID(id)\n\t}\n}\n\nfunc (cr connRunners) ReplaceWithClosed(ids []protocol.ConnectionID, b []byte) {\n\tfor _, c := range cr {\n\t\tc.ReplaceWithClosed(ids, b)\n\t}\n}\n\ntype connIDGenerator struct {\n\tgenerator   ConnectionIDGenerator\n\thighestSeq  uint64\n\tconnRunners connRunners\n\n\tactiveSrcConnIDs        map[uint64]protocol.ConnectionID\n\tinitialClientDestConnID *protocol.ConnectionID // nil for the client\n\n\tstatelessResetter *statelessResetter\n\n\tqueueControlFrame func(wire.Frame)\n}\n\nfunc newConnIDGenerator(\n\ttID transportID,\n\tinitialConnectionID protocol.ConnectionID,\n\tinitialClientDestConnID *protocol.ConnectionID, // nil for the client\n\tstatelessResetter *statelessResetter,\n\tconnRunner connRunnerCallbacks,\n\tqueueControlFrame func(wire.Frame),\n\tgenerator ConnectionIDGenerator,\n) *connIDGenerator {\n\tm := &connIDGenerator{\n\t\tgenerator:         generator,\n\t\tactiveSrcConnIDs:  make(map[uint64]protocol.ConnectionID),\n\t\tstatelessResetter: statelessResetter,\n\t\tconnRunners:       map[transportID]connRunnerCallbacks{tID: connRunner},\n\t\tqueueControlFrame: queueControlFrame,\n\t}\n\tm.activeSrcConnIDs[0] = initialConnectionID\n\tm.initialClientDestConnID = initialClientDestConnID\n\treturn m\n}\n\nfunc (m *connIDGenerator) SetMaxActiveConnIDs(limit uint64) error {\n\tif m.generator.ConnectionIDLen() == 0 {\n\t\treturn nil\n\t}\n\t// The active_connection_id_limit transport parameter is the number of\n\t// connection IDs the peer will store. This limit includes the connection ID\n\t// used during the handshake, and the one sent in the preferred_address\n\t// transport parameter.\n\t// We currently don't send the preferred_address transport parameter,\n\t// so we can issue (limit - 1) connection IDs.\n\tfor i := uint64(len(m.activeSrcConnIDs)); i < min(limit, protocol.MaxIssuedConnectionIDs); i++ {\n\t\tif err := m.issueNewConnID(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (m *connIDGenerator) Retire(seq uint64, sentWithDestConnID protocol.ConnectionID) error {\n\tif seq > m.highestSeq {\n\t\treturn &qerr.TransportError{\n\t\t\tErrorCode:    qerr.ProtocolViolation,\n\t\t\tErrorMessage: fmt.Sprintf(\"retired connection ID %d (highest issued: %d)\", seq, m.highestSeq),\n\t\t}\n\t}\n\tconnID, ok := m.activeSrcConnIDs[seq]\n\t// We might already have deleted this connection ID, if this is a duplicate frame.\n\tif !ok {\n\t\treturn nil\n\t}\n\tif connID == sentWithDestConnID {\n\t\treturn &qerr.TransportError{\n\t\t\tErrorCode:    qerr.ProtocolViolation,\n\t\t\tErrorMessage: fmt.Sprintf(\"retired connection ID %d (%s), which was used as the Destination Connection ID on this packet\", seq, connID),\n\t\t}\n\t}\n\tm.connRunners.RetireConnectionID(connID)\n\tdelete(m.activeSrcConnIDs, seq)\n\t// Don't issue a replacement for the initial connection ID.\n\tif seq == 0 {\n\t\treturn nil\n\t}\n\treturn m.issueNewConnID()\n}\n\nfunc (m *connIDGenerator) issueNewConnID() error {\n\tconnID, err := m.generator.GenerateConnectionID()\n\tif err != nil {\n\t\treturn err\n\t}\n\tm.activeSrcConnIDs[m.highestSeq+1] = connID\n\tm.connRunners.AddConnectionID(connID)\n\tm.queueControlFrame(&wire.NewConnectionIDFrame{\n\t\tSequenceNumber:      m.highestSeq + 1,\n\t\tConnectionID:        connID,\n\t\tStatelessResetToken: m.statelessResetter.GetStatelessResetToken(connID),\n\t})\n\tm.highestSeq++\n\treturn nil\n}\n\nfunc (m *connIDGenerator) SetHandshakeComplete() {\n\tif m.initialClientDestConnID != nil {\n\t\tm.connRunners.RetireConnectionID(*m.initialClientDestConnID)\n\t\tm.initialClientDestConnID = nil\n\t}\n}\n\nfunc (m *connIDGenerator) RemoveAll() {\n\tif m.initialClientDestConnID != nil {\n\t\tm.connRunners.RemoveConnectionID(*m.initialClientDestConnID)\n\t}\n\tfor _, connID := range m.activeSrcConnIDs {\n\t\tm.connRunners.RemoveConnectionID(connID)\n\t}\n}\n\nfunc (m *connIDGenerator) ReplaceWithClosed(connClose []byte) {\n\tconnIDs := make([]protocol.ConnectionID, 0, len(m.activeSrcConnIDs)+1)\n\tif m.initialClientDestConnID != nil {\n\t\tconnIDs = append(connIDs, *m.initialClientDestConnID)\n\t}\n\tfor _, connID := range m.activeSrcConnIDs {\n\t\tconnIDs = append(connIDs, connID)\n\t}\n\tm.connRunners.ReplaceWithClosed(connIDs, connClose)\n}\n\nfunc (m *connIDGenerator) AddConnRunner(id transportID, r connRunnerCallbacks) {\n\t// The transport might have already been added earlier.\n\t// This happens if the application migrates back to and old path.\n\tif _, ok := m.connRunners[id]; ok {\n\t\treturn\n\t}\n\tm.connRunners[id] = r\n\tif m.initialClientDestConnID != nil {\n\t\tr.AddConnectionID(*m.initialClientDestConnID)\n\t}\n\tfor _, connID := range m.activeSrcConnIDs {\n\t\tr.AddConnectionID(connID)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/conn_id_manager.go",
    "content": "package quic\n\nimport (\n\t\"fmt\"\n\t\"slices\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\ntype newConnID struct {\n\tSequenceNumber      uint64\n\tConnectionID        protocol.ConnectionID\n\tStatelessResetToken protocol.StatelessResetToken\n}\n\ntype connIDManager struct {\n\tqueue []newConnID\n\n\thighestProbingID uint64\n\tpathProbing      map[pathID]newConnID // initialized lazily\n\n\thandshakeComplete         bool\n\tactiveSequenceNumber      uint64\n\thighestRetired            uint64\n\tactiveConnectionID        protocol.ConnectionID\n\tactiveStatelessResetToken *protocol.StatelessResetToken\n\n\t// We change the connection ID after sending on average\n\t// protocol.PacketsPerConnectionID packets. The actual value is randomized\n\t// hide the packet loss rate from on-path observers.\n\trand                   utils.Rand\n\tpacketsSinceLastChange uint32\n\tpacketsPerConnectionID uint32\n\n\taddStatelessResetToken    func(protocol.StatelessResetToken)\n\tremoveStatelessResetToken func(protocol.StatelessResetToken)\n\tqueueControlFrame         func(wire.Frame)\n\n\tclosed bool\n}\n\nfunc newConnIDManager(\n\tinitialDestConnID protocol.ConnectionID,\n\taddStatelessResetToken func(protocol.StatelessResetToken),\n\tremoveStatelessResetToken func(protocol.StatelessResetToken),\n\tqueueControlFrame func(wire.Frame),\n) *connIDManager {\n\treturn &connIDManager{\n\t\tactiveConnectionID:        initialDestConnID,\n\t\taddStatelessResetToken:    addStatelessResetToken,\n\t\tremoveStatelessResetToken: removeStatelessResetToken,\n\t\tqueueControlFrame:         queueControlFrame,\n\t\tqueue:                     make([]newConnID, 0, protocol.MaxActiveConnectionIDs),\n\t}\n}\n\nfunc (h *connIDManager) AddFromPreferredAddress(connID protocol.ConnectionID, resetToken protocol.StatelessResetToken) error {\n\treturn h.addConnectionID(1, connID, resetToken)\n}\n\nfunc (h *connIDManager) Add(f *wire.NewConnectionIDFrame) error {\n\tif err := h.add(f); err != nil {\n\t\treturn err\n\t}\n\tif len(h.queue) >= protocol.MaxActiveConnectionIDs {\n\t\treturn &qerr.TransportError{ErrorCode: qerr.ConnectionIDLimitError}\n\t}\n\treturn nil\n}\n\nfunc (h *connIDManager) add(f *wire.NewConnectionIDFrame) error {\n\tif h.activeConnectionID.Len() == 0 {\n\t\treturn &qerr.TransportError{\n\t\t\tErrorCode:    qerr.ProtocolViolation,\n\t\t\tErrorMessage: \"received NEW_CONNECTION_ID frame but zero-length connection IDs are in use\",\n\t\t}\n\t}\n\t// If the NEW_CONNECTION_ID frame is reordered, such that its sequence number is smaller than the currently active\n\t// connection ID or if it was already retired, send the RETIRE_CONNECTION_ID frame immediately.\n\tif f.SequenceNumber < max(h.activeSequenceNumber, h.highestProbingID) || f.SequenceNumber < h.highestRetired {\n\t\th.queueControlFrame(&wire.RetireConnectionIDFrame{\n\t\t\tSequenceNumber: f.SequenceNumber,\n\t\t})\n\t\treturn nil\n\t}\n\n\tif f.RetirePriorTo != 0 && h.pathProbing != nil {\n\t\tfor id, entry := range h.pathProbing {\n\t\t\tif entry.SequenceNumber < f.RetirePriorTo {\n\t\t\t\th.queueControlFrame(&wire.RetireConnectionIDFrame{\n\t\t\t\t\tSequenceNumber: entry.SequenceNumber,\n\t\t\t\t})\n\t\t\t\th.removeStatelessResetToken(entry.StatelessResetToken)\n\t\t\t\tdelete(h.pathProbing, id)\n\t\t\t}\n\t\t}\n\t}\n\t// Retire elements in the queue.\n\t// Doesn't retire the active connection ID.\n\tif f.RetirePriorTo > h.highestRetired {\n\t\tvar newQueue []newConnID\n\t\tfor _, entry := range h.queue {\n\t\t\tif entry.SequenceNumber >= f.RetirePriorTo {\n\t\t\t\tnewQueue = append(newQueue, entry)\n\t\t\t} else {\n\t\t\t\th.queueControlFrame(&wire.RetireConnectionIDFrame{SequenceNumber: entry.SequenceNumber})\n\t\t\t}\n\t\t}\n\t\th.queue = newQueue\n\t\th.highestRetired = f.RetirePriorTo\n\t}\n\n\tif f.SequenceNumber == h.activeSequenceNumber {\n\t\treturn nil\n\t}\n\n\tif err := h.addConnectionID(f.SequenceNumber, f.ConnectionID, f.StatelessResetToken); err != nil {\n\t\treturn err\n\t}\n\n\t// Retire the active connection ID, if necessary.\n\tif h.activeSequenceNumber < f.RetirePriorTo {\n\t\t// The queue is guaranteed to have at least one element at this point.\n\t\th.updateConnectionID()\n\t}\n\treturn nil\n}\n\nfunc (h *connIDManager) addConnectionID(seq uint64, connID protocol.ConnectionID, resetToken protocol.StatelessResetToken) error {\n\t// fast path: add to the end of the queue\n\tif len(h.queue) == 0 || h.queue[len(h.queue)-1].SequenceNumber < seq {\n\t\th.queue = append(h.queue, newConnID{\n\t\t\tSequenceNumber:      seq,\n\t\t\tConnectionID:        connID,\n\t\t\tStatelessResetToken: resetToken,\n\t\t})\n\t\treturn nil\n\t}\n\n\t// slow path: insert in the middle\n\tfor i, entry := range h.queue {\n\t\tif entry.SequenceNumber == seq {\n\t\t\tif entry.ConnectionID != connID {\n\t\t\t\treturn fmt.Errorf(\"received conflicting connection IDs for sequence number %d\", seq)\n\t\t\t}\n\t\t\tif entry.StatelessResetToken != resetToken {\n\t\t\t\treturn fmt.Errorf(\"received conflicting stateless reset tokens for sequence number %d\", seq)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\t// insert at the correct position to maintain sorted order\n\t\tif entry.SequenceNumber > seq {\n\t\t\th.queue = slices.Insert(h.queue, i, newConnID{\n\t\t\t\tSequenceNumber:      seq,\n\t\t\t\tConnectionID:        connID,\n\t\t\t\tStatelessResetToken: resetToken,\n\t\t\t})\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn nil // unreachable\n}\n\nfunc (h *connIDManager) updateConnectionID() {\n\th.assertNotClosed()\n\th.queueControlFrame(&wire.RetireConnectionIDFrame{\n\t\tSequenceNumber: h.activeSequenceNumber,\n\t})\n\th.highestRetired = max(h.highestRetired, h.activeSequenceNumber)\n\tif h.activeStatelessResetToken != nil {\n\t\th.removeStatelessResetToken(*h.activeStatelessResetToken)\n\t}\n\n\tfront := h.queue[0]\n\th.queue = h.queue[1:]\n\th.activeSequenceNumber = front.SequenceNumber\n\th.activeConnectionID = front.ConnectionID\n\th.activeStatelessResetToken = &front.StatelessResetToken\n\th.packetsSinceLastChange = 0\n\th.packetsPerConnectionID = protocol.PacketsPerConnectionID/2 + uint32(h.rand.Int31n(protocol.PacketsPerConnectionID))\n\th.addStatelessResetToken(*h.activeStatelessResetToken)\n}\n\nfunc (h *connIDManager) Close() {\n\th.closed = true\n\tif h.activeStatelessResetToken != nil {\n\t\th.removeStatelessResetToken(*h.activeStatelessResetToken)\n\t}\n\tif h.pathProbing != nil {\n\t\tfor _, entry := range h.pathProbing {\n\t\t\th.removeStatelessResetToken(entry.StatelessResetToken)\n\t\t}\n\t}\n}\n\n// is called when the server performs a Retry\n// and when the server changes the connection ID in the first Initial sent\nfunc (h *connIDManager) ChangeInitialConnID(newConnID protocol.ConnectionID) {\n\tif h.activeSequenceNumber != 0 {\n\t\tpanic(\"expected first connection ID to have sequence number 0\")\n\t}\n\th.activeConnectionID = newConnID\n}\n\n// is called when the server provides a stateless reset token in the transport parameters\nfunc (h *connIDManager) SetStatelessResetToken(token protocol.StatelessResetToken) {\n\th.assertNotClosed()\n\tif h.activeSequenceNumber != 0 {\n\t\tpanic(\"expected first connection ID to have sequence number 0\")\n\t}\n\th.activeStatelessResetToken = &token\n\th.addStatelessResetToken(token)\n}\n\nfunc (h *connIDManager) SentPacket() {\n\th.packetsSinceLastChange++\n}\n\nfunc (h *connIDManager) shouldUpdateConnID() bool {\n\tif !h.handshakeComplete {\n\t\treturn false\n\t}\n\t// initiate the first change as early as possible (after handshake completion)\n\tif len(h.queue) > 0 && h.activeSequenceNumber == 0 {\n\t\treturn true\n\t}\n\t// For later changes, only change if\n\t// 1. The queue of connection IDs is filled more than 50%.\n\t// 2. We sent at least PacketsPerConnectionID packets\n\treturn 2*len(h.queue) >= protocol.MaxActiveConnectionIDs &&\n\t\th.packetsSinceLastChange >= h.packetsPerConnectionID\n}\n\nfunc (h *connIDManager) Get() protocol.ConnectionID {\n\th.assertNotClosed()\n\tif h.shouldUpdateConnID() {\n\t\th.updateConnectionID()\n\t}\n\treturn h.activeConnectionID\n}\n\nfunc (h *connIDManager) SetHandshakeComplete() {\n\th.handshakeComplete = true\n}\n\n// GetConnIDForPath retrieves a connection ID for a new path (i.e. not the active one).\n// Once a connection ID is allocated for a path, it cannot be used for a different path.\n// When called with the same pathID, it will return the same connection ID,\n// unless the peer requested that this connection ID be retired.\nfunc (h *connIDManager) GetConnIDForPath(id pathID) (protocol.ConnectionID, bool) {\n\th.assertNotClosed()\n\t// if we're using zero-length connection IDs, we don't need to change the connection ID\n\tif h.activeConnectionID.Len() == 0 {\n\t\treturn protocol.ConnectionID{}, true\n\t}\n\n\tif h.pathProbing == nil {\n\t\th.pathProbing = make(map[pathID]newConnID)\n\t}\n\tentry, ok := h.pathProbing[id]\n\tif ok {\n\t\treturn entry.ConnectionID, true\n\t}\n\tif len(h.queue) == 0 {\n\t\treturn protocol.ConnectionID{}, false\n\t}\n\tfront := h.queue[0]\n\th.queue = h.queue[1:]\n\th.pathProbing[id] = front\n\th.highestProbingID = front.SequenceNumber\n\th.addStatelessResetToken(front.StatelessResetToken)\n\treturn front.ConnectionID, true\n}\n\nfunc (h *connIDManager) RetireConnIDForPath(pathID pathID) {\n\th.assertNotClosed()\n\t// if we're using zero-length connection IDs, we don't need to change the connection ID\n\tif h.activeConnectionID.Len() == 0 {\n\t\treturn\n\t}\n\n\tentry, ok := h.pathProbing[pathID]\n\tif !ok {\n\t\treturn\n\t}\n\th.queueControlFrame(&wire.RetireConnectionIDFrame{\n\t\tSequenceNumber: entry.SequenceNumber,\n\t})\n\th.removeStatelessResetToken(entry.StatelessResetToken)\n\tdelete(h.pathProbing, pathID)\n}\n\nfunc (h *connIDManager) IsActiveStatelessResetToken(token protocol.StatelessResetToken) bool {\n\tif h.activeStatelessResetToken != nil {\n\t\tif *h.activeStatelessResetToken == token {\n\t\t\treturn true\n\t\t}\n\t}\n\tif h.pathProbing != nil {\n\t\tfor _, entry := range h.pathProbing {\n\t\t\tif entry.StatelessResetToken == token {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\n// Using the connIDManager after it has been closed can have disastrous effects:\n// If the connection ID is rotated, a new entry would be inserted into the packet handler map,\n// leading to a memory leak of the connection struct.\n// See https://github.com/quic-go/quic-go/pull/4852 for more details.\nfunc (h *connIDManager) assertNotClosed() {\n\tif h.closed {\n\t\tpanic(\"connection ID manager is closed\")\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/connection.go",
    "content": "package quic\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/ackhandler\"\n\t\"github.com/quic-go/quic-go/internal/flowcontrol\"\n\t\"github.com/quic-go/quic-go/internal/handshake\"\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/internal/utils/ringbuffer\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n\t\"github.com/quic-go/quic-go/logging\"\n)\n\ntype unpacker interface {\n\tUnpackLongHeader(hdr *wire.Header, data []byte) (*unpackedPacket, error)\n\tUnpackShortHeader(rcvTime time.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error)\n}\n\ntype streamManager interface {\n\tGetOrOpenSendStream(protocol.StreamID) (sendStreamI, error)\n\tGetOrOpenReceiveStream(protocol.StreamID) (receiveStreamI, error)\n\tOpenStream() (Stream, error)\n\tOpenUniStream() (SendStream, error)\n\tOpenStreamSync(context.Context) (Stream, error)\n\tOpenUniStreamSync(context.Context) (SendStream, error)\n\tAcceptStream(context.Context) (Stream, error)\n\tAcceptUniStream(context.Context) (ReceiveStream, error)\n\tDeleteStream(protocol.StreamID) error\n\tUpdateLimits(*wire.TransportParameters)\n\tHandleMaxStreamsFrame(*wire.MaxStreamsFrame)\n\tCloseWithError(error)\n\tResetFor0RTT()\n\tUseResetMaps()\n}\n\ntype cryptoStreamHandler interface {\n\tStartHandshake(context.Context) error\n\tChangeConnectionID(protocol.ConnectionID)\n\tSetLargest1RTTAcked(protocol.PacketNumber) error\n\tSetHandshakeConfirmed()\n\tGetSessionTicket() ([]byte, error)\n\tNextEvent() handshake.Event\n\tDiscardInitialKeys()\n\tHandleMessage([]byte, protocol.EncryptionLevel) error\n\tio.Closer\n\tConnectionState() handshake.ConnectionState\n}\n\ntype receivedPacket struct {\n\tbuffer *packetBuffer\n\n\tremoteAddr net.Addr\n\trcvTime    time.Time\n\tdata       []byte\n\n\tecn protocol.ECN\n\n\tinfo packetInfo // only valid if the contained IP address is valid\n}\n\nfunc (p *receivedPacket) Size() protocol.ByteCount { return protocol.ByteCount(len(p.data)) }\n\nfunc (p *receivedPacket) Clone() *receivedPacket {\n\treturn &receivedPacket{\n\t\tremoteAddr: p.remoteAddr,\n\t\trcvTime:    p.rcvTime,\n\t\tdata:       p.data,\n\t\tbuffer:     p.buffer,\n\t\tecn:        p.ecn,\n\t\tinfo:       p.info,\n\t}\n}\n\ntype connRunner interface {\n\tAdd(protocol.ConnectionID, packetHandler) bool\n\tRetire(protocol.ConnectionID)\n\tRemove(protocol.ConnectionID)\n\tReplaceWithClosed([]protocol.ConnectionID, []byte)\n\tAddResetToken(protocol.StatelessResetToken, packetHandler)\n\tRemoveResetToken(protocol.StatelessResetToken)\n}\n\ntype closeError struct {\n\terr       error\n\timmediate bool\n}\n\ntype errCloseForRecreating struct {\n\tnextPacketNumber protocol.PacketNumber\n\tnextVersion      protocol.Version\n}\n\nfunc (e *errCloseForRecreating) Error() string {\n\treturn \"closing connection in order to recreate it\"\n}\n\nvar connTracingID atomic.Uint64              // to be accessed atomically\nfunc nextConnTracingID() ConnectionTracingID { return ConnectionTracingID(connTracingID.Add(1)) }\n\n// A Connection is a QUIC connection\ntype connection struct {\n\ttr *Transport\n\n\t// Destination connection ID used during the handshake.\n\t// Used to check source connection ID on incoming packets.\n\thandshakeDestConnID protocol.ConnectionID\n\t// Set for the client. Destination connection ID used on the first Initial sent.\n\torigDestConnID protocol.ConnectionID\n\tretrySrcConnID *protocol.ConnectionID // only set for the client (and if a Retry was performed)\n\n\tsrcConnIDLen int\n\n\tperspective protocol.Perspective\n\tversion     protocol.Version\n\tconfig      *Config\n\n\tconn      sendConn\n\tsendQueue sender\n\n\t// lazily initialzed: most connections never migrate\n\tpathManager         *pathManager\n\tlargestRcvdAppData  protocol.PacketNumber\n\tpathManagerOutgoing atomic.Pointer[pathManagerOutgoing]\n\n\tstreamsMap      streamManager\n\tconnIDManager   *connIDManager\n\tconnIDGenerator *connIDGenerator\n\n\trttStats *utils.RTTStats\n\n\tcryptoStreamManager   *cryptoStreamManager\n\tsentPacketHandler     ackhandler.SentPacketHandler\n\treceivedPacketHandler ackhandler.ReceivedPacketHandler\n\tretransmissionQueue   *retransmissionQueue\n\tframer                *framer\n\tconnFlowController    flowcontrol.ConnectionFlowController\n\ttokenStoreKey         string                    // only set for the client\n\ttokenGenerator        *handshake.TokenGenerator // only set for the server\n\n\tunpacker      unpacker\n\tframeParser   wire.FrameParser\n\tpacker        packer\n\tmtuDiscoverer mtuDiscoverer // initialized when the transport parameters are received\n\n\tcurrentMTUEstimate atomic.Uint32\n\n\tinitialStream       *cryptoStream\n\thandshakeStream     *cryptoStream\n\toneRTTStream        *cryptoStream // only set for the server\n\tcryptoStreamHandler cryptoStreamHandler\n\n\tnotifyReceivedPacket chan struct{}\n\tsendingScheduled     chan struct{}\n\treceivedPacketMx     sync.Mutex\n\treceivedPackets      ringbuffer.RingBuffer[receivedPacket]\n\n\t// closeChan is used to notify the run loop that it should terminate\n\tcloseChan chan struct{}\n\tcloseErr  atomic.Pointer[closeError]\n\n\tctx                   context.Context\n\tctxCancel             context.CancelCauseFunc\n\thandshakeCompleteChan chan struct{}\n\n\tundecryptablePackets          []receivedPacket // undecryptable packets, waiting for a change in encryption level\n\tundecryptablePacketsToProcess []receivedPacket\n\n\tearlyConnReadyChan chan struct{}\n\tsentFirstPacket    bool\n\tdroppedInitialKeys bool\n\thandshakeComplete  bool\n\thandshakeConfirmed bool\n\n\treceivedRetry       bool\n\tversionNegotiated   bool\n\treceivedFirstPacket bool\n\n\t// the minimum of the max_idle_timeout values advertised by both endpoints\n\tidleTimeout  time.Duration\n\tcreationTime time.Time\n\t// The idle timeout is set based on the max of the time we received the last packet...\n\tlastPacketReceivedTime time.Time\n\t// ... and the time we sent a new ack-eliciting packet after receiving a packet.\n\tfirstAckElicitingPacketAfterIdleSentTime time.Time\n\t// pacingDeadline is the time when the next packet should be sent\n\tpacingDeadline time.Time\n\n\tpeerParams *wire.TransportParameters\n\n\ttimer connectionTimer\n\t// keepAlivePingSent stores whether a keep alive PING is in flight.\n\t// It is reset as soon as we receive a packet from the peer.\n\tkeepAlivePingSent bool\n\tkeepAliveInterval time.Duration\n\n\tdatagramQueue *datagramQueue\n\n\tconnStateMutex sync.Mutex\n\tconnState      ConnectionState\n\n\tlogID  string\n\ttracer *logging.ConnectionTracer\n\tlogger utils.Logger\n}\n\nvar (\n\t_ Connection      = &connection{}\n\t_ EarlyConnection = &connection{}\n\t_ streamSender    = &connection{}\n)\n\nvar newConnection = func(\n\tctx context.Context,\n\tctxCancel context.CancelCauseFunc,\n\tconn sendConn,\n\ttr *Transport,\n\torigDestConnID protocol.ConnectionID,\n\tretrySrcConnID *protocol.ConnectionID,\n\tclientDestConnID protocol.ConnectionID,\n\tdestConnID protocol.ConnectionID,\n\tsrcConnID protocol.ConnectionID,\n\tconnIDGenerator ConnectionIDGenerator,\n\tstatelessResetter *statelessResetter,\n\tconf *Config,\n\ttlsConf *tls.Config,\n\ttokenGenerator *handshake.TokenGenerator,\n\tclientAddressValidated bool,\n\ttracer *logging.ConnectionTracer,\n\tlogger utils.Logger,\n\tv protocol.Version,\n) quicConn {\n\ts := &connection{\n\t\tctx:                 ctx,\n\t\tctxCancel:           ctxCancel,\n\t\ttr:                  tr,\n\t\tconn:                conn,\n\t\tconfig:              conf,\n\t\thandshakeDestConnID: destConnID,\n\t\tsrcConnIDLen:        srcConnID.Len(),\n\t\ttokenGenerator:      tokenGenerator,\n\t\toneRTTStream:        newCryptoStream(),\n\t\tperspective:         protocol.PerspectiveServer,\n\t\ttracer:              tracer,\n\t\tlogger:              logger,\n\t\tversion:             v,\n\t}\n\tif origDestConnID.Len() > 0 {\n\t\ts.logID = origDestConnID.String()\n\t} else {\n\t\ts.logID = destConnID.String()\n\t}\n\trunner := tr.connRunner()\n\ts.connIDManager = newConnIDManager(\n\t\tdestConnID,\n\t\tfunc(token protocol.StatelessResetToken) { runner.AddResetToken(token, s) },\n\t\trunner.RemoveResetToken,\n\t\ts.queueControlFrame,\n\t)\n\ts.connIDGenerator = newConnIDGenerator(\n\t\ttr.id(),\n\t\tsrcConnID,\n\t\t&clientDestConnID,\n\t\tstatelessResetter,\n\t\tconnRunnerCallbacks{\n\t\t\tAddConnectionID:    func(connID protocol.ConnectionID) { runner.Add(connID, s) },\n\t\t\tRemoveConnectionID: runner.Remove,\n\t\t\tRetireConnectionID: runner.Retire,\n\t\t\tReplaceWithClosed:  runner.ReplaceWithClosed,\n\t\t},\n\t\ts.queueControlFrame,\n\t\tconnIDGenerator,\n\t)\n\ts.preSetup()\n\ts.sentPacketHandler, s.receivedPacketHandler = ackhandler.NewAckHandler(\n\t\t0,\n\t\tprotocol.ByteCount(s.config.InitialPacketSize),\n\t\ts.rttStats,\n\t\tclientAddressValidated,\n\t\ts.conn.capabilities().ECN,\n\t\ts.perspective,\n\t\ts.tracer,\n\t\ts.logger,\n\t)\n\ts.currentMTUEstimate.Store(uint32(estimateMaxPayloadSize(protocol.ByteCount(s.config.InitialPacketSize))))\n\tstatelessResetToken := statelessResetter.GetStatelessResetToken(srcConnID)\n\t// Allow server to define custom MaxUDPPayloadSize\n\tmaxUDPPayloadSize := protocol.MaxPacketBufferSize\n\tif maxPacketSize := os.Getenv(\"TUNNEL_MAX_QUIC_PACKET_SIZE\"); maxPacketSize != \"\" {\n\t\tif customMaxPacketSize, err := strconv.ParseUint(maxPacketSize, 10, 64); err == nil {\n\t\t\tmaxUDPPayloadSize = int(customMaxPacketSize)\n\t\t} else {\n\t\t\tutils.DefaultLogger.Errorf(\"failed to parse TUNNEL_MAX_QUIC_PACKET_SIZE: %v\", err)\n\t\t}\n\t}\n\n\tparams := &wire.TransportParameters{\n\t\tInitialMaxStreamDataBidiLocal:   protocol.ByteCount(s.config.InitialStreamReceiveWindow),\n\t\tInitialMaxStreamDataBidiRemote:  protocol.ByteCount(s.config.InitialStreamReceiveWindow),\n\t\tInitialMaxStreamDataUni:         protocol.ByteCount(s.config.InitialStreamReceiveWindow),\n\t\tInitialMaxData:                  protocol.ByteCount(s.config.InitialConnectionReceiveWindow),\n\t\tMaxIdleTimeout:                  s.config.MaxIdleTimeout,\n\t\tMaxBidiStreamNum:                protocol.StreamNum(s.config.MaxIncomingStreams),\n\t\tMaxUniStreamNum:                 protocol.StreamNum(s.config.MaxIncomingUniStreams),\n\t\tMaxAckDelay:                     protocol.MaxAckDelayInclGranularity,\n\t\tAckDelayExponent:                protocol.AckDelayExponent,\n\t\tMaxUDPPayloadSize:               protocol.ByteCount(maxUDPPayloadSize),\n\t\tStatelessResetToken:             &statelessResetToken,\n\t\tOriginalDestinationConnectionID: origDestConnID,\n\t\t// For interoperability with quic-go versions before May 2023, this value must be set to a value\n\t\t// different from protocol.DefaultActiveConnectionIDLimit.\n\t\t// If set to the default value, it will be omitted from the transport parameters, which will make\n\t\t// old quic-go versions interpret it as 0, instead of the default value of 2.\n\t\t// See https://github.com/quic-go/quic-go/pull/3806.\n\t\tActiveConnectionIDLimit:   protocol.MaxActiveConnectionIDs,\n\t\tInitialSourceConnectionID: srcConnID,\n\t\tRetrySourceConnectionID:   retrySrcConnID,\n\t}\n\tif s.config.EnableDatagrams {\n\t\tparams.MaxDatagramFrameSize = wire.MaxDatagramSize\n\t} else {\n\t\tparams.MaxDatagramFrameSize = protocol.InvalidByteCount\n\t}\n\tif s.tracer != nil && s.tracer.SentTransportParameters != nil {\n\t\ts.tracer.SentTransportParameters(params)\n\t}\n\tcs := handshake.NewCryptoSetupServer(\n\t\tclientDestConnID,\n\t\tconn.LocalAddr(),\n\t\tconn.RemoteAddr(),\n\t\tparams,\n\t\ttlsConf,\n\t\tconf.Allow0RTT,\n\t\ts.rttStats,\n\t\ttracer,\n\t\tlogger,\n\t\ts.version,\n\t)\n\ts.cryptoStreamHandler = cs\n\ts.packer = newPacketPacker(srcConnID, s.connIDManager.Get, s.initialStream, s.handshakeStream, s.sentPacketHandler, s.retransmissionQueue, cs, s.framer, s.receivedPacketHandler, s.datagramQueue, s.perspective)\n\ts.unpacker = newPacketUnpacker(cs, s.srcConnIDLen)\n\ts.cryptoStreamManager = newCryptoStreamManager(s.initialStream, s.handshakeStream, s.oneRTTStream)\n\treturn s\n}\n\n// declare this as a variable, such that we can it mock it in the tests\nvar newClientConnection = func(\n\tctx context.Context,\n\tconn sendConn,\n\ttr *Transport,\n\tdestConnID protocol.ConnectionID,\n\tsrcConnID protocol.ConnectionID,\n\tconnIDGenerator ConnectionIDGenerator,\n\tstatelessResetter *statelessResetter,\n\tconf *Config,\n\ttlsConf *tls.Config,\n\tinitialPacketNumber protocol.PacketNumber,\n\tenable0RTT bool,\n\thasNegotiatedVersion bool,\n\ttracer *logging.ConnectionTracer,\n\tlogger utils.Logger,\n\tv protocol.Version,\n) quicConn {\n\ts := &connection{\n\t\ttr:                  tr,\n\t\tconn:                conn,\n\t\tconfig:              conf,\n\t\torigDestConnID:      destConnID,\n\t\thandshakeDestConnID: destConnID,\n\t\tsrcConnIDLen:        srcConnID.Len(),\n\t\tperspective:         protocol.PerspectiveClient,\n\t\tlogID:               destConnID.String(),\n\t\tlogger:              logger,\n\t\ttracer:              tracer,\n\t\tversionNegotiated:   hasNegotiatedVersion,\n\t\tversion:             v,\n\t}\n\trunner := tr.connRunner()\n\ts.connIDManager = newConnIDManager(\n\t\tdestConnID,\n\t\tfunc(token protocol.StatelessResetToken) { runner.AddResetToken(token, s) },\n\t\trunner.RemoveResetToken,\n\t\ts.queueControlFrame,\n\t)\n\ts.connIDGenerator = newConnIDGenerator(\n\t\ttr.id(),\n\t\tsrcConnID,\n\t\tnil,\n\t\tstatelessResetter,\n\t\tconnRunnerCallbacks{\n\t\t\tAddConnectionID:    func(connID protocol.ConnectionID) { runner.Add(connID, s) },\n\t\t\tRemoveConnectionID: runner.Remove,\n\t\t\tRetireConnectionID: runner.Retire,\n\t\t\tReplaceWithClosed:  runner.ReplaceWithClosed,\n\t\t},\n\t\ts.queueControlFrame,\n\t\tconnIDGenerator,\n\t)\n\ts.ctx, s.ctxCancel = context.WithCancelCause(ctx)\n\ts.preSetup()\n\ts.sentPacketHandler, s.receivedPacketHandler = ackhandler.NewAckHandler(\n\t\tinitialPacketNumber,\n\t\tprotocol.ByteCount(s.config.InitialPacketSize),\n\t\ts.rttStats,\n\t\tfalse, // has no effect\n\t\ts.conn.capabilities().ECN,\n\t\ts.perspective,\n\t\ts.tracer,\n\t\ts.logger,\n\t)\n\ts.currentMTUEstimate.Store(uint32(estimateMaxPayloadSize(protocol.ByteCount(s.config.InitialPacketSize))))\n\toneRTTStream := newCryptoStream()\n\tparams := &wire.TransportParameters{\n\t\tInitialMaxStreamDataBidiRemote: protocol.ByteCount(s.config.InitialStreamReceiveWindow),\n\t\tInitialMaxStreamDataBidiLocal:  protocol.ByteCount(s.config.InitialStreamReceiveWindow),\n\t\tInitialMaxStreamDataUni:        protocol.ByteCount(s.config.InitialStreamReceiveWindow),\n\t\tInitialMaxData:                 protocol.ByteCount(s.config.InitialConnectionReceiveWindow),\n\t\tMaxIdleTimeout:                 s.config.MaxIdleTimeout,\n\t\tMaxBidiStreamNum:               protocol.StreamNum(s.config.MaxIncomingStreams),\n\t\tMaxUniStreamNum:                protocol.StreamNum(s.config.MaxIncomingUniStreams),\n\t\tMaxAckDelay:                    protocol.MaxAckDelayInclGranularity,\n\t\tMaxUDPPayloadSize:              protocol.MaxPacketBufferSize,\n\t\tAckDelayExponent:               protocol.AckDelayExponent,\n\t\t// For interoperability with quic-go versions before May 2023, this value must be set to a value\n\t\t// different from protocol.DefaultActiveConnectionIDLimit.\n\t\t// If set to the default value, it will be omitted from the transport parameters, which will make\n\t\t// old quic-go versions interpret it as 0, instead of the default value of 2.\n\t\t// See https://github.com/quic-go/quic-go/pull/3806.\n\t\tActiveConnectionIDLimit:   protocol.MaxActiveConnectionIDs,\n\t\tInitialSourceConnectionID: srcConnID,\n\t}\n\tif s.config.EnableDatagrams {\n\t\tparams.MaxDatagramFrameSize = wire.MaxDatagramSize\n\t} else {\n\t\tparams.MaxDatagramFrameSize = protocol.InvalidByteCount\n\t}\n\tif s.tracer != nil && s.tracer.SentTransportParameters != nil {\n\t\ts.tracer.SentTransportParameters(params)\n\t}\n\tcs := handshake.NewCryptoSetupClient(\n\t\tdestConnID,\n\t\tparams,\n\t\ttlsConf,\n\t\tenable0RTT,\n\t\ts.rttStats,\n\t\ttracer,\n\t\tlogger,\n\t\ts.version,\n\t)\n\ts.cryptoStreamHandler = cs\n\ts.cryptoStreamManager = newCryptoStreamManager(s.initialStream, s.handshakeStream, oneRTTStream)\n\ts.unpacker = newPacketUnpacker(cs, s.srcConnIDLen)\n\ts.packer = newPacketPacker(srcConnID, s.connIDManager.Get, s.initialStream, s.handshakeStream, s.sentPacketHandler, s.retransmissionQueue, cs, s.framer, s.receivedPacketHandler, s.datagramQueue, s.perspective)\n\tif len(tlsConf.ServerName) > 0 {\n\t\ts.tokenStoreKey = tlsConf.ServerName\n\t} else {\n\t\ts.tokenStoreKey = conn.RemoteAddr().String()\n\t}\n\tif s.config.TokenStore != nil {\n\t\tif token := s.config.TokenStore.Pop(s.tokenStoreKey); token != nil {\n\t\t\ts.packer.SetToken(token.data)\n\t\t}\n\t}\n\treturn s\n}\n\nfunc (s *connection) preSetup() {\n\ts.largestRcvdAppData = protocol.InvalidPacketNumber\n\ts.initialStream = newCryptoStream()\n\ts.handshakeStream = newCryptoStream()\n\ts.sendQueue = newSendQueue(s.conn)\n\ts.retransmissionQueue = newRetransmissionQueue()\n\ts.frameParser = *wire.NewFrameParser(s.config.EnableDatagrams)\n\ts.rttStats = &utils.RTTStats{}\n\ts.connFlowController = flowcontrol.NewConnectionFlowController(\n\t\tprotocol.ByteCount(s.config.InitialConnectionReceiveWindow),\n\t\tprotocol.ByteCount(s.config.MaxConnectionReceiveWindow),\n\t\tfunc(size protocol.ByteCount) bool {\n\t\t\tif s.config.AllowConnectionWindowIncrease == nil {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn s.config.AllowConnectionWindowIncrease(s, uint64(size))\n\t\t},\n\t\ts.rttStats,\n\t\ts.logger,\n\t)\n\ts.earlyConnReadyChan = make(chan struct{})\n\ts.streamsMap = newStreamsMap(\n\t\ts.ctx,\n\t\ts,\n\t\ts.queueControlFrame,\n\t\ts.newFlowController,\n\t\tuint64(s.config.MaxIncomingStreams),\n\t\tuint64(s.config.MaxIncomingUniStreams),\n\t\ts.perspective,\n\t)\n\ts.framer = newFramer(s.connFlowController)\n\ts.receivedPackets.Init(8)\n\ts.notifyReceivedPacket = make(chan struct{}, 1)\n\ts.closeChan = make(chan struct{}, 1)\n\ts.sendingScheduled = make(chan struct{}, 1)\n\ts.handshakeCompleteChan = make(chan struct{})\n\n\tnow := time.Now()\n\ts.lastPacketReceivedTime = now\n\ts.creationTime = now\n\n\ts.datagramQueue = newDatagramQueue(s.scheduleSending, s.logger)\n\ts.connState.Version = s.version\n}\n\n// run the connection main loop\nfunc (s *connection) run() (err error) {\n\tdefer func() { s.ctxCancel(err) }()\n\n\tdefer func() {\n\t\t// drain queued packets that will never be processed\n\t\ts.receivedPacketMx.Lock()\n\t\tdefer s.receivedPacketMx.Unlock()\n\n\t\tfor !s.receivedPackets.Empty() {\n\t\t\tp := s.receivedPackets.PopFront()\n\t\t\tp.buffer.Decrement()\n\t\t\tp.buffer.MaybeRelease()\n\t\t}\n\t}()\n\n\ts.timer = *newTimer()\n\n\tif err := s.cryptoStreamHandler.StartHandshake(s.ctx); err != nil {\n\t\treturn err\n\t}\n\tif err := s.handleHandshakeEvents(time.Now()); err != nil {\n\t\treturn err\n\t}\n\tgo func() {\n\t\tif err := s.sendQueue.Run(); err != nil {\n\t\t\ts.destroyImpl(err)\n\t\t}\n\t}()\n\n\tif s.perspective == protocol.PerspectiveClient {\n\t\ts.scheduleSending() // so the ClientHello actually gets sent\n\t}\n\n\tvar sendQueueAvailable <-chan struct{}\n\nrunLoop:\n\tfor {\n\t\tif s.framer.QueuedTooManyControlFrames() {\n\t\t\ts.setCloseError(&closeError{err: &qerr.TransportError{ErrorCode: InternalError}})\n\t\t\tbreak runLoop\n\t\t}\n\t\t// Close immediately if requested\n\t\tselect {\n\t\tcase <-s.closeChan:\n\t\t\tbreak runLoop\n\t\tdefault:\n\t\t}\n\n\t\t// no need to set a timer if we can send packets immediately\n\t\tif s.pacingDeadline != deadlineSendImmediately {\n\t\t\ts.maybeResetTimer()\n\t\t}\n\n\t\t// 1st: handle undecryptable packets, if any.\n\t\t// This can only occur before completion of the handshake.\n\t\tif len(s.undecryptablePacketsToProcess) > 0 {\n\t\t\tvar processedUndecryptablePacket bool\n\t\t\tqueue := s.undecryptablePacketsToProcess\n\t\t\ts.undecryptablePacketsToProcess = nil\n\t\t\tfor _, p := range queue {\n\t\t\t\tprocessed, err := s.handleOnePacket(p)\n\t\t\t\tif err != nil {\n\t\t\t\t\ts.setCloseError(&closeError{err: err})\n\t\t\t\t\tbreak runLoop\n\t\t\t\t}\n\t\t\t\tif processed {\n\t\t\t\t\tprocessedUndecryptablePacket = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tif processedUndecryptablePacket {\n\t\t\t\t// if we processed any undecryptable packets, jump to the resetting of the timers directly\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// 2nd: receive packets.\n\t\tprocessed, err := s.handlePackets() // don't check receivedPackets.Len() in the run loop to avoid locking the mutex\n\t\tif err != nil {\n\t\t\ts.setCloseError(&closeError{err: err})\n\t\t\tbreak runLoop\n\t\t}\n\n\t\t// We don't need to wait for new events if:\n\t\t// * we processed packets: we probably need to send an ACK, and potentially more data\n\t\t// * the pacer allows us to send more packets immediately\n\t\tshouldProceedImmediately := sendQueueAvailable == nil && (processed || s.pacingDeadline.Equal(deadlineSendImmediately))\n\t\tif !shouldProceedImmediately {\n\t\t\t// 3rd: wait for something to happen:\n\t\t\t// * closing of the connection\n\t\t\t// * timer firing\n\t\t\t// * sending scheduled\n\t\t\t// * send queue available\n\t\t\t// * received packets\n\t\t\tselect {\n\t\t\tcase <-s.closeChan:\n\t\t\t\tbreak runLoop\n\t\t\tcase <-s.timer.Chan():\n\t\t\t\ts.timer.SetRead()\n\t\t\tcase <-s.sendingScheduled:\n\t\t\tcase <-sendQueueAvailable:\n\t\t\tcase <-s.notifyReceivedPacket:\n\t\t\t\twasProcessed, err := s.handlePackets()\n\t\t\t\tif err != nil {\n\t\t\t\t\ts.setCloseError(&closeError{err: err})\n\t\t\t\t\tbreak runLoop\n\t\t\t\t}\n\t\t\t\t// if we processed any undecryptable packets, jump to the resetting of the timers directly\n\t\t\t\tif !wasProcessed {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Check for loss detection timeout.\n\t\t// This could cause packets to be declared lost, and retransmissions to be enqueued.\n\t\tnow := time.Now()\n\t\tif timeout := s.sentPacketHandler.GetLossDetectionTimeout(); !timeout.IsZero() && timeout.Before(now) {\n\t\t\tif err := s.sentPacketHandler.OnLossDetectionTimeout(now); err != nil {\n\t\t\t\ts.setCloseError(&closeError{err: err})\n\t\t\t\tbreak runLoop\n\t\t\t}\n\t\t}\n\n\t\tif keepAliveTime := s.nextKeepAliveTime(); !keepAliveTime.IsZero() && !now.Before(keepAliveTime) {\n\t\t\t// send a PING frame since there is no activity in the connection\n\t\t\ts.logger.Debugf(\"Sending a keep-alive PING to keep the connection alive.\")\n\t\t\ts.framer.QueueControlFrame(&wire.PingFrame{})\n\t\t\ts.keepAlivePingSent = true\n\t\t} else if !s.handshakeComplete && now.Sub(s.creationTime) >= s.config.handshakeTimeout() {\n\t\t\ts.destroyImpl(qerr.ErrHandshakeTimeout)\n\t\t\tbreak runLoop\n\t\t} else {\n\t\t\tidleTimeoutStartTime := s.idleTimeoutStartTime()\n\t\t\tif (!s.handshakeComplete && now.Sub(idleTimeoutStartTime) >= s.config.HandshakeIdleTimeout) ||\n\t\t\t\t(s.handshakeComplete && now.After(s.nextIdleTimeoutTime())) {\n\t\t\t\ts.destroyImpl(qerr.ErrIdleTimeout)\n\t\t\t\tbreak runLoop\n\t\t\t}\n\t\t}\n\n\t\tif s.perspective == protocol.PerspectiveClient {\n\t\t\tpm := s.pathManagerOutgoing.Load()\n\t\t\tif pm != nil {\n\t\t\t\ttr, ok := pm.ShouldSwitchPath()\n\t\t\t\tif ok {\n\t\t\t\t\ts.switchToNewPath(tr, now)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif s.sendQueue.WouldBlock() {\n\t\t\t// The send queue is still busy sending out packets. Wait until there's space to enqueue new packets.\n\t\t\tsendQueueAvailable = s.sendQueue.Available()\n\t\t\t// Cancel the pacing timer, as we can't send any more packets until the send queue is available again.\n\t\t\ts.pacingDeadline = time.Time{}\n\t\t\tcontinue\n\t\t}\n\n\t\tif s.closeErr.Load() != nil {\n\t\t\tbreak runLoop\n\t\t}\n\n\t\tif err := s.triggerSending(now); err != nil {\n\t\t\ts.setCloseError(&closeError{err: err})\n\t\t\tbreak runLoop\n\t\t}\n\t\tif s.sendQueue.WouldBlock() {\n\t\t\t// The send queue is still busy sending out packets. Wait until there's space to enqueue new packets.\n\t\t\tsendQueueAvailable = s.sendQueue.Available()\n\t\t\t// Cancel the pacing timer, as we can't send any more packets until the send queue is available again.\n\t\t\ts.pacingDeadline = time.Time{}\n\t\t} else {\n\t\t\tsendQueueAvailable = nil\n\t\t}\n\t}\n\n\tcloseErr := s.closeErr.Load()\n\ts.cryptoStreamHandler.Close()\n\ts.sendQueue.Close() // close the send queue before sending the CONNECTION_CLOSE\n\ts.handleCloseError(closeErr)\n\tif s.tracer != nil && s.tracer.Close != nil {\n\t\tif e := (&errCloseForRecreating{}); !errors.As(closeErr.err, &e) {\n\t\t\ts.tracer.Close()\n\t\t}\n\t}\n\ts.logger.Infof(\"Connection %s closed.\", s.logID)\n\ts.timer.Stop()\n\treturn closeErr.err\n}\n\n// blocks until the early connection can be used\nfunc (s *connection) earlyConnReady() <-chan struct{} {\n\treturn s.earlyConnReadyChan\n}\n\nfunc (s *connection) HandshakeComplete() <-chan struct{} {\n\treturn s.handshakeCompleteChan\n}\n\nfunc (s *connection) Context() context.Context {\n\treturn s.ctx\n}\n\nfunc (s *connection) supportsDatagrams() bool {\n\treturn s.peerParams.MaxDatagramFrameSize > 0\n}\n\nfunc (s *connection) ConnectionState() ConnectionState {\n\ts.connStateMutex.Lock()\n\tdefer s.connStateMutex.Unlock()\n\tcs := s.cryptoStreamHandler.ConnectionState()\n\ts.connState.TLS = cs.ConnectionState\n\ts.connState.Used0RTT = cs.Used0RTT\n\ts.connState.GSO = s.conn.capabilities().GSO\n\treturn s.connState\n}\n\n// Time when the connection should time out\nfunc (s *connection) nextIdleTimeoutTime() time.Time {\n\tidleTimeout := max(s.idleTimeout, s.rttStats.PTO(true)*3)\n\treturn s.idleTimeoutStartTime().Add(idleTimeout)\n}\n\n// Time when the next keep-alive packet should be sent.\n// It returns a zero time if no keep-alive should be sent.\nfunc (s *connection) nextKeepAliveTime() time.Time {\n\tif s.config.KeepAlivePeriod == 0 || s.keepAlivePingSent {\n\t\treturn time.Time{}\n\t}\n\tkeepAliveInterval := max(s.keepAliveInterval, s.rttStats.PTO(true)*3/2)\n\treturn s.lastPacketReceivedTime.Add(keepAliveInterval)\n}\n\nfunc (s *connection) maybeResetTimer() {\n\tvar deadline time.Time\n\tif !s.handshakeComplete {\n\t\tdeadline = s.creationTime.Add(s.config.handshakeTimeout())\n\t\tif t := s.idleTimeoutStartTime().Add(s.config.HandshakeIdleTimeout); t.Before(deadline) {\n\t\t\tdeadline = t\n\t\t}\n\t} else {\n\t\tif keepAliveTime := s.nextKeepAliveTime(); !keepAliveTime.IsZero() {\n\t\t\tdeadline = keepAliveTime\n\t\t} else {\n\t\t\tdeadline = s.nextIdleTimeoutTime()\n\t\t}\n\t}\n\n\ts.timer.SetTimer(\n\t\tdeadline,\n\t\ts.receivedPacketHandler.GetAlarmTimeout(),\n\t\ts.sentPacketHandler.GetLossDetectionTimeout(),\n\t\ts.pacingDeadline,\n\t)\n}\n\nfunc (s *connection) idleTimeoutStartTime() time.Time {\n\tstartTime := s.lastPacketReceivedTime\n\tif t := s.firstAckElicitingPacketAfterIdleSentTime; t.After(startTime) {\n\t\tstartTime = t\n\t}\n\treturn startTime\n}\n\nfunc (s *connection) switchToNewPath(tr *Transport, now time.Time) {\n\tinitialPacketSize := protocol.ByteCount(s.config.InitialPacketSize)\n\ts.sentPacketHandler.MigratedPath(now, initialPacketSize)\n\tmaxPacketSize := protocol.ByteCount(protocol.MaxPacketBufferSize)\n\tif s.peerParams.MaxUDPPayloadSize > 0 && s.peerParams.MaxUDPPayloadSize < maxPacketSize {\n\t\tmaxPacketSize = s.peerParams.MaxUDPPayloadSize\n\t}\n\ts.mtuDiscoverer.Reset(now, initialPacketSize, maxPacketSize)\n\ts.conn = newSendConn(tr.conn, s.conn.RemoteAddr(), packetInfo{}, utils.DefaultLogger) // TODO: find a better way\n\ts.sendQueue.Close()\n\ts.sendQueue = newSendQueue(s.conn)\n\tgo func() {\n\t\tif err := s.sendQueue.Run(); err != nil {\n\t\t\ts.destroyImpl(err)\n\t\t}\n\t}()\n}\n\nfunc (s *connection) handleHandshakeComplete(now time.Time) error {\n\tdefer close(s.handshakeCompleteChan)\n\t// Once the handshake completes, we have derived 1-RTT keys.\n\t// There's no point in queueing undecryptable packets for later decryption anymore.\n\ts.undecryptablePackets = nil\n\n\ts.connIDManager.SetHandshakeComplete()\n\ts.connIDGenerator.SetHandshakeComplete()\n\n\tif s.tracer != nil && s.tracer.ChoseALPN != nil {\n\t\ts.tracer.ChoseALPN(s.cryptoStreamHandler.ConnectionState().NegotiatedProtocol)\n\t}\n\n\t// The server applies transport parameters right away, but the client side has to wait for handshake completion.\n\t// During a 0-RTT connection, the client is only allowed to use the new transport parameters for 1-RTT packets.\n\tif s.perspective == protocol.PerspectiveClient {\n\t\ts.applyTransportParameters()\n\t\treturn nil\n\t}\n\n\t// All these only apply to the server side.\n\tif err := s.handleHandshakeConfirmed(now); err != nil {\n\t\treturn err\n\t}\n\n\tticket, err := s.cryptoStreamHandler.GetSessionTicket()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif ticket != nil { // may be nil if session tickets are disabled via tls.Config.SessionTicketsDisabled\n\t\ts.oneRTTStream.Write(ticket)\n\t\tfor s.oneRTTStream.HasData() {\n\t\t\ts.queueControlFrame(s.oneRTTStream.PopCryptoFrame(protocol.MaxPostHandshakeCryptoFrameSize))\n\t\t}\n\t}\n\ttoken, err := s.tokenGenerator.NewToken(s.conn.RemoteAddr())\n\tif err != nil {\n\t\treturn err\n\t}\n\ts.queueControlFrame(&wire.NewTokenFrame{Token: token})\n\ts.queueControlFrame(&wire.HandshakeDoneFrame{})\n\treturn nil\n}\n\nfunc (s *connection) handleHandshakeConfirmed(now time.Time) error {\n\tif err := s.dropEncryptionLevel(protocol.EncryptionHandshake, now); err != nil {\n\t\treturn err\n\t}\n\n\ts.handshakeConfirmed = true\n\ts.cryptoStreamHandler.SetHandshakeConfirmed()\n\n\tif !s.config.DisablePathMTUDiscovery && s.conn.capabilities().DF {\n\t\ts.mtuDiscoverer.Start(now)\n\t}\n\treturn nil\n}\n\nfunc (s *connection) handlePackets() (wasProcessed bool, _ error) {\n\t// Now process all packets in the receivedPackets channel.\n\t// Limit the number of packets to the length of the receivedPackets channel,\n\t// so we eventually get a chance to send out an ACK when receiving a lot of packets.\n\ts.receivedPacketMx.Lock()\n\tnumPackets := s.receivedPackets.Len()\n\tif numPackets == 0 {\n\t\ts.receivedPacketMx.Unlock()\n\t\treturn false, nil\n\t}\n\n\tvar hasMorePackets bool\n\tfor i := 0; i < numPackets; i++ {\n\t\tif i > 0 {\n\t\t\ts.receivedPacketMx.Lock()\n\t\t}\n\t\tp := s.receivedPackets.PopFront()\n\t\thasMorePackets = !s.receivedPackets.Empty()\n\t\ts.receivedPacketMx.Unlock()\n\n\t\tprocessed, err := s.handleOnePacket(p)\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\t\tif processed {\n\t\t\twasProcessed = true\n\t\t}\n\t\tif !hasMorePackets {\n\t\t\tbreak\n\t\t}\n\t\t// only process a single packet at a time before handshake completion\n\t\tif !s.handshakeComplete {\n\t\t\tbreak\n\t\t}\n\t}\n\tif hasMorePackets {\n\t\tselect {\n\t\tcase s.notifyReceivedPacket <- struct{}{}:\n\t\tdefault:\n\t\t}\n\t}\n\treturn wasProcessed, nil\n}\n\nfunc (s *connection) handleOnePacket(rp receivedPacket) (wasProcessed bool, _ error) {\n\ts.sentPacketHandler.ReceivedBytes(rp.Size(), rp.rcvTime)\n\n\tif wire.IsVersionNegotiationPacket(rp.data) {\n\t\ts.handleVersionNegotiationPacket(rp)\n\t\treturn false, nil\n\t}\n\n\tvar counter uint8\n\tvar lastConnID protocol.ConnectionID\n\tdata := rp.data\n\tp := rp\n\tfor len(data) > 0 {\n\t\tif counter > 0 {\n\t\t\tp = *(p.Clone())\n\t\t\tp.data = data\n\n\t\t\tdestConnID, err := wire.ParseConnectionID(p.data, s.srcConnIDLen)\n\t\t\tif err != nil {\n\t\t\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\t\t\ts.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropHeaderParseError)\n\t\t\t\t}\n\t\t\t\ts.logger.Debugf(\"error parsing packet, couldn't parse connection ID: %s\", err)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif destConnID != lastConnID {\n\t\t\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\t\t\ts.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnknownConnectionID)\n\t\t\t\t}\n\t\t\t\ts.logger.Debugf(\"coalesced packet has different destination connection ID: %s, expected %s\", destConnID, lastConnID)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif wire.IsLongHeaderPacket(p.data[0]) {\n\t\t\thdr, packetData, rest, err := wire.ParsePacket(p.data)\n\t\t\tif err != nil {\n\t\t\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\t\t\tdropReason := logging.PacketDropHeaderParseError\n\t\t\t\t\tif err == wire.ErrUnsupportedVersion {\n\t\t\t\t\t\tdropReason = logging.PacketDropUnsupportedVersion\n\t\t\t\t\t}\n\t\t\t\t\ts.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), dropReason)\n\t\t\t\t}\n\t\t\t\ts.logger.Debugf(\"error parsing packet: %s\", err)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tlastConnID = hdr.DestConnectionID\n\n\t\t\tif hdr.Version != s.version {\n\t\t\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\t\t\ts.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedVersion)\n\t\t\t\t}\n\t\t\t\ts.logger.Debugf(\"Dropping packet with version %x. Expected %x.\", hdr.Version, s.version)\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif counter > 0 {\n\t\t\t\tp.buffer.Split()\n\t\t\t}\n\t\t\tcounter++\n\n\t\t\t// only log if this actually a coalesced packet\n\t\t\tif s.logger.Debug() && (counter > 1 || len(rest) > 0) {\n\t\t\t\ts.logger.Debugf(\"Parsed a coalesced packet. Part %d: %d bytes. Remaining: %d bytes.\", counter, len(packetData), len(rest))\n\t\t\t}\n\n\t\t\tp.data = packetData\n\n\t\t\tprocessed, err := s.handleLongHeaderPacket(p, hdr)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif processed {\n\t\t\t\twasProcessed = true\n\t\t\t}\n\t\t\tdata = rest\n\t\t} else {\n\t\t\tif counter > 0 {\n\t\t\t\tp.buffer.Split()\n\t\t\t}\n\t\t\tprocessed, err := s.handleShortHeaderPacket(p, counter > 0)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif processed {\n\t\t\t\twasProcessed = true\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\n\tp.buffer.MaybeRelease()\n\treturn wasProcessed, nil\n}\n\nfunc (s *connection) handleShortHeaderPacket(p receivedPacket, isCoalesced bool) (wasProcessed bool, _ error) {\n\tvar wasQueued bool\n\n\tdefer func() {\n\t\t// Put back the packet buffer if the packet wasn't queued for later decryption.\n\t\tif !wasQueued {\n\t\t\tp.buffer.Decrement()\n\t\t}\n\t}()\n\n\tdestConnID, err := wire.ParseConnectionID(p.data, s.srcConnIDLen)\n\tif err != nil {\n\t\ts.tracer.DroppedPacket(logging.PacketType1RTT, protocol.InvalidPacketNumber, protocol.ByteCount(len(p.data)), logging.PacketDropHeaderParseError)\n\t\treturn false, nil\n\t}\n\tpn, pnLen, keyPhase, data, err := s.unpacker.UnpackShortHeader(p.rcvTime, p.data)\n\tif err != nil {\n\t\t// Stateless reset packets (see RFC 9000, section 10.3):\n\t\t// * fill the entire UDP datagram (i.e. they cannot be part of a coalesced packet)\n\t\t// * are short header packets (first bit is 0)\n\t\t// * have the QUIC bit set (second bit is 1)\n\t\t// * are at least 21 bytes long\n\t\tif !isCoalesced && len(p.data) >= protocol.MinReceivedStatelessResetSize && p.data[0]&0b11000000 == 0b01000000 {\n\t\t\ttoken := protocol.StatelessResetToken(p.data[len(p.data)-16:])\n\t\t\tif s.connIDManager.IsActiveStatelessResetToken(token) {\n\t\t\t\treturn false, &StatelessResetError{}\n\t\t\t}\n\t\t}\n\t\twasQueued, err = s.handleUnpackError(err, p, logging.PacketType1RTT)\n\t\treturn false, err\n\t}\n\ts.largestRcvdAppData = max(s.largestRcvdAppData, pn)\n\n\tif s.logger.Debug() {\n\t\ts.logger.Debugf(\"<- Reading packet %d (%d bytes) for connection %s, 1-RTT\", pn, p.Size(), destConnID)\n\t\twire.LogShortHeader(s.logger, destConnID, pn, pnLen, keyPhase)\n\t}\n\n\tif s.receivedPacketHandler.IsPotentiallyDuplicate(pn, protocol.Encryption1RTT) {\n\t\ts.logger.Debugf(\"Dropping (potentially) duplicate packet.\")\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(logging.PacketType1RTT, pn, p.Size(), logging.PacketDropDuplicate)\n\t\t}\n\t\treturn false, nil\n\t}\n\n\tvar log func([]logging.Frame)\n\tif s.tracer != nil && s.tracer.ReceivedShortHeaderPacket != nil {\n\t\tlog = func(frames []logging.Frame) {\n\t\t\ts.tracer.ReceivedShortHeaderPacket(\n\t\t\t\t&logging.ShortHeader{\n\t\t\t\t\tDestConnectionID: destConnID,\n\t\t\t\t\tPacketNumber:     pn,\n\t\t\t\t\tPacketNumberLen:  pnLen,\n\t\t\t\t\tKeyPhase:         keyPhase,\n\t\t\t\t},\n\t\t\t\tp.Size(),\n\t\t\t\tp.ecn,\n\t\t\t\tframes,\n\t\t\t)\n\t\t}\n\t}\n\tisNonProbing, pathChallenge, err := s.handleUnpackedShortHeaderPacket(destConnID, pn, data, p.ecn, p.rcvTime, log)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\t// In RFC 9000, only the client can migrate between paths.\n\tif s.perspective == protocol.PerspectiveClient {\n\t\treturn true, nil\n\t}\n\tif addrsEqual(p.remoteAddr, s.RemoteAddr()) {\n\t\treturn true, nil\n\t}\n\n\tvar shouldSwitchPath bool\n\tif s.pathManager == nil {\n\t\ts.pathManager = newPathManager(\n\t\t\ts.connIDManager.GetConnIDForPath,\n\t\t\ts.connIDManager.RetireConnIDForPath,\n\t\t\ts.logger,\n\t\t)\n\t}\n\tdestConnID, frames, shouldSwitchPath := s.pathManager.HandlePacket(p.remoteAddr, p.rcvTime, pathChallenge, isNonProbing)\n\tif len(frames) > 0 {\n\t\tprobe, buf, err := s.packer.PackPathProbePacket(destConnID, frames, s.version)\n\t\tif err != nil {\n\t\t\treturn true, err\n\t\t}\n\t\ts.logger.Debugf(\"sending path probe packet to %s\", p.remoteAddr)\n\t\ts.logShortHeaderPacket(probe.DestConnID, probe.Ack, probe.Frames, probe.StreamFrames, probe.PacketNumber, probe.PacketNumberLen, probe.KeyPhase, protocol.ECNNon, buf.Len(), false)\n\t\ts.registerPackedShortHeaderPacket(probe, protocol.ECNNon, p.rcvTime)\n\t\ts.sendQueue.SendProbe(buf, p.remoteAddr)\n\t}\n\t// We only switch paths in response to the highest-numbered non-probing packet,\n\t// see section 9.3 of RFC 9000.\n\tif !shouldSwitchPath || pn != s.largestRcvdAppData {\n\t\treturn true, nil\n\t}\n\ts.pathManager.SwitchToPath(p.remoteAddr)\n\ts.sentPacketHandler.MigratedPath(p.rcvTime, protocol.ByteCount(s.config.InitialPacketSize))\n\tmaxPacketSize := protocol.ByteCount(protocol.MaxPacketBufferSize)\n\tif s.peerParams.MaxUDPPayloadSize > 0 && s.peerParams.MaxUDPPayloadSize < maxPacketSize {\n\t\tmaxPacketSize = s.peerParams.MaxUDPPayloadSize\n\t}\n\ts.mtuDiscoverer.Reset(\n\t\tp.rcvTime,\n\t\tprotocol.ByteCount(s.config.InitialPacketSize),\n\t\tmaxPacketSize,\n\t)\n\ts.conn.ChangeRemoteAddr(p.remoteAddr, p.info)\n\treturn true, nil\n}\n\nfunc (s *connection) handleLongHeaderPacket(p receivedPacket, hdr *wire.Header) (wasProcessed bool, _ error) {\n\tvar wasQueued bool\n\n\tdefer func() {\n\t\t// Put back the packet buffer if the packet wasn't queued for later decryption.\n\t\tif !wasQueued {\n\t\t\tp.buffer.Decrement()\n\t\t}\n\t}()\n\n\tif hdr.Type == protocol.PacketTypeRetry {\n\t\treturn s.handleRetryPacket(hdr, p.data, p.rcvTime), nil\n\t}\n\n\t// The server can change the source connection ID with the first Handshake packet.\n\t// After this, all packets with a different source connection have to be ignored.\n\tif s.receivedFirstPacket && hdr.Type == protocol.PacketTypeInitial && hdr.SrcConnectionID != s.handshakeDestConnID {\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(logging.PacketTypeInitial, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnknownConnectionID)\n\t\t}\n\t\ts.logger.Debugf(\"Dropping Initial packet (%d bytes) with unexpected source connection ID: %s (expected %s)\", p.Size(), hdr.SrcConnectionID, s.handshakeDestConnID)\n\t\treturn false, nil\n\t}\n\t// drop 0-RTT packets, if we are a client\n\tif s.perspective == protocol.PerspectiveClient && hdr.Type == protocol.PacketType0RTT {\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(logging.PacketType0RTT, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedPacket)\n\t\t}\n\t\treturn false, nil\n\t}\n\n\tpacket, err := s.unpacker.UnpackLongHeader(hdr, p.data)\n\tif err != nil {\n\t\twasQueued, err = s.handleUnpackError(err, p, logging.PacketTypeFromHeader(hdr))\n\t\treturn false, err\n\t}\n\n\tif s.logger.Debug() {\n\t\ts.logger.Debugf(\"<- Reading packet %d (%d bytes) for connection %s, %s\", packet.hdr.PacketNumber, p.Size(), hdr.DestConnectionID, packet.encryptionLevel)\n\t\tpacket.hdr.Log(s.logger)\n\t}\n\n\tif pn := packet.hdr.PacketNumber; s.receivedPacketHandler.IsPotentiallyDuplicate(pn, packet.encryptionLevel) {\n\t\ts.logger.Debugf(\"Dropping (potentially) duplicate packet.\")\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), pn, p.Size(), logging.PacketDropDuplicate)\n\t\t}\n\t\treturn false, nil\n\t}\n\n\tif err := s.handleUnpackedLongHeaderPacket(packet, p.ecn, p.rcvTime, p.Size()); err != nil {\n\t\treturn false, err\n\t}\n\treturn true, nil\n}\n\nfunc (s *connection) handleUnpackError(err error, p receivedPacket, pt logging.PacketType) (wasQueued bool, _ error) {\n\tswitch err {\n\tcase handshake.ErrKeysDropped:\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(pt, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropKeyUnavailable)\n\t\t}\n\t\ts.logger.Debugf(\"Dropping %s packet (%d bytes) because we already dropped the keys.\", pt, p.Size())\n\t\treturn false, nil\n\tcase handshake.ErrKeysNotYetAvailable:\n\t\t// Sealer for this encryption level not yet available.\n\t\t// Try again later.\n\t\ts.tryQueueingUndecryptablePacket(p, pt)\n\t\treturn true, nil\n\tcase wire.ErrInvalidReservedBits:\n\t\treturn false, &qerr.TransportError{\n\t\t\tErrorCode:    qerr.ProtocolViolation,\n\t\t\tErrorMessage: err.Error(),\n\t\t}\n\tcase handshake.ErrDecryptionFailed:\n\t\t// This might be a packet injected by an attacker. Drop it.\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(pt, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropPayloadDecryptError)\n\t\t}\n\t\ts.logger.Debugf(\"Dropping %s packet (%d bytes) that could not be unpacked. Error: %s\", pt, p.Size(), err)\n\t\treturn false, nil\n\tdefault:\n\t\tvar headerErr *headerParseError\n\t\tif errors.As(err, &headerErr) {\n\t\t\t// This might be a packet injected by an attacker. Drop it.\n\t\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\t\ts.tracer.DroppedPacket(pt, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropHeaderParseError)\n\t\t\t}\n\t\t\ts.logger.Debugf(\"Dropping %s packet (%d bytes) for which we couldn't unpack the header. Error: %s\", pt, p.Size(), err)\n\t\t\treturn false, nil\n\t\t}\n\t\t// This is an error returned by the AEAD (other than ErrDecryptionFailed).\n\t\t// For example, a PROTOCOL_VIOLATION due to key updates.\n\t\treturn false, err\n\t}\n}\n\nfunc (s *connection) handleRetryPacket(hdr *wire.Header, data []byte, rcvTime time.Time) bool /* was this a valid Retry */ {\n\tif s.perspective == protocol.PerspectiveServer {\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket)\n\t\t}\n\t\ts.logger.Debugf(\"Ignoring Retry.\")\n\t\treturn false\n\t}\n\tif s.receivedFirstPacket {\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket)\n\t\t}\n\t\ts.logger.Debugf(\"Ignoring Retry, since we already received a packet.\")\n\t\treturn false\n\t}\n\tdestConnID := s.connIDManager.Get()\n\tif hdr.SrcConnectionID == destConnID {\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket)\n\t\t}\n\t\ts.logger.Debugf(\"Ignoring Retry, since the server didn't change the Source Connection ID.\")\n\t\treturn false\n\t}\n\t// If a token is already set, this means that we already received a Retry from the server.\n\t// Ignore this Retry packet.\n\tif s.receivedRetry {\n\t\ts.logger.Debugf(\"Ignoring Retry, since a Retry was already received.\")\n\t\treturn false\n\t}\n\n\ttag := handshake.GetRetryIntegrityTag(data[:len(data)-16], destConnID, hdr.Version)\n\tif !bytes.Equal(data[len(data)-16:], tag[:]) {\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropPayloadDecryptError)\n\t\t}\n\t\ts.logger.Debugf(\"Ignoring spoofed Retry. Integrity Tag doesn't match.\")\n\t\treturn false\n\t}\n\n\tnewDestConnID := hdr.SrcConnectionID\n\ts.receivedRetry = true\n\ts.sentPacketHandler.ResetForRetry(rcvTime)\n\ts.handshakeDestConnID = newDestConnID\n\ts.retrySrcConnID = &newDestConnID\n\ts.cryptoStreamHandler.ChangeConnectionID(newDestConnID)\n\ts.packer.SetToken(hdr.Token)\n\ts.connIDManager.ChangeInitialConnID(newDestConnID)\n\n\tif s.logger.Debug() {\n\t\ts.logger.Debugf(\"<- Received Retry:\")\n\t\t(&wire.ExtendedHeader{Header: *hdr}).Log(s.logger)\n\t\ts.logger.Debugf(\"Switching destination connection ID to: %s\", hdr.SrcConnectionID)\n\t}\n\tif s.tracer != nil && s.tracer.ReceivedRetry != nil {\n\t\ts.tracer.ReceivedRetry(hdr)\n\t}\n\n\ts.scheduleSending()\n\treturn true\n}\n\nfunc (s *connection) handleVersionNegotiationPacket(p receivedPacket) {\n\tif s.perspective == protocol.PerspectiveServer || // servers never receive version negotiation packets\n\t\ts.receivedFirstPacket || s.versionNegotiated { // ignore delayed / duplicated version negotiation packets\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedPacket)\n\t\t}\n\t\treturn\n\t}\n\n\tsrc, dest, supportedVersions, err := wire.ParseVersionNegotiationPacket(p.data)\n\tif err != nil {\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropHeaderParseError)\n\t\t}\n\t\ts.logger.Debugf(\"Error parsing Version Negotiation packet: %s\", err)\n\t\treturn\n\t}\n\n\tfor _, v := range supportedVersions {\n\t\tif v == s.version {\n\t\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\t\ts.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedVersion)\n\t\t\t}\n\t\t\t// The Version Negotiation packet contains the version that we offered.\n\t\t\t// This might be a packet sent by an attacker, or it was corrupted.\n\t\t\treturn\n\t\t}\n\t}\n\n\ts.logger.Infof(\"Received a Version Negotiation packet. Supported Versions: %s\", supportedVersions)\n\tif s.tracer != nil && s.tracer.ReceivedVersionNegotiationPacket != nil {\n\t\ts.tracer.ReceivedVersionNegotiationPacket(dest, src, supportedVersions)\n\t}\n\tnewVersion, ok := protocol.ChooseSupportedVersion(s.config.Versions, supportedVersions)\n\tif !ok {\n\t\ts.destroyImpl(&VersionNegotiationError{\n\t\t\tOurs:   s.config.Versions,\n\t\t\tTheirs: supportedVersions,\n\t\t})\n\t\ts.logger.Infof(\"No compatible QUIC version found.\")\n\t\treturn\n\t}\n\tif s.tracer != nil && s.tracer.NegotiatedVersion != nil {\n\t\ts.tracer.NegotiatedVersion(newVersion, s.config.Versions, supportedVersions)\n\t}\n\n\ts.logger.Infof(\"Switching to QUIC version %s.\", newVersion)\n\tnextPN, _ := s.sentPacketHandler.PeekPacketNumber(protocol.EncryptionInitial)\n\ts.destroyImpl(&errCloseForRecreating{\n\t\tnextPacketNumber: nextPN,\n\t\tnextVersion:      newVersion,\n\t})\n}\n\nfunc (s *connection) handleUnpackedLongHeaderPacket(\n\tpacket *unpackedPacket,\n\tecn protocol.ECN,\n\trcvTime time.Time,\n\tpacketSize protocol.ByteCount, // only for logging\n) error {\n\tif !s.receivedFirstPacket {\n\t\ts.receivedFirstPacket = true\n\t\tif !s.versionNegotiated && s.tracer != nil && s.tracer.NegotiatedVersion != nil {\n\t\t\tvar clientVersions, serverVersions []protocol.Version\n\t\t\tswitch s.perspective {\n\t\t\tcase protocol.PerspectiveClient:\n\t\t\t\tclientVersions = s.config.Versions\n\t\t\tcase protocol.PerspectiveServer:\n\t\t\t\tserverVersions = s.config.Versions\n\t\t\t}\n\t\t\ts.tracer.NegotiatedVersion(s.version, clientVersions, serverVersions)\n\t\t}\n\t\t// The server can change the source connection ID with the first Handshake packet.\n\t\tif s.perspective == protocol.PerspectiveClient && packet.hdr.SrcConnectionID != s.handshakeDestConnID {\n\t\t\tcid := packet.hdr.SrcConnectionID\n\t\t\ts.logger.Debugf(\"Received first packet. Switching destination connection ID to: %s\", cid)\n\t\t\ts.handshakeDestConnID = cid\n\t\t\ts.connIDManager.ChangeInitialConnID(cid)\n\t\t}\n\t\t// We create the connection as soon as we receive the first packet from the client.\n\t\t// We do that before authenticating the packet.\n\t\t// That means that if the source connection ID was corrupted,\n\t\t// we might have created a connection with an incorrect source connection ID.\n\t\t// Once we authenticate the first packet, we need to update it.\n\t\tif s.perspective == protocol.PerspectiveServer {\n\t\t\tif packet.hdr.SrcConnectionID != s.handshakeDestConnID {\n\t\t\t\ts.handshakeDestConnID = packet.hdr.SrcConnectionID\n\t\t\t\ts.connIDManager.ChangeInitialConnID(packet.hdr.SrcConnectionID)\n\t\t\t}\n\t\t\tif s.tracer != nil && s.tracer.StartedConnection != nil {\n\t\t\t\ts.tracer.StartedConnection(\n\t\t\t\t\ts.conn.LocalAddr(),\n\t\t\t\t\ts.conn.RemoteAddr(),\n\t\t\t\t\tpacket.hdr.SrcConnectionID,\n\t\t\t\t\tpacket.hdr.DestConnectionID,\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n\n\tif s.perspective == protocol.PerspectiveServer && packet.encryptionLevel == protocol.EncryptionHandshake &&\n\t\t!s.droppedInitialKeys {\n\t\t// On the server side, Initial keys are dropped as soon as the first Handshake packet is received.\n\t\t// See Section 4.9.1 of RFC 9001.\n\t\tif err := s.dropEncryptionLevel(protocol.EncryptionInitial, rcvTime); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\ts.lastPacketReceivedTime = rcvTime\n\ts.firstAckElicitingPacketAfterIdleSentTime = time.Time{}\n\ts.keepAlivePingSent = false\n\n\tif packet.hdr.Type == protocol.PacketType0RTT {\n\t\ts.largestRcvdAppData = max(s.largestRcvdAppData, packet.hdr.PacketNumber)\n\t}\n\n\tvar log func([]logging.Frame)\n\tif s.tracer != nil && s.tracer.ReceivedLongHeaderPacket != nil {\n\t\tlog = func(frames []logging.Frame) {\n\t\t\ts.tracer.ReceivedLongHeaderPacket(packet.hdr, packetSize, ecn, frames)\n\t\t}\n\t}\n\tisAckEliciting, _, _, err := s.handleFrames(packet.data, packet.hdr.DestConnectionID, packet.encryptionLevel, log, rcvTime)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn s.receivedPacketHandler.ReceivedPacket(packet.hdr.PacketNumber, ecn, packet.encryptionLevel, rcvTime, isAckEliciting)\n}\n\nfunc (s *connection) handleUnpackedShortHeaderPacket(\n\tdestConnID protocol.ConnectionID,\n\tpn protocol.PacketNumber,\n\tdata []byte,\n\tecn protocol.ECN,\n\trcvTime time.Time,\n\tlog func([]logging.Frame),\n) (isNonProbing bool, pathChallenge *wire.PathChallengeFrame, _ error) {\n\ts.lastPacketReceivedTime = rcvTime\n\ts.firstAckElicitingPacketAfterIdleSentTime = time.Time{}\n\ts.keepAlivePingSent = false\n\n\tisAckEliciting, isNonProbing, pathChallenge, err := s.handleFrames(data, destConnID, protocol.Encryption1RTT, log, rcvTime)\n\tif err != nil {\n\t\treturn false, nil, err\n\t}\n\tif err := s.receivedPacketHandler.ReceivedPacket(pn, ecn, protocol.Encryption1RTT, rcvTime, isAckEliciting); err != nil {\n\t\treturn false, nil, err\n\t}\n\treturn isNonProbing, pathChallenge, nil\n}\n\n// handleFrames parses the frames, one after the other, and handles them.\n// It returns the last PATH_CHALLENGE frame contained in the packet, if any.\nfunc (s *connection) handleFrames(\n\tdata []byte,\n\tdestConnID protocol.ConnectionID,\n\tencLevel protocol.EncryptionLevel,\n\tlog func([]logging.Frame),\n\trcvTime time.Time,\n) (isAckEliciting, isNonProbing bool, pathChallenge *wire.PathChallengeFrame, _ error) {\n\t// Only used for tracing.\n\t// If we're not tracing, this slice will always remain empty.\n\tvar frames []logging.Frame\n\tif log != nil {\n\t\tframes = make([]logging.Frame, 0, 4)\n\t}\n\thandshakeWasComplete := s.handshakeComplete\n\tvar handleErr error\n\tfor len(data) > 0 {\n\t\tl, frame, err := s.frameParser.ParseNext(data, encLevel, s.version)\n\t\tif err != nil {\n\t\t\treturn false, false, nil, err\n\t\t}\n\t\tdata = data[l:]\n\t\tif frame == nil {\n\t\t\tbreak\n\t\t}\n\t\tif ackhandler.IsFrameAckEliciting(frame) {\n\t\t\tisAckEliciting = true\n\t\t}\n\t\tif !wire.IsProbingFrame(frame) {\n\t\t\tisNonProbing = true\n\t\t}\n\t\tif log != nil {\n\t\t\tframes = append(frames, toLoggingFrame(frame))\n\t\t}\n\t\t// An error occurred handling a previous frame.\n\t\t// Don't handle the current frame.\n\t\tif handleErr != nil {\n\t\t\tcontinue\n\t\t}\n\t\tpc, err := s.handleFrame(frame, encLevel, destConnID, rcvTime)\n\t\tif err != nil {\n\t\t\tif log == nil {\n\t\t\t\treturn false, false, nil, err\n\t\t\t}\n\t\t\t// If we're logging, we need to keep parsing (but not handling) all frames.\n\t\t\thandleErr = err\n\t\t}\n\t\tif pc != nil {\n\t\t\tpathChallenge = pc\n\t\t}\n\t}\n\n\tif log != nil {\n\t\tlog(frames)\n\t\tif handleErr != nil {\n\t\t\treturn false, false, nil, handleErr\n\t\t}\n\t}\n\n\t// Handle completion of the handshake after processing all the frames.\n\t// This ensures that we correctly handle the following case on the server side:\n\t// We receive a Handshake packet that contains the CRYPTO frame that allows us to complete the handshake,\n\t// and an ACK serialized after that CRYPTO frame. In this case, we still want to process the ACK frame.\n\tif !handshakeWasComplete && s.handshakeComplete {\n\t\tif err := s.handleHandshakeComplete(rcvTime); err != nil {\n\t\t\treturn false, false, nil, err\n\t\t}\n\t}\n\treturn\n}\n\nfunc (s *connection) handleFrame(\n\tf wire.Frame,\n\tencLevel protocol.EncryptionLevel,\n\tdestConnID protocol.ConnectionID,\n\trcvTime time.Time,\n) (pathChallenge *wire.PathChallengeFrame, _ error) {\n\tvar err error\n\twire.LogFrame(s.logger, f, false)\n\tswitch frame := f.(type) {\n\tcase *wire.CryptoFrame:\n\t\terr = s.handleCryptoFrame(frame, encLevel, rcvTime)\n\tcase *wire.StreamFrame:\n\t\terr = s.handleStreamFrame(frame, rcvTime)\n\tcase *wire.AckFrame:\n\t\terr = s.handleAckFrame(frame, encLevel, rcvTime)\n\tcase *wire.ConnectionCloseFrame:\n\t\terr = s.handleConnectionCloseFrame(frame)\n\tcase *wire.ResetStreamFrame:\n\t\terr = s.handleResetStreamFrame(frame, rcvTime)\n\tcase *wire.MaxDataFrame:\n\t\ts.handleMaxDataFrame(frame)\n\tcase *wire.MaxStreamDataFrame:\n\t\terr = s.handleMaxStreamDataFrame(frame)\n\tcase *wire.MaxStreamsFrame:\n\t\ts.handleMaxStreamsFrame(frame)\n\tcase *wire.DataBlockedFrame:\n\tcase *wire.StreamDataBlockedFrame:\n\t\terr = s.handleStreamDataBlockedFrame(frame)\n\tcase *wire.StreamsBlockedFrame:\n\tcase *wire.StopSendingFrame:\n\t\terr = s.handleStopSendingFrame(frame)\n\tcase *wire.PingFrame:\n\tcase *wire.PathChallengeFrame:\n\t\ts.handlePathChallengeFrame(frame)\n\t\tpathChallenge = frame\n\tcase *wire.PathResponseFrame:\n\t\terr = s.handlePathResponseFrame(frame)\n\tcase *wire.NewTokenFrame:\n\t\terr = s.handleNewTokenFrame(frame)\n\tcase *wire.NewConnectionIDFrame:\n\t\terr = s.handleNewConnectionIDFrame(frame)\n\tcase *wire.RetireConnectionIDFrame:\n\t\terr = s.handleRetireConnectionIDFrame(frame, destConnID)\n\tcase *wire.HandshakeDoneFrame:\n\t\terr = s.handleHandshakeDoneFrame(rcvTime)\n\tcase *wire.DatagramFrame:\n\t\terr = s.handleDatagramFrame(frame)\n\tdefault:\n\t\terr = fmt.Errorf(\"unexpected frame type: %s\", reflect.ValueOf(&frame).Elem().Type().Name())\n\t}\n\treturn pathChallenge, err\n}\n\n// handlePacket is called by the server with a new packet\nfunc (s *connection) handlePacket(p receivedPacket) {\n\ts.receivedPacketMx.Lock()\n\t// Discard packets once the amount of queued packets is larger than\n\t// the channel size, protocol.MaxConnUnprocessedPackets\n\tif s.receivedPackets.Len() >= protocol.MaxConnUnprocessedPackets {\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropDOSPrevention)\n\t\t}\n\t\ts.receivedPacketMx.Unlock()\n\t\treturn\n\t}\n\ts.receivedPackets.PushBack(p)\n\ts.receivedPacketMx.Unlock()\n\n\tselect {\n\tcase s.notifyReceivedPacket <- struct{}{}:\n\tdefault:\n\t}\n}\n\nfunc (s *connection) handleConnectionCloseFrame(frame *wire.ConnectionCloseFrame) error {\n\tif frame.IsApplicationError {\n\t\treturn &qerr.ApplicationError{\n\t\t\tRemote:       true,\n\t\t\tErrorCode:    qerr.ApplicationErrorCode(frame.ErrorCode),\n\t\t\tErrorMessage: frame.ReasonPhrase,\n\t\t}\n\t}\n\treturn &qerr.TransportError{\n\t\tRemote:       true,\n\t\tErrorCode:    qerr.TransportErrorCode(frame.ErrorCode),\n\t\tFrameType:    frame.FrameType,\n\t\tErrorMessage: frame.ReasonPhrase,\n\t}\n}\n\nfunc (s *connection) handleCryptoFrame(frame *wire.CryptoFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) error {\n\tif err := s.cryptoStreamManager.HandleCryptoFrame(frame, encLevel); err != nil {\n\t\treturn err\n\t}\n\tfor {\n\t\tdata := s.cryptoStreamManager.GetCryptoData(encLevel)\n\t\tif data == nil {\n\t\t\tbreak\n\t\t}\n\t\tif err := s.cryptoStreamHandler.HandleMessage(data, encLevel); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn s.handleHandshakeEvents(rcvTime)\n}\n\nfunc (s *connection) handleHandshakeEvents(now time.Time) error {\n\tfor {\n\t\tev := s.cryptoStreamHandler.NextEvent()\n\t\tvar err error\n\t\tswitch ev.Kind {\n\t\tcase handshake.EventNoEvent:\n\t\t\treturn nil\n\t\tcase handshake.EventHandshakeComplete:\n\t\t\t// Don't call handleHandshakeComplete yet.\n\t\t\t// It's advantageous to process ACK frames that might be serialized after the CRYPTO frame first.\n\t\t\ts.handshakeComplete = true\n\t\tcase handshake.EventReceivedTransportParameters:\n\t\t\terr = s.handleTransportParameters(ev.TransportParameters)\n\t\tcase handshake.EventRestoredTransportParameters:\n\t\t\ts.restoreTransportParameters(ev.TransportParameters)\n\t\t\tclose(s.earlyConnReadyChan)\n\t\tcase handshake.EventReceivedReadKeys:\n\t\t\t// queue all previously undecryptable packets\n\t\t\ts.undecryptablePacketsToProcess = append(s.undecryptablePacketsToProcess, s.undecryptablePackets...)\n\t\t\ts.undecryptablePackets = nil\n\t\tcase handshake.EventDiscard0RTTKeys:\n\t\t\terr = s.dropEncryptionLevel(protocol.Encryption0RTT, now)\n\t\tcase handshake.EventWriteInitialData:\n\t\t\t_, err = s.initialStream.Write(ev.Data)\n\t\tcase handshake.EventWriteHandshakeData:\n\t\t\t_, err = s.handshakeStream.Write(ev.Data)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n}\n\nfunc (s *connection) handleStreamFrame(frame *wire.StreamFrame, rcvTime time.Time) error {\n\tstr, err := s.streamsMap.GetOrOpenReceiveStream(frame.StreamID)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif str == nil { // stream was already closed and garbage collected\n\t\treturn nil\n\t}\n\treturn str.handleStreamFrame(frame, rcvTime)\n}\n\nfunc (s *connection) handleMaxDataFrame(frame *wire.MaxDataFrame) {\n\ts.connFlowController.UpdateSendWindow(frame.MaximumData)\n}\n\nfunc (s *connection) handleMaxStreamDataFrame(frame *wire.MaxStreamDataFrame) error {\n\tstr, err := s.streamsMap.GetOrOpenSendStream(frame.StreamID)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif str == nil {\n\t\t// stream is closed and already garbage collected\n\t\treturn nil\n\t}\n\tstr.updateSendWindow(frame.MaximumStreamData)\n\treturn nil\n}\n\nfunc (s *connection) handleStreamDataBlockedFrame(frame *wire.StreamDataBlockedFrame) error {\n\t// We don't need to do anything in response to a STREAM_DATA_BLOCKED frame,\n\t// but we need to make sure that the stream ID is valid.\n\t_, err := s.streamsMap.GetOrOpenReceiveStream(frame.StreamID)\n\treturn err\n}\n\nfunc (s *connection) handleMaxStreamsFrame(frame *wire.MaxStreamsFrame) {\n\ts.streamsMap.HandleMaxStreamsFrame(frame)\n}\n\nfunc (s *connection) handleResetStreamFrame(frame *wire.ResetStreamFrame, rcvTime time.Time) error {\n\tstr, err := s.streamsMap.GetOrOpenReceiveStream(frame.StreamID)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif str == nil {\n\t\t// stream is closed and already garbage collected\n\t\treturn nil\n\t}\n\treturn str.handleResetStreamFrame(frame, rcvTime)\n}\n\nfunc (s *connection) handleStopSendingFrame(frame *wire.StopSendingFrame) error {\n\tstr, err := s.streamsMap.GetOrOpenSendStream(frame.StreamID)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif str == nil {\n\t\t// stream is closed and already garbage collected\n\t\treturn nil\n\t}\n\tstr.handleStopSendingFrame(frame)\n\treturn nil\n}\n\nfunc (s *connection) handlePathChallengeFrame(f *wire.PathChallengeFrame) {\n\tif s.perspective == protocol.PerspectiveClient {\n\t\ts.queueControlFrame(&wire.PathResponseFrame{Data: f.Data})\n\t}\n}\n\nfunc (s *connection) handlePathResponseFrame(f *wire.PathResponseFrame) error {\n\tswitch s.perspective {\n\tcase protocol.PerspectiveClient:\n\t\treturn s.handlePathResponseFrameClient(f)\n\tcase protocol.PerspectiveServer:\n\t\treturn s.handlePathResponseFrameServer(f)\n\tdefault:\n\t\tpanic(\"unreachable\")\n\t}\n}\n\nfunc (s *connection) handlePathResponseFrameClient(f *wire.PathResponseFrame) error {\n\tpm := s.pathManagerOutgoing.Load()\n\tif pm == nil {\n\t\treturn &qerr.TransportError{\n\t\t\tErrorCode:    qerr.ProtocolViolation,\n\t\t\tErrorMessage: \"unexpected PATH_RESPONSE frame\",\n\t\t}\n\t}\n\tpm.HandlePathResponseFrame(f)\n\treturn nil\n}\n\nfunc (s *connection) handlePathResponseFrameServer(f *wire.PathResponseFrame) error {\n\tif s.pathManager == nil {\n\t\t// since we didn't send PATH_CHALLENGEs yet, we don't expect PATH_RESPONSEs\n\t\treturn &qerr.TransportError{\n\t\t\tErrorCode:    qerr.ProtocolViolation,\n\t\t\tErrorMessage: \"unexpected PATH_RESPONSE frame\",\n\t\t}\n\t}\n\ts.pathManager.HandlePathResponseFrame(f)\n\treturn nil\n}\n\nfunc (s *connection) handleNewTokenFrame(frame *wire.NewTokenFrame) error {\n\tif s.perspective == protocol.PerspectiveServer {\n\t\treturn &qerr.TransportError{\n\t\t\tErrorCode:    qerr.ProtocolViolation,\n\t\t\tErrorMessage: \"received NEW_TOKEN frame from the client\",\n\t\t}\n\t}\n\tif s.config.TokenStore != nil {\n\t\ts.config.TokenStore.Put(s.tokenStoreKey, &ClientToken{data: frame.Token})\n\t}\n\treturn nil\n}\n\nfunc (s *connection) handleNewConnectionIDFrame(f *wire.NewConnectionIDFrame) error {\n\treturn s.connIDManager.Add(f)\n}\n\nfunc (s *connection) handleRetireConnectionIDFrame(f *wire.RetireConnectionIDFrame, destConnID protocol.ConnectionID) error {\n\treturn s.connIDGenerator.Retire(f.SequenceNumber, destConnID)\n}\n\nfunc (s *connection) handleHandshakeDoneFrame(rcvTime time.Time) error {\n\tif s.perspective == protocol.PerspectiveServer {\n\t\treturn &qerr.TransportError{\n\t\t\tErrorCode:    qerr.ProtocolViolation,\n\t\t\tErrorMessage: \"received a HANDSHAKE_DONE frame\",\n\t\t}\n\t}\n\tif !s.handshakeConfirmed {\n\t\treturn s.handleHandshakeConfirmed(rcvTime)\n\t}\n\treturn nil\n}\n\nfunc (s *connection) handleAckFrame(frame *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) error {\n\tacked1RTTPacket, err := s.sentPacketHandler.ReceivedAck(frame, encLevel, s.lastPacketReceivedTime)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !acked1RTTPacket {\n\t\treturn nil\n\t}\n\t// On the client side: If the packet acknowledged a 1-RTT packet, this confirms the handshake.\n\t// This is only possible if the ACK was sent in a 1-RTT packet.\n\t// This is an optimization over simply waiting for a HANDSHAKE_DONE frame, see section 4.1.2 of RFC 9001.\n\tif s.perspective == protocol.PerspectiveClient && !s.handshakeConfirmed {\n\t\tif err := s.handleHandshakeConfirmed(rcvTime); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t// If one of the acknowledged packets was a Path MTU probe packet, this might have increased the Path MTU estimate.\n\tif s.mtuDiscoverer != nil {\n\t\tif mtu := s.mtuDiscoverer.CurrentSize(); mtu > protocol.ByteCount(s.currentMTUEstimate.Load()) {\n\t\t\ts.currentMTUEstimate.Store(uint32(mtu))\n\t\t\ts.sentPacketHandler.SetMaxDatagramSize(mtu)\n\t\t}\n\t}\n\treturn s.cryptoStreamHandler.SetLargest1RTTAcked(frame.LargestAcked())\n}\n\nfunc (s *connection) handleDatagramFrame(f *wire.DatagramFrame) error {\n\tif f.Length(s.version) > wire.MaxDatagramSize {\n\t\treturn &qerr.TransportError{\n\t\t\tErrorCode:    qerr.ProtocolViolation,\n\t\t\tErrorMessage: \"DATAGRAM frame too large\",\n\t\t}\n\t}\n\ts.datagramQueue.HandleDatagramFrame(f)\n\treturn nil\n}\n\nfunc (s *connection) setCloseError(e *closeError) {\n\ts.closeErr.CompareAndSwap(nil, e)\n\tselect {\n\tcase s.closeChan <- struct{}{}:\n\tdefault:\n\t}\n}\n\n// closeLocal closes the connection and send a CONNECTION_CLOSE containing the error\nfunc (s *connection) closeLocal(e error) {\n\ts.setCloseError(&closeError{err: e, immediate: false})\n}\n\n// destroy closes the connection without sending the error on the wire\nfunc (s *connection) destroy(e error) {\n\ts.destroyImpl(e)\n\t<-s.ctx.Done()\n}\n\nfunc (s *connection) destroyImpl(e error) {\n\ts.setCloseError(&closeError{err: e, immediate: true})\n}\n\nfunc (s *connection) CloseWithError(code ApplicationErrorCode, desc string) error {\n\ts.closeLocal(&qerr.ApplicationError{\n\t\tErrorCode:    code,\n\t\tErrorMessage: desc,\n\t})\n\t<-s.ctx.Done()\n\treturn nil\n}\n\nfunc (s *connection) closeWithTransportError(code TransportErrorCode) {\n\ts.closeLocal(&qerr.TransportError{ErrorCode: code})\n\t<-s.ctx.Done()\n}\n\nfunc (s *connection) handleCloseError(closeErr *closeError) {\n\tif closeErr.immediate {\n\t\tif nerr, ok := closeErr.err.(net.Error); ok && nerr.Timeout() {\n\t\t\ts.logger.Errorf(\"Destroying connection: %s\", closeErr.err)\n\t\t} else {\n\t\t\ts.logger.Errorf(\"Destroying connection with error: %s\", closeErr.err)\n\t\t}\n\t} else {\n\t\tif closeErr.err == nil {\n\t\t\ts.logger.Infof(\"Closing connection.\")\n\t\t} else {\n\t\t\ts.logger.Errorf(\"Closing connection with error: %s\", closeErr.err)\n\t\t}\n\t}\n\n\te := closeErr.err\n\tif e == nil {\n\t\te = &qerr.ApplicationError{}\n\t} else {\n\t\tdefer func() { closeErr.err = e }()\n\t}\n\n\tvar (\n\t\tstatelessResetErr     *StatelessResetError\n\t\tversionNegotiationErr *VersionNegotiationError\n\t\trecreateErr           *errCloseForRecreating\n\t\tapplicationErr        *ApplicationError\n\t\ttransportErr          *TransportError\n\t)\n\tvar isRemoteClose bool\n\tswitch {\n\tcase errors.Is(e, qerr.ErrIdleTimeout),\n\t\terrors.Is(e, qerr.ErrHandshakeTimeout),\n\t\terrors.As(e, &statelessResetErr),\n\t\terrors.As(e, &versionNegotiationErr),\n\t\terrors.As(e, &recreateErr):\n\tcase errors.As(e, &applicationErr):\n\t\tisRemoteClose = applicationErr.Remote\n\tcase errors.As(e, &transportErr):\n\t\tisRemoteClose = transportErr.Remote\n\tcase closeErr.immediate:\n\t\te = closeErr.err\n\tdefault:\n\t\te = &qerr.TransportError{\n\t\t\tErrorCode:    qerr.InternalError,\n\t\t\tErrorMessage: e.Error(),\n\t\t}\n\t}\n\n\ts.streamsMap.CloseWithError(e)\n\tif s.datagramQueue != nil {\n\t\ts.datagramQueue.CloseWithError(e)\n\t}\n\n\t// In rare instances, the connection ID manager might switch to a new connection ID\n\t// when sending the CONNECTION_CLOSE frame.\n\t// The connection ID manager removes the active stateless reset token from the packet\n\t// handler map when it is closed, so we need to make sure that this happens last.\n\tdefer s.connIDManager.Close()\n\n\tif s.tracer != nil && s.tracer.ClosedConnection != nil && !errors.As(e, &recreateErr) {\n\t\ts.tracer.ClosedConnection(e)\n\t}\n\n\t// If this is a remote close we're done here\n\tif isRemoteClose {\n\t\ts.connIDGenerator.ReplaceWithClosed(nil)\n\t\treturn\n\t}\n\tif closeErr.immediate {\n\t\ts.connIDGenerator.RemoveAll()\n\t\treturn\n\t}\n\t// Don't send out any CONNECTION_CLOSE if this is an error that occurred\n\t// before we even sent out the first packet.\n\tif s.perspective == protocol.PerspectiveClient && !s.sentFirstPacket {\n\t\ts.connIDGenerator.RemoveAll()\n\t\treturn\n\t}\n\tconnClosePacket, err := s.sendConnectionClose(e)\n\tif err != nil {\n\t\ts.logger.Debugf(\"Error sending CONNECTION_CLOSE: %s\", err)\n\t}\n\ts.connIDGenerator.ReplaceWithClosed(connClosePacket)\n}\n\nfunc (s *connection) dropEncryptionLevel(encLevel protocol.EncryptionLevel, now time.Time) error {\n\tif s.tracer != nil && s.tracer.DroppedEncryptionLevel != nil {\n\t\ts.tracer.DroppedEncryptionLevel(encLevel)\n\t}\n\ts.sentPacketHandler.DropPackets(encLevel, now)\n\ts.receivedPacketHandler.DropPackets(encLevel)\n\t//nolint:exhaustive // only Initial and 0-RTT need special treatment\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\ts.droppedInitialKeys = true\n\t\ts.cryptoStreamHandler.DiscardInitialKeys()\n\tcase protocol.Encryption0RTT:\n\t\ts.streamsMap.ResetFor0RTT()\n\t\ts.framer.Handle0RTTRejection()\n\t\treturn s.connFlowController.Reset()\n\t}\n\treturn s.cryptoStreamManager.Drop(encLevel)\n}\n\n// is called for the client, when restoring transport parameters saved for 0-RTT\nfunc (s *connection) restoreTransportParameters(params *wire.TransportParameters) {\n\tif s.logger.Debug() {\n\t\ts.logger.Debugf(\"Restoring Transport Parameters: %s\", params)\n\t}\n\n\ts.peerParams = params\n\ts.connIDGenerator.SetMaxActiveConnIDs(params.ActiveConnectionIDLimit)\n\ts.connFlowController.UpdateSendWindow(params.InitialMaxData)\n\ts.streamsMap.UpdateLimits(params)\n\ts.connStateMutex.Lock()\n\ts.connState.SupportsDatagrams = s.supportsDatagrams()\n\ts.connStateMutex.Unlock()\n}\n\nfunc (s *connection) handleTransportParameters(params *wire.TransportParameters) error {\n\tif s.tracer != nil && s.tracer.ReceivedTransportParameters != nil {\n\t\ts.tracer.ReceivedTransportParameters(params)\n\t}\n\tif err := s.checkTransportParameters(params); err != nil {\n\t\treturn &qerr.TransportError{\n\t\t\tErrorCode:    qerr.TransportParameterError,\n\t\t\tErrorMessage: err.Error(),\n\t\t}\n\t}\n\n\tif s.perspective == protocol.PerspectiveClient && s.peerParams != nil && s.ConnectionState().Used0RTT && !params.ValidForUpdate(s.peerParams) {\n\t\treturn &qerr.TransportError{\n\t\t\tErrorCode:    qerr.ProtocolViolation,\n\t\t\tErrorMessage: \"server sent reduced limits after accepting 0-RTT data\",\n\t\t}\n\t}\n\n\ts.peerParams = params\n\t// On the client side we have to wait for handshake completion.\n\t// During a 0-RTT connection, we are only allowed to use the new transport parameters for 1-RTT packets.\n\tif s.perspective == protocol.PerspectiveServer {\n\t\ts.applyTransportParameters()\n\t\t// On the server side, the early connection is ready as soon as we processed\n\t\t// the client's transport parameters.\n\t\tclose(s.earlyConnReadyChan)\n\t}\n\n\ts.connStateMutex.Lock()\n\ts.connState.SupportsDatagrams = s.supportsDatagrams()\n\ts.connStateMutex.Unlock()\n\treturn nil\n}\n\nfunc (s *connection) checkTransportParameters(params *wire.TransportParameters) error {\n\tif s.logger.Debug() {\n\t\ts.logger.Debugf(\"Processed Transport Parameters: %s\", params)\n\t}\n\n\t// check the initial_source_connection_id\n\tif params.InitialSourceConnectionID != s.handshakeDestConnID {\n\t\treturn fmt.Errorf(\"expected initial_source_connection_id to equal %s, is %s\", s.handshakeDestConnID, params.InitialSourceConnectionID)\n\t}\n\n\tif s.perspective == protocol.PerspectiveServer {\n\t\treturn nil\n\t}\n\t// check the original_destination_connection_id\n\tif params.OriginalDestinationConnectionID != s.origDestConnID {\n\t\treturn fmt.Errorf(\"expected original_destination_connection_id to equal %s, is %s\", s.origDestConnID, params.OriginalDestinationConnectionID)\n\t}\n\tif s.retrySrcConnID != nil { // a Retry was performed\n\t\tif params.RetrySourceConnectionID == nil {\n\t\t\treturn errors.New(\"missing retry_source_connection_id\")\n\t\t}\n\t\tif *params.RetrySourceConnectionID != *s.retrySrcConnID {\n\t\t\treturn fmt.Errorf(\"expected retry_source_connection_id to equal %s, is %s\", s.retrySrcConnID, *params.RetrySourceConnectionID)\n\t\t}\n\t} else if params.RetrySourceConnectionID != nil {\n\t\treturn errors.New(\"received retry_source_connection_id, although no Retry was performed\")\n\t}\n\treturn nil\n}\n\nfunc (s *connection) applyTransportParameters() {\n\tparams := s.peerParams\n\t// Our local idle timeout will always be > 0.\n\ts.idleTimeout = s.config.MaxIdleTimeout\n\t// If the peer advertised an idle timeout, take the minimum of the values.\n\tif params.MaxIdleTimeout > 0 {\n\t\ts.idleTimeout = min(s.idleTimeout, params.MaxIdleTimeout)\n\t}\n\ts.keepAliveInterval = min(s.config.KeepAlivePeriod, s.idleTimeout/2)\n\ts.streamsMap.UpdateLimits(params)\n\ts.frameParser.SetAckDelayExponent(params.AckDelayExponent)\n\ts.connFlowController.UpdateSendWindow(params.InitialMaxData)\n\ts.rttStats.SetMaxAckDelay(params.MaxAckDelay)\n\ts.connIDGenerator.SetMaxActiveConnIDs(params.ActiveConnectionIDLimit)\n\tif params.StatelessResetToken != nil {\n\t\ts.connIDManager.SetStatelessResetToken(*params.StatelessResetToken)\n\t}\n\t// We don't support connection migration yet, so we don't have any use for the preferred_address.\n\tif params.PreferredAddress != nil {\n\t\t// Retire the connection ID.\n\t\ts.connIDManager.AddFromPreferredAddress(params.PreferredAddress.ConnectionID, params.PreferredAddress.StatelessResetToken)\n\t}\n\tmaxPacketSize := protocol.ByteCount(protocol.MaxPacketBufferSize)\n\tif params.MaxUDPPayloadSize > 0 && params.MaxUDPPayloadSize < maxPacketSize {\n\t\tmaxPacketSize = params.MaxUDPPayloadSize\n\t}\n\ts.mtuDiscoverer = newMTUDiscoverer(\n\t\ts.rttStats,\n\t\tprotocol.ByteCount(s.config.InitialPacketSize),\n\t\tmaxPacketSize,\n\t\ts.tracer,\n\t)\n}\n\nfunc (s *connection) triggerSending(now time.Time) error {\n\ts.pacingDeadline = time.Time{}\n\n\tsendMode := s.sentPacketHandler.SendMode(now)\n\t//nolint:exhaustive // No need to handle pacing limited here.\n\tswitch sendMode {\n\tcase ackhandler.SendAny:\n\t\treturn s.sendPackets(now)\n\tcase ackhandler.SendNone:\n\t\treturn nil\n\tcase ackhandler.SendPacingLimited:\n\t\tdeadline := s.sentPacketHandler.TimeUntilSend()\n\t\tif deadline.IsZero() {\n\t\t\tdeadline = deadlineSendImmediately\n\t\t}\n\t\ts.pacingDeadline = deadline\n\t\t// Allow sending of an ACK if we're pacing limit.\n\t\t// This makes sure that a peer that is mostly receiving data (and thus has an inaccurate cwnd estimate)\n\t\t// sends enough ACKs to allow its peer to utilize the bandwidth.\n\t\tfallthrough\n\tcase ackhandler.SendAck:\n\t\t// We can at most send a single ACK only packet.\n\t\t// There will only be a new ACK after receiving new packets.\n\t\t// SendAck is only returned when we're congestion limited, so we don't need to set the pacing timer.\n\t\treturn s.maybeSendAckOnlyPacket(now)\n\tcase ackhandler.SendPTOInitial, ackhandler.SendPTOHandshake, ackhandler.SendPTOAppData:\n\t\tif err := s.sendProbePacket(sendMode, now); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif s.sendQueue.WouldBlock() {\n\t\t\ts.scheduleSending()\n\t\t\treturn nil\n\t\t}\n\t\treturn s.triggerSending(now)\n\tdefault:\n\t\treturn fmt.Errorf(\"BUG: invalid send mode %d\", sendMode)\n\t}\n}\n\nfunc (s *connection) sendPackets(now time.Time) error {\n\tif s.perspective == protocol.PerspectiveClient && s.handshakeConfirmed {\n\t\tif pm := s.pathManagerOutgoing.Load(); pm != nil {\n\t\t\tconnID, frame, tr, ok := pm.NextPathToProbe()\n\t\t\tif ok {\n\t\t\t\tprobe, buf, err := s.packer.PackPathProbePacket(connID, []ackhandler.Frame{frame}, s.version)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\ts.logger.Debugf(\"sending path probe packet from %s\", s.LocalAddr())\n\t\t\t\ts.logShortHeaderPacket(probe.DestConnID, probe.Ack, probe.Frames, probe.StreamFrames, probe.PacketNumber, probe.PacketNumberLen, probe.KeyPhase, protocol.ECNNon, buf.Len(), false)\n\t\t\t\ts.registerPackedShortHeaderPacket(probe, protocol.ECNNon, now)\n\t\t\t\ttr.WriteTo(buf.Data, s.conn.RemoteAddr())\n\t\t\t\t// There's (likely) more data to send. Loop around again.\n\t\t\t\ts.scheduleSending()\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\n\t// Path MTU Discovery\n\t// Can't use GSO, since we need to send a single packet that's larger than our current maximum size.\n\t// Performance-wise, this doesn't matter, since we only send a very small (<10) number of\n\t// MTU probe packets per connection.\n\tif s.handshakeConfirmed && s.mtuDiscoverer != nil && s.mtuDiscoverer.ShouldSendProbe(now) {\n\t\tping, size := s.mtuDiscoverer.GetPing(now)\n\t\tp, buf, err := s.packer.PackMTUProbePacket(ping, size, s.version)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tecn := s.sentPacketHandler.ECNMode(true)\n\t\ts.logShortHeaderPacket(p.DestConnID, p.Ack, p.Frames, p.StreamFrames, p.PacketNumber, p.PacketNumberLen, p.KeyPhase, ecn, buf.Len(), false)\n\t\ts.registerPackedShortHeaderPacket(p, ecn, now)\n\t\ts.sendQueue.Send(buf, 0, ecn)\n\t\t// There's (likely) more data to send. Loop around again.\n\t\ts.scheduleSending()\n\t\treturn nil\n\t}\n\n\tif offset := s.connFlowController.GetWindowUpdate(now); offset > 0 {\n\t\ts.framer.QueueControlFrame(&wire.MaxDataFrame{MaximumData: offset})\n\t}\n\tif cf := s.cryptoStreamManager.GetPostHandshakeData(protocol.MaxPostHandshakeCryptoFrameSize); cf != nil {\n\t\ts.queueControlFrame(cf)\n\t}\n\n\tif !s.handshakeConfirmed {\n\t\tpacket, err := s.packer.PackCoalescedPacket(false, s.maxPacketSize(), now, s.version)\n\t\tif err != nil || packet == nil {\n\t\t\treturn err\n\t\t}\n\t\ts.sentFirstPacket = true\n\t\tif err := s.sendPackedCoalescedPacket(packet, s.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket()), now); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t//nolint:exhaustive // only need to handle pacing-related events here\n\t\tswitch s.sentPacketHandler.SendMode(now) {\n\t\tcase ackhandler.SendPacingLimited:\n\t\t\ts.resetPacingDeadline()\n\t\tcase ackhandler.SendAny:\n\t\t\ts.pacingDeadline = deadlineSendImmediately\n\t\t}\n\t\treturn nil\n\t}\n\n\tif s.conn.capabilities().GSO {\n\t\treturn s.sendPacketsWithGSO(now)\n\t}\n\treturn s.sendPacketsWithoutGSO(now)\n}\n\nfunc (s *connection) sendPacketsWithoutGSO(now time.Time) error {\n\tfor {\n\t\tbuf := getPacketBuffer()\n\t\tecn := s.sentPacketHandler.ECNMode(true)\n\t\tif _, err := s.appendOneShortHeaderPacket(buf, s.maxPacketSize(), ecn, now); err != nil {\n\t\t\tif err == errNothingToPack {\n\t\t\t\tbuf.Release()\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\ts.sendQueue.Send(buf, 0, ecn)\n\n\t\tif s.sendQueue.WouldBlock() {\n\t\t\treturn nil\n\t\t}\n\t\tsendMode := s.sentPacketHandler.SendMode(now)\n\t\tif sendMode == ackhandler.SendPacingLimited {\n\t\t\ts.resetPacingDeadline()\n\t\t\treturn nil\n\t\t}\n\t\tif sendMode != ackhandler.SendAny {\n\t\t\treturn nil\n\t\t}\n\t\t// Prioritize receiving of packets over sending out more packets.\n\t\ts.receivedPacketMx.Lock()\n\t\thasPackets := !s.receivedPackets.Empty()\n\t\ts.receivedPacketMx.Unlock()\n\t\tif hasPackets {\n\t\t\ts.pacingDeadline = deadlineSendImmediately\n\t\t\treturn nil\n\t\t}\n\t}\n}\n\nfunc (s *connection) sendPacketsWithGSO(now time.Time) error {\n\tbuf := getLargePacketBuffer()\n\tmaxSize := s.maxPacketSize()\n\n\tecn := s.sentPacketHandler.ECNMode(true)\n\tfor {\n\t\tvar dontSendMore bool\n\t\tsize, err := s.appendOneShortHeaderPacket(buf, maxSize, ecn, now)\n\t\tif err != nil {\n\t\t\tif err != errNothingToPack {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif buf.Len() == 0 {\n\t\t\t\tbuf.Release()\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tdontSendMore = true\n\t\t}\n\n\t\tif !dontSendMore {\n\t\t\tsendMode := s.sentPacketHandler.SendMode(now)\n\t\t\tif sendMode == ackhandler.SendPacingLimited {\n\t\t\t\ts.resetPacingDeadline()\n\t\t\t}\n\t\t\tif sendMode != ackhandler.SendAny {\n\t\t\t\tdontSendMore = true\n\t\t\t}\n\t\t}\n\n\t\t// Don't send more packets in this batch if they require a different ECN marking than the previous ones.\n\t\tnextECN := s.sentPacketHandler.ECNMode(true)\n\n\t\t// Append another packet if\n\t\t// 1. The congestion controller and pacer allow sending more\n\t\t// 2. The last packet appended was a full-size packet\n\t\t// 3. The next packet will have the same ECN marking\n\t\t// 4. We still have enough space for another full-size packet in the buffer\n\t\tif !dontSendMore && size == maxSize && nextECN == ecn && buf.Len()+maxSize <= buf.Cap() {\n\t\t\tcontinue\n\t\t}\n\n\t\ts.sendQueue.Send(buf, uint16(maxSize), ecn)\n\n\t\tif dontSendMore {\n\t\t\treturn nil\n\t\t}\n\t\tif s.sendQueue.WouldBlock() {\n\t\t\treturn nil\n\t\t}\n\n\t\t// Prioritize receiving of packets over sending out more packets.\n\t\ts.receivedPacketMx.Lock()\n\t\thasPackets := !s.receivedPackets.Empty()\n\t\ts.receivedPacketMx.Unlock()\n\t\tif hasPackets {\n\t\t\ts.pacingDeadline = deadlineSendImmediately\n\t\t\treturn nil\n\t\t}\n\n\t\tecn = nextECN\n\t\tbuf = getLargePacketBuffer()\n\t}\n}\n\nfunc (s *connection) resetPacingDeadline() {\n\tdeadline := s.sentPacketHandler.TimeUntilSend()\n\tif deadline.IsZero() {\n\t\tdeadline = deadlineSendImmediately\n\t}\n\ts.pacingDeadline = deadline\n}\n\nfunc (s *connection) maybeSendAckOnlyPacket(now time.Time) error {\n\tif !s.handshakeConfirmed {\n\t\tecn := s.sentPacketHandler.ECNMode(false)\n\t\tpacket, err := s.packer.PackCoalescedPacket(true, s.maxPacketSize(), now, s.version)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif packet == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn s.sendPackedCoalescedPacket(packet, ecn, now)\n\t}\n\n\tecn := s.sentPacketHandler.ECNMode(true)\n\tp, buf, err := s.packer.PackAckOnlyPacket(s.maxPacketSize(), now, s.version)\n\tif err != nil {\n\t\tif err == errNothingToPack {\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\ts.logShortHeaderPacket(p.DestConnID, p.Ack, p.Frames, p.StreamFrames, p.PacketNumber, p.PacketNumberLen, p.KeyPhase, ecn, buf.Len(), false)\n\ts.registerPackedShortHeaderPacket(p, ecn, now)\n\ts.sendQueue.Send(buf, 0, ecn)\n\treturn nil\n}\n\nfunc (s *connection) sendProbePacket(sendMode ackhandler.SendMode, now time.Time) error {\n\tvar encLevel protocol.EncryptionLevel\n\t//nolint:exhaustive // We only need to handle the PTO send modes here.\n\tswitch sendMode {\n\tcase ackhandler.SendPTOInitial:\n\t\tencLevel = protocol.EncryptionInitial\n\tcase ackhandler.SendPTOHandshake:\n\t\tencLevel = protocol.EncryptionHandshake\n\tcase ackhandler.SendPTOAppData:\n\t\tencLevel = protocol.Encryption1RTT\n\tdefault:\n\t\treturn fmt.Errorf(\"connection BUG: unexpected send mode: %d\", sendMode)\n\t}\n\t// Queue probe packets until we actually send out a packet,\n\t// or until there are no more packets to queue.\n\tvar packet *coalescedPacket\n\tfor packet == nil {\n\t\tif wasQueued := s.sentPacketHandler.QueueProbePacket(encLevel); !wasQueued {\n\t\t\tbreak\n\t\t}\n\t\tvar err error\n\t\tpacket, err = s.packer.PackPTOProbePacket(encLevel, s.maxPacketSize(), false, now, s.version)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif packet == nil {\n\t\tvar err error\n\t\tpacket, err = s.packer.PackPTOProbePacket(encLevel, s.maxPacketSize(), true, now, s.version)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif packet == nil || (len(packet.longHdrPackets) == 0 && packet.shortHdrPacket == nil) {\n\t\treturn fmt.Errorf(\"connection BUG: couldn't pack %s probe packet: %v\", encLevel, packet)\n\t}\n\treturn s.sendPackedCoalescedPacket(packet, s.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket()), now)\n}\n\n// appendOneShortHeaderPacket appends a new packet to the given packetBuffer.\n// If there was nothing to pack, the returned size is 0.\nfunc (s *connection) appendOneShortHeaderPacket(buf *packetBuffer, maxSize protocol.ByteCount, ecn protocol.ECN, now time.Time) (protocol.ByteCount, error) {\n\tstartLen := buf.Len()\n\tp, err := s.packer.AppendPacket(buf, maxSize, now, s.version)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tsize := buf.Len() - startLen\n\ts.logShortHeaderPacket(p.DestConnID, p.Ack, p.Frames, p.StreamFrames, p.PacketNumber, p.PacketNumberLen, p.KeyPhase, ecn, size, false)\n\ts.registerPackedShortHeaderPacket(p, ecn, now)\n\treturn size, nil\n}\n\nfunc (s *connection) registerPackedShortHeaderPacket(p shortHeaderPacket, ecn protocol.ECN, now time.Time) {\n\tif p.IsPathProbePacket {\n\t\ts.sentPacketHandler.SentPacket(\n\t\t\tnow,\n\t\t\tp.PacketNumber,\n\t\t\tprotocol.InvalidPacketNumber,\n\t\t\tp.StreamFrames,\n\t\t\tp.Frames,\n\t\t\tprotocol.Encryption1RTT,\n\t\t\tecn,\n\t\t\tp.Length,\n\t\t\tp.IsPathMTUProbePacket,\n\t\t\ttrue,\n\t\t)\n\t\treturn\n\t}\n\tif s.firstAckElicitingPacketAfterIdleSentTime.IsZero() && (len(p.StreamFrames) > 0 || ackhandler.HasAckElicitingFrames(p.Frames)) {\n\t\ts.firstAckElicitingPacketAfterIdleSentTime = now\n\t}\n\n\tlargestAcked := protocol.InvalidPacketNumber\n\tif p.Ack != nil {\n\t\tlargestAcked = p.Ack.LargestAcked()\n\t}\n\ts.sentPacketHandler.SentPacket(\n\t\tnow,\n\t\tp.PacketNumber,\n\t\tlargestAcked,\n\t\tp.StreamFrames,\n\t\tp.Frames,\n\t\tprotocol.Encryption1RTT,\n\t\tecn,\n\t\tp.Length,\n\t\tp.IsPathMTUProbePacket,\n\t\tfalse,\n\t)\n\ts.connIDManager.SentPacket()\n}\n\nfunc (s *connection) sendPackedCoalescedPacket(packet *coalescedPacket, ecn protocol.ECN, now time.Time) error {\n\ts.logCoalescedPacket(packet, ecn)\n\tfor _, p := range packet.longHdrPackets {\n\t\tif s.firstAckElicitingPacketAfterIdleSentTime.IsZero() && p.IsAckEliciting() {\n\t\t\ts.firstAckElicitingPacketAfterIdleSentTime = now\n\t\t}\n\t\tlargestAcked := protocol.InvalidPacketNumber\n\t\tif p.ack != nil {\n\t\t\tlargestAcked = p.ack.LargestAcked()\n\t\t}\n\t\ts.sentPacketHandler.SentPacket(\n\t\t\tnow,\n\t\t\tp.header.PacketNumber,\n\t\t\tlargestAcked,\n\t\t\tp.streamFrames,\n\t\t\tp.frames,\n\t\t\tp.EncryptionLevel(),\n\t\t\tecn,\n\t\t\tp.length,\n\t\t\tfalse,\n\t\t\tfalse,\n\t\t)\n\t\tif s.perspective == protocol.PerspectiveClient && p.EncryptionLevel() == protocol.EncryptionHandshake &&\n\t\t\t!s.droppedInitialKeys {\n\t\t\t// On the client side, Initial keys are dropped as soon as the first Handshake packet is sent.\n\t\t\t// See Section 4.9.1 of RFC 9001.\n\t\t\tif err := s.dropEncryptionLevel(protocol.EncryptionInitial, now); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\tif p := packet.shortHdrPacket; p != nil {\n\t\tif s.firstAckElicitingPacketAfterIdleSentTime.IsZero() && p.IsAckEliciting() {\n\t\t\ts.firstAckElicitingPacketAfterIdleSentTime = now\n\t\t}\n\t\tlargestAcked := protocol.InvalidPacketNumber\n\t\tif p.Ack != nil {\n\t\t\tlargestAcked = p.Ack.LargestAcked()\n\t\t}\n\t\ts.sentPacketHandler.SentPacket(\n\t\t\tnow,\n\t\t\tp.PacketNumber,\n\t\t\tlargestAcked,\n\t\t\tp.StreamFrames,\n\t\t\tp.Frames,\n\t\t\tprotocol.Encryption1RTT,\n\t\t\tecn,\n\t\t\tp.Length,\n\t\t\tp.IsPathMTUProbePacket,\n\t\t\tfalse,\n\t\t)\n\t}\n\ts.connIDManager.SentPacket()\n\ts.sendQueue.Send(packet.buffer, 0, ecn)\n\treturn nil\n}\n\nfunc (s *connection) sendConnectionClose(e error) ([]byte, error) {\n\tvar packet *coalescedPacket\n\tvar err error\n\tvar transportErr *qerr.TransportError\n\tvar applicationErr *qerr.ApplicationError\n\tif errors.As(e, &transportErr) {\n\t\tpacket, err = s.packer.PackConnectionClose(transportErr, s.maxPacketSize(), s.version)\n\t} else if errors.As(e, &applicationErr) {\n\t\tpacket, err = s.packer.PackApplicationClose(applicationErr, s.maxPacketSize(), s.version)\n\t} else {\n\t\tpacket, err = s.packer.PackConnectionClose(&qerr.TransportError{\n\t\t\tErrorCode:    qerr.InternalError,\n\t\t\tErrorMessage: fmt.Sprintf(\"connection BUG: unspecified error type (msg: %s)\", e.Error()),\n\t\t}, s.maxPacketSize(), s.version)\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tecn := s.sentPacketHandler.ECNMode(packet.IsOnlyShortHeaderPacket())\n\ts.logCoalescedPacket(packet, ecn)\n\treturn packet.buffer.Data, s.conn.Write(packet.buffer.Data, 0, ecn)\n}\n\nfunc (s *connection) maxPacketSize() protocol.ByteCount {\n\tif s.mtuDiscoverer == nil {\n\t\t// Use the configured packet size on the client side.\n\t\t// If the server sends a max_udp_payload_size that's smaller than this size, we can ignore this:\n\t\t// Apparently the server still processed the (fully padded) Initial packet anyway.\n\t\tif s.perspective == protocol.PerspectiveClient {\n\t\t\treturn protocol.ByteCount(s.config.InitialPacketSize)\n\t\t}\n\t\t// On the server side, there's no downside to using 1200 bytes until we received the client's transport\n\t\t// parameters:\n\t\t// * If the first packet didn't contain the entire ClientHello, all we can do is ACK that packet. We don't\n\t\t//   need a lot of bytes for that.\n\t\t// * If it did, we will have processed the transport parameters and initialized the MTU discoverer.\n\t\treturn protocol.MinInitialPacketSize\n\t}\n\treturn s.mtuDiscoverer.CurrentSize()\n}\n\n// AcceptStream returns the next stream openend by the peer\nfunc (s *connection) AcceptStream(ctx context.Context) (Stream, error) {\n\treturn s.streamsMap.AcceptStream(ctx)\n}\n\nfunc (s *connection) AcceptUniStream(ctx context.Context) (ReceiveStream, error) {\n\treturn s.streamsMap.AcceptUniStream(ctx)\n}\n\n// OpenStream opens a stream\nfunc (s *connection) OpenStream() (Stream, error) {\n\treturn s.streamsMap.OpenStream()\n}\n\nfunc (s *connection) OpenStreamSync(ctx context.Context) (Stream, error) {\n\treturn s.streamsMap.OpenStreamSync(ctx)\n}\n\nfunc (s *connection) OpenUniStream() (SendStream, error) {\n\treturn s.streamsMap.OpenUniStream()\n}\n\nfunc (s *connection) OpenUniStreamSync(ctx context.Context) (SendStream, error) {\n\treturn s.streamsMap.OpenUniStreamSync(ctx)\n}\n\nfunc (s *connection) newFlowController(id protocol.StreamID) flowcontrol.StreamFlowController {\n\tinitialSendWindow := s.peerParams.InitialMaxStreamDataUni\n\tif id.Type() == protocol.StreamTypeBidi {\n\t\tif id.InitiatedBy() == s.perspective {\n\t\t\tinitialSendWindow = s.peerParams.InitialMaxStreamDataBidiRemote\n\t\t} else {\n\t\t\tinitialSendWindow = s.peerParams.InitialMaxStreamDataBidiLocal\n\t\t}\n\t}\n\treturn flowcontrol.NewStreamFlowController(\n\t\tid,\n\t\ts.connFlowController,\n\t\tprotocol.ByteCount(s.config.InitialStreamReceiveWindow),\n\t\tprotocol.ByteCount(s.config.MaxStreamReceiveWindow),\n\t\tinitialSendWindow,\n\t\ts.rttStats,\n\t\ts.logger,\n\t)\n}\n\n// scheduleSending signals that we have data for sending\nfunc (s *connection) scheduleSending() {\n\tselect {\n\tcase s.sendingScheduled <- struct{}{}:\n\tdefault:\n\t}\n}\n\n// tryQueueingUndecryptablePacket queues a packet for which we're missing the decryption keys.\n// The logging.PacketType is only used for logging purposes.\nfunc (s *connection) tryQueueingUndecryptablePacket(p receivedPacket, pt logging.PacketType) {\n\tif s.handshakeComplete {\n\t\tpanic(\"shouldn't queue undecryptable packets after handshake completion\")\n\t}\n\tif len(s.undecryptablePackets)+1 > protocol.MaxUndecryptablePackets {\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(pt, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropDOSPrevention)\n\t\t}\n\t\ts.logger.Infof(\"Dropping undecryptable packet (%d bytes). Undecryptable packet queue full.\", p.Size())\n\t\treturn\n\t}\n\ts.logger.Infof(\"Queueing packet (%d bytes) for later decryption\", p.Size())\n\tif s.tracer != nil && s.tracer.BufferedPacket != nil {\n\t\ts.tracer.BufferedPacket(pt, p.Size())\n\t}\n\ts.undecryptablePackets = append(s.undecryptablePackets, p)\n}\n\nfunc (s *connection) queueControlFrame(f wire.Frame) {\n\ts.framer.QueueControlFrame(f)\n\ts.scheduleSending()\n}\n\nfunc (s *connection) onHasConnectionData() { s.scheduleSending() }\n\nfunc (s *connection) onHasStreamData(id protocol.StreamID, str sendStreamI) {\n\ts.framer.AddActiveStream(id, str)\n\ts.scheduleSending()\n}\n\nfunc (s *connection) onHasStreamControlFrame(id protocol.StreamID, str streamControlFrameGetter) {\n\ts.framer.AddStreamWithControlFrames(id, str)\n\ts.scheduleSending()\n}\n\nfunc (s *connection) onStreamCompleted(id protocol.StreamID) {\n\tif err := s.streamsMap.DeleteStream(id); err != nil {\n\t\ts.closeLocal(err)\n\t}\n\ts.framer.RemoveActiveStream(id)\n}\n\nfunc (s *connection) SendDatagram(p []byte) error {\n\tif !s.supportsDatagrams() {\n\t\treturn errors.New(\"datagram support disabled\")\n\t}\n\n\tf := &wire.DatagramFrame{DataLenPresent: true}\n\t// The payload size estimate is conservative.\n\t// Under many circumstances we could send a few more bytes.\n\tmaxDataLen := min(\n\t\tf.MaxDataLen(s.peerParams.MaxDatagramFrameSize, s.version),\n\t\tprotocol.ByteCount(s.currentMTUEstimate.Load()),\n\t)\n\tif protocol.ByteCount(len(p)) > maxDataLen {\n\t\treturn &DatagramTooLargeError{MaxDatagramPayloadSize: int64(maxDataLen)}\n\t}\n\tf.Data = make([]byte, len(p))\n\tcopy(f.Data, p)\n\treturn s.datagramQueue.Add(f)\n}\n\nfunc (s *connection) ReceiveDatagram(ctx context.Context) ([]byte, error) {\n\tif !s.config.EnableDatagrams {\n\t\treturn nil, errors.New(\"datagram support disabled\")\n\t}\n\treturn s.datagramQueue.Receive(ctx)\n}\n\nfunc (s *connection) LocalAddr() net.Addr  { return s.conn.LocalAddr() }\nfunc (s *connection) RemoteAddr() net.Addr { return s.conn.RemoteAddr() }\n\nfunc (s *connection) getPathManager() *pathManagerOutgoing {\n\ts.pathManagerOutgoing.CompareAndSwap(nil,\n\t\tfunc() *pathManagerOutgoing { // this function is only called if a swap is performed\n\t\t\treturn newPathManagerOutgoing(\n\t\t\t\ts.connIDManager.GetConnIDForPath,\n\t\t\t\ts.connIDManager.RetireConnIDForPath,\n\t\t\t\ts.scheduleSending,\n\t\t\t)\n\t\t}(),\n\t)\n\treturn s.pathManagerOutgoing.Load()\n}\n\nfunc (s *connection) AddPath(t *Transport) (*Path, error) {\n\tif s.perspective == protocol.PerspectiveServer {\n\t\treturn nil, errors.New(\"server cannot initiate connection migration\")\n\t}\n\tif s.peerParams.DisableActiveMigration {\n\t\treturn nil, errors.New(\"server disabled connection migration\")\n\t}\n\tif err := t.init(false); err != nil {\n\t\treturn nil, err\n\t}\n\treturn s.getPathManager().NewPath(\n\t\tt,\n\t\t200*time.Millisecond, // initial RTT estimate\n\t\tfunc() {\n\t\t\trunner := t.connRunner()\n\t\t\ts.connIDGenerator.AddConnRunner(\n\t\t\t\tt.id(),\n\t\t\t\tconnRunnerCallbacks{\n\t\t\t\t\tAddConnectionID:    func(connID protocol.ConnectionID) { runner.Add(connID, s) },\n\t\t\t\t\tRemoveConnectionID: runner.Remove,\n\t\t\t\t\tRetireConnectionID: runner.Retire,\n\t\t\t\t\tReplaceWithClosed:  runner.ReplaceWithClosed,\n\t\t\t\t},\n\t\t\t)\n\t\t},\n\t), nil\n}\n\nfunc (s *connection) NextConnection(ctx context.Context) (Connection, error) {\n\t// The handshake might fail after the server rejected 0-RTT.\n\t// This could happen if the Finished message is malformed or never received.\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn nil, context.Cause(ctx)\n\tcase <-s.Context().Done():\n\tcase <-s.HandshakeComplete():\n\t\ts.streamsMap.UseResetMaps()\n\t}\n\treturn s, nil\n}\n\n// estimateMaxPayloadSize estimates the maximum payload size for short header packets.\n// It is not very sophisticated: it just subtracts the size of header (assuming the maximum\n// connection ID length), and the size of the encryption tag.\nfunc estimateMaxPayloadSize(mtu protocol.ByteCount) protocol.ByteCount {\n\treturn mtu - 1 /* type byte */ - 20 /* maximum connection ID length */ - 16 /* tag size */\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/connection_logging.go",
    "content": "package quic\n\nimport (\n\t\"slices\"\n\n\t\"github.com/quic-go/quic-go/internal/ackhandler\"\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n\t\"github.com/quic-go/quic-go/logging\"\n)\n\n// ConvertFrame converts a wire.Frame into a logging.Frame.\n// This makes it possible for external packages to access the frames.\n// Furthermore, it removes the data slices from CRYPTO and STREAM frames.\nfunc toLoggingFrame(frame wire.Frame) logging.Frame {\n\tswitch f := frame.(type) {\n\tcase *wire.AckFrame:\n\t\t// We use a pool for ACK frames.\n\t\t// Implementations of the tracer interface may hold on to frames, so we need to make a copy here.\n\t\treturn toLoggingAckFrame(f)\n\tcase *wire.CryptoFrame:\n\t\treturn &logging.CryptoFrame{\n\t\t\tOffset: f.Offset,\n\t\t\tLength: protocol.ByteCount(len(f.Data)),\n\t\t}\n\tcase *wire.StreamFrame:\n\t\treturn &logging.StreamFrame{\n\t\t\tStreamID: f.StreamID,\n\t\t\tOffset:   f.Offset,\n\t\t\tLength:   f.DataLen(),\n\t\t\tFin:      f.Fin,\n\t\t}\n\tcase *wire.DatagramFrame:\n\t\treturn &logging.DatagramFrame{\n\t\t\tLength: logging.ByteCount(len(f.Data)),\n\t\t}\n\tdefault:\n\t\treturn logging.Frame(frame)\n\t}\n}\n\nfunc toLoggingAckFrame(f *wire.AckFrame) *logging.AckFrame {\n\tack := &logging.AckFrame{\n\t\tAckRanges: slices.Clone(f.AckRanges),\n\t\tDelayTime: f.DelayTime,\n\t\tECNCE:     f.ECNCE,\n\t\tECT0:      f.ECT0,\n\t\tECT1:      f.ECT1,\n\t}\n\treturn ack\n}\n\nfunc (s *connection) logLongHeaderPacket(p *longHeaderPacket, ecn protocol.ECN) {\n\t// quic-go logging\n\tif s.logger.Debug() {\n\t\tp.header.Log(s.logger)\n\t\tif p.ack != nil {\n\t\t\twire.LogFrame(s.logger, p.ack, true)\n\t\t}\n\t\tfor _, frame := range p.frames {\n\t\t\twire.LogFrame(s.logger, frame.Frame, true)\n\t\t}\n\t\tfor _, frame := range p.streamFrames {\n\t\t\twire.LogFrame(s.logger, frame.Frame, true)\n\t\t}\n\t}\n\n\t// tracing\n\tif s.tracer != nil && s.tracer.SentLongHeaderPacket != nil {\n\t\tframes := make([]logging.Frame, 0, len(p.frames))\n\t\tfor _, f := range p.frames {\n\t\t\tframes = append(frames, toLoggingFrame(f.Frame))\n\t\t}\n\t\tfor _, f := range p.streamFrames {\n\t\t\tframes = append(frames, toLoggingFrame(f.Frame))\n\t\t}\n\t\tvar ack *logging.AckFrame\n\t\tif p.ack != nil {\n\t\t\tack = toLoggingAckFrame(p.ack)\n\t\t}\n\t\ts.tracer.SentLongHeaderPacket(p.header, p.length, ecn, ack, frames)\n\t}\n}\n\nfunc (s *connection) logShortHeaderPacket(\n\tdestConnID protocol.ConnectionID,\n\tackFrame *wire.AckFrame,\n\tframes []ackhandler.Frame,\n\tstreamFrames []ackhandler.StreamFrame,\n\tpn protocol.PacketNumber,\n\tpnLen protocol.PacketNumberLen,\n\tkp protocol.KeyPhaseBit,\n\tecn protocol.ECN,\n\tsize protocol.ByteCount,\n\tisCoalesced bool,\n) {\n\tif s.logger.Debug() && !isCoalesced {\n\t\ts.logger.Debugf(\"-> Sending packet %d (%d bytes) for connection %s, 1-RTT (ECN: %s)\", pn, size, s.logID, ecn)\n\t}\n\t// quic-go logging\n\tif s.logger.Debug() {\n\t\twire.LogShortHeader(s.logger, destConnID, pn, pnLen, kp)\n\t\tif ackFrame != nil {\n\t\t\twire.LogFrame(s.logger, ackFrame, true)\n\t\t}\n\t\tfor _, f := range frames {\n\t\t\twire.LogFrame(s.logger, f.Frame, true)\n\t\t}\n\t\tfor _, f := range streamFrames {\n\t\t\twire.LogFrame(s.logger, f.Frame, true)\n\t\t}\n\t}\n\n\t// tracing\n\tif s.tracer != nil && s.tracer.SentShortHeaderPacket != nil {\n\t\tfs := make([]logging.Frame, 0, len(frames)+len(streamFrames))\n\t\tfor _, f := range frames {\n\t\t\tfs = append(fs, toLoggingFrame(f.Frame))\n\t\t}\n\t\tfor _, f := range streamFrames {\n\t\t\tfs = append(fs, toLoggingFrame(f.Frame))\n\t\t}\n\t\tvar ack *logging.AckFrame\n\t\tif ackFrame != nil {\n\t\t\tack = toLoggingAckFrame(ackFrame)\n\t\t}\n\t\ts.tracer.SentShortHeaderPacket(\n\t\t\t&logging.ShortHeader{DestConnectionID: destConnID, PacketNumber: pn, PacketNumberLen: pnLen, KeyPhase: kp},\n\t\t\tsize,\n\t\t\tecn,\n\t\t\tack,\n\t\t\tfs,\n\t\t)\n\t}\n}\n\nfunc (s *connection) logCoalescedPacket(packet *coalescedPacket, ecn protocol.ECN) {\n\tif s.logger.Debug() {\n\t\t// There's a short period between dropping both Initial and Handshake keys and completion of the handshake,\n\t\t// during which we might call PackCoalescedPacket but just pack a short header packet.\n\t\tif len(packet.longHdrPackets) == 0 && packet.shortHdrPacket != nil {\n\t\t\ts.logShortHeaderPacket(\n\t\t\t\tpacket.shortHdrPacket.DestConnID,\n\t\t\t\tpacket.shortHdrPacket.Ack,\n\t\t\t\tpacket.shortHdrPacket.Frames,\n\t\t\t\tpacket.shortHdrPacket.StreamFrames,\n\t\t\t\tpacket.shortHdrPacket.PacketNumber,\n\t\t\t\tpacket.shortHdrPacket.PacketNumberLen,\n\t\t\t\tpacket.shortHdrPacket.KeyPhase,\n\t\t\t\tecn,\n\t\t\t\tpacket.shortHdrPacket.Length,\n\t\t\t\tfalse,\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t\tif len(packet.longHdrPackets) > 1 {\n\t\t\ts.logger.Debugf(\"-> Sending coalesced packet (%d parts, %d bytes) for connection %s\", len(packet.longHdrPackets), packet.buffer.Len(), s.logID)\n\t\t} else {\n\t\t\ts.logger.Debugf(\"-> Sending packet %d (%d bytes) for connection %s, %s\", packet.longHdrPackets[0].header.PacketNumber, packet.buffer.Len(), s.logID, packet.longHdrPackets[0].EncryptionLevel())\n\t\t}\n\t}\n\tfor _, p := range packet.longHdrPackets {\n\t\ts.logLongHeaderPacket(p, ecn)\n\t}\n\tif p := packet.shortHdrPacket; p != nil {\n\t\ts.logShortHeaderPacket(p.DestConnID, p.Ack, p.Frames, p.StreamFrames, p.PacketNumber, p.PacketNumberLen, p.KeyPhase, ecn, p.Length, true)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/connection_timer.go",
    "content": "package quic\n\nimport (\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/utils\"\n)\n\nvar deadlineSendImmediately = time.Time{}.Add(42 * time.Millisecond) // any value > time.Time{} and before time.Now() is fine\n\ntype connectionTimer struct {\n\ttimer *utils.Timer\n\tlast  time.Time\n}\n\nfunc newTimer() *connectionTimer {\n\treturn &connectionTimer{timer: utils.NewTimer()}\n}\n\nfunc (t *connectionTimer) SetRead() {\n\tif deadline := t.timer.Deadline(); deadline != deadlineSendImmediately {\n\t\tt.last = deadline\n\t}\n\tt.timer.SetRead()\n}\n\nfunc (t *connectionTimer) Chan() <-chan time.Time {\n\treturn t.timer.Chan()\n}\n\n// SetTimer resets the timer.\n// It makes sure that the deadline is strictly increasing.\n// This prevents busy-looping in cases where the timer fires, but we can't actually send out a packet.\n// This doesn't apply to the pacing deadline, which can be set multiple times to deadlineSendImmediately.\nfunc (t *connectionTimer) SetTimer(idleTimeoutOrKeepAlive, ackAlarm, lossTime, pacing time.Time) {\n\tdeadline := idleTimeoutOrKeepAlive\n\tif !ackAlarm.IsZero() && ackAlarm.Before(deadline) && ackAlarm.After(t.last) {\n\t\tdeadline = ackAlarm\n\t}\n\tif !lossTime.IsZero() && lossTime.Before(deadline) && lossTime.After(t.last) {\n\t\tdeadline = lossTime\n\t}\n\tif !pacing.IsZero() && pacing.Before(deadline) {\n\t\tdeadline = pacing\n\t}\n\tt.timer.Reset(deadline)\n}\n\nfunc (t *connectionTimer) Stop() {\n\tt.timer.Stop()\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/crypto_stream.go",
    "content": "package quic\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\ntype cryptoStream struct {\n\tqueue frameSorter\n\n\thighestOffset protocol.ByteCount\n\tfinished      bool\n\n\twriteOffset protocol.ByteCount\n\twriteBuf    []byte\n}\n\nfunc newCryptoStream() *cryptoStream {\n\treturn &cryptoStream{queue: *newFrameSorter()}\n}\n\nfunc (s *cryptoStream) HandleCryptoFrame(f *wire.CryptoFrame) error {\n\thighestOffset := f.Offset + protocol.ByteCount(len(f.Data))\n\tif maxOffset := highestOffset; maxOffset > protocol.MaxCryptoStreamOffset {\n\t\treturn &qerr.TransportError{\n\t\t\tErrorCode:    qerr.CryptoBufferExceeded,\n\t\t\tErrorMessage: fmt.Sprintf(\"received invalid offset %d on crypto stream, maximum allowed %d\", maxOffset, protocol.MaxCryptoStreamOffset),\n\t\t}\n\t}\n\tif s.finished {\n\t\tif highestOffset > s.highestOffset {\n\t\t\t// reject crypto data received after this stream was already finished\n\t\t\treturn &qerr.TransportError{\n\t\t\t\tErrorCode:    qerr.ProtocolViolation,\n\t\t\t\tErrorMessage: \"received crypto data after change of encryption level\",\n\t\t\t}\n\t\t}\n\t\t// ignore data with a smaller offset than the highest received\n\t\t// could e.g. be a retransmission\n\t\treturn nil\n\t}\n\ts.highestOffset = max(s.highestOffset, highestOffset)\n\treturn s.queue.Push(f.Data, f.Offset, nil)\n}\n\n// GetCryptoData retrieves data that was received in CRYPTO frames\nfunc (s *cryptoStream) GetCryptoData() []byte {\n\t_, data, _ := s.queue.Pop()\n\treturn data\n}\n\nfunc (s *cryptoStream) Finish() error {\n\tif s.queue.HasMoreData() {\n\t\treturn &qerr.TransportError{\n\t\t\tErrorCode:    qerr.ProtocolViolation,\n\t\t\tErrorMessage: \"encryption level changed, but crypto stream has more data to read\",\n\t\t}\n\t}\n\ts.finished = true\n\treturn nil\n}\n\n// Writes writes data that should be sent out in CRYPTO frames\nfunc (s *cryptoStream) Write(p []byte) (int, error) {\n\ts.writeBuf = append(s.writeBuf, p...)\n\treturn len(p), nil\n}\n\nfunc (s *cryptoStream) HasData() bool {\n\treturn len(s.writeBuf) > 0\n}\n\nfunc (s *cryptoStream) PopCryptoFrame(maxLen protocol.ByteCount) *wire.CryptoFrame {\n\tf := &wire.CryptoFrame{Offset: s.writeOffset}\n\tn := min(f.MaxDataLen(maxLen), protocol.ByteCount(len(s.writeBuf)))\n\tf.Data = s.writeBuf[:n]\n\ts.writeBuf = s.writeBuf[n:]\n\ts.writeOffset += n\n\treturn f\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/crypto_stream_manager.go",
    "content": "package quic\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\ntype cryptoStreamManager struct {\n\tinitialStream   *cryptoStream\n\thandshakeStream *cryptoStream\n\toneRTTStream    *cryptoStream\n}\n\nfunc newCryptoStreamManager(\n\tinitialStream *cryptoStream,\n\thandshakeStream *cryptoStream,\n\toneRTTStream *cryptoStream,\n) *cryptoStreamManager {\n\treturn &cryptoStreamManager{\n\t\tinitialStream:   initialStream,\n\t\thandshakeStream: handshakeStream,\n\t\toneRTTStream:    oneRTTStream,\n\t}\n}\n\nfunc (m *cryptoStreamManager) HandleCryptoFrame(frame *wire.CryptoFrame, encLevel protocol.EncryptionLevel) error {\n\tvar str *cryptoStream\n\t//nolint:exhaustive // CRYPTO frames cannot be sent in 0-RTT packets.\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\tstr = m.initialStream\n\tcase protocol.EncryptionHandshake:\n\t\tstr = m.handshakeStream\n\tcase protocol.Encryption1RTT:\n\t\tstr = m.oneRTTStream\n\tdefault:\n\t\treturn fmt.Errorf(\"received CRYPTO frame with unexpected encryption level: %s\", encLevel)\n\t}\n\treturn str.HandleCryptoFrame(frame)\n}\n\nfunc (m *cryptoStreamManager) GetCryptoData(encLevel protocol.EncryptionLevel) []byte {\n\tvar str *cryptoStream\n\t//nolint:exhaustive // CRYPTO frames cannot be sent in 0-RTT packets.\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\tstr = m.initialStream\n\tcase protocol.EncryptionHandshake:\n\t\tstr = m.handshakeStream\n\tcase protocol.Encryption1RTT:\n\t\tstr = m.oneRTTStream\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"received CRYPTO frame with unexpected encryption level: %s\", encLevel))\n\t}\n\treturn str.GetCryptoData()\n}\n\nfunc (m *cryptoStreamManager) GetPostHandshakeData(maxSize protocol.ByteCount) *wire.CryptoFrame {\n\tif !m.oneRTTStream.HasData() {\n\t\treturn nil\n\t}\n\treturn m.oneRTTStream.PopCryptoFrame(maxSize)\n}\n\nfunc (m *cryptoStreamManager) Drop(encLevel protocol.EncryptionLevel) error {\n\t//nolint:exhaustive // 1-RTT keys should never get dropped.\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\treturn m.initialStream.Finish()\n\tcase protocol.EncryptionHandshake:\n\t\treturn m.handshakeStream.Finish()\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"dropped unexpected encryption level: %s\", encLevel))\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/datagram_queue.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/internal/utils/ringbuffer\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\nconst (\n\tmaxDatagramSendQueueLen = 32\n\tmaxDatagramRcvQueueLen  = 128\n)\n\ntype datagramQueue struct {\n\tsendMx    sync.Mutex\n\tsendQueue ringbuffer.RingBuffer[*wire.DatagramFrame]\n\tsent      chan struct{} // used to notify Add that a datagram was dequeued\n\n\trcvMx    sync.Mutex\n\trcvQueue [][]byte\n\trcvd     chan struct{} // used to notify Receive that a new datagram was received\n\n\tcloseErr error\n\tclosed   chan struct{}\n\n\thasData func()\n\n\tlogger utils.Logger\n}\n\nfunc newDatagramQueue(hasData func(), logger utils.Logger) *datagramQueue {\n\treturn &datagramQueue{\n\t\thasData: hasData,\n\t\trcvd:    make(chan struct{}, 1),\n\t\tsent:    make(chan struct{}, 1),\n\t\tclosed:  make(chan struct{}),\n\t\tlogger:  logger,\n\t}\n}\n\n// Add queues a new DATAGRAM frame for sending.\n// Up to 32 DATAGRAM frames will be queued.\n// Once that limit is reached, Add blocks until the queue size has reduced.\nfunc (h *datagramQueue) Add(f *wire.DatagramFrame) error {\n\th.sendMx.Lock()\n\n\tfor {\n\t\tif h.sendQueue.Len() < maxDatagramSendQueueLen {\n\t\t\th.sendQueue.PushBack(f)\n\t\t\th.sendMx.Unlock()\n\t\t\th.hasData()\n\t\t\treturn nil\n\t\t}\n\t\tselect {\n\t\tcase <-h.sent: // drain the queue so we don't loop immediately\n\t\tdefault:\n\t\t}\n\t\th.sendMx.Unlock()\n\t\tselect {\n\t\tcase <-h.closed:\n\t\t\treturn h.closeErr\n\t\tcase <-h.sent:\n\t\t}\n\t\th.sendMx.Lock()\n\t}\n}\n\n// Peek gets the next DATAGRAM frame for sending.\n// If actually sent out, Pop needs to be called before the next call to Peek.\nfunc (h *datagramQueue) Peek() *wire.DatagramFrame {\n\th.sendMx.Lock()\n\tdefer h.sendMx.Unlock()\n\tif h.sendQueue.Empty() {\n\t\treturn nil\n\t}\n\treturn h.sendQueue.PeekFront()\n}\n\nfunc (h *datagramQueue) Pop() {\n\th.sendMx.Lock()\n\tdefer h.sendMx.Unlock()\n\t_ = h.sendQueue.PopFront()\n\tselect {\n\tcase h.sent <- struct{}{}:\n\tdefault:\n\t}\n}\n\n// HandleDatagramFrame handles a received DATAGRAM frame.\nfunc (h *datagramQueue) HandleDatagramFrame(f *wire.DatagramFrame) {\n\tdata := make([]byte, len(f.Data))\n\tcopy(data, f.Data)\n\tvar queued bool\n\th.rcvMx.Lock()\n\tif len(h.rcvQueue) < maxDatagramRcvQueueLen {\n\t\th.rcvQueue = append(h.rcvQueue, data)\n\t\tqueued = true\n\t\tselect {\n\t\tcase h.rcvd <- struct{}{}:\n\t\tdefault:\n\t\t}\n\t}\n\th.rcvMx.Unlock()\n\tif !queued && h.logger.Debug() {\n\t\th.logger.Debugf(\"Discarding received DATAGRAM frame (%d bytes payload)\", len(f.Data))\n\t}\n}\n\n// Receive gets a received DATAGRAM frame.\nfunc (h *datagramQueue) Receive(ctx context.Context) ([]byte, error) {\n\tfor {\n\t\th.rcvMx.Lock()\n\t\tif len(h.rcvQueue) > 0 {\n\t\t\tdata := h.rcvQueue[0]\n\t\t\th.rcvQueue = h.rcvQueue[1:]\n\t\t\th.rcvMx.Unlock()\n\t\t\treturn data, nil\n\t\t}\n\t\th.rcvMx.Unlock()\n\t\tselect {\n\t\tcase <-h.rcvd:\n\t\t\tcontinue\n\t\tcase <-h.closed:\n\t\t\treturn nil, h.closeErr\n\t\tcase <-ctx.Done():\n\t\t\treturn nil, ctx.Err()\n\t\t}\n\t}\n}\n\nfunc (h *datagramQueue) CloseWithError(e error) {\n\th.closeErr = e\n\tclose(h.closed)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/errors.go",
    "content": "package quic\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n)\n\ntype (\n\tTransportError          = qerr.TransportError\n\tApplicationError        = qerr.ApplicationError\n\tVersionNegotiationError = qerr.VersionNegotiationError\n\tStatelessResetError     = qerr.StatelessResetError\n\tIdleTimeoutError        = qerr.IdleTimeoutError\n\tHandshakeTimeoutError   = qerr.HandshakeTimeoutError\n)\n\ntype (\n\tTransportErrorCode   = qerr.TransportErrorCode\n\tApplicationErrorCode = qerr.ApplicationErrorCode\n\tStreamErrorCode      = qerr.StreamErrorCode\n)\n\nconst (\n\tNoError                   = qerr.NoError\n\tInternalError             = qerr.InternalError\n\tConnectionRefused         = qerr.ConnectionRefused\n\tFlowControlError          = qerr.FlowControlError\n\tStreamLimitError          = qerr.StreamLimitError\n\tStreamStateError          = qerr.StreamStateError\n\tFinalSizeError            = qerr.FinalSizeError\n\tFrameEncodingError        = qerr.FrameEncodingError\n\tTransportParameterError   = qerr.TransportParameterError\n\tConnectionIDLimitError    = qerr.ConnectionIDLimitError\n\tProtocolViolation         = qerr.ProtocolViolation\n\tInvalidToken              = qerr.InvalidToken\n\tApplicationErrorErrorCode = qerr.ApplicationErrorErrorCode\n\tCryptoBufferExceeded      = qerr.CryptoBufferExceeded\n\tKeyUpdateError            = qerr.KeyUpdateError\n\tAEADLimitReached          = qerr.AEADLimitReached\n\tNoViablePathError         = qerr.NoViablePathError\n)\n\n// A StreamError is used for Stream.CancelRead and Stream.CancelWrite.\n// It is also returned from Stream.Read and Stream.Write if the peer canceled reading or writing.\ntype StreamError struct {\n\tStreamID  StreamID\n\tErrorCode StreamErrorCode\n\tRemote    bool\n}\n\nfunc (e *StreamError) Is(target error) bool {\n\tt, ok := target.(*StreamError)\n\treturn ok && e.StreamID == t.StreamID && e.ErrorCode == t.ErrorCode && e.Remote == t.Remote\n}\n\nfunc (e *StreamError) Error() string {\n\tpers := \"local\"\n\tif e.Remote {\n\t\tpers = \"remote\"\n\t}\n\treturn fmt.Sprintf(\"stream %d canceled by %s with error code %d\", e.StreamID, pers, e.ErrorCode)\n}\n\n// DatagramTooLargeError is returned from Connection.SendDatagram if the payload is too large to be sent.\ntype DatagramTooLargeError struct {\n\tMaxDatagramPayloadSize int64\n}\n\nfunc (e *DatagramTooLargeError) Is(target error) bool {\n\tt, ok := target.(*DatagramTooLargeError)\n\treturn ok && e.MaxDatagramPayloadSize == t.MaxDatagramPayloadSize\n}\n\nfunc (e *DatagramTooLargeError) Error() string { return \"DATAGRAM frame too large\" }\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/frame_sorter.go",
    "content": "package quic\n\nimport (\n\t\"errors\"\n\t\"sync\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\tlist \"github.com/quic-go/quic-go/internal/utils/linkedlist\"\n)\n\n// byteInterval is an interval from one ByteCount to the other\ntype byteInterval struct {\n\tStart protocol.ByteCount\n\tEnd   protocol.ByteCount\n}\n\nvar byteIntervalElementPool sync.Pool\n\nfunc init() {\n\tbyteIntervalElementPool = *list.NewPool[byteInterval]()\n}\n\ntype frameSorterEntry struct {\n\tData   []byte\n\tDoneCb func()\n}\n\ntype frameSorter struct {\n\tqueue   map[protocol.ByteCount]frameSorterEntry\n\treadPos protocol.ByteCount\n\tgaps    *list.List[byteInterval]\n}\n\nvar errDuplicateStreamData = errors.New(\"duplicate stream data\")\n\nfunc newFrameSorter() *frameSorter {\n\ts := frameSorter{\n\t\tgaps:  list.NewWithPool[byteInterval](&byteIntervalElementPool),\n\t\tqueue: make(map[protocol.ByteCount]frameSorterEntry),\n\t}\n\ts.gaps.PushFront(byteInterval{Start: 0, End: protocol.MaxByteCount})\n\treturn &s\n}\n\nfunc (s *frameSorter) Push(data []byte, offset protocol.ByteCount, doneCb func()) error {\n\terr := s.push(data, offset, doneCb)\n\tif err == errDuplicateStreamData {\n\t\tif doneCb != nil {\n\t\t\tdoneCb()\n\t\t}\n\t\treturn nil\n\t}\n\treturn err\n}\n\nfunc (s *frameSorter) push(data []byte, offset protocol.ByteCount, doneCb func()) error {\n\tif len(data) == 0 {\n\t\treturn errDuplicateStreamData\n\t}\n\n\tstart := offset\n\tend := offset + protocol.ByteCount(len(data))\n\n\tif end <= s.gaps.Front().Value.Start {\n\t\treturn errDuplicateStreamData\n\t}\n\n\tstartGap, startsInGap := s.findStartGap(start)\n\tendGap, endsInGap := s.findEndGap(startGap, end)\n\n\tstartGapEqualsEndGap := startGap == endGap\n\n\tif (startGapEqualsEndGap && end <= startGap.Value.Start) ||\n\t\t(!startGapEqualsEndGap && startGap.Value.End >= endGap.Value.Start && end <= startGap.Value.Start) {\n\t\treturn errDuplicateStreamData\n\t}\n\n\tstartGapNext := startGap.Next()\n\tstartGapEnd := startGap.Value.End // save it, in case startGap is modified\n\tendGapStart := endGap.Value.Start // save it, in case endGap is modified\n\tendGapEnd := endGap.Value.End     // save it, in case endGap is modified\n\tvar adjustedStartGapEnd bool\n\tvar wasCut bool\n\n\tpos := start\n\tvar hasReplacedAtLeastOne bool\n\tfor {\n\t\toldEntry, ok := s.queue[pos]\n\t\tif !ok {\n\t\t\tbreak\n\t\t}\n\t\toldEntryLen := protocol.ByteCount(len(oldEntry.Data))\n\t\tif end-pos > oldEntryLen || (hasReplacedAtLeastOne && end-pos == oldEntryLen) {\n\t\t\t// The existing frame is shorter than the new frame. Replace it.\n\t\t\tdelete(s.queue, pos)\n\t\t\tpos += oldEntryLen\n\t\t\thasReplacedAtLeastOne = true\n\t\t\tif oldEntry.DoneCb != nil {\n\t\t\t\toldEntry.DoneCb()\n\t\t\t}\n\t\t} else {\n\t\t\tif !hasReplacedAtLeastOne {\n\t\t\t\treturn errDuplicateStreamData\n\t\t\t}\n\t\t\t// The existing frame is longer than the new frame.\n\t\t\t// Cut the new frame such that the end aligns with the start of the existing frame.\n\t\t\tdata = data[:pos-start]\n\t\t\tend = pos\n\t\t\twasCut = true\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif !startsInGap && !hasReplacedAtLeastOne {\n\t\t// cut the frame, such that it starts at the start of the gap\n\t\tdata = data[startGap.Value.Start-start:]\n\t\tstart = startGap.Value.Start\n\t\twasCut = true\n\t}\n\tif start <= startGap.Value.Start {\n\t\tif end >= startGap.Value.End {\n\t\t\t// The frame covers the whole startGap. Delete the gap.\n\t\t\ts.gaps.Remove(startGap)\n\t\t} else {\n\t\t\tstartGap.Value.Start = end\n\t\t}\n\t} else if !hasReplacedAtLeastOne {\n\t\tstartGap.Value.End = start\n\t\tadjustedStartGapEnd = true\n\t}\n\n\tif !startGapEqualsEndGap {\n\t\ts.deleteConsecutive(startGapEnd)\n\t\tvar nextGap *list.Element[byteInterval]\n\t\tfor gap := startGapNext; gap.Value.End < endGapStart; gap = nextGap {\n\t\t\tnextGap = gap.Next()\n\t\t\ts.deleteConsecutive(gap.Value.End)\n\t\t\ts.gaps.Remove(gap)\n\t\t}\n\t}\n\n\tif !endsInGap && start != endGapEnd && end > endGapEnd {\n\t\t// cut the frame, such that it ends at the end of the gap\n\t\tdata = data[:endGapEnd-start]\n\t\tend = endGapEnd\n\t\twasCut = true\n\t}\n\tif end == endGapEnd {\n\t\tif !startGapEqualsEndGap {\n\t\t\t// The frame covers the whole endGap. Delete the gap.\n\t\t\ts.gaps.Remove(endGap)\n\t\t}\n\t} else {\n\t\tif startGapEqualsEndGap && adjustedStartGapEnd {\n\t\t\t// The frame split the existing gap into two.\n\t\t\ts.gaps.InsertAfter(byteInterval{Start: end, End: startGapEnd}, startGap)\n\t\t} else if !startGapEqualsEndGap {\n\t\t\tendGap.Value.Start = end\n\t\t}\n\t}\n\n\tif wasCut && len(data) < protocol.MinStreamFrameBufferSize {\n\t\tnewData := make([]byte, len(data))\n\t\tcopy(newData, data)\n\t\tdata = newData\n\t\tif doneCb != nil {\n\t\t\tdoneCb()\n\t\t\tdoneCb = nil\n\t\t}\n\t}\n\n\tif s.gaps.Len() > protocol.MaxStreamFrameSorterGaps {\n\t\treturn errors.New(\"too many gaps in received data\")\n\t}\n\n\ts.queue[start] = frameSorterEntry{Data: data, DoneCb: doneCb}\n\treturn nil\n}\n\nfunc (s *frameSorter) findStartGap(offset protocol.ByteCount) (*list.Element[byteInterval], bool) {\n\tfor gap := s.gaps.Front(); gap != nil; gap = gap.Next() {\n\t\tif offset >= gap.Value.Start && offset <= gap.Value.End {\n\t\t\treturn gap, true\n\t\t}\n\t\tif offset < gap.Value.Start {\n\t\t\treturn gap, false\n\t\t}\n\t}\n\tpanic(\"no gap found\")\n}\n\nfunc (s *frameSorter) findEndGap(startGap *list.Element[byteInterval], offset protocol.ByteCount) (*list.Element[byteInterval], bool) {\n\tfor gap := startGap; gap != nil; gap = gap.Next() {\n\t\tif offset >= gap.Value.Start && offset < gap.Value.End {\n\t\t\treturn gap, true\n\t\t}\n\t\tif offset < gap.Value.Start {\n\t\t\treturn gap.Prev(), false\n\t\t}\n\t}\n\tpanic(\"no gap found\")\n}\n\n// deleteConsecutive deletes consecutive frames from the queue, starting at pos\nfunc (s *frameSorter) deleteConsecutive(pos protocol.ByteCount) {\n\tfor {\n\t\toldEntry, ok := s.queue[pos]\n\t\tif !ok {\n\t\t\tbreak\n\t\t}\n\t\toldEntryLen := protocol.ByteCount(len(oldEntry.Data))\n\t\tdelete(s.queue, pos)\n\t\tif oldEntry.DoneCb != nil {\n\t\t\toldEntry.DoneCb()\n\t\t}\n\t\tpos += oldEntryLen\n\t}\n}\n\nfunc (s *frameSorter) Pop() (protocol.ByteCount, []byte, func()) {\n\tentry, ok := s.queue[s.readPos]\n\tif !ok {\n\t\treturn s.readPos, nil, nil\n\t}\n\tdelete(s.queue, s.readPos)\n\toffset := s.readPos\n\ts.readPos += protocol.ByteCount(len(entry.Data))\n\tif s.gaps.Front().Value.End <= s.readPos {\n\t\tpanic(\"frame sorter BUG: read position higher than a gap\")\n\t}\n\treturn offset, entry.Data, entry.DoneCb\n}\n\n// HasMoreData says if there is any more data queued at *any* offset.\nfunc (s *frameSorter) HasMoreData() bool {\n\treturn len(s.queue) > 0\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/framer.go",
    "content": "package quic\n\nimport (\n\t\"slices\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/ackhandler\"\n\t\"github.com/quic-go/quic-go/internal/flowcontrol\"\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils/ringbuffer\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\nconst (\n\tmaxPathResponses = 256\n\tmaxControlFrames = 16 << 10\n)\n\n// This is the largest possible size of a stream-related control frame\n// (which is the RESET_STREAM frame).\nconst maxStreamControlFrameSize = 25\n\ntype streamControlFrameGetter interface {\n\tgetControlFrame(time.Time) (_ ackhandler.Frame, ok, hasMore bool)\n}\n\ntype framer struct {\n\tmutex sync.Mutex\n\n\tactiveStreams            map[protocol.StreamID]sendStreamI\n\tstreamQueue              ringbuffer.RingBuffer[protocol.StreamID]\n\tstreamsWithControlFrames map[protocol.StreamID]streamControlFrameGetter\n\n\tcontrolFrameMutex          sync.Mutex\n\tcontrolFrames              []wire.Frame\n\tpathResponses              []*wire.PathResponseFrame\n\tconnFlowController         flowcontrol.ConnectionFlowController\n\tqueuedTooManyControlFrames bool\n}\n\nfunc newFramer(connFlowController flowcontrol.ConnectionFlowController) *framer {\n\treturn &framer{\n\t\tactiveStreams:            make(map[protocol.StreamID]sendStreamI),\n\t\tstreamsWithControlFrames: make(map[protocol.StreamID]streamControlFrameGetter),\n\t\tconnFlowController:       connFlowController,\n\t}\n}\n\nfunc (f *framer) HasData() bool {\n\tf.mutex.Lock()\n\thasData := !f.streamQueue.Empty()\n\tf.mutex.Unlock()\n\tif hasData {\n\t\treturn true\n\t}\n\tf.controlFrameMutex.Lock()\n\tdefer f.controlFrameMutex.Unlock()\n\treturn len(f.streamsWithControlFrames) > 0 || len(f.controlFrames) > 0 || len(f.pathResponses) > 0\n}\n\nfunc (f *framer) QueueControlFrame(frame wire.Frame) {\n\tf.controlFrameMutex.Lock()\n\tdefer f.controlFrameMutex.Unlock()\n\n\tif pr, ok := frame.(*wire.PathResponseFrame); ok {\n\t\t// Only queue up to maxPathResponses PATH_RESPONSE frames.\n\t\t// This limit should be high enough to never be hit in practice,\n\t\t// unless the peer is doing something malicious.\n\t\tif len(f.pathResponses) >= maxPathResponses {\n\t\t\treturn\n\t\t}\n\t\tf.pathResponses = append(f.pathResponses, pr)\n\t\treturn\n\t}\n\t// This is a hack.\n\tif len(f.controlFrames) >= maxControlFrames {\n\t\tf.queuedTooManyControlFrames = true\n\t\treturn\n\t}\n\tf.controlFrames = append(f.controlFrames, frame)\n}\n\nfunc (f *framer) Append(\n\tframes []ackhandler.Frame,\n\tstreamFrames []ackhandler.StreamFrame,\n\tmaxLen protocol.ByteCount,\n\tnow time.Time,\n\tv protocol.Version,\n) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount) {\n\tf.controlFrameMutex.Lock()\n\tframes, controlFrameLen := f.appendControlFrames(frames, maxLen, now, v)\n\tmaxLen -= controlFrameLen\n\n\tvar lastFrame ackhandler.StreamFrame\n\tvar streamFrameLen protocol.ByteCount\n\tf.mutex.Lock()\n\t// pop STREAM frames, until less than 128 bytes are left in the packet\n\tnumActiveStreams := f.streamQueue.Len()\n\tfor i := 0; i < numActiveStreams; i++ {\n\t\tif protocol.MinStreamFrameSize > maxLen {\n\t\t\tbreak\n\t\t}\n\t\tsf, blocked := f.getNextStreamFrame(maxLen, v)\n\t\tif sf.Frame != nil {\n\t\t\tstreamFrames = append(streamFrames, sf)\n\t\t\tmaxLen -= sf.Frame.Length(v)\n\t\t\tlastFrame = sf\n\t\t\tstreamFrameLen += sf.Frame.Length(v)\n\t\t}\n\t\t// If the stream just became blocked on stream flow control, attempt to pack the\n\t\t// STREAM_DATA_BLOCKED into the same packet.\n\t\tif blocked != nil {\n\t\t\tl := blocked.Length(v)\n\t\t\t// In case it doesn't fit, queue it for the next packet.\n\t\t\tif maxLen < l {\n\t\t\t\tf.controlFrames = append(f.controlFrames, blocked)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tframes = append(frames, ackhandler.Frame{Frame: blocked})\n\t\t\tmaxLen -= l\n\t\t\tcontrolFrameLen += l\n\t\t}\n\t}\n\n\t// The only way to become blocked on connection-level flow control is by sending STREAM frames.\n\tif isBlocked, offset := f.connFlowController.IsNewlyBlocked(); isBlocked {\n\t\tblocked := &wire.DataBlockedFrame{MaximumData: offset}\n\t\tl := blocked.Length(v)\n\t\t// In case it doesn't fit, queue it for the next packet.\n\t\tif maxLen >= l {\n\t\t\tframes = append(frames, ackhandler.Frame{Frame: blocked})\n\t\t\tcontrolFrameLen += l\n\t\t} else {\n\t\t\tf.controlFrames = append(f.controlFrames, blocked)\n\t\t}\n\t}\n\n\tf.mutex.Unlock()\n\tf.controlFrameMutex.Unlock()\n\n\tif lastFrame.Frame != nil {\n\t\t// account for the smaller size of the last STREAM frame\n\t\tstreamFrameLen -= lastFrame.Frame.Length(v)\n\t\tlastFrame.Frame.DataLenPresent = false\n\t\tstreamFrameLen += lastFrame.Frame.Length(v)\n\t}\n\n\treturn frames, streamFrames, controlFrameLen + streamFrameLen\n}\n\nfunc (f *framer) appendControlFrames(\n\tframes []ackhandler.Frame,\n\tmaxLen protocol.ByteCount,\n\tnow time.Time,\n\tv protocol.Version,\n) ([]ackhandler.Frame, protocol.ByteCount) {\n\tvar length protocol.ByteCount\n\t// add a PATH_RESPONSE first, but only pack a single PATH_RESPONSE per packet\n\tif len(f.pathResponses) > 0 {\n\t\tframe := f.pathResponses[0]\n\t\tframeLen := frame.Length(v)\n\t\tif frameLen <= maxLen {\n\t\t\tframes = append(frames, ackhandler.Frame{Frame: frame})\n\t\t\tlength += frameLen\n\t\t\tf.pathResponses = f.pathResponses[1:]\n\t\t}\n\t}\n\n\t// add stream-related control frames\n\tfor id, str := range f.streamsWithControlFrames {\n\tstart:\n\t\tremainingLen := maxLen - length\n\t\tif remainingLen <= maxStreamControlFrameSize {\n\t\t\tbreak\n\t\t}\n\t\tfr, ok, hasMore := str.getControlFrame(now)\n\t\tif !hasMore {\n\t\t\tdelete(f.streamsWithControlFrames, id)\n\t\t}\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tframes = append(frames, fr)\n\t\tlength += fr.Frame.Length(v)\n\t\tif hasMore {\n\t\t\t// It is rare that a stream has more than one control frame to queue.\n\t\t\t// We don't want to spawn another loop for just to cover that case.\n\t\t\tgoto start\n\t\t}\n\t}\n\n\tfor len(f.controlFrames) > 0 {\n\t\tframe := f.controlFrames[len(f.controlFrames)-1]\n\t\tframeLen := frame.Length(v)\n\t\tif length+frameLen > maxLen {\n\t\t\tbreak\n\t\t}\n\t\tframes = append(frames, ackhandler.Frame{Frame: frame})\n\t\tlength += frameLen\n\t\tf.controlFrames = f.controlFrames[:len(f.controlFrames)-1]\n\t}\n\n\treturn frames, length\n}\n\n// QueuedTooManyControlFrames says if the control frame queue exceeded its maximum queue length.\n// This is a hack.\n// It is easier to implement than propagating an error return value in QueueControlFrame.\n// The correct solution would be to queue frames with their respective structs.\n// See https://github.com/quic-go/quic-go/issues/4271 for the queueing of stream-related control frames.\nfunc (f *framer) QueuedTooManyControlFrames() bool {\n\treturn f.queuedTooManyControlFrames\n}\n\nfunc (f *framer) AddActiveStream(id protocol.StreamID, str sendStreamI) {\n\tf.mutex.Lock()\n\tif _, ok := f.activeStreams[id]; !ok {\n\t\tf.streamQueue.PushBack(id)\n\t\tf.activeStreams[id] = str\n\t}\n\tf.mutex.Unlock()\n}\n\nfunc (f *framer) AddStreamWithControlFrames(id protocol.StreamID, str streamControlFrameGetter) {\n\tf.controlFrameMutex.Lock()\n\tif _, ok := f.streamsWithControlFrames[id]; !ok {\n\t\tf.streamsWithControlFrames[id] = str\n\t}\n\tf.controlFrameMutex.Unlock()\n}\n\n// RemoveActiveStream is called when a stream completes.\nfunc (f *framer) RemoveActiveStream(id protocol.StreamID) {\n\tf.mutex.Lock()\n\tdelete(f.activeStreams, id)\n\t// We don't delete the stream from the streamQueue,\n\t// since we'd have to iterate over the ringbuffer.\n\t// Instead, we check if the stream is still in activeStreams when appending STREAM frames.\n\tf.mutex.Unlock()\n}\n\nfunc (f *framer) getNextStreamFrame(maxLen protocol.ByteCount, v protocol.Version) (ackhandler.StreamFrame, *wire.StreamDataBlockedFrame) {\n\tid := f.streamQueue.PopFront()\n\t// This should never return an error. Better check it anyway.\n\t// The stream will only be in the streamQueue, if it enqueued itself there.\n\tstr, ok := f.activeStreams[id]\n\t// The stream might have been removed after being enqueued.\n\tif !ok {\n\t\treturn ackhandler.StreamFrame{}, nil\n\t}\n\t// For the last STREAM frame, we'll remove the DataLen field later.\n\t// Therefore, we can pretend to have more bytes available when popping\n\t// the STREAM frame (which will always have the DataLen set).\n\tmaxLen += protocol.ByteCount(quicvarint.Len(uint64(maxLen)))\n\tframe, blocked, hasMoreData := str.popStreamFrame(maxLen, v)\n\tif hasMoreData { // put the stream back in the queue (at the end)\n\t\tf.streamQueue.PushBack(id)\n\t} else { // no more data to send. Stream is not active\n\t\tdelete(f.activeStreams, id)\n\t}\n\t// Note that the frame.Frame can be nil:\n\t// * if the stream was canceled after it said it had data\n\t// * the remaining size doesn't allow us to add another STREAM frame\n\treturn frame, blocked\n}\n\nfunc (f *framer) Handle0RTTRejection() {\n\tf.mutex.Lock()\n\tdefer f.mutex.Unlock()\n\tf.controlFrameMutex.Lock()\n\tdefer f.controlFrameMutex.Unlock()\n\n\tf.streamQueue.Clear()\n\tfor id := range f.activeStreams {\n\t\tdelete(f.activeStreams, id)\n\t}\n\tvar j int\n\tfor i, frame := range f.controlFrames {\n\t\tswitch frame.(type) {\n\t\tcase *wire.MaxDataFrame, *wire.MaxStreamDataFrame, *wire.MaxStreamsFrame,\n\t\t\t*wire.DataBlockedFrame, *wire.StreamDataBlockedFrame, *wire.StreamsBlockedFrame:\n\t\t\tcontinue\n\t\tdefault:\n\t\t\tf.controlFrames[j] = f.controlFrames[i]\n\t\t\tj++\n\t\t}\n\t}\n\tf.controlFrames = slices.Delete(f.controlFrames, j, len(f.controlFrames))\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/interface.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/handshake\"\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/logging\"\n)\n\n// The StreamID is the ID of a QUIC stream.\ntype StreamID = protocol.StreamID\n\n// A Version is a QUIC version number.\ntype Version = protocol.Version\n\nconst (\n\t// Version1 is RFC 9000\n\tVersion1 = protocol.Version1\n\t// Version2 is RFC 9369\n\tVersion2 = protocol.Version2\n)\n\n// A ClientToken is a token received by the client.\n// It can be used to skip address validation on future connection attempts.\ntype ClientToken struct {\n\tdata []byte\n}\n\ntype TokenStore interface {\n\t// Pop searches for a ClientToken associated with the given key.\n\t// Since tokens are not supposed to be reused, it must remove the token from the cache.\n\t// It returns nil when no token is found.\n\tPop(key string) (token *ClientToken)\n\n\t// Put adds a token to the cache with the given key. It might get called\n\t// multiple times in a connection.\n\tPut(key string, token *ClientToken)\n}\n\n// Err0RTTRejected is the returned from:\n//   - Open{Uni}Stream{Sync}\n//   - Accept{Uni}Stream\n//   - Stream.Read and Stream.Write\n//\n// when the server rejects a 0-RTT connection attempt.\nvar Err0RTTRejected = errors.New(\"0-RTT rejected\")\n\n// ConnectionTracingKey can be used to associate a [logging.ConnectionTracer] with a [Connection].\n// It is set on the Connection.Context() context,\n// as well as on the context passed to logging.Tracer.NewConnectionTracer.\n//\n// Deprecated: Applications can set their own tracing key using Transport.ConnContext.\nvar ConnectionTracingKey = connTracingCtxKey{}\n\n// ConnectionTracingID is the type of the context value saved under the ConnectionTracingKey.\n//\n// Deprecated: Applications can set their own tracing key using Transport.ConnContext.\ntype ConnectionTracingID uint64\n\ntype connTracingCtxKey struct{}\n\n// QUICVersionContextKey can be used to find out the QUIC version of a TLS handshake from the\n// context returned by tls.Config.ClientInfo.Context.\nvar QUICVersionContextKey = handshake.QUICVersionContextKey\n\n// Stream is the interface implemented by QUIC streams.\n// In addition to the errors listed on the [Connection],\n// calls to stream functions can return a [StreamError] if the stream is canceled.\ntype Stream interface {\n\tReceiveStream\n\tSendStream\n\t// SetDeadline sets the read and write deadlines associated\n\t// with the connection. It is equivalent to calling both\n\t// SetReadDeadline and SetWriteDeadline.\n\tSetDeadline(t time.Time) error\n}\n\n// A ReceiveStream is a unidirectional Receive Stream.\ntype ReceiveStream interface {\n\t// StreamID returns the stream ID.\n\tStreamID() StreamID\n\t// Read reads data from the stream.\n\t// Read can be made to time out using SetDeadline and SetReadDeadline.\n\t// If the stream was canceled, the error is a StreamError.\n\tio.Reader\n\t// CancelRead aborts receiving on this stream.\n\t// It will ask the peer to stop transmitting stream data.\n\t// Read will unblock immediately, and future Read calls will fail.\n\t// When called multiple times or after reading the io.EOF it is a no-op.\n\tCancelRead(StreamErrorCode)\n\t// SetReadDeadline sets the deadline for future Read calls and\n\t// any currently-blocked Read call.\n\t// A zero value for t means Read will not time out.\n\tSetReadDeadline(t time.Time) error\n}\n\n// A SendStream is a unidirectional Send Stream.\ntype SendStream interface {\n\t// StreamID returns the stream ID.\n\tStreamID() StreamID\n\t// Write writes data to the stream.\n\t// Write can be made to time out using SetDeadline and SetWriteDeadline.\n\t// If the stream was canceled, the error is a StreamError.\n\tio.Writer\n\t// Close closes the write-direction of the stream.\n\t// Future calls to Write are not permitted after calling Close.\n\t// It must not be called concurrently with Write.\n\t// It must not be called after calling CancelWrite.\n\tio.Closer\n\t// CancelWrite aborts sending on this stream.\n\t// Data already written, but not yet delivered to the peer is not guaranteed to be delivered reliably.\n\t// Write will unblock immediately, and future calls to Write will fail.\n\t// When called multiple times it is a no-op.\n\t// When called after Close, it aborts delivery. Note that there is no guarantee if\n\t// the peer will receive the FIN or the reset first.\n\tCancelWrite(StreamErrorCode)\n\t// The Context is canceled as soon as the write-side of the stream is closed.\n\t// This happens when Close() or CancelWrite() is called, or when the peer\n\t// cancels the read-side of their stream.\n\t// The cancellation cause is set to the error that caused the stream to\n\t// close, or `context.Canceled` in case the stream is closed without error.\n\tContext() context.Context\n\t// SetWriteDeadline sets the deadline for future Write calls\n\t// and any currently-blocked Write call.\n\t// Even if write times out, it may return n > 0, indicating that\n\t// some data was successfully written.\n\t// A zero value for t means Write will not time out.\n\tSetWriteDeadline(t time.Time) error\n}\n\n// A Connection is a QUIC connection between two peers.\n// Calls to the connection (and to streams) can return the following types of errors:\n//   - [ApplicationError]: for errors triggered by the application running on top of QUIC\n//   - [TransportError]: for errors triggered by the QUIC transport (in many cases a misbehaving peer)\n//   - [IdleTimeoutError]: when the peer goes away unexpectedly (this is a [net.Error] timeout error)\n//   - [HandshakeTimeoutError]: when the cryptographic handshake takes too long (this is a [net.Error] timeout error)\n//   - [StatelessResetError]: when we receive a stateless reset\n//   - [VersionNegotiationError]: returned by the client, when there's no version overlap between the peers\ntype Connection interface {\n\t// AcceptStream returns the next stream opened by the peer, blocking until one is available.\n\tAcceptStream(context.Context) (Stream, error)\n\t// AcceptUniStream returns the next unidirectional stream opened by the peer, blocking until one is available.\n\tAcceptUniStream(context.Context) (ReceiveStream, error)\n\t// OpenStream opens a new bidirectional QUIC stream.\n\t// There is no signaling to the peer about new streams:\n\t// The peer can only accept the stream after data has been sent on the stream,\n\t// or the stream has been reset or closed.\n\t// When reaching the peer's stream limit, it is not possible to open a new stream until the\n\t// peer raises the stream limit. In that case, a StreamLimitReachedError is returned.\n\tOpenStream() (Stream, error)\n\t// OpenStreamSync opens a new bidirectional QUIC stream.\n\t// It blocks until a new stream can be opened.\n\t// There is no signaling to the peer about new streams:\n\t// The peer can only accept the stream after data has been sent on the stream,\n\t// or the stream has been reset or closed.\n\tOpenStreamSync(context.Context) (Stream, error)\n\t// OpenUniStream opens a new outgoing unidirectional QUIC stream.\n\t// There is no signaling to the peer about new streams:\n\t// The peer can only accept the stream after data has been sent on the stream,\n\t// or the stream has been reset or closed.\n\t// When reaching the peer's stream limit, it is not possible to open a new stream until the\n\t// peer raises the stream limit. In that case, a StreamLimitReachedError is returned.\n\tOpenUniStream() (SendStream, error)\n\t// OpenUniStreamSync opens a new outgoing unidirectional QUIC stream.\n\t// It blocks until a new stream can be opened.\n\t// There is no signaling to the peer about new streams:\n\t// The peer can only accept the stream after data has been sent on the stream,\n\t// or the stream has been reset or closed.\n\tOpenUniStreamSync(context.Context) (SendStream, error)\n\t// LocalAddr returns the local address.\n\tLocalAddr() net.Addr\n\t// RemoteAddr returns the address of the peer.\n\tRemoteAddr() net.Addr\n\t// CloseWithError closes the connection with an error.\n\t// The error string will be sent to the peer.\n\tCloseWithError(ApplicationErrorCode, string) error\n\t// Context returns a context that is cancelled when the connection is closed.\n\t// The cancellation cause is set to the error that caused the connection to\n\t// close, or `context.Canceled` in case the listener is closed first.\n\tContext() context.Context\n\t// ConnectionState returns basic details about the QUIC connection.\n\t// Warning: This API should not be considered stable and might change soon.\n\tConnectionState() ConnectionState\n\n\t// SendDatagram sends a message using a QUIC datagram, as specified in RFC 9221.\n\t// There is no delivery guarantee for DATAGRAM frames, they are not retransmitted if lost.\n\t// The payload of the datagram needs to fit into a single QUIC packet.\n\t// In addition, a datagram may be dropped before being sent out if the available packet size suddenly decreases.\n\t// If the payload is too large to be sent at the current time, a DatagramTooLargeError is returned.\n\tSendDatagram(payload []byte) error\n\t// ReceiveDatagram gets a message received in a datagram, as specified in RFC 9221.\n\tReceiveDatagram(context.Context) ([]byte, error)\n\n\tAddPath(*Transport) (*Path, error)\n}\n\n// An EarlyConnection is a connection that is handshaking.\n// Data sent during the handshake is encrypted using the forward secure keys.\n// When using client certificates, the client's identity is only verified\n// after completion of the handshake.\ntype EarlyConnection interface {\n\tConnection\n\n\t// HandshakeComplete blocks until the handshake completes (or fails).\n\t// For the client, data sent before completion of the handshake is encrypted with 0-RTT keys.\n\t// For the server, data sent before completion of the handshake is encrypted with 1-RTT keys,\n\t// however the client's identity is only verified once the handshake completes.\n\tHandshakeComplete() <-chan struct{}\n\n\tNextConnection(context.Context) (Connection, error)\n}\n\n// StatelessResetKey is a key used to derive stateless reset tokens.\ntype StatelessResetKey [32]byte\n\n// TokenGeneratorKey is a key used to encrypt session resumption tokens.\ntype TokenGeneratorKey = handshake.TokenProtectorKey\n\n// A ConnectionID is a QUIC Connection ID, as defined in RFC 9000.\n// It is not able to handle QUIC Connection IDs longer than 20 bytes,\n// as they are allowed by RFC 8999.\ntype ConnectionID = protocol.ConnectionID\n\n// ConnectionIDFromBytes interprets b as a [ConnectionID]. It panics if b is\n// longer than 20 bytes.\nfunc ConnectionIDFromBytes(b []byte) ConnectionID {\n\treturn protocol.ParseConnectionID(b)\n}\n\n// A ConnectionIDGenerator allows the application to take control over the generation of Connection IDs.\n// Connection IDs generated by an implementation must be of constant length.\ntype ConnectionIDGenerator interface {\n\t// GenerateConnectionID generates a new Connection ID.\n\t// Generated Connection IDs must be unique and observers should not be able to correlate two Connection IDs.\n\tGenerateConnectionID() (ConnectionID, error)\n\n\t// ConnectionIDLen returns the length of Connection IDs generated by this implementation.\n\t// Implementations must return constant-length Connection IDs with lengths between 0 and 20 bytes.\n\t// A length of 0 can only be used when an endpoint doesn't need to multiplex connections during migration.\n\tConnectionIDLen() int\n}\n\n// Config contains all configuration data needed for a QUIC server or client.\ntype Config struct {\n\t// GetConfigForClient is called for incoming connections.\n\t// If the error is not nil, the connection attempt is refused.\n\tGetConfigForClient func(info *ClientInfo) (*Config, error)\n\t// The QUIC versions that can be negotiated.\n\t// If not set, it uses all versions available.\n\tVersions []Version\n\t// HandshakeIdleTimeout is the idle timeout before completion of the handshake.\n\t// If we don't receive any packet from the peer within this time, the connection attempt is aborted.\n\t// Additionally, if the handshake doesn't complete in twice this time, the connection attempt is also aborted.\n\t// If this value is zero, the timeout is set to 5 seconds.\n\tHandshakeIdleTimeout time.Duration\n\t// MaxIdleTimeout is the maximum duration that may pass without any incoming network activity.\n\t// The actual value for the idle timeout is the minimum of this value and the peer's.\n\t// This value only applies after the handshake has completed.\n\t// If the timeout is exceeded, the connection is closed.\n\t// If this value is zero, the timeout is set to 30 seconds.\n\tMaxIdleTimeout time.Duration\n\t// The TokenStore stores tokens received from the server.\n\t// Tokens are used to skip address validation on future connection attempts.\n\t// The key used to store tokens is the ServerName from the tls.Config, if set\n\t// otherwise the token is associated with the server's IP address.\n\tTokenStore TokenStore\n\t// InitialStreamReceiveWindow is the initial size of the stream-level flow control window for receiving data.\n\t// If the application is consuming data quickly enough, the flow control auto-tuning algorithm\n\t// will increase the window up to MaxStreamReceiveWindow.\n\t// If this value is zero, it will default to 512 KB.\n\t// Values larger than the maximum varint (quicvarint.Max) will be clipped to that value.\n\tInitialStreamReceiveWindow uint64\n\t// MaxStreamReceiveWindow is the maximum stream-level flow control window for receiving data.\n\t// If this value is zero, it will default to 6 MB.\n\t// Values larger than the maximum varint (quicvarint.Max) will be clipped to that value.\n\tMaxStreamReceiveWindow uint64\n\t// InitialConnectionReceiveWindow is the initial size of the stream-level flow control window for receiving data.\n\t// If the application is consuming data quickly enough, the flow control auto-tuning algorithm\n\t// will increase the window up to MaxConnectionReceiveWindow.\n\t// If this value is zero, it will default to 512 KB.\n\t// Values larger than the maximum varint (quicvarint.Max) will be clipped to that value.\n\tInitialConnectionReceiveWindow uint64\n\t// MaxConnectionReceiveWindow is the connection-level flow control window for receiving data.\n\t// If this value is zero, it will default to 15 MB.\n\t// Values larger than the maximum varint (quicvarint.Max) will be clipped to that value.\n\tMaxConnectionReceiveWindow uint64\n\t// AllowConnectionWindowIncrease is called every time the connection flow controller attempts\n\t// to increase the connection flow control window.\n\t// If set, the caller can prevent an increase of the window. Typically, it would do so to\n\t// limit the memory usage.\n\t// To avoid deadlocks, it is not valid to call other functions on the connection or on streams\n\t// in this callback.\n\tAllowConnectionWindowIncrease func(conn Connection, delta uint64) bool\n\t// MaxIncomingStreams is the maximum number of concurrent bidirectional streams that a peer is allowed to open.\n\t// If not set, it will default to 100.\n\t// If set to a negative value, it doesn't allow any bidirectional streams.\n\t// Values larger than 2^60 will be clipped to that value.\n\tMaxIncomingStreams int64\n\t// MaxIncomingUniStreams is the maximum number of concurrent unidirectional streams that a peer is allowed to open.\n\t// If not set, it will default to 100.\n\t// If set to a negative value, it doesn't allow any unidirectional streams.\n\t// Values larger than 2^60 will be clipped to that value.\n\tMaxIncomingUniStreams int64\n\t// KeepAlivePeriod defines whether this peer will periodically send a packet to keep the connection alive.\n\t// If set to 0, then no keep alive is sent. Otherwise, the keep alive is sent on that period (or at most\n\t// every half of MaxIdleTimeout, whichever is smaller).\n\tKeepAlivePeriod time.Duration\n\t// InitialPacketSize is the initial size (and the lower limit) for packets sent.\n\t// Under most circumstances, it is not necessary to manually set this value,\n\t// since path MTU discovery quickly finds the path's MTU.\n\t// If set too high, the path might not support packets of that size, leading to a timeout of the QUIC handshake.\n\t// Values below 1200 are invalid.\n\tInitialPacketSize uint16\n\t// DisablePathMTUDiscovery disables Path MTU Discovery (RFC 8899).\n\t// This allows the sending of QUIC packets that fully utilize the available MTU of the path.\n\t// Path MTU discovery is only available on systems that allow setting of the Don't Fragment (DF) bit.\n\tDisablePathMTUDiscovery bool\n\t// Allow0RTT allows the application to decide if a 0-RTT connection attempt should be accepted.\n\t// Only valid for the server.\n\tAllow0RTT bool\n\t// Enable QUIC datagram support (RFC 9221).\n\tEnableDatagrams bool\n\tTracer          func(context.Context, logging.Perspective, ConnectionID) *logging.ConnectionTracer\n}\n\n// ClientHelloInfo contains information about an incoming connection attempt.\n//\n// Deprecated: Use ClientInfo instead.\ntype ClientHelloInfo = ClientInfo\n\n// ClientInfo contains information about an incoming connection attempt.\ntype ClientInfo struct {\n\t// RemoteAddr is the remote address on the Initial packet.\n\t// Unless AddrVerified is set, the address is not yet verified, and could be a spoofed IP address.\n\tRemoteAddr net.Addr\n\t// AddrVerified says if the remote address was verified using QUIC's Retry mechanism.\n\t// Note that the Retry mechanism costs one network roundtrip,\n\t// and is not performed unless Transport.MaxUnvalidatedHandshakes is surpassed.\n\tAddrVerified bool\n}\n\n// ConnectionState records basic details about a QUIC connection.\ntype ConnectionState struct {\n\t// TLS contains information about the TLS connection state, incl. the tls.ConnectionState.\n\tTLS tls.ConnectionState\n\t// SupportsDatagrams indicates whether the peer advertised support for QUIC datagrams (RFC 9221).\n\t// When true, datagrams can be sent using the Connection's SendDatagram method.\n\t// This is a unilateral declaration by the peer - receiving datagrams is only possible if\n\t// datagram support was enabled locally via Config.EnableDatagrams.\n\tSupportsDatagrams bool\n\t// Used0RTT says if 0-RTT resumption was used.\n\tUsed0RTT bool\n\t// Version is the QUIC version of the QUIC connection.\n\tVersion Version\n\t// GSO says if generic segmentation offload is used.\n\tGSO bool\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/ackhandler/ack_eliciting.go",
    "content": "package ackhandler\n\nimport \"github.com/quic-go/quic-go/internal/wire\"\n\n// IsFrameAckEliciting returns true if the frame is ack-eliciting.\nfunc IsFrameAckEliciting(f wire.Frame) bool {\n\t_, isAck := f.(*wire.AckFrame)\n\t_, isConnectionClose := f.(*wire.ConnectionCloseFrame)\n\treturn !isAck && !isConnectionClose\n}\n\n// HasAckElicitingFrames returns true if at least one frame is ack-eliciting.\nfunc HasAckElicitingFrames(fs []Frame) bool {\n\tfor _, f := range fs {\n\t\tif IsFrameAckEliciting(f.Frame) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/ackhandler/ackhandler.go",
    "content": "package ackhandler\n\nimport (\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/logging\"\n)\n\n// NewAckHandler creates a new SentPacketHandler and a new ReceivedPacketHandler.\n// clientAddressValidated indicates whether the address was validated beforehand by an address validation token.\n// clientAddressValidated has no effect for a client.\nfunc NewAckHandler(\n\tinitialPacketNumber protocol.PacketNumber,\n\tinitialMaxDatagramSize protocol.ByteCount,\n\trttStats *utils.RTTStats,\n\tclientAddressValidated bool,\n\tenableECN bool,\n\tpers protocol.Perspective,\n\ttracer *logging.ConnectionTracer,\n\tlogger utils.Logger,\n) (SentPacketHandler, ReceivedPacketHandler) {\n\tsph := newSentPacketHandler(initialPacketNumber, initialMaxDatagramSize, rttStats, clientAddressValidated, enableECN, pers, tracer, logger)\n\treturn sph, newReceivedPacketHandler(sph, logger)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/ackhandler/ecn.go",
    "content": "package ackhandler\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/logging\"\n)\n\ntype ecnState uint8\n\nconst (\n\tecnStateInitial ecnState = iota\n\tecnStateTesting\n\tecnStateUnknown\n\tecnStateCapable\n\tecnStateFailed\n)\n\n// must fit into an uint8, otherwise numSentTesting and numLostTesting must have a larger type\nconst numECNTestingPackets = 10\n\ntype ecnHandler interface {\n\tSentPacket(protocol.PacketNumber, protocol.ECN)\n\tMode() protocol.ECN\n\tHandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64) (congested bool)\n\tLostPacket(protocol.PacketNumber)\n}\n\n// The ecnTracker performs ECN validation of a path.\n// Once failed, it doesn't do any re-validation of the path.\n// It is designed only work for 1-RTT packets, it doesn't handle multiple packet number spaces.\n// In order to avoid revealing any internal state to on-path observers,\n// callers should make sure to start using ECN (i.e. calling Mode) for the very first 1-RTT packet sent.\n// The validation logic implemented here strictly follows the algorithm described in RFC 9000 section 13.4.2 and A.4.\ntype ecnTracker struct {\n\tstate                          ecnState\n\tnumSentTesting, numLostTesting uint8\n\n\tfirstTestingPacket protocol.PacketNumber\n\tlastTestingPacket  protocol.PacketNumber\n\tfirstCapablePacket protocol.PacketNumber\n\n\tnumSentECT0, numSentECT1                  int64\n\tnumAckedECT0, numAckedECT1, numAckedECNCE int64\n\n\ttracer *logging.ConnectionTracer\n\tlogger utils.Logger\n}\n\nvar _ ecnHandler = &ecnTracker{}\n\nfunc newECNTracker(logger utils.Logger, tracer *logging.ConnectionTracer) *ecnTracker {\n\treturn &ecnTracker{\n\t\tfirstTestingPacket: protocol.InvalidPacketNumber,\n\t\tlastTestingPacket:  protocol.InvalidPacketNumber,\n\t\tfirstCapablePacket: protocol.InvalidPacketNumber,\n\t\tstate:              ecnStateInitial,\n\t\tlogger:             logger,\n\t\ttracer:             tracer,\n\t}\n}\n\nfunc (e *ecnTracker) SentPacket(pn protocol.PacketNumber, ecn protocol.ECN) {\n\t//nolint:exhaustive // These are the only ones we need to take care of.\n\tswitch ecn {\n\tcase protocol.ECNNon:\n\t\treturn\n\tcase protocol.ECT0:\n\t\te.numSentECT0++\n\tcase protocol.ECT1:\n\t\te.numSentECT1++\n\tcase protocol.ECNUnsupported:\n\t\tif e.state != ecnStateFailed {\n\t\t\tpanic(\"didn't expect ECN to be unsupported\")\n\t\t}\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"sent packet with unexpected ECN marking: %s\", ecn))\n\t}\n\n\tif e.state == ecnStateCapable && e.firstCapablePacket == protocol.InvalidPacketNumber {\n\t\te.firstCapablePacket = pn\n\t}\n\n\tif e.state != ecnStateTesting {\n\t\treturn\n\t}\n\n\te.numSentTesting++\n\tif e.firstTestingPacket == protocol.InvalidPacketNumber {\n\t\te.firstTestingPacket = pn\n\t}\n\tif e.numSentECT0+e.numSentECT1 >= numECNTestingPackets {\n\t\tif e.tracer != nil && e.tracer.ECNStateUpdated != nil {\n\t\t\te.tracer.ECNStateUpdated(logging.ECNStateUnknown, logging.ECNTriggerNoTrigger)\n\t\t}\n\t\te.state = ecnStateUnknown\n\t\te.lastTestingPacket = pn\n\t}\n}\n\nfunc (e *ecnTracker) Mode() protocol.ECN {\n\tswitch e.state {\n\tcase ecnStateInitial:\n\t\tif e.tracer != nil && e.tracer.ECNStateUpdated != nil {\n\t\t\te.tracer.ECNStateUpdated(logging.ECNStateTesting, logging.ECNTriggerNoTrigger)\n\t\t}\n\t\te.state = ecnStateTesting\n\t\treturn e.Mode()\n\tcase ecnStateTesting, ecnStateCapable:\n\t\treturn protocol.ECT0\n\tcase ecnStateUnknown, ecnStateFailed:\n\t\treturn protocol.ECNNon\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unknown ECN state: %d\", e.state))\n\t}\n}\n\nfunc (e *ecnTracker) LostPacket(pn protocol.PacketNumber) {\n\tif e.state != ecnStateTesting && e.state != ecnStateUnknown {\n\t\treturn\n\t}\n\tif !e.isTestingPacket(pn) {\n\t\treturn\n\t}\n\te.numLostTesting++\n\t// Only proceed if we have sent all 10 testing packets.\n\tif e.state != ecnStateUnknown {\n\t\treturn\n\t}\n\tif e.numLostTesting >= e.numSentTesting {\n\t\te.logger.Debugf(\"Disabling ECN. All testing packets were lost.\")\n\t\tif e.tracer != nil && e.tracer.ECNStateUpdated != nil {\n\t\t\te.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedLostAllTestingPackets)\n\t\t}\n\t\te.state = ecnStateFailed\n\t\treturn\n\t}\n\t// Path validation also fails if some testing packets are lost, and all other testing packets where CE-marked\n\te.failIfMangled()\n}\n\n// HandleNewlyAcked handles the ECN counts on an ACK frame.\n// It must only be called for ACK frames that increase the largest acknowledged packet number,\n// see section 13.4.2.1 of RFC 9000.\nfunc (e *ecnTracker) HandleNewlyAcked(packets []*packet, ect0, ect1, ecnce int64) (congested bool) {\n\tif e.state == ecnStateFailed {\n\t\treturn false\n\t}\n\n\t// ECN validation can fail if the received total count for either ECT(0) or ECT(1) exceeds\n\t// the total number of packets sent with each corresponding ECT codepoint.\n\tif ect0 > e.numSentECT0 || ect1 > e.numSentECT1 {\n\t\te.logger.Debugf(\"Disabling ECN. Received more ECT(0) / ECT(1) acknowledgements than packets sent.\")\n\t\tif e.tracer != nil && e.tracer.ECNStateUpdated != nil {\n\t\t\te.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedMoreECNCountsThanSent)\n\t\t}\n\t\te.state = ecnStateFailed\n\t\treturn false\n\t}\n\n\t// Count ECT0 and ECT1 marks that we used when sending the packets that are now being acknowledged.\n\tvar ackedECT0, ackedECT1 int64\n\tfor _, p := range packets {\n\t\t//nolint:exhaustive // We only ever send ECT(0) and ECT(1).\n\t\tswitch e.ecnMarking(p.PacketNumber) {\n\t\tcase protocol.ECT0:\n\t\t\tackedECT0++\n\t\tcase protocol.ECT1:\n\t\t\tackedECT1++\n\t\t}\n\t}\n\n\t// If an ACK frame newly acknowledges a packet that the endpoint sent with either the ECT(0) or ECT(1)\n\t// codepoint set, ECN validation fails if the corresponding ECN counts are not present in the ACK frame.\n\t// This check detects:\n\t// * paths that bleach all ECN marks, and\n\t// * peers that don't report any ECN counts\n\tif (ackedECT0 > 0 || ackedECT1 > 0) && ect0 == 0 && ect1 == 0 && ecnce == 0 {\n\t\te.logger.Debugf(\"Disabling ECN. ECN-marked packet acknowledged, but no ECN counts on ACK frame.\")\n\t\tif e.tracer != nil && e.tracer.ECNStateUpdated != nil {\n\t\t\te.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedNoECNCounts)\n\t\t}\n\t\te.state = ecnStateFailed\n\t\treturn false\n\t}\n\n\t// Determine the increase in ECT0, ECT1 and ECNCE marks\n\tnewECT0 := ect0 - e.numAckedECT0\n\tnewECT1 := ect1 - e.numAckedECT1\n\tnewECNCE := ecnce - e.numAckedECNCE\n\n\t// We're only processing ACKs that increase the Largest Acked.\n\t// Therefore, the ECN counters should only ever increase.\n\t// Any decrease means that the peer's counting logic is broken.\n\tif newECT0 < 0 || newECT1 < 0 || newECNCE < 0 {\n\t\te.logger.Debugf(\"Disabling ECN. ECN counts decreased unexpectedly.\")\n\t\tif e.tracer != nil && e.tracer.ECNStateUpdated != nil {\n\t\t\te.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedDecreasedECNCounts)\n\t\t}\n\t\te.state = ecnStateFailed\n\t\treturn false\n\t}\n\n\t// ECN validation also fails if the sum of the increase in ECT(0) and ECN-CE counts is less than the number\n\t// of newly acknowledged packets that were originally sent with an ECT(0) marking.\n\t// This could be the result of (partial) bleaching.\n\tif newECT0+newECNCE < ackedECT0 {\n\t\te.logger.Debugf(\"Disabling ECN. Received less ECT(0) + ECN-CE than packets sent with ECT(0).\")\n\t\tif e.tracer != nil && e.tracer.ECNStateUpdated != nil {\n\t\t\te.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedTooFewECNCounts)\n\t\t}\n\t\te.state = ecnStateFailed\n\t\treturn false\n\t}\n\t// Similarly, ECN validation fails if the sum of the increases to ECT(1) and ECN-CE counts is less than\n\t// the number of newly acknowledged packets sent with an ECT(1) marking.\n\tif newECT1+newECNCE < ackedECT1 {\n\t\te.logger.Debugf(\"Disabling ECN. Received less ECT(1) + ECN-CE than packets sent with ECT(1).\")\n\t\tif e.tracer != nil && e.tracer.ECNStateUpdated != nil {\n\t\t\te.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedTooFewECNCounts)\n\t\t}\n\t\te.state = ecnStateFailed\n\t\treturn false\n\t}\n\n\t// update our counters\n\te.numAckedECT0 = ect0\n\te.numAckedECT1 = ect1\n\te.numAckedECNCE = ecnce\n\n\t// Detect mangling (a path remarking all ECN-marked testing packets as CE),\n\t// once all 10 testing packets have been sent out.\n\tif e.state == ecnStateUnknown {\n\t\te.failIfMangled()\n\t\tif e.state == ecnStateFailed {\n\t\t\treturn false\n\t\t}\n\t}\n\tif e.state == ecnStateTesting || e.state == ecnStateUnknown {\n\t\tvar ackedTestingPacket bool\n\t\tfor _, p := range packets {\n\t\t\tif e.isTestingPacket(p.PacketNumber) {\n\t\t\t\tackedTestingPacket = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\t// This check won't succeed if the path is mangling ECN-marks (i.e. rewrites all ECN-marked packets to CE).\n\t\tif ackedTestingPacket && (newECT0 > 0 || newECT1 > 0) {\n\t\t\te.logger.Debugf(\"ECN capability confirmed.\")\n\t\t\tif e.tracer != nil && e.tracer.ECNStateUpdated != nil {\n\t\t\t\te.tracer.ECNStateUpdated(logging.ECNStateCapable, logging.ECNTriggerNoTrigger)\n\t\t\t}\n\t\t\te.state = ecnStateCapable\n\t\t}\n\t}\n\n\t// Don't trust CE marks before having confirmed ECN capability of the path.\n\t// Otherwise, mangling would be misinterpreted as actual congestion.\n\treturn e.state == ecnStateCapable && newECNCE > 0\n}\n\n// failIfMangled fails ECN validation if all testing packets are lost or CE-marked.\nfunc (e *ecnTracker) failIfMangled() {\n\tnumAckedECNCE := e.numAckedECNCE + int64(e.numLostTesting)\n\tif e.numSentECT0+e.numSentECT1 > numAckedECNCE {\n\t\treturn\n\t}\n\tif e.tracer != nil && e.tracer.ECNStateUpdated != nil {\n\t\te.tracer.ECNStateUpdated(logging.ECNStateFailed, logging.ECNFailedManglingDetected)\n\t}\n\te.state = ecnStateFailed\n}\n\nfunc (e *ecnTracker) ecnMarking(pn protocol.PacketNumber) protocol.ECN {\n\tif pn < e.firstTestingPacket || e.firstTestingPacket == protocol.InvalidPacketNumber {\n\t\treturn protocol.ECNNon\n\t}\n\tif pn < e.lastTestingPacket || e.lastTestingPacket == protocol.InvalidPacketNumber {\n\t\treturn protocol.ECT0\n\t}\n\tif pn < e.firstCapablePacket || e.firstCapablePacket == protocol.InvalidPacketNumber {\n\t\treturn protocol.ECNNon\n\t}\n\t// We don't need to deal with the case when ECN validation fails,\n\t// since we're ignoring any ECN counts reported in ACK frames in that case.\n\treturn protocol.ECT0\n}\n\nfunc (e *ecnTracker) isTestingPacket(pn protocol.PacketNumber) bool {\n\tif e.firstTestingPacket == protocol.InvalidPacketNumber {\n\t\treturn false\n\t}\n\treturn pn >= e.firstTestingPacket && (pn <= e.lastTestingPacket || e.lastTestingPacket == protocol.InvalidPacketNumber)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/ackhandler/frame.go",
    "content": "package ackhandler\n\nimport (\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\n// FrameHandler handles the acknowledgement and the loss of a frame.\ntype FrameHandler interface {\n\tOnAcked(wire.Frame)\n\tOnLost(wire.Frame)\n}\n\ntype Frame struct {\n\tFrame   wire.Frame // nil if the frame has already been acknowledged in another packet\n\tHandler FrameHandler\n}\n\ntype StreamFrame struct {\n\tFrame   *wire.StreamFrame\n\tHandler FrameHandler\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/ackhandler/interfaces.go",
    "content": "package ackhandler\n\nimport (\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\n// SentPacketHandler handles ACKs received for outgoing packets\ntype SentPacketHandler interface {\n\t// SentPacket may modify the packet\n\tSentPacket(t time.Time, pn, largestAcked protocol.PacketNumber, streamFrames []StreamFrame, frames []Frame, encLevel protocol.EncryptionLevel, ecn protocol.ECN, size protocol.ByteCount, isPathMTUProbePacket, isPathProbePacket bool)\n\t// ReceivedAck processes an ACK frame.\n\t// It does not store a copy of the frame.\n\tReceivedAck(f *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) (bool /* 1-RTT packet acked */, error)\n\tReceivedBytes(_ protocol.ByteCount, rcvTime time.Time)\n\tDropPackets(_ protocol.EncryptionLevel, rcvTime time.Time)\n\tResetForRetry(rcvTime time.Time)\n\n\t// The SendMode determines if and what kind of packets can be sent.\n\tSendMode(now time.Time) SendMode\n\t// TimeUntilSend is the time when the next packet should be sent.\n\t// It is used for pacing packets.\n\tTimeUntilSend() time.Time\n\tSetMaxDatagramSize(count protocol.ByteCount)\n\n\t// only to be called once the handshake is complete\n\tQueueProbePacket(protocol.EncryptionLevel) bool /* was a packet queued */\n\n\tECNMode(isShortHeaderPacket bool) protocol.ECN // isShortHeaderPacket should only be true for non-coalesced 1-RTT packets\n\tPeekPacketNumber(protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen)\n\tPopPacketNumber(protocol.EncryptionLevel) protocol.PacketNumber\n\n\tGetLossDetectionTimeout() time.Time\n\tOnLossDetectionTimeout(now time.Time) error\n\n\tMigratedPath(now time.Time, initialMaxPacketSize protocol.ByteCount)\n}\n\ntype sentPacketTracker interface {\n\tGetLowestPacketNotConfirmedAcked() protocol.PacketNumber\n\tReceivedPacket(_ protocol.EncryptionLevel, rcvTime time.Time)\n}\n\n// ReceivedPacketHandler handles ACKs needed to send for incoming packets\ntype ReceivedPacketHandler interface {\n\tIsPotentiallyDuplicate(protocol.PacketNumber, protocol.EncryptionLevel) bool\n\tReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, encLevel protocol.EncryptionLevel, rcvTime time.Time, ackEliciting bool) error\n\tDropPackets(protocol.EncryptionLevel)\n\n\tGetAlarmTimeout() time.Time\n\tGetAckFrame(_ protocol.EncryptionLevel, now time.Time, onlyIfQueued bool) *wire.AckFrame\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/ackhandler/mockgen.go",
    "content": "//go:build gomock || generate\n\npackage ackhandler\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\"  -package ackhandler -destination mock_sent_packet_tracker_test.go github.com/quic-go/quic-go/internal/ackhandler SentPacketTracker\"\ntype SentPacketTracker = sentPacketTracker\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -build_flags=\\\"-tags=gomock\\\"  -package ackhandler -destination mock_ecn_handler_test.go github.com/quic-go/quic-go/internal/ackhandler ECNHandler\"\ntype ECNHandler = ecnHandler\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/ackhandler/packet.go",
    "content": "package ackhandler\n\nimport (\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\n// A Packet is a packet\ntype packet struct {\n\tSendTime        time.Time\n\tPacketNumber    protocol.PacketNumber\n\tStreamFrames    []StreamFrame\n\tFrames          []Frame\n\tLargestAcked    protocol.PacketNumber // InvalidPacketNumber if the packet doesn't contain an ACK\n\tLength          protocol.ByteCount\n\tEncryptionLevel protocol.EncryptionLevel\n\n\tIsPathMTUProbePacket bool // We don't report the loss of Path MTU probe packets to the congestion controller.\n\n\tincludedInBytesInFlight bool\n\tdeclaredLost            bool\n\tskippedPacket           bool\n\tisPathProbePacket       bool\n}\n\nfunc (p *packet) outstanding() bool {\n\treturn !p.declaredLost && !p.skippedPacket && !p.IsPathMTUProbePacket && !p.isPathProbePacket\n}\n\nvar packetPool = sync.Pool{New: func() any { return &packet{} }}\n\nfunc getPacket() *packet {\n\tp := packetPool.Get().(*packet)\n\tp.PacketNumber = 0\n\tp.StreamFrames = nil\n\tp.Frames = nil\n\tp.LargestAcked = 0\n\tp.Length = 0\n\tp.EncryptionLevel = protocol.EncryptionLevel(0)\n\tp.SendTime = time.Time{}\n\tp.IsPathMTUProbePacket = false\n\tp.includedInBytesInFlight = false\n\tp.declaredLost = false\n\tp.skippedPacket = false\n\treturn p\n}\n\n// We currently only return Packets back into the pool when they're acknowledged (not when they're lost).\n// This simplifies the code, and gives the vast majority of the performance benefit we can gain from using the pool.\nfunc putPacket(p *packet) {\n\tp.Frames = nil\n\tp.StreamFrames = nil\n\tpacketPool.Put(p)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/ackhandler/packet_number_generator.go",
    "content": "package ackhandler\n\nimport (\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n)\n\ntype packetNumberGenerator interface {\n\tPeek() protocol.PacketNumber\n\t// Pop pops the packet number.\n\t// It reports if the packet number (before the one just popped) was skipped.\n\t// It never skips more than one packet number in a row.\n\tPop() (skipped bool, _ protocol.PacketNumber)\n}\n\ntype sequentialPacketNumberGenerator struct {\n\tnext protocol.PacketNumber\n}\n\nvar _ packetNumberGenerator = &sequentialPacketNumberGenerator{}\n\nfunc newSequentialPacketNumberGenerator(initial protocol.PacketNumber) packetNumberGenerator {\n\treturn &sequentialPacketNumberGenerator{next: initial}\n}\n\nfunc (p *sequentialPacketNumberGenerator) Peek() protocol.PacketNumber {\n\treturn p.next\n}\n\nfunc (p *sequentialPacketNumberGenerator) Pop() (bool, protocol.PacketNumber) {\n\tnext := p.next\n\tp.next++\n\treturn false, next\n}\n\n// The skippingPacketNumberGenerator generates the packet number for the next packet\n// it randomly skips a packet number every averagePeriod packets (on average).\n// It is guaranteed to never skip two consecutive packet numbers.\ntype skippingPacketNumberGenerator struct {\n\tperiod    protocol.PacketNumber\n\tmaxPeriod protocol.PacketNumber\n\n\tnext       protocol.PacketNumber\n\tnextToSkip protocol.PacketNumber\n\n\trng utils.Rand\n}\n\nvar _ packetNumberGenerator = &skippingPacketNumberGenerator{}\n\nfunc newSkippingPacketNumberGenerator(initial, initialPeriod, maxPeriod protocol.PacketNumber) packetNumberGenerator {\n\tg := &skippingPacketNumberGenerator{\n\t\tnext:      initial,\n\t\tperiod:    initialPeriod,\n\t\tmaxPeriod: maxPeriod,\n\t}\n\tg.generateNewSkip()\n\treturn g\n}\n\nfunc (p *skippingPacketNumberGenerator) Peek() protocol.PacketNumber {\n\tif p.next == p.nextToSkip {\n\t\treturn p.next + 1\n\t}\n\treturn p.next\n}\n\nfunc (p *skippingPacketNumberGenerator) Pop() (bool, protocol.PacketNumber) {\n\tnext := p.next\n\tif p.next == p.nextToSkip {\n\t\tnext++\n\t\tp.next += 2\n\t\tp.generateNewSkip()\n\t\treturn true, next\n\t}\n\tp.next++ // generate a new packet number for the next packet\n\treturn false, next\n}\n\nfunc (p *skippingPacketNumberGenerator) generateNewSkip() {\n\t// make sure that there are never two consecutive packet numbers that are skipped\n\tp.nextToSkip = p.next + 3 + protocol.PacketNumber(p.rng.Int31n(int32(2*p.period)))\n\tp.period = min(2*p.period, p.maxPeriod)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_handler.go",
    "content": "package ackhandler\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\ntype receivedPacketHandler struct {\n\tsentPackets sentPacketTracker\n\n\tinitialPackets   *receivedPacketTracker\n\thandshakePackets *receivedPacketTracker\n\tappDataPackets   appDataReceivedPacketTracker\n\n\tlowest1RTTPacket protocol.PacketNumber\n}\n\nvar _ ReceivedPacketHandler = &receivedPacketHandler{}\n\nfunc newReceivedPacketHandler(sentPackets sentPacketTracker, logger utils.Logger) ReceivedPacketHandler {\n\treturn &receivedPacketHandler{\n\t\tsentPackets:      sentPackets,\n\t\tinitialPackets:   newReceivedPacketTracker(),\n\t\thandshakePackets: newReceivedPacketTracker(),\n\t\tappDataPackets:   *newAppDataReceivedPacketTracker(logger),\n\t\tlowest1RTTPacket: protocol.InvalidPacketNumber,\n\t}\n}\n\nfunc (h *receivedPacketHandler) ReceivedPacket(\n\tpn protocol.PacketNumber,\n\tecn protocol.ECN,\n\tencLevel protocol.EncryptionLevel,\n\trcvTime time.Time,\n\tackEliciting bool,\n) error {\n\th.sentPackets.ReceivedPacket(encLevel, rcvTime)\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\treturn h.initialPackets.ReceivedPacket(pn, ecn, rcvTime, ackEliciting)\n\tcase protocol.EncryptionHandshake:\n\t\t// The Handshake packet number space might already have been dropped as a result\n\t\t// of processing the CRYPTO frame that was contained in this packet.\n\t\tif h.handshakePackets == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn h.handshakePackets.ReceivedPacket(pn, ecn, rcvTime, ackEliciting)\n\tcase protocol.Encryption0RTT:\n\t\tif h.lowest1RTTPacket != protocol.InvalidPacketNumber && pn > h.lowest1RTTPacket {\n\t\t\treturn fmt.Errorf(\"received packet number %d on a 0-RTT packet after receiving %d on a 1-RTT packet\", pn, h.lowest1RTTPacket)\n\t\t}\n\t\treturn h.appDataPackets.ReceivedPacket(pn, ecn, rcvTime, ackEliciting)\n\tcase protocol.Encryption1RTT:\n\t\tif h.lowest1RTTPacket == protocol.InvalidPacketNumber || pn < h.lowest1RTTPacket {\n\t\t\th.lowest1RTTPacket = pn\n\t\t}\n\t\tif err := h.appDataPackets.ReceivedPacket(pn, ecn, rcvTime, ackEliciting); err != nil {\n\t\t\treturn err\n\t\t}\n\t\th.appDataPackets.IgnoreBelow(h.sentPackets.GetLowestPacketNotConfirmedAcked())\n\t\treturn nil\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"received packet with unknown encryption level: %s\", encLevel))\n\t}\n}\n\nfunc (h *receivedPacketHandler) DropPackets(encLevel protocol.EncryptionLevel) {\n\t//nolint:exhaustive // 1-RTT packet number space is never dropped.\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\th.initialPackets = nil\n\tcase protocol.EncryptionHandshake:\n\t\th.handshakePackets = nil\n\tcase protocol.Encryption0RTT:\n\t\t// Nothing to do here.\n\t\t// If we are rejecting 0-RTT, no 0-RTT packets will have been decrypted.\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"Cannot drop keys for encryption level %s\", encLevel))\n\t}\n}\n\nfunc (h *receivedPacketHandler) GetAlarmTimeout() time.Time {\n\treturn h.appDataPackets.GetAlarmTimeout()\n}\n\nfunc (h *receivedPacketHandler) GetAckFrame(encLevel protocol.EncryptionLevel, now time.Time, onlyIfQueued bool) *wire.AckFrame {\n\t//nolint:exhaustive // 0-RTT packets can't contain ACK frames.\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\tif h.initialPackets != nil {\n\t\t\treturn h.initialPackets.GetAckFrame()\n\t\t}\n\t\treturn nil\n\tcase protocol.EncryptionHandshake:\n\t\tif h.handshakePackets != nil {\n\t\t\treturn h.handshakePackets.GetAckFrame()\n\t\t}\n\t\treturn nil\n\tcase protocol.Encryption1RTT:\n\t\treturn h.appDataPackets.GetAckFrame(now, onlyIfQueued)\n\tdefault:\n\t\t// 0-RTT packets can't contain ACK frames\n\t\treturn nil\n\t}\n}\n\nfunc (h *receivedPacketHandler) IsPotentiallyDuplicate(pn protocol.PacketNumber, encLevel protocol.EncryptionLevel) bool {\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\tif h.initialPackets != nil {\n\t\t\treturn h.initialPackets.IsPotentiallyDuplicate(pn)\n\t\t}\n\tcase protocol.EncryptionHandshake:\n\t\tif h.handshakePackets != nil {\n\t\t\treturn h.handshakePackets.IsPotentiallyDuplicate(pn)\n\t\t}\n\tcase protocol.Encryption0RTT, protocol.Encryption1RTT:\n\t\treturn h.appDataPackets.IsPotentiallyDuplicate(pn)\n\t}\n\tpanic(\"unexpected encryption level\")\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_history.go",
    "content": "package ackhandler\n\nimport (\n\t\"slices\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\n// interval is an interval from one PacketNumber to the other\ntype interval struct {\n\tStart protocol.PacketNumber\n\tEnd   protocol.PacketNumber\n}\n\n// The receivedPacketHistory stores if a packet number has already been received.\n// It generates ACK ranges which can be used to assemble an ACK frame.\n// It does not store packet contents.\ntype receivedPacketHistory struct {\n\tranges []interval // maximum length: protocol.MaxNumAckRanges\n\n\tdeletedBelow protocol.PacketNumber\n}\n\nfunc newReceivedPacketHistory() *receivedPacketHistory {\n\treturn &receivedPacketHistory{}\n}\n\n// ReceivedPacket registers a packet with PacketNumber p and updates the ranges\nfunc (h *receivedPacketHistory) ReceivedPacket(p protocol.PacketNumber) bool /* is a new packet (and not a duplicate / delayed packet) */ {\n\t// ignore delayed packets, if we already deleted the range\n\tif p < h.deletedBelow {\n\t\treturn false\n\t}\n\n\tisNew := h.addToRanges(p)\n\t// Delete old ranges, if we're tracking too many of them.\n\t// This is a DoS defense against a peer that sends us too many gaps.\n\tif len(h.ranges) > protocol.MaxNumAckRanges {\n\t\th.ranges = slices.Delete(h.ranges, 0, len(h.ranges)-protocol.MaxNumAckRanges)\n\t}\n\treturn isNew\n}\n\nfunc (h *receivedPacketHistory) addToRanges(p protocol.PacketNumber) bool /* is a new packet (and not a duplicate / delayed packet) */ {\n\tif len(h.ranges) == 0 {\n\t\th.ranges = append(h.ranges, interval{Start: p, End: p})\n\t\treturn true\n\t}\n\n\tfor i := len(h.ranges) - 1; i >= 0; i-- {\n\t\t// p already included in an existing range. Nothing to do here\n\t\tif p >= h.ranges[i].Start && p <= h.ranges[i].End {\n\t\t\treturn false\n\t\t}\n\n\t\tif h.ranges[i].End == p-1 { // extend a range at the end\n\t\t\th.ranges[i].End = p\n\t\t\treturn true\n\t\t}\n\t\tif h.ranges[i].Start == p+1 { // extend a range at the beginning\n\t\t\th.ranges[i].Start = p\n\n\t\t\tif i > 0 && h.ranges[i-1].End+1 == h.ranges[i].Start { // merge two ranges\n\t\t\t\th.ranges[i-1].End = h.ranges[i].End\n\t\t\t\th.ranges = slices.Delete(h.ranges, i, i+1)\n\t\t\t}\n\t\t\treturn true\n\t\t}\n\n\t\t// create a new range after the current one\n\t\tif p > h.ranges[i].End {\n\t\t\th.ranges = slices.Insert(h.ranges, i+1, interval{Start: p, End: p})\n\t\t\treturn true\n\t\t}\n\t}\n\n\t// create a new range at the beginning\n\th.ranges = slices.Insert(h.ranges, 0, interval{Start: p, End: p})\n\treturn true\n}\n\n// DeleteBelow deletes all entries below (but not including) p\nfunc (h *receivedPacketHistory) DeleteBelow(p protocol.PacketNumber) {\n\tif p < h.deletedBelow {\n\t\treturn\n\t}\n\th.deletedBelow = p\n\n\tif len(h.ranges) == 0 {\n\t\treturn\n\t}\n\n\tidx := -1\n\tfor i := 0; i < len(h.ranges); i++ {\n\t\tif h.ranges[i].End < p { // delete a whole range\n\t\t\tidx = i\n\t\t} else if p > h.ranges[i].Start && p <= h.ranges[i].End {\n\t\t\th.ranges[i].Start = p\n\t\t\tbreak\n\t\t} else { // no ranges affected. Nothing to do\n\t\t\tbreak\n\t\t}\n\t}\n\tif idx >= 0 {\n\t\th.ranges = slices.Delete(h.ranges, 0, idx+1)\n\t}\n}\n\n// AppendAckRanges appends to a slice of all AckRanges that can be used in an AckFrame\nfunc (h *receivedPacketHistory) AppendAckRanges(ackRanges []wire.AckRange) []wire.AckRange {\n\tfor i := len(h.ranges) - 1; i >= 0; i-- {\n\t\tackRanges = append(ackRanges, wire.AckRange{Smallest: h.ranges[i].Start, Largest: h.ranges[i].End})\n\t}\n\treturn ackRanges\n}\n\nfunc (h *receivedPacketHistory) GetHighestAckRange() wire.AckRange {\n\tackRange := wire.AckRange{}\n\tif len(h.ranges) > 0 {\n\t\tackRange.Smallest = h.ranges[len(h.ranges)-1].Start\n\t\tackRange.Largest = h.ranges[len(h.ranges)-1].End\n\t}\n\treturn ackRange\n}\n\nfunc (h *receivedPacketHistory) IsPotentiallyDuplicate(p protocol.PacketNumber) bool {\n\tif p < h.deletedBelow {\n\t\treturn true\n\t}\n\t// Iterating over the slices is faster than using a binary search (using slices.BinarySearchFunc).\n\tfor i := len(h.ranges) - 1; i >= 0; i-- {\n\t\tif p > h.ranges[i].End {\n\t\t\treturn false\n\t\t}\n\t\tif p <= h.ranges[i].End && p >= h.ranges[i].Start {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/ackhandler/received_packet_tracker.go",
    "content": "package ackhandler\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\n// The receivedPacketTracker tracks packets for the Initial and Handshake packet number space.\n// Every received packet is acknowledged immediately.\ntype receivedPacketTracker struct {\n\tect0, ect1, ecnce uint64\n\n\tpacketHistory receivedPacketHistory\n\n\tlastAck   *wire.AckFrame\n\thasNewAck bool // true as soon as we received an ack-eliciting new packet\n}\n\nfunc newReceivedPacketTracker() *receivedPacketTracker {\n\treturn &receivedPacketTracker{packetHistory: *newReceivedPacketHistory()}\n}\n\nfunc (h *receivedPacketTracker) ReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, rcvTime time.Time, ackEliciting bool) error {\n\tif isNew := h.packetHistory.ReceivedPacket(pn); !isNew {\n\t\treturn fmt.Errorf(\"recevedPacketTracker BUG: ReceivedPacket called for old / duplicate packet %d\", pn)\n\t}\n\n\t//nolint:exhaustive // Only need to count ECT(0), ECT(1) and ECN-CE.\n\tswitch ecn {\n\tcase protocol.ECT0:\n\t\th.ect0++\n\tcase protocol.ECT1:\n\t\th.ect1++\n\tcase protocol.ECNCE:\n\t\th.ecnce++\n\t}\n\tif !ackEliciting {\n\t\treturn nil\n\t}\n\th.hasNewAck = true\n\treturn nil\n}\n\nfunc (h *receivedPacketTracker) GetAckFrame() *wire.AckFrame {\n\tif !h.hasNewAck {\n\t\treturn nil\n\t}\n\n\t// This function always returns the same ACK frame struct, filled with the most recent values.\n\tack := h.lastAck\n\tif ack == nil {\n\t\tack = &wire.AckFrame{}\n\t}\n\tack.Reset()\n\tack.ECT0 = h.ect0\n\tack.ECT1 = h.ect1\n\tack.ECNCE = h.ecnce\n\tack.AckRanges = h.packetHistory.AppendAckRanges(ack.AckRanges)\n\n\th.lastAck = ack\n\th.hasNewAck = false\n\treturn ack\n}\n\nfunc (h *receivedPacketTracker) IsPotentiallyDuplicate(pn protocol.PacketNumber) bool {\n\treturn h.packetHistory.IsPotentiallyDuplicate(pn)\n}\n\n// number of ack-eliciting packets received before sending an ACK\nconst packetsBeforeAck = 2\n\n// The appDataReceivedPacketTracker tracks packets received in the Application Data packet number space.\n// It waits until at least 2 packets were received before queueing an ACK, or until the max_ack_delay was reached.\ntype appDataReceivedPacketTracker struct {\n\treceivedPacketTracker\n\n\tlargestObservedRcvdTime time.Time\n\n\tlargestObserved protocol.PacketNumber\n\tignoreBelow     protocol.PacketNumber\n\n\tmaxAckDelay time.Duration\n\tackQueued   bool // true if we need send a new ACK\n\n\tackElicitingPacketsReceivedSinceLastAck int\n\tackAlarm                                time.Time\n\n\tlogger utils.Logger\n}\n\nfunc newAppDataReceivedPacketTracker(logger utils.Logger) *appDataReceivedPacketTracker {\n\th := &appDataReceivedPacketTracker{\n\t\treceivedPacketTracker: *newReceivedPacketTracker(),\n\t\tmaxAckDelay:           protocol.MaxAckDelay,\n\t\tlogger:                logger,\n\t}\n\treturn h\n}\n\nfunc (h *appDataReceivedPacketTracker) ReceivedPacket(pn protocol.PacketNumber, ecn protocol.ECN, rcvTime time.Time, ackEliciting bool) error {\n\tif err := h.receivedPacketTracker.ReceivedPacket(pn, ecn, rcvTime, ackEliciting); err != nil {\n\t\treturn err\n\t}\n\tif pn >= h.largestObserved {\n\t\th.largestObserved = pn\n\t\th.largestObservedRcvdTime = rcvTime\n\t}\n\tif !ackEliciting {\n\t\treturn nil\n\t}\n\th.ackElicitingPacketsReceivedSinceLastAck++\n\tisMissing := h.isMissing(pn)\n\tif !h.ackQueued && h.shouldQueueACK(pn, ecn, isMissing) {\n\t\th.ackQueued = true\n\t\th.ackAlarm = time.Time{} // cancel the ack alarm\n\t}\n\tif !h.ackQueued {\n\t\t// No ACK queued, but we'll need to acknowledge the packet after max_ack_delay.\n\t\th.ackAlarm = rcvTime.Add(h.maxAckDelay)\n\t\tif h.logger.Debug() {\n\t\t\th.logger.Debugf(\"\\tSetting ACK timer to max ack delay: %s\", h.maxAckDelay)\n\t\t}\n\t}\n\treturn nil\n}\n\n// IgnoreBelow sets a lower limit for acknowledging packets.\n// Packets with packet numbers smaller than p will not be acked.\nfunc (h *appDataReceivedPacketTracker) IgnoreBelow(pn protocol.PacketNumber) {\n\tif pn <= h.ignoreBelow {\n\t\treturn\n\t}\n\th.ignoreBelow = pn\n\th.packetHistory.DeleteBelow(pn)\n\tif h.logger.Debug() {\n\t\th.logger.Debugf(\"\\tIgnoring all packets below %d.\", pn)\n\t}\n}\n\n// isMissing says if a packet was reported missing in the last ACK.\nfunc (h *appDataReceivedPacketTracker) isMissing(p protocol.PacketNumber) bool {\n\tif h.lastAck == nil || p < h.ignoreBelow {\n\t\treturn false\n\t}\n\treturn p < h.lastAck.LargestAcked() && !h.lastAck.AcksPacket(p)\n}\n\nfunc (h *appDataReceivedPacketTracker) hasNewMissingPackets() bool {\n\tif h.lastAck == nil {\n\t\treturn false\n\t}\n\thighestRange := h.packetHistory.GetHighestAckRange()\n\treturn highestRange.Smallest > h.lastAck.LargestAcked()+1 && highestRange.Len() == 1\n}\n\nfunc (h *appDataReceivedPacketTracker) shouldQueueACK(pn protocol.PacketNumber, ecn protocol.ECN, wasMissing bool) bool {\n\t// always acknowledge the first packet\n\tif h.lastAck == nil {\n\t\th.logger.Debugf(\"\\tQueueing ACK because the first packet should be acknowledged.\")\n\t\treturn true\n\t}\n\n\t// Send an ACK if this packet was reported missing in an ACK sent before.\n\t// Ack decimation with reordering relies on the timer to send an ACK, but if\n\t// missing packets we reported in the previous ACK, send an ACK immediately.\n\tif wasMissing {\n\t\tif h.logger.Debug() {\n\t\t\th.logger.Debugf(\"\\tQueueing ACK because packet %d was missing before.\", pn)\n\t\t}\n\t\treturn true\n\t}\n\n\t// send an ACK every 2 ack-eliciting packets\n\tif h.ackElicitingPacketsReceivedSinceLastAck >= packetsBeforeAck {\n\t\tif h.logger.Debug() {\n\t\t\th.logger.Debugf(\"\\tQueueing ACK because packet %d packets were received after the last ACK (using initial threshold: %d).\", h.ackElicitingPacketsReceivedSinceLastAck, packetsBeforeAck)\n\t\t}\n\t\treturn true\n\t}\n\n\t// queue an ACK if there are new missing packets to report\n\tif h.hasNewMissingPackets() {\n\t\th.logger.Debugf(\"\\tQueuing ACK because there's a new missing packet to report.\")\n\t\treturn true\n\t}\n\n\t// queue an ACK if the packet was ECN-CE marked\n\tif ecn == protocol.ECNCE {\n\t\th.logger.Debugf(\"\\tQueuing ACK because the packet was ECN-CE marked.\")\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (h *appDataReceivedPacketTracker) GetAckFrame(now time.Time, onlyIfQueued bool) *wire.AckFrame {\n\tif onlyIfQueued && !h.ackQueued {\n\t\tif h.ackAlarm.IsZero() || h.ackAlarm.After(now) {\n\t\t\treturn nil\n\t\t}\n\t\tif h.logger.Debug() && !h.ackAlarm.IsZero() {\n\t\t\th.logger.Debugf(\"Sending ACK because the ACK timer expired.\")\n\t\t}\n\t}\n\tack := h.receivedPacketTracker.GetAckFrame()\n\tif ack == nil {\n\t\treturn nil\n\t}\n\tack.DelayTime = max(0, now.Sub(h.largestObservedRcvdTime))\n\th.ackQueued = false\n\th.ackAlarm = time.Time{}\n\th.ackElicitingPacketsReceivedSinceLastAck = 0\n\treturn ack\n}\n\nfunc (h *appDataReceivedPacketTracker) GetAlarmTimeout() time.Time { return h.ackAlarm }\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/ackhandler/send_mode.go",
    "content": "package ackhandler\n\nimport \"fmt\"\n\n// The SendMode says what kind of packets can be sent.\ntype SendMode uint8\n\nconst (\n\t// SendNone means that no packets should be sent\n\tSendNone SendMode = iota\n\t// SendAck means an ACK-only packet should be sent\n\tSendAck\n\t// SendPTOInitial means that an Initial probe packet should be sent\n\tSendPTOInitial\n\t// SendPTOHandshake means that a Handshake probe packet should be sent\n\tSendPTOHandshake\n\t// SendPTOAppData means that an Application data probe packet should be sent\n\tSendPTOAppData\n\t// SendPacingLimited means that the pacer doesn't allow sending of a packet right now,\n\t// but will do in a little while.\n\t// The timestamp when sending is allowed again can be obtained via the SentPacketHandler.TimeUntilSend.\n\tSendPacingLimited\n\t// SendAny means that any packet should be sent\n\tSendAny\n)\n\nfunc (s SendMode) String() string {\n\tswitch s {\n\tcase SendNone:\n\t\treturn \"none\"\n\tcase SendAck:\n\t\treturn \"ack\"\n\tcase SendPTOInitial:\n\t\treturn \"pto (Initial)\"\n\tcase SendPTOHandshake:\n\t\treturn \"pto (Handshake)\"\n\tcase SendPTOAppData:\n\t\treturn \"pto (Application Data)\"\n\tcase SendAny:\n\t\treturn \"any\"\n\tcase SendPacingLimited:\n\t\treturn \"pacing limited\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"invalid send mode: %d\", s)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/ackhandler/sent_packet_handler.go",
    "content": "package ackhandler\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/congestion\"\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n\t\"github.com/quic-go/quic-go/logging\"\n)\n\nconst (\n\t// Maximum reordering in time space before time based loss detection considers a packet lost.\n\t// Specified as an RTT multiplier.\n\ttimeThreshold = 9.0 / 8\n\t// Maximum reordering in packets before packet threshold loss detection considers a packet lost.\n\tpacketThreshold = 3\n\t// Before validating the client's address, the server won't send more than 3x bytes than it received.\n\tamplificationFactor = 3\n\t// We use Retry packets to derive an RTT estimate. Make sure we don't set the RTT to a super low value yet.\n\tminRTTAfterRetry = 5 * time.Millisecond\n\t// The PTO duration uses exponential backoff, but is truncated to a maximum value, as allowed by RFC 8961, section 4.4.\n\tmaxPTODuration = 60 * time.Second\n)\n\n// Path probe packets are declared lost after this time.\nconst pathProbePacketLossTimeout = time.Second\n\ntype packetNumberSpace struct {\n\thistory sentPacketHistory\n\tpns     packetNumberGenerator\n\n\tlossTime                   time.Time\n\tlastAckElicitingPacketTime time.Time\n\n\tlargestAcked protocol.PacketNumber\n\tlargestSent  protocol.PacketNumber\n}\n\nfunc newPacketNumberSpace(initialPN protocol.PacketNumber, isAppData bool) *packetNumberSpace {\n\tvar pns packetNumberGenerator\n\tif isAppData {\n\t\tpns = newSkippingPacketNumberGenerator(initialPN, protocol.SkipPacketInitialPeriod, protocol.SkipPacketMaxPeriod)\n\t} else {\n\t\tpns = newSequentialPacketNumberGenerator(initialPN)\n\t}\n\treturn &packetNumberSpace{\n\t\thistory:      *newSentPacketHistory(isAppData),\n\t\tpns:          pns,\n\t\tlargestSent:  protocol.InvalidPacketNumber,\n\t\tlargestAcked: protocol.InvalidPacketNumber,\n\t}\n}\n\ntype alarmTimer struct {\n\tTime            time.Time\n\tTimerType       logging.TimerType\n\tEncryptionLevel protocol.EncryptionLevel\n}\n\ntype sentPacketHandler struct {\n\tinitialPackets   *packetNumberSpace\n\thandshakePackets *packetNumberSpace\n\tappDataPackets   *packetNumberSpace\n\n\t// Do we know that the peer completed address validation yet?\n\t// Always true for the server.\n\tpeerCompletedAddressValidation bool\n\tbytesReceived                  protocol.ByteCount\n\tbytesSent                      protocol.ByteCount\n\t// Have we validated the peer's address yet?\n\t// Always true for the client.\n\tpeerAddressValidated bool\n\n\thandshakeConfirmed bool\n\n\t// lowestNotConfirmedAcked is the lowest packet number that we sent an ACK for, but haven't received confirmation, that this ACK actually arrived\n\t// example: we send an ACK for packets 90-100 with packet number 20\n\t// once we receive an ACK from the peer for packet 20, the lowestNotConfirmedAcked is 101\n\t// Only applies to the application-data packet number space.\n\tlowestNotConfirmedAcked protocol.PacketNumber\n\n\tackedPackets []*packet // to avoid allocations in detectAndRemoveAckedPackets\n\n\tbytesInFlight protocol.ByteCount\n\n\tcongestion congestion.SendAlgorithmWithDebugInfos\n\trttStats   *utils.RTTStats\n\n\t// The number of times a PTO has been sent without receiving an ack.\n\tptoCount uint32\n\tptoMode  SendMode\n\t// The number of PTO probe packets that should be sent.\n\t// Only applies to the application-data packet number space.\n\tnumProbesToSend int\n\n\t// The alarm timeout\n\talarm alarmTimer\n\n\tenableECN  bool\n\tecnTracker ecnHandler\n\n\tperspective protocol.Perspective\n\n\ttracer *logging.ConnectionTracer\n\tlogger utils.Logger\n}\n\nvar (\n\t_ SentPacketHandler = &sentPacketHandler{}\n\t_ sentPacketTracker = &sentPacketHandler{}\n)\n\n// clientAddressValidated indicates whether the address was validated beforehand by an address validation token.\n// If the address was validated, the amplification limit doesn't apply. It has no effect for a client.\nfunc newSentPacketHandler(\n\tinitialPN protocol.PacketNumber,\n\tinitialMaxDatagramSize protocol.ByteCount,\n\trttStats *utils.RTTStats,\n\tclientAddressValidated bool,\n\tenableECN bool,\n\tpers protocol.Perspective,\n\ttracer *logging.ConnectionTracer,\n\tlogger utils.Logger,\n) *sentPacketHandler {\n\tcongestion := congestion.NewCubicSender(\n\t\tcongestion.DefaultClock{},\n\t\trttStats,\n\t\tinitialMaxDatagramSize,\n\t\ttrue, // use Reno\n\t\ttracer,\n\t)\n\n\th := &sentPacketHandler{\n\t\tpeerCompletedAddressValidation: pers == protocol.PerspectiveServer,\n\t\tpeerAddressValidated:           pers == protocol.PerspectiveClient || clientAddressValidated,\n\t\tinitialPackets:                 newPacketNumberSpace(initialPN, false),\n\t\thandshakePackets:               newPacketNumberSpace(0, false),\n\t\tappDataPackets:                 newPacketNumberSpace(0, true),\n\t\trttStats:                       rttStats,\n\t\tcongestion:                     congestion,\n\t\tperspective:                    pers,\n\t\ttracer:                         tracer,\n\t\tlogger:                         logger,\n\t}\n\tif enableECN {\n\t\th.enableECN = true\n\t\th.ecnTracker = newECNTracker(logger, tracer)\n\t}\n\treturn h\n}\n\nfunc (h *sentPacketHandler) removeFromBytesInFlight(p *packet) {\n\tif p.includedInBytesInFlight {\n\t\tif p.Length > h.bytesInFlight {\n\t\t\tpanic(\"negative bytes_in_flight\")\n\t\t}\n\t\th.bytesInFlight -= p.Length\n\t\tp.includedInBytesInFlight = false\n\t}\n}\n\nfunc (h *sentPacketHandler) DropPackets(encLevel protocol.EncryptionLevel, now time.Time) {\n\t// The server won't await address validation after the handshake is confirmed.\n\t// This applies even if we didn't receive an ACK for a Handshake packet.\n\tif h.perspective == protocol.PerspectiveClient && encLevel == protocol.EncryptionHandshake {\n\t\th.peerCompletedAddressValidation = true\n\t}\n\t// remove outstanding packets from bytes_in_flight\n\tif encLevel == protocol.EncryptionInitial || encLevel == protocol.EncryptionHandshake {\n\t\tpnSpace := h.getPacketNumberSpace(encLevel)\n\t\t// We might already have dropped this packet number space.\n\t\tif pnSpace == nil {\n\t\t\treturn\n\t\t}\n\t\tfor p := range pnSpace.history.Packets() {\n\t\t\th.removeFromBytesInFlight(p)\n\t\t}\n\t}\n\t// drop the packet history\n\t//nolint:exhaustive // Not every packet number space can be dropped.\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\th.initialPackets = nil\n\tcase protocol.EncryptionHandshake:\n\t\t// Dropping the handshake packet number space means that the handshake is confirmed,\n\t\t// see section 4.9.2 of RFC 9001.\n\t\th.handshakeConfirmed = true\n\t\th.handshakePackets = nil\n\tcase protocol.Encryption0RTT:\n\t\t// This function is only called when 0-RTT is rejected,\n\t\t// and not when the client drops 0-RTT keys when the handshake completes.\n\t\t// When 0-RTT is rejected, all application data sent so far becomes invalid.\n\t\t// Delete the packets from the history and remove them from bytes_in_flight.\n\t\tfor p := range h.appDataPackets.history.Packets() {\n\t\t\tif p.EncryptionLevel != protocol.Encryption0RTT && !p.skippedPacket {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\th.removeFromBytesInFlight(p)\n\t\t\th.appDataPackets.history.Remove(p.PacketNumber)\n\t\t}\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"Cannot drop keys for encryption level %s\", encLevel))\n\t}\n\tif h.tracer != nil && h.tracer.UpdatedPTOCount != nil && h.ptoCount != 0 {\n\t\th.tracer.UpdatedPTOCount(0)\n\t}\n\th.ptoCount = 0\n\th.numProbesToSend = 0\n\th.ptoMode = SendNone\n\th.setLossDetectionTimer(now)\n}\n\nfunc (h *sentPacketHandler) ReceivedBytes(n protocol.ByteCount, t time.Time) {\n\twasAmplificationLimit := h.isAmplificationLimited()\n\th.bytesReceived += n\n\tif wasAmplificationLimit && !h.isAmplificationLimited() {\n\t\th.setLossDetectionTimer(t)\n\t}\n}\n\nfunc (h *sentPacketHandler) ReceivedPacket(l protocol.EncryptionLevel, t time.Time) {\n\tif h.perspective == protocol.PerspectiveServer && l == protocol.EncryptionHandshake && !h.peerAddressValidated {\n\t\th.peerAddressValidated = true\n\t\th.setLossDetectionTimer(t)\n\t}\n}\n\nfunc (h *sentPacketHandler) packetsInFlight() int {\n\tpacketsInFlight := h.appDataPackets.history.Len()\n\tif h.handshakePackets != nil {\n\t\tpacketsInFlight += h.handshakePackets.history.Len()\n\t}\n\tif h.initialPackets != nil {\n\t\tpacketsInFlight += h.initialPackets.history.Len()\n\t}\n\treturn packetsInFlight\n}\n\nfunc (h *sentPacketHandler) SentPacket(\n\tt time.Time,\n\tpn, largestAcked protocol.PacketNumber,\n\tstreamFrames []StreamFrame,\n\tframes []Frame,\n\tencLevel protocol.EncryptionLevel,\n\tecn protocol.ECN,\n\tsize protocol.ByteCount,\n\tisPathMTUProbePacket bool,\n\tisPathProbePacket bool,\n) {\n\th.bytesSent += size\n\n\tpnSpace := h.getPacketNumberSpace(encLevel)\n\tif h.logger.Debug() && (pnSpace.history.HasOutstandingPackets() || pnSpace.history.HasOutstandingPathProbes()) {\n\t\tfor p := max(0, pnSpace.largestSent+1); p < pn; p++ {\n\t\t\th.logger.Debugf(\"Skipping packet number %d\", p)\n\t\t}\n\t}\n\n\tpnSpace.largestSent = pn\n\tisAckEliciting := len(streamFrames) > 0 || len(frames) > 0\n\n\tif isPathProbePacket {\n\t\tp := getPacket()\n\t\tp.SendTime = t\n\t\tp.PacketNumber = pn\n\t\tp.EncryptionLevel = encLevel\n\t\tp.Length = size\n\t\tp.Frames = frames\n\t\tp.isPathProbePacket = true\n\t\tpnSpace.history.SentPathProbePacket(p)\n\t\th.setLossDetectionTimer(t)\n\t\treturn\n\t}\n\tif isAckEliciting {\n\t\tpnSpace.lastAckElicitingPacketTime = t\n\t\th.bytesInFlight += size\n\t\tif h.numProbesToSend > 0 {\n\t\t\th.numProbesToSend--\n\t\t}\n\t}\n\th.congestion.OnPacketSent(t, h.bytesInFlight, pn, size, isAckEliciting)\n\n\tif encLevel == protocol.Encryption1RTT && h.ecnTracker != nil {\n\t\th.ecnTracker.SentPacket(pn, ecn)\n\t}\n\n\tif !isAckEliciting {\n\t\tpnSpace.history.SentNonAckElicitingPacket(pn)\n\t\tif !h.peerCompletedAddressValidation {\n\t\t\th.setLossDetectionTimer(t)\n\t\t}\n\t\treturn\n\t}\n\n\tp := getPacket()\n\tp.SendTime = t\n\tp.PacketNumber = pn\n\tp.EncryptionLevel = encLevel\n\tp.Length = size\n\tp.LargestAcked = largestAcked\n\tp.StreamFrames = streamFrames\n\tp.Frames = frames\n\tp.IsPathMTUProbePacket = isPathMTUProbePacket\n\tp.includedInBytesInFlight = true\n\n\tpnSpace.history.SentAckElicitingPacket(p)\n\tif h.tracer != nil && h.tracer.UpdatedMetrics != nil {\n\t\th.tracer.UpdatedMetrics(h.rttStats, h.congestion.GetCongestionWindow(), h.bytesInFlight, h.packetsInFlight())\n\t}\n\th.setLossDetectionTimer(t)\n}\n\nfunc (h *sentPacketHandler) getPacketNumberSpace(encLevel protocol.EncryptionLevel) *packetNumberSpace {\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\treturn h.initialPackets\n\tcase protocol.EncryptionHandshake:\n\t\treturn h.handshakePackets\n\tcase protocol.Encryption0RTT, protocol.Encryption1RTT:\n\t\treturn h.appDataPackets\n\tdefault:\n\t\tpanic(\"invalid packet number space\")\n\t}\n}\n\nfunc (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) (bool /* contained 1-RTT packet */, error) {\n\tpnSpace := h.getPacketNumberSpace(encLevel)\n\n\tlargestAcked := ack.LargestAcked()\n\tif largestAcked > pnSpace.largestSent {\n\t\treturn false, &qerr.TransportError{\n\t\t\tErrorCode:    qerr.ProtocolViolation,\n\t\t\tErrorMessage: \"received ACK for an unsent packet\",\n\t\t}\n\t}\n\n\t// Servers complete address validation when a protected packet is received.\n\tif h.perspective == protocol.PerspectiveClient && !h.peerCompletedAddressValidation &&\n\t\t(encLevel == protocol.EncryptionHandshake || encLevel == protocol.Encryption1RTT) {\n\t\th.peerCompletedAddressValidation = true\n\t\th.logger.Debugf(\"Peer doesn't await address validation any longer.\")\n\t\t// Make sure that the timer is reset, even if this ACK doesn't acknowledge any (ack-eliciting) packets.\n\t\th.setLossDetectionTimer(rcvTime)\n\t}\n\n\tpriorInFlight := h.bytesInFlight\n\tackedPackets, err := h.detectAndRemoveAckedPackets(ack, encLevel)\n\tif err != nil || len(ackedPackets) == 0 {\n\t\treturn false, err\n\t}\n\t// update the RTT, if the largest acked is newly acknowledged\n\tif len(ackedPackets) > 0 {\n\t\tif p := ackedPackets[len(ackedPackets)-1]; p.PacketNumber == ack.LargestAcked() && !p.isPathProbePacket {\n\t\t\t// don't use the ack delay for Initial and Handshake packets\n\t\t\tvar ackDelay time.Duration\n\t\t\tif encLevel == protocol.Encryption1RTT {\n\t\t\t\tackDelay = min(ack.DelayTime, h.rttStats.MaxAckDelay())\n\t\t\t}\n\t\t\th.rttStats.UpdateRTT(rcvTime.Sub(p.SendTime), ackDelay)\n\t\t\tif h.logger.Debug() {\n\t\t\t\th.logger.Debugf(\"\\tupdated RTT: %s (σ: %s)\", h.rttStats.SmoothedRTT(), h.rttStats.MeanDeviation())\n\t\t\t}\n\t\t\th.congestion.MaybeExitSlowStart()\n\t\t}\n\t}\n\n\t// Only inform the ECN tracker about new 1-RTT ACKs if the ACK increases the largest acked.\n\tif encLevel == protocol.Encryption1RTT && h.ecnTracker != nil && largestAcked > pnSpace.largestAcked {\n\t\tcongested := h.ecnTracker.HandleNewlyAcked(ackedPackets, int64(ack.ECT0), int64(ack.ECT1), int64(ack.ECNCE))\n\t\tif congested {\n\t\t\th.congestion.OnCongestionEvent(largestAcked, 0, priorInFlight)\n\t\t}\n\t}\n\n\tpnSpace.largestAcked = max(pnSpace.largestAcked, largestAcked)\n\n\th.detectLostPackets(rcvTime, encLevel)\n\tif encLevel == protocol.Encryption1RTT {\n\t\th.detectLostPathProbes(rcvTime)\n\t}\n\tvar acked1RTTPacket bool\n\tfor _, p := range ackedPackets {\n\t\tif p.includedInBytesInFlight && !p.declaredLost {\n\t\t\th.congestion.OnPacketAcked(p.PacketNumber, p.Length, priorInFlight, rcvTime)\n\t\t}\n\t\tif p.EncryptionLevel == protocol.Encryption1RTT {\n\t\t\tacked1RTTPacket = true\n\t\t}\n\t\th.removeFromBytesInFlight(p)\n\t\tif !p.isPathProbePacket {\n\t\t\tputPacket(p)\n\t\t}\n\t}\n\t// After this point, we must not use ackedPackets any longer!\n\t// We've already returned the buffers.\n\tackedPackets = nil //nolint:ineffassign // This is just to be on the safe side.\n\n\t// Reset the pto_count unless the client is unsure if the server has validated the client's address.\n\tif h.peerCompletedAddressValidation {\n\t\tif h.tracer != nil && h.tracer.UpdatedPTOCount != nil && h.ptoCount != 0 {\n\t\t\th.tracer.UpdatedPTOCount(0)\n\t\t}\n\t\th.ptoCount = 0\n\t}\n\th.numProbesToSend = 0\n\n\tif h.tracer != nil && h.tracer.UpdatedMetrics != nil {\n\t\th.tracer.UpdatedMetrics(h.rttStats, h.congestion.GetCongestionWindow(), h.bytesInFlight, h.packetsInFlight())\n\t}\n\n\th.setLossDetectionTimer(rcvTime)\n\treturn acked1RTTPacket, nil\n}\n\nfunc (h *sentPacketHandler) GetLowestPacketNotConfirmedAcked() protocol.PacketNumber {\n\treturn h.lowestNotConfirmedAcked\n}\n\n// Packets are returned in ascending packet number order.\nfunc (h *sentPacketHandler) detectAndRemoveAckedPackets(ack *wire.AckFrame, encLevel protocol.EncryptionLevel) ([]*packet, error) {\n\tpnSpace := h.getPacketNumberSpace(encLevel)\n\th.ackedPackets = h.ackedPackets[:0]\n\tackRangeIndex := 0\n\tlowestAcked := ack.LowestAcked()\n\tlargestAcked := ack.LargestAcked()\n\tfor p := range pnSpace.history.Packets() {\n\t\t// ignore packets below the lowest acked\n\t\tif p.PacketNumber < lowestAcked {\n\t\t\tcontinue\n\t\t}\n\t\tif p.PacketNumber > largestAcked {\n\t\t\tbreak\n\t\t}\n\n\t\tif ack.HasMissingRanges() {\n\t\t\tackRange := ack.AckRanges[len(ack.AckRanges)-1-ackRangeIndex]\n\n\t\t\tfor p.PacketNumber > ackRange.Largest && ackRangeIndex < len(ack.AckRanges)-1 {\n\t\t\t\tackRangeIndex++\n\t\t\t\tackRange = ack.AckRanges[len(ack.AckRanges)-1-ackRangeIndex]\n\t\t\t}\n\n\t\t\tif p.PacketNumber < ackRange.Smallest { // packet not contained in ACK range\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif p.PacketNumber > ackRange.Largest {\n\t\t\t\treturn nil, fmt.Errorf(\"BUG: ackhandler would have acked wrong packet %d, while evaluating range %d -> %d\", p.PacketNumber, ackRange.Smallest, ackRange.Largest)\n\t\t\t}\n\t\t}\n\t\tif p.skippedPacket {\n\t\t\treturn nil, &qerr.TransportError{\n\t\t\t\tErrorCode:    qerr.ProtocolViolation,\n\t\t\t\tErrorMessage: fmt.Sprintf(\"received an ACK for skipped packet number: %d (%s)\", p.PacketNumber, encLevel),\n\t\t\t}\n\t\t}\n\t\tif p.isPathProbePacket {\n\t\t\tprobePacket := pnSpace.history.RemovePathProbe(p.PacketNumber)\n\t\t\t// the probe packet might already have been declared lost\n\t\t\tif probePacket != nil {\n\t\t\t\th.ackedPackets = append(h.ackedPackets, probePacket)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\th.ackedPackets = append(h.ackedPackets, p)\n\t}\n\tif h.logger.Debug() && len(h.ackedPackets) > 0 {\n\t\tpns := make([]protocol.PacketNumber, len(h.ackedPackets))\n\t\tfor i, p := range h.ackedPackets {\n\t\t\tpns[i] = p.PacketNumber\n\t\t}\n\t\th.logger.Debugf(\"\\tnewly acked packets (%d): %d\", len(pns), pns)\n\t}\n\n\tfor _, p := range h.ackedPackets {\n\t\tif p.LargestAcked != protocol.InvalidPacketNumber && encLevel == protocol.Encryption1RTT {\n\t\t\th.lowestNotConfirmedAcked = max(h.lowestNotConfirmedAcked, p.LargestAcked+1)\n\t\t}\n\n\t\tfor _, f := range p.Frames {\n\t\t\tif f.Handler != nil {\n\t\t\t\tf.Handler.OnAcked(f.Frame)\n\t\t\t}\n\t\t}\n\t\tfor _, f := range p.StreamFrames {\n\t\t\tif f.Handler != nil {\n\t\t\t\tf.Handler.OnAcked(f.Frame)\n\t\t\t}\n\t\t}\n\t\tif err := pnSpace.history.Remove(p.PacketNumber); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif h.tracer != nil && h.tracer.AcknowledgedPacket != nil {\n\t\t\th.tracer.AcknowledgedPacket(encLevel, p.PacketNumber)\n\t\t}\n\t}\n\treturn h.ackedPackets, nil\n}\n\nfunc (h *sentPacketHandler) getLossTimeAndSpace() (time.Time, protocol.EncryptionLevel) {\n\tvar encLevel protocol.EncryptionLevel\n\tvar lossTime time.Time\n\n\tif h.initialPackets != nil {\n\t\tlossTime = h.initialPackets.lossTime\n\t\tencLevel = protocol.EncryptionInitial\n\t}\n\tif h.handshakePackets != nil && (lossTime.IsZero() || (!h.handshakePackets.lossTime.IsZero() && h.handshakePackets.lossTime.Before(lossTime))) {\n\t\tlossTime = h.handshakePackets.lossTime\n\t\tencLevel = protocol.EncryptionHandshake\n\t}\n\tif lossTime.IsZero() || (!h.appDataPackets.lossTime.IsZero() && h.appDataPackets.lossTime.Before(lossTime)) {\n\t\tlossTime = h.appDataPackets.lossTime\n\t\tencLevel = protocol.Encryption1RTT\n\t}\n\treturn lossTime, encLevel\n}\n\nfunc (h *sentPacketHandler) getScaledPTO(includeMaxAckDelay bool) time.Duration {\n\tpto := h.rttStats.PTO(includeMaxAckDelay) << h.ptoCount\n\tif pto > maxPTODuration || pto <= 0 {\n\t\treturn maxPTODuration\n\t}\n\treturn pto\n}\n\n// same logic as getLossTimeAndSpace, but for lastAckElicitingPacketTime instead of lossTime\nfunc (h *sentPacketHandler) getPTOTimeAndSpace(now time.Time) (pto time.Time, encLevel protocol.EncryptionLevel) {\n\t// We only send application data probe packets once the handshake is confirmed,\n\t// because before that, we don't have the keys to decrypt ACKs sent in 1-RTT packets.\n\tif !h.handshakeConfirmed && !h.hasOutstandingCryptoPackets() {\n\t\tif h.peerCompletedAddressValidation {\n\t\t\treturn\n\t\t}\n\t\tt := now.Add(h.getScaledPTO(false))\n\t\tif h.initialPackets != nil {\n\t\t\treturn t, protocol.EncryptionInitial\n\t\t}\n\t\treturn t, protocol.EncryptionHandshake\n\t}\n\n\tif h.initialPackets != nil && h.initialPackets.history.HasOutstandingPackets() &&\n\t\t!h.initialPackets.lastAckElicitingPacketTime.IsZero() {\n\t\tencLevel = protocol.EncryptionInitial\n\t\tif t := h.initialPackets.lastAckElicitingPacketTime; !t.IsZero() {\n\t\t\tpto = t.Add(h.getScaledPTO(false))\n\t\t}\n\t}\n\tif h.handshakePackets != nil && h.handshakePackets.history.HasOutstandingPackets() &&\n\t\t!h.handshakePackets.lastAckElicitingPacketTime.IsZero() {\n\t\tt := h.handshakePackets.lastAckElicitingPacketTime.Add(h.getScaledPTO(false))\n\t\tif pto.IsZero() || (!t.IsZero() && t.Before(pto)) {\n\t\t\tpto = t\n\t\t\tencLevel = protocol.EncryptionHandshake\n\t\t}\n\t}\n\tif h.handshakeConfirmed && h.appDataPackets.history.HasOutstandingPackets() &&\n\t\t!h.appDataPackets.lastAckElicitingPacketTime.IsZero() {\n\t\tt := h.appDataPackets.lastAckElicitingPacketTime.Add(h.getScaledPTO(true))\n\t\tif pto.IsZero() || (!t.IsZero() && t.Before(pto)) {\n\t\t\tpto = t\n\t\t\tencLevel = protocol.Encryption1RTT\n\t\t}\n\t}\n\treturn pto, encLevel\n}\n\nfunc (h *sentPacketHandler) hasOutstandingCryptoPackets() bool {\n\tif h.initialPackets != nil && h.initialPackets.history.HasOutstandingPackets() {\n\t\treturn true\n\t}\n\tif h.handshakePackets != nil && h.handshakePackets.history.HasOutstandingPackets() {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (h *sentPacketHandler) setLossDetectionTimer(now time.Time) {\n\toldAlarm := h.alarm // only needed in case tracing is enabled\n\tnewAlarm := h.lossDetectionTime(now)\n\th.alarm = newAlarm\n\n\thasAlarm := !newAlarm.Time.IsZero()\n\tif !hasAlarm && !oldAlarm.Time.IsZero() {\n\t\th.logger.Debugf(\"Canceling loss detection timer.\")\n\t\tif h.tracer != nil && h.tracer.LossTimerCanceled != nil {\n\t\t\th.tracer.LossTimerCanceled()\n\t\t}\n\t}\n\n\tif hasAlarm && h.tracer != nil && h.tracer.SetLossTimer != nil && newAlarm != oldAlarm {\n\t\th.tracer.SetLossTimer(newAlarm.TimerType, newAlarm.EncryptionLevel, newAlarm.Time)\n\t}\n}\n\nfunc (h *sentPacketHandler) lossDetectionTime(now time.Time) alarmTimer {\n\t// cancel the alarm if no packets are outstanding\n\tif h.peerCompletedAddressValidation && !h.hasOutstandingCryptoPackets() &&\n\t\t!h.appDataPackets.history.HasOutstandingPackets() && !h.appDataPackets.history.HasOutstandingPathProbes() {\n\t\treturn alarmTimer{}\n\t}\n\n\t// cancel the alarm if amplification limited\n\tif h.isAmplificationLimited() {\n\t\treturn alarmTimer{}\n\t}\n\n\tvar pathProbeLossTime time.Time\n\tif h.appDataPackets.history.HasOutstandingPathProbes() {\n\t\tif p := h.appDataPackets.history.FirstOutstandingPathProbe(); p != nil {\n\t\t\tpathProbeLossTime = p.SendTime.Add(pathProbePacketLossTimeout)\n\t\t}\n\t}\n\n\t// early retransmit timer or time loss detection\n\tlossTime, encLevel := h.getLossTimeAndSpace()\n\tif !lossTime.IsZero() && (pathProbeLossTime.IsZero() || lossTime.Before(pathProbeLossTime)) {\n\t\treturn alarmTimer{\n\t\t\tTime:            lossTime,\n\t\t\tTimerType:       logging.TimerTypeACK,\n\t\t\tEncryptionLevel: encLevel,\n\t\t}\n\t}\n\tptoTime, encLevel := h.getPTOTimeAndSpace(now)\n\tif !ptoTime.IsZero() && (pathProbeLossTime.IsZero() || ptoTime.Before(pathProbeLossTime)) {\n\t\treturn alarmTimer{\n\t\t\tTime:            ptoTime,\n\t\t\tTimerType:       logging.TimerTypePTO,\n\t\t\tEncryptionLevel: encLevel,\n\t\t}\n\t}\n\tif !pathProbeLossTime.IsZero() {\n\t\treturn alarmTimer{\n\t\t\tTime:            pathProbeLossTime,\n\t\t\tTimerType:       logging.TimerTypePathProbe,\n\t\t\tEncryptionLevel: protocol.Encryption1RTT,\n\t\t}\n\t}\n\treturn alarmTimer{}\n}\n\nfunc (h *sentPacketHandler) detectLostPathProbes(now time.Time) {\n\tif !h.appDataPackets.history.HasOutstandingPathProbes() {\n\t\treturn\n\t}\n\tlossTime := now.Add(-pathProbePacketLossTimeout)\n\t// RemovePathProbe cannot be called while iterating.\n\tvar lostPathProbes []*packet\n\tfor p := range h.appDataPackets.history.PathProbes() {\n\t\tif !p.SendTime.After(lossTime) {\n\t\t\tlostPathProbes = append(lostPathProbes, p)\n\t\t}\n\t}\n\tfor _, p := range lostPathProbes {\n\t\tfor _, f := range p.Frames {\n\t\t\tf.Handler.OnLost(f.Frame)\n\t\t}\n\t\th.appDataPackets.history.RemovePathProbe(p.PacketNumber)\n\t}\n}\n\nfunc (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.EncryptionLevel) {\n\tpnSpace := h.getPacketNumberSpace(encLevel)\n\tpnSpace.lossTime = time.Time{}\n\n\tmaxRTT := float64(max(h.rttStats.LatestRTT(), h.rttStats.SmoothedRTT()))\n\tlossDelay := time.Duration(timeThreshold * maxRTT)\n\n\t// Minimum time of granularity before packets are deemed lost.\n\tlossDelay = max(lossDelay, protocol.TimerGranularity)\n\n\t// Packets sent before this time are deemed lost.\n\tlostSendTime := now.Add(-lossDelay)\n\n\tpriorInFlight := h.bytesInFlight\n\tfor p := range pnSpace.history.Packets() {\n\t\tif p.PacketNumber > pnSpace.largestAcked {\n\t\t\tbreak\n\t\t}\n\n\t\tisRegularPacket := !p.skippedPacket && !p.isPathProbePacket\n\t\tvar packetLost bool\n\t\tif !p.SendTime.After(lostSendTime) {\n\t\t\tpacketLost = true\n\t\t\tif isRegularPacket {\n\t\t\t\tif h.logger.Debug() {\n\t\t\t\t\th.logger.Debugf(\"\\tlost packet %d (time threshold)\", p.PacketNumber)\n\t\t\t\t}\n\t\t\t\tif h.tracer != nil && h.tracer.LostPacket != nil {\n\t\t\t\t\th.tracer.LostPacket(p.EncryptionLevel, p.PacketNumber, logging.PacketLossTimeThreshold)\n\t\t\t\t}\n\t\t\t}\n\t\t} else if pnSpace.largestAcked >= p.PacketNumber+packetThreshold {\n\t\t\tpacketLost = true\n\t\t\tif isRegularPacket {\n\t\t\t\tif h.logger.Debug() {\n\t\t\t\t\th.logger.Debugf(\"\\tlost packet %d (reordering threshold)\", p.PacketNumber)\n\t\t\t\t}\n\t\t\t\tif h.tracer != nil && h.tracer.LostPacket != nil {\n\t\t\t\t\th.tracer.LostPacket(p.EncryptionLevel, p.PacketNumber, logging.PacketLossReorderingThreshold)\n\t\t\t\t}\n\t\t\t}\n\t\t} else if pnSpace.lossTime.IsZero() {\n\t\t\t// Note: This conditional is only entered once per call\n\t\t\tlossTime := p.SendTime.Add(lossDelay)\n\t\t\tif h.logger.Debug() {\n\t\t\t\th.logger.Debugf(\"\\tsetting loss timer for packet %d (%s) to %s (in %s)\", p.PacketNumber, encLevel, lossDelay, lossTime)\n\t\t\t}\n\t\t\tpnSpace.lossTime = lossTime\n\t\t}\n\t\tif packetLost {\n\t\t\tpnSpace.history.DeclareLost(p.PacketNumber)\n\t\t\tif isRegularPacket {\n\t\t\t\t// the bytes in flight need to be reduced no matter if the frames in this packet will be retransmitted\n\t\t\t\th.removeFromBytesInFlight(p)\n\t\t\t\th.queueFramesForRetransmission(p)\n\t\t\t\tif !p.IsPathMTUProbePacket {\n\t\t\t\t\th.congestion.OnCongestionEvent(p.PacketNumber, p.Length, priorInFlight)\n\t\t\t\t}\n\t\t\t\tif encLevel == protocol.Encryption1RTT && h.ecnTracker != nil {\n\t\t\t\t\th.ecnTracker.LostPacket(p.PacketNumber)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (h *sentPacketHandler) OnLossDetectionTimeout(now time.Time) error {\n\tdefer h.setLossDetectionTimer(now)\n\n\tif h.handshakeConfirmed {\n\t\th.detectLostPathProbes(now)\n\t}\n\n\tearliestLossTime, encLevel := h.getLossTimeAndSpace()\n\tif !earliestLossTime.IsZero() {\n\t\tif h.logger.Debug() {\n\t\t\th.logger.Debugf(\"Loss detection alarm fired in loss timer mode. Loss time: %s\", earliestLossTime)\n\t\t}\n\t\tif h.tracer != nil && h.tracer.LossTimerExpired != nil {\n\t\t\th.tracer.LossTimerExpired(logging.TimerTypeACK, encLevel)\n\t\t}\n\t\t// Early retransmit or time loss detection\n\t\th.detectLostPackets(now, encLevel)\n\t\treturn nil\n\t}\n\n\t// PTO\n\t// When all outstanding are acknowledged, the alarm is canceled in setLossDetectionTimer.\n\t// However, there's no way to reset the timer in the connection.\n\t// When OnLossDetectionTimeout is called, we therefore need to make sure that there are\n\t// actually packets outstanding.\n\tif h.bytesInFlight == 0 && !h.peerCompletedAddressValidation {\n\t\th.ptoCount++\n\t\th.numProbesToSend++\n\t\tif h.initialPackets != nil {\n\t\t\th.ptoMode = SendPTOInitial\n\t\t} else if h.handshakePackets != nil {\n\t\t\th.ptoMode = SendPTOHandshake\n\t\t} else {\n\t\t\treturn errors.New(\"sentPacketHandler BUG: PTO fired, but bytes_in_flight is 0 and Initial and Handshake already dropped\")\n\t\t}\n\t\treturn nil\n\t}\n\n\tptoTime, encLevel := h.getPTOTimeAndSpace(now)\n\tif ptoTime.IsZero() {\n\t\treturn nil\n\t}\n\tps := h.getPacketNumberSpace(encLevel)\n\tif !ps.history.HasOutstandingPackets() && !ps.history.HasOutstandingPathProbes() && !h.peerCompletedAddressValidation {\n\t\treturn nil\n\t}\n\th.ptoCount++\n\tif h.logger.Debug() {\n\t\th.logger.Debugf(\"Loss detection alarm for %s fired in PTO mode. PTO count: %d\", encLevel, h.ptoCount)\n\t}\n\tif h.tracer != nil {\n\t\tif h.tracer.LossTimerExpired != nil {\n\t\t\th.tracer.LossTimerExpired(logging.TimerTypePTO, encLevel)\n\t\t}\n\t\tif h.tracer.UpdatedPTOCount != nil {\n\t\t\th.tracer.UpdatedPTOCount(h.ptoCount)\n\t\t}\n\t}\n\th.numProbesToSend += 2\n\t//nolint:exhaustive // We never arm a PTO timer for 0-RTT packets.\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\th.ptoMode = SendPTOInitial\n\tcase protocol.EncryptionHandshake:\n\t\th.ptoMode = SendPTOHandshake\n\tcase protocol.Encryption1RTT:\n\t\t// skip a packet number in order to elicit an immediate ACK\n\t\tpn := h.PopPacketNumber(protocol.Encryption1RTT)\n\t\th.getPacketNumberSpace(protocol.Encryption1RTT).history.SkippedPacket(pn)\n\t\th.ptoMode = SendPTOAppData\n\tdefault:\n\t\treturn fmt.Errorf(\"PTO timer in unexpected encryption level: %s\", encLevel)\n\t}\n\treturn nil\n}\n\nfunc (h *sentPacketHandler) GetLossDetectionTimeout() time.Time {\n\treturn h.alarm.Time\n}\n\nfunc (h *sentPacketHandler) ECNMode(isShortHeaderPacket bool) protocol.ECN {\n\tif !h.enableECN {\n\t\treturn protocol.ECNUnsupported\n\t}\n\tif !isShortHeaderPacket {\n\t\treturn protocol.ECNNon\n\t}\n\treturn h.ecnTracker.Mode()\n}\n\nfunc (h *sentPacketHandler) PeekPacketNumber(encLevel protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen) {\n\tpnSpace := h.getPacketNumberSpace(encLevel)\n\tpn := pnSpace.pns.Peek()\n\t// See section 17.1 of RFC 9000.\n\treturn pn, protocol.PacketNumberLengthForHeader(pn, pnSpace.largestAcked)\n}\n\nfunc (h *sentPacketHandler) PopPacketNumber(encLevel protocol.EncryptionLevel) protocol.PacketNumber {\n\tpnSpace := h.getPacketNumberSpace(encLevel)\n\tskipped, pn := pnSpace.pns.Pop()\n\tif skipped {\n\t\tskippedPN := pn - 1\n\t\tpnSpace.history.SkippedPacket(skippedPN)\n\t\tif h.logger.Debug() {\n\t\t\th.logger.Debugf(\"Skipping packet number %d\", skippedPN)\n\t\t}\n\t}\n\treturn pn\n}\n\nfunc (h *sentPacketHandler) SendMode(now time.Time) SendMode {\n\tnumTrackedPackets := h.appDataPackets.history.Len()\n\tif h.initialPackets != nil {\n\t\tnumTrackedPackets += h.initialPackets.history.Len()\n\t}\n\tif h.handshakePackets != nil {\n\t\tnumTrackedPackets += h.handshakePackets.history.Len()\n\t}\n\n\tif h.isAmplificationLimited() {\n\t\th.logger.Debugf(\"Amplification window limited. Received %d bytes, already sent out %d bytes\", h.bytesReceived, h.bytesSent)\n\t\treturn SendNone\n\t}\n\t// Don't send any packets if we're keeping track of the maximum number of packets.\n\t// Note that since MaxOutstandingSentPackets is smaller than MaxTrackedSentPackets,\n\t// we will stop sending out new data when reaching MaxOutstandingSentPackets,\n\t// but still allow sending of retransmissions and ACKs.\n\tif numTrackedPackets >= protocol.MaxTrackedSentPackets {\n\t\tif h.logger.Debug() {\n\t\t\th.logger.Debugf(\"Limited by the number of tracked packets: tracking %d packets, maximum %d\", numTrackedPackets, protocol.MaxTrackedSentPackets)\n\t\t}\n\t\treturn SendNone\n\t}\n\tif h.numProbesToSend > 0 {\n\t\treturn h.ptoMode\n\t}\n\t// Only send ACKs if we're congestion limited.\n\tif !h.congestion.CanSend(h.bytesInFlight) {\n\t\tif h.logger.Debug() {\n\t\t\th.logger.Debugf(\"Congestion limited: bytes in flight %d, window %d\", h.bytesInFlight, h.congestion.GetCongestionWindow())\n\t\t}\n\t\treturn SendAck\n\t}\n\tif numTrackedPackets >= protocol.MaxOutstandingSentPackets {\n\t\tif h.logger.Debug() {\n\t\t\th.logger.Debugf(\"Max outstanding limited: tracking %d packets, maximum: %d\", numTrackedPackets, protocol.MaxOutstandingSentPackets)\n\t\t}\n\t\treturn SendAck\n\t}\n\tif !h.congestion.HasPacingBudget(now) {\n\t\treturn SendPacingLimited\n\t}\n\treturn SendAny\n}\n\nfunc (h *sentPacketHandler) TimeUntilSend() time.Time {\n\treturn h.congestion.TimeUntilSend(h.bytesInFlight)\n}\n\nfunc (h *sentPacketHandler) SetMaxDatagramSize(s protocol.ByteCount) {\n\th.congestion.SetMaxDatagramSize(s)\n}\n\nfunc (h *sentPacketHandler) isAmplificationLimited() bool {\n\tif h.peerAddressValidated {\n\t\treturn false\n\t}\n\treturn h.bytesSent >= amplificationFactor*h.bytesReceived\n}\n\nfunc (h *sentPacketHandler) QueueProbePacket(encLevel protocol.EncryptionLevel) bool {\n\tpnSpace := h.getPacketNumberSpace(encLevel)\n\tp := pnSpace.history.FirstOutstanding()\n\tif p == nil {\n\t\treturn false\n\t}\n\th.queueFramesForRetransmission(p)\n\t// TODO: don't declare the packet lost here.\n\t// Keep track of acknowledged frames instead.\n\th.removeFromBytesInFlight(p)\n\tpnSpace.history.DeclareLost(p.PacketNumber)\n\treturn true\n}\n\nfunc (h *sentPacketHandler) queueFramesForRetransmission(p *packet) {\n\tif len(p.Frames) == 0 && len(p.StreamFrames) == 0 {\n\t\tpanic(\"no frames\")\n\t}\n\tfor _, f := range p.Frames {\n\t\tif f.Handler != nil {\n\t\t\tf.Handler.OnLost(f.Frame)\n\t\t}\n\t}\n\tfor _, f := range p.StreamFrames {\n\t\tif f.Handler != nil {\n\t\t\tf.Handler.OnLost(f.Frame)\n\t\t}\n\t}\n\tp.StreamFrames = nil\n\tp.Frames = nil\n}\n\nfunc (h *sentPacketHandler) ResetForRetry(now time.Time) {\n\th.bytesInFlight = 0\n\tvar firstPacketSendTime time.Time\n\tfor p := range h.initialPackets.history.Packets() {\n\t\tif firstPacketSendTime.IsZero() {\n\t\t\tfirstPacketSendTime = p.SendTime\n\t\t}\n\t\tif !p.declaredLost && !p.skippedPacket {\n\t\t\th.queueFramesForRetransmission(p)\n\t\t}\n\t}\n\t// All application data packets sent at this point are 0-RTT packets.\n\t// In the case of a Retry, we can assume that the server dropped all of them.\n\tfor p := range h.appDataPackets.history.Packets() {\n\t\tif !p.declaredLost && !p.skippedPacket {\n\t\t\th.queueFramesForRetransmission(p)\n\t\t}\n\t}\n\n\t// Only use the Retry to estimate the RTT if we didn't send any retransmission for the Initial.\n\t// Otherwise, we don't know which Initial the Retry was sent in response to.\n\tif h.ptoCount == 0 {\n\t\t// Don't set the RTT to a value lower than 5ms here.\n\t\th.rttStats.UpdateRTT(max(minRTTAfterRetry, now.Sub(firstPacketSendTime)), 0)\n\t\tif h.logger.Debug() {\n\t\t\th.logger.Debugf(\"\\tupdated RTT: %s (σ: %s)\", h.rttStats.SmoothedRTT(), h.rttStats.MeanDeviation())\n\t\t}\n\t\tif h.tracer != nil && h.tracer.UpdatedMetrics != nil {\n\t\t\th.tracer.UpdatedMetrics(h.rttStats, h.congestion.GetCongestionWindow(), h.bytesInFlight, h.packetsInFlight())\n\t\t}\n\t}\n\th.initialPackets = newPacketNumberSpace(h.initialPackets.pns.Peek(), false)\n\th.appDataPackets = newPacketNumberSpace(h.appDataPackets.pns.Peek(), true)\n\toldAlarm := h.alarm\n\th.alarm = alarmTimer{}\n\tif h.tracer != nil {\n\t\tif h.tracer.UpdatedPTOCount != nil {\n\t\t\th.tracer.UpdatedPTOCount(0)\n\t\t}\n\t\tif !oldAlarm.Time.IsZero() && h.tracer.LossTimerCanceled != nil {\n\t\t\th.tracer.LossTimerCanceled()\n\t\t}\n\t}\n\th.ptoCount = 0\n}\n\nfunc (h *sentPacketHandler) MigratedPath(now time.Time, initialMaxDatagramSize protocol.ByteCount) {\n\th.rttStats.ResetForPathMigration()\n\tfor p := range h.appDataPackets.history.Packets() {\n\t\th.appDataPackets.history.DeclareLost(p.PacketNumber)\n\t\tif !p.skippedPacket && !p.isPathProbePacket {\n\t\t\th.removeFromBytesInFlight(p)\n\t\t\th.queueFramesForRetransmission(p)\n\t\t}\n\t}\n\tfor p := range h.appDataPackets.history.PathProbes() {\n\t\th.appDataPackets.history.RemovePathProbe(p.PacketNumber)\n\t}\n\th.congestion = congestion.NewCubicSender(\n\t\tcongestion.DefaultClock{},\n\t\th.rttStats,\n\t\tinitialMaxDatagramSize,\n\t\ttrue, // use Reno\n\t\th.tracer,\n\t)\n\th.setLossDetectionTimer(now)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/ackhandler/sent_packet_history.go",
    "content": "package ackhandler\n\nimport (\n\t\"fmt\"\n\t\"iter\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\ntype sentPacketHistory struct {\n\tpackets          []*packet\n\tpathProbePackets []*packet\n\n\tnumOutstanding int\n\n\thighestPacketNumber protocol.PacketNumber\n}\n\nfunc newSentPacketHistory(isAppData bool) *sentPacketHistory {\n\th := &sentPacketHistory{\n\t\thighestPacketNumber: protocol.InvalidPacketNumber,\n\t}\n\tif isAppData {\n\t\th.packets = make([]*packet, 0, 32)\n\t} else {\n\t\th.packets = make([]*packet, 0, 6)\n\t}\n\treturn h\n}\n\nfunc (h *sentPacketHistory) checkSequentialPacketNumberUse(pn protocol.PacketNumber) {\n\tif h.highestPacketNumber != protocol.InvalidPacketNumber {\n\t\tif pn != h.highestPacketNumber+1 {\n\t\t\tpanic(\"non-sequential packet number use\")\n\t\t}\n\t}\n\th.highestPacketNumber = pn\n}\n\nfunc (h *sentPacketHistory) SkippedPacket(pn protocol.PacketNumber) {\n\th.checkSequentialPacketNumberUse(pn)\n\th.packets = append(h.packets, &packet{\n\t\tPacketNumber:  pn,\n\t\tskippedPacket: true,\n\t})\n}\n\nfunc (h *sentPacketHistory) SentNonAckElicitingPacket(pn protocol.PacketNumber) {\n\th.checkSequentialPacketNumberUse(pn)\n\tif len(h.packets) > 0 {\n\t\th.packets = append(h.packets, nil)\n\t}\n}\n\nfunc (h *sentPacketHistory) SentAckElicitingPacket(p *packet) {\n\th.checkSequentialPacketNumberUse(p.PacketNumber)\n\th.packets = append(h.packets, p)\n\tif p.outstanding() {\n\t\th.numOutstanding++\n\t}\n}\n\nfunc (h *sentPacketHistory) SentPathProbePacket(p *packet) {\n\th.checkSequentialPacketNumberUse(p.PacketNumber)\n\th.packets = append(h.packets, &packet{\n\t\tPacketNumber:      p.PacketNumber,\n\t\tisPathProbePacket: true,\n\t})\n\th.pathProbePackets = append(h.pathProbePackets, p)\n}\n\nfunc (h *sentPacketHistory) Packets() iter.Seq[*packet] {\n\treturn func(yield func(*packet) bool) {\n\t\tfor _, p := range h.packets {\n\t\t\tif p == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif !yield(p) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (h *sentPacketHistory) PathProbes() iter.Seq[*packet] {\n\treturn func(yield func(*packet) bool) {\n\t\tfor _, p := range h.pathProbePackets {\n\t\t\tif !yield(p) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n}\n\n// FirstOutstanding returns the first outstanding packet.\nfunc (h *sentPacketHistory) FirstOutstanding() *packet {\n\tif !h.HasOutstandingPackets() {\n\t\treturn nil\n\t}\n\tfor _, p := range h.packets {\n\t\tif p != nil && p.outstanding() {\n\t\t\treturn p\n\t\t}\n\t}\n\treturn nil\n}\n\n// FirstOutstandingPathProbe returns the first outstanding path probe packet\nfunc (h *sentPacketHistory) FirstOutstandingPathProbe() *packet {\n\tif len(h.pathProbePackets) == 0 {\n\t\treturn nil\n\t}\n\treturn h.pathProbePackets[0]\n}\n\nfunc (h *sentPacketHistory) Len() int {\n\treturn len(h.packets)\n}\n\nfunc (h *sentPacketHistory) Remove(pn protocol.PacketNumber) error {\n\tidx, ok := h.getIndex(pn)\n\tif !ok {\n\t\treturn fmt.Errorf(\"packet %d not found in sent packet history\", pn)\n\t}\n\tp := h.packets[idx]\n\tif p.outstanding() {\n\t\th.numOutstanding--\n\t\tif h.numOutstanding < 0 {\n\t\t\tpanic(\"negative number of outstanding packets\")\n\t\t}\n\t}\n\th.packets[idx] = nil\n\t// clean up all skipped packets directly before this packet number\n\tfor idx > 0 {\n\t\tidx--\n\t\tp := h.packets[idx]\n\t\tif p == nil || !p.skippedPacket {\n\t\t\tbreak\n\t\t}\n\t\th.packets[idx] = nil\n\t}\n\tif idx == 0 {\n\t\th.cleanupStart()\n\t}\n\tif len(h.packets) > 0 && h.packets[0] == nil {\n\t\tpanic(\"remove failed\")\n\t}\n\treturn nil\n}\n\n// RemovePathProbe removes a path probe packet.\n// It scales O(N), but that's ok, since we don't expect to send many path probe packets.\n// It is not valid to call this function in IteratePathProbes.\nfunc (h *sentPacketHistory) RemovePathProbe(pn protocol.PacketNumber) *packet {\n\tvar packetToDelete *packet\n\tidx := -1\n\tfor i, p := range h.pathProbePackets {\n\t\tif p.PacketNumber == pn {\n\t\t\tpacketToDelete = p\n\t\t\tidx = i\n\t\t\tbreak\n\t\t}\n\t}\n\tif idx != -1 {\n\t\t// don't use slices.Delete, because it zeros the deleted element\n\t\tcopy(h.pathProbePackets[idx:], h.pathProbePackets[idx+1:])\n\t\th.pathProbePackets = h.pathProbePackets[:len(h.pathProbePackets)-1]\n\t}\n\treturn packetToDelete\n}\n\n// getIndex gets the index of packet p in the packets slice.\nfunc (h *sentPacketHistory) getIndex(p protocol.PacketNumber) (int, bool) {\n\tif len(h.packets) == 0 {\n\t\treturn 0, false\n\t}\n\tfirst := h.packets[0].PacketNumber\n\tif p < first {\n\t\treturn 0, false\n\t}\n\tindex := int(p - first)\n\tif index > len(h.packets)-1 {\n\t\treturn 0, false\n\t}\n\treturn index, true\n}\n\nfunc (h *sentPacketHistory) HasOutstandingPackets() bool {\n\treturn h.numOutstanding > 0\n}\n\nfunc (h *sentPacketHistory) HasOutstandingPathProbes() bool {\n\treturn len(h.pathProbePackets) > 0\n}\n\n// delete all nil entries at the beginning of the packets slice\nfunc (h *sentPacketHistory) cleanupStart() {\n\tfor i, p := range h.packets {\n\t\tif p != nil {\n\t\t\th.packets = h.packets[i:]\n\t\t\treturn\n\t\t}\n\t}\n\th.packets = h.packets[:0]\n}\n\nfunc (h *sentPacketHistory) LowestPacketNumber() protocol.PacketNumber {\n\tif len(h.packets) == 0 {\n\t\treturn protocol.InvalidPacketNumber\n\t}\n\treturn h.packets[0].PacketNumber\n}\n\nfunc (h *sentPacketHistory) DeclareLost(pn protocol.PacketNumber) {\n\tidx, ok := h.getIndex(pn)\n\tif !ok {\n\t\treturn\n\t}\n\tp := h.packets[idx]\n\tif p.outstanding() {\n\t\th.numOutstanding--\n\t\tif h.numOutstanding < 0 {\n\t\t\tpanic(\"negative number of outstanding packets\")\n\t\t}\n\t}\n\th.packets[idx] = nil\n\tif idx == 0 {\n\t\th.cleanupStart()\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/congestion/bandwidth.go",
    "content": "package congestion\n\nimport (\n\t\"math\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\n// Bandwidth of a connection\ntype Bandwidth uint64\n\nconst infBandwidth Bandwidth = math.MaxUint64\n\nconst (\n\t// BitsPerSecond is 1 bit per second\n\tBitsPerSecond Bandwidth = 1\n\t// BytesPerSecond is 1 byte per second\n\tBytesPerSecond = 8 * BitsPerSecond\n)\n\n// BandwidthFromDelta calculates the bandwidth from a number of bytes and a time delta\nfunc BandwidthFromDelta(bytes protocol.ByteCount, delta time.Duration) Bandwidth {\n\treturn Bandwidth(bytes) * Bandwidth(time.Second) / Bandwidth(delta) * BytesPerSecond\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/congestion/clock.go",
    "content": "package congestion\n\nimport \"time\"\n\n// A Clock returns the current time\ntype Clock interface {\n\tNow() time.Time\n}\n\n// DefaultClock implements the Clock interface using the Go stdlib clock.\ntype DefaultClock struct{}\n\nvar _ Clock = DefaultClock{}\n\n// Now gets the current time\nfunc (DefaultClock) Now() time.Time {\n\treturn time.Now()\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/congestion/cubic.go",
    "content": "package congestion\n\nimport (\n\t\"math\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\n// This cubic implementation is based on the one found in Chromiums's QUIC\n// implementation, in the files net/quic/congestion_control/cubic.{hh,cc}.\n\n// Constants based on TCP defaults.\n// The following constants are in 2^10 fractions of a second instead of ms to\n// allow a 10 shift right to divide.\n\n// 1024*1024^3 (first 1024 is from 0.100^3)\n// where 0.100 is 100 ms which is the scaling round trip time.\nconst (\n\tcubeScale                 = 40\n\tcubeCongestionWindowScale = 410\n\tcubeFactor                = 1 << cubeScale / cubeCongestionWindowScale / maxDatagramSize\n\t// TODO: when re-enabling cubic, make sure to use the actual packet size here\n\tmaxDatagramSize = protocol.ByteCount(protocol.InitialPacketSize)\n)\n\nconst defaultNumConnections = 1\n\n// Default Cubic backoff factor\nconst beta float32 = 0.7\n\n// Additional backoff factor when loss occurs in the concave part of the Cubic\n// curve. This additional backoff factor is expected to give up bandwidth to\n// new concurrent flows and speed up convergence.\nconst betaLastMax float32 = 0.85\n\n// Cubic implements the cubic algorithm from TCP\ntype Cubic struct {\n\tclock Clock\n\n\t// Number of connections to simulate.\n\tnumConnections int\n\n\t// Time when this cycle started, after last loss event.\n\tepoch time.Time\n\n\t// Max congestion window used just before last loss event.\n\t// Note: to improve fairness to other streams an additional back off is\n\t// applied to this value if the new value is below our latest value.\n\tlastMaxCongestionWindow protocol.ByteCount\n\n\t// Number of acked bytes since the cycle started (epoch).\n\tackedBytesCount protocol.ByteCount\n\n\t// TCP Reno equivalent congestion window in packets.\n\testimatedTCPcongestionWindow protocol.ByteCount\n\n\t// Origin point of cubic function.\n\toriginPointCongestionWindow protocol.ByteCount\n\n\t// Time to origin point of cubic function in 2^10 fractions of a second.\n\ttimeToOriginPoint uint32\n\n\t// Last congestion window in packets computed by cubic function.\n\tlastTargetCongestionWindow protocol.ByteCount\n}\n\n// NewCubic returns a new Cubic instance\nfunc NewCubic(clock Clock) *Cubic {\n\tc := &Cubic{\n\t\tclock:          clock,\n\t\tnumConnections: defaultNumConnections,\n\t}\n\tc.Reset()\n\treturn c\n}\n\n// Reset is called after a timeout to reset the cubic state\nfunc (c *Cubic) Reset() {\n\tc.epoch = time.Time{}\n\tc.lastMaxCongestionWindow = 0\n\tc.ackedBytesCount = 0\n\tc.estimatedTCPcongestionWindow = 0\n\tc.originPointCongestionWindow = 0\n\tc.timeToOriginPoint = 0\n\tc.lastTargetCongestionWindow = 0\n}\n\nfunc (c *Cubic) alpha() float32 {\n\t// TCPFriendly alpha is described in Section 3.3 of the CUBIC paper. Note that\n\t// beta here is a cwnd multiplier, and is equal to 1-beta from the paper.\n\t// We derive the equivalent alpha for an N-connection emulation as:\n\tb := c.beta()\n\treturn 3 * float32(c.numConnections) * float32(c.numConnections) * (1 - b) / (1 + b)\n}\n\nfunc (c *Cubic) beta() float32 {\n\t// kNConnectionBeta is the backoff factor after loss for our N-connection\n\t// emulation, which emulates the effective backoff of an ensemble of N\n\t// TCP-Reno connections on a single loss event. The effective multiplier is\n\t// computed as:\n\treturn (float32(c.numConnections) - 1 + beta) / float32(c.numConnections)\n}\n\nfunc (c *Cubic) betaLastMax() float32 {\n\t// betaLastMax is the additional backoff factor after loss for our\n\t// N-connection emulation, which emulates the additional backoff of\n\t// an ensemble of N TCP-Reno connections on a single loss event. The\n\t// effective multiplier is computed as:\n\treturn (float32(c.numConnections) - 1 + betaLastMax) / float32(c.numConnections)\n}\n\n// OnApplicationLimited is called on ack arrival when sender is unable to use\n// the available congestion window. Resets Cubic state during quiescence.\nfunc (c *Cubic) OnApplicationLimited() {\n\t// When sender is not using the available congestion window, the window does\n\t// not grow. But to be RTT-independent, Cubic assumes that the sender has been\n\t// using the entire window during the time since the beginning of the current\n\t// \"epoch\" (the end of the last loss recovery period). Since\n\t// application-limited periods break this assumption, we reset the epoch when\n\t// in such a period. This reset effectively freezes congestion window growth\n\t// through application-limited periods and allows Cubic growth to continue\n\t// when the entire window is being used.\n\tc.epoch = time.Time{}\n}\n\n// CongestionWindowAfterPacketLoss computes a new congestion window to use after\n// a loss event. Returns the new congestion window in packets. The new\n// congestion window is a multiplicative decrease of our current window.\nfunc (c *Cubic) CongestionWindowAfterPacketLoss(currentCongestionWindow protocol.ByteCount) protocol.ByteCount {\n\tif currentCongestionWindow+maxDatagramSize < c.lastMaxCongestionWindow {\n\t\t// We never reached the old max, so assume we are competing with another\n\t\t// flow. Use our extra back off factor to allow the other flow to go up.\n\t\tc.lastMaxCongestionWindow = protocol.ByteCount(c.betaLastMax() * float32(currentCongestionWindow))\n\t} else {\n\t\tc.lastMaxCongestionWindow = currentCongestionWindow\n\t}\n\tc.epoch = time.Time{} // Reset time.\n\treturn protocol.ByteCount(float32(currentCongestionWindow) * c.beta())\n}\n\n// CongestionWindowAfterAck computes a new congestion window to use after a received ACK.\n// Returns the new congestion window in packets. The new congestion window\n// follows a cubic function that depends on the time passed since last\n// packet loss.\nfunc (c *Cubic) CongestionWindowAfterAck(\n\tackedBytes protocol.ByteCount,\n\tcurrentCongestionWindow protocol.ByteCount,\n\tdelayMin time.Duration,\n\teventTime time.Time,\n) protocol.ByteCount {\n\tc.ackedBytesCount += ackedBytes\n\n\tif c.epoch.IsZero() {\n\t\t// First ACK after a loss event.\n\t\tc.epoch = eventTime            // Start of epoch.\n\t\tc.ackedBytesCount = ackedBytes // Reset count.\n\t\t// Reset estimated_tcp_congestion_window_ to be in sync with cubic.\n\t\tc.estimatedTCPcongestionWindow = currentCongestionWindow\n\t\tif c.lastMaxCongestionWindow <= currentCongestionWindow {\n\t\t\tc.timeToOriginPoint = 0\n\t\t\tc.originPointCongestionWindow = currentCongestionWindow\n\t\t} else {\n\t\t\tc.timeToOriginPoint = uint32(math.Cbrt(float64(cubeFactor * (c.lastMaxCongestionWindow - currentCongestionWindow))))\n\t\t\tc.originPointCongestionWindow = c.lastMaxCongestionWindow\n\t\t}\n\t}\n\n\t// Change the time unit from microseconds to 2^10 fractions per second. Take\n\t// the round trip time in account. This is done to allow us to use shift as a\n\t// divide operator.\n\telapsedTime := int64(eventTime.Add(delayMin).Sub(c.epoch)/time.Microsecond) << 10 / (1000 * 1000)\n\n\t// Right-shifts of negative, signed numbers have implementation-dependent\n\t// behavior, so force the offset to be positive, as is done in the kernel.\n\toffset := int64(c.timeToOriginPoint) - elapsedTime\n\tif offset < 0 {\n\t\toffset = -offset\n\t}\n\n\tdeltaCongestionWindow := protocol.ByteCount(cubeCongestionWindowScale*offset*offset*offset) * maxDatagramSize >> cubeScale\n\tvar targetCongestionWindow protocol.ByteCount\n\tif elapsedTime > int64(c.timeToOriginPoint) {\n\t\ttargetCongestionWindow = c.originPointCongestionWindow + deltaCongestionWindow\n\t} else {\n\t\ttargetCongestionWindow = c.originPointCongestionWindow - deltaCongestionWindow\n\t}\n\t// Limit the CWND increase to half the acked bytes.\n\ttargetCongestionWindow = min(targetCongestionWindow, currentCongestionWindow+c.ackedBytesCount/2)\n\n\t// Increase the window by approximately Alpha * 1 MSS of bytes every\n\t// time we ack an estimated tcp window of bytes.  For small\n\t// congestion windows (less than 25), the formula below will\n\t// increase slightly slower than linearly per estimated tcp window\n\t// of bytes.\n\tc.estimatedTCPcongestionWindow += protocol.ByteCount(float32(c.ackedBytesCount) * c.alpha() * float32(maxDatagramSize) / float32(c.estimatedTCPcongestionWindow))\n\tc.ackedBytesCount = 0\n\n\t// We have a new cubic congestion window.\n\tc.lastTargetCongestionWindow = targetCongestionWindow\n\n\t// Compute target congestion_window based on cubic target and estimated TCP\n\t// congestion_window, use highest (fastest).\n\tif targetCongestionWindow < c.estimatedTCPcongestionWindow {\n\t\ttargetCongestionWindow = c.estimatedTCPcongestionWindow\n\t}\n\treturn targetCongestionWindow\n}\n\n// SetNumConnections sets the number of emulated connections\nfunc (c *Cubic) SetNumConnections(n int) {\n\tc.numConnections = n\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/congestion/cubic_sender.go",
    "content": "package congestion\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/logging\"\n)\n\nconst (\n\t// maxDatagramSize is the default maximum packet size used in the Linux TCP implementation.\n\t// Used in QUIC for congestion window computations in bytes.\n\tinitialMaxDatagramSize     = protocol.ByteCount(protocol.InitialPacketSize)\n\tmaxBurstPackets            = 3\n\trenoBeta                   = 0.7 // Reno backoff factor.\n\tminCongestionWindowPackets = 2\n\tinitialCongestionWindow    = 32\n)\n\ntype cubicSender struct {\n\thybridSlowStart HybridSlowStart\n\trttStats        *utils.RTTStats\n\tcubic           *Cubic\n\tpacer           *pacer\n\tclock           Clock\n\n\treno bool\n\n\t// Track the largest packet that has been sent.\n\tlargestSentPacketNumber protocol.PacketNumber\n\n\t// Track the largest packet that has been acked.\n\tlargestAckedPacketNumber protocol.PacketNumber\n\n\t// Track the largest packet number outstanding when a CWND cutback occurs.\n\tlargestSentAtLastCutback protocol.PacketNumber\n\n\t// Whether the last loss event caused us to exit slowstart.\n\t// Used for stats collection of slowstartPacketsLost\n\tlastCutbackExitedSlowstart bool\n\n\t// Congestion window in bytes.\n\tcongestionWindow protocol.ByteCount\n\n\t// Slow start congestion window in bytes, aka ssthresh.\n\tslowStartThreshold protocol.ByteCount\n\n\t// ACK counter for the Reno implementation.\n\tnumAckedPackets uint64\n\n\tinitialCongestionWindow    protocol.ByteCount\n\tinitialMaxCongestionWindow protocol.ByteCount\n\n\tmaxDatagramSize protocol.ByteCount\n\n\tlastState logging.CongestionState\n\ttracer    *logging.ConnectionTracer\n}\n\nvar (\n\t_ SendAlgorithm               = &cubicSender{}\n\t_ SendAlgorithmWithDebugInfos = &cubicSender{}\n)\n\n// NewCubicSender makes a new cubic sender\nfunc NewCubicSender(\n\tclock Clock,\n\trttStats *utils.RTTStats,\n\tinitialMaxDatagramSize protocol.ByteCount,\n\treno bool,\n\ttracer *logging.ConnectionTracer,\n) *cubicSender {\n\treturn newCubicSender(\n\t\tclock,\n\t\trttStats,\n\t\treno,\n\t\tinitialMaxDatagramSize,\n\t\tinitialCongestionWindow*initialMaxDatagramSize,\n\t\tprotocol.MaxCongestionWindowPackets*initialMaxDatagramSize,\n\t\ttracer,\n\t)\n}\n\nfunc newCubicSender(\n\tclock Clock,\n\trttStats *utils.RTTStats,\n\treno bool,\n\tinitialMaxDatagramSize,\n\tinitialCongestionWindow,\n\tinitialMaxCongestionWindow protocol.ByteCount,\n\ttracer *logging.ConnectionTracer,\n) *cubicSender {\n\tc := &cubicSender{\n\t\trttStats:                   rttStats,\n\t\tlargestSentPacketNumber:    protocol.InvalidPacketNumber,\n\t\tlargestAckedPacketNumber:   protocol.InvalidPacketNumber,\n\t\tlargestSentAtLastCutback:   protocol.InvalidPacketNumber,\n\t\tinitialCongestionWindow:    initialCongestionWindow,\n\t\tinitialMaxCongestionWindow: initialMaxCongestionWindow,\n\t\tcongestionWindow:           initialCongestionWindow,\n\t\tslowStartThreshold:         protocol.MaxByteCount,\n\t\tcubic:                      NewCubic(clock),\n\t\tclock:                      clock,\n\t\treno:                       reno,\n\t\ttracer:                     tracer,\n\t\tmaxDatagramSize:            initialMaxDatagramSize,\n\t}\n\tc.pacer = newPacer(c.BandwidthEstimate)\n\tif c.tracer != nil && c.tracer.UpdatedCongestionState != nil {\n\t\tc.lastState = logging.CongestionStateSlowStart\n\t\tc.tracer.UpdatedCongestionState(logging.CongestionStateSlowStart)\n\t}\n\treturn c\n}\n\n// TimeUntilSend returns when the next packet should be sent.\nfunc (c *cubicSender) TimeUntilSend(_ protocol.ByteCount) time.Time {\n\treturn c.pacer.TimeUntilSend()\n}\n\nfunc (c *cubicSender) HasPacingBudget(now time.Time) bool {\n\treturn c.pacer.Budget(now) >= c.maxDatagramSize\n}\n\nfunc (c *cubicSender) maxCongestionWindow() protocol.ByteCount {\n\treturn c.maxDatagramSize * protocol.MaxCongestionWindowPackets\n}\n\nfunc (c *cubicSender) minCongestionWindow() protocol.ByteCount {\n\treturn c.maxDatagramSize * minCongestionWindowPackets\n}\n\nfunc (c *cubicSender) OnPacketSent(\n\tsentTime time.Time,\n\t_ protocol.ByteCount,\n\tpacketNumber protocol.PacketNumber,\n\tbytes protocol.ByteCount,\n\tisRetransmittable bool,\n) {\n\tc.pacer.SentPacket(sentTime, bytes)\n\tif !isRetransmittable {\n\t\treturn\n\t}\n\tc.largestSentPacketNumber = packetNumber\n\tc.hybridSlowStart.OnPacketSent(packetNumber)\n}\n\nfunc (c *cubicSender) CanSend(bytesInFlight protocol.ByteCount) bool {\n\treturn bytesInFlight < c.GetCongestionWindow()\n}\n\nfunc (c *cubicSender) InRecovery() bool {\n\treturn c.largestAckedPacketNumber != protocol.InvalidPacketNumber && c.largestAckedPacketNumber <= c.largestSentAtLastCutback\n}\n\nfunc (c *cubicSender) InSlowStart() bool {\n\treturn c.GetCongestionWindow() < c.slowStartThreshold\n}\n\nfunc (c *cubicSender) GetCongestionWindow() protocol.ByteCount {\n\treturn c.congestionWindow\n}\n\nfunc (c *cubicSender) MaybeExitSlowStart() {\n\tif c.InSlowStart() &&\n\t\tc.hybridSlowStart.ShouldExitSlowStart(c.rttStats.LatestRTT(), c.rttStats.MinRTT(), c.GetCongestionWindow()/c.maxDatagramSize) {\n\t\t// exit slow start\n\t\tc.slowStartThreshold = c.congestionWindow\n\t\tc.maybeTraceStateChange(logging.CongestionStateCongestionAvoidance)\n\t}\n}\n\nfunc (c *cubicSender) OnPacketAcked(\n\tackedPacketNumber protocol.PacketNumber,\n\tackedBytes protocol.ByteCount,\n\tpriorInFlight protocol.ByteCount,\n\teventTime time.Time,\n) {\n\tc.largestAckedPacketNumber = max(ackedPacketNumber, c.largestAckedPacketNumber)\n\tif c.InRecovery() {\n\t\treturn\n\t}\n\tc.maybeIncreaseCwnd(ackedPacketNumber, ackedBytes, priorInFlight, eventTime)\n\tif c.InSlowStart() {\n\t\tc.hybridSlowStart.OnPacketAcked(ackedPacketNumber)\n\t}\n}\n\nfunc (c *cubicSender) OnCongestionEvent(packetNumber protocol.PacketNumber, lostBytes, priorInFlight protocol.ByteCount) {\n\t// TCP NewReno (RFC6582) says that once a loss occurs, any losses in packets\n\t// already sent should be treated as a single loss event, since it's expected.\n\tif packetNumber <= c.largestSentAtLastCutback {\n\t\treturn\n\t}\n\tc.lastCutbackExitedSlowstart = c.InSlowStart()\n\tc.maybeTraceStateChange(logging.CongestionStateRecovery)\n\n\tif c.reno {\n\t\tc.congestionWindow = protocol.ByteCount(float64(c.congestionWindow) * renoBeta)\n\t} else {\n\t\tc.congestionWindow = c.cubic.CongestionWindowAfterPacketLoss(c.congestionWindow)\n\t}\n\tif minCwnd := c.minCongestionWindow(); c.congestionWindow < minCwnd {\n\t\tc.congestionWindow = minCwnd\n\t}\n\tc.slowStartThreshold = c.congestionWindow\n\tc.largestSentAtLastCutback = c.largestSentPacketNumber\n\t// reset packet count from congestion avoidance mode. We start\n\t// counting again when we're out of recovery.\n\tc.numAckedPackets = 0\n}\n\n// Called when we receive an ack. Normal TCP tracks how many packets one ack\n// represents, but quic has a separate ack for each packet.\nfunc (c *cubicSender) maybeIncreaseCwnd(\n\t_ protocol.PacketNumber,\n\tackedBytes protocol.ByteCount,\n\tpriorInFlight protocol.ByteCount,\n\teventTime time.Time,\n) {\n\t// Do not increase the congestion window unless the sender is close to using\n\t// the current window.\n\tif !c.isCwndLimited(priorInFlight) {\n\t\tc.cubic.OnApplicationLimited()\n\t\tc.maybeTraceStateChange(logging.CongestionStateApplicationLimited)\n\t\treturn\n\t}\n\tif c.congestionWindow >= c.maxCongestionWindow() {\n\t\treturn\n\t}\n\tif c.InSlowStart() {\n\t\t// TCP slow start, exponential growth, increase by one for each ACK.\n\t\tc.congestionWindow += c.maxDatagramSize\n\t\tc.maybeTraceStateChange(logging.CongestionStateSlowStart)\n\t\treturn\n\t}\n\t// Congestion avoidance\n\tc.maybeTraceStateChange(logging.CongestionStateCongestionAvoidance)\n\tif c.reno {\n\t\t// Classic Reno congestion avoidance.\n\t\tc.numAckedPackets++\n\t\tif c.numAckedPackets >= uint64(c.congestionWindow/c.maxDatagramSize) {\n\t\t\tc.congestionWindow += c.maxDatagramSize\n\t\t\tc.numAckedPackets = 0\n\t\t}\n\t} else {\n\t\tc.congestionWindow = min(c.maxCongestionWindow(), c.cubic.CongestionWindowAfterAck(ackedBytes, c.congestionWindow, c.rttStats.MinRTT(), eventTime))\n\t}\n}\n\nfunc (c *cubicSender) isCwndLimited(bytesInFlight protocol.ByteCount) bool {\n\tcongestionWindow := c.GetCongestionWindow()\n\tif bytesInFlight >= congestionWindow {\n\t\treturn true\n\t}\n\tavailableBytes := congestionWindow - bytesInFlight\n\tslowStartLimited := c.InSlowStart() && bytesInFlight > congestionWindow/2\n\treturn slowStartLimited || availableBytes <= maxBurstPackets*c.maxDatagramSize\n}\n\n// BandwidthEstimate returns the current bandwidth estimate\nfunc (c *cubicSender) BandwidthEstimate() Bandwidth {\n\tsrtt := c.rttStats.SmoothedRTT()\n\tif srtt == 0 {\n\t\t// If we haven't measured an rtt, the bandwidth estimate is unknown.\n\t\treturn infBandwidth\n\t}\n\treturn BandwidthFromDelta(c.GetCongestionWindow(), srtt)\n}\n\n// OnRetransmissionTimeout is called on an retransmission timeout\nfunc (c *cubicSender) OnRetransmissionTimeout(packetsRetransmitted bool) {\n\tc.largestSentAtLastCutback = protocol.InvalidPacketNumber\n\tif !packetsRetransmitted {\n\t\treturn\n\t}\n\tc.hybridSlowStart.Restart()\n\tc.cubic.Reset()\n\tc.slowStartThreshold = c.congestionWindow / 2\n\tc.congestionWindow = c.minCongestionWindow()\n}\n\n// OnConnectionMigration is called when the connection is migrated (?)\nfunc (c *cubicSender) OnConnectionMigration() {\n\tc.hybridSlowStart.Restart()\n\tc.largestSentPacketNumber = protocol.InvalidPacketNumber\n\tc.largestAckedPacketNumber = protocol.InvalidPacketNumber\n\tc.largestSentAtLastCutback = protocol.InvalidPacketNumber\n\tc.lastCutbackExitedSlowstart = false\n\tc.cubic.Reset()\n\tc.numAckedPackets = 0\n\tc.congestionWindow = c.initialCongestionWindow\n\tc.slowStartThreshold = c.initialMaxCongestionWindow\n}\n\nfunc (c *cubicSender) maybeTraceStateChange(new logging.CongestionState) {\n\tif c.tracer == nil || c.tracer.UpdatedCongestionState == nil || new == c.lastState {\n\t\treturn\n\t}\n\tc.tracer.UpdatedCongestionState(new)\n\tc.lastState = new\n}\n\nfunc (c *cubicSender) SetMaxDatagramSize(s protocol.ByteCount) {\n\tif s < c.maxDatagramSize {\n\t\tpanic(fmt.Sprintf(\"congestion BUG: decreased max datagram size from %d to %d\", c.maxDatagramSize, s))\n\t}\n\tcwndIsMinCwnd := c.congestionWindow == c.minCongestionWindow()\n\tc.maxDatagramSize = s\n\tif cwndIsMinCwnd {\n\t\tc.congestionWindow = c.minCongestionWindow()\n\t}\n\tc.pacer.SetMaxDatagramSize(s)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/congestion/hybrid_slow_start.go",
    "content": "package congestion\n\nimport (\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\n// Note(pwestin): the magic clamping numbers come from the original code in\n// tcp_cubic.c.\nconst hybridStartLowWindow = protocol.ByteCount(16)\n\n// Number of delay samples for detecting the increase of delay.\nconst hybridStartMinSamples = uint32(8)\n\n// Exit slow start if the min rtt has increased by more than 1/8th.\nconst hybridStartDelayFactorExp = 3 // 2^3 = 8\n// The original paper specifies 2 and 8ms, but those have changed over time.\nconst (\n\thybridStartDelayMinThresholdUs = int64(4000)\n\thybridStartDelayMaxThresholdUs = int64(16000)\n)\n\n// HybridSlowStart implements the TCP hybrid slow start algorithm\ntype HybridSlowStart struct {\n\tendPacketNumber      protocol.PacketNumber\n\tlastSentPacketNumber protocol.PacketNumber\n\tstarted              bool\n\tcurrentMinRTT        time.Duration\n\trttSampleCount       uint32\n\thystartFound         bool\n}\n\n// StartReceiveRound is called for the start of each receive round (burst) in the slow start phase.\nfunc (s *HybridSlowStart) StartReceiveRound(lastSent protocol.PacketNumber) {\n\ts.endPacketNumber = lastSent\n\ts.currentMinRTT = 0\n\ts.rttSampleCount = 0\n\ts.started = true\n}\n\n// IsEndOfRound returns true if this ack is the last packet number of our current slow start round.\nfunc (s *HybridSlowStart) IsEndOfRound(ack protocol.PacketNumber) bool {\n\treturn s.endPacketNumber < ack\n}\n\n// ShouldExitSlowStart should be called on every new ack frame, since a new\n// RTT measurement can be made then.\n// rtt: the RTT for this ack packet.\n// minRTT: is the lowest delay (RTT) we have seen during the session.\n// congestionWindow: the congestion window in packets.\nfunc (s *HybridSlowStart) ShouldExitSlowStart(latestRTT time.Duration, minRTT time.Duration, congestionWindow protocol.ByteCount) bool {\n\tif !s.started {\n\t\t// Time to start the hybrid slow start.\n\t\ts.StartReceiveRound(s.lastSentPacketNumber)\n\t}\n\tif s.hystartFound {\n\t\treturn true\n\t}\n\t// Second detection parameter - delay increase detection.\n\t// Compare the minimum delay (s.currentMinRTT) of the current\n\t// burst of packets relative to the minimum delay during the session.\n\t// Note: we only look at the first few(8) packets in each burst, since we\n\t// only want to compare the lowest RTT of the burst relative to previous\n\t// bursts.\n\ts.rttSampleCount++\n\tif s.rttSampleCount <= hybridStartMinSamples {\n\t\tif s.currentMinRTT == 0 || s.currentMinRTT > latestRTT {\n\t\t\ts.currentMinRTT = latestRTT\n\t\t}\n\t}\n\t// We only need to check this once per round.\n\tif s.rttSampleCount == hybridStartMinSamples {\n\t\t// Divide minRTT by 8 to get a rtt increase threshold for exiting.\n\t\tminRTTincreaseThresholdUs := int64(minRTT / time.Microsecond >> hybridStartDelayFactorExp)\n\t\t// Ensure the rtt threshold is never less than 2ms or more than 16ms.\n\t\tminRTTincreaseThresholdUs = min(minRTTincreaseThresholdUs, hybridStartDelayMaxThresholdUs)\n\t\tminRTTincreaseThreshold := time.Duration(max(minRTTincreaseThresholdUs, hybridStartDelayMinThresholdUs)) * time.Microsecond\n\n\t\tif s.currentMinRTT > (minRTT + minRTTincreaseThreshold) {\n\t\t\ts.hystartFound = true\n\t\t}\n\t}\n\t// Exit from slow start if the cwnd is greater than 16 and\n\t// increasing delay is found.\n\treturn congestionWindow >= hybridStartLowWindow && s.hystartFound\n}\n\n// OnPacketSent is called when a packet was sent\nfunc (s *HybridSlowStart) OnPacketSent(packetNumber protocol.PacketNumber) {\n\ts.lastSentPacketNumber = packetNumber\n}\n\n// OnPacketAcked gets invoked after ShouldExitSlowStart, so it's best to end\n// the round when the final packet of the burst is received and start it on\n// the next incoming ack.\nfunc (s *HybridSlowStart) OnPacketAcked(ackedPacketNumber protocol.PacketNumber) {\n\tif s.IsEndOfRound(ackedPacketNumber) {\n\t\ts.started = false\n\t}\n}\n\n// Started returns true if started\nfunc (s *HybridSlowStart) Started() bool {\n\treturn s.started\n}\n\n// Restart the slow start phase\nfunc (s *HybridSlowStart) Restart() {\n\ts.started = false\n\ts.hystartFound = false\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/congestion/interface.go",
    "content": "package congestion\n\nimport (\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\n// A SendAlgorithm performs congestion control\ntype SendAlgorithm interface {\n\tTimeUntilSend(bytesInFlight protocol.ByteCount) time.Time\n\tHasPacingBudget(now time.Time) bool\n\tOnPacketSent(sentTime time.Time, bytesInFlight protocol.ByteCount, packetNumber protocol.PacketNumber, bytes protocol.ByteCount, isRetransmittable bool)\n\tCanSend(bytesInFlight protocol.ByteCount) bool\n\tMaybeExitSlowStart()\n\tOnPacketAcked(number protocol.PacketNumber, ackedBytes protocol.ByteCount, priorInFlight protocol.ByteCount, eventTime time.Time)\n\tOnCongestionEvent(number protocol.PacketNumber, lostBytes protocol.ByteCount, priorInFlight protocol.ByteCount)\n\tOnRetransmissionTimeout(packetsRetransmitted bool)\n\tSetMaxDatagramSize(protocol.ByteCount)\n}\n\n// A SendAlgorithmWithDebugInfos is a SendAlgorithm that exposes some debug infos\ntype SendAlgorithmWithDebugInfos interface {\n\tSendAlgorithm\n\tInSlowStart() bool\n\tInRecovery() bool\n\tGetCongestionWindow() protocol.ByteCount\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/congestion/pacer.go",
    "content": "package congestion\n\nimport (\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\nconst maxBurstSizePackets = 10\n\n// The pacer implements a token bucket pacing algorithm.\ntype pacer struct {\n\tbudgetAtLastSent  protocol.ByteCount\n\tmaxDatagramSize   protocol.ByteCount\n\tlastSentTime      time.Time\n\tadjustedBandwidth func() uint64 // in bytes/s\n}\n\nfunc newPacer(getBandwidth func() Bandwidth) *pacer {\n\tp := &pacer{\n\t\tmaxDatagramSize: initialMaxDatagramSize,\n\t\tadjustedBandwidth: func() uint64 {\n\t\t\t// Bandwidth is in bits/s. We need the value in bytes/s.\n\t\t\tbw := uint64(getBandwidth() / BytesPerSecond)\n\t\t\t// Use a slightly higher value than the actual measured bandwidth.\n\t\t\t// RTT variations then won't result in under-utilization of the congestion window.\n\t\t\t// Ultimately, this will result in sending packets as acknowledgments are received rather than when timers fire,\n\t\t\t// provided the congestion window is fully utilized and acknowledgments arrive at regular intervals.\n\t\t\treturn bw * 5 / 4\n\t\t},\n\t}\n\tp.budgetAtLastSent = p.maxBurstSize()\n\treturn p\n}\n\nfunc (p *pacer) SentPacket(sendTime time.Time, size protocol.ByteCount) {\n\tbudget := p.Budget(sendTime)\n\tif size >= budget {\n\t\tp.budgetAtLastSent = 0\n\t} else {\n\t\tp.budgetAtLastSent = budget - size\n\t}\n\tp.lastSentTime = sendTime\n}\n\nfunc (p *pacer) Budget(now time.Time) protocol.ByteCount {\n\tif p.lastSentTime.IsZero() {\n\t\treturn p.maxBurstSize()\n\t}\n\tbudget := p.budgetAtLastSent + (protocol.ByteCount(p.adjustedBandwidth())*protocol.ByteCount(now.Sub(p.lastSentTime).Nanoseconds()))/1e9\n\tif budget < 0 { // protect against overflows\n\t\tbudget = protocol.MaxByteCount\n\t}\n\treturn min(p.maxBurstSize(), budget)\n}\n\nfunc (p *pacer) maxBurstSize() protocol.ByteCount {\n\treturn max(\n\t\tprotocol.ByteCount(uint64((protocol.MinPacingDelay+protocol.TimerGranularity).Nanoseconds())*p.adjustedBandwidth())/1e9,\n\t\tmaxBurstSizePackets*p.maxDatagramSize,\n\t)\n}\n\n// TimeUntilSend returns when the next packet should be sent.\n// It returns the zero value of time.Time if a packet can be sent immediately.\nfunc (p *pacer) TimeUntilSend() time.Time {\n\tif p.budgetAtLastSent >= p.maxDatagramSize {\n\t\treturn time.Time{}\n\t}\n\tdiff := 1e9 * uint64(p.maxDatagramSize-p.budgetAtLastSent)\n\tbw := p.adjustedBandwidth()\n\t// We might need to round up this value.\n\t// Otherwise, we might have a budget (slightly) smaller than the datagram size when the timer expires.\n\td := diff / bw\n\t// this is effectively a math.Ceil, but using only integer math\n\tif diff%bw > 0 {\n\t\td++\n\t}\n\treturn p.lastSentTime.Add(max(protocol.MinPacingDelay, time.Duration(d)*time.Nanosecond))\n}\n\nfunc (p *pacer) SetMaxDatagramSize(s protocol.ByteCount) {\n\tp.maxDatagramSize = s\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/flowcontrol/base_flow_controller.go",
    "content": "package flowcontrol\n\nimport (\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n)\n\ntype baseFlowController struct {\n\t// for sending data\n\tbytesSent     protocol.ByteCount\n\tsendWindow    protocol.ByteCount\n\tlastBlockedAt protocol.ByteCount\n\n\t// for receiving data\n\t//nolint:structcheck // The mutex is used both by the stream and the connection flow controller\n\tmutex                sync.Mutex\n\tbytesRead            protocol.ByteCount\n\thighestReceived      protocol.ByteCount\n\treceiveWindow        protocol.ByteCount\n\treceiveWindowSize    protocol.ByteCount\n\tmaxReceiveWindowSize protocol.ByteCount\n\n\tallowWindowIncrease func(size protocol.ByteCount) bool\n\n\tepochStartTime   time.Time\n\tepochStartOffset protocol.ByteCount\n\trttStats         *utils.RTTStats\n\n\tlogger utils.Logger\n}\n\n// IsNewlyBlocked says if it is newly blocked by flow control.\n// For every offset, it only returns true once.\n// If it is blocked, the offset is returned.\nfunc (c *baseFlowController) IsNewlyBlocked() (bool, protocol.ByteCount) {\n\tif c.SendWindowSize() != 0 || c.sendWindow == c.lastBlockedAt {\n\t\treturn false, 0\n\t}\n\tc.lastBlockedAt = c.sendWindow\n\treturn true, c.sendWindow\n}\n\nfunc (c *baseFlowController) AddBytesSent(n protocol.ByteCount) {\n\tc.bytesSent += n\n}\n\n// UpdateSendWindow is called after receiving a MAX_{STREAM_}DATA frame.\nfunc (c *baseFlowController) UpdateSendWindow(offset protocol.ByteCount) (updated bool) {\n\tif offset > c.sendWindow {\n\t\tc.sendWindow = offset\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (c *baseFlowController) SendWindowSize() protocol.ByteCount {\n\t// this only happens during connection establishment, when data is sent before we receive the peer's transport parameters\n\tif c.bytesSent > c.sendWindow {\n\t\treturn 0\n\t}\n\treturn c.sendWindow - c.bytesSent\n}\n\n// needs to be called with locked mutex\nfunc (c *baseFlowController) addBytesRead(n protocol.ByteCount) {\n\tc.bytesRead += n\n}\n\nfunc (c *baseFlowController) hasWindowUpdate() bool {\n\tbytesRemaining := c.receiveWindow - c.bytesRead\n\t// update the window when more than the threshold was consumed\n\treturn bytesRemaining <= protocol.ByteCount(float64(c.receiveWindowSize)*(1-protocol.WindowUpdateThreshold))\n}\n\n// getWindowUpdate updates the receive window, if necessary\n// it returns the new offset\nfunc (c *baseFlowController) getWindowUpdate(now time.Time) protocol.ByteCount {\n\tif !c.hasWindowUpdate() {\n\t\treturn 0\n\t}\n\n\tc.maybeAdjustWindowSize(now)\n\tc.receiveWindow = c.bytesRead + c.receiveWindowSize\n\treturn c.receiveWindow\n}\n\n// maybeAdjustWindowSize increases the receiveWindowSize if we're sending updates too often.\n// For details about auto-tuning, see https://docs.google.com/document/d/1SExkMmGiz8VYzV3s9E35JQlJ73vhzCekKkDi85F1qCE/edit?usp=sharing.\nfunc (c *baseFlowController) maybeAdjustWindowSize(now time.Time) {\n\tbytesReadInEpoch := c.bytesRead - c.epochStartOffset\n\t// don't do anything if less than half the window has been consumed\n\tif bytesReadInEpoch <= c.receiveWindowSize/2 {\n\t\treturn\n\t}\n\trtt := c.rttStats.SmoothedRTT()\n\tif rtt == 0 {\n\t\treturn\n\t}\n\n\tfraction := float64(bytesReadInEpoch) / float64(c.receiveWindowSize)\n\tif now.Sub(c.epochStartTime) < time.Duration(4*fraction*float64(rtt)) {\n\t\t// window is consumed too fast, try to increase the window size\n\t\tnewSize := min(2*c.receiveWindowSize, c.maxReceiveWindowSize)\n\t\tif newSize > c.receiveWindowSize && (c.allowWindowIncrease == nil || c.allowWindowIncrease(newSize-c.receiveWindowSize)) {\n\t\t\tc.receiveWindowSize = newSize\n\t\t}\n\t}\n\tc.startNewAutoTuningEpoch(now)\n}\n\nfunc (c *baseFlowController) startNewAutoTuningEpoch(now time.Time) {\n\tc.epochStartTime = now\n\tc.epochStartOffset = c.bytesRead\n}\n\nfunc (c *baseFlowController) checkFlowControlViolation() bool {\n\treturn c.highestReceived > c.receiveWindow\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/flowcontrol/connection_flow_controller.go",
    "content": "package flowcontrol\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n)\n\ntype connectionFlowController struct {\n\tbaseFlowController\n}\n\nvar _ ConnectionFlowController = &connectionFlowController{}\n\n// NewConnectionFlowController gets a new flow controller for the connection\n// It is created before we receive the peer's transport parameters, thus it starts with a sendWindow of 0.\nfunc NewConnectionFlowController(\n\treceiveWindow protocol.ByteCount,\n\tmaxReceiveWindow protocol.ByteCount,\n\tallowWindowIncrease func(size protocol.ByteCount) bool,\n\trttStats *utils.RTTStats,\n\tlogger utils.Logger,\n) *connectionFlowController {\n\treturn &connectionFlowController{\n\t\tbaseFlowController: baseFlowController{\n\t\t\trttStats:             rttStats,\n\t\t\treceiveWindow:        receiveWindow,\n\t\t\treceiveWindowSize:    receiveWindow,\n\t\t\tmaxReceiveWindowSize: maxReceiveWindow,\n\t\t\tallowWindowIncrease:  allowWindowIncrease,\n\t\t\tlogger:               logger,\n\t\t},\n\t}\n}\n\n// IncrementHighestReceived adds an increment to the highestReceived value\nfunc (c *connectionFlowController) IncrementHighestReceived(increment protocol.ByteCount, now time.Time) error {\n\tc.mutex.Lock()\n\tdefer c.mutex.Unlock()\n\n\t// If this is the first frame received on this connection, start flow-control auto-tuning.\n\tif c.highestReceived == 0 {\n\t\tc.startNewAutoTuningEpoch(now)\n\t}\n\tc.highestReceived += increment\n\n\tif c.checkFlowControlViolation() {\n\t\treturn &qerr.TransportError{\n\t\t\tErrorCode:    qerr.FlowControlError,\n\t\t\tErrorMessage: fmt.Sprintf(\"received %d bytes for the connection, allowed %d bytes\", c.highestReceived, c.receiveWindow),\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (c *connectionFlowController) AddBytesRead(n protocol.ByteCount) (hasWindowUpdate bool) {\n\tc.mutex.Lock()\n\tdefer c.mutex.Unlock()\n\n\tc.addBytesRead(n)\n\treturn c.hasWindowUpdate()\n}\n\nfunc (c *connectionFlowController) GetWindowUpdate(now time.Time) protocol.ByteCount {\n\tc.mutex.Lock()\n\tdefer c.mutex.Unlock()\n\n\toldWindowSize := c.receiveWindowSize\n\toffset := c.getWindowUpdate(now)\n\tif c.logger.Debug() && oldWindowSize < c.receiveWindowSize {\n\t\tc.logger.Debugf(\"Increasing receive flow control window for the connection to %d kB\", c.receiveWindowSize/(1<<10))\n\t}\n\treturn offset\n}\n\n// EnsureMinimumWindowSize sets a minimum window size\n// it should make sure that the connection-level window is increased when a stream-level window grows\nfunc (c *connectionFlowController) EnsureMinimumWindowSize(inc protocol.ByteCount, now time.Time) {\n\tc.mutex.Lock()\n\tdefer c.mutex.Unlock()\n\n\tif inc <= c.receiveWindowSize {\n\t\treturn\n\t}\n\tnewSize := min(inc, c.maxReceiveWindowSize)\n\tif delta := newSize - c.receiveWindowSize; delta > 0 && c.allowWindowIncrease(delta) {\n\t\tc.receiveWindowSize = newSize\n\t\tif c.logger.Debug() {\n\t\t\tc.logger.Debugf(\"Increasing receive flow control window for the connection to %d, in response to stream flow control window increase\", newSize)\n\t\t}\n\t}\n\tc.startNewAutoTuningEpoch(now)\n}\n\n// Reset rests the flow controller. This happens when 0-RTT is rejected.\n// All stream data is invalidated, it's as if we had never opened a stream and never sent any data.\n// At that point, we only have sent stream data, but we didn't have the keys to open 1-RTT keys yet.\nfunc (c *connectionFlowController) Reset() error {\n\tc.mutex.Lock()\n\tdefer c.mutex.Unlock()\n\n\tif c.bytesRead > 0 || c.highestReceived > 0 || !c.epochStartTime.IsZero() {\n\t\treturn errors.New(\"flow controller reset after reading data\")\n\t}\n\tc.bytesSent = 0\n\tc.lastBlockedAt = 0\n\tc.sendWindow = 0\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/flowcontrol/interface.go",
    "content": "package flowcontrol\n\nimport (\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\ntype flowController interface {\n\t// for sending\n\tSendWindowSize() protocol.ByteCount\n\tUpdateSendWindow(protocol.ByteCount) (updated bool)\n\tAddBytesSent(protocol.ByteCount)\n\t// for receiving\n\tGetWindowUpdate(time.Time) protocol.ByteCount // returns 0 if no update is necessary\n}\n\n// A StreamFlowController is a flow controller for a QUIC stream.\ntype StreamFlowController interface {\n\tflowController\n\tAddBytesRead(protocol.ByteCount) (hasStreamWindowUpdate, hasConnWindowUpdate bool)\n\t// UpdateHighestReceived is called when a new highest offset is received\n\t// final has to be to true if this is the final offset of the stream,\n\t// as contained in a STREAM frame with FIN bit, and the RESET_STREAM frame\n\tUpdateHighestReceived(offset protocol.ByteCount, final bool, now time.Time) error\n\t// Abandon is called when reading from the stream is aborted early,\n\t// and there won't be any further calls to AddBytesRead.\n\tAbandon()\n\tIsNewlyBlocked() bool\n}\n\n// The ConnectionFlowController is the flow controller for the connection.\ntype ConnectionFlowController interface {\n\tflowController\n\tAddBytesRead(protocol.ByteCount) (hasWindowUpdate bool)\n\tReset() error\n\tIsNewlyBlocked() (bool, protocol.ByteCount)\n}\n\ntype connectionFlowControllerI interface {\n\tConnectionFlowController\n\t// The following two methods are not supposed to be called from outside this packet, but are needed internally\n\t// for sending\n\tEnsureMinimumWindowSize(protocol.ByteCount, time.Time)\n\t// for receiving\n\tIncrementHighestReceived(protocol.ByteCount, time.Time) error\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/flowcontrol/stream_flow_controller.go",
    "content": "package flowcontrol\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n)\n\ntype streamFlowController struct {\n\tbaseFlowController\n\n\tstreamID protocol.StreamID\n\n\tconnection connectionFlowControllerI\n\n\treceivedFinalOffset bool\n}\n\nvar _ StreamFlowController = &streamFlowController{}\n\n// NewStreamFlowController gets a new flow controller for a stream\nfunc NewStreamFlowController(\n\tstreamID protocol.StreamID,\n\tcfc ConnectionFlowController,\n\treceiveWindow protocol.ByteCount,\n\tmaxReceiveWindow protocol.ByteCount,\n\tinitialSendWindow protocol.ByteCount,\n\trttStats *utils.RTTStats,\n\tlogger utils.Logger,\n) StreamFlowController {\n\treturn &streamFlowController{\n\t\tstreamID:   streamID,\n\t\tconnection: cfc.(connectionFlowControllerI),\n\t\tbaseFlowController: baseFlowController{\n\t\t\trttStats:             rttStats,\n\t\t\treceiveWindow:        receiveWindow,\n\t\t\treceiveWindowSize:    receiveWindow,\n\t\t\tmaxReceiveWindowSize: maxReceiveWindow,\n\t\t\tsendWindow:           initialSendWindow,\n\t\t\tlogger:               logger,\n\t\t},\n\t}\n}\n\n// UpdateHighestReceived updates the highestReceived value, if the offset is higher.\nfunc (c *streamFlowController) UpdateHighestReceived(offset protocol.ByteCount, final bool, now time.Time) error {\n\t// If the final offset for this stream is already known, check for consistency.\n\tif c.receivedFinalOffset {\n\t\t// If we receive another final offset, check that it's the same.\n\t\tif final && offset != c.highestReceived {\n\t\t\treturn &qerr.TransportError{\n\t\t\t\tErrorCode:    qerr.FinalSizeError,\n\t\t\t\tErrorMessage: fmt.Sprintf(\"received inconsistent final offset for stream %d (old: %d, new: %d bytes)\", c.streamID, c.highestReceived, offset),\n\t\t\t}\n\t\t}\n\t\t// Check that the offset is below the final offset.\n\t\tif offset > c.highestReceived {\n\t\t\treturn &qerr.TransportError{\n\t\t\t\tErrorCode:    qerr.FinalSizeError,\n\t\t\t\tErrorMessage: fmt.Sprintf(\"received offset %d for stream %d, but final offset was already received at %d\", offset, c.streamID, c.highestReceived),\n\t\t\t}\n\t\t}\n\t}\n\n\tif final {\n\t\tc.receivedFinalOffset = true\n\t}\n\tif offset == c.highestReceived {\n\t\treturn nil\n\t}\n\t// A higher offset was received before. This can happen due to reordering.\n\tif offset < c.highestReceived {\n\t\tif final {\n\t\t\treturn &qerr.TransportError{\n\t\t\t\tErrorCode:    qerr.FinalSizeError,\n\t\t\t\tErrorMessage: fmt.Sprintf(\"received final offset %d for stream %d, but already received offset %d before\", offset, c.streamID, c.highestReceived),\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\n\t// If this is the first frame received for this stream, start flow-control auto-tuning.\n\tif c.highestReceived == 0 {\n\t\tc.startNewAutoTuningEpoch(now)\n\t}\n\tincrement := offset - c.highestReceived\n\tc.highestReceived = offset\n\n\tif c.checkFlowControlViolation() {\n\t\treturn &qerr.TransportError{\n\t\t\tErrorCode:    qerr.FlowControlError,\n\t\t\tErrorMessage: fmt.Sprintf(\"received %d bytes on stream %d, allowed %d bytes\", offset, c.streamID, c.receiveWindow),\n\t\t}\n\t}\n\treturn c.connection.IncrementHighestReceived(increment, now)\n}\n\nfunc (c *streamFlowController) AddBytesRead(n protocol.ByteCount) (hasStreamWindowUpdate, hasConnWindowUpdate bool) {\n\tc.mutex.Lock()\n\tc.addBytesRead(n)\n\thasStreamWindowUpdate = c.shouldQueueWindowUpdate()\n\tc.mutex.Unlock()\n\thasConnWindowUpdate = c.connection.AddBytesRead(n)\n\treturn\n}\n\nfunc (c *streamFlowController) Abandon() {\n\tc.mutex.Lock()\n\tunread := c.highestReceived - c.bytesRead\n\tc.bytesRead = c.highestReceived\n\tc.mutex.Unlock()\n\tif unread > 0 {\n\t\tc.connection.AddBytesRead(unread)\n\t}\n}\n\nfunc (c *streamFlowController) AddBytesSent(n protocol.ByteCount) {\n\tc.baseFlowController.AddBytesSent(n)\n\tc.connection.AddBytesSent(n)\n}\n\nfunc (c *streamFlowController) SendWindowSize() protocol.ByteCount {\n\treturn min(c.baseFlowController.SendWindowSize(), c.connection.SendWindowSize())\n}\n\nfunc (c *streamFlowController) IsNewlyBlocked() bool {\n\tblocked, _ := c.baseFlowController.IsNewlyBlocked()\n\treturn blocked\n}\n\nfunc (c *streamFlowController) shouldQueueWindowUpdate() bool {\n\treturn !c.receivedFinalOffset && c.hasWindowUpdate()\n}\n\nfunc (c *streamFlowController) GetWindowUpdate(now time.Time) protocol.ByteCount {\n\t// If we already received the final offset for this stream, the peer won't need any additional flow control credit.\n\tif c.receivedFinalOffset {\n\t\treturn 0\n\t}\n\n\tc.mutex.Lock()\n\tdefer c.mutex.Unlock()\n\n\toldWindowSize := c.receiveWindowSize\n\toffset := c.getWindowUpdate(now)\n\tif c.receiveWindowSize > oldWindowSize { // auto-tuning enlarged the window size\n\t\tc.logger.Debugf(\"Increasing receive flow control window for stream %d to %d\", c.streamID, c.receiveWindowSize)\n\t\tc.connection.EnsureMinimumWindowSize(protocol.ByteCount(float64(c.receiveWindowSize)*protocol.ConnectionFlowControlMultiplier), now)\n\t}\n\treturn offset\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/handshake/aead.go",
    "content": "package handshake\n\nimport (\n\t\"encoding/binary\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\nfunc createAEAD(suite *cipherSuite, trafficSecret []byte, v protocol.Version) *xorNonceAEAD {\n\tkeyLabel := hkdfLabelKeyV1\n\tivLabel := hkdfLabelIVV1\n\tif v == protocol.Version2 {\n\t\tkeyLabel = hkdfLabelKeyV2\n\t\tivLabel = hkdfLabelIVV2\n\t}\n\tkey := hkdfExpandLabel(suite.Hash, trafficSecret, []byte{}, keyLabel, suite.KeyLen)\n\tiv := hkdfExpandLabel(suite.Hash, trafficSecret, []byte{}, ivLabel, suite.IVLen())\n\treturn suite.AEAD(key, iv)\n}\n\ntype longHeaderSealer struct {\n\taead            *xorNonceAEAD\n\theaderProtector headerProtector\n\tnonceBuf        [8]byte\n}\n\nvar _ LongHeaderSealer = &longHeaderSealer{}\n\nfunc newLongHeaderSealer(aead *xorNonceAEAD, headerProtector headerProtector) LongHeaderSealer {\n\tif aead.NonceSize() != 8 {\n\t\tpanic(\"unexpected nonce size\")\n\t}\n\treturn &longHeaderSealer{\n\t\taead:            aead,\n\t\theaderProtector: headerProtector,\n\t}\n}\n\nfunc (s *longHeaderSealer) Seal(dst, src []byte, pn protocol.PacketNumber, ad []byte) []byte {\n\tbinary.BigEndian.PutUint64(s.nonceBuf[:], uint64(pn))\n\treturn s.aead.Seal(dst, s.nonceBuf[:], src, ad)\n}\n\nfunc (s *longHeaderSealer) EncryptHeader(sample []byte, firstByte *byte, pnBytes []byte) {\n\ts.headerProtector.EncryptHeader(sample, firstByte, pnBytes)\n}\n\nfunc (s *longHeaderSealer) Overhead() int {\n\treturn s.aead.Overhead()\n}\n\ntype longHeaderOpener struct {\n\taead            *xorNonceAEAD\n\theaderProtector headerProtector\n\thighestRcvdPN   protocol.PacketNumber // highest packet number received (which could be successfully unprotected)\n\n\t// use a single array to avoid allocations\n\tnonceBuf [8]byte\n}\n\nvar _ LongHeaderOpener = &longHeaderOpener{}\n\nfunc newLongHeaderOpener(aead *xorNonceAEAD, headerProtector headerProtector) LongHeaderOpener {\n\tif aead.NonceSize() != 8 {\n\t\tpanic(\"unexpected nonce size\")\n\t}\n\treturn &longHeaderOpener{\n\t\taead:            aead,\n\t\theaderProtector: headerProtector,\n\t}\n}\n\nfunc (o *longHeaderOpener) DecodePacketNumber(wirePN protocol.PacketNumber, wirePNLen protocol.PacketNumberLen) protocol.PacketNumber {\n\treturn protocol.DecodePacketNumber(wirePNLen, o.highestRcvdPN, wirePN)\n}\n\nfunc (o *longHeaderOpener) Open(dst, src []byte, pn protocol.PacketNumber, ad []byte) ([]byte, error) {\n\tbinary.BigEndian.PutUint64(o.nonceBuf[:], uint64(pn))\n\tdec, err := o.aead.Open(dst, o.nonceBuf[:], src, ad)\n\tif err == nil {\n\t\to.highestRcvdPN = max(o.highestRcvdPN, pn)\n\t} else {\n\t\terr = ErrDecryptionFailed\n\t}\n\treturn dec, err\n}\n\nfunc (o *longHeaderOpener) DecryptHeader(sample []byte, firstByte *byte, pnBytes []byte) {\n\to.headerProtector.DecryptHeader(sample, firstByte, pnBytes)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/handshake/cipher_suite.go",
    "content": "package handshake\n\nimport (\n\t\"crypto\"\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/tls\"\n\t\"fmt\"\n\n\t\"golang.org/x/crypto/chacha20poly1305\"\n)\n\n// These cipher suite implementations are copied from the standard library crypto/tls package.\n\nconst aeadNonceLength = 12\n\ntype cipherSuite struct {\n\tID     uint16\n\tHash   crypto.Hash\n\tKeyLen int\n\tAEAD   func(key, nonceMask []byte) *xorNonceAEAD\n}\n\nfunc (s cipherSuite) IVLen() int { return aeadNonceLength }\n\nfunc getCipherSuite(id uint16) *cipherSuite {\n\tswitch id {\n\tcase tls.TLS_AES_128_GCM_SHA256:\n\t\treturn &cipherSuite{ID: tls.TLS_AES_128_GCM_SHA256, Hash: crypto.SHA256, KeyLen: 16, AEAD: aeadAESGCMTLS13}\n\tcase tls.TLS_CHACHA20_POLY1305_SHA256:\n\t\treturn &cipherSuite{ID: tls.TLS_CHACHA20_POLY1305_SHA256, Hash: crypto.SHA256, KeyLen: 32, AEAD: aeadChaCha20Poly1305}\n\tcase tls.TLS_AES_256_GCM_SHA384:\n\t\treturn &cipherSuite{ID: tls.TLS_AES_256_GCM_SHA384, Hash: crypto.SHA384, KeyLen: 32, AEAD: aeadAESGCMTLS13}\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unknown cypher suite: %d\", id))\n\t}\n}\n\nfunc aeadAESGCMTLS13(key, nonceMask []byte) *xorNonceAEAD {\n\tif len(nonceMask) != aeadNonceLength {\n\t\tpanic(\"tls: internal error: wrong nonce length\")\n\t}\n\taes, err := aes.NewCipher(key)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\taead, err := newAEAD(aes)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tret := &xorNonceAEAD{aead: aead, hasSeenNonceZero: false}\n\tcopy(ret.nonceMask[:], nonceMask)\n\treturn ret\n}\n\nfunc aeadChaCha20Poly1305(key, nonceMask []byte) *xorNonceAEAD {\n\tif len(nonceMask) != aeadNonceLength {\n\t\tpanic(\"tls: internal error: wrong nonce length\")\n\t}\n\taead, err := chacha20poly1305.New(key)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tret := &xorNonceAEAD{aead: aead}\n\tcopy(ret.nonceMask[:], nonceMask)\n\treturn ret\n}\n\n// xorNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce\n// before each call.\ntype xorNonceAEAD struct {\n\tnonceMask        [aeadNonceLength]byte\n\taead             cipher.AEAD\n\thasSeenNonceZero bool // This value denotes if the aead field was used with a nonce = 0\n}\n\nfunc (f *xorNonceAEAD) NonceSize() int        { return 8 } // 64-bit sequence number\nfunc (f *xorNonceAEAD) Overhead() int         { return f.aead.Overhead() }\nfunc (f *xorNonceAEAD) explicitNonceLen() int { return 0 }\n\nfunc (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {\n\treturn f.seal(nonce, out, plaintext, additionalData)\n}\n\nfunc (f *xorNonceAEAD) doSeal(nonce, out, plaintext, additionalData []byte) []byte {\n\tfor i, b := range nonce {\n\t\tf.nonceMask[4+i] ^= b\n\t}\n\tresult := f.aead.Seal(out, f.nonceMask[:], plaintext, additionalData)\n\tfor i, b := range nonce {\n\t\tf.nonceMask[4+i] ^= b\n\t}\n\n\treturn result\n}\n\nfunc (f *xorNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) {\n\tfor i, b := range nonce {\n\t\tf.nonceMask[4+i] ^= b\n\t}\n\tresult, err := f.aead.Open(out, f.nonceMask[:], ciphertext, additionalData)\n\tfor i, b := range nonce {\n\t\tf.nonceMask[4+i] ^= b\n\t}\n\n\treturn result, err\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/handshake/crypto_setup.go",
    "content": "package handshake\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"strings\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n\t\"github.com/quic-go/quic-go/logging\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\ntype quicVersionContextKey struct{}\n\nvar QUICVersionContextKey = &quicVersionContextKey{}\n\nconst clientSessionStateRevision = 4\n\ntype cryptoSetup struct {\n\ttlsConf *tls.Config\n\tconn    *tls.QUICConn\n\n\tevents []Event\n\n\tversion protocol.Version\n\n\tourParams  *wire.TransportParameters\n\tpeerParams *wire.TransportParameters\n\n\tzeroRTTParameters *wire.TransportParameters\n\tallow0RTT         bool\n\n\trttStats *utils.RTTStats\n\n\ttracer *logging.ConnectionTracer\n\tlogger utils.Logger\n\n\tperspective protocol.Perspective\n\n\thandshakeCompleteTime time.Time\n\n\tzeroRTTOpener LongHeaderOpener // only set for the server\n\tzeroRTTSealer LongHeaderSealer // only set for the client\n\n\tinitialOpener LongHeaderOpener\n\tinitialSealer LongHeaderSealer\n\n\thandshakeOpener LongHeaderOpener\n\thandshakeSealer LongHeaderSealer\n\n\tused0RTT atomic.Bool\n\n\taead          *updatableAEAD\n\thas1RTTSealer bool\n\thas1RTTOpener bool\n}\n\nvar _ CryptoSetup = &cryptoSetup{}\n\n// NewCryptoSetupClient creates a new crypto setup for the client\nfunc NewCryptoSetupClient(\n\tconnID protocol.ConnectionID,\n\ttp *wire.TransportParameters,\n\ttlsConf *tls.Config,\n\tenable0RTT bool,\n\trttStats *utils.RTTStats,\n\ttracer *logging.ConnectionTracer,\n\tlogger utils.Logger,\n\tversion protocol.Version,\n) CryptoSetup {\n\tcs := newCryptoSetup(\n\t\tconnID,\n\t\ttp,\n\t\trttStats,\n\t\ttracer,\n\t\tlogger,\n\t\tprotocol.PerspectiveClient,\n\t\tversion,\n\t)\n\n\ttlsConf = tlsConf.Clone()\n\ttlsConf.MinVersion = tls.VersionTLS13\n\tcs.tlsConf = tlsConf\n\tcs.allow0RTT = enable0RTT\n\n\tcs.conn = tls.QUICClient(&tls.QUICConfig{\n\t\tTLSConfig:           tlsConf,\n\t\tEnableSessionEvents: true,\n\t})\n\tcs.conn.SetTransportParameters(cs.ourParams.Marshal(protocol.PerspectiveClient))\n\n\treturn cs\n}\n\n// NewCryptoSetupServer creates a new crypto setup for the server\nfunc NewCryptoSetupServer(\n\tconnID protocol.ConnectionID,\n\tlocalAddr, remoteAddr net.Addr,\n\ttp *wire.TransportParameters,\n\ttlsConf *tls.Config,\n\tallow0RTT bool,\n\trttStats *utils.RTTStats,\n\ttracer *logging.ConnectionTracer,\n\tlogger utils.Logger,\n\tversion protocol.Version,\n) CryptoSetup {\n\tcs := newCryptoSetup(\n\t\tconnID,\n\t\ttp,\n\t\trttStats,\n\t\ttracer,\n\t\tlogger,\n\t\tprotocol.PerspectiveServer,\n\t\tversion,\n\t)\n\tcs.allow0RTT = allow0RTT\n\n\ttlsConf = setupConfigForServer(tlsConf, localAddr, remoteAddr)\n\n\tcs.tlsConf = tlsConf\n\tcs.conn = tls.QUICServer(&tls.QUICConfig{\n\t\tTLSConfig:           tlsConf,\n\t\tEnableSessionEvents: true,\n\t})\n\treturn cs\n}\n\nfunc newCryptoSetup(\n\tconnID protocol.ConnectionID,\n\ttp *wire.TransportParameters,\n\trttStats *utils.RTTStats,\n\ttracer *logging.ConnectionTracer,\n\tlogger utils.Logger,\n\tperspective protocol.Perspective,\n\tversion protocol.Version,\n) *cryptoSetup {\n\tinitialSealer, initialOpener := NewInitialAEAD(connID, perspective, version)\n\tif tracer != nil && tracer.UpdatedKeyFromTLS != nil {\n\t\ttracer.UpdatedKeyFromTLS(protocol.EncryptionInitial, protocol.PerspectiveClient)\n\t\ttracer.UpdatedKeyFromTLS(protocol.EncryptionInitial, protocol.PerspectiveServer)\n\t}\n\treturn &cryptoSetup{\n\t\tinitialSealer: initialSealer,\n\t\tinitialOpener: initialOpener,\n\t\taead:          newUpdatableAEAD(rttStats, tracer, logger, version),\n\t\tevents:        make([]Event, 0, 16),\n\t\tourParams:     tp,\n\t\trttStats:      rttStats,\n\t\ttracer:        tracer,\n\t\tlogger:        logger,\n\t\tperspective:   perspective,\n\t\tversion:       version,\n\t}\n}\n\nfunc (h *cryptoSetup) ChangeConnectionID(id protocol.ConnectionID) {\n\tinitialSealer, initialOpener := NewInitialAEAD(id, h.perspective, h.version)\n\th.initialSealer = initialSealer\n\th.initialOpener = initialOpener\n\tif h.tracer != nil && h.tracer.UpdatedKeyFromTLS != nil {\n\t\th.tracer.UpdatedKeyFromTLS(protocol.EncryptionInitial, protocol.PerspectiveClient)\n\t\th.tracer.UpdatedKeyFromTLS(protocol.EncryptionInitial, protocol.PerspectiveServer)\n\t}\n}\n\nfunc (h *cryptoSetup) SetLargest1RTTAcked(pn protocol.PacketNumber) error {\n\treturn h.aead.SetLargestAcked(pn)\n}\n\nfunc (h *cryptoSetup) StartHandshake(ctx context.Context) error {\n\terr := h.conn.Start(context.WithValue(ctx, QUICVersionContextKey, h.version))\n\tif err != nil {\n\t\treturn wrapError(err)\n\t}\n\tfor {\n\t\tev := h.conn.NextEvent()\n\t\tif err := h.handleEvent(ev); err != nil {\n\t\t\treturn wrapError(err)\n\t\t}\n\t\tif ev.Kind == tls.QUICNoEvent {\n\t\t\tbreak\n\t\t}\n\t}\n\tif h.perspective == protocol.PerspectiveClient {\n\t\tif h.zeroRTTSealer != nil && h.zeroRTTParameters != nil {\n\t\t\th.logger.Debugf(\"Doing 0-RTT.\")\n\t\t\th.events = append(h.events, Event{Kind: EventRestoredTransportParameters, TransportParameters: h.zeroRTTParameters})\n\t\t} else {\n\t\t\th.logger.Debugf(\"Not doing 0-RTT. Has sealer: %t, has params: %t\", h.zeroRTTSealer != nil, h.zeroRTTParameters != nil)\n\t\t}\n\t}\n\treturn nil\n}\n\n// Close closes the crypto setup.\n// It aborts the handshake, if it is still running.\nfunc (h *cryptoSetup) Close() error {\n\treturn h.conn.Close()\n}\n\n// HandleMessage handles a TLS handshake message.\n// It is called by the crypto streams when a new message is available.\nfunc (h *cryptoSetup) HandleMessage(data []byte, encLevel protocol.EncryptionLevel) error {\n\tif err := h.handleMessage(data, encLevel); err != nil {\n\t\treturn wrapError(err)\n\t}\n\treturn nil\n}\n\nfunc (h *cryptoSetup) handleMessage(data []byte, encLevel protocol.EncryptionLevel) error {\n\tif err := h.conn.HandleData(encLevel.ToTLSEncryptionLevel(), data); err != nil {\n\t\treturn err\n\t}\n\tfor {\n\t\tev := h.conn.NextEvent()\n\t\tif err := h.handleEvent(ev); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif ev.Kind == tls.QUICNoEvent {\n\t\t\treturn nil\n\t\t}\n\t}\n}\n\nfunc (h *cryptoSetup) handleEvent(ev tls.QUICEvent) (err error) {\n\tswitch ev.Kind {\n\tcase tls.QUICNoEvent:\n\t\treturn nil\n\tcase tls.QUICSetReadSecret:\n\t\th.setReadKey(ev.Level, ev.Suite, ev.Data)\n\t\treturn nil\n\tcase tls.QUICSetWriteSecret:\n\t\th.setWriteKey(ev.Level, ev.Suite, ev.Data)\n\t\treturn nil\n\tcase tls.QUICTransportParameters:\n\t\treturn h.handleTransportParameters(ev.Data)\n\tcase tls.QUICTransportParametersRequired:\n\t\th.conn.SetTransportParameters(h.ourParams.Marshal(h.perspective))\n\t\treturn nil\n\tcase tls.QUICRejectedEarlyData:\n\t\th.rejected0RTT()\n\t\treturn nil\n\tcase tls.QUICWriteData:\n\t\th.writeRecord(ev.Level, ev.Data)\n\t\treturn nil\n\tcase tls.QUICHandshakeDone:\n\t\th.handshakeComplete()\n\t\treturn nil\n\tcase tls.QUICStoreSession:\n\t\tif h.perspective == protocol.PerspectiveServer {\n\t\t\tpanic(\"cryptoSetup BUG: unexpected QUICStoreSession event for the server\")\n\t\t}\n\t\tev.SessionState.Extra = append(\n\t\t\tev.SessionState.Extra,\n\t\t\taddSessionStateExtraPrefix(h.marshalDataForSessionState(ev.SessionState.EarlyData)),\n\t\t)\n\t\treturn h.conn.StoreSession(ev.SessionState)\n\tcase tls.QUICResumeSession:\n\t\tvar allowEarlyData bool\n\t\tswitch h.perspective {\n\t\tcase protocol.PerspectiveClient:\n\t\t\t// for clients, this event occurs when a session ticket is selected\n\t\t\tallowEarlyData = h.handleDataFromSessionState(\n\t\t\t\tfindSessionStateExtraData(ev.SessionState.Extra),\n\t\t\t\tev.SessionState.EarlyData,\n\t\t\t)\n\t\tcase protocol.PerspectiveServer:\n\t\t\t// for servers, this event occurs when receiving the client's session ticket\n\t\t\tallowEarlyData = h.handleSessionTicket(\n\t\t\t\tfindSessionStateExtraData(ev.SessionState.Extra),\n\t\t\t\tev.SessionState.EarlyData,\n\t\t\t)\n\t\t}\n\t\tif ev.SessionState.EarlyData {\n\t\t\tev.SessionState.EarlyData = allowEarlyData\n\t\t}\n\t\treturn nil\n\tdefault:\n\t\t// Unknown events should be ignored.\n\t\t// crypto/tls will ensure that this is safe to do.\n\t\t// See the discussion following https://github.com/golang/go/issues/68124#issuecomment-2187042510 for details.\n\t\treturn nil\n\t}\n}\n\nfunc (h *cryptoSetup) NextEvent() Event {\n\tif len(h.events) == 0 {\n\t\treturn Event{Kind: EventNoEvent}\n\t}\n\tev := h.events[0]\n\th.events = h.events[1:]\n\treturn ev\n}\n\nfunc (h *cryptoSetup) handleTransportParameters(data []byte) error {\n\tvar tp wire.TransportParameters\n\tif err := tp.Unmarshal(data, h.perspective.Opposite()); err != nil {\n\t\treturn err\n\t}\n\th.peerParams = &tp\n\th.events = append(h.events, Event{Kind: EventReceivedTransportParameters, TransportParameters: h.peerParams})\n\treturn nil\n}\n\n// must be called after receiving the transport parameters\nfunc (h *cryptoSetup) marshalDataForSessionState(earlyData bool) []byte {\n\tb := make([]byte, 0, 256)\n\tb = quicvarint.Append(b, clientSessionStateRevision)\n\tb = quicvarint.Append(b, uint64(h.rttStats.SmoothedRTT().Microseconds()))\n\tif earlyData {\n\t\t// only save the transport parameters for 0-RTT enabled session tickets\n\t\treturn h.peerParams.MarshalForSessionTicket(b)\n\t}\n\treturn b\n}\n\nfunc (h *cryptoSetup) handleDataFromSessionState(data []byte, earlyData bool) (allowEarlyData bool) {\n\trtt, tp, err := decodeDataFromSessionState(data, earlyData)\n\tif err != nil {\n\t\th.logger.Debugf(\"Restoring of transport parameters from session ticket failed: %s\", err.Error())\n\t\treturn\n\t}\n\th.rttStats.SetInitialRTT(rtt)\n\t// The session ticket might have been saved from a connection that allowed 0-RTT,\n\t// and therefore contain transport parameters.\n\t// Only use them if 0-RTT is actually used on the new connection.\n\tif tp != nil && h.allow0RTT {\n\t\th.zeroRTTParameters = tp\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc decodeDataFromSessionState(b []byte, earlyData bool) (time.Duration, *wire.TransportParameters, error) {\n\tver, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn 0, nil, err\n\t}\n\tb = b[l:]\n\tif ver != clientSessionStateRevision {\n\t\treturn 0, nil, fmt.Errorf(\"mismatching version. Got %d, expected %d\", ver, clientSessionStateRevision)\n\t}\n\trttEncoded, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn 0, nil, err\n\t}\n\tb = b[l:]\n\trtt := time.Duration(rttEncoded) * time.Microsecond\n\tif !earlyData {\n\t\treturn rtt, nil, nil\n\t}\n\tvar tp wire.TransportParameters\n\tif err := tp.UnmarshalFromSessionTicket(b); err != nil {\n\t\treturn 0, nil, err\n\t}\n\treturn rtt, &tp, nil\n}\n\nfunc (h *cryptoSetup) getDataForSessionTicket() []byte {\n\tticket := &sessionTicket{\n\t\tRTT: h.rttStats.SmoothedRTT(),\n\t}\n\tif h.allow0RTT {\n\t\tticket.Parameters = h.ourParams\n\t}\n\treturn ticket.Marshal()\n}\n\n// GetSessionTicket generates a new session ticket.\n// Due to limitations in crypto/tls, it's only possible to generate a single session ticket per connection.\n// It is only valid for the server.\nfunc (h *cryptoSetup) GetSessionTicket() ([]byte, error) {\n\tif err := h.conn.SendSessionTicket(tls.QUICSessionTicketOptions{\n\t\tEarlyData: h.allow0RTT,\n\t\tExtra:     [][]byte{addSessionStateExtraPrefix(h.getDataForSessionTicket())},\n\t}); err != nil {\n\t\t// Session tickets might be disabled by tls.Config.SessionTicketsDisabled.\n\t\t// We can't check h.tlsConfig here, since the actual config might have been obtained from\n\t\t// the GetConfigForClient callback.\n\t\t// See https://github.com/golang/go/issues/62032.\n\t\t// Once that issue is resolved, this error assertion can be removed.\n\t\tif strings.Contains(err.Error(), \"session ticket keys unavailable\") {\n\t\t\treturn nil, nil\n\t\t}\n\t\treturn nil, err\n\t}\n\tev := h.conn.NextEvent()\n\tif ev.Kind != tls.QUICWriteData || ev.Level != tls.QUICEncryptionLevelApplication {\n\t\tpanic(\"crypto/tls bug: where's my session ticket?\")\n\t}\n\tticket := ev.Data\n\tif ev := h.conn.NextEvent(); ev.Kind != tls.QUICNoEvent {\n\t\tpanic(\"crypto/tls bug: why more than one ticket?\")\n\t}\n\treturn ticket, nil\n}\n\n// handleSessionTicket is called for the server when receiving the client's session ticket.\n// It reads parameters from the session ticket and checks whether to accept 0-RTT if the session ticket enabled 0-RTT.\n// Note that the fact that the session ticket allows 0-RTT doesn't mean that the actual TLS handshake enables 0-RTT:\n// A client may use a 0-RTT enabled session to resume a TLS session without using 0-RTT.\nfunc (h *cryptoSetup) handleSessionTicket(data []byte, using0RTT bool) (allowEarlyData bool) {\n\tvar t sessionTicket\n\tif err := t.Unmarshal(data, using0RTT); err != nil {\n\t\th.logger.Debugf(\"Unmarshalling session ticket failed: %s\", err.Error())\n\t\treturn false\n\t}\n\th.rttStats.SetInitialRTT(t.RTT)\n\tif !using0RTT {\n\t\treturn false\n\t}\n\tvalid := h.ourParams.ValidFor0RTT(t.Parameters)\n\tif !valid {\n\t\th.logger.Debugf(\"Transport parameters changed. Rejecting 0-RTT.\")\n\t\treturn false\n\t}\n\tif !h.allow0RTT {\n\t\th.logger.Debugf(\"0-RTT not allowed. Rejecting 0-RTT.\")\n\t\treturn false\n\t}\n\th.logger.Debugf(\"Accepting 0-RTT. Restoring RTT from session ticket: %s\", t.RTT)\n\treturn true\n}\n\n// rejected0RTT is called for the client when the server rejects 0-RTT.\nfunc (h *cryptoSetup) rejected0RTT() {\n\th.logger.Debugf(\"0-RTT was rejected. Dropping 0-RTT keys.\")\n\n\thad0RTTKeys := h.zeroRTTSealer != nil\n\th.zeroRTTSealer = nil\n\n\tif had0RTTKeys {\n\t\th.events = append(h.events, Event{Kind: EventDiscard0RTTKeys})\n\t}\n}\n\nfunc (h *cryptoSetup) setReadKey(el tls.QUICEncryptionLevel, suiteID uint16, trafficSecret []byte) {\n\tsuite := getCipherSuite(suiteID)\n\t//nolint:exhaustive // The TLS stack doesn't export Initial keys.\n\tswitch el {\n\tcase tls.QUICEncryptionLevelEarly:\n\t\tif h.perspective == protocol.PerspectiveClient {\n\t\t\tpanic(\"Received 0-RTT read key for the client\")\n\t\t}\n\t\th.zeroRTTOpener = newLongHeaderOpener(\n\t\t\tcreateAEAD(suite, trafficSecret, h.version),\n\t\t\tnewHeaderProtector(suite, trafficSecret, true, h.version),\n\t\t)\n\t\th.used0RTT.Store(true)\n\t\tif h.logger.Debug() {\n\t\t\th.logger.Debugf(\"Installed 0-RTT Read keys (using %s)\", tls.CipherSuiteName(suite.ID))\n\t\t}\n\tcase tls.QUICEncryptionLevelHandshake:\n\t\th.handshakeOpener = newLongHeaderOpener(\n\t\t\tcreateAEAD(suite, trafficSecret, h.version),\n\t\t\tnewHeaderProtector(suite, trafficSecret, true, h.version),\n\t\t)\n\t\tif h.logger.Debug() {\n\t\t\th.logger.Debugf(\"Installed Handshake Read keys (using %s)\", tls.CipherSuiteName(suite.ID))\n\t\t}\n\tcase tls.QUICEncryptionLevelApplication:\n\t\th.aead.SetReadKey(suite, trafficSecret)\n\t\th.has1RTTOpener = true\n\t\tif h.logger.Debug() {\n\t\t\th.logger.Debugf(\"Installed 1-RTT Read keys (using %s)\", tls.CipherSuiteName(suite.ID))\n\t\t}\n\tdefault:\n\t\tpanic(\"unexpected read encryption level\")\n\t}\n\th.events = append(h.events, Event{Kind: EventReceivedReadKeys})\n\tif h.tracer != nil && h.tracer.UpdatedKeyFromTLS != nil {\n\t\th.tracer.UpdatedKeyFromTLS(protocol.FromTLSEncryptionLevel(el), h.perspective.Opposite())\n\t}\n}\n\nfunc (h *cryptoSetup) setWriteKey(el tls.QUICEncryptionLevel, suiteID uint16, trafficSecret []byte) {\n\tsuite := getCipherSuite(suiteID)\n\t//nolint:exhaustive // The TLS stack doesn't export Initial keys.\n\tswitch el {\n\tcase tls.QUICEncryptionLevelEarly:\n\t\tif h.perspective == protocol.PerspectiveServer {\n\t\t\tpanic(\"Received 0-RTT write key for the server\")\n\t\t}\n\t\th.zeroRTTSealer = newLongHeaderSealer(\n\t\t\tcreateAEAD(suite, trafficSecret, h.version),\n\t\t\tnewHeaderProtector(suite, trafficSecret, true, h.version),\n\t\t)\n\t\tif h.logger.Debug() {\n\t\t\th.logger.Debugf(\"Installed 0-RTT Write keys (using %s)\", tls.CipherSuiteName(suite.ID))\n\t\t}\n\t\tif h.tracer != nil && h.tracer.UpdatedKeyFromTLS != nil {\n\t\t\th.tracer.UpdatedKeyFromTLS(protocol.Encryption0RTT, h.perspective)\n\t\t}\n\t\t// don't set used0RTT here. 0-RTT might still get rejected.\n\t\treturn\n\tcase tls.QUICEncryptionLevelHandshake:\n\t\th.handshakeSealer = newLongHeaderSealer(\n\t\t\tcreateAEAD(suite, trafficSecret, h.version),\n\t\t\tnewHeaderProtector(suite, trafficSecret, true, h.version),\n\t\t)\n\t\tif h.logger.Debug() {\n\t\t\th.logger.Debugf(\"Installed Handshake Write keys (using %s)\", tls.CipherSuiteName(suite.ID))\n\t\t}\n\tcase tls.QUICEncryptionLevelApplication:\n\t\th.aead.SetWriteKey(suite, trafficSecret)\n\t\th.has1RTTSealer = true\n\t\tif h.logger.Debug() {\n\t\t\th.logger.Debugf(\"Installed 1-RTT Write keys (using %s)\", tls.CipherSuiteName(suite.ID))\n\t\t}\n\t\tif h.zeroRTTSealer != nil {\n\t\t\t// Once we receive handshake keys, we know that 0-RTT was not rejected.\n\t\t\th.used0RTT.Store(true)\n\t\t\th.zeroRTTSealer = nil\n\t\t\th.logger.Debugf(\"Dropping 0-RTT keys.\")\n\t\t\tif h.tracer != nil && h.tracer.DroppedEncryptionLevel != nil {\n\t\t\t\th.tracer.DroppedEncryptionLevel(protocol.Encryption0RTT)\n\t\t\t}\n\t\t}\n\tdefault:\n\t\tpanic(\"unexpected write encryption level\")\n\t}\n\tif h.tracer != nil && h.tracer.UpdatedKeyFromTLS != nil {\n\t\th.tracer.UpdatedKeyFromTLS(protocol.FromTLSEncryptionLevel(el), h.perspective)\n\t}\n}\n\n// writeRecord is called when TLS writes data\nfunc (h *cryptoSetup) writeRecord(encLevel tls.QUICEncryptionLevel, p []byte) {\n\t//nolint:exhaustive // handshake records can only be written for Initial and Handshake.\n\tswitch encLevel {\n\tcase tls.QUICEncryptionLevelInitial:\n\t\th.events = append(h.events, Event{Kind: EventWriteInitialData, Data: p})\n\tcase tls.QUICEncryptionLevelHandshake:\n\t\th.events = append(h.events, Event{Kind: EventWriteHandshakeData, Data: p})\n\tcase tls.QUICEncryptionLevelApplication:\n\t\tpanic(\"unexpected write\")\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unexpected write encryption level: %s\", encLevel))\n\t}\n}\n\nfunc (h *cryptoSetup) DiscardInitialKeys() {\n\tdropped := h.initialOpener != nil\n\th.initialOpener = nil\n\th.initialSealer = nil\n\tif dropped {\n\t\th.logger.Debugf(\"Dropping Initial keys.\")\n\t}\n}\n\nfunc (h *cryptoSetup) handshakeComplete() {\n\th.handshakeCompleteTime = time.Now()\n\th.events = append(h.events, Event{Kind: EventHandshakeComplete})\n}\n\nfunc (h *cryptoSetup) SetHandshakeConfirmed() {\n\th.aead.SetHandshakeConfirmed()\n\t// drop Handshake keys\n\tvar dropped bool\n\tif h.handshakeOpener != nil {\n\t\th.handshakeOpener = nil\n\t\th.handshakeSealer = nil\n\t\tdropped = true\n\t}\n\tif dropped {\n\t\th.logger.Debugf(\"Dropping Handshake keys.\")\n\t}\n}\n\nfunc (h *cryptoSetup) GetInitialSealer() (LongHeaderSealer, error) {\n\tif h.initialSealer == nil {\n\t\treturn nil, ErrKeysDropped\n\t}\n\treturn h.initialSealer, nil\n}\n\nfunc (h *cryptoSetup) Get0RTTSealer() (LongHeaderSealer, error) {\n\tif h.zeroRTTSealer == nil {\n\t\treturn nil, ErrKeysDropped\n\t}\n\treturn h.zeroRTTSealer, nil\n}\n\nfunc (h *cryptoSetup) GetHandshakeSealer() (LongHeaderSealer, error) {\n\tif h.handshakeSealer == nil {\n\t\tif h.initialSealer == nil {\n\t\t\treturn nil, ErrKeysDropped\n\t\t}\n\t\treturn nil, ErrKeysNotYetAvailable\n\t}\n\treturn h.handshakeSealer, nil\n}\n\nfunc (h *cryptoSetup) Get1RTTSealer() (ShortHeaderSealer, error) {\n\tif !h.has1RTTSealer {\n\t\treturn nil, ErrKeysNotYetAvailable\n\t}\n\treturn h.aead, nil\n}\n\nfunc (h *cryptoSetup) GetInitialOpener() (LongHeaderOpener, error) {\n\tif h.initialOpener == nil {\n\t\treturn nil, ErrKeysDropped\n\t}\n\treturn h.initialOpener, nil\n}\n\nfunc (h *cryptoSetup) Get0RTTOpener() (LongHeaderOpener, error) {\n\tif h.zeroRTTOpener == nil {\n\t\tif h.initialOpener != nil {\n\t\t\treturn nil, ErrKeysNotYetAvailable\n\t\t}\n\t\t// if the initial opener is also not available, the keys were already dropped\n\t\treturn nil, ErrKeysDropped\n\t}\n\treturn h.zeroRTTOpener, nil\n}\n\nfunc (h *cryptoSetup) GetHandshakeOpener() (LongHeaderOpener, error) {\n\tif h.handshakeOpener == nil {\n\t\tif h.initialOpener != nil {\n\t\t\treturn nil, ErrKeysNotYetAvailable\n\t\t}\n\t\t// if the initial opener is also not available, the keys were already dropped\n\t\treturn nil, ErrKeysDropped\n\t}\n\treturn h.handshakeOpener, nil\n}\n\nfunc (h *cryptoSetup) Get1RTTOpener() (ShortHeaderOpener, error) {\n\tif h.zeroRTTOpener != nil && time.Since(h.handshakeCompleteTime) > 3*h.rttStats.PTO(true) {\n\t\th.zeroRTTOpener = nil\n\t\th.logger.Debugf(\"Dropping 0-RTT keys.\")\n\t\tif h.tracer != nil && h.tracer.DroppedEncryptionLevel != nil {\n\t\t\th.tracer.DroppedEncryptionLevel(protocol.Encryption0RTT)\n\t\t}\n\t}\n\n\tif !h.has1RTTOpener {\n\t\treturn nil, ErrKeysNotYetAvailable\n\t}\n\treturn h.aead, nil\n}\n\nfunc (h *cryptoSetup) ConnectionState() ConnectionState {\n\treturn ConnectionState{\n\t\tConnectionState: h.conn.ConnectionState(),\n\t\tUsed0RTT:        h.used0RTT.Load(),\n\t}\n}\n\nfunc wrapError(err error) error {\n\tif alertErr := tls.AlertError(0); errors.As(err, &alertErr) {\n\t\treturn qerr.NewLocalCryptoError(uint8(alertErr), err)\n\t}\n\treturn &qerr.TransportError{ErrorCode: qerr.InternalError, ErrorMessage: err.Error()}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/handshake/fake_conn.go",
    "content": "package handshake\n\nimport (\n\t\"net\"\n\t\"time\"\n)\n\ntype conn struct {\n\tlocalAddr, remoteAddr net.Addr\n}\n\nvar _ net.Conn = &conn{}\n\nfunc (c *conn) Read([]byte) (int, error)         { return 0, nil }\nfunc (c *conn) Write([]byte) (int, error)        { return 0, nil }\nfunc (c *conn) Close() error                     { return nil }\nfunc (c *conn) RemoteAddr() net.Addr             { return c.remoteAddr }\nfunc (c *conn) LocalAddr() net.Addr              { return c.localAddr }\nfunc (c *conn) SetReadDeadline(time.Time) error  { return nil }\nfunc (c *conn) SetWriteDeadline(time.Time) error { return nil }\nfunc (c *conn) SetDeadline(time.Time) error      { return nil }\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/handshake/header_protector.go",
    "content": "package handshake\n\nimport (\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/tls\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\n\t\"golang.org/x/crypto/chacha20\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\ntype headerProtector interface {\n\tEncryptHeader(sample []byte, firstByte *byte, hdrBytes []byte)\n\tDecryptHeader(sample []byte, firstByte *byte, hdrBytes []byte)\n}\n\nfunc hkdfHeaderProtectionLabel(v protocol.Version) string {\n\tif v == protocol.Version2 {\n\t\treturn \"quicv2 hp\"\n\t}\n\treturn \"quic hp\"\n}\n\nfunc newHeaderProtector(suite *cipherSuite, trafficSecret []byte, isLongHeader bool, v protocol.Version) headerProtector {\n\thkdfLabel := hkdfHeaderProtectionLabel(v)\n\tswitch suite.ID {\n\tcase tls.TLS_AES_128_GCM_SHA256, tls.TLS_AES_256_GCM_SHA384:\n\t\treturn newAESHeaderProtector(suite, trafficSecret, isLongHeader, hkdfLabel)\n\tcase tls.TLS_CHACHA20_POLY1305_SHA256:\n\t\treturn newChaChaHeaderProtector(suite, trafficSecret, isLongHeader, hkdfLabel)\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"Invalid cipher suite id: %d\", suite.ID))\n\t}\n}\n\ntype aesHeaderProtector struct {\n\tmask         [16]byte // AES always has a 16 byte block size\n\tblock        cipher.Block\n\tisLongHeader bool\n}\n\nvar _ headerProtector = &aesHeaderProtector{}\n\nfunc newAESHeaderProtector(suite *cipherSuite, trafficSecret []byte, isLongHeader bool, hkdfLabel string) headerProtector {\n\thpKey := hkdfExpandLabel(suite.Hash, trafficSecret, []byte{}, hkdfLabel, suite.KeyLen)\n\tblock, err := aes.NewCipher(hpKey)\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"error creating new AES cipher: %s\", err))\n\t}\n\treturn &aesHeaderProtector{\n\t\tblock:        block,\n\t\tisLongHeader: isLongHeader,\n\t}\n}\n\nfunc (p *aesHeaderProtector) DecryptHeader(sample []byte, firstByte *byte, hdrBytes []byte) {\n\tp.apply(sample, firstByte, hdrBytes)\n}\n\nfunc (p *aesHeaderProtector) EncryptHeader(sample []byte, firstByte *byte, hdrBytes []byte) {\n\tp.apply(sample, firstByte, hdrBytes)\n}\n\nfunc (p *aesHeaderProtector) apply(sample []byte, firstByte *byte, hdrBytes []byte) {\n\tif len(sample) != len(p.mask) {\n\t\tpanic(\"invalid sample size\")\n\t}\n\tp.block.Encrypt(p.mask[:], sample)\n\tif p.isLongHeader {\n\t\t*firstByte ^= p.mask[0] & 0xf\n\t} else {\n\t\t*firstByte ^= p.mask[0] & 0x1f\n\t}\n\tfor i := range hdrBytes {\n\t\thdrBytes[i] ^= p.mask[i+1]\n\t}\n}\n\ntype chachaHeaderProtector struct {\n\tmask [5]byte\n\n\tkey          [32]byte\n\tisLongHeader bool\n}\n\nvar _ headerProtector = &chachaHeaderProtector{}\n\nfunc newChaChaHeaderProtector(suite *cipherSuite, trafficSecret []byte, isLongHeader bool, hkdfLabel string) headerProtector {\n\thpKey := hkdfExpandLabel(suite.Hash, trafficSecret, []byte{}, hkdfLabel, suite.KeyLen)\n\n\tp := &chachaHeaderProtector{\n\t\tisLongHeader: isLongHeader,\n\t}\n\tcopy(p.key[:], hpKey)\n\treturn p\n}\n\nfunc (p *chachaHeaderProtector) DecryptHeader(sample []byte, firstByte *byte, hdrBytes []byte) {\n\tp.apply(sample, firstByte, hdrBytes)\n}\n\nfunc (p *chachaHeaderProtector) EncryptHeader(sample []byte, firstByte *byte, hdrBytes []byte) {\n\tp.apply(sample, firstByte, hdrBytes)\n}\n\nfunc (p *chachaHeaderProtector) apply(sample []byte, firstByte *byte, hdrBytes []byte) {\n\tif len(sample) != 16 {\n\t\tpanic(\"invalid sample size\")\n\t}\n\tfor i := 0; i < 5; i++ {\n\t\tp.mask[i] = 0\n\t}\n\tcipher, err := chacha20.NewUnauthenticatedCipher(p.key[:], sample[4:])\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tcipher.SetCounter(binary.LittleEndian.Uint32(sample[:4]))\n\tcipher.XORKeyStream(p.mask[:], p.mask[:])\n\tp.applyMask(firstByte, hdrBytes)\n}\n\nfunc (p *chachaHeaderProtector) applyMask(firstByte *byte, hdrBytes []byte) {\n\tif p.isLongHeader {\n\t\t*firstByte ^= p.mask[0] & 0xf\n\t} else {\n\t\t*firstByte ^= p.mask[0] & 0x1f\n\t}\n\tfor i := range hdrBytes {\n\t\thdrBytes[i] ^= p.mask[i+1]\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/handshake/hkdf.go",
    "content": "package handshake\n\nimport (\n\t\"crypto\"\n\t\"encoding/binary\"\n\n\t\"golang.org/x/crypto/hkdf\"\n)\n\n// hkdfExpandLabel HKDF expands a label as defined in RFC 8446, section 7.1.\nfunc hkdfExpandLabel(hash crypto.Hash, secret, context []byte, label string, length int) []byte {\n\tb := make([]byte, 3, 3+6+len(label)+1+len(context))\n\tbinary.BigEndian.PutUint16(b, uint16(length))\n\tb[2] = uint8(6 + len(label))\n\tb = append(b, []byte(\"tls13 \")...)\n\tb = append(b, []byte(label)...)\n\tb = b[:3+6+len(label)+1]\n\tb[3+6+len(label)] = uint8(len(context))\n\tb = append(b, context...)\n\n\tout := make([]byte, length)\n\tn, err := hkdf.Expand(hash.New, secret, b).Read(out)\n\tif err != nil || n != length {\n\t\tpanic(\"quic: HKDF-Expand-Label invocation failed unexpectedly\")\n\t}\n\treturn out\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/handshake/initial_aead.go",
    "content": "package handshake\n\nimport (\n\t\"crypto\"\n\t\"crypto/tls\"\n\n\t\"golang.org/x/crypto/hkdf\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\nvar (\n\tquicSaltV1 = []byte{0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8, 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a}\n\tquicSaltV2 = []byte{0x0d, 0xed, 0xe3, 0xde, 0xf7, 0x00, 0xa6, 0xdb, 0x81, 0x93, 0x81, 0xbe, 0x6e, 0x26, 0x9d, 0xcb, 0xf9, 0xbd, 0x2e, 0xd9}\n)\n\nconst (\n\thkdfLabelKeyV1 = \"quic key\"\n\thkdfLabelKeyV2 = \"quicv2 key\"\n\thkdfLabelIVV1  = \"quic iv\"\n\thkdfLabelIVV2  = \"quicv2 iv\"\n)\n\nfunc getSalt(v protocol.Version) []byte {\n\tif v == protocol.Version2 {\n\t\treturn quicSaltV2\n\t}\n\treturn quicSaltV1\n}\n\nvar initialSuite = getCipherSuite(tls.TLS_AES_128_GCM_SHA256)\n\n// NewInitialAEAD creates a new AEAD for Initial encryption / decryption.\nfunc NewInitialAEAD(connID protocol.ConnectionID, pers protocol.Perspective, v protocol.Version) (LongHeaderSealer, LongHeaderOpener) {\n\tclientSecret, serverSecret := computeSecrets(connID, v)\n\tvar mySecret, otherSecret []byte\n\tif pers == protocol.PerspectiveClient {\n\t\tmySecret = clientSecret\n\t\totherSecret = serverSecret\n\t} else {\n\t\tmySecret = serverSecret\n\t\totherSecret = clientSecret\n\t}\n\tmyKey, myIV := computeInitialKeyAndIV(mySecret, v)\n\totherKey, otherIV := computeInitialKeyAndIV(otherSecret, v)\n\n\tencrypter := initialSuite.AEAD(myKey, myIV)\n\tdecrypter := initialSuite.AEAD(otherKey, otherIV)\n\n\treturn newLongHeaderSealer(encrypter, newHeaderProtector(initialSuite, mySecret, true, v)),\n\t\tnewLongHeaderOpener(decrypter, newAESHeaderProtector(initialSuite, otherSecret, true, hkdfHeaderProtectionLabel(v)))\n}\n\nfunc computeSecrets(connID protocol.ConnectionID, v protocol.Version) (clientSecret, serverSecret []byte) {\n\tinitialSecret := hkdf.Extract(crypto.SHA256.New, connID.Bytes(), getSalt(v))\n\tclientSecret = hkdfExpandLabel(crypto.SHA256, initialSecret, []byte{}, \"client in\", crypto.SHA256.Size())\n\tserverSecret = hkdfExpandLabel(crypto.SHA256, initialSecret, []byte{}, \"server in\", crypto.SHA256.Size())\n\treturn\n}\n\nfunc computeInitialKeyAndIV(secret []byte, v protocol.Version) (key, iv []byte) {\n\tkeyLabel := hkdfLabelKeyV1\n\tivLabel := hkdfLabelIVV1\n\tif v == protocol.Version2 {\n\t\tkeyLabel = hkdfLabelKeyV2\n\t\tivLabel = hkdfLabelIVV2\n\t}\n\tkey = hkdfExpandLabel(crypto.SHA256, secret, []byte{}, keyLabel, 16)\n\tiv = hkdfExpandLabel(crypto.SHA256, secret, []byte{}, ivLabel, 12)\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/handshake/interface.go",
    "content": "package handshake\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\nvar (\n\t// ErrKeysNotYetAvailable is returned when an opener or a sealer is requested for an encryption level,\n\t// but the corresponding opener has not yet been initialized\n\t// This can happen when packets arrive out of order.\n\tErrKeysNotYetAvailable = errors.New(\"CryptoSetup: keys at this encryption level not yet available\")\n\t// ErrKeysDropped is returned when an opener or a sealer is requested for an encryption level,\n\t// but the corresponding keys have already been dropped.\n\tErrKeysDropped = errors.New(\"CryptoSetup: keys were already dropped\")\n\t// ErrDecryptionFailed is returned when the AEAD fails to open the packet.\n\tErrDecryptionFailed = errors.New(\"decryption failed\")\n)\n\ntype headerDecryptor interface {\n\tDecryptHeader(sample []byte, firstByte *byte, pnBytes []byte)\n}\n\n// LongHeaderOpener opens a long header packet\ntype LongHeaderOpener interface {\n\theaderDecryptor\n\tDecodePacketNumber(wirePN protocol.PacketNumber, wirePNLen protocol.PacketNumberLen) protocol.PacketNumber\n\tOpen(dst, src []byte, pn protocol.PacketNumber, associatedData []byte) ([]byte, error)\n}\n\n// ShortHeaderOpener opens a short header packet\ntype ShortHeaderOpener interface {\n\theaderDecryptor\n\tDecodePacketNumber(wirePN protocol.PacketNumber, wirePNLen protocol.PacketNumberLen) protocol.PacketNumber\n\tOpen(dst, src []byte, rcvTime time.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, associatedData []byte) ([]byte, error)\n}\n\n// LongHeaderSealer seals a long header packet\ntype LongHeaderSealer interface {\n\tSeal(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) []byte\n\tEncryptHeader(sample []byte, firstByte *byte, pnBytes []byte)\n\tOverhead() int\n}\n\n// ShortHeaderSealer seals a short header packet\ntype ShortHeaderSealer interface {\n\tLongHeaderSealer\n\tKeyPhase() protocol.KeyPhaseBit\n}\n\ntype ConnectionState struct {\n\ttls.ConnectionState\n\tUsed0RTT bool\n}\n\n// EventKind is the kind of handshake event.\ntype EventKind uint8\n\nconst (\n\t// EventNoEvent signals that there are no new handshake events\n\tEventNoEvent EventKind = iota + 1\n\t// EventWriteInitialData contains new CRYPTO data to send at the Initial encryption level\n\tEventWriteInitialData\n\t// EventWriteHandshakeData contains new CRYPTO data to send at the Handshake encryption level\n\tEventWriteHandshakeData\n\t// EventReceivedReadKeys signals that new decryption keys are available.\n\t// It doesn't say which encryption level those keys are for.\n\tEventReceivedReadKeys\n\t// EventDiscard0RTTKeys signals that the Handshake keys were discarded.\n\tEventDiscard0RTTKeys\n\t// EventReceivedTransportParameters contains the transport parameters sent by the peer.\n\tEventReceivedTransportParameters\n\t// EventRestoredTransportParameters contains the transport parameters restored from the session ticket.\n\t// It is only used for the client.\n\tEventRestoredTransportParameters\n\t// EventHandshakeComplete signals that the TLS handshake was completed.\n\tEventHandshakeComplete\n)\n\nfunc (k EventKind) String() string {\n\tswitch k {\n\tcase EventNoEvent:\n\t\treturn \"EventNoEvent\"\n\tcase EventWriteInitialData:\n\t\treturn \"EventWriteInitialData\"\n\tcase EventWriteHandshakeData:\n\t\treturn \"EventWriteHandshakeData\"\n\tcase EventReceivedReadKeys:\n\t\treturn \"EventReceivedReadKeys\"\n\tcase EventDiscard0RTTKeys:\n\t\treturn \"EventDiscard0RTTKeys\"\n\tcase EventReceivedTransportParameters:\n\t\treturn \"EventReceivedTransportParameters\"\n\tcase EventRestoredTransportParameters:\n\t\treturn \"EventRestoredTransportParameters\"\n\tcase EventHandshakeComplete:\n\t\treturn \"EventHandshakeComplete\"\n\tdefault:\n\t\treturn \"Unknown EventKind\"\n\t}\n}\n\n// Event is a handshake event.\ntype Event struct {\n\tKind                EventKind\n\tData                []byte\n\tTransportParameters *wire.TransportParameters\n}\n\n// CryptoSetup handles the handshake and protecting / unprotecting packets\ntype CryptoSetup interface {\n\tStartHandshake(context.Context) error\n\tio.Closer\n\tChangeConnectionID(protocol.ConnectionID)\n\tGetSessionTicket() ([]byte, error)\n\n\tHandleMessage([]byte, protocol.EncryptionLevel) error\n\tNextEvent() Event\n\n\tSetLargest1RTTAcked(protocol.PacketNumber) error\n\tDiscardInitialKeys()\n\tSetHandshakeConfirmed()\n\tConnectionState() ConnectionState\n\n\tGetInitialOpener() (LongHeaderOpener, error)\n\tGetHandshakeOpener() (LongHeaderOpener, error)\n\tGet0RTTOpener() (LongHeaderOpener, error)\n\tGet1RTTOpener() (ShortHeaderOpener, error)\n\n\tGetInitialSealer() (LongHeaderSealer, error)\n\tGetHandshakeSealer() (LongHeaderSealer, error)\n\tGet0RTTSealer() (LongHeaderSealer, error)\n\tGet1RTTSealer() (ShortHeaderSealer, error)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/handshake/retry.go",
    "content": "package handshake\n\nimport (\n\t\"bytes\"\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\n// Instead of using an init function, the AEADs are created lazily.\n// For more details see https://github.com/quic-go/quic-go/issues/4894.\nvar (\n\tretryAEADv1 cipher.AEAD // used for QUIC v1 (RFC 9000)\n\tretryAEADv2 cipher.AEAD // used for QUIC v2 (RFC 9369)\n)\n\nfunc initAEAD(key [16]byte) cipher.AEAD {\n\taes, err := aes.NewCipher(key[:])\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\taead, err := cipher.NewGCM(aes)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn aead\n}\n\nvar (\n\tretryBuf     bytes.Buffer\n\tretryMutex   sync.Mutex\n\tretryNonceV1 = [12]byte{0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb}\n\tretryNonceV2 = [12]byte{0xd8, 0x69, 0x69, 0xbc, 0x2d, 0x7c, 0x6d, 0x99, 0x90, 0xef, 0xb0, 0x4a}\n)\n\n// GetRetryIntegrityTag calculates the integrity tag on a Retry packet\nfunc GetRetryIntegrityTag(retry []byte, origDestConnID protocol.ConnectionID, version protocol.Version) *[16]byte {\n\tretryMutex.Lock()\n\tdefer retryMutex.Unlock()\n\n\tretryBuf.WriteByte(uint8(origDestConnID.Len()))\n\tretryBuf.Write(origDestConnID.Bytes())\n\tretryBuf.Write(retry)\n\tdefer retryBuf.Reset()\n\n\tvar tag [16]byte\n\tvar sealed []byte\n\tif version == protocol.Version2 {\n\t\tif retryAEADv2 == nil {\n\t\t\tretryAEADv2 = initAEAD([16]byte{0x8f, 0xb4, 0xb0, 0x1b, 0x56, 0xac, 0x48, 0xe2, 0x60, 0xfb, 0xcb, 0xce, 0xad, 0x7c, 0xcc, 0x92})\n\t\t}\n\t\tsealed = retryAEADv2.Seal(tag[:0], retryNonceV2[:], nil, retryBuf.Bytes())\n\t} else {\n\t\tif retryAEADv1 == nil {\n\t\t\tretryAEADv1 = initAEAD([16]byte{0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66, 0x57, 0x5a, 0x1d, 0x76, 0x6b, 0x54, 0xe3, 0x68, 0xc8, 0x4e})\n\t\t}\n\t\tsealed = retryAEADv1.Seal(tag[:0], retryNonceV1[:], nil, retryBuf.Bytes())\n\t}\n\tif len(sealed) != 16 {\n\t\tpanic(fmt.Sprintf(\"unexpected Retry integrity tag length: %d\", len(sealed)))\n\t}\n\treturn &tag\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/handshake/session_ticket.go",
    "content": "package handshake\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/wire\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\nconst sessionTicketRevision = 4\n\ntype sessionTicket struct {\n\tParameters *wire.TransportParameters\n\tRTT        time.Duration // to be encoded in mus\n}\n\nfunc (t *sessionTicket) Marshal() []byte {\n\tb := make([]byte, 0, 256)\n\tb = quicvarint.Append(b, sessionTicketRevision)\n\tb = quicvarint.Append(b, uint64(t.RTT.Microseconds()))\n\tif t.Parameters == nil {\n\t\treturn b\n\t}\n\treturn t.Parameters.MarshalForSessionTicket(b)\n}\n\nfunc (t *sessionTicket) Unmarshal(b []byte, using0RTT bool) error {\n\trev, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn errors.New(\"failed to read session ticket revision\")\n\t}\n\tb = b[l:]\n\tif rev != sessionTicketRevision {\n\t\treturn fmt.Errorf(\"unknown session ticket revision: %d\", rev)\n\t}\n\trtt, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn errors.New(\"failed to read RTT\")\n\t}\n\tb = b[l:]\n\tif using0RTT {\n\t\tvar tp wire.TransportParameters\n\t\tif err := tp.UnmarshalFromSessionTicket(b); err != nil {\n\t\t\treturn fmt.Errorf(\"unmarshaling transport parameters from session ticket failed: %s\", err.Error())\n\t\t}\n\t\tt.Parameters = &tp\n\t} else if len(b) > 0 {\n\t\treturn fmt.Errorf(\"the session ticket has more bytes than expected\")\n\t}\n\tt.RTT = time.Duration(rtt) * time.Microsecond\n\treturn nil\n}\n\nconst extraPrefix = \"quic-go1\"\n\nfunc addSessionStateExtraPrefix(b []byte) []byte {\n\treturn append([]byte(extraPrefix), b...)\n}\n\nfunc findSessionStateExtraData(extras [][]byte) []byte {\n\tprefix := []byte(extraPrefix)\n\tfor _, extra := range extras {\n\t\tif len(extra) < len(prefix) || !bytes.Equal(prefix, extra[:len(prefix)]) {\n\t\t\tcontinue\n\t\t}\n\t\treturn extra[len(prefix):]\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/handshake/tls_config.go",
    "content": "package handshake\n\nimport (\n\t\"crypto/tls\"\n\t\"net\"\n)\n\nfunc setupConfigForServer(conf *tls.Config, localAddr, remoteAddr net.Addr) *tls.Config {\n\t// Workaround for https://github.com/golang/go/issues/60506.\n\t// This initializes the session tickets _before_ cloning the config.\n\t_, _ = conf.DecryptTicket(nil, tls.ConnectionState{})\n\n\tconf = conf.Clone()\n\tconf.MinVersion = tls.VersionTLS13\n\n\t// The tls.Config contains two callbacks that pass in a tls.ClientHelloInfo.\n\t// Since crypto/tls doesn't do it, we need to make sure to set the Conn field with a fake net.Conn\n\t// that allows the caller to get the local and the remote address.\n\tif conf.GetConfigForClient != nil {\n\t\tgcfc := conf.GetConfigForClient\n\t\tconf.GetConfigForClient = func(info *tls.ClientHelloInfo) (*tls.Config, error) {\n\t\t\tinfo.Conn = &conn{localAddr: localAddr, remoteAddr: remoteAddr}\n\t\t\tc, err := gcfc(info)\n\t\t\tif c != nil {\n\t\t\t\t// we're returning a tls.Config here, so we need to apply this recursively\n\t\t\t\tc = setupConfigForServer(c, localAddr, remoteAddr)\n\t\t\t}\n\t\t\treturn c, err\n\t\t}\n\t}\n\tif conf.GetCertificate != nil {\n\t\tgc := conf.GetCertificate\n\t\tconf.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {\n\t\t\tinfo.Conn = &conn{localAddr: localAddr, remoteAddr: remoteAddr}\n\t\t\treturn gc(info)\n\t\t}\n\t}\n\treturn conf\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/handshake/token_generator.go",
    "content": "package handshake\n\nimport (\n\t\"bytes\"\n\t\"encoding/asn1\"\n\t\"fmt\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\nconst (\n\ttokenPrefixIP byte = iota\n\ttokenPrefixString\n)\n\n// A Token is derived from the client address and can be used to verify the ownership of this address.\ntype Token struct {\n\tIsRetryToken      bool\n\tSentTime          time.Time\n\tencodedRemoteAddr []byte\n\t// only set for retry tokens\n\tOriginalDestConnectionID protocol.ConnectionID\n\tRetrySrcConnectionID     protocol.ConnectionID\n}\n\n// ValidateRemoteAddr validates the address, but does not check expiration\nfunc (t *Token) ValidateRemoteAddr(addr net.Addr) bool {\n\treturn bytes.Equal(encodeRemoteAddr(addr), t.encodedRemoteAddr)\n}\n\n// token is the struct that is used for ASN1 serialization and deserialization\ntype token struct {\n\tIsRetryToken             bool\n\tRemoteAddr               []byte\n\tTimestamp                int64\n\tOriginalDestConnectionID []byte\n\tRetrySrcConnectionID     []byte\n}\n\n// A TokenGenerator generates tokens\ntype TokenGenerator struct {\n\ttokenProtector tokenProtector\n}\n\n// NewTokenGenerator initializes a new TokenGenerator\nfunc NewTokenGenerator(key TokenProtectorKey) *TokenGenerator {\n\treturn &TokenGenerator{tokenProtector: *newTokenProtector(key)}\n}\n\n// NewRetryToken generates a new token for a Retry for a given source address\nfunc (g *TokenGenerator) NewRetryToken(\n\traddr net.Addr,\n\torigDestConnID protocol.ConnectionID,\n\tretrySrcConnID protocol.ConnectionID,\n) ([]byte, error) {\n\tdata, err := asn1.Marshal(token{\n\t\tIsRetryToken:             true,\n\t\tRemoteAddr:               encodeRemoteAddr(raddr),\n\t\tOriginalDestConnectionID: origDestConnID.Bytes(),\n\t\tRetrySrcConnectionID:     retrySrcConnID.Bytes(),\n\t\tTimestamp:                time.Now().UnixNano(),\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn g.tokenProtector.NewToken(data)\n}\n\n// NewToken generates a new token to be sent in a NEW_TOKEN frame\nfunc (g *TokenGenerator) NewToken(raddr net.Addr) ([]byte, error) {\n\tdata, err := asn1.Marshal(token{\n\t\tRemoteAddr: encodeRemoteAddr(raddr),\n\t\tTimestamp:  time.Now().UnixNano(),\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn g.tokenProtector.NewToken(data)\n}\n\n// DecodeToken decodes a token\nfunc (g *TokenGenerator) DecodeToken(encrypted []byte) (*Token, error) {\n\t// if the client didn't send any token, DecodeToken will be called with a nil-slice\n\tif len(encrypted) == 0 {\n\t\treturn nil, nil\n\t}\n\n\tdata, err := g.tokenProtector.DecodeToken(encrypted)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tt := &token{}\n\trest, err := asn1.Unmarshal(data, t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(rest) != 0 {\n\t\treturn nil, fmt.Errorf(\"rest when unpacking token: %d\", len(rest))\n\t}\n\ttoken := &Token{\n\t\tIsRetryToken:      t.IsRetryToken,\n\t\tSentTime:          time.Unix(0, t.Timestamp),\n\t\tencodedRemoteAddr: t.RemoteAddr,\n\t}\n\tif t.IsRetryToken {\n\t\ttoken.OriginalDestConnectionID = protocol.ParseConnectionID(t.OriginalDestConnectionID)\n\t\ttoken.RetrySrcConnectionID = protocol.ParseConnectionID(t.RetrySrcConnectionID)\n\t}\n\treturn token, nil\n}\n\n// encodeRemoteAddr encodes a remote address such that it can be saved in the token\nfunc encodeRemoteAddr(remoteAddr net.Addr) []byte {\n\tif udpAddr, ok := remoteAddr.(*net.UDPAddr); ok {\n\t\treturn append([]byte{tokenPrefixIP}, udpAddr.IP...)\n\t}\n\treturn append([]byte{tokenPrefixString}, []byte(remoteAddr.String())...)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/handshake/token_protector.go",
    "content": "package handshake\n\nimport (\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/rand\"\n\t\"crypto/sha256\"\n\t\"fmt\"\n\t\"io\"\n\n\t\"golang.org/x/crypto/hkdf\"\n)\n\n// TokenProtectorKey is the key used to encrypt both Retry and session resumption tokens.\ntype TokenProtectorKey [32]byte\n\nconst tokenNonceSize = 32\n\n// tokenProtector is used to create and verify a token\ntype tokenProtector struct {\n\tkey TokenProtectorKey\n}\n\n// newTokenProtector creates a source for source address tokens\nfunc newTokenProtector(key TokenProtectorKey) *tokenProtector {\n\treturn &tokenProtector{key: key}\n}\n\n// NewToken encodes data into a new token.\nfunc (s *tokenProtector) NewToken(data []byte) ([]byte, error) {\n\tvar nonce [tokenNonceSize]byte\n\tif _, err := rand.Read(nonce[:]); err != nil {\n\t\treturn nil, err\n\t}\n\taead, aeadNonce, err := s.createAEAD(nonce[:])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn append(nonce[:], aead.Seal(nil, aeadNonce, data, nil)...), nil\n}\n\n// DecodeToken decodes a token.\nfunc (s *tokenProtector) DecodeToken(p []byte) ([]byte, error) {\n\tif len(p) < tokenNonceSize {\n\t\treturn nil, fmt.Errorf(\"token too short: %d\", len(p))\n\t}\n\tnonce := p[:tokenNonceSize]\n\taead, aeadNonce, err := s.createAEAD(nonce)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn aead.Open(nil, aeadNonce, p[tokenNonceSize:], nil)\n}\n\nfunc (s *tokenProtector) createAEAD(nonce []byte) (cipher.AEAD, []byte, error) {\n\th := hkdf.New(sha256.New, s.key[:], nonce, []byte(\"quic-go token source\"))\n\tkey := make([]byte, 32) // use a 32 byte key, in order to select AES-256\n\tif _, err := io.ReadFull(h, key); err != nil {\n\t\treturn nil, nil, err\n\t}\n\taeadNonce := make([]byte, 12)\n\tif _, err := io.ReadFull(h, aeadNonce); err != nil {\n\t\treturn nil, nil, err\n\t}\n\tc, err := aes.NewCipher(key)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\taead, err := cipher.NewGCM(c)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\treturn aead, aeadNonce, nil\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/handshake/updatable_aead.go",
    "content": "package handshake\n\nimport (\n\t\"crypto\"\n\t\"crypto/cipher\"\n\t\"crypto/tls\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/logging\"\n)\n\n// KeyUpdateInterval is the maximum number of packets we send or receive before initiating a key update.\n// It's a package-level variable to allow modifying it for testing purposes.\nvar KeyUpdateInterval uint64 = protocol.KeyUpdateInterval\n\n// FirstKeyUpdateInterval is the maximum number of packets we send or receive before initiating the first key update.\n// It's a package-level variable to allow modifying it for testing purposes.\nvar FirstKeyUpdateInterval uint64 = 100\n\ntype updatableAEAD struct {\n\tsuite *cipherSuite\n\n\tkeyPhase           protocol.KeyPhase\n\tlargestAcked       protocol.PacketNumber\n\tfirstPacketNumber  protocol.PacketNumber\n\thandshakeConfirmed bool\n\n\tinvalidPacketLimit uint64\n\tinvalidPacketCount uint64\n\n\t// Time when the keys should be dropped. Keys are dropped on the next call to Open().\n\tprevRcvAEADExpiry time.Time\n\tprevRcvAEAD       cipher.AEAD\n\n\tfirstRcvdWithCurrentKey protocol.PacketNumber\n\tfirstSentWithCurrentKey protocol.PacketNumber\n\thighestRcvdPN           protocol.PacketNumber // highest packet number received (which could be successfully unprotected)\n\tnumRcvdWithCurrentKey   uint64\n\tnumSentWithCurrentKey   uint64\n\trcvAEAD                 cipher.AEAD\n\tsendAEAD                cipher.AEAD\n\t// caches cipher.AEAD.Overhead(). This speeds up calls to Overhead().\n\taeadOverhead int\n\n\tnextRcvAEAD           cipher.AEAD\n\tnextSendAEAD          cipher.AEAD\n\tnextRcvTrafficSecret  []byte\n\tnextSendTrafficSecret []byte\n\n\theaderDecrypter headerProtector\n\theaderEncrypter headerProtector\n\n\trttStats *utils.RTTStats\n\n\ttracer  *logging.ConnectionTracer\n\tlogger  utils.Logger\n\tversion protocol.Version\n\n\t// use a single slice to avoid allocations\n\tnonceBuf []byte\n}\n\nvar (\n\t_ ShortHeaderOpener = &updatableAEAD{}\n\t_ ShortHeaderSealer = &updatableAEAD{}\n)\n\nfunc newUpdatableAEAD(rttStats *utils.RTTStats, tracer *logging.ConnectionTracer, logger utils.Logger, version protocol.Version) *updatableAEAD {\n\treturn &updatableAEAD{\n\t\tfirstPacketNumber:       protocol.InvalidPacketNumber,\n\t\tlargestAcked:            protocol.InvalidPacketNumber,\n\t\tfirstRcvdWithCurrentKey: protocol.InvalidPacketNumber,\n\t\tfirstSentWithCurrentKey: protocol.InvalidPacketNumber,\n\t\trttStats:                rttStats,\n\t\ttracer:                  tracer,\n\t\tlogger:                  logger,\n\t\tversion:                 version,\n\t}\n}\n\nfunc (a *updatableAEAD) rollKeys() {\n\tif a.prevRcvAEAD != nil {\n\t\ta.logger.Debugf(\"Dropping key phase %d ahead of scheduled time. Drop time was: %s\", a.keyPhase-1, a.prevRcvAEADExpiry)\n\t\tif a.tracer != nil && a.tracer.DroppedKey != nil {\n\t\t\ta.tracer.DroppedKey(a.keyPhase - 1)\n\t\t}\n\t\ta.prevRcvAEADExpiry = time.Time{}\n\t}\n\n\ta.keyPhase++\n\ta.firstRcvdWithCurrentKey = protocol.InvalidPacketNumber\n\ta.firstSentWithCurrentKey = protocol.InvalidPacketNumber\n\ta.numRcvdWithCurrentKey = 0\n\ta.numSentWithCurrentKey = 0\n\ta.prevRcvAEAD = a.rcvAEAD\n\ta.rcvAEAD = a.nextRcvAEAD\n\ta.sendAEAD = a.nextSendAEAD\n\n\ta.nextRcvTrafficSecret = a.getNextTrafficSecret(a.suite.Hash, a.nextRcvTrafficSecret)\n\ta.nextSendTrafficSecret = a.getNextTrafficSecret(a.suite.Hash, a.nextSendTrafficSecret)\n\ta.nextRcvAEAD = createAEAD(a.suite, a.nextRcvTrafficSecret, a.version)\n\ta.nextSendAEAD = createAEAD(a.suite, a.nextSendTrafficSecret, a.version)\n}\n\nfunc (a *updatableAEAD) startKeyDropTimer(now time.Time) {\n\td := 3 * a.rttStats.PTO(true)\n\ta.logger.Debugf(\"Starting key drop timer to drop key phase %d (in %s)\", a.keyPhase-1, d)\n\ta.prevRcvAEADExpiry = now.Add(d)\n}\n\nfunc (a *updatableAEAD) getNextTrafficSecret(hash crypto.Hash, ts []byte) []byte {\n\treturn hkdfExpandLabel(hash, ts, []byte{}, \"quic ku\", hash.Size())\n}\n\n// SetReadKey sets the read key.\n// For the client, this function is called before SetWriteKey.\n// For the server, this function is called after SetWriteKey.\nfunc (a *updatableAEAD) SetReadKey(suite *cipherSuite, trafficSecret []byte) {\n\ta.rcvAEAD = createAEAD(suite, trafficSecret, a.version)\n\ta.headerDecrypter = newHeaderProtector(suite, trafficSecret, false, a.version)\n\tif a.suite == nil {\n\t\ta.setAEADParameters(a.rcvAEAD, suite)\n\t}\n\n\ta.nextRcvTrafficSecret = a.getNextTrafficSecret(suite.Hash, trafficSecret)\n\ta.nextRcvAEAD = createAEAD(suite, a.nextRcvTrafficSecret, a.version)\n}\n\n// SetWriteKey sets the write key.\n// For the client, this function is called after SetReadKey.\n// For the server, this function is called before SetReadKey.\nfunc (a *updatableAEAD) SetWriteKey(suite *cipherSuite, trafficSecret []byte) {\n\ta.sendAEAD = createAEAD(suite, trafficSecret, a.version)\n\ta.headerEncrypter = newHeaderProtector(suite, trafficSecret, false, a.version)\n\tif a.suite == nil {\n\t\ta.setAEADParameters(a.sendAEAD, suite)\n\t}\n\n\ta.nextSendTrafficSecret = a.getNextTrafficSecret(suite.Hash, trafficSecret)\n\ta.nextSendAEAD = createAEAD(suite, a.nextSendTrafficSecret, a.version)\n}\n\nfunc (a *updatableAEAD) setAEADParameters(aead cipher.AEAD, suite *cipherSuite) {\n\ta.nonceBuf = make([]byte, aead.NonceSize())\n\ta.aeadOverhead = aead.Overhead()\n\ta.suite = suite\n\tswitch suite.ID {\n\tcase tls.TLS_AES_128_GCM_SHA256, tls.TLS_AES_256_GCM_SHA384:\n\t\ta.invalidPacketLimit = protocol.InvalidPacketLimitAES\n\tcase tls.TLS_CHACHA20_POLY1305_SHA256:\n\t\ta.invalidPacketLimit = protocol.InvalidPacketLimitChaCha\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unknown cipher suite %d\", suite.ID))\n\t}\n}\n\nfunc (a *updatableAEAD) DecodePacketNumber(wirePN protocol.PacketNumber, wirePNLen protocol.PacketNumberLen) protocol.PacketNumber {\n\treturn protocol.DecodePacketNumber(wirePNLen, a.highestRcvdPN, wirePN)\n}\n\nfunc (a *updatableAEAD) Open(dst, src []byte, rcvTime time.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, ad []byte) ([]byte, error) {\n\tdec, err := a.open(dst, src, rcvTime, pn, kp, ad)\n\tif err == ErrDecryptionFailed {\n\t\ta.invalidPacketCount++\n\t\tif a.invalidPacketCount >= a.invalidPacketLimit {\n\t\t\treturn nil, &qerr.TransportError{ErrorCode: qerr.AEADLimitReached}\n\t\t}\n\t}\n\tif err == nil {\n\t\ta.highestRcvdPN = max(a.highestRcvdPN, pn)\n\t}\n\treturn dec, err\n}\n\nfunc (a *updatableAEAD) open(dst, src []byte, rcvTime time.Time, pn protocol.PacketNumber, kp protocol.KeyPhaseBit, ad []byte) ([]byte, error) {\n\tif a.prevRcvAEAD != nil && !a.prevRcvAEADExpiry.IsZero() && rcvTime.After(a.prevRcvAEADExpiry) {\n\t\ta.prevRcvAEAD = nil\n\t\ta.logger.Debugf(\"Dropping key phase %d\", a.keyPhase-1)\n\t\ta.prevRcvAEADExpiry = time.Time{}\n\t\tif a.tracer != nil && a.tracer.DroppedKey != nil {\n\t\t\ta.tracer.DroppedKey(a.keyPhase - 1)\n\t\t}\n\t}\n\tbinary.BigEndian.PutUint64(a.nonceBuf[len(a.nonceBuf)-8:], uint64(pn))\n\tif kp != a.keyPhase.Bit() {\n\t\tif a.keyPhase > 0 && a.firstRcvdWithCurrentKey == protocol.InvalidPacketNumber || pn < a.firstRcvdWithCurrentKey {\n\t\t\tif a.prevRcvAEAD == nil {\n\t\t\t\treturn nil, ErrKeysDropped\n\t\t\t}\n\t\t\t// we updated the key, but the peer hasn't updated yet\n\t\t\tdec, err := a.prevRcvAEAD.Open(dst, a.nonceBuf, src, ad)\n\t\t\tif err != nil {\n\t\t\t\terr = ErrDecryptionFailed\n\t\t\t}\n\t\t\treturn dec, err\n\t\t}\n\t\t// try opening the packet with the next key phase\n\t\tdec, err := a.nextRcvAEAD.Open(dst, a.nonceBuf, src, ad)\n\t\tif err != nil {\n\t\t\treturn nil, ErrDecryptionFailed\n\t\t}\n\t\t// Opening succeeded. Check if the peer was allowed to update.\n\t\tif a.keyPhase > 0 && a.firstSentWithCurrentKey == protocol.InvalidPacketNumber {\n\t\t\treturn nil, &qerr.TransportError{\n\t\t\t\tErrorCode:    qerr.KeyUpdateError,\n\t\t\t\tErrorMessage: \"keys updated too quickly\",\n\t\t\t}\n\t\t}\n\t\ta.rollKeys()\n\t\ta.logger.Debugf(\"Peer updated keys to %d\", a.keyPhase)\n\t\t// The peer initiated this key update. It's safe to drop the keys for the previous generation now.\n\t\t// Start a timer to drop the previous key generation.\n\t\ta.startKeyDropTimer(rcvTime)\n\t\tif a.tracer != nil && a.tracer.UpdatedKey != nil {\n\t\t\ta.tracer.UpdatedKey(a.keyPhase, true)\n\t\t}\n\t\ta.firstRcvdWithCurrentKey = pn\n\t\treturn dec, err\n\t}\n\t// The AEAD we're using here will be the qtls.aeadAESGCM13.\n\t// It uses the nonce provided here and XOR it with the IV.\n\tdec, err := a.rcvAEAD.Open(dst, a.nonceBuf, src, ad)\n\tif err != nil {\n\t\treturn dec, ErrDecryptionFailed\n\t}\n\ta.numRcvdWithCurrentKey++\n\tif a.firstRcvdWithCurrentKey == protocol.InvalidPacketNumber {\n\t\t// We initiated the key updated, and now we received the first packet protected with the new key phase.\n\t\t// Therefore, we are certain that the peer rolled its keys as well. Start a timer to drop the old keys.\n\t\tif a.keyPhase > 0 {\n\t\t\ta.logger.Debugf(\"Peer confirmed key update to phase %d\", a.keyPhase)\n\t\t\ta.startKeyDropTimer(rcvTime)\n\t\t}\n\t\ta.firstRcvdWithCurrentKey = pn\n\t}\n\treturn dec, err\n}\n\nfunc (a *updatableAEAD) Seal(dst, src []byte, pn protocol.PacketNumber, ad []byte) []byte {\n\tif a.firstSentWithCurrentKey == protocol.InvalidPacketNumber {\n\t\ta.firstSentWithCurrentKey = pn\n\t}\n\tif a.firstPacketNumber == protocol.InvalidPacketNumber {\n\t\ta.firstPacketNumber = pn\n\t}\n\ta.numSentWithCurrentKey++\n\tbinary.BigEndian.PutUint64(a.nonceBuf[len(a.nonceBuf)-8:], uint64(pn))\n\t// The AEAD we're using here will be the qtls.aeadAESGCM13.\n\t// It uses the nonce provided here and XOR it with the IV.\n\treturn a.sendAEAD.Seal(dst, a.nonceBuf, src, ad)\n}\n\nfunc (a *updatableAEAD) SetLargestAcked(pn protocol.PacketNumber) error {\n\tif a.firstSentWithCurrentKey != protocol.InvalidPacketNumber &&\n\t\tpn >= a.firstSentWithCurrentKey && a.numRcvdWithCurrentKey == 0 {\n\t\treturn &qerr.TransportError{\n\t\t\tErrorCode:    qerr.KeyUpdateError,\n\t\t\tErrorMessage: fmt.Sprintf(\"received ACK for key phase %d, but peer didn't update keys\", a.keyPhase),\n\t\t}\n\t}\n\ta.largestAcked = pn\n\treturn nil\n}\n\nfunc (a *updatableAEAD) SetHandshakeConfirmed() {\n\ta.handshakeConfirmed = true\n}\n\nfunc (a *updatableAEAD) updateAllowed() bool {\n\tif !a.handshakeConfirmed {\n\t\treturn false\n\t}\n\t// the first key update is allowed as soon as the handshake is confirmed\n\treturn a.keyPhase == 0 ||\n\t\t// subsequent key updates as soon as a packet sent with that key phase has been acknowledged\n\t\t(a.firstSentWithCurrentKey != protocol.InvalidPacketNumber &&\n\t\t\ta.largestAcked != protocol.InvalidPacketNumber &&\n\t\t\ta.largestAcked >= a.firstSentWithCurrentKey)\n}\n\nfunc (a *updatableAEAD) shouldInitiateKeyUpdate() bool {\n\tif !a.updateAllowed() {\n\t\treturn false\n\t}\n\t// Initiate the first key update shortly after the handshake, in order to exercise the key update mechanism.\n\tif a.keyPhase == 0 {\n\t\tif a.numRcvdWithCurrentKey >= FirstKeyUpdateInterval || a.numSentWithCurrentKey >= FirstKeyUpdateInterval {\n\t\t\treturn true\n\t\t}\n\t}\n\tif a.numRcvdWithCurrentKey >= KeyUpdateInterval {\n\t\ta.logger.Debugf(\"Received %d packets with current key phase. Initiating key update to the next key phase: %d\", a.numRcvdWithCurrentKey, a.keyPhase+1)\n\t\treturn true\n\t}\n\tif a.numSentWithCurrentKey >= KeyUpdateInterval {\n\t\ta.logger.Debugf(\"Sent %d packets with current key phase. Initiating key update to the next key phase: %d\", a.numSentWithCurrentKey, a.keyPhase+1)\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (a *updatableAEAD) KeyPhase() protocol.KeyPhaseBit {\n\tif a.shouldInitiateKeyUpdate() {\n\t\ta.rollKeys()\n\t\ta.logger.Debugf(\"Initiating key update to key phase %d\", a.keyPhase)\n\t\tif a.tracer != nil && a.tracer.UpdatedKey != nil {\n\t\t\ta.tracer.UpdatedKey(a.keyPhase, false)\n\t\t}\n\t}\n\treturn a.keyPhase.Bit()\n}\n\nfunc (a *updatableAEAD) Overhead() int {\n\treturn a.aeadOverhead\n}\n\nfunc (a *updatableAEAD) EncryptHeader(sample []byte, firstByte *byte, hdrBytes []byte) {\n\ta.headerEncrypter.EncryptHeader(sample, firstByte, hdrBytes)\n}\n\nfunc (a *updatableAEAD) DecryptHeader(sample []byte, firstByte *byte, hdrBytes []byte) {\n\ta.headerDecrypter.DecryptHeader(sample, firstByte, hdrBytes)\n}\n\nfunc (a *updatableAEAD) FirstPacketNumber() protocol.PacketNumber {\n\treturn a.firstPacketNumber\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/handshake/xor_nonce_aead_boring.go",
    "content": "//go:build boringcrypto\n\npackage handshake\n\nimport (\n\t\"crypto/cipher\"\n\t\"crypto/tls\"\n\t\"os\"\n\t\"strings\"\n)\n\nvar goBoringDisabled bool = strings.TrimSpace(os.Getenv(\"QUIC_GO_DISABLE_BORING\")) == \"1\"\n\nfunc newAEAD(aes cipher.Block) (cipher.AEAD, error) {\n\tif goBoringDisabled {\n\t\t// In case Go Boring is disabled then\n\t\t// fallback to normal cryptographic procedure.\n\t\treturn cipher.NewGCM(aes)\n\t}\n\treturn tls.NewGCMTLS13(aes)\n}\n\nfunc allZeros(nonce []byte) bool {\n\tfor _, e := range nonce {\n\t\tif e != 0 {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (f *xorNonceAEAD) sealZeroNonce() {\n\tf.doSeal([]byte{}, []byte{}, []byte{}, []byte{})\n}\n\nfunc (f *xorNonceAEAD) seal(nonce, out, plaintext, additionalData []byte) []byte {\n\tif !goBoringDisabled {\n\t\tif !f.hasSeenNonceZero {\n\t\t\t// BoringSSL expects that the first nonce passed to the\n\t\t\t// AEAD instance is zero.\n\t\t\t// At this point the nonce argument is either zero or\n\t\t\t// an artificial one will be passed to the AEAD through\n\t\t\t// [sealZeroNonce]\n\t\t\tf.hasSeenNonceZero = true\n\t\t\tif !allZeros(nonce) {\n\t\t\t\tf.sealZeroNonce()\n\t\t\t}\n\t\t}\n\t}\n\treturn f.doSeal(nonce, out, plaintext, additionalData)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/handshake/xor_nonce_aead_noboring.go",
    "content": "//go:build !boringcrypto\n\npackage handshake\n\nimport \"crypto/cipher\"\n\nfunc newAEAD(aes cipher.Block) (cipher.AEAD, error) {\n\treturn cipher.NewGCM(aes)\n}\n\nfunc (f *xorNonceAEAD) seal(nonce, out, plaintext, additionalData []byte) []byte {\n\treturn f.doSeal(nonce, out, plaintext, additionalData)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/protocol/connection_id.go",
    "content": "package protocol\n\nimport (\n\t\"crypto/rand\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\nvar ErrInvalidConnectionIDLen = errors.New(\"invalid Connection ID length\")\n\n// An ArbitraryLenConnectionID is a QUIC Connection ID able to represent Connection IDs according to RFC 8999.\n// Future QUIC versions might allow connection ID lengths up to 255 bytes, while QUIC v1\n// restricts the length to 20 bytes.\ntype ArbitraryLenConnectionID []byte\n\nfunc (c ArbitraryLenConnectionID) Len() int {\n\treturn len(c)\n}\n\nfunc (c ArbitraryLenConnectionID) Bytes() []byte {\n\treturn c\n}\n\nfunc (c ArbitraryLenConnectionID) String() string {\n\tif c.Len() == 0 {\n\t\treturn \"(empty)\"\n\t}\n\treturn fmt.Sprintf(\"%x\", c.Bytes())\n}\n\nconst maxConnectionIDLen = 20\n\n// A ConnectionID in QUIC\ntype ConnectionID struct {\n\tb [20]byte\n\tl uint8\n}\n\n// GenerateConnectionID generates a connection ID using cryptographic random\nfunc GenerateConnectionID(l int) (ConnectionID, error) {\n\tvar c ConnectionID\n\tc.l = uint8(l)\n\t_, err := rand.Read(c.b[:l])\n\treturn c, err\n}\n\n// ParseConnectionID interprets b as a Connection ID.\n// It panics if b is longer than 20 bytes.\nfunc ParseConnectionID(b []byte) ConnectionID {\n\tif len(b) > maxConnectionIDLen {\n\t\tpanic(\"invalid conn id length\")\n\t}\n\tvar c ConnectionID\n\tc.l = uint8(len(b))\n\tcopy(c.b[:c.l], b)\n\treturn c\n}\n\n// GenerateConnectionIDForInitial generates a connection ID for the Initial packet.\n// It uses a length randomly chosen between 8 and 20 bytes.\nfunc GenerateConnectionIDForInitial() (ConnectionID, error) {\n\tr := make([]byte, 1)\n\tif _, err := rand.Read(r); err != nil {\n\t\treturn ConnectionID{}, err\n\t}\n\tl := MinConnectionIDLenInitial + int(r[0])%(maxConnectionIDLen-MinConnectionIDLenInitial+1)\n\treturn GenerateConnectionID(l)\n}\n\n// ReadConnectionID reads a connection ID of length len from the given io.Reader.\n// It returns io.EOF if there are not enough bytes to read.\nfunc ReadConnectionID(r io.Reader, l int) (ConnectionID, error) {\n\tvar c ConnectionID\n\tif l == 0 {\n\t\treturn c, nil\n\t}\n\tif l > maxConnectionIDLen {\n\t\treturn c, ErrInvalidConnectionIDLen\n\t}\n\tc.l = uint8(l)\n\t_, err := io.ReadFull(r, c.b[:l])\n\tif err == io.ErrUnexpectedEOF {\n\t\treturn c, io.EOF\n\t}\n\treturn c, err\n}\n\n// Len returns the length of the connection ID in bytes\nfunc (c ConnectionID) Len() int {\n\treturn int(c.l)\n}\n\n// Bytes returns the byte representation\nfunc (c ConnectionID) Bytes() []byte {\n\treturn c.b[:c.l]\n}\n\nfunc (c ConnectionID) String() string {\n\tif c.Len() == 0 {\n\t\treturn \"(empty)\"\n\t}\n\treturn fmt.Sprintf(\"%x\", c.Bytes())\n}\n\ntype DefaultConnectionIDGenerator struct {\n\tConnLen int\n}\n\nfunc (d *DefaultConnectionIDGenerator) GenerateConnectionID() (ConnectionID, error) {\n\treturn GenerateConnectionID(d.ConnLen)\n}\n\nfunc (d *DefaultConnectionIDGenerator) ConnectionIDLen() int {\n\treturn d.ConnLen\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/protocol/encryption_level.go",
    "content": "package protocol\n\nimport (\n\t\"crypto/tls\"\n\t\"fmt\"\n)\n\n// EncryptionLevel is the encryption level\n// Default value is Unencrypted\ntype EncryptionLevel uint8\n\nconst (\n\t// EncryptionInitial is the Initial encryption level\n\tEncryptionInitial EncryptionLevel = 1 + iota\n\t// EncryptionHandshake is the Handshake encryption level\n\tEncryptionHandshake\n\t// Encryption0RTT is the 0-RTT encryption level\n\tEncryption0RTT\n\t// Encryption1RTT is the 1-RTT encryption level\n\tEncryption1RTT\n)\n\nfunc (e EncryptionLevel) String() string {\n\tswitch e {\n\tcase EncryptionInitial:\n\t\treturn \"Initial\"\n\tcase EncryptionHandshake:\n\t\treturn \"Handshake\"\n\tcase Encryption0RTT:\n\t\treturn \"0-RTT\"\n\tcase Encryption1RTT:\n\t\treturn \"1-RTT\"\n\t}\n\treturn \"unknown\"\n}\n\nfunc (e EncryptionLevel) ToTLSEncryptionLevel() tls.QUICEncryptionLevel {\n\tswitch e {\n\tcase EncryptionInitial:\n\t\treturn tls.QUICEncryptionLevelInitial\n\tcase EncryptionHandshake:\n\t\treturn tls.QUICEncryptionLevelHandshake\n\tcase Encryption1RTT:\n\t\treturn tls.QUICEncryptionLevelApplication\n\tcase Encryption0RTT:\n\t\treturn tls.QUICEncryptionLevelEarly\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unexpected encryption level: %s\", e))\n\t}\n}\n\nfunc FromTLSEncryptionLevel(e tls.QUICEncryptionLevel) EncryptionLevel {\n\tswitch e {\n\tcase tls.QUICEncryptionLevelInitial:\n\t\treturn EncryptionInitial\n\tcase tls.QUICEncryptionLevelHandshake:\n\t\treturn EncryptionHandshake\n\tcase tls.QUICEncryptionLevelApplication:\n\t\treturn Encryption1RTT\n\tcase tls.QUICEncryptionLevelEarly:\n\t\treturn Encryption0RTT\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unexpect encryption level: %s\", e))\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/protocol/key_phase.go",
    "content": "package protocol\n\n// KeyPhase is the key phase\ntype KeyPhase uint64\n\n// Bit determines the key phase bit\nfunc (p KeyPhase) Bit() KeyPhaseBit {\n\tif p%2 == 0 {\n\t\treturn KeyPhaseZero\n\t}\n\treturn KeyPhaseOne\n}\n\n// KeyPhaseBit is the key phase bit\ntype KeyPhaseBit uint8\n\nconst (\n\t// KeyPhaseUndefined is an undefined key phase\n\tKeyPhaseUndefined KeyPhaseBit = iota\n\t// KeyPhaseZero is key phase 0\n\tKeyPhaseZero\n\t// KeyPhaseOne is key phase 1\n\tKeyPhaseOne\n)\n\nfunc (p KeyPhaseBit) String() string {\n\t//nolint:exhaustive\n\tswitch p {\n\tcase KeyPhaseZero:\n\t\treturn \"0\"\n\tcase KeyPhaseOne:\n\t\treturn \"1\"\n\tdefault:\n\t\treturn \"undefined\"\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/protocol/packet_number.go",
    "content": "package protocol\n\n// A PacketNumber in QUIC\ntype PacketNumber int64\n\n// InvalidPacketNumber is a packet number that is never sent.\n// In QUIC, 0 is a valid packet number.\nconst InvalidPacketNumber PacketNumber = -1\n\n// PacketNumberLen is the length of the packet number in bytes\ntype PacketNumberLen uint8\n\nconst (\n\t// PacketNumberLen1 is a packet number length of 1 byte\n\tPacketNumberLen1 PacketNumberLen = 1\n\t// PacketNumberLen2 is a packet number length of 2 bytes\n\tPacketNumberLen2 PacketNumberLen = 2\n\t// PacketNumberLen3 is a packet number length of 3 bytes\n\tPacketNumberLen3 PacketNumberLen = 3\n\t// PacketNumberLen4 is a packet number length of 4 bytes\n\tPacketNumberLen4 PacketNumberLen = 4\n)\n\n// DecodePacketNumber calculates the packet number based its length and the last seen packet number\n// This function is taken from https://www.rfc-editor.org/rfc/rfc9000.html#section-a.3.\nfunc DecodePacketNumber(length PacketNumberLen, largest PacketNumber, truncated PacketNumber) PacketNumber {\n\texpected := largest + 1\n\twin := PacketNumber(1 << (length * 8))\n\thwin := win / 2\n\tmask := win - 1\n\tcandidate := (expected & ^mask) | truncated\n\tif candidate <= expected-hwin && candidate < 1<<62-win {\n\t\treturn candidate + win\n\t}\n\tif candidate > expected+hwin && candidate >= win {\n\t\treturn candidate - win\n\t}\n\treturn candidate\n}\n\n// PacketNumberLengthForHeader gets the length of the packet number for the public header\n// it never chooses a PacketNumberLen of 1 byte, since this is too short under certain circumstances\nfunc PacketNumberLengthForHeader(pn, largestAcked PacketNumber) PacketNumberLen {\n\tvar numUnacked PacketNumber\n\tif largestAcked == InvalidPacketNumber {\n\t\tnumUnacked = pn + 1\n\t} else {\n\t\tnumUnacked = pn - largestAcked\n\t}\n\tif numUnacked < 1<<(16-1) {\n\t\treturn PacketNumberLen2\n\t}\n\tif numUnacked < 1<<(24-1) {\n\t\treturn PacketNumberLen3\n\t}\n\treturn PacketNumberLen4\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/protocol/params.go",
    "content": "package protocol\n\nimport \"time\"\n\n// DesiredReceiveBufferSize is the kernel UDP receive buffer size that we'd like to use.\nconst DesiredReceiveBufferSize = (1 << 20) * 7 // 7 MB\n\n// DesiredSendBufferSize is the kernel UDP send buffer size that we'd like to use.\nconst DesiredSendBufferSize = (1 << 20) * 7 // 7 MB\n\n// InitialPacketSize is the initial (before Path MTU discovery) maximum packet size used.\nconst InitialPacketSize = 1280\n\n// MaxCongestionWindowPackets is the maximum congestion window in packet.\nconst MaxCongestionWindowPackets = 10000\n\n// MaxUndecryptablePackets limits the number of undecryptable packets that are queued in the connection.\nconst MaxUndecryptablePackets = 32\n\n// ConnectionFlowControlMultiplier determines how much larger the connection flow control windows needs to be relative to any stream's flow control window\n// This is the value that Chromium is using\nconst ConnectionFlowControlMultiplier = 1.5\n\n// DefaultInitialMaxStreamData is the default initial stream-level flow control window for receiving data\nconst DefaultInitialMaxStreamData = (1 << 10) * 512 // 512 kb\n\n// DefaultInitialMaxData is the connection-level flow control window for receiving data\nconst DefaultInitialMaxData = ConnectionFlowControlMultiplier * DefaultInitialMaxStreamData\n\n// DefaultMaxReceiveStreamFlowControlWindow is the default maximum stream-level flow control window for receiving data\nconst DefaultMaxReceiveStreamFlowControlWindow = 6 * (1 << 20) // 6 MB\n\n// DefaultMaxReceiveConnectionFlowControlWindow is the default connection-level flow control window for receiving data\nconst DefaultMaxReceiveConnectionFlowControlWindow = 15 * (1 << 20) // 15 MB\n\n// WindowUpdateThreshold is the fraction of the receive window that has to be consumed before an higher offset is advertised to the client\nconst WindowUpdateThreshold = 0.25\n\n// DefaultMaxIncomingStreams is the maximum number of streams that a peer may open\nconst DefaultMaxIncomingStreams = 100\n\n// DefaultMaxIncomingUniStreams is the maximum number of unidirectional streams that a peer may open\nconst DefaultMaxIncomingUniStreams = 100\n\n// MaxServerUnprocessedPackets is the max number of packets stored in the server that are not yet processed.\nconst MaxServerUnprocessedPackets = 1024\n\n// MaxConnUnprocessedPackets is the max number of packets stored in each connection that are not yet processed.\nconst MaxConnUnprocessedPackets = 256\n\n// SkipPacketInitialPeriod is the initial period length used for packet number skipping to prevent an Optimistic ACK attack.\n// Every time a packet number is skipped, the period is doubled, up to SkipPacketMaxPeriod.\nconst SkipPacketInitialPeriod PacketNumber = 256\n\n// SkipPacketMaxPeriod is the maximum period length used for packet number skipping.\nconst SkipPacketMaxPeriod PacketNumber = 128 * 1024\n\n// MaxAcceptQueueSize is the maximum number of connections that the server queues for accepting.\n// If the queue is full, new connection attempts will be rejected.\nconst MaxAcceptQueueSize = 32\n\n// TokenValidity is the duration that a (non-retry) token is considered valid\nconst TokenValidity = 24 * time.Hour\n\n// MaxOutstandingSentPackets is maximum number of packets saved for retransmission.\n// When reached, it imposes a soft limit on sending new packets:\n// Sending ACKs and retransmission is still allowed, but now new regular packets can be sent.\nconst MaxOutstandingSentPackets = 2 * MaxCongestionWindowPackets\n\n// MaxTrackedSentPackets is maximum number of sent packets saved for retransmission.\n// When reached, no more packets will be sent.\n// This value *must* be larger than MaxOutstandingSentPackets.\nconst MaxTrackedSentPackets = MaxOutstandingSentPackets * 5 / 4\n\n// MaxNonAckElicitingAcks is the maximum number of packets containing an ACK,\n// but no ack-eliciting frames, that we send in a row\nconst MaxNonAckElicitingAcks = 19\n\n// MaxStreamFrameSorterGaps is the maximum number of gaps between received StreamFrames\n// prevents DoS attacks against the streamFrameSorter\nconst MaxStreamFrameSorterGaps = 1000\n\n// MinStreamFrameBufferSize is the minimum data length of a received STREAM frame\n// that we use the buffer for. This protects against a DoS where an attacker would send us\n// very small STREAM frames to consume a lot of memory.\nconst MinStreamFrameBufferSize = 128\n\n// MinCoalescedPacketSize is the minimum size of a coalesced packet that we pack.\n// If a packet has less than this number of bytes, we won't coalesce any more packets onto it.\nconst MinCoalescedPacketSize = 128\n\n// MaxCryptoStreamOffset is the maximum offset allowed on any of the crypto streams.\n// This limits the size of the ClientHello and Certificates that can be received.\nconst MaxCryptoStreamOffset = 16 * (1 << 10)\n\n// MinRemoteIdleTimeout is the minimum value that we accept for the remote idle timeout\nconst MinRemoteIdleTimeout = 5 * time.Second\n\n// DefaultIdleTimeout is the default idle timeout\nconst DefaultIdleTimeout = 30 * time.Second\n\n// DefaultHandshakeIdleTimeout is the default idle timeout used before handshake completion.\nconst DefaultHandshakeIdleTimeout = 5 * time.Second\n\n// RetiredConnectionIDDeleteTimeout is the time we keep closed connections around in order to retransmit the CONNECTION_CLOSE.\n// after this time all information about the old connection will be deleted\nconst RetiredConnectionIDDeleteTimeout = 5 * time.Second\n\n// MinStreamFrameSize is the minimum size that has to be left in a packet, so that we add another STREAM frame.\n// This avoids splitting up STREAM frames into small pieces, which has 2 advantages:\n// 1. it reduces the framing overhead\n// 2. it reduces the head-of-line blocking, when a packet is lost\nconst MinStreamFrameSize ByteCount = 128\n\n// MaxPostHandshakeCryptoFrameSize is the maximum size of CRYPTO frames\n// we send after the handshake completes.\nconst MaxPostHandshakeCryptoFrameSize = 1000\n\n// MaxAckFrameSize is the maximum size for an ACK frame that we write\n// Due to the varint encoding, ACK frames can grow (almost) indefinitely large.\n// The MaxAckFrameSize should be large enough to encode many ACK range,\n// but must ensure that a maximum size ACK frame fits into one packet.\nconst MaxAckFrameSize ByteCount = 1000\n\n// MaxNumAckRanges is the maximum number of ACK ranges that we send in an ACK frame.\n// It also serves as a limit for the packet history.\n// If at any point we keep track of more ranges, old ranges are discarded.\nconst MaxNumAckRanges = 32\n\n// MinPacingDelay is the minimum duration that is used for packet pacing\n// If the packet packing frequency is higher, multiple packets might be sent at once.\n// Example: For a packet pacing delay of 200μs, we would send 5 packets at once, wait for 1ms, and so forth.\nconst MinPacingDelay = time.Millisecond\n\n// DefaultConnectionIDLength is the connection ID length that is used for multiplexed connections\n// if no other value is configured.\nconst DefaultConnectionIDLength = 4\n\n// MaxActiveConnectionIDs is the number of connection IDs that we're storing.\nconst MaxActiveConnectionIDs = 4\n\n// MaxIssuedConnectionIDs is the maximum number of connection IDs that we're issuing at the same time.\nconst MaxIssuedConnectionIDs = 6\n\n// PacketsPerConnectionID is the number of packets we send using one connection ID.\n// If the peer provices us with enough new connection IDs, we switch to a new connection ID.\nconst PacketsPerConnectionID = 10000\n\n// AckDelayExponent is the ack delay exponent used when sending ACKs.\nconst AckDelayExponent = 3\n\n// Estimated timer granularity.\n// The loss detection timer will not be set to a value smaller than granularity.\nconst TimerGranularity = time.Millisecond\n\n// MaxAckDelay is the maximum time by which we delay sending ACKs.\nconst MaxAckDelay = 25 * time.Millisecond\n\n// MaxAckDelayInclGranularity is the max_ack_delay including the timer granularity.\n// This is the value that should be advertised to the peer.\nconst MaxAckDelayInclGranularity = MaxAckDelay + TimerGranularity\n\n// KeyUpdateInterval is the maximum number of packets we send or receive before initiating a key update.\nconst KeyUpdateInterval = 100 * 1000\n\n// Max0RTTQueueingDuration is the maximum time that we store 0-RTT packets in order to wait for the corresponding Initial to be received.\nconst Max0RTTQueueingDuration = 100 * time.Millisecond\n\n// Max0RTTQueues is the maximum number of connections that we buffer 0-RTT packets for.\nconst Max0RTTQueues = 32\n\n// Max0RTTQueueLen is the maximum number of 0-RTT packets that we buffer for each connection.\n// When a new connection is created, all buffered packets are passed to the connection immediately.\n// To avoid blocking, this value has to be smaller than MaxConnUnprocessedPackets.\n// To avoid packets being dropped as undecryptable by the connection, this value has to be smaller than MaxUndecryptablePackets.\nconst Max0RTTQueueLen = 31\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/protocol/perspective.go",
    "content": "package protocol\n\n// Perspective determines if we're acting as a server or a client\ntype Perspective int\n\n// the perspectives\nconst (\n\tPerspectiveServer Perspective = 1\n\tPerspectiveClient Perspective = 2\n)\n\n// Opposite returns the perspective of the peer\nfunc (p Perspective) Opposite() Perspective {\n\treturn 3 - p\n}\n\nfunc (p Perspective) String() string {\n\tswitch p {\n\tcase PerspectiveServer:\n\t\treturn \"server\"\n\tcase PerspectiveClient:\n\t\treturn \"client\"\n\tdefault:\n\t\treturn \"invalid perspective\"\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/protocol/protocol.go",
    "content": "package protocol\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\n// The PacketType is the Long Header Type\ntype PacketType uint8\n\nconst (\n\t// PacketTypeInitial is the packet type of an Initial packet\n\tPacketTypeInitial PacketType = 1 + iota\n\t// PacketTypeRetry is the packet type of a Retry packet\n\tPacketTypeRetry\n\t// PacketTypeHandshake is the packet type of a Handshake packet\n\tPacketTypeHandshake\n\t// PacketType0RTT is the packet type of a 0-RTT packet\n\tPacketType0RTT\n)\n\nfunc (t PacketType) String() string {\n\tswitch t {\n\tcase PacketTypeInitial:\n\t\treturn \"Initial\"\n\tcase PacketTypeRetry:\n\t\treturn \"Retry\"\n\tcase PacketTypeHandshake:\n\t\treturn \"Handshake\"\n\tcase PacketType0RTT:\n\t\treturn \"0-RTT Protected\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"unknown packet type: %d\", t)\n\t}\n}\n\ntype ECN uint8\n\nconst (\n\tECNUnsupported ECN = iota\n\tECNNon             // 00\n\tECT1               // 01\n\tECT0               // 10\n\tECNCE              // 11\n)\n\nfunc ParseECNHeaderBits(bits byte) ECN {\n\tswitch bits {\n\tcase 0:\n\t\treturn ECNNon\n\tcase 0b00000010:\n\t\treturn ECT0\n\tcase 0b00000001:\n\t\treturn ECT1\n\tcase 0b00000011:\n\t\treturn ECNCE\n\tdefault:\n\t\tpanic(\"invalid ECN bits\")\n\t}\n}\n\nfunc (e ECN) ToHeaderBits() byte {\n\t//nolint:exhaustive // There are only 4 values.\n\tswitch e {\n\tcase ECNNon:\n\t\treturn 0\n\tcase ECT0:\n\t\treturn 0b00000010\n\tcase ECT1:\n\t\treturn 0b00000001\n\tcase ECNCE:\n\t\treturn 0b00000011\n\tdefault:\n\t\tpanic(\"ECN unsupported\")\n\t}\n}\n\nfunc (e ECN) String() string {\n\tswitch e {\n\tcase ECNUnsupported:\n\t\treturn \"ECN unsupported\"\n\tcase ECNNon:\n\t\treturn \"Not-ECT\"\n\tcase ECT1:\n\t\treturn \"ECT(1)\"\n\tcase ECT0:\n\t\treturn \"ECT(0)\"\n\tcase ECNCE:\n\t\treturn \"CE\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"invalid ECN value: %d\", e)\n\t}\n}\n\n// A ByteCount in QUIC\ntype ByteCount int64\n\n// MaxByteCount is the maximum value of a ByteCount\nconst MaxByteCount = ByteCount(1<<62 - 1)\n\n// InvalidByteCount is an invalid byte count\nconst InvalidByteCount ByteCount = -1\n\n// A StatelessResetToken is a stateless reset token.\ntype StatelessResetToken [16]byte\n\n// MaxPacketBufferSize maximum packet size of any QUIC packet, based on\n// ethernet's max size, minus the IP and UDP headers. IPv6 has a 40 byte header,\n// UDP adds an additional 8 bytes.  This is a total overhead of 48 bytes.\n// Ethernet's max packet size is 1500 bytes,  1500 - 48 = 1452.\nconst MaxPacketBufferSize = 1452\n\n// MaxLargePacketBufferSize is used when using GSO\nconst MaxLargePacketBufferSize = 20 * 1024\n\n// MinInitialPacketSize is the minimum size an Initial packet is required to have.\nconst MinInitialPacketSize = 1200\n\n// MinUnknownVersionPacketSize is the minimum size a packet with an unknown version\n// needs to have in order to trigger a Version Negotiation packet.\nconst MinUnknownVersionPacketSize = MinInitialPacketSize\n\n// MinStatelessResetSize is the minimum size of a stateless reset packet that we send\nconst MinStatelessResetSize = 1 /* first byte */ + 20 /* max. conn ID length */ + 4 /* max. packet number length */ + 1 /* min. payload length */ + 16 /* token */\n\n// MinReceivedStatelessResetSize is the minimum size of a received stateless reset,\n// as specified in section 10.3 of RFC 9000.\nconst MinReceivedStatelessResetSize = 5 + 16\n\n// MinConnectionIDLenInitial is the minimum length of the destination connection ID on an Initial packet.\nconst MinConnectionIDLenInitial = 8\n\n// DefaultAckDelayExponent is the default ack delay exponent\nconst DefaultAckDelayExponent = 3\n\n// DefaultActiveConnectionIDLimit is the default active connection ID limit\nconst DefaultActiveConnectionIDLimit = 2\n\n// MaxAckDelayExponent is the maximum ack delay exponent\nconst MaxAckDelayExponent = 20\n\n// DefaultMaxAckDelay is the default max_ack_delay\nconst DefaultMaxAckDelay = 25 * time.Millisecond\n\n// MaxMaxAckDelay is the maximum max_ack_delay\nconst MaxMaxAckDelay = (1<<14 - 1) * time.Millisecond\n\n// MaxConnIDLen is the maximum length of the connection ID\nconst MaxConnIDLen = 20\n\n// InvalidPacketLimitAES is the maximum number of packets that we can fail to decrypt when using\n// AEAD_AES_128_GCM or AEAD_AES_265_GCM.\nconst InvalidPacketLimitAES = 1 << 52\n\n// InvalidPacketLimitChaCha is the maximum number of packets that we can fail to decrypt when using AEAD_CHACHA20_POLY1305.\nconst InvalidPacketLimitChaCha = 1 << 36\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/protocol/stream.go",
    "content": "package protocol\n\n// StreamType encodes if this is a unidirectional or bidirectional stream\ntype StreamType uint8\n\nconst (\n\t// StreamTypeUni is a unidirectional stream\n\tStreamTypeUni StreamType = iota\n\t// StreamTypeBidi is a bidirectional stream\n\tStreamTypeBidi\n)\n\n// InvalidPacketNumber is a stream ID that is invalid.\n// The first valid stream ID in QUIC is 0.\nconst InvalidStreamID StreamID = -1\n\n// StreamNum is the stream number\ntype StreamNum int64\n\nconst (\n\t// InvalidStreamNum is an invalid stream number.\n\tInvalidStreamNum = -1\n\t// MaxStreamCount is the maximum stream count value that can be sent in MAX_STREAMS frames\n\t// and as the stream count in the transport parameters\n\tMaxStreamCount StreamNum = 1 << 60\n)\n\n// StreamID calculates the stream ID.\nfunc (s StreamNum) StreamID(stype StreamType, pers Perspective) StreamID {\n\tif s == 0 {\n\t\treturn InvalidStreamID\n\t}\n\tvar first StreamID\n\tswitch stype {\n\tcase StreamTypeBidi:\n\t\tswitch pers {\n\t\tcase PerspectiveClient:\n\t\t\tfirst = 0\n\t\tcase PerspectiveServer:\n\t\t\tfirst = 1\n\t\t}\n\tcase StreamTypeUni:\n\t\tswitch pers {\n\t\tcase PerspectiveClient:\n\t\t\tfirst = 2\n\t\tcase PerspectiveServer:\n\t\t\tfirst = 3\n\t\t}\n\t}\n\treturn first + 4*StreamID(s-1)\n}\n\n// A StreamID in QUIC\ntype StreamID int64\n\n// InitiatedBy says if the stream was initiated by the client or by the server\nfunc (s StreamID) InitiatedBy() Perspective {\n\tif s%2 == 0 {\n\t\treturn PerspectiveClient\n\t}\n\treturn PerspectiveServer\n}\n\n// Type says if this is a unidirectional or bidirectional stream\nfunc (s StreamID) Type() StreamType {\n\tif s%4 >= 2 {\n\t\treturn StreamTypeUni\n\t}\n\treturn StreamTypeBidi\n}\n\n// StreamNum returns how many streams in total are below this\n// Example: for stream 9 it returns 3 (i.e. streams 1, 5 and 9)\nfunc (s StreamID) StreamNum() StreamNum {\n\treturn StreamNum(s/4) + 1\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/protocol/version.go",
    "content": "package protocol\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"math\"\n\tmrand \"math/rand/v2\"\n\t\"sync\"\n)\n\n// Version is a version number as int\ntype Version uint32\n\n// gQUIC version range as defined in the wiki: https://github.com/quicwg/base-drafts/wiki/QUIC-Versions\nconst (\n\tgquicVersion0   = 0x51303030\n\tmaxGquicVersion = 0x51303439\n)\n\n// The version numbers, making grepping easier\nconst (\n\tVersionUnknown Version = math.MaxUint32\n\tversionDraft29 Version = 0xff00001d // draft-29 used to be a widely deployed version\n\tVersion1       Version = 0x1\n\tVersion2       Version = 0x6b3343cf\n)\n\n// SupportedVersions lists the versions that the server supports\n// must be in sorted descending order\nvar SupportedVersions = []Version{Version1, Version2}\n\n// IsValidVersion says if the version is known to quic-go\nfunc IsValidVersion(v Version) bool {\n\treturn v == Version1 || IsSupportedVersion(SupportedVersions, v)\n}\n\nfunc (vn Version) String() string {\n\t//nolint:exhaustive\n\tswitch vn {\n\tcase VersionUnknown:\n\t\treturn \"unknown\"\n\tcase versionDraft29:\n\t\treturn \"draft-29\"\n\tcase Version1:\n\t\treturn \"v1\"\n\tcase Version2:\n\t\treturn \"v2\"\n\tdefault:\n\t\tif vn.isGQUIC() {\n\t\t\treturn fmt.Sprintf(\"gQUIC %d\", vn.toGQUICVersion())\n\t\t}\n\t\treturn fmt.Sprintf(\"%#x\", uint32(vn))\n\t}\n}\n\nfunc (vn Version) isGQUIC() bool {\n\treturn vn > gquicVersion0 && vn <= maxGquicVersion\n}\n\nfunc (vn Version) toGQUICVersion() int {\n\treturn int(10*(vn-gquicVersion0)/0x100) + int(vn%0x10)\n}\n\n// IsSupportedVersion returns true if the server supports this version\nfunc IsSupportedVersion(supported []Version, v Version) bool {\n\tfor _, t := range supported {\n\t\tif t == v {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// ChooseSupportedVersion finds the best version in the overlap of ours and theirs\n// ours is a slice of versions that we support, sorted by our preference (descending)\n// theirs is a slice of versions offered by the peer. The order does not matter.\n// The bool returned indicates if a matching version was found.\nfunc ChooseSupportedVersion(ours, theirs []Version) (Version, bool) {\n\tfor _, ourVer := range ours {\n\t\tfor _, theirVer := range theirs {\n\t\t\tif ourVer == theirVer {\n\t\t\t\treturn ourVer, true\n\t\t\t}\n\t\t}\n\t}\n\treturn 0, false\n}\n\nvar (\n\tversionNegotiationMx   sync.Mutex\n\tversionNegotiationRand mrand.Rand\n)\n\nfunc init() {\n\tvar seed [16]byte\n\trand.Read(seed[:])\n\tversionNegotiationRand = *mrand.New(mrand.NewPCG(\n\t\tbinary.BigEndian.Uint64(seed[:8]),\n\t\tbinary.BigEndian.Uint64(seed[8:]),\n\t))\n}\n\n// generateReservedVersion generates a reserved version (v & 0x0f0f0f0f == 0x0a0a0a0a)\nfunc generateReservedVersion() Version {\n\tvar b [4]byte\n\tbinary.BigEndian.PutUint32(b[:], versionNegotiationRand.Uint32())\n\treturn Version((binary.BigEndian.Uint32(b[:]) | 0x0a0a0a0a) & 0xfafafafa)\n}\n\n// GetGreasedVersions adds one reserved version number to a slice of version numbers, at a random position.\n// It doesn't modify the supported slice.\nfunc GetGreasedVersions(supported []Version) []Version {\n\tversionNegotiationMx.Lock()\n\tdefer versionNegotiationMx.Unlock()\n\trandPos := versionNegotiationRand.IntN(len(supported) + 1)\n\tgreased := make([]Version, len(supported)+1)\n\tcopy(greased, supported[:randPos])\n\tgreased[randPos] = generateReservedVersion()\n\tcopy(greased[randPos+1:], supported[randPos:])\n\treturn greased\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/qerr/error_codes.go",
    "content": "package qerr\n\nimport (\n\t\"crypto/tls\"\n\t\"fmt\"\n)\n\n// TransportErrorCode is a QUIC transport error.\ntype TransportErrorCode uint64\n\n// The error codes defined by QUIC\nconst (\n\tNoError                   TransportErrorCode = 0x0\n\tInternalError             TransportErrorCode = 0x1\n\tConnectionRefused         TransportErrorCode = 0x2\n\tFlowControlError          TransportErrorCode = 0x3\n\tStreamLimitError          TransportErrorCode = 0x4\n\tStreamStateError          TransportErrorCode = 0x5\n\tFinalSizeError            TransportErrorCode = 0x6\n\tFrameEncodingError        TransportErrorCode = 0x7\n\tTransportParameterError   TransportErrorCode = 0x8\n\tConnectionIDLimitError    TransportErrorCode = 0x9\n\tProtocolViolation         TransportErrorCode = 0xa\n\tInvalidToken              TransportErrorCode = 0xb\n\tApplicationErrorErrorCode TransportErrorCode = 0xc\n\tCryptoBufferExceeded      TransportErrorCode = 0xd\n\tKeyUpdateError            TransportErrorCode = 0xe\n\tAEADLimitReached          TransportErrorCode = 0xf\n\tNoViablePathError         TransportErrorCode = 0x10\n)\n\nfunc (e TransportErrorCode) IsCryptoError() bool {\n\treturn e >= 0x100 && e < 0x200\n}\n\n// Message is a description of the error.\n// It only returns a non-empty string for crypto errors.\nfunc (e TransportErrorCode) Message() string {\n\tif !e.IsCryptoError() {\n\t\treturn \"\"\n\t}\n\treturn tls.AlertError(e - 0x100).Error()\n}\n\nfunc (e TransportErrorCode) String() string {\n\tswitch e {\n\tcase NoError:\n\t\treturn \"NO_ERROR\"\n\tcase InternalError:\n\t\treturn \"INTERNAL_ERROR\"\n\tcase ConnectionRefused:\n\t\treturn \"CONNECTION_REFUSED\"\n\tcase FlowControlError:\n\t\treturn \"FLOW_CONTROL_ERROR\"\n\tcase StreamLimitError:\n\t\treturn \"STREAM_LIMIT_ERROR\"\n\tcase StreamStateError:\n\t\treturn \"STREAM_STATE_ERROR\"\n\tcase FinalSizeError:\n\t\treturn \"FINAL_SIZE_ERROR\"\n\tcase FrameEncodingError:\n\t\treturn \"FRAME_ENCODING_ERROR\"\n\tcase TransportParameterError:\n\t\treturn \"TRANSPORT_PARAMETER_ERROR\"\n\tcase ConnectionIDLimitError:\n\t\treturn \"CONNECTION_ID_LIMIT_ERROR\"\n\tcase ProtocolViolation:\n\t\treturn \"PROTOCOL_VIOLATION\"\n\tcase InvalidToken:\n\t\treturn \"INVALID_TOKEN\"\n\tcase ApplicationErrorErrorCode:\n\t\treturn \"APPLICATION_ERROR\"\n\tcase CryptoBufferExceeded:\n\t\treturn \"CRYPTO_BUFFER_EXCEEDED\"\n\tcase KeyUpdateError:\n\t\treturn \"KEY_UPDATE_ERROR\"\n\tcase AEADLimitReached:\n\t\treturn \"AEAD_LIMIT_REACHED\"\n\tcase NoViablePathError:\n\t\treturn \"NO_VIABLE_PATH\"\n\tdefault:\n\t\tif e.IsCryptoError() {\n\t\t\treturn fmt.Sprintf(\"CRYPTO_ERROR %#x\", uint16(e))\n\t\t}\n\t\treturn fmt.Sprintf(\"unknown error code: %#x\", uint16(e))\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/qerr/errors.go",
    "content": "package qerr\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\nvar (\n\tErrHandshakeTimeout = &HandshakeTimeoutError{}\n\tErrIdleTimeout      = &IdleTimeoutError{}\n)\n\ntype TransportError struct {\n\tRemote       bool\n\tFrameType    uint64\n\tErrorCode    TransportErrorCode\n\tErrorMessage string\n\terror        error // only set for local errors, sometimes\n}\n\nvar _ error = &TransportError{}\n\n// NewLocalCryptoError create a new TransportError instance for a crypto error\nfunc NewLocalCryptoError(tlsAlert uint8, err error) *TransportError {\n\treturn &TransportError{\n\t\tErrorCode: 0x100 + TransportErrorCode(tlsAlert),\n\t\terror:     err,\n\t}\n}\n\nfunc (e *TransportError) Error() string {\n\tstr := fmt.Sprintf(\"%s (%s)\", e.ErrorCode.String(), getRole(e.Remote))\n\tif e.FrameType != 0 {\n\t\tstr += fmt.Sprintf(\" (frame type: %#x)\", e.FrameType)\n\t}\n\tmsg := e.ErrorMessage\n\tif len(msg) == 0 && e.error != nil {\n\t\tmsg = e.error.Error()\n\t}\n\tif len(msg) == 0 {\n\t\tmsg = e.ErrorCode.Message()\n\t}\n\tif len(msg) == 0 {\n\t\treturn str\n\t}\n\treturn str + \": \" + msg\n}\n\nfunc (e *TransportError) Unwrap() []error { return []error{net.ErrClosed, e.error} }\n\nfunc (e *TransportError) Is(target error) bool {\n\tt, ok := target.(*TransportError)\n\treturn ok && e.ErrorCode == t.ErrorCode && e.FrameType == t.FrameType && e.Remote == t.Remote\n}\n\n// An ApplicationErrorCode is an application-defined error code.\ntype ApplicationErrorCode uint64\n\n// A StreamErrorCode is an error code used to cancel streams.\ntype StreamErrorCode uint64\n\ntype ApplicationError struct {\n\tRemote       bool\n\tErrorCode    ApplicationErrorCode\n\tErrorMessage string\n}\n\nvar _ error = &ApplicationError{}\n\nfunc (e *ApplicationError) Error() string {\n\tif len(e.ErrorMessage) == 0 {\n\t\treturn fmt.Sprintf(\"Application error %#x (%s)\", e.ErrorCode, getRole(e.Remote))\n\t}\n\treturn fmt.Sprintf(\"Application error %#x (%s): %s\", e.ErrorCode, getRole(e.Remote), e.ErrorMessage)\n}\n\nfunc (e *ApplicationError) Unwrap() error { return net.ErrClosed }\n\nfunc (e *ApplicationError) Is(target error) bool {\n\tt, ok := target.(*ApplicationError)\n\treturn ok && e.ErrorCode == t.ErrorCode && e.Remote == t.Remote\n}\n\ntype IdleTimeoutError struct{}\n\nvar _ error = &IdleTimeoutError{}\n\nfunc (e *IdleTimeoutError) Timeout() bool   { return true }\nfunc (e *IdleTimeoutError) Temporary() bool { return false }\nfunc (e *IdleTimeoutError) Error() string   { return \"timeout: no recent network activity\" }\nfunc (e *IdleTimeoutError) Unwrap() error   { return net.ErrClosed }\n\ntype HandshakeTimeoutError struct{}\n\nvar _ error = &HandshakeTimeoutError{}\n\nfunc (e *HandshakeTimeoutError) Timeout() bool   { return true }\nfunc (e *HandshakeTimeoutError) Temporary() bool { return false }\nfunc (e *HandshakeTimeoutError) Error() string   { return \"timeout: handshake did not complete in time\" }\nfunc (e *HandshakeTimeoutError) Unwrap() error   { return net.ErrClosed }\n\n// A VersionNegotiationError occurs when the client and the server can't agree on a QUIC version.\ntype VersionNegotiationError struct {\n\tOurs   []protocol.Version\n\tTheirs []protocol.Version\n}\n\nfunc (e *VersionNegotiationError) Error() string {\n\treturn fmt.Sprintf(\"no compatible QUIC version found (we support %s, server offered %s)\", e.Ours, e.Theirs)\n}\n\nfunc (e *VersionNegotiationError) Unwrap() error { return net.ErrClosed }\n\n// A StatelessResetError occurs when we receive a stateless reset.\ntype StatelessResetError struct{}\n\nvar _ net.Error = &StatelessResetError{}\n\nfunc (e *StatelessResetError) Error() string {\n\treturn \"received a stateless reset\"\n}\n\nfunc (e *StatelessResetError) Unwrap() error   { return net.ErrClosed }\nfunc (e *StatelessResetError) Timeout() bool   { return false }\nfunc (e *StatelessResetError) Temporary() bool { return true }\n\nfunc getRole(remote bool) string {\n\tif remote {\n\t\treturn \"remote\"\n\t}\n\treturn \"local\"\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/utils/buffered_write_closer.go",
    "content": "package utils\n\nimport (\n\t\"bufio\"\n\t\"io\"\n)\n\ntype bufferedWriteCloser struct {\n\t*bufio.Writer\n\tio.Closer\n}\n\n// NewBufferedWriteCloser creates an io.WriteCloser from a bufio.Writer and an io.Closer\nfunc NewBufferedWriteCloser(writer *bufio.Writer, closer io.Closer) io.WriteCloser {\n\treturn &bufferedWriteCloser{\n\t\tWriter: writer,\n\t\tCloser: closer,\n\t}\n}\n\nfunc (h bufferedWriteCloser) Close() error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\treturn h.Closer.Close()\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/utils/linkedlist/README.md",
    "content": "# Usage\n\nThis is the Go standard library implementation of a linked list \n(https://golang.org/src/container/list/list.go), with the following modifications:\n* it uses Go generics\n* it allows passing in a `sync.Pool` (via the `NewWithPool` constructor) to reduce allocations of `Element` structs\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/utils/linkedlist/linkedlist.go",
    "content": "// Copyright 2009 The Go 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\n// Package list implements a doubly linked list.\n//\n// To iterate over a list (where l is a *List[T]):\n//\n//\tfor e := l.Front(); e != nil; e = e.Next() {\n//\t\t// do something with e.Value\n//\t}\npackage list\n\nimport \"sync\"\n\nfunc NewPool[T any]() *sync.Pool {\n\treturn &sync.Pool{New: func() any { return &Element[T]{} }}\n}\n\n// Element is an element of a linked list.\ntype Element[T any] struct {\n\t// Next and previous pointers in the doubly-linked list of elements.\n\t// To simplify the implementation, internally a list l is implemented\n\t// as a ring, such that &l.root is both the next element of the last\n\t// list element (l.Back()) and the previous element of the first list\n\t// element (l.Front()).\n\tnext, prev *Element[T]\n\n\t// The list to which this element belongs.\n\tlist *List[T]\n\n\t// The value stored with this element.\n\tValue T\n}\n\n// Next returns the next list element or nil.\nfunc (e *Element[T]) Next() *Element[T] {\n\tif p := e.next; e.list != nil && p != &e.list.root {\n\t\treturn p\n\t}\n\treturn nil\n}\n\n// Prev returns the previous list element or nil.\nfunc (e *Element[T]) Prev() *Element[T] {\n\tif p := e.prev; e.list != nil && p != &e.list.root {\n\t\treturn p\n\t}\n\treturn nil\n}\n\nfunc (e *Element[T]) List() *List[T] {\n\treturn e.list\n}\n\n// List represents a doubly linked list.\n// The zero value for List is an empty list ready to use.\ntype List[T any] struct {\n\troot Element[T] // sentinel list element, only &root, root.prev, and root.next are used\n\tlen  int        // current list length excluding (this) sentinel element\n\n\tpool *sync.Pool\n}\n\n// Init initializes or clears list l.\nfunc (l *List[T]) Init() *List[T] {\n\tl.root.next = &l.root\n\tl.root.prev = &l.root\n\tl.len = 0\n\treturn l\n}\n\n// New returns an initialized list.\nfunc New[T any]() *List[T] { return new(List[T]).Init() }\n\n// NewWithPool returns an initialized list, using a sync.Pool for list elements.\nfunc NewWithPool[T any](pool *sync.Pool) *List[T] {\n\tl := &List[T]{pool: pool}\n\treturn l.Init()\n}\n\n// Len returns the number of elements of list l.\n// The complexity is O(1).\nfunc (l *List[T]) Len() int { return l.len }\n\n// Front returns the first element of list l or nil if the list is empty.\nfunc (l *List[T]) Front() *Element[T] {\n\tif l.len == 0 {\n\t\treturn nil\n\t}\n\treturn l.root.next\n}\n\n// Back returns the last element of list l or nil if the list is empty.\nfunc (l *List[T]) Back() *Element[T] {\n\tif l.len == 0 {\n\t\treturn nil\n\t}\n\treturn l.root.prev\n}\n\n// lazyInit lazily initializes a zero List value.\nfunc (l *List[T]) lazyInit() {\n\tif l.root.next == nil {\n\t\tl.Init()\n\t}\n}\n\n// insert inserts e after at, increments l.len, and returns e.\nfunc (l *List[T]) insert(e, at *Element[T]) *Element[T] {\n\te.prev = at\n\te.next = at.next\n\te.prev.next = e\n\te.next.prev = e\n\te.list = l\n\tl.len++\n\treturn e\n}\n\n// insertValue is a convenience wrapper for insert(&Element{Value: v}, at).\nfunc (l *List[T]) insertValue(v T, at *Element[T]) *Element[T] {\n\tvar e *Element[T]\n\tif l.pool != nil {\n\t\te = l.pool.Get().(*Element[T])\n\t} else {\n\t\te = &Element[T]{}\n\t}\n\te.Value = v\n\treturn l.insert(e, at)\n}\n\n// remove removes e from its list, decrements l.len\nfunc (l *List[T]) remove(e *Element[T]) {\n\te.prev.next = e.next\n\te.next.prev = e.prev\n\te.next = nil // avoid memory leaks\n\te.prev = nil // avoid memory leaks\n\te.list = nil\n\tif l.pool != nil {\n\t\tl.pool.Put(e)\n\t}\n\tl.len--\n}\n\n// move moves e to next to at.\nfunc (l *List[T]) move(e, at *Element[T]) {\n\tif e == at {\n\t\treturn\n\t}\n\te.prev.next = e.next\n\te.next.prev = e.prev\n\n\te.prev = at\n\te.next = at.next\n\te.prev.next = e\n\te.next.prev = e\n}\n\n// Remove removes e from l if e is an element of list l.\n// It returns the element value e.Value.\n// The element must not be nil.\nfunc (l *List[T]) Remove(e *Element[T]) T {\n\tv := e.Value\n\tif e.list == l {\n\t\t// if e.list == l, l must have been initialized when e was inserted\n\t\t// in l or l == nil (e is a zero Element) and l.remove will crash\n\t\tl.remove(e)\n\t}\n\treturn v\n}\n\n// PushFront inserts a new element e with value v at the front of list l and returns e.\nfunc (l *List[T]) PushFront(v T) *Element[T] {\n\tl.lazyInit()\n\treturn l.insertValue(v, &l.root)\n}\n\n// PushBack inserts a new element e with value v at the back of list l and returns e.\nfunc (l *List[T]) PushBack(v T) *Element[T] {\n\tl.lazyInit()\n\treturn l.insertValue(v, l.root.prev)\n}\n\n// InsertBefore inserts a new element e with value v immediately before mark and returns e.\n// If mark is not an element of l, the list is not modified.\n// The mark must not be nil.\nfunc (l *List[T]) InsertBefore(v T, mark *Element[T]) *Element[T] {\n\tif mark.list != l {\n\t\treturn nil\n\t}\n\t// see comment in List.Remove about initialization of l\n\treturn l.insertValue(v, mark.prev)\n}\n\n// InsertAfter inserts a new element e with value v immediately after mark and returns e.\n// If mark is not an element of l, the list is not modified.\n// The mark must not be nil.\nfunc (l *List[T]) InsertAfter(v T, mark *Element[T]) *Element[T] {\n\tif mark.list != l {\n\t\treturn nil\n\t}\n\t// see comment in List.Remove about initialization of l\n\treturn l.insertValue(v, mark)\n}\n\n// MoveToFront moves element e to the front of list l.\n// If e is not an element of l, the list is not modified.\n// The element must not be nil.\nfunc (l *List[T]) MoveToFront(e *Element[T]) {\n\tif e.list != l || l.root.next == e {\n\t\treturn\n\t}\n\t// see comment in List.Remove about initialization of l\n\tl.move(e, &l.root)\n}\n\n// MoveToBack moves element e to the back of list l.\n// If e is not an element of l, the list is not modified.\n// The element must not be nil.\nfunc (l *List[T]) MoveToBack(e *Element[T]) {\n\tif e.list != l || l.root.prev == e {\n\t\treturn\n\t}\n\t// see comment in List.Remove about initialization of l\n\tl.move(e, l.root.prev)\n}\n\n// MoveBefore moves element e to its new position before mark.\n// If e or mark is not an element of l, or e == mark, the list is not modified.\n// The element and mark must not be nil.\nfunc (l *List[T]) MoveBefore(e, mark *Element[T]) {\n\tif e.list != l || e == mark || mark.list != l {\n\t\treturn\n\t}\n\tl.move(e, mark.prev)\n}\n\n// MoveAfter moves element e to its new position after mark.\n// If e or mark is not an element of l, or e == mark, the list is not modified.\n// The element and mark must not be nil.\nfunc (l *List[T]) MoveAfter(e, mark *Element[T]) {\n\tif e.list != l || e == mark || mark.list != l {\n\t\treturn\n\t}\n\tl.move(e, mark)\n}\n\n// PushBackList inserts a copy of another list at the back of list l.\n// The lists l and other may be the same. They must not be nil.\nfunc (l *List[T]) PushBackList(other *List[T]) {\n\tl.lazyInit()\n\tfor i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() {\n\t\tl.insertValue(e.Value, l.root.prev)\n\t}\n}\n\n// PushFrontList inserts a copy of another list at the front of list l.\n// The lists l and other may be the same. They must not be nil.\nfunc (l *List[T]) PushFrontList(other *List[T]) {\n\tl.lazyInit()\n\tfor i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() {\n\t\tl.insertValue(e.Value, &l.root)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/utils/log.go",
    "content": "package utils\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n)\n\n// LogLevel of quic-go\ntype LogLevel uint8\n\nconst (\n\t// LogLevelNothing disables\n\tLogLevelNothing LogLevel = iota\n\t// LogLevelError enables err logs\n\tLogLevelError\n\t// LogLevelInfo enables info logs (e.g. packets)\n\tLogLevelInfo\n\t// LogLevelDebug enables debug logs (e.g. packet contents)\n\tLogLevelDebug\n)\n\nconst logEnv = \"QUIC_GO_LOG_LEVEL\"\n\n// A Logger logs.\ntype Logger interface {\n\tSetLogLevel(LogLevel)\n\tSetLogTimeFormat(format string)\n\tWithPrefix(prefix string) Logger\n\tDebug() bool\n\n\tErrorf(format string, args ...interface{})\n\tInfof(format string, args ...interface{})\n\tDebugf(format string, args ...interface{})\n}\n\n// DefaultLogger is used by quic-go for logging.\nvar DefaultLogger Logger\n\ntype defaultLogger struct {\n\tprefix string\n\n\tlogLevel   LogLevel\n\ttimeFormat string\n}\n\nvar _ Logger = &defaultLogger{}\n\n// SetLogLevel sets the log level\nfunc (l *defaultLogger) SetLogLevel(level LogLevel) {\n\tl.logLevel = level\n}\n\n// SetLogTimeFormat sets the format of the timestamp\n// an empty string disables the logging of timestamps\nfunc (l *defaultLogger) SetLogTimeFormat(format string) {\n\tlog.SetFlags(0) // disable timestamp logging done by the log package\n\tl.timeFormat = format\n}\n\n// Debugf logs something\nfunc (l *defaultLogger) Debugf(format string, args ...interface{}) {\n\tif l.logLevel == LogLevelDebug {\n\t\tl.logMessage(format, args...)\n\t}\n}\n\n// Infof logs something\nfunc (l *defaultLogger) Infof(format string, args ...interface{}) {\n\tif l.logLevel >= LogLevelInfo {\n\t\tl.logMessage(format, args...)\n\t}\n}\n\n// Errorf logs something\nfunc (l *defaultLogger) Errorf(format string, args ...interface{}) {\n\tif l.logLevel >= LogLevelError {\n\t\tl.logMessage(format, args...)\n\t}\n}\n\nfunc (l *defaultLogger) logMessage(format string, args ...interface{}) {\n\tvar pre string\n\n\tif len(l.timeFormat) > 0 {\n\t\tpre = time.Now().Format(l.timeFormat) + \" \"\n\t}\n\tif len(l.prefix) > 0 {\n\t\tpre += l.prefix + \" \"\n\t}\n\tlog.Printf(pre+format, args...)\n}\n\nfunc (l *defaultLogger) WithPrefix(prefix string) Logger {\n\tif len(l.prefix) > 0 {\n\t\tprefix = l.prefix + \" \" + prefix\n\t}\n\treturn &defaultLogger{\n\t\tlogLevel:   l.logLevel,\n\t\ttimeFormat: l.timeFormat,\n\t\tprefix:     prefix,\n\t}\n}\n\n// Debug returns true if the log level is LogLevelDebug\nfunc (l *defaultLogger) Debug() bool {\n\treturn l.logLevel == LogLevelDebug\n}\n\nfunc init() {\n\tDefaultLogger = &defaultLogger{}\n\tDefaultLogger.SetLogLevel(readLoggingEnv())\n}\n\nfunc readLoggingEnv() LogLevel {\n\tswitch strings.ToLower(os.Getenv(logEnv)) {\n\tcase \"\":\n\t\treturn LogLevelNothing\n\tcase \"debug\":\n\t\treturn LogLevelDebug\n\tcase \"info\":\n\t\treturn LogLevelInfo\n\tcase \"error\":\n\t\treturn LogLevelError\n\tdefault:\n\t\tfmt.Fprintln(os.Stderr, \"invalid quic-go log level, see https://github.com/quic-go/quic-go/wiki/Logging\")\n\t\treturn LogLevelNothing\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/utils/rand.go",
    "content": "package utils\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/binary\"\n)\n\n// Rand is a wrapper around crypto/rand that adds some convenience functions known from math/rand.\ntype Rand struct {\n\tbuf [4]byte\n}\n\nfunc (r *Rand) Int31() int32 {\n\trand.Read(r.buf[:])\n\treturn int32(binary.BigEndian.Uint32(r.buf[:]) & ^uint32(1<<31))\n}\n\n// copied from the standard library math/rand implementation of Int63n\nfunc (r *Rand) Int31n(n int32) int32 {\n\tif n&(n-1) == 0 { // n is power of two, can mask\n\t\treturn r.Int31() & (n - 1)\n\t}\n\tmax := int32((1 << 31) - 1 - (1<<31)%uint32(n))\n\tv := r.Int31()\n\tfor v > max {\n\t\tv = r.Int31()\n\t}\n\treturn v % n\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/utils/ringbuffer/ringbuffer.go",
    "content": "package ringbuffer\n\n// A RingBuffer is a ring buffer.\n// It acts as a heap that doesn't cause any allocations.\ntype RingBuffer[T any] struct {\n\tring             []T\n\theadPos, tailPos int\n\tfull             bool\n}\n\n// Init preallocates a buffer with a certain size.\nfunc (r *RingBuffer[T]) Init(size int) {\n\tr.ring = make([]T, size)\n}\n\n// Len returns the number of elements in the ring buffer.\nfunc (r *RingBuffer[T]) Len() int {\n\tif r.full {\n\t\treturn len(r.ring)\n\t}\n\tif r.tailPos >= r.headPos {\n\t\treturn r.tailPos - r.headPos\n\t}\n\treturn r.tailPos - r.headPos + len(r.ring)\n}\n\n// Empty says if the ring buffer is empty.\nfunc (r *RingBuffer[T]) Empty() bool {\n\treturn !r.full && r.headPos == r.tailPos\n}\n\n// PushBack adds a new element.\n// If the ring buffer is full, its capacity is increased first.\nfunc (r *RingBuffer[T]) PushBack(t T) {\n\tif r.full || len(r.ring) == 0 {\n\t\tr.grow()\n\t}\n\tr.ring[r.tailPos] = t\n\tr.tailPos++\n\tif r.tailPos == len(r.ring) {\n\t\tr.tailPos = 0\n\t}\n\tif r.tailPos == r.headPos {\n\t\tr.full = true\n\t}\n}\n\n// PopFront returns the next element.\n// It must not be called when the buffer is empty, that means that\n// callers might need to check if there are elements in the buffer first.\nfunc (r *RingBuffer[T]) PopFront() T {\n\tif r.Empty() {\n\t\tpanic(\"github.com/quic-go/quic-go/internal/utils/ringbuffer: pop from an empty queue\")\n\t}\n\tr.full = false\n\tt := r.ring[r.headPos]\n\tr.ring[r.headPos] = *new(T)\n\tr.headPos++\n\tif r.headPos == len(r.ring) {\n\t\tr.headPos = 0\n\t}\n\treturn t\n}\n\n// PeekFront returns the next element.\n// It must not be called when the buffer is empty, that means that\n// callers might need to check if there are elements in the buffer first.\nfunc (r *RingBuffer[T]) PeekFront() T {\n\tif r.Empty() {\n\t\tpanic(\"github.com/quic-go/quic-go/internal/utils/ringbuffer: peek from an empty queue\")\n\t}\n\treturn r.ring[r.headPos]\n}\n\n// Grow the maximum size of the queue.\n// This method assume the queue is full.\nfunc (r *RingBuffer[T]) grow() {\n\toldRing := r.ring\n\tnewSize := len(oldRing) * 2\n\tif newSize == 0 {\n\t\tnewSize = 1\n\t}\n\tr.ring = make([]T, newSize)\n\theadLen := copy(r.ring, oldRing[r.headPos:])\n\tcopy(r.ring[headLen:], oldRing[:r.headPos])\n\tr.headPos, r.tailPos, r.full = 0, len(oldRing), false\n}\n\n// Clear removes all elements.\nfunc (r *RingBuffer[T]) Clear() {\n\tvar zeroValue T\n\tfor i := range r.ring {\n\t\tr.ring[i] = zeroValue\n\t}\n\tr.headPos, r.tailPos, r.full = 0, 0, false\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/utils/rtt_stats.go",
    "content": "package utils\n\nimport (\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\nconst (\n\trttAlpha      = 0.125\n\toneMinusAlpha = 1 - rttAlpha\n\trttBeta       = 0.25\n\toneMinusBeta  = 1 - rttBeta\n\t// The default RTT used before an RTT sample is taken.\n\tdefaultInitialRTT = 100 * time.Millisecond\n)\n\n// RTTStats provides round-trip statistics\ntype RTTStats struct {\n\thasMeasurement bool\n\n\tminRTT        time.Duration\n\tlatestRTT     time.Duration\n\tsmoothedRTT   time.Duration\n\tmeanDeviation time.Duration\n\n\tmaxAckDelay time.Duration\n}\n\n// MinRTT Returns the minRTT for the entire connection.\n// May return Zero if no valid updates have occurred.\nfunc (r *RTTStats) MinRTT() time.Duration { return r.minRTT }\n\n// LatestRTT returns the most recent rtt measurement.\n// May return Zero if no valid updates have occurred.\nfunc (r *RTTStats) LatestRTT() time.Duration { return r.latestRTT }\n\n// SmoothedRTT returns the smoothed RTT for the connection.\n// May return Zero if no valid updates have occurred.\nfunc (r *RTTStats) SmoothedRTT() time.Duration { return r.smoothedRTT }\n\n// MeanDeviation gets the mean deviation\nfunc (r *RTTStats) MeanDeviation() time.Duration { return r.meanDeviation }\n\n// MaxAckDelay gets the max_ack_delay advertised by the peer\nfunc (r *RTTStats) MaxAckDelay() time.Duration { return r.maxAckDelay }\n\n// PTO gets the probe timeout duration.\nfunc (r *RTTStats) PTO(includeMaxAckDelay bool) time.Duration {\n\tif r.SmoothedRTT() == 0 {\n\t\treturn 2 * defaultInitialRTT\n\t}\n\tpto := r.SmoothedRTT() + max(4*r.MeanDeviation(), protocol.TimerGranularity)\n\tif includeMaxAckDelay {\n\t\tpto += r.MaxAckDelay()\n\t}\n\treturn pto\n}\n\n// UpdateRTT updates the RTT based on a new sample.\nfunc (r *RTTStats) UpdateRTT(sendDelta, ackDelay time.Duration) {\n\tif sendDelta <= 0 {\n\t\treturn\n\t}\n\n\t// Update r.minRTT first. r.minRTT does not use an rttSample corrected for\n\t// ackDelay but the raw observed sendDelta, since poor clock granularity at\n\t// the client may cause a high ackDelay to result in underestimation of the\n\t// r.minRTT.\n\tif r.minRTT == 0 || r.minRTT > sendDelta {\n\t\tr.minRTT = sendDelta\n\t}\n\n\t// Correct for ackDelay if information received from the peer results in a\n\t// an RTT sample at least as large as minRTT. Otherwise, only use the\n\t// sendDelta.\n\tsample := sendDelta\n\tif sample-r.minRTT >= ackDelay {\n\t\tsample -= ackDelay\n\t}\n\tr.latestRTT = sample\n\t// First time call.\n\tif !r.hasMeasurement {\n\t\tr.hasMeasurement = true\n\t\tr.smoothedRTT = sample\n\t\tr.meanDeviation = sample / 2\n\t} else {\n\t\tr.meanDeviation = time.Duration(oneMinusBeta*float32(r.meanDeviation/time.Microsecond)+rttBeta*float32((r.smoothedRTT-sample).Abs()/time.Microsecond)) * time.Microsecond\n\t\tr.smoothedRTT = time.Duration((float32(r.smoothedRTT/time.Microsecond)*oneMinusAlpha)+(float32(sample/time.Microsecond)*rttAlpha)) * time.Microsecond\n\t}\n}\n\n// SetMaxAckDelay sets the max_ack_delay\nfunc (r *RTTStats) SetMaxAckDelay(mad time.Duration) {\n\tr.maxAckDelay = mad\n}\n\n// SetInitialRTT sets the initial RTT.\n// It is used during the 0-RTT handshake when restoring the RTT stats from the session state.\nfunc (r *RTTStats) SetInitialRTT(t time.Duration) {\n\t// On the server side, by the time we get to process the session ticket,\n\t// we might already have obtained an RTT measurement.\n\t// This can happen if we received the ClientHello in multiple pieces, and one of those pieces was lost.\n\t// Discard the restored value. A fresh measurement is always better.\n\tif r.hasMeasurement {\n\t\treturn\n\t}\n\tr.smoothedRTT = t\n\tr.latestRTT = t\n}\n\nfunc (r *RTTStats) ResetForPathMigration() {\n\tr.hasMeasurement = false\n\tr.minRTT = 0\n\tr.latestRTT = 0\n\tr.smoothedRTT = 0\n\tr.meanDeviation = 0\n\t// max_ack_delay remains valid\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/utils/timer.go",
    "content": "package utils\n\nimport (\n\t\"math\"\n\t\"time\"\n)\n\n// A Timer wrapper that behaves correctly when resetting\ntype Timer struct {\n\tt        *time.Timer\n\tread     bool\n\tdeadline time.Time\n}\n\n// NewTimer creates a new timer that is not set\nfunc NewTimer() *Timer {\n\treturn &Timer{t: time.NewTimer(time.Duration(math.MaxInt64))}\n}\n\n// Chan returns the channel of the wrapped timer\nfunc (t *Timer) Chan() <-chan time.Time {\n\treturn t.t.C\n}\n\n// Reset the timer, no matter whether the value was read or not\nfunc (t *Timer) Reset(deadline time.Time) {\n\tif deadline.Equal(t.deadline) && !t.read {\n\t\t// No need to reset the timer\n\t\treturn\n\t}\n\n\t// We need to drain the timer if the value from its channel was not read yet.\n\t// See https://groups.google.com/forum/#!topic/golang-dev/c9UUfASVPoU\n\tif !t.t.Stop() && !t.read {\n\t\t<-t.t.C\n\t}\n\tif !deadline.IsZero() {\n\t\tt.t.Reset(time.Until(deadline))\n\t}\n\n\tt.read = false\n\tt.deadline = deadline\n}\n\n// SetRead should be called after the value from the chan was read\nfunc (t *Timer) SetRead() {\n\tt.read = true\n}\n\nfunc (t *Timer) Deadline() time.Time {\n\treturn t.deadline\n}\n\n// Stop stops the timer\nfunc (t *Timer) Stop() {\n\tt.t.Stop()\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/ack_frame.go",
    "content": "package wire\n\nimport (\n\t\"errors\"\n\t\"math\"\n\t\"sort\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\nvar errInvalidAckRanges = errors.New(\"AckFrame: ACK frame contains invalid ACK ranges\")\n\n// An AckFrame is an ACK frame\ntype AckFrame struct {\n\tAckRanges []AckRange // has to be ordered. The highest ACK range goes first, the lowest ACK range goes last\n\tDelayTime time.Duration\n\n\tECT0, ECT1, ECNCE uint64\n}\n\n// parseAckFrame reads an ACK frame\nfunc parseAckFrame(frame *AckFrame, b []byte, typ uint64, ackDelayExponent uint8, _ protocol.Version) (int, error) {\n\tstartLen := len(b)\n\tecn := typ == ackECNFrameType\n\n\tla, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\tlargestAcked := protocol.PacketNumber(la)\n\tdelay, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\n\tdelayTime := time.Duration(delay*1<<ackDelayExponent) * time.Microsecond\n\tif delayTime < 0 {\n\t\t// If the delay time overflows, set it to the maximum encode-able value.\n\t\tdelayTime = time.Duration(math.MaxInt64)\n\t}\n\tframe.DelayTime = delayTime\n\n\tnumBlocks, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\n\t// read the first ACK range\n\tab, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\tackBlock := protocol.PacketNumber(ab)\n\tif ackBlock > largestAcked {\n\t\treturn 0, errors.New(\"invalid first ACK range\")\n\t}\n\tsmallest := largestAcked - ackBlock\n\tframe.AckRanges = append(frame.AckRanges, AckRange{Smallest: smallest, Largest: largestAcked})\n\n\t// read all the other ACK ranges\n\tfor i := uint64(0); i < numBlocks; i++ {\n\t\tg, l, err := quicvarint.Parse(b)\n\t\tif err != nil {\n\t\t\treturn 0, replaceUnexpectedEOF(err)\n\t\t}\n\t\tb = b[l:]\n\t\tgap := protocol.PacketNumber(g)\n\t\tif smallest < gap+2 {\n\t\t\treturn 0, errInvalidAckRanges\n\t\t}\n\t\tlargest := smallest - gap - 2\n\n\t\tab, l, err := quicvarint.Parse(b)\n\t\tif err != nil {\n\t\t\treturn 0, replaceUnexpectedEOF(err)\n\t\t}\n\t\tb = b[l:]\n\t\tackBlock := protocol.PacketNumber(ab)\n\n\t\tif ackBlock > largest {\n\t\t\treturn 0, errInvalidAckRanges\n\t\t}\n\t\tsmallest = largest - ackBlock\n\t\tframe.AckRanges = append(frame.AckRanges, AckRange{Smallest: smallest, Largest: largest})\n\t}\n\n\tif !frame.validateAckRanges() {\n\t\treturn 0, errInvalidAckRanges\n\t}\n\n\tif ecn {\n\t\tect0, l, err := quicvarint.Parse(b)\n\t\tif err != nil {\n\t\t\treturn 0, replaceUnexpectedEOF(err)\n\t\t}\n\t\tb = b[l:]\n\t\tframe.ECT0 = ect0\n\t\tect1, l, err := quicvarint.Parse(b)\n\t\tif err != nil {\n\t\t\treturn 0, replaceUnexpectedEOF(err)\n\t\t}\n\t\tb = b[l:]\n\t\tframe.ECT1 = ect1\n\t\tecnce, l, err := quicvarint.Parse(b)\n\t\tif err != nil {\n\t\t\treturn 0, replaceUnexpectedEOF(err)\n\t\t}\n\t\tb = b[l:]\n\t\tframe.ECNCE = ecnce\n\t}\n\n\treturn startLen - len(b), nil\n}\n\n// Append appends an ACK frame.\nfunc (f *AckFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\thasECN := f.ECT0 > 0 || f.ECT1 > 0 || f.ECNCE > 0\n\tif hasECN {\n\t\tb = append(b, ackECNFrameType)\n\t} else {\n\t\tb = append(b, ackFrameType)\n\t}\n\tb = quicvarint.Append(b, uint64(f.LargestAcked()))\n\tb = quicvarint.Append(b, encodeAckDelay(f.DelayTime))\n\n\tnumRanges := f.numEncodableAckRanges()\n\tb = quicvarint.Append(b, uint64(numRanges-1))\n\n\t// write the first range\n\t_, firstRange := f.encodeAckRange(0)\n\tb = quicvarint.Append(b, firstRange)\n\n\t// write all the other range\n\tfor i := 1; i < numRanges; i++ {\n\t\tgap, len := f.encodeAckRange(i)\n\t\tb = quicvarint.Append(b, gap)\n\t\tb = quicvarint.Append(b, len)\n\t}\n\n\tif hasECN {\n\t\tb = quicvarint.Append(b, f.ECT0)\n\t\tb = quicvarint.Append(b, f.ECT1)\n\t\tb = quicvarint.Append(b, f.ECNCE)\n\t}\n\treturn b, nil\n}\n\n// Length of a written frame\nfunc (f *AckFrame) Length(_ protocol.Version) protocol.ByteCount {\n\tlargestAcked := f.AckRanges[0].Largest\n\tnumRanges := f.numEncodableAckRanges()\n\n\tlength := 1 + quicvarint.Len(uint64(largestAcked)) + quicvarint.Len(encodeAckDelay(f.DelayTime))\n\n\tlength += quicvarint.Len(uint64(numRanges - 1))\n\tlowestInFirstRange := f.AckRanges[0].Smallest\n\tlength += quicvarint.Len(uint64(largestAcked - lowestInFirstRange))\n\n\tfor i := 1; i < numRanges; i++ {\n\t\tgap, len := f.encodeAckRange(i)\n\t\tlength += quicvarint.Len(gap)\n\t\tlength += quicvarint.Len(len)\n\t}\n\tif f.ECT0 > 0 || f.ECT1 > 0 || f.ECNCE > 0 {\n\t\tlength += quicvarint.Len(f.ECT0)\n\t\tlength += quicvarint.Len(f.ECT1)\n\t\tlength += quicvarint.Len(f.ECNCE)\n\t}\n\treturn protocol.ByteCount(length)\n}\n\n// gets the number of ACK ranges that can be encoded\n// such that the resulting frame is smaller than the maximum ACK frame size\nfunc (f *AckFrame) numEncodableAckRanges() int {\n\tlength := 1 + quicvarint.Len(uint64(f.LargestAcked())) + quicvarint.Len(encodeAckDelay(f.DelayTime))\n\tlength += 2 // assume that the number of ranges will consume 2 bytes\n\tfor i := 1; i < len(f.AckRanges); i++ {\n\t\tgap, len := f.encodeAckRange(i)\n\t\trangeLen := quicvarint.Len(gap) + quicvarint.Len(len)\n\t\tif protocol.ByteCount(length+rangeLen) > protocol.MaxAckFrameSize {\n\t\t\t// Writing range i would exceed the MaxAckFrameSize.\n\t\t\t// So encode one range less than that.\n\t\t\treturn i - 1\n\t\t}\n\t\tlength += rangeLen\n\t}\n\treturn len(f.AckRanges)\n}\n\nfunc (f *AckFrame) encodeAckRange(i int) (uint64 /* gap */, uint64 /* length */) {\n\tif i == 0 {\n\t\treturn 0, uint64(f.AckRanges[0].Largest - f.AckRanges[0].Smallest)\n\t}\n\treturn uint64(f.AckRanges[i-1].Smallest - f.AckRanges[i].Largest - 2),\n\t\tuint64(f.AckRanges[i].Largest - f.AckRanges[i].Smallest)\n}\n\n// HasMissingRanges returns if this frame reports any missing packets\nfunc (f *AckFrame) HasMissingRanges() bool {\n\treturn len(f.AckRanges) > 1\n}\n\nfunc (f *AckFrame) validateAckRanges() bool {\n\tif len(f.AckRanges) == 0 {\n\t\treturn false\n\t}\n\n\t// check the validity of every single ACK range\n\tfor _, ackRange := range f.AckRanges {\n\t\tif ackRange.Smallest > ackRange.Largest {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// check the consistency for ACK with multiple NACK ranges\n\tfor i, ackRange := range f.AckRanges {\n\t\tif i == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tlastAckRange := f.AckRanges[i-1]\n\t\tif lastAckRange.Smallest <= ackRange.Smallest {\n\t\t\treturn false\n\t\t}\n\t\tif lastAckRange.Smallest <= ackRange.Largest+1 {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\n// LargestAcked is the largest acked packet number\nfunc (f *AckFrame) LargestAcked() protocol.PacketNumber {\n\treturn f.AckRanges[0].Largest\n}\n\n// LowestAcked is the lowest acked packet number\nfunc (f *AckFrame) LowestAcked() protocol.PacketNumber {\n\treturn f.AckRanges[len(f.AckRanges)-1].Smallest\n}\n\n// AcksPacket determines if this ACK frame acks a certain packet number\nfunc (f *AckFrame) AcksPacket(p protocol.PacketNumber) bool {\n\tif p < f.LowestAcked() || p > f.LargestAcked() {\n\t\treturn false\n\t}\n\n\ti := sort.Search(len(f.AckRanges), func(i int) bool {\n\t\treturn p >= f.AckRanges[i].Smallest\n\t})\n\t// i will always be < len(f.AckRanges), since we checked above that p is not bigger than the largest acked\n\treturn p <= f.AckRanges[i].Largest\n}\n\nfunc (f *AckFrame) Reset() {\n\tf.DelayTime = 0\n\tf.ECT0 = 0\n\tf.ECT1 = 0\n\tf.ECNCE = 0\n\tfor _, r := range f.AckRanges {\n\t\tr.Largest = 0\n\t\tr.Smallest = 0\n\t}\n\tf.AckRanges = f.AckRanges[:0]\n}\n\nfunc encodeAckDelay(delay time.Duration) uint64 {\n\treturn uint64(delay.Nanoseconds() / (1000 * (1 << protocol.AckDelayExponent)))\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/ack_range.go",
    "content": "package wire\n\nimport \"github.com/quic-go/quic-go/internal/protocol\"\n\n// AckRange is an ACK range\ntype AckRange struct {\n\tSmallest protocol.PacketNumber\n\tLargest  protocol.PacketNumber\n}\n\n// Len returns the number of packets contained in this ACK range\nfunc (r AckRange) Len() protocol.PacketNumber {\n\treturn r.Largest - r.Smallest + 1\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/connection_close_frame.go",
    "content": "package wire\n\nimport (\n\t\"io\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// A ConnectionCloseFrame is a CONNECTION_CLOSE frame\ntype ConnectionCloseFrame struct {\n\tIsApplicationError bool\n\tErrorCode          uint64\n\tFrameType          uint64\n\tReasonPhrase       string\n}\n\nfunc parseConnectionCloseFrame(b []byte, typ uint64, _ protocol.Version) (*ConnectionCloseFrame, int, error) {\n\tstartLen := len(b)\n\tf := &ConnectionCloseFrame{IsApplicationError: typ == applicationCloseFrameType}\n\tec, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\tf.ErrorCode = ec\n\t// read the Frame Type, if this is not an application error\n\tif !f.IsApplicationError {\n\t\tft, l, err := quicvarint.Parse(b)\n\t\tif err != nil {\n\t\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t\t}\n\t\tb = b[l:]\n\t\tf.FrameType = ft\n\t}\n\tvar reasonPhraseLen uint64\n\treasonPhraseLen, l, err = quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\tif int(reasonPhraseLen) > len(b) {\n\t\treturn nil, 0, io.EOF\n\t}\n\n\treasonPhrase := make([]byte, reasonPhraseLen)\n\tcopy(reasonPhrase, b)\n\tf.ReasonPhrase = string(reasonPhrase)\n\treturn f, startLen - len(b) + int(reasonPhraseLen), nil\n}\n\n// Length of a written frame\nfunc (f *ConnectionCloseFrame) Length(protocol.Version) protocol.ByteCount {\n\tlength := 1 + protocol.ByteCount(quicvarint.Len(f.ErrorCode)+quicvarint.Len(uint64(len(f.ReasonPhrase)))) + protocol.ByteCount(len(f.ReasonPhrase))\n\tif !f.IsApplicationError {\n\t\tlength += protocol.ByteCount(quicvarint.Len(f.FrameType)) // for the frame type\n\t}\n\treturn length\n}\n\nfunc (f *ConnectionCloseFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\tif f.IsApplicationError {\n\t\tb = append(b, applicationCloseFrameType)\n\t} else {\n\t\tb = append(b, connectionCloseFrameType)\n\t}\n\n\tb = quicvarint.Append(b, f.ErrorCode)\n\tif !f.IsApplicationError {\n\t\tb = quicvarint.Append(b, f.FrameType)\n\t}\n\tb = quicvarint.Append(b, uint64(len(f.ReasonPhrase)))\n\tb = append(b, []byte(f.ReasonPhrase)...)\n\treturn b, nil\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/crypto_frame.go",
    "content": "package wire\n\nimport (\n\t\"io\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// A CryptoFrame is a CRYPTO frame\ntype CryptoFrame struct {\n\tOffset protocol.ByteCount\n\tData   []byte\n}\n\nfunc parseCryptoFrame(b []byte, _ protocol.Version) (*CryptoFrame, int, error) {\n\tstartLen := len(b)\n\tframe := &CryptoFrame{}\n\toffset, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\tframe.Offset = protocol.ByteCount(offset)\n\tdataLen, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\tif dataLen > uint64(len(b)) {\n\t\treturn nil, 0, io.EOF\n\t}\n\tif dataLen != 0 {\n\t\tframe.Data = make([]byte, dataLen)\n\t\tcopy(frame.Data, b)\n\t}\n\treturn frame, startLen - len(b) + int(dataLen), nil\n}\n\nfunc (f *CryptoFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\tb = append(b, cryptoFrameType)\n\tb = quicvarint.Append(b, uint64(f.Offset))\n\tb = quicvarint.Append(b, uint64(len(f.Data)))\n\tb = append(b, f.Data...)\n\treturn b, nil\n}\n\n// Length of a written frame\nfunc (f *CryptoFrame) Length(_ protocol.Version) protocol.ByteCount {\n\treturn protocol.ByteCount(1 + quicvarint.Len(uint64(f.Offset)) + quicvarint.Len(uint64(len(f.Data))) + len(f.Data))\n}\n\n// MaxDataLen returns the maximum data length\nfunc (f *CryptoFrame) MaxDataLen(maxSize protocol.ByteCount) protocol.ByteCount {\n\t// pretend that the data size will be 1 bytes\n\t// if it turns out that varint encoding the length will consume 2 bytes, we need to adjust the data length afterwards\n\theaderLen := protocol.ByteCount(1 + quicvarint.Len(uint64(f.Offset)) + 1)\n\tif headerLen > maxSize {\n\t\treturn 0\n\t}\n\tmaxDataLen := maxSize - headerLen\n\tif quicvarint.Len(uint64(maxDataLen)) != 1 {\n\t\tmaxDataLen--\n\t}\n\treturn maxDataLen\n}\n\n// MaybeSplitOffFrame splits a frame such that it is not bigger than n bytes.\n// It returns if the frame was actually split.\n// The frame might not be split if:\n// * the size is large enough to fit the whole frame\n// * the size is too small to fit even a 1-byte frame. In that case, the frame returned is nil.\nfunc (f *CryptoFrame) MaybeSplitOffFrame(maxSize protocol.ByteCount, version protocol.Version) (*CryptoFrame, bool /* was splitting required */) {\n\tif f.Length(version) <= maxSize {\n\t\treturn nil, false\n\t}\n\n\tn := f.MaxDataLen(maxSize)\n\tif n == 0 {\n\t\treturn nil, true\n\t}\n\n\tnewLen := protocol.ByteCount(len(f.Data)) - n\n\n\tnew := &CryptoFrame{}\n\tnew.Offset = f.Offset\n\tnew.Data = make([]byte, newLen)\n\n\t// swap the data slices\n\tnew.Data, f.Data = f.Data, new.Data\n\n\tcopy(f.Data, new.Data[n:])\n\tnew.Data = new.Data[:n]\n\tf.Offset += n\n\n\treturn new, true\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/data_blocked_frame.go",
    "content": "package wire\n\nimport (\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// A DataBlockedFrame is a DATA_BLOCKED frame\ntype DataBlockedFrame struct {\n\tMaximumData protocol.ByteCount\n}\n\nfunc parseDataBlockedFrame(b []byte, _ protocol.Version) (*DataBlockedFrame, int, error) {\n\toffset, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\treturn &DataBlockedFrame{MaximumData: protocol.ByteCount(offset)}, l, nil\n}\n\nfunc (f *DataBlockedFrame) Append(b []byte, version protocol.Version) ([]byte, error) {\n\tb = append(b, dataBlockedFrameType)\n\treturn quicvarint.Append(b, uint64(f.MaximumData)), nil\n}\n\n// Length of a written frame\nfunc (f *DataBlockedFrame) Length(version protocol.Version) protocol.ByteCount {\n\treturn 1 + protocol.ByteCount(quicvarint.Len(uint64(f.MaximumData)))\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/datagram_frame.go",
    "content": "package wire\n\nimport (\n\t\"io\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// MaxDatagramSize is the maximum size of a DATAGRAM frame (RFC 9221).\n// By setting it to a large value, we allow all datagrams that fit into a QUIC packet.\n// The value is chosen such that it can still be encoded as a 2 byte varint.\n// This is a var and not a const so it can be set in tests.\nvar MaxDatagramSize protocol.ByteCount = 16383\n\n// A DatagramFrame is a DATAGRAM frame\ntype DatagramFrame struct {\n\tDataLenPresent bool\n\tData           []byte\n}\n\nfunc parseDatagramFrame(b []byte, typ uint64, _ protocol.Version) (*DatagramFrame, int, error) {\n\tstartLen := len(b)\n\tf := &DatagramFrame{}\n\tf.DataLenPresent = typ&0x1 > 0\n\n\tvar length uint64\n\tif f.DataLenPresent {\n\t\tvar err error\n\t\tvar l int\n\t\tlength, l, err = quicvarint.Parse(b)\n\t\tif err != nil {\n\t\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t\t}\n\t\tb = b[l:]\n\t\tif length > uint64(len(b)) {\n\t\t\treturn nil, 0, io.EOF\n\t\t}\n\t} else {\n\t\tlength = uint64(len(b))\n\t}\n\tf.Data = make([]byte, length)\n\tcopy(f.Data, b)\n\treturn f, startLen - len(b) + int(length), nil\n}\n\nfunc (f *DatagramFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\ttyp := uint8(0x30)\n\tif f.DataLenPresent {\n\t\ttyp ^= 0b1\n\t}\n\tb = append(b, typ)\n\tif f.DataLenPresent {\n\t\tb = quicvarint.Append(b, uint64(len(f.Data)))\n\t}\n\tb = append(b, f.Data...)\n\treturn b, nil\n}\n\n// MaxDataLen returns the maximum data length\nfunc (f *DatagramFrame) MaxDataLen(maxSize protocol.ByteCount, version protocol.Version) protocol.ByteCount {\n\theaderLen := protocol.ByteCount(1)\n\tif f.DataLenPresent {\n\t\t// pretend that the data size will be 1 bytes\n\t\t// if it turns out that varint encoding the length will consume 2 bytes, we need to adjust the data length afterwards\n\t\theaderLen++\n\t}\n\tif headerLen > maxSize {\n\t\treturn 0\n\t}\n\tmaxDataLen := maxSize - headerLen\n\tif f.DataLenPresent && quicvarint.Len(uint64(maxDataLen)) != 1 {\n\t\tmaxDataLen--\n\t}\n\treturn maxDataLen\n}\n\n// Length of a written frame\nfunc (f *DatagramFrame) Length(_ protocol.Version) protocol.ByteCount {\n\tlength := 1 + protocol.ByteCount(len(f.Data))\n\tif f.DataLenPresent {\n\t\tlength += protocol.ByteCount(quicvarint.Len(uint64(len(f.Data))))\n\t}\n\treturn length\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/extended_header.go",
    "content": "package wire\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// ErrInvalidReservedBits is returned when the reserved bits are incorrect.\n// When this error is returned, parsing continues, and an ExtendedHeader is returned.\n// This is necessary because we need to decrypt the packet in that case,\n// in order to avoid a timing side-channel.\nvar ErrInvalidReservedBits = errors.New(\"invalid reserved bits\")\n\n// ExtendedHeader is the header of a QUIC packet.\ntype ExtendedHeader struct {\n\tHeader\n\n\ttypeByte byte\n\n\tKeyPhase protocol.KeyPhaseBit\n\n\tPacketNumberLen protocol.PacketNumberLen\n\tPacketNumber    protocol.PacketNumber\n\n\tparsedLen protocol.ByteCount\n}\n\nfunc (h *ExtendedHeader) parse(data []byte) (bool /* reserved bits valid */, error) {\n\t// read the (now unencrypted) first byte\n\th.typeByte = data[0]\n\th.PacketNumberLen = protocol.PacketNumberLen(h.typeByte&0x3) + 1\n\tif protocol.ByteCount(len(data)) < h.Header.ParsedLen()+protocol.ByteCount(h.PacketNumberLen) {\n\t\treturn false, io.EOF\n\t}\n\n\tpn, err := readPacketNumber(data[h.Header.ParsedLen():], h.PacketNumberLen)\n\tif err != nil {\n\t\treturn true, nil\n\t}\n\th.PacketNumber = pn\n\treservedBitsValid := h.typeByte&0xc == 0\n\n\th.parsedLen = h.Header.ParsedLen() + protocol.ByteCount(h.PacketNumberLen)\n\treturn reservedBitsValid, err\n}\n\n// Append appends the Header.\nfunc (h *ExtendedHeader) Append(b []byte, v protocol.Version) ([]byte, error) {\n\tif h.DestConnectionID.Len() > protocol.MaxConnIDLen {\n\t\treturn nil, fmt.Errorf(\"invalid connection ID length: %d bytes\", h.DestConnectionID.Len())\n\t}\n\tif h.SrcConnectionID.Len() > protocol.MaxConnIDLen {\n\t\treturn nil, fmt.Errorf(\"invalid connection ID length: %d bytes\", h.SrcConnectionID.Len())\n\t}\n\n\tvar packetType uint8\n\tif v == protocol.Version2 {\n\t\t//nolint:exhaustive\n\t\tswitch h.Type {\n\t\tcase protocol.PacketTypeInitial:\n\t\t\tpacketType = 0b01\n\t\tcase protocol.PacketType0RTT:\n\t\t\tpacketType = 0b10\n\t\tcase protocol.PacketTypeHandshake:\n\t\t\tpacketType = 0b11\n\t\tcase protocol.PacketTypeRetry:\n\t\t\tpacketType = 0b00\n\t\t}\n\t} else {\n\t\t//nolint:exhaustive\n\t\tswitch h.Type {\n\t\tcase protocol.PacketTypeInitial:\n\t\t\tpacketType = 0b00\n\t\tcase protocol.PacketType0RTT:\n\t\t\tpacketType = 0b01\n\t\tcase protocol.PacketTypeHandshake:\n\t\t\tpacketType = 0b10\n\t\tcase protocol.PacketTypeRetry:\n\t\t\tpacketType = 0b11\n\t\t}\n\t}\n\tfirstByte := 0xc0 | packetType<<4\n\tif h.Type != protocol.PacketTypeRetry {\n\t\t// Retry packets don't have a packet number\n\t\tfirstByte |= uint8(h.PacketNumberLen - 1)\n\t}\n\n\tb = append(b, firstByte)\n\tb = append(b, make([]byte, 4)...)\n\tbinary.BigEndian.PutUint32(b[len(b)-4:], uint32(h.Version))\n\tb = append(b, uint8(h.DestConnectionID.Len()))\n\tb = append(b, h.DestConnectionID.Bytes()...)\n\tb = append(b, uint8(h.SrcConnectionID.Len()))\n\tb = append(b, h.SrcConnectionID.Bytes()...)\n\n\t//nolint:exhaustive\n\tswitch h.Type {\n\tcase protocol.PacketTypeRetry:\n\t\tb = append(b, h.Token...)\n\t\treturn b, nil\n\tcase protocol.PacketTypeInitial:\n\t\tb = quicvarint.Append(b, uint64(len(h.Token)))\n\t\tb = append(b, h.Token...)\n\t}\n\tb = quicvarint.AppendWithLen(b, uint64(h.Length), 2)\n\treturn appendPacketNumber(b, h.PacketNumber, h.PacketNumberLen)\n}\n\n// ParsedLen returns the number of bytes that were consumed when parsing the header\nfunc (h *ExtendedHeader) ParsedLen() protocol.ByteCount {\n\treturn h.parsedLen\n}\n\n// GetLength determines the length of the Header.\nfunc (h *ExtendedHeader) GetLength(_ protocol.Version) protocol.ByteCount {\n\tlength := 1 /* type byte */ + 4 /* version */ + 1 /* dest conn ID len */ + protocol.ByteCount(h.DestConnectionID.Len()) + 1 /* src conn ID len */ + protocol.ByteCount(h.SrcConnectionID.Len()) + protocol.ByteCount(h.PacketNumberLen) + 2 /* length */\n\tif h.Type == protocol.PacketTypeInitial {\n\t\tlength += protocol.ByteCount(quicvarint.Len(uint64(len(h.Token))) + len(h.Token))\n\t}\n\treturn length\n}\n\n// Log logs the Header\nfunc (h *ExtendedHeader) Log(logger utils.Logger) {\n\tvar token string\n\tif h.Type == protocol.PacketTypeInitial || h.Type == protocol.PacketTypeRetry {\n\t\tif len(h.Token) == 0 {\n\t\t\ttoken = \"Token: (empty), \"\n\t\t} else {\n\t\t\ttoken = fmt.Sprintf(\"Token: %#x, \", h.Token)\n\t\t}\n\t\tif h.Type == protocol.PacketTypeRetry {\n\t\t\tlogger.Debugf(\"\\tLong Header{Type: %s, DestConnectionID: %s, SrcConnectionID: %s, %sVersion: %s}\", h.Type, h.DestConnectionID, h.SrcConnectionID, token, h.Version)\n\t\t\treturn\n\t\t}\n\t}\n\tlogger.Debugf(\"\\tLong Header{Type: %s, DestConnectionID: %s, SrcConnectionID: %s, %sPacketNumber: %d, PacketNumberLen: %d, Length: %d, Version: %s}\", h.Type, h.DestConnectionID, h.SrcConnectionID, token, h.PacketNumber, h.PacketNumberLen, h.Length, h.Version)\n}\n\nfunc appendPacketNumber(b []byte, pn protocol.PacketNumber, pnLen protocol.PacketNumberLen) ([]byte, error) {\n\tswitch pnLen {\n\tcase protocol.PacketNumberLen1:\n\t\tb = append(b, uint8(pn))\n\tcase protocol.PacketNumberLen2:\n\t\tbuf := make([]byte, 2)\n\t\tbinary.BigEndian.PutUint16(buf, uint16(pn))\n\t\tb = append(b, buf...)\n\tcase protocol.PacketNumberLen3:\n\t\tbuf := make([]byte, 4)\n\t\tbinary.BigEndian.PutUint32(buf, uint32(pn))\n\t\tb = append(b, buf[1:]...)\n\tcase protocol.PacketNumberLen4:\n\t\tbuf := make([]byte, 4)\n\t\tbinary.BigEndian.PutUint32(buf, uint32(pn))\n\t\tb = append(b, buf...)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"invalid packet number length: %d\", pnLen)\n\t}\n\treturn b, nil\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/frame.go",
    "content": "package wire\n\nimport (\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\n// A Frame in QUIC\ntype Frame interface {\n\tAppend(b []byte, version protocol.Version) ([]byte, error)\n\tLength(version protocol.Version) protocol.ByteCount\n}\n\n// IsProbingFrame returns true if the frame is a probing frame.\n// See section 9.1 of RFC 9000.\nfunc IsProbingFrame(f Frame) bool {\n\tswitch f.(type) {\n\tcase *PathChallengeFrame, *PathResponseFrame, *NewConnectionIDFrame:\n\t\treturn true\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/frame_parser.go",
    "content": "package wire\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\nconst (\n\tpingFrameType               = 0x1\n\tackFrameType                = 0x2\n\tackECNFrameType             = 0x3\n\tresetStreamFrameType        = 0x4\n\tstopSendingFrameType        = 0x5\n\tcryptoFrameType             = 0x6\n\tnewTokenFrameType           = 0x7\n\tmaxDataFrameType            = 0x10\n\tmaxStreamDataFrameType      = 0x11\n\tbidiMaxStreamsFrameType     = 0x12\n\tuniMaxStreamsFrameType      = 0x13\n\tdataBlockedFrameType        = 0x14\n\tstreamDataBlockedFrameType  = 0x15\n\tbidiStreamBlockedFrameType  = 0x16\n\tuniStreamBlockedFrameType   = 0x17\n\tnewConnectionIDFrameType    = 0x18\n\tretireConnectionIDFrameType = 0x19\n\tpathChallengeFrameType      = 0x1a\n\tpathResponseFrameType       = 0x1b\n\tconnectionCloseFrameType    = 0x1c\n\tapplicationCloseFrameType   = 0x1d\n\thandshakeDoneFrameType      = 0x1e\n)\n\n// The FrameParser parses QUIC frames, one by one.\ntype FrameParser struct {\n\tackDelayExponent  uint8\n\tsupportsDatagrams bool\n\n\t// To avoid allocating when parsing, keep a single ACK frame struct.\n\t// It is used over and over again.\n\tackFrame *AckFrame\n}\n\n// NewFrameParser creates a new frame parser.\nfunc NewFrameParser(supportsDatagrams bool) *FrameParser {\n\treturn &FrameParser{\n\t\tsupportsDatagrams: supportsDatagrams,\n\t\tackFrame:          &AckFrame{},\n\t}\n}\n\n// ParseNext parses the next frame.\n// It skips PADDING frames.\nfunc (p *FrameParser) ParseNext(data []byte, encLevel protocol.EncryptionLevel, v protocol.Version) (int, Frame, error) {\n\tframe, l, err := p.parseNext(data, encLevel, v)\n\treturn l, frame, err\n}\n\nfunc (p *FrameParser) parseNext(b []byte, encLevel protocol.EncryptionLevel, v protocol.Version) (Frame, int, error) {\n\tvar parsed int\n\tfor len(b) != 0 {\n\t\ttyp, l, err := quicvarint.Parse(b)\n\t\tparsed += l\n\t\tif err != nil {\n\t\t\treturn nil, parsed, &qerr.TransportError{\n\t\t\t\tErrorCode:    qerr.FrameEncodingError,\n\t\t\t\tErrorMessage: err.Error(),\n\t\t\t}\n\t\t}\n\t\tb = b[l:]\n\t\tif typ == 0x0 { // skip PADDING frames\n\t\t\tcontinue\n\t\t}\n\n\t\tf, l, err := p.parseFrame(b, typ, encLevel, v)\n\t\tparsed += l\n\t\tif err != nil {\n\t\t\treturn nil, parsed, &qerr.TransportError{\n\t\t\t\tFrameType:    typ,\n\t\t\t\tErrorCode:    qerr.FrameEncodingError,\n\t\t\t\tErrorMessage: err.Error(),\n\t\t\t}\n\t\t}\n\t\treturn f, parsed, nil\n\t}\n\treturn nil, parsed, nil\n}\n\nfunc (p *FrameParser) parseFrame(b []byte, typ uint64, encLevel protocol.EncryptionLevel, v protocol.Version) (Frame, int, error) {\n\tvar frame Frame\n\tvar err error\n\tvar l int\n\tif typ&0xf8 == 0x8 {\n\t\tframe, l, err = parseStreamFrame(b, typ, v)\n\t} else {\n\t\tswitch typ {\n\t\tcase pingFrameType:\n\t\t\tframe = &PingFrame{}\n\t\tcase ackFrameType, ackECNFrameType:\n\t\t\tackDelayExponent := p.ackDelayExponent\n\t\t\tif encLevel != protocol.Encryption1RTT {\n\t\t\t\tackDelayExponent = protocol.DefaultAckDelayExponent\n\t\t\t}\n\t\t\tp.ackFrame.Reset()\n\t\t\tl, err = parseAckFrame(p.ackFrame, b, typ, ackDelayExponent, v)\n\t\t\tframe = p.ackFrame\n\t\tcase resetStreamFrameType:\n\t\t\tframe, l, err = parseResetStreamFrame(b, v)\n\t\tcase stopSendingFrameType:\n\t\t\tframe, l, err = parseStopSendingFrame(b, v)\n\t\tcase cryptoFrameType:\n\t\t\tframe, l, err = parseCryptoFrame(b, v)\n\t\tcase newTokenFrameType:\n\t\t\tframe, l, err = parseNewTokenFrame(b, v)\n\t\tcase maxDataFrameType:\n\t\t\tframe, l, err = parseMaxDataFrame(b, v)\n\t\tcase maxStreamDataFrameType:\n\t\t\tframe, l, err = parseMaxStreamDataFrame(b, v)\n\t\tcase bidiMaxStreamsFrameType, uniMaxStreamsFrameType:\n\t\t\tframe, l, err = parseMaxStreamsFrame(b, typ, v)\n\t\tcase dataBlockedFrameType:\n\t\t\tframe, l, err = parseDataBlockedFrame(b, v)\n\t\tcase streamDataBlockedFrameType:\n\t\t\tframe, l, err = parseStreamDataBlockedFrame(b, v)\n\t\tcase bidiStreamBlockedFrameType, uniStreamBlockedFrameType:\n\t\t\tframe, l, err = parseStreamsBlockedFrame(b, typ, v)\n\t\tcase newConnectionIDFrameType:\n\t\t\tframe, l, err = parseNewConnectionIDFrame(b, v)\n\t\tcase retireConnectionIDFrameType:\n\t\t\tframe, l, err = parseRetireConnectionIDFrame(b, v)\n\t\tcase pathChallengeFrameType:\n\t\t\tframe, l, err = parsePathChallengeFrame(b, v)\n\t\tcase pathResponseFrameType:\n\t\t\tframe, l, err = parsePathResponseFrame(b, v)\n\t\tcase connectionCloseFrameType, applicationCloseFrameType:\n\t\t\tframe, l, err = parseConnectionCloseFrame(b, typ, v)\n\t\tcase handshakeDoneFrameType:\n\t\t\tframe = &HandshakeDoneFrame{}\n\t\tcase 0x30, 0x31:\n\t\t\tif p.supportsDatagrams {\n\t\t\t\tframe, l, err = parseDatagramFrame(b, typ, v)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tfallthrough\n\t\tdefault:\n\t\t\terr = errors.New(\"unknown frame type\")\n\t\t}\n\t}\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\tif !p.isAllowedAtEncLevel(frame, encLevel) {\n\t\treturn nil, l, fmt.Errorf(\"%s not allowed at encryption level %s\", reflect.TypeOf(frame).Elem().Name(), encLevel)\n\t}\n\treturn frame, l, nil\n}\n\nfunc (p *FrameParser) isAllowedAtEncLevel(f Frame, encLevel protocol.EncryptionLevel) bool {\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial, protocol.EncryptionHandshake:\n\t\tswitch f.(type) {\n\t\tcase *CryptoFrame, *AckFrame, *ConnectionCloseFrame, *PingFrame:\n\t\t\treturn true\n\t\tdefault:\n\t\t\treturn false\n\t\t}\n\tcase protocol.Encryption0RTT:\n\t\tswitch f.(type) {\n\t\tcase *CryptoFrame, *AckFrame, *ConnectionCloseFrame, *NewTokenFrame, *PathResponseFrame, *RetireConnectionIDFrame:\n\t\t\treturn false\n\t\tdefault:\n\t\t\treturn true\n\t\t}\n\tcase protocol.Encryption1RTT:\n\t\treturn true\n\tdefault:\n\t\tpanic(\"unknown encryption level\")\n\t}\n}\n\n// SetAckDelayExponent sets the acknowledgment delay exponent (sent in the transport parameters).\n// This value is used to scale the ACK Delay field in the ACK frame.\nfunc (p *FrameParser) SetAckDelayExponent(exp uint8) {\n\tp.ackDelayExponent = exp\n}\n\nfunc replaceUnexpectedEOF(e error) error {\n\tif e == io.ErrUnexpectedEOF {\n\t\treturn io.EOF\n\t}\n\treturn e\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/handshake_done_frame.go",
    "content": "package wire\n\nimport (\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\n// A HandshakeDoneFrame is a HANDSHAKE_DONE frame\ntype HandshakeDoneFrame struct{}\n\nfunc (f *HandshakeDoneFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\treturn append(b, handshakeDoneFrameType), nil\n}\n\n// Length of a written frame\nfunc (f *HandshakeDoneFrame) Length(_ protocol.Version) protocol.ByteCount {\n\treturn 1\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/header.go",
    "content": "package wire\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// ParseConnectionID parses the destination connection ID of a packet.\nfunc ParseConnectionID(data []byte, shortHeaderConnIDLen int) (protocol.ConnectionID, error) {\n\tif len(data) == 0 {\n\t\treturn protocol.ConnectionID{}, io.EOF\n\t}\n\tif !IsLongHeaderPacket(data[0]) {\n\t\tif len(data) < shortHeaderConnIDLen+1 {\n\t\t\treturn protocol.ConnectionID{}, io.EOF\n\t\t}\n\t\treturn protocol.ParseConnectionID(data[1 : 1+shortHeaderConnIDLen]), nil\n\t}\n\tif len(data) < 6 {\n\t\treturn protocol.ConnectionID{}, io.EOF\n\t}\n\tdestConnIDLen := int(data[5])\n\tif destConnIDLen > protocol.MaxConnIDLen {\n\t\treturn protocol.ConnectionID{}, protocol.ErrInvalidConnectionIDLen\n\t}\n\tif len(data) < 6+destConnIDLen {\n\t\treturn protocol.ConnectionID{}, io.EOF\n\t}\n\treturn protocol.ParseConnectionID(data[6 : 6+destConnIDLen]), nil\n}\n\n// ParseArbitraryLenConnectionIDs parses the most general form of a Long Header packet,\n// using only the version-independent packet format as described in Section 5.1 of RFC 8999:\n// https://datatracker.ietf.org/doc/html/rfc8999#section-5.1.\n// This function should only be called on Long Header packets for which we don't support the version.\nfunc ParseArbitraryLenConnectionIDs(data []byte) (bytesParsed int, dest, src protocol.ArbitraryLenConnectionID, _ error) {\n\tstartLen := len(data)\n\tif len(data) < 6 {\n\t\treturn 0, nil, nil, io.EOF\n\t}\n\tdata = data[5:] // skip first byte and version field\n\tdestConnIDLen := data[0]\n\tdata = data[1:]\n\tdestConnID := make(protocol.ArbitraryLenConnectionID, destConnIDLen)\n\tif len(data) < int(destConnIDLen)+1 {\n\t\treturn 0, nil, nil, io.EOF\n\t}\n\tcopy(destConnID, data)\n\tdata = data[destConnIDLen:]\n\tsrcConnIDLen := data[0]\n\tdata = data[1:]\n\tif len(data) < int(srcConnIDLen) {\n\t\treturn 0, nil, nil, io.EOF\n\t}\n\tsrcConnID := make(protocol.ArbitraryLenConnectionID, srcConnIDLen)\n\tcopy(srcConnID, data)\n\treturn startLen - len(data) + int(srcConnIDLen), destConnID, srcConnID, nil\n}\n\nfunc IsPotentialQUICPacket(firstByte byte) bool {\n\treturn firstByte&0x40 > 0\n}\n\n// IsLongHeaderPacket says if this is a Long Header packet\nfunc IsLongHeaderPacket(firstByte byte) bool {\n\treturn firstByte&0x80 > 0\n}\n\n// ParseVersion parses the QUIC version.\n// It should only be called for Long Header packets (Short Header packets don't contain a version number).\nfunc ParseVersion(data []byte) (protocol.Version, error) {\n\tif len(data) < 5 {\n\t\treturn 0, io.EOF\n\t}\n\treturn protocol.Version(binary.BigEndian.Uint32(data[1:5])), nil\n}\n\n// IsVersionNegotiationPacket says if this is a version negotiation packet\nfunc IsVersionNegotiationPacket(b []byte) bool {\n\tif len(b) < 5 {\n\t\treturn false\n\t}\n\treturn IsLongHeaderPacket(b[0]) && b[1] == 0 && b[2] == 0 && b[3] == 0 && b[4] == 0\n}\n\n// Is0RTTPacket says if this is a 0-RTT packet.\n// A packet sent with a version we don't understand can never be a 0-RTT packet.\nfunc Is0RTTPacket(b []byte) bool {\n\tif len(b) < 5 {\n\t\treturn false\n\t}\n\tif !IsLongHeaderPacket(b[0]) {\n\t\treturn false\n\t}\n\tversion := protocol.Version(binary.BigEndian.Uint32(b[1:5]))\n\t//nolint:exhaustive // We only need to test QUIC versions that we support.\n\tswitch version {\n\tcase protocol.Version1:\n\t\treturn b[0]>>4&0b11 == 0b01\n\tcase protocol.Version2:\n\t\treturn b[0]>>4&0b11 == 0b10\n\tdefault:\n\t\treturn false\n\t}\n}\n\nvar ErrUnsupportedVersion = errors.New(\"unsupported version\")\n\n// The Header is the version independent part of the header\ntype Header struct {\n\ttypeByte byte\n\tType     protocol.PacketType\n\n\tVersion          protocol.Version\n\tSrcConnectionID  protocol.ConnectionID\n\tDestConnectionID protocol.ConnectionID\n\n\tLength protocol.ByteCount\n\n\tToken []byte\n\n\tparsedLen protocol.ByteCount // how many bytes were read while parsing this header\n}\n\n// ParsePacket parses a long header packet.\n// The packet is cut according to the length field.\n// If we understand the version, the packet is parsed up unto the packet number.\n// Otherwise, only the invariant part of the header is parsed.\nfunc ParsePacket(data []byte) (*Header, []byte, []byte, error) {\n\tif len(data) == 0 || !IsLongHeaderPacket(data[0]) {\n\t\treturn nil, nil, nil, errors.New(\"not a long header packet\")\n\t}\n\thdr, err := parseHeader(data)\n\tif err != nil {\n\t\tif errors.Is(err, ErrUnsupportedVersion) {\n\t\t\treturn hdr, nil, nil, err\n\t\t}\n\t\treturn nil, nil, nil, err\n\t}\n\tif protocol.ByteCount(len(data)) < hdr.ParsedLen()+hdr.Length {\n\t\treturn nil, nil, nil, fmt.Errorf(\"packet length (%d bytes) is smaller than the expected length (%d bytes)\", len(data)-int(hdr.ParsedLen()), hdr.Length)\n\t}\n\tpacketLen := int(hdr.ParsedLen() + hdr.Length)\n\treturn hdr, data[:packetLen], data[packetLen:], nil\n}\n\n// ParseHeader parses the header:\n// * if we understand the version: up to the packet number\n// * if not, only the invariant part of the header\nfunc parseHeader(b []byte) (*Header, error) {\n\tif len(b) == 0 {\n\t\treturn nil, io.EOF\n\t}\n\ttypeByte := b[0]\n\n\th := &Header{typeByte: typeByte}\n\tl, err := h.parseLongHeader(b[1:])\n\th.parsedLen = protocol.ByteCount(l) + 1\n\treturn h, err\n}\n\nfunc (h *Header) parseLongHeader(b []byte) (int, error) {\n\tstartLen := len(b)\n\tif len(b) < 5 {\n\t\treturn 0, io.EOF\n\t}\n\th.Version = protocol.Version(binary.BigEndian.Uint32(b[:4]))\n\tif h.Version != 0 && h.typeByte&0x40 == 0 {\n\t\treturn startLen - len(b), errors.New(\"not a QUIC packet\")\n\t}\n\tdestConnIDLen := int(b[4])\n\tif destConnIDLen > protocol.MaxConnIDLen {\n\t\treturn startLen - len(b), protocol.ErrInvalidConnectionIDLen\n\t}\n\tb = b[5:]\n\tif len(b) < destConnIDLen+1 {\n\t\treturn startLen - len(b), io.EOF\n\t}\n\th.DestConnectionID = protocol.ParseConnectionID(b[:destConnIDLen])\n\tsrcConnIDLen := int(b[destConnIDLen])\n\tif srcConnIDLen > protocol.MaxConnIDLen {\n\t\treturn startLen - len(b), protocol.ErrInvalidConnectionIDLen\n\t}\n\tb = b[destConnIDLen+1:]\n\tif len(b) < srcConnIDLen {\n\t\treturn startLen - len(b), io.EOF\n\t}\n\th.SrcConnectionID = protocol.ParseConnectionID(b[:srcConnIDLen])\n\tb = b[srcConnIDLen:]\n\tif h.Version == 0 { // version negotiation packet\n\t\treturn startLen - len(b), nil\n\t}\n\t// If we don't understand the version, we have no idea how to interpret the rest of the bytes\n\tif !protocol.IsSupportedVersion(protocol.SupportedVersions, h.Version) {\n\t\treturn startLen - len(b), ErrUnsupportedVersion\n\t}\n\n\tif h.Version == protocol.Version2 {\n\t\tswitch h.typeByte >> 4 & 0b11 {\n\t\tcase 0b00:\n\t\t\th.Type = protocol.PacketTypeRetry\n\t\tcase 0b01:\n\t\t\th.Type = protocol.PacketTypeInitial\n\t\tcase 0b10:\n\t\t\th.Type = protocol.PacketType0RTT\n\t\tcase 0b11:\n\t\t\th.Type = protocol.PacketTypeHandshake\n\t\t}\n\t} else {\n\t\tswitch h.typeByte >> 4 & 0b11 {\n\t\tcase 0b00:\n\t\t\th.Type = protocol.PacketTypeInitial\n\t\tcase 0b01:\n\t\t\th.Type = protocol.PacketType0RTT\n\t\tcase 0b10:\n\t\t\th.Type = protocol.PacketTypeHandshake\n\t\tcase 0b11:\n\t\t\th.Type = protocol.PacketTypeRetry\n\t\t}\n\t}\n\n\tif h.Type == protocol.PacketTypeRetry {\n\t\ttokenLen := len(b) - 16\n\t\tif tokenLen <= 0 {\n\t\t\treturn startLen - len(b), io.EOF\n\t\t}\n\t\th.Token = make([]byte, tokenLen)\n\t\tcopy(h.Token, b[:tokenLen])\n\t\treturn startLen - len(b) + tokenLen + 16, nil\n\t}\n\n\tif h.Type == protocol.PacketTypeInitial {\n\t\ttokenLen, n, err := quicvarint.Parse(b)\n\t\tif err != nil {\n\t\t\treturn startLen - len(b), err\n\t\t}\n\t\tb = b[n:]\n\t\tif tokenLen > uint64(len(b)) {\n\t\t\treturn startLen - len(b), io.EOF\n\t\t}\n\t\th.Token = make([]byte, tokenLen)\n\t\tcopy(h.Token, b[:tokenLen])\n\t\tb = b[tokenLen:]\n\t}\n\n\tpl, n, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\th.Length = protocol.ByteCount(pl)\n\treturn startLen - len(b) + n, nil\n}\n\n// ParsedLen returns the number of bytes that were consumed when parsing the header\nfunc (h *Header) ParsedLen() protocol.ByteCount {\n\treturn h.parsedLen\n}\n\n// ParseExtended parses the version dependent part of the header.\n// The Reader has to be set such that it points to the first byte of the header.\nfunc (h *Header) ParseExtended(data []byte) (*ExtendedHeader, error) {\n\textHdr := h.toExtendedHeader()\n\treservedBitsValid, err := extHdr.parse(data)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif !reservedBitsValid {\n\t\treturn extHdr, ErrInvalidReservedBits\n\t}\n\treturn extHdr, nil\n}\n\nfunc (h *Header) toExtendedHeader() *ExtendedHeader {\n\treturn &ExtendedHeader{Header: *h}\n}\n\n// PacketType is the type of the packet, for logging purposes\nfunc (h *Header) PacketType() string {\n\treturn h.Type.String()\n}\n\nfunc readPacketNumber(data []byte, pnLen protocol.PacketNumberLen) (protocol.PacketNumber, error) {\n\tvar pn protocol.PacketNumber\n\tswitch pnLen {\n\tcase protocol.PacketNumberLen1:\n\t\tpn = protocol.PacketNumber(data[0])\n\tcase protocol.PacketNumberLen2:\n\t\tpn = protocol.PacketNumber(binary.BigEndian.Uint16(data[:2]))\n\tcase protocol.PacketNumberLen3:\n\t\tpn = protocol.PacketNumber(uint32(data[2]) + uint32(data[1])<<8 + uint32(data[0])<<16)\n\tcase protocol.PacketNumberLen4:\n\t\tpn = protocol.PacketNumber(binary.BigEndian.Uint32(data[:4]))\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"invalid packet number length: %d\", pnLen)\n\t}\n\treturn pn, nil\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/log.go",
    "content": "package wire\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n)\n\n// LogFrame logs a frame, either sent or received\nfunc LogFrame(logger utils.Logger, frame Frame, sent bool) {\n\tif !logger.Debug() {\n\t\treturn\n\t}\n\tdir := \"<-\"\n\tif sent {\n\t\tdir = \"->\"\n\t}\n\tswitch f := frame.(type) {\n\tcase *CryptoFrame:\n\t\tdataLen := protocol.ByteCount(len(f.Data))\n\t\tlogger.Debugf(\"\\t%s &wire.CryptoFrame{Offset: %d, Data length: %d, Offset + Data length: %d}\", dir, f.Offset, dataLen, f.Offset+dataLen)\n\tcase *StreamFrame:\n\t\tlogger.Debugf(\"\\t%s &wire.StreamFrame{StreamID: %d, Fin: %t, Offset: %d, Data length: %d, Offset + Data length: %d}\", dir, f.StreamID, f.Fin, f.Offset, f.DataLen(), f.Offset+f.DataLen())\n\tcase *ResetStreamFrame:\n\t\tlogger.Debugf(\"\\t%s &wire.ResetStreamFrame{StreamID: %d, ErrorCode: %#x, FinalSize: %d}\", dir, f.StreamID, f.ErrorCode, f.FinalSize)\n\tcase *AckFrame:\n\t\thasECN := f.ECT0 > 0 || f.ECT1 > 0 || f.ECNCE > 0\n\t\tvar ecn string\n\t\tif hasECN {\n\t\t\tecn = fmt.Sprintf(\", ECT0: %d, ECT1: %d, CE: %d\", f.ECT0, f.ECT1, f.ECNCE)\n\t\t}\n\t\tif len(f.AckRanges) > 1 {\n\t\t\tackRanges := make([]string, len(f.AckRanges))\n\t\t\tfor i, r := range f.AckRanges {\n\t\t\t\tackRanges[i] = fmt.Sprintf(\"{Largest: %d, Smallest: %d}\", r.Largest, r.Smallest)\n\t\t\t}\n\t\t\tlogger.Debugf(\"\\t%s &wire.AckFrame{LargestAcked: %d, LowestAcked: %d, AckRanges: {%s}, DelayTime: %s%s}\", dir, f.LargestAcked(), f.LowestAcked(), strings.Join(ackRanges, \", \"), f.DelayTime.String(), ecn)\n\t\t} else {\n\t\t\tlogger.Debugf(\"\\t%s &wire.AckFrame{LargestAcked: %d, LowestAcked: %d, DelayTime: %s%s}\", dir, f.LargestAcked(), f.LowestAcked(), f.DelayTime.String(), ecn)\n\t\t}\n\tcase *MaxDataFrame:\n\t\tlogger.Debugf(\"\\t%s &wire.MaxDataFrame{MaximumData: %d}\", dir, f.MaximumData)\n\tcase *MaxStreamDataFrame:\n\t\tlogger.Debugf(\"\\t%s &wire.MaxStreamDataFrame{StreamID: %d, MaximumStreamData: %d}\", dir, f.StreamID, f.MaximumStreamData)\n\tcase *DataBlockedFrame:\n\t\tlogger.Debugf(\"\\t%s &wire.DataBlockedFrame{MaximumData: %d}\", dir, f.MaximumData)\n\tcase *StreamDataBlockedFrame:\n\t\tlogger.Debugf(\"\\t%s &wire.StreamDataBlockedFrame{StreamID: %d, MaximumStreamData: %d}\", dir, f.StreamID, f.MaximumStreamData)\n\tcase *MaxStreamsFrame:\n\t\tswitch f.Type {\n\t\tcase protocol.StreamTypeUni:\n\t\t\tlogger.Debugf(\"\\t%s &wire.MaxStreamsFrame{Type: uni, MaxStreamNum: %d}\", dir, f.MaxStreamNum)\n\t\tcase protocol.StreamTypeBidi:\n\t\t\tlogger.Debugf(\"\\t%s &wire.MaxStreamsFrame{Type: bidi, MaxStreamNum: %d}\", dir, f.MaxStreamNum)\n\t\t}\n\tcase *StreamsBlockedFrame:\n\t\tswitch f.Type {\n\t\tcase protocol.StreamTypeUni:\n\t\t\tlogger.Debugf(\"\\t%s &wire.StreamsBlockedFrame{Type: uni, MaxStreams: %d}\", dir, f.StreamLimit)\n\t\tcase protocol.StreamTypeBidi:\n\t\t\tlogger.Debugf(\"\\t%s &wire.StreamsBlockedFrame{Type: bidi, MaxStreams: %d}\", dir, f.StreamLimit)\n\t\t}\n\tcase *NewConnectionIDFrame:\n\t\tlogger.Debugf(\"\\t%s &wire.NewConnectionIDFrame{SequenceNumber: %d, RetirePriorTo: %d, ConnectionID: %s, StatelessResetToken: %#x}\", dir, f.SequenceNumber, f.RetirePriorTo, f.ConnectionID, f.StatelessResetToken)\n\tcase *RetireConnectionIDFrame:\n\t\tlogger.Debugf(\"\\t%s &wire.RetireConnectionIDFrame{SequenceNumber: %d}\", dir, f.SequenceNumber)\n\tcase *NewTokenFrame:\n\t\tlogger.Debugf(\"\\t%s &wire.NewTokenFrame{Token: %#x}\", dir, f.Token)\n\tdefault:\n\t\tlogger.Debugf(\"\\t%s %#v\", dir, frame)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/max_data_frame.go",
    "content": "package wire\n\nimport (\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// A MaxDataFrame carries flow control information for the connection\ntype MaxDataFrame struct {\n\tMaximumData protocol.ByteCount\n}\n\n// parseMaxDataFrame parses a MAX_DATA frame\nfunc parseMaxDataFrame(b []byte, _ protocol.Version) (*MaxDataFrame, int, error) {\n\tframe := &MaxDataFrame{}\n\tbyteOffset, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tframe.MaximumData = protocol.ByteCount(byteOffset)\n\treturn frame, l, nil\n}\n\nfunc (f *MaxDataFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\tb = append(b, maxDataFrameType)\n\tb = quicvarint.Append(b, uint64(f.MaximumData))\n\treturn b, nil\n}\n\n// Length of a written frame\nfunc (f *MaxDataFrame) Length(_ protocol.Version) protocol.ByteCount {\n\treturn 1 + protocol.ByteCount(quicvarint.Len(uint64(f.MaximumData)))\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/max_stream_data_frame.go",
    "content": "package wire\n\nimport (\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// A MaxStreamDataFrame is a MAX_STREAM_DATA frame\ntype MaxStreamDataFrame struct {\n\tStreamID          protocol.StreamID\n\tMaximumStreamData protocol.ByteCount\n}\n\nfunc parseMaxStreamDataFrame(b []byte, _ protocol.Version) (*MaxStreamDataFrame, int, error) {\n\tstartLen := len(b)\n\tsid, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\toffset, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\n\treturn &MaxStreamDataFrame{\n\t\tStreamID:          protocol.StreamID(sid),\n\t\tMaximumStreamData: protocol.ByteCount(offset),\n\t}, startLen - len(b), nil\n}\n\nfunc (f *MaxStreamDataFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\tb = append(b, maxStreamDataFrameType)\n\tb = quicvarint.Append(b, uint64(f.StreamID))\n\tb = quicvarint.Append(b, uint64(f.MaximumStreamData))\n\treturn b, nil\n}\n\n// Length of a written frame\nfunc (f *MaxStreamDataFrame) Length(protocol.Version) protocol.ByteCount {\n\treturn 1 + protocol.ByteCount(quicvarint.Len(uint64(f.StreamID))+quicvarint.Len(uint64(f.MaximumStreamData)))\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/max_streams_frame.go",
    "content": "package wire\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// A MaxStreamsFrame is a MAX_STREAMS frame\ntype MaxStreamsFrame struct {\n\tType         protocol.StreamType\n\tMaxStreamNum protocol.StreamNum\n}\n\nfunc parseMaxStreamsFrame(b []byte, typ uint64, _ protocol.Version) (*MaxStreamsFrame, int, error) {\n\tf := &MaxStreamsFrame{}\n\tswitch typ {\n\tcase bidiMaxStreamsFrameType:\n\t\tf.Type = protocol.StreamTypeBidi\n\tcase uniMaxStreamsFrameType:\n\t\tf.Type = protocol.StreamTypeUni\n\t}\n\tstreamID, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tf.MaxStreamNum = protocol.StreamNum(streamID)\n\tif f.MaxStreamNum > protocol.MaxStreamCount {\n\t\treturn nil, 0, fmt.Errorf(\"%d exceeds the maximum stream count\", f.MaxStreamNum)\n\t}\n\treturn f, l, nil\n}\n\nfunc (f *MaxStreamsFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\tswitch f.Type {\n\tcase protocol.StreamTypeBidi:\n\t\tb = append(b, bidiMaxStreamsFrameType)\n\tcase protocol.StreamTypeUni:\n\t\tb = append(b, uniMaxStreamsFrameType)\n\t}\n\tb = quicvarint.Append(b, uint64(f.MaxStreamNum))\n\treturn b, nil\n}\n\n// Length of a written frame\nfunc (f *MaxStreamsFrame) Length(protocol.Version) protocol.ByteCount {\n\treturn 1 + protocol.ByteCount(quicvarint.Len(uint64(f.MaxStreamNum)))\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/new_connection_id_frame.go",
    "content": "package wire\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// A NewConnectionIDFrame is a NEW_CONNECTION_ID frame\ntype NewConnectionIDFrame struct {\n\tSequenceNumber      uint64\n\tRetirePriorTo       uint64\n\tConnectionID        protocol.ConnectionID\n\tStatelessResetToken protocol.StatelessResetToken\n}\n\nfunc parseNewConnectionIDFrame(b []byte, _ protocol.Version) (*NewConnectionIDFrame, int, error) {\n\tstartLen := len(b)\n\tseq, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\tret, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\tif ret > seq {\n\t\t//nolint:staticcheck // SA1021: Retire Prior To is the name of the field\n\t\treturn nil, 0, fmt.Errorf(\"Retire Prior To value (%d) larger than Sequence Number (%d)\", ret, seq)\n\t}\n\tif len(b) == 0 {\n\t\treturn nil, 0, io.EOF\n\t}\n\tconnIDLen := int(b[0])\n\tb = b[1:]\n\tif connIDLen == 0 {\n\t\treturn nil, 0, errors.New(\"invalid zero-length connection ID\")\n\t}\n\tif connIDLen > protocol.MaxConnIDLen {\n\t\treturn nil, 0, protocol.ErrInvalidConnectionIDLen\n\t}\n\tif len(b) < connIDLen {\n\t\treturn nil, 0, io.EOF\n\t}\n\tframe := &NewConnectionIDFrame{\n\t\tSequenceNumber: seq,\n\t\tRetirePriorTo:  ret,\n\t\tConnectionID:   protocol.ParseConnectionID(b[:connIDLen]),\n\t}\n\tb = b[connIDLen:]\n\tif len(b) < len(frame.StatelessResetToken) {\n\t\treturn nil, 0, io.EOF\n\t}\n\tcopy(frame.StatelessResetToken[:], b)\n\treturn frame, startLen - len(b) + len(frame.StatelessResetToken), nil\n}\n\nfunc (f *NewConnectionIDFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\tb = append(b, newConnectionIDFrameType)\n\tb = quicvarint.Append(b, f.SequenceNumber)\n\tb = quicvarint.Append(b, f.RetirePriorTo)\n\tconnIDLen := f.ConnectionID.Len()\n\tif connIDLen > protocol.MaxConnIDLen {\n\t\treturn nil, fmt.Errorf(\"invalid connection ID length: %d\", connIDLen)\n\t}\n\tb = append(b, uint8(connIDLen))\n\tb = append(b, f.ConnectionID.Bytes()...)\n\tb = append(b, f.StatelessResetToken[:]...)\n\treturn b, nil\n}\n\n// Length of a written frame\nfunc (f *NewConnectionIDFrame) Length(protocol.Version) protocol.ByteCount {\n\treturn 1 + protocol.ByteCount(quicvarint.Len(f.SequenceNumber)+quicvarint.Len(f.RetirePriorTo)+1 /* connection ID length */ +f.ConnectionID.Len()) + 16\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/new_token_frame.go",
    "content": "package wire\n\nimport (\n\t\"errors\"\n\t\"io\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// A NewTokenFrame is a NEW_TOKEN frame\ntype NewTokenFrame struct {\n\tToken []byte\n}\n\nfunc parseNewTokenFrame(b []byte, _ protocol.Version) (*NewTokenFrame, int, error) {\n\ttokenLen, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\tif tokenLen == 0 {\n\t\treturn nil, 0, errors.New(\"token must not be empty\")\n\t}\n\tif uint64(len(b)) < tokenLen {\n\t\treturn nil, 0, io.EOF\n\t}\n\ttoken := make([]byte, int(tokenLen))\n\tcopy(token, b)\n\treturn &NewTokenFrame{Token: token}, l + int(tokenLen), nil\n}\n\nfunc (f *NewTokenFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\tb = append(b, newTokenFrameType)\n\tb = quicvarint.Append(b, uint64(len(f.Token)))\n\tb = append(b, f.Token...)\n\treturn b, nil\n}\n\n// Length of a written frame\nfunc (f *NewTokenFrame) Length(protocol.Version) protocol.ByteCount {\n\treturn 1 + protocol.ByteCount(quicvarint.Len(uint64(len(f.Token)))+len(f.Token))\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/path_challenge_frame.go",
    "content": "package wire\n\nimport (\n\t\"io\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\n// A PathChallengeFrame is a PATH_CHALLENGE frame\ntype PathChallengeFrame struct {\n\tData [8]byte\n}\n\nfunc parsePathChallengeFrame(b []byte, _ protocol.Version) (*PathChallengeFrame, int, error) {\n\tf := &PathChallengeFrame{}\n\tif len(b) < 8 {\n\t\treturn nil, 0, io.EOF\n\t}\n\tcopy(f.Data[:], b)\n\treturn f, 8, nil\n}\n\nfunc (f *PathChallengeFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\tb = append(b, pathChallengeFrameType)\n\tb = append(b, f.Data[:]...)\n\treturn b, nil\n}\n\n// Length of a written frame\nfunc (f *PathChallengeFrame) Length(_ protocol.Version) protocol.ByteCount {\n\treturn 1 + 8\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/path_response_frame.go",
    "content": "package wire\n\nimport (\n\t\"io\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\n// A PathResponseFrame is a PATH_RESPONSE frame\ntype PathResponseFrame struct {\n\tData [8]byte\n}\n\nfunc parsePathResponseFrame(b []byte, _ protocol.Version) (*PathResponseFrame, int, error) {\n\tf := &PathResponseFrame{}\n\tif len(b) < 8 {\n\t\treturn nil, 0, io.EOF\n\t}\n\tcopy(f.Data[:], b)\n\treturn f, 8, nil\n}\n\nfunc (f *PathResponseFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\tb = append(b, pathResponseFrameType)\n\tb = append(b, f.Data[:]...)\n\treturn b, nil\n}\n\n// Length of a written frame\nfunc (f *PathResponseFrame) Length(_ protocol.Version) protocol.ByteCount {\n\treturn 1 + 8\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/ping_frame.go",
    "content": "package wire\n\nimport (\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\n// A PingFrame is a PING frame\ntype PingFrame struct{}\n\nfunc (f *PingFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\treturn append(b, pingFrameType), nil\n}\n\n// Length of a written frame\nfunc (f *PingFrame) Length(_ protocol.Version) protocol.ByteCount {\n\treturn 1\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/pool.go",
    "content": "package wire\n\nimport (\n\t\"sync\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\nvar pool sync.Pool\n\nfunc init() {\n\tpool.New = func() interface{} {\n\t\treturn &StreamFrame{\n\t\t\tData:     make([]byte, 0, protocol.MaxPacketBufferSize),\n\t\t\tfromPool: true,\n\t\t}\n\t}\n}\n\nfunc GetStreamFrame() *StreamFrame {\n\tf := pool.Get().(*StreamFrame)\n\treturn f\n}\n\nfunc putStreamFrame(f *StreamFrame) {\n\tif !f.fromPool {\n\t\treturn\n\t}\n\tif protocol.ByteCount(cap(f.Data)) != protocol.MaxPacketBufferSize {\n\t\tpanic(\"wire.PutStreamFrame called with packet of wrong size!\")\n\t}\n\tpool.Put(f)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/reset_stream_frame.go",
    "content": "package wire\n\nimport (\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// A ResetStreamFrame is a RESET_STREAM frame in QUIC\ntype ResetStreamFrame struct {\n\tStreamID  protocol.StreamID\n\tErrorCode qerr.StreamErrorCode\n\tFinalSize protocol.ByteCount\n}\n\nfunc parseResetStreamFrame(b []byte, _ protocol.Version) (*ResetStreamFrame, int, error) {\n\tstartLen := len(b)\n\tvar streamID protocol.StreamID\n\tvar byteOffset protocol.ByteCount\n\tsid, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\tstreamID = protocol.StreamID(sid)\n\terrorCode, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\tbo, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tbyteOffset = protocol.ByteCount(bo)\n\n\treturn &ResetStreamFrame{\n\t\tStreamID:  streamID,\n\t\tErrorCode: qerr.StreamErrorCode(errorCode),\n\t\tFinalSize: byteOffset,\n\t}, startLen - len(b) + l, nil\n}\n\nfunc (f *ResetStreamFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\tb = append(b, resetStreamFrameType)\n\tb = quicvarint.Append(b, uint64(f.StreamID))\n\tb = quicvarint.Append(b, uint64(f.ErrorCode))\n\tb = quicvarint.Append(b, uint64(f.FinalSize))\n\treturn b, nil\n}\n\n// Length of a written frame\nfunc (f *ResetStreamFrame) Length(protocol.Version) protocol.ByteCount {\n\treturn 1 + protocol.ByteCount(quicvarint.Len(uint64(f.StreamID))+quicvarint.Len(uint64(f.ErrorCode))+quicvarint.Len(uint64(f.FinalSize)))\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/retire_connection_id_frame.go",
    "content": "package wire\n\nimport (\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// A RetireConnectionIDFrame is a RETIRE_CONNECTION_ID frame\ntype RetireConnectionIDFrame struct {\n\tSequenceNumber uint64\n}\n\nfunc parseRetireConnectionIDFrame(b []byte, _ protocol.Version) (*RetireConnectionIDFrame, int, error) {\n\tseq, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\treturn &RetireConnectionIDFrame{SequenceNumber: seq}, l, nil\n}\n\nfunc (f *RetireConnectionIDFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\tb = append(b, retireConnectionIDFrameType)\n\tb = quicvarint.Append(b, f.SequenceNumber)\n\treturn b, nil\n}\n\n// Length of a written frame\nfunc (f *RetireConnectionIDFrame) Length(protocol.Version) protocol.ByteCount {\n\treturn 1 + protocol.ByteCount(quicvarint.Len(f.SequenceNumber))\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/short_header.go",
    "content": "package wire\n\nimport (\n\t\"errors\"\n\t\"io\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n)\n\n// ParseShortHeader parses a short header packet.\n// It must be called after header protection was removed.\n// Otherwise, the check for the reserved bits will (most likely) fail.\nfunc ParseShortHeader(data []byte, connIDLen int) (length int, _ protocol.PacketNumber, _ protocol.PacketNumberLen, _ protocol.KeyPhaseBit, _ error) {\n\tif len(data) == 0 {\n\t\treturn 0, 0, 0, 0, io.EOF\n\t}\n\tif data[0]&0x80 > 0 {\n\t\treturn 0, 0, 0, 0, errors.New(\"not a short header packet\")\n\t}\n\tif data[0]&0x40 == 0 {\n\t\treturn 0, 0, 0, 0, errors.New(\"not a QUIC packet\")\n\t}\n\tpnLen := protocol.PacketNumberLen(data[0]&0b11) + 1\n\tif len(data) < 1+int(pnLen)+connIDLen {\n\t\treturn 0, 0, 0, 0, io.EOF\n\t}\n\n\tpos := 1 + connIDLen\n\tpn, err := readPacketNumber(data[pos:], pnLen)\n\tif err != nil {\n\t\treturn 0, 0, 0, 0, err\n\t}\n\tkp := protocol.KeyPhaseZero\n\tif data[0]&0b100 > 0 {\n\t\tkp = protocol.KeyPhaseOne\n\t}\n\n\tif data[0]&0x18 != 0 {\n\t\terr = ErrInvalidReservedBits\n\t}\n\treturn 1 + connIDLen + int(pnLen), pn, pnLen, kp, err\n}\n\n// AppendShortHeader writes a short header.\nfunc AppendShortHeader(b []byte, connID protocol.ConnectionID, pn protocol.PacketNumber, pnLen protocol.PacketNumberLen, kp protocol.KeyPhaseBit) ([]byte, error) {\n\ttypeByte := 0x40 | uint8(pnLen-1)\n\tif kp == protocol.KeyPhaseOne {\n\t\ttypeByte |= byte(1 << 2)\n\t}\n\tb = append(b, typeByte)\n\tb = append(b, connID.Bytes()...)\n\treturn appendPacketNumber(b, pn, pnLen)\n}\n\nfunc ShortHeaderLen(dest protocol.ConnectionID, pnLen protocol.PacketNumberLen) protocol.ByteCount {\n\treturn 1 + protocol.ByteCount(dest.Len()) + protocol.ByteCount(pnLen)\n}\n\nfunc LogShortHeader(logger utils.Logger, dest protocol.ConnectionID, pn protocol.PacketNumber, pnLen protocol.PacketNumberLen, kp protocol.KeyPhaseBit) {\n\tlogger.Debugf(\"\\tShort Header{DestConnectionID: %s, PacketNumber: %d, PacketNumberLen: %d, KeyPhase: %s}\", dest, pn, pnLen, kp)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/stop_sending_frame.go",
    "content": "package wire\n\nimport (\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// A StopSendingFrame is a STOP_SENDING frame\ntype StopSendingFrame struct {\n\tStreamID  protocol.StreamID\n\tErrorCode qerr.StreamErrorCode\n}\n\n// parseStopSendingFrame parses a STOP_SENDING frame\nfunc parseStopSendingFrame(b []byte, _ protocol.Version) (*StopSendingFrame, int, error) {\n\tstartLen := len(b)\n\tstreamID, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\terrorCode, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\n\treturn &StopSendingFrame{\n\t\tStreamID:  protocol.StreamID(streamID),\n\t\tErrorCode: qerr.StreamErrorCode(errorCode),\n\t}, startLen - len(b), nil\n}\n\n// Length of a written frame\nfunc (f *StopSendingFrame) Length(_ protocol.Version) protocol.ByteCount {\n\treturn 1 + protocol.ByteCount(quicvarint.Len(uint64(f.StreamID))+quicvarint.Len(uint64(f.ErrorCode)))\n}\n\nfunc (f *StopSendingFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\tb = append(b, stopSendingFrameType)\n\tb = quicvarint.Append(b, uint64(f.StreamID))\n\tb = quicvarint.Append(b, uint64(f.ErrorCode))\n\treturn b, nil\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/stream_data_blocked_frame.go",
    "content": "package wire\n\nimport (\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// A StreamDataBlockedFrame is a STREAM_DATA_BLOCKED frame\ntype StreamDataBlockedFrame struct {\n\tStreamID          protocol.StreamID\n\tMaximumStreamData protocol.ByteCount\n}\n\nfunc parseStreamDataBlockedFrame(b []byte, _ protocol.Version) (*StreamDataBlockedFrame, int, error) {\n\tstartLen := len(b)\n\tsid, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\toffset, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\n\treturn &StreamDataBlockedFrame{\n\t\tStreamID:          protocol.StreamID(sid),\n\t\tMaximumStreamData: protocol.ByteCount(offset),\n\t}, startLen - len(b) + l, nil\n}\n\nfunc (f *StreamDataBlockedFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\tb = append(b, 0x15)\n\tb = quicvarint.Append(b, uint64(f.StreamID))\n\tb = quicvarint.Append(b, uint64(f.MaximumStreamData))\n\treturn b, nil\n}\n\n// Length of a written frame\nfunc (f *StreamDataBlockedFrame) Length(protocol.Version) protocol.ByteCount {\n\treturn 1 + protocol.ByteCount(quicvarint.Len(uint64(f.StreamID))+quicvarint.Len(uint64(f.MaximumStreamData)))\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/stream_frame.go",
    "content": "package wire\n\nimport (\n\t\"errors\"\n\t\"io\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// A StreamFrame of QUIC\ntype StreamFrame struct {\n\tStreamID       protocol.StreamID\n\tOffset         protocol.ByteCount\n\tData           []byte\n\tFin            bool\n\tDataLenPresent bool\n\n\tfromPool bool\n}\n\nfunc parseStreamFrame(b []byte, typ uint64, _ protocol.Version) (*StreamFrame, int, error) {\n\tstartLen := len(b)\n\thasOffset := typ&0b100 > 0\n\tfin := typ&0b1 > 0\n\thasDataLen := typ&0b10 > 0\n\n\tstreamID, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tb = b[l:]\n\tvar offset uint64\n\tif hasOffset {\n\t\toffset, l, err = quicvarint.Parse(b)\n\t\tif err != nil {\n\t\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t\t}\n\t\tb = b[l:]\n\t}\n\n\tvar dataLen uint64\n\tif hasDataLen {\n\t\tvar err error\n\t\tvar l int\n\t\tdataLen, l, err = quicvarint.Parse(b)\n\t\tif err != nil {\n\t\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t\t}\n\t\tb = b[l:]\n\t\tif dataLen > uint64(len(b)) {\n\t\t\treturn nil, 0, io.EOF\n\t\t}\n\t} else {\n\t\t// The rest of the packet is data\n\t\tdataLen = uint64(len(b))\n\t}\n\n\tvar frame *StreamFrame\n\tif dataLen < protocol.MinStreamFrameBufferSize {\n\t\tframe = &StreamFrame{}\n\t\tif dataLen > 0 {\n\t\t\tframe.Data = make([]byte, dataLen)\n\t\t}\n\t} else {\n\t\tframe = GetStreamFrame()\n\t\t// The STREAM frame can't be larger than the StreamFrame we obtained from the buffer,\n\t\t// since those StreamFrames have a buffer length of the maximum packet size.\n\t\tif dataLen > uint64(cap(frame.Data)) {\n\t\t\treturn nil, 0, io.EOF\n\t\t}\n\t\tframe.Data = frame.Data[:dataLen]\n\t}\n\n\tframe.StreamID = protocol.StreamID(streamID)\n\tframe.Offset = protocol.ByteCount(offset)\n\tframe.Fin = fin\n\tframe.DataLenPresent = hasDataLen\n\n\tif dataLen > 0 {\n\t\tcopy(frame.Data, b)\n\t}\n\tif frame.Offset+frame.DataLen() > protocol.MaxByteCount {\n\t\treturn nil, 0, errors.New(\"stream data overflows maximum offset\")\n\t}\n\treturn frame, startLen - len(b) + int(dataLen), nil\n}\n\nfunc (f *StreamFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\tif len(f.Data) == 0 && !f.Fin {\n\t\treturn nil, errors.New(\"StreamFrame: attempting to write empty frame without FIN\")\n\t}\n\n\ttyp := byte(0x8)\n\tif f.Fin {\n\t\ttyp ^= 0b1\n\t}\n\thasOffset := f.Offset != 0\n\tif f.DataLenPresent {\n\t\ttyp ^= 0b10\n\t}\n\tif hasOffset {\n\t\ttyp ^= 0b100\n\t}\n\tb = append(b, typ)\n\tb = quicvarint.Append(b, uint64(f.StreamID))\n\tif hasOffset {\n\t\tb = quicvarint.Append(b, uint64(f.Offset))\n\t}\n\tif f.DataLenPresent {\n\t\tb = quicvarint.Append(b, uint64(f.DataLen()))\n\t}\n\tb = append(b, f.Data...)\n\treturn b, nil\n}\n\n// Length returns the total length of the STREAM frame\nfunc (f *StreamFrame) Length(protocol.Version) protocol.ByteCount {\n\tlength := 1 + quicvarint.Len(uint64(f.StreamID))\n\tif f.Offset != 0 {\n\t\tlength += quicvarint.Len(uint64(f.Offset))\n\t}\n\tif f.DataLenPresent {\n\t\tlength += quicvarint.Len(uint64(f.DataLen()))\n\t}\n\treturn protocol.ByteCount(length) + f.DataLen()\n}\n\n// DataLen gives the length of data in bytes\nfunc (f *StreamFrame) DataLen() protocol.ByteCount {\n\treturn protocol.ByteCount(len(f.Data))\n}\n\n// MaxDataLen returns the maximum data length\n// If 0 is returned, writing will fail (a STREAM frame must contain at least 1 byte of data).\nfunc (f *StreamFrame) MaxDataLen(maxSize protocol.ByteCount, _ protocol.Version) protocol.ByteCount {\n\theaderLen := 1 + protocol.ByteCount(quicvarint.Len(uint64(f.StreamID)))\n\tif f.Offset != 0 {\n\t\theaderLen += protocol.ByteCount(quicvarint.Len(uint64(f.Offset)))\n\t}\n\tif f.DataLenPresent {\n\t\t// Pretend that the data size will be 1 byte.\n\t\t// If it turns out that varint encoding the length will consume 2 bytes, we need to adjust the data length afterward\n\t\theaderLen++\n\t}\n\tif headerLen > maxSize {\n\t\treturn 0\n\t}\n\tmaxDataLen := maxSize - headerLen\n\tif f.DataLenPresent && quicvarint.Len(uint64(maxDataLen)) != 1 {\n\t\tmaxDataLen--\n\t}\n\treturn maxDataLen\n}\n\n// MaybeSplitOffFrame splits a frame such that it is not bigger than n bytes.\n// It returns if the frame was actually split.\n// The frame might not be split if:\n// * the size is large enough to fit the whole frame\n// * the size is too small to fit even a 1-byte frame. In that case, the frame returned is nil.\nfunc (f *StreamFrame) MaybeSplitOffFrame(maxSize protocol.ByteCount, version protocol.Version) (*StreamFrame, bool /* was splitting required */) {\n\tif maxSize >= f.Length(version) {\n\t\treturn nil, false\n\t}\n\n\tn := f.MaxDataLen(maxSize, version)\n\tif n == 0 {\n\t\treturn nil, true\n\t}\n\n\tnew := GetStreamFrame()\n\tnew.StreamID = f.StreamID\n\tnew.Offset = f.Offset\n\tnew.Fin = false\n\tnew.DataLenPresent = f.DataLenPresent\n\n\t// swap the data slices\n\tnew.Data, f.Data = f.Data, new.Data\n\tnew.fromPool, f.fromPool = f.fromPool, new.fromPool\n\n\tf.Data = f.Data[:protocol.ByteCount(len(new.Data))-n]\n\tcopy(f.Data, new.Data[n:])\n\tnew.Data = new.Data[:n]\n\tf.Offset += n\n\n\treturn new, true\n}\n\nfunc (f *StreamFrame) PutBack() {\n\tputStreamFrame(f)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/streams_blocked_frame.go",
    "content": "package wire\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// A StreamsBlockedFrame is a STREAMS_BLOCKED frame\ntype StreamsBlockedFrame struct {\n\tType        protocol.StreamType\n\tStreamLimit protocol.StreamNum\n}\n\nfunc parseStreamsBlockedFrame(b []byte, typ uint64, _ protocol.Version) (*StreamsBlockedFrame, int, error) {\n\tf := &StreamsBlockedFrame{}\n\tswitch typ {\n\tcase bidiStreamBlockedFrameType:\n\t\tf.Type = protocol.StreamTypeBidi\n\tcase uniStreamBlockedFrameType:\n\t\tf.Type = protocol.StreamTypeUni\n\t}\n\tstreamLimit, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn nil, 0, replaceUnexpectedEOF(err)\n\t}\n\tf.StreamLimit = protocol.StreamNum(streamLimit)\n\tif f.StreamLimit > protocol.MaxStreamCount {\n\t\treturn nil, 0, fmt.Errorf(\"%d exceeds the maximum stream count\", f.StreamLimit)\n\t}\n\treturn f, l, nil\n}\n\nfunc (f *StreamsBlockedFrame) Append(b []byte, _ protocol.Version) ([]byte, error) {\n\tswitch f.Type {\n\tcase protocol.StreamTypeBidi:\n\t\tb = append(b, bidiStreamBlockedFrameType)\n\tcase protocol.StreamTypeUni:\n\t\tb = append(b, uniStreamBlockedFrameType)\n\t}\n\tb = quicvarint.Append(b, uint64(f.StreamLimit))\n\treturn b, nil\n}\n\n// Length of a written frame\nfunc (f *StreamsBlockedFrame) Length(_ protocol.Version) protocol.ByteCount {\n\treturn 1 + protocol.ByteCount(quicvarint.Len(uint64(f.StreamLimit)))\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/transport_parameters.go",
    "content": "package wire\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/netip\"\n\t\"slices\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/quicvarint\"\n)\n\n// AdditionalTransportParametersClient are additional transport parameters that will be added\n// to the client's transport parameters.\n// This is not intended for production use, but _only_ to increase the size of the ClientHello beyond\n// the usual size of less than 1 MTU.\nvar AdditionalTransportParametersClient map[uint64][]byte\n\nconst transportParameterMarshalingVersion = 1\n\ntype transportParameterID uint64\n\nconst (\n\toriginalDestinationConnectionIDParameterID transportParameterID = 0x0\n\tmaxIdleTimeoutParameterID                  transportParameterID = 0x1\n\tstatelessResetTokenParameterID             transportParameterID = 0x2\n\tmaxUDPPayloadSizeParameterID               transportParameterID = 0x3\n\tinitialMaxDataParameterID                  transportParameterID = 0x4\n\tinitialMaxStreamDataBidiLocalParameterID   transportParameterID = 0x5\n\tinitialMaxStreamDataBidiRemoteParameterID  transportParameterID = 0x6\n\tinitialMaxStreamDataUniParameterID         transportParameterID = 0x7\n\tinitialMaxStreamsBidiParameterID           transportParameterID = 0x8\n\tinitialMaxStreamsUniParameterID            transportParameterID = 0x9\n\tackDelayExponentParameterID                transportParameterID = 0xa\n\tmaxAckDelayParameterID                     transportParameterID = 0xb\n\tdisableActiveMigrationParameterID          transportParameterID = 0xc\n\tpreferredAddressParameterID                transportParameterID = 0xd\n\tactiveConnectionIDLimitParameterID         transportParameterID = 0xe\n\tinitialSourceConnectionIDParameterID       transportParameterID = 0xf\n\tretrySourceConnectionIDParameterID         transportParameterID = 0x10\n\t// RFC 9221\n\tmaxDatagramFrameSizeParameterID transportParameterID = 0x20\n)\n\n// PreferredAddress is the value encoding in the preferred_address transport parameter\ntype PreferredAddress struct {\n\tIPv4, IPv6          netip.AddrPort\n\tConnectionID        protocol.ConnectionID\n\tStatelessResetToken protocol.StatelessResetToken\n}\n\n// TransportParameters are parameters sent to the peer during the handshake\ntype TransportParameters struct {\n\tInitialMaxStreamDataBidiLocal  protocol.ByteCount\n\tInitialMaxStreamDataBidiRemote protocol.ByteCount\n\tInitialMaxStreamDataUni        protocol.ByteCount\n\tInitialMaxData                 protocol.ByteCount\n\n\tMaxAckDelay      time.Duration\n\tAckDelayExponent uint8\n\n\tDisableActiveMigration bool\n\n\tMaxUDPPayloadSize protocol.ByteCount\n\n\tMaxUniStreamNum  protocol.StreamNum\n\tMaxBidiStreamNum protocol.StreamNum\n\n\tMaxIdleTimeout time.Duration\n\n\tPreferredAddress *PreferredAddress\n\n\tOriginalDestinationConnectionID protocol.ConnectionID\n\tInitialSourceConnectionID       protocol.ConnectionID\n\tRetrySourceConnectionID         *protocol.ConnectionID // use a pointer here to distinguish zero-length connection IDs from missing transport parameters\n\n\tStatelessResetToken     *protocol.StatelessResetToken\n\tActiveConnectionIDLimit uint64\n\n\tMaxDatagramFrameSize protocol.ByteCount\n}\n\n// Unmarshal the transport parameters\nfunc (p *TransportParameters) Unmarshal(data []byte, sentBy protocol.Perspective) error {\n\tif err := p.unmarshal(data, sentBy, false); err != nil {\n\t\treturn &qerr.TransportError{\n\t\t\tErrorCode:    qerr.TransportParameterError,\n\t\t\tErrorMessage: err.Error(),\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (p *TransportParameters) unmarshal(b []byte, sentBy protocol.Perspective, fromSessionTicket bool) error {\n\t// needed to check that every parameter is only sent at most once\n\tparameterIDs := make([]transportParameterID, 0, 32)\n\n\tvar (\n\t\treadOriginalDestinationConnectionID bool\n\t\treadInitialSourceConnectionID       bool\n\t\treadActiveConnectionIDLimit         bool\n\t)\n\n\tp.AckDelayExponent = protocol.DefaultAckDelayExponent\n\tp.MaxAckDelay = protocol.DefaultMaxAckDelay\n\tp.MaxDatagramFrameSize = protocol.InvalidByteCount\n\n\tfor len(b) > 0 {\n\t\tparamIDInt, l, err := quicvarint.Parse(b)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tparamID := transportParameterID(paramIDInt)\n\t\tb = b[l:]\n\t\tparamLen, l, err := quicvarint.Parse(b)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tb = b[l:]\n\t\tif uint64(len(b)) < paramLen {\n\t\t\treturn fmt.Errorf(\"remaining length (%d) smaller than parameter length (%d)\", len(b), paramLen)\n\t\t}\n\t\tparameterIDs = append(parameterIDs, paramID)\n\t\tswitch paramID {\n\t\tcase activeConnectionIDLimitParameterID:\n\t\t\treadActiveConnectionIDLimit = true\n\t\t\tfallthrough\n\t\tcase maxIdleTimeoutParameterID,\n\t\t\tmaxUDPPayloadSizeParameterID,\n\t\t\tinitialMaxDataParameterID,\n\t\t\tinitialMaxStreamDataBidiLocalParameterID,\n\t\t\tinitialMaxStreamDataBidiRemoteParameterID,\n\t\t\tinitialMaxStreamDataUniParameterID,\n\t\t\tinitialMaxStreamsBidiParameterID,\n\t\t\tinitialMaxStreamsUniParameterID,\n\t\t\tmaxAckDelayParameterID,\n\t\t\tmaxDatagramFrameSizeParameterID,\n\t\t\tackDelayExponentParameterID:\n\t\t\tif err := p.readNumericTransportParameter(b, paramID, int(paramLen)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tb = b[paramLen:]\n\t\tcase preferredAddressParameterID:\n\t\t\tif sentBy == protocol.PerspectiveClient {\n\t\t\t\treturn errors.New(\"client sent a preferred_address\")\n\t\t\t}\n\t\t\tif err := p.readPreferredAddress(b, int(paramLen)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tb = b[paramLen:]\n\t\tcase disableActiveMigrationParameterID:\n\t\t\tif paramLen != 0 {\n\t\t\t\treturn fmt.Errorf(\"wrong length for disable_active_migration: %d (expected empty)\", paramLen)\n\t\t\t}\n\t\t\tp.DisableActiveMigration = true\n\t\tcase statelessResetTokenParameterID:\n\t\t\tif sentBy == protocol.PerspectiveClient {\n\t\t\t\treturn errors.New(\"client sent a stateless_reset_token\")\n\t\t\t}\n\t\t\tif paramLen != 16 {\n\t\t\t\treturn fmt.Errorf(\"wrong length for stateless_reset_token: %d (expected 16)\", paramLen)\n\t\t\t}\n\t\t\tvar token protocol.StatelessResetToken\n\t\t\tif len(b) < len(token) {\n\t\t\t\treturn io.EOF\n\t\t\t}\n\t\t\tcopy(token[:], b)\n\t\t\tb = b[len(token):]\n\t\t\tp.StatelessResetToken = &token\n\t\tcase originalDestinationConnectionIDParameterID:\n\t\t\tif sentBy == protocol.PerspectiveClient {\n\t\t\t\treturn errors.New(\"client sent an original_destination_connection_id\")\n\t\t\t}\n\t\t\tif paramLen > protocol.MaxConnIDLen {\n\t\t\t\treturn protocol.ErrInvalidConnectionIDLen\n\t\t\t}\n\t\t\tp.OriginalDestinationConnectionID = protocol.ParseConnectionID(b[:paramLen])\n\t\t\tb = b[paramLen:]\n\t\t\treadOriginalDestinationConnectionID = true\n\t\tcase initialSourceConnectionIDParameterID:\n\t\t\tif paramLen > protocol.MaxConnIDLen {\n\t\t\t\treturn protocol.ErrInvalidConnectionIDLen\n\t\t\t}\n\t\t\tp.InitialSourceConnectionID = protocol.ParseConnectionID(b[:paramLen])\n\t\t\tb = b[paramLen:]\n\t\t\treadInitialSourceConnectionID = true\n\t\tcase retrySourceConnectionIDParameterID:\n\t\t\tif sentBy == protocol.PerspectiveClient {\n\t\t\t\treturn errors.New(\"client sent a retry_source_connection_id\")\n\t\t\t}\n\t\t\tif paramLen > protocol.MaxConnIDLen {\n\t\t\t\treturn protocol.ErrInvalidConnectionIDLen\n\t\t\t}\n\t\t\tconnID := protocol.ParseConnectionID(b[:paramLen])\n\t\t\tb = b[paramLen:]\n\t\t\tp.RetrySourceConnectionID = &connID\n\t\tdefault:\n\t\t\tb = b[paramLen:]\n\t\t}\n\t}\n\n\tif !readActiveConnectionIDLimit {\n\t\tp.ActiveConnectionIDLimit = protocol.DefaultActiveConnectionIDLimit\n\t}\n\tif !fromSessionTicket {\n\t\tif sentBy == protocol.PerspectiveServer && !readOriginalDestinationConnectionID {\n\t\t\treturn errors.New(\"missing original_destination_connection_id\")\n\t\t}\n\t\tif p.MaxUDPPayloadSize == 0 {\n\t\t\tp.MaxUDPPayloadSize = protocol.MaxByteCount\n\t\t}\n\t\tif !readInitialSourceConnectionID {\n\t\t\treturn errors.New(\"missing initial_source_connection_id\")\n\t\t}\n\t}\n\n\t// check that every transport parameter was sent at most once\n\tslices.SortFunc(parameterIDs, func(a, b transportParameterID) int {\n\t\tif a < b {\n\t\t\treturn -1\n\t\t}\n\t\treturn 1\n\t})\n\tfor i := 0; i < len(parameterIDs)-1; i++ {\n\t\tif parameterIDs[i] == parameterIDs[i+1] {\n\t\t\treturn fmt.Errorf(\"received duplicate transport parameter %#x\", parameterIDs[i])\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (p *TransportParameters) readPreferredAddress(b []byte, expectedLen int) error {\n\tremainingLen := len(b)\n\tpa := &PreferredAddress{}\n\tif len(b) < 4+2+16+2+1 {\n\t\treturn io.EOF\n\t}\n\tvar ipv4 [4]byte\n\tcopy(ipv4[:], b[:4])\n\tport4 := binary.BigEndian.Uint16(b[4:])\n\tb = b[4+2:]\n\tif port4 != 0 && ipv4 != [4]byte{} {\n\t\tpa.IPv4 = netip.AddrPortFrom(netip.AddrFrom4(ipv4), port4)\n\t}\n\tvar ipv6 [16]byte\n\tcopy(ipv6[:], b[:16])\n\tport6 := binary.BigEndian.Uint16(b[16:])\n\tif port6 != 0 && ipv6 != [16]byte{} {\n\t\tpa.IPv6 = netip.AddrPortFrom(netip.AddrFrom16(ipv6), port6)\n\t}\n\tb = b[16+2:]\n\tconnIDLen := int(b[0])\n\tb = b[1:]\n\tif connIDLen == 0 || connIDLen > protocol.MaxConnIDLen {\n\t\treturn fmt.Errorf(\"invalid connection ID length: %d\", connIDLen)\n\t}\n\tif len(b) < connIDLen+len(pa.StatelessResetToken) {\n\t\treturn io.EOF\n\t}\n\tpa.ConnectionID = protocol.ParseConnectionID(b[:connIDLen])\n\tb = b[connIDLen:]\n\tcopy(pa.StatelessResetToken[:], b)\n\tb = b[len(pa.StatelessResetToken):]\n\tif bytesRead := remainingLen - len(b); bytesRead != expectedLen {\n\t\treturn fmt.Errorf(\"expected preferred_address to be %d long, read %d bytes\", expectedLen, bytesRead)\n\t}\n\tp.PreferredAddress = pa\n\treturn nil\n}\n\nfunc (p *TransportParameters) readNumericTransportParameter(b []byte, paramID transportParameterID, expectedLen int) error {\n\tval, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error while reading transport parameter %d: %s\", paramID, err)\n\t}\n\tif l != expectedLen {\n\t\treturn fmt.Errorf(\"inconsistent transport parameter length for transport parameter %#x\", paramID)\n\t}\n\t//nolint:exhaustive // This only covers the numeric transport parameters.\n\tswitch paramID {\n\tcase initialMaxStreamDataBidiLocalParameterID:\n\t\tp.InitialMaxStreamDataBidiLocal = protocol.ByteCount(val)\n\tcase initialMaxStreamDataBidiRemoteParameterID:\n\t\tp.InitialMaxStreamDataBidiRemote = protocol.ByteCount(val)\n\tcase initialMaxStreamDataUniParameterID:\n\t\tp.InitialMaxStreamDataUni = protocol.ByteCount(val)\n\tcase initialMaxDataParameterID:\n\t\tp.InitialMaxData = protocol.ByteCount(val)\n\tcase initialMaxStreamsBidiParameterID:\n\t\tp.MaxBidiStreamNum = protocol.StreamNum(val)\n\t\tif p.MaxBidiStreamNum > protocol.MaxStreamCount {\n\t\t\treturn fmt.Errorf(\"initial_max_streams_bidi too large: %d (maximum %d)\", p.MaxBidiStreamNum, protocol.MaxStreamCount)\n\t\t}\n\tcase initialMaxStreamsUniParameterID:\n\t\tp.MaxUniStreamNum = protocol.StreamNum(val)\n\t\tif p.MaxUniStreamNum > protocol.MaxStreamCount {\n\t\t\treturn fmt.Errorf(\"initial_max_streams_uni too large: %d (maximum %d)\", p.MaxUniStreamNum, protocol.MaxStreamCount)\n\t\t}\n\tcase maxIdleTimeoutParameterID:\n\t\tp.MaxIdleTimeout = max(protocol.MinRemoteIdleTimeout, time.Duration(val)*time.Millisecond)\n\tcase maxUDPPayloadSizeParameterID:\n\t\tif val < 1200 {\n\t\t\treturn fmt.Errorf(\"invalid value for max_udp_payload_size: %d (minimum 1200)\", val)\n\t\t}\n\t\tp.MaxUDPPayloadSize = protocol.ByteCount(val)\n\tcase ackDelayExponentParameterID:\n\t\tif val > protocol.MaxAckDelayExponent {\n\t\t\treturn fmt.Errorf(\"invalid value for ack_delay_exponent: %d (maximum %d)\", val, protocol.MaxAckDelayExponent)\n\t\t}\n\t\tp.AckDelayExponent = uint8(val)\n\tcase maxAckDelayParameterID:\n\t\tif val > uint64(protocol.MaxMaxAckDelay/time.Millisecond) {\n\t\t\treturn fmt.Errorf(\"invalid value for max_ack_delay: %dms (maximum %dms)\", val, protocol.MaxMaxAckDelay/time.Millisecond)\n\t\t}\n\t\tp.MaxAckDelay = time.Duration(val) * time.Millisecond\n\tcase activeConnectionIDLimitParameterID:\n\t\tif val < 2 {\n\t\t\treturn fmt.Errorf(\"invalid value for active_connection_id_limit: %d (minimum 2)\", val)\n\t\t}\n\t\tp.ActiveConnectionIDLimit = val\n\tcase maxDatagramFrameSizeParameterID:\n\t\tp.MaxDatagramFrameSize = protocol.ByteCount(val)\n\tdefault:\n\t\treturn fmt.Errorf(\"TransportParameter BUG: transport parameter %d not found\", paramID)\n\t}\n\treturn nil\n}\n\n// Marshal the transport parameters\nfunc (p *TransportParameters) Marshal(pers protocol.Perspective) []byte {\n\t// Typical Transport Parameters consume around 110 bytes, depending on the exact values,\n\t// especially the lengths of the Connection IDs.\n\t// Allocate 256 bytes, so we won't have to grow the slice in any case.\n\tb := make([]byte, 0, 256)\n\n\t// add a greased value\n\trandom := make([]byte, 18)\n\trand.Read(random)\n\tb = quicvarint.Append(b, 27+31*uint64(random[0]))\n\tlength := random[1] % 16\n\tb = quicvarint.Append(b, uint64(length))\n\tb = append(b, random[2:2+length]...)\n\n\t// initial_max_stream_data_bidi_local\n\tb = p.marshalVarintParam(b, initialMaxStreamDataBidiLocalParameterID, uint64(p.InitialMaxStreamDataBidiLocal))\n\t// initial_max_stream_data_bidi_remote\n\tb = p.marshalVarintParam(b, initialMaxStreamDataBidiRemoteParameterID, uint64(p.InitialMaxStreamDataBidiRemote))\n\t// initial_max_stream_data_uni\n\tb = p.marshalVarintParam(b, initialMaxStreamDataUniParameterID, uint64(p.InitialMaxStreamDataUni))\n\t// initial_max_data\n\tb = p.marshalVarintParam(b, initialMaxDataParameterID, uint64(p.InitialMaxData))\n\t// initial_max_bidi_streams\n\tb = p.marshalVarintParam(b, initialMaxStreamsBidiParameterID, uint64(p.MaxBidiStreamNum))\n\t// initial_max_uni_streams\n\tb = p.marshalVarintParam(b, initialMaxStreamsUniParameterID, uint64(p.MaxUniStreamNum))\n\t// idle_timeout\n\tb = p.marshalVarintParam(b, maxIdleTimeoutParameterID, uint64(p.MaxIdleTimeout/time.Millisecond))\n\t// max_udp_payload_size\n\tif p.MaxUDPPayloadSize > 0 {\n\t\tb = p.marshalVarintParam(b, maxUDPPayloadSizeParameterID, uint64(p.MaxUDPPayloadSize))\n\t}\n\t// max_ack_delay\n\t// Only send it if is different from the default value.\n\tif p.MaxAckDelay != protocol.DefaultMaxAckDelay {\n\t\tb = p.marshalVarintParam(b, maxAckDelayParameterID, uint64(p.MaxAckDelay/time.Millisecond))\n\t}\n\t// ack_delay_exponent\n\t// Only send it if is different from the default value.\n\tif p.AckDelayExponent != protocol.DefaultAckDelayExponent {\n\t\tb = p.marshalVarintParam(b, ackDelayExponentParameterID, uint64(p.AckDelayExponent))\n\t}\n\t// disable_active_migration\n\tif p.DisableActiveMigration {\n\t\tb = quicvarint.Append(b, uint64(disableActiveMigrationParameterID))\n\t\tb = quicvarint.Append(b, 0)\n\t}\n\tif pers == protocol.PerspectiveServer {\n\t\t// stateless_reset_token\n\t\tif p.StatelessResetToken != nil {\n\t\t\tb = quicvarint.Append(b, uint64(statelessResetTokenParameterID))\n\t\t\tb = quicvarint.Append(b, 16)\n\t\t\tb = append(b, p.StatelessResetToken[:]...)\n\t\t}\n\t\t// original_destination_connection_id\n\t\tb = quicvarint.Append(b, uint64(originalDestinationConnectionIDParameterID))\n\t\tb = quicvarint.Append(b, uint64(p.OriginalDestinationConnectionID.Len()))\n\t\tb = append(b, p.OriginalDestinationConnectionID.Bytes()...)\n\t\t// preferred_address\n\t\tif p.PreferredAddress != nil {\n\t\t\tb = quicvarint.Append(b, uint64(preferredAddressParameterID))\n\t\t\tb = quicvarint.Append(b, 4+2+16+2+1+uint64(p.PreferredAddress.ConnectionID.Len())+16)\n\t\t\tif p.PreferredAddress.IPv4.IsValid() {\n\t\t\t\tipv4 := p.PreferredAddress.IPv4.Addr().As4()\n\t\t\t\tb = append(b, ipv4[:]...)\n\t\t\t\tb = binary.BigEndian.AppendUint16(b, p.PreferredAddress.IPv4.Port())\n\t\t\t} else {\n\t\t\t\tb = append(b, make([]byte, 6)...)\n\t\t\t}\n\t\t\tif p.PreferredAddress.IPv6.IsValid() {\n\t\t\t\tipv6 := p.PreferredAddress.IPv6.Addr().As16()\n\t\t\t\tb = append(b, ipv6[:]...)\n\t\t\t\tb = binary.BigEndian.AppendUint16(b, p.PreferredAddress.IPv6.Port())\n\t\t\t} else {\n\t\t\t\tb = append(b, make([]byte, 18)...)\n\t\t\t}\n\t\t\tb = append(b, uint8(p.PreferredAddress.ConnectionID.Len()))\n\t\t\tb = append(b, p.PreferredAddress.ConnectionID.Bytes()...)\n\t\t\tb = append(b, p.PreferredAddress.StatelessResetToken[:]...)\n\t\t}\n\t}\n\t// active_connection_id_limit\n\tif p.ActiveConnectionIDLimit != protocol.DefaultActiveConnectionIDLimit {\n\t\tb = p.marshalVarintParam(b, activeConnectionIDLimitParameterID, p.ActiveConnectionIDLimit)\n\t}\n\t// initial_source_connection_id\n\tb = quicvarint.Append(b, uint64(initialSourceConnectionIDParameterID))\n\tb = quicvarint.Append(b, uint64(p.InitialSourceConnectionID.Len()))\n\tb = append(b, p.InitialSourceConnectionID.Bytes()...)\n\t// retry_source_connection_id\n\tif pers == protocol.PerspectiveServer && p.RetrySourceConnectionID != nil {\n\t\tb = quicvarint.Append(b, uint64(retrySourceConnectionIDParameterID))\n\t\tb = quicvarint.Append(b, uint64(p.RetrySourceConnectionID.Len()))\n\t\tb = append(b, p.RetrySourceConnectionID.Bytes()...)\n\t}\n\tif p.MaxDatagramFrameSize != protocol.InvalidByteCount {\n\t\tb = p.marshalVarintParam(b, maxDatagramFrameSizeParameterID, uint64(p.MaxDatagramFrameSize))\n\t}\n\n\tif pers == protocol.PerspectiveClient && len(AdditionalTransportParametersClient) > 0 {\n\t\tfor k, v := range AdditionalTransportParametersClient {\n\t\t\tb = quicvarint.Append(b, k)\n\t\t\tb = quicvarint.Append(b, uint64(len(v)))\n\t\t\tb = append(b, v...)\n\t\t}\n\t}\n\n\treturn b\n}\n\nfunc (p *TransportParameters) marshalVarintParam(b []byte, id transportParameterID, val uint64) []byte {\n\tb = quicvarint.Append(b, uint64(id))\n\tb = quicvarint.Append(b, uint64(quicvarint.Len(val)))\n\treturn quicvarint.Append(b, val)\n}\n\n// MarshalForSessionTicket marshals the transport parameters we save in the session ticket.\n// When sending a 0-RTT enabled TLS session tickets, we need to save the transport parameters.\n// The client will remember the transport parameters used in the last session,\n// and apply those to the 0-RTT data it sends.\n// Saving the transport parameters in the ticket gives the server the option to reject 0-RTT\n// if the transport parameters changed.\n// Since the session ticket is encrypted, the serialization format is defined by the server.\n// For convenience, we use the same format that we also use for sending the transport parameters.\nfunc (p *TransportParameters) MarshalForSessionTicket(b []byte) []byte {\n\tb = quicvarint.Append(b, transportParameterMarshalingVersion)\n\n\t// initial_max_stream_data_bidi_local\n\tb = p.marshalVarintParam(b, initialMaxStreamDataBidiLocalParameterID, uint64(p.InitialMaxStreamDataBidiLocal))\n\t// initial_max_stream_data_bidi_remote\n\tb = p.marshalVarintParam(b, initialMaxStreamDataBidiRemoteParameterID, uint64(p.InitialMaxStreamDataBidiRemote))\n\t// initial_max_stream_data_uni\n\tb = p.marshalVarintParam(b, initialMaxStreamDataUniParameterID, uint64(p.InitialMaxStreamDataUni))\n\t// initial_max_data\n\tb = p.marshalVarintParam(b, initialMaxDataParameterID, uint64(p.InitialMaxData))\n\t// initial_max_bidi_streams\n\tb = p.marshalVarintParam(b, initialMaxStreamsBidiParameterID, uint64(p.MaxBidiStreamNum))\n\t// initial_max_uni_streams\n\tb = p.marshalVarintParam(b, initialMaxStreamsUniParameterID, uint64(p.MaxUniStreamNum))\n\t// max_datagram_frame_size\n\tif p.MaxDatagramFrameSize != protocol.InvalidByteCount {\n\t\tb = p.marshalVarintParam(b, maxDatagramFrameSizeParameterID, uint64(p.MaxDatagramFrameSize))\n\t}\n\t// active_connection_id_limit\n\treturn p.marshalVarintParam(b, activeConnectionIDLimitParameterID, p.ActiveConnectionIDLimit)\n}\n\n// UnmarshalFromSessionTicket unmarshals transport parameters from a session ticket.\nfunc (p *TransportParameters) UnmarshalFromSessionTicket(b []byte) error {\n\tversion, l, err := quicvarint.Parse(b)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif version != transportParameterMarshalingVersion {\n\t\treturn fmt.Errorf(\"unknown transport parameter marshaling version: %d\", version)\n\t}\n\treturn p.unmarshal(b[l:], protocol.PerspectiveServer, true)\n}\n\n// ValidFor0RTT checks if the transport parameters match those saved in the session ticket.\nfunc (p *TransportParameters) ValidFor0RTT(saved *TransportParameters) bool {\n\tif saved.MaxDatagramFrameSize != protocol.InvalidByteCount && (p.MaxDatagramFrameSize == protocol.InvalidByteCount || p.MaxDatagramFrameSize < saved.MaxDatagramFrameSize) {\n\t\treturn false\n\t}\n\treturn p.InitialMaxStreamDataBidiLocal >= saved.InitialMaxStreamDataBidiLocal &&\n\t\tp.InitialMaxStreamDataBidiRemote >= saved.InitialMaxStreamDataBidiRemote &&\n\t\tp.InitialMaxStreamDataUni >= saved.InitialMaxStreamDataUni &&\n\t\tp.InitialMaxData >= saved.InitialMaxData &&\n\t\tp.MaxBidiStreamNum >= saved.MaxBidiStreamNum &&\n\t\tp.MaxUniStreamNum >= saved.MaxUniStreamNum &&\n\t\tp.ActiveConnectionIDLimit == saved.ActiveConnectionIDLimit\n}\n\n// ValidForUpdate checks that the new transport parameters don't reduce limits after resuming a 0-RTT connection.\n// It is only used on the client side.\nfunc (p *TransportParameters) ValidForUpdate(saved *TransportParameters) bool {\n\tif saved.MaxDatagramFrameSize != protocol.InvalidByteCount && (p.MaxDatagramFrameSize == protocol.InvalidByteCount || p.MaxDatagramFrameSize < saved.MaxDatagramFrameSize) {\n\t\treturn false\n\t}\n\treturn p.ActiveConnectionIDLimit >= saved.ActiveConnectionIDLimit &&\n\t\tp.InitialMaxData >= saved.InitialMaxData &&\n\t\tp.InitialMaxStreamDataBidiLocal >= saved.InitialMaxStreamDataBidiLocal &&\n\t\tp.InitialMaxStreamDataBidiRemote >= saved.InitialMaxStreamDataBidiRemote &&\n\t\tp.InitialMaxStreamDataUni >= saved.InitialMaxStreamDataUni &&\n\t\tp.MaxBidiStreamNum >= saved.MaxBidiStreamNum &&\n\t\tp.MaxUniStreamNum >= saved.MaxUniStreamNum\n}\n\n// String returns a string representation, intended for logging.\nfunc (p *TransportParameters) String() string {\n\tlogString := \"&wire.TransportParameters{OriginalDestinationConnectionID: %s, InitialSourceConnectionID: %s, \"\n\tlogParams := []interface{}{p.OriginalDestinationConnectionID, p.InitialSourceConnectionID}\n\tif p.RetrySourceConnectionID != nil {\n\t\tlogString += \"RetrySourceConnectionID: %s, \"\n\t\tlogParams = append(logParams, p.RetrySourceConnectionID)\n\t}\n\tlogString += \"InitialMaxStreamDataBidiLocal: %d, InitialMaxStreamDataBidiRemote: %d, InitialMaxStreamDataUni: %d, InitialMaxData: %d, MaxBidiStreamNum: %d, MaxUniStreamNum: %d, MaxIdleTimeout: %s, AckDelayExponent: %d, MaxAckDelay: %s, ActiveConnectionIDLimit: %d\"\n\tlogParams = append(logParams, []interface{}{p.InitialMaxStreamDataBidiLocal, p.InitialMaxStreamDataBidiRemote, p.InitialMaxStreamDataUni, p.InitialMaxData, p.MaxBidiStreamNum, p.MaxUniStreamNum, p.MaxIdleTimeout, p.AckDelayExponent, p.MaxAckDelay, p.ActiveConnectionIDLimit}...)\n\tif p.StatelessResetToken != nil { // the client never sends a stateless reset token\n\t\tlogString += \", StatelessResetToken: %#x\"\n\t\tlogParams = append(logParams, *p.StatelessResetToken)\n\t}\n\tif p.MaxDatagramFrameSize != protocol.InvalidByteCount {\n\t\tlogString += \", MaxDatagramFrameSize: %d\"\n\t\tlogParams = append(logParams, p.MaxDatagramFrameSize)\n\t}\n\tlogString += \"}\"\n\treturn fmt.Sprintf(logString, logParams...)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/internal/wire/version_negotiation.go",
    "content": "package wire\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/binary\"\n\t\"errors\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\n// ParseVersionNegotiationPacket parses a Version Negotiation packet.\nfunc ParseVersionNegotiationPacket(b []byte) (dest, src protocol.ArbitraryLenConnectionID, _ []protocol.Version, _ error) {\n\tn, dest, src, err := ParseArbitraryLenConnectionIDs(b)\n\tif err != nil {\n\t\treturn nil, nil, nil, err\n\t}\n\tb = b[n:]\n\tif len(b) == 0 {\n\t\t//nolint:staticcheck // SA1021: the packet is called Version Negotiation packet\n\t\treturn nil, nil, nil, errors.New(\"Version Negotiation packet has empty version list\")\n\t}\n\tif len(b)%4 != 0 {\n\t\t//nolint:staticcheck // SA1021: the packet is called Version Negotiation packet\n\t\treturn nil, nil, nil, errors.New(\"Version Negotiation packet has a version list with an invalid length\")\n\t}\n\tversions := make([]protocol.Version, len(b)/4)\n\tfor i := 0; len(b) > 0; i++ {\n\t\tversions[i] = protocol.Version(binary.BigEndian.Uint32(b[:4]))\n\t\tb = b[4:]\n\t}\n\treturn dest, src, versions, nil\n}\n\n// ComposeVersionNegotiation composes a Version Negotiation\nfunc ComposeVersionNegotiation(destConnID, srcConnID protocol.ArbitraryLenConnectionID, versions []protocol.Version) []byte {\n\tgreasedVersions := protocol.GetGreasedVersions(versions)\n\texpectedLen := 1 /* type byte */ + 4 /* version field */ + 1 /* dest connection ID length field */ + destConnID.Len() + 1 /* src connection ID length field */ + srcConnID.Len() + len(greasedVersions)*4\n\tbuf := make([]byte, 1+4 /* type byte and version field */, expectedLen)\n\t_, _ = rand.Read(buf[:1]) // ignore the error here. It is not critical to have perfect random here.\n\t// Setting the \"QUIC bit\" (0x40) is not required by the RFC,\n\t// but it allows clients to demultiplex QUIC with a long list of other protocols.\n\t// See RFC 9443 and https://mailarchive.ietf.org/arch/msg/quic/oR4kxGKY6mjtPC1CZegY1ED4beg/ for details.\n\tbuf[0] |= 0xc0\n\t// The next 4 bytes are left at 0 (version number).\n\tbuf = append(buf, uint8(destConnID.Len()))\n\tbuf = append(buf, destConnID.Bytes()...)\n\tbuf = append(buf, uint8(srcConnID.Len()))\n\tbuf = append(buf, srcConnID.Bytes()...)\n\tfor _, v := range greasedVersions {\n\t\tbuf = binary.BigEndian.AppendUint32(buf, uint32(v))\n\t}\n\treturn buf\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/logging/connection_tracer.go",
    "content": "package logging\n\nimport (\n\t\"net\"\n\t\"time\"\n)\n\n//go:generate go run generate_multiplexer.go ConnectionTracer connection_tracer.go multiplexer.tmpl connection_tracer_multiplexer.go\n\n// A ConnectionTracer records events.\ntype ConnectionTracer struct {\n\tStartedConnection                func(local, remote net.Addr, srcConnID, destConnID ConnectionID)\n\tNegotiatedVersion                func(chosen Version, clientVersions, serverVersions []Version)\n\tClosedConnection                 func(err error)\n\tSentTransportParameters          func(parameters *TransportParameters)\n\tReceivedTransportParameters      func(parameters *TransportParameters)\n\tRestoredTransportParameters      func(parameters *TransportParameters) // for 0-RTT\n\tSentLongHeaderPacket             func(hdr *ExtendedHeader, size ByteCount, ecn ECN, ack *AckFrame, frames []Frame)\n\tSentShortHeaderPacket            func(hdr *ShortHeader, size ByteCount, ecn ECN, ack *AckFrame, frames []Frame)\n\tReceivedVersionNegotiationPacket func(dest, src ArbitraryLenConnectionID, versions []Version)\n\tReceivedRetry                    func(hdr *Header)\n\tReceivedLongHeaderPacket         func(hdr *ExtendedHeader, size ByteCount, ecn ECN, frames []Frame)\n\tReceivedShortHeaderPacket        func(hdr *ShortHeader, size ByteCount, ecn ECN, frames []Frame)\n\tBufferedPacket                   func(packetType PacketType, size ByteCount)\n\tDroppedPacket                    func(packetType PacketType, pn PacketNumber, size ByteCount, reason PacketDropReason)\n\tUpdatedMetrics                   func(rttStats *RTTStats, cwnd, bytesInFlight ByteCount, packetsInFlight int)\n\tAcknowledgedPacket               func(encLevel EncryptionLevel, pn PacketNumber)\n\tLostPacket                       func(encLevel EncryptionLevel, pn PacketNumber, reason PacketLossReason)\n\tUpdatedMTU                       func(mtu ByteCount, done bool)\n\tUpdatedCongestionState           func(state CongestionState)\n\tUpdatedPTOCount                  func(value uint32)\n\tUpdatedKeyFromTLS                func(encLevel EncryptionLevel, p Perspective)\n\tUpdatedKey                       func(keyPhase KeyPhase, remote bool)\n\tDroppedEncryptionLevel           func(encLevel EncryptionLevel)\n\tDroppedKey                       func(keyPhase KeyPhase)\n\tSetLossTimer                     func(timerType TimerType, encLevel EncryptionLevel, time time.Time)\n\tLossTimerExpired                 func(timerType TimerType, encLevel EncryptionLevel)\n\tLossTimerCanceled                func()\n\tECNStateUpdated                  func(state ECNState, trigger ECNStateTrigger)\n\tChoseALPN                        func(protocol string)\n\t// Close is called when the connection is closed.\n\tClose func()\n\tDebug func(name, msg string)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/logging/connection_tracer_multiplexer.go",
    "content": "// Code generated by generate_multiplexer.go; DO NOT EDIT.\n\npackage logging\n\nimport (\n\t\"net\"\n\t\"time\"\n)\n\nfunc NewMultiplexedConnectionTracer(tracers ...*ConnectionTracer) *ConnectionTracer {\n\tif len(tracers) == 0 {\n\t\treturn nil\n\t}\n\tif len(tracers) == 1 {\n\t\treturn tracers[0]\n\t}\n\treturn &ConnectionTracer{\n\t\tStartedConnection: func(local net.Addr, remote net.Addr, srcConnID ConnectionID, destConnID ConnectionID) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.StartedConnection != nil {\n\t\t\t\t\tt.StartedConnection(local, remote, srcConnID, destConnID)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tNegotiatedVersion: func(chosen Version, clientVersions []Version, serverVersions []Version) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.NegotiatedVersion != nil {\n\t\t\t\t\tt.NegotiatedVersion(chosen, clientVersions, serverVersions)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tClosedConnection: func(err error) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.ClosedConnection != nil {\n\t\t\t\t\tt.ClosedConnection(err)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tSentTransportParameters: func(parameters *TransportParameters) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.SentTransportParameters != nil {\n\t\t\t\t\tt.SentTransportParameters(parameters)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tReceivedTransportParameters: func(parameters *TransportParameters) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.ReceivedTransportParameters != nil {\n\t\t\t\t\tt.ReceivedTransportParameters(parameters)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tRestoredTransportParameters: func(parameters *TransportParameters) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.RestoredTransportParameters != nil {\n\t\t\t\t\tt.RestoredTransportParameters(parameters)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tSentLongHeaderPacket: func(hdr *ExtendedHeader, size ByteCount, ecn ECN, ack *AckFrame, frames []Frame) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.SentLongHeaderPacket != nil {\n\t\t\t\t\tt.SentLongHeaderPacket(hdr, size, ecn, ack, frames)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tSentShortHeaderPacket: func(hdr *ShortHeader, size ByteCount, ecn ECN, ack *AckFrame, frames []Frame) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.SentShortHeaderPacket != nil {\n\t\t\t\t\tt.SentShortHeaderPacket(hdr, size, ecn, ack, frames)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tReceivedVersionNegotiationPacket: func(dest ArbitraryLenConnectionID, src ArbitraryLenConnectionID, versions []Version) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.ReceivedVersionNegotiationPacket != nil {\n\t\t\t\t\tt.ReceivedVersionNegotiationPacket(dest, src, versions)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tReceivedRetry: func(hdr *Header) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.ReceivedRetry != nil {\n\t\t\t\t\tt.ReceivedRetry(hdr)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tReceivedLongHeaderPacket: func(hdr *ExtendedHeader, size ByteCount, ecn ECN, frames []Frame) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.ReceivedLongHeaderPacket != nil {\n\t\t\t\t\tt.ReceivedLongHeaderPacket(hdr, size, ecn, frames)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tReceivedShortHeaderPacket: func(hdr *ShortHeader, size ByteCount, ecn ECN, frames []Frame) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.ReceivedShortHeaderPacket != nil {\n\t\t\t\t\tt.ReceivedShortHeaderPacket(hdr, size, ecn, frames)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tBufferedPacket: func(packetType PacketType, size ByteCount) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.BufferedPacket != nil {\n\t\t\t\t\tt.BufferedPacket(packetType, size)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tDroppedPacket: func(packetType PacketType, pn PacketNumber, size ByteCount, reason PacketDropReason) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.DroppedPacket != nil {\n\t\t\t\t\tt.DroppedPacket(packetType, pn, size, reason)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tUpdatedMetrics: func(rttStats *RTTStats, cwnd ByteCount, bytesInFlight ByteCount, packetsInFlight int) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.UpdatedMetrics != nil {\n\t\t\t\t\tt.UpdatedMetrics(rttStats, cwnd, bytesInFlight, packetsInFlight)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tAcknowledgedPacket: func(encLevel EncryptionLevel, pn PacketNumber) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.AcknowledgedPacket != nil {\n\t\t\t\t\tt.AcknowledgedPacket(encLevel, pn)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tLostPacket: func(encLevel EncryptionLevel, pn PacketNumber, reason PacketLossReason) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.LostPacket != nil {\n\t\t\t\t\tt.LostPacket(encLevel, pn, reason)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tUpdatedMTU: func(mtu ByteCount, done bool) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.UpdatedMTU != nil {\n\t\t\t\t\tt.UpdatedMTU(mtu, done)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tUpdatedCongestionState: func(state CongestionState) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.UpdatedCongestionState != nil {\n\t\t\t\t\tt.UpdatedCongestionState(state)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tUpdatedPTOCount: func(value uint32) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.UpdatedPTOCount != nil {\n\t\t\t\t\tt.UpdatedPTOCount(value)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tUpdatedKeyFromTLS: func(encLevel EncryptionLevel, p Perspective) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.UpdatedKeyFromTLS != nil {\n\t\t\t\t\tt.UpdatedKeyFromTLS(encLevel, p)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tUpdatedKey: func(keyPhase KeyPhase, remote bool) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.UpdatedKey != nil {\n\t\t\t\t\tt.UpdatedKey(keyPhase, remote)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tDroppedEncryptionLevel: func(encLevel EncryptionLevel) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.DroppedEncryptionLevel != nil {\n\t\t\t\t\tt.DroppedEncryptionLevel(encLevel)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tDroppedKey: func(keyPhase KeyPhase) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.DroppedKey != nil {\n\t\t\t\t\tt.DroppedKey(keyPhase)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tSetLossTimer: func(timerType TimerType, encLevel EncryptionLevel, time time.Time) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.SetLossTimer != nil {\n\t\t\t\t\tt.SetLossTimer(timerType, encLevel, time)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tLossTimerExpired: func(timerType TimerType, encLevel EncryptionLevel) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.LossTimerExpired != nil {\n\t\t\t\t\tt.LossTimerExpired(timerType, encLevel)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tLossTimerCanceled: func() {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.LossTimerCanceled != nil {\n\t\t\t\t\tt.LossTimerCanceled()\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tECNStateUpdated: func(state ECNState, trigger ECNStateTrigger) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.ECNStateUpdated != nil {\n\t\t\t\t\tt.ECNStateUpdated(state, trigger)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tChoseALPN: func(protocol string) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.ChoseALPN != nil {\n\t\t\t\t\tt.ChoseALPN(protocol)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tClose: func() {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.Close != nil {\n\t\t\t\t\tt.Close()\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tDebug: func(name string, msg string) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.Debug != nil {\n\t\t\t\t\tt.Debug(name, msg)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/logging/frame.go",
    "content": "package logging\n\nimport \"github.com/quic-go/quic-go/internal/wire\"\n\n// A Frame is a QUIC frame\ntype Frame interface{}\n\n// The AckRange is used within the AckFrame.\n// It is a range of packet numbers that is being acknowledged.\ntype AckRange = wire.AckRange\n\ntype (\n\t// An AckFrame is an ACK frame.\n\tAckFrame = wire.AckFrame\n\t// A ConnectionCloseFrame is a CONNECTION_CLOSE frame.\n\tConnectionCloseFrame = wire.ConnectionCloseFrame\n\t// A DataBlockedFrame is a DATA_BLOCKED frame.\n\tDataBlockedFrame = wire.DataBlockedFrame\n\t// A HandshakeDoneFrame is a HANDSHAKE_DONE frame.\n\tHandshakeDoneFrame = wire.HandshakeDoneFrame\n\t// A MaxDataFrame is a MAX_DATA frame.\n\tMaxDataFrame = wire.MaxDataFrame\n\t// A MaxStreamDataFrame is a MAX_STREAM_DATA frame.\n\tMaxStreamDataFrame = wire.MaxStreamDataFrame\n\t// A MaxStreamsFrame is a MAX_STREAMS_FRAME.\n\tMaxStreamsFrame = wire.MaxStreamsFrame\n\t// A NewConnectionIDFrame is a NEW_CONNECTION_ID frame.\n\tNewConnectionIDFrame = wire.NewConnectionIDFrame\n\t// A NewTokenFrame is a NEW_TOKEN frame.\n\tNewTokenFrame = wire.NewTokenFrame\n\t// A PathChallengeFrame is a PATH_CHALLENGE frame.\n\tPathChallengeFrame = wire.PathChallengeFrame\n\t// A PathResponseFrame is a PATH_RESPONSE frame.\n\tPathResponseFrame = wire.PathResponseFrame\n\t// A PingFrame is a PING frame.\n\tPingFrame = wire.PingFrame\n\t// A ResetStreamFrame is a RESET_STREAM frame.\n\tResetStreamFrame = wire.ResetStreamFrame\n\t// A RetireConnectionIDFrame is a RETIRE_CONNECTION_ID frame.\n\tRetireConnectionIDFrame = wire.RetireConnectionIDFrame\n\t// A StopSendingFrame is a STOP_SENDING frame.\n\tStopSendingFrame = wire.StopSendingFrame\n\t// A StreamsBlockedFrame is a STREAMS_BLOCKED frame.\n\tStreamsBlockedFrame = wire.StreamsBlockedFrame\n\t// A StreamDataBlockedFrame is a STREAM_DATA_BLOCKED frame.\n\tStreamDataBlockedFrame = wire.StreamDataBlockedFrame\n)\n\n// A CryptoFrame is a CRYPTO frame.\ntype CryptoFrame struct {\n\tOffset ByteCount\n\tLength ByteCount\n}\n\n// A StreamFrame is a STREAM frame.\ntype StreamFrame struct {\n\tStreamID StreamID\n\tOffset   ByteCount\n\tLength   ByteCount\n\tFin      bool\n}\n\n// A DatagramFrame is a DATAGRAM frame.\ntype DatagramFrame struct {\n\tLength ByteCount\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/logging/generate_multiplexer.go",
    "content": "//go:build generate\n\npackage main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"go/ast\"\n\t\"go/parser\"\n\t\"go/printer\"\n\t\"go/token\"\n\t\"log\"\n\t\"os\"\n\t\"strings\"\n\t\"text/template\"\n\n\t\"golang.org/x/tools/imports\"\n)\n\nfunc main() {\n\tif len(os.Args) != 5 {\n\t\tlog.Fatalf(\"Usage: %s <struct_name> <input_file> <template_file> <output_file>\", os.Args[0])\n\t}\n\n\tstructName := os.Args[1]\n\tinputFile := os.Args[2]\n\ttemplateFile := os.Args[3]\n\toutputFile := os.Args[4]\n\n\tfset := token.NewFileSet()\n\n\t// Parse the input file containing the struct type\n\tfile, err := parser.ParseFile(fset, inputFile, nil, parser.AllErrors)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to parse file: %v\", err)\n\t}\n\n\tvar fields []*ast.Field\n\n\t// Find the specified struct type in the AST\n\tfor _, decl := range file.Decls {\n\t\tgenDecl, ok := decl.(*ast.GenDecl)\n\t\tif !ok || genDecl.Tok != token.TYPE {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, spec := range genDecl.Specs {\n\t\t\ttypeSpec, ok := spec.(*ast.TypeSpec)\n\t\t\tif !ok || typeSpec.Name.Name != structName {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tstructType, ok := typeSpec.Type.(*ast.StructType)\n\t\t\tif !ok {\n\t\t\t\tlog.Fatalf(\"%s is not a struct\", structName)\n\t\t\t}\n\t\t\tfields = structType.Fields.List\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif fields == nil {\n\t\tlog.Fatalf(\"Could not find %s type\", structName)\n\t}\n\n\t// Prepare data for the template\n\ttype FieldData struct {\n\t\tName        string\n\t\tParams      string\n\t\tArgs        string\n\t\tHasParams   bool\n\t\tReturnTypes string\n\t\tHasReturn   bool\n\t}\n\n\tvar fieldDataList []FieldData\n\n\tfor _, field := range fields {\n\t\tfuncType, ok := field.Type.(*ast.FuncType)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, name := range field.Names {\n\t\t\tfieldData := FieldData{Name: name.Name}\n\n\t\t\t// extract parameters\n\t\t\tvar params []string\n\t\t\tvar args []string\n\t\t\tif funcType.Params != nil {\n\t\t\t\tfor i, param := range funcType.Params.List {\n\t\t\t\t\t// We intentionally reject unnamed (and, further down, \"_\") function parameters.\n\t\t\t\t\t// We could auto-generate parameter names,\n\t\t\t\t\t// but having meaningful variable names will be more helpful for the user.\n\t\t\t\t\tif len(param.Names) == 0 {\n\t\t\t\t\t\tlog.Fatalf(\"encountered unnamed parameter at position %d in function %s\", i, fieldData.Name)\n\t\t\t\t\t}\n\t\t\t\t\tvar buf bytes.Buffer\n\t\t\t\t\tprinter.Fprint(&buf, fset, param.Type)\n\t\t\t\t\tparamType := buf.String()\n\t\t\t\t\tfor _, paramName := range param.Names {\n\t\t\t\t\t\tif paramName.Name == \"_\" {\n\t\t\t\t\t\t\tlog.Fatalf(\"encountered underscore parameter at position %d in function %s\", i, fieldData.Name)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparams = append(params, fmt.Sprintf(\"%s %s\", paramName.Name, paramType))\n\t\t\t\t\t\targs = append(args, paramName.Name)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tfieldData.Params = strings.Join(params, \", \")\n\t\t\tfieldData.Args = strings.Join(args, \", \")\n\t\t\tfieldData.HasParams = len(params) > 0\n\n\t\t\t// extract return types\n\t\t\tif funcType.Results != nil && len(funcType.Results.List) > 0 {\n\t\t\t\tfieldData.HasReturn = true\n\t\t\t\tvar returns []string\n\t\t\t\tfor _, result := range funcType.Results.List {\n\t\t\t\t\tvar buf bytes.Buffer\n\t\t\t\t\tprinter.Fprint(&buf, fset, result.Type)\n\t\t\t\t\treturns = append(returns, buf.String())\n\t\t\t\t}\n\t\t\t\tif len(returns) == 1 {\n\t\t\t\t\tfieldData.ReturnTypes = fmt.Sprintf(\" %s\", returns[0])\n\t\t\t\t} else {\n\t\t\t\t\tfieldData.ReturnTypes = fmt.Sprintf(\" (%s)\", strings.Join(returns, \", \"))\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfieldDataList = append(fieldDataList, fieldData)\n\t\t}\n\t}\n\n\t// Read the template from file\n\ttemplateContent, err := os.ReadFile(templateFile)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to read template file: %v\", err)\n\t}\n\n\t// Generate the code using the template\n\ttmpl, err := template.New(\"multiplexer\").Funcs(template.FuncMap{\"join\": strings.Join}).Parse(string(templateContent))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to parse template: %v\", err)\n\t}\n\n\tvar generatedCode bytes.Buffer\n\tgeneratedCode.WriteString(\"// Code generated by generate_multiplexer.go; DO NOT EDIT.\\n\\n\")\n\tif err = tmpl.Execute(&generatedCode, map[string]interface{}{\n\t\t\"Fields\":     fieldDataList,\n\t\t\"StructName\": structName,\n\t}); err != nil {\n\t\tlog.Fatalf(\"Failed to execute template: %v\", err)\n\t}\n\n\t// Format the generated code and add imports\n\tformattedCode, err := imports.Process(outputFile, generatedCode.Bytes(), nil)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to process imports: %v\", err)\n\t}\n\n\tif err := os.WriteFile(outputFile, formattedCode, 0o644); err != nil {\n\t\tlog.Fatalf(\"Failed to write output file: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/logging/interface.go",
    "content": "// Package logging defines a logging interface for quic-go.\n// This package should not be considered stable\npackage logging\n\nimport (\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\ntype (\n\t// A ByteCount is used to count bytes.\n\tByteCount = protocol.ByteCount\n\t// ECN is the ECN value\n\tECN = protocol.ECN\n\t// A ConnectionID is a QUIC Connection ID.\n\tConnectionID = protocol.ConnectionID\n\t// An ArbitraryLenConnectionID is a QUIC Connection ID that can be up to 255 bytes long.\n\tArbitraryLenConnectionID = protocol.ArbitraryLenConnectionID\n\t// The EncryptionLevel is the encryption level of a packet.\n\tEncryptionLevel = protocol.EncryptionLevel\n\t// The KeyPhase is the key phase of the 1-RTT keys.\n\tKeyPhase = protocol.KeyPhase\n\t// The KeyPhaseBit is the value of the key phase bit of the 1-RTT packets.\n\tKeyPhaseBit = protocol.KeyPhaseBit\n\t// The PacketNumber is the packet number of a packet.\n\tPacketNumber = protocol.PacketNumber\n\t// The Perspective is the role of a QUIC endpoint (client or server).\n\tPerspective = protocol.Perspective\n\t// A StatelessResetToken is a stateless reset token.\n\tStatelessResetToken = protocol.StatelessResetToken\n\t// The StreamID is the stream ID.\n\tStreamID = protocol.StreamID\n\t// The StreamNum is the number of the stream.\n\tStreamNum = protocol.StreamNum\n\t// The StreamType is the type of the stream (unidirectional or bidirectional).\n\tStreamType = protocol.StreamType\n\t// The Version is the QUIC version.\n\tVersion = protocol.Version\n\n\t// The Header is the QUIC packet header, before removing header protection.\n\tHeader = wire.Header\n\t// The ExtendedHeader is the QUIC Long Header packet header, after removing header protection.\n\tExtendedHeader = wire.ExtendedHeader\n\t// The TransportParameters are QUIC transport parameters.\n\tTransportParameters = wire.TransportParameters\n\t// The PreferredAddress is the preferred address sent in the transport parameters.\n\tPreferredAddress = wire.PreferredAddress\n\n\t// A TransportError is a transport-level error code.\n\tTransportError = qerr.TransportErrorCode\n\t// An ApplicationError is an application-defined error code.\n\tApplicationError = qerr.TransportErrorCode\n\n\t// The RTTStats contain statistics used by the congestion controller.\n\tRTTStats = utils.RTTStats\n)\n\nconst (\n\t// ECNUnsupported means that no ECN value was set / received\n\tECNUnsupported = protocol.ECNUnsupported\n\t// ECTNot is Not-ECT\n\tECTNot = protocol.ECNNon\n\t// ECT0 is ECT(0)\n\tECT0 = protocol.ECT0\n\t// ECT1 is ECT(1)\n\tECT1 = protocol.ECT1\n\t// ECNCE is CE\n\tECNCE = protocol.ECNCE\n)\n\nconst (\n\t// KeyPhaseZero is key phase bit 0\n\tKeyPhaseZero = protocol.KeyPhaseZero\n\t// KeyPhaseOne is key phase bit 1\n\tKeyPhaseOne = protocol.KeyPhaseOne\n)\n\nconst (\n\t// PerspectiveServer is used for a QUIC server\n\tPerspectiveServer = protocol.PerspectiveServer\n\t// PerspectiveClient is used for a QUIC client\n\tPerspectiveClient = protocol.PerspectiveClient\n)\n\nconst (\n\t// EncryptionInitial is the Initial encryption level\n\tEncryptionInitial = protocol.EncryptionInitial\n\t// EncryptionHandshake is the Handshake encryption level\n\tEncryptionHandshake = protocol.EncryptionHandshake\n\t// Encryption1RTT is the 1-RTT encryption level\n\tEncryption1RTT = protocol.Encryption1RTT\n\t// Encryption0RTT is the 0-RTT encryption level\n\tEncryption0RTT = protocol.Encryption0RTT\n)\n\nconst (\n\t// StreamTypeUni is a unidirectional stream\n\tStreamTypeUni = protocol.StreamTypeUni\n\t// StreamTypeBidi is a bidirectional stream\n\tStreamTypeBidi = protocol.StreamTypeBidi\n)\n\n// The ShortHeader is the QUIC Short Header packet header, after removing header protection.\ntype ShortHeader struct {\n\tDestConnectionID ConnectionID\n\tPacketNumber     PacketNumber\n\tPacketNumberLen  protocol.PacketNumberLen\n\tKeyPhase         KeyPhaseBit\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/logging/multiplexer.tmpl",
    "content": "package logging\n\nfunc NewMultiplexed{{ .StructName }} (tracers ...*{{ .StructName }}) *{{ .StructName }} {\n    if len(tracers) == 0 {\n        return nil\n    }\n    if len(tracers) == 1 {\n        return tracers[0]\n    }\n    return &{{ .StructName }}{\n        {{- range .Fields }}\n        {{ .Name }}: func({{ .Params }}){{ .ReturnTypes }} {\n            for _, t := range tracers {\n                if t.{{ .Name }} != nil {\n                    t.{{ .Name }}({{ .Args }})\n                }\n            }\n        },\n        {{- end }}\n    }\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/logging/packet_header.go",
    "content": "package logging\n\nimport (\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\n// PacketTypeFromHeader determines the packet type from a *wire.Header.\nfunc PacketTypeFromHeader(hdr *Header) PacketType {\n\tif hdr.Version == 0 {\n\t\treturn PacketTypeVersionNegotiation\n\t}\n\tswitch hdr.Type {\n\tcase protocol.PacketTypeInitial:\n\t\treturn PacketTypeInitial\n\tcase protocol.PacketTypeHandshake:\n\t\treturn PacketTypeHandshake\n\tcase protocol.PacketType0RTT:\n\t\treturn PacketType0RTT\n\tcase protocol.PacketTypeRetry:\n\t\treturn PacketTypeRetry\n\tdefault:\n\t\treturn PacketTypeNotDetermined\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/logging/tracer.go",
    "content": "package logging\n\nimport \"net\"\n\n//go:generate go run generate_multiplexer.go Tracer tracer.go multiplexer.tmpl tracer_multiplexer.go\n\n// A Tracer traces events.\ntype Tracer struct {\n\tSentPacket                   func(dest net.Addr, hdr *Header, size ByteCount, frames []Frame)\n\tSentVersionNegotiationPacket func(dest net.Addr, destConnID, srcConnID ArbitraryLenConnectionID, versions []Version)\n\tDroppedPacket                func(addr net.Addr, packetType PacketType, size ByteCount, reason PacketDropReason)\n\tDebug                        func(name, msg string)\n\tClose                        func()\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/logging/tracer_multiplexer.go",
    "content": "// Code generated by generate_multiplexer.go; DO NOT EDIT.\n\npackage logging\n\nimport \"net\"\n\nfunc NewMultiplexedTracer(tracers ...*Tracer) *Tracer {\n\tif len(tracers) == 0 {\n\t\treturn nil\n\t}\n\tif len(tracers) == 1 {\n\t\treturn tracers[0]\n\t}\n\treturn &Tracer{\n\t\tSentPacket: func(dest net.Addr, hdr *Header, size ByteCount, frames []Frame) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.SentPacket != nil {\n\t\t\t\t\tt.SentPacket(dest, hdr, size, frames)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tSentVersionNegotiationPacket: func(dest net.Addr, destConnID ArbitraryLenConnectionID, srcConnID ArbitraryLenConnectionID, versions []Version) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.SentVersionNegotiationPacket != nil {\n\t\t\t\t\tt.SentVersionNegotiationPacket(dest, destConnID, srcConnID, versions)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tDroppedPacket: func(addr net.Addr, packetType PacketType, size ByteCount, reason PacketDropReason) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.DroppedPacket != nil {\n\t\t\t\t\tt.DroppedPacket(addr, packetType, size, reason)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tDebug: func(name string, msg string) {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.Debug != nil {\n\t\t\t\t\tt.Debug(name, msg)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tClose: func() {\n\t\t\tfor _, t := range tracers {\n\t\t\t\tif t.Close != nil {\n\t\t\t\t\tt.Close()\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/logging/types.go",
    "content": "package logging\n\n// PacketType is the packet type of a QUIC packet\ntype PacketType uint8\n\nconst (\n\t// PacketTypeInitial is the packet type of an Initial packet\n\tPacketTypeInitial PacketType = iota\n\t// PacketTypeHandshake is the packet type of a Handshake packet\n\tPacketTypeHandshake\n\t// PacketTypeRetry is the packet type of a Retry packet\n\tPacketTypeRetry\n\t// PacketType0RTT is the packet type of a 0-RTT packet\n\tPacketType0RTT\n\t// PacketTypeVersionNegotiation is the packet type of a Version Negotiation packet\n\tPacketTypeVersionNegotiation\n\t// PacketType1RTT is a 1-RTT packet\n\tPacketType1RTT\n\t// PacketTypeStatelessReset is a stateless reset\n\tPacketTypeStatelessReset\n\t// PacketTypeNotDetermined is the packet type when it could not be determined\n\tPacketTypeNotDetermined\n)\n\ntype PacketLossReason uint8\n\nconst (\n\t// PacketLossReorderingThreshold: when a packet is deemed lost due to reordering threshold\n\tPacketLossReorderingThreshold PacketLossReason = iota\n\t// PacketLossTimeThreshold: when a packet is deemed lost due to time threshold\n\tPacketLossTimeThreshold\n)\n\ntype PacketDropReason uint8\n\nconst (\n\t// PacketDropKeyUnavailable is used when a packet is dropped because keys are unavailable\n\tPacketDropKeyUnavailable PacketDropReason = iota\n\t// PacketDropUnknownConnectionID is used when a packet is dropped because the connection ID is unknown\n\tPacketDropUnknownConnectionID\n\t// PacketDropHeaderParseError is used when a packet is dropped because header parsing failed\n\tPacketDropHeaderParseError\n\t// PacketDropPayloadDecryptError is used when a packet is dropped because decrypting the payload failed\n\tPacketDropPayloadDecryptError\n\t// PacketDropProtocolViolation is used when a packet is dropped due to a protocol violation\n\tPacketDropProtocolViolation\n\t// PacketDropDOSPrevention is used when a packet is dropped to mitigate a DoS attack\n\tPacketDropDOSPrevention\n\t// PacketDropUnsupportedVersion is used when a packet is dropped because the version is not supported\n\tPacketDropUnsupportedVersion\n\t// PacketDropUnexpectedPacket is used when an unexpected packet is received\n\tPacketDropUnexpectedPacket\n\t// PacketDropUnexpectedSourceConnectionID is used when a packet with an unexpected source connection ID is received\n\tPacketDropUnexpectedSourceConnectionID\n\t// PacketDropUnexpectedVersion is used when a packet with an unexpected version is received\n\tPacketDropUnexpectedVersion\n\t// PacketDropDuplicate is used when a duplicate packet is received\n\tPacketDropDuplicate\n)\n\n// TimerType is the type of the loss detection timer\ntype TimerType uint8\n\nconst (\n\t// TimerTypeACK is the timer type for the early retransmit timer\n\tTimerTypeACK TimerType = iota + 1\n\t// TimerTypePTO is the timer type for the PTO retransmit timer\n\tTimerTypePTO\n\t// TimerTypePathProbe is the timer type for the path probe retransmit timer\n\tTimerTypePathProbe\n)\n\n// TimeoutReason is the reason why a connection is closed\ntype TimeoutReason uint8\n\nconst (\n\t// TimeoutReasonHandshake is used when the connection is closed due to a handshake timeout\n\t// This reason is not defined in the qlog draft, but very useful for debugging.\n\tTimeoutReasonHandshake TimeoutReason = iota\n\t// TimeoutReasonIdle is used when the connection is closed due to an idle timeout\n\t// This reason is not defined in the qlog draft, but very useful for debugging.\n\tTimeoutReasonIdle\n)\n\ntype CongestionState uint8\n\nconst (\n\t// CongestionStateSlowStart is the slow start phase of Reno / Cubic\n\tCongestionStateSlowStart CongestionState = iota\n\t// CongestionStateCongestionAvoidance is the slow start phase of Reno / Cubic\n\tCongestionStateCongestionAvoidance\n\t// CongestionStateRecovery is the recovery phase of Reno / Cubic\n\tCongestionStateRecovery\n\t// CongestionStateApplicationLimited means that the congestion controller is application limited\n\tCongestionStateApplicationLimited\n)\n\n// ECNState is the state of the ECN state machine (see Appendix A.4 of RFC 9000)\ntype ECNState uint8\n\nconst (\n\t// ECNStateTesting is the testing state\n\tECNStateTesting ECNState = 1 + iota\n\t// ECNStateUnknown is the unknown state\n\tECNStateUnknown\n\t// ECNStateFailed is the failed state\n\tECNStateFailed\n\t// ECNStateCapable is the capable state\n\tECNStateCapable\n)\n\n// ECNStateTrigger is a trigger for an ECN state transition.\ntype ECNStateTrigger uint8\n\nconst (\n\tECNTriggerNoTrigger ECNStateTrigger = iota\n\t// ECNFailedNoECNCounts is emitted when an ACK acknowledges ECN-marked packets,\n\t// but doesn't contain any ECN counts\n\tECNFailedNoECNCounts\n\t// ECNFailedDecreasedECNCounts is emitted when an ACK frame decreases ECN counts\n\tECNFailedDecreasedECNCounts\n\t// ECNFailedLostAllTestingPackets is emitted when all ECN testing packets are declared lost\n\tECNFailedLostAllTestingPackets\n\t// ECNFailedMoreECNCountsThanSent is emitted when an ACK contains more ECN counts than ECN-marked packets were sent\n\tECNFailedMoreECNCountsThanSent\n\t// ECNFailedTooFewECNCounts is emitted when an ACK contains fewer ECN counts than it acknowledges packets\n\tECNFailedTooFewECNCounts\n\t// ECNFailedManglingDetected is emitted when the path marks all ECN-marked packets as CE\n\tECNFailedManglingDetected\n)\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/mockgen.go",
    "content": "//go:build gomock || generate\n\npackage quic\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_send_conn_test.go github.com/quic-go/quic-go SendConn\"\ntype SendConn = sendConn\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_raw_conn_test.go github.com/quic-go/quic-go RawConn\"\ntype RawConn = rawConn\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_sender_test.go github.com/quic-go/quic-go Sender\"\ntype Sender = sender\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_internal_test.go github.com/quic-go/quic-go StreamI\"\ntype StreamI = streamI\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_receive_stream_internal_test.go github.com/quic-go/quic-go ReceiveStreamI\"\ntype ReceiveStreamI = receiveStreamI\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_send_stream_internal_test.go github.com/quic-go/quic-go SendStreamI\"\ntype SendStreamI = sendStreamI\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_sender_test.go github.com/quic-go/quic-go StreamSender\"\ntype StreamSender = streamSender\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_control_frame_getter_test.go github.com/quic-go/quic-go StreamControlFrameGetter\"\ntype StreamControlFrameGetter = streamControlFrameGetter\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_frame_source_test.go github.com/quic-go/quic-go FrameSource\"\ntype FrameSource = frameSource\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_ack_frame_source_test.go github.com/quic-go/quic-go AckFrameSource\"\ntype AckFrameSource = ackFrameSource\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_stream_manager_test.go github.com/quic-go/quic-go StreamManager\"\ntype StreamManager = streamManager\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_sealing_manager_test.go github.com/quic-go/quic-go SealingManager\"\ntype SealingManager = sealingManager\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_unpacker_test.go github.com/quic-go/quic-go Unpacker\"\ntype Unpacker = unpacker\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packer_test.go github.com/quic-go/quic-go Packer\"\ntype Packer = packer\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_mtu_discoverer_test.go github.com/quic-go/quic-go MTUDiscoverer\"\ntype MTUDiscoverer = mtuDiscoverer\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_conn_runner_test.go github.com/quic-go/quic-go ConnRunner\"\ntype ConnRunner = connRunner\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_quic_conn_test.go github.com/quic-go/quic-go QUICConn\"\ntype QUICConn = quicConn\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_test.go github.com/quic-go/quic-go PacketHandler\"\ntype PacketHandler = packetHandler\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_manager_test.go github.com/quic-go/quic-go PacketHandlerManager\"\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -build_flags=\\\"-tags=gomock\\\" -package quic -self_package github.com/quic-go/quic-go -destination mock_packet_handler_manager_test.go github.com/quic-go/quic-go PacketHandlerManager\"\ntype PacketHandlerManager = packetHandlerManager\n\n//go:generate sh -c \"go run go.uber.org/mock/mockgen -typed -package quic -self_package github.com/quic-go/quic-go -self_package github.com/quic-go/quic-go -destination mock_packetconn_test.go net PacketConn\"\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/mtu_discoverer.go",
    "content": "package quic\n\nimport (\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/ackhandler\"\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n\t\"github.com/quic-go/quic-go/logging\"\n)\n\ntype mtuDiscoverer interface {\n\t// Start starts the MTU discovery process.\n\t// It's unnecessary to call ShouldSendProbe before that.\n\tStart(now time.Time)\n\tShouldSendProbe(now time.Time) bool\n\tCurrentSize() protocol.ByteCount\n\tGetPing(now time.Time) (ping ackhandler.Frame, datagramSize protocol.ByteCount)\n\tReset(now time.Time, start, max protocol.ByteCount)\n}\n\nconst (\n\t// At some point, we have to stop searching for a higher MTU.\n\t// We're happy to send a packet that's 10 bytes smaller than the actual MTU.\n\tmaxMTUDiff protocol.ByteCount = 20\n\t// send a probe packet every mtuProbeDelay RTTs\n\tmtuProbeDelay = 5\n\t// Once maxLostMTUProbes MTU probe packets larger than a certain size are lost,\n\t// MTU discovery won't probe for larger MTUs than this size.\n\t// The algorithm used here is resilient to packet loss of (maxLostMTUProbes - 1) packets.\n\tmaxLostMTUProbes = 3\n)\n\n// The Path MTU is found by sending a larger packet every now and then.\n// If the packet is acknowledged, we conclude that the path supports this larger packet size.\n// If the packet is lost, this can mean one of two things:\n//   1. The path doesn't support this larger packet size, or\n//   2. The packet was lost due to packet loss, independent of its size.\n// The algorithm used here is resilient to packet loss of (maxLostMTUProbes - 1) packets.\n// For simplicty, the following example use maxLostMTUProbes = 2.\n//\n// Initialization:\n//    |------------------------------------------------------------------------------|\n//   min                                                                            max\n//\n// The first MTU probe packet will have size (min+max)/2.\n// Assume that this packet is acknowledged. We can now move the min marker,\n// and continue the search in the resulting interval.\n//\n// If 1st probe packet acknowledged:\n//    |---------------------------------------|--------------------------------------|\n//                                           min                                    max\n//\n// If 1st probe packet lost:\n//    |---------------------------------------|--------------------------------------|\n//   min                                    lost[0]                                 max\n//\n// We can't conclude that the path doesn't support this packet size, since the loss of the probe\n// packet could have been unrelated to the packet size.  A larger probe packet will be sent later on.\n// After a loss, the next probe packet has size (min+lost[0])/2.\n// Now assume this probe packet is acknowledged:\n//\n// 2nd probe packet acknowledged:\n//    |------------------|--------------------|--------------------------------------|\n//                      min                lost[0]                                  max\n//\n// First of all, we conclude that the path supports at least this MTU. That's progress!\n// Second, we probe a bit more aggressively with the next probe packet:\n// After an acknowledgement, the next probe packet has size (min+max)/2.\n// This means we'll send a packet larger than the first probe packet (which was lost).\n//\n// If 3rd probe packet acknowledged:\n//    |-------------------------------------------------|----------------------------|\n//                                                     min                          max\n//\n// We can conclude that the loss of the 1st probe packet was not due to its size, and\n// continue searching in a much smaller interval now.\n//\n// If 3rd probe packet lost:\n//    |------------------|--------------------|---------|----------------------------|\n//                      min                lost[0]     max\n//\n// Since in our example numPTOProbes = 2, and we lost 2 packets smaller than max, we\n// conclude that this packet size is not supported on the path, and reduce the maximum\n// value of the search interval.\n//\n// MTU discovery concludes once the interval min and max has been narrowed down to maxMTUDiff.\n\ntype mtuFinder struct {\n\tlastProbeTime time.Time\n\n\trttStats *utils.RTTStats\n\n\tinFlight protocol.ByteCount // the size of the probe packet currently in flight. InvalidByteCount if none is in flight\n\tmin      protocol.ByteCount\n\n\t// on initialization, we treat the maximum size as the first \"lost\" packet\n\tlost             [maxLostMTUProbes]protocol.ByteCount\n\tlastProbeWasLost bool\n\n\t// The generation is used to ignore ACKs / losses for probe packets sent before a reset.\n\t// Resets happen when the connection is migrated to a new path.\n\t// We're therefore not concerned about overflows of this counter.\n\tgeneration uint8\n\n\ttracer *logging.ConnectionTracer\n}\n\nvar _ mtuDiscoverer = &mtuFinder{}\n\nfunc newMTUDiscoverer(\n\trttStats *utils.RTTStats,\n\tstart, max protocol.ByteCount,\n\ttracer *logging.ConnectionTracer,\n) *mtuFinder {\n\tf := &mtuFinder{\n\t\tinFlight: protocol.InvalidByteCount,\n\t\trttStats: rttStats,\n\t\ttracer:   tracer,\n\t}\n\tf.init(start, max)\n\treturn f\n}\n\nfunc (f *mtuFinder) init(start, max protocol.ByteCount) {\n\tf.min = start\n\tfor i := range f.lost {\n\t\tif i == 0 {\n\t\t\tf.lost[i] = max\n\t\t\tcontinue\n\t\t}\n\t\tf.lost[i] = protocol.InvalidByteCount\n\t}\n}\n\nfunc (f *mtuFinder) done() bool {\n\treturn f.max()-f.min <= maxMTUDiff+1\n}\n\nfunc (f *mtuFinder) max() protocol.ByteCount {\n\tfor i, v := range f.lost {\n\t\tif v == protocol.InvalidByteCount {\n\t\t\treturn f.lost[i-1]\n\t\t}\n\t}\n\treturn f.lost[len(f.lost)-1]\n}\n\nfunc (f *mtuFinder) Start(now time.Time) {\n\tf.lastProbeTime = now // makes sure the first probe packet is not sent immediately\n}\n\nfunc (f *mtuFinder) ShouldSendProbe(now time.Time) bool {\n\tif f.lastProbeTime.IsZero() {\n\t\treturn false\n\t}\n\tif f.inFlight != protocol.InvalidByteCount || f.done() {\n\t\treturn false\n\t}\n\treturn !now.Before(f.lastProbeTime.Add(mtuProbeDelay * f.rttStats.SmoothedRTT()))\n}\n\nfunc (f *mtuFinder) GetPing(now time.Time) (ackhandler.Frame, protocol.ByteCount) {\n\tvar size protocol.ByteCount\n\tif f.lastProbeWasLost {\n\t\tsize = (f.min + f.lost[0]) / 2\n\t} else {\n\t\tsize = (f.min + f.max()) / 2\n\t}\n\tf.lastProbeTime = now\n\tf.inFlight = size\n\treturn ackhandler.Frame{\n\t\tFrame:   &wire.PingFrame{},\n\t\tHandler: &mtuFinderAckHandler{mtuFinder: f, generation: f.generation},\n\t}, size\n}\n\nfunc (f *mtuFinder) CurrentSize() protocol.ByteCount {\n\treturn f.min\n}\n\nfunc (f *mtuFinder) Reset(now time.Time, start, max protocol.ByteCount) {\n\tf.generation++\n\tf.lastProbeTime = now\n\tf.lastProbeWasLost = false\n\tf.inFlight = protocol.InvalidByteCount\n\tf.init(start, max)\n}\n\ntype mtuFinderAckHandler struct {\n\t*mtuFinder\n\tgeneration uint8\n}\n\nvar _ ackhandler.FrameHandler = &mtuFinderAckHandler{}\n\nfunc (h *mtuFinderAckHandler) OnAcked(wire.Frame) {\n\tif h.generation != h.mtuFinder.generation {\n\t\t// ACK for probe sent before reset\n\t\treturn\n\t}\n\tsize := h.inFlight\n\tif size == protocol.InvalidByteCount {\n\t\tpanic(\"OnAcked callback called although there's no MTU probe packet in flight\")\n\t}\n\th.inFlight = protocol.InvalidByteCount\n\th.min = size\n\th.lastProbeWasLost = false\n\t// remove all values smaller than size from the lost array\n\tvar j int\n\tfor i, v := range h.lost {\n\t\tif size < v {\n\t\t\tj = i\n\t\t\tbreak\n\t\t}\n\t}\n\tif j > 0 {\n\t\tfor i := 0; i < len(h.lost); i++ {\n\t\t\tif i+j < len(h.lost) {\n\t\t\t\th.lost[i] = h.lost[i+j]\n\t\t\t} else {\n\t\t\t\th.lost[i] = protocol.InvalidByteCount\n\t\t\t}\n\t\t}\n\t}\n\tif h.tracer != nil && h.tracer.UpdatedMTU != nil {\n\t\th.tracer.UpdatedMTU(size, h.done())\n\t}\n}\n\nfunc (h *mtuFinderAckHandler) OnLost(wire.Frame) {\n\tif h.generation != h.mtuFinder.generation {\n\t\t// probe sent before reset received\n\t\treturn\n\t}\n\tsize := h.inFlight\n\tif size == protocol.InvalidByteCount {\n\t\tpanic(\"OnLost callback called although there's no MTU probe packet in flight\")\n\t}\n\th.lastProbeWasLost = true\n\th.inFlight = protocol.InvalidByteCount\n\tfor i, v := range h.lost {\n\t\tif size < v {\n\t\t\tcopy(h.lost[i+1:], h.lost[i:])\n\t\t\th.lost[i] = size\n\t\t\tbreak\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/oss-fuzz.sh",
    "content": "#!/bin/bash\n\n# Install Go manually, since oss-fuzz ships with an outdated Go version.\n# See https://github.com/google/oss-fuzz/pull/10643.\nexport CXX=\"${CXX} -lresolv\" # required by Go 1.20\nwget https://go.dev/dl/go1.23.0.linux-amd64.tar.gz \\\n  && mkdir temp-go \\\n  && rm -rf /root/.go/* \\\n  && tar -C temp-go/ -xzf go1.23.0.linux-amd64.tar.gz \\\n  && mv temp-go/go/* /root/.go/ \\\n  && rm -rf temp-go go1.23.0.linux-amd64.tar.gz\n\n(\n# fuzz qpack\ncompile_go_fuzzer github.com/quic-go/qpack/fuzzing Fuzz qpack_fuzzer\n)\n\n(\n# fuzz quic-go\ncompile_go_fuzzer github.com/quic-go/quic-go/fuzzing/frames Fuzz frame_fuzzer\ncompile_go_fuzzer github.com/quic-go/quic-go/fuzzing/header Fuzz header_fuzzer\ncompile_go_fuzzer github.com/quic-go/quic-go/fuzzing/transportparameters Fuzz transportparameter_fuzzer\ncompile_go_fuzzer github.com/quic-go/quic-go/fuzzing/tokens Fuzz token_fuzzer\ncompile_go_fuzzer github.com/quic-go/quic-go/fuzzing/handshake Fuzz handshake_fuzzer\n\nif [ $SANITIZER == \"coverage\" ]; then\n    # no need for corpora if coverage\n    exit 0\nfi\n\n# generate seed corpora\ncd $GOPATH/src/github.com/quic-go/quic-go/\ngo generate -x ./fuzzing/...\n\nzip --quiet -r $OUT/header_fuzzer_seed_corpus.zip fuzzing/header/corpus\nzip --quiet -r $OUT/frame_fuzzer_seed_corpus.zip fuzzing/frames/corpus\nzip --quiet -r $OUT/transportparameter_fuzzer_seed_corpus.zip fuzzing/transportparameters/corpus\nzip --quiet -r $OUT/handshake_fuzzer_seed_corpus.zip fuzzing/handshake/corpus\n)\n\n# for debugging\nls -al $OUT\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/packet_handler_map.go",
    "content": "package quic\n\nimport (\n\t\"io\"\n\t\"net\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n)\n\ntype connCapabilities struct {\n\t// This connection has the Don't Fragment (DF) bit set.\n\t// This means it makes to run DPLPMTUD.\n\tDF bool\n\t// GSO (Generic Segmentation Offload) supported\n\tGSO bool\n\t// ECN (Explicit Congestion Notifications) supported\n\tECN bool\n}\n\n// rawConn is a connection that allow reading of a receivedPackeh.\ntype rawConn interface {\n\tReadPacket() (receivedPacket, error)\n\t// WritePacket writes a packet on the wire.\n\t// gsoSize is the size of a single packet, or 0 to disable GSO.\n\t// It is invalid to set gsoSize if capabilities.GSO is not set.\n\tWritePacket(b []byte, addr net.Addr, packetInfoOOB []byte, gsoSize uint16, ecn protocol.ECN) (int, error)\n\tLocalAddr() net.Addr\n\tSetReadDeadline(time.Time) error\n\tio.Closer\n\n\tcapabilities() connCapabilities\n}\n\ntype closePacket struct {\n\tpayload []byte\n\taddr    net.Addr\n\tinfo    packetInfo\n}\n\ntype packetHandlerMap struct {\n\tmutex       sync.Mutex\n\thandlers    map[protocol.ConnectionID]packetHandler\n\tresetTokens map[protocol.StatelessResetToken] /* stateless reset token */ packetHandler\n\n\tclosed    bool\n\tcloseChan chan struct{}\n\n\tenqueueClosePacket func(closePacket)\n\n\tdeleteRetiredConnsAfter time.Duration\n\n\tlogger utils.Logger\n}\n\nvar _ packetHandlerManager = &packetHandlerMap{}\n\nfunc newPacketHandlerMap(enqueueClosePacket func(closePacket), logger utils.Logger) *packetHandlerMap {\n\th := &packetHandlerMap{\n\t\tcloseChan:               make(chan struct{}),\n\t\thandlers:                make(map[protocol.ConnectionID]packetHandler),\n\t\tresetTokens:             make(map[protocol.StatelessResetToken]packetHandler),\n\t\tdeleteRetiredConnsAfter: protocol.RetiredConnectionIDDeleteTimeout,\n\t\tenqueueClosePacket:      enqueueClosePacket,\n\t\tlogger:                  logger,\n\t}\n\tif h.logger.Debug() {\n\t\tgo h.logUsage()\n\t}\n\treturn h\n}\n\nfunc (h *packetHandlerMap) logUsage() {\n\tticker := time.NewTicker(2 * time.Second)\n\tvar printedZero bool\n\tfor {\n\t\tselect {\n\t\tcase <-h.closeChan:\n\t\t\treturn\n\t\tcase <-ticker.C:\n\t\t}\n\n\t\th.mutex.Lock()\n\t\tnumHandlers := len(h.handlers)\n\t\tnumTokens := len(h.resetTokens)\n\t\th.mutex.Unlock()\n\t\t// If the number tracked handlers and tokens is zero, only print it a single time.\n\t\thasZero := numHandlers == 0 && numTokens == 0\n\t\tif !hasZero || (hasZero && !printedZero) {\n\t\t\th.logger.Debugf(\"Tracking %d connection IDs and %d reset tokens.\\n\", numHandlers, numTokens)\n\t\t\tprintedZero = false\n\t\t\tif hasZero {\n\t\t\t\tprintedZero = true\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (h *packetHandlerMap) Get(id protocol.ConnectionID) (packetHandler, bool) {\n\th.mutex.Lock()\n\tdefer h.mutex.Unlock()\n\n\thandler, ok := h.handlers[id]\n\treturn handler, ok\n}\n\nfunc (h *packetHandlerMap) Add(id protocol.ConnectionID, handler packetHandler) bool /* was added */ {\n\th.mutex.Lock()\n\tdefer h.mutex.Unlock()\n\n\tif _, ok := h.handlers[id]; ok {\n\t\th.logger.Debugf(\"Not adding connection ID %s, as it already exists.\", id)\n\t\treturn false\n\t}\n\th.handlers[id] = handler\n\th.logger.Debugf(\"Adding connection ID %s.\", id)\n\treturn true\n}\n\nfunc (h *packetHandlerMap) AddWithConnID(clientDestConnID, newConnID protocol.ConnectionID, handler packetHandler) bool {\n\th.mutex.Lock()\n\tdefer h.mutex.Unlock()\n\n\tif _, ok := h.handlers[clientDestConnID]; ok {\n\t\th.logger.Debugf(\"Not adding connection ID %s for a new connection, as it already exists.\", clientDestConnID)\n\t\treturn false\n\t}\n\th.handlers[clientDestConnID] = handler\n\th.handlers[newConnID] = handler\n\th.logger.Debugf(\"Adding connection IDs %s and %s for a new connection.\", clientDestConnID, newConnID)\n\treturn true\n}\n\nfunc (h *packetHandlerMap) Remove(id protocol.ConnectionID) {\n\th.mutex.Lock()\n\tdelete(h.handlers, id)\n\th.mutex.Unlock()\n\th.logger.Debugf(\"Removing connection ID %s.\", id)\n}\n\nfunc (h *packetHandlerMap) Retire(id protocol.ConnectionID) {\n\th.logger.Debugf(\"Retiring connection ID %s in %s.\", id, h.deleteRetiredConnsAfter)\n\ttime.AfterFunc(h.deleteRetiredConnsAfter, func() {\n\t\th.mutex.Lock()\n\t\tdelete(h.handlers, id)\n\t\th.mutex.Unlock()\n\t\th.logger.Debugf(\"Removing connection ID %s after it has been retired.\", id)\n\t})\n}\n\n// ReplaceWithClosed is called when a connection is closed.\n// Depending on which side closed the connection, we need to:\n// * remote close: absorb delayed packets\n// * local close: retransmit the CONNECTION_CLOSE packet, in case it was lost\nfunc (h *packetHandlerMap) ReplaceWithClosed(ids []protocol.ConnectionID, connClosePacket []byte) {\n\tvar handler packetHandler\n\tif connClosePacket != nil {\n\t\thandler = newClosedLocalConn(\n\t\t\tfunc(addr net.Addr, info packetInfo) {\n\t\t\t\th.enqueueClosePacket(closePacket{payload: connClosePacket, addr: addr, info: info})\n\t\t\t},\n\t\t\th.logger,\n\t\t)\n\t} else {\n\t\thandler = newClosedRemoteConn()\n\t}\n\n\th.mutex.Lock()\n\tfor _, id := range ids {\n\t\th.handlers[id] = handler\n\t}\n\th.mutex.Unlock()\n\th.logger.Debugf(\"Replacing connection for connection IDs %s with a closed connection.\", ids)\n\n\ttime.AfterFunc(h.deleteRetiredConnsAfter, func() {\n\t\th.mutex.Lock()\n\t\tfor _, id := range ids {\n\t\t\tdelete(h.handlers, id)\n\t\t}\n\t\th.mutex.Unlock()\n\t\th.logger.Debugf(\"Removing connection IDs %s for a closed connection after it has been retired.\", ids)\n\t})\n}\n\nfunc (h *packetHandlerMap) AddResetToken(token protocol.StatelessResetToken, handler packetHandler) {\n\th.mutex.Lock()\n\th.resetTokens[token] = handler\n\th.mutex.Unlock()\n}\n\nfunc (h *packetHandlerMap) RemoveResetToken(token protocol.StatelessResetToken) {\n\th.mutex.Lock()\n\tdelete(h.resetTokens, token)\n\th.mutex.Unlock()\n}\n\nfunc (h *packetHandlerMap) GetByResetToken(token protocol.StatelessResetToken) (packetHandler, bool) {\n\th.mutex.Lock()\n\tdefer h.mutex.Unlock()\n\n\thandler, ok := h.resetTokens[token]\n\treturn handler, ok\n}\n\nfunc (h *packetHandlerMap) Close(e error) {\n\th.mutex.Lock()\n\n\tif h.closed {\n\t\th.mutex.Unlock()\n\t\treturn\n\t}\n\n\tclose(h.closeChan)\n\n\tvar wg sync.WaitGroup\n\tfor _, handler := range h.handlers {\n\t\twg.Add(1)\n\t\tgo func(handler packetHandler) {\n\t\t\thandler.destroy(e)\n\t\t\twg.Done()\n\t\t}(handler)\n\t}\n\th.closed = true\n\th.mutex.Unlock()\n\twg.Wait()\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/packet_packer.go",
    "content": "package quic\n\nimport (\n\tcrand \"crypto/rand\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math/rand/v2\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/ackhandler\"\n\t\"github.com/quic-go/quic-go/internal/handshake\"\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\nvar errNothingToPack = errors.New(\"nothing to pack\")\n\ntype packer interface {\n\tPackCoalescedPacket(onlyAck bool, maxPacketSize protocol.ByteCount, now time.Time, v protocol.Version) (*coalescedPacket, error)\n\tPackAckOnlyPacket(maxPacketSize protocol.ByteCount, now time.Time, v protocol.Version) (shortHeaderPacket, *packetBuffer, error)\n\tAppendPacket(_ *packetBuffer, maxPacketSize protocol.ByteCount, now time.Time, v protocol.Version) (shortHeaderPacket, error)\n\tPackPTOProbePacket(_ protocol.EncryptionLevel, _ protocol.ByteCount, addPingIfEmpty bool, now time.Time, v protocol.Version) (*coalescedPacket, error)\n\tPackConnectionClose(*qerr.TransportError, protocol.ByteCount, protocol.Version) (*coalescedPacket, error)\n\tPackApplicationClose(*qerr.ApplicationError, protocol.ByteCount, protocol.Version) (*coalescedPacket, error)\n\tPackPathProbePacket(protocol.ConnectionID, []ackhandler.Frame, protocol.Version) (shortHeaderPacket, *packetBuffer, error)\n\tPackMTUProbePacket(ping ackhandler.Frame, size protocol.ByteCount, v protocol.Version) (shortHeaderPacket, *packetBuffer, error)\n\n\tSetToken([]byte)\n}\n\ntype sealer interface {\n\thandshake.LongHeaderSealer\n}\n\ntype payload struct {\n\tstreamFrames []ackhandler.StreamFrame\n\tframes       []ackhandler.Frame\n\tack          *wire.AckFrame\n\tlength       protocol.ByteCount\n}\n\ntype longHeaderPacket struct {\n\theader       *wire.ExtendedHeader\n\tack          *wire.AckFrame\n\tframes       []ackhandler.Frame\n\tstreamFrames []ackhandler.StreamFrame // only used for 0-RTT packets\n\n\tlength protocol.ByteCount\n}\n\ntype shortHeaderPacket struct {\n\tPacketNumber         protocol.PacketNumber\n\tFrames               []ackhandler.Frame\n\tStreamFrames         []ackhandler.StreamFrame\n\tAck                  *wire.AckFrame\n\tLength               protocol.ByteCount\n\tIsPathMTUProbePacket bool\n\tIsPathProbePacket    bool\n\n\t// used for logging\n\tDestConnID      protocol.ConnectionID\n\tPacketNumberLen protocol.PacketNumberLen\n\tKeyPhase        protocol.KeyPhaseBit\n}\n\nfunc (p *shortHeaderPacket) IsAckEliciting() bool { return ackhandler.HasAckElicitingFrames(p.Frames) }\n\ntype coalescedPacket struct {\n\tbuffer         *packetBuffer\n\tlongHdrPackets []*longHeaderPacket\n\tshortHdrPacket *shortHeaderPacket\n}\n\n// IsOnlyShortHeaderPacket says if this packet only contains a short header packet (and no long header packets).\nfunc (p *coalescedPacket) IsOnlyShortHeaderPacket() bool {\n\treturn len(p.longHdrPackets) == 0 && p.shortHdrPacket != nil\n}\n\nfunc (p *longHeaderPacket) EncryptionLevel() protocol.EncryptionLevel {\n\t//nolint:exhaustive // Will never be called for Retry packets (and they don't have encrypted data).\n\tswitch p.header.Type {\n\tcase protocol.PacketTypeInitial:\n\t\treturn protocol.EncryptionInitial\n\tcase protocol.PacketTypeHandshake:\n\t\treturn protocol.EncryptionHandshake\n\tcase protocol.PacketType0RTT:\n\t\treturn protocol.Encryption0RTT\n\tdefault:\n\t\tpanic(\"can't determine encryption level\")\n\t}\n}\n\nfunc (p *longHeaderPacket) IsAckEliciting() bool { return ackhandler.HasAckElicitingFrames(p.frames) }\n\ntype packetNumberManager interface {\n\tPeekPacketNumber(protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen)\n\tPopPacketNumber(protocol.EncryptionLevel) protocol.PacketNumber\n}\n\ntype sealingManager interface {\n\tGetInitialSealer() (handshake.LongHeaderSealer, error)\n\tGetHandshakeSealer() (handshake.LongHeaderSealer, error)\n\tGet0RTTSealer() (handshake.LongHeaderSealer, error)\n\tGet1RTTSealer() (handshake.ShortHeaderSealer, error)\n}\n\ntype frameSource interface {\n\tHasData() bool\n\tAppend([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount, time.Time, protocol.Version) ([]ackhandler.Frame, []ackhandler.StreamFrame, protocol.ByteCount)\n}\n\ntype ackFrameSource interface {\n\tGetAckFrame(_ protocol.EncryptionLevel, now time.Time, onlyIfQueued bool) *wire.AckFrame\n}\n\ntype packetPacker struct {\n\tsrcConnID     protocol.ConnectionID\n\tgetDestConnID func() protocol.ConnectionID\n\n\tperspective protocol.Perspective\n\tcryptoSetup sealingManager\n\n\tinitialStream   *cryptoStream\n\thandshakeStream *cryptoStream\n\n\ttoken []byte\n\n\tpnManager           packetNumberManager\n\tframer              frameSource\n\tacks                ackFrameSource\n\tdatagramQueue       *datagramQueue\n\tretransmissionQueue *retransmissionQueue\n\trand                rand.Rand\n\n\tnumNonAckElicitingAcks int\n}\n\nvar _ packer = &packetPacker{}\n\nfunc newPacketPacker(\n\tsrcConnID protocol.ConnectionID,\n\tgetDestConnID func() protocol.ConnectionID,\n\tinitialStream, handshakeStream *cryptoStream,\n\tpacketNumberManager packetNumberManager,\n\tretransmissionQueue *retransmissionQueue,\n\tcryptoSetup sealingManager,\n\tframer frameSource,\n\tacks ackFrameSource,\n\tdatagramQueue *datagramQueue,\n\tperspective protocol.Perspective,\n) *packetPacker {\n\tvar b [16]byte\n\t_, _ = crand.Read(b[:])\n\n\treturn &packetPacker{\n\t\tcryptoSetup:         cryptoSetup,\n\t\tgetDestConnID:       getDestConnID,\n\t\tsrcConnID:           srcConnID,\n\t\tinitialStream:       initialStream,\n\t\thandshakeStream:     handshakeStream,\n\t\tretransmissionQueue: retransmissionQueue,\n\t\tdatagramQueue:       datagramQueue,\n\t\tperspective:         perspective,\n\t\tframer:              framer,\n\t\tacks:                acks,\n\t\trand:                *rand.New(rand.NewPCG(binary.BigEndian.Uint64(b[:8]), binary.BigEndian.Uint64(b[8:]))),\n\t\tpnManager:           packetNumberManager,\n\t}\n}\n\n// PackConnectionClose packs a packet that closes the connection with a transport error.\nfunc (p *packetPacker) PackConnectionClose(e *qerr.TransportError, maxPacketSize protocol.ByteCount, v protocol.Version) (*coalescedPacket, error) {\n\tvar reason string\n\t// don't send details of crypto errors\n\tif !e.ErrorCode.IsCryptoError() {\n\t\treason = e.ErrorMessage\n\t}\n\treturn p.packConnectionClose(false, uint64(e.ErrorCode), e.FrameType, reason, maxPacketSize, v)\n}\n\n// PackApplicationClose packs a packet that closes the connection with an application error.\nfunc (p *packetPacker) PackApplicationClose(e *qerr.ApplicationError, maxPacketSize protocol.ByteCount, v protocol.Version) (*coalescedPacket, error) {\n\treturn p.packConnectionClose(true, uint64(e.ErrorCode), 0, e.ErrorMessage, maxPacketSize, v)\n}\n\nfunc (p *packetPacker) packConnectionClose(\n\tisApplicationError bool,\n\terrorCode uint64,\n\tframeType uint64,\n\treason string,\n\tmaxPacketSize protocol.ByteCount,\n\tv protocol.Version,\n) (*coalescedPacket, error) {\n\tvar sealers [4]sealer\n\tvar hdrs [3]*wire.ExtendedHeader\n\tvar payloads [4]payload\n\tvar size protocol.ByteCount\n\tvar connID protocol.ConnectionID\n\tvar oneRTTPacketNumber protocol.PacketNumber\n\tvar oneRTTPacketNumberLen protocol.PacketNumberLen\n\tvar keyPhase protocol.KeyPhaseBit // only set for 1-RTT\n\tvar numLongHdrPackets uint8\n\tencLevels := [4]protocol.EncryptionLevel{protocol.EncryptionInitial, protocol.EncryptionHandshake, protocol.Encryption0RTT, protocol.Encryption1RTT}\n\tfor i, encLevel := range encLevels {\n\t\tif p.perspective == protocol.PerspectiveServer && encLevel == protocol.Encryption0RTT {\n\t\t\tcontinue\n\t\t}\n\t\tccf := &wire.ConnectionCloseFrame{\n\t\t\tIsApplicationError: isApplicationError,\n\t\t\tErrorCode:          errorCode,\n\t\t\tFrameType:          frameType,\n\t\t\tReasonPhrase:       reason,\n\t\t}\n\t\t// don't send application errors in Initial or Handshake packets\n\t\tif isApplicationError && (encLevel == protocol.EncryptionInitial || encLevel == protocol.EncryptionHandshake) {\n\t\t\tccf.IsApplicationError = false\n\t\t\tccf.ErrorCode = uint64(qerr.ApplicationErrorErrorCode)\n\t\t\tccf.ReasonPhrase = \"\"\n\t\t}\n\t\tpl := payload{\n\t\t\tframes: []ackhandler.Frame{{Frame: ccf}},\n\t\t\tlength: ccf.Length(v),\n\t\t}\n\n\t\tvar sealer sealer\n\t\tvar err error\n\t\tswitch encLevel {\n\t\tcase protocol.EncryptionInitial:\n\t\t\tsealer, err = p.cryptoSetup.GetInitialSealer()\n\t\tcase protocol.EncryptionHandshake:\n\t\t\tsealer, err = p.cryptoSetup.GetHandshakeSealer()\n\t\tcase protocol.Encryption0RTT:\n\t\t\tsealer, err = p.cryptoSetup.Get0RTTSealer()\n\t\tcase protocol.Encryption1RTT:\n\t\t\tvar s handshake.ShortHeaderSealer\n\t\t\ts, err = p.cryptoSetup.Get1RTTSealer()\n\t\t\tif err == nil {\n\t\t\t\tkeyPhase = s.KeyPhase()\n\t\t\t}\n\t\t\tsealer = s\n\t\t}\n\t\tif err == handshake.ErrKeysNotYetAvailable || err == handshake.ErrKeysDropped {\n\t\t\tcontinue\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tsealers[i] = sealer\n\t\tvar hdr *wire.ExtendedHeader\n\t\tif encLevel == protocol.Encryption1RTT {\n\t\t\tconnID = p.getDestConnID()\n\t\t\toneRTTPacketNumber, oneRTTPacketNumberLen = p.pnManager.PeekPacketNumber(protocol.Encryption1RTT)\n\t\t\tsize += p.shortHeaderPacketLength(connID, oneRTTPacketNumberLen, pl)\n\t\t} else {\n\t\t\thdr = p.getLongHeader(encLevel, v)\n\t\t\thdrs[i] = hdr\n\t\t\tsize += p.longHeaderPacketLength(hdr, pl, v) + protocol.ByteCount(sealer.Overhead())\n\t\t\tnumLongHdrPackets++\n\t\t}\n\t\tpayloads[i] = pl\n\t}\n\tbuffer := getPacketBuffer()\n\tpacket := &coalescedPacket{\n\t\tbuffer:         buffer,\n\t\tlongHdrPackets: make([]*longHeaderPacket, 0, numLongHdrPackets),\n\t}\n\tfor i, encLevel := range encLevels {\n\t\tif sealers[i] == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif encLevel == protocol.Encryption1RTT {\n\t\t\tshp, err := p.appendShortHeaderPacket(buffer, connID, oneRTTPacketNumber, oneRTTPacketNumberLen, keyPhase, payloads[i], 0, maxPacketSize, sealers[i], false, v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tpacket.shortHdrPacket = &shp\n\t\t} else {\n\t\t\tvar paddingLen protocol.ByteCount\n\t\t\tif encLevel == protocol.EncryptionInitial {\n\t\t\t\tpaddingLen = p.initialPaddingLen(payloads[i].frames, size, maxPacketSize)\n\t\t\t}\n\t\t\tlongHdrPacket, err := p.appendLongHeaderPacket(buffer, hdrs[i], payloads[i], paddingLen, encLevel, sealers[i], v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tpacket.longHdrPackets = append(packet.longHdrPackets, longHdrPacket)\n\t\t}\n\t}\n\treturn packet, nil\n}\n\n// longHeaderPacketLength calculates the length of a serialized long header packet.\n// It takes into account that packets that have a tiny payload need to be padded,\n// such that len(payload) + packet number len >= 4 + AEAD overhead\nfunc (p *packetPacker) longHeaderPacketLength(hdr *wire.ExtendedHeader, pl payload, v protocol.Version) protocol.ByteCount {\n\tvar paddingLen protocol.ByteCount\n\tpnLen := protocol.ByteCount(hdr.PacketNumberLen)\n\tif pl.length < 4-pnLen {\n\t\tpaddingLen = 4 - pnLen - pl.length\n\t}\n\treturn hdr.GetLength(v) + pl.length + paddingLen\n}\n\n// shortHeaderPacketLength calculates the length of a serialized short header packet.\n// It takes into account that packets that have a tiny payload need to be padded,\n// such that len(payload) + packet number len >= 4 + AEAD overhead\nfunc (p *packetPacker) shortHeaderPacketLength(connID protocol.ConnectionID, pnLen protocol.PacketNumberLen, pl payload) protocol.ByteCount {\n\tvar paddingLen protocol.ByteCount\n\tif pl.length < 4-protocol.ByteCount(pnLen) {\n\t\tpaddingLen = 4 - protocol.ByteCount(pnLen) - pl.length\n\t}\n\treturn wire.ShortHeaderLen(connID, pnLen) + pl.length + paddingLen\n}\n\n// size is the expected size of the packet, if no padding was applied.\nfunc (p *packetPacker) initialPaddingLen(frames []ackhandler.Frame, currentSize, maxPacketSize protocol.ByteCount) protocol.ByteCount {\n\t// For the server, only ack-eliciting Initial packets need to be padded.\n\tif p.perspective == protocol.PerspectiveServer && !ackhandler.HasAckElicitingFrames(frames) {\n\t\treturn 0\n\t}\n\tif currentSize >= maxPacketSize {\n\t\treturn 0\n\t}\n\treturn maxPacketSize - currentSize\n}\n\n// PackCoalescedPacket packs a new packet.\n// It packs an Initial / Handshake if there is data to send in these packet number spaces.\n// It should only be called before the handshake is confirmed.\nfunc (p *packetPacker) PackCoalescedPacket(onlyAck bool, maxSize protocol.ByteCount, now time.Time, v protocol.Version) (*coalescedPacket, error) {\n\tvar (\n\t\tinitialHdr, handshakeHdr, zeroRTTHdr                            *wire.ExtendedHeader\n\t\tinitialPayload, handshakePayload, zeroRTTPayload, oneRTTPayload payload\n\t\toneRTTPacketNumber                                              protocol.PacketNumber\n\t\toneRTTPacketNumberLen                                           protocol.PacketNumberLen\n\t)\n\t// Try packing an Initial packet.\n\tinitialSealer, err := p.cryptoSetup.GetInitialSealer()\n\tif err != nil && err != handshake.ErrKeysDropped {\n\t\treturn nil, err\n\t}\n\tvar size protocol.ByteCount\n\tif initialSealer != nil {\n\t\tinitialHdr, initialPayload = p.maybeGetCryptoPacket(\n\t\t\tmaxSize-protocol.ByteCount(initialSealer.Overhead()),\n\t\t\tprotocol.EncryptionInitial,\n\t\t\tnow,\n\t\t\tfalse,\n\t\t\tonlyAck,\n\t\t\ttrue,\n\t\t\tv,\n\t\t)\n\t\tif initialPayload.length > 0 {\n\t\t\tsize += p.longHeaderPacketLength(initialHdr, initialPayload, v) + protocol.ByteCount(initialSealer.Overhead())\n\t\t}\n\t}\n\n\t// Add a Handshake packet.\n\tvar handshakeSealer sealer\n\tif (onlyAck && size == 0) || (!onlyAck && size < maxSize-protocol.MinCoalescedPacketSize) {\n\t\tvar err error\n\t\thandshakeSealer, err = p.cryptoSetup.GetHandshakeSealer()\n\t\tif err != nil && err != handshake.ErrKeysDropped && err != handshake.ErrKeysNotYetAvailable {\n\t\t\treturn nil, err\n\t\t}\n\t\tif handshakeSealer != nil {\n\t\t\thandshakeHdr, handshakePayload = p.maybeGetCryptoPacket(\n\t\t\t\tmaxSize-size-protocol.ByteCount(handshakeSealer.Overhead()),\n\t\t\t\tprotocol.EncryptionHandshake,\n\t\t\t\tnow,\n\t\t\t\tfalse,\n\t\t\t\tonlyAck,\n\t\t\t\tsize == 0,\n\t\t\t\tv,\n\t\t\t)\n\t\t\tif handshakePayload.length > 0 {\n\t\t\t\ts := p.longHeaderPacketLength(handshakeHdr, handshakePayload, v) + protocol.ByteCount(handshakeSealer.Overhead())\n\t\t\t\tsize += s\n\t\t\t}\n\t\t}\n\t}\n\n\t// Add a 0-RTT / 1-RTT packet.\n\tvar zeroRTTSealer sealer\n\tvar oneRTTSealer handshake.ShortHeaderSealer\n\tvar connID protocol.ConnectionID\n\tvar kp protocol.KeyPhaseBit\n\tif (onlyAck && size == 0) || (!onlyAck && size < maxSize-protocol.MinCoalescedPacketSize) {\n\t\tvar err error\n\t\toneRTTSealer, err = p.cryptoSetup.Get1RTTSealer()\n\t\tif err != nil && err != handshake.ErrKeysDropped && err != handshake.ErrKeysNotYetAvailable {\n\t\t\treturn nil, err\n\t\t}\n\t\tif err == nil { // 1-RTT\n\t\t\tkp = oneRTTSealer.KeyPhase()\n\t\t\tconnID = p.getDestConnID()\n\t\t\toneRTTPacketNumber, oneRTTPacketNumberLen = p.pnManager.PeekPacketNumber(protocol.Encryption1RTT)\n\t\t\thdrLen := wire.ShortHeaderLen(connID, oneRTTPacketNumberLen)\n\t\t\toneRTTPayload = p.maybeGetShortHeaderPacket(oneRTTSealer, hdrLen, maxSize-size, onlyAck, size == 0, now, v)\n\t\t\tif oneRTTPayload.length > 0 {\n\t\t\t\tsize += p.shortHeaderPacketLength(connID, oneRTTPacketNumberLen, oneRTTPayload) + protocol.ByteCount(oneRTTSealer.Overhead())\n\t\t\t}\n\t\t} else if p.perspective == protocol.PerspectiveClient && !onlyAck { // 0-RTT packets can't contain ACK frames\n\t\t\tvar err error\n\t\t\tzeroRTTSealer, err = p.cryptoSetup.Get0RTTSealer()\n\t\t\tif err != nil && err != handshake.ErrKeysDropped && err != handshake.ErrKeysNotYetAvailable {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif zeroRTTSealer != nil {\n\t\t\t\tzeroRTTHdr, zeroRTTPayload = p.maybeGetAppDataPacketFor0RTT(zeroRTTSealer, maxSize-size, now, v)\n\t\t\t\tif zeroRTTPayload.length > 0 {\n\t\t\t\t\tsize += p.longHeaderPacketLength(zeroRTTHdr, zeroRTTPayload, v) + protocol.ByteCount(zeroRTTSealer.Overhead())\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif initialPayload.length == 0 && handshakePayload.length == 0 && zeroRTTPayload.length == 0 && oneRTTPayload.length == 0 {\n\t\treturn nil, nil\n\t}\n\n\tbuffer := getPacketBuffer()\n\tpacket := &coalescedPacket{\n\t\tbuffer:         buffer,\n\t\tlongHdrPackets: make([]*longHeaderPacket, 0, 3),\n\t}\n\tif initialPayload.length > 0 {\n\t\tpadding := p.initialPaddingLen(initialPayload.frames, size, maxSize)\n\t\tcont, err := p.appendLongHeaderPacket(buffer, initialHdr, initialPayload, padding, protocol.EncryptionInitial, initialSealer, v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tpacket.longHdrPackets = append(packet.longHdrPackets, cont)\n\t}\n\tif handshakePayload.length > 0 {\n\t\tcont, err := p.appendLongHeaderPacket(buffer, handshakeHdr, handshakePayload, 0, protocol.EncryptionHandshake, handshakeSealer, v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tpacket.longHdrPackets = append(packet.longHdrPackets, cont)\n\t}\n\tif zeroRTTPayload.length > 0 {\n\t\tlongHdrPacket, err := p.appendLongHeaderPacket(buffer, zeroRTTHdr, zeroRTTPayload, 0, protocol.Encryption0RTT, zeroRTTSealer, v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tpacket.longHdrPackets = append(packet.longHdrPackets, longHdrPacket)\n\t} else if oneRTTPayload.length > 0 {\n\t\tshp, err := p.appendShortHeaderPacket(buffer, connID, oneRTTPacketNumber, oneRTTPacketNumberLen, kp, oneRTTPayload, 0, maxSize, oneRTTSealer, false, v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tpacket.shortHdrPacket = &shp\n\t}\n\treturn packet, nil\n}\n\n// PackAckOnlyPacket packs a packet containing only an ACK in the application data packet number space.\n// It should be called after the handshake is confirmed.\nfunc (p *packetPacker) PackAckOnlyPacket(maxSize protocol.ByteCount, now time.Time, v protocol.Version) (shortHeaderPacket, *packetBuffer, error) {\n\tbuf := getPacketBuffer()\n\tpacket, err := p.appendPacket(buf, true, maxSize, now, v)\n\treturn packet, buf, err\n}\n\n// AppendPacket packs a packet in the application data packet number space.\n// It should be called after the handshake is confirmed.\nfunc (p *packetPacker) AppendPacket(buf *packetBuffer, maxSize protocol.ByteCount, now time.Time, v protocol.Version) (shortHeaderPacket, error) {\n\treturn p.appendPacket(buf, false, maxSize, now, v)\n}\n\nfunc (p *packetPacker) appendPacket(\n\tbuf *packetBuffer,\n\tonlyAck bool,\n\tmaxPacketSize protocol.ByteCount,\n\tnow time.Time,\n\tv protocol.Version,\n) (shortHeaderPacket, error) {\n\tsealer, err := p.cryptoSetup.Get1RTTSealer()\n\tif err != nil {\n\t\treturn shortHeaderPacket{}, err\n\t}\n\tpn, pnLen := p.pnManager.PeekPacketNumber(protocol.Encryption1RTT)\n\tconnID := p.getDestConnID()\n\thdrLen := wire.ShortHeaderLen(connID, pnLen)\n\tpl := p.maybeGetShortHeaderPacket(sealer, hdrLen, maxPacketSize, onlyAck, true, now, v)\n\tif pl.length == 0 {\n\t\treturn shortHeaderPacket{}, errNothingToPack\n\t}\n\tkp := sealer.KeyPhase()\n\n\treturn p.appendShortHeaderPacket(buf, connID, pn, pnLen, kp, pl, 0, maxPacketSize, sealer, false, v)\n}\n\nfunc (p *packetPacker) maybeGetCryptoPacket(\n\tmaxPacketSize protocol.ByteCount,\n\tencLevel protocol.EncryptionLevel,\n\tnow time.Time,\n\taddPingIfEmpty bool,\n\tonlyAck, ackAllowed bool,\n\tv protocol.Version,\n) (*wire.ExtendedHeader, payload) {\n\tif onlyAck {\n\t\tif ack := p.acks.GetAckFrame(encLevel, now, true); ack != nil {\n\t\t\treturn p.getLongHeader(encLevel, v), payload{\n\t\t\t\tack:    ack,\n\t\t\t\tlength: ack.Length(v),\n\t\t\t}\n\t\t}\n\t\treturn nil, payload{}\n\t}\n\n\tvar s *cryptoStream\n\t//nolint:exhaustive // Initial and Handshake are the only two encryption levels here.\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\ts = p.initialStream\n\tcase protocol.EncryptionHandshake:\n\t\ts = p.handshakeStream\n\t}\n\thasData := s.HasData()\n\thandler := p.retransmissionQueue.AckHandler(encLevel)\n\thasRetransmission := p.retransmissionQueue.HasData(encLevel)\n\n\tvar ack *wire.AckFrame\n\tif ackAllowed {\n\t\tack = p.acks.GetAckFrame(encLevel, now, !hasRetransmission && !hasData)\n\t}\n\tvar pl payload\n\tif !hasData && !hasRetransmission && ack == nil {\n\t\tif !addPingIfEmpty {\n\t\t\t// nothing to send\n\t\t\treturn nil, payload{}\n\t\t}\n\t\tping := &wire.PingFrame{}\n\t\tpl.frames = append(pl.frames, ackhandler.Frame{Frame: ping, Handler: emptyHandler{}})\n\t\tpl.length += ping.Length(v)\n\t}\n\n\tif ack != nil {\n\t\tpl.ack = ack\n\t\tpl.length = ack.Length(v)\n\t\tmaxPacketSize -= pl.length\n\t}\n\thdr := p.getLongHeader(encLevel, v)\n\tmaxPacketSize -= hdr.GetLength(v)\n\tif hasRetransmission {\n\t\tfor {\n\t\t\tframe := p.retransmissionQueue.GetFrame(encLevel, maxPacketSize, v)\n\t\t\tif frame == nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tpl.frames = append(pl.frames, ackhandler.Frame{\n\t\t\t\tFrame:   frame,\n\t\t\t\tHandler: p.retransmissionQueue.AckHandler(encLevel),\n\t\t\t})\n\t\t\tframeLen := frame.Length(v)\n\t\t\tpl.length += frameLen\n\t\t\tmaxPacketSize -= frameLen\n\t\t}\n\t} else if s.HasData() {\n\t\tcf := s.PopCryptoFrame(maxPacketSize)\n\t\tpl.frames = append(pl.frames, ackhandler.Frame{Frame: cf, Handler: handler})\n\t\tpl.length += cf.Length(v)\n\t}\n\treturn hdr, pl\n}\n\nfunc (p *packetPacker) maybeGetAppDataPacketFor0RTT(sealer sealer, maxSize protocol.ByteCount, now time.Time, v protocol.Version) (*wire.ExtendedHeader, payload) {\n\tif p.perspective != protocol.PerspectiveClient {\n\t\treturn nil, payload{}\n\t}\n\n\thdr := p.getLongHeader(protocol.Encryption0RTT, v)\n\tmaxPayloadSize := maxSize - hdr.GetLength(v) - protocol.ByteCount(sealer.Overhead())\n\treturn hdr, p.maybeGetAppDataPacket(maxPayloadSize, false, false, now, v)\n}\n\nfunc (p *packetPacker) maybeGetShortHeaderPacket(\n\tsealer handshake.ShortHeaderSealer,\n\thdrLen, maxPacketSize protocol.ByteCount,\n\tonlyAck, ackAllowed bool,\n\tnow time.Time,\n\tv protocol.Version,\n) payload {\n\tmaxPayloadSize := maxPacketSize - hdrLen - protocol.ByteCount(sealer.Overhead())\n\treturn p.maybeGetAppDataPacket(maxPayloadSize, onlyAck, ackAllowed, now, v)\n}\n\nfunc (p *packetPacker) maybeGetAppDataPacket(\n\tmaxPayloadSize protocol.ByteCount,\n\tonlyAck, ackAllowed bool,\n\tnow time.Time,\n\tv protocol.Version,\n) payload {\n\tpl := p.composeNextPacket(maxPayloadSize, onlyAck, ackAllowed, now, v)\n\n\t// check if we have anything to send\n\tif len(pl.frames) == 0 && len(pl.streamFrames) == 0 {\n\t\tif pl.ack == nil {\n\t\t\treturn payload{}\n\t\t}\n\t\t// the packet only contains an ACK\n\t\tif p.numNonAckElicitingAcks >= protocol.MaxNonAckElicitingAcks {\n\t\t\tping := &wire.PingFrame{}\n\t\t\tpl.frames = append(pl.frames, ackhandler.Frame{Frame: ping})\n\t\t\tpl.length += ping.Length(v)\n\t\t\tp.numNonAckElicitingAcks = 0\n\t\t} else {\n\t\t\tp.numNonAckElicitingAcks++\n\t\t}\n\t} else {\n\t\tp.numNonAckElicitingAcks = 0\n\t}\n\treturn pl\n}\n\nfunc (p *packetPacker) composeNextPacket(\n\tmaxPayloadSize protocol.ByteCount,\n\tonlyAck, ackAllowed bool,\n\tnow time.Time,\n\tv protocol.Version,\n) payload {\n\tif onlyAck {\n\t\tif ack := p.acks.GetAckFrame(protocol.Encryption1RTT, now, true); ack != nil {\n\t\t\treturn payload{ack: ack, length: ack.Length(v)}\n\t\t}\n\t\treturn payload{}\n\t}\n\n\thasData := p.framer.HasData()\n\thasRetransmission := p.retransmissionQueue.HasData(protocol.Encryption1RTT)\n\n\tvar hasAck bool\n\tvar pl payload\n\tif ackAllowed {\n\t\tif ack := p.acks.GetAckFrame(protocol.Encryption1RTT, now, !hasRetransmission && !hasData); ack != nil {\n\t\t\tpl.ack = ack\n\t\t\tpl.length += ack.Length(v)\n\t\t\thasAck = true\n\t\t}\n\t}\n\n\tif p.datagramQueue != nil {\n\t\tif f := p.datagramQueue.Peek(); f != nil {\n\t\t\tsize := f.Length(v)\n\t\t\tif size <= maxPayloadSize-pl.length { // DATAGRAM frame fits\n\t\t\t\tpl.frames = append(pl.frames, ackhandler.Frame{Frame: f})\n\t\t\t\tpl.length += size\n\t\t\t\tp.datagramQueue.Pop()\n\t\t\t} else if !hasAck {\n\t\t\t\t// The DATAGRAM frame doesn't fit, and the packet doesn't contain an ACK.\n\t\t\t\t// Discard this frame. There's no point in retrying this in the next packet,\n\t\t\t\t// as it's unlikely that the available packet size will increase.\n\t\t\t\tp.datagramQueue.Pop()\n\t\t\t}\n\t\t\t// If the DATAGRAM frame was too large and the packet contained an ACK, we'll try to send it out later.\n\t\t}\n\t}\n\n\tif hasAck && !hasData && !hasRetransmission {\n\t\treturn pl\n\t}\n\n\tif hasRetransmission {\n\t\tfor {\n\t\t\tremainingLen := maxPayloadSize - pl.length\n\t\t\tif remainingLen < protocol.MinStreamFrameSize {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tf := p.retransmissionQueue.GetFrame(protocol.Encryption1RTT, remainingLen, v)\n\t\t\tif f == nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tpl.frames = append(pl.frames, ackhandler.Frame{Frame: f, Handler: p.retransmissionQueue.AckHandler(protocol.Encryption1RTT)})\n\t\t\tpl.length += f.Length(v)\n\t\t}\n\t}\n\n\tif hasData {\n\t\tvar lengthAdded protocol.ByteCount\n\t\tstartLen := len(pl.frames)\n\t\tpl.frames, pl.streamFrames, lengthAdded = p.framer.Append(pl.frames, pl.streamFrames, maxPayloadSize-pl.length, now, v)\n\t\tpl.length += lengthAdded\n\t\t// add handlers for the control frames that were added\n\t\tfor i := startLen; i < len(pl.frames); i++ {\n\t\t\tif pl.frames[i].Handler != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tswitch pl.frames[i].Frame.(type) {\n\t\t\tcase *wire.PathChallengeFrame, *wire.PathResponseFrame:\n\t\t\t\t// Path probing is currently not supported, therefore we don't need to set the OnAcked callback yet.\n\t\t\t\t// PATH_CHALLENGE and PATH_RESPONSE are never retransmitted.\n\t\t\tdefault:\n\t\t\t\t// we might be packing a 0-RTT packet, but we need to use the 1-RTT ack handler anyway\n\t\t\t\tpl.frames[i].Handler = p.retransmissionQueue.AckHandler(protocol.Encryption1RTT)\n\t\t\t}\n\t\t}\n\t}\n\treturn pl\n}\n\nfunc (p *packetPacker) PackPTOProbePacket(\n\tencLevel protocol.EncryptionLevel,\n\tmaxPacketSize protocol.ByteCount,\n\taddPingIfEmpty bool,\n\tnow time.Time,\n\tv protocol.Version,\n) (*coalescedPacket, error) {\n\tif encLevel == protocol.Encryption1RTT {\n\t\treturn p.packPTOProbePacket1RTT(maxPacketSize, addPingIfEmpty, now, v)\n\t}\n\n\tvar sealer handshake.LongHeaderSealer\n\t//nolint:exhaustive // Probe packets are never sent for 0-RTT.\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\tvar err error\n\t\tsealer, err = p.cryptoSetup.GetInitialSealer()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\tcase protocol.EncryptionHandshake:\n\t\tvar err error\n\t\tsealer, err = p.cryptoSetup.GetHandshakeSealer()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\tdefault:\n\t\tpanic(\"unknown encryption level\")\n\t}\n\thdr, pl := p.maybeGetCryptoPacket(\n\t\tmaxPacketSize-protocol.ByteCount(sealer.Overhead()),\n\t\tencLevel,\n\t\tnow,\n\t\taddPingIfEmpty,\n\t\tfalse,\n\t\ttrue,\n\t\tv,\n\t)\n\tif pl.length == 0 {\n\t\treturn nil, nil\n\t}\n\tbuffer := getPacketBuffer()\n\tpacket := &coalescedPacket{buffer: buffer}\n\tsize := p.longHeaderPacketLength(hdr, pl, v) + protocol.ByteCount(sealer.Overhead())\n\tvar padding protocol.ByteCount\n\tif encLevel == protocol.EncryptionInitial {\n\t\tpadding = p.initialPaddingLen(pl.frames, size, maxPacketSize)\n\t}\n\n\tlongHdrPacket, err := p.appendLongHeaderPacket(buffer, hdr, pl, padding, encLevel, sealer, v)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpacket.longHdrPackets = []*longHeaderPacket{longHdrPacket}\n\treturn packet, nil\n}\n\nfunc (p *packetPacker) packPTOProbePacket1RTT(maxPacketSize protocol.ByteCount, addPingIfEmpty bool, now time.Time, v protocol.Version) (*coalescedPacket, error) {\n\ts, err := p.cryptoSetup.Get1RTTSealer()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tkp := s.KeyPhase()\n\tconnID := p.getDestConnID()\n\tpn, pnLen := p.pnManager.PeekPacketNumber(protocol.Encryption1RTT)\n\thdrLen := wire.ShortHeaderLen(connID, pnLen)\n\tpl := p.maybeGetAppDataPacket(maxPacketSize-protocol.ByteCount(s.Overhead())-hdrLen, false, true, now, v)\n\tif pl.length == 0 {\n\t\tif !addPingIfEmpty {\n\t\t\treturn nil, nil\n\t\t}\n\t\tping := &wire.PingFrame{}\n\t\tpl.frames = append(pl.frames, ackhandler.Frame{Frame: ping, Handler: emptyHandler{}})\n\t\tpl.length += ping.Length(v)\n\t}\n\tbuffer := getPacketBuffer()\n\tpacket := &coalescedPacket{buffer: buffer}\n\tshp, err := p.appendShortHeaderPacket(buffer, connID, pn, pnLen, kp, pl, 0, maxPacketSize, s, false, v)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpacket.shortHdrPacket = &shp\n\treturn packet, nil\n}\n\nfunc (p *packetPacker) PackMTUProbePacket(ping ackhandler.Frame, size protocol.ByteCount, v protocol.Version) (shortHeaderPacket, *packetBuffer, error) {\n\tpl := payload{\n\t\tframes: []ackhandler.Frame{ping},\n\t\tlength: ping.Frame.Length(v),\n\t}\n\tbuffer := getPacketBuffer()\n\ts, err := p.cryptoSetup.Get1RTTSealer()\n\tif err != nil {\n\t\treturn shortHeaderPacket{}, nil, err\n\t}\n\tconnID := p.getDestConnID()\n\tpn, pnLen := p.pnManager.PeekPacketNumber(protocol.Encryption1RTT)\n\tpadding := size - p.shortHeaderPacketLength(connID, pnLen, pl) - protocol.ByteCount(s.Overhead())\n\tkp := s.KeyPhase()\n\tpacket, err := p.appendShortHeaderPacket(buffer, connID, pn, pnLen, kp, pl, padding, size, s, true, v)\n\treturn packet, buffer, err\n}\n\nfunc (p *packetPacker) PackPathProbePacket(connID protocol.ConnectionID, frames []ackhandler.Frame, v protocol.Version) (shortHeaderPacket, *packetBuffer, error) {\n\tpn, pnLen := p.pnManager.PeekPacketNumber(protocol.Encryption1RTT)\n\tbuf := getPacketBuffer()\n\ts, err := p.cryptoSetup.Get1RTTSealer()\n\tif err != nil {\n\t\treturn shortHeaderPacket{}, nil, err\n\t}\n\tvar l protocol.ByteCount\n\tfor _, f := range frames {\n\t\tl += f.Frame.Length(v)\n\t}\n\tpayload := payload{\n\t\tframes: frames,\n\t\tlength: l,\n\t}\n\tpadding := protocol.MinInitialPacketSize - p.shortHeaderPacketLength(connID, pnLen, payload) - protocol.ByteCount(s.Overhead())\n\tpacket, err := p.appendShortHeaderPacket(buf, connID, pn, pnLen, s.KeyPhase(), payload, padding, protocol.MinInitialPacketSize, s, false, v)\n\tif err != nil {\n\t\treturn shortHeaderPacket{}, nil, err\n\t}\n\tpacket.IsPathProbePacket = true\n\treturn packet, buf, err\n}\n\nfunc (p *packetPacker) getLongHeader(encLevel protocol.EncryptionLevel, v protocol.Version) *wire.ExtendedHeader {\n\tpn, pnLen := p.pnManager.PeekPacketNumber(encLevel)\n\thdr := &wire.ExtendedHeader{\n\t\tPacketNumber:    pn,\n\t\tPacketNumberLen: pnLen,\n\t}\n\thdr.Version = v\n\thdr.SrcConnectionID = p.srcConnID\n\thdr.DestConnectionID = p.getDestConnID()\n\n\t//nolint:exhaustive // 1-RTT packets are not long header packets.\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\thdr.Type = protocol.PacketTypeInitial\n\t\thdr.Token = p.token\n\tcase protocol.EncryptionHandshake:\n\t\thdr.Type = protocol.PacketTypeHandshake\n\tcase protocol.Encryption0RTT:\n\t\thdr.Type = protocol.PacketType0RTT\n\t}\n\treturn hdr\n}\n\nfunc (p *packetPacker) appendLongHeaderPacket(buffer *packetBuffer, header *wire.ExtendedHeader, pl payload, padding protocol.ByteCount, encLevel protocol.EncryptionLevel, sealer sealer, v protocol.Version) (*longHeaderPacket, error) {\n\tvar paddingLen protocol.ByteCount\n\tpnLen := protocol.ByteCount(header.PacketNumberLen)\n\tif pl.length < 4-pnLen {\n\t\tpaddingLen = 4 - pnLen - pl.length\n\t}\n\tpaddingLen += padding\n\theader.Length = pnLen + protocol.ByteCount(sealer.Overhead()) + pl.length + paddingLen\n\n\tstartLen := len(buffer.Data)\n\traw := buffer.Data[startLen:]\n\traw, err := header.Append(raw, v)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpayloadOffset := protocol.ByteCount(len(raw))\n\n\traw, err = p.appendPacketPayload(raw, pl, paddingLen, v)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\traw = p.encryptPacket(raw, sealer, header.PacketNumber, payloadOffset, pnLen)\n\tbuffer.Data = buffer.Data[:len(buffer.Data)+len(raw)]\n\n\tif pn := p.pnManager.PopPacketNumber(encLevel); pn != header.PacketNumber {\n\t\treturn nil, fmt.Errorf(\"packetPacker BUG: Peeked and Popped packet numbers do not match: expected %d, got %d\", pn, header.PacketNumber)\n\t}\n\treturn &longHeaderPacket{\n\t\theader:       header,\n\t\tack:          pl.ack,\n\t\tframes:       pl.frames,\n\t\tstreamFrames: pl.streamFrames,\n\t\tlength:       protocol.ByteCount(len(raw)),\n\t}, nil\n}\n\nfunc (p *packetPacker) appendShortHeaderPacket(\n\tbuffer *packetBuffer,\n\tconnID protocol.ConnectionID,\n\tpn protocol.PacketNumber,\n\tpnLen protocol.PacketNumberLen,\n\tkp protocol.KeyPhaseBit,\n\tpl payload,\n\tpadding, maxPacketSize protocol.ByteCount,\n\tsealer sealer,\n\tisMTUProbePacket bool,\n\tv protocol.Version,\n) (shortHeaderPacket, error) {\n\tvar paddingLen protocol.ByteCount\n\tif pl.length < 4-protocol.ByteCount(pnLen) {\n\t\tpaddingLen = 4 - protocol.ByteCount(pnLen) - pl.length\n\t}\n\tpaddingLen += padding\n\n\tstartLen := len(buffer.Data)\n\traw := buffer.Data[startLen:]\n\traw, err := wire.AppendShortHeader(raw, connID, pn, pnLen, kp)\n\tif err != nil {\n\t\treturn shortHeaderPacket{}, err\n\t}\n\tpayloadOffset := protocol.ByteCount(len(raw))\n\n\traw, err = p.appendPacketPayload(raw, pl, paddingLen, v)\n\tif err != nil {\n\t\treturn shortHeaderPacket{}, err\n\t}\n\tif !isMTUProbePacket {\n\t\tif size := protocol.ByteCount(len(raw) + sealer.Overhead()); size > maxPacketSize {\n\t\t\treturn shortHeaderPacket{}, fmt.Errorf(\"PacketPacker BUG: packet too large (%d bytes, allowed %d bytes)\", size, maxPacketSize)\n\t\t}\n\t}\n\traw = p.encryptPacket(raw, sealer, pn, payloadOffset, protocol.ByteCount(pnLen))\n\tbuffer.Data = buffer.Data[:len(buffer.Data)+len(raw)]\n\n\tif newPN := p.pnManager.PopPacketNumber(protocol.Encryption1RTT); newPN != pn {\n\t\treturn shortHeaderPacket{}, fmt.Errorf(\"packetPacker BUG: Peeked and Popped packet numbers do not match: expected %d, got %d\", pn, newPN)\n\t}\n\treturn shortHeaderPacket{\n\t\tPacketNumber:         pn,\n\t\tPacketNumberLen:      pnLen,\n\t\tKeyPhase:             kp,\n\t\tStreamFrames:         pl.streamFrames,\n\t\tFrames:               pl.frames,\n\t\tAck:                  pl.ack,\n\t\tLength:               protocol.ByteCount(len(raw)),\n\t\tDestConnID:           connID,\n\t\tIsPathMTUProbePacket: isMTUProbePacket,\n\t}, nil\n}\n\n// appendPacketPayload serializes the payload of a packet into the raw byte slice.\n// It modifies the order of payload.frames.\nfunc (p *packetPacker) appendPacketPayload(raw []byte, pl payload, paddingLen protocol.ByteCount, v protocol.Version) ([]byte, error) {\n\tpayloadOffset := len(raw)\n\tif pl.ack != nil {\n\t\tvar err error\n\t\traw, err = pl.ack.Append(raw, v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif paddingLen > 0 {\n\t\traw = append(raw, make([]byte, paddingLen)...)\n\t}\n\t// Randomize the order of the control frames.\n\t// This makes sure that the receiver doesn't rely on the order in which frames are packed.\n\tif len(pl.frames) > 1 {\n\t\tp.rand.Shuffle(len(pl.frames), func(i, j int) { pl.frames[i], pl.frames[j] = pl.frames[j], pl.frames[i] })\n\t}\n\tfor _, f := range pl.frames {\n\t\tvar err error\n\t\traw, err = f.Frame.Append(raw, v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tfor _, f := range pl.streamFrames {\n\t\tvar err error\n\t\traw, err = f.Frame.Append(raw, v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif payloadSize := protocol.ByteCount(len(raw)-payloadOffset) - paddingLen; payloadSize != pl.length {\n\t\treturn nil, fmt.Errorf(\"PacketPacker BUG: payload size inconsistent (expected %d, got %d bytes)\", pl.length, payloadSize)\n\t}\n\treturn raw, nil\n}\n\nfunc (p *packetPacker) encryptPacket(raw []byte, sealer sealer, pn protocol.PacketNumber, payloadOffset, pnLen protocol.ByteCount) []byte {\n\t_ = sealer.Seal(raw[payloadOffset:payloadOffset], raw[payloadOffset:], pn, raw[:payloadOffset])\n\traw = raw[:len(raw)+sealer.Overhead()]\n\t// apply header protection\n\tpnOffset := payloadOffset - pnLen\n\tsealer.EncryptHeader(raw[pnOffset+4:pnOffset+4+16], &raw[0], raw[pnOffset:payloadOffset])\n\treturn raw\n}\n\nfunc (p *packetPacker) SetToken(token []byte) {\n\tp.token = token\n}\n\ntype emptyHandler struct{}\n\nvar _ ackhandler.FrameHandler = emptyHandler{}\n\nfunc (emptyHandler) OnAcked(wire.Frame) {}\nfunc (emptyHandler) OnLost(wire.Frame)  {}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/packet_unpacker.go",
    "content": "package quic\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/handshake\"\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\ntype headerDecryptor interface {\n\tDecryptHeader(sample []byte, firstByte *byte, pnBytes []byte)\n}\n\ntype headerParseError struct {\n\terr error\n}\n\nfunc (e *headerParseError) Unwrap() error {\n\treturn e.err\n}\n\nfunc (e *headerParseError) Error() string {\n\treturn e.err.Error()\n}\n\ntype unpackedPacket struct {\n\thdr             *wire.ExtendedHeader\n\tencryptionLevel protocol.EncryptionLevel\n\tdata            []byte\n}\n\n// The packetUnpacker unpacks QUIC packets.\ntype packetUnpacker struct {\n\tcs handshake.CryptoSetup\n\n\tshortHdrConnIDLen int\n}\n\nvar _ unpacker = &packetUnpacker{}\n\nfunc newPacketUnpacker(cs handshake.CryptoSetup, shortHdrConnIDLen int) *packetUnpacker {\n\treturn &packetUnpacker{\n\t\tcs:                cs,\n\t\tshortHdrConnIDLen: shortHdrConnIDLen,\n\t}\n}\n\n// UnpackLongHeader unpacks a Long Header packet.\n// If the reserved bits are invalid, the error is wire.ErrInvalidReservedBits.\n// If any other error occurred when parsing the header, the error is of type headerParseError.\n// If decrypting the payload fails for any reason, the error is the error returned by the AEAD.\nfunc (u *packetUnpacker) UnpackLongHeader(hdr *wire.Header, data []byte) (*unpackedPacket, error) {\n\tvar encLevel protocol.EncryptionLevel\n\tvar extHdr *wire.ExtendedHeader\n\tvar decrypted []byte\n\t//nolint:exhaustive // Retry packets can't be unpacked.\n\tswitch hdr.Type {\n\tcase protocol.PacketTypeInitial:\n\t\tencLevel = protocol.EncryptionInitial\n\t\topener, err := u.cs.GetInitialOpener()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\textHdr, decrypted, err = u.unpackLongHeaderPacket(opener, hdr, data)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\tcase protocol.PacketTypeHandshake:\n\t\tencLevel = protocol.EncryptionHandshake\n\t\topener, err := u.cs.GetHandshakeOpener()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\textHdr, decrypted, err = u.unpackLongHeaderPacket(opener, hdr, data)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\tcase protocol.PacketType0RTT:\n\t\tencLevel = protocol.Encryption0RTT\n\t\topener, err := u.cs.Get0RTTOpener()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\textHdr, decrypted, err = u.unpackLongHeaderPacket(opener, hdr, data)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown packet type: %s\", hdr.Type)\n\t}\n\n\tif len(decrypted) == 0 {\n\t\treturn nil, &qerr.TransportError{\n\t\t\tErrorCode:    qerr.ProtocolViolation,\n\t\t\tErrorMessage: \"empty packet\",\n\t\t}\n\t}\n\n\treturn &unpackedPacket{\n\t\thdr:             extHdr,\n\t\tencryptionLevel: encLevel,\n\t\tdata:            decrypted,\n\t}, nil\n}\n\nfunc (u *packetUnpacker) UnpackShortHeader(rcvTime time.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) {\n\topener, err := u.cs.Get1RTTOpener()\n\tif err != nil {\n\t\treturn 0, 0, 0, nil, err\n\t}\n\tpn, pnLen, kp, decrypted, err := u.unpackShortHeaderPacket(opener, rcvTime, data)\n\tif err != nil {\n\t\treturn 0, 0, 0, nil, err\n\t}\n\tif len(decrypted) == 0 {\n\t\treturn 0, 0, 0, nil, &qerr.TransportError{\n\t\t\tErrorCode:    qerr.ProtocolViolation,\n\t\t\tErrorMessage: \"empty packet\",\n\t\t}\n\t}\n\treturn pn, pnLen, kp, decrypted, nil\n}\n\nfunc (u *packetUnpacker) unpackLongHeaderPacket(opener handshake.LongHeaderOpener, hdr *wire.Header, data []byte) (*wire.ExtendedHeader, []byte, error) {\n\textHdr, parseErr := u.unpackLongHeader(opener, hdr, data)\n\t// If the reserved bits are set incorrectly, we still need to continue unpacking.\n\t// This avoids a timing side-channel, which otherwise might allow an attacker\n\t// to gain information about the header encryption.\n\tif parseErr != nil && parseErr != wire.ErrInvalidReservedBits {\n\t\treturn nil, nil, parseErr\n\t}\n\textHdrLen := extHdr.ParsedLen()\n\textHdr.PacketNumber = opener.DecodePacketNumber(extHdr.PacketNumber, extHdr.PacketNumberLen)\n\tdecrypted, err := opener.Open(data[extHdrLen:extHdrLen], data[extHdrLen:], extHdr.PacketNumber, data[:extHdrLen])\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tif parseErr != nil {\n\t\treturn nil, nil, parseErr\n\t}\n\treturn extHdr, decrypted, nil\n}\n\nfunc (u *packetUnpacker) unpackShortHeaderPacket(opener handshake.ShortHeaderOpener, rcvTime time.Time, data []byte) (protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, []byte, error) {\n\tl, pn, pnLen, kp, parseErr := u.unpackShortHeader(opener, data)\n\t// If the reserved bits are set incorrectly, we still need to continue unpacking.\n\t// This avoids a timing side-channel, which otherwise might allow an attacker\n\t// to gain information about the header encryption.\n\tif parseErr != nil && parseErr != wire.ErrInvalidReservedBits {\n\t\treturn 0, 0, 0, nil, &headerParseError{parseErr}\n\t}\n\tpn = opener.DecodePacketNumber(pn, pnLen)\n\tdecrypted, err := opener.Open(data[l:l], data[l:], rcvTime, pn, kp, data[:l])\n\tif err != nil {\n\t\treturn 0, 0, 0, nil, err\n\t}\n\treturn pn, pnLen, kp, decrypted, parseErr\n}\n\nfunc (u *packetUnpacker) unpackShortHeader(hd headerDecryptor, data []byte) (int, protocol.PacketNumber, protocol.PacketNumberLen, protocol.KeyPhaseBit, error) {\n\thdrLen := 1 /* first header byte */ + u.shortHdrConnIDLen\n\tif len(data) < hdrLen+4+16 {\n\t\treturn 0, 0, 0, 0, fmt.Errorf(\"packet too small, expected at least 20 bytes after the header, got %d\", len(data)-hdrLen)\n\t}\n\torigPNBytes := make([]byte, 4)\n\tcopy(origPNBytes, data[hdrLen:hdrLen+4])\n\t// 2. decrypt the header, assuming a 4 byte packet number\n\thd.DecryptHeader(\n\t\tdata[hdrLen+4:hdrLen+4+16],\n\t\t&data[0],\n\t\tdata[hdrLen:hdrLen+4],\n\t)\n\t// 3. parse the header (and learn the actual length of the packet number)\n\tl, pn, pnLen, kp, parseErr := wire.ParseShortHeader(data, u.shortHdrConnIDLen)\n\tif parseErr != nil && parseErr != wire.ErrInvalidReservedBits {\n\t\treturn l, pn, pnLen, kp, parseErr\n\t}\n\t// 4. if the packet number is shorter than 4 bytes, replace the remaining bytes with the copy we saved earlier\n\tif pnLen != protocol.PacketNumberLen4 {\n\t\tcopy(data[hdrLen+int(pnLen):hdrLen+4], origPNBytes[int(pnLen):])\n\t}\n\treturn l, pn, pnLen, kp, parseErr\n}\n\n// The error is either nil, a wire.ErrInvalidReservedBits or of type headerParseError.\nfunc (u *packetUnpacker) unpackLongHeader(hd headerDecryptor, hdr *wire.Header, data []byte) (*wire.ExtendedHeader, error) {\n\textHdr, err := unpackLongHeader(hd, hdr, data)\n\tif err != nil && err != wire.ErrInvalidReservedBits {\n\t\treturn nil, &headerParseError{err: err}\n\t}\n\treturn extHdr, err\n}\n\nfunc unpackLongHeader(hd headerDecryptor, hdr *wire.Header, data []byte) (*wire.ExtendedHeader, error) {\n\thdrLen := hdr.ParsedLen()\n\tif protocol.ByteCount(len(data)) < hdrLen+4+16 {\n\t\treturn nil, fmt.Errorf(\"packet too small, expected at least 20 bytes after the header, got %d\", protocol.ByteCount(len(data))-hdrLen)\n\t}\n\t// The packet number can be up to 4 bytes long, but we won't know the length until we decrypt it.\n\t// 1. save a copy of the 4 bytes\n\torigPNBytes := make([]byte, 4)\n\tcopy(origPNBytes, data[hdrLen:hdrLen+4])\n\t// 2. decrypt the header, assuming a 4 byte packet number\n\thd.DecryptHeader(\n\t\tdata[hdrLen+4:hdrLen+4+16],\n\t\t&data[0],\n\t\tdata[hdrLen:hdrLen+4],\n\t)\n\t// 3. parse the header (and learn the actual length of the packet number)\n\textHdr, parseErr := hdr.ParseExtended(data)\n\tif parseErr != nil && parseErr != wire.ErrInvalidReservedBits {\n\t\treturn nil, parseErr\n\t}\n\t// 4. if the packet number is shorter than 4 bytes, replace the remaining bytes with the copy we saved earlier\n\tif extHdr.PacketNumberLen != protocol.PacketNumberLen4 {\n\t\tcopy(data[extHdr.ParsedLen():hdrLen+4], origPNBytes[int(extHdr.PacketNumberLen):])\n\t}\n\treturn extHdr, parseErr\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/path_manager.go",
    "content": "package quic\n\nimport (\n\t\"crypto/rand\"\n\t\"net\"\n\t\"slices\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/ackhandler\"\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\ntype pathID int64\n\nconst invalidPathID pathID = -1\n\n// Maximum number of paths to keep track of.\n// If the peer probes another path (before the pathTimeout of an existing path expires),\n// this probing attempt is ignored.\nconst maxPaths = 3\n\n// If no packet is received for a path for pathTimeout,\n// the path can be evicted when the peer probes another path.\n// This prevents an attacker from churning through paths by duplicating packets and\n// sending them with spoofed source addresses.\nconst pathTimeout = 5 * time.Second\n\ntype path struct {\n\tid             pathID\n\taddr           net.Addr\n\tlastPacketTime time.Time\n\tpathChallenge  [8]byte\n\tvalidated      bool\n\trcvdNonProbing bool\n}\n\ntype pathManager struct {\n\tnextPathID pathID\n\t// ordered by lastPacketTime, with the most recently used path at the end\n\tpaths []*path\n\n\tgetConnID    func(pathID) (_ protocol.ConnectionID, ok bool)\n\tretireConnID func(pathID)\n\n\tlogger utils.Logger\n}\n\nfunc newPathManager(\n\tgetConnID func(pathID) (_ protocol.ConnectionID, ok bool),\n\tretireConnID func(pathID),\n\tlogger utils.Logger,\n) *pathManager {\n\treturn &pathManager{\n\t\tpaths:        make([]*path, 0, maxPaths+1),\n\t\tgetConnID:    getConnID,\n\t\tretireConnID: retireConnID,\n\t\tlogger:       logger,\n\t}\n}\n\n// Returns a path challenge frame if one should be sent.\n// May return nil.\nfunc (pm *pathManager) HandlePacket(\n\tremoteAddr net.Addr,\n\tt time.Time,\n\tpathChallenge *wire.PathChallengeFrame, // may be nil if the packet didn't contain a PATH_CHALLENGE\n\tisNonProbing bool,\n) (_ protocol.ConnectionID, _ []ackhandler.Frame, shouldSwitch bool) {\n\tvar p *path\n\tfor i, path := range pm.paths {\n\t\tif addrsEqual(path.addr, remoteAddr) {\n\t\t\tp = path\n\t\t\tp.lastPacketTime = t\n\t\t\t// already sent a PATH_CHALLENGE for this path\n\t\t\tif isNonProbing {\n\t\t\t\tpath.rcvdNonProbing = true\n\t\t\t}\n\t\t\tif pm.logger.Debug() {\n\t\t\t\tpm.logger.Debugf(\"received packet for path %s that was already probed, validated: %t\", remoteAddr, path.validated)\n\t\t\t}\n\t\t\tshouldSwitch = path.validated && path.rcvdNonProbing\n\t\t\tif i != len(pm.paths)-1 {\n\t\t\t\t// move the path to the end of the list\n\t\t\t\tpm.paths = slices.Delete(pm.paths, i, i+1)\n\t\t\t\tpm.paths = append(pm.paths, p)\n\t\t\t}\n\t\t\tif pathChallenge == nil {\n\t\t\t\treturn protocol.ConnectionID{}, nil, shouldSwitch\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(pm.paths) >= maxPaths {\n\t\tif pm.paths[0].lastPacketTime.Add(pathTimeout).After(t) {\n\t\t\tif pm.logger.Debug() {\n\t\t\t\tpm.logger.Debugf(\"received packet for previously unseen path %s, but already have %d paths\", remoteAddr, len(pm.paths))\n\t\t\t}\n\t\t\treturn protocol.ConnectionID{}, nil, shouldSwitch\n\t\t}\n\t\t// evict the oldest path, if the last packet was received more than pathTimeout ago\n\t\tpm.retireConnID(pm.paths[0].id)\n\t\tpm.paths = pm.paths[1:]\n\t}\n\n\tvar pathID pathID\n\tif p != nil {\n\t\tpathID = p.id\n\t} else {\n\t\tpathID = pm.nextPathID\n\t}\n\n\t// previously unseen path, initiate path validation by sending a PATH_CHALLENGE\n\tconnID, ok := pm.getConnID(pathID)\n\tif !ok {\n\t\tpm.logger.Debugf(\"skipping validation of new path %s since no connection ID is available\", remoteAddr)\n\t\treturn protocol.ConnectionID{}, nil, shouldSwitch\n\t}\n\n\tframes := make([]ackhandler.Frame, 0, 2)\n\tif p == nil {\n\t\tvar pathChallengeData [8]byte\n\t\trand.Read(pathChallengeData[:])\n\t\tp = &path{\n\t\t\tid:             pm.nextPathID,\n\t\t\taddr:           remoteAddr,\n\t\t\tlastPacketTime: t,\n\t\t\trcvdNonProbing: isNonProbing,\n\t\t\tpathChallenge:  pathChallengeData,\n\t\t}\n\t\tpm.nextPathID++\n\t\tpm.paths = append(pm.paths, p)\n\t\tframes = append(frames, ackhandler.Frame{\n\t\t\tFrame:   &wire.PathChallengeFrame{Data: p.pathChallenge},\n\t\t\tHandler: (*pathManagerAckHandler)(pm),\n\t\t})\n\t\tpm.logger.Debugf(\"enqueueing PATH_CHALLENGE for new path %s\", remoteAddr)\n\t}\n\tif pathChallenge != nil {\n\t\tframes = append(frames, ackhandler.Frame{\n\t\t\tFrame:   &wire.PathResponseFrame{Data: pathChallenge.Data},\n\t\t\tHandler: (*pathManagerAckHandler)(pm),\n\t\t})\n\t}\n\treturn connID, frames, shouldSwitch\n}\n\nfunc (pm *pathManager) HandlePathResponseFrame(f *wire.PathResponseFrame) {\n\tfor _, p := range pm.paths {\n\t\tif f.Data == p.pathChallenge {\n\t\t\t// path validated\n\t\t\tp.validated = true\n\t\t\tpm.logger.Debugf(\"path %s validated\", p.addr)\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n// SwitchToPath is called when the connection switches to a new path\nfunc (pm *pathManager) SwitchToPath(addr net.Addr) {\n\t// retire all other paths\n\tfor _, path := range pm.paths {\n\t\tif addrsEqual(path.addr, addr) {\n\t\t\tpm.logger.Debugf(\"switching to path %d (%s)\", path.id, addr)\n\t\t\tcontinue\n\t\t}\n\t\tpm.retireConnID(path.id)\n\t}\n\tclear(pm.paths)\n\tpm.paths = pm.paths[:0]\n}\n\ntype pathManagerAckHandler pathManager\n\nvar _ ackhandler.FrameHandler = &pathManagerAckHandler{}\n\n// Acknowledging the frame doesn't validate the path, only receiving the PATH_RESPONSE does.\nfunc (pm *pathManagerAckHandler) OnAcked(f wire.Frame) {}\n\nfunc (pm *pathManagerAckHandler) OnLost(f wire.Frame) {\n\tpc, ok := f.(*wire.PathChallengeFrame)\n\tif !ok {\n\t\treturn\n\t}\n\tfor i, path := range pm.paths {\n\t\tif path.pathChallenge == pc.Data {\n\t\t\tpm.paths = slices.Delete(pm.paths, i, i+1)\n\t\t\tpm.retireConnID(path.id)\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc addrsEqual(addr1, addr2 net.Addr) bool {\n\tif addr1 == nil || addr2 == nil {\n\t\treturn false\n\t}\n\ta1, ok1 := addr1.(*net.UDPAddr)\n\ta2, ok2 := addr2.(*net.UDPAddr)\n\tif ok1 && ok2 {\n\t\treturn a1.IP.Equal(a2.IP) && a1.Port == a2.Port\n\t}\n\treturn addr1.String() == addr2.String()\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/path_manager_outgoing.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"errors\"\n\t\"slices\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/ackhandler\"\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\nvar (\n\t// ErrPathClosed is returned when trying to switch to a path that has been closed.\n\tErrPathClosed = errors.New(\"path closed\")\n\t// ErrPathNotValidated is returned when trying to use a path before path probing has completed.\n\tErrPathNotValidated = errors.New(\"path not yet validated\")\n)\n\nvar errPathDoesNotExist = errors.New(\"path does not exist\")\n\n// Path is a network path.\ntype Path struct {\n\tid          pathID\n\tpathManager *pathManagerOutgoing\n\ttr          *Transport\n\tinitialRTT  time.Duration\n\n\tenablePath func()\n\tvalidated  atomic.Bool\n\tabandon    chan struct{}\n}\n\nfunc (p *Path) Probe(ctx context.Context) error {\n\tpath := p.pathManager.addPath(p, p.enablePath)\n\n\tp.pathManager.enqueueProbe(p)\n\tnextProbeDur := p.initialRTT\n\tvar timer *time.Timer\n\tvar timerChan <-chan time.Time\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn context.Cause(ctx)\n\t\tcase <-path.Validated():\n\t\t\tp.validated.Store(true)\n\t\t\treturn nil\n\t\tcase <-timerChan:\n\t\t\tp.pathManager.enqueueProbe(p)\n\t\tcase <-path.ProbeSent():\n\t\tcase <-p.abandon:\n\t\t\treturn ErrPathClosed\n\t\t}\n\n\t\tif timer != nil {\n\t\t\ttimer.Stop()\n\t\t}\n\t\ttimer = time.NewTimer(nextProbeDur)\n\t\ttimerChan = timer.C\n\t\tnextProbeDur *= 2 // exponential backoff\n\t}\n}\n\n// Switch switches the QUIC connection to this path.\n// It immediately stops sending on the old path, and sends on this new path.\nfunc (p *Path) Switch() error {\n\tif err := p.pathManager.switchToPath(p.id); err != nil {\n\t\tswitch {\n\t\tcase errors.Is(err, ErrPathNotValidated):\n\t\t\treturn err\n\t\tcase errors.Is(err, errPathDoesNotExist) && !p.validated.Load():\n\t\t\tselect {\n\t\t\tcase <-p.abandon:\n\t\t\t\treturn ErrPathClosed\n\t\t\tdefault:\n\t\t\t\treturn ErrPathNotValidated\n\t\t\t}\n\t\tdefault:\n\t\t\treturn ErrPathClosed\n\t\t}\n\t}\n\treturn nil\n}\n\n// Close abandons a path.\n// It is not possible to close the path that’s currently active.\n// After closing, it is not possible to probe this path again.\nfunc (p *Path) Close() error {\n\tselect {\n\tcase <-p.abandon:\n\t\treturn nil\n\tdefault:\n\t}\n\n\tif err := p.pathManager.removePath(p.id); err != nil {\n\t\treturn err\n\t}\n\tclose(p.abandon)\n\treturn nil\n}\n\ntype pathOutgoing struct {\n\tpathChallenges [][8]byte // length is implicitly limited by exponential backoff\n\ttr             *Transport\n\tisValidated    bool\n\tprobeSent      chan struct{} // receives when a PATH_CHALLENGE is sent\n\tvalidated      chan struct{} // closed when the path the corresponding PATH_RESPONSE is received\n\tenablePath     func()\n}\n\nfunc (p *pathOutgoing) ProbeSent() <-chan struct{} { return p.probeSent }\nfunc (p *pathOutgoing) Validated() <-chan struct{} { return p.validated }\n\ntype pathManagerOutgoing struct {\n\tgetConnID       func(pathID) (_ protocol.ConnectionID, ok bool)\n\tretireConnID    func(pathID)\n\tscheduleSending func()\n\n\tmx             sync.Mutex\n\tactivePath     pathID\n\tpathsToProbe   []pathID\n\tpaths          map[pathID]*pathOutgoing\n\tnextPathID     pathID\n\tpathToSwitchTo *pathOutgoing\n}\n\nfunc newPathManagerOutgoing(\n\tgetConnID func(pathID) (_ protocol.ConnectionID, ok bool),\n\tretireConnID func(pathID),\n\tscheduleSending func(),\n) *pathManagerOutgoing {\n\treturn &pathManagerOutgoing{\n\t\tactivePath:      0, // at initialization time, we're guaranteed to be using the handshake path\n\t\tnextPathID:      1,\n\t\tgetConnID:       getConnID,\n\t\tretireConnID:    retireConnID,\n\t\tscheduleSending: scheduleSending,\n\t\tpaths:           make(map[pathID]*pathOutgoing, 4),\n\t}\n}\n\nfunc (pm *pathManagerOutgoing) addPath(p *Path, enablePath func()) *pathOutgoing {\n\tpm.mx.Lock()\n\tdefer pm.mx.Unlock()\n\n\t// path might already exist, and just being re-probed\n\tif existingPath, ok := pm.paths[p.id]; ok {\n\t\texistingPath.validated = make(chan struct{})\n\t\treturn existingPath\n\t}\n\n\tpath := &pathOutgoing{\n\t\ttr:         p.tr,\n\t\tprobeSent:  make(chan struct{}, 1),\n\t\tvalidated:  make(chan struct{}),\n\t\tenablePath: enablePath,\n\t}\n\tpm.paths[p.id] = path\n\treturn path\n}\n\nfunc (pm *pathManagerOutgoing) enqueueProbe(p *Path) {\n\tpm.mx.Lock()\n\tpm.pathsToProbe = append(pm.pathsToProbe, p.id)\n\tpm.mx.Unlock()\n\tpm.scheduleSending()\n}\n\nfunc (pm *pathManagerOutgoing) removePath(id pathID) error {\n\tif err := pm.removePathImpl(id); err != nil {\n\t\treturn err\n\t}\n\tpm.scheduleSending()\n\treturn nil\n}\n\nfunc (pm *pathManagerOutgoing) removePathImpl(id pathID) error {\n\tpm.mx.Lock()\n\tdefer pm.mx.Unlock()\n\n\tif id == pm.activePath {\n\t\treturn errors.New(\"cannot close active path\")\n\t}\n\tp, ok := pm.paths[id]\n\tif !ok {\n\t\treturn nil\n\t}\n\tif len(p.pathChallenges) > 0 {\n\t\tpm.retireConnID(id)\n\t}\n\tdelete(pm.paths, id)\n\treturn nil\n}\n\nfunc (pm *pathManagerOutgoing) switchToPath(id pathID) error {\n\tpm.mx.Lock()\n\tdefer pm.mx.Unlock()\n\n\tp, ok := pm.paths[id]\n\tif !ok {\n\t\treturn errPathDoesNotExist\n\t}\n\tif !p.isValidated {\n\t\treturn ErrPathNotValidated\n\t}\n\tpm.pathToSwitchTo = p\n\tpm.activePath = id\n\treturn nil\n}\n\nfunc (pm *pathManagerOutgoing) NewPath(t *Transport, initialRTT time.Duration, enablePath func()) *Path {\n\tpm.mx.Lock()\n\tdefer pm.mx.Unlock()\n\n\tid := pm.nextPathID\n\tpm.nextPathID++\n\treturn &Path{\n\t\tpathManager: pm,\n\t\tid:          id,\n\t\ttr:          t,\n\t\tenablePath:  enablePath,\n\t\tinitialRTT:  initialRTT,\n\t\tabandon:     make(chan struct{}),\n\t}\n}\n\nfunc (pm *pathManagerOutgoing) NextPathToProbe() (_ protocol.ConnectionID, _ ackhandler.Frame, _ *Transport, hasPath bool) {\n\tpm.mx.Lock()\n\tdefer pm.mx.Unlock()\n\n\tvar p *pathOutgoing\n\tid := invalidPathID\n\tfor _, pID := range pm.pathsToProbe {\n\t\tvar ok bool\n\t\tp, ok = pm.paths[pID]\n\t\tif ok {\n\t\t\tid = pID\n\t\t\tbreak\n\t\t}\n\t\t// if the path doesn't exist in the map, it might have been abandoned\n\t\tpm.pathsToProbe = pm.pathsToProbe[1:]\n\t}\n\tif id == invalidPathID {\n\t\treturn protocol.ConnectionID{}, ackhandler.Frame{}, nil, false\n\t}\n\n\tconnID, ok := pm.getConnID(id)\n\tif !ok {\n\t\treturn protocol.ConnectionID{}, ackhandler.Frame{}, nil, false\n\t}\n\n\tvar b [8]byte\n\t_, _ = rand.Read(b[:])\n\tp.pathChallenges = append(p.pathChallenges, b)\n\n\tpm.pathsToProbe = pm.pathsToProbe[1:]\n\tp.enablePath()\n\tselect {\n\tcase p.probeSent <- struct{}{}:\n\tdefault:\n\t}\n\tframe := ackhandler.Frame{\n\t\tFrame:   &wire.PathChallengeFrame{Data: b},\n\t\tHandler: (*pathManagerOutgoingAckHandler)(pm),\n\t}\n\treturn connID, frame, p.tr, true\n}\n\nfunc (pm *pathManagerOutgoing) HandlePathResponseFrame(f *wire.PathResponseFrame) {\n\tpm.mx.Lock()\n\tdefer pm.mx.Unlock()\n\n\tfor _, p := range pm.paths {\n\t\tif slices.Contains(p.pathChallenges, f.Data) {\n\t\t\t// path validated\n\t\t\tif !p.isValidated {\n\t\t\t\t// make sure that duplicate PATH_RESPONSE frames are ignored\n\t\t\t\tp.isValidated = true\n\t\t\t\tp.pathChallenges = nil\n\t\t\t\tclose(p.validated)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc (pm *pathManagerOutgoing) ShouldSwitchPath() (*Transport, bool) {\n\tpm.mx.Lock()\n\tdefer pm.mx.Unlock()\n\n\tif pm.pathToSwitchTo == nil {\n\t\treturn nil, false\n\t}\n\tp := pm.pathToSwitchTo\n\tpm.pathToSwitchTo = nil\n\treturn p.tr, true\n}\n\ntype pathManagerOutgoingAckHandler pathManagerOutgoing\n\nvar _ ackhandler.FrameHandler = &pathManagerOutgoingAckHandler{}\n\n// OnAcked is called when the PATH_CHALLENGE is acked.\n// This doesn't validate the path, only receiving the PATH_RESPONSE does.\nfunc (pm *pathManagerOutgoingAckHandler) OnAcked(wire.Frame) {}\n\nfunc (pm *pathManagerOutgoingAckHandler) OnLost(wire.Frame) {}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/quicvarint/io.go",
    "content": "package quicvarint\n\nimport (\n\t\"bytes\"\n\t\"io\"\n)\n\n// Reader implements both the io.ByteReader and io.Reader interfaces.\ntype Reader interface {\n\tio.ByteReader\n\tio.Reader\n}\n\nvar _ Reader = &bytes.Reader{}\n\ntype byteReader struct {\n\tio.Reader\n}\n\nvar _ Reader = &byteReader{}\n\n// NewReader returns a Reader for r.\n// If r already implements both io.ByteReader and io.Reader, NewReader returns r.\n// Otherwise, r is wrapped to add the missing interfaces.\nfunc NewReader(r io.Reader) Reader {\n\tif r, ok := r.(Reader); ok {\n\t\treturn r\n\t}\n\treturn &byteReader{r}\n}\n\nfunc (r *byteReader) ReadByte() (byte, error) {\n\tvar b [1]byte\n\tn, err := r.Read(b[:])\n\tif n == 1 && err == io.EOF {\n\t\terr = nil\n\t}\n\treturn b[0], err\n}\n\n// Writer implements both the io.ByteWriter and io.Writer interfaces.\ntype Writer interface {\n\tio.ByteWriter\n\tio.Writer\n}\n\nvar _ Writer = &bytes.Buffer{}\n\ntype byteWriter struct {\n\tio.Writer\n}\n\nvar _ Writer = &byteWriter{}\n\n// NewWriter returns a Writer for w.\n// If r already implements both io.ByteWriter and io.Writer, NewWriter returns w.\n// Otherwise, w is wrapped to add the missing interfaces.\nfunc NewWriter(w io.Writer) Writer {\n\tif w, ok := w.(Writer); ok {\n\t\treturn w\n\t}\n\treturn &byteWriter{w}\n}\n\nfunc (w *byteWriter) WriteByte(c byte) error {\n\t_, err := w.Write([]byte{c})\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/quicvarint/varint.go",
    "content": "package quicvarint\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n// taken from the QUIC draft\nconst (\n\t// Min is the minimum value allowed for a QUIC varint.\n\tMin = 0\n\n\t// Max is the maximum allowed value for a QUIC varint (2^62-1).\n\tMax = maxVarInt8\n\n\tmaxVarInt1 = 63\n\tmaxVarInt2 = 16383\n\tmaxVarInt4 = 1073741823\n\tmaxVarInt8 = 4611686018427387903\n)\n\n// Read reads a number in the QUIC varint format from r.\nfunc Read(r io.ByteReader) (uint64, error) {\n\tfirstByte, err := r.ReadByte()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\t// the first two bits of the first byte encode the length\n\tl := 1 << ((firstByte & 0xc0) >> 6)\n\tb1 := firstByte & (0xff - 0xc0)\n\tif l == 1 {\n\t\treturn uint64(b1), nil\n\t}\n\tb2, err := r.ReadByte()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif l == 2 {\n\t\treturn uint64(b2) + uint64(b1)<<8, nil\n\t}\n\tb3, err := r.ReadByte()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tb4, err := r.ReadByte()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif l == 4 {\n\t\treturn uint64(b4) + uint64(b3)<<8 + uint64(b2)<<16 + uint64(b1)<<24, nil\n\t}\n\tb5, err := r.ReadByte()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tb6, err := r.ReadByte()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tb7, err := r.ReadByte()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tb8, err := r.ReadByte()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn uint64(b8) + uint64(b7)<<8 + uint64(b6)<<16 + uint64(b5)<<24 + uint64(b4)<<32 + uint64(b3)<<40 + uint64(b2)<<48 + uint64(b1)<<56, nil\n}\n\n// Parse reads a number in the QUIC varint format.\n// It returns the number of bytes consumed.\nfunc Parse(b []byte) (uint64 /* value */, int /* bytes consumed */, error) {\n\tif len(b) == 0 {\n\t\treturn 0, 0, io.EOF\n\t}\n\tfirstByte := b[0]\n\t// the first two bits of the first byte encode the length\n\tl := 1 << ((firstByte & 0xc0) >> 6)\n\tif len(b) < l {\n\t\treturn 0, 0, io.ErrUnexpectedEOF\n\t}\n\tb0 := firstByte & (0xff - 0xc0)\n\tif l == 1 {\n\t\treturn uint64(b0), 1, nil\n\t}\n\tif l == 2 {\n\t\treturn uint64(b[1]) + uint64(b0)<<8, 2, nil\n\t}\n\tif l == 4 {\n\t\treturn uint64(b[3]) + uint64(b[2])<<8 + uint64(b[1])<<16 + uint64(b0)<<24, 4, nil\n\t}\n\treturn uint64(b[7]) + uint64(b[6])<<8 + uint64(b[5])<<16 + uint64(b[4])<<24 + uint64(b[3])<<32 + uint64(b[2])<<40 + uint64(b[1])<<48 + uint64(b0)<<56, 8, nil\n}\n\n// Append appends i in the QUIC varint format.\nfunc Append(b []byte, i uint64) []byte {\n\tif i <= maxVarInt1 {\n\t\treturn append(b, uint8(i))\n\t}\n\tif i <= maxVarInt2 {\n\t\treturn append(b, []byte{uint8(i>>8) | 0x40, uint8(i)}...)\n\t}\n\tif i <= maxVarInt4 {\n\t\treturn append(b, []byte{uint8(i>>24) | 0x80, uint8(i >> 16), uint8(i >> 8), uint8(i)}...)\n\t}\n\tif i <= maxVarInt8 {\n\t\treturn append(b, []byte{\n\t\t\tuint8(i>>56) | 0xc0, uint8(i >> 48), uint8(i >> 40), uint8(i >> 32),\n\t\t\tuint8(i >> 24), uint8(i >> 16), uint8(i >> 8), uint8(i),\n\t\t}...)\n\t}\n\tpanic(fmt.Sprintf(\"%#x doesn't fit into 62 bits\", i))\n}\n\n// AppendWithLen append i in the QUIC varint format with the desired length.\nfunc AppendWithLen(b []byte, i uint64, length int) []byte {\n\tif length != 1 && length != 2 && length != 4 && length != 8 {\n\t\tpanic(\"invalid varint length\")\n\t}\n\tl := Len(i)\n\tif l == length {\n\t\treturn Append(b, i)\n\t}\n\tif l > length {\n\t\tpanic(fmt.Sprintf(\"cannot encode %d in %d bytes\", i, length))\n\t}\n\tswitch length {\n\tcase 2:\n\t\tb = append(b, 0b01000000)\n\tcase 4:\n\t\tb = append(b, 0b10000000)\n\tcase 8:\n\t\tb = append(b, 0b11000000)\n\t}\n\tfor range length - l - 1 {\n\t\tb = append(b, 0)\n\t}\n\tfor j := range l {\n\t\tb = append(b, uint8(i>>(8*(l-1-j))))\n\t}\n\treturn b\n}\n\n// Len determines the number of bytes that will be needed to write the number i.\nfunc Len(i uint64) int {\n\tif i <= maxVarInt1 {\n\t\treturn 1\n\t}\n\tif i <= maxVarInt2 {\n\t\treturn 2\n\t}\n\tif i <= maxVarInt4 {\n\t\treturn 4\n\t}\n\tif i <= maxVarInt8 {\n\t\treturn 8\n\t}\n\t// Don't use a fmt.Sprintf here to format the error message.\n\t// The function would then exceed the inlining budget.\n\tpanic(struct {\n\t\tmessage string\n\t\tnum     uint64\n\t}{\"value doesn't fit into 62 bits: \", i})\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/receive_stream.go",
    "content": "package quic\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/ackhandler\"\n\t\"github.com/quic-go/quic-go/internal/flowcontrol\"\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\ntype receiveStreamI interface {\n\tReceiveStream\n\n\thandleStreamFrame(*wire.StreamFrame, time.Time) error\n\thandleResetStreamFrame(*wire.ResetStreamFrame, time.Time) error\n\tcloseForShutdown(error)\n}\n\ntype receiveStream struct {\n\tmutex sync.Mutex\n\n\tstreamID protocol.StreamID\n\n\tsender streamSender\n\n\tframeQueue  *frameSorter\n\tfinalOffset protocol.ByteCount\n\n\tcurrentFrame       []byte\n\tcurrentFrameDone   func()\n\treadPosInFrame     int\n\tcurrentFrameIsLast bool // is the currentFrame the last frame on this stream\n\n\tqueuedStopSending   bool\n\tqueuedMaxStreamData bool\n\n\t// Set once we read the io.EOF or the cancellation error.\n\t// Note that for local cancellations, this doesn't necessarily mean that we know the final offset yet.\n\terrorRead           bool\n\tcompleted           bool // set once we've called streamSender.onStreamCompleted\n\tcancelledRemotely   bool\n\tcancelledLocally    bool\n\tcancelErr           *StreamError\n\tcloseForShutdownErr error\n\n\treadChan chan struct{}\n\treadOnce chan struct{} // cap: 1, to protect against concurrent use of Read\n\tdeadline time.Time\n\n\tflowController flowcontrol.StreamFlowController\n}\n\nvar (\n\t_ ReceiveStream            = &receiveStream{}\n\t_ receiveStreamI           = &receiveStream{}\n\t_ streamControlFrameGetter = &receiveStream{}\n)\n\nfunc newReceiveStream(\n\tstreamID protocol.StreamID,\n\tsender streamSender,\n\tflowController flowcontrol.StreamFlowController,\n) *receiveStream {\n\treturn &receiveStream{\n\t\tstreamID:       streamID,\n\t\tsender:         sender,\n\t\tflowController: flowController,\n\t\tframeQueue:     newFrameSorter(),\n\t\treadChan:       make(chan struct{}, 1),\n\t\treadOnce:       make(chan struct{}, 1),\n\t\tfinalOffset:    protocol.MaxByteCount,\n\t}\n}\n\nfunc (s *receiveStream) StreamID() protocol.StreamID {\n\treturn s.streamID\n}\n\n// Read implements io.Reader. It is not thread safe!\nfunc (s *receiveStream) Read(p []byte) (int, error) {\n\t// Concurrent use of Read is not permitted (and doesn't make any sense),\n\t// but sometimes people do it anyway.\n\t// Make sure that we only execute one call at any given time to avoid hard to debug failures.\n\ts.readOnce <- struct{}{}\n\tdefer func() { <-s.readOnce }()\n\n\ts.mutex.Lock()\n\tqueuedStreamWindowUpdate, queuedConnWindowUpdate, n, err := s.readImpl(p)\n\tcompleted := s.isNewlyCompleted()\n\ts.mutex.Unlock()\n\n\tif completed {\n\t\ts.sender.onStreamCompleted(s.streamID)\n\t}\n\tif queuedStreamWindowUpdate {\n\t\ts.sender.onHasStreamControlFrame(s.streamID, s)\n\t}\n\tif queuedConnWindowUpdate {\n\t\ts.sender.onHasConnectionData()\n\t}\n\treturn n, err\n}\n\nfunc (s *receiveStream) isNewlyCompleted() bool {\n\tif s.completed {\n\t\treturn false\n\t}\n\t// We need to know the final offset (either via FIN or RESET_STREAM) for flow control accounting.\n\tif s.finalOffset == protocol.MaxByteCount {\n\t\treturn false\n\t}\n\t// We're done with the stream if it was cancelled locally...\n\tif s.cancelledLocally {\n\t\ts.completed = true\n\t\treturn true\n\t}\n\t// ... or if the error (either io.EOF or the reset error) was read\n\tif s.errorRead {\n\t\ts.completed = true\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (s *receiveStream) readImpl(p []byte) (hasStreamWindowUpdate bool, hasConnWindowUpdate bool, _ int, _ error) {\n\tif s.currentFrameIsLast && s.currentFrame == nil {\n\t\ts.errorRead = true\n\t\treturn false, false, 0, io.EOF\n\t}\n\tif s.cancelledRemotely || s.cancelledLocally {\n\t\ts.errorRead = true\n\t\treturn false, false, 0, s.cancelErr\n\t}\n\tif s.closeForShutdownErr != nil {\n\t\treturn false, false, 0, s.closeForShutdownErr\n\t}\n\n\tvar bytesRead int\n\tvar deadlineTimer *utils.Timer\n\tfor bytesRead < len(p) {\n\t\tif s.currentFrame == nil || s.readPosInFrame >= len(s.currentFrame) {\n\t\t\ts.dequeueNextFrame()\n\t\t}\n\t\tif s.currentFrame == nil && bytesRead > 0 {\n\t\t\treturn hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, s.closeForShutdownErr\n\t\t}\n\n\t\tfor {\n\t\t\t// Stop waiting on errors\n\t\t\tif s.closeForShutdownErr != nil {\n\t\t\t\treturn hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, s.closeForShutdownErr\n\t\t\t}\n\t\t\tif s.cancelledRemotely || s.cancelledLocally {\n\t\t\t\ts.errorRead = true\n\t\t\t\treturn hasStreamWindowUpdate, hasConnWindowUpdate, 0, s.cancelErr\n\t\t\t}\n\n\t\t\tdeadline := s.deadline\n\t\t\tif !deadline.IsZero() {\n\t\t\t\tif !time.Now().Before(deadline) {\n\t\t\t\t\treturn hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, errDeadline\n\t\t\t\t}\n\t\t\t\tif deadlineTimer == nil {\n\t\t\t\t\tdeadlineTimer = utils.NewTimer()\n\t\t\t\t\tdefer deadlineTimer.Stop()\n\t\t\t\t}\n\t\t\t\tdeadlineTimer.Reset(deadline)\n\t\t\t}\n\n\t\t\tif s.currentFrame != nil || s.currentFrameIsLast {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\ts.mutex.Unlock()\n\t\t\tif deadline.IsZero() {\n\t\t\t\t<-s.readChan\n\t\t\t} else {\n\t\t\t\tselect {\n\t\t\t\tcase <-s.readChan:\n\t\t\t\tcase <-deadlineTimer.Chan():\n\t\t\t\t\tdeadlineTimer.SetRead()\n\t\t\t\t}\n\t\t\t}\n\t\t\ts.mutex.Lock()\n\t\t\tif s.currentFrame == nil {\n\t\t\t\ts.dequeueNextFrame()\n\t\t\t}\n\t\t}\n\n\t\tif bytesRead > len(p) {\n\t\t\treturn hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, fmt.Errorf(\"BUG: bytesRead (%d) > len(p) (%d) in stream.Read\", bytesRead, len(p))\n\t\t}\n\t\tif s.readPosInFrame > len(s.currentFrame) {\n\t\t\treturn hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, fmt.Errorf(\"BUG: readPosInFrame (%d) > frame.DataLen (%d) in stream.Read\", s.readPosInFrame, len(s.currentFrame))\n\t\t}\n\n\t\tm := copy(p[bytesRead:], s.currentFrame[s.readPosInFrame:])\n\t\ts.readPosInFrame += m\n\t\tbytesRead += m\n\n\t\t// when a RESET_STREAM was received, the flow controller was already\n\t\t// informed about the final byteOffset for this stream\n\t\tif !s.cancelledRemotely {\n\t\t\thasStream, hasConn := s.flowController.AddBytesRead(protocol.ByteCount(m))\n\t\t\tif hasStream {\n\t\t\t\ts.queuedMaxStreamData = true\n\t\t\t\thasStreamWindowUpdate = true\n\t\t\t}\n\t\t\tif hasConn {\n\t\t\t\thasConnWindowUpdate = true\n\t\t\t}\n\t\t}\n\n\t\tif s.readPosInFrame >= len(s.currentFrame) && s.currentFrameIsLast {\n\t\t\ts.currentFrame = nil\n\t\t\tif s.currentFrameDone != nil {\n\t\t\t\ts.currentFrameDone()\n\t\t\t}\n\t\t\ts.errorRead = true\n\t\t\treturn hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, io.EOF\n\t\t}\n\t}\n\treturn hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, nil\n}\n\nfunc (s *receiveStream) dequeueNextFrame() {\n\tvar offset protocol.ByteCount\n\t// We're done with the last frame. Release the buffer.\n\tif s.currentFrameDone != nil {\n\t\ts.currentFrameDone()\n\t}\n\toffset, s.currentFrame, s.currentFrameDone = s.frameQueue.Pop()\n\ts.currentFrameIsLast = offset+protocol.ByteCount(len(s.currentFrame)) >= s.finalOffset\n\ts.readPosInFrame = 0\n}\n\nfunc (s *receiveStream) CancelRead(errorCode StreamErrorCode) {\n\ts.mutex.Lock()\n\tqueuedNewControlFrame := s.cancelReadImpl(errorCode)\n\tcompleted := s.isNewlyCompleted()\n\ts.mutex.Unlock()\n\n\tif queuedNewControlFrame {\n\t\ts.sender.onHasStreamControlFrame(s.streamID, s)\n\t}\n\tif completed {\n\t\ts.flowController.Abandon()\n\t\ts.sender.onStreamCompleted(s.streamID)\n\t}\n}\n\nfunc (s *receiveStream) cancelReadImpl(errorCode qerr.StreamErrorCode) (queuedNewControlFrame bool) {\n\tif s.cancelledLocally { // duplicate call to CancelRead\n\t\treturn false\n\t}\n\tif s.closeForShutdownErr != nil {\n\t\treturn false\n\t}\n\ts.cancelledLocally = true\n\tif s.errorRead || s.cancelledRemotely {\n\t\treturn false\n\t}\n\ts.queuedStopSending = true\n\ts.cancelErr = &StreamError{StreamID: s.streamID, ErrorCode: errorCode, Remote: false}\n\ts.signalRead()\n\treturn true\n}\n\nfunc (s *receiveStream) handleStreamFrame(frame *wire.StreamFrame, now time.Time) error {\n\ts.mutex.Lock()\n\terr := s.handleStreamFrameImpl(frame, now)\n\tcompleted := s.isNewlyCompleted()\n\ts.mutex.Unlock()\n\n\tif completed {\n\t\ts.flowController.Abandon()\n\t\ts.sender.onStreamCompleted(s.streamID)\n\t}\n\treturn err\n}\n\nfunc (s *receiveStream) handleStreamFrameImpl(frame *wire.StreamFrame, now time.Time) error {\n\tmaxOffset := frame.Offset + frame.DataLen()\n\tif err := s.flowController.UpdateHighestReceived(maxOffset, frame.Fin, now); err != nil {\n\t\treturn err\n\t}\n\tif frame.Fin {\n\t\ts.finalOffset = maxOffset\n\t}\n\tif s.cancelledLocally {\n\t\treturn nil\n\t}\n\tif err := s.frameQueue.Push(frame.Data, frame.Offset, frame.PutBack); err != nil {\n\t\treturn err\n\t}\n\ts.signalRead()\n\treturn nil\n}\n\nfunc (s *receiveStream) handleResetStreamFrame(frame *wire.ResetStreamFrame, now time.Time) error {\n\ts.mutex.Lock()\n\terr := s.handleResetStreamFrameImpl(frame, now)\n\tcompleted := s.isNewlyCompleted()\n\ts.mutex.Unlock()\n\n\tif completed {\n\t\ts.sender.onStreamCompleted(s.streamID)\n\t}\n\treturn err\n}\n\nfunc (s *receiveStream) handleResetStreamFrameImpl(frame *wire.ResetStreamFrame, now time.Time) error {\n\tif s.closeForShutdownErr != nil {\n\t\treturn nil\n\t}\n\tif err := s.flowController.UpdateHighestReceived(frame.FinalSize, true, now); err != nil {\n\t\treturn err\n\t}\n\ts.finalOffset = frame.FinalSize\n\n\t// ignore duplicate RESET_STREAM frames for this stream (after checking their final offset)\n\tif s.cancelledRemotely {\n\t\treturn nil\n\t}\n\ts.flowController.Abandon()\n\t// don't save the error if the RESET_STREAM frames was received after CancelRead was called\n\tif s.cancelledLocally {\n\t\treturn nil\n\t}\n\ts.cancelledRemotely = true\n\ts.cancelErr = &StreamError{StreamID: s.streamID, ErrorCode: frame.ErrorCode, Remote: true}\n\ts.signalRead()\n\treturn nil\n}\n\nfunc (s *receiveStream) getControlFrame(now time.Time) (_ ackhandler.Frame, ok, hasMore bool) {\n\ts.mutex.Lock()\n\tdefer s.mutex.Unlock()\n\n\tif !s.queuedStopSending && !s.queuedMaxStreamData {\n\t\treturn ackhandler.Frame{}, false, false\n\t}\n\tif s.queuedStopSending {\n\t\ts.queuedStopSending = false\n\t\treturn ackhandler.Frame{\n\t\t\tFrame: &wire.StopSendingFrame{StreamID: s.streamID, ErrorCode: s.cancelErr.ErrorCode},\n\t\t}, true, s.queuedMaxStreamData\n\t}\n\n\ts.queuedMaxStreamData = false\n\treturn ackhandler.Frame{\n\t\tFrame: &wire.MaxStreamDataFrame{\n\t\t\tStreamID:          s.streamID,\n\t\t\tMaximumStreamData: s.flowController.GetWindowUpdate(now),\n\t\t},\n\t}, true, false\n}\n\nfunc (s *receiveStream) SetReadDeadline(t time.Time) error {\n\ts.mutex.Lock()\n\ts.deadline = t\n\ts.mutex.Unlock()\n\ts.signalRead()\n\treturn nil\n}\n\n// CloseForShutdown closes a stream abruptly.\n// It makes Read unblock (and return the error) immediately.\n// The peer will NOT be informed about this: the stream is closed without sending a FIN or RESET.\nfunc (s *receiveStream) closeForShutdown(err error) {\n\ts.mutex.Lock()\n\ts.closeForShutdownErr = err\n\ts.mutex.Unlock()\n\ts.signalRead()\n}\n\n// signalRead performs a non-blocking send on the readChan\nfunc (s *receiveStream) signalRead() {\n\tselect {\n\tcase s.readChan <- struct{}{}:\n\tdefault:\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/retransmission_queue.go",
    "content": "package quic\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/quic-go/quic-go/internal/ackhandler\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\ntype framesToRetransmit struct {\n\tcrypto []*wire.CryptoFrame\n\tother  []wire.Frame\n}\n\ntype retransmissionQueue struct {\n\tinitial   *framesToRetransmit\n\thandshake *framesToRetransmit\n\tappData   framesToRetransmit\n}\n\nfunc newRetransmissionQueue() *retransmissionQueue {\n\treturn &retransmissionQueue{\n\t\tinitial:   &framesToRetransmit{},\n\t\thandshake: &framesToRetransmit{},\n\t}\n}\n\nfunc (q *retransmissionQueue) addInitial(f wire.Frame) {\n\tif q.initial == nil {\n\t\treturn\n\t}\n\tif cf, ok := f.(*wire.CryptoFrame); ok {\n\t\tq.initial.crypto = append(q.initial.crypto, cf)\n\t\treturn\n\t}\n\tq.initial.other = append(q.initial.other, f)\n}\n\nfunc (q *retransmissionQueue) addHandshake(f wire.Frame) {\n\tif q.handshake == nil {\n\t\treturn\n\t}\n\tif cf, ok := f.(*wire.CryptoFrame); ok {\n\t\tq.handshake.crypto = append(q.handshake.crypto, cf)\n\t\treturn\n\t}\n\tq.handshake.other = append(q.handshake.other, f)\n}\n\nfunc (q *retransmissionQueue) addAppData(f wire.Frame) {\n\tswitch f := f.(type) {\n\tcase *wire.StreamFrame:\n\t\tpanic(\"STREAM frames are handled with their respective streams.\")\n\tcase *wire.CryptoFrame:\n\t\tq.appData.crypto = append(q.appData.crypto, f)\n\tdefault:\n\t\tq.appData.other = append(q.appData.other, f)\n\t}\n}\n\nfunc (q *retransmissionQueue) HasData(encLevel protocol.EncryptionLevel) bool {\n\t//nolint:exhaustive // 0-RTT data is retransmitted in 1-RTT packets.\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\treturn q.initial != nil &&\n\t\t\t(len(q.initial.crypto) > 0 || len(q.initial.other) > 0)\n\tcase protocol.EncryptionHandshake:\n\t\treturn q.handshake != nil &&\n\t\t\t(len(q.handshake.crypto) > 0 || len(q.handshake.other) > 0)\n\tcase protocol.Encryption1RTT:\n\t\treturn len(q.appData.crypto) > 0 || len(q.appData.other) > 0\n\t}\n\treturn false\n}\n\nfunc (q *retransmissionQueue) GetFrame(encLevel protocol.EncryptionLevel, maxLen protocol.ByteCount, v protocol.Version) wire.Frame {\n\tvar r *framesToRetransmit\n\t//nolint:exhaustive // 0-RTT data is retransmitted in 1-RTT packets.\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\tr = q.initial\n\tcase protocol.EncryptionHandshake:\n\t\tr = q.handshake\n\tcase protocol.Encryption1RTT:\n\t\tr = &q.appData\n\t}\n\tif r == nil {\n\t\treturn nil\n\t}\n\n\tif len(r.crypto) > 0 {\n\t\tf := r.crypto[0]\n\t\tnewFrame, needsSplit := f.MaybeSplitOffFrame(maxLen, v)\n\t\tif newFrame == nil && !needsSplit { // the whole frame fits\n\t\t\tr.crypto = r.crypto[1:]\n\t\t\treturn f\n\t\t}\n\t\tif newFrame != nil { // frame was split. Leave the original frame in the queue.\n\t\t\treturn newFrame\n\t\t}\n\t}\n\tif len(r.other) == 0 {\n\t\treturn nil\n\t}\n\tf := r.other[0]\n\tif f.Length(v) > maxLen {\n\t\treturn nil\n\t}\n\tr.other = r.other[1:]\n\treturn f\n}\n\nfunc (q *retransmissionQueue) DropPackets(encLevel protocol.EncryptionLevel) {\n\t//nolint:exhaustive // Can only drop Initial and Handshake packet number space.\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\tq.initial = nil\n\tcase protocol.EncryptionHandshake:\n\t\tq.handshake = nil\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unexpected encryption level: %s\", encLevel))\n\t}\n}\n\nfunc (q *retransmissionQueue) AckHandler(encLevel protocol.EncryptionLevel) ackhandler.FrameHandler {\n\tswitch encLevel {\n\tcase protocol.EncryptionInitial:\n\t\treturn (*retransmissionQueueInitialAckHandler)(q)\n\tcase protocol.EncryptionHandshake:\n\t\treturn (*retransmissionQueueHandshakeAckHandler)(q)\n\tcase protocol.Encryption0RTT, protocol.Encryption1RTT:\n\t\treturn (*retransmissionQueueAppDataAckHandler)(q)\n\t}\n\treturn nil\n}\n\ntype retransmissionQueueInitialAckHandler retransmissionQueue\n\nfunc (q *retransmissionQueueInitialAckHandler) OnAcked(wire.Frame) {}\nfunc (q *retransmissionQueueInitialAckHandler) OnLost(f wire.Frame) {\n\t(*retransmissionQueue)(q).addInitial(f)\n}\n\ntype retransmissionQueueHandshakeAckHandler retransmissionQueue\n\nfunc (q *retransmissionQueueHandshakeAckHandler) OnAcked(wire.Frame) {}\nfunc (q *retransmissionQueueHandshakeAckHandler) OnLost(f wire.Frame) {\n\t(*retransmissionQueue)(q).addHandshake(f)\n}\n\ntype retransmissionQueueAppDataAckHandler retransmissionQueue\n\nfunc (q *retransmissionQueueAppDataAckHandler) OnAcked(wire.Frame) {}\nfunc (q *retransmissionQueueAppDataAckHandler) OnLost(f wire.Frame) {\n\t(*retransmissionQueue)(q).addAppData(f)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/send_conn.go",
    "content": "package quic\n\nimport (\n\t\"net\"\n\t\"sync/atomic\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n)\n\n// A sendConn allows sending using a simple Write() on a non-connected packet conn.\ntype sendConn interface {\n\tWrite(b []byte, gsoSize uint16, ecn protocol.ECN) error\n\tWriteTo([]byte, net.Addr) error\n\tClose() error\n\tLocalAddr() net.Addr\n\tRemoteAddr() net.Addr\n\tChangeRemoteAddr(addr net.Addr, info packetInfo)\n\n\tcapabilities() connCapabilities\n}\n\ntype remoteAddrInfo struct {\n\taddr net.Addr\n\toob  []byte\n}\n\ntype sconn struct {\n\trawConn\n\n\tlocalAddr net.Addr\n\n\tremoteAddrInfo atomic.Pointer[remoteAddrInfo]\n\n\tlogger utils.Logger\n\n\t// If GSO enabled, and we receive a GSO error for this remote address, GSO is disabled.\n\tgotGSOError bool\n\t// Used to catch the error sometimes returned by the first sendmsg call on Linux,\n\t// see https://github.com/golang/go/issues/63322.\n\twroteFirstPacket bool\n}\n\nvar _ sendConn = &sconn{}\n\nfunc newSendConn(c rawConn, remote net.Addr, info packetInfo, logger utils.Logger) *sconn {\n\tlocalAddr := c.LocalAddr()\n\tif info.addr.IsValid() {\n\t\tif udpAddr, ok := localAddr.(*net.UDPAddr); ok {\n\t\t\taddrCopy := *udpAddr\n\t\t\taddrCopy.IP = info.addr.AsSlice()\n\t\t\tlocalAddr = &addrCopy\n\t\t}\n\t}\n\n\toob := info.OOB()\n\t// increase oob slice capacity, so we can add the UDP_SEGMENT and ECN control messages without allocating\n\tl := len(oob)\n\toob = append(oob, make([]byte, 64)...)[:l]\n\tsc := &sconn{\n\t\trawConn:   c,\n\t\tlocalAddr: localAddr,\n\t\tlogger:    logger,\n\t}\n\tsc.remoteAddrInfo.Store(&remoteAddrInfo{\n\t\taddr: remote,\n\t\toob:  oob,\n\t})\n\treturn sc\n}\n\nfunc (c *sconn) Write(p []byte, gsoSize uint16, ecn protocol.ECN) error {\n\tai := c.remoteAddrInfo.Load()\n\terr := c.writePacket(p, ai.addr, ai.oob, gsoSize, ecn)\n\tif err != nil && isGSOError(err) {\n\t\t// disable GSO for future calls\n\t\tc.gotGSOError = true\n\t\tif c.logger.Debug() {\n\t\t\tc.logger.Debugf(\"GSO failed when sending to %s\", ai.addr)\n\t\t}\n\t\t// send out the packets one by one\n\t\tfor len(p) > 0 {\n\t\t\tl := len(p)\n\t\t\tif l > int(gsoSize) {\n\t\t\t\tl = int(gsoSize)\n\t\t\t}\n\t\t\tif err := c.writePacket(p[:l], ai.addr, ai.oob, 0, ecn); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tp = p[l:]\n\t\t}\n\t\treturn nil\n\t}\n\treturn err\n}\n\nfunc (c *sconn) writePacket(p []byte, addr net.Addr, oob []byte, gsoSize uint16, ecn protocol.ECN) error {\n\t_, err := c.WritePacket(p, addr, oob, gsoSize, ecn)\n\tif err != nil && !c.wroteFirstPacket && isPermissionError(err) {\n\t\t_, err = c.WritePacket(p, addr, oob, gsoSize, ecn)\n\t}\n\tc.wroteFirstPacket = true\n\treturn err\n}\n\nfunc (c *sconn) WriteTo(b []byte, addr net.Addr) error {\n\t_, err := c.WritePacket(b, addr, nil, 0, protocol.ECNUnsupported)\n\treturn err\n}\n\nfunc (c *sconn) capabilities() connCapabilities {\n\tcapabilities := c.rawConn.capabilities()\n\tif capabilities.GSO {\n\t\tcapabilities.GSO = !c.gotGSOError\n\t}\n\treturn capabilities\n}\n\nfunc (c *sconn) ChangeRemoteAddr(addr net.Addr, info packetInfo) {\n\tc.remoteAddrInfo.Store(&remoteAddrInfo{\n\t\taddr: addr,\n\t\toob:  info.OOB(),\n\t})\n}\n\nfunc (c *sconn) RemoteAddr() net.Addr { return c.remoteAddrInfo.Load().addr }\nfunc (c *sconn) LocalAddr() net.Addr  { return c.localAddr }\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/send_queue.go",
    "content": "package quic\n\nimport (\n\t\"net\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\ntype sender interface {\n\tSend(p *packetBuffer, gsoSize uint16, ecn protocol.ECN)\n\tSendProbe(*packetBuffer, net.Addr)\n\tRun() error\n\tWouldBlock() bool\n\tAvailable() <-chan struct{}\n\tClose()\n}\n\ntype queueEntry struct {\n\tbuf     *packetBuffer\n\tgsoSize uint16\n\tecn     protocol.ECN\n}\n\ntype sendQueue struct {\n\tqueue       chan queueEntry\n\tcloseCalled chan struct{} // runStopped when Close() is called\n\trunStopped  chan struct{} // runStopped when the run loop returns\n\tavailable   chan struct{}\n\tconn        sendConn\n}\n\nvar _ sender = &sendQueue{}\n\nconst sendQueueCapacity = 8\n\nfunc newSendQueue(conn sendConn) sender {\n\treturn &sendQueue{\n\t\tconn:        conn,\n\t\trunStopped:  make(chan struct{}),\n\t\tcloseCalled: make(chan struct{}),\n\t\tavailable:   make(chan struct{}, 1),\n\t\tqueue:       make(chan queueEntry, sendQueueCapacity),\n\t}\n}\n\n// Send sends out a packet. It's guaranteed to not block.\n// Callers need to make sure that there's actually space in the send queue by calling WouldBlock.\n// Otherwise Send will panic.\nfunc (h *sendQueue) Send(p *packetBuffer, gsoSize uint16, ecn protocol.ECN) {\n\tselect {\n\tcase h.queue <- queueEntry{buf: p, gsoSize: gsoSize, ecn: ecn}:\n\t\t// clear available channel if we've reached capacity\n\t\tif len(h.queue) == sendQueueCapacity {\n\t\t\tselect {\n\t\t\tcase <-h.available:\n\t\t\tdefault:\n\t\t\t}\n\t\t}\n\tcase <-h.runStopped:\n\tdefault:\n\t\tpanic(\"sendQueue.Send would have blocked\")\n\t}\n}\n\nfunc (h *sendQueue) SendProbe(p *packetBuffer, addr net.Addr) {\n\th.conn.WriteTo(p.Data, addr)\n}\n\nfunc (h *sendQueue) WouldBlock() bool {\n\treturn len(h.queue) == sendQueueCapacity\n}\n\nfunc (h *sendQueue) Available() <-chan struct{} {\n\treturn h.available\n}\n\nfunc (h *sendQueue) Run() error {\n\tdefer close(h.runStopped)\n\tvar shouldClose bool\n\tfor {\n\t\tif shouldClose && len(h.queue) == 0 {\n\t\t\treturn nil\n\t\t}\n\t\tselect {\n\t\tcase <-h.closeCalled:\n\t\t\th.closeCalled = nil // prevent this case from being selected again\n\t\t\t// make sure that all queued packets are actually sent out\n\t\t\tshouldClose = true\n\t\tcase e := <-h.queue:\n\t\t\tif err := h.conn.Write(e.buf.Data, e.gsoSize, e.ecn); err != nil {\n\t\t\t\t// This additional check enables:\n\t\t\t\t// 1. Checking for \"datagram too large\" message from the kernel, as such,\n\t\t\t\t// 2. Path MTU discovery,and\n\t\t\t\t// 3. Eventual detection of loss PingFrame.\n\t\t\t\tif !isSendMsgSizeErr(err) {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t\te.buf.Release()\n\t\t\tselect {\n\t\t\tcase h.available <- struct{}{}:\n\t\t\tdefault:\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (h *sendQueue) Close() {\n\tclose(h.closeCalled)\n\t// wait until the run loop returned\n\t<-h.runStopped\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/send_stream.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/ackhandler\"\n\t\"github.com/quic-go/quic-go/internal/flowcontrol\"\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\ntype sendStreamI interface {\n\tSendStream\n\thandleStopSendingFrame(*wire.StopSendingFrame)\n\thasData() bool\n\tpopStreamFrame(protocol.ByteCount, protocol.Version) (_ ackhandler.StreamFrame, _ *wire.StreamDataBlockedFrame, hasMore bool)\n\tcloseForShutdown(error)\n\tupdateSendWindow(protocol.ByteCount)\n}\n\ntype sendStream struct {\n\tmutex sync.Mutex\n\n\tnumOutstandingFrames int64 // outstanding STREAM and RESET_STREAM frames\n\tretransmissionQueue  []*wire.StreamFrame\n\n\tctx       context.Context\n\tctxCancel context.CancelCauseFunc\n\n\tstreamID protocol.StreamID\n\tsender   streamSender\n\n\twriteOffset protocol.ByteCount\n\n\t// finalError is the error that is returned by Write.\n\t// It can either be a cancellation error or the shutdown error.\n\tfinalError             error\n\tqueuedResetStreamFrame *wire.ResetStreamFrame\n\n\tfinishedWriting bool // set once Close() is called\n\tfinSent         bool // set when a STREAM_FRAME with FIN bit has been sent\n\t// Set when the application knows about the cancellation.\n\t// This can happen because the application called CancelWrite,\n\t// or because Write returned the error (for remote cancellations).\n\tcancellationFlagged bool\n\tcancelled           bool // both local and remote cancellations\n\tclosedForShutdown   bool // set by closeForShutdown\n\tcompleted           bool // set when this stream has been reported to the streamSender as completed\n\n\tdataForWriting []byte // during a Write() call, this slice is the part of p that still needs to be sent out\n\tnextFrame      *wire.StreamFrame\n\n\twriteChan chan struct{}\n\twriteOnce chan struct{}\n\tdeadline  time.Time\n\n\tflowController flowcontrol.StreamFlowController\n}\n\nvar (\n\t_ SendStream               = &sendStream{}\n\t_ sendStreamI              = &sendStream{}\n\t_ streamControlFrameGetter = &sendStream{}\n)\n\nfunc newSendStream(\n\tctx context.Context,\n\tstreamID protocol.StreamID,\n\tsender streamSender,\n\tflowController flowcontrol.StreamFlowController,\n) *sendStream {\n\ts := &sendStream{\n\t\tstreamID:       streamID,\n\t\tsender:         sender,\n\t\tflowController: flowController,\n\t\twriteChan:      make(chan struct{}, 1),\n\t\twriteOnce:      make(chan struct{}, 1), // cap: 1, to protect against concurrent use of Write\n\t}\n\ts.ctx, s.ctxCancel = context.WithCancelCause(ctx)\n\treturn s\n}\n\nfunc (s *sendStream) StreamID() protocol.StreamID {\n\treturn s.streamID // same for receiveStream and sendStream\n}\n\nfunc (s *sendStream) Write(p []byte) (int, error) {\n\t// Concurrent use of Write is not permitted (and doesn't make any sense),\n\t// but sometimes people do it anyway.\n\t// Make sure that we only execute one call at any given time to avoid hard to debug failures.\n\ts.writeOnce <- struct{}{}\n\tdefer func() { <-s.writeOnce }()\n\n\tisNewlyCompleted, n, err := s.write(p)\n\tif isNewlyCompleted {\n\t\ts.sender.onStreamCompleted(s.streamID)\n\t}\n\treturn n, err\n}\n\nfunc (s *sendStream) write(p []byte) (bool /* is newly completed */, int, error) {\n\ts.mutex.Lock()\n\tdefer s.mutex.Unlock()\n\n\tif s.finalError != nil {\n\t\tif s.cancelled {\n\t\t\ts.cancellationFlagged = true\n\t\t}\n\t\treturn s.isNewlyCompleted(), 0, s.finalError\n\t}\n\tif s.finishedWriting {\n\t\treturn false, 0, fmt.Errorf(\"write on closed stream %d\", s.streamID)\n\t}\n\tif !s.deadline.IsZero() && !time.Now().Before(s.deadline) {\n\t\treturn false, 0, errDeadline\n\t}\n\tif len(p) == 0 {\n\t\treturn false, 0, nil\n\t}\n\n\ts.dataForWriting = p\n\n\tvar (\n\t\tdeadlineTimer  *utils.Timer\n\t\tbytesWritten   int\n\t\tnotifiedSender bool\n\t)\n\tfor {\n\t\tvar copied bool\n\t\tvar deadline time.Time\n\t\t// As soon as dataForWriting becomes smaller than a certain size x, we copy all the data to a STREAM frame (s.nextFrame),\n\t\t// which can then be popped the next time we assemble a packet.\n\t\t// This allows us to return Write() when all data but x bytes have been sent out.\n\t\t// When the user now calls Close(), this is much more likely to happen before we popped that last STREAM frame,\n\t\t// allowing us to set the FIN bit on that frame (instead of sending an empty STREAM frame with FIN).\n\t\tif s.canBufferStreamFrame() && len(s.dataForWriting) > 0 {\n\t\t\tif s.nextFrame == nil {\n\t\t\t\tf := wire.GetStreamFrame()\n\t\t\t\tf.Offset = s.writeOffset\n\t\t\t\tf.StreamID = s.streamID\n\t\t\t\tf.DataLenPresent = true\n\t\t\t\tf.Data = f.Data[:len(s.dataForWriting)]\n\t\t\t\tcopy(f.Data, s.dataForWriting)\n\t\t\t\ts.nextFrame = f\n\t\t\t} else {\n\t\t\t\tl := len(s.nextFrame.Data)\n\t\t\t\ts.nextFrame.Data = s.nextFrame.Data[:l+len(s.dataForWriting)]\n\t\t\t\tcopy(s.nextFrame.Data[l:], s.dataForWriting)\n\t\t\t}\n\t\t\ts.dataForWriting = nil\n\t\t\tbytesWritten = len(p)\n\t\t\tcopied = true\n\t\t} else {\n\t\t\tbytesWritten = len(p) - len(s.dataForWriting)\n\t\t\tdeadline = s.deadline\n\t\t\tif !deadline.IsZero() {\n\t\t\t\tif !time.Now().Before(deadline) {\n\t\t\t\t\ts.dataForWriting = nil\n\t\t\t\t\treturn false, bytesWritten, errDeadline\n\t\t\t\t}\n\t\t\t\tif deadlineTimer == nil {\n\t\t\t\t\tdeadlineTimer = utils.NewTimer()\n\t\t\t\t\tdefer deadlineTimer.Stop()\n\t\t\t\t}\n\t\t\t\tdeadlineTimer.Reset(deadline)\n\t\t\t}\n\t\t\tif s.dataForWriting == nil || s.finalError != nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\ts.mutex.Unlock()\n\t\tif !notifiedSender {\n\t\t\ts.sender.onHasStreamData(s.streamID, s) // must be called without holding the mutex\n\t\t\tnotifiedSender = true\n\t\t}\n\t\tif copied {\n\t\t\ts.mutex.Lock()\n\t\t\tbreak\n\t\t}\n\t\tif deadline.IsZero() {\n\t\t\t<-s.writeChan\n\t\t} else {\n\t\t\tselect {\n\t\t\tcase <-s.writeChan:\n\t\t\tcase <-deadlineTimer.Chan():\n\t\t\t\tdeadlineTimer.SetRead()\n\t\t\t}\n\t\t}\n\t\ts.mutex.Lock()\n\t}\n\n\tif bytesWritten == len(p) {\n\t\treturn false, bytesWritten, nil\n\t}\n\tif s.finalError != nil {\n\t\tif s.cancelled {\n\t\t\ts.cancellationFlagged = true\n\t\t}\n\t\treturn s.isNewlyCompleted(), bytesWritten, s.finalError\n\t}\n\treturn false, bytesWritten, nil\n}\n\nfunc (s *sendStream) canBufferStreamFrame() bool {\n\tvar l protocol.ByteCount\n\tif s.nextFrame != nil {\n\t\tl = s.nextFrame.DataLen()\n\t}\n\treturn l+protocol.ByteCount(len(s.dataForWriting)) <= protocol.MaxPacketBufferSize\n}\n\n// popStreamFrame returns the next STREAM frame that is supposed to be sent on this stream\n// maxBytes is the maximum length this frame (including frame header) will have.\nfunc (s *sendStream) popStreamFrame(maxBytes protocol.ByteCount, v protocol.Version) (_ ackhandler.StreamFrame, _ *wire.StreamDataBlockedFrame, hasMore bool) {\n\ts.mutex.Lock()\n\tf, blocked, hasMoreData := s.popNewOrRetransmittedStreamFrame(maxBytes, v)\n\tif f != nil {\n\t\ts.numOutstandingFrames++\n\t}\n\ts.mutex.Unlock()\n\n\tif f == nil {\n\t\treturn ackhandler.StreamFrame{}, blocked, hasMoreData\n\t}\n\treturn ackhandler.StreamFrame{\n\t\tFrame:   f,\n\t\tHandler: (*sendStreamAckHandler)(s),\n\t}, blocked, hasMoreData\n}\n\nfunc (s *sendStream) popNewOrRetransmittedStreamFrame(maxBytes protocol.ByteCount, v protocol.Version) (_ *wire.StreamFrame, _ *wire.StreamDataBlockedFrame, hasMoreData bool) {\n\tif s.finalError != nil {\n\t\treturn nil, nil, false\n\t}\n\n\tif len(s.retransmissionQueue) > 0 {\n\t\tf, hasMoreRetransmissions := s.maybeGetRetransmission(maxBytes, v)\n\t\tif f != nil || hasMoreRetransmissions {\n\t\t\tif f == nil {\n\t\t\t\treturn nil, nil, true\n\t\t\t}\n\t\t\t// We always claim that we have more data to send.\n\t\t\t// This might be incorrect, in which case there'll be a spurious call to popStreamFrame in the future.\n\t\t\treturn f, nil, true\n\t\t}\n\t}\n\n\tif len(s.dataForWriting) == 0 && s.nextFrame == nil {\n\t\tif s.finishedWriting && !s.finSent {\n\t\t\ts.finSent = true\n\t\t\treturn &wire.StreamFrame{\n\t\t\t\tStreamID:       s.streamID,\n\t\t\t\tOffset:         s.writeOffset,\n\t\t\t\tDataLenPresent: true,\n\t\t\t\tFin:            true,\n\t\t\t}, nil, false\n\t\t}\n\t\treturn nil, nil, false\n\t}\n\n\tsendWindow := s.flowController.SendWindowSize()\n\tif sendWindow == 0 {\n\t\treturn nil, nil, true\n\t}\n\n\tf, hasMoreData := s.popNewStreamFrame(maxBytes, sendWindow, v)\n\tif f == nil {\n\t\treturn nil, nil, hasMoreData\n\t}\n\tif f.DataLen() > 0 {\n\t\ts.writeOffset += f.DataLen()\n\t\ts.flowController.AddBytesSent(f.DataLen())\n\t}\n\tvar blocked *wire.StreamDataBlockedFrame\n\t// If the entire send window is used, the stream might have become blocked on stream-level flow control.\n\t// This is not guaranteed though, because the stream might also have been blocked on connection-level flow control.\n\tif f.DataLen() == sendWindow && s.flowController.IsNewlyBlocked() {\n\t\tblocked = &wire.StreamDataBlockedFrame{StreamID: s.streamID, MaximumStreamData: s.writeOffset}\n\t}\n\tf.Fin = s.finishedWriting && s.dataForWriting == nil && s.nextFrame == nil && !s.finSent\n\tif f.Fin {\n\t\ts.finSent = true\n\t}\n\treturn f, blocked, hasMoreData\n}\n\nfunc (s *sendStream) popNewStreamFrame(maxBytes, sendWindow protocol.ByteCount, v protocol.Version) (*wire.StreamFrame, bool) {\n\tif s.nextFrame != nil {\n\t\tmaxDataLen := min(sendWindow, s.nextFrame.MaxDataLen(maxBytes, v))\n\t\tif maxDataLen == 0 {\n\t\t\treturn nil, true\n\t\t}\n\t\tnextFrame := s.nextFrame\n\t\ts.nextFrame = nil\n\t\tif nextFrame.DataLen() > maxDataLen {\n\t\t\ts.nextFrame = wire.GetStreamFrame()\n\t\t\ts.nextFrame.StreamID = s.streamID\n\t\t\ts.nextFrame.Offset = s.writeOffset + maxDataLen\n\t\t\ts.nextFrame.Data = s.nextFrame.Data[:nextFrame.DataLen()-maxDataLen]\n\t\t\ts.nextFrame.DataLenPresent = true\n\t\t\tcopy(s.nextFrame.Data, nextFrame.Data[maxDataLen:])\n\t\t\tnextFrame.Data = nextFrame.Data[:maxDataLen]\n\t\t} else {\n\t\t\ts.signalWrite()\n\t\t}\n\t\treturn nextFrame, s.nextFrame != nil || s.dataForWriting != nil\n\t}\n\n\tf := wire.GetStreamFrame()\n\tf.Fin = false\n\tf.StreamID = s.streamID\n\tf.Offset = s.writeOffset\n\tf.DataLenPresent = true\n\tf.Data = f.Data[:0]\n\n\thasMoreData := s.popNewStreamFrameWithoutBuffer(f, maxBytes, sendWindow, v)\n\tif len(f.Data) == 0 && !f.Fin {\n\t\tf.PutBack()\n\t\treturn nil, hasMoreData\n\t}\n\treturn f, hasMoreData\n}\n\nfunc (s *sendStream) popNewStreamFrameWithoutBuffer(f *wire.StreamFrame, maxBytes, sendWindow protocol.ByteCount, v protocol.Version) bool {\n\tmaxDataLen := f.MaxDataLen(maxBytes, v)\n\tif maxDataLen == 0 { // a STREAM frame must have at least one byte of data\n\t\treturn s.dataForWriting != nil || s.nextFrame != nil || s.finishedWriting\n\t}\n\ts.getDataForWriting(f, min(maxDataLen, sendWindow))\n\n\treturn s.dataForWriting != nil || s.nextFrame != nil || s.finishedWriting\n}\n\nfunc (s *sendStream) maybeGetRetransmission(maxBytes protocol.ByteCount, v protocol.Version) (*wire.StreamFrame, bool /* has more retransmissions */) {\n\tf := s.retransmissionQueue[0]\n\tnewFrame, needsSplit := f.MaybeSplitOffFrame(maxBytes, v)\n\tif needsSplit {\n\t\treturn newFrame, true\n\t}\n\ts.retransmissionQueue = s.retransmissionQueue[1:]\n\treturn f, len(s.retransmissionQueue) > 0\n}\n\nfunc (s *sendStream) hasData() bool {\n\ts.mutex.Lock()\n\thasData := len(s.dataForWriting) > 0\n\ts.mutex.Unlock()\n\treturn hasData\n}\n\nfunc (s *sendStream) getDataForWriting(f *wire.StreamFrame, maxBytes protocol.ByteCount) {\n\tif protocol.ByteCount(len(s.dataForWriting)) <= maxBytes {\n\t\tf.Data = f.Data[:len(s.dataForWriting)]\n\t\tcopy(f.Data, s.dataForWriting)\n\t\ts.dataForWriting = nil\n\t\ts.signalWrite()\n\t\treturn\n\t}\n\tf.Data = f.Data[:maxBytes]\n\tcopy(f.Data, s.dataForWriting)\n\ts.dataForWriting = s.dataForWriting[maxBytes:]\n\tif s.canBufferStreamFrame() {\n\t\ts.signalWrite()\n\t}\n}\n\nfunc (s *sendStream) isNewlyCompleted() bool {\n\tif s.completed {\n\t\treturn false\n\t}\n\t// We need to keep the stream around until all frames have been sent and acknowledged.\n\tif s.numOutstandingFrames > 0 || len(s.retransmissionQueue) > 0 || s.queuedResetStreamFrame != nil {\n\t\treturn false\n\t}\n\t// The stream is completed if we sent the FIN.\n\tif s.finSent {\n\t\ts.completed = true\n\t\treturn true\n\t}\n\t// The stream is also completed if:\n\t// 1. the application called CancelWrite, or\n\t// 2. we received a STOP_SENDING, and\n\t// \t\t* the application consumed the error via Write, or\n\t//\t\t* the application called Close\n\tif s.cancelled && (s.cancellationFlagged || s.finishedWriting) {\n\t\ts.completed = true\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (s *sendStream) Close() error {\n\ts.mutex.Lock()\n\tif s.closedForShutdown || s.finishedWriting {\n\t\ts.mutex.Unlock()\n\t\treturn nil\n\t}\n\ts.finishedWriting = true\n\tcancelled := s.cancelled\n\tif cancelled {\n\t\ts.cancellationFlagged = true\n\t}\n\tcompleted := s.isNewlyCompleted()\n\ts.mutex.Unlock()\n\n\tif completed {\n\t\ts.sender.onStreamCompleted(s.streamID)\n\t}\n\tif cancelled {\n\t\treturn fmt.Errorf(\"close called for canceled stream %d\", s.streamID)\n\t}\n\ts.sender.onHasStreamData(s.streamID, s) // need to send the FIN, must be called without holding the mutex\n\n\ts.ctxCancel(nil)\n\treturn nil\n}\n\nfunc (s *sendStream) CancelWrite(errorCode StreamErrorCode) {\n\ts.cancelWrite(errorCode, false)\n}\n\n// cancelWrite cancels the stream\n// It is possible to cancel a stream after it has been closed, both locally and remotely.\n// This is useful to prevent the retransmission of outstanding stream data.\nfunc (s *sendStream) cancelWrite(errorCode qerr.StreamErrorCode, remote bool) {\n\ts.mutex.Lock()\n\tif s.closedForShutdown {\n\t\ts.mutex.Unlock()\n\t\treturn\n\t}\n\tif !remote {\n\t\ts.cancellationFlagged = true\n\t\tif s.cancelled {\n\t\t\tcompleted := s.isNewlyCompleted()\n\t\t\ts.mutex.Unlock()\n\t\t\t// The user has called CancelWrite. If the previous cancellation was\n\t\t\t// because of a STOP_SENDING, we don't need to flag the error to the\n\t\t\t// user anymore.\n\t\t\tif completed {\n\t\t\t\ts.sender.onStreamCompleted(s.streamID)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n\tif s.cancelled {\n\t\ts.mutex.Unlock()\n\t\treturn\n\t}\n\ts.cancelled = true\n\ts.finalError = &StreamError{StreamID: s.streamID, ErrorCode: errorCode, Remote: remote}\n\ts.ctxCancel(s.finalError)\n\ts.numOutstandingFrames = 0\n\ts.retransmissionQueue = nil\n\ts.queuedResetStreamFrame = &wire.ResetStreamFrame{\n\t\tStreamID:  s.streamID,\n\t\tFinalSize: s.writeOffset,\n\t\tErrorCode: errorCode,\n\t}\n\ts.mutex.Unlock()\n\n\ts.signalWrite()\n\ts.sender.onHasStreamControlFrame(s.streamID, s)\n}\n\nfunc (s *sendStream) updateSendWindow(limit protocol.ByteCount) {\n\tupdated := s.flowController.UpdateSendWindow(limit)\n\tif !updated { // duplicate or reordered MAX_STREAM_DATA frame\n\t\treturn\n\t}\n\ts.mutex.Lock()\n\thasStreamData := s.dataForWriting != nil || s.nextFrame != nil\n\ts.mutex.Unlock()\n\tif hasStreamData {\n\t\ts.sender.onHasStreamData(s.streamID, s)\n\t}\n}\n\nfunc (s *sendStream) handleStopSendingFrame(frame *wire.StopSendingFrame) {\n\ts.cancelWrite(frame.ErrorCode, true)\n}\n\nfunc (s *sendStream) getControlFrame(time.Time) (_ ackhandler.Frame, ok, hasMore bool) {\n\ts.mutex.Lock()\n\tdefer s.mutex.Unlock()\n\n\tif s.queuedResetStreamFrame == nil {\n\t\treturn ackhandler.Frame{}, false, false\n\t}\n\ts.numOutstandingFrames++\n\tf := ackhandler.Frame{\n\t\tFrame:   s.queuedResetStreamFrame,\n\t\tHandler: (*sendStreamResetStreamHandler)(s),\n\t}\n\ts.queuedResetStreamFrame = nil\n\treturn f, true, false\n}\n\nfunc (s *sendStream) Context() context.Context {\n\treturn s.ctx\n}\n\nfunc (s *sendStream) SetWriteDeadline(t time.Time) error {\n\ts.mutex.Lock()\n\ts.deadline = t\n\ts.mutex.Unlock()\n\ts.signalWrite()\n\treturn nil\n}\n\n// CloseForShutdown closes a stream abruptly.\n// It makes Write unblock (and return the error) immediately.\n// The peer will NOT be informed about this: the stream is closed without sending a FIN or RST.\nfunc (s *sendStream) closeForShutdown(err error) {\n\ts.mutex.Lock()\n\ts.closedForShutdown = true\n\tif s.finalError == nil && !s.finishedWriting {\n\t\ts.finalError = err\n\t}\n\ts.mutex.Unlock()\n\ts.signalWrite()\n}\n\n// signalWrite performs a non-blocking send on the writeChan\nfunc (s *sendStream) signalWrite() {\n\tselect {\n\tcase s.writeChan <- struct{}{}:\n\tdefault:\n\t}\n}\n\ntype sendStreamAckHandler sendStream\n\nvar _ ackhandler.FrameHandler = &sendStreamAckHandler{}\n\nfunc (s *sendStreamAckHandler) OnAcked(f wire.Frame) {\n\tsf := f.(*wire.StreamFrame)\n\tsf.PutBack()\n\ts.mutex.Lock()\n\tif s.cancelled {\n\t\ts.mutex.Unlock()\n\t\treturn\n\t}\n\ts.numOutstandingFrames--\n\tif s.numOutstandingFrames < 0 {\n\t\tpanic(\"numOutStandingFrames negative\")\n\t}\n\tcompleted := (*sendStream)(s).isNewlyCompleted()\n\ts.mutex.Unlock()\n\n\tif completed {\n\t\ts.sender.onStreamCompleted(s.streamID)\n\t}\n}\n\nfunc (s *sendStreamAckHandler) OnLost(f wire.Frame) {\n\tsf := f.(*wire.StreamFrame)\n\ts.mutex.Lock()\n\tif s.cancelled {\n\t\ts.mutex.Unlock()\n\t\treturn\n\t}\n\tsf.DataLenPresent = true\n\ts.retransmissionQueue = append(s.retransmissionQueue, sf)\n\ts.numOutstandingFrames--\n\tif s.numOutstandingFrames < 0 {\n\t\tpanic(\"numOutStandingFrames negative\")\n\t}\n\ts.mutex.Unlock()\n\n\ts.sender.onHasStreamData(s.streamID, (*sendStream)(s))\n}\n\ntype sendStreamResetStreamHandler sendStream\n\nvar _ ackhandler.FrameHandler = &sendStreamResetStreamHandler{}\n\nfunc (s *sendStreamResetStreamHandler) OnAcked(wire.Frame) {\n\ts.mutex.Lock()\n\ts.numOutstandingFrames--\n\tif s.numOutstandingFrames < 0 {\n\t\tpanic(\"numOutStandingFrames negative\")\n\t}\n\tcompleted := (*sendStream)(s).isNewlyCompleted()\n\ts.mutex.Unlock()\n\n\tif completed {\n\t\ts.sender.onStreamCompleted(s.streamID)\n\t}\n}\n\nfunc (s *sendStreamResetStreamHandler) OnLost(f wire.Frame) {\n\ts.mutex.Lock()\n\ts.queuedResetStreamFrame = f.(*wire.ResetStreamFrame)\n\ts.numOutstandingFrames--\n\ts.mutex.Unlock()\n\ts.sender.onHasStreamControlFrame(s.streamID, (*sendStream)(s))\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/server.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/handshake\"\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n\t\"github.com/quic-go/quic-go/logging\"\n)\n\n// ErrServerClosed is returned by the [Listener] or [EarlyListener]'s Accept method after a call to Close.\nvar ErrServerClosed = errServerClosed{}\n\ntype errServerClosed struct{}\n\nfunc (errServerClosed) Error() string { return \"quic: server closed\" }\nfunc (errServerClosed) Unwrap() error { return net.ErrClosed }\n\n// packetHandler handles packets\ntype packetHandler interface {\n\thandlePacket(receivedPacket)\n\tdestroy(error)\n\tcloseWithTransportError(qerr.TransportErrorCode)\n}\n\ntype packetHandlerManager interface {\n\tGet(protocol.ConnectionID) (packetHandler, bool)\n\tGetByResetToken(protocol.StatelessResetToken) (packetHandler, bool)\n\tAddWithConnID(destConnID, newConnID protocol.ConnectionID, h packetHandler) bool\n\tClose(error)\n\tconnRunner\n}\n\ntype quicConn interface {\n\tEarlyConnection\n\tearlyConnReady() <-chan struct{}\n\thandlePacket(receivedPacket)\n\trun() error\n\tdestroy(error)\n\tcloseWithTransportError(TransportErrorCode)\n}\n\ntype zeroRTTQueue struct {\n\tpackets    []receivedPacket\n\texpiration time.Time\n}\n\ntype rejectedPacket struct {\n\treceivedPacket\n\thdr *wire.Header\n}\n\n// A Listener of QUIC\ntype baseServer struct {\n\ttr                        *Transport\n\tdisableVersionNegotiation bool\n\tacceptEarlyConns          bool\n\n\ttlsConf *tls.Config\n\tconfig  *Config\n\n\tconn rawConn\n\n\ttokenGenerator *handshake.TokenGenerator\n\tmaxTokenAge    time.Duration\n\n\tconnIDGenerator   ConnectionIDGenerator\n\tstatelessResetter *statelessResetter\n\tonClose           func()\n\n\treceivedPackets chan receivedPacket\n\n\tnextZeroRTTCleanup time.Time\n\tzeroRTTQueues      map[protocol.ConnectionID]*zeroRTTQueue // only initialized if acceptEarlyConns == true\n\n\tconnContext func(context.Context) context.Context\n\n\t// set as a member, so they can be set in the tests\n\tnewConn func(\n\t\tcontext.Context,\n\t\tcontext.CancelCauseFunc,\n\t\tsendConn,\n\t\t*Transport,\n\t\tprotocol.ConnectionID, /* original dest connection ID */\n\t\t*protocol.ConnectionID, /* retry src connection ID */\n\t\tprotocol.ConnectionID, /* client dest connection ID */\n\t\tprotocol.ConnectionID, /* destination connection ID */\n\t\tprotocol.ConnectionID, /* source connection ID */\n\t\tConnectionIDGenerator,\n\t\t*statelessResetter,\n\t\t*Config,\n\t\t*tls.Config,\n\t\t*handshake.TokenGenerator,\n\t\tbool, /* client address validated by an address validation token */\n\t\t*logging.ConnectionTracer,\n\t\tutils.Logger,\n\t\tprotocol.Version,\n\t) quicConn\n\n\tcloseMx sync.Mutex\n\t// errorChan is closed when Close is called. This has two effects:\n\t// 1. it cancels handshakes that are still in flight (using CONNECTION_REFUSED) errors\n\t// 2. it stops handling of packets passed to this server\n\terrorChan chan struct{}\n\t// acceptChan is closed when Close returns.\n\t// This only happens once all handshake in flight have either completed and canceled.\n\t// Calls to Accept will first drain the queue of connections that have completed the handshake,\n\t// and then return ErrServerClosed.\n\tstopAccepting chan struct{}\n\tcloseErr      error\n\trunning       chan struct{} // closed as soon as run() returns\n\n\tversionNegotiationQueue chan receivedPacket\n\tinvalidTokenQueue       chan rejectedPacket\n\tconnectionRefusedQueue  chan rejectedPacket\n\tretryQueue              chan rejectedPacket\n\thandshakingCount        sync.WaitGroup\n\n\tverifySourceAddress func(net.Addr) bool\n\n\tconnQueue chan quicConn\n\n\ttracer *logging.Tracer\n\n\tlogger utils.Logger\n}\n\n// A Listener listens for incoming QUIC connections.\n// It returns connections once the handshake has completed.\ntype Listener struct {\n\tbaseServer *baseServer\n}\n\n// Accept returns new connections. It should be called in a loop.\nfunc (l *Listener) Accept(ctx context.Context) (Connection, error) {\n\treturn l.baseServer.Accept(ctx)\n}\n\n// Close closes the listener.\n// Accept will return [ErrServerClosed] as soon as all connections in the accept queue have been accepted.\n// QUIC handshakes that are still in flight will be rejected with a CONNECTION_REFUSED error.\n// The effect of closing the listener depends on how it was created:\n//   - if it was created using [Transport.Listen], already established connections will be unaffected\n//   - if it was created using the [Listen] convenience method, all established connection will be closed immediately\nfunc (l *Listener) Close() error {\n\treturn l.baseServer.Close()\n}\n\n// Addr returns the local network address that the server is listening on.\nfunc (l *Listener) Addr() net.Addr {\n\treturn l.baseServer.Addr()\n}\n\n// An EarlyListener listens for incoming QUIC connections, and returns them before the handshake completes.\n// For connections that don't use 0-RTT, this allows the server to send 0.5-RTT data.\n// This data is encrypted with forward-secure keys, however, the client's identity has not yet been verified.\n// For connection using 0-RTT, this allows the server to accept and respond to streams that the client opened in the\n// 0-RTT data it sent. Note that at this point during the handshake, the live-ness of the\n// client has not yet been confirmed, and the 0-RTT data could have been replayed by an attacker.\ntype EarlyListener struct {\n\tbaseServer *baseServer\n}\n\n// Accept returns a new connections. It should be called in a loop.\nfunc (l *EarlyListener) Accept(ctx context.Context) (EarlyConnection, error) {\n\treturn l.baseServer.accept(ctx)\n}\n\n// Close the server. All active connections will be closed.\nfunc (l *EarlyListener) Close() error {\n\treturn l.baseServer.Close()\n}\n\n// Addr returns the local network addr that the server is listening on.\nfunc (l *EarlyListener) Addr() net.Addr {\n\treturn l.baseServer.Addr()\n}\n\n// ListenAddr creates a QUIC server listening on a given address.\n// See [Listen] for more details.\nfunc ListenAddr(addr string, tlsConf *tls.Config, config *Config) (*Listener, error) {\n\tconn, err := listenUDP(addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn (&Transport{\n\t\tConn:        conn,\n\t\tcreatedConn: true,\n\t\tisSingleUse: true,\n\t}).Listen(tlsConf, config)\n}\n\n// ListenAddrEarly works like [ListenAddr], but it returns connections before the handshake completes.\nfunc ListenAddrEarly(addr string, tlsConf *tls.Config, config *Config) (*EarlyListener, error) {\n\tconn, err := listenUDP(addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn (&Transport{\n\t\tConn:        conn,\n\t\tcreatedConn: true,\n\t\tisSingleUse: true,\n\t}).ListenEarly(tlsConf, config)\n}\n\nfunc listenUDP(addr string) (*net.UDPConn, error) {\n\tudpAddr, err := net.ResolveUDPAddr(\"udp\", addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn net.ListenUDP(\"udp\", udpAddr)\n}\n\n// Listen listens for QUIC connections on a given net.PacketConn.\n// If the PacketConn satisfies the [OOBCapablePacketConn] interface (as a [net.UDPConn] does),\n// ECN and packet info support will be enabled. In this case, ReadMsgUDP and WriteMsgUDP\n// will be used instead of ReadFrom and WriteTo to read/write packets.\n// A single net.PacketConn can only be used for a single call to Listen.\n//\n// The tls.Config must not be nil and must contain a certificate configuration.\n// Furthermore, it must define an application control (using [NextProtos]).\n// The quic.Config may be nil, in that case the default values will be used.\n//\n// This is a convenience function. More advanced use cases should instantiate a [Transport],\n// which offers configuration options for a more fine-grained control of the connection establishment,\n// including reusing the underlying UDP socket for outgoing QUIC connections.\n// When closing a listener created with Listen, all established QUIC connections will be closed immediately.\nfunc Listen(conn net.PacketConn, tlsConf *tls.Config, config *Config) (*Listener, error) {\n\ttr := &Transport{Conn: conn, isSingleUse: true}\n\treturn tr.Listen(tlsConf, config)\n}\n\n// ListenEarly works like [Listen], but it returns connections before the handshake completes.\nfunc ListenEarly(conn net.PacketConn, tlsConf *tls.Config, config *Config) (*EarlyListener, error) {\n\ttr := &Transport{Conn: conn, isSingleUse: true}\n\treturn tr.ListenEarly(tlsConf, config)\n}\n\nfunc newServer(\n\tconn rawConn,\n\ttr *Transport,\n\tconnIDGenerator ConnectionIDGenerator,\n\tstatelessResetter *statelessResetter,\n\tconnContext func(context.Context) context.Context,\n\ttlsConf *tls.Config,\n\tconfig *Config,\n\ttracer *logging.Tracer,\n\tonClose func(),\n\ttokenGeneratorKey TokenGeneratorKey,\n\tmaxTokenAge time.Duration,\n\tverifySourceAddress func(net.Addr) bool,\n\tdisableVersionNegotiation bool,\n\tacceptEarly bool,\n) *baseServer {\n\ts := &baseServer{\n\t\tconn:                      conn,\n\t\tconnContext:               connContext,\n\t\ttr:                        tr,\n\t\ttlsConf:                   tlsConf,\n\t\tconfig:                    config,\n\t\ttokenGenerator:            handshake.NewTokenGenerator(tokenGeneratorKey),\n\t\tmaxTokenAge:               maxTokenAge,\n\t\tverifySourceAddress:       verifySourceAddress,\n\t\tconnIDGenerator:           connIDGenerator,\n\t\tstatelessResetter:         statelessResetter,\n\t\tconnQueue:                 make(chan quicConn, protocol.MaxAcceptQueueSize),\n\t\terrorChan:                 make(chan struct{}),\n\t\tstopAccepting:             make(chan struct{}),\n\t\trunning:                   make(chan struct{}),\n\t\treceivedPackets:           make(chan receivedPacket, protocol.MaxServerUnprocessedPackets),\n\t\tversionNegotiationQueue:   make(chan receivedPacket, 4),\n\t\tinvalidTokenQueue:         make(chan rejectedPacket, 4),\n\t\tconnectionRefusedQueue:    make(chan rejectedPacket, 4),\n\t\tretryQueue:                make(chan rejectedPacket, 8),\n\t\tnewConn:                   newConnection,\n\t\ttracer:                    tracer,\n\t\tlogger:                    utils.DefaultLogger.WithPrefix(\"server\"),\n\t\tacceptEarlyConns:          acceptEarly,\n\t\tdisableVersionNegotiation: disableVersionNegotiation,\n\t\tonClose:                   onClose,\n\t}\n\tif acceptEarly {\n\t\ts.zeroRTTQueues = map[protocol.ConnectionID]*zeroRTTQueue{}\n\t}\n\tgo s.run()\n\tgo s.runSendQueue()\n\ts.logger.Debugf(\"Listening for %s connections on %s\", conn.LocalAddr().Network(), conn.LocalAddr().String())\n\treturn s\n}\n\nfunc (s *baseServer) run() {\n\tdefer close(s.running)\n\tfor {\n\t\tselect {\n\t\tcase <-s.errorChan:\n\t\t\treturn\n\t\tdefault:\n\t\t}\n\t\tselect {\n\t\tcase <-s.errorChan:\n\t\t\treturn\n\t\tcase p := <-s.receivedPackets:\n\t\t\tif bufferStillInUse := s.handlePacketImpl(p); !bufferStillInUse {\n\t\t\t\tp.buffer.Release()\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (s *baseServer) runSendQueue() {\n\tfor {\n\t\tselect {\n\t\tcase <-s.running:\n\t\t\treturn\n\t\tcase p := <-s.versionNegotiationQueue:\n\t\t\ts.maybeSendVersionNegotiationPacket(p)\n\t\tcase p := <-s.invalidTokenQueue:\n\t\t\ts.maybeSendInvalidToken(p)\n\t\tcase p := <-s.connectionRefusedQueue:\n\t\t\ts.sendConnectionRefused(p)\n\t\tcase p := <-s.retryQueue:\n\t\t\ts.sendRetry(p)\n\t\t}\n\t}\n}\n\n// Accept returns connections that already completed the handshake.\n// It is only valid if acceptEarlyConns is false.\nfunc (s *baseServer) Accept(ctx context.Context) (Connection, error) {\n\treturn s.accept(ctx)\n}\n\nfunc (s *baseServer) accept(ctx context.Context) (quicConn, error) {\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn nil, ctx.Err()\n\tcase conn := <-s.connQueue:\n\t\treturn conn, nil\n\tcase <-s.stopAccepting:\n\t\t// first drain the queue\n\t\tselect {\n\t\tcase conn := <-s.connQueue:\n\t\t\treturn conn, nil\n\t\tdefault:\n\t\t}\n\t\treturn nil, s.closeErr\n\t}\n}\n\nfunc (s *baseServer) Close() error {\n\ts.close(ErrServerClosed, true)\n\treturn nil\n}\n\nfunc (s *baseServer) close(e error, notifyOnClose bool) {\n\ts.closeMx.Lock()\n\tif s.closeErr != nil {\n\t\ts.closeMx.Unlock()\n\t\treturn\n\t}\n\ts.closeErr = e\n\tclose(s.errorChan)\n\t<-s.running\n\ts.closeMx.Unlock()\n\n\tif notifyOnClose {\n\t\ts.onClose()\n\t}\n\t// wait until all handshakes in flight have terminated\n\ts.handshakingCount.Wait()\n\tclose(s.stopAccepting)\n}\n\n// Addr returns the server's network address\nfunc (s *baseServer) Addr() net.Addr {\n\treturn s.conn.LocalAddr()\n}\n\nfunc (s *baseServer) handlePacket(p receivedPacket) {\n\tselect {\n\tcase s.receivedPackets <- p:\n\tcase <-s.errorChan:\n\t\treturn\n\tdefault:\n\t\ts.logger.Debugf(\"Dropping packet from %s (%d bytes). Server receive queue full.\", p.remoteAddr, p.Size())\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropDOSPrevention)\n\t\t}\n\t}\n}\n\nfunc (s *baseServer) handlePacketImpl(p receivedPacket) bool /* is the buffer still in use? */ {\n\tif !s.nextZeroRTTCleanup.IsZero() && p.rcvTime.After(s.nextZeroRTTCleanup) {\n\t\tdefer s.cleanupZeroRTTQueues(p.rcvTime)\n\t}\n\n\tif wire.IsVersionNegotiationPacket(p.data) {\n\t\ts.logger.Debugf(\"Dropping Version Negotiation packet.\")\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropUnexpectedPacket)\n\t\t}\n\t\treturn false\n\t}\n\t// Short header packets should never end up here in the first place\n\tif !wire.IsLongHeaderPacket(p.data[0]) {\n\t\tpanic(fmt.Sprintf(\"misrouted packet: %#v\", p.data))\n\t}\n\tv, err := wire.ParseVersion(p.data)\n\t// drop the packet if we failed to parse the protocol version\n\tif err != nil {\n\t\ts.logger.Debugf(\"Dropping a packet with an unknown version\")\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnexpectedPacket)\n\t\t}\n\t\treturn false\n\t}\n\t// send a Version Negotiation Packet if the client is speaking a different protocol version\n\tif !protocol.IsSupportedVersion(s.config.Versions, v) {\n\t\tif s.disableVersionNegotiation {\n\t\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\t\ts.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnexpectedVersion)\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\n\t\tif p.Size() < protocol.MinUnknownVersionPacketSize {\n\t\t\ts.logger.Debugf(\"Dropping a packet with an unsupported version number %d that is too small (%d bytes)\", v, p.Size())\n\t\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\t\ts.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnexpectedPacket)\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\t\treturn s.enqueueVersionNegotiationPacket(p)\n\t}\n\n\tif wire.Is0RTTPacket(p.data) {\n\t\tif !s.acceptEarlyConns {\n\t\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\t\ts.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropUnexpectedPacket)\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\t\treturn s.handle0RTTPacket(p)\n\t}\n\n\t// If we're creating a new connection, the packet will be passed to the connection.\n\t// The header will then be parsed again.\n\thdr, _, _, err := wire.ParsePacket(p.data)\n\tif err != nil {\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropHeaderParseError)\n\t\t}\n\t\ts.logger.Debugf(\"Error parsing packet: %s\", err)\n\t\treturn false\n\t}\n\tif hdr.Type == protocol.PacketTypeInitial && p.Size() < protocol.MinInitialPacketSize {\n\t\ts.logger.Debugf(\"Dropping a packet that is too small to be a valid Initial (%d bytes)\", p.Size())\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropUnexpectedPacket)\n\t\t}\n\t\treturn false\n\t}\n\n\tif hdr.Type != protocol.PacketTypeInitial {\n\t\t// Drop long header packets.\n\t\t// There's little point in sending a Stateless Reset, since the client\n\t\t// might not have received the token yet.\n\t\ts.logger.Debugf(\"Dropping long header packet of type %s (%d bytes)\", hdr.Type, len(p.data))\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeFromHeader(hdr), p.Size(), logging.PacketDropUnexpectedPacket)\n\t\t}\n\t\treturn false\n\t}\n\n\ts.logger.Debugf(\"<- Received Initial packet.\")\n\n\tif err := s.handleInitialImpl(p, hdr); err != nil {\n\t\ts.logger.Errorf(\"Error occurred handling initial packet: %s\", err)\n\t}\n\t// Don't put the packet buffer back.\n\t// handleInitialImpl deals with the buffer.\n\treturn true\n}\n\nfunc (s *baseServer) handle0RTTPacket(p receivedPacket) bool {\n\tconnID, err := wire.ParseConnectionID(p.data, 0)\n\tif err != nil {\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropHeaderParseError)\n\t\t}\n\t\treturn false\n\t}\n\n\t// check again if we might have a connection now\n\tif handler, ok := s.tr.connRunner().Get(connID); ok {\n\t\thandler.handlePacket(p)\n\t\treturn true\n\t}\n\n\tif q, ok := s.zeroRTTQueues[connID]; ok {\n\t\tif len(q.packets) >= protocol.Max0RTTQueueLen {\n\t\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\t\ts.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropDOSPrevention)\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\t\tq.packets = append(q.packets, p)\n\t\treturn true\n\t}\n\n\tif len(s.zeroRTTQueues) >= protocol.Max0RTTQueues {\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropDOSPrevention)\n\t\t}\n\t\treturn false\n\t}\n\tqueue := &zeroRTTQueue{packets: make([]receivedPacket, 1, 8)}\n\tqueue.packets[0] = p\n\texpiration := p.rcvTime.Add(protocol.Max0RTTQueueingDuration)\n\tqueue.expiration = expiration\n\tif s.nextZeroRTTCleanup.IsZero() || s.nextZeroRTTCleanup.After(expiration) {\n\t\ts.nextZeroRTTCleanup = expiration\n\t}\n\ts.zeroRTTQueues[connID] = queue\n\treturn true\n}\n\nfunc (s *baseServer) cleanupZeroRTTQueues(now time.Time) {\n\t// Iterate over all queues to find those that are expired.\n\t// This is ok since we're placing a pretty low limit on the number of queues.\n\tvar nextCleanup time.Time\n\tfor connID, q := range s.zeroRTTQueues {\n\t\tif q.expiration.After(now) {\n\t\t\tif nextCleanup.IsZero() || nextCleanup.After(q.expiration) {\n\t\t\t\tnextCleanup = q.expiration\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tfor _, p := range q.packets {\n\t\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\t\ts.tracer.DroppedPacket(p.remoteAddr, logging.PacketType0RTT, p.Size(), logging.PacketDropDOSPrevention)\n\t\t\t}\n\t\t\tp.buffer.Release()\n\t\t}\n\t\tdelete(s.zeroRTTQueues, connID)\n\t\tif s.logger.Debug() {\n\t\t\ts.logger.Debugf(\"Removing 0-RTT queue for %s.\", connID)\n\t\t}\n\t}\n\ts.nextZeroRTTCleanup = nextCleanup\n}\n\n// validateToken returns false if:\n//   - address is invalid\n//   - token is expired\n//   - token is null\nfunc (s *baseServer) validateToken(token *handshake.Token, addr net.Addr) bool {\n\tif token == nil {\n\t\treturn false\n\t}\n\tif !token.ValidateRemoteAddr(addr) {\n\t\treturn false\n\t}\n\tif !token.IsRetryToken && time.Since(token.SentTime) > s.maxTokenAge {\n\t\treturn false\n\t}\n\tif token.IsRetryToken && time.Since(token.SentTime) > s.config.maxRetryTokenAge() {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (s *baseServer) handleInitialImpl(p receivedPacket, hdr *wire.Header) error {\n\tif len(hdr.Token) == 0 && hdr.DestConnectionID.Len() < protocol.MinConnectionIDLenInitial {\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropUnexpectedPacket)\n\t\t}\n\t\tp.buffer.Release()\n\t\treturn errors.New(\"too short connection ID\")\n\t}\n\n\t// The server queues packets for a while, and we might already have established a connection by now.\n\t// This results in a second check in the connection map.\n\t// That's ok since it's not the hot path (it's only taken by some Initial and 0-RTT packets).\n\tif handler, ok := s.tr.connRunner().Get(hdr.DestConnectionID); ok {\n\t\thandler.handlePacket(p)\n\t\treturn nil\n\t}\n\n\tvar (\n\t\ttoken              *handshake.Token\n\t\tretrySrcConnID     *protocol.ConnectionID\n\t\tclientAddrVerified bool\n\t)\n\torigDestConnID := hdr.DestConnectionID\n\tif len(hdr.Token) > 0 {\n\t\ttok, err := s.tokenGenerator.DecodeToken(hdr.Token)\n\t\tif err == nil {\n\t\t\tif tok.IsRetryToken {\n\t\t\t\torigDestConnID = tok.OriginalDestConnectionID\n\t\t\t\tretrySrcConnID = &tok.RetrySrcConnectionID\n\t\t\t}\n\t\t\ttoken = tok\n\t\t}\n\t}\n\tif token != nil {\n\t\tclientAddrVerified = s.validateToken(token, p.remoteAddr)\n\t\tif !clientAddrVerified {\n\t\t\t// For invalid and expired non-retry tokens, we don't send an INVALID_TOKEN error.\n\t\t\t// We just ignore them, and act as if there was no token on this packet at all.\n\t\t\t// This also means we might send a Retry later.\n\t\t\tif !token.IsRetryToken {\n\t\t\t\ttoken = nil\n\t\t\t} else {\n\t\t\t\t// For Retry tokens, we send an INVALID_ERROR if\n\t\t\t\t// * the token is too old, or\n\t\t\t\t// * the token is invalid, in case of a retry token.\n\t\t\t\tselect {\n\t\t\t\tcase s.invalidTokenQueue <- rejectedPacket{receivedPacket: p, hdr: hdr}:\n\t\t\t\tdefault:\n\t\t\t\t\t// drop packet if we can't send out the  INVALID_TOKEN packets fast enough\n\t\t\t\t\tp.buffer.Release()\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\n\tif token == nil && s.verifySourceAddress != nil && s.verifySourceAddress(p.remoteAddr) {\n\t\t// Retry invalidates all 0-RTT packets sent.\n\t\tdelete(s.zeroRTTQueues, hdr.DestConnectionID)\n\t\tselect {\n\t\tcase s.retryQueue <- rejectedPacket{receivedPacket: p, hdr: hdr}:\n\t\tdefault:\n\t\t\t// drop packet if we can't send out Retry packets fast enough\n\t\t\tp.buffer.Release()\n\t\t}\n\t\treturn nil\n\t}\n\n\tconfig := s.config\n\tif s.config.GetConfigForClient != nil {\n\t\tconf, err := s.config.GetConfigForClient(&ClientInfo{\n\t\t\tRemoteAddr:   p.remoteAddr,\n\t\t\tAddrVerified: clientAddrVerified,\n\t\t})\n\t\tif err != nil {\n\t\t\ts.logger.Debugf(\"Rejecting new connection due to GetConfigForClient callback\")\n\t\t\tdelete(s.zeroRTTQueues, hdr.DestConnectionID)\n\t\t\tselect {\n\t\t\tcase s.connectionRefusedQueue <- rejectedPacket{receivedPacket: p, hdr: hdr}:\n\t\t\tdefault:\n\t\t\t\t// drop packet if we can't send out the CONNECTION_REFUSED fast enough\n\t\t\t\tp.buffer.Release()\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t\tconfig = populateConfig(conf)\n\t}\n\n\tvar conn quicConn\n\tvar cancel context.CancelCauseFunc\n\tctx, cancel1 := context.WithCancelCause(context.Background())\n\tif s.connContext != nil {\n\t\tctx = s.connContext(ctx)\n\t\tif ctx == nil {\n\t\t\tpanic(\"quic: ConnContext returned nil\")\n\t\t}\n\t\t// There's no guarantee that the application returns a context\n\t\t// that's derived from the context we passed into ConnContext.\n\t\t// We need to make sure that both contexts are cancelled.\n\t\tvar cancel2 context.CancelCauseFunc\n\t\tctx, cancel2 = context.WithCancelCause(ctx)\n\t\tcancel = func(cause error) {\n\t\t\tcancel1(cause)\n\t\t\tcancel2(cause)\n\t\t}\n\t} else {\n\t\tcancel = cancel1\n\t}\n\tctx = context.WithValue(ctx, ConnectionTracingKey, nextConnTracingID())\n\tvar tracer *logging.ConnectionTracer\n\tif config.Tracer != nil {\n\t\t// Use the same connection ID that is passed to the client's GetLogWriter callback.\n\t\tconnID := hdr.DestConnectionID\n\t\tif origDestConnID.Len() > 0 {\n\t\t\tconnID = origDestConnID\n\t\t}\n\t\ttracer = config.Tracer(ctx, protocol.PerspectiveServer, connID)\n\t}\n\tconnID, err := s.connIDGenerator.GenerateConnectionID()\n\tif err != nil {\n\t\treturn err\n\t}\n\ts.logger.Debugf(\"Changing connection ID to %s.\", connID)\n\tconn = s.newConn(\n\t\tctx,\n\t\tcancel,\n\t\tnewSendConn(s.conn, p.remoteAddr, p.info, s.logger),\n\t\ts.tr,\n\t\torigDestConnID,\n\t\tretrySrcConnID,\n\t\thdr.DestConnectionID,\n\t\thdr.SrcConnectionID,\n\t\tconnID,\n\t\ts.connIDGenerator,\n\t\ts.statelessResetter,\n\t\tconfig,\n\t\ts.tlsConf,\n\t\ts.tokenGenerator,\n\t\tclientAddrVerified,\n\t\ttracer,\n\t\ts.logger,\n\t\thdr.Version,\n\t)\n\tconn.handlePacket(p)\n\t// Adding the connection will fail if the client's chosen Destination Connection ID is already in use.\n\t// This is very unlikely: Even if an attacker chooses a connection ID that's already in use,\n\t// under normal circumstances the packet would just be routed to that connection.\n\t// The only time this collision will occur if we receive the two Initial packets at the same time.\n\tif added := s.tr.connRunner().AddWithConnID(hdr.DestConnectionID, connID, conn); !added {\n\t\tdelete(s.zeroRTTQueues, hdr.DestConnectionID)\n\t\tconn.closeWithTransportError(qerr.ConnectionRefused)\n\t\treturn nil\n\t}\n\t// Pass queued 0-RTT to the newly established connection.\n\tif q, ok := s.zeroRTTQueues[hdr.DestConnectionID]; ok {\n\t\tfor _, p := range q.packets {\n\t\t\tconn.handlePacket(p)\n\t\t}\n\t\tdelete(s.zeroRTTQueues, hdr.DestConnectionID)\n\t}\n\n\ts.handshakingCount.Add(1)\n\tgo func() {\n\t\tdefer s.handshakingCount.Done()\n\t\ts.handleNewConn(conn)\n\t}()\n\tgo conn.run()\n\treturn nil\n}\n\nfunc (s *baseServer) handleNewConn(conn quicConn) {\n\tif s.acceptEarlyConns {\n\t\t// wait until the early connection is ready, the handshake fails, or the server is closed\n\t\tselect {\n\t\tcase <-s.errorChan:\n\t\t\tconn.closeWithTransportError(ConnectionRefused)\n\t\t\treturn\n\t\tcase <-conn.Context().Done():\n\t\t\treturn\n\t\tcase <-conn.earlyConnReady():\n\t\t}\n\t} else {\n\t\t// wait until the handshake completes, fails, or the server is closed\n\t\tselect {\n\t\tcase <-s.errorChan:\n\t\t\tconn.closeWithTransportError(ConnectionRefused)\n\t\t\treturn\n\t\tcase <-conn.Context().Done():\n\t\t\treturn\n\t\tcase <-conn.HandshakeComplete():\n\t\t}\n\t}\n\n\tselect {\n\tcase s.connQueue <- conn:\n\tdefault:\n\t\tconn.closeWithTransportError(ConnectionRefused)\n\t}\n}\n\nfunc (s *baseServer) sendRetry(p rejectedPacket) {\n\tif err := s.sendRetryPacket(p); err != nil {\n\t\ts.logger.Debugf(\"Error sending Retry packet: %s\", err)\n\t}\n}\n\nfunc (s *baseServer) sendRetryPacket(p rejectedPacket) error {\n\thdr := p.hdr\n\t// Log the Initial packet now.\n\t// If no Retry is sent, the packet will be logged by the connection.\n\t(&wire.ExtendedHeader{Header: *hdr}).Log(s.logger)\n\tsrcConnID, err := s.connIDGenerator.GenerateConnectionID()\n\tif err != nil {\n\t\treturn err\n\t}\n\ttoken, err := s.tokenGenerator.NewRetryToken(p.remoteAddr, hdr.DestConnectionID, srcConnID)\n\tif err != nil {\n\t\treturn err\n\t}\n\treplyHdr := &wire.ExtendedHeader{}\n\treplyHdr.Type = protocol.PacketTypeRetry\n\treplyHdr.Version = hdr.Version\n\treplyHdr.SrcConnectionID = srcConnID\n\treplyHdr.DestConnectionID = hdr.SrcConnectionID\n\treplyHdr.Token = token\n\tif s.logger.Debug() {\n\t\ts.logger.Debugf(\"Changing connection ID to %s.\", srcConnID)\n\t\ts.logger.Debugf(\"-> Sending Retry\")\n\t\treplyHdr.Log(s.logger)\n\t}\n\n\tbuf := getPacketBuffer()\n\tdefer buf.Release()\n\tbuf.Data, err = replyHdr.Append(buf.Data, hdr.Version)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// append the Retry integrity tag\n\ttag := handshake.GetRetryIntegrityTag(buf.Data, hdr.DestConnectionID, hdr.Version)\n\tbuf.Data = append(buf.Data, tag[:]...)\n\tif s.tracer != nil && s.tracer.SentPacket != nil {\n\t\ts.tracer.SentPacket(p.remoteAddr, &replyHdr.Header, protocol.ByteCount(len(buf.Data)), nil)\n\t}\n\t_, err = s.conn.WritePacket(buf.Data, p.remoteAddr, p.info.OOB(), 0, protocol.ECNUnsupported)\n\treturn err\n}\n\nfunc (s *baseServer) maybeSendInvalidToken(p rejectedPacket) {\n\tdefer p.buffer.Release()\n\n\t// Only send INVALID_TOKEN if we can unprotect the packet.\n\t// This makes sure that we won't send it for packets that were corrupted.\n\thdr := p.hdr\n\tsealer, opener := handshake.NewInitialAEAD(hdr.DestConnectionID, protocol.PerspectiveServer, hdr.Version)\n\tdata := p.data[:hdr.ParsedLen()+hdr.Length]\n\textHdr, err := unpackLongHeader(opener, hdr, data)\n\t// Only send INVALID_TOKEN if we can unprotect the packet.\n\t// This makes sure that we won't send it for packets that were corrupted.\n\tif err != nil {\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropHeaderParseError)\n\t\t}\n\t\treturn\n\t}\n\thdrLen := extHdr.ParsedLen()\n\tif _, err := opener.Open(data[hdrLen:hdrLen], data[hdrLen:], extHdr.PacketNumber, data[:hdrLen]); err != nil {\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeInitial, p.Size(), logging.PacketDropPayloadDecryptError)\n\t\t}\n\t\treturn\n\t}\n\tif s.logger.Debug() {\n\t\ts.logger.Debugf(\"Client sent an invalid retry token. Sending INVALID_TOKEN to %s.\", p.remoteAddr)\n\t}\n\tif err := s.sendError(p.remoteAddr, hdr, sealer, qerr.InvalidToken, p.info); err != nil {\n\t\ts.logger.Debugf(\"Error sending INVALID_TOKEN error: %s\", err)\n\t}\n}\n\nfunc (s *baseServer) sendConnectionRefused(p rejectedPacket) {\n\tdefer p.buffer.Release()\n\tsealer, _ := handshake.NewInitialAEAD(p.hdr.DestConnectionID, protocol.PerspectiveServer, p.hdr.Version)\n\tif err := s.sendError(p.remoteAddr, p.hdr, sealer, qerr.ConnectionRefused, p.info); err != nil {\n\t\ts.logger.Debugf(\"Error sending CONNECTION_REFUSED error: %s\", err)\n\t}\n}\n\n// sendError sends the error as a response to the packet received with header hdr\nfunc (s *baseServer) sendError(remoteAddr net.Addr, hdr *wire.Header, sealer handshake.LongHeaderSealer, errorCode qerr.TransportErrorCode, info packetInfo) error {\n\tb := getPacketBuffer()\n\tdefer b.Release()\n\n\tccf := &wire.ConnectionCloseFrame{ErrorCode: uint64(errorCode)}\n\n\treplyHdr := &wire.ExtendedHeader{}\n\treplyHdr.Type = protocol.PacketTypeInitial\n\treplyHdr.Version = hdr.Version\n\treplyHdr.SrcConnectionID = hdr.DestConnectionID\n\treplyHdr.DestConnectionID = hdr.SrcConnectionID\n\treplyHdr.PacketNumberLen = protocol.PacketNumberLen4\n\treplyHdr.Length = 4 /* packet number len */ + ccf.Length(hdr.Version) + protocol.ByteCount(sealer.Overhead())\n\tvar err error\n\tb.Data, err = replyHdr.Append(b.Data, hdr.Version)\n\tif err != nil {\n\t\treturn err\n\t}\n\tpayloadOffset := len(b.Data)\n\n\tb.Data, err = ccf.Append(b.Data, hdr.Version)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_ = sealer.Seal(b.Data[payloadOffset:payloadOffset], b.Data[payloadOffset:], replyHdr.PacketNumber, b.Data[:payloadOffset])\n\tb.Data = b.Data[0 : len(b.Data)+sealer.Overhead()]\n\n\tpnOffset := payloadOffset - int(replyHdr.PacketNumberLen)\n\tsealer.EncryptHeader(\n\t\tb.Data[pnOffset+4:pnOffset+4+16],\n\t\t&b.Data[0],\n\t\tb.Data[pnOffset:payloadOffset],\n\t)\n\n\treplyHdr.Log(s.logger)\n\twire.LogFrame(s.logger, ccf, true)\n\tif s.tracer != nil && s.tracer.SentPacket != nil {\n\t\ts.tracer.SentPacket(remoteAddr, &replyHdr.Header, protocol.ByteCount(len(b.Data)), []logging.Frame{ccf})\n\t}\n\t_, err = s.conn.WritePacket(b.Data, remoteAddr, info.OOB(), 0, protocol.ECNUnsupported)\n\treturn err\n}\n\nfunc (s *baseServer) enqueueVersionNegotiationPacket(p receivedPacket) (bufferInUse bool) {\n\tselect {\n\tcase s.versionNegotiationQueue <- p:\n\t\treturn true\n\tdefault:\n\t\t// it's fine to not send version negotiation packets when we are busy\n\t}\n\treturn false\n}\n\nfunc (s *baseServer) maybeSendVersionNegotiationPacket(p receivedPacket) {\n\tdefer p.buffer.Release()\n\n\tv, err := wire.ParseVersion(p.data)\n\tif err != nil {\n\t\ts.logger.Debugf(\"failed to parse version for sending version negotiation packet: %s\", err)\n\t\treturn\n\t}\n\n\t_, src, dest, err := wire.ParseArbitraryLenConnectionIDs(p.data)\n\tif err != nil { // should never happen\n\t\ts.logger.Debugf(\"Dropping a packet with an unknown version for which we failed to parse connection IDs\")\n\t\tif s.tracer != nil && s.tracer.DroppedPacket != nil {\n\t\t\ts.tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnexpectedPacket)\n\t\t}\n\t\treturn\n\t}\n\n\ts.logger.Debugf(\"Client offered version %s, sending Version Negotiation\", v)\n\n\tdata := wire.ComposeVersionNegotiation(dest, src, s.config.Versions)\n\tif s.tracer != nil && s.tracer.SentVersionNegotiationPacket != nil {\n\t\ts.tracer.SentVersionNegotiationPacket(p.remoteAddr, src, dest, s.config.Versions)\n\t}\n\tif _, err := s.conn.WritePacket(data, p.remoteAddr, p.info.OOB(), 0, protocol.ECNUnsupported); err != nil {\n\t\ts.logger.Debugf(\"Error sending Version Negotiation: %s\", err)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/stateless_reset.go",
    "content": "package quic\n\nimport (\n\t\"crypto/hmac\"\n\t\"crypto/rand\"\n\t\"crypto/sha256\"\n\t\"hash\"\n\t\"sync\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n)\n\ntype statelessResetter struct {\n\tmx sync.Mutex\n\th  hash.Hash\n}\n\n// newStatelessRetter creates a new stateless reset generator.\n// It is valid to use a nil key. In that case, a random key will be used.\n// This makes is impossible for on-path attackers to shut down established connections.\nfunc newStatelessResetter(key *StatelessResetKey) *statelessResetter {\n\tvar h hash.Hash\n\tif key != nil {\n\t\th = hmac.New(sha256.New, key[:])\n\t} else {\n\t\tb := make([]byte, 32)\n\t\t_, _ = rand.Read(b)\n\t\th = hmac.New(sha256.New, b)\n\t}\n\treturn &statelessResetter{h: h}\n}\n\nfunc (r *statelessResetter) GetStatelessResetToken(connID protocol.ConnectionID) protocol.StatelessResetToken {\n\tr.mx.Lock()\n\tdefer r.mx.Unlock()\n\n\tvar token protocol.StatelessResetToken\n\tr.h.Write(connID.Bytes())\n\tcopy(token[:], r.h.Sum(nil))\n\tr.h.Reset()\n\treturn token\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/stream.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/ackhandler\"\n\t\"github.com/quic-go/quic-go/internal/flowcontrol\"\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\ntype deadlineError struct{}\n\nfunc (deadlineError) Error() string   { return \"deadline exceeded\" }\nfunc (deadlineError) Temporary() bool { return true }\nfunc (deadlineError) Timeout() bool   { return true }\nfunc (deadlineError) Unwrap() error   { return os.ErrDeadlineExceeded }\n\nvar errDeadline net.Error = &deadlineError{}\n\n// The streamSender is notified by the stream about various events.\ntype streamSender interface {\n\tonHasConnectionData()\n\tonHasStreamData(protocol.StreamID, sendStreamI)\n\tonHasStreamControlFrame(protocol.StreamID, streamControlFrameGetter)\n\t// must be called without holding the mutex that is acquired by closeForShutdown\n\tonStreamCompleted(protocol.StreamID)\n}\n\n// Each of the both stream halves gets its own uniStreamSender.\n// This is necessary in order to keep track when both halves have been completed.\ntype uniStreamSender struct {\n\tstreamSender\n\tonStreamCompletedImpl       func()\n\tonHasStreamControlFrameImpl func(protocol.StreamID, streamControlFrameGetter)\n}\n\nfunc (s *uniStreamSender) onHasStreamData(id protocol.StreamID, str sendStreamI) {\n\ts.streamSender.onHasStreamData(id, str)\n}\nfunc (s *uniStreamSender) onStreamCompleted(protocol.StreamID) { s.onStreamCompletedImpl() }\nfunc (s *uniStreamSender) onHasStreamControlFrame(id protocol.StreamID, str streamControlFrameGetter) {\n\ts.onHasStreamControlFrameImpl(id, str)\n}\n\nvar _ streamSender = &uniStreamSender{}\n\ntype streamI interface {\n\tStream\n\tcloseForShutdown(error)\n\t// for receiving\n\thandleStreamFrame(*wire.StreamFrame, time.Time) error\n\thandleResetStreamFrame(*wire.ResetStreamFrame, time.Time) error\n\t// for sending\n\thasData() bool\n\thandleStopSendingFrame(*wire.StopSendingFrame)\n\tpopStreamFrame(protocol.ByteCount, protocol.Version) (_ ackhandler.StreamFrame, _ *wire.StreamDataBlockedFrame, hasMore bool)\n\tupdateSendWindow(protocol.ByteCount)\n}\n\nvar (\n\t_ receiveStreamI = (streamI)(nil)\n\t_ sendStreamI    = (streamI)(nil)\n)\n\n// A Stream assembles the data from StreamFrames and provides a super-convenient Read-Interface\n//\n// Read() and Write() may be called concurrently, but multiple calls to Read() or Write() individually must be synchronized manually.\ntype stream struct {\n\treceiveStream\n\tsendStream\n\n\tcompletedMutex         sync.Mutex\n\tsender                 streamSender\n\treceiveStreamCompleted bool\n\tsendStreamCompleted    bool\n}\n\nvar (\n\t_ Stream                   = &stream{}\n\t_ streamControlFrameGetter = &receiveStream{}\n)\n\n// newStream creates a new Stream\nfunc newStream(\n\tctx context.Context,\n\tstreamID protocol.StreamID,\n\tsender streamSender,\n\tflowController flowcontrol.StreamFlowController,\n) *stream {\n\ts := &stream{sender: sender}\n\tsenderForSendStream := &uniStreamSender{\n\t\tstreamSender: sender,\n\t\tonStreamCompletedImpl: func() {\n\t\t\ts.completedMutex.Lock()\n\t\t\ts.sendStreamCompleted = true\n\t\t\ts.checkIfCompleted()\n\t\t\ts.completedMutex.Unlock()\n\t\t},\n\t\tonHasStreamControlFrameImpl: func(id protocol.StreamID, str streamControlFrameGetter) {\n\t\t\tsender.onHasStreamControlFrame(streamID, s)\n\t\t},\n\t}\n\ts.sendStream = *newSendStream(ctx, streamID, senderForSendStream, flowController)\n\tsenderForReceiveStream := &uniStreamSender{\n\t\tstreamSender: sender,\n\t\tonStreamCompletedImpl: func() {\n\t\t\ts.completedMutex.Lock()\n\t\t\ts.receiveStreamCompleted = true\n\t\t\ts.checkIfCompleted()\n\t\t\ts.completedMutex.Unlock()\n\t\t},\n\t\tonHasStreamControlFrameImpl: func(id protocol.StreamID, str streamControlFrameGetter) {\n\t\t\tsender.onHasStreamControlFrame(streamID, s)\n\t\t},\n\t}\n\ts.receiveStream = *newReceiveStream(streamID, senderForReceiveStream, flowController)\n\treturn s\n}\n\n// need to define StreamID() here, since both receiveStream and readStream have a StreamID()\nfunc (s *stream) StreamID() protocol.StreamID {\n\t// the result is same for receiveStream and sendStream\n\treturn s.sendStream.StreamID()\n}\n\nfunc (s *stream) Close() error {\n\treturn s.sendStream.Close()\n}\n\nfunc (s *stream) getControlFrame(now time.Time) (_ ackhandler.Frame, ok, hasMore bool) {\n\tf, ok, _ := s.sendStream.getControlFrame(now)\n\tif ok {\n\t\treturn f, true, true\n\t}\n\treturn s.receiveStream.getControlFrame(now)\n}\n\nfunc (s *stream) SetDeadline(t time.Time) error {\n\t_ = s.SetReadDeadline(t)  // SetReadDeadline never errors\n\t_ = s.SetWriteDeadline(t) // SetWriteDeadline never errors\n\treturn nil\n}\n\n// CloseForShutdown closes a stream abruptly.\n// It makes Read and Write unblock (and return the error) immediately.\n// The peer will NOT be informed about this: the stream is closed without sending a FIN or RST.\nfunc (s *stream) closeForShutdown(err error) {\n\ts.sendStream.closeForShutdown(err)\n\ts.receiveStream.closeForShutdown(err)\n}\n\n// checkIfCompleted is called from the uniStreamSender, when one of the stream halves is completed.\n// It makes sure that the onStreamCompleted callback is only called if both receive and send side have completed.\nfunc (s *stream) checkIfCompleted() {\n\tif s.sendStreamCompleted && s.receiveStreamCompleted {\n\t\ts.sender.onStreamCompleted(s.StreamID())\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/streams_map.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/quic-go/quic-go/internal/flowcontrol\"\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/qerr\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\ntype streamError struct {\n\tmessage string\n\tnums    []protocol.StreamNum\n}\n\nfunc (e streamError) Error() string {\n\treturn e.message\n}\n\nfunc convertStreamError(err error, stype protocol.StreamType, pers protocol.Perspective) error {\n\tstrError, ok := err.(streamError)\n\tif !ok {\n\t\treturn err\n\t}\n\tids := make([]interface{}, len(strError.nums))\n\tfor i, num := range strError.nums {\n\t\tids[i] = num.StreamID(stype, pers)\n\t}\n\treturn fmt.Errorf(strError.Error(), ids...)\n}\n\n// StreamLimitReachedError is returned from Connection.OpenStream and Connection.OpenUniStream\n// when it is not possible to open a new stream because the number of opens streams reached\n// the peer's stream limit.\ntype StreamLimitReachedError struct{}\n\nfunc (e StreamLimitReachedError) Error() string { return \"too many open streams\" }\n\ntype streamsMap struct {\n\tctx         context.Context // not used for cancellations, but carries the values associated with the connection\n\tperspective protocol.Perspective\n\n\tmaxIncomingBidiStreams uint64\n\tmaxIncomingUniStreams  uint64\n\n\tsender            streamSender\n\tqueueControlFrame func(wire.Frame)\n\tnewFlowController func(protocol.StreamID) flowcontrol.StreamFlowController\n\n\tmutex               sync.Mutex\n\toutgoingBidiStreams *outgoingStreamsMap[streamI]\n\toutgoingUniStreams  *outgoingStreamsMap[sendStreamI]\n\tincomingBidiStreams *incomingStreamsMap[streamI]\n\tincomingUniStreams  *incomingStreamsMap[receiveStreamI]\n\treset               bool\n}\n\nvar _ streamManager = &streamsMap{}\n\nfunc newStreamsMap(\n\tctx context.Context,\n\tsender streamSender,\n\tqueueControlFrame func(wire.Frame),\n\tnewFlowController func(protocol.StreamID) flowcontrol.StreamFlowController,\n\tmaxIncomingBidiStreams uint64,\n\tmaxIncomingUniStreams uint64,\n\tperspective protocol.Perspective,\n) *streamsMap {\n\tm := &streamsMap{\n\t\tctx:                    ctx,\n\t\tperspective:            perspective,\n\t\tqueueControlFrame:      queueControlFrame,\n\t\tnewFlowController:      newFlowController,\n\t\tmaxIncomingBidiStreams: maxIncomingBidiStreams,\n\t\tmaxIncomingUniStreams:  maxIncomingUniStreams,\n\t\tsender:                 sender,\n\t}\n\tm.initMaps()\n\treturn m\n}\n\nfunc (m *streamsMap) initMaps() {\n\tm.outgoingBidiStreams = newOutgoingStreamsMap(\n\t\tprotocol.StreamTypeBidi,\n\t\tfunc(num protocol.StreamNum) streamI {\n\t\t\tid := num.StreamID(protocol.StreamTypeBidi, m.perspective)\n\t\t\treturn newStream(m.ctx, id, m.sender, m.newFlowController(id))\n\t\t},\n\t\tm.queueControlFrame,\n\t)\n\tm.incomingBidiStreams = newIncomingStreamsMap(\n\t\tprotocol.StreamTypeBidi,\n\t\tfunc(num protocol.StreamNum) streamI {\n\t\t\tid := num.StreamID(protocol.StreamTypeBidi, m.perspective.Opposite())\n\t\t\treturn newStream(m.ctx, id, m.sender, m.newFlowController(id))\n\t\t},\n\t\tm.maxIncomingBidiStreams,\n\t\tm.queueControlFrame,\n\t)\n\tm.outgoingUniStreams = newOutgoingStreamsMap(\n\t\tprotocol.StreamTypeUni,\n\t\tfunc(num protocol.StreamNum) sendStreamI {\n\t\t\tid := num.StreamID(protocol.StreamTypeUni, m.perspective)\n\t\t\treturn newSendStream(m.ctx, id, m.sender, m.newFlowController(id))\n\t\t},\n\t\tm.queueControlFrame,\n\t)\n\tm.incomingUniStreams = newIncomingStreamsMap(\n\t\tprotocol.StreamTypeUni,\n\t\tfunc(num protocol.StreamNum) receiveStreamI {\n\t\t\tid := num.StreamID(protocol.StreamTypeUni, m.perspective.Opposite())\n\t\t\treturn newReceiveStream(id, m.sender, m.newFlowController(id))\n\t\t},\n\t\tm.maxIncomingUniStreams,\n\t\tm.queueControlFrame,\n\t)\n}\n\nfunc (m *streamsMap) OpenStream() (Stream, error) {\n\tm.mutex.Lock()\n\treset := m.reset\n\tmm := m.outgoingBidiStreams\n\tm.mutex.Unlock()\n\tif reset {\n\t\treturn nil, Err0RTTRejected\n\t}\n\tstr, err := mm.OpenStream()\n\treturn str, convertStreamError(err, protocol.StreamTypeBidi, m.perspective)\n}\n\nfunc (m *streamsMap) OpenStreamSync(ctx context.Context) (Stream, error) {\n\tm.mutex.Lock()\n\treset := m.reset\n\tmm := m.outgoingBidiStreams\n\tm.mutex.Unlock()\n\tif reset {\n\t\treturn nil, Err0RTTRejected\n\t}\n\tstr, err := mm.OpenStreamSync(ctx)\n\treturn str, convertStreamError(err, protocol.StreamTypeBidi, m.perspective)\n}\n\nfunc (m *streamsMap) OpenUniStream() (SendStream, error) {\n\tm.mutex.Lock()\n\treset := m.reset\n\tmm := m.outgoingUniStreams\n\tm.mutex.Unlock()\n\tif reset {\n\t\treturn nil, Err0RTTRejected\n\t}\n\tstr, err := mm.OpenStream()\n\treturn str, convertStreamError(err, protocol.StreamTypeBidi, m.perspective)\n}\n\nfunc (m *streamsMap) OpenUniStreamSync(ctx context.Context) (SendStream, error) {\n\tm.mutex.Lock()\n\treset := m.reset\n\tmm := m.outgoingUniStreams\n\tm.mutex.Unlock()\n\tif reset {\n\t\treturn nil, Err0RTTRejected\n\t}\n\tstr, err := mm.OpenStreamSync(ctx)\n\treturn str, convertStreamError(err, protocol.StreamTypeUni, m.perspective)\n}\n\nfunc (m *streamsMap) AcceptStream(ctx context.Context) (Stream, error) {\n\tm.mutex.Lock()\n\treset := m.reset\n\tmm := m.incomingBidiStreams\n\tm.mutex.Unlock()\n\tif reset {\n\t\treturn nil, Err0RTTRejected\n\t}\n\tstr, err := mm.AcceptStream(ctx)\n\treturn str, convertStreamError(err, protocol.StreamTypeBidi, m.perspective.Opposite())\n}\n\nfunc (m *streamsMap) AcceptUniStream(ctx context.Context) (ReceiveStream, error) {\n\tm.mutex.Lock()\n\treset := m.reset\n\tmm := m.incomingUniStreams\n\tm.mutex.Unlock()\n\tif reset {\n\t\treturn nil, Err0RTTRejected\n\t}\n\tstr, err := mm.AcceptStream(ctx)\n\treturn str, convertStreamError(err, protocol.StreamTypeUni, m.perspective.Opposite())\n}\n\nfunc (m *streamsMap) DeleteStream(id protocol.StreamID) error {\n\tnum := id.StreamNum()\n\tswitch id.Type() {\n\tcase protocol.StreamTypeUni:\n\t\tif id.InitiatedBy() == m.perspective {\n\t\t\treturn convertStreamError(m.outgoingUniStreams.DeleteStream(num), protocol.StreamTypeUni, m.perspective)\n\t\t}\n\t\treturn convertStreamError(m.incomingUniStreams.DeleteStream(num), protocol.StreamTypeUni, m.perspective.Opposite())\n\tcase protocol.StreamTypeBidi:\n\t\tif id.InitiatedBy() == m.perspective {\n\t\t\treturn convertStreamError(m.outgoingBidiStreams.DeleteStream(num), protocol.StreamTypeBidi, m.perspective)\n\t\t}\n\t\treturn convertStreamError(m.incomingBidiStreams.DeleteStream(num), protocol.StreamTypeBidi, m.perspective.Opposite())\n\t}\n\tpanic(\"\")\n}\n\nfunc (m *streamsMap) GetOrOpenReceiveStream(id protocol.StreamID) (receiveStreamI, error) {\n\tstr, err := m.getOrOpenReceiveStream(id)\n\tif err != nil {\n\t\treturn nil, &qerr.TransportError{\n\t\t\tErrorCode:    qerr.StreamStateError,\n\t\t\tErrorMessage: err.Error(),\n\t\t}\n\t}\n\treturn str, nil\n}\n\nfunc (m *streamsMap) getOrOpenReceiveStream(id protocol.StreamID) (receiveStreamI, error) {\n\tnum := id.StreamNum()\n\tswitch id.Type() {\n\tcase protocol.StreamTypeUni:\n\t\tif id.InitiatedBy() == m.perspective {\n\t\t\t// an outgoing unidirectional stream is a send stream, not a receive stream\n\t\t\treturn nil, fmt.Errorf(\"peer attempted to open receive stream %d\", id)\n\t\t}\n\t\tstr, err := m.incomingUniStreams.GetOrOpenStream(num)\n\t\treturn str, convertStreamError(err, protocol.StreamTypeUni, m.perspective)\n\tcase protocol.StreamTypeBidi:\n\t\tvar str receiveStreamI\n\t\tvar err error\n\t\tif id.InitiatedBy() == m.perspective {\n\t\t\tstr, err = m.outgoingBidiStreams.GetStream(num)\n\t\t} else {\n\t\t\tstr, err = m.incomingBidiStreams.GetOrOpenStream(num)\n\t\t}\n\t\treturn str, convertStreamError(err, protocol.StreamTypeBidi, id.InitiatedBy())\n\t}\n\tpanic(\"\")\n}\n\nfunc (m *streamsMap) GetOrOpenSendStream(id protocol.StreamID) (sendStreamI, error) {\n\tstr, err := m.getOrOpenSendStream(id)\n\tif err != nil {\n\t\treturn nil, &qerr.TransportError{\n\t\t\tErrorCode:    qerr.StreamStateError,\n\t\t\tErrorMessage: err.Error(),\n\t\t}\n\t}\n\treturn str, nil\n}\n\nfunc (m *streamsMap) getOrOpenSendStream(id protocol.StreamID) (sendStreamI, error) {\n\tnum := id.StreamNum()\n\tswitch id.Type() {\n\tcase protocol.StreamTypeUni:\n\t\tif id.InitiatedBy() == m.perspective {\n\t\t\tstr, err := m.outgoingUniStreams.GetStream(num)\n\t\t\treturn str, convertStreamError(err, protocol.StreamTypeUni, m.perspective)\n\t\t}\n\t\t// an incoming unidirectional stream is a receive stream, not a send stream\n\t\treturn nil, fmt.Errorf(\"peer attempted to open send stream %d\", id)\n\tcase protocol.StreamTypeBidi:\n\t\tvar str sendStreamI\n\t\tvar err error\n\t\tif id.InitiatedBy() == m.perspective {\n\t\t\tstr, err = m.outgoingBidiStreams.GetStream(num)\n\t\t} else {\n\t\t\tstr, err = m.incomingBidiStreams.GetOrOpenStream(num)\n\t\t}\n\t\treturn str, convertStreamError(err, protocol.StreamTypeBidi, id.InitiatedBy())\n\t}\n\tpanic(\"\")\n}\n\nfunc (m *streamsMap) HandleMaxStreamsFrame(f *wire.MaxStreamsFrame) {\n\tswitch f.Type {\n\tcase protocol.StreamTypeUni:\n\t\tm.outgoingUniStreams.SetMaxStream(f.MaxStreamNum)\n\tcase protocol.StreamTypeBidi:\n\t\tm.outgoingBidiStreams.SetMaxStream(f.MaxStreamNum)\n\t}\n}\n\nfunc (m *streamsMap) UpdateLimits(p *wire.TransportParameters) {\n\tm.outgoingBidiStreams.UpdateSendWindow(p.InitialMaxStreamDataBidiRemote)\n\tm.outgoingBidiStreams.SetMaxStream(p.MaxBidiStreamNum)\n\tm.outgoingUniStreams.UpdateSendWindow(p.InitialMaxStreamDataUni)\n\tm.outgoingUniStreams.SetMaxStream(p.MaxUniStreamNum)\n}\n\nfunc (m *streamsMap) CloseWithError(err error) {\n\tm.outgoingBidiStreams.CloseWithError(err)\n\tm.outgoingUniStreams.CloseWithError(err)\n\tm.incomingBidiStreams.CloseWithError(err)\n\tm.incomingUniStreams.CloseWithError(err)\n}\n\n// ResetFor0RTT resets is used when 0-RTT is rejected. In that case, the streams maps are\n// 1. closed with an Err0RTTRejected, making calls to Open{Uni}Stream{Sync} / Accept{Uni}Stream return that error.\n// 2. reset to their initial state, such that we can immediately process new incoming stream data.\n// Afterwards, calls to Open{Uni}Stream{Sync} / Accept{Uni}Stream will continue to return the error,\n// until UseResetMaps() has been called.\nfunc (m *streamsMap) ResetFor0RTT() {\n\tm.mutex.Lock()\n\tdefer m.mutex.Unlock()\n\tm.reset = true\n\tm.CloseWithError(Err0RTTRejected)\n\tm.initMaps()\n}\n\nfunc (m *streamsMap) UseResetMaps() {\n\tm.mutex.Lock()\n\tm.reset = false\n\tm.mutex.Unlock()\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/streams_map_incoming.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\ntype incomingStream interface {\n\tcloseForShutdown(error)\n}\n\n// When a stream is deleted before it was accepted, we can't delete it from the map immediately.\n// We need to wait until the application accepts it, and delete it then.\ntype incomingStreamEntry[T incomingStream] struct {\n\tstream       T\n\tshouldDelete bool\n}\n\ntype incomingStreamsMap[T incomingStream] struct {\n\tmutex         sync.RWMutex\n\tnewStreamChan chan struct{}\n\n\tstreamType protocol.StreamType\n\tstreams    map[protocol.StreamNum]incomingStreamEntry[T]\n\n\tnextStreamToAccept protocol.StreamNum // the next stream that will be returned by AcceptStream()\n\tnextStreamToOpen   protocol.StreamNum // the highest stream that the peer opened\n\tmaxStream          protocol.StreamNum // the highest stream that the peer is allowed to open\n\tmaxNumStreams      uint64             // maximum number of streams\n\n\tnewStream        func(protocol.StreamNum) T\n\tqueueMaxStreamID func(*wire.MaxStreamsFrame)\n\n\tcloseErr error\n}\n\nfunc newIncomingStreamsMap[T incomingStream](\n\tstreamType protocol.StreamType,\n\tnewStream func(protocol.StreamNum) T,\n\tmaxStreams uint64,\n\tqueueControlFrame func(wire.Frame),\n) *incomingStreamsMap[T] {\n\treturn &incomingStreamsMap[T]{\n\t\tnewStreamChan:      make(chan struct{}, 1),\n\t\tstreamType:         streamType,\n\t\tstreams:            make(map[protocol.StreamNum]incomingStreamEntry[T]),\n\t\tmaxStream:          protocol.StreamNum(maxStreams),\n\t\tmaxNumStreams:      maxStreams,\n\t\tnewStream:          newStream,\n\t\tnextStreamToOpen:   1,\n\t\tnextStreamToAccept: 1,\n\t\tqueueMaxStreamID:   func(f *wire.MaxStreamsFrame) { queueControlFrame(f) },\n\t}\n}\n\nfunc (m *incomingStreamsMap[T]) AcceptStream(ctx context.Context) (T, error) {\n\t// drain the newStreamChan, so we don't check the map twice if the stream doesn't exist\n\tselect {\n\tcase <-m.newStreamChan:\n\tdefault:\n\t}\n\n\tm.mutex.Lock()\n\n\tvar num protocol.StreamNum\n\tvar entry incomingStreamEntry[T]\n\tfor {\n\t\tnum = m.nextStreamToAccept\n\t\tif m.closeErr != nil {\n\t\t\tm.mutex.Unlock()\n\t\t\treturn *new(T), m.closeErr\n\t\t}\n\t\tvar ok bool\n\t\tentry, ok = m.streams[num]\n\t\tif ok {\n\t\t\tbreak\n\t\t}\n\t\tm.mutex.Unlock()\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn *new(T), ctx.Err()\n\t\tcase <-m.newStreamChan:\n\t\t}\n\t\tm.mutex.Lock()\n\t}\n\tm.nextStreamToAccept++\n\t// If this stream was completed before being accepted, we can delete it now.\n\tif entry.shouldDelete {\n\t\tif err := m.deleteStream(num); err != nil {\n\t\t\tm.mutex.Unlock()\n\t\t\treturn *new(T), err\n\t\t}\n\t}\n\tm.mutex.Unlock()\n\treturn entry.stream, nil\n}\n\nfunc (m *incomingStreamsMap[T]) GetOrOpenStream(num protocol.StreamNum) (T, error) {\n\tm.mutex.RLock()\n\tif num > m.maxStream {\n\t\tm.mutex.RUnlock()\n\t\treturn *new(T), streamError{\n\t\t\tmessage: \"peer tried to open stream %d (current limit: %d)\",\n\t\t\tnums:    []protocol.StreamNum{num, m.maxStream},\n\t\t}\n\t}\n\t// if the num is smaller than the highest we accepted\n\t// * this stream exists in the map, and we can return it, or\n\t// * this stream was already closed, then we can return the nil\n\tif num < m.nextStreamToOpen {\n\t\tvar s T\n\t\t// If the stream was already queued for deletion, and is just waiting to be accepted, don't return it.\n\t\tif entry, ok := m.streams[num]; ok && !entry.shouldDelete {\n\t\t\ts = entry.stream\n\t\t}\n\t\tm.mutex.RUnlock()\n\t\treturn s, nil\n\t}\n\tm.mutex.RUnlock()\n\n\tm.mutex.Lock()\n\t// no need to check the two error conditions from above again\n\t// * maxStream can only increase, so if the id was valid before, it definitely is valid now\n\t// * highestStream is only modified by this function\n\tfor newNum := m.nextStreamToOpen; newNum <= num; newNum++ {\n\t\tm.streams[newNum] = incomingStreamEntry[T]{stream: m.newStream(newNum)}\n\t\tselect {\n\t\tcase m.newStreamChan <- struct{}{}:\n\t\tdefault:\n\t\t}\n\t}\n\tm.nextStreamToOpen = num + 1\n\tentry := m.streams[num]\n\tm.mutex.Unlock()\n\treturn entry.stream, nil\n}\n\nfunc (m *incomingStreamsMap[T]) DeleteStream(num protocol.StreamNum) error {\n\tm.mutex.Lock()\n\tdefer m.mutex.Unlock()\n\n\treturn m.deleteStream(num)\n}\n\nfunc (m *incomingStreamsMap[T]) deleteStream(num protocol.StreamNum) error {\n\tif _, ok := m.streams[num]; !ok {\n\t\treturn streamError{\n\t\t\tmessage: \"tried to delete unknown incoming stream %d\",\n\t\t\tnums:    []protocol.StreamNum{num},\n\t\t}\n\t}\n\n\t// Don't delete this stream yet, if it was not yet accepted.\n\t// Just save it to streamsToDelete map, to make sure it is deleted as soon as it gets accepted.\n\tif num >= m.nextStreamToAccept {\n\t\tentry, ok := m.streams[num]\n\t\tif ok && entry.shouldDelete {\n\t\t\treturn streamError{\n\t\t\t\tmessage: \"tried to delete incoming stream %d multiple times\",\n\t\t\t\tnums:    []protocol.StreamNum{num},\n\t\t\t}\n\t\t}\n\t\tentry.shouldDelete = true\n\t\tm.streams[num] = entry // can't assign to struct in map, so we need to reassign\n\t\treturn nil\n\t}\n\n\tdelete(m.streams, num)\n\t// queue a MAX_STREAM_ID frame, giving the peer the option to open a new stream\n\tif m.maxNumStreams > uint64(len(m.streams)) {\n\t\tmaxStream := m.nextStreamToOpen + protocol.StreamNum(m.maxNumStreams-uint64(len(m.streams))) - 1\n\t\t// Never send a value larger than protocol.MaxStreamCount.\n\t\tif maxStream <= protocol.MaxStreamCount {\n\t\t\tm.maxStream = maxStream\n\t\t\tm.queueMaxStreamID(&wire.MaxStreamsFrame{\n\t\t\t\tType:         m.streamType,\n\t\t\t\tMaxStreamNum: m.maxStream,\n\t\t\t})\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (m *incomingStreamsMap[T]) CloseWithError(err error) {\n\tm.mutex.Lock()\n\tm.closeErr = err\n\tfor _, entry := range m.streams {\n\t\tentry.stream.closeForShutdown(err)\n\t}\n\tm.mutex.Unlock()\n\tclose(m.newStreamChan)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/streams_map_outgoing.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"slices\"\n\t\"sync\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n)\n\ntype outgoingStream interface {\n\tupdateSendWindow(protocol.ByteCount)\n\tcloseForShutdown(error)\n}\n\ntype outgoingStreamsMap[T outgoingStream] struct {\n\tmutex sync.RWMutex\n\n\tstreamType protocol.StreamType\n\tstreams    map[protocol.StreamNum]T\n\n\topenQueue []chan struct{}\n\n\tnextStream  protocol.StreamNum // stream ID of the stream returned by OpenStream(Sync)\n\tmaxStream   protocol.StreamNum // the maximum stream ID we're allowed to open\n\tblockedSent bool               // was a STREAMS_BLOCKED sent for the current maxStream\n\n\tnewStream            func(protocol.StreamNum) T\n\tqueueStreamIDBlocked func(*wire.StreamsBlockedFrame)\n\n\tcloseErr error\n}\n\nfunc newOutgoingStreamsMap[T outgoingStream](\n\tstreamType protocol.StreamType,\n\tnewStream func(protocol.StreamNum) T,\n\tqueueControlFrame func(wire.Frame),\n) *outgoingStreamsMap[T] {\n\treturn &outgoingStreamsMap[T]{\n\t\tstreamType:           streamType,\n\t\tstreams:              make(map[protocol.StreamNum]T),\n\t\tmaxStream:            protocol.InvalidStreamNum,\n\t\tnextStream:           1,\n\t\tnewStream:            newStream,\n\t\tqueueStreamIDBlocked: func(f *wire.StreamsBlockedFrame) { queueControlFrame(f) },\n\t}\n}\n\nfunc (m *outgoingStreamsMap[T]) OpenStream() (T, error) {\n\tm.mutex.Lock()\n\tdefer m.mutex.Unlock()\n\n\tif m.closeErr != nil {\n\t\treturn *new(T), m.closeErr\n\t}\n\n\t// if there are OpenStreamSync calls waiting, return an error here\n\tif len(m.openQueue) > 0 || m.nextStream > m.maxStream {\n\t\tm.maybeSendBlockedFrame()\n\t\treturn *new(T), &StreamLimitReachedError{}\n\t}\n\treturn m.openStream(), nil\n}\n\nfunc (m *outgoingStreamsMap[T]) OpenStreamSync(ctx context.Context) (T, error) {\n\tm.mutex.Lock()\n\tdefer m.mutex.Unlock()\n\n\tif m.closeErr != nil {\n\t\treturn *new(T), m.closeErr\n\t}\n\tif err := ctx.Err(); err != nil {\n\t\treturn *new(T), err\n\t}\n\tif len(m.openQueue) == 0 && m.nextStream <= m.maxStream {\n\t\treturn m.openStream(), nil\n\t}\n\n\twaitChan := make(chan struct{}, 1)\n\tm.openQueue = append(m.openQueue, waitChan)\n\tm.maybeSendBlockedFrame()\n\n\tfor {\n\t\tm.mutex.Unlock()\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\tm.mutex.Lock()\n\t\t\tm.openQueue = slices.DeleteFunc(m.openQueue, func(c chan struct{}) bool {\n\t\t\t\treturn c == waitChan\n\t\t\t})\n\t\t\t// If we just received a MAX_STREAMS frame, this might have been the next stream\n\t\t\t// that could be opened. Make sure we unblock the next OpenStreamSync call.\n\t\t\tm.maybeUnblockOpenSync()\n\t\t\treturn *new(T), ctx.Err()\n\t\tcase <-waitChan:\n\t\t}\n\n\t\tm.mutex.Lock()\n\t\tif m.closeErr != nil {\n\t\t\treturn *new(T), m.closeErr\n\t\t}\n\t\tif m.nextStream > m.maxStream {\n\t\t\t// no stream available. Continue waiting\n\t\t\tcontinue\n\t\t}\n\t\tstr := m.openStream()\n\t\tm.openQueue = m.openQueue[1:]\n\t\tm.maybeUnblockOpenSync()\n\t\treturn str, nil\n\t}\n}\n\nfunc (m *outgoingStreamsMap[T]) openStream() T {\n\ts := m.newStream(m.nextStream)\n\tm.streams[m.nextStream] = s\n\tm.nextStream++\n\treturn s\n}\n\n// maybeSendBlockedFrame queues a STREAMS_BLOCKED frame for the current stream offset,\n// if we haven't sent one for this offset yet\nfunc (m *outgoingStreamsMap[T]) maybeSendBlockedFrame() {\n\tif m.blockedSent {\n\t\treturn\n\t}\n\n\tvar streamNum protocol.StreamNum\n\tif m.maxStream != protocol.InvalidStreamNum {\n\t\tstreamNum = m.maxStream\n\t}\n\tm.queueStreamIDBlocked(&wire.StreamsBlockedFrame{\n\t\tType:        m.streamType,\n\t\tStreamLimit: streamNum,\n\t})\n\tm.blockedSent = true\n}\n\nfunc (m *outgoingStreamsMap[T]) GetStream(num protocol.StreamNum) (T, error) {\n\tm.mutex.RLock()\n\tif num >= m.nextStream {\n\t\tm.mutex.RUnlock()\n\t\treturn *new(T), streamError{\n\t\t\tmessage: \"peer attempted to open stream %d\",\n\t\t\tnums:    []protocol.StreamNum{num},\n\t\t}\n\t}\n\ts := m.streams[num]\n\tm.mutex.RUnlock()\n\treturn s, nil\n}\n\nfunc (m *outgoingStreamsMap[T]) DeleteStream(num protocol.StreamNum) error {\n\tm.mutex.Lock()\n\tdefer m.mutex.Unlock()\n\n\tif _, ok := m.streams[num]; !ok {\n\t\treturn streamError{\n\t\t\tmessage: \"tried to delete unknown outgoing stream %d\",\n\t\t\tnums:    []protocol.StreamNum{num},\n\t\t}\n\t}\n\tdelete(m.streams, num)\n\treturn nil\n}\n\nfunc (m *outgoingStreamsMap[T]) SetMaxStream(num protocol.StreamNum) {\n\tm.mutex.Lock()\n\tdefer m.mutex.Unlock()\n\n\tif num <= m.maxStream {\n\t\treturn\n\t}\n\tm.maxStream = num\n\tm.blockedSent = false\n\tif m.maxStream < m.nextStream-1+protocol.StreamNum(len(m.openQueue)) {\n\t\tm.maybeSendBlockedFrame()\n\t}\n\tm.maybeUnblockOpenSync()\n}\n\n// UpdateSendWindow is called when the peer's transport parameters are received.\n// Only in the case of a 0-RTT handshake will we have open streams at this point.\n// We might need to update the send window, in case the server increased it.\nfunc (m *outgoingStreamsMap[T]) UpdateSendWindow(limit protocol.ByteCount) {\n\tm.mutex.Lock()\n\tfor _, str := range m.streams {\n\t\tstr.updateSendWindow(limit)\n\t}\n\tm.mutex.Unlock()\n}\n\n// unblockOpenSync unblocks the next OpenStreamSync go-routine to open a new stream\nfunc (m *outgoingStreamsMap[T]) maybeUnblockOpenSync() {\n\tif len(m.openQueue) == 0 {\n\t\treturn\n\t}\n\tif m.nextStream > m.maxStream {\n\t\treturn\n\t}\n\t// unblockOpenSync is called both from OpenStreamSync and from SetMaxStream.\n\t// It's sufficient to only unblock OpenStreamSync once.\n\tselect {\n\tcase m.openQueue[0] <- struct{}{}:\n\tdefault:\n\t}\n}\n\nfunc (m *outgoingStreamsMap[T]) CloseWithError(err error) {\n\tm.mutex.Lock()\n\tdefer m.mutex.Unlock()\n\n\tm.closeErr = err\n\tfor _, str := range m.streams {\n\t\tstr.closeForShutdown(err)\n\t}\n\tfor _, c := range m.openQueue {\n\t\tif c != nil {\n\t\t\tclose(c)\n\t\t}\n\t}\n\tm.openQueue = nil\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/sys_conn.go",
    "content": "package quic\n\nimport (\n\t\"log\"\n\t\"net\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n)\n\n// OOBCapablePacketConn is a connection that allows the reading of ECN bits from the IP header.\n// If the PacketConn passed to the [Transport] satisfies this interface, quic-go will use it.\n// In this case, ReadMsgUDP() will be used instead of ReadFrom() to read packets.\ntype OOBCapablePacketConn interface {\n\tnet.PacketConn\n\tSyscallConn() (syscall.RawConn, error)\n\tSetReadBuffer(int) error\n\tReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error)\n\tWriteMsgUDP(b, oob []byte, addr *net.UDPAddr) (n, oobn int, err error)\n}\n\nvar _ OOBCapablePacketConn = &net.UDPConn{}\n\nfunc wrapConn(pc net.PacketConn) (rawConn, error) {\n\tif err := setReceiveBuffer(pc); err != nil {\n\t\tif !strings.Contains(err.Error(), \"use of closed network connection\") {\n\t\t\tsetBufferWarningOnce.Do(func() {\n\t\t\t\tif disable, _ := strconv.ParseBool(os.Getenv(\"QUIC_GO_DISABLE_RECEIVE_BUFFER_WARNING\")); disable {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tlog.Printf(\"%s. See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details.\", err)\n\t\t\t})\n\t\t}\n\t}\n\tif err := setSendBuffer(pc); err != nil {\n\t\tif !strings.Contains(err.Error(), \"use of closed network connection\") {\n\t\t\tsetBufferWarningOnce.Do(func() {\n\t\t\t\tif disable, _ := strconv.ParseBool(os.Getenv(\"QUIC_GO_DISABLE_RECEIVE_BUFFER_WARNING\")); disable {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tlog.Printf(\"%s. See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details.\", err)\n\t\t\t})\n\t\t}\n\t}\n\n\tconn, ok := pc.(interface {\n\t\tSyscallConn() (syscall.RawConn, error)\n\t})\n\tvar supportsDF bool\n\tif ok {\n\t\trawConn, err := conn.SyscallConn()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\t// only set DF on UDP sockets\n\t\tif _, ok := pc.LocalAddr().(*net.UDPAddr); ok {\n\t\t\tvar err error\n\t\t\tsupportsDF, err = setDF(rawConn)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\tc, ok := pc.(OOBCapablePacketConn)\n\tif !ok {\n\t\tutils.DefaultLogger.Infof(\"PacketConn is not a net.UDPConn. Disabling optimizations possible on UDP connections.\")\n\t\treturn &basicConn{PacketConn: pc, supportsDF: supportsDF}, nil\n\t}\n\treturn newConn(c, supportsDF)\n}\n\n// The basicConn is the most trivial implementation of a rawConn.\n// It reads a single packet from the underlying net.PacketConn.\n// It is used when\n// * the net.PacketConn is not a OOBCapablePacketConn, and\n// * when the OS doesn't support OOB.\ntype basicConn struct {\n\tnet.PacketConn\n\tsupportsDF bool\n}\n\nvar _ rawConn = &basicConn{}\n\nfunc (c *basicConn) ReadPacket() (receivedPacket, error) {\n\tbuffer := getPacketBuffer()\n\t// The packet size should not exceed protocol.MaxPacketBufferSize bytes\n\t// If it does, we only read a truncated packet, which will then end up undecryptable\n\tbuffer.Data = buffer.Data[:protocol.MaxPacketBufferSize]\n\tn, addr, err := c.ReadFrom(buffer.Data)\n\tif err != nil {\n\t\treturn receivedPacket{}, err\n\t}\n\treturn receivedPacket{\n\t\tremoteAddr: addr,\n\t\trcvTime:    time.Now(),\n\t\tdata:       buffer.Data[:n],\n\t\tbuffer:     buffer,\n\t}, nil\n}\n\nfunc (c *basicConn) WritePacket(b []byte, addr net.Addr, _ []byte, gsoSize uint16, ecn protocol.ECN) (n int, err error) {\n\tif gsoSize != 0 {\n\t\tpanic(\"cannot use GSO with a basicConn\")\n\t}\n\tif ecn != protocol.ECNUnsupported {\n\t\tpanic(\"cannot use ECN with a basicConn\")\n\t}\n\treturn c.WriteTo(b, addr)\n}\n\nfunc (c *basicConn) capabilities() connCapabilities { return connCapabilities{DF: c.supportsDF} }\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/sys_conn_buffers.go",
    "content": "package quic\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"syscall\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n)\n\n//go:generate sh -c \"echo '// Code generated by go generate. DO NOT EDIT.\\n// Source: sys_conn_buffers.go\\n' > sys_conn_buffers_write.go && sed -e 's/SetReadBuffer/SetWriteBuffer/g' -e 's/setReceiveBuffer/setSendBuffer/g' -e 's/inspectReadBuffer/inspectWriteBuffer/g' -e 's/protocol\\\\.DesiredReceiveBufferSize/protocol\\\\.DesiredSendBufferSize/g' -e 's/forceSetReceiveBuffer/forceSetSendBuffer/g' -e 's/receive buffer/send buffer/g' sys_conn_buffers.go | sed '/^\\\\/\\\\/go:generate/d' >> sys_conn_buffers_write.go\"\nfunc setReceiveBuffer(c net.PacketConn) error {\n\tconn, ok := c.(interface{ SetReadBuffer(int) error })\n\tif !ok {\n\t\treturn errors.New(\"connection doesn't allow setting of receive buffer size. Not a *net.UDPConn?\")\n\t}\n\n\tvar syscallConn syscall.RawConn\n\tif sc, ok := c.(interface {\n\t\tSyscallConn() (syscall.RawConn, error)\n\t}); ok {\n\t\tvar err error\n\t\tsyscallConn, err = sc.SyscallConn()\n\t\tif err != nil {\n\t\t\tsyscallConn = nil\n\t\t}\n\t}\n\t// The connection has a SetReadBuffer method, but we couldn't obtain a syscall.RawConn.\n\t// This shouldn't happen for a net.UDPConn, but is possible if the connection just implements the\n\t// net.PacketConn interface and the SetReadBuffer method.\n\t// We have no way of checking if increasing the buffer size actually worked.\n\tif syscallConn == nil {\n\t\treturn conn.SetReadBuffer(protocol.DesiredReceiveBufferSize)\n\t}\n\n\tsize, err := inspectReadBuffer(syscallConn)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to determine receive buffer size: %w\", err)\n\t}\n\tif size >= protocol.DesiredReceiveBufferSize {\n\t\tutils.DefaultLogger.Debugf(\"Conn has receive buffer of %d kiB (wanted: at least %d kiB)\", size/1024, protocol.DesiredReceiveBufferSize/1024)\n\t\treturn nil\n\t}\n\t// Ignore the error. We check if we succeeded by querying the buffer size afterward.\n\t_ = conn.SetReadBuffer(protocol.DesiredReceiveBufferSize)\n\tnewSize, err := inspectReadBuffer(syscallConn)\n\tif newSize < protocol.DesiredReceiveBufferSize {\n\t\t// Try again with RCVBUFFORCE on Linux\n\t\t_ = forceSetReceiveBuffer(syscallConn, protocol.DesiredReceiveBufferSize)\n\t\tnewSize, err = inspectReadBuffer(syscallConn)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to determine receive buffer size: %w\", err)\n\t\t}\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to determine receive buffer size: %w\", err)\n\t}\n\tif newSize == size {\n\t\treturn fmt.Errorf(\"failed to increase receive buffer size (wanted: %d kiB, got %d kiB)\", protocol.DesiredReceiveBufferSize/1024, newSize/1024)\n\t}\n\tif newSize < protocol.DesiredReceiveBufferSize {\n\t\treturn fmt.Errorf(\"failed to sufficiently increase receive buffer size (was: %d kiB, wanted: %d kiB, got: %d kiB)\", size/1024, protocol.DesiredReceiveBufferSize/1024, newSize/1024)\n\t}\n\tutils.DefaultLogger.Debugf(\"Increased receive buffer size to %d kiB\", newSize/1024)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/sys_conn_buffers_write.go",
    "content": "// Code generated by go generate. DO NOT EDIT.\n// Source: sys_conn_buffers.go\n\npackage quic\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"syscall\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n)\n\nfunc setSendBuffer(c net.PacketConn) error {\n\tconn, ok := c.(interface{ SetWriteBuffer(int) error })\n\tif !ok {\n\t\treturn errors.New(\"connection doesn't allow setting of send buffer size. Not a *net.UDPConn?\")\n\t}\n\n\tvar syscallConn syscall.RawConn\n\tif sc, ok := c.(interface {\n\t\tSyscallConn() (syscall.RawConn, error)\n\t}); ok {\n\t\tvar err error\n\t\tsyscallConn, err = sc.SyscallConn()\n\t\tif err != nil {\n\t\t\tsyscallConn = nil\n\t\t}\n\t}\n\t// The connection has a SetWriteBuffer method, but we couldn't obtain a syscall.RawConn.\n\t// This shouldn't happen for a net.UDPConn, but is possible if the connection just implements the\n\t// net.PacketConn interface and the SetWriteBuffer method.\n\t// We have no way of checking if increasing the buffer size actually worked.\n\tif syscallConn == nil {\n\t\treturn conn.SetWriteBuffer(protocol.DesiredSendBufferSize)\n\t}\n\n\tsize, err := inspectWriteBuffer(syscallConn)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to determine send buffer size: %w\", err)\n\t}\n\tif size >= protocol.DesiredSendBufferSize {\n\t\tutils.DefaultLogger.Debugf(\"Conn has send buffer of %d kiB (wanted: at least %d kiB)\", size/1024, protocol.DesiredSendBufferSize/1024)\n\t\treturn nil\n\t}\n\t// Ignore the error. We check if we succeeded by querying the buffer size afterward.\n\t_ = conn.SetWriteBuffer(protocol.DesiredSendBufferSize)\n\tnewSize, err := inspectWriteBuffer(syscallConn)\n\tif newSize < protocol.DesiredSendBufferSize {\n\t\t// Try again with RCVBUFFORCE on Linux\n\t\t_ = forceSetSendBuffer(syscallConn, protocol.DesiredSendBufferSize)\n\t\tnewSize, err = inspectWriteBuffer(syscallConn)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to determine send buffer size: %w\", err)\n\t\t}\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to determine send buffer size: %w\", err)\n\t}\n\tif newSize == size {\n\t\treturn fmt.Errorf(\"failed to increase send buffer size (wanted: %d kiB, got %d kiB)\", protocol.DesiredSendBufferSize/1024, newSize/1024)\n\t}\n\tif newSize < protocol.DesiredSendBufferSize {\n\t\treturn fmt.Errorf(\"failed to sufficiently increase send buffer size (was: %d kiB, wanted: %d kiB, got: %d kiB)\", size/1024, protocol.DesiredSendBufferSize/1024, newSize/1024)\n\t}\n\tutils.DefaultLogger.Debugf(\"Increased send buffer size to %d kiB\", newSize/1024)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/sys_conn_df.go",
    "content": "//go:build !linux && !windows && !darwin\n\npackage quic\n\nimport (\n\t\"syscall\"\n)\n\nfunc setDF(syscall.RawConn) (bool, error) {\n\t// no-op on unsupported platforms\n\treturn false, nil\n}\n\nfunc isSendMsgSizeErr(err error) bool {\n\t// to be implemented for more specific platforms\n\treturn false\n}\n\nfunc isRecvMsgSizeErr(err error) bool {\n\t// to be implemented for more specific platforms\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/sys_conn_df_darwin.go",
    "content": "//go:build darwin\n\npackage quic\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\n// for macOS versions, see https://en.wikipedia.org/wiki/Darwin_(operating_system)#Darwin_20_onwards\nconst (\n\tmacOSVersion11 = 20\n\tmacOSVersion15 = 24\n)\n\nfunc setDF(rawConn syscall.RawConn) (bool, error) {\n\t// Setting DF bit is only supported from macOS 11.\n\t// https://github.com/chromium/chromium/blob/117.0.5881.2/net/socket/udp_socket_posix.cc#L555\n\tversion, err := getMacOSVersion()\n\tif err != nil || version < macOSVersion11 {\n\t\treturn false, err\n\t}\n\n\tvar controlErr error\n\tvar disableDF bool\n\tif err := rawConn.Control(func(fd uintptr) {\n\t\taddr, err := unix.Getsockname(int(fd))\n\t\tif err != nil {\n\t\t\tcontrolErr = fmt.Errorf(\"getsockname: %w\", err)\n\t\t\treturn\n\t\t}\n\n\t\t// Dual-stack sockets are effectively IPv6 sockets (with IPV6_ONLY set to 0).\n\t\t// On macOS, the DF bit on dual-stack sockets is controlled by the IPV6_DONTFRAG option.\n\t\t// See https://datatracker.ietf.org/doc/draft-seemann-tsvwg-udp-fragmentation/ for details.\n\t\tswitch addr.(type) {\n\t\tcase *unix.SockaddrInet4:\n\t\t\tcontrolErr = unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_DONTFRAG, 1)\n\t\tcase *unix.SockaddrInet6:\n\t\t\tcontrolErr = unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_DONTFRAG, 1)\n\n\t\t\t// Setting the DF bit on dual-stack sockets works since macOS Sequoia.\n\t\t\t// Disable DF on dual-stack sockets before Sequoia.\n\t\t\tif version < macOSVersion15 {\n\t\t\t\t// check if this is a dual-stack socket by reading the IPV6_V6ONLY flag\n\t\t\t\tv6only, err := unix.GetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_V6ONLY)\n\t\t\t\tif err != nil {\n\t\t\t\t\tcontrolErr = fmt.Errorf(\"getting IPV6_V6ONLY: %w\", err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tdisableDF = v6only == 0\n\t\t\t}\n\t\tdefault:\n\t\t\tcontrolErr = fmt.Errorf(\"unknown address type: %T\", addr)\n\t\t}\n\t}); err != nil {\n\t\treturn false, err\n\t}\n\tif controlErr != nil {\n\t\treturn false, controlErr\n\t}\n\treturn !disableDF, nil\n}\n\nfunc isSendMsgSizeErr(err error) bool {\n\treturn errors.Is(err, unix.EMSGSIZE)\n}\n\nfunc isRecvMsgSizeErr(error) bool { return false }\n\nfunc getMacOSVersion() (int, error) {\n\tuname := &unix.Utsname{}\n\tif err := unix.Uname(uname); err != nil {\n\t\treturn 0, err\n\t}\n\n\trelease := string(uname.Release[:])\n\tidx := strings.Index(release, \".\")\n\tif idx == -1 {\n\t\treturn 0, nil\n\t}\n\tversion, err := strconv.Atoi(release[:idx])\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn version, nil\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/sys_conn_df_linux.go",
    "content": "//go:build linux\n\npackage quic\n\nimport (\n\t\"errors\"\n\t\"syscall\"\n\n\t\"golang.org/x/sys/unix\"\n\n\t\"github.com/quic-go/quic-go/internal/utils\"\n)\n\nfunc setDF(rawConn syscall.RawConn) (bool, error) {\n\t// Enabling IP_MTU_DISCOVER will force the kernel to return \"sendto: message too long\"\n\t// and the datagram will not be fragmented\n\tvar errDFIPv4, errDFIPv6 error\n\tif err := rawConn.Control(func(fd uintptr) {\n\t\terrDFIPv4 = unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_MTU_DISCOVER, unix.IP_PMTUDISC_PROBE)\n\t\terrDFIPv6 = unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_MTU_DISCOVER, unix.IPV6_PMTUDISC_PROBE)\n\t}); err != nil {\n\t\treturn false, err\n\t}\n\tswitch {\n\tcase errDFIPv4 == nil && errDFIPv6 == nil:\n\t\tutils.DefaultLogger.Debugf(\"Setting DF for IPv4 and IPv6.\")\n\tcase errDFIPv4 == nil && errDFIPv6 != nil:\n\t\tutils.DefaultLogger.Debugf(\"Setting DF for IPv4.\")\n\tcase errDFIPv4 != nil && errDFIPv6 == nil:\n\t\tutils.DefaultLogger.Debugf(\"Setting DF for IPv6.\")\n\tcase errDFIPv4 != nil && errDFIPv6 != nil:\n\t\treturn false, errors.New(\"setting DF failed for both IPv4 and IPv6\")\n\t}\n\treturn true, nil\n}\n\nfunc isSendMsgSizeErr(err error) bool {\n\t// https://man7.org/linux/man-pages/man7/udp.7.html\n\treturn errors.Is(err, unix.EMSGSIZE)\n}\n\nfunc isRecvMsgSizeErr(error) bool { return false }\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/sys_conn_df_windows.go",
    "content": "//go:build windows\n\npackage quic\n\nimport (\n\t\"errors\"\n\t\"syscall\"\n\n\t\"golang.org/x/sys/windows\"\n\n\t\"github.com/quic-go/quic-go/internal/utils\"\n)\n\nconst (\n\t// https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Networking/WinSock/constant.IP_DONTFRAGMENT.html\n\t//nolint:stylecheck\n\tIP_DONTFRAGMENT = 14\n\t// https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Networking/WinSock/constant.IPV6_DONTFRAG.html\n\t//nolint:stylecheck\n\tIPV6_DONTFRAG = 14\n)\n\nfunc setDF(rawConn syscall.RawConn) (bool, error) {\n\tvar errDFIPv4, errDFIPv6 error\n\tif err := rawConn.Control(func(fd uintptr) {\n\t\terrDFIPv4 = windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IP, IP_DONTFRAGMENT, 1)\n\t\terrDFIPv6 = windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IPV6, IPV6_DONTFRAG, 1)\n\t}); err != nil {\n\t\treturn false, err\n\t}\n\tswitch {\n\tcase errDFIPv4 == nil && errDFIPv6 == nil:\n\t\tutils.DefaultLogger.Debugf(\"Setting DF for IPv4 and IPv6.\")\n\tcase errDFIPv4 == nil && errDFIPv6 != nil:\n\t\tutils.DefaultLogger.Debugf(\"Setting DF for IPv4.\")\n\tcase errDFIPv4 != nil && errDFIPv6 == nil:\n\t\tutils.DefaultLogger.Debugf(\"Setting DF for IPv6.\")\n\tcase errDFIPv4 != nil && errDFIPv6 != nil:\n\t\treturn false, errors.New(\"setting DF failed for both IPv4 and IPv6\")\n\t}\n\treturn true, nil\n}\n\nfunc isSendMsgSizeErr(err error) bool {\n\t// https://docs.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2\n\treturn errors.Is(err, windows.WSAEMSGSIZE)\n}\n\nfunc isRecvMsgSizeErr(err error) bool {\n\t// https://docs.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2\n\treturn errors.Is(err, windows.WSAEMSGSIZE)\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/sys_conn_helper_darwin.go",
    "content": "//go:build darwin\n\npackage quic\n\nimport (\n\t\"encoding/binary\"\n\t\"net/netip\"\n\t\"syscall\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nconst (\n\tmsgTypeIPTOS = unix.IP_RECVTOS\n\tipv4PKTINFO  = unix.IP_RECVPKTINFO\n)\n\nconst ecnIPv4DataLen = 4\n\n// ReadBatch only returns a single packet on OSX,\n// see https://godoc.org/golang.org/x/net/ipv4#PacketConn.ReadBatch.\nconst batchSize = 1\n\nfunc parseIPv4PktInfo(body []byte) (ip netip.Addr, ifIndex uint32, ok bool) {\n\t// struct in_pktinfo {\n\t// \tunsigned int   ipi_ifindex;  /* Interface index */\n\t// \tstruct in_addr ipi_spec_dst; /* Local address */\n\t// \tstruct in_addr ipi_addr;     /* Header Destination address */\n\t// };\n\tif len(body) != 12 {\n\t\treturn netip.Addr{}, 0, false\n\t}\n\treturn netip.AddrFrom4(*(*[4]byte)(body[8:12])), binary.LittleEndian.Uint32(body), true\n}\n\nfunc isGSOEnabled(syscall.RawConn) bool { return false }\n\nfunc isECNEnabled() bool { return !isECNDisabledUsingEnv() }\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/sys_conn_helper_freebsd.go",
    "content": "//go:build freebsd\n\npackage quic\n\nimport (\n\t\"net/netip\"\n\t\"syscall\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nconst (\n\tmsgTypeIPTOS = unix.IP_RECVTOS\n\tipv4PKTINFO  = 0x7\n)\n\nconst ecnIPv4DataLen = 1\n\nconst batchSize = 8\n\nfunc parseIPv4PktInfo(body []byte) (ip netip.Addr, _ uint32, ok bool) {\n\t// struct in_pktinfo {\n\t// \tstruct in_addr ipi_addr;     /* Header Destination address */\n\t// };\n\tif len(body) != 4 {\n\t\treturn netip.Addr{}, 0, false\n\t}\n\treturn netip.AddrFrom4(*(*[4]byte)(body)), 0, true\n}\n\nfunc isGSOEnabled(syscall.RawConn) bool { return false }\n\nfunc isECNEnabled() bool { return !isECNDisabledUsingEnv() }\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/sys_conn_helper_linux.go",
    "content": "//go:build linux\n\npackage quic\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"net/netip\"\n\t\"os\"\n\t\"strconv\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nconst (\n\tmsgTypeIPTOS = unix.IP_TOS\n\tipv4PKTINFO  = unix.IP_PKTINFO\n)\n\nconst ecnIPv4DataLen = 1\n\nconst batchSize = 8 // needs to smaller than MaxUint8 (otherwise the type of oobConn.readPos has to be changed)\n\nvar kernelVersionMajor int\n\nfunc init() {\n\tkernelVersionMajor, _ = kernelVersion()\n}\n\nfunc forceSetReceiveBuffer(c syscall.RawConn, bytes int) error {\n\tvar serr error\n\tif err := c.Control(func(fd uintptr) {\n\t\tserr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_RCVBUFFORCE, bytes)\n\t}); err != nil {\n\t\treturn err\n\t}\n\treturn serr\n}\n\nfunc forceSetSendBuffer(c syscall.RawConn, bytes int) error {\n\tvar serr error\n\tif err := c.Control(func(fd uintptr) {\n\t\tserr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_SNDBUFFORCE, bytes)\n\t}); err != nil {\n\t\treturn err\n\t}\n\treturn serr\n}\n\nfunc parseIPv4PktInfo(body []byte) (ip netip.Addr, ifIndex uint32, ok bool) {\n\t// struct in_pktinfo {\n\t// \tunsigned int   ipi_ifindex;  /* Interface index */\n\t// \tstruct in_addr ipi_spec_dst; /* Local address */\n\t// \tstruct in_addr ipi_addr;     /* Header Destination address */\n\t// };\n\tif len(body) != 12 {\n\t\treturn netip.Addr{}, 0, false\n\t}\n\treturn netip.AddrFrom4(*(*[4]byte)(body[8:12])), binary.LittleEndian.Uint32(body), true\n}\n\n// isGSOEnabled tests if the kernel supports GSO.\n// Sending with GSO might still fail later on, if the interface doesn't support it (see isGSOError).\nfunc isGSOEnabled(conn syscall.RawConn) bool {\n\tif kernelVersionMajor < 5 {\n\t\treturn false\n\t}\n\tdisabled, err := strconv.ParseBool(os.Getenv(\"QUIC_GO_DISABLE_GSO\"))\n\tif err == nil && disabled {\n\t\treturn false\n\t}\n\tvar serr error\n\tif err := conn.Control(func(fd uintptr) {\n\t\t_, serr = unix.GetsockoptInt(int(fd), unix.IPPROTO_UDP, unix.UDP_SEGMENT)\n\t}); err != nil {\n\t\treturn false\n\t}\n\treturn serr == nil\n}\n\nfunc appendUDPSegmentSizeMsg(b []byte, size uint16) []byte {\n\tstartLen := len(b)\n\tconst dataLen = 2 // payload is a uint16\n\tb = append(b, make([]byte, unix.CmsgSpace(dataLen))...)\n\th := (*unix.Cmsghdr)(unsafe.Pointer(&b[startLen]))\n\th.Level = syscall.IPPROTO_UDP\n\th.Type = unix.UDP_SEGMENT\n\th.SetLen(unix.CmsgLen(dataLen))\n\n\t// UnixRights uses the private `data` method, but I *think* this achieves the same goal.\n\toffset := startLen + unix.CmsgSpace(0)\n\t*(*uint16)(unsafe.Pointer(&b[offset])) = size\n\treturn b\n}\n\nfunc isGSOError(err error) bool {\n\tvar serr *os.SyscallError\n\tif errors.As(err, &serr) {\n\t\t// EIO is returned by udp_send_skb() if the device driver does not have tx checksums enabled,\n\t\t// which is a hard requirement of UDP_SEGMENT. See:\n\t\t// https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/man7/udp.7?id=806eabd74910447f21005160e90957bde4db0183#n228\n\t\t// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/ipv4/udp.c?h=v6.2&id=c9c3395d5e3dcc6daee66c6908354d47bf98cb0c#n942\n\t\treturn serr.Err == unix.EIO\n\t}\n\treturn false\n}\n\n// The first sendmsg call on a new UDP socket sometimes errors on Linux.\n// It's not clear why this happens.\n// See https://github.com/golang/go/issues/63322.\nfunc isPermissionError(err error) bool {\n\tvar serr *os.SyscallError\n\tif errors.As(err, &serr) {\n\t\treturn serr.Syscall == \"sendmsg\" && serr.Err == unix.EPERM\n\t}\n\treturn false\n}\n\nfunc isECNEnabled() bool {\n\treturn kernelVersionMajor >= 5 && !isECNDisabledUsingEnv()\n}\n\n// kernelVersion returns major and minor kernel version numbers, parsed from\n// the syscall.Uname's Release field, or 0, 0 if the version can't be obtained\n// or parsed.\n//\n// copied from the standard library's internal/syscall/unix/kernel_version_linux.go\nfunc kernelVersion() (major, minor int) {\n\tvar uname syscall.Utsname\n\tif err := syscall.Uname(&uname); err != nil {\n\t\treturn\n\t}\n\n\tvar (\n\t\tvalues    [2]int\n\t\tvalue, vi int\n\t)\n\tfor _, c := range uname.Release {\n\t\tif '0' <= c && c <= '9' {\n\t\t\tvalue = (value * 10) + int(c-'0')\n\t\t} else {\n\t\t\t// Note that we're assuming N.N.N here.\n\t\t\t// If we see anything else, we are likely to mis-parse it.\n\t\t\tvalues[vi] = value\n\t\t\tvi++\n\t\t\tif vi >= len(values) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tvalue = 0\n\t\t}\n\t}\n\n\treturn values[0], values[1]\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/sys_conn_helper_nonlinux.go",
    "content": "//go:build !linux\n\npackage quic\n\nfunc forceSetReceiveBuffer(c any, bytes int) error { return nil }\nfunc forceSetSendBuffer(c any, bytes int) error    { return nil }\n\nfunc appendUDPSegmentSizeMsg([]byte, uint16) []byte { return nil }\nfunc isGSOError(error) bool                         { return false }\nfunc isPermissionError(err error) bool              { return false }\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/sys_conn_no_oob.go",
    "content": "//go:build !darwin && !linux && !freebsd && !windows\n\npackage quic\n\nimport (\n\t\"net\"\n\t\"net/netip\"\n)\n\nfunc newConn(c net.PacketConn, supportsDF bool) (*basicConn, error) {\n\treturn &basicConn{PacketConn: c, supportsDF: supportsDF}, nil\n}\n\nfunc inspectReadBuffer(any) (int, error)  { return 0, nil }\nfunc inspectWriteBuffer(any) (int, error) { return 0, nil }\n\ntype packetInfo struct {\n\taddr netip.Addr\n}\n\nfunc (i *packetInfo) OOB() []byte { return nil }\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/sys_conn_oob.go",
    "content": "//go:build darwin || linux || freebsd\n\npackage quic\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"log\"\n\t\"net\"\n\t\"net/netip\"\n\t\"os\"\n\t\"strconv\"\n\t\"sync\"\n\t\"syscall\"\n\t\"time\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/ipv4\"\n\t\"golang.org/x/net/ipv6\"\n\t\"golang.org/x/sys/unix\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n)\n\nconst (\n\tecnMask       = 0x3\n\toobBufferSize = 128\n)\n\n// Contrary to what the naming suggests, the ipv{4,6}.Message is not dependent on the IP version.\n// They're both just aliases for x/net/internal/socket.Message.\n// This means we can use this struct to read from a socket that receives both IPv4 and IPv6 messages.\nvar _ ipv4.Message = ipv6.Message{}\n\ntype batchConn interface {\n\tReadBatch(ms []ipv4.Message, flags int) (int, error)\n}\n\nfunc inspectReadBuffer(c syscall.RawConn) (int, error) {\n\tvar size int\n\tvar serr error\n\tif err := c.Control(func(fd uintptr) {\n\t\tsize, serr = unix.GetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_RCVBUF)\n\t}); err != nil {\n\t\treturn 0, err\n\t}\n\treturn size, serr\n}\n\nfunc inspectWriteBuffer(c syscall.RawConn) (int, error) {\n\tvar size int\n\tvar serr error\n\tif err := c.Control(func(fd uintptr) {\n\t\tsize, serr = unix.GetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_SNDBUF)\n\t}); err != nil {\n\t\treturn 0, err\n\t}\n\treturn size, serr\n}\n\nfunc isECNDisabledUsingEnv() bool {\n\tdisabled, err := strconv.ParseBool(os.Getenv(\"QUIC_GO_DISABLE_ECN\"))\n\treturn err == nil && disabled\n}\n\ntype oobConn struct {\n\tOOBCapablePacketConn\n\tbatchConn batchConn\n\n\treadPos uint8\n\t// Packets received from the kernel, but not yet returned by ReadPacket().\n\tmessages []ipv4.Message\n\tbuffers  [batchSize]*packetBuffer\n\n\tcap connCapabilities\n}\n\nvar _ rawConn = &oobConn{}\n\nfunc newConn(c OOBCapablePacketConn, supportsDF bool) (*oobConn, error) {\n\trawConn, err := c.SyscallConn()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar needsPacketInfo bool\n\tif udpAddr, ok := c.LocalAddr().(*net.UDPAddr); ok && udpAddr.IP.IsUnspecified() {\n\t\tneedsPacketInfo = true\n\t}\n\t// We don't know if this a IPv4-only, IPv6-only or a IPv4-and-IPv6 connection.\n\t// Try enabling receiving of ECN and packet info for both IP versions.\n\t// We expect at least one of those syscalls to succeed.\n\tvar errECNIPv4, errECNIPv6, errPIIPv4, errPIIPv6 error\n\tif err := rawConn.Control(func(fd uintptr) {\n\t\terrECNIPv4 = unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, unix.IP_RECVTOS, 1)\n\t\terrECNIPv6 = unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_RECVTCLASS, 1)\n\n\t\tif needsPacketInfo {\n\t\t\terrPIIPv4 = unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, ipv4PKTINFO, 1)\n\t\t\terrPIIPv6 = unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, unix.IPV6_RECVPKTINFO, 1)\n\t\t}\n\t}); err != nil {\n\t\treturn nil, err\n\t}\n\tswitch {\n\tcase errECNIPv4 == nil && errECNIPv6 == nil:\n\t\tutils.DefaultLogger.Debugf(\"Activating reading of ECN bits for IPv4 and IPv6.\")\n\tcase errECNIPv4 == nil && errECNIPv6 != nil:\n\t\tutils.DefaultLogger.Debugf(\"Activating reading of ECN bits for IPv4.\")\n\tcase errECNIPv4 != nil && errECNIPv6 == nil:\n\t\tutils.DefaultLogger.Debugf(\"Activating reading of ECN bits for IPv6.\")\n\tcase errECNIPv4 != nil && errECNIPv6 != nil:\n\t\treturn nil, errors.New(\"activating ECN failed for both IPv4 and IPv6\")\n\t}\n\tif needsPacketInfo {\n\t\tswitch {\n\t\tcase errPIIPv4 == nil && errPIIPv6 == nil:\n\t\t\tutils.DefaultLogger.Debugf(\"Activating reading of packet info for IPv4 and IPv6.\")\n\t\tcase errPIIPv4 == nil && errPIIPv6 != nil:\n\t\t\tutils.DefaultLogger.Debugf(\"Activating reading of packet info bits for IPv4.\")\n\t\tcase errPIIPv4 != nil && errPIIPv6 == nil:\n\t\t\tutils.DefaultLogger.Debugf(\"Activating reading of packet info bits for IPv6.\")\n\t\tcase errPIIPv4 != nil && errPIIPv6 != nil:\n\t\t\treturn nil, errors.New(\"activating packet info failed for both IPv4 and IPv6\")\n\t\t}\n\t}\n\n\t// Allows callers to pass in a connection that already satisfies batchConn interface\n\t// to make use of the optimisation. Otherwise, ipv4.NewPacketConn would unwrap the file descriptor\n\t// via SyscallConn(), and read it that way, which might not be what the caller wants.\n\tvar bc batchConn\n\tif ibc, ok := c.(batchConn); ok {\n\t\tbc = ibc\n\t} else {\n\t\tbc = ipv4.NewPacketConn(c)\n\t}\n\n\tmsgs := make([]ipv4.Message, batchSize)\n\tfor i := range msgs {\n\t\t// preallocate the [][]byte\n\t\tmsgs[i].Buffers = make([][]byte, 1)\n\t}\n\toobConn := &oobConn{\n\t\tOOBCapablePacketConn: c,\n\t\tbatchConn:            bc,\n\t\tmessages:             msgs,\n\t\treadPos:              batchSize,\n\t\tcap: connCapabilities{\n\t\t\tDF:  supportsDF,\n\t\t\tGSO: isGSOEnabled(rawConn),\n\t\t\tECN: isECNEnabled(),\n\t\t},\n\t}\n\tfor i := 0; i < batchSize; i++ {\n\t\toobConn.messages[i].OOB = make([]byte, oobBufferSize)\n\t}\n\treturn oobConn, nil\n}\n\nvar invalidCmsgOnceV4, invalidCmsgOnceV6 sync.Once\n\nfunc (c *oobConn) ReadPacket() (receivedPacket, error) {\n\tif len(c.messages) == int(c.readPos) { // all messages read. Read the next batch of messages.\n\t\tc.messages = c.messages[:batchSize]\n\t\t// replace buffers data buffers up to the packet that has been consumed during the last ReadBatch call\n\t\tfor i := uint8(0); i < c.readPos; i++ {\n\t\t\tbuffer := getPacketBuffer()\n\t\t\tbuffer.Data = buffer.Data[:protocol.MaxPacketBufferSize]\n\t\t\tc.buffers[i] = buffer\n\t\t\tc.messages[i].Buffers[0] = c.buffers[i].Data\n\t\t}\n\t\tc.readPos = 0\n\n\t\tn, err := c.batchConn.ReadBatch(c.messages, 0)\n\t\tif n == 0 || err != nil {\n\t\t\treturn receivedPacket{}, err\n\t\t}\n\t\tc.messages = c.messages[:n]\n\t}\n\n\tmsg := c.messages[c.readPos]\n\tbuffer := c.buffers[c.readPos]\n\tc.readPos++\n\n\tdata := msg.OOB[:msg.NN]\n\tp := receivedPacket{\n\t\tremoteAddr: msg.Addr,\n\t\trcvTime:    time.Now(),\n\t\tdata:       msg.Buffers[0][:msg.N],\n\t\tbuffer:     buffer,\n\t}\n\tfor len(data) > 0 {\n\t\thdr, body, remainder, err := unix.ParseOneSocketControlMessage(data)\n\t\tif err != nil {\n\t\t\treturn receivedPacket{}, err\n\t\t}\n\t\tif hdr.Level == unix.IPPROTO_IP {\n\t\t\tswitch hdr.Type {\n\t\t\tcase msgTypeIPTOS:\n\t\t\t\tp.ecn = protocol.ParseECNHeaderBits(body[0] & ecnMask)\n\t\t\tcase ipv4PKTINFO:\n\t\t\t\tip, ifIndex, ok := parseIPv4PktInfo(body)\n\t\t\t\tif ok {\n\t\t\t\t\tp.info.addr = ip\n\t\t\t\t\tp.info.ifIndex = ifIndex\n\t\t\t\t} else {\n\t\t\t\t\tinvalidCmsgOnceV4.Do(func() {\n\t\t\t\t\t\tlog.Printf(\"Received invalid IPv4 packet info control message: %+x. \"+\n\t\t\t\t\t\t\t\"This should never occur, please open a new issue and include details about the architecture.\", body)\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif hdr.Level == unix.IPPROTO_IPV6 {\n\t\t\tswitch hdr.Type {\n\t\t\tcase unix.IPV6_TCLASS:\n\t\t\t\tp.ecn = protocol.ParseECNHeaderBits(body[0] & ecnMask)\n\t\t\tcase unix.IPV6_PKTINFO:\n\t\t\t\t// struct in6_pktinfo {\n\t\t\t\t// \tstruct in6_addr ipi6_addr;    /* src/dst IPv6 address */\n\t\t\t\t// \tunsigned int    ipi6_ifindex; /* send/recv interface index */\n\t\t\t\t// };\n\t\t\t\tif len(body) == 20 {\n\t\t\t\t\tp.info.addr = netip.AddrFrom16(*(*[16]byte)(body[:16])).Unmap()\n\t\t\t\t\tp.info.ifIndex = binary.LittleEndian.Uint32(body[16:])\n\t\t\t\t} else {\n\t\t\t\t\tinvalidCmsgOnceV6.Do(func() {\n\t\t\t\t\t\tlog.Printf(\"Received invalid IPv6 packet info control message: %+x. \"+\n\t\t\t\t\t\t\t\"This should never occur, please open a new issue and include details about the architecture.\", body)\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdata = remainder\n\t}\n\treturn p, nil\n}\n\n// WritePacket writes a new packet.\nfunc (c *oobConn) WritePacket(b []byte, addr net.Addr, packetInfoOOB []byte, gsoSize uint16, ecn protocol.ECN) (int, error) {\n\toob := packetInfoOOB\n\tif gsoSize > 0 {\n\t\tif !c.capabilities().GSO {\n\t\t\tpanic(\"GSO disabled\")\n\t\t}\n\t\toob = appendUDPSegmentSizeMsg(oob, gsoSize)\n\t}\n\tif ecn != protocol.ECNUnsupported {\n\t\tif !c.capabilities().ECN {\n\t\t\tpanic(\"tried to send an ECN-marked packet although ECN is disabled\")\n\t\t}\n\t\tif remoteUDPAddr, ok := addr.(*net.UDPAddr); ok {\n\t\t\tif remoteUDPAddr.IP.To4() != nil {\n\t\t\t\toob = appendIPv4ECNMsg(oob, ecn)\n\t\t\t} else {\n\t\t\t\toob = appendIPv6ECNMsg(oob, ecn)\n\t\t\t}\n\t\t}\n\t}\n\tn, _, err := c.WriteMsgUDP(b, oob, addr.(*net.UDPAddr))\n\treturn n, err\n}\n\nfunc (c *oobConn) capabilities() connCapabilities {\n\treturn c.cap\n}\n\ntype packetInfo struct {\n\taddr    netip.Addr\n\tifIndex uint32\n}\n\nfunc (info *packetInfo) OOB() []byte {\n\tif info == nil {\n\t\treturn nil\n\t}\n\tif info.addr.Is4() {\n\t\tip := info.addr.As4()\n\t\t// struct in_pktinfo {\n\t\t// \tunsigned int   ipi_ifindex;  /* Interface index */\n\t\t// \tstruct in_addr ipi_spec_dst; /* Local address */\n\t\t// \tstruct in_addr ipi_addr;     /* Header Destination address */\n\t\t// };\n\t\tcm := ipv4.ControlMessage{\n\t\t\tSrc:     ip[:],\n\t\t\tIfIndex: int(info.ifIndex),\n\t\t}\n\t\treturn cm.Marshal()\n\t} else if info.addr.Is6() {\n\t\tip := info.addr.As16()\n\t\t// struct in6_pktinfo {\n\t\t// \tstruct in6_addr ipi6_addr;    /* src/dst IPv6 address */\n\t\t// \tunsigned int    ipi6_ifindex; /* send/recv interface index */\n\t\t// };\n\t\tcm := ipv6.ControlMessage{\n\t\t\tSrc:     ip[:],\n\t\t\tIfIndex: int(info.ifIndex),\n\t\t}\n\t\treturn cm.Marshal()\n\t}\n\treturn nil\n}\n\nfunc appendIPv4ECNMsg(b []byte, val protocol.ECN) []byte {\n\tstartLen := len(b)\n\tb = append(b, make([]byte, unix.CmsgSpace(ecnIPv4DataLen))...)\n\th := (*unix.Cmsghdr)(unsafe.Pointer(&b[startLen]))\n\th.Level = syscall.IPPROTO_IP\n\th.Type = unix.IP_TOS\n\th.SetLen(unix.CmsgLen(ecnIPv4DataLen))\n\n\t// UnixRights uses the private `data` method, but I *think* this achieves the same goal.\n\toffset := startLen + unix.CmsgSpace(0)\n\tb[offset] = val.ToHeaderBits()\n\treturn b\n}\n\nfunc appendIPv6ECNMsg(b []byte, val protocol.ECN) []byte {\n\tstartLen := len(b)\n\tconst dataLen = 4\n\tb = append(b, make([]byte, unix.CmsgSpace(dataLen))...)\n\th := (*unix.Cmsghdr)(unsafe.Pointer(&b[startLen]))\n\th.Level = syscall.IPPROTO_IPV6\n\th.Type = unix.IPV6_TCLASS\n\th.SetLen(unix.CmsgLen(dataLen))\n\n\t// UnixRights uses the private `data` method, but I *think* this achieves the same goal.\n\toffset := startLen + unix.CmsgSpace(0)\n\tb[offset] = val.ToHeaderBits()\n\treturn b\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/sys_conn_windows.go",
    "content": "//go:build windows\n\npackage quic\n\nimport (\n\t\"net/netip\"\n\t\"syscall\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\nfunc newConn(c OOBCapablePacketConn, supportsDF bool) (*basicConn, error) {\n\treturn &basicConn{PacketConn: c, supportsDF: supportsDF}, nil\n}\n\nfunc inspectReadBuffer(c syscall.RawConn) (int, error) {\n\tvar size int\n\tvar serr error\n\tif err := c.Control(func(fd uintptr) {\n\t\tsize, serr = windows.GetsockoptInt(windows.Handle(fd), windows.SOL_SOCKET, windows.SO_RCVBUF)\n\t}); err != nil {\n\t\treturn 0, err\n\t}\n\treturn size, serr\n}\n\nfunc inspectWriteBuffer(c syscall.RawConn) (int, error) {\n\tvar size int\n\tvar serr error\n\tif err := c.Control(func(fd uintptr) {\n\t\tsize, serr = windows.GetsockoptInt(windows.Handle(fd), windows.SOL_SOCKET, windows.SO_SNDBUF)\n\t}); err != nil {\n\t\treturn 0, err\n\t}\n\treturn size, serr\n}\n\ntype packetInfo struct {\n\taddr netip.Addr\n}\n\nfunc (i *packetInfo) OOB() []byte { return nil }\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/token_store.go",
    "content": "package quic\n\nimport (\n\t\"sync\"\n\n\tlist \"github.com/quic-go/quic-go/internal/utils/linkedlist\"\n)\n\ntype singleOriginTokenStore struct {\n\ttokens []*ClientToken\n\tlen    int\n\tp      int\n}\n\nfunc newSingleOriginTokenStore(size int) *singleOriginTokenStore {\n\treturn &singleOriginTokenStore{tokens: make([]*ClientToken, size)}\n}\n\nfunc (s *singleOriginTokenStore) Add(token *ClientToken) {\n\ts.tokens[s.p] = token\n\ts.p = s.index(s.p + 1)\n\ts.len = min(s.len+1, len(s.tokens))\n}\n\nfunc (s *singleOriginTokenStore) Pop() *ClientToken {\n\ts.p = s.index(s.p - 1)\n\ttoken := s.tokens[s.p]\n\ts.tokens[s.p] = nil\n\ts.len = max(s.len-1, 0)\n\treturn token\n}\n\nfunc (s *singleOriginTokenStore) Len() int {\n\treturn s.len\n}\n\nfunc (s *singleOriginTokenStore) index(i int) int {\n\tmod := len(s.tokens)\n\treturn (i + mod) % mod\n}\n\ntype lruTokenStoreEntry struct {\n\tkey   string\n\tcache *singleOriginTokenStore\n}\n\ntype lruTokenStore struct {\n\tmutex sync.Mutex\n\n\tm                map[string]*list.Element[*lruTokenStoreEntry]\n\tq                *list.List[*lruTokenStoreEntry]\n\tcapacity         int\n\tsingleOriginSize int\n}\n\nvar _ TokenStore = &lruTokenStore{}\n\n// NewLRUTokenStore creates a new LRU cache for tokens received by the client.\n// maxOrigins specifies how many origins this cache is saving tokens for.\n// tokensPerOrigin specifies the maximum number of tokens per origin.\nfunc NewLRUTokenStore(maxOrigins, tokensPerOrigin int) TokenStore {\n\treturn &lruTokenStore{\n\t\tm:                make(map[string]*list.Element[*lruTokenStoreEntry]),\n\t\tq:                list.New[*lruTokenStoreEntry](),\n\t\tcapacity:         maxOrigins,\n\t\tsingleOriginSize: tokensPerOrigin,\n\t}\n}\n\nfunc (s *lruTokenStore) Put(key string, token *ClientToken) {\n\ts.mutex.Lock()\n\tdefer s.mutex.Unlock()\n\n\tif el, ok := s.m[key]; ok {\n\t\tentry := el.Value\n\t\tentry.cache.Add(token)\n\t\ts.q.MoveToFront(el)\n\t\treturn\n\t}\n\n\tif s.q.Len() < s.capacity {\n\t\tentry := &lruTokenStoreEntry{\n\t\t\tkey:   key,\n\t\t\tcache: newSingleOriginTokenStore(s.singleOriginSize),\n\t\t}\n\t\tentry.cache.Add(token)\n\t\ts.m[key] = s.q.PushFront(entry)\n\t\treturn\n\t}\n\n\telem := s.q.Back()\n\tentry := elem.Value\n\tdelete(s.m, entry.key)\n\tentry.key = key\n\tentry.cache = newSingleOriginTokenStore(s.singleOriginSize)\n\tentry.cache.Add(token)\n\ts.q.MoveToFront(elem)\n\ts.m[key] = elem\n}\n\nfunc (s *lruTokenStore) Pop(key string) *ClientToken {\n\ts.mutex.Lock()\n\tdefer s.mutex.Unlock()\n\n\tvar token *ClientToken\n\tif el, ok := s.m[key]; ok {\n\t\ts.q.MoveToFront(el)\n\t\tcache := el.Value.cache\n\t\ttoken = cache.Pop()\n\t\tif cache.Len() == 0 {\n\t\t\ts.q.Remove(el)\n\t\t\tdelete(s.m, key)\n\t\t}\n\t}\n\treturn token\n}\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/tools.go",
    "content": "//go:build tools\n\npackage quic\n\nimport (\n\t_ \"github.com/onsi/ginkgo/v2/ginkgo\"\n\t_ \"go.uber.org/mock/mockgen\"\n)\n"
  },
  {
    "path": "vendor/github.com/quic-go/quic-go/transport.go",
    "content": "package quic\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/quic-go/quic-go/internal/protocol\"\n\t\"github.com/quic-go/quic-go/internal/utils\"\n\t\"github.com/quic-go/quic-go/internal/wire\"\n\t\"github.com/quic-go/quic-go/logging\"\n)\n\n// ErrTransportClosed is returned by the [Transport]'s Listen or Dial method after it was closed.\nvar ErrTransportClosed = &errTransportClosed{}\n\ntype errTransportClosed struct {\n\terr error\n}\n\nfunc (e *errTransportClosed) Unwrap() []error { return []error{net.ErrClosed, e.err} }\n\nfunc (e *errTransportClosed) Error() string {\n\tif e.err == nil {\n\t\treturn \"quic: transport closed\"\n\t}\n\treturn fmt.Sprintf(\"quic: transport closed: %s\", e.err)\n}\n\nfunc (e *errTransportClosed) Is(target error) bool {\n\t_, ok := target.(*errTransportClosed)\n\treturn ok\n}\n\ntype transportID uint64\n\nvar transportIDCounter atomic.Uint64\n\nvar errListenerAlreadySet = errors.New(\"listener already set\")\n\n// The Transport is the central point to manage incoming and outgoing QUIC connections.\n// QUIC demultiplexes connections based on their QUIC Connection IDs, not based on the 4-tuple.\n// This means that a single UDP socket can be used for listening for incoming connections, as well as\n// for dialing an arbitrary number of outgoing connections.\n// A Transport handles a single net.PacketConn, and offers a range of configuration options\n// compared to the simple helper functions like [Listen] and [Dial] that this package provides.\ntype Transport struct {\n\t// A single net.PacketConn can only be handled by one Transport.\n\t// Bad things will happen if passed to multiple Transports.\n\t//\n\t// A number of optimizations will be enabled if the connections implements the OOBCapablePacketConn interface,\n\t// as a *net.UDPConn does.\n\t// 1. It enables the Don't Fragment (DF) bit on the IP header.\n\t//    This is required to run DPLPMTUD (Path MTU Discovery, RFC 8899).\n\t// 2. It enables reading of the ECN bits from the IP header.\n\t//    This allows the remote node to speed up its loss detection and recovery.\n\t// 3. It uses batched syscalls (recvmmsg) to more efficiently receive packets from the socket.\n\t// 4. It uses Generic Segmentation Offload (GSO) to efficiently send batches of packets (on Linux).\n\t//\n\t// After passing the connection to the Transport, it's invalid to call ReadFrom or WriteTo on the connection.\n\tConn net.PacketConn\n\n\t// The length of the connection ID in bytes.\n\t// It can be any value between 1 and 20.\n\t// Due to the increased risk of collisions, it is not recommended to use connection IDs shorter than 4 bytes.\n\t// If unset, a 4 byte connection ID will be used.\n\tConnectionIDLength int\n\n\t// Use for generating new connection IDs.\n\t// This allows the application to control of the connection IDs used,\n\t// which allows routing / load balancing based on connection IDs.\n\t// All Connection IDs returned by the ConnectionIDGenerator MUST\n\t// have the same length.\n\tConnectionIDGenerator ConnectionIDGenerator\n\n\t// The StatelessResetKey is used to generate stateless reset tokens.\n\t// If no key is configured, sending of stateless resets is disabled.\n\t// It is highly recommended to configure a stateless reset key, as stateless resets\n\t// allow the peer to quickly recover from crashes and reboots of this node.\n\t// See section 10.3 of RFC 9000 for details.\n\tStatelessResetKey *StatelessResetKey\n\n\t// The TokenGeneratorKey is used to encrypt session resumption tokens.\n\t// If no key is configured, a random key will be generated.\n\t// If multiple servers are authoritative for the same domain, they should use the same key,\n\t// see section 8.1.3 of RFC 9000 for details.\n\tTokenGeneratorKey *TokenGeneratorKey\n\n\t// MaxTokenAge is the maximum age of the resumption token presented during the handshake.\n\t// These tokens allow skipping address resumption when resuming a QUIC connection,\n\t// and are especially useful when using 0-RTT.\n\t// If not set, it defaults to 24 hours.\n\t// See section 8.1.3 of RFC 9000 for details.\n\tMaxTokenAge time.Duration\n\n\t// DisableVersionNegotiationPackets disables the sending of Version Negotiation packets.\n\t// This can be useful if version information is exchanged out-of-band.\n\t// It has no effect for clients.\n\tDisableVersionNegotiationPackets bool\n\n\t// VerifySourceAddress decides if a connection attempt originating from unvalidated source\n\t// addresses first needs to go through source address validation using QUIC's Retry mechanism,\n\t// as described in RFC 9000 section 8.1.2.\n\t// Note that the address passed to this callback is unvalidated, and might be spoofed in case\n\t// of an attack.\n\t// Validating the source address adds one additional network roundtrip to the handshake,\n\t// and should therefore only be used if a suspiciously high number of incoming connection is recorded.\n\t// For most use cases, wrapping the Allow function of a rate.Limiter will be a reasonable\n\t// implementation of this callback (negating its return value).\n\tVerifySourceAddress func(net.Addr) bool\n\n\t// ConnContext is called when the server accepts a new connection.\n\t// The context is closed when the connection is closed, or when the handshake fails for any reason.\n\t// The context returned from the callback is used to derive every other context used during the\n\t// lifetime of the connection:\n\t// * the context passed to crypto/tls (and used on the tls.ClientHelloInfo)\n\t// * the context used in Config.Tracer\n\t// * the context returned from Connection.Context\n\t// * the context returned from SendStream.Context\n\t// It is not used for dialed connections.\n\tConnContext func(context.Context) context.Context\n\n\t// A Tracer traces events that don't belong to a single QUIC connection.\n\t// Tracer.Close is called when the transport is closed.\n\tTracer *logging.Tracer\n\n\thandlerMap packetHandlerManager\n\n\tmutex    sync.Mutex\n\tinitOnce sync.Once\n\tinitErr  error\n\n\t// Set in init.\n\ttransportID transportID\n\t// If no ConnectionIDGenerator is set, this is the ConnectionIDLength.\n\tconnIDLen int\n\t// Set in init.\n\t// If no ConnectionIDGenerator is set, this is set to a default.\n\tconnIDGenerator   ConnectionIDGenerator\n\tstatelessResetter *statelessResetter\n\n\tserver *baseServer\n\n\tconn rawConn\n\n\tcloseQueue          chan closePacket\n\tstatelessResetQueue chan receivedPacket\n\n\tlistening   chan struct{} // is closed when listen returns\n\tcloseErr    error\n\tcreatedConn bool\n\tisSingleUse bool // was created for a single server or client, i.e. by calling quic.Listen or quic.Dial\n\n\treadingNonQUICPackets atomic.Bool\n\tnonQUICPackets        chan receivedPacket\n\n\tlogger utils.Logger\n}\n\n// Listen starts listening for incoming QUIC connections.\n// There can only be a single listener on any net.PacketConn.\n// Listen may only be called again after the current listener was closed.\nfunc (t *Transport) Listen(tlsConf *tls.Config, conf *Config) (*Listener, error) {\n\ts, err := t.createServer(tlsConf, conf, false)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Listener{baseServer: s}, nil\n}\n\n// ListenEarly starts listening for incoming QUIC connections.\n// There can only be a single listener on any net.PacketConn.\n// ListenEarly may only be called again after the current listener was closed.\nfunc (t *Transport) ListenEarly(tlsConf *tls.Config, conf *Config) (*EarlyListener, error) {\n\ts, err := t.createServer(tlsConf, conf, true)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &EarlyListener{baseServer: s}, nil\n}\n\nfunc (t *Transport) createServer(tlsConf *tls.Config, conf *Config, allow0RTT bool) (*baseServer, error) {\n\tif tlsConf == nil {\n\t\treturn nil, errors.New(\"quic: tls.Config not set\")\n\t}\n\tif err := validateConfig(conf); err != nil {\n\t\treturn nil, err\n\t}\n\n\tt.mutex.Lock()\n\tdefer t.mutex.Unlock()\n\n\tif t.closeErr != nil {\n\t\treturn nil, t.closeErr\n\t}\n\tif t.server != nil {\n\t\treturn nil, errListenerAlreadySet\n\t}\n\tconf = populateConfig(conf)\n\tif err := t.init(false); err != nil {\n\t\treturn nil, err\n\t}\n\tmaxTokenAge := t.MaxTokenAge\n\tif maxTokenAge == 0 {\n\t\tmaxTokenAge = 24 * time.Hour\n\t}\n\ts := newServer(\n\t\tt.conn,\n\t\tt,\n\t\tt.connIDGenerator,\n\t\tt.statelessResetter,\n\t\tt.ConnContext,\n\t\ttlsConf,\n\t\tconf,\n\t\tt.Tracer,\n\t\tt.closeServer,\n\t\t*t.TokenGeneratorKey,\n\t\tmaxTokenAge,\n\t\tt.VerifySourceAddress,\n\t\tt.DisableVersionNegotiationPackets,\n\t\tallow0RTT,\n\t)\n\tt.server = s\n\treturn s, nil\n}\n\n// Dial dials a new connection to a remote host (not using 0-RTT).\nfunc (t *Transport) Dial(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *Config) (Connection, error) {\n\treturn t.dial(ctx, addr, \"\", tlsConf, conf, false)\n}\n\n// DialEarly dials a new connection, attempting to use 0-RTT if possible.\nfunc (t *Transport) DialEarly(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *Config) (EarlyConnection, error) {\n\treturn t.dial(ctx, addr, \"\", tlsConf, conf, true)\n}\n\nfunc (t *Transport) dial(ctx context.Context, addr net.Addr, host string, tlsConf *tls.Config, conf *Config, use0RTT bool) (EarlyConnection, error) {\n\tif err := t.init(t.isSingleUse); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := validateConfig(conf); err != nil {\n\t\treturn nil, err\n\t}\n\tconf = populateConfig(conf)\n\ttlsConf = tlsConf.Clone()\n\tsetTLSConfigServerName(tlsConf, addr, host)\n\treturn t.doDial(ctx,\n\t\tnewSendConn(t.conn, addr, packetInfo{}, utils.DefaultLogger),\n\t\ttlsConf,\n\t\tconf,\n\t\t0,\n\t\tfalse,\n\t\tuse0RTT,\n\t\tconf.Versions[0],\n\t)\n}\n\nfunc (t *Transport) doDial(\n\tctx context.Context,\n\tsendConn sendConn,\n\ttlsConf *tls.Config,\n\tconfig *Config,\n\tinitialPacketNumber protocol.PacketNumber,\n\thasNegotiatedVersion bool,\n\tuse0RTT bool,\n\tversion protocol.Version,\n) (quicConn, error) {\n\tsrcConnID, err := t.connIDGenerator.GenerateConnectionID()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdestConnID, err := generateConnectionIDForInitial()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttracingID := nextConnTracingID()\n\tctx = context.WithValue(ctx, ConnectionTracingKey, tracingID)\n\n\tt.mutex.Lock()\n\tif t.closeErr != nil {\n\t\tt.mutex.Unlock()\n\t\treturn nil, t.closeErr\n\t}\n\n\tvar tracer *logging.ConnectionTracer\n\tif config.Tracer != nil {\n\t\ttracer = config.Tracer(ctx, protocol.PerspectiveClient, destConnID)\n\t}\n\tif tracer != nil && tracer.StartedConnection != nil {\n\t\ttracer.StartedConnection(sendConn.LocalAddr(), sendConn.RemoteAddr(), srcConnID, destConnID)\n\t}\n\n\tlogger := utils.DefaultLogger.WithPrefix(\"client\")\n\tlogger.Infof(\"Starting new connection to %s (%s -> %s), source connection ID %s, destination connection ID %s, version %s\", tlsConf.ServerName, sendConn.LocalAddr(), sendConn.RemoteAddr(), srcConnID, destConnID, version)\n\n\tconn := newClientConnection(\n\t\tcontext.WithoutCancel(ctx),\n\t\tsendConn,\n\t\tt,\n\t\tdestConnID,\n\t\tsrcConnID,\n\t\tt.connIDGenerator,\n\t\tt.statelessResetter,\n\t\tconfig,\n\t\ttlsConf,\n\t\tinitialPacketNumber,\n\t\tuse0RTT,\n\t\thasNegotiatedVersion,\n\t\ttracer,\n\t\tlogger,\n\t\tversion,\n\t)\n\tt.handlerMap.Add(srcConnID, conn)\n\tt.mutex.Unlock()\n\n\t// The error channel needs to be buffered, as the run loop will continue running\n\t// after doDial returns (if the handshake is successful).\n\terrChan := make(chan error, 1)\n\trecreateChan := make(chan errCloseForRecreating)\n\tgo func() {\n\t\terr := conn.run()\n\t\tvar recreateErr *errCloseForRecreating\n\t\tif errors.As(err, &recreateErr) {\n\t\t\trecreateChan <- *recreateErr\n\t\t\treturn\n\t\t}\n\t\tif t.isSingleUse {\n\t\t\tt.Close()\n\t\t}\n\t\terrChan <- err\n\t}()\n\n\t// Only set when we're using 0-RTT.\n\t// Otherwise, earlyConnChan will be nil. Receiving from a nil chan blocks forever.\n\tvar earlyConnChan <-chan struct{}\n\tif use0RTT {\n\t\tearlyConnChan = conn.earlyConnReady()\n\t}\n\n\tselect {\n\tcase <-ctx.Done():\n\t\tconn.destroy(nil)\n\t\t// wait until the Go routine that called Connection.run() returns\n\t\tselect {\n\t\tcase <-errChan:\n\t\tcase <-recreateChan:\n\t\t}\n\t\treturn nil, context.Cause(ctx)\n\tcase params := <-recreateChan:\n\t\treturn t.doDial(ctx,\n\t\t\tsendConn,\n\t\t\ttlsConf,\n\t\t\tconfig,\n\t\t\tparams.nextPacketNumber,\n\t\t\ttrue,\n\t\t\tuse0RTT,\n\t\t\tparams.nextVersion,\n\t\t)\n\tcase err := <-errChan:\n\t\treturn nil, err\n\tcase <-earlyConnChan:\n\t\t// ready to send 0-RTT data\n\t\treturn conn, nil\n\tcase <-conn.HandshakeComplete():\n\t\t// handshake successfully completed\n\t\treturn conn, nil\n\t}\n}\n\nfunc (t *Transport) init(allowZeroLengthConnIDs bool) error {\n\tt.initOnce.Do(func() {\n\t\tt.transportID = transportID(transportIDCounter.Add(1))\n\t\tvar conn rawConn\n\t\tif c, ok := t.Conn.(rawConn); ok {\n\t\t\tconn = c\n\t\t} else {\n\t\t\tvar err error\n\t\t\tconn, err = wrapConn(t.Conn)\n\t\t\tif err != nil {\n\t\t\t\tt.initErr = err\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tt.logger = utils.DefaultLogger // TODO: make this configurable\n\t\tt.conn = conn\n\t\tif t.handlerMap == nil { // allows mocking the handlerMap in tests\n\t\t\tt.handlerMap = newPacketHandlerMap(t.enqueueClosePacket, t.logger)\n\t\t}\n\t\tt.listening = make(chan struct{})\n\n\t\tt.closeQueue = make(chan closePacket, 4)\n\t\tt.statelessResetQueue = make(chan receivedPacket, 4)\n\t\tif t.TokenGeneratorKey == nil {\n\t\t\tvar key TokenGeneratorKey\n\t\t\tif _, err := rand.Read(key[:]); err != nil {\n\t\t\t\tt.initErr = err\n\t\t\t\treturn\n\t\t\t}\n\t\t\tt.TokenGeneratorKey = &key\n\t\t}\n\n\t\tif t.ConnectionIDGenerator != nil {\n\t\t\tt.connIDGenerator = t.ConnectionIDGenerator\n\t\t\tt.connIDLen = t.ConnectionIDGenerator.ConnectionIDLen()\n\t\t} else {\n\t\t\tconnIDLen := t.ConnectionIDLength\n\t\t\tif t.ConnectionIDLength == 0 && !allowZeroLengthConnIDs {\n\t\t\t\tconnIDLen = protocol.DefaultConnectionIDLength\n\t\t\t}\n\t\t\tt.connIDLen = connIDLen\n\t\t\tt.connIDGenerator = &protocol.DefaultConnectionIDGenerator{ConnLen: t.connIDLen}\n\t\t}\n\t\tt.statelessResetter = newStatelessResetter(t.StatelessResetKey)\n\n\t\tgo t.listen(conn)\n\t\tgo t.runSendQueue()\n\t})\n\treturn t.initErr\n}\n\nfunc (t *Transport) connRunner() packetHandlerManager {\n\treturn t.handlerMap\n}\n\nfunc (t *Transport) id() transportID { return t.transportID }\n\n// WriteTo sends a packet on the underlying connection.\nfunc (t *Transport) WriteTo(b []byte, addr net.Addr) (int, error) {\n\tif err := t.init(false); err != nil {\n\t\treturn 0, err\n\t}\n\treturn t.conn.WritePacket(b, addr, nil, 0, protocol.ECNUnsupported)\n}\n\nfunc (t *Transport) enqueueClosePacket(p closePacket) {\n\tselect {\n\tcase t.closeQueue <- p:\n\tdefault:\n\t\t// Oops, we're backlogged.\n\t\t// Just drop the packet, sending CONNECTION_CLOSE copies is best effort anyway.\n\t}\n}\n\nfunc (t *Transport) runSendQueue() {\n\tfor {\n\t\tselect {\n\t\tcase <-t.listening:\n\t\t\treturn\n\t\tcase p := <-t.closeQueue:\n\t\t\tt.conn.WritePacket(p.payload, p.addr, p.info.OOB(), 0, protocol.ECNUnsupported)\n\t\tcase p := <-t.statelessResetQueue:\n\t\t\tt.sendStatelessReset(p)\n\t\t}\n\t}\n}\n\n// Close stops listening for UDP datagrams on the Transport.Conn.\n// If any listener was started, it will be closed as well.\n// It is invalid to start new listeners or connections after that.\nfunc (t *Transport) Close() error {\n\t// avoid race condition if the transport is currently being initialized\n\tt.init(false)\n\n\tt.close(nil)\n\tif t.createdConn {\n\t\tif err := t.Conn.Close(); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if t.conn != nil {\n\t\tt.conn.SetReadDeadline(time.Now())\n\t\tdefer func() { t.conn.SetReadDeadline(time.Time{}) }()\n\t}\n\tif t.listening != nil {\n\t\t<-t.listening // wait until listening returns\n\t}\n\treturn nil\n}\n\nfunc (t *Transport) closeServer() {\n\tt.mutex.Lock()\n\tt.server = nil\n\tif t.isSingleUse {\n\t\tt.closeErr = ErrServerClosed\n\t}\n\tt.mutex.Unlock()\n\tif t.createdConn {\n\t\tt.Conn.Close()\n\t}\n\tif t.isSingleUse {\n\t\tt.conn.SetReadDeadline(time.Now())\n\t\tdefer func() { t.conn.SetReadDeadline(time.Time{}) }()\n\t\t<-t.listening // wait until listening returns\n\t}\n}\n\nfunc (t *Transport) close(e error) {\n\tt.mutex.Lock()\n\tdefer t.mutex.Unlock()\n\n\tif t.closeErr != nil {\n\t\treturn\n\t}\n\n\te = &errTransportClosed{err: e}\n\tif t.handlerMap != nil {\n\t\tt.handlerMap.Close(e)\n\t}\n\tif t.server != nil {\n\t\tt.server.close(e, false)\n\t}\n\tif t.Tracer != nil && t.Tracer.Close != nil {\n\t\tt.Tracer.Close()\n\t}\n\tt.closeErr = e\n}\n\n// only print warnings about the UDP receive buffer size once\nvar setBufferWarningOnce sync.Once\n\nfunc (t *Transport) listen(conn rawConn) {\n\tdefer close(t.listening)\n\n\tfor {\n\t\tp, err := conn.ReadPacket()\n\t\t//nolint:staticcheck // SA1019 ignore this!\n\t\t// TODO: This code is used to ignore wsa errors on Windows.\n\t\t// Since net.Error.Temporary is deprecated as of Go 1.18, we should find a better solution.\n\t\t// See https://github.com/quic-go/quic-go/issues/1737 for details.\n\t\tif nerr, ok := err.(net.Error); ok && nerr.Temporary() {\n\t\t\tt.mutex.Lock()\n\t\t\tclosed := t.closeErr != nil\n\t\t\tt.mutex.Unlock()\n\t\t\tif closed {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tt.logger.Debugf(\"Temporary error reading from conn: %w\", err)\n\t\t\tcontinue\n\t\t}\n\t\tif err != nil {\n\t\t\t// Windows returns an error when receiving a UDP datagram that doesn't fit into the provided buffer.\n\t\t\tif isRecvMsgSizeErr(err) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tt.close(err)\n\t\t\treturn\n\t\t}\n\t\tt.handlePacket(p)\n\t}\n}\n\nfunc (t *Transport) handlePacket(p receivedPacket) {\n\tif len(p.data) == 0 {\n\t\treturn\n\t}\n\tif !wire.IsPotentialQUICPacket(p.data[0]) && !wire.IsLongHeaderPacket(p.data[0]) {\n\t\tt.handleNonQUICPacket(p)\n\t\treturn\n\t}\n\tconnID, err := wire.ParseConnectionID(p.data, t.connIDLen)\n\tif err != nil {\n\t\tt.logger.Debugf(\"error parsing connection ID on packet from %s: %s\", p.remoteAddr, err)\n\t\tif t.Tracer != nil && t.Tracer.DroppedPacket != nil {\n\t\t\tt.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropHeaderParseError)\n\t\t}\n\t\tp.buffer.MaybeRelease()\n\t\treturn\n\t}\n\n\t// If there's a connection associated with the connection ID, pass the packet there.\n\tif handler, ok := t.handlerMap.Get(connID); ok {\n\t\thandler.handlePacket(p)\n\t\treturn\n\t}\n\t// RFC 9000 section 10.3.1 requires that the stateless reset detection logic is run for both\n\t// packets that cannot be associated with any connections, and for packets that can't be decrypted.\n\t// We deviate from the RFC and ignore the latter: If a packet's connection ID is associated with an\n\t// existing connection, it is dropped there if if it can't be decrypted.\n\t// Stateless resets use random connection IDs, and at reasonable connection ID lengths collisions are\n\t// exceedingly rare. In the unlikely event that a stateless reset is misrouted to an existing connection,\n\t// it is to be expected that the next stateless reset will be correctly detected.\n\tif isStatelessReset := t.maybeHandleStatelessReset(p.data); isStatelessReset {\n\t\treturn\n\t}\n\tif !wire.IsLongHeaderPacket(p.data[0]) {\n\t\tif statelessResetQueued := t.maybeSendStatelessReset(p); !statelessResetQueued {\n\t\t\tif t.Tracer != nil && t.Tracer.DroppedPacket != nil {\n\t\t\t\tt.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnknownConnectionID)\n\t\t\t}\n\t\t\tp.buffer.Release()\n\t\t}\n\t\treturn\n\t}\n\n\tt.mutex.Lock()\n\tdefer t.mutex.Unlock()\n\tif t.server == nil { // no server set\n\t\tt.logger.Debugf(\"received a packet with an unexpected connection ID %s\", connID)\n\t\tif t.Tracer != nil && t.Tracer.DroppedPacket != nil {\n\t\t\tt.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnknownConnectionID)\n\t\t}\n\t\tp.buffer.MaybeRelease()\n\t\treturn\n\t}\n\tt.server.handlePacket(p)\n}\n\nfunc (t *Transport) maybeSendStatelessReset(p receivedPacket) (statelessResetQueued bool) {\n\tif t.StatelessResetKey == nil {\n\t\treturn false\n\t}\n\n\t// Don't send a stateless reset in response to very small packets.\n\t// This includes packets that could be stateless resets.\n\tif len(p.data) <= protocol.MinStatelessResetSize {\n\t\treturn false\n\t}\n\n\tselect {\n\tcase t.statelessResetQueue <- p:\n\t\treturn true\n\tdefault:\n\t\t// it's fine to not send a stateless reset when we're busy\n\t\treturn false\n\t}\n}\n\nfunc (t *Transport) sendStatelessReset(p receivedPacket) {\n\tdefer p.buffer.Release()\n\n\tconnID, err := wire.ParseConnectionID(p.data, t.connIDLen)\n\tif err != nil {\n\t\tt.logger.Errorf(\"error parsing connection ID on packet from %s: %s\", p.remoteAddr, err)\n\t\treturn\n\t}\n\ttoken := t.statelessResetter.GetStatelessResetToken(connID)\n\tt.logger.Debugf(\"Sending stateless reset to %s (connection ID: %s). Token: %#x\", p.remoteAddr, connID, token)\n\tdata := make([]byte, protocol.MinStatelessResetSize-16, protocol.MinStatelessResetSize)\n\trand.Read(data)\n\tdata[0] = (data[0] & 0x7f) | 0x40\n\tdata = append(data, token[:]...)\n\tif _, err := t.conn.WritePacket(data, p.remoteAddr, p.info.OOB(), 0, protocol.ECNUnsupported); err != nil {\n\t\tt.logger.Debugf(\"Error sending Stateless Reset to %s: %s\", p.remoteAddr, err)\n\t}\n}\n\nfunc (t *Transport) maybeHandleStatelessReset(data []byte) bool {\n\t// stateless resets are always short header packets\n\tif wire.IsLongHeaderPacket(data[0]) {\n\t\treturn false\n\t}\n\tif len(data) < 17 /* type byte + 16 bytes for the reset token */ {\n\t\treturn false\n\t}\n\n\ttoken := *(*protocol.StatelessResetToken)(data[len(data)-16:])\n\tif conn, ok := t.handlerMap.GetByResetToken(token); ok {\n\t\tt.logger.Debugf(\"Received a stateless reset with token %#x. Closing connection.\", token)\n\t\tgo conn.destroy(&StatelessResetError{})\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (t *Transport) handleNonQUICPacket(p receivedPacket) {\n\t// Strictly speaking, this is racy,\n\t// but we only care about receiving packets at some point after ReadNonQUICPacket has been called.\n\tif !t.readingNonQUICPackets.Load() {\n\t\treturn\n\t}\n\tselect {\n\tcase t.nonQUICPackets <- p:\n\tdefault:\n\t\tif t.Tracer != nil && t.Tracer.DroppedPacket != nil {\n\t\t\tt.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropDOSPrevention)\n\t\t}\n\t}\n}\n\nconst maxQueuedNonQUICPackets = 32\n\n// ReadNonQUICPacket reads non-QUIC packets received on the underlying connection.\n// The detection logic is very simple: Any packet that has the first and second bit of the packet set to 0.\n// Note that this is stricter than the detection logic defined in RFC 9443.\nfunc (t *Transport) ReadNonQUICPacket(ctx context.Context, b []byte) (int, net.Addr, error) {\n\tif err := t.init(false); err != nil {\n\t\treturn 0, nil, err\n\t}\n\tif !t.readingNonQUICPackets.Load() {\n\t\tt.nonQUICPackets = make(chan receivedPacket, maxQueuedNonQUICPackets)\n\t\tt.readingNonQUICPackets.Store(true)\n\t}\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn 0, nil, ctx.Err()\n\tcase p := <-t.nonQUICPackets:\n\t\tn := copy(b, p.data)\n\t\treturn n, p.remoteAddr, nil\n\tcase <-t.listening:\n\t\treturn 0, nil, errors.New(\"closed\")\n\t}\n}\n\nfunc setTLSConfigServerName(tlsConf *tls.Config, addr net.Addr, host string) {\n\t// If no ServerName is set, infer the ServerName from the host we're connecting to.\n\tif tlsConf.ServerName != \"\" {\n\t\treturn\n\t}\n\tif host == \"\" {\n\t\tif udpAddr, ok := addr.(*net.UDPAddr); ok {\n\t\t\ttlsConf.ServerName = udpAddr.IP.String()\n\t\t\treturn\n\t\t}\n\t}\n\th, _, err := net.SplitHostPort(host)\n\tif err != nil { // This happens if the host doesn't contain a port number.\n\t\ttlsConf.ServerName = host\n\t\treturn\n\t}\n\ttlsConf.ServerName = h\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/.gitignore",
    "content": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\ntmp\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n*.test\n*.prof\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/.travis.yml",
    "content": "language: go\ngo:\n- \"1.7\"\n- \"1.8\"\n- \"1.9\"\n- \"1.10\"\n- \"1.11\"\n- \"1.12\"\n- \"master\"\nmatrix:\n  allow_failures:\n      - go: \"master\"\nscript:\n  - go test -v -race -cpu=1,2,4 -bench . -benchmem ./...\n  - go test -v -tags binary_log -race -cpu=1,2,4 -bench . -benchmem ./...\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/CNAME",
    "content": "zerolog.io"
  },
  {
    "path": "vendor/github.com/rs/zerolog/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 Olivier Poitrey\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": "vendor/github.com/rs/zerolog/README.md",
    "content": "# Zero Allocation JSON Logger\n\n[![godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/rs/zerolog) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/rs/zerolog/master/LICENSE) [![Build Status](https://travis-ci.org/rs/zerolog.svg?branch=master)](https://travis-ci.org/rs/zerolog) [![Coverage](http://gocover.io/_badge/github.com/rs/zerolog)](http://gocover.io/github.com/rs/zerolog)\n\nThe zerolog package provides a fast and simple logger dedicated to JSON output.\n\nZerolog's API is designed to provide both a great developer experience and stunning [performance](#benchmarks). Its unique chaining API allows zerolog to write JSON (or CBOR) log events by avoiding allocations and reflection.\n\nUber's [zap](https://godoc.org/go.uber.org/zap) library pioneered this approach. Zerolog is taking this concept to the next level with a simpler to use API and even better performance.\n\nTo keep the code base and the API simple, zerolog focuses on efficient structured logging only. Pretty logging on the console is made possible using the provided (but inefficient) [`zerolog.ConsoleWriter`](#pretty-logging).\n\n![Pretty Logging Image](pretty.png)\n\n## Who uses zerolog\n\nFind out [who uses zerolog](https://github.com/rs/zerolog/wiki/Who-uses-zerolog) and add your company / project to the list.\n\n## Features\n\n* Blazing fast\n* Low to zero allocation\n* Level logging\n* Sampling\n* Hooks\n* Contextual fields\n* `context.Context` integration\n* `net/http` helpers\n* JSON and CBOR encoding formats\n* Pretty logging for development\n\n## Installation\n\n```bash\ngo get -u github.com/rs/zerolog/log\n```\n\n## Getting Started\n\n### Simple Logging Example\n\nFor simple logging, import the global logger package **github.com/rs/zerolog/log**\n\n```go\npackage main\n\nimport (\n    \"github.com/rs/zerolog\"\n    \"github.com/rs/zerolog/log\"\n)\n\nfunc main() {\n    // UNIX Time is faster and smaller than most timestamps\n    // If you set zerolog.TimeFieldFormat to an empty string,\n    // logs will write with UNIX time\n    zerolog.TimeFieldFormat = zerolog.TimeFormatUnix\n\n    log.Print(\"hello world\")\n}\n\n// Output: {\"time\":1516134303,\"level\":\"debug\",\"message\":\"hello world\"}\n```\n> Note: By default log writes to `os.Stderr`\n> Note: The default log level for `log.Print` is *debug*\n\n### Contextual Logging\n\n**zerolog** allows data to be added to log messages in the form of key:value pairs. The data added to the message adds \"context\" about the log event that can be critical for debugging as well as myriad other purposes. An example of this is below:\n\n```go\npackage main\n\nimport (\n    \"github.com/rs/zerolog\"\n    \"github.com/rs/zerolog/log\"\n)\n\nfunc main() {\n    zerolog.TimeFieldFormat = zerolog.TimeFormatUnix\n\n    log.Debug().\n        Str(\"Scale\", \"833 cents\").\n        Float64(\"Interval\", 833.09).\n        Msg(\"Fibonacci is everywhere\")\n    \n    log.Debug().\n        Str(\"Name\", \"Tom\").\n        Send()\n}\n\n// Output: {\"level\":\"debug\",\"Scale\":\"833 cents\",\"Interval\":833.09,\"time\":1562212768,\"message\":\"Fibonacci is everywhere\"}\n// Output: {\"level\":\"debug\",\"Name\":\"Tom\",\"time\":1562212768}\n```\n\n> You'll note in the above example that when adding contextual fields, the fields are strongly typed. You can find the full list of supported fields [here](#standard-types)\n\n### Leveled Logging\n\n#### Simple Leveled Logging Example\n\n```go\npackage main\n\nimport (\n    \"github.com/rs/zerolog\"\n    \"github.com/rs/zerolog/log\"\n)\n\nfunc main() {\n    zerolog.TimeFieldFormat = zerolog.TimeFormatUnix\n\n    log.Info().Msg(\"hello world\")\n}\n\n// Output: {\"time\":1516134303,\"level\":\"info\",\"message\":\"hello world\"}\n```\n\n> It is very important to note that when using the **zerolog** chaining API, as shown above (`log.Info().Msg(\"hello world\"`), the chain must have either the `Msg` or `Msgf` method call. If you forget to add either of these, the log will not occur and there is no compile time error to alert you of this.\n\n**zerolog** allows for logging at the following levels (from highest to lowest):\n\n* panic (`zerolog.PanicLevel`, 5)\n* fatal (`zerolog.FatalLevel`, 4)\n* error (`zerolog.ErrorLevel`, 3)\n* warn (`zerolog.WarnLevel`, 2)\n* info (`zerolog.InfoLevel`, 1)\n* debug (`zerolog.DebugLevel`, 0)\n* trace (`zerolog.TraceLevel`, -1)\n\nYou can set the Global logging level to any of these options using the `SetGlobalLevel` function in the zerolog package, passing in one of the given constants above, e.g. `zerolog.InfoLevel` would be the \"info\" level.  Whichever level is chosen, all logs with a level greater than or equal to that level will be written. To turn off logging entirely, pass the `zerolog.Disabled` constant.\n\n#### Setting Global Log Level\n\nThis example uses command-line flags to demonstrate various outputs depending on the chosen log level.\n\n```go\npackage main\n\nimport (\n    \"flag\"\n\n    \"github.com/rs/zerolog\"\n    \"github.com/rs/zerolog/log\"\n)\n\nfunc main() {\n    zerolog.TimeFieldFormat = zerolog.TimeFormatUnix\n    debug := flag.Bool(\"debug\", false, \"sets log level to debug\")\n\n    flag.Parse()\n\n    // Default level for this example is info, unless debug flag is present\n    zerolog.SetGlobalLevel(zerolog.InfoLevel)\n    if *debug {\n        zerolog.SetGlobalLevel(zerolog.DebugLevel)\n    }\n\n    log.Debug().Msg(\"This message appears only when log level set to Debug\")\n    log.Info().Msg(\"This message appears when log level set to Debug or Info\")\n\n    if e := log.Debug(); e.Enabled() {\n        // Compute log output only if enabled.\n        value := \"bar\"\n        e.Str(\"foo\", value).Msg(\"some debug message\")\n    }\n}\n```\n\nInfo Output (no flag)\n\n```bash\n$ ./logLevelExample\n{\"time\":1516387492,\"level\":\"info\",\"message\":\"This message appears when log level set to Debug or Info\"}\n```\n\nDebug Output (debug flag set)\n\n```bash\n$ ./logLevelExample -debug\n{\"time\":1516387573,\"level\":\"debug\",\"message\":\"This message appears only when log level set to Debug\"}\n{\"time\":1516387573,\"level\":\"info\",\"message\":\"This message appears when log level set to Debug or Info\"}\n{\"time\":1516387573,\"level\":\"debug\",\"foo\":\"bar\",\"message\":\"some debug message\"}\n```\n\n#### Logging without Level or Message\n\nYou may choose to log without a specific level by using the `Log` method. You may also write without a message by setting an empty string in the `msg string` parameter of the `Msg` method. Both are demonstrated in the example below.\n\n```go\npackage main\n\nimport (\n    \"github.com/rs/zerolog\"\n    \"github.com/rs/zerolog/log\"\n)\n\nfunc main() {\n    zerolog.TimeFieldFormat = zerolog.TimeFormatUnix\n\n    log.Log().\n        Str(\"foo\", \"bar\").\n        Msg(\"\")\n}\n\n// Output: {\"time\":1494567715,\"foo\":\"bar\"}\n```\n\n#### Logging Fatal Messages\n\n```go\npackage main\n\nimport (\n    \"errors\"\n\n    \"github.com/rs/zerolog\"\n    \"github.com/rs/zerolog/log\"\n)\n\nfunc main() {\n    err := errors.New(\"A repo man spends his life getting into tense situations\")\n    service := \"myservice\"\n\n    zerolog.TimeFieldFormat = zerolog.TimeFormatUnix\n\n    log.Fatal().\n        Err(err).\n        Str(\"service\", service).\n        Msgf(\"Cannot start %s\", service)\n}\n\n// Output: {\"time\":1516133263,\"level\":\"fatal\",\"error\":\"A repo man spends his life getting into tense situations\",\"service\":\"myservice\",\"message\":\"Cannot start myservice\"}\n//         exit status 1\n```\n\n> NOTE: Using `Msgf` generates one allocation even when the logger is disabled.\n\n### Create logger instance to manage different outputs\n\n```go\nlogger := zerolog.New(os.Stderr).With().Timestamp().Logger()\n\nlogger.Info().Str(\"foo\", \"bar\").Msg(\"hello world\")\n\n// Output: {\"level\":\"info\",\"time\":1494567715,\"message\":\"hello world\",\"foo\":\"bar\"}\n```\n\n### Sub-loggers let you chain loggers with additional context\n\n```go\nsublogger := log.With().\n                 Str(\"component\", \"foo\").\n                 Logger()\nsublogger.Info().Msg(\"hello world\")\n\n// Output: {\"level\":\"info\",\"time\":1494567715,\"message\":\"hello world\",\"component\":\"foo\"}\n```\n\n### Pretty logging\n\nTo log a human-friendly, colorized output, use `zerolog.ConsoleWriter`:\n\n```go\nlog.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})\n\nlog.Info().Str(\"foo\", \"bar\").Msg(\"Hello world\")\n\n// Output: 3:04PM INF Hello World foo=bar\n```\n\nTo customize the configuration and formatting:\n\n```go\noutput := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339}\noutput.FormatLevel = func(i interface{}) string {\n    return strings.ToUpper(fmt.Sprintf(\"| %-6s|\", i))\n}\noutput.FormatMessage = func(i interface{}) string {\n    return fmt.Sprintf(\"***%s****\", i)\n}\noutput.FormatFieldName = func(i interface{}) string {\n    return fmt.Sprintf(\"%s:\", i)\n}\noutput.FormatFieldValue = func(i interface{}) string {\n    return strings.ToUpper(fmt.Sprintf(\"%s\", i))\n}\n\nlog := zerolog.New(output).With().Timestamp().Logger()\n\nlog.Info().Str(\"foo\", \"bar\").Msg(\"Hello World\")\n\n// Output: 2006-01-02T15:04:05Z07:00 | INFO  | ***Hello World**** foo:BAR\n```\n\n### Sub dictionary\n\n```go\nlog.Info().\n    Str(\"foo\", \"bar\").\n    Dict(\"dict\", zerolog.Dict().\n        Str(\"bar\", \"baz\").\n        Int(\"n\", 1),\n    ).Msg(\"hello world\")\n\n// Output: {\"level\":\"info\",\"time\":1494567715,\"foo\":\"bar\",\"dict\":{\"bar\":\"baz\",\"n\":1},\"message\":\"hello world\"}\n```\n\n### Customize automatic field names\n\n```go\nzerolog.TimestampFieldName = \"t\"\nzerolog.LevelFieldName = \"l\"\nzerolog.MessageFieldName = \"m\"\n\nlog.Info().Msg(\"hello world\")\n\n// Output: {\"l\":\"info\",\"t\":1494567715,\"m\":\"hello world\"}\n```\n\n### Add contextual fields to the global logger\n\n```go\nlog.Logger = log.With().Str(\"foo\", \"bar\").Logger()\n```\n\n### Add file and line number to log\n\n```go\nlog.Logger = log.With().Caller().Logger()\nlog.Info().Msg(\"hello world\")\n\n// Output: {\"level\": \"info\", \"message\": \"hello world\", \"caller\": \"/go/src/your_project/some_file:21\"}\n```\n\n\n### Thread-safe, lock-free, non-blocking writer\n\nIf your writer might be slow or not thread-safe and you need your log producers to never get slowed down by a slow writer, you can use a `diode.Writer` as follow:\n\n```go\nwr := diode.NewWriter(os.Stdout, 1000, 10*time.Millisecond, func(missed int) {\n\t\tfmt.Printf(\"Logger Dropped %d messages\", missed)\n\t})\nlog := zerolog.New(wr)\nlog.Print(\"test\")\n```\n\nYou will need to install `code.cloudfoundry.org/go-diodes` to use this feature.\n\n### Log Sampling\n\n```go\nsampled := log.Sample(&zerolog.BasicSampler{N: 10})\nsampled.Info().Msg(\"will be logged every 10 messages\")\n\n// Output: {\"time\":1494567715,\"level\":\"info\",\"message\":\"will be logged every 10 messages\"}\n```\n\nMore advanced sampling:\n\n```go\n// Will let 5 debug messages per period of 1 second.\n// Over 5 debug message, 1 every 100 debug messages are logged.\n// Other levels are not sampled.\nsampled := log.Sample(zerolog.LevelSampler{\n    DebugSampler: &zerolog.BurstSampler{\n        Burst: 5,\n        Period: 1*time.Second,\n        NextSampler: &zerolog.BasicSampler{N: 100},\n    },\n})\nsampled.Debug().Msg(\"hello world\")\n\n// Output: {\"time\":1494567715,\"level\":\"debug\",\"message\":\"hello world\"}\n```\n\n### Hooks\n\n```go\ntype SeverityHook struct{}\n\nfunc (h SeverityHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {\n    if level != zerolog.NoLevel {\n        e.Str(\"severity\", level.String())\n    }\n}\n\nhooked := log.Hook(SeverityHook{})\nhooked.Warn().Msg(\"\")\n\n// Output: {\"level\":\"warn\",\"severity\":\"warn\"}\n```\n\n### Pass a sub-logger by context\n\n```go\nctx := log.With().Str(\"component\", \"module\").Logger().WithContext(ctx)\n\nlog.Ctx(ctx).Info().Msg(\"hello world\")\n\n// Output: {\"component\":\"module\",\"level\":\"info\",\"message\":\"hello world\"}\n```\n\n### Set as standard logger output\n\n```go\nlog := zerolog.New(os.Stdout).With().\n    Str(\"foo\", \"bar\").\n    Logger()\n\nstdlog.SetFlags(0)\nstdlog.SetOutput(log)\n\nstdlog.Print(\"hello world\")\n\n// Output: {\"foo\":\"bar\",\"message\":\"hello world\"}\n```\n\n### Integration with `net/http`\n\nThe `github.com/rs/zerolog/hlog` package provides some helpers to integrate zerolog with `http.Handler`.\n\nIn this example we use [alice](https://github.com/justinas/alice) to install logger for better readability.\n\n```go\nlog := zerolog.New(os.Stdout).With().\n    Timestamp().\n    Str(\"role\", \"my-service\").\n    Str(\"host\", host).\n    Logger()\n\nc := alice.New()\n\n// Install the logger handler with default output on the console\nc = c.Append(hlog.NewHandler(log))\n\n// Install some provided extra handler to set some request's context fields.\n// Thanks to that handler, all our logs will come with some prepopulated fields.\nc = c.Append(hlog.AccessHandler(func(r *http.Request, status, size int, duration time.Duration) {\n    hlog.FromRequest(r).Info().\n        Str(\"method\", r.Method).\n        Stringer(\"url\", r.URL).\n        Int(\"status\", status).\n        Int(\"size\", size).\n        Dur(\"duration\", duration).\n        Msg(\"\")\n}))\nc = c.Append(hlog.RemoteAddrHandler(\"ip\"))\nc = c.Append(hlog.UserAgentHandler(\"user_agent\"))\nc = c.Append(hlog.RefererHandler(\"referer\"))\nc = c.Append(hlog.RequestIDHandler(\"req_id\", \"Request-Id\"))\n\n// Here is your final handler\nh := c.Then(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n    // Get the logger from the request's context. You can safely assume it\n    // will be always there: if the handler is removed, hlog.FromRequest\n    // will return a no-op logger.\n    hlog.FromRequest(r).Info().\n        Str(\"user\", \"current user\").\n        Str(\"status\", \"ok\").\n        Msg(\"Something happened\")\n\n    // Output: {\"level\":\"info\",\"time\":\"2001-02-03T04:05:06Z\",\"role\":\"my-service\",\"host\":\"local-hostname\",\"req_id\":\"b4g0l5t6tfid6dtrapu0\",\"user\":\"current user\",\"status\":\"ok\",\"message\":\"Something happened\"}\n}))\nhttp.Handle(\"/\", h)\n\nif err := http.ListenAndServe(\":8080\", nil); err != nil {\n    log.Fatal().Err(err).Msg(\"Startup failed\")\n}\n```\n\n## Multiple Log Output\n`zerolog.MultiLevelWriter` may be used to send the log message to multiple outputs. \nIn this example, we send the log message to both `os.Stdout` and the in-built ConsoleWriter.\n```go\nfunc main() {\n\tconsoleWriter := zerolog.ConsoleWriter{Out: os.Stdout}\n\n\tmulti := zerolog.MultiLevelWriter(consoleWriter, os.Stdout)\n\n\tlogger := zerolog.New(multi).With().Timestamp().Logger()\n\n\tlogger.Info().Msg(\"Hello World!\")\n}\n\n// Output (Line 1: Console; Line 2: Stdout)\n// 12:36PM INF Hello World!\n// {\"level\":\"info\",\"time\":\"2019-11-07T12:36:38+03:00\",\"message\":\"Hello World!\"}\n``` \n\n## Global Settings\n\nSome settings can be changed and will by applied to all loggers:\n\n* `log.Logger`: You can set this value to customize the global logger (the one used by package level methods).\n* `zerolog.SetGlobalLevel`: Can raise the minimum level of all loggers. Call this with `zerolog.Disabled` to disable logging altogether (quiet mode).\n* `zerolog.DisableSampling`: If argument is `true`, all sampled loggers will stop sampling and issue 100% of their log events.\n* `zerolog.TimestampFieldName`: Can be set to customize `Timestamp` field name.\n* `zerolog.LevelFieldName`: Can be set to customize level field name.\n* `zerolog.MessageFieldName`: Can be set to customize message field name.\n* `zerolog.ErrorFieldName`: Can be set to customize `Err` field name.\n* `zerolog.TimeFieldFormat`: Can be set to customize `Time` field value formatting. If set with `zerolog.TimeFormatUnix`, `zerolog.TimeFormatUnixMs` or `zerolog.TimeFormatUnixMicro`, times are formated as UNIX timestamp.\n* `zerolog.DurationFieldUnit`: Can be set to customize the unit for time.Duration type fields added by `Dur` (default: `time.Millisecond`).\n* `zerolog.DurationFieldInteger`: If set to `true`, `Dur` fields are formatted as integers instead of floats (default: `false`). \n* `zerolog.ErrorHandler`: Called whenever zerolog fails to write an event on its output. If not set, an error is printed on the stderr. This handler must be thread safe and non-blocking.\n\n## Field Types\n\n### Standard Types\n\n* `Str`\n* `Bool`\n* `Int`, `Int8`, `Int16`, `Int32`, `Int64`\n* `Uint`, `Uint8`, `Uint16`, `Uint32`, `Uint64`\n* `Float32`, `Float64`\n\n### Advanced Fields\n\n* `Err`: Takes an `error` and renders it as a string using the `zerolog.ErrorFieldName` field name.\n* `Timestamp`: Inserts a timestamp field with `zerolog.TimestampFieldName` field name, formatted using `zerolog.TimeFieldFormat`.\n* `Time`: Adds a field with time formatted with `zerolog.TimeFieldFormat`.\n* `Dur`: Adds a field with `time.Duration`.\n* `Dict`: Adds a sub-key/value as a field of the event.\n* `RawJSON`: Adds a field with an already encoded JSON (`[]byte`)\n* `Hex`: Adds a field with value formatted as a hexadecimal string (`[]byte`)\n* `Interface`: Uses reflection to marshal the type.\n\nMost fields are also available in the slice format (`Strs` for `[]string`, `Errs` for `[]error` etc.)\n\n## Binary Encoding\n\nIn addition to the default JSON encoding, `zerolog` can produce binary logs using [CBOR](http://cbor.io) encoding. The choice of encoding can be decided at compile time using the build tag `binary_log` as follows:\n\n```bash\ngo build -tags binary_log .\n```\n\nTo Decode binary encoded log files you can use any CBOR decoder. One has been tested to work\nwith zerolog library is [CSD](https://github.com/toravir/csd/).\n\n## Related Projects\n\n* [grpc-zerolog](https://github.com/cheapRoc/grpc-zerolog): Implementation of `grpclog.LoggerV2` interface using `zerolog`\n\n## Benchmarks\n\nSee [logbench](http://hackemist.com/logbench/) for more comprehensive and up-to-date benchmarks.\n\nAll operations are allocation free (those numbers *include* JSON encoding):\n\n```text\nBenchmarkLogEmpty-8        100000000    19.1 ns/op     0 B/op       0 allocs/op\nBenchmarkDisabled-8        500000000    4.07 ns/op     0 B/op       0 allocs/op\nBenchmarkInfo-8            30000000     42.5 ns/op     0 B/op       0 allocs/op\nBenchmarkContextFields-8   30000000     44.9 ns/op     0 B/op       0 allocs/op\nBenchmarkLogFields-8       10000000     184 ns/op      0 B/op       0 allocs/op\n```\n\nThere are a few Go logging benchmarks and comparisons that include zerolog.\n\n* [imkira/go-loggers-bench](https://github.com/imkira/go-loggers-bench)\n* [uber-common/zap](https://github.com/uber-go/zap#performance)\n\nUsing Uber's zap comparison benchmark:\n\nLog a message and 10 fields:\n\n| Library | Time | Bytes Allocated | Objects Allocated |\n| :--- | :---: | :---: | :---: |\n| zerolog | 767 ns/op | 552 B/op | 6 allocs/op |\n| :zap: zap | 848 ns/op | 704 B/op | 2 allocs/op |\n| :zap: zap (sugared) | 1363 ns/op | 1610 B/op | 20 allocs/op |\n| go-kit | 3614 ns/op | 2895 B/op | 66 allocs/op |\n| lion | 5392 ns/op | 5807 B/op | 63 allocs/op |\n| logrus | 5661 ns/op | 6092 B/op | 78 allocs/op |\n| apex/log | 15332 ns/op | 3832 B/op | 65 allocs/op |\n| log15 | 20657 ns/op | 5632 B/op | 93 allocs/op |\n\nLog a message with a logger that already has 10 fields of context:\n\n| Library | Time | Bytes Allocated | Objects Allocated |\n| :--- | :---: | :---: | :---: |\n| zerolog | 52 ns/op | 0 B/op | 0 allocs/op |\n| :zap: zap | 283 ns/op | 0 B/op | 0 allocs/op |\n| :zap: zap (sugared) | 337 ns/op | 80 B/op | 2 allocs/op |\n| lion | 2702 ns/op | 4074 B/op | 38 allocs/op |\n| go-kit | 3378 ns/op | 3046 B/op | 52 allocs/op |\n| logrus | 4309 ns/op | 4564 B/op | 63 allocs/op |\n| apex/log | 13456 ns/op | 2898 B/op | 51 allocs/op |\n| log15 | 14179 ns/op | 2642 B/op | 44 allocs/op |\n\nLog a static string, without any context or `printf`-style templating:\n\n| Library | Time | Bytes Allocated | Objects Allocated |\n| :--- | :---: | :---: | :---: |\n| zerolog | 50 ns/op | 0 B/op | 0 allocs/op |\n| :zap: zap | 236 ns/op | 0 B/op | 0 allocs/op |\n| standard library | 453 ns/op | 80 B/op | 2 allocs/op |\n| :zap: zap (sugared) | 337 ns/op | 80 B/op | 2 allocs/op |\n| go-kit | 508 ns/op | 656 B/op | 13 allocs/op |\n| lion | 771 ns/op | 1224 B/op | 10 allocs/op |\n| logrus | 1244 ns/op | 1505 B/op | 27 allocs/op |\n| apex/log | 2751 ns/op | 584 B/op | 11 allocs/op |\n| log15 | 5181 ns/op | 1592 B/op | 26 allocs/op |\n\n## Caveats\n\nNote that zerolog does no de-duplication of fields. Using the same key multiple times creates multiple keys in final JSON:\n\n```go\nlogger := zerolog.New(os.Stderr).With().Timestamp().Logger()\nlogger.Info().\n       Timestamp().\n       Msg(\"dup\")\n// Output: {\"level\":\"info\",\"time\":1494567715,\"time\":1494567715,\"message\":\"dup\"}\n```\n\nIn this case, many consumers will take the last value, but this is not guaranteed; check yours if in doubt.\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/_config.yml",
    "content": "remote_theme: rs/gh-readme\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/array.go",
    "content": "package zerolog\n\nimport (\n\t\"net\"\n\t\"sync\"\n\t\"time\"\n)\n\nvar arrayPool = &sync.Pool{\n\tNew: func() interface{} {\n\t\treturn &Array{\n\t\t\tbuf: make([]byte, 0, 500),\n\t\t}\n\t},\n}\n\n// Array is used to prepopulate an array of items\n// which can be re-used to add to log messages.\ntype Array struct {\n\tbuf []byte\n}\n\nfunc putArray(a *Array) {\n\t// Proper usage of a sync.Pool requires each entry to have approximately\n\t// the same memory cost. To obtain this property when the stored type\n\t// contains a variably-sized buffer, we add a hard limit on the maximum buffer\n\t// to place back in the pool.\n\t//\n\t// See https://golang.org/issue/23199\n\tconst maxSize = 1 << 16 // 64KiB\n\tif cap(a.buf) > maxSize {\n\t\treturn\n\t}\n\tarrayPool.Put(a)\n}\n\n// Arr creates an array to be added to an Event or Context.\nfunc Arr() *Array {\n\ta := arrayPool.Get().(*Array)\n\ta.buf = a.buf[:0]\n\treturn a\n}\n\n// MarshalZerologArray method here is no-op - since data is\n// already in the needed format.\nfunc (*Array) MarshalZerologArray(*Array) {\n}\n\nfunc (a *Array) write(dst []byte) []byte {\n\tdst = enc.AppendArrayStart(dst)\n\tif len(a.buf) > 0 {\n\t\tdst = append(append(dst, a.buf...))\n\t}\n\tdst = enc.AppendArrayEnd(dst)\n\tputArray(a)\n\treturn dst\n}\n\n// Object marshals an object that implement the LogObjectMarshaler\n// interface and append append it to the array.\nfunc (a *Array) Object(obj LogObjectMarshaler) *Array {\n\te := Dict()\n\tobj.MarshalZerologObject(e)\n\te.buf = enc.AppendEndMarker(e.buf)\n\ta.buf = append(enc.AppendArrayDelim(a.buf), e.buf...)\n\tputEvent(e)\n\treturn a\n}\n\n// Str append append the val as a string to the array.\nfunc (a *Array) Str(val string) *Array {\n\ta.buf = enc.AppendString(enc.AppendArrayDelim(a.buf), val)\n\treturn a\n}\n\n// Bytes append append the val as a string to the array.\nfunc (a *Array) Bytes(val []byte) *Array {\n\ta.buf = enc.AppendBytes(enc.AppendArrayDelim(a.buf), val)\n\treturn a\n}\n\n// Hex append append the val as a hex string to the array.\nfunc (a *Array) Hex(val []byte) *Array {\n\ta.buf = enc.AppendHex(enc.AppendArrayDelim(a.buf), val)\n\treturn a\n}\n\n// RawJSON adds already encoded JSON to the array.\nfunc (a *Array) RawJSON(val []byte) *Array {\n\ta.buf = appendJSON(enc.AppendArrayDelim(a.buf), val)\n\treturn a\n}\n\n// Err serializes and appends the err to the array.\nfunc (a *Array) Err(err error) *Array {\n\tswitch m := ErrorMarshalFunc(err).(type) {\n\tcase LogObjectMarshaler:\n\t\te := newEvent(nil, 0)\n\t\te.buf = e.buf[:0]\n\t\te.appendObject(m)\n\t\ta.buf = append(enc.AppendArrayDelim(a.buf), e.buf...)\n\t\tputEvent(e)\n\tcase error:\n\t\tif m == nil || isNilValue(m) {\n\t\t\ta.buf = enc.AppendNil(enc.AppendArrayDelim(a.buf))\n\t\t} else {\n\t\t\ta.buf = enc.AppendString(enc.AppendArrayDelim(a.buf), m.Error())\n\t\t}\n\tcase string:\n\t\ta.buf = enc.AppendString(enc.AppendArrayDelim(a.buf), m)\n\tdefault:\n\t\ta.buf = enc.AppendInterface(enc.AppendArrayDelim(a.buf), m)\n\t}\n\n\treturn a\n}\n\n// Bool append append the val as a bool to the array.\nfunc (a *Array) Bool(b bool) *Array {\n\ta.buf = enc.AppendBool(enc.AppendArrayDelim(a.buf), b)\n\treturn a\n}\n\n// Int append append i as a int to the array.\nfunc (a *Array) Int(i int) *Array {\n\ta.buf = enc.AppendInt(enc.AppendArrayDelim(a.buf), i)\n\treturn a\n}\n\n// Int8 append append i as a int8 to the array.\nfunc (a *Array) Int8(i int8) *Array {\n\ta.buf = enc.AppendInt8(enc.AppendArrayDelim(a.buf), i)\n\treturn a\n}\n\n// Int16 append append i as a int16 to the array.\nfunc (a *Array) Int16(i int16) *Array {\n\ta.buf = enc.AppendInt16(enc.AppendArrayDelim(a.buf), i)\n\treturn a\n}\n\n// Int32 append append i as a int32 to the array.\nfunc (a *Array) Int32(i int32) *Array {\n\ta.buf = enc.AppendInt32(enc.AppendArrayDelim(a.buf), i)\n\treturn a\n}\n\n// Int64 append append i as a int64 to the array.\nfunc (a *Array) Int64(i int64) *Array {\n\ta.buf = enc.AppendInt64(enc.AppendArrayDelim(a.buf), i)\n\treturn a\n}\n\n// Uint append append i as a uint to the array.\nfunc (a *Array) Uint(i uint) *Array {\n\ta.buf = enc.AppendUint(enc.AppendArrayDelim(a.buf), i)\n\treturn a\n}\n\n// Uint8 append append i as a uint8 to the array.\nfunc (a *Array) Uint8(i uint8) *Array {\n\ta.buf = enc.AppendUint8(enc.AppendArrayDelim(a.buf), i)\n\treturn a\n}\n\n// Uint16 append append i as a uint16 to the array.\nfunc (a *Array) Uint16(i uint16) *Array {\n\ta.buf = enc.AppendUint16(enc.AppendArrayDelim(a.buf), i)\n\treturn a\n}\n\n// Uint32 append append i as a uint32 to the array.\nfunc (a *Array) Uint32(i uint32) *Array {\n\ta.buf = enc.AppendUint32(enc.AppendArrayDelim(a.buf), i)\n\treturn a\n}\n\n// Uint64 append append i as a uint64 to the array.\nfunc (a *Array) Uint64(i uint64) *Array {\n\ta.buf = enc.AppendUint64(enc.AppendArrayDelim(a.buf), i)\n\treturn a\n}\n\n// Float32 append append f as a float32 to the array.\nfunc (a *Array) Float32(f float32) *Array {\n\ta.buf = enc.AppendFloat32(enc.AppendArrayDelim(a.buf), f)\n\treturn a\n}\n\n// Float64 append append f as a float64 to the array.\nfunc (a *Array) Float64(f float64) *Array {\n\ta.buf = enc.AppendFloat64(enc.AppendArrayDelim(a.buf), f)\n\treturn a\n}\n\n// Time append append t formated as string using zerolog.TimeFieldFormat.\nfunc (a *Array) Time(t time.Time) *Array {\n\ta.buf = enc.AppendTime(enc.AppendArrayDelim(a.buf), t, TimeFieldFormat)\n\treturn a\n}\n\n// Dur append append d to the array.\nfunc (a *Array) Dur(d time.Duration) *Array {\n\ta.buf = enc.AppendDuration(enc.AppendArrayDelim(a.buf), d, DurationFieldUnit, DurationFieldInteger)\n\treturn a\n}\n\n// Interface append append i marshaled using reflection.\nfunc (a *Array) Interface(i interface{}) *Array {\n\tif obj, ok := i.(LogObjectMarshaler); ok {\n\t\treturn a.Object(obj)\n\t}\n\ta.buf = enc.AppendInterface(enc.AppendArrayDelim(a.buf), i)\n\treturn a\n}\n\n// IPAddr adds IPv4 or IPv6 address to the array\nfunc (a *Array) IPAddr(ip net.IP) *Array {\n\ta.buf = enc.AppendIPAddr(enc.AppendArrayDelim(a.buf), ip)\n\treturn a\n}\n\n// IPPrefix adds IPv4 or IPv6 Prefix (IP + mask) to the array\nfunc (a *Array) IPPrefix(pfx net.IPNet) *Array {\n\ta.buf = enc.AppendIPPrefix(enc.AppendArrayDelim(a.buf), pfx)\n\treturn a\n}\n\n// MACAddr adds a MAC (Ethernet) address to the array\nfunc (a *Array) MACAddr(ha net.HardwareAddr) *Array {\n\ta.buf = enc.AppendMACAddr(enc.AppendArrayDelim(a.buf), ha)\n\treturn a\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/console.go",
    "content": "package zerolog\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\nconst (\n\tcolorBlack = iota + 30\n\tcolorRed\n\tcolorGreen\n\tcolorYellow\n\tcolorBlue\n\tcolorMagenta\n\tcolorCyan\n\tcolorWhite\n\n\tcolorBold     = 1\n\tcolorDarkGray = 90\n)\n\nvar (\n\tconsoleBufPool = sync.Pool{\n\t\tNew: func() interface{} {\n\t\t\treturn bytes.NewBuffer(make([]byte, 0, 100))\n\t\t},\n\t}\n)\n\nconst (\n\tconsoleDefaultTimeFormat = time.Kitchen\n)\n\n// Formatter transforms the input into a formatted string.\ntype Formatter func(interface{}) string\n\n// ConsoleWriter parses the JSON input and writes it in an\n// (optionally) colorized, human-friendly format to Out.\ntype ConsoleWriter struct {\n\t// Out is the output destination.\n\tOut io.Writer\n\n\t// NoColor disables the colorized output.\n\tNoColor bool\n\n\t// TimeFormat specifies the format for timestamp in output.\n\tTimeFormat string\n\n\t// PartsOrder defines the order of parts in output.\n\tPartsOrder []string\n\n\tFormatTimestamp     Formatter\n\tFormatLevel         Formatter\n\tFormatCaller        Formatter\n\tFormatMessage       Formatter\n\tFormatFieldName     Formatter\n\tFormatFieldValue    Formatter\n\tFormatErrFieldName  Formatter\n\tFormatErrFieldValue Formatter\n}\n\n// NewConsoleWriter creates and initializes a new ConsoleWriter.\nfunc NewConsoleWriter(options ...func(w *ConsoleWriter)) ConsoleWriter {\n\tw := ConsoleWriter{\n\t\tOut:        os.Stdout,\n\t\tTimeFormat: consoleDefaultTimeFormat,\n\t\tPartsOrder: consoleDefaultPartsOrder(),\n\t}\n\n\tfor _, opt := range options {\n\t\topt(&w)\n\t}\n\n\treturn w\n}\n\n// Write transforms the JSON input with formatters and appends to w.Out.\nfunc (w ConsoleWriter) Write(p []byte) (n int, err error) {\n\tif w.PartsOrder == nil {\n\t\tw.PartsOrder = consoleDefaultPartsOrder()\n\t}\n\n\tvar buf = consoleBufPool.Get().(*bytes.Buffer)\n\tdefer func() {\n\t\tbuf.Reset()\n\t\tconsoleBufPool.Put(buf)\n\t}()\n\n\tvar evt map[string]interface{}\n\tp = decodeIfBinaryToBytes(p)\n\td := json.NewDecoder(bytes.NewReader(p))\n\td.UseNumber()\n\terr = d.Decode(&evt)\n\tif err != nil {\n\t\treturn n, fmt.Errorf(\"cannot decode event: %s\", err)\n\t}\n\n\tfor _, p := range w.PartsOrder {\n\t\tw.writePart(buf, evt, p)\n\t}\n\n\tw.writeFields(evt, buf)\n\n\terr = buf.WriteByte('\\n')\n\tif err != nil {\n\t\treturn n, err\n\t}\n\t_, err = buf.WriteTo(w.Out)\n\treturn len(p), err\n}\n\n// writeFields appends formatted key-value pairs to buf.\nfunc (w ConsoleWriter) writeFields(evt map[string]interface{}, buf *bytes.Buffer) {\n\tvar fields = make([]string, 0, len(evt))\n\tfor field := range evt {\n\t\tswitch field {\n\t\tcase LevelFieldName, TimestampFieldName, MessageFieldName, CallerFieldName:\n\t\t\tcontinue\n\t\t}\n\t\tfields = append(fields, field)\n\t}\n\tsort.Strings(fields)\n\n\tif len(fields) > 0 {\n\t\tbuf.WriteByte(' ')\n\t}\n\n\t// Move the \"error\" field to the front\n\tei := sort.Search(len(fields), func(i int) bool { return fields[i] >= ErrorFieldName })\n\tif ei < len(fields) && fields[ei] == ErrorFieldName {\n\t\tfields[ei] = \"\"\n\t\tfields = append([]string{ErrorFieldName}, fields...)\n\t\tvar xfields = make([]string, 0, len(fields))\n\t\tfor _, field := range fields {\n\t\t\tif field == \"\" { // Skip empty fields\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\txfields = append(xfields, field)\n\t\t}\n\t\tfields = xfields\n\t}\n\n\tfor i, field := range fields {\n\t\tvar fn Formatter\n\t\tvar fv Formatter\n\n\t\tif field == ErrorFieldName {\n\t\t\tif w.FormatErrFieldName == nil {\n\t\t\t\tfn = consoleDefaultFormatErrFieldName(w.NoColor)\n\t\t\t} else {\n\t\t\t\tfn = w.FormatErrFieldName\n\t\t\t}\n\n\t\t\tif w.FormatErrFieldValue == nil {\n\t\t\t\tfv = consoleDefaultFormatErrFieldValue(w.NoColor)\n\t\t\t} else {\n\t\t\t\tfv = w.FormatErrFieldValue\n\t\t\t}\n\t\t} else {\n\t\t\tif w.FormatFieldName == nil {\n\t\t\t\tfn = consoleDefaultFormatFieldName(w.NoColor)\n\t\t\t} else {\n\t\t\t\tfn = w.FormatFieldName\n\t\t\t}\n\n\t\t\tif w.FormatFieldValue == nil {\n\t\t\t\tfv = consoleDefaultFormatFieldValue\n\t\t\t} else {\n\t\t\t\tfv = w.FormatFieldValue\n\t\t\t}\n\t\t}\n\n\t\tbuf.WriteString(fn(field))\n\n\t\tswitch fValue := evt[field].(type) {\n\t\tcase string:\n\t\t\tif needsQuote(fValue) {\n\t\t\t\tbuf.WriteString(fv(strconv.Quote(fValue)))\n\t\t\t} else {\n\t\t\t\tbuf.WriteString(fv(fValue))\n\t\t\t}\n\t\tcase json.Number:\n\t\t\tbuf.WriteString(fv(fValue))\n\t\tdefault:\n\t\t\tb, err := json.Marshal(fValue)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Fprintf(buf, colorize(\"[error: %v]\", colorRed, w.NoColor), err)\n\t\t\t} else {\n\t\t\t\tfmt.Fprint(buf, fv(b))\n\t\t\t}\n\t\t}\n\n\t\tif i < len(fields)-1 { // Skip space for last field\n\t\t\tbuf.WriteByte(' ')\n\t\t}\n\t}\n}\n\n// writePart appends a formatted part to buf.\nfunc (w ConsoleWriter) writePart(buf *bytes.Buffer, evt map[string]interface{}, p string) {\n\tvar f Formatter\n\n\tswitch p {\n\tcase LevelFieldName:\n\t\tif w.FormatLevel == nil {\n\t\t\tf = consoleDefaultFormatLevel(w.NoColor)\n\t\t} else {\n\t\t\tf = w.FormatLevel\n\t\t}\n\tcase TimestampFieldName:\n\t\tif w.FormatTimestamp == nil {\n\t\t\tf = consoleDefaultFormatTimestamp(w.TimeFormat, w.NoColor)\n\t\t} else {\n\t\t\tf = w.FormatTimestamp\n\t\t}\n\tcase MessageFieldName:\n\t\tif w.FormatMessage == nil {\n\t\t\tf = consoleDefaultFormatMessage\n\t\t} else {\n\t\t\tf = w.FormatMessage\n\t\t}\n\tcase CallerFieldName:\n\t\tif w.FormatCaller == nil {\n\t\t\tf = consoleDefaultFormatCaller(w.NoColor)\n\t\t} else {\n\t\t\tf = w.FormatCaller\n\t\t}\n\tdefault:\n\t\tif w.FormatFieldValue == nil {\n\t\t\tf = consoleDefaultFormatFieldValue\n\t\t} else {\n\t\t\tf = w.FormatFieldValue\n\t\t}\n\t}\n\n\tvar s = f(evt[p])\n\n\tif len(s) > 0 {\n\t\tbuf.WriteString(s)\n\t\tif p != w.PartsOrder[len(w.PartsOrder)-1] { // Skip space for last part\n\t\t\tbuf.WriteByte(' ')\n\t\t}\n\t}\n}\n\n// needsQuote returns true when the string s should be quoted in output.\nfunc needsQuote(s string) bool {\n\tfor i := range s {\n\t\tif s[i] < 0x20 || s[i] > 0x7e || s[i] == ' ' || s[i] == '\\\\' || s[i] == '\"' {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// colorize returns the string s wrapped in ANSI code c, unless disabled is true.\nfunc colorize(s interface{}, c int, disabled bool) string {\n\tif disabled {\n\t\treturn fmt.Sprintf(\"%s\", s)\n\t}\n\treturn fmt.Sprintf(\"\\x1b[%dm%v\\x1b[0m\", c, s)\n}\n\n// ----- DEFAULT FORMATTERS ---------------------------------------------------\n\nfunc consoleDefaultPartsOrder() []string {\n\treturn []string{\n\t\tTimestampFieldName,\n\t\tLevelFieldName,\n\t\tCallerFieldName,\n\t\tMessageFieldName,\n\t}\n}\n\nfunc consoleDefaultFormatTimestamp(timeFormat string, noColor bool) Formatter {\n\tif timeFormat == \"\" {\n\t\ttimeFormat = consoleDefaultTimeFormat\n\t}\n\treturn func(i interface{}) string {\n\t\tt := \"<nil>\"\n\t\tswitch tt := i.(type) {\n\t\tcase string:\n\t\t\tts, err := time.Parse(TimeFieldFormat, tt)\n\t\t\tif err != nil {\n\t\t\t\tt = tt\n\t\t\t} else {\n\t\t\t\tt = ts.Format(timeFormat)\n\t\t\t}\n\t\tcase json.Number:\n\t\t\ti, err := tt.Int64()\n\t\t\tif err != nil {\n\t\t\t\tt = tt.String()\n\t\t\t} else {\n\t\t\t\tvar sec, nsec int64 = i, 0\n\t\t\t\tswitch TimeFieldFormat {\n\t\t\t\tcase TimeFormatUnixMs:\n\t\t\t\t\tnsec = int64(time.Duration(i) * time.Millisecond)\n\t\t\t\t\tsec = 0\n\t\t\t\tcase TimeFormatUnixMicro:\n\t\t\t\t\tnsec = int64(time.Duration(i) * time.Microsecond)\n\t\t\t\t\tsec = 0\n\t\t\t\t}\n\t\t\t\tts := time.Unix(sec, nsec).UTC()\n\t\t\t\tt = ts.Format(timeFormat)\n\t\t\t}\n\t\t}\n\t\treturn colorize(t, colorDarkGray, noColor)\n\t}\n}\n\nfunc consoleDefaultFormatLevel(noColor bool) Formatter {\n\treturn func(i interface{}) string {\n\t\tvar l string\n\t\tif ll, ok := i.(string); ok {\n\t\t\tswitch ll {\n\t\t\tcase \"trace\":\n\t\t\t\tl = colorize(\"TRC\", colorMagenta, noColor)\n\t\t\tcase \"debug\":\n\t\t\t\tl = colorize(\"DBG\", colorYellow, noColor)\n\t\t\tcase \"info\":\n\t\t\t\tl = colorize(\"INF\", colorGreen, noColor)\n\t\t\tcase \"warn\":\n\t\t\t\tl = colorize(\"WRN\", colorRed, noColor)\n\t\t\tcase \"error\":\n\t\t\t\tl = colorize(colorize(\"ERR\", colorRed, noColor), colorBold, noColor)\n\t\t\tcase \"fatal\":\n\t\t\t\tl = colorize(colorize(\"FTL\", colorRed, noColor), colorBold, noColor)\n\t\t\tcase \"panic\":\n\t\t\t\tl = colorize(colorize(\"PNC\", colorRed, noColor), colorBold, noColor)\n\t\t\tdefault:\n\t\t\t\tl = colorize(\"???\", colorBold, noColor)\n\t\t\t}\n\t\t} else {\n\t\t\tif i == nil {\n\t\t\t\tl = colorize(\"???\", colorBold, noColor)\n\t\t\t} else {\n\t\t\t\tl = strings.ToUpper(fmt.Sprintf(\"%s\", i))[0:3]\n\t\t\t}\n\t\t}\n\t\treturn l\n\t}\n}\n\nfunc consoleDefaultFormatCaller(noColor bool) Formatter {\n\treturn func(i interface{}) string {\n\t\tvar c string\n\t\tif cc, ok := i.(string); ok {\n\t\t\tc = cc\n\t\t}\n\t\tif len(c) > 0 {\n\t\t\tcwd, err := os.Getwd()\n\t\t\tif err == nil {\n\t\t\t\tc = strings.TrimPrefix(c, cwd)\n\t\t\t\tc = strings.TrimPrefix(c, \"/\")\n\t\t\t}\n\t\t\tc = colorize(c, colorBold, noColor) + colorize(\" >\", colorCyan, noColor)\n\t\t}\n\t\treturn c\n\t}\n}\n\nfunc consoleDefaultFormatMessage(i interface{}) string {\n\tif i == nil {\n\t\treturn \"\"\n\t}\n\treturn fmt.Sprintf(\"%s\", i)\n}\n\nfunc consoleDefaultFormatFieldName(noColor bool) Formatter {\n\treturn func(i interface{}) string {\n\t\treturn colorize(fmt.Sprintf(\"%s=\", i), colorCyan, noColor)\n\t}\n}\n\nfunc consoleDefaultFormatFieldValue(i interface{}) string {\n\treturn fmt.Sprintf(\"%s\", i)\n}\n\nfunc consoleDefaultFormatErrFieldName(noColor bool) Formatter {\n\treturn func(i interface{}) string {\n\t\treturn colorize(fmt.Sprintf(\"%s=\", i), colorRed, noColor)\n\t}\n}\n\nfunc consoleDefaultFormatErrFieldValue(noColor bool) Formatter {\n\treturn func(i interface{}) string {\n\t\treturn colorize(fmt.Sprintf(\"%s\", i), colorRed, noColor)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/context.go",
    "content": "package zerolog\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"math\"\n\t\"net\"\n\t\"time\"\n)\n\n// Context configures a new sub-logger with contextual fields.\ntype Context struct {\n\tl Logger\n}\n\n// Logger returns the logger with the context previously set.\nfunc (c Context) Logger() Logger {\n\treturn c.l\n}\n\n// Fields is a helper function to use a map to set fields using type assertion.\nfunc (c Context) Fields(fields map[string]interface{}) Context {\n\tc.l.context = appendFields(c.l.context, fields)\n\treturn c\n}\n\n// Dict adds the field key with the dict to the logger context.\nfunc (c Context) Dict(key string, dict *Event) Context {\n\tdict.buf = enc.AppendEndMarker(dict.buf)\n\tc.l.context = append(enc.AppendKey(c.l.context, key), dict.buf...)\n\tputEvent(dict)\n\treturn c\n}\n\n// Array adds the field key with an array to the event context.\n// Use zerolog.Arr() to create the array or pass a type that\n// implement the LogArrayMarshaler interface.\nfunc (c Context) Array(key string, arr LogArrayMarshaler) Context {\n\tc.l.context = enc.AppendKey(c.l.context, key)\n\tif arr, ok := arr.(*Array); ok {\n\t\tc.l.context = arr.write(c.l.context)\n\t\treturn c\n\t}\n\tvar a *Array\n\tif aa, ok := arr.(*Array); ok {\n\t\ta = aa\n\t} else {\n\t\ta = Arr()\n\t\tarr.MarshalZerologArray(a)\n\t}\n\tc.l.context = a.write(c.l.context)\n\treturn c\n}\n\n// Object marshals an object that implement the LogObjectMarshaler interface.\nfunc (c Context) Object(key string, obj LogObjectMarshaler) Context {\n\te := newEvent(levelWriterAdapter{ioutil.Discard}, 0)\n\te.Object(key, obj)\n\tc.l.context = enc.AppendObjectData(c.l.context, e.buf)\n\tputEvent(e)\n\treturn c\n}\n\n// EmbedObject marshals and Embeds an object that implement the LogObjectMarshaler interface.\nfunc (c Context) EmbedObject(obj LogObjectMarshaler) Context {\n\te := newEvent(levelWriterAdapter{ioutil.Discard}, 0)\n\te.EmbedObject(obj)\n\tc.l.context = enc.AppendObjectData(c.l.context, e.buf)\n\tputEvent(e)\n\treturn c\n}\n\n// Str adds the field key with val as a string to the logger context.\nfunc (c Context) Str(key, val string) Context {\n\tc.l.context = enc.AppendString(enc.AppendKey(c.l.context, key), val)\n\treturn c\n}\n\n// Strs adds the field key with val as a string to the logger context.\nfunc (c Context) Strs(key string, vals []string) Context {\n\tc.l.context = enc.AppendStrings(enc.AppendKey(c.l.context, key), vals)\n\treturn c\n}\n\n// Stringer adds the field key with val.String() (or null if val is nil) to the logger context.\nfunc (c Context) Stringer(key string, val fmt.Stringer) Context {\n\tif val != nil {\n\t\tc.l.context = enc.AppendString(enc.AppendKey(c.l.context, key), val.String())\n\t\treturn c\n\t}\n\n\tc.l.context = enc.AppendInterface(enc.AppendKey(c.l.context, key), nil)\n\treturn c\n}\n\n// Bytes adds the field key with val as a []byte to the logger context.\nfunc (c Context) Bytes(key string, val []byte) Context {\n\tc.l.context = enc.AppendBytes(enc.AppendKey(c.l.context, key), val)\n\treturn c\n}\n\n// Hex adds the field key with val as a hex string to the logger context.\nfunc (c Context) Hex(key string, val []byte) Context {\n\tc.l.context = enc.AppendHex(enc.AppendKey(c.l.context, key), val)\n\treturn c\n}\n\n// RawJSON adds already encoded JSON to context.\n//\n// No sanity check is performed on b; it must not contain carriage returns and\n// be valid JSON.\nfunc (c Context) RawJSON(key string, b []byte) Context {\n\tc.l.context = appendJSON(enc.AppendKey(c.l.context, key), b)\n\treturn c\n}\n\n// AnErr adds the field key with serialized err to the logger context.\nfunc (c Context) AnErr(key string, err error) Context {\n\tswitch m := ErrorMarshalFunc(err).(type) {\n\tcase nil:\n\t\treturn c\n\tcase LogObjectMarshaler:\n\t\treturn c.Object(key, m)\n\tcase error:\n\t\tif m == nil || isNilValue(m) {\n\t\t\treturn c\n\t\t} else {\n\t\t\treturn c.Str(key, m.Error())\n\t\t}\n\tcase string:\n\t\treturn c.Str(key, m)\n\tdefault:\n\t\treturn c.Interface(key, m)\n\t}\n}\n\n// Errs adds the field key with errs as an array of serialized errors to the\n// logger context.\nfunc (c Context) Errs(key string, errs []error) Context {\n\tarr := Arr()\n\tfor _, err := range errs {\n\t\tswitch m := ErrorMarshalFunc(err).(type) {\n\t\tcase LogObjectMarshaler:\n\t\t\tarr = arr.Object(m)\n\t\tcase error:\n\t\t\tif m == nil || isNilValue(m) {\n\t\t\t\tarr = arr.Interface(nil)\n\t\t\t} else {\n\t\t\t\tarr = arr.Str(m.Error())\n\t\t\t}\n\t\tcase string:\n\t\t\tarr = arr.Str(m)\n\t\tdefault:\n\t\t\tarr = arr.Interface(m)\n\t\t}\n\t}\n\n\treturn c.Array(key, arr)\n}\n\n// Err adds the field \"error\" with serialized err to the logger context.\nfunc (c Context) Err(err error) Context {\n\treturn c.AnErr(ErrorFieldName, err)\n}\n\n// Bool adds the field key with val as a bool to the logger context.\nfunc (c Context) Bool(key string, b bool) Context {\n\tc.l.context = enc.AppendBool(enc.AppendKey(c.l.context, key), b)\n\treturn c\n}\n\n// Bools adds the field key with val as a []bool to the logger context.\nfunc (c Context) Bools(key string, b []bool) Context {\n\tc.l.context = enc.AppendBools(enc.AppendKey(c.l.context, key), b)\n\treturn c\n}\n\n// Int adds the field key with i as a int to the logger context.\nfunc (c Context) Int(key string, i int) Context {\n\tc.l.context = enc.AppendInt(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Ints adds the field key with i as a []int to the logger context.\nfunc (c Context) Ints(key string, i []int) Context {\n\tc.l.context = enc.AppendInts(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Int8 adds the field key with i as a int8 to the logger context.\nfunc (c Context) Int8(key string, i int8) Context {\n\tc.l.context = enc.AppendInt8(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Ints8 adds the field key with i as a []int8 to the logger context.\nfunc (c Context) Ints8(key string, i []int8) Context {\n\tc.l.context = enc.AppendInts8(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Int16 adds the field key with i as a int16 to the logger context.\nfunc (c Context) Int16(key string, i int16) Context {\n\tc.l.context = enc.AppendInt16(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Ints16 adds the field key with i as a []int16 to the logger context.\nfunc (c Context) Ints16(key string, i []int16) Context {\n\tc.l.context = enc.AppendInts16(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Int32 adds the field key with i as a int32 to the logger context.\nfunc (c Context) Int32(key string, i int32) Context {\n\tc.l.context = enc.AppendInt32(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Ints32 adds the field key with i as a []int32 to the logger context.\nfunc (c Context) Ints32(key string, i []int32) Context {\n\tc.l.context = enc.AppendInts32(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Int64 adds the field key with i as a int64 to the logger context.\nfunc (c Context) Int64(key string, i int64) Context {\n\tc.l.context = enc.AppendInt64(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Ints64 adds the field key with i as a []int64 to the logger context.\nfunc (c Context) Ints64(key string, i []int64) Context {\n\tc.l.context = enc.AppendInts64(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Uint adds the field key with i as a uint to the logger context.\nfunc (c Context) Uint(key string, i uint) Context {\n\tc.l.context = enc.AppendUint(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Uints adds the field key with i as a []uint to the logger context.\nfunc (c Context) Uints(key string, i []uint) Context {\n\tc.l.context = enc.AppendUints(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Uint8 adds the field key with i as a uint8 to the logger context.\nfunc (c Context) Uint8(key string, i uint8) Context {\n\tc.l.context = enc.AppendUint8(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Uints8 adds the field key with i as a []uint8 to the logger context.\nfunc (c Context) Uints8(key string, i []uint8) Context {\n\tc.l.context = enc.AppendUints8(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Uint16 adds the field key with i as a uint16 to the logger context.\nfunc (c Context) Uint16(key string, i uint16) Context {\n\tc.l.context = enc.AppendUint16(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Uints16 adds the field key with i as a []uint16 to the logger context.\nfunc (c Context) Uints16(key string, i []uint16) Context {\n\tc.l.context = enc.AppendUints16(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Uint32 adds the field key with i as a uint32 to the logger context.\nfunc (c Context) Uint32(key string, i uint32) Context {\n\tc.l.context = enc.AppendUint32(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Uints32 adds the field key with i as a []uint32 to the logger context.\nfunc (c Context) Uints32(key string, i []uint32) Context {\n\tc.l.context = enc.AppendUints32(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Uint64 adds the field key with i as a uint64 to the logger context.\nfunc (c Context) Uint64(key string, i uint64) Context {\n\tc.l.context = enc.AppendUint64(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Uints64 adds the field key with i as a []uint64 to the logger context.\nfunc (c Context) Uints64(key string, i []uint64) Context {\n\tc.l.context = enc.AppendUints64(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\n// Float32 adds the field key with f as a float32 to the logger context.\nfunc (c Context) Float32(key string, f float32) Context {\n\tc.l.context = enc.AppendFloat32(enc.AppendKey(c.l.context, key), f)\n\treturn c\n}\n\n// Floats32 adds the field key with f as a []float32 to the logger context.\nfunc (c Context) Floats32(key string, f []float32) Context {\n\tc.l.context = enc.AppendFloats32(enc.AppendKey(c.l.context, key), f)\n\treturn c\n}\n\n// Float64 adds the field key with f as a float64 to the logger context.\nfunc (c Context) Float64(key string, f float64) Context {\n\tc.l.context = enc.AppendFloat64(enc.AppendKey(c.l.context, key), f)\n\treturn c\n}\n\n// Floats64 adds the field key with f as a []float64 to the logger context.\nfunc (c Context) Floats64(key string, f []float64) Context {\n\tc.l.context = enc.AppendFloats64(enc.AppendKey(c.l.context, key), f)\n\treturn c\n}\n\ntype timestampHook struct{}\n\nfunc (ts timestampHook) Run(e *Event, level Level, msg string) {\n\te.Timestamp()\n}\n\nvar th = timestampHook{}\n\n// Timestamp adds the current local time as UNIX timestamp to the logger context with the \"time\" key.\n// To customize the key name, change zerolog.TimestampFieldName.\n//\n// NOTE: It won't dedupe the \"time\" key if the *Context has one already.\nfunc (c Context) Timestamp() Context {\n\tc.l = c.l.Hook(th)\n\treturn c\n}\n\n// Time adds the field key with t formated as string using zerolog.TimeFieldFormat.\nfunc (c Context) Time(key string, t time.Time) Context {\n\tc.l.context = enc.AppendTime(enc.AppendKey(c.l.context, key), t, TimeFieldFormat)\n\treturn c\n}\n\n// Times adds the field key with t formated as string using zerolog.TimeFieldFormat.\nfunc (c Context) Times(key string, t []time.Time) Context {\n\tc.l.context = enc.AppendTimes(enc.AppendKey(c.l.context, key), t, TimeFieldFormat)\n\treturn c\n}\n\n// Dur adds the fields key with d divided by unit and stored as a float.\nfunc (c Context) Dur(key string, d time.Duration) Context {\n\tc.l.context = enc.AppendDuration(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger)\n\treturn c\n}\n\n// Durs adds the fields key with d divided by unit and stored as a float.\nfunc (c Context) Durs(key string, d []time.Duration) Context {\n\tc.l.context = enc.AppendDurations(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger)\n\treturn c\n}\n\n// Interface adds the field key with obj marshaled using reflection.\nfunc (c Context) Interface(key string, i interface{}) Context {\n\tc.l.context = enc.AppendInterface(enc.AppendKey(c.l.context, key), i)\n\treturn c\n}\n\ntype callerHook struct {\n\tcallerSkipFrameCount int\n}\n\nfunc newCallerHook(skipFrameCount int) callerHook {\n\treturn callerHook{callerSkipFrameCount: skipFrameCount}\n}\n\nfunc (ch callerHook) Run(e *Event, level Level, msg string) {\n\tswitch ch.callerSkipFrameCount {\n\tcase useGlobalSkipFrameCount:\n\t\t// Extra frames to skip (added by hook infra).\n\t\te.caller(CallerSkipFrameCount + contextCallerSkipFrameCount)\n\tdefault:\n\t\t// Extra frames to skip (added by hook infra).\n\t\te.caller(ch.callerSkipFrameCount + contextCallerSkipFrameCount)\n\t}\n}\n\n// useGlobalSkipFrameCount acts as a flag to informat callerHook.Run\n// to use the global CallerSkipFrameCount.\nconst useGlobalSkipFrameCount = math.MinInt32\n\n// ch is the default caller hook using the global CallerSkipFrameCount.\nvar ch = newCallerHook(useGlobalSkipFrameCount)\n\n// Caller adds the file:line of the caller with the zerolog.CallerFieldName key.\nfunc (c Context) Caller() Context {\n\tc.l = c.l.Hook(ch)\n\treturn c\n}\n\n// CallerWithSkipFrameCount adds the file:line of the caller with the zerolog.CallerFieldName key.\n// The specified skipFrameCount int will override the global CallerSkipFrameCount for this context's respective logger.\n// If set to -1 the global CallerSkipFrameCount will be used.\nfunc (c Context) CallerWithSkipFrameCount(skipFrameCount int) Context {\n\tc.l = c.l.Hook(newCallerHook(skipFrameCount))\n\treturn c\n}\n\ntype stackTraceHook struct{}\n\nfunc (sh stackTraceHook) Run(e *Event, level Level, msg string) {\n\te.Stack()\n}\n\nvar sh = stackTraceHook{}\n\n// Stack enables stack trace printing for the error passed to Err().\nfunc (c Context) Stack() Context {\n\tc.l = c.l.Hook(sh)\n\treturn c\n}\n\n// IPAddr adds IPv4 or IPv6 Address to the context\nfunc (c Context) IPAddr(key string, ip net.IP) Context {\n\tc.l.context = enc.AppendIPAddr(enc.AppendKey(c.l.context, key), ip)\n\treturn c\n}\n\n// IPPrefix adds IPv4 or IPv6 Prefix (address and mask) to the context\nfunc (c Context) IPPrefix(key string, pfx net.IPNet) Context {\n\tc.l.context = enc.AppendIPPrefix(enc.AppendKey(c.l.context, key), pfx)\n\treturn c\n}\n\n// MACAddr adds MAC address to the context\nfunc (c Context) MACAddr(key string, ha net.HardwareAddr) Context {\n\tc.l.context = enc.AppendMACAddr(enc.AppendKey(c.l.context, key), ha)\n\treturn c\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/ctx.go",
    "content": "package zerolog\n\nimport (\n\t\"context\"\n)\n\nvar disabledLogger *Logger\n\nfunc init() {\n\tSetGlobalLevel(TraceLevel)\n\tl := Nop()\n\tdisabledLogger = &l\n}\n\ntype ctxKey struct{}\n\n// WithContext returns a copy of ctx with l associated. If an instance of Logger\n// is already in the context, the context is not updated.\n//\n// For instance, to add a field to an existing logger in the context, use this\n// notation:\n//\n//     ctx := r.Context()\n//     l := zerolog.Ctx(ctx)\n//     l.UpdateContext(func(c Context) Context {\n//         return c.Str(\"bar\", \"baz\")\n//     })\nfunc (l *Logger) WithContext(ctx context.Context) context.Context {\n\tif lp, ok := ctx.Value(ctxKey{}).(*Logger); ok {\n\t\tif lp == l {\n\t\t\t// Do not store same logger.\n\t\t\treturn ctx\n\t\t}\n\t} else if l.level == Disabled {\n\t\t// Do not store disabled logger.\n\t\treturn ctx\n\t}\n\treturn context.WithValue(ctx, ctxKey{}, l)\n}\n\n// Ctx returns the Logger associated with the ctx. If no logger\n// is associated, a disabled logger is returned.\nfunc Ctx(ctx context.Context) *Logger {\n\tif l, ok := ctx.Value(ctxKey{}).(*Logger); ok {\n\t\treturn l\n\t}\n\treturn disabledLogger\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/encoder.go",
    "content": "package zerolog\n\nimport (\n\t\"net\"\n\t\"time\"\n)\n\ntype encoder interface {\n\tAppendArrayDelim(dst []byte) []byte\n\tAppendArrayEnd(dst []byte) []byte\n\tAppendArrayStart(dst []byte) []byte\n\tAppendBeginMarker(dst []byte) []byte\n\tAppendBool(dst []byte, val bool) []byte\n\tAppendBools(dst []byte, vals []bool) []byte\n\tAppendBytes(dst, s []byte) []byte\n\tAppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte\n\tAppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte\n\tAppendEndMarker(dst []byte) []byte\n\tAppendFloat32(dst []byte, val float32) []byte\n\tAppendFloat64(dst []byte, val float64) []byte\n\tAppendFloats32(dst []byte, vals []float32) []byte\n\tAppendFloats64(dst []byte, vals []float64) []byte\n\tAppendHex(dst, s []byte) []byte\n\tAppendIPAddr(dst []byte, ip net.IP) []byte\n\tAppendIPPrefix(dst []byte, pfx net.IPNet) []byte\n\tAppendInt(dst []byte, val int) []byte\n\tAppendInt16(dst []byte, val int16) []byte\n\tAppendInt32(dst []byte, val int32) []byte\n\tAppendInt64(dst []byte, val int64) []byte\n\tAppendInt8(dst []byte, val int8) []byte\n\tAppendInterface(dst []byte, i interface{}) []byte\n\tAppendInts(dst []byte, vals []int) []byte\n\tAppendInts16(dst []byte, vals []int16) []byte\n\tAppendInts32(dst []byte, vals []int32) []byte\n\tAppendInts64(dst []byte, vals []int64) []byte\n\tAppendInts8(dst []byte, vals []int8) []byte\n\tAppendKey(dst []byte, key string) []byte\n\tAppendLineBreak(dst []byte) []byte\n\tAppendMACAddr(dst []byte, ha net.HardwareAddr) []byte\n\tAppendNil(dst []byte) []byte\n\tAppendObjectData(dst []byte, o []byte) []byte\n\tAppendString(dst []byte, s string) []byte\n\tAppendStrings(dst []byte, vals []string) []byte\n\tAppendTime(dst []byte, t time.Time, format string) []byte\n\tAppendTimes(dst []byte, vals []time.Time, format string) []byte\n\tAppendUint(dst []byte, val uint) []byte\n\tAppendUint16(dst []byte, val uint16) []byte\n\tAppendUint32(dst []byte, val uint32) []byte\n\tAppendUint64(dst []byte, val uint64) []byte\n\tAppendUint8(dst []byte, val uint8) []byte\n\tAppendUints(dst []byte, vals []uint) []byte\n\tAppendUints16(dst []byte, vals []uint16) []byte\n\tAppendUints32(dst []byte, vals []uint32) []byte\n\tAppendUints64(dst []byte, vals []uint64) []byte\n\tAppendUints8(dst []byte, vals []uint8) []byte\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/encoder_cbor.go",
    "content": "// +build binary_log\n\npackage zerolog\n\n// This file contains bindings to do binary encoding.\n\nimport (\n\t\"github.com/rs/zerolog/internal/cbor\"\n)\n\nvar (\n\t_ encoder = (*cbor.Encoder)(nil)\n\n\tenc = cbor.Encoder{}\n)\n\nfunc appendJSON(dst []byte, j []byte) []byte {\n\treturn cbor.AppendEmbeddedJSON(dst, j)\n}\n\n// decodeIfBinaryToString - converts a binary formatted log msg to a\n// JSON formatted String Log message.\nfunc decodeIfBinaryToString(in []byte) string {\n\treturn cbor.DecodeIfBinaryToString(in)\n}\n\nfunc decodeObjectToStr(in []byte) string {\n\treturn cbor.DecodeObjectToStr(in)\n}\n\n// decodeIfBinaryToBytes - converts a binary formatted log msg to a\n// JSON formatted Bytes Log message.\nfunc decodeIfBinaryToBytes(in []byte) []byte {\n\treturn cbor.DecodeIfBinaryToBytes(in)\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/encoder_json.go",
    "content": "// +build !binary_log\n\npackage zerolog\n\n// encoder_json.go file contains bindings to generate\n// JSON encoded byte stream.\n\nimport (\n\t\"github.com/rs/zerolog/internal/json\"\n)\n\nvar (\n\t_ encoder = (*json.Encoder)(nil)\n\n\tenc = json.Encoder{}\n)\n\nfunc appendJSON(dst []byte, j []byte) []byte {\n\treturn append(dst, j...)\n}\n\nfunc decodeIfBinaryToString(in []byte) string {\n\treturn string(in)\n}\n\nfunc decodeObjectToStr(in []byte) string {\n\treturn string(in)\n}\n\nfunc decodeIfBinaryToBytes(in []byte) []byte {\n\treturn in\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/event.go",
    "content": "package zerolog\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"runtime\"\n\t\"sync\"\n\t\"time\"\n)\n\nvar eventPool = &sync.Pool{\n\tNew: func() interface{} {\n\t\treturn &Event{\n\t\t\tbuf: make([]byte, 0, 500),\n\t\t}\n\t},\n}\n\n// Event represents a log event. It is instanced by one of the level method of\n// Logger and finalized by the Msg or Msgf method.\ntype Event struct {\n\tbuf   []byte\n\tw     LevelWriter\n\tlevel Level\n\tdone  func(msg string)\n\tstack bool   // enable error stack trace\n\tch    []Hook // hooks from context\n}\n\nfunc putEvent(e *Event) {\n\t// Proper usage of a sync.Pool requires each entry to have approximately\n\t// the same memory cost. To obtain this property when the stored type\n\t// contains a variably-sized buffer, we add a hard limit on the maximum buffer\n\t// to place back in the pool.\n\t//\n\t// See https://golang.org/issue/23199\n\tconst maxSize = 1 << 16 // 64KiB\n\tif cap(e.buf) > maxSize {\n\t\treturn\n\t}\n\teventPool.Put(e)\n}\n\n// LogObjectMarshaler provides a strongly-typed and encoding-agnostic interface\n// to be implemented by types used with Event/Context's Object methods.\ntype LogObjectMarshaler interface {\n\tMarshalZerologObject(e *Event)\n}\n\n// LogArrayMarshaler provides a strongly-typed and encoding-agnostic interface\n// to be implemented by types used with Event/Context's Array methods.\ntype LogArrayMarshaler interface {\n\tMarshalZerologArray(a *Array)\n}\n\nfunc newEvent(w LevelWriter, level Level) *Event {\n\te := eventPool.Get().(*Event)\n\te.buf = e.buf[:0]\n\te.ch = nil\n\te.buf = enc.AppendBeginMarker(e.buf)\n\te.w = w\n\te.level = level\n\te.stack = false\n\treturn e\n}\n\nfunc (e *Event) write() (err error) {\n\tif e == nil {\n\t\treturn nil\n\t}\n\tif e.level != Disabled {\n\t\te.buf = enc.AppendEndMarker(e.buf)\n\t\te.buf = enc.AppendLineBreak(e.buf)\n\t\tif e.w != nil {\n\t\t\t_, err = e.w.WriteLevel(e.level, e.buf)\n\t\t}\n\t}\n\tputEvent(e)\n\treturn\n}\n\n// Enabled return false if the *Event is going to be filtered out by\n// log level or sampling.\nfunc (e *Event) Enabled() bool {\n\treturn e != nil && e.level != Disabled\n}\n\n// Discard disables the event so Msg(f) won't print it.\nfunc (e *Event) Discard() *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.level = Disabled\n\treturn nil\n}\n\n// Msg sends the *Event with msg added as the message field if not empty.\n//\n// NOTICE: once this method is called, the *Event should be disposed.\n// Calling Msg twice can have unexpected result.\nfunc (e *Event) Msg(msg string) {\n\tif e == nil {\n\t\treturn\n\t}\n\te.msg(msg)\n}\n\n// Send is equivalent to calling Msg(\"\").\n//\n// NOTICE: once this method is called, the *Event should be disposed.\nfunc (e *Event) Send() {\n\tif e == nil {\n\t\treturn\n\t}\n\te.msg(\"\")\n}\n\n// Msgf sends the event with formatted msg added as the message field if not empty.\n//\n// NOTICE: once this method is called, the *Event should be disposed.\n// Calling Msgf twice can have unexpected result.\nfunc (e *Event) Msgf(format string, v ...interface{}) {\n\tif e == nil {\n\t\treturn\n\t}\n\te.msg(fmt.Sprintf(format, v...))\n}\n\nfunc (e *Event) msg(msg string) {\n\tfor _, hook := range e.ch {\n\t\thook.Run(e, e.level, msg)\n\t}\n\tif msg != \"\" {\n\t\te.buf = enc.AppendString(enc.AppendKey(e.buf, MessageFieldName), msg)\n\t}\n\tif e.done != nil {\n\t\tdefer e.done(msg)\n\t}\n\tif err := e.write(); err != nil {\n\t\tif ErrorHandler != nil {\n\t\t\tErrorHandler(err)\n\t\t} else {\n\t\t\tfmt.Fprintf(os.Stderr, \"zerolog: could not write event: %v\\n\", err)\n\t\t}\n\t}\n}\n\n// Fields is a helper function to use a map to set fields using type assertion.\nfunc (e *Event) Fields(fields map[string]interface{}) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = appendFields(e.buf, fields)\n\treturn e\n}\n\n// Dict adds the field key with a dict to the event context.\n// Use zerolog.Dict() to create the dictionary.\nfunc (e *Event) Dict(key string, dict *Event) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\tdict.buf = enc.AppendEndMarker(dict.buf)\n\te.buf = append(enc.AppendKey(e.buf, key), dict.buf...)\n\tputEvent(dict)\n\treturn e\n}\n\n// Dict creates an Event to be used with the *Event.Dict method.\n// Call usual field methods like Str, Int etc to add fields to this\n// event and give it as argument the *Event.Dict method.\nfunc Dict() *Event {\n\treturn newEvent(nil, 0)\n}\n\n// Array adds the field key with an array to the event context.\n// Use zerolog.Arr() to create the array or pass a type that\n// implement the LogArrayMarshaler interface.\nfunc (e *Event) Array(key string, arr LogArrayMarshaler) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendKey(e.buf, key)\n\tvar a *Array\n\tif aa, ok := arr.(*Array); ok {\n\t\ta = aa\n\t} else {\n\t\ta = Arr()\n\t\tarr.MarshalZerologArray(a)\n\t}\n\te.buf = a.write(e.buf)\n\treturn e\n}\n\nfunc (e *Event) appendObject(obj LogObjectMarshaler) {\n\te.buf = enc.AppendBeginMarker(e.buf)\n\tobj.MarshalZerologObject(e)\n\te.buf = enc.AppendEndMarker(e.buf)\n}\n\n// Object marshals an object that implement the LogObjectMarshaler interface.\nfunc (e *Event) Object(key string, obj LogObjectMarshaler) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendKey(e.buf, key)\n\te.appendObject(obj)\n\treturn e\n}\n\n// EmbedObject marshals an object that implement the LogObjectMarshaler interface.\nfunc (e *Event) EmbedObject(obj LogObjectMarshaler) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\tobj.MarshalZerologObject(e)\n\treturn e\n}\n\n// Str adds the field key with val as a string to the *Event context.\nfunc (e *Event) Str(key, val string) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendString(enc.AppendKey(e.buf, key), val)\n\treturn e\n}\n\n// Strs adds the field key with vals as a []string to the *Event context.\nfunc (e *Event) Strs(key string, vals []string) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendStrings(enc.AppendKey(e.buf, key), vals)\n\treturn e\n}\n\n// Stringer adds the field key with val.String() (or null if val is nil) to the *Event context.\nfunc (e *Event) Stringer(key string, val fmt.Stringer) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\n\tif val != nil {\n\t\te.buf = enc.AppendString(enc.AppendKey(e.buf, key), val.String())\n\t\treturn e\n\t}\n\n\te.buf = enc.AppendInterface(enc.AppendKey(e.buf, key), nil)\n\treturn e\n}\n\n// Bytes adds the field key with val as a string to the *Event context.\n//\n// Runes outside of normal ASCII ranges will be hex-encoded in the resulting\n// JSON.\nfunc (e *Event) Bytes(key string, val []byte) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendBytes(enc.AppendKey(e.buf, key), val)\n\treturn e\n}\n\n// Hex adds the field key with val as a hex string to the *Event context.\nfunc (e *Event) Hex(key string, val []byte) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendHex(enc.AppendKey(e.buf, key), val)\n\treturn e\n}\n\n// RawJSON adds already encoded JSON to the log line under key.\n//\n// No sanity check is performed on b; it must not contain carriage returns and\n// be valid JSON.\nfunc (e *Event) RawJSON(key string, b []byte) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = appendJSON(enc.AppendKey(e.buf, key), b)\n\treturn e\n}\n\n// AnErr adds the field key with serialized err to the *Event context.\n// If err is nil, no field is added.\nfunc (e *Event) AnErr(key string, err error) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\tswitch m := ErrorMarshalFunc(err).(type) {\n\tcase nil:\n\t\treturn e\n\tcase LogObjectMarshaler:\n\t\treturn e.Object(key, m)\n\tcase error:\n\t\tif m == nil || isNilValue(m) {\n\t\t\treturn e\n\t\t} else {\n\t\t\treturn e.Str(key, m.Error())\n\t\t}\n\tcase string:\n\t\treturn e.Str(key, m)\n\tdefault:\n\t\treturn e.Interface(key, m)\n\t}\n}\n\n// Errs adds the field key with errs as an array of serialized errors to the\n// *Event context.\nfunc (e *Event) Errs(key string, errs []error) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\tarr := Arr()\n\tfor _, err := range errs {\n\t\tswitch m := ErrorMarshalFunc(err).(type) {\n\t\tcase LogObjectMarshaler:\n\t\t\tarr = arr.Object(m)\n\t\tcase error:\n\t\t\tarr = arr.Err(m)\n\t\tcase string:\n\t\t\tarr = arr.Str(m)\n\t\tdefault:\n\t\t\tarr = arr.Interface(m)\n\t\t}\n\t}\n\n\treturn e.Array(key, arr)\n}\n\n// Err adds the field \"error\" with serialized err to the *Event context.\n// If err is nil, no field is added.\n//\n// To customize the key name, change zerolog.ErrorFieldName.\n//\n// If Stack() has been called before and zerolog.ErrorStackMarshaler is defined,\n// the err is passed to ErrorStackMarshaler and the result is appended to the\n// zerolog.ErrorStackFieldName.\nfunc (e *Event) Err(err error) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\tif e.stack && ErrorStackMarshaler != nil {\n\t\tswitch m := ErrorStackMarshaler(err).(type) {\n\t\tcase nil:\n\t\tcase LogObjectMarshaler:\n\t\t\te.Object(ErrorStackFieldName, m)\n\t\tcase error:\n\t\t\tif m != nil && !isNilValue(m) {\n\t\t\t\te.Str(ErrorStackFieldName, m.Error())\n\t\t\t}\n\t\tcase string:\n\t\t\te.Str(ErrorStackFieldName, m)\n\t\tdefault:\n\t\t\te.Interface(ErrorStackFieldName, m)\n\t\t}\n\t}\n\treturn e.AnErr(ErrorFieldName, err)\n}\n\n// Stack enables stack trace printing for the error passed to Err().\n//\n// ErrorStackMarshaler must be set for this method to do something.\nfunc (e *Event) Stack() *Event {\n\tif e != nil {\n\t\te.stack = true\n\t}\n\treturn e\n}\n\n// Bool adds the field key with val as a bool to the *Event context.\nfunc (e *Event) Bool(key string, b bool) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendBool(enc.AppendKey(e.buf, key), b)\n\treturn e\n}\n\n// Bools adds the field key with val as a []bool to the *Event context.\nfunc (e *Event) Bools(key string, b []bool) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendBools(enc.AppendKey(e.buf, key), b)\n\treturn e\n}\n\n// Int adds the field key with i as a int to the *Event context.\nfunc (e *Event) Int(key string, i int) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendInt(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Ints adds the field key with i as a []int to the *Event context.\nfunc (e *Event) Ints(key string, i []int) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendInts(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Int8 adds the field key with i as a int8 to the *Event context.\nfunc (e *Event) Int8(key string, i int8) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendInt8(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Ints8 adds the field key with i as a []int8 to the *Event context.\nfunc (e *Event) Ints8(key string, i []int8) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendInts8(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Int16 adds the field key with i as a int16 to the *Event context.\nfunc (e *Event) Int16(key string, i int16) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendInt16(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Ints16 adds the field key with i as a []int16 to the *Event context.\nfunc (e *Event) Ints16(key string, i []int16) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendInts16(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Int32 adds the field key with i as a int32 to the *Event context.\nfunc (e *Event) Int32(key string, i int32) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendInt32(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Ints32 adds the field key with i as a []int32 to the *Event context.\nfunc (e *Event) Ints32(key string, i []int32) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendInts32(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Int64 adds the field key with i as a int64 to the *Event context.\nfunc (e *Event) Int64(key string, i int64) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendInt64(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Ints64 adds the field key with i as a []int64 to the *Event context.\nfunc (e *Event) Ints64(key string, i []int64) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendInts64(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Uint adds the field key with i as a uint to the *Event context.\nfunc (e *Event) Uint(key string, i uint) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendUint(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Uints adds the field key with i as a []int to the *Event context.\nfunc (e *Event) Uints(key string, i []uint) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendUints(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Uint8 adds the field key with i as a uint8 to the *Event context.\nfunc (e *Event) Uint8(key string, i uint8) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendUint8(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Uints8 adds the field key with i as a []int8 to the *Event context.\nfunc (e *Event) Uints8(key string, i []uint8) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendUints8(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Uint16 adds the field key with i as a uint16 to the *Event context.\nfunc (e *Event) Uint16(key string, i uint16) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendUint16(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Uints16 adds the field key with i as a []int16 to the *Event context.\nfunc (e *Event) Uints16(key string, i []uint16) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendUints16(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Uint32 adds the field key with i as a uint32 to the *Event context.\nfunc (e *Event) Uint32(key string, i uint32) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendUint32(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Uints32 adds the field key with i as a []int32 to the *Event context.\nfunc (e *Event) Uints32(key string, i []uint32) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendUints32(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Uint64 adds the field key with i as a uint64 to the *Event context.\nfunc (e *Event) Uint64(key string, i uint64) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendUint64(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Uints64 adds the field key with i as a []int64 to the *Event context.\nfunc (e *Event) Uints64(key string, i []uint64) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendUints64(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Float32 adds the field key with f as a float32 to the *Event context.\nfunc (e *Event) Float32(key string, f float32) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendFloat32(enc.AppendKey(e.buf, key), f)\n\treturn e\n}\n\n// Floats32 adds the field key with f as a []float32 to the *Event context.\nfunc (e *Event) Floats32(key string, f []float32) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendFloats32(enc.AppendKey(e.buf, key), f)\n\treturn e\n}\n\n// Float64 adds the field key with f as a float64 to the *Event context.\nfunc (e *Event) Float64(key string, f float64) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendFloat64(enc.AppendKey(e.buf, key), f)\n\treturn e\n}\n\n// Floats64 adds the field key with f as a []float64 to the *Event context.\nfunc (e *Event) Floats64(key string, f []float64) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendFloats64(enc.AppendKey(e.buf, key), f)\n\treturn e\n}\n\n// Timestamp adds the current local time as UNIX timestamp to the *Event context with the \"time\" key.\n// To customize the key name, change zerolog.TimestampFieldName.\n//\n// NOTE: It won't dedupe the \"time\" key if the *Event (or *Context) has one\n// already.\nfunc (e *Event) Timestamp() *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendTime(enc.AppendKey(e.buf, TimestampFieldName), TimestampFunc(), TimeFieldFormat)\n\treturn e\n}\n\n// Time adds the field key with t formated as string using zerolog.TimeFieldFormat.\nfunc (e *Event) Time(key string, t time.Time) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendTime(enc.AppendKey(e.buf, key), t, TimeFieldFormat)\n\treturn e\n}\n\n// Times adds the field key with t formated as string using zerolog.TimeFieldFormat.\nfunc (e *Event) Times(key string, t []time.Time) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendTimes(enc.AppendKey(e.buf, key), t, TimeFieldFormat)\n\treturn e\n}\n\n// Dur adds the field key with duration d stored as zerolog.DurationFieldUnit.\n// If zerolog.DurationFieldInteger is true, durations are rendered as integer\n// instead of float.\nfunc (e *Event) Dur(key string, d time.Duration) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger)\n\treturn e\n}\n\n// Durs adds the field key with duration d stored as zerolog.DurationFieldUnit.\n// If zerolog.DurationFieldInteger is true, durations are rendered as integer\n// instead of float.\nfunc (e *Event) Durs(key string, d []time.Duration) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendDurations(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger)\n\treturn e\n}\n\n// TimeDiff adds the field key with positive duration between time t and start.\n// If time t is not greater than start, duration will be 0.\n// Duration format follows the same principle as Dur().\nfunc (e *Event) TimeDiff(key string, t time.Time, start time.Time) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\tvar d time.Duration\n\tif t.After(start) {\n\t\td = t.Sub(start)\n\t}\n\te.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger)\n\treturn e\n}\n\n// Interface adds the field key with i marshaled using reflection.\nfunc (e *Event) Interface(key string, i interface{}) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\tif obj, ok := i.(LogObjectMarshaler); ok {\n\t\treturn e.Object(key, obj)\n\t}\n\te.buf = enc.AppendInterface(enc.AppendKey(e.buf, key), i)\n\treturn e\n}\n\n// Caller adds the file:line of the caller with the zerolog.CallerFieldName key.\n// The argument skip is the number of stack frames to ascend\n// Skip If not passed, use the global variable CallerSkipFrameCount\nfunc (e *Event) Caller(skip ...int) *Event {\n\tsk := CallerSkipFrameCount\n\tif len(skip) > 0 {\n\t\tsk = skip[0] + CallerSkipFrameCount\n\t}\n\treturn e.caller(sk)\n}\n\nfunc (e *Event) caller(skip int) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\t_, file, line, ok := runtime.Caller(skip)\n\tif !ok {\n\t\treturn e\n\t}\n\te.buf = enc.AppendString(enc.AppendKey(e.buf, CallerFieldName), CallerMarshalFunc(file, line))\n\treturn e\n}\n\n// IPAddr adds IPv4 or IPv6 Address to the event\nfunc (e *Event) IPAddr(key string, ip net.IP) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendIPAddr(enc.AppendKey(e.buf, key), ip)\n\treturn e\n}\n\n// IPPrefix adds IPv4 or IPv6 Prefix (address and mask) to the event\nfunc (e *Event) IPPrefix(key string, pfx net.IPNet) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendIPPrefix(enc.AppendKey(e.buf, key), pfx)\n\treturn e\n}\n\n// MACAddr adds MAC address to the event\nfunc (e *Event) MACAddr(key string, ha net.HardwareAddr) *Event {\n\tif e == nil {\n\t\treturn e\n\t}\n\te.buf = enc.AppendMACAddr(enc.AppendKey(e.buf, key), ha)\n\treturn e\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/fields.go",
    "content": "package zerolog\n\nimport (\n\t\"net\"\n\t\"sort\"\n\t\"time\"\n\t\"unsafe\"\n)\n\nfunc isNilValue(i interface{}) bool {\n\treturn (*[2]uintptr)(unsafe.Pointer(&i))[1] == 0\n}\n\nfunc appendFields(dst []byte, fields map[string]interface{}) []byte {\n\tkeys := make([]string, 0, len(fields))\n\tfor key := range fields {\n\t\tkeys = append(keys, key)\n\t}\n\tsort.Strings(keys)\n\tfor _, key := range keys {\n\t\tdst = enc.AppendKey(dst, key)\n\t\tval := fields[key]\n\t\tif val, ok := val.(LogObjectMarshaler); ok {\n\t\t\te := newEvent(nil, 0)\n\t\t\te.buf = e.buf[:0]\n\t\t\te.appendObject(val)\n\t\t\tdst = append(dst, e.buf...)\n\t\t\tputEvent(e)\n\t\t\tcontinue\n\t\t}\n\t\tswitch val := val.(type) {\n\t\tcase string:\n\t\t\tdst = enc.AppendString(dst, val)\n\t\tcase []byte:\n\t\t\tdst = enc.AppendBytes(dst, val)\n\t\tcase error:\n\t\t\tswitch m := ErrorMarshalFunc(val).(type) {\n\t\t\tcase LogObjectMarshaler:\n\t\t\t\te := newEvent(nil, 0)\n\t\t\t\te.buf = e.buf[:0]\n\t\t\t\te.appendObject(m)\n\t\t\t\tdst = append(dst, e.buf...)\n\t\t\t\tputEvent(e)\n\t\t\tcase error:\n\t\t\t\tif m == nil || isNilValue(m) {\n\t\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t\t} else {\n\t\t\t\t\tdst = enc.AppendString(dst, m.Error())\n\t\t\t\t}\n\t\t\tcase string:\n\t\t\t\tdst = enc.AppendString(dst, m)\n\t\t\tdefault:\n\t\t\t\tdst = enc.AppendInterface(dst, m)\n\t\t\t}\n\t\tcase []error:\n\t\t\tdst = enc.AppendArrayStart(dst)\n\t\t\tfor i, err := range val {\n\t\t\t\tswitch m := ErrorMarshalFunc(err).(type) {\n\t\t\t\tcase LogObjectMarshaler:\n\t\t\t\t\te := newEvent(nil, 0)\n\t\t\t\t\te.buf = e.buf[:0]\n\t\t\t\t\te.appendObject(m)\n\t\t\t\t\tdst = append(dst, e.buf...)\n\t\t\t\t\tputEvent(e)\n\t\t\t\tcase error:\n\t\t\t\t\tif m == nil || isNilValue(m) {\n\t\t\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdst = enc.AppendString(dst, m.Error())\n\t\t\t\t\t}\n\t\t\t\tcase string:\n\t\t\t\t\tdst = enc.AppendString(dst, m)\n\t\t\t\tdefault:\n\t\t\t\t\tdst = enc.AppendInterface(dst, m)\n\t\t\t\t}\n\n\t\t\t\tif i < (len(val) - 1) {\n\t\t\t\t\tenc.AppendArrayDelim(dst)\n\t\t\t\t}\n\t\t\t}\n\t\t\tdst = enc.AppendArrayEnd(dst)\n\t\tcase bool:\n\t\t\tdst = enc.AppendBool(dst, val)\n\t\tcase int:\n\t\t\tdst = enc.AppendInt(dst, val)\n\t\tcase int8:\n\t\t\tdst = enc.AppendInt8(dst, val)\n\t\tcase int16:\n\t\t\tdst = enc.AppendInt16(dst, val)\n\t\tcase int32:\n\t\t\tdst = enc.AppendInt32(dst, val)\n\t\tcase int64:\n\t\t\tdst = enc.AppendInt64(dst, val)\n\t\tcase uint:\n\t\t\tdst = enc.AppendUint(dst, val)\n\t\tcase uint8:\n\t\t\tdst = enc.AppendUint8(dst, val)\n\t\tcase uint16:\n\t\t\tdst = enc.AppendUint16(dst, val)\n\t\tcase uint32:\n\t\t\tdst = enc.AppendUint32(dst, val)\n\t\tcase uint64:\n\t\t\tdst = enc.AppendUint64(dst, val)\n\t\tcase float32:\n\t\t\tdst = enc.AppendFloat32(dst, val)\n\t\tcase float64:\n\t\t\tdst = enc.AppendFloat64(dst, val)\n\t\tcase time.Time:\n\t\t\tdst = enc.AppendTime(dst, val, TimeFieldFormat)\n\t\tcase time.Duration:\n\t\t\tdst = enc.AppendDuration(dst, val, DurationFieldUnit, DurationFieldInteger)\n\t\tcase *string:\n\t\t\tif val != nil {\n\t\t\t\tdst = enc.AppendString(dst, *val)\n\t\t\t} else {\n\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t}\n\t\tcase *bool:\n\t\t\tif val != nil {\n\t\t\t\tdst = enc.AppendBool(dst, *val)\n\t\t\t} else {\n\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t}\n\t\tcase *int:\n\t\t\tif val != nil {\n\t\t\t\tdst = enc.AppendInt(dst, *val)\n\t\t\t} else {\n\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t}\n\t\tcase *int8:\n\t\t\tif val != nil {\n\t\t\t\tdst = enc.AppendInt8(dst, *val)\n\t\t\t} else {\n\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t}\n\t\tcase *int16:\n\t\t\tif val != nil {\n\t\t\t\tdst = enc.AppendInt16(dst, *val)\n\t\t\t} else {\n\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t}\n\t\tcase *int32:\n\t\t\tif val != nil {\n\t\t\t\tdst = enc.AppendInt32(dst, *val)\n\t\t\t} else {\n\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t}\n\t\tcase *int64:\n\t\t\tif val != nil {\n\t\t\t\tdst = enc.AppendInt64(dst, *val)\n\t\t\t} else {\n\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t}\n\t\tcase *uint:\n\t\t\tif val != nil {\n\t\t\t\tdst = enc.AppendUint(dst, *val)\n\t\t\t} else {\n\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t}\n\t\tcase *uint8:\n\t\t\tif val != nil {\n\t\t\t\tdst = enc.AppendUint8(dst, *val)\n\t\t\t} else {\n\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t}\n\t\tcase *uint16:\n\t\t\tif val != nil {\n\t\t\t\tdst = enc.AppendUint16(dst, *val)\n\t\t\t} else {\n\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t}\n\t\tcase *uint32:\n\t\t\tif val != nil {\n\t\t\t\tdst = enc.AppendUint32(dst, *val)\n\t\t\t} else {\n\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t}\n\t\tcase *uint64:\n\t\t\tif val != nil {\n\t\t\t\tdst = enc.AppendUint64(dst, *val)\n\t\t\t} else {\n\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t}\n\t\tcase *float32:\n\t\t\tif val != nil {\n\t\t\t\tdst = enc.AppendFloat32(dst, *val)\n\t\t\t} else {\n\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t}\n\t\tcase *float64:\n\t\t\tif val != nil {\n\t\t\t\tdst = enc.AppendFloat64(dst, *val)\n\t\t\t} else {\n\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t}\n\t\tcase *time.Time:\n\t\t\tif val != nil {\n\t\t\t\tdst = enc.AppendTime(dst, *val, TimeFieldFormat)\n\t\t\t} else {\n\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t}\n\t\tcase *time.Duration:\n\t\t\tif val != nil {\n\t\t\t\tdst = enc.AppendDuration(dst, *val, DurationFieldUnit, DurationFieldInteger)\n\t\t\t} else {\n\t\t\t\tdst = enc.AppendNil(dst)\n\t\t\t}\n\t\tcase []string:\n\t\t\tdst = enc.AppendStrings(dst, val)\n\t\tcase []bool:\n\t\t\tdst = enc.AppendBools(dst, val)\n\t\tcase []int:\n\t\t\tdst = enc.AppendInts(dst, val)\n\t\tcase []int8:\n\t\t\tdst = enc.AppendInts8(dst, val)\n\t\tcase []int16:\n\t\t\tdst = enc.AppendInts16(dst, val)\n\t\tcase []int32:\n\t\t\tdst = enc.AppendInts32(dst, val)\n\t\tcase []int64:\n\t\t\tdst = enc.AppendInts64(dst, val)\n\t\tcase []uint:\n\t\t\tdst = enc.AppendUints(dst, val)\n\t\t// case []uint8:\n\t\t// \tdst = enc.AppendUints8(dst, val)\n\t\tcase []uint16:\n\t\t\tdst = enc.AppendUints16(dst, val)\n\t\tcase []uint32:\n\t\t\tdst = enc.AppendUints32(dst, val)\n\t\tcase []uint64:\n\t\t\tdst = enc.AppendUints64(dst, val)\n\t\tcase []float32:\n\t\t\tdst = enc.AppendFloats32(dst, val)\n\t\tcase []float64:\n\t\t\tdst = enc.AppendFloats64(dst, val)\n\t\tcase []time.Time:\n\t\t\tdst = enc.AppendTimes(dst, val, TimeFieldFormat)\n\t\tcase []time.Duration:\n\t\t\tdst = enc.AppendDurations(dst, val, DurationFieldUnit, DurationFieldInteger)\n\t\tcase nil:\n\t\t\tdst = enc.AppendNil(dst)\n\t\tcase net.IP:\n\t\t\tdst = enc.AppendIPAddr(dst, val)\n\t\tcase net.IPNet:\n\t\t\tdst = enc.AppendIPPrefix(dst, val)\n\t\tcase net.HardwareAddr:\n\t\t\tdst = enc.AppendMACAddr(dst, val)\n\t\tdefault:\n\t\t\tdst = enc.AppendInterface(dst, val)\n\t\t}\n\t}\n\treturn dst\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/globals.go",
    "content": "package zerolog\n\nimport (\n\t\"strconv\"\n\t\"sync/atomic\"\n\t\"time\"\n)\n\nconst (\n\t// TimeFormatUnix defines a time format that makes time fields to be\n\t// serialized as Unix timestamp integers.\n\tTimeFormatUnix = \"\"\n\n\t// TimeFormatUnixMs defines a time format that makes time fields to be\n\t// serialized as Unix timestamp integers in milliseconds.\n\tTimeFormatUnixMs = \"UNIXMS\"\n\n\t// TimeFormatUnixMicro defines a time format that makes time fields to be\n\t// serialized as Unix timestamp integers in microseconds.\n\tTimeFormatUnixMicro = \"UNIXMICRO\"\n)\n\nvar (\n\t// TimestampFieldName is the field name used for the timestamp field.\n\tTimestampFieldName = \"time\"\n\n\t// LevelFieldName is the field name used for the level field.\n\tLevelFieldName = \"level\"\n\n\t// LevelFieldMarshalFunc allows customization of global level field marshaling\n\tLevelFieldMarshalFunc = func(l Level) string {\n\t\treturn l.String()\n\t}\n\n\t// MessageFieldName is the field name used for the message field.\n\tMessageFieldName = \"message\"\n\n\t// ErrorFieldName is the field name used for error fields.\n\tErrorFieldName = \"error\"\n\n\t// CallerFieldName is the field name used for caller field.\n\tCallerFieldName = \"caller\"\n\n\t// CallerSkipFrameCount is the number of stack frames to skip to find the caller.\n\tCallerSkipFrameCount = 2\n\n\t// CallerMarshalFunc allows customization of global caller marshaling\n\tCallerMarshalFunc = func(file string, line int) string {\n\t\treturn file + \":\" + strconv.Itoa(line)\n\t}\n\n\t// ErrorStackFieldName is the field name used for error stacks.\n\tErrorStackFieldName = \"stack\"\n\n\t// ErrorStackMarshaler extract the stack from err if any.\n\tErrorStackMarshaler func(err error) interface{}\n\n\t// ErrorMarshalFunc allows customization of global error marshaling\n\tErrorMarshalFunc = func(err error) interface{} {\n\t\treturn err\n\t}\n\n\t// TimeFieldFormat defines the time format of the Time field type. If set to\n\t// TimeFormatUnix, TimeFormatUnixMs or TimeFormatUnixMicro, the time is formatted as an UNIX\n\t// timestamp as integer.\n\tTimeFieldFormat = time.RFC3339\n\n\t// TimestampFunc defines the function called to generate a timestamp.\n\tTimestampFunc = time.Now\n\n\t// DurationFieldUnit defines the unit for time.Duration type fields added\n\t// using the Dur method.\n\tDurationFieldUnit = time.Millisecond\n\n\t// DurationFieldInteger renders Dur fields as integer instead of float if\n\t// set to true.\n\tDurationFieldInteger = false\n\n\t// ErrorHandler is called whenever zerolog fails to write an event on its\n\t// output. If not set, an error is printed on the stderr. This handler must\n\t// be thread safe and non-blocking.\n\tErrorHandler func(err error)\n)\n\nvar (\n\tgLevel          = new(int32)\n\tdisableSampling = new(int32)\n)\n\n// SetGlobalLevel sets the global override for log level. If this\n// values is raised, all Loggers will use at least this value.\n//\n// To globally disable logs, set GlobalLevel to Disabled.\nfunc SetGlobalLevel(l Level) {\n\tatomic.StoreInt32(gLevel, int32(l))\n}\n\n// GlobalLevel returns the current global log level\nfunc GlobalLevel() Level {\n\treturn Level(atomic.LoadInt32(gLevel))\n}\n\n// DisableSampling will disable sampling in all Loggers if true.\nfunc DisableSampling(v bool) {\n\tvar i int32\n\tif v {\n\t\ti = 1\n\t}\n\tatomic.StoreInt32(disableSampling, i)\n}\n\nfunc samplingDisabled() bool {\n\treturn atomic.LoadInt32(disableSampling) == 1\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/go112.go",
    "content": "// +build go1.12\n\npackage zerolog\n\n// Since go 1.12, some auto generated init functions are hidden from\n// runtime.Caller.\nconst contextCallerSkipFrameCount = 2\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/hook.go",
    "content": "package zerolog\n\n// Hook defines an interface to a log hook.\ntype Hook interface {\n\t// Run runs the hook with the event.\n\tRun(e *Event, level Level, message string)\n}\n\n// HookFunc is an adaptor to allow the use of an ordinary function\n// as a Hook.\ntype HookFunc func(e *Event, level Level, message string)\n\n// Run implements the Hook interface.\nfunc (h HookFunc) Run(e *Event, level Level, message string) {\n\th(e, level, message)\n}\n\n// LevelHook applies a different hook for each level.\ntype LevelHook struct {\n\tNoLevelHook, TraceHook, DebugHook, InfoHook, WarnHook, ErrorHook, FatalHook, PanicHook Hook\n}\n\n// Run implements the Hook interface.\nfunc (h LevelHook) Run(e *Event, level Level, message string) {\n\tswitch level {\n\tcase TraceLevel:\n\t\tif h.TraceHook != nil {\n\t\t\th.TraceHook.Run(e, level, message)\n\t\t}\n\tcase DebugLevel:\n\t\tif h.DebugHook != nil {\n\t\t\th.DebugHook.Run(e, level, message)\n\t\t}\n\tcase InfoLevel:\n\t\tif h.InfoHook != nil {\n\t\t\th.InfoHook.Run(e, level, message)\n\t\t}\n\tcase WarnLevel:\n\t\tif h.WarnHook != nil {\n\t\t\th.WarnHook.Run(e, level, message)\n\t\t}\n\tcase ErrorLevel:\n\t\tif h.ErrorHook != nil {\n\t\t\th.ErrorHook.Run(e, level, message)\n\t\t}\n\tcase FatalLevel:\n\t\tif h.FatalHook != nil {\n\t\t\th.FatalHook.Run(e, level, message)\n\t\t}\n\tcase PanicLevel:\n\t\tif h.PanicHook != nil {\n\t\t\th.PanicHook.Run(e, level, message)\n\t\t}\n\tcase NoLevel:\n\t\tif h.NoLevelHook != nil {\n\t\t\th.NoLevelHook.Run(e, level, message)\n\t\t}\n\t}\n}\n\n// NewLevelHook returns a new LevelHook.\nfunc NewLevelHook() LevelHook {\n\treturn LevelHook{}\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/internal/cbor/README.md",
    "content": "## Reference:\n   CBOR Encoding is described in [RFC7049](https://tools.ietf.org/html/rfc7049)\n\n## Comparison of JSON vs CBOR\n\nTwo main areas of reduction are:\n\n1. CPU usage to write a log msg \n2. Size (in bytes) of log messages.\n\n\nCPU Usage savings are below:\n```\nname                                    JSON time/op    CBOR time/op   delta\nInfo-32                                   15.3ns ± 1%    11.7ns ± 3%  -23.78%  (p=0.000 n=9+10)      \nContextFields-32                          16.2ns ± 2%    12.3ns ± 3%  -23.97%  (p=0.000 n=9+9)       \nContextAppend-32                          6.70ns ± 0%    6.20ns ± 0%   -7.44%  (p=0.000 n=9+9)       \nLogFields-32                              66.4ns ± 0%    24.6ns ± 2%  -62.89%  (p=0.000 n=10+9)      \nLogArrayObject-32                          911ns ±11%     768ns ± 6%  -15.64%  (p=0.000 n=10+10)     \nLogFieldType/Floats-32                    70.3ns ± 2%    29.5ns ± 1%  -57.98%  (p=0.000 n=10+10)     \nLogFieldType/Err-32                       14.0ns ± 3%    12.1ns ± 8%  -13.20%  (p=0.000 n=8+10)      \nLogFieldType/Dur-32                       17.2ns ± 2%    13.1ns ± 1%  -24.27%  (p=0.000 n=10+9)      \nLogFieldType/Object-32                    54.3ns ±11%    52.3ns ± 7%     ~     (p=0.239 n=10+10)     \nLogFieldType/Ints-32                      20.3ns ± 2%    15.1ns ± 2%  -25.50%  (p=0.000 n=9+10)      \nLogFieldType/Interfaces-32                 642ns ±11%     621ns ± 9%     ~     (p=0.118 n=10+10)     \nLogFieldType/Interface(Objects)-32         635ns ±13%     632ns ± 9%     ~     (p=0.592 n=10+10)     \nLogFieldType/Times-32                      294ns ± 0%      27ns ± 1%  -90.71%  (p=0.000 n=10+9)      \nLogFieldType/Durs-32                       121ns ± 0%      33ns ± 2%  -72.44%  (p=0.000 n=9+9)       \nLogFieldType/Interface(Object)-32         56.6ns ± 8%    52.3ns ± 8%   -7.54%  (p=0.007 n=10+10)     \nLogFieldType/Errs-32                      17.8ns ± 3%    16.1ns ± 2%   -9.71%  (p=0.000 n=10+9)      \nLogFieldType/Time-32                      40.5ns ± 1%    12.7ns ± 6%  -68.66%  (p=0.000 n=8+9)       \nLogFieldType/Bool-32                      12.0ns ± 5%    10.2ns ± 2%  -15.18%  (p=0.000 n=10+8)      \nLogFieldType/Bools-32                     17.2ns ± 2%    12.6ns ± 4%  -26.63%  (p=0.000 n=10+10)     \nLogFieldType/Int-32                       12.3ns ± 2%    11.2ns ± 4%   -9.27%  (p=0.000 n=9+10)      \nLogFieldType/Float-32                     16.7ns ± 1%    12.6ns ± 2%  -24.42%  (p=0.000 n=7+9)       \nLogFieldType/Str-32                       12.7ns ± 7%    11.3ns ± 7%  -10.88%  (p=0.000 n=10+9)      \nLogFieldType/Strs-32                      20.3ns ± 3%    18.2ns ± 3%  -10.25%  (p=0.000 n=9+10)      \nLogFieldType/Interface-32                  183ns ±12%     175ns ± 9%     ~     (p=0.078 n=10+10)     \n```\n\nLog message size savings is greatly dependent on the number and type of fields in the log message.\nAssuming this log message (with an Integer, timestamp and string, in addition to level).\n\n`{\"level\":\"error\",\"Fault\":41650,\"time\":\"2018-04-01T15:18:19-07:00\",\"message\":\"Some Message\"}`\n\nTwo measurements were done for the log file sizes - one without any compression, second\nusing [compress/zlib](https://golang.org/pkg/compress/zlib/). \n\nResults for 10,000 log messages:\n\n| Log Format |  Plain File Size (in KB) | Compressed File Size (in KB) |\n| :--- | :---: | :---: |\n| JSON | 920 | 28 |\n| CBOR | 550 | 28 |\n\nThe example used to calculate the above data is available in [Examples](examples).\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/internal/cbor/base.go",
    "content": "package cbor\n\ntype Encoder struct{}\n\n// AppendKey adds a key (string) to the binary encoded log message\nfunc (e Encoder) AppendKey(dst []byte, key string) []byte {\n\tif len(dst) < 1 {\n\t\tdst = e.AppendBeginMarker(dst)\n\t}\n\treturn e.AppendString(dst, key)\n}"
  },
  {
    "path": "vendor/github.com/rs/zerolog/internal/cbor/cbor.go",
    "content": "// Package cbor provides primitives for storing different data\n// in the CBOR (binary) format. CBOR is defined in RFC7049.\npackage cbor\n\nimport \"time\"\n\nconst (\n\tmajorOffset   = 5\n\tadditionalMax = 23\n\n\t// Non Values.\n\tadditionalTypeBoolFalse byte = 20\n\tadditionalTypeBoolTrue  byte = 21\n\tadditionalTypeNull      byte = 22\n\n\t// Integer (+ve and -ve) Sub-types.\n\tadditionalTypeIntUint8  byte = 24\n\tadditionalTypeIntUint16 byte = 25\n\tadditionalTypeIntUint32 byte = 26\n\tadditionalTypeIntUint64 byte = 27\n\n\t// Float Sub-types.\n\tadditionalTypeFloat16 byte = 25\n\tadditionalTypeFloat32 byte = 26\n\tadditionalTypeFloat64 byte = 27\n\tadditionalTypeBreak   byte = 31\n\n\t// Tag Sub-types.\n\tadditionalTypeTimestamp byte = 01\n\n\t// Extended Tags - from https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml\n\tadditionalTypeTagNetworkAddr   uint16 = 260\n\tadditionalTypeTagNetworkPrefix uint16 = 261\n\tadditionalTypeEmbeddedJSON     uint16 = 262\n\tadditionalTypeTagHexString     uint16 = 263\n\n\t// Unspecified number of elements.\n\tadditionalTypeInfiniteCount byte = 31\n)\nconst (\n\tmajorTypeUnsignedInt    byte = iota << majorOffset // Major type 0\n\tmajorTypeNegativeInt                               // Major type 1\n\tmajorTypeByteString                                // Major type 2\n\tmajorTypeUtf8String                                // Major type 3\n\tmajorTypeArray                                     // Major type 4\n\tmajorTypeMap                                       // Major type 5\n\tmajorTypeTags                                      // Major type 6\n\tmajorTypeSimpleAndFloat                            // Major type 7\n)\n\nconst (\n\tmaskOutAdditionalType byte = (7 << majorOffset)\n\tmaskOutMajorType      byte = 31\n)\n\nconst (\n\tfloat32Nan         = \"\\xfa\\x7f\\xc0\\x00\\x00\"\n\tfloat32PosInfinity = \"\\xfa\\x7f\\x80\\x00\\x00\"\n\tfloat32NegInfinity = \"\\xfa\\xff\\x80\\x00\\x00\"\n\tfloat64Nan         = \"\\xfb\\x7f\\xf8\\x00\\x00\\x00\\x00\\x00\\x00\"\n\tfloat64PosInfinity = \"\\xfb\\x7f\\xf0\\x00\\x00\\x00\\x00\\x00\\x00\"\n\tfloat64NegInfinity = \"\\xfb\\xff\\xf0\\x00\\x00\\x00\\x00\\x00\\x00\"\n)\n\n// IntegerTimeFieldFormat indicates the format of timestamp decoded\n// from an integer (time in seconds).\nvar IntegerTimeFieldFormat = time.RFC3339\n\n// NanoTimeFieldFormat indicates the format of timestamp decoded\n// from a float value (time in seconds and nano seconds).\nvar NanoTimeFieldFormat = time.RFC3339Nano\n\nfunc appendCborTypePrefix(dst []byte, major byte, number uint64) []byte {\n\tbyteCount := 8\n\tvar minor byte\n\tswitch {\n\tcase number < 256:\n\t\tbyteCount = 1\n\t\tminor = additionalTypeIntUint8\n\n\tcase number < 65536:\n\t\tbyteCount = 2\n\t\tminor = additionalTypeIntUint16\n\n\tcase number < 4294967296:\n\t\tbyteCount = 4\n\t\tminor = additionalTypeIntUint32\n\n\tdefault:\n\t\tbyteCount = 8\n\t\tminor = additionalTypeIntUint64\n\n\t}\n\tdst = append(dst, byte(major|minor))\n\tbyteCount--\n\tfor ; byteCount >= 0; byteCount-- {\n\t\tdst = append(dst, byte(number>>(uint(byteCount)*8)))\n\t}\n\treturn dst\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/internal/cbor/decode_stream.go",
    "content": "package cbor\n\n// This file contains code to decode a stream of CBOR Data into JSON.\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"net\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\t\"unicode/utf8\"\n)\n\nvar decodeTimeZone *time.Location\n\nconst hexTable = \"0123456789abcdef\"\n\nconst isFloat32 = 4\nconst isFloat64 = 8\n\nfunc readNBytes(src *bufio.Reader, n int) []byte {\n\tret := make([]byte, n)\n\tfor i := 0; i < n; i++ {\n\t\tch, e := src.ReadByte()\n\t\tif e != nil {\n\t\t\tpanic(fmt.Errorf(\"Tried to Read %d Bytes.. But hit end of file\", n))\n\t\t}\n\t\tret[i] = ch\n\t}\n\treturn ret\n}\n\nfunc readByte(src *bufio.Reader) byte {\n\tb, e := src.ReadByte()\n\tif e != nil {\n\t\tpanic(fmt.Errorf(\"Tried to Read 1 Byte.. But hit end of file\"))\n\t}\n\treturn b\n}\n\nfunc decodeIntAdditonalType(src *bufio.Reader, minor byte) int64 {\n\tval := int64(0)\n\tif minor <= 23 {\n\t\tval = int64(minor)\n\t} else {\n\t\tbytesToRead := 0\n\t\tswitch minor {\n\t\tcase additionalTypeIntUint8:\n\t\t\tbytesToRead = 1\n\t\tcase additionalTypeIntUint16:\n\t\t\tbytesToRead = 2\n\t\tcase additionalTypeIntUint32:\n\t\t\tbytesToRead = 4\n\t\tcase additionalTypeIntUint64:\n\t\t\tbytesToRead = 8\n\t\tdefault:\n\t\t\tpanic(fmt.Errorf(\"Invalid Additional Type: %d in decodeInteger (expected <28)\", minor))\n\t\t}\n\t\tpb := readNBytes(src, bytesToRead)\n\t\tfor i := 0; i < bytesToRead; i++ {\n\t\t\tval = val * 256\n\t\t\tval += int64(pb[i])\n\t\t}\n\t}\n\treturn val\n}\n\nfunc decodeInteger(src *bufio.Reader) int64 {\n\tpb := readByte(src)\n\tmajor := pb & maskOutAdditionalType\n\tminor := pb & maskOutMajorType\n\tif major != majorTypeUnsignedInt && major != majorTypeNegativeInt {\n\t\tpanic(fmt.Errorf(\"Major type is: %d in decodeInteger!! (expected 0 or 1)\", major))\n\t}\n\tval := decodeIntAdditonalType(src, minor)\n\tif major == 0 {\n\t\treturn val\n\t}\n\treturn (-1 - val)\n}\n\nfunc decodeFloat(src *bufio.Reader) (float64, int) {\n\tpb := readByte(src)\n\tmajor := pb & maskOutAdditionalType\n\tminor := pb & maskOutMajorType\n\tif major != majorTypeSimpleAndFloat {\n\t\tpanic(fmt.Errorf(\"Incorrect Major type is: %d in decodeFloat\", major))\n\t}\n\n\tswitch minor {\n\tcase additionalTypeFloat16:\n\t\tpanic(fmt.Errorf(\"float16 is not suppported in decodeFloat\"))\n\n\tcase additionalTypeFloat32:\n\t\tpb := readNBytes(src, 4)\n\t\tswitch string(pb) {\n\t\tcase float32Nan:\n\t\t\treturn math.NaN(), isFloat32\n\t\tcase float32PosInfinity:\n\t\t\treturn math.Inf(0), isFloat32\n\t\tcase float32NegInfinity:\n\t\t\treturn math.Inf(-1), isFloat32\n\t\t}\n\t\tn := uint32(0)\n\t\tfor i := 0; i < 4; i++ {\n\t\t\tn = n * 256\n\t\t\tn += uint32(pb[i])\n\t\t}\n\t\tval := math.Float32frombits(n)\n\t\treturn float64(val), isFloat32\n\tcase additionalTypeFloat64:\n\t\tpb := readNBytes(src, 8)\n\t\tswitch string(pb) {\n\t\tcase float64Nan:\n\t\t\treturn math.NaN(), isFloat64\n\t\tcase float64PosInfinity:\n\t\t\treturn math.Inf(0), isFloat64\n\t\tcase float64NegInfinity:\n\t\t\treturn math.Inf(-1), isFloat64\n\t\t}\n\t\tn := uint64(0)\n\t\tfor i := 0; i < 8; i++ {\n\t\t\tn = n * 256\n\t\t\tn += uint64(pb[i])\n\t\t}\n\t\tval := math.Float64frombits(n)\n\t\treturn val, isFloat64\n\t}\n\tpanic(fmt.Errorf(\"Invalid Additional Type: %d in decodeFloat\", minor))\n}\n\nfunc decodeStringComplex(dst []byte, s string, pos uint) []byte {\n\ti := int(pos)\n\tstart := 0\n\n\tfor i < len(s) {\n\t\tb := s[i]\n\t\tif b >= utf8.RuneSelf {\n\t\t\tr, size := utf8.DecodeRuneInString(s[i:])\n\t\t\tif r == utf8.RuneError && size == 1 {\n\t\t\t\t// In case of error, first append previous simple characters to\n\t\t\t\t// the byte slice if any and append a replacement character code\n\t\t\t\t// in place of the invalid sequence.\n\t\t\t\tif start < i {\n\t\t\t\t\tdst = append(dst, s[start:i]...)\n\t\t\t\t}\n\t\t\t\tdst = append(dst, `\\ufffd`...)\n\t\t\t\ti += size\n\t\t\t\tstart = i\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ti += size\n\t\t\tcontinue\n\t\t}\n\t\tif b >= 0x20 && b <= 0x7e && b != '\\\\' && b != '\"' {\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\t\t// We encountered a character that needs to be encoded.\n\t\t// Let's append the previous simple characters to the byte slice\n\t\t// and switch our operation to read and encode the remainder\n\t\t// characters byte-by-byte.\n\t\tif start < i {\n\t\t\tdst = append(dst, s[start:i]...)\n\t\t}\n\t\tswitch b {\n\t\tcase '\"', '\\\\':\n\t\t\tdst = append(dst, '\\\\', b)\n\t\tcase '\\b':\n\t\t\tdst = append(dst, '\\\\', 'b')\n\t\tcase '\\f':\n\t\t\tdst = append(dst, '\\\\', 'f')\n\t\tcase '\\n':\n\t\t\tdst = append(dst, '\\\\', 'n')\n\t\tcase '\\r':\n\t\t\tdst = append(dst, '\\\\', 'r')\n\t\tcase '\\t':\n\t\t\tdst = append(dst, '\\\\', 't')\n\t\tdefault:\n\t\t\tdst = append(dst, '\\\\', 'u', '0', '0', hexTable[b>>4], hexTable[b&0xF])\n\t\t}\n\t\ti++\n\t\tstart = i\n\t}\n\tif start < len(s) {\n\t\tdst = append(dst, s[start:]...)\n\t}\n\treturn dst\n}\n\nfunc decodeString(src *bufio.Reader, noQuotes bool) []byte {\n\tpb := readByte(src)\n\tmajor := pb & maskOutAdditionalType\n\tminor := pb & maskOutMajorType\n\tif major != majorTypeByteString {\n\t\tpanic(fmt.Errorf(\"Major type is: %d in decodeString\", major))\n\t}\n\tresult := []byte{}\n\tif !noQuotes {\n\t\tresult = append(result, '\"')\n\t}\n\tlength := decodeIntAdditonalType(src, minor)\n\tlen := int(length)\n\tpbs := readNBytes(src, len)\n\tresult = append(result, pbs...)\n\tif noQuotes {\n\t\treturn result\n\t}\n\treturn append(result, '\"')\n}\n\nfunc decodeUTF8String(src *bufio.Reader) []byte {\n\tpb := readByte(src)\n\tmajor := pb & maskOutAdditionalType\n\tminor := pb & maskOutMajorType\n\tif major != majorTypeUtf8String {\n\t\tpanic(fmt.Errorf(\"Major type is: %d in decodeUTF8String\", major))\n\t}\n\tresult := []byte{'\"'}\n\tlength := decodeIntAdditonalType(src, minor)\n\tlen := int(length)\n\tpbs := readNBytes(src, len)\n\n\tfor i := 0; i < len; i++ {\n\t\t// Check if the character needs encoding. Control characters, slashes,\n\t\t// and the double quote need json encoding. Bytes above the ascii\n\t\t// boundary needs utf8 encoding.\n\t\tif pbs[i] < 0x20 || pbs[i] > 0x7e || pbs[i] == '\\\\' || pbs[i] == '\"' {\n\t\t\t// We encountered a character that needs to be encoded. Switch\n\t\t\t// to complex version of the algorithm.\n\t\t\tdst := []byte{'\"'}\n\t\t\tdst = decodeStringComplex(dst, string(pbs), uint(i))\n\t\t\treturn append(dst, '\"')\n\t\t}\n\t}\n\t// The string has no need for encoding an therefore is directly\n\t// appended to the byte slice.\n\tresult = append(result, pbs...)\n\treturn append(result, '\"')\n}\n\nfunc array2Json(src *bufio.Reader, dst io.Writer) {\n\tdst.Write([]byte{'['})\n\tpb := readByte(src)\n\tmajor := pb & maskOutAdditionalType\n\tminor := pb & maskOutMajorType\n\tif major != majorTypeArray {\n\t\tpanic(fmt.Errorf(\"Major type is: %d in array2Json\", major))\n\t}\n\tlen := 0\n\tunSpecifiedCount := false\n\tif minor == additionalTypeInfiniteCount {\n\t\tunSpecifiedCount = true\n\t} else {\n\t\tlength := decodeIntAdditonalType(src, minor)\n\t\tlen = int(length)\n\t}\n\tfor i := 0; unSpecifiedCount || i < len; i++ {\n\t\tif unSpecifiedCount {\n\t\t\tpb, e := src.Peek(1)\n\t\t\tif e != nil {\n\t\t\t\tpanic(e)\n\t\t\t}\n\t\t\tif pb[0] == byte(majorTypeSimpleAndFloat|additionalTypeBreak) {\n\t\t\t\treadByte(src)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tcbor2JsonOneObject(src, dst)\n\t\tif unSpecifiedCount {\n\t\t\tpb, e := src.Peek(1)\n\t\t\tif e != nil {\n\t\t\t\tpanic(e)\n\t\t\t}\n\t\t\tif pb[0] == byte(majorTypeSimpleAndFloat|additionalTypeBreak) {\n\t\t\t\treadByte(src)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdst.Write([]byte{','})\n\t\t} else if i+1 < len {\n\t\t\tdst.Write([]byte{','})\n\t\t}\n\t}\n\tdst.Write([]byte{']'})\n}\n\nfunc map2Json(src *bufio.Reader, dst io.Writer) {\n\tpb := readByte(src)\n\tmajor := pb & maskOutAdditionalType\n\tminor := pb & maskOutMajorType\n\tif major != majorTypeMap {\n\t\tpanic(fmt.Errorf(\"Major type is: %d in map2Json\", major))\n\t}\n\tlen := 0\n\tunSpecifiedCount := false\n\tif minor == additionalTypeInfiniteCount {\n\t\tunSpecifiedCount = true\n\t} else {\n\t\tlength := decodeIntAdditonalType(src, minor)\n\t\tlen = int(length)\n\t}\n\tdst.Write([]byte{'{'})\n\tfor i := 0; unSpecifiedCount || i < len; i++ {\n\t\tif unSpecifiedCount {\n\t\t\tpb, e := src.Peek(1)\n\t\t\tif e != nil {\n\t\t\t\tpanic(e)\n\t\t\t}\n\t\t\tif pb[0] == byte(majorTypeSimpleAndFloat|additionalTypeBreak) {\n\t\t\t\treadByte(src)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tcbor2JsonOneObject(src, dst)\n\t\tif i%2 == 0 {\n\t\t\t// Even position values are keys.\n\t\t\tdst.Write([]byte{':'})\n\t\t} else {\n\t\t\tif unSpecifiedCount {\n\t\t\t\tpb, e := src.Peek(1)\n\t\t\t\tif e != nil {\n\t\t\t\t\tpanic(e)\n\t\t\t\t}\n\t\t\t\tif pb[0] == byte(majorTypeSimpleAndFloat|additionalTypeBreak) {\n\t\t\t\t\treadByte(src)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tdst.Write([]byte{','})\n\t\t\t} else if i+1 < len {\n\t\t\t\tdst.Write([]byte{','})\n\t\t\t}\n\t\t}\n\t}\n\tdst.Write([]byte{'}'})\n}\n\nfunc decodeTagData(src *bufio.Reader) []byte {\n\tpb := readByte(src)\n\tmajor := pb & maskOutAdditionalType\n\tminor := pb & maskOutMajorType\n\tif major != majorTypeTags {\n\t\tpanic(fmt.Errorf(\"Major type is: %d in decodeTagData\", major))\n\t}\n\tswitch minor {\n\tcase additionalTypeTimestamp:\n\t\treturn decodeTimeStamp(src)\n\n\t// Tag value is larger than 256 (so uint16).\n\tcase additionalTypeIntUint16:\n\t\tval := decodeIntAdditonalType(src, minor)\n\n\t\tswitch uint16(val) {\n\t\tcase additionalTypeEmbeddedJSON:\n\t\t\tpb := readByte(src)\n\t\t\tdataMajor := pb & maskOutAdditionalType\n\t\t\tif dataMajor != majorTypeByteString {\n\t\t\t\tpanic(fmt.Errorf(\"Unsupported embedded Type: %d in decodeEmbeddedJSON\", dataMajor))\n\t\t\t}\n\t\t\tsrc.UnreadByte()\n\t\t\treturn decodeString(src, true)\n\n\t\tcase additionalTypeTagNetworkAddr:\n\t\t\toctets := decodeString(src, true)\n\t\t\tss := []byte{'\"'}\n\t\t\tswitch len(octets) {\n\t\t\tcase 6: // MAC address.\n\t\t\t\tha := net.HardwareAddr(octets)\n\t\t\t\tss = append(append(ss, ha.String()...), '\"')\n\t\t\tcase 4: // IPv4 address.\n\t\t\t\tfallthrough\n\t\t\tcase 16: // IPv6 address.\n\t\t\t\tip := net.IP(octets)\n\t\t\t\tss = append(append(ss, ip.String()...), '\"')\n\t\t\tdefault:\n\t\t\t\tpanic(fmt.Errorf(\"Unexpected Network Address length: %d (expected 4,6,16)\", len(octets)))\n\t\t\t}\n\t\t\treturn ss\n\n\t\tcase additionalTypeTagNetworkPrefix:\n\t\t\tpb := readByte(src)\n\t\t\tif pb != byte(majorTypeMap|0x1) {\n\t\t\t\tpanic(fmt.Errorf(\"IP Prefix is NOT of MAP of 1 elements as expected\"))\n\t\t\t}\n\t\t\toctets := decodeString(src, true)\n\t\t\tval := decodeInteger(src)\n\t\t\tip := net.IP(octets)\n\t\t\tvar mask net.IPMask\n\t\t\tpfxLen := int(val)\n\t\t\tif len(octets) == 4 {\n\t\t\t\tmask = net.CIDRMask(pfxLen, 32)\n\t\t\t} else {\n\t\t\t\tmask = net.CIDRMask(pfxLen, 128)\n\t\t\t}\n\t\t\tipPfx := net.IPNet{IP: ip, Mask: mask}\n\t\t\tss := []byte{'\"'}\n\t\t\tss = append(append(ss, ipPfx.String()...), '\"')\n\t\t\treturn ss\n\n\t\tcase additionalTypeTagHexString:\n\t\t\toctets := decodeString(src, true)\n\t\t\tss := []byte{'\"'}\n\t\t\tfor _, v := range octets {\n\t\t\t\tss = append(ss, hexTable[v>>4], hexTable[v&0x0f])\n\t\t\t}\n\t\t\treturn append(ss, '\"')\n\n\t\tdefault:\n\t\t\tpanic(fmt.Errorf(\"Unsupported Additional Tag Type: %d in decodeTagData\", val))\n\t\t}\n\t}\n\tpanic(fmt.Errorf(\"Unsupported Additional Type: %d in decodeTagData\", minor))\n}\n\nfunc decodeTimeStamp(src *bufio.Reader) []byte {\n\tpb := readByte(src)\n\tsrc.UnreadByte()\n\ttsMajor := pb & maskOutAdditionalType\n\tif tsMajor == majorTypeUnsignedInt || tsMajor == majorTypeNegativeInt {\n\t\tn := decodeInteger(src)\n\t\tt := time.Unix(n, 0)\n\t\tif decodeTimeZone != nil {\n\t\t\tt = t.In(decodeTimeZone)\n\t\t} else {\n\t\t\tt = t.In(time.UTC)\n\t\t}\n\t\ttsb := []byte{}\n\t\ttsb = append(tsb, '\"')\n\t\ttsb = t.AppendFormat(tsb, IntegerTimeFieldFormat)\n\t\ttsb = append(tsb, '\"')\n\t\treturn tsb\n\t} else if tsMajor == majorTypeSimpleAndFloat {\n\t\tn, _ := decodeFloat(src)\n\t\tsecs := int64(n)\n\t\tn -= float64(secs)\n\t\tn *= float64(1e9)\n\t\tt := time.Unix(secs, int64(n))\n\t\tif decodeTimeZone != nil {\n\t\t\tt = t.In(decodeTimeZone)\n\t\t} else {\n\t\t\tt = t.In(time.UTC)\n\t\t}\n\t\ttsb := []byte{}\n\t\ttsb = append(tsb, '\"')\n\t\ttsb = t.AppendFormat(tsb, NanoTimeFieldFormat)\n\t\ttsb = append(tsb, '\"')\n\t\treturn tsb\n\t}\n\tpanic(fmt.Errorf(\"TS format is neigther int nor float: %d\", tsMajor))\n}\n\nfunc decodeSimpleFloat(src *bufio.Reader) []byte {\n\tpb := readByte(src)\n\tmajor := pb & maskOutAdditionalType\n\tminor := pb & maskOutMajorType\n\tif major != majorTypeSimpleAndFloat {\n\t\tpanic(fmt.Errorf(\"Major type is: %d in decodeSimpleFloat\", major))\n\t}\n\tswitch minor {\n\tcase additionalTypeBoolTrue:\n\t\treturn []byte(\"true\")\n\tcase additionalTypeBoolFalse:\n\t\treturn []byte(\"false\")\n\tcase additionalTypeNull:\n\t\treturn []byte(\"null\")\n\tcase additionalTypeFloat16:\n\t\tfallthrough\n\tcase additionalTypeFloat32:\n\t\tfallthrough\n\tcase additionalTypeFloat64:\n\t\tsrc.UnreadByte()\n\t\tv, bc := decodeFloat(src)\n\t\tba := []byte{}\n\t\tswitch {\n\t\tcase math.IsNaN(v):\n\t\t\treturn []byte(\"\\\"NaN\\\"\")\n\t\tcase math.IsInf(v, 1):\n\t\t\treturn []byte(\"\\\"+Inf\\\"\")\n\t\tcase math.IsInf(v, -1):\n\t\t\treturn []byte(\"\\\"-Inf\\\"\")\n\t\t}\n\t\tif bc == isFloat32 {\n\t\t\tba = strconv.AppendFloat(ba, v, 'f', -1, 32)\n\t\t} else if bc == isFloat64 {\n\t\t\tba = strconv.AppendFloat(ba, v, 'f', -1, 64)\n\t\t} else {\n\t\t\tpanic(fmt.Errorf(\"Invalid Float precision from decodeFloat: %d\", bc))\n\t\t}\n\t\treturn ba\n\tdefault:\n\t\tpanic(fmt.Errorf(\"Invalid Additional Type: %d in decodeSimpleFloat\", minor))\n\t}\n}\n\nfunc cbor2JsonOneObject(src *bufio.Reader, dst io.Writer) {\n\tpb, e := src.Peek(1)\n\tif e != nil {\n\t\tpanic(e)\n\t}\n\tmajor := (pb[0] & maskOutAdditionalType)\n\n\tswitch major {\n\tcase majorTypeUnsignedInt:\n\t\tfallthrough\n\tcase majorTypeNegativeInt:\n\t\tn := decodeInteger(src)\n\t\tdst.Write([]byte(strconv.Itoa(int(n))))\n\n\tcase majorTypeByteString:\n\t\ts := decodeString(src, false)\n\t\tdst.Write(s)\n\n\tcase majorTypeUtf8String:\n\t\ts := decodeUTF8String(src)\n\t\tdst.Write(s)\n\n\tcase majorTypeArray:\n\t\tarray2Json(src, dst)\n\n\tcase majorTypeMap:\n\t\tmap2Json(src, dst)\n\n\tcase majorTypeTags:\n\t\ts := decodeTagData(src)\n\t\tdst.Write(s)\n\n\tcase majorTypeSimpleAndFloat:\n\t\ts := decodeSimpleFloat(src)\n\t\tdst.Write(s)\n\t}\n}\n\nfunc moreBytesToRead(src *bufio.Reader) bool {\n\t_, e := src.ReadByte()\n\tif e == nil {\n\t\tsrc.UnreadByte()\n\t\treturn true\n\t}\n\treturn false\n}\n\n// Cbor2JsonManyObjects decodes all the CBOR Objects read from src\n// reader. It keeps on decoding until reader returns EOF (error when reading).\n// Decoded string is written to the dst. At the end of every CBOR Object\n// newline is written to the output stream.\n//\n// Returns error (if any) that was encountered during decode.\n// The child functions will generate a panic when error is encountered and\n// this function will recover non-runtime Errors and return the reason as error.\nfunc Cbor2JsonManyObjects(src io.Reader, dst io.Writer) (err error) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tif _, ok := r.(runtime.Error); ok {\n\t\t\t\tpanic(r)\n\t\t\t}\n\t\t\terr = r.(error)\n\t\t}\n\t}()\n\tbufRdr := bufio.NewReader(src)\n\tfor moreBytesToRead(bufRdr) {\n\t\tcbor2JsonOneObject(bufRdr, dst)\n\t\tdst.Write([]byte(\"\\n\"))\n\t}\n\treturn nil\n}\n\n// Detect if the bytes to be printed is Binary or not.\nfunc binaryFmt(p []byte) bool {\n\tif len(p) > 0 && p[0] > 0x7F {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc getReader(str string) *bufio.Reader {\n\treturn bufio.NewReader(strings.NewReader(str))\n}\n\n// DecodeIfBinaryToString converts a binary formatted log msg to a\n// JSON formatted String Log message - suitable for printing to Console/Syslog.\nfunc DecodeIfBinaryToString(in []byte) string {\n\tif binaryFmt(in) {\n\t\tvar b bytes.Buffer\n\t\tCbor2JsonManyObjects(strings.NewReader(string(in)), &b)\n\t\treturn b.String()\n\t}\n\treturn string(in)\n}\n\n// DecodeObjectToStr checks if the input is a binary format, if so,\n// it will decode a single Object and return the decoded string.\nfunc DecodeObjectToStr(in []byte) string {\n\tif binaryFmt(in) {\n\t\tvar b bytes.Buffer\n\t\tcbor2JsonOneObject(getReader(string(in)), &b)\n\t\treturn b.String()\n\t}\n\treturn string(in)\n}\n\n// DecodeIfBinaryToBytes checks if the input is a binary format, if so,\n// it will decode all Objects and return the decoded string as byte array.\nfunc DecodeIfBinaryToBytes(in []byte) []byte {\n\tif binaryFmt(in) {\n\t\tvar b bytes.Buffer\n\t\tCbor2JsonManyObjects(bytes.NewReader(in), &b)\n\t\treturn b.Bytes()\n\t}\n\treturn in\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/internal/cbor/string.go",
    "content": "package cbor\n\n// AppendStrings encodes and adds an array of strings to the dst byte array.\nfunc (e Encoder) AppendStrings(dst []byte, vals []string) []byte {\n\tmajor := majorTypeArray\n\tl := len(vals)\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\tfor _, v := range vals {\n\t\tdst = e.AppendString(dst, v)\n\t}\n\treturn dst\n}\n\n// AppendString encodes and adds a string to the dst byte array.\nfunc (Encoder) AppendString(dst []byte, s string) []byte {\n\tmajor := majorTypeUtf8String\n\n\tl := len(s)\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, majorTypeUtf8String, uint64(l))\n\t}\n\treturn append(dst, s...)\n}\n\n// AppendBytes encodes and adds an array of bytes to the dst byte array.\nfunc (Encoder) AppendBytes(dst, s []byte) []byte {\n\tmajor := majorTypeByteString\n\n\tl := len(s)\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\treturn append(dst, s...)\n}\n\n// AppendEmbeddedJSON adds a tag and embeds input JSON as such.\nfunc AppendEmbeddedJSON(dst, s []byte) []byte {\n\tmajor := majorTypeTags\n\tminor := additionalTypeEmbeddedJSON\n\n\t// Append the TAG to indicate this is Embedded JSON.\n\tdst = append(dst, byte(major|additionalTypeIntUint16))\n\tdst = append(dst, byte(minor>>8))\n\tdst = append(dst, byte(minor&0xff))\n\n\t// Append the JSON Object as Byte String.\n\tmajor = majorTypeByteString\n\n\tl := len(s)\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\treturn append(dst, s...)\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/internal/cbor/time.go",
    "content": "package cbor\n\nimport (\n\t\"time\"\n)\n\nfunc appendIntegerTimestamp(dst []byte, t time.Time) []byte {\n\tmajor := majorTypeTags\n\tminor := additionalTypeTimestamp\n\tdst = append(dst, byte(major|minor))\n\tsecs := t.Unix()\n\tvar val uint64\n\tif secs < 0 {\n\t\tmajor = majorTypeNegativeInt\n\t\tval = uint64(-secs - 1)\n\t} else {\n\t\tmajor = majorTypeUnsignedInt\n\t\tval = uint64(secs)\n\t}\n\tdst = appendCborTypePrefix(dst, major, uint64(val))\n\treturn dst\n}\n\nfunc (e Encoder) appendFloatTimestamp(dst []byte, t time.Time) []byte {\n\tmajor := majorTypeTags\n\tminor := additionalTypeTimestamp\n\tdst = append(dst, byte(major|minor))\n\tsecs := t.Unix()\n\tnanos := t.Nanosecond()\n\tvar val float64\n\tval = float64(secs)*1.0 + float64(nanos)*1E-9\n\treturn e.AppendFloat64(dst, val)\n}\n\n// AppendTime encodes and adds a timestamp to the dst byte array.\nfunc (e Encoder) AppendTime(dst []byte, t time.Time, unused string) []byte {\n\tutc := t.UTC()\n\tif utc.Nanosecond() == 0 {\n\t\treturn appendIntegerTimestamp(dst, utc)\n\t}\n\treturn e.appendFloatTimestamp(dst, utc)\n}\n\n// AppendTimes encodes and adds an array of timestamps to the dst byte array.\nfunc (e Encoder) AppendTimes(dst []byte, vals []time.Time, unused string) []byte {\n\tmajor := majorTypeArray\n\tl := len(vals)\n\tif l == 0 {\n\t\treturn e.AppendArrayEnd(e.AppendArrayStart(dst))\n\t}\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\n\tfor _, t := range vals {\n\t\tdst = e.AppendTime(dst, t, unused)\n\t}\n\treturn dst\n}\n\n// AppendDuration encodes and adds a duration to the dst byte array.\n// useInt field indicates whether to store the duration as seconds (integer) or\n// as seconds+nanoseconds (float).\nfunc (e Encoder) AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte {\n\tif useInt {\n\t\treturn e.AppendInt64(dst, int64(d/unit))\n\t}\n\treturn e.AppendFloat64(dst, float64(d)/float64(unit))\n}\n\n// AppendDurations encodes and adds an array of durations to the dst byte array.\n// useInt field indicates whether to store the duration as seconds (integer) or\n// as seconds+nanoseconds (float).\nfunc (e Encoder) AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte {\n\tmajor := majorTypeArray\n\tl := len(vals)\n\tif l == 0 {\n\t\treturn e.AppendArrayEnd(e.AppendArrayStart(dst))\n\t}\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\tfor _, d := range vals {\n\t\tdst = e.AppendDuration(dst, d, unit, useInt)\n\t}\n\treturn dst\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/internal/cbor/types.go",
    "content": "package cbor\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"math\"\n\t\"net\"\n)\n\n// AppendNil inserts a 'Nil' object into the dst byte array.\nfunc (Encoder) AppendNil(dst []byte) []byte {\n\treturn append(dst, byte(majorTypeSimpleAndFloat|additionalTypeNull))\n}\n\n// AppendBeginMarker inserts a map start into the dst byte array.\nfunc (Encoder) AppendBeginMarker(dst []byte) []byte {\n\treturn append(dst, byte(majorTypeMap|additionalTypeInfiniteCount))\n}\n\n// AppendEndMarker inserts a map end into the dst byte array.\nfunc (Encoder) AppendEndMarker(dst []byte) []byte {\n\treturn append(dst, byte(majorTypeSimpleAndFloat|additionalTypeBreak))\n}\n\n// AppendObjectData takes an object in form of a byte array and appends to dst.\nfunc (Encoder) AppendObjectData(dst []byte, o []byte) []byte {\n\t// BeginMarker is present in the dst, which\n\t// should not be copied when appending to existing data.\n\treturn append(dst, o[1:]...)\n}\n\n// AppendArrayStart adds markers to indicate the start of an array.\nfunc (Encoder) AppendArrayStart(dst []byte) []byte {\n\treturn append(dst, byte(majorTypeArray|additionalTypeInfiniteCount))\n}\n\n// AppendArrayEnd adds markers to indicate the end of an array.\nfunc (Encoder) AppendArrayEnd(dst []byte) []byte {\n\treturn append(dst, byte(majorTypeSimpleAndFloat|additionalTypeBreak))\n}\n\n// AppendArrayDelim adds markers to indicate end of a particular array element.\nfunc (Encoder) AppendArrayDelim(dst []byte) []byte {\n\t//No delimiters needed in cbor\n\treturn dst\n}\n\n// AppendLineBreak is a noop that keep API compat with json encoder.\nfunc (Encoder) AppendLineBreak(dst []byte) []byte {\n\t// No line breaks needed in binary format.\n\treturn dst\n}\n\n// AppendBool encodes and inserts a boolean value into the dst byte array.\nfunc (Encoder) AppendBool(dst []byte, val bool) []byte {\n\tb := additionalTypeBoolFalse\n\tif val {\n\t\tb = additionalTypeBoolTrue\n\t}\n\treturn append(dst, byte(majorTypeSimpleAndFloat|b))\n}\n\n// AppendBools encodes and inserts an array of boolean values into the dst byte array.\nfunc (e Encoder) AppendBools(dst []byte, vals []bool) []byte {\n\tmajor := majorTypeArray\n\tl := len(vals)\n\tif l == 0 {\n\t\treturn e.AppendArrayEnd(e.AppendArrayStart(dst))\n\t}\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\tfor _, v := range vals {\n\t\tdst = e.AppendBool(dst, v)\n\t}\n\treturn dst\n}\n\n// AppendInt encodes and inserts an integer value into the dst byte array.\nfunc (Encoder) AppendInt(dst []byte, val int) []byte {\n\tmajor := majorTypeUnsignedInt\n\tcontentVal := val\n\tif val < 0 {\n\t\tmajor = majorTypeNegativeInt\n\t\tcontentVal = -val - 1\n\t}\n\tif contentVal <= additionalMax {\n\t\tlb := byte(contentVal)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(contentVal))\n\t}\n\treturn dst\n}\n\n// AppendInts encodes and inserts an array of integer values into the dst byte array.\nfunc (e Encoder) AppendInts(dst []byte, vals []int) []byte {\n\tmajor := majorTypeArray\n\tl := len(vals)\n\tif l == 0 {\n\t\treturn e.AppendArrayEnd(e.AppendArrayStart(dst))\n\t}\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\tfor _, v := range vals {\n\t\tdst = e.AppendInt(dst, v)\n\t}\n\treturn dst\n}\n\n// AppendInt8 encodes and inserts an int8 value into the dst byte array.\nfunc (e Encoder) AppendInt8(dst []byte, val int8) []byte {\n\treturn e.AppendInt(dst, int(val))\n}\n\n// AppendInts8 encodes and inserts an array of integer values into the dst byte array.\nfunc (e Encoder) AppendInts8(dst []byte, vals []int8) []byte {\n\tmajor := majorTypeArray\n\tl := len(vals)\n\tif l == 0 {\n\t\treturn e.AppendArrayEnd(e.AppendArrayStart(dst))\n\t}\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\tfor _, v := range vals {\n\t\tdst = e.AppendInt(dst, int(v))\n\t}\n\treturn dst\n}\n\n// AppendInt16 encodes and inserts a int16 value into the dst byte array.\nfunc (e Encoder) AppendInt16(dst []byte, val int16) []byte {\n\treturn e.AppendInt(dst, int(val))\n}\n\n// AppendInts16 encodes and inserts an array of int16 values into the dst byte array.\nfunc (e Encoder) AppendInts16(dst []byte, vals []int16) []byte {\n\tmajor := majorTypeArray\n\tl := len(vals)\n\tif l == 0 {\n\t\treturn e.AppendArrayEnd(e.AppendArrayStart(dst))\n\t}\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\tfor _, v := range vals {\n\t\tdst = e.AppendInt(dst, int(v))\n\t}\n\treturn dst\n}\n\n// AppendInt32 encodes and inserts a int32 value into the dst byte array.\nfunc (e Encoder) AppendInt32(dst []byte, val int32) []byte {\n\treturn e.AppendInt(dst, int(val))\n}\n\n// AppendInts32 encodes and inserts an array of int32 values into the dst byte array.\nfunc (e Encoder) AppendInts32(dst []byte, vals []int32) []byte {\n\tmajor := majorTypeArray\n\tl := len(vals)\n\tif l == 0 {\n\t\treturn e.AppendArrayEnd(e.AppendArrayStart(dst))\n\t}\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\tfor _, v := range vals {\n\t\tdst = e.AppendInt(dst, int(v))\n\t}\n\treturn dst\n}\n\n// AppendInt64 encodes and inserts a int64 value into the dst byte array.\nfunc (Encoder) AppendInt64(dst []byte, val int64) []byte {\n\tmajor := majorTypeUnsignedInt\n\tcontentVal := val\n\tif val < 0 {\n\t\tmajor = majorTypeNegativeInt\n\t\tcontentVal = -val - 1\n\t}\n\tif contentVal <= additionalMax {\n\t\tlb := byte(contentVal)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(contentVal))\n\t}\n\treturn dst\n}\n\n// AppendInts64 encodes and inserts an array of int64 values into the dst byte array.\nfunc (e Encoder) AppendInts64(dst []byte, vals []int64) []byte {\n\tmajor := majorTypeArray\n\tl := len(vals)\n\tif l == 0 {\n\t\treturn e.AppendArrayEnd(e.AppendArrayStart(dst))\n\t}\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\tfor _, v := range vals {\n\t\tdst = e.AppendInt64(dst, v)\n\t}\n\treturn dst\n}\n\n// AppendUint encodes and inserts an unsigned integer value into the dst byte array.\nfunc (e Encoder) AppendUint(dst []byte, val uint) []byte {\n\treturn e.AppendInt64(dst, int64(val))\n}\n\n// AppendUints encodes and inserts an array of unsigned integer values into the dst byte array.\nfunc (e Encoder) AppendUints(dst []byte, vals []uint) []byte {\n\tmajor := majorTypeArray\n\tl := len(vals)\n\tif l == 0 {\n\t\treturn e.AppendArrayEnd(e.AppendArrayStart(dst))\n\t}\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\tfor _, v := range vals {\n\t\tdst = e.AppendUint(dst, v)\n\t}\n\treturn dst\n}\n\n// AppendUint8 encodes and inserts a unsigned int8 value into the dst byte array.\nfunc (e Encoder) AppendUint8(dst []byte, val uint8) []byte {\n\treturn e.AppendUint(dst, uint(val))\n}\n\n// AppendUints8 encodes and inserts an array of uint8 values into the dst byte array.\nfunc (e Encoder) AppendUints8(dst []byte, vals []uint8) []byte {\n\tmajor := majorTypeArray\n\tl := len(vals)\n\tif l == 0 {\n\t\treturn e.AppendArrayEnd(e.AppendArrayStart(dst))\n\t}\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\tfor _, v := range vals {\n\t\tdst = e.AppendUint8(dst, v)\n\t}\n\treturn dst\n}\n\n// AppendUint16 encodes and inserts a uint16 value into the dst byte array.\nfunc (e Encoder) AppendUint16(dst []byte, val uint16) []byte {\n\treturn e.AppendUint(dst, uint(val))\n}\n\n// AppendUints16 encodes and inserts an array of uint16 values into the dst byte array.\nfunc (e Encoder) AppendUints16(dst []byte, vals []uint16) []byte {\n\tmajor := majorTypeArray\n\tl := len(vals)\n\tif l == 0 {\n\t\treturn e.AppendArrayEnd(e.AppendArrayStart(dst))\n\t}\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\tfor _, v := range vals {\n\t\tdst = e.AppendUint16(dst, v)\n\t}\n\treturn dst\n}\n\n// AppendUint32 encodes and inserts a uint32 value into the dst byte array.\nfunc (e Encoder) AppendUint32(dst []byte, val uint32) []byte {\n\treturn e.AppendUint(dst, uint(val))\n}\n\n// AppendUints32 encodes and inserts an array of uint32 values into the dst byte array.\nfunc (e Encoder) AppendUints32(dst []byte, vals []uint32) []byte {\n\tmajor := majorTypeArray\n\tl := len(vals)\n\tif l == 0 {\n\t\treturn e.AppendArrayEnd(e.AppendArrayStart(dst))\n\t}\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\tfor _, v := range vals {\n\t\tdst = e.AppendUint32(dst, v)\n\t}\n\treturn dst\n}\n\n// AppendUint64 encodes and inserts a uint64 value into the dst byte array.\nfunc (Encoder) AppendUint64(dst []byte, val uint64) []byte {\n\tmajor := majorTypeUnsignedInt\n\tcontentVal := val\n\tif contentVal <= additionalMax {\n\t\tlb := byte(contentVal)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(contentVal))\n\t}\n\treturn dst\n}\n\n// AppendUints64 encodes and inserts an array of uint64 values into the dst byte array.\nfunc (e Encoder) AppendUints64(dst []byte, vals []uint64) []byte {\n\tmajor := majorTypeArray\n\tl := len(vals)\n\tif l == 0 {\n\t\treturn e.AppendArrayEnd(e.AppendArrayStart(dst))\n\t}\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\tfor _, v := range vals {\n\t\tdst = e.AppendUint64(dst, v)\n\t}\n\treturn dst\n}\n\n// AppendFloat32 encodes and inserts a single precision float value into the dst byte array.\nfunc (Encoder) AppendFloat32(dst []byte, val float32) []byte {\n\tswitch {\n\tcase math.IsNaN(float64(val)):\n\t\treturn append(dst, \"\\xfa\\x7f\\xc0\\x00\\x00\"...)\n\tcase math.IsInf(float64(val), 1):\n\t\treturn append(dst, \"\\xfa\\x7f\\x80\\x00\\x00\"...)\n\tcase math.IsInf(float64(val), -1):\n\t\treturn append(dst, \"\\xfa\\xff\\x80\\x00\\x00\"...)\n\t}\n\tmajor := majorTypeSimpleAndFloat\n\tsubType := additionalTypeFloat32\n\tn := math.Float32bits(val)\n\tvar buf [4]byte\n\tfor i := uint(0); i < 4; i++ {\n\t\tbuf[i] = byte(n >> ((3 - i) * 8))\n\t}\n\treturn append(append(dst, byte(major|subType)), buf[0], buf[1], buf[2], buf[3])\n}\n\n// AppendFloats32 encodes and inserts an array of single precision float value into the dst byte array.\nfunc (e Encoder) AppendFloats32(dst []byte, vals []float32) []byte {\n\tmajor := majorTypeArray\n\tl := len(vals)\n\tif l == 0 {\n\t\treturn e.AppendArrayEnd(e.AppendArrayStart(dst))\n\t}\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\tfor _, v := range vals {\n\t\tdst = e.AppendFloat32(dst, v)\n\t}\n\treturn dst\n}\n\n// AppendFloat64 encodes and inserts a double precision float value into the dst byte array.\nfunc (Encoder) AppendFloat64(dst []byte, val float64) []byte {\n\tswitch {\n\tcase math.IsNaN(val):\n\t\treturn append(dst, \"\\xfb\\x7f\\xf8\\x00\\x00\\x00\\x00\\x00\\x00\"...)\n\tcase math.IsInf(val, 1):\n\t\treturn append(dst, \"\\xfb\\x7f\\xf0\\x00\\x00\\x00\\x00\\x00\\x00\"...)\n\tcase math.IsInf(val, -1):\n\t\treturn append(dst, \"\\xfb\\xff\\xf0\\x00\\x00\\x00\\x00\\x00\\x00\"...)\n\t}\n\tmajor := majorTypeSimpleAndFloat\n\tsubType := additionalTypeFloat64\n\tn := math.Float64bits(val)\n\tdst = append(dst, byte(major|subType))\n\tfor i := uint(1); i <= 8; i++ {\n\t\tb := byte(n >> ((8 - i) * 8))\n\t\tdst = append(dst, b)\n\t}\n\treturn dst\n}\n\n// AppendFloats64 encodes and inserts an array of double precision float values into the dst byte array.\nfunc (e Encoder) AppendFloats64(dst []byte, vals []float64) []byte {\n\tmajor := majorTypeArray\n\tl := len(vals)\n\tif l == 0 {\n\t\treturn e.AppendArrayEnd(e.AppendArrayStart(dst))\n\t}\n\tif l <= additionalMax {\n\t\tlb := byte(l)\n\t\tdst = append(dst, byte(major|lb))\n\t} else {\n\t\tdst = appendCborTypePrefix(dst, major, uint64(l))\n\t}\n\tfor _, v := range vals {\n\t\tdst = e.AppendFloat64(dst, v)\n\t}\n\treturn dst\n}\n\n// AppendInterface takes an arbitrary object and converts it to JSON and embeds it dst.\nfunc (e Encoder) AppendInterface(dst []byte, i interface{}) []byte {\n\tmarshaled, err := json.Marshal(i)\n\tif err != nil {\n\t\treturn e.AppendString(dst, fmt.Sprintf(\"marshaling error: %v\", err))\n\t}\n\treturn AppendEmbeddedJSON(dst, marshaled)\n}\n\n// AppendIPAddr encodes and inserts an IP Address (IPv4 or IPv6).\nfunc (e Encoder) AppendIPAddr(dst []byte, ip net.IP) []byte {\n\tdst = append(dst, byte(majorTypeTags|additionalTypeIntUint16))\n\tdst = append(dst, byte(additionalTypeTagNetworkAddr>>8))\n\tdst = append(dst, byte(additionalTypeTagNetworkAddr&0xff))\n\treturn e.AppendBytes(dst, ip)\n}\n\n// AppendIPPrefix encodes and inserts an IP Address Prefix (Address + Mask Length).\nfunc (e Encoder) AppendIPPrefix(dst []byte, pfx net.IPNet) []byte {\n\tdst = append(dst, byte(majorTypeTags|additionalTypeIntUint16))\n\tdst = append(dst, byte(additionalTypeTagNetworkPrefix>>8))\n\tdst = append(dst, byte(additionalTypeTagNetworkPrefix&0xff))\n\n\t// Prefix is a tuple (aka MAP of 1 pair of elements) -\n\t// first element is prefix, second is mask length.\n\tdst = append(dst, byte(majorTypeMap|0x1))\n\tdst = e.AppendBytes(dst, pfx.IP)\n\tmaskLen, _ := pfx.Mask.Size()\n\treturn e.AppendUint8(dst, uint8(maskLen))\n}\n\n// AppendMACAddr encodes and inserts an Hardware (MAC) address.\nfunc (e Encoder) AppendMACAddr(dst []byte, ha net.HardwareAddr) []byte {\n\tdst = append(dst, byte(majorTypeTags|additionalTypeIntUint16))\n\tdst = append(dst, byte(additionalTypeTagNetworkAddr>>8))\n\tdst = append(dst, byte(additionalTypeTagNetworkAddr&0xff))\n\treturn e.AppendBytes(dst, ha)\n}\n\n// AppendHex adds a TAG and inserts a hex bytes as a string.\nfunc (e Encoder) AppendHex(dst []byte, val []byte) []byte {\n\tdst = append(dst, byte(majorTypeTags|additionalTypeIntUint16))\n\tdst = append(dst, byte(additionalTypeTagHexString>>8))\n\tdst = append(dst, byte(additionalTypeTagHexString&0xff))\n\treturn e.AppendBytes(dst, val)\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/internal/json/base.go",
    "content": "package json\n\ntype Encoder struct{}\n\n// AppendKey appends a new key to the output JSON.\nfunc (e Encoder) AppendKey(dst []byte, key string) []byte {\n\tif dst[len(dst)-1] != '{' {\n\t\tdst = append(dst, ',')\n\t}\n\treturn append(e.AppendString(dst, key), ':')\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/internal/json/bytes.go",
    "content": "package json\n\nimport \"unicode/utf8\"\n\n// AppendBytes is a mirror of appendString with []byte arg\nfunc (Encoder) AppendBytes(dst, s []byte) []byte {\n\tdst = append(dst, '\"')\n\tfor i := 0; i < len(s); i++ {\n\t\tif !noEscapeTable[s[i]] {\n\t\t\tdst = appendBytesComplex(dst, s, i)\n\t\t\treturn append(dst, '\"')\n\t\t}\n\t}\n\tdst = append(dst, s...)\n\treturn append(dst, '\"')\n}\n\n// AppendHex encodes the input bytes to a hex string and appends\n// the encoded string to the input byte slice.\n//\n// The operation loops though each byte and encodes it as hex using\n// the hex lookup table.\nfunc (Encoder) AppendHex(dst, s []byte) []byte {\n\tdst = append(dst, '\"')\n\tfor _, v := range s {\n\t\tdst = append(dst, hex[v>>4], hex[v&0x0f])\n\t}\n\treturn append(dst, '\"')\n}\n\n// appendBytesComplex is a mirror of the appendStringComplex\n// with []byte arg\nfunc appendBytesComplex(dst, s []byte, i int) []byte {\n\tstart := 0\n\tfor i < len(s) {\n\t\tb := s[i]\n\t\tif b >= utf8.RuneSelf {\n\t\t\tr, size := utf8.DecodeRune(s[i:])\n\t\t\tif r == utf8.RuneError && size == 1 {\n\t\t\t\tif start < i {\n\t\t\t\t\tdst = append(dst, s[start:i]...)\n\t\t\t\t}\n\t\t\t\tdst = append(dst, `\\ufffd`...)\n\t\t\t\ti += size\n\t\t\t\tstart = i\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ti += size\n\t\t\tcontinue\n\t\t}\n\t\tif noEscapeTable[b] {\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\t\t// We encountered a character that needs to be encoded.\n\t\t// Let's append the previous simple characters to the byte slice\n\t\t// and switch our operation to read and encode the remainder\n\t\t// characters byte-by-byte.\n\t\tif start < i {\n\t\t\tdst = append(dst, s[start:i]...)\n\t\t}\n\t\tswitch b {\n\t\tcase '\"', '\\\\':\n\t\t\tdst = append(dst, '\\\\', b)\n\t\tcase '\\b':\n\t\t\tdst = append(dst, '\\\\', 'b')\n\t\tcase '\\f':\n\t\t\tdst = append(dst, '\\\\', 'f')\n\t\tcase '\\n':\n\t\t\tdst = append(dst, '\\\\', 'n')\n\t\tcase '\\r':\n\t\t\tdst = append(dst, '\\\\', 'r')\n\t\tcase '\\t':\n\t\t\tdst = append(dst, '\\\\', 't')\n\t\tdefault:\n\t\t\tdst = append(dst, '\\\\', 'u', '0', '0', hex[b>>4], hex[b&0xF])\n\t\t}\n\t\ti++\n\t\tstart = i\n\t}\n\tif start < len(s) {\n\t\tdst = append(dst, s[start:]...)\n\t}\n\treturn dst\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/internal/json/string.go",
    "content": "package json\n\nimport \"unicode/utf8\"\n\nconst hex = \"0123456789abcdef\"\n\nvar noEscapeTable = [256]bool{}\n\nfunc init() {\n\tfor i := 0; i <= 0x7e; i++ {\n\t\tnoEscapeTable[i] = i >= 0x20 && i != '\\\\' && i != '\"'\n\t}\n}\n\n// AppendStrings encodes the input strings to json and\n// appends the encoded string list to the input byte slice.\nfunc (e Encoder) AppendStrings(dst []byte, vals []string) []byte {\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = e.AppendString(dst, vals[0])\n\tif len(vals) > 1 {\n\t\tfor _, val := range vals[1:] {\n\t\t\tdst = e.AppendString(append(dst, ','), val)\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n\n// AppendString encodes the input string to json and appends\n// the encoded string to the input byte slice.\n//\n// The operation loops though each byte in the string looking\n// for characters that need json or utf8 encoding. If the string\n// does not need encoding, then the string is appended in it's\n// entirety to the byte slice.\n// If we encounter a byte that does need encoding, switch up\n// the operation and perform a byte-by-byte read-encode-append.\nfunc (Encoder) AppendString(dst []byte, s string) []byte {\n\t// Start with a double quote.\n\tdst = append(dst, '\"')\n\t// Loop through each character in the string.\n\tfor i := 0; i < len(s); i++ {\n\t\t// Check if the character needs encoding. Control characters, slashes,\n\t\t// and the double quote need json encoding. Bytes above the ascii\n\t\t// boundary needs utf8 encoding.\n\t\tif !noEscapeTable[s[i]] {\n\t\t\t// We encountered a character that needs to be encoded. Switch\n\t\t\t// to complex version of the algorithm.\n\t\t\tdst = appendStringComplex(dst, s, i)\n\t\t\treturn append(dst, '\"')\n\t\t}\n\t}\n\t// The string has no need for encoding an therefore is directly\n\t// appended to the byte slice.\n\tdst = append(dst, s...)\n\t// End with a double quote\n\treturn append(dst, '\"')\n}\n\n// appendStringComplex is used by appendString to take over an in\n// progress JSON string encoding that encountered a character that needs\n// to be encoded.\nfunc appendStringComplex(dst []byte, s string, i int) []byte {\n\tstart := 0\n\tfor i < len(s) {\n\t\tb := s[i]\n\t\tif b >= utf8.RuneSelf {\n\t\t\tr, size := utf8.DecodeRuneInString(s[i:])\n\t\t\tif r == utf8.RuneError && size == 1 {\n\t\t\t\t// In case of error, first append previous simple characters to\n\t\t\t\t// the byte slice if any and append a remplacement character code\n\t\t\t\t// in place of the invalid sequence.\n\t\t\t\tif start < i {\n\t\t\t\t\tdst = append(dst, s[start:i]...)\n\t\t\t\t}\n\t\t\t\tdst = append(dst, `\\ufffd`...)\n\t\t\t\ti += size\n\t\t\t\tstart = i\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ti += size\n\t\t\tcontinue\n\t\t}\n\t\tif noEscapeTable[b] {\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\t\t// We encountered a character that needs to be encoded.\n\t\t// Let's append the previous simple characters to the byte slice\n\t\t// and switch our operation to read and encode the remainder\n\t\t// characters byte-by-byte.\n\t\tif start < i {\n\t\t\tdst = append(dst, s[start:i]...)\n\t\t}\n\t\tswitch b {\n\t\tcase '\"', '\\\\':\n\t\t\tdst = append(dst, '\\\\', b)\n\t\tcase '\\b':\n\t\t\tdst = append(dst, '\\\\', 'b')\n\t\tcase '\\f':\n\t\t\tdst = append(dst, '\\\\', 'f')\n\t\tcase '\\n':\n\t\t\tdst = append(dst, '\\\\', 'n')\n\t\tcase '\\r':\n\t\t\tdst = append(dst, '\\\\', 'r')\n\t\tcase '\\t':\n\t\t\tdst = append(dst, '\\\\', 't')\n\t\tdefault:\n\t\t\tdst = append(dst, '\\\\', 'u', '0', '0', hex[b>>4], hex[b&0xF])\n\t\t}\n\t\ti++\n\t\tstart = i\n\t}\n\tif start < len(s) {\n\t\tdst = append(dst, s[start:]...)\n\t}\n\treturn dst\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/internal/json/time.go",
    "content": "package json\n\nimport (\n\t\"strconv\"\n\t\"time\"\n)\n\nconst (\n\t// Import from zerolog/global.go\n\ttimeFormatUnix   = \"\"\n\ttimeFormatUnixMs = \"UNIXMS\"\n\ttimeFormatUnixMicro = \"UNIXMICRO\"\n)\n\n// AppendTime formats the input time with the given format\n// and appends the encoded string to the input byte slice.\nfunc (e Encoder) AppendTime(dst []byte, t time.Time, format string) []byte {\n\tswitch format {\n\tcase timeFormatUnix:\n\t\treturn e.AppendInt64(dst, t.Unix())\n\tcase timeFormatUnixMs:\n\t\treturn e.AppendInt64(dst, t.UnixNano()/1000000)\n\tcase timeFormatUnixMicro:\n\t\treturn e.AppendInt64(dst, t.UnixNano()/1000)\n\t}\n\treturn append(t.AppendFormat(append(dst, '\"'), format), '\"')\n}\n\n// AppendTimes converts the input times with the given format\n// and appends the encoded string list to the input byte slice.\nfunc (Encoder) AppendTimes(dst []byte, vals []time.Time, format string) []byte {\n\tswitch format {\n\tcase timeFormatUnix:\n\t\treturn appendUnixTimes(dst, vals)\n\tcase timeFormatUnixMs:\n\t\treturn appendUnixMsTimes(dst, vals)\n\t}\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = append(vals[0].AppendFormat(append(dst, '\"'), format), '\"')\n\tif len(vals) > 1 {\n\t\tfor _, t := range vals[1:] {\n\t\t\tdst = append(t.AppendFormat(append(dst, ',', '\"'), format), '\"')\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n\nfunc appendUnixTimes(dst []byte, vals []time.Time) []byte {\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = strconv.AppendInt(dst, vals[0].Unix(), 10)\n\tif len(vals) > 1 {\n\t\tfor _, t := range vals[1:] {\n\t\t\tdst = strconv.AppendInt(append(dst, ','), t.Unix(), 10)\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n\nfunc appendUnixMsTimes(dst []byte, vals []time.Time) []byte {\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = strconv.AppendInt(dst, vals[0].UnixNano()/1000000, 10)\n\tif len(vals) > 1 {\n\t\tfor _, t := range vals[1:] {\n\t\t\tdst = strconv.AppendInt(append(dst, ','), t.UnixNano()/1000000, 10)\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n\n// AppendDuration formats the input duration with the given unit & format\n// and appends the encoded string to the input byte slice.\nfunc (e Encoder) AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte {\n\tif useInt {\n\t\treturn strconv.AppendInt(dst, int64(d/unit), 10)\n\t}\n\treturn e.AppendFloat64(dst, float64(d)/float64(unit))\n}\n\n// AppendDurations formats the input durations with the given unit & format\n// and appends the encoded string list to the input byte slice.\nfunc (e Encoder) AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte {\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = e.AppendDuration(dst, vals[0], unit, useInt)\n\tif len(vals) > 1 {\n\t\tfor _, d := range vals[1:] {\n\t\t\tdst = e.AppendDuration(append(dst, ','), d, unit, useInt)\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/internal/json/types.go",
    "content": "package json\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"math\"\n\t\"net\"\n\t\"strconv\"\n)\n\n// AppendNil inserts a 'Nil' object into the dst byte array.\nfunc (Encoder) AppendNil(dst []byte) []byte {\n\treturn append(dst, \"null\"...)\n}\n\n// AppendBeginMarker inserts a map start into the dst byte array.\nfunc (Encoder) AppendBeginMarker(dst []byte) []byte {\n\treturn append(dst, '{')\n}\n\n// AppendEndMarker inserts a map end into the dst byte array.\nfunc (Encoder) AppendEndMarker(dst []byte) []byte {\n\treturn append(dst, '}')\n}\n\n// AppendLineBreak appends a line break.\nfunc (Encoder) AppendLineBreak(dst []byte) []byte {\n\treturn append(dst, '\\n')\n}\n\n// AppendArrayStart adds markers to indicate the start of an array.\nfunc (Encoder) AppendArrayStart(dst []byte) []byte {\n\treturn append(dst, '[')\n}\n\n// AppendArrayEnd adds markers to indicate the end of an array.\nfunc (Encoder) AppendArrayEnd(dst []byte) []byte {\n\treturn append(dst, ']')\n}\n\n// AppendArrayDelim adds markers to indicate end of a particular array element.\nfunc (Encoder) AppendArrayDelim(dst []byte) []byte {\n\tif len(dst) > 0 {\n\t\treturn append(dst, ',')\n\t}\n\treturn dst\n}\n\n// AppendBool converts the input bool to a string and\n// appends the encoded string to the input byte slice.\nfunc (Encoder) AppendBool(dst []byte, val bool) []byte {\n\treturn strconv.AppendBool(dst, val)\n}\n\n// AppendBools encodes the input bools to json and\n// appends the encoded string list to the input byte slice.\nfunc (Encoder) AppendBools(dst []byte, vals []bool) []byte {\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = strconv.AppendBool(dst, vals[0])\n\tif len(vals) > 1 {\n\t\tfor _, val := range vals[1:] {\n\t\t\tdst = strconv.AppendBool(append(dst, ','), val)\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n\n// AppendInt converts the input int to a string and\n// appends the encoded string to the input byte slice.\nfunc (Encoder) AppendInt(dst []byte, val int) []byte {\n\treturn strconv.AppendInt(dst, int64(val), 10)\n}\n\n// AppendInts encodes the input ints to json and\n// appends the encoded string list to the input byte slice.\nfunc (Encoder) AppendInts(dst []byte, vals []int) []byte {\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = strconv.AppendInt(dst, int64(vals[0]), 10)\n\tif len(vals) > 1 {\n\t\tfor _, val := range vals[1:] {\n\t\t\tdst = strconv.AppendInt(append(dst, ','), int64(val), 10)\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n\n// AppendInt8 converts the input []int8 to a string and\n// appends the encoded string to the input byte slice.\nfunc (Encoder) AppendInt8(dst []byte, val int8) []byte {\n\treturn strconv.AppendInt(dst, int64(val), 10)\n}\n\n// AppendInts8 encodes the input int8s to json and\n// appends the encoded string list to the input byte slice.\nfunc (Encoder) AppendInts8(dst []byte, vals []int8) []byte {\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = strconv.AppendInt(dst, int64(vals[0]), 10)\n\tif len(vals) > 1 {\n\t\tfor _, val := range vals[1:] {\n\t\t\tdst = strconv.AppendInt(append(dst, ','), int64(val), 10)\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n\n// AppendInt16 converts the input int16 to a string and\n// appends the encoded string to the input byte slice.\nfunc (Encoder) AppendInt16(dst []byte, val int16) []byte {\n\treturn strconv.AppendInt(dst, int64(val), 10)\n}\n\n// AppendInts16 encodes the input int16s to json and\n// appends the encoded string list to the input byte slice.\nfunc (Encoder) AppendInts16(dst []byte, vals []int16) []byte {\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = strconv.AppendInt(dst, int64(vals[0]), 10)\n\tif len(vals) > 1 {\n\t\tfor _, val := range vals[1:] {\n\t\t\tdst = strconv.AppendInt(append(dst, ','), int64(val), 10)\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n\n// AppendInt32 converts the input int32 to a string and\n// appends the encoded string to the input byte slice.\nfunc (Encoder) AppendInt32(dst []byte, val int32) []byte {\n\treturn strconv.AppendInt(dst, int64(val), 10)\n}\n\n// AppendInts32 encodes the input int32s to json and\n// appends the encoded string list to the input byte slice.\nfunc (Encoder) AppendInts32(dst []byte, vals []int32) []byte {\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = strconv.AppendInt(dst, int64(vals[0]), 10)\n\tif len(vals) > 1 {\n\t\tfor _, val := range vals[1:] {\n\t\t\tdst = strconv.AppendInt(append(dst, ','), int64(val), 10)\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n\n// AppendInt64 converts the input int64 to a string and\n// appends the encoded string to the input byte slice.\nfunc (Encoder) AppendInt64(dst []byte, val int64) []byte {\n\treturn strconv.AppendInt(dst, val, 10)\n}\n\n// AppendInts64 encodes the input int64s to json and\n// appends the encoded string list to the input byte slice.\nfunc (Encoder) AppendInts64(dst []byte, vals []int64) []byte {\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = strconv.AppendInt(dst, vals[0], 10)\n\tif len(vals) > 1 {\n\t\tfor _, val := range vals[1:] {\n\t\t\tdst = strconv.AppendInt(append(dst, ','), val, 10)\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n\n// AppendUint converts the input uint to a string and\n// appends the encoded string to the input byte slice.\nfunc (Encoder) AppendUint(dst []byte, val uint) []byte {\n\treturn strconv.AppendUint(dst, uint64(val), 10)\n}\n\n// AppendUints encodes the input uints to json and\n// appends the encoded string list to the input byte slice.\nfunc (Encoder) AppendUints(dst []byte, vals []uint) []byte {\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = strconv.AppendUint(dst, uint64(vals[0]), 10)\n\tif len(vals) > 1 {\n\t\tfor _, val := range vals[1:] {\n\t\t\tdst = strconv.AppendUint(append(dst, ','), uint64(val), 10)\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n\n// AppendUint8 converts the input uint8 to a string and\n// appends the encoded string to the input byte slice.\nfunc (Encoder) AppendUint8(dst []byte, val uint8) []byte {\n\treturn strconv.AppendUint(dst, uint64(val), 10)\n}\n\n// AppendUints8 encodes the input uint8s to json and\n// appends the encoded string list to the input byte slice.\nfunc (Encoder) AppendUints8(dst []byte, vals []uint8) []byte {\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = strconv.AppendUint(dst, uint64(vals[0]), 10)\n\tif len(vals) > 1 {\n\t\tfor _, val := range vals[1:] {\n\t\t\tdst = strconv.AppendUint(append(dst, ','), uint64(val), 10)\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n\n// AppendUint16 converts the input uint16 to a string and\n// appends the encoded string to the input byte slice.\nfunc (Encoder) AppendUint16(dst []byte, val uint16) []byte {\n\treturn strconv.AppendUint(dst, uint64(val), 10)\n}\n\n// AppendUints16 encodes the input uint16s to json and\n// appends the encoded string list to the input byte slice.\nfunc (Encoder) AppendUints16(dst []byte, vals []uint16) []byte {\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = strconv.AppendUint(dst, uint64(vals[0]), 10)\n\tif len(vals) > 1 {\n\t\tfor _, val := range vals[1:] {\n\t\t\tdst = strconv.AppendUint(append(dst, ','), uint64(val), 10)\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n\n// AppendUint32 converts the input uint32 to a string and\n// appends the encoded string to the input byte slice.\nfunc (Encoder) AppendUint32(dst []byte, val uint32) []byte {\n\treturn strconv.AppendUint(dst, uint64(val), 10)\n}\n\n// AppendUints32 encodes the input uint32s to json and\n// appends the encoded string list to the input byte slice.\nfunc (Encoder) AppendUints32(dst []byte, vals []uint32) []byte {\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = strconv.AppendUint(dst, uint64(vals[0]), 10)\n\tif len(vals) > 1 {\n\t\tfor _, val := range vals[1:] {\n\t\t\tdst = strconv.AppendUint(append(dst, ','), uint64(val), 10)\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n\n// AppendUint64 converts the input uint64 to a string and\n// appends the encoded string to the input byte slice.\nfunc (Encoder) AppendUint64(dst []byte, val uint64) []byte {\n\treturn strconv.AppendUint(dst, uint64(val), 10)\n}\n\n// AppendUints64 encodes the input uint64s to json and\n// appends the encoded string list to the input byte slice.\nfunc (Encoder) AppendUints64(dst []byte, vals []uint64) []byte {\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = strconv.AppendUint(dst, vals[0], 10)\n\tif len(vals) > 1 {\n\t\tfor _, val := range vals[1:] {\n\t\t\tdst = strconv.AppendUint(append(dst, ','), val, 10)\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n\nfunc appendFloat(dst []byte, val float64, bitSize int) []byte {\n\t// JSON does not permit NaN or Infinity. A typical JSON encoder would fail\n\t// with an error, but a logging library wants the data to get thru so we\n\t// make a tradeoff and store those types as string.\n\tswitch {\n\tcase math.IsNaN(val):\n\t\treturn append(dst, `\"NaN\"`...)\n\tcase math.IsInf(val, 1):\n\t\treturn append(dst, `\"+Inf\"`...)\n\tcase math.IsInf(val, -1):\n\t\treturn append(dst, `\"-Inf\"`...)\n\t}\n\treturn strconv.AppendFloat(dst, val, 'f', -1, bitSize)\n}\n\n// AppendFloat32 converts the input float32 to a string and\n// appends the encoded string to the input byte slice.\nfunc (Encoder) AppendFloat32(dst []byte, val float32) []byte {\n\treturn appendFloat(dst, float64(val), 32)\n}\n\n// AppendFloats32 encodes the input float32s to json and\n// appends the encoded string list to the input byte slice.\nfunc (Encoder) AppendFloats32(dst []byte, vals []float32) []byte {\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = appendFloat(dst, float64(vals[0]), 32)\n\tif len(vals) > 1 {\n\t\tfor _, val := range vals[1:] {\n\t\t\tdst = appendFloat(append(dst, ','), float64(val), 32)\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n\n// AppendFloat64 converts the input float64 to a string and\n// appends the encoded string to the input byte slice.\nfunc (Encoder) AppendFloat64(dst []byte, val float64) []byte {\n\treturn appendFloat(dst, val, 64)\n}\n\n// AppendFloats64 encodes the input float64s to json and\n// appends the encoded string list to the input byte slice.\nfunc (Encoder) AppendFloats64(dst []byte, vals []float64) []byte {\n\tif len(vals) == 0 {\n\t\treturn append(dst, '[', ']')\n\t}\n\tdst = append(dst, '[')\n\tdst = appendFloat(dst, vals[0], 32)\n\tif len(vals) > 1 {\n\t\tfor _, val := range vals[1:] {\n\t\t\tdst = appendFloat(append(dst, ','), val, 64)\n\t\t}\n\t}\n\tdst = append(dst, ']')\n\treturn dst\n}\n\n// AppendInterface marshals the input interface to a string and\n// appends the encoded string to the input byte slice.\nfunc (e Encoder) AppendInterface(dst []byte, i interface{}) []byte {\n\tmarshaled, err := json.Marshal(i)\n\tif err != nil {\n\t\treturn e.AppendString(dst, fmt.Sprintf(\"marshaling error: %v\", err))\n\t}\n\treturn append(dst, marshaled...)\n}\n\n// AppendObjectData takes in an object that is already in a byte array\n// and adds it to the dst.\nfunc (Encoder) AppendObjectData(dst []byte, o []byte) []byte {\n\t// Three conditions apply here:\n\t// 1. new content starts with '{' - which should be dropped   OR\n\t// 2. new content starts with '{' - which should be replaced with ','\n\t//    to separate with existing content OR\n\t// 3. existing content has already other fields\n\tif o[0] == '{' {\n\t\tif len(dst) > 1 {\n\t\t\tdst = append(dst, ',')\n\t\t}\n\t\to = o[1:]\n\t} else if len(dst) > 1 {\n\t\tdst = append(dst, ',')\n\t}\n\treturn append(dst, o...)\n}\n\n// AppendIPAddr adds IPv4 or IPv6 address to dst.\nfunc (e Encoder) AppendIPAddr(dst []byte, ip net.IP) []byte {\n\treturn e.AppendString(dst, ip.String())\n}\n\n// AppendIPPrefix adds IPv4 or IPv6 Prefix (address & mask) to dst.\nfunc (e Encoder) AppendIPPrefix(dst []byte, pfx net.IPNet) []byte {\n\treturn e.AppendString(dst, pfx.String())\n\n}\n\n// AppendMACAddr adds MAC address to dst.\nfunc (e Encoder) AppendMACAddr(dst []byte, ha net.HardwareAddr) []byte {\n\treturn e.AppendString(dst, ha.String())\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/log/log.go",
    "content": "// Package log provides a global logger for zerolog.\npackage log\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\n\t\"github.com/rs/zerolog\"\n)\n\n// Logger is the global logger.\nvar Logger = zerolog.New(os.Stderr).With().Timestamp().Logger()\n\n// Output duplicates the global logger and sets w as its output.\nfunc Output(w io.Writer) zerolog.Logger {\n\treturn Logger.Output(w)\n}\n\n// With creates a child logger with the field added to its context.\nfunc With() zerolog.Context {\n\treturn Logger.With()\n}\n\n// Level creates a child logger with the minimum accepted level set to level.\nfunc Level(level zerolog.Level) zerolog.Logger {\n\treturn Logger.Level(level)\n}\n\n// Sample returns a logger with the s sampler.\nfunc Sample(s zerolog.Sampler) zerolog.Logger {\n\treturn Logger.Sample(s)\n}\n\n// Hook returns a logger with the h Hook.\nfunc Hook(h zerolog.Hook) zerolog.Logger {\n\treturn Logger.Hook(h)\n}\n\n// Err starts a new message with error level with err as a field if not nil or\n// with info level if err is nil.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc Err(err error) *zerolog.Event {\n\treturn Logger.Err(err)\n}\n\n// Trace starts a new message with trace level.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc Trace() *zerolog.Event {\n\treturn Logger.Trace()\n}\n\n// Debug starts a new message with debug level.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc Debug() *zerolog.Event {\n\treturn Logger.Debug()\n}\n\n// Info starts a new message with info level.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc Info() *zerolog.Event {\n\treturn Logger.Info()\n}\n\n// Warn starts a new message with warn level.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc Warn() *zerolog.Event {\n\treturn Logger.Warn()\n}\n\n// Error starts a new message with error level.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc Error() *zerolog.Event {\n\treturn Logger.Error()\n}\n\n// Fatal starts a new message with fatal level. The os.Exit(1) function\n// is called by the Msg method.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc Fatal() *zerolog.Event {\n\treturn Logger.Fatal()\n}\n\n// Panic starts a new message with panic level. The message is also sent\n// to the panic function.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc Panic() *zerolog.Event {\n\treturn Logger.Panic()\n}\n\n// WithLevel starts a new message with level.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc WithLevel(level zerolog.Level) *zerolog.Event {\n\treturn Logger.WithLevel(level)\n}\n\n// Log starts a new message with no level. Setting zerolog.GlobalLevel to\n// zerolog.Disabled will still disable events produced by this method.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc Log() *zerolog.Event {\n\treturn Logger.Log()\n}\n\n// Print sends a log event using debug level and no extra field.\n// Arguments are handled in the manner of fmt.Print.\nfunc Print(v ...interface{}) {\n\tLogger.Print(v...)\n}\n\n// Printf sends a log event using debug level and no extra field.\n// Arguments are handled in the manner of fmt.Printf.\nfunc Printf(format string, v ...interface{}) {\n\tLogger.Printf(format, v...)\n}\n\n// Ctx returns the Logger associated with the ctx. If no logger\n// is associated, a disabled logger is returned.\nfunc Ctx(ctx context.Context) *zerolog.Logger {\n\treturn zerolog.Ctx(ctx)\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/log.go",
    "content": "// Package zerolog provides a lightweight logging library dedicated to JSON logging.\n//\n// A global Logger can be use for simple logging:\n//\n//     import \"github.com/rs/zerolog/log\"\n//\n//     log.Info().Msg(\"hello world\")\n//     // Output: {\"time\":1494567715,\"level\":\"info\",\"message\":\"hello world\"}\n//\n// NOTE: To import the global logger, import the \"log\" subpackage \"github.com/rs/zerolog/log\".\n//\n// Fields can be added to log messages:\n//\n//     log.Info().Str(\"foo\", \"bar\").Msg(\"hello world\")\n//     // Output: {\"time\":1494567715,\"level\":\"info\",\"message\":\"hello world\",\"foo\":\"bar\"}\n//\n// Create logger instance to manage different outputs:\n//\n//     logger := zerolog.New(os.Stderr).With().Timestamp().Logger()\n//     logger.Info().\n//            Str(\"foo\", \"bar\").\n//            Msg(\"hello world\")\n//     // Output: {\"time\":1494567715,\"level\":\"info\",\"message\":\"hello world\",\"foo\":\"bar\"}\n//\n// Sub-loggers let you chain loggers with additional context:\n//\n//     sublogger := log.With().Str(\"component\": \"foo\").Logger()\n//     sublogger.Info().Msg(\"hello world\")\n//     // Output: {\"time\":1494567715,\"level\":\"info\",\"message\":\"hello world\",\"component\":\"foo\"}\n//\n// Level logging\n//\n//     zerolog.SetGlobalLevel(zerolog.InfoLevel)\n//\n//     log.Debug().Msg(\"filtered out message\")\n//     log.Info().Msg(\"routed message\")\n//\n//     if e := log.Debug(); e.Enabled() {\n//         // Compute log output only if enabled.\n//         value := compute()\n//         e.Str(\"foo\": value).Msg(\"some debug message\")\n//     }\n//     // Output: {\"level\":\"info\",\"time\":1494567715,\"routed message\"}\n//\n// Customize automatic field names:\n//\n//     log.TimestampFieldName = \"t\"\n//     log.LevelFieldName = \"p\"\n//     log.MessageFieldName = \"m\"\n//\n//     log.Info().Msg(\"hello world\")\n//     // Output: {\"t\":1494567715,\"p\":\"info\",\"m\":\"hello world\"}\n//\n// Log with no level and message:\n//\n//     log.Log().Str(\"foo\",\"bar\").Msg(\"\")\n//     // Output: {\"time\":1494567715,\"foo\":\"bar\"}\n//\n// Add contextual fields to global Logger:\n//\n//     log.Logger = log.With().Str(\"foo\", \"bar\").Logger()\n//\n// Sample logs:\n//\n//     sampled := log.Sample(&zerolog.BasicSampler{N: 10})\n//     sampled.Info().Msg(\"will be logged every 10 messages\")\n//\n// Log with contextual hooks:\n//\n//     // Create the hook:\n//     type SeverityHook struct{}\n//\n//     func (h SeverityHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {\n//          if level != zerolog.NoLevel {\n//              e.Str(\"severity\", level.String())\n//          }\n//     }\n//\n//     // And use it:\n//     var h SeverityHook\n//     log := zerolog.New(os.Stdout).Hook(h)\n//     log.Warn().Msg(\"\")\n//     // Output: {\"level\":\"warn\",\"severity\":\"warn\"}\n//\n//\n// Caveats\n//\n// There is no fields deduplication out-of-the-box.\n// Using the same key multiple times creates new key in final JSON each time.\n//\n//     logger := zerolog.New(os.Stderr).With().Timestamp().Logger()\n//     logger.Info().\n//            Timestamp().\n//            Msg(\"dup\")\n//     // Output: {\"level\":\"info\",\"time\":1494567715,\"time\":1494567715,\"message\":\"dup\"}\n//\n// In this case, many consumers will take the last value,\n// but this is not guaranteed; check yours if in doubt.\npackage zerolog\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"strconv\"\n)\n\n// Level defines log levels.\ntype Level int8\n\nconst (\n\t// DebugLevel defines debug log level.\n\tDebugLevel Level = iota\n\t// InfoLevel defines info log level.\n\tInfoLevel\n\t// WarnLevel defines warn log level.\n\tWarnLevel\n\t// ErrorLevel defines error log level.\n\tErrorLevel\n\t// FatalLevel defines fatal log level.\n\tFatalLevel\n\t// PanicLevel defines panic log level.\n\tPanicLevel\n\t// NoLevel defines an absent log level.\n\tNoLevel\n\t// Disabled disables the logger.\n\tDisabled\n\n\t// TraceLevel defines trace log level.\n\tTraceLevel Level = -1\n)\n\nfunc (l Level) String() string {\n\tswitch l {\n\tcase TraceLevel:\n\t\treturn \"trace\"\n\tcase DebugLevel:\n\t\treturn \"debug\"\n\tcase InfoLevel:\n\t\treturn \"info\"\n\tcase WarnLevel:\n\t\treturn \"warn\"\n\tcase ErrorLevel:\n\t\treturn \"error\"\n\tcase FatalLevel:\n\t\treturn \"fatal\"\n\tcase PanicLevel:\n\t\treturn \"panic\"\n\tcase NoLevel:\n\t\treturn \"\"\n\t}\n\treturn \"\"\n}\n\n// ParseLevel converts a level string into a zerolog Level value.\n// returns an error if the input string does not match known values.\nfunc ParseLevel(levelStr string) (Level, error) {\n\tswitch levelStr {\n\tcase LevelFieldMarshalFunc(TraceLevel):\n\t\treturn TraceLevel, nil\n\tcase LevelFieldMarshalFunc(DebugLevel):\n\t\treturn DebugLevel, nil\n\tcase LevelFieldMarshalFunc(InfoLevel):\n\t\treturn InfoLevel, nil\n\tcase LevelFieldMarshalFunc(WarnLevel):\n\t\treturn WarnLevel, nil\n\tcase LevelFieldMarshalFunc(ErrorLevel):\n\t\treturn ErrorLevel, nil\n\tcase LevelFieldMarshalFunc(FatalLevel):\n\t\treturn FatalLevel, nil\n\tcase LevelFieldMarshalFunc(PanicLevel):\n\t\treturn PanicLevel, nil\n\tcase LevelFieldMarshalFunc(NoLevel):\n\t\treturn NoLevel, nil\n\t}\n\treturn NoLevel, fmt.Errorf(\"Unknown Level String: '%s', defaulting to NoLevel\", levelStr)\n}\n\n// A Logger represents an active logging object that generates lines\n// of JSON output to an io.Writer. Each logging operation makes a single\n// call to the Writer's Write method. There is no guarantee on access\n// serialization to the Writer. If your Writer is not thread safe,\n// you may consider a sync wrapper.\ntype Logger struct {\n\tw       LevelWriter\n\tlevel   Level\n\tsampler Sampler\n\tcontext []byte\n\thooks   []Hook\n}\n\n// New creates a root logger with given output writer. If the output writer implements\n// the LevelWriter interface, the WriteLevel method will be called instead of the Write\n// one.\n//\n// Each logging operation makes a single call to the Writer's Write method. There is no\n// guarantee on access serialization to the Writer. If your Writer is not thread safe,\n// you may consider using sync wrapper.\nfunc New(w io.Writer) Logger {\n\tif w == nil {\n\t\tw = ioutil.Discard\n\t}\n\tlw, ok := w.(LevelWriter)\n\tif !ok {\n\t\tlw = levelWriterAdapter{w}\n\t}\n\treturn Logger{w: lw, level: TraceLevel}\n}\n\n// Nop returns a disabled logger for which all operation are no-op.\nfunc Nop() Logger {\n\treturn New(nil).Level(Disabled)\n}\n\n// Output duplicates the current logger and sets w as its output.\nfunc (l Logger) Output(w io.Writer) Logger {\n\tl2 := New(w)\n\tl2.level = l.level\n\tl2.sampler = l.sampler\n\tif len(l.hooks) > 0 {\n\t\tl2.hooks = append(l2.hooks, l.hooks...)\n\t}\n\tif l.context != nil {\n\t\tl2.context = make([]byte, len(l.context), cap(l.context))\n\t\tcopy(l2.context, l.context)\n\t}\n\treturn l2\n}\n\n// With creates a child logger with the field added to its context.\nfunc (l Logger) With() Context {\n\tcontext := l.context\n\tl.context = make([]byte, 0, 500)\n\tif context != nil {\n\t\tl.context = append(l.context, context...)\n\t} else {\n\t\t// This is needed for AppendKey to not check len of input\n\t\t// thus making it inlinable\n\t\tl.context = enc.AppendBeginMarker(l.context)\n\t}\n\treturn Context{l}\n}\n\n// UpdateContext updates the internal logger's context.\n//\n// Use this method with caution. If unsure, prefer the With method.\nfunc (l *Logger) UpdateContext(update func(c Context) Context) {\n\tif l == disabledLogger {\n\t\treturn\n\t}\n\tif cap(l.context) == 0 {\n\t\tl.context = make([]byte, 0, 500)\n\t}\n\tif len(l.context) == 0 {\n\t\tl.context = enc.AppendBeginMarker(l.context)\n\t}\n\tc := update(Context{*l})\n\tl.context = c.l.context\n}\n\n// Level creates a child logger with the minimum accepted level set to level.\nfunc (l Logger) Level(lvl Level) Logger {\n\tl.level = lvl\n\treturn l\n}\n\n// GetLevel returns the current Level of l.\nfunc (l Logger) GetLevel() Level {\n\treturn l.level\n}\n\n// Sample returns a logger with the s sampler.\nfunc (l Logger) Sample(s Sampler) Logger {\n\tl.sampler = s\n\treturn l\n}\n\n// Hook returns a logger with the h Hook.\nfunc (l Logger) Hook(h Hook) Logger {\n\tl.hooks = append(l.hooks, h)\n\treturn l\n}\n\n// Trace starts a new message with trace level.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc (l *Logger) Trace() *Event {\n\treturn l.newEvent(TraceLevel, nil)\n}\n\n// Debug starts a new message with debug level.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc (l *Logger) Debug() *Event {\n\treturn l.newEvent(DebugLevel, nil)\n}\n\n// Info starts a new message with info level.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc (l *Logger) Info() *Event {\n\treturn l.newEvent(InfoLevel, nil)\n}\n\n// Warn starts a new message with warn level.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc (l *Logger) Warn() *Event {\n\treturn l.newEvent(WarnLevel, nil)\n}\n\n// Error starts a new message with error level.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc (l *Logger) Error() *Event {\n\treturn l.newEvent(ErrorLevel, nil)\n}\n\n// Err starts a new message with error level with err as a field if not nil or\n// with info level if err is nil.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc (l *Logger) Err(err error) *Event {\n\tif err != nil {\n\t\treturn l.Error().Err(err)\n\t}\n\n\treturn l.Info()\n}\n\n// Fatal starts a new message with fatal level. The os.Exit(1) function\n// is called by the Msg method, which terminates the program immediately.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc (l *Logger) Fatal() *Event {\n\treturn l.newEvent(FatalLevel, func(msg string) { os.Exit(1) })\n}\n\n// Panic starts a new message with panic level. The panic() function\n// is called by the Msg method, which stops the ordinary flow of a goroutine.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc (l *Logger) Panic() *Event {\n\treturn l.newEvent(PanicLevel, func(msg string) { panic(msg) })\n}\n\n// WithLevel starts a new message with level. Unlike Fatal and Panic\n// methods, WithLevel does not terminate the program or stop the ordinary\n// flow of a gourotine when used with their respective levels.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc (l *Logger) WithLevel(level Level) *Event {\n\tswitch level {\n\tcase TraceLevel:\n\t\treturn l.Trace()\n\tcase DebugLevel:\n\t\treturn l.Debug()\n\tcase InfoLevel:\n\t\treturn l.Info()\n\tcase WarnLevel:\n\t\treturn l.Warn()\n\tcase ErrorLevel:\n\t\treturn l.Error()\n\tcase FatalLevel:\n\t\treturn l.newEvent(FatalLevel, nil)\n\tcase PanicLevel:\n\t\treturn l.newEvent(PanicLevel, nil)\n\tcase NoLevel:\n\t\treturn l.Log()\n\tcase Disabled:\n\t\treturn nil\n\tdefault:\n\t\tpanic(\"zerolog: WithLevel(): invalid level: \" + strconv.Itoa(int(level)))\n\t}\n}\n\n// Log starts a new message with no level. Setting GlobalLevel to Disabled\n// will still disable events produced by this method.\n//\n// You must call Msg on the returned event in order to send the event.\nfunc (l *Logger) Log() *Event {\n\treturn l.newEvent(NoLevel, nil)\n}\n\n// Print sends a log event using debug level and no extra field.\n// Arguments are handled in the manner of fmt.Print.\nfunc (l *Logger) Print(v ...interface{}) {\n\tif e := l.Debug(); e.Enabled() {\n\t\te.Msg(fmt.Sprint(v...))\n\t}\n}\n\n// Printf sends a log event using debug level and no extra field.\n// Arguments are handled in the manner of fmt.Printf.\nfunc (l *Logger) Printf(format string, v ...interface{}) {\n\tif e := l.Debug(); e.Enabled() {\n\t\te.Msg(fmt.Sprintf(format, v...))\n\t}\n}\n\n// Write implements the io.Writer interface. This is useful to set as a writer\n// for the standard library log.\nfunc (l Logger) Write(p []byte) (n int, err error) {\n\tn = len(p)\n\tif n > 0 && p[n-1] == '\\n' {\n\t\t// Trim CR added by stdlog.\n\t\tp = p[0 : n-1]\n\t}\n\tl.Log().Msg(string(p))\n\treturn\n}\n\nfunc (l *Logger) newEvent(level Level, done func(string)) *Event {\n\tenabled := l.should(level)\n\tif !enabled {\n\t\treturn nil\n\t}\n\te := newEvent(l.w, level)\n\te.done = done\n\te.ch = l.hooks\n\tif level != NoLevel {\n\t\te.Str(LevelFieldName, LevelFieldMarshalFunc(level))\n\t}\n\tif l.context != nil && len(l.context) > 1 {\n\t\te.buf = enc.AppendObjectData(e.buf, l.context)\n\t}\n\treturn e\n}\n\n// should returns true if the log event should be logged.\nfunc (l *Logger) should(lvl Level) bool {\n\tif lvl < l.level || lvl < GlobalLevel() {\n\t\treturn false\n\t}\n\tif l.sampler != nil && !samplingDisabled() {\n\t\treturn l.sampler.Sample(lvl)\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/not_go112.go",
    "content": "// +build !go1.12\n\npackage zerolog\n\nconst contextCallerSkipFrameCount = 3\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/sampler.go",
    "content": "package zerolog\n\nimport (\n\t\"math/rand\"\n\t\"sync/atomic\"\n\t\"time\"\n)\n\nvar (\n\t// Often samples log every ~ 10 events.\n\tOften = RandomSampler(10)\n\t// Sometimes samples log every ~ 100 events.\n\tSometimes = RandomSampler(100)\n\t// Rarely samples log every ~ 1000 events.\n\tRarely = RandomSampler(1000)\n)\n\n// Sampler defines an interface to a log sampler.\ntype Sampler interface {\n\t// Sample returns true if the event should be part of the sample, false if\n\t// the event should be dropped.\n\tSample(lvl Level) bool\n}\n\n// RandomSampler use a PRNG to randomly sample an event out of N events,\n// regardless of their level.\ntype RandomSampler uint32\n\n// Sample implements the Sampler interface.\nfunc (s RandomSampler) Sample(lvl Level) bool {\n\tif s <= 0 {\n\t\treturn false\n\t}\n\tif rand.Intn(int(s)) != 0 {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// BasicSampler is a sampler that will send every Nth events, regardless of\n// there level.\ntype BasicSampler struct {\n\tN       uint32\n\tcounter uint32\n}\n\n// Sample implements the Sampler interface.\nfunc (s *BasicSampler) Sample(lvl Level) bool {\n\tn := s.N\n\tif n == 1 {\n\t\treturn true\n\t}\n\tc := atomic.AddUint32(&s.counter, 1)\n\treturn c%n == 1\n}\n\n// BurstSampler lets Burst events pass per Period then pass the decision to\n// NextSampler. If Sampler is not set, all subsequent events are rejected.\ntype BurstSampler struct {\n\t// Burst is the maximum number of event per period allowed before calling\n\t// NextSampler.\n\tBurst uint32\n\t// Period defines the burst period. If 0, NextSampler is always called.\n\tPeriod time.Duration\n\t// NextSampler is the sampler used after the burst is reached. If nil,\n\t// events are always rejected after the burst.\n\tNextSampler Sampler\n\n\tcounter uint32\n\tresetAt int64\n}\n\n// Sample implements the Sampler interface.\nfunc (s *BurstSampler) Sample(lvl Level) bool {\n\tif s.Burst > 0 && s.Period > 0 {\n\t\tif s.inc() <= s.Burst {\n\t\t\treturn true\n\t\t}\n\t}\n\tif s.NextSampler == nil {\n\t\treturn false\n\t}\n\treturn s.NextSampler.Sample(lvl)\n}\n\nfunc (s *BurstSampler) inc() uint32 {\n\tnow := time.Now().UnixNano()\n\tresetAt := atomic.LoadInt64(&s.resetAt)\n\tvar c uint32\n\tif now > resetAt {\n\t\tc = 1\n\t\tatomic.StoreUint32(&s.counter, c)\n\t\tnewResetAt := now + s.Period.Nanoseconds()\n\t\treset := atomic.CompareAndSwapInt64(&s.resetAt, resetAt, newResetAt)\n\t\tif !reset {\n\t\t\t// Lost the race with another goroutine trying to reset.\n\t\t\tc = atomic.AddUint32(&s.counter, 1)\n\t\t}\n\t} else {\n\t\tc = atomic.AddUint32(&s.counter, 1)\n\t}\n\treturn c\n}\n\n// LevelSampler applies a different sampler for each level.\ntype LevelSampler struct {\n\tTraceSampler, DebugSampler, InfoSampler, WarnSampler, ErrorSampler Sampler\n}\n\nfunc (s LevelSampler) Sample(lvl Level) bool {\n\tswitch lvl {\n\tcase TraceLevel:\n\t\tif s.TraceSampler != nil {\n\t\t\treturn s.TraceSampler.Sample(lvl)\n\t\t}\n\tcase DebugLevel:\n\t\tif s.DebugSampler != nil {\n\t\t\treturn s.DebugSampler.Sample(lvl)\n\t\t}\n\tcase InfoLevel:\n\t\tif s.InfoSampler != nil {\n\t\t\treturn s.InfoSampler.Sample(lvl)\n\t\t}\n\tcase WarnLevel:\n\t\tif s.WarnSampler != nil {\n\t\t\treturn s.WarnSampler.Sample(lvl)\n\t\t}\n\tcase ErrorLevel:\n\t\tif s.ErrorSampler != nil {\n\t\t\treturn s.ErrorSampler.Sample(lvl)\n\t\t}\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/syslog.go",
    "content": "// +build !windows\n// +build !binary_log\n\npackage zerolog\n\nimport (\n\t\"io\"\n)\n\n// SyslogWriter is an interface matching a syslog.Writer struct.\ntype SyslogWriter interface {\n\tio.Writer\n\tDebug(m string) error\n\tInfo(m string) error\n\tWarning(m string) error\n\tErr(m string) error\n\tEmerg(m string) error\n\tCrit(m string) error\n}\n\ntype syslogWriter struct {\n\tw SyslogWriter\n}\n\n// SyslogLevelWriter wraps a SyslogWriter and call the right syslog level\n// method matching the zerolog level.\nfunc SyslogLevelWriter(w SyslogWriter) LevelWriter {\n\treturn syslogWriter{w}\n}\n\nfunc (sw syslogWriter) Write(p []byte) (n int, err error) {\n\treturn sw.w.Write(p)\n}\n\n// WriteLevel implements LevelWriter interface.\nfunc (sw syslogWriter) WriteLevel(level Level, p []byte) (n int, err error) {\n\tswitch level {\n\tcase TraceLevel:\n\tcase DebugLevel:\n\t\terr = sw.w.Debug(string(p))\n\tcase InfoLevel:\n\t\terr = sw.w.Info(string(p))\n\tcase WarnLevel:\n\t\terr = sw.w.Warning(string(p))\n\tcase ErrorLevel:\n\t\terr = sw.w.Err(string(p))\n\tcase FatalLevel:\n\t\terr = sw.w.Emerg(string(p))\n\tcase PanicLevel:\n\t\terr = sw.w.Crit(string(p))\n\tcase NoLevel:\n\t\terr = sw.w.Info(string(p))\n\tdefault:\n\t\tpanic(\"invalid level\")\n\t}\n\tn = len(p)\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/rs/zerolog/writer.go",
    "content": "package zerolog\n\nimport (\n\t\"io\"\n\t\"sync\"\n)\n\n// LevelWriter defines as interface a writer may implement in order\n// to receive level information with payload.\ntype LevelWriter interface {\n\tio.Writer\n\tWriteLevel(level Level, p []byte) (n int, err error)\n}\n\ntype levelWriterAdapter struct {\n\tio.Writer\n}\n\nfunc (lw levelWriterAdapter) WriteLevel(l Level, p []byte) (n int, err error) {\n\treturn lw.Write(p)\n}\n\ntype syncWriter struct {\n\tmu sync.Mutex\n\tlw LevelWriter\n}\n\n// SyncWriter wraps w so that each call to Write is synchronized with a mutex.\n// This syncer can be used to wrap the call to writer's Write method if it is\n// not thread safe. Note that you do not need this wrapper for os.File Write\n// operations on POSIX and Windows systems as they are already thread-safe.\nfunc SyncWriter(w io.Writer) io.Writer {\n\tif lw, ok := w.(LevelWriter); ok {\n\t\treturn &syncWriter{lw: lw}\n\t}\n\treturn &syncWriter{lw: levelWriterAdapter{w}}\n}\n\n// Write implements the io.Writer interface.\nfunc (s *syncWriter) Write(p []byte) (n int, err error) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.lw.Write(p)\n}\n\n// WriteLevel implements the LevelWriter interface.\nfunc (s *syncWriter) WriteLevel(l Level, p []byte) (n int, err error) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.lw.WriteLevel(l, p)\n}\n\ntype multiLevelWriter struct {\n\twriters []LevelWriter\n}\n\nfunc (t multiLevelWriter) Write(p []byte) (n int, err error) {\n\tfor _, w := range t.writers {\n\t\tn, err = w.Write(p)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tif n != len(p) {\n\t\t\terr = io.ErrShortWrite\n\t\t\treturn\n\t\t}\n\t}\n\treturn len(p), nil\n}\n\nfunc (t multiLevelWriter) WriteLevel(l Level, p []byte) (n int, err error) {\n\tfor _, w := range t.writers {\n\t\tn, err = w.WriteLevel(l, p)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tif n != len(p) {\n\t\t\terr = io.ErrShortWrite\n\t\t\treturn\n\t\t}\n\t}\n\treturn len(p), nil\n}\n\n// MultiLevelWriter creates a writer that duplicates its writes to all the\n// provided writers, similar to the Unix tee(1) command. If some writers\n// implement LevelWriter, their WriteLevel method will be used instead of Write.\nfunc MultiLevelWriter(writers ...io.Writer) LevelWriter {\n\tlwriters := make([]LevelWriter, 0, len(writers))\n\tfor _, w := range writers {\n\t\tif lw, ok := w.(LevelWriter); ok {\n\t\t\tlwriters = append(lwriters, lw)\n\t\t} else {\n\t\t\tlwriters = append(lwriters, levelWriterAdapter{w})\n\t\t}\n\t}\n\treturn multiLevelWriter{lwriters}\n}\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/.gitignore",
    "content": "*.out\n*.swp\n*.8\n*.6\n_obj\n_test*\nmarkdown\ntags\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/.travis.yml",
    "content": "sudo: false\nlanguage: go\ngo:\n  - \"1.10.x\"\n  - \"1.11.x\"\n  - tip\nmatrix:\n  fast_finish: true\n  allow_failures:\n    - go: tip\ninstall:\n  - # Do nothing. This is needed to prevent default install action \"go get -t -v ./...\" from happening here (we want it to happen inside script step).\nscript:\n  - go get -t -v ./...\n  - diff -u <(echo -n) <(gofmt -d -s .)\n  - go tool vet .\n  - go test -v ./...\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/LICENSE.txt",
    "content": "Blackfriday is distributed under the Simplified BSD License:\n\n> Copyright © 2011 Russ Ross\n> All rights reserved.\n>\n> Redistribution and use in source and binary forms, with or without\n> modification, are permitted provided that the following conditions\n> are met:\n>\n> 1.  Redistributions of source code must retain the above copyright\n>     notice, this list of conditions and the following disclaimer.\n>\n> 2.  Redistributions in binary form must reproduce the above\n>     copyright notice, this list of conditions and the following\n>     disclaimer in the documentation and/or other materials provided with\n>     the distribution.\n>\n> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n> \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n> LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n> FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n> COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n> INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n> BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n> LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n> LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n> ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n> POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/README.md",
    "content": "Blackfriday\n[![Build Status][BuildV2SVG]][BuildV2URL]\n[![PkgGoDev][PkgGoDevV2SVG]][PkgGoDevV2URL]\n===========\n\nBlackfriday is a [Markdown][1] processor implemented in [Go][2]. It\nis paranoid about its input (so you can safely feed it user-supplied\ndata), it is fast, it supports common extensions (tables, smart\npunctuation substitutions, etc.), and it is safe for all utf-8\n(unicode) input.\n\nHTML output is currently supported, along with Smartypants\nextensions.\n\nIt started as a translation from C of [Sundown][3].\n\n\nInstallation\n------------\n\nBlackfriday is compatible with modern Go releases in module mode.\nWith Go installed:\n\n    go get github.com/russross/blackfriday/v2\n\nwill resolve and add the package to the current development module,\nthen build and install it. Alternatively, you can achieve the same\nif you import it in a package:\n\n    import \"github.com/russross/blackfriday/v2\"\n\nand `go get` without parameters.\n\nLegacy GOPATH mode is unsupported.\n\n\nVersions\n--------\n\nCurrently maintained and recommended version of Blackfriday is `v2`. It's being\ndeveloped on its own branch: https://github.com/russross/blackfriday/tree/v2 and the\ndocumentation is available at\nhttps://pkg.go.dev/github.com/russross/blackfriday/v2.\n\nIt is `go get`-able in module mode at `github.com/russross/blackfriday/v2`.\n\nVersion 2 offers a number of improvements over v1:\n\n* Cleaned up API\n* A separate call to [`Parse`][4], which produces an abstract syntax tree for\n  the document\n* Latest bug fixes\n* Flexibility to easily add your own rendering extensions\n\nPotential drawbacks:\n\n* Our benchmarks show v2 to be slightly slower than v1. Currently in the\n  ballpark of around 15%.\n* API breakage. If you can't afford modifying your code to adhere to the new API\n  and don't care too much about the new features, v2 is probably not for you.\n* Several bug fixes are trailing behind and still need to be forward-ported to\n  v2. See issue [#348](https://github.com/russross/blackfriday/issues/348) for\n  tracking.\n\nIf you are still interested in the legacy `v1`, you can import it from\n`github.com/russross/blackfriday`. Documentation for the legacy v1 can be found\nhere: https://pkg.go.dev/github.com/russross/blackfriday.\n\n\nUsage\n-----\n\nFor the most sensible markdown processing, it is as simple as getting your input\ninto a byte slice and calling:\n\n```go\noutput := blackfriday.Run(input)\n```\n\nYour input will be parsed and the output rendered with a set of most popular\nextensions enabled. If you want the most basic feature set, corresponding with\nthe bare Markdown specification, use:\n\n```go\noutput := blackfriday.Run(input, blackfriday.WithNoExtensions())\n```\n\n### Sanitize untrusted content\n\nBlackfriday itself does nothing to protect against malicious content. If you are\ndealing with user-supplied markdown, we recommend running Blackfriday's output\nthrough HTML sanitizer such as [Bluemonday][5].\n\nHere's an example of simple usage of Blackfriday together with Bluemonday:\n\n```go\nimport (\n    \"github.com/microcosm-cc/bluemonday\"\n    \"github.com/russross/blackfriday/v2\"\n)\n\n// ...\nunsafe := blackfriday.Run(input)\nhtml := bluemonday.UGCPolicy().SanitizeBytes(unsafe)\n```\n\n### Custom options\n\nIf you want to customize the set of options, use `blackfriday.WithExtensions`,\n`blackfriday.WithRenderer` and `blackfriday.WithRefOverride`.\n\n### `blackfriday-tool`\n\nYou can also check out `blackfriday-tool` for a more complete example\nof how to use it. Download and install it using:\n\n    go get github.com/russross/blackfriday-tool\n\nThis is a simple command-line tool that allows you to process a\nmarkdown file using a standalone program.  You can also browse the\nsource directly on github if you are just looking for some example\ncode:\n\n* <https://github.com/russross/blackfriday-tool>\n\nNote that if you have not already done so, installing\n`blackfriday-tool` will be sufficient to download and install\nblackfriday in addition to the tool itself. The tool binary will be\ninstalled in `$GOPATH/bin`.  This is a statically-linked binary that\ncan be copied to wherever you need it without worrying about\ndependencies and library versions.\n\n### Sanitized anchor names\n\nBlackfriday includes an algorithm for creating sanitized anchor names\ncorresponding to a given input text. This algorithm is used to create\nanchors for headings when `AutoHeadingIDs` extension is enabled. The\nalgorithm has a specification, so that other packages can create\ncompatible anchor names and links to those anchors.\n\nThe specification is located at https://pkg.go.dev/github.com/russross/blackfriday/v2#hdr-Sanitized_Anchor_Names.\n\n[`SanitizedAnchorName`](https://pkg.go.dev/github.com/russross/blackfriday/v2#SanitizedAnchorName) exposes this functionality, and can be used to\ncreate compatible links to the anchor names generated by blackfriday.\nThis algorithm is also implemented in a small standalone package at\n[`github.com/shurcooL/sanitized_anchor_name`](https://pkg.go.dev/github.com/shurcooL/sanitized_anchor_name). It can be useful for clients\nthat want a small package and don't need full functionality of blackfriday.\n\n\nFeatures\n--------\n\nAll features of Sundown are supported, including:\n\n*   **Compatibility**. The Markdown v1.0.3 test suite passes with\n    the `--tidy` option.  Without `--tidy`, the differences are\n    mostly in whitespace and entity escaping, where blackfriday is\n    more consistent and cleaner.\n\n*   **Common extensions**, including table support, fenced code\n    blocks, autolinks, strikethroughs, non-strict emphasis, etc.\n\n*   **Safety**. Blackfriday is paranoid when parsing, making it safe\n    to feed untrusted user input without fear of bad things\n    happening. The test suite stress tests this and there are no\n    known inputs that make it crash.  If you find one, please let me\n    know and send me the input that does it.\n\n    NOTE: \"safety\" in this context means *runtime safety only*. In order to\n    protect yourself against JavaScript injection in untrusted content, see\n    [this example](https://github.com/russross/blackfriday#sanitize-untrusted-content).\n\n*   **Fast processing**. It is fast enough to render on-demand in\n    most web applications without having to cache the output.\n\n*   **Thread safety**. You can run multiple parsers in different\n    goroutines without ill effect. There is no dependence on global\n    shared state.\n\n*   **Minimal dependencies**. Blackfriday only depends on standard\n    library packages in Go. The source code is pretty\n    self-contained, so it is easy to add to any project, including\n    Google App Engine projects.\n\n*   **Standards compliant**. Output successfully validates using the\n    W3C validation tool for HTML 4.01 and XHTML 1.0 Transitional.\n\n\nExtensions\n----------\n\nIn addition to the standard markdown syntax, this package\nimplements the following extensions:\n\n*   **Intra-word emphasis supression**. The `_` character is\n    commonly used inside words when discussing code, so having\n    markdown interpret it as an emphasis command is usually the\n    wrong thing. Blackfriday lets you treat all emphasis markers as\n    normal characters when they occur inside a word.\n\n*   **Tables**. Tables can be created by drawing them in the input\n    using a simple syntax:\n\n    ```\n    Name    | Age\n    --------|------\n    Bob     | 27\n    Alice   | 23\n    ```\n\n*   **Fenced code blocks**. In addition to the normal 4-space\n    indentation to mark code blocks, you can explicitly mark them\n    and supply a language (to make syntax highlighting simple). Just\n    mark it like this:\n\n        ```go\n        func getTrue() bool {\n            return true\n        }\n        ```\n\n    You can use 3 or more backticks to mark the beginning of the\n    block, and the same number to mark the end of the block.\n\n    To preserve classes of fenced code blocks while using the bluemonday\n    HTML sanitizer, use the following policy:\n\n    ```go\n    p := bluemonday.UGCPolicy()\n    p.AllowAttrs(\"class\").Matching(regexp.MustCompile(\"^language-[a-zA-Z0-9]+$\")).OnElements(\"code\")\n    html := p.SanitizeBytes(unsafe)\n    ```\n\n*   **Definition lists**. A simple definition list is made of a single-line\n    term followed by a colon and the definition for that term.\n\n        Cat\n        : Fluffy animal everyone likes\n\n        Internet\n        : Vector of transmission for pictures of cats\n\n    Terms must be separated from the previous definition by a blank line.\n\n*   **Footnotes**. A marker in the text that will become a superscript number;\n    a footnote definition that will be placed in a list of footnotes at the\n    end of the document. A footnote looks like this:\n\n        This is a footnote.[^1]\n\n        [^1]: the footnote text.\n\n*   **Autolinking**. Blackfriday can find URLs that have not been\n    explicitly marked as links and turn them into links.\n\n*   **Strikethrough**. Use two tildes (`~~`) to mark text that\n    should be crossed out.\n\n*   **Hard line breaks**. With this extension enabled newlines in the input\n    translate into line breaks in the output. This extension is off by default.\n\n*   **Smart quotes**. Smartypants-style punctuation substitution is\n    supported, turning normal double- and single-quote marks into\n    curly quotes, etc.\n\n*   **LaTeX-style dash parsing** is an additional option, where `--`\n    is translated into `&ndash;`, and `---` is translated into\n    `&mdash;`. This differs from most smartypants processors, which\n    turn a single hyphen into an ndash and a double hyphen into an\n    mdash.\n\n*   **Smart fractions**, where anything that looks like a fraction\n    is translated into suitable HTML (instead of just a few special\n    cases like most smartypant processors). For example, `4/5`\n    becomes `<sup>4</sup>&frasl;<sub>5</sub>`, which renders as\n    <sup>4</sup>&frasl;<sub>5</sub>.\n\n\nOther renderers\n---------------\n\nBlackfriday is structured to allow alternative rendering engines. Here\nare a few of note:\n\n*   [github_flavored_markdown](https://pkg.go.dev/github.com/shurcooL/github_flavored_markdown):\n    provides a GitHub Flavored Markdown renderer with fenced code block\n    highlighting, clickable heading anchor links.\n\n    It's not customizable, and its goal is to produce HTML output\n    equivalent to the [GitHub Markdown API endpoint](https://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode),\n    except the rendering is performed locally.\n\n*   [markdownfmt](https://github.com/shurcooL/markdownfmt): like gofmt,\n    but for markdown.\n\n*   [LaTeX output](https://gitlab.com/ambrevar/blackfriday-latex):\n    renders output as LaTeX.\n\n*   [bfchroma](https://github.com/Depado/bfchroma/): provides convenience\n    integration with the [Chroma](https://github.com/alecthomas/chroma) code\n    highlighting library. bfchroma is only compatible with v2 of Blackfriday and\n    provides a drop-in renderer ready to use with Blackfriday, as well as\n    options and means for further customization.\n\n*   [Blackfriday-Confluence](https://github.com/kentaro-m/blackfriday-confluence): provides a [Confluence Wiki Markup](https://confluence.atlassian.com/doc/confluence-wiki-markup-251003035.html) renderer.\n\n*   [Blackfriday-Slack](https://github.com/karriereat/blackfriday-slack): converts markdown to slack message style\n\n\nTODO\n----\n\n*   More unit testing\n*   Improve Unicode support. It does not understand all Unicode\n    rules (about what constitutes a letter, a punctuation symbol,\n    etc.), so it may fail to detect word boundaries correctly in\n    some instances. It is safe on all UTF-8 input.\n\n\nLicense\n-------\n\n[Blackfriday is distributed under the Simplified BSD License](LICENSE.txt)\n\n\n   [1]: https://daringfireball.net/projects/markdown/ \"Markdown\"\n   [2]: https://golang.org/ \"Go Language\"\n   [3]: https://github.com/vmg/sundown \"Sundown\"\n   [4]: https://pkg.go.dev/github.com/russross/blackfriday/v2#Parse \"Parse func\"\n   [5]: https://github.com/microcosm-cc/bluemonday \"Bluemonday\"\n\n   [BuildV2SVG]: https://travis-ci.org/russross/blackfriday.svg?branch=v2\n   [BuildV2URL]: https://travis-ci.org/russross/blackfriday\n   [PkgGoDevV2SVG]: https://pkg.go.dev/badge/github.com/russross/blackfriday/v2\n   [PkgGoDevV2URL]: https://pkg.go.dev/github.com/russross/blackfriday/v2\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/block.go",
    "content": "//\n// Blackfriday Markdown Processor\n// Available at http://github.com/russross/blackfriday\n//\n// Copyright © 2011 Russ Ross <russ@russross.com>.\n// Distributed under the Simplified BSD License.\n// See README.md for details.\n//\n\n//\n// Functions to parse block-level elements.\n//\n\npackage blackfriday\n\nimport (\n\t\"bytes\"\n\t\"html\"\n\t\"regexp\"\n\t\"strings\"\n\t\"unicode\"\n)\n\nconst (\n\tcharEntity = \"&(?:#x[a-f0-9]{1,8}|#[0-9]{1,8}|[a-z][a-z0-9]{1,31});\"\n\tescapable  = \"[!\\\"#$%&'()*+,./:;<=>?@[\\\\\\\\\\\\]^_`{|}~-]\"\n)\n\nvar (\n\treBackslashOrAmp      = regexp.MustCompile(\"[\\\\&]\")\n\treEntityOrEscapedChar = regexp.MustCompile(\"(?i)\\\\\\\\\" + escapable + \"|\" + charEntity)\n)\n\n// Parse block-level data.\n// Note: this function and many that it calls assume that\n// the input buffer ends with a newline.\nfunc (p *Markdown) block(data []byte) {\n\t// this is called recursively: enforce a maximum depth\n\tif p.nesting >= p.maxNesting {\n\t\treturn\n\t}\n\tp.nesting++\n\n\t// parse out one block-level construct at a time\n\tfor len(data) > 0 {\n\t\t// prefixed heading:\n\t\t//\n\t\t// # Heading 1\n\t\t// ## Heading 2\n\t\t// ...\n\t\t// ###### Heading 6\n\t\tif p.isPrefixHeading(data) {\n\t\t\tdata = data[p.prefixHeading(data):]\n\t\t\tcontinue\n\t\t}\n\n\t\t// block of preformatted HTML:\n\t\t//\n\t\t// <div>\n\t\t//     ...\n\t\t// </div>\n\t\tif data[0] == '<' {\n\t\t\tif i := p.html(data, true); i > 0 {\n\t\t\t\tdata = data[i:]\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// title block\n\t\t//\n\t\t// % stuff\n\t\t// % more stuff\n\t\t// % even more stuff\n\t\tif p.extensions&Titleblock != 0 {\n\t\t\tif data[0] == '%' {\n\t\t\t\tif i := p.titleBlock(data, true); i > 0 {\n\t\t\t\t\tdata = data[i:]\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// blank lines.  note: returns the # of bytes to skip\n\t\tif i := p.isEmpty(data); i > 0 {\n\t\t\tdata = data[i:]\n\t\t\tcontinue\n\t\t}\n\n\t\t// indented code block:\n\t\t//\n\t\t//     func max(a, b int) int {\n\t\t//         if a > b {\n\t\t//             return a\n\t\t//         }\n\t\t//         return b\n\t\t//      }\n\t\tif p.codePrefix(data) > 0 {\n\t\t\tdata = data[p.code(data):]\n\t\t\tcontinue\n\t\t}\n\n\t\t// fenced code block:\n\t\t//\n\t\t// ``` go\n\t\t// func fact(n int) int {\n\t\t//     if n <= 1 {\n\t\t//         return n\n\t\t//     }\n\t\t//     return n * fact(n-1)\n\t\t// }\n\t\t// ```\n\t\tif p.extensions&FencedCode != 0 {\n\t\t\tif i := p.fencedCodeBlock(data, true); i > 0 {\n\t\t\t\tdata = data[i:]\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// horizontal rule:\n\t\t//\n\t\t// ------\n\t\t// or\n\t\t// ******\n\t\t// or\n\t\t// ______\n\t\tif p.isHRule(data) {\n\t\t\tp.addBlock(HorizontalRule, nil)\n\t\t\tvar i int\n\t\t\tfor i = 0; i < len(data) && data[i] != '\\n'; i++ {\n\t\t\t}\n\t\t\tdata = data[i:]\n\t\t\tcontinue\n\t\t}\n\n\t\t// block quote:\n\t\t//\n\t\t// > A big quote I found somewhere\n\t\t// > on the web\n\t\tif p.quotePrefix(data) > 0 {\n\t\t\tdata = data[p.quote(data):]\n\t\t\tcontinue\n\t\t}\n\n\t\t// table:\n\t\t//\n\t\t// Name  | Age | Phone\n\t\t// ------|-----|---------\n\t\t// Bob   | 31  | 555-1234\n\t\t// Alice | 27  | 555-4321\n\t\tif p.extensions&Tables != 0 {\n\t\t\tif i := p.table(data); i > 0 {\n\t\t\t\tdata = data[i:]\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// an itemized/unordered list:\n\t\t//\n\t\t// * Item 1\n\t\t// * Item 2\n\t\t//\n\t\t// also works with + or -\n\t\tif p.uliPrefix(data) > 0 {\n\t\t\tdata = data[p.list(data, 0):]\n\t\t\tcontinue\n\t\t}\n\n\t\t// a numbered/ordered list:\n\t\t//\n\t\t// 1. Item 1\n\t\t// 2. Item 2\n\t\tif p.oliPrefix(data) > 0 {\n\t\t\tdata = data[p.list(data, ListTypeOrdered):]\n\t\t\tcontinue\n\t\t}\n\n\t\t// definition lists:\n\t\t//\n\t\t// Term 1\n\t\t// :   Definition a\n\t\t// :   Definition b\n\t\t//\n\t\t// Term 2\n\t\t// :   Definition c\n\t\tif p.extensions&DefinitionLists != 0 {\n\t\t\tif p.dliPrefix(data) > 0 {\n\t\t\t\tdata = data[p.list(data, ListTypeDefinition):]\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// anything else must look like a normal paragraph\n\t\t// note: this finds underlined headings, too\n\t\tdata = data[p.paragraph(data):]\n\t}\n\n\tp.nesting--\n}\n\nfunc (p *Markdown) addBlock(typ NodeType, content []byte) *Node {\n\tp.closeUnmatchedBlocks()\n\tcontainer := p.addChild(typ, 0)\n\tcontainer.content = content\n\treturn container\n}\n\nfunc (p *Markdown) isPrefixHeading(data []byte) bool {\n\tif data[0] != '#' {\n\t\treturn false\n\t}\n\n\tif p.extensions&SpaceHeadings != 0 {\n\t\tlevel := 0\n\t\tfor level < 6 && level < len(data) && data[level] == '#' {\n\t\t\tlevel++\n\t\t}\n\t\tif level == len(data) || data[level] != ' ' {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (p *Markdown) prefixHeading(data []byte) int {\n\tlevel := 0\n\tfor level < 6 && level < len(data) && data[level] == '#' {\n\t\tlevel++\n\t}\n\ti := skipChar(data, level, ' ')\n\tend := skipUntilChar(data, i, '\\n')\n\tskip := end\n\tid := \"\"\n\tif p.extensions&HeadingIDs != 0 {\n\t\tj, k := 0, 0\n\t\t// find start/end of heading id\n\t\tfor j = i; j < end-1 && (data[j] != '{' || data[j+1] != '#'); j++ {\n\t\t}\n\t\tfor k = j + 1; k < end && data[k] != '}'; k++ {\n\t\t}\n\t\t// extract heading id iff found\n\t\tif j < end && k < end {\n\t\t\tid = string(data[j+2 : k])\n\t\t\tend = j\n\t\t\tskip = k + 1\n\t\t\tfor end > 0 && data[end-1] == ' ' {\n\t\t\t\tend--\n\t\t\t}\n\t\t}\n\t}\n\tfor end > 0 && data[end-1] == '#' {\n\t\tif isBackslashEscaped(data, end-1) {\n\t\t\tbreak\n\t\t}\n\t\tend--\n\t}\n\tfor end > 0 && data[end-1] == ' ' {\n\t\tend--\n\t}\n\tif end > i {\n\t\tif id == \"\" && p.extensions&AutoHeadingIDs != 0 {\n\t\t\tid = SanitizedAnchorName(string(data[i:end]))\n\t\t}\n\t\tblock := p.addBlock(Heading, data[i:end])\n\t\tblock.HeadingID = id\n\t\tblock.Level = level\n\t}\n\treturn skip\n}\n\nfunc (p *Markdown) isUnderlinedHeading(data []byte) int {\n\t// test of level 1 heading\n\tif data[0] == '=' {\n\t\ti := skipChar(data, 1, '=')\n\t\ti = skipChar(data, i, ' ')\n\t\tif i < len(data) && data[i] == '\\n' {\n\t\t\treturn 1\n\t\t}\n\t\treturn 0\n\t}\n\n\t// test of level 2 heading\n\tif data[0] == '-' {\n\t\ti := skipChar(data, 1, '-')\n\t\ti = skipChar(data, i, ' ')\n\t\tif i < len(data) && data[i] == '\\n' {\n\t\t\treturn 2\n\t\t}\n\t\treturn 0\n\t}\n\n\treturn 0\n}\n\nfunc (p *Markdown) titleBlock(data []byte, doRender bool) int {\n\tif data[0] != '%' {\n\t\treturn 0\n\t}\n\tsplitData := bytes.Split(data, []byte(\"\\n\"))\n\tvar i int\n\tfor idx, b := range splitData {\n\t\tif !bytes.HasPrefix(b, []byte(\"%\")) {\n\t\t\ti = idx // - 1\n\t\t\tbreak\n\t\t}\n\t}\n\n\tdata = bytes.Join(splitData[0:i], []byte(\"\\n\"))\n\tconsumed := len(data)\n\tdata = bytes.TrimPrefix(data, []byte(\"% \"))\n\tdata = bytes.Replace(data, []byte(\"\\n% \"), []byte(\"\\n\"), -1)\n\tblock := p.addBlock(Heading, data)\n\tblock.Level = 1\n\tblock.IsTitleblock = true\n\n\treturn consumed\n}\n\nfunc (p *Markdown) html(data []byte, doRender bool) int {\n\tvar i, j int\n\n\t// identify the opening tag\n\tif data[0] != '<' {\n\t\treturn 0\n\t}\n\tcurtag, tagfound := p.htmlFindTag(data[1:])\n\n\t// handle special cases\n\tif !tagfound {\n\t\t// check for an HTML comment\n\t\tif size := p.htmlComment(data, doRender); size > 0 {\n\t\t\treturn size\n\t\t}\n\n\t\t// check for an <hr> tag\n\t\tif size := p.htmlHr(data, doRender); size > 0 {\n\t\t\treturn size\n\t\t}\n\n\t\t// no special case recognized\n\t\treturn 0\n\t}\n\n\t// look for an unindented matching closing tag\n\t// followed by a blank line\n\tfound := false\n\t/*\n\t\tclosetag := []byte(\"\\n</\" + curtag + \">\")\n\t\tj = len(curtag) + 1\n\t\tfor !found {\n\t\t\t// scan for a closing tag at the beginning of a line\n\t\t\tif skip := bytes.Index(data[j:], closetag); skip >= 0 {\n\t\t\t\tj += skip + len(closetag)\n\t\t\t} else {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// see if it is the only thing on the line\n\t\t\tif skip := p.isEmpty(data[j:]); skip > 0 {\n\t\t\t\t// see if it is followed by a blank line/eof\n\t\t\t\tj += skip\n\t\t\t\tif j >= len(data) {\n\t\t\t\t\tfound = true\n\t\t\t\t\ti = j\n\t\t\t\t} else {\n\t\t\t\t\tif skip := p.isEmpty(data[j:]); skip > 0 {\n\t\t\t\t\t\tj += skip\n\t\t\t\t\t\tfound = true\n\t\t\t\t\t\ti = j\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t*/\n\n\t// if not found, try a second pass looking for indented match\n\t// but not if tag is \"ins\" or \"del\" (following original Markdown.pl)\n\tif !found && curtag != \"ins\" && curtag != \"del\" {\n\t\ti = 1\n\t\tfor i < len(data) {\n\t\t\ti++\n\t\t\tfor i < len(data) && !(data[i-1] == '<' && data[i] == '/') {\n\t\t\t\ti++\n\t\t\t}\n\n\t\t\tif i+2+len(curtag) >= len(data) {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tj = p.htmlFindEnd(curtag, data[i-1:])\n\n\t\t\tif j > 0 {\n\t\t\t\ti += j - 1\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tif !found {\n\t\treturn 0\n\t}\n\n\t// the end of the block has been found\n\tif doRender {\n\t\t// trim newlines\n\t\tend := i\n\t\tfor end > 0 && data[end-1] == '\\n' {\n\t\t\tend--\n\t\t}\n\t\tfinalizeHTMLBlock(p.addBlock(HTMLBlock, data[:end]))\n\t}\n\n\treturn i\n}\n\nfunc finalizeHTMLBlock(block *Node) {\n\tblock.Literal = block.content\n\tblock.content = nil\n}\n\n// HTML comment, lax form\nfunc (p *Markdown) htmlComment(data []byte, doRender bool) int {\n\ti := p.inlineHTMLComment(data)\n\t// needs to end with a blank line\n\tif j := p.isEmpty(data[i:]); j > 0 {\n\t\tsize := i + j\n\t\tif doRender {\n\t\t\t// trim trailing newlines\n\t\t\tend := size\n\t\t\tfor end > 0 && data[end-1] == '\\n' {\n\t\t\t\tend--\n\t\t\t}\n\t\t\tblock := p.addBlock(HTMLBlock, data[:end])\n\t\t\tfinalizeHTMLBlock(block)\n\t\t}\n\t\treturn size\n\t}\n\treturn 0\n}\n\n// HR, which is the only self-closing block tag considered\nfunc (p *Markdown) htmlHr(data []byte, doRender bool) int {\n\tif len(data) < 4 {\n\t\treturn 0\n\t}\n\tif data[0] != '<' || (data[1] != 'h' && data[1] != 'H') || (data[2] != 'r' && data[2] != 'R') {\n\t\treturn 0\n\t}\n\tif data[3] != ' ' && data[3] != '/' && data[3] != '>' {\n\t\t// not an <hr> tag after all; at least not a valid one\n\t\treturn 0\n\t}\n\ti := 3\n\tfor i < len(data) && data[i] != '>' && data[i] != '\\n' {\n\t\ti++\n\t}\n\tif i < len(data) && data[i] == '>' {\n\t\ti++\n\t\tif j := p.isEmpty(data[i:]); j > 0 {\n\t\t\tsize := i + j\n\t\t\tif doRender {\n\t\t\t\t// trim newlines\n\t\t\t\tend := size\n\t\t\t\tfor end > 0 && data[end-1] == '\\n' {\n\t\t\t\t\tend--\n\t\t\t\t}\n\t\t\t\tfinalizeHTMLBlock(p.addBlock(HTMLBlock, data[:end]))\n\t\t\t}\n\t\t\treturn size\n\t\t}\n\t}\n\treturn 0\n}\n\nfunc (p *Markdown) htmlFindTag(data []byte) (string, bool) {\n\ti := 0\n\tfor i < len(data) && isalnum(data[i]) {\n\t\ti++\n\t}\n\tkey := string(data[:i])\n\tif _, ok := blockTags[key]; ok {\n\t\treturn key, true\n\t}\n\treturn \"\", false\n}\n\nfunc (p *Markdown) htmlFindEnd(tag string, data []byte) int {\n\t// assume data[0] == '<' && data[1] == '/' already tested\n\tif tag == \"hr\" {\n\t\treturn 2\n\t}\n\t// check if tag is a match\n\tclosetag := []byte(\"</\" + tag + \">\")\n\tif !bytes.HasPrefix(data, closetag) {\n\t\treturn 0\n\t}\n\ti := len(closetag)\n\n\t// check that the rest of the line is blank\n\tskip := 0\n\tif skip = p.isEmpty(data[i:]); skip == 0 {\n\t\treturn 0\n\t}\n\ti += skip\n\tskip = 0\n\n\tif i >= len(data) {\n\t\treturn i\n\t}\n\n\tif p.extensions&LaxHTMLBlocks != 0 {\n\t\treturn i\n\t}\n\tif skip = p.isEmpty(data[i:]); skip == 0 {\n\t\t// following line must be blank\n\t\treturn 0\n\t}\n\n\treturn i + skip\n}\n\nfunc (*Markdown) isEmpty(data []byte) int {\n\t// it is okay to call isEmpty on an empty buffer\n\tif len(data) == 0 {\n\t\treturn 0\n\t}\n\n\tvar i int\n\tfor i = 0; i < len(data) && data[i] != '\\n'; i++ {\n\t\tif data[i] != ' ' && data[i] != '\\t' {\n\t\t\treturn 0\n\t\t}\n\t}\n\tif i < len(data) && data[i] == '\\n' {\n\t\ti++\n\t}\n\treturn i\n}\n\nfunc (*Markdown) isHRule(data []byte) bool {\n\ti := 0\n\n\t// skip up to three spaces\n\tfor i < 3 && data[i] == ' ' {\n\t\ti++\n\t}\n\n\t// look at the hrule char\n\tif data[i] != '*' && data[i] != '-' && data[i] != '_' {\n\t\treturn false\n\t}\n\tc := data[i]\n\n\t// the whole line must be the char or whitespace\n\tn := 0\n\tfor i < len(data) && data[i] != '\\n' {\n\t\tswitch {\n\t\tcase data[i] == c:\n\t\t\tn++\n\t\tcase data[i] != ' ':\n\t\t\treturn false\n\t\t}\n\t\ti++\n\t}\n\n\treturn n >= 3\n}\n\n// isFenceLine checks if there's a fence line (e.g., ``` or ``` go) at the beginning of data,\n// and returns the end index if so, or 0 otherwise. It also returns the marker found.\n// If info is not nil, it gets set to the syntax specified in the fence line.\nfunc isFenceLine(data []byte, info *string, oldmarker string) (end int, marker string) {\n\ti, size := 0, 0\n\n\t// skip up to three spaces\n\tfor i < len(data) && i < 3 && data[i] == ' ' {\n\t\ti++\n\t}\n\n\t// check for the marker characters: ~ or `\n\tif i >= len(data) {\n\t\treturn 0, \"\"\n\t}\n\tif data[i] != '~' && data[i] != '`' {\n\t\treturn 0, \"\"\n\t}\n\n\tc := data[i]\n\n\t// the whole line must be the same char or whitespace\n\tfor i < len(data) && data[i] == c {\n\t\tsize++\n\t\ti++\n\t}\n\n\t// the marker char must occur at least 3 times\n\tif size < 3 {\n\t\treturn 0, \"\"\n\t}\n\tmarker = string(data[i-size : i])\n\n\t// if this is the end marker, it must match the beginning marker\n\tif oldmarker != \"\" && marker != oldmarker {\n\t\treturn 0, \"\"\n\t}\n\n\t// TODO(shurcooL): It's probably a good idea to simplify the 2 code paths here\n\t// into one, always get the info string, and discard it if the caller doesn't care.\n\tif info != nil {\n\t\tinfoLength := 0\n\t\ti = skipChar(data, i, ' ')\n\n\t\tif i >= len(data) {\n\t\t\tif i == len(data) {\n\t\t\t\treturn i, marker\n\t\t\t}\n\t\t\treturn 0, \"\"\n\t\t}\n\n\t\tinfoStart := i\n\n\t\tif data[i] == '{' {\n\t\t\ti++\n\t\t\tinfoStart++\n\n\t\t\tfor i < len(data) && data[i] != '}' && data[i] != '\\n' {\n\t\t\t\tinfoLength++\n\t\t\t\ti++\n\t\t\t}\n\n\t\t\tif i >= len(data) || data[i] != '}' {\n\t\t\t\treturn 0, \"\"\n\t\t\t}\n\n\t\t\t// strip all whitespace at the beginning and the end\n\t\t\t// of the {} block\n\t\t\tfor infoLength > 0 && isspace(data[infoStart]) {\n\t\t\t\tinfoStart++\n\t\t\t\tinfoLength--\n\t\t\t}\n\n\t\t\tfor infoLength > 0 && isspace(data[infoStart+infoLength-1]) {\n\t\t\t\tinfoLength--\n\t\t\t}\n\t\t\ti++\n\t\t\ti = skipChar(data, i, ' ')\n\t\t} else {\n\t\t\tfor i < len(data) && !isverticalspace(data[i]) {\n\t\t\t\tinfoLength++\n\t\t\t\ti++\n\t\t\t}\n\t\t}\n\n\t\t*info = strings.TrimSpace(string(data[infoStart : infoStart+infoLength]))\n\t}\n\n\tif i == len(data) {\n\t\treturn i, marker\n\t}\n\tif i > len(data) || data[i] != '\\n' {\n\t\treturn 0, \"\"\n\t}\n\treturn i + 1, marker // Take newline into account.\n}\n\n// fencedCodeBlock returns the end index if data contains a fenced code block at the beginning,\n// or 0 otherwise. It writes to out if doRender is true, otherwise it has no side effects.\n// If doRender is true, a final newline is mandatory to recognize the fenced code block.\nfunc (p *Markdown) fencedCodeBlock(data []byte, doRender bool) int {\n\tvar info string\n\tbeg, marker := isFenceLine(data, &info, \"\")\n\tif beg == 0 || beg >= len(data) {\n\t\treturn 0\n\t}\n\tfenceLength := beg - 1\n\n\tvar work bytes.Buffer\n\twork.Write([]byte(info))\n\twork.WriteByte('\\n')\n\n\tfor {\n\t\t// safe to assume beg < len(data)\n\n\t\t// check for the end of the code block\n\t\tfenceEnd, _ := isFenceLine(data[beg:], nil, marker)\n\t\tif fenceEnd != 0 {\n\t\t\tbeg += fenceEnd\n\t\t\tbreak\n\t\t}\n\n\t\t// copy the current line\n\t\tend := skipUntilChar(data, beg, '\\n') + 1\n\n\t\t// did we reach the end of the buffer without a closing marker?\n\t\tif end >= len(data) {\n\t\t\treturn 0\n\t\t}\n\n\t\t// verbatim copy to the working buffer\n\t\tif doRender {\n\t\t\twork.Write(data[beg:end])\n\t\t}\n\t\tbeg = end\n\t}\n\n\tif doRender {\n\t\tblock := p.addBlock(CodeBlock, work.Bytes()) // TODO: get rid of temp buffer\n\t\tblock.IsFenced = true\n\t\tblock.FenceLength = fenceLength\n\t\tfinalizeCodeBlock(block)\n\t}\n\n\treturn beg\n}\n\nfunc unescapeChar(str []byte) []byte {\n\tif str[0] == '\\\\' {\n\t\treturn []byte{str[1]}\n\t}\n\treturn []byte(html.UnescapeString(string(str)))\n}\n\nfunc unescapeString(str []byte) []byte {\n\tif reBackslashOrAmp.Match(str) {\n\t\treturn reEntityOrEscapedChar.ReplaceAllFunc(str, unescapeChar)\n\t}\n\treturn str\n}\n\nfunc finalizeCodeBlock(block *Node) {\n\tif block.IsFenced {\n\t\tnewlinePos := bytes.IndexByte(block.content, '\\n')\n\t\tfirstLine := block.content[:newlinePos]\n\t\trest := block.content[newlinePos+1:]\n\t\tblock.Info = unescapeString(bytes.Trim(firstLine, \"\\n\"))\n\t\tblock.Literal = rest\n\t} else {\n\t\tblock.Literal = block.content\n\t}\n\tblock.content = nil\n}\n\nfunc (p *Markdown) table(data []byte) int {\n\ttable := p.addBlock(Table, nil)\n\ti, columns := p.tableHeader(data)\n\tif i == 0 {\n\t\tp.tip = table.Parent\n\t\ttable.Unlink()\n\t\treturn 0\n\t}\n\n\tp.addBlock(TableBody, nil)\n\n\tfor i < len(data) {\n\t\tpipes, rowStart := 0, i\n\t\tfor ; i < len(data) && data[i] != '\\n'; i++ {\n\t\t\tif data[i] == '|' {\n\t\t\t\tpipes++\n\t\t\t}\n\t\t}\n\n\t\tif pipes == 0 {\n\t\t\ti = rowStart\n\t\t\tbreak\n\t\t}\n\n\t\t// include the newline in data sent to tableRow\n\t\tif i < len(data) && data[i] == '\\n' {\n\t\t\ti++\n\t\t}\n\t\tp.tableRow(data[rowStart:i], columns, false)\n\t}\n\n\treturn i\n}\n\n// check if the specified position is preceded by an odd number of backslashes\nfunc isBackslashEscaped(data []byte, i int) bool {\n\tbackslashes := 0\n\tfor i-backslashes-1 >= 0 && data[i-backslashes-1] == '\\\\' {\n\t\tbackslashes++\n\t}\n\treturn backslashes&1 == 1\n}\n\nfunc (p *Markdown) tableHeader(data []byte) (size int, columns []CellAlignFlags) {\n\ti := 0\n\tcolCount := 1\n\tfor i = 0; i < len(data) && data[i] != '\\n'; i++ {\n\t\tif data[i] == '|' && !isBackslashEscaped(data, i) {\n\t\t\tcolCount++\n\t\t}\n\t}\n\n\t// doesn't look like a table header\n\tif colCount == 1 {\n\t\treturn\n\t}\n\n\t// include the newline in the data sent to tableRow\n\tj := i\n\tif j < len(data) && data[j] == '\\n' {\n\t\tj++\n\t}\n\theader := data[:j]\n\n\t// column count ignores pipes at beginning or end of line\n\tif data[0] == '|' {\n\t\tcolCount--\n\t}\n\tif i > 2 && data[i-1] == '|' && !isBackslashEscaped(data, i-1) {\n\t\tcolCount--\n\t}\n\n\tcolumns = make([]CellAlignFlags, colCount)\n\n\t// move on to the header underline\n\ti++\n\tif i >= len(data) {\n\t\treturn\n\t}\n\n\tif data[i] == '|' && !isBackslashEscaped(data, i) {\n\t\ti++\n\t}\n\ti = skipChar(data, i, ' ')\n\n\t// each column header is of form: / *:?-+:? *|/ with # dashes + # colons >= 3\n\t// and trailing | optional on last column\n\tcol := 0\n\tfor i < len(data) && data[i] != '\\n' {\n\t\tdashes := 0\n\n\t\tif data[i] == ':' {\n\t\t\ti++\n\t\t\tcolumns[col] |= TableAlignmentLeft\n\t\t\tdashes++\n\t\t}\n\t\tfor i < len(data) && data[i] == '-' {\n\t\t\ti++\n\t\t\tdashes++\n\t\t}\n\t\tif i < len(data) && data[i] == ':' {\n\t\t\ti++\n\t\t\tcolumns[col] |= TableAlignmentRight\n\t\t\tdashes++\n\t\t}\n\t\tfor i < len(data) && data[i] == ' ' {\n\t\t\ti++\n\t\t}\n\t\tif i == len(data) {\n\t\t\treturn\n\t\t}\n\t\t// end of column test is messy\n\t\tswitch {\n\t\tcase dashes < 3:\n\t\t\t// not a valid column\n\t\t\treturn\n\n\t\tcase data[i] == '|' && !isBackslashEscaped(data, i):\n\t\t\t// marker found, now skip past trailing whitespace\n\t\t\tcol++\n\t\t\ti++\n\t\t\tfor i < len(data) && data[i] == ' ' {\n\t\t\t\ti++\n\t\t\t}\n\n\t\t\t// trailing junk found after last column\n\t\t\tif col >= colCount && i < len(data) && data[i] != '\\n' {\n\t\t\t\treturn\n\t\t\t}\n\n\t\tcase (data[i] != '|' || isBackslashEscaped(data, i)) && col+1 < colCount:\n\t\t\t// something else found where marker was required\n\t\t\treturn\n\n\t\tcase data[i] == '\\n':\n\t\t\t// marker is optional for the last column\n\t\t\tcol++\n\n\t\tdefault:\n\t\t\t// trailing junk found after last column\n\t\t\treturn\n\t\t}\n\t}\n\tif col != colCount {\n\t\treturn\n\t}\n\n\tp.addBlock(TableHead, nil)\n\tp.tableRow(header, columns, true)\n\tsize = i\n\tif size < len(data) && data[size] == '\\n' {\n\t\tsize++\n\t}\n\treturn\n}\n\nfunc (p *Markdown) tableRow(data []byte, columns []CellAlignFlags, header bool) {\n\tp.addBlock(TableRow, nil)\n\ti, col := 0, 0\n\n\tif data[i] == '|' && !isBackslashEscaped(data, i) {\n\t\ti++\n\t}\n\n\tfor col = 0; col < len(columns) && i < len(data); col++ {\n\t\tfor i < len(data) && data[i] == ' ' {\n\t\t\ti++\n\t\t}\n\n\t\tcellStart := i\n\n\t\tfor i < len(data) && (data[i] != '|' || isBackslashEscaped(data, i)) && data[i] != '\\n' {\n\t\t\ti++\n\t\t}\n\n\t\tcellEnd := i\n\n\t\t// skip the end-of-cell marker, possibly taking us past end of buffer\n\t\ti++\n\n\t\tfor cellEnd > cellStart && cellEnd-1 < len(data) && data[cellEnd-1] == ' ' {\n\t\t\tcellEnd--\n\t\t}\n\n\t\tcell := p.addBlock(TableCell, data[cellStart:cellEnd])\n\t\tcell.IsHeader = header\n\t\tcell.Align = columns[col]\n\t}\n\n\t// pad it out with empty columns to get the right number\n\tfor ; col < len(columns); col++ {\n\t\tcell := p.addBlock(TableCell, nil)\n\t\tcell.IsHeader = header\n\t\tcell.Align = columns[col]\n\t}\n\n\t// silently ignore rows with too many cells\n}\n\n// returns blockquote prefix length\nfunc (p *Markdown) quotePrefix(data []byte) int {\n\ti := 0\n\tfor i < 3 && i < len(data) && data[i] == ' ' {\n\t\ti++\n\t}\n\tif i < len(data) && data[i] == '>' {\n\t\tif i+1 < len(data) && data[i+1] == ' ' {\n\t\t\treturn i + 2\n\t\t}\n\t\treturn i + 1\n\t}\n\treturn 0\n}\n\n// blockquote ends with at least one blank line\n// followed by something without a blockquote prefix\nfunc (p *Markdown) terminateBlockquote(data []byte, beg, end int) bool {\n\tif p.isEmpty(data[beg:]) <= 0 {\n\t\treturn false\n\t}\n\tif end >= len(data) {\n\t\treturn true\n\t}\n\treturn p.quotePrefix(data[end:]) == 0 && p.isEmpty(data[end:]) == 0\n}\n\n// parse a blockquote fragment\nfunc (p *Markdown) quote(data []byte) int {\n\tblock := p.addBlock(BlockQuote, nil)\n\tvar raw bytes.Buffer\n\tbeg, end := 0, 0\n\tfor beg < len(data) {\n\t\tend = beg\n\t\t// Step over whole lines, collecting them. While doing that, check for\n\t\t// fenced code and if one's found, incorporate it altogether,\n\t\t// irregardless of any contents inside it\n\t\tfor end < len(data) && data[end] != '\\n' {\n\t\t\tif p.extensions&FencedCode != 0 {\n\t\t\t\tif i := p.fencedCodeBlock(data[end:], false); i > 0 {\n\t\t\t\t\t// -1 to compensate for the extra end++ after the loop:\n\t\t\t\t\tend += i - 1\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tend++\n\t\t}\n\t\tif end < len(data) && data[end] == '\\n' {\n\t\t\tend++\n\t\t}\n\t\tif pre := p.quotePrefix(data[beg:]); pre > 0 {\n\t\t\t// skip the prefix\n\t\t\tbeg += pre\n\t\t} else if p.terminateBlockquote(data, beg, end) {\n\t\t\tbreak\n\t\t}\n\t\t// this line is part of the blockquote\n\t\traw.Write(data[beg:end])\n\t\tbeg = end\n\t}\n\tp.block(raw.Bytes())\n\tp.finalize(block)\n\treturn end\n}\n\n// returns prefix length for block code\nfunc (p *Markdown) codePrefix(data []byte) int {\n\tif len(data) >= 1 && data[0] == '\\t' {\n\t\treturn 1\n\t}\n\tif len(data) >= 4 && data[0] == ' ' && data[1] == ' ' && data[2] == ' ' && data[3] == ' ' {\n\t\treturn 4\n\t}\n\treturn 0\n}\n\nfunc (p *Markdown) code(data []byte) int {\n\tvar work bytes.Buffer\n\n\ti := 0\n\tfor i < len(data) {\n\t\tbeg := i\n\t\tfor i < len(data) && data[i] != '\\n' {\n\t\t\ti++\n\t\t}\n\t\tif i < len(data) && data[i] == '\\n' {\n\t\t\ti++\n\t\t}\n\n\t\tblankline := p.isEmpty(data[beg:i]) > 0\n\t\tif pre := p.codePrefix(data[beg:i]); pre > 0 {\n\t\t\tbeg += pre\n\t\t} else if !blankline {\n\t\t\t// non-empty, non-prefixed line breaks the pre\n\t\t\ti = beg\n\t\t\tbreak\n\t\t}\n\n\t\t// verbatim copy to the working buffer\n\t\tif blankline {\n\t\t\twork.WriteByte('\\n')\n\t\t} else {\n\t\t\twork.Write(data[beg:i])\n\t\t}\n\t}\n\n\t// trim all the \\n off the end of work\n\tworkbytes := work.Bytes()\n\teol := len(workbytes)\n\tfor eol > 0 && workbytes[eol-1] == '\\n' {\n\t\teol--\n\t}\n\tif eol != len(workbytes) {\n\t\twork.Truncate(eol)\n\t}\n\n\twork.WriteByte('\\n')\n\n\tblock := p.addBlock(CodeBlock, work.Bytes()) // TODO: get rid of temp buffer\n\tblock.IsFenced = false\n\tfinalizeCodeBlock(block)\n\n\treturn i\n}\n\n// returns unordered list item prefix\nfunc (p *Markdown) uliPrefix(data []byte) int {\n\ti := 0\n\t// start with up to 3 spaces\n\tfor i < len(data) && i < 3 && data[i] == ' ' {\n\t\ti++\n\t}\n\tif i >= len(data)-1 {\n\t\treturn 0\n\t}\n\t// need one of {'*', '+', '-'} followed by a space or a tab\n\tif (data[i] != '*' && data[i] != '+' && data[i] != '-') ||\n\t\t(data[i+1] != ' ' && data[i+1] != '\\t') {\n\t\treturn 0\n\t}\n\treturn i + 2\n}\n\n// returns ordered list item prefix\nfunc (p *Markdown) oliPrefix(data []byte) int {\n\ti := 0\n\n\t// start with up to 3 spaces\n\tfor i < 3 && i < len(data) && data[i] == ' ' {\n\t\ti++\n\t}\n\n\t// count the digits\n\tstart := i\n\tfor i < len(data) && data[i] >= '0' && data[i] <= '9' {\n\t\ti++\n\t}\n\tif start == i || i >= len(data)-1 {\n\t\treturn 0\n\t}\n\n\t// we need >= 1 digits followed by a dot and a space or a tab\n\tif data[i] != '.' || !(data[i+1] == ' ' || data[i+1] == '\\t') {\n\t\treturn 0\n\t}\n\treturn i + 2\n}\n\n// returns definition list item prefix\nfunc (p *Markdown) dliPrefix(data []byte) int {\n\tif len(data) < 2 {\n\t\treturn 0\n\t}\n\ti := 0\n\t// need a ':' followed by a space or a tab\n\tif data[i] != ':' || !(data[i+1] == ' ' || data[i+1] == '\\t') {\n\t\treturn 0\n\t}\n\tfor i < len(data) && data[i] == ' ' {\n\t\ti++\n\t}\n\treturn i + 2\n}\n\n// parse ordered or unordered list block\nfunc (p *Markdown) list(data []byte, flags ListType) int {\n\ti := 0\n\tflags |= ListItemBeginningOfList\n\tblock := p.addBlock(List, nil)\n\tblock.ListFlags = flags\n\tblock.Tight = true\n\n\tfor i < len(data) {\n\t\tskip := p.listItem(data[i:], &flags)\n\t\tif flags&ListItemContainsBlock != 0 {\n\t\t\tblock.ListData.Tight = false\n\t\t}\n\t\ti += skip\n\t\tif skip == 0 || flags&ListItemEndOfList != 0 {\n\t\t\tbreak\n\t\t}\n\t\tflags &= ^ListItemBeginningOfList\n\t}\n\n\tabove := block.Parent\n\tfinalizeList(block)\n\tp.tip = above\n\treturn i\n}\n\n// Returns true if the list item is not the same type as its parent list\nfunc (p *Markdown) listTypeChanged(data []byte, flags *ListType) bool {\n\tif p.dliPrefix(data) > 0 && *flags&ListTypeDefinition == 0 {\n\t\treturn true\n\t} else if p.oliPrefix(data) > 0 && *flags&ListTypeOrdered == 0 {\n\t\treturn true\n\t} else if p.uliPrefix(data) > 0 && (*flags&ListTypeOrdered != 0 || *flags&ListTypeDefinition != 0) {\n\t\treturn true\n\t}\n\treturn false\n}\n\n// Returns true if block ends with a blank line, descending if needed\n// into lists and sublists.\nfunc endsWithBlankLine(block *Node) bool {\n\t// TODO: figure this out. Always false now.\n\tfor block != nil {\n\t\t//if block.lastLineBlank {\n\t\t//return true\n\t\t//}\n\t\tt := block.Type\n\t\tif t == List || t == Item {\n\t\t\tblock = block.LastChild\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn false\n}\n\nfunc finalizeList(block *Node) {\n\tblock.open = false\n\titem := block.FirstChild\n\tfor item != nil {\n\t\t// check for non-final list item ending with blank line:\n\t\tif endsWithBlankLine(item) && item.Next != nil {\n\t\t\tblock.ListData.Tight = false\n\t\t\tbreak\n\t\t}\n\t\t// recurse into children of list item, to see if there are spaces\n\t\t// between any of them:\n\t\tsubItem := item.FirstChild\n\t\tfor subItem != nil {\n\t\t\tif endsWithBlankLine(subItem) && (item.Next != nil || subItem.Next != nil) {\n\t\t\t\tblock.ListData.Tight = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tsubItem = subItem.Next\n\t\t}\n\t\titem = item.Next\n\t}\n}\n\n// Parse a single list item.\n// Assumes initial prefix is already removed if this is a sublist.\nfunc (p *Markdown) listItem(data []byte, flags *ListType) int {\n\t// keep track of the indentation of the first line\n\titemIndent := 0\n\tif data[0] == '\\t' {\n\t\titemIndent += 4\n\t} else {\n\t\tfor itemIndent < 3 && data[itemIndent] == ' ' {\n\t\t\titemIndent++\n\t\t}\n\t}\n\n\tvar bulletChar byte = '*'\n\ti := p.uliPrefix(data)\n\tif i == 0 {\n\t\ti = p.oliPrefix(data)\n\t} else {\n\t\tbulletChar = data[i-2]\n\t}\n\tif i == 0 {\n\t\ti = p.dliPrefix(data)\n\t\t// reset definition term flag\n\t\tif i > 0 {\n\t\t\t*flags &= ^ListTypeTerm\n\t\t}\n\t}\n\tif i == 0 {\n\t\t// if in definition list, set term flag and continue\n\t\tif *flags&ListTypeDefinition != 0 {\n\t\t\t*flags |= ListTypeTerm\n\t\t} else {\n\t\t\treturn 0\n\t\t}\n\t}\n\n\t// skip leading whitespace on first line\n\tfor i < len(data) && data[i] == ' ' {\n\t\ti++\n\t}\n\n\t// find the end of the line\n\tline := i\n\tfor i > 0 && i < len(data) && data[i-1] != '\\n' {\n\t\ti++\n\t}\n\n\t// get working buffer\n\tvar raw bytes.Buffer\n\n\t// put the first line into the working buffer\n\traw.Write(data[line:i])\n\tline = i\n\n\t// process the following lines\n\tcontainsBlankLine := false\n\tsublist := 0\n\tcodeBlockMarker := \"\"\n\ngatherlines:\n\tfor line < len(data) {\n\t\ti++\n\n\t\t// find the end of this line\n\t\tfor i < len(data) && data[i-1] != '\\n' {\n\t\t\ti++\n\t\t}\n\n\t\t// if it is an empty line, guess that it is part of this item\n\t\t// and move on to the next line\n\t\tif p.isEmpty(data[line:i]) > 0 {\n\t\t\tcontainsBlankLine = true\n\t\t\tline = i\n\t\t\tcontinue\n\t\t}\n\n\t\t// calculate the indentation\n\t\tindent := 0\n\t\tindentIndex := 0\n\t\tif data[line] == '\\t' {\n\t\t\tindentIndex++\n\t\t\tindent += 4\n\t\t} else {\n\t\t\tfor indent < 4 && line+indent < i && data[line+indent] == ' ' {\n\t\t\t\tindent++\n\t\t\t\tindentIndex++\n\t\t\t}\n\t\t}\n\n\t\tchunk := data[line+indentIndex : i]\n\n\t\tif p.extensions&FencedCode != 0 {\n\t\t\t// determine if in or out of codeblock\n\t\t\t// if in codeblock, ignore normal list processing\n\t\t\t_, marker := isFenceLine(chunk, nil, codeBlockMarker)\n\t\t\tif marker != \"\" {\n\t\t\t\tif codeBlockMarker == \"\" {\n\t\t\t\t\t// start of codeblock\n\t\t\t\t\tcodeBlockMarker = marker\n\t\t\t\t} else {\n\t\t\t\t\t// end of codeblock.\n\t\t\t\t\tcodeBlockMarker = \"\"\n\t\t\t\t}\n\t\t\t}\n\t\t\t// we are in a codeblock, write line, and continue\n\t\t\tif codeBlockMarker != \"\" || marker != \"\" {\n\t\t\t\traw.Write(data[line+indentIndex : i])\n\t\t\t\tline = i\n\t\t\t\tcontinue gatherlines\n\t\t\t}\n\t\t}\n\n\t\t// evaluate how this line fits in\n\t\tswitch {\n\t\t// is this a nested list item?\n\t\tcase (p.uliPrefix(chunk) > 0 && !p.isHRule(chunk)) ||\n\t\t\tp.oliPrefix(chunk) > 0 ||\n\t\t\tp.dliPrefix(chunk) > 0:\n\n\t\t\t// to be a nested list, it must be indented more\n\t\t\t// if not, it is either a different kind of list\n\t\t\t// or the next item in the same list\n\t\t\tif indent <= itemIndent {\n\t\t\t\tif p.listTypeChanged(chunk, flags) {\n\t\t\t\t\t*flags |= ListItemEndOfList\n\t\t\t\t} else if containsBlankLine {\n\t\t\t\t\t*flags |= ListItemContainsBlock\n\t\t\t\t}\n\n\t\t\t\tbreak gatherlines\n\t\t\t}\n\n\t\t\tif containsBlankLine {\n\t\t\t\t*flags |= ListItemContainsBlock\n\t\t\t}\n\n\t\t\t// is this the first item in the nested list?\n\t\t\tif sublist == 0 {\n\t\t\t\tsublist = raw.Len()\n\t\t\t}\n\n\t\t// is this a nested prefix heading?\n\t\tcase p.isPrefixHeading(chunk):\n\t\t\t// if the heading is not indented, it is not nested in the list\n\t\t\t// and thus ends the list\n\t\t\tif containsBlankLine && indent < 4 {\n\t\t\t\t*flags |= ListItemEndOfList\n\t\t\t\tbreak gatherlines\n\t\t\t}\n\t\t\t*flags |= ListItemContainsBlock\n\n\t\t// anything following an empty line is only part\n\t\t// of this item if it is indented 4 spaces\n\t\t// (regardless of the indentation of the beginning of the item)\n\t\tcase containsBlankLine && indent < 4:\n\t\t\tif *flags&ListTypeDefinition != 0 && i < len(data)-1 {\n\t\t\t\t// is the next item still a part of this list?\n\t\t\t\tnext := i\n\t\t\t\tfor next < len(data) && data[next] != '\\n' {\n\t\t\t\t\tnext++\n\t\t\t\t}\n\t\t\t\tfor next < len(data)-1 && data[next] == '\\n' {\n\t\t\t\t\tnext++\n\t\t\t\t}\n\t\t\t\tif i < len(data)-1 && data[i] != ':' && data[next] != ':' {\n\t\t\t\t\t*flags |= ListItemEndOfList\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t*flags |= ListItemEndOfList\n\t\t\t}\n\t\t\tbreak gatherlines\n\n\t\t// a blank line means this should be parsed as a block\n\t\tcase containsBlankLine:\n\t\t\traw.WriteByte('\\n')\n\t\t\t*flags |= ListItemContainsBlock\n\t\t}\n\n\t\t// if this line was preceded by one or more blanks,\n\t\t// re-introduce the blank into the buffer\n\t\tif containsBlankLine {\n\t\t\tcontainsBlankLine = false\n\t\t\traw.WriteByte('\\n')\n\t\t}\n\n\t\t// add the line into the working buffer without prefix\n\t\traw.Write(data[line+indentIndex : i])\n\n\t\tline = i\n\t}\n\n\trawBytes := raw.Bytes()\n\n\tblock := p.addBlock(Item, nil)\n\tblock.ListFlags = *flags\n\tblock.Tight = false\n\tblock.BulletChar = bulletChar\n\tblock.Delimiter = '.' // Only '.' is possible in Markdown, but ')' will also be possible in CommonMark\n\n\t// render the contents of the list item\n\tif *flags&ListItemContainsBlock != 0 && *flags&ListTypeTerm == 0 {\n\t\t// intermediate render of block item, except for definition term\n\t\tif sublist > 0 {\n\t\t\tp.block(rawBytes[:sublist])\n\t\t\tp.block(rawBytes[sublist:])\n\t\t} else {\n\t\t\tp.block(rawBytes)\n\t\t}\n\t} else {\n\t\t// intermediate render of inline item\n\t\tif sublist > 0 {\n\t\t\tchild := p.addChild(Paragraph, 0)\n\t\t\tchild.content = rawBytes[:sublist]\n\t\t\tp.block(rawBytes[sublist:])\n\t\t} else {\n\t\t\tchild := p.addChild(Paragraph, 0)\n\t\t\tchild.content = rawBytes\n\t\t}\n\t}\n\treturn line\n}\n\n// render a single paragraph that has already been parsed out\nfunc (p *Markdown) renderParagraph(data []byte) {\n\tif len(data) == 0 {\n\t\treturn\n\t}\n\n\t// trim leading spaces\n\tbeg := 0\n\tfor data[beg] == ' ' {\n\t\tbeg++\n\t}\n\n\tend := len(data)\n\t// trim trailing newline\n\tif data[len(data)-1] == '\\n' {\n\t\tend--\n\t}\n\n\t// trim trailing spaces\n\tfor end > beg && data[end-1] == ' ' {\n\t\tend--\n\t}\n\n\tp.addBlock(Paragraph, data[beg:end])\n}\n\nfunc (p *Markdown) paragraph(data []byte) int {\n\t// prev: index of 1st char of previous line\n\t// line: index of 1st char of current line\n\t// i: index of cursor/end of current line\n\tvar prev, line, i int\n\ttabSize := TabSizeDefault\n\tif p.extensions&TabSizeEight != 0 {\n\t\ttabSize = TabSizeDouble\n\t}\n\t// keep going until we find something to mark the end of the paragraph\n\tfor i < len(data) {\n\t\t// mark the beginning of the current line\n\t\tprev = line\n\t\tcurrent := data[i:]\n\t\tline = i\n\n\t\t// did we find a reference or a footnote? If so, end a paragraph\n\t\t// preceding it and report that we have consumed up to the end of that\n\t\t// reference:\n\t\tif refEnd := isReference(p, current, tabSize); refEnd > 0 {\n\t\t\tp.renderParagraph(data[:i])\n\t\t\treturn i + refEnd\n\t\t}\n\n\t\t// did we find a blank line marking the end of the paragraph?\n\t\tif n := p.isEmpty(current); n > 0 {\n\t\t\t// did this blank line followed by a definition list item?\n\t\t\tif p.extensions&DefinitionLists != 0 {\n\t\t\t\tif i < len(data)-1 && data[i+1] == ':' {\n\t\t\t\t\treturn p.list(data[prev:], ListTypeDefinition)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tp.renderParagraph(data[:i])\n\t\t\treturn i + n\n\t\t}\n\n\t\t// an underline under some text marks a heading, so our paragraph ended on prev line\n\t\tif i > 0 {\n\t\t\tif level := p.isUnderlinedHeading(current); level > 0 {\n\t\t\t\t// render the paragraph\n\t\t\t\tp.renderParagraph(data[:prev])\n\n\t\t\t\t// ignore leading and trailing whitespace\n\t\t\t\teol := i - 1\n\t\t\t\tfor prev < eol && data[prev] == ' ' {\n\t\t\t\t\tprev++\n\t\t\t\t}\n\t\t\t\tfor eol > prev && data[eol-1] == ' ' {\n\t\t\t\t\teol--\n\t\t\t\t}\n\n\t\t\t\tid := \"\"\n\t\t\t\tif p.extensions&AutoHeadingIDs != 0 {\n\t\t\t\t\tid = SanitizedAnchorName(string(data[prev:eol]))\n\t\t\t\t}\n\n\t\t\t\tblock := p.addBlock(Heading, data[prev:eol])\n\t\t\t\tblock.Level = level\n\t\t\t\tblock.HeadingID = id\n\n\t\t\t\t// find the end of the underline\n\t\t\t\tfor i < len(data) && data[i] != '\\n' {\n\t\t\t\t\ti++\n\t\t\t\t}\n\t\t\t\treturn i\n\t\t\t}\n\t\t}\n\n\t\t// if the next line starts a block of HTML, then the paragraph ends here\n\t\tif p.extensions&LaxHTMLBlocks != 0 {\n\t\t\tif data[i] == '<' && p.html(current, false) > 0 {\n\t\t\t\t// rewind to before the HTML block\n\t\t\t\tp.renderParagraph(data[:i])\n\t\t\t\treturn i\n\t\t\t}\n\t\t}\n\n\t\t// if there's a prefixed heading or a horizontal rule after this, paragraph is over\n\t\tif p.isPrefixHeading(current) || p.isHRule(current) {\n\t\t\tp.renderParagraph(data[:i])\n\t\t\treturn i\n\t\t}\n\n\t\t// if there's a fenced code block, paragraph is over\n\t\tif p.extensions&FencedCode != 0 {\n\t\t\tif p.fencedCodeBlock(current, false) > 0 {\n\t\t\t\tp.renderParagraph(data[:i])\n\t\t\t\treturn i\n\t\t\t}\n\t\t}\n\n\t\t// if there's a definition list item, prev line is a definition term\n\t\tif p.extensions&DefinitionLists != 0 {\n\t\t\tif p.dliPrefix(current) != 0 {\n\t\t\t\tret := p.list(data[prev:], ListTypeDefinition)\n\t\t\t\treturn ret\n\t\t\t}\n\t\t}\n\n\t\t// if there's a list after this, paragraph is over\n\t\tif p.extensions&NoEmptyLineBeforeBlock != 0 {\n\t\t\tif p.uliPrefix(current) != 0 ||\n\t\t\t\tp.oliPrefix(current) != 0 ||\n\t\t\t\tp.quotePrefix(current) != 0 ||\n\t\t\t\tp.codePrefix(current) != 0 {\n\t\t\t\tp.renderParagraph(data[:i])\n\t\t\t\treturn i\n\t\t\t}\n\t\t}\n\n\t\t// otherwise, scan to the beginning of the next line\n\t\tnl := bytes.IndexByte(data[i:], '\\n')\n\t\tif nl >= 0 {\n\t\t\ti += nl + 1\n\t\t} else {\n\t\t\ti += len(data[i:])\n\t\t}\n\t}\n\n\tp.renderParagraph(data[:i])\n\treturn i\n}\n\nfunc skipChar(data []byte, start int, char byte) int {\n\ti := start\n\tfor i < len(data) && data[i] == char {\n\t\ti++\n\t}\n\treturn i\n}\n\nfunc skipUntilChar(text []byte, start int, char byte) int {\n\ti := start\n\tfor i < len(text) && text[i] != char {\n\t\ti++\n\t}\n\treturn i\n}\n\n// SanitizedAnchorName returns a sanitized anchor name for the given text.\n//\n// It implements the algorithm specified in the package comment.\nfunc SanitizedAnchorName(text string) string {\n\tvar anchorName []rune\n\tfutureDash := false\n\tfor _, r := range text {\n\t\tswitch {\n\t\tcase unicode.IsLetter(r) || unicode.IsNumber(r):\n\t\t\tif futureDash && len(anchorName) > 0 {\n\t\t\t\tanchorName = append(anchorName, '-')\n\t\t\t}\n\t\t\tfutureDash = false\n\t\t\tanchorName = append(anchorName, unicode.ToLower(r))\n\t\tdefault:\n\t\t\tfutureDash = true\n\t\t}\n\t}\n\treturn string(anchorName)\n}\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/doc.go",
    "content": "// Package blackfriday is a markdown processor.\n//\n// It translates plain text with simple formatting rules into an AST, which can\n// then be further processed to HTML (provided by Blackfriday itself) or other\n// formats (provided by the community).\n//\n// The simplest way to invoke Blackfriday is to call the Run function. It will\n// take a text input and produce a text output in HTML (or other format).\n//\n// A slightly more sophisticated way to use Blackfriday is to create a Markdown\n// processor and to call Parse, which returns a syntax tree for the input\n// document. You can leverage Blackfriday's parsing for content extraction from\n// markdown documents. You can assign a custom renderer and set various options\n// to the Markdown processor.\n//\n// If you're interested in calling Blackfriday from command line, see\n// https://github.com/russross/blackfriday-tool.\n//\n// Sanitized Anchor Names\n//\n// Blackfriday includes an algorithm for creating sanitized anchor names\n// corresponding to a given input text. This algorithm is used to create\n// anchors for headings when AutoHeadingIDs extension is enabled. The\n// algorithm is specified below, so that other packages can create\n// compatible anchor names and links to those anchors.\n//\n// The algorithm iterates over the input text, interpreted as UTF-8,\n// one Unicode code point (rune) at a time. All runes that are letters (category L)\n// or numbers (category N) are considered valid characters. They are mapped to\n// lower case, and included in the output. All other runes are considered\n// invalid characters. Invalid characters that precede the first valid character,\n// as well as invalid character that follow the last valid character\n// are dropped completely. All other sequences of invalid characters\n// between two valid characters are replaced with a single dash character '-'.\n//\n// SanitizedAnchorName exposes this functionality, and can be used to\n// create compatible links to the anchor names generated by blackfriday.\n// This algorithm is also implemented in a small standalone package at\n// github.com/shurcooL/sanitized_anchor_name. It can be useful for clients\n// that want a small package and don't need full functionality of blackfriday.\npackage blackfriday\n\n// NOTE: Keep Sanitized Anchor Name algorithm in sync with package\n//       github.com/shurcooL/sanitized_anchor_name.\n//       Otherwise, users of sanitized_anchor_name will get anchor names\n//       that are incompatible with those generated by blackfriday.\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/entities.go",
    "content": "package blackfriday\n\n// Extracted from https://html.spec.whatwg.org/multipage/entities.json\nvar entities = map[string]bool{\n\t\"&AElig\":                            true,\n\t\"&AElig;\":                           true,\n\t\"&AMP\":                              true,\n\t\"&AMP;\":                             true,\n\t\"&Aacute\":                           true,\n\t\"&Aacute;\":                          true,\n\t\"&Abreve;\":                          true,\n\t\"&Acirc\":                            true,\n\t\"&Acirc;\":                           true,\n\t\"&Acy;\":                             true,\n\t\"&Afr;\":                             true,\n\t\"&Agrave\":                           true,\n\t\"&Agrave;\":                          true,\n\t\"&Alpha;\":                           true,\n\t\"&Amacr;\":                           true,\n\t\"&And;\":                             true,\n\t\"&Aogon;\":                           true,\n\t\"&Aopf;\":                            true,\n\t\"&ApplyFunction;\":                   true,\n\t\"&Aring\":                            true,\n\t\"&Aring;\":                           true,\n\t\"&Ascr;\":                            true,\n\t\"&Assign;\":                          true,\n\t\"&Atilde\":                           true,\n\t\"&Atilde;\":                          true,\n\t\"&Auml\":                             true,\n\t\"&Auml;\":                            true,\n\t\"&Backslash;\":                       true,\n\t\"&Barv;\":                            true,\n\t\"&Barwed;\":                          true,\n\t\"&Bcy;\":                             true,\n\t\"&Because;\":                         true,\n\t\"&Bernoullis;\":                      true,\n\t\"&Beta;\":                            true,\n\t\"&Bfr;\":                             true,\n\t\"&Bopf;\":                            true,\n\t\"&Breve;\":                           true,\n\t\"&Bscr;\":                            true,\n\t\"&Bumpeq;\":                          true,\n\t\"&CHcy;\":                            true,\n\t\"&COPY\":                             true,\n\t\"&COPY;\":                            true,\n\t\"&Cacute;\":                          true,\n\t\"&Cap;\":                             true,\n\t\"&CapitalDifferentialD;\":            true,\n\t\"&Cayleys;\":                         true,\n\t\"&Ccaron;\":                          true,\n\t\"&Ccedil\":                           true,\n\t\"&Ccedil;\":                          true,\n\t\"&Ccirc;\":                           true,\n\t\"&Cconint;\":                         true,\n\t\"&Cdot;\":                            true,\n\t\"&Cedilla;\":                         true,\n\t\"&CenterDot;\":                       true,\n\t\"&Cfr;\":                             true,\n\t\"&Chi;\":                             true,\n\t\"&CircleDot;\":                       true,\n\t\"&CircleMinus;\":                     true,\n\t\"&CirclePlus;\":                      true,\n\t\"&CircleTimes;\":                     true,\n\t\"&ClockwiseContourIntegral;\":        true,\n\t\"&CloseCurlyDoubleQuote;\":           true,\n\t\"&CloseCurlyQuote;\":                 true,\n\t\"&Colon;\":                           true,\n\t\"&Colone;\":                          true,\n\t\"&Congruent;\":                       true,\n\t\"&Conint;\":                          true,\n\t\"&ContourIntegral;\":                 true,\n\t\"&Copf;\":                            true,\n\t\"&Coproduct;\":                       true,\n\t\"&CounterClockwiseContourIntegral;\": true,\n\t\"&Cross;\":                           true,\n\t\"&Cscr;\":                            true,\n\t\"&Cup;\":                             true,\n\t\"&CupCap;\":                          true,\n\t\"&DD;\":                              true,\n\t\"&DDotrahd;\":                        true,\n\t\"&DJcy;\":                            true,\n\t\"&DScy;\":                            true,\n\t\"&DZcy;\":                            true,\n\t\"&Dagger;\":                          true,\n\t\"&Darr;\":                            true,\n\t\"&Dashv;\":                           true,\n\t\"&Dcaron;\":                          true,\n\t\"&Dcy;\":                             true,\n\t\"&Del;\":                             true,\n\t\"&Delta;\":                           true,\n\t\"&Dfr;\":                             true,\n\t\"&DiacriticalAcute;\":                true,\n\t\"&DiacriticalDot;\":                  true,\n\t\"&DiacriticalDoubleAcute;\":          true,\n\t\"&DiacriticalGrave;\":                true,\n\t\"&DiacriticalTilde;\":                true,\n\t\"&Diamond;\":                         true,\n\t\"&DifferentialD;\":                   true,\n\t\"&Dopf;\":                            true,\n\t\"&Dot;\":                             true,\n\t\"&DotDot;\":                          true,\n\t\"&DotEqual;\":                        true,\n\t\"&DoubleContourIntegral;\":           true,\n\t\"&DoubleDot;\":                       true,\n\t\"&DoubleDownArrow;\":                 true,\n\t\"&DoubleLeftArrow;\":                 true,\n\t\"&DoubleLeftRightArrow;\":            true,\n\t\"&DoubleLeftTee;\":                   true,\n\t\"&DoubleLongLeftArrow;\":             true,\n\t\"&DoubleLongLeftRightArrow;\":        true,\n\t\"&DoubleLongRightArrow;\":            true,\n\t\"&DoubleRightArrow;\":                true,\n\t\"&DoubleRightTee;\":                  true,\n\t\"&DoubleUpArrow;\":                   true,\n\t\"&DoubleUpDownArrow;\":               true,\n\t\"&DoubleVerticalBar;\":               true,\n\t\"&DownArrow;\":                       true,\n\t\"&DownArrowBar;\":                    true,\n\t\"&DownArrowUpArrow;\":                true,\n\t\"&DownBreve;\":                       true,\n\t\"&DownLeftRightVector;\":             true,\n\t\"&DownLeftTeeVector;\":               true,\n\t\"&DownLeftVector;\":                  true,\n\t\"&DownLeftVectorBar;\":               true,\n\t\"&DownRightTeeVector;\":              true,\n\t\"&DownRightVector;\":                 true,\n\t\"&DownRightVectorBar;\":              true,\n\t\"&DownTee;\":                         true,\n\t\"&DownTeeArrow;\":                    true,\n\t\"&Downarrow;\":                       true,\n\t\"&Dscr;\":                            true,\n\t\"&Dstrok;\":                          true,\n\t\"&ENG;\":                             true,\n\t\"&ETH\":                              true,\n\t\"&ETH;\":                             true,\n\t\"&Eacute\":                           true,\n\t\"&Eacute;\":                          true,\n\t\"&Ecaron;\":                          true,\n\t\"&Ecirc\":                            true,\n\t\"&Ecirc;\":                           true,\n\t\"&Ecy;\":                             true,\n\t\"&Edot;\":                            true,\n\t\"&Efr;\":                             true,\n\t\"&Egrave\":                           true,\n\t\"&Egrave;\":                          true,\n\t\"&Element;\":                         true,\n\t\"&Emacr;\":                           true,\n\t\"&EmptySmallSquare;\":                true,\n\t\"&EmptyVerySmallSquare;\":            true,\n\t\"&Eogon;\":                           true,\n\t\"&Eopf;\":                            true,\n\t\"&Epsilon;\":                         true,\n\t\"&Equal;\":                           true,\n\t\"&EqualTilde;\":                      true,\n\t\"&Equilibrium;\":                     true,\n\t\"&Escr;\":                            true,\n\t\"&Esim;\":                            true,\n\t\"&Eta;\":                             true,\n\t\"&Euml\":                             true,\n\t\"&Euml;\":                            true,\n\t\"&Exists;\":                          true,\n\t\"&ExponentialE;\":                    true,\n\t\"&Fcy;\":                             true,\n\t\"&Ffr;\":                             true,\n\t\"&FilledSmallSquare;\":               true,\n\t\"&FilledVerySmallSquare;\":           true,\n\t\"&Fopf;\":                            true,\n\t\"&ForAll;\":                          true,\n\t\"&Fouriertrf;\":                      true,\n\t\"&Fscr;\":                            true,\n\t\"&GJcy;\":                            true,\n\t\"&GT\":                               true,\n\t\"&GT;\":                              true,\n\t\"&Gamma;\":                           true,\n\t\"&Gammad;\":                          true,\n\t\"&Gbreve;\":                          true,\n\t\"&Gcedil;\":                          true,\n\t\"&Gcirc;\":                           true,\n\t\"&Gcy;\":                             true,\n\t\"&Gdot;\":                            true,\n\t\"&Gfr;\":                             true,\n\t\"&Gg;\":                              true,\n\t\"&Gopf;\":                            true,\n\t\"&GreaterEqual;\":                    true,\n\t\"&GreaterEqualLess;\":                true,\n\t\"&GreaterFullEqual;\":                true,\n\t\"&GreaterGreater;\":                  true,\n\t\"&GreaterLess;\":                     true,\n\t\"&GreaterSlantEqual;\":               true,\n\t\"&GreaterTilde;\":                    true,\n\t\"&Gscr;\":                            true,\n\t\"&Gt;\":                              true,\n\t\"&HARDcy;\":                          true,\n\t\"&Hacek;\":                           true,\n\t\"&Hat;\":                             true,\n\t\"&Hcirc;\":                           true,\n\t\"&Hfr;\":                             true,\n\t\"&HilbertSpace;\":                    true,\n\t\"&Hopf;\":                            true,\n\t\"&HorizontalLine;\":                  true,\n\t\"&Hscr;\":                            true,\n\t\"&Hstrok;\":                          true,\n\t\"&HumpDownHump;\":                    true,\n\t\"&HumpEqual;\":                       true,\n\t\"&IEcy;\":                            true,\n\t\"&IJlig;\":                           true,\n\t\"&IOcy;\":                            true,\n\t\"&Iacute\":                           true,\n\t\"&Iacute;\":                          true,\n\t\"&Icirc\":                            true,\n\t\"&Icirc;\":                           true,\n\t\"&Icy;\":                             true,\n\t\"&Idot;\":                            true,\n\t\"&Ifr;\":                             true,\n\t\"&Igrave\":                           true,\n\t\"&Igrave;\":                          true,\n\t\"&Im;\":                              true,\n\t\"&Imacr;\":                           true,\n\t\"&ImaginaryI;\":                      true,\n\t\"&Implies;\":                         true,\n\t\"&Int;\":                             true,\n\t\"&Integral;\":                        true,\n\t\"&Intersection;\":                    true,\n\t\"&InvisibleComma;\":                  true,\n\t\"&InvisibleTimes;\":                  true,\n\t\"&Iogon;\":                           true,\n\t\"&Iopf;\":                            true,\n\t\"&Iota;\":                            true,\n\t\"&Iscr;\":                            true,\n\t\"&Itilde;\":                          true,\n\t\"&Iukcy;\":                           true,\n\t\"&Iuml\":                             true,\n\t\"&Iuml;\":                            true,\n\t\"&Jcirc;\":                           true,\n\t\"&Jcy;\":                             true,\n\t\"&Jfr;\":                             true,\n\t\"&Jopf;\":                            true,\n\t\"&Jscr;\":                            true,\n\t\"&Jsercy;\":                          true,\n\t\"&Jukcy;\":                           true,\n\t\"&KHcy;\":                            true,\n\t\"&KJcy;\":                            true,\n\t\"&Kappa;\":                           true,\n\t\"&Kcedil;\":                          true,\n\t\"&Kcy;\":                             true,\n\t\"&Kfr;\":                             true,\n\t\"&Kopf;\":                            true,\n\t\"&Kscr;\":                            true,\n\t\"&LJcy;\":                            true,\n\t\"&LT\":                               true,\n\t\"&LT;\":                              true,\n\t\"&Lacute;\":                          true,\n\t\"&Lambda;\":                          true,\n\t\"&Lang;\":                            true,\n\t\"&Laplacetrf;\":                      true,\n\t\"&Larr;\":                            true,\n\t\"&Lcaron;\":                          true,\n\t\"&Lcedil;\":                          true,\n\t\"&Lcy;\":                             true,\n\t\"&LeftAngleBracket;\":                true,\n\t\"&LeftArrow;\":                       true,\n\t\"&LeftArrowBar;\":                    true,\n\t\"&LeftArrowRightArrow;\":             true,\n\t\"&LeftCeiling;\":                     true,\n\t\"&LeftDoubleBracket;\":               true,\n\t\"&LeftDownTeeVector;\":               true,\n\t\"&LeftDownVector;\":                  true,\n\t\"&LeftDownVectorBar;\":               true,\n\t\"&LeftFloor;\":                       true,\n\t\"&LeftRightArrow;\":                  true,\n\t\"&LeftRightVector;\":                 true,\n\t\"&LeftTee;\":                         true,\n\t\"&LeftTeeArrow;\":                    true,\n\t\"&LeftTeeVector;\":                   true,\n\t\"&LeftTriangle;\":                    true,\n\t\"&LeftTriangleBar;\":                 true,\n\t\"&LeftTriangleEqual;\":               true,\n\t\"&LeftUpDownVector;\":                true,\n\t\"&LeftUpTeeVector;\":                 true,\n\t\"&LeftUpVector;\":                    true,\n\t\"&LeftUpVectorBar;\":                 true,\n\t\"&LeftVector;\":                      true,\n\t\"&LeftVectorBar;\":                   true,\n\t\"&Leftarrow;\":                       true,\n\t\"&Leftrightarrow;\":                  true,\n\t\"&LessEqualGreater;\":                true,\n\t\"&LessFullEqual;\":                   true,\n\t\"&LessGreater;\":                     true,\n\t\"&LessLess;\":                        true,\n\t\"&LessSlantEqual;\":                  true,\n\t\"&LessTilde;\":                       true,\n\t\"&Lfr;\":                             true,\n\t\"&Ll;\":                              true,\n\t\"&Lleftarrow;\":                      true,\n\t\"&Lmidot;\":                          true,\n\t\"&LongLeftArrow;\":                   true,\n\t\"&LongLeftRightArrow;\":              true,\n\t\"&LongRightArrow;\":                  true,\n\t\"&Longleftarrow;\":                   true,\n\t\"&Longleftrightarrow;\":              true,\n\t\"&Longrightarrow;\":                  true,\n\t\"&Lopf;\":                            true,\n\t\"&LowerLeftArrow;\":                  true,\n\t\"&LowerRightArrow;\":                 true,\n\t\"&Lscr;\":                            true,\n\t\"&Lsh;\":                             true,\n\t\"&Lstrok;\":                          true,\n\t\"&Lt;\":                              true,\n\t\"&Map;\":                             true,\n\t\"&Mcy;\":                             true,\n\t\"&MediumSpace;\":                     true,\n\t\"&Mellintrf;\":                       true,\n\t\"&Mfr;\":                             true,\n\t\"&MinusPlus;\":                       true,\n\t\"&Mopf;\":                            true,\n\t\"&Mscr;\":                            true,\n\t\"&Mu;\":                              true,\n\t\"&NJcy;\":                            true,\n\t\"&Nacute;\":                          true,\n\t\"&Ncaron;\":                          true,\n\t\"&Ncedil;\":                          true,\n\t\"&Ncy;\":                             true,\n\t\"&NegativeMediumSpace;\":             true,\n\t\"&NegativeThickSpace;\":              true,\n\t\"&NegativeThinSpace;\":               true,\n\t\"&NegativeVeryThinSpace;\":           true,\n\t\"&NestedGreaterGreater;\":            true,\n\t\"&NestedLessLess;\":                  true,\n\t\"&NewLine;\":                         true,\n\t\"&Nfr;\":                             true,\n\t\"&NoBreak;\":                         true,\n\t\"&NonBreakingSpace;\":                true,\n\t\"&Nopf;\":                            true,\n\t\"&Not;\":                             true,\n\t\"&NotCongruent;\":                    true,\n\t\"&NotCupCap;\":                       true,\n\t\"&NotDoubleVerticalBar;\":            true,\n\t\"&NotElement;\":                      true,\n\t\"&NotEqual;\":                        true,\n\t\"&NotEqualTilde;\":                   true,\n\t\"&NotExists;\":                       true,\n\t\"&NotGreater;\":                      true,\n\t\"&NotGreaterEqual;\":                 true,\n\t\"&NotGreaterFullEqual;\":             true,\n\t\"&NotGreaterGreater;\":               true,\n\t\"&NotGreaterLess;\":                  true,\n\t\"&NotGreaterSlantEqual;\":            true,\n\t\"&NotGreaterTilde;\":                 true,\n\t\"&NotHumpDownHump;\":                 true,\n\t\"&NotHumpEqual;\":                    true,\n\t\"&NotLeftTriangle;\":                 true,\n\t\"&NotLeftTriangleBar;\":              true,\n\t\"&NotLeftTriangleEqual;\":            true,\n\t\"&NotLess;\":                         true,\n\t\"&NotLessEqual;\":                    true,\n\t\"&NotLessGreater;\":                  true,\n\t\"&NotLessLess;\":                     true,\n\t\"&NotLessSlantEqual;\":               true,\n\t\"&NotLessTilde;\":                    true,\n\t\"&NotNestedGreaterGreater;\":         true,\n\t\"&NotNestedLessLess;\":               true,\n\t\"&NotPrecedes;\":                     true,\n\t\"&NotPrecedesEqual;\":                true,\n\t\"&NotPrecedesSlantEqual;\":           true,\n\t\"&NotReverseElement;\":               true,\n\t\"&NotRightTriangle;\":                true,\n\t\"&NotRightTriangleBar;\":             true,\n\t\"&NotRightTriangleEqual;\":           true,\n\t\"&NotSquareSubset;\":                 true,\n\t\"&NotSquareSubsetEqual;\":            true,\n\t\"&NotSquareSuperset;\":               true,\n\t\"&NotSquareSupersetEqual;\":          true,\n\t\"&NotSubset;\":                       true,\n\t\"&NotSubsetEqual;\":                  true,\n\t\"&NotSucceeds;\":                     true,\n\t\"&NotSucceedsEqual;\":                true,\n\t\"&NotSucceedsSlantEqual;\":           true,\n\t\"&NotSucceedsTilde;\":                true,\n\t\"&NotSuperset;\":                     true,\n\t\"&NotSupersetEqual;\":                true,\n\t\"&NotTilde;\":                        true,\n\t\"&NotTildeEqual;\":                   true,\n\t\"&NotTildeFullEqual;\":               true,\n\t\"&NotTildeTilde;\":                   true,\n\t\"&NotVerticalBar;\":                  true,\n\t\"&Nscr;\":                            true,\n\t\"&Ntilde\":                           true,\n\t\"&Ntilde;\":                          true,\n\t\"&Nu;\":                              true,\n\t\"&OElig;\":                           true,\n\t\"&Oacute\":                           true,\n\t\"&Oacute;\":                          true,\n\t\"&Ocirc\":                            true,\n\t\"&Ocirc;\":                           true,\n\t\"&Ocy;\":                             true,\n\t\"&Odblac;\":                          true,\n\t\"&Ofr;\":                             true,\n\t\"&Ograve\":                           true,\n\t\"&Ograve;\":                          true,\n\t\"&Omacr;\":                           true,\n\t\"&Omega;\":                           true,\n\t\"&Omicron;\":                         true,\n\t\"&Oopf;\":                            true,\n\t\"&OpenCurlyDoubleQuote;\":            true,\n\t\"&OpenCurlyQuote;\":                  true,\n\t\"&Or;\":                              true,\n\t\"&Oscr;\":                            true,\n\t\"&Oslash\":                           true,\n\t\"&Oslash;\":                          true,\n\t\"&Otilde\":                           true,\n\t\"&Otilde;\":                          true,\n\t\"&Otimes;\":                          true,\n\t\"&Ouml\":                             true,\n\t\"&Ouml;\":                            true,\n\t\"&OverBar;\":                         true,\n\t\"&OverBrace;\":                       true,\n\t\"&OverBracket;\":                     true,\n\t\"&OverParenthesis;\":                 true,\n\t\"&PartialD;\":                        true,\n\t\"&Pcy;\":                             true,\n\t\"&Pfr;\":                             true,\n\t\"&Phi;\":                             true,\n\t\"&Pi;\":                              true,\n\t\"&PlusMinus;\":                       true,\n\t\"&Poincareplane;\":                   true,\n\t\"&Popf;\":                            true,\n\t\"&Pr;\":                              true,\n\t\"&Precedes;\":                        true,\n\t\"&PrecedesEqual;\":                   true,\n\t\"&PrecedesSlantEqual;\":              true,\n\t\"&PrecedesTilde;\":                   true,\n\t\"&Prime;\":                           true,\n\t\"&Product;\":                         true,\n\t\"&Proportion;\":                      true,\n\t\"&Proportional;\":                    true,\n\t\"&Pscr;\":                            true,\n\t\"&Psi;\":                             true,\n\t\"&QUOT\":                             true,\n\t\"&QUOT;\":                            true,\n\t\"&Qfr;\":                             true,\n\t\"&Qopf;\":                            true,\n\t\"&Qscr;\":                            true,\n\t\"&RBarr;\":                           true,\n\t\"&REG\":                              true,\n\t\"&REG;\":                             true,\n\t\"&Racute;\":                          true,\n\t\"&Rang;\":                            true,\n\t\"&Rarr;\":                            true,\n\t\"&Rarrtl;\":                          true,\n\t\"&Rcaron;\":                          true,\n\t\"&Rcedil;\":                          true,\n\t\"&Rcy;\":                             true,\n\t\"&Re;\":                              true,\n\t\"&ReverseElement;\":                  true,\n\t\"&ReverseEquilibrium;\":              true,\n\t\"&ReverseUpEquilibrium;\":            true,\n\t\"&Rfr;\":                             true,\n\t\"&Rho;\":                             true,\n\t\"&RightAngleBracket;\":               true,\n\t\"&RightArrow;\":                      true,\n\t\"&RightArrowBar;\":                   true,\n\t\"&RightArrowLeftArrow;\":             true,\n\t\"&RightCeiling;\":                    true,\n\t\"&RightDoubleBracket;\":              true,\n\t\"&RightDownTeeVector;\":              true,\n\t\"&RightDownVector;\":                 true,\n\t\"&RightDownVectorBar;\":              true,\n\t\"&RightFloor;\":                      true,\n\t\"&RightTee;\":                        true,\n\t\"&RightTeeArrow;\":                   true,\n\t\"&RightTeeVector;\":                  true,\n\t\"&RightTriangle;\":                   true,\n\t\"&RightTriangleBar;\":                true,\n\t\"&RightTriangleEqual;\":              true,\n\t\"&RightUpDownVector;\":               true,\n\t\"&RightUpTeeVector;\":                true,\n\t\"&RightUpVector;\":                   true,\n\t\"&RightUpVectorBar;\":                true,\n\t\"&RightVector;\":                     true,\n\t\"&RightVectorBar;\":                  true,\n\t\"&Rightarrow;\":                      true,\n\t\"&Ropf;\":                            true,\n\t\"&RoundImplies;\":                    true,\n\t\"&Rrightarrow;\":                     true,\n\t\"&Rscr;\":                            true,\n\t\"&Rsh;\":                             true,\n\t\"&RuleDelayed;\":                     true,\n\t\"&SHCHcy;\":                          true,\n\t\"&SHcy;\":                            true,\n\t\"&SOFTcy;\":                          true,\n\t\"&Sacute;\":                          true,\n\t\"&Sc;\":                              true,\n\t\"&Scaron;\":                          true,\n\t\"&Scedil;\":                          true,\n\t\"&Scirc;\":                           true,\n\t\"&Scy;\":                             true,\n\t\"&Sfr;\":                             true,\n\t\"&ShortDownArrow;\":                  true,\n\t\"&ShortLeftArrow;\":                  true,\n\t\"&ShortRightArrow;\":                 true,\n\t\"&ShortUpArrow;\":                    true,\n\t\"&Sigma;\":                           true,\n\t\"&SmallCircle;\":                     true,\n\t\"&Sopf;\":                            true,\n\t\"&Sqrt;\":                            true,\n\t\"&Square;\":                          true,\n\t\"&SquareIntersection;\":              true,\n\t\"&SquareSubset;\":                    true,\n\t\"&SquareSubsetEqual;\":               true,\n\t\"&SquareSuperset;\":                  true,\n\t\"&SquareSupersetEqual;\":             true,\n\t\"&SquareUnion;\":                     true,\n\t\"&Sscr;\":                            true,\n\t\"&Star;\":                            true,\n\t\"&Sub;\":                             true,\n\t\"&Subset;\":                          true,\n\t\"&SubsetEqual;\":                     true,\n\t\"&Succeeds;\":                        true,\n\t\"&SucceedsEqual;\":                   true,\n\t\"&SucceedsSlantEqual;\":              true,\n\t\"&SucceedsTilde;\":                   true,\n\t\"&SuchThat;\":                        true,\n\t\"&Sum;\":                             true,\n\t\"&Sup;\":                             true,\n\t\"&Superset;\":                        true,\n\t\"&SupersetEqual;\":                   true,\n\t\"&Supset;\":                          true,\n\t\"&THORN\":                            true,\n\t\"&THORN;\":                           true,\n\t\"&TRADE;\":                           true,\n\t\"&TSHcy;\":                           true,\n\t\"&TScy;\":                            true,\n\t\"&Tab;\":                             true,\n\t\"&Tau;\":                             true,\n\t\"&Tcaron;\":                          true,\n\t\"&Tcedil;\":                          true,\n\t\"&Tcy;\":                             true,\n\t\"&Tfr;\":                             true,\n\t\"&Therefore;\":                       true,\n\t\"&Theta;\":                           true,\n\t\"&ThickSpace;\":                      true,\n\t\"&ThinSpace;\":                       true,\n\t\"&Tilde;\":                           true,\n\t\"&TildeEqual;\":                      true,\n\t\"&TildeFullEqual;\":                  true,\n\t\"&TildeTilde;\":                      true,\n\t\"&Topf;\":                            true,\n\t\"&TripleDot;\":                       true,\n\t\"&Tscr;\":                            true,\n\t\"&Tstrok;\":                          true,\n\t\"&Uacute\":                           true,\n\t\"&Uacute;\":                          true,\n\t\"&Uarr;\":                            true,\n\t\"&Uarrocir;\":                        true,\n\t\"&Ubrcy;\":                           true,\n\t\"&Ubreve;\":                          true,\n\t\"&Ucirc\":                            true,\n\t\"&Ucirc;\":                           true,\n\t\"&Ucy;\":                             true,\n\t\"&Udblac;\":                          true,\n\t\"&Ufr;\":                             true,\n\t\"&Ugrave\":                           true,\n\t\"&Ugrave;\":                          true,\n\t\"&Umacr;\":                           true,\n\t\"&UnderBar;\":                        true,\n\t\"&UnderBrace;\":                      true,\n\t\"&UnderBracket;\":                    true,\n\t\"&UnderParenthesis;\":                true,\n\t\"&Union;\":                           true,\n\t\"&UnionPlus;\":                       true,\n\t\"&Uogon;\":                           true,\n\t\"&Uopf;\":                            true,\n\t\"&UpArrow;\":                         true,\n\t\"&UpArrowBar;\":                      true,\n\t\"&UpArrowDownArrow;\":                true,\n\t\"&UpDownArrow;\":                     true,\n\t\"&UpEquilibrium;\":                   true,\n\t\"&UpTee;\":                           true,\n\t\"&UpTeeArrow;\":                      true,\n\t\"&Uparrow;\":                         true,\n\t\"&Updownarrow;\":                     true,\n\t\"&UpperLeftArrow;\":                  true,\n\t\"&UpperRightArrow;\":                 true,\n\t\"&Upsi;\":                            true,\n\t\"&Upsilon;\":                         true,\n\t\"&Uring;\":                           true,\n\t\"&Uscr;\":                            true,\n\t\"&Utilde;\":                          true,\n\t\"&Uuml\":                             true,\n\t\"&Uuml;\":                            true,\n\t\"&VDash;\":                           true,\n\t\"&Vbar;\":                            true,\n\t\"&Vcy;\":                             true,\n\t\"&Vdash;\":                           true,\n\t\"&Vdashl;\":                          true,\n\t\"&Vee;\":                             true,\n\t\"&Verbar;\":                          true,\n\t\"&Vert;\":                            true,\n\t\"&VerticalBar;\":                     true,\n\t\"&VerticalLine;\":                    true,\n\t\"&VerticalSeparator;\":               true,\n\t\"&VerticalTilde;\":                   true,\n\t\"&VeryThinSpace;\":                   true,\n\t\"&Vfr;\":                             true,\n\t\"&Vopf;\":                            true,\n\t\"&Vscr;\":                            true,\n\t\"&Vvdash;\":                          true,\n\t\"&Wcirc;\":                           true,\n\t\"&Wedge;\":                           true,\n\t\"&Wfr;\":                             true,\n\t\"&Wopf;\":                            true,\n\t\"&Wscr;\":                            true,\n\t\"&Xfr;\":                             true,\n\t\"&Xi;\":                              true,\n\t\"&Xopf;\":                            true,\n\t\"&Xscr;\":                            true,\n\t\"&YAcy;\":                            true,\n\t\"&YIcy;\":                            true,\n\t\"&YUcy;\":                            true,\n\t\"&Yacute\":                           true,\n\t\"&Yacute;\":                          true,\n\t\"&Ycirc;\":                           true,\n\t\"&Ycy;\":                             true,\n\t\"&Yfr;\":                             true,\n\t\"&Yopf;\":                            true,\n\t\"&Yscr;\":                            true,\n\t\"&Yuml;\":                            true,\n\t\"&ZHcy;\":                            true,\n\t\"&Zacute;\":                          true,\n\t\"&Zcaron;\":                          true,\n\t\"&Zcy;\":                             true,\n\t\"&Zdot;\":                            true,\n\t\"&ZeroWidthSpace;\":                  true,\n\t\"&Zeta;\":                            true,\n\t\"&Zfr;\":                             true,\n\t\"&Zopf;\":                            true,\n\t\"&Zscr;\":                            true,\n\t\"&aacute\":                           true,\n\t\"&aacute;\":                          true,\n\t\"&abreve;\":                          true,\n\t\"&ac;\":                              true,\n\t\"&acE;\":                             true,\n\t\"&acd;\":                             true,\n\t\"&acirc\":                            true,\n\t\"&acirc;\":                           true,\n\t\"&acute\":                            true,\n\t\"&acute;\":                           true,\n\t\"&acy;\":                             true,\n\t\"&aelig\":                            true,\n\t\"&aelig;\":                           true,\n\t\"&af;\":                              true,\n\t\"&afr;\":                             true,\n\t\"&agrave\":                           true,\n\t\"&agrave;\":                          true,\n\t\"&alefsym;\":                         true,\n\t\"&aleph;\":                           true,\n\t\"&alpha;\":                           true,\n\t\"&amacr;\":                           true,\n\t\"&amalg;\":                           true,\n\t\"&amp\":                              true,\n\t\"&amp;\":                             true,\n\t\"&and;\":                             true,\n\t\"&andand;\":                          true,\n\t\"&andd;\":                            true,\n\t\"&andslope;\":                        true,\n\t\"&andv;\":                            true,\n\t\"&ang;\":                             true,\n\t\"&ange;\":                            true,\n\t\"&angle;\":                           true,\n\t\"&angmsd;\":                          true,\n\t\"&angmsdaa;\":                        true,\n\t\"&angmsdab;\":                        true,\n\t\"&angmsdac;\":                        true,\n\t\"&angmsdad;\":                        true,\n\t\"&angmsdae;\":                        true,\n\t\"&angmsdaf;\":                        true,\n\t\"&angmsdag;\":                        true,\n\t\"&angmsdah;\":                        true,\n\t\"&angrt;\":                           true,\n\t\"&angrtvb;\":                         true,\n\t\"&angrtvbd;\":                        true,\n\t\"&angsph;\":                          true,\n\t\"&angst;\":                           true,\n\t\"&angzarr;\":                         true,\n\t\"&aogon;\":                           true,\n\t\"&aopf;\":                            true,\n\t\"&ap;\":                              true,\n\t\"&apE;\":                             true,\n\t\"&apacir;\":                          true,\n\t\"&ape;\":                             true,\n\t\"&apid;\":                            true,\n\t\"&apos;\":                            true,\n\t\"&approx;\":                          true,\n\t\"&approxeq;\":                        true,\n\t\"&aring\":                            true,\n\t\"&aring;\":                           true,\n\t\"&ascr;\":                            true,\n\t\"&ast;\":                             true,\n\t\"&asymp;\":                           true,\n\t\"&asympeq;\":                         true,\n\t\"&atilde\":                           true,\n\t\"&atilde;\":                          true,\n\t\"&auml\":                             true,\n\t\"&auml;\":                            true,\n\t\"&awconint;\":                        true,\n\t\"&awint;\":                           true,\n\t\"&bNot;\":                            true,\n\t\"&backcong;\":                        true,\n\t\"&backepsilon;\":                     true,\n\t\"&backprime;\":                       true,\n\t\"&backsim;\":                         true,\n\t\"&backsimeq;\":                       true,\n\t\"&barvee;\":                          true,\n\t\"&barwed;\":                          true,\n\t\"&barwedge;\":                        true,\n\t\"&bbrk;\":                            true,\n\t\"&bbrktbrk;\":                        true,\n\t\"&bcong;\":                           true,\n\t\"&bcy;\":                             true,\n\t\"&bdquo;\":                           true,\n\t\"&becaus;\":                          true,\n\t\"&because;\":                         true,\n\t\"&bemptyv;\":                         true,\n\t\"&bepsi;\":                           true,\n\t\"&bernou;\":                          true,\n\t\"&beta;\":                            true,\n\t\"&beth;\":                            true,\n\t\"&between;\":                         true,\n\t\"&bfr;\":                             true,\n\t\"&bigcap;\":                          true,\n\t\"&bigcirc;\":                         true,\n\t\"&bigcup;\":                          true,\n\t\"&bigodot;\":                         true,\n\t\"&bigoplus;\":                        true,\n\t\"&bigotimes;\":                       true,\n\t\"&bigsqcup;\":                        true,\n\t\"&bigstar;\":                         true,\n\t\"&bigtriangledown;\":                 true,\n\t\"&bigtriangleup;\":                   true,\n\t\"&biguplus;\":                        true,\n\t\"&bigvee;\":                          true,\n\t\"&bigwedge;\":                        true,\n\t\"&bkarow;\":                          true,\n\t\"&blacklozenge;\":                    true,\n\t\"&blacksquare;\":                     true,\n\t\"&blacktriangle;\":                   true,\n\t\"&blacktriangledown;\":               true,\n\t\"&blacktriangleleft;\":               true,\n\t\"&blacktriangleright;\":              true,\n\t\"&blank;\":                           true,\n\t\"&blk12;\":                           true,\n\t\"&blk14;\":                           true,\n\t\"&blk34;\":                           true,\n\t\"&block;\":                           true,\n\t\"&bne;\":                             true,\n\t\"&bnequiv;\":                         true,\n\t\"&bnot;\":                            true,\n\t\"&bopf;\":                            true,\n\t\"&bot;\":                             true,\n\t\"&bottom;\":                          true,\n\t\"&bowtie;\":                          true,\n\t\"&boxDL;\":                           true,\n\t\"&boxDR;\":                           true,\n\t\"&boxDl;\":                           true,\n\t\"&boxDr;\":                           true,\n\t\"&boxH;\":                            true,\n\t\"&boxHD;\":                           true,\n\t\"&boxHU;\":                           true,\n\t\"&boxHd;\":                           true,\n\t\"&boxHu;\":                           true,\n\t\"&boxUL;\":                           true,\n\t\"&boxUR;\":                           true,\n\t\"&boxUl;\":                           true,\n\t\"&boxUr;\":                           true,\n\t\"&boxV;\":                            true,\n\t\"&boxVH;\":                           true,\n\t\"&boxVL;\":                           true,\n\t\"&boxVR;\":                           true,\n\t\"&boxVh;\":                           true,\n\t\"&boxVl;\":                           true,\n\t\"&boxVr;\":                           true,\n\t\"&boxbox;\":                          true,\n\t\"&boxdL;\":                           true,\n\t\"&boxdR;\":                           true,\n\t\"&boxdl;\":                           true,\n\t\"&boxdr;\":                           true,\n\t\"&boxh;\":                            true,\n\t\"&boxhD;\":                           true,\n\t\"&boxhU;\":                           true,\n\t\"&boxhd;\":                           true,\n\t\"&boxhu;\":                           true,\n\t\"&boxminus;\":                        true,\n\t\"&boxplus;\":                         true,\n\t\"&boxtimes;\":                        true,\n\t\"&boxuL;\":                           true,\n\t\"&boxuR;\":                           true,\n\t\"&boxul;\":                           true,\n\t\"&boxur;\":                           true,\n\t\"&boxv;\":                            true,\n\t\"&boxvH;\":                           true,\n\t\"&boxvL;\":                           true,\n\t\"&boxvR;\":                           true,\n\t\"&boxvh;\":                           true,\n\t\"&boxvl;\":                           true,\n\t\"&boxvr;\":                           true,\n\t\"&bprime;\":                          true,\n\t\"&breve;\":                           true,\n\t\"&brvbar\":                           true,\n\t\"&brvbar;\":                          true,\n\t\"&bscr;\":                            true,\n\t\"&bsemi;\":                           true,\n\t\"&bsim;\":                            true,\n\t\"&bsime;\":                           true,\n\t\"&bsol;\":                            true,\n\t\"&bsolb;\":                           true,\n\t\"&bsolhsub;\":                        true,\n\t\"&bull;\":                            true,\n\t\"&bullet;\":                          true,\n\t\"&bump;\":                            true,\n\t\"&bumpE;\":                           true,\n\t\"&bumpe;\":                           true,\n\t\"&bumpeq;\":                          true,\n\t\"&cacute;\":                          true,\n\t\"&cap;\":                             true,\n\t\"&capand;\":                          true,\n\t\"&capbrcup;\":                        true,\n\t\"&capcap;\":                          true,\n\t\"&capcup;\":                          true,\n\t\"&capdot;\":                          true,\n\t\"&caps;\":                            true,\n\t\"&caret;\":                           true,\n\t\"&caron;\":                           true,\n\t\"&ccaps;\":                           true,\n\t\"&ccaron;\":                          true,\n\t\"&ccedil\":                           true,\n\t\"&ccedil;\":                          true,\n\t\"&ccirc;\":                           true,\n\t\"&ccups;\":                           true,\n\t\"&ccupssm;\":                         true,\n\t\"&cdot;\":                            true,\n\t\"&cedil\":                            true,\n\t\"&cedil;\":                           true,\n\t\"&cemptyv;\":                         true,\n\t\"&cent\":                             true,\n\t\"&cent;\":                            true,\n\t\"&centerdot;\":                       true,\n\t\"&cfr;\":                             true,\n\t\"&chcy;\":                            true,\n\t\"&check;\":                           true,\n\t\"&checkmark;\":                       true,\n\t\"&chi;\":                             true,\n\t\"&cir;\":                             true,\n\t\"&cirE;\":                            true,\n\t\"&circ;\":                            true,\n\t\"&circeq;\":                          true,\n\t\"&circlearrowleft;\":                 true,\n\t\"&circlearrowright;\":                true,\n\t\"&circledR;\":                        true,\n\t\"&circledS;\":                        true,\n\t\"&circledast;\":                      true,\n\t\"&circledcirc;\":                     true,\n\t\"&circleddash;\":                     true,\n\t\"&cire;\":                            true,\n\t\"&cirfnint;\":                        true,\n\t\"&cirmid;\":                          true,\n\t\"&cirscir;\":                         true,\n\t\"&clubs;\":                           true,\n\t\"&clubsuit;\":                        true,\n\t\"&colon;\":                           true,\n\t\"&colone;\":                          true,\n\t\"&coloneq;\":                         true,\n\t\"&comma;\":                           true,\n\t\"&commat;\":                          true,\n\t\"&comp;\":                            true,\n\t\"&compfn;\":                          true,\n\t\"&complement;\":                      true,\n\t\"&complexes;\":                       true,\n\t\"&cong;\":                            true,\n\t\"&congdot;\":                         true,\n\t\"&conint;\":                          true,\n\t\"&copf;\":                            true,\n\t\"&coprod;\":                          true,\n\t\"&copy\":                             true,\n\t\"&copy;\":                            true,\n\t\"&copysr;\":                          true,\n\t\"&crarr;\":                           true,\n\t\"&cross;\":                           true,\n\t\"&cscr;\":                            true,\n\t\"&csub;\":                            true,\n\t\"&csube;\":                           true,\n\t\"&csup;\":                            true,\n\t\"&csupe;\":                           true,\n\t\"&ctdot;\":                           true,\n\t\"&cudarrl;\":                         true,\n\t\"&cudarrr;\":                         true,\n\t\"&cuepr;\":                           true,\n\t\"&cuesc;\":                           true,\n\t\"&cularr;\":                          true,\n\t\"&cularrp;\":                         true,\n\t\"&cup;\":                             true,\n\t\"&cupbrcap;\":                        true,\n\t\"&cupcap;\":                          true,\n\t\"&cupcup;\":                          true,\n\t\"&cupdot;\":                          true,\n\t\"&cupor;\":                           true,\n\t\"&cups;\":                            true,\n\t\"&curarr;\":                          true,\n\t\"&curarrm;\":                         true,\n\t\"&curlyeqprec;\":                     true,\n\t\"&curlyeqsucc;\":                     true,\n\t\"&curlyvee;\":                        true,\n\t\"&curlywedge;\":                      true,\n\t\"&curren\":                           true,\n\t\"&curren;\":                          true,\n\t\"&curvearrowleft;\":                  true,\n\t\"&curvearrowright;\":                 true,\n\t\"&cuvee;\":                           true,\n\t\"&cuwed;\":                           true,\n\t\"&cwconint;\":                        true,\n\t\"&cwint;\":                           true,\n\t\"&cylcty;\":                          true,\n\t\"&dArr;\":                            true,\n\t\"&dHar;\":                            true,\n\t\"&dagger;\":                          true,\n\t\"&daleth;\":                          true,\n\t\"&darr;\":                            true,\n\t\"&dash;\":                            true,\n\t\"&dashv;\":                           true,\n\t\"&dbkarow;\":                         true,\n\t\"&dblac;\":                           true,\n\t\"&dcaron;\":                          true,\n\t\"&dcy;\":                             true,\n\t\"&dd;\":                              true,\n\t\"&ddagger;\":                         true,\n\t\"&ddarr;\":                           true,\n\t\"&ddotseq;\":                         true,\n\t\"&deg\":                              true,\n\t\"&deg;\":                             true,\n\t\"&delta;\":                           true,\n\t\"&demptyv;\":                         true,\n\t\"&dfisht;\":                          true,\n\t\"&dfr;\":                             true,\n\t\"&dharl;\":                           true,\n\t\"&dharr;\":                           true,\n\t\"&diam;\":                            true,\n\t\"&diamond;\":                         true,\n\t\"&diamondsuit;\":                     true,\n\t\"&diams;\":                           true,\n\t\"&die;\":                             true,\n\t\"&digamma;\":                         true,\n\t\"&disin;\":                           true,\n\t\"&div;\":                             true,\n\t\"&divide\":                           true,\n\t\"&divide;\":                          true,\n\t\"&divideontimes;\":                   true,\n\t\"&divonx;\":                          true,\n\t\"&djcy;\":                            true,\n\t\"&dlcorn;\":                          true,\n\t\"&dlcrop;\":                          true,\n\t\"&dollar;\":                          true,\n\t\"&dopf;\":                            true,\n\t\"&dot;\":                             true,\n\t\"&doteq;\":                           true,\n\t\"&doteqdot;\":                        true,\n\t\"&dotminus;\":                        true,\n\t\"&dotplus;\":                         true,\n\t\"&dotsquare;\":                       true,\n\t\"&doublebarwedge;\":                  true,\n\t\"&downarrow;\":                       true,\n\t\"&downdownarrows;\":                  true,\n\t\"&downharpoonleft;\":                 true,\n\t\"&downharpoonright;\":                true,\n\t\"&drbkarow;\":                        true,\n\t\"&drcorn;\":                          true,\n\t\"&drcrop;\":                          true,\n\t\"&dscr;\":                            true,\n\t\"&dscy;\":                            true,\n\t\"&dsol;\":                            true,\n\t\"&dstrok;\":                          true,\n\t\"&dtdot;\":                           true,\n\t\"&dtri;\":                            true,\n\t\"&dtrif;\":                           true,\n\t\"&duarr;\":                           true,\n\t\"&duhar;\":                           true,\n\t\"&dwangle;\":                         true,\n\t\"&dzcy;\":                            true,\n\t\"&dzigrarr;\":                        true,\n\t\"&eDDot;\":                           true,\n\t\"&eDot;\":                            true,\n\t\"&eacute\":                           true,\n\t\"&eacute;\":                          true,\n\t\"&easter;\":                          true,\n\t\"&ecaron;\":                          true,\n\t\"&ecir;\":                            true,\n\t\"&ecirc\":                            true,\n\t\"&ecirc;\":                           true,\n\t\"&ecolon;\":                          true,\n\t\"&ecy;\":                             true,\n\t\"&edot;\":                            true,\n\t\"&ee;\":                              true,\n\t\"&efDot;\":                           true,\n\t\"&efr;\":                             true,\n\t\"&eg;\":                              true,\n\t\"&egrave\":                           true,\n\t\"&egrave;\":                          true,\n\t\"&egs;\":                             true,\n\t\"&egsdot;\":                          true,\n\t\"&el;\":                              true,\n\t\"&elinters;\":                        true,\n\t\"&ell;\":                             true,\n\t\"&els;\":                             true,\n\t\"&elsdot;\":                          true,\n\t\"&emacr;\":                           true,\n\t\"&empty;\":                           true,\n\t\"&emptyset;\":                        true,\n\t\"&emptyv;\":                          true,\n\t\"&emsp13;\":                          true,\n\t\"&emsp14;\":                          true,\n\t\"&emsp;\":                            true,\n\t\"&eng;\":                             true,\n\t\"&ensp;\":                            true,\n\t\"&eogon;\":                           true,\n\t\"&eopf;\":                            true,\n\t\"&epar;\":                            true,\n\t\"&eparsl;\":                          true,\n\t\"&eplus;\":                           true,\n\t\"&epsi;\":                            true,\n\t\"&epsilon;\":                         true,\n\t\"&epsiv;\":                           true,\n\t\"&eqcirc;\":                          true,\n\t\"&eqcolon;\":                         true,\n\t\"&eqsim;\":                           true,\n\t\"&eqslantgtr;\":                      true,\n\t\"&eqslantless;\":                     true,\n\t\"&equals;\":                          true,\n\t\"&equest;\":                          true,\n\t\"&equiv;\":                           true,\n\t\"&equivDD;\":                         true,\n\t\"&eqvparsl;\":                        true,\n\t\"&erDot;\":                           true,\n\t\"&erarr;\":                           true,\n\t\"&escr;\":                            true,\n\t\"&esdot;\":                           true,\n\t\"&esim;\":                            true,\n\t\"&eta;\":                             true,\n\t\"&eth\":                              true,\n\t\"&eth;\":                             true,\n\t\"&euml\":                             true,\n\t\"&euml;\":                            true,\n\t\"&euro;\":                            true,\n\t\"&excl;\":                            true,\n\t\"&exist;\":                           true,\n\t\"&expectation;\":                     true,\n\t\"&exponentiale;\":                    true,\n\t\"&fallingdotseq;\":                   true,\n\t\"&fcy;\":                             true,\n\t\"&female;\":                          true,\n\t\"&ffilig;\":                          true,\n\t\"&fflig;\":                           true,\n\t\"&ffllig;\":                          true,\n\t\"&ffr;\":                             true,\n\t\"&filig;\":                           true,\n\t\"&fjlig;\":                           true,\n\t\"&flat;\":                            true,\n\t\"&fllig;\":                           true,\n\t\"&fltns;\":                           true,\n\t\"&fnof;\":                            true,\n\t\"&fopf;\":                            true,\n\t\"&forall;\":                          true,\n\t\"&fork;\":                            true,\n\t\"&forkv;\":                           true,\n\t\"&fpartint;\":                        true,\n\t\"&frac12\":                           true,\n\t\"&frac12;\":                          true,\n\t\"&frac13;\":                          true,\n\t\"&frac14\":                           true,\n\t\"&frac14;\":                          true,\n\t\"&frac15;\":                          true,\n\t\"&frac16;\":                          true,\n\t\"&frac18;\":                          true,\n\t\"&frac23;\":                          true,\n\t\"&frac25;\":                          true,\n\t\"&frac34\":                           true,\n\t\"&frac34;\":                          true,\n\t\"&frac35;\":                          true,\n\t\"&frac38;\":                          true,\n\t\"&frac45;\":                          true,\n\t\"&frac56;\":                          true,\n\t\"&frac58;\":                          true,\n\t\"&frac78;\":                          true,\n\t\"&frasl;\":                           true,\n\t\"&frown;\":                           true,\n\t\"&fscr;\":                            true,\n\t\"&gE;\":                              true,\n\t\"&gEl;\":                             true,\n\t\"&gacute;\":                          true,\n\t\"&gamma;\":                           true,\n\t\"&gammad;\":                          true,\n\t\"&gap;\":                             true,\n\t\"&gbreve;\":                          true,\n\t\"&gcirc;\":                           true,\n\t\"&gcy;\":                             true,\n\t\"&gdot;\":                            true,\n\t\"&ge;\":                              true,\n\t\"&gel;\":                             true,\n\t\"&geq;\":                             true,\n\t\"&geqq;\":                            true,\n\t\"&geqslant;\":                        true,\n\t\"&ges;\":                             true,\n\t\"&gescc;\":                           true,\n\t\"&gesdot;\":                          true,\n\t\"&gesdoto;\":                         true,\n\t\"&gesdotol;\":                        true,\n\t\"&gesl;\":                            true,\n\t\"&gesles;\":                          true,\n\t\"&gfr;\":                             true,\n\t\"&gg;\":                              true,\n\t\"&ggg;\":                             true,\n\t\"&gimel;\":                           true,\n\t\"&gjcy;\":                            true,\n\t\"&gl;\":                              true,\n\t\"&glE;\":                             true,\n\t\"&gla;\":                             true,\n\t\"&glj;\":                             true,\n\t\"&gnE;\":                             true,\n\t\"&gnap;\":                            true,\n\t\"&gnapprox;\":                        true,\n\t\"&gne;\":                             true,\n\t\"&gneq;\":                            true,\n\t\"&gneqq;\":                           true,\n\t\"&gnsim;\":                           true,\n\t\"&gopf;\":                            true,\n\t\"&grave;\":                           true,\n\t\"&gscr;\":                            true,\n\t\"&gsim;\":                            true,\n\t\"&gsime;\":                           true,\n\t\"&gsiml;\":                           true,\n\t\"&gt\":                               true,\n\t\"&gt;\":                              true,\n\t\"&gtcc;\":                            true,\n\t\"&gtcir;\":                           true,\n\t\"&gtdot;\":                           true,\n\t\"&gtlPar;\":                          true,\n\t\"&gtquest;\":                         true,\n\t\"&gtrapprox;\":                       true,\n\t\"&gtrarr;\":                          true,\n\t\"&gtrdot;\":                          true,\n\t\"&gtreqless;\":                       true,\n\t\"&gtreqqless;\":                      true,\n\t\"&gtrless;\":                         true,\n\t\"&gtrsim;\":                          true,\n\t\"&gvertneqq;\":                       true,\n\t\"&gvnE;\":                            true,\n\t\"&hArr;\":                            true,\n\t\"&hairsp;\":                          true,\n\t\"&half;\":                            true,\n\t\"&hamilt;\":                          true,\n\t\"&hardcy;\":                          true,\n\t\"&harr;\":                            true,\n\t\"&harrcir;\":                         true,\n\t\"&harrw;\":                           true,\n\t\"&hbar;\":                            true,\n\t\"&hcirc;\":                           true,\n\t\"&hearts;\":                          true,\n\t\"&heartsuit;\":                       true,\n\t\"&hellip;\":                          true,\n\t\"&hercon;\":                          true,\n\t\"&hfr;\":                             true,\n\t\"&hksearow;\":                        true,\n\t\"&hkswarow;\":                        true,\n\t\"&hoarr;\":                           true,\n\t\"&homtht;\":                          true,\n\t\"&hookleftarrow;\":                   true,\n\t\"&hookrightarrow;\":                  true,\n\t\"&hopf;\":                            true,\n\t\"&horbar;\":                          true,\n\t\"&hscr;\":                            true,\n\t\"&hslash;\":                          true,\n\t\"&hstrok;\":                          true,\n\t\"&hybull;\":                          true,\n\t\"&hyphen;\":                          true,\n\t\"&iacute\":                           true,\n\t\"&iacute;\":                          true,\n\t\"&ic;\":                              true,\n\t\"&icirc\":                            true,\n\t\"&icirc;\":                           true,\n\t\"&icy;\":                             true,\n\t\"&iecy;\":                            true,\n\t\"&iexcl\":                            true,\n\t\"&iexcl;\":                           true,\n\t\"&iff;\":                             true,\n\t\"&ifr;\":                             true,\n\t\"&igrave\":                           true,\n\t\"&igrave;\":                          true,\n\t\"&ii;\":                              true,\n\t\"&iiiint;\":                          true,\n\t\"&iiint;\":                           true,\n\t\"&iinfin;\":                          true,\n\t\"&iiota;\":                           true,\n\t\"&ijlig;\":                           true,\n\t\"&imacr;\":                           true,\n\t\"&image;\":                           true,\n\t\"&imagline;\":                        true,\n\t\"&imagpart;\":                        true,\n\t\"&imath;\":                           true,\n\t\"&imof;\":                            true,\n\t\"&imped;\":                           true,\n\t\"&in;\":                              true,\n\t\"&incare;\":                          true,\n\t\"&infin;\":                           true,\n\t\"&infintie;\":                        true,\n\t\"&inodot;\":                          true,\n\t\"&int;\":                             true,\n\t\"&intcal;\":                          true,\n\t\"&integers;\":                        true,\n\t\"&intercal;\":                        true,\n\t\"&intlarhk;\":                        true,\n\t\"&intprod;\":                         true,\n\t\"&iocy;\":                            true,\n\t\"&iogon;\":                           true,\n\t\"&iopf;\":                            true,\n\t\"&iota;\":                            true,\n\t\"&iprod;\":                           true,\n\t\"&iquest\":                           true,\n\t\"&iquest;\":                          true,\n\t\"&iscr;\":                            true,\n\t\"&isin;\":                            true,\n\t\"&isinE;\":                           true,\n\t\"&isindot;\":                         true,\n\t\"&isins;\":                           true,\n\t\"&isinsv;\":                          true,\n\t\"&isinv;\":                           true,\n\t\"&it;\":                              true,\n\t\"&itilde;\":                          true,\n\t\"&iukcy;\":                           true,\n\t\"&iuml\":                             true,\n\t\"&iuml;\":                            true,\n\t\"&jcirc;\":                           true,\n\t\"&jcy;\":                             true,\n\t\"&jfr;\":                             true,\n\t\"&jmath;\":                           true,\n\t\"&jopf;\":                            true,\n\t\"&jscr;\":                            true,\n\t\"&jsercy;\":                          true,\n\t\"&jukcy;\":                           true,\n\t\"&kappa;\":                           true,\n\t\"&kappav;\":                          true,\n\t\"&kcedil;\":                          true,\n\t\"&kcy;\":                             true,\n\t\"&kfr;\":                             true,\n\t\"&kgreen;\":                          true,\n\t\"&khcy;\":                            true,\n\t\"&kjcy;\":                            true,\n\t\"&kopf;\":                            true,\n\t\"&kscr;\":                            true,\n\t\"&lAarr;\":                           true,\n\t\"&lArr;\":                            true,\n\t\"&lAtail;\":                          true,\n\t\"&lBarr;\":                           true,\n\t\"&lE;\":                              true,\n\t\"&lEg;\":                             true,\n\t\"&lHar;\":                            true,\n\t\"&lacute;\":                          true,\n\t\"&laemptyv;\":                        true,\n\t\"&lagran;\":                          true,\n\t\"&lambda;\":                          true,\n\t\"&lang;\":                            true,\n\t\"&langd;\":                           true,\n\t\"&langle;\":                          true,\n\t\"&lap;\":                             true,\n\t\"&laquo\":                            true,\n\t\"&laquo;\":                           true,\n\t\"&larr;\":                            true,\n\t\"&larrb;\":                           true,\n\t\"&larrbfs;\":                         true,\n\t\"&larrfs;\":                          true,\n\t\"&larrhk;\":                          true,\n\t\"&larrlp;\":                          true,\n\t\"&larrpl;\":                          true,\n\t\"&larrsim;\":                         true,\n\t\"&larrtl;\":                          true,\n\t\"&lat;\":                             true,\n\t\"&latail;\":                          true,\n\t\"&late;\":                            true,\n\t\"&lates;\":                           true,\n\t\"&lbarr;\":                           true,\n\t\"&lbbrk;\":                           true,\n\t\"&lbrace;\":                          true,\n\t\"&lbrack;\":                          true,\n\t\"&lbrke;\":                           true,\n\t\"&lbrksld;\":                         true,\n\t\"&lbrkslu;\":                         true,\n\t\"&lcaron;\":                          true,\n\t\"&lcedil;\":                          true,\n\t\"&lceil;\":                           true,\n\t\"&lcub;\":                            true,\n\t\"&lcy;\":                             true,\n\t\"&ldca;\":                            true,\n\t\"&ldquo;\":                           true,\n\t\"&ldquor;\":                          true,\n\t\"&ldrdhar;\":                         true,\n\t\"&ldrushar;\":                        true,\n\t\"&ldsh;\":                            true,\n\t\"&le;\":                              true,\n\t\"&leftarrow;\":                       true,\n\t\"&leftarrowtail;\":                   true,\n\t\"&leftharpoondown;\":                 true,\n\t\"&leftharpoonup;\":                   true,\n\t\"&leftleftarrows;\":                  true,\n\t\"&leftrightarrow;\":                  true,\n\t\"&leftrightarrows;\":                 true,\n\t\"&leftrightharpoons;\":               true,\n\t\"&leftrightsquigarrow;\":             true,\n\t\"&leftthreetimes;\":                  true,\n\t\"&leg;\":                             true,\n\t\"&leq;\":                             true,\n\t\"&leqq;\":                            true,\n\t\"&leqslant;\":                        true,\n\t\"&les;\":                             true,\n\t\"&lescc;\":                           true,\n\t\"&lesdot;\":                          true,\n\t\"&lesdoto;\":                         true,\n\t\"&lesdotor;\":                        true,\n\t\"&lesg;\":                            true,\n\t\"&lesges;\":                          true,\n\t\"&lessapprox;\":                      true,\n\t\"&lessdot;\":                         true,\n\t\"&lesseqgtr;\":                       true,\n\t\"&lesseqqgtr;\":                      true,\n\t\"&lessgtr;\":                         true,\n\t\"&lesssim;\":                         true,\n\t\"&lfisht;\":                          true,\n\t\"&lfloor;\":                          true,\n\t\"&lfr;\":                             true,\n\t\"&lg;\":                              true,\n\t\"&lgE;\":                             true,\n\t\"&lhard;\":                           true,\n\t\"&lharu;\":                           true,\n\t\"&lharul;\":                          true,\n\t\"&lhblk;\":                           true,\n\t\"&ljcy;\":                            true,\n\t\"&ll;\":                              true,\n\t\"&llarr;\":                           true,\n\t\"&llcorner;\":                        true,\n\t\"&llhard;\":                          true,\n\t\"&lltri;\":                           true,\n\t\"&lmidot;\":                          true,\n\t\"&lmoust;\":                          true,\n\t\"&lmoustache;\":                      true,\n\t\"&lnE;\":                             true,\n\t\"&lnap;\":                            true,\n\t\"&lnapprox;\":                        true,\n\t\"&lne;\":                             true,\n\t\"&lneq;\":                            true,\n\t\"&lneqq;\":                           true,\n\t\"&lnsim;\":                           true,\n\t\"&loang;\":                           true,\n\t\"&loarr;\":                           true,\n\t\"&lobrk;\":                           true,\n\t\"&longleftarrow;\":                   true,\n\t\"&longleftrightarrow;\":              true,\n\t\"&longmapsto;\":                      true,\n\t\"&longrightarrow;\":                  true,\n\t\"&looparrowleft;\":                   true,\n\t\"&looparrowright;\":                  true,\n\t\"&lopar;\":                           true,\n\t\"&lopf;\":                            true,\n\t\"&loplus;\":                          true,\n\t\"&lotimes;\":                         true,\n\t\"&lowast;\":                          true,\n\t\"&lowbar;\":                          true,\n\t\"&loz;\":                             true,\n\t\"&lozenge;\":                         true,\n\t\"&lozf;\":                            true,\n\t\"&lpar;\":                            true,\n\t\"&lparlt;\":                          true,\n\t\"&lrarr;\":                           true,\n\t\"&lrcorner;\":                        true,\n\t\"&lrhar;\":                           true,\n\t\"&lrhard;\":                          true,\n\t\"&lrm;\":                             true,\n\t\"&lrtri;\":                           true,\n\t\"&lsaquo;\":                          true,\n\t\"&lscr;\":                            true,\n\t\"&lsh;\":                             true,\n\t\"&lsim;\":                            true,\n\t\"&lsime;\":                           true,\n\t\"&lsimg;\":                           true,\n\t\"&lsqb;\":                            true,\n\t\"&lsquo;\":                           true,\n\t\"&lsquor;\":                          true,\n\t\"&lstrok;\":                          true,\n\t\"&lt\":                               true,\n\t\"&lt;\":                              true,\n\t\"&ltcc;\":                            true,\n\t\"&ltcir;\":                           true,\n\t\"&ltdot;\":                           true,\n\t\"&lthree;\":                          true,\n\t\"&ltimes;\":                          true,\n\t\"&ltlarr;\":                          true,\n\t\"&ltquest;\":                         true,\n\t\"&ltrPar;\":                          true,\n\t\"&ltri;\":                            true,\n\t\"&ltrie;\":                           true,\n\t\"&ltrif;\":                           true,\n\t\"&lurdshar;\":                        true,\n\t\"&luruhar;\":                         true,\n\t\"&lvertneqq;\":                       true,\n\t\"&lvnE;\":                            true,\n\t\"&mDDot;\":                           true,\n\t\"&macr\":                             true,\n\t\"&macr;\":                            true,\n\t\"&male;\":                            true,\n\t\"&malt;\":                            true,\n\t\"&maltese;\":                         true,\n\t\"&map;\":                             true,\n\t\"&mapsto;\":                          true,\n\t\"&mapstodown;\":                      true,\n\t\"&mapstoleft;\":                      true,\n\t\"&mapstoup;\":                        true,\n\t\"&marker;\":                          true,\n\t\"&mcomma;\":                          true,\n\t\"&mcy;\":                             true,\n\t\"&mdash;\":                           true,\n\t\"&measuredangle;\":                   true,\n\t\"&mfr;\":                             true,\n\t\"&mho;\":                             true,\n\t\"&micro\":                            true,\n\t\"&micro;\":                           true,\n\t\"&mid;\":                             true,\n\t\"&midast;\":                          true,\n\t\"&midcir;\":                          true,\n\t\"&middot\":                           true,\n\t\"&middot;\":                          true,\n\t\"&minus;\":                           true,\n\t\"&minusb;\":                          true,\n\t\"&minusd;\":                          true,\n\t\"&minusdu;\":                         true,\n\t\"&mlcp;\":                            true,\n\t\"&mldr;\":                            true,\n\t\"&mnplus;\":                          true,\n\t\"&models;\":                          true,\n\t\"&mopf;\":                            true,\n\t\"&mp;\":                              true,\n\t\"&mscr;\":                            true,\n\t\"&mstpos;\":                          true,\n\t\"&mu;\":                              true,\n\t\"&multimap;\":                        true,\n\t\"&mumap;\":                           true,\n\t\"&nGg;\":                             true,\n\t\"&nGt;\":                             true,\n\t\"&nGtv;\":                            true,\n\t\"&nLeftarrow;\":                      true,\n\t\"&nLeftrightarrow;\":                 true,\n\t\"&nLl;\":                             true,\n\t\"&nLt;\":                             true,\n\t\"&nLtv;\":                            true,\n\t\"&nRightarrow;\":                     true,\n\t\"&nVDash;\":                          true,\n\t\"&nVdash;\":                          true,\n\t\"&nabla;\":                           true,\n\t\"&nacute;\":                          true,\n\t\"&nang;\":                            true,\n\t\"&nap;\":                             true,\n\t\"&napE;\":                            true,\n\t\"&napid;\":                           true,\n\t\"&napos;\":                           true,\n\t\"&napprox;\":                         true,\n\t\"&natur;\":                           true,\n\t\"&natural;\":                         true,\n\t\"&naturals;\":                        true,\n\t\"&nbsp\":                             true,\n\t\"&nbsp;\":                            true,\n\t\"&nbump;\":                           true,\n\t\"&nbumpe;\":                          true,\n\t\"&ncap;\":                            true,\n\t\"&ncaron;\":                          true,\n\t\"&ncedil;\":                          true,\n\t\"&ncong;\":                           true,\n\t\"&ncongdot;\":                        true,\n\t\"&ncup;\":                            true,\n\t\"&ncy;\":                             true,\n\t\"&ndash;\":                           true,\n\t\"&ne;\":                              true,\n\t\"&neArr;\":                           true,\n\t\"&nearhk;\":                          true,\n\t\"&nearr;\":                           true,\n\t\"&nearrow;\":                         true,\n\t\"&nedot;\":                           true,\n\t\"&nequiv;\":                          true,\n\t\"&nesear;\":                          true,\n\t\"&nesim;\":                           true,\n\t\"&nexist;\":                          true,\n\t\"&nexists;\":                         true,\n\t\"&nfr;\":                             true,\n\t\"&ngE;\":                             true,\n\t\"&nge;\":                             true,\n\t\"&ngeq;\":                            true,\n\t\"&ngeqq;\":                           true,\n\t\"&ngeqslant;\":                       true,\n\t\"&nges;\":                            true,\n\t\"&ngsim;\":                           true,\n\t\"&ngt;\":                             true,\n\t\"&ngtr;\":                            true,\n\t\"&nhArr;\":                           true,\n\t\"&nharr;\":                           true,\n\t\"&nhpar;\":                           true,\n\t\"&ni;\":                              true,\n\t\"&nis;\":                             true,\n\t\"&nisd;\":                            true,\n\t\"&niv;\":                             true,\n\t\"&njcy;\":                            true,\n\t\"&nlArr;\":                           true,\n\t\"&nlE;\":                             true,\n\t\"&nlarr;\":                           true,\n\t\"&nldr;\":                            true,\n\t\"&nle;\":                             true,\n\t\"&nleftarrow;\":                      true,\n\t\"&nleftrightarrow;\":                 true,\n\t\"&nleq;\":                            true,\n\t\"&nleqq;\":                           true,\n\t\"&nleqslant;\":                       true,\n\t\"&nles;\":                            true,\n\t\"&nless;\":                           true,\n\t\"&nlsim;\":                           true,\n\t\"&nlt;\":                             true,\n\t\"&nltri;\":                           true,\n\t\"&nltrie;\":                          true,\n\t\"&nmid;\":                            true,\n\t\"&nopf;\":                            true,\n\t\"&not\":                              true,\n\t\"&not;\":                             true,\n\t\"&notin;\":                           true,\n\t\"&notinE;\":                          true,\n\t\"&notindot;\":                        true,\n\t\"&notinva;\":                         true,\n\t\"&notinvb;\":                         true,\n\t\"&notinvc;\":                         true,\n\t\"&notni;\":                           true,\n\t\"&notniva;\":                         true,\n\t\"&notnivb;\":                         true,\n\t\"&notnivc;\":                         true,\n\t\"&npar;\":                            true,\n\t\"&nparallel;\":                       true,\n\t\"&nparsl;\":                          true,\n\t\"&npart;\":                           true,\n\t\"&npolint;\":                         true,\n\t\"&npr;\":                             true,\n\t\"&nprcue;\":                          true,\n\t\"&npre;\":                            true,\n\t\"&nprec;\":                           true,\n\t\"&npreceq;\":                         true,\n\t\"&nrArr;\":                           true,\n\t\"&nrarr;\":                           true,\n\t\"&nrarrc;\":                          true,\n\t\"&nrarrw;\":                          true,\n\t\"&nrightarrow;\":                     true,\n\t\"&nrtri;\":                           true,\n\t\"&nrtrie;\":                          true,\n\t\"&nsc;\":                             true,\n\t\"&nsccue;\":                          true,\n\t\"&nsce;\":                            true,\n\t\"&nscr;\":                            true,\n\t\"&nshortmid;\":                       true,\n\t\"&nshortparallel;\":                  true,\n\t\"&nsim;\":                            true,\n\t\"&nsime;\":                           true,\n\t\"&nsimeq;\":                          true,\n\t\"&nsmid;\":                           true,\n\t\"&nspar;\":                           true,\n\t\"&nsqsube;\":                         true,\n\t\"&nsqsupe;\":                         true,\n\t\"&nsub;\":                            true,\n\t\"&nsubE;\":                           true,\n\t\"&nsube;\":                           true,\n\t\"&nsubset;\":                         true,\n\t\"&nsubseteq;\":                       true,\n\t\"&nsubseteqq;\":                      true,\n\t\"&nsucc;\":                           true,\n\t\"&nsucceq;\":                         true,\n\t\"&nsup;\":                            true,\n\t\"&nsupE;\":                           true,\n\t\"&nsupe;\":                           true,\n\t\"&nsupset;\":                         true,\n\t\"&nsupseteq;\":                       true,\n\t\"&nsupseteqq;\":                      true,\n\t\"&ntgl;\":                            true,\n\t\"&ntilde\":                           true,\n\t\"&ntilde;\":                          true,\n\t\"&ntlg;\":                            true,\n\t\"&ntriangleleft;\":                   true,\n\t\"&ntrianglelefteq;\":                 true,\n\t\"&ntriangleright;\":                  true,\n\t\"&ntrianglerighteq;\":                true,\n\t\"&nu;\":                              true,\n\t\"&num;\":                             true,\n\t\"&numero;\":                          true,\n\t\"&numsp;\":                           true,\n\t\"&nvDash;\":                          true,\n\t\"&nvHarr;\":                          true,\n\t\"&nvap;\":                            true,\n\t\"&nvdash;\":                          true,\n\t\"&nvge;\":                            true,\n\t\"&nvgt;\":                            true,\n\t\"&nvinfin;\":                         true,\n\t\"&nvlArr;\":                          true,\n\t\"&nvle;\":                            true,\n\t\"&nvlt;\":                            true,\n\t\"&nvltrie;\":                         true,\n\t\"&nvrArr;\":                          true,\n\t\"&nvrtrie;\":                         true,\n\t\"&nvsim;\":                           true,\n\t\"&nwArr;\":                           true,\n\t\"&nwarhk;\":                          true,\n\t\"&nwarr;\":                           true,\n\t\"&nwarrow;\":                         true,\n\t\"&nwnear;\":                          true,\n\t\"&oS;\":                              true,\n\t\"&oacute\":                           true,\n\t\"&oacute;\":                          true,\n\t\"&oast;\":                            true,\n\t\"&ocir;\":                            true,\n\t\"&ocirc\":                            true,\n\t\"&ocirc;\":                           true,\n\t\"&ocy;\":                             true,\n\t\"&odash;\":                           true,\n\t\"&odblac;\":                          true,\n\t\"&odiv;\":                            true,\n\t\"&odot;\":                            true,\n\t\"&odsold;\":                          true,\n\t\"&oelig;\":                           true,\n\t\"&ofcir;\":                           true,\n\t\"&ofr;\":                             true,\n\t\"&ogon;\":                            true,\n\t\"&ograve\":                           true,\n\t\"&ograve;\":                          true,\n\t\"&ogt;\":                             true,\n\t\"&ohbar;\":                           true,\n\t\"&ohm;\":                             true,\n\t\"&oint;\":                            true,\n\t\"&olarr;\":                           true,\n\t\"&olcir;\":                           true,\n\t\"&olcross;\":                         true,\n\t\"&oline;\":                           true,\n\t\"&olt;\":                             true,\n\t\"&omacr;\":                           true,\n\t\"&omega;\":                           true,\n\t\"&omicron;\":                         true,\n\t\"&omid;\":                            true,\n\t\"&ominus;\":                          true,\n\t\"&oopf;\":                            true,\n\t\"&opar;\":                            true,\n\t\"&operp;\":                           true,\n\t\"&oplus;\":                           true,\n\t\"&or;\":                              true,\n\t\"&orarr;\":                           true,\n\t\"&ord;\":                             true,\n\t\"&order;\":                           true,\n\t\"&orderof;\":                         true,\n\t\"&ordf\":                             true,\n\t\"&ordf;\":                            true,\n\t\"&ordm\":                             true,\n\t\"&ordm;\":                            true,\n\t\"&origof;\":                          true,\n\t\"&oror;\":                            true,\n\t\"&orslope;\":                         true,\n\t\"&orv;\":                             true,\n\t\"&oscr;\":                            true,\n\t\"&oslash\":                           true,\n\t\"&oslash;\":                          true,\n\t\"&osol;\":                            true,\n\t\"&otilde\":                           true,\n\t\"&otilde;\":                          true,\n\t\"&otimes;\":                          true,\n\t\"&otimesas;\":                        true,\n\t\"&ouml\":                             true,\n\t\"&ouml;\":                            true,\n\t\"&ovbar;\":                           true,\n\t\"&par;\":                             true,\n\t\"&para\":                             true,\n\t\"&para;\":                            true,\n\t\"&parallel;\":                        true,\n\t\"&parsim;\":                          true,\n\t\"&parsl;\":                           true,\n\t\"&part;\":                            true,\n\t\"&pcy;\":                             true,\n\t\"&percnt;\":                          true,\n\t\"&period;\":                          true,\n\t\"&permil;\":                          true,\n\t\"&perp;\":                            true,\n\t\"&pertenk;\":                         true,\n\t\"&pfr;\":                             true,\n\t\"&phi;\":                             true,\n\t\"&phiv;\":                            true,\n\t\"&phmmat;\":                          true,\n\t\"&phone;\":                           true,\n\t\"&pi;\":                              true,\n\t\"&pitchfork;\":                       true,\n\t\"&piv;\":                             true,\n\t\"&planck;\":                          true,\n\t\"&planckh;\":                         true,\n\t\"&plankv;\":                          true,\n\t\"&plus;\":                            true,\n\t\"&plusacir;\":                        true,\n\t\"&plusb;\":                           true,\n\t\"&pluscir;\":                         true,\n\t\"&plusdo;\":                          true,\n\t\"&plusdu;\":                          true,\n\t\"&pluse;\":                           true,\n\t\"&plusmn\":                           true,\n\t\"&plusmn;\":                          true,\n\t\"&plussim;\":                         true,\n\t\"&plustwo;\":                         true,\n\t\"&pm;\":                              true,\n\t\"&pointint;\":                        true,\n\t\"&popf;\":                            true,\n\t\"&pound\":                            true,\n\t\"&pound;\":                           true,\n\t\"&pr;\":                              true,\n\t\"&prE;\":                             true,\n\t\"&prap;\":                            true,\n\t\"&prcue;\":                           true,\n\t\"&pre;\":                             true,\n\t\"&prec;\":                            true,\n\t\"&precapprox;\":                      true,\n\t\"&preccurlyeq;\":                     true,\n\t\"&preceq;\":                          true,\n\t\"&precnapprox;\":                     true,\n\t\"&precneqq;\":                        true,\n\t\"&precnsim;\":                        true,\n\t\"&precsim;\":                         true,\n\t\"&prime;\":                           true,\n\t\"&primes;\":                          true,\n\t\"&prnE;\":                            true,\n\t\"&prnap;\":                           true,\n\t\"&prnsim;\":                          true,\n\t\"&prod;\":                            true,\n\t\"&profalar;\":                        true,\n\t\"&profline;\":                        true,\n\t\"&profsurf;\":                        true,\n\t\"&prop;\":                            true,\n\t\"&propto;\":                          true,\n\t\"&prsim;\":                           true,\n\t\"&prurel;\":                          true,\n\t\"&pscr;\":                            true,\n\t\"&psi;\":                             true,\n\t\"&puncsp;\":                          true,\n\t\"&qfr;\":                             true,\n\t\"&qint;\":                            true,\n\t\"&qopf;\":                            true,\n\t\"&qprime;\":                          true,\n\t\"&qscr;\":                            true,\n\t\"&quaternions;\":                     true,\n\t\"&quatint;\":                         true,\n\t\"&quest;\":                           true,\n\t\"&questeq;\":                         true,\n\t\"&quot\":                             true,\n\t\"&quot;\":                            true,\n\t\"&rAarr;\":                           true,\n\t\"&rArr;\":                            true,\n\t\"&rAtail;\":                          true,\n\t\"&rBarr;\":                           true,\n\t\"&rHar;\":                            true,\n\t\"&race;\":                            true,\n\t\"&racute;\":                          true,\n\t\"&radic;\":                           true,\n\t\"&raemptyv;\":                        true,\n\t\"&rang;\":                            true,\n\t\"&rangd;\":                           true,\n\t\"&range;\":                           true,\n\t\"&rangle;\":                          true,\n\t\"&raquo\":                            true,\n\t\"&raquo;\":                           true,\n\t\"&rarr;\":                            true,\n\t\"&rarrap;\":                          true,\n\t\"&rarrb;\":                           true,\n\t\"&rarrbfs;\":                         true,\n\t\"&rarrc;\":                           true,\n\t\"&rarrfs;\":                          true,\n\t\"&rarrhk;\":                          true,\n\t\"&rarrlp;\":                          true,\n\t\"&rarrpl;\":                          true,\n\t\"&rarrsim;\":                         true,\n\t\"&rarrtl;\":                          true,\n\t\"&rarrw;\":                           true,\n\t\"&ratail;\":                          true,\n\t\"&ratio;\":                           true,\n\t\"&rationals;\":                       true,\n\t\"&rbarr;\":                           true,\n\t\"&rbbrk;\":                           true,\n\t\"&rbrace;\":                          true,\n\t\"&rbrack;\":                          true,\n\t\"&rbrke;\":                           true,\n\t\"&rbrksld;\":                         true,\n\t\"&rbrkslu;\":                         true,\n\t\"&rcaron;\":                          true,\n\t\"&rcedil;\":                          true,\n\t\"&rceil;\":                           true,\n\t\"&rcub;\":                            true,\n\t\"&rcy;\":                             true,\n\t\"&rdca;\":                            true,\n\t\"&rdldhar;\":                         true,\n\t\"&rdquo;\":                           true,\n\t\"&rdquor;\":                          true,\n\t\"&rdsh;\":                            true,\n\t\"&real;\":                            true,\n\t\"&realine;\":                         true,\n\t\"&realpart;\":                        true,\n\t\"&reals;\":                           true,\n\t\"&rect;\":                            true,\n\t\"&reg\":                              true,\n\t\"&reg;\":                             true,\n\t\"&rfisht;\":                          true,\n\t\"&rfloor;\":                          true,\n\t\"&rfr;\":                             true,\n\t\"&rhard;\":                           true,\n\t\"&rharu;\":                           true,\n\t\"&rharul;\":                          true,\n\t\"&rho;\":                             true,\n\t\"&rhov;\":                            true,\n\t\"&rightarrow;\":                      true,\n\t\"&rightarrowtail;\":                  true,\n\t\"&rightharpoondown;\":                true,\n\t\"&rightharpoonup;\":                  true,\n\t\"&rightleftarrows;\":                 true,\n\t\"&rightleftharpoons;\":               true,\n\t\"&rightrightarrows;\":                true,\n\t\"&rightsquigarrow;\":                 true,\n\t\"&rightthreetimes;\":                 true,\n\t\"&ring;\":                            true,\n\t\"&risingdotseq;\":                    true,\n\t\"&rlarr;\":                           true,\n\t\"&rlhar;\":                           true,\n\t\"&rlm;\":                             true,\n\t\"&rmoust;\":                          true,\n\t\"&rmoustache;\":                      true,\n\t\"&rnmid;\":                           true,\n\t\"&roang;\":                           true,\n\t\"&roarr;\":                           true,\n\t\"&robrk;\":                           true,\n\t\"&ropar;\":                           true,\n\t\"&ropf;\":                            true,\n\t\"&roplus;\":                          true,\n\t\"&rotimes;\":                         true,\n\t\"&rpar;\":                            true,\n\t\"&rpargt;\":                          true,\n\t\"&rppolint;\":                        true,\n\t\"&rrarr;\":                           true,\n\t\"&rsaquo;\":                          true,\n\t\"&rscr;\":                            true,\n\t\"&rsh;\":                             true,\n\t\"&rsqb;\":                            true,\n\t\"&rsquo;\":                           true,\n\t\"&rsquor;\":                          true,\n\t\"&rthree;\":                          true,\n\t\"&rtimes;\":                          true,\n\t\"&rtri;\":                            true,\n\t\"&rtrie;\":                           true,\n\t\"&rtrif;\":                           true,\n\t\"&rtriltri;\":                        true,\n\t\"&ruluhar;\":                         true,\n\t\"&rx;\":                              true,\n\t\"&sacute;\":                          true,\n\t\"&sbquo;\":                           true,\n\t\"&sc;\":                              true,\n\t\"&scE;\":                             true,\n\t\"&scap;\":                            true,\n\t\"&scaron;\":                          true,\n\t\"&sccue;\":                           true,\n\t\"&sce;\":                             true,\n\t\"&scedil;\":                          true,\n\t\"&scirc;\":                           true,\n\t\"&scnE;\":                            true,\n\t\"&scnap;\":                           true,\n\t\"&scnsim;\":                          true,\n\t\"&scpolint;\":                        true,\n\t\"&scsim;\":                           true,\n\t\"&scy;\":                             true,\n\t\"&sdot;\":                            true,\n\t\"&sdotb;\":                           true,\n\t\"&sdote;\":                           true,\n\t\"&seArr;\":                           true,\n\t\"&searhk;\":                          true,\n\t\"&searr;\":                           true,\n\t\"&searrow;\":                         true,\n\t\"&sect\":                             true,\n\t\"&sect;\":                            true,\n\t\"&semi;\":                            true,\n\t\"&seswar;\":                          true,\n\t\"&setminus;\":                        true,\n\t\"&setmn;\":                           true,\n\t\"&sext;\":                            true,\n\t\"&sfr;\":                             true,\n\t\"&sfrown;\":                          true,\n\t\"&sharp;\":                           true,\n\t\"&shchcy;\":                          true,\n\t\"&shcy;\":                            true,\n\t\"&shortmid;\":                        true,\n\t\"&shortparallel;\":                   true,\n\t\"&shy\":                              true,\n\t\"&shy;\":                             true,\n\t\"&sigma;\":                           true,\n\t\"&sigmaf;\":                          true,\n\t\"&sigmav;\":                          true,\n\t\"&sim;\":                             true,\n\t\"&simdot;\":                          true,\n\t\"&sime;\":                            true,\n\t\"&simeq;\":                           true,\n\t\"&simg;\":                            true,\n\t\"&simgE;\":                           true,\n\t\"&siml;\":                            true,\n\t\"&simlE;\":                           true,\n\t\"&simne;\":                           true,\n\t\"&simplus;\":                         true,\n\t\"&simrarr;\":                         true,\n\t\"&slarr;\":                           true,\n\t\"&smallsetminus;\":                   true,\n\t\"&smashp;\":                          true,\n\t\"&smeparsl;\":                        true,\n\t\"&smid;\":                            true,\n\t\"&smile;\":                           true,\n\t\"&smt;\":                             true,\n\t\"&smte;\":                            true,\n\t\"&smtes;\":                           true,\n\t\"&softcy;\":                          true,\n\t\"&sol;\":                             true,\n\t\"&solb;\":                            true,\n\t\"&solbar;\":                          true,\n\t\"&sopf;\":                            true,\n\t\"&spades;\":                          true,\n\t\"&spadesuit;\":                       true,\n\t\"&spar;\":                            true,\n\t\"&sqcap;\":                           true,\n\t\"&sqcaps;\":                          true,\n\t\"&sqcup;\":                           true,\n\t\"&sqcups;\":                          true,\n\t\"&sqsub;\":                           true,\n\t\"&sqsube;\":                          true,\n\t\"&sqsubset;\":                        true,\n\t\"&sqsubseteq;\":                      true,\n\t\"&sqsup;\":                           true,\n\t\"&sqsupe;\":                          true,\n\t\"&sqsupset;\":                        true,\n\t\"&sqsupseteq;\":                      true,\n\t\"&squ;\":                             true,\n\t\"&square;\":                          true,\n\t\"&squarf;\":                          true,\n\t\"&squf;\":                            true,\n\t\"&srarr;\":                           true,\n\t\"&sscr;\":                            true,\n\t\"&ssetmn;\":                          true,\n\t\"&ssmile;\":                          true,\n\t\"&sstarf;\":                          true,\n\t\"&star;\":                            true,\n\t\"&starf;\":                           true,\n\t\"&straightepsilon;\":                 true,\n\t\"&straightphi;\":                     true,\n\t\"&strns;\":                           true,\n\t\"&sub;\":                             true,\n\t\"&subE;\":                            true,\n\t\"&subdot;\":                          true,\n\t\"&sube;\":                            true,\n\t\"&subedot;\":                         true,\n\t\"&submult;\":                         true,\n\t\"&subnE;\":                           true,\n\t\"&subne;\":                           true,\n\t\"&subplus;\":                         true,\n\t\"&subrarr;\":                         true,\n\t\"&subset;\":                          true,\n\t\"&subseteq;\":                        true,\n\t\"&subseteqq;\":                       true,\n\t\"&subsetneq;\":                       true,\n\t\"&subsetneqq;\":                      true,\n\t\"&subsim;\":                          true,\n\t\"&subsub;\":                          true,\n\t\"&subsup;\":                          true,\n\t\"&succ;\":                            true,\n\t\"&succapprox;\":                      true,\n\t\"&succcurlyeq;\":                     true,\n\t\"&succeq;\":                          true,\n\t\"&succnapprox;\":                     true,\n\t\"&succneqq;\":                        true,\n\t\"&succnsim;\":                        true,\n\t\"&succsim;\":                         true,\n\t\"&sum;\":                             true,\n\t\"&sung;\":                            true,\n\t\"&sup1\":                             true,\n\t\"&sup1;\":                            true,\n\t\"&sup2\":                             true,\n\t\"&sup2;\":                            true,\n\t\"&sup3\":                             true,\n\t\"&sup3;\":                            true,\n\t\"&sup;\":                             true,\n\t\"&supE;\":                            true,\n\t\"&supdot;\":                          true,\n\t\"&supdsub;\":                         true,\n\t\"&supe;\":                            true,\n\t\"&supedot;\":                         true,\n\t\"&suphsol;\":                         true,\n\t\"&suphsub;\":                         true,\n\t\"&suplarr;\":                         true,\n\t\"&supmult;\":                         true,\n\t\"&supnE;\":                           true,\n\t\"&supne;\":                           true,\n\t\"&supplus;\":                         true,\n\t\"&supset;\":                          true,\n\t\"&supseteq;\":                        true,\n\t\"&supseteqq;\":                       true,\n\t\"&supsetneq;\":                       true,\n\t\"&supsetneqq;\":                      true,\n\t\"&supsim;\":                          true,\n\t\"&supsub;\":                          true,\n\t\"&supsup;\":                          true,\n\t\"&swArr;\":                           true,\n\t\"&swarhk;\":                          true,\n\t\"&swarr;\":                           true,\n\t\"&swarrow;\":                         true,\n\t\"&swnwar;\":                          true,\n\t\"&szlig\":                            true,\n\t\"&szlig;\":                           true,\n\t\"&target;\":                          true,\n\t\"&tau;\":                             true,\n\t\"&tbrk;\":                            true,\n\t\"&tcaron;\":                          true,\n\t\"&tcedil;\":                          true,\n\t\"&tcy;\":                             true,\n\t\"&tdot;\":                            true,\n\t\"&telrec;\":                          true,\n\t\"&tfr;\":                             true,\n\t\"&there4;\":                          true,\n\t\"&therefore;\":                       true,\n\t\"&theta;\":                           true,\n\t\"&thetasym;\":                        true,\n\t\"&thetav;\":                          true,\n\t\"&thickapprox;\":                     true,\n\t\"&thicksim;\":                        true,\n\t\"&thinsp;\":                          true,\n\t\"&thkap;\":                           true,\n\t\"&thksim;\":                          true,\n\t\"&thorn\":                            true,\n\t\"&thorn;\":                           true,\n\t\"&tilde;\":                           true,\n\t\"&times\":                            true,\n\t\"&times;\":                           true,\n\t\"&timesb;\":                          true,\n\t\"&timesbar;\":                        true,\n\t\"&timesd;\":                          true,\n\t\"&tint;\":                            true,\n\t\"&toea;\":                            true,\n\t\"&top;\":                             true,\n\t\"&topbot;\":                          true,\n\t\"&topcir;\":                          true,\n\t\"&topf;\":                            true,\n\t\"&topfork;\":                         true,\n\t\"&tosa;\":                            true,\n\t\"&tprime;\":                          true,\n\t\"&trade;\":                           true,\n\t\"&triangle;\":                        true,\n\t\"&triangledown;\":                    true,\n\t\"&triangleleft;\":                    true,\n\t\"&trianglelefteq;\":                  true,\n\t\"&triangleq;\":                       true,\n\t\"&triangleright;\":                   true,\n\t\"&trianglerighteq;\":                 true,\n\t\"&tridot;\":                          true,\n\t\"&trie;\":                            true,\n\t\"&triminus;\":                        true,\n\t\"&triplus;\":                         true,\n\t\"&trisb;\":                           true,\n\t\"&tritime;\":                         true,\n\t\"&trpezium;\":                        true,\n\t\"&tscr;\":                            true,\n\t\"&tscy;\":                            true,\n\t\"&tshcy;\":                           true,\n\t\"&tstrok;\":                          true,\n\t\"&twixt;\":                           true,\n\t\"&twoheadleftarrow;\":                true,\n\t\"&twoheadrightarrow;\":               true,\n\t\"&uArr;\":                            true,\n\t\"&uHar;\":                            true,\n\t\"&uacute\":                           true,\n\t\"&uacute;\":                          true,\n\t\"&uarr;\":                            true,\n\t\"&ubrcy;\":                           true,\n\t\"&ubreve;\":                          true,\n\t\"&ucirc\":                            true,\n\t\"&ucirc;\":                           true,\n\t\"&ucy;\":                             true,\n\t\"&udarr;\":                           true,\n\t\"&udblac;\":                          true,\n\t\"&udhar;\":                           true,\n\t\"&ufisht;\":                          true,\n\t\"&ufr;\":                             true,\n\t\"&ugrave\":                           true,\n\t\"&ugrave;\":                          true,\n\t\"&uharl;\":                           true,\n\t\"&uharr;\":                           true,\n\t\"&uhblk;\":                           true,\n\t\"&ulcorn;\":                          true,\n\t\"&ulcorner;\":                        true,\n\t\"&ulcrop;\":                          true,\n\t\"&ultri;\":                           true,\n\t\"&umacr;\":                           true,\n\t\"&uml\":                              true,\n\t\"&uml;\":                             true,\n\t\"&uogon;\":                           true,\n\t\"&uopf;\":                            true,\n\t\"&uparrow;\":                         true,\n\t\"&updownarrow;\":                     true,\n\t\"&upharpoonleft;\":                   true,\n\t\"&upharpoonright;\":                  true,\n\t\"&uplus;\":                           true,\n\t\"&upsi;\":                            true,\n\t\"&upsih;\":                           true,\n\t\"&upsilon;\":                         true,\n\t\"&upuparrows;\":                      true,\n\t\"&urcorn;\":                          true,\n\t\"&urcorner;\":                        true,\n\t\"&urcrop;\":                          true,\n\t\"&uring;\":                           true,\n\t\"&urtri;\":                           true,\n\t\"&uscr;\":                            true,\n\t\"&utdot;\":                           true,\n\t\"&utilde;\":                          true,\n\t\"&utri;\":                            true,\n\t\"&utrif;\":                           true,\n\t\"&uuarr;\":                           true,\n\t\"&uuml\":                             true,\n\t\"&uuml;\":                            true,\n\t\"&uwangle;\":                         true,\n\t\"&vArr;\":                            true,\n\t\"&vBar;\":                            true,\n\t\"&vBarv;\":                           true,\n\t\"&vDash;\":                           true,\n\t\"&vangrt;\":                          true,\n\t\"&varepsilon;\":                      true,\n\t\"&varkappa;\":                        true,\n\t\"&varnothing;\":                      true,\n\t\"&varphi;\":                          true,\n\t\"&varpi;\":                           true,\n\t\"&varpropto;\":                       true,\n\t\"&varr;\":                            true,\n\t\"&varrho;\":                          true,\n\t\"&varsigma;\":                        true,\n\t\"&varsubsetneq;\":                    true,\n\t\"&varsubsetneqq;\":                   true,\n\t\"&varsupsetneq;\":                    true,\n\t\"&varsupsetneqq;\":                   true,\n\t\"&vartheta;\":                        true,\n\t\"&vartriangleleft;\":                 true,\n\t\"&vartriangleright;\":                true,\n\t\"&vcy;\":                             true,\n\t\"&vdash;\":                           true,\n\t\"&vee;\":                             true,\n\t\"&veebar;\":                          true,\n\t\"&veeeq;\":                           true,\n\t\"&vellip;\":                          true,\n\t\"&verbar;\":                          true,\n\t\"&vert;\":                            true,\n\t\"&vfr;\":                             true,\n\t\"&vltri;\":                           true,\n\t\"&vnsub;\":                           true,\n\t\"&vnsup;\":                           true,\n\t\"&vopf;\":                            true,\n\t\"&vprop;\":                           true,\n\t\"&vrtri;\":                           true,\n\t\"&vscr;\":                            true,\n\t\"&vsubnE;\":                          true,\n\t\"&vsubne;\":                          true,\n\t\"&vsupnE;\":                          true,\n\t\"&vsupne;\":                          true,\n\t\"&vzigzag;\":                         true,\n\t\"&wcirc;\":                           true,\n\t\"&wedbar;\":                          true,\n\t\"&wedge;\":                           true,\n\t\"&wedgeq;\":                          true,\n\t\"&weierp;\":                          true,\n\t\"&wfr;\":                             true,\n\t\"&wopf;\":                            true,\n\t\"&wp;\":                              true,\n\t\"&wr;\":                              true,\n\t\"&wreath;\":                          true,\n\t\"&wscr;\":                            true,\n\t\"&xcap;\":                            true,\n\t\"&xcirc;\":                           true,\n\t\"&xcup;\":                            true,\n\t\"&xdtri;\":                           true,\n\t\"&xfr;\":                             true,\n\t\"&xhArr;\":                           true,\n\t\"&xharr;\":                           true,\n\t\"&xi;\":                              true,\n\t\"&xlArr;\":                           true,\n\t\"&xlarr;\":                           true,\n\t\"&xmap;\":                            true,\n\t\"&xnis;\":                            true,\n\t\"&xodot;\":                           true,\n\t\"&xopf;\":                            true,\n\t\"&xoplus;\":                          true,\n\t\"&xotime;\":                          true,\n\t\"&xrArr;\":                           true,\n\t\"&xrarr;\":                           true,\n\t\"&xscr;\":                            true,\n\t\"&xsqcup;\":                          true,\n\t\"&xuplus;\":                          true,\n\t\"&xutri;\":                           true,\n\t\"&xvee;\":                            true,\n\t\"&xwedge;\":                          true,\n\t\"&yacute\":                           true,\n\t\"&yacute;\":                          true,\n\t\"&yacy;\":                            true,\n\t\"&ycirc;\":                           true,\n\t\"&ycy;\":                             true,\n\t\"&yen\":                              true,\n\t\"&yen;\":                             true,\n\t\"&yfr;\":                             true,\n\t\"&yicy;\":                            true,\n\t\"&yopf;\":                            true,\n\t\"&yscr;\":                            true,\n\t\"&yucy;\":                            true,\n\t\"&yuml\":                             true,\n\t\"&yuml;\":                            true,\n\t\"&zacute;\":                          true,\n\t\"&zcaron;\":                          true,\n\t\"&zcy;\":                             true,\n\t\"&zdot;\":                            true,\n\t\"&zeetrf;\":                          true,\n\t\"&zeta;\":                            true,\n\t\"&zfr;\":                             true,\n\t\"&zhcy;\":                            true,\n\t\"&zigrarr;\":                         true,\n\t\"&zopf;\":                            true,\n\t\"&zscr;\":                            true,\n\t\"&zwj;\":                             true,\n\t\"&zwnj;\":                            true,\n}\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/esc.go",
    "content": "package blackfriday\n\nimport (\n\t\"html\"\n\t\"io\"\n)\n\nvar htmlEscaper = [256][]byte{\n\t'&': []byte(\"&amp;\"),\n\t'<': []byte(\"&lt;\"),\n\t'>': []byte(\"&gt;\"),\n\t'\"': []byte(\"&quot;\"),\n}\n\nfunc escapeHTML(w io.Writer, s []byte) {\n\tescapeEntities(w, s, false)\n}\n\nfunc escapeAllHTML(w io.Writer, s []byte) {\n\tescapeEntities(w, s, true)\n}\n\nfunc escapeEntities(w io.Writer, s []byte, escapeValidEntities bool) {\n\tvar start, end int\n\tfor end < len(s) {\n\t\tescSeq := htmlEscaper[s[end]]\n\t\tif escSeq != nil {\n\t\t\tisEntity, entityEnd := nodeIsEntity(s, end)\n\t\t\tif isEntity && !escapeValidEntities {\n\t\t\t\tw.Write(s[start : entityEnd+1])\n\t\t\t\tstart = entityEnd + 1\n\t\t\t} else {\n\t\t\t\tw.Write(s[start:end])\n\t\t\t\tw.Write(escSeq)\n\t\t\t\tstart = end + 1\n\t\t\t}\n\t\t}\n\t\tend++\n\t}\n\tif start < len(s) && end <= len(s) {\n\t\tw.Write(s[start:end])\n\t}\n}\n\nfunc nodeIsEntity(s []byte, end int) (isEntity bool, endEntityPos int) {\n\tisEntity = false\n\tendEntityPos = end + 1\n\n\tif s[end] == '&' {\n\t\tfor endEntityPos < len(s) {\n\t\t\tif s[endEntityPos] == ';' {\n\t\t\t\tif entities[string(s[end:endEntityPos+1])] {\n\t\t\t\t\tisEntity = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !isalnum(s[endEntityPos]) && s[endEntityPos] != '&' && s[endEntityPos] != '#' {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tendEntityPos++\n\t\t}\n\t}\n\n\treturn isEntity, endEntityPos\n}\n\nfunc escLink(w io.Writer, text []byte) {\n\tunesc := html.UnescapeString(string(text))\n\tescapeHTML(w, []byte(unesc))\n}\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/html.go",
    "content": "//\n// Blackfriday Markdown Processor\n// Available at http://github.com/russross/blackfriday\n//\n// Copyright © 2011 Russ Ross <russ@russross.com>.\n// Distributed under the Simplified BSD License.\n// See README.md for details.\n//\n\n//\n//\n// HTML rendering backend\n//\n//\n\npackage blackfriday\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"regexp\"\n\t\"strings\"\n)\n\n// HTMLFlags control optional behavior of HTML renderer.\ntype HTMLFlags int\n\n// HTML renderer configuration options.\nconst (\n\tHTMLFlagsNone           HTMLFlags = 0\n\tSkipHTML                HTMLFlags = 1 << iota // Skip preformatted HTML blocks\n\tSkipImages                                    // Skip embedded images\n\tSkipLinks                                     // Skip all links\n\tSafelink                                      // Only link to trusted protocols\n\tNofollowLinks                                 // Only link with rel=\"nofollow\"\n\tNoreferrerLinks                               // Only link with rel=\"noreferrer\"\n\tNoopenerLinks                                 // Only link with rel=\"noopener\"\n\tHrefTargetBlank                               // Add a blank target\n\tCompletePage                                  // Generate a complete HTML page\n\tUseXHTML                                      // Generate XHTML output instead of HTML\n\tFootnoteReturnLinks                           // Generate a link at the end of a footnote to return to the source\n\tSmartypants                                   // Enable smart punctuation substitutions\n\tSmartypantsFractions                          // Enable smart fractions (with Smartypants)\n\tSmartypantsDashes                             // Enable smart dashes (with Smartypants)\n\tSmartypantsLatexDashes                        // Enable LaTeX-style dashes (with Smartypants)\n\tSmartypantsAngledQuotes                       // Enable angled double quotes (with Smartypants) for double quotes rendering\n\tSmartypantsQuotesNBSP                         // Enable « French guillemets » (with Smartypants)\n\tTOC                                           // Generate a table of contents\n)\n\nvar (\n\thtmlTagRe = regexp.MustCompile(\"(?i)^\" + htmlTag)\n)\n\nconst (\n\thtmlTag = \"(?:\" + openTag + \"|\" + closeTag + \"|\" + htmlComment + \"|\" +\n\t\tprocessingInstruction + \"|\" + declaration + \"|\" + cdata + \")\"\n\tcloseTag              = \"</\" + tagName + \"\\\\s*[>]\"\n\topenTag               = \"<\" + tagName + attribute + \"*\" + \"\\\\s*/?>\"\n\tattribute             = \"(?:\" + \"\\\\s+\" + attributeName + attributeValueSpec + \"?)\"\n\tattributeValue        = \"(?:\" + unquotedValue + \"|\" + singleQuotedValue + \"|\" + doubleQuotedValue + \")\"\n\tattributeValueSpec    = \"(?:\" + \"\\\\s*=\" + \"\\\\s*\" + attributeValue + \")\"\n\tattributeName         = \"[a-zA-Z_:][a-zA-Z0-9:._-]*\"\n\tcdata                 = \"<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?\\\\]\\\\]>\"\n\tdeclaration           = \"<![A-Z]+\" + \"\\\\s+[^>]*>\"\n\tdoubleQuotedValue     = \"\\\"[^\\\"]*\\\"\"\n\thtmlComment           = \"<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->\"\n\tprocessingInstruction = \"[<][?].*?[?][>]\"\n\tsingleQuotedValue     = \"'[^']*'\"\n\ttagName               = \"[A-Za-z][A-Za-z0-9-]*\"\n\tunquotedValue         = \"[^\\\"'=<>`\\\\x00-\\\\x20]+\"\n)\n\n// HTMLRendererParameters is a collection of supplementary parameters tweaking\n// the behavior of various parts of HTML renderer.\ntype HTMLRendererParameters struct {\n\t// Prepend this text to each relative URL.\n\tAbsolutePrefix string\n\t// Add this text to each footnote anchor, to ensure uniqueness.\n\tFootnoteAnchorPrefix string\n\t// Show this text inside the <a> tag for a footnote return link, if the\n\t// HTML_FOOTNOTE_RETURN_LINKS flag is enabled. If blank, the string\n\t// <sup>[return]</sup> is used.\n\tFootnoteReturnLinkContents string\n\t// If set, add this text to the front of each Heading ID, to ensure\n\t// uniqueness.\n\tHeadingIDPrefix string\n\t// If set, add this text to the back of each Heading ID, to ensure uniqueness.\n\tHeadingIDSuffix string\n\t// Increase heading levels: if the offset is 1, <h1> becomes <h2> etc.\n\t// Negative offset is also valid.\n\t// Resulting levels are clipped between 1 and 6.\n\tHeadingLevelOffset int\n\n\tTitle string // Document title (used if CompletePage is set)\n\tCSS   string // Optional CSS file URL (used if CompletePage is set)\n\tIcon  string // Optional icon file URL (used if CompletePage is set)\n\n\tFlags HTMLFlags // Flags allow customizing this renderer's behavior\n}\n\n// HTMLRenderer is a type that implements the Renderer interface for HTML output.\n//\n// Do not create this directly, instead use the NewHTMLRenderer function.\ntype HTMLRenderer struct {\n\tHTMLRendererParameters\n\n\tcloseTag string // how to end singleton tags: either \" />\" or \">\"\n\n\t// Track heading IDs to prevent ID collision in a single generation.\n\theadingIDs map[string]int\n\n\tlastOutputLen int\n\tdisableTags   int\n\n\tsr *SPRenderer\n}\n\nconst (\n\txhtmlClose = \" />\"\n\thtmlClose  = \">\"\n)\n\n// NewHTMLRenderer creates and configures an HTMLRenderer object, which\n// satisfies the Renderer interface.\nfunc NewHTMLRenderer(params HTMLRendererParameters) *HTMLRenderer {\n\t// configure the rendering engine\n\tcloseTag := htmlClose\n\tif params.Flags&UseXHTML != 0 {\n\t\tcloseTag = xhtmlClose\n\t}\n\n\tif params.FootnoteReturnLinkContents == \"\" {\n\t\t// U+FE0E is VARIATION SELECTOR-15.\n\t\t// It suppresses automatic emoji presentation of the preceding\n\t\t// U+21A9 LEFTWARDS ARROW WITH HOOK on iOS and iPadOS.\n\t\tparams.FootnoteReturnLinkContents = \"<span aria-label='Return'>↩\\ufe0e</span>\"\n\t}\n\n\treturn &HTMLRenderer{\n\t\tHTMLRendererParameters: params,\n\n\t\tcloseTag:   closeTag,\n\t\theadingIDs: make(map[string]int),\n\n\t\tsr: NewSmartypantsRenderer(params.Flags),\n\t}\n}\n\nfunc isHTMLTag(tag []byte, tagname string) bool {\n\tfound, _ := findHTMLTagPos(tag, tagname)\n\treturn found\n}\n\n// Look for a character, but ignore it when it's in any kind of quotes, it\n// might be JavaScript\nfunc skipUntilCharIgnoreQuotes(html []byte, start int, char byte) int {\n\tinSingleQuote := false\n\tinDoubleQuote := false\n\tinGraveQuote := false\n\ti := start\n\tfor i < len(html) {\n\t\tswitch {\n\t\tcase html[i] == char && !inSingleQuote && !inDoubleQuote && !inGraveQuote:\n\t\t\treturn i\n\t\tcase html[i] == '\\'':\n\t\t\tinSingleQuote = !inSingleQuote\n\t\tcase html[i] == '\"':\n\t\t\tinDoubleQuote = !inDoubleQuote\n\t\tcase html[i] == '`':\n\t\t\tinGraveQuote = !inGraveQuote\n\t\t}\n\t\ti++\n\t}\n\treturn start\n}\n\nfunc findHTMLTagPos(tag []byte, tagname string) (bool, int) {\n\ti := 0\n\tif i < len(tag) && tag[0] != '<' {\n\t\treturn false, -1\n\t}\n\ti++\n\ti = skipSpace(tag, i)\n\n\tif i < len(tag) && tag[i] == '/' {\n\t\ti++\n\t}\n\n\ti = skipSpace(tag, i)\n\tj := 0\n\tfor ; i < len(tag); i, j = i+1, j+1 {\n\t\tif j >= len(tagname) {\n\t\t\tbreak\n\t\t}\n\n\t\tif strings.ToLower(string(tag[i]))[0] != tagname[j] {\n\t\t\treturn false, -1\n\t\t}\n\t}\n\n\tif i == len(tag) {\n\t\treturn false, -1\n\t}\n\n\trightAngle := skipUntilCharIgnoreQuotes(tag, i, '>')\n\tif rightAngle >= i {\n\t\treturn true, rightAngle\n\t}\n\n\treturn false, -1\n}\n\nfunc skipSpace(tag []byte, i int) int {\n\tfor i < len(tag) && isspace(tag[i]) {\n\t\ti++\n\t}\n\treturn i\n}\n\nfunc isRelativeLink(link []byte) (yes bool) {\n\t// a tag begin with '#'\n\tif link[0] == '#' {\n\t\treturn true\n\t}\n\n\t// link begin with '/' but not '//', the second maybe a protocol relative link\n\tif len(link) >= 2 && link[0] == '/' && link[1] != '/' {\n\t\treturn true\n\t}\n\n\t// only the root '/'\n\tif len(link) == 1 && link[0] == '/' {\n\t\treturn true\n\t}\n\n\t// current directory : begin with \"./\"\n\tif bytes.HasPrefix(link, []byte(\"./\")) {\n\t\treturn true\n\t}\n\n\t// parent directory : begin with \"../\"\n\tif bytes.HasPrefix(link, []byte(\"../\")) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc (r *HTMLRenderer) ensureUniqueHeadingID(id string) string {\n\tfor count, found := r.headingIDs[id]; found; count, found = r.headingIDs[id] {\n\t\ttmp := fmt.Sprintf(\"%s-%d\", id, count+1)\n\n\t\tif _, tmpFound := r.headingIDs[tmp]; !tmpFound {\n\t\t\tr.headingIDs[id] = count + 1\n\t\t\tid = tmp\n\t\t} else {\n\t\t\tid = id + \"-1\"\n\t\t}\n\t}\n\n\tif _, found := r.headingIDs[id]; !found {\n\t\tr.headingIDs[id] = 0\n\t}\n\n\treturn id\n}\n\nfunc (r *HTMLRenderer) addAbsPrefix(link []byte) []byte {\n\tif r.AbsolutePrefix != \"\" && isRelativeLink(link) && link[0] != '.' {\n\t\tnewDest := r.AbsolutePrefix\n\t\tif link[0] != '/' {\n\t\t\tnewDest += \"/\"\n\t\t}\n\t\tnewDest += string(link)\n\t\treturn []byte(newDest)\n\t}\n\treturn link\n}\n\nfunc appendLinkAttrs(attrs []string, flags HTMLFlags, link []byte) []string {\n\tif isRelativeLink(link) {\n\t\treturn attrs\n\t}\n\tval := []string{}\n\tif flags&NofollowLinks != 0 {\n\t\tval = append(val, \"nofollow\")\n\t}\n\tif flags&NoreferrerLinks != 0 {\n\t\tval = append(val, \"noreferrer\")\n\t}\n\tif flags&NoopenerLinks != 0 {\n\t\tval = append(val, \"noopener\")\n\t}\n\tif flags&HrefTargetBlank != 0 {\n\t\tattrs = append(attrs, \"target=\\\"_blank\\\"\")\n\t}\n\tif len(val) == 0 {\n\t\treturn attrs\n\t}\n\tattr := fmt.Sprintf(\"rel=%q\", strings.Join(val, \" \"))\n\treturn append(attrs, attr)\n}\n\nfunc isMailto(link []byte) bool {\n\treturn bytes.HasPrefix(link, []byte(\"mailto:\"))\n}\n\nfunc needSkipLink(flags HTMLFlags, dest []byte) bool {\n\tif flags&SkipLinks != 0 {\n\t\treturn true\n\t}\n\treturn flags&Safelink != 0 && !isSafeLink(dest) && !isMailto(dest)\n}\n\nfunc isSmartypantable(node *Node) bool {\n\tpt := node.Parent.Type\n\treturn pt != Link && pt != CodeBlock && pt != Code\n}\n\nfunc appendLanguageAttr(attrs []string, info []byte) []string {\n\tif len(info) == 0 {\n\t\treturn attrs\n\t}\n\tendOfLang := bytes.IndexAny(info, \"\\t \")\n\tif endOfLang < 0 {\n\t\tendOfLang = len(info)\n\t}\n\treturn append(attrs, fmt.Sprintf(\"class=\\\"language-%s\\\"\", info[:endOfLang]))\n}\n\nfunc (r *HTMLRenderer) tag(w io.Writer, name []byte, attrs []string) {\n\tw.Write(name)\n\tif len(attrs) > 0 {\n\t\tw.Write(spaceBytes)\n\t\tw.Write([]byte(strings.Join(attrs, \" \")))\n\t}\n\tw.Write(gtBytes)\n\tr.lastOutputLen = 1\n}\n\nfunc footnoteRef(prefix string, node *Node) []byte {\n\turlFrag := prefix + string(slugify(node.Destination))\n\tanchor := fmt.Sprintf(`<a href=\"#fn:%s\">%d</a>`, urlFrag, node.NoteID)\n\treturn []byte(fmt.Sprintf(`<sup class=\"footnote-ref\" id=\"fnref:%s\">%s</sup>`, urlFrag, anchor))\n}\n\nfunc footnoteItem(prefix string, slug []byte) []byte {\n\treturn []byte(fmt.Sprintf(`<li id=\"fn:%s%s\">`, prefix, slug))\n}\n\nfunc footnoteReturnLink(prefix, returnLink string, slug []byte) []byte {\n\tconst format = ` <a class=\"footnote-return\" href=\"#fnref:%s%s\">%s</a>`\n\treturn []byte(fmt.Sprintf(format, prefix, slug, returnLink))\n}\n\nfunc itemOpenCR(node *Node) bool {\n\tif node.Prev == nil {\n\t\treturn false\n\t}\n\tld := node.Parent.ListData\n\treturn !ld.Tight && ld.ListFlags&ListTypeDefinition == 0\n}\n\nfunc skipParagraphTags(node *Node) bool {\n\tgrandparent := node.Parent.Parent\n\tif grandparent == nil || grandparent.Type != List {\n\t\treturn false\n\t}\n\ttightOrTerm := grandparent.Tight || node.Parent.ListFlags&ListTypeTerm != 0\n\treturn grandparent.Type == List && tightOrTerm\n}\n\nfunc cellAlignment(align CellAlignFlags) string {\n\tswitch align {\n\tcase TableAlignmentLeft:\n\t\treturn \"left\"\n\tcase TableAlignmentRight:\n\t\treturn \"right\"\n\tcase TableAlignmentCenter:\n\t\treturn \"center\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\nfunc (r *HTMLRenderer) out(w io.Writer, text []byte) {\n\tif r.disableTags > 0 {\n\t\tw.Write(htmlTagRe.ReplaceAll(text, []byte{}))\n\t} else {\n\t\tw.Write(text)\n\t}\n\tr.lastOutputLen = len(text)\n}\n\nfunc (r *HTMLRenderer) cr(w io.Writer) {\n\tif r.lastOutputLen > 0 {\n\t\tr.out(w, nlBytes)\n\t}\n}\n\nvar (\n\tnlBytes    = []byte{'\\n'}\n\tgtBytes    = []byte{'>'}\n\tspaceBytes = []byte{' '}\n)\n\nvar (\n\tbrTag              = []byte(\"<br>\")\n\tbrXHTMLTag         = []byte(\"<br />\")\n\temTag              = []byte(\"<em>\")\n\temCloseTag         = []byte(\"</em>\")\n\tstrongTag          = []byte(\"<strong>\")\n\tstrongCloseTag     = []byte(\"</strong>\")\n\tdelTag             = []byte(\"<del>\")\n\tdelCloseTag        = []byte(\"</del>\")\n\tttTag              = []byte(\"<tt>\")\n\tttCloseTag         = []byte(\"</tt>\")\n\taTag               = []byte(\"<a\")\n\taCloseTag          = []byte(\"</a>\")\n\tpreTag             = []byte(\"<pre>\")\n\tpreCloseTag        = []byte(\"</pre>\")\n\tcodeTag            = []byte(\"<code>\")\n\tcodeCloseTag       = []byte(\"</code>\")\n\tpTag               = []byte(\"<p>\")\n\tpCloseTag          = []byte(\"</p>\")\n\tblockquoteTag      = []byte(\"<blockquote>\")\n\tblockquoteCloseTag = []byte(\"</blockquote>\")\n\thrTag              = []byte(\"<hr>\")\n\thrXHTMLTag         = []byte(\"<hr />\")\n\tulTag              = []byte(\"<ul>\")\n\tulCloseTag         = []byte(\"</ul>\")\n\tolTag              = []byte(\"<ol>\")\n\tolCloseTag         = []byte(\"</ol>\")\n\tdlTag              = []byte(\"<dl>\")\n\tdlCloseTag         = []byte(\"</dl>\")\n\tliTag              = []byte(\"<li>\")\n\tliCloseTag         = []byte(\"</li>\")\n\tddTag              = []byte(\"<dd>\")\n\tddCloseTag         = []byte(\"</dd>\")\n\tdtTag              = []byte(\"<dt>\")\n\tdtCloseTag         = []byte(\"</dt>\")\n\ttableTag           = []byte(\"<table>\")\n\ttableCloseTag      = []byte(\"</table>\")\n\ttdTag              = []byte(\"<td\")\n\ttdCloseTag         = []byte(\"</td>\")\n\tthTag              = []byte(\"<th\")\n\tthCloseTag         = []byte(\"</th>\")\n\ttheadTag           = []byte(\"<thead>\")\n\ttheadCloseTag      = []byte(\"</thead>\")\n\ttbodyTag           = []byte(\"<tbody>\")\n\ttbodyCloseTag      = []byte(\"</tbody>\")\n\ttrTag              = []byte(\"<tr>\")\n\ttrCloseTag         = []byte(\"</tr>\")\n\th1Tag              = []byte(\"<h1\")\n\th1CloseTag         = []byte(\"</h1>\")\n\th2Tag              = []byte(\"<h2\")\n\th2CloseTag         = []byte(\"</h2>\")\n\th3Tag              = []byte(\"<h3\")\n\th3CloseTag         = []byte(\"</h3>\")\n\th4Tag              = []byte(\"<h4\")\n\th4CloseTag         = []byte(\"</h4>\")\n\th5Tag              = []byte(\"<h5\")\n\th5CloseTag         = []byte(\"</h5>\")\n\th6Tag              = []byte(\"<h6\")\n\th6CloseTag         = []byte(\"</h6>\")\n\n\tfootnotesDivBytes      = []byte(\"\\n<div class=\\\"footnotes\\\">\\n\\n\")\n\tfootnotesCloseDivBytes = []byte(\"\\n</div>\\n\")\n)\n\nfunc headingTagsFromLevel(level int) ([]byte, []byte) {\n\tif level <= 1 {\n\t\treturn h1Tag, h1CloseTag\n\t}\n\tswitch level {\n\tcase 2:\n\t\treturn h2Tag, h2CloseTag\n\tcase 3:\n\t\treturn h3Tag, h3CloseTag\n\tcase 4:\n\t\treturn h4Tag, h4CloseTag\n\tcase 5:\n\t\treturn h5Tag, h5CloseTag\n\t}\n\treturn h6Tag, h6CloseTag\n}\n\nfunc (r *HTMLRenderer) outHRTag(w io.Writer) {\n\tif r.Flags&UseXHTML == 0 {\n\t\tr.out(w, hrTag)\n\t} else {\n\t\tr.out(w, hrXHTMLTag)\n\t}\n}\n\n// RenderNode is a default renderer of a single node of a syntax tree. For\n// block nodes it will be called twice: first time with entering=true, second\n// time with entering=false, so that it could know when it's working on an open\n// tag and when on close. It writes the result to w.\n//\n// The return value is a way to tell the calling walker to adjust its walk\n// pattern: e.g. it can terminate the traversal by returning Terminate. Or it\n// can ask the walker to skip a subtree of this node by returning SkipChildren.\n// The typical behavior is to return GoToNext, which asks for the usual\n// traversal to the next node.\nfunc (r *HTMLRenderer) RenderNode(w io.Writer, node *Node, entering bool) WalkStatus {\n\tattrs := []string{}\n\tswitch node.Type {\n\tcase Text:\n\t\tif r.Flags&Smartypants != 0 {\n\t\t\tvar tmp bytes.Buffer\n\t\t\tescapeHTML(&tmp, node.Literal)\n\t\t\tr.sr.Process(w, tmp.Bytes())\n\t\t} else {\n\t\t\tif node.Parent.Type == Link {\n\t\t\t\tescLink(w, node.Literal)\n\t\t\t} else {\n\t\t\t\tescapeHTML(w, node.Literal)\n\t\t\t}\n\t\t}\n\tcase Softbreak:\n\t\tr.cr(w)\n\t\t// TODO: make it configurable via out(renderer.softbreak)\n\tcase Hardbreak:\n\t\tif r.Flags&UseXHTML == 0 {\n\t\t\tr.out(w, brTag)\n\t\t} else {\n\t\t\tr.out(w, brXHTMLTag)\n\t\t}\n\t\tr.cr(w)\n\tcase Emph:\n\t\tif entering {\n\t\t\tr.out(w, emTag)\n\t\t} else {\n\t\t\tr.out(w, emCloseTag)\n\t\t}\n\tcase Strong:\n\t\tif entering {\n\t\t\tr.out(w, strongTag)\n\t\t} else {\n\t\t\tr.out(w, strongCloseTag)\n\t\t}\n\tcase Del:\n\t\tif entering {\n\t\t\tr.out(w, delTag)\n\t\t} else {\n\t\t\tr.out(w, delCloseTag)\n\t\t}\n\tcase HTMLSpan:\n\t\tif r.Flags&SkipHTML != 0 {\n\t\t\tbreak\n\t\t}\n\t\tr.out(w, node.Literal)\n\tcase Link:\n\t\t// mark it but don't link it if it is not a safe link: no smartypants\n\t\tdest := node.LinkData.Destination\n\t\tif needSkipLink(r.Flags, dest) {\n\t\t\tif entering {\n\t\t\t\tr.out(w, ttTag)\n\t\t\t} else {\n\t\t\t\tr.out(w, ttCloseTag)\n\t\t\t}\n\t\t} else {\n\t\t\tif entering {\n\t\t\t\tdest = r.addAbsPrefix(dest)\n\t\t\t\tvar hrefBuf bytes.Buffer\n\t\t\t\threfBuf.WriteString(\"href=\\\"\")\n\t\t\t\tescLink(&hrefBuf, dest)\n\t\t\t\threfBuf.WriteByte('\"')\n\t\t\t\tattrs = append(attrs, hrefBuf.String())\n\t\t\t\tif node.NoteID != 0 {\n\t\t\t\t\tr.out(w, footnoteRef(r.FootnoteAnchorPrefix, node))\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tattrs = appendLinkAttrs(attrs, r.Flags, dest)\n\t\t\t\tif len(node.LinkData.Title) > 0 {\n\t\t\t\t\tvar titleBuff bytes.Buffer\n\t\t\t\t\ttitleBuff.WriteString(\"title=\\\"\")\n\t\t\t\t\tescapeHTML(&titleBuff, node.LinkData.Title)\n\t\t\t\t\ttitleBuff.WriteByte('\"')\n\t\t\t\t\tattrs = append(attrs, titleBuff.String())\n\t\t\t\t}\n\t\t\t\tr.tag(w, aTag, attrs)\n\t\t\t} else {\n\t\t\t\tif node.NoteID != 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tr.out(w, aCloseTag)\n\t\t\t}\n\t\t}\n\tcase Image:\n\t\tif r.Flags&SkipImages != 0 {\n\t\t\treturn SkipChildren\n\t\t}\n\t\tif entering {\n\t\t\tdest := node.LinkData.Destination\n\t\t\tdest = r.addAbsPrefix(dest)\n\t\t\tif r.disableTags == 0 {\n\t\t\t\t//if options.safe && potentiallyUnsafe(dest) {\n\t\t\t\t//out(w, `<img src=\"\" alt=\"`)\n\t\t\t\t//} else {\n\t\t\t\tr.out(w, []byte(`<img src=\"`))\n\t\t\t\tescLink(w, dest)\n\t\t\t\tr.out(w, []byte(`\" alt=\"`))\n\t\t\t\t//}\n\t\t\t}\n\t\t\tr.disableTags++\n\t\t} else {\n\t\t\tr.disableTags--\n\t\t\tif r.disableTags == 0 {\n\t\t\t\tif node.LinkData.Title != nil {\n\t\t\t\t\tr.out(w, []byte(`\" title=\"`))\n\t\t\t\t\tescapeHTML(w, node.LinkData.Title)\n\t\t\t\t}\n\t\t\t\tr.out(w, []byte(`\" />`))\n\t\t\t}\n\t\t}\n\tcase Code:\n\t\tr.out(w, codeTag)\n\t\tescapeAllHTML(w, node.Literal)\n\t\tr.out(w, codeCloseTag)\n\tcase Document:\n\t\tbreak\n\tcase Paragraph:\n\t\tif skipParagraphTags(node) {\n\t\t\tbreak\n\t\t}\n\t\tif entering {\n\t\t\t// TODO: untangle this clusterfuck about when the newlines need\n\t\t\t// to be added and when not.\n\t\t\tif node.Prev != nil {\n\t\t\t\tswitch node.Prev.Type {\n\t\t\t\tcase HTMLBlock, List, Paragraph, Heading, CodeBlock, BlockQuote, HorizontalRule:\n\t\t\t\t\tr.cr(w)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif node.Parent.Type == BlockQuote && node.Prev == nil {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t\tr.out(w, pTag)\n\t\t} else {\n\t\t\tr.out(w, pCloseTag)\n\t\t\tif !(node.Parent.Type == Item && node.Next == nil) {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t}\n\tcase BlockQuote:\n\t\tif entering {\n\t\t\tr.cr(w)\n\t\t\tr.out(w, blockquoteTag)\n\t\t} else {\n\t\t\tr.out(w, blockquoteCloseTag)\n\t\t\tr.cr(w)\n\t\t}\n\tcase HTMLBlock:\n\t\tif r.Flags&SkipHTML != 0 {\n\t\t\tbreak\n\t\t}\n\t\tr.cr(w)\n\t\tr.out(w, node.Literal)\n\t\tr.cr(w)\n\tcase Heading:\n\t\theadingLevel := r.HTMLRendererParameters.HeadingLevelOffset + node.Level\n\t\topenTag, closeTag := headingTagsFromLevel(headingLevel)\n\t\tif entering {\n\t\t\tif node.IsTitleblock {\n\t\t\t\tattrs = append(attrs, `class=\"title\"`)\n\t\t\t}\n\t\t\tif node.HeadingID != \"\" {\n\t\t\t\tid := r.ensureUniqueHeadingID(node.HeadingID)\n\t\t\t\tif r.HeadingIDPrefix != \"\" {\n\t\t\t\t\tid = r.HeadingIDPrefix + id\n\t\t\t\t}\n\t\t\t\tif r.HeadingIDSuffix != \"\" {\n\t\t\t\t\tid = id + r.HeadingIDSuffix\n\t\t\t\t}\n\t\t\t\tattrs = append(attrs, fmt.Sprintf(`id=\"%s\"`, id))\n\t\t\t}\n\t\t\tr.cr(w)\n\t\t\tr.tag(w, openTag, attrs)\n\t\t} else {\n\t\t\tr.out(w, closeTag)\n\t\t\tif !(node.Parent.Type == Item && node.Next == nil) {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t}\n\tcase HorizontalRule:\n\t\tr.cr(w)\n\t\tr.outHRTag(w)\n\t\tr.cr(w)\n\tcase List:\n\t\topenTag := ulTag\n\t\tcloseTag := ulCloseTag\n\t\tif node.ListFlags&ListTypeOrdered != 0 {\n\t\t\topenTag = olTag\n\t\t\tcloseTag = olCloseTag\n\t\t}\n\t\tif node.ListFlags&ListTypeDefinition != 0 {\n\t\t\topenTag = dlTag\n\t\t\tcloseTag = dlCloseTag\n\t\t}\n\t\tif entering {\n\t\t\tif node.IsFootnotesList {\n\t\t\t\tr.out(w, footnotesDivBytes)\n\t\t\t\tr.outHRTag(w)\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t\tr.cr(w)\n\t\t\tif node.Parent.Type == Item && node.Parent.Parent.Tight {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t\tr.tag(w, openTag[:len(openTag)-1], attrs)\n\t\t\tr.cr(w)\n\t\t} else {\n\t\t\tr.out(w, closeTag)\n\t\t\t//cr(w)\n\t\t\t//if node.parent.Type != Item {\n\t\t\t//\tcr(w)\n\t\t\t//}\n\t\t\tif node.Parent.Type == Item && node.Next != nil {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t\tif node.Parent.Type == Document || node.Parent.Type == BlockQuote {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t\tif node.IsFootnotesList {\n\t\t\t\tr.out(w, footnotesCloseDivBytes)\n\t\t\t}\n\t\t}\n\tcase Item:\n\t\topenTag := liTag\n\t\tcloseTag := liCloseTag\n\t\tif node.ListFlags&ListTypeDefinition != 0 {\n\t\t\topenTag = ddTag\n\t\t\tcloseTag = ddCloseTag\n\t\t}\n\t\tif node.ListFlags&ListTypeTerm != 0 {\n\t\t\topenTag = dtTag\n\t\t\tcloseTag = dtCloseTag\n\t\t}\n\t\tif entering {\n\t\t\tif itemOpenCR(node) {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t\tif node.ListData.RefLink != nil {\n\t\t\t\tslug := slugify(node.ListData.RefLink)\n\t\t\t\tr.out(w, footnoteItem(r.FootnoteAnchorPrefix, slug))\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tr.out(w, openTag)\n\t\t} else {\n\t\t\tif node.ListData.RefLink != nil {\n\t\t\t\tslug := slugify(node.ListData.RefLink)\n\t\t\t\tif r.Flags&FootnoteReturnLinks != 0 {\n\t\t\t\t\tr.out(w, footnoteReturnLink(r.FootnoteAnchorPrefix, r.FootnoteReturnLinkContents, slug))\n\t\t\t\t}\n\t\t\t}\n\t\t\tr.out(w, closeTag)\n\t\t\tr.cr(w)\n\t\t}\n\tcase CodeBlock:\n\t\tattrs = appendLanguageAttr(attrs, node.Info)\n\t\tr.cr(w)\n\t\tr.out(w, preTag)\n\t\tr.tag(w, codeTag[:len(codeTag)-1], attrs)\n\t\tescapeAllHTML(w, node.Literal)\n\t\tr.out(w, codeCloseTag)\n\t\tr.out(w, preCloseTag)\n\t\tif node.Parent.Type != Item {\n\t\t\tr.cr(w)\n\t\t}\n\tcase Table:\n\t\tif entering {\n\t\t\tr.cr(w)\n\t\t\tr.out(w, tableTag)\n\t\t} else {\n\t\t\tr.out(w, tableCloseTag)\n\t\t\tr.cr(w)\n\t\t}\n\tcase TableCell:\n\t\topenTag := tdTag\n\t\tcloseTag := tdCloseTag\n\t\tif node.IsHeader {\n\t\t\topenTag = thTag\n\t\t\tcloseTag = thCloseTag\n\t\t}\n\t\tif entering {\n\t\t\talign := cellAlignment(node.Align)\n\t\t\tif align != \"\" {\n\t\t\t\tattrs = append(attrs, fmt.Sprintf(`align=\"%s\"`, align))\n\t\t\t}\n\t\t\tif node.Prev == nil {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t\tr.tag(w, openTag, attrs)\n\t\t} else {\n\t\t\tr.out(w, closeTag)\n\t\t\tr.cr(w)\n\t\t}\n\tcase TableHead:\n\t\tif entering {\n\t\t\tr.cr(w)\n\t\t\tr.out(w, theadTag)\n\t\t} else {\n\t\t\tr.out(w, theadCloseTag)\n\t\t\tr.cr(w)\n\t\t}\n\tcase TableBody:\n\t\tif entering {\n\t\t\tr.cr(w)\n\t\t\tr.out(w, tbodyTag)\n\t\t\t// XXX: this is to adhere to a rather silly test. Should fix test.\n\t\t\tif node.FirstChild == nil {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t} else {\n\t\t\tr.out(w, tbodyCloseTag)\n\t\t\tr.cr(w)\n\t\t}\n\tcase TableRow:\n\t\tif entering {\n\t\t\tr.cr(w)\n\t\t\tr.out(w, trTag)\n\t\t} else {\n\t\t\tr.out(w, trCloseTag)\n\t\t\tr.cr(w)\n\t\t}\n\tdefault:\n\t\tpanic(\"Unknown node type \" + node.Type.String())\n\t}\n\treturn GoToNext\n}\n\n// RenderHeader writes HTML document preamble and TOC if requested.\nfunc (r *HTMLRenderer) RenderHeader(w io.Writer, ast *Node) {\n\tr.writeDocumentHeader(w)\n\tif r.Flags&TOC != 0 {\n\t\tr.writeTOC(w, ast)\n\t}\n}\n\n// RenderFooter writes HTML document footer.\nfunc (r *HTMLRenderer) RenderFooter(w io.Writer, ast *Node) {\n\tif r.Flags&CompletePage == 0 {\n\t\treturn\n\t}\n\tio.WriteString(w, \"\\n</body>\\n</html>\\n\")\n}\n\nfunc (r *HTMLRenderer) writeDocumentHeader(w io.Writer) {\n\tif r.Flags&CompletePage == 0 {\n\t\treturn\n\t}\n\tending := \"\"\n\tif r.Flags&UseXHTML != 0 {\n\t\tio.WriteString(w, \"<!DOCTYPE html PUBLIC \\\"-//W3C//DTD XHTML 1.0 Transitional//EN\\\" \")\n\t\tio.WriteString(w, \"\\\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\\\">\\n\")\n\t\tio.WriteString(w, \"<html xmlns=\\\"http://www.w3.org/1999/xhtml\\\">\\n\")\n\t\tending = \" /\"\n\t} else {\n\t\tio.WriteString(w, \"<!DOCTYPE html>\\n\")\n\t\tio.WriteString(w, \"<html>\\n\")\n\t}\n\tio.WriteString(w, \"<head>\\n\")\n\tio.WriteString(w, \"  <title>\")\n\tif r.Flags&Smartypants != 0 {\n\t\tr.sr.Process(w, []byte(r.Title))\n\t} else {\n\t\tescapeHTML(w, []byte(r.Title))\n\t}\n\tio.WriteString(w, \"</title>\\n\")\n\tio.WriteString(w, \"  <meta name=\\\"GENERATOR\\\" content=\\\"Blackfriday Markdown Processor v\")\n\tio.WriteString(w, Version)\n\tio.WriteString(w, \"\\\"\")\n\tio.WriteString(w, ending)\n\tio.WriteString(w, \">\\n\")\n\tio.WriteString(w, \"  <meta charset=\\\"utf-8\\\"\")\n\tio.WriteString(w, ending)\n\tio.WriteString(w, \">\\n\")\n\tif r.CSS != \"\" {\n\t\tio.WriteString(w, \"  <link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"\")\n\t\tescapeHTML(w, []byte(r.CSS))\n\t\tio.WriteString(w, \"\\\"\")\n\t\tio.WriteString(w, ending)\n\t\tio.WriteString(w, \">\\n\")\n\t}\n\tif r.Icon != \"\" {\n\t\tio.WriteString(w, \"  <link rel=\\\"icon\\\" type=\\\"image/x-icon\\\" href=\\\"\")\n\t\tescapeHTML(w, []byte(r.Icon))\n\t\tio.WriteString(w, \"\\\"\")\n\t\tio.WriteString(w, ending)\n\t\tio.WriteString(w, \">\\n\")\n\t}\n\tio.WriteString(w, \"</head>\\n\")\n\tio.WriteString(w, \"<body>\\n\\n\")\n}\n\nfunc (r *HTMLRenderer) writeTOC(w io.Writer, ast *Node) {\n\tbuf := bytes.Buffer{}\n\n\tinHeading := false\n\ttocLevel := 0\n\theadingCount := 0\n\n\tast.Walk(func(node *Node, entering bool) WalkStatus {\n\t\tif node.Type == Heading && !node.HeadingData.IsTitleblock {\n\t\t\tinHeading = entering\n\t\t\tif entering {\n\t\t\t\tnode.HeadingID = fmt.Sprintf(\"toc_%d\", headingCount)\n\t\t\t\tif node.Level == tocLevel {\n\t\t\t\t\tbuf.WriteString(\"</li>\\n\\n<li>\")\n\t\t\t\t} else if node.Level < tocLevel {\n\t\t\t\t\tfor node.Level < tocLevel {\n\t\t\t\t\t\ttocLevel--\n\t\t\t\t\t\tbuf.WriteString(\"</li>\\n</ul>\")\n\t\t\t\t\t}\n\t\t\t\t\tbuf.WriteString(\"</li>\\n\\n<li>\")\n\t\t\t\t} else {\n\t\t\t\t\tfor node.Level > tocLevel {\n\t\t\t\t\t\ttocLevel++\n\t\t\t\t\t\tbuf.WriteString(\"\\n<ul>\\n<li>\")\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfmt.Fprintf(&buf, `<a href=\"#toc_%d\">`, headingCount)\n\t\t\t\theadingCount++\n\t\t\t} else {\n\t\t\t\tbuf.WriteString(\"</a>\")\n\t\t\t}\n\t\t\treturn GoToNext\n\t\t}\n\n\t\tif inHeading {\n\t\t\treturn r.RenderNode(&buf, node, entering)\n\t\t}\n\n\t\treturn GoToNext\n\t})\n\n\tfor ; tocLevel > 0; tocLevel-- {\n\t\tbuf.WriteString(\"</li>\\n</ul>\")\n\t}\n\n\tif buf.Len() > 0 {\n\t\tio.WriteString(w, \"<nav>\\n\")\n\t\tw.Write(buf.Bytes())\n\t\tio.WriteString(w, \"\\n\\n</nav>\\n\")\n\t}\n\tr.lastOutputLen = buf.Len()\n}\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/inline.go",
    "content": "//\n// Blackfriday Markdown Processor\n// Available at http://github.com/russross/blackfriday\n//\n// Copyright © 2011 Russ Ross <russ@russross.com>.\n// Distributed under the Simplified BSD License.\n// See README.md for details.\n//\n\n//\n// Functions to parse inline elements.\n//\n\npackage blackfriday\n\nimport (\n\t\"bytes\"\n\t\"regexp\"\n\t\"strconv\"\n)\n\nvar (\n\turlRe    = `((https?|ftp):\\/\\/|\\/)[-A-Za-z0-9+&@#\\/%?=~_|!:,.;\\(\\)]+`\n\tanchorRe = regexp.MustCompile(`^(<a\\shref=\"` + urlRe + `\"(\\stitle=\"[^\"<>]+\")?\\s?>` + urlRe + `<\\/a>)`)\n\n\t// https://www.w3.org/TR/html5/syntax.html#character-references\n\t// highest unicode code point in 17 planes (2^20): 1,114,112d =\n\t// 7 dec digits or 6 hex digits\n\t// named entity references can be 2-31 characters with stuff like &lt;\n\t// at one end and &CounterClockwiseContourIntegral; at the other. There\n\t// are also sometimes numbers at the end, although this isn't inherent\n\t// in the specification; there are never numbers anywhere else in\n\t// current character references, though; see &frac34; and &blk12;, etc.\n\t// https://www.w3.org/TR/html5/syntax.html#named-character-references\n\t//\n\t// entity := \"&\" (named group | number ref) \";\"\n\t// named group := [a-zA-Z]{2,31}[0-9]{0,2}\n\t// number ref := \"#\" (dec ref | hex ref)\n\t// dec ref := [0-9]{1,7}\n\t// hex ref := (\"x\" | \"X\") [0-9a-fA-F]{1,6}\n\thtmlEntityRe = regexp.MustCompile(`&([a-zA-Z]{2,31}[0-9]{0,2}|#([0-9]{1,7}|[xX][0-9a-fA-F]{1,6}));`)\n)\n\n// Functions to parse text within a block\n// Each function returns the number of chars taken care of\n// data is the complete block being rendered\n// offset is the number of valid chars before the current cursor\n\nfunc (p *Markdown) inline(currBlock *Node, data []byte) {\n\t// handlers might call us recursively: enforce a maximum depth\n\tif p.nesting >= p.maxNesting || len(data) == 0 {\n\t\treturn\n\t}\n\tp.nesting++\n\tbeg, end := 0, 0\n\tfor end < len(data) {\n\t\thandler := p.inlineCallback[data[end]]\n\t\tif handler != nil {\n\t\t\tif consumed, node := handler(p, data, end); consumed == 0 {\n\t\t\t\t// No action from the callback.\n\t\t\t\tend++\n\t\t\t} else {\n\t\t\t\t// Copy inactive chars into the output.\n\t\t\t\tcurrBlock.AppendChild(text(data[beg:end]))\n\t\t\t\tif node != nil {\n\t\t\t\t\tcurrBlock.AppendChild(node)\n\t\t\t\t}\n\t\t\t\t// Skip past whatever the callback used.\n\t\t\t\tbeg = end + consumed\n\t\t\t\tend = beg\n\t\t\t}\n\t\t} else {\n\t\t\tend++\n\t\t}\n\t}\n\tif beg < len(data) {\n\t\tif data[end-1] == '\\n' {\n\t\t\tend--\n\t\t}\n\t\tcurrBlock.AppendChild(text(data[beg:end]))\n\t}\n\tp.nesting--\n}\n\n// single and double emphasis parsing\nfunc emphasis(p *Markdown, data []byte, offset int) (int, *Node) {\n\tdata = data[offset:]\n\tc := data[0]\n\n\tif len(data) > 2 && data[1] != c {\n\t\t// whitespace cannot follow an opening emphasis;\n\t\t// strikethrough only takes two characters '~~'\n\t\tif c == '~' || isspace(data[1]) {\n\t\t\treturn 0, nil\n\t\t}\n\t\tret, node := helperEmphasis(p, data[1:], c)\n\t\tif ret == 0 {\n\t\t\treturn 0, nil\n\t\t}\n\n\t\treturn ret + 1, node\n\t}\n\n\tif len(data) > 3 && data[1] == c && data[2] != c {\n\t\tif isspace(data[2]) {\n\t\t\treturn 0, nil\n\t\t}\n\t\tret, node := helperDoubleEmphasis(p, data[2:], c)\n\t\tif ret == 0 {\n\t\t\treturn 0, nil\n\t\t}\n\n\t\treturn ret + 2, node\n\t}\n\n\tif len(data) > 4 && data[1] == c && data[2] == c && data[3] != c {\n\t\tif c == '~' || isspace(data[3]) {\n\t\t\treturn 0, nil\n\t\t}\n\t\tret, node := helperTripleEmphasis(p, data, 3, c)\n\t\tif ret == 0 {\n\t\t\treturn 0, nil\n\t\t}\n\n\t\treturn ret + 3, node\n\t}\n\n\treturn 0, nil\n}\n\nfunc codeSpan(p *Markdown, data []byte, offset int) (int, *Node) {\n\tdata = data[offset:]\n\n\tnb := 0\n\n\t// count the number of backticks in the delimiter\n\tfor nb < len(data) && data[nb] == '`' {\n\t\tnb++\n\t}\n\n\t// find the next delimiter\n\ti, end := 0, 0\n\tfor end = nb; end < len(data) && i < nb; end++ {\n\t\tif data[end] == '`' {\n\t\t\ti++\n\t\t} else {\n\t\t\ti = 0\n\t\t}\n\t}\n\n\t// no matching delimiter?\n\tif i < nb && end >= len(data) {\n\t\treturn 0, nil\n\t}\n\n\t// trim outside whitespace\n\tfBegin := nb\n\tfor fBegin < end && data[fBegin] == ' ' {\n\t\tfBegin++\n\t}\n\n\tfEnd := end - nb\n\tfor fEnd > fBegin && data[fEnd-1] == ' ' {\n\t\tfEnd--\n\t}\n\n\t// render the code span\n\tif fBegin != fEnd {\n\t\tcode := NewNode(Code)\n\t\tcode.Literal = data[fBegin:fEnd]\n\t\treturn end, code\n\t}\n\n\treturn end, nil\n}\n\n// newline preceded by two spaces becomes <br>\nfunc maybeLineBreak(p *Markdown, data []byte, offset int) (int, *Node) {\n\torigOffset := offset\n\tfor offset < len(data) && data[offset] == ' ' {\n\t\toffset++\n\t}\n\n\tif offset < len(data) && data[offset] == '\\n' {\n\t\tif offset-origOffset >= 2 {\n\t\t\treturn offset - origOffset + 1, NewNode(Hardbreak)\n\t\t}\n\t\treturn offset - origOffset, nil\n\t}\n\treturn 0, nil\n}\n\n// newline without two spaces works when HardLineBreak is enabled\nfunc lineBreak(p *Markdown, data []byte, offset int) (int, *Node) {\n\tif p.extensions&HardLineBreak != 0 {\n\t\treturn 1, NewNode(Hardbreak)\n\t}\n\treturn 0, nil\n}\n\ntype linkType int\n\nconst (\n\tlinkNormal linkType = iota\n\tlinkImg\n\tlinkDeferredFootnote\n\tlinkInlineFootnote\n)\n\nfunc isReferenceStyleLink(data []byte, pos int, t linkType) bool {\n\tif t == linkDeferredFootnote {\n\t\treturn false\n\t}\n\treturn pos < len(data)-1 && data[pos] == '[' && data[pos+1] != '^'\n}\n\nfunc maybeImage(p *Markdown, data []byte, offset int) (int, *Node) {\n\tif offset < len(data)-1 && data[offset+1] == '[' {\n\t\treturn link(p, data, offset)\n\t}\n\treturn 0, nil\n}\n\nfunc maybeInlineFootnote(p *Markdown, data []byte, offset int) (int, *Node) {\n\tif offset < len(data)-1 && data[offset+1] == '[' {\n\t\treturn link(p, data, offset)\n\t}\n\treturn 0, nil\n}\n\n// '[': parse a link or an image or a footnote\nfunc link(p *Markdown, data []byte, offset int) (int, *Node) {\n\t// no links allowed inside regular links, footnote, and deferred footnotes\n\tif p.insideLink && (offset > 0 && data[offset-1] == '[' || len(data)-1 > offset && data[offset+1] == '^') {\n\t\treturn 0, nil\n\t}\n\n\tvar t linkType\n\tswitch {\n\t// special case: ![^text] == deferred footnote (that follows something with\n\t// an exclamation point)\n\tcase p.extensions&Footnotes != 0 && len(data)-1 > offset && data[offset+1] == '^':\n\t\tt = linkDeferredFootnote\n\t// ![alt] == image\n\tcase offset >= 0 && data[offset] == '!':\n\t\tt = linkImg\n\t\toffset++\n\t// ^[text] == inline footnote\n\t// [^refId] == deferred footnote\n\tcase p.extensions&Footnotes != 0:\n\t\tif offset >= 0 && data[offset] == '^' {\n\t\t\tt = linkInlineFootnote\n\t\t\toffset++\n\t\t} else if len(data)-1 > offset && data[offset+1] == '^' {\n\t\t\tt = linkDeferredFootnote\n\t\t}\n\t// [text] == regular link\n\tdefault:\n\t\tt = linkNormal\n\t}\n\n\tdata = data[offset:]\n\n\tvar (\n\t\ti                       = 1\n\t\tnoteID                  int\n\t\ttitle, link, altContent []byte\n\t\ttextHasNl               = false\n\t)\n\n\tif t == linkDeferredFootnote {\n\t\ti++\n\t}\n\n\t// look for the matching closing bracket\n\tfor level := 1; level > 0 && i < len(data); i++ {\n\t\tswitch {\n\t\tcase data[i] == '\\n':\n\t\t\ttextHasNl = true\n\n\t\tcase isBackslashEscaped(data, i):\n\t\t\tcontinue\n\n\t\tcase data[i] == '[':\n\t\t\tlevel++\n\n\t\tcase data[i] == ']':\n\t\t\tlevel--\n\t\t\tif level <= 0 {\n\t\t\t\ti-- // compensate for extra i++ in for loop\n\t\t\t}\n\t\t}\n\t}\n\n\tif i >= len(data) {\n\t\treturn 0, nil\n\t}\n\n\ttxtE := i\n\ti++\n\tvar footnoteNode *Node\n\n\t// skip any amount of whitespace or newline\n\t// (this is much more lax than original markdown syntax)\n\tfor i < len(data) && isspace(data[i]) {\n\t\ti++\n\t}\n\n\t// inline style link\n\tswitch {\n\tcase i < len(data) && data[i] == '(':\n\t\t// skip initial whitespace\n\t\ti++\n\n\t\tfor i < len(data) && isspace(data[i]) {\n\t\t\ti++\n\t\t}\n\n\t\tlinkB := i\n\n\t\t// look for link end: ' \" )\n\tfindlinkend:\n\t\tfor i < len(data) {\n\t\t\tswitch {\n\t\t\tcase data[i] == '\\\\':\n\t\t\t\ti += 2\n\n\t\t\tcase data[i] == ')' || data[i] == '\\'' || data[i] == '\"':\n\t\t\t\tbreak findlinkend\n\n\t\t\tdefault:\n\t\t\t\ti++\n\t\t\t}\n\t\t}\n\n\t\tif i >= len(data) {\n\t\t\treturn 0, nil\n\t\t}\n\t\tlinkE := i\n\n\t\t// look for title end if present\n\t\ttitleB, titleE := 0, 0\n\t\tif data[i] == '\\'' || data[i] == '\"' {\n\t\t\ti++\n\t\t\ttitleB = i\n\n\t\tfindtitleend:\n\t\t\tfor i < len(data) {\n\t\t\t\tswitch {\n\t\t\t\tcase data[i] == '\\\\':\n\t\t\t\t\ti += 2\n\n\t\t\t\tcase data[i] == ')':\n\t\t\t\t\tbreak findtitleend\n\n\t\t\t\tdefault:\n\t\t\t\t\ti++\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif i >= len(data) {\n\t\t\t\treturn 0, nil\n\t\t\t}\n\n\t\t\t// skip whitespace after title\n\t\t\ttitleE = i - 1\n\t\t\tfor titleE > titleB && isspace(data[titleE]) {\n\t\t\t\ttitleE--\n\t\t\t}\n\n\t\t\t// check for closing quote presence\n\t\t\tif data[titleE] != '\\'' && data[titleE] != '\"' {\n\t\t\t\ttitleB, titleE = 0, 0\n\t\t\t\tlinkE = i\n\t\t\t}\n\t\t}\n\n\t\t// remove whitespace at the end of the link\n\t\tfor linkE > linkB && isspace(data[linkE-1]) {\n\t\t\tlinkE--\n\t\t}\n\n\t\t// remove optional angle brackets around the link\n\t\tif data[linkB] == '<' {\n\t\t\tlinkB++\n\t\t}\n\t\tif data[linkE-1] == '>' {\n\t\t\tlinkE--\n\t\t}\n\n\t\t// build escaped link and title\n\t\tif linkE > linkB {\n\t\t\tlink = data[linkB:linkE]\n\t\t}\n\n\t\tif titleE > titleB {\n\t\t\ttitle = data[titleB:titleE]\n\t\t}\n\n\t\ti++\n\n\t// reference style link\n\tcase isReferenceStyleLink(data, i, t):\n\t\tvar id []byte\n\t\taltContentConsidered := false\n\n\t\t// look for the id\n\t\ti++\n\t\tlinkB := i\n\t\tfor i < len(data) && data[i] != ']' {\n\t\t\ti++\n\t\t}\n\t\tif i >= len(data) {\n\t\t\treturn 0, nil\n\t\t}\n\t\tlinkE := i\n\n\t\t// find the reference\n\t\tif linkB == linkE {\n\t\t\tif textHasNl {\n\t\t\t\tvar b bytes.Buffer\n\n\t\t\t\tfor j := 1; j < txtE; j++ {\n\t\t\t\t\tswitch {\n\t\t\t\t\tcase data[j] != '\\n':\n\t\t\t\t\t\tb.WriteByte(data[j])\n\t\t\t\t\tcase data[j-1] != ' ':\n\t\t\t\t\t\tb.WriteByte(' ')\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tid = b.Bytes()\n\t\t\t} else {\n\t\t\t\tid = data[1:txtE]\n\t\t\t\taltContentConsidered = true\n\t\t\t}\n\t\t} else {\n\t\t\tid = data[linkB:linkE]\n\t\t}\n\n\t\t// find the reference with matching id\n\t\tlr, ok := p.getRef(string(id))\n\t\tif !ok {\n\t\t\treturn 0, nil\n\t\t}\n\n\t\t// keep link and title from reference\n\t\tlink = lr.link\n\t\ttitle = lr.title\n\t\tif altContentConsidered {\n\t\t\taltContent = lr.text\n\t\t}\n\t\ti++\n\n\t// shortcut reference style link or reference or inline footnote\n\tdefault:\n\t\tvar id []byte\n\n\t\t// craft the id\n\t\tif textHasNl {\n\t\t\tvar b bytes.Buffer\n\n\t\t\tfor j := 1; j < txtE; j++ {\n\t\t\t\tswitch {\n\t\t\t\tcase data[j] != '\\n':\n\t\t\t\t\tb.WriteByte(data[j])\n\t\t\t\tcase data[j-1] != ' ':\n\t\t\t\t\tb.WriteByte(' ')\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tid = b.Bytes()\n\t\t} else {\n\t\t\tif t == linkDeferredFootnote {\n\t\t\t\tid = data[2:txtE] // get rid of the ^\n\t\t\t} else {\n\t\t\t\tid = data[1:txtE]\n\t\t\t}\n\t\t}\n\n\t\tfootnoteNode = NewNode(Item)\n\t\tif t == linkInlineFootnote {\n\t\t\t// create a new reference\n\t\t\tnoteID = len(p.notes) + 1\n\n\t\t\tvar fragment []byte\n\t\t\tif len(id) > 0 {\n\t\t\t\tif len(id) < 16 {\n\t\t\t\t\tfragment = make([]byte, len(id))\n\t\t\t\t} else {\n\t\t\t\t\tfragment = make([]byte, 16)\n\t\t\t\t}\n\t\t\t\tcopy(fragment, slugify(id))\n\t\t\t} else {\n\t\t\t\tfragment = append([]byte(\"footnote-\"), []byte(strconv.Itoa(noteID))...)\n\t\t\t}\n\n\t\t\tref := &reference{\n\t\t\t\tnoteID:   noteID,\n\t\t\t\thasBlock: false,\n\t\t\t\tlink:     fragment,\n\t\t\t\ttitle:    id,\n\t\t\t\tfootnote: footnoteNode,\n\t\t\t}\n\n\t\t\tp.notes = append(p.notes, ref)\n\n\t\t\tlink = ref.link\n\t\t\ttitle = ref.title\n\t\t} else {\n\t\t\t// find the reference with matching id\n\t\t\tlr, ok := p.getRef(string(id))\n\t\t\tif !ok {\n\t\t\t\treturn 0, nil\n\t\t\t}\n\n\t\t\tif t == linkDeferredFootnote {\n\t\t\t\tlr.noteID = len(p.notes) + 1\n\t\t\t\tlr.footnote = footnoteNode\n\t\t\t\tp.notes = append(p.notes, lr)\n\t\t\t}\n\n\t\t\t// keep link and title from reference\n\t\t\tlink = lr.link\n\t\t\t// if inline footnote, title == footnote contents\n\t\t\ttitle = lr.title\n\t\t\tnoteID = lr.noteID\n\t\t}\n\n\t\t// rewind the whitespace\n\t\ti = txtE + 1\n\t}\n\n\tvar uLink []byte\n\tif t == linkNormal || t == linkImg {\n\t\tif len(link) > 0 {\n\t\t\tvar uLinkBuf bytes.Buffer\n\t\t\tunescapeText(&uLinkBuf, link)\n\t\t\tuLink = uLinkBuf.Bytes()\n\t\t}\n\n\t\t// links need something to click on and somewhere to go\n\t\tif len(uLink) == 0 || (t == linkNormal && txtE <= 1) {\n\t\t\treturn 0, nil\n\t\t}\n\t}\n\n\t// call the relevant rendering function\n\tvar linkNode *Node\n\tswitch t {\n\tcase linkNormal:\n\t\tlinkNode = NewNode(Link)\n\t\tlinkNode.Destination = normalizeURI(uLink)\n\t\tlinkNode.Title = title\n\t\tif len(altContent) > 0 {\n\t\t\tlinkNode.AppendChild(text(altContent))\n\t\t} else {\n\t\t\t// links cannot contain other links, so turn off link parsing\n\t\t\t// temporarily and recurse\n\t\t\tinsideLink := p.insideLink\n\t\t\tp.insideLink = true\n\t\t\tp.inline(linkNode, data[1:txtE])\n\t\t\tp.insideLink = insideLink\n\t\t}\n\n\tcase linkImg:\n\t\tlinkNode = NewNode(Image)\n\t\tlinkNode.Destination = uLink\n\t\tlinkNode.Title = title\n\t\tlinkNode.AppendChild(text(data[1:txtE]))\n\t\ti++\n\n\tcase linkInlineFootnote, linkDeferredFootnote:\n\t\tlinkNode = NewNode(Link)\n\t\tlinkNode.Destination = link\n\t\tlinkNode.Title = title\n\t\tlinkNode.NoteID = noteID\n\t\tlinkNode.Footnote = footnoteNode\n\t\tif t == linkInlineFootnote {\n\t\t\ti++\n\t\t}\n\n\tdefault:\n\t\treturn 0, nil\n\t}\n\n\treturn i, linkNode\n}\n\nfunc (p *Markdown) inlineHTMLComment(data []byte) int {\n\tif len(data) < 5 {\n\t\treturn 0\n\t}\n\tif data[0] != '<' || data[1] != '!' || data[2] != '-' || data[3] != '-' {\n\t\treturn 0\n\t}\n\ti := 5\n\t// scan for an end-of-comment marker, across lines if necessary\n\tfor i < len(data) && !(data[i-2] == '-' && data[i-1] == '-' && data[i] == '>') {\n\t\ti++\n\t}\n\t// no end-of-comment marker\n\tif i >= len(data) {\n\t\treturn 0\n\t}\n\treturn i + 1\n}\n\nfunc stripMailto(link []byte) []byte {\n\tif bytes.HasPrefix(link, []byte(\"mailto://\")) {\n\t\treturn link[9:]\n\t} else if bytes.HasPrefix(link, []byte(\"mailto:\")) {\n\t\treturn link[7:]\n\t} else {\n\t\treturn link\n\t}\n}\n\n// autolinkType specifies a kind of autolink that gets detected.\ntype autolinkType int\n\n// These are the possible flag values for the autolink renderer.\nconst (\n\tnotAutolink autolinkType = iota\n\tnormalAutolink\n\temailAutolink\n)\n\n// '<' when tags or autolinks are allowed\nfunc leftAngle(p *Markdown, data []byte, offset int) (int, *Node) {\n\tdata = data[offset:]\n\taltype, end := tagLength(data)\n\tif size := p.inlineHTMLComment(data); size > 0 {\n\t\tend = size\n\t}\n\tif end > 2 {\n\t\tif altype != notAutolink {\n\t\t\tvar uLink bytes.Buffer\n\t\t\tunescapeText(&uLink, data[1:end+1-2])\n\t\t\tif uLink.Len() > 0 {\n\t\t\t\tlink := uLink.Bytes()\n\t\t\t\tnode := NewNode(Link)\n\t\t\t\tnode.Destination = link\n\t\t\t\tif altype == emailAutolink {\n\t\t\t\t\tnode.Destination = append([]byte(\"mailto:\"), link...)\n\t\t\t\t}\n\t\t\t\tnode.AppendChild(text(stripMailto(link)))\n\t\t\t\treturn end, node\n\t\t\t}\n\t\t} else {\n\t\t\thtmlTag := NewNode(HTMLSpan)\n\t\t\thtmlTag.Literal = data[:end]\n\t\t\treturn end, htmlTag\n\t\t}\n\t}\n\n\treturn end, nil\n}\n\n// '\\\\' backslash escape\nvar escapeChars = []byte(\"\\\\`*_{}[]()#+-.!:|&<>~\")\n\nfunc escape(p *Markdown, data []byte, offset int) (int, *Node) {\n\tdata = data[offset:]\n\n\tif len(data) > 1 {\n\t\tif p.extensions&BackslashLineBreak != 0 && data[1] == '\\n' {\n\t\t\treturn 2, NewNode(Hardbreak)\n\t\t}\n\t\tif bytes.IndexByte(escapeChars, data[1]) < 0 {\n\t\t\treturn 0, nil\n\t\t}\n\n\t\treturn 2, text(data[1:2])\n\t}\n\n\treturn 2, nil\n}\n\nfunc unescapeText(ob *bytes.Buffer, src []byte) {\n\ti := 0\n\tfor i < len(src) {\n\t\torg := i\n\t\tfor i < len(src) && src[i] != '\\\\' {\n\t\t\ti++\n\t\t}\n\n\t\tif i > org {\n\t\t\tob.Write(src[org:i])\n\t\t}\n\n\t\tif i+1 >= len(src) {\n\t\t\tbreak\n\t\t}\n\n\t\tob.WriteByte(src[i+1])\n\t\ti += 2\n\t}\n}\n\n// '&' escaped when it doesn't belong to an entity\n// valid entities are assumed to be anything matching &#?[A-Za-z0-9]+;\nfunc entity(p *Markdown, data []byte, offset int) (int, *Node) {\n\tdata = data[offset:]\n\n\tend := 1\n\n\tif end < len(data) && data[end] == '#' {\n\t\tend++\n\t}\n\n\tfor end < len(data) && isalnum(data[end]) {\n\t\tend++\n\t}\n\n\tif end < len(data) && data[end] == ';' {\n\t\tend++ // real entity\n\t} else {\n\t\treturn 0, nil // lone '&'\n\t}\n\n\tent := data[:end]\n\t// undo &amp; escaping or it will be converted to &amp;amp; by another\n\t// escaper in the renderer\n\tif bytes.Equal(ent, []byte(\"&amp;\")) {\n\t\tent = []byte{'&'}\n\t}\n\n\treturn end, text(ent)\n}\n\nfunc linkEndsWithEntity(data []byte, linkEnd int) bool {\n\tentityRanges := htmlEntityRe.FindAllIndex(data[:linkEnd], -1)\n\treturn entityRanges != nil && entityRanges[len(entityRanges)-1][1] == linkEnd\n}\n\n// hasPrefixCaseInsensitive is a custom implementation of\n//     strings.HasPrefix(strings.ToLower(s), prefix)\n// we rolled our own because ToLower pulls in a huge machinery of lowercasing\n// anything from Unicode and that's very slow. Since this func will only be\n// used on ASCII protocol prefixes, we can take shortcuts.\nfunc hasPrefixCaseInsensitive(s, prefix []byte) bool {\n\tif len(s) < len(prefix) {\n\t\treturn false\n\t}\n\tdelta := byte('a' - 'A')\n\tfor i, b := range prefix {\n\t\tif b != s[i] && b != s[i]+delta {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nvar protocolPrefixes = [][]byte{\n\t[]byte(\"http://\"),\n\t[]byte(\"https://\"),\n\t[]byte(\"ftp://\"),\n\t[]byte(\"file://\"),\n\t[]byte(\"mailto:\"),\n}\n\nconst shortestPrefix = 6 // len(\"ftp://\"), the shortest of the above\n\nfunc maybeAutoLink(p *Markdown, data []byte, offset int) (int, *Node) {\n\t// quick check to rule out most false hits\n\tif p.insideLink || len(data) < offset+shortestPrefix {\n\t\treturn 0, nil\n\t}\n\tfor _, prefix := range protocolPrefixes {\n\t\tendOfHead := offset + 8 // 8 is the len() of the longest prefix\n\t\tif endOfHead > len(data) {\n\t\t\tendOfHead = len(data)\n\t\t}\n\t\tif hasPrefixCaseInsensitive(data[offset:endOfHead], prefix) {\n\t\t\treturn autoLink(p, data, offset)\n\t\t}\n\t}\n\treturn 0, nil\n}\n\nfunc autoLink(p *Markdown, data []byte, offset int) (int, *Node) {\n\t// Now a more expensive check to see if we're not inside an anchor element\n\tanchorStart := offset\n\toffsetFromAnchor := 0\n\tfor anchorStart > 0 && data[anchorStart] != '<' {\n\t\tanchorStart--\n\t\toffsetFromAnchor++\n\t}\n\n\tanchorStr := anchorRe.Find(data[anchorStart:])\n\tif anchorStr != nil {\n\t\tanchorClose := NewNode(HTMLSpan)\n\t\tanchorClose.Literal = anchorStr[offsetFromAnchor:]\n\t\treturn len(anchorStr) - offsetFromAnchor, anchorClose\n\t}\n\n\t// scan backward for a word boundary\n\trewind := 0\n\tfor offset-rewind > 0 && rewind <= 7 && isletter(data[offset-rewind-1]) {\n\t\trewind++\n\t}\n\tif rewind > 6 { // longest supported protocol is \"mailto\" which has 6 letters\n\t\treturn 0, nil\n\t}\n\n\torigData := data\n\tdata = data[offset-rewind:]\n\n\tif !isSafeLink(data) {\n\t\treturn 0, nil\n\t}\n\n\tlinkEnd := 0\n\tfor linkEnd < len(data) && !isEndOfLink(data[linkEnd]) {\n\t\tlinkEnd++\n\t}\n\n\t// Skip punctuation at the end of the link\n\tif (data[linkEnd-1] == '.' || data[linkEnd-1] == ',') && data[linkEnd-2] != '\\\\' {\n\t\tlinkEnd--\n\t}\n\n\t// But don't skip semicolon if it's a part of escaped entity:\n\tif data[linkEnd-1] == ';' && data[linkEnd-2] != '\\\\' && !linkEndsWithEntity(data, linkEnd) {\n\t\tlinkEnd--\n\t}\n\n\t// See if the link finishes with a punctuation sign that can be closed.\n\tvar copen byte\n\tswitch data[linkEnd-1] {\n\tcase '\"':\n\t\tcopen = '\"'\n\tcase '\\'':\n\t\tcopen = '\\''\n\tcase ')':\n\t\tcopen = '('\n\tcase ']':\n\t\tcopen = '['\n\tcase '}':\n\t\tcopen = '{'\n\tdefault:\n\t\tcopen = 0\n\t}\n\n\tif copen != 0 {\n\t\tbufEnd := offset - rewind + linkEnd - 2\n\n\t\topenDelim := 1\n\n\t\t/* Try to close the final punctuation sign in this same line;\n\t\t * if we managed to close it outside of the URL, that means that it's\n\t\t * not part of the URL. If it closes inside the URL, that means it\n\t\t * is part of the URL.\n\t\t *\n\t\t * Examples:\n\t\t *\n\t\t *      foo http://www.pokemon.com/Pikachu_(Electric) bar\n\t\t *              => http://www.pokemon.com/Pikachu_(Electric)\n\t\t *\n\t\t *      foo (http://www.pokemon.com/Pikachu_(Electric)) bar\n\t\t *              => http://www.pokemon.com/Pikachu_(Electric)\n\t\t *\n\t\t *      foo http://www.pokemon.com/Pikachu_(Electric)) bar\n\t\t *              => http://www.pokemon.com/Pikachu_(Electric))\n\t\t *\n\t\t *      (foo http://www.pokemon.com/Pikachu_(Electric)) bar\n\t\t *              => foo http://www.pokemon.com/Pikachu_(Electric)\n\t\t */\n\n\t\tfor bufEnd >= 0 && origData[bufEnd] != '\\n' && openDelim != 0 {\n\t\t\tif origData[bufEnd] == data[linkEnd-1] {\n\t\t\t\topenDelim++\n\t\t\t}\n\n\t\t\tif origData[bufEnd] == copen {\n\t\t\t\topenDelim--\n\t\t\t}\n\n\t\t\tbufEnd--\n\t\t}\n\n\t\tif openDelim == 0 {\n\t\t\tlinkEnd--\n\t\t}\n\t}\n\n\tvar uLink bytes.Buffer\n\tunescapeText(&uLink, data[:linkEnd])\n\n\tif uLink.Len() > 0 {\n\t\tnode := NewNode(Link)\n\t\tnode.Destination = uLink.Bytes()\n\t\tnode.AppendChild(text(uLink.Bytes()))\n\t\treturn linkEnd, node\n\t}\n\n\treturn linkEnd, nil\n}\n\nfunc isEndOfLink(char byte) bool {\n\treturn isspace(char) || char == '<'\n}\n\nvar validUris = [][]byte{[]byte(\"http://\"), []byte(\"https://\"), []byte(\"ftp://\"), []byte(\"mailto://\")}\nvar validPaths = [][]byte{[]byte(\"/\"), []byte(\"./\"), []byte(\"../\")}\n\nfunc isSafeLink(link []byte) bool {\n\tfor _, path := range validPaths {\n\t\tif len(link) >= len(path) && bytes.Equal(link[:len(path)], path) {\n\t\t\tif len(link) == len(path) {\n\t\t\t\treturn true\n\t\t\t} else if isalnum(link[len(path)]) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\n\tfor _, prefix := range validUris {\n\t\t// TODO: handle unicode here\n\t\t// case-insensitive prefix test\n\t\tif len(link) > len(prefix) && bytes.Equal(bytes.ToLower(link[:len(prefix)]), prefix) && isalnum(link[len(prefix)]) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\n// return the length of the given tag, or 0 is it's not valid\nfunc tagLength(data []byte) (autolink autolinkType, end int) {\n\tvar i, j int\n\n\t// a valid tag can't be shorter than 3 chars\n\tif len(data) < 3 {\n\t\treturn notAutolink, 0\n\t}\n\n\t// begins with a '<' optionally followed by '/', followed by letter or number\n\tif data[0] != '<' {\n\t\treturn notAutolink, 0\n\t}\n\tif data[1] == '/' {\n\t\ti = 2\n\t} else {\n\t\ti = 1\n\t}\n\n\tif !isalnum(data[i]) {\n\t\treturn notAutolink, 0\n\t}\n\n\t// scheme test\n\tautolink = notAutolink\n\n\t// try to find the beginning of an URI\n\tfor i < len(data) && (isalnum(data[i]) || data[i] == '.' || data[i] == '+' || data[i] == '-') {\n\t\ti++\n\t}\n\n\tif i > 1 && i < len(data) && data[i] == '@' {\n\t\tif j = isMailtoAutoLink(data[i:]); j != 0 {\n\t\t\treturn emailAutolink, i + j\n\t\t}\n\t}\n\n\tif i > 2 && i < len(data) && data[i] == ':' {\n\t\tautolink = normalAutolink\n\t\ti++\n\t}\n\n\t// complete autolink test: no whitespace or ' or \"\n\tswitch {\n\tcase i >= len(data):\n\t\tautolink = notAutolink\n\tcase autolink != notAutolink:\n\t\tj = i\n\n\t\tfor i < len(data) {\n\t\t\tif data[i] == '\\\\' {\n\t\t\t\ti += 2\n\t\t\t} else if data[i] == '>' || data[i] == '\\'' || data[i] == '\"' || isspace(data[i]) {\n\t\t\t\tbreak\n\t\t\t} else {\n\t\t\t\ti++\n\t\t\t}\n\n\t\t}\n\n\t\tif i >= len(data) {\n\t\t\treturn autolink, 0\n\t\t}\n\t\tif i > j && data[i] == '>' {\n\t\t\treturn autolink, i + 1\n\t\t}\n\n\t\t// one of the forbidden chars has been found\n\t\tautolink = notAutolink\n\t}\n\ti += bytes.IndexByte(data[i:], '>')\n\tif i < 0 {\n\t\treturn autolink, 0\n\t}\n\treturn autolink, i + 1\n}\n\n// look for the address part of a mail autolink and '>'\n// this is less strict than the original markdown e-mail address matching\nfunc isMailtoAutoLink(data []byte) int {\n\tnb := 0\n\n\t// address is assumed to be: [-@._a-zA-Z0-9]+ with exactly one '@'\n\tfor i := 0; i < len(data); i++ {\n\t\tif isalnum(data[i]) {\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch data[i] {\n\t\tcase '@':\n\t\t\tnb++\n\n\t\tcase '-', '.', '_':\n\t\t\tbreak\n\n\t\tcase '>':\n\t\t\tif nb == 1 {\n\t\t\t\treturn i + 1\n\t\t\t}\n\t\t\treturn 0\n\t\tdefault:\n\t\t\treturn 0\n\t\t}\n\t}\n\n\treturn 0\n}\n\n// look for the next emph char, skipping other constructs\nfunc helperFindEmphChar(data []byte, c byte) int {\n\ti := 0\n\n\tfor i < len(data) {\n\t\tfor i < len(data) && data[i] != c && data[i] != '`' && data[i] != '[' {\n\t\t\ti++\n\t\t}\n\t\tif i >= len(data) {\n\t\t\treturn 0\n\t\t}\n\t\t// do not count escaped chars\n\t\tif i != 0 && data[i-1] == '\\\\' {\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\t\tif data[i] == c {\n\t\t\treturn i\n\t\t}\n\n\t\tif data[i] == '`' {\n\t\t\t// skip a code span\n\t\t\ttmpI := 0\n\t\t\ti++\n\t\t\tfor i < len(data) && data[i] != '`' {\n\t\t\t\tif tmpI == 0 && data[i] == c {\n\t\t\t\t\ttmpI = i\n\t\t\t\t}\n\t\t\t\ti++\n\t\t\t}\n\t\t\tif i >= len(data) {\n\t\t\t\treturn tmpI\n\t\t\t}\n\t\t\ti++\n\t\t} else if data[i] == '[' {\n\t\t\t// skip a link\n\t\t\ttmpI := 0\n\t\t\ti++\n\t\t\tfor i < len(data) && data[i] != ']' {\n\t\t\t\tif tmpI == 0 && data[i] == c {\n\t\t\t\t\ttmpI = i\n\t\t\t\t}\n\t\t\t\ti++\n\t\t\t}\n\t\t\ti++\n\t\t\tfor i < len(data) && (data[i] == ' ' || data[i] == '\\n') {\n\t\t\t\ti++\n\t\t\t}\n\t\t\tif i >= len(data) {\n\t\t\t\treturn tmpI\n\t\t\t}\n\t\t\tif data[i] != '[' && data[i] != '(' { // not a link\n\t\t\t\tif tmpI > 0 {\n\t\t\t\t\treturn tmpI\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcc := data[i]\n\t\t\ti++\n\t\t\tfor i < len(data) && data[i] != cc {\n\t\t\t\tif tmpI == 0 && data[i] == c {\n\t\t\t\t\treturn i\n\t\t\t\t}\n\t\t\t\ti++\n\t\t\t}\n\t\t\tif i >= len(data) {\n\t\t\t\treturn tmpI\n\t\t\t}\n\t\t\ti++\n\t\t}\n\t}\n\treturn 0\n}\n\nfunc helperEmphasis(p *Markdown, data []byte, c byte) (int, *Node) {\n\ti := 0\n\n\t// skip one symbol if coming from emph3\n\tif len(data) > 1 && data[0] == c && data[1] == c {\n\t\ti = 1\n\t}\n\n\tfor i < len(data) {\n\t\tlength := helperFindEmphChar(data[i:], c)\n\t\tif length == 0 {\n\t\t\treturn 0, nil\n\t\t}\n\t\ti += length\n\t\tif i >= len(data) {\n\t\t\treturn 0, nil\n\t\t}\n\n\t\tif i+1 < len(data) && data[i+1] == c {\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\n\t\tif data[i] == c && !isspace(data[i-1]) {\n\n\t\t\tif p.extensions&NoIntraEmphasis != 0 {\n\t\t\t\tif !(i+1 == len(data) || isspace(data[i+1]) || ispunct(data[i+1])) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\temph := NewNode(Emph)\n\t\t\tp.inline(emph, data[:i])\n\t\t\treturn i + 1, emph\n\t\t}\n\t}\n\n\treturn 0, nil\n}\n\nfunc helperDoubleEmphasis(p *Markdown, data []byte, c byte) (int, *Node) {\n\ti := 0\n\n\tfor i < len(data) {\n\t\tlength := helperFindEmphChar(data[i:], c)\n\t\tif length == 0 {\n\t\t\treturn 0, nil\n\t\t}\n\t\ti += length\n\n\t\tif i+1 < len(data) && data[i] == c && data[i+1] == c && i > 0 && !isspace(data[i-1]) {\n\t\t\tnodeType := Strong\n\t\t\tif c == '~' {\n\t\t\t\tnodeType = Del\n\t\t\t}\n\t\t\tnode := NewNode(nodeType)\n\t\t\tp.inline(node, data[:i])\n\t\t\treturn i + 2, node\n\t\t}\n\t\ti++\n\t}\n\treturn 0, nil\n}\n\nfunc helperTripleEmphasis(p *Markdown, data []byte, offset int, c byte) (int, *Node) {\n\ti := 0\n\torigData := data\n\tdata = data[offset:]\n\n\tfor i < len(data) {\n\t\tlength := helperFindEmphChar(data[i:], c)\n\t\tif length == 0 {\n\t\t\treturn 0, nil\n\t\t}\n\t\ti += length\n\n\t\t// skip whitespace preceded symbols\n\t\tif data[i] != c || isspace(data[i-1]) {\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch {\n\t\tcase i+2 < len(data) && data[i+1] == c && data[i+2] == c:\n\t\t\t// triple symbol found\n\t\t\tstrong := NewNode(Strong)\n\t\t\tem := NewNode(Emph)\n\t\t\tstrong.AppendChild(em)\n\t\t\tp.inline(em, data[:i])\n\t\t\treturn i + 3, strong\n\t\tcase (i+1 < len(data) && data[i+1] == c):\n\t\t\t// double symbol found, hand over to emph1\n\t\t\tlength, node := helperEmphasis(p, origData[offset-2:], c)\n\t\t\tif length == 0 {\n\t\t\t\treturn 0, nil\n\t\t\t}\n\t\t\treturn length - 2, node\n\t\tdefault:\n\t\t\t// single symbol found, hand over to emph2\n\t\t\tlength, node := helperDoubleEmphasis(p, origData[offset-1:], c)\n\t\t\tif length == 0 {\n\t\t\t\treturn 0, nil\n\t\t\t}\n\t\t\treturn length - 1, node\n\t\t}\n\t}\n\treturn 0, nil\n}\n\nfunc text(s []byte) *Node {\n\tnode := NewNode(Text)\n\tnode.Literal = s\n\treturn node\n}\n\nfunc normalizeURI(s []byte) []byte {\n\treturn s // TODO: implement\n}\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/markdown.go",
    "content": "// Blackfriday Markdown Processor\n// Available at http://github.com/russross/blackfriday\n//\n// Copyright © 2011 Russ Ross <russ@russross.com>.\n// Distributed under the Simplified BSD License.\n// See README.md for details.\n\npackage blackfriday\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\n//\n// Markdown parsing and processing\n//\n\n// Version string of the package. Appears in the rendered document when\n// CompletePage flag is on.\nconst Version = \"2.0\"\n\n// Extensions is a bitwise or'ed collection of enabled Blackfriday's\n// extensions.\ntype Extensions int\n\n// These are the supported markdown parsing extensions.\n// OR these values together to select multiple extensions.\nconst (\n\tNoExtensions           Extensions = 0\n\tNoIntraEmphasis        Extensions = 1 << iota // Ignore emphasis markers inside words\n\tTables                                        // Render tables\n\tFencedCode                                    // Render fenced code blocks\n\tAutolink                                      // Detect embedded URLs that are not explicitly marked\n\tStrikethrough                                 // Strikethrough text using ~~test~~\n\tLaxHTMLBlocks                                 // Loosen up HTML block parsing rules\n\tSpaceHeadings                                 // Be strict about prefix heading rules\n\tHardLineBreak                                 // Translate newlines into line breaks\n\tTabSizeEight                                  // Expand tabs to eight spaces instead of four\n\tFootnotes                                     // Pandoc-style footnotes\n\tNoEmptyLineBeforeBlock                        // No need to insert an empty line to start a (code, quote, ordered list, unordered list) block\n\tHeadingIDs                                    // specify heading IDs  with {#id}\n\tTitleblock                                    // Titleblock ala pandoc\n\tAutoHeadingIDs                                // Create the heading ID from the text\n\tBackslashLineBreak                            // Translate trailing backslashes into line breaks\n\tDefinitionLists                               // Render definition lists\n\n\tCommonHTMLFlags HTMLFlags = UseXHTML | Smartypants |\n\t\tSmartypantsFractions | SmartypantsDashes | SmartypantsLatexDashes\n\n\tCommonExtensions Extensions = NoIntraEmphasis | Tables | FencedCode |\n\t\tAutolink | Strikethrough | SpaceHeadings | HeadingIDs |\n\t\tBackslashLineBreak | DefinitionLists\n)\n\n// ListType contains bitwise or'ed flags for list and list item objects.\ntype ListType int\n\n// These are the possible flag values for the ListItem renderer.\n// Multiple flag values may be ORed together.\n// These are mostly of interest if you are writing a new output format.\nconst (\n\tListTypeOrdered ListType = 1 << iota\n\tListTypeDefinition\n\tListTypeTerm\n\n\tListItemContainsBlock\n\tListItemBeginningOfList // TODO: figure out if this is of any use now\n\tListItemEndOfList\n)\n\n// CellAlignFlags holds a type of alignment in a table cell.\ntype CellAlignFlags int\n\n// These are the possible flag values for the table cell renderer.\n// Only a single one of these values will be used; they are not ORed together.\n// These are mostly of interest if you are writing a new output format.\nconst (\n\tTableAlignmentLeft CellAlignFlags = 1 << iota\n\tTableAlignmentRight\n\tTableAlignmentCenter = (TableAlignmentLeft | TableAlignmentRight)\n)\n\n// The size of a tab stop.\nconst (\n\tTabSizeDefault = 4\n\tTabSizeDouble  = 8\n)\n\n// blockTags is a set of tags that are recognized as HTML block tags.\n// Any of these can be included in markdown text without special escaping.\nvar blockTags = map[string]struct{}{\n\t\"blockquote\": {},\n\t\"del\":        {},\n\t\"div\":        {},\n\t\"dl\":         {},\n\t\"fieldset\":   {},\n\t\"form\":       {},\n\t\"h1\":         {},\n\t\"h2\":         {},\n\t\"h3\":         {},\n\t\"h4\":         {},\n\t\"h5\":         {},\n\t\"h6\":         {},\n\t\"iframe\":     {},\n\t\"ins\":        {},\n\t\"math\":       {},\n\t\"noscript\":   {},\n\t\"ol\":         {},\n\t\"pre\":        {},\n\t\"p\":          {},\n\t\"script\":     {},\n\t\"style\":      {},\n\t\"table\":      {},\n\t\"ul\":         {},\n\n\t// HTML5\n\t\"address\":    {},\n\t\"article\":    {},\n\t\"aside\":      {},\n\t\"canvas\":     {},\n\t\"figcaption\": {},\n\t\"figure\":     {},\n\t\"footer\":     {},\n\t\"header\":     {},\n\t\"hgroup\":     {},\n\t\"main\":       {},\n\t\"nav\":        {},\n\t\"output\":     {},\n\t\"progress\":   {},\n\t\"section\":    {},\n\t\"video\":      {},\n}\n\n// Renderer is the rendering interface. This is mostly of interest if you are\n// implementing a new rendering format.\n//\n// Only an HTML implementation is provided in this repository, see the README\n// for external implementations.\ntype Renderer interface {\n\t// RenderNode is the main rendering method. It will be called once for\n\t// every leaf node and twice for every non-leaf node (first with\n\t// entering=true, then with entering=false). The method should write its\n\t// rendition of the node to the supplied writer w.\n\tRenderNode(w io.Writer, node *Node, entering bool) WalkStatus\n\n\t// RenderHeader is a method that allows the renderer to produce some\n\t// content preceding the main body of the output document. The header is\n\t// understood in the broad sense here. For example, the default HTML\n\t// renderer will write not only the HTML document preamble, but also the\n\t// table of contents if it was requested.\n\t//\n\t// The method will be passed an entire document tree, in case a particular\n\t// implementation needs to inspect it to produce output.\n\t//\n\t// The output should be written to the supplied writer w. If your\n\t// implementation has no header to write, supply an empty implementation.\n\tRenderHeader(w io.Writer, ast *Node)\n\n\t// RenderFooter is a symmetric counterpart of RenderHeader.\n\tRenderFooter(w io.Writer, ast *Node)\n}\n\n// Callback functions for inline parsing. One such function is defined\n// for each character that triggers a response when parsing inline data.\ntype inlineParser func(p *Markdown, data []byte, offset int) (int, *Node)\n\n// Markdown is a type that holds extensions and the runtime state used by\n// Parse, and the renderer. You can not use it directly, construct it with New.\ntype Markdown struct {\n\trenderer          Renderer\n\treferenceOverride ReferenceOverrideFunc\n\trefs              map[string]*reference\n\tinlineCallback    [256]inlineParser\n\textensions        Extensions\n\tnesting           int\n\tmaxNesting        int\n\tinsideLink        bool\n\n\t// Footnotes need to be ordered as well as available to quickly check for\n\t// presence. If a ref is also a footnote, it's stored both in refs and here\n\t// in notes. Slice is nil if footnotes not enabled.\n\tnotes []*reference\n\n\tdoc                  *Node\n\ttip                  *Node // = doc\n\toldTip               *Node\n\tlastMatchedContainer *Node // = doc\n\tallClosed            bool\n}\n\nfunc (p *Markdown) getRef(refid string) (ref *reference, found bool) {\n\tif p.referenceOverride != nil {\n\t\tr, overridden := p.referenceOverride(refid)\n\t\tif overridden {\n\t\t\tif r == nil {\n\t\t\t\treturn nil, false\n\t\t\t}\n\t\t\treturn &reference{\n\t\t\t\tlink:     []byte(r.Link),\n\t\t\t\ttitle:    []byte(r.Title),\n\t\t\t\tnoteID:   0,\n\t\t\t\thasBlock: false,\n\t\t\t\ttext:     []byte(r.Text)}, true\n\t\t}\n\t}\n\t// refs are case insensitive\n\tref, found = p.refs[strings.ToLower(refid)]\n\treturn ref, found\n}\n\nfunc (p *Markdown) finalize(block *Node) {\n\tabove := block.Parent\n\tblock.open = false\n\tp.tip = above\n}\n\nfunc (p *Markdown) addChild(node NodeType, offset uint32) *Node {\n\treturn p.addExistingChild(NewNode(node), offset)\n}\n\nfunc (p *Markdown) addExistingChild(node *Node, offset uint32) *Node {\n\tfor !p.tip.canContain(node.Type) {\n\t\tp.finalize(p.tip)\n\t}\n\tp.tip.AppendChild(node)\n\tp.tip = node\n\treturn node\n}\n\nfunc (p *Markdown) closeUnmatchedBlocks() {\n\tif !p.allClosed {\n\t\tfor p.oldTip != p.lastMatchedContainer {\n\t\t\tparent := p.oldTip.Parent\n\t\t\tp.finalize(p.oldTip)\n\t\t\tp.oldTip = parent\n\t\t}\n\t\tp.allClosed = true\n\t}\n}\n\n//\n//\n// Public interface\n//\n//\n\n// Reference represents the details of a link.\n// See the documentation in Options for more details on use-case.\ntype Reference struct {\n\t// Link is usually the URL the reference points to.\n\tLink string\n\t// Title is the alternate text describing the link in more detail.\n\tTitle string\n\t// Text is the optional text to override the ref with if the syntax used was\n\t// [refid][]\n\tText string\n}\n\n// ReferenceOverrideFunc is expected to be called with a reference string and\n// return either a valid Reference type that the reference string maps to or\n// nil. If overridden is false, the default reference logic will be executed.\n// See the documentation in Options for more details on use-case.\ntype ReferenceOverrideFunc func(reference string) (ref *Reference, overridden bool)\n\n// New constructs a Markdown processor. You can use the same With* functions as\n// for Run() to customize parser's behavior and the renderer.\nfunc New(opts ...Option) *Markdown {\n\tvar p Markdown\n\tfor _, opt := range opts {\n\t\topt(&p)\n\t}\n\tp.refs = make(map[string]*reference)\n\tp.maxNesting = 16\n\tp.insideLink = false\n\tdocNode := NewNode(Document)\n\tp.doc = docNode\n\tp.tip = docNode\n\tp.oldTip = docNode\n\tp.lastMatchedContainer = docNode\n\tp.allClosed = true\n\t// register inline parsers\n\tp.inlineCallback[' '] = maybeLineBreak\n\tp.inlineCallback['*'] = emphasis\n\tp.inlineCallback['_'] = emphasis\n\tif p.extensions&Strikethrough != 0 {\n\t\tp.inlineCallback['~'] = emphasis\n\t}\n\tp.inlineCallback['`'] = codeSpan\n\tp.inlineCallback['\\n'] = lineBreak\n\tp.inlineCallback['['] = link\n\tp.inlineCallback['<'] = leftAngle\n\tp.inlineCallback['\\\\'] = escape\n\tp.inlineCallback['&'] = entity\n\tp.inlineCallback['!'] = maybeImage\n\tp.inlineCallback['^'] = maybeInlineFootnote\n\tif p.extensions&Autolink != 0 {\n\t\tp.inlineCallback['h'] = maybeAutoLink\n\t\tp.inlineCallback['m'] = maybeAutoLink\n\t\tp.inlineCallback['f'] = maybeAutoLink\n\t\tp.inlineCallback['H'] = maybeAutoLink\n\t\tp.inlineCallback['M'] = maybeAutoLink\n\t\tp.inlineCallback['F'] = maybeAutoLink\n\t}\n\tif p.extensions&Footnotes != 0 {\n\t\tp.notes = make([]*reference, 0)\n\t}\n\treturn &p\n}\n\n// Option customizes the Markdown processor's default behavior.\ntype Option func(*Markdown)\n\n// WithRenderer allows you to override the default renderer.\nfunc WithRenderer(r Renderer) Option {\n\treturn func(p *Markdown) {\n\t\tp.renderer = r\n\t}\n}\n\n// WithExtensions allows you to pick some of the many extensions provided by\n// Blackfriday. You can bitwise OR them.\nfunc WithExtensions(e Extensions) Option {\n\treturn func(p *Markdown) {\n\t\tp.extensions = e\n\t}\n}\n\n// WithNoExtensions turns off all extensions and custom behavior.\nfunc WithNoExtensions() Option {\n\treturn func(p *Markdown) {\n\t\tp.extensions = NoExtensions\n\t\tp.renderer = NewHTMLRenderer(HTMLRendererParameters{\n\t\t\tFlags: HTMLFlagsNone,\n\t\t})\n\t}\n}\n\n// WithRefOverride sets an optional function callback that is called every\n// time a reference is resolved.\n//\n// In Markdown, the link reference syntax can be made to resolve a link to\n// a reference instead of an inline URL, in one of the following ways:\n//\n//  * [link text][refid]\n//  * [refid][]\n//\n// Usually, the refid is defined at the bottom of the Markdown document. If\n// this override function is provided, the refid is passed to the override\n// function first, before consulting the defined refids at the bottom. If\n// the override function indicates an override did not occur, the refids at\n// the bottom will be used to fill in the link details.\nfunc WithRefOverride(o ReferenceOverrideFunc) Option {\n\treturn func(p *Markdown) {\n\t\tp.referenceOverride = o\n\t}\n}\n\n// Run is the main entry point to Blackfriday. It parses and renders a\n// block of markdown-encoded text.\n//\n// The simplest invocation of Run takes one argument, input:\n//     output := Run(input)\n// This will parse the input with CommonExtensions enabled and render it with\n// the default HTMLRenderer (with CommonHTMLFlags).\n//\n// Variadic arguments opts can customize the default behavior. Since Markdown\n// type does not contain exported fields, you can not use it directly. Instead,\n// use the With* functions. For example, this will call the most basic\n// functionality, with no extensions:\n//     output := Run(input, WithNoExtensions())\n//\n// You can use any number of With* arguments, even contradicting ones. They\n// will be applied in order of appearance and the latter will override the\n// former:\n//     output := Run(input, WithNoExtensions(), WithExtensions(exts),\n//         WithRenderer(yourRenderer))\nfunc Run(input []byte, opts ...Option) []byte {\n\tr := NewHTMLRenderer(HTMLRendererParameters{\n\t\tFlags: CommonHTMLFlags,\n\t})\n\toptList := []Option{WithRenderer(r), WithExtensions(CommonExtensions)}\n\toptList = append(optList, opts...)\n\tparser := New(optList...)\n\tast := parser.Parse(input)\n\tvar buf bytes.Buffer\n\tparser.renderer.RenderHeader(&buf, ast)\n\tast.Walk(func(node *Node, entering bool) WalkStatus {\n\t\treturn parser.renderer.RenderNode(&buf, node, entering)\n\t})\n\tparser.renderer.RenderFooter(&buf, ast)\n\treturn buf.Bytes()\n}\n\n// Parse is an entry point to the parsing part of Blackfriday. It takes an\n// input markdown document and produces a syntax tree for its contents. This\n// tree can then be rendered with a default or custom renderer, or\n// analyzed/transformed by the caller to whatever non-standard needs they have.\n// The return value is the root node of the syntax tree.\nfunc (p *Markdown) Parse(input []byte) *Node {\n\tp.block(input)\n\t// Walk the tree and finish up some of unfinished blocks\n\tfor p.tip != nil {\n\t\tp.finalize(p.tip)\n\t}\n\t// Walk the tree again and process inline markdown in each block\n\tp.doc.Walk(func(node *Node, entering bool) WalkStatus {\n\t\tif node.Type == Paragraph || node.Type == Heading || node.Type == TableCell {\n\t\t\tp.inline(node, node.content)\n\t\t\tnode.content = nil\n\t\t}\n\t\treturn GoToNext\n\t})\n\tp.parseRefsToAST()\n\treturn p.doc\n}\n\nfunc (p *Markdown) parseRefsToAST() {\n\tif p.extensions&Footnotes == 0 || len(p.notes) == 0 {\n\t\treturn\n\t}\n\tp.tip = p.doc\n\tblock := p.addBlock(List, nil)\n\tblock.IsFootnotesList = true\n\tblock.ListFlags = ListTypeOrdered\n\tflags := ListItemBeginningOfList\n\t// Note: this loop is intentionally explicit, not range-form. This is\n\t// because the body of the loop will append nested footnotes to p.notes and\n\t// we need to process those late additions. Range form would only walk over\n\t// the fixed initial set.\n\tfor i := 0; i < len(p.notes); i++ {\n\t\tref := p.notes[i]\n\t\tp.addExistingChild(ref.footnote, 0)\n\t\tblock := ref.footnote\n\t\tblock.ListFlags = flags | ListTypeOrdered\n\t\tblock.RefLink = ref.link\n\t\tif ref.hasBlock {\n\t\t\tflags |= ListItemContainsBlock\n\t\t\tp.block(ref.title)\n\t\t} else {\n\t\t\tp.inline(block, ref.title)\n\t\t}\n\t\tflags &^= ListItemBeginningOfList | ListItemContainsBlock\n\t}\n\tabove := block.Parent\n\tfinalizeList(block)\n\tp.tip = above\n\tblock.Walk(func(node *Node, entering bool) WalkStatus {\n\t\tif node.Type == Paragraph || node.Type == Heading {\n\t\t\tp.inline(node, node.content)\n\t\t\tnode.content = nil\n\t\t}\n\t\treturn GoToNext\n\t})\n}\n\n//\n// Link references\n//\n// This section implements support for references that (usually) appear\n// as footnotes in a document, and can be referenced anywhere in the document.\n// The basic format is:\n//\n//    [1]: http://www.google.com/ \"Google\"\n//    [2]: http://www.github.com/ \"Github\"\n//\n// Anywhere in the document, the reference can be linked by referring to its\n// label, i.e., 1 and 2 in this example, as in:\n//\n//    This library is hosted on [Github][2], a git hosting site.\n//\n// Actual footnotes as specified in Pandoc and supported by some other Markdown\n// libraries such as php-markdown are also taken care of. They look like this:\n//\n//    This sentence needs a bit of further explanation.[^note]\n//\n//    [^note]: This is the explanation.\n//\n// Footnotes should be placed at the end of the document in an ordered list.\n// Finally, there are inline footnotes such as:\n//\n//    Inline footnotes^[Also supported.] provide a quick inline explanation,\n//    but are rendered at the bottom of the document.\n//\n\n// reference holds all information necessary for a reference-style links or\n// footnotes.\n//\n// Consider this markdown with reference-style links:\n//\n//     [link][ref]\n//\n//     [ref]: /url/ \"tooltip title\"\n//\n// It will be ultimately converted to this HTML:\n//\n//     <p><a href=\\\"/url/\\\" title=\\\"title\\\">link</a></p>\n//\n// And a reference structure will be populated as follows:\n//\n//     p.refs[\"ref\"] = &reference{\n//         link: \"/url/\",\n//         title: \"tooltip title\",\n//     }\n//\n// Alternatively, reference can contain information about a footnote. Consider\n// this markdown:\n//\n//     Text needing a footnote.[^a]\n//\n//     [^a]: This is the note\n//\n// A reference structure will be populated as follows:\n//\n//     p.refs[\"a\"] = &reference{\n//         link: \"a\",\n//         title: \"This is the note\",\n//         noteID: <some positive int>,\n//     }\n//\n// TODO: As you can see, it begs for splitting into two dedicated structures\n// for refs and for footnotes.\ntype reference struct {\n\tlink     []byte\n\ttitle    []byte\n\tnoteID   int // 0 if not a footnote ref\n\thasBlock bool\n\tfootnote *Node // a link to the Item node within a list of footnotes\n\n\ttext []byte // only gets populated by refOverride feature with Reference.Text\n}\n\nfunc (r *reference) String() string {\n\treturn fmt.Sprintf(\"{link: %q, title: %q, text: %q, noteID: %d, hasBlock: %v}\",\n\t\tr.link, r.title, r.text, r.noteID, r.hasBlock)\n}\n\n// Check whether or not data starts with a reference link.\n// If so, it is parsed and stored in the list of references\n// (in the render struct).\n// Returns the number of bytes to skip to move past it,\n// or zero if the first line is not a reference.\nfunc isReference(p *Markdown, data []byte, tabSize int) int {\n\t// up to 3 optional leading spaces\n\tif len(data) < 4 {\n\t\treturn 0\n\t}\n\ti := 0\n\tfor i < 3 && data[i] == ' ' {\n\t\ti++\n\t}\n\n\tnoteID := 0\n\n\t// id part: anything but a newline between brackets\n\tif data[i] != '[' {\n\t\treturn 0\n\t}\n\ti++\n\tif p.extensions&Footnotes != 0 {\n\t\tif i < len(data) && data[i] == '^' {\n\t\t\t// we can set it to anything here because the proper noteIds will\n\t\t\t// be assigned later during the second pass. It just has to be != 0\n\t\t\tnoteID = 1\n\t\t\ti++\n\t\t}\n\t}\n\tidOffset := i\n\tfor i < len(data) && data[i] != '\\n' && data[i] != '\\r' && data[i] != ']' {\n\t\ti++\n\t}\n\tif i >= len(data) || data[i] != ']' {\n\t\treturn 0\n\t}\n\tidEnd := i\n\t// footnotes can have empty ID, like this: [^], but a reference can not be\n\t// empty like this: []. Break early if it's not a footnote and there's no ID\n\tif noteID == 0 && idOffset == idEnd {\n\t\treturn 0\n\t}\n\t// spacer: colon (space | tab)* newline? (space | tab)*\n\ti++\n\tif i >= len(data) || data[i] != ':' {\n\t\treturn 0\n\t}\n\ti++\n\tfor i < len(data) && (data[i] == ' ' || data[i] == '\\t') {\n\t\ti++\n\t}\n\tif i < len(data) && (data[i] == '\\n' || data[i] == '\\r') {\n\t\ti++\n\t\tif i < len(data) && data[i] == '\\n' && data[i-1] == '\\r' {\n\t\t\ti++\n\t\t}\n\t}\n\tfor i < len(data) && (data[i] == ' ' || data[i] == '\\t') {\n\t\ti++\n\t}\n\tif i >= len(data) {\n\t\treturn 0\n\t}\n\n\tvar (\n\t\tlinkOffset, linkEnd   int\n\t\ttitleOffset, titleEnd int\n\t\tlineEnd               int\n\t\traw                   []byte\n\t\thasBlock              bool\n\t)\n\n\tif p.extensions&Footnotes != 0 && noteID != 0 {\n\t\tlinkOffset, linkEnd, raw, hasBlock = scanFootnote(p, data, i, tabSize)\n\t\tlineEnd = linkEnd\n\t} else {\n\t\tlinkOffset, linkEnd, titleOffset, titleEnd, lineEnd = scanLinkRef(p, data, i)\n\t}\n\tif lineEnd == 0 {\n\t\treturn 0\n\t}\n\n\t// a valid ref has been found\n\n\tref := &reference{\n\t\tnoteID:   noteID,\n\t\thasBlock: hasBlock,\n\t}\n\n\tif noteID > 0 {\n\t\t// reusing the link field for the id since footnotes don't have links\n\t\tref.link = data[idOffset:idEnd]\n\t\t// if footnote, it's not really a title, it's the contained text\n\t\tref.title = raw\n\t} else {\n\t\tref.link = data[linkOffset:linkEnd]\n\t\tref.title = data[titleOffset:titleEnd]\n\t}\n\n\t// id matches are case-insensitive\n\tid := string(bytes.ToLower(data[idOffset:idEnd]))\n\n\tp.refs[id] = ref\n\n\treturn lineEnd\n}\n\nfunc scanLinkRef(p *Markdown, data []byte, i int) (linkOffset, linkEnd, titleOffset, titleEnd, lineEnd int) {\n\t// link: whitespace-free sequence, optionally between angle brackets\n\tif data[i] == '<' {\n\t\ti++\n\t}\n\tlinkOffset = i\n\tfor i < len(data) && data[i] != ' ' && data[i] != '\\t' && data[i] != '\\n' && data[i] != '\\r' {\n\t\ti++\n\t}\n\tlinkEnd = i\n\tif data[linkOffset] == '<' && data[linkEnd-1] == '>' {\n\t\tlinkOffset++\n\t\tlinkEnd--\n\t}\n\n\t// optional spacer: (space | tab)* (newline | '\\'' | '\"' | '(' )\n\tfor i < len(data) && (data[i] == ' ' || data[i] == '\\t') {\n\t\ti++\n\t}\n\tif i < len(data) && data[i] != '\\n' && data[i] != '\\r' && data[i] != '\\'' && data[i] != '\"' && data[i] != '(' {\n\t\treturn\n\t}\n\n\t// compute end-of-line\n\tif i >= len(data) || data[i] == '\\r' || data[i] == '\\n' {\n\t\tlineEnd = i\n\t}\n\tif i+1 < len(data) && data[i] == '\\r' && data[i+1] == '\\n' {\n\t\tlineEnd++\n\t}\n\n\t// optional (space|tab)* spacer after a newline\n\tif lineEnd > 0 {\n\t\ti = lineEnd + 1\n\t\tfor i < len(data) && (data[i] == ' ' || data[i] == '\\t') {\n\t\t\ti++\n\t\t}\n\t}\n\n\t// optional title: any non-newline sequence enclosed in '\"() alone on its line\n\tif i+1 < len(data) && (data[i] == '\\'' || data[i] == '\"' || data[i] == '(') {\n\t\ti++\n\t\ttitleOffset = i\n\n\t\t// look for EOL\n\t\tfor i < len(data) && data[i] != '\\n' && data[i] != '\\r' {\n\t\t\ti++\n\t\t}\n\t\tif i+1 < len(data) && data[i] == '\\n' && data[i+1] == '\\r' {\n\t\t\ttitleEnd = i + 1\n\t\t} else {\n\t\t\ttitleEnd = i\n\t\t}\n\n\t\t// step back\n\t\ti--\n\t\tfor i > titleOffset && (data[i] == ' ' || data[i] == '\\t') {\n\t\t\ti--\n\t\t}\n\t\tif i > titleOffset && (data[i] == '\\'' || data[i] == '\"' || data[i] == ')') {\n\t\t\tlineEnd = titleEnd\n\t\t\ttitleEnd = i\n\t\t}\n\t}\n\n\treturn\n}\n\n// The first bit of this logic is the same as Parser.listItem, but the rest\n// is much simpler. This function simply finds the entire block and shifts it\n// over by one tab if it is indeed a block (just returns the line if it's not).\n// blockEnd is the end of the section in the input buffer, and contents is the\n// extracted text that was shifted over one tab. It will need to be rendered at\n// the end of the document.\nfunc scanFootnote(p *Markdown, data []byte, i, indentSize int) (blockStart, blockEnd int, contents []byte, hasBlock bool) {\n\tif i == 0 || len(data) == 0 {\n\t\treturn\n\t}\n\n\t// skip leading whitespace on first line\n\tfor i < len(data) && data[i] == ' ' {\n\t\ti++\n\t}\n\n\tblockStart = i\n\n\t// find the end of the line\n\tblockEnd = i\n\tfor i < len(data) && data[i-1] != '\\n' {\n\t\ti++\n\t}\n\n\t// get working buffer\n\tvar raw bytes.Buffer\n\n\t// put the first line into the working buffer\n\traw.Write(data[blockEnd:i])\n\tblockEnd = i\n\n\t// process the following lines\n\tcontainsBlankLine := false\n\ngatherLines:\n\tfor blockEnd < len(data) {\n\t\ti++\n\n\t\t// find the end of this line\n\t\tfor i < len(data) && data[i-1] != '\\n' {\n\t\t\ti++\n\t\t}\n\n\t\t// if it is an empty line, guess that it is part of this item\n\t\t// and move on to the next line\n\t\tif p.isEmpty(data[blockEnd:i]) > 0 {\n\t\t\tcontainsBlankLine = true\n\t\t\tblockEnd = i\n\t\t\tcontinue\n\t\t}\n\n\t\tn := 0\n\t\tif n = isIndented(data[blockEnd:i], indentSize); n == 0 {\n\t\t\t// this is the end of the block.\n\t\t\t// we don't want to include this last line in the index.\n\t\t\tbreak gatherLines\n\t\t}\n\n\t\t// if there were blank lines before this one, insert a new one now\n\t\tif containsBlankLine {\n\t\t\traw.WriteByte('\\n')\n\t\t\tcontainsBlankLine = false\n\t\t}\n\n\t\t// get rid of that first tab, write to buffer\n\t\traw.Write(data[blockEnd+n : i])\n\t\thasBlock = true\n\n\t\tblockEnd = i\n\t}\n\n\tif data[blockEnd-1] != '\\n' {\n\t\traw.WriteByte('\\n')\n\t}\n\n\tcontents = raw.Bytes()\n\n\treturn\n}\n\n//\n//\n// Miscellaneous helper functions\n//\n//\n\n// Test if a character is a punctuation symbol.\n// Taken from a private function in regexp in the stdlib.\nfunc ispunct(c byte) bool {\n\tfor _, r := range []byte(\"!\\\"#$%&'()*+,-./:;<=>?@[\\\\]^_`{|}~\") {\n\t\tif c == r {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Test if a character is a whitespace character.\nfunc isspace(c byte) bool {\n\treturn ishorizontalspace(c) || isverticalspace(c)\n}\n\n// Test if a character is a horizontal whitespace character.\nfunc ishorizontalspace(c byte) bool {\n\treturn c == ' ' || c == '\\t'\n}\n\n// Test if a character is a vertical character.\nfunc isverticalspace(c byte) bool {\n\treturn c == '\\n' || c == '\\r' || c == '\\f' || c == '\\v'\n}\n\n// Test if a character is letter.\nfunc isletter(c byte) bool {\n\treturn (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')\n}\n\n// Test if a character is a letter or a digit.\n// TODO: check when this is looking for ASCII alnum and when it should use unicode\nfunc isalnum(c byte) bool {\n\treturn (c >= '0' && c <= '9') || isletter(c)\n}\n\n// Replace tab characters with spaces, aligning to the next TAB_SIZE column.\n// always ends output with a newline\nfunc expandTabs(out *bytes.Buffer, line []byte, tabSize int) {\n\t// first, check for common cases: no tabs, or only tabs at beginning of line\n\ti, prefix := 0, 0\n\tslowcase := false\n\tfor i = 0; i < len(line); i++ {\n\t\tif line[i] == '\\t' {\n\t\t\tif prefix == i {\n\t\t\t\tprefix++\n\t\t\t} else {\n\t\t\t\tslowcase = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\t// no need to decode runes if all tabs are at the beginning of the line\n\tif !slowcase {\n\t\tfor i = 0; i < prefix*tabSize; i++ {\n\t\t\tout.WriteByte(' ')\n\t\t}\n\t\tout.Write(line[prefix:])\n\t\treturn\n\t}\n\n\t// the slow case: we need to count runes to figure out how\n\t// many spaces to insert for each tab\n\tcolumn := 0\n\ti = 0\n\tfor i < len(line) {\n\t\tstart := i\n\t\tfor i < len(line) && line[i] != '\\t' {\n\t\t\t_, size := utf8.DecodeRune(line[i:])\n\t\t\ti += size\n\t\t\tcolumn++\n\t\t}\n\n\t\tif i > start {\n\t\t\tout.Write(line[start:i])\n\t\t}\n\n\t\tif i >= len(line) {\n\t\t\tbreak\n\t\t}\n\n\t\tfor {\n\t\t\tout.WriteByte(' ')\n\t\t\tcolumn++\n\t\t\tif column%tabSize == 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\ti++\n\t}\n}\n\n// Find if a line counts as indented or not.\n// Returns number of characters the indent is (0 = not indented).\nfunc isIndented(data []byte, indentSize int) int {\n\tif len(data) == 0 {\n\t\treturn 0\n\t}\n\tif data[0] == '\\t' {\n\t\treturn 1\n\t}\n\tif len(data) < indentSize {\n\t\treturn 0\n\t}\n\tfor i := 0; i < indentSize; i++ {\n\t\tif data[i] != ' ' {\n\t\t\treturn 0\n\t\t}\n\t}\n\treturn indentSize\n}\n\n// Create a url-safe slug for fragments\nfunc slugify(in []byte) []byte {\n\tif len(in) == 0 {\n\t\treturn in\n\t}\n\tout := make([]byte, 0, len(in))\n\tsym := false\n\n\tfor _, ch := range in {\n\t\tif isalnum(ch) {\n\t\t\tsym = false\n\t\t\tout = append(out, ch)\n\t\t} else if sym {\n\t\t\tcontinue\n\t\t} else {\n\t\t\tout = append(out, '-')\n\t\t\tsym = true\n\t\t}\n\t}\n\tvar a, b int\n\tvar ch byte\n\tfor a, ch = range out {\n\t\tif ch != '-' {\n\t\t\tbreak\n\t\t}\n\t}\n\tfor b = len(out) - 1; b > 0; b-- {\n\t\tif out[b] != '-' {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn out[a : b+1]\n}\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/node.go",
    "content": "package blackfriday\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n)\n\n// NodeType specifies a type of a single node of a syntax tree. Usually one\n// node (and its type) corresponds to a single markdown feature, e.g. emphasis\n// or code block.\ntype NodeType int\n\n// Constants for identifying different types of nodes. See NodeType.\nconst (\n\tDocument NodeType = iota\n\tBlockQuote\n\tList\n\tItem\n\tParagraph\n\tHeading\n\tHorizontalRule\n\tEmph\n\tStrong\n\tDel\n\tLink\n\tImage\n\tText\n\tHTMLBlock\n\tCodeBlock\n\tSoftbreak\n\tHardbreak\n\tCode\n\tHTMLSpan\n\tTable\n\tTableCell\n\tTableHead\n\tTableBody\n\tTableRow\n)\n\nvar nodeTypeNames = []string{\n\tDocument:       \"Document\",\n\tBlockQuote:     \"BlockQuote\",\n\tList:           \"List\",\n\tItem:           \"Item\",\n\tParagraph:      \"Paragraph\",\n\tHeading:        \"Heading\",\n\tHorizontalRule: \"HorizontalRule\",\n\tEmph:           \"Emph\",\n\tStrong:         \"Strong\",\n\tDel:            \"Del\",\n\tLink:           \"Link\",\n\tImage:          \"Image\",\n\tText:           \"Text\",\n\tHTMLBlock:      \"HTMLBlock\",\n\tCodeBlock:      \"CodeBlock\",\n\tSoftbreak:      \"Softbreak\",\n\tHardbreak:      \"Hardbreak\",\n\tCode:           \"Code\",\n\tHTMLSpan:       \"HTMLSpan\",\n\tTable:          \"Table\",\n\tTableCell:      \"TableCell\",\n\tTableHead:      \"TableHead\",\n\tTableBody:      \"TableBody\",\n\tTableRow:       \"TableRow\",\n}\n\nfunc (t NodeType) String() string {\n\treturn nodeTypeNames[t]\n}\n\n// ListData contains fields relevant to a List and Item node type.\ntype ListData struct {\n\tListFlags       ListType\n\tTight           bool   // Skip <p>s around list item data if true\n\tBulletChar      byte   // '*', '+' or '-' in bullet lists\n\tDelimiter       byte   // '.' or ')' after the number in ordered lists\n\tRefLink         []byte // If not nil, turns this list item into a footnote item and triggers different rendering\n\tIsFootnotesList bool   // This is a list of footnotes\n}\n\n// LinkData contains fields relevant to a Link node type.\ntype LinkData struct {\n\tDestination []byte // Destination is what goes into a href\n\tTitle       []byte // Title is the tooltip thing that goes in a title attribute\n\tNoteID      int    // NoteID contains a serial number of a footnote, zero if it's not a footnote\n\tFootnote    *Node  // If it's a footnote, this is a direct link to the footnote Node. Otherwise nil.\n}\n\n// CodeBlockData contains fields relevant to a CodeBlock node type.\ntype CodeBlockData struct {\n\tIsFenced    bool   // Specifies whether it's a fenced code block or an indented one\n\tInfo        []byte // This holds the info string\n\tFenceChar   byte\n\tFenceLength int\n\tFenceOffset int\n}\n\n// TableCellData contains fields relevant to a TableCell node type.\ntype TableCellData struct {\n\tIsHeader bool           // This tells if it's under the header row\n\tAlign    CellAlignFlags // This holds the value for align attribute\n}\n\n// HeadingData contains fields relevant to a Heading node type.\ntype HeadingData struct {\n\tLevel        int    // This holds the heading level number\n\tHeadingID    string // This might hold heading ID, if present\n\tIsTitleblock bool   // Specifies whether it's a title block\n}\n\n// Node is a single element in the abstract syntax tree of the parsed document.\n// It holds connections to the structurally neighboring nodes and, for certain\n// types of nodes, additional information that might be needed when rendering.\ntype Node struct {\n\tType       NodeType // Determines the type of the node\n\tParent     *Node    // Points to the parent\n\tFirstChild *Node    // Points to the first child, if any\n\tLastChild  *Node    // Points to the last child, if any\n\tPrev       *Node    // Previous sibling; nil if it's the first child\n\tNext       *Node    // Next sibling; nil if it's the last child\n\n\tLiteral []byte // Text contents of the leaf nodes\n\n\tHeadingData   // Populated if Type is Heading\n\tListData      // Populated if Type is List\n\tCodeBlockData // Populated if Type is CodeBlock\n\tLinkData      // Populated if Type is Link\n\tTableCellData // Populated if Type is TableCell\n\n\tcontent []byte // Markdown content of the block nodes\n\topen    bool   // Specifies an open block node that has not been finished to process yet\n}\n\n// NewNode allocates a node of a specified type.\nfunc NewNode(typ NodeType) *Node {\n\treturn &Node{\n\t\tType: typ,\n\t\topen: true,\n\t}\n}\n\nfunc (n *Node) String() string {\n\tellipsis := \"\"\n\tsnippet := n.Literal\n\tif len(snippet) > 16 {\n\t\tsnippet = snippet[:16]\n\t\tellipsis = \"...\"\n\t}\n\treturn fmt.Sprintf(\"%s: '%s%s'\", n.Type, snippet, ellipsis)\n}\n\n// Unlink removes node 'n' from the tree.\n// It panics if the node is nil.\nfunc (n *Node) Unlink() {\n\tif n.Prev != nil {\n\t\tn.Prev.Next = n.Next\n\t} else if n.Parent != nil {\n\t\tn.Parent.FirstChild = n.Next\n\t}\n\tif n.Next != nil {\n\t\tn.Next.Prev = n.Prev\n\t} else if n.Parent != nil {\n\t\tn.Parent.LastChild = n.Prev\n\t}\n\tn.Parent = nil\n\tn.Next = nil\n\tn.Prev = nil\n}\n\n// AppendChild adds a node 'child' as a child of 'n'.\n// It panics if either node is nil.\nfunc (n *Node) AppendChild(child *Node) {\n\tchild.Unlink()\n\tchild.Parent = n\n\tif n.LastChild != nil {\n\t\tn.LastChild.Next = child\n\t\tchild.Prev = n.LastChild\n\t\tn.LastChild = child\n\t} else {\n\t\tn.FirstChild = child\n\t\tn.LastChild = child\n\t}\n}\n\n// InsertBefore inserts 'sibling' immediately before 'n'.\n// It panics if either node is nil.\nfunc (n *Node) InsertBefore(sibling *Node) {\n\tsibling.Unlink()\n\tsibling.Prev = n.Prev\n\tif sibling.Prev != nil {\n\t\tsibling.Prev.Next = sibling\n\t}\n\tsibling.Next = n\n\tn.Prev = sibling\n\tsibling.Parent = n.Parent\n\tif sibling.Prev == nil {\n\t\tsibling.Parent.FirstChild = sibling\n\t}\n}\n\n// IsContainer returns true if 'n' can contain children.\nfunc (n *Node) IsContainer() bool {\n\tswitch n.Type {\n\tcase Document:\n\t\tfallthrough\n\tcase BlockQuote:\n\t\tfallthrough\n\tcase List:\n\t\tfallthrough\n\tcase Item:\n\t\tfallthrough\n\tcase Paragraph:\n\t\tfallthrough\n\tcase Heading:\n\t\tfallthrough\n\tcase Emph:\n\t\tfallthrough\n\tcase Strong:\n\t\tfallthrough\n\tcase Del:\n\t\tfallthrough\n\tcase Link:\n\t\tfallthrough\n\tcase Image:\n\t\tfallthrough\n\tcase Table:\n\t\tfallthrough\n\tcase TableHead:\n\t\tfallthrough\n\tcase TableBody:\n\t\tfallthrough\n\tcase TableRow:\n\t\tfallthrough\n\tcase TableCell:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// IsLeaf returns true if 'n' is a leaf node.\nfunc (n *Node) IsLeaf() bool {\n\treturn !n.IsContainer()\n}\n\nfunc (n *Node) canContain(t NodeType) bool {\n\tif n.Type == List {\n\t\treturn t == Item\n\t}\n\tif n.Type == Document || n.Type == BlockQuote || n.Type == Item {\n\t\treturn t != Item\n\t}\n\tif n.Type == Table {\n\t\treturn t == TableHead || t == TableBody\n\t}\n\tif n.Type == TableHead || n.Type == TableBody {\n\t\treturn t == TableRow\n\t}\n\tif n.Type == TableRow {\n\t\treturn t == TableCell\n\t}\n\treturn false\n}\n\n// WalkStatus allows NodeVisitor to have some control over the tree traversal.\n// It is returned from NodeVisitor and different values allow Node.Walk to\n// decide which node to go to next.\ntype WalkStatus int\n\nconst (\n\t// GoToNext is the default traversal of every node.\n\tGoToNext WalkStatus = iota\n\t// SkipChildren tells walker to skip all children of current node.\n\tSkipChildren\n\t// Terminate tells walker to terminate the traversal.\n\tTerminate\n)\n\n// NodeVisitor is a callback to be called when traversing the syntax tree.\n// Called twice for every node: once with entering=true when the branch is\n// first visited, then with entering=false after all the children are done.\ntype NodeVisitor func(node *Node, entering bool) WalkStatus\n\n// Walk is a convenience method that instantiates a walker and starts a\n// traversal of subtree rooted at n.\nfunc (n *Node) Walk(visitor NodeVisitor) {\n\tw := newNodeWalker(n)\n\tfor w.current != nil {\n\t\tstatus := visitor(w.current, w.entering)\n\t\tswitch status {\n\t\tcase GoToNext:\n\t\t\tw.next()\n\t\tcase SkipChildren:\n\t\t\tw.entering = false\n\t\t\tw.next()\n\t\tcase Terminate:\n\t\t\treturn\n\t\t}\n\t}\n}\n\ntype nodeWalker struct {\n\tcurrent  *Node\n\troot     *Node\n\tentering bool\n}\n\nfunc newNodeWalker(root *Node) *nodeWalker {\n\treturn &nodeWalker{\n\t\tcurrent:  root,\n\t\troot:     root,\n\t\tentering: true,\n\t}\n}\n\nfunc (nw *nodeWalker) next() {\n\tif (!nw.current.IsContainer() || !nw.entering) && nw.current == nw.root {\n\t\tnw.current = nil\n\t\treturn\n\t}\n\tif nw.entering && nw.current.IsContainer() {\n\t\tif nw.current.FirstChild != nil {\n\t\t\tnw.current = nw.current.FirstChild\n\t\t\tnw.entering = true\n\t\t} else {\n\t\t\tnw.entering = false\n\t\t}\n\t} else if nw.current.Next == nil {\n\t\tnw.current = nw.current.Parent\n\t\tnw.entering = false\n\t} else {\n\t\tnw.current = nw.current.Next\n\t\tnw.entering = true\n\t}\n}\n\nfunc dump(ast *Node) {\n\tfmt.Println(dumpString(ast))\n}\n\nfunc dumpR(ast *Node, depth int) string {\n\tif ast == nil {\n\t\treturn \"\"\n\t}\n\tindent := bytes.Repeat([]byte(\"\\t\"), depth)\n\tcontent := ast.Literal\n\tif content == nil {\n\t\tcontent = ast.content\n\t}\n\tresult := fmt.Sprintf(\"%s%s(%q)\\n\", indent, ast.Type, content)\n\tfor n := ast.FirstChild; n != nil; n = n.Next {\n\t\tresult += dumpR(n, depth+1)\n\t}\n\treturn result\n}\n\nfunc dumpString(ast *Node) string {\n\treturn dumpR(ast, 0)\n}\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/smartypants.go",
    "content": "//\n// Blackfriday Markdown Processor\n// Available at http://github.com/russross/blackfriday\n//\n// Copyright © 2011 Russ Ross <russ@russross.com>.\n// Distributed under the Simplified BSD License.\n// See README.md for details.\n//\n\n//\n//\n// SmartyPants rendering\n//\n//\n\npackage blackfriday\n\nimport (\n\t\"bytes\"\n\t\"io\"\n)\n\n// SPRenderer is a struct containing state of a Smartypants renderer.\ntype SPRenderer struct {\n\tinSingleQuote bool\n\tinDoubleQuote bool\n\tcallbacks     [256]smartCallback\n}\n\nfunc wordBoundary(c byte) bool {\n\treturn c == 0 || isspace(c) || ispunct(c)\n}\n\nfunc tolower(c byte) byte {\n\tif c >= 'A' && c <= 'Z' {\n\t\treturn c - 'A' + 'a'\n\t}\n\treturn c\n}\n\nfunc isdigit(c byte) bool {\n\treturn c >= '0' && c <= '9'\n}\n\nfunc smartQuoteHelper(out *bytes.Buffer, previousChar byte, nextChar byte, quote byte, isOpen *bool, addNBSP bool) bool {\n\t// edge of the buffer is likely to be a tag that we don't get to see,\n\t// so we treat it like text sometimes\n\n\t// enumerate all sixteen possibilities for (previousChar, nextChar)\n\t// each can be one of {0, space, punct, other}\n\tswitch {\n\tcase previousChar == 0 && nextChar == 0:\n\t\t// context is not any help here, so toggle\n\t\t*isOpen = !*isOpen\n\tcase isspace(previousChar) && nextChar == 0:\n\t\t// [ \"] might be [ \"<code>foo...]\n\t\t*isOpen = true\n\tcase ispunct(previousChar) && nextChar == 0:\n\t\t// [!\"] hmm... could be [Run!\"] or [(\"<code>...]\n\t\t*isOpen = false\n\tcase /* isnormal(previousChar) && */ nextChar == 0:\n\t\t// [a\"] is probably a close\n\t\t*isOpen = false\n\tcase previousChar == 0 && isspace(nextChar):\n\t\t// [\" ] might be [...foo</code>\" ]\n\t\t*isOpen = false\n\tcase isspace(previousChar) && isspace(nextChar):\n\t\t// [ \" ] context is not any help here, so toggle\n\t\t*isOpen = !*isOpen\n\tcase ispunct(previousChar) && isspace(nextChar):\n\t\t// [!\" ] is probably a close\n\t\t*isOpen = false\n\tcase /* isnormal(previousChar) && */ isspace(nextChar):\n\t\t// [a\" ] this is one of the easy cases\n\t\t*isOpen = false\n\tcase previousChar == 0 && ispunct(nextChar):\n\t\t// [\"!] hmm... could be [\"$1.95] or [</code>\"!...]\n\t\t*isOpen = false\n\tcase isspace(previousChar) && ispunct(nextChar):\n\t\t// [ \"!] looks more like [ \"$1.95]\n\t\t*isOpen = true\n\tcase ispunct(previousChar) && ispunct(nextChar):\n\t\t// [!\"!] context is not any help here, so toggle\n\t\t*isOpen = !*isOpen\n\tcase /* isnormal(previousChar) && */ ispunct(nextChar):\n\t\t// [a\"!] is probably a close\n\t\t*isOpen = false\n\tcase previousChar == 0 /* && isnormal(nextChar) */ :\n\t\t// [\"a] is probably an open\n\t\t*isOpen = true\n\tcase isspace(previousChar) /* && isnormal(nextChar) */ :\n\t\t// [ \"a] this is one of the easy cases\n\t\t*isOpen = true\n\tcase ispunct(previousChar) /* && isnormal(nextChar) */ :\n\t\t// [!\"a] is probably an open\n\t\t*isOpen = true\n\tdefault:\n\t\t// [a'b] maybe a contraction?\n\t\t*isOpen = false\n\t}\n\n\t// Note that with the limited lookahead, this non-breaking\n\t// space will also be appended to single double quotes.\n\tif addNBSP && !*isOpen {\n\t\tout.WriteString(\"&nbsp;\")\n\t}\n\n\tout.WriteByte('&')\n\tif *isOpen {\n\t\tout.WriteByte('l')\n\t} else {\n\t\tout.WriteByte('r')\n\t}\n\tout.WriteByte(quote)\n\tout.WriteString(\"quo;\")\n\n\tif addNBSP && *isOpen {\n\t\tout.WriteString(\"&nbsp;\")\n\t}\n\n\treturn true\n}\n\nfunc (r *SPRenderer) smartSingleQuote(out *bytes.Buffer, previousChar byte, text []byte) int {\n\tif len(text) >= 2 {\n\t\tt1 := tolower(text[1])\n\n\t\tif t1 == '\\'' {\n\t\t\tnextChar := byte(0)\n\t\t\tif len(text) >= 3 {\n\t\t\t\tnextChar = text[2]\n\t\t\t}\n\t\t\tif smartQuoteHelper(out, previousChar, nextChar, 'd', &r.inDoubleQuote, false) {\n\t\t\t\treturn 1\n\t\t\t}\n\t\t}\n\n\t\tif (t1 == 's' || t1 == 't' || t1 == 'm' || t1 == 'd') && (len(text) < 3 || wordBoundary(text[2])) {\n\t\t\tout.WriteString(\"&rsquo;\")\n\t\t\treturn 0\n\t\t}\n\n\t\tif len(text) >= 3 {\n\t\t\tt2 := tolower(text[2])\n\n\t\t\tif ((t1 == 'r' && t2 == 'e') || (t1 == 'l' && t2 == 'l') || (t1 == 'v' && t2 == 'e')) &&\n\t\t\t\t(len(text) < 4 || wordBoundary(text[3])) {\n\t\t\t\tout.WriteString(\"&rsquo;\")\n\t\t\t\treturn 0\n\t\t\t}\n\t\t}\n\t}\n\n\tnextChar := byte(0)\n\tif len(text) > 1 {\n\t\tnextChar = text[1]\n\t}\n\tif smartQuoteHelper(out, previousChar, nextChar, 's', &r.inSingleQuote, false) {\n\t\treturn 0\n\t}\n\n\tout.WriteByte(text[0])\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartParens(out *bytes.Buffer, previousChar byte, text []byte) int {\n\tif len(text) >= 3 {\n\t\tt1 := tolower(text[1])\n\t\tt2 := tolower(text[2])\n\n\t\tif t1 == 'c' && t2 == ')' {\n\t\t\tout.WriteString(\"&copy;\")\n\t\t\treturn 2\n\t\t}\n\n\t\tif t1 == 'r' && t2 == ')' {\n\t\t\tout.WriteString(\"&reg;\")\n\t\t\treturn 2\n\t\t}\n\n\t\tif len(text) >= 4 && t1 == 't' && t2 == 'm' && text[3] == ')' {\n\t\t\tout.WriteString(\"&trade;\")\n\t\t\treturn 3\n\t\t}\n\t}\n\n\tout.WriteByte(text[0])\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartDash(out *bytes.Buffer, previousChar byte, text []byte) int {\n\tif len(text) >= 2 {\n\t\tif text[1] == '-' {\n\t\t\tout.WriteString(\"&mdash;\")\n\t\t\treturn 1\n\t\t}\n\n\t\tif wordBoundary(previousChar) && wordBoundary(text[1]) {\n\t\t\tout.WriteString(\"&ndash;\")\n\t\t\treturn 0\n\t\t}\n\t}\n\n\tout.WriteByte(text[0])\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartDashLatex(out *bytes.Buffer, previousChar byte, text []byte) int {\n\tif len(text) >= 3 && text[1] == '-' && text[2] == '-' {\n\t\tout.WriteString(\"&mdash;\")\n\t\treturn 2\n\t}\n\tif len(text) >= 2 && text[1] == '-' {\n\t\tout.WriteString(\"&ndash;\")\n\t\treturn 1\n\t}\n\n\tout.WriteByte(text[0])\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartAmpVariant(out *bytes.Buffer, previousChar byte, text []byte, quote byte, addNBSP bool) int {\n\tif bytes.HasPrefix(text, []byte(\"&quot;\")) {\n\t\tnextChar := byte(0)\n\t\tif len(text) >= 7 {\n\t\t\tnextChar = text[6]\n\t\t}\n\t\tif smartQuoteHelper(out, previousChar, nextChar, quote, &r.inDoubleQuote, addNBSP) {\n\t\t\treturn 5\n\t\t}\n\t}\n\n\tif bytes.HasPrefix(text, []byte(\"&#0;\")) {\n\t\treturn 3\n\t}\n\n\tout.WriteByte('&')\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartAmp(angledQuotes, addNBSP bool) func(*bytes.Buffer, byte, []byte) int {\n\tvar quote byte = 'd'\n\tif angledQuotes {\n\t\tquote = 'a'\n\t}\n\n\treturn func(out *bytes.Buffer, previousChar byte, text []byte) int {\n\t\treturn r.smartAmpVariant(out, previousChar, text, quote, addNBSP)\n\t}\n}\n\nfunc (r *SPRenderer) smartPeriod(out *bytes.Buffer, previousChar byte, text []byte) int {\n\tif len(text) >= 3 && text[1] == '.' && text[2] == '.' {\n\t\tout.WriteString(\"&hellip;\")\n\t\treturn 2\n\t}\n\n\tif len(text) >= 5 && text[1] == ' ' && text[2] == '.' && text[3] == ' ' && text[4] == '.' {\n\t\tout.WriteString(\"&hellip;\")\n\t\treturn 4\n\t}\n\n\tout.WriteByte(text[0])\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartBacktick(out *bytes.Buffer, previousChar byte, text []byte) int {\n\tif len(text) >= 2 && text[1] == '`' {\n\t\tnextChar := byte(0)\n\t\tif len(text) >= 3 {\n\t\t\tnextChar = text[2]\n\t\t}\n\t\tif smartQuoteHelper(out, previousChar, nextChar, 'd', &r.inDoubleQuote, false) {\n\t\t\treturn 1\n\t\t}\n\t}\n\n\tout.WriteByte(text[0])\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartNumberGeneric(out *bytes.Buffer, previousChar byte, text []byte) int {\n\tif wordBoundary(previousChar) && previousChar != '/' && len(text) >= 3 {\n\t\t// is it of the form digits/digits(word boundary)?, i.e., \\d+/\\d+\\b\n\t\t// note: check for regular slash (/) or fraction slash (⁄, 0x2044, or 0xe2 81 84 in utf-8)\n\t\t//       and avoid changing dates like 1/23/2005 into fractions.\n\t\tnumEnd := 0\n\t\tfor len(text) > numEnd && isdigit(text[numEnd]) {\n\t\t\tnumEnd++\n\t\t}\n\t\tif numEnd == 0 {\n\t\t\tout.WriteByte(text[0])\n\t\t\treturn 0\n\t\t}\n\t\tdenStart := numEnd + 1\n\t\tif len(text) > numEnd+3 && text[numEnd] == 0xe2 && text[numEnd+1] == 0x81 && text[numEnd+2] == 0x84 {\n\t\t\tdenStart = numEnd + 3\n\t\t} else if len(text) < numEnd+2 || text[numEnd] != '/' {\n\t\t\tout.WriteByte(text[0])\n\t\t\treturn 0\n\t\t}\n\t\tdenEnd := denStart\n\t\tfor len(text) > denEnd && isdigit(text[denEnd]) {\n\t\t\tdenEnd++\n\t\t}\n\t\tif denEnd == denStart {\n\t\t\tout.WriteByte(text[0])\n\t\t\treturn 0\n\t\t}\n\t\tif len(text) == denEnd || wordBoundary(text[denEnd]) && text[denEnd] != '/' {\n\t\t\tout.WriteString(\"<sup>\")\n\t\t\tout.Write(text[:numEnd])\n\t\t\tout.WriteString(\"</sup>&frasl;<sub>\")\n\t\t\tout.Write(text[denStart:denEnd])\n\t\t\tout.WriteString(\"</sub>\")\n\t\t\treturn denEnd - 1\n\t\t}\n\t}\n\n\tout.WriteByte(text[0])\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartNumber(out *bytes.Buffer, previousChar byte, text []byte) int {\n\tif wordBoundary(previousChar) && previousChar != '/' && len(text) >= 3 {\n\t\tif text[0] == '1' && text[1] == '/' && text[2] == '2' {\n\t\t\tif len(text) < 4 || wordBoundary(text[3]) && text[3] != '/' {\n\t\t\t\tout.WriteString(\"&frac12;\")\n\t\t\t\treturn 2\n\t\t\t}\n\t\t}\n\n\t\tif text[0] == '1' && text[1] == '/' && text[2] == '4' {\n\t\t\tif len(text) < 4 || wordBoundary(text[3]) && text[3] != '/' || (len(text) >= 5 && tolower(text[3]) == 't' && tolower(text[4]) == 'h') {\n\t\t\t\tout.WriteString(\"&frac14;\")\n\t\t\t\treturn 2\n\t\t\t}\n\t\t}\n\n\t\tif text[0] == '3' && text[1] == '/' && text[2] == '4' {\n\t\t\tif len(text) < 4 || wordBoundary(text[3]) && text[3] != '/' || (len(text) >= 6 && tolower(text[3]) == 't' && tolower(text[4]) == 'h' && tolower(text[5]) == 's') {\n\t\t\t\tout.WriteString(\"&frac34;\")\n\t\t\t\treturn 2\n\t\t\t}\n\t\t}\n\t}\n\n\tout.WriteByte(text[0])\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartDoubleQuoteVariant(out *bytes.Buffer, previousChar byte, text []byte, quote byte) int {\n\tnextChar := byte(0)\n\tif len(text) > 1 {\n\t\tnextChar = text[1]\n\t}\n\tif !smartQuoteHelper(out, previousChar, nextChar, quote, &r.inDoubleQuote, false) {\n\t\tout.WriteString(\"&quot;\")\n\t}\n\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartDoubleQuote(out *bytes.Buffer, previousChar byte, text []byte) int {\n\treturn r.smartDoubleQuoteVariant(out, previousChar, text, 'd')\n}\n\nfunc (r *SPRenderer) smartAngledDoubleQuote(out *bytes.Buffer, previousChar byte, text []byte) int {\n\treturn r.smartDoubleQuoteVariant(out, previousChar, text, 'a')\n}\n\nfunc (r *SPRenderer) smartLeftAngle(out *bytes.Buffer, previousChar byte, text []byte) int {\n\ti := 0\n\n\tfor i < len(text) && text[i] != '>' {\n\t\ti++\n\t}\n\n\tout.Write(text[:i+1])\n\treturn i\n}\n\ntype smartCallback func(out *bytes.Buffer, previousChar byte, text []byte) int\n\n// NewSmartypantsRenderer constructs a Smartypants renderer object.\nfunc NewSmartypantsRenderer(flags HTMLFlags) *SPRenderer {\n\tvar (\n\t\tr SPRenderer\n\n\t\tsmartAmpAngled      = r.smartAmp(true, false)\n\t\tsmartAmpAngledNBSP  = r.smartAmp(true, true)\n\t\tsmartAmpRegular     = r.smartAmp(false, false)\n\t\tsmartAmpRegularNBSP = r.smartAmp(false, true)\n\n\t\taddNBSP = flags&SmartypantsQuotesNBSP != 0\n\t)\n\n\tif flags&SmartypantsAngledQuotes == 0 {\n\t\tr.callbacks['\"'] = r.smartDoubleQuote\n\t\tif !addNBSP {\n\t\t\tr.callbacks['&'] = smartAmpRegular\n\t\t} else {\n\t\t\tr.callbacks['&'] = smartAmpRegularNBSP\n\t\t}\n\t} else {\n\t\tr.callbacks['\"'] = r.smartAngledDoubleQuote\n\t\tif !addNBSP {\n\t\t\tr.callbacks['&'] = smartAmpAngled\n\t\t} else {\n\t\t\tr.callbacks['&'] = smartAmpAngledNBSP\n\t\t}\n\t}\n\tr.callbacks['\\''] = r.smartSingleQuote\n\tr.callbacks['('] = r.smartParens\n\tif flags&SmartypantsDashes != 0 {\n\t\tif flags&SmartypantsLatexDashes == 0 {\n\t\t\tr.callbacks['-'] = r.smartDash\n\t\t} else {\n\t\t\tr.callbacks['-'] = r.smartDashLatex\n\t\t}\n\t}\n\tr.callbacks['.'] = r.smartPeriod\n\tif flags&SmartypantsFractions == 0 {\n\t\tr.callbacks['1'] = r.smartNumber\n\t\tr.callbacks['3'] = r.smartNumber\n\t} else {\n\t\tfor ch := '1'; ch <= '9'; ch++ {\n\t\t\tr.callbacks[ch] = r.smartNumberGeneric\n\t\t}\n\t}\n\tr.callbacks['<'] = r.smartLeftAngle\n\tr.callbacks['`'] = r.smartBacktick\n\treturn &r\n}\n\n// Process is the entry point of the Smartypants renderer.\nfunc (r *SPRenderer) Process(w io.Writer, text []byte) {\n\tmark := 0\n\tfor i := 0; i < len(text); i++ {\n\t\tif action := r.callbacks[text[i]]; action != nil {\n\t\t\tif i > mark {\n\t\t\t\tw.Write(text[mark:i])\n\t\t\t}\n\t\t\tpreviousChar := byte(0)\n\t\t\tif i > 0 {\n\t\t\t\tpreviousChar = text[i-1]\n\t\t\t}\n\t\t\tvar tmp bytes.Buffer\n\t\t\ti += action(&tmp, previousChar, text[i:])\n\t\t\tw.Write(tmp.Bytes())\n\t\t\tmark = i + 1\n\t\t}\n\t}\n\tif mark < len(text) {\n\t\tw.Write(text[mark:])\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2012-2020 Mat Ryer, Tyler Bunnell and contributors.\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": "vendor/github.com/stretchr/testify/assert/assertion_compare.go",
    "content": "package assert\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"time\"\n)\n\n// Deprecated: CompareType has only ever been for internal use and has accidentally been published since v1.6.0. Do not use it.\ntype CompareType = compareResult\n\ntype compareResult int\n\nconst (\n\tcompareLess compareResult = iota - 1\n\tcompareEqual\n\tcompareGreater\n)\n\nvar (\n\tintType   = reflect.TypeOf(int(1))\n\tint8Type  = reflect.TypeOf(int8(1))\n\tint16Type = reflect.TypeOf(int16(1))\n\tint32Type = reflect.TypeOf(int32(1))\n\tint64Type = reflect.TypeOf(int64(1))\n\n\tuintType   = reflect.TypeOf(uint(1))\n\tuint8Type  = reflect.TypeOf(uint8(1))\n\tuint16Type = reflect.TypeOf(uint16(1))\n\tuint32Type = reflect.TypeOf(uint32(1))\n\tuint64Type = reflect.TypeOf(uint64(1))\n\n\tuintptrType = reflect.TypeOf(uintptr(1))\n\n\tfloat32Type = reflect.TypeOf(float32(1))\n\tfloat64Type = reflect.TypeOf(float64(1))\n\n\tstringType = reflect.TypeOf(\"\")\n\n\ttimeType  = reflect.TypeOf(time.Time{})\n\tbytesType = reflect.TypeOf([]byte{})\n)\n\nfunc compare(obj1, obj2 interface{}, kind reflect.Kind) (compareResult, bool) {\n\tobj1Value := reflect.ValueOf(obj1)\n\tobj2Value := reflect.ValueOf(obj2)\n\n\t// throughout this switch we try and avoid calling .Convert() if possible,\n\t// as this has a pretty big performance impact\n\tswitch kind {\n\tcase reflect.Int:\n\t\t{\n\t\t\tintobj1, ok := obj1.(int)\n\t\t\tif !ok {\n\t\t\t\tintobj1 = obj1Value.Convert(intType).Interface().(int)\n\t\t\t}\n\t\t\tintobj2, ok := obj2.(int)\n\t\t\tif !ok {\n\t\t\t\tintobj2 = obj2Value.Convert(intType).Interface().(int)\n\t\t\t}\n\t\t\tif intobj1 > intobj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif intobj1 == intobj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif intobj1 < intobj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Int8:\n\t\t{\n\t\t\tint8obj1, ok := obj1.(int8)\n\t\t\tif !ok {\n\t\t\t\tint8obj1 = obj1Value.Convert(int8Type).Interface().(int8)\n\t\t\t}\n\t\t\tint8obj2, ok := obj2.(int8)\n\t\t\tif !ok {\n\t\t\t\tint8obj2 = obj2Value.Convert(int8Type).Interface().(int8)\n\t\t\t}\n\t\t\tif int8obj1 > int8obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif int8obj1 == int8obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif int8obj1 < int8obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Int16:\n\t\t{\n\t\t\tint16obj1, ok := obj1.(int16)\n\t\t\tif !ok {\n\t\t\t\tint16obj1 = obj1Value.Convert(int16Type).Interface().(int16)\n\t\t\t}\n\t\t\tint16obj2, ok := obj2.(int16)\n\t\t\tif !ok {\n\t\t\t\tint16obj2 = obj2Value.Convert(int16Type).Interface().(int16)\n\t\t\t}\n\t\t\tif int16obj1 > int16obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif int16obj1 == int16obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif int16obj1 < int16obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Int32:\n\t\t{\n\t\t\tint32obj1, ok := obj1.(int32)\n\t\t\tif !ok {\n\t\t\t\tint32obj1 = obj1Value.Convert(int32Type).Interface().(int32)\n\t\t\t}\n\t\t\tint32obj2, ok := obj2.(int32)\n\t\t\tif !ok {\n\t\t\t\tint32obj2 = obj2Value.Convert(int32Type).Interface().(int32)\n\t\t\t}\n\t\t\tif int32obj1 > int32obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif int32obj1 == int32obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif int32obj1 < int32obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Int64:\n\t\t{\n\t\t\tint64obj1, ok := obj1.(int64)\n\t\t\tif !ok {\n\t\t\t\tint64obj1 = obj1Value.Convert(int64Type).Interface().(int64)\n\t\t\t}\n\t\t\tint64obj2, ok := obj2.(int64)\n\t\t\tif !ok {\n\t\t\t\tint64obj2 = obj2Value.Convert(int64Type).Interface().(int64)\n\t\t\t}\n\t\t\tif int64obj1 > int64obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif int64obj1 == int64obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif int64obj1 < int64obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Uint:\n\t\t{\n\t\t\tuintobj1, ok := obj1.(uint)\n\t\t\tif !ok {\n\t\t\t\tuintobj1 = obj1Value.Convert(uintType).Interface().(uint)\n\t\t\t}\n\t\t\tuintobj2, ok := obj2.(uint)\n\t\t\tif !ok {\n\t\t\t\tuintobj2 = obj2Value.Convert(uintType).Interface().(uint)\n\t\t\t}\n\t\t\tif uintobj1 > uintobj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif uintobj1 == uintobj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif uintobj1 < uintobj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Uint8:\n\t\t{\n\t\t\tuint8obj1, ok := obj1.(uint8)\n\t\t\tif !ok {\n\t\t\t\tuint8obj1 = obj1Value.Convert(uint8Type).Interface().(uint8)\n\t\t\t}\n\t\t\tuint8obj2, ok := obj2.(uint8)\n\t\t\tif !ok {\n\t\t\t\tuint8obj2 = obj2Value.Convert(uint8Type).Interface().(uint8)\n\t\t\t}\n\t\t\tif uint8obj1 > uint8obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif uint8obj1 == uint8obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif uint8obj1 < uint8obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Uint16:\n\t\t{\n\t\t\tuint16obj1, ok := obj1.(uint16)\n\t\t\tif !ok {\n\t\t\t\tuint16obj1 = obj1Value.Convert(uint16Type).Interface().(uint16)\n\t\t\t}\n\t\t\tuint16obj2, ok := obj2.(uint16)\n\t\t\tif !ok {\n\t\t\t\tuint16obj2 = obj2Value.Convert(uint16Type).Interface().(uint16)\n\t\t\t}\n\t\t\tif uint16obj1 > uint16obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif uint16obj1 == uint16obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif uint16obj1 < uint16obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Uint32:\n\t\t{\n\t\t\tuint32obj1, ok := obj1.(uint32)\n\t\t\tif !ok {\n\t\t\t\tuint32obj1 = obj1Value.Convert(uint32Type).Interface().(uint32)\n\t\t\t}\n\t\t\tuint32obj2, ok := obj2.(uint32)\n\t\t\tif !ok {\n\t\t\t\tuint32obj2 = obj2Value.Convert(uint32Type).Interface().(uint32)\n\t\t\t}\n\t\t\tif uint32obj1 > uint32obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif uint32obj1 == uint32obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif uint32obj1 < uint32obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Uint64:\n\t\t{\n\t\t\tuint64obj1, ok := obj1.(uint64)\n\t\t\tif !ok {\n\t\t\t\tuint64obj1 = obj1Value.Convert(uint64Type).Interface().(uint64)\n\t\t\t}\n\t\t\tuint64obj2, ok := obj2.(uint64)\n\t\t\tif !ok {\n\t\t\t\tuint64obj2 = obj2Value.Convert(uint64Type).Interface().(uint64)\n\t\t\t}\n\t\t\tif uint64obj1 > uint64obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif uint64obj1 == uint64obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif uint64obj1 < uint64obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Float32:\n\t\t{\n\t\t\tfloat32obj1, ok := obj1.(float32)\n\t\t\tif !ok {\n\t\t\t\tfloat32obj1 = obj1Value.Convert(float32Type).Interface().(float32)\n\t\t\t}\n\t\t\tfloat32obj2, ok := obj2.(float32)\n\t\t\tif !ok {\n\t\t\t\tfloat32obj2 = obj2Value.Convert(float32Type).Interface().(float32)\n\t\t\t}\n\t\t\tif float32obj1 > float32obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif float32obj1 == float32obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif float32obj1 < float32obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Float64:\n\t\t{\n\t\t\tfloat64obj1, ok := obj1.(float64)\n\t\t\tif !ok {\n\t\t\t\tfloat64obj1 = obj1Value.Convert(float64Type).Interface().(float64)\n\t\t\t}\n\t\t\tfloat64obj2, ok := obj2.(float64)\n\t\t\tif !ok {\n\t\t\t\tfloat64obj2 = obj2Value.Convert(float64Type).Interface().(float64)\n\t\t\t}\n\t\t\tif float64obj1 > float64obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif float64obj1 == float64obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif float64obj1 < float64obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.String:\n\t\t{\n\t\t\tstringobj1, ok := obj1.(string)\n\t\t\tif !ok {\n\t\t\t\tstringobj1 = obj1Value.Convert(stringType).Interface().(string)\n\t\t\t}\n\t\t\tstringobj2, ok := obj2.(string)\n\t\t\tif !ok {\n\t\t\t\tstringobj2 = obj2Value.Convert(stringType).Interface().(string)\n\t\t\t}\n\t\t\tif stringobj1 > stringobj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif stringobj1 == stringobj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif stringobj1 < stringobj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\t// Check for known struct types we can check for compare results.\n\tcase reflect.Struct:\n\t\t{\n\t\t\t// All structs enter here. We're not interested in most types.\n\t\t\tif !obj1Value.CanConvert(timeType) {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// time.Time can be compared!\n\t\t\ttimeObj1, ok := obj1.(time.Time)\n\t\t\tif !ok {\n\t\t\t\ttimeObj1 = obj1Value.Convert(timeType).Interface().(time.Time)\n\t\t\t}\n\n\t\t\ttimeObj2, ok := obj2.(time.Time)\n\t\t\tif !ok {\n\t\t\t\ttimeObj2 = obj2Value.Convert(timeType).Interface().(time.Time)\n\t\t\t}\n\n\t\t\tif timeObj1.Before(timeObj2) {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t\tif timeObj1.Equal(timeObj2) {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\treturn compareGreater, true\n\t\t}\n\tcase reflect.Slice:\n\t\t{\n\t\t\t// We only care about the []byte type.\n\t\t\tif !obj1Value.CanConvert(bytesType) {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// []byte can be compared!\n\t\t\tbytesObj1, ok := obj1.([]byte)\n\t\t\tif !ok {\n\t\t\t\tbytesObj1 = obj1Value.Convert(bytesType).Interface().([]byte)\n\n\t\t\t}\n\t\t\tbytesObj2, ok := obj2.([]byte)\n\t\t\tif !ok {\n\t\t\t\tbytesObj2 = obj2Value.Convert(bytesType).Interface().([]byte)\n\t\t\t}\n\n\t\t\treturn compareResult(bytes.Compare(bytesObj1, bytesObj2)), true\n\t\t}\n\tcase reflect.Uintptr:\n\t\t{\n\t\t\tuintptrObj1, ok := obj1.(uintptr)\n\t\t\tif !ok {\n\t\t\t\tuintptrObj1 = obj1Value.Convert(uintptrType).Interface().(uintptr)\n\t\t\t}\n\t\t\tuintptrObj2, ok := obj2.(uintptr)\n\t\t\tif !ok {\n\t\t\t\tuintptrObj2 = obj2Value.Convert(uintptrType).Interface().(uintptr)\n\t\t\t}\n\t\t\tif uintptrObj1 > uintptrObj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif uintptrObj1 == uintptrObj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif uintptrObj1 < uintptrObj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn compareEqual, false\n}\n\n// Greater asserts that the first element is greater than the second\n//\n//\tassert.Greater(t, 2, 1)\n//\tassert.Greater(t, float64(2), float64(1))\n//\tassert.Greater(t, \"b\", \"a\")\nfunc Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tfailMessage := fmt.Sprintf(\"\\\"%v\\\" is not greater than \\\"%v\\\"\", e1, e2)\n\treturn compareTwoValues(t, e1, e2, []compareResult{compareGreater}, failMessage, msgAndArgs...)\n}\n\n// GreaterOrEqual asserts that the first element is greater than or equal to the second\n//\n//\tassert.GreaterOrEqual(t, 2, 1)\n//\tassert.GreaterOrEqual(t, 2, 2)\n//\tassert.GreaterOrEqual(t, \"b\", \"a\")\n//\tassert.GreaterOrEqual(t, \"b\", \"b\")\nfunc GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tfailMessage := fmt.Sprintf(\"\\\"%v\\\" is not greater than or equal to \\\"%v\\\"\", e1, e2)\n\treturn compareTwoValues(t, e1, e2, []compareResult{compareGreater, compareEqual}, failMessage, msgAndArgs...)\n}\n\n// Less asserts that the first element is less than the second\n//\n//\tassert.Less(t, 1, 2)\n//\tassert.Less(t, float64(1), float64(2))\n//\tassert.Less(t, \"a\", \"b\")\nfunc Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tfailMessage := fmt.Sprintf(\"\\\"%v\\\" is not less than \\\"%v\\\"\", e1, e2)\n\treturn compareTwoValues(t, e1, e2, []compareResult{compareLess}, failMessage, msgAndArgs...)\n}\n\n// LessOrEqual asserts that the first element is less than or equal to the second\n//\n//\tassert.LessOrEqual(t, 1, 2)\n//\tassert.LessOrEqual(t, 2, 2)\n//\tassert.LessOrEqual(t, \"a\", \"b\")\n//\tassert.LessOrEqual(t, \"b\", \"b\")\nfunc LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tfailMessage := fmt.Sprintf(\"\\\"%v\\\" is not less than or equal to \\\"%v\\\"\", e1, e2)\n\treturn compareTwoValues(t, e1, e2, []compareResult{compareLess, compareEqual}, failMessage, msgAndArgs...)\n}\n\n// Positive asserts that the specified element is positive\n//\n//\tassert.Positive(t, 1)\n//\tassert.Positive(t, 1.23)\nfunc Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tzero := reflect.Zero(reflect.TypeOf(e))\n\tfailMessage := fmt.Sprintf(\"\\\"%v\\\" is not positive\", e)\n\treturn compareTwoValues(t, e, zero.Interface(), []compareResult{compareGreater}, failMessage, msgAndArgs...)\n}\n\n// Negative asserts that the specified element is negative\n//\n//\tassert.Negative(t, -1)\n//\tassert.Negative(t, -1.23)\nfunc Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tzero := reflect.Zero(reflect.TypeOf(e))\n\tfailMessage := fmt.Sprintf(\"\\\"%v\\\" is not negative\", e)\n\treturn compareTwoValues(t, e, zero.Interface(), []compareResult{compareLess}, failMessage, msgAndArgs...)\n}\n\nfunc compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\te1Kind := reflect.ValueOf(e1).Kind()\n\te2Kind := reflect.ValueOf(e2).Kind()\n\tif e1Kind != e2Kind {\n\t\treturn Fail(t, \"Elements should be the same type\", msgAndArgs...)\n\t}\n\n\tcompareResult, isComparable := compare(e1, e2, e1Kind)\n\tif !isComparable {\n\t\treturn Fail(t, fmt.Sprintf(`Can not compare type \"%T\"`, e1), msgAndArgs...)\n\t}\n\n\tif !containsValue(allowedComparesResults, compareResult) {\n\t\treturn Fail(t, failMessage, msgAndArgs...)\n\t}\n\n\treturn true\n}\n\nfunc containsValue(values []compareResult, value compareResult) bool {\n\tfor _, v := range values {\n\t\tif v == value {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/assertion_format.go",
    "content": "// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT.\n\npackage assert\n\nimport (\n\thttp \"net/http\"\n\turl \"net/url\"\n\ttime \"time\"\n)\n\n// Conditionf uses a Comparison to assert a complex condition.\nfunc Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Condition(t, comp, append([]interface{}{msg}, args...)...)\n}\n\n// Containsf asserts that the specified string, list(array, slice...) or map contains the\n// specified substring or element.\n//\n//\tassert.Containsf(t, \"Hello World\", \"World\", \"error message %s\", \"formatted\")\n//\tassert.Containsf(t, [\"Hello\", \"World\"], \"World\", \"error message %s\", \"formatted\")\n//\tassert.Containsf(t, {\"Hello\": \"World\"}, \"Hello\", \"error message %s\", \"formatted\")\nfunc Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Contains(t, s, contains, append([]interface{}{msg}, args...)...)\n}\n\n// DirExistsf checks whether a directory exists in the given path. It also fails\n// if the path is a file rather a directory or there is an error checking whether it exists.\nfunc DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn DirExists(t, path, append([]interface{}{msg}, args...)...)\n}\n\n// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should match.\n//\n// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], \"error message %s\", \"formatted\")\nfunc ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...)\n}\n\n// Emptyf asserts that the given value is \"empty\".\n//\n// [Zero values] are \"empty\".\n//\n// Arrays are \"empty\" if every element is the zero value of the type (stricter than \"empty\").\n//\n// Slices, maps and channels with zero length are \"empty\".\n//\n// Pointer values are \"empty\" if the pointer is nil or if the pointed value is \"empty\".\n//\n//\tassert.Emptyf(t, obj, \"error message %s\", \"formatted\")\n//\n// [Zero values]: https://go.dev/ref/spec#The_zero_value\nfunc Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Empty(t, object, append([]interface{}{msg}, args...)...)\n}\n\n// Equalf asserts that two objects are equal.\n//\n//\tassert.Equalf(t, 123, 123, \"error message %s\", \"formatted\")\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses). Function equality\n// cannot be determined and will always fail.\nfunc Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Equal(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// EqualErrorf asserts that a function returned an error (i.e. not `nil`)\n// and that it is equal to the provided error.\n//\n//\tactualObj, err := SomeFunction()\n//\tassert.EqualErrorf(t, err,  expectedErrorString, \"error message %s\", \"formatted\")\nfunc EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualError(t, theError, errString, append([]interface{}{msg}, args...)...)\n}\n\n// EqualExportedValuesf asserts that the types of two objects are equal and their public\n// fields are also equal. This is useful for comparing structs that have private fields\n// that could potentially differ.\n//\n//\t type S struct {\n//\t\tExported     \tint\n//\t\tnotExported   \tint\n//\t }\n//\t assert.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, \"error message %s\", \"formatted\") => true\n//\t assert.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, \"error message %s\", \"formatted\") => false\nfunc EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualExportedValues(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// EqualValuesf asserts that two objects are equal or convertible to the larger\n// type and equal.\n//\n//\tassert.EqualValuesf(t, uint32(123), int32(123), \"error message %s\", \"formatted\")\nfunc EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualValues(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// Errorf asserts that a function returned an error (i.e. not `nil`).\n//\n//\tactualObj, err := SomeFunction()\n//\tassert.Errorf(t, err, \"error message %s\", \"formatted\")\nfunc Errorf(t TestingT, err error, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Error(t, err, append([]interface{}{msg}, args...)...)\n}\n\n// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.\n// This is a wrapper for errors.As.\nfunc ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorAs(t, err, target, append([]interface{}{msg}, args...)...)\n}\n\n// ErrorContainsf asserts that a function returned an error (i.e. not `nil`)\n// and that the error contains the specified substring.\n//\n//\tactualObj, err := SomeFunction()\n//\tassert.ErrorContainsf(t, err,  expectedErrorSubString, \"error message %s\", \"formatted\")\nfunc ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorContains(t, theError, contains, append([]interface{}{msg}, args...)...)\n}\n\n// ErrorIsf asserts that at least one of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc ErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorIs(t, err, target, append([]interface{}{msg}, args...)...)\n}\n\n// Eventuallyf asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick.\n//\n//\tassert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, \"error message %s\", \"formatted\")\nfunc Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Eventually(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...)\n}\n\n// EventuallyWithTf asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick. In contrast to Eventually,\n// it supplies a CollectT to the condition function, so that the condition\n// function can use the CollectT to call other assertions.\n// The condition is considered \"met\" if no errors are raised in a tick.\n// The supplied CollectT collects all errors from one tick (if there are any).\n// If the condition is not met before waitFor, the collected errors of\n// the last tick are copied to t.\n//\n//\texternalValue := false\n//\tgo func() {\n//\t\ttime.Sleep(8*time.Second)\n//\t\texternalValue = true\n//\t}()\n//\tassert.EventuallyWithTf(t, func(c *assert.CollectT, \"error message %s\", \"formatted\") {\n//\t\t// add assertions as needed; any assertion failure will fail the current tick\n//\t\tassert.True(c, externalValue, \"expected 'externalValue' to be true\")\n//\t}, 10*time.Second, 1*time.Second, \"external state has not changed to 'true'; still false\")\nfunc EventuallyWithTf(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EventuallyWithT(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...)\n}\n\n// Exactlyf asserts that two objects are equal in value and type.\n//\n//\tassert.Exactlyf(t, int32(123), int64(123), \"error message %s\", \"formatted\")\nfunc Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Exactly(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// Failf reports a failure through\nfunc Failf(t TestingT, failureMessage string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Fail(t, failureMessage, append([]interface{}{msg}, args...)...)\n}\n\n// FailNowf fails test\nfunc FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn FailNow(t, failureMessage, append([]interface{}{msg}, args...)...)\n}\n\n// Falsef asserts that the specified value is false.\n//\n//\tassert.Falsef(t, myBool, \"error message %s\", \"formatted\")\nfunc Falsef(t TestingT, value bool, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn False(t, value, append([]interface{}{msg}, args...)...)\n}\n\n// FileExistsf checks whether a file exists in the given path. It also fails if\n// the path points to a directory or there is an error when trying to check the file.\nfunc FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn FileExists(t, path, append([]interface{}{msg}, args...)...)\n}\n\n// Greaterf asserts that the first element is greater than the second\n//\n//\tassert.Greaterf(t, 2, 1, \"error message %s\", \"formatted\")\n//\tassert.Greaterf(t, float64(2), float64(1), \"error message %s\", \"formatted\")\n//\tassert.Greaterf(t, \"b\", \"a\", \"error message %s\", \"formatted\")\nfunc Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Greater(t, e1, e2, append([]interface{}{msg}, args...)...)\n}\n\n// GreaterOrEqualf asserts that the first element is greater than or equal to the second\n//\n//\tassert.GreaterOrEqualf(t, 2, 1, \"error message %s\", \"formatted\")\n//\tassert.GreaterOrEqualf(t, 2, 2, \"error message %s\", \"formatted\")\n//\tassert.GreaterOrEqualf(t, \"b\", \"a\", \"error message %s\", \"formatted\")\n//\tassert.GreaterOrEqualf(t, \"b\", \"b\", \"error message %s\", \"formatted\")\nfunc GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn GreaterOrEqual(t, e1, e2, append([]interface{}{msg}, args...)...)\n}\n\n// HTTPBodyContainsf asserts that a specified handler returns a\n// body that contains a string.\n//\n//\tassert.HTTPBodyContainsf(t, myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\", \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPBodyContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...)\n}\n\n// HTTPBodyNotContainsf asserts that a specified handler returns a\n// body that does not contain a string.\n//\n//\tassert.HTTPBodyNotContainsf(t, myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\", \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPBodyNotContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...)\n}\n\n// HTTPErrorf asserts that a specified handler returns an error status code.\n//\n//\tassert.HTTPErrorf(t, myHandler, \"POST\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPError(t, handler, method, url, values, append([]interface{}{msg}, args...)...)\n}\n\n// HTTPRedirectf asserts that a specified handler returns a redirect status code.\n//\n//\tassert.HTTPRedirectf(t, myHandler, \"GET\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPRedirect(t, handler, method, url, values, append([]interface{}{msg}, args...)...)\n}\n\n// HTTPStatusCodef asserts that a specified handler returns a specified status code.\n//\n//\tassert.HTTPStatusCodef(t, myHandler, \"GET\", \"/notImplemented\", nil, 501, \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPStatusCode(t, handler, method, url, values, statuscode, append([]interface{}{msg}, args...)...)\n}\n\n// HTTPSuccessf asserts that a specified handler returns a success status code.\n//\n//\tassert.HTTPSuccessf(t, myHandler, \"POST\", \"http://www.google.com\", nil, \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPSuccess(t, handler, method, url, values, append([]interface{}{msg}, args...)...)\n}\n\n// Implementsf asserts that an object is implemented by the specified interface.\n//\n//\tassert.Implementsf(t, (*MyInterface)(nil), new(MyObject), \"error message %s\", \"formatted\")\nfunc Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Implements(t, interfaceObject, object, append([]interface{}{msg}, args...)...)\n}\n\n// InDeltaf asserts that the two numerals are within delta of each other.\n//\n//\tassert.InDeltaf(t, math.Pi, 22/7.0, 0.01, \"error message %s\", \"formatted\")\nfunc InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDelta(t, expected, actual, delta, append([]interface{}{msg}, args...)...)\n}\n\n// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.\nfunc InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDeltaMapValues(t, expected, actual, delta, append([]interface{}{msg}, args...)...)\n}\n\n// InDeltaSlicef is the same as InDelta, except it compares two slices.\nfunc InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDeltaSlice(t, expected, actual, delta, append([]interface{}{msg}, args...)...)\n}\n\n// InEpsilonf asserts that expected and actual have a relative error less than epsilon\nfunc InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InEpsilon(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)\n}\n\n// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.\nfunc InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InEpsilonSlice(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)\n}\n\n// IsDecreasingf asserts that the collection is decreasing\n//\n//\tassert.IsDecreasingf(t, []int{2, 1, 0}, \"error message %s\", \"formatted\")\n//\tassert.IsDecreasingf(t, []float{2, 1}, \"error message %s\", \"formatted\")\n//\tassert.IsDecreasingf(t, []string{\"b\", \"a\"}, \"error message %s\", \"formatted\")\nfunc IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsDecreasing(t, object, append([]interface{}{msg}, args...)...)\n}\n\n// IsIncreasingf asserts that the collection is increasing\n//\n//\tassert.IsIncreasingf(t, []int{1, 2, 3}, \"error message %s\", \"formatted\")\n//\tassert.IsIncreasingf(t, []float{1, 2}, \"error message %s\", \"formatted\")\n//\tassert.IsIncreasingf(t, []string{\"a\", \"b\"}, \"error message %s\", \"formatted\")\nfunc IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsIncreasing(t, object, append([]interface{}{msg}, args...)...)\n}\n\n// IsNonDecreasingf asserts that the collection is not decreasing\n//\n//\tassert.IsNonDecreasingf(t, []int{1, 1, 2}, \"error message %s\", \"formatted\")\n//\tassert.IsNonDecreasingf(t, []float{1, 2}, \"error message %s\", \"formatted\")\n//\tassert.IsNonDecreasingf(t, []string{\"a\", \"b\"}, \"error message %s\", \"formatted\")\nfunc IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsNonDecreasing(t, object, append([]interface{}{msg}, args...)...)\n}\n\n// IsNonIncreasingf asserts that the collection is not increasing\n//\n//\tassert.IsNonIncreasingf(t, []int{2, 1, 1}, \"error message %s\", \"formatted\")\n//\tassert.IsNonIncreasingf(t, []float{2, 1}, \"error message %s\", \"formatted\")\n//\tassert.IsNonIncreasingf(t, []string{\"b\", \"a\"}, \"error message %s\", \"formatted\")\nfunc IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsNonIncreasing(t, object, append([]interface{}{msg}, args...)...)\n}\n\n// IsNotTypef asserts that the specified objects are not of the same type.\n//\n//\tassert.IsNotTypef(t, &NotMyStruct{}, &MyStruct{}, \"error message %s\", \"formatted\")\nfunc IsNotTypef(t TestingT, theType interface{}, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsNotType(t, theType, object, append([]interface{}{msg}, args...)...)\n}\n\n// IsTypef asserts that the specified objects are of the same type.\n//\n//\tassert.IsTypef(t, &MyStruct{}, &MyStruct{}, \"error message %s\", \"formatted\")\nfunc IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsType(t, expectedType, object, append([]interface{}{msg}, args...)...)\n}\n\n// JSONEqf asserts that two JSON strings are equivalent.\n//\n//\tassert.JSONEqf(t, `{\"hello\": \"world\", \"foo\": \"bar\"}`, `{\"foo\": \"bar\", \"hello\": \"world\"}`, \"error message %s\", \"formatted\")\nfunc JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn JSONEq(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// Lenf asserts that the specified object has specific length.\n// Lenf also fails if the object has a type that len() not accept.\n//\n//\tassert.Lenf(t, mySlice, 3, \"error message %s\", \"formatted\")\nfunc Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Len(t, object, length, append([]interface{}{msg}, args...)...)\n}\n\n// Lessf asserts that the first element is less than the second\n//\n//\tassert.Lessf(t, 1, 2, \"error message %s\", \"formatted\")\n//\tassert.Lessf(t, float64(1), float64(2), \"error message %s\", \"formatted\")\n//\tassert.Lessf(t, \"a\", \"b\", \"error message %s\", \"formatted\")\nfunc Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Less(t, e1, e2, append([]interface{}{msg}, args...)...)\n}\n\n// LessOrEqualf asserts that the first element is less than or equal to the second\n//\n//\tassert.LessOrEqualf(t, 1, 2, \"error message %s\", \"formatted\")\n//\tassert.LessOrEqualf(t, 2, 2, \"error message %s\", \"formatted\")\n//\tassert.LessOrEqualf(t, \"a\", \"b\", \"error message %s\", \"formatted\")\n//\tassert.LessOrEqualf(t, \"b\", \"b\", \"error message %s\", \"formatted\")\nfunc LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn LessOrEqual(t, e1, e2, append([]interface{}{msg}, args...)...)\n}\n\n// Negativef asserts that the specified element is negative\n//\n//\tassert.Negativef(t, -1, \"error message %s\", \"formatted\")\n//\tassert.Negativef(t, -1.23, \"error message %s\", \"formatted\")\nfunc Negativef(t TestingT, e interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Negative(t, e, append([]interface{}{msg}, args...)...)\n}\n\n// Neverf asserts that the given condition doesn't satisfy in waitFor time,\n// periodically checking the target function each tick.\n//\n//\tassert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, \"error message %s\", \"formatted\")\nfunc Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Never(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...)\n}\n\n// Nilf asserts that the specified object is nil.\n//\n//\tassert.Nilf(t, err, \"error message %s\", \"formatted\")\nfunc Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Nil(t, object, append([]interface{}{msg}, args...)...)\n}\n\n// NoDirExistsf checks whether a directory does not exist in the given path.\n// It fails if the path points to an existing _directory_ only.\nfunc NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoDirExists(t, path, append([]interface{}{msg}, args...)...)\n}\n\n// NoErrorf asserts that a function returned no error (i.e. `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if assert.NoErrorf(t, err, \"error message %s\", \"formatted\") {\n//\t\t   assert.Equal(t, expectedObj, actualObj)\n//\t  }\nfunc NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoError(t, err, append([]interface{}{msg}, args...)...)\n}\n\n// NoFileExistsf checks whether a file does not exist in a given path. It fails\n// if the path points to an existing _file_ only.\nfunc NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoFileExists(t, path, append([]interface{}{msg}, args...)...)\n}\n\n// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the\n// specified substring or element.\n//\n//\tassert.NotContainsf(t, \"Hello World\", \"Earth\", \"error message %s\", \"formatted\")\n//\tassert.NotContainsf(t, [\"Hello\", \"World\"], \"Earth\", \"error message %s\", \"formatted\")\n//\tassert.NotContainsf(t, {\"Hello\": \"World\"}, \"Earth\", \"error message %s\", \"formatted\")\nfunc NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotContains(t, s, contains, append([]interface{}{msg}, args...)...)\n}\n\n// NotElementsMatchf asserts that the specified listA(array, slice...) is NOT equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should not match.\n// This is an inverse of ElementsMatch.\n//\n// assert.NotElementsMatchf(t, [1, 1, 2, 3], [1, 1, 2, 3], \"error message %s\", \"formatted\") -> false\n//\n// assert.NotElementsMatchf(t, [1, 1, 2, 3], [1, 2, 3], \"error message %s\", \"formatted\") -> true\n//\n// assert.NotElementsMatchf(t, [1, 2, 3], [1, 2, 4], \"error message %s\", \"formatted\") -> true\nfunc NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...)\n}\n\n// NotEmptyf asserts that the specified object is NOT [Empty].\n//\n//\tif assert.NotEmptyf(t, obj, \"error message %s\", \"formatted\") {\n//\t  assert.Equal(t, \"two\", obj[1])\n//\t}\nfunc NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEmpty(t, object, append([]interface{}{msg}, args...)...)\n}\n\n// NotEqualf asserts that the specified values are NOT equal.\n//\n//\tassert.NotEqualf(t, obj1, obj2, \"error message %s\", \"formatted\")\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses).\nfunc NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEqual(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// NotEqualValuesf asserts that two objects are not equal even when converted to the same type\n//\n//\tassert.NotEqualValuesf(t, obj1, obj2, \"error message %s\", \"formatted\")\nfunc NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEqualValues(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// NotErrorAsf asserts that none of the errors in err's chain matches target,\n// but if so, sets target to that error value.\nfunc NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotErrorAs(t, err, target, append([]interface{}{msg}, args...)...)\n}\n\n// NotErrorIsf asserts that none of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotErrorIs(t, err, target, append([]interface{}{msg}, args...)...)\n}\n\n// NotImplementsf asserts that an object does not implement the specified interface.\n//\n//\tassert.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), \"error message %s\", \"formatted\")\nfunc NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotImplements(t, interfaceObject, object, append([]interface{}{msg}, args...)...)\n}\n\n// NotNilf asserts that the specified object is not nil.\n//\n//\tassert.NotNilf(t, err, \"error message %s\", \"formatted\")\nfunc NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotNil(t, object, append([]interface{}{msg}, args...)...)\n}\n\n// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic.\n//\n//\tassert.NotPanicsf(t, func(){ RemainCalm() }, \"error message %s\", \"formatted\")\nfunc NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotPanics(t, f, append([]interface{}{msg}, args...)...)\n}\n\n// NotRegexpf asserts that a specified regexp does not match a string.\n//\n//\tassert.NotRegexpf(t, regexp.MustCompile(\"starts\"), \"it's starting\", \"error message %s\", \"formatted\")\n//\tassert.NotRegexpf(t, \"^start\", \"it's not starting\", \"error message %s\", \"formatted\")\nfunc NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotRegexp(t, rx, str, append([]interface{}{msg}, args...)...)\n}\n\n// NotSamef asserts that two pointers do not reference the same object.\n//\n//\tassert.NotSamef(t, ptr1, ptr2, \"error message %s\", \"formatted\")\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotSame(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// NotSubsetf asserts that the list (array, slice, or map) does NOT contain all\n// elements given in the subset (array, slice, or map).\n// Map elements are key-value pairs unless compared with an array or slice where\n// only the map key is evaluated.\n//\n//\tassert.NotSubsetf(t, [1, 3, 4], [1, 2], \"error message %s\", \"formatted\")\n//\tassert.NotSubsetf(t, {\"x\": 1, \"y\": 2}, {\"z\": 3}, \"error message %s\", \"formatted\")\n//\tassert.NotSubsetf(t, [1, 3, 4], {1: \"one\", 2: \"two\"}, \"error message %s\", \"formatted\")\n//\tassert.NotSubsetf(t, {\"x\": 1, \"y\": 2}, [\"z\"], \"error message %s\", \"formatted\")\nfunc NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotSubset(t, list, subset, append([]interface{}{msg}, args...)...)\n}\n\n// NotZerof asserts that i is not the zero value for its type.\nfunc NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotZero(t, i, append([]interface{}{msg}, args...)...)\n}\n\n// Panicsf asserts that the code inside the specified PanicTestFunc panics.\n//\n//\tassert.Panicsf(t, func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Panics(t, f, append([]interface{}{msg}, args...)...)\n}\n\n// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc\n// panics, and that the recovered panic value is an error that satisfies the\n// EqualError comparison.\n//\n//\tassert.PanicsWithErrorf(t, \"crazy error\", func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc PanicsWithErrorf(t TestingT, errString string, f PanicTestFunc, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn PanicsWithError(t, errString, f, append([]interface{}{msg}, args...)...)\n}\n\n// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that\n// the recovered panic value equals the expected panic value.\n//\n//\tassert.PanicsWithValuef(t, \"crazy error\", func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn PanicsWithValue(t, expected, f, append([]interface{}{msg}, args...)...)\n}\n\n// Positivef asserts that the specified element is positive\n//\n//\tassert.Positivef(t, 1, \"error message %s\", \"formatted\")\n//\tassert.Positivef(t, 1.23, \"error message %s\", \"formatted\")\nfunc Positivef(t TestingT, e interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Positive(t, e, append([]interface{}{msg}, args...)...)\n}\n\n// Regexpf asserts that a specified regexp matches a string.\n//\n//\tassert.Regexpf(t, regexp.MustCompile(\"start\"), \"it's starting\", \"error message %s\", \"formatted\")\n//\tassert.Regexpf(t, \"start...$\", \"it's not starting\", \"error message %s\", \"formatted\")\nfunc Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Regexp(t, rx, str, append([]interface{}{msg}, args...)...)\n}\n\n// Samef asserts that two pointers reference the same object.\n//\n//\tassert.Samef(t, ptr1, ptr2, \"error message %s\", \"formatted\")\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc Samef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Same(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// Subsetf asserts that the list (array, slice, or map) contains all elements\n// given in the subset (array, slice, or map).\n// Map elements are key-value pairs unless compared with an array or slice where\n// only the map key is evaluated.\n//\n//\tassert.Subsetf(t, [1, 2, 3], [1, 2], \"error message %s\", \"formatted\")\n//\tassert.Subsetf(t, {\"x\": 1, \"y\": 2}, {\"x\": 1}, \"error message %s\", \"formatted\")\n//\tassert.Subsetf(t, [1, 2, 3], {1: \"one\", 2: \"two\"}, \"error message %s\", \"formatted\")\n//\tassert.Subsetf(t, {\"x\": 1, \"y\": 2}, [\"x\"], \"error message %s\", \"formatted\")\nfunc Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Subset(t, list, subset, append([]interface{}{msg}, args...)...)\n}\n\n// Truef asserts that the specified value is true.\n//\n//\tassert.Truef(t, myBool, \"error message %s\", \"formatted\")\nfunc Truef(t TestingT, value bool, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn True(t, value, append([]interface{}{msg}, args...)...)\n}\n\n// WithinDurationf asserts that the two times are within duration delta of each other.\n//\n//\tassert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, \"error message %s\", \"formatted\")\nfunc WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn WithinDuration(t, expected, actual, delta, append([]interface{}{msg}, args...)...)\n}\n\n// WithinRangef asserts that a time is within a time range (inclusive).\n//\n//\tassert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), \"error message %s\", \"formatted\")\nfunc WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn WithinRange(t, actual, start, end, append([]interface{}{msg}, args...)...)\n}\n\n// YAMLEqf asserts that two YAML strings are equivalent.\nfunc YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn YAMLEq(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// Zerof asserts that i is the zero value for its type.\nfunc Zerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Zero(t, i, append([]interface{}{msg}, args...)...)\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl",
    "content": "{{.CommentFormat}}\nfunc {{.DocInfo.Name}}f(t TestingT, {{.ParamsFormat}}) bool {\n\tif h, ok := t.(tHelper); ok { h.Helper() }\n\treturn {{.DocInfo.Name}}(t, {{.ForwardedParamsFormat}})\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/assertion_forward.go",
    "content": "// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT.\n\npackage assert\n\nimport (\n\thttp \"net/http\"\n\turl \"net/url\"\n\ttime \"time\"\n)\n\n// Condition uses a Comparison to assert a complex condition.\nfunc (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Condition(a.t, comp, msgAndArgs...)\n}\n\n// Conditionf uses a Comparison to assert a complex condition.\nfunc (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Conditionf(a.t, comp, msg, args...)\n}\n\n// Contains asserts that the specified string, list(array, slice...) or map contains the\n// specified substring or element.\n//\n//\ta.Contains(\"Hello World\", \"World\")\n//\ta.Contains([\"Hello\", \"World\"], \"World\")\n//\ta.Contains({\"Hello\": \"World\"}, \"Hello\")\nfunc (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Contains(a.t, s, contains, msgAndArgs...)\n}\n\n// Containsf asserts that the specified string, list(array, slice...) or map contains the\n// specified substring or element.\n//\n//\ta.Containsf(\"Hello World\", \"World\", \"error message %s\", \"formatted\")\n//\ta.Containsf([\"Hello\", \"World\"], \"World\", \"error message %s\", \"formatted\")\n//\ta.Containsf({\"Hello\": \"World\"}, \"Hello\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Containsf(a.t, s, contains, msg, args...)\n}\n\n// DirExists checks whether a directory exists in the given path. It also fails\n// if the path is a file rather a directory or there is an error checking whether it exists.\nfunc (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn DirExists(a.t, path, msgAndArgs...)\n}\n\n// DirExistsf checks whether a directory exists in the given path. It also fails\n// if the path is a file rather a directory or there is an error checking whether it exists.\nfunc (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn DirExistsf(a.t, path, msg, args...)\n}\n\n// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should match.\n//\n// a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2])\nfunc (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ElementsMatch(a.t, listA, listB, msgAndArgs...)\n}\n\n// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should match.\n//\n// a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], \"error message %s\", \"formatted\")\nfunc (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ElementsMatchf(a.t, listA, listB, msg, args...)\n}\n\n// Empty asserts that the given value is \"empty\".\n//\n// [Zero values] are \"empty\".\n//\n// Arrays are \"empty\" if every element is the zero value of the type (stricter than \"empty\").\n//\n// Slices, maps and channels with zero length are \"empty\".\n//\n// Pointer values are \"empty\" if the pointer is nil or if the pointed value is \"empty\".\n//\n//\ta.Empty(obj)\n//\n// [Zero values]: https://go.dev/ref/spec#The_zero_value\nfunc (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Empty(a.t, object, msgAndArgs...)\n}\n\n// Emptyf asserts that the given value is \"empty\".\n//\n// [Zero values] are \"empty\".\n//\n// Arrays are \"empty\" if every element is the zero value of the type (stricter than \"empty\").\n//\n// Slices, maps and channels with zero length are \"empty\".\n//\n// Pointer values are \"empty\" if the pointer is nil or if the pointed value is \"empty\".\n//\n//\ta.Emptyf(obj, \"error message %s\", \"formatted\")\n//\n// [Zero values]: https://go.dev/ref/spec#The_zero_value\nfunc (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Emptyf(a.t, object, msg, args...)\n}\n\n// Equal asserts that two objects are equal.\n//\n//\ta.Equal(123, 123)\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses). Function equality\n// cannot be determined and will always fail.\nfunc (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Equal(a.t, expected, actual, msgAndArgs...)\n}\n\n// EqualError asserts that a function returned an error (i.e. not `nil`)\n// and that it is equal to the provided error.\n//\n//\tactualObj, err := SomeFunction()\n//\ta.EqualError(err,  expectedErrorString)\nfunc (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualError(a.t, theError, errString, msgAndArgs...)\n}\n\n// EqualErrorf asserts that a function returned an error (i.e. not `nil`)\n// and that it is equal to the provided error.\n//\n//\tactualObj, err := SomeFunction()\n//\ta.EqualErrorf(err,  expectedErrorString, \"error message %s\", \"formatted\")\nfunc (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualErrorf(a.t, theError, errString, msg, args...)\n}\n\n// EqualExportedValues asserts that the types of two objects are equal and their public\n// fields are also equal. This is useful for comparing structs that have private fields\n// that could potentially differ.\n//\n//\t type S struct {\n//\t\tExported     \tint\n//\t\tnotExported   \tint\n//\t }\n//\t a.EqualExportedValues(S{1, 2}, S{1, 3}) => true\n//\t a.EqualExportedValues(S{1, 2}, S{2, 3}) => false\nfunc (a *Assertions) EqualExportedValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualExportedValues(a.t, expected, actual, msgAndArgs...)\n}\n\n// EqualExportedValuesf asserts that the types of two objects are equal and their public\n// fields are also equal. This is useful for comparing structs that have private fields\n// that could potentially differ.\n//\n//\t type S struct {\n//\t\tExported     \tint\n//\t\tnotExported   \tint\n//\t }\n//\t a.EqualExportedValuesf(S{1, 2}, S{1, 3}, \"error message %s\", \"formatted\") => true\n//\t a.EqualExportedValuesf(S{1, 2}, S{2, 3}, \"error message %s\", \"formatted\") => false\nfunc (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualExportedValuesf(a.t, expected, actual, msg, args...)\n}\n\n// EqualValues asserts that two objects are equal or convertible to the larger\n// type and equal.\n//\n//\ta.EqualValues(uint32(123), int32(123))\nfunc (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualValues(a.t, expected, actual, msgAndArgs...)\n}\n\n// EqualValuesf asserts that two objects are equal or convertible to the larger\n// type and equal.\n//\n//\ta.EqualValuesf(uint32(123), int32(123), \"error message %s\", \"formatted\")\nfunc (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualValuesf(a.t, expected, actual, msg, args...)\n}\n\n// Equalf asserts that two objects are equal.\n//\n//\ta.Equalf(123, 123, \"error message %s\", \"formatted\")\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses). Function equality\n// cannot be determined and will always fail.\nfunc (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Equalf(a.t, expected, actual, msg, args...)\n}\n\n// Error asserts that a function returned an error (i.e. not `nil`).\n//\n//\tactualObj, err := SomeFunction()\n//\ta.Error(err)\nfunc (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Error(a.t, err, msgAndArgs...)\n}\n\n// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.\n// This is a wrapper for errors.As.\nfunc (a *Assertions) ErrorAs(err error, target interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorAs(a.t, err, target, msgAndArgs...)\n}\n\n// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.\n// This is a wrapper for errors.As.\nfunc (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorAsf(a.t, err, target, msg, args...)\n}\n\n// ErrorContains asserts that a function returned an error (i.e. not `nil`)\n// and that the error contains the specified substring.\n//\n//\tactualObj, err := SomeFunction()\n//\ta.ErrorContains(err,  expectedErrorSubString)\nfunc (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorContains(a.t, theError, contains, msgAndArgs...)\n}\n\n// ErrorContainsf asserts that a function returned an error (i.e. not `nil`)\n// and that the error contains the specified substring.\n//\n//\tactualObj, err := SomeFunction()\n//\ta.ErrorContainsf(err,  expectedErrorSubString, \"error message %s\", \"formatted\")\nfunc (a *Assertions) ErrorContainsf(theError error, contains string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorContainsf(a.t, theError, contains, msg, args...)\n}\n\n// ErrorIs asserts that at least one of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc (a *Assertions) ErrorIs(err error, target error, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorIs(a.t, err, target, msgAndArgs...)\n}\n\n// ErrorIsf asserts that at least one of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc (a *Assertions) ErrorIsf(err error, target error, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorIsf(a.t, err, target, msg, args...)\n}\n\n// Errorf asserts that a function returned an error (i.e. not `nil`).\n//\n//\tactualObj, err := SomeFunction()\n//\ta.Errorf(err, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Errorf(a.t, err, msg, args...)\n}\n\n// Eventually asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick.\n//\n//\ta.Eventually(func() bool { return true; }, time.Second, 10*time.Millisecond)\nfunc (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Eventually(a.t, condition, waitFor, tick, msgAndArgs...)\n}\n\n// EventuallyWithT asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick. In contrast to Eventually,\n// it supplies a CollectT to the condition function, so that the condition\n// function can use the CollectT to call other assertions.\n// The condition is considered \"met\" if no errors are raised in a tick.\n// The supplied CollectT collects all errors from one tick (if there are any).\n// If the condition is not met before waitFor, the collected errors of\n// the last tick are copied to t.\n//\n//\texternalValue := false\n//\tgo func() {\n//\t\ttime.Sleep(8*time.Second)\n//\t\texternalValue = true\n//\t}()\n//\ta.EventuallyWithT(func(c *assert.CollectT) {\n//\t\t// add assertions as needed; any assertion failure will fail the current tick\n//\t\tassert.True(c, externalValue, \"expected 'externalValue' to be true\")\n//\t}, 10*time.Second, 1*time.Second, \"external state has not changed to 'true'; still false\")\nfunc (a *Assertions) EventuallyWithT(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EventuallyWithT(a.t, condition, waitFor, tick, msgAndArgs...)\n}\n\n// EventuallyWithTf asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick. In contrast to Eventually,\n// it supplies a CollectT to the condition function, so that the condition\n// function can use the CollectT to call other assertions.\n// The condition is considered \"met\" if no errors are raised in a tick.\n// The supplied CollectT collects all errors from one tick (if there are any).\n// If the condition is not met before waitFor, the collected errors of\n// the last tick are copied to t.\n//\n//\texternalValue := false\n//\tgo func() {\n//\t\ttime.Sleep(8*time.Second)\n//\t\texternalValue = true\n//\t}()\n//\ta.EventuallyWithTf(func(c *assert.CollectT, \"error message %s\", \"formatted\") {\n//\t\t// add assertions as needed; any assertion failure will fail the current tick\n//\t\tassert.True(c, externalValue, \"expected 'externalValue' to be true\")\n//\t}, 10*time.Second, 1*time.Second, \"external state has not changed to 'true'; still false\")\nfunc (a *Assertions) EventuallyWithTf(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EventuallyWithTf(a.t, condition, waitFor, tick, msg, args...)\n}\n\n// Eventuallyf asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick.\n//\n//\ta.Eventuallyf(func() bool { return true; }, time.Second, 10*time.Millisecond, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Eventuallyf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Eventuallyf(a.t, condition, waitFor, tick, msg, args...)\n}\n\n// Exactly asserts that two objects are equal in value and type.\n//\n//\ta.Exactly(int32(123), int64(123))\nfunc (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Exactly(a.t, expected, actual, msgAndArgs...)\n}\n\n// Exactlyf asserts that two objects are equal in value and type.\n//\n//\ta.Exactlyf(int32(123), int64(123), \"error message %s\", \"formatted\")\nfunc (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Exactlyf(a.t, expected, actual, msg, args...)\n}\n\n// Fail reports a failure through\nfunc (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Fail(a.t, failureMessage, msgAndArgs...)\n}\n\n// FailNow fails test\nfunc (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn FailNow(a.t, failureMessage, msgAndArgs...)\n}\n\n// FailNowf fails test\nfunc (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn FailNowf(a.t, failureMessage, msg, args...)\n}\n\n// Failf reports a failure through\nfunc (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Failf(a.t, failureMessage, msg, args...)\n}\n\n// False asserts that the specified value is false.\n//\n//\ta.False(myBool)\nfunc (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn False(a.t, value, msgAndArgs...)\n}\n\n// Falsef asserts that the specified value is false.\n//\n//\ta.Falsef(myBool, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Falsef(value bool, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Falsef(a.t, value, msg, args...)\n}\n\n// FileExists checks whether a file exists in the given path. It also fails if\n// the path points to a directory or there is an error when trying to check the file.\nfunc (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn FileExists(a.t, path, msgAndArgs...)\n}\n\n// FileExistsf checks whether a file exists in the given path. It also fails if\n// the path points to a directory or there is an error when trying to check the file.\nfunc (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn FileExistsf(a.t, path, msg, args...)\n}\n\n// Greater asserts that the first element is greater than the second\n//\n//\ta.Greater(2, 1)\n//\ta.Greater(float64(2), float64(1))\n//\ta.Greater(\"b\", \"a\")\nfunc (a *Assertions) Greater(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Greater(a.t, e1, e2, msgAndArgs...)\n}\n\n// GreaterOrEqual asserts that the first element is greater than or equal to the second\n//\n//\ta.GreaterOrEqual(2, 1)\n//\ta.GreaterOrEqual(2, 2)\n//\ta.GreaterOrEqual(\"b\", \"a\")\n//\ta.GreaterOrEqual(\"b\", \"b\")\nfunc (a *Assertions) GreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn GreaterOrEqual(a.t, e1, e2, msgAndArgs...)\n}\n\n// GreaterOrEqualf asserts that the first element is greater than or equal to the second\n//\n//\ta.GreaterOrEqualf(2, 1, \"error message %s\", \"formatted\")\n//\ta.GreaterOrEqualf(2, 2, \"error message %s\", \"formatted\")\n//\ta.GreaterOrEqualf(\"b\", \"a\", \"error message %s\", \"formatted\")\n//\ta.GreaterOrEqualf(\"b\", \"b\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) GreaterOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn GreaterOrEqualf(a.t, e1, e2, msg, args...)\n}\n\n// Greaterf asserts that the first element is greater than the second\n//\n//\ta.Greaterf(2, 1, \"error message %s\", \"formatted\")\n//\ta.Greaterf(float64(2), float64(1), \"error message %s\", \"formatted\")\n//\ta.Greaterf(\"b\", \"a\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Greaterf(a.t, e1, e2, msg, args...)\n}\n\n// HTTPBodyContains asserts that a specified handler returns a\n// body that contains a string.\n//\n//\ta.HTTPBodyContains(myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...)\n}\n\n// HTTPBodyContainsf asserts that a specified handler returns a\n// body that contains a string.\n//\n//\ta.HTTPBodyContainsf(myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\", \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...)\n}\n\n// HTTPBodyNotContains asserts that a specified handler returns a\n// body that does not contain a string.\n//\n//\ta.HTTPBodyNotContains(myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...)\n}\n\n// HTTPBodyNotContainsf asserts that a specified handler returns a\n// body that does not contain a string.\n//\n//\ta.HTTPBodyNotContainsf(myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\", \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...)\n}\n\n// HTTPError asserts that a specified handler returns an error status code.\n//\n//\ta.HTTPError(myHandler, \"POST\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPError(a.t, handler, method, url, values, msgAndArgs...)\n}\n\n// HTTPErrorf asserts that a specified handler returns an error status code.\n//\n//\ta.HTTPErrorf(myHandler, \"POST\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPErrorf(a.t, handler, method, url, values, msg, args...)\n}\n\n// HTTPRedirect asserts that a specified handler returns a redirect status code.\n//\n//\ta.HTTPRedirect(myHandler, \"GET\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPRedirect(a.t, handler, method, url, values, msgAndArgs...)\n}\n\n// HTTPRedirectf asserts that a specified handler returns a redirect status code.\n//\n//\ta.HTTPRedirectf(myHandler, \"GET\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPRedirectf(a.t, handler, method, url, values, msg, args...)\n}\n\n// HTTPStatusCode asserts that a specified handler returns a specified status code.\n//\n//\ta.HTTPStatusCode(myHandler, \"GET\", \"/notImplemented\", nil, 501)\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPStatusCode(a.t, handler, method, url, values, statuscode, msgAndArgs...)\n}\n\n// HTTPStatusCodef asserts that a specified handler returns a specified status code.\n//\n//\ta.HTTPStatusCodef(myHandler, \"GET\", \"/notImplemented\", nil, 501, \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPStatusCodef(a.t, handler, method, url, values, statuscode, msg, args...)\n}\n\n// HTTPSuccess asserts that a specified handler returns a success status code.\n//\n//\ta.HTTPSuccess(myHandler, \"POST\", \"http://www.google.com\", nil)\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPSuccess(a.t, handler, method, url, values, msgAndArgs...)\n}\n\n// HTTPSuccessf asserts that a specified handler returns a success status code.\n//\n//\ta.HTTPSuccessf(myHandler, \"POST\", \"http://www.google.com\", nil, \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPSuccessf(a.t, handler, method, url, values, msg, args...)\n}\n\n// Implements asserts that an object is implemented by the specified interface.\n//\n//\ta.Implements((*MyInterface)(nil), new(MyObject))\nfunc (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Implements(a.t, interfaceObject, object, msgAndArgs...)\n}\n\n// Implementsf asserts that an object is implemented by the specified interface.\n//\n//\ta.Implementsf((*MyInterface)(nil), new(MyObject), \"error message %s\", \"formatted\")\nfunc (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Implementsf(a.t, interfaceObject, object, msg, args...)\n}\n\n// InDelta asserts that the two numerals are within delta of each other.\n//\n//\ta.InDelta(math.Pi, 22/7.0, 0.01)\nfunc (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDelta(a.t, expected, actual, delta, msgAndArgs...)\n}\n\n// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.\nfunc (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...)\n}\n\n// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.\nfunc (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...)\n}\n\n// InDeltaSlice is the same as InDelta, except it compares two slices.\nfunc (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...)\n}\n\n// InDeltaSlicef is the same as InDelta, except it compares two slices.\nfunc (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDeltaSlicef(a.t, expected, actual, delta, msg, args...)\n}\n\n// InDeltaf asserts that the two numerals are within delta of each other.\n//\n//\ta.InDeltaf(math.Pi, 22/7.0, 0.01, \"error message %s\", \"formatted\")\nfunc (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDeltaf(a.t, expected, actual, delta, msg, args...)\n}\n\n// InEpsilon asserts that expected and actual have a relative error less than epsilon\nfunc (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)\n}\n\n// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.\nfunc (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...)\n}\n\n// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.\nfunc (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...)\n}\n\n// InEpsilonf asserts that expected and actual have a relative error less than epsilon\nfunc (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InEpsilonf(a.t, expected, actual, epsilon, msg, args...)\n}\n\n// IsDecreasing asserts that the collection is decreasing\n//\n//\ta.IsDecreasing([]int{2, 1, 0})\n//\ta.IsDecreasing([]float{2, 1})\n//\ta.IsDecreasing([]string{\"b\", \"a\"})\nfunc (a *Assertions) IsDecreasing(object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsDecreasing(a.t, object, msgAndArgs...)\n}\n\n// IsDecreasingf asserts that the collection is decreasing\n//\n//\ta.IsDecreasingf([]int{2, 1, 0}, \"error message %s\", \"formatted\")\n//\ta.IsDecreasingf([]float{2, 1}, \"error message %s\", \"formatted\")\n//\ta.IsDecreasingf([]string{\"b\", \"a\"}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsDecreasingf(object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsDecreasingf(a.t, object, msg, args...)\n}\n\n// IsIncreasing asserts that the collection is increasing\n//\n//\ta.IsIncreasing([]int{1, 2, 3})\n//\ta.IsIncreasing([]float{1, 2})\n//\ta.IsIncreasing([]string{\"a\", \"b\"})\nfunc (a *Assertions) IsIncreasing(object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsIncreasing(a.t, object, msgAndArgs...)\n}\n\n// IsIncreasingf asserts that the collection is increasing\n//\n//\ta.IsIncreasingf([]int{1, 2, 3}, \"error message %s\", \"formatted\")\n//\ta.IsIncreasingf([]float{1, 2}, \"error message %s\", \"formatted\")\n//\ta.IsIncreasingf([]string{\"a\", \"b\"}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsIncreasingf(object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsIncreasingf(a.t, object, msg, args...)\n}\n\n// IsNonDecreasing asserts that the collection is not decreasing\n//\n//\ta.IsNonDecreasing([]int{1, 1, 2})\n//\ta.IsNonDecreasing([]float{1, 2})\n//\ta.IsNonDecreasing([]string{\"a\", \"b\"})\nfunc (a *Assertions) IsNonDecreasing(object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsNonDecreasing(a.t, object, msgAndArgs...)\n}\n\n// IsNonDecreasingf asserts that the collection is not decreasing\n//\n//\ta.IsNonDecreasingf([]int{1, 1, 2}, \"error message %s\", \"formatted\")\n//\ta.IsNonDecreasingf([]float{1, 2}, \"error message %s\", \"formatted\")\n//\ta.IsNonDecreasingf([]string{\"a\", \"b\"}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsNonDecreasingf(object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsNonDecreasingf(a.t, object, msg, args...)\n}\n\n// IsNonIncreasing asserts that the collection is not increasing\n//\n//\ta.IsNonIncreasing([]int{2, 1, 1})\n//\ta.IsNonIncreasing([]float{2, 1})\n//\ta.IsNonIncreasing([]string{\"b\", \"a\"})\nfunc (a *Assertions) IsNonIncreasing(object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsNonIncreasing(a.t, object, msgAndArgs...)\n}\n\n// IsNonIncreasingf asserts that the collection is not increasing\n//\n//\ta.IsNonIncreasingf([]int{2, 1, 1}, \"error message %s\", \"formatted\")\n//\ta.IsNonIncreasingf([]float{2, 1}, \"error message %s\", \"formatted\")\n//\ta.IsNonIncreasingf([]string{\"b\", \"a\"}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsNonIncreasingf(a.t, object, msg, args...)\n}\n\n// IsNotType asserts that the specified objects are not of the same type.\n//\n//\ta.IsNotType(&NotMyStruct{}, &MyStruct{})\nfunc (a *Assertions) IsNotType(theType interface{}, object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsNotType(a.t, theType, object, msgAndArgs...)\n}\n\n// IsNotTypef asserts that the specified objects are not of the same type.\n//\n//\ta.IsNotTypef(&NotMyStruct{}, &MyStruct{}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsNotTypef(theType interface{}, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsNotTypef(a.t, theType, object, msg, args...)\n}\n\n// IsType asserts that the specified objects are of the same type.\n//\n//\ta.IsType(&MyStruct{}, &MyStruct{})\nfunc (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsType(a.t, expectedType, object, msgAndArgs...)\n}\n\n// IsTypef asserts that the specified objects are of the same type.\n//\n//\ta.IsTypef(&MyStruct{}, &MyStruct{}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsTypef(a.t, expectedType, object, msg, args...)\n}\n\n// JSONEq asserts that two JSON strings are equivalent.\n//\n//\ta.JSONEq(`{\"hello\": \"world\", \"foo\": \"bar\"}`, `{\"foo\": \"bar\", \"hello\": \"world\"}`)\nfunc (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn JSONEq(a.t, expected, actual, msgAndArgs...)\n}\n\n// JSONEqf asserts that two JSON strings are equivalent.\n//\n//\ta.JSONEqf(`{\"hello\": \"world\", \"foo\": \"bar\"}`, `{\"foo\": \"bar\", \"hello\": \"world\"}`, \"error message %s\", \"formatted\")\nfunc (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn JSONEqf(a.t, expected, actual, msg, args...)\n}\n\n// Len asserts that the specified object has specific length.\n// Len also fails if the object has a type that len() not accept.\n//\n//\ta.Len(mySlice, 3)\nfunc (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Len(a.t, object, length, msgAndArgs...)\n}\n\n// Lenf asserts that the specified object has specific length.\n// Lenf also fails if the object has a type that len() not accept.\n//\n//\ta.Lenf(mySlice, 3, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Lenf(a.t, object, length, msg, args...)\n}\n\n// Less asserts that the first element is less than the second\n//\n//\ta.Less(1, 2)\n//\ta.Less(float64(1), float64(2))\n//\ta.Less(\"a\", \"b\")\nfunc (a *Assertions) Less(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Less(a.t, e1, e2, msgAndArgs...)\n}\n\n// LessOrEqual asserts that the first element is less than or equal to the second\n//\n//\ta.LessOrEqual(1, 2)\n//\ta.LessOrEqual(2, 2)\n//\ta.LessOrEqual(\"a\", \"b\")\n//\ta.LessOrEqual(\"b\", \"b\")\nfunc (a *Assertions) LessOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn LessOrEqual(a.t, e1, e2, msgAndArgs...)\n}\n\n// LessOrEqualf asserts that the first element is less than or equal to the second\n//\n//\ta.LessOrEqualf(1, 2, \"error message %s\", \"formatted\")\n//\ta.LessOrEqualf(2, 2, \"error message %s\", \"formatted\")\n//\ta.LessOrEqualf(\"a\", \"b\", \"error message %s\", \"formatted\")\n//\ta.LessOrEqualf(\"b\", \"b\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) LessOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn LessOrEqualf(a.t, e1, e2, msg, args...)\n}\n\n// Lessf asserts that the first element is less than the second\n//\n//\ta.Lessf(1, 2, \"error message %s\", \"formatted\")\n//\ta.Lessf(float64(1), float64(2), \"error message %s\", \"formatted\")\n//\ta.Lessf(\"a\", \"b\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Lessf(a.t, e1, e2, msg, args...)\n}\n\n// Negative asserts that the specified element is negative\n//\n//\ta.Negative(-1)\n//\ta.Negative(-1.23)\nfunc (a *Assertions) Negative(e interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Negative(a.t, e, msgAndArgs...)\n}\n\n// Negativef asserts that the specified element is negative\n//\n//\ta.Negativef(-1, \"error message %s\", \"formatted\")\n//\ta.Negativef(-1.23, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Negativef(e interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Negativef(a.t, e, msg, args...)\n}\n\n// Never asserts that the given condition doesn't satisfy in waitFor time,\n// periodically checking the target function each tick.\n//\n//\ta.Never(func() bool { return false; }, time.Second, 10*time.Millisecond)\nfunc (a *Assertions) Never(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Never(a.t, condition, waitFor, tick, msgAndArgs...)\n}\n\n// Neverf asserts that the given condition doesn't satisfy in waitFor time,\n// periodically checking the target function each tick.\n//\n//\ta.Neverf(func() bool { return false; }, time.Second, 10*time.Millisecond, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Neverf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Neverf(a.t, condition, waitFor, tick, msg, args...)\n}\n\n// Nil asserts that the specified object is nil.\n//\n//\ta.Nil(err)\nfunc (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Nil(a.t, object, msgAndArgs...)\n}\n\n// Nilf asserts that the specified object is nil.\n//\n//\ta.Nilf(err, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Nilf(a.t, object, msg, args...)\n}\n\n// NoDirExists checks whether a directory does not exist in the given path.\n// It fails if the path points to an existing _directory_ only.\nfunc (a *Assertions) NoDirExists(path string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoDirExists(a.t, path, msgAndArgs...)\n}\n\n// NoDirExistsf checks whether a directory does not exist in the given path.\n// It fails if the path points to an existing _directory_ only.\nfunc (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoDirExistsf(a.t, path, msg, args...)\n}\n\n// NoError asserts that a function returned no error (i.e. `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if a.NoError(err) {\n//\t\t   assert.Equal(t, expectedObj, actualObj)\n//\t  }\nfunc (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoError(a.t, err, msgAndArgs...)\n}\n\n// NoErrorf asserts that a function returned no error (i.e. `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if a.NoErrorf(err, \"error message %s\", \"formatted\") {\n//\t\t   assert.Equal(t, expectedObj, actualObj)\n//\t  }\nfunc (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoErrorf(a.t, err, msg, args...)\n}\n\n// NoFileExists checks whether a file does not exist in a given path. It fails\n// if the path points to an existing _file_ only.\nfunc (a *Assertions) NoFileExists(path string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoFileExists(a.t, path, msgAndArgs...)\n}\n\n// NoFileExistsf checks whether a file does not exist in a given path. It fails\n// if the path points to an existing _file_ only.\nfunc (a *Assertions) NoFileExistsf(path string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoFileExistsf(a.t, path, msg, args...)\n}\n\n// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the\n// specified substring or element.\n//\n//\ta.NotContains(\"Hello World\", \"Earth\")\n//\ta.NotContains([\"Hello\", \"World\"], \"Earth\")\n//\ta.NotContains({\"Hello\": \"World\"}, \"Earth\")\nfunc (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotContains(a.t, s, contains, msgAndArgs...)\n}\n\n// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the\n// specified substring or element.\n//\n//\ta.NotContainsf(\"Hello World\", \"Earth\", \"error message %s\", \"formatted\")\n//\ta.NotContainsf([\"Hello\", \"World\"], \"Earth\", \"error message %s\", \"formatted\")\n//\ta.NotContainsf({\"Hello\": \"World\"}, \"Earth\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotContainsf(a.t, s, contains, msg, args...)\n}\n\n// NotElementsMatch asserts that the specified listA(array, slice...) is NOT equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should not match.\n// This is an inverse of ElementsMatch.\n//\n// a.NotElementsMatch([1, 1, 2, 3], [1, 1, 2, 3]) -> false\n//\n// a.NotElementsMatch([1, 1, 2, 3], [1, 2, 3]) -> true\n//\n// a.NotElementsMatch([1, 2, 3], [1, 2, 4]) -> true\nfunc (a *Assertions) NotElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotElementsMatch(a.t, listA, listB, msgAndArgs...)\n}\n\n// NotElementsMatchf asserts that the specified listA(array, slice...) is NOT equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should not match.\n// This is an inverse of ElementsMatch.\n//\n// a.NotElementsMatchf([1, 1, 2, 3], [1, 1, 2, 3], \"error message %s\", \"formatted\") -> false\n//\n// a.NotElementsMatchf([1, 1, 2, 3], [1, 2, 3], \"error message %s\", \"formatted\") -> true\n//\n// a.NotElementsMatchf([1, 2, 3], [1, 2, 4], \"error message %s\", \"formatted\") -> true\nfunc (a *Assertions) NotElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotElementsMatchf(a.t, listA, listB, msg, args...)\n}\n\n// NotEmpty asserts that the specified object is NOT [Empty].\n//\n//\tif a.NotEmpty(obj) {\n//\t  assert.Equal(t, \"two\", obj[1])\n//\t}\nfunc (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEmpty(a.t, object, msgAndArgs...)\n}\n\n// NotEmptyf asserts that the specified object is NOT [Empty].\n//\n//\tif a.NotEmptyf(obj, \"error message %s\", \"formatted\") {\n//\t  assert.Equal(t, \"two\", obj[1])\n//\t}\nfunc (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEmptyf(a.t, object, msg, args...)\n}\n\n// NotEqual asserts that the specified values are NOT equal.\n//\n//\ta.NotEqual(obj1, obj2)\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses).\nfunc (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEqual(a.t, expected, actual, msgAndArgs...)\n}\n\n// NotEqualValues asserts that two objects are not equal even when converted to the same type\n//\n//\ta.NotEqualValues(obj1, obj2)\nfunc (a *Assertions) NotEqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEqualValues(a.t, expected, actual, msgAndArgs...)\n}\n\n// NotEqualValuesf asserts that two objects are not equal even when converted to the same type\n//\n//\ta.NotEqualValuesf(obj1, obj2, \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotEqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEqualValuesf(a.t, expected, actual, msg, args...)\n}\n\n// NotEqualf asserts that the specified values are NOT equal.\n//\n//\ta.NotEqualf(obj1, obj2, \"error message %s\", \"formatted\")\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses).\nfunc (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEqualf(a.t, expected, actual, msg, args...)\n}\n\n// NotErrorAs asserts that none of the errors in err's chain matches target,\n// but if so, sets target to that error value.\nfunc (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotErrorAs(a.t, err, target, msgAndArgs...)\n}\n\n// NotErrorAsf asserts that none of the errors in err's chain matches target,\n// but if so, sets target to that error value.\nfunc (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotErrorAsf(a.t, err, target, msg, args...)\n}\n\n// NotErrorIs asserts that none of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotErrorIs(a.t, err, target, msgAndArgs...)\n}\n\n// NotErrorIsf asserts that none of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotErrorIsf(a.t, err, target, msg, args...)\n}\n\n// NotImplements asserts that an object does not implement the specified interface.\n//\n//\ta.NotImplements((*MyInterface)(nil), new(MyObject))\nfunc (a *Assertions) NotImplements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotImplements(a.t, interfaceObject, object, msgAndArgs...)\n}\n\n// NotImplementsf asserts that an object does not implement the specified interface.\n//\n//\ta.NotImplementsf((*MyInterface)(nil), new(MyObject), \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotImplementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotImplementsf(a.t, interfaceObject, object, msg, args...)\n}\n\n// NotNil asserts that the specified object is not nil.\n//\n//\ta.NotNil(err)\nfunc (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotNil(a.t, object, msgAndArgs...)\n}\n\n// NotNilf asserts that the specified object is not nil.\n//\n//\ta.NotNilf(err, \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotNilf(a.t, object, msg, args...)\n}\n\n// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.\n//\n//\ta.NotPanics(func(){ RemainCalm() })\nfunc (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotPanics(a.t, f, msgAndArgs...)\n}\n\n// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic.\n//\n//\ta.NotPanicsf(func(){ RemainCalm() }, \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotPanicsf(a.t, f, msg, args...)\n}\n\n// NotRegexp asserts that a specified regexp does not match a string.\n//\n//\ta.NotRegexp(regexp.MustCompile(\"starts\"), \"it's starting\")\n//\ta.NotRegexp(\"^start\", \"it's not starting\")\nfunc (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotRegexp(a.t, rx, str, msgAndArgs...)\n}\n\n// NotRegexpf asserts that a specified regexp does not match a string.\n//\n//\ta.NotRegexpf(regexp.MustCompile(\"starts\"), \"it's starting\", \"error message %s\", \"formatted\")\n//\ta.NotRegexpf(\"^start\", \"it's not starting\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotRegexpf(a.t, rx, str, msg, args...)\n}\n\n// NotSame asserts that two pointers do not reference the same object.\n//\n//\ta.NotSame(ptr1, ptr2)\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc (a *Assertions) NotSame(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotSame(a.t, expected, actual, msgAndArgs...)\n}\n\n// NotSamef asserts that two pointers do not reference the same object.\n//\n//\ta.NotSamef(ptr1, ptr2, \"error message %s\", \"formatted\")\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotSamef(a.t, expected, actual, msg, args...)\n}\n\n// NotSubset asserts that the list (array, slice, or map) does NOT contain all\n// elements given in the subset (array, slice, or map).\n// Map elements are key-value pairs unless compared with an array or slice where\n// only the map key is evaluated.\n//\n//\ta.NotSubset([1, 3, 4], [1, 2])\n//\ta.NotSubset({\"x\": 1, \"y\": 2}, {\"z\": 3})\n//\ta.NotSubset([1, 3, 4], {1: \"one\", 2: \"two\"})\n//\ta.NotSubset({\"x\": 1, \"y\": 2}, [\"z\"])\nfunc (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotSubset(a.t, list, subset, msgAndArgs...)\n}\n\n// NotSubsetf asserts that the list (array, slice, or map) does NOT contain all\n// elements given in the subset (array, slice, or map).\n// Map elements are key-value pairs unless compared with an array or slice where\n// only the map key is evaluated.\n//\n//\ta.NotSubsetf([1, 3, 4], [1, 2], \"error message %s\", \"formatted\")\n//\ta.NotSubsetf({\"x\": 1, \"y\": 2}, {\"z\": 3}, \"error message %s\", \"formatted\")\n//\ta.NotSubsetf([1, 3, 4], {1: \"one\", 2: \"two\"}, \"error message %s\", \"formatted\")\n//\ta.NotSubsetf({\"x\": 1, \"y\": 2}, [\"z\"], \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotSubsetf(a.t, list, subset, msg, args...)\n}\n\n// NotZero asserts that i is not the zero value for its type.\nfunc (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotZero(a.t, i, msgAndArgs...)\n}\n\n// NotZerof asserts that i is not the zero value for its type.\nfunc (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotZerof(a.t, i, msg, args...)\n}\n\n// Panics asserts that the code inside the specified PanicTestFunc panics.\n//\n//\ta.Panics(func(){ GoCrazy() })\nfunc (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Panics(a.t, f, msgAndArgs...)\n}\n\n// PanicsWithError asserts that the code inside the specified PanicTestFunc\n// panics, and that the recovered panic value is an error that satisfies the\n// EqualError comparison.\n//\n//\ta.PanicsWithError(\"crazy error\", func(){ GoCrazy() })\nfunc (a *Assertions) PanicsWithError(errString string, f PanicTestFunc, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn PanicsWithError(a.t, errString, f, msgAndArgs...)\n}\n\n// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc\n// panics, and that the recovered panic value is an error that satisfies the\n// EqualError comparison.\n//\n//\ta.PanicsWithErrorf(\"crazy error\", func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc (a *Assertions) PanicsWithErrorf(errString string, f PanicTestFunc, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn PanicsWithErrorf(a.t, errString, f, msg, args...)\n}\n\n// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that\n// the recovered panic value equals the expected panic value.\n//\n//\ta.PanicsWithValue(\"crazy error\", func(){ GoCrazy() })\nfunc (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn PanicsWithValue(a.t, expected, f, msgAndArgs...)\n}\n\n// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that\n// the recovered panic value equals the expected panic value.\n//\n//\ta.PanicsWithValuef(\"crazy error\", func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn PanicsWithValuef(a.t, expected, f, msg, args...)\n}\n\n// Panicsf asserts that the code inside the specified PanicTestFunc panics.\n//\n//\ta.Panicsf(func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Panicsf(a.t, f, msg, args...)\n}\n\n// Positive asserts that the specified element is positive\n//\n//\ta.Positive(1)\n//\ta.Positive(1.23)\nfunc (a *Assertions) Positive(e interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Positive(a.t, e, msgAndArgs...)\n}\n\n// Positivef asserts that the specified element is positive\n//\n//\ta.Positivef(1, \"error message %s\", \"formatted\")\n//\ta.Positivef(1.23, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Positivef(e interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Positivef(a.t, e, msg, args...)\n}\n\n// Regexp asserts that a specified regexp matches a string.\n//\n//\ta.Regexp(regexp.MustCompile(\"start\"), \"it's starting\")\n//\ta.Regexp(\"start...$\", \"it's not starting\")\nfunc (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Regexp(a.t, rx, str, msgAndArgs...)\n}\n\n// Regexpf asserts that a specified regexp matches a string.\n//\n//\ta.Regexpf(regexp.MustCompile(\"start\"), \"it's starting\", \"error message %s\", \"formatted\")\n//\ta.Regexpf(\"start...$\", \"it's not starting\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Regexpf(a.t, rx, str, msg, args...)\n}\n\n// Same asserts that two pointers reference the same object.\n//\n//\ta.Same(ptr1, ptr2)\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc (a *Assertions) Same(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Same(a.t, expected, actual, msgAndArgs...)\n}\n\n// Samef asserts that two pointers reference the same object.\n//\n//\ta.Samef(ptr1, ptr2, \"error message %s\", \"formatted\")\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc (a *Assertions) Samef(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Samef(a.t, expected, actual, msg, args...)\n}\n\n// Subset asserts that the list (array, slice, or map) contains all elements\n// given in the subset (array, slice, or map).\n// Map elements are key-value pairs unless compared with an array or slice where\n// only the map key is evaluated.\n//\n//\ta.Subset([1, 2, 3], [1, 2])\n//\ta.Subset({\"x\": 1, \"y\": 2}, {\"x\": 1})\n//\ta.Subset([1, 2, 3], {1: \"one\", 2: \"two\"})\n//\ta.Subset({\"x\": 1, \"y\": 2}, [\"x\"])\nfunc (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Subset(a.t, list, subset, msgAndArgs...)\n}\n\n// Subsetf asserts that the list (array, slice, or map) contains all elements\n// given in the subset (array, slice, or map).\n// Map elements are key-value pairs unless compared with an array or slice where\n// only the map key is evaluated.\n//\n//\ta.Subsetf([1, 2, 3], [1, 2], \"error message %s\", \"formatted\")\n//\ta.Subsetf({\"x\": 1, \"y\": 2}, {\"x\": 1}, \"error message %s\", \"formatted\")\n//\ta.Subsetf([1, 2, 3], {1: \"one\", 2: \"two\"}, \"error message %s\", \"formatted\")\n//\ta.Subsetf({\"x\": 1, \"y\": 2}, [\"x\"], \"error message %s\", \"formatted\")\nfunc (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Subsetf(a.t, list, subset, msg, args...)\n}\n\n// True asserts that the specified value is true.\n//\n//\ta.True(myBool)\nfunc (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn True(a.t, value, msgAndArgs...)\n}\n\n// Truef asserts that the specified value is true.\n//\n//\ta.Truef(myBool, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Truef(a.t, value, msg, args...)\n}\n\n// WithinDuration asserts that the two times are within duration delta of each other.\n//\n//\ta.WithinDuration(time.Now(), time.Now(), 10*time.Second)\nfunc (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn WithinDuration(a.t, expected, actual, delta, msgAndArgs...)\n}\n\n// WithinDurationf asserts that the two times are within duration delta of each other.\n//\n//\ta.WithinDurationf(time.Now(), time.Now(), 10*time.Second, \"error message %s\", \"formatted\")\nfunc (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn WithinDurationf(a.t, expected, actual, delta, msg, args...)\n}\n\n// WithinRange asserts that a time is within a time range (inclusive).\n//\n//\ta.WithinRange(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second))\nfunc (a *Assertions) WithinRange(actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn WithinRange(a.t, actual, start, end, msgAndArgs...)\n}\n\n// WithinRangef asserts that a time is within a time range (inclusive).\n//\n//\ta.WithinRangef(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), \"error message %s\", \"formatted\")\nfunc (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn WithinRangef(a.t, actual, start, end, msg, args...)\n}\n\n// YAMLEq asserts that two YAML strings are equivalent.\nfunc (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn YAMLEq(a.t, expected, actual, msgAndArgs...)\n}\n\n// YAMLEqf asserts that two YAML strings are equivalent.\nfunc (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn YAMLEqf(a.t, expected, actual, msg, args...)\n}\n\n// Zero asserts that i is the zero value for its type.\nfunc (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Zero(a.t, i, msgAndArgs...)\n}\n\n// Zerof asserts that i is the zero value for its type.\nfunc (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Zerof(a.t, i, msg, args...)\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl",
    "content": "{{.CommentWithoutT \"a\"}}\nfunc (a *Assertions) {{.DocInfo.Name}}({{.Params}}) bool {\n\tif h, ok := a.t.(tHelper); ok { h.Helper() }\n\treturn {{.DocInfo.Name}}(a.t, {{.ForwardedParams}})\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/assertion_order.go",
    "content": "package assert\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\n// isOrdered checks that collection contains orderable elements.\nfunc isOrdered(t TestingT, object interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool {\n\tobjKind := reflect.TypeOf(object).Kind()\n\tif objKind != reflect.Slice && objKind != reflect.Array {\n\t\treturn false\n\t}\n\n\tobjValue := reflect.ValueOf(object)\n\tobjLen := objValue.Len()\n\n\tif objLen <= 1 {\n\t\treturn true\n\t}\n\n\tvalue := objValue.Index(0)\n\tvalueInterface := value.Interface()\n\tfirstValueKind := value.Kind()\n\n\tfor i := 1; i < objLen; i++ {\n\t\tprevValue := value\n\t\tprevValueInterface := valueInterface\n\n\t\tvalue = objValue.Index(i)\n\t\tvalueInterface = value.Interface()\n\n\t\tcompareResult, isComparable := compare(prevValueInterface, valueInterface, firstValueKind)\n\n\t\tif !isComparable {\n\t\t\treturn Fail(t, fmt.Sprintf(`Can not compare type \"%T\" and \"%T\"`, value, prevValue), msgAndArgs...)\n\t\t}\n\n\t\tif !containsValue(allowedComparesResults, compareResult) {\n\t\t\treturn Fail(t, fmt.Sprintf(failMessage, prevValue, value), msgAndArgs...)\n\t\t}\n\t}\n\n\treturn true\n}\n\n// IsIncreasing asserts that the collection is increasing\n//\n//\tassert.IsIncreasing(t, []int{1, 2, 3})\n//\tassert.IsIncreasing(t, []float{1, 2})\n//\tassert.IsIncreasing(t, []string{\"a\", \"b\"})\nfunc IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {\n\treturn isOrdered(t, object, []compareResult{compareLess}, \"\\\"%v\\\" is not less than \\\"%v\\\"\", msgAndArgs...)\n}\n\n// IsNonIncreasing asserts that the collection is not increasing\n//\n//\tassert.IsNonIncreasing(t, []int{2, 1, 1})\n//\tassert.IsNonIncreasing(t, []float{2, 1})\n//\tassert.IsNonIncreasing(t, []string{\"b\", \"a\"})\nfunc IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {\n\treturn isOrdered(t, object, []compareResult{compareEqual, compareGreater}, \"\\\"%v\\\" is not greater than or equal to \\\"%v\\\"\", msgAndArgs...)\n}\n\n// IsDecreasing asserts that the collection is decreasing\n//\n//\tassert.IsDecreasing(t, []int{2, 1, 0})\n//\tassert.IsDecreasing(t, []float{2, 1})\n//\tassert.IsDecreasing(t, []string{\"b\", \"a\"})\nfunc IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {\n\treturn isOrdered(t, object, []compareResult{compareGreater}, \"\\\"%v\\\" is not greater than \\\"%v\\\"\", msgAndArgs...)\n}\n\n// IsNonDecreasing asserts that the collection is not decreasing\n//\n//\tassert.IsNonDecreasing(t, []int{1, 1, 2})\n//\tassert.IsNonDecreasing(t, []float{1, 2})\n//\tassert.IsNonDecreasing(t, []string{\"a\", \"b\"})\nfunc IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {\n\treturn isOrdered(t, object, []compareResult{compareLess, compareEqual}, \"\\\"%v\\\" is not less than or equal to \\\"%v\\\"\", msgAndArgs...)\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/assertions.go",
    "content": "package assert\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"os\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"time\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n\n\t\"github.com/davecgh/go-spew/spew\"\n\t\"github.com/pmezard/go-difflib/difflib\"\n\n\t// Wrapper around gopkg.in/yaml.v3\n\t\"github.com/stretchr/testify/assert/yaml\"\n)\n\n//go:generate sh -c \"cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_format.go.tmpl\"\n\n// TestingT is an interface wrapper around *testing.T\ntype TestingT interface {\n\tErrorf(format string, args ...interface{})\n}\n\n// ComparisonAssertionFunc is a common function prototype when comparing two values.  Can be useful\n// for table driven tests.\ntype ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) bool\n\n// ValueAssertionFunc is a common function prototype when validating a single value.  Can be useful\n// for table driven tests.\ntype ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool\n\n// BoolAssertionFunc is a common function prototype when validating a bool value.  Can be useful\n// for table driven tests.\ntype BoolAssertionFunc func(TestingT, bool, ...interface{}) bool\n\n// ErrorAssertionFunc is a common function prototype when validating an error value.  Can be useful\n// for table driven tests.\ntype ErrorAssertionFunc func(TestingT, error, ...interface{}) bool\n\n// PanicAssertionFunc is a common function prototype when validating a panic value.  Can be useful\n// for table driven tests.\ntype PanicAssertionFunc = func(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool\n\n// Comparison is a custom function that returns true on success and false on failure\ntype Comparison func() (success bool)\n\n/*\n\tHelper functions\n*/\n\n// ObjectsAreEqual determines if two objects are considered equal.\n//\n// This function does no assertion of any kind.\nfunc ObjectsAreEqual(expected, actual interface{}) bool {\n\tif expected == nil || actual == nil {\n\t\treturn expected == actual\n\t}\n\n\texp, ok := expected.([]byte)\n\tif !ok {\n\t\treturn reflect.DeepEqual(expected, actual)\n\t}\n\n\tact, ok := actual.([]byte)\n\tif !ok {\n\t\treturn false\n\t}\n\tif exp == nil || act == nil {\n\t\treturn exp == nil && act == nil\n\t}\n\treturn bytes.Equal(exp, act)\n}\n\n// copyExportedFields iterates downward through nested data structures and creates a copy\n// that only contains the exported struct fields.\nfunc copyExportedFields(expected interface{}) interface{} {\n\tif isNil(expected) {\n\t\treturn expected\n\t}\n\n\texpectedType := reflect.TypeOf(expected)\n\texpectedKind := expectedType.Kind()\n\texpectedValue := reflect.ValueOf(expected)\n\n\tswitch expectedKind {\n\tcase reflect.Struct:\n\t\tresult := reflect.New(expectedType).Elem()\n\t\tfor i := 0; i < expectedType.NumField(); i++ {\n\t\t\tfield := expectedType.Field(i)\n\t\t\tisExported := field.IsExported()\n\t\t\tif isExported {\n\t\t\t\tfieldValue := expectedValue.Field(i)\n\t\t\t\tif isNil(fieldValue) || isNil(fieldValue.Interface()) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tnewValue := copyExportedFields(fieldValue.Interface())\n\t\t\t\tresult.Field(i).Set(reflect.ValueOf(newValue))\n\t\t\t}\n\t\t}\n\t\treturn result.Interface()\n\n\tcase reflect.Ptr:\n\t\tresult := reflect.New(expectedType.Elem())\n\t\tunexportedRemoved := copyExportedFields(expectedValue.Elem().Interface())\n\t\tresult.Elem().Set(reflect.ValueOf(unexportedRemoved))\n\t\treturn result.Interface()\n\n\tcase reflect.Array, reflect.Slice:\n\t\tvar result reflect.Value\n\t\tif expectedKind == reflect.Array {\n\t\t\tresult = reflect.New(reflect.ArrayOf(expectedValue.Len(), expectedType.Elem())).Elem()\n\t\t} else {\n\t\t\tresult = reflect.MakeSlice(expectedType, expectedValue.Len(), expectedValue.Len())\n\t\t}\n\t\tfor i := 0; i < expectedValue.Len(); i++ {\n\t\t\tindex := expectedValue.Index(i)\n\t\t\tif isNil(index) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tunexportedRemoved := copyExportedFields(index.Interface())\n\t\t\tresult.Index(i).Set(reflect.ValueOf(unexportedRemoved))\n\t\t}\n\t\treturn result.Interface()\n\n\tcase reflect.Map:\n\t\tresult := reflect.MakeMap(expectedType)\n\t\tfor _, k := range expectedValue.MapKeys() {\n\t\t\tindex := expectedValue.MapIndex(k)\n\t\t\tunexportedRemoved := copyExportedFields(index.Interface())\n\t\t\tresult.SetMapIndex(k, reflect.ValueOf(unexportedRemoved))\n\t\t}\n\t\treturn result.Interface()\n\n\tdefault:\n\t\treturn expected\n\t}\n}\n\n// ObjectsExportedFieldsAreEqual determines if the exported (public) fields of two objects are\n// considered equal. This comparison of only exported fields is applied recursively to nested data\n// structures.\n//\n// This function does no assertion of any kind.\n//\n// Deprecated: Use [EqualExportedValues] instead.\nfunc ObjectsExportedFieldsAreEqual(expected, actual interface{}) bool {\n\texpectedCleaned := copyExportedFields(expected)\n\tactualCleaned := copyExportedFields(actual)\n\treturn ObjectsAreEqualValues(expectedCleaned, actualCleaned)\n}\n\n// ObjectsAreEqualValues gets whether two objects are equal, or if their\n// values are equal.\nfunc ObjectsAreEqualValues(expected, actual interface{}) bool {\n\tif ObjectsAreEqual(expected, actual) {\n\t\treturn true\n\t}\n\n\texpectedValue := reflect.ValueOf(expected)\n\tactualValue := reflect.ValueOf(actual)\n\tif !expectedValue.IsValid() || !actualValue.IsValid() {\n\t\treturn false\n\t}\n\n\texpectedType := expectedValue.Type()\n\tactualType := actualValue.Type()\n\tif !expectedType.ConvertibleTo(actualType) {\n\t\treturn false\n\t}\n\n\tif !isNumericType(expectedType) || !isNumericType(actualType) {\n\t\t// Attempt comparison after type conversion\n\t\treturn reflect.DeepEqual(\n\t\t\texpectedValue.Convert(actualType).Interface(), actual,\n\t\t)\n\t}\n\n\t// If BOTH values are numeric, there are chances of false positives due\n\t// to overflow or underflow. So, we need to make sure to always convert\n\t// the smaller type to a larger type before comparing.\n\tif expectedType.Size() >= actualType.Size() {\n\t\treturn actualValue.Convert(expectedType).Interface() == expected\n\t}\n\n\treturn expectedValue.Convert(actualType).Interface() == actual\n}\n\n// isNumericType returns true if the type is one of:\n// int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64,\n// float32, float64, complex64, complex128\nfunc isNumericType(t reflect.Type) bool {\n\treturn t.Kind() >= reflect.Int && t.Kind() <= reflect.Complex128\n}\n\n/* CallerInfo is necessary because the assert functions use the testing object\ninternally, causing it to print the file:line of the assert method, rather than where\nthe problem actually occurred in calling code.*/\n\n// CallerInfo returns an array of strings containing the file and line number\n// of each stack frame leading from the current test to the assert call that\n// failed.\nfunc CallerInfo() []string {\n\tvar pc uintptr\n\tvar file string\n\tvar line int\n\tvar name string\n\n\tconst stackFrameBufferSize = 10\n\tpcs := make([]uintptr, stackFrameBufferSize)\n\n\tcallers := []string{}\n\toffset := 1\n\n\tfor {\n\t\tn := runtime.Callers(offset, pcs)\n\n\t\tif n == 0 {\n\t\t\tbreak\n\t\t}\n\n\t\tframes := runtime.CallersFrames(pcs[:n])\n\n\t\tfor {\n\t\t\tframe, more := frames.Next()\n\t\t\tpc = frame.PC\n\t\t\tfile = frame.File\n\t\t\tline = frame.Line\n\n\t\t\t// This is a huge edge case, but it will panic if this is the case, see #180\n\t\t\tif file == \"<autogenerated>\" {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tf := runtime.FuncForPC(pc)\n\t\t\tif f == nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tname = f.Name()\n\n\t\t\t// testing.tRunner is the standard library function that calls\n\t\t\t// tests. Subtests are called directly by tRunner, without going through\n\t\t\t// the Test/Benchmark/Example function that contains the t.Run calls, so\n\t\t\t// with subtests we should break when we hit tRunner, without adding it\n\t\t\t// to the list of callers.\n\t\t\tif name == \"testing.tRunner\" {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tparts := strings.Split(file, \"/\")\n\t\t\tif len(parts) > 1 {\n\t\t\t\tfilename := parts[len(parts)-1]\n\t\t\t\tdir := parts[len(parts)-2]\n\t\t\t\tif (dir != \"assert\" && dir != \"mock\" && dir != \"require\") || filename == \"mock_test.go\" {\n\t\t\t\t\tcallers = append(callers, fmt.Sprintf(\"%s:%d\", file, line))\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Drop the package\n\t\t\tdotPos := strings.LastIndexByte(name, '.')\n\t\t\tname = name[dotPos+1:]\n\t\t\tif isTest(name, \"Test\") ||\n\t\t\t\tisTest(name, \"Benchmark\") ||\n\t\t\t\tisTest(name, \"Example\") {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif !more {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Next batch\n\t\toffset += cap(pcs)\n\t}\n\n\treturn callers\n}\n\n// Stolen from the `go test` tool.\n// isTest tells whether name looks like a test (or benchmark, according to prefix).\n// It is a Test (say) if there is a character after Test that is not a lower-case letter.\n// We don't want TesticularCancer.\nfunc isTest(name, prefix string) bool {\n\tif !strings.HasPrefix(name, prefix) {\n\t\treturn false\n\t}\n\tif len(name) == len(prefix) { // \"Test\" is ok\n\t\treturn true\n\t}\n\tr, _ := utf8.DecodeRuneInString(name[len(prefix):])\n\treturn !unicode.IsLower(r)\n}\n\nfunc messageFromMsgAndArgs(msgAndArgs ...interface{}) string {\n\tif len(msgAndArgs) == 0 || msgAndArgs == nil {\n\t\treturn \"\"\n\t}\n\tif len(msgAndArgs) == 1 {\n\t\tmsg := msgAndArgs[0]\n\t\tif msgAsStr, ok := msg.(string); ok {\n\t\t\treturn msgAsStr\n\t\t}\n\t\treturn fmt.Sprintf(\"%+v\", msg)\n\t}\n\tif len(msgAndArgs) > 1 {\n\t\treturn fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)\n\t}\n\treturn \"\"\n}\n\n// Aligns the provided message so that all lines after the first line start at the same location as the first line.\n// Assumes that the first line starts at the correct location (after carriage return, tab, label, spacer and tab).\n// The longestLabelLen parameter specifies the length of the longest label in the output (required because this is the\n// basis on which the alignment occurs).\nfunc indentMessageLines(message string, longestLabelLen int) string {\n\toutBuf := new(bytes.Buffer)\n\n\tfor i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ {\n\t\t// no need to align first line because it starts at the correct location (after the label)\n\t\tif i != 0 {\n\t\t\t// append alignLen+1 spaces to align with \"{{longestLabel}}:\" before adding tab\n\t\t\toutBuf.WriteString(\"\\n\\t\" + strings.Repeat(\" \", longestLabelLen+1) + \"\\t\")\n\t\t}\n\t\toutBuf.WriteString(scanner.Text())\n\t}\n\n\treturn outBuf.String()\n}\n\ntype failNower interface {\n\tFailNow()\n}\n\n// FailNow fails test\nfunc FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFail(t, failureMessage, msgAndArgs...)\n\n\t// We cannot extend TestingT with FailNow() and\n\t// maintain backwards compatibility, so we fallback\n\t// to panicking when FailNow is not available in\n\t// TestingT.\n\t// See issue #263\n\n\tif t, ok := t.(failNower); ok {\n\t\tt.FailNow()\n\t} else {\n\t\tpanic(\"test failed and t is missing `FailNow()`\")\n\t}\n\treturn false\n}\n\n// Fail reports a failure through\nfunc Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tcontent := []labeledContent{\n\t\t{\"Error Trace\", strings.Join(CallerInfo(), \"\\n\\t\\t\\t\")},\n\t\t{\"Error\", failureMessage},\n\t}\n\n\t// Add test name if the Go version supports it\n\tif n, ok := t.(interface {\n\t\tName() string\n\t}); ok {\n\t\tcontent = append(content, labeledContent{\"Test\", n.Name()})\n\t}\n\n\tmessage := messageFromMsgAndArgs(msgAndArgs...)\n\tif len(message) > 0 {\n\t\tcontent = append(content, labeledContent{\"Messages\", message})\n\t}\n\n\tt.Errorf(\"\\n%s\", \"\"+labeledOutput(content...))\n\n\treturn false\n}\n\ntype labeledContent struct {\n\tlabel   string\n\tcontent string\n}\n\n// labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner:\n//\n//\t\\t{{label}}:{{align_spaces}}\\t{{content}}\\n\n//\n// The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The \"\\t{{label}}:\" is for the label.\n// If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this\n// alignment is achieved, \"\\t{{content}}\\n\" is added for the output.\n//\n// If the content of the labeledOutput contains line breaks, the subsequent lines are aligned so that they start at the same location as the first line.\nfunc labeledOutput(content ...labeledContent) string {\n\tlongestLabel := 0\n\tfor _, v := range content {\n\t\tif len(v.label) > longestLabel {\n\t\t\tlongestLabel = len(v.label)\n\t\t}\n\t}\n\tvar output string\n\tfor _, v := range content {\n\t\toutput += \"\\t\" + v.label + \":\" + strings.Repeat(\" \", longestLabel-len(v.label)) + \"\\t\" + indentMessageLines(v.content, longestLabel) + \"\\n\"\n\t}\n\treturn output\n}\n\n// Implements asserts that an object is implemented by the specified interface.\n//\n//\tassert.Implements(t, (*MyInterface)(nil), new(MyObject))\nfunc Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tinterfaceType := reflect.TypeOf(interfaceObject).Elem()\n\n\tif object == nil {\n\t\treturn Fail(t, fmt.Sprintf(\"Cannot check if nil implements %v\", interfaceType), msgAndArgs...)\n\t}\n\tif !reflect.TypeOf(object).Implements(interfaceType) {\n\t\treturn Fail(t, fmt.Sprintf(\"%T must implement %v\", object, interfaceType), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// NotImplements asserts that an object does not implement the specified interface.\n//\n//\tassert.NotImplements(t, (*MyInterface)(nil), new(MyObject))\nfunc NotImplements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tinterfaceType := reflect.TypeOf(interfaceObject).Elem()\n\n\tif object == nil {\n\t\treturn Fail(t, fmt.Sprintf(\"Cannot check if nil does not implement %v\", interfaceType), msgAndArgs...)\n\t}\n\tif reflect.TypeOf(object).Implements(interfaceType) {\n\t\treturn Fail(t, fmt.Sprintf(\"%T implements %v\", object, interfaceType), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\nfunc isType(expectedType, object interface{}) bool {\n\treturn ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType))\n}\n\n// IsType asserts that the specified objects are of the same type.\n//\n//\tassert.IsType(t, &MyStruct{}, &MyStruct{})\nfunc IsType(t TestingT, expectedType, object interface{}, msgAndArgs ...interface{}) bool {\n\tif isType(expectedType, object) {\n\t\treturn true\n\t}\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Fail(t, fmt.Sprintf(\"Object expected to be of type %T, but was %T\", expectedType, object), msgAndArgs...)\n}\n\n// IsNotType asserts that the specified objects are not of the same type.\n//\n//\tassert.IsNotType(t, &NotMyStruct{}, &MyStruct{})\nfunc IsNotType(t TestingT, theType, object interface{}, msgAndArgs ...interface{}) bool {\n\tif !isType(theType, object) {\n\t\treturn true\n\t}\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Fail(t, fmt.Sprintf(\"Object type expected to be different than %T\", theType), msgAndArgs...)\n}\n\n// Equal asserts that two objects are equal.\n//\n//\tassert.Equal(t, 123, 123)\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses). Function equality\n// cannot be determined and will always fail.\nfunc Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif err := validateEqualArgs(expected, actual); err != nil {\n\t\treturn Fail(t, fmt.Sprintf(\"Invalid operation: %#v == %#v (%s)\",\n\t\t\texpected, actual, err), msgAndArgs...)\n\t}\n\n\tif !ObjectsAreEqual(expected, actual) {\n\t\tdiff := diff(expected, actual)\n\t\texpected, actual = formatUnequalValues(expected, actual)\n\t\treturn Fail(t, fmt.Sprintf(\"Not equal: \\n\"+\n\t\t\t\"expected: %s\\n\"+\n\t\t\t\"actual  : %s%s\", expected, actual, diff), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// validateEqualArgs checks whether provided arguments can be safely used in the\n// Equal/NotEqual functions.\nfunc validateEqualArgs(expected, actual interface{}) error {\n\tif expected == nil && actual == nil {\n\t\treturn nil\n\t}\n\n\tif isFunction(expected) || isFunction(actual) {\n\t\treturn errors.New(\"cannot take func type as argument\")\n\t}\n\treturn nil\n}\n\n// Same asserts that two pointers reference the same object.\n//\n//\tassert.Same(t, ptr1, ptr2)\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tsame, ok := samePointers(expected, actual)\n\tif !ok {\n\t\treturn Fail(t, \"Both arguments must be pointers\", msgAndArgs...)\n\t}\n\n\tif !same {\n\t\t// both are pointers but not the same type & pointing to the same address\n\t\treturn Fail(t, fmt.Sprintf(\"Not same: \\n\"+\n\t\t\t\"expected: %p %#[1]v\\n\"+\n\t\t\t\"actual  : %p %#[2]v\",\n\t\t\texpected, actual), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// NotSame asserts that two pointers do not reference the same object.\n//\n//\tassert.NotSame(t, ptr1, ptr2)\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tsame, ok := samePointers(expected, actual)\n\tif !ok {\n\t\t// fails when the arguments are not pointers\n\t\treturn !(Fail(t, \"Both arguments must be pointers\", msgAndArgs...))\n\t}\n\n\tif same {\n\t\treturn Fail(t, fmt.Sprintf(\n\t\t\t\"Expected and actual point to the same object: %p %#[1]v\",\n\t\t\texpected), msgAndArgs...)\n\t}\n\treturn true\n}\n\n// samePointers checks if two generic interface objects are pointers of the same\n// type pointing to the same object. It returns two values: same indicating if\n// they are the same type and point to the same object, and ok indicating that\n// both inputs are pointers.\nfunc samePointers(first, second interface{}) (same bool, ok bool) {\n\tfirstPtr, secondPtr := reflect.ValueOf(first), reflect.ValueOf(second)\n\tif firstPtr.Kind() != reflect.Ptr || secondPtr.Kind() != reflect.Ptr {\n\t\treturn false, false // not both are pointers\n\t}\n\n\tfirstType, secondType := reflect.TypeOf(first), reflect.TypeOf(second)\n\tif firstType != secondType {\n\t\treturn false, true // both are pointers, but of different types\n\t}\n\n\t// compare pointer addresses\n\treturn first == second, true\n}\n\n// formatUnequalValues takes two values of arbitrary types and returns string\n// representations appropriate to be presented to the user.\n//\n// If the values are not of like type, the returned strings will be prefixed\n// with the type name, and the value will be enclosed in parentheses similar\n// to a type conversion in the Go grammar.\nfunc formatUnequalValues(expected, actual interface{}) (e string, a string) {\n\tif reflect.TypeOf(expected) != reflect.TypeOf(actual) {\n\t\treturn fmt.Sprintf(\"%T(%s)\", expected, truncatingFormat(expected)),\n\t\t\tfmt.Sprintf(\"%T(%s)\", actual, truncatingFormat(actual))\n\t}\n\tswitch expected.(type) {\n\tcase time.Duration:\n\t\treturn fmt.Sprintf(\"%v\", expected), fmt.Sprintf(\"%v\", actual)\n\t}\n\treturn truncatingFormat(expected), truncatingFormat(actual)\n}\n\n// truncatingFormat formats the data and truncates it if it's too long.\n//\n// This helps keep formatted error messages lines from exceeding the\n// bufio.MaxScanTokenSize max line length that the go testing framework imposes.\nfunc truncatingFormat(data interface{}) string {\n\tvalue := fmt.Sprintf(\"%#v\", data)\n\tmax := bufio.MaxScanTokenSize - 100 // Give us some space the type info too if needed.\n\tif len(value) > max {\n\t\tvalue = value[0:max] + \"<... truncated>\"\n\t}\n\treturn value\n}\n\n// EqualValues asserts that two objects are equal or convertible to the larger\n// type and equal.\n//\n//\tassert.EqualValues(t, uint32(123), int32(123))\nfunc EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tif !ObjectsAreEqualValues(expected, actual) {\n\t\tdiff := diff(expected, actual)\n\t\texpected, actual = formatUnequalValues(expected, actual)\n\t\treturn Fail(t, fmt.Sprintf(\"Not equal: \\n\"+\n\t\t\t\"expected: %s\\n\"+\n\t\t\t\"actual  : %s%s\", expected, actual, diff), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// EqualExportedValues asserts that the types of two objects are equal and their public\n// fields are also equal. This is useful for comparing structs that have private fields\n// that could potentially differ.\n//\n//\t type S struct {\n//\t\tExported     \tint\n//\t\tnotExported   \tint\n//\t }\n//\t assert.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true\n//\t assert.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false\nfunc EqualExportedValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\taType := reflect.TypeOf(expected)\n\tbType := reflect.TypeOf(actual)\n\n\tif aType != bType {\n\t\treturn Fail(t, fmt.Sprintf(\"Types expected to match exactly\\n\\t%v != %v\", aType, bType), msgAndArgs...)\n\t}\n\n\texpected = copyExportedFields(expected)\n\tactual = copyExportedFields(actual)\n\n\tif !ObjectsAreEqualValues(expected, actual) {\n\t\tdiff := diff(expected, actual)\n\t\texpected, actual = formatUnequalValues(expected, actual)\n\t\treturn Fail(t, fmt.Sprintf(\"Not equal (comparing only exported fields): \\n\"+\n\t\t\t\"expected: %s\\n\"+\n\t\t\t\"actual  : %s%s\", expected, actual, diff), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// Exactly asserts that two objects are equal in value and type.\n//\n//\tassert.Exactly(t, int32(123), int64(123))\nfunc Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\taType := reflect.TypeOf(expected)\n\tbType := reflect.TypeOf(actual)\n\n\tif aType != bType {\n\t\treturn Fail(t, fmt.Sprintf(\"Types expected to match exactly\\n\\t%v != %v\", aType, bType), msgAndArgs...)\n\t}\n\n\treturn Equal(t, expected, actual, msgAndArgs...)\n}\n\n// NotNil asserts that the specified object is not nil.\n//\n//\tassert.NotNil(t, err)\nfunc NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {\n\tif !isNil(object) {\n\t\treturn true\n\t}\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Fail(t, \"Expected value not to be nil.\", msgAndArgs...)\n}\n\n// isNil checks if a specified object is nil or not, without Failing.\nfunc isNil(object interface{}) bool {\n\tif object == nil {\n\t\treturn true\n\t}\n\n\tvalue := reflect.ValueOf(object)\n\tswitch value.Kind() {\n\tcase\n\t\treflect.Chan, reflect.Func,\n\t\treflect.Interface, reflect.Map,\n\t\treflect.Ptr, reflect.Slice, reflect.UnsafePointer:\n\n\t\treturn value.IsNil()\n\t}\n\n\treturn false\n}\n\n// Nil asserts that the specified object is nil.\n//\n//\tassert.Nil(t, err)\nfunc Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {\n\tif isNil(object) {\n\t\treturn true\n\t}\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Fail(t, fmt.Sprintf(\"Expected nil, but got: %#v\", object), msgAndArgs...)\n}\n\n// isEmpty gets whether the specified object is considered empty or not.\nfunc isEmpty(object interface{}) bool {\n\t// get nil case out of the way\n\tif object == nil {\n\t\treturn true\n\t}\n\n\treturn isEmptyValue(reflect.ValueOf(object))\n}\n\n// isEmptyValue gets whether the specified reflect.Value is considered empty or not.\nfunc isEmptyValue(objValue reflect.Value) bool {\n\tif objValue.IsZero() {\n\t\treturn true\n\t}\n\t// Special cases of non-zero values that we consider empty\n\tswitch objValue.Kind() {\n\t// collection types are empty when they have no element\n\t// Note: array types are empty when they match their zero-initialized state.\n\tcase reflect.Chan, reflect.Map, reflect.Slice:\n\t\treturn objValue.Len() == 0\n\t// non-nil pointers are empty if the value they point to is empty\n\tcase reflect.Ptr:\n\t\treturn isEmptyValue(objValue.Elem())\n\t}\n\treturn false\n}\n\n// Empty asserts that the given value is \"empty\".\n//\n// [Zero values] are \"empty\".\n//\n// Arrays are \"empty\" if every element is the zero value of the type (stricter than \"empty\").\n//\n// Slices, maps and channels with zero length are \"empty\".\n//\n// Pointer values are \"empty\" if the pointer is nil or if the pointed value is \"empty\".\n//\n//\tassert.Empty(t, obj)\n//\n// [Zero values]: https://go.dev/ref/spec#The_zero_value\nfunc Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {\n\tpass := isEmpty(object)\n\tif !pass {\n\t\tif h, ok := t.(tHelper); ok {\n\t\t\th.Helper()\n\t\t}\n\t\tFail(t, fmt.Sprintf(\"Should be empty, but was %v\", object), msgAndArgs...)\n\t}\n\n\treturn pass\n}\n\n// NotEmpty asserts that the specified object is NOT [Empty].\n//\n//\tif assert.NotEmpty(t, obj) {\n//\t  assert.Equal(t, \"two\", obj[1])\n//\t}\nfunc NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {\n\tpass := !isEmpty(object)\n\tif !pass {\n\t\tif h, ok := t.(tHelper); ok {\n\t\t\th.Helper()\n\t\t}\n\t\tFail(t, fmt.Sprintf(\"Should NOT be empty, but was %v\", object), msgAndArgs...)\n\t}\n\n\treturn pass\n}\n\n// getLen tries to get the length of an object.\n// It returns (0, false) if impossible.\nfunc getLen(x interface{}) (length int, ok bool) {\n\tv := reflect.ValueOf(x)\n\tdefer func() {\n\t\tok = recover() == nil\n\t}()\n\treturn v.Len(), true\n}\n\n// Len asserts that the specified object has specific length.\n// Len also fails if the object has a type that len() not accept.\n//\n//\tassert.Len(t, mySlice, 3)\nfunc Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tl, ok := getLen(object)\n\tif !ok {\n\t\treturn Fail(t, fmt.Sprintf(\"\\\"%v\\\" could not be applied builtin len()\", object), msgAndArgs...)\n\t}\n\n\tif l != length {\n\t\treturn Fail(t, fmt.Sprintf(\"\\\"%v\\\" should have %d item(s), but has %d\", object, length, l), msgAndArgs...)\n\t}\n\treturn true\n}\n\n// True asserts that the specified value is true.\n//\n//\tassert.True(t, myBool)\nfunc True(t TestingT, value bool, msgAndArgs ...interface{}) bool {\n\tif !value {\n\t\tif h, ok := t.(tHelper); ok {\n\t\t\th.Helper()\n\t\t}\n\t\treturn Fail(t, \"Should be true\", msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// False asserts that the specified value is false.\n//\n//\tassert.False(t, myBool)\nfunc False(t TestingT, value bool, msgAndArgs ...interface{}) bool {\n\tif value {\n\t\tif h, ok := t.(tHelper); ok {\n\t\t\th.Helper()\n\t\t}\n\t\treturn Fail(t, \"Should be false\", msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// NotEqual asserts that the specified values are NOT equal.\n//\n//\tassert.NotEqual(t, obj1, obj2)\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses).\nfunc NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif err := validateEqualArgs(expected, actual); err != nil {\n\t\treturn Fail(t, fmt.Sprintf(\"Invalid operation: %#v != %#v (%s)\",\n\t\t\texpected, actual, err), msgAndArgs...)\n\t}\n\n\tif ObjectsAreEqual(expected, actual) {\n\t\treturn Fail(t, fmt.Sprintf(\"Should not be: %#v\\n\", actual), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// NotEqualValues asserts that two objects are not equal even when converted to the same type\n//\n//\tassert.NotEqualValues(t, obj1, obj2)\nfunc NotEqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tif ObjectsAreEqualValues(expected, actual) {\n\t\treturn Fail(t, fmt.Sprintf(\"Should not be: %#v\\n\", actual), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// containsElement try loop over the list check if the list includes the element.\n// return (false, false) if impossible.\n// return (true, false) if element was not found.\n// return (true, true) if element was found.\nfunc containsElement(list interface{}, element interface{}) (ok, found bool) {\n\tlistValue := reflect.ValueOf(list)\n\tlistType := reflect.TypeOf(list)\n\tif listType == nil {\n\t\treturn false, false\n\t}\n\tlistKind := listType.Kind()\n\tdefer func() {\n\t\tif e := recover(); e != nil {\n\t\t\tok = false\n\t\t\tfound = false\n\t\t}\n\t}()\n\n\tif listKind == reflect.String {\n\t\telementValue := reflect.ValueOf(element)\n\t\treturn true, strings.Contains(listValue.String(), elementValue.String())\n\t}\n\n\tif listKind == reflect.Map {\n\t\tmapKeys := listValue.MapKeys()\n\t\tfor i := 0; i < len(mapKeys); i++ {\n\t\t\tif ObjectsAreEqual(mapKeys[i].Interface(), element) {\n\t\t\t\treturn true, true\n\t\t\t}\n\t\t}\n\t\treturn true, false\n\t}\n\n\tfor i := 0; i < listValue.Len(); i++ {\n\t\tif ObjectsAreEqual(listValue.Index(i).Interface(), element) {\n\t\t\treturn true, true\n\t\t}\n\t}\n\treturn true, false\n}\n\n// Contains asserts that the specified string, list(array, slice...) or map contains the\n// specified substring or element.\n//\n//\tassert.Contains(t, \"Hello World\", \"World\")\n//\tassert.Contains(t, [\"Hello\", \"World\"], \"World\")\n//\tassert.Contains(t, {\"Hello\": \"World\"}, \"Hello\")\nfunc Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tok, found := containsElement(s, contains)\n\tif !ok {\n\t\treturn Fail(t, fmt.Sprintf(\"%#v could not be applied builtin len()\", s), msgAndArgs...)\n\t}\n\tif !found {\n\t\treturn Fail(t, fmt.Sprintf(\"%#v does not contain %#v\", s, contains), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the\n// specified substring or element.\n//\n//\tassert.NotContains(t, \"Hello World\", \"Earth\")\n//\tassert.NotContains(t, [\"Hello\", \"World\"], \"Earth\")\n//\tassert.NotContains(t, {\"Hello\": \"World\"}, \"Earth\")\nfunc NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tok, found := containsElement(s, contains)\n\tif !ok {\n\t\treturn Fail(t, fmt.Sprintf(\"%#v could not be applied builtin len()\", s), msgAndArgs...)\n\t}\n\tif found {\n\t\treturn Fail(t, fmt.Sprintf(\"%#v should not contain %#v\", s, contains), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// Subset asserts that the list (array, slice, or map) contains all elements\n// given in the subset (array, slice, or map).\n// Map elements are key-value pairs unless compared with an array or slice where\n// only the map key is evaluated.\n//\n//\tassert.Subset(t, [1, 2, 3], [1, 2])\n//\tassert.Subset(t, {\"x\": 1, \"y\": 2}, {\"x\": 1})\n//\tassert.Subset(t, [1, 2, 3], {1: \"one\", 2: \"two\"})\n//\tassert.Subset(t, {\"x\": 1, \"y\": 2}, [\"x\"])\nfunc Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif subset == nil {\n\t\treturn true // we consider nil to be equal to the nil set\n\t}\n\n\tlistKind := reflect.TypeOf(list).Kind()\n\tif listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map {\n\t\treturn Fail(t, fmt.Sprintf(\"%q has an unsupported type %s\", list, listKind), msgAndArgs...)\n\t}\n\n\tsubsetKind := reflect.TypeOf(subset).Kind()\n\tif subsetKind != reflect.Array && subsetKind != reflect.Slice && subsetKind != reflect.Map {\n\t\treturn Fail(t, fmt.Sprintf(\"%q has an unsupported type %s\", subset, subsetKind), msgAndArgs...)\n\t}\n\n\tif subsetKind == reflect.Map && listKind == reflect.Map {\n\t\tsubsetMap := reflect.ValueOf(subset)\n\t\tactualMap := reflect.ValueOf(list)\n\n\t\tfor _, k := range subsetMap.MapKeys() {\n\t\t\tev := subsetMap.MapIndex(k)\n\t\t\tav := actualMap.MapIndex(k)\n\n\t\t\tif !av.IsValid() {\n\t\t\t\treturn Fail(t, fmt.Sprintf(\"%#v does not contain %#v\", list, subset), msgAndArgs...)\n\t\t\t}\n\t\t\tif !ObjectsAreEqual(ev.Interface(), av.Interface()) {\n\t\t\t\treturn Fail(t, fmt.Sprintf(\"%#v does not contain %#v\", list, subset), msgAndArgs...)\n\t\t\t}\n\t\t}\n\n\t\treturn true\n\t}\n\n\tsubsetList := reflect.ValueOf(subset)\n\tif subsetKind == reflect.Map {\n\t\tkeys := make([]interface{}, subsetList.Len())\n\t\tfor idx, key := range subsetList.MapKeys() {\n\t\t\tkeys[idx] = key.Interface()\n\t\t}\n\t\tsubsetList = reflect.ValueOf(keys)\n\t}\n\tfor i := 0; i < subsetList.Len(); i++ {\n\t\telement := subsetList.Index(i).Interface()\n\t\tok, found := containsElement(list, element)\n\t\tif !ok {\n\t\t\treturn Fail(t, fmt.Sprintf(\"%#v could not be applied builtin len()\", list), msgAndArgs...)\n\t\t}\n\t\tif !found {\n\t\t\treturn Fail(t, fmt.Sprintf(\"%#v does not contain %#v\", list, element), msgAndArgs...)\n\t\t}\n\t}\n\n\treturn true\n}\n\n// NotSubset asserts that the list (array, slice, or map) does NOT contain all\n// elements given in the subset (array, slice, or map).\n// Map elements are key-value pairs unless compared with an array or slice where\n// only the map key is evaluated.\n//\n//\tassert.NotSubset(t, [1, 3, 4], [1, 2])\n//\tassert.NotSubset(t, {\"x\": 1, \"y\": 2}, {\"z\": 3})\n//\tassert.NotSubset(t, [1, 3, 4], {1: \"one\", 2: \"two\"})\n//\tassert.NotSubset(t, {\"x\": 1, \"y\": 2}, [\"z\"])\nfunc NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif subset == nil {\n\t\treturn Fail(t, \"nil is the empty set which is a subset of every set\", msgAndArgs...)\n\t}\n\n\tlistKind := reflect.TypeOf(list).Kind()\n\tif listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map {\n\t\treturn Fail(t, fmt.Sprintf(\"%q has an unsupported type %s\", list, listKind), msgAndArgs...)\n\t}\n\n\tsubsetKind := reflect.TypeOf(subset).Kind()\n\tif subsetKind != reflect.Array && subsetKind != reflect.Slice && subsetKind != reflect.Map {\n\t\treturn Fail(t, fmt.Sprintf(\"%q has an unsupported type %s\", subset, subsetKind), msgAndArgs...)\n\t}\n\n\tif subsetKind == reflect.Map && listKind == reflect.Map {\n\t\tsubsetMap := reflect.ValueOf(subset)\n\t\tactualMap := reflect.ValueOf(list)\n\n\t\tfor _, k := range subsetMap.MapKeys() {\n\t\t\tev := subsetMap.MapIndex(k)\n\t\t\tav := actualMap.MapIndex(k)\n\n\t\t\tif !av.IsValid() {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif !ObjectsAreEqual(ev.Interface(), av.Interface()) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\n\t\treturn Fail(t, fmt.Sprintf(\"%q is a subset of %q\", subset, list), msgAndArgs...)\n\t}\n\n\tsubsetList := reflect.ValueOf(subset)\n\tif subsetKind == reflect.Map {\n\t\tkeys := make([]interface{}, subsetList.Len())\n\t\tfor idx, key := range subsetList.MapKeys() {\n\t\t\tkeys[idx] = key.Interface()\n\t\t}\n\t\tsubsetList = reflect.ValueOf(keys)\n\t}\n\tfor i := 0; i < subsetList.Len(); i++ {\n\t\telement := subsetList.Index(i).Interface()\n\t\tok, found := containsElement(list, element)\n\t\tif !ok {\n\t\t\treturn Fail(t, fmt.Sprintf(\"%q could not be applied builtin len()\", list), msgAndArgs...)\n\t\t}\n\t\tif !found {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn Fail(t, fmt.Sprintf(\"%q is a subset of %q\", subset, list), msgAndArgs...)\n}\n\n// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should match.\n//\n// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])\nfunc ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif isEmpty(listA) && isEmpty(listB) {\n\t\treturn true\n\t}\n\n\tif !isList(t, listA, msgAndArgs...) || !isList(t, listB, msgAndArgs...) {\n\t\treturn false\n\t}\n\n\textraA, extraB := diffLists(listA, listB)\n\n\tif len(extraA) == 0 && len(extraB) == 0 {\n\t\treturn true\n\t}\n\n\treturn Fail(t, formatListDiff(listA, listB, extraA, extraB), msgAndArgs...)\n}\n\n// isList checks that the provided value is array or slice.\nfunc isList(t TestingT, list interface{}, msgAndArgs ...interface{}) (ok bool) {\n\tkind := reflect.TypeOf(list).Kind()\n\tif kind != reflect.Array && kind != reflect.Slice {\n\t\treturn Fail(t, fmt.Sprintf(\"%q has an unsupported type %s, expecting array or slice\", list, kind),\n\t\t\tmsgAndArgs...)\n\t}\n\treturn true\n}\n\n// diffLists diffs two arrays/slices and returns slices of elements that are only in A and only in B.\n// If some element is present multiple times, each instance is counted separately (e.g. if something is 2x in A and\n// 5x in B, it will be 0x in extraA and 3x in extraB). The order of items in both lists is ignored.\nfunc diffLists(listA, listB interface{}) (extraA, extraB []interface{}) {\n\taValue := reflect.ValueOf(listA)\n\tbValue := reflect.ValueOf(listB)\n\n\taLen := aValue.Len()\n\tbLen := bValue.Len()\n\n\t// Mark indexes in bValue that we already used\n\tvisited := make([]bool, bLen)\n\tfor i := 0; i < aLen; i++ {\n\t\telement := aValue.Index(i).Interface()\n\t\tfound := false\n\t\tfor j := 0; j < bLen; j++ {\n\t\t\tif visited[j] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif ObjectsAreEqual(bValue.Index(j).Interface(), element) {\n\t\t\t\tvisited[j] = true\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\textraA = append(extraA, element)\n\t\t}\n\t}\n\n\tfor j := 0; j < bLen; j++ {\n\t\tif visited[j] {\n\t\t\tcontinue\n\t\t}\n\t\textraB = append(extraB, bValue.Index(j).Interface())\n\t}\n\n\treturn\n}\n\nfunc formatListDiff(listA, listB interface{}, extraA, extraB []interface{}) string {\n\tvar msg bytes.Buffer\n\n\tmsg.WriteString(\"elements differ\")\n\tif len(extraA) > 0 {\n\t\tmsg.WriteString(\"\\n\\nextra elements in list A:\\n\")\n\t\tmsg.WriteString(spewConfig.Sdump(extraA))\n\t}\n\tif len(extraB) > 0 {\n\t\tmsg.WriteString(\"\\n\\nextra elements in list B:\\n\")\n\t\tmsg.WriteString(spewConfig.Sdump(extraB))\n\t}\n\tmsg.WriteString(\"\\n\\nlistA:\\n\")\n\tmsg.WriteString(spewConfig.Sdump(listA))\n\tmsg.WriteString(\"\\n\\nlistB:\\n\")\n\tmsg.WriteString(spewConfig.Sdump(listB))\n\n\treturn msg.String()\n}\n\n// NotElementsMatch asserts that the specified listA(array, slice...) is NOT equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should not match.\n// This is an inverse of ElementsMatch.\n//\n// assert.NotElementsMatch(t, [1, 1, 2, 3], [1, 1, 2, 3]) -> false\n//\n// assert.NotElementsMatch(t, [1, 1, 2, 3], [1, 2, 3]) -> true\n//\n// assert.NotElementsMatch(t, [1, 2, 3], [1, 2, 4]) -> true\nfunc NotElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif isEmpty(listA) && isEmpty(listB) {\n\t\treturn Fail(t, \"listA and listB contain the same elements\", msgAndArgs)\n\t}\n\n\tif !isList(t, listA, msgAndArgs...) {\n\t\treturn Fail(t, \"listA is not a list type\", msgAndArgs...)\n\t}\n\tif !isList(t, listB, msgAndArgs...) {\n\t\treturn Fail(t, \"listB is not a list type\", msgAndArgs...)\n\t}\n\n\textraA, extraB := diffLists(listA, listB)\n\tif len(extraA) == 0 && len(extraB) == 0 {\n\t\treturn Fail(t, \"listA and listB contain the same elements\", msgAndArgs)\n\t}\n\n\treturn true\n}\n\n// Condition uses a Comparison to assert a complex condition.\nfunc Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tresult := comp()\n\tif !result {\n\t\tFail(t, \"Condition failed!\", msgAndArgs...)\n\t}\n\treturn result\n}\n\n// PanicTestFunc defines a func that should be passed to the assert.Panics and assert.NotPanics\n// methods, and represents a simple func that takes no arguments, and returns nothing.\ntype PanicTestFunc func()\n\n// didPanic returns true if the function passed to it panics. Otherwise, it returns false.\nfunc didPanic(f PanicTestFunc) (didPanic bool, message interface{}, stack string) {\n\tdidPanic = true\n\n\tdefer func() {\n\t\tmessage = recover()\n\t\tif didPanic {\n\t\t\tstack = string(debug.Stack())\n\t\t}\n\t}()\n\n\t// call the target function\n\tf()\n\tdidPanic = false\n\n\treturn\n}\n\n// Panics asserts that the code inside the specified PanicTestFunc panics.\n//\n//\tassert.Panics(t, func(){ GoCrazy() })\nfunc Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tif funcDidPanic, panicValue, _ := didPanic(f); !funcDidPanic {\n\t\treturn Fail(t, fmt.Sprintf(\"func %#v should panic\\n\\tPanic value:\\t%#v\", f, panicValue), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that\n// the recovered panic value equals the expected panic value.\n//\n//\tassert.PanicsWithValue(t, \"crazy error\", func(){ GoCrazy() })\nfunc PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tfuncDidPanic, panicValue, panickedStack := didPanic(f)\n\tif !funcDidPanic {\n\t\treturn Fail(t, fmt.Sprintf(\"func %#v should panic\\n\\tPanic value:\\t%#v\", f, panicValue), msgAndArgs...)\n\t}\n\tif panicValue != expected {\n\t\treturn Fail(t, fmt.Sprintf(\"func %#v should panic with value:\\t%#v\\n\\tPanic value:\\t%#v\\n\\tPanic stack:\\t%s\", f, expected, panicValue, panickedStack), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// PanicsWithError asserts that the code inside the specified PanicTestFunc\n// panics, and that the recovered panic value is an error that satisfies the\n// EqualError comparison.\n//\n//\tassert.PanicsWithError(t, \"crazy error\", func(){ GoCrazy() })\nfunc PanicsWithError(t TestingT, errString string, f PanicTestFunc, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tfuncDidPanic, panicValue, panickedStack := didPanic(f)\n\tif !funcDidPanic {\n\t\treturn Fail(t, fmt.Sprintf(\"func %#v should panic\\n\\tPanic value:\\t%#v\", f, panicValue), msgAndArgs...)\n\t}\n\tpanicErr, ok := panicValue.(error)\n\tif !ok || panicErr.Error() != errString {\n\t\treturn Fail(t, fmt.Sprintf(\"func %#v should panic with error message:\\t%#v\\n\\tPanic value:\\t%#v\\n\\tPanic stack:\\t%s\", f, errString, panicValue, panickedStack), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.\n//\n//\tassert.NotPanics(t, func(){ RemainCalm() })\nfunc NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tif funcDidPanic, panicValue, panickedStack := didPanic(f); funcDidPanic {\n\t\treturn Fail(t, fmt.Sprintf(\"func %#v should not panic\\n\\tPanic value:\\t%v\\n\\tPanic stack:\\t%s\", f, panicValue, panickedStack), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// WithinDuration asserts that the two times are within duration delta of each other.\n//\n//\tassert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second)\nfunc WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tdt := expected.Sub(actual)\n\tif dt < -delta || dt > delta {\n\t\treturn Fail(t, fmt.Sprintf(\"Max difference between %v and %v allowed is %v, but difference was %v\", expected, actual, delta, dt), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// WithinRange asserts that a time is within a time range (inclusive).\n//\n//\tassert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second))\nfunc WithinRange(t TestingT, actual, start, end time.Time, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tif end.Before(start) {\n\t\treturn Fail(t, \"Start should be before end\", msgAndArgs...)\n\t}\n\n\tif actual.Before(start) {\n\t\treturn Fail(t, fmt.Sprintf(\"Time %v expected to be in time range %v to %v, but is before the range\", actual, start, end), msgAndArgs...)\n\t} else if actual.After(end) {\n\t\treturn Fail(t, fmt.Sprintf(\"Time %v expected to be in time range %v to %v, but is after the range\", actual, start, end), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\nfunc toFloat(x interface{}) (float64, bool) {\n\tvar xf float64\n\txok := true\n\n\tswitch xn := x.(type) {\n\tcase uint:\n\t\txf = float64(xn)\n\tcase uint8:\n\t\txf = float64(xn)\n\tcase uint16:\n\t\txf = float64(xn)\n\tcase uint32:\n\t\txf = float64(xn)\n\tcase uint64:\n\t\txf = float64(xn)\n\tcase int:\n\t\txf = float64(xn)\n\tcase int8:\n\t\txf = float64(xn)\n\tcase int16:\n\t\txf = float64(xn)\n\tcase int32:\n\t\txf = float64(xn)\n\tcase int64:\n\t\txf = float64(xn)\n\tcase float32:\n\t\txf = float64(xn)\n\tcase float64:\n\t\txf = xn\n\tcase time.Duration:\n\t\txf = float64(xn)\n\tdefault:\n\t\txok = false\n\t}\n\n\treturn xf, xok\n}\n\n// InDelta asserts that the two numerals are within delta of each other.\n//\n//\tassert.InDelta(t, math.Pi, 22/7.0, 0.01)\nfunc InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\taf, aok := toFloat(expected)\n\tbf, bok := toFloat(actual)\n\n\tif !aok || !bok {\n\t\treturn Fail(t, \"Parameters must be numerical\", msgAndArgs...)\n\t}\n\n\tif math.IsNaN(af) && math.IsNaN(bf) {\n\t\treturn true\n\t}\n\n\tif math.IsNaN(af) {\n\t\treturn Fail(t, \"Expected must not be NaN\", msgAndArgs...)\n\t}\n\n\tif math.IsNaN(bf) {\n\t\treturn Fail(t, fmt.Sprintf(\"Expected %v with delta %v, but was NaN\", expected, delta), msgAndArgs...)\n\t}\n\n\tdt := af - bf\n\tif dt < -delta || dt > delta {\n\t\treturn Fail(t, fmt.Sprintf(\"Max difference between %v and %v allowed is %v, but difference was %v\", expected, actual, delta, dt), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// InDeltaSlice is the same as InDelta, except it compares two slices.\nfunc InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif expected == nil || actual == nil ||\n\t\treflect.TypeOf(actual).Kind() != reflect.Slice ||\n\t\treflect.TypeOf(expected).Kind() != reflect.Slice {\n\t\treturn Fail(t, \"Parameters must be slice\", msgAndArgs...)\n\t}\n\n\tactualSlice := reflect.ValueOf(actual)\n\texpectedSlice := reflect.ValueOf(expected)\n\n\tfor i := 0; i < actualSlice.Len(); i++ {\n\t\tresult := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta, msgAndArgs...)\n\t\tif !result {\n\t\t\treturn result\n\t\t}\n\t}\n\n\treturn true\n}\n\n// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.\nfunc InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif expected == nil || actual == nil ||\n\t\treflect.TypeOf(actual).Kind() != reflect.Map ||\n\t\treflect.TypeOf(expected).Kind() != reflect.Map {\n\t\treturn Fail(t, \"Arguments must be maps\", msgAndArgs...)\n\t}\n\n\texpectedMap := reflect.ValueOf(expected)\n\tactualMap := reflect.ValueOf(actual)\n\n\tif expectedMap.Len() != actualMap.Len() {\n\t\treturn Fail(t, \"Arguments must have the same number of keys\", msgAndArgs...)\n\t}\n\n\tfor _, k := range expectedMap.MapKeys() {\n\t\tev := expectedMap.MapIndex(k)\n\t\tav := actualMap.MapIndex(k)\n\n\t\tif !ev.IsValid() {\n\t\t\treturn Fail(t, fmt.Sprintf(\"missing key %q in expected map\", k), msgAndArgs...)\n\t\t}\n\n\t\tif !av.IsValid() {\n\t\t\treturn Fail(t, fmt.Sprintf(\"missing key %q in actual map\", k), msgAndArgs...)\n\t\t}\n\n\t\tif !InDelta(\n\t\t\tt,\n\t\t\tev.Interface(),\n\t\t\tav.Interface(),\n\t\t\tdelta,\n\t\t\tmsgAndArgs...,\n\t\t) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc calcRelativeError(expected, actual interface{}) (float64, error) {\n\taf, aok := toFloat(expected)\n\tbf, bok := toFloat(actual)\n\tif !aok || !bok {\n\t\treturn 0, fmt.Errorf(\"Parameters must be numerical\")\n\t}\n\tif math.IsNaN(af) && math.IsNaN(bf) {\n\t\treturn 0, nil\n\t}\n\tif math.IsNaN(af) {\n\t\treturn 0, errors.New(\"expected value must not be NaN\")\n\t}\n\tif af == 0 {\n\t\treturn 0, fmt.Errorf(\"expected value must have a value other than zero to calculate the relative error\")\n\t}\n\tif math.IsNaN(bf) {\n\t\treturn 0, errors.New(\"actual value must not be NaN\")\n\t}\n\n\treturn math.Abs(af-bf) / math.Abs(af), nil\n}\n\n// InEpsilon asserts that expected and actual have a relative error less than epsilon\nfunc InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif math.IsNaN(epsilon) {\n\t\treturn Fail(t, \"epsilon must not be NaN\", msgAndArgs...)\n\t}\n\tactualEpsilon, err := calcRelativeError(expected, actual)\n\tif err != nil {\n\t\treturn Fail(t, err.Error(), msgAndArgs...)\n\t}\n\tif math.IsNaN(actualEpsilon) {\n\t\treturn Fail(t, \"relative error is NaN\", msgAndArgs...)\n\t}\n\tif actualEpsilon > epsilon {\n\t\treturn Fail(t, fmt.Sprintf(\"Relative error is too high: %#v (expected)\\n\"+\n\t\t\t\"        < %#v (actual)\", epsilon, actualEpsilon), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.\nfunc InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tif expected == nil || actual == nil {\n\t\treturn Fail(t, \"Parameters must be slice\", msgAndArgs...)\n\t}\n\n\texpectedSlice := reflect.ValueOf(expected)\n\tactualSlice := reflect.ValueOf(actual)\n\n\tif expectedSlice.Type().Kind() != reflect.Slice {\n\t\treturn Fail(t, \"Expected value must be slice\", msgAndArgs...)\n\t}\n\n\texpectedLen := expectedSlice.Len()\n\tif !IsType(t, expected, actual) || !Len(t, actual, expectedLen) {\n\t\treturn false\n\t}\n\n\tfor i := 0; i < expectedLen; i++ {\n\t\tif !InEpsilon(t, expectedSlice.Index(i).Interface(), actualSlice.Index(i).Interface(), epsilon, \"at index %d\", i) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\n/*\n\tErrors\n*/\n\n// NoError asserts that a function returned no error (i.e. `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if assert.NoError(t, err) {\n//\t\t   assert.Equal(t, expectedObj, actualObj)\n//\t  }\nfunc NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {\n\tif err != nil {\n\t\tif h, ok := t.(tHelper); ok {\n\t\t\th.Helper()\n\t\t}\n\t\treturn Fail(t, fmt.Sprintf(\"Received unexpected error:\\n%+v\", err), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// Error asserts that a function returned an error (i.e. not `nil`).\n//\n//\tactualObj, err := SomeFunction()\n//\tassert.Error(t, err)\nfunc Error(t TestingT, err error, msgAndArgs ...interface{}) bool {\n\tif err == nil {\n\t\tif h, ok := t.(tHelper); ok {\n\t\t\th.Helper()\n\t\t}\n\t\treturn Fail(t, \"An error is expected but got nil.\", msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// EqualError asserts that a function returned an error (i.e. not `nil`)\n// and that it is equal to the provided error.\n//\n//\tactualObj, err := SomeFunction()\n//\tassert.EqualError(t, err,  expectedErrorString)\nfunc EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif !Error(t, theError, msgAndArgs...) {\n\t\treturn false\n\t}\n\texpected := errString\n\tactual := theError.Error()\n\t// don't need to use deep equals here, we know they are both strings\n\tif expected != actual {\n\t\treturn Fail(t, fmt.Sprintf(\"Error message not equal:\\n\"+\n\t\t\t\"expected: %q\\n\"+\n\t\t\t\"actual  : %q\", expected, actual), msgAndArgs...)\n\t}\n\treturn true\n}\n\n// ErrorContains asserts that a function returned an error (i.e. not `nil`)\n// and that the error contains the specified substring.\n//\n//\tactualObj, err := SomeFunction()\n//\tassert.ErrorContains(t, err,  expectedErrorSubString)\nfunc ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif !Error(t, theError, msgAndArgs...) {\n\t\treturn false\n\t}\n\n\tactual := theError.Error()\n\tif !strings.Contains(actual, contains) {\n\t\treturn Fail(t, fmt.Sprintf(\"Error %#v does not contain %#v\", actual, contains), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// matchRegexp return true if a specified regexp matches a string.\nfunc matchRegexp(rx interface{}, str interface{}) bool {\n\tvar r *regexp.Regexp\n\tif rr, ok := rx.(*regexp.Regexp); ok {\n\t\tr = rr\n\t} else {\n\t\tr = regexp.MustCompile(fmt.Sprint(rx))\n\t}\n\n\tswitch v := str.(type) {\n\tcase []byte:\n\t\treturn r.Match(v)\n\tcase string:\n\t\treturn r.MatchString(v)\n\tdefault:\n\t\treturn r.MatchString(fmt.Sprint(v))\n\t}\n}\n\n// Regexp asserts that a specified regexp matches a string.\n//\n//\tassert.Regexp(t, regexp.MustCompile(\"start\"), \"it's starting\")\n//\tassert.Regexp(t, \"start...$\", \"it's not starting\")\nfunc Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tmatch := matchRegexp(rx, str)\n\n\tif !match {\n\t\tFail(t, fmt.Sprintf(\"Expect \\\"%v\\\" to match \\\"%v\\\"\", str, rx), msgAndArgs...)\n\t}\n\n\treturn match\n}\n\n// NotRegexp asserts that a specified regexp does not match a string.\n//\n//\tassert.NotRegexp(t, regexp.MustCompile(\"starts\"), \"it's starting\")\n//\tassert.NotRegexp(t, \"^start\", \"it's not starting\")\nfunc NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tmatch := matchRegexp(rx, str)\n\n\tif match {\n\t\tFail(t, fmt.Sprintf(\"Expect \\\"%v\\\" to NOT match \\\"%v\\\"\", str, rx), msgAndArgs...)\n\t}\n\n\treturn !match\n}\n\n// Zero asserts that i is the zero value for its type.\nfunc Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {\n\t\treturn Fail(t, fmt.Sprintf(\"Should be zero, but was %v\", i), msgAndArgs...)\n\t}\n\treturn true\n}\n\n// NotZero asserts that i is not the zero value for its type.\nfunc NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {\n\t\treturn Fail(t, fmt.Sprintf(\"Should not be zero, but was %v\", i), msgAndArgs...)\n\t}\n\treturn true\n}\n\n// FileExists checks whether a file exists in the given path. It also fails if\n// the path points to a directory or there is an error when trying to check the file.\nfunc FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tinfo, err := os.Lstat(path)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn Fail(t, fmt.Sprintf(\"unable to find file %q\", path), msgAndArgs...)\n\t\t}\n\t\treturn Fail(t, fmt.Sprintf(\"error when running os.Lstat(%q): %s\", path, err), msgAndArgs...)\n\t}\n\tif info.IsDir() {\n\t\treturn Fail(t, fmt.Sprintf(\"%q is a directory\", path), msgAndArgs...)\n\t}\n\treturn true\n}\n\n// NoFileExists checks whether a file does not exist in a given path. It fails\n// if the path points to an existing _file_ only.\nfunc NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tinfo, err := os.Lstat(path)\n\tif err != nil {\n\t\treturn true\n\t}\n\tif info.IsDir() {\n\t\treturn true\n\t}\n\treturn Fail(t, fmt.Sprintf(\"file %q exists\", path), msgAndArgs...)\n}\n\n// DirExists checks whether a directory exists in the given path. It also fails\n// if the path is a file rather a directory or there is an error checking whether it exists.\nfunc DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tinfo, err := os.Lstat(path)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn Fail(t, fmt.Sprintf(\"unable to find file %q\", path), msgAndArgs...)\n\t\t}\n\t\treturn Fail(t, fmt.Sprintf(\"error when running os.Lstat(%q): %s\", path, err), msgAndArgs...)\n\t}\n\tif !info.IsDir() {\n\t\treturn Fail(t, fmt.Sprintf(\"%q is a file\", path), msgAndArgs...)\n\t}\n\treturn true\n}\n\n// NoDirExists checks whether a directory does not exist in the given path.\n// It fails if the path points to an existing _directory_ only.\nfunc NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tinfo, err := os.Lstat(path)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn true\n\t\t}\n\t\treturn true\n\t}\n\tif !info.IsDir() {\n\t\treturn true\n\t}\n\treturn Fail(t, fmt.Sprintf(\"directory %q exists\", path), msgAndArgs...)\n}\n\n// JSONEq asserts that two JSON strings are equivalent.\n//\n//\tassert.JSONEq(t, `{\"hello\": \"world\", \"foo\": \"bar\"}`, `{\"foo\": \"bar\", \"hello\": \"world\"}`)\nfunc JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tvar expectedJSONAsInterface, actualJSONAsInterface interface{}\n\n\tif err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil {\n\t\treturn Fail(t, fmt.Sprintf(\"Expected value ('%s') is not valid json.\\nJSON parsing error: '%s'\", expected, err.Error()), msgAndArgs...)\n\t}\n\n\t// Shortcut if same bytes\n\tif actual == expected {\n\t\treturn true\n\t}\n\n\tif err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil {\n\t\treturn Fail(t, fmt.Sprintf(\"Input ('%s') needs to be valid json.\\nJSON parsing error: '%s'\", actual, err.Error()), msgAndArgs...)\n\t}\n\n\treturn Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...)\n}\n\n// YAMLEq asserts that two YAML strings are equivalent.\nfunc YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tvar expectedYAMLAsInterface, actualYAMLAsInterface interface{}\n\n\tif err := yaml.Unmarshal([]byte(expected), &expectedYAMLAsInterface); err != nil {\n\t\treturn Fail(t, fmt.Sprintf(\"Expected value ('%s') is not valid yaml.\\nYAML parsing error: '%s'\", expected, err.Error()), msgAndArgs...)\n\t}\n\n\t// Shortcut if same bytes\n\tif actual == expected {\n\t\treturn true\n\t}\n\n\tif err := yaml.Unmarshal([]byte(actual), &actualYAMLAsInterface); err != nil {\n\t\treturn Fail(t, fmt.Sprintf(\"Input ('%s') needs to be valid yaml.\\nYAML error: '%s'\", actual, err.Error()), msgAndArgs...)\n\t}\n\n\treturn Equal(t, expectedYAMLAsInterface, actualYAMLAsInterface, msgAndArgs...)\n}\n\nfunc typeAndKind(v interface{}) (reflect.Type, reflect.Kind) {\n\tt := reflect.TypeOf(v)\n\tk := t.Kind()\n\n\tif k == reflect.Ptr {\n\t\tt = t.Elem()\n\t\tk = t.Kind()\n\t}\n\treturn t, k\n}\n\n// diff returns a diff of both values as long as both are of the same type and\n// are a struct, map, slice, array or string. Otherwise it returns an empty string.\nfunc diff(expected interface{}, actual interface{}) string {\n\tif expected == nil || actual == nil {\n\t\treturn \"\"\n\t}\n\n\tet, ek := typeAndKind(expected)\n\tat, _ := typeAndKind(actual)\n\n\tif et != at {\n\t\treturn \"\"\n\t}\n\n\tif ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array && ek != reflect.String {\n\t\treturn \"\"\n\t}\n\n\tvar e, a string\n\n\tswitch et {\n\tcase reflect.TypeOf(\"\"):\n\t\te = reflect.ValueOf(expected).String()\n\t\ta = reflect.ValueOf(actual).String()\n\tcase reflect.TypeOf(time.Time{}):\n\t\te = spewConfigStringerEnabled.Sdump(expected)\n\t\ta = spewConfigStringerEnabled.Sdump(actual)\n\tdefault:\n\t\te = spewConfig.Sdump(expected)\n\t\ta = spewConfig.Sdump(actual)\n\t}\n\n\tdiff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{\n\t\tA:        difflib.SplitLines(e),\n\t\tB:        difflib.SplitLines(a),\n\t\tFromFile: \"Expected\",\n\t\tFromDate: \"\",\n\t\tToFile:   \"Actual\",\n\t\tToDate:   \"\",\n\t\tContext:  1,\n\t})\n\n\treturn \"\\n\\nDiff:\\n\" + diff\n}\n\nfunc isFunction(arg interface{}) bool {\n\tif arg == nil {\n\t\treturn false\n\t}\n\treturn reflect.TypeOf(arg).Kind() == reflect.Func\n}\n\nvar spewConfig = spew.ConfigState{\n\tIndent:                  \" \",\n\tDisablePointerAddresses: true,\n\tDisableCapacities:       true,\n\tSortKeys:                true,\n\tDisableMethods:          true,\n\tMaxDepth:                10,\n}\n\nvar spewConfigStringerEnabled = spew.ConfigState{\n\tIndent:                  \" \",\n\tDisablePointerAddresses: true,\n\tDisableCapacities:       true,\n\tSortKeys:                true,\n\tMaxDepth:                10,\n}\n\ntype tHelper = interface {\n\tHelper()\n}\n\n// Eventually asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick.\n//\n//\tassert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond)\nfunc Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tch := make(chan bool, 1)\n\tcheckCond := func() { ch <- condition() }\n\n\ttimer := time.NewTimer(waitFor)\n\tdefer timer.Stop()\n\n\tticker := time.NewTicker(tick)\n\tdefer ticker.Stop()\n\n\tvar tickC <-chan time.Time\n\n\t// Check the condition once first on the initial call.\n\tgo checkCond()\n\n\tfor {\n\t\tselect {\n\t\tcase <-timer.C:\n\t\t\treturn Fail(t, \"Condition never satisfied\", msgAndArgs...)\n\t\tcase <-tickC:\n\t\t\ttickC = nil\n\t\t\tgo checkCond()\n\t\tcase v := <-ch:\n\t\t\tif v {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\ttickC = ticker.C\n\t\t}\n\t}\n}\n\n// CollectT implements the TestingT interface and collects all errors.\ntype CollectT struct {\n\t// A slice of errors. Non-nil slice denotes a failure.\n\t// If it's non-nil but len(c.errors) == 0, this is also a failure\n\t// obtained by direct c.FailNow() call.\n\terrors []error\n}\n\n// Helper is like [testing.T.Helper] but does nothing.\nfunc (CollectT) Helper() {}\n\n// Errorf collects the error.\nfunc (c *CollectT) Errorf(format string, args ...interface{}) {\n\tc.errors = append(c.errors, fmt.Errorf(format, args...))\n}\n\n// FailNow stops execution by calling runtime.Goexit.\nfunc (c *CollectT) FailNow() {\n\tc.fail()\n\truntime.Goexit()\n}\n\n// Deprecated: That was a method for internal usage that should not have been published. Now just panics.\nfunc (*CollectT) Reset() {\n\tpanic(\"Reset() is deprecated\")\n}\n\n// Deprecated: That was a method for internal usage that should not have been published. Now just panics.\nfunc (*CollectT) Copy(TestingT) {\n\tpanic(\"Copy() is deprecated\")\n}\n\nfunc (c *CollectT) fail() {\n\tif !c.failed() {\n\t\tc.errors = []error{} // Make it non-nil to mark a failure.\n\t}\n}\n\nfunc (c *CollectT) failed() bool {\n\treturn c.errors != nil\n}\n\n// EventuallyWithT asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick. In contrast to Eventually,\n// it supplies a CollectT to the condition function, so that the condition\n// function can use the CollectT to call other assertions.\n// The condition is considered \"met\" if no errors are raised in a tick.\n// The supplied CollectT collects all errors from one tick (if there are any).\n// If the condition is not met before waitFor, the collected errors of\n// the last tick are copied to t.\n//\n//\texternalValue := false\n//\tgo func() {\n//\t\ttime.Sleep(8*time.Second)\n//\t\texternalValue = true\n//\t}()\n//\tassert.EventuallyWithT(t, func(c *assert.CollectT) {\n//\t\t// add assertions as needed; any assertion failure will fail the current tick\n//\t\tassert.True(c, externalValue, \"expected 'externalValue' to be true\")\n//\t}, 10*time.Second, 1*time.Second, \"external state has not changed to 'true'; still false\")\nfunc EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tvar lastFinishedTickErrs []error\n\tch := make(chan *CollectT, 1)\n\n\tcheckCond := func() {\n\t\tcollect := new(CollectT)\n\t\tdefer func() {\n\t\t\tch <- collect\n\t\t}()\n\t\tcondition(collect)\n\t}\n\n\ttimer := time.NewTimer(waitFor)\n\tdefer timer.Stop()\n\n\tticker := time.NewTicker(tick)\n\tdefer ticker.Stop()\n\n\tvar tickC <-chan time.Time\n\n\t// Check the condition once first on the initial call.\n\tgo checkCond()\n\n\tfor {\n\t\tselect {\n\t\tcase <-timer.C:\n\t\t\tfor _, err := range lastFinishedTickErrs {\n\t\t\t\tt.Errorf(\"%v\", err)\n\t\t\t}\n\t\t\treturn Fail(t, \"Condition never satisfied\", msgAndArgs...)\n\t\tcase <-tickC:\n\t\t\ttickC = nil\n\t\t\tgo checkCond()\n\t\tcase collect := <-ch:\n\t\t\tif !collect.failed() {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\t// Keep the errors from the last ended condition, so that they can be copied to t if timeout is reached.\n\t\t\tlastFinishedTickErrs = collect.errors\n\t\t\ttickC = ticker.C\n\t\t}\n\t}\n}\n\n// Never asserts that the given condition doesn't satisfy in waitFor time,\n// periodically checking the target function each tick.\n//\n//\tassert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond)\nfunc Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tch := make(chan bool, 1)\n\tcheckCond := func() { ch <- condition() }\n\n\ttimer := time.NewTimer(waitFor)\n\tdefer timer.Stop()\n\n\tticker := time.NewTicker(tick)\n\tdefer ticker.Stop()\n\n\tvar tickC <-chan time.Time\n\n\t// Check the condition once first on the initial call.\n\tgo checkCond()\n\n\tfor {\n\t\tselect {\n\t\tcase <-timer.C:\n\t\t\treturn true\n\t\tcase <-tickC:\n\t\t\ttickC = nil\n\t\t\tgo checkCond()\n\t\tcase v := <-ch:\n\t\t\tif v {\n\t\t\t\treturn Fail(t, \"Condition satisfied\", msgAndArgs...)\n\t\t\t}\n\t\t\ttickC = ticker.C\n\t\t}\n\t}\n}\n\n// ErrorIs asserts that at least one of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif errors.Is(err, target) {\n\t\treturn true\n\t}\n\n\tvar expectedText string\n\tif target != nil {\n\t\texpectedText = target.Error()\n\t\tif err == nil {\n\t\t\treturn Fail(t, fmt.Sprintf(\"Expected error with %q in chain but got nil.\", expectedText), msgAndArgs...)\n\t\t}\n\t}\n\n\tchain := buildErrorChainString(err, false)\n\n\treturn Fail(t, fmt.Sprintf(\"Target error should be in err chain:\\n\"+\n\t\t\"expected: %q\\n\"+\n\t\t\"in chain: %s\", expectedText, chain,\n\t), msgAndArgs...)\n}\n\n// NotErrorIs asserts that none of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc NotErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif !errors.Is(err, target) {\n\t\treturn true\n\t}\n\n\tvar expectedText string\n\tif target != nil {\n\t\texpectedText = target.Error()\n\t}\n\n\tchain := buildErrorChainString(err, false)\n\n\treturn Fail(t, fmt.Sprintf(\"Target error should not be in err chain:\\n\"+\n\t\t\"found: %q\\n\"+\n\t\t\"in chain: %s\", expectedText, chain,\n\t), msgAndArgs...)\n}\n\n// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.\n// This is a wrapper for errors.As.\nfunc ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif errors.As(err, target) {\n\t\treturn true\n\t}\n\n\texpectedType := reflect.TypeOf(target).Elem().String()\n\tif err == nil {\n\t\treturn Fail(t, fmt.Sprintf(\"An error is expected but got nil.\\n\"+\n\t\t\t\"expected: %s\", expectedType), msgAndArgs...)\n\t}\n\n\tchain := buildErrorChainString(err, true)\n\n\treturn Fail(t, fmt.Sprintf(\"Should be in error chain:\\n\"+\n\t\t\"expected: %s\\n\"+\n\t\t\"in chain: %s\", expectedType, chain,\n\t), msgAndArgs...)\n}\n\n// NotErrorAs asserts that none of the errors in err's chain matches target,\n// but if so, sets target to that error value.\nfunc NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif !errors.As(err, target) {\n\t\treturn true\n\t}\n\n\tchain := buildErrorChainString(err, true)\n\n\treturn Fail(t, fmt.Sprintf(\"Target error should not be in err chain:\\n\"+\n\t\t\"found: %s\\n\"+\n\t\t\"in chain: %s\", reflect.TypeOf(target).Elem().String(), chain,\n\t), msgAndArgs...)\n}\n\nfunc unwrapAll(err error) (errs []error) {\n\terrs = append(errs, err)\n\tswitch x := err.(type) {\n\tcase interface{ Unwrap() error }:\n\t\terr = x.Unwrap()\n\t\tif err == nil {\n\t\t\treturn\n\t\t}\n\t\terrs = append(errs, unwrapAll(err)...)\n\tcase interface{ Unwrap() []error }:\n\t\tfor _, err := range x.Unwrap() {\n\t\t\terrs = append(errs, unwrapAll(err)...)\n\t\t}\n\t}\n\treturn\n}\n\nfunc buildErrorChainString(err error, withType bool) string {\n\tif err == nil {\n\t\treturn \"\"\n\t}\n\n\tvar chain string\n\terrs := unwrapAll(err)\n\tfor i := range errs {\n\t\tif i != 0 {\n\t\t\tchain += \"\\n\\t\"\n\t\t}\n\t\tchain += fmt.Sprintf(\"%q\", errs[i].Error())\n\t\tif withType {\n\t\t\tchain += fmt.Sprintf(\" (%T)\", errs[i])\n\t\t}\n\t}\n\treturn chain\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/doc.go",
    "content": "// Package assert provides a set of comprehensive testing tools for use with the normal Go testing system.\n//\n// # Note\n//\n// All functions in this package return a bool value indicating whether the assertion has passed.\n//\n// # Example Usage\n//\n// The following is a complete example using assert in a standard test function:\n//\n//\timport (\n//\t  \"testing\"\n//\t  \"github.com/stretchr/testify/assert\"\n//\t)\n//\n//\tfunc TestSomething(t *testing.T) {\n//\n//\t  var a string = \"Hello\"\n//\t  var b string = \"Hello\"\n//\n//\t  assert.Equal(t, a, b, \"The two words should be the same.\")\n//\n//\t}\n//\n// if you assert many times, use the format below:\n//\n//\timport (\n//\t  \"testing\"\n//\t  \"github.com/stretchr/testify/assert\"\n//\t)\n//\n//\tfunc TestSomething(t *testing.T) {\n//\t  assert := assert.New(t)\n//\n//\t  var a string = \"Hello\"\n//\t  var b string = \"Hello\"\n//\n//\t  assert.Equal(a, b, \"The two words should be the same.\")\n//\t}\n//\n// # Assertions\n//\n// Assertions allow you to easily write test code, and are global funcs in the `assert` package.\n// All assertion functions take, as the first argument, the `*testing.T` object provided by the\n// testing framework. This allows the assertion funcs to write the failings and other details to\n// the correct place.\n//\n// Every assertion function also takes an optional string message as the final argument,\n// allowing custom error messages to be appended to the message the assertion method outputs.\npackage assert\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/errors.go",
    "content": "package assert\n\nimport (\n\t\"errors\"\n)\n\n// AnError is an error instance useful for testing.  If the code does not care\n// about error specifics, and only needs to return the error for example, this\n// error should be used to make the test code more readable.\nvar AnError = errors.New(\"assert.AnError general error for testing\")\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/forward_assertions.go",
    "content": "package assert\n\n// Assertions provides assertion methods around the\n// TestingT interface.\ntype Assertions struct {\n\tt TestingT\n}\n\n// New makes a new Assertions object for the specified TestingT.\nfunc New(t TestingT) *Assertions {\n\treturn &Assertions{\n\t\tt: t,\n\t}\n}\n\n//go:generate sh -c \"cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_forward.go.tmpl -include-format-funcs\"\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/http_assertions.go",
    "content": "package assert\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"net/url\"\n\t\"strings\"\n)\n\n// httpCode is a helper that returns HTTP code of the response. It returns -1 and\n// an error if building a new request fails.\nfunc httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) {\n\tw := httptest.NewRecorder()\n\treq, err := http.NewRequest(method, url, http.NoBody)\n\tif err != nil {\n\t\treturn -1, err\n\t}\n\treq.URL.RawQuery = values.Encode()\n\thandler(w, req)\n\treturn w.Code, nil\n}\n\n// HTTPSuccess asserts that a specified handler returns a success status code.\n//\n//\tassert.HTTPSuccess(t, myHandler, \"POST\", \"http://www.google.com\", nil)\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tcode, err := httpCode(handler, method, url, values)\n\tif err != nil {\n\t\tFail(t, fmt.Sprintf(\"Failed to build test request, got error: %s\", err), msgAndArgs...)\n\t}\n\n\tisSuccessCode := code >= http.StatusOK && code <= http.StatusPartialContent\n\tif !isSuccessCode {\n\t\tFail(t, fmt.Sprintf(\"Expected HTTP success status code for %q but received %d\", url+\"?\"+values.Encode(), code), msgAndArgs...)\n\t}\n\n\treturn isSuccessCode\n}\n\n// HTTPRedirect asserts that a specified handler returns a redirect status code.\n//\n//\tassert.HTTPRedirect(t, myHandler, \"GET\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tcode, err := httpCode(handler, method, url, values)\n\tif err != nil {\n\t\tFail(t, fmt.Sprintf(\"Failed to build test request, got error: %s\", err), msgAndArgs...)\n\t}\n\n\tisRedirectCode := code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect\n\tif !isRedirectCode {\n\t\tFail(t, fmt.Sprintf(\"Expected HTTP redirect status code for %q but received %d\", url+\"?\"+values.Encode(), code), msgAndArgs...)\n\t}\n\n\treturn isRedirectCode\n}\n\n// HTTPError asserts that a specified handler returns an error status code.\n//\n//\tassert.HTTPError(t, myHandler, \"POST\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tcode, err := httpCode(handler, method, url, values)\n\tif err != nil {\n\t\tFail(t, fmt.Sprintf(\"Failed to build test request, got error: %s\", err), msgAndArgs...)\n\t}\n\n\tisErrorCode := code >= http.StatusBadRequest\n\tif !isErrorCode {\n\t\tFail(t, fmt.Sprintf(\"Expected HTTP error status code for %q but received %d\", url+\"?\"+values.Encode(), code), msgAndArgs...)\n\t}\n\n\treturn isErrorCode\n}\n\n// HTTPStatusCode asserts that a specified handler returns a specified status code.\n//\n//\tassert.HTTPStatusCode(t, myHandler, \"GET\", \"/notImplemented\", nil, 501)\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPStatusCode(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tcode, err := httpCode(handler, method, url, values)\n\tif err != nil {\n\t\tFail(t, fmt.Sprintf(\"Failed to build test request, got error: %s\", err), msgAndArgs...)\n\t}\n\n\tsuccessful := code == statuscode\n\tif !successful {\n\t\tFail(t, fmt.Sprintf(\"Expected HTTP status code %d for %q but received %d\", statuscode, url+\"?\"+values.Encode(), code), msgAndArgs...)\n\t}\n\n\treturn successful\n}\n\n// HTTPBody is a helper that returns HTTP body of the response. It returns\n// empty string if building a new request fails.\nfunc HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string {\n\tw := httptest.NewRecorder()\n\tif len(values) > 0 {\n\t\turl += \"?\" + values.Encode()\n\t}\n\treq, err := http.NewRequest(method, url, http.NoBody)\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\thandler(w, req)\n\treturn w.Body.String()\n}\n\n// HTTPBodyContains asserts that a specified handler returns a\n// body that contains a string.\n//\n//\tassert.HTTPBodyContains(t, myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tbody := HTTPBody(handler, method, url, values)\n\n\tcontains := strings.Contains(body, fmt.Sprint(str))\n\tif !contains {\n\t\tFail(t, fmt.Sprintf(\"Expected response body for %q to contain %q but found %q\", url+\"?\"+values.Encode(), str, body), msgAndArgs...)\n\t}\n\n\treturn contains\n}\n\n// HTTPBodyNotContains asserts that a specified handler returns a\n// body that does not contain a string.\n//\n//\tassert.HTTPBodyNotContains(t, myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tbody := HTTPBody(handler, method, url, values)\n\n\tcontains := strings.Contains(body, fmt.Sprint(str))\n\tif contains {\n\t\tFail(t, fmt.Sprintf(\"Expected response body for %q to NOT contain %q but found %q\", url+\"?\"+values.Encode(), str, body), msgAndArgs...)\n\t}\n\n\treturn !contains\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go",
    "content": "//go:build testify_yaml_custom && !testify_yaml_fail && !testify_yaml_default\n\n// Package yaml is an implementation of YAML functions that calls a pluggable implementation.\n//\n// This implementation is selected with the testify_yaml_custom build tag.\n//\n//\tgo test -tags testify_yaml_custom\n//\n// This implementation can be used at build time to replace the default implementation\n// to avoid linking with [gopkg.in/yaml.v3].\n//\n// In your test package:\n//\n//\t\timport assertYaml \"github.com/stretchr/testify/assert/yaml\"\n//\n//\t\tfunc init() {\n//\t\t\tassertYaml.Unmarshal = func (in []byte, out interface{}) error {\n//\t\t\t\t// ...\n//\t     \t\t\treturn nil\n//\t\t\t}\n//\t\t}\npackage yaml\n\nvar Unmarshal func(in []byte, out interface{}) error\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go",
    "content": "//go:build !testify_yaml_fail && !testify_yaml_custom\n\n// Package yaml is just an indirection to handle YAML deserialization.\n//\n// This package is just an indirection that allows the builder to override the\n// indirection with an alternative implementation of this package that uses\n// another implementation of YAML deserialization. This allows to not either not\n// use YAML deserialization at all, or to use another implementation than\n// [gopkg.in/yaml.v3] (for example for license compatibility reasons, see [PR #1120]).\n//\n// Alternative implementations are selected using build tags:\n//\n//   - testify_yaml_fail: [Unmarshal] always fails with an error\n//   - testify_yaml_custom: [Unmarshal] is a variable. Caller must initialize it\n//     before calling any of [github.com/stretchr/testify/assert.YAMLEq] or\n//     [github.com/stretchr/testify/assert.YAMLEqf].\n//\n// Usage:\n//\n//\tgo test -tags testify_yaml_fail\n//\n// You can check with \"go list\" which implementation is linked:\n//\n//\tgo list -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml\n//\tgo list -tags testify_yaml_fail -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml\n//\tgo list -tags testify_yaml_custom -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml\n//\n// [PR #1120]: https://github.com/stretchr/testify/pull/1120\npackage yaml\n\nimport goyaml \"gopkg.in/yaml.v3\"\n\n// Unmarshal is just a wrapper of [gopkg.in/yaml.v3.Unmarshal].\nfunc Unmarshal(in []byte, out interface{}) error {\n\treturn goyaml.Unmarshal(in, out)\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go",
    "content": "//go:build testify_yaml_fail && !testify_yaml_custom && !testify_yaml_default\n\n// Package yaml is an implementation of YAML functions that always fail.\n//\n// This implementation can be used at build time to replace the default implementation\n// to avoid linking with [gopkg.in/yaml.v3]:\n//\n//\tgo test -tags testify_yaml_fail\npackage yaml\n\nimport \"errors\"\n\nvar errNotImplemented = errors.New(\"YAML functions are not available (see https://pkg.go.dev/github.com/stretchr/testify/assert/yaml)\")\n\nfunc Unmarshal([]byte, interface{}) error {\n\treturn errNotImplemented\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/require/doc.go",
    "content": "// Package require implements the same assertions as the `assert` package but\n// stops test execution when a test fails.\n//\n// # Example Usage\n//\n// The following is a complete example using require in a standard test function:\n//\n//\timport (\n//\t  \"testing\"\n//\t  \"github.com/stretchr/testify/require\"\n//\t)\n//\n//\tfunc TestSomething(t *testing.T) {\n//\n//\t  var a string = \"Hello\"\n//\t  var b string = \"Hello\"\n//\n//\t  require.Equal(t, a, b, \"The two words should be the same.\")\n//\n//\t}\n//\n// # Assertions\n//\n// The `require` package have same global functions as in the `assert` package,\n// but instead of returning a boolean result they call `t.FailNow()`.\n// A consequence of this is that it must be called from the goroutine running\n// the test function, not from other goroutines created during the test.\n//\n// Every assertion function also takes an optional string message as the final argument,\n// allowing custom error messages to be appended to the message the assertion method outputs.\npackage require\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/require/forward_requirements.go",
    "content": "package require\n\n// Assertions provides assertion methods around the\n// TestingT interface.\ntype Assertions struct {\n\tt TestingT\n}\n\n// New makes a new Assertions object for the specified TestingT.\nfunc New(t TestingT) *Assertions {\n\treturn &Assertions{\n\t\tt: t,\n\t}\n}\n\n//go:generate sh -c \"cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=require -template=require_forward.go.tmpl -include-format-funcs\"\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/require/require.go",
    "content": "// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT.\n\npackage require\n\nimport (\n\tassert \"github.com/stretchr/testify/assert\"\n\thttp \"net/http\"\n\turl \"net/url\"\n\ttime \"time\"\n)\n\n// Condition uses a Comparison to assert a complex condition.\nfunc Condition(t TestingT, comp assert.Comparison, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Condition(t, comp, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Conditionf uses a Comparison to assert a complex condition.\nfunc Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Conditionf(t, comp, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Contains asserts that the specified string, list(array, slice...) or map contains the\n// specified substring or element.\n//\n//\trequire.Contains(t, \"Hello World\", \"World\")\n//\trequire.Contains(t, [\"Hello\", \"World\"], \"World\")\n//\trequire.Contains(t, {\"Hello\": \"World\"}, \"Hello\")\nfunc Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Contains(t, s, contains, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Containsf asserts that the specified string, list(array, slice...) or map contains the\n// specified substring or element.\n//\n//\trequire.Containsf(t, \"Hello World\", \"World\", \"error message %s\", \"formatted\")\n//\trequire.Containsf(t, [\"Hello\", \"World\"], \"World\", \"error message %s\", \"formatted\")\n//\trequire.Containsf(t, {\"Hello\": \"World\"}, \"Hello\", \"error message %s\", \"formatted\")\nfunc Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Containsf(t, s, contains, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// DirExists checks whether a directory exists in the given path. It also fails\n// if the path is a file rather a directory or there is an error checking whether it exists.\nfunc DirExists(t TestingT, path string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.DirExists(t, path, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// DirExistsf checks whether a directory exists in the given path. It also fails\n// if the path is a file rather a directory or there is an error checking whether it exists.\nfunc DirExistsf(t TestingT, path string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.DirExistsf(t, path, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should match.\n//\n// require.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])\nfunc ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.ElementsMatch(t, listA, listB, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should match.\n//\n// require.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], \"error message %s\", \"formatted\")\nfunc ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.ElementsMatchf(t, listA, listB, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Empty asserts that the given value is \"empty\".\n//\n// [Zero values] are \"empty\".\n//\n// Arrays are \"empty\" if every element is the zero value of the type (stricter than \"empty\").\n//\n// Slices, maps and channels with zero length are \"empty\".\n//\n// Pointer values are \"empty\" if the pointer is nil or if the pointed value is \"empty\".\n//\n//\trequire.Empty(t, obj)\n//\n// [Zero values]: https://go.dev/ref/spec#The_zero_value\nfunc Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Empty(t, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Emptyf asserts that the given value is \"empty\".\n//\n// [Zero values] are \"empty\".\n//\n// Arrays are \"empty\" if every element is the zero value of the type (stricter than \"empty\").\n//\n// Slices, maps and channels with zero length are \"empty\".\n//\n// Pointer values are \"empty\" if the pointer is nil or if the pointed value is \"empty\".\n//\n//\trequire.Emptyf(t, obj, \"error message %s\", \"formatted\")\n//\n// [Zero values]: https://go.dev/ref/spec#The_zero_value\nfunc Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Emptyf(t, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Equal asserts that two objects are equal.\n//\n//\trequire.Equal(t, 123, 123)\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses). Function equality\n// cannot be determined and will always fail.\nfunc Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Equal(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// EqualError asserts that a function returned an error (i.e. not `nil`)\n// and that it is equal to the provided error.\n//\n//\tactualObj, err := SomeFunction()\n//\trequire.EqualError(t, err,  expectedErrorString)\nfunc EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.EqualError(t, theError, errString, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// EqualErrorf asserts that a function returned an error (i.e. not `nil`)\n// and that it is equal to the provided error.\n//\n//\tactualObj, err := SomeFunction()\n//\trequire.EqualErrorf(t, err,  expectedErrorString, \"error message %s\", \"formatted\")\nfunc EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.EqualErrorf(t, theError, errString, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// EqualExportedValues asserts that the types of two objects are equal and their public\n// fields are also equal. This is useful for comparing structs that have private fields\n// that could potentially differ.\n//\n//\t type S struct {\n//\t\tExported     \tint\n//\t\tnotExported   \tint\n//\t }\n//\t require.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true\n//\t require.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false\nfunc EqualExportedValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.EqualExportedValues(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// EqualExportedValuesf asserts that the types of two objects are equal and their public\n// fields are also equal. This is useful for comparing structs that have private fields\n// that could potentially differ.\n//\n//\t type S struct {\n//\t\tExported     \tint\n//\t\tnotExported   \tint\n//\t }\n//\t require.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, \"error message %s\", \"formatted\") => true\n//\t require.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, \"error message %s\", \"formatted\") => false\nfunc EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.EqualExportedValuesf(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// EqualValues asserts that two objects are equal or convertible to the larger\n// type and equal.\n//\n//\trequire.EqualValues(t, uint32(123), int32(123))\nfunc EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.EqualValues(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// EqualValuesf asserts that two objects are equal or convertible to the larger\n// type and equal.\n//\n//\trequire.EqualValuesf(t, uint32(123), int32(123), \"error message %s\", \"formatted\")\nfunc EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.EqualValuesf(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Equalf asserts that two objects are equal.\n//\n//\trequire.Equalf(t, 123, 123, \"error message %s\", \"formatted\")\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses). Function equality\n// cannot be determined and will always fail.\nfunc Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Equalf(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Error asserts that a function returned an error (i.e. not `nil`).\n//\n//\tactualObj, err := SomeFunction()\n//\trequire.Error(t, err)\nfunc Error(t TestingT, err error, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Error(t, err, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.\n// This is a wrapper for errors.As.\nfunc ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.ErrorAs(t, err, target, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.\n// This is a wrapper for errors.As.\nfunc ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.ErrorAsf(t, err, target, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// ErrorContains asserts that a function returned an error (i.e. not `nil`)\n// and that the error contains the specified substring.\n//\n//\tactualObj, err := SomeFunction()\n//\trequire.ErrorContains(t, err,  expectedErrorSubString)\nfunc ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.ErrorContains(t, theError, contains, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// ErrorContainsf asserts that a function returned an error (i.e. not `nil`)\n// and that the error contains the specified substring.\n//\n//\tactualObj, err := SomeFunction()\n//\trequire.ErrorContainsf(t, err,  expectedErrorSubString, \"error message %s\", \"formatted\")\nfunc ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.ErrorContainsf(t, theError, contains, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// ErrorIs asserts that at least one of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc ErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.ErrorIs(t, err, target, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// ErrorIsf asserts that at least one of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc ErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.ErrorIsf(t, err, target, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Errorf asserts that a function returned an error (i.e. not `nil`).\n//\n//\tactualObj, err := SomeFunction()\n//\trequire.Errorf(t, err, \"error message %s\", \"formatted\")\nfunc Errorf(t TestingT, err error, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Errorf(t, err, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Eventually asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick.\n//\n//\trequire.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond)\nfunc Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Eventually(t, condition, waitFor, tick, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// EventuallyWithT asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick. In contrast to Eventually,\n// it supplies a CollectT to the condition function, so that the condition\n// function can use the CollectT to call other assertions.\n// The condition is considered \"met\" if no errors are raised in a tick.\n// The supplied CollectT collects all errors from one tick (if there are any).\n// If the condition is not met before waitFor, the collected errors of\n// the last tick are copied to t.\n//\n//\texternalValue := false\n//\tgo func() {\n//\t\ttime.Sleep(8*time.Second)\n//\t\texternalValue = true\n//\t}()\n//\trequire.EventuallyWithT(t, func(c *require.CollectT) {\n//\t\t// add assertions as needed; any assertion failure will fail the current tick\n//\t\trequire.True(c, externalValue, \"expected 'externalValue' to be true\")\n//\t}, 10*time.Second, 1*time.Second, \"external state has not changed to 'true'; still false\")\nfunc EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.EventuallyWithT(t, condition, waitFor, tick, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// EventuallyWithTf asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick. In contrast to Eventually,\n// it supplies a CollectT to the condition function, so that the condition\n// function can use the CollectT to call other assertions.\n// The condition is considered \"met\" if no errors are raised in a tick.\n// The supplied CollectT collects all errors from one tick (if there are any).\n// If the condition is not met before waitFor, the collected errors of\n// the last tick are copied to t.\n//\n//\texternalValue := false\n//\tgo func() {\n//\t\ttime.Sleep(8*time.Second)\n//\t\texternalValue = true\n//\t}()\n//\trequire.EventuallyWithTf(t, func(c *require.CollectT, \"error message %s\", \"formatted\") {\n//\t\t// add assertions as needed; any assertion failure will fail the current tick\n//\t\trequire.True(c, externalValue, \"expected 'externalValue' to be true\")\n//\t}, 10*time.Second, 1*time.Second, \"external state has not changed to 'true'; still false\")\nfunc EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.EventuallyWithTf(t, condition, waitFor, tick, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Eventuallyf asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick.\n//\n//\trequire.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, \"error message %s\", \"formatted\")\nfunc Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Eventuallyf(t, condition, waitFor, tick, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Exactly asserts that two objects are equal in value and type.\n//\n//\trequire.Exactly(t, int32(123), int64(123))\nfunc Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Exactly(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Exactlyf asserts that two objects are equal in value and type.\n//\n//\trequire.Exactlyf(t, int32(123), int64(123), \"error message %s\", \"formatted\")\nfunc Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Exactlyf(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Fail reports a failure through\nfunc Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Fail(t, failureMessage, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// FailNow fails test\nfunc FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.FailNow(t, failureMessage, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// FailNowf fails test\nfunc FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.FailNowf(t, failureMessage, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Failf reports a failure through\nfunc Failf(t TestingT, failureMessage string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Failf(t, failureMessage, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// False asserts that the specified value is false.\n//\n//\trequire.False(t, myBool)\nfunc False(t TestingT, value bool, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.False(t, value, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Falsef asserts that the specified value is false.\n//\n//\trequire.Falsef(t, myBool, \"error message %s\", \"formatted\")\nfunc Falsef(t TestingT, value bool, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Falsef(t, value, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// FileExists checks whether a file exists in the given path. It also fails if\n// the path points to a directory or there is an error when trying to check the file.\nfunc FileExists(t TestingT, path string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.FileExists(t, path, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// FileExistsf checks whether a file exists in the given path. It also fails if\n// the path points to a directory or there is an error when trying to check the file.\nfunc FileExistsf(t TestingT, path string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.FileExistsf(t, path, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Greater asserts that the first element is greater than the second\n//\n//\trequire.Greater(t, 2, 1)\n//\trequire.Greater(t, float64(2), float64(1))\n//\trequire.Greater(t, \"b\", \"a\")\nfunc Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Greater(t, e1, e2, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// GreaterOrEqual asserts that the first element is greater than or equal to the second\n//\n//\trequire.GreaterOrEqual(t, 2, 1)\n//\trequire.GreaterOrEqual(t, 2, 2)\n//\trequire.GreaterOrEqual(t, \"b\", \"a\")\n//\trequire.GreaterOrEqual(t, \"b\", \"b\")\nfunc GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.GreaterOrEqual(t, e1, e2, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// GreaterOrEqualf asserts that the first element is greater than or equal to the second\n//\n//\trequire.GreaterOrEqualf(t, 2, 1, \"error message %s\", \"formatted\")\n//\trequire.GreaterOrEqualf(t, 2, 2, \"error message %s\", \"formatted\")\n//\trequire.GreaterOrEqualf(t, \"b\", \"a\", \"error message %s\", \"formatted\")\n//\trequire.GreaterOrEqualf(t, \"b\", \"b\", \"error message %s\", \"formatted\")\nfunc GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.GreaterOrEqualf(t, e1, e2, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Greaterf asserts that the first element is greater than the second\n//\n//\trequire.Greaterf(t, 2, 1, \"error message %s\", \"formatted\")\n//\trequire.Greaterf(t, float64(2), float64(1), \"error message %s\", \"formatted\")\n//\trequire.Greaterf(t, \"b\", \"a\", \"error message %s\", \"formatted\")\nfunc Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Greaterf(t, e1, e2, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPBodyContains asserts that a specified handler returns a\n// body that contains a string.\n//\n//\trequire.HTTPBodyContains(t, myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPBodyContains(t, handler, method, url, values, str, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPBodyContainsf asserts that a specified handler returns a\n// body that contains a string.\n//\n//\trequire.HTTPBodyContainsf(t, myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\", \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPBodyContainsf(t, handler, method, url, values, str, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPBodyNotContains asserts that a specified handler returns a\n// body that does not contain a string.\n//\n//\trequire.HTTPBodyNotContains(t, myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPBodyNotContains(t, handler, method, url, values, str, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPBodyNotContainsf asserts that a specified handler returns a\n// body that does not contain a string.\n//\n//\trequire.HTTPBodyNotContainsf(t, myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\", \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPBodyNotContainsf(t, handler, method, url, values, str, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPError asserts that a specified handler returns an error status code.\n//\n//\trequire.HTTPError(t, myHandler, \"POST\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPError(t, handler, method, url, values, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPErrorf asserts that a specified handler returns an error status code.\n//\n//\trequire.HTTPErrorf(t, myHandler, \"POST\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPErrorf(t, handler, method, url, values, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPRedirect asserts that a specified handler returns a redirect status code.\n//\n//\trequire.HTTPRedirect(t, myHandler, \"GET\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPRedirect(t, handler, method, url, values, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPRedirectf asserts that a specified handler returns a redirect status code.\n//\n//\trequire.HTTPRedirectf(t, myHandler, \"GET\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPRedirectf(t, handler, method, url, values, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPStatusCode asserts that a specified handler returns a specified status code.\n//\n//\trequire.HTTPStatusCode(t, myHandler, \"GET\", \"/notImplemented\", nil, 501)\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPStatusCode(t, handler, method, url, values, statuscode, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPStatusCodef asserts that a specified handler returns a specified status code.\n//\n//\trequire.HTTPStatusCodef(t, myHandler, \"GET\", \"/notImplemented\", nil, 501, \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPStatusCodef(t, handler, method, url, values, statuscode, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPSuccess asserts that a specified handler returns a success status code.\n//\n//\trequire.HTTPSuccess(t, myHandler, \"POST\", \"http://www.google.com\", nil)\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPSuccess(t, handler, method, url, values, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPSuccessf asserts that a specified handler returns a success status code.\n//\n//\trequire.HTTPSuccessf(t, myHandler, \"POST\", \"http://www.google.com\", nil, \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPSuccessf(t, handler, method, url, values, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Implements asserts that an object is implemented by the specified interface.\n//\n//\trequire.Implements(t, (*MyInterface)(nil), new(MyObject))\nfunc Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Implements(t, interfaceObject, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Implementsf asserts that an object is implemented by the specified interface.\n//\n//\trequire.Implementsf(t, (*MyInterface)(nil), new(MyObject), \"error message %s\", \"formatted\")\nfunc Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Implementsf(t, interfaceObject, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InDelta asserts that the two numerals are within delta of each other.\n//\n//\trequire.InDelta(t, math.Pi, 22/7.0, 0.01)\nfunc InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InDelta(t, expected, actual, delta, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.\nfunc InDeltaMapValues(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InDeltaMapValues(t, expected, actual, delta, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.\nfunc InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InDeltaMapValuesf(t, expected, actual, delta, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InDeltaSlice is the same as InDelta, except it compares two slices.\nfunc InDeltaSlice(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InDeltaSlice(t, expected, actual, delta, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InDeltaSlicef is the same as InDelta, except it compares two slices.\nfunc InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InDeltaSlicef(t, expected, actual, delta, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InDeltaf asserts that the two numerals are within delta of each other.\n//\n//\trequire.InDeltaf(t, math.Pi, 22/7.0, 0.01, \"error message %s\", \"formatted\")\nfunc InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InDeltaf(t, expected, actual, delta, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InEpsilon asserts that expected and actual have a relative error less than epsilon\nfunc InEpsilon(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InEpsilon(t, expected, actual, epsilon, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.\nfunc InEpsilonSlice(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InEpsilonSlice(t, expected, actual, epsilon, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.\nfunc InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InEpsilonSlicef(t, expected, actual, epsilon, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InEpsilonf asserts that expected and actual have a relative error less than epsilon\nfunc InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InEpsilonf(t, expected, actual, epsilon, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsDecreasing asserts that the collection is decreasing\n//\n//\trequire.IsDecreasing(t, []int{2, 1, 0})\n//\trequire.IsDecreasing(t, []float{2, 1})\n//\trequire.IsDecreasing(t, []string{\"b\", \"a\"})\nfunc IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsDecreasing(t, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsDecreasingf asserts that the collection is decreasing\n//\n//\trequire.IsDecreasingf(t, []int{2, 1, 0}, \"error message %s\", \"formatted\")\n//\trequire.IsDecreasingf(t, []float{2, 1}, \"error message %s\", \"formatted\")\n//\trequire.IsDecreasingf(t, []string{\"b\", \"a\"}, \"error message %s\", \"formatted\")\nfunc IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsDecreasingf(t, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsIncreasing asserts that the collection is increasing\n//\n//\trequire.IsIncreasing(t, []int{1, 2, 3})\n//\trequire.IsIncreasing(t, []float{1, 2})\n//\trequire.IsIncreasing(t, []string{\"a\", \"b\"})\nfunc IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsIncreasing(t, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsIncreasingf asserts that the collection is increasing\n//\n//\trequire.IsIncreasingf(t, []int{1, 2, 3}, \"error message %s\", \"formatted\")\n//\trequire.IsIncreasingf(t, []float{1, 2}, \"error message %s\", \"formatted\")\n//\trequire.IsIncreasingf(t, []string{\"a\", \"b\"}, \"error message %s\", \"formatted\")\nfunc IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsIncreasingf(t, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsNonDecreasing asserts that the collection is not decreasing\n//\n//\trequire.IsNonDecreasing(t, []int{1, 1, 2})\n//\trequire.IsNonDecreasing(t, []float{1, 2})\n//\trequire.IsNonDecreasing(t, []string{\"a\", \"b\"})\nfunc IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsNonDecreasing(t, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsNonDecreasingf asserts that the collection is not decreasing\n//\n//\trequire.IsNonDecreasingf(t, []int{1, 1, 2}, \"error message %s\", \"formatted\")\n//\trequire.IsNonDecreasingf(t, []float{1, 2}, \"error message %s\", \"formatted\")\n//\trequire.IsNonDecreasingf(t, []string{\"a\", \"b\"}, \"error message %s\", \"formatted\")\nfunc IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsNonDecreasingf(t, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsNonIncreasing asserts that the collection is not increasing\n//\n//\trequire.IsNonIncreasing(t, []int{2, 1, 1})\n//\trequire.IsNonIncreasing(t, []float{2, 1})\n//\trequire.IsNonIncreasing(t, []string{\"b\", \"a\"})\nfunc IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsNonIncreasing(t, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsNonIncreasingf asserts that the collection is not increasing\n//\n//\trequire.IsNonIncreasingf(t, []int{2, 1, 1}, \"error message %s\", \"formatted\")\n//\trequire.IsNonIncreasingf(t, []float{2, 1}, \"error message %s\", \"formatted\")\n//\trequire.IsNonIncreasingf(t, []string{\"b\", \"a\"}, \"error message %s\", \"formatted\")\nfunc IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsNonIncreasingf(t, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsNotType asserts that the specified objects are not of the same type.\n//\n//\trequire.IsNotType(t, &NotMyStruct{}, &MyStruct{})\nfunc IsNotType(t TestingT, theType interface{}, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsNotType(t, theType, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsNotTypef asserts that the specified objects are not of the same type.\n//\n//\trequire.IsNotTypef(t, &NotMyStruct{}, &MyStruct{}, \"error message %s\", \"formatted\")\nfunc IsNotTypef(t TestingT, theType interface{}, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsNotTypef(t, theType, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsType asserts that the specified objects are of the same type.\n//\n//\trequire.IsType(t, &MyStruct{}, &MyStruct{})\nfunc IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsType(t, expectedType, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsTypef asserts that the specified objects are of the same type.\n//\n//\trequire.IsTypef(t, &MyStruct{}, &MyStruct{}, \"error message %s\", \"formatted\")\nfunc IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsTypef(t, expectedType, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// JSONEq asserts that two JSON strings are equivalent.\n//\n//\trequire.JSONEq(t, `{\"hello\": \"world\", \"foo\": \"bar\"}`, `{\"foo\": \"bar\", \"hello\": \"world\"}`)\nfunc JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.JSONEq(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// JSONEqf asserts that two JSON strings are equivalent.\n//\n//\trequire.JSONEqf(t, `{\"hello\": \"world\", \"foo\": \"bar\"}`, `{\"foo\": \"bar\", \"hello\": \"world\"}`, \"error message %s\", \"formatted\")\nfunc JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.JSONEqf(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Len asserts that the specified object has specific length.\n// Len also fails if the object has a type that len() not accept.\n//\n//\trequire.Len(t, mySlice, 3)\nfunc Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Len(t, object, length, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Lenf asserts that the specified object has specific length.\n// Lenf also fails if the object has a type that len() not accept.\n//\n//\trequire.Lenf(t, mySlice, 3, \"error message %s\", \"formatted\")\nfunc Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Lenf(t, object, length, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Less asserts that the first element is less than the second\n//\n//\trequire.Less(t, 1, 2)\n//\trequire.Less(t, float64(1), float64(2))\n//\trequire.Less(t, \"a\", \"b\")\nfunc Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Less(t, e1, e2, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// LessOrEqual asserts that the first element is less than or equal to the second\n//\n//\trequire.LessOrEqual(t, 1, 2)\n//\trequire.LessOrEqual(t, 2, 2)\n//\trequire.LessOrEqual(t, \"a\", \"b\")\n//\trequire.LessOrEqual(t, \"b\", \"b\")\nfunc LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.LessOrEqual(t, e1, e2, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// LessOrEqualf asserts that the first element is less than or equal to the second\n//\n//\trequire.LessOrEqualf(t, 1, 2, \"error message %s\", \"formatted\")\n//\trequire.LessOrEqualf(t, 2, 2, \"error message %s\", \"formatted\")\n//\trequire.LessOrEqualf(t, \"a\", \"b\", \"error message %s\", \"formatted\")\n//\trequire.LessOrEqualf(t, \"b\", \"b\", \"error message %s\", \"formatted\")\nfunc LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.LessOrEqualf(t, e1, e2, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Lessf asserts that the first element is less than the second\n//\n//\trequire.Lessf(t, 1, 2, \"error message %s\", \"formatted\")\n//\trequire.Lessf(t, float64(1), float64(2), \"error message %s\", \"formatted\")\n//\trequire.Lessf(t, \"a\", \"b\", \"error message %s\", \"formatted\")\nfunc Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Lessf(t, e1, e2, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Negative asserts that the specified element is negative\n//\n//\trequire.Negative(t, -1)\n//\trequire.Negative(t, -1.23)\nfunc Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Negative(t, e, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Negativef asserts that the specified element is negative\n//\n//\trequire.Negativef(t, -1, \"error message %s\", \"formatted\")\n//\trequire.Negativef(t, -1.23, \"error message %s\", \"formatted\")\nfunc Negativef(t TestingT, e interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Negativef(t, e, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Never asserts that the given condition doesn't satisfy in waitFor time,\n// periodically checking the target function each tick.\n//\n//\trequire.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond)\nfunc Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Never(t, condition, waitFor, tick, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Neverf asserts that the given condition doesn't satisfy in waitFor time,\n// periodically checking the target function each tick.\n//\n//\trequire.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, \"error message %s\", \"formatted\")\nfunc Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Neverf(t, condition, waitFor, tick, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Nil asserts that the specified object is nil.\n//\n//\trequire.Nil(t, err)\nfunc Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Nil(t, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Nilf asserts that the specified object is nil.\n//\n//\trequire.Nilf(t, err, \"error message %s\", \"formatted\")\nfunc Nilf(t TestingT, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Nilf(t, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NoDirExists checks whether a directory does not exist in the given path.\n// It fails if the path points to an existing _directory_ only.\nfunc NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NoDirExists(t, path, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NoDirExistsf checks whether a directory does not exist in the given path.\n// It fails if the path points to an existing _directory_ only.\nfunc NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NoDirExistsf(t, path, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NoError asserts that a function returned no error (i.e. `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if require.NoError(t, err) {\n//\t\t   require.Equal(t, expectedObj, actualObj)\n//\t  }\nfunc NoError(t TestingT, err error, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NoError(t, err, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NoErrorf asserts that a function returned no error (i.e. `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if require.NoErrorf(t, err, \"error message %s\", \"formatted\") {\n//\t\t   require.Equal(t, expectedObj, actualObj)\n//\t  }\nfunc NoErrorf(t TestingT, err error, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NoErrorf(t, err, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NoFileExists checks whether a file does not exist in a given path. It fails\n// if the path points to an existing _file_ only.\nfunc NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NoFileExists(t, path, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NoFileExistsf checks whether a file does not exist in a given path. It fails\n// if the path points to an existing _file_ only.\nfunc NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NoFileExistsf(t, path, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the\n// specified substring or element.\n//\n//\trequire.NotContains(t, \"Hello World\", \"Earth\")\n//\trequire.NotContains(t, [\"Hello\", \"World\"], \"Earth\")\n//\trequire.NotContains(t, {\"Hello\": \"World\"}, \"Earth\")\nfunc NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotContains(t, s, contains, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the\n// specified substring or element.\n//\n//\trequire.NotContainsf(t, \"Hello World\", \"Earth\", \"error message %s\", \"formatted\")\n//\trequire.NotContainsf(t, [\"Hello\", \"World\"], \"Earth\", \"error message %s\", \"formatted\")\n//\trequire.NotContainsf(t, {\"Hello\": \"World\"}, \"Earth\", \"error message %s\", \"formatted\")\nfunc NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotContainsf(t, s, contains, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotElementsMatch asserts that the specified listA(array, slice...) is NOT equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should not match.\n// This is an inverse of ElementsMatch.\n//\n// require.NotElementsMatch(t, [1, 1, 2, 3], [1, 1, 2, 3]) -> false\n//\n// require.NotElementsMatch(t, [1, 1, 2, 3], [1, 2, 3]) -> true\n//\n// require.NotElementsMatch(t, [1, 2, 3], [1, 2, 4]) -> true\nfunc NotElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotElementsMatch(t, listA, listB, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotElementsMatchf asserts that the specified listA(array, slice...) is NOT equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should not match.\n// This is an inverse of ElementsMatch.\n//\n// require.NotElementsMatchf(t, [1, 1, 2, 3], [1, 1, 2, 3], \"error message %s\", \"formatted\") -> false\n//\n// require.NotElementsMatchf(t, [1, 1, 2, 3], [1, 2, 3], \"error message %s\", \"formatted\") -> true\n//\n// require.NotElementsMatchf(t, [1, 2, 3], [1, 2, 4], \"error message %s\", \"formatted\") -> true\nfunc NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotElementsMatchf(t, listA, listB, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotEmpty asserts that the specified object is NOT [Empty].\n//\n//\tif require.NotEmpty(t, obj) {\n//\t  require.Equal(t, \"two\", obj[1])\n//\t}\nfunc NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotEmpty(t, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotEmptyf asserts that the specified object is NOT [Empty].\n//\n//\tif require.NotEmptyf(t, obj, \"error message %s\", \"formatted\") {\n//\t  require.Equal(t, \"two\", obj[1])\n//\t}\nfunc NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotEmptyf(t, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotEqual asserts that the specified values are NOT equal.\n//\n//\trequire.NotEqual(t, obj1, obj2)\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses).\nfunc NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotEqual(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotEqualValues asserts that two objects are not equal even when converted to the same type\n//\n//\trequire.NotEqualValues(t, obj1, obj2)\nfunc NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotEqualValues(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotEqualValuesf asserts that two objects are not equal even when converted to the same type\n//\n//\trequire.NotEqualValuesf(t, obj1, obj2, \"error message %s\", \"formatted\")\nfunc NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotEqualValuesf(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotEqualf asserts that the specified values are NOT equal.\n//\n//\trequire.NotEqualf(t, obj1, obj2, \"error message %s\", \"formatted\")\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses).\nfunc NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotEqualf(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotErrorAs asserts that none of the errors in err's chain matches target,\n// but if so, sets target to that error value.\nfunc NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotErrorAs(t, err, target, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotErrorAsf asserts that none of the errors in err's chain matches target,\n// but if so, sets target to that error value.\nfunc NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotErrorAsf(t, err, target, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotErrorIs asserts that none of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotErrorIs(t, err, target, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotErrorIsf asserts that none of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotErrorIsf(t, err, target, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotImplements asserts that an object does not implement the specified interface.\n//\n//\trequire.NotImplements(t, (*MyInterface)(nil), new(MyObject))\nfunc NotImplements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotImplements(t, interfaceObject, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotImplementsf asserts that an object does not implement the specified interface.\n//\n//\trequire.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), \"error message %s\", \"formatted\")\nfunc NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotImplementsf(t, interfaceObject, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotNil asserts that the specified object is not nil.\n//\n//\trequire.NotNil(t, err)\nfunc NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotNil(t, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotNilf asserts that the specified object is not nil.\n//\n//\trequire.NotNilf(t, err, \"error message %s\", \"formatted\")\nfunc NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotNilf(t, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.\n//\n//\trequire.NotPanics(t, func(){ RemainCalm() })\nfunc NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotPanics(t, f, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic.\n//\n//\trequire.NotPanicsf(t, func(){ RemainCalm() }, \"error message %s\", \"formatted\")\nfunc NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotPanicsf(t, f, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotRegexp asserts that a specified regexp does not match a string.\n//\n//\trequire.NotRegexp(t, regexp.MustCompile(\"starts\"), \"it's starting\")\n//\trequire.NotRegexp(t, \"^start\", \"it's not starting\")\nfunc NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotRegexp(t, rx, str, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotRegexpf asserts that a specified regexp does not match a string.\n//\n//\trequire.NotRegexpf(t, regexp.MustCompile(\"starts\"), \"it's starting\", \"error message %s\", \"formatted\")\n//\trequire.NotRegexpf(t, \"^start\", \"it's not starting\", \"error message %s\", \"formatted\")\nfunc NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotRegexpf(t, rx, str, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotSame asserts that two pointers do not reference the same object.\n//\n//\trequire.NotSame(t, ptr1, ptr2)\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc NotSame(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotSame(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotSamef asserts that two pointers do not reference the same object.\n//\n//\trequire.NotSamef(t, ptr1, ptr2, \"error message %s\", \"formatted\")\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotSamef(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotSubset asserts that the list (array, slice, or map) does NOT contain all\n// elements given in the subset (array, slice, or map).\n// Map elements are key-value pairs unless compared with an array or slice where\n// only the map key is evaluated.\n//\n//\trequire.NotSubset(t, [1, 3, 4], [1, 2])\n//\trequire.NotSubset(t, {\"x\": 1, \"y\": 2}, {\"z\": 3})\n//\trequire.NotSubset(t, [1, 3, 4], {1: \"one\", 2: \"two\"})\n//\trequire.NotSubset(t, {\"x\": 1, \"y\": 2}, [\"z\"])\nfunc NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotSubset(t, list, subset, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotSubsetf asserts that the list (array, slice, or map) does NOT contain all\n// elements given in the subset (array, slice, or map).\n// Map elements are key-value pairs unless compared with an array or slice where\n// only the map key is evaluated.\n//\n//\trequire.NotSubsetf(t, [1, 3, 4], [1, 2], \"error message %s\", \"formatted\")\n//\trequire.NotSubsetf(t, {\"x\": 1, \"y\": 2}, {\"z\": 3}, \"error message %s\", \"formatted\")\n//\trequire.NotSubsetf(t, [1, 3, 4], {1: \"one\", 2: \"two\"}, \"error message %s\", \"formatted\")\n//\trequire.NotSubsetf(t, {\"x\": 1, \"y\": 2}, [\"z\"], \"error message %s\", \"formatted\")\nfunc NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotSubsetf(t, list, subset, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotZero asserts that i is not the zero value for its type.\nfunc NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotZero(t, i, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotZerof asserts that i is not the zero value for its type.\nfunc NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotZerof(t, i, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Panics asserts that the code inside the specified PanicTestFunc panics.\n//\n//\trequire.Panics(t, func(){ GoCrazy() })\nfunc Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Panics(t, f, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// PanicsWithError asserts that the code inside the specified PanicTestFunc\n// panics, and that the recovered panic value is an error that satisfies the\n// EqualError comparison.\n//\n//\trequire.PanicsWithError(t, \"crazy error\", func(){ GoCrazy() })\nfunc PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.PanicsWithError(t, errString, f, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc\n// panics, and that the recovered panic value is an error that satisfies the\n// EqualError comparison.\n//\n//\trequire.PanicsWithErrorf(t, \"crazy error\", func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.PanicsWithErrorf(t, errString, f, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that\n// the recovered panic value equals the expected panic value.\n//\n//\trequire.PanicsWithValue(t, \"crazy error\", func(){ GoCrazy() })\nfunc PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.PanicsWithValue(t, expected, f, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that\n// the recovered panic value equals the expected panic value.\n//\n//\trequire.PanicsWithValuef(t, \"crazy error\", func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.PanicsWithValuef(t, expected, f, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Panicsf asserts that the code inside the specified PanicTestFunc panics.\n//\n//\trequire.Panicsf(t, func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Panicsf(t, f, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Positive asserts that the specified element is positive\n//\n//\trequire.Positive(t, 1)\n//\trequire.Positive(t, 1.23)\nfunc Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Positive(t, e, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Positivef asserts that the specified element is positive\n//\n//\trequire.Positivef(t, 1, \"error message %s\", \"formatted\")\n//\trequire.Positivef(t, 1.23, \"error message %s\", \"formatted\")\nfunc Positivef(t TestingT, e interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Positivef(t, e, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Regexp asserts that a specified regexp matches a string.\n//\n//\trequire.Regexp(t, regexp.MustCompile(\"start\"), \"it's starting\")\n//\trequire.Regexp(t, \"start...$\", \"it's not starting\")\nfunc Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Regexp(t, rx, str, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Regexpf asserts that a specified regexp matches a string.\n//\n//\trequire.Regexpf(t, regexp.MustCompile(\"start\"), \"it's starting\", \"error message %s\", \"formatted\")\n//\trequire.Regexpf(t, \"start...$\", \"it's not starting\", \"error message %s\", \"formatted\")\nfunc Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Regexpf(t, rx, str, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Same asserts that two pointers reference the same object.\n//\n//\trequire.Same(t, ptr1, ptr2)\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc Same(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Same(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Samef asserts that two pointers reference the same object.\n//\n//\trequire.Samef(t, ptr1, ptr2, \"error message %s\", \"formatted\")\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc Samef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Samef(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Subset asserts that the list (array, slice, or map) contains all elements\n// given in the subset (array, slice, or map).\n// Map elements are key-value pairs unless compared with an array or slice where\n// only the map key is evaluated.\n//\n//\trequire.Subset(t, [1, 2, 3], [1, 2])\n//\trequire.Subset(t, {\"x\": 1, \"y\": 2}, {\"x\": 1})\n//\trequire.Subset(t, [1, 2, 3], {1: \"one\", 2: \"two\"})\n//\trequire.Subset(t, {\"x\": 1, \"y\": 2}, [\"x\"])\nfunc Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Subset(t, list, subset, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Subsetf asserts that the list (array, slice, or map) contains all elements\n// given in the subset (array, slice, or map).\n// Map elements are key-value pairs unless compared with an array or slice where\n// only the map key is evaluated.\n//\n//\trequire.Subsetf(t, [1, 2, 3], [1, 2], \"error message %s\", \"formatted\")\n//\trequire.Subsetf(t, {\"x\": 1, \"y\": 2}, {\"x\": 1}, \"error message %s\", \"formatted\")\n//\trequire.Subsetf(t, [1, 2, 3], {1: \"one\", 2: \"two\"}, \"error message %s\", \"formatted\")\n//\trequire.Subsetf(t, {\"x\": 1, \"y\": 2}, [\"x\"], \"error message %s\", \"formatted\")\nfunc Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Subsetf(t, list, subset, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// True asserts that the specified value is true.\n//\n//\trequire.True(t, myBool)\nfunc True(t TestingT, value bool, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.True(t, value, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Truef asserts that the specified value is true.\n//\n//\trequire.Truef(t, myBool, \"error message %s\", \"formatted\")\nfunc Truef(t TestingT, value bool, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Truef(t, value, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// WithinDuration asserts that the two times are within duration delta of each other.\n//\n//\trequire.WithinDuration(t, time.Now(), time.Now(), 10*time.Second)\nfunc WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.WithinDuration(t, expected, actual, delta, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// WithinDurationf asserts that the two times are within duration delta of each other.\n//\n//\trequire.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, \"error message %s\", \"formatted\")\nfunc WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.WithinDurationf(t, expected, actual, delta, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// WithinRange asserts that a time is within a time range (inclusive).\n//\n//\trequire.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second))\nfunc WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.WithinRange(t, actual, start, end, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// WithinRangef asserts that a time is within a time range (inclusive).\n//\n//\trequire.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), \"error message %s\", \"formatted\")\nfunc WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.WithinRangef(t, actual, start, end, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// YAMLEq asserts that two YAML strings are equivalent.\nfunc YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.YAMLEq(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// YAMLEqf asserts that two YAML strings are equivalent.\nfunc YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.YAMLEqf(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Zero asserts that i is the zero value for its type.\nfunc Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Zero(t, i, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Zerof asserts that i is the zero value for its type.\nfunc Zerof(t TestingT, i interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Zerof(t, i, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/require/require.go.tmpl",
    "content": "{{ replace .Comment \"assert.\" \"require.\"}}\nfunc {{.DocInfo.Name}}(t TestingT, {{.Params}}) {\n\tif h, ok := t.(tHelper); ok { h.Helper() }\n\tif assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return }\n\tt.FailNow()\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/require/require_forward.go",
    "content": "// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT.\n\npackage require\n\nimport (\n\tassert \"github.com/stretchr/testify/assert\"\n\thttp \"net/http\"\n\turl \"net/url\"\n\ttime \"time\"\n)\n\n// Condition uses a Comparison to assert a complex condition.\nfunc (a *Assertions) Condition(comp assert.Comparison, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tCondition(a.t, comp, msgAndArgs...)\n}\n\n// Conditionf uses a Comparison to assert a complex condition.\nfunc (a *Assertions) Conditionf(comp assert.Comparison, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tConditionf(a.t, comp, msg, args...)\n}\n\n// Contains asserts that the specified string, list(array, slice...) or map contains the\n// specified substring or element.\n//\n//\ta.Contains(\"Hello World\", \"World\")\n//\ta.Contains([\"Hello\", \"World\"], \"World\")\n//\ta.Contains({\"Hello\": \"World\"}, \"Hello\")\nfunc (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tContains(a.t, s, contains, msgAndArgs...)\n}\n\n// Containsf asserts that the specified string, list(array, slice...) or map contains the\n// specified substring or element.\n//\n//\ta.Containsf(\"Hello World\", \"World\", \"error message %s\", \"formatted\")\n//\ta.Containsf([\"Hello\", \"World\"], \"World\", \"error message %s\", \"formatted\")\n//\ta.Containsf({\"Hello\": \"World\"}, \"Hello\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tContainsf(a.t, s, contains, msg, args...)\n}\n\n// DirExists checks whether a directory exists in the given path. It also fails\n// if the path is a file rather a directory or there is an error checking whether it exists.\nfunc (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tDirExists(a.t, path, msgAndArgs...)\n}\n\n// DirExistsf checks whether a directory exists in the given path. It also fails\n// if the path is a file rather a directory or there is an error checking whether it exists.\nfunc (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tDirExistsf(a.t, path, msg, args...)\n}\n\n// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should match.\n//\n// a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2])\nfunc (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tElementsMatch(a.t, listA, listB, msgAndArgs...)\n}\n\n// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should match.\n//\n// a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], \"error message %s\", \"formatted\")\nfunc (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tElementsMatchf(a.t, listA, listB, msg, args...)\n}\n\n// Empty asserts that the given value is \"empty\".\n//\n// [Zero values] are \"empty\".\n//\n// Arrays are \"empty\" if every element is the zero value of the type (stricter than \"empty\").\n//\n// Slices, maps and channels with zero length are \"empty\".\n//\n// Pointer values are \"empty\" if the pointer is nil or if the pointed value is \"empty\".\n//\n//\ta.Empty(obj)\n//\n// [Zero values]: https://go.dev/ref/spec#The_zero_value\nfunc (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEmpty(a.t, object, msgAndArgs...)\n}\n\n// Emptyf asserts that the given value is \"empty\".\n//\n// [Zero values] are \"empty\".\n//\n// Arrays are \"empty\" if every element is the zero value of the type (stricter than \"empty\").\n//\n// Slices, maps and channels with zero length are \"empty\".\n//\n// Pointer values are \"empty\" if the pointer is nil or if the pointed value is \"empty\".\n//\n//\ta.Emptyf(obj, \"error message %s\", \"formatted\")\n//\n// [Zero values]: https://go.dev/ref/spec#The_zero_value\nfunc (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEmptyf(a.t, object, msg, args...)\n}\n\n// Equal asserts that two objects are equal.\n//\n//\ta.Equal(123, 123)\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses). Function equality\n// cannot be determined and will always fail.\nfunc (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEqual(a.t, expected, actual, msgAndArgs...)\n}\n\n// EqualError asserts that a function returned an error (i.e. not `nil`)\n// and that it is equal to the provided error.\n//\n//\tactualObj, err := SomeFunction()\n//\ta.EqualError(err,  expectedErrorString)\nfunc (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEqualError(a.t, theError, errString, msgAndArgs...)\n}\n\n// EqualErrorf asserts that a function returned an error (i.e. not `nil`)\n// and that it is equal to the provided error.\n//\n//\tactualObj, err := SomeFunction()\n//\ta.EqualErrorf(err,  expectedErrorString, \"error message %s\", \"formatted\")\nfunc (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEqualErrorf(a.t, theError, errString, msg, args...)\n}\n\n// EqualExportedValues asserts that the types of two objects are equal and their public\n// fields are also equal. This is useful for comparing structs that have private fields\n// that could potentially differ.\n//\n//\t type S struct {\n//\t\tExported     \tint\n//\t\tnotExported   \tint\n//\t }\n//\t a.EqualExportedValues(S{1, 2}, S{1, 3}) => true\n//\t a.EqualExportedValues(S{1, 2}, S{2, 3}) => false\nfunc (a *Assertions) EqualExportedValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEqualExportedValues(a.t, expected, actual, msgAndArgs...)\n}\n\n// EqualExportedValuesf asserts that the types of two objects are equal and their public\n// fields are also equal. This is useful for comparing structs that have private fields\n// that could potentially differ.\n//\n//\t type S struct {\n//\t\tExported     \tint\n//\t\tnotExported   \tint\n//\t }\n//\t a.EqualExportedValuesf(S{1, 2}, S{1, 3}, \"error message %s\", \"formatted\") => true\n//\t a.EqualExportedValuesf(S{1, 2}, S{2, 3}, \"error message %s\", \"formatted\") => false\nfunc (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEqualExportedValuesf(a.t, expected, actual, msg, args...)\n}\n\n// EqualValues asserts that two objects are equal or convertible to the larger\n// type and equal.\n//\n//\ta.EqualValues(uint32(123), int32(123))\nfunc (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEqualValues(a.t, expected, actual, msgAndArgs...)\n}\n\n// EqualValuesf asserts that two objects are equal or convertible to the larger\n// type and equal.\n//\n//\ta.EqualValuesf(uint32(123), int32(123), \"error message %s\", \"formatted\")\nfunc (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEqualValuesf(a.t, expected, actual, msg, args...)\n}\n\n// Equalf asserts that two objects are equal.\n//\n//\ta.Equalf(123, 123, \"error message %s\", \"formatted\")\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses). Function equality\n// cannot be determined and will always fail.\nfunc (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEqualf(a.t, expected, actual, msg, args...)\n}\n\n// Error asserts that a function returned an error (i.e. not `nil`).\n//\n//\tactualObj, err := SomeFunction()\n//\ta.Error(err)\nfunc (a *Assertions) Error(err error, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tError(a.t, err, msgAndArgs...)\n}\n\n// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.\n// This is a wrapper for errors.As.\nfunc (a *Assertions) ErrorAs(err error, target interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tErrorAs(a.t, err, target, msgAndArgs...)\n}\n\n// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.\n// This is a wrapper for errors.As.\nfunc (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tErrorAsf(a.t, err, target, msg, args...)\n}\n\n// ErrorContains asserts that a function returned an error (i.e. not `nil`)\n// and that the error contains the specified substring.\n//\n//\tactualObj, err := SomeFunction()\n//\ta.ErrorContains(err,  expectedErrorSubString)\nfunc (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tErrorContains(a.t, theError, contains, msgAndArgs...)\n}\n\n// ErrorContainsf asserts that a function returned an error (i.e. not `nil`)\n// and that the error contains the specified substring.\n//\n//\tactualObj, err := SomeFunction()\n//\ta.ErrorContainsf(err,  expectedErrorSubString, \"error message %s\", \"formatted\")\nfunc (a *Assertions) ErrorContainsf(theError error, contains string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tErrorContainsf(a.t, theError, contains, msg, args...)\n}\n\n// ErrorIs asserts that at least one of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc (a *Assertions) ErrorIs(err error, target error, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tErrorIs(a.t, err, target, msgAndArgs...)\n}\n\n// ErrorIsf asserts that at least one of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc (a *Assertions) ErrorIsf(err error, target error, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tErrorIsf(a.t, err, target, msg, args...)\n}\n\n// Errorf asserts that a function returned an error (i.e. not `nil`).\n//\n//\tactualObj, err := SomeFunction()\n//\ta.Errorf(err, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Errorf(err error, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tErrorf(a.t, err, msg, args...)\n}\n\n// Eventually asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick.\n//\n//\ta.Eventually(func() bool { return true; }, time.Second, 10*time.Millisecond)\nfunc (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEventually(a.t, condition, waitFor, tick, msgAndArgs...)\n}\n\n// EventuallyWithT asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick. In contrast to Eventually,\n// it supplies a CollectT to the condition function, so that the condition\n// function can use the CollectT to call other assertions.\n// The condition is considered \"met\" if no errors are raised in a tick.\n// The supplied CollectT collects all errors from one tick (if there are any).\n// If the condition is not met before waitFor, the collected errors of\n// the last tick are copied to t.\n//\n//\texternalValue := false\n//\tgo func() {\n//\t\ttime.Sleep(8*time.Second)\n//\t\texternalValue = true\n//\t}()\n//\ta.EventuallyWithT(func(c *assert.CollectT) {\n//\t\t// add assertions as needed; any assertion failure will fail the current tick\n//\t\tassert.True(c, externalValue, \"expected 'externalValue' to be true\")\n//\t}, 10*time.Second, 1*time.Second, \"external state has not changed to 'true'; still false\")\nfunc (a *Assertions) EventuallyWithT(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEventuallyWithT(a.t, condition, waitFor, tick, msgAndArgs...)\n}\n\n// EventuallyWithTf asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick. In contrast to Eventually,\n// it supplies a CollectT to the condition function, so that the condition\n// function can use the CollectT to call other assertions.\n// The condition is considered \"met\" if no errors are raised in a tick.\n// The supplied CollectT collects all errors from one tick (if there are any).\n// If the condition is not met before waitFor, the collected errors of\n// the last tick are copied to t.\n//\n//\texternalValue := false\n//\tgo func() {\n//\t\ttime.Sleep(8*time.Second)\n//\t\texternalValue = true\n//\t}()\n//\ta.EventuallyWithTf(func(c *assert.CollectT, \"error message %s\", \"formatted\") {\n//\t\t// add assertions as needed; any assertion failure will fail the current tick\n//\t\tassert.True(c, externalValue, \"expected 'externalValue' to be true\")\n//\t}, 10*time.Second, 1*time.Second, \"external state has not changed to 'true'; still false\")\nfunc (a *Assertions) EventuallyWithTf(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEventuallyWithTf(a.t, condition, waitFor, tick, msg, args...)\n}\n\n// Eventuallyf asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick.\n//\n//\ta.Eventuallyf(func() bool { return true; }, time.Second, 10*time.Millisecond, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Eventuallyf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEventuallyf(a.t, condition, waitFor, tick, msg, args...)\n}\n\n// Exactly asserts that two objects are equal in value and type.\n//\n//\ta.Exactly(int32(123), int64(123))\nfunc (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tExactly(a.t, expected, actual, msgAndArgs...)\n}\n\n// Exactlyf asserts that two objects are equal in value and type.\n//\n//\ta.Exactlyf(int32(123), int64(123), \"error message %s\", \"formatted\")\nfunc (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tExactlyf(a.t, expected, actual, msg, args...)\n}\n\n// Fail reports a failure through\nfunc (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFail(a.t, failureMessage, msgAndArgs...)\n}\n\n// FailNow fails test\nfunc (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFailNow(a.t, failureMessage, msgAndArgs...)\n}\n\n// FailNowf fails test\nfunc (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFailNowf(a.t, failureMessage, msg, args...)\n}\n\n// Failf reports a failure through\nfunc (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFailf(a.t, failureMessage, msg, args...)\n}\n\n// False asserts that the specified value is false.\n//\n//\ta.False(myBool)\nfunc (a *Assertions) False(value bool, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFalse(a.t, value, msgAndArgs...)\n}\n\n// Falsef asserts that the specified value is false.\n//\n//\ta.Falsef(myBool, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Falsef(value bool, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFalsef(a.t, value, msg, args...)\n}\n\n// FileExists checks whether a file exists in the given path. It also fails if\n// the path points to a directory or there is an error when trying to check the file.\nfunc (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFileExists(a.t, path, msgAndArgs...)\n}\n\n// FileExistsf checks whether a file exists in the given path. It also fails if\n// the path points to a directory or there is an error when trying to check the file.\nfunc (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFileExistsf(a.t, path, msg, args...)\n}\n\n// Greater asserts that the first element is greater than the second\n//\n//\ta.Greater(2, 1)\n//\ta.Greater(float64(2), float64(1))\n//\ta.Greater(\"b\", \"a\")\nfunc (a *Assertions) Greater(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tGreater(a.t, e1, e2, msgAndArgs...)\n}\n\n// GreaterOrEqual asserts that the first element is greater than or equal to the second\n//\n//\ta.GreaterOrEqual(2, 1)\n//\ta.GreaterOrEqual(2, 2)\n//\ta.GreaterOrEqual(\"b\", \"a\")\n//\ta.GreaterOrEqual(\"b\", \"b\")\nfunc (a *Assertions) GreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tGreaterOrEqual(a.t, e1, e2, msgAndArgs...)\n}\n\n// GreaterOrEqualf asserts that the first element is greater than or equal to the second\n//\n//\ta.GreaterOrEqualf(2, 1, \"error message %s\", \"formatted\")\n//\ta.GreaterOrEqualf(2, 2, \"error message %s\", \"formatted\")\n//\ta.GreaterOrEqualf(\"b\", \"a\", \"error message %s\", \"formatted\")\n//\ta.GreaterOrEqualf(\"b\", \"b\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) GreaterOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tGreaterOrEqualf(a.t, e1, e2, msg, args...)\n}\n\n// Greaterf asserts that the first element is greater than the second\n//\n//\ta.Greaterf(2, 1, \"error message %s\", \"formatted\")\n//\ta.Greaterf(float64(2), float64(1), \"error message %s\", \"formatted\")\n//\ta.Greaterf(\"b\", \"a\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tGreaterf(a.t, e1, e2, msg, args...)\n}\n\n// HTTPBodyContains asserts that a specified handler returns a\n// body that contains a string.\n//\n//\ta.HTTPBodyContains(myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...)\n}\n\n// HTTPBodyContainsf asserts that a specified handler returns a\n// body that contains a string.\n//\n//\ta.HTTPBodyContainsf(myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\", \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...)\n}\n\n// HTTPBodyNotContains asserts that a specified handler returns a\n// body that does not contain a string.\n//\n//\ta.HTTPBodyNotContains(myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...)\n}\n\n// HTTPBodyNotContainsf asserts that a specified handler returns a\n// body that does not contain a string.\n//\n//\ta.HTTPBodyNotContainsf(myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\", \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...)\n}\n\n// HTTPError asserts that a specified handler returns an error status code.\n//\n//\ta.HTTPError(myHandler, \"POST\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPError(a.t, handler, method, url, values, msgAndArgs...)\n}\n\n// HTTPErrorf asserts that a specified handler returns an error status code.\n//\n//\ta.HTTPErrorf(myHandler, \"POST\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPErrorf(a.t, handler, method, url, values, msg, args...)\n}\n\n// HTTPRedirect asserts that a specified handler returns a redirect status code.\n//\n//\ta.HTTPRedirect(myHandler, \"GET\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPRedirect(a.t, handler, method, url, values, msgAndArgs...)\n}\n\n// HTTPRedirectf asserts that a specified handler returns a redirect status code.\n//\n//\ta.HTTPRedirectf(myHandler, \"GET\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPRedirectf(a.t, handler, method, url, values, msg, args...)\n}\n\n// HTTPStatusCode asserts that a specified handler returns a specified status code.\n//\n//\ta.HTTPStatusCode(myHandler, \"GET\", \"/notImplemented\", nil, 501)\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPStatusCode(a.t, handler, method, url, values, statuscode, msgAndArgs...)\n}\n\n// HTTPStatusCodef asserts that a specified handler returns a specified status code.\n//\n//\ta.HTTPStatusCodef(myHandler, \"GET\", \"/notImplemented\", nil, 501, \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPStatusCodef(a.t, handler, method, url, values, statuscode, msg, args...)\n}\n\n// HTTPSuccess asserts that a specified handler returns a success status code.\n//\n//\ta.HTTPSuccess(myHandler, \"POST\", \"http://www.google.com\", nil)\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPSuccess(a.t, handler, method, url, values, msgAndArgs...)\n}\n\n// HTTPSuccessf asserts that a specified handler returns a success status code.\n//\n//\ta.HTTPSuccessf(myHandler, \"POST\", \"http://www.google.com\", nil, \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPSuccessf(a.t, handler, method, url, values, msg, args...)\n}\n\n// Implements asserts that an object is implemented by the specified interface.\n//\n//\ta.Implements((*MyInterface)(nil), new(MyObject))\nfunc (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tImplements(a.t, interfaceObject, object, msgAndArgs...)\n}\n\n// Implementsf asserts that an object is implemented by the specified interface.\n//\n//\ta.Implementsf((*MyInterface)(nil), new(MyObject), \"error message %s\", \"formatted\")\nfunc (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tImplementsf(a.t, interfaceObject, object, msg, args...)\n}\n\n// InDelta asserts that the two numerals are within delta of each other.\n//\n//\ta.InDelta(math.Pi, 22/7.0, 0.01)\nfunc (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInDelta(a.t, expected, actual, delta, msgAndArgs...)\n}\n\n// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.\nfunc (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...)\n}\n\n// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.\nfunc (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInDeltaMapValuesf(a.t, expected, actual, delta, msg, args...)\n}\n\n// InDeltaSlice is the same as InDelta, except it compares two slices.\nfunc (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInDeltaSlice(a.t, expected, actual, delta, msgAndArgs...)\n}\n\n// InDeltaSlicef is the same as InDelta, except it compares two slices.\nfunc (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInDeltaSlicef(a.t, expected, actual, delta, msg, args...)\n}\n\n// InDeltaf asserts that the two numerals are within delta of each other.\n//\n//\ta.InDeltaf(math.Pi, 22/7.0, 0.01, \"error message %s\", \"formatted\")\nfunc (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInDeltaf(a.t, expected, actual, delta, msg, args...)\n}\n\n// InEpsilon asserts that expected and actual have a relative error less than epsilon\nfunc (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)\n}\n\n// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.\nfunc (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...)\n}\n\n// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.\nfunc (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...)\n}\n\n// InEpsilonf asserts that expected and actual have a relative error less than epsilon\nfunc (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInEpsilonf(a.t, expected, actual, epsilon, msg, args...)\n}\n\n// IsDecreasing asserts that the collection is decreasing\n//\n//\ta.IsDecreasing([]int{2, 1, 0})\n//\ta.IsDecreasing([]float{2, 1})\n//\ta.IsDecreasing([]string{\"b\", \"a\"})\nfunc (a *Assertions) IsDecreasing(object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsDecreasing(a.t, object, msgAndArgs...)\n}\n\n// IsDecreasingf asserts that the collection is decreasing\n//\n//\ta.IsDecreasingf([]int{2, 1, 0}, \"error message %s\", \"formatted\")\n//\ta.IsDecreasingf([]float{2, 1}, \"error message %s\", \"formatted\")\n//\ta.IsDecreasingf([]string{\"b\", \"a\"}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsDecreasingf(object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsDecreasingf(a.t, object, msg, args...)\n}\n\n// IsIncreasing asserts that the collection is increasing\n//\n//\ta.IsIncreasing([]int{1, 2, 3})\n//\ta.IsIncreasing([]float{1, 2})\n//\ta.IsIncreasing([]string{\"a\", \"b\"})\nfunc (a *Assertions) IsIncreasing(object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsIncreasing(a.t, object, msgAndArgs...)\n}\n\n// IsIncreasingf asserts that the collection is increasing\n//\n//\ta.IsIncreasingf([]int{1, 2, 3}, \"error message %s\", \"formatted\")\n//\ta.IsIncreasingf([]float{1, 2}, \"error message %s\", \"formatted\")\n//\ta.IsIncreasingf([]string{\"a\", \"b\"}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsIncreasingf(object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsIncreasingf(a.t, object, msg, args...)\n}\n\n// IsNonDecreasing asserts that the collection is not decreasing\n//\n//\ta.IsNonDecreasing([]int{1, 1, 2})\n//\ta.IsNonDecreasing([]float{1, 2})\n//\ta.IsNonDecreasing([]string{\"a\", \"b\"})\nfunc (a *Assertions) IsNonDecreasing(object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsNonDecreasing(a.t, object, msgAndArgs...)\n}\n\n// IsNonDecreasingf asserts that the collection is not decreasing\n//\n//\ta.IsNonDecreasingf([]int{1, 1, 2}, \"error message %s\", \"formatted\")\n//\ta.IsNonDecreasingf([]float{1, 2}, \"error message %s\", \"formatted\")\n//\ta.IsNonDecreasingf([]string{\"a\", \"b\"}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsNonDecreasingf(object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsNonDecreasingf(a.t, object, msg, args...)\n}\n\n// IsNonIncreasing asserts that the collection is not increasing\n//\n//\ta.IsNonIncreasing([]int{2, 1, 1})\n//\ta.IsNonIncreasing([]float{2, 1})\n//\ta.IsNonIncreasing([]string{\"b\", \"a\"})\nfunc (a *Assertions) IsNonIncreasing(object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsNonIncreasing(a.t, object, msgAndArgs...)\n}\n\n// IsNonIncreasingf asserts that the collection is not increasing\n//\n//\ta.IsNonIncreasingf([]int{2, 1, 1}, \"error message %s\", \"formatted\")\n//\ta.IsNonIncreasingf([]float{2, 1}, \"error message %s\", \"formatted\")\n//\ta.IsNonIncreasingf([]string{\"b\", \"a\"}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsNonIncreasingf(a.t, object, msg, args...)\n}\n\n// IsNotType asserts that the specified objects are not of the same type.\n//\n//\ta.IsNotType(&NotMyStruct{}, &MyStruct{})\nfunc (a *Assertions) IsNotType(theType interface{}, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsNotType(a.t, theType, object, msgAndArgs...)\n}\n\n// IsNotTypef asserts that the specified objects are not of the same type.\n//\n//\ta.IsNotTypef(&NotMyStruct{}, &MyStruct{}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsNotTypef(theType interface{}, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsNotTypef(a.t, theType, object, msg, args...)\n}\n\n// IsType asserts that the specified objects are of the same type.\n//\n//\ta.IsType(&MyStruct{}, &MyStruct{})\nfunc (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsType(a.t, expectedType, object, msgAndArgs...)\n}\n\n// IsTypef asserts that the specified objects are of the same type.\n//\n//\ta.IsTypef(&MyStruct{}, &MyStruct{}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsTypef(a.t, expectedType, object, msg, args...)\n}\n\n// JSONEq asserts that two JSON strings are equivalent.\n//\n//\ta.JSONEq(`{\"hello\": \"world\", \"foo\": \"bar\"}`, `{\"foo\": \"bar\", \"hello\": \"world\"}`)\nfunc (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tJSONEq(a.t, expected, actual, msgAndArgs...)\n}\n\n// JSONEqf asserts that two JSON strings are equivalent.\n//\n//\ta.JSONEqf(`{\"hello\": \"world\", \"foo\": \"bar\"}`, `{\"foo\": \"bar\", \"hello\": \"world\"}`, \"error message %s\", \"formatted\")\nfunc (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tJSONEqf(a.t, expected, actual, msg, args...)\n}\n\n// Len asserts that the specified object has specific length.\n// Len also fails if the object has a type that len() not accept.\n//\n//\ta.Len(mySlice, 3)\nfunc (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tLen(a.t, object, length, msgAndArgs...)\n}\n\n// Lenf asserts that the specified object has specific length.\n// Lenf also fails if the object has a type that len() not accept.\n//\n//\ta.Lenf(mySlice, 3, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tLenf(a.t, object, length, msg, args...)\n}\n\n// Less asserts that the first element is less than the second\n//\n//\ta.Less(1, 2)\n//\ta.Less(float64(1), float64(2))\n//\ta.Less(\"a\", \"b\")\nfunc (a *Assertions) Less(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tLess(a.t, e1, e2, msgAndArgs...)\n}\n\n// LessOrEqual asserts that the first element is less than or equal to the second\n//\n//\ta.LessOrEqual(1, 2)\n//\ta.LessOrEqual(2, 2)\n//\ta.LessOrEqual(\"a\", \"b\")\n//\ta.LessOrEqual(\"b\", \"b\")\nfunc (a *Assertions) LessOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tLessOrEqual(a.t, e1, e2, msgAndArgs...)\n}\n\n// LessOrEqualf asserts that the first element is less than or equal to the second\n//\n//\ta.LessOrEqualf(1, 2, \"error message %s\", \"formatted\")\n//\ta.LessOrEqualf(2, 2, \"error message %s\", \"formatted\")\n//\ta.LessOrEqualf(\"a\", \"b\", \"error message %s\", \"formatted\")\n//\ta.LessOrEqualf(\"b\", \"b\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) LessOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tLessOrEqualf(a.t, e1, e2, msg, args...)\n}\n\n// Lessf asserts that the first element is less than the second\n//\n//\ta.Lessf(1, 2, \"error message %s\", \"formatted\")\n//\ta.Lessf(float64(1), float64(2), \"error message %s\", \"formatted\")\n//\ta.Lessf(\"a\", \"b\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tLessf(a.t, e1, e2, msg, args...)\n}\n\n// Negative asserts that the specified element is negative\n//\n//\ta.Negative(-1)\n//\ta.Negative(-1.23)\nfunc (a *Assertions) Negative(e interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNegative(a.t, e, msgAndArgs...)\n}\n\n// Negativef asserts that the specified element is negative\n//\n//\ta.Negativef(-1, \"error message %s\", \"formatted\")\n//\ta.Negativef(-1.23, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Negativef(e interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNegativef(a.t, e, msg, args...)\n}\n\n// Never asserts that the given condition doesn't satisfy in waitFor time,\n// periodically checking the target function each tick.\n//\n//\ta.Never(func() bool { return false; }, time.Second, 10*time.Millisecond)\nfunc (a *Assertions) Never(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNever(a.t, condition, waitFor, tick, msgAndArgs...)\n}\n\n// Neverf asserts that the given condition doesn't satisfy in waitFor time,\n// periodically checking the target function each tick.\n//\n//\ta.Neverf(func() bool { return false; }, time.Second, 10*time.Millisecond, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Neverf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNeverf(a.t, condition, waitFor, tick, msg, args...)\n}\n\n// Nil asserts that the specified object is nil.\n//\n//\ta.Nil(err)\nfunc (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNil(a.t, object, msgAndArgs...)\n}\n\n// Nilf asserts that the specified object is nil.\n//\n//\ta.Nilf(err, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNilf(a.t, object, msg, args...)\n}\n\n// NoDirExists checks whether a directory does not exist in the given path.\n// It fails if the path points to an existing _directory_ only.\nfunc (a *Assertions) NoDirExists(path string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNoDirExists(a.t, path, msgAndArgs...)\n}\n\n// NoDirExistsf checks whether a directory does not exist in the given path.\n// It fails if the path points to an existing _directory_ only.\nfunc (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNoDirExistsf(a.t, path, msg, args...)\n}\n\n// NoError asserts that a function returned no error (i.e. `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if a.NoError(err) {\n//\t\t   assert.Equal(t, expectedObj, actualObj)\n//\t  }\nfunc (a *Assertions) NoError(err error, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNoError(a.t, err, msgAndArgs...)\n}\n\n// NoErrorf asserts that a function returned no error (i.e. `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if a.NoErrorf(err, \"error message %s\", \"formatted\") {\n//\t\t   assert.Equal(t, expectedObj, actualObj)\n//\t  }\nfunc (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNoErrorf(a.t, err, msg, args...)\n}\n\n// NoFileExists checks whether a file does not exist in a given path. It fails\n// if the path points to an existing _file_ only.\nfunc (a *Assertions) NoFileExists(path string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNoFileExists(a.t, path, msgAndArgs...)\n}\n\n// NoFileExistsf checks whether a file does not exist in a given path. It fails\n// if the path points to an existing _file_ only.\nfunc (a *Assertions) NoFileExistsf(path string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNoFileExistsf(a.t, path, msg, args...)\n}\n\n// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the\n// specified substring or element.\n//\n//\ta.NotContains(\"Hello World\", \"Earth\")\n//\ta.NotContains([\"Hello\", \"World\"], \"Earth\")\n//\ta.NotContains({\"Hello\": \"World\"}, \"Earth\")\nfunc (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotContains(a.t, s, contains, msgAndArgs...)\n}\n\n// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the\n// specified substring or element.\n//\n//\ta.NotContainsf(\"Hello World\", \"Earth\", \"error message %s\", \"formatted\")\n//\ta.NotContainsf([\"Hello\", \"World\"], \"Earth\", \"error message %s\", \"formatted\")\n//\ta.NotContainsf({\"Hello\": \"World\"}, \"Earth\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotContainsf(a.t, s, contains, msg, args...)\n}\n\n// NotElementsMatch asserts that the specified listA(array, slice...) is NOT equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should not match.\n// This is an inverse of ElementsMatch.\n//\n// a.NotElementsMatch([1, 1, 2, 3], [1, 1, 2, 3]) -> false\n//\n// a.NotElementsMatch([1, 1, 2, 3], [1, 2, 3]) -> true\n//\n// a.NotElementsMatch([1, 2, 3], [1, 2, 4]) -> true\nfunc (a *Assertions) NotElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotElementsMatch(a.t, listA, listB, msgAndArgs...)\n}\n\n// NotElementsMatchf asserts that the specified listA(array, slice...) is NOT equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should not match.\n// This is an inverse of ElementsMatch.\n//\n// a.NotElementsMatchf([1, 1, 2, 3], [1, 1, 2, 3], \"error message %s\", \"formatted\") -> false\n//\n// a.NotElementsMatchf([1, 1, 2, 3], [1, 2, 3], \"error message %s\", \"formatted\") -> true\n//\n// a.NotElementsMatchf([1, 2, 3], [1, 2, 4], \"error message %s\", \"formatted\") -> true\nfunc (a *Assertions) NotElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotElementsMatchf(a.t, listA, listB, msg, args...)\n}\n\n// NotEmpty asserts that the specified object is NOT [Empty].\n//\n//\tif a.NotEmpty(obj) {\n//\t  assert.Equal(t, \"two\", obj[1])\n//\t}\nfunc (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotEmpty(a.t, object, msgAndArgs...)\n}\n\n// NotEmptyf asserts that the specified object is NOT [Empty].\n//\n//\tif a.NotEmptyf(obj, \"error message %s\", \"formatted\") {\n//\t  assert.Equal(t, \"two\", obj[1])\n//\t}\nfunc (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotEmptyf(a.t, object, msg, args...)\n}\n\n// NotEqual asserts that the specified values are NOT equal.\n//\n//\ta.NotEqual(obj1, obj2)\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses).\nfunc (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotEqual(a.t, expected, actual, msgAndArgs...)\n}\n\n// NotEqualValues asserts that two objects are not equal even when converted to the same type\n//\n//\ta.NotEqualValues(obj1, obj2)\nfunc (a *Assertions) NotEqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotEqualValues(a.t, expected, actual, msgAndArgs...)\n}\n\n// NotEqualValuesf asserts that two objects are not equal even when converted to the same type\n//\n//\ta.NotEqualValuesf(obj1, obj2, \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotEqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotEqualValuesf(a.t, expected, actual, msg, args...)\n}\n\n// NotEqualf asserts that the specified values are NOT equal.\n//\n//\ta.NotEqualf(obj1, obj2, \"error message %s\", \"formatted\")\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses).\nfunc (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotEqualf(a.t, expected, actual, msg, args...)\n}\n\n// NotErrorAs asserts that none of the errors in err's chain matches target,\n// but if so, sets target to that error value.\nfunc (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotErrorAs(a.t, err, target, msgAndArgs...)\n}\n\n// NotErrorAsf asserts that none of the errors in err's chain matches target,\n// but if so, sets target to that error value.\nfunc (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotErrorAsf(a.t, err, target, msg, args...)\n}\n\n// NotErrorIs asserts that none of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotErrorIs(a.t, err, target, msgAndArgs...)\n}\n\n// NotErrorIsf asserts that none of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotErrorIsf(a.t, err, target, msg, args...)\n}\n\n// NotImplements asserts that an object does not implement the specified interface.\n//\n//\ta.NotImplements((*MyInterface)(nil), new(MyObject))\nfunc (a *Assertions) NotImplements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotImplements(a.t, interfaceObject, object, msgAndArgs...)\n}\n\n// NotImplementsf asserts that an object does not implement the specified interface.\n//\n//\ta.NotImplementsf((*MyInterface)(nil), new(MyObject), \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotImplementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotImplementsf(a.t, interfaceObject, object, msg, args...)\n}\n\n// NotNil asserts that the specified object is not nil.\n//\n//\ta.NotNil(err)\nfunc (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotNil(a.t, object, msgAndArgs...)\n}\n\n// NotNilf asserts that the specified object is not nil.\n//\n//\ta.NotNilf(err, \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotNilf(a.t, object, msg, args...)\n}\n\n// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.\n//\n//\ta.NotPanics(func(){ RemainCalm() })\nfunc (a *Assertions) NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotPanics(a.t, f, msgAndArgs...)\n}\n\n// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic.\n//\n//\ta.NotPanicsf(func(){ RemainCalm() }, \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotPanicsf(f assert.PanicTestFunc, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotPanicsf(a.t, f, msg, args...)\n}\n\n// NotRegexp asserts that a specified regexp does not match a string.\n//\n//\ta.NotRegexp(regexp.MustCompile(\"starts\"), \"it's starting\")\n//\ta.NotRegexp(\"^start\", \"it's not starting\")\nfunc (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotRegexp(a.t, rx, str, msgAndArgs...)\n}\n\n// NotRegexpf asserts that a specified regexp does not match a string.\n//\n//\ta.NotRegexpf(regexp.MustCompile(\"starts\"), \"it's starting\", \"error message %s\", \"formatted\")\n//\ta.NotRegexpf(\"^start\", \"it's not starting\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotRegexpf(a.t, rx, str, msg, args...)\n}\n\n// NotSame asserts that two pointers do not reference the same object.\n//\n//\ta.NotSame(ptr1, ptr2)\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc (a *Assertions) NotSame(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotSame(a.t, expected, actual, msgAndArgs...)\n}\n\n// NotSamef asserts that two pointers do not reference the same object.\n//\n//\ta.NotSamef(ptr1, ptr2, \"error message %s\", \"formatted\")\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotSamef(a.t, expected, actual, msg, args...)\n}\n\n// NotSubset asserts that the list (array, slice, or map) does NOT contain all\n// elements given in the subset (array, slice, or map).\n// Map elements are key-value pairs unless compared with an array or slice where\n// only the map key is evaluated.\n//\n//\ta.NotSubset([1, 3, 4], [1, 2])\n//\ta.NotSubset({\"x\": 1, \"y\": 2}, {\"z\": 3})\n//\ta.NotSubset([1, 3, 4], {1: \"one\", 2: \"two\"})\n//\ta.NotSubset({\"x\": 1, \"y\": 2}, [\"z\"])\nfunc (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotSubset(a.t, list, subset, msgAndArgs...)\n}\n\n// NotSubsetf asserts that the list (array, slice, or map) does NOT contain all\n// elements given in the subset (array, slice, or map).\n// Map elements are key-value pairs unless compared with an array or slice where\n// only the map key is evaluated.\n//\n//\ta.NotSubsetf([1, 3, 4], [1, 2], \"error message %s\", \"formatted\")\n//\ta.NotSubsetf({\"x\": 1, \"y\": 2}, {\"z\": 3}, \"error message %s\", \"formatted\")\n//\ta.NotSubsetf([1, 3, 4], {1: \"one\", 2: \"two\"}, \"error message %s\", \"formatted\")\n//\ta.NotSubsetf({\"x\": 1, \"y\": 2}, [\"z\"], \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotSubsetf(a.t, list, subset, msg, args...)\n}\n\n// NotZero asserts that i is not the zero value for its type.\nfunc (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotZero(a.t, i, msgAndArgs...)\n}\n\n// NotZerof asserts that i is not the zero value for its type.\nfunc (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotZerof(a.t, i, msg, args...)\n}\n\n// Panics asserts that the code inside the specified PanicTestFunc panics.\n//\n//\ta.Panics(func(){ GoCrazy() })\nfunc (a *Assertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tPanics(a.t, f, msgAndArgs...)\n}\n\n// PanicsWithError asserts that the code inside the specified PanicTestFunc\n// panics, and that the recovered panic value is an error that satisfies the\n// EqualError comparison.\n//\n//\ta.PanicsWithError(\"crazy error\", func(){ GoCrazy() })\nfunc (a *Assertions) PanicsWithError(errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tPanicsWithError(a.t, errString, f, msgAndArgs...)\n}\n\n// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc\n// panics, and that the recovered panic value is an error that satisfies the\n// EqualError comparison.\n//\n//\ta.PanicsWithErrorf(\"crazy error\", func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc (a *Assertions) PanicsWithErrorf(errString string, f assert.PanicTestFunc, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tPanicsWithErrorf(a.t, errString, f, msg, args...)\n}\n\n// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that\n// the recovered panic value equals the expected panic value.\n//\n//\ta.PanicsWithValue(\"crazy error\", func(){ GoCrazy() })\nfunc (a *Assertions) PanicsWithValue(expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tPanicsWithValue(a.t, expected, f, msgAndArgs...)\n}\n\n// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that\n// the recovered panic value equals the expected panic value.\n//\n//\ta.PanicsWithValuef(\"crazy error\", func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc (a *Assertions) PanicsWithValuef(expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tPanicsWithValuef(a.t, expected, f, msg, args...)\n}\n\n// Panicsf asserts that the code inside the specified PanicTestFunc panics.\n//\n//\ta.Panicsf(func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Panicsf(f assert.PanicTestFunc, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tPanicsf(a.t, f, msg, args...)\n}\n\n// Positive asserts that the specified element is positive\n//\n//\ta.Positive(1)\n//\ta.Positive(1.23)\nfunc (a *Assertions) Positive(e interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tPositive(a.t, e, msgAndArgs...)\n}\n\n// Positivef asserts that the specified element is positive\n//\n//\ta.Positivef(1, \"error message %s\", \"formatted\")\n//\ta.Positivef(1.23, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Positivef(e interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tPositivef(a.t, e, msg, args...)\n}\n\n// Regexp asserts that a specified regexp matches a string.\n//\n//\ta.Regexp(regexp.MustCompile(\"start\"), \"it's starting\")\n//\ta.Regexp(\"start...$\", \"it's not starting\")\nfunc (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tRegexp(a.t, rx, str, msgAndArgs...)\n}\n\n// Regexpf asserts that a specified regexp matches a string.\n//\n//\ta.Regexpf(regexp.MustCompile(\"start\"), \"it's starting\", \"error message %s\", \"formatted\")\n//\ta.Regexpf(\"start...$\", \"it's not starting\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tRegexpf(a.t, rx, str, msg, args...)\n}\n\n// Same asserts that two pointers reference the same object.\n//\n//\ta.Same(ptr1, ptr2)\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc (a *Assertions) Same(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tSame(a.t, expected, actual, msgAndArgs...)\n}\n\n// Samef asserts that two pointers reference the same object.\n//\n//\ta.Samef(ptr1, ptr2, \"error message %s\", \"formatted\")\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc (a *Assertions) Samef(expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tSamef(a.t, expected, actual, msg, args...)\n}\n\n// Subset asserts that the list (array, slice, or map) contains all elements\n// given in the subset (array, slice, or map).\n// Map elements are key-value pairs unless compared with an array or slice where\n// only the map key is evaluated.\n//\n//\ta.Subset([1, 2, 3], [1, 2])\n//\ta.Subset({\"x\": 1, \"y\": 2}, {\"x\": 1})\n//\ta.Subset([1, 2, 3], {1: \"one\", 2: \"two\"})\n//\ta.Subset({\"x\": 1, \"y\": 2}, [\"x\"])\nfunc (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tSubset(a.t, list, subset, msgAndArgs...)\n}\n\n// Subsetf asserts that the list (array, slice, or map) contains all elements\n// given in the subset (array, slice, or map).\n// Map elements are key-value pairs unless compared with an array or slice where\n// only the map key is evaluated.\n//\n//\ta.Subsetf([1, 2, 3], [1, 2], \"error message %s\", \"formatted\")\n//\ta.Subsetf({\"x\": 1, \"y\": 2}, {\"x\": 1}, \"error message %s\", \"formatted\")\n//\ta.Subsetf([1, 2, 3], {1: \"one\", 2: \"two\"}, \"error message %s\", \"formatted\")\n//\ta.Subsetf({\"x\": 1, \"y\": 2}, [\"x\"], \"error message %s\", \"formatted\")\nfunc (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tSubsetf(a.t, list, subset, msg, args...)\n}\n\n// True asserts that the specified value is true.\n//\n//\ta.True(myBool)\nfunc (a *Assertions) True(value bool, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tTrue(a.t, value, msgAndArgs...)\n}\n\n// Truef asserts that the specified value is true.\n//\n//\ta.Truef(myBool, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Truef(value bool, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tTruef(a.t, value, msg, args...)\n}\n\n// WithinDuration asserts that the two times are within duration delta of each other.\n//\n//\ta.WithinDuration(time.Now(), time.Now(), 10*time.Second)\nfunc (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tWithinDuration(a.t, expected, actual, delta, msgAndArgs...)\n}\n\n// WithinDurationf asserts that the two times are within duration delta of each other.\n//\n//\ta.WithinDurationf(time.Now(), time.Now(), 10*time.Second, \"error message %s\", \"formatted\")\nfunc (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tWithinDurationf(a.t, expected, actual, delta, msg, args...)\n}\n\n// WithinRange asserts that a time is within a time range (inclusive).\n//\n//\ta.WithinRange(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second))\nfunc (a *Assertions) WithinRange(actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tWithinRange(a.t, actual, start, end, msgAndArgs...)\n}\n\n// WithinRangef asserts that a time is within a time range (inclusive).\n//\n//\ta.WithinRangef(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), \"error message %s\", \"formatted\")\nfunc (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tWithinRangef(a.t, actual, start, end, msg, args...)\n}\n\n// YAMLEq asserts that two YAML strings are equivalent.\nfunc (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tYAMLEq(a.t, expected, actual, msgAndArgs...)\n}\n\n// YAMLEqf asserts that two YAML strings are equivalent.\nfunc (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tYAMLEqf(a.t, expected, actual, msg, args...)\n}\n\n// Zero asserts that i is the zero value for its type.\nfunc (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tZero(a.t, i, msgAndArgs...)\n}\n\n// Zerof asserts that i is the zero value for its type.\nfunc (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tZerof(a.t, i, msg, args...)\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/require/require_forward.go.tmpl",
    "content": "{{.CommentWithoutT \"a\"}}\nfunc (a *Assertions) {{.DocInfo.Name}}({{.Params}}) {\n\tif h, ok := a.t.(tHelper); ok { h.Helper() }\n\t{{.DocInfo.Name}}(a.t, {{.ForwardedParams}})\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/require/requirements.go",
    "content": "package require\n\n// TestingT is an interface wrapper around *testing.T\ntype TestingT interface {\n\tErrorf(format string, args ...interface{})\n\tFailNow()\n}\n\ntype tHelper = interface {\n\tHelper()\n}\n\n// ComparisonAssertionFunc is a common function prototype when comparing two values.  Can be useful\n// for table driven tests.\ntype ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{})\n\n// ValueAssertionFunc is a common function prototype when validating a single value.  Can be useful\n// for table driven tests.\ntype ValueAssertionFunc func(TestingT, interface{}, ...interface{})\n\n// BoolAssertionFunc is a common function prototype when validating a bool value.  Can be useful\n// for table driven tests.\ntype BoolAssertionFunc func(TestingT, bool, ...interface{})\n\n// ErrorAssertionFunc is a common function prototype when validating an error value.  Can be useful\n// for table driven tests.\ntype ErrorAssertionFunc func(TestingT, error, ...interface{})\n\n//go:generate sh -c \"cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=require -template=require.go.tmpl -include-format-funcs\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/CONTRIBUTING.md",
    "content": "# Contributing to go.opentelemetry.io/auto/sdk\n\nThe `go.opentelemetry.io/auto/sdk` module is a purpose built OpenTelemetry SDK.\nIt is designed to be:\n\n0. An OpenTelemetry compliant SDK\n1. Instrumented by auto-instrumentation (serializable into OTLP JSON)\n2. Lightweight\n3. User-friendly\n\nThese design choices are listed in the order of their importance.\n\nThe primary design goal of this module is to be an OpenTelemetry SDK.\nThis means that it needs to implement the Go APIs found in `go.opentelemetry.io/otel`.\n\nHaving met the requirement of SDK compliance, this module needs to provide code that the `go.opentelemetry.io/auto` module can instrument.\nThe chosen approach to meet this goal is to ensure the telemetry from the SDK is serializable into JSON encoded OTLP.\nThis ensures then that the serialized form is compatible with other OpenTelemetry systems, and the auto-instrumentation can use these systems to deserialize any telemetry it is sent.\n\nOutside of these first two goals, the intended use becomes relevant.\nThis package is intended to be used in the `go.opentelemetry.io/otel` global API as a default when the auto-instrumentation is running.\nBecause of this, this package needs to not add unnecessary dependencies to that API.\nIdeally, it adds none.\nIt also needs to operate efficiently.\n\nFinally, this module is designed to be user-friendly to Go development.\nIt hides complexity in order to provide simpler APIs when the previous goals can all still be met.\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/VERSIONING.md",
    "content": "# Versioning\n\nThis document describes the versioning policy for this module.\nThis policy is designed so the following goals can be achieved.\n\n**Users are provided a codebase of value that is stable and secure.**\n\n## Policy\n\n* Versioning of this module will be idiomatic of a Go project using [Go modules](https://github.com/golang/go/wiki/Modules).\n  * [Semantic import versioning](https://github.com/golang/go/wiki/Modules#semantic-import-versioning) will be used.\n    * Versions will comply with [semver 2.0](https://semver.org/spec/v2.0.0.html).\n    * Any `v2` or higher version of this module will be included as a `/vN` at the end of the module path used in `go.mod` files and in the package import path.\n\n* GitHub releases will be made for all releases.\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n/*\nPackage sdk provides an auto-instrumentable OpenTelemetry SDK.\n\nAn [go.opentelemetry.io/auto.Instrumentation] can be configured to target the\nprocess running this SDK. In that case, all telemetry the SDK produces will be\nprocessed and handled by that [go.opentelemetry.io/auto.Instrumentation].\n\nBy default, if there is no [go.opentelemetry.io/auto.Instrumentation] set to\nauto-instrument the SDK, the SDK will not generate any telemetry.\n*/\npackage sdk\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/attr.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry\n\n// Attr is a key-value pair.\ntype Attr struct {\n\tKey   string `json:\"key,omitempty\"`\n\tValue Value  `json:\"value,omitempty\"`\n}\n\n// String returns an Attr for a string value.\nfunc String(key, value string) Attr {\n\treturn Attr{key, StringValue(value)}\n}\n\n// Int64 returns an Attr for an int64 value.\nfunc Int64(key string, value int64) Attr {\n\treturn Attr{key, Int64Value(value)}\n}\n\n// Int returns an Attr for an int value.\nfunc Int(key string, value int) Attr {\n\treturn Int64(key, int64(value))\n}\n\n// Float64 returns an Attr for a float64 value.\nfunc Float64(key string, value float64) Attr {\n\treturn Attr{key, Float64Value(value)}\n}\n\n// Bool returns an Attr for a bool value.\nfunc Bool(key string, value bool) Attr {\n\treturn Attr{key, BoolValue(value)}\n}\n\n// Bytes returns an Attr for a []byte value.\n// The passed slice must not be changed after it is passed.\nfunc Bytes(key string, value []byte) Attr {\n\treturn Attr{key, BytesValue(value)}\n}\n\n// Slice returns an Attr for a []Value value.\n// The passed slice must not be changed after it is passed.\nfunc Slice(key string, value ...Value) Attr {\n\treturn Attr{key, SliceValue(value...)}\n}\n\n// Map returns an Attr for a map value.\n// The passed slice must not be changed after it is passed.\nfunc Map(key string, value ...Attr) Attr {\n\treturn Attr{key, MapValue(value...)}\n}\n\n// Equal returns if a is equal to b.\nfunc (a Attr) Equal(b Attr) bool {\n\treturn a.Key == b.Key && a.Value.Equal(b.Value)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n/*\nPackage telemetry provides a lightweight representations of OpenTelemetry\ntelemetry that is compatible with the OTLP JSON protobuf encoding.\n*/\npackage telemetry\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/id.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry\n\nimport (\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n)\n\nconst (\n\ttraceIDSize = 16\n\tspanIDSize  = 8\n)\n\n// TraceID is a custom data type that is used for all trace IDs.\ntype TraceID [traceIDSize]byte\n\n// String returns the hex string representation form of a TraceID.\nfunc (tid TraceID) String() string {\n\treturn hex.EncodeToString(tid[:])\n}\n\n// IsEmpty returns false if id contains at least one non-zero byte.\nfunc (tid TraceID) IsEmpty() bool {\n\treturn tid == [traceIDSize]byte{}\n}\n\n// MarshalJSON converts the trace ID into a hex string enclosed in quotes.\nfunc (tid TraceID) MarshalJSON() ([]byte, error) {\n\tif tid.IsEmpty() {\n\t\treturn []byte(`\"\"`), nil\n\t}\n\treturn marshalJSON(tid[:])\n}\n\n// UnmarshalJSON inflates the trace ID from hex string, possibly enclosed in\n// quotes.\nfunc (tid *TraceID) UnmarshalJSON(data []byte) error {\n\t*tid = [traceIDSize]byte{}\n\treturn unmarshalJSON(tid[:], data)\n}\n\n// SpanID is a custom data type that is used for all span IDs.\ntype SpanID [spanIDSize]byte\n\n// String returns the hex string representation form of a SpanID.\nfunc (sid SpanID) String() string {\n\treturn hex.EncodeToString(sid[:])\n}\n\n// IsEmpty returns true if the span ID contains at least one non-zero byte.\nfunc (sid SpanID) IsEmpty() bool {\n\treturn sid == [spanIDSize]byte{}\n}\n\n// MarshalJSON converts span ID into a hex string enclosed in quotes.\nfunc (sid SpanID) MarshalJSON() ([]byte, error) {\n\tif sid.IsEmpty() {\n\t\treturn []byte(`\"\"`), nil\n\t}\n\treturn marshalJSON(sid[:])\n}\n\n// UnmarshalJSON decodes span ID from hex string, possibly enclosed in quotes.\nfunc (sid *SpanID) UnmarshalJSON(data []byte) error {\n\t*sid = [spanIDSize]byte{}\n\treturn unmarshalJSON(sid[:], data)\n}\n\n// marshalJSON converts id into a hex string enclosed in quotes.\nfunc marshalJSON(id []byte) ([]byte, error) {\n\t// Plus 2 quote chars at the start and end.\n\thexLen := hex.EncodedLen(len(id)) + 2\n\n\tb := make([]byte, hexLen)\n\thex.Encode(b[1:hexLen-1], id)\n\tb[0], b[hexLen-1] = '\"', '\"'\n\n\treturn b, nil\n}\n\n// unmarshalJSON inflates trace id from hex string, possibly enclosed in quotes.\nfunc unmarshalJSON(dst, src []byte) error {\n\tif l := len(src); l >= 2 && src[0] == '\"' && src[l-1] == '\"' {\n\t\tsrc = src[1 : l-1]\n\t}\n\tnLen := len(src)\n\tif nLen == 0 {\n\t\treturn nil\n\t}\n\n\tif len(dst) != hex.DecodedLen(nLen) {\n\t\treturn errors.New(\"invalid length for ID\")\n\t}\n\n\t_, err := hex.Decode(dst, src)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot unmarshal ID from string '%s': %w\", string(src), err)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/number.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry\n\nimport (\n\t\"encoding/json\"\n\t\"strconv\"\n)\n\n// protoInt64 represents the protobuf encoding of integers which can be either\n// strings or integers.\ntype protoInt64 int64\n\n// Int64 returns the protoInt64 as an int64.\nfunc (i *protoInt64) Int64() int64 { return int64(*i) }\n\n// UnmarshalJSON decodes both strings and integers.\nfunc (i *protoInt64) UnmarshalJSON(data []byte) error {\n\tif data[0] == '\"' {\n\t\tvar str string\n\t\tif err := json.Unmarshal(data, &str); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tparsedInt, err := strconv.ParseInt(str, 10, 64)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t*i = protoInt64(parsedInt)\n\t} else {\n\t\tvar parsedInt int64\n\t\tif err := json.Unmarshal(data, &parsedInt); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t*i = protoInt64(parsedInt)\n\t}\n\treturn nil\n}\n\n// protoUint64 represents the protobuf encoding of integers which can be either\n// strings or integers.\ntype protoUint64 uint64\n\n// Uint64 returns the protoUint64 as a uint64.\nfunc (i *protoUint64) Uint64() uint64 { return uint64(*i) }\n\n// UnmarshalJSON decodes both strings and integers.\nfunc (i *protoUint64) UnmarshalJSON(data []byte) error {\n\tif data[0] == '\"' {\n\t\tvar str string\n\t\tif err := json.Unmarshal(data, &str); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tparsedUint, err := strconv.ParseUint(str, 10, 64)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t*i = protoUint64(parsedUint)\n\t} else {\n\t\tvar parsedUint uint64\n\t\tif err := json.Unmarshal(data, &parsedUint); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t*i = protoUint64(parsedUint)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/resource.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\n// Resource information.\ntype Resource struct {\n\t// Attrs are the set of attributes that describe the resource. Attribute\n\t// keys MUST be unique (it is not allowed to have more than one attribute\n\t// with the same key).\n\tAttrs []Attr `json:\"attributes,omitempty\"`\n\t// DroppedAttrs is the number of dropped attributes. If the value\n\t// is 0, then no attributes were dropped.\n\tDroppedAttrs uint32 `json:\"droppedAttributesCount,omitempty\"`\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into r.\nfunc (r *Resource) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid Resource type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid Resource field: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"attributes\":\n\t\t\terr = decoder.Decode(&r.Attrs)\n\t\tcase \"droppedAttributesCount\", \"dropped_attributes_count\":\n\t\t\terr = decoder.Decode(&r.DroppedAttrs)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/scope.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\n// Scope is the identifying values of the instrumentation scope.\ntype Scope struct {\n\tName         string `json:\"name,omitempty\"`\n\tVersion      string `json:\"version,omitempty\"`\n\tAttrs        []Attr `json:\"attributes,omitempty\"`\n\tDroppedAttrs uint32 `json:\"droppedAttributesCount,omitempty\"`\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into r.\nfunc (s *Scope) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid Scope type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid Scope field: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"name\":\n\t\t\terr = decoder.Decode(&s.Name)\n\t\tcase \"version\":\n\t\t\terr = decoder.Decode(&s.Version)\n\t\tcase \"attributes\":\n\t\t\terr = decoder.Decode(&s.Attrs)\n\t\tcase \"droppedAttributesCount\", \"dropped_attributes_count\":\n\t\t\terr = decoder.Decode(&s.DroppedAttrs)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/span.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry\n\nimport (\n\t\"bytes\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"time\"\n)\n\n// A Span represents a single operation performed by a single component of the\n// system.\ntype Span struct {\n\t// A unique identifier for a trace. All spans from the same trace share\n\t// the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes OR\n\t// of length other than 16 bytes is considered invalid (empty string in OTLP/JSON\n\t// is zero-length and thus is also invalid).\n\t//\n\t// This field is required.\n\tTraceID TraceID `json:\"traceId,omitempty\"`\n\t// A unique identifier for a span within a trace, assigned when the span\n\t// is created. The ID is an 8-byte array. An ID with all zeroes OR of length\n\t// other than 8 bytes is considered invalid (empty string in OTLP/JSON\n\t// is zero-length and thus is also invalid).\n\t//\n\t// This field is required.\n\tSpanID SpanID `json:\"spanId,omitempty\"`\n\t// trace_state conveys information about request position in multiple distributed tracing graphs.\n\t// It is a trace_state in w3c-trace-context format: https://www.w3.org/TR/trace-context/#tracestate-header\n\t// See also https://github.com/w3c/distributed-tracing for more details about this field.\n\tTraceState string `json:\"traceState,omitempty\"`\n\t// The `span_id` of this span's parent span. If this is a root span, then this\n\t// field must be empty. The ID is an 8-byte array.\n\tParentSpanID SpanID `json:\"parentSpanId,omitempty\"`\n\t// Flags, a bit field.\n\t//\n\t// Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C Trace\n\t// Context specification. To read the 8-bit W3C trace flag, use\n\t// `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`.\n\t//\n\t// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions.\n\t//\n\t// Bits 8 and 9 represent the 3 states of whether a span's parent\n\t// is remote. The states are (unknown, is not remote, is remote).\n\t// To read whether the value is known, use `(flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`.\n\t// To read whether the span is remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`.\n\t//\n\t// When creating span messages, if the message is logically forwarded from another source\n\t// with an equivalent flags fields (i.e., usually another OTLP span message), the field SHOULD\n\t// be copied as-is. If creating from a source that does not have an equivalent flags field\n\t// (such as a runtime representation of an OpenTelemetry span), the high 22 bits MUST\n\t// be set to zero.\n\t// Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero.\n\t//\n\t// [Optional].\n\tFlags uint32 `json:\"flags,omitempty\"`\n\t// A description of the span's operation.\n\t//\n\t// For example, the name can be a qualified method name or a file name\n\t// and a line number where the operation is called. A best practice is to use\n\t// the same display name at the same call point in an application.\n\t// This makes it easier to correlate spans in different traces.\n\t//\n\t// This field is semantically required to be set to non-empty string.\n\t// Empty value is equivalent to an unknown span name.\n\t//\n\t// This field is required.\n\tName string `json:\"name\"`\n\t// Distinguishes between spans generated in a particular context. For example,\n\t// two spans with the same name may be distinguished using `CLIENT` (caller)\n\t// and `SERVER` (callee) to identify queueing latency associated with the span.\n\tKind SpanKind `json:\"kind,omitempty\"`\n\t// start_time_unix_nano is the start time of the span. On the client side, this is the time\n\t// kept by the local machine where the span execution starts. On the server side, this\n\t// is the time when the server's application handler starts running.\n\t// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970.\n\t//\n\t// This field is semantically required and it is expected that end_time >= start_time.\n\tStartTime time.Time `json:\"startTimeUnixNano,omitempty\"`\n\t// end_time_unix_nano is the end time of the span. On the client side, this is the time\n\t// kept by the local machine where the span execution ends. On the server side, this\n\t// is the time when the server application handler stops running.\n\t// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970.\n\t//\n\t// This field is semantically required and it is expected that end_time >= start_time.\n\tEndTime time.Time `json:\"endTimeUnixNano,omitempty\"`\n\t// attributes is a collection of key/value pairs. Note, global attributes\n\t// like server name can be set using the resource API. Examples of attributes:\n\t//\n\t//     \"/http/user_agent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36\"\n\t//     \"/http/server_latency\": 300\n\t//     \"example.com/myattribute\": true\n\t//     \"example.com/score\": 10.239\n\t//\n\t// The OpenTelemetry API specification further restricts the allowed value types:\n\t// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute\n\t// Attribute keys MUST be unique (it is not allowed to have more than one\n\t// attribute with the same key).\n\tAttrs []Attr `json:\"attributes,omitempty\"`\n\t// dropped_attributes_count is the number of attributes that were discarded. Attributes\n\t// can be discarded because their keys are too long or because there are too many\n\t// attributes. If this value is 0, then no attributes were dropped.\n\tDroppedAttrs uint32 `json:\"droppedAttributesCount,omitempty\"`\n\t// events is a collection of Event items.\n\tEvents []*SpanEvent `json:\"events,omitempty\"`\n\t// dropped_events_count is the number of dropped events. If the value is 0, then no\n\t// events were dropped.\n\tDroppedEvents uint32 `json:\"droppedEventsCount,omitempty\"`\n\t// links is a collection of Links, which are references from this span to a span\n\t// in the same or different trace.\n\tLinks []*SpanLink `json:\"links,omitempty\"`\n\t// dropped_links_count is the number of dropped links after the maximum size was\n\t// enforced. If this value is 0, then no links were dropped.\n\tDroppedLinks uint32 `json:\"droppedLinksCount,omitempty\"`\n\t// An optional final status for this span. Semantically when Status isn't set, it means\n\t// span's status code is unset, i.e. assume STATUS_CODE_UNSET (code = 0).\n\tStatus *Status `json:\"status,omitempty\"`\n}\n\n// MarshalJSON encodes s into OTLP formatted JSON.\nfunc (s Span) MarshalJSON() ([]byte, error) {\n\tstartT := s.StartTime.UnixNano()\n\tif s.StartTime.IsZero() || startT < 0 {\n\t\tstartT = 0\n\t}\n\n\tendT := s.EndTime.UnixNano()\n\tif s.EndTime.IsZero() || endT < 0 {\n\t\tendT = 0\n\t}\n\n\t// Override non-empty default SpanID marshal and omitempty.\n\tvar parentSpanId string\n\tif !s.ParentSpanID.IsEmpty() {\n\t\tb := make([]byte, hex.EncodedLen(spanIDSize))\n\t\thex.Encode(b, s.ParentSpanID[:])\n\t\tparentSpanId = string(b)\n\t}\n\n\ttype Alias Span\n\treturn json.Marshal(struct {\n\t\tAlias\n\t\tParentSpanID string `json:\"parentSpanId,omitempty\"`\n\t\tStartTime    uint64 `json:\"startTimeUnixNano,omitempty\"`\n\t\tEndTime      uint64 `json:\"endTimeUnixNano,omitempty\"`\n\t}{\n\t\tAlias:        Alias(s),\n\t\tParentSpanID: parentSpanId,\n\t\tStartTime:    uint64(startT), // nolint:gosec  // >0 checked above.\n\t\tEndTime:      uint64(endT),   // nolint:gosec  // >0 checked above.\n\t})\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into s.\nfunc (s *Span) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid Span type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid Span field: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"traceId\", \"trace_id\":\n\t\t\terr = decoder.Decode(&s.TraceID)\n\t\tcase \"spanId\", \"span_id\":\n\t\t\terr = decoder.Decode(&s.SpanID)\n\t\tcase \"traceState\", \"trace_state\":\n\t\t\terr = decoder.Decode(&s.TraceState)\n\t\tcase \"parentSpanId\", \"parent_span_id\":\n\t\t\terr = decoder.Decode(&s.ParentSpanID)\n\t\tcase \"flags\":\n\t\t\terr = decoder.Decode(&s.Flags)\n\t\tcase \"name\":\n\t\t\terr = decoder.Decode(&s.Name)\n\t\tcase \"kind\":\n\t\t\terr = decoder.Decode(&s.Kind)\n\t\tcase \"startTimeUnixNano\", \"start_time_unix_nano\":\n\t\t\tvar val protoUint64\n\t\t\terr = decoder.Decode(&val)\n\t\t\tv := int64(min(val.Uint64(), math.MaxInt64)) //nolint:gosec  // Overflow checked.\n\t\t\ts.StartTime = time.Unix(0, v)\n\t\tcase \"endTimeUnixNano\", \"end_time_unix_nano\":\n\t\t\tvar val protoUint64\n\t\t\terr = decoder.Decode(&val)\n\t\t\tv := int64(min(val.Uint64(), math.MaxInt64)) //nolint:gosec  // Overflow checked.\n\t\t\ts.EndTime = time.Unix(0, v)\n\t\tcase \"attributes\":\n\t\t\terr = decoder.Decode(&s.Attrs)\n\t\tcase \"droppedAttributesCount\", \"dropped_attributes_count\":\n\t\t\terr = decoder.Decode(&s.DroppedAttrs)\n\t\tcase \"events\":\n\t\t\terr = decoder.Decode(&s.Events)\n\t\tcase \"droppedEventsCount\", \"dropped_events_count\":\n\t\t\terr = decoder.Decode(&s.DroppedEvents)\n\t\tcase \"links\":\n\t\t\terr = decoder.Decode(&s.Links)\n\t\tcase \"droppedLinksCount\", \"dropped_links_count\":\n\t\t\terr = decoder.Decode(&s.DroppedLinks)\n\t\tcase \"status\":\n\t\t\terr = decoder.Decode(&s.Status)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// SpanFlags represents constants used to interpret the\n// Span.flags field, which is protobuf 'fixed32' type and is to\n// be used as bit-fields. Each non-zero value defined in this enum is\n// a bit-mask.  To extract the bit-field, for example, use an\n// expression like:\n//\n//\t(span.flags & SPAN_FLAGS_TRACE_FLAGS_MASK)\n//\n// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions.\n//\n// Note that Span flags were introduced in version 1.1 of the\n// OpenTelemetry protocol.  Older Span producers do not set this\n// field, consequently consumers should not rely on the absence of a\n// particular flag bit to indicate the presence of a particular feature.\ntype SpanFlags int32\n\nconst (\n\t// SpanFlagsTraceFlagsMask is a mask for trace-flags.\n\t//\n\t// Bits 0-7 are used for trace flags.\n\tSpanFlagsTraceFlagsMask SpanFlags = 255\n\t// SpanFlagsContextHasIsRemoteMask is a mask for HAS_IS_REMOTE status.\n\t//\n\t// Bits 8 and 9 are used to indicate that the parent span or link span is\n\t// remote. Bit 8 (`HAS_IS_REMOTE`) indicates whether the value is known.\n\tSpanFlagsContextHasIsRemoteMask SpanFlags = 256\n\t// SpanFlagsContextIsRemoteMask is a mask for IS_REMOTE status.\n\t//\n\t// Bits 8 and 9 are used to indicate that the parent span or link span is\n\t// remote. Bit 9 (`IS_REMOTE`) indicates whether the span or link is\n\t// remote.\n\tSpanFlagsContextIsRemoteMask SpanFlags = 512\n)\n\n// SpanKind is the type of span. Can be used to specify additional relationships between spans\n// in addition to a parent/child relationship.\ntype SpanKind int32\n\nconst (\n\t// SpanKindInternal indicates that the span represents an internal\n\t// operation within an application, as opposed to an operation happening at\n\t// the boundaries.\n\tSpanKindInternal SpanKind = 1\n\t// SpanKindServer indicates that the span covers server-side handling of an\n\t// RPC or other remote network request.\n\tSpanKindServer SpanKind = 2\n\t// SpanKindClient indicates that the span describes a request to some\n\t// remote service.\n\tSpanKindClient SpanKind = 3\n\t// SpanKindProducer indicates that the span describes a producer sending a\n\t// message to a broker. Unlike SpanKindClient and SpanKindServer, there is\n\t// often no direct critical path latency relationship between producer and\n\t// consumer spans. A SpanKindProducer span ends when the message was\n\t// accepted by the broker while the logical processing of the message might\n\t// span a much longer time.\n\tSpanKindProducer SpanKind = 4\n\t// SpanKindConsumer indicates that the span describes a consumer receiving\n\t// a message from a broker. Like SpanKindProducer, there is often no direct\n\t// critical path latency relationship between producer and consumer spans.\n\tSpanKindConsumer SpanKind = 5\n)\n\n// SpanEvent is a time-stamped annotation of the span, consisting of user-supplied\n// text description and key-value pairs.\ntype SpanEvent struct {\n\t// time_unix_nano is the time the event occurred.\n\tTime time.Time `json:\"timeUnixNano,omitempty\"`\n\t// name of the event.\n\t// This field is semantically required to be set to non-empty string.\n\tName string `json:\"name,omitempty\"`\n\t// attributes is a collection of attribute key/value pairs on the event.\n\t// Attribute keys MUST be unique (it is not allowed to have more than one\n\t// attribute with the same key).\n\tAttrs []Attr `json:\"attributes,omitempty\"`\n\t// dropped_attributes_count is the number of dropped attributes. If the value is 0,\n\t// then no attributes were dropped.\n\tDroppedAttrs uint32 `json:\"droppedAttributesCount,omitempty\"`\n}\n\n// MarshalJSON encodes e into OTLP formatted JSON.\nfunc (e SpanEvent) MarshalJSON() ([]byte, error) {\n\tt := e.Time.UnixNano()\n\tif e.Time.IsZero() || t < 0 {\n\t\tt = 0\n\t}\n\n\ttype Alias SpanEvent\n\treturn json.Marshal(struct {\n\t\tAlias\n\t\tTime uint64 `json:\"timeUnixNano,omitempty\"`\n\t}{\n\t\tAlias: Alias(e),\n\t\tTime:  uint64(t), //nolint:gosec  // >0 checked above\n\t})\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into se.\nfunc (se *SpanEvent) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid SpanEvent type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid SpanEvent field: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"timeUnixNano\", \"time_unix_nano\":\n\t\t\tvar val protoUint64\n\t\t\terr = decoder.Decode(&val)\n\t\t\tv := int64(min(val.Uint64(), math.MaxInt64)) //nolint:gosec  // Overflow checked.\n\t\t\tse.Time = time.Unix(0, v)\n\t\tcase \"name\":\n\t\t\terr = decoder.Decode(&se.Name)\n\t\tcase \"attributes\":\n\t\t\terr = decoder.Decode(&se.Attrs)\n\t\tcase \"droppedAttributesCount\", \"dropped_attributes_count\":\n\t\t\terr = decoder.Decode(&se.DroppedAttrs)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// SpanLink is a reference from the current span to another span in the same\n// trace or in a different trace. For example, this can be used in batching\n// operations, where a single batch handler processes multiple requests from\n// different traces or when the handler receives a request from a different\n// project.\ntype SpanLink struct {\n\t// A unique identifier of a trace that this linked span is part of. The ID is a\n\t// 16-byte array.\n\tTraceID TraceID `json:\"traceId,omitempty\"`\n\t// A unique identifier for the linked span. The ID is an 8-byte array.\n\tSpanID SpanID `json:\"spanId,omitempty\"`\n\t// The trace_state associated with the link.\n\tTraceState string `json:\"traceState,omitempty\"`\n\t// attributes is a collection of attribute key/value pairs on the link.\n\t// Attribute keys MUST be unique (it is not allowed to have more than one\n\t// attribute with the same key).\n\tAttrs []Attr `json:\"attributes,omitempty\"`\n\t// dropped_attributes_count is the number of dropped attributes. If the value is 0,\n\t// then no attributes were dropped.\n\tDroppedAttrs uint32 `json:\"droppedAttributesCount,omitempty\"`\n\t// Flags, a bit field.\n\t//\n\t// Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C Trace\n\t// Context specification. To read the 8-bit W3C trace flag, use\n\t// `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`.\n\t//\n\t// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions.\n\t//\n\t// Bits 8 and 9 represent the 3 states of whether the link is remote.\n\t// The states are (unknown, is not remote, is remote).\n\t// To read whether the value is known, use `(flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`.\n\t// To read whether the link is remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`.\n\t//\n\t// Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero.\n\t// When creating new spans, bits 10-31 (most-significant 22-bits) MUST be zero.\n\t//\n\t// [Optional].\n\tFlags uint32 `json:\"flags,omitempty\"`\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into sl.\nfunc (sl *SpanLink) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid SpanLink type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid SpanLink field: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"traceId\", \"trace_id\":\n\t\t\terr = decoder.Decode(&sl.TraceID)\n\t\tcase \"spanId\", \"span_id\":\n\t\t\terr = decoder.Decode(&sl.SpanID)\n\t\tcase \"traceState\", \"trace_state\":\n\t\t\terr = decoder.Decode(&sl.TraceState)\n\t\tcase \"attributes\":\n\t\t\terr = decoder.Decode(&sl.Attrs)\n\t\tcase \"droppedAttributesCount\", \"dropped_attributes_count\":\n\t\t\terr = decoder.Decode(&sl.DroppedAttrs)\n\t\tcase \"flags\":\n\t\t\terr = decoder.Decode(&sl.Flags)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/status.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry\n\n// StatusCode is the status of a Span.\n//\n// For the semantics of status codes see\n// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status\ntype StatusCode int32\n\nconst (\n\t// StatusCodeUnset is the default status.\n\tStatusCodeUnset StatusCode = 0\n\t// StatusCodeOK is used when the Span has been validated by an Application\n\t// developer or Operator to have completed successfully.\n\tStatusCodeOK StatusCode = 1\n\t// StatusCodeError is used when the Span contains an error.\n\tStatusCodeError StatusCode = 2\n)\n\nvar statusCodeStrings = []string{\n\t\"Unset\",\n\t\"OK\",\n\t\"Error\",\n}\n\nfunc (s StatusCode) String() string {\n\tif s >= 0 && int(s) < len(statusCodeStrings) {\n\t\treturn statusCodeStrings[s]\n\t}\n\treturn \"<unknown telemetry.StatusCode>\"\n}\n\n// The Status type defines a logical error model that is suitable for different\n// programming environments, including REST APIs and RPC APIs.\ntype Status struct {\n\t// A developer-facing human readable error message.\n\tMessage string `json:\"message,omitempty\"`\n\t// The status code.\n\tCode StatusCode `json:\"code,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/traces.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\n// Traces represents the traces data that can be stored in a persistent storage,\n// OR can be embedded by other protocols that transfer OTLP traces data but do\n// not implement the OTLP protocol.\n//\n// The main difference between this message and collector protocol is that\n// in this message there will not be any \"control\" or \"metadata\" specific to\n// OTLP protocol.\n//\n// When new fields are added into this message, the OTLP request MUST be updated\n// as well.\ntype Traces struct {\n\t// An array of ResourceSpans.\n\t// For data coming from a single resource this array will typically contain\n\t// one element. Intermediary nodes that receive data from multiple origins\n\t// typically batch the data before forwarding further and in that case this\n\t// array will contain multiple elements.\n\tResourceSpans []*ResourceSpans `json:\"resourceSpans,omitempty\"`\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into td.\nfunc (td *Traces) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid TracesData type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid TracesData field: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"resourceSpans\", \"resource_spans\":\n\t\t\terr = decoder.Decode(&td.ResourceSpans)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// ResourceSpans is a collection of ScopeSpans from a Resource.\ntype ResourceSpans struct {\n\t// The resource for the spans in this message.\n\t// If this field is not set then no resource info is known.\n\tResource Resource `json:\"resource\"`\n\t// A list of ScopeSpans that originate from a resource.\n\tScopeSpans []*ScopeSpans `json:\"scopeSpans,omitempty\"`\n\t// This schema_url applies to the data in the \"resource\" field. It does not apply\n\t// to the data in the \"scope_spans\" field which have their own schema_url field.\n\tSchemaURL string `json:\"schemaUrl,omitempty\"`\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into rs.\nfunc (rs *ResourceSpans) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid ResourceSpans type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid ResourceSpans field: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"resource\":\n\t\t\terr = decoder.Decode(&rs.Resource)\n\t\tcase \"scopeSpans\", \"scope_spans\":\n\t\t\terr = decoder.Decode(&rs.ScopeSpans)\n\t\tcase \"schemaUrl\", \"schema_url\":\n\t\t\terr = decoder.Decode(&rs.SchemaURL)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// ScopeSpans is a collection of Spans produced by an InstrumentationScope.\ntype ScopeSpans struct {\n\t// The instrumentation scope information for the spans in this message.\n\t// Semantically when InstrumentationScope isn't set, it is equivalent with\n\t// an empty instrumentation scope name (unknown).\n\tScope *Scope `json:\"scope\"`\n\t// A list of Spans that originate from an instrumentation scope.\n\tSpans []*Span `json:\"spans,omitempty\"`\n\t// The Schema URL, if known. This is the identifier of the Schema that the span data\n\t// is recorded in. To learn more about Schema URL see\n\t// https://opentelemetry.io/docs/specs/otel/schemas/#schema-url\n\t// This schema_url applies to all spans and span events in the \"spans\" field.\n\tSchemaURL string `json:\"schemaUrl,omitempty\"`\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into ss.\nfunc (ss *ScopeSpans) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid ScopeSpans type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid ScopeSpans field: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"scope\":\n\t\t\terr = decoder.Decode(&ss.Scope)\n\t\tcase \"spans\":\n\t\t\terr = decoder.Decode(&ss.Spans)\n\t\tcase \"schemaUrl\", \"schema_url\":\n\t\t\terr = decoder.Decode(&ss.SchemaURL)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/internal/telemetry/value.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry\n\nimport (\n\t\"bytes\"\n\t\"cmp\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"slices\"\n\t\"strconv\"\n\t\"unsafe\"\n)\n\n// A Value represents a structured value.\n// A zero value is valid and represents an empty value.\ntype Value struct {\n\t// Ensure forward compatibility by explicitly making this not comparable.\n\tnoCmp [0]func() //nolint:unused  // This is indeed used.\n\n\t// num holds the value for Int64, Float64, and Bool. It holds the length\n\t// for String, Bytes, Slice, Map.\n\tnum uint64\n\t// any holds either the KindBool, KindInt64, KindFloat64, stringptr,\n\t// bytesptr, sliceptr, or mapptr. If KindBool, KindInt64, or KindFloat64\n\t// then the value of Value is in num as described above. Otherwise, it\n\t// contains the value wrapped in the appropriate type.\n\tany any\n}\n\ntype (\n\t// sliceptr represents a value in Value.any for KindString Values.\n\tstringptr *byte\n\t// bytesptr represents a value in Value.any for KindBytes Values.\n\tbytesptr *byte\n\t// sliceptr represents a value in Value.any for KindSlice Values.\n\tsliceptr *Value\n\t// mapptr represents a value in Value.any for KindMap Values.\n\tmapptr *Attr\n)\n\n// ValueKind is the kind of a [Value].\ntype ValueKind int\n\n// ValueKind values.\nconst (\n\tValueKindEmpty ValueKind = iota\n\tValueKindBool\n\tValueKindFloat64\n\tValueKindInt64\n\tValueKindString\n\tValueKindBytes\n\tValueKindSlice\n\tValueKindMap\n)\n\nvar valueKindStrings = []string{\n\t\"Empty\",\n\t\"Bool\",\n\t\"Float64\",\n\t\"Int64\",\n\t\"String\",\n\t\"Bytes\",\n\t\"Slice\",\n\t\"Map\",\n}\n\nfunc (k ValueKind) String() string {\n\tif k >= 0 && int(k) < len(valueKindStrings) {\n\t\treturn valueKindStrings[k]\n\t}\n\treturn \"<unknown telemetry.ValueKind>\"\n}\n\n// StringValue returns a new [Value] for a string.\nfunc StringValue(v string) Value {\n\treturn Value{\n\t\tnum: uint64(len(v)),\n\t\tany: stringptr(unsafe.StringData(v)),\n\t}\n}\n\n// IntValue returns a [Value] for an int.\nfunc IntValue(v int) Value { return Int64Value(int64(v)) }\n\n// Int64Value returns a [Value] for an int64.\nfunc Int64Value(v int64) Value {\n\treturn Value{num: uint64(v), any: ValueKindInt64} //nolint:gosec  // Raw value conv.\n}\n\n// Float64Value returns a [Value] for a float64.\nfunc Float64Value(v float64) Value {\n\treturn Value{num: math.Float64bits(v), any: ValueKindFloat64}\n}\n\n// BoolValue returns a [Value] for a bool.\nfunc BoolValue(v bool) Value { //nolint:revive // Not a control flag.\n\tvar n uint64\n\tif v {\n\t\tn = 1\n\t}\n\treturn Value{num: n, any: ValueKindBool}\n}\n\n// BytesValue returns a [Value] for a byte slice. The passed slice must not be\n// changed after it is passed.\nfunc BytesValue(v []byte) Value {\n\treturn Value{\n\t\tnum: uint64(len(v)),\n\t\tany: bytesptr(unsafe.SliceData(v)),\n\t}\n}\n\n// SliceValue returns a [Value] for a slice of [Value]. The passed slice must\n// not be changed after it is passed.\nfunc SliceValue(vs ...Value) Value {\n\treturn Value{\n\t\tnum: uint64(len(vs)),\n\t\tany: sliceptr(unsafe.SliceData(vs)),\n\t}\n}\n\n// MapValue returns a new [Value] for a slice of key-value pairs. The passed\n// slice must not be changed after it is passed.\nfunc MapValue(kvs ...Attr) Value {\n\treturn Value{\n\t\tnum: uint64(len(kvs)),\n\t\tany: mapptr(unsafe.SliceData(kvs)),\n\t}\n}\n\n// AsString returns the value held by v as a string.\nfunc (v Value) AsString() string {\n\tif sp, ok := v.any.(stringptr); ok {\n\t\treturn unsafe.String(sp, v.num)\n\t}\n\t// TODO: error handle\n\treturn \"\"\n}\n\n// asString returns the value held by v as a string. It will panic if the Value\n// is not KindString.\nfunc (v Value) asString() string {\n\treturn unsafe.String(v.any.(stringptr), v.num)\n}\n\n// AsInt64 returns the value held by v as an int64.\nfunc (v Value) AsInt64() int64 {\n\tif v.Kind() != ValueKindInt64 {\n\t\t// TODO: error handle\n\t\treturn 0\n\t}\n\treturn v.asInt64()\n}\n\n// asInt64 returns the value held by v as an int64. If v is not of KindInt64,\n// this will return garbage.\nfunc (v Value) asInt64() int64 {\n\t// Assumes v.num was a valid int64 (overflow not checked).\n\treturn int64(v.num) //nolint:gosec  // Bounded.\n}\n\n// AsBool returns the value held by v as a bool.\nfunc (v Value) AsBool() bool {\n\tif v.Kind() != ValueKindBool {\n\t\t// TODO: error handle\n\t\treturn false\n\t}\n\treturn v.asBool()\n}\n\n// asBool returns the value held by v as a bool. If v is not of KindBool, this\n// will return garbage.\nfunc (v Value) asBool() bool { return v.num == 1 }\n\n// AsFloat64 returns the value held by v as a float64.\nfunc (v Value) AsFloat64() float64 {\n\tif v.Kind() != ValueKindFloat64 {\n\t\t// TODO: error handle\n\t\treturn 0\n\t}\n\treturn v.asFloat64()\n}\n\n// asFloat64 returns the value held by v as a float64. If v is not of\n// KindFloat64, this will return garbage.\nfunc (v Value) asFloat64() float64 { return math.Float64frombits(v.num) }\n\n// AsBytes returns the value held by v as a []byte.\nfunc (v Value) AsBytes() []byte {\n\tif sp, ok := v.any.(bytesptr); ok {\n\t\treturn unsafe.Slice((*byte)(sp), v.num)\n\t}\n\t// TODO: error handle\n\treturn nil\n}\n\n// asBytes returns the value held by v as a []byte. It will panic if the Value\n// is not KindBytes.\nfunc (v Value) asBytes() []byte {\n\treturn unsafe.Slice((*byte)(v.any.(bytesptr)), v.num)\n}\n\n// AsSlice returns the value held by v as a []Value.\nfunc (v Value) AsSlice() []Value {\n\tif sp, ok := v.any.(sliceptr); ok {\n\t\treturn unsafe.Slice((*Value)(sp), v.num)\n\t}\n\t// TODO: error handle\n\treturn nil\n}\n\n// asSlice returns the value held by v as a []Value. It will panic if the Value\n// is not KindSlice.\nfunc (v Value) asSlice() []Value {\n\treturn unsafe.Slice((*Value)(v.any.(sliceptr)), v.num)\n}\n\n// AsMap returns the value held by v as a []Attr.\nfunc (v Value) AsMap() []Attr {\n\tif sp, ok := v.any.(mapptr); ok {\n\t\treturn unsafe.Slice((*Attr)(sp), v.num)\n\t}\n\t// TODO: error handle\n\treturn nil\n}\n\n// asMap returns the value held by v as a []Attr. It will panic if the\n// Value is not KindMap.\nfunc (v Value) asMap() []Attr {\n\treturn unsafe.Slice((*Attr)(v.any.(mapptr)), v.num)\n}\n\n// Kind returns the Kind of v.\nfunc (v Value) Kind() ValueKind {\n\tswitch x := v.any.(type) {\n\tcase ValueKind:\n\t\treturn x\n\tcase stringptr:\n\t\treturn ValueKindString\n\tcase bytesptr:\n\t\treturn ValueKindBytes\n\tcase sliceptr:\n\t\treturn ValueKindSlice\n\tcase mapptr:\n\t\treturn ValueKindMap\n\tdefault:\n\t\treturn ValueKindEmpty\n\t}\n}\n\n// Empty returns if v does not hold any value.\nfunc (v Value) Empty() bool { return v.Kind() == ValueKindEmpty }\n\n// Equal returns if v is equal to w.\nfunc (v Value) Equal(w Value) bool {\n\tk1 := v.Kind()\n\tk2 := w.Kind()\n\tif k1 != k2 {\n\t\treturn false\n\t}\n\tswitch k1 {\n\tcase ValueKindInt64, ValueKindBool:\n\t\treturn v.num == w.num\n\tcase ValueKindString:\n\t\treturn v.asString() == w.asString()\n\tcase ValueKindFloat64:\n\t\treturn v.asFloat64() == w.asFloat64()\n\tcase ValueKindSlice:\n\t\treturn slices.EqualFunc(v.asSlice(), w.asSlice(), Value.Equal)\n\tcase ValueKindMap:\n\t\tsv := sortMap(v.asMap())\n\t\tsw := sortMap(w.asMap())\n\t\treturn slices.EqualFunc(sv, sw, Attr.Equal)\n\tcase ValueKindBytes:\n\t\treturn bytes.Equal(v.asBytes(), w.asBytes())\n\tcase ValueKindEmpty:\n\t\treturn true\n\tdefault:\n\t\t// TODO: error handle\n\t\treturn false\n\t}\n}\n\nfunc sortMap(m []Attr) []Attr {\n\tsm := make([]Attr, len(m))\n\tcopy(sm, m)\n\tslices.SortFunc(sm, func(a, b Attr) int {\n\t\treturn cmp.Compare(a.Key, b.Key)\n\t})\n\n\treturn sm\n}\n\n// String returns Value's value as a string, formatted like [fmt.Sprint].\n//\n// The returned string is meant for debugging;\n// the string representation is not stable.\nfunc (v Value) String() string {\n\tswitch v.Kind() {\n\tcase ValueKindString:\n\t\treturn v.asString()\n\tcase ValueKindInt64:\n\t\t// Assumes v.num was a valid int64 (overflow not checked).\n\t\treturn strconv.FormatInt(int64(v.num), 10) //nolint:gosec  // Bounded.\n\tcase ValueKindFloat64:\n\t\treturn strconv.FormatFloat(v.asFloat64(), 'g', -1, 64)\n\tcase ValueKindBool:\n\t\treturn strconv.FormatBool(v.asBool())\n\tcase ValueKindBytes:\n\t\treturn string(v.asBytes())\n\tcase ValueKindMap:\n\t\treturn fmt.Sprint(v.asMap())\n\tcase ValueKindSlice:\n\t\treturn fmt.Sprint(v.asSlice())\n\tcase ValueKindEmpty:\n\t\treturn \"<nil>\"\n\tdefault:\n\t\t// Try to handle this as gracefully as possible.\n\t\t//\n\t\t// Don't panic here. The goal here is to have developers find this\n\t\t// first if a slog.Kind is is not handled. It is\n\t\t// preferable to have user's open issue asking why their attributes\n\t\t// have a \"unhandled: \" prefix than say that their code is panicking.\n\t\treturn fmt.Sprintf(\"<unhandled telemetry.ValueKind: %s>\", v.Kind())\n\t}\n}\n\n// MarshalJSON encodes v into OTLP formatted JSON.\nfunc (v *Value) MarshalJSON() ([]byte, error) {\n\tswitch v.Kind() {\n\tcase ValueKindString:\n\t\treturn json.Marshal(struct {\n\t\t\tValue string `json:\"stringValue\"`\n\t\t}{v.asString()})\n\tcase ValueKindInt64:\n\t\treturn json.Marshal(struct {\n\t\t\tValue string `json:\"intValue\"`\n\t\t}{strconv.FormatInt(int64(v.num), 10)}) //nolint:gosec  // Raw value conv.\n\tcase ValueKindFloat64:\n\t\treturn json.Marshal(struct {\n\t\t\tValue float64 `json:\"doubleValue\"`\n\t\t}{v.asFloat64()})\n\tcase ValueKindBool:\n\t\treturn json.Marshal(struct {\n\t\t\tValue bool `json:\"boolValue\"`\n\t\t}{v.asBool()})\n\tcase ValueKindBytes:\n\t\treturn json.Marshal(struct {\n\t\t\tValue []byte `json:\"bytesValue\"`\n\t\t}{v.asBytes()})\n\tcase ValueKindMap:\n\t\treturn json.Marshal(struct {\n\t\t\tValue struct {\n\t\t\t\tValues []Attr `json:\"values\"`\n\t\t\t} `json:\"kvlistValue\"`\n\t\t}{struct {\n\t\t\tValues []Attr `json:\"values\"`\n\t\t}{v.asMap()}})\n\tcase ValueKindSlice:\n\t\treturn json.Marshal(struct {\n\t\t\tValue struct {\n\t\t\t\tValues []Value `json:\"values\"`\n\t\t\t} `json:\"arrayValue\"`\n\t\t}{struct {\n\t\t\tValues []Value `json:\"values\"`\n\t\t}{v.asSlice()}})\n\tcase ValueKindEmpty:\n\t\treturn nil, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown Value kind: %s\", v.Kind().String())\n\t}\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into v.\nfunc (v *Value) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid Value type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid Value key: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"stringValue\", \"string_value\":\n\t\t\tvar val string\n\t\t\terr = decoder.Decode(&val)\n\t\t\t*v = StringValue(val)\n\t\tcase \"boolValue\", \"bool_value\":\n\t\t\tvar val bool\n\t\t\terr = decoder.Decode(&val)\n\t\t\t*v = BoolValue(val)\n\t\tcase \"intValue\", \"int_value\":\n\t\t\tvar val protoInt64\n\t\t\terr = decoder.Decode(&val)\n\t\t\t*v = Int64Value(val.Int64())\n\t\tcase \"doubleValue\", \"double_value\":\n\t\t\tvar val float64\n\t\t\terr = decoder.Decode(&val)\n\t\t\t*v = Float64Value(val)\n\t\tcase \"bytesValue\", \"bytes_value\":\n\t\t\tvar val64 string\n\t\t\tif err := decoder.Decode(&val64); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tvar val []byte\n\t\t\tval, err = base64.StdEncoding.DecodeString(val64)\n\t\t\t*v = BytesValue(val)\n\t\tcase \"arrayValue\", \"array_value\":\n\t\t\tvar val struct{ Values []Value }\n\t\t\terr = decoder.Decode(&val)\n\t\t\t*v = SliceValue(val.Values...)\n\t\tcase \"kvlistValue\", \"kvlist_value\":\n\t\t\tvar val struct{ Values []Attr }\n\t\t\terr = decoder.Decode(&val)\n\t\t\t*v = MapValue(val.Values...)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t\tcontinue\n\t\t}\n\t\t// Use first valid. Ignore the rest.\n\t\treturn err\n\t}\n\n\t// Only unknown fields. Return nil without unmarshaling any value.\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/limit.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage sdk\n\nimport (\n\t\"log/slog\"\n\t\"os\"\n\t\"strconv\"\n)\n\n// maxSpan are the span limits resolved during startup.\nvar maxSpan = newSpanLimits()\n\ntype spanLimits struct {\n\t// Attrs is the number of allowed attributes for a span.\n\t//\n\t// This is resolved from the environment variable value for the\n\t// OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT key if it exists. Otherwise, the\n\t// environment variable value for OTEL_ATTRIBUTE_COUNT_LIMIT, or 128 if\n\t// that is not set, is used.\n\tAttrs int\n\t// AttrValueLen is the maximum attribute value length allowed for a span.\n\t//\n\t// This is resolved from the environment variable value for the\n\t// OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT key if it exists. Otherwise, the\n\t// environment variable value for OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT, or -1\n\t// if that is not set, is used.\n\tAttrValueLen int\n\t// Events is the number of allowed events for a span.\n\t//\n\t// This is resolved from the environment variable value for the\n\t// OTEL_SPAN_EVENT_COUNT_LIMIT key, or 128 is used if that is not set.\n\tEvents int\n\t// EventAttrs is the number of allowed attributes for a span event.\n\t//\n\t// The is resolved from the environment variable value for the\n\t// OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT key, or 128 is used if that is not set.\n\tEventAttrs int\n\t// Links is the number of allowed Links for a span.\n\t//\n\t// This is resolved from the environment variable value for the\n\t// OTEL_SPAN_LINK_COUNT_LIMIT, or 128 is used if that is not set.\n\tLinks int\n\t// LinkAttrs is the number of allowed attributes for a span link.\n\t//\n\t// This is resolved from the environment variable value for the\n\t// OTEL_LINK_ATTRIBUTE_COUNT_LIMIT, or 128 is used if that is not set.\n\tLinkAttrs int\n}\n\nfunc newSpanLimits() spanLimits {\n\treturn spanLimits{\n\t\tAttrs: firstEnv(\n\t\t\t128,\n\t\t\t\"OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT\",\n\t\t\t\"OTEL_ATTRIBUTE_COUNT_LIMIT\",\n\t\t),\n\t\tAttrValueLen: firstEnv(\n\t\t\t-1, // Unlimited.\n\t\t\t\"OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT\",\n\t\t\t\"OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT\",\n\t\t),\n\t\tEvents:     firstEnv(128, \"OTEL_SPAN_EVENT_COUNT_LIMIT\"),\n\t\tEventAttrs: firstEnv(128, \"OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT\"),\n\t\tLinks:      firstEnv(128, \"OTEL_SPAN_LINK_COUNT_LIMIT\"),\n\t\tLinkAttrs:  firstEnv(128, \"OTEL_LINK_ATTRIBUTE_COUNT_LIMIT\"),\n\t}\n}\n\n// firstEnv returns the parsed integer value of the first matching environment\n// variable from keys. The defaultVal is returned if the value is not an\n// integer or no match is found.\nfunc firstEnv(defaultVal int, keys ...string) int {\n\tfor _, key := range keys {\n\t\tstrV := os.Getenv(key)\n\t\tif strV == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tv, err := strconv.Atoi(strV)\n\t\tif err == nil {\n\t\t\treturn v\n\t\t}\n\t\tslog.Warn(\n\t\t\t\"invalid limit environment variable\",\n\t\t\t\"error\", err,\n\t\t\t\"key\", key,\n\t\t\t\"value\", strV,\n\t\t)\n\t}\n\n\treturn defaultVal\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/span.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage sdk\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"math\"\n\t\"reflect\"\n\t\"runtime\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\t\"unicode/utf8\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.37.0\"\n\t\"go.opentelemetry.io/otel/trace\"\n\t\"go.opentelemetry.io/otel/trace/noop\"\n\n\t\"go.opentelemetry.io/auto/sdk/internal/telemetry\"\n)\n\ntype span struct {\n\tnoop.Span\n\n\tspanContext trace.SpanContext\n\tsampled     atomic.Bool\n\n\tmu     sync.Mutex\n\ttraces *telemetry.Traces\n\tspan   *telemetry.Span\n}\n\nfunc (s *span) SpanContext() trace.SpanContext {\n\tif s == nil {\n\t\treturn trace.SpanContext{}\n\t}\n\t// s.spanContext is immutable, do not acquire lock s.mu.\n\treturn s.spanContext\n}\n\nfunc (s *span) IsRecording() bool {\n\tif s == nil {\n\t\treturn false\n\t}\n\n\treturn s.sampled.Load()\n}\n\nfunc (s *span) SetStatus(c codes.Code, msg string) {\n\tif s == nil || !s.sampled.Load() {\n\t\treturn\n\t}\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tif s.span.Status == nil {\n\t\ts.span.Status = new(telemetry.Status)\n\t}\n\n\ts.span.Status.Message = msg\n\n\tswitch c {\n\tcase codes.Unset:\n\t\ts.span.Status.Code = telemetry.StatusCodeUnset\n\tcase codes.Error:\n\t\ts.span.Status.Code = telemetry.StatusCodeError\n\tcase codes.Ok:\n\t\ts.span.Status.Code = telemetry.StatusCodeOK\n\t}\n}\n\nfunc (s *span) SetAttributes(attrs ...attribute.KeyValue) {\n\tif s == nil || !s.sampled.Load() {\n\t\treturn\n\t}\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tlimit := maxSpan.Attrs\n\tif limit == 0 {\n\t\t// No attributes allowed.\n\t\tn := int64(len(attrs))\n\t\tif n > 0 {\n\t\t\ts.span.DroppedAttrs += uint32( //nolint:gosec  // Bounds checked.\n\t\t\t\tmin(n, math.MaxUint32),\n\t\t\t)\n\t\t}\n\t\treturn\n\t}\n\n\tm := make(map[string]int)\n\tfor i, a := range s.span.Attrs {\n\t\tm[a.Key] = i\n\t}\n\n\tfor _, a := range attrs {\n\t\tval := convAttrValue(a.Value)\n\t\tif val.Empty() {\n\t\t\ts.span.DroppedAttrs++\n\t\t\tcontinue\n\t\t}\n\n\t\tif idx, ok := m[string(a.Key)]; ok {\n\t\t\ts.span.Attrs[idx] = telemetry.Attr{\n\t\t\t\tKey:   string(a.Key),\n\t\t\t\tValue: val,\n\t\t\t}\n\t\t} else if limit < 0 || len(s.span.Attrs) < limit {\n\t\t\ts.span.Attrs = append(s.span.Attrs, telemetry.Attr{\n\t\t\t\tKey:   string(a.Key),\n\t\t\t\tValue: val,\n\t\t\t})\n\t\t\tm[string(a.Key)] = len(s.span.Attrs) - 1\n\t\t} else {\n\t\t\ts.span.DroppedAttrs++\n\t\t}\n\t}\n}\n\n// convCappedAttrs converts up to limit attrs into a []telemetry.Attr. The\n// number of dropped attributes is also returned.\nfunc convCappedAttrs(limit int, attrs []attribute.KeyValue) ([]telemetry.Attr, uint32) {\n\tn := len(attrs)\n\tif limit == 0 {\n\t\tvar out uint32\n\t\tif n > 0 {\n\t\t\tout = uint32(min(int64(n), math.MaxUint32)) //nolint:gosec  // Bounds checked.\n\t\t}\n\t\treturn nil, out\n\t}\n\n\tif limit < 0 {\n\t\t// Unlimited.\n\t\treturn convAttrs(attrs), 0\n\t}\n\n\tif n < 0 {\n\t\tn = 0\n\t}\n\n\tlimit = min(n, limit)\n\treturn convAttrs(attrs[:limit]), uint32(n - limit) //nolint:gosec  // Bounds checked.\n}\n\nfunc convAttrs(attrs []attribute.KeyValue) []telemetry.Attr {\n\tif len(attrs) == 0 {\n\t\t// Avoid allocations if not necessary.\n\t\treturn nil\n\t}\n\n\tout := make([]telemetry.Attr, 0, len(attrs))\n\tfor _, attr := range attrs {\n\t\tkey := string(attr.Key)\n\t\tval := convAttrValue(attr.Value)\n\t\tif val.Empty() {\n\t\t\tcontinue\n\t\t}\n\t\tout = append(out, telemetry.Attr{Key: key, Value: val})\n\t}\n\treturn out\n}\n\nfunc convAttrValue(value attribute.Value) telemetry.Value {\n\tswitch value.Type() {\n\tcase attribute.BOOL:\n\t\treturn telemetry.BoolValue(value.AsBool())\n\tcase attribute.INT64:\n\t\treturn telemetry.Int64Value(value.AsInt64())\n\tcase attribute.FLOAT64:\n\t\treturn telemetry.Float64Value(value.AsFloat64())\n\tcase attribute.STRING:\n\t\tv := truncate(maxSpan.AttrValueLen, value.AsString())\n\t\treturn telemetry.StringValue(v)\n\tcase attribute.BOOLSLICE:\n\t\tslice := value.AsBoolSlice()\n\t\tout := make([]telemetry.Value, 0, len(slice))\n\t\tfor _, v := range slice {\n\t\t\tout = append(out, telemetry.BoolValue(v))\n\t\t}\n\t\treturn telemetry.SliceValue(out...)\n\tcase attribute.INT64SLICE:\n\t\tslice := value.AsInt64Slice()\n\t\tout := make([]telemetry.Value, 0, len(slice))\n\t\tfor _, v := range slice {\n\t\t\tout = append(out, telemetry.Int64Value(v))\n\t\t}\n\t\treturn telemetry.SliceValue(out...)\n\tcase attribute.FLOAT64SLICE:\n\t\tslice := value.AsFloat64Slice()\n\t\tout := make([]telemetry.Value, 0, len(slice))\n\t\tfor _, v := range slice {\n\t\t\tout = append(out, telemetry.Float64Value(v))\n\t\t}\n\t\treturn telemetry.SliceValue(out...)\n\tcase attribute.STRINGSLICE:\n\t\tslice := value.AsStringSlice()\n\t\tout := make([]telemetry.Value, 0, len(slice))\n\t\tfor _, v := range slice {\n\t\t\tv = truncate(maxSpan.AttrValueLen, v)\n\t\t\tout = append(out, telemetry.StringValue(v))\n\t\t}\n\t\treturn telemetry.SliceValue(out...)\n\t}\n\treturn telemetry.Value{}\n}\n\n// truncate returns a truncated version of s such that it contains less than\n// the limit number of characters. Truncation is applied by returning the limit\n// number of valid characters contained in s.\n//\n// If limit is negative, it returns the original string.\n//\n// UTF-8 is supported. When truncating, all invalid characters are dropped\n// before applying truncation.\n//\n// If s already contains less than the limit number of bytes, it is returned\n// unchanged. No invalid characters are removed.\nfunc truncate(limit int, s string) string {\n\t// This prioritize performance in the following order based on the most\n\t// common expected use-cases.\n\t//\n\t//  - Short values less than the default limit (128).\n\t//  - Strings with valid encodings that exceed the limit.\n\t//  - No limit.\n\t//  - Strings with invalid encodings that exceed the limit.\n\tif limit < 0 || len(s) <= limit {\n\t\treturn s\n\t}\n\n\t// Optimistically, assume all valid UTF-8.\n\tvar b strings.Builder\n\tcount := 0\n\tfor i, c := range s {\n\t\tif c != utf8.RuneError {\n\t\t\tcount++\n\t\t\tif count > limit {\n\t\t\t\treturn s[:i]\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t_, size := utf8.DecodeRuneInString(s[i:])\n\t\tif size == 1 {\n\t\t\t// Invalid encoding.\n\t\t\tb.Grow(len(s) - 1)\n\t\t\t_, _ = b.WriteString(s[:i])\n\t\t\ts = s[i:]\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Fast-path, no invalid input.\n\tif b.Cap() == 0 {\n\t\treturn s\n\t}\n\n\t// Truncate while validating UTF-8.\n\tfor i := 0; i < len(s) && count < limit; {\n\t\tc := s[i]\n\t\tif c < utf8.RuneSelf {\n\t\t\t// Optimization for single byte runes (common case).\n\t\t\t_ = b.WriteByte(c)\n\t\t\ti++\n\t\t\tcount++\n\t\t\tcontinue\n\t\t}\n\n\t\t_, size := utf8.DecodeRuneInString(s[i:])\n\t\tif size == 1 {\n\t\t\t// We checked for all 1-byte runes above, this is a RuneError.\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\n\t\t_, _ = b.WriteString(s[i : i+size])\n\t\ti += size\n\t\tcount++\n\t}\n\n\treturn b.String()\n}\n\nfunc (s *span) End(opts ...trace.SpanEndOption) {\n\tif s == nil || !s.sampled.Swap(false) {\n\t\treturn\n\t}\n\n\t// s.end exists so the lock (s.mu) is not held while s.ended is called.\n\ts.ended(s.end(opts))\n}\n\nfunc (s *span) end(opts []trace.SpanEndOption) []byte {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tcfg := trace.NewSpanEndConfig(opts...)\n\tif t := cfg.Timestamp(); !t.IsZero() {\n\t\ts.span.EndTime = cfg.Timestamp()\n\t} else {\n\t\ts.span.EndTime = time.Now()\n\t}\n\n\tb, _ := json.Marshal(s.traces) // TODO: do not ignore this error.\n\treturn b\n}\n\n// Expected to be implemented in eBPF.\n//\n//go:noinline\nfunc (*span) ended(buf []byte) { ended(buf) }\n\n// ended is used for testing.\nvar ended = func([]byte) {}\n\nfunc (s *span) RecordError(err error, opts ...trace.EventOption) {\n\tif s == nil || err == nil || !s.sampled.Load() {\n\t\treturn\n\t}\n\n\tcfg := trace.NewEventConfig(opts...)\n\n\tattrs := cfg.Attributes()\n\tattrs = append(attrs,\n\t\tsemconv.ExceptionType(typeStr(err)),\n\t\tsemconv.ExceptionMessage(err.Error()),\n\t)\n\tif cfg.StackTrace() {\n\t\tbuf := make([]byte, 2048)\n\t\tn := runtime.Stack(buf, false)\n\t\tattrs = append(attrs, semconv.ExceptionStacktrace(string(buf[0:n])))\n\t}\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\ts.addEvent(semconv.ExceptionEventName, cfg.Timestamp(), attrs)\n}\n\nfunc typeStr(i any) string {\n\tt := reflect.TypeOf(i)\n\tif t.PkgPath() == \"\" && t.Name() == \"\" {\n\t\t// Likely a builtin type.\n\t\treturn t.String()\n\t}\n\treturn fmt.Sprintf(\"%s.%s\", t.PkgPath(), t.Name())\n}\n\nfunc (s *span) AddEvent(name string, opts ...trace.EventOption) {\n\tif s == nil || !s.sampled.Load() {\n\t\treturn\n\t}\n\n\tcfg := trace.NewEventConfig(opts...)\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\ts.addEvent(name, cfg.Timestamp(), cfg.Attributes())\n}\n\n// addEvent adds an event with name and attrs at tStamp to the span. The span\n// lock (s.mu) needs to be held by the caller.\nfunc (s *span) addEvent(name string, tStamp time.Time, attrs []attribute.KeyValue) {\n\tlimit := maxSpan.Events\n\n\tif limit == 0 {\n\t\ts.span.DroppedEvents++\n\t\treturn\n\t}\n\n\tif limit > 0 && len(s.span.Events) == limit {\n\t\t// Drop head while avoiding allocation of more capacity.\n\t\tcopy(s.span.Events[:limit-1], s.span.Events[1:])\n\t\ts.span.Events = s.span.Events[:limit-1]\n\t\ts.span.DroppedEvents++\n\t}\n\n\te := &telemetry.SpanEvent{Time: tStamp, Name: name}\n\te.Attrs, e.DroppedAttrs = convCappedAttrs(maxSpan.EventAttrs, attrs)\n\n\ts.span.Events = append(s.span.Events, e)\n}\n\nfunc (s *span) AddLink(link trace.Link) {\n\tif s == nil || !s.sampled.Load() {\n\t\treturn\n\t}\n\n\tl := maxSpan.Links\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tif l == 0 {\n\t\ts.span.DroppedLinks++\n\t\treturn\n\t}\n\n\tif l > 0 && len(s.span.Links) == l {\n\t\t// Drop head while avoiding allocation of more capacity.\n\t\tcopy(s.span.Links[:l-1], s.span.Links[1:])\n\t\ts.span.Links = s.span.Links[:l-1]\n\t\ts.span.DroppedLinks++\n\t}\n\n\ts.span.Links = append(s.span.Links, convLink(link))\n}\n\nfunc convLinks(links []trace.Link) []*telemetry.SpanLink {\n\tout := make([]*telemetry.SpanLink, 0, len(links))\n\tfor _, link := range links {\n\t\tout = append(out, convLink(link))\n\t}\n\treturn out\n}\n\nfunc convLink(link trace.Link) *telemetry.SpanLink {\n\tl := &telemetry.SpanLink{\n\t\tTraceID:    telemetry.TraceID(link.SpanContext.TraceID()),\n\t\tSpanID:     telemetry.SpanID(link.SpanContext.SpanID()),\n\t\tTraceState: link.SpanContext.TraceState().String(),\n\t\tFlags:      uint32(link.SpanContext.TraceFlags()),\n\t}\n\tl.Attrs, l.DroppedAttrs = convCappedAttrs(maxSpan.LinkAttrs, link.Attributes)\n\n\treturn l\n}\n\nfunc (s *span) SetName(name string) {\n\tif s == nil || !s.sampled.Load() {\n\t\treturn\n\t}\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\ts.span.Name = name\n}\n\nfunc (*span) TracerProvider() trace.TracerProvider { return TracerProvider() }\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/tracer.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage sdk\n\nimport (\n\t\"context\"\n\t\"math\"\n\t\"time\"\n\n\t\"go.opentelemetry.io/otel/trace\"\n\t\"go.opentelemetry.io/otel/trace/noop\"\n\n\t\"go.opentelemetry.io/auto/sdk/internal/telemetry\"\n)\n\ntype tracer struct {\n\tnoop.Tracer\n\n\tname, schemaURL, version string\n}\n\nvar _ trace.Tracer = tracer{}\n\nfunc (t tracer) Start(\n\tctx context.Context,\n\tname string,\n\topts ...trace.SpanStartOption,\n) (context.Context, trace.Span) {\n\tvar psc, sc trace.SpanContext\n\tsampled := true\n\tspan := new(span)\n\n\t// Ask eBPF for sampling decision and span context info.\n\tt.start(ctx, span, &psc, &sampled, &sc)\n\n\tspan.sampled.Store(sampled)\n\tspan.spanContext = sc\n\n\tctx = trace.ContextWithSpan(ctx, span)\n\n\tif sampled {\n\t\t// Only build traces if sampled.\n\t\tcfg := trace.NewSpanStartConfig(opts...)\n\t\tspan.traces, span.span = t.traces(name, cfg, span.spanContext, psc)\n\t}\n\n\treturn ctx, span\n}\n\n// Expected to be implemented in eBPF.\n//\n//go:noinline\nfunc (t *tracer) start(\n\tctx context.Context,\n\tspanPtr *span,\n\tpsc *trace.SpanContext,\n\tsampled *bool,\n\tsc *trace.SpanContext,\n) {\n\tstart(ctx, spanPtr, psc, sampled, sc)\n}\n\n// start is used for testing.\nvar start = func(context.Context, *span, *trace.SpanContext, *bool, *trace.SpanContext) {}\n\nvar intToUint32Bound = min(math.MaxInt, math.MaxUint32)\n\nfunc (t tracer) traces(\n\tname string,\n\tcfg trace.SpanConfig,\n\tsc, psc trace.SpanContext,\n) (*telemetry.Traces, *telemetry.Span) {\n\tspan := &telemetry.Span{\n\t\tTraceID:      telemetry.TraceID(sc.TraceID()),\n\t\tSpanID:       telemetry.SpanID(sc.SpanID()),\n\t\tFlags:        uint32(sc.TraceFlags()),\n\t\tTraceState:   sc.TraceState().String(),\n\t\tParentSpanID: telemetry.SpanID(psc.SpanID()),\n\t\tName:         name,\n\t\tKind:         spanKind(cfg.SpanKind()),\n\t}\n\n\tspan.Attrs, span.DroppedAttrs = convCappedAttrs(maxSpan.Attrs, cfg.Attributes())\n\n\tlinks := cfg.Links()\n\tif limit := maxSpan.Links; limit == 0 {\n\t\tn := len(links)\n\t\tif n > 0 {\n\t\t\tbounded := max(min(n, intToUint32Bound), 0)\n\t\t\tspan.DroppedLinks = uint32(bounded) //nolint:gosec  // Bounds checked.\n\t\t}\n\t} else {\n\t\tif limit > 0 {\n\t\t\tn := max(len(links)-limit, 0)\n\t\t\tbounded := min(n, intToUint32Bound)\n\t\t\tspan.DroppedLinks = uint32(bounded) //nolint:gosec  // Bounds checked.\n\t\t\tlinks = links[n:]\n\t\t}\n\t\tspan.Links = convLinks(links)\n\t}\n\n\tif t := cfg.Timestamp(); !t.IsZero() {\n\t\tspan.StartTime = cfg.Timestamp()\n\t} else {\n\t\tspan.StartTime = time.Now()\n\t}\n\n\treturn &telemetry.Traces{\n\t\tResourceSpans: []*telemetry.ResourceSpans{\n\t\t\t{\n\t\t\t\tScopeSpans: []*telemetry.ScopeSpans{\n\t\t\t\t\t{\n\t\t\t\t\t\tScope: &telemetry.Scope{\n\t\t\t\t\t\t\tName:    t.name,\n\t\t\t\t\t\t\tVersion: t.version,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tSpans:     []*telemetry.Span{span},\n\t\t\t\t\t\tSchemaURL: t.schemaURL,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}, span\n}\n\nfunc spanKind(kind trace.SpanKind) telemetry.SpanKind {\n\tswitch kind {\n\tcase trace.SpanKindInternal:\n\t\treturn telemetry.SpanKindInternal\n\tcase trace.SpanKindServer:\n\t\treturn telemetry.SpanKindServer\n\tcase trace.SpanKindClient:\n\t\treturn telemetry.SpanKindClient\n\tcase trace.SpanKindProducer:\n\t\treturn telemetry.SpanKindProducer\n\tcase trace.SpanKindConsumer:\n\t\treturn telemetry.SpanKindConsumer\n\t}\n\treturn telemetry.SpanKind(0) // undefined.\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/auto/sdk/tracer_provider.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage sdk\n\nimport (\n\t\"go.opentelemetry.io/otel/trace\"\n\t\"go.opentelemetry.io/otel/trace/noop\"\n)\n\n// TracerProvider returns an auto-instrumentable [trace.TracerProvider].\n//\n// If an [go.opentelemetry.io/auto.Instrumentation] is configured to instrument\n// the process using the returned TracerProvider, all of the telemetry it\n// produces will be processed and handled by that Instrumentation. By default,\n// if no Instrumentation instruments the TracerProvider it will not generate\n// any trace telemetry.\nfunc TracerProvider() trace.TracerProvider { return tracerProviderInstance }\n\nvar tracerProviderInstance = new(tracerProvider)\n\ntype tracerProvider struct{ noop.TracerProvider }\n\nvar _ trace.TracerProvider = tracerProvider{}\n\nfunc (p tracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer {\n\tcfg := trace.NewTracerConfig(opts...)\n\treturn tracer{\n\t\tname:      name,\n\t\tversion:   cfg.InstrumentationVersion(),\n\t\tschemaURL: cfg.SchemaURL(),\n\t}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/contrib/propagators/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/contrib/propagators/jaeger/context.go",
    "content": "// Copyright The OpenTelemetry Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage jaeger\n\nimport \"context\"\n\ntype jaegerKeyType int\n\nconst (\n\tdebugKey jaegerKeyType = iota\n)\n\n// withDebug returns a copy of parent with debug set as the debug flag value .\nfunc withDebug(parent context.Context, debug bool) context.Context {\n\treturn context.WithValue(parent, debugKey, debug)\n}\n\n// debugFromContext returns the debug value stored in ctx.\n//\n// If no debug value is stored in ctx false is returned.\nfunc debugFromContext(ctx context.Context) bool {\n\tif ctx == nil {\n\t\treturn false\n\t}\n\tif debug, ok := ctx.Value(debugKey).(bool); ok {\n\t\treturn debug\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/contrib/propagators/jaeger/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// This package implements the Jaeger propagator specification as defined\n// at https://www.jaegertracing.io/docs/1.18/client-libraries/#propagation-format\npackage jaeger // import \"go.opentelemetry.io/contrib/propagators/jaeger\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/contrib/propagators/jaeger/jaeger_propagator.go",
    "content": "// Copyright The OpenTelemetry Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage jaeger\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"go.opentelemetry.io/otel/propagation\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\nconst (\n\tjaegerHeader        = \"uber-trace-id\"\n\tseparator           = \":\"\n\ttraceID64bitsWidth  = 64 / 4\n\ttraceID128bitsWidth = 128 / 4\n\tspanIDWidth         = 64 / 4\n\n\ttraceIDPadding = \"0000000000000000\"\n\n\tflagsDebug      = 0x02\n\tflagsSampled    = 0x01\n\tflagsNotSampled = 0x00\n\n\tdeprecatedParentSpanID = \"0\"\n)\n\nvar (\n\tempty = trace.SpanContext{}\n\n\terrMalformedTraceContextVal = errors.New(\"header value of uber-trace-id should contain four different part separated by : \")\n\terrInvalidTraceIDLength     = errors.New(\"invalid trace id length, must be either 16 or 32\")\n\terrMalformedTraceID         = errors.New(\"cannot decode trace id from header, should be a string of hex, lowercase trace id can't be all zero\")\n\terrInvalidSpanIDLength      = errors.New(\"invalid span id length, must be 16\")\n\terrMalformedSpanID          = errors.New(\"cannot decode span id from header, should be a string of hex, lowercase span id can't be all zero\")\n\terrMalformedFlag            = errors.New(\"cannot decode flag\")\n)\n\n// Jaeger propagator serializes SpanContext to/from Jaeger Headers\n//\n// Jaeger format:\n//\n// uber-trace-id: {trace-id}:{span-id}:{parent-span-id}:{flags}\ntype Jaeger struct{}\n\nvar _ propagation.TextMapPropagator = &Jaeger{}\n\n// Inject injects a context to the carrier following jaeger format.\n// The parent span ID is set to an dummy parent span id as the most implementations do.\nfunc (jaeger Jaeger) Inject(ctx context.Context, carrier propagation.TextMapCarrier) {\n\tsc := trace.SpanFromContext(ctx).SpanContext()\n\theaders := []string{}\n\tif !sc.TraceID().IsValid() || !sc.SpanID().IsValid() {\n\t\treturn\n\t}\n\theaders = append(headers, sc.TraceID().String(), sc.SpanID().String(), deprecatedParentSpanID)\n\tif debugFromContext(ctx) {\n\t\theaders = append(headers, fmt.Sprintf(\"%x\", flagsDebug|flagsSampled))\n\t} else if sc.IsSampled() {\n\t\theaders = append(headers, fmt.Sprintf(\"%x\", flagsSampled))\n\t} else {\n\t\theaders = append(headers, fmt.Sprintf(\"%x\", flagsNotSampled))\n\t}\n\n\tcarrier.Set(jaegerHeader, strings.Join(headers, separator))\n}\n\n// Extract extracts a context from the carrier if it contains Jaeger headers.\nfunc (jaeger Jaeger) Extract(ctx context.Context, carrier propagation.TextMapCarrier) context.Context {\n\t// extract tracing information\n\tif h := carrier.Get(jaegerHeader); h != \"\" {\n\t\tctx, sc, err := extract(ctx, h)\n\t\tif err == nil && sc.IsValid() {\n\t\t\treturn trace.ContextWithRemoteSpanContext(ctx, sc)\n\t\t}\n\t}\n\n\treturn ctx\n}\n\nfunc extract(ctx context.Context, headerVal string) (context.Context, trace.SpanContext, error) {\n\tvar (\n\t\tscc = trace.SpanContextConfig{}\n\t\terr error\n\t)\n\n\tparts := strings.Split(headerVal, separator)\n\tif len(parts) != 4 {\n\t\treturn ctx, empty, errMalformedTraceContextVal\n\t}\n\n\t// extract trace ID\n\tif parts[0] != \"\" {\n\t\tid := parts[0]\n\t\tif len(id) != traceID128bitsWidth && len(id) != traceID64bitsWidth {\n\t\t\treturn ctx, empty, errInvalidTraceIDLength\n\t\t}\n\t\t// padding when length is 16\n\t\tif len(id) == traceID64bitsWidth {\n\t\t\tid = traceIDPadding + id\n\t\t}\n\t\tscc.TraceID, err = trace.TraceIDFromHex(id)\n\t\tif err != nil {\n\t\t\treturn ctx, empty, errMalformedTraceID\n\t\t}\n\t}\n\n\t// extract span ID\n\tif parts[1] != \"\" {\n\t\tid := parts[1]\n\t\tif len(id) != spanIDWidth {\n\t\t\treturn ctx, empty, errInvalidSpanIDLength\n\t\t}\n\t\tscc.SpanID, err = trace.SpanIDFromHex(id)\n\t\tif err != nil {\n\t\t\treturn ctx, empty, errMalformedSpanID\n\t\t}\n\t}\n\n\t// skip third part as it is deprecated\n\n\t// extract flag\n\tif parts[3] != \"\" {\n\t\tflagStr := parts[3]\n\t\tflag, err := strconv.ParseInt(flagStr, 16, 64)\n\t\tif err != nil {\n\t\t\treturn ctx, empty, errMalformedFlag\n\t\t}\n\t\tif flag&flagsSampled == flagsSampled {\n\t\t\t// if sample bit is set, we check if debug bit is also set\n\t\t\tif flag&flagsDebug == flagsDebug {\n\t\t\t\tscc.TraceFlags |= trace.FlagsSampled\n\t\t\t\tctx = withDebug(ctx, true)\n\t\t\t} else {\n\t\t\t\tscc.TraceFlags |= trace.FlagsSampled\n\t\t\t}\n\t\t}\n\t\t// ignore other bit, including firehose since we don't have corresponding flag in trace context.\n\t}\n\treturn ctx, trace.NewSpanContext(scc), nil\n}\n\nfunc (jaeger Jaeger) Fields() []string {\n\treturn []string{jaegerHeader}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/.clomonitor.yml",
    "content": "exemptions:\n  - check: artifacthub_badge\n    reason: \"Artifact Hub doesn't support Go packages\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/.codespellignore",
    "content": "ot\nfo\nte\ncollison\nconsequentially\nans\nnam\nvalu\nthirdparty\naddOpt\nobserv\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/.codespellrc",
    "content": "# https://github.com/codespell-project/codespell\n[codespell]\nbuiltin = clear,rare,informal\ncheck-filenames =\ncheck-hidden =\nignore-words = .codespellignore\ninteractive = 1\nskip = .git,go.mod,go.sum,go.work,go.work.sum,semconv,venv,.tools\nuri-ignore-words-list = *\nwrite =\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/.gitattributes",
    "content": "* text=auto eol=lf\n*.{cmd,[cC][mM][dD]} text eol=crlf\n*.{bat,[bB][aA][tT]} text eol=crlf\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/.gitignore",
    "content": ".DS_Store\nThumbs.db\n\n.cache/\n.tools/\nvenv/\n.idea/\n.vscode/\n*.iml\n*.so\ncoverage.*\ngo.work\ngo.work.sum\n\ngen/\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/.golangci.yml",
    "content": "version: \"2\"\nrun:\n  issues-exit-code: 1\n  tests: true\nlinters:\n  default: none\n  enable:\n    - asasalint\n    - bodyclose\n    - depguard\n    - errcheck\n    - errorlint\n    - gocritic\n    - godot\n    - gosec\n    - govet\n    - ineffassign\n    - misspell\n    - modernize\n    - perfsprint\n    - revive\n    - staticcheck\n    - testifylint\n    - unconvert\n    - unparam\n    - unused\n    - usestdlibvars\n    - usetesting\n  settings:\n    depguard:\n      rules:\n        auto/sdk:\n          files:\n            - '!internal/global/trace.go'\n            - ~internal/global/trace_test.go\n          deny:\n            - pkg: go.opentelemetry.io/auto/sdk\n              desc: Do not use SDK from automatic instrumentation.\n        non-tests:\n          files:\n            - '!$test'\n            - '!**/*test/*.go'\n            - '!**/internal/matchers/*.go'\n          deny:\n            - pkg: testing\n            - pkg: github.com/stretchr/testify\n            - pkg: crypto/md5\n            - pkg: crypto/sha1\n            - pkg: crypto/**/pkix\n        otel-internal:\n          files:\n            - '**/sdk/*.go'\n            - '**/sdk/**/*.go'\n            - '**/exporters/*.go'\n            - '**/exporters/**/*.go'\n            - '**/schema/*.go'\n            - '**/schema/**/*.go'\n            - '**/metric/*.go'\n            - '**/metric/**/*.go'\n            - '**/bridge/*.go'\n            - '**/bridge/**/*.go'\n            - '**/trace/*.go'\n            - '**/trace/**/*.go'\n            - '**/log/*.go'\n            - '**/log/**/*.go'\n          deny:\n            - pkg: go.opentelemetry.io/otel/internal$\n              desc: Do not use cross-module internal packages.\n            - pkg: go.opentelemetry.io/otel/internal/internaltest\n              desc: Do not use cross-module internal packages.\n        otlp-internal:\n          files:\n            - '!**/exporters/otlp/internal/**/*.go'\n          deny:\n            - pkg: go.opentelemetry.io/otel/exporters/otlp/internal\n              desc: Do not use cross-module internal packages.\n        otlpmetric-internal:\n          files:\n            - '!**/exporters/otlp/otlpmetric/internal/*.go'\n            - '!**/exporters/otlp/otlpmetric/internal/**/*.go'\n          deny:\n            - pkg: go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal\n              desc: Do not use cross-module internal packages.\n        otlptrace-internal:\n          files:\n            - '!**/exporters/otlp/otlptrace/*.go'\n            - '!**/exporters/otlp/otlptrace/internal/**.go'\n          deny:\n            - pkg: go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal\n              desc: Do not use cross-module internal packages.\n    gocritic:\n      disabled-checks:\n        - appendAssign\n        - commentedOutCode\n        - dupArg\n        - hugeParam\n        - importShadow\n        - preferDecodeRune\n        - rangeValCopy\n        - unnamedResult\n        - whyNoLint\n      enable-all: true\n    godot:\n      exclude:\n        # Exclude links.\n        - '^ *\\[[^]]+\\]:'\n        # Exclude sentence fragments for lists.\n        - ^[ ]*[-•]\n        # Exclude sentences prefixing a list.\n        - :$\n    misspell:\n      locale: US\n      ignore-rules:\n        - cancelled\n    modernize:\n      disable:\n        - omitzero\n    perfsprint:\n      int-conversion: true\n      err-error: true\n      errorf: true\n      sprintf1: true\n      strconcat: true\n    revive:\n      confidence: 0.01\n      rules:\n        - name: blank-imports\n        - name: bool-literal-in-expr\n        - name: constant-logical-expr\n        - name: context-as-argument\n          arguments:\n            - allowTypesBefore: '*testing.T'\n          disabled: true\n        - name: context-keys-type\n        - name: deep-exit\n        - name: defer\n          arguments:\n            - - call-chain\n              - loop\n        - name: dot-imports\n        - name: duplicated-imports\n        - name: early-return\n          arguments:\n            - preserveScope\n        - name: empty-block\n        - name: empty-lines\n        - name: error-naming\n        - name: error-return\n        - name: error-strings\n        - name: errorf\n        - name: exported\n          arguments:\n            - sayRepetitiveInsteadOfStutters\n        - name: flag-parameter\n        - name: identical-branches\n        - name: if-return\n        - name: import-shadowing\n        - name: increment-decrement\n        - name: indent-error-flow\n          arguments:\n            - preserveScope\n        - name: package-comments\n        - name: range\n        - name: range-val-in-closure\n        - name: range-val-address\n        - name: redefines-builtin-id\n        - name: string-format\n          arguments:\n            - - panic\n              - /^[^\\n]*$/\n              - must not contain line breaks\n        - name: struct-tag\n        - name: superfluous-else\n          arguments:\n            - preserveScope\n        - name: time-equal\n        - name: unconditional-recursion\n        - name: unexported-return\n        - name: unhandled-error\n          arguments:\n            - fmt.Fprint\n            - fmt.Fprintf\n            - fmt.Fprintln\n            - fmt.Print\n            - fmt.Printf\n            - fmt.Println\n        - name: unused-parameter\n        - name: unused-receiver\n        - name: unnecessary-stmt\n        - name: use-any\n        - name: useless-break\n        - name: var-declaration\n        - name: var-naming\n          arguments:\n            - [\"ID\"] # AllowList\n            - [\"Otel\", \"Aws\", \"Gcp\"] # DenyList\n        - name: waitgroup-by-value\n    testifylint:\n      enable-all: true\n      disable:\n        - float-compare\n        - go-require\n        - require-error\n    usetesting:\n      context-background: true\n      context-todo: true\n  exclusions:\n    generated: lax\n    presets:\n      - common-false-positives\n      - legacy\n      - std-error-handling\n    rules:\n      - linters:\n          - revive\n        path: schema/v.*/types/.*\n        text: avoid meaningless package names\n      # TODO: Having appropriate comments for exported objects helps development,\n      # even for objects in internal packages. Appropriate comments for all\n      # exported objects should be added and this exclusion removed.\n      - linters:\n          - revive\n        path: .*internal/.*\n        text: exported (method|function|type|const) (.+) should have comment or be unexported\n      # Yes, they are, but it's okay in a test.\n      - linters:\n          - revive\n        path: _test\\.go\n        text: exported func.*returns unexported type.*which can be annoying to use\n      # Example test functions should be treated like main.\n      - linters:\n          - revive\n        path: example.*_test\\.go\n        text: calls to (.+) only in main[(][)] or init[(][)] functions\n      # It's okay to not run gosec and perfsprint in a test.\n      - linters:\n          - gosec\n          - perfsprint\n        path: _test\\.go\n      # Ignoring gosec G404: Use of weak random number generator (math/rand instead of crypto/rand)\n      # as we commonly use it in tests and examples.\n      - linters:\n          - gosec\n        text: 'G404:'\n      # Ignoring gosec G402: TLS MinVersion too low\n      # as the https://pkg.go.dev/crypto/tls#Config handles MinVersion default well.\n      - linters:\n          - gosec\n        text: 'G402: TLS MinVersion too low.'\nissues:\n  max-issues-per-linter: 0\n  max-same-issues: 0\nformatters:\n  enable:\n    - gofumpt\n    - goimports\n    - golines\n  settings:\n    gofumpt:\n      extra-rules: true\n    goimports:\n      local-prefixes:\n        - go.opentelemetry.io/otel\n    golines:\n      max-len: 120\n  exclusions:\n    generated: lax\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/.lycheeignore",
    "content": "http://localhost\nhttps://localhost\nhttp://jaeger-collector\nhttps://github.com/open-telemetry/opentelemetry-go/milestone/\nhttps://github.com/open-telemetry/opentelemetry-go/projects\n# Weaver model URL for semantic-conventions repository.\nhttps?:\\/\\/github\\.com\\/open-telemetry\\/semantic-conventions\\/archive\\/refs\\/tags\\/[^.]+\\.zip\\[[^]]+]\nfile:///home/runner/work/opentelemetry-go/opentelemetry-go/libraries\nfile:///home/runner/work/opentelemetry-go/opentelemetry-go/manual\nhttp://4.3.2.1:78/user/123\nfile:///home/runner/work/opentelemetry-go/opentelemetry-go/exporters/otlp/otlptrace/otlptracegrpc/internal/observ/dns:/:4317\n# URL works, but it has blocked link checkers.\nhttps://dl.acm.org/doi/10.1145/198429.198435\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/.markdownlint.yaml",
    "content": "# Default state for all rules\ndefault: true\n\n# ul-style\nMD004: false\n\n# hard-tabs\nMD010: false\n\n# line-length\nMD013: false\n\n# no-duplicate-header\nMD024:\n  siblings_only: true\n\n#single-title\nMD025: false\n\n# ol-prefix\nMD029:\n  style: ordered\n\n# no-inline-html\nMD033: false\n\n# fenced-code-language\nMD040: false\n\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).\n\nThis project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [Unreleased]\n\n<!-- Released section -->\n<!-- Don't change this section unless doing release -->\n\n## [1.40.0/0.62.0/0.16.0] 2026-02-02\n\n### Added\n\n- Add `AlwaysRecord` sampler in `go.opentelemetry.io/otel/sdk/trace`. (#7724)\n- Add `Enabled` method to all synchronous instrument interfaces (`Float64Counter`, `Float64UpDownCounter`, `Float64Histogram`, `Float64Gauge`, `Int64Counter`, `Int64UpDownCounter`, `Int64Histogram`, `Int64Gauge`,) in `go.opentelemetry.io/otel/metric`.\n  This stabilizes the synchronous instrument enabled feature, allowing users to check if an instrument will process measurements before performing computationally expensive operations. (#7763)\n- Add `go.opentelemetry.io/otel/semconv/v1.39.0` package.\n  The package contains semantic conventions from the `v1.39.0` version of the OpenTelemetry Semantic Conventions.\n  See the [migration documentation](./semconv/v1.39.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.38.0.` (#7783, #7789)\n\n### Changed\n\n- Improve the concurrent performance of `HistogramReservoir` in `go.opentelemetry.io/otel/sdk/metric/exemplar` by 4x. (#7443)\n- Improve the concurrent performance of `FixedSizeReservoir` in `go.opentelemetry.io/otel/sdk/metric/exemplar`. (#7447)\n- Improve performance of concurrent histogram measurements in `go.opentelemetry.io/otel/sdk/metric`. (#7474)\n- Improve performance of concurrent synchronous gauge measurements in `go.opentelemetry.io/otel/sdk/metric`. (#7478)\n- Add experimental observability metrics in `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric`. (#7492)\n- `Exporter` in `go.opentelemetry.io/otel/exporters/prometheus` ignores metrics with the scope `go.opentelemetry.io/contrib/bridges/prometheus`.\n  This prevents scrape failures when the Prometheus exporter is misconfigured to get data from the Prometheus bridge. (#7688)\n- Improve performance of concurrent exponential histogram measurements in `go.opentelemetry.io/otel/sdk/metric`. (#7702)\n- The `rpc.grpc.status_code` attribute in the experimental metrics emitted from `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` is replaced with the `rpc.response.status_code` attribute to align with the semantic conventions. (#7854)\n- The `rpc.grpc.status_code` attribute in the experimental metrics emitted from `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc` is replaced with the `rpc.response.status_code` attribute to align with the semantic conventions. (#7854)\n\n### Fixed\n\n- Fix bad log message when key-value pairs are dropped because of key duplication in `go.opentelemetry.io/otel/sdk/log`. (#7662)\n- Fix `DroppedAttributes` on `Record` in `go.opentelemetry.io/otel/sdk/log` to not count the non-attribute key-value pairs dropped because of key duplication. (#7662)\n- Fix `SetAttributes` on `Record` in `go.opentelemetry.io/otel/sdk/log` to not log that attributes are dropped when they are actually not dropped. (#7662)\n- Fix missing `request.GetBody` in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` to correctly handle HTTP/2 `GOAWAY` frame. (#7794)\n- `WithHostID` detector in `go.opentelemetry.io/otel/sdk/resource` to use full path for `ioreg` command on Darwin (macOS). (#7818)\n\n### Deprecated\n\n- Deprecate `go.opentelemetry.io/otel/exporters/zipkin`.\n  For more information, see the [OTel blog post deprecating the Zipkin exporter](https://opentelemetry.io/blog/2025/deprecating-zipkin-exporters/). (#7670)\n\n## [1.39.0/0.61.0/0.15.0/0.0.14] 2025-12-05\n\n### Added\n\n- Greatly reduce the cost of recording metrics in `go.opentelemetry.io/otel/sdk/metric` using hashing for map keys. (#7175)\n- Add `WithInstrumentationAttributeSet` option to `go.opentelemetry.io/otel/log`, `go.opentelemetry.io/otel/metric`, and `go.opentelemetry.io/otel/trace` packages.\n  This provides a concurrent-safe and performant alternative to `WithInstrumentationAttributes` by accepting a pre-constructed `attribute.Set`. (#7287)\n- Add experimental observability for the Prometheus exporter in `go.opentelemetry.io/otel/exporters/prometheus`.\n  Check the `go.opentelemetry.io/otel/exporters/prometheus/internal/x` package documentation for more information. (#7345)\n- Add experimental observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`. (#7353)\n- Add temporality selector functions `DeltaTemporalitySelector`, `CumulativeTemporalitySelector`, `LowMemoryTemporalitySelector` to `go.opentelemetry.io/otel/sdk/metric`. (#7434)\n- Add experimental observability metrics for simple log processor in `go.opentelemetry.io/otel/sdk/log`. (#7548)\n- Add experimental observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. (#7459)\n- Add experimental observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#7486)\n- Add experimental observability metrics for simple span processor in `go.opentelemetry.io/otel/sdk/trace`. (#7374)\n- Add experimental observability metrics in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#7512)\n- Add experimental observability metrics for manual reader in `go.opentelemetry.io/otel/sdk/metric`. (#7524)\n- Add experimental observability metrics for periodic reader in `go.opentelemetry.io/otel/sdk/metric`. (#7571)\n- Support `OTEL_EXPORTER_OTLP_LOGS_INSECURE` and `OTEL_EXPORTER_OTLP_INSECURE` environmental variables in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#7608)\n- Add `Enabled` method to the `Processor` interface in `go.opentelemetry.io/otel/sdk/log`.\n  All `Processor` implementations now include an `Enabled` method. (#7639)\n- The `go.opentelemetry.io/otel/semconv/v1.38.0` package.\n  The package contains semantic conventions from the `v1.38.0` version of the OpenTelemetry Semantic Conventions.\n  See the [migration documentation](./semconv/v1.38.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.37.0.`(#7648)\n\n### Changed\n\n- `Distinct` in `go.opentelemetry.io/otel/attribute` is no longer guaranteed to uniquely identify an attribute set.\n  Collisions between `Distinct` values for different Sets are possible with extremely high cardinality (billions of series per instrument), but are highly unlikely. (#7175)\n- `WithInstrumentationAttributes` in `go.opentelemetry.io/otel/trace` synchronously de-duplicates the passed attributes instead of delegating it to the returned `TracerOption`. (#7266)\n- `WithInstrumentationAttributes` in `go.opentelemetry.io/otel/meter` synchronously de-duplicates the passed attributes instead of delegating it to the returned `MeterOption`. (#7266)\n- `WithInstrumentationAttributes` in `go.opentelemetry.io/otel/log` synchronously de-duplicates the passed attributes instead of delegating it to the returned `LoggerOption`. (#7266)\n- Rename the `OTEL_GO_X_SELF_OBSERVABILITY` environment variable to `OTEL_GO_X_OBSERVABILITY` in `go.opentelemetry.io/otel/sdk/trace`, `go.opentelemetry.io/otel/sdk/log`, and `go.opentelemetry.io/otel/exporters/stdout/stdouttrace`. (#7302)\n- Improve performance of histogram `Record` in `go.opentelemetry.io/otel/sdk/metric` when min and max are disabled using `NoMinMax`. (#7306)\n- Improve error handling for dropped data during translation by using `prometheus.NewInvalidMetric` in `go.opentelemetry.io/otel/exporters/prometheus`.\n  ⚠️ **Breaking Change:** Previously, these cases were only logged and scrapes succeeded.\n  Now, when translation would drop data (e.g., invalid label/value), the exporter emits a `NewInvalidMetric`, and Prometheus scrapes **fail with HTTP 500** by default.\n  To preserve the prior behavior (scrapes succeed while errors are logged), configure your Prometheus HTTP handler with: `promhttp.HandlerOpts{ ErrorHandling: promhttp.ContinueOnError }`. (#7363)\n- Replace fnv hash with xxhash in `go.opentelemetry.io/otel/attribute` for better performance. (#7371)\n- The default `TranslationStrategy` in `go.opentelemetry.io/exporters/prometheus` is changed from `otlptranslator.NoUTF8EscapingWithSuffixes` to `otlptranslator.UnderscoreEscapingWithSuffixes`. (#7421)\n- Improve performance of concurrent measurements in `go.opentelemetry.io/otel/sdk/metric`. (#7427)\n- Include W3C TraceFlags (bits 0–7) in the OTLP `Span.Flags` field in `go.opentelemetry.io/exporters/otlp/otlptrace/otlptracehttp` and `go.opentelemetry.io/exporters/otlp/otlptrace/otlptracegrpc`. (#7438)\n- The `ErrorType` function in `go.opentelemetry.io/otel/semconv/v1.37.0` now handles custom error types.\n  If an error implements an `ErrorType() string` method, the return value of that method will be used as the error type. (#7442)\n\n### Fixed\n\n- Fix `WithInstrumentationAttributes` options in `go.opentelemetry.io/otel/trace`, `go.opentelemetry.io/otel/metric`, and `go.opentelemetry.io/otel/log` to properly merge attributes when passed multiple times instead of replacing them.\n  Attributes with duplicate keys will use the last value passed. (#7300)\n- The equality of `attribute.Set` when using the `Equal` method is not affected by the user overriding the empty set pointed to by `attribute.EmptySet` in `go.opentelemetry.io/otel/attribute`. (#7357)\n- Return partial OTLP export errors to the caller in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`. (#7372)\n- Return partial OTLP export errors to the caller in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#7372)\n- Return partial OTLP export errors to the caller in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#7372)\n- Return partial OTLP export errors to the caller in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#7372)\n- Return partial OTLP export errors to the caller in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. (#7372)\n- Return partial OTLP export errors to the caller in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#7372)\n- Fix `AddAttributes`, `SetAttributes`, `SetBody` on `Record` in `go.opentelemetry.io/otel/sdk/log` to not mutate input. (#7403)\n- Do not double record measurements of `RecordSet` methods in `go.opentelemetry.io/otel/semconv/v1.37.0`. (#7655)\n- Do not double record measurements of `RecordSet` methods in `go.opentelemetry.io/otel/semconv/v1.36.0`. (#7656)\n\n### Removed\n\n- Drop support for [Go 1.23]. (#7274)\n- Remove the `FilterProcessor` interface in `go.opentelemetry.io/otel/sdk/log`.\n  The `Enabled` method has been added to the `Processor` interface instead.\n  All `Processor` implementations must now implement the `Enabled` method.\n  Custom processors that do not filter records can implement `Enabled` to return `true`. (#7639)\n\n## [1.38.0/0.60.0/0.14.0/0.0.13] 2025-08-29\n\nThis release is the last to support [Go 1.23].\nThe next release will require at least [Go 1.24].\n\n### Added\n\n- Add native histogram exemplar support in `go.opentelemetry.io/otel/exporters/prometheus`. (#6772)\n- Add template attribute functions to the `go.opentelmetry.io/otel/semconv/v1.34.0` package. (#6939)\n  - `ContainerLabel`\n  - `DBOperationParameter`\n  - `DBSystemParameter`\n  - `HTTPRequestHeader`\n  - `HTTPResponseHeader`\n  - `K8SCronJobAnnotation`\n  - `K8SCronJobLabel`\n  - `K8SDaemonSetAnnotation`\n  - `K8SDaemonSetLabel`\n  - `K8SDeploymentAnnotation`\n  - `K8SDeploymentLabel`\n  - `K8SJobAnnotation`\n  - `K8SJobLabel`\n  - `K8SNamespaceAnnotation`\n  - `K8SNamespaceLabel`\n  - `K8SNodeAnnotation`\n  - `K8SNodeLabel`\n  - `K8SPodAnnotation`\n  - `K8SPodLabel`\n  - `K8SReplicaSetAnnotation`\n  - `K8SReplicaSetLabel`\n  - `K8SStatefulSetAnnotation`\n  - `K8SStatefulSetLabel`\n  - `ProcessEnvironmentVariable`\n  - `RPCConnectRPCRequestMetadata`\n  - `RPCConnectRPCResponseMetadata`\n  - `RPCGRPCRequestMetadata`\n  - `RPCGRPCResponseMetadata`\n- Add `ErrorType` attribute helper function to the `go.opentelmetry.io/otel/semconv/v1.34.0` package. (#6962)\n- Add `WithAllowKeyDuplication` in `go.opentelemetry.io/otel/sdk/log` which can be used to disable deduplication for log records. (#6968)\n- Add `WithCardinalityLimit` option to configure the cardinality limit in `go.opentelemetry.io/otel/sdk/metric`. (#6996, #7065, #7081, #7164, #7165, #7179)\n- Add `Clone` method to `Record` in `go.opentelemetry.io/otel/log` that returns a copy of the record with no shared state. (#7001)\n- Add experimental self-observability span and batch span processor metrics in `go.opentelemetry.io/otel/sdk/trace`.\n  Check the `go.opentelemetry.io/otel/sdk/trace/internal/x` package documentation for more information. (#7027, #6393, #7209)\n- The `go.opentelemetry.io/otel/semconv/v1.36.0` package.\n  The package contains semantic conventions from the `v1.36.0` version of the OpenTelemetry Semantic Conventions.\n  See the [migration documentation](./semconv/v1.36.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.34.0.`(#7032, #7041)\n- Add support for configuring Prometheus name translation using `WithTranslationStrategy` option in `go.opentelemetry.io/otel/exporters/prometheus`. The current default translation strategy when UTF-8 mode is enabled is `NoUTF8EscapingWithSuffixes`, but a future release will change the default strategy to `UnderscoreEscapingWithSuffixes` for compliance with the specification. (#7111)\n- Add experimental self-observability log metrics in `go.opentelemetry.io/otel/sdk/log`.\n  Check the `go.opentelemetry.io/otel/sdk/log/internal/x` package documentation for more information. (#7121)\n- Add experimental self-observability trace exporter metrics in `go.opentelemetry.io/otel/exporters/stdout/stdouttrace`.\n  Check the `go.opentelemetry.io/otel/exporters/stdout/stdouttrace/internal/x` package documentation for more information. (#7133)\n- Support testing of [Go 1.25]. (#7187)\n- The `go.opentelemetry.io/otel/semconv/v1.37.0` package.\n  The package contains semantic conventions from the `v1.37.0` version of the OpenTelemetry Semantic Conventions.\n  See the [migration documentation](./semconv/v1.37.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.36.0.`(#7254)\n\n### Changed\n\n- Optimize `TraceIDFromHex` and `SpanIDFromHex` in `go.opentelemetry.io/otel/sdk/trace`. (#6791)\n- Change `AssertEqual` in `go.opentelemetry.io/otel/log/logtest` to accept `TestingT` in order to support benchmarks and fuzz tests. (#6908)\n- Change `DefaultExemplarReservoirProviderSelector` in `go.opentelemetry.io/otel/sdk/metric` to use `runtime.GOMAXPROCS(0)` instead of `runtime.NumCPU()` for the `FixedSizeReservoirProvider` default size. (#7094)\n\n### Fixed\n\n- `SetBody` method of `Record` in `go.opentelemetry.io/otel/sdk/log` now deduplicates key-value collections (`log.Value` of `log.KindMap` from `go.opentelemetry.io/otel/log`). (#7002)\n- Fix `go.opentelemetry.io/otel/exporters/prometheus` to not append a suffix if it's already present in metric name. (#7088)\n- Fix the `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` self-observability component type and name. (#7195)\n- Fix partial export count metric in `go.opentelemetry.io/otel/exporters/stdout/stdouttrace`. (#7199)\n\n### Deprecated\n\n- Deprecate `WithoutUnits` and `WithoutCounterSuffixes` options, preferring `WithTranslationStrategy` instead. (#7111)\n- Deprecate support for `OTEL_GO_X_CARDINALITY_LIMIT` environment variable in `go.opentelemetry.io/otel/sdk/metric`. Use `WithCardinalityLimit` option instead. (#7166)\n\n## [0.59.1] 2025-07-21\n\n### Changed\n\n- Retract `v0.59.0` release of `go.opentelemetry.io/otel/exporters/prometheus` module which appends incorrect unit suffixes. (#7046)\n- Change `go.opentelemetry.io/otel/exporters/prometheus` to no longer deduplicate suffixes when UTF8 is enabled.\n  It is recommended to disable unit and counter suffixes in the exporter, and manually add suffixes if you rely on the existing behavior. (#7044)\n\n### Fixed\n\n- Fix `go.opentelemetry.io/otel/exporters/prometheus` to properly handle unit suffixes when the unit is in brackets.\n  E.g. `{spans}`. (#7044)\n\n## [1.37.0/0.59.0/0.13.0] 2025-06-25\n\n### Added\n\n- The `go.opentelemetry.io/otel/semconv/v1.33.0` package.\n  The package contains semantic conventions from the `v1.33.0` version of the OpenTelemetry Semantic Conventions.\n  See the [migration documentation](./semconv/v1.33.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.32.0.`(#6799)\n- The `go.opentelemetry.io/otel/semconv/v1.34.0` package.\n  The package contains semantic conventions from the `v1.34.0` version of the OpenTelemetry Semantic Conventions. (#6812)\n- Add metric's schema URL as `otel_scope_schema_url` label in `go.opentelemetry.io/otel/exporters/prometheus`. (#5947)\n- Add metric's scope attributes as `otel_scope_[attribute]` labels in `go.opentelemetry.io/otel/exporters/prometheus`. (#5947)\n- Add `EventName` to `EnabledParameters` in `go.opentelemetry.io/otel/log`. (#6825)\n- Add `EventName` to `EnabledParameters` in `go.opentelemetry.io/otel/sdk/log`. (#6825)\n- Changed handling of `go.opentelemetry.io/otel/exporters/prometheus` metric renaming to add unit suffixes when it doesn't match one of the pre-defined values in the unit suffix map. (#6839)\n\n### Changed\n\n- The semantic conventions have been upgraded from `v1.26.0` to `v1.34.0` in `go.opentelemetry.io/otel/bridge/opentracing`. (#6827)\n- The semantic conventions have been upgraded from `v1.26.0` to `v1.34.0` in `go.opentelemetry.io/otel/exporters/zipkin`. (#6829)\n- The semantic conventions have been upgraded from `v1.26.0` to `v1.34.0` in `go.opentelemetry.io/otel/metric`. (#6832)\n- The semantic conventions have been upgraded from `v1.26.0` to `v1.34.0` in `go.opentelemetry.io/otel/sdk/resource`. (#6834)\n- The semantic conventions have been upgraded from `v1.26.0` to `v1.34.0` in `go.opentelemetry.io/otel/sdk/trace`. (#6835)\n- The semantic conventions have been upgraded from `v1.26.0` to `v1.34.0` in `go.opentelemetry.io/otel/trace`. (#6836)\n- `Record.Resource` now returns `*resource.Resource` instead of `resource.Resource` in `go.opentelemetry.io/otel/sdk/log`. (#6864)\n- Retry now shows error cause for context timeout in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`, `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`, `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`, `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`, `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`, `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#6898)\n\n### Fixed\n\n- Stop stripping trailing slashes from configured endpoint URL in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. (#6710)\n- Stop stripping trailing slashes from configured endpoint URL in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#6710)\n- Stop stripping trailing slashes from configured endpoint URL in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#6710)\n- Stop stripping trailing slashes from configured endpoint URL in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#6710)\n- Validate exponential histogram scale range for Prometheus compatibility in `go.opentelemetry.io/otel/exporters/prometheus`. (#6822)\n- Context cancellation during metric pipeline produce does not corrupt data in `go.opentelemetry.io/otel/sdk/metric`. (#6914)\n\n### Removed\n\n- `go.opentelemetry.io/otel/exporters/prometheus` no longer exports `otel_scope_info` metric. (#6770)\n\n## [0.12.2] 2025-05-22\n\n### Fixed\n\n- Retract `v0.12.0` release of `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc` module that contains invalid dependencies. (#6804)\n- Retract `v0.12.0` release of `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` module that contains invalid dependencies. (#6804)\n- Retract `v0.12.0` release of `go.opentelemetry.io/otel/exporters/stdout/stdoutlog` module that contains invalid dependencies. (#6804)\n\n## [0.12.1] 2025-05-21\n\n### Fixes\n\n- Use the proper dependency version of `go.opentelemetry.io/otel/sdk/log/logtest` in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`. (#6800)\n- Use the proper dependency version of `go.opentelemetry.io/otel/sdk/log/logtest` in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#6800)\n- Use the proper dependency version of `go.opentelemetry.io/otel/sdk/log/logtest` in `go.opentelemetry.io/otel/exporters/stdout/stdoutlog`. (#6800)\n\n## [1.36.0/0.58.0/0.12.0] 2025-05-20\n\n### Added\n\n- Add exponential histogram support in `go.opentelemetry.io/otel/exporters/prometheus`. (#6421)\n- The `go.opentelemetry.io/otel/semconv/v1.31.0` package.\n  The package contains semantic conventions from the `v1.31.0` version of the OpenTelemetry Semantic Conventions.\n  See the [migration documentation](./semconv/v1.31.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.30.0`. (#6479)\n- Add `Recording`, `Scope`, and `Record` types in `go.opentelemetry.io/otel/log/logtest`. (#6507)\n- Add `WithHTTPClient` option to configure the `http.Client` used by `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#6751)\n- Add `WithHTTPClient` option to configure the `http.Client` used by `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#6752)\n- Add `WithHTTPClient` option to configure the `http.Client` used by `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#6688)\n- Add `ValuesGetter` in `go.opentelemetry.io/otel/propagation`, a `TextMapCarrier` that supports retrieving multiple values for a single key. (#5973)\n- Add `Values` method to `HeaderCarrier` to implement the new `ValuesGetter` interface in `go.opentelemetry.io/otel/propagation`. (#5973)\n- Update `Baggage` in `go.opentelemetry.io/otel/propagation` to retrieve multiple values for a key when the carrier implements `ValuesGetter`. (#5973)\n- Add `AssertEqual` function in `go.opentelemetry.io/otel/log/logtest`. (#6662)\n- The `go.opentelemetry.io/otel/semconv/v1.32.0` package.\n  The package contains semantic conventions from the `v1.32.0` version of the OpenTelemetry Semantic Conventions.\n  See the [migration documentation](./semconv/v1.32.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.31.0`(#6782)\n- Add `Transform` option in `go.opentelemetry.io/otel/log/logtest`. (#6794)\n- Add `Desc` option in `go.opentelemetry.io/otel/log/logtest`. (#6796)\n\n### Removed\n\n- Drop support for [Go 1.22]. (#6381, #6418)\n- Remove `Resource` field from `EnabledParameters` in `go.opentelemetry.io/otel/sdk/log`. (#6494)\n- Remove `RecordFactory` type from `go.opentelemetry.io/otel/log/logtest`. (#6492)\n- Remove `ScopeRecords`, `EmittedRecord`, and `RecordFactory` types from `go.opentelemetry.io/otel/log/logtest`. (#6507)\n- Remove `AssertRecordEqual` function in `go.opentelemetry.io/otel/log/logtest`, use `AssertEqual` instead. (#6662)\n\n### Changed\n\n- ⚠️ Update `github.com/prometheus/client_golang` to `v1.21.1`, which changes the `NameValidationScheme` to `UTF8Validation`.\n  This allows metrics names to keep original delimiters (e.g. `.`), rather than replacing with underscores.\n  This can be reverted by setting `github.com/prometheus/common/model.NameValidationScheme` to `LegacyValidation` in `github.com/prometheus/common/model`. (#6433)\n- Initialize map with `len(keys)` in `NewAllowKeysFilter` and `NewDenyKeysFilter` to avoid unnecessary allocations in `go.opentelemetry.io/otel/attribute`. (#6455)\n- `go.opentelemetry.io/otel/log/logtest` is now a separate Go module. (#6465)\n- `go.opentelemetry.io/otel/sdk/log/logtest` is now a separate Go module. (#6466)\n- `Recorder` in `go.opentelemetry.io/otel/log/logtest` no longer separately stores records emitted by loggers with the same instrumentation scope. (#6507)\n- Improve performance of `BatchProcessor` in `go.opentelemetry.io/otel/sdk/log` by not exporting when exporter cannot accept more. (#6569, #6641)\n\n### Deprecated\n\n- Deprecate support for `model.LegacyValidation` for `go.opentelemetry.io/otel/exporters/prometheus`. (#6449)\n\n### Fixes\n\n- Stop percent encoding header environment variables in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#6392)\n- Ensure the `noopSpan.tracerProvider` method is not inlined in `go.opentelemetry.io/otel/trace` so the `go.opentelemetry.io/auto` instrumentation can instrument non-recording spans. (#6456)\n- Use a `sync.Pool` instead of allocating `metricdata.ResourceMetrics` in `go.opentelemetry.io/otel/exporters/prometheus`. (#6472)\n\n## [1.35.0/0.57.0/0.11.0] 2025-03-05\n\nThis release is the last to support [Go 1.22].\nThe next release will require at least [Go 1.23].\n\n### Added\n\n- Add `ValueFromAttribute` and `KeyValueFromAttribute` in `go.opentelemetry.io/otel/log`. (#6180)\n- Add `EventName` and `SetEventName` to `Record` in `go.opentelemetry.io/otel/log`. (#6187)\n- Add `EventName` to `RecordFactory` in `go.opentelemetry.io/otel/log/logtest`. (#6187)\n- `AssertRecordEqual` in `go.opentelemetry.io/otel/log/logtest` checks `Record.EventName`. (#6187)\n- Add `EventName` and `SetEventName` to `Record` in `go.opentelemetry.io/otel/sdk/log`. (#6193)\n- Add `EventName` to `RecordFactory` in `go.opentelemetry.io/otel/sdk/log/logtest`. (#6193)\n- Emit `Record.EventName` field in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`. (#6211)\n- Emit `Record.EventName` field in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#6211)\n- Emit `Record.EventName` field in `go.opentelemetry.io/otel/exporters/stdout/stdoutlog` (#6210)\n- The `go.opentelemetry.io/otel/semconv/v1.28.0` package.\n  The package contains semantic conventions from the `v1.28.0` version of the OpenTelemetry Semantic Conventions.\n  See the [migration documentation](./semconv/v1.28.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.27.0`(#6236)\n- The `go.opentelemetry.io/otel/semconv/v1.30.0` package.\n  The package contains semantic conventions from the `v1.30.0` version of the OpenTelemetry Semantic Conventions.\n  See the [migration documentation](./semconv/v1.30.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.28.0`(#6240)\n- Document the pitfalls of using `Resource` as a comparable type.\n  `Resource.Equal` and `Resource.Equivalent` should be used instead. (#6272)\n- Support [Go 1.24]. (#6304)\n- Add `FilterProcessor` and `EnabledParameters` in `go.opentelemetry.io/otel/sdk/log`.\n  It replaces `go.opentelemetry.io/otel/sdk/log/internal/x.FilterProcessor`.\n  Compared to previous version it additionally gives the possibility to filter by resource and instrumentation scope. (#6317)\n\n### Changed\n\n- Update `github.com/prometheus/common` to `v0.62.0`, which changes the `NameValidationScheme` to `NoEscaping`.\n  This allows metrics names to keep original delimiters (e.g. `.`), rather than replacing with underscores.\n  This is controlled by the `Content-Type` header, or can be reverted by setting `NameValidationScheme` to `LegacyValidation` in `github.com/prometheus/common/model`. (#6198)\n\n### Fixes\n\n- Eliminate goroutine leak for the processor returned by `NewSimpleSpanProcessor` in `go.opentelemetry.io/otel/sdk/trace` when `Shutdown` is called and the passed `ctx` is canceled and `SpanExporter.Shutdown` has not returned. (#6368)\n- Eliminate goroutine leak for the processor returned by `NewBatchSpanProcessor` in `go.opentelemetry.io/otel/sdk/trace` when `ForceFlush` is called and the passed `ctx` is canceled and `SpanExporter.Export` has not returned. (#6369)\n\n## [1.34.0/0.56.0/0.10.0] 2025-01-17\n\n### Changed\n\n- Remove the notices from `Logger` to make the whole Logs API user-facing in `go.opentelemetry.io/otel/log`. (#6167)\n\n### Fixed\n\n- Relax minimum Go version to 1.22.0 in various modules. (#6073)\n- The `Type` name logged for the `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` client is corrected from `otlphttpgrpc` to `otlptracegrpc`. (#6143)\n- The `Type` name logged for the `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlphttpgrpc` client is corrected from `otlphttphttp` to `otlptracehttp`. (#6143)\n\n## [1.33.0/0.55.0/0.9.0/0.0.12] 2024-12-12\n\n### Added\n\n- Add `Reset` method to `SpanRecorder` in `go.opentelemetry.io/otel/sdk/trace/tracetest`. (#5994)\n- Add `EnabledInstrument` interface in `go.opentelemetry.io/otel/sdk/metric/internal/x`.\n  This is an experimental interface that is implemented by synchronous instruments provided by `go.opentelemetry.io/otel/sdk/metric`.\n  Users can use it to avoid performing computationally expensive operations when recording measurements.\n  It does not fall within the scope of the OpenTelemetry Go versioning and stability [policy](./VERSIONING.md) and it may be changed in backwards incompatible ways or removed in feature releases. (#6016)\n\n### Changed\n\n- The default global API now supports full auto-instrumentation from the `go.opentelemetry.io/auto` package.\n  See that package for more information. (#5920)\n- Propagate non-retryable error messages to client in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#5929)\n- Propagate non-retryable error messages to client in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#5929)\n- Propagate non-retryable error messages to client in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#5929)\n- Performance improvements for attribute value `AsStringSlice`, `AsFloat64Slice`, `AsInt64Slice`, `AsBoolSlice`. (#6011)\n- Change `EnabledParameters` to have a `Severity` field instead of a getter and setter in `go.opentelemetry.io/otel/log`. (#6009)\n\n### Fixed\n\n- Fix inconsistent request body closing in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#5954)\n- Fix inconsistent request body closing in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#5954)\n- Fix inconsistent request body closing in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#5954)\n- Fix invalid exemplar keys in `go.opentelemetry.io/otel/exporters/prometheus`. (#5995)\n- Fix attribute value truncation in `go.opentelemetry.io/otel/sdk/trace`. (#5997)\n- Fix attribute value truncation in `go.opentelemetry.io/otel/sdk/log`. (#6032)\n\n## [1.32.0/0.54.0/0.8.0/0.0.11] 2024-11-08\n\n### Added\n\n- Add `go.opentelemetry.io/otel/sdk/metric/exemplar.AlwaysOffFilter`, which can be used to disable exemplar recording. (#5850)\n- Add `go.opentelemetry.io/otel/sdk/metric.WithExemplarFilter`, which can be used to configure the exemplar filter used by the metrics SDK. (#5850)\n- Add `ExemplarReservoirProviderSelector` and `DefaultExemplarReservoirProviderSelector` to `go.opentelemetry.io/otel/sdk/metric`, which defines the exemplar reservoir to use based on the aggregation of the metric. (#5861)\n- Add `ExemplarReservoirProviderSelector` to `go.opentelemetry.io/otel/sdk/metric.Stream` to allow using views to configure the exemplar reservoir to use for a metric. (#5861)\n- Add `ReservoirProvider`, `HistogramReservoirProvider` and `FixedSizeReservoirProvider` to `go.opentelemetry.io/otel/sdk/metric/exemplar` to make it convenient to use providers of Reservoirs. (#5861)\n- The `go.opentelemetry.io/otel/semconv/v1.27.0` package.\n  The package contains semantic conventions from the `v1.27.0` version of the OpenTelemetry Semantic Conventions. (#5894)\n- Add `Attributes attribute.Set` field to `Scope` in `go.opentelemetry.io/otel/sdk/instrumentation`. (#5903)\n- Add `Attributes attribute.Set` field to `ScopeRecords` in `go.opentelemetry.io/otel/log/logtest`. (#5927)\n- `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` adds instrumentation scope attributes. (#5934)\n- `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` adds instrumentation scope attributes. (#5934)\n- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` adds instrumentation scope attributes. (#5935)\n- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` adds instrumentation scope attributes. (#5935)\n- `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc` adds instrumentation scope attributes. (#5933)\n- `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` adds instrumentation scope attributes. (#5933)\n- `go.opentelemetry.io/otel/exporters/prometheus` adds instrumentation scope attributes in `otel_scope_info` metric as labels. (#5932)\n\n### Changed\n\n- Support scope attributes and make them as identifying for `Tracer` in `go.opentelemetry.io/otel` and `go.opentelemetry.io/otel/sdk/trace`. (#5924)\n- Support scope attributes and make them as identifying for `Meter` in `go.opentelemetry.io/otel` and `go.opentelemetry.io/otel/sdk/metric`. (#5926)\n- Support scope attributes and make them as identifying for `Logger` in `go.opentelemetry.io/otel` and `go.opentelemetry.io/otel/sdk/log`. (#5925)\n- Make schema URL and scope attributes as identifying for `Tracer` in `go.opentelemetry.io/otel/bridge/opentracing`. (#5931)\n- Clear unneeded slice elements to allow GC to collect the objects in `go.opentelemetry.io/otel/sdk/metric` and `go.opentelemetry.io/otel/sdk/trace`. (#5804)\n\n### Fixed\n\n- Global MeterProvider registration unwraps global instrument Observers, the undocumented Unwrap() methods are now private. (#5881)\n- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` now keeps the metadata already present in the context when `WithHeaders` is used. (#5892)\n- `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc` now keeps the metadata already present in the context when `WithHeaders` is used. (#5911)\n- `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` now keeps the metadata already present in the context when `WithHeaders` is used. (#5915)\n- Fix `go.opentelemetry.io/otel/exporters/prometheus` trying to add exemplars to Gauge metrics, which is unsupported. (#5912)\n- Fix `WithEndpointURL` to always use a secure connection when an https URL is passed in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#5944)\n- Fix `WithEndpointURL` to always use a secure connection when an https URL is passed in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#5944)\n- Fix `WithEndpointURL` to always use a secure connection when an https URL is passed in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. (#5944)\n- Fix `WithEndpointURL` to always use a secure connection when an https URL is passed in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#5944)\n- Fix incorrect metrics generated from callbacks when multiple readers are used in `go.opentelemetry.io/otel/sdk/metric`. (#5900)\n\n### Removed\n\n- Remove all examples under `go.opentelemetry.io/otel/example` as they are moved to [Contrib repository](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/examples). (#5930)\n\n## [1.31.0/0.53.0/0.7.0/0.0.10] 2024-10-11\n\n### Added\n\n- Add `go.opentelemetry.io/otel/sdk/metric/exemplar` package which includes `Exemplar`, `Filter`, `TraceBasedFilter`, `AlwaysOnFilter`, `HistogramReservoir`, `FixedSizeReservoir`, `Reservoir`, `Value` and `ValueType` types. These will be used for configuring the exemplar reservoir for the metrics sdk. (#5747, #5862)\n- Add `WithExportBufferSize` option to log batch processor.(#5877)\n\n### Changed\n\n- Enable exemplars by default in `go.opentelemetry.io/otel/sdk/metric`. Exemplars can be disabled by setting `OTEL_METRICS_EXEMPLAR_FILTER=always_off` (#5778)\n- `Logger.Enabled` in `go.opentelemetry.io/otel/log` now accepts a newly introduced `EnabledParameters` type instead of `Record`. (#5791)\n- `FilterProcessor.Enabled` in `go.opentelemetry.io/otel/sdk/log/internal/x` now accepts `EnabledParameters` instead of `Record`. (#5791)\n- The `Record` type in `go.opentelemetry.io/otel/log` is no longer comparable. (#5847)\n- Performance improvements for the trace SDK `SetAttributes` method in `Span`. (#5864)\n- Reduce memory allocations for the `Event` and `Link` lists in `Span`. (#5858)\n- Performance improvements for the trace SDK `AddEvent`, `AddLink`, `RecordError` and `End` methods in `Span`. (#5874)\n\n### Deprecated\n\n- Deprecate all examples under `go.opentelemetry.io/otel/example` as they are moved to [Contrib repository](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/examples). (#5854)\n\n### Fixed\n\n- The race condition for multiple `FixedSize` exemplar reservoirs identified in #5814 is resolved. (#5819)\n- Fix log records duplication in case of heterogeneous resource attributes by correctly mapping each log record to it's resource and scope. (#5803)\n- Fix timer channel drain to avoid hanging on Go 1.23. (#5868)\n- Fix delegation for global meter providers, and panic when calling otel.SetMeterProvider. (#5827)\n- Change the `reflect.TypeOf` to use a nil pointer to not allocate on the heap unless necessary. (#5827)\n\n## [1.30.0/0.52.0/0.6.0/0.0.9] 2024-09-09\n\n### Added\n\n- Support `OTEL_EXPORTER_OTLP_LOGS_INSECURE` and `OTEL_EXPORTER_OTLP_INSECURE` environments in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`. (#5739)\n- The `WithResource` option for `NewMeterProvider` now merges the provided resources with the ones from environment variables. (#5773)\n- The `WithResource` option for `NewLoggerProvider` now merges the provided resources with the ones from environment variables. (#5773)\n- Add UTF-8 support to `go.opentelemetry.io/otel/exporters/prometheus`. (#5755)\n\n### Fixed\n\n- Fix memory leak in the global `MeterProvider` when identical instruments are repeatedly created. (#5754)\n- Fix panic on instruments creation when setting meter provider. (#5758)\n- Fix an issue where `SetMeterProvider` in `go.opentelemetry.io/otel` might miss the delegation for instruments and registries. (#5780)\n\n### Removed\n\n- Drop support for [Go 1.21]. (#5736, #5740, #5800)\n\n## [1.29.0/0.51.0/0.5.0] 2024-08-23\n\nThis release is the last to support [Go 1.21].\nThe next release will require at least [Go 1.22].\n\n### Added\n\n- Add MacOS ARM64 platform to the compatibility testing suite. (#5577)\n- Add `InstrumentationScope` field to `SpanStub` in `go.opentelemetry.io/otel/sdk/trace/tracetest`, as a replacement for the deprecated `InstrumentationLibrary`. (#5627)\n- Make the initial release of `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`.\n  This new module contains an OTLP exporter that transmits log telemetry using gRPC.\n  This module is unstable and breaking changes may be introduced.\n  See our [versioning policy](VERSIONING.md) for more information about these stability guarantees. (#5629)\n- Add `Walk` function to `TraceState` in `go.opentelemetry.io/otel/trace` to iterate all the key-value pairs. (#5651)\n- Bridge the trace state in `go.opentelemetry.io/otel/bridge/opencensus`. (#5651)\n- Zero value of `SimpleProcessor` in `go.opentelemetry.io/otel/sdk/log` no longer panics. (#5665)\n- The `FilterProcessor` interface type is added in `go.opentelemetry.io/otel/sdk/log/internal/x`.\n  This is an optional and experimental interface that log `Processor`s can implement to instruct the `Logger` if a `Record` will be processed or not.\n  It replaces the existing `Enabled` method that is removed from the `Processor` interface itself.\n  It does not fall within the scope of the OpenTelemetry Go versioning and stability [policy](./VERSIONING.md) and it may be changed in backwards incompatible ways or removed in feature releases. (#5692)\n- Support [Go 1.23]. (#5720)\n\n### Changed\n\n- `NewMemberRaw`, `NewKeyProperty` and `NewKeyValuePropertyRaw` in `go.opentelemetry.io/otel/baggage` allow UTF-8 string in key. (#5132)\n- `Processor.OnEmit` in `go.opentelemetry.io/otel/sdk/log` now accepts a pointer to `Record` instead of a value so that the record modifications done in a processor are propagated to subsequent registered processors. (#5636)\n- `SimpleProcessor.Enabled` in `go.opentelemetry.io/otel/sdk/log` now returns `false` if the exporter is `nil`. (#5665)\n- Update the concurrency requirements of `Exporter` in `go.opentelemetry.io/otel/sdk/log`. (#5666)\n- `SimpleProcessor` in `go.opentelemetry.io/otel/sdk/log` synchronizes `OnEmit` calls. (#5666)\n- The `Processor` interface in `go.opentelemetry.io/otel/sdk/log` no longer includes the `Enabled` method.\n  See the `FilterProcessor` interface type added in `go.opentelemetry.io/otel/sdk/log/internal/x` to continue providing this functionality. (#5692)\n- The `SimpleProcessor` type in `go.opentelemetry.io/otel/sdk/log` is no longer comparable. (#5693)\n- The `BatchProcessor` type in `go.opentelemetry.io/otel/sdk/log` is no longer comparable. (#5693)\n\n### Fixed\n\n- Correct comments for the priority of the `WithEndpoint` and `WithEndpointURL` options and their corresponding environment variables in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#5584)\n- Pass the underlying error rather than a generic retry-able failure in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`, `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` and `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#5541)\n- Correct the `Tracer`, `Meter`, and `Logger` names used in `go.opentelemetry.io/otel/example/dice`. (#5612)\n- Correct the `Tracer` names used in `go.opentelemetry.io/otel/example/namedtracer`. (#5612)\n- Correct the `Tracer` name used in `go.opentelemetry.io/otel/example/opencensus`. (#5612)\n- Correct the `Tracer` and `Meter` names used in `go.opentelemetry.io/otel/example/otel-collector`. (#5612)\n- Correct the `Tracer` names used in `go.opentelemetry.io/otel/example/passthrough`. (#5612)\n- Correct the `Meter` name used in `go.opentelemetry.io/otel/example/prometheus`. (#5612)\n- Correct the `Tracer` names used in `go.opentelemetry.io/otel/example/zipkin`. (#5612)\n- Correct comments for the priority of the `WithEndpoint` and `WithEndpointURL` options and their corresponding environment variables in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#5641)\n- Correct comments for the priority of the `WithEndpoint` and `WithEndpointURL` options and their corresponding environment variables in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#5650)\n- Stop percent encoding header environment variables in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`, `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`, `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` (#5705)\n- Remove invalid environment variable header keys in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`, `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`, `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` (#5705)\n\n### Removed\n\n- The `Enabled` method of the `SimpleProcessor` in `go.opentelemetry.io/otel/sdk/log` is removed. (#5692)\n- The `Enabled` method of the `BatchProcessor` in `go.opentelemetry.io/otel/sdk/log` is removed. (#5692)\n\n## [1.28.0/0.50.0/0.4.0] 2024-07-02\n\n### Added\n\n- The `IsEmpty` method is added to the `Instrument` type in `go.opentelemetry.io/otel/sdk/metric`.\n  This method is used to check if an `Instrument` instance is a zero-value. (#5431)\n- Store and provide the emitted `context.Context` in `ScopeRecords` of `go.opentelemetry.io/otel/sdk/log/logtest`. (#5468)\n- The `go.opentelemetry.io/otel/semconv/v1.26.0` package.\n  The package contains semantic conventions from the `v1.26.0` version of the OpenTelemetry Semantic Conventions. (#5476)\n- The `AssertRecordEqual` method to `go.opentelemetry.io/otel/log/logtest` to allow comparison of two log records in tests. (#5499)\n- The `WithHeaders` option to `go.opentelemetry.io/otel/exporters/zipkin` to allow configuring custom http headers while exporting spans. (#5530)\n\n### Changed\n\n- `Tracer.Start` in `go.opentelemetry.io/otel/trace/noop` no longer allocates a span for empty span context. (#5457)\n- Upgrade `go.opentelemetry.io/otel/semconv/v1.25.0` to `go.opentelemetry.io/otel/semconv/v1.26.0` in `go.opentelemetry.io/otel/example/otel-collector`. (#5490)\n- Upgrade `go.opentelemetry.io/otel/semconv/v1.25.0` to `go.opentelemetry.io/otel/semconv/v1.26.0` in `go.opentelemetry.io/otel/example/zipkin`. (#5490)\n- Upgrade `go.opentelemetry.io/otel/semconv/v1.25.0` to `go.opentelemetry.io/otel/semconv/v1.26.0` in `go.opentelemetry.io/otel/exporters/zipkin`. (#5490)\n  - The exporter no longer exports the deprecated \"otel.library.name\" or \"otel.library.version\" attributes.\n- Upgrade `go.opentelemetry.io/otel/semconv/v1.25.0` to `go.opentelemetry.io/otel/semconv/v1.26.0` in `go.opentelemetry.io/otel/sdk/resource`. (#5490)\n- Upgrade `go.opentelemetry.io/otel/semconv/v1.25.0` to `go.opentelemetry.io/otel/semconv/v1.26.0` in `go.opentelemetry.io/otel/sdk/trace`. (#5490)\n- `SimpleProcessor.OnEmit` in `go.opentelemetry.io/otel/sdk/log` no longer allocates a slice which makes it possible to have a zero-allocation log processing using `SimpleProcessor`. (#5493)\n- Use non-generic functions in the `Start` method of `\"go.opentelemetry.io/otel/sdk/trace\".Trace` to reduce memory allocation. (#5497)\n- `service.instance.id` is populated for a `Resource` created with `\"go.opentelemetry.io/otel/sdk/resource\".Default` with a default value when `OTEL_GO_X_RESOURCE` is set. (#5520)\n- Improve performance of metric instruments in `go.opentelemetry.io/otel/sdk/metric` by removing unnecessary calls to `time.Now`. (#5545)\n\n### Fixed\n\n- Log a warning to the OpenTelemetry internal logger when a `Record` in `go.opentelemetry.io/otel/sdk/log` drops an attribute due to a limit being reached. (#5376)\n- Identify the `Tracer` returned from the global `TracerProvider` in `go.opentelemetry.io/otel/global` with its schema URL. (#5426)\n- Identify the `Meter` returned from the global `MeterProvider` in `go.opentelemetry.io/otel/global` with its schema URL. (#5426)\n- Log a warning to the OpenTelemetry internal logger when a `Span` in `go.opentelemetry.io/otel/sdk/trace` drops an attribute, event, or link due to a limit being reached. (#5434)\n- Document instrument name requirements in `go.opentelemetry.io/otel/metric`. (#5435)\n- Prevent random number generation data-race for experimental rand exemplars in `go.opentelemetry.io/otel/sdk/metric`. (#5456)\n- Fix counting number of dropped attributes of `Record` in `go.opentelemetry.io/otel/sdk/log`. (#5464)\n- Fix panic in baggage creation when a member contains `0x80` char in key or value. (#5494)\n- Correct comments for the priority of the `WithEndpoint` and `WithEndpointURL` options and their corresponding environment variables in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. (#5508)\n- Retry trace and span ID generation if it generated an invalid one in `go.opentelemetry.io/otel/sdk/trace`. (#5514)\n- Fix stale timestamps reported by the last-value aggregation. (#5517)\n- Indicate the `Exporter` in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` must be created by the `New` method. (#5521)\n- Improved performance in all `{Bool,Int64,Float64,String}SliceValue` functions of `go.opentelemetry.io/attributes` by reducing the number of allocations. (#5549)\n- Replace invalid percent-encoded octet sequences with replacement char in `go.opentelemetry.io/otel/baggage`. (#5528)\n\n## [1.27.0/0.49.0/0.3.0] 2024-05-21\n\n### Added\n\n- Add example for `go.opentelemetry.io/otel/exporters/stdout/stdoutlog`. (#5242)\n- Add `RecordFactory` in `go.opentelemetry.io/otel/sdk/log/logtest` to facilitate testing exporter and processor implementations. (#5258)\n- Add `RecordFactory` in `go.opentelemetry.io/otel/log/logtest` to facilitate testing bridge implementations. (#5263)\n- The count of dropped records from the `BatchProcessor` in `go.opentelemetry.io/otel/sdk/log` is logged. (#5276)\n- Add metrics in the `otel-collector` example. (#5283)\n- Add the synchronous gauge instrument to `go.opentelemetry.io/otel/metric`. (#5304)\n  - An `int64` or `float64` synchronous gauge instrument can now be created from a `Meter`.\n  - All implementations of the API (`go.opentelemetry.io/otel/metric/noop`, `go.opentelemetry.io/otel/sdk/metric`) are updated to support this instrument.\n- Add logs to `go.opentelemetry.io/otel/example/dice`. (#5349)\n\n### Changed\n\n- The `Shutdown` method of `Exporter` in `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` ignores the context cancellation and always returns `nil`. (#5189)\n- The `ForceFlush` and `Shutdown` methods of the exporter returned by `New` in `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` ignore the context cancellation and always return `nil`. (#5189)\n- Apply the value length limits to `Record` attributes in `go.opentelemetry.io/otel/sdk/log`. (#5230)\n- De-duplicate map attributes added to a `Record` in `go.opentelemetry.io/otel/sdk/log`. (#5230)\n- `go.opentelemetry.io/otel/exporters/stdout/stdoutlog` won't print timestamps when `WithoutTimestamps` option is set. (#5241)\n- The `go.opentelemetry.io/otel/exporters/stdout/stdoutlog` exporter won't print `AttributeValueLengthLimit` and `AttributeCountLimit` fields now, instead it prints the `DroppedAttributes` field. (#5272)\n- Improved performance in the `Stringer` implementation of `go.opentelemetry.io/otel/baggage.Member` by reducing the number of allocations. (#5286)\n- Set the start time for last-value aggregates in `go.opentelemetry.io/otel/sdk/metric`. (#5305)\n- The `Span` in `go.opentelemetry.io/otel/sdk/trace` will record links without span context if either non-empty `TraceState` or attributes are provided. (#5315)\n- Upgrade all dependencies of `go.opentelemetry.io/otel/semconv/v1.24.0` to `go.opentelemetry.io/otel/semconv/v1.25.0`. (#5374)\n\n### Fixed\n\n- Comparison of unordered maps for `go.opentelemetry.io/otel/log.KeyValue` and `go.opentelemetry.io/otel/log.Value`. (#5306)\n- Fix the empty output of `go.opentelemetry.io/otel/log.Value` in `go.opentelemetry.io/otel/exporters/stdout/stdoutlog`. (#5311)\n- Split the behavior of `Recorder` in `go.opentelemetry.io/otel/log/logtest` so it behaves as a `LoggerProvider` only. (#5365)\n- Fix wrong package name of the error message when parsing endpoint URL in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#5371)\n- Identify the `Logger` returned from the global `LoggerProvider` in `go.opentelemetry.io/otel/log/global` with its schema URL. (#5375)\n\n## [1.26.0/0.48.0/0.2.0-alpha] 2024-04-24\n\n### Added\n\n- Add `Recorder` in `go.opentelemetry.io/otel/log/logtest` to facilitate testing the log bridge implementations. (#5134)\n- Add span flags to OTLP spans and links exported by `go.opentelemetry.io/otel/exporters/otlp/otlptrace`. (#5194)\n- Make the initial alpha release of `go.opentelemetry.io/otel/sdk/log`.\n  This new module contains the Go implementation of the OpenTelemetry Logs SDK.\n  This module is unstable and breaking changes may be introduced.\n  See our [versioning policy](VERSIONING.md) for more information about these stability guarantees. (#5240)\n- Make the initial alpha release of `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`.\n  This new module contains an OTLP exporter that transmits log telemetry using HTTP.\n  This module is unstable and breaking changes may be introduced.\n  See our [versioning policy](VERSIONING.md) for more information about these stability guarantees. (#5240)\n- Make the initial alpha release of `go.opentelemetry.io/otel/exporters/stdout/stdoutlog`.\n  This new module contains an exporter prints log records to STDOUT.\n  This module is unstable and breaking changes may be introduced.\n  See our [versioning policy](VERSIONING.md) for more information about these stability guarantees. (#5240)\n- The `go.opentelemetry.io/otel/semconv/v1.25.0` package.\n  The package contains semantic conventions from the `v1.25.0` version of the OpenTelemetry Semantic Conventions. (#5254)\n\n### Changed\n\n- Update `go.opentelemetry.io/proto/otlp` from v1.1.0 to v1.2.0. (#5177)\n- Improve performance of baggage member character validation in `go.opentelemetry.io/otel/baggage`. (#5214)\n- The `otel-collector` example now uses docker compose to bring up services instead of kubernetes. (#5244)\n\n### Fixed\n\n- Slice attribute values in `go.opentelemetry.io/otel/attribute` are now emitted as their JSON representation. (#5159)\n\n## [1.25.0/0.47.0/0.0.8/0.1.0-alpha] 2024-04-05\n\n### Added\n\n- Add `WithProxy` option in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4906)\n- Add `WithProxy` option in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlptracehttp`. (#4906)\n- Add `AddLink` method to the `Span` interface in `go.opentelemetry.io/otel/trace`. (#5032)\n- The `Enabled` method is added to the `Logger` interface in `go.opentelemetry.io/otel/log`.\n  This method is used to notify users if a log record will be emitted or not. (#5071)\n- Add `SeverityUndefined` `const` to `go.opentelemetry.io/otel/log`.\n  This value represents an unset severity level. (#5072)\n- Add `Empty` function in `go.opentelemetry.io/otel/log` to return a `KeyValue` for an empty value. (#5076)\n- Add `go.opentelemetry.io/otel/log/global` to manage the global `LoggerProvider`.\n  This package is provided with the anticipation that all functionality will be migrate to `go.opentelemetry.io/otel` when `go.opentelemetry.io/otel/log` stabilizes.\n  At which point, users will be required to migrage their code, and this package will be deprecated then removed. (#5085)\n- Add support for `Summary` metrics in the `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` exporters. (#5100)\n- Add `otel.scope.name` and `otel.scope.version` tags to spans exported by `go.opentelemetry.io/otel/exporters/zipkin`. (#5108)\n- Add support for `AddLink` to `go.opentelemetry.io/otel/bridge/opencensus`. (#5116)\n- Add `String` method to `Value` and `KeyValue` in `go.opentelemetry.io/otel/log`. (#5117)\n- Add Exemplar support to `go.opentelemetry.io/otel/exporters/prometheus`. (#5111)\n- Add metric semantic conventions to `go.opentelemetry.io/otel/semconv/v1.24.0`. Future `semconv` packages will include metric semantic conventions as well. (#4528)\n\n### Changed\n\n- `SpanFromContext` and `SpanContextFromContext` in `go.opentelemetry.io/otel/trace` no longer make a heap allocation when the passed context has no span. (#5049)\n- `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` now create a gRPC client in idle mode and with \"dns\" as the default resolver using [`grpc.NewClient`](https://pkg.go.dev/google.golang.org/grpc#NewClient). (#5151)\n  Because of that `WithDialOption` ignores [`grpc.WithBlock`](https://pkg.go.dev/google.golang.org/grpc#WithBlock), [`grpc.WithTimeout`](https://pkg.go.dev/google.golang.org/grpc#WithTimeout), and [`grpc.WithReturnConnectionError`](https://pkg.go.dev/google.golang.org/grpc#WithReturnConnectionError).\n  Notice that [`grpc.DialContext`](https://pkg.go.dev/google.golang.org/grpc#DialContext) which was used before is now deprecated.\n\n### Fixed\n\n- Clarify the documentation about equivalence guarantees for the `Set` and `Distinct` types in `go.opentelemetry.io/otel/attribute`. (#5027)\n- Prevent default `ErrorHandler` self-delegation. (#5137)\n- Update all dependencies to address [GO-2024-2687]. (#5139)\n\n### Removed\n\n- Drop support for [Go 1.20]. (#4967)\n\n### Deprecated\n\n- Deprecate `go.opentelemetry.io/otel/attribute.Sortable` type. (#4734)\n- Deprecate `go.opentelemetry.io/otel/attribute.NewSetWithSortable` function. (#4734)\n- Deprecate `go.opentelemetry.io/otel/attribute.NewSetWithSortableFiltered` function. (#4734)\n\n## [1.24.0/0.46.0/0.0.1-alpha] 2024-02-23\n\nThis release is the last to support [Go 1.20].\nThe next release will require at least [Go 1.21].\n\n### Added\n\n- Support [Go 1.22]. (#4890)\n- Add exemplar support to `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4900)\n- Add exemplar support to `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4900)\n- The `go.opentelemetry.io/otel/log` module is added.\n  This module includes OpenTelemetry Go's implementation of the Logs Bridge API.\n  This module is in an alpha state, it is subject to breaking changes.\n  See our [versioning policy](./VERSIONING.md) for more info. (#4961)\n- Add ARM64 platform to the compatibility testing suite. (#4994)\n\n### Fixed\n\n- Fix registration of multiple callbacks when using the global meter provider from `go.opentelemetry.io/otel`. (#4945)\n- Fix negative buckets in output of exponential histograms. (#4956)\n\n## [1.23.1] 2024-02-07\n\n### Fixed\n\n- Register all callbacks passed during observable instrument creation instead of just the last one multiple times in `go.opentelemetry.io/otel/sdk/metric`. (#4888)\n\n## [1.23.0] 2024-02-06\n\nThis release contains the first stable, `v1`, release of the following modules:\n\n- `go.opentelemetry.io/otel/bridge/opencensus`\n- `go.opentelemetry.io/otel/bridge/opencensus/test`\n- `go.opentelemetry.io/otel/example/opencensus`\n- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`\n- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`\n- `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric`\n\nSee our [versioning policy](VERSIONING.md) for more information about these stability guarantees.\n\n### Added\n\n- Add `WithEndpointURL` option to the `exporters/otlp/otlpmetric/otlpmetricgrpc`, `exporters/otlp/otlpmetric/otlpmetrichttp`, `exporters/otlp/otlptrace/otlptracegrpc` and `exporters/otlp/otlptrace/otlptracehttp` packages. (#4808)\n- Experimental exemplar exporting is added to the metric SDK.\n  See [metric documentation](./sdk/metric/internal/x/README.md#exemplars) for more information about this feature and how to enable it. (#4871)\n- `ErrSchemaURLConflict` is added to `go.opentelemetry.io/otel/sdk/resource`.\n  This error is returned when a merge of two `Resource`s with different (non-empty) schema URL is attempted. (#4876)\n\n### Changed\n\n- The `Merge` and `New` functions in `go.opentelemetry.io/otel/sdk/resource` now returns a partial result if there is a schema URL merge conflict.\n  Instead of returning `nil` when two `Resource`s with different (non-empty) schema URLs are merged the merged `Resource`, along with the new `ErrSchemaURLConflict` error, is returned.\n  It is up to the user to decide if they want to use the returned `Resource` or not.\n  It may have desired attributes overwritten or include stale semantic conventions. (#4876)\n\n### Fixed\n\n- Fix `ContainerID` resource detection on systemd when cgroup path has a colon. (#4449)\n- Fix `go.opentelemetry.io/otel/sdk/metric` to cache instruments to avoid leaking memory when the same instrument is created multiple times. (#4820)\n- Fix missing `Mix` and `Max` values for `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` by introducing `MarshalText` and `MarshalJSON` for the `Extrema` type in `go.opentelemetry.io/sdk/metric/metricdata`. (#4827)\n\n## [1.23.0-rc.1] 2024-01-18\n\nThis is a release candidate for the v1.23.0 release.\nThat release is expected to include the `v1` release of the following modules:\n\n- `go.opentelemetry.io/otel/bridge/opencensus`\n- `go.opentelemetry.io/otel/bridge/opencensus/test`\n- `go.opentelemetry.io/otel/example/opencensus`\n- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`\n- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`\n- `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric`\n\nSee our [versioning policy](VERSIONING.md) for more information about these stability guarantees.\n\n## [1.22.0/0.45.0] 2024-01-17\n\n### Added\n\n- The `go.opentelemetry.io/otel/semconv/v1.22.0` package.\n  The package contains semantic conventions from the `v1.22.0` version of the OpenTelemetry Semantic Conventions. (#4735)\n- The `go.opentelemetry.io/otel/semconv/v1.23.0` package.\n  The package contains semantic conventions from the `v1.23.0` version of the OpenTelemetry Semantic Conventions. (#4746)\n- The `go.opentelemetry.io/otel/semconv/v1.23.1` package.\n  The package contains semantic conventions from the `v1.23.1` version of the OpenTelemetry Semantic Conventions. (#4749)\n- The `go.opentelemetry.io/otel/semconv/v1.24.0` package.\n  The package contains semantic conventions from the `v1.24.0` version of the OpenTelemetry Semantic Conventions. (#4770)\n- Add `WithResourceAsConstantLabels` option to apply resource attributes for every metric emitted by the Prometheus exporter. (#4733)\n- Experimental cardinality limiting is added to the metric SDK.\n  See [metric documentation](./sdk/metric/internal/x/README.md#cardinality-limit) for more information about this feature and how to enable it. (#4457)\n- Add `NewMemberRaw` and `NewKeyValuePropertyRaw` in `go.opentelemetry.io/otel/baggage`. (#4804)\n\n### Changed\n\n- Upgrade all use of `go.opentelemetry.io/otel/semconv` to use `v1.24.0`. (#4754)\n- Update transformations in `go.opentelemetry.io/otel/exporters/zipkin` to follow `v1.24.0` version of the OpenTelemetry specification. (#4754)\n- Record synchronous measurements when the passed context is canceled instead of dropping in `go.opentelemetry.io/otel/sdk/metric`.\n  If you do not want to make a measurement when the context is cancelled, you need to handle it yourself (e.g  `if ctx.Err() != nil`). (#4671)\n- Improve `go.opentelemetry.io/otel/trace.TraceState`'s performance. (#4722)\n- Improve `go.opentelemetry.io/otel/propagation.TraceContext`'s performance. (#4721)\n- Improve `go.opentelemetry.io/otel/baggage` performance. (#4743)\n- Improve performance of the `(*Set).Filter` method in `go.opentelemetry.io/otel/attribute` when the passed filter does not filter out any attributes from the set. (#4774)\n- `Member.String` in `go.opentelemetry.io/otel/baggage` percent-encodes only when necessary. (#4775)\n- Improve `go.opentelemetry.io/otel/trace.Span`'s performance when adding multiple attributes. (#4818)\n- `Property.Value` in `go.opentelemetry.io/otel/baggage` now returns a raw string instead of a percent-encoded value. (#4804)\n\n### Fixed\n\n- Fix `Parse` in `go.opentelemetry.io/otel/baggage` to validate member value before percent-decoding. (#4755)\n- Fix whitespace encoding of `Member.String` in `go.opentelemetry.io/otel/baggage`. (#4756)\n- Fix observable not registered error when the asynchronous instrument has a drop aggregation in `go.opentelemetry.io/otel/sdk/metric`. (#4772)\n- Fix baggage item key so that it is not canonicalized in `go.opentelemetry.io/otel/bridge/opentracing`. (#4776)\n- Fix `go.opentelemetry.io/otel/bridge/opentracing` to properly handle baggage values that requires escaping during propagation. (#4804)\n- Fix a bug where using multiple readers resulted in incorrect asynchronous counter values in `go.opentelemetry.io/otel/sdk/metric`. (#4742)\n\n## [1.21.0/0.44.0] 2023-11-16\n\n### Removed\n\n- Remove the deprecated `go.opentelemetry.io/otel/bridge/opencensus.NewTracer`. (#4706)\n- Remove the deprecated `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` module. (#4707)\n- Remove the deprecated `go.opentelemetry.io/otel/example/view` module. (#4708)\n- Remove the deprecated `go.opentelemetry.io/otel/example/fib` module. (#4723)\n\n### Fixed\n\n- Do not parse non-protobuf responses in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4719)\n- Do not parse non-protobuf responses in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#4719)\n\n## [1.20.0/0.43.0] 2023-11-10\n\nThis release brings a breaking change for custom trace API implementations. Some interfaces (`TracerProvider`, `Tracer`, `Span`) now embed the `go.opentelemetry.io/otel/trace/embedded` types. Implementers need to update their implementations based on what they want the default behavior to be. See the \"API Implementations\" section of the [trace API] package documentation for more information about how to accomplish this.\n\n### Added\n\n- Add `go.opentelemetry.io/otel/bridge/opencensus.InstallTraceBridge`, which installs the OpenCensus trace bridge, and replaces `opencensus.NewTracer`. (#4567)\n- Add scope version to trace and metric bridges in `go.opentelemetry.io/otel/bridge/opencensus`. (#4584)\n- Add the `go.opentelemetry.io/otel/trace/embedded` package to be embedded in the exported trace API interfaces. (#4620)\n- Add the `go.opentelemetry.io/otel/trace/noop` package as a default no-op implementation of the trace API. (#4620)\n- Add context propagation in `go.opentelemetry.io/otel/example/dice`. (#4644)\n- Add view configuration to `go.opentelemetry.io/otel/example/prometheus`. (#4649)\n- Add `go.opentelemetry.io/otel/metric.WithExplicitBucketBoundaries`, which allows defining default explicit bucket boundaries when creating histogram instruments. (#4603)\n- Add `Version` function in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4660)\n- Add `Version` function in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4660)\n- Add Summary, SummaryDataPoint, and QuantileValue to `go.opentelemetry.io/sdk/metric/metricdata`. (#4622)\n- `go.opentelemetry.io/otel/bridge/opencensus.NewMetricProducer` now supports exemplars from OpenCensus. (#4585)\n- Add support for `WithExplicitBucketBoundaries` in `go.opentelemetry.io/otel/sdk/metric`. (#4605)\n- Add support for Summary metrics in `go.opentelemetry.io/otel/bridge/opencensus`. (#4668)\n\n### Deprecated\n\n- Deprecate `go.opentelemetry.io/otel/bridge/opencensus.NewTracer` in favor of `opencensus.InstallTraceBridge`. (#4567)\n- Deprecate `go.opentelemetry.io/otel/example/fib` package is in favor of `go.opentelemetry.io/otel/example/dice`. (#4618)\n- Deprecate `go.opentelemetry.io/otel/trace.NewNoopTracerProvider`.\n  Use the added `NewTracerProvider` function in `go.opentelemetry.io/otel/trace/noop` instead. (#4620)\n- Deprecate `go.opentelemetry.io/otel/example/view` package in favor of `go.opentelemetry.io/otel/example/prometheus`. (#4649)\n- Deprecate `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#4693)\n\n### Changed\n\n- `go.opentelemetry.io/otel/bridge/opencensus.NewMetricProducer` returns a `*MetricProducer` struct instead of the metric.Producer interface. (#4583)\n- The `TracerProvider` in `go.opentelemetry.io/otel/trace` now embeds the `go.opentelemetry.io/otel/trace/embedded.TracerProvider` type.\n  This extends the `TracerProvider` interface and is is a breaking change for any existing implementation.\n  Implementers need to update their implementations based on what they want the default behavior of the interface to be.\n  See the \"API Implementations\" section of the `go.opentelemetry.io/otel/trace` package documentation for more information about how to accomplish this. (#4620)\n- The `Tracer` in `go.opentelemetry.io/otel/trace` now embeds the `go.opentelemetry.io/otel/trace/embedded.Tracer` type.\n  This extends the `Tracer` interface and is is a breaking change for any existing implementation.\n  Implementers need to update their implementations based on what they want the default behavior of the interface to be.\n  See the \"API Implementations\" section of the `go.opentelemetry.io/otel/trace` package documentation for more information about how to accomplish this. (#4620)\n- The `Span` in `go.opentelemetry.io/otel/trace` now embeds the `go.opentelemetry.io/otel/trace/embedded.Span` type.\n  This extends the `Span` interface and is is a breaking change for any existing implementation.\n  Implementers need to update their implementations based on what they want the default behavior of the interface to be.\n  See the \"API Implementations\" section of the `go.opentelemetry.io/otel/trace` package documentation for more information about how to accomplish this. (#4620)\n- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` does no longer depend on `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#4660)\n- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` does no longer depend on `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#4660)\n- Retry for `502 Bad Gateway` and `504 Gateway Timeout` HTTP statuses in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4670)\n- Retry for `502 Bad Gateway` and `504 Gateway Timeout` HTTP statuses in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#4670)\n- Retry for `RESOURCE_EXHAUSTED` only if RetryInfo is returned in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4669)\n- Retry for `RESOURCE_EXHAUSTED` only if RetryInfo is returned in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. (#4669)\n- Retry temporary HTTP request failures in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4679)\n- Retry temporary HTTP request failures in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#4679)\n\n### Fixed\n\n- Fix improper parsing of characters such us `+`, `/` by `Parse` in `go.opentelemetry.io/otel/baggage` as they were rendered as a whitespace. (#4667)\n- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_RESOURCE_ATTRIBUTES` in `go.opentelemetry.io/otel/sdk/resource` as they were rendered as a whitespace. (#4699)\n- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_EXPORTER_OTLP_HEADERS` and `OTEL_EXPORTER_OTLP_METRICS_HEADERS` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` as they were rendered as a whitespace. (#4699)\n- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_EXPORTER_OTLP_HEADERS` and `OTEL_EXPORTER_OTLP_METRICS_HEADERS` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` as they were rendered as a whitespace. (#4699)\n- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_EXPORTER_OTLP_HEADERS` and `OTEL_EXPORTER_OTLP_TRACES_HEADERS` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlptracegrpc` as they were rendered as a whitespace. (#4699)\n- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_EXPORTER_OTLP_HEADERS` and `OTEL_EXPORTER_OTLP_TRACES_HEADERS` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlptracehttp` as they were rendered as a whitespace. (#4699)\n- In `go.opentelemetry.op/otel/exporters/prometheus`, the exporter no longer `Collect`s metrics after `Shutdown` is invoked. (#4648)\n- Fix documentation for `WithCompressor` in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. (#4695)\n- Fix documentation for `WithCompressor` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4695)\n\n## [1.19.0/0.42.0/0.0.7] 2023-09-28\n\nThis release contains the first stable release of the OpenTelemetry Go [metric SDK].\nOur project stability guarantees now apply to the `go.opentelemetry.io/otel/sdk/metric` package.\nSee our [versioning policy](VERSIONING.md) for more information about these stability guarantees.\n\n### Added\n\n- Add the \"Roll the dice\" getting started application example in `go.opentelemetry.io/otel/example/dice`. (#4539)\n- The `WithWriter` and `WithPrettyPrint` options to `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` to set a custom `io.Writer`, and allow displaying the output in human-readable JSON. (#4507)\n\n### Changed\n\n- Allow '/' characters in metric instrument names. (#4501)\n- The exporter in `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` does not prettify its output by default anymore. (#4507)\n- Upgrade `gopkg.io/yaml` from `v2` to `v3` in `go.opentelemetry.io/otel/schema`. (#4535)\n\n### Fixed\n\n- In `go.opentelemetry.op/otel/exporters/prometheus`, don't try to create the Prometheus metric on every `Collect` if we know the scope is invalid. (#4499)\n\n### Removed\n\n- Remove `\"go.opentelemetry.io/otel/bridge/opencensus\".NewMetricExporter`, which is replaced by `NewMetricProducer`. (#4566)\n\n## [1.19.0-rc.1/0.42.0-rc.1] 2023-09-14\n\nThis is a release candidate for the v1.19.0/v0.42.0 release.\nThat release is expected to include the `v1` release of the OpenTelemetry Go metric SDK and will provide stability guarantees of that SDK.\nSee our [versioning policy](VERSIONING.md) for more information about these stability guarantees.\n\n### Changed\n\n- Allow '/' characters in metric instrument names. (#4501)\n\n### Fixed\n\n- In `go.opentelemetry.op/otel/exporters/prometheus`, don't try to create the prometheus metric on every `Collect` if we know the scope is invalid. (#4499)\n\n## [1.18.0/0.41.0/0.0.6] 2023-09-12\n\nThis release drops the compatibility guarantee of [Go 1.19].\n\n### Added\n\n- Add `WithProducer` option in `go.opentelemetry.op/otel/exporters/prometheus` to restore the ability to register producers on the prometheus exporter's manual reader. (#4473)\n- Add `IgnoreValue` option in `go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest` to allow ignoring values when comparing metrics. (#4447)\n\n### Changed\n\n- Use a `TestingT` interface instead of `*testing.T` struct in `go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest`. (#4483)\n\n### Deprecated\n\n- The `NewMetricExporter` in `go.opentelemetry.io/otel/bridge/opencensus` was deprecated in `v0.35.0` (#3541).\n  The deprecation notice format for the function has been corrected to trigger Go documentation and build tooling. (#4470)\n\n### Removed\n\n- Removed the deprecated `go.opentelemetry.io/otel/exporters/jaeger` package. (#4467)\n- Removed the deprecated `go.opentelemetry.io/otel/example/jaeger` package. (#4467)\n- Removed the deprecated `go.opentelemetry.io/otel/sdk/metric/aggregation` package. (#4468)\n- Removed the deprecated internal packages in `go.opentelemetry.io/otel/exporters/otlp` and its sub-packages. (#4469)\n- Dropped guaranteed support for versions of Go less than 1.20. (#4481)\n\n## [1.17.0/0.40.0/0.0.5] 2023-08-28\n\n### Added\n\n- Export the `ManualReader` struct in `go.opentelemetry.io/otel/sdk/metric`. (#4244)\n- Export the `PeriodicReader` struct in `go.opentelemetry.io/otel/sdk/metric`. (#4244)\n- Add support for exponential histogram aggregations.\n  A histogram can be configured as an exponential histogram using a view with `\"go.opentelemetry.io/otel/sdk/metric\".ExponentialHistogram` as the aggregation. (#4245)\n- Export the `Exporter` struct in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4272)\n- Export the `Exporter` struct in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4272)\n- The exporters in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` now support the `OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` environment variable. (#4287)\n- Add `WithoutCounterSuffixes` option in `go.opentelemetry.io/otel/exporters/prometheus` to disable addition of `_total` suffixes. (#4306)\n- Add info and debug logging to the metric SDK in `go.opentelemetry.io/otel/sdk/metric`. (#4315)\n- The `go.opentelemetry.io/otel/semconv/v1.21.0` package.\n  The package contains semantic conventions from the `v1.21.0` version of the OpenTelemetry Semantic Conventions. (#4362)\n- Accept 201 to 299 HTTP status as success in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` and `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#4365)\n- Document the `Temporality` and `Aggregation` methods of the `\"go.opentelemetry.io/otel/sdk/metric\".Exporter\"` need to be concurrent safe. (#4381)\n- Expand the set of units supported by the Prometheus exporter, and don't add unit suffixes if they are already present in `go.opentelemetry.op/otel/exporters/prometheus` (#4374)\n- Move the `Aggregation` interface and its implementations from `go.opentelemetry.io/otel/sdk/metric/aggregation` to `go.opentelemetry.io/otel/sdk/metric`. (#4435)\n- The exporters in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` now support the `OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION` environment variable. (#4437)\n- Add the `NewAllowKeysFilter` and `NewDenyKeysFilter` functions to `go.opentelemetry.io/otel/attribute` to allow convenient creation of allow-keys and deny-keys filters. (#4444)\n- Support Go 1.21. (#4463)\n\n### Changed\n\n- Starting from `v1.21.0` of semantic conventions, `go.opentelemetry.io/otel/semconv/{version}/httpconv` and `go.opentelemetry.io/otel/semconv/{version}/netconv` packages will no longer be published. (#4145)\n- Log duplicate instrument conflict at a warning level instead of info in `go.opentelemetry.io/otel/sdk/metric`. (#4202)\n- Return an error on the creation of new instruments in `go.opentelemetry.io/otel/sdk/metric` if their name doesn't pass regexp validation. (#4210)\n- `NewManualReader` in `go.opentelemetry.io/otel/sdk/metric` returns `*ManualReader` instead of `Reader`. (#4244)\n- `NewPeriodicReader` in `go.opentelemetry.io/otel/sdk/metric` returns `*PeriodicReader` instead of `Reader`. (#4244)\n- Count the Collect time in the `PeriodicReader` timeout in `go.opentelemetry.io/otel/sdk/metric`. (#4221)\n- The function `New` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` returns `*Exporter` instead of `\"go.opentelemetry.io/otel/sdk/metric\".Exporter`. (#4272)\n- The function `New` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` returns `*Exporter` instead of `\"go.opentelemetry.io/otel/sdk/metric\".Exporter`. (#4272)\n- If an attribute set is omitted from an async callback, the previous value will no longer be exported in `go.opentelemetry.io/otel/sdk/metric`. (#4290)\n- If an attribute set is observed multiple times in an async callback in `go.opentelemetry.io/otel/sdk/metric`, the values will be summed instead of the last observation winning. (#4289)\n- Allow the explicit bucket histogram aggregation to be used for the up-down counter, observable counter, observable up-down counter, and observable gauge in the `go.opentelemetry.io/otel/sdk/metric` package. (#4332)\n- Restrict `Meter`s in `go.opentelemetry.io/otel/sdk/metric` to only register and collect instruments it created. (#4333)\n- `PeriodicReader.Shutdown` and `PeriodicReader.ForceFlush` in `go.opentelemetry.io/otel/sdk/metric` now apply the periodic reader's timeout to the operation if the user provided context does not contain a deadline. (#4356, #4377)\n- Upgrade all use of `go.opentelemetry.io/otel/semconv` to use `v1.21.0`. (#4408)\n- Increase instrument name maximum length from 63 to 255 characters in `go.opentelemetry.io/otel/sdk/metric`. (#4434)\n- Add `go.opentelemetry.op/otel/sdk/metric.WithProducer` as an `Option` for `\"go.opentelemetry.io/otel/sdk/metric\".NewManualReader` and `\"go.opentelemetry.io/otel/sdk/metric\".NewPeriodicReader`. (#4346)\n\n### Removed\n\n- Remove `Reader.RegisterProducer` in `go.opentelemetry.io/otel/metric`.\n  Use the added `WithProducer` option instead. (#4346)\n- Remove `Reader.ForceFlush` in `go.opentelemetry.io/otel/metric`.\n  Notice that `PeriodicReader.ForceFlush` is still available. (#4375)\n\n### Fixed\n\n- Correctly format log messages from the `go.opentelemetry.io/otel/exporters/zipkin` exporter. (#4143)\n- Log an error for calls to `NewView` in `go.opentelemetry.io/otel/sdk/metric` that have empty criteria. (#4307)\n- Fix `\"go.opentelemetry.io/otel/sdk/resource\".WithHostID()` to not set an empty `host.id`. (#4317)\n- Use the instrument identifying fields to cache aggregators and determine duplicate instrument registrations in `go.opentelemetry.io/otel/sdk/metric`. (#4337)\n- Detect duplicate instruments for case-insensitive names in `go.opentelemetry.io/otel/sdk/metric`. (#4338)\n- The `ManualReader` will not panic if `AggregationSelector` returns `nil` in `go.opentelemetry.io/otel/sdk/metric`. (#4350)\n- If a `Reader`'s `AggregationSelector` returns `nil` or `DefaultAggregation` the pipeline will use the default aggregation. (#4350)\n- Log a suggested view that fixes instrument conflicts in `go.opentelemetry.io/otel/sdk/metric`. (#4349)\n- Fix possible panic, deadlock and race condition in batch span processor in `go.opentelemetry.io/otel/sdk/trace`. (#4353)\n- Improve context cancellation handling in batch span processor's `ForceFlush` in  `go.opentelemetry.io/otel/sdk/trace`. (#4369)\n- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` using gotmpl. (#4397, #3846)\n- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal` using gotmpl. (#4404, #3846)\n- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal` using gotmpl. (#4407, #3846)\n- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` using gotmpl. (#4400, #3846)\n- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` using gotmpl. (#4401, #3846)\n- Do not block the metric SDK when OTLP metric exports are blocked in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#3925, #4395)\n- Do not append `_total` if the counter already has that suffix for the Prometheus exproter in `go.opentelemetry.io/otel/exporter/prometheus`. (#4373)\n- Fix resource detection data race in `go.opentelemetry.io/otel/sdk/resource`. (#4409)\n- Use the first-seen instrument name during instrument name conflicts in `go.opentelemetry.io/otel/sdk/metric`. (#4428)\n\n### Deprecated\n\n- The `go.opentelemetry.io/otel/exporters/jaeger` package is deprecated.\n  OpenTelemetry dropped support for Jaeger exporter in July 2023.\n  Use `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`\n  or `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` instead. (#4423)\n- The `go.opentelemetry.io/otel/example/jaeger` package is deprecated. (#4423)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal` package is deprecated. (#4420)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/oconf` package is deprecated. (#4420)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/otest` package is deprecated. (#4420)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/transform` package is deprecated. (#4420)\n- The `go.opentelemetry.io/otel/exporters/otlp/internal` package is deprecated. (#4421)\n- The `go.opentelemetry.io/otel/exporters/otlp/internal/envconfig` package is deprecated. (#4421)\n- The `go.opentelemetry.io/otel/exporters/otlp/internal/retry` package is deprecated. (#4421)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` package is deprecated. (#4425)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/envconfig` package is deprecated. (#4425)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig` package is deprecated. (#4425)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlptracetest` package is deprecated. (#4425)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/retry` package is deprecated. (#4425)\n- The `go.opentelemetry.io/otel/sdk/metric/aggregation` package is deprecated.\n  Use the aggregation types added to `go.opentelemetry.io/otel/sdk/metric` instead. (#4435)\n\n## [1.16.0/0.39.0] 2023-05-18\n\nThis release contains the first stable release of the OpenTelemetry Go [metric API].\nOur project stability guarantees now apply to the `go.opentelemetry.io/otel/metric` package.\nSee our [versioning policy](VERSIONING.md) for more information about these stability guarantees.\n\n### Added\n\n- The `go.opentelemetry.io/otel/semconv/v1.19.0` package.\n  The package contains semantic conventions from the `v1.19.0` version of the OpenTelemetry specification. (#3848)\n- The `go.opentelemetry.io/otel/semconv/v1.20.0` package.\n  The package contains semantic conventions from the `v1.20.0` version of the OpenTelemetry specification. (#4078)\n- The Exponential Histogram data types in `go.opentelemetry.io/otel/sdk/metric/metricdata`. (#4165)\n- OTLP metrics exporter now supports the Exponential Histogram Data Type. (#4222)\n- Fix serialization of `time.Time` zero values in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` packages. (#4271)\n\n### Changed\n\n- Use `strings.Cut()` instead of `string.SplitN()` for better readability and memory use. (#4049)\n- `MeterProvider` returns noop meters once it has been shutdown. (#4154)\n\n### Removed\n\n- The deprecated `go.opentelemetry.io/otel/metric/instrument` package is removed.\n  Use `go.opentelemetry.io/otel/metric` instead. (#4055)\n\n### Fixed\n\n- Fix build for BSD based systems in `go.opentelemetry.io/otel/sdk/resource`. (#4077)\n\n## [1.16.0-rc.1/0.39.0-rc.1] 2023-05-03\n\nThis is a release candidate for the v1.16.0/v0.39.0 release.\nThat release is expected to include the `v1` release of the OpenTelemetry Go metric API and will provide stability guarantees of that API.\nSee our [versioning policy](VERSIONING.md) for more information about these stability guarantees.\n\n### Added\n\n- Support global `MeterProvider` in `go.opentelemetry.io/otel`. (#4039)\n  - Use `Meter` for a `metric.Meter` from the global `metric.MeterProvider`.\n  - Use `GetMeterProivder` for a global `metric.MeterProvider`.\n  - Use `SetMeterProivder` to set the global `metric.MeterProvider`.\n\n### Changed\n\n- Move the `go.opentelemetry.io/otel/metric` module to the `stable-v1` module set.\n  This stages the metric API to be released as a stable module. (#4038)\n\n### Removed\n\n- The `go.opentelemetry.io/otel/metric/global` package is removed.\n  Use `go.opentelemetry.io/otel` instead. (#4039)\n\n## [1.15.1/0.38.1] 2023-05-02\n\n### Fixed\n\n- Remove unused imports from `sdk/resource/host_id_bsd.go` which caused build failures. (#4040, #4041)\n\n## [1.15.0/0.38.0] 2023-04-27\n\n### Added\n\n- The `go.opentelemetry.io/otel/metric/embedded` package. (#3916)\n- The `Version` function to `go.opentelemetry.io/otel/sdk` to return the SDK version. (#3949)\n- Add a `WithNamespace` option to `go.opentelemetry.io/otel/exporters/prometheus` to allow users to prefix metrics with a namespace. (#3970)\n- The following configuration types were added to `go.opentelemetry.io/otel/metric/instrument` to be used in the configuration of measurement methods. (#3971)\n  - The `AddConfig` used to hold configuration for addition measurements\n    - `NewAddConfig` used to create a new `AddConfig`\n    - `AddOption` used to configure an `AddConfig`\n  - The `RecordConfig` used to hold configuration for recorded measurements\n    - `NewRecordConfig` used to create a new `RecordConfig`\n    - `RecordOption` used to configure a `RecordConfig`\n  - The `ObserveConfig` used to hold configuration for observed measurements\n    - `NewObserveConfig` used to create a new `ObserveConfig`\n    - `ObserveOption` used to configure an `ObserveConfig`\n- `WithAttributeSet` and `WithAttributes` are added to `go.opentelemetry.io/otel/metric/instrument`.\n  They return an option used during a measurement that defines the attribute Set associated with the measurement. (#3971)\n- The `Version` function to `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` to return the OTLP metrics client version. (#3956)\n- The `Version` function to `go.opentelemetry.io/otel/exporters/otlp/otlptrace` to return the OTLP trace client version. (#3956)\n\n### Changed\n\n- The `Extrema` in `go.opentelemetry.io/otel/sdk/metric/metricdata` is redefined with a generic argument of `[N int64 | float64]`. (#3870)\n- Update all exported interfaces from `go.opentelemetry.io/otel/metric` to embed their corresponding interface from `go.opentelemetry.io/otel/metric/embedded`.\n  This adds an implementation requirement to set the interface default behavior for unimplemented methods. (#3916)\n- Move No-Op implementation from `go.opentelemetry.io/otel/metric` into its own package `go.opentelemetry.io/otel/metric/noop`. (#3941)\n  - `metric.NewNoopMeterProvider` is replaced with `noop.NewMeterProvider`\n- Add all the methods from `\"go.opentelemetry.io/otel/trace\".SpanContext` to `bridgeSpanContext` by embedding `otel.SpanContext` in `bridgeSpanContext`. (#3966)\n- Wrap `UploadMetrics` error in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/` to improve error message when encountering generic grpc errors. (#3974)\n- The measurement methods for all instruments in `go.opentelemetry.io/otel/metric/instrument` accept an option instead of the variadic `\"go.opentelemetry.io/otel/attribute\".KeyValue`. (#3971)\n  - The `Int64Counter.Add` method now accepts `...AddOption`\n  - The `Float64Counter.Add` method now accepts `...AddOption`\n  - The `Int64UpDownCounter.Add` method now accepts `...AddOption`\n  - The `Float64UpDownCounter.Add` method now accepts `...AddOption`\n  - The `Int64Histogram.Record` method now accepts `...RecordOption`\n  - The `Float64Histogram.Record` method now accepts `...RecordOption`\n  - The `Int64Observer.Observe` method now accepts `...ObserveOption`\n  - The `Float64Observer.Observe` method now accepts `...ObserveOption`\n- The `Observer` methods in `go.opentelemetry.io/otel/metric` accept an option instead of the variadic `\"go.opentelemetry.io/otel/attribute\".KeyValue`. (#3971)\n  - The `Observer.ObserveInt64` method now accepts `...ObserveOption`\n  - The `Observer.ObserveFloat64` method now accepts `...ObserveOption`\n- Move global metric back to `go.opentelemetry.io/otel/metric/global` from `go.opentelemetry.io/otel`. (#3986)\n\n### Fixed\n\n- `TracerProvider` allows calling `Tracer()` while it's shutting down.\n  It used to deadlock. (#3924)\n- Use the SDK version for the Telemetry SDK resource detector in `go.opentelemetry.io/otel/sdk/resource`. (#3949)\n- Fix a data race in `SpanProcessor` returned by `NewSimpleSpanProcessor` in `go.opentelemetry.io/otel/sdk/trace`. (#3951)\n- Automatically figure out the default aggregation with `aggregation.Default`. (#3967)\n\n### Deprecated\n\n- The `go.opentelemetry.io/otel/metric/instrument` package is deprecated.\n  Use the equivalent types added to `go.opentelemetry.io/otel/metric` instead. (#4018)\n\n## [1.15.0-rc.2/0.38.0-rc.2] 2023-03-23\n\nThis is a release candidate for the v1.15.0/v0.38.0 release.\nThat release will include the `v1` release of the OpenTelemetry Go metric API and will provide stability guarantees of that API.\nSee our [versioning policy](VERSIONING.md) for more information about these stability guarantees.\n\n### Added\n\n- The `WithHostID` option to `go.opentelemetry.io/otel/sdk/resource`. (#3812)\n- The `WithoutTimestamps` option to `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` to sets all timestamps to zero. (#3828)\n- The new `Exemplar` type is added to `go.opentelemetry.io/otel/sdk/metric/metricdata`.\n  Both the `DataPoint` and `HistogramDataPoint` types from that package have a new field of `Exemplars` containing the sampled exemplars for their timeseries. (#3849)\n- Configuration for each metric instrument in `go.opentelemetry.io/otel/sdk/metric/instrument`. (#3895)\n- The internal logging introduces a warning level verbosity equal to `V(1)`. (#3900)\n- Added a log message warning about usage of `SimpleSpanProcessor` in production environments. (#3854)\n\n### Changed\n\n- Optimize memory allocation when creation a new `Set` using `NewSet` or `NewSetWithFiltered` in `go.opentelemetry.io/otel/attribute`. (#3832)\n- Optimize memory allocation when creation new metric instruments in `go.opentelemetry.io/otel/sdk/metric`. (#3832)\n- Avoid creating new objects on all calls to `WithDeferredSetup` and `SkipContextSetup` in OpenTracing bridge. (#3833)\n- The `New` and `Detect` functions from `go.opentelemetry.io/otel/sdk/resource` return errors that wrap underlying errors instead of just containing the underlying error strings. (#3844)\n- Both the `Histogram` and `HistogramDataPoint` are redefined with a generic argument of `[N int64 | float64]` in `go.opentelemetry.io/otel/sdk/metric/metricdata`. (#3849)\n- The metric `Export` interface from `go.opentelemetry.io/otel/sdk/metric` accepts a `*ResourceMetrics` instead of `ResourceMetrics`. (#3853)\n- Rename `Asynchronous` to `Observable` in `go.opentelemetry.io/otel/metric/instrument`. (#3892)\n- Rename `Int64ObserverOption` to `Int64ObservableOption` in `go.opentelemetry.io/otel/metric/instrument`. (#3895)\n- Rename `Float64ObserverOption` to `Float64ObservableOption` in `go.opentelemetry.io/otel/metric/instrument`. (#3895)\n- The internal logging changes the verbosity level of info to `V(4)`, the verbosity level of debug to `V(8)`. (#3900)\n\n### Fixed\n\n- `TracerProvider` consistently doesn't allow to register a `SpanProcessor` after shutdown. (#3845)\n\n### Removed\n\n- The deprecated `go.opentelemetry.io/otel/metric/global` package is removed. (#3829)\n- The unneeded `Synchronous` interface in `go.opentelemetry.io/otel/metric/instrument` was removed. (#3892)\n- The `Float64ObserverConfig` and `NewFloat64ObserverConfig` in `go.opentelemetry.io/otel/sdk/metric/instrument`.\n  Use the added `float64` instrument configuration instead. (#3895)\n- The `Int64ObserverConfig` and `NewInt64ObserverConfig` in `go.opentelemetry.io/otel/sdk/metric/instrument`.\n  Use the added `int64` instrument configuration instead. (#3895)\n- The `NewNoopMeter` function in `go.opentelemetry.io/otel/metric`, use `NewMeterProvider().Meter(\"\")` instead. (#3893)\n\n## [1.15.0-rc.1/0.38.0-rc.1] 2023-03-01\n\nThis is a release candidate for the v1.15.0/v0.38.0 release.\nThat release will include the `v1` release of the OpenTelemetry Go metric API and will provide stability guarantees of that API.\nSee our [versioning policy](VERSIONING.md) for more information about these stability guarantees.\n\nThis release drops the compatibility guarantee of [Go 1.18].\n\n### Added\n\n- Support global `MeterProvider` in `go.opentelemetry.io/otel`. (#3818)\n  - Use `Meter` for a `metric.Meter` from the global `metric.MeterProvider`.\n  - Use `GetMeterProivder` for a global `metric.MeterProvider`.\n  - Use `SetMeterProivder` to set the global `metric.MeterProvider`.\n\n### Changed\n\n- Dropped compatibility testing for [Go 1.18].\n  The project no longer guarantees support for this version of Go. (#3813)\n\n### Fixed\n\n- Handle empty environment variable as it they were not set. (#3764)\n- Clarify the `httpconv` and `netconv` packages in `go.opentelemetry.io/otel/semconv/*` provide tracing semantic conventions. (#3823)\n- Fix race conditions in `go.opentelemetry.io/otel/exporters/metric/prometheus` that could cause a panic. (#3899)\n- Fix sending nil `scopeInfo` to metrics channel in `go.opentelemetry.io/otel/exporters/metric/prometheus` that could cause a panic in `github.com/prometheus/client_golang/prometheus`. (#3899)\n\n### Deprecated\n\n- The `go.opentelemetry.io/otel/metric/global` package is deprecated.\n  Use `go.opentelemetry.io/otel` instead. (#3818)\n\n### Removed\n\n- The deprecated `go.opentelemetry.io/otel/metric/unit` package is removed. (#3814)\n\n## [1.14.0/0.37.0/0.0.4] 2023-02-27\n\nThis release is the last to support [Go 1.18].\nThe next release will require at least [Go 1.19].\n\n### Added\n\n- The `event` type semantic conventions are added to `go.opentelemetry.io/otel/semconv/v1.17.0`. (#3697)\n- Support [Go 1.20]. (#3693)\n- The `go.opentelemetry.io/otel/semconv/v1.18.0` package.\n  The package contains semantic conventions from the `v1.18.0` version of the OpenTelemetry specification. (#3719)\n  - The following `const` renames from `go.opentelemetry.io/otel/semconv/v1.17.0` are included:\n    - `OtelScopeNameKey` -> `OTelScopeNameKey`\n    - `OtelScopeVersionKey` -> `OTelScopeVersionKey`\n    - `OtelLibraryNameKey` -> `OTelLibraryNameKey`\n    - `OtelLibraryVersionKey` -> `OTelLibraryVersionKey`\n    - `OtelStatusCodeKey` -> `OTelStatusCodeKey`\n    - `OtelStatusDescriptionKey` -> `OTelStatusDescriptionKey`\n    - `OtelStatusCodeOk` -> `OTelStatusCodeOk`\n    - `OtelStatusCodeError` -> `OTelStatusCodeError`\n  - The following `func` renames from `go.opentelemetry.io/otel/semconv/v1.17.0` are included:\n    - `OtelScopeName` -> `OTelScopeName`\n    - `OtelScopeVersion` -> `OTelScopeVersion`\n    - `OtelLibraryName` -> `OTelLibraryName`\n    - `OtelLibraryVersion` -> `OTelLibraryVersion`\n    - `OtelStatusDescription` -> `OTelStatusDescription`\n- A `IsSampled` method is added to the `SpanContext` implementation in `go.opentelemetry.io/otel/bridge/opentracing` to expose the span sampled state.\n  See the [README](./bridge/opentracing/README.md) for more information. (#3570)\n- The `WithInstrumentationAttributes` option to `go.opentelemetry.io/otel/metric`. (#3738)\n- The `WithInstrumentationAttributes` option to `go.opentelemetry.io/otel/trace`. (#3739)\n- The following environment variables are supported by the periodic `Reader` in `go.opentelemetry.io/otel/sdk/metric`. (#3763)\n  - `OTEL_METRIC_EXPORT_INTERVAL` sets the time between collections and exports.\n  - `OTEL_METRIC_EXPORT_TIMEOUT` sets the timeout an export is attempted.\n\n### Changed\n\n- Fall-back to `TextMapCarrier` when it's not `HttpHeader`s in `go.opentelemetry.io/otel/bridge/opentracing`. (#3679)\n- The `Collect` method of the `\"go.opentelemetry.io/otel/sdk/metric\".Reader` interface is updated to accept the `metricdata.ResourceMetrics` value the collection will be made into.\n  This change is made to enable memory reuse by SDK users. (#3732)\n- The `WithUnit` option in `go.opentelemetry.io/otel/sdk/metric/instrument` is updated to accept a `string` for the unit value. (#3776)\n\n### Fixed\n\n- Ensure `go.opentelemetry.io/otel` does not use generics. (#3723, #3725)\n- Multi-reader `MeterProvider`s now export metrics for all readers, instead of just the first reader. (#3720, #3724)\n- Remove use of deprecated `\"math/rand\".Seed` in `go.opentelemetry.io/otel/example/prometheus`. (#3733)\n- Do not silently drop unknown schema data with `Parse` in  `go.opentelemetry.io/otel/schema/v1.1`. (#3743)\n- Data race issue in OTLP exporter retry mechanism. (#3755, #3756)\n- Wrapping empty errors when exporting in `go.opentelemetry.io/otel/sdk/metric`. (#3698, #3772)\n- Incorrect \"all\" and \"resource\" definition for schema files in `go.opentelemetry.io/otel/schema/v1.1`. (#3777)\n\n### Deprecated\n\n- The `go.opentelemetry.io/otel/metric/unit` package is deprecated.\n  Use the equivalent unit string instead. (#3776)\n  - Use `\"1\"` instead of `unit.Dimensionless`\n  - Use `\"By\"` instead of `unit.Bytes`\n  - Use `\"ms\"` instead of `unit.Milliseconds`\n\n## [1.13.0/0.36.0] 2023-02-07\n\n### Added\n\n- Attribute `KeyValue` creations functions to `go.opentelemetry.io/otel/semconv/v1.17.0` for all non-enum semantic conventions.\n  These functions ensure semantic convention type correctness. (#3675)\n\n### Fixed\n\n- Removed the `http.target` attribute from being added by `ServerRequest` in the following packages. (#3687)\n  - `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`\n  - `go.opentelemetry.io/otel/semconv/v1.14.0/httpconv`\n  - `go.opentelemetry.io/otel/semconv/v1.15.0/httpconv`\n  - `go.opentelemetry.io/otel/semconv/v1.16.0/httpconv`\n  - `go.opentelemetry.io/otel/semconv/v1.17.0/httpconv`\n\n### Removed\n\n- The deprecated `go.opentelemetry.io/otel/metric/instrument/asyncfloat64` package is removed. (#3631)\n- The deprecated `go.opentelemetry.io/otel/metric/instrument/asyncint64` package is removed. (#3631)\n- The deprecated `go.opentelemetry.io/otel/metric/instrument/syncfloat64` package is removed. (#3631)\n- The deprecated `go.opentelemetry.io/otel/metric/instrument/syncint64` package is removed. (#3631)\n\n## [1.12.0/0.35.0] 2023-01-28\n\n### Added\n\n- The `WithInt64Callback` option to `go.opentelemetry.io/otel/metric/instrument`.\n  This options is used to configure `int64` Observer callbacks during their creation. (#3507)\n- The `WithFloat64Callback` option to `go.opentelemetry.io/otel/metric/instrument`.\n  This options is used to configure `float64` Observer callbacks during their creation. (#3507)\n- The `Producer` interface and `Reader.RegisterProducer(Producer)` to `go.opentelemetry.io/otel/sdk/metric`.\n  These additions are used to enable external metric Producers. (#3524)\n- The `Callback` function type to `go.opentelemetry.io/otel/metric`.\n  This new named function type is registered with a `Meter`. (#3564)\n- The `go.opentelemetry.io/otel/semconv/v1.13.0` package.\n  The package contains semantic conventions from the `v1.13.0` version of the OpenTelemetry specification. (#3499)\n  - The `EndUserAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is merged into `ClientRequest` and `ServerRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.\n  - The `HTTPAttributesFromHTTPStatusCode` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is merged into `ClientResponse` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.\n  - The `HTTPClientAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is replaced by `ClientRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.\n  - The `HTTPServerAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is replaced by `ServerRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.\n  - The `HTTPServerMetricAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is replaced by `ServerRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.\n  - The `NetAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is split into `Transport` in `go.opentelemetry.io/otel/semconv/v1.13.0/netconv` and `ClientRequest` or `ServerRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.\n  - The `SpanStatusFromHTTPStatusCode` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is replaced by `ClientStatus` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.\n  - The `SpanStatusFromHTTPStatusCodeAndSpanKind` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is split into `ClientStatus` and `ServerStatus` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.\n  - The `Client` function is included in `go.opentelemetry.io/otel/semconv/v1.13.0/netconv` to generate attributes for a `net.Conn`.\n  - The `Server` function is included in `go.opentelemetry.io/otel/semconv/v1.13.0/netconv` to generate attributes for a `net.Listener`.\n- The `go.opentelemetry.io/otel/semconv/v1.14.0` package.\n  The package contains semantic conventions from the `v1.14.0` version of the OpenTelemetry specification. (#3566)\n- The `go.opentelemetry.io/otel/semconv/v1.15.0` package.\n  The package contains semantic conventions from the `v1.15.0` version of the OpenTelemetry specification. (#3578)\n- The `go.opentelemetry.io/otel/semconv/v1.16.0` package.\n  The package contains semantic conventions from the `v1.16.0` version of the OpenTelemetry specification. (#3579)\n- Metric instruments to `go.opentelemetry.io/otel/metric/instrument`.\n  These instruments are use as replacements of the deprecated `go.opentelemetry.io/otel/metric/instrument/{asyncfloat64,asyncint64,syncfloat64,syncint64}` packages.(#3575, #3586)\n  - `Float64ObservableCounter` replaces the `asyncfloat64.Counter`\n  - `Float64ObservableUpDownCounter` replaces the `asyncfloat64.UpDownCounter`\n  - `Float64ObservableGauge` replaces the `asyncfloat64.Gauge`\n  - `Int64ObservableCounter` replaces the `asyncint64.Counter`\n  - `Int64ObservableUpDownCounter` replaces the `asyncint64.UpDownCounter`\n  - `Int64ObservableGauge` replaces the `asyncint64.Gauge`\n  - `Float64Counter` replaces the `syncfloat64.Counter`\n  - `Float64UpDownCounter` replaces the `syncfloat64.UpDownCounter`\n  - `Float64Histogram` replaces the `syncfloat64.Histogram`\n  - `Int64Counter` replaces the `syncint64.Counter`\n  - `Int64UpDownCounter` replaces the `syncint64.UpDownCounter`\n  - `Int64Histogram` replaces the `syncint64.Histogram`\n- `NewTracerProvider` to `go.opentelemetry.io/otel/bridge/opentracing`.\n  This is used to create `WrapperTracer` instances from a `TracerProvider`. (#3116)\n- The `Extrema` type to `go.opentelemetry.io/otel/sdk/metric/metricdata`.\n  This type is used to represent min/max values and still be able to distinguish unset and zero values. (#3487)\n- The `go.opentelemetry.io/otel/semconv/v1.17.0` package.\n  The package contains semantic conventions from the `v1.17.0` version of the OpenTelemetry specification. (#3599)\n\n### Changed\n\n- Jaeger and Zipkin exporter use `github.com/go-logr/logr` as the logging interface, and add the `WithLogr` option. (#3497, #3500)\n- Instrument configuration in `go.opentelemetry.io/otel/metric/instrument` is split into specific options and configuration based on the instrument type. (#3507)\n  - Use the added `Int64Option` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/syncint64`.\n  - Use the added `Float64Option` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/syncfloat64`.\n  - Use the added `Int64ObserverOption` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/asyncint64`.\n  - Use the added `Float64ObserverOption` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/asyncfloat64`.\n- Return a `Registration` from the `RegisterCallback` method of a `Meter` in the `go.opentelemetry.io/otel/metric` package.\n  This `Registration` can be used to unregister callbacks. (#3522)\n- Global error handler uses an atomic value instead of a mutex. (#3543)\n- Add `NewMetricProducer` to `go.opentelemetry.io/otel/bridge/opencensus`, which can be used to pass OpenCensus metrics to an OpenTelemetry Reader. (#3541)\n- Global logger uses an atomic value instead of a mutex. (#3545)\n- The `Shutdown` method of the `\"go.opentelemetry.io/otel/sdk/trace\".TracerProvider` releases all computational resources when called the first time. (#3551)\n- The `Sampler` returned from `TraceIDRatioBased` `go.opentelemetry.io/otel/sdk/trace` now uses the rightmost bits for sampling decisions.\n  This fixes random sampling when using ID generators like `xray.IDGenerator` and increasing parity with other language implementations. (#3557)\n- Errors from `go.opentelemetry.io/otel/exporters/otlp/otlptrace` exporters are wrapped in errors identifying their signal name.\n  Existing users of the exporters attempting to identify specific errors will need to use `errors.Unwrap()` to get the underlying error. (#3516)\n- Exporters from `go.opentelemetry.io/otel/exporters/otlp` will print the final retryable error message when attempts to retry time out. (#3514)\n- The instrument kind names in `go.opentelemetry.io/otel/sdk/metric` are updated to match the API. (#3562)\n  - `InstrumentKindSyncCounter` is renamed to `InstrumentKindCounter`\n  - `InstrumentKindSyncUpDownCounter` is renamed to `InstrumentKindUpDownCounter`\n  - `InstrumentKindSyncHistogram` is renamed to `InstrumentKindHistogram`\n  - `InstrumentKindAsyncCounter` is renamed to `InstrumentKindObservableCounter`\n  - `InstrumentKindAsyncUpDownCounter` is renamed to `InstrumentKindObservableUpDownCounter`\n  - `InstrumentKindAsyncGauge` is renamed to `InstrumentKindObservableGauge`\n- The `RegisterCallback` method of the `Meter` in `go.opentelemetry.io/otel/metric` changed.\n  - The named `Callback` replaces the inline function parameter. (#3564)\n  - `Callback` is required to return an error. (#3576)\n  - `Callback` accepts the added `Observer` parameter added.\n    This new parameter is used by `Callback` implementations to observe values for asynchronous instruments instead of calling the `Observe` method of the instrument directly. (#3584)\n  - The slice of `instrument.Asynchronous` is now passed as a variadic argument. (#3587)\n- The exporter from `go.opentelemetry.io/otel/exporters/zipkin` is updated to use the `v1.16.0` version of semantic conventions.\n  This means it no longer uses the removed `net.peer.ip` or `http.host` attributes to determine the remote endpoint.\n  Instead it uses the `net.sock.peer` attributes. (#3581)\n- The `Min` and `Max` fields of the `HistogramDataPoint` in `go.opentelemetry.io/otel/sdk/metric/metricdata` are now defined with the added `Extrema` type instead of a `*float64`. (#3487)\n\n### Fixed\n\n- Asynchronous instruments that use sum aggregators and attribute filters correctly add values from equivalent attribute sets that have been filtered. (#3439, #3549)\n- The `RegisterCallback` method of the `Meter` from `go.opentelemetry.io/otel/sdk/metric` only registers a callback for instruments created by that meter.\n  Trying to register a callback with instruments from a different meter will result in an error being returned. (#3584)\n\n### Deprecated\n\n- The `NewMetricExporter` in `go.opentelemetry.io/otel/bridge/opencensus` is deprecated.\n  Use `NewMetricProducer` instead. (#3541)\n- The `go.opentelemetry.io/otel/metric/instrument/asyncfloat64` package is deprecated.\n  Use the instruments from `go.opentelemetry.io/otel/metric/instrument` instead. (#3575)\n- The `go.opentelemetry.io/otel/metric/instrument/asyncint64` package is deprecated.\n  Use the instruments from `go.opentelemetry.io/otel/metric/instrument` instead. (#3575)\n- The `go.opentelemetry.io/otel/metric/instrument/syncfloat64` package is deprecated.\n  Use the instruments from `go.opentelemetry.io/otel/metric/instrument` instead. (#3575)\n- The `go.opentelemetry.io/otel/metric/instrument/syncint64` package is deprecated.\n  Use the instruments from `go.opentelemetry.io/otel/metric/instrument` instead. (#3575)\n- The `NewWrappedTracerProvider` in `go.opentelemetry.io/otel/bridge/opentracing` is now deprecated.\n  Use `NewTracerProvider` instead. (#3116)\n\n### Removed\n\n- The deprecated `go.opentelemetry.io/otel/sdk/metric/view` package is removed. (#3520)\n- The `InstrumentProvider` from `go.opentelemetry.io/otel/sdk/metric/asyncint64` is removed.\n  Use the new creation methods of the `Meter` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3530)\n  - The `Counter` method is replaced by `Meter.Int64ObservableCounter`\n  - The `UpDownCounter` method is replaced by `Meter.Int64ObservableUpDownCounter`\n  - The `Gauge` method is replaced by `Meter.Int64ObservableGauge`\n- The `InstrumentProvider` from `go.opentelemetry.io/otel/sdk/metric/asyncfloat64` is removed.\n  Use the new creation methods of the `Meter` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3530)\n  - The `Counter` method is replaced by `Meter.Float64ObservableCounter`\n  - The `UpDownCounter` method is replaced by `Meter.Float64ObservableUpDownCounter`\n  - The `Gauge` method is replaced by `Meter.Float64ObservableGauge`\n- The `InstrumentProvider` from `go.opentelemetry.io/otel/sdk/metric/syncint64` is removed.\n  Use the new creation methods of the `Meter` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3530)\n  - The `Counter` method is replaced by `Meter.Int64Counter`\n  - The `UpDownCounter` method is replaced by `Meter.Int64UpDownCounter`\n  - The `Histogram` method is replaced by `Meter.Int64Histogram`\n- The `InstrumentProvider` from `go.opentelemetry.io/otel/sdk/metric/syncfloat64` is removed.\n  Use the new creation methods of the `Meter` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3530)\n  - The `Counter` method is replaced by `Meter.Float64Counter`\n  - The `UpDownCounter` method is replaced by `Meter.Float64UpDownCounter`\n  - The `Histogram` method is replaced by `Meter.Float64Histogram`\n\n## [1.11.2/0.34.0] 2022-12-05\n\n### Added\n\n- The `WithView` `Option` is added to the `go.opentelemetry.io/otel/sdk/metric` package.\n   This option is used to configure the view(s) a `MeterProvider` will use for all `Reader`s that are registered with it. (#3387)\n- Add Instrumentation Scope and Version as info metric and label in Prometheus exporter.\n  This can be disabled using the `WithoutScopeInfo()` option added to that package.(#3273, #3357)\n- OTLP exporters now recognize: (#3363)\n  - `OTEL_EXPORTER_OTLP_INSECURE`\n  - `OTEL_EXPORTER_OTLP_TRACES_INSECURE`\n  - `OTEL_EXPORTER_OTLP_METRICS_INSECURE`\n  - `OTEL_EXPORTER_OTLP_CLIENT_KEY`\n  - `OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY`\n  - `OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY`\n  - `OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE`\n  - `OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE`\n  - `OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE`\n- The `View` type and related `NewView` function to create a view according to the OpenTelemetry specification are added to `go.opentelemetry.io/otel/sdk/metric`.\n  These additions are replacements for the `View` type and `New` function from `go.opentelemetry.io/otel/sdk/metric/view`. (#3459)\n- The `Instrument` and `InstrumentKind` type are added to `go.opentelemetry.io/otel/sdk/metric`.\n  These additions are replacements for the `Instrument` and `InstrumentKind` types from `go.opentelemetry.io/otel/sdk/metric/view`. (#3459)\n- The `Stream` type is added to `go.opentelemetry.io/otel/sdk/metric` to define a metric data stream a view will produce. (#3459)\n- The `AssertHasAttributes` allows instrument authors to test that datapoints returned have appropriate attributes. (#3487)\n\n### Changed\n\n- The `\"go.opentelemetry.io/otel/sdk/metric\".WithReader` option no longer accepts views to associate with the `Reader`.\n   Instead, views are now registered directly with the `MeterProvider` via the new `WithView` option.\n   The views registered with the `MeterProvider` apply to all `Reader`s. (#3387)\n- The `Temporality(view.InstrumentKind) metricdata.Temporality` and `Aggregation(view.InstrumentKind) aggregation.Aggregation` methods are added to the `\"go.opentelemetry.io/otel/sdk/metric\".Exporter` interface. (#3260)\n- The `Temporality(view.InstrumentKind) metricdata.Temporality` and `Aggregation(view.InstrumentKind) aggregation.Aggregation` methods are added to the `\"go.opentelemetry.io/otel/exporters/otlp/otlpmetric\".Client` interface. (#3260)\n- The `WithTemporalitySelector` and `WithAggregationSelector` `ReaderOption`s have been changed to `ManualReaderOption`s in the `go.opentelemetry.io/otel/sdk/metric` package. (#3260)\n- The periodic reader in the `go.opentelemetry.io/otel/sdk/metric` package now uses the temporality and aggregation selectors from its configured exporter instead of accepting them as options. (#3260)\n\n### Fixed\n\n- The `go.opentelemetry.io/otel/exporters/prometheus` exporter fixes duplicated `_total` suffixes. (#3369)\n- Remove comparable requirement for `Reader`s. (#3387)\n- Cumulative metrics from the OpenCensus bridge (`go.opentelemetry.io/otel/bridge/opencensus`) are defined as monotonic sums, instead of non-monotonic. (#3389)\n- Asynchronous counters (`Counter` and `UpDownCounter`) from the metric SDK now produce delta sums when configured with delta temporality. (#3398)\n- Exported `Status` codes in the `go.opentelemetry.io/otel/exporters/zipkin` exporter are now exported as all upper case values. (#3340)\n- `Aggregation`s from `go.opentelemetry.io/otel/sdk/metric` with no data are not exported. (#3394, #3436)\n- Re-enabled Attribute Filters in the Metric SDK. (#3396)\n- Asynchronous callbacks are only called if they are registered with at least one instrument that does not use drop aggregation. (#3408)\n- Do not report empty partial-success responses in the `go.opentelemetry.io/otel/exporters/otlp` exporters. (#3438, #3432)\n- Handle partial success responses in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` exporters. (#3162, #3440)\n- Prevent duplicate Prometheus description, unit, and type. (#3469)\n- Prevents panic when using incorrect `attribute.Value.As[Type]Slice()`. (#3489)\n\n### Removed\n\n- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric.Client` interface is removed. (#3486)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric.New` function is removed. Use the `otlpmetric[http|grpc].New` directly. (#3486)\n\n### Deprecated\n\n- The `go.opentelemetry.io/otel/sdk/metric/view` package is deprecated.\n  Use `Instrument`, `InstrumentKind`, `View`, and `NewView` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3476)\n\n## [1.11.1/0.33.0] 2022-10-19\n\n### Added\n\n- The Prometheus exporter in `go.opentelemetry.io/otel/exporters/prometheus` registers with a Prometheus registerer on creation.\n   By default, it will register with the default Prometheus registerer.\n   A non-default registerer can be used by passing the `WithRegisterer` option. (#3239)\n- Added the `WithAggregationSelector` option to the `go.opentelemetry.io/otel/exporters/prometheus` package to change the default `AggregationSelector` used. (#3341)\n- The Prometheus exporter in `go.opentelemetry.io/otel/exporters/prometheus` converts the `Resource` associated with metric exports into a `target_info` metric. (#3285)\n\n### Changed\n\n- The `\"go.opentelemetry.io/otel/exporters/prometheus\".New` function is updated to return an error.\n   It will return an error if the exporter fails to register with Prometheus. (#3239)\n\n### Fixed\n\n- The URL-encoded values from the `OTEL_RESOURCE_ATTRIBUTES` environment variable are decoded. (#2963)\n- The `baggage.NewMember` function decodes the `value` parameter instead of directly using it.\n   This fixes the implementation to be compliant with the W3C specification. (#3226)\n- Slice attributes of the `attribute` package are now comparable based on their value, not instance. (#3108 #3252)\n- The `Shutdown` and `ForceFlush` methods of the `\"go.opentelemetry.io/otel/sdk/trace\".TraceProvider` no longer return an error when no processor is registered. (#3268)\n- The Prometheus exporter in `go.opentelemetry.io/otel/exporters/prometheus` cumulatively sums histogram buckets. (#3281)\n- The sum of each histogram data point is now uniquely exported by the `go.opentelemetry.io/otel/exporters/otlpmetric` exporters. (#3284, #3293)\n- Recorded values for asynchronous counters (`Counter` and `UpDownCounter`) are interpreted as exact, not incremental, sum values by the metric SDK. (#3350, #3278)\n- `UpDownCounters` are now correctly output as Prometheus gauges in the `go.opentelemetry.io/otel/exporters/prometheus` exporter. (#3358)\n- The Prometheus exporter in `go.opentelemetry.io/otel/exporters/prometheus` no longer describes the metrics it will send to Prometheus on startup.\n   Instead the exporter is defined as an \"unchecked\" collector for Prometheus.\n   This fixes the `reader is not registered` warning currently emitted on startup. (#3291 #3342)\n- The `go.opentelemetry.io/otel/exporters/prometheus` exporter now correctly adds `_total` suffixes to counter metrics. (#3360)\n- The `go.opentelemetry.io/otel/exporters/prometheus` exporter now adds a unit suffix to metric names.\n   This can be disabled using the `WithoutUnits()` option added to that package. (#3352)\n\n## [1.11.0/0.32.3] 2022-10-12\n\n### Added\n\n- Add default User-Agent header to OTLP exporter requests (`go.opentelemetry.io/otel/exporters/otlptrace/otlptracegrpc` and `go.opentelemetry.io/otel/exporters/otlptrace/otlptracehttp`). (#3261)\n\n### Changed\n\n- `span.SetStatus` has been updated such that calls that lower the status are now no-ops. (#3214)\n- Upgrade `golang.org/x/sys/unix` from `v0.0.0-20210423185535-09eb48e85fd7` to `v0.0.0-20220919091848-fb04ddd9f9c8`.\n  This addresses [GO-2022-0493](https://pkg.go.dev/vuln/GO-2022-0493). (#3235)\n\n## [0.32.2] Metric SDK (Alpha) - 2022-10-11\n\n### Added\n\n- Added an example of using metric views to customize instruments. (#3177)\n- Add default User-Agent header to OTLP exporter requests (`go.opentelemetry.io/otel/exporters/otlpmetric/otlpmetricgrpc` and `go.opentelemetry.io/otel/exporters/otlpmetric/otlpmetrichttp`). (#3261)\n\n### Changed\n\n- Flush pending measurements with the `PeriodicReader` in the `go.opentelemetry.io/otel/sdk/metric` when `ForceFlush` or `Shutdown` are called. (#3220)\n- Update histogram default bounds to match the requirements of the latest specification. (#3222)\n- Encode the HTTP status code in the OpenTracing bridge (`go.opentelemetry.io/otel/bridge/opentracing`) as an integer.  (#3265)\n\n### Fixed\n\n- Use default view if instrument does not match any registered view of a reader. (#3224, #3237)\n- Return the same instrument every time a user makes the exact same instrument creation call. (#3229, #3251)\n- Return the existing instrument when a view transforms a creation call to match an existing instrument. (#3240, #3251)\n- Log a warning when a conflicting instrument (e.g. description, unit, data-type) is created instead of returning an error. (#3251)\n- The OpenCensus bridge no longer sends empty batches of metrics. (#3263)\n\n## [0.32.1] Metric SDK (Alpha) - 2022-09-22\n\n### Changed\n\n- The Prometheus exporter sanitizes OpenTelemetry instrument names when exporting.\n   Invalid characters are replaced with `_`. (#3212)\n\n### Added\n\n- The metric portion of the OpenCensus bridge (`go.opentelemetry.io/otel/bridge/opencensus`) has been reintroduced. (#3192)\n- The OpenCensus bridge example (`go.opentelemetry.io/otel/example/opencensus`) has been reintroduced. (#3206)\n\n### Fixed\n\n- Updated go.mods to point to valid versions of the sdk. (#3216)\n- Set the `MeterProvider` resource on all exported metric data. (#3218)\n\n## [0.32.0] Revised Metric SDK (Alpha) - 2022-09-18\n\n### Changed\n\n- The metric SDK in `go.opentelemetry.io/otel/sdk/metric` is completely refactored to comply with the OpenTelemetry specification.\n  Please see the package documentation for how the new SDK is initialized and configured. (#3175)\n- Update the minimum supported go version to go1.18. Removes support for go1.17 (#3179)\n\n### Removed\n\n- The metric portion of the OpenCensus bridge (`go.opentelemetry.io/otel/bridge/opencensus`) has been removed.\n  A new bridge compliant with the revised metric SDK will be added back in a future release. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/aggregator/histogram` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/aggregator/sum` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/aggregator` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/controller/basic` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/controller/controllertest` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/controller/time` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/export/aggregation` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/export` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/metrictest` package is removed.\n  A replacement package that supports the new metric SDK will be added back in a future release. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/number` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/processor/basic` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/processor/processortest` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/processor/reducer` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/registry` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/sdkapi` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/selector/simple` package is removed, see the new metric SDK. (#3175)\n- The `\"go.opentelemetry.io/otel/sdk/metric\".ErrUninitializedInstrument` variable was removed. (#3175)\n- The `\"go.opentelemetry.io/otel/sdk/metric\".ErrBadInstrument` variable was removed. (#3175)\n- The `\"go.opentelemetry.io/otel/sdk/metric\".Accumulator` type was removed, see the `MeterProvider`in the new metric SDK. (#3175)\n- The `\"go.opentelemetry.io/otel/sdk/metric\".NewAccumulator` function was removed, see `NewMeterProvider`in the new metric SDK. (#3175)\n- The deprecated `\"go.opentelemetry.io/otel/sdk/metric\".AtomicFieldOffsets` function was removed. (#3175)\n\n## [1.10.0] - 2022-09-09\n\n### Added\n\n- Support Go 1.19. (#3077)\n  Include compatibility testing and document support. (#3077)\n- Support the OTLP ExportTracePartialSuccess response; these are passed to the registered error handler. (#3106)\n- Upgrade go.opentelemetry.io/proto/otlp from v0.18.0 to v0.19.0 (#3107)\n\n### Changed\n\n- Fix misidentification of OpenTelemetry `SpanKind` in OpenTracing bridge (`go.opentelemetry.io/otel/bridge/opentracing`).  (#3096)\n- Attempting to start a span with a nil `context` will no longer cause a panic. (#3110)\n- All exporters will be shutdown even if one reports an error (#3091)\n- Ensure valid UTF-8 when truncating over-length attribute values. (#3156)\n\n## [1.9.0/0.0.3] - 2022-08-01\n\n### Added\n\n- Add support for Schema Files format 1.1.x (metric \"split\" transform) with the new `go.opentelemetry.io/otel/schema/v1.1` package. (#2999)\n- Add the `go.opentelemetry.io/otel/semconv/v1.11.0` package.\n  The package contains semantic conventions from the `v1.11.0` version of the OpenTelemetry specification. (#3009)\n- Add the `go.opentelemetry.io/otel/semconv/v1.12.0` package.\n  The package contains semantic conventions from the `v1.12.0` version of the OpenTelemetry specification. (#3010)\n- Add the `http.method` attribute to HTTP server metric from all `go.opentelemetry.io/otel/semconv/*` packages. (#3018)\n\n### Fixed\n\n- Invalid warning for context setup being deferred in `go.opentelemetry.io/otel/bridge/opentracing` package. (#3029)\n\n## [1.8.0/0.31.0] - 2022-07-08\n\n### Added\n\n- Add support for `opentracing.TextMap` format in the `Inject` and `Extract` methods\nof the `\"go.opentelemetry.io/otel/bridge/opentracing\".BridgeTracer` type. (#2911)\n\n### Changed\n\n- The `crosslink` make target has been updated to use the `go.opentelemetry.io/build-tools/crosslink` package. (#2886)\n- In the `go.opentelemetry.io/otel/sdk/instrumentation` package rename `Library` to `Scope` and alias `Library` as `Scope` (#2976)\n- Move metric no-op implementation form `nonrecording` to `metric` package. (#2866)\n\n### Removed\n\n- Support for go1.16. Support is now only for go1.17 and go1.18 (#2917)\n\n### Deprecated\n\n- The `Library` struct in the `go.opentelemetry.io/otel/sdk/instrumentation` package is deprecated.\n  Use the equivalent `Scope` struct instead. (#2977)\n- The `ReadOnlySpan.InstrumentationLibrary` method from the `go.opentelemetry.io/otel/sdk/trace` package is deprecated.\n  Use the equivalent `ReadOnlySpan.InstrumentationScope` method instead. (#2977)\n\n## [1.7.0/0.30.0] - 2022-04-28\n\n### Added\n\n- Add the `go.opentelemetry.io/otel/semconv/v1.8.0` package.\n  The package contains semantic conventions from the `v1.8.0` version of the OpenTelemetry specification. (#2763)\n- Add the `go.opentelemetry.io/otel/semconv/v1.9.0` package.\n  The package contains semantic conventions from the `v1.9.0` version of the OpenTelemetry specification. (#2792)\n- Add the `go.opentelemetry.io/otel/semconv/v1.10.0` package.\n  The package contains semantic conventions from the `v1.10.0` version of the OpenTelemetry specification. (#2842)\n- Added an in-memory exporter to metrictest to aid testing with a full SDK. (#2776)\n\n### Fixed\n\n- Globally delegated instruments are unwrapped before delegating asynchronous callbacks. (#2784)\n- Remove import of `testing` package in non-tests builds of the `go.opentelemetry.io/otel` package. (#2786)\n\n### Changed\n\n- The `WithLabelEncoder` option from the `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` package is renamed to `WithAttributeEncoder`. (#2790)\n- The `LabelFilterSelector` interface from `go.opentelemetry.io/otel/sdk/metric/processor/reducer` is renamed to `AttributeFilterSelector`.\n  The method included in the renamed interface also changed from `LabelFilterFor` to `AttributeFilterFor`. (#2790)\n- The `Metadata.Labels` method from the `go.opentelemetry.io/otel/sdk/metric/export` package is renamed to `Metadata.Attributes`.\n  Consequentially, the `Record` type from the same package also has had the embedded method renamed. (#2790)\n\n### Deprecated\n\n- The `Iterator.Label` method in the `go.opentelemetry.io/otel/attribute` package is deprecated.\n  Use the equivalent `Iterator.Attribute` method instead. (#2790)\n- The `Iterator.IndexedLabel` method in the `go.opentelemetry.io/otel/attribute` package is deprecated.\n  Use the equivalent `Iterator.IndexedAttribute` method instead. (#2790)\n- The `MergeIterator.Label` method in the `go.opentelemetry.io/otel/attribute` package is deprecated.\n  Use the equivalent `MergeIterator.Attribute` method instead. (#2790)\n\n### Removed\n\n- Removed the `Batch` type from the `go.opentelemetry.io/otel/sdk/metric/metrictest` package. (#2864)\n- Removed the `Measurement` type from the `go.opentelemetry.io/otel/sdk/metric/metrictest` package. (#2864)\n\n## [0.29.0] - 2022-04-11\n\n### Added\n\n- The metrics global package was added back into several test files. (#2764)\n- The `Meter` function is added back to the `go.opentelemetry.io/otel/metric/global` package.\n  This function is a convenience function equivalent to calling `global.MeterProvider().Meter(...)`. (#2750)\n\n### Removed\n\n- Removed module the `go.opentelemetry.io/otel/sdk/export/metric`.\n  Use the `go.opentelemetry.io/otel/sdk/metric` module instead. (#2720)\n\n### Changed\n\n- Don't panic anymore when setting a global MeterProvider to itself. (#2749)\n- Upgrade `go.opentelemetry.io/proto/otlp` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` from `v0.12.1` to `v0.15.0`.\n  This replaces the use of the now deprecated `InstrumentationLibrary` and `InstrumentationLibraryMetrics` types and fields in the proto library with the equivalent `InstrumentationScope` and `ScopeMetrics`. (#2748)\n\n## [1.6.3] - 2022-04-07\n\n### Fixed\n\n- Allow non-comparable global `MeterProvider`, `TracerProvider`, and `TextMapPropagator` types to be set. (#2772, #2773)\n\n## [1.6.2] - 2022-04-06\n\n### Changed\n\n- Don't panic anymore when setting a global TracerProvider or TextMapPropagator to itself. (#2749)\n- Upgrade `go.opentelemetry.io/proto/otlp` in `go.opentelemetry.io/otel/exporters/otlp/otlptrace` from `v0.12.1` to `v0.15.0`.\n  This replaces the use of the now deprecated `InstrumentationLibrary` and `InstrumentationLibrarySpans` types and fields in the proto library with the equivalent `InstrumentationScope` and `ScopeSpans`. (#2748)\n\n## [1.6.1] - 2022-03-28\n\n### Fixed\n\n- The `go.opentelemetry.io/otel/schema/*` packages now use the correct schema URL for their `SchemaURL` constant.\n  Instead of using `\"https://opentelemetry.io/schemas/v<version>\"` they now use the correct URL without a `v` prefix, `\"https://opentelemetry.io/schemas/<version>\"`. (#2743, #2744)\n\n### Security\n\n- Upgrade `go.opentelemetry.io/proto/otlp` from `v0.12.0` to `v0.12.1`.\n  This includes an indirect upgrade of `github.com/grpc-ecosystem/grpc-gateway` which resolves [a vulnerability](https://nvd.nist.gov/vuln/detail/CVE-2019-11254) from `gopkg.in/yaml.v2` in version `v2.2.3`. (#2724, #2728)\n\n## [1.6.0/0.28.0] - 2022-03-23\n\n### ⚠️ Notice ⚠️\n\nThis update is a breaking change of the unstable Metrics API.\nCode instrumented with the `go.opentelemetry.io/otel/metric` will need to be modified.\n\n### Added\n\n- Add metrics exponential histogram support.\n  New mapping functions have been made available in `sdk/metric/aggregator/exponential/mapping` for other OpenTelemetry projects to take dependencies on. (#2502)\n- Add Go 1.18 to our compatibility tests. (#2679)\n- Allow configuring the Sampler with the `OTEL_TRACES_SAMPLER` and `OTEL_TRACES_SAMPLER_ARG` environment variables. (#2305, #2517)\n- Add the `metric/global` for obtaining and setting the global `MeterProvider`. (#2660)\n\n### Changed\n\n- The metrics API has been significantly changed to match the revised OpenTelemetry specification.\n  High-level changes include:\n\n  - Synchronous and asynchronous instruments are now handled by independent `InstrumentProvider`s.\n    These `InstrumentProvider`s are managed with a `Meter`.\n  - Synchronous and asynchronous instruments are grouped into their own packages based on value types.\n  - Asynchronous callbacks can now be registered with a `Meter`.\n\n  Be sure to check out the metric module documentation for more information on how to use the revised API. (#2587, #2660)\n\n### Fixed\n\n- Fallback to general attribute limits when span specific ones are not set in the environment. (#2675, #2677)\n\n## [1.5.0] - 2022-03-16\n\n### Added\n\n- Log the Exporters configuration in the TracerProviders message. (#2578)\n- Added support to configure the span limits with environment variables.\n  The following environment variables are supported. (#2606, #2637)\n  - `OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT`\n  - `OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT`\n  - `OTEL_SPAN_EVENT_COUNT_LIMIT`\n  - `OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT`\n  - `OTEL_SPAN_LINK_COUNT_LIMIT`\n  - `OTEL_LINK_ATTRIBUTE_COUNT_LIMIT`\n\n  If the provided environment variables are invalid (negative), the default values would be used.\n- Rename the `gc` runtime name to `go` (#2560)\n- Add resource container ID detection. (#2418)\n- Add span attribute value length limit.\n  The new `AttributeValueLengthLimit` field is added to the `\"go.opentelemetry.io/otel/sdk/trace\".SpanLimits` type to configure this limit for a `TracerProvider`.\n  The default limit for this resource is \"unlimited\". (#2637)\n- Add the `WithRawSpanLimits` option to `go.opentelemetry.io/otel/sdk/trace`.\n  This option replaces the `WithSpanLimits` option.\n  Zero or negative values will not be changed to the default value like `WithSpanLimits` does.\n  Setting a limit to zero will effectively disable the related resource it limits and setting to a negative value will mean that resource is unlimited.\n  Consequentially, limits should be constructed using `NewSpanLimits` and updated accordingly. (#2637)\n\n### Changed\n\n- Drop oldest tracestate `Member` when capacity is reached. (#2592)\n- Add event and link drop counts to the exported data from the `oltptrace` exporter. (#2601)\n- Unify path cleaning functionally in the `otlpmetric` and `otlptrace` configuration. (#2639)\n- Change the debug message from the `sdk/trace.BatchSpanProcessor` to reflect the count is cumulative. (#2640)\n- Introduce new internal `envconfig` package for OTLP exporters. (#2608)\n- If `http.Request.Host` is empty, fall back to use `URL.Host` when populating `http.host` in the `semconv` packages. (#2661)\n\n### Fixed\n\n- Remove the OTLP trace exporter limit of SpanEvents when exporting. (#2616)\n- Default to port `4318` instead of `4317` for the `otlpmetrichttp` and `otlptracehttp` client. (#2614, #2625)\n- Unlimited span limits are now supported (negative values). (#2636, #2637)\n\n### Deprecated\n\n- Deprecated `\"go.opentelemetry.io/otel/sdk/trace\".WithSpanLimits`.\n  Use `WithRawSpanLimits` instead.\n  That option allows setting unlimited and zero limits, this option does not.\n  This option will be kept until the next major version incremented release. (#2637)\n\n## [1.4.1] - 2022-02-16\n\n### Fixed\n\n- Fix race condition in reading the dropped spans number for the `BatchSpanProcessor`. (#2615)\n\n## [1.4.0] - 2022-02-11\n\n### Added\n\n- Use `OTEL_EXPORTER_ZIPKIN_ENDPOINT` environment variable to specify zipkin collector endpoint. (#2490)\n- Log the configuration of `TracerProvider`s, and `Tracer`s for debugging.\n  To enable use a logger with Verbosity (V level) `>=1`. (#2500)\n- Added support to configure the batch span-processor with environment variables.\n  The following environment variables are used. (#2515)\n  - `OTEL_BSP_SCHEDULE_DELAY`\n  - `OTEL_BSP_EXPORT_TIMEOUT`\n  - `OTEL_BSP_MAX_QUEUE_SIZE`.\n  - `OTEL_BSP_MAX_EXPORT_BATCH_SIZE`\n\n### Changed\n\n- Zipkin exporter exports `Resource` attributes in the `Tags` field. (#2589)\n\n### Deprecated\n\n- Deprecate module the `go.opentelemetry.io/otel/sdk/export/metric`.\n  Use the `go.opentelemetry.io/otel/sdk/metric` module instead. (#2382)\n- Deprecate `\"go.opentelemetry.io/otel/sdk/metric\".AtomicFieldOffsets`. (#2445)\n\n### Fixed\n\n- Fixed the instrument kind for noop async instruments to correctly report an implementation. (#2461)\n- Fix UDP packets overflowing with Jaeger payloads. (#2489, #2512)\n- Change the `otlpmetric.Client` interface's `UploadMetrics` method to accept a single `ResourceMetrics` instead of a slice of them. (#2491)\n- Specify explicit buckets in Prometheus example, fixing issue where example only has `+inf` bucket. (#2419, #2493)\n- W3C baggage will now decode urlescaped values. (#2529)\n- Baggage members are now only validated once, when calling `NewMember` and not also when adding it to the baggage itself. (#2522)\n- The order attributes are dropped from spans in the `go.opentelemetry.io/otel/sdk/trace` package when capacity is reached is fixed to be in compliance with the OpenTelemetry specification.\n  Instead of dropping the least-recently-used attribute, the last added attribute is dropped.\n  This drop order still only applies to attributes with unique keys not already contained in the span.\n  If an attribute is added with a key already contained in the span, that attribute is updated to the new value being added. (#2576)\n\n### Removed\n\n- Updated `go.opentelemetry.io/proto/otlp` from `v0.11.0` to `v0.12.0`. This version removes a number of deprecated methods. (#2546)\n  - [`Metric.GetIntGauge()`](https://pkg.go.dev/go.opentelemetry.io/proto/otlp@v0.11.0/metrics/v1#Metric.GetIntGauge)\n  - [`Metric.GetIntHistogram()`](https://pkg.go.dev/go.opentelemetry.io/proto/otlp@v0.11.0/metrics/v1#Metric.GetIntHistogram)\n  - [`Metric.GetIntSum()`](https://pkg.go.dev/go.opentelemetry.io/proto/otlp@v0.11.0/metrics/v1#Metric.GetIntSum)\n\n## [1.3.0] - 2021-12-10\n\n### ⚠️ Notice ⚠️\n\nWe have updated the project minimum supported Go version to 1.16\n\n### Added\n\n- Added an internal Logger.\n  This can be used by the SDK and API to provide users with feedback of the internal state.\n  To enable verbose logs configure the logger which will print V(1) logs. For debugging information configure to print V(5) logs. (#2343)\n- Add the `WithRetry` `Option` and the `RetryConfig` type to the `go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetrichttp` package to specify retry behavior consistently. (#2425)\n- Add `SpanStatusFromHTTPStatusCodeAndSpanKind` to all `semconv` packages to return a span status code similar to `SpanStatusFromHTTPStatusCode`, but exclude `4XX` HTTP errors as span errors if the span is of server kind. (#2296)\n\n### Changed\n\n- The `\"go.opentelemetry.io/otel/exporter/otel/otlptrace/otlptracegrpc\".Client` now uses the underlying gRPC `ClientConn` to handle name resolution, TCP connection establishment (with retries and backoff) and TLS handshakes, and handling errors on established connections by re-resolving the name and reconnecting. (#2329)\n- The `\"go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetricgrpc\".Client` now uses the underlying gRPC `ClientConn` to handle name resolution, TCP connection establishment (with retries and backoff) and TLS handshakes, and handling errors on established connections by re-resolving the name and reconnecting. (#2425)\n- The `\"go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetricgrpc\".RetrySettings` type is renamed to `RetryConfig`. (#2425)\n- The `go.opentelemetry.io/otel/exporter/otel/*` gRPC exporters now default to using the host's root CA set if none are provided by the user and `WithInsecure` is not specified. (#2432)\n- Change `resource.Default` to be evaluated the first time it is called, rather than on import. This allows the caller the option to update `OTEL_RESOURCE_ATTRIBUTES` first, such as with `os.Setenv`. (#2371)\n\n### Fixed\n\n- The `go.opentelemetry.io/otel/exporter/otel/*` exporters are updated to handle per-signal and universal endpoints according to the OpenTelemetry specification.\n  Any per-signal endpoint set via an `OTEL_EXPORTER_OTLP_<signal>_ENDPOINT` environment variable is now used without modification of the path.\n  When `OTEL_EXPORTER_OTLP_ENDPOINT` is set, if it contains a path, that path is used as a base path which per-signal paths are appended to. (#2433)\n- Basic metric controller updated to use sync.Map to avoid blocking calls (#2381)\n- The `go.opentelemetry.io/otel/exporter/jaeger` correctly sets the `otel.status_code` value to be a string of `ERROR` or `OK` instead of an integer code. (#2439, #2440)\n\n### Deprecated\n\n- Deprecated the `\"go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetrichttp\".WithMaxAttempts` `Option`, use the new `WithRetry` `Option` instead. (#2425)\n- Deprecated the `\"go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetrichttp\".WithBackoff` `Option`, use the new `WithRetry` `Option` instead. (#2425)\n\n### Removed\n\n- Remove the metric Processor's ability to convert cumulative to delta aggregation temporality. (#2350)\n- Remove the metric Bound Instruments interface and implementations. (#2399)\n- Remove the metric MinMaxSumCount kind aggregation and the corresponding OTLP export path. (#2423)\n- Metric SDK removes the \"exact\" aggregator for histogram instruments, as it performed a non-standard aggregation for OTLP export (creating repeated Gauge points) and worked its way into a number of confusing examples. (#2348)\n\n## [1.2.0] - 2021-11-12\n\n### Changed\n\n- Metric SDK `export.ExportKind`, `export.ExportKindSelector` types have been renamed to `aggregation.Temporality` and `aggregation.TemporalitySelector` respectively to keep in line with current specification and protocol along with built-in selectors (e.g., `aggregation.CumulativeTemporalitySelector`, ...). (#2274)\n- The Metric `Exporter` interface now requires a `TemporalitySelector` method instead of an `ExportKindSelector`. (#2274)\n- Metrics API cleanup. The `metric/sdkapi` package has been created to relocate the API-to-SDK interface:\n  - The following interface types simply moved from `metric` to `metric/sdkapi`: `Descriptor`, `MeterImpl`, `InstrumentImpl`, `SyncImpl`, `BoundSyncImpl`, `AsyncImpl`, `AsyncRunner`, `AsyncSingleRunner`, and `AsyncBatchRunner`\n  - The following struct types moved and are replaced with type aliases, since they are exposed to the user: `Observation`, `Measurement`.\n  - The No-op implementations of sync and async instruments are no longer exported, new functions `sdkapi.NewNoopAsyncInstrument()` and `sdkapi.NewNoopSyncInstrument()` are provided instead. (#2271)\n- Update the SDK `BatchSpanProcessor` to export all queued spans when `ForceFlush` is called. (#2080, #2335)\n\n### Added\n\n- Add the `\"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc\".WithGRPCConn` option so the exporter can reuse an existing gRPC connection. (#2002)\n- Added a new `schema` module to help parse Schema Files in OTEP 0152 format. (#2267)\n- Added a new `MapCarrier` to the `go.opentelemetry.io/otel/propagation` package to hold propagated cross-cutting concerns as a `map[string]string` held in memory. (#2334)\n\n## [1.1.0] - 2021-10-27\n\n### Added\n\n- Add the `\"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc\".WithGRPCConn` option so the exporter can reuse an existing gRPC connection. (#2002)\n- Add the `go.opentelemetry.io/otel/semconv/v1.7.0` package.\n  The package contains semantic conventions from the `v1.7.0` version of the OpenTelemetry specification. (#2320)\n- Add the `go.opentelemetry.io/otel/semconv/v1.6.1` package.\n  The package contains semantic conventions from the `v1.6.1` version of the OpenTelemetry specification. (#2321)\n- Add the `go.opentelemetry.io/otel/semconv/v1.5.0` package.\n  The package contains semantic conventions from the `v1.5.0` version of the OpenTelemetry specification. (#2322)\n  - When upgrading from the `semconv/v1.4.0` package note the following name changes:\n    - `K8SReplicasetUIDKey` -> `K8SReplicaSetUIDKey`\n    - `K8SReplicasetNameKey` -> `K8SReplicaSetNameKey`\n    - `K8SStatefulsetUIDKey` -> `K8SStatefulSetUIDKey`\n    - `k8SStatefulsetNameKey` -> `K8SStatefulSetNameKey`\n    - `K8SDaemonsetUIDKey` -> `K8SDaemonSetUIDKey`\n    - `K8SDaemonsetNameKey` -> `K8SDaemonSetNameKey`\n\n### Changed\n\n- Links added to a span will be dropped by the SDK if they contain an invalid span context (#2275).\n\n### Fixed\n\n- The `\"go.opentelemetry.io/otel/semconv/v1.4.0\".HTTPServerAttributesFromHTTPRequest` now correctly only sets the HTTP client IP attribute even if the connection was routed with proxies and there are multiple addresses in the `X-Forwarded-For` header. (#2282, #2284)\n- The `\"go.opentelemetry.io/otel/semconv/v1.4.0\".NetAttributesFromHTTPRequest` function correctly handles IPv6 addresses as IP addresses and sets the correct net peer IP instead of the net peer hostname attribute. (#2283, #2285)\n- The simple span processor shutdown method deterministically returns the exporter error status if it simultaneously finishes when the deadline is reached. (#2290, #2289)\n\n## [1.0.1] - 2021-10-01\n\n### Fixed\n\n- json stdout exporter no longer crashes due to concurrency bug. (#2265)\n\n## [Metrics 0.24.0] - 2021-10-01\n\n### Changed\n\n- NoopMeterProvider is now private and NewNoopMeterProvider must be used to obtain a noopMeterProvider. (#2237)\n- The Metric SDK `Export()` function takes a new two-level reader interface for iterating over results one instrumentation library at a time. (#2197)\n  - The former `\"go.opentelemetry.io/otel/sdk/export/metric\".CheckpointSet` is renamed `Reader`.\n  - The new interface is named `\"go.opentelemetry.io/otel/sdk/export/metric\".InstrumentationLibraryReader`.\n\n## [1.0.0] - 2021-09-20\n\nThis is the first stable release for the project.\nThis release includes an API and SDK for the tracing signal that will comply with the stability guarantees defined by the projects [versioning policy](./VERSIONING.md).\n\n### Added\n\n- OTLP trace exporter now sets the `SchemaURL` field in the exported telemetry if the Tracer has `WithSchemaURL` option. (#2242)\n\n### Fixed\n\n- Slice-valued attributes can correctly be used as map keys. (#2223)\n\n### Removed\n\n- Removed the `\"go.opentelemetry.io/otel/exporters/zipkin\".WithSDKOptions` function. (#2248)\n- Removed the deprecated package `go.opentelemetry.io/otel/oteltest`. (#2234)\n- Removed the deprecated package `go.opentelemetry.io/otel/bridge/opencensus/utils`. (#2233)\n- Removed deprecated functions, types, and methods from `go.opentelemetry.io/otel/attribute` package.\n  Use the typed functions and methods added to the package instead. (#2235)\n  - The `Key.Array` method is removed.\n  - The `Array` function is removed.\n  - The `Any` function is removed.\n  - The `ArrayValue` function is removed.\n  - The `AsArray` function is removed.\n\n## [1.0.0-RC3] - 2021-09-02\n\n### Added\n\n- Added `ErrorHandlerFunc` to use a function as an `\"go.opentelemetry.io/otel\".ErrorHandler`. (#2149)\n- Added `\"go.opentelemetry.io/otel/trace\".WithStackTrace` option to add a stack trace when using `span.RecordError` or when panic is handled in `span.End`. (#2163)\n- Added typed slice attribute types and functionality to the `go.opentelemetry.io/otel/attribute` package to replace the existing array type and functions. (#2162)\n  - `BoolSlice`, `IntSlice`, `Int64Slice`, `Float64Slice`, and `StringSlice` replace the use of the `Array` function in the package.\n- Added the `go.opentelemetry.io/otel/example/fib` example package.\n  Included is an example application that computes Fibonacci numbers. (#2203)\n\n### Changed\n\n- Metric instruments have been renamed to match the (feature-frozen) metric API specification:\n  - ValueRecorder becomes Histogram\n  - ValueObserver becomes Gauge\n  - SumObserver becomes CounterObserver\n  - UpDownSumObserver becomes UpDownCounterObserver\n  The API exported from this project is still considered experimental. (#2202)\n- Metric SDK/API implementation type `InstrumentKind` moves into `sdkapi` sub-package. (#2091)\n- The Metrics SDK export record no longer contains a Resource pointer, the SDK `\"go.opentelemetry.io/otel/sdk/trace/export/metric\".Exporter.Export()` function for push-based exporters now takes a single Resource argument, pull-based exporters use `\"go.opentelemetry.io/otel/sdk/metric/controller/basic\".Controller.Resource()`. (#2120)\n- The JSON output of the `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` is harmonized now such that the output is \"plain\" JSON objects after each other of the form `{ ... } { ... } { ... }`. Earlier the JSON objects describing a span were wrapped in a slice for each `Exporter.ExportSpans` call, like `[ { ... } ][ { ... } { ... } ]`. Outputting JSON object directly after each other is consistent with JSON loggers, and a bit easier to parse and read. (#2196)\n- Update the `NewTracerConfig`, `NewSpanStartConfig`, `NewSpanEndConfig`, and `NewEventConfig` function in the `go.opentelemetry.io/otel/trace` package to return their respective configurations as structs instead of pointers to the struct. (#2212)\n\n### Deprecated\n\n- The `go.opentelemetry.io/otel/bridge/opencensus/utils` package is deprecated.\n  All functionality from this package now exists in the `go.opentelemetry.io/otel/bridge/opencensus` package.\n  The functions from that package should be used instead. (#2166)\n- The `\"go.opentelemetry.io/otel/attribute\".Array` function and the related `ARRAY` value type is deprecated.\n  Use the typed `*Slice` functions and types added to the package instead. (#2162)\n- The `\"go.opentelemetry.io/otel/attribute\".Any` function is deprecated.\n  Use the typed functions instead. (#2181)\n- The `go.opentelemetry.io/otel/oteltest` package is deprecated.\n  The `\"go.opentelemetry.io/otel/sdk/trace/tracetest\".SpanRecorder` can be registered with the default SDK (`go.opentelemetry.io/otel/sdk/trace`) as a `SpanProcessor` and used as a replacement for this deprecated package. (#2188)\n\n### Removed\n\n- Removed metrics test package `go.opentelemetry.io/otel/sdk/export/metric/metrictest`. (#2105)\n\n### Fixed\n\n- The `fromEnv` detector no longer throws an error when `OTEL_RESOURCE_ATTRIBUTES` environment variable is not set or empty. (#2138)\n- Setting the global `ErrorHandler` with `\"go.opentelemetry.io/otel\".SetErrorHandler` multiple times is now supported. (#2160, #2140)\n- The `\"go.opentelemetry.io/otel/attribute\".Any` function now supports `int32` values. (#2169)\n- Multiple calls to `\"go.opentelemetry.io/otel/sdk/metric/controller/basic\".WithResource()` are handled correctly, and when no resources are provided `\"go.opentelemetry.io/otel/sdk/resource\".Default()` is used. (#2120)\n- The `WithoutTimestamps` option for the `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` exporter causes the exporter to correctly omit timestamps. (#2195)\n- Fixed typos in resources.go. (#2201)\n\n## [1.0.0-RC2] - 2021-07-26\n\n### Added\n\n- Added `WithOSDescription` resource configuration option to set OS (Operating System) description resource attribute (`os.description`). (#1840)\n- Added `WithOS` resource configuration option to set all OS (Operating System) resource attributes at once. (#1840)\n- Added the `WithRetry` option to the `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` package.\n  This option is a replacement for the removed `WithMaxAttempts` and `WithBackoff` options. (#2095)\n- Added API `LinkFromContext` to return Link which encapsulates SpanContext from provided context and also encapsulates attributes. (#2115)\n- Added a new `Link` type under the SDK `otel/sdk/trace` package that counts the number of attributes that were dropped for surpassing the `AttributePerLinkCountLimit` configured in the Span's `SpanLimits`.\n  This new type replaces the equal-named API `Link` type found in the `otel/trace` package for most usages within the SDK.\n  For example, instances of this type are now returned by the `Links()` function of `ReadOnlySpan`s provided in places like the `OnEnd` function of `SpanProcessor` implementations. (#2118)\n- Added the `SpanRecorder` type to the `go.opentelemetry.io/otel/skd/trace/tracetest` package.\n  This type can be used with the default SDK as a `SpanProcessor` during testing. (#2132)\n\n### Changed\n\n- The `SpanModels` function is now exported from the `go.opentelemetry.io/otel/exporters/zipkin` package to convert OpenTelemetry spans into Zipkin model spans. (#2027)\n- Rename the `\"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc\".RetrySettings` to `RetryConfig`. (#2095)\n\n### Deprecated\n\n- The `TextMapCarrier` and `TextMapPropagator` from the `go.opentelemetry.io/otel/oteltest` package and their associated creation functions (`TextMapCarrier`, `NewTextMapPropagator`) are deprecated. (#2114)\n- The `Harness` type from the `go.opentelemetry.io/otel/oteltest` package and its associated creation function, `NewHarness` are deprecated and will be removed in the next release. (#2123)\n- The `TraceStateFromKeyValues` function from the `go.opentelemetry.io/otel/oteltest` package is deprecated.\n  Use the `trace.ParseTraceState` function instead. (#2122)\n\n### Removed\n\n- Removed the deprecated package `go.opentelemetry.io/otel/exporters/trace/jaeger`. (#2020)\n- Removed the deprecated package `go.opentelemetry.io/otel/exporters/trace/zipkin`. (#2020)\n- Removed the `\"go.opentelemetry.io/otel/sdk/resource\".WithBuiltinDetectors` function.\n  The explicit `With*` options for every built-in detector should be used instead. (#2026 #2097)\n- Removed the `WithMaxAttempts` and `WithBackoff` options from the `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` package.\n  The retry logic of the package has been updated to match the `otlptracegrpc` package and accordingly a `WithRetry` option is added that should be used instead. (#2095)\n- Removed `DroppedAttributeCount` field from `otel/trace.Link` struct. (#2118)\n\n### Fixed\n\n- When using WithNewRoot, don't use the parent context for making sampling decisions. (#2032)\n- `oteltest.Tracer` now creates a valid `SpanContext` when using `WithNewRoot`. (#2073)\n- OS type detector now sets the correct `dragonflybsd` value for DragonFly BSD. (#2092)\n- The OTel span status is correctly transformed into the OTLP status in the `go.opentelemetry.io/otel/exporters/otlp/otlptrace` package.\n  This fix will by default set the status to `Unset` if it is not explicitly set to `Ok` or `Error`. (#2099 #2102)\n- The `Inject` method for the `\"go.opentelemetry.io/otel/propagation\".TraceContext` type no longer injects empty `tracestate` values. (#2108)\n- Use `6831` as default Jaeger agent port instead of `6832`. (#2131)\n\n## [Experimental Metrics v0.22.0] - 2021-07-19\n\n### Added\n\n- Adds HTTP support for OTLP metrics exporter. (#2022)\n\n### Removed\n\n- Removed the deprecated package `go.opentelemetry.io/otel/exporters/metric/prometheus`. (#2020)\n\n## [1.0.0-RC1] / 0.21.0 - 2021-06-18\n\nWith this release we are introducing a split in module versions.  The tracing API and SDK are entering the `v1.0.0` Release Candidate phase with `v1.0.0-RC1`\nwhile the experimental metrics API and SDK continue with `v0.x` releases at `v0.21.0`.  Modules at major version 1 or greater will not depend on modules\nwith major version 0.\n\n### Added\n\n- Adds `otlpgrpc.WithRetry`option for configuring the retry policy for transient errors on the otlp/gRPC exporter. (#1832)\n  - The following status codes are defined as transient errors:\n      | gRPC Status Code | Description |\n      | ---------------- | ----------- |\n      | 1  | Cancelled |\n      | 4  | Deadline Exceeded |\n      | 8  | Resource Exhausted |\n      | 10 | Aborted |\n      | 10 | Out of Range |\n      | 14 | Unavailable |\n      | 15 | Data Loss |\n- Added `Status` type to the `go.opentelemetry.io/otel/sdk/trace` package to represent the status of a span. (#1874)\n- Added `SpanStub` type and its associated functions to the `go.opentelemetry.io/otel/sdk/trace/tracetest` package.\n  This type can be used as a testing replacement for the `SpanSnapshot` that was removed from the `go.opentelemetry.io/otel/sdk/trace` package. (#1873)\n- Adds support for scheme in `OTEL_EXPORTER_OTLP_ENDPOINT` according to the spec. (#1886)\n- Adds `trace.WithSchemaURL` option for configuring the tracer with a Schema URL. (#1889)\n- Added an example of using OpenTelemetry Go as a trace context forwarder. (#1912)\n- `ParseTraceState` is added to the `go.opentelemetry.io/otel/trace` package.\n  It can be used to decode a `TraceState` from a `tracestate` header string value. (#1937)\n- Added `Len` method to the `TraceState` type in the `go.opentelemetry.io/otel/trace` package.\n  This method returns the number of list-members the `TraceState` holds. (#1937)\n- Creates package `go.opentelemetry.io/otel/exporters/otlp/otlptrace` that defines a trace exporter that uses a `otlptrace.Client` to send data.\n  Creates package `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` implementing a gRPC `otlptrace.Client` and offers convenience functions, `NewExportPipeline` and `InstallNewPipeline`, to setup and install a `otlptrace.Exporter` in tracing .(#1922)\n- Added `Baggage`, `Member`, and `Property` types to the `go.opentelemetry.io/otel/baggage` package along with their related functions. (#1967)\n- Added `ContextWithBaggage`, `ContextWithoutBaggage`, and `FromContext` functions to the `go.opentelemetry.io/otel/baggage` package.\n  These functions replace the `Set`, `Value`, `ContextWithValue`, `ContextWithoutValue`, and `ContextWithEmpty` functions from that package and directly work with the new `Baggage` type. (#1967)\n- The `OTEL_SERVICE_NAME` environment variable is the preferred source for `service.name`, used by the environment resource detector if a service name is present both there and in `OTEL_RESOURCE_ATTRIBUTES`. (#1969)\n- Creates package `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` implementing an HTTP `otlptrace.Client` and offers convenience functions, `NewExportPipeline` and `InstallNewPipeline`, to setup and install a `otlptrace.Exporter` in tracing. (#1963)\n- Changes `go.opentelemetry.io/otel/sdk/resource.NewWithAttributes` to require a schema URL. The old function is still available as `resource.NewSchemaless`. This is a breaking change. (#1938)\n- Several builtin resource detectors now correctly populate the schema URL. (#1938)\n- Creates package `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` that defines a metrics exporter that uses a `otlpmetric.Client` to send data.\n- Creates package `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` implementing a gRPC `otlpmetric.Client` and offers convenience functions, `New` and `NewUnstarted`, to create an `otlpmetric.Exporter`.(#1991)\n- Added `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` exporter. (#2005)\n- Added `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` exporter. (#2005)\n- Added a `TracerProvider()` method to the `\"go.opentelemetry.io/otel/trace\".Span` interface. This can be used to obtain a `TracerProvider` from a given span that utilizes the same trace processing pipeline.  (#2009)\n\n### Changed\n\n- Make `NewSplitDriver` from `go.opentelemetry.io/otel/exporters/otlp` take variadic arguments instead of a `SplitConfig` item.\n  `NewSplitDriver` now automatically implements an internal `noopDriver` for `SplitConfig` fields that are not initialized. (#1798)\n- `resource.New()` now creates a Resource without builtin detectors. Previous behavior is now achieved by using `WithBuiltinDetectors` Option. (#1810)\n- Move the `Event` type from the `go.opentelemetry.io/otel` package to the `go.opentelemetry.io/otel/sdk/trace` package. (#1846)\n- CI builds validate against last two versions of Go, dropping 1.14 and adding 1.16. (#1865)\n- BatchSpanProcessor now report export failures when calling `ForceFlush()` method. (#1860)\n- `Set.Encoded(Encoder)` no longer caches the result of an encoding. (#1855)\n- Renamed `CloudZoneKey` to `CloudAvailabilityZoneKey` in Resource semantic conventions according to spec. (#1871)\n- The `StatusCode` and `StatusMessage` methods of the `ReadOnlySpan` interface and the `Span` produced by the `go.opentelemetry.io/otel/sdk/trace` package have been replaced with a single `Status` method.\n  This method returns the status of a span using the new `Status` type. (#1874)\n- Updated `ExportSpans` method of the`SpanExporter` interface type to accept `ReadOnlySpan`s instead of the removed `SpanSnapshot`.\n  This brings the export interface into compliance with the specification in that it now accepts an explicitly immutable type instead of just an implied one. (#1873)\n- Unembed `SpanContext` in `Link`. (#1877)\n- Generate Semantic conventions from the specification YAML. (#1891)\n- Spans created by the global `Tracer` obtained from `go.opentelemetry.io/otel`, prior to a functioning `TracerProvider` being set, now propagate the span context from their parent if one exists. (#1901)\n- The `\"go.opentelemetry.io/otel\".Tracer` function now accepts tracer options. (#1902)\n- Move the `go.opentelemetry.io/otel/unit` package to `go.opentelemetry.io/otel/metric/unit`. (#1903)\n- Changed `go.opentelemetry.io/otel/trace.TracerConfig` to conform to the [Contributing guidelines](CONTRIBUTING.md#config.) (#1921)\n- Changed `go.opentelemetry.io/otel/trace.SpanConfig` to conform to the [Contributing guidelines](CONTRIBUTING.md#config). (#1921)\n- Changed `span.End()` now only accepts Options that are allowed at `End()`. (#1921)\n- Changed `go.opentelemetry.io/otel/metric.InstrumentConfig` to conform to the [Contributing guidelines](CONTRIBUTING.md#config). (#1921)\n- Changed `go.opentelemetry.io/otel/metric.MeterConfig` to conform to the [Contributing guidelines](CONTRIBUTING.md#config). (#1921)\n- Refactored option types according to the contribution style guide. (#1882)\n- Move the `go.opentelemetry.io/otel/trace.TraceStateFromKeyValues` function to the `go.opentelemetry.io/otel/oteltest` package.\n  This function is preserved for testing purposes where it may be useful to create a `TraceState` from `attribute.KeyValue`s, but it is not intended for production use.\n  The new `ParseTraceState` function should be used to create a `TraceState`. (#1931)\n- Updated `MarshalJSON` method of the `go.opentelemetry.io/otel/trace.TraceState` type to marshal the type into the string representation of the `TraceState`. (#1931)\n- The `TraceState.Delete` method from the `go.opentelemetry.io/otel/trace` package no longer returns an error in addition to a `TraceState`. (#1931)\n- Updated `Get` method of the `TraceState` type from the `go.opentelemetry.io/otel/trace` package to accept a `string` instead of an `attribute.Key` type. (#1931)\n- Updated `Insert` method of the `TraceState` type from the `go.opentelemetry.io/otel/trace` package to accept a pair of `string`s instead of an `attribute.KeyValue` type. (#1931)\n- Updated `Delete` method of the `TraceState` type from the `go.opentelemetry.io/otel/trace` package to accept a `string` instead of an `attribute.Key` type. (#1931)\n- Renamed `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/stdout` package. (#1985)\n- Renamed `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/metric/prometheus` package. (#1985)\n- Renamed `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/trace/jaeger` package. (#1985)\n- Renamed `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/trace/zipkin` package. (#1985)\n- Renamed `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/otlp` package. (#1985)\n- Renamed `NewUnstartedExporter` to `NewUnstarted` in the `go.opentelemetry.io/otel/exporters/otlp` package. (#1985)\n- The `go.opentelemetry.io/otel/semconv` package has been moved to `go.opentelemetry.io/otel/semconv/v1.4.0` to allow for multiple [telemetry schema](https://github.com/open-telemetry/oteps/blob/main/text/0152-telemetry-schemas.md) versions to be used concurrently. (#1987)\n- Metrics test helpers in `go.opentelemetry.io/otel/oteltest` have been moved to `go.opentelemetry.io/otel/metric/metrictest`. (#1988)\n\n### Deprecated\n\n- The `go.opentelemetry.io/otel/exporters/metric/prometheus` is deprecated, use `go.opentelemetry.io/otel/exporters/prometheus` instead. (#1993)\n- The `go.opentelemetry.io/otel/exporters/trace/jaeger` is deprecated, use `go.opentelemetry.io/otel/exporters/jaeger` instead. (#1993)\n- The `go.opentelemetry.io/otel/exporters/trace/zipkin` is deprecated, use `go.opentelemetry.io/otel/exporters/zipkin` instead. (#1993)\n\n### Removed\n\n- Removed `resource.WithoutBuiltin()`. Use `resource.New()`. (#1810)\n- Unexported types `resource.FromEnv`, `resource.Host`, and `resource.TelemetrySDK`, Use the corresponding `With*()` to use individually. (#1810)\n- Removed the `Tracer` and `IsRecording` method from the `ReadOnlySpan` in the `go.opentelemetry.io/otel/sdk/trace`.\n  The `Tracer` method is not a required to be included in this interface and given the mutable nature of the tracer that is associated with a span, this method is not appropriate.\n  The `IsRecording` method returns if the span is recording or not.\n  A read-only span value does not need to know if updates to it will be recorded or not.\n  By definition, it cannot be updated so there is no point in communicating if an update is recorded. (#1873)\n- Removed the `SpanSnapshot` type from the `go.opentelemetry.io/otel/sdk/trace` package.\n  The use of this type has been replaced with the use of the explicitly immutable `ReadOnlySpan` type.\n  When a concrete representation of a read-only span is needed for testing, the newly added `SpanStub` in the `go.opentelemetry.io/otel/sdk/trace/tracetest` package should be used. (#1873)\n- Removed the `Tracer` method from the `Span` interface in the `go.opentelemetry.io/otel/trace` package.\n  Using the same tracer that created a span introduces the error where an instrumentation library's `Tracer` is used by other code instead of their own.\n  The `\"go.opentelemetry.io/otel\".Tracer` function or a `TracerProvider` should be used to acquire a library specific `Tracer` instead. (#1900)\n  - The `TracerProvider()` method on the `Span` interface may also be used to obtain a `TracerProvider` using the same trace processing pipeline. (#2009)\n- The `http.url` attribute generated by `HTTPClientAttributesFromHTTPRequest` will no longer include username or password information. (#1919)\n- Removed `IsEmpty` method of the `TraceState` type in the `go.opentelemetry.io/otel/trace` package in favor of using the added `TraceState.Len` method. (#1931)\n- Removed `Set`, `Value`, `ContextWithValue`, `ContextWithoutValue`, and `ContextWithEmpty` functions in the `go.opentelemetry.io/otel/baggage` package.\n  Handling of baggage is now done using the added `Baggage` type and related context functions (`ContextWithBaggage`, `ContextWithoutBaggage`, and `FromContext`) in that package. (#1967)\n- The `InstallNewPipeline` and `NewExportPipeline` creation functions in all the exporters (prometheus, otlp, stdout, jaeger, and zipkin) have been removed.\n  These functions were deemed premature attempts to provide convenience that did not achieve this aim. (#1985)\n- The `go.opentelemetry.io/otel/exporters/otlp` exporter has been removed.  Use `go.opentelemetry.io/otel/exporters/otlp/otlptrace` instead. (#1990)\n- The `go.opentelemetry.io/otel/exporters/stdout` exporter has been removed.  Use `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` or `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` instead. (#2005)\n\n### Fixed\n\n- Only report errors from the `\"go.opentelemetry.io/otel/sdk/resource\".Environment` function when they are not `nil`. (#1850, #1851)\n- The `Shutdown` method of the simple `SpanProcessor` in the `go.opentelemetry.io/otel/sdk/trace` package now honors the context deadline or cancellation. (#1616, #1856)\n- BatchSpanProcessor now drops span batches that failed to be exported. (#1860)\n- Use `http://localhost:14268/api/traces` as default Jaeger collector endpoint instead of `http://localhost:14250`. (#1898)\n- Allow trailing and leading whitespace in the parsing of a `tracestate` header. (#1931)\n- Add logic to determine if the channel is closed to fix Jaeger exporter test panic with close closed channel. (#1870, #1973)\n- Avoid transport security when OTLP endpoint is a Unix socket. (#2001)\n\n### Security\n\n## [0.20.0] - 2021-04-23\n\n### Added\n\n- The OTLP exporter now has two new convenience functions, `NewExportPipeline` and `InstallNewPipeline`, setup and install the exporter in tracing and metrics pipelines. (#1373)\n- Adds semantic conventions for exceptions. (#1492)\n- Added Jaeger Environment variables: `OTEL_EXPORTER_JAEGER_AGENT_HOST`, `OTEL_EXPORTER_JAEGER_AGENT_PORT`\n  These environment variables can be used to override Jaeger agent hostname and port (#1752)\n- Option `ExportTimeout` was added to batch span processor. (#1755)\n- `trace.TraceFlags` is now a defined type over `byte` and `WithSampled(bool) TraceFlags` and `IsSampled() bool` methods have been added to it. (#1770)\n- The `Event` and `Link` struct types from the `go.opentelemetry.io/otel` package now include a `DroppedAttributeCount` field to record the number of attributes that were not recorded due to configured limits being reached. (#1771)\n- The Jaeger exporter now reports dropped attributes for a Span event in the exported log. (#1771)\n- Adds test to check BatchSpanProcessor ignores `OnEnd` and `ForceFlush` post `Shutdown`. (#1772)\n- Extract resource attributes from the `OTEL_RESOURCE_ATTRIBUTES` environment variable and merge them with the `resource.Default` resource as well as resources provided to the `TracerProvider` and metric `Controller`. (#1785)\n- Added `WithOSType` resource configuration option to set OS (Operating System) type resource attribute (`os.type`). (#1788)\n- Added `WithProcess*` resource configuration options to set Process resource attributes. (#1788)\n  - `process.pid`\n  - `process.executable.name`\n  - `process.executable.path`\n  - `process.command_args`\n  - `process.owner`\n  - `process.runtime.name`\n  - `process.runtime.version`\n  - `process.runtime.description`\n- Adds `k8s.node.name` and `k8s.node.uid` attribute keys to the `semconv` package. (#1789)\n- Added support for configuring OTLP/HTTP and OTLP/gRPC Endpoints, TLS Certificates, Headers, Compression and Timeout via Environment Variables. (#1758, #1769 and #1811)\n  - `OTEL_EXPORTER_OTLP_ENDPOINT`\n  - `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`\n  - `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`\n  - `OTEL_EXPORTER_OTLP_HEADERS`\n  - `OTEL_EXPORTER_OTLP_TRACES_HEADERS`\n  - `OTEL_EXPORTER_OTLP_METRICS_HEADERS`\n  - `OTEL_EXPORTER_OTLP_COMPRESSION`\n  - `OTEL_EXPORTER_OTLP_TRACES_COMPRESSION`\n  - `OTEL_EXPORTER_OTLP_METRICS_COMPRESSION`\n  - `OTEL_EXPORTER_OTLP_TIMEOUT`\n  - `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT`\n  - `OTEL_EXPORTER_OTLP_METRICS_TIMEOUT`\n  - `OTEL_EXPORTER_OTLP_CERTIFICATE`\n  - `OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE`\n  - `OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE`\n- Adds `otlpgrpc.WithTimeout` option for configuring timeout to the otlp/gRPC exporter. (#1821)\n- Adds `jaeger.WithMaxPacketSize` option for configuring maximum UDP packet size used when connecting to the Jaeger agent. (#1853)\n\n### Fixed\n\n- The `Span.IsRecording` implementation from `go.opentelemetry.io/otel/sdk/trace` always returns false when not being sampled. (#1750)\n- The Jaeger exporter now correctly sets tags for the Span status code and message.\n  This means it uses the correct tag keys (`\"otel.status_code\"`, `\"otel.status_description\"`) and does not set the status message as a tag unless it is set on the span. (#1761)\n- The Jaeger exporter now correctly records Span event's names using the `\"event\"` key for a tag.\n  Additionally, this tag is overridden, as specified in the OTel specification, if the event contains an attribute with that key. (#1768)\n- Zipkin Exporter: Ensure mapping between OTel and Zipkin span data complies with the specification. (#1688)\n- Fixed typo for default service name in Jaeger Exporter. (#1797)\n- Fix flaky OTLP for the reconnnection of the client connection. (#1527, #1814)\n- Fix Jaeger exporter dropping of span batches that exceed the UDP packet size limit.\n  Instead, the exporter now splits the batch into smaller sendable batches. (#1828)\n\n### Changed\n\n- Span `RecordError` now records an `exception` event to comply with the semantic convention specification. (#1492)\n- Jaeger exporter was updated to use thrift v0.14.1. (#1712)\n- Migrate from using internally built and maintained version of the OTLP to the one hosted at `go.opentelemetry.io/proto/otlp`. (#1713)\n- Migrate from using `github.com/gogo/protobuf` to `google.golang.org/protobuf` to match `go.opentelemetry.io/proto/otlp`. (#1713)\n- The storage of a local or remote Span in a `context.Context` using its SpanContext is unified to store just the current Span.\n  The Span's SpanContext can now self-identify as being remote or not.\n  This means that `\"go.opentelemetry.io/otel/trace\".ContextWithRemoteSpanContext` will now overwrite any existing current Span, not just existing remote Spans, and make it the current Span in a `context.Context`. (#1731)\n- Improve OTLP/gRPC exporter connection errors. (#1737)\n- Information about a parent span context in a `\"go.opentelemetry.io/otel/export/trace\".SpanSnapshot` is unified in a new `Parent` field.\n  The existing `ParentSpanID` and `HasRemoteParent` fields are removed in favor of this. (#1748)\n- The `ParentContext` field of the `\"go.opentelemetry.io/otel/sdk/trace\".SamplingParameters` is updated to hold a `context.Context` containing the parent span.\n  This changes it to make `SamplingParameters` conform with the OpenTelemetry specification. (#1749)\n- Updated Jaeger Environment Variables: `JAEGER_ENDPOINT`, `JAEGER_USER`, `JAEGER_PASSWORD`\n  to `OTEL_EXPORTER_JAEGER_ENDPOINT`, `OTEL_EXPORTER_JAEGER_USER`, `OTEL_EXPORTER_JAEGER_PASSWORD` in compliance with OTel specification. (#1752)\n- Modify `BatchSpanProcessor.ForceFlush` to abort after timeout/cancellation. (#1757)\n- The `DroppedAttributeCount` field of the `Span` in the `go.opentelemetry.io/otel` package now only represents the number of attributes dropped for the span itself.\n  It no longer is a conglomerate of itself, events, and link attributes that have been dropped. (#1771)\n- Make `ExportSpans` in Jaeger Exporter honor context deadline. (#1773)\n- Modify Zipkin Exporter default service name, use default resource's serviceName instead of empty. (#1777)\n- The `go.opentelemetry.io/otel/sdk/export/trace` package is merged into the `go.opentelemetry.io/otel/sdk/trace` package. (#1778)\n- The prometheus.InstallNewPipeline example is moved from comment to example test (#1796)\n- The convenience functions for the stdout exporter have been updated to return the `TracerProvider` implementation and enable the shutdown of the exporter. (#1800)\n- Replace the flush function returned from the Jaeger exporter's convenience creation functions (`InstallNewPipeline` and `NewExportPipeline`) with the `TracerProvider` implementation they create.\n  This enables the caller to shutdown and flush using the related `TracerProvider` methods. (#1822)\n- Updated the Jaeger exporter to have a default endpoint, `http://localhost:14250`, for the collector. (#1824)\n- Changed the function `WithCollectorEndpoint` in the Jaeger exporter to no longer accept an endpoint as an argument.\n  The endpoint can be passed with the `CollectorEndpointOption` using the `WithEndpoint` function or by setting the `OTEL_EXPORTER_JAEGER_ENDPOINT` environment variable value appropriately. (#1824)\n- The Jaeger exporter no longer batches exported spans itself, instead it relies on the SDK's `BatchSpanProcessor` for this functionality. (#1830)\n- The Jaeger exporter creation functions (`NewRawExporter`, `NewExportPipeline`, and `InstallNewPipeline`) no longer accept the removed `Option` type as a variadic argument. (#1830)\n\n### Removed\n\n- Removed Jaeger Environment variables: `JAEGER_SERVICE_NAME`, `JAEGER_DISABLED`, `JAEGER_TAGS`\n  These environment variables will no longer be used to override values of the Jaeger exporter (#1752)\n- No longer set the links for a `Span` in `go.opentelemetry.io/otel/sdk/trace` that is configured to be a new root.\n  This is unspecified behavior that the OpenTelemetry community plans to standardize in the future.\n  To prevent backwards incompatible changes when it is specified, these links are removed. (#1726)\n- Setting error status while recording error with Span from oteltest package. (#1729)\n- The concept of a remote and local Span stored in a context is unified to just the current Span.\n  Because of this `\"go.opentelemetry.io/otel/trace\".RemoteSpanContextFromContext` is removed as it is no longer needed.\n  Instead, `\"go.opentelemetry.io/otel/trace\".SpanContextFromContext` can be used to return the current Span.\n  If needed, that Span's `SpanContext.IsRemote()` can then be used to determine if it is remote or not. (#1731)\n- The `HasRemoteParent` field of the `\"go.opentelemetry.io/otel/sdk/trace\".SamplingParameters` is removed.\n  This field is redundant to the information returned from the `Remote` method of the `SpanContext` held in the `ParentContext` field. (#1749)\n- The `trace.FlagsDebug` and `trace.FlagsDeferred` constants have been removed and will be localized to the B3 propagator. (#1770)\n- Remove `Process` configuration, `WithProcessFromEnv` and `ProcessFromEnv`, and type from the Jaeger exporter package.\n  The information that could be configured in the `Process` struct should be configured in a `Resource` instead. (#1776, #1804)\n- Remove the `WithDisabled` option from the Jaeger exporter.\n  To disable the exporter unregister it from the `TracerProvider` or use a no-operation `TracerProvider`. (#1806)\n- Removed the functions `CollectorEndpointFromEnv` and `WithCollectorEndpointOptionFromEnv` from the Jaeger exporter.\n  These functions for retrieving specific environment variable values are redundant of other internal functions and\n  are not intended for end user use. (#1824)\n- Removed the Jaeger exporter `WithSDKOptions` `Option`.\n  This option was used to set SDK options for the exporter creation convenience functions.\n  These functions are provided as a way to easily setup or install the exporter with what are deemed reasonable SDK settings for common use cases.\n  If the SDK needs to be configured differently, the `NewRawExporter` function and direct setup of the SDK with the desired settings should be used. (#1825)\n- The `WithBufferMaxCount` and `WithBatchMaxCount` `Option`s from the Jaeger exporter are removed.\n  The exporter no longer batches exports, instead relying on the SDK's `BatchSpanProcessor` for this functionality. (#1830)\n- The Jaeger exporter `Option` type is removed.\n  The type is no longer used by the exporter to configure anything.\n  All the previous configurations these options provided were duplicates of SDK configuration.\n  They have been removed in favor of using the SDK configuration and focuses the exporter configuration to be only about the endpoints it will send telemetry to. (#1830)\n\n## [0.19.0] - 2021-03-18\n\n### Added\n\n- Added `Marshaler` config option to `otlphttp` to enable otlp over json or protobufs. (#1586)\n- A `ForceFlush` method to the `\"go.opentelemetry.io/otel/sdk/trace\".TracerProvider` to flush all registered `SpanProcessor`s. (#1608)\n- Added `WithSampler` and `WithSpanLimits` to tracer provider. (#1633, #1702)\n- `\"go.opentelemetry.io/otel/trace\".SpanContext` now has a `remote` property, and `IsRemote()` predicate, that is true when the `SpanContext` has been extracted from remote context data. (#1701)\n- A `Valid` method to the `\"go.opentelemetry.io/otel/attribute\".KeyValue` type. (#1703)\n\n### Changed\n\n- `trace.SpanContext` is now immutable and has no exported fields. (#1573)\n  - `trace.NewSpanContext()` can be used in conjunction with the `trace.SpanContextConfig` struct to initialize a new `SpanContext` where all values are known.\n- Update the `ForceFlush` method signature to the `\"go.opentelemetry.io/otel/sdk/trace\".SpanProcessor` to accept a `context.Context` and return an error. (#1608)\n- Update the `Shutdown` method to the `\"go.opentelemetry.io/otel/sdk/trace\".TracerProvider` return an error on shutdown failure. (#1608)\n- The SimpleSpanProcessor will now shut down the enclosed `SpanExporter` and gracefully ignore subsequent calls to `OnEnd` after `Shutdown` is called. (#1612)\n- `\"go.opentelemetry.io/sdk/metric/controller.basic\".WithPusher` is replaced with `WithExporter` to provide consistent naming across project. (#1656)\n- Added non-empty string check for trace `Attribute` keys. (#1659)\n- Add `description` to SpanStatus only when `StatusCode` is set to error. (#1662)\n- Jaeger exporter falls back to `resource.Default`'s `service.name` if the exported Span does not have one. (#1673)\n- Jaeger exporter populates Jaeger's Span Process from Resource. (#1673)\n- Renamed the `LabelSet` method of `\"go.opentelemetry.io/otel/sdk/resource\".Resource` to `Set`. (#1692)\n- Changed `WithSDK` to `WithSDKOptions` to accept variadic arguments of `TracerProviderOption` type in `go.opentelemetry.io/otel/exporters/trace/jaeger` package. (#1693)\n- Changed `WithSDK` to `WithSDKOptions` to accept variadic arguments of `TracerProviderOption` type in `go.opentelemetry.io/otel/exporters/trace/zipkin` package. (#1693)\n\n### Removed\n\n- Removed `serviceName` parameter from Zipkin exporter and uses resource instead. (#1549)\n- Removed `WithConfig` from tracer provider to avoid overriding configuration. (#1633)\n- Removed the exported `SimpleSpanProcessor` and `BatchSpanProcessor` structs.\n   These are now returned as a SpanProcessor interface from their respective constructors. (#1638)\n- Removed `WithRecord()` from `trace.SpanOption` when creating a span. (#1660)\n- Removed setting status to `Error` while recording an error as a span event in `RecordError`. (#1663)\n- Removed `jaeger.WithProcess` configuration option. (#1673)\n- Removed `ApplyConfig` method from `\"go.opentelemetry.io/otel/sdk/trace\".TracerProvider` and the now unneeded `Config` struct. (#1693)\n\n### Fixed\n\n- Jaeger Exporter: Ensure mapping between OTEL and Jaeger span data complies with the specification. (#1626)\n- `SamplingResult.TraceState` is correctly propagated to a newly created span's `SpanContext`. (#1655)\n- The `otel-collector` example now correctly flushes metric events prior to shutting down the exporter. (#1678)\n- Do not set span status message in `SpanStatusFromHTTPStatusCode` if it can be inferred from `http.status_code`. (#1681)\n- Synchronization issues in global trace delegate implementation. (#1686)\n- Reduced excess memory usage by global `TracerProvider`. (#1687)\n\n## [0.18.0] - 2021-03-03\n\n### Added\n\n- Added `resource.Default()` for use with meter and tracer providers. (#1507)\n- `AttributePerEventCountLimit` and `AttributePerLinkCountLimit` for `SpanLimits`. (#1535)\n- Added `Keys()` method to `propagation.TextMapCarrier` and `propagation.HeaderCarrier` to adapt `http.Header` to this interface. (#1544)\n- Added `code` attributes to `go.opentelemetry.io/otel/semconv` package. (#1558)\n- Compatibility testing suite in the CI system for the following systems. (#1567)\n   | OS      | Go Version | Architecture |\n   | ------- | ---------- | ------------ |\n   | Ubuntu  | 1.15       | amd64        |\n   | Ubuntu  | 1.14       | amd64        |\n   | Ubuntu  | 1.15       | 386          |\n   | Ubuntu  | 1.14       | 386          |\n   | MacOS   | 1.15       | amd64        |\n   | MacOS   | 1.14       | amd64        |\n   | Windows | 1.15       | amd64        |\n   | Windows | 1.14       | amd64        |\n   | Windows | 1.15       | 386          |\n   | Windows | 1.14       | 386          |\n\n### Changed\n\n- Replaced interface `oteltest.SpanRecorder` with its existing implementation\n  `StandardSpanRecorder`. (#1542)\n- Default span limit values to 128. (#1535)\n- Rename `MaxEventsPerSpan`, `MaxAttributesPerSpan` and `MaxLinksPerSpan` to `EventCountLimit`, `AttributeCountLimit` and `LinkCountLimit`, and move these fields into `SpanLimits`. (#1535)\n- Renamed the `otel/label` package to `otel/attribute`. (#1541)\n- Vendor the Jaeger exporter's dependency on Apache Thrift. (#1551)\n- Parallelize the CI linting and testing. (#1567)\n- Stagger timestamps in exact aggregator tests. (#1569)\n- Changed all examples to use `WithBatchTimeout(5 * time.Second)` rather than `WithBatchTimeout(5)`. (#1621)\n- Prevent end-users from implementing some interfaces (#1575)\n\n  ```\n      \"otel/exporters/otlp/otlphttp\".Option\n      \"otel/exporters/stdout\".Option\n      \"otel/oteltest\".Option\n      \"otel/trace\".TracerOption\n      \"otel/trace\".SpanOption\n      \"otel/trace\".EventOption\n      \"otel/trace\".LifeCycleOption\n      \"otel/trace\".InstrumentationOption\n      \"otel/sdk/resource\".Option\n      \"otel/sdk/trace\".ParentBasedSamplerOption\n      \"otel/sdk/trace\".ReadOnlySpan\n      \"otel/sdk/trace\".ReadWriteSpan\n  ```\n\n### Removed\n\n- Removed attempt to resample spans upon changing the span name with `span.SetName()`. (#1545)\n- The `test-benchmark` is no longer a dependency of the `precommit` make target. (#1567)\n- Removed the `test-386` make target.\n   This was replaced with a full compatibility testing suite (i.e. multi OS/arch) in the CI system. (#1567)\n\n### Fixed\n\n- The sequential timing check of timestamps in the stdout exporter are now setup explicitly to be sequential (#1571). (#1572)\n- Windows build of Jaeger tests now compiles with OS specific functions (#1576). (#1577)\n- The sequential timing check of timestamps of go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue are now setup explicitly to be sequential (#1578). (#1579)\n- Validate tracestate header keys with vendors according to the W3C TraceContext specification (#1475). (#1581)\n- The OTLP exporter includes related labels for translations of a GaugeArray (#1563). (#1570)\n\n## [0.17.0] - 2021-02-12\n\n### Changed\n\n- Rename project default branch from `master` to `main`. (#1505)\n- Reverse order in which `Resource` attributes are merged, per change in spec. (#1501)\n- Add tooling to maintain \"replace\" directives in go.mod files automatically. (#1528)\n- Create new modules: otel/metric, otel/trace, otel/oteltest, otel/sdk/export/metric, otel/sdk/metric (#1528)\n- Move metric-related public global APIs from otel to otel/metric/global. (#1528)\n\n## Fixed\n\n- Fixed otlpgrpc reconnection issue.\n- The example code in the README.md of `go.opentelemetry.io/otel/exporters/otlp` is moved to a compiled example test and used the new `WithAddress` instead of `WithEndpoint`. (#1513)\n- The otel-collector example now uses the default OTLP receiver port of the collector.\n\n## [0.16.0] - 2021-01-13\n\n### Added\n\n- Add the `ReadOnlySpan` and `ReadWriteSpan` interfaces to provide better control for accessing span data. (#1360)\n- `NewGRPCDriver` function returns a `ProtocolDriver` that maintains a single gRPC connection to the collector. (#1369)\n- Added documentation about the project's versioning policy. (#1388)\n- Added `NewSplitDriver` for OTLP exporter that allows sending traces and metrics to different endpoints. (#1418)\n- Added codeql workflow to GitHub Actions (#1428)\n- Added Gosec workflow to GitHub Actions (#1429)\n- Add new HTTP driver for OTLP exporter in `exporters/otlp/otlphttp`. Currently it only supports the binary protobuf payloads. (#1420)\n- Add an OpenCensus exporter bridge. (#1444)\n\n### Changed\n\n- Rename `internal/testing` to `internal/internaltest`. (#1449)\n- Rename `export.SpanData` to `export.SpanSnapshot` and use it only for exporting spans. (#1360)\n- Store the parent's full `SpanContext` rather than just its span ID in the `span` struct. (#1360)\n- Improve span duration accuracy. (#1360)\n- Migrated CI/CD from CircleCI to GitHub Actions (#1382)\n- Remove duplicate checkout from GitHub Actions workflow (#1407)\n- Metric `array` aggregator renamed `exact` to match its `aggregation.Kind` (#1412)\n- Metric `exact` aggregator includes per-point timestamps (#1412)\n- Metric stdout exporter uses MinMaxSumCount aggregator for ValueRecorder instruments (#1412)\n- `NewExporter` from `exporters/otlp` now takes a `ProtocolDriver` as a parameter. (#1369)\n- Many OTLP Exporter options became gRPC ProtocolDriver options. (#1369)\n- Unify endpoint API that related to OTel exporter. (#1401)\n- Optimize metric histogram aggregator to reuse its slice of buckets. (#1435)\n- Metric aggregator Count() and histogram Bucket.Counts are consistently `uint64`. (1430)\n- Histogram aggregator accepts functional options, uses default boundaries if none given. (#1434)\n- `SamplingResult` now passed a `Tracestate` from the parent `SpanContext` (#1432)\n- Moved gRPC driver for OTLP exporter to `exporters/otlp/otlpgrpc`. (#1420)\n- The `TraceContext` propagator now correctly propagates `TraceState` through the `SpanContext`. (#1447)\n- Metric Push and Pull Controller components are combined into a single \"basic\" Controller:\n  - `WithExporter()` and `Start()` to configure Push behavior\n  - `Start()` is optional; use `Collect()` and `ForEach()` for Pull behavior\n  - `Start()` and `Stop()` accept Context. (#1378)\n- The `Event` type is moved from the `otel/sdk/export/trace` package to the `otel/trace` API package. (#1452)\n\n### Removed\n\n- Remove `errUninitializedSpan` as its only usage is now obsolete. (#1360)\n- Remove Metric export functionality related to quantiles and summary data points: this is not specified (#1412)\n- Remove DDSketch metric aggregator; our intention is to re-introduce this as an option of the histogram aggregator after [new OTLP histogram data types](https://github.com/open-telemetry/opentelemetry-proto/pull/226) are released (#1412)\n\n### Fixed\n\n- `BatchSpanProcessor.Shutdown()` will now shutdown underlying `export.SpanExporter`. (#1443)\n\n## [0.15.0] - 2020-12-10\n\n### Added\n\n- The `WithIDGenerator` `TracerProviderOption` is added to the `go.opentelemetry.io/otel/trace` package to configure an `IDGenerator` for the `TracerProvider`. (#1363)\n\n### Changed\n\n- The Zipkin exporter now uses the Span status code to determine. (#1328)\n- `NewExporter` and `Start` functions in `go.opentelemetry.io/otel/exporters/otlp` now receive `context.Context` as a first parameter. (#1357)\n- Move the OpenCensus example into `example` directory. (#1359)\n- Moved the SDK's `internal.IDGenerator` interface in to the `sdk/trace` package to enable support for externally-defined ID generators. (#1363)\n- Bump `github.com/google/go-cmp` from 0.5.3 to 0.5.4 (#1374)\n- Bump `github.com/golangci/golangci-lint` in `/internal/tools` (#1375)\n\n### Fixed\n\n- Metric SDK `SumObserver` and `UpDownSumObserver` instruments correctness fixes. (#1381)\n\n## [0.14.0] - 2020-11-19\n\n### Added\n\n- An `EventOption` and the related `NewEventConfig` function are added to the `go.opentelemetry.io/otel` package to configure Span events. (#1254)\n- A `TextMapPropagator` and associated `TextMapCarrier` are added to the `go.opentelemetry.io/otel/oteltest` package to test `TextMap` type propagators and their use. (#1259)\n- `SpanContextFromContext` returns `SpanContext` from context. (#1255)\n- `TraceState` has been added to `SpanContext`. (#1340)\n- `DeploymentEnvironmentKey` added to `go.opentelemetry.io/otel/semconv` package. (#1323)\n- Add an OpenCensus to OpenTelemetry tracing bridge. (#1305)\n- Add a parent context argument to `SpanProcessor.OnStart` to follow the specification. (#1333)\n- Add missing tests for `sdk/trace/attributes_map.go`. (#1337)\n\n### Changed\n\n- Move the `go.opentelemetry.io/otel/api/trace` package into `go.opentelemetry.io/otel/trace` with the following changes. (#1229) (#1307)\n  - `ID` has been renamed to `TraceID`.\n  - `IDFromHex` has been renamed to `TraceIDFromHex`.\n  - `EmptySpanContext` is removed.\n- Move the `go.opentelemetry.io/otel/api/trace/tracetest` package into `go.opentelemetry.io/otel/oteltest`. (#1229)\n- OTLP Exporter updates:\n  - supports OTLP v0.6.0 (#1230, #1354)\n  - supports configurable aggregation temporality (default: Cumulative, optional: Stateless). (#1296)\n- The Sampler is now called on local child spans. (#1233)\n- The `Kind` type from the `go.opentelemetry.io/otel/api/metric` package was renamed to `InstrumentKind` to more specifically describe what it is and avoid semantic ambiguity. (#1240)\n- The `MetricKind` method of the `Descriptor` type in the `go.opentelemetry.io/otel/api/metric` package was renamed to `Descriptor.InstrumentKind`.\n   This matches the returned type and fixes misuse of the term metric. (#1240)\n- Move test harness from the `go.opentelemetry.io/otel/api/apitest` package into `go.opentelemetry.io/otel/oteltest`. (#1241)\n- Move the `go.opentelemetry.io/otel/api/metric/metrictest` package into `go.opentelemetry.io/oteltest` as part of #964. (#1252)\n- Move the `go.opentelemetry.io/otel/api/metric` package into `go.opentelemetry.io/otel/metric` as part of #1303. (#1321)\n- Move the `go.opentelemetry.io/otel/api/metric/registry` package into `go.opentelemetry.io/otel/metric/registry` as a part of #1303. (#1316)\n- Move the `Number` type (together with related functions) from `go.opentelemetry.io/otel/api/metric` package into `go.opentelemetry.io/otel/metric/number` as a part of #1303. (#1316)\n- The function signature of the Span `AddEvent` method in `go.opentelemetry.io/otel` is updated to no longer take an unused context and instead take a required name and a variable number of `EventOption`s. (#1254)\n- The function signature of the Span `RecordError` method in `go.opentelemetry.io/otel` is updated to no longer take an unused context and instead take a required error value and a variable number of `EventOption`s. (#1254)\n- Move the `go.opentelemetry.io/otel/api/global` package to `go.opentelemetry.io/otel`. (#1262) (#1330)\n- Move the `Version` function from `go.opentelemetry.io/otel/sdk` to `go.opentelemetry.io/otel`. (#1330)\n- Rename correlation context header from `\"otcorrelations\"` to `\"baggage\"` to match the OpenTelemetry specification. (#1267)\n- Fix `Code.UnmarshalJSON` to work with valid JSON only. (#1276)\n- The `resource.New()` method changes signature to support builtin attributes and functional options, including `telemetry.sdk.*` and\n  `host.name` semantic conventions; the former method is renamed `resource.NewWithAttributes`. (#1235)\n- The Prometheus exporter now exports non-monotonic counters (i.e. `UpDownCounter`s) as gauges. (#1210)\n- Correct the `Span.End` method documentation in the `otel` API to state updates are not allowed on a span after it has ended. (#1310)\n- Updated span collection limits for attribute, event and link counts to 1000 (#1318)\n- Renamed `semconv.HTTPUrlKey` to `semconv.HTTPURLKey`. (#1338)\n\n### Removed\n\n- The `ErrInvalidHexID`, `ErrInvalidTraceIDLength`, `ErrInvalidSpanIDLength`, `ErrInvalidSpanIDLength`, or `ErrNilSpanID` from the `go.opentelemetry.io/otel` package are unexported now. (#1243)\n- The `AddEventWithTimestamp` method on the `Span` interface in `go.opentelemetry.io/otel` is removed due to its redundancy.\n   It is replaced by using the `AddEvent` method with a `WithTimestamp` option. (#1254)\n- The `MockSpan` and `MockTracer` types are removed from `go.opentelemetry.io/otel/oteltest`.\n   `Tracer` and `Span` from the same module should be used in their place instead. (#1306)\n- `WorkerCount` option is removed from `go.opentelemetry.io/otel/exporters/otlp`. (#1350)\n- Remove the following labels types: INT32, UINT32, UINT64 and FLOAT32. (#1314)\n\n### Fixed\n\n- Rename `MergeItererator` to `MergeIterator` in the `go.opentelemetry.io/otel/label` package. (#1244)\n- The `go.opentelemetry.io/otel/api/global` packages global TextMapPropagator now delegates functionality to a globally set delegate for all previously returned propagators. (#1258)\n- Fix condition in `label.Any`. (#1299)\n- Fix global `TracerProvider` to pass options to its configured provider. (#1329)\n- Fix missing handler for `ExactKind` aggregator in OTLP metrics transformer (#1309)\n\n## [0.13.0] - 2020-10-08\n\n### Added\n\n- OTLP Metric exporter supports Histogram aggregation. (#1209)\n- The `Code` struct from the `go.opentelemetry.io/otel/codes` package now supports JSON marshaling and unmarshaling as well as implements the `Stringer` interface. (#1214)\n- A Baggage API to implement the OpenTelemetry specification. (#1217)\n- Add Shutdown method to sdk/trace/provider, shutdown processors in the order they were registered. (#1227)\n\n### Changed\n\n- Set default propagator to no-op propagator. (#1184)\n- The `HTTPSupplier`, `HTTPExtractor`, `HTTPInjector`, and `HTTPPropagator` from the `go.opentelemetry.io/otel/api/propagation` package were replaced with unified `TextMapCarrier` and `TextMapPropagator` in the `go.opentelemetry.io/otel/propagation` package. (#1212) (#1325)\n- The `New` function from the `go.opentelemetry.io/otel/api/propagation` package was replaced with `NewCompositeTextMapPropagator` in the `go.opentelemetry.io/otel` package. (#1212)\n- The status codes of the `go.opentelemetry.io/otel/codes` package have been updated to match the latest OpenTelemetry specification.\n   They now are `Unset`, `Error`, and `Ok`.\n   They no longer track the gRPC codes. (#1214)\n- The `StatusCode` field of the `SpanData` struct in the `go.opentelemetry.io/otel/sdk/export/trace` package now uses the codes package from this package instead of the gRPC project. (#1214)\n- Move the `go.opentelemetry.io/otel/api/baggage` package into `go.opentelemetry.io/otel/baggage`. (#1217) (#1325)\n- A `Shutdown` method of `SpanProcessor` and all its implementations receives a context and returns an error. (#1264)\n\n### Fixed\n\n- Copies of data from arrays and slices passed to `go.opentelemetry.io/otel/label.ArrayValue()` are now used in the returned `Value` instead of using the mutable data itself. (#1226)\n\n### Removed\n\n- The `ExtractHTTP` and `InjectHTTP` functions from the `go.opentelemetry.io/otel/api/propagation` package were removed. (#1212)\n- The `Propagators` interface from the `go.opentelemetry.io/otel/api/propagation` package was removed to conform to the OpenTelemetry specification.\n   The explicit `TextMapPropagator` type can be used in its place as this is the `Propagator` type the specification defines. (#1212)\n- The `SetAttribute` method of the `Span` from the `go.opentelemetry.io/otel/api/trace` package was removed given its redundancy with the `SetAttributes` method. (#1216)\n- The internal implementation of Baggage storage is removed in favor of using the new Baggage API functionality. (#1217)\n- Remove duplicate hostname key `HostHostNameKey` in Resource semantic conventions. (#1219)\n- Nested array/slice support has been removed. (#1226)\n\n## [0.12.0] - 2020-09-24\n\n### Added\n\n- A `SpanConfigure` function in `go.opentelemetry.io/otel/api/trace` to create a new `SpanConfig` from `SpanOption`s. (#1108)\n- In the `go.opentelemetry.io/otel/api/trace` package, `NewTracerConfig` was added to construct new `TracerConfig`s.\n   This addition was made to conform with our project option conventions. (#1155)\n- Instrumentation library information was added to the Zipkin exporter. (#1119)\n- The `SpanProcessor` interface now has a `ForceFlush()` method. (#1166)\n- More semantic conventions for k8s as resource attributes. (#1167)\n\n### Changed\n\n- Add reconnecting udp connection type to Jaeger exporter.\n   This change adds a new optional implementation of the udp conn interface used to detect changes to an agent's host dns record.\n   It then adopts the new destination address to ensure the exporter doesn't get stuck. This change was ported from jaegertracing/jaeger-client-go#520. (#1063)\n- Replace `StartOption` and `EndOption` in `go.opentelemetry.io/otel/api/trace` with `SpanOption`.\n   This change is matched by replacing the `StartConfig` and `EndConfig` with a unified `SpanConfig`. (#1108)\n- Replace the `LinkedTo` span option in `go.opentelemetry.io/otel/api/trace` with `WithLinks`.\n   This is be more consistent with our other option patterns, i.e. passing the item to be configured directly instead of its component parts, and provides a cleaner function signature. (#1108)\n- The `go.opentelemetry.io/otel/api/trace` `TracerOption` was changed to an interface to conform to project option conventions. (#1109)\n- Move the `B3` and `TraceContext` from within the `go.opentelemetry.io/otel/api/trace` package to their own `go.opentelemetry.io/otel/propagators` package.\n    This removal of the propagators is reflective of the OpenTelemetry specification for these propagators as well as cleans up the `go.opentelemetry.io/otel/api/trace` API. (#1118)\n- Rename Jaeger tags used for instrumentation library information to reflect changes in OpenTelemetry specification. (#1119)\n- Rename `ProbabilitySampler` to `TraceIDRatioBased` and change semantics to ignore parent span sampling status. (#1115)\n- Move `tools` package under `internal`. (#1141)\n- Move `go.opentelemetry.io/otel/api/correlation` package to `go.opentelemetry.io/otel/api/baggage`. (#1142)\n   The `correlation.CorrelationContext` propagator has been renamed `baggage.Baggage`.  Other exported functions and types are unchanged.\n- Rename `ParentOrElse` sampler to `ParentBased` and allow setting samplers depending on parent span. (#1153)\n- In the `go.opentelemetry.io/otel/api/trace` package, `SpanConfigure` was renamed to `NewSpanConfig`. (#1155)\n- Change `dependabot.yml` to add a `Skip Changelog` label to dependabot-sourced PRs. (#1161)\n- The [configuration style guide](https://github.com/open-telemetry/opentelemetry-go/blob/master/CONTRIBUTING.md#config) has been updated to\n   recommend the use of `newConfig()` instead of `configure()`. (#1163)\n- The `otlp.Config` type has been unexported and changed to `otlp.config`, along with its initializer. (#1163)\n- Ensure exported interface types include parameter names and update the\n   Style Guide to reflect this styling rule. (#1172)\n- Don't consider unset environment variable for resource detection to be an error. (#1170)\n- Rename `go.opentelemetry.io/otel/api/metric.ConfigureInstrument` to `NewInstrumentConfig` and\n  `go.opentelemetry.io/otel/api/metric.ConfigureMeter` to `NewMeterConfig`.\n- ValueObserver instruments use LastValue aggregator by default. (#1165)\n- OTLP Metric exporter supports LastValue aggregation. (#1165)\n- Move the `go.opentelemetry.io/otel/api/unit` package to `go.opentelemetry.io/otel/unit`. (#1185)\n- Rename `Provider` to `MeterProvider` in the `go.opentelemetry.io/otel/api/metric` package. (#1190)\n- Rename `NoopProvider` to `NoopMeterProvider` in the `go.opentelemetry.io/otel/api/metric` package. (#1190)\n- Rename `NewProvider` to `NewMeterProvider` in the `go.opentelemetry.io/otel/api/metric/metrictest` package. (#1190)\n- Rename `Provider` to `MeterProvider` in the `go.opentelemetry.io/otel/api/metric/registry` package. (#1190)\n- Rename `NewProvider` to `NewMeterProvider` in the `go.opentelemetry.io/otel/api/metri/registryc` package. (#1190)\n- Rename `Provider` to `TracerProvider` in the `go.opentelemetry.io/otel/api/trace` package. (#1190)\n- Rename `NoopProvider` to `NoopTracerProvider` in the `go.opentelemetry.io/otel/api/trace` package. (#1190)\n- Rename `Provider` to `TracerProvider` in the `go.opentelemetry.io/otel/api/trace/tracetest` package. (#1190)\n- Rename `NewProvider` to `NewTracerProvider` in the `go.opentelemetry.io/otel/api/trace/tracetest` package. (#1190)\n- Rename `WrapperProvider` to `WrapperTracerProvider` in the `go.opentelemetry.io/otel/bridge/opentracing` package. (#1190)\n- Rename `NewWrapperProvider` to `NewWrapperTracerProvider` in the `go.opentelemetry.io/otel/bridge/opentracing` package. (#1190)\n- Rename `Provider` method of the pull controller to `MeterProvider` in the `go.opentelemetry.io/otel/sdk/metric/controller/pull` package. (#1190)\n- Rename `Provider` method of the push controller to `MeterProvider` in the `go.opentelemetry.io/otel/sdk/metric/controller/push` package. (#1190)\n- Rename `ProviderOptions` to `TracerProviderConfig` in the `go.opentelemetry.io/otel/sdk/trace` package. (#1190)\n- Rename `ProviderOption` to `TracerProviderOption` in the `go.opentelemetry.io/otel/sdk/trace` package. (#1190)\n- Rename `Provider` to `TracerProvider` in the `go.opentelemetry.io/otel/sdk/trace` package. (#1190)\n- Rename `NewProvider` to `NewTracerProvider` in the `go.opentelemetry.io/otel/sdk/trace` package. (#1190)\n- Renamed `SamplingDecision` values to comply with OpenTelemetry specification change. (#1192)\n- Renamed Zipkin attribute names from `ot.status_code & ot.status_description` to `otel.status_code & otel.status_description`. (#1201)\n- The default SDK now invokes registered `SpanProcessor`s in the order they were registered with the `TracerProvider`. (#1195)\n- Add test of spans being processed by the `SpanProcessor`s in the order they were registered. (#1203)\n\n### Removed\n\n- Remove the B3 propagator from `go.opentelemetry.io/otel/propagators`. It is now located in the\n   `go.opentelemetry.io/contrib/propagators/` module. (#1191)\n- Remove the semantic convention for HTTP status text, `HTTPStatusTextKey` from package `go.opentelemetry.io/otel/semconv`. (#1194)\n\n### Fixed\n\n- Zipkin example no longer mentions `ParentSampler`, corrected to `ParentBased`. (#1171)\n- Fix missing shutdown processor in otel-collector example. (#1186)\n- Fix missing shutdown processor in basic and namedtracer examples. (#1197)\n\n## [0.11.0] - 2020-08-24\n\n### Added\n\n- Support for exporting array-valued attributes via OTLP. (#992)\n- `Noop` and `InMemory` `SpanBatcher` implementations to help with testing integrations. (#994)\n- Support for filtering metric label sets. (#1047)\n- A dimensionality-reducing metric Processor. (#1057)\n- Integration tests for more OTel Collector Attribute types. (#1062)\n- A new `WithSpanProcessor` `ProviderOption` is added to the `go.opentelemetry.io/otel/sdk/trace` package to create a `Provider` and automatically register the `SpanProcessor`. (#1078)\n\n### Changed\n\n- Rename `sdk/metric/processor/test` to `sdk/metric/processor/processortest`. (#1049)\n- Rename `sdk/metric/controller/test` to `sdk/metric/controller/controllertest`. (#1049)\n- Rename `api/testharness` to `api/apitest`. (#1049)\n- Rename `api/trace/testtrace` to `api/trace/tracetest`. (#1049)\n- Change Metric Processor to merge multiple observations. (#1024)\n- The `go.opentelemetry.io/otel/bridge/opentracing` bridge package has been made into its own module.\n   This removes the package dependencies of this bridge from the rest of the OpenTelemetry based project. (#1038)\n- Renamed `go.opentelemetry.io/otel/api/standard` package to `go.opentelemetry.io/otel/semconv` to avoid the ambiguous and generic name `standard` and better describe the package as containing OpenTelemetry semantic conventions. (#1016)\n- The environment variable used for resource detection has been changed from `OTEL_RESOURCE_LABELS` to `OTEL_RESOURCE_ATTRIBUTES` (#1042)\n- Replace `WithSyncer` with `WithBatcher` in examples. (#1044)\n- Replace the `google.golang.org/grpc/codes` dependency in the API with an equivalent `go.opentelemetry.io/otel/codes` package. (#1046)\n- Merge the `go.opentelemetry.io/otel/api/label` and `go.opentelemetry.io/otel/api/kv` into the new `go.opentelemetry.io/otel/label` package. (#1060)\n- Unify Callback Function Naming.\n   Rename `*Callback` with `*Func`. (#1061)\n- CI builds validate against last two versions of Go, dropping 1.13 and adding 1.15. (#1064)\n- The `go.opentelemetry.io/otel/sdk/export/trace` interfaces `SpanSyncer` and `SpanBatcher` have been replaced with a specification compliant `Exporter` interface.\n   This interface still supports the export of `SpanData`, but only as a slice.\n   Implementation are also required now to return any error from `ExportSpans` if one occurs as well as implement a `Shutdown` method for exporter clean-up. (#1078)\n- The `go.opentelemetry.io/otel/sdk/trace` `NewBatchSpanProcessor` function no longer returns an error.\n   If a `nil` exporter is passed as an argument to this function, instead of it returning an error, it now returns a `BatchSpanProcessor` that handles the export of `SpanData` by not taking any action. (#1078)\n- The `go.opentelemetry.io/otel/sdk/trace` `NewProvider` function to create a `Provider` no longer returns an error, instead only a `*Provider`.\n   This change is related to `NewBatchSpanProcessor` not returning an error which was the only error this function would return. (#1078)\n\n### Removed\n\n- Duplicate, unused API sampler interface. (#999)\n   Use the [`Sampler` interface](https://github.com/open-telemetry/opentelemetry-go/blob/v0.11.0/sdk/trace/sampling.go) provided by the SDK instead.\n- The `grpctrace` instrumentation was moved to the `go.opentelemetry.io/contrib` repository and out of this repository.\n   This move includes moving the `grpc` example to the `go.opentelemetry.io/contrib` as well. (#1027)\n- The `WithSpan` method of the `Tracer` interface.\n   The functionality this method provided was limited compared to what a user can provide themselves.\n   It was removed with the understanding that if there is sufficient user need it can be added back based on actual user usage. (#1043)\n- The `RegisterSpanProcessor` and `UnregisterSpanProcessor` functions.\n   These were holdovers from an approach prior to the TracerProvider design. They were not used anymore. (#1077)\n- The `oterror` package. (#1026)\n- The `othttp` and `httptrace` instrumentations were moved to `go.opentelemetry.io/contrib`. (#1032)\n\n### Fixed\n\n- The `semconv.HTTPServerMetricAttributesFromHTTPRequest()` function no longer generates the high-cardinality `http.request.content.length` label. (#1031)\n- Correct instrumentation version tag in Jaeger exporter. (#1037)\n- The SDK span will now set an error event if the `End` method is called during a panic (i.e. it was deferred). (#1043)\n- Move internally generated protobuf code from the `go.opentelemetry.io/otel` to the OTLP exporter to reduce dependency overhead. (#1050)\n- The `otel-collector` example referenced outdated collector processors. (#1006)\n\n## [0.10.0] - 2020-07-29\n\nThis release migrates the default OpenTelemetry SDK into its own Go module, decoupling the SDK from the API and reducing dependencies for instrumentation packages.\n\n### Added\n\n- The Zipkin exporter now has `NewExportPipeline` and `InstallNewPipeline` constructor functions to match the common pattern.\n    These function build a new exporter with default SDK options and register the exporter with the `global` package respectively. (#944)\n- Add propagator option for gRPC instrumentation. (#986)\n- The `testtrace` package now tracks the `trace.SpanKind` for each span. (#987)\n\n### Changed\n\n- Replace the `RegisterGlobal` `Option` in the Jaeger exporter with an `InstallNewPipeline` constructor function.\n   This matches the other exporter constructor patterns and will register a new exporter after building it with default configuration. (#944)\n- The trace (`go.opentelemetry.io/otel/exporters/trace/stdout`) and metric (`go.opentelemetry.io/otel/exporters/metric/stdout`) `stdout` exporters are now merged into a single exporter at `go.opentelemetry.io/otel/exporters/stdout`.\n   This new exporter was made into its own Go module to follow the pattern of all exporters and decouple it from the `go.opentelemetry.io/otel` module. (#956, #963)\n- Move the `go.opentelemetry.io/otel/exporters/test` test package to `go.opentelemetry.io/otel/sdk/export/metric/metrictest`. (#962)\n- The `go.opentelemetry.io/otel/api/kv/value` package was merged into the parent `go.opentelemetry.io/otel/api/kv` package. (#968)\n  - `value.Bool` was replaced with `kv.BoolValue`.\n  - `value.Int64` was replaced with `kv.Int64Value`.\n  - `value.Uint64` was replaced with `kv.Uint64Value`.\n  - `value.Float64` was replaced with `kv.Float64Value`.\n  - `value.Int32` was replaced with `kv.Int32Value`.\n  - `value.Uint32` was replaced with `kv.Uint32Value`.\n  - `value.Float32` was replaced with `kv.Float32Value`.\n  - `value.String` was replaced with `kv.StringValue`.\n  - `value.Int` was replaced with `kv.IntValue`.\n  - `value.Uint` was replaced with `kv.UintValue`.\n  - `value.Array` was replaced with `kv.ArrayValue`.\n- Rename `Infer` to `Any` in the `go.opentelemetry.io/otel/api/kv` package. (#972)\n- Change `othttp` to use the `httpsnoop` package to wrap the `ResponseWriter` so that optional interfaces (`http.Hijacker`, `http.Flusher`, etc.) that are implemented by the original `ResponseWriter`are also implemented by the wrapped `ResponseWriter`. (#979)\n- Rename `go.opentelemetry.io/otel/sdk/metric/aggregator/test` package to `go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest`. (#980)\n- Make the SDK into its own Go module called `go.opentelemetry.io/otel/sdk`. (#985)\n- Changed the default trace `Sampler` from `AlwaysOn` to `ParentOrElse(AlwaysOn)`. (#989)\n\n### Removed\n\n- The `IndexedAttribute` function from the `go.opentelemetry.io/otel/api/label` package was removed in favor of `IndexedLabel` which it was synonymous with. (#970)\n\n### Fixed\n\n- Bump github.com/golangci/golangci-lint from 1.28.3 to 1.29.0 in /tools. (#953)\n- Bump github.com/google/go-cmp from 0.5.0 to 0.5.1. (#957)\n- Use `global.Handle` for span export errors in the OTLP exporter. (#946)\n- Correct Go language formatting in the README documentation. (#961)\n- Remove default SDK dependencies from the `go.opentelemetry.io/otel/api` package. (#977)\n- Remove default SDK dependencies from the `go.opentelemetry.io/otel/instrumentation` package. (#983)\n- Move documented examples for `go.opentelemetry.io/otel/instrumentation/grpctrace` interceptors into Go example tests. (#984)\n\n## [0.9.0] - 2020-07-20\n\n### Added\n\n- A new Resource Detector interface is included to allow resources to be automatically detected and included. (#939)\n- A Detector to automatically detect resources from an environment variable. (#939)\n- Github action to generate protobuf Go bindings locally in `internal/opentelemetry-proto-gen`. (#938)\n- OTLP .proto files from `open-telemetry/opentelemetry-proto` imported as a git submodule under `internal/opentelemetry-proto`.\n   References to `github.com/open-telemetry/opentelemetry-proto` changed to `go.opentelemetry.io/otel/internal/opentelemetry-proto-gen`. (#942)\n\n### Changed\n\n- Non-nil value `struct`s for key-value pairs will be marshalled using JSON rather than `Sprintf`. (#948)\n\n### Removed\n\n- Removed dependency on `github.com/open-telemetry/opentelemetry-collector`. (#943)\n\n## [0.8.0] - 2020-07-09\n\n### Added\n\n- The `B3Encoding` type to represent the B3 encoding(s) the B3 propagator can inject.\n   A value for HTTP supported encodings (Multiple Header: `MultipleHeader`, Single Header: `SingleHeader`) are included. (#882)\n- The `FlagsDeferred` trace flag to indicate if the trace sampling decision has been deferred. (#882)\n- The `FlagsDebug` trace flag to indicate if the trace is a debug trace. (#882)\n- Add `peer.service` semantic attribute. (#898)\n- Add database-specific semantic attributes. (#899)\n- Add semantic convention for `faas.coldstart` and `container.id`. (#909)\n- Add http content size semantic conventions. (#905)\n- Include `http.request_content_length` in HTTP request basic attributes. (#905)\n- Add semantic conventions for operating system process resource attribute keys. (#919)\n- The Jaeger exporter now has a `WithBatchMaxCount` option to specify the maximum number of spans sent in a batch. (#931)\n\n### Changed\n\n- Update `CONTRIBUTING.md` to ask for updates to `CHANGELOG.md` with each pull request. (#879)\n- Use lowercase header names for B3 Multiple Headers. (#881)\n- The B3 propagator `SingleHeader` field has been replaced with `InjectEncoding`.\n   This new field can be set to combinations of the `B3Encoding` bitmasks and will inject trace information in these encodings.\n   If no encoding is set, the propagator will default to `MultipleHeader` encoding. (#882)\n- The B3 propagator now extracts from either HTTP encoding of B3 (Single Header or Multiple Header) based on what is contained in the header.\n   Preference is given to Single Header encoding with Multiple Header being the fallback if Single Header is not found or is invalid.\n   This behavior change is made to dynamically support all correctly encoded traces received instead of having to guess the expected encoding prior to receiving. (#882)\n- Extend semantic conventions for RPC. (#900)\n- To match constant naming conventions in the `api/standard` package, the `FaaS*` key names are appended with a suffix of `Key`. (#920)\n  - `\"api/standard\".FaaSName` -> `FaaSNameKey`\n  - `\"api/standard\".FaaSID` -> `FaaSIDKey`\n  - `\"api/standard\".FaaSVersion` -> `FaaSVersionKey`\n  - `\"api/standard\".FaaSInstance` -> `FaaSInstanceKey`\n\n### Removed\n\n- The `FlagsUnused` trace flag is removed.\n   The purpose of this flag was to act as the inverse of `FlagsSampled`, the inverse of `FlagsSampled` is used instead. (#882)\n- The B3 header constants (`B3SingleHeader`, `B3DebugFlagHeader`, `B3TraceIDHeader`, `B3SpanIDHeader`, `B3SampledHeader`, `B3ParentSpanIDHeader`) are removed.\n   If B3 header keys are needed [the authoritative OpenZipkin package constants](https://pkg.go.dev/github.com/openzipkin/zipkin-go@v0.2.2/propagation/b3?tab=doc#pkg-constants) should be used instead. (#882)\n\n### Fixed\n\n- The B3 Single Header name is now correctly `b3` instead of the previous `X-B3`. (#881)\n- The B3 propagator now correctly supports sampling only values (`b3: 0`, `b3: 1`, or `b3: d`) for a Single B3 Header. (#882)\n- The B3 propagator now propagates the debug flag.\n   This removes the behavior of changing the debug flag into a set sampling bit.\n   Instead, this now follow the B3 specification and omits the `X-B3-Sampling` header. (#882)\n- The B3 propagator now tracks \"unset\" sampling state (meaning \"defer the decision\") and does not set the `X-B3-Sampling` header when injecting. (#882)\n- Bump github.com/itchyny/gojq from 0.10.3 to 0.10.4 in /tools. (#883)\n- Bump github.com/opentracing/opentracing-go from v1.1.1-0.20190913142402-a7454ce5950e to v1.2.0. (#885)\n- The tracing time conversion for OTLP spans is now correctly set to `UnixNano`. (#896)\n- Ensure span status is not set to `Unknown` when no HTTP status code is provided as it is assumed to be `200 OK`. (#908)\n- Ensure `httptrace.clientTracer` closes `http.headers` span. (#912)\n- Prometheus exporter will not apply stale updates or forget inactive metrics. (#903)\n- Add test for api.standard `HTTPClientAttributesFromHTTPRequest`. (#905)\n- Bump github.com/golangci/golangci-lint from 1.27.0 to 1.28.1 in /tools. (#901, #913)\n- Update otel-collector example to use the v0.5.0 collector. (#915)\n- The `grpctrace` instrumentation uses a span name conforming to the OpenTelemetry semantic conventions (does not contain a leading slash (`/`)). (#922)\n- The `grpctrace` instrumentation includes an `rpc.method` attribute now set to the gRPC method name. (#900, #922)\n- The `grpctrace` instrumentation `rpc.service` attribute now contains the package name if one exists.\n   This is in accordance with OpenTelemetry semantic conventions. (#922)\n- Correlation Context extractor will no longer insert an empty map into the returned context when no valid values are extracted. (#923)\n- Bump google.golang.org/api from 0.28.0 to 0.29.0 in /exporters/trace/jaeger. (#925)\n- Bump github.com/itchyny/gojq from 0.10.4 to 0.11.0 in /tools. (#926)\n- Bump github.com/golangci/golangci-lint from 1.28.1 to 1.28.2 in /tools. (#930)\n\n## [0.7.0] - 2020-06-26\n\nThis release implements the v0.5.0 version of the OpenTelemetry specification.\n\n### Added\n\n- The othttp instrumentation now includes default metrics. (#861)\n- This CHANGELOG file to track all changes in the project going forward.\n- Support for array type attributes. (#798)\n- Apply transitive dependabot go.mod dependency updates as part of a new automatic Github workflow. (#844)\n- Timestamps are now passed to exporters for each export. (#835)\n- Add new `Accumulation` type to metric SDK to transport telemetry from `Accumulator`s to `Processor`s.\n   This replaces the prior `Record` `struct` use for this purpose. (#835)\n- New dependabot integration to automate package upgrades. (#814)\n- `Meter` and `Tracer` implementations accept instrumentation version version as an optional argument.\n   This instrumentation version is passed on to exporters. (#811) (#805) (#802)\n- The OTLP exporter includes the instrumentation version in telemetry it exports. (#811)\n- Environment variables for Jaeger exporter are supported. (#796)\n- New `aggregation.Kind` in the export metric API. (#808)\n- New example that uses OTLP and the collector. (#790)\n- Handle errors in the span `SetName` during span initialization. (#791)\n- Default service config to enable retries for retry-able failed requests in the OTLP exporter and an option to override this default. (#777)\n- New `go.opentelemetry.io/otel/api/oterror` package to uniformly support error handling and definitions for the project. (#778)\n- New `global` default implementation of the `go.opentelemetry.io/otel/api/oterror.Handler` interface to be used to handle errors prior to an user defined `Handler`.\n   There is also functionality for the user to register their `Handler` as well as a convenience function `Handle` to handle an error with this global `Handler`(#778)\n- Options to specify propagators for httptrace and grpctrace instrumentation. (#784)\n- The required `application/json` header for the Zipkin exporter is included in all exports. (#774)\n- Integrate HTTP semantics helpers from the contrib repository into the `api/standard` package. #769\n\n### Changed\n\n- Rename `Integrator` to `Processor` in the metric SDK. (#863)\n- Rename `AggregationSelector` to `AggregatorSelector`. (#859)\n- Rename `SynchronizedCopy` to `SynchronizedMove`. (#858)\n- Rename `simple` integrator to `basic` integrator. (#857)\n- Merge otlp collector examples. (#841)\n- Change the metric SDK to support cumulative, delta, and pass-through exporters directly.\n   With these changes, cumulative and delta specific exporters are able to request the correct kind of aggregation from the SDK. (#840)\n- The `Aggregator.Checkpoint` API is renamed to `SynchronizedCopy` and adds an argument, a different `Aggregator` into which the copy is stored. (#812)\n- The `export.Aggregator` contract is that `Update()` and `SynchronizedCopy()` are synchronized with each other.\n   All the aggregation interfaces (`Sum`, `LastValue`, ...) are not meant to be synchronized, as the caller is expected to synchronize aggregators at a higher level after the `Accumulator`.\n   Some of the `Aggregators` used unnecessary locking and that has been cleaned up. (#812)\n- Use of `metric.Number` was replaced by `int64` now that we use `sync.Mutex` in the `MinMaxSumCount` and `Histogram` `Aggregators`. (#812)\n- Replace `AlwaysParentSample` with `ParentSample(fallback)` to match the OpenTelemetry v0.5.0 specification. (#810)\n- Rename `sdk/export/metric/aggregator` to `sdk/export/metric/aggregation`. #808\n- Send configured headers with every request in the OTLP exporter, instead of just on connection creation. (#806)\n- Update error handling for any one off error handlers, replacing, instead, with the `global.Handle` function. (#791)\n- Rename `plugin` directory to `instrumentation` to match the OpenTelemetry specification. (#779)\n- Makes the argument order to Histogram and DDSketch `New()` consistent. (#781)\n\n### Removed\n\n- `Uint64NumberKind` and related functions from the API. (#864)\n- Context arguments from `Aggregator.Checkpoint` and `Integrator.Process` as they were unused. (#803)\n- `SpanID` is no longer included in parameters for sampling decision to match the OpenTelemetry specification. (#775)\n\n### Fixed\n\n- Upgrade OTLP exporter to opentelemetry-proto matching the opentelemetry-collector v0.4.0 release. (#866)\n- Allow changes to `go.sum` and `go.mod` when running dependabot tidy-up. (#871)\n- Bump github.com/stretchr/testify from 1.4.0 to 1.6.1. (#824)\n- Bump github.com/prometheus/client_golang from 1.7.0 to 1.7.1 in /exporters/metric/prometheus. (#867)\n- Bump google.golang.org/grpc from 1.29.1 to 1.30.0 in /exporters/trace/jaeger. (#853)\n- Bump google.golang.org/grpc from 1.29.1 to 1.30.0 in /exporters/trace/zipkin. (#854)\n- Bumps github.com/golang/protobuf from 1.3.2 to 1.4.2 (#848)\n- Bump github.com/stretchr/testify from 1.4.0 to 1.6.1 in /exporters/otlp (#817)\n- Bump github.com/golangci/golangci-lint from 1.25.1 to 1.27.0 in /tools (#828)\n- Bump github.com/prometheus/client_golang from 1.5.0 to 1.7.0 in /exporters/metric/prometheus (#838)\n- Bump github.com/stretchr/testify from 1.4.0 to 1.6.1 in /exporters/trace/jaeger (#829)\n- Bump github.com/benbjohnson/clock from 1.0.0 to 1.0.3 (#815)\n- Bump github.com/stretchr/testify from 1.4.0 to 1.6.1 in /exporters/trace/zipkin (#823)\n- Bump github.com/itchyny/gojq from 0.10.1 to 0.10.3 in /tools (#830)\n- Bump github.com/stretchr/testify from 1.4.0 to 1.6.1 in /exporters/metric/prometheus (#822)\n- Bump google.golang.org/grpc from 1.27.1 to 1.29.1 in /exporters/trace/zipkin (#820)\n- Bump google.golang.org/grpc from 1.27.1 to 1.29.1 in /exporters/trace/jaeger (#831)\n- Bump github.com/google/go-cmp from 0.4.0 to 0.5.0 (#836)\n- Bump github.com/google/go-cmp from 0.4.0 to 0.5.0 in /exporters/trace/jaeger (#837)\n- Bump github.com/google/go-cmp from 0.4.0 to 0.5.0 in /exporters/otlp (#839)\n- Bump google.golang.org/api from 0.20.0 to 0.28.0 in /exporters/trace/jaeger (#843)\n- Set span status from HTTP status code in the othttp instrumentation. (#832)\n- Fixed typo in push controller comment. (#834)\n- The `Aggregator` testing has been updated and cleaned. (#812)\n- `metric.Number(0)` expressions are replaced by `0` where possible. (#812)\n- Fixed `global` `handler_test.go` test failure. #804\n- Fixed `BatchSpanProcessor.Shutdown` to wait until all spans are processed. (#766)\n- Fixed OTLP example's accidental early close of exporter. (#807)\n- Ensure zipkin exporter reads and closes response body. (#788)\n- Update instrumentation to use `api/standard` keys instead of custom keys. (#782)\n- Clean up tools and RELEASING documentation. (#762)\n\n## [0.6.0] - 2020-05-21\n\n### Added\n\n- Support for `Resource`s in the prometheus exporter. (#757)\n- New pull controller. (#751)\n- New `UpDownSumObserver` instrument. (#750)\n- OpenTelemetry collector demo. (#711)\n- New `SumObserver` instrument. (#747)\n- New `UpDownCounter` instrument. (#745)\n- New timeout `Option` and configuration function `WithTimeout` to the push controller. (#742)\n- New `api/standards` package to implement semantic conventions and standard key-value generation. (#731)\n\n### Changed\n\n- Rename `Register*` functions in the metric API to `New*` for all `Observer` instruments. (#761)\n- Use `[]float64` for histogram boundaries, not `[]metric.Number`. (#758)\n- Change OTLP example to use exporter as a trace `Syncer` instead of as an unneeded `Batcher`. (#756)\n- Replace `WithResourceAttributes()` with `WithResource()` in the trace SDK. (#754)\n- The prometheus exporter now uses the new pull controller. (#751)\n- Rename `ScheduleDelayMillis` to `BatchTimeout` in the trace `BatchSpanProcessor`.(#752)\n- Support use of synchronous instruments in asynchronous callbacks (#725)\n- Move `Resource` from the `Export` method parameter into the metric export `Record`. (#739)\n- Rename `Observer` instrument to `ValueObserver`. (#734)\n- The push controller now has a method (`Provider()`) to return a `metric.Provider` instead of the old `Meter` method that acted as a `metric.Provider`. (#738)\n- Replace `Measure` instrument by `ValueRecorder` instrument. (#732)\n- Rename correlation context header from `\"Correlation-Context\"` to `\"otcorrelations\"` to match the OpenTelemetry specification. (#727)\n\n### Fixed\n\n- Ensure gRPC `ClientStream` override methods do not panic in grpctrace package. (#755)\n- Disable parts of `BatchSpanProcessor` test until a fix is found. (#743)\n- Fix `string` case in `kv` `Infer` function. (#746)\n- Fix panic in grpctrace client interceptors. (#740)\n- Refactor the `api/metrics` push controller and add `CheckpointSet` synchronization. (#737)\n- Rewrite span batch process queue batching logic. (#719)\n- Remove the push controller named Meter map. (#738)\n- Fix Histogram aggregator initial state (fix #735). (#736)\n- Ensure golang alpine image is running `golang-1.14` for examples. (#733)\n- Added test for grpctrace `UnaryInterceptorClient`. (#695)\n- Rearrange `api/metric` code layout. (#724)\n\n## [0.5.0] - 2020-05-13\n\n### Added\n\n- Batch `Observer` callback support. (#717)\n- Alias `api` types to root package of project. (#696)\n- Create basic `othttp.Transport` for simple client instrumentation. (#678)\n- `SetAttribute(string, interface{})` to the trace API. (#674)\n- Jaeger exporter option that allows user to specify custom http client. (#671)\n- `Stringer` and `Infer` methods to `key`s. (#662)\n\n### Changed\n\n- Rename `NewKey` in the `kv` package to just `Key`. (#721)\n- Move `core` and `key` to `kv` package. (#720)\n- Make the metric API `Meter` a `struct` so the abstract `MeterImpl` can be passed and simplify implementation. (#709)\n- Rename SDK `Batcher` to `Integrator` to match draft OpenTelemetry SDK specification. (#710)\n- Rename SDK `Ungrouped` integrator to `simple.Integrator` to match draft OpenTelemetry SDK specification. (#710)\n- Rename SDK `SDK` `struct` to `Accumulator` to match draft OpenTelemetry SDK specification. (#710)\n- Move `Number` from `core` to `api/metric` package. (#706)\n- Move `SpanContext` from `core` to `trace` package. (#692)\n- Change traceparent header from `Traceparent` to `traceparent` to implement the W3C specification. (#681)\n\n### Fixed\n\n- Update tooling to run generators in all submodules. (#705)\n- gRPC interceptor regexp to match methods without a service name. (#683)\n- Use a `const` for padding 64-bit B3 trace IDs. (#701)\n- Update `mockZipkin` listen address from `:0` to `127.0.0.1:0`. (#700)\n- Left-pad 64-bit B3 trace IDs with zero. (#698)\n- Propagate at least the first W3C tracestate header. (#694)\n- Remove internal `StateLocker` implementation. (#688)\n- Increase instance size CI system uses. (#690)\n- Add a `key` benchmark and use reflection in `key.Infer()`. (#679)\n- Fix internal `global` test by using `global.Meter` with `RecordBatch()`. (#680)\n- Reimplement histogram using mutex instead of `StateLocker`. (#669)\n- Switch `MinMaxSumCount` to a mutex lock implementation instead of `StateLocker`. (#667)\n- Update documentation to not include any references to `WithKeys`. (#672)\n- Correct misspelling. (#668)\n- Fix clobbering of the span context if extraction fails. (#656)\n- Bump `golangci-lint` and work around the corrupting bug. (#666) (#670)\n\n## [0.4.3] - 2020-04-24\n\n### Added\n\n- `Dockerfile` and `docker-compose.yml` to run example code. (#635)\n- New `grpctrace` package that provides gRPC client and server interceptors for both unary and stream connections. (#621)\n- New `api/label` package, providing common label set implementation. (#651)\n- Support for JSON marshaling of `Resources`. (#654)\n- `TraceID` and `SpanID` implementations for `Stringer` interface. (#642)\n- `RemoteAddrKey` in the othttp plugin to include the HTTP client address in top-level spans. (#627)\n- `WithSpanFormatter` option to the othttp plugin. (#617)\n- Updated README to include section for compatible libraries and include reference to the contrib repository. (#612)\n- The prometheus exporter now supports exporting histograms. (#601)\n- A `String` method to the `Resource` to return a hashable identifier for a now unique resource. (#613)\n- An `Iter` method to the `Resource` to return an array `AttributeIterator`. (#613)\n- An `Equal` method to the `Resource` test the equivalence of resources. (#613)\n- An iterable structure (`AttributeIterator`) for `Resource` attributes.\n\n### Changed\n\n- zipkin export's `NewExporter` now requires a `serviceName` argument to ensure this needed values is provided. (#644)\n- Pass `Resources` through the metrics export pipeline. (#659)\n\n### Removed\n\n- `WithKeys` option from the metric API. (#639)\n\n### Fixed\n\n- Use the `label.Set.Equivalent` value instead of an encoding in the batcher. (#658)\n- Correct typo `trace.Exporter` to `trace.SpanSyncer` in comments. (#653)\n- Use type names for return values in jaeger exporter. (#648)\n- Increase the visibility of the `api/key` package by updating comments and fixing usages locally. (#650)\n- `Checkpoint` only after `Update`; Keep records in the `sync.Map` longer. (#647)\n- Do not cache `reflect.ValueOf()` in metric Labels. (#649)\n- Batch metrics exported from the OTLP exporter based on `Resource` and labels. (#626)\n- Add error wrapping to the prometheus exporter. (#631)\n- Update the OTLP exporter batching of traces to use a unique `string` representation of an associated `Resource` as the batching key. (#623)\n- Update OTLP `SpanData` transform to only include the `ParentSpanID` if one exists. (#614)\n- Update `Resource` internal representation to uniquely and reliably identify resources. (#613)\n- Check return value from `CheckpointSet.ForEach` in prometheus exporter. (#622)\n- Ensure spans created by httptrace client tracer reflect operation structure. (#618)\n- Create a new recorder rather than reuse when multiple observations in same epoch for asynchronous instruments. #610\n- The default port the OTLP exporter uses to connect to the OpenTelemetry collector is updated to match the one the collector listens on by default. (#611)\n\n## [0.4.2] - 2020-03-31\n\n### Fixed\n\n- Fix `pre_release.sh` to update version in `sdk/opentelemetry.go`. (#607)\n- Fix time conversion from internal to OTLP in OTLP exporter. (#606)\n\n## [0.4.1] - 2020-03-31\n\n### Fixed\n\n- Update `tag.sh` to create signed tags. (#604)\n\n## [0.4.0] - 2020-03-30\n\n### Added\n\n- New API package `api/metric/registry` that exposes a `MeterImpl` wrapper for use by SDKs to generate unique instruments. (#580)\n- Script to verify examples after a new release. (#579)\n\n### Removed\n\n- The dogstatsd exporter due to lack of support.\n   This additionally removes support for statsd. (#591)\n- `LabelSet` from the metric API.\n   This is replaced by a `[]core.KeyValue` slice. (#595)\n- `Labels` from the metric API's `Meter` interface. (#595)\n\n### Changed\n\n- The metric `export.Labels` became an interface which the SDK implements and the `export` package provides a simple, immutable implementation of this interface intended for testing purposes. (#574)\n- Renamed `internal/metric.Meter` to `MeterImpl`. (#580)\n- Renamed `api/global/internal.obsImpl` to `asyncImpl`. (#580)\n\n### Fixed\n\n- Corrected missing return in mock span. (#582)\n- Update License header for all source files to match CNCF guidelines and include a test to ensure it is present. (#586) (#596)\n- Update to v0.3.0 of the OTLP in the OTLP exporter. (#588)\n- Update pre-release script to be compatible between GNU and BSD based systems. (#592)\n- Add a `RecordBatch` benchmark. (#594)\n- Moved span transforms of the OTLP exporter to the internal package. (#593)\n- Build both go-1.13 and go-1.14 in circleci to test for all supported versions of Go. (#569)\n- Removed unneeded allocation on empty labels in OLTP exporter. (#597)\n- Update `BatchedSpanProcessor` to process the queue until no data but respect max batch size. (#599)\n- Update project documentation godoc.org links to pkg.go.dev. (#602)\n\n## [0.3.0] - 2020-03-21\n\nThis is a first official beta release, which provides almost fully complete metrics, tracing, and context propagation functionality.\nThere is still a possibility of breaking changes.\n\n### Added\n\n- Add `Observer` metric instrument. (#474)\n- Add global `Propagators` functionality to enable deferred initialization for propagators registered before the first Meter SDK is installed. (#494)\n- Simplified export setup pipeline for the jaeger exporter to match other exporters. (#459)\n- The zipkin trace exporter. (#495)\n- The OTLP exporter to export metric and trace telemetry to the OpenTelemetry collector. (#497) (#544) (#545)\n- Add `StatusMessage` field to the trace `Span`. (#524)\n- Context propagation in OpenTracing bridge in terms of OpenTelemetry context propagation. (#525)\n- The `Resource` type was added to the SDK. (#528)\n- The global API now supports a `Tracer` and `Meter` function as shortcuts to getting a global `*Provider` and calling these methods directly. (#538)\n- The metric API now defines a generic `MeterImpl` interface to support general purpose `Meter` construction.\n   Additionally, `SyncImpl` and `AsyncImpl` are added to support general purpose instrument construction. (#560)\n- A metric `Kind` is added to represent the `MeasureKind`, `ObserverKind`, and `CounterKind`. (#560)\n- Scripts to better automate the release process. (#576)\n\n### Changed\n\n- Default to to use `AlwaysSampler` instead of `ProbabilitySampler` to match OpenTelemetry specification. (#506)\n- Renamed `AlwaysSampleSampler` to `AlwaysOnSampler` in the trace API. (#511)\n- Renamed `NeverSampleSampler` to `AlwaysOffSampler` in the trace API. (#511)\n- The `Status` field of the `Span` was changed to `StatusCode` to disambiguate with the added `StatusMessage`. (#524)\n- Updated the trace `Sampler` interface conform to the OpenTelemetry specification. (#531)\n- Rename metric API `Options` to `Config`. (#541)\n- Rename metric `Counter` aggregator to be `Sum`. (#541)\n- Unify metric options into `Option` from instrument specific options. (#541)\n- The trace API's `TraceProvider` now support `Resource`s. (#545)\n- Correct error in zipkin module name. (#548)\n- The jaeger trace exporter now supports `Resource`s. (#551)\n- Metric SDK now supports `Resource`s.\n   The `WithResource` option was added to configure a `Resource` on creation and the `Resource` method was added to the metric `Descriptor` to return the associated `Resource`. (#552)\n- Replace `ErrNoLastValue` and `ErrEmptyDataSet` by `ErrNoData` in the metric SDK. (#557)\n- The stdout trace exporter now supports `Resource`s. (#558)\n- The metric `Descriptor` is now included at the API instead of the SDK. (#560)\n- Replace `Ordered` with an iterator in `export.Labels`. (#567)\n\n### Removed\n\n- The vendor specific Stackdriver. It is now hosted on 3rd party vendor infrastructure. (#452)\n- The `Unregister` method for metric observers as it is not in the OpenTelemetry specification. (#560)\n- `GetDescriptor` from the metric SDK. (#575)\n- The `Gauge` instrument from the metric API. (#537)\n\n### Fixed\n\n- Make histogram aggregator checkpoint consistent. (#438)\n- Update README with import instructions and how to build and test. (#505)\n- The default label encoding was updated to be unique. (#508)\n- Use `NewRoot` in the othttp plugin for public endpoints. (#513)\n- Fix data race in `BatchedSpanProcessor`. (#518)\n- Skip test-386 for Mac OS 10.15.x (Catalina and upwards). #521\n- Use a variable-size array to represent ordered labels in maps. (#523)\n- Update the OTLP protobuf and update changed import path. (#532)\n- Use `StateLocker` implementation in `MinMaxSumCount`. (#546)\n- Eliminate goroutine leak in histogram stress test. (#547)\n- Update OTLP exporter with latest protobuf. (#550)\n- Add filters to the othttp plugin. (#556)\n- Provide an implementation of the `Header*` filters that do not depend on Go 1.14. (#565)\n- Encode labels once during checkpoint.\n   The checkpoint function is executed in a single thread so we can do the encoding lazily before passing the encoded version of labels to the exporter.\n   This is a cheap and quick way to avoid encoding the labels on every collection interval. (#572)\n- Run coverage over all packages in `COVERAGE_MOD_DIR`. (#573)\n\n## [0.2.3] - 2020-03-04\n\n### Added\n\n- `RecordError` method on `Span`s in the trace API to Simplify adding error events to spans. (#473)\n- Configurable push frequency for exporters setup pipeline. (#504)\n\n### Changed\n\n- Rename the `exporter` directory to `exporters`.\n   The `go.opentelemetry.io/otel/exporter/trace/jaeger` package was mistakenly released with a `v1.0.0` tag instead of `v0.1.0`.\n   This resulted in all subsequent releases not becoming the default latest.\n   A consequence of this was that all `go get`s pulled in the incompatible `v0.1.0` release of that package when pulling in more recent packages from other otel packages.\n   Renaming the `exporter` directory to `exporters` fixes this issue by renaming the package and therefore clearing any existing dependency tags.\n   Consequentially, this action also renames *all* exporter packages. (#502)\n\n### Removed\n\n- The `CorrelationContextHeader` constant in the `correlation` package is no longer exported. (#503)\n\n## [0.2.2] - 2020-02-27\n\n### Added\n\n- `HTTPSupplier` interface in the propagation API to specify methods to retrieve and store a single value for a key to be associated with a carrier. (#467)\n- `HTTPExtractor` interface in the propagation API to extract information from an `HTTPSupplier` into a context. (#467)\n- `HTTPInjector` interface in the propagation API to inject information into an `HTTPSupplier.` (#467)\n- `Config` and configuring `Option` to the propagator API. (#467)\n- `Propagators` interface in the propagation API to contain the set of injectors and extractors for all supported carrier formats. (#467)\n- `HTTPPropagator` interface in the propagation API to inject and extract from an `HTTPSupplier.` (#467)\n- `WithInjectors` and `WithExtractors` functions to the propagator API to configure injectors and extractors to use. (#467)\n- `ExtractHTTP` and `InjectHTTP` functions to apply configured HTTP extractors and injectors to a passed context. (#467)\n- Histogram aggregator. (#433)\n- `DefaultPropagator` function and have it return `trace.TraceContext` as the default context propagator. (#456)\n- `AlwaysParentSample` sampler to the trace API. (#455)\n- `WithNewRoot` option function to the trace API to specify the created span should be considered a root span. (#451)\n\n### Changed\n\n- Renamed `WithMap` to `ContextWithMap` in the correlation package. (#481)\n- Renamed `FromContext` to `MapFromContext` in the correlation package. (#481)\n- Move correlation context propagation to correlation package. (#479)\n- Do not default to putting remote span context into links. (#480)\n- `Tracer.WithSpan` updated to accept `StartOptions`. (#472)\n- Renamed `MetricKind` to `Kind` to not stutter in the type usage. (#432)\n- Renamed the `export` package to `metric` to match directory structure. (#432)\n- Rename the `api/distributedcontext` package to `api/correlation`. (#444)\n- Rename the `api/propagators` package to `api/propagation`. (#444)\n- Move the propagators from the `propagators` package into the `trace` API package. (#444)\n- Update `Float64Gauge`, `Int64Gauge`, `Float64Counter`, `Int64Counter`, `Float64Measure`, and `Int64Measure` metric methods to use value receivers instead of pointers. (#462)\n- Moved all dependencies of tools package to a tools directory. (#466)\n\n### Removed\n\n- Binary propagators. (#467)\n- NOOP propagator. (#467)\n\n### Fixed\n\n- Upgraded `github.com/golangci/golangci-lint` from `v1.21.0` to `v1.23.6` in `tools/`. (#492)\n- Fix a possible nil-dereference crash (#478)\n- Correct comments for `InstallNewPipeline` in the stdout exporter. (#483)\n- Correct comments for `InstallNewPipeline` in the dogstatsd exporter. (#484)\n- Correct comments for `InstallNewPipeline` in the prometheus exporter. (#482)\n- Initialize `onError` based on `Config` in prometheus exporter. (#486)\n- Correct module name in prometheus exporter README. (#475)\n- Removed tracer name prefix from span names. (#430)\n- Fix `aggregator_test.go` import package comment. (#431)\n- Improved detail in stdout exporter. (#436)\n- Fix a dependency issue (generate target should depend on stringer, not lint target) in Makefile. (#442)\n- Reorders the Makefile targets within `precommit` target so we generate files and build the code before doing linting, so we can get much nicer errors about syntax errors from the compiler. (#442)\n- Reword function documentation in gRPC plugin. (#446)\n- Send the `span.kind` tag to Jaeger from the jaeger exporter. (#441)\n- Fix `metadataSupplier` in the jaeger exporter to overwrite the header if existing instead of appending to it. (#441)\n- Upgraded to Go 1.13 in CI. (#465)\n- Correct opentelemetry.io URL in trace SDK documentation. (#464)\n- Refactored reference counting logic in SDK determination of stale records. (#468)\n- Add call to `runtime.Gosched` in instrument `acquireHandle` logic to not block the collector. (#469)\n\n## [0.2.1.1] - 2020-01-13\n\n### Fixed\n\n- Use stateful batcher on Prometheus exporter fixing regression introduced in #395. (#428)\n\n## [0.2.1] - 2020-01-08\n\n### Added\n\n- Global meter forwarding implementation.\n   This enables deferred initialization for metric instruments registered before the first Meter SDK is installed. (#392)\n- Global trace forwarding implementation.\n   This enables deferred initialization for tracers registered before the first Trace SDK is installed. (#406)\n- Standardize export pipeline creation in all exporters. (#395)\n- A testing, organization, and comments for 64-bit field alignment. (#418)\n- Script to tag all modules in the project. (#414)\n\n### Changed\n\n- Renamed `propagation` package to `propagators`. (#362)\n- Renamed `B3Propagator` propagator to `B3`. (#362)\n- Renamed `TextFormatPropagator` propagator to `TextFormat`. (#362)\n- Renamed `BinaryPropagator` propagator to `Binary`. (#362)\n- Renamed `BinaryFormatPropagator` propagator to `BinaryFormat`. (#362)\n- Renamed `NoopTextFormatPropagator` propagator to `NoopTextFormat`. (#362)\n- Renamed `TraceContextPropagator` propagator to `TraceContext`. (#362)\n- Renamed `SpanOption` to `StartOption` in the trace API. (#369)\n- Renamed `StartOptions` to `StartConfig` in the trace API. (#369)\n- Renamed `EndOptions` to `EndConfig` in the trace API. (#369)\n- `Number` now has a pointer receiver for its methods. (#375)\n- Renamed `CurrentSpan` to `SpanFromContext` in the trace API. (#379)\n- Renamed `SetCurrentSpan` to `ContextWithSpan` in the trace API. (#379)\n- Renamed `Message` in Event to `Name` in the trace API. (#389)\n- Prometheus exporter no longer aggregates metrics, instead it only exports them. (#385)\n- Renamed `HandleImpl` to `BoundInstrumentImpl` in the metric API. (#400)\n- Renamed `Float64CounterHandle` to `Float64CounterBoundInstrument` in the metric API. (#400)\n- Renamed `Int64CounterHandle` to `Int64CounterBoundInstrument` in the metric API. (#400)\n- Renamed `Float64GaugeHandle` to `Float64GaugeBoundInstrument` in the metric API. (#400)\n- Renamed `Int64GaugeHandle` to `Int64GaugeBoundInstrument` in the metric API. (#400)\n- Renamed `Float64MeasureHandle` to `Float64MeasureBoundInstrument` in the metric API. (#400)\n- Renamed `Int64MeasureHandle` to `Int64MeasureBoundInstrument` in the metric API. (#400)\n- Renamed `Release` method for bound instruments in the metric API to `Unbind`. (#400)\n- Renamed `AcquireHandle` method for bound instruments in the metric API to `Bind`. (#400)\n- Renamed the `File` option in the stdout exporter to `Writer`. (#404)\n- Renamed all `Options` to `Config` for all metric exports where this wasn't already the case.\n\n### Fixed\n\n- Aggregator import path corrected. (#421)\n- Correct links in README. (#368)\n- The README was updated to match latest code changes in its examples. (#374)\n- Don't capitalize error statements. (#375)\n- Fix ignored errors. (#375)\n- Fix ambiguous variable naming. (#375)\n- Removed unnecessary type casting. (#375)\n- Use named parameters. (#375)\n- Updated release schedule. (#378)\n- Correct http-stackdriver example module name. (#394)\n- Removed the `http.request` span in `httptrace` package. (#397)\n- Add comments in the metrics SDK (#399)\n- Initialize checkpoint when creating ddsketch aggregator to prevent panic when merging into a empty one. (#402) (#403)\n- Add documentation of compatible exporters in the README. (#405)\n- Typo fix. (#408)\n- Simplify span check logic in SDK tracer implementation. (#419)\n\n## [0.2.0] - 2019-12-03\n\n### Added\n\n- Unary gRPC tracing example. (#351)\n- Prometheus exporter. (#334)\n- Dogstatsd metrics exporter. (#326)\n\n### Changed\n\n- Rename `MaxSumCount` aggregation to `MinMaxSumCount` and add the `Min` interface for this aggregation. (#352)\n- Rename `GetMeter` to `Meter`. (#357)\n- Rename `HTTPTraceContextPropagator` to `TraceContextPropagator`. (#355)\n- Rename `HTTPB3Propagator` to `B3Propagator`. (#355)\n- Rename `HTTPTraceContextPropagator` to `TraceContextPropagator`. (#355)\n- Move `/global` package to `/api/global`. (#356)\n- Rename `GetTracer` to `Tracer`. (#347)\n\n### Removed\n\n- `SetAttribute` from the `Span` interface in the trace API. (#361)\n- `AddLink` from the `Span` interface in the trace API. (#349)\n- `Link` from the `Span` interface in the trace API. (#349)\n\n### Fixed\n\n- Exclude example directories from coverage report. (#365)\n- Lint make target now implements automatic fixes with `golangci-lint` before a second run to report the remaining issues. (#360)\n- Drop `GO111MODULE` environment variable in Makefile as Go 1.13 is the project specified minimum version and this is environment variable is not needed for that version of Go. (#359)\n- Run the race checker for all test. (#354)\n- Redundant commands in the Makefile are removed. (#354)\n- Split the `generate` and `lint` targets of the Makefile. (#354)\n- Renames `circle-ci` target to more generic `ci` in Makefile. (#354)\n- Add example Prometheus binary to gitignore. (#358)\n- Support negative numbers with the `MaxSumCount`. (#335)\n- Resolve race conditions in `push_test.go` identified in #339. (#340)\n- Use `/usr/bin/env bash` as a shebang in scripts rather than `/bin/bash`. (#336)\n- Trace benchmark now tests both `AlwaysSample` and `NeverSample`.\n   Previously it was testing `AlwaysSample` twice. (#325)\n- Trace benchmark now uses a `[]byte` for `TraceID` to fix failing test. (#325)\n- Added a trace benchmark to test variadic functions in `setAttribute` vs `setAttributes` (#325)\n- The `defaultkeys` batcher was only using the encoded label set as its map key while building a checkpoint.\n   This allowed distinct label sets through, but any metrics sharing a label set could be overwritten or merged incorrectly.\n   This was corrected. (#333)\n\n## [0.1.2] - 2019-11-18\n\n### Fixed\n\n- Optimized the `simplelru` map for attributes to reduce the number of allocations. (#328)\n- Removed unnecessary unslicing of parameters that are already a slice. (#324)\n\n## [0.1.1] - 2019-11-18\n\nThis release contains a Metrics SDK with stdout exporter and supports basic aggregations such as counter, gauges, array, maxsumcount, and ddsketch.\n\n### Added\n\n- Metrics stdout export pipeline. (#265)\n- Array aggregation for raw measure metrics. (#282)\n- The core.Value now have a `MarshalJSON` method. (#281)\n\n### Removed\n\n- `WithService`, `WithResources`, and `WithComponent` methods of tracers. (#314)\n- Prefix slash in `Tracer.Start()` for the Jaeger example. (#292)\n\n### Changed\n\n- Allocation in LabelSet construction to reduce GC overhead. (#318)\n- `trace.WithAttributes` to append values instead of replacing (#315)\n- Use a formula for tolerance in sampling tests. (#298)\n- Move export types into trace and metric-specific sub-directories. (#289)\n- `SpanKind` back to being based on an `int` type. (#288)\n\n### Fixed\n\n- URL to OpenTelemetry website in README. (#323)\n- Name of othttp default tracer. (#321)\n- `ExportSpans` for the stackdriver exporter now handles `nil` context. (#294)\n- CI modules cache to correctly restore/save from/to the cache. (#316)\n- Fix metric SDK race condition between `LoadOrStore` and the assignment `rec.recorder = i.meter.exporter.AggregatorFor(rec)`. (#293)\n- README now reflects the new code structure introduced with these changes. (#291)\n- Make the basic example work. (#279)\n\n## [0.1.0] - 2019-11-04\n\nThis is the first release of open-telemetry go library.\nIt contains api and sdk for trace and meter.\n\n### Added\n\n- Initial OpenTelemetry trace and metric API prototypes.\n- Initial OpenTelemetry trace, metric, and export SDK packages.\n- A wireframe bridge to support compatibility with OpenTracing.\n- Example code for a basic, http-stackdriver, http, jaeger, and named tracer setup.\n- Exporters for Jaeger, Stackdriver, and stdout.\n- Propagators for binary, B3, and trace-context protocols.\n- Project information and guidelines in the form of a README and CONTRIBUTING.\n- Tools to build the project and a Makefile to automate the process.\n- Apache-2.0 license.\n- CircleCI build CI manifest files.\n- CODEOWNERS file to track owners of this project.\n\n[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.40.0...HEAD\n[1.40.0/0.62.0/0.16.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.40.0\n[1.39.0/0.61.0/0.15.0/0.0.14]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.39.0\n[1.38.0/0.60.0/0.14.0/0.0.13]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.38.0\n[0.59.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/exporters/prometheus/v0.59.1\n[1.37.0/0.59.0/0.13.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.37.0\n[0.12.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/log/v0.12.2\n[0.12.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/log/v0.12.1\n[1.36.0/0.58.0/0.12.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.36.0\n[1.35.0/0.57.0/0.11.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.35.0\n[1.34.0/0.56.0/0.10.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.34.0\n[1.33.0/0.55.0/0.9.0/0.0.12]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.33.0\n[1.32.0/0.54.0/0.8.0/0.0.11]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.32.0\n[1.31.0/0.53.0/0.7.0/0.0.10]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.31.0\n[1.30.0/0.52.0/0.6.0/0.0.9]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.30.0\n[1.29.0/0.51.0/0.5.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.29.0\n[1.28.0/0.50.0/0.4.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.28.0\n[1.27.0/0.49.0/0.3.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.27.0\n[1.26.0/0.48.0/0.2.0-alpha]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.26.0\n[1.25.0/0.47.0/0.0.8/0.1.0-alpha]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.25.0\n[1.24.0/0.46.0/0.0.1-alpha]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.24.0\n[1.23.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.23.1\n[1.23.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.23.0\n[1.23.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.23.0-rc.1\n[1.22.0/0.45.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.22.0\n[1.21.0/0.44.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.21.0\n[1.20.0/0.43.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.20.0\n[1.19.0/0.42.0/0.0.7]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.19.0\n[1.19.0-rc.1/0.42.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.19.0-rc.1\n[1.18.0/0.41.0/0.0.6]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.18.0\n[1.17.0/0.40.0/0.0.5]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.17.0\n[1.16.0/0.39.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.16.0\n[1.16.0-rc.1/0.39.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.16.0-rc.1\n[1.15.1/0.38.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.1\n[1.15.0/0.38.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.0\n[1.15.0-rc.2/0.38.0-rc.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.0-rc.2\n[1.15.0-rc.1/0.38.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.0-rc.1\n[1.14.0/0.37.0/0.0.4]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.14.0\n[1.13.0/0.36.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.13.0\n[1.12.0/0.35.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.12.0\n[1.11.2/0.34.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.11.2\n[1.11.1/0.33.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.11.1\n[1.11.0/0.32.3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.11.0\n[0.32.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/sdk/metric/v0.32.2\n[0.32.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/sdk/metric/v0.32.1\n[0.32.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/sdk/metric/v0.32.0\n[1.10.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.10.0\n[1.9.0/0.0.3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.9.0\n[1.8.0/0.31.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.8.0\n[1.7.0/0.30.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.7.0\n[0.29.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/metric/v0.29.0\n[1.6.3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.6.3\n[1.6.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.6.2\n[1.6.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.6.1\n[1.6.0/0.28.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.6.0\n[1.5.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.5.0\n[1.4.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.4.1\n[1.4.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.4.0\n[1.3.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.3.0\n[1.2.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.2.0\n[1.1.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.1.0\n[1.0.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.1\n[Metrics 0.24.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/metric/v0.24.0\n[1.0.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.0\n[1.0.0-RC3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.0-RC3\n[1.0.0-RC2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.0-RC2\n[Experimental Metrics v0.22.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/metric/v0.22.0\n[1.0.0-RC1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.0-RC1\n[0.20.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.20.0\n[0.19.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.19.0\n[0.18.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.18.0\n[0.17.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.17.0\n[0.16.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.16.0\n[0.15.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.15.0\n[0.14.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.14.0\n[0.13.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.13.0\n[0.12.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.12.0\n[0.11.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.11.0\n[0.10.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.10.0\n[0.9.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.9.0\n[0.8.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.8.0\n[0.7.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.7.0\n[0.6.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.6.0\n[0.5.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.5.0\n[0.4.3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.4.3\n[0.4.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.4.2\n[0.4.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.4.1\n[0.4.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.4.0\n[0.3.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.3.0\n[0.2.3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.2.3\n[0.2.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.2.2\n[0.2.1.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.2.1.1\n[0.2.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.2.1\n[0.2.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.2.0\n[0.1.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.1.2\n[0.1.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.1.1\n[0.1.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.1.0\n\n<!-- Released section ended -->\n\n[Go 1.25]: https://go.dev/doc/go1.25\n[Go 1.24]: https://go.dev/doc/go1.24\n[Go 1.23]: https://go.dev/doc/go1.23\n[Go 1.22]: https://go.dev/doc/go1.22\n[Go 1.21]: https://go.dev/doc/go1.21\n[Go 1.20]: https://go.dev/doc/go1.20\n[Go 1.19]: https://go.dev/doc/go1.19\n[Go 1.18]: https://go.dev/doc/go1.18\n\n[metric API]:https://pkg.go.dev/go.opentelemetry.io/otel/metric\n[metric SDK]:https://pkg.go.dev/go.opentelemetry.io/otel/sdk/metric\n[trace API]:https://pkg.go.dev/go.opentelemetry.io/otel/trace\n\n[GO-2024-2687]: https://pkg.go.dev/vuln/GO-2024-2687\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/CODEOWNERS",
    "content": "#####################################################\n#\n# List of approvers for this repository\n#\n#####################################################\n#\n# Learn about membership in OpenTelemetry community:\n#  https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md\n#\n#\n# Learn about CODEOWNERS file format:\n#  https://help.github.com/en/articles/about-code-owners\n#\n\n* @MrAlias @XSAM @dashpole @pellared @dmathieu @flc1125\n\nCODEOWNERS @MrAlias @pellared @dashpole @XSAM @dmathieu\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/CONTRIBUTING.md",
    "content": "# Contributing to opentelemetry-go\n\nThe Go special interest group (SIG) meets regularly. See the\nOpenTelemetry\n[community](https://github.com/open-telemetry/community#golang-sdk)\nrepo for information on this and other language SIGs.\n\nSee the [public meeting\nnotes](https://docs.google.com/document/d/1E5e7Ld0NuU1iVvf-42tOBpu2VBBLYnh73GJuITGJTTU/edit)\nfor a summary description of past meetings. To request edit access,\njoin the meeting or get in touch on\n[Slack](https://cloud-native.slack.com/archives/C01NPAXACKT).\n\n## Development\n\nYou can view and edit the source code by cloning this repository:\n\n```sh\ngit clone https://github.com/open-telemetry/opentelemetry-go.git\n```\n\nRun `make test` to run the tests instead of `go test`.\n\nThere are some generated files checked into the repo. To make sure\nthat the generated files are up-to-date, run `make` (or `make\nprecommit` - the `precommit` target is the default).\n\nThe `precommit` target also fixes the formatting of the code and\nchecks the status of the go module files.\n\nAdditionally, there is a `codespell` target that checks for common\ntypos in the code. It is not run by default, but you can run it\nmanually with `make codespell`. It will set up a virtual environment\nin `venv` and install `codespell` there.\n\nIf after running `make precommit` the output of `git status` contains\n`nothing to commit, working tree clean` then it means that everything\nis up-to-date and properly formatted.\n\n## Pull Requests\n\n### How to Send Pull Requests\n\nEveryone is welcome to contribute code to `opentelemetry-go` via\nGitHub pull requests (PRs).\n\nTo create a new PR, fork the project in GitHub and clone the upstream\nrepo:\n\n```sh\ngo get -d go.opentelemetry.io/otel\n```\n\n(This may print some warning about \"build constraints exclude all Go\nfiles\", just ignore it.)\n\nThis will put the project in `${GOPATH}/src/go.opentelemetry.io/otel`.\nAlternatively, you can use `git` directly with:\n\n```sh\ngit clone https://github.com/open-telemetry/opentelemetry-go\n```\n\n(Note that `git clone` is *not* using the `go.opentelemetry.io/otel` name -\nthat name is a kind of a redirector to GitHub that `go get` can\nunderstand, but `git` does not.)\n\nThis will add the project as `opentelemetry-go` within the current directory.\n\nEnter the newly created directory and add your fork as a new remote:\n\n```sh\ngit remote add <YOUR_FORK> git@github.com:<YOUR_GITHUB_USERNAME>/opentelemetry-go\n```\n\nCheck out a new branch, make modifications, run linters and tests, update\n`CHANGELOG.md`, and push the branch to your fork:\n\n```sh\ngit checkout -b <YOUR_BRANCH_NAME>\n# edit files\n# update changelog\nmake precommit\ngit add -p\ngit commit\ngit push <YOUR_FORK> <YOUR_BRANCH_NAME>\n```\n\nOpen a pull request against the main `opentelemetry-go` repo. Be sure to add the pull\nrequest ID to the entry you added to `CHANGELOG.md`.\n\nAvoid rebasing and force-pushing to your branch to facilitate reviewing the pull request.\nRewriting Git history makes it difficult to keep track of iterations during code review.\nAll pull requests are squashed to a single commit upon merge to `main`.\n\n### How to Receive Comments\n\n* If the PR is not ready for review, please put `[WIP]` in the title,\n  tag it as `work-in-progress`, or mark it as\n  [`draft`](https://github.blog/2019-02-14-introducing-draft-pull-requests/).\n* Make sure CLA is signed and CI is clear.\n\n### How to Get PRs Merged\n\nA PR is considered **ready to merge** when:\n\n* It has received two qualified approvals[^1].\n\n  This is not enforced through automation, but needs to be validated by the\n  maintainer merging.\n  * At least one of the qualified approvals needs to be from an\n    [Approver]/[Maintainer] affiliated with a different company than the author\n    of the PR.\n  * PRs introducing changes that have already been discussed and consensus\n    reached only need one qualified approval. The discussion and resolution\n    needs to be linked to the PR.\n  * Trivial changes[^2] only need one qualified approval.\n\n* All feedback has been addressed.\n  * All PR comments and suggestions are resolved.\n  * All GitHub Pull Request reviews with a status of \"Request changes\" have\n    been addressed. Another review by the objecting reviewer with a different\n    status can be submitted to clear the original review, or the review can be\n    dismissed by a [Maintainer] when the issues from the original review have\n    been addressed.\n  * Any comments or reviews that cannot be resolved between the PR author and\n    reviewers can be submitted to the community [Approver]s and [Maintainer]s\n    during the weekly SIG meeting. If consensus is reached among the\n    [Approver]s and [Maintainer]s during the SIG meeting the objections to the\n    PR may be dismissed or resolved or the PR closed by a [Maintainer].\n  * Any substantive changes to the PR require existing Approval reviews be\n    cleared unless the approver explicitly states that their approval persists\n    across changes. This includes changes resulting from other feedback.\n    [Approver]s and [Maintainer]s can help in clearing reviews and they should\n    be consulted if there are any questions.\n\n* The PR branch is up to date with the base branch it is merging into.\n  * To ensure this does not block the PR, it should be configured to allow\n    maintainers to update it.\n\n* It has been open for review for at least one working day. This gives people\n  reasonable time to review.\n  * Trivial changes[^2] do not have to wait for one day and may be merged with\n    a single [Maintainer]'s approval.\n\n* All required GitHub workflows have succeeded.\n* Urgent fix can take exception as long as it has been actively communicated\n  among [Maintainer]s.\n\nAny [Maintainer] can merge the PR once the above criteria have been met.\n\n[^1]: A qualified approval is a GitHub Pull Request review with \"Approve\"\n  status from an OpenTelemetry Go [Approver] or [Maintainer].\n[^2]: Trivial changes include: typo corrections, cosmetic non-substantive\n  changes, documentation corrections or updates, dependency updates, etc.\n\n## Design Choices\n\nAs with other OpenTelemetry clients, opentelemetry-go follows the\n[OpenTelemetry Specification](https://opentelemetry.io/docs/specs/otel).\n\nIt's especially valuable to read through the [library\nguidelines](https://opentelemetry.io/docs/specs/otel/library-guidelines).\n\n### Focus on Capabilities, Not Structure Compliance\n\nOpenTelemetry is an evolving specification, one where the desires and\nuse cases are clear, but the methods to satisfy those use cases are\nnot.\n\nAs such, Contributions should provide functionality and behavior that\nconforms to the specification, but the interface and structure are\nflexible.\n\nIt is preferable to have contributions follow the idioms of the\nlanguage rather than conform to specific API names or argument\npatterns in the spec.\n\nFor a deeper discussion, see\n[this](https://github.com/open-telemetry/opentelemetry-specification/issues/165).\n\n## Tests\n\nEach functionality should be covered by tests.\n\nPerformance-critical functionality should also be covered by benchmarks.\n\n- Pull requests adding a performance-critical functionality\nshould have `go test -bench` output in their description.\n- Pull requests changing a performance-critical functionality\nshould have [`benchstat`](https://pkg.go.dev/golang.org/x/perf/cmd/benchstat)\noutput in their description.\n\n## Dependencies\n\nThis project uses [Go Modules] for dependency management. All modules will use\n`go.mod` to explicitly list all direct and indirect dependencies, ensuring a\nclear dependency graph. The `go.sum` file for each module will be committed to\nthe repository and used to verify the integrity of downloaded modules,\npreventing malicious tampering.\n\nThis project uses automated dependency update tools (i.e. dependabot,\nrenovatebot) to manage updates to dependencies. This ensures that dependencies\nare kept up-to-date with the latest security patches and features and are\nreviewed before being merged. If you would like to propose a change to a\ndependency it should be done through a pull request that updates the `go.mod`\nfile and includes a description of the change.\n\nSee the [versioning and compatibility](./VERSIONING.md) policy for more details\nabout dependency compatibility.\n\n[Go Modules]: https://pkg.go.dev/cmd/go#hdr-Modules__module_versions__and_more\n\n### Environment Dependencies\n\nThis project does not partition dependencies based on the environment (i.e.\n`development`, `staging`, `production`).\n\nOnly the dependencies explicitly included in the released modules have been\ntested and verified to work with the released code. No other guarantee is made\nabout the compatibility of other dependencies.\n\n## Documentation\n\nEach (non-internal, non-test) package must be documented using\n[Go Doc Comments](https://go.dev/doc/comment),\npreferably in a `doc.go` file.\n\nPrefer using [Examples](https://pkg.go.dev/testing#hdr-Examples)\ninstead of putting code snippets in Go doc comments.\nIn some cases, you can even create [Testable Examples](https://go.dev/blog/examples).\n\nYou can install and run a \"local Go Doc site\" in the following way:\n\n  ```sh\n  go install golang.org/x/pkgsite/cmd/pkgsite@latest\n  pkgsite\n  ```\n\n[`go.opentelemetry.io/otel/metric`](https://pkg.go.dev/go.opentelemetry.io/otel/metric)\nis an example of a very well-documented package.\n\n### README files\n\nEach (non-internal, non-test, non-documentation) package must contain a\n`README.md` file containing at least a title, and a `pkg.go.dev` badge.\n\nThe README should not be a repetition of Go doc comments.\n\nYou can verify the presence of all README files with the `make verify-readmes`\ncommand.\n\n## Style Guide\n\nOne of the primary goals of this project is that it is actually used by\ndevelopers. With this goal in mind the project strives to build\nuser-friendly and idiomatic Go code adhering to the Go community's best\npractices.\n\nFor a non-comprehensive but foundational overview of these best practices\nthe [Effective Go](https://golang.org/doc/effective_go.html) documentation\nis an excellent starting place.\n\nWe also recommend following the\n[Go Code Review Comments](https://go.dev/wiki/CodeReviewComments)\nthat collects common comments made during reviews of Go code.\n\nAs a convenience for developers building this project the `make precommit`\nwill format, lint, validate, and in some cases fix the changes you plan to\nsubmit. This check will need to pass for your changes to be able to be\nmerged.\n\nIn addition to idiomatic Go, the project has adopted certain standards for\nimplementations of common patterns. These standards should be followed as a\ndefault, and if they are not followed documentation needs to be included as\nto the reasons why.\n\n### Configuration\n\nWhen creating an instantiation function for a complex `type T struct`, it is\nuseful to allow variable number of options to be applied. However, the strong\ntype system of Go restricts the function design options. There are a few ways\nto solve this problem, but we have landed on the following design.\n\n#### `config`\n\nConfiguration should be held in a `struct` named `config`, or prefixed with\nspecific type name this Configuration applies to if there are multiple\n`config` in the package. This type must contain configuration options.\n\n```go\n// config contains configuration options for a thing.\ntype config struct {\n\t// options ...\n}\n```\n\nIn general the `config` type will not need to be used externally to the\npackage and should be unexported. If, however, it is expected that the user\nwill likely want to build custom options for the configuration, the `config`\nshould be exported. Please, include in the documentation for the `config`\nhow the user can extend the configuration.\n\nIt is important that internal `config` are not shared across package boundaries.\nMeaning a `config` from one package should not be directly used by another. The\none exception is the API packages.  The configs from the base API, eg.\n`go.opentelemetry.io/otel/trace.TracerConfig` and\n`go.opentelemetry.io/otel/metric.InstrumentConfig`, are intended to be consumed\nby the SDK therefore it is expected that these are exported.\n\nWhen a config is exported we want to maintain forward and backward\ncompatibility, to achieve this no fields should be exported but should\ninstead be accessed by methods.\n\nOptionally, it is common to include a `newConfig` function (with the same\nnaming scheme). This function wraps any defaults setting and looping over\nall options to create a configured `config`.\n\n```go\n// newConfig returns an appropriately configured config.\nfunc newConfig(options ...Option) config {\n\t// Set default values for config.\n\tconfig := config{/* […] */}\n\tfor _, option := range options {\n\t\tconfig = option.apply(config)\n\t}\n\t// Perform any validation here.\n\treturn config\n}\n```\n\nIf validation of the `config` options is also performed this can return an\nerror as well that is expected to be handled by the instantiation function\nor propagated to the user.\n\nGiven the design goal of not having the user need to work with the `config`,\nthe `newConfig` function should also be unexported.\n\n#### `Option`\n\nTo set the value of the options a `config` contains, a corresponding\n`Option` interface type should be used.\n\n```go\ntype Option interface {\n\tapply(config) config\n}\n```\n\nHaving `apply` unexported makes sure that it will not be used externally.\nMoreover, the interface becomes sealed so the user cannot easily implement\nthe interface on its own.\n\nThe `apply` method should return a modified version of the passed config.\nThis approach, instead of passing a pointer, is used to prevent the config from being allocated to the heap.\n\nThe name of the interface should be prefixed in the same way the\ncorresponding `config` is (if at all).\n\n#### Options\n\nAll user configurable options for a `config` must have a related unexported\nimplementation of the `Option` interface and an exported configuration\nfunction that wraps this implementation.\n\nThe wrapping function name should be prefixed with `With*` (or in the\nspecial case of a boolean options `Without*`) and should have the following\nfunction signature.\n\n```go\nfunc With*(…) Option { … }\n```\n\n##### `bool` Options\n\n```go\ntype defaultFalseOption bool\n\nfunc (o defaultFalseOption) apply(c config) config {\n\tc.Bool = bool(o)\n    return c\n}\n\n// WithOption sets a T to have an option included.\nfunc WithOption() Option {\n\treturn defaultFalseOption(true)\n}\n```\n\n```go\ntype defaultTrueOption bool\n\nfunc (o defaultTrueOption) apply(c config) config {\n\tc.Bool = bool(o)\n    return c\n}\n\n// WithoutOption sets a T to have Bool option excluded.\nfunc WithoutOption() Option {\n\treturn defaultTrueOption(false)\n}\n```\n\n##### Declared Type Options\n\n```go\ntype myTypeOption struct {\n\tMyType MyType\n}\n\nfunc (o myTypeOption) apply(c config) config {\n\tc.MyType = o.MyType\n    return c\n}\n\n// WithMyType sets T to have include MyType.\nfunc WithMyType(t MyType) Option {\n\treturn myTypeOption{t}\n}\n```\n\n##### Functional Options\n\n```go\ntype optionFunc func(config) config\n\nfunc (fn optionFunc) apply(c config) config {\n\treturn fn(c)\n}\n\n// WithMyType sets t as MyType.\nfunc WithMyType(t MyType) Option {\n\treturn optionFunc(func(c config) config {\n\t\tc.MyType = t\n        return c\n\t})\n}\n```\n\n#### Instantiation\n\nUsing this configuration pattern to configure instantiation with a `NewT`\nfunction.\n\n```go\nfunc NewT(options ...Option) T {…}\n```\n\nAny required parameters can be declared before the variadic `options`.\n\n#### Dealing with Overlap\n\nSometimes there are multiple complex `struct` that share common\nconfiguration and also have distinct configuration. To avoid repeated\nportions of `config`s, a common `config` can be used with the union of\noptions being handled with the `Option` interface.\n\nFor example.\n\n```go\n// config holds options for all animals.\ntype config struct {\n\tWeight      float64\n\tColor       string\n\tMaxAltitude float64\n}\n\n// DogOption apply Dog specific options.\ntype DogOption interface {\n\tapplyDog(config) config\n}\n\n// BirdOption apply Bird specific options.\ntype BirdOption interface {\n\tapplyBird(config) config\n}\n\n// Option apply options for all animals.\ntype Option interface {\n\tBirdOption\n\tDogOption\n}\n\ntype weightOption float64\n\nfunc (o weightOption) applyDog(c config) config {\n\tc.Weight = float64(o)\n\treturn c\n}\n\nfunc (o weightOption) applyBird(c config) config {\n\tc.Weight = float64(o)\n\treturn c\n}\n\nfunc WithWeight(w float64) Option { return weightOption(w) }\n\ntype furColorOption string\n\nfunc (o furColorOption) applyDog(c config) config {\n\tc.Color = string(o)\n\treturn c\n}\n\nfunc WithFurColor(c string) DogOption { return furColorOption(c) }\n\ntype maxAltitudeOption float64\n\nfunc (o maxAltitudeOption) applyBird(c config) config {\n\tc.MaxAltitude = float64(o)\n\treturn c\n}\n\nfunc WithMaxAltitude(a float64) BirdOption { return maxAltitudeOption(a) }\n\nfunc NewDog(name string, o ...DogOption) Dog    {…}\nfunc NewBird(name string, o ...BirdOption) Bird {…}\n```\n\n### Interfaces\n\nTo allow other developers to better comprehend the code, it is important\nto ensure it is sufficiently documented. One simple measure that contributes\nto this aim is self-documenting by naming method parameters. Therefore,\nwhere appropriate, methods of every exported interface type should have\ntheir parameters appropriately named.\n\n#### Interface Stability\n\nAll exported stable interfaces that include the following warning in their\ndocumentation are allowed to be extended with additional methods.\n\n> Warning: methods may be added to this interface in minor releases.\n\nThese interfaces are defined by the OpenTelemetry specification and will be\nupdated as the specification evolves.\n\nOtherwise, stable interfaces MUST NOT be modified.\n\n#### How to Change Specification Interfaces\n\nWhen an API change must be made, we will update the SDK with the new method one\nrelease before the API change. This will allow the SDK one version before the\nAPI change to work seamlessly with the new API.\n\nIf an incompatible version of the SDK is used with the new API the application\nwill fail to compile.\n\n#### How Not to Change Specification Interfaces\n\nWe have explored using a v2 of the API to change interfaces and found that there\nwas no way to introduce a v2 and have it work seamlessly with the v1 of the API.\nProblems happened with libraries that upgraded to v2 when an application did not,\nand would not produce any telemetry.\n\nMore detail of the approaches considered and their limitations can be found in\nthe [Use a V2 API to evolve interfaces](https://github.com/open-telemetry/opentelemetry-go/issues/3920)\nissue.\n\n#### How to Change Other Interfaces\n\nIf new functionality is needed for an interface that cannot be changed it MUST\nbe added by including an additional interface. That added interface can be a\nsimple interface for the specific functionality that you want to add or it can\nbe a super-set of the original interface. For example, if you wanted to a\n`Close` method to the `Exporter` interface:\n\n```go\ntype Exporter interface {\n\tExport()\n}\n```\n\nA new interface, `Closer`, can be added:\n\n```go\ntype Closer interface {\n\tClose()\n}\n```\n\nCode that is passed the `Exporter` interface can now check to see if the passed\nvalue also satisfies the new interface. E.g.\n\n```go\nfunc caller(e Exporter) {\n\t/* ... */\n\tif c, ok := e.(Closer); ok {\n\t\tc.Close()\n\t}\n\t/* ... */\n}\n```\n\nAlternatively, a new type that is the super-set of an `Exporter` can be created.\n\n```go\ntype ClosingExporter struct {\n\tExporter\n\tClose()\n}\n```\n\nThis new type can be used similar to the simple interface above in that a\npassed `Exporter` type can be asserted to satisfy the `ClosingExporter` type\nand the `Close` method called.\n\nThis super-set approach can be useful if there is explicit behavior that needs\nto be coupled with the original type and passed as a unified type to a new\nfunction, but, because of this coupling, it also limits the applicability of\nthe added functionality. If there exist other interfaces where this\nfunctionality should be added, each one will need their own super-set\ninterfaces and will duplicate the pattern. For this reason, the simple targeted\ninterface that defines the specific functionality should be preferred.\n\nSee also:\n[Keeping Your Modules Compatible: Working with interfaces](https://go.dev/blog/module-compatibility#working-with-interfaces).\n\n### Testing\n\nWe allow using [`testify`](https://github.com/stretchr/testify) even though\nit is seen as non-idiomatic according to\nthe [Go Test Comments](https://go.dev/wiki/TestComments#assert-libraries) page.\n\nThe tests should never leak goroutines.\n\nUse the term `ConcurrentSafe` in the test name when it aims to verify the\nabsence of race conditions. The top-level tests with this term will be run\nmany times in the `test-concurrent-safe` CI job to increase the chance of\ncatching concurrency issues. This does not apply to subtests when this term\nis not in their root name.\n\n### Internal packages\n\nThe use of internal packages should be scoped to a single module. A sub-module\nshould never import from a parent internal package. This creates a coupling\nbetween the two modules where a user can upgrade the parent without the child,\nand if the internal package API has changed, it will fail to upgrade[^3].\n\nThere are two known exceptions to this rule:\n\n- `go.opentelemetry.io/otel/internal/global`\n  - This package manages global state for all of opentelemetry-go. It needs to\n  be a single package in order to ensure the uniqueness of the global state.\n- `go.opentelemetry.io/otel/internal/baggage`\n  - This package provides values in a `context.Context` that need to be\n  recognized by `go.opentelemetry.io/otel/baggage` and\n  `go.opentelemetry.io/otel/bridge/opentracing` but remain private.\n\nIf you have duplicate code in multiple modules, make that code into a Go\ntemplate stored in `go.opentelemetry.io/otel/internal/shared` and use [gotmpl]\nto render the templates in the desired locations. See [#4404] for an example of\nthis.\n\n[^3]: https://github.com/open-telemetry/opentelemetry-go/issues/3548\n\n### Ignoring context cancellation\n\nOpenTelemetry API implementations need to ignore the cancellation of the context that is\npassed when recording a value (e.g. starting a span, recording a measurement, emitting a log).\nRecording methods should not return an error describing the cancellation state of the context\nwhen they complete, nor should they abort any work.\n\nThis rule may not apply if the OpenTelemetry specification defines a timeout mechanism for\nthe method. In that case the context cancellation can be used for the timeout with the\nrestriction that this behavior is documented for the method. Otherwise, timeouts\nare expected to be handled by the user calling the API, not the implementation.\n\nStoppage of the telemetry pipeline is handled by calling the appropriate `Shutdown` method\nof a provider. It is assumed the context passed from a user is not used for this purpose.\n\nOutside of the direct recording of telemetry from the API (e.g. exporting telemetry,\nforce flushing telemetry, shutting down a signal provider) the context cancellation\nshould be honored. This means all work done on behalf of the user provided context\nshould be canceled.\n\n### Observability\n\nOpenTelemetry Go SDK components should be instrumented to enable users observability for the health and performance of the telemetry pipeline itself.\nThis allows operators to understand how well their observability infrastructure is functioning and to identify potential issues before they impact their applications.\n\nThis section outlines the best practices for building instrumentation in OpenTelemetry Go SDK components.\n\n#### Environment Variable Activation\n\nObservability features are currently experimental.\nThey should be disabled by default and activated through the `OTEL_GO_X_OBSERVABILITY` environment variable.\nThis follows the established experimental feature pattern used throughout the SDK.\n\nComponents should check for this environment variable using a consistent pattern:\n\n```go\nimport \"go.opentelemetry.io/otel/*/internal/x\"\n\nif x.Observability.Enabled() {\n    // Initialize observability metrics\n}\n```\n\n**References**:\n\n- [stdouttrace exporter](./exporters/stdout/stdouttrace/internal/x/x.go)\n- [sdk](./sdk/internal/x/x.go)\n\n#### Encapsulation\n\nInstrumentation should be encapsulated within a dedicated `struct` (e.g. `instrumentation`).\nIt should not be mixed into the instrumented component.\n\nPrefer this:\n\n```go\ntype SDKComponent struct {\n    inst *instrumentation\n}\n\ntype instrumentation struct {\n\tinflight otelconv.SDKComponentInflight\n\texported otelconv.SDKComponentExported\n}\n```\n\nTo this:\n\n```go\n// ❌ Avoid this pattern.\ntype SDKComponent struct {\n\t/* other SDKComponent fields... */\n\n\tinflight otelconv.SDKComponentInflight\n\texported otelconv.SDKComponentExported\n}\n```\n\nThe instrumentation code should not bloat the code being instrumented.\nLikely, this means its own file, or its own package if it is complex or reused.\n\n#### Initialization\n\nInstrumentation setup should be explicit, side-effect free, and local to the relevant component.\nAvoid relying on global or implicit [side effects][side-effect] for initialization.\n\nEncapsulate setup in constructor functions, ensuring clear ownership and scope:\n\n```go\nimport (\n\t\"errors\"\n\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.39.0\"\n\t\"go.opentelemetry.io/otel/semconv/v1.39.0/otelconv\"\n)\n\ntype SDKComponent struct {\n    inst *instrumentation\n}\n\nfunc NewSDKComponent(config Config) (*SDKComponent, error) {\n    inst, err := newInstrumentation()\n    if err != nil {\n        return nil, err\n    }\n    return &SDKComponent{inst: inst}, nil\n}\n\ntype instrumentation struct {\n    inflight otelconv.SDKComponentInflight\n    exported otelconv.SDKComponentExported\n}\n\nfunc newInstrumentation() (*instrumentation, error) {\n    if !x.Observability.Enabled() {\n        return nil, nil\n    }\n \n    meter := otel.GetMeterProvider().Meter(\n        \"<component-package-name>\",\n        metric.WithInstrumentationVersion(sdk.Version()),\n        metric.WithSchemaURL(semconv.SchemaURL),\n    )\n\n\tinst := &instrumentation{}\n\n\tvar err, e error\n    inst.inflight, e = otelconv.NewSDKComponentInflight(meter)\n\terr = errors.Join(err, e)\n\n    inst.exported, e = otelconv.NewSDKComponentExported(meter)\n\terr = errors.Join(err, e)\n\n    return inst, err\n}\n```\n\n```go\n// ❌ Avoid this pattern.\nfunc (c *Component) initObservability() {\n\t// Initialize observability metrics\n\tif !x.Observability.Enabled() {\n\t\treturn\n\t}\n\n\t// Initialize observability metrics\n\tc.inst = &instrumentation{/* ... */}\n}\n```\n\n[side-effect]: https://en.wikipedia.org/wiki/Side_effect_(computer_science)\n\n#### Performance\n\nWhen observability is disabled there should be little to no overhead.\n\n```go\nfunc (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error {\n\tif e.inst != nil {\n\t\tattrs := expensiveOperation()\n\t\te.inst.recordSpanInflight(ctx, int64(len(spans)), attrs...)\n\t}\n    // Export spans...\n}\n```\n\n```go\n// ❌ Avoid this pattern.\nfunc (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error {\n\tattrs := expensiveOperation()\n\te.inst.recordSpanInflight(ctx, int64(len(spans)), attrs...)\n    // Export spans...\n}\n\nfunc (i *instrumentation) recordSpanInflight(ctx context.Context, count int64, attrs ...attribute.KeyValue) {\n\tif i == nil || i.inflight == nil {\n\t\treturn\n\t}\n\ti.inflight.Add(ctx, count, metric.WithAttributes(attrs...))\n}\n```\n\nWhen observability is enabled, the instrumentation code paths should be optimized to reduce allocation and computation overhead.\n\n##### Attribute and Option Allocation Management\n\nPool attribute slices and options with [`sync.Pool`] to minimize allocations in measurement calls with dynamic attributes.\n\n```go\nvar (\n\tattrPool = sync.Pool{\n        New: func() any {\n\t\t    // Pre-allocate common capacity\n    \t\tknownCap := 8 // Adjust based on expected usage\n            s := make([]attribute.KeyValue, 0, knownCap)\n    \t\t// Return a pointer to avoid extra allocation on Put().\n            return &s\n        },\n    }\n\n\taddOptPool = &sync.Pool{\n\t\tNew: func() any {\n\t\t\tconst n = 1 // WithAttributeSet\n\t\t\to := make([]metric.AddOption, 0, n)\n    \t\t// Return a pointer to avoid extra allocation on Put().\n\t\t\treturn &o\n\t\t},\n\t}\n)\n\nfunc (i *instrumentation) record(ctx context.Context, value int64, baseAttrs ...attribute.KeyValue) {\n    attrs := attrPool.Get().(*[]attribute.KeyValue)\n    defer func() {\n        *attrs = (*attrs)[:0] // Reset.\n        attrPool.Put(attrs)\n    }()\n\n    *attrs = append(*attrs, baseAttrs...)\n    // Add any dynamic attributes.\n    *attrs = append(*attrs, semconv.OTelComponentName(\"exporter-1\"))\n\n\taddOpt := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*addOpt = (*addOpt)[:0]\n\t\taddOptPool.Put(addOpt)\n\t}()\n\n\tset := attribute.NewSet(*attrs...)\n\t*addOpt = append(*addOpt, metric.WithAttributeSet(set))\n\n    i.counter.Add(ctx, value, *addOpt...)\n}\n```\n\nPools are most effective when there are many pooled objects of the same sufficiently large size, and the objects are repeatedly used.\nThis amortizes the cost of allocation and synchronization.\nIdeally, the pools should be scoped to be used as widely as possible within the component to maximize this efficiency while still ensuring correctness.\n\n[`sync.Pool`]: https://pkg.go.dev/sync#Pool\n\n##### Cache common attribute sets for repeated measurements\n\nIf a static set of attributes are used for measurements and they are known at compile time, pre-compute and cache these attributes.\n\n```go\ntype spanLiveSetKey struct {\n\tsampled bool\n}\n\nvar spanLiveSetCache = map[spanLiveSetKey]attribute.Set{\n\t{true}: attribute.NewSet(\n\t\totelconv.SDKSpanLive{}.AttrSpanSamplingResult(\n\t\t\totelconv.SpanSamplingResultRecordAndSample,\n\t\t),\n\t),\n\t{false}: attribute.NewSet(\n\t\totelconv.SDKSpanLive{}.AttrSpanSamplingResult(\n\t\t\totelconv.SpanSamplingResultRecordOnly,\n\t\t),\n\t),\n}\n\nfunc spanLiveSet(sampled bool) attribute.Set {\n\tkey := spanLiveSetKey{sampled: sampled}\n\treturn spanLiveSetCache[key]\n}\n```\n\n##### Benchmarking\n\nAlways provide benchmarks when introducing or refactoring instrumentation.\nDemonstrate the impact (allocs/op, B/op, ns/op) in enabled/disabled scenarios:\n\n```go\nfunc BenchmarkExportSpans(b *testing.B) {\n    scenarios := []struct {\n        name           string\n        obsEnabled bool\n    }{\n        {\"ObsDisabled\", false},\n        {\"ObsEnabled\", true},\n    }\n \n    for _, scenario := range scenarios {\n        b.Run(scenario.name, func(b *testing.B) {\n            b.Setenv(\n\t\t\t\t\"OTEL_GO_X_OBSERVABILITY\",\n\t\t\t\tstrconv.FormatBool(scenario.obsEnabled),\n\t\t\t)\n\n            exporter := NewExporter()\n            spans := generateTestSpans(100)\n\n            b.ResetTimer()\n            b.ReportAllocs()\n\n            for i := 0; i < b.N; i++ {\n                _ = exporter.ExportSpans(context.Background(), spans)\n            }\n        })\n    }\n}\n```\n\n#### Error Handling and Robustness\n\nErrors should be reported back to the caller if possible, and partial failures should be handled as gracefully as possible.\n\n```go\nfunc newInstrumentation() (*instrumentation, error) {\n    if !x.Observability.Enabled() {\n        return nil, nil\n    }\n \n    m := otel.GetMeterProvider().Meter(/* initialize meter */)\n    counter, err := otelconv.NewSDKComponentCounter(m)\n\t// Use the partially initialized counter if available.\n\ti := &instrumentation{counter: counter}\n\t// Return any error to the caller.\n    return i, err\n}\n```\n\n```go\n// ❌ Avoid this pattern.\nfunc newInstrumentation() *instrumentation {\n    if !x.Observability.Enabled() {\n        return nil, nil\n    }\n \n    m := otel.GetMeterProvider().Meter(/* initialize meter */)\n    counter, err := otelconv.NewSDKComponentCounter(m)\n\tif err != nil {\n\t\t// ❌ Do not dump the error to the OTel Handler. Return it to the\n\t\t// caller.\n\t\totel.Handle(err)\n\t\t// ❌ Do not return nil if we can still use the partially initialized\n\t\t// counter.\n\t\treturn nil\n\t}\n    return &instrumentation{counter: counter}\n}\n```\n\nIf the instrumented component cannot report the error to the user, let it report the error to `otel.Handle`.\n\n#### Context Propagation\n\nEnsure observability measurements receive the correct context, especially for trace exemplars and distributed context:\n\n```go\nfunc (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error {\n    // Use the provided context for observability measurements\n    e.inst.recordSpanExportStarted(ctx, len(spans))\n \n    err := e.doExport(ctx, spans)\n\n    if err != nil {\n        e.inst.recordSpanExportFailed(ctx, len(spans), err)\n    } else {\n        e.inst.recordSpanExportSucceeded(ctx, len(spans))\n    }\n \n    return err\n}\n```\n\n```go\n// ❌ Avoid this pattern.\nfunc (e *Exporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error {\n    // ❌ Do not break the context propagation.\n    e.inst.recordSpanExportStarted(context.Background(), len(spans))\n \n    err := e.doExport(ctx, spans)\n\n\t/* ... */\n \n    return err\n}\n```\n\n#### Semantic Conventions Compliance\n\nAll observability metrics should follow the [OpenTelemetry Semantic Conventions for SDK metrics](https://github.com/open-telemetry/semantic-conventions/blob/1cf2476ae5e518225a766990a28a6d5602bd5a30/docs/otel/sdk-metrics.md).\n\nUse the metric semantic conventions convenience package [otelconv](./semconv/v1.39.0/otelconv/metric.go).\n\n##### Component Identification\n\nComponent names and types should follow [semantic convention](https://github.com/open-telemetry/semantic-conventions/blob/1cf2476ae5e518225a766990a28a6d5602bd5a30/docs/registry/attributes/otel.md#otel-component-attributes).\n\nIf a component is not a well-known type specified in the semantic conventions, use the package path scope type as a stable identifier.\n\n```go\ncomponentType := \"go.opentelemetry.io/otel/sdk/trace.Span\"\n```\n\n```go\n// ❌ Do not do this.\ncomponentType := \"trace-span\"\n```\n\nThe component name should be a stable unique identifier for the specific instance of the component.\n\nUse a global counter to ensure uniqueness if necessary.\n\n```go\n// Unique 0-based ID counter for component instances.\nvar componentIDCounter atomic.Int64\n\n// nextID returns the next unique ID for a component.\nfunc nextID() int64 {\n\treturn componentIDCounter.Add(1) - 1\n}\n\n// componentName returns a unique name for the component instance.\nfunc componentName() attribute.KeyValue {\n\tid := nextID()\n\tname := fmt.Sprintf(\"%s/%d\", componentType, id)\n\treturn semconv.OTelComponentName(name)\n}\n```\n\nThe component ID will need to be resettable for deterministic testing.\nIf tests are in a different package than the component being tested (i.e. a `<component package>_test` package name), use a generated `counter` internal package to manage the counter.\nSee [stdouttrace exporter example](./exporters/stdout/stdouttrace/internal/gen.go) for reference.\n\n#### Testing\n\nUse deterministic testing with isolated state:\n\n```go\nfunc TestObservability(t *testing.T) {\n\t// Restore state after test to ensure this does not affect other tests.\n    prev := otel.GetMeterProvider()\n    t.Cleanup(func() { otel.SetMeterProvider(prev) })\n\n    // Isolate the meter provider for deterministic testing\n    reader := metric.NewManualReader()\n    meterProvider := metric.NewMeterProvider(metric.WithReader(reader))\n    otel.SetMeterProvider(meterProvider)\n\n\t// Use t.Setenv to ensure environment variable is restored after test.\n    t.Setenv(\"OTEL_GO_X_OBSERVABILITY\", \"true\")\n\n\t// Reset component ID counter to ensure deterministic component names.\n\tcomponentIDCounter.Store(0)\n \n\t/* ... test code ... */\n}\n```\n\nTest order should not affect results.\nEnsure that any global state (e.g. component ID counters) is reset between tests.\n\n## Approvers and Maintainers\n\n### Maintainers\n\n- [Damien Mathieu](https://github.com/dmathieu), Elastic ([GPG](https://keys.openpgp.org/search?q=5A126B972A81A6CE443E5E1B408B8E44F0873832))\n- [David Ashpole](https://github.com/dashpole), Google ([GPG](https://keys.openpgp.org/search?q=C0D1BDDCAAEAE573673085F176327DA4D864DC70))\n- [Robert Pająk](https://github.com/pellared), Splunk ([GPG](https://keys.openpgp.org/search?q=CDAD3A60476A3DE599AA5092E5F7C35A4DBE90C2))\n- [Sam Xie](https://github.com/XSAM), Splunk ([GPG](https://keys.openpgp.org/search?q=AEA033782371ABB18EE39188B8044925D6FEEBEA))\n- [Tyler Yahn](https://github.com/MrAlias), Splunk ([GPG](https://keys.openpgp.org/search?q=0x46B0F3E1A8B1BA5A))\n\nFor more information about the maintainer role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#maintainer).\n\n### Approvers\n\n- [Flc](https://github.com/flc1125), Independent\n\nFor more information about the approver role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#approver).\n\n### Triagers\n\n- [Alex Kats](https://github.com/akats7), Capital One\n\nFor more information about the triager role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#triager).\n\n### Emeritus\n\n- [Aaron Clawson](https://github.com/MadVikingGod)\n- [Anthony Mirabella](https://github.com/Aneurysm9)\n- [Cheng-Zhen Yang](https://github.com/scorpionknifes)\n- [Chester Cheung](https://github.com/hanyuancheung)\n- [Evan Torrie](https://github.com/evantorrie)\n- [Gustavo Silva Paiva](https://github.com/paivagustavo)\n- [Josh MacDonald](https://github.com/jmacd)\n- [Liz Fong-Jones](https://github.com/lizthegrey)\n\nFor more information about the emeritus role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#emeritus-maintainerapprovertriager).\n\n### Become an Approver or a Maintainer\n\nSee the [community membership document in OpenTelemetry community\nrepo](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md).\n\n[Approver]: #approvers\n[Maintainer]: #maintainers\n[gotmpl]: https://pkg.go.dev/go.opentelemetry.io/build-tools/gotmpl\n[#4404]: https://github.com/open-telemetry/opentelemetry-go/pull/4404\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n--------------------------------------------------------------------------------\n\nCopyright 2009 The Go Authors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google LLC nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/Makefile",
    "content": "# Copyright The OpenTelemetry Authors\n# SPDX-License-Identifier: Apache-2.0\n\nTOOLS_MOD_DIR := ./internal/tools\n\nALL_DOCS := $(shell find . -name '*.md' -type f | sort)\nALL_GO_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \\; | sort)\nOTEL_GO_MOD_DIRS := $(filter-out $(TOOLS_MOD_DIR), $(ALL_GO_MOD_DIRS))\nALL_COVERAGE_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \\; | grep -E -v '^./example|^$(TOOLS_MOD_DIR)' | sort)\n\nGO = go\nTIMEOUT = 60\n\n# User to run as in docker images.\nDOCKER_USER=$(shell id -u):$(shell id -g)\nDEPENDENCIES_DOCKERFILE=./dependencies.Dockerfile\n\n.DEFAULT_GOAL := precommit\n\n.PHONY: precommit ci\nprecommit: generate toolchain-check license-check misspell go-mod-tidy golangci-lint-fix verify-readmes verify-mods test-default\nci: generate toolchain-check license-check lint vanity-import-check verify-readmes verify-mods build test-default check-clean-work-tree test-coverage\n\n# Tools\n\nTOOLS = $(CURDIR)/.tools\n\n$(TOOLS):\n\t@mkdir -p $@\n$(TOOLS)/%: $(TOOLS_MOD_DIR)/go.mod | $(TOOLS)\n\tcd $(TOOLS_MOD_DIR) && \\\n\t$(GO) build -o $@ $(PACKAGE)\n\nMULTIMOD = $(TOOLS)/multimod\n$(TOOLS)/multimod: PACKAGE=go.opentelemetry.io/build-tools/multimod\n\nCROSSLINK = $(TOOLS)/crosslink\n$(TOOLS)/crosslink: PACKAGE=go.opentelemetry.io/build-tools/crosslink\n\nSEMCONVKIT = $(TOOLS)/semconvkit\n$(TOOLS)/semconvkit: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/semconvkit\n\nVERIFYREADMES = $(TOOLS)/verifyreadmes\n$(TOOLS)/verifyreadmes: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/verifyreadmes\n\nGOLANGCI_LINT = $(TOOLS)/golangci-lint\n$(TOOLS)/golangci-lint: PACKAGE=github.com/golangci/golangci-lint/v2/cmd/golangci-lint\n\nMISSPELL = $(TOOLS)/misspell\n$(TOOLS)/misspell: PACKAGE=github.com/client9/misspell/cmd/misspell\n\nGOCOVMERGE = $(TOOLS)/gocovmerge\n$(TOOLS)/gocovmerge: PACKAGE=github.com/wadey/gocovmerge\n\nSTRINGER = $(TOOLS)/stringer\n$(TOOLS)/stringer: PACKAGE=golang.org/x/tools/cmd/stringer\n\nPORTO = $(TOOLS)/porto\n$(TOOLS)/porto: PACKAGE=github.com/jcchavezs/porto/cmd/porto\n\nGOTMPL = $(TOOLS)/gotmpl\n$(GOTMPL): PACKAGE=go.opentelemetry.io/build-tools/gotmpl\n\nGORELEASE = $(TOOLS)/gorelease\n$(GORELEASE): PACKAGE=golang.org/x/exp/cmd/gorelease\n\nGOVULNCHECK = $(TOOLS)/govulncheck\n$(TOOLS)/govulncheck: PACKAGE=golang.org/x/vuln/cmd/govulncheck\n\n.PHONY: tools\ntools: $(CROSSLINK) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(PORTO) $(VERIFYREADMES) $(MULTIMOD) $(SEMCONVKIT) $(GOTMPL) $(GORELEASE)\n\n# Virtualized python tools via docker\n\n# The directory where the virtual environment is created.\nVENVDIR := venv\n\n# The directory where the python tools are installed.\nPYTOOLS := $(VENVDIR)/bin\n\n# The pip executable in the virtual environment.\nPIP := $(PYTOOLS)/pip\n\n# The directory in the docker image where the current directory is mounted.\nWORKDIR := /workdir\n\n# The python image to use for the virtual environment.\nPYTHONIMAGE := $(shell awk '$$4==\"python\" {print $$2}' $(DEPENDENCIES_DOCKERFILE))\n\n# Run the python image with the current directory mounted.\nDOCKERPY := docker run --rm -u $(DOCKER_USER) -v \"$(CURDIR):$(WORKDIR)\" -w $(WORKDIR) $(PYTHONIMAGE)\n\n# Create a virtual environment for Python tools.\n$(PYTOOLS):\n# The `--upgrade` flag is needed to ensure that the virtual environment is\n# created with the latest pip version.\n\t@$(DOCKERPY) bash -c \"python3 -m venv $(VENVDIR) && $(PIP) install --upgrade --cache-dir=$(WORKDIR)/.cache/pip pip\"\n\n# Install python packages into the virtual environment.\n$(PYTOOLS)/%: $(PYTOOLS)\n\t@$(DOCKERPY) $(PIP) install --cache-dir=$(WORKDIR)/.cache/pip -r requirements.txt\n\nCODESPELL = $(PYTOOLS)/codespell\n$(CODESPELL): PACKAGE=codespell\n\n# Generate\n\n.PHONY: generate\ngenerate: go-generate vanity-import-fix\n\n.PHONY: go-generate\ngo-generate: $(OTEL_GO_MOD_DIRS:%=go-generate/%)\ngo-generate/%: DIR=$*\ngo-generate/%: $(STRINGER) $(GOTMPL)\n\t@echo \"$(GO) generate $(DIR)/...\" \\\n\t\t&& cd $(DIR) \\\n\t\t&& PATH=\"$(TOOLS):$${PATH}\" $(GO) generate ./...\n\n.PHONY: vanity-import-fix\nvanity-import-fix: $(PORTO)\n\t@$(PORTO) --include-internal -w .\n\n# Generate go.work file for local development.\n.PHONY: go-work\ngo-work: $(CROSSLINK)\n\t$(CROSSLINK) work --root=$(shell pwd) --go=1.22.7\n\n# Build\n\n.PHONY: build\n\nbuild: $(OTEL_GO_MOD_DIRS:%=build/%) $(OTEL_GO_MOD_DIRS:%=build-tests/%)\nbuild/%: DIR=$*\nbuild/%:\n\t@echo \"$(GO) build $(DIR)/...\" \\\n\t\t&& cd $(DIR) \\\n\t\t&& $(GO) build ./...\n\nbuild-tests/%: DIR=$*\nbuild-tests/%:\n\t@echo \"$(GO) build tests $(DIR)/...\" \\\n\t\t&& cd $(DIR) \\\n\t\t&& $(GO) list ./... \\\n\t\t| grep -v third_party \\\n\t\t| xargs $(GO) test -vet=off -run xxxxxMatchNothingxxxxx >/dev/null\n\n# Tests\n\nTEST_TARGETS := test-default test-bench test-short test-verbose test-race test-concurrent-safe test-fuzz\n.PHONY: $(TEST_TARGETS) test\ntest-default test-race: ARGS=-race\ntest-bench:   ARGS=-run=xxxxxMatchNothingxxxxx -test.benchtime=1ms -bench=.\ntest-short:   ARGS=-short\ntest-fuzz:    ARGS=-fuzztime=10s -fuzz\ntest-verbose: ARGS=-v -race\ntest-concurrent-safe: ARGS=-run=ConcurrentSafe -count=100 -race\ntest-concurrent-safe: TIMEOUT=120\n$(TEST_TARGETS): test\ntest: $(OTEL_GO_MOD_DIRS:%=test/%)\ntest/%: DIR=$*\ntest/%:\n\t@echo \"$(GO) test -timeout $(TIMEOUT)s $(ARGS) $(DIR)/...\" \\\n\t\t&& cd $(DIR) \\\n\t\t&& $(GO) list ./... \\\n\t\t| grep -v third_party \\\n\t\t| xargs $(GO) test -timeout $(TIMEOUT)s $(ARGS)\n\nCOVERAGE_MODE    = atomic\nCOVERAGE_PROFILE = coverage.out\n.PHONY: test-coverage\ntest-coverage: $(GOCOVMERGE)\n\t@set -e; \\\n\tprintf \"\" > coverage.txt; \\\n\tfor dir in $(ALL_COVERAGE_MOD_DIRS); do \\\n\t  echo \"$(GO) test -coverpkg=go.opentelemetry.io/otel/... -covermode=$(COVERAGE_MODE) -coverprofile=\"$(COVERAGE_PROFILE)\" $${dir}/...\"; \\\n\t  (cd \"$${dir}\" && \\\n\t    $(GO) list ./... \\\n\t    | grep -v third_party \\\n\t    | grep -v 'semconv/v.*' \\\n\t    | xargs $(GO) test -coverpkg=./... -covermode=$(COVERAGE_MODE) -coverprofile=\"$(COVERAGE_PROFILE)\" && \\\n\t  $(GO) tool cover -html=coverage.out -o coverage.html); \\\n\tdone; \\\n\t$(GOCOVMERGE) $$(find . -name coverage.out) > coverage.txt\n\n.PHONY: benchmark\nbenchmark: $(OTEL_GO_MOD_DIRS:%=benchmark/%)\nbenchmark/%:\n\t@echo \"$(GO) test -run=xxxxxMatchNothingxxxxx -bench=. $*...\" \\\n\t\t&& cd $* \\\n\t\t&& $(GO) list ./... \\\n\t\t| grep -v third_party \\\n\t\t| xargs $(GO) test -run=xxxxxMatchNothingxxxxx -bench=.\n\n.PHONY: golangci-lint golangci-lint-fix\ngolangci-lint-fix: ARGS=--fix\ngolangci-lint-fix: golangci-lint\ngolangci-lint: $(OTEL_GO_MOD_DIRS:%=golangci-lint/%)\ngolangci-lint/%: DIR=$*\ngolangci-lint/%: $(GOLANGCI_LINT)\n\t@echo 'golangci-lint $(if $(ARGS),$(ARGS) ,)$(DIR)' \\\n\t\t&& cd $(DIR) \\\n\t\t&& $(GOLANGCI_LINT) run --allow-serial-runners $(ARGS)\n\n.PHONY: crosslink\ncrosslink: $(CROSSLINK)\n\t@echo \"Updating intra-repository dependencies in all go modules\" \\\n\t\t&& $(CROSSLINK) --root=$(shell pwd) --prune\n\n.PHONY: go-mod-tidy\ngo-mod-tidy: $(ALL_GO_MOD_DIRS:%=go-mod-tidy/%)\ngo-mod-tidy/%: DIR=$*\ngo-mod-tidy/%: crosslink\n\t@echo \"$(GO) mod tidy in $(DIR)\" \\\n\t\t&& cd $(DIR) \\\n\t\t&& $(GO) mod tidy -compat=1.21\n\n.PHONY: lint\nlint: misspell go-mod-tidy golangci-lint govulncheck\n\n.PHONY: vanity-import-check\nvanity-import-check: $(PORTO)\n\t@$(PORTO) --include-internal -l . || ( echo \"(run: make vanity-import-fix)\"; exit 1 )\n\n.PHONY: misspell\nmisspell: $(MISSPELL)\n\t@$(MISSPELL) -w $(ALL_DOCS)\n\n.PHONY: govulncheck\ngovulncheck: $(OTEL_GO_MOD_DIRS:%=govulncheck/%)\ngovulncheck/%: DIR=$*\ngovulncheck/%: $(GOVULNCHECK)\n\t@echo \"govulncheck ./... in $(DIR)\" \\\n\t\t&& cd $(DIR) \\\n\t\t&& $(GOVULNCHECK) ./...\n\n.PHONY: codespell\ncodespell: $(CODESPELL)\n\t@$(DOCKERPY) $(CODESPELL)\n\n.PHONY: toolchain-check\ntoolchain-check:\n\t@toolchainRes=$$(for f in $(ALL_GO_MOD_DIRS); do \\\n\t           awk '/^toolchain/ { found=1; next } END { if (found) print FILENAME }' $$f/go.mod; \\\n\tdone); \\\n\tif [ -n \"$${toolchainRes}\" ]; then \\\n\t\t\techo \"toolchain checking failed:\"; echo \"$${toolchainRes}\"; \\\n\t\t\texit 1; \\\n\tfi\n\n.PHONY: license-check\nlicense-check:\n\t@licRes=$$(for f in $$(find . -type f \\( -iname '*.go' -o -iname '*.sh' \\) ! -path '**/third_party/*' ! -path './.git/*' ) ; do \\\n\t           awk '/Copyright The OpenTelemetry Authors|generated|GENERATED/ && NR<=4 { found=1; next } END { if (!found) print FILENAME }' $$f; \\\n\t   done); \\\n\t   if [ -n \"$${licRes}\" ]; then \\\n\t           echo \"license header checking failed:\"; echo \"$${licRes}\"; \\\n\t           exit 1; \\\n\t   fi\n\n.PHONY: check-clean-work-tree\ncheck-clean-work-tree:\n\t@if ! git diff --quiet; then \\\n\t  echo; \\\n\t  echo 'Working tree is not clean, did you forget to run \"make precommit\"?'; \\\n\t  echo; \\\n\t  git status; \\\n\t  exit 1; \\\n\tfi\n\n# The weaver docker image to use for semconv-generate.\nWEAVER_IMAGE := $(shell awk '$$4==\"weaver\" {print $$2}' $(DEPENDENCIES_DOCKERFILE))\n\nSEMCONVPKG ?= \"semconv/\"\n.PHONY: semconv-generate\nsemconv-generate: $(SEMCONVKIT)\n\t[ \"$(TAG)\" ] || ( echo \"TAG unset: missing opentelemetry semantic-conventions tag\"; exit 1 )\n\t# Ensure the target directory for source code is available.\n\tmkdir -p $(PWD)/$(SEMCONVPKG)/${TAG}\n\t# Note: We mount a home directory for downloading/storing the semconv repository.\n\t# Weaver will automatically clean the cache when finished, but the directories will remain.\n\tmkdir -p ~/.weaver\n\tdocker run --rm \\\n\t\t-u $(DOCKER_USER) \\\n\t\t--env HOME=/tmp/weaver \\\n\t\t--mount 'type=bind,source=$(PWD)/semconv/templates,target=/home/weaver/templates,readonly' \\\n\t\t--mount 'type=bind,source=$(PWD)/semconv/${TAG},target=/home/weaver/target' \\\n\t\t--mount 'type=bind,source=$(HOME)/.weaver,target=/tmp/weaver/.weaver' \\\n\t\t$(WEAVER_IMAGE) registry generate \\\n\t\t--registry=https://github.com/open-telemetry/semantic-conventions/archive/refs/tags/$(TAG).zip[model] \\\n\t\t--templates=/home/weaver/templates \\\n\t\t--param tag=$(TAG) \\\n\t\tgo \\\n\t\t/home/weaver/target\n\t$(SEMCONVKIT) -semconv \"$(SEMCONVPKG)\" -tag \"$(TAG)\"\n\n.PHONY: gorelease\ngorelease: $(OTEL_GO_MOD_DIRS:%=gorelease/%)\ngorelease/%: DIR=$*\ngorelease/%:| $(GORELEASE)\n\t@echo \"gorelease in $(DIR):\" \\\n\t\t&& cd $(DIR) \\\n\t\t&& $(GORELEASE) \\\n\t\t|| echo \"\"\n\n.PHONY: verify-mods\nverify-mods: $(MULTIMOD)\n\t$(MULTIMOD) verify\n\n.PHONY: prerelease\nprerelease: verify-mods\n\t@[ \"${MODSET}\" ] || ( echo \">> env var MODSET is not set\"; exit 1 )\n\t$(MULTIMOD) prerelease -m ${MODSET}\n\nCOMMIT ?= \"HEAD\"\n.PHONY: add-tags\nadd-tags: verify-mods\n\t@[ \"${MODSET}\" ] || ( echo \">> env var MODSET is not set\"; exit 1 )\n\t$(MULTIMOD) tag -m ${MODSET} -c ${COMMIT}\n\nMARKDOWNIMAGE := $(shell awk '$$4==\"markdown\" {print $$2}' $(DEPENDENCIES_DOCKERFILE))\n.PHONY: lint-markdown\nlint-markdown:\n\tdocker run --rm -u $(DOCKER_USER) -v \"$(CURDIR):$(WORKDIR)\" $(MARKDOWNIMAGE) -c $(WORKDIR)/.markdownlint.yaml $(WORKDIR)/**/*.md\n\n.PHONY: verify-readmes\nverify-readmes: $(VERIFYREADMES)\n\t$(VERIFYREADMES)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/README.md",
    "content": "# OpenTelemetry-Go\n\n[![ci](https://github.com/open-telemetry/opentelemetry-go/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/open-telemetry/opentelemetry-go/actions/workflows/ci.yml)\n[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-go/coverage.svg?branch=main)](https://app.codecov.io/gh/open-telemetry/opentelemetry-go?branch=main)\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel)](https://pkg.go.dev/go.opentelemetry.io/otel)\n[![Go Report Card](https://goreportcard.com/badge/go.opentelemetry.io/otel)](https://goreportcard.com/report/go.opentelemetry.io/otel)\n[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/open-telemetry/opentelemetry-go/badge)](https://scorecard.dev/viewer/?uri=github.com/open-telemetry/opentelemetry-go)\n[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/9996/badge)](https://www.bestpractices.dev/projects/9996)\n[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/opentelemetry-go.svg)](https://issues.oss-fuzz.com/issues?q=project:opentelemetry-go)\n[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B162%2Fgithub.com%2Fopen-telemetry%2Fopentelemetry-go.svg?type=shield&issueType=license)](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fopen-telemetry%2Fopentelemetry-go?ref=badge_shield&issueType=license)\n[![Slack](https://img.shields.io/badge/slack-@cncf/otel--go-brightgreen.svg?logo=slack)](https://cloud-native.slack.com/archives/C01NPAXACKT)\n\nOpenTelemetry-Go is the [Go](https://golang.org/) implementation of [OpenTelemetry](https://opentelemetry.io/).\nIt provides a set of APIs to directly measure performance and behavior of your software and send this data to observability platforms.\n\n## Project Status\n\n| Signal  | Status             |\n|---------|--------------------|\n| Traces  | Stable             |\n| Metrics | Stable             |\n| Logs    | Beta[^1]           |\n\nProgress and status specific to this repository is tracked in our\n[project boards](https://github.com/open-telemetry/opentelemetry-go/projects)\nand\n[milestones](https://github.com/open-telemetry/opentelemetry-go/milestones).\n\nProject versioning information and stability guarantees can be found in the\n[versioning documentation](VERSIONING.md).\n\n[^1]: https://github.com/orgs/open-telemetry/projects/43\n\n### Compatibility\n\nOpenTelemetry-Go ensures compatibility with the current supported versions of\nthe [Go language](https://golang.org/doc/devel/release#policy):\n\n> Each major Go release is supported until there are two newer major releases.\n> For example, Go 1.5 was supported until the Go 1.7 release, and Go 1.6 was supported until the Go 1.8 release.\n\nFor versions of Go that are no longer supported upstream, opentelemetry-go will\nstop ensuring compatibility with these versions in the following manner:\n\n- A minor release of opentelemetry-go will be made to add support for the new\n  supported release of Go.\n- The following minor release of opentelemetry-go will remove compatibility\n  testing for the oldest (now archived upstream) version of Go. This, and\n  future, releases of opentelemetry-go may include features only supported by\n  the currently supported versions of Go.\n\nCurrently, this project supports the following environments.\n\n| OS       | Go Version | Architecture |\n|----------|------------|--------------|\n| Ubuntu   | 1.25       | amd64        |\n| Ubuntu   | 1.24       | amd64        |\n| Ubuntu   | 1.25       | 386          |\n| Ubuntu   | 1.24       | 386          |\n| Ubuntu   | 1.25       | arm64        |\n| Ubuntu   | 1.24       | arm64        |\n| macOS    | 1.25       | amd64        |\n| macOS    | 1.24       | amd64        |\n| macOS    | 1.25       | arm64        |\n| macOS    | 1.24       | arm64        |\n| Windows  | 1.25       | amd64        |\n| Windows  | 1.24       | amd64        |\n| Windows  | 1.25       | 386          |\n| Windows  | 1.24       | 386          |\n\nWhile this project should work for other systems, no compatibility guarantees\nare made for those systems currently.\n\n## Getting Started\n\nYou can find a getting started guide on [opentelemetry.io](https://opentelemetry.io/docs/languages/go/getting-started/).\n\nOpenTelemetry's goal is to provide a single set of APIs to capture distributed\ntraces and metrics from your application and send them to an observability\nplatform. This project allows you to do just that for applications written in\nGo. There are two steps to this process: instrument your application, and\nconfigure an exporter.\n\n### Instrumentation\n\nTo start capturing distributed traces and metric events from your application\nit first needs to be instrumented. The easiest way to do this is by using an\ninstrumentation library for your code. Be sure to check out [the officially\nsupported instrumentation\nlibraries](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/instrumentation).\n\nIf you need to extend the telemetry an instrumentation library provides or want\nto build your own instrumentation for your application directly you will need\nto use the\n[Go otel](https://pkg.go.dev/go.opentelemetry.io/otel)\npackage. The [examples](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/examples)\nare a good way to see some practical uses of this process.\n\n### Export\n\nNow that your application is instrumented to collect telemetry, it needs an\nexport pipeline to send that telemetry to an observability platform.\n\nAll officially supported exporters for the OpenTelemetry project are contained in the [exporters directory](./exporters).\n\n| Exporter                              | Logs | Metrics | Traces |\n|---------------------------------------|:----:|:-------:|:------:|\n| [OTLP](./exporters/otlp/)             |  ✓   |    ✓    |   ✓    |\n| [Prometheus](./exporters/prometheus/) |      |    ✓    |        |\n| [stdout](./exporters/stdout/)         |  ✓   |    ✓    |   ✓    |\n| [Zipkin](./exporters/zipkin/)         |      |         |   ✓    |\n\n## Contributing\n\nSee the [contributing documentation](CONTRIBUTING.md).\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/RELEASING.md",
    "content": "# Release Process\n\n## Create a `Version Release` issue\n\nCreate a `Version Release` issue to track the release process.\n\n## Semantic Convention Generation\n\nNew versions of the [OpenTelemetry Semantic Conventions] mean new versions of the `semconv` package need to be generated.\nThe `semconv-generate` make target is used for this.\n\n1. Set the `TAG` environment variable to the semantic convention tag you want to generate.\n2. Run the `make semconv-generate ...` target from this repository.\n\nFor example,\n\n```sh\nexport TAG=\"v1.30.0\" # Change to the release version you are generating.\nmake semconv-generate # Uses the exported TAG.\n```\n\nThis should create a new sub-package of [`semconv`](./semconv).\nEnsure things look correct before submitting a pull request to include the addition.\n\n## Breaking changes validation\n\nYou can run `make gorelease` which runs [gorelease](https://pkg.go.dev/golang.org/x/exp/cmd/gorelease) to ensure that there are no unwanted changes made in the public API.\n\nYou can check/report problems with `gorelease` [here](https://golang.org/issues/26420).\n\n## Verify changes for contrib repository\n\nIf the changes in the main repository are going to affect the contrib repository, it is important to verify that the changes are compatible with the contrib repository.\n\nFollow [the steps](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/RELEASING.md#verify-otel-changes) in the contrib repository to verify OTel changes.\n\n## Pre-Release\n\nFirst, decide which module sets will be released and update their versions\nin `versions.yaml`.  Commit this change to a new branch.\n\nUpdate go.mod for submodules to depend on the new release which will happen in the next step.\n\n1. Run the `prerelease` make target. It creates a branch\n    `prerelease_<module set>_<new tag>` that will contain all release changes.\n\n    ```\n    make prerelease MODSET=<module set>\n    ```\n\n2. Verify the changes.\n\n    ```\n    git diff ...prerelease_<module set>_<new tag>\n    ```\n\n    This should have changed the version for all modules to be `<new tag>`.\n    If these changes look correct, merge them into your pre-release branch:\n\n    ```go\n    git merge prerelease_<module set>_<new tag>\n    ```\n\n3. Update the [Changelog](./CHANGELOG.md).\n   - Make sure all relevant changes for this release are included and are written in language that non-contributors to the project can understand.\n       To verify this, you can look directly at the commits since the `<last tag>`.\n\n       ```\n       git --no-pager log --pretty=oneline \"<last tag>..HEAD\"\n       ```\n\n   - Move all the `Unreleased` changes into a new section following the title scheme (`[<new tag>] - <date of release>`).\n   - Make sure the new section is under the comment for released section, like `<!-- Released section -->`, so it is protected from being overwritten in the future.\n   - Update all the appropriate links at the bottom.\n\n4. Push the changes to upstream and create a Pull Request on GitHub.\n    Be sure to include the curated changes from the [Changelog](./CHANGELOG.md) in the description.\n\n## Tag\n\nOnce the Pull Request with all the version changes has been approved and merged it is time to tag the merged commit.\n\n***IMPORTANT***: It is critical you use the same tag that you used in the Pre-Release step!\nFailure to do so will leave things in a broken state. As long as you do not\nchange `versions.yaml` between pre-release and this step, things should be fine.\n\n***IMPORTANT***: [There is currently no way to remove an incorrectly tagged version of a Go module](https://github.com/golang/go/issues/34189).\nIt is critical you make sure the version you push upstream is correct.\n[Failure to do so will lead to minor emergencies and tough to work around](https://github.com/open-telemetry/opentelemetry-go/issues/331).\n\n1. For each module set that will be released, run the `add-tags` make target\n    using the `<commit-hash>` of the commit on the main branch for the merged Pull Request.\n\n    ```\n    make add-tags MODSET=<module set> COMMIT=<commit hash>\n    ```\n\n    It should only be necessary to provide an explicit `COMMIT` value if the\n    current `HEAD` of your working directory is not the correct commit.\n\n2. Push tags to the upstream remote (not your fork: `github.com/open-telemetry/opentelemetry-go.git`).\n    Make sure you push all sub-modules as well.\n\n    ```\n    git push upstream <new tag>\n    git push upstream <submodules-path/new tag>\n    ...\n    ```\n\n## Sign artifacts\n\nTo ensure we comply with CNCF best practices, we need to sign the release artifacts.\n\nDownload the `.tar.gz` and `.zip` archives from the [tags page](https://github.com/open-telemetry/opentelemetry-go/tags) for the new release tag.\nBoth archives need to be signed with your GPG key.\n\nYou can use [this script] to verify the contents of the archives before signing them.\n\nTo find your GPG key ID, run:\n\n```terminal\ngpg --list-secret-keys --keyid-format=long\n```\n\nThe key ID is the 16-character string after `sec rsa4096/` (or similar).\n\nSet environment variables and sign both artifacts:\n\n```terminal\nexport VERSION=\"<version>\"  # e.g., v1.32.0\nexport KEY_ID=\"<your-gpg-key-id>\"\n\ngpg --local-user $KEY_ID --armor --detach-sign opentelemetry-go-$VERSION.tar.gz\ngpg --local-user $KEY_ID --armor --detach-sign opentelemetry-go-$VERSION.zip\n```\n\nYou can verify the signatures with:\n\n```terminal\ngpg --verify opentelemetry-go-$VERSION.tar.gz.asc opentelemetry-go-$VERSION.tar.gz\ngpg --verify opentelemetry-go-$VERSION.zip.asc opentelemetry-go-$VERSION.zip\n```\n\n[this script]: https://github.com/MrAlias/attest-sh\n\n## Release\n\nFinally create a Release for the new `<new tag>` on GitHub.\nThe release body should include all the release notes from the Changelog for this release.\n\n***IMPORTANT***: GitHub Releases are immutable once created.\nYou must upload the signed artifacts (`.tar.gz`, `.tar.gz.asc`, `.zip`, and `.zip.asc`) when creating the release, as they cannot be added or modified later.\n\n## Post-Release\n\n### Contrib Repository\n\nOnce verified be sure to [make a release for the `contrib` repository](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/RELEASING.md) that uses this release.\n\n### Website Documentation\n\nUpdate the [Go instrumentation documentation] in the OpenTelemetry website under [content/en/docs/languages/go].\nImportantly, bump any package versions referenced to be the latest one you just released and ensure all code examples still compile and are accurate.\n\n[OpenTelemetry Semantic Conventions]: https://github.com/open-telemetry/semantic-conventions\n[Go instrumentation documentation]: https://opentelemetry.io/docs/languages/go/\n[content/en/docs/languages/go]: https://github.com/open-telemetry/opentelemetry.io/tree/main/content/en/docs/languages/go\n\n### Close the milestone\n\nOnce a release is made, ensure all issues that were fixed and PRs that were merged as part of this release are added to the corresponding milestone.\nThis helps track what changes were included in each release.\n\n- To find issues that haven't been included in a milestone, use this [GitHub search query](https://github.com/open-telemetry/opentelemetry-go/issues?q=is%3Aissue%20no%3Amilestone%20is%3Aclosed%20sort%3Aupdated-desc%20reason%3Acompleted%20-label%3AStale%20linked%3Apr)\n- To find merged PRs that haven't been included in a milestone, use this [GitHub search query](https://github.com/open-telemetry/opentelemetry-go/pulls?q=is%3Apr+no%3Amilestone+is%3Amerged).\n\nOnce all related issues and PRs have been added to the milestone, close the milestone.\n\n### Close the `Version Release` issue\n\nOnce the todo list in the `Version Release` issue is complete, close the issue.\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/SECURITY-INSIGHTS.yml",
    "content": "header:\n  schema-version: \"1.0.0\"\n  expiration-date: \"2026-08-04T00:00:00.000Z\"\n  last-updated: \"2025-08-04\"\n  last-reviewed: \"2025-08-04\"\n  commit-hash: 69e81088ad40f45a0764597326722dea8f3f00a8\n  project-url: https://github.com/open-telemetry/opentelemetry-go\n  project-release: \"v1.37.0\"\n  changelog: https://github.com/open-telemetry/opentelemetry-go/blob/69e81088ad40f45a0764597326722dea8f3f00a8/CHANGELOG.md\n  license: https://github.com/open-telemetry/opentelemetry-go/blob/69e81088ad40f45a0764597326722dea8f3f00a8/LICENSE\n\nproject-lifecycle:\n  status: active\n  bug-fixes-only: false\n  core-maintainers:\n    - https://github.com/dmathieu\n    - https://github.com/dashpole\n    - https://github.com/pellared\n    - https://github.com/XSAM\n    - https://github.com/MrAlias\n  release-process: |\n    See https://github.com/open-telemetry/opentelemetry-go/blob/69e81088ad40f45a0764597326722dea8f3f00a8/RELEASING.md\n\ncontribution-policy:\n  accepts-pull-requests: true\n  accepts-automated-pull-requests: true\n  automated-tools-list:\n    - automated-tool: dependabot\n      action: allowed\n      comment: Automated dependency updates are accepted.\n    - automated-tool: renovatebot\n      action: allowed\n      comment: Automated dependency updates are accepted.\n    - automated-tool: opentelemetrybot\n      action: allowed\n      comment: Automated OpenTelemetry actions are accepted.\n  contributing-policy: https://github.com/open-telemetry/opentelemetry-go/blob/69e81088ad40f45a0764597326722dea8f3f00a8/CONTRIBUTING.md\n  code-of-conduct: https://github.com/open-telemetry/.github/blob/ffa15f76b65ec7bcc41f6a0b277edbb74f832206/CODE_OF_CONDUCT.md\n\ndocumentation:\n  - https://pkg.go.dev/go.opentelemetry.io/otel\n  - https://opentelemetry.io/docs/instrumentation/go/\n\ndistribution-points:\n  - pkg:golang/go.opentelemetry.io/otel\n  - pkg:golang/go.opentelemetry.io/otel/bridge/opencensus\n  - pkg:golang/go.opentelemetry.io/otel/bridge/opencensus/test\n  - pkg:golang/go.opentelemetry.io/otel/bridge/opentracing\n  - pkg:golang/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc\n  - pkg:golang/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp\n  - pkg:golang/go.opentelemetry.io/otel/exporters/otlp/otlptrace\n  - pkg:golang/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc\n  - pkg:golang/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp\n  - pkg:golang/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric\n  - pkg:golang/go.opentelemetry.io/otel/exporters/stdout/stdouttrace\n  - pkg:golang/go.opentelemetry.io/otel/exporters/zipkin\n  - pkg:golang/go.opentelemetry.io/otel/metric\n  - pkg:golang/go.opentelemetry.io/otel/sdk\n  - pkg:golang/go.opentelemetry.io/otel/sdk/metric\n  - pkg:golang/go.opentelemetry.io/otel/trace\n  - pkg:golang/go.opentelemetry.io/otel/exporters/prometheus\n  - pkg:golang/go.opentelemetry.io/otel/log\n  - pkg:golang/go.opentelemetry.io/otel/log/logtest\n  - pkg:golang/go.opentelemetry.io/otel/sdk/log\n  - pkg:golang/go.opentelemetry.io/otel/sdk/log/logtest\n  - pkg:golang/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc\n  - pkg:golang/go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp\n  - pkg:golang/go.opentelemetry.io/otel/exporters/stdout/stdoutlog\n  - pkg:golang/go.opentelemetry.io/otel/schema\n\nsecurity-artifacts:\n  threat-model:\n    threat-model-created: false\n    comment: |\n      No formal threat model created yet.\n  self-assessment:\n    self-assessment-created: false\n    comment: |\n      No formal self-assessment yet.\n\nsecurity-testing:\n  - tool-type: sca\n    tool-name: Dependabot\n    tool-version: latest\n    tool-url: https://github.com/dependabot\n    tool-rulesets:\n      - built-in\n    integration:\n      ad-hoc: false\n      ci: true\n      before-release: true\n    comment: |\n      Automated dependency updates.\n  - tool-type: sast\n    tool-name: golangci-lint\n    tool-version: latest\n    tool-url: https://github.com/golangci/golangci-lint\n    tool-rulesets:\n      - built-in\n    integration:\n      ad-hoc: false\n      ci: true\n      before-release: true\n    comment: |\n      Static analysis in CI.\n  - tool-type: fuzzing\n    tool-name: OSS-Fuzz\n    tool-version: latest\n    tool-url: https://github.com/google/oss-fuzz\n    tool-rulesets:\n      - default\n    integration:\n      ad-hoc: false\n      ci: false\n      before-release: false\n    comment: |\n      OpenTelemetry Go is integrated with OSS-Fuzz for continuous fuzz testing. See https://github.com/google/oss-fuzz/tree/f0f9b221190c6063a773bea606d192ebfc3d00cf/projects/opentelemetry-go for more details.\n  - tool-type: sast\n    tool-name: CodeQL\n    tool-version: latest\n    tool-url: https://github.com/github/codeql\n    tool-rulesets:\n      - default\n    integration:\n      ad-hoc: false\n      ci: true\n      before-release: true\n    comment: |\n      CodeQL static analysis is run in CI for all commits and pull requests to detect security vulnerabilities in the Go source code. See https://github.com/open-telemetry/opentelemetry-go/blob/d5b5b059849720144a03ca5c87561bfbdb940119/.github/workflows/codeql-analysis.yml for workflow details.\n  - tool-type: sca\n    tool-name: govulncheck\n    tool-version: latest\n    tool-url: https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck\n    tool-rulesets:\n      - default\n    integration:\n      ad-hoc: false\n      ci: true\n      before-release: true\n    comment: |\n      govulncheck is run in CI to detect known vulnerabilities in Go modules and code paths. See https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/.github/workflows/ci.yml for workflow configuration.\n\nsecurity-assessments:\n  - auditor-name: 7ASecurity\n    auditor-url: https://7asecurity.com\n    auditor-report: https://7asecurity.com/reports/pentest-report-opentelemetry.pdf\n    report-year: 2023\n    comment: |\n      This independent penetration test by 7ASecurity covered OpenTelemetry repositories including opentelemetry-go. The assessment focused on codebase review, threat modeling, and vulnerability identification. See the report for details of findings and recommendations applicable to opentelemetry-go. No critical vulnerabilities were found for this repository.\n\nsecurity-contacts:\n  - type: email\n    value: cncf-opentelemetry-security@lists.cncf.io\n    primary: true\n  - type: website\n    value: https://github.com/open-telemetry/opentelemetry-go/security/policy\n    primary: false\n\nvulnerability-reporting:\n  accepts-vulnerability-reports: true\n  email-contact: cncf-opentelemetry-security@lists.cncf.io\n  security-policy: https://github.com/open-telemetry/opentelemetry-go/security/policy\n  comment: |\n    Security issues should be reported via email or GitHub security policy page.\n\ndependencies:\n  third-party-packages: true\n  dependencies-lists:\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/bridge/opencensus/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/bridge/opencensus/test/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/bridge/opentracing/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/exporters/otlp/otlplog/otlploggrpc/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/exporters/otlp/otlplog/otlploghttp/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/exporters/otlp/otlpmetric/otlpmetrichttp/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/exporters/otlp/otlptrace/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/exporters/otlp/otlptrace/otlptracegrpc/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/exporters/otlp/otlptrace/otlptracehttp/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/exporters/prometheus/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/exporters/stdout/stdoutlog/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/exporters/stdout/stdoutmetric/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/exporters/stdout/stdouttrace/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/exporters/zipkin/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/internal/tools/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/log/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/log/logtest/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/metric/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/schema/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/sdk/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/sdk/log/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/sdk/log/logtest/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/sdk/metric/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/trace/go.mod\n    - https://github.com/open-telemetry/opentelemetry-go/blob/v1.37.0/trace/internal/telemetry/test/go.mod\n  dependencies-lifecycle:\n    policy-url: https://github.com/open-telemetry/opentelemetry-go/blob/69e81088ad40f45a0764597326722dea8f3f00a8/CONTRIBUTING.md\n    comment: |\n      Dependency lifecycle managed via go.mod and renovatebot.\n  env-dependencies-policy:\n    policy-url: https://github.com/open-telemetry/opentelemetry-go/blob/69e81088ad40f45a0764597326722dea8f3f00a8/CONTRIBUTING.md\n    comment: |\n      See contributing policy for environment usage.\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/VERSIONING.md",
    "content": "# Versioning\n\nThis document describes the versioning policy for this repository. This policy\nis designed so the following goals can be achieved.\n\n**Users are provided a codebase of value that is stable and secure.**\n\n## Policy\n\n* Versioning of this project will be idiomatic of a Go project using [Go\n  modules](https://github.com/golang/go/wiki/Modules).\n  * [Semantic import\n    versioning](https://github.com/golang/go/wiki/Modules#semantic-import-versioning)\n    will be used.\n    * Versions will comply with [semver\n      2.0](https://semver.org/spec/v2.0.0.html) with the following exceptions.\n      * New methods may be added to exported API interfaces. All exported\n        interfaces that fall within this exception will include the following\n        paragraph in their public documentation.\n\n        > Warning: methods may be added to this interface in minor releases.\n\n    * If a module is version `v2` or higher, the major version of the module\n      must be included as a `/vN` at the end of the module paths used in\n      `go.mod` files (e.g., `module go.opentelemetry.io/otel/v2`, `require\n      go.opentelemetry.io/otel/v2 v2.0.1`) and in the package import path\n      (e.g., `import \"go.opentelemetry.io/otel/v2/trace\"`). This includes the\n      paths used in `go get` commands (e.g., `go get\n      go.opentelemetry.io/otel/v2@v2.0.1`).  Note there is both a `/v2` and a\n      `@v2.0.1` in that example. One way to think about it is that the module\n      name now includes the `/v2`, so include `/v2` whenever you are using the\n      module name).\n    * If a module is version `v0` or `v1`, do not include the major version in\n      either the module path or the import path.\n  * Modules will be used to encapsulate signals and components.\n    * Experimental modules still under active development will be versioned at\n      `v0` to imply the stability guarantee defined by\n      [semver](https://semver.org/spec/v2.0.0.html#spec-item-4).\n\n      > Major version zero (0.y.z) is for initial development. Anything MAY\n      > change at any time. The public API SHOULD NOT be considered stable.\n\n    * Mature modules for which we guarantee a stable public API will be versioned\n      with a major version greater than `v0`.\n      * The decision to make a module stable will be made on a case-by-case\n        basis by the maintainers of this project.\n    * Experimental modules will start their versioning at `v0.0.0` and will\n      increment their minor version when backwards incompatible changes are\n      released and increment their patch version when backwards compatible\n      changes are released.\n    * All stable modules that use the same major version number will use the\n      same entire version number.\n      * Stable modules may be released with an incremented minor or patch\n        version even though that module has not been changed, but rather so\n        that it will remain at the same version as other stable modules that\n        did undergo change.\n      * When an experimental module becomes stable a new stable module version\n        will be released and will include this now stable module. The new\n        stable module version will be an increment of the minor version number\n        and will be applied to all existing stable modules as well as the newly\n        stable module being released.\n* Versioning of the associated [contrib\n  repository](https://github.com/open-telemetry/opentelemetry-go-contrib) of\n  this project will be idiomatic of a Go project using [Go\n  modules](https://github.com/golang/go/wiki/Modules).\n  * [Semantic import\n    versioning](https://github.com/golang/go/wiki/Modules#semantic-import-versioning)\n    will be used.\n    * Versions will comply with [semver 2.0](https://semver.org/spec/v2.0.0.html).\n    * If a module is version `v2` or higher, the\n      major version of the module must be included as a `/vN` at the end of the\n      module paths used in `go.mod` files (e.g., `module\n      go.opentelemetry.io/contrib/instrumentation/host/v2`, `require\n      go.opentelemetry.io/contrib/instrumentation/host/v2 v2.0.1`) and in the\n      package import path (e.g., `import\n      \"go.opentelemetry.io/contrib/instrumentation/host/v2\"`). This includes\n      the paths used in `go get` commands (e.g., `go get\n      go.opentelemetry.io/contrib/instrumentation/host/v2@v2.0.1`.  Note there\n      is both a `/v2` and a `@v2.0.1` in that example. One way to think about\n      it is that the module name now includes the `/v2`, so include `/v2`\n      whenever you are using the module name).\n    * If a module is version `v0` or `v1`, do not include the major version\n      in either the module path or the import path.\n  * In addition to public APIs, telemetry produced by stable instrumentation\n    will remain stable and backwards compatible. This is to avoid breaking\n    alerts and dashboards.\n  * Modules will be used to encapsulate instrumentation, detectors, exporters,\n    propagators, and any other independent sets of related components.\n    * Experimental modules still under active development will be versioned at\n      `v0` to imply the stability guarantee defined by\n      [semver](https://semver.org/spec/v2.0.0.html#spec-item-4).\n\n      > Major version zero (0.y.z) is for initial development. Anything MAY\n      > change at any time. The public API SHOULD NOT be considered stable.\n\n    * Mature modules for which we guarantee a stable public API and telemetry will\n      be versioned with a major version greater than `v0`.\n    * Experimental modules will start their versioning at `v0.0.0` and will\n      increment their minor version when backwards incompatible changes are\n      released and increment their patch version when backwards compatible\n      changes are released.\n    * Stable contrib modules cannot depend on experimental modules from this\n      project.\n    * All stable contrib modules of the same major version with this project\n      will use the same entire version as this project.\n      * Stable modules may be released with an incremented minor or patch\n        version even though that module's code has not been changed. Instead\n        the only change that will have been included is to have updated that\n        modules dependency on this project's stable APIs.\n      * When an experimental module in contrib becomes stable a new stable\n        module version will be released and will include this now stable\n        module. The new stable module version will be an increment of the minor\n        version number and will be applied to all existing stable contrib\n        modules, this project's modules, and the newly stable module being\n        released.\n  * Contrib modules will be kept up to date with this project's releases.\n    * Due to the dependency contrib modules will implicitly have on this\n      project's modules the release of stable contrib modules to match the\n      released version number will be staggered after this project's release.\n      There is no explicit time guarantee for how long after this projects\n      release the contrib release will be. Effort should be made to keep them\n      as close in time as possible.\n    * No additional stable release in this project can be made until the\n      contrib repository has a matching stable release.\n    * No release can be made in the contrib repository after this project's\n      stable release except for a stable release of the contrib repository.\n* GitHub releases will be made for all releases.\n* Go modules will be made available at Go package mirrors.\n\n## Example Versioning Lifecycle\n\nTo better understand the implementation of the above policy the following\nexample is provided. This project is simplified to include only the following\nmodules and their versions:\n\n* `otel`: `v0.14.0`\n* `otel/trace`: `v0.14.0`\n* `otel/metric`: `v0.14.0`\n* `otel/baggage`: `v0.14.0`\n* `otel/sdk/trace`: `v0.14.0`\n* `otel/sdk/metric`: `v0.14.0`\n\nThese modules have been developed to a point where the `otel/trace`,\n`otel/baggage`, and `otel/sdk/trace` modules have reached a point that they\nshould be considered for a stable release. The `otel/metric` and\n`otel/sdk/metric` are still under active development and the `otel` module\ndepends on both `otel/trace` and `otel/metric`.\n\nThe `otel` package is refactored to remove its dependencies on `otel/metric` so\nit can be released as stable as well. With that done the following release\ncandidates are made:\n\n* `otel`: `v1.0.0-RC1`\n* `otel/trace`: `v1.0.0-RC1`\n* `otel/baggage`: `v1.0.0-RC1`\n* `otel/sdk/trace`: `v1.0.0-RC1`\n\nThe `otel/metric` and `otel/sdk/metric` modules remain at `v0.14.0`.\n\nA few minor issues are discovered in the `otel/trace` package. These issues are\nresolved with some minor, but backwards incompatible, changes and are released\nas a second release candidate:\n\n* `otel`: `v1.0.0-RC2`\n* `otel/trace`: `v1.0.0-RC2`\n* `otel/baggage`: `v1.0.0-RC2`\n* `otel/sdk/trace`: `v1.0.0-RC2`\n\nNotice that all module version numbers are incremented to adhere to our\nversioning policy.\n\nAfter these release candidates have been evaluated to satisfaction, they are\nreleased as version `v1.0.0`.\n\n* `otel`: `v1.0.0`\n* `otel/trace`: `v1.0.0`\n* `otel/baggage`: `v1.0.0`\n* `otel/sdk/trace`: `v1.0.0`\n\nSince both the `go` utility and the Go module system support [the semantic\nversioning definition of\nprecedence](https://semver.org/spec/v2.0.0.html#spec-item-11), this release\nwill correctly be interpreted as the successor to the previous release\ncandidates.\n\nActive development of this project continues. The `otel/metric` module now has\nbackwards incompatible changes to its API that need to be released and the\n`otel/baggage` module has a minor bug fix that needs to be released. The\nfollowing release is made:\n\n* `otel`: `v1.0.1`\n* `otel/trace`: `v1.0.1`\n* `otel/metric`: `v0.15.0`\n* `otel/baggage`: `v1.0.1`\n* `otel/sdk/trace`: `v1.0.1`\n* `otel/sdk/metric`: `v0.15.0`\n\nNotice that, again, all stable module versions are incremented in unison and\nthe `otel/sdk/metric` package, which depends on the `otel/metric` package, also\nbumped its version. This bump of the `otel/sdk/metric` package makes sense\ngiven their coupling, though it is not explicitly required by our versioning\npolicy.\n\nAs we progress, the `otel/metric` and `otel/sdk/metric` packages have reached a\npoint where they should be evaluated for stability. The `otel` module is\nreintegrated with the `otel/metric` package and the following release is made:\n\n* `otel`: `v1.1.0-RC1`\n* `otel/trace`: `v1.1.0-RC1`\n* `otel/metric`: `v1.1.0-RC1`\n* `otel/baggage`: `v1.1.0-RC1`\n* `otel/sdk/trace`: `v1.1.0-RC1`\n* `otel/sdk/metric`: `v1.1.0-RC1`\n\nAll the modules are evaluated and determined to a viable stable release. They\nare then released as version `v1.1.0` (the minor version is incremented to\nindicate the addition of new signal).\n\n* `otel`: `v1.1.0`\n* `otel/trace`: `v1.1.0`\n* `otel/metric`: `v1.1.0`\n* `otel/baggage`: `v1.1.0`\n* `otel/sdk/trace`: `v1.1.0`\n* `otel/sdk/metric`: `v1.1.0`\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/README.md",
    "content": "# Attribute\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/attribute)](https://pkg.go.dev/go.opentelemetry.io/otel/attribute)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package attribute provides key and value attributes.\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/encoder.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n\nimport (\n\t\"bytes\"\n\t\"sync\"\n\t\"sync/atomic\"\n)\n\ntype (\n\t// Encoder is a mechanism for serializing an attribute set into a specific\n\t// string representation that supports caching, to avoid repeated\n\t// serialization. An example could be an exporter encoding the attribute\n\t// set into a wire representation.\n\tEncoder interface {\n\t\t// Encode returns the serialized encoding of the attribute set using\n\t\t// its Iterator. This result may be cached by an attribute.Set.\n\t\tEncode(iterator Iterator) string\n\n\t\t// ID returns a value that is unique for each class of attribute\n\t\t// encoder. Attribute encoders allocate these using `NewEncoderID`.\n\t\tID() EncoderID\n\t}\n\n\t// EncoderID is used to identify distinct Encoder\n\t// implementations, for caching encoded results.\n\tEncoderID struct {\n\t\tvalue uint64\n\t}\n\n\t// defaultAttrEncoder uses a sync.Pool of buffers to reduce the number of\n\t// allocations used in encoding attributes. This implementation encodes a\n\t// comma-separated list of key=value, with '/'-escaping of '=', ',', and\n\t// '\\'.\n\tdefaultAttrEncoder struct {\n\t\t// pool is a pool of attribute set builders. The buffers in this pool\n\t\t// grow to a size that most attribute encodings will not allocate new\n\t\t// memory.\n\t\tpool sync.Pool // *bytes.Buffer\n\t}\n)\n\n// escapeChar is used to ensure uniqueness of the attribute encoding where\n// keys or values contain either '=' or ','.  Since there is no parser needed\n// for this encoding and its only requirement is to be unique, this choice is\n// arbitrary.  Users will see these in some exporters (e.g., stdout), so the\n// backslash ('\\') is used as a conventional choice.\nconst escapeChar = '\\\\'\n\nvar (\n\t_ Encoder = &defaultAttrEncoder{}\n\n\t// encoderIDCounter is for generating IDs for other attribute encoders.\n\tencoderIDCounter uint64\n\n\tdefaultEncoderOnce     sync.Once\n\tdefaultEncoderID       = NewEncoderID()\n\tdefaultEncoderInstance *defaultAttrEncoder\n)\n\n// NewEncoderID returns a unique attribute encoder ID. It should be called\n// once per each type of attribute encoder. Preferably in init() or in var\n// definition.\nfunc NewEncoderID() EncoderID {\n\treturn EncoderID{value: atomic.AddUint64(&encoderIDCounter, 1)}\n}\n\n// DefaultEncoder returns an attribute encoder that encodes attributes in such\n// a way that each escaped attribute's key is followed by an equal sign and\n// then by an escaped attribute's value. All key-value pairs are separated by\n// a comma.\n//\n// Escaping is done by prepending a backslash before either a backslash, equal\n// sign or a comma.\nfunc DefaultEncoder() Encoder {\n\tdefaultEncoderOnce.Do(func() {\n\t\tdefaultEncoderInstance = &defaultAttrEncoder{\n\t\t\tpool: sync.Pool{\n\t\t\t\tNew: func() any {\n\t\t\t\t\treturn &bytes.Buffer{}\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t})\n\treturn defaultEncoderInstance\n}\n\n// Encode is a part of an implementation of the AttributeEncoder interface.\nfunc (d *defaultAttrEncoder) Encode(iter Iterator) string {\n\tbuf := d.pool.Get().(*bytes.Buffer)\n\tdefer d.pool.Put(buf)\n\tbuf.Reset()\n\n\tfor iter.Next() {\n\t\ti, keyValue := iter.IndexedAttribute()\n\t\tif i > 0 {\n\t\t\t_ = buf.WriteByte(',')\n\t\t}\n\t\tcopyAndEscape(buf, string(keyValue.Key))\n\n\t\t_ = buf.WriteByte('=')\n\n\t\tif keyValue.Value.Type() == STRING {\n\t\t\tcopyAndEscape(buf, keyValue.Value.AsString())\n\t\t} else {\n\t\t\t_, _ = buf.WriteString(keyValue.Value.Emit())\n\t\t}\n\t}\n\treturn buf.String()\n}\n\n// ID is a part of an implementation of the AttributeEncoder interface.\nfunc (*defaultAttrEncoder) ID() EncoderID {\n\treturn defaultEncoderID\n}\n\n// copyAndEscape escapes `=`, `,` and its own escape character (`\\`),\n// making the default encoding unique.\nfunc copyAndEscape(buf *bytes.Buffer, val string) {\n\tfor _, ch := range val {\n\t\tswitch ch {\n\t\tcase '=', ',', escapeChar:\n\t\t\t_ = buf.WriteByte(escapeChar)\n\t\t}\n\t\t_, _ = buf.WriteRune(ch)\n\t}\n}\n\n// Valid reports whether this encoder ID was allocated by\n// [NewEncoderID]. Invalid encoder IDs will not be cached.\nfunc (id EncoderID) Valid() bool {\n\treturn id.value != 0\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/filter.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n\n// Filter supports removing certain attributes from attribute sets. When\n// the filter returns true, the attribute will be kept in the filtered\n// attribute set. When the filter returns false, the attribute is excluded\n// from the filtered attribute set, and the attribute instead appears in\n// the removed list of excluded attributes.\ntype Filter func(KeyValue) bool\n\n// NewAllowKeysFilter returns a Filter that only allows attributes with one of\n// the provided keys.\n//\n// If keys is empty a deny-all filter is returned.\nfunc NewAllowKeysFilter(keys ...Key) Filter {\n\tif len(keys) == 0 {\n\t\treturn func(KeyValue) bool { return false }\n\t}\n\n\tallowed := make(map[Key]struct{}, len(keys))\n\tfor _, k := range keys {\n\t\tallowed[k] = struct{}{}\n\t}\n\treturn func(kv KeyValue) bool {\n\t\t_, ok := allowed[kv.Key]\n\t\treturn ok\n\t}\n}\n\n// NewDenyKeysFilter returns a Filter that only allows attributes\n// that do not have one of the provided keys.\n//\n// If keys is empty an allow-all filter is returned.\nfunc NewDenyKeysFilter(keys ...Key) Filter {\n\tif len(keys) == 0 {\n\t\treturn func(KeyValue) bool { return true }\n\t}\n\n\tforbid := make(map[Key]struct{}, len(keys))\n\tfor _, k := range keys {\n\t\tforbid[k] = struct{}{}\n\t}\n\treturn func(kv KeyValue) bool {\n\t\t_, ok := forbid[kv.Key]\n\t\treturn !ok\n\t}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/hash.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\n\t\"go.opentelemetry.io/otel/attribute/internal/xxhash\"\n)\n\n// Type identifiers. These identifiers are hashed before the value of the\n// corresponding type. This is done to distinguish values that are hashed with\n// the same value representation (e.g. `int64(1)` and `true`, []int64{0} and\n// int64(0)).\n//\n// These are all 8 byte length strings converted to a uint64 representation. A\n// uint64 is used instead of the string directly as an optimization, it avoids\n// the for loop in [xxhash] which adds minor overhead.\nconst (\n\tboolID         uint64 = 7953749933313450591 // \"_boolean\" (little endian)\n\tint64ID        uint64 = 7592915492740740150 // \"64_bit_i\" (little endian)\n\tfloat64ID      uint64 = 7376742710626956342 // \"64_bit_f\" (little endian)\n\tstringID       uint64 = 6874584755375207263 // \"_string_\" (little endian)\n\tboolSliceID    uint64 = 6875993255270243167 // \"_[]bool_\" (little endian)\n\tint64SliceID   uint64 = 3762322556277578591 // \"_[]int64\" (little endian)\n\tfloat64SliceID uint64 = 7308324551835016539 // \"[]double\" (little endian)\n\tstringSliceID  uint64 = 7453010373645655387 // \"[]string\" (little endian)\n)\n\n// hashKVs returns a new xxHash64 hash of kvs.\nfunc hashKVs(kvs []KeyValue) uint64 {\n\th := xxhash.New()\n\tfor _, kv := range kvs {\n\t\th = hashKV(h, kv)\n\t}\n\treturn h.Sum64()\n}\n\n// hashKV returns the xxHash64 hash of kv with h as the base.\nfunc hashKV(h xxhash.Hash, kv KeyValue) xxhash.Hash {\n\th = h.String(string(kv.Key))\n\n\tswitch kv.Value.Type() {\n\tcase BOOL:\n\t\th = h.Uint64(boolID)\n\t\th = h.Uint64(kv.Value.numeric)\n\tcase INT64:\n\t\th = h.Uint64(int64ID)\n\t\th = h.Uint64(kv.Value.numeric)\n\tcase FLOAT64:\n\t\th = h.Uint64(float64ID)\n\t\t// Assumes numeric stored with math.Float64bits.\n\t\th = h.Uint64(kv.Value.numeric)\n\tcase STRING:\n\t\th = h.Uint64(stringID)\n\t\th = h.String(kv.Value.stringly)\n\tcase BOOLSLICE:\n\t\th = h.Uint64(boolSliceID)\n\t\trv := reflect.ValueOf(kv.Value.slice)\n\t\tfor i := 0; i < rv.Len(); i++ {\n\t\t\th = h.Bool(rv.Index(i).Bool())\n\t\t}\n\tcase INT64SLICE:\n\t\th = h.Uint64(int64SliceID)\n\t\trv := reflect.ValueOf(kv.Value.slice)\n\t\tfor i := 0; i < rv.Len(); i++ {\n\t\t\th = h.Int64(rv.Index(i).Int())\n\t\t}\n\tcase FLOAT64SLICE:\n\t\th = h.Uint64(float64SliceID)\n\t\trv := reflect.ValueOf(kv.Value.slice)\n\t\tfor i := 0; i < rv.Len(); i++ {\n\t\t\th = h.Float64(rv.Index(i).Float())\n\t\t}\n\tcase STRINGSLICE:\n\t\th = h.Uint64(stringSliceID)\n\t\trv := reflect.ValueOf(kv.Value.slice)\n\t\tfor i := 0; i < rv.Len(); i++ {\n\t\t\th = h.String(rv.Index(i).String())\n\t\t}\n\tcase INVALID:\n\tdefault:\n\t\t// Logging is an alternative, but using the internal logger here\n\t\t// causes an import cycle so it is not done.\n\t\tv := kv.Value.AsInterface()\n\t\tmsg := fmt.Sprintf(\"unknown value type: %[1]v (%[1]T)\", v)\n\t\tpanic(msg)\n\t}\n\treturn h\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/internal/attribute.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n/*\nPackage attribute provide several helper functions for some commonly used\nlogic of processing attributes.\n*/\npackage attribute // import \"go.opentelemetry.io/otel/attribute/internal\"\n\nimport (\n\t\"reflect\"\n)\n\n// BoolSliceValue converts a bool slice into an array with same elements as slice.\nfunc BoolSliceValue(v []bool) any {\n\tcp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeFor[bool]())).Elem()\n\treflect.Copy(cp, reflect.ValueOf(v))\n\treturn cp.Interface()\n}\n\n// Int64SliceValue converts an int64 slice into an array with same elements as slice.\nfunc Int64SliceValue(v []int64) any {\n\tcp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeFor[int64]())).Elem()\n\treflect.Copy(cp, reflect.ValueOf(v))\n\treturn cp.Interface()\n}\n\n// Float64SliceValue converts a float64 slice into an array with same elements as slice.\nfunc Float64SliceValue(v []float64) any {\n\tcp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeFor[float64]())).Elem()\n\treflect.Copy(cp, reflect.ValueOf(v))\n\treturn cp.Interface()\n}\n\n// StringSliceValue converts a string slice into an array with same elements as slice.\nfunc StringSliceValue(v []string) any {\n\tcp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeFor[string]())).Elem()\n\treflect.Copy(cp, reflect.ValueOf(v))\n\treturn cp.Interface()\n}\n\n// AsBoolSlice converts a bool array into a slice into with same elements as array.\nfunc AsBoolSlice(v any) []bool {\n\trv := reflect.ValueOf(v)\n\tif rv.Type().Kind() != reflect.Array {\n\t\treturn nil\n\t}\n\tcpy := make([]bool, rv.Len())\n\tif len(cpy) > 0 {\n\t\t_ = reflect.Copy(reflect.ValueOf(cpy), rv)\n\t}\n\treturn cpy\n}\n\n// AsInt64Slice converts an int64 array into a slice into with same elements as array.\nfunc AsInt64Slice(v any) []int64 {\n\trv := reflect.ValueOf(v)\n\tif rv.Type().Kind() != reflect.Array {\n\t\treturn nil\n\t}\n\tcpy := make([]int64, rv.Len())\n\tif len(cpy) > 0 {\n\t\t_ = reflect.Copy(reflect.ValueOf(cpy), rv)\n\t}\n\treturn cpy\n}\n\n// AsFloat64Slice converts a float64 array into a slice into with same elements as array.\nfunc AsFloat64Slice(v any) []float64 {\n\trv := reflect.ValueOf(v)\n\tif rv.Type().Kind() != reflect.Array {\n\t\treturn nil\n\t}\n\tcpy := make([]float64, rv.Len())\n\tif len(cpy) > 0 {\n\t\t_ = reflect.Copy(reflect.ValueOf(cpy), rv)\n\t}\n\treturn cpy\n}\n\n// AsStringSlice converts a string array into a slice into with same elements as array.\nfunc AsStringSlice(v any) []string {\n\trv := reflect.ValueOf(v)\n\tif rv.Type().Kind() != reflect.Array {\n\t\treturn nil\n\t}\n\tcpy := make([]string, rv.Len())\n\tif len(cpy) > 0 {\n\t\t_ = reflect.Copy(reflect.ValueOf(cpy), rv)\n\t}\n\treturn cpy\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/internal/xxhash/xxhash.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package xxhash provides a wrapper around the xxhash library for attribute hashing.\npackage xxhash // import \"go.opentelemetry.io/otel/attribute/internal/xxhash\"\n\nimport (\n\t\"encoding/binary\"\n\t\"math\"\n\n\t\"github.com/cespare/xxhash/v2\"\n)\n\n// Hash wraps xxhash.Digest to provide an API friendly for hashing attribute values.\ntype Hash struct {\n\td *xxhash.Digest\n}\n\n// New returns a new initialized xxHash64 hasher.\nfunc New() Hash {\n\treturn Hash{d: xxhash.New()}\n}\n\nfunc (h Hash) Uint64(val uint64) Hash {\n\tvar buf [8]byte\n\tbinary.LittleEndian.PutUint64(buf[:], val)\n\t// errors from Write are always nil for xxhash\n\t// if it returns an err then panic\n\t_, err := h.d.Write(buf[:])\n\tif err != nil {\n\t\tpanic(\"xxhash write of uint64 failed: \" + err.Error())\n\t}\n\treturn h\n}\n\nfunc (h Hash) Bool(val bool) Hash { // nolint:revive // This is a hashing function.\n\tif val {\n\t\treturn h.Uint64(1)\n\t}\n\treturn h.Uint64(0)\n}\n\nfunc (h Hash) Float64(val float64) Hash {\n\treturn h.Uint64(math.Float64bits(val))\n}\n\nfunc (h Hash) Int64(val int64) Hash {\n\treturn h.Uint64(uint64(val)) // nolint:gosec // Overflow doesn't matter since we are hashing.\n}\n\nfunc (h Hash) String(val string) Hash {\n\t// errors from WriteString are always nil for xxhash\n\t// if it returns an err then panic\n\t_, err := h.d.WriteString(val)\n\tif err != nil {\n\t\tpanic(\"xxhash write of string failed: \" + err.Error())\n\t}\n\treturn h\n}\n\n// Sum64 returns the current hash value.\nfunc (h Hash) Sum64() uint64 {\n\treturn h.d.Sum64()\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/iterator.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n\n// Iterator allows iterating over the set of attributes in order, sorted by\n// key.\ntype Iterator struct {\n\tstorage *Set\n\tidx     int\n}\n\n// MergeIterator supports iterating over two sets of attributes while\n// eliminating duplicate values from the combined set. The first iterator\n// value takes precedence.\ntype MergeIterator struct {\n\tone     oneIterator\n\ttwo     oneIterator\n\tcurrent KeyValue\n}\n\ntype oneIterator struct {\n\titer Iterator\n\tdone bool\n\tattr KeyValue\n}\n\n// Next moves the iterator to the next position.\n// Next reports whether there are more attributes.\nfunc (i *Iterator) Next() bool {\n\ti.idx++\n\treturn i.idx < i.Len()\n}\n\n// Label returns current KeyValue. Must be called only after Next returns\n// true.\n//\n// Deprecated: Use Attribute instead.\nfunc (i *Iterator) Label() KeyValue {\n\treturn i.Attribute()\n}\n\n// Attribute returns the current KeyValue of the Iterator. It must be called\n// only after Next returns true.\nfunc (i *Iterator) Attribute() KeyValue {\n\tkv, _ := i.storage.Get(i.idx)\n\treturn kv\n}\n\n// IndexedLabel returns current index and attribute. Must be called only\n// after Next returns true.\n//\n// Deprecated: Use IndexedAttribute instead.\nfunc (i *Iterator) IndexedLabel() (int, KeyValue) {\n\treturn i.idx, i.Attribute()\n}\n\n// IndexedAttribute returns current index and attribute. Must be called only\n// after Next returns true.\nfunc (i *Iterator) IndexedAttribute() (int, KeyValue) {\n\treturn i.idx, i.Attribute()\n}\n\n// Len returns a number of attributes in the iterated set.\nfunc (i *Iterator) Len() int {\n\treturn i.storage.Len()\n}\n\n// ToSlice is a convenience function that creates a slice of attributes from\n// the passed iterator. The iterator is set up to start from the beginning\n// before creating the slice.\nfunc (i *Iterator) ToSlice() []KeyValue {\n\tl := i.Len()\n\tif l == 0 {\n\t\treturn nil\n\t}\n\ti.idx = -1\n\tslice := make([]KeyValue, 0, l)\n\tfor i.Next() {\n\t\tslice = append(slice, i.Attribute())\n\t}\n\treturn slice\n}\n\n// NewMergeIterator returns a MergeIterator for merging two attribute sets.\n// Duplicates are resolved by taking the value from the first set.\nfunc NewMergeIterator(s1, s2 *Set) MergeIterator {\n\tmi := MergeIterator{\n\t\tone: makeOne(s1.Iter()),\n\t\ttwo: makeOne(s2.Iter()),\n\t}\n\treturn mi\n}\n\nfunc makeOne(iter Iterator) oneIterator {\n\toi := oneIterator{\n\t\titer: iter,\n\t}\n\toi.advance()\n\treturn oi\n}\n\nfunc (oi *oneIterator) advance() {\n\tif oi.done = !oi.iter.Next(); !oi.done {\n\t\toi.attr = oi.iter.Attribute()\n\t}\n}\n\n// Next moves the iterator to the next position.\n// Next reports whether there is another attribute available.\nfunc (m *MergeIterator) Next() bool {\n\tif m.one.done && m.two.done {\n\t\treturn false\n\t}\n\tif m.one.done {\n\t\tm.current = m.two.attr\n\t\tm.two.advance()\n\t\treturn true\n\t}\n\tif m.two.done {\n\t\tm.current = m.one.attr\n\t\tm.one.advance()\n\t\treturn true\n\t}\n\tif m.one.attr.Key == m.two.attr.Key {\n\t\tm.current = m.one.attr // first iterator attribute value wins\n\t\tm.one.advance()\n\t\tm.two.advance()\n\t\treturn true\n\t}\n\tif m.one.attr.Key < m.two.attr.Key {\n\t\tm.current = m.one.attr\n\t\tm.one.advance()\n\t\treturn true\n\t}\n\tm.current = m.two.attr\n\tm.two.advance()\n\treturn true\n}\n\n// Label returns the current value after Next() returns true.\n//\n// Deprecated: Use Attribute instead.\nfunc (m *MergeIterator) Label() KeyValue {\n\treturn m.current\n}\n\n// Attribute returns the current value after Next() returns true.\nfunc (m *MergeIterator) Attribute() KeyValue {\n\treturn m.current\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/key.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n\n// Key represents the key part in key-value pairs. It's a string. The\n// allowed character set in the key depends on the use of the key.\ntype Key string\n\n// Bool creates a KeyValue instance with a BOOL Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- Bool(name, value).\nfunc (k Key) Bool(v bool) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: BoolValue(v),\n\t}\n}\n\n// BoolSlice creates a KeyValue instance with a BOOLSLICE Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- BoolSlice(name, value).\nfunc (k Key) BoolSlice(v []bool) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: BoolSliceValue(v),\n\t}\n}\n\n// Int creates a KeyValue instance with an INT64 Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- Int(name, value).\nfunc (k Key) Int(v int) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: IntValue(v),\n\t}\n}\n\n// IntSlice creates a KeyValue instance with an INT64SLICE Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- IntSlice(name, value).\nfunc (k Key) IntSlice(v []int) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: IntSliceValue(v),\n\t}\n}\n\n// Int64 creates a KeyValue instance with an INT64 Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- Int64(name, value).\nfunc (k Key) Int64(v int64) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: Int64Value(v),\n\t}\n}\n\n// Int64Slice creates a KeyValue instance with an INT64SLICE Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- Int64Slice(name, value).\nfunc (k Key) Int64Slice(v []int64) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: Int64SliceValue(v),\n\t}\n}\n\n// Float64 creates a KeyValue instance with a FLOAT64 Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- Float64(name, value).\nfunc (k Key) Float64(v float64) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: Float64Value(v),\n\t}\n}\n\n// Float64Slice creates a KeyValue instance with a FLOAT64SLICE Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- Float64(name, value).\nfunc (k Key) Float64Slice(v []float64) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: Float64SliceValue(v),\n\t}\n}\n\n// String creates a KeyValue instance with a STRING Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- String(name, value).\nfunc (k Key) String(v string) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: StringValue(v),\n\t}\n}\n\n// StringSlice creates a KeyValue instance with a STRINGSLICE Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- StringSlice(name, value).\nfunc (k Key) StringSlice(v []string) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: StringSliceValue(v),\n\t}\n}\n\n// Defined reports whether the key is not empty.\nfunc (k Key) Defined() bool {\n\treturn len(k) != 0\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/kv.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n\nimport (\n\t\"fmt\"\n)\n\n// KeyValue holds a key and value pair.\ntype KeyValue struct {\n\tKey   Key\n\tValue Value\n}\n\n// Valid reports whether kv is a valid OpenTelemetry attribute.\nfunc (kv KeyValue) Valid() bool {\n\treturn kv.Key.Defined() && kv.Value.Type() != INVALID\n}\n\n// Bool creates a KeyValue with a BOOL Value type.\nfunc Bool(k string, v bool) KeyValue {\n\treturn Key(k).Bool(v)\n}\n\n// BoolSlice creates a KeyValue with a BOOLSLICE Value type.\nfunc BoolSlice(k string, v []bool) KeyValue {\n\treturn Key(k).BoolSlice(v)\n}\n\n// Int creates a KeyValue with an INT64 Value type.\nfunc Int(k string, v int) KeyValue {\n\treturn Key(k).Int(v)\n}\n\n// IntSlice creates a KeyValue with an INT64SLICE Value type.\nfunc IntSlice(k string, v []int) KeyValue {\n\treturn Key(k).IntSlice(v)\n}\n\n// Int64 creates a KeyValue with an INT64 Value type.\nfunc Int64(k string, v int64) KeyValue {\n\treturn Key(k).Int64(v)\n}\n\n// Int64Slice creates a KeyValue with an INT64SLICE Value type.\nfunc Int64Slice(k string, v []int64) KeyValue {\n\treturn Key(k).Int64Slice(v)\n}\n\n// Float64 creates a KeyValue with a FLOAT64 Value type.\nfunc Float64(k string, v float64) KeyValue {\n\treturn Key(k).Float64(v)\n}\n\n// Float64Slice creates a KeyValue with a FLOAT64SLICE Value type.\nfunc Float64Slice(k string, v []float64) KeyValue {\n\treturn Key(k).Float64Slice(v)\n}\n\n// String creates a KeyValue with a STRING Value type.\nfunc String(k, v string) KeyValue {\n\treturn Key(k).String(v)\n}\n\n// StringSlice creates a KeyValue with a STRINGSLICE Value type.\nfunc StringSlice(k string, v []string) KeyValue {\n\treturn Key(k).StringSlice(v)\n}\n\n// Stringer creates a new key-value pair with a passed name and a string\n// value generated by the passed Stringer interface.\nfunc Stringer(k string, v fmt.Stringer) KeyValue {\n\treturn Key(k).String(v.String())\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/rawhelpers.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n\nimport (\n\t\"math\"\n)\n\nfunc boolToRaw(b bool) uint64 { // nolint:revive  // b is not a control flag.\n\tif b {\n\t\treturn 1\n\t}\n\treturn 0\n}\n\nfunc rawToBool(r uint64) bool {\n\treturn r != 0\n}\n\nfunc int64ToRaw(i int64) uint64 {\n\t// Assumes original was a valid int64 (overflow not checked).\n\treturn uint64(i) // nolint: gosec\n}\n\nfunc rawToInt64(r uint64) int64 {\n\t// Assumes original was a valid int64 (overflow not checked).\n\treturn int64(r) // nolint: gosec\n}\n\nfunc float64ToRaw(f float64) uint64 {\n\treturn math.Float64bits(f)\n}\n\nfunc rawToFloat64(r uint64) float64 {\n\treturn math.Float64frombits(r)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/set.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n\nimport (\n\t\"cmp\"\n\t\"encoding/json\"\n\t\"reflect\"\n\t\"slices\"\n\t\"sort\"\n\n\t\"go.opentelemetry.io/otel/attribute/internal/xxhash\"\n)\n\ntype (\n\t// Set is the representation for a distinct attribute set. It manages an\n\t// immutable set of attributes, with an internal cache for storing\n\t// attribute encodings.\n\t//\n\t// This type will remain comparable for backwards compatibility. The\n\t// equivalence of Sets across versions is not guaranteed to be stable.\n\t// Prior versions may find two Sets to be equal or not when compared\n\t// directly (i.e. ==), but subsequent versions may not. Users should use\n\t// the Equals method to ensure stable equivalence checking.\n\t//\n\t// Users should also use the Distinct returned from Equivalent as a map key\n\t// instead of a Set directly. Set has relatively poor performance when used\n\t// as a map key compared to Distinct.\n\tSet struct {\n\t\thash uint64\n\t\tdata any\n\t}\n\n\t// Distinct is an identifier of a Set which is very likely to be unique.\n\t//\n\t// Distinct should be used as a map key instead of a Set for to provide better\n\t// performance for map operations.\n\tDistinct struct {\n\t\thash uint64\n\t}\n\n\t// Sortable implements sort.Interface, used for sorting KeyValue.\n\t//\n\t// Deprecated: This type is no longer used. It was added as a performance\n\t// optimization for Go < 1.21 that is no longer needed (Go < 1.21 is no\n\t// longer supported by the module).\n\tSortable []KeyValue\n)\n\n// Compile time check these types remain comparable.\nvar (\n\t_ = isComparable(Set{})\n\t_ = isComparable(Distinct{})\n)\n\nfunc isComparable[T comparable](t T) T { return t }\n\nvar (\n\t// keyValueType is used in computeDistinctReflect.\n\tkeyValueType = reflect.TypeFor[KeyValue]()\n\n\t// emptyHash is the hash of an empty set.\n\temptyHash = xxhash.New().Sum64()\n\n\t// userDefinedEmptySet is an empty set. It was mistakenly exposed to users\n\t// as something they can assign to, so it must remain addressable and\n\t// mutable.\n\t//\n\t// This is kept for backwards compatibility, but should not be used in new code.\n\tuserDefinedEmptySet = &Set{\n\t\thash: emptyHash,\n\t\tdata: [0]KeyValue{},\n\t}\n\n\temptySet = Set{\n\t\thash: emptyHash,\n\t\tdata: [0]KeyValue{},\n\t}\n)\n\n// EmptySet returns a reference to a Set with no elements.\n//\n// This is a convenience provided for optimized calling utility.\nfunc EmptySet() *Set {\n\t// Continue to return the pointer to the user-defined empty set for\n\t// backwards-compatibility.\n\t//\n\t// New code should not use this, instead use emptySet.\n\treturn userDefinedEmptySet\n}\n\n// Valid reports whether this value refers to a valid Set.\nfunc (d Distinct) Valid() bool { return d.hash != 0 }\n\n// reflectValue abbreviates reflect.ValueOf(d).\nfunc (l Set) reflectValue() reflect.Value {\n\treturn reflect.ValueOf(l.data)\n}\n\n// Len returns the number of attributes in this set.\nfunc (l *Set) Len() int {\n\tif l == nil || l.hash == 0 {\n\t\treturn 0\n\t}\n\treturn l.reflectValue().Len()\n}\n\n// Get returns the KeyValue at ordered position idx in this set.\nfunc (l *Set) Get(idx int) (KeyValue, bool) {\n\tif l == nil || l.hash == 0 {\n\t\treturn KeyValue{}, false\n\t}\n\tvalue := l.reflectValue()\n\n\tif idx >= 0 && idx < value.Len() {\n\t\t// Note: The Go compiler successfully avoids an allocation for\n\t\t// the interface{} conversion here:\n\t\treturn value.Index(idx).Interface().(KeyValue), true\n\t}\n\n\treturn KeyValue{}, false\n}\n\n// Value returns the value of a specified key in this set.\nfunc (l *Set) Value(k Key) (Value, bool) {\n\tif l == nil || l.hash == 0 {\n\t\treturn Value{}, false\n\t}\n\trValue := l.reflectValue()\n\tvlen := rValue.Len()\n\n\tidx := sort.Search(vlen, func(idx int) bool {\n\t\treturn rValue.Index(idx).Interface().(KeyValue).Key >= k\n\t})\n\tif idx >= vlen {\n\t\treturn Value{}, false\n\t}\n\tkeyValue := rValue.Index(idx).Interface().(KeyValue)\n\tif k == keyValue.Key {\n\t\treturn keyValue.Value, true\n\t}\n\treturn Value{}, false\n}\n\n// HasValue reports whether a key is defined in this set.\nfunc (l *Set) HasValue(k Key) bool {\n\tif l == nil {\n\t\treturn false\n\t}\n\t_, ok := l.Value(k)\n\treturn ok\n}\n\n// Iter returns an iterator for visiting the attributes in this set.\nfunc (l *Set) Iter() Iterator {\n\treturn Iterator{\n\t\tstorage: l,\n\t\tidx:     -1,\n\t}\n}\n\n// ToSlice returns the set of attributes belonging to this set, sorted, where\n// keys appear no more than once.\nfunc (l *Set) ToSlice() []KeyValue {\n\titer := l.Iter()\n\treturn iter.ToSlice()\n}\n\n// Equivalent returns a value that may be used as a map key. Equal Distinct\n// values are very likely to be equivalent attribute Sets. Distinct value of any\n// attribute set with the same elements as this, where sets are made unique by\n// choosing the last value in the input for any given key.\nfunc (l *Set) Equivalent() Distinct {\n\tif l == nil || l.hash == 0 {\n\t\treturn Distinct{hash: emptySet.hash}\n\t}\n\treturn Distinct{hash: l.hash}\n}\n\n// Equals reports whether the argument set is equivalent to this set.\nfunc (l *Set) Equals(o *Set) bool {\n\tif l.Equivalent() != o.Equivalent() {\n\t\treturn false\n\t}\n\tif l == nil || l.hash == 0 {\n\t\tl = &emptySet\n\t}\n\tif o == nil || o.hash == 0 {\n\t\to = &emptySet\n\t}\n\treturn l.data == o.data\n}\n\n// Encoded returns the encoded form of this set, according to encoder.\nfunc (l *Set) Encoded(encoder Encoder) string {\n\tif l == nil || encoder == nil {\n\t\treturn \"\"\n\t}\n\n\treturn encoder.Encode(l.Iter())\n}\n\n// NewSet returns a new Set. See the documentation for\n// NewSetWithSortableFiltered for more details.\n//\n// Except for empty sets, this method adds an additional allocation compared\n// with calls that include a Sortable.\nfunc NewSet(kvs ...KeyValue) Set {\n\ts, _ := NewSetWithFiltered(kvs, nil)\n\treturn s\n}\n\n// NewSetWithSortable returns a new Set. See the documentation for\n// NewSetWithSortableFiltered for more details.\n//\n// This call includes a Sortable option as a memory optimization.\n//\n// Deprecated: Use [NewSet] instead.\nfunc NewSetWithSortable(kvs []KeyValue, _ *Sortable) Set {\n\ts, _ := NewSetWithFiltered(kvs, nil)\n\treturn s\n}\n\n// NewSetWithFiltered returns a new Set. See the documentation for\n// NewSetWithSortableFiltered for more details.\n//\n// This call includes a Filter to include/exclude attribute keys from the\n// return value. Excluded keys are returned as a slice of attribute values.\nfunc NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) {\n\t// Check for empty set.\n\tif len(kvs) == 0 {\n\t\treturn emptySet, nil\n\t}\n\n\t// Stable sort so the following de-duplication can implement\n\t// last-value-wins semantics.\n\tslices.SortStableFunc(kvs, func(a, b KeyValue) int {\n\t\treturn cmp.Compare(a.Key, b.Key)\n\t})\n\n\tposition := len(kvs) - 1\n\toffset := position - 1\n\n\t// The requirements stated above require that the stable\n\t// result be placed in the end of the input slice, while\n\t// overwritten values are swapped to the beginning.\n\t//\n\t// De-duplicate with last-value-wins semantics.  Preserve\n\t// duplicate values at the beginning of the input slice.\n\tfor ; offset >= 0; offset-- {\n\t\tif kvs[offset].Key == kvs[position].Key {\n\t\t\tcontinue\n\t\t}\n\t\tposition--\n\t\tkvs[offset], kvs[position] = kvs[position], kvs[offset]\n\t}\n\tkvs = kvs[position:]\n\n\tif filter != nil {\n\t\tif div := filteredToFront(kvs, filter); div != 0 {\n\t\t\treturn newSet(kvs[div:]), kvs[:div]\n\t\t}\n\t}\n\treturn newSet(kvs), nil\n}\n\n// NewSetWithSortableFiltered returns a new Set.\n//\n// Duplicate keys are eliminated by taking the last value.  This\n// re-orders the input slice so that unique last-values are contiguous\n// at the end of the slice.\n//\n// This ensures the following:\n//\n// - Last-value-wins semantics\n// - Caller sees the reordering, but doesn't lose values\n// - Repeated call preserve last-value wins.\n//\n// Note that methods are defined on Set, although this returns Set. Callers\n// can avoid memory allocations by:\n//\n// - allocating a Sortable for use as a temporary in this method\n// - allocating a Set for storing the return value of this constructor.\n//\n// The result maintains a cache of encoded attributes, by attribute.EncoderID.\n// This value should not be copied after its first use.\n//\n// The second []KeyValue return value is a list of attributes that were\n// excluded by the Filter (if non-nil).\n//\n// Deprecated: Use [NewSetWithFiltered] instead.\nfunc NewSetWithSortableFiltered(kvs []KeyValue, _ *Sortable, filter Filter) (Set, []KeyValue) {\n\treturn NewSetWithFiltered(kvs, filter)\n}\n\n// filteredToFront filters slice in-place using keep function. All KeyValues that need to\n// be removed are moved to the front. All KeyValues that need to be kept are\n// moved (in-order) to the back. The index for the first KeyValue to be kept is\n// returned.\nfunc filteredToFront(slice []KeyValue, keep Filter) int {\n\tn := len(slice)\n\tj := n\n\tfor i := n - 1; i >= 0; i-- {\n\t\tif keep(slice[i]) {\n\t\t\tj--\n\t\t\tslice[i], slice[j] = slice[j], slice[i]\n\t\t}\n\t}\n\treturn j\n}\n\n// Filter returns a filtered copy of this Set. See the documentation for\n// NewSetWithSortableFiltered for more details.\nfunc (l *Set) Filter(re Filter) (Set, []KeyValue) {\n\tif re == nil {\n\t\treturn *l, nil\n\t}\n\n\t// Iterate in reverse to the first attribute that will be filtered out.\n\tn := l.Len()\n\tfirst := n - 1\n\tfor ; first >= 0; first-- {\n\t\tkv, _ := l.Get(first)\n\t\tif !re(kv) {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// No attributes will be dropped, return the immutable Set l and nil.\n\tif first < 0 {\n\t\treturn *l, nil\n\t}\n\n\t// Copy now that we know we need to return a modified set.\n\t//\n\t// Do not do this in-place on the underlying storage of *Set l. Sets are\n\t// immutable and filtering should not change this.\n\tslice := l.ToSlice()\n\n\t// Don't re-iterate the slice if only slice[0] is filtered.\n\tif first == 0 {\n\t\t// It is safe to assume len(slice) >= 1 given we found at least one\n\t\t// attribute above that needs to be filtered out.\n\t\treturn newSet(slice[1:]), slice[:1]\n\t}\n\n\t// Move the filtered slice[first] to the front (preserving order).\n\tkv := slice[first]\n\tcopy(slice[1:first+1], slice[:first])\n\tslice[0] = kv\n\n\t// Do not re-evaluate re(slice[first+1:]).\n\tdiv := filteredToFront(slice[1:first+1], re) + 1\n\treturn newSet(slice[div:]), slice[:div]\n}\n\n// newSet returns a new set based on the sorted and uniqued kvs.\nfunc newSet(kvs []KeyValue) Set {\n\ts := Set{\n\t\thash: hashKVs(kvs),\n\t\tdata: computeDataFixed(kvs),\n\t}\n\tif s.data == nil {\n\t\ts.data = computeDataReflect(kvs)\n\t}\n\treturn s\n}\n\n// computeDataFixed computes a Set data for small slices. It returns nil if the\n// input is too large for this code path.\nfunc computeDataFixed(kvs []KeyValue) any {\n\tswitch len(kvs) {\n\tcase 1:\n\t\treturn [1]KeyValue(kvs)\n\tcase 2:\n\t\treturn [2]KeyValue(kvs)\n\tcase 3:\n\t\treturn [3]KeyValue(kvs)\n\tcase 4:\n\t\treturn [4]KeyValue(kvs)\n\tcase 5:\n\t\treturn [5]KeyValue(kvs)\n\tcase 6:\n\t\treturn [6]KeyValue(kvs)\n\tcase 7:\n\t\treturn [7]KeyValue(kvs)\n\tcase 8:\n\t\treturn [8]KeyValue(kvs)\n\tcase 9:\n\t\treturn [9]KeyValue(kvs)\n\tcase 10:\n\t\treturn [10]KeyValue(kvs)\n\tdefault:\n\t\treturn nil\n\t}\n}\n\n// computeDataReflect computes a Set data using reflection, works for any size\n// input.\nfunc computeDataReflect(kvs []KeyValue) any {\n\tat := reflect.New(reflect.ArrayOf(len(kvs), keyValueType)).Elem()\n\tfor i, keyValue := range kvs {\n\t\t*(at.Index(i).Addr().Interface().(*KeyValue)) = keyValue\n\t}\n\treturn at.Interface()\n}\n\n// MarshalJSON returns the JSON encoding of the Set.\nfunc (l *Set) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(l.data)\n}\n\n// MarshalLog is the marshaling function used by the logging system to represent this Set.\nfunc (l Set) MarshalLog() any {\n\tkvs := make(map[string]string)\n\tfor _, kv := range l.ToSlice() {\n\t\tkvs[string(kv.Key)] = kv.Value.Emit()\n\t}\n\treturn kvs\n}\n\n// Len implements sort.Interface.\nfunc (l *Sortable) Len() int {\n\treturn len(*l)\n}\n\n// Swap implements sort.Interface.\nfunc (l *Sortable) Swap(i, j int) {\n\t(*l)[i], (*l)[j] = (*l)[j], (*l)[i]\n}\n\n// Less implements sort.Interface.\nfunc (l *Sortable) Less(i, j int) bool {\n\treturn (*l)[i].Key < (*l)[j].Key\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/type_string.go",
    "content": "// Code generated by \"stringer -type=Type\"; DO NOT EDIT.\n\npackage attribute\n\nimport \"strconv\"\n\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[INVALID-0]\n\t_ = x[BOOL-1]\n\t_ = x[INT64-2]\n\t_ = x[FLOAT64-3]\n\t_ = x[STRING-4]\n\t_ = x[BOOLSLICE-5]\n\t_ = x[INT64SLICE-6]\n\t_ = x[FLOAT64SLICE-7]\n\t_ = x[STRINGSLICE-8]\n}\n\nconst _Type_name = \"INVALIDBOOLINT64FLOAT64STRINGBOOLSLICEINT64SLICEFLOAT64SLICESTRINGSLICE\"\n\nvar _Type_index = [...]uint8{0, 7, 11, 16, 23, 29, 38, 48, 60, 71}\n\nfunc (i Type) String() string {\n\tidx := int(i) - 0\n\tif i < 0 || idx >= len(_Type_index)-1 {\n\t\treturn \"Type(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _Type_name[_Type_index[idx]:_Type_index[idx+1]]\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/value.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n\n\tattribute \"go.opentelemetry.io/otel/attribute/internal\"\n)\n\n//go:generate stringer -type=Type\n\n// Type describes the type of the data Value holds.\ntype Type int // nolint: revive  // redefines builtin Type.\n\n// Value represents the value part in key-value pairs.\ntype Value struct {\n\tvtype    Type\n\tnumeric  uint64\n\tstringly string\n\tslice    any\n}\n\nconst (\n\t// INVALID is used for a Value with no value set.\n\tINVALID Type = iota\n\t// BOOL is a boolean Type Value.\n\tBOOL\n\t// INT64 is a 64-bit signed integral Type Value.\n\tINT64\n\t// FLOAT64 is a 64-bit floating point Type Value.\n\tFLOAT64\n\t// STRING is a string Type Value.\n\tSTRING\n\t// BOOLSLICE is a slice of booleans Type Value.\n\tBOOLSLICE\n\t// INT64SLICE is a slice of 64-bit signed integral numbers Type Value.\n\tINT64SLICE\n\t// FLOAT64SLICE is a slice of 64-bit floating point numbers Type Value.\n\tFLOAT64SLICE\n\t// STRINGSLICE is a slice of strings Type Value.\n\tSTRINGSLICE\n)\n\n// BoolValue creates a BOOL Value.\nfunc BoolValue(v bool) Value {\n\treturn Value{\n\t\tvtype:   BOOL,\n\t\tnumeric: boolToRaw(v),\n\t}\n}\n\n// BoolSliceValue creates a BOOLSLICE Value.\nfunc BoolSliceValue(v []bool) Value {\n\treturn Value{vtype: BOOLSLICE, slice: attribute.BoolSliceValue(v)}\n}\n\n// IntValue creates an INT64 Value.\nfunc IntValue(v int) Value {\n\treturn Int64Value(int64(v))\n}\n\n// IntSliceValue creates an INTSLICE Value.\nfunc IntSliceValue(v []int) Value {\n\tcp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeFor[int64]()))\n\tfor i, val := range v {\n\t\tcp.Elem().Index(i).SetInt(int64(val))\n\t}\n\treturn Value{\n\t\tvtype: INT64SLICE,\n\t\tslice: cp.Elem().Interface(),\n\t}\n}\n\n// Int64Value creates an INT64 Value.\nfunc Int64Value(v int64) Value {\n\treturn Value{\n\t\tvtype:   INT64,\n\t\tnumeric: int64ToRaw(v),\n\t}\n}\n\n// Int64SliceValue creates an INT64SLICE Value.\nfunc Int64SliceValue(v []int64) Value {\n\treturn Value{vtype: INT64SLICE, slice: attribute.Int64SliceValue(v)}\n}\n\n// Float64Value creates a FLOAT64 Value.\nfunc Float64Value(v float64) Value {\n\treturn Value{\n\t\tvtype:   FLOAT64,\n\t\tnumeric: float64ToRaw(v),\n\t}\n}\n\n// Float64SliceValue creates a FLOAT64SLICE Value.\nfunc Float64SliceValue(v []float64) Value {\n\treturn Value{vtype: FLOAT64SLICE, slice: attribute.Float64SliceValue(v)}\n}\n\n// StringValue creates a STRING Value.\nfunc StringValue(v string) Value {\n\treturn Value{\n\t\tvtype:    STRING,\n\t\tstringly: v,\n\t}\n}\n\n// StringSliceValue creates a STRINGSLICE Value.\nfunc StringSliceValue(v []string) Value {\n\treturn Value{vtype: STRINGSLICE, slice: attribute.StringSliceValue(v)}\n}\n\n// Type returns a type of the Value.\nfunc (v Value) Type() Type {\n\treturn v.vtype\n}\n\n// AsBool returns the bool value. Make sure that the Value's type is\n// BOOL.\nfunc (v Value) AsBool() bool {\n\treturn rawToBool(v.numeric)\n}\n\n// AsBoolSlice returns the []bool value. Make sure that the Value's type is\n// BOOLSLICE.\nfunc (v Value) AsBoolSlice() []bool {\n\tif v.vtype != BOOLSLICE {\n\t\treturn nil\n\t}\n\treturn v.asBoolSlice()\n}\n\nfunc (v Value) asBoolSlice() []bool {\n\treturn attribute.AsBoolSlice(v.slice)\n}\n\n// AsInt64 returns the int64 value. Make sure that the Value's type is\n// INT64.\nfunc (v Value) AsInt64() int64 {\n\treturn rawToInt64(v.numeric)\n}\n\n// AsInt64Slice returns the []int64 value. Make sure that the Value's type is\n// INT64SLICE.\nfunc (v Value) AsInt64Slice() []int64 {\n\tif v.vtype != INT64SLICE {\n\t\treturn nil\n\t}\n\treturn v.asInt64Slice()\n}\n\nfunc (v Value) asInt64Slice() []int64 {\n\treturn attribute.AsInt64Slice(v.slice)\n}\n\n// AsFloat64 returns the float64 value. Make sure that the Value's\n// type is FLOAT64.\nfunc (v Value) AsFloat64() float64 {\n\treturn rawToFloat64(v.numeric)\n}\n\n// AsFloat64Slice returns the []float64 value. Make sure that the Value's type is\n// FLOAT64SLICE.\nfunc (v Value) AsFloat64Slice() []float64 {\n\tif v.vtype != FLOAT64SLICE {\n\t\treturn nil\n\t}\n\treturn v.asFloat64Slice()\n}\n\nfunc (v Value) asFloat64Slice() []float64 {\n\treturn attribute.AsFloat64Slice(v.slice)\n}\n\n// AsString returns the string value. Make sure that the Value's type\n// is STRING.\nfunc (v Value) AsString() string {\n\treturn v.stringly\n}\n\n// AsStringSlice returns the []string value. Make sure that the Value's type is\n// STRINGSLICE.\nfunc (v Value) AsStringSlice() []string {\n\tif v.vtype != STRINGSLICE {\n\t\treturn nil\n\t}\n\treturn v.asStringSlice()\n}\n\nfunc (v Value) asStringSlice() []string {\n\treturn attribute.AsStringSlice(v.slice)\n}\n\ntype unknownValueType struct{}\n\n// AsInterface returns Value's data as any.\nfunc (v Value) AsInterface() any {\n\tswitch v.Type() {\n\tcase BOOL:\n\t\treturn v.AsBool()\n\tcase BOOLSLICE:\n\t\treturn v.asBoolSlice()\n\tcase INT64:\n\t\treturn v.AsInt64()\n\tcase INT64SLICE:\n\t\treturn v.asInt64Slice()\n\tcase FLOAT64:\n\t\treturn v.AsFloat64()\n\tcase FLOAT64SLICE:\n\t\treturn v.asFloat64Slice()\n\tcase STRING:\n\t\treturn v.stringly\n\tcase STRINGSLICE:\n\t\treturn v.asStringSlice()\n\t}\n\treturn unknownValueType{}\n}\n\n// Emit returns a string representation of Value's data.\nfunc (v Value) Emit() string {\n\tswitch v.Type() {\n\tcase BOOLSLICE:\n\t\treturn fmt.Sprint(v.asBoolSlice())\n\tcase BOOL:\n\t\treturn strconv.FormatBool(v.AsBool())\n\tcase INT64SLICE:\n\t\tj, err := json.Marshal(v.asInt64Slice())\n\t\tif err != nil {\n\t\t\treturn fmt.Sprintf(\"invalid: %v\", v.asInt64Slice())\n\t\t}\n\t\treturn string(j)\n\tcase INT64:\n\t\treturn strconv.FormatInt(v.AsInt64(), 10)\n\tcase FLOAT64SLICE:\n\t\tj, err := json.Marshal(v.asFloat64Slice())\n\t\tif err != nil {\n\t\t\treturn fmt.Sprintf(\"invalid: %v\", v.asFloat64Slice())\n\t\t}\n\t\treturn string(j)\n\tcase FLOAT64:\n\t\treturn fmt.Sprint(v.AsFloat64())\n\tcase STRINGSLICE:\n\t\tj, err := json.Marshal(v.asStringSlice())\n\t\tif err != nil {\n\t\t\treturn fmt.Sprintf(\"invalid: %v\", v.asStringSlice())\n\t\t}\n\t\treturn string(j)\n\tcase STRING:\n\t\treturn v.stringly\n\tdefault:\n\t\treturn \"unknown\"\n\t}\n}\n\n// MarshalJSON returns the JSON encoding of the Value.\nfunc (v Value) MarshalJSON() ([]byte, error) {\n\tvar jsonVal struct {\n\t\tType  string\n\t\tValue any\n\t}\n\tjsonVal.Type = v.Type().String()\n\tjsonVal.Value = v.AsInterface()\n\treturn json.Marshal(jsonVal)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/baggage/README.md",
    "content": "# Baggage\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/baggage)](https://pkg.go.dev/go.opentelemetry.io/otel/baggage)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/baggage/baggage.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage baggage // import \"go.opentelemetry.io/otel/baggage\"\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"go.opentelemetry.io/otel/internal/baggage\"\n)\n\nconst (\n\tmaxMembers               = 180\n\tmaxBytesPerMembers       = 4096\n\tmaxBytesPerBaggageString = 8192\n\n\tlistDelimiter     = \",\"\n\tkeyValueDelimiter = \"=\"\n\tpropertyDelimiter = \";\"\n)\n\nvar (\n\terrInvalidKey      = errors.New(\"invalid key\")\n\terrInvalidValue    = errors.New(\"invalid value\")\n\terrInvalidProperty = errors.New(\"invalid baggage list-member property\")\n\terrInvalidMember   = errors.New(\"invalid baggage list-member\")\n\terrMemberNumber    = errors.New(\"too many list-members in baggage-string\")\n\terrMemberBytes     = errors.New(\"list-member too large\")\n\terrBaggageBytes    = errors.New(\"baggage-string too large\")\n)\n\n// Property is an additional metadata entry for a baggage list-member.\ntype Property struct {\n\tkey, value string\n\n\t// hasValue indicates if a zero-value value means the property does not\n\t// have a value or if it was the zero-value.\n\thasValue bool\n}\n\n// NewKeyProperty returns a new Property for key.\n//\n// The passed key must be valid, non-empty UTF-8 string.\n// If key is invalid, an error will be returned.\n// However, the specific Propagators that are used to transmit baggage entries across\n// component boundaries may impose their own restrictions on Property key.\n// For example, the W3C Baggage specification restricts the Property keys to strings that\n// satisfy the token definition from RFC7230, Section 3.2.6.\n// For maximum compatibility, alphanumeric value are strongly recommended to be used as Property key.\nfunc NewKeyProperty(key string) (Property, error) {\n\tif !validateBaggageName(key) {\n\t\treturn newInvalidProperty(), fmt.Errorf(\"%w: %q\", errInvalidKey, key)\n\t}\n\n\tp := Property{key: key}\n\treturn p, nil\n}\n\n// NewKeyValueProperty returns a new Property for key with value.\n//\n// The passed key must be compliant with W3C Baggage specification.\n// The passed value must be percent-encoded as defined in W3C Baggage specification.\n//\n// Notice: Consider using [NewKeyValuePropertyRaw] instead\n// that does not require percent-encoding of the value.\nfunc NewKeyValueProperty(key, value string) (Property, error) {\n\tif !validateKey(key) {\n\t\treturn newInvalidProperty(), fmt.Errorf(\"%w: %q\", errInvalidKey, key)\n\t}\n\n\tif !validateValue(value) {\n\t\treturn newInvalidProperty(), fmt.Errorf(\"%w: %q\", errInvalidValue, value)\n\t}\n\tdecodedValue, err := url.PathUnescape(value)\n\tif err != nil {\n\t\treturn newInvalidProperty(), fmt.Errorf(\"%w: %q\", errInvalidValue, value)\n\t}\n\treturn NewKeyValuePropertyRaw(key, decodedValue)\n}\n\n// NewKeyValuePropertyRaw returns a new Property for key with value.\n//\n// The passed key must be valid, non-empty UTF-8 string.\n// The passed value must be valid UTF-8 string.\n// However, the specific Propagators that are used to transmit baggage entries across\n// component boundaries may impose their own restrictions on Property key.\n// For example, the W3C Baggage specification restricts the Property keys to strings that\n// satisfy the token definition from RFC7230, Section 3.2.6.\n// For maximum compatibility, alphanumeric value are strongly recommended to be used as Property key.\nfunc NewKeyValuePropertyRaw(key, value string) (Property, error) {\n\tif !validateBaggageName(key) {\n\t\treturn newInvalidProperty(), fmt.Errorf(\"%w: %q\", errInvalidKey, key)\n\t}\n\tif !validateBaggageValue(value) {\n\t\treturn newInvalidProperty(), fmt.Errorf(\"%w: %q\", errInvalidValue, value)\n\t}\n\n\tp := Property{\n\t\tkey:      key,\n\t\tvalue:    value,\n\t\thasValue: true,\n\t}\n\treturn p, nil\n}\n\nfunc newInvalidProperty() Property {\n\treturn Property{}\n}\n\n// parseProperty attempts to decode a Property from the passed string. It\n// returns an error if the input is invalid according to the W3C Baggage\n// specification.\nfunc parseProperty(property string) (Property, error) {\n\tif property == \"\" {\n\t\treturn newInvalidProperty(), nil\n\t}\n\n\tp, ok := parsePropertyInternal(property)\n\tif !ok {\n\t\treturn newInvalidProperty(), fmt.Errorf(\"%w: %q\", errInvalidProperty, property)\n\t}\n\n\treturn p, nil\n}\n\n// validate ensures p conforms to the W3C Baggage specification, returning an\n// error otherwise.\nfunc (p Property) validate() error {\n\terrFunc := func(err error) error {\n\t\treturn fmt.Errorf(\"invalid property: %w\", err)\n\t}\n\n\tif !validateBaggageName(p.key) {\n\t\treturn errFunc(fmt.Errorf(\"%w: %q\", errInvalidKey, p.key))\n\t}\n\tif !p.hasValue && p.value != \"\" {\n\t\treturn errFunc(errors.New(\"inconsistent value\"))\n\t}\n\tif p.hasValue && !validateBaggageValue(p.value) {\n\t\treturn errFunc(fmt.Errorf(\"%w: %q\", errInvalidValue, p.value))\n\t}\n\treturn nil\n}\n\n// Key returns the Property key.\nfunc (p Property) Key() string {\n\treturn p.key\n}\n\n// Value returns the Property value. Additionally, a boolean value is returned\n// indicating if the returned value is the empty if the Property has a value\n// that is empty or if the value is not set.\nfunc (p Property) Value() (string, bool) {\n\treturn p.value, p.hasValue\n}\n\n// String encodes Property into a header string compliant with the W3C Baggage\n// specification.\n// It would return empty string if the key is invalid with the W3C Baggage\n// specification. This could happen for a UTF-8 key, as it may contain\n// invalid characters.\nfunc (p Property) String() string {\n\t//  W3C Baggage specification does not allow percent-encoded keys.\n\tif !validateKey(p.key) {\n\t\treturn \"\"\n\t}\n\n\tif p.hasValue {\n\t\treturn fmt.Sprintf(\"%s%s%v\", p.key, keyValueDelimiter, valueEscape(p.value))\n\t}\n\treturn p.key\n}\n\ntype properties []Property\n\nfunc fromInternalProperties(iProps []baggage.Property) properties {\n\tif len(iProps) == 0 {\n\t\treturn nil\n\t}\n\n\tprops := make(properties, len(iProps))\n\tfor i, p := range iProps {\n\t\tprops[i] = Property{\n\t\t\tkey:      p.Key,\n\t\t\tvalue:    p.Value,\n\t\t\thasValue: p.HasValue,\n\t\t}\n\t}\n\treturn props\n}\n\nfunc (p properties) asInternal() []baggage.Property {\n\tif len(p) == 0 {\n\t\treturn nil\n\t}\n\n\tiProps := make([]baggage.Property, len(p))\n\tfor i, prop := range p {\n\t\tiProps[i] = baggage.Property{\n\t\t\tKey:      prop.key,\n\t\t\tValue:    prop.value,\n\t\t\tHasValue: prop.hasValue,\n\t\t}\n\t}\n\treturn iProps\n}\n\nfunc (p properties) Copy() properties {\n\tif len(p) == 0 {\n\t\treturn nil\n\t}\n\n\tprops := make(properties, len(p))\n\tcopy(props, p)\n\treturn props\n}\n\n// validate ensures each Property in p conforms to the W3C Baggage\n// specification, returning an error otherwise.\nfunc (p properties) validate() error {\n\tfor _, prop := range p {\n\t\tif err := prop.validate(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// String encodes properties into a header string compliant with the W3C Baggage\n// specification.\nfunc (p properties) String() string {\n\tprops := make([]string, 0, len(p))\n\tfor _, prop := range p {\n\t\ts := prop.String()\n\n\t\t// Ignored empty properties.\n\t\tif s != \"\" {\n\t\t\tprops = append(props, s)\n\t\t}\n\t}\n\treturn strings.Join(props, propertyDelimiter)\n}\n\n// Member is a list-member of a baggage-string as defined by the W3C Baggage\n// specification.\ntype Member struct {\n\tkey, value string\n\tproperties properties\n\n\t// hasData indicates whether the created property contains data or not.\n\t// Properties that do not contain data are invalid with no other check\n\t// required.\n\thasData bool\n}\n\n// NewMember returns a new Member from the passed arguments.\n//\n// The passed key must be compliant with W3C Baggage specification.\n// The passed value must be percent-encoded as defined in W3C Baggage specification.\n//\n// Notice: Consider using [NewMemberRaw] instead\n// that does not require percent-encoding of the value.\nfunc NewMember(key, value string, props ...Property) (Member, error) {\n\tif !validateKey(key) {\n\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %q\", errInvalidKey, key)\n\t}\n\n\tif !validateValue(value) {\n\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %q\", errInvalidValue, value)\n\t}\n\tdecodedValue, err := url.PathUnescape(value)\n\tif err != nil {\n\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %q\", errInvalidValue, value)\n\t}\n\treturn NewMemberRaw(key, decodedValue, props...)\n}\n\n// NewMemberRaw returns a new Member from the passed arguments.\n//\n// The passed key must be valid, non-empty UTF-8 string.\n// The passed value must be valid UTF-8 string.\n// However, the specific Propagators that are used to transmit baggage entries across\n// component boundaries may impose their own restrictions on baggage key.\n// For example, the W3C Baggage specification restricts the baggage keys to strings that\n// satisfy the token definition from RFC7230, Section 3.2.6.\n// For maximum compatibility, alphanumeric value are strongly recommended to be used as baggage key.\nfunc NewMemberRaw(key, value string, props ...Property) (Member, error) {\n\tm := Member{\n\t\tkey:        key,\n\t\tvalue:      value,\n\t\tproperties: properties(props).Copy(),\n\t\thasData:    true,\n\t}\n\tif err := m.validate(); err != nil {\n\t\treturn newInvalidMember(), err\n\t}\n\treturn m, nil\n}\n\nfunc newInvalidMember() Member {\n\treturn Member{}\n}\n\n// parseMember attempts to decode a Member from the passed string. It returns\n// an error if the input is invalid according to the W3C Baggage\n// specification.\nfunc parseMember(member string) (Member, error) {\n\tif n := len(member); n > maxBytesPerMembers {\n\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %d\", errMemberBytes, n)\n\t}\n\n\tvar props properties\n\tkeyValue, properties, found := strings.Cut(member, propertyDelimiter)\n\tif found {\n\t\t// Parse the member properties.\n\t\tfor pStr := range strings.SplitSeq(properties, propertyDelimiter) {\n\t\t\tp, err := parseProperty(pStr)\n\t\t\tif err != nil {\n\t\t\t\treturn newInvalidMember(), err\n\t\t\t}\n\t\t\tprops = append(props, p)\n\t\t}\n\t}\n\t// Parse the member key/value pair.\n\n\t// Take into account a value can contain equal signs (=).\n\tk, v, found := strings.Cut(keyValue, keyValueDelimiter)\n\tif !found {\n\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %q\", errInvalidMember, member)\n\t}\n\t// \"Leading and trailing whitespaces are allowed but MUST be trimmed\n\t// when converting the header into a data structure.\"\n\tkey := strings.TrimSpace(k)\n\tif !validateKey(key) {\n\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %q\", errInvalidKey, key)\n\t}\n\n\trawVal := strings.TrimSpace(v)\n\tif !validateValue(rawVal) {\n\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %q\", errInvalidValue, v)\n\t}\n\n\t// Decode a percent-encoded value.\n\tunescapeVal, err := url.PathUnescape(rawVal)\n\tif err != nil {\n\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %w\", errInvalidValue, err)\n\t}\n\n\tvalue := replaceInvalidUTF8Sequences(len(rawVal), unescapeVal)\n\treturn Member{key: key, value: value, properties: props, hasData: true}, nil\n}\n\n// replaceInvalidUTF8Sequences replaces invalid UTF-8 sequences with '�'.\nfunc replaceInvalidUTF8Sequences(c int, unescapeVal string) string {\n\tif utf8.ValidString(unescapeVal) {\n\t\treturn unescapeVal\n\t}\n\t// W3C baggage spec:\n\t// https://github.com/w3c/baggage/blob/8c215efbeebd3fa4b1aceb937a747e56444f22f3/baggage/HTTP_HEADER_FORMAT.md?plain=1#L69\n\n\tvar b strings.Builder\n\tb.Grow(c)\n\tfor i := 0; i < len(unescapeVal); {\n\t\tr, size := utf8.DecodeRuneInString(unescapeVal[i:])\n\t\tif r == utf8.RuneError && size == 1 {\n\t\t\t// Invalid UTF-8 sequence found, replace it with '�'\n\t\t\t_, _ = b.WriteString(\"�\")\n\t\t} else {\n\t\t\t_, _ = b.WriteRune(r)\n\t\t}\n\t\ti += size\n\t}\n\n\treturn b.String()\n}\n\n// validate ensures m conforms to the W3C Baggage specification.\n// A key must be an ASCII string, returning an error otherwise.\nfunc (m Member) validate() error {\n\tif !m.hasData {\n\t\treturn fmt.Errorf(\"%w: %q\", errInvalidMember, m)\n\t}\n\n\tif !validateBaggageName(m.key) {\n\t\treturn fmt.Errorf(\"%w: %q\", errInvalidKey, m.key)\n\t}\n\tif !validateBaggageValue(m.value) {\n\t\treturn fmt.Errorf(\"%w: %q\", errInvalidValue, m.value)\n\t}\n\treturn m.properties.validate()\n}\n\n// Key returns the Member key.\nfunc (m Member) Key() string { return m.key }\n\n// Value returns the Member value.\nfunc (m Member) Value() string { return m.value }\n\n// Properties returns a copy of the Member properties.\nfunc (m Member) Properties() []Property { return m.properties.Copy() }\n\n// String encodes Member into a header string compliant with the W3C Baggage\n// specification.\n// It would return empty string if the key is invalid with the W3C Baggage\n// specification. This could happen for a UTF-8 key, as it may contain\n// invalid characters.\nfunc (m Member) String() string {\n\t//  W3C Baggage specification does not allow percent-encoded keys.\n\tif !validateKey(m.key) {\n\t\treturn \"\"\n\t}\n\n\ts := m.key + keyValueDelimiter + valueEscape(m.value)\n\tif len(m.properties) > 0 {\n\t\ts += propertyDelimiter + m.properties.String()\n\t}\n\treturn s\n}\n\n// Baggage is a list of baggage members representing the baggage-string as\n// defined by the W3C Baggage specification.\ntype Baggage struct { //nolint:golint\n\tlist baggage.List\n}\n\n// New returns a new valid Baggage. It returns an error if it results in a\n// Baggage exceeding limits set in that specification.\n//\n// It expects all the provided members to have already been validated.\nfunc New(members ...Member) (Baggage, error) {\n\tif len(members) == 0 {\n\t\treturn Baggage{}, nil\n\t}\n\n\tb := make(baggage.List)\n\tfor _, m := range members {\n\t\tif !m.hasData {\n\t\t\treturn Baggage{}, errInvalidMember\n\t\t}\n\n\t\t// OpenTelemetry resolves duplicates by last-one-wins.\n\t\tb[m.key] = baggage.Item{\n\t\t\tValue:      m.value,\n\t\t\tProperties: m.properties.asInternal(),\n\t\t}\n\t}\n\n\t// Check member numbers after deduplication.\n\tif len(b) > maxMembers {\n\t\treturn Baggage{}, errMemberNumber\n\t}\n\n\tbag := Baggage{b}\n\tif n := len(bag.String()); n > maxBytesPerBaggageString {\n\t\treturn Baggage{}, fmt.Errorf(\"%w: %d\", errBaggageBytes, n)\n\t}\n\n\treturn bag, nil\n}\n\n// Parse attempts to decode a baggage-string from the passed string. It\n// returns an error if the input is invalid according to the W3C Baggage\n// specification.\n//\n// If there are duplicate list-members contained in baggage, the last one\n// defined (reading left-to-right) will be the only one kept. This diverges\n// from the W3C Baggage specification which allows duplicate list-members, but\n// conforms to the OpenTelemetry Baggage specification.\nfunc Parse(bStr string) (Baggage, error) {\n\tif bStr == \"\" {\n\t\treturn Baggage{}, nil\n\t}\n\n\tif n := len(bStr); n > maxBytesPerBaggageString {\n\t\treturn Baggage{}, fmt.Errorf(\"%w: %d\", errBaggageBytes, n)\n\t}\n\n\tb := make(baggage.List)\n\tfor memberStr := range strings.SplitSeq(bStr, listDelimiter) {\n\t\tm, err := parseMember(memberStr)\n\t\tif err != nil {\n\t\t\treturn Baggage{}, err\n\t\t}\n\t\t// OpenTelemetry resolves duplicates by last-one-wins.\n\t\tb[m.key] = baggage.Item{\n\t\t\tValue:      m.value,\n\t\t\tProperties: m.properties.asInternal(),\n\t\t}\n\t}\n\n\t// OpenTelemetry does not allow for duplicate list-members, but the W3C\n\t// specification does. Now that we have deduplicated, ensure the baggage\n\t// does not exceed list-member limits.\n\tif len(b) > maxMembers {\n\t\treturn Baggage{}, errMemberNumber\n\t}\n\n\treturn Baggage{b}, nil\n}\n\n// Member returns the baggage list-member identified by key.\n//\n// If there is no list-member matching the passed key the returned Member will\n// be a zero-value Member.\n// The returned member is not validated, as we assume the validation happened\n// when it was added to the Baggage.\nfunc (b Baggage) Member(key string) Member {\n\tv, ok := b.list[key]\n\tif !ok {\n\t\t// We do not need to worry about distinguishing between the situation\n\t\t// where a zero-valued Member is included in the Baggage because a\n\t\t// zero-valued Member is invalid according to the W3C Baggage\n\t\t// specification (it has an empty key).\n\t\treturn newInvalidMember()\n\t}\n\n\treturn Member{\n\t\tkey:        key,\n\t\tvalue:      v.Value,\n\t\tproperties: fromInternalProperties(v.Properties),\n\t\thasData:    true,\n\t}\n}\n\n// Members returns all the baggage list-members.\n// The order of the returned list-members is not significant.\n//\n// The returned members are not validated, as we assume the validation happened\n// when they were added to the Baggage.\nfunc (b Baggage) Members() []Member {\n\tif len(b.list) == 0 {\n\t\treturn nil\n\t}\n\n\tmembers := make([]Member, 0, len(b.list))\n\tfor k, v := range b.list {\n\t\tmembers = append(members, Member{\n\t\t\tkey:        k,\n\t\t\tvalue:      v.Value,\n\t\t\tproperties: fromInternalProperties(v.Properties),\n\t\t\thasData:    true,\n\t\t})\n\t}\n\treturn members\n}\n\n// SetMember returns a copy of the Baggage with the member included. If the\n// baggage contains a Member with the same key, the existing Member is\n// replaced.\n//\n// If member is invalid according to the W3C Baggage specification, an error\n// is returned with the original Baggage.\nfunc (b Baggage) SetMember(member Member) (Baggage, error) {\n\tif !member.hasData {\n\t\treturn b, errInvalidMember\n\t}\n\n\tn := len(b.list)\n\tif _, ok := b.list[member.key]; !ok {\n\t\tn++\n\t}\n\tlist := make(baggage.List, n)\n\n\tfor k, v := range b.list {\n\t\t// Do not copy if we are just going to overwrite.\n\t\tif k == member.key {\n\t\t\tcontinue\n\t\t}\n\t\tlist[k] = v\n\t}\n\n\tlist[member.key] = baggage.Item{\n\t\tValue:      member.value,\n\t\tProperties: member.properties.asInternal(),\n\t}\n\n\treturn Baggage{list: list}, nil\n}\n\n// DeleteMember returns a copy of the Baggage with the list-member identified\n// by key removed.\nfunc (b Baggage) DeleteMember(key string) Baggage {\n\tn := len(b.list)\n\tif _, ok := b.list[key]; ok {\n\t\tn--\n\t}\n\tlist := make(baggage.List, n)\n\n\tfor k, v := range b.list {\n\t\tif k == key {\n\t\t\tcontinue\n\t\t}\n\t\tlist[k] = v\n\t}\n\n\treturn Baggage{list: list}\n}\n\n// Len returns the number of list-members in the Baggage.\nfunc (b Baggage) Len() int {\n\treturn len(b.list)\n}\n\n// String encodes Baggage into a header string compliant with the W3C Baggage\n// specification.\n// It would ignore members where the member key is invalid with the W3C Baggage\n// specification. This could happen for a UTF-8 key, as it may contain\n// invalid characters.\nfunc (b Baggage) String() string {\n\tmembers := make([]string, 0, len(b.list))\n\tfor k, v := range b.list {\n\t\ts := Member{\n\t\t\tkey:        k,\n\t\t\tvalue:      v.Value,\n\t\t\tproperties: fromInternalProperties(v.Properties),\n\t\t}.String()\n\n\t\t// Ignored empty members.\n\t\tif s != \"\" {\n\t\t\tmembers = append(members, s)\n\t\t}\n\t}\n\treturn strings.Join(members, listDelimiter)\n}\n\n// parsePropertyInternal attempts to decode a Property from the passed string.\n// It follows the spec at https://www.w3.org/TR/baggage/#definition.\nfunc parsePropertyInternal(s string) (p Property, ok bool) {\n\t// For the entire function we will use \"   key    =    value  \" as an example.\n\t// Attempting to parse the key.\n\t// First skip spaces at the beginning \"<   >key    =    value  \" (they could be empty).\n\tindex := skipSpace(s, 0)\n\n\t// Parse the key: \"   <key>    =    value  \".\n\tkeyStart := index\n\tkeyEnd := index\n\tfor _, c := range s[keyStart:] {\n\t\tif !validateKeyChar(c) {\n\t\t\tbreak\n\t\t}\n\t\tkeyEnd++\n\t}\n\n\t// If we couldn't find any valid key character,\n\t// it means the key is either empty or invalid.\n\tif keyStart == keyEnd {\n\t\treturn p, ok\n\t}\n\n\t// Skip spaces after the key: \"   key<    >=    value  \".\n\tindex = skipSpace(s, keyEnd)\n\n\tif index == len(s) {\n\t\t// A key can have no value, like: \"   key    \".\n\t\tok = true\n\t\tp.key = s[keyStart:keyEnd]\n\t\treturn p, ok\n\t}\n\n\t// If we have not reached the end and we can't find the '=' delimiter,\n\t// it means the property is invalid.\n\tif s[index] != keyValueDelimiter[0] {\n\t\treturn p, ok\n\t}\n\n\t// Attempting to parse the value.\n\t// Match: \"   key    =<    >value  \".\n\tindex = skipSpace(s, index+1)\n\n\t// Match the value string: \"   key    =    <value>  \".\n\t// A valid property can be: \"   key    =\".\n\t// Therefore, we don't have to check if the value is empty.\n\tvalueStart := index\n\tvalueEnd := index\n\tfor _, c := range s[valueStart:] {\n\t\tif !validateValueChar(c) {\n\t\t\tbreak\n\t\t}\n\t\tvalueEnd++\n\t}\n\n\t// Skip all trailing whitespaces: \"   key    =    value<  >\".\n\tindex = skipSpace(s, valueEnd)\n\n\t// If after looking for the value and skipping whitespaces\n\t// we have not reached the end, it means the property is\n\t// invalid, something like: \"   key    =    value  value1\".\n\tif index != len(s) {\n\t\treturn p, ok\n\t}\n\n\t// Decode a percent-encoded value.\n\trawVal := s[valueStart:valueEnd]\n\tunescapeVal, err := url.PathUnescape(rawVal)\n\tif err != nil {\n\t\treturn p, ok\n\t}\n\tvalue := replaceInvalidUTF8Sequences(len(rawVal), unescapeVal)\n\n\tok = true\n\tp.key = s[keyStart:keyEnd]\n\tp.hasValue = true\n\n\tp.value = value\n\treturn p, ok\n}\n\nfunc skipSpace(s string, offset int) int {\n\ti := offset\n\tfor ; i < len(s); i++ {\n\t\tc := s[i]\n\t\tif c != ' ' && c != '\\t' {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn i\n}\n\nvar safeKeyCharset = [utf8.RuneSelf]bool{\n\t// 0x23 to 0x27\n\t'#':  true,\n\t'$':  true,\n\t'%':  true,\n\t'&':  true,\n\t'\\'': true,\n\n\t// 0x30 to 0x39\n\t'0': true,\n\t'1': true,\n\t'2': true,\n\t'3': true,\n\t'4': true,\n\t'5': true,\n\t'6': true,\n\t'7': true,\n\t'8': true,\n\t'9': true,\n\n\t// 0x41 to 0x5a\n\t'A': true,\n\t'B': true,\n\t'C': true,\n\t'D': true,\n\t'E': true,\n\t'F': true,\n\t'G': true,\n\t'H': true,\n\t'I': true,\n\t'J': true,\n\t'K': true,\n\t'L': true,\n\t'M': true,\n\t'N': true,\n\t'O': true,\n\t'P': true,\n\t'Q': true,\n\t'R': true,\n\t'S': true,\n\t'T': true,\n\t'U': true,\n\t'V': true,\n\t'W': true,\n\t'X': true,\n\t'Y': true,\n\t'Z': true,\n\n\t// 0x5e to 0x7a\n\t'^': true,\n\t'_': true,\n\t'`': true,\n\t'a': true,\n\t'b': true,\n\t'c': true,\n\t'd': true,\n\t'e': true,\n\t'f': true,\n\t'g': true,\n\t'h': true,\n\t'i': true,\n\t'j': true,\n\t'k': true,\n\t'l': true,\n\t'm': true,\n\t'n': true,\n\t'o': true,\n\t'p': true,\n\t'q': true,\n\t'r': true,\n\t's': true,\n\t't': true,\n\t'u': true,\n\t'v': true,\n\t'w': true,\n\t'x': true,\n\t'y': true,\n\t'z': true,\n\n\t// remainder\n\t'!': true,\n\t'*': true,\n\t'+': true,\n\t'-': true,\n\t'.': true,\n\t'|': true,\n\t'~': true,\n}\n\n// validateBaggageName checks if the string is a valid OpenTelemetry Baggage name.\n// Baggage name is a valid, non-empty UTF-8 string.\nfunc validateBaggageName(s string) bool {\n\tif s == \"\" {\n\t\treturn false\n\t}\n\n\treturn utf8.ValidString(s)\n}\n\n// validateBaggageValue checks if the string is a valid OpenTelemetry Baggage value.\n// Baggage value is a valid UTF-8 strings.\n// Empty string is also a valid UTF-8 string.\nfunc validateBaggageValue(s string) bool {\n\treturn utf8.ValidString(s)\n}\n\n// validateKey checks if the string is a valid W3C Baggage key.\nfunc validateKey(s string) bool {\n\tif s == \"\" {\n\t\treturn false\n\t}\n\n\tfor _, c := range s {\n\t\tif !validateKeyChar(c) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc validateKeyChar(c int32) bool {\n\treturn c >= 0 && c < int32(utf8.RuneSelf) && safeKeyCharset[c]\n}\n\n// validateValue checks if the string is a valid W3C Baggage value.\nfunc validateValue(s string) bool {\n\tfor _, c := range s {\n\t\tif !validateValueChar(c) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nvar safeValueCharset = [utf8.RuneSelf]bool{\n\t'!': true, // 0x21\n\n\t// 0x23 to 0x2b\n\t'#':  true,\n\t'$':  true,\n\t'%':  true,\n\t'&':  true,\n\t'\\'': true,\n\t'(':  true,\n\t')':  true,\n\t'*':  true,\n\t'+':  true,\n\n\t// 0x2d to 0x3a\n\t'-': true,\n\t'.': true,\n\t'/': true,\n\t'0': true,\n\t'1': true,\n\t'2': true,\n\t'3': true,\n\t'4': true,\n\t'5': true,\n\t'6': true,\n\t'7': true,\n\t'8': true,\n\t'9': true,\n\t':': true,\n\n\t// 0x3c to 0x5b\n\t'<': true, // 0x3C\n\t'=': true, // 0x3D\n\t'>': true, // 0x3E\n\t'?': true, // 0x3F\n\t'@': true, // 0x40\n\t'A': true, // 0x41\n\t'B': true, // 0x42\n\t'C': true, // 0x43\n\t'D': true, // 0x44\n\t'E': true, // 0x45\n\t'F': true, // 0x46\n\t'G': true, // 0x47\n\t'H': true, // 0x48\n\t'I': true, // 0x49\n\t'J': true, // 0x4A\n\t'K': true, // 0x4B\n\t'L': true, // 0x4C\n\t'M': true, // 0x4D\n\t'N': true, // 0x4E\n\t'O': true, // 0x4F\n\t'P': true, // 0x50\n\t'Q': true, // 0x51\n\t'R': true, // 0x52\n\t'S': true, // 0x53\n\t'T': true, // 0x54\n\t'U': true, // 0x55\n\t'V': true, // 0x56\n\t'W': true, // 0x57\n\t'X': true, // 0x58\n\t'Y': true, // 0x59\n\t'Z': true, // 0x5A\n\t'[': true, // 0x5B\n\n\t// 0x5d to 0x7e\n\t']': true, // 0x5D\n\t'^': true, // 0x5E\n\t'_': true, // 0x5F\n\t'`': true, // 0x60\n\t'a': true, // 0x61\n\t'b': true, // 0x62\n\t'c': true, // 0x63\n\t'd': true, // 0x64\n\t'e': true, // 0x65\n\t'f': true, // 0x66\n\t'g': true, // 0x67\n\t'h': true, // 0x68\n\t'i': true, // 0x69\n\t'j': true, // 0x6A\n\t'k': true, // 0x6B\n\t'l': true, // 0x6C\n\t'm': true, // 0x6D\n\t'n': true, // 0x6E\n\t'o': true, // 0x6F\n\t'p': true, // 0x70\n\t'q': true, // 0x71\n\t'r': true, // 0x72\n\t's': true, // 0x73\n\t't': true, // 0x74\n\t'u': true, // 0x75\n\t'v': true, // 0x76\n\t'w': true, // 0x77\n\t'x': true, // 0x78\n\t'y': true, // 0x79\n\t'z': true, // 0x7A\n\t'{': true, // 0x7B\n\t'|': true, // 0x7C\n\t'}': true, // 0x7D\n\t'~': true, // 0x7E\n}\n\nfunc validateValueChar(c int32) bool {\n\treturn c >= 0 && c < int32(utf8.RuneSelf) && safeValueCharset[c]\n}\n\n// valueEscape escapes the string so it can be safely placed inside a baggage value,\n// replacing special characters with %XX sequences as needed.\n//\n// The implementation is based on:\n// https://github.com/golang/go/blob/f6509cf5cdbb5787061b784973782933c47f1782/src/net/url/url.go#L285.\nfunc valueEscape(s string) string {\n\thexCount := 0\n\tfor i := 0; i < len(s); i++ {\n\t\tc := s[i]\n\t\tif shouldEscape(c) {\n\t\t\thexCount++\n\t\t}\n\t}\n\n\tif hexCount == 0 {\n\t\treturn s\n\t}\n\n\tvar buf [64]byte\n\tvar t []byte\n\n\trequired := len(s) + 2*hexCount\n\tif required <= len(buf) {\n\t\tt = buf[:required]\n\t} else {\n\t\tt = make([]byte, required)\n\t}\n\n\tj := 0\n\tfor i := 0; i < len(s); i++ {\n\t\tc := s[i]\n\t\tif shouldEscape(s[i]) {\n\t\t\tconst upperhex = \"0123456789ABCDEF\"\n\t\t\tt[j] = '%'\n\t\t\tt[j+1] = upperhex[c>>4]\n\t\t\tt[j+2] = upperhex[c&15]\n\t\t\tj += 3\n\t\t} else {\n\t\t\tt[j] = c\n\t\t\tj++\n\t\t}\n\t}\n\n\treturn string(t)\n}\n\n// shouldEscape returns true if the specified byte should be escaped when\n// appearing in a baggage value string.\nfunc shouldEscape(c byte) bool {\n\tif c == '%' {\n\t\t// The percent character must be encoded so that percent-encoding can work.\n\t\treturn true\n\t}\n\treturn !validateValueChar(int32(c))\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/baggage/context.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage baggage // import \"go.opentelemetry.io/otel/baggage\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/internal/baggage\"\n)\n\n// ContextWithBaggage returns a copy of parent with baggage.\nfunc ContextWithBaggage(parent context.Context, b Baggage) context.Context {\n\t// Delegate so any hooks for the OpenTracing bridge are handled.\n\treturn baggage.ContextWithList(parent, b.list)\n}\n\n// ContextWithoutBaggage returns a copy of parent with no baggage.\nfunc ContextWithoutBaggage(parent context.Context) context.Context {\n\t// Delegate so any hooks for the OpenTracing bridge are handled.\n\treturn baggage.ContextWithList(parent, nil)\n}\n\n// FromContext returns the baggage contained in ctx.\nfunc FromContext(ctx context.Context) Baggage {\n\t// Delegate so any hooks for the OpenTracing bridge are handled.\n\treturn Baggage{list: baggage.ListFromContext(ctx)}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/baggage/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n/*\nPackage baggage provides functionality for storing and retrieving\nbaggage items in Go context. For propagating the baggage, see the\ngo.opentelemetry.io/otel/propagation package.\n*/\npackage baggage // import \"go.opentelemetry.io/otel/baggage\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/codes/README.md",
    "content": "# Codes\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/codes)](https://pkg.go.dev/go.opentelemetry.io/otel/codes)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/codes/codes.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage codes // import \"go.opentelemetry.io/otel/codes\"\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n)\n\nconst (\n\t// Unset is the default status code.\n\tUnset Code = 0\n\n\t// Error indicates the operation contains an error.\n\t//\n\t// NOTE: The error code in OTLP is 2.\n\t// The value of this enum is only relevant to the internals\n\t// of the Go SDK.\n\tError Code = 1\n\n\t// Ok indicates operation has been validated by an Application developers\n\t// or Operator to have completed successfully, or contain no error.\n\t//\n\t// NOTE: The Ok code in OTLP is 1.\n\t// The value of this enum is only relevant to the internals\n\t// of the Go SDK.\n\tOk Code = 2\n\n\tmaxCode = 3\n)\n\n// Code is an 32-bit representation of a status state.\ntype Code uint32\n\nvar codeToStr = map[Code]string{\n\tUnset: \"Unset\",\n\tError: \"Error\",\n\tOk:    \"Ok\",\n}\n\nvar strToCode = map[string]Code{\n\t`\"Unset\"`: Unset,\n\t`\"Error\"`: Error,\n\t`\"Ok\"`:    Ok,\n}\n\n// String returns the Code as a string.\nfunc (c Code) String() string {\n\treturn codeToStr[c]\n}\n\n// UnmarshalJSON unmarshals b into the Code.\n//\n// This is based on the functionality in the gRPC codes package:\n// https://github.com/grpc/grpc-go/blob/bb64fee312b46ebee26be43364a7a966033521b1/codes/codes.go#L218-L244\nfunc (c *Code) UnmarshalJSON(b []byte) error {\n\t// From json.Unmarshaler: By convention, to approximate the behavior of\n\t// Unmarshal itself, Unmarshalers implement UnmarshalJSON([]byte(\"null\")) as\n\t// a no-op.\n\tif string(b) == \"null\" {\n\t\treturn nil\n\t}\n\tif c == nil {\n\t\treturn errors.New(\"nil receiver passed to UnmarshalJSON\")\n\t}\n\n\tvar x any\n\tif err := json.Unmarshal(b, &x); err != nil {\n\t\treturn err\n\t}\n\tswitch x.(type) {\n\tcase string:\n\t\tif jc, ok := strToCode[string(b)]; ok {\n\t\t\t*c = jc\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"invalid code: %q\", string(b))\n\tcase float64:\n\t\tif ci, err := strconv.ParseUint(string(b), 10, 32); err == nil {\n\t\t\tif ci >= maxCode {\n\t\t\t\treturn fmt.Errorf(\"invalid code: %q\", ci)\n\t\t\t}\n\n\t\t\t*c = Code(ci) // nolint: gosec  // Bit size of 32 check above.\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"invalid code: %q\", string(b))\n\tdefault:\n\t\treturn fmt.Errorf(\"invalid code: %q\", string(b))\n\t}\n}\n\n// MarshalJSON returns c as the JSON encoding of c.\nfunc (c *Code) MarshalJSON() ([]byte, error) {\n\tif c == nil {\n\t\treturn []byte(\"null\"), nil\n\t}\n\tstr, ok := codeToStr[*c]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"invalid code: %d\", *c)\n\t}\n\treturn fmt.Appendf(nil, \"%q\", str), nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/codes/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n/*\nPackage codes defines the canonical error codes used by OpenTelemetry.\n\nIt conforms to [the OpenTelemetry\nspecification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/api.md#set-status).\n*/\npackage codes // import \"go.opentelemetry.io/otel/codes\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/dependencies.Dockerfile",
    "content": "# This is a renovate-friendly source of Docker images.\nFROM python:3.13.6-slim-bullseye@sha256:e98b521460ee75bca92175c16247bdf7275637a8faaeb2bcfa19d879ae5c4b9a AS python\nFROM otel/weaver:v0.20.0@sha256:fa4f1c6954ecea78ab1a4e865bd6f5b4aaba80c1896f9f4a11e2c361d04e197e AS weaver\nFROM avtodev/markdown-lint:v1@sha256:6aeedc2f49138ce7a1cd0adffc1b1c0321b841dc2102408967d9301c031949ee AS markdown\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n/*\nPackage otel provides global access to the OpenTelemetry API. The subpackages of\nthe otel package provide an implementation of the OpenTelemetry API.\n\nThe provided API is used to instrument code and measure data about that code's\nperformance and operation. The measured data, by default, is not processed or\ntransmitted anywhere. An implementation of the OpenTelemetry SDK, like the\ndefault SDK implementation (go.opentelemetry.io/otel/sdk), and associated\nexporters are used to process and transport this data.\n\nTo read the getting started guide, see https://opentelemetry.io/docs/languages/go/getting-started/.\n\nTo read more about tracing, see go.opentelemetry.io/otel/trace.\n\nTo read more about metrics, see go.opentelemetry.io/otel/metric.\n\nTo read more about logs, see go.opentelemetry.io/otel/log.\n\nTo read more about propagation, see go.opentelemetry.io/otel/propagation and\ngo.opentelemetry.io/otel/baggage.\n*/\npackage otel // import \"go.opentelemetry.io/otel\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/error_handler.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage otel // import \"go.opentelemetry.io/otel\"\n\n// ErrorHandler handles irremediable events.\ntype ErrorHandler interface {\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Handle handles any error deemed irremediable by an OpenTelemetry\n\t// component.\n\tHandle(error)\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n}\n\n// ErrorHandlerFunc is a convenience adapter to allow the use of a function\n// as an ErrorHandler.\ntype ErrorHandlerFunc func(error)\n\nvar _ ErrorHandler = ErrorHandlerFunc(nil)\n\n// Handle handles the irremediable error by calling the ErrorHandlerFunc itself.\nfunc (f ErrorHandlerFunc) Handle(err error) {\n\tf(err)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/README.md",
    "content": "# OTLP Trace Exporter\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/exporters/otlp/otlptrace)](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlptrace)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/clients.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage otlptrace // import \"go.opentelemetry.io/otel/exporters/otlp/otlptrace\"\n\nimport (\n\t\"context\"\n\n\ttracepb \"go.opentelemetry.io/proto/otlp/trace/v1\"\n)\n\n// Client manages connections to the collector, handles the\n// transformation of data into wire format, and the transmission of that\n// data to the collector.\ntype Client interface {\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Start should establish connection(s) to endpoint(s). It is\n\t// called just once by the exporter, so the implementation\n\t// does not need to worry about idempotence and locking.\n\tStart(ctx context.Context) error\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Stop should close the connections. The function is called\n\t// only once by the exporter, so the implementation does not\n\t// need to worry about idempotence, but it may be called\n\t// concurrently with UploadTraces, so proper\n\t// locking is required. The function serves as a\n\t// synchronization point - after the function returns, the\n\t// process of closing connections is assumed to be finished.\n\tStop(ctx context.Context) error\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// UploadTraces should transform the passed traces to the wire\n\t// format and send it to the collector. May be called\n\t// concurrently.\n\tUploadTraces(ctx context.Context, protoSpans []*tracepb.ResourceSpans) error\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n/*\nPackage otlptrace contains abstractions for OTLP span exporters.\nSee the official OTLP span exporter implementations:\n  - [go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc],\n  - [go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp].\n*/\npackage otlptrace // import \"go.opentelemetry.io/otel/exporters/otlp/otlptrace\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/exporter.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage otlptrace // import \"go.opentelemetry.io/otel/exporters/otlp/otlptrace\"\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\n\t\"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform\"\n\ttracesdk \"go.opentelemetry.io/otel/sdk/trace\"\n)\n\nvar errAlreadyStarted = errors.New(\"already started\")\n\n// Exporter exports trace data in the OTLP wire format.\ntype Exporter struct {\n\tclient Client\n\n\tmu      sync.RWMutex\n\tstarted bool\n\n\tstartOnce sync.Once\n\tstopOnce  sync.Once\n}\n\n// ExportSpans exports a batch of spans.\nfunc (e *Exporter) ExportSpans(ctx context.Context, ss []tracesdk.ReadOnlySpan) error {\n\tprotoSpans := tracetransform.Spans(ss)\n\tif len(protoSpans) == 0 {\n\t\treturn nil\n\t}\n\n\terr := e.client.UploadTraces(ctx, protoSpans)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"traces export: %w\", err)\n\t}\n\treturn nil\n}\n\n// Start establishes a connection to the receiving endpoint.\nfunc (e *Exporter) Start(ctx context.Context) error {\n\terr := errAlreadyStarted\n\te.startOnce.Do(func() {\n\t\te.mu.Lock()\n\t\te.started = true\n\t\te.mu.Unlock()\n\t\terr = e.client.Start(ctx)\n\t})\n\n\treturn err\n}\n\n// Shutdown flushes all exports and closes all connections to the receiving endpoint.\nfunc (e *Exporter) Shutdown(ctx context.Context) error {\n\te.mu.RLock()\n\tstarted := e.started\n\te.mu.RUnlock()\n\n\tif !started {\n\t\treturn nil\n\t}\n\n\tvar err error\n\n\te.stopOnce.Do(func() {\n\t\terr = e.client.Stop(ctx)\n\t\te.mu.Lock()\n\t\te.started = false\n\t\te.mu.Unlock()\n\t})\n\n\treturn err\n}\n\nvar _ tracesdk.SpanExporter = (*Exporter)(nil)\n\n// New constructs a new Exporter and starts it.\nfunc New(ctx context.Context, client Client) (*Exporter, error) {\n\texp := NewUnstarted(client)\n\tif err := exp.Start(ctx); err != nil {\n\t\treturn nil, err\n\t}\n\treturn exp, nil\n}\n\n// NewUnstarted constructs a new Exporter and does not start it.\nfunc NewUnstarted(client Client) *Exporter {\n\treturn &Exporter{\n\t\tclient: client,\n\t}\n}\n\n// MarshalLog is the marshaling function used by the logging system to represent this Exporter.\nfunc (e *Exporter) MarshalLog() interface{} {\n\treturn struct {\n\t\tType   string\n\t\tClient Client\n\t}{\n\t\tType:   \"otlptrace\",\n\t\tClient: e.client,\n\t}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/attribute.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage tracetransform // import \"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform\"\n\nimport (\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/sdk/resource\"\n\tcommonpb \"go.opentelemetry.io/proto/otlp/common/v1\"\n)\n\n// KeyValues transforms a slice of attribute KeyValues into OTLP key-values.\nfunc KeyValues(attrs []attribute.KeyValue) []*commonpb.KeyValue {\n\tif len(attrs) == 0 {\n\t\treturn nil\n\t}\n\n\tout := make([]*commonpb.KeyValue, 0, len(attrs))\n\tfor _, kv := range attrs {\n\t\tout = append(out, KeyValue(kv))\n\t}\n\treturn out\n}\n\n// Iterator transforms an attribute iterator into OTLP key-values.\nfunc Iterator(iter attribute.Iterator) []*commonpb.KeyValue {\n\tl := iter.Len()\n\tif l == 0 {\n\t\treturn nil\n\t}\n\n\tout := make([]*commonpb.KeyValue, 0, l)\n\tfor iter.Next() {\n\t\tout = append(out, KeyValue(iter.Attribute()))\n\t}\n\treturn out\n}\n\n// ResourceAttributes transforms a Resource OTLP key-values.\nfunc ResourceAttributes(res *resource.Resource) []*commonpb.KeyValue {\n\treturn Iterator(res.Iter())\n}\n\n// KeyValue transforms an attribute KeyValue into an OTLP key-value.\nfunc KeyValue(kv attribute.KeyValue) *commonpb.KeyValue {\n\treturn &commonpb.KeyValue{Key: string(kv.Key), Value: Value(kv.Value)}\n}\n\n// Value transforms an attribute Value into an OTLP AnyValue.\nfunc Value(v attribute.Value) *commonpb.AnyValue {\n\tav := new(commonpb.AnyValue)\n\tswitch v.Type() {\n\tcase attribute.BOOL:\n\t\tav.Value = &commonpb.AnyValue_BoolValue{\n\t\t\tBoolValue: v.AsBool(),\n\t\t}\n\tcase attribute.BOOLSLICE:\n\t\tav.Value = &commonpb.AnyValue_ArrayValue{\n\t\t\tArrayValue: &commonpb.ArrayValue{\n\t\t\t\tValues: boolSliceValues(v.AsBoolSlice()),\n\t\t\t},\n\t\t}\n\tcase attribute.INT64:\n\t\tav.Value = &commonpb.AnyValue_IntValue{\n\t\t\tIntValue: v.AsInt64(),\n\t\t}\n\tcase attribute.INT64SLICE:\n\t\tav.Value = &commonpb.AnyValue_ArrayValue{\n\t\t\tArrayValue: &commonpb.ArrayValue{\n\t\t\t\tValues: int64SliceValues(v.AsInt64Slice()),\n\t\t\t},\n\t\t}\n\tcase attribute.FLOAT64:\n\t\tav.Value = &commonpb.AnyValue_DoubleValue{\n\t\t\tDoubleValue: v.AsFloat64(),\n\t\t}\n\tcase attribute.FLOAT64SLICE:\n\t\tav.Value = &commonpb.AnyValue_ArrayValue{\n\t\t\tArrayValue: &commonpb.ArrayValue{\n\t\t\t\tValues: float64SliceValues(v.AsFloat64Slice()),\n\t\t\t},\n\t\t}\n\tcase attribute.STRING:\n\t\tav.Value = &commonpb.AnyValue_StringValue{\n\t\t\tStringValue: v.AsString(),\n\t\t}\n\tcase attribute.STRINGSLICE:\n\t\tav.Value = &commonpb.AnyValue_ArrayValue{\n\t\t\tArrayValue: &commonpb.ArrayValue{\n\t\t\t\tValues: stringSliceValues(v.AsStringSlice()),\n\t\t\t},\n\t\t}\n\tdefault:\n\t\tav.Value = &commonpb.AnyValue_StringValue{\n\t\t\tStringValue: \"INVALID\",\n\t\t}\n\t}\n\treturn av\n}\n\nfunc boolSliceValues(vals []bool) []*commonpb.AnyValue {\n\tconverted := make([]*commonpb.AnyValue, len(vals))\n\tfor i, v := range vals {\n\t\tconverted[i] = &commonpb.AnyValue{\n\t\t\tValue: &commonpb.AnyValue_BoolValue{\n\t\t\t\tBoolValue: v,\n\t\t\t},\n\t\t}\n\t}\n\treturn converted\n}\n\nfunc int64SliceValues(vals []int64) []*commonpb.AnyValue {\n\tconverted := make([]*commonpb.AnyValue, len(vals))\n\tfor i, v := range vals {\n\t\tconverted[i] = &commonpb.AnyValue{\n\t\t\tValue: &commonpb.AnyValue_IntValue{\n\t\t\t\tIntValue: v,\n\t\t\t},\n\t\t}\n\t}\n\treturn converted\n}\n\nfunc float64SliceValues(vals []float64) []*commonpb.AnyValue {\n\tconverted := make([]*commonpb.AnyValue, len(vals))\n\tfor i, v := range vals {\n\t\tconverted[i] = &commonpb.AnyValue{\n\t\t\tValue: &commonpb.AnyValue_DoubleValue{\n\t\t\t\tDoubleValue: v,\n\t\t\t},\n\t\t}\n\t}\n\treturn converted\n}\n\nfunc stringSliceValues(vals []string) []*commonpb.AnyValue {\n\tconverted := make([]*commonpb.AnyValue, len(vals))\n\tfor i, v := range vals {\n\t\tconverted[i] = &commonpb.AnyValue{\n\t\t\tValue: &commonpb.AnyValue_StringValue{\n\t\t\t\tStringValue: v,\n\t\t\t},\n\t\t}\n\t}\n\treturn converted\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/instrumentation.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage tracetransform // import \"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform\"\n\nimport (\n\t\"go.opentelemetry.io/otel/sdk/instrumentation\"\n\tcommonpb \"go.opentelemetry.io/proto/otlp/common/v1\"\n)\n\nfunc InstrumentationScope(il instrumentation.Scope) *commonpb.InstrumentationScope {\n\tif il == (instrumentation.Scope{}) {\n\t\treturn nil\n\t}\n\treturn &commonpb.InstrumentationScope{\n\t\tName:    il.Name,\n\t\tVersion: il.Version,\n\t}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/resource.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage tracetransform // import \"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform\"\n\nimport (\n\t\"go.opentelemetry.io/otel/sdk/resource\"\n\tresourcepb \"go.opentelemetry.io/proto/otlp/resource/v1\"\n)\n\n// Resource transforms a Resource into an OTLP Resource.\nfunc Resource(r *resource.Resource) *resourcepb.Resource {\n\tif r == nil {\n\t\treturn nil\n\t}\n\treturn &resourcepb.Resource{Attributes: ResourceAttributes(r)}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/span.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage tracetransform // import \"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform\"\n\nimport (\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n\t\"go.opentelemetry.io/otel/sdk/instrumentation\"\n\ttracesdk \"go.opentelemetry.io/otel/sdk/trace\"\n\t\"go.opentelemetry.io/otel/trace\"\n\ttracepb \"go.opentelemetry.io/proto/otlp/trace/v1\"\n)\n\n// Spans transforms a slice of OpenTelemetry spans into a slice of OTLP\n// ResourceSpans.\nfunc Spans(sdl []tracesdk.ReadOnlySpan) []*tracepb.ResourceSpans {\n\tif len(sdl) == 0 {\n\t\treturn nil\n\t}\n\n\trsm := make(map[attribute.Distinct]*tracepb.ResourceSpans)\n\n\ttype key struct {\n\t\tr  attribute.Distinct\n\t\tis instrumentation.Scope\n\t}\n\tssm := make(map[key]*tracepb.ScopeSpans)\n\n\tvar resources int\n\tfor _, sd := range sdl {\n\t\tif sd == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\trKey := sd.Resource().Equivalent()\n\t\tk := key{\n\t\t\tr:  rKey,\n\t\t\tis: sd.InstrumentationScope(),\n\t\t}\n\t\tscopeSpan, iOk := ssm[k]\n\t\tif !iOk {\n\t\t\t// Either the resource or instrumentation scope were unknown.\n\t\t\tscopeSpan = &tracepb.ScopeSpans{\n\t\t\t\tScope:     InstrumentationScope(sd.InstrumentationScope()),\n\t\t\t\tSpans:     []*tracepb.Span{},\n\t\t\t\tSchemaUrl: sd.InstrumentationScope().SchemaURL,\n\t\t\t}\n\t\t}\n\t\tscopeSpan.Spans = append(scopeSpan.Spans, span(sd))\n\t\tssm[k] = scopeSpan\n\n\t\trs, rOk := rsm[rKey]\n\t\tif !rOk {\n\t\t\tresources++\n\t\t\t// The resource was unknown.\n\t\t\trs = &tracepb.ResourceSpans{\n\t\t\t\tResource:   Resource(sd.Resource()),\n\t\t\t\tScopeSpans: []*tracepb.ScopeSpans{scopeSpan},\n\t\t\t\tSchemaUrl:  sd.Resource().SchemaURL(),\n\t\t\t}\n\t\t\trsm[rKey] = rs\n\t\t\tcontinue\n\t\t}\n\n\t\t// The resource has been seen before. Check if the instrumentation\n\t\t// library lookup was unknown because if so we need to add it to the\n\t\t// ResourceSpans. Otherwise, the instrumentation library has already\n\t\t// been seen and the append we did above will be included it in the\n\t\t// ScopeSpans reference.\n\t\tif !iOk {\n\t\t\trs.ScopeSpans = append(rs.ScopeSpans, scopeSpan)\n\t\t}\n\t}\n\n\t// Transform the categorized map into a slice\n\trss := make([]*tracepb.ResourceSpans, 0, resources)\n\tfor _, rs := range rsm {\n\t\trss = append(rss, rs)\n\t}\n\treturn rss\n}\n\n// span transforms a Span into an OTLP span.\nfunc span(sd tracesdk.ReadOnlySpan) *tracepb.Span {\n\tif sd == nil {\n\t\treturn nil\n\t}\n\n\ttid := sd.SpanContext().TraceID()\n\tsid := sd.SpanContext().SpanID()\n\n\ts := &tracepb.Span{\n\t\tTraceId:                tid[:],\n\t\tSpanId:                 sid[:],\n\t\tTraceState:             sd.SpanContext().TraceState().String(),\n\t\tStatus:                 status(sd.Status().Code, sd.Status().Description),\n\t\tStartTimeUnixNano:      uint64(sd.StartTime().UnixNano()),\n\t\tEndTimeUnixNano:        uint64(sd.EndTime().UnixNano()),\n\t\tLinks:                  links(sd.Links()),\n\t\tKind:                   spanKind(sd.SpanKind()),\n\t\tName:                   sd.Name(),\n\t\tAttributes:             KeyValues(sd.Attributes()),\n\t\tEvents:                 spanEvents(sd.Events()),\n\t\tDroppedAttributesCount: uint32(sd.DroppedAttributes()),\n\t\tDroppedEventsCount:     uint32(sd.DroppedEvents()),\n\t\tDroppedLinksCount:      uint32(sd.DroppedLinks()),\n\t}\n\n\tif psid := sd.Parent().SpanID(); psid.IsValid() {\n\t\ts.ParentSpanId = psid[:]\n\t}\n\ts.Flags = buildSpanFlags(sd.Parent())\n\n\treturn s\n}\n\n// status transform a span code and message into an OTLP span status.\nfunc status(status codes.Code, message string) *tracepb.Status {\n\tvar c tracepb.Status_StatusCode\n\tswitch status {\n\tcase codes.Ok:\n\t\tc = tracepb.Status_STATUS_CODE_OK\n\tcase codes.Error:\n\t\tc = tracepb.Status_STATUS_CODE_ERROR\n\tdefault:\n\t\tc = tracepb.Status_STATUS_CODE_UNSET\n\t}\n\treturn &tracepb.Status{\n\t\tCode:    c,\n\t\tMessage: message,\n\t}\n}\n\n// links transforms span Links to OTLP span links.\nfunc links(links []tracesdk.Link) []*tracepb.Span_Link {\n\tif len(links) == 0 {\n\t\treturn nil\n\t}\n\n\tsl := make([]*tracepb.Span_Link, 0, len(links))\n\tfor _, otLink := range links {\n\t\t// This redefinition is necessary to prevent otLink.*ID[:] copies\n\t\t// being reused -- in short we need a new otLink per iteration.\n\t\totLink := otLink\n\n\t\ttid := otLink.SpanContext.TraceID()\n\t\tsid := otLink.SpanContext.SpanID()\n\n\t\tflags := buildSpanFlags(otLink.SpanContext)\n\n\t\tsl = append(sl, &tracepb.Span_Link{\n\t\t\tTraceId:                tid[:],\n\t\t\tSpanId:                 sid[:],\n\t\t\tAttributes:             KeyValues(otLink.Attributes),\n\t\t\tDroppedAttributesCount: uint32(otLink.DroppedAttributeCount),\n\t\t\tFlags:                  flags,\n\t\t})\n\t}\n\treturn sl\n}\n\nfunc buildSpanFlags(sc trace.SpanContext) uint32 {\n\tflags := tracepb.SpanFlags_SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK\n\tif sc.IsRemote() {\n\t\tflags |= tracepb.SpanFlags_SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK\n\t}\n\n\treturn uint32(flags)\n}\n\n// spanEvents transforms span Events to an OTLP span events.\nfunc spanEvents(es []tracesdk.Event) []*tracepb.Span_Event {\n\tif len(es) == 0 {\n\t\treturn nil\n\t}\n\n\tevents := make([]*tracepb.Span_Event, len(es))\n\t// Transform message events\n\tfor i := 0; i < len(es); i++ {\n\t\tevents[i] = &tracepb.Span_Event{\n\t\t\tName:                   es[i].Name,\n\t\t\tTimeUnixNano:           uint64(es[i].Time.UnixNano()),\n\t\t\tAttributes:             KeyValues(es[i].Attributes),\n\t\t\tDroppedAttributesCount: uint32(es[i].DroppedAttributeCount),\n\t\t}\n\t}\n\treturn events\n}\n\n// spanKind transforms a SpanKind to an OTLP span kind.\nfunc spanKind(kind trace.SpanKind) tracepb.Span_SpanKind {\n\tswitch kind {\n\tcase trace.SpanKindInternal:\n\t\treturn tracepb.Span_SPAN_KIND_INTERNAL\n\tcase trace.SpanKindClient:\n\t\treturn tracepb.Span_SPAN_KIND_CLIENT\n\tcase trace.SpanKindServer:\n\t\treturn tracepb.Span_SPAN_KIND_SERVER\n\tcase trace.SpanKindProducer:\n\t\treturn tracepb.Span_SPAN_KIND_PRODUCER\n\tcase trace.SpanKindConsumer:\n\t\treturn tracepb.Span_SPAN_KIND_CONSUMER\n\tdefault:\n\t\treturn tracepb.Span_SPAN_KIND_UNSPECIFIED\n\t}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/version.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage otlptrace // import \"go.opentelemetry.io/otel/exporters/otlp/otlptrace\"\n\n// Version is the current release version of the OpenTelemetry OTLP trace exporter in use.\nfunc Version() string {\n\treturn \"1.26.0\"\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/handler.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage otel // import \"go.opentelemetry.io/otel\"\n\nimport (\n\t\"go.opentelemetry.io/otel/internal/global\"\n)\n\n// Compile-time check global.ErrDelegator implements ErrorHandler.\nvar _ ErrorHandler = (*global.ErrDelegator)(nil)\n\n// GetErrorHandler returns the global ErrorHandler instance.\n//\n// The default ErrorHandler instance returned will log all errors to STDERR\n// until an override ErrorHandler is set with SetErrorHandler. All\n// ErrorHandler returned prior to this will automatically forward errors to\n// the set instance instead of logging.\n//\n// Subsequent calls to SetErrorHandler after the first will not forward errors\n// to the new ErrorHandler for prior returned instances.\nfunc GetErrorHandler() ErrorHandler { return global.GetErrorHandler() }\n\n// SetErrorHandler sets the global ErrorHandler to h.\n//\n// The first time this is called all ErrorHandler previously returned from\n// GetErrorHandler will send errors to h instead of the default logging\n// ErrorHandler. Subsequent calls will set the global ErrorHandler, but not\n// delegate errors to h.\nfunc SetErrorHandler(h ErrorHandler) { global.SetErrorHandler(h) }\n\n// Handle is a convenience function for GetErrorHandler().Handle(err).\nfunc Handle(err error) { global.GetErrorHandler().Handle(err) }\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n/*\nPackage baggage provides base types and functionality to store and retrieve\nbaggage in Go context. This package exists because the OpenTracing bridge to\nOpenTelemetry needs to synchronize state whenever baggage for a context is\nmodified and that context contains an OpenTracing span. If it were not for\nthis need this package would not need to exist and the\n`go.opentelemetry.io/otel/baggage` package would be the singular place where\nW3C baggage is handled.\n*/\npackage baggage // import \"go.opentelemetry.io/otel/internal/baggage\"\n\n// List is the collection of baggage members. The W3C allows for duplicates,\n// but OpenTelemetry does not, therefore, this is represented as a map.\ntype List map[string]Item\n\n// Item is the value and metadata properties part of a list-member.\ntype Item struct {\n\tValue      string\n\tProperties []Property\n}\n\n// Property is a metadata entry for a list-member.\ntype Property struct {\n\tKey, Value string\n\n\t// HasValue indicates if a zero-value value means the property does not\n\t// have a value or if it was the zero-value.\n\tHasValue bool\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/baggage/context.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage baggage // import \"go.opentelemetry.io/otel/internal/baggage\"\n\nimport \"context\"\n\ntype baggageContextKeyType int\n\nconst baggageKey baggageContextKeyType = iota\n\n// SetHookFunc is a callback called when storing baggage in the context.\ntype SetHookFunc func(context.Context, List) context.Context\n\n// GetHookFunc is a callback called when getting baggage from the context.\ntype GetHookFunc func(context.Context, List) List\n\ntype baggageState struct {\n\tlist List\n\n\tsetHook SetHookFunc\n\tgetHook GetHookFunc\n}\n\n// ContextWithSetHook returns a copy of parent with hook configured to be\n// invoked every time ContextWithBaggage is called.\n//\n// Passing nil SetHookFunc creates a context with no set hook to call.\nfunc ContextWithSetHook(parent context.Context, hook SetHookFunc) context.Context {\n\tvar s baggageState\n\tif v, ok := parent.Value(baggageKey).(baggageState); ok {\n\t\ts = v\n\t}\n\n\ts.setHook = hook\n\treturn context.WithValue(parent, baggageKey, s)\n}\n\n// ContextWithGetHook returns a copy of parent with hook configured to be\n// invoked every time FromContext is called.\n//\n// Passing nil GetHookFunc creates a context with no get hook to call.\nfunc ContextWithGetHook(parent context.Context, hook GetHookFunc) context.Context {\n\tvar s baggageState\n\tif v, ok := parent.Value(baggageKey).(baggageState); ok {\n\t\ts = v\n\t}\n\n\ts.getHook = hook\n\treturn context.WithValue(parent, baggageKey, s)\n}\n\n// ContextWithList returns a copy of parent with baggage. Passing nil list\n// returns a context without any baggage.\nfunc ContextWithList(parent context.Context, list List) context.Context {\n\tvar s baggageState\n\tif v, ok := parent.Value(baggageKey).(baggageState); ok {\n\t\ts = v\n\t}\n\n\ts.list = list\n\tctx := context.WithValue(parent, baggageKey, s)\n\tif s.setHook != nil {\n\t\tctx = s.setHook(ctx, list)\n\t}\n\n\treturn ctx\n}\n\n// ListFromContext returns the baggage contained in ctx.\nfunc ListFromContext(ctx context.Context) List {\n\tswitch v := ctx.Value(baggageKey).(type) {\n\tcase baggageState:\n\t\tif v.getHook != nil {\n\t\t\treturn v.getHook(ctx, v.list)\n\t\t}\n\t\treturn v.list\n\tdefault:\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/global/handler.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package global provides the OpenTelemetry global API.\npackage global // import \"go.opentelemetry.io/otel/internal/global\"\n\nimport (\n\t\"log\"\n\t\"sync/atomic\"\n)\n\n// ErrorHandler handles irremediable events.\ntype ErrorHandler interface {\n\t// Handle handles any error deemed irremediable by an OpenTelemetry\n\t// component.\n\tHandle(error)\n}\n\ntype ErrDelegator struct {\n\tdelegate atomic.Pointer[ErrorHandler]\n}\n\n// Compile-time check that delegator implements ErrorHandler.\nvar _ ErrorHandler = (*ErrDelegator)(nil)\n\nfunc (d *ErrDelegator) Handle(err error) {\n\tif eh := d.delegate.Load(); eh != nil {\n\t\t(*eh).Handle(err)\n\t\treturn\n\t}\n\tlog.Print(err)\n}\n\n// setDelegate sets the ErrorHandler delegate.\nfunc (d *ErrDelegator) setDelegate(eh ErrorHandler) {\n\td.delegate.Store(&eh)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/global/instruments.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage global // import \"go.opentelemetry.io/otel/internal/global\"\n\nimport (\n\t\"context\"\n\t\"sync/atomic\"\n\n\t\"go.opentelemetry.io/otel/metric\"\n\t\"go.opentelemetry.io/otel/metric/embedded\"\n)\n\n// unwrapper unwraps to return the underlying instrument implementation.\ntype unwrapper interface {\n\tunwrap() metric.Observable\n}\n\ntype afCounter struct {\n\tembedded.Float64ObservableCounter\n\tmetric.Float64Observable\n\n\tname string\n\topts []metric.Float64ObservableCounterOption\n\n\tdelegate atomic.Value // metric.Float64ObservableCounter\n}\n\nvar (\n\t_ unwrapper                       = (*afCounter)(nil)\n\t_ metric.Float64ObservableCounter = (*afCounter)(nil)\n)\n\nfunc (i *afCounter) setDelegate(m metric.Meter) {\n\tctr, err := m.Float64ObservableCounter(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *afCounter) unwrap() metric.Observable {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Float64ObservableCounter)\n\t}\n\treturn nil\n}\n\ntype afUpDownCounter struct {\n\tembedded.Float64ObservableUpDownCounter\n\tmetric.Float64Observable\n\n\tname string\n\topts []metric.Float64ObservableUpDownCounterOption\n\n\tdelegate atomic.Value // metric.Float64ObservableUpDownCounter\n}\n\nvar (\n\t_ unwrapper                             = (*afUpDownCounter)(nil)\n\t_ metric.Float64ObservableUpDownCounter = (*afUpDownCounter)(nil)\n)\n\nfunc (i *afUpDownCounter) setDelegate(m metric.Meter) {\n\tctr, err := m.Float64ObservableUpDownCounter(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *afUpDownCounter) unwrap() metric.Observable {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Float64ObservableUpDownCounter)\n\t}\n\treturn nil\n}\n\ntype afGauge struct {\n\tembedded.Float64ObservableGauge\n\tmetric.Float64Observable\n\n\tname string\n\topts []metric.Float64ObservableGaugeOption\n\n\tdelegate atomic.Value // metric.Float64ObservableGauge\n}\n\nvar (\n\t_ unwrapper                     = (*afGauge)(nil)\n\t_ metric.Float64ObservableGauge = (*afGauge)(nil)\n)\n\nfunc (i *afGauge) setDelegate(m metric.Meter) {\n\tctr, err := m.Float64ObservableGauge(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *afGauge) unwrap() metric.Observable {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Float64ObservableGauge)\n\t}\n\treturn nil\n}\n\ntype aiCounter struct {\n\tembedded.Int64ObservableCounter\n\tmetric.Int64Observable\n\n\tname string\n\topts []metric.Int64ObservableCounterOption\n\n\tdelegate atomic.Value // metric.Int64ObservableCounter\n}\n\nvar (\n\t_ unwrapper                     = (*aiCounter)(nil)\n\t_ metric.Int64ObservableCounter = (*aiCounter)(nil)\n)\n\nfunc (i *aiCounter) setDelegate(m metric.Meter) {\n\tctr, err := m.Int64ObservableCounter(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *aiCounter) unwrap() metric.Observable {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Int64ObservableCounter)\n\t}\n\treturn nil\n}\n\ntype aiUpDownCounter struct {\n\tembedded.Int64ObservableUpDownCounter\n\tmetric.Int64Observable\n\n\tname string\n\topts []metric.Int64ObservableUpDownCounterOption\n\n\tdelegate atomic.Value // metric.Int64ObservableUpDownCounter\n}\n\nvar (\n\t_ unwrapper                           = (*aiUpDownCounter)(nil)\n\t_ metric.Int64ObservableUpDownCounter = (*aiUpDownCounter)(nil)\n)\n\nfunc (i *aiUpDownCounter) setDelegate(m metric.Meter) {\n\tctr, err := m.Int64ObservableUpDownCounter(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *aiUpDownCounter) unwrap() metric.Observable {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Int64ObservableUpDownCounter)\n\t}\n\treturn nil\n}\n\ntype aiGauge struct {\n\tembedded.Int64ObservableGauge\n\tmetric.Int64Observable\n\n\tname string\n\topts []metric.Int64ObservableGaugeOption\n\n\tdelegate atomic.Value // metric.Int64ObservableGauge\n}\n\nvar (\n\t_ unwrapper                   = (*aiGauge)(nil)\n\t_ metric.Int64ObservableGauge = (*aiGauge)(nil)\n)\n\nfunc (i *aiGauge) setDelegate(m metric.Meter) {\n\tctr, err := m.Int64ObservableGauge(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *aiGauge) unwrap() metric.Observable {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Int64ObservableGauge)\n\t}\n\treturn nil\n}\n\n// Sync Instruments.\ntype sfCounter struct {\n\tembedded.Float64Counter\n\n\tname string\n\topts []metric.Float64CounterOption\n\n\tdelegate atomic.Value // metric.Float64Counter\n}\n\nvar _ metric.Float64Counter = (*sfCounter)(nil)\n\nfunc (i *sfCounter) setDelegate(m metric.Meter) {\n\tctr, err := m.Float64Counter(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *sfCounter) Add(ctx context.Context, incr float64, opts ...metric.AddOption) {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\tctr.(metric.Float64Counter).Add(ctx, incr, opts...)\n\t}\n}\n\nfunc (i *sfCounter) Enabled(ctx context.Context) bool {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Float64Counter).Enabled(ctx)\n\t}\n\treturn false\n}\n\ntype sfUpDownCounter struct {\n\tembedded.Float64UpDownCounter\n\n\tname string\n\topts []metric.Float64UpDownCounterOption\n\n\tdelegate atomic.Value // metric.Float64UpDownCounter\n}\n\nvar _ metric.Float64UpDownCounter = (*sfUpDownCounter)(nil)\n\nfunc (i *sfUpDownCounter) setDelegate(m metric.Meter) {\n\tctr, err := m.Float64UpDownCounter(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *sfUpDownCounter) Add(ctx context.Context, incr float64, opts ...metric.AddOption) {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\tctr.(metric.Float64UpDownCounter).Add(ctx, incr, opts...)\n\t}\n}\n\nfunc (i *sfUpDownCounter) Enabled(ctx context.Context) bool {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Float64UpDownCounter).Enabled(ctx)\n\t}\n\treturn false\n}\n\ntype sfHistogram struct {\n\tembedded.Float64Histogram\n\n\tname string\n\topts []metric.Float64HistogramOption\n\n\tdelegate atomic.Value // metric.Float64Histogram\n}\n\nvar _ metric.Float64Histogram = (*sfHistogram)(nil)\n\nfunc (i *sfHistogram) setDelegate(m metric.Meter) {\n\tctr, err := m.Float64Histogram(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *sfHistogram) Record(ctx context.Context, x float64, opts ...metric.RecordOption) {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\tctr.(metric.Float64Histogram).Record(ctx, x, opts...)\n\t}\n}\n\nfunc (i *sfHistogram) Enabled(ctx context.Context) bool {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Float64Histogram).Enabled(ctx)\n\t}\n\treturn false\n}\n\ntype sfGauge struct {\n\tembedded.Float64Gauge\n\n\tname string\n\topts []metric.Float64GaugeOption\n\n\tdelegate atomic.Value // metric.Float64Gauge\n}\n\nvar _ metric.Float64Gauge = (*sfGauge)(nil)\n\nfunc (i *sfGauge) setDelegate(m metric.Meter) {\n\tctr, err := m.Float64Gauge(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *sfGauge) Record(ctx context.Context, x float64, opts ...metric.RecordOption) {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\tctr.(metric.Float64Gauge).Record(ctx, x, opts...)\n\t}\n}\n\nfunc (i *sfGauge) Enabled(ctx context.Context) bool {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Float64Gauge).Enabled(ctx)\n\t}\n\treturn false\n}\n\ntype siCounter struct {\n\tembedded.Int64Counter\n\n\tname string\n\topts []metric.Int64CounterOption\n\n\tdelegate atomic.Value // metric.Int64Counter\n}\n\nvar _ metric.Int64Counter = (*siCounter)(nil)\n\nfunc (i *siCounter) setDelegate(m metric.Meter) {\n\tctr, err := m.Int64Counter(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *siCounter) Add(ctx context.Context, x int64, opts ...metric.AddOption) {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\tctr.(metric.Int64Counter).Add(ctx, x, opts...)\n\t}\n}\n\nfunc (i *siCounter) Enabled(ctx context.Context) bool {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Int64Counter).Enabled(ctx)\n\t}\n\treturn false\n}\n\ntype siUpDownCounter struct {\n\tembedded.Int64UpDownCounter\n\n\tname string\n\topts []metric.Int64UpDownCounterOption\n\n\tdelegate atomic.Value // metric.Int64UpDownCounter\n}\n\nvar _ metric.Int64UpDownCounter = (*siUpDownCounter)(nil)\n\nfunc (i *siUpDownCounter) setDelegate(m metric.Meter) {\n\tctr, err := m.Int64UpDownCounter(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *siUpDownCounter) Add(ctx context.Context, x int64, opts ...metric.AddOption) {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\tctr.(metric.Int64UpDownCounter).Add(ctx, x, opts...)\n\t}\n}\n\nfunc (i *siUpDownCounter) Enabled(ctx context.Context) bool {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Int64UpDownCounter).Enabled(ctx)\n\t}\n\treturn false\n}\n\ntype siHistogram struct {\n\tembedded.Int64Histogram\n\n\tname string\n\topts []metric.Int64HistogramOption\n\n\tdelegate atomic.Value // metric.Int64Histogram\n}\n\nvar _ metric.Int64Histogram = (*siHistogram)(nil)\n\nfunc (i *siHistogram) setDelegate(m metric.Meter) {\n\tctr, err := m.Int64Histogram(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *siHistogram) Record(ctx context.Context, x int64, opts ...metric.RecordOption) {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\tctr.(metric.Int64Histogram).Record(ctx, x, opts...)\n\t}\n}\n\nfunc (i *siHistogram) Enabled(ctx context.Context) bool {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Int64Histogram).Enabled(ctx)\n\t}\n\treturn false\n}\n\ntype siGauge struct {\n\tembedded.Int64Gauge\n\n\tname string\n\topts []metric.Int64GaugeOption\n\n\tdelegate atomic.Value // metric.Int64Gauge\n}\n\nvar _ metric.Int64Gauge = (*siGauge)(nil)\n\nfunc (i *siGauge) setDelegate(m metric.Meter) {\n\tctr, err := m.Int64Gauge(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *siGauge) Record(ctx context.Context, x int64, opts ...metric.RecordOption) {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\tctr.(metric.Int64Gauge).Record(ctx, x, opts...)\n\t}\n}\n\nfunc (i *siGauge) Enabled(ctx context.Context) bool {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Int64Gauge).Enabled(ctx)\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage global // import \"go.opentelemetry.io/otel/internal/global\"\n\nimport (\n\t\"log\"\n\t\"os\"\n\t\"sync/atomic\"\n\n\t\"github.com/go-logr/logr\"\n\t\"github.com/go-logr/stdr\"\n)\n\n// globalLogger holds a reference to the [logr.Logger] used within\n// go.opentelemetry.io/otel.\n//\n// The default logger uses stdr which is backed by the standard `log.Logger`\n// interface. This logger will only show messages at the Error Level.\nvar globalLogger = func() *atomic.Pointer[logr.Logger] {\n\tl := stdr.New(log.New(os.Stderr, \"\", log.LstdFlags|log.Lshortfile))\n\n\tp := new(atomic.Pointer[logr.Logger])\n\tp.Store(&l)\n\treturn p\n}()\n\n// SetLogger sets the global Logger to l.\n//\n// To see Warn messages use a logger with `l.V(1).Enabled() == true`\n// To see Info messages use a logger with `l.V(4).Enabled() == true`\n// To see Debug messages use a logger with `l.V(8).Enabled() == true`.\nfunc SetLogger(l logr.Logger) {\n\tglobalLogger.Store(&l)\n}\n\n// GetLogger returns the global logger.\nfunc GetLogger() logr.Logger {\n\treturn *globalLogger.Load()\n}\n\n// Info prints messages about the general state of the API or SDK.\n// This should usually be less than 5 messages a minute.\nfunc Info(msg string, keysAndValues ...any) {\n\tGetLogger().V(4).Info(msg, keysAndValues...)\n}\n\n// Error prints messages about exceptional states of the API or SDK.\nfunc Error(err error, msg string, keysAndValues ...any) {\n\tGetLogger().Error(err, msg, keysAndValues...)\n}\n\n// Debug prints messages about all internal changes in the API or SDK.\nfunc Debug(msg string, keysAndValues ...any) {\n\tGetLogger().V(8).Info(msg, keysAndValues...)\n}\n\n// Warn prints messages about warnings in the API or SDK.\n// Not an error but is likely more important than an informational event.\nfunc Warn(msg string, keysAndValues ...any) {\n\tGetLogger().V(1).Info(msg, keysAndValues...)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/global/meter.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage global // import \"go.opentelemetry.io/otel/internal/global\"\n\nimport (\n\t\"container/list\"\n\t\"context\"\n\t\"reflect\"\n\t\"sync\"\n\n\t\"go.opentelemetry.io/otel/metric\"\n\t\"go.opentelemetry.io/otel/metric/embedded\"\n)\n\n// meterProvider is a placeholder for a configured SDK MeterProvider.\n//\n// All MeterProvider functionality is forwarded to a delegate once\n// configured.\ntype meterProvider struct {\n\tembedded.MeterProvider\n\n\tmtx    sync.Mutex\n\tmeters map[il]*meter\n\n\tdelegate metric.MeterProvider\n}\n\n// setDelegate configures p to delegate all MeterProvider functionality to\n// provider.\n//\n// All Meters provided prior to this function call are switched out to be\n// Meters provided by provider. All instruments and callbacks are recreated and\n// delegated.\n//\n// It is guaranteed by the caller that this happens only once.\nfunc (p *meterProvider) setDelegate(provider metric.MeterProvider) {\n\tp.mtx.Lock()\n\tdefer p.mtx.Unlock()\n\n\tp.delegate = provider\n\n\tif len(p.meters) == 0 {\n\t\treturn\n\t}\n\n\tfor _, meter := range p.meters {\n\t\tmeter.setDelegate(provider)\n\t}\n\n\tp.meters = nil\n}\n\n// Meter implements MeterProvider.\nfunc (p *meterProvider) Meter(name string, opts ...metric.MeterOption) metric.Meter {\n\tp.mtx.Lock()\n\tdefer p.mtx.Unlock()\n\n\tif p.delegate != nil {\n\t\treturn p.delegate.Meter(name, opts...)\n\t}\n\n\t// At this moment it is guaranteed that no sdk is installed, save the meter in the meters map.\n\n\tc := metric.NewMeterConfig(opts...)\n\tkey := il{\n\t\tname:    name,\n\t\tversion: c.InstrumentationVersion(),\n\t\tschema:  c.SchemaURL(),\n\t\tattrs:   c.InstrumentationAttributes(),\n\t}\n\n\tif p.meters == nil {\n\t\tp.meters = make(map[il]*meter)\n\t}\n\n\tif val, ok := p.meters[key]; ok {\n\t\treturn val\n\t}\n\n\tt := &meter{name: name, opts: opts, instruments: make(map[instID]delegatedInstrument)}\n\tp.meters[key] = t\n\treturn t\n}\n\n// meter is a placeholder for a metric.Meter.\n//\n// All Meter functionality is forwarded to a delegate once configured.\n// Otherwise, all functionality is forwarded to a NoopMeter.\ntype meter struct {\n\tembedded.Meter\n\n\tname string\n\topts []metric.MeterOption\n\n\tmtx         sync.Mutex\n\tinstruments map[instID]delegatedInstrument\n\n\tregistry list.List\n\n\tdelegate metric.Meter\n}\n\ntype delegatedInstrument interface {\n\tsetDelegate(metric.Meter)\n}\n\n// instID are the identifying properties of an instrument.\ntype instID struct {\n\t// name is the name of the stream.\n\tname string\n\t// description is the description of the stream.\n\tdescription string\n\t// kind defines the functional group of the instrument.\n\tkind reflect.Type\n\t// unit is the unit of the stream.\n\tunit string\n}\n\n// setDelegate configures m to delegate all Meter functionality to Meters\n// created by provider.\n//\n// All subsequent calls to the Meter methods will be passed to the delegate.\n//\n// It is guaranteed by the caller that this happens only once.\nfunc (m *meter) setDelegate(provider metric.MeterProvider) {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tmeter := provider.Meter(m.name, m.opts...)\n\tm.delegate = meter\n\n\tfor _, inst := range m.instruments {\n\t\tinst.setDelegate(meter)\n\t}\n\n\tvar n *list.Element\n\tfor e := m.registry.Front(); e != nil; e = n {\n\t\tr := e.Value.(*registration)\n\t\tr.setDelegate(meter)\n\t\tn = e.Next()\n\t\tm.registry.Remove(e)\n\t}\n\n\tm.instruments = nil\n\tm.registry.Init()\n}\n\nfunc (m *meter) Int64Counter(name string, options ...metric.Int64CounterOption) (metric.Int64Counter, error) {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tif m.delegate != nil {\n\t\treturn m.delegate.Int64Counter(name, options...)\n\t}\n\n\tcfg := metric.NewInt64CounterConfig(options...)\n\tid := instID{\n\t\tname:        name,\n\t\tkind:        reflect.TypeFor[*siCounter](),\n\t\tdescription: cfg.Description(),\n\t\tunit:        cfg.Unit(),\n\t}\n\tif f, ok := m.instruments[id]; ok {\n\t\treturn f.(metric.Int64Counter), nil\n\t}\n\ti := &siCounter{name: name, opts: options}\n\tm.instruments[id] = i\n\treturn i, nil\n}\n\nfunc (m *meter) Int64UpDownCounter(\n\tname string,\n\toptions ...metric.Int64UpDownCounterOption,\n) (metric.Int64UpDownCounter, error) {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tif m.delegate != nil {\n\t\treturn m.delegate.Int64UpDownCounter(name, options...)\n\t}\n\n\tcfg := metric.NewInt64UpDownCounterConfig(options...)\n\tid := instID{\n\t\tname:        name,\n\t\tkind:        reflect.TypeFor[*siUpDownCounter](),\n\t\tdescription: cfg.Description(),\n\t\tunit:        cfg.Unit(),\n\t}\n\tif f, ok := m.instruments[id]; ok {\n\t\treturn f.(metric.Int64UpDownCounter), nil\n\t}\n\ti := &siUpDownCounter{name: name, opts: options}\n\tm.instruments[id] = i\n\treturn i, nil\n}\n\nfunc (m *meter) Int64Histogram(name string, options ...metric.Int64HistogramOption) (metric.Int64Histogram, error) {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tif m.delegate != nil {\n\t\treturn m.delegate.Int64Histogram(name, options...)\n\t}\n\n\tcfg := metric.NewInt64HistogramConfig(options...)\n\tid := instID{\n\t\tname:        name,\n\t\tkind:        reflect.TypeFor[*siHistogram](),\n\t\tdescription: cfg.Description(),\n\t\tunit:        cfg.Unit(),\n\t}\n\tif f, ok := m.instruments[id]; ok {\n\t\treturn f.(metric.Int64Histogram), nil\n\t}\n\ti := &siHistogram{name: name, opts: options}\n\tm.instruments[id] = i\n\treturn i, nil\n}\n\nfunc (m *meter) Int64Gauge(name string, options ...metric.Int64GaugeOption) (metric.Int64Gauge, error) {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tif m.delegate != nil {\n\t\treturn m.delegate.Int64Gauge(name, options...)\n\t}\n\n\tcfg := metric.NewInt64GaugeConfig(options...)\n\tid := instID{\n\t\tname:        name,\n\t\tkind:        reflect.TypeFor[*siGauge](),\n\t\tdescription: cfg.Description(),\n\t\tunit:        cfg.Unit(),\n\t}\n\tif f, ok := m.instruments[id]; ok {\n\t\treturn f.(metric.Int64Gauge), nil\n\t}\n\ti := &siGauge{name: name, opts: options}\n\tm.instruments[id] = i\n\treturn i, nil\n}\n\nfunc (m *meter) Int64ObservableCounter(\n\tname string,\n\toptions ...metric.Int64ObservableCounterOption,\n) (metric.Int64ObservableCounter, error) {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tif m.delegate != nil {\n\t\treturn m.delegate.Int64ObservableCounter(name, options...)\n\t}\n\n\tcfg := metric.NewInt64ObservableCounterConfig(options...)\n\tid := instID{\n\t\tname:        name,\n\t\tkind:        reflect.TypeFor[*aiCounter](),\n\t\tdescription: cfg.Description(),\n\t\tunit:        cfg.Unit(),\n\t}\n\tif f, ok := m.instruments[id]; ok {\n\t\treturn f.(metric.Int64ObservableCounter), nil\n\t}\n\ti := &aiCounter{name: name, opts: options}\n\tm.instruments[id] = i\n\treturn i, nil\n}\n\nfunc (m *meter) Int64ObservableUpDownCounter(\n\tname string,\n\toptions ...metric.Int64ObservableUpDownCounterOption,\n) (metric.Int64ObservableUpDownCounter, error) {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tif m.delegate != nil {\n\t\treturn m.delegate.Int64ObservableUpDownCounter(name, options...)\n\t}\n\n\tcfg := metric.NewInt64ObservableUpDownCounterConfig(options...)\n\tid := instID{\n\t\tname:        name,\n\t\tkind:        reflect.TypeFor[*aiUpDownCounter](),\n\t\tdescription: cfg.Description(),\n\t\tunit:        cfg.Unit(),\n\t}\n\tif f, ok := m.instruments[id]; ok {\n\t\treturn f.(metric.Int64ObservableUpDownCounter), nil\n\t}\n\ti := &aiUpDownCounter{name: name, opts: options}\n\tm.instruments[id] = i\n\treturn i, nil\n}\n\nfunc (m *meter) Int64ObservableGauge(\n\tname string,\n\toptions ...metric.Int64ObservableGaugeOption,\n) (metric.Int64ObservableGauge, error) {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tif m.delegate != nil {\n\t\treturn m.delegate.Int64ObservableGauge(name, options...)\n\t}\n\n\tcfg := metric.NewInt64ObservableGaugeConfig(options...)\n\tid := instID{\n\t\tname:        name,\n\t\tkind:        reflect.TypeFor[*aiGauge](),\n\t\tdescription: cfg.Description(),\n\t\tunit:        cfg.Unit(),\n\t}\n\tif f, ok := m.instruments[id]; ok {\n\t\treturn f.(metric.Int64ObservableGauge), nil\n\t}\n\ti := &aiGauge{name: name, opts: options}\n\tm.instruments[id] = i\n\treturn i, nil\n}\n\nfunc (m *meter) Float64Counter(name string, options ...metric.Float64CounterOption) (metric.Float64Counter, error) {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tif m.delegate != nil {\n\t\treturn m.delegate.Float64Counter(name, options...)\n\t}\n\n\tcfg := metric.NewFloat64CounterConfig(options...)\n\tid := instID{\n\t\tname:        name,\n\t\tkind:        reflect.TypeFor[*sfCounter](),\n\t\tdescription: cfg.Description(),\n\t\tunit:        cfg.Unit(),\n\t}\n\tif f, ok := m.instruments[id]; ok {\n\t\treturn f.(metric.Float64Counter), nil\n\t}\n\ti := &sfCounter{name: name, opts: options}\n\tm.instruments[id] = i\n\treturn i, nil\n}\n\nfunc (m *meter) Float64UpDownCounter(\n\tname string,\n\toptions ...metric.Float64UpDownCounterOption,\n) (metric.Float64UpDownCounter, error) {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tif m.delegate != nil {\n\t\treturn m.delegate.Float64UpDownCounter(name, options...)\n\t}\n\n\tcfg := metric.NewFloat64UpDownCounterConfig(options...)\n\tid := instID{\n\t\tname:        name,\n\t\tkind:        reflect.TypeFor[*sfUpDownCounter](),\n\t\tdescription: cfg.Description(),\n\t\tunit:        cfg.Unit(),\n\t}\n\tif f, ok := m.instruments[id]; ok {\n\t\treturn f.(metric.Float64UpDownCounter), nil\n\t}\n\ti := &sfUpDownCounter{name: name, opts: options}\n\tm.instruments[id] = i\n\treturn i, nil\n}\n\nfunc (m *meter) Float64Histogram(\n\tname string,\n\toptions ...metric.Float64HistogramOption,\n) (metric.Float64Histogram, error) {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tif m.delegate != nil {\n\t\treturn m.delegate.Float64Histogram(name, options...)\n\t}\n\n\tcfg := metric.NewFloat64HistogramConfig(options...)\n\tid := instID{\n\t\tname:        name,\n\t\tkind:        reflect.TypeFor[*sfHistogram](),\n\t\tdescription: cfg.Description(),\n\t\tunit:        cfg.Unit(),\n\t}\n\tif f, ok := m.instruments[id]; ok {\n\t\treturn f.(metric.Float64Histogram), nil\n\t}\n\ti := &sfHistogram{name: name, opts: options}\n\tm.instruments[id] = i\n\treturn i, nil\n}\n\nfunc (m *meter) Float64Gauge(name string, options ...metric.Float64GaugeOption) (metric.Float64Gauge, error) {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tif m.delegate != nil {\n\t\treturn m.delegate.Float64Gauge(name, options...)\n\t}\n\n\tcfg := metric.NewFloat64GaugeConfig(options...)\n\tid := instID{\n\t\tname:        name,\n\t\tkind:        reflect.TypeFor[*sfGauge](),\n\t\tdescription: cfg.Description(),\n\t\tunit:        cfg.Unit(),\n\t}\n\tif f, ok := m.instruments[id]; ok {\n\t\treturn f.(metric.Float64Gauge), nil\n\t}\n\ti := &sfGauge{name: name, opts: options}\n\tm.instruments[id] = i\n\treturn i, nil\n}\n\nfunc (m *meter) Float64ObservableCounter(\n\tname string,\n\toptions ...metric.Float64ObservableCounterOption,\n) (metric.Float64ObservableCounter, error) {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tif m.delegate != nil {\n\t\treturn m.delegate.Float64ObservableCounter(name, options...)\n\t}\n\n\tcfg := metric.NewFloat64ObservableCounterConfig(options...)\n\tid := instID{\n\t\tname:        name,\n\t\tkind:        reflect.TypeFor[*afCounter](),\n\t\tdescription: cfg.Description(),\n\t\tunit:        cfg.Unit(),\n\t}\n\tif f, ok := m.instruments[id]; ok {\n\t\treturn f.(metric.Float64ObservableCounter), nil\n\t}\n\ti := &afCounter{name: name, opts: options}\n\tm.instruments[id] = i\n\treturn i, nil\n}\n\nfunc (m *meter) Float64ObservableUpDownCounter(\n\tname string,\n\toptions ...metric.Float64ObservableUpDownCounterOption,\n) (metric.Float64ObservableUpDownCounter, error) {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tif m.delegate != nil {\n\t\treturn m.delegate.Float64ObservableUpDownCounter(name, options...)\n\t}\n\n\tcfg := metric.NewFloat64ObservableUpDownCounterConfig(options...)\n\tid := instID{\n\t\tname:        name,\n\t\tkind:        reflect.TypeFor[*afUpDownCounter](),\n\t\tdescription: cfg.Description(),\n\t\tunit:        cfg.Unit(),\n\t}\n\tif f, ok := m.instruments[id]; ok {\n\t\treturn f.(metric.Float64ObservableUpDownCounter), nil\n\t}\n\ti := &afUpDownCounter{name: name, opts: options}\n\tm.instruments[id] = i\n\treturn i, nil\n}\n\nfunc (m *meter) Float64ObservableGauge(\n\tname string,\n\toptions ...metric.Float64ObservableGaugeOption,\n) (metric.Float64ObservableGauge, error) {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tif m.delegate != nil {\n\t\treturn m.delegate.Float64ObservableGauge(name, options...)\n\t}\n\n\tcfg := metric.NewFloat64ObservableGaugeConfig(options...)\n\tid := instID{\n\t\tname:        name,\n\t\tkind:        reflect.TypeFor[*afGauge](),\n\t\tdescription: cfg.Description(),\n\t\tunit:        cfg.Unit(),\n\t}\n\tif f, ok := m.instruments[id]; ok {\n\t\treturn f.(metric.Float64ObservableGauge), nil\n\t}\n\ti := &afGauge{name: name, opts: options}\n\tm.instruments[id] = i\n\treturn i, nil\n}\n\n// RegisterCallback captures the function that will be called during Collect.\nfunc (m *meter) RegisterCallback(f metric.Callback, insts ...metric.Observable) (metric.Registration, error) {\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tif m.delegate != nil {\n\t\treturn m.delegate.RegisterCallback(unwrapCallback(f), unwrapInstruments(insts)...)\n\t}\n\n\treg := &registration{instruments: insts, function: f}\n\te := m.registry.PushBack(reg)\n\treg.unreg = func() error {\n\t\tm.mtx.Lock()\n\t\t_ = m.registry.Remove(e)\n\t\tm.mtx.Unlock()\n\t\treturn nil\n\t}\n\treturn reg, nil\n}\n\nfunc unwrapInstruments(instruments []metric.Observable) []metric.Observable {\n\tout := make([]metric.Observable, 0, len(instruments))\n\n\tfor _, inst := range instruments {\n\t\tif in, ok := inst.(unwrapper); ok {\n\t\t\tout = append(out, in.unwrap())\n\t\t} else {\n\t\t\tout = append(out, inst)\n\t\t}\n\t}\n\n\treturn out\n}\n\ntype registration struct {\n\tembedded.Registration\n\n\tinstruments []metric.Observable\n\tfunction    metric.Callback\n\n\tunreg   func() error\n\tunregMu sync.Mutex\n}\n\ntype unwrapObs struct {\n\tembedded.Observer\n\tobs metric.Observer\n}\n\n// unwrapFloat64Observable returns an expected metric.Float64Observable after\n// unwrapping the global object.\nfunc unwrapFloat64Observable(inst metric.Float64Observable) metric.Float64Observable {\n\tif unwrapped, ok := inst.(unwrapper); ok {\n\t\tif floatObs, ok := unwrapped.unwrap().(metric.Float64Observable); ok {\n\t\t\t// Note: if the unwrapped object does not\n\t\t\t// unwrap as an observable for either of the\n\t\t\t// predicates here, it means an internal bug in\n\t\t\t// this package.  We avoid logging an error in\n\t\t\t// this case, because the SDK has to try its\n\t\t\t// own type conversion on the object.  The SDK\n\t\t\t// will see this and be forced to respond with\n\t\t\t// its own error.\n\t\t\t//\n\t\t\t// This code uses a double-nested if statement\n\t\t\t// to avoid creating a branch that is\n\t\t\t// impossible to cover.\n\t\t\tinst = floatObs\n\t\t}\n\t}\n\treturn inst\n}\n\n// unwrapInt64Observable returns an expected metric.Int64Observable after\n// unwrapping the global object.\nfunc unwrapInt64Observable(inst metric.Int64Observable) metric.Int64Observable {\n\tif unwrapped, ok := inst.(unwrapper); ok {\n\t\tif unint, ok := unwrapped.unwrap().(metric.Int64Observable); ok {\n\t\t\t// See the comment in unwrapFloat64Observable().\n\t\t\tinst = unint\n\t\t}\n\t}\n\treturn inst\n}\n\nfunc (uo *unwrapObs) ObserveFloat64(inst metric.Float64Observable, value float64, opts ...metric.ObserveOption) {\n\tuo.obs.ObserveFloat64(unwrapFloat64Observable(inst), value, opts...)\n}\n\nfunc (uo *unwrapObs) ObserveInt64(inst metric.Int64Observable, value int64, opts ...metric.ObserveOption) {\n\tuo.obs.ObserveInt64(unwrapInt64Observable(inst), value, opts...)\n}\n\nfunc unwrapCallback(f metric.Callback) metric.Callback {\n\treturn func(ctx context.Context, obs metric.Observer) error {\n\t\treturn f(ctx, &unwrapObs{obs: obs})\n\t}\n}\n\nfunc (c *registration) setDelegate(m metric.Meter) {\n\tc.unregMu.Lock()\n\tdefer c.unregMu.Unlock()\n\n\tif c.unreg == nil {\n\t\t// Unregister already called.\n\t\treturn\n\t}\n\n\treg, err := m.RegisterCallback(unwrapCallback(c.function), unwrapInstruments(c.instruments)...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\n\tc.unreg = reg.Unregister\n}\n\nfunc (c *registration) Unregister() error {\n\tc.unregMu.Lock()\n\tdefer c.unregMu.Unlock()\n\tif c.unreg == nil {\n\t\t// Unregister already called.\n\t\treturn nil\n\t}\n\n\tvar err error\n\terr, c.unreg = c.unreg(), nil\n\treturn err\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/global/propagator.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage global // import \"go.opentelemetry.io/otel/internal/global\"\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"go.opentelemetry.io/otel/propagation\"\n)\n\n// textMapPropagator is a default TextMapPropagator that delegates calls to a\n// registered delegate if one is set, otherwise it defaults to delegating the\n// calls to a the default no-op propagation.TextMapPropagator.\ntype textMapPropagator struct {\n\tmtx      sync.Mutex\n\tonce     sync.Once\n\tdelegate propagation.TextMapPropagator\n\tnoop     propagation.TextMapPropagator\n}\n\n// Compile-time guarantee that textMapPropagator implements the\n// propagation.TextMapPropagator interface.\nvar _ propagation.TextMapPropagator = (*textMapPropagator)(nil)\n\nfunc newTextMapPropagator() *textMapPropagator {\n\treturn &textMapPropagator{\n\t\tnoop: propagation.NewCompositeTextMapPropagator(),\n\t}\n}\n\n// SetDelegate sets a delegate propagation.TextMapPropagator that all calls are\n// forwarded to. Delegation can only be performed once, all subsequent calls\n// perform no delegation.\nfunc (p *textMapPropagator) SetDelegate(delegate propagation.TextMapPropagator) {\n\tif delegate == nil {\n\t\treturn\n\t}\n\n\tp.mtx.Lock()\n\tp.once.Do(func() { p.delegate = delegate })\n\tp.mtx.Unlock()\n}\n\n// effectiveDelegate returns the current delegate of p if one is set,\n// otherwise the default noop TextMapPropagator is returned. This method\n// can be called concurrently.\nfunc (p *textMapPropagator) effectiveDelegate() propagation.TextMapPropagator {\n\tp.mtx.Lock()\n\tdefer p.mtx.Unlock()\n\tif p.delegate != nil {\n\t\treturn p.delegate\n\t}\n\treturn p.noop\n}\n\n// Inject set cross-cutting concerns from the Context into the carrier.\nfunc (p *textMapPropagator) Inject(ctx context.Context, carrier propagation.TextMapCarrier) {\n\tp.effectiveDelegate().Inject(ctx, carrier)\n}\n\n// Extract reads cross-cutting concerns from the carrier into a Context.\nfunc (p *textMapPropagator) Extract(ctx context.Context, carrier propagation.TextMapCarrier) context.Context {\n\treturn p.effectiveDelegate().Extract(ctx, carrier)\n}\n\n// Fields returns the keys whose values are set with Inject.\nfunc (p *textMapPropagator) Fields() []string {\n\treturn p.effectiveDelegate().Fields()\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/global/state.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage global // import \"go.opentelemetry.io/otel/internal/global\"\n\nimport (\n\t\"errors\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\t\"go.opentelemetry.io/otel/metric\"\n\t\"go.opentelemetry.io/otel/propagation\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\ntype (\n\terrorHandlerHolder struct {\n\t\teh ErrorHandler\n\t}\n\n\ttracerProviderHolder struct {\n\t\ttp trace.TracerProvider\n\t}\n\n\tpropagatorsHolder struct {\n\t\ttm propagation.TextMapPropagator\n\t}\n\n\tmeterProviderHolder struct {\n\t\tmp metric.MeterProvider\n\t}\n)\n\nvar (\n\tglobalErrorHandler  = defaultErrorHandler()\n\tglobalTracer        = defaultTracerValue()\n\tglobalPropagators   = defaultPropagatorsValue()\n\tglobalMeterProvider = defaultMeterProvider()\n\n\tdelegateErrorHandlerOnce      sync.Once\n\tdelegateTraceOnce             sync.Once\n\tdelegateTextMapPropagatorOnce sync.Once\n\tdelegateMeterOnce             sync.Once\n)\n\n// GetErrorHandler returns the global ErrorHandler instance.\n//\n// The default ErrorHandler instance returned will log all errors to STDERR\n// until an override ErrorHandler is set with SetErrorHandler. All\n// ErrorHandler returned prior to this will automatically forward errors to\n// the set instance instead of logging.\n//\n// Subsequent calls to SetErrorHandler after the first will not forward errors\n// to the new ErrorHandler for prior returned instances.\nfunc GetErrorHandler() ErrorHandler {\n\treturn globalErrorHandler.Load().(errorHandlerHolder).eh\n}\n\n// SetErrorHandler sets the global ErrorHandler to h.\n//\n// The first time this is called all ErrorHandler previously returned from\n// GetErrorHandler will send errors to h instead of the default logging\n// ErrorHandler. Subsequent calls will set the global ErrorHandler, but not\n// delegate errors to h.\nfunc SetErrorHandler(h ErrorHandler) {\n\tcurrent := GetErrorHandler()\n\n\tif _, cOk := current.(*ErrDelegator); cOk {\n\t\tif _, ehOk := h.(*ErrDelegator); ehOk && current == h {\n\t\t\t// Do not assign to the delegate of the default ErrDelegator to be\n\t\t\t// itself.\n\t\t\tError(\n\t\t\t\terrors.New(\"no ErrorHandler delegate configured\"),\n\t\t\t\t\"ErrorHandler remains its current value.\",\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t}\n\n\tdelegateErrorHandlerOnce.Do(func() {\n\t\tif def, ok := current.(*ErrDelegator); ok {\n\t\t\tdef.setDelegate(h)\n\t\t}\n\t})\n\tglobalErrorHandler.Store(errorHandlerHolder{eh: h})\n}\n\n// TracerProvider is the internal implementation for global.TracerProvider.\nfunc TracerProvider() trace.TracerProvider {\n\treturn globalTracer.Load().(tracerProviderHolder).tp\n}\n\n// SetTracerProvider is the internal implementation for global.SetTracerProvider.\nfunc SetTracerProvider(tp trace.TracerProvider) {\n\tcurrent := TracerProvider()\n\n\tif _, cOk := current.(*tracerProvider); cOk {\n\t\tif _, tpOk := tp.(*tracerProvider); tpOk && current == tp {\n\t\t\t// Do not assign the default delegating TracerProvider to delegate\n\t\t\t// to itself.\n\t\t\tError(\n\t\t\t\terrors.New(\"no delegate configured in tracer provider\"),\n\t\t\t\t\"Setting tracer provider to its current value. No delegate will be configured\",\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t}\n\n\tdelegateTraceOnce.Do(func() {\n\t\tif def, ok := current.(*tracerProvider); ok {\n\t\t\tdef.setDelegate(tp)\n\t\t}\n\t})\n\tglobalTracer.Store(tracerProviderHolder{tp: tp})\n}\n\n// TextMapPropagator is the internal implementation for global.TextMapPropagator.\nfunc TextMapPropagator() propagation.TextMapPropagator {\n\treturn globalPropagators.Load().(propagatorsHolder).tm\n}\n\n// SetTextMapPropagator is the internal implementation for global.SetTextMapPropagator.\nfunc SetTextMapPropagator(p propagation.TextMapPropagator) {\n\tcurrent := TextMapPropagator()\n\n\tif _, cOk := current.(*textMapPropagator); cOk {\n\t\tif _, pOk := p.(*textMapPropagator); pOk && current == p {\n\t\t\t// Do not assign the default delegating TextMapPropagator to\n\t\t\t// delegate to itself.\n\t\t\tError(\n\t\t\t\terrors.New(\"no delegate configured in text map propagator\"),\n\t\t\t\t\"Setting text map propagator to its current value. No delegate will be configured\",\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// For the textMapPropagator already returned by TextMapPropagator\n\t// delegate to p.\n\tdelegateTextMapPropagatorOnce.Do(func() {\n\t\tif def, ok := current.(*textMapPropagator); ok {\n\t\t\tdef.SetDelegate(p)\n\t\t}\n\t})\n\t// Return p when subsequent calls to TextMapPropagator are made.\n\tglobalPropagators.Store(propagatorsHolder{tm: p})\n}\n\n// MeterProvider is the internal implementation for global.MeterProvider.\nfunc MeterProvider() metric.MeterProvider {\n\treturn globalMeterProvider.Load().(meterProviderHolder).mp\n}\n\n// SetMeterProvider is the internal implementation for global.SetMeterProvider.\nfunc SetMeterProvider(mp metric.MeterProvider) {\n\tcurrent := MeterProvider()\n\tif _, cOk := current.(*meterProvider); cOk {\n\t\tif _, mpOk := mp.(*meterProvider); mpOk && current == mp {\n\t\t\t// Do not assign the default delegating MeterProvider to delegate\n\t\t\t// to itself.\n\t\t\tError(\n\t\t\t\terrors.New(\"no delegate configured in meter provider\"),\n\t\t\t\t\"Setting meter provider to its current value. No delegate will be configured\",\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t}\n\n\tdelegateMeterOnce.Do(func() {\n\t\tif def, ok := current.(*meterProvider); ok {\n\t\t\tdef.setDelegate(mp)\n\t\t}\n\t})\n\tglobalMeterProvider.Store(meterProviderHolder{mp: mp})\n}\n\nfunc defaultErrorHandler() *atomic.Value {\n\tv := &atomic.Value{}\n\tv.Store(errorHandlerHolder{eh: &ErrDelegator{}})\n\treturn v\n}\n\nfunc defaultTracerValue() *atomic.Value {\n\tv := &atomic.Value{}\n\tv.Store(tracerProviderHolder{tp: &tracerProvider{}})\n\treturn v\n}\n\nfunc defaultPropagatorsValue() *atomic.Value {\n\tv := &atomic.Value{}\n\tv.Store(propagatorsHolder{tm: newTextMapPropagator()})\n\treturn v\n}\n\nfunc defaultMeterProvider() *atomic.Value {\n\tv := &atomic.Value{}\n\tv.Store(meterProviderHolder{mp: &meterProvider{}})\n\treturn v\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/global/trace.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage global // import \"go.opentelemetry.io/otel/internal/global\"\n\n/*\nThis file contains the forwarding implementation of the TracerProvider used as\nthe default global instance. Prior to initialization of an SDK, Tracers\nreturned by the global TracerProvider will provide no-op functionality. This\nmeans that all Span created prior to initialization are no-op Spans.\n\nOnce an SDK has been initialized, all provided no-op Tracers are swapped for\nTracers provided by the SDK defined TracerProvider. However, any Span started\nprior to this initialization does not change its behavior. Meaning, the Span\nremains a no-op Span.\n\nThe implementation to track and swap Tracers locks all new Tracer creation\nuntil the swap is complete. This assumes that this operation is not\nperformance-critical. If that assumption is incorrect, be sure to configure an\nSDK prior to any Tracer creation.\n*/\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\t\"go.opentelemetry.io/auto/sdk\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n\t\"go.opentelemetry.io/otel/trace\"\n\t\"go.opentelemetry.io/otel/trace/embedded\"\n)\n\n// tracerProvider is a placeholder for a configured SDK TracerProvider.\n//\n// All TracerProvider functionality is forwarded to a delegate once\n// configured.\ntype tracerProvider struct {\n\tembedded.TracerProvider\n\n\tmtx      sync.Mutex\n\ttracers  map[il]*tracer\n\tdelegate trace.TracerProvider\n}\n\n// Compile-time guarantee that tracerProvider implements the TracerProvider\n// interface.\nvar _ trace.TracerProvider = &tracerProvider{}\n\n// setDelegate configures p to delegate all TracerProvider functionality to\n// provider.\n//\n// All Tracers provided prior to this function call are switched out to be\n// Tracers provided by provider.\n//\n// It is guaranteed by the caller that this happens only once.\nfunc (p *tracerProvider) setDelegate(provider trace.TracerProvider) {\n\tp.mtx.Lock()\n\tdefer p.mtx.Unlock()\n\n\tp.delegate = provider\n\n\tif len(p.tracers) == 0 {\n\t\treturn\n\t}\n\n\tfor _, t := range p.tracers {\n\t\tt.setDelegate(provider)\n\t}\n\n\tp.tracers = nil\n}\n\n// Tracer implements TracerProvider.\nfunc (p *tracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer {\n\tp.mtx.Lock()\n\tdefer p.mtx.Unlock()\n\n\tif p.delegate != nil {\n\t\treturn p.delegate.Tracer(name, opts...)\n\t}\n\n\t// At this moment it is guaranteed that no sdk is installed, save the tracer in the tracers map.\n\n\tc := trace.NewTracerConfig(opts...)\n\tkey := il{\n\t\tname:    name,\n\t\tversion: c.InstrumentationVersion(),\n\t\tschema:  c.SchemaURL(),\n\t\tattrs:   c.InstrumentationAttributes(),\n\t}\n\n\tif p.tracers == nil {\n\t\tp.tracers = make(map[il]*tracer)\n\t}\n\n\tif val, ok := p.tracers[key]; ok {\n\t\treturn val\n\t}\n\n\tt := &tracer{name: name, opts: opts, provider: p}\n\tp.tracers[key] = t\n\treturn t\n}\n\ntype il struct {\n\tname    string\n\tversion string\n\tschema  string\n\tattrs   attribute.Set\n}\n\n// tracer is a placeholder for a trace.Tracer.\n//\n// All Tracer functionality is forwarded to a delegate once configured.\n// Otherwise, all functionality is forwarded to a NoopTracer.\ntype tracer struct {\n\tembedded.Tracer\n\n\tname     string\n\topts     []trace.TracerOption\n\tprovider *tracerProvider\n\n\tdelegate atomic.Value\n}\n\n// Compile-time guarantee that tracer implements the trace.Tracer interface.\nvar _ trace.Tracer = &tracer{}\n\n// setDelegate configures t to delegate all Tracer functionality to Tracers\n// created by provider.\n//\n// All subsequent calls to the Tracer methods will be passed to the delegate.\n//\n// It is guaranteed by the caller that this happens only once.\nfunc (t *tracer) setDelegate(provider trace.TracerProvider) {\n\tt.delegate.Store(provider.Tracer(t.name, t.opts...))\n}\n\n// Start implements trace.Tracer by forwarding the call to t.delegate if\n// set, otherwise it forwards the call to a NoopTracer.\nfunc (t *tracer) Start(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) {\n\tdelegate := t.delegate.Load()\n\tif delegate != nil {\n\t\treturn delegate.(trace.Tracer).Start(ctx, name, opts...)\n\t}\n\n\treturn t.newSpan(ctx, autoInstEnabled, name, opts)\n}\n\n// autoInstEnabled determines if the auto-instrumentation SDK span is returned\n// from the tracer when not backed by a delegate and auto-instrumentation has\n// attached to this process.\n//\n// The auto-instrumentation is expected to overwrite this value to true when it\n// attaches. By default, this will point to false and mean a tracer will return\n// a nonRecordingSpan by default.\nvar autoInstEnabled = new(bool)\n\n// newSpan is called by tracer.Start so auto-instrumentation can attach an eBPF\n// uprobe to this code.\n//\n// \"noinline\" pragma prevents the method from ever being inlined.\n//\n//go:noinline\nfunc (t *tracer) newSpan(\n\tctx context.Context,\n\tautoSpan *bool,\n\tname string,\n\topts []trace.SpanStartOption,\n) (context.Context, trace.Span) {\n\t// autoInstEnabled is passed to newSpan via the autoSpan parameter. This is\n\t// so the auto-instrumentation can define a uprobe for (*t).newSpan and be\n\t// provided with the address of the bool autoInstEnabled points to. It\n\t// needs to be a parameter so that pointer can be reliably determined, it\n\t// should not be read from the global.\n\n\tif *autoSpan {\n\t\ttracer := sdk.TracerProvider().Tracer(t.name, t.opts...)\n\t\treturn tracer.Start(ctx, name, opts...)\n\t}\n\n\ts := nonRecordingSpan{sc: trace.SpanContextFromContext(ctx), tracer: t}\n\tctx = trace.ContextWithSpan(ctx, s)\n\treturn ctx, s\n}\n\n// nonRecordingSpan is a minimal implementation of a Span that wraps a\n// SpanContext. It performs no operations other than to return the wrapped\n// SpanContext.\ntype nonRecordingSpan struct {\n\tembedded.Span\n\n\tsc     trace.SpanContext\n\ttracer *tracer\n}\n\nvar _ trace.Span = nonRecordingSpan{}\n\n// SpanContext returns the wrapped SpanContext.\nfunc (s nonRecordingSpan) SpanContext() trace.SpanContext { return s.sc }\n\n// IsRecording always returns false.\nfunc (nonRecordingSpan) IsRecording() bool { return false }\n\n// SetStatus does nothing.\nfunc (nonRecordingSpan) SetStatus(codes.Code, string) {}\n\n// SetError does nothing.\nfunc (nonRecordingSpan) SetError(bool) {}\n\n// SetAttributes does nothing.\nfunc (nonRecordingSpan) SetAttributes(...attribute.KeyValue) {}\n\n// End does nothing.\nfunc (nonRecordingSpan) End(...trace.SpanEndOption) {}\n\n// RecordError does nothing.\nfunc (nonRecordingSpan) RecordError(error, ...trace.EventOption) {}\n\n// AddEvent does nothing.\nfunc (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {}\n\n// AddLink does nothing.\nfunc (nonRecordingSpan) AddLink(trace.Link) {}\n\n// SetName does nothing.\nfunc (nonRecordingSpan) SetName(string) {}\n\nfunc (s nonRecordingSpan) TracerProvider() trace.TracerProvider { return s.tracer.provider }\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal_logging.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage otel // import \"go.opentelemetry.io/otel\"\n\nimport (\n\t\"github.com/go-logr/logr\"\n\n\t\"go.opentelemetry.io/otel/internal/global\"\n)\n\n// SetLogger configures the logger used internally to opentelemetry.\nfunc SetLogger(logger logr.Logger) {\n\tglobal.SetLogger(logger)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n--------------------------------------------------------------------------------\n\nCopyright 2009 The Go Authors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google LLC nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/README.md",
    "content": "# Metric API\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/metric)](https://pkg.go.dev/go.opentelemetry.io/otel/metric)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage metric // import \"go.opentelemetry.io/otel/metric\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/metric/embedded\"\n)\n\n// Float64Observable describes a set of instruments used asynchronously to\n// record float64 measurements once per collection cycle. Observations of\n// these instruments are only made within a callback.\n//\n// Warning: Methods may be added to this interface in minor releases.\ntype Float64Observable interface {\n\tObservable\n\n\tfloat64Observable()\n}\n\n// Float64ObservableCounter is an instrument used to asynchronously record\n// increasing float64 measurements once per collection cycle. Observations are\n// only made within a callback for this instrument. The value observed is\n// assumed the to be the cumulative sum of the count.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for\n// unimplemented methods.\ntype Float64ObservableCounter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Float64ObservableCounter\n\n\tFloat64Observable\n}\n\n// Float64ObservableCounterConfig contains options for asynchronous counter\n// instruments that record float64 values.\ntype Float64ObservableCounterConfig struct {\n\tdescription string\n\tunit        string\n\tcallbacks   []Float64Callback\n}\n\n// NewFloat64ObservableCounterConfig returns a new\n// [Float64ObservableCounterConfig] with all opts applied.\nfunc NewFloat64ObservableCounterConfig(opts ...Float64ObservableCounterOption) Float64ObservableCounterConfig {\n\tvar config Float64ObservableCounterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyFloat64ObservableCounter(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Float64ObservableCounterConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Float64ObservableCounterConfig) Unit() string {\n\treturn c.unit\n}\n\n// Callbacks returns the configured callbacks.\nfunc (c Float64ObservableCounterConfig) Callbacks() []Float64Callback {\n\treturn c.callbacks\n}\n\n// Float64ObservableCounterOption applies options to a\n// [Float64ObservableCounterConfig]. See [Float64ObservableOption] and\n// [InstrumentOption] for other options that can be used as a\n// Float64ObservableCounterOption.\ntype Float64ObservableCounterOption interface {\n\tapplyFloat64ObservableCounter(Float64ObservableCounterConfig) Float64ObservableCounterConfig\n}\n\n// Float64ObservableUpDownCounter is an instrument used to asynchronously\n// record float64 measurements once per collection cycle. Observations are only\n// made within a callback for this instrument. The value observed is assumed\n// the to be the cumulative sum of the count.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Float64ObservableUpDownCounter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Float64ObservableUpDownCounter\n\n\tFloat64Observable\n}\n\n// Float64ObservableUpDownCounterConfig contains options for asynchronous\n// counter instruments that record float64 values.\ntype Float64ObservableUpDownCounterConfig struct {\n\tdescription string\n\tunit        string\n\tcallbacks   []Float64Callback\n}\n\n// NewFloat64ObservableUpDownCounterConfig returns a new\n// [Float64ObservableUpDownCounterConfig] with all opts applied.\nfunc NewFloat64ObservableUpDownCounterConfig(\n\topts ...Float64ObservableUpDownCounterOption,\n) Float64ObservableUpDownCounterConfig {\n\tvar config Float64ObservableUpDownCounterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyFloat64ObservableUpDownCounter(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Float64ObservableUpDownCounterConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Float64ObservableUpDownCounterConfig) Unit() string {\n\treturn c.unit\n}\n\n// Callbacks returns the configured callbacks.\nfunc (c Float64ObservableUpDownCounterConfig) Callbacks() []Float64Callback {\n\treturn c.callbacks\n}\n\n// Float64ObservableUpDownCounterOption applies options to a\n// [Float64ObservableUpDownCounterConfig]. See [Float64ObservableOption] and\n// [InstrumentOption] for other options that can be used as a\n// Float64ObservableUpDownCounterOption.\ntype Float64ObservableUpDownCounterOption interface {\n\tapplyFloat64ObservableUpDownCounter(Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig\n}\n\n// Float64ObservableGauge is an instrument used to asynchronously record\n// instantaneous float64 measurements once per collection cycle. Observations\n// are only made within a callback for this instrument.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Float64ObservableGauge interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Float64ObservableGauge\n\n\tFloat64Observable\n}\n\n// Float64ObservableGaugeConfig contains options for asynchronous counter\n// instruments that record float64 values.\ntype Float64ObservableGaugeConfig struct {\n\tdescription string\n\tunit        string\n\tcallbacks   []Float64Callback\n}\n\n// NewFloat64ObservableGaugeConfig returns a new [Float64ObservableGaugeConfig]\n// with all opts applied.\nfunc NewFloat64ObservableGaugeConfig(opts ...Float64ObservableGaugeOption) Float64ObservableGaugeConfig {\n\tvar config Float64ObservableGaugeConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyFloat64ObservableGauge(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Float64ObservableGaugeConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Float64ObservableGaugeConfig) Unit() string {\n\treturn c.unit\n}\n\n// Callbacks returns the configured callbacks.\nfunc (c Float64ObservableGaugeConfig) Callbacks() []Float64Callback {\n\treturn c.callbacks\n}\n\n// Float64ObservableGaugeOption applies options to a\n// [Float64ObservableGaugeConfig]. See [Float64ObservableOption] and\n// [InstrumentOption] for other options that can be used as a\n// Float64ObservableGaugeOption.\ntype Float64ObservableGaugeOption interface {\n\tapplyFloat64ObservableGauge(Float64ObservableGaugeConfig) Float64ObservableGaugeConfig\n}\n\n// Float64Observer is a recorder of float64 measurements.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Float64Observer interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Float64Observer\n\n\t// Observe records the float64 value.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tObserve(value float64, options ...ObserveOption)\n}\n\n// Float64Callback is a function registered with a Meter that makes\n// observations for a Float64Observable instrument it is registered with.\n// Calls to the Float64Observer record measurement values for the\n// Float64Observable.\n//\n// The function needs to complete in a finite amount of time and the deadline\n// of the passed context is expected to be honored.\n//\n// The function needs to make unique observations across all registered\n// Float64Callbacks. Meaning, it should not report measurements with the same\n// attributes as another Float64Callbacks also registered for the same\n// instrument.\n//\n// The function needs to be reentrant and concurrent safe.\n//\n// Note that Go's mutexes are not reentrant, and locking a mutex takes\n// an indefinite amount of time. It is therefore advised to avoid\n// using mutexes inside callbacks.\ntype Float64Callback func(context.Context, Float64Observer) error\n\n// Float64ObservableOption applies options to float64 Observer instruments.\ntype Float64ObservableOption interface {\n\tFloat64ObservableCounterOption\n\tFloat64ObservableUpDownCounterOption\n\tFloat64ObservableGaugeOption\n}\n\ntype float64CallbackOpt struct {\n\tcback Float64Callback\n}\n\nfunc (o float64CallbackOpt) applyFloat64ObservableCounter(\n\tcfg Float64ObservableCounterConfig,\n) Float64ObservableCounterConfig {\n\tcfg.callbacks = append(cfg.callbacks, o.cback)\n\treturn cfg\n}\n\nfunc (o float64CallbackOpt) applyFloat64ObservableUpDownCounter(\n\tcfg Float64ObservableUpDownCounterConfig,\n) Float64ObservableUpDownCounterConfig {\n\tcfg.callbacks = append(cfg.callbacks, o.cback)\n\treturn cfg\n}\n\nfunc (o float64CallbackOpt) applyFloat64ObservableGauge(cfg Float64ObservableGaugeConfig) Float64ObservableGaugeConfig {\n\tcfg.callbacks = append(cfg.callbacks, o.cback)\n\treturn cfg\n}\n\n// WithFloat64Callback adds callback to be called for an instrument.\nfunc WithFloat64Callback(callback Float64Callback) Float64ObservableOption {\n\treturn float64CallbackOpt{callback}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/asyncint64.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage metric // import \"go.opentelemetry.io/otel/metric\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/metric/embedded\"\n)\n\n// Int64Observable describes a set of instruments used asynchronously to record\n// int64 measurements once per collection cycle. Observations of these\n// instruments are only made within a callback.\n//\n// Warning: Methods may be added to this interface in minor releases.\ntype Int64Observable interface {\n\tObservable\n\n\tint64Observable()\n}\n\n// Int64ObservableCounter is an instrument used to asynchronously record\n// increasing int64 measurements once per collection cycle. Observations are\n// only made within a callback for this instrument. The value observed is\n// assumed the to be the cumulative sum of the count.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Int64ObservableCounter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Int64ObservableCounter\n\n\tInt64Observable\n}\n\n// Int64ObservableCounterConfig contains options for asynchronous counter\n// instruments that record int64 values.\ntype Int64ObservableCounterConfig struct {\n\tdescription string\n\tunit        string\n\tcallbacks   []Int64Callback\n}\n\n// NewInt64ObservableCounterConfig returns a new [Int64ObservableCounterConfig]\n// with all opts applied.\nfunc NewInt64ObservableCounterConfig(opts ...Int64ObservableCounterOption) Int64ObservableCounterConfig {\n\tvar config Int64ObservableCounterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyInt64ObservableCounter(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Int64ObservableCounterConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Int64ObservableCounterConfig) Unit() string {\n\treturn c.unit\n}\n\n// Callbacks returns the configured callbacks.\nfunc (c Int64ObservableCounterConfig) Callbacks() []Int64Callback {\n\treturn c.callbacks\n}\n\n// Int64ObservableCounterOption applies options to a\n// [Int64ObservableCounterConfig]. See [Int64ObservableOption] and\n// [InstrumentOption] for other options that can be used as an\n// Int64ObservableCounterOption.\ntype Int64ObservableCounterOption interface {\n\tapplyInt64ObservableCounter(Int64ObservableCounterConfig) Int64ObservableCounterConfig\n}\n\n// Int64ObservableUpDownCounter is an instrument used to asynchronously record\n// int64 measurements once per collection cycle. Observations are only made\n// within a callback for this instrument. The value observed is assumed the to\n// be the cumulative sum of the count.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Int64ObservableUpDownCounter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Int64ObservableUpDownCounter\n\n\tInt64Observable\n}\n\n// Int64ObservableUpDownCounterConfig contains options for asynchronous counter\n// instruments that record int64 values.\ntype Int64ObservableUpDownCounterConfig struct {\n\tdescription string\n\tunit        string\n\tcallbacks   []Int64Callback\n}\n\n// NewInt64ObservableUpDownCounterConfig returns a new\n// [Int64ObservableUpDownCounterConfig] with all opts applied.\nfunc NewInt64ObservableUpDownCounterConfig(\n\topts ...Int64ObservableUpDownCounterOption,\n) Int64ObservableUpDownCounterConfig {\n\tvar config Int64ObservableUpDownCounterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyInt64ObservableUpDownCounter(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Int64ObservableUpDownCounterConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Int64ObservableUpDownCounterConfig) Unit() string {\n\treturn c.unit\n}\n\n// Callbacks returns the configured callbacks.\nfunc (c Int64ObservableUpDownCounterConfig) Callbacks() []Int64Callback {\n\treturn c.callbacks\n}\n\n// Int64ObservableUpDownCounterOption applies options to a\n// [Int64ObservableUpDownCounterConfig]. See [Int64ObservableOption] and\n// [InstrumentOption] for other options that can be used as an\n// Int64ObservableUpDownCounterOption.\ntype Int64ObservableUpDownCounterOption interface {\n\tapplyInt64ObservableUpDownCounter(Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig\n}\n\n// Int64ObservableGauge is an instrument used to asynchronously record\n// instantaneous int64 measurements once per collection cycle. Observations are\n// only made within a callback for this instrument.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Int64ObservableGauge interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Int64ObservableGauge\n\n\tInt64Observable\n}\n\n// Int64ObservableGaugeConfig contains options for asynchronous counter\n// instruments that record int64 values.\ntype Int64ObservableGaugeConfig struct {\n\tdescription string\n\tunit        string\n\tcallbacks   []Int64Callback\n}\n\n// NewInt64ObservableGaugeConfig returns a new [Int64ObservableGaugeConfig]\n// with all opts applied.\nfunc NewInt64ObservableGaugeConfig(opts ...Int64ObservableGaugeOption) Int64ObservableGaugeConfig {\n\tvar config Int64ObservableGaugeConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyInt64ObservableGauge(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Int64ObservableGaugeConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Int64ObservableGaugeConfig) Unit() string {\n\treturn c.unit\n}\n\n// Callbacks returns the configured callbacks.\nfunc (c Int64ObservableGaugeConfig) Callbacks() []Int64Callback {\n\treturn c.callbacks\n}\n\n// Int64ObservableGaugeOption applies options to a\n// [Int64ObservableGaugeConfig]. See [Int64ObservableOption] and\n// [InstrumentOption] for other options that can be used as an\n// Int64ObservableGaugeOption.\ntype Int64ObservableGaugeOption interface {\n\tapplyInt64ObservableGauge(Int64ObservableGaugeConfig) Int64ObservableGaugeConfig\n}\n\n// Int64Observer is a recorder of int64 measurements.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Int64Observer interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Int64Observer\n\n\t// Observe records the int64 value.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tObserve(value int64, options ...ObserveOption)\n}\n\n// Int64Callback is a function registered with a Meter that makes observations\n// for an Int64Observable instrument it is registered with. Calls to the\n// Int64Observer record measurement values for the Int64Observable.\n//\n// The function needs to complete in a finite amount of time and the deadline\n// of the passed context is expected to be honored.\n//\n// The function needs to make unique observations across all registered\n// Int64Callbacks. Meaning, it should not report measurements with the same\n// attributes as another Int64Callbacks also registered for the same\n// instrument.\n//\n// The function needs to be reentrant and concurrent safe.\n//\n// Note that Go's mutexes are not reentrant, and locking a mutex takes\n// an indefinite amount of time. It is therefore advised to avoid\n// using mutexes inside callbacks.\ntype Int64Callback func(context.Context, Int64Observer) error\n\n// Int64ObservableOption applies options to int64 Observer instruments.\ntype Int64ObservableOption interface {\n\tInt64ObservableCounterOption\n\tInt64ObservableUpDownCounterOption\n\tInt64ObservableGaugeOption\n}\n\ntype int64CallbackOpt struct {\n\tcback Int64Callback\n}\n\nfunc (o int64CallbackOpt) applyInt64ObservableCounter(cfg Int64ObservableCounterConfig) Int64ObservableCounterConfig {\n\tcfg.callbacks = append(cfg.callbacks, o.cback)\n\treturn cfg\n}\n\nfunc (o int64CallbackOpt) applyInt64ObservableUpDownCounter(\n\tcfg Int64ObservableUpDownCounterConfig,\n) Int64ObservableUpDownCounterConfig {\n\tcfg.callbacks = append(cfg.callbacks, o.cback)\n\treturn cfg\n}\n\nfunc (o int64CallbackOpt) applyInt64ObservableGauge(cfg Int64ObservableGaugeConfig) Int64ObservableGaugeConfig {\n\tcfg.callbacks = append(cfg.callbacks, o.cback)\n\treturn cfg\n}\n\n// WithInt64Callback adds callback to be called for an instrument.\nfunc WithInt64Callback(callback Int64Callback) Int64ObservableOption {\n\treturn int64CallbackOpt{callback}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/config.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage metric // import \"go.opentelemetry.io/otel/metric\"\n\nimport (\n\t\"slices\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n)\n\n// MeterConfig contains options for Meters.\ntype MeterConfig struct {\n\tinstrumentationVersion string\n\tschemaURL              string\n\tattrs                  attribute.Set\n\n\t// Ensure forward compatibility by explicitly making this not comparable.\n\tnoCmp [0]func() //nolint: unused  // This is indeed used.\n}\n\n// InstrumentationVersion returns the version of the library providing\n// instrumentation.\nfunc (cfg MeterConfig) InstrumentationVersion() string {\n\treturn cfg.instrumentationVersion\n}\n\n// InstrumentationAttributes returns the attributes associated with the library\n// providing instrumentation.\nfunc (cfg MeterConfig) InstrumentationAttributes() attribute.Set {\n\treturn cfg.attrs\n}\n\n// SchemaURL is the schema_url of the library providing instrumentation.\nfunc (cfg MeterConfig) SchemaURL() string {\n\treturn cfg.schemaURL\n}\n\n// MeterOption is an interface for applying Meter options.\ntype MeterOption interface {\n\t// applyMeter is used to set a MeterOption value of a MeterConfig.\n\tapplyMeter(MeterConfig) MeterConfig\n}\n\n// NewMeterConfig creates a new MeterConfig and applies\n// all the given options.\nfunc NewMeterConfig(opts ...MeterOption) MeterConfig {\n\tvar config MeterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyMeter(config)\n\t}\n\treturn config\n}\n\ntype meterOptionFunc func(MeterConfig) MeterConfig\n\nfunc (fn meterOptionFunc) applyMeter(cfg MeterConfig) MeterConfig {\n\treturn fn(cfg)\n}\n\n// WithInstrumentationVersion sets the instrumentation version.\nfunc WithInstrumentationVersion(version string) MeterOption {\n\treturn meterOptionFunc(func(config MeterConfig) MeterConfig {\n\t\tconfig.instrumentationVersion = version\n\t\treturn config\n\t})\n}\n\n// WithInstrumentationAttributes adds the instrumentation attributes.\n//\n// This is equivalent to calling [WithInstrumentationAttributeSet] with an\n// [attribute.Set] created from a clone of the passed attributes.\n// [WithInstrumentationAttributeSet] is recommended for more control.\n//\n// If multiple [WithInstrumentationAttributes] or [WithInstrumentationAttributeSet]\n// options are passed, the attributes will be merged together in the order\n// they are passed. Attributes with duplicate keys will use the last value passed.\nfunc WithInstrumentationAttributes(attr ...attribute.KeyValue) MeterOption {\n\tset := attribute.NewSet(slices.Clone(attr)...)\n\treturn WithInstrumentationAttributeSet(set)\n}\n\n// WithInstrumentationAttributeSet adds the instrumentation attributes.\n//\n// If multiple [WithInstrumentationAttributes] or [WithInstrumentationAttributeSet]\n// options are passed, the attributes will be merged together in the order\n// they are passed. Attributes with duplicate keys will use the last value passed.\nfunc WithInstrumentationAttributeSet(set attribute.Set) MeterOption {\n\tif set.Len() == 0 {\n\t\treturn meterOptionFunc(func(config MeterConfig) MeterConfig {\n\t\t\treturn config\n\t\t})\n\t}\n\n\treturn meterOptionFunc(func(config MeterConfig) MeterConfig {\n\t\tif config.attrs.Len() == 0 {\n\t\t\tconfig.attrs = set\n\t\t} else {\n\t\t\tconfig.attrs = mergeSets(config.attrs, set)\n\t\t}\n\t\treturn config\n\t})\n}\n\n// WithSchemaURL sets the schema URL.\nfunc WithSchemaURL(schemaURL string) MeterOption {\n\treturn meterOptionFunc(func(config MeterConfig) MeterConfig {\n\t\tconfig.schemaURL = schemaURL\n\t\treturn config\n\t})\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n/*\nPackage metric provides the OpenTelemetry API used to measure metrics about\nsource code operation.\n\nThis API is separate from its implementation so the instrumentation built from\nit is reusable. See [go.opentelemetry.io/otel/sdk/metric] for the official\nOpenTelemetry implementation of this API.\n\nAll measurements made with this package are made via instruments. These\ninstruments are created by a [Meter] which itself is created by a\n[MeterProvider]. Applications need to accept a [MeterProvider] implementation\nas a starting point when instrumenting. This can be done directly, or by using\nthe OpenTelemetry global MeterProvider via [GetMeterProvider]. Using an\nappropriately named [Meter] from the accepted [MeterProvider], instrumentation\ncan then be built from the [Meter]'s instruments.\n\n# Instruments\n\nEach instrument is designed to make measurements of a particular type. Broadly,\nall instruments fall into two overlapping logical categories: asynchronous or\nsynchronous, and int64 or float64.\n\nAll synchronous instruments ([Int64Counter], [Int64UpDownCounter],\n[Int64Histogram], [Float64Counter], [Float64UpDownCounter], and\n[Float64Histogram]) are used to measure the operation and performance of source\ncode during the source code execution. These instruments only make measurements\nwhen the source code they instrument is run.\n\nAll asynchronous instruments ([Int64ObservableCounter],\n[Int64ObservableUpDownCounter], [Int64ObservableGauge],\n[Float64ObservableCounter], [Float64ObservableUpDownCounter], and\n[Float64ObservableGauge]) are used to measure metrics outside of the execution\nof source code. They are said to make \"observations\" via a callback function\ncalled once every measurement collection cycle.\n\nEach instrument is also grouped by the value type it measures. Either int64 or\nfloat64. The value being measured will dictate which instrument in these\ncategories to use.\n\nOutside of these two broad categories, instruments are described by the\nfunction they are designed to serve. All Counters ([Int64Counter],\n[Float64Counter], [Int64ObservableCounter], and [Float64ObservableCounter]) are\ndesigned to measure values that never decrease in value, but instead only\nincrementally increase in value. UpDownCounters ([Int64UpDownCounter],\n[Float64UpDownCounter], [Int64ObservableUpDownCounter], and\n[Float64ObservableUpDownCounter]) on the other hand, are designed to measure\nvalues that can increase and decrease. When more information needs to be\nconveyed about all the synchronous measurements made during a collection cycle,\na Histogram ([Int64Histogram] and [Float64Histogram]) should be used. Finally,\nwhen just the most recent measurement needs to be conveyed about an\nasynchronous measurement, a Gauge ([Int64ObservableGauge] and\n[Float64ObservableGauge]) should be used.\n\nSee the [OpenTelemetry documentation] for more information about instruments\nand their intended use.\n\n# Instrument Name\n\nOpenTelemetry defines an [instrument name syntax] that restricts what\ninstrument names are allowed.\n\nInstrument names should ...\n\n  - Not be empty.\n  - Have an alphabetic character as their first letter.\n  - Have any letter after the first be an alphanumeric character, ‘_’, ‘.’,\n    ‘-’, or ‘/’.\n  - Have a maximum length of 255 letters.\n\nTo ensure compatibility with observability platforms, all instruments created\nneed to conform to this syntax. Not all implementations of the API will validate\nthese names, it is the callers responsibility to ensure compliance.\n\n# Measurements\n\nMeasurements are made by recording values and information about the values with\nan instrument. How these measurements are recorded depends on the instrument.\n\nMeasurements for synchronous instruments ([Int64Counter], [Int64UpDownCounter],\n[Int64Histogram], [Float64Counter], [Float64UpDownCounter], and\n[Float64Histogram]) are recorded using the instrument methods directly. All\ncounter instruments have an Add method that is used to measure an increment\nvalue, and all histogram instruments have a Record method to measure a data\npoint.\n\nAsynchronous instruments ([Int64ObservableCounter],\n[Int64ObservableUpDownCounter], [Int64ObservableGauge],\n[Float64ObservableCounter], [Float64ObservableUpDownCounter], and\n[Float64ObservableGauge]) record measurements within a callback function. The\ncallback is registered with the Meter which ensures the callback is called once\nper collection cycle. A callback can be registered two ways: during the\ninstrument's creation using an option, or later using the RegisterCallback\nmethod of the [Meter] that created the instrument.\n\nIf the following criteria are met, an option ([WithInt64Callback] or\n[WithFloat64Callback]) can be used during the asynchronous instrument's\ncreation to register a callback ([Int64Callback] or [Float64Callback],\nrespectively):\n\n  - The measurement process is known when the instrument is created\n  - Only that instrument will make a measurement within the callback\n  - The callback never needs to be unregistered\n\nIf the criteria are not met, use the RegisterCallback method of the [Meter] that\ncreated the instrument to register a [Callback].\n\n# API Implementations\n\nThis package does not conform to the standard Go versioning policy, all of its\ninterfaces may have methods added to them without a package major version bump.\nThis non-standard API evolution could surprise an uninformed implementation\nauthor. They could unknowingly build their implementation in a way that would\nresult in a runtime panic for their users that update to the new API.\n\nThe API is designed to help inform an instrumentation author about this\nnon-standard API evolution. It requires them to choose a default behavior for\nunimplemented interface methods. There are three behavior choices they can\nmake:\n\n  - Compilation failure\n  - Panic\n  - Default to another implementation\n\nAll interfaces in this API embed a corresponding interface from\n[go.opentelemetry.io/otel/metric/embedded]. If an author wants the default\nbehavior of their implementations to be a compilation failure, signaling to\ntheir users they need to update to the latest version of that implementation,\nthey need to embed the corresponding interface from\n[go.opentelemetry.io/otel/metric/embedded] in their implementation. For\nexample,\n\n\timport \"go.opentelemetry.io/otel/metric/embedded\"\n\n\ttype MeterProvider struct {\n\t\tembedded.MeterProvider\n\t\t// ...\n\t}\n\nIf an author wants the default behavior of their implementations to a panic,\nthey need to embed the API interface directly.\n\n\timport \"go.opentelemetry.io/otel/metric\"\n\n\ttype MeterProvider struct {\n\t\tmetric.MeterProvider\n\t\t// ...\n\t}\n\nThis is not a recommended behavior as it could lead to publishing packages that\ncontain runtime panics when users update other package that use newer versions\nof [go.opentelemetry.io/otel/metric].\n\nFinally, an author can embed another implementation in theirs. The embedded\nimplementation will be used for methods not defined by the author. For example,\nan author who wants to default to silently dropping the call can use\n[go.opentelemetry.io/otel/metric/noop]:\n\n\timport \"go.opentelemetry.io/otel/metric/noop\"\n\n\ttype MeterProvider struct {\n\t\tnoop.MeterProvider\n\t\t// ...\n\t}\n\nIt is strongly recommended that authors only embed\n[go.opentelemetry.io/otel/metric/noop] if they choose this default behavior.\nThat implementation is the only one OpenTelemetry authors can guarantee will\nfully implement all the API interfaces when a user updates their API.\n\n[instrument name syntax]: https://opentelemetry.io/docs/specs/otel/metrics/api/#instrument-name-syntax\n[OpenTelemetry documentation]: https://opentelemetry.io/docs/concepts/signals/metrics/\n[GetMeterProvider]: https://pkg.go.dev/go.opentelemetry.io/otel#GetMeterProvider\n*/\npackage metric // import \"go.opentelemetry.io/otel/metric\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/embedded/README.md",
    "content": "# Metric Embedded\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/metric/embedded)](https://pkg.go.dev/go.opentelemetry.io/otel/metric/embedded)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/embedded/embedded.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package embedded provides interfaces embedded within the [OpenTelemetry\n// metric API].\n//\n// Implementers of the [OpenTelemetry metric API] can embed the relevant type\n// from this package into their implementation directly. Doing so will result\n// in a compilation error for users when the [OpenTelemetry metric API] is\n// extended (which is something that can happen without a major version bump of\n// the API package).\n//\n// [OpenTelemetry metric API]: https://pkg.go.dev/go.opentelemetry.io/otel/metric\npackage embedded // import \"go.opentelemetry.io/otel/metric/embedded\"\n\n// MeterProvider is embedded in\n// [go.opentelemetry.io/otel/metric.MeterProvider].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.MeterProvider] if you want users to\n// experience a compilation error, signaling they need to update to your latest\n// implementation, when the [go.opentelemetry.io/otel/metric.MeterProvider]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype MeterProvider interface{ meterProvider() }\n\n// Meter is embedded in [go.opentelemetry.io/otel/metric.Meter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Meter] if you want users to experience a\n// compilation error, signaling they need to update to your latest\n// implementation, when the [go.opentelemetry.io/otel/metric.Meter] interface\n// is extended (which is something that can happen without a major version bump\n// of the API package).\ntype Meter interface{ meter() }\n\n// Float64Observer is embedded in\n// [go.opentelemetry.io/otel/metric.Float64Observer].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Float64Observer] if you want\n// users to experience a compilation error, signaling they need to update to\n// your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Float64Observer] interface is\n// extended (which is something that can happen without a major version bump of\n// the API package).\ntype Float64Observer interface{ float64Observer() }\n\n// Int64Observer is embedded in\n// [go.opentelemetry.io/otel/metric.Int64Observer].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Int64Observer] if you want users\n// to experience a compilation error, signaling they need to update to your\n// latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Int64Observer] interface is\n// extended (which is something that can happen without a major version bump of\n// the API package).\ntype Int64Observer interface{ int64Observer() }\n\n// Observer is embedded in [go.opentelemetry.io/otel/metric.Observer].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Observer] if you want users to experience a\n// compilation error, signaling they need to update to your latest\n// implementation, when the [go.opentelemetry.io/otel/metric.Observer]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype Observer interface{ observer() }\n\n// Registration is embedded in [go.opentelemetry.io/otel/metric.Registration].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Registration] if you want users to\n// experience a compilation error, signaling they need to update to your latest\n// implementation, when the [go.opentelemetry.io/otel/metric.Registration]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype Registration interface{ registration() }\n\n// Float64Counter is embedded in\n// [go.opentelemetry.io/otel/metric.Float64Counter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Float64Counter] if you want\n// users to experience a compilation error, signaling they need to update to\n// your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Float64Counter] interface is\n// extended (which is something that can happen without a major version bump of\n// the API package).\ntype Float64Counter interface{ float64Counter() }\n\n// Float64Histogram is embedded in\n// [go.opentelemetry.io/otel/metric.Float64Histogram].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Float64Histogram] if you want\n// users to experience a compilation error, signaling they need to update to\n// your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Float64Histogram] interface is\n// extended (which is something that can happen without a major version bump of\n// the API package).\ntype Float64Histogram interface{ float64Histogram() }\n\n// Float64Gauge is embedded in [go.opentelemetry.io/otel/metric.Float64Gauge].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Float64Gauge] if you want users to\n// experience a compilation error, signaling they need to update to your latest\n// implementation, when the [go.opentelemetry.io/otel/metric.Float64Gauge]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype Float64Gauge interface{ float64Gauge() }\n\n// Float64ObservableCounter is embedded in\n// [go.opentelemetry.io/otel/metric.Float64ObservableCounter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Float64ObservableCounter] if you\n// want users to experience a compilation error, signaling they need to update\n// to your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Float64ObservableCounter]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype Float64ObservableCounter interface{ float64ObservableCounter() }\n\n// Float64ObservableGauge is embedded in\n// [go.opentelemetry.io/otel/metric.Float64ObservableGauge].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Float64ObservableGauge] if you\n// want users to experience a compilation error, signaling they need to update\n// to your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Float64ObservableGauge]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype Float64ObservableGauge interface{ float64ObservableGauge() }\n\n// Float64ObservableUpDownCounter is embedded in\n// [go.opentelemetry.io/otel/metric.Float64ObservableUpDownCounter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Float64ObservableUpDownCounter]\n// if you want users to experience a compilation error, signaling they need to\n// update to your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Float64ObservableUpDownCounter]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype Float64ObservableUpDownCounter interface{ float64ObservableUpDownCounter() }\n\n// Float64UpDownCounter is embedded in\n// [go.opentelemetry.io/otel/metric.Float64UpDownCounter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Float64UpDownCounter] if you\n// want users to experience a compilation error, signaling they need to update\n// to your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Float64UpDownCounter] interface\n// is extended (which is something that can happen without a major version bump\n// of the API package).\ntype Float64UpDownCounter interface{ float64UpDownCounter() }\n\n// Int64Counter is embedded in\n// [go.opentelemetry.io/otel/metric.Int64Counter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Int64Counter] if you want users\n// to experience a compilation error, signaling they need to update to your\n// latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Int64Counter] interface is\n// extended (which is something that can happen without a major version bump of\n// the API package).\ntype Int64Counter interface{ int64Counter() }\n\n// Int64Histogram is embedded in\n// [go.opentelemetry.io/otel/metric.Int64Histogram].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Int64Histogram] if you want\n// users to experience a compilation error, signaling they need to update to\n// your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Int64Histogram] interface is\n// extended (which is something that can happen without a major version bump of\n// the API package).\ntype Int64Histogram interface{ int64Histogram() }\n\n// Int64Gauge is embedded in [go.opentelemetry.io/otel/metric.Int64Gauge].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Int64Gauge] if you want users to experience\n// a compilation error, signaling they need to update to your latest\n// implementation, when the [go.opentelemetry.io/otel/metric.Int64Gauge]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype Int64Gauge interface{ int64Gauge() }\n\n// Int64ObservableCounter is embedded in\n// [go.opentelemetry.io/otel/metric.Int64ObservableCounter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Int64ObservableCounter] if you\n// want users to experience a compilation error, signaling they need to update\n// to your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Int64ObservableCounter]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype Int64ObservableCounter interface{ int64ObservableCounter() }\n\n// Int64ObservableGauge is embedded in\n// [go.opentelemetry.io/otel/metric.Int64ObservableGauge].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Int64ObservableGauge] if you\n// want users to experience a compilation error, signaling they need to update\n// to your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Int64ObservableGauge] interface\n// is extended (which is something that can happen without a major version bump\n// of the API package).\ntype Int64ObservableGauge interface{ int64ObservableGauge() }\n\n// Int64ObservableUpDownCounter is embedded in\n// [go.opentelemetry.io/otel/metric.Int64ObservableUpDownCounter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Int64ObservableUpDownCounter] if\n// you want users to experience a compilation error, signaling they need to\n// update to your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Int64ObservableUpDownCounter]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype Int64ObservableUpDownCounter interface{ int64ObservableUpDownCounter() }\n\n// Int64UpDownCounter is embedded in\n// [go.opentelemetry.io/otel/metric.Int64UpDownCounter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Int64UpDownCounter] if you want\n// users to experience a compilation error, signaling they need to update to\n// your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Int64UpDownCounter] interface is\n// extended (which is something that can happen without a major version bump of\n// the API package).\ntype Int64UpDownCounter interface{ int64UpDownCounter() }\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/instrument.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage metric // import \"go.opentelemetry.io/otel/metric\"\n\nimport \"go.opentelemetry.io/otel/attribute\"\n\n// Observable is used as a grouping mechanism for all instruments that are\n// updated within a Callback.\ntype Observable interface {\n\tobservable()\n}\n\n// InstrumentOption applies options to all instruments.\ntype InstrumentOption interface {\n\tInt64CounterOption\n\tInt64UpDownCounterOption\n\tInt64HistogramOption\n\tInt64GaugeOption\n\tInt64ObservableCounterOption\n\tInt64ObservableUpDownCounterOption\n\tInt64ObservableGaugeOption\n\n\tFloat64CounterOption\n\tFloat64UpDownCounterOption\n\tFloat64HistogramOption\n\tFloat64GaugeOption\n\tFloat64ObservableCounterOption\n\tFloat64ObservableUpDownCounterOption\n\tFloat64ObservableGaugeOption\n}\n\n// HistogramOption applies options to histogram instruments.\ntype HistogramOption interface {\n\tInt64HistogramOption\n\tFloat64HistogramOption\n}\n\ntype descOpt string\n\nfunc (o descOpt) applyFloat64Counter(c Float64CounterConfig) Float64CounterConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyFloat64UpDownCounter(c Float64UpDownCounterConfig) Float64UpDownCounterConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyFloat64Histogram(c Float64HistogramConfig) Float64HistogramConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyFloat64Gauge(c Float64GaugeConfig) Float64GaugeConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyFloat64ObservableCounter(c Float64ObservableCounterConfig) Float64ObservableCounterConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyFloat64ObservableUpDownCounter(\n\tc Float64ObservableUpDownCounterConfig,\n) Float64ObservableUpDownCounterConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyFloat64ObservableGauge(c Float64ObservableGaugeConfig) Float64ObservableGaugeConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyInt64Counter(c Int64CounterConfig) Int64CounterConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyInt64UpDownCounter(c Int64UpDownCounterConfig) Int64UpDownCounterConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyInt64Histogram(c Int64HistogramConfig) Int64HistogramConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyInt64Gauge(c Int64GaugeConfig) Int64GaugeConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyInt64ObservableCounter(c Int64ObservableCounterConfig) Int64ObservableCounterConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyInt64ObservableUpDownCounter(\n\tc Int64ObservableUpDownCounterConfig,\n) Int64ObservableUpDownCounterConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyInt64ObservableGauge(c Int64ObservableGaugeConfig) Int64ObservableGaugeConfig {\n\tc.description = string(o)\n\treturn c\n}\n\n// WithDescription sets the instrument description.\nfunc WithDescription(desc string) InstrumentOption { return descOpt(desc) }\n\ntype unitOpt string\n\nfunc (o unitOpt) applyFloat64Counter(c Float64CounterConfig) Float64CounterConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyFloat64UpDownCounter(c Float64UpDownCounterConfig) Float64UpDownCounterConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyFloat64Histogram(c Float64HistogramConfig) Float64HistogramConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyFloat64Gauge(c Float64GaugeConfig) Float64GaugeConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyFloat64ObservableCounter(c Float64ObservableCounterConfig) Float64ObservableCounterConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyFloat64ObservableUpDownCounter(\n\tc Float64ObservableUpDownCounterConfig,\n) Float64ObservableUpDownCounterConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyFloat64ObservableGauge(c Float64ObservableGaugeConfig) Float64ObservableGaugeConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyInt64Counter(c Int64CounterConfig) Int64CounterConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyInt64UpDownCounter(c Int64UpDownCounterConfig) Int64UpDownCounterConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyInt64Histogram(c Int64HistogramConfig) Int64HistogramConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyInt64Gauge(c Int64GaugeConfig) Int64GaugeConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyInt64ObservableCounter(c Int64ObservableCounterConfig) Int64ObservableCounterConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyInt64ObservableUpDownCounter(\n\tc Int64ObservableUpDownCounterConfig,\n) Int64ObservableUpDownCounterConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyInt64ObservableGauge(c Int64ObservableGaugeConfig) Int64ObservableGaugeConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\n// WithUnit sets the instrument unit.\n//\n// The unit u should be defined using the appropriate [UCUM](https://ucum.org) case-sensitive code.\nfunc WithUnit(u string) InstrumentOption { return unitOpt(u) }\n\n// WithExplicitBucketBoundaries sets the instrument explicit bucket boundaries.\n//\n// This option is considered \"advisory\", and may be ignored by API implementations.\nfunc WithExplicitBucketBoundaries(bounds ...float64) HistogramOption { return bucketOpt(bounds) }\n\ntype bucketOpt []float64\n\nfunc (o bucketOpt) applyFloat64Histogram(c Float64HistogramConfig) Float64HistogramConfig {\n\tc.explicitBucketBoundaries = o\n\treturn c\n}\n\nfunc (o bucketOpt) applyInt64Histogram(c Int64HistogramConfig) Int64HistogramConfig {\n\tc.explicitBucketBoundaries = o\n\treturn c\n}\n\n// AddOption applies options to an addition measurement. See\n// [MeasurementOption] for other options that can be used as an AddOption.\ntype AddOption interface {\n\tapplyAdd(AddConfig) AddConfig\n}\n\n// AddConfig contains options for an addition measurement.\ntype AddConfig struct {\n\tattrs attribute.Set\n}\n\n// NewAddConfig returns a new [AddConfig] with all opts applied.\nfunc NewAddConfig(opts []AddOption) AddConfig {\n\tconfig := AddConfig{attrs: *attribute.EmptySet()}\n\tfor _, o := range opts {\n\t\tconfig = o.applyAdd(config)\n\t}\n\treturn config\n}\n\n// Attributes returns the configured attribute set.\nfunc (c AddConfig) Attributes() attribute.Set {\n\treturn c.attrs\n}\n\n// RecordOption applies options to an addition measurement. See\n// [MeasurementOption] for other options that can be used as a RecordOption.\ntype RecordOption interface {\n\tapplyRecord(RecordConfig) RecordConfig\n}\n\n// RecordConfig contains options for a recorded measurement.\ntype RecordConfig struct {\n\tattrs attribute.Set\n}\n\n// NewRecordConfig returns a new [RecordConfig] with all opts applied.\nfunc NewRecordConfig(opts []RecordOption) RecordConfig {\n\tconfig := RecordConfig{attrs: *attribute.EmptySet()}\n\tfor _, o := range opts {\n\t\tconfig = o.applyRecord(config)\n\t}\n\treturn config\n}\n\n// Attributes returns the configured attribute set.\nfunc (c RecordConfig) Attributes() attribute.Set {\n\treturn c.attrs\n}\n\n// ObserveOption applies options to an addition measurement. See\n// [MeasurementOption] for other options that can be used as a ObserveOption.\ntype ObserveOption interface {\n\tapplyObserve(ObserveConfig) ObserveConfig\n}\n\n// ObserveConfig contains options for an observed measurement.\ntype ObserveConfig struct {\n\tattrs attribute.Set\n}\n\n// NewObserveConfig returns a new [ObserveConfig] with all opts applied.\nfunc NewObserveConfig(opts []ObserveOption) ObserveConfig {\n\tconfig := ObserveConfig{attrs: *attribute.EmptySet()}\n\tfor _, o := range opts {\n\t\tconfig = o.applyObserve(config)\n\t}\n\treturn config\n}\n\n// Attributes returns the configured attribute set.\nfunc (c ObserveConfig) Attributes() attribute.Set {\n\treturn c.attrs\n}\n\n// MeasurementOption applies options to all instrument measurement.\ntype MeasurementOption interface {\n\tAddOption\n\tRecordOption\n\tObserveOption\n}\n\ntype attrOpt struct {\n\tset attribute.Set\n}\n\n// mergeSets returns the union of keys between a and b. Any duplicate keys will\n// use the value associated with b.\nfunc mergeSets(a, b attribute.Set) attribute.Set {\n\t// NewMergeIterator uses the first value for any duplicates.\n\titer := attribute.NewMergeIterator(&b, &a)\n\tmerged := make([]attribute.KeyValue, 0, a.Len()+b.Len())\n\tfor iter.Next() {\n\t\tmerged = append(merged, iter.Attribute())\n\t}\n\treturn attribute.NewSet(merged...)\n}\n\nfunc (o attrOpt) applyAdd(c AddConfig) AddConfig {\n\tswitch {\n\tcase o.set.Len() == 0:\n\tcase c.attrs.Len() == 0:\n\t\tc.attrs = o.set\n\tdefault:\n\t\tc.attrs = mergeSets(c.attrs, o.set)\n\t}\n\treturn c\n}\n\nfunc (o attrOpt) applyRecord(c RecordConfig) RecordConfig {\n\tswitch {\n\tcase o.set.Len() == 0:\n\tcase c.attrs.Len() == 0:\n\t\tc.attrs = o.set\n\tdefault:\n\t\tc.attrs = mergeSets(c.attrs, o.set)\n\t}\n\treturn c\n}\n\nfunc (o attrOpt) applyObserve(c ObserveConfig) ObserveConfig {\n\tswitch {\n\tcase o.set.Len() == 0:\n\tcase c.attrs.Len() == 0:\n\t\tc.attrs = o.set\n\tdefault:\n\t\tc.attrs = mergeSets(c.attrs, o.set)\n\t}\n\treturn c\n}\n\n// WithAttributeSet sets the attribute Set associated with a measurement is\n// made with.\n//\n// If multiple WithAttributeSet or WithAttributes options are passed the\n// attributes will be merged together in the order they are passed. Attributes\n// with duplicate keys will use the last value passed.\nfunc WithAttributeSet(attributes attribute.Set) MeasurementOption {\n\treturn attrOpt{set: attributes}\n}\n\n// WithAttributes converts attributes into an attribute Set and sets the Set to\n// be associated with a measurement. This is shorthand for:\n//\n//\tcp := make([]attribute.KeyValue, len(attributes))\n//\tcopy(cp, attributes)\n//\tWithAttributeSet(attribute.NewSet(cp...))\n//\n// [attribute.NewSet] may modify the passed attributes so this will make a copy\n// of attributes before creating a set in order to ensure this function is\n// concurrent safe. This makes this option function less optimized in\n// comparison to [WithAttributeSet]. Therefore, [WithAttributeSet] should be\n// preferred for performance sensitive code.\n//\n// See [WithAttributeSet] for information about how multiple WithAttributes are\n// merged.\nfunc WithAttributes(attributes ...attribute.KeyValue) MeasurementOption {\n\tcp := make([]attribute.KeyValue, len(attributes))\n\tcopy(cp, attributes)\n\treturn attrOpt{set: attribute.NewSet(cp...)}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/meter.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage metric // import \"go.opentelemetry.io/otel/metric\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/metric/embedded\"\n)\n\n// MeterProvider provides access to named Meter instances, for instrumenting\n// an application or package.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype MeterProvider interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.MeterProvider\n\n\t// Meter returns a new Meter with the provided name and configuration.\n\t//\n\t// A Meter should be scoped at most to a single package. The name needs to\n\t// be unique so it does not collide with other names used by\n\t// an application, nor other applications. To achieve this, the import path\n\t// of the instrumentation package is recommended to be used as name.\n\t//\n\t// If the name is empty, then an implementation defined default name will\n\t// be used instead.\n\tMeter(name string, opts ...MeterOption) Meter\n}\n\n// Meter provides access to instrument instances for recording metrics.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Meter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Meter\n\n\t// Int64Counter returns a new Int64Counter instrument identified by name\n\t// and configured with options. The instrument is used to synchronously\n\t// record increasing int64 measurements during a computational operation.\n\t//\n\t// The name needs to conform to the OpenTelemetry instrument name syntax.\n\t// See the Instrument Name section of the package documentation for more\n\t// information.\n\tInt64Counter(name string, options ...Int64CounterOption) (Int64Counter, error)\n\n\t// Int64UpDownCounter returns a new Int64UpDownCounter instrument\n\t// identified by name and configured with options. The instrument is used\n\t// to synchronously record int64 measurements during a computational\n\t// operation.\n\t//\n\t// The name needs to conform to the OpenTelemetry instrument name syntax.\n\t// See the Instrument Name section of the package documentation for more\n\t// information.\n\tInt64UpDownCounter(name string, options ...Int64UpDownCounterOption) (Int64UpDownCounter, error)\n\n\t// Int64Histogram returns a new Int64Histogram instrument identified by\n\t// name and configured with options. The instrument is used to\n\t// synchronously record the distribution of int64 measurements during a\n\t// computational operation.\n\t//\n\t// The name needs to conform to the OpenTelemetry instrument name syntax.\n\t// See the Instrument Name section of the package documentation for more\n\t// information.\n\tInt64Histogram(name string, options ...Int64HistogramOption) (Int64Histogram, error)\n\n\t// Int64Gauge returns a new Int64Gauge instrument identified by name and\n\t// configured with options. The instrument is used to synchronously record\n\t// instantaneous int64 measurements during a computational operation.\n\t//\n\t// The name needs to conform to the OpenTelemetry instrument name syntax.\n\t// See the Instrument Name section of the package documentation for more\n\t// information.\n\tInt64Gauge(name string, options ...Int64GaugeOption) (Int64Gauge, error)\n\n\t// Int64ObservableCounter returns a new Int64ObservableCounter identified\n\t// by name and configured with options. The instrument is used to\n\t// asynchronously record increasing int64 measurements once per a\n\t// measurement collection cycle.\n\t//\n\t// Measurements for the returned instrument are made via a callback. Use\n\t// the WithInt64Callback option to register the callback here, or use the\n\t// RegisterCallback method of this Meter to register one later. See the\n\t// Measurements section of the package documentation for more information.\n\t//\n\t// The name needs to conform to the OpenTelemetry instrument name syntax.\n\t// See the Instrument Name section of the package documentation for more\n\t// information.\n\tInt64ObservableCounter(name string, options ...Int64ObservableCounterOption) (Int64ObservableCounter, error)\n\n\t// Int64ObservableUpDownCounter returns a new Int64ObservableUpDownCounter\n\t// instrument identified by name and configured with options. The\n\t// instrument is used to asynchronously record int64 measurements once per\n\t// a measurement collection cycle.\n\t//\n\t// Measurements for the returned instrument are made via a callback. Use\n\t// the WithInt64Callback option to register the callback here, or use the\n\t// RegisterCallback method of this Meter to register one later. See the\n\t// Measurements section of the package documentation for more information.\n\t//\n\t// The name needs to conform to the OpenTelemetry instrument name syntax.\n\t// See the Instrument Name section of the package documentation for more\n\t// information.\n\tInt64ObservableUpDownCounter(\n\t\tname string,\n\t\toptions ...Int64ObservableUpDownCounterOption,\n\t) (Int64ObservableUpDownCounter, error)\n\n\t// Int64ObservableGauge returns a new Int64ObservableGauge instrument\n\t// identified by name and configured with options. The instrument is used\n\t// to asynchronously record instantaneous int64 measurements once per a\n\t// measurement collection cycle.\n\t//\n\t// Measurements for the returned instrument are made via a callback. Use\n\t// the WithInt64Callback option to register the callback here, or use the\n\t// RegisterCallback method of this Meter to register one later. See the\n\t// Measurements section of the package documentation for more information.\n\t//\n\t// The name needs to conform to the OpenTelemetry instrument name syntax.\n\t// See the Instrument Name section of the package documentation for more\n\t// information.\n\tInt64ObservableGauge(name string, options ...Int64ObservableGaugeOption) (Int64ObservableGauge, error)\n\n\t// Float64Counter returns a new Float64Counter instrument identified by\n\t// name and configured with options. The instrument is used to\n\t// synchronously record increasing float64 measurements during a\n\t// computational operation.\n\t//\n\t// The name needs to conform to the OpenTelemetry instrument name syntax.\n\t// See the Instrument Name section of the package documentation for more\n\t// information.\n\tFloat64Counter(name string, options ...Float64CounterOption) (Float64Counter, error)\n\n\t// Float64UpDownCounter returns a new Float64UpDownCounter instrument\n\t// identified by name and configured with options. The instrument is used\n\t// to synchronously record float64 measurements during a computational\n\t// operation.\n\t//\n\t// The name needs to conform to the OpenTelemetry instrument name syntax.\n\t// See the Instrument Name section of the package documentation for more\n\t// information.\n\tFloat64UpDownCounter(name string, options ...Float64UpDownCounterOption) (Float64UpDownCounter, error)\n\n\t// Float64Histogram returns a new Float64Histogram instrument identified by\n\t// name and configured with options. The instrument is used to\n\t// synchronously record the distribution of float64 measurements during a\n\t// computational operation.\n\t//\n\t// The name needs to conform to the OpenTelemetry instrument name syntax.\n\t// See the Instrument Name section of the package documentation for more\n\t// information.\n\tFloat64Histogram(name string, options ...Float64HistogramOption) (Float64Histogram, error)\n\n\t// Float64Gauge returns a new Float64Gauge instrument identified by name and\n\t// configured with options. The instrument is used to synchronously record\n\t// instantaneous float64 measurements during a computational operation.\n\t//\n\t// The name needs to conform to the OpenTelemetry instrument name syntax.\n\t// See the Instrument Name section of the package documentation for more\n\t// information.\n\tFloat64Gauge(name string, options ...Float64GaugeOption) (Float64Gauge, error)\n\n\t// Float64ObservableCounter returns a new Float64ObservableCounter\n\t// instrument identified by name and configured with options. The\n\t// instrument is used to asynchronously record increasing float64\n\t// measurements once per a measurement collection cycle.\n\t//\n\t// Measurements for the returned instrument are made via a callback. Use\n\t// the WithFloat64Callback option to register the callback here, or use the\n\t// RegisterCallback method of this Meter to register one later. See the\n\t// Measurements section of the package documentation for more information.\n\t//\n\t// The name needs to conform to the OpenTelemetry instrument name syntax.\n\t// See the Instrument Name section of the package documentation for more\n\t// information.\n\tFloat64ObservableCounter(name string, options ...Float64ObservableCounterOption) (Float64ObservableCounter, error)\n\n\t// Float64ObservableUpDownCounter returns a new\n\t// Float64ObservableUpDownCounter instrument identified by name and\n\t// configured with options. The instrument is used to asynchronously record\n\t// float64 measurements once per a measurement collection cycle.\n\t//\n\t// Measurements for the returned instrument are made via a callback. Use\n\t// the WithFloat64Callback option to register the callback here, or use the\n\t// RegisterCallback method of this Meter to register one later. See the\n\t// Measurements section of the package documentation for more information.\n\t//\n\t// The name needs to conform to the OpenTelemetry instrument name syntax.\n\t// See the Instrument Name section of the package documentation for more\n\t// information.\n\tFloat64ObservableUpDownCounter(\n\t\tname string,\n\t\toptions ...Float64ObservableUpDownCounterOption,\n\t) (Float64ObservableUpDownCounter, error)\n\n\t// Float64ObservableGauge returns a new Float64ObservableGauge instrument\n\t// identified by name and configured with options. The instrument is used\n\t// to asynchronously record instantaneous float64 measurements once per a\n\t// measurement collection cycle.\n\t//\n\t// Measurements for the returned instrument are made via a callback. Use\n\t// the WithFloat64Callback option to register the callback here, or use the\n\t// RegisterCallback method of this Meter to register one later. See the\n\t// Measurements section of the package documentation for more information.\n\t//\n\t// The name needs to conform to the OpenTelemetry instrument name syntax.\n\t// See the Instrument Name section of the package documentation for more\n\t// information.\n\tFloat64ObservableGauge(name string, options ...Float64ObservableGaugeOption) (Float64ObservableGauge, error)\n\n\t// RegisterCallback registers f to be called during the collection of a\n\t// measurement cycle.\n\t//\n\t// If Unregister of the returned Registration is called, f needs to be\n\t// unregistered and not called during collection.\n\t//\n\t// The instruments f is registered with are the only instruments that f may\n\t// observe values for.\n\t//\n\t// If no instruments are passed, f should not be registered nor called\n\t// during collection.\n\t//\n\t// The function f needs to be concurrent safe.\n\tRegisterCallback(f Callback, instruments ...Observable) (Registration, error)\n}\n\n// Callback is a function registered with a Meter that makes observations for\n// the set of instruments it is registered with. The Observer parameter is used\n// to record measurement observations for these instruments.\n//\n// The function needs to complete in a finite amount of time and the deadline\n// of the passed context is expected to be honored.\n//\n// The function needs to make unique observations across all registered\n// Callbacks. Meaning, it should not report measurements for an instrument with\n// the same attributes as another Callback will report.\n//\n// The function needs to be reentrant and concurrent safe.\n//\n// Note that Go's mutexes are not reentrant, and locking a mutex takes\n// an indefinite amount of time. It is therefore advised to avoid\n// using mutexes inside callbacks.\ntype Callback func(context.Context, Observer) error\n\n// Observer records measurements for multiple instruments in a Callback.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Observer interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Observer\n\n\t// ObserveFloat64 records the float64 value for obsrv.\n\tObserveFloat64(obsrv Float64Observable, value float64, opts ...ObserveOption)\n\n\t// ObserveInt64 records the int64 value for obsrv.\n\tObserveInt64(obsrv Int64Observable, value int64, opts ...ObserveOption)\n}\n\n// Registration is an token representing the unique registration of a callback\n// for a set of instruments with a Meter.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Registration interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Registration\n\n\t// Unregister removes the callback registration from a Meter.\n\t//\n\t// This method needs to be idempotent and concurrent safe.\n\tUnregister() error\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/noop/README.md",
    "content": "# Metric Noop\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/metric/noop)](https://pkg.go.dev/go.opentelemetry.io/otel/metric/noop)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/noop/noop.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package noop provides an implementation of the OpenTelemetry metric API that\n// produces no telemetry and minimizes used computation resources.\n//\n// Using this package to implement the OpenTelemetry metric API will\n// effectively disable OpenTelemetry.\n//\n// This implementation can be embedded in other implementations of the\n// OpenTelemetry metric API. Doing so will mean the implementation defaults to\n// no operation for methods it does not implement.\npackage noop // import \"go.opentelemetry.io/otel/metric/noop\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/metric\"\n\t\"go.opentelemetry.io/otel/metric/embedded\"\n)\n\nvar (\n\t// Compile-time check this implements the OpenTelemetry API.\n\n\t_ metric.MeterProvider                  = MeterProvider{}\n\t_ metric.Meter                          = Meter{}\n\t_ metric.Observer                       = Observer{}\n\t_ metric.Registration                   = Registration{}\n\t_ metric.Int64Counter                   = Int64Counter{}\n\t_ metric.Float64Counter                 = Float64Counter{}\n\t_ metric.Int64UpDownCounter             = Int64UpDownCounter{}\n\t_ metric.Float64UpDownCounter           = Float64UpDownCounter{}\n\t_ metric.Int64Histogram                 = Int64Histogram{}\n\t_ metric.Float64Histogram               = Float64Histogram{}\n\t_ metric.Int64Gauge                     = Int64Gauge{}\n\t_ metric.Float64Gauge                   = Float64Gauge{}\n\t_ metric.Int64ObservableCounter         = Int64ObservableCounter{}\n\t_ metric.Float64ObservableCounter       = Float64ObservableCounter{}\n\t_ metric.Int64ObservableGauge           = Int64ObservableGauge{}\n\t_ metric.Float64ObservableGauge         = Float64ObservableGauge{}\n\t_ metric.Int64ObservableUpDownCounter   = Int64ObservableUpDownCounter{}\n\t_ metric.Float64ObservableUpDownCounter = Float64ObservableUpDownCounter{}\n\t_ metric.Int64Observer                  = Int64Observer{}\n\t_ metric.Float64Observer                = Float64Observer{}\n)\n\n// MeterProvider is an OpenTelemetry No-Op MeterProvider.\ntype MeterProvider struct{ embedded.MeterProvider }\n\n// NewMeterProvider returns a MeterProvider that does not record any telemetry.\nfunc NewMeterProvider() MeterProvider {\n\treturn MeterProvider{}\n}\n\n// Meter returns an OpenTelemetry Meter that does not record any telemetry.\nfunc (MeterProvider) Meter(string, ...metric.MeterOption) metric.Meter {\n\treturn Meter{}\n}\n\n// Meter is an OpenTelemetry No-Op Meter.\ntype Meter struct{ embedded.Meter }\n\n// Int64Counter returns a Counter used to record int64 measurements that\n// produces no telemetry.\nfunc (Meter) Int64Counter(string, ...metric.Int64CounterOption) (metric.Int64Counter, error) {\n\treturn Int64Counter{}, nil\n}\n\n// Int64UpDownCounter returns an UpDownCounter used to record int64\n// measurements that produces no telemetry.\nfunc (Meter) Int64UpDownCounter(string, ...metric.Int64UpDownCounterOption) (metric.Int64UpDownCounter, error) {\n\treturn Int64UpDownCounter{}, nil\n}\n\n// Int64Histogram returns a Histogram used to record int64 measurements that\n// produces no telemetry.\nfunc (Meter) Int64Histogram(string, ...metric.Int64HistogramOption) (metric.Int64Histogram, error) {\n\treturn Int64Histogram{}, nil\n}\n\n// Int64Gauge returns a Gauge used to record int64 measurements that\n// produces no telemetry.\nfunc (Meter) Int64Gauge(string, ...metric.Int64GaugeOption) (metric.Int64Gauge, error) {\n\treturn Int64Gauge{}, nil\n}\n\n// Int64ObservableCounter returns an ObservableCounter used to record int64\n// measurements that produces no telemetry.\nfunc (Meter) Int64ObservableCounter(\n\tstring,\n\t...metric.Int64ObservableCounterOption,\n) (metric.Int64ObservableCounter, error) {\n\treturn Int64ObservableCounter{}, nil\n}\n\n// Int64ObservableUpDownCounter returns an ObservableUpDownCounter used to\n// record int64 measurements that produces no telemetry.\nfunc (Meter) Int64ObservableUpDownCounter(\n\tstring,\n\t...metric.Int64ObservableUpDownCounterOption,\n) (metric.Int64ObservableUpDownCounter, error) {\n\treturn Int64ObservableUpDownCounter{}, nil\n}\n\n// Int64ObservableGauge returns an ObservableGauge used to record int64\n// measurements that produces no telemetry.\nfunc (Meter) Int64ObservableGauge(string, ...metric.Int64ObservableGaugeOption) (metric.Int64ObservableGauge, error) {\n\treturn Int64ObservableGauge{}, nil\n}\n\n// Float64Counter returns a Counter used to record int64 measurements that\n// produces no telemetry.\nfunc (Meter) Float64Counter(string, ...metric.Float64CounterOption) (metric.Float64Counter, error) {\n\treturn Float64Counter{}, nil\n}\n\n// Float64UpDownCounter returns an UpDownCounter used to record int64\n// measurements that produces no telemetry.\nfunc (Meter) Float64UpDownCounter(string, ...metric.Float64UpDownCounterOption) (metric.Float64UpDownCounter, error) {\n\treturn Float64UpDownCounter{}, nil\n}\n\n// Float64Histogram returns a Histogram used to record int64 measurements that\n// produces no telemetry.\nfunc (Meter) Float64Histogram(string, ...metric.Float64HistogramOption) (metric.Float64Histogram, error) {\n\treturn Float64Histogram{}, nil\n}\n\n// Float64Gauge returns a Gauge used to record float64 measurements that\n// produces no telemetry.\nfunc (Meter) Float64Gauge(string, ...metric.Float64GaugeOption) (metric.Float64Gauge, error) {\n\treturn Float64Gauge{}, nil\n}\n\n// Float64ObservableCounter returns an ObservableCounter used to record int64\n// measurements that produces no telemetry.\nfunc (Meter) Float64ObservableCounter(\n\tstring,\n\t...metric.Float64ObservableCounterOption,\n) (metric.Float64ObservableCounter, error) {\n\treturn Float64ObservableCounter{}, nil\n}\n\n// Float64ObservableUpDownCounter returns an ObservableUpDownCounter used to\n// record int64 measurements that produces no telemetry.\nfunc (Meter) Float64ObservableUpDownCounter(\n\tstring,\n\t...metric.Float64ObservableUpDownCounterOption,\n) (metric.Float64ObservableUpDownCounter, error) {\n\treturn Float64ObservableUpDownCounter{}, nil\n}\n\n// Float64ObservableGauge returns an ObservableGauge used to record int64\n// measurements that produces no telemetry.\nfunc (Meter) Float64ObservableGauge(\n\tstring,\n\t...metric.Float64ObservableGaugeOption,\n) (metric.Float64ObservableGauge, error) {\n\treturn Float64ObservableGauge{}, nil\n}\n\n// RegisterCallback performs no operation.\nfunc (Meter) RegisterCallback(metric.Callback, ...metric.Observable) (metric.Registration, error) {\n\treturn Registration{}, nil\n}\n\n// Observer acts as a recorder of measurements for multiple instruments in a\n// Callback, it performing no operation.\ntype Observer struct{ embedded.Observer }\n\n// ObserveFloat64 performs no operation.\nfunc (Observer) ObserveFloat64(metric.Float64Observable, float64, ...metric.ObserveOption) {\n}\n\n// ObserveInt64 performs no operation.\nfunc (Observer) ObserveInt64(metric.Int64Observable, int64, ...metric.ObserveOption) {\n}\n\n// Registration is the registration of a Callback with a No-Op Meter.\ntype Registration struct{ embedded.Registration }\n\n// Unregister unregisters the Callback the Registration represents with the\n// No-Op Meter. This will always return nil because the No-Op Meter performs no\n// operation, including hold any record of registrations.\nfunc (Registration) Unregister() error { return nil }\n\n// Int64Counter is an OpenTelemetry Counter used to record int64 measurements.\n// It produces no telemetry.\ntype Int64Counter struct{ embedded.Int64Counter }\n\n// Add performs no operation.\nfunc (Int64Counter) Add(context.Context, int64, ...metric.AddOption) {}\n\n// Enabled performs no operation.\nfunc (Int64Counter) Enabled(context.Context) bool { return false }\n\n// Float64Counter is an OpenTelemetry Counter used to record float64\n// measurements. It produces no telemetry.\ntype Float64Counter struct{ embedded.Float64Counter }\n\n// Add performs no operation.\nfunc (Float64Counter) Add(context.Context, float64, ...metric.AddOption) {}\n\n// Enabled performs no operation.\nfunc (Float64Counter) Enabled(context.Context) bool { return false }\n\n// Int64UpDownCounter is an OpenTelemetry UpDownCounter used to record int64\n// measurements. It produces no telemetry.\ntype Int64UpDownCounter struct{ embedded.Int64UpDownCounter }\n\n// Add performs no operation.\nfunc (Int64UpDownCounter) Add(context.Context, int64, ...metric.AddOption) {}\n\n// Enabled performs no operation.\nfunc (Int64UpDownCounter) Enabled(context.Context) bool { return false }\n\n// Float64UpDownCounter is an OpenTelemetry UpDownCounter used to record\n// float64 measurements. It produces no telemetry.\ntype Float64UpDownCounter struct{ embedded.Float64UpDownCounter }\n\n// Add performs no operation.\nfunc (Float64UpDownCounter) Add(context.Context, float64, ...metric.AddOption) {}\n\n// Enabled performs no operation.\nfunc (Float64UpDownCounter) Enabled(context.Context) bool { return false }\n\n// Int64Histogram is an OpenTelemetry Histogram used to record int64\n// measurements. It produces no telemetry.\ntype Int64Histogram struct{ embedded.Int64Histogram }\n\n// Record performs no operation.\nfunc (Int64Histogram) Record(context.Context, int64, ...metric.RecordOption) {}\n\n// Enabled performs no operation.\nfunc (Int64Histogram) Enabled(context.Context) bool { return false }\n\n// Float64Histogram is an OpenTelemetry Histogram used to record float64\n// measurements. It produces no telemetry.\ntype Float64Histogram struct{ embedded.Float64Histogram }\n\n// Record performs no operation.\nfunc (Float64Histogram) Record(context.Context, float64, ...metric.RecordOption) {}\n\n// Enabled performs no operation.\nfunc (Float64Histogram) Enabled(context.Context) bool { return false }\n\n// Int64Gauge is an OpenTelemetry Gauge used to record instantaneous int64\n// measurements. It produces no telemetry.\ntype Int64Gauge struct{ embedded.Int64Gauge }\n\n// Record performs no operation.\nfunc (Int64Gauge) Record(context.Context, int64, ...metric.RecordOption) {}\n\n// Enabled performs no operation.\nfunc (Int64Gauge) Enabled(context.Context) bool { return false }\n\n// Float64Gauge is an OpenTelemetry Gauge used to record instantaneous float64\n// measurements. It produces no telemetry.\ntype Float64Gauge struct{ embedded.Float64Gauge }\n\n// Record performs no operation.\nfunc (Float64Gauge) Record(context.Context, float64, ...metric.RecordOption) {}\n\n// Enabled performs no operation.\nfunc (Float64Gauge) Enabled(context.Context) bool { return false }\n\n// Int64ObservableCounter is an OpenTelemetry ObservableCounter used to record\n// int64 measurements. It produces no telemetry.\ntype Int64ObservableCounter struct {\n\tmetric.Int64Observable\n\tembedded.Int64ObservableCounter\n}\n\n// Float64ObservableCounter is an OpenTelemetry ObservableCounter used to record\n// float64 measurements. It produces no telemetry.\ntype Float64ObservableCounter struct {\n\tmetric.Float64Observable\n\tembedded.Float64ObservableCounter\n}\n\n// Int64ObservableGauge is an OpenTelemetry ObservableGauge used to record\n// int64 measurements. It produces no telemetry.\ntype Int64ObservableGauge struct {\n\tmetric.Int64Observable\n\tembedded.Int64ObservableGauge\n}\n\n// Float64ObservableGauge is an OpenTelemetry ObservableGauge used to record\n// float64 measurements. It produces no telemetry.\ntype Float64ObservableGauge struct {\n\tmetric.Float64Observable\n\tembedded.Float64ObservableGauge\n}\n\n// Int64ObservableUpDownCounter is an OpenTelemetry ObservableUpDownCounter\n// used to record int64 measurements. It produces no telemetry.\ntype Int64ObservableUpDownCounter struct {\n\tmetric.Int64Observable\n\tembedded.Int64ObservableUpDownCounter\n}\n\n// Float64ObservableUpDownCounter is an OpenTelemetry ObservableUpDownCounter\n// used to record float64 measurements. It produces no telemetry.\ntype Float64ObservableUpDownCounter struct {\n\tmetric.Float64Observable\n\tembedded.Float64ObservableUpDownCounter\n}\n\n// Int64Observer is a recorder of int64 measurements that performs no operation.\ntype Int64Observer struct{ embedded.Int64Observer }\n\n// Observe performs no operation.\nfunc (Int64Observer) Observe(int64, ...metric.ObserveOption) {}\n\n// Float64Observer is a recorder of float64 measurements that performs no\n// operation.\ntype Float64Observer struct{ embedded.Float64Observer }\n\n// Observe performs no operation.\nfunc (Float64Observer) Observe(float64, ...metric.ObserveOption) {}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/syncfloat64.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage metric // import \"go.opentelemetry.io/otel/metric\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/metric/embedded\"\n)\n\n// Float64Counter is an instrument that records increasing float64 values.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Float64Counter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Float64Counter\n\n\t// Add records a change to the counter.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tAdd(ctx context.Context, incr float64, options ...AddOption)\n\n\t// Enabled reports whether the instrument will process measurements for the given context.\n\t//\n\t// This function can be used in places where measuring an instrument\n\t// would result in computationally expensive operations.\n\tEnabled(context.Context) bool\n}\n\n// Float64CounterConfig contains options for synchronous counter instruments that\n// record float64 values.\ntype Float64CounterConfig struct {\n\tdescription string\n\tunit        string\n}\n\n// NewFloat64CounterConfig returns a new [Float64CounterConfig] with all opts\n// applied.\nfunc NewFloat64CounterConfig(opts ...Float64CounterOption) Float64CounterConfig {\n\tvar config Float64CounterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyFloat64Counter(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Float64CounterConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Float64CounterConfig) Unit() string {\n\treturn c.unit\n}\n\n// Float64CounterOption applies options to a [Float64CounterConfig]. See\n// [InstrumentOption] for other options that can be used as a\n// Float64CounterOption.\ntype Float64CounterOption interface {\n\tapplyFloat64Counter(Float64CounterConfig) Float64CounterConfig\n}\n\n// Float64UpDownCounter is an instrument that records increasing or decreasing\n// float64 values.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Float64UpDownCounter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Float64UpDownCounter\n\n\t// Add records a change to the counter.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tAdd(ctx context.Context, incr float64, options ...AddOption)\n\n\t// Enabled reports whether the instrument will process measurements for the given context.\n\t//\n\t// This function can be used in places where measuring an instrument\n\t// would result in computationally expensive operations.\n\tEnabled(context.Context) bool\n}\n\n// Float64UpDownCounterConfig contains options for synchronous counter\n// instruments that record float64 values.\ntype Float64UpDownCounterConfig struct {\n\tdescription string\n\tunit        string\n}\n\n// NewFloat64UpDownCounterConfig returns a new [Float64UpDownCounterConfig]\n// with all opts applied.\nfunc NewFloat64UpDownCounterConfig(opts ...Float64UpDownCounterOption) Float64UpDownCounterConfig {\n\tvar config Float64UpDownCounterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyFloat64UpDownCounter(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Float64UpDownCounterConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Float64UpDownCounterConfig) Unit() string {\n\treturn c.unit\n}\n\n// Float64UpDownCounterOption applies options to a\n// [Float64UpDownCounterConfig]. See [InstrumentOption] for other options that\n// can be used as a Float64UpDownCounterOption.\ntype Float64UpDownCounterOption interface {\n\tapplyFloat64UpDownCounter(Float64UpDownCounterConfig) Float64UpDownCounterConfig\n}\n\n// Float64Histogram is an instrument that records a distribution of float64\n// values.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Float64Histogram interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Float64Histogram\n\n\t// Record adds an additional value to the distribution.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tRecord(ctx context.Context, incr float64, options ...RecordOption)\n\n\t// Enabled reports whether the instrument will process measurements for the given context.\n\t//\n\t// This function can be used in places where measuring an instrument\n\t// would result in computationally expensive operations.\n\tEnabled(context.Context) bool\n}\n\n// Float64HistogramConfig contains options for synchronous histogram\n// instruments that record float64 values.\ntype Float64HistogramConfig struct {\n\tdescription              string\n\tunit                     string\n\texplicitBucketBoundaries []float64\n}\n\n// NewFloat64HistogramConfig returns a new [Float64HistogramConfig] with all\n// opts applied.\nfunc NewFloat64HistogramConfig(opts ...Float64HistogramOption) Float64HistogramConfig {\n\tvar config Float64HistogramConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyFloat64Histogram(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Float64HistogramConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Float64HistogramConfig) Unit() string {\n\treturn c.unit\n}\n\n// ExplicitBucketBoundaries returns the configured explicit bucket boundaries.\nfunc (c Float64HistogramConfig) ExplicitBucketBoundaries() []float64 {\n\treturn c.explicitBucketBoundaries\n}\n\n// Float64HistogramOption applies options to a [Float64HistogramConfig]. See\n// [InstrumentOption] for other options that can be used as a\n// Float64HistogramOption.\ntype Float64HistogramOption interface {\n\tapplyFloat64Histogram(Float64HistogramConfig) Float64HistogramConfig\n}\n\n// Float64Gauge is an instrument that records instantaneous float64 values.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Float64Gauge interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Float64Gauge\n\n\t// Record records the instantaneous value.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tRecord(ctx context.Context, value float64, options ...RecordOption)\n\n\t// Enabled reports whether the instrument will process measurements for the given context.\n\t//\n\t// This function can be used in places where measuring an instrument\n\t// would result in computationally expensive operations.\n\tEnabled(context.Context) bool\n}\n\n// Float64GaugeConfig contains options for synchronous gauge instruments that\n// record float64 values.\ntype Float64GaugeConfig struct {\n\tdescription string\n\tunit        string\n}\n\n// NewFloat64GaugeConfig returns a new [Float64GaugeConfig] with all opts\n// applied.\nfunc NewFloat64GaugeConfig(opts ...Float64GaugeOption) Float64GaugeConfig {\n\tvar config Float64GaugeConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyFloat64Gauge(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Float64GaugeConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Float64GaugeConfig) Unit() string {\n\treturn c.unit\n}\n\n// Float64GaugeOption applies options to a [Float64GaugeConfig]. See\n// [InstrumentOption] for other options that can be used as a\n// Float64GaugeOption.\ntype Float64GaugeOption interface {\n\tapplyFloat64Gauge(Float64GaugeConfig) Float64GaugeConfig\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/syncint64.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage metric // import \"go.opentelemetry.io/otel/metric\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/metric/embedded\"\n)\n\n// Int64Counter is an instrument that records increasing int64 values.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Int64Counter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Int64Counter\n\n\t// Add records a change to the counter.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tAdd(ctx context.Context, incr int64, options ...AddOption)\n\n\t// Enabled reports whether the instrument will process measurements for the given context.\n\t//\n\t// This function can be used in places where measuring an instrument\n\t// would result in computationally expensive operations.\n\tEnabled(context.Context) bool\n}\n\n// Int64CounterConfig contains options for synchronous counter instruments that\n// record int64 values.\ntype Int64CounterConfig struct {\n\tdescription string\n\tunit        string\n}\n\n// NewInt64CounterConfig returns a new [Int64CounterConfig] with all opts\n// applied.\nfunc NewInt64CounterConfig(opts ...Int64CounterOption) Int64CounterConfig {\n\tvar config Int64CounterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyInt64Counter(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Int64CounterConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Int64CounterConfig) Unit() string {\n\treturn c.unit\n}\n\n// Int64CounterOption applies options to a [Int64CounterConfig]. See\n// [InstrumentOption] for other options that can be used as an\n// Int64CounterOption.\ntype Int64CounterOption interface {\n\tapplyInt64Counter(Int64CounterConfig) Int64CounterConfig\n}\n\n// Int64UpDownCounter is an instrument that records increasing or decreasing\n// int64 values.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Int64UpDownCounter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Int64UpDownCounter\n\n\t// Add records a change to the counter.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tAdd(ctx context.Context, incr int64, options ...AddOption)\n\n\t// Enabled reports whether the instrument will process measurements for the given context.\n\t//\n\t// This function can be used in places where measuring an instrument\n\t// would result in computationally expensive operations.\n\tEnabled(context.Context) bool\n}\n\n// Int64UpDownCounterConfig contains options for synchronous counter\n// instruments that record int64 values.\ntype Int64UpDownCounterConfig struct {\n\tdescription string\n\tunit        string\n}\n\n// NewInt64UpDownCounterConfig returns a new [Int64UpDownCounterConfig] with\n// all opts applied.\nfunc NewInt64UpDownCounterConfig(opts ...Int64UpDownCounterOption) Int64UpDownCounterConfig {\n\tvar config Int64UpDownCounterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyInt64UpDownCounter(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Int64UpDownCounterConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Int64UpDownCounterConfig) Unit() string {\n\treturn c.unit\n}\n\n// Int64UpDownCounterOption applies options to a [Int64UpDownCounterConfig].\n// See [InstrumentOption] for other options that can be used as an\n// Int64UpDownCounterOption.\ntype Int64UpDownCounterOption interface {\n\tapplyInt64UpDownCounter(Int64UpDownCounterConfig) Int64UpDownCounterConfig\n}\n\n// Int64Histogram is an instrument that records a distribution of int64\n// values.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Int64Histogram interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Int64Histogram\n\n\t// Record adds an additional value to the distribution.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tRecord(ctx context.Context, incr int64, options ...RecordOption)\n\n\t// Enabled reports whether the instrument will process measurements for the given context.\n\t//\n\t// This function can be used in places where measuring an instrument\n\t// would result in computationally expensive operations.\n\tEnabled(context.Context) bool\n}\n\n// Int64HistogramConfig contains options for synchronous histogram instruments\n// that record int64 values.\ntype Int64HistogramConfig struct {\n\tdescription              string\n\tunit                     string\n\texplicitBucketBoundaries []float64\n}\n\n// NewInt64HistogramConfig returns a new [Int64HistogramConfig] with all opts\n// applied.\nfunc NewInt64HistogramConfig(opts ...Int64HistogramOption) Int64HistogramConfig {\n\tvar config Int64HistogramConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyInt64Histogram(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Int64HistogramConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Int64HistogramConfig) Unit() string {\n\treturn c.unit\n}\n\n// ExplicitBucketBoundaries returns the configured explicit bucket boundaries.\nfunc (c Int64HistogramConfig) ExplicitBucketBoundaries() []float64 {\n\treturn c.explicitBucketBoundaries\n}\n\n// Int64HistogramOption applies options to a [Int64HistogramConfig]. See\n// [InstrumentOption] for other options that can be used as an\n// Int64HistogramOption.\ntype Int64HistogramOption interface {\n\tapplyInt64Histogram(Int64HistogramConfig) Int64HistogramConfig\n}\n\n// Int64Gauge is an instrument that records instantaneous int64 values.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Int64Gauge interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Int64Gauge\n\n\t// Record records the instantaneous value.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tRecord(ctx context.Context, value int64, options ...RecordOption)\n\n\t// Enabled reports whether the instrument will process measurements for the given context.\n\t//\n\t// This function can be used in places where measuring an instrument\n\t// would result in computationally expensive operations.\n\tEnabled(context.Context) bool\n}\n\n// Int64GaugeConfig contains options for synchronous gauge instruments that\n// record int64 values.\ntype Int64GaugeConfig struct {\n\tdescription string\n\tunit        string\n}\n\n// NewInt64GaugeConfig returns a new [Int64GaugeConfig] with all opts\n// applied.\nfunc NewInt64GaugeConfig(opts ...Int64GaugeOption) Int64GaugeConfig {\n\tvar config Int64GaugeConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyInt64Gauge(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Int64GaugeConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Int64GaugeConfig) Unit() string {\n\treturn c.unit\n}\n\n// Int64GaugeOption applies options to a [Int64GaugeConfig]. See\n// [InstrumentOption] for other options that can be used as a\n// Int64GaugeOption.\ntype Int64GaugeOption interface {\n\tapplyInt64Gauge(Int64GaugeConfig) Int64GaugeConfig\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage otel // import \"go.opentelemetry.io/otel\"\n\nimport (\n\t\"go.opentelemetry.io/otel/internal/global\"\n\t\"go.opentelemetry.io/otel/metric\"\n)\n\n// Meter returns a Meter from the global MeterProvider. The name must be the\n// name of the library providing instrumentation. This name may be the same as\n// the instrumented code only if that code provides built-in instrumentation.\n// If the name is empty, then an implementation defined default name will be\n// used instead.\n//\n// If this is called before a global MeterProvider is registered the returned\n// Meter will be a No-op implementation of a Meter. When a global MeterProvider\n// is registered for the first time, the returned Meter, and all the\n// instruments it has created or will create, are recreated automatically from\n// the new MeterProvider.\n//\n// This is short for GetMeterProvider().Meter(name).\nfunc Meter(name string, opts ...metric.MeterOption) metric.Meter {\n\treturn GetMeterProvider().Meter(name, opts...)\n}\n\n// GetMeterProvider returns the registered global meter provider.\n//\n// If no global GetMeterProvider has been registered, a No-op GetMeterProvider\n// implementation is returned. When a global GetMeterProvider is registered for\n// the first time, the returned GetMeterProvider, and all the Meters it has\n// created or will create, are recreated automatically from the new\n// GetMeterProvider.\nfunc GetMeterProvider() metric.MeterProvider {\n\treturn global.MeterProvider()\n}\n\n// SetMeterProvider registers mp as the global MeterProvider.\nfunc SetMeterProvider(mp metric.MeterProvider) {\n\tglobal.SetMeterProvider(mp)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/propagation/README.md",
    "content": "# Propagation\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/propagation)](https://pkg.go.dev/go.opentelemetry.io/otel/propagation)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/propagation/baggage.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage propagation // import \"go.opentelemetry.io/otel/propagation\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/baggage\"\n)\n\nconst baggageHeader = \"baggage\"\n\n// Baggage is a propagator that supports the W3C Baggage format.\n//\n// This propagates user-defined baggage associated with a trace. The complete\n// specification is defined at https://www.w3.org/TR/baggage/.\ntype Baggage struct{}\n\nvar _ TextMapPropagator = Baggage{}\n\n// Inject sets baggage key-values from ctx into the carrier.\nfunc (Baggage) Inject(ctx context.Context, carrier TextMapCarrier) {\n\tbStr := baggage.FromContext(ctx).String()\n\tif bStr != \"\" {\n\t\tcarrier.Set(baggageHeader, bStr)\n\t}\n}\n\n// Extract returns a copy of parent with the baggage from the carrier added.\n// If carrier implements [ValuesGetter] (e.g. [HeaderCarrier]), Values is invoked\n// for multiple values extraction. Otherwise, Get is called.\nfunc (Baggage) Extract(parent context.Context, carrier TextMapCarrier) context.Context {\n\tif multiCarrier, ok := carrier.(ValuesGetter); ok {\n\t\treturn extractMultiBaggage(parent, multiCarrier)\n\t}\n\treturn extractSingleBaggage(parent, carrier)\n}\n\n// Fields returns the keys who's values are set with Inject.\nfunc (Baggage) Fields() []string {\n\treturn []string{baggageHeader}\n}\n\nfunc extractSingleBaggage(parent context.Context, carrier TextMapCarrier) context.Context {\n\tbStr := carrier.Get(baggageHeader)\n\tif bStr == \"\" {\n\t\treturn parent\n\t}\n\n\tbag, err := baggage.Parse(bStr)\n\tif err != nil {\n\t\treturn parent\n\t}\n\treturn baggage.ContextWithBaggage(parent, bag)\n}\n\nfunc extractMultiBaggage(parent context.Context, carrier ValuesGetter) context.Context {\n\tbVals := carrier.Values(baggageHeader)\n\tif len(bVals) == 0 {\n\t\treturn parent\n\t}\n\tvar members []baggage.Member\n\tfor _, bStr := range bVals {\n\t\tcurrBag, err := baggage.Parse(bStr)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tmembers = append(members, currBag.Members()...)\n\t}\n\n\tb, err := baggage.New(members...)\n\tif err != nil || b.Len() == 0 {\n\t\treturn parent\n\t}\n\treturn baggage.ContextWithBaggage(parent, b)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/propagation/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n/*\nPackage propagation contains OpenTelemetry context propagators.\n\nOpenTelemetry propagators are used to extract and inject context data from and\ninto messages exchanged by applications. The propagator supported by this\npackage is the W3C Trace Context encoding\n(https://www.w3.org/TR/trace-context/), and W3C Baggage\n(https://www.w3.org/TR/baggage/).\n*/\npackage propagation // import \"go.opentelemetry.io/otel/propagation\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/propagation/propagation.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage propagation // import \"go.opentelemetry.io/otel/propagation\"\n\nimport (\n\t\"context\"\n\t\"net/http\"\n)\n\n// TextMapCarrier is the storage medium used by a TextMapPropagator.\n// See ValuesGetter for how a TextMapCarrier can get multiple values for a key.\ntype TextMapCarrier interface {\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Get returns the value associated with the passed key.\n\tGet(key string) string\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Set stores the key-value pair.\n\tSet(key, value string)\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Keys lists the keys stored in this carrier.\n\tKeys() []string\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n}\n\n// ValuesGetter can return multiple values for a single key,\n// with contrast to TextMapCarrier.Get which returns a single value.\ntype ValuesGetter interface {\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Values returns all values associated with the passed key.\n\tValues(key string) []string\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n}\n\n// MapCarrier is a TextMapCarrier that uses a map held in memory as a storage\n// medium for propagated key-value pairs.\ntype MapCarrier map[string]string\n\n// Compile time check that MapCarrier implements the TextMapCarrier.\nvar _ TextMapCarrier = MapCarrier{}\n\n// Get returns the value associated with the passed key.\nfunc (c MapCarrier) Get(key string) string {\n\treturn c[key]\n}\n\n// Set stores the key-value pair.\nfunc (c MapCarrier) Set(key, value string) {\n\tc[key] = value\n}\n\n// Keys lists the keys stored in this carrier.\nfunc (c MapCarrier) Keys() []string {\n\tkeys := make([]string, 0, len(c))\n\tfor k := range c {\n\t\tkeys = append(keys, k)\n\t}\n\treturn keys\n}\n\n// HeaderCarrier adapts http.Header to satisfy the TextMapCarrier and ValuesGetter interfaces.\ntype HeaderCarrier http.Header\n\n// Compile time check that HeaderCarrier implements ValuesGetter.\nvar _ TextMapCarrier = HeaderCarrier{}\n\n// Compile time check that HeaderCarrier implements TextMapCarrier.\nvar _ ValuesGetter = HeaderCarrier{}\n\n// Get returns the first value associated with the passed key.\nfunc (hc HeaderCarrier) Get(key string) string {\n\treturn http.Header(hc).Get(key)\n}\n\n// Values returns all values associated with the passed key.\nfunc (hc HeaderCarrier) Values(key string) []string {\n\treturn http.Header(hc).Values(key)\n}\n\n// Set stores the key-value pair.\nfunc (hc HeaderCarrier) Set(key, value string) {\n\thttp.Header(hc).Set(key, value)\n}\n\n// Keys lists the keys stored in this carrier.\nfunc (hc HeaderCarrier) Keys() []string {\n\tkeys := make([]string, 0, len(hc))\n\tfor k := range hc {\n\t\tkeys = append(keys, k)\n\t}\n\treturn keys\n}\n\n// TextMapPropagator propagates cross-cutting concerns as key-value text\n// pairs within a carrier that travels in-band across process boundaries.\ntype TextMapPropagator interface {\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Inject set cross-cutting concerns from the Context into the carrier.\n\tInject(ctx context.Context, carrier TextMapCarrier)\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Extract reads cross-cutting concerns from the carrier into a Context.\n\t// Implementations may check if the carrier implements ValuesGetter,\n\t// to support extraction of multiple values per key.\n\tExtract(ctx context.Context, carrier TextMapCarrier) context.Context\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Fields returns the keys whose values are set with Inject.\n\tFields() []string\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n}\n\ntype compositeTextMapPropagator []TextMapPropagator\n\nfunc (p compositeTextMapPropagator) Inject(ctx context.Context, carrier TextMapCarrier) {\n\tfor _, i := range p {\n\t\ti.Inject(ctx, carrier)\n\t}\n}\n\nfunc (p compositeTextMapPropagator) Extract(ctx context.Context, carrier TextMapCarrier) context.Context {\n\tfor _, i := range p {\n\t\tctx = i.Extract(ctx, carrier)\n\t}\n\treturn ctx\n}\n\nfunc (p compositeTextMapPropagator) Fields() []string {\n\tunique := make(map[string]struct{})\n\tfor _, i := range p {\n\t\tfor _, k := range i.Fields() {\n\t\t\tunique[k] = struct{}{}\n\t\t}\n\t}\n\n\tfields := make([]string, 0, len(unique))\n\tfor k := range unique {\n\t\tfields = append(fields, k)\n\t}\n\treturn fields\n}\n\n// NewCompositeTextMapPropagator returns a unified TextMapPropagator from the\n// group of passed TextMapPropagator. This allows different cross-cutting\n// concerns to be propagates in a unified manner.\n//\n// The returned TextMapPropagator will inject and extract cross-cutting\n// concerns in the order the TextMapPropagators were provided. Additionally,\n// the Fields method will return a de-duplicated slice of the keys that are\n// set with the Inject method.\nfunc NewCompositeTextMapPropagator(p ...TextMapPropagator) TextMapPropagator {\n\treturn compositeTextMapPropagator(p)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/propagation/trace_context.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage propagation // import \"go.opentelemetry.io/otel/propagation\"\n\nimport (\n\t\"context\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\nconst (\n\tsupportedVersion  = 0\n\tmaxVersion        = 254\n\ttraceparentHeader = \"traceparent\"\n\ttracestateHeader  = \"tracestate\"\n\tdelimiter         = \"-\"\n)\n\n// TraceContext is a propagator that supports the W3C Trace Context format\n// (https://www.w3.org/TR/trace-context/)\n//\n// This propagator will propagate the traceparent and tracestate headers to\n// guarantee traces are not broken. It is up to the users of this propagator\n// to choose if they want to participate in a trace by modifying the\n// traceparent header and relevant parts of the tracestate header containing\n// their proprietary information.\ntype TraceContext struct{}\n\nvar (\n\t_           TextMapPropagator = TraceContext{}\n\tversionPart                   = fmt.Sprintf(\"%.2X\", supportedVersion)\n)\n\n// Inject injects the trace context from ctx into carrier.\nfunc (TraceContext) Inject(ctx context.Context, carrier TextMapCarrier) {\n\tsc := trace.SpanContextFromContext(ctx)\n\tif !sc.IsValid() {\n\t\treturn\n\t}\n\n\tif ts := sc.TraceState().String(); ts != \"\" {\n\t\tcarrier.Set(tracestateHeader, ts)\n\t}\n\n\t// Clear all flags other than the trace-context supported sampling bit.\n\tflags := sc.TraceFlags() & trace.FlagsSampled\n\n\tvar sb strings.Builder\n\tsb.Grow(2 + 32 + 16 + 2 + 3)\n\t_, _ = sb.WriteString(versionPart)\n\ttraceID := sc.TraceID()\n\tspanID := sc.SpanID()\n\tflagByte := [1]byte{byte(flags)}\n\tvar buf [32]byte\n\tfor _, src := range [][]byte{traceID[:], spanID[:], flagByte[:]} {\n\t\t_ = sb.WriteByte(delimiter[0])\n\t\tn := hex.Encode(buf[:], src)\n\t\t_, _ = sb.Write(buf[:n])\n\t}\n\tcarrier.Set(traceparentHeader, sb.String())\n}\n\n// Extract reads tracecontext from the carrier into a returned Context.\n//\n// The returned Context will be a copy of ctx and contain the extracted\n// tracecontext as the remote SpanContext. If the extracted tracecontext is\n// invalid, the passed ctx will be returned directly instead.\nfunc (tc TraceContext) Extract(ctx context.Context, carrier TextMapCarrier) context.Context {\n\tsc := tc.extract(carrier)\n\tif !sc.IsValid() {\n\t\treturn ctx\n\t}\n\treturn trace.ContextWithRemoteSpanContext(ctx, sc)\n}\n\nfunc (TraceContext) extract(carrier TextMapCarrier) trace.SpanContext {\n\th := carrier.Get(traceparentHeader)\n\tif h == \"\" {\n\t\treturn trace.SpanContext{}\n\t}\n\n\tvar ver [1]byte\n\tif !extractPart(ver[:], &h, 2) {\n\t\treturn trace.SpanContext{}\n\t}\n\tversion := int(ver[0])\n\tif version > maxVersion {\n\t\treturn trace.SpanContext{}\n\t}\n\n\tvar scc trace.SpanContextConfig\n\tif !extractPart(scc.TraceID[:], &h, 32) {\n\t\treturn trace.SpanContext{}\n\t}\n\tif !extractPart(scc.SpanID[:], &h, 16) {\n\t\treturn trace.SpanContext{}\n\t}\n\n\tvar opts [1]byte\n\tif !extractPart(opts[:], &h, 2) {\n\t\treturn trace.SpanContext{}\n\t}\n\tif version == 0 && (h != \"\" || opts[0] > 2) {\n\t\t// version 0 not allow extra\n\t\t// version 0 not allow other flag\n\t\treturn trace.SpanContext{}\n\t}\n\n\t// Clear all flags other than the trace-context supported sampling bit.\n\tscc.TraceFlags = trace.TraceFlags(opts[0]) & trace.FlagsSampled // nolint:gosec // slice size already checked.\n\n\t// Ignore the error returned here. Failure to parse tracestate MUST NOT\n\t// affect the parsing of traceparent according to the W3C tracecontext\n\t// specification.\n\tscc.TraceState, _ = trace.ParseTraceState(carrier.Get(tracestateHeader))\n\tscc.Remote = true\n\n\tsc := trace.NewSpanContext(scc)\n\tif !sc.IsValid() {\n\t\treturn trace.SpanContext{}\n\t}\n\n\treturn sc\n}\n\n// upperHex detect hex is upper case Unicode characters.\nfunc upperHex(v string) bool {\n\tfor _, c := range v {\n\t\tif c >= 'A' && c <= 'F' {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc extractPart(dst []byte, h *string, n int) bool {\n\tpart, left, _ := strings.Cut(*h, delimiter)\n\t*h = left\n\t// hex.Decode decodes unsupported upper-case characters, so exclude explicitly.\n\tif len(part) != n || upperHex(part) {\n\t\treturn false\n\t}\n\tif p, err := hex.Decode(dst, []byte(part)); err != nil || p != n/2 {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// Fields returns the keys who's values are set with Inject.\nfunc (TraceContext) Fields() []string {\n\treturn []string{traceparentHeader, tracestateHeader}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/propagation.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage otel // import \"go.opentelemetry.io/otel\"\n\nimport (\n\t\"go.opentelemetry.io/otel/internal/global\"\n\t\"go.opentelemetry.io/otel/propagation\"\n)\n\n// GetTextMapPropagator returns the global TextMapPropagator. If none has been\n// set, a No-Op TextMapPropagator is returned.\nfunc GetTextMapPropagator() propagation.TextMapPropagator {\n\treturn global.TextMapPropagator()\n}\n\n// SetTextMapPropagator sets propagator as the global TextMapPropagator.\nfunc SetTextMapPropagator(propagator propagation.TextMapPropagator) {\n\tglobal.SetTextMapPropagator(propagator)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/renovate.json",
    "content": "{\n  \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n  \"extends\": [\n    \"config:best-practices\",\n    \"helpers:pinGitHubActionDigestsToSemver\"\n  ],\n  \"ignorePaths\": [],\n  \"labels\": [\"Skip Changelog\", \"dependencies\"],\n  \"postUpdateOptions\" : [\n    \"gomodTidy\"\n  ],\n  \"packageRules\": [\n    {\n      \"matchManagers\": [\"gomod\"],\n      \"matchDepTypes\": [\"indirect\"],\n      \"enabled\": true\n    },\n    {\n      \"matchPackageNames\": [\"go.opentelemetry.io/build-tools/**\"],\n      \"groupName\": \"build-tools\"\n    },\n    {\n      \"matchPackageNames\": [\"google.golang.org/genproto/googleapis/**\"],\n      \"groupName\": \"googleapis\"\n    },\n    {\n      \"matchPackageNames\": [\"golang.org/x/**\"],\n      \"groupName\": \"golang.org/x\"\n    },\n    {\n      \"matchPackageNames\": [\"go.opentelemetry.io/otel/sdk/log/logtest\"],\n      \"enabled\": false\n    }\n  ]\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/requirements.txt",
    "content": "codespell==2.4.1\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n--------------------------------------------------------------------------------\n\nCopyright 2009 The Go Authors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google LLC nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/README.md",
    "content": "# SDK\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/sdk)](https://pkg.go.dev/go.opentelemetry.io/otel/sdk)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/instrumentation/README.md",
    "content": "# SDK Instrumentation\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/sdk/instrumentation)](https://pkg.go.dev/go.opentelemetry.io/otel/sdk/instrumentation)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/instrumentation/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package instrumentation provides types to represent the code libraries that\n// provide OpenTelemetry instrumentation. These types are used in the\n// OpenTelemetry signal pipelines to identify the source of telemetry.\n//\n// See\n// https://github.com/open-telemetry/oteps/blob/d226b677d73a785523fe9b9701be13225ebc528d/text/0083-component.md\n// and\n// https://github.com/open-telemetry/oteps/blob/d226b677d73a785523fe9b9701be13225ebc528d/text/0201-scope-attributes.md\n// for more information.\npackage instrumentation // import \"go.opentelemetry.io/otel/sdk/instrumentation\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/instrumentation/library.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage instrumentation // import \"go.opentelemetry.io/otel/sdk/instrumentation\"\n\n// Library represents the instrumentation library.\n//\n// Deprecated: use [Scope] instead.\ntype Library = Scope\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/instrumentation/scope.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage instrumentation // import \"go.opentelemetry.io/otel/sdk/instrumentation\"\n\nimport \"go.opentelemetry.io/otel/attribute\"\n\n// Scope represents the instrumentation scope.\ntype Scope struct {\n\t// Name is the name of the instrumentation scope. This should be the\n\t// Go package name of that scope.\n\tName string\n\t// Version is the version of the instrumentation scope.\n\tVersion string\n\t// SchemaURL of the telemetry emitted by the scope.\n\tSchemaURL string\n\t// Attributes of the telemetry emitted by the scope.\n\tAttributes attribute.Set\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/internal/x/README.md",
    "content": "# Experimental Features\n\nThe SDK contains features that have not yet stabilized in the OpenTelemetry specification.\nThese features are added to the OpenTelemetry Go SDK prior to stabilization in the specification so that users can start experimenting with them and provide feedback.\n\nThese feature may change in backwards incompatible ways as feedback is applied.\nSee the [Compatibility and Stability](#compatibility-and-stability) section for more information.\n\n## Features\n\n- [Resource](#resource)\n\n### Resource\n\n[OpenTelemetry resource semantic conventions] include many attribute definitions that are defined as experimental.\nTo have experimental semantic conventions be added by [resource detectors] set the `OTEL_GO_X_RESOURCE` environment variable.\nThe value set must be the case-insensitive string of `\"true\"` to enable the feature.\nAll other values are ignored.\n\n<!-- TODO: document what attributes are added by which detector -->\n\n[OpenTelemetry resource semantic conventions]: https://opentelemetry.io/docs/specs/semconv/resource/\n[resource detectors]: https://pkg.go.dev/go.opentelemetry.io/otel/sdk/resource#Detector\n\n#### Examples\n\nEnable experimental resource semantic conventions.\n\n```console\nexport OTEL_GO_X_RESOURCE=true\n```\n\nDisable experimental resource semantic conventions.\n\n```console\nunset OTEL_GO_X_RESOURCE\n```\n\n## Compatibility and Stability\n\nExperimental features do not fall within the scope of the OpenTelemetry Go versioning and stability [policy](../../../VERSIONING.md).\nThese features may be removed or modified in successive version releases, including patch versions.\n\nWhen an experimental feature is promoted to a stable feature, a migration path will be included in the changelog entry of the release.\nThere is no guarantee that any environment variable feature flags that enabled the experimental feature will be supported by the stable version.\nIf they are supported, they may be accompanied with a deprecation notice stating a timeline for the removal of that support.\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/internal/x/features.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package x documents experimental features for [go.opentelemetry.io/otel/sdk].\npackage x // import \"go.opentelemetry.io/otel/sdk/internal/x\"\n\nimport \"strings\"\n\n// Resource is an experimental feature flag that defines if resource detectors\n// should be included experimental semantic conventions.\n//\n// To enable this feature set the OTEL_GO_X_RESOURCE environment variable\n// to the case-insensitive string value of \"true\" (i.e. \"True\" and \"TRUE\"\n// will also enable this).\nvar Resource = newFeature(\n\t[]string{\"RESOURCE\"},\n\tfunc(v string) (string, bool) {\n\t\tif strings.EqualFold(v, \"true\") {\n\t\t\treturn v, true\n\t\t}\n\t\treturn \"\", false\n\t},\n)\n\n// Observability is an experimental feature flag that determines if SDK\n// observability metrics are enabled.\n//\n// To enable this feature set the OTEL_GO_X_OBSERVABILITY environment variable\n// to the case-insensitive string value of \"true\" (i.e. \"True\" and \"TRUE\"\n// will also enable this).\nvar Observability = newFeature(\n\t[]string{\"OBSERVABILITY\", \"SELF_OBSERVABILITY\"},\n\tfunc(v string) (string, bool) {\n\t\tif strings.EqualFold(v, \"true\") {\n\t\t\treturn v, true\n\t\t}\n\t\treturn \"\", false\n\t},\n)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/internal/x/x.go",
    "content": "// Code generated by gotmpl. DO NOT MODIFY.\n// source: internal/shared/x/x.go.tmpl\n\n// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package x documents experimental features for [go.opentelemetry.io/otel/sdk].\npackage x // import \"go.opentelemetry.io/otel/sdk/internal/x\"\n\nimport (\n\t\"os\"\n)\n\n// Feature is an experimental feature control flag. It provides a uniform way\n// to interact with these feature flags and parse their values.\ntype Feature[T any] struct {\n\tkeys  []string\n\tparse func(v string) (T, bool)\n}\n\nfunc newFeature[T any](suffix []string, parse func(string) (T, bool)) Feature[T] {\n\tconst envKeyRoot = \"OTEL_GO_X_\"\n\tkeys := make([]string, 0, len(suffix))\n\tfor _, s := range suffix {\n\t\tkeys = append(keys, envKeyRoot+s)\n\t}\n\treturn Feature[T]{\n\t\tkeys:  keys,\n\t\tparse: parse,\n\t}\n}\n\n// Keys returns the environment variable keys that can be set to enable the\n// feature.\nfunc (f Feature[T]) Keys() []string { return f.keys }\n\n// Lookup returns the user configured value for the feature and true if the\n// user has enabled the feature. Otherwise, if the feature is not enabled, a\n// zero-value and false are returned.\nfunc (f Feature[T]) Lookup() (v T, ok bool) {\n\t// https://github.com/open-telemetry/opentelemetry-specification/blob/62effed618589a0bec416a87e559c0a9d96289bb/specification/configuration/sdk-environment-variables.md#parsing-empty-value\n\t//\n\t// > The SDK MUST interpret an empty value of an environment variable the\n\t// > same way as when the variable is unset.\n\tfor _, key := range f.keys {\n\t\tvRaw := os.Getenv(key)\n\t\tif vRaw != \"\" {\n\t\t\treturn f.parse(vRaw)\n\t\t}\n\t}\n\treturn v, ok\n}\n\n// Enabled reports whether the feature is enabled.\nfunc (f Feature[T]) Enabled() bool {\n\t_, ok := f.Lookup()\n\treturn ok\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/README.md",
    "content": "# SDK Resource\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/sdk/resource)](https://pkg.go.dev/go.opentelemetry.io/otel/sdk/resource)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/auto.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n)\n\n// ErrPartialResource is returned by a detector when complete source\n// information for a Resource is unavailable or the source information\n// contains invalid values that are omitted from the returned Resource.\nvar ErrPartialResource = errors.New(\"partial resource\")\n\n// Detector detects OpenTelemetry resource information.\ntype Detector interface {\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Detect returns an initialized Resource based on gathered information.\n\t// If the source information to construct a Resource contains invalid\n\t// values, a Resource is returned with the valid parts of the source\n\t// information used for initialization along with an appropriately\n\t// wrapped ErrPartialResource error.\n\tDetect(ctx context.Context) (*Resource, error)\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n}\n\n// Detect returns a new [Resource] merged from all the Resources each of the\n// detectors produces. Each of the detectors are called sequentially, in the\n// order they are passed, merging the produced resource into the previous.\n//\n// This may return a partial Resource along with an error containing\n// [ErrPartialResource] if that error is returned from a detector. It may also\n// return a merge-conflicting Resource along with an error containing\n// [ErrSchemaURLConflict] if merging Resources from different detectors results\n// in a schema URL conflict. It is up to the caller to determine if this\n// returned Resource should be used or not.\n//\n// If one of the detectors returns an error that is not [ErrPartialResource],\n// the resource produced by the detector will not be merged and the returned\n// error will wrap that detector's error.\nfunc Detect(ctx context.Context, detectors ...Detector) (*Resource, error) {\n\tr := new(Resource)\n\treturn r, detect(ctx, r, detectors)\n}\n\n// detect runs all detectors using ctx and merges the result into res. This\n// assumes res is allocated and not nil, it will panic otherwise.\n//\n// If the detectors or merging resources produces any errors (i.e.\n// [ErrPartialResource] [ErrSchemaURLConflict]), a single error wrapping all of\n// these errors will be returned. Otherwise, nil is returned.\nfunc detect(ctx context.Context, res *Resource, detectors []Detector) error {\n\tvar (\n\t\tr   *Resource\n\t\terr error\n\t\te   error\n\t)\n\n\tfor _, detector := range detectors {\n\t\tif detector == nil {\n\t\t\tcontinue\n\t\t}\n\t\tr, e = detector.Detect(ctx)\n\t\tif e != nil {\n\t\t\terr = errors.Join(err, e)\n\t\t\tif !errors.Is(e, ErrPartialResource) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tr, e = Merge(res, r)\n\t\tif e != nil {\n\t\t\terr = errors.Join(err, e)\n\t\t}\n\t\t*res = *r\n\t}\n\n\tif err != nil {\n\t\tif errors.Is(err, ErrSchemaURLConflict) {\n\t\t\t// If there has been a merge conflict, ensure the resource has no\n\t\t\t// schema URL.\n\t\t\tres.schemaURL = \"\"\n\t\t}\n\n\t\terr = fmt.Errorf(\"error detecting resource: %w\", err)\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/google/uuid\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/sdk\"\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.39.0\"\n)\n\ntype (\n\t// telemetrySDK is a Detector that provides information about\n\t// the OpenTelemetry SDK used.  This Detector is included as a\n\t// builtin. If these resource attributes are not wanted, use\n\t// resource.New() to explicitly disable them.\n\ttelemetrySDK struct{}\n\n\t// host is a Detector that provides information about the host\n\t// being run on. This Detector is included as a builtin. If\n\t// these resource attributes are not wanted, use the\n\t// resource.New() to explicitly disable them.\n\thost struct{}\n\n\tstringDetector struct {\n\t\tschemaURL string\n\t\tK         attribute.Key\n\t\tF         func() (string, error)\n\t}\n\n\tdefaultServiceNameDetector struct{}\n\n\tdefaultServiceInstanceIDDetector struct{}\n)\n\nvar (\n\t_ Detector = telemetrySDK{}\n\t_ Detector = host{}\n\t_ Detector = stringDetector{}\n\t_ Detector = defaultServiceNameDetector{}\n\t_ Detector = defaultServiceInstanceIDDetector{}\n)\n\n// Detect returns a *Resource that describes the OpenTelemetry SDK used.\nfunc (telemetrySDK) Detect(context.Context) (*Resource, error) {\n\treturn NewWithAttributes(\n\t\tsemconv.SchemaURL,\n\t\tsemconv.TelemetrySDKName(\"opentelemetry\"),\n\t\tsemconv.TelemetrySDKLanguageGo,\n\t\tsemconv.TelemetrySDKVersion(sdk.Version()),\n\t), nil\n}\n\n// Detect returns a *Resource that describes the host being run on.\nfunc (host) Detect(ctx context.Context) (*Resource, error) {\n\treturn StringDetector(semconv.SchemaURL, semconv.HostNameKey, os.Hostname).Detect(ctx)\n}\n\n// StringDetector returns a Detector that will produce a *Resource\n// containing the string as a value corresponding to k. The resulting Resource\n// will have the specified schemaURL.\nfunc StringDetector(schemaURL string, k attribute.Key, f func() (string, error)) Detector {\n\treturn stringDetector{schemaURL: schemaURL, K: k, F: f}\n}\n\n// Detect returns a *Resource that describes the string as a value\n// corresponding to attribute.Key as well as the specific schemaURL.\nfunc (sd stringDetector) Detect(context.Context) (*Resource, error) {\n\tvalue, err := sd.F()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%s: %w\", string(sd.K), err)\n\t}\n\ta := sd.K.String(value)\n\tif !a.Valid() {\n\t\treturn nil, fmt.Errorf(\"invalid attribute: %q -> %q\", a.Key, a.Value.Emit())\n\t}\n\treturn NewWithAttributes(sd.schemaURL, sd.K.String(value)), nil\n}\n\n// Detect implements Detector.\nfunc (defaultServiceNameDetector) Detect(ctx context.Context) (*Resource, error) {\n\treturn StringDetector(\n\t\tsemconv.SchemaURL,\n\t\tsemconv.ServiceNameKey,\n\t\tfunc() (string, error) {\n\t\t\texecutable, err := os.Executable()\n\t\t\tif err != nil {\n\t\t\t\treturn \"unknown_service:go\", nil\n\t\t\t}\n\t\t\treturn \"unknown_service:\" + filepath.Base(executable), nil\n\t\t},\n\t).Detect(ctx)\n}\n\n// Detect implements Detector.\nfunc (defaultServiceInstanceIDDetector) Detect(ctx context.Context) (*Resource, error) {\n\treturn StringDetector(\n\t\tsemconv.SchemaURL,\n\t\tsemconv.ServiceInstanceIDKey,\n\t\tfunc() (string, error) {\n\t\t\tversion4Uuid, err := uuid.NewRandom()\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", err\n\t\t\t}\n\n\t\t\treturn version4Uuid.String(), nil\n\t\t},\n\t).Detect(ctx)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/config.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n)\n\n// config contains configuration for Resource creation.\ntype config struct {\n\t// detectors that will be evaluated.\n\tdetectors []Detector\n\t// SchemaURL to associate with the Resource.\n\tschemaURL string\n}\n\n// Option is the interface that applies a configuration option.\ntype Option interface {\n\t// apply sets the Option value of a config.\n\tapply(config) config\n}\n\n// WithAttributes adds attributes to the configured Resource.\nfunc WithAttributes(attributes ...attribute.KeyValue) Option {\n\treturn WithDetectors(detectAttributes{attributes})\n}\n\ntype detectAttributes struct {\n\tattributes []attribute.KeyValue\n}\n\nfunc (d detectAttributes) Detect(context.Context) (*Resource, error) {\n\treturn NewSchemaless(d.attributes...), nil\n}\n\n// WithDetectors adds detectors to be evaluated for the configured resource.\nfunc WithDetectors(detectors ...Detector) Option {\n\treturn detectorsOption{detectors: detectors}\n}\n\ntype detectorsOption struct {\n\tdetectors []Detector\n}\n\nfunc (o detectorsOption) apply(cfg config) config {\n\tcfg.detectors = append(cfg.detectors, o.detectors...)\n\treturn cfg\n}\n\n// WithFromEnv adds attributes from environment variables to the configured resource.\nfunc WithFromEnv() Option {\n\treturn WithDetectors(fromEnv{})\n}\n\n// WithHost adds attributes from the host to the configured resource.\nfunc WithHost() Option {\n\treturn WithDetectors(host{})\n}\n\n// WithHostID adds host ID information to the configured resource.\nfunc WithHostID() Option {\n\treturn WithDetectors(hostIDDetector{})\n}\n\n// WithTelemetrySDK adds TelemetrySDK version info to the configured resource.\nfunc WithTelemetrySDK() Option {\n\treturn WithDetectors(telemetrySDK{})\n}\n\n// WithSchemaURL sets the schema URL for the configured resource.\nfunc WithSchemaURL(schemaURL string) Option {\n\treturn schemaURLOption(schemaURL)\n}\n\ntype schemaURLOption string\n\nfunc (o schemaURLOption) apply(cfg config) config {\n\tcfg.schemaURL = string(o)\n\treturn cfg\n}\n\n// WithOS adds all the OS attributes to the configured Resource.\n// See individual WithOS* functions to configure specific attributes.\nfunc WithOS() Option {\n\treturn WithDetectors(\n\t\tosTypeDetector{},\n\t\tosDescriptionDetector{},\n\t)\n}\n\n// WithOSType adds an attribute with the operating system type to the configured Resource.\nfunc WithOSType() Option {\n\treturn WithDetectors(osTypeDetector{})\n}\n\n// WithOSDescription adds an attribute with the operating system description to the\n// configured Resource. The formatted string is equivalent to the output of the\n// `uname -snrvm` command.\nfunc WithOSDescription() Option {\n\treturn WithDetectors(osDescriptionDetector{})\n}\n\n// WithProcess adds all the Process attributes to the configured Resource.\n//\n// Warning! This option will include process command line arguments. If these\n// contain sensitive information it will be included in the exported resource.\n//\n// This option is equivalent to calling WithProcessPID,\n// WithProcessExecutableName, WithProcessExecutablePath,\n// WithProcessCommandArgs, WithProcessOwner, WithProcessRuntimeName,\n// WithProcessRuntimeVersion, and WithProcessRuntimeDescription. See each\n// option function for information about what resource attributes each\n// includes.\nfunc WithProcess() Option {\n\treturn WithDetectors(\n\t\tprocessPIDDetector{},\n\t\tprocessExecutableNameDetector{},\n\t\tprocessExecutablePathDetector{},\n\t\tprocessCommandArgsDetector{},\n\t\tprocessOwnerDetector{},\n\t\tprocessRuntimeNameDetector{},\n\t\tprocessRuntimeVersionDetector{},\n\t\tprocessRuntimeDescriptionDetector{},\n\t)\n}\n\n// WithProcessPID adds an attribute with the process identifier (PID) to the\n// configured Resource.\nfunc WithProcessPID() Option {\n\treturn WithDetectors(processPIDDetector{})\n}\n\n// WithProcessExecutableName adds an attribute with the name of the process\n// executable to the configured Resource.\nfunc WithProcessExecutableName() Option {\n\treturn WithDetectors(processExecutableNameDetector{})\n}\n\n// WithProcessExecutablePath adds an attribute with the full path to the process\n// executable to the configured Resource.\nfunc WithProcessExecutablePath() Option {\n\treturn WithDetectors(processExecutablePathDetector{})\n}\n\n// WithProcessCommandArgs adds an attribute with all the command arguments (including\n// the command/executable itself) as received by the process to the configured\n// Resource.\n//\n// Warning! This option will include process command line arguments. If these\n// contain sensitive information it will be included in the exported resource.\nfunc WithProcessCommandArgs() Option {\n\treturn WithDetectors(processCommandArgsDetector{})\n}\n\n// WithProcessOwner adds an attribute with the username of the user that owns the process\n// to the configured Resource.\nfunc WithProcessOwner() Option {\n\treturn WithDetectors(processOwnerDetector{})\n}\n\n// WithProcessRuntimeName adds an attribute with the name of the runtime of this\n// process to the configured Resource.\nfunc WithProcessRuntimeName() Option {\n\treturn WithDetectors(processRuntimeNameDetector{})\n}\n\n// WithProcessRuntimeVersion adds an attribute with the version of the runtime of\n// this process to the configured Resource.\nfunc WithProcessRuntimeVersion() Option {\n\treturn WithDetectors(processRuntimeVersionDetector{})\n}\n\n// WithProcessRuntimeDescription adds an attribute with an additional description\n// about the runtime of the process to the configured Resource.\nfunc WithProcessRuntimeDescription() Option {\n\treturn WithDetectors(processRuntimeDescriptionDetector{})\n}\n\n// WithContainer adds all the Container attributes to the configured Resource.\n// See individual WithContainer* functions to configure specific attributes.\nfunc WithContainer() Option {\n\treturn WithDetectors(\n\t\tcgroupContainerIDDetector{},\n\t)\n}\n\n// WithContainerID adds an attribute with the id of the container to the configured Resource.\n// Note: WithContainerID will not extract the correct container ID in an ECS environment.\n// Please use the ECS resource detector instead (https://pkg.go.dev/go.opentelemetry.io/contrib/detectors/aws/ecs).\nfunc WithContainerID() Option {\n\treturn WithDetectors(cgroupContainerIDDetector{})\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/container.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"os\"\n\t\"regexp\"\n\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.39.0\"\n)\n\ntype containerIDProvider func() (string, error)\n\nvar (\n\tcontainerID         containerIDProvider = getContainerIDFromCGroup\n\tcgroupContainerIDRe                     = regexp.MustCompile(`^.*/(?:.*[-:])?([0-9a-f]+)(?:\\.|\\s*$)`)\n)\n\ntype cgroupContainerIDDetector struct{}\n\nconst cgroupPath = \"/proc/self/cgroup\"\n\n// Detect returns a *Resource that describes the id of the container.\n// If no container id found, an empty resource will be returned.\nfunc (cgroupContainerIDDetector) Detect(context.Context) (*Resource, error) {\n\tcontainerID, err := containerID()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif containerID == \"\" {\n\t\treturn Empty(), nil\n\t}\n\treturn NewWithAttributes(semconv.SchemaURL, semconv.ContainerID(containerID)), nil\n}\n\nvar (\n\tdefaultOSStat = os.Stat\n\tosStat        = defaultOSStat\n\n\tdefaultOSOpen = func(name string) (io.ReadCloser, error) {\n\t\treturn os.Open(name)\n\t}\n\tosOpen = defaultOSOpen\n)\n\n// getContainerIDFromCGroup returns the id of the container from the cgroup file.\n// If no container id found, an empty string will be returned.\nfunc getContainerIDFromCGroup() (string, error) {\n\tif _, err := osStat(cgroupPath); errors.Is(err, os.ErrNotExist) {\n\t\t// File does not exist, skip\n\t\treturn \"\", nil\n\t}\n\n\tfile, err := osOpen(cgroupPath)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer file.Close()\n\n\treturn getContainerIDFromReader(file), nil\n}\n\n// getContainerIDFromReader returns the id of the container from reader.\nfunc getContainerIDFromReader(reader io.Reader) string {\n\tscanner := bufio.NewScanner(reader)\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\n\t\tif id := getContainerIDFromLine(line); id != \"\" {\n\t\t\treturn id\n\t\t}\n\t}\n\treturn \"\"\n}\n\n// getContainerIDFromLine returns the id of the container from one string line.\nfunc getContainerIDFromLine(line string) string {\n\tmatches := cgroupContainerIDRe.FindStringSubmatch(line)\n\tif len(matches) <= 1 {\n\t\treturn \"\"\n\t}\n\treturn matches[1]\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package resource provides detecting and representing resources.\n//\n// The fundamental struct is a Resource which holds identifying information\n// about the entities for which telemetry is exported.\n//\n// To automatically construct Resources from an environment a Detector\n// interface is defined. Implementations of this interface can be passed to\n// the Detect function to generate a Resource from the merged information.\n//\n// To load a user defined Resource from the environment variable\n// OTEL_RESOURCE_ATTRIBUTES the FromEnv Detector can be used. It will interpret\n// the value as a list of comma delimited key/value pairs\n// (e.g. `<key1>=<value1>,<key2>=<value2>,...`).\n//\n// While this package provides a stable API,\n// the attributes added by resource detectors may change.\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/env.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"os\"\n\t\"strings\"\n\n\t\"go.opentelemetry.io/otel\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.39.0\"\n)\n\nconst (\n\t// resourceAttrKey is the environment variable name OpenTelemetry Resource information will be read from.\n\tresourceAttrKey = \"OTEL_RESOURCE_ATTRIBUTES\" //nolint:gosec // False positive G101: Potential hardcoded credentials\n\n\t// svcNameKey is the environment variable name that Service Name information will be read from.\n\tsvcNameKey = \"OTEL_SERVICE_NAME\"\n)\n\n// errMissingValue is returned when a resource value is missing.\nvar errMissingValue = fmt.Errorf(\"%w: missing value\", ErrPartialResource)\n\n// fromEnv is a Detector that implements the Detector and collects\n// resources from environment.  This Detector is included as a\n// builtin.\ntype fromEnv struct{}\n\n// compile time assertion that FromEnv implements Detector interface.\nvar _ Detector = fromEnv{}\n\n// Detect collects resources from environment.\nfunc (fromEnv) Detect(context.Context) (*Resource, error) {\n\tattrs := strings.TrimSpace(os.Getenv(resourceAttrKey))\n\tsvcName := strings.TrimSpace(os.Getenv(svcNameKey))\n\n\tif attrs == \"\" && svcName == \"\" {\n\t\treturn Empty(), nil\n\t}\n\n\tvar res *Resource\n\n\tif svcName != \"\" {\n\t\tres = NewSchemaless(semconv.ServiceName(svcName))\n\t}\n\n\tr2, err := constructOTResources(attrs)\n\n\t// Ensure that the resource with the service name from OTEL_SERVICE_NAME\n\t// takes precedence, if it was defined.\n\tres, err2 := Merge(r2, res)\n\n\tif err == nil {\n\t\terr = err2\n\t} else if err2 != nil {\n\t\terr = fmt.Errorf(\"detecting resources: %s\", []string{err.Error(), err2.Error()})\n\t}\n\n\treturn res, err\n}\n\nfunc constructOTResources(s string) (*Resource, error) {\n\tif s == \"\" {\n\t\treturn Empty(), nil\n\t}\n\tpairs := strings.Split(s, \",\")\n\tvar attrs []attribute.KeyValue\n\tvar invalid []string\n\tfor _, p := range pairs {\n\t\tk, v, found := strings.Cut(p, \"=\")\n\t\tif !found {\n\t\t\tinvalid = append(invalid, p)\n\t\t\tcontinue\n\t\t}\n\t\tkey := strings.TrimSpace(k)\n\t\tval, err := url.PathUnescape(strings.TrimSpace(v))\n\t\tif err != nil {\n\t\t\t// Retain original value if decoding fails, otherwise it will be\n\t\t\t// an empty string.\n\t\t\tval = v\n\t\t\totel.Handle(err)\n\t\t}\n\t\tattrs = append(attrs, attribute.String(key, val))\n\t}\n\tvar err error\n\tif len(invalid) > 0 {\n\t\terr = fmt.Errorf(\"%w: %v\", errMissingValue, invalid)\n\t}\n\treturn NewSchemaless(attrs...), err\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/host_id.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"strings\"\n\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.39.0\"\n)\n\ntype hostIDProvider func() (string, error)\n\nvar defaultHostIDProvider hostIDProvider = platformHostIDReader.read\n\nvar hostID = defaultHostIDProvider\n\ntype hostIDReader interface {\n\tread() (string, error)\n}\n\ntype fileReader func(string) (string, error)\n\ntype commandExecutor func(string, ...string) (string, error)\n\n// hostIDReaderBSD implements hostIDReader.\ntype hostIDReaderBSD struct {\n\texecCommand commandExecutor\n\treadFile    fileReader\n}\n\n// read attempts to read the machine-id from /etc/hostid. If not found it will\n// execute `kenv -q smbios.system.uuid`. If neither location yields an id an\n// error will be returned.\nfunc (r *hostIDReaderBSD) read() (string, error) {\n\tif result, err := r.readFile(\"/etc/hostid\"); err == nil {\n\t\treturn strings.TrimSpace(result), nil\n\t}\n\n\tif result, err := r.execCommand(\"kenv\", \"-q\", \"smbios.system.uuid\"); err == nil {\n\t\treturn strings.TrimSpace(result), nil\n\t}\n\n\treturn \"\", errors.New(\"host id not found in: /etc/hostid or kenv\")\n}\n\n// hostIDReaderDarwin implements hostIDReader.\ntype hostIDReaderDarwin struct {\n\texecCommand commandExecutor\n}\n\n// read executes `/usr/sbin/ioreg -rd1 -c \"IOPlatformExpertDevice\"` and parses host id\n// from the IOPlatformUUID line. If the command fails or the uuid cannot be\n// parsed an error will be returned.\nfunc (r *hostIDReaderDarwin) read() (string, error) {\n\tresult, err := r.execCommand(\"/usr/sbin/ioreg\", \"-rd1\", \"-c\", \"IOPlatformExpertDevice\")\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tfor line := range strings.SplitSeq(result, \"\\n\") {\n\t\tif strings.Contains(line, \"IOPlatformUUID\") {\n\t\t\tparts := strings.Split(line, \" = \")\n\t\t\tif len(parts) == 2 {\n\t\t\t\treturn strings.Trim(parts[1], \"\\\"\"), nil\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn \"\", errors.New(\"could not parse IOPlatformUUID\")\n}\n\ntype hostIDReaderLinux struct {\n\treadFile fileReader\n}\n\n// read attempts to read the machine-id from /etc/machine-id followed by\n// /var/lib/dbus/machine-id. If neither location yields an ID an error will\n// be returned.\nfunc (r *hostIDReaderLinux) read() (string, error) {\n\tif result, err := r.readFile(\"/etc/machine-id\"); err == nil {\n\t\treturn strings.TrimSpace(result), nil\n\t}\n\n\tif result, err := r.readFile(\"/var/lib/dbus/machine-id\"); err == nil {\n\t\treturn strings.TrimSpace(result), nil\n\t}\n\n\treturn \"\", errors.New(\"host id not found in: /etc/machine-id or /var/lib/dbus/machine-id\")\n}\n\ntype hostIDDetector struct{}\n\n// Detect returns a *Resource containing the platform specific host id.\nfunc (hostIDDetector) Detect(context.Context) (*Resource, error) {\n\thostID, err := hostID()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn NewWithAttributes(\n\t\tsemconv.SchemaURL,\n\t\tsemconv.HostID(hostID),\n\t), nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/host_id_bsd.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n//go:build dragonfly || freebsd || netbsd || openbsd || solaris\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nvar platformHostIDReader hostIDReader = &hostIDReaderBSD{\n\texecCommand: execCommand,\n\treadFile:    readFile,\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/host_id_darwin.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nvar platformHostIDReader hostIDReader = &hostIDReaderDarwin{\n\texecCommand: execCommand,\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/host_id_exec.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n//go:build darwin || dragonfly || freebsd || netbsd || openbsd || solaris\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nimport \"os/exec\"\n\nfunc execCommand(name string, arg ...string) (string, error) {\n\tcmd := exec.Command(name, arg...)\n\tb, err := cmd.Output()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn string(b), nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/host_id_linux.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n//go:build linux\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nvar platformHostIDReader hostIDReader = &hostIDReaderLinux{\n\treadFile: readFile,\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/host_id_readfile.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n//go:build linux || dragonfly || freebsd || netbsd || openbsd || solaris\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nimport \"os\"\n\nfunc readFile(filename string) (string, error) {\n\tb, err := os.ReadFile(filename)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn string(b), nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/host_id_unsupported.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n//go:build !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\n// hostIDReaderUnsupported is a placeholder implementation for operating systems\n// for which this project currently doesn't support host.id\n// attribute detection. See build tags declaration early on this file\n// for a list of unsupported OSes.\ntype hostIDReaderUnsupported struct{}\n\nfunc (*hostIDReaderUnsupported) read() (string, error) {\n\treturn \"<unknown>\", nil\n}\n\nvar platformHostIDReader hostIDReader = &hostIDReaderUnsupported{}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/host_id_windows.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n//go:build windows\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nimport (\n\t\"golang.org/x/sys/windows/registry\"\n)\n\n// implements hostIDReader.\ntype hostIDReaderWindows struct{}\n\n// read reads MachineGuid from the Windows registry key:\n// SOFTWARE\\Microsoft\\Cryptography.\nfunc (*hostIDReaderWindows) read() (string, error) {\n\tk, err := registry.OpenKey(\n\t\tregistry.LOCAL_MACHINE, `SOFTWARE\\Microsoft\\Cryptography`,\n\t\tregistry.QUERY_VALUE|registry.WOW64_64KEY,\n\t)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer k.Close()\n\n\tguid, _, err := k.GetStringValue(\"MachineGuid\")\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn guid, nil\n}\n\nvar platformHostIDReader hostIDReader = &hostIDReaderWindows{}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/os.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nimport (\n\t\"context\"\n\t\"strings\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.39.0\"\n)\n\ntype osDescriptionProvider func() (string, error)\n\nvar defaultOSDescriptionProvider osDescriptionProvider = platformOSDescription\n\nvar osDescription = defaultOSDescriptionProvider\n\nfunc setDefaultOSDescriptionProvider() {\n\tsetOSDescriptionProvider(defaultOSDescriptionProvider)\n}\n\nfunc setOSDescriptionProvider(osDescriptionProvider osDescriptionProvider) {\n\tosDescription = osDescriptionProvider\n}\n\ntype (\n\tosTypeDetector        struct{}\n\tosDescriptionDetector struct{}\n)\n\n// Detect returns a *Resource that describes the operating system type the\n// service is running on.\nfunc (osTypeDetector) Detect(context.Context) (*Resource, error) {\n\tosType := runtimeOS()\n\n\tosTypeAttribute := mapRuntimeOSToSemconvOSType(osType)\n\n\treturn NewWithAttributes(\n\t\tsemconv.SchemaURL,\n\t\tosTypeAttribute,\n\t), nil\n}\n\n// Detect returns a *Resource that describes the operating system the\n// service is running on.\nfunc (osDescriptionDetector) Detect(context.Context) (*Resource, error) {\n\tdescription, err := osDescription()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn NewWithAttributes(\n\t\tsemconv.SchemaURL,\n\t\tsemconv.OSDescription(description),\n\t), nil\n}\n\n// mapRuntimeOSToSemconvOSType translates the OS name as provided by the Go runtime\n// into an OS type attribute with the corresponding value defined by the semantic\n// conventions. In case the provided OS name isn't mapped, it's transformed to lowercase\n// and used as the value for the returned OS type attribute.\nfunc mapRuntimeOSToSemconvOSType(osType string) attribute.KeyValue {\n\t// the elements in this map are the intersection between\n\t// available GOOS values and defined semconv OS types\n\tosTypeAttributeMap := map[string]attribute.KeyValue{\n\t\t\"aix\":       semconv.OSTypeAIX,\n\t\t\"darwin\":    semconv.OSTypeDarwin,\n\t\t\"dragonfly\": semconv.OSTypeDragonflyBSD,\n\t\t\"freebsd\":   semconv.OSTypeFreeBSD,\n\t\t\"linux\":     semconv.OSTypeLinux,\n\t\t\"netbsd\":    semconv.OSTypeNetBSD,\n\t\t\"openbsd\":   semconv.OSTypeOpenBSD,\n\t\t\"solaris\":   semconv.OSTypeSolaris,\n\t\t\"windows\":   semconv.OSTypeWindows,\n\t\t\"zos\":       semconv.OSTypeZOS,\n\t}\n\n\tvar osTypeAttribute attribute.KeyValue\n\n\tif attr, ok := osTypeAttributeMap[osType]; ok {\n\t\tosTypeAttribute = attr\n\t} else {\n\t\tosTypeAttribute = semconv.OSTypeKey.String(strings.ToLower(osType))\n\t}\n\n\treturn osTypeAttribute\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/os_release_darwin.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nimport (\n\t\"encoding/xml\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n)\n\ntype plist struct {\n\tXMLName xml.Name `xml:\"plist\"`\n\tDict    dict     `xml:\"dict\"`\n}\n\ntype dict struct {\n\tKey    []string `xml:\"key\"`\n\tString []string `xml:\"string\"`\n}\n\n// osRelease builds a string describing the operating system release based on the\n// contents of the property list (.plist) system files. If no .plist files are found,\n// or if the required properties to build the release description string are missing,\n// an empty string is returned instead. The generated string resembles the output of\n// the `sw_vers` commandline program, but in a single-line string. For more information\n// about the `sw_vers` program, see: https://www.unix.com/man-page/osx/1/SW_VERS.\nfunc osRelease() string {\n\tfile, err := getPlistFile()\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\n\tdefer file.Close()\n\n\tvalues, err := parsePlistFile(file)\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\n\treturn buildOSRelease(values)\n}\n\n// getPlistFile returns a *os.File pointing to one of the well-known .plist files\n// available on macOS. If no file can be opened, it returns an error.\nfunc getPlistFile() (*os.File, error) {\n\treturn getFirstAvailableFile([]string{\n\t\t\"/System/Library/CoreServices/SystemVersion.plist\",\n\t\t\"/System/Library/CoreServices/ServerVersion.plist\",\n\t})\n}\n\n// parsePlistFile process the file pointed by `file` as a .plist file and returns\n// a map with the key-values for each pair of correlated <key> and <string> elements\n// contained in it.\nfunc parsePlistFile(file io.Reader) (map[string]string, error) {\n\tvar v plist\n\n\terr := xml.NewDecoder(file).Decode(&v)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif len(v.Dict.Key) != len(v.Dict.String) {\n\t\treturn nil, errors.New(\"the number of <key> and <string> elements doesn't match\")\n\t}\n\n\tproperties := make(map[string]string, len(v.Dict.Key))\n\tfor i, key := range v.Dict.Key {\n\t\tproperties[key] = v.Dict.String[i]\n\t}\n\n\treturn properties, nil\n}\n\n// buildOSRelease builds a string describing the OS release based on the properties\n// available on the provided map. It tries to find the `ProductName`, `ProductVersion`\n// and `ProductBuildVersion` properties. If some of these properties are not found,\n// it returns an empty string.\nfunc buildOSRelease(properties map[string]string) string {\n\tproductName := properties[\"ProductName\"]\n\tproductVersion := properties[\"ProductVersion\"]\n\tproductBuildVersion := properties[\"ProductBuildVersion\"]\n\n\tif productName == \"\" || productVersion == \"\" || productBuildVersion == \"\" {\n\t\treturn \"\"\n\t}\n\n\treturn fmt.Sprintf(\"%s %s (%s)\", productName, productVersion, productBuildVersion)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/os_release_unix.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n//go:build aix || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n)\n\n// osRelease builds a string describing the operating system release based on the\n// properties of the os-release file. If no os-release file is found, or if the\n// required properties to build the release description string are missing, an empty\n// string is returned instead. For more information about os-release files, see:\n// https://www.freedesktop.org/software/systemd/man/os-release.html\nfunc osRelease() string {\n\tfile, err := getOSReleaseFile()\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\n\tdefer file.Close()\n\n\tvalues := parseOSReleaseFile(file)\n\n\treturn buildOSRelease(values)\n}\n\n// getOSReleaseFile returns a *os.File pointing to one of the well-known os-release\n// files, according to their order of preference. If no file can be opened, it\n// returns an error.\nfunc getOSReleaseFile() (*os.File, error) {\n\treturn getFirstAvailableFile([]string{\"/etc/os-release\", \"/usr/lib/os-release\"})\n}\n\n// parseOSReleaseFile process the file pointed by `file` as an os-release file and\n// returns a map with the key-values contained in it. Empty lines or lines starting\n// with a '#' character are ignored, as well as lines with the missing key=value\n// separator. Values are unquoted and unescaped.\nfunc parseOSReleaseFile(file io.Reader) map[string]string {\n\tvalues := make(map[string]string)\n\tscanner := bufio.NewScanner(file)\n\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\n\t\tif skip(line) {\n\t\t\tcontinue\n\t\t}\n\n\t\tkey, value, ok := parse(line)\n\t\tif ok {\n\t\t\tvalues[key] = value\n\t\t}\n\t}\n\n\treturn values\n}\n\n// skip reports whether the line is blank or starts with a '#' character, and\n// therefore should be skipped from processing.\nfunc skip(line string) bool {\n\tline = strings.TrimSpace(line)\n\n\treturn line == \"\" || strings.HasPrefix(line, \"#\")\n}\n\n// parse attempts to split the provided line on the first '=' character, and then\n// sanitize each side of the split before returning them as a key-value pair.\nfunc parse(line string) (string, string, bool) {\n\tk, v, found := strings.Cut(line, \"=\")\n\n\tif !found || k == \"\" {\n\t\treturn \"\", \"\", false\n\t}\n\n\tkey := strings.TrimSpace(k)\n\tvalue := unescape(unquote(strings.TrimSpace(v)))\n\n\treturn key, value, true\n}\n\n// unquote checks whether the string `s` is quoted with double or single quotes\n// and, if so, returns a version of the string without them. Otherwise it returns\n// the provided string unchanged.\nfunc unquote(s string) string {\n\tif len(s) < 2 {\n\t\treturn s\n\t}\n\n\tif (s[0] == '\"' || s[0] == '\\'') && s[0] == s[len(s)-1] {\n\t\treturn s[1 : len(s)-1]\n\t}\n\n\treturn s\n}\n\n// unescape removes the `\\` prefix from some characters that are expected\n// to have it added in front of them for escaping purposes.\nfunc unescape(s string) string {\n\treturn strings.NewReplacer(\n\t\t`\\$`, `$`,\n\t\t`\\\"`, `\"`,\n\t\t`\\'`, `'`,\n\t\t`\\\\`, `\\`,\n\t\t\"\\\\`\", \"`\",\n\t).Replace(s)\n}\n\n// buildOSRelease builds a string describing the OS release based on the properties\n// available on the provided map. It favors a combination of the `NAME` and `VERSION`\n// properties as first option (falling back to `VERSION_ID` if `VERSION` isn't\n// found), and using `PRETTY_NAME` alone if some of the previous are not present. If\n// none of these properties are found, it returns an empty string.\n//\n// The rationale behind not using `PRETTY_NAME` as first choice was that, for some\n// Linux distributions, it doesn't include the same detail that can be found on the\n// individual `NAME` and `VERSION` properties, and combining `PRETTY_NAME` with\n// other properties can produce \"pretty\" redundant strings in some cases.\nfunc buildOSRelease(values map[string]string) string {\n\tvar osRelease string\n\n\tname := values[\"NAME\"]\n\tversion := values[\"VERSION\"]\n\n\tif version == \"\" {\n\t\tversion = values[\"VERSION_ID\"]\n\t}\n\n\tif name != \"\" && version != \"\" {\n\t\tosRelease = fmt.Sprintf(\"%s %s\", name, version)\n\t} else {\n\t\tosRelease = values[\"PRETTY_NAME\"]\n\t}\n\n\treturn osRelease\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/os_unix.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\ntype unameProvider func(buf *unix.Utsname) (err error)\n\nvar defaultUnameProvider unameProvider = unix.Uname\n\nvar currentUnameProvider = defaultUnameProvider\n\nfunc setDefaultUnameProvider() {\n\tsetUnameProvider(defaultUnameProvider)\n}\n\nfunc setUnameProvider(unameProvider unameProvider) {\n\tcurrentUnameProvider = unameProvider\n}\n\n// platformOSDescription returns a human readable OS version information string.\n// The final string combines OS release information (where available) and the\n// result of the `uname` system call.\nfunc platformOSDescription() (string, error) {\n\tuname, err := uname()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tosRelease := osRelease()\n\tif osRelease != \"\" {\n\t\treturn fmt.Sprintf(\"%s (%s)\", osRelease, uname), nil\n\t}\n\n\treturn uname, nil\n}\n\n// uname issues a uname(2) system call (or equivalent on systems which doesn't\n// have one) and formats the output in a single string, similar to the output\n// of the `uname` commandline program. The final string resembles the one\n// obtained with a call to `uname -snrvm`.\nfunc uname() (string, error) {\n\tvar utsName unix.Utsname\n\n\terr := currentUnameProvider(&utsName)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn fmt.Sprintf(\"%s %s %s %s %s\",\n\t\tunix.ByteSliceToString(utsName.Sysname[:]),\n\t\tunix.ByteSliceToString(utsName.Nodename[:]),\n\t\tunix.ByteSliceToString(utsName.Release[:]),\n\t\tunix.ByteSliceToString(utsName.Version[:]),\n\t\tunix.ByteSliceToString(utsName.Machine[:]),\n\t), nil\n}\n\n// getFirstAvailableFile returns an *os.File of the first available\n// file from a list of candidate file paths.\nfunc getFirstAvailableFile(candidates []string) (*os.File, error) {\n\tfor _, c := range candidates {\n\t\tfile, err := os.Open(c)\n\t\tif err == nil {\n\t\t\treturn file, nil\n\t\t}\n\t}\n\n\treturn nil, fmt.Errorf(\"no candidate file available: %v\", candidates)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/os_unsupported.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\n// platformOSDescription is a placeholder implementation for OSes\n// for which this project currently doesn't support os.description\n// attribute detection. See build tags declaration early on this file\n// for a list of unsupported OSes.\nfunc platformOSDescription() (string, error) {\n\treturn \"<unknown>\", nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/os_windows.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\n\t\"golang.org/x/sys/windows/registry\"\n)\n\n// platformOSDescription returns a human readable OS version information string.\n// It does so by querying registry values under the\n// `SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion` key. The final string\n// resembles the one displayed by the Version Reporter Applet (winver.exe).\nfunc platformOSDescription() (string, error) {\n\tk, err := registry.OpenKey(\n\t\tregistry.LOCAL_MACHINE, `SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion`, registry.QUERY_VALUE)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tdefer k.Close()\n\n\tvar (\n\t\tproductName               = readProductName(k)\n\t\tdisplayVersion            = readDisplayVersion(k)\n\t\treleaseID                 = readReleaseID(k)\n\t\tcurrentMajorVersionNumber = readCurrentMajorVersionNumber(k)\n\t\tcurrentMinorVersionNumber = readCurrentMinorVersionNumber(k)\n\t\tcurrentBuildNumber        = readCurrentBuildNumber(k)\n\t\tubr                       = readUBR(k)\n\t)\n\n\tif displayVersion != \"\" {\n\t\tdisplayVersion += \" \"\n\t}\n\n\treturn fmt.Sprintf(\"%s %s(%s) [Version %s.%s.%s.%s]\",\n\t\tproductName,\n\t\tdisplayVersion,\n\t\treleaseID,\n\t\tcurrentMajorVersionNumber,\n\t\tcurrentMinorVersionNumber,\n\t\tcurrentBuildNumber,\n\t\tubr,\n\t), nil\n}\n\nfunc getStringValue(name string, k registry.Key) string {\n\tvalue, _, _ := k.GetStringValue(name)\n\n\treturn value\n}\n\nfunc getIntegerValue(name string, k registry.Key) uint64 {\n\tvalue, _, _ := k.GetIntegerValue(name)\n\n\treturn value\n}\n\nfunc readProductName(k registry.Key) string {\n\treturn getStringValue(\"ProductName\", k)\n}\n\nfunc readDisplayVersion(k registry.Key) string {\n\treturn getStringValue(\"DisplayVersion\", k)\n}\n\nfunc readReleaseID(k registry.Key) string {\n\treturn getStringValue(\"ReleaseID\", k)\n}\n\nfunc readCurrentMajorVersionNumber(k registry.Key) string {\n\treturn strconv.FormatUint(getIntegerValue(\"CurrentMajorVersionNumber\", k), 10)\n}\n\nfunc readCurrentMinorVersionNumber(k registry.Key) string {\n\treturn strconv.FormatUint(getIntegerValue(\"CurrentMinorVersionNumber\", k), 10)\n}\n\nfunc readCurrentBuildNumber(k registry.Key) string {\n\treturn getStringValue(\"CurrentBuildNumber\", k)\n}\n\nfunc readUBR(k registry.Key) string {\n\treturn strconv.FormatUint(getIntegerValue(\"UBR\", k), 10)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/process.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/user\"\n\t\"path/filepath\"\n\t\"runtime\"\n\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.39.0\"\n)\n\ntype (\n\tpidProvider            func() int\n\texecutablePathProvider func() (string, error)\n\tcommandArgsProvider    func() []string\n\townerProvider          func() (*user.User, error)\n\truntimeNameProvider    func() string\n\truntimeVersionProvider func() string\n\truntimeOSProvider      func() string\n\truntimeArchProvider    func() string\n)\n\nvar (\n\tdefaultPidProvider            pidProvider            = os.Getpid\n\tdefaultExecutablePathProvider executablePathProvider = os.Executable\n\tdefaultCommandArgsProvider    commandArgsProvider    = func() []string { return os.Args }\n\tdefaultOwnerProvider          ownerProvider          = user.Current\n\tdefaultRuntimeNameProvider    runtimeNameProvider    = func() string {\n\t\tif runtime.Compiler == \"gc\" {\n\t\t\treturn \"go\"\n\t\t}\n\t\treturn runtime.Compiler\n\t}\n\tdefaultRuntimeVersionProvider runtimeVersionProvider = runtime.Version\n\tdefaultRuntimeOSProvider      runtimeOSProvider      = func() string { return runtime.GOOS }\n\tdefaultRuntimeArchProvider    runtimeArchProvider    = func() string { return runtime.GOARCH }\n)\n\nvar (\n\tpid            = defaultPidProvider\n\texecutablePath = defaultExecutablePathProvider\n\tcommandArgs    = defaultCommandArgsProvider\n\towner          = defaultOwnerProvider\n\truntimeName    = defaultRuntimeNameProvider\n\truntimeVersion = defaultRuntimeVersionProvider\n\truntimeOS      = defaultRuntimeOSProvider\n\truntimeArch    = defaultRuntimeArchProvider\n)\n\nfunc setDefaultOSProviders() {\n\tsetOSProviders(\n\t\tdefaultPidProvider,\n\t\tdefaultExecutablePathProvider,\n\t\tdefaultCommandArgsProvider,\n\t)\n}\n\nfunc setOSProviders(\n\tpidProvider pidProvider,\n\texecutablePathProvider executablePathProvider,\n\tcommandArgsProvider commandArgsProvider,\n) {\n\tpid = pidProvider\n\texecutablePath = executablePathProvider\n\tcommandArgs = commandArgsProvider\n}\n\nfunc setDefaultRuntimeProviders() {\n\tsetRuntimeProviders(\n\t\tdefaultRuntimeNameProvider,\n\t\tdefaultRuntimeVersionProvider,\n\t\tdefaultRuntimeOSProvider,\n\t\tdefaultRuntimeArchProvider,\n\t)\n}\n\nfunc setRuntimeProviders(\n\truntimeNameProvider runtimeNameProvider,\n\truntimeVersionProvider runtimeVersionProvider,\n\truntimeOSProvider runtimeOSProvider,\n\truntimeArchProvider runtimeArchProvider,\n) {\n\truntimeName = runtimeNameProvider\n\truntimeVersion = runtimeVersionProvider\n\truntimeOS = runtimeOSProvider\n\truntimeArch = runtimeArchProvider\n}\n\nfunc setDefaultUserProviders() {\n\tsetUserProviders(defaultOwnerProvider)\n}\n\nfunc setUserProviders(ownerProvider ownerProvider) {\n\towner = ownerProvider\n}\n\ntype (\n\tprocessPIDDetector                struct{}\n\tprocessExecutableNameDetector     struct{}\n\tprocessExecutablePathDetector     struct{}\n\tprocessCommandArgsDetector        struct{}\n\tprocessOwnerDetector              struct{}\n\tprocessRuntimeNameDetector        struct{}\n\tprocessRuntimeVersionDetector     struct{}\n\tprocessRuntimeDescriptionDetector struct{}\n)\n\n// Detect returns a *Resource that describes the process identifier (PID) of the\n// executing process.\nfunc (processPIDDetector) Detect(context.Context) (*Resource, error) {\n\treturn NewWithAttributes(semconv.SchemaURL, semconv.ProcessPID(pid())), nil\n}\n\n// Detect returns a *Resource that describes the name of the process executable.\nfunc (processExecutableNameDetector) Detect(context.Context) (*Resource, error) {\n\texecutableName := filepath.Base(commandArgs()[0])\n\n\treturn NewWithAttributes(semconv.SchemaURL, semconv.ProcessExecutableName(executableName)), nil\n}\n\n// Detect returns a *Resource that describes the full path of the process executable.\nfunc (processExecutablePathDetector) Detect(context.Context) (*Resource, error) {\n\texecutablePath, err := executablePath()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn NewWithAttributes(semconv.SchemaURL, semconv.ProcessExecutablePath(executablePath)), nil\n}\n\n// Detect returns a *Resource that describes all the command arguments as received\n// by the process.\nfunc (processCommandArgsDetector) Detect(context.Context) (*Resource, error) {\n\treturn NewWithAttributes(semconv.SchemaURL, semconv.ProcessCommandArgs(commandArgs()...)), nil\n}\n\n// Detect returns a *Resource that describes the username of the user that owns the\n// process.\nfunc (processOwnerDetector) Detect(context.Context) (*Resource, error) {\n\towner, err := owner()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn NewWithAttributes(semconv.SchemaURL, semconv.ProcessOwner(owner.Username)), nil\n}\n\n// Detect returns a *Resource that describes the name of the compiler used to compile\n// this process image.\nfunc (processRuntimeNameDetector) Detect(context.Context) (*Resource, error) {\n\treturn NewWithAttributes(semconv.SchemaURL, semconv.ProcessRuntimeName(runtimeName())), nil\n}\n\n// Detect returns a *Resource that describes the version of the runtime of this process.\nfunc (processRuntimeVersionDetector) Detect(context.Context) (*Resource, error) {\n\treturn NewWithAttributes(semconv.SchemaURL, semconv.ProcessRuntimeVersion(runtimeVersion())), nil\n}\n\n// Detect returns a *Resource that describes the runtime of this process.\nfunc (processRuntimeDescriptionDetector) Detect(context.Context) (*Resource, error) {\n\truntimeDescription := fmt.Sprintf(\n\t\t\"go version %s %s/%s\", runtimeVersion(), runtimeOS(), runtimeArch())\n\n\treturn NewWithAttributes(\n\t\tsemconv.SchemaURL,\n\t\tsemconv.ProcessRuntimeDescription(runtimeDescription),\n\t), nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/resource/resource.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage resource // import \"go.opentelemetry.io/otel/sdk/resource\"\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\n\t\"go.opentelemetry.io/otel\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/sdk/internal/x\"\n)\n\n// Resource describes an entity about which identifying information\n// and metadata is exposed.  Resource is an immutable object,\n// equivalent to a map from key to unique value.\n//\n// Resources should be passed and stored as pointers\n// (`*resource.Resource`).  The `nil` value is equivalent to an empty\n// Resource.\n//\n// Note that the Go == operator compares not just the resource attributes but\n// also all other internals of the Resource type. Therefore, Resource values\n// should not be used as map or database keys. In general, the [Resource.Equal]\n// method should be used instead of direct comparison with ==, since that\n// method ensures the correct comparison of resource attributes, and the\n// [attribute.Distinct] returned from [Resource.Equivalent] should be used for\n// map and database keys instead.\ntype Resource struct {\n\tattrs     attribute.Set\n\tschemaURL string\n}\n\n// Compile-time check that the Resource remains comparable.\nvar _ map[Resource]struct{} = nil\n\nvar (\n\tdefaultResource     *Resource\n\tdefaultResourceOnce sync.Once\n)\n\n// ErrSchemaURLConflict is an error returned when two Resources are merged\n// together that contain different, non-empty, schema URLs.\nvar ErrSchemaURLConflict = errors.New(\"conflicting Schema URL\")\n\n// New returns a [Resource] built using opts.\n//\n// This may return a partial Resource along with an error containing\n// [ErrPartialResource] if options that provide a [Detector] are used and that\n// error is returned from one or more of the Detectors. It may also return a\n// merge-conflict Resource along with an error containing\n// [ErrSchemaURLConflict] if merging Resources from the opts results in a\n// schema URL conflict (see [Resource.Merge] for more information). It is up to\n// the caller to determine if this returned Resource should be used or not\n// based on these errors.\nfunc New(ctx context.Context, opts ...Option) (*Resource, error) {\n\tcfg := config{}\n\tfor _, opt := range opts {\n\t\tcfg = opt.apply(cfg)\n\t}\n\n\tr := &Resource{schemaURL: cfg.schemaURL}\n\treturn r, detect(ctx, r, cfg.detectors)\n}\n\n// NewWithAttributes creates a resource from attrs and associates the resource with a\n// schema URL. If attrs contains duplicate keys, the last value will be used. If attrs\n// contains any invalid items those items will be dropped. The attrs are assumed to be\n// in a schema identified by schemaURL.\nfunc NewWithAttributes(schemaURL string, attrs ...attribute.KeyValue) *Resource {\n\tresource := NewSchemaless(attrs...)\n\tresource.schemaURL = schemaURL\n\treturn resource\n}\n\n// NewSchemaless creates a resource from attrs. If attrs contains duplicate keys,\n// the last value will be used. If attrs contains any invalid items those items will\n// be dropped. The resource will not be associated with a schema URL. If the schema\n// of the attrs is known use NewWithAttributes instead.\nfunc NewSchemaless(attrs ...attribute.KeyValue) *Resource {\n\tif len(attrs) == 0 {\n\t\treturn &Resource{}\n\t}\n\n\t// Ensure attributes comply with the specification:\n\t// https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/common/README.md#attribute\n\ts, _ := attribute.NewSetWithFiltered(attrs, func(kv attribute.KeyValue) bool {\n\t\treturn kv.Valid()\n\t})\n\n\t// If attrs only contains invalid entries do not allocate a new resource.\n\tif s.Len() == 0 {\n\t\treturn &Resource{}\n\t}\n\n\treturn &Resource{attrs: s} //nolint\n}\n\n// String implements the Stringer interface and provides a\n// human-readable form of the resource.\n//\n// Avoid using this representation as the key in a map of resources,\n// use Equivalent() as the key instead.\nfunc (r *Resource) String() string {\n\tif r == nil {\n\t\treturn \"\"\n\t}\n\treturn r.attrs.Encoded(attribute.DefaultEncoder())\n}\n\n// MarshalLog is the marshaling function used by the logging system to represent this Resource.\nfunc (r *Resource) MarshalLog() any {\n\treturn struct {\n\t\tAttributes attribute.Set\n\t\tSchemaURL  string\n\t}{\n\t\tAttributes: r.attrs,\n\t\tSchemaURL:  r.schemaURL,\n\t}\n}\n\n// Attributes returns a copy of attributes from the resource in a sorted order.\n// To avoid allocating a new slice, use an iterator.\nfunc (r *Resource) Attributes() []attribute.KeyValue {\n\tif r == nil {\n\t\tr = Empty()\n\t}\n\treturn r.attrs.ToSlice()\n}\n\n// SchemaURL returns the schema URL associated with Resource r.\nfunc (r *Resource) SchemaURL() string {\n\tif r == nil {\n\t\treturn \"\"\n\t}\n\treturn r.schemaURL\n}\n\n// Iter returns an iterator of the Resource attributes.\n// This is ideal to use if you do not want a copy of the attributes.\nfunc (r *Resource) Iter() attribute.Iterator {\n\tif r == nil {\n\t\tr = Empty()\n\t}\n\treturn r.attrs.Iter()\n}\n\n// Equal reports whether r and o represent the same resource. Two resources can\n// be equal even if they have different schema URLs.\n//\n// See the documentation on the [Resource] type for the pitfalls of using ==\n// with Resource values; most code should use Equal instead.\nfunc (r *Resource) Equal(o *Resource) bool {\n\tif r == nil {\n\t\tr = Empty()\n\t}\n\tif o == nil {\n\t\to = Empty()\n\t}\n\treturn r.Equivalent() == o.Equivalent()\n}\n\n// Merge creates a new [Resource] by merging a and b.\n//\n// If there are common keys between a and b, then the value from b will\n// overwrite the value from a, even if b's value is empty.\n//\n// The SchemaURL of the resources will be merged according to the\n// [OpenTelemetry specification rules]:\n//\n//   - If a's schema URL is empty then the returned Resource's schema URL will\n//     be set to the schema URL of b,\n//   - Else if b's schema URL is empty then the returned Resource's schema URL\n//     will be set to the schema URL of a,\n//   - Else if the schema URLs of a and b are the same then that will be the\n//     schema URL of the returned Resource,\n//   - Else this is a merging error. If the resources have different,\n//     non-empty, schema URLs an error containing [ErrSchemaURLConflict] will\n//     be returned with the merged Resource. The merged Resource will have an\n//     empty schema URL. It may be the case that some unintended attributes\n//     have been overwritten or old semantic conventions persisted in the\n//     returned Resource. It is up to the caller to determine if this returned\n//     Resource should be used or not.\n//\n// [OpenTelemetry specification rules]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/resource/sdk.md#merge\nfunc Merge(a, b *Resource) (*Resource, error) {\n\tif a == nil && b == nil {\n\t\treturn Empty(), nil\n\t}\n\tif a == nil {\n\t\treturn b, nil\n\t}\n\tif b == nil {\n\t\treturn a, nil\n\t}\n\n\t// Note: 'b' attributes will overwrite 'a' with last-value-wins in attribute.Key()\n\t// Meaning this is equivalent to: append(a.Attributes(), b.Attributes()...)\n\tmi := attribute.NewMergeIterator(b.Set(), a.Set())\n\tcombine := make([]attribute.KeyValue, 0, a.Len()+b.Len())\n\tfor mi.Next() {\n\t\tcombine = append(combine, mi.Attribute())\n\t}\n\n\tswitch {\n\tcase a.schemaURL == \"\":\n\t\treturn NewWithAttributes(b.schemaURL, combine...), nil\n\tcase b.schemaURL == \"\":\n\t\treturn NewWithAttributes(a.schemaURL, combine...), nil\n\tcase a.schemaURL == b.schemaURL:\n\t\treturn NewWithAttributes(a.schemaURL, combine...), nil\n\t}\n\t// Return the merged resource with an appropriate error. It is up to\n\t// the user to decide if the returned resource can be used or not.\n\treturn NewSchemaless(combine...), fmt.Errorf(\n\t\t\"%w: %s and %s\",\n\t\tErrSchemaURLConflict,\n\t\ta.schemaURL,\n\t\tb.schemaURL,\n\t)\n}\n\n// Empty returns an instance of Resource with no attributes. It is\n// equivalent to a `nil` Resource.\nfunc Empty() *Resource {\n\treturn &Resource{}\n}\n\n// Default returns an instance of Resource with a default\n// \"service.name\" and OpenTelemetrySDK attributes.\nfunc Default() *Resource {\n\tdefaultResourceOnce.Do(func() {\n\t\tvar err error\n\t\tdefaultDetectors := []Detector{\n\t\t\tdefaultServiceNameDetector{},\n\t\t\tfromEnv{},\n\t\t\ttelemetrySDK{},\n\t\t}\n\t\tif x.Resource.Enabled() {\n\t\t\tdefaultDetectors = append([]Detector{defaultServiceInstanceIDDetector{}}, defaultDetectors...)\n\t\t}\n\t\tdefaultResource, err = Detect(\n\t\t\tcontext.Background(),\n\t\t\tdefaultDetectors...,\n\t\t)\n\t\tif err != nil {\n\t\t\totel.Handle(err)\n\t\t}\n\t\t// If Detect did not return a valid resource, fall back to emptyResource.\n\t\tif defaultResource == nil {\n\t\t\tdefaultResource = &Resource{}\n\t\t}\n\t})\n\treturn defaultResource\n}\n\n// Environment returns an instance of Resource with attributes\n// extracted from the OTEL_RESOURCE_ATTRIBUTES environment variable.\nfunc Environment() *Resource {\n\tdetector := &fromEnv{}\n\tresource, err := detector.Detect(context.Background())\n\tif err != nil {\n\t\totel.Handle(err)\n\t}\n\treturn resource\n}\n\n// Equivalent returns an object that can be compared for equality\n// between two resources. This value is suitable for use as a key in\n// a map.\nfunc (r *Resource) Equivalent() attribute.Distinct {\n\treturn r.Set().Equivalent()\n}\n\n// Set returns the equivalent *attribute.Set of this resource's attributes.\nfunc (r *Resource) Set() *attribute.Set {\n\tif r == nil {\n\t\tr = Empty()\n\t}\n\treturn &r.attrs\n}\n\n// MarshalJSON encodes the resource attributes as a JSON list of { \"Key\":\n// \"...\", \"Value\": ... } pairs in order sorted by key.\nfunc (r *Resource) MarshalJSON() ([]byte, error) {\n\tif r == nil {\n\t\tr = Empty()\n\t}\n\treturn r.attrs.MarshalJSON()\n}\n\n// Len returns the number of unique key-values in this Resource.\nfunc (r *Resource) Len() int {\n\tif r == nil {\n\t\treturn 0\n\t}\n\treturn r.attrs.Len()\n}\n\n// Encoded returns an encoded representation of the resource.\nfunc (r *Resource) Encoded(enc attribute.Encoder) string {\n\tif r == nil {\n\t\treturn \"\"\n\t}\n\treturn r.attrs.Encoded(enc)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/README.md",
    "content": "# SDK Trace\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/sdk/trace)](https://pkg.go.dev/go.opentelemetry.io/otel/sdk/trace)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/sdk/trace\"\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"go.opentelemetry.io/otel\"\n\t\"go.opentelemetry.io/otel/internal/global\"\n\t\"go.opentelemetry.io/otel/sdk/trace/internal/env\"\n\t\"go.opentelemetry.io/otel/sdk/trace/internal/observ\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\n// Defaults for BatchSpanProcessorOptions.\nconst (\n\tDefaultMaxQueueSize = 2048\n\t// DefaultScheduleDelay is the delay interval between two consecutive exports, in milliseconds.\n\tDefaultScheduleDelay = 5000\n\t// DefaultExportTimeout is the duration after which an export is cancelled, in milliseconds.\n\tDefaultExportTimeout      = 30000\n\tDefaultMaxExportBatchSize = 512\n)\n\n// BatchSpanProcessorOption configures a BatchSpanProcessor.\ntype BatchSpanProcessorOption func(o *BatchSpanProcessorOptions)\n\n// BatchSpanProcessorOptions is configuration settings for a\n// BatchSpanProcessor.\ntype BatchSpanProcessorOptions struct {\n\t// MaxQueueSize is the maximum queue size to buffer spans for delayed processing. If the\n\t// queue gets full it drops the spans. Use BlockOnQueueFull to change this behavior.\n\t// The default value of MaxQueueSize is 2048.\n\tMaxQueueSize int\n\n\t// BatchTimeout is the maximum duration for constructing a batch. Processor\n\t// forcefully sends available spans when timeout is reached.\n\t// The default value of BatchTimeout is 5000 msec.\n\tBatchTimeout time.Duration\n\n\t// ExportTimeout specifies the maximum duration for exporting spans. If the timeout\n\t// is reached, the export will be cancelled.\n\t// The default value of ExportTimeout is 30000 msec.\n\tExportTimeout time.Duration\n\n\t// MaxExportBatchSize is the maximum number of spans to process in a single batch.\n\t// If there are more than one batch worth of spans then it processes multiple batches\n\t// of spans one batch after the other without any delay.\n\t// The default value of MaxExportBatchSize is 512.\n\tMaxExportBatchSize int\n\n\t// BlockOnQueueFull blocks onEnd() and onStart() method if the queue is full\n\t// AND if BlockOnQueueFull is set to true.\n\t// Blocking option should be used carefully as it can severely affect the performance of an\n\t// application.\n\tBlockOnQueueFull bool\n}\n\n// batchSpanProcessor is a SpanProcessor that batches asynchronously-received\n// spans and sends them to a trace.Exporter when complete.\ntype batchSpanProcessor struct {\n\te SpanExporter\n\to BatchSpanProcessorOptions\n\n\tqueue   chan ReadOnlySpan\n\tdropped uint32\n\n\tinst *observ.BSP\n\n\tbatch      []ReadOnlySpan\n\tbatchMutex sync.Mutex\n\ttimer      *time.Timer\n\tstopWait   sync.WaitGroup\n\tstopOnce   sync.Once\n\tstopCh     chan struct{}\n\tstopped    atomic.Bool\n}\n\nvar _ SpanProcessor = (*batchSpanProcessor)(nil)\n\n// NewBatchSpanProcessor creates a new SpanProcessor that will send completed\n// span batches to the exporter with the supplied options.\n//\n// If the exporter is nil, the span processor will perform no action.\nfunc NewBatchSpanProcessor(exporter SpanExporter, options ...BatchSpanProcessorOption) SpanProcessor {\n\tmaxQueueSize := env.BatchSpanProcessorMaxQueueSize(DefaultMaxQueueSize)\n\tmaxExportBatchSize := env.BatchSpanProcessorMaxExportBatchSize(DefaultMaxExportBatchSize)\n\n\tif maxExportBatchSize > maxQueueSize {\n\t\tmaxExportBatchSize = min(DefaultMaxExportBatchSize, maxQueueSize)\n\t}\n\n\to := BatchSpanProcessorOptions{\n\t\tBatchTimeout:       time.Duration(env.BatchSpanProcessorScheduleDelay(DefaultScheduleDelay)) * time.Millisecond,\n\t\tExportTimeout:      time.Duration(env.BatchSpanProcessorExportTimeout(DefaultExportTimeout)) * time.Millisecond,\n\t\tMaxQueueSize:       maxQueueSize,\n\t\tMaxExportBatchSize: maxExportBatchSize,\n\t}\n\tfor _, opt := range options {\n\t\topt(&o)\n\t}\n\tbsp := &batchSpanProcessor{\n\t\te:      exporter,\n\t\to:      o,\n\t\tbatch:  make([]ReadOnlySpan, 0, o.MaxExportBatchSize),\n\t\ttimer:  time.NewTimer(o.BatchTimeout),\n\t\tqueue:  make(chan ReadOnlySpan, o.MaxQueueSize),\n\t\tstopCh: make(chan struct{}),\n\t}\n\n\tvar err error\n\tbsp.inst, err = observ.NewBSP(\n\t\tnextProcessorID(),\n\t\tfunc() int64 { return int64(len(bsp.queue)) },\n\t\tint64(bsp.o.MaxQueueSize),\n\t)\n\tif err != nil {\n\t\totel.Handle(err)\n\t}\n\n\tbsp.stopWait.Add(1)\n\tgo func() {\n\t\tdefer bsp.stopWait.Done()\n\t\tbsp.processQueue()\n\t\tbsp.drainQueue()\n\t}()\n\n\treturn bsp\n}\n\nvar processorIDCounter atomic.Int64\n\n// nextProcessorID returns an identifier for this batch span processor,\n// starting with 0 and incrementing by 1 each time it is called.\nfunc nextProcessorID() int64 {\n\treturn processorIDCounter.Add(1) - 1\n}\n\n// OnStart method does nothing.\nfunc (*batchSpanProcessor) OnStart(context.Context, ReadWriteSpan) {}\n\n// OnEnd method enqueues a ReadOnlySpan for later processing.\nfunc (bsp *batchSpanProcessor) OnEnd(s ReadOnlySpan) {\n\t// Do not enqueue spans after Shutdown.\n\tif bsp.stopped.Load() {\n\t\treturn\n\t}\n\n\t// Do not enqueue spans if we are just going to drop them.\n\tif bsp.e == nil {\n\t\treturn\n\t}\n\tbsp.enqueue(s)\n}\n\n// Shutdown flushes the queue and waits until all spans are processed.\n// It only executes once. Subsequent call does nothing.\nfunc (bsp *batchSpanProcessor) Shutdown(ctx context.Context) error {\n\tvar err error\n\tbsp.stopOnce.Do(func() {\n\t\tbsp.stopped.Store(true)\n\t\twait := make(chan struct{})\n\t\tgo func() {\n\t\t\tclose(bsp.stopCh)\n\t\t\tbsp.stopWait.Wait()\n\t\t\tif bsp.e != nil {\n\t\t\t\tif err := bsp.e.Shutdown(ctx); err != nil {\n\t\t\t\t\totel.Handle(err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tclose(wait)\n\t\t}()\n\t\t// Wait until the wait group is done or the context is cancelled\n\t\tselect {\n\t\tcase <-wait:\n\t\tcase <-ctx.Done():\n\t\t\terr = ctx.Err()\n\t\t}\n\t\tif bsp.inst != nil {\n\t\t\terr = errors.Join(err, bsp.inst.Shutdown())\n\t\t}\n\t})\n\treturn err\n}\n\ntype forceFlushSpan struct {\n\tReadOnlySpan\n\tflushed chan struct{}\n}\n\nfunc (forceFlushSpan) SpanContext() trace.SpanContext {\n\treturn trace.NewSpanContext(trace.SpanContextConfig{TraceFlags: trace.FlagsSampled})\n}\n\n// ForceFlush exports all ended spans that have not yet been exported.\nfunc (bsp *batchSpanProcessor) ForceFlush(ctx context.Context) error {\n\t// Interrupt if context is already canceled.\n\tif err := ctx.Err(); err != nil {\n\t\treturn err\n\t}\n\n\t// Do nothing after Shutdown.\n\tif bsp.stopped.Load() {\n\t\treturn nil\n\t}\n\n\tvar err error\n\tif bsp.e != nil {\n\t\tflushCh := make(chan struct{})\n\t\tif bsp.enqueueBlockOnQueueFull(ctx, forceFlushSpan{flushed: flushCh}) {\n\t\t\tselect {\n\t\t\tcase <-bsp.stopCh:\n\t\t\t\t// The batchSpanProcessor is Shutdown.\n\t\t\t\treturn nil\n\t\t\tcase <-flushCh:\n\t\t\t\t// Processed any items in queue prior to ForceFlush being called\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn ctx.Err()\n\t\t\t}\n\t\t}\n\n\t\twait := make(chan error, 1)\n\t\tgo func() {\n\t\t\twait <- bsp.exportSpans(ctx)\n\t\t}()\n\t\t// Wait until the export is finished or the context is cancelled/timed out\n\t\tselect {\n\t\tcase err = <-wait:\n\t\tcase <-ctx.Done():\n\t\t\terr = ctx.Err()\n\t\t}\n\t}\n\treturn err\n}\n\n// WithMaxQueueSize returns a BatchSpanProcessorOption that configures the\n// maximum queue size allowed for a BatchSpanProcessor.\nfunc WithMaxQueueSize(size int) BatchSpanProcessorOption {\n\treturn func(o *BatchSpanProcessorOptions) {\n\t\to.MaxQueueSize = size\n\t}\n}\n\n// WithMaxExportBatchSize returns a BatchSpanProcessorOption that configures\n// the maximum export batch size allowed for a BatchSpanProcessor.\nfunc WithMaxExportBatchSize(size int) BatchSpanProcessorOption {\n\treturn func(o *BatchSpanProcessorOptions) {\n\t\to.MaxExportBatchSize = size\n\t}\n}\n\n// WithBatchTimeout returns a BatchSpanProcessorOption that configures the\n// maximum delay allowed for a BatchSpanProcessor before it will export any\n// held span (whether the queue is full or not).\nfunc WithBatchTimeout(delay time.Duration) BatchSpanProcessorOption {\n\treturn func(o *BatchSpanProcessorOptions) {\n\t\to.BatchTimeout = delay\n\t}\n}\n\n// WithExportTimeout returns a BatchSpanProcessorOption that configures the\n// amount of time a BatchSpanProcessor waits for an exporter to export before\n// abandoning the export.\nfunc WithExportTimeout(timeout time.Duration) BatchSpanProcessorOption {\n\treturn func(o *BatchSpanProcessorOptions) {\n\t\to.ExportTimeout = timeout\n\t}\n}\n\n// WithBlocking returns a BatchSpanProcessorOption that configures a\n// BatchSpanProcessor to wait for enqueue operations to succeed instead of\n// dropping data when the queue is full.\nfunc WithBlocking() BatchSpanProcessorOption {\n\treturn func(o *BatchSpanProcessorOptions) {\n\t\to.BlockOnQueueFull = true\n\t}\n}\n\n// exportSpans is a subroutine of processing and draining the queue.\nfunc (bsp *batchSpanProcessor) exportSpans(ctx context.Context) error {\n\tbsp.timer.Reset(bsp.o.BatchTimeout)\n\n\tbsp.batchMutex.Lock()\n\tdefer bsp.batchMutex.Unlock()\n\n\tif bsp.o.ExportTimeout > 0 {\n\t\tvar cancel context.CancelFunc\n\t\tctx, cancel = context.WithTimeoutCause(ctx, bsp.o.ExportTimeout, errors.New(\"processor export timeout\"))\n\t\tdefer cancel()\n\t}\n\n\tif l := len(bsp.batch); l > 0 {\n\t\tglobal.Debug(\"exporting spans\", \"count\", len(bsp.batch), \"total_dropped\", atomic.LoadUint32(&bsp.dropped))\n\t\tif bsp.inst != nil {\n\t\t\tbsp.inst.Processed(ctx, int64(l))\n\t\t}\n\t\terr := bsp.e.ExportSpans(ctx, bsp.batch)\n\n\t\t// A new batch is always created after exporting, even if the batch failed to be exported.\n\t\t//\n\t\t// It is up to the exporter to implement any type of retry logic if a batch is failing\n\t\t// to be exported, since it is specific to the protocol and backend being sent to.\n\t\tclear(bsp.batch) // Erase elements to let GC collect objects\n\t\tbsp.batch = bsp.batch[:0]\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// processQueue removes spans from the `queue` channel until processor\n// is shut down. It calls the exporter in batches of up to MaxExportBatchSize\n// waiting up to BatchTimeout to form a batch.\nfunc (bsp *batchSpanProcessor) processQueue() {\n\tdefer bsp.timer.Stop()\n\n\tctx, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\tfor {\n\t\tselect {\n\t\tcase <-bsp.stopCh:\n\t\t\treturn\n\t\tcase <-bsp.timer.C:\n\t\t\tif err := bsp.exportSpans(ctx); err != nil {\n\t\t\t\totel.Handle(err)\n\t\t\t}\n\t\tcase sd := <-bsp.queue:\n\t\t\tif ffs, ok := sd.(forceFlushSpan); ok {\n\t\t\t\tclose(ffs.flushed)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tbsp.batchMutex.Lock()\n\t\t\tbsp.batch = append(bsp.batch, sd)\n\t\t\tshouldExport := len(bsp.batch) >= bsp.o.MaxExportBatchSize\n\t\t\tbsp.batchMutex.Unlock()\n\t\t\tif shouldExport {\n\t\t\t\tif !bsp.timer.Stop() {\n\t\t\t\t\t// Handle both GODEBUG=asynctimerchan=[0|1] properly.\n\t\t\t\t\tselect {\n\t\t\t\t\tcase <-bsp.timer.C:\n\t\t\t\t\tdefault:\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif err := bsp.exportSpans(ctx); err != nil {\n\t\t\t\t\totel.Handle(err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n// drainQueue awaits the any caller that had added to bsp.stopWait\n// to finish the enqueue, then exports the final batch.\nfunc (bsp *batchSpanProcessor) drainQueue() {\n\tctx, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\tfor {\n\t\tselect {\n\t\tcase sd := <-bsp.queue:\n\t\t\tif _, ok := sd.(forceFlushSpan); ok {\n\t\t\t\t// Ignore flush requests as they are not valid spans.\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tbsp.batchMutex.Lock()\n\t\t\tbsp.batch = append(bsp.batch, sd)\n\t\t\tshouldExport := len(bsp.batch) == bsp.o.MaxExportBatchSize\n\t\t\tbsp.batchMutex.Unlock()\n\n\t\t\tif shouldExport {\n\t\t\t\tif err := bsp.exportSpans(ctx); err != nil {\n\t\t\t\t\totel.Handle(err)\n\t\t\t\t}\n\t\t\t}\n\t\tdefault:\n\t\t\t// There are no more enqueued spans. Make final export.\n\t\t\tif err := bsp.exportSpans(ctx); err != nil {\n\t\t\t\totel.Handle(err)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (bsp *batchSpanProcessor) enqueue(sd ReadOnlySpan) {\n\tctx := context.TODO()\n\tif bsp.o.BlockOnQueueFull {\n\t\tbsp.enqueueBlockOnQueueFull(ctx, sd)\n\t} else {\n\t\tbsp.enqueueDrop(ctx, sd)\n\t}\n}\n\nfunc (bsp *batchSpanProcessor) enqueueBlockOnQueueFull(ctx context.Context, sd ReadOnlySpan) bool {\n\tif !sd.SpanContext().IsSampled() {\n\t\treturn false\n\t}\n\n\tselect {\n\tcase bsp.queue <- sd:\n\t\treturn true\n\tcase <-ctx.Done():\n\t\tif bsp.inst != nil {\n\t\t\tbsp.inst.ProcessedQueueFull(ctx, 1)\n\t\t}\n\t\treturn false\n\t}\n}\n\nfunc (bsp *batchSpanProcessor) enqueueDrop(ctx context.Context, sd ReadOnlySpan) bool {\n\tif !sd.SpanContext().IsSampled() {\n\t\treturn false\n\t}\n\n\tselect {\n\tcase bsp.queue <- sd:\n\t\treturn true\n\tdefault:\n\t\tatomic.AddUint32(&bsp.dropped, 1)\n\t\tif bsp.inst != nil {\n\t\t\tbsp.inst.ProcessedQueueFull(ctx, 1)\n\t\t}\n\t}\n\treturn false\n}\n\n// MarshalLog is the marshaling function used by the logging system to represent this Span Processor.\nfunc (bsp *batchSpanProcessor) MarshalLog() any {\n\treturn struct {\n\t\tType         string\n\t\tSpanExporter SpanExporter\n\t\tConfig       BatchSpanProcessorOptions\n\t}{\n\t\tType:         \"BatchSpanProcessor\",\n\t\tSpanExporter: bsp.e,\n\t\tConfig:       bsp.o,\n\t}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n/*\nPackage trace contains support for OpenTelemetry distributed tracing.\n\nThe following assumes a basic familiarity with OpenTelemetry concepts.\nSee https://opentelemetry.io.\n\nSee [go.opentelemetry.io/otel/sdk/internal/x] for information about\nthe experimental features.\n*/\npackage trace // import \"go.opentelemetry.io/otel/sdk/trace\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/event.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/sdk/trace\"\n\nimport (\n\t\"time\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n)\n\n// Event is a thing that happened during a Span's lifetime.\ntype Event struct {\n\t// Name is the name of this event\n\tName string\n\n\t// Attributes describe the aspects of the event.\n\tAttributes []attribute.KeyValue\n\n\t// DroppedAttributeCount is the number of attributes that were not\n\t// recorded due to configured limits being reached.\n\tDroppedAttributeCount int\n\n\t// Time at which this event was recorded.\n\tTime time.Time\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/evictedqueue.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/sdk/trace\"\n\nimport (\n\t\"slices\"\n\t\"sync\"\n\n\t\"go.opentelemetry.io/otel/internal/global\"\n)\n\n// evictedQueue is a FIFO queue with a configurable capacity.\ntype evictedQueue[T any] struct {\n\tqueue          []T\n\tcapacity       int\n\tdroppedCount   int\n\tlogDroppedMsg  string\n\tlogDroppedOnce sync.Once\n}\n\nfunc newEvictedQueueEvent(capacity int) evictedQueue[Event] {\n\t// Do not pre-allocate queue, do this lazily.\n\treturn evictedQueue[Event]{\n\t\tcapacity:      capacity,\n\t\tlogDroppedMsg: \"limit reached: dropping trace trace.Event\",\n\t}\n}\n\nfunc newEvictedQueueLink(capacity int) evictedQueue[Link] {\n\t// Do not pre-allocate queue, do this lazily.\n\treturn evictedQueue[Link]{\n\t\tcapacity:      capacity,\n\t\tlogDroppedMsg: \"limit reached: dropping trace trace.Link\",\n\t}\n}\n\n// add adds value to the evictedQueue eq. If eq is at capacity, the oldest\n// queued value will be discarded and the drop count incremented.\nfunc (eq *evictedQueue[T]) add(value T) {\n\tif eq.capacity == 0 {\n\t\teq.droppedCount++\n\t\teq.logDropped()\n\t\treturn\n\t}\n\n\tif eq.capacity > 0 && len(eq.queue) == eq.capacity {\n\t\t// Drop first-in while avoiding allocating more capacity to eq.queue.\n\t\tcopy(eq.queue[:eq.capacity-1], eq.queue[1:])\n\t\teq.queue = eq.queue[:eq.capacity-1]\n\t\teq.droppedCount++\n\t\teq.logDropped()\n\t}\n\teq.queue = append(eq.queue, value)\n}\n\nfunc (eq *evictedQueue[T]) logDropped() {\n\teq.logDroppedOnce.Do(func() { global.Warn(eq.logDroppedMsg) })\n}\n\n// copy returns a copy of the evictedQueue.\nfunc (eq *evictedQueue[T]) copy() []T {\n\treturn slices.Clone(eq.queue)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/id_generator.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/sdk/trace\"\n\nimport (\n\t\"context\"\n\t\"encoding/binary\"\n\t\"math/rand/v2\"\n\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\n// IDGenerator allows custom generators for TraceID and SpanID.\ntype IDGenerator interface {\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// NewIDs returns a new trace and span ID.\n\tNewIDs(ctx context.Context) (trace.TraceID, trace.SpanID)\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// NewSpanID returns a ID for a new span in the trace with traceID.\n\tNewSpanID(ctx context.Context, traceID trace.TraceID) trace.SpanID\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n}\n\ntype randomIDGenerator struct{}\n\nvar _ IDGenerator = &randomIDGenerator{}\n\n// NewSpanID returns a non-zero span ID from a randomly-chosen sequence.\nfunc (*randomIDGenerator) NewSpanID(context.Context, trace.TraceID) trace.SpanID {\n\tsid := trace.SpanID{}\n\tfor {\n\t\tbinary.NativeEndian.PutUint64(sid[:], rand.Uint64())\n\t\tif sid.IsValid() {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn sid\n}\n\n// NewIDs returns a non-zero trace ID and a non-zero span ID from a\n// randomly-chosen sequence.\nfunc (*randomIDGenerator) NewIDs(context.Context) (trace.TraceID, trace.SpanID) {\n\ttid := trace.TraceID{}\n\tsid := trace.SpanID{}\n\tfor {\n\t\tbinary.NativeEndian.PutUint64(tid[:8], rand.Uint64())\n\t\tbinary.NativeEndian.PutUint64(tid[8:], rand.Uint64())\n\t\tif tid.IsValid() {\n\t\t\tbreak\n\t\t}\n\t}\n\tfor {\n\t\tbinary.NativeEndian.PutUint64(sid[:], rand.Uint64())\n\t\tif sid.IsValid() {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn tid, sid\n}\n\nfunc defaultIDGenerator() IDGenerator {\n\treturn &randomIDGenerator{}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/internal/env/env.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package env provides types and functionality for environment variable support\n// in the OpenTelemetry SDK.\npackage env // import \"go.opentelemetry.io/otel/sdk/trace/internal/env\"\n\nimport (\n\t\"os\"\n\t\"strconv\"\n\n\t\"go.opentelemetry.io/otel/internal/global\"\n)\n\n// Environment variable names.\nconst (\n\t// BatchSpanProcessorScheduleDelayKey is the delay interval between two\n\t// consecutive exports (i.e. 5000).\n\tBatchSpanProcessorScheduleDelayKey = \"OTEL_BSP_SCHEDULE_DELAY\"\n\t// BatchSpanProcessorExportTimeoutKey is the maximum allowed time to\n\t// export data (i.e. 3000).\n\tBatchSpanProcessorExportTimeoutKey = \"OTEL_BSP_EXPORT_TIMEOUT\"\n\t// BatchSpanProcessorMaxQueueSizeKey is the maximum queue size (i.e. 2048).\n\tBatchSpanProcessorMaxQueueSizeKey = \"OTEL_BSP_MAX_QUEUE_SIZE\"\n\t// BatchSpanProcessorMaxExportBatchSizeKey is the maximum batch size (i.e.\n\t// 512). Note: it must be less than or equal to\n\t// BatchSpanProcessorMaxQueueSize.\n\tBatchSpanProcessorMaxExportBatchSizeKey = \"OTEL_BSP_MAX_EXPORT_BATCH_SIZE\"\n\n\t// AttributeValueLengthKey is the maximum allowed attribute value size.\n\tAttributeValueLengthKey = \"OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT\"\n\n\t// AttributeCountKey is the maximum allowed span attribute count.\n\tAttributeCountKey = \"OTEL_ATTRIBUTE_COUNT_LIMIT\"\n\n\t// SpanAttributeValueLengthKey is the maximum allowed attribute value size\n\t// for a span.\n\tSpanAttributeValueLengthKey = \"OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT\"\n\n\t// SpanAttributeCountKey is the maximum allowed span attribute count for a\n\t// span.\n\tSpanAttributeCountKey = \"OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT\"\n\n\t// SpanEventCountKey is the maximum allowed span event count.\n\tSpanEventCountKey = \"OTEL_SPAN_EVENT_COUNT_LIMIT\"\n\n\t// SpanEventAttributeCountKey is the maximum allowed attribute per span\n\t// event count.\n\tSpanEventAttributeCountKey = \"OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT\"\n\n\t// SpanLinkCountKey is the maximum allowed span link count.\n\tSpanLinkCountKey = \"OTEL_SPAN_LINK_COUNT_LIMIT\"\n\n\t// SpanLinkAttributeCountKey is the maximum allowed attribute per span\n\t// link count.\n\tSpanLinkAttributeCountKey = \"OTEL_LINK_ATTRIBUTE_COUNT_LIMIT\"\n)\n\n// firstInt returns the value of the first matching environment variable from\n// keys. If the value is not an integer or no match is found, defaultValue is\n// returned.\nfunc firstInt(defaultValue int, keys ...string) int {\n\tfor _, key := range keys {\n\t\tvalue := os.Getenv(key)\n\t\tif value == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tintValue, err := strconv.Atoi(value)\n\t\tif err != nil {\n\t\t\tglobal.Info(\"Got invalid value, number value expected.\", key, value)\n\t\t\treturn defaultValue\n\t\t}\n\n\t\treturn intValue\n\t}\n\n\treturn defaultValue\n}\n\n// IntEnvOr returns the int value of the environment variable with name key if\n// it exists, it is not empty, and the value is an int. Otherwise, defaultValue is returned.\nfunc IntEnvOr(key string, defaultValue int) int {\n\tvalue := os.Getenv(key)\n\tif value == \"\" {\n\t\treturn defaultValue\n\t}\n\n\tintValue, err := strconv.Atoi(value)\n\tif err != nil {\n\t\tglobal.Info(\"Got invalid value, number value expected.\", key, value)\n\t\treturn defaultValue\n\t}\n\n\treturn intValue\n}\n\n// BatchSpanProcessorScheduleDelay returns the environment variable value for\n// the OTEL_BSP_SCHEDULE_DELAY key if it exists, otherwise defaultValue is\n// returned.\nfunc BatchSpanProcessorScheduleDelay(defaultValue int) int {\n\treturn IntEnvOr(BatchSpanProcessorScheduleDelayKey, defaultValue)\n}\n\n// BatchSpanProcessorExportTimeout returns the environment variable value for\n// the OTEL_BSP_EXPORT_TIMEOUT key if it exists, otherwise defaultValue is\n// returned.\nfunc BatchSpanProcessorExportTimeout(defaultValue int) int {\n\treturn IntEnvOr(BatchSpanProcessorExportTimeoutKey, defaultValue)\n}\n\n// BatchSpanProcessorMaxQueueSize returns the environment variable value for\n// the OTEL_BSP_MAX_QUEUE_SIZE key if it exists, otherwise defaultValue is\n// returned.\nfunc BatchSpanProcessorMaxQueueSize(defaultValue int) int {\n\treturn IntEnvOr(BatchSpanProcessorMaxQueueSizeKey, defaultValue)\n}\n\n// BatchSpanProcessorMaxExportBatchSize returns the environment variable value for\n// the OTEL_BSP_MAX_EXPORT_BATCH_SIZE key if it exists, otherwise defaultValue\n// is returned.\nfunc BatchSpanProcessorMaxExportBatchSize(defaultValue int) int {\n\treturn IntEnvOr(BatchSpanProcessorMaxExportBatchSizeKey, defaultValue)\n}\n\n// SpanAttributeValueLength returns the environment variable value for the\n// OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT key if it exists. Otherwise, the\n// environment variable value for OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT is\n// returned or defaultValue if that is not set.\nfunc SpanAttributeValueLength(defaultValue int) int {\n\treturn firstInt(defaultValue, SpanAttributeValueLengthKey, AttributeValueLengthKey)\n}\n\n// SpanAttributeCount returns the environment variable value for the\n// OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT key if it exists. Otherwise, the\n// environment variable value for OTEL_ATTRIBUTE_COUNT_LIMIT is returned or\n// defaultValue if that is not set.\nfunc SpanAttributeCount(defaultValue int) int {\n\treturn firstInt(defaultValue, SpanAttributeCountKey, AttributeCountKey)\n}\n\n// SpanEventCount returns the environment variable value for the\n// OTEL_SPAN_EVENT_COUNT_LIMIT key if it exists, otherwise defaultValue is\n// returned.\nfunc SpanEventCount(defaultValue int) int {\n\treturn IntEnvOr(SpanEventCountKey, defaultValue)\n}\n\n// SpanEventAttributeCount returns the environment variable value for the\n// OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT key if it exists, otherwise defaultValue\n// is returned.\nfunc SpanEventAttributeCount(defaultValue int) int {\n\treturn IntEnvOr(SpanEventAttributeCountKey, defaultValue)\n}\n\n// SpanLinkCount returns the environment variable value for the\n// OTEL_SPAN_LINK_COUNT_LIMIT key if it exists, otherwise defaultValue is\n// returned.\nfunc SpanLinkCount(defaultValue int) int {\n\treturn IntEnvOr(SpanLinkCountKey, defaultValue)\n}\n\n// SpanLinkAttributeCount returns the environment variable value for the\n// OTEL_LINK_ATTRIBUTE_COUNT_LIMIT key if it exists, otherwise defaultValue is\n// returned.\nfunc SpanLinkAttributeCount(defaultValue int) int {\n\treturn IntEnvOr(SpanLinkAttributeCountKey, defaultValue)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/batch_span_processor.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage observ // import \"go.opentelemetry.io/otel/sdk/trace/internal/observ\"\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"go.opentelemetry.io/otel\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/metric\"\n\t\"go.opentelemetry.io/otel/sdk\"\n\t\"go.opentelemetry.io/otel/sdk/internal/x\"\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.39.0\"\n\t\"go.opentelemetry.io/otel/semconv/v1.39.0/otelconv\"\n)\n\nconst (\n\t// ScopeName is the name of the instrumentation scope.\n\tScopeName = \"go.opentelemetry.io/otel/sdk/trace/internal/observ\"\n\n\t// SchemaURL is the schema URL of the instrumentation.\n\tSchemaURL = semconv.SchemaURL\n)\n\n// ErrQueueFull is the attribute value for the \"queue_full\" error type.\nvar ErrQueueFull = otelconv.SDKProcessorSpanProcessed{}.AttrErrorType(\n\totelconv.ErrorTypeAttr(\"queue_full\"),\n)\n\n// BSPComponentName returns the component name attribute for a\n// BatchSpanProcessor with the given ID.\nfunc BSPComponentName(id int64) attribute.KeyValue {\n\tt := otelconv.ComponentTypeBatchingSpanProcessor\n\tname := fmt.Sprintf(\"%s/%d\", t, id)\n\treturn semconv.OTelComponentName(name)\n}\n\n// BSP is the instrumentation for an OTel SDK BatchSpanProcessor.\ntype BSP struct {\n\treg metric.Registration\n\n\tprocessed              metric.Int64Counter\n\tprocessedOpts          []metric.AddOption\n\tprocessedQueueFullOpts []metric.AddOption\n}\n\nfunc NewBSP(id int64, qLen func() int64, qMax int64) (*BSP, error) {\n\tif !x.Observability.Enabled() {\n\t\treturn nil, nil\n\t}\n\n\tmeter := otel.GetMeterProvider().Meter(\n\t\tScopeName,\n\t\tmetric.WithInstrumentationVersion(sdk.Version()),\n\t\tmetric.WithSchemaURL(SchemaURL),\n\t)\n\n\tqCap, err := otelconv.NewSDKProcessorSpanQueueCapacity(meter)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"failed to create BSP queue capacity metric: %w\", err)\n\t}\n\tqCapInst := qCap.Inst()\n\n\tqSize, e := otelconv.NewSDKProcessorSpanQueueSize(meter)\n\tif e != nil {\n\t\te := fmt.Errorf(\"failed to create BSP queue size metric: %w\", e)\n\t\terr = errors.Join(err, e)\n\t}\n\tqSizeInst := qSize.Inst()\n\n\tcmpntT := semconv.OTelComponentTypeBatchingSpanProcessor\n\tcmpnt := BSPComponentName(id)\n\tset := attribute.NewSet(cmpnt, cmpntT)\n\n\tobsOpts := []metric.ObserveOption{metric.WithAttributeSet(set)}\n\treg, e := meter.RegisterCallback(\n\t\tfunc(_ context.Context, o metric.Observer) error {\n\t\t\to.ObserveInt64(qSizeInst, qLen(), obsOpts...)\n\t\t\to.ObserveInt64(qCapInst, qMax, obsOpts...)\n\t\t\treturn nil\n\t\t},\n\t\tqSizeInst,\n\t\tqCapInst,\n\t)\n\tif e != nil {\n\t\te := fmt.Errorf(\"failed to register BSP queue size/capacity callback: %w\", e)\n\t\terr = errors.Join(err, e)\n\t}\n\n\tprocessed, e := otelconv.NewSDKProcessorSpanProcessed(meter)\n\tif e != nil {\n\t\te := fmt.Errorf(\"failed to create BSP processed spans metric: %w\", e)\n\t\terr = errors.Join(err, e)\n\t}\n\tprocessedOpts := []metric.AddOption{metric.WithAttributeSet(set)}\n\n\tset = attribute.NewSet(cmpnt, cmpntT, ErrQueueFull)\n\tprocessedQueueFullOpts := []metric.AddOption{metric.WithAttributeSet(set)}\n\n\treturn &BSP{\n\t\treg:                    reg,\n\t\tprocessed:              processed.Inst(),\n\t\tprocessedOpts:          processedOpts,\n\t\tprocessedQueueFullOpts: processedQueueFullOpts,\n\t}, err\n}\n\nfunc (b *BSP) Shutdown() error { return b.reg.Unregister() }\n\nfunc (b *BSP) Processed(ctx context.Context, n int64) {\n\tb.processed.Add(ctx, n, b.processedOpts...)\n}\n\nfunc (b *BSP) ProcessedQueueFull(ctx context.Context, n int64) {\n\tb.processed.Add(ctx, n, b.processedQueueFullOpts...)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package observ provides observability instrumentation for the OTel trace SDK\n// package.\npackage observ // import \"go.opentelemetry.io/otel/sdk/trace/internal/observ\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/simple_span_processor.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage observ // import \"go.opentelemetry.io/otel/sdk/trace/internal/observ\"\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\n\t\"go.opentelemetry.io/otel\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/metric\"\n\t\"go.opentelemetry.io/otel/sdk\"\n\t\"go.opentelemetry.io/otel/sdk/internal/x\"\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.39.0\"\n\t\"go.opentelemetry.io/otel/semconv/v1.39.0/otelconv\"\n)\n\nvar measureAttrsPool = sync.Pool{\n\tNew: func() any {\n\t\t// \"component.name\" + \"component.type\" + \"error.type\"\n\t\tconst n = 1 + 1 + 1\n\t\ts := make([]attribute.KeyValue, 0, n)\n\t\t// Return a pointer to a slice instead of a slice itself\n\t\t// to avoid allocations on every call.\n\t\treturn &s\n\t},\n}\n\n// SSP is the instrumentation for an OTel SDK SimpleSpanProcessor.\ntype SSP struct {\n\tspansProcessedCounter metric.Int64Counter\n\taddOpts               []metric.AddOption\n\tattrs                 []attribute.KeyValue\n}\n\n// SSPComponentName returns the component name attribute for a\n// SimpleSpanProcessor with the given ID.\nfunc SSPComponentName(id int64) attribute.KeyValue {\n\tt := otelconv.ComponentTypeSimpleSpanProcessor\n\tname := fmt.Sprintf(\"%s/%d\", t, id)\n\treturn semconv.OTelComponentName(name)\n}\n\n// NewSSP returns instrumentation for an OTel SDK SimpleSpanProcessor with the\n// provided ID.\n//\n// If the experimental observability is disabled, nil is returned.\nfunc NewSSP(id int64) (*SSP, error) {\n\tif !x.Observability.Enabled() {\n\t\treturn nil, nil\n\t}\n\n\tmeter := otel.GetMeterProvider().Meter(\n\t\tScopeName,\n\t\tmetric.WithInstrumentationVersion(sdk.Version()),\n\t\tmetric.WithSchemaURL(SchemaURL),\n\t)\n\tspansProcessedCounter, err := otelconv.NewSDKProcessorSpanProcessed(meter)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"failed to create SSP processed spans metric: %w\", err)\n\t}\n\n\tcomponentName := SSPComponentName(id)\n\tcomponentType := spansProcessedCounter.AttrComponentType(otelconv.ComponentTypeSimpleSpanProcessor)\n\tattrs := []attribute.KeyValue{componentName, componentType}\n\taddOpts := []metric.AddOption{metric.WithAttributeSet(attribute.NewSet(attrs...))}\n\n\treturn &SSP{\n\t\tspansProcessedCounter: spansProcessedCounter.Inst(),\n\t\taddOpts:               addOpts,\n\t\tattrs:                 attrs,\n\t}, err\n}\n\n// SpanProcessed records that a span has been processed by the SimpleSpanProcessor.\n// If err is non-nil, it records the processing error as an attribute.\nfunc (ssp *SSP) SpanProcessed(ctx context.Context, err error) {\n\tssp.spansProcessedCounter.Add(ctx, 1, ssp.addOption(err)...)\n}\n\nfunc (ssp *SSP) addOption(err error) []metric.AddOption {\n\tif err == nil {\n\t\treturn ssp.addOpts\n\t}\n\tattrs := measureAttrsPool.Get().(*[]attribute.KeyValue)\n\tdefer func() {\n\t\t*attrs = (*attrs)[:0] // reset the slice for reuse\n\t\tmeasureAttrsPool.Put(attrs)\n\t}()\n\t*attrs = append(*attrs, ssp.attrs...)\n\t*attrs = append(*attrs, semconv.ErrorType(err))\n\t// Do not inefficiently make a copy of attrs by using\n\t// WithAttributes instead of WithAttributeSet.\n\treturn []metric.AddOption{metric.WithAttributeSet(attribute.NewSet(*attrs...))}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/internal/observ/tracer.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage observ // import \"go.opentelemetry.io/otel/sdk/trace/internal/observ\"\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"go.opentelemetry.io/otel\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/metric\"\n\t\"go.opentelemetry.io/otel/sdk\"\n\t\"go.opentelemetry.io/otel/sdk/internal/x\"\n\t\"go.opentelemetry.io/otel/semconv/v1.39.0/otelconv\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\nvar meterOpts = []metric.MeterOption{\n\tmetric.WithInstrumentationVersion(sdk.Version()),\n\tmetric.WithSchemaURL(SchemaURL),\n}\n\n// Tracer is instrumentation for an OTel SDK Tracer.\ntype Tracer struct {\n\tenabled bool\n\n\tlive    metric.Int64UpDownCounter\n\tstarted metric.Int64Counter\n}\n\nfunc NewTracer() (Tracer, error) {\n\tif !x.Observability.Enabled() {\n\t\treturn Tracer{}, nil\n\t}\n\tmeter := otel.GetMeterProvider().Meter(ScopeName, meterOpts...)\n\n\tvar err error\n\tl, e := otelconv.NewSDKSpanLive(meter)\n\tif e != nil {\n\t\te = fmt.Errorf(\"failed to create span live metric: %w\", e)\n\t\terr = errors.Join(err, e)\n\t}\n\n\ts, e := otelconv.NewSDKSpanStarted(meter)\n\tif e != nil {\n\t\te = fmt.Errorf(\"failed to create span started metric: %w\", e)\n\t\terr = errors.Join(err, e)\n\t}\n\n\treturn Tracer{enabled: true, live: l.Inst(), started: s.Inst()}, err\n}\n\nfunc (t Tracer) Enabled() bool { return t.enabled }\n\nfunc (t Tracer) SpanStarted(ctx context.Context, psc trace.SpanContext, span trace.Span) {\n\tkey := spanStartedKey{\n\t\tparent:   parentStateNoParent,\n\t\tsampling: samplingStateDrop,\n\t}\n\n\tif psc.IsValid() {\n\t\tif psc.IsRemote() {\n\t\t\tkey.parent = parentStateRemoteParent\n\t\t} else {\n\t\t\tkey.parent = parentStateLocalParent\n\t\t}\n\t}\n\n\tif span.IsRecording() {\n\t\tif span.SpanContext().IsSampled() {\n\t\t\tkey.sampling = samplingStateRecordAndSample\n\t\t} else {\n\t\t\tkey.sampling = samplingStateRecordOnly\n\t\t}\n\t}\n\n\topts := spanStartedOpts[key]\n\tt.started.Add(ctx, 1, opts...)\n}\n\nfunc (t Tracer) SpanLive(ctx context.Context, span trace.Span) {\n\tt.spanLive(ctx, 1, span)\n}\n\nfunc (t Tracer) SpanEnded(ctx context.Context, span trace.Span) {\n\tt.spanLive(ctx, -1, span)\n}\n\nfunc (t Tracer) spanLive(ctx context.Context, value int64, span trace.Span) {\n\tkey := spanLiveKey{sampled: span.SpanContext().IsSampled()}\n\topts := spanLiveOpts[key]\n\tt.live.Add(ctx, value, opts...)\n}\n\ntype parentState int\n\nconst (\n\tparentStateNoParent parentState = iota\n\tparentStateLocalParent\n\tparentStateRemoteParent\n)\n\ntype samplingState int\n\nconst (\n\tsamplingStateDrop samplingState = iota\n\tsamplingStateRecordOnly\n\tsamplingStateRecordAndSample\n)\n\ntype spanStartedKey struct {\n\tparent   parentState\n\tsampling samplingState\n}\n\nvar spanStartedOpts = map[spanStartedKey][]metric.AddOption{\n\t{\n\t\tparentStateNoParent,\n\t\tsamplingStateDrop,\n\t}: {\n\t\tmetric.WithAttributeSet(attribute.NewSet(\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanParentOrigin(otelconv.SpanParentOriginNone),\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanSamplingResult(otelconv.SpanSamplingResultDrop),\n\t\t)),\n\t},\n\t{\n\t\tparentStateLocalParent,\n\t\tsamplingStateDrop,\n\t}: {\n\t\tmetric.WithAttributeSet(attribute.NewSet(\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanParentOrigin(otelconv.SpanParentOriginLocal),\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanSamplingResult(otelconv.SpanSamplingResultDrop),\n\t\t)),\n\t},\n\t{\n\t\tparentStateRemoteParent,\n\t\tsamplingStateDrop,\n\t}: {\n\t\tmetric.WithAttributeSet(attribute.NewSet(\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanParentOrigin(otelconv.SpanParentOriginRemote),\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanSamplingResult(otelconv.SpanSamplingResultDrop),\n\t\t)),\n\t},\n\n\t{\n\t\tparentStateNoParent,\n\t\tsamplingStateRecordOnly,\n\t}: {\n\t\tmetric.WithAttributeSet(attribute.NewSet(\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanParentOrigin(otelconv.SpanParentOriginNone),\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanSamplingResult(otelconv.SpanSamplingResultRecordOnly),\n\t\t)),\n\t},\n\t{\n\t\tparentStateLocalParent,\n\t\tsamplingStateRecordOnly,\n\t}: {\n\t\tmetric.WithAttributeSet(attribute.NewSet(\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanParentOrigin(otelconv.SpanParentOriginLocal),\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanSamplingResult(otelconv.SpanSamplingResultRecordOnly),\n\t\t)),\n\t},\n\t{\n\t\tparentStateRemoteParent,\n\t\tsamplingStateRecordOnly,\n\t}: {\n\t\tmetric.WithAttributeSet(attribute.NewSet(\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanParentOrigin(otelconv.SpanParentOriginRemote),\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanSamplingResult(otelconv.SpanSamplingResultRecordOnly),\n\t\t)),\n\t},\n\n\t{\n\t\tparentStateNoParent,\n\t\tsamplingStateRecordAndSample,\n\t}: {\n\t\tmetric.WithAttributeSet(attribute.NewSet(\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanParentOrigin(otelconv.SpanParentOriginNone),\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanSamplingResult(otelconv.SpanSamplingResultRecordAndSample),\n\t\t)),\n\t},\n\t{\n\t\tparentStateLocalParent,\n\t\tsamplingStateRecordAndSample,\n\t}: {\n\t\tmetric.WithAttributeSet(attribute.NewSet(\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanParentOrigin(otelconv.SpanParentOriginLocal),\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanSamplingResult(otelconv.SpanSamplingResultRecordAndSample),\n\t\t)),\n\t},\n\t{\n\t\tparentStateRemoteParent,\n\t\tsamplingStateRecordAndSample,\n\t}: {\n\t\tmetric.WithAttributeSet(attribute.NewSet(\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanParentOrigin(otelconv.SpanParentOriginRemote),\n\t\t\totelconv.SDKSpanStarted{}.AttrSpanSamplingResult(otelconv.SpanSamplingResultRecordAndSample),\n\t\t)),\n\t},\n}\n\ntype spanLiveKey struct {\n\tsampled bool\n}\n\nvar spanLiveOpts = map[spanLiveKey][]metric.AddOption{\n\t{true}: {\n\t\tmetric.WithAttributeSet(attribute.NewSet(\n\t\t\totelconv.SDKSpanLive{}.AttrSpanSamplingResult(\n\t\t\t\totelconv.SpanSamplingResultRecordAndSample,\n\t\t\t),\n\t\t)),\n\t},\n\t{false}: {\n\t\tmetric.WithAttributeSet(attribute.NewSet(\n\t\t\totelconv.SDKSpanLive{}.AttrSpanSamplingResult(\n\t\t\t\totelconv.SpanSamplingResultRecordOnly,\n\t\t\t),\n\t\t)),\n\t},\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/link.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/sdk/trace\"\n\nimport (\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\n// Link is the relationship between two Spans. The relationship can be within\n// the same Trace or across different Traces.\ntype Link struct {\n\t// SpanContext of the linked Span.\n\tSpanContext trace.SpanContext\n\n\t// Attributes describe the aspects of the link.\n\tAttributes []attribute.KeyValue\n\n\t// DroppedAttributeCount is the number of attributes that were not\n\t// recorded due to configured limits being reached.\n\tDroppedAttributeCount int\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/provider.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/sdk/trace\"\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\t\"go.opentelemetry.io/otel\"\n\t\"go.opentelemetry.io/otel/internal/global\"\n\t\"go.opentelemetry.io/otel/sdk/instrumentation\"\n\t\"go.opentelemetry.io/otel/sdk/resource\"\n\t\"go.opentelemetry.io/otel/sdk/trace/internal/observ\"\n\t\"go.opentelemetry.io/otel/trace\"\n\t\"go.opentelemetry.io/otel/trace/embedded\"\n\t\"go.opentelemetry.io/otel/trace/noop\"\n)\n\nconst defaultTracerName = \"go.opentelemetry.io/otel/sdk/tracer\"\n\n// tracerProviderConfig.\ntype tracerProviderConfig struct {\n\t// processors contains collection of SpanProcessors that are processing pipeline\n\t// for spans in the trace signal.\n\t// SpanProcessors registered with a TracerProvider and are called at the start\n\t// and end of a Span's lifecycle, and are called in the order they are\n\t// registered.\n\tprocessors []SpanProcessor\n\n\t// sampler is the default sampler used when creating new spans.\n\tsampler Sampler\n\n\t// idGenerator is used to generate all Span and Trace IDs when needed.\n\tidGenerator IDGenerator\n\n\t// spanLimits defines the attribute, event, and link limits for spans.\n\tspanLimits SpanLimits\n\n\t// resource contains attributes representing an entity that produces telemetry.\n\tresource *resource.Resource\n}\n\n// MarshalLog is the marshaling function used by the logging system to represent this Provider.\nfunc (cfg tracerProviderConfig) MarshalLog() any {\n\treturn struct {\n\t\tSpanProcessors  []SpanProcessor\n\t\tSamplerType     string\n\t\tIDGeneratorType string\n\t\tSpanLimits      SpanLimits\n\t\tResource        *resource.Resource\n\t}{\n\t\tSpanProcessors:  cfg.processors,\n\t\tSamplerType:     fmt.Sprintf(\"%T\", cfg.sampler),\n\t\tIDGeneratorType: fmt.Sprintf(\"%T\", cfg.idGenerator),\n\t\tSpanLimits:      cfg.spanLimits,\n\t\tResource:        cfg.resource,\n\t}\n}\n\n// TracerProvider is an OpenTelemetry TracerProvider. It provides Tracers to\n// instrumentation so it can trace operational flow through a system.\ntype TracerProvider struct {\n\tembedded.TracerProvider\n\n\tmu             sync.Mutex\n\tnamedTracer    map[instrumentation.Scope]*tracer\n\tspanProcessors atomic.Pointer[spanProcessorStates]\n\n\tisShutdown atomic.Bool\n\n\t// These fields are not protected by the lock mu. They are assumed to be\n\t// immutable after creation of the TracerProvider.\n\tsampler     Sampler\n\tidGenerator IDGenerator\n\tspanLimits  SpanLimits\n\tresource    *resource.Resource\n}\n\nvar _ trace.TracerProvider = &TracerProvider{}\n\n// NewTracerProvider returns a new and configured TracerProvider.\n//\n// By default the returned TracerProvider is configured with:\n//   - a ParentBased(AlwaysSample) Sampler\n//   - a random number IDGenerator\n//   - the resource.Default() Resource\n//   - the default SpanLimits.\n//\n// The passed opts are used to override these default values and configure the\n// returned TracerProvider appropriately.\nfunc NewTracerProvider(opts ...TracerProviderOption) *TracerProvider {\n\to := tracerProviderConfig{\n\t\tspanLimits: NewSpanLimits(),\n\t}\n\to = applyTracerProviderEnvConfigs(o)\n\n\tfor _, opt := range opts {\n\t\to = opt.apply(o)\n\t}\n\n\to = ensureValidTracerProviderConfig(o)\n\n\ttp := &TracerProvider{\n\t\tnamedTracer: make(map[instrumentation.Scope]*tracer),\n\t\tsampler:     o.sampler,\n\t\tidGenerator: o.idGenerator,\n\t\tspanLimits:  o.spanLimits,\n\t\tresource:    o.resource,\n\t}\n\tglobal.Info(\"TracerProvider created\", \"config\", o)\n\n\tspss := make(spanProcessorStates, 0, len(o.processors))\n\tfor _, sp := range o.processors {\n\t\tspss = append(spss, newSpanProcessorState(sp))\n\t}\n\ttp.spanProcessors.Store(&spss)\n\n\treturn tp\n}\n\n// Tracer returns a Tracer with the given name and options. If a Tracer for\n// the given name and options does not exist it is created, otherwise the\n// existing Tracer is returned.\n//\n// If name is empty, DefaultTracerName is used instead.\n//\n// This method is safe to be called concurrently.\nfunc (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer {\n\t// This check happens before the mutex is acquired to avoid deadlocking if Tracer() is called from within Shutdown().\n\tif p.isShutdown.Load() {\n\t\treturn noop.NewTracerProvider().Tracer(name, opts...)\n\t}\n\tc := trace.NewTracerConfig(opts...)\n\tif name == \"\" {\n\t\tname = defaultTracerName\n\t}\n\tis := instrumentation.Scope{\n\t\tName:       name,\n\t\tVersion:    c.InstrumentationVersion(),\n\t\tSchemaURL:  c.SchemaURL(),\n\t\tAttributes: c.InstrumentationAttributes(),\n\t}\n\n\tt, ok := func() (trace.Tracer, bool) {\n\t\tp.mu.Lock()\n\t\tdefer p.mu.Unlock()\n\t\t// Must check the flag after acquiring the mutex to avoid returning a valid tracer if Shutdown() ran\n\t\t// after the first check above but before we acquired the mutex.\n\t\tif p.isShutdown.Load() {\n\t\t\treturn noop.NewTracerProvider().Tracer(name, opts...), true\n\t\t}\n\t\tt, ok := p.namedTracer[is]\n\t\tif !ok {\n\t\t\tt = &tracer{\n\t\t\t\tprovider:             p,\n\t\t\t\tinstrumentationScope: is,\n\t\t\t}\n\n\t\t\tvar err error\n\t\t\tt.inst, err = observ.NewTracer()\n\t\t\tif err != nil {\n\t\t\t\totel.Handle(err)\n\t\t\t}\n\n\t\t\tp.namedTracer[is] = t\n\t\t}\n\t\treturn t, ok\n\t}()\n\tif !ok {\n\t\t// This code is outside the mutex to not hold the lock while calling third party logging code:\n\t\t// - That code may do slow things like I/O, which would prolong the duration the lock is held,\n\t\t//   slowing down all tracing consumers.\n\t\t// - Logging code may be instrumented with tracing and deadlock because it could try\n\t\t//   acquiring the same non-reentrant mutex.\n\t\tglobal.Info(\n\t\t\t\"Tracer created\",\n\t\t\t\"name\",\n\t\t\tname,\n\t\t\t\"version\",\n\t\t\tis.Version,\n\t\t\t\"schemaURL\",\n\t\t\tis.SchemaURL,\n\t\t\t\"attributes\",\n\t\t\tis.Attributes,\n\t\t)\n\t}\n\treturn t\n}\n\n// RegisterSpanProcessor adds the given SpanProcessor to the list of SpanProcessors.\nfunc (p *TracerProvider) RegisterSpanProcessor(sp SpanProcessor) {\n\t// This check prevents calls during a shutdown.\n\tif p.isShutdown.Load() {\n\t\treturn\n\t}\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\t// This check prevents calls after a shutdown.\n\tif p.isShutdown.Load() {\n\t\treturn\n\t}\n\n\tcurrent := p.getSpanProcessors()\n\tnewSPS := make(spanProcessorStates, 0, len(current)+1)\n\tnewSPS = append(newSPS, current...)\n\tnewSPS = append(newSPS, newSpanProcessorState(sp))\n\tp.spanProcessors.Store(&newSPS)\n}\n\n// UnregisterSpanProcessor removes the given SpanProcessor from the list of SpanProcessors.\nfunc (p *TracerProvider) UnregisterSpanProcessor(sp SpanProcessor) {\n\t// This check prevents calls during a shutdown.\n\tif p.isShutdown.Load() {\n\t\treturn\n\t}\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\t// This check prevents calls after a shutdown.\n\tif p.isShutdown.Load() {\n\t\treturn\n\t}\n\told := p.getSpanProcessors()\n\tif len(old) == 0 {\n\t\treturn\n\t}\n\tspss := make(spanProcessorStates, len(old))\n\tcopy(spss, old)\n\n\t// stop the span processor if it is started and remove it from the list\n\tvar stopOnce *spanProcessorState\n\tvar idx int\n\tfor i, sps := range spss {\n\t\tif sps.sp == sp {\n\t\t\tstopOnce = sps\n\t\t\tidx = i\n\t\t}\n\t}\n\tif stopOnce != nil {\n\t\tstopOnce.state.Do(func() {\n\t\t\tif err := sp.Shutdown(context.Background()); err != nil {\n\t\t\t\totel.Handle(err)\n\t\t\t}\n\t\t})\n\t}\n\tif len(spss) > 1 {\n\t\tcopy(spss[idx:], spss[idx+1:])\n\t}\n\tspss[len(spss)-1] = nil\n\tspss = spss[:len(spss)-1]\n\n\tp.spanProcessors.Store(&spss)\n}\n\n// ForceFlush immediately exports all spans that have not yet been exported for\n// all the registered span processors.\nfunc (p *TracerProvider) ForceFlush(ctx context.Context) error {\n\tspss := p.getSpanProcessors()\n\tif len(spss) == 0 {\n\t\treturn nil\n\t}\n\n\tfor _, sps := range spss {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tdefault:\n\t\t}\n\n\t\tif err := sps.sp.ForceFlush(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// Shutdown shuts down TracerProvider. All registered span processors are shut down\n// in the order they were registered and any held computational resources are released.\n// After Shutdown is called, all methods are no-ops.\nfunc (p *TracerProvider) Shutdown(ctx context.Context) error {\n\t// This check prevents deadlocks in case of recursive shutdown.\n\tif p.isShutdown.Load() {\n\t\treturn nil\n\t}\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\t// This check prevents calls after a shutdown has already been done concurrently.\n\tif !p.isShutdown.CompareAndSwap(false, true) { // did toggle?\n\t\treturn nil\n\t}\n\n\tvar retErr error\n\tfor _, sps := range p.getSpanProcessors() {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tdefault:\n\t\t}\n\n\t\tvar err error\n\t\tsps.state.Do(func() {\n\t\t\terr = sps.sp.Shutdown(ctx)\n\t\t})\n\t\tif err != nil {\n\t\t\tif retErr == nil {\n\t\t\t\tretErr = err\n\t\t\t} else {\n\t\t\t\t// Poor man's list of errors\n\t\t\t\tretErr = fmt.Errorf(\"%w; %w\", retErr, err)\n\t\t\t}\n\t\t}\n\t}\n\tp.spanProcessors.Store(&spanProcessorStates{})\n\treturn retErr\n}\n\nfunc (p *TracerProvider) getSpanProcessors() spanProcessorStates {\n\treturn *(p.spanProcessors.Load())\n}\n\n// TracerProviderOption configures a TracerProvider.\ntype TracerProviderOption interface {\n\tapply(tracerProviderConfig) tracerProviderConfig\n}\n\ntype traceProviderOptionFunc func(tracerProviderConfig) tracerProviderConfig\n\nfunc (fn traceProviderOptionFunc) apply(cfg tracerProviderConfig) tracerProviderConfig {\n\treturn fn(cfg)\n}\n\n// WithSyncer registers the exporter with the TracerProvider using a\n// SimpleSpanProcessor.\n//\n// This is not recommended for production use. The synchronous nature of the\n// SimpleSpanProcessor that will wrap the exporter make it good for testing,\n// debugging, or showing examples of other feature, but it will be slow and\n// have a high computation resource usage overhead. The WithBatcher option is\n// recommended for production use instead.\nfunc WithSyncer(e SpanExporter) TracerProviderOption {\n\treturn WithSpanProcessor(NewSimpleSpanProcessor(e))\n}\n\n// WithBatcher registers the exporter with the TracerProvider using a\n// BatchSpanProcessor configured with the passed opts.\nfunc WithBatcher(e SpanExporter, opts ...BatchSpanProcessorOption) TracerProviderOption {\n\treturn WithSpanProcessor(NewBatchSpanProcessor(e, opts...))\n}\n\n// WithSpanProcessor registers the SpanProcessor with a TracerProvider.\nfunc WithSpanProcessor(sp SpanProcessor) TracerProviderOption {\n\treturn traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig {\n\t\tcfg.processors = append(cfg.processors, sp)\n\t\treturn cfg\n\t})\n}\n\n// WithResource returns a TracerProviderOption that will configure the\n// Resource r as a TracerProvider's Resource. The configured Resource is\n// referenced by all the Tracers the TracerProvider creates. It represents the\n// entity producing telemetry.\n//\n// If this option is not used, the TracerProvider will use the\n// resource.Default() Resource by default.\nfunc WithResource(r *resource.Resource) TracerProviderOption {\n\treturn traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig {\n\t\tvar err error\n\t\tcfg.resource, err = resource.Merge(resource.Environment(), r)\n\t\tif err != nil {\n\t\t\totel.Handle(err)\n\t\t}\n\t\treturn cfg\n\t})\n}\n\n// WithIDGenerator returns a TracerProviderOption that will configure the\n// IDGenerator g as a TracerProvider's IDGenerator. The configured IDGenerator\n// is used by the Tracers the TracerProvider creates to generate new Span and\n// Trace IDs.\n//\n// If this option is not used, the TracerProvider will use a random number\n// IDGenerator by default.\nfunc WithIDGenerator(g IDGenerator) TracerProviderOption {\n\treturn traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig {\n\t\tif g != nil {\n\t\t\tcfg.idGenerator = g\n\t\t}\n\t\treturn cfg\n\t})\n}\n\n// WithSampler returns a TracerProviderOption that will configure the Sampler\n// s as a TracerProvider's Sampler. The configured Sampler is used by the\n// Tracers the TracerProvider creates to make their sampling decisions for the\n// Spans they create.\n//\n// This option overrides the Sampler configured through the OTEL_TRACES_SAMPLER\n// and OTEL_TRACES_SAMPLER_ARG environment variables. If this option is not used\n// and the sampler is not configured through environment variables or the environment\n// contains invalid/unsupported configuration, the TracerProvider will use a\n// ParentBased(AlwaysSample) Sampler by default.\nfunc WithSampler(s Sampler) TracerProviderOption {\n\treturn traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig {\n\t\tif s != nil {\n\t\t\tcfg.sampler = s\n\t\t}\n\t\treturn cfg\n\t})\n}\n\n// WithSpanLimits returns a TracerProviderOption that configures a\n// TracerProvider to use the SpanLimits sl. These SpanLimits bound any Span\n// created by a Tracer from the TracerProvider.\n//\n// If any field of sl is zero or negative it will be replaced with the default\n// value for that field.\n//\n// If this or WithRawSpanLimits are not provided, the TracerProvider will use\n// the limits defined by environment variables, or the defaults if unset.\n// Refer to the NewSpanLimits documentation for information about this\n// relationship.\n//\n// Deprecated: Use WithRawSpanLimits instead which allows setting unlimited\n// and zero limits. This option will be kept until the next major version\n// incremented release.\nfunc WithSpanLimits(sl SpanLimits) TracerProviderOption {\n\tif sl.AttributeValueLengthLimit <= 0 {\n\t\tsl.AttributeValueLengthLimit = DefaultAttributeValueLengthLimit\n\t}\n\tif sl.AttributeCountLimit <= 0 {\n\t\tsl.AttributeCountLimit = DefaultAttributeCountLimit\n\t}\n\tif sl.EventCountLimit <= 0 {\n\t\tsl.EventCountLimit = DefaultEventCountLimit\n\t}\n\tif sl.AttributePerEventCountLimit <= 0 {\n\t\tsl.AttributePerEventCountLimit = DefaultAttributePerEventCountLimit\n\t}\n\tif sl.LinkCountLimit <= 0 {\n\t\tsl.LinkCountLimit = DefaultLinkCountLimit\n\t}\n\tif sl.AttributePerLinkCountLimit <= 0 {\n\t\tsl.AttributePerLinkCountLimit = DefaultAttributePerLinkCountLimit\n\t}\n\treturn traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig {\n\t\tcfg.spanLimits = sl\n\t\treturn cfg\n\t})\n}\n\n// WithRawSpanLimits returns a TracerProviderOption that configures a\n// TracerProvider to use these limits. These limits bound any Span created by\n// a Tracer from the TracerProvider.\n//\n// The limits will be used as-is. Zero or negative values will not be changed\n// to the default value like WithSpanLimits does. Setting a limit to zero will\n// effectively disable the related resource it limits and setting to a\n// negative value will mean that resource is unlimited. Consequentially, this\n// means that the zero-value SpanLimits will disable all span resources.\n// Because of this, limits should be constructed using NewSpanLimits and\n// updated accordingly.\n//\n// If this or WithSpanLimits are not provided, the TracerProvider will use the\n// limits defined by environment variables, or the defaults if unset. Refer to\n// the NewSpanLimits documentation for information about this relationship.\nfunc WithRawSpanLimits(limits SpanLimits) TracerProviderOption {\n\treturn traceProviderOptionFunc(func(cfg tracerProviderConfig) tracerProviderConfig {\n\t\tcfg.spanLimits = limits\n\t\treturn cfg\n\t})\n}\n\nfunc applyTracerProviderEnvConfigs(cfg tracerProviderConfig) tracerProviderConfig {\n\tfor _, opt := range tracerProviderOptionsFromEnv() {\n\t\tcfg = opt.apply(cfg)\n\t}\n\n\treturn cfg\n}\n\nfunc tracerProviderOptionsFromEnv() []TracerProviderOption {\n\tvar opts []TracerProviderOption\n\n\tsampler, err := samplerFromEnv()\n\tif err != nil {\n\t\totel.Handle(err)\n\t}\n\n\tif sampler != nil {\n\t\topts = append(opts, WithSampler(sampler))\n\t}\n\n\treturn opts\n}\n\n// ensureValidTracerProviderConfig ensures that given TracerProviderConfig is valid.\nfunc ensureValidTracerProviderConfig(cfg tracerProviderConfig) tracerProviderConfig {\n\tif cfg.sampler == nil {\n\t\tcfg.sampler = ParentBased(AlwaysSample())\n\t}\n\tif cfg.idGenerator == nil {\n\t\tcfg.idGenerator = defaultIDGenerator()\n\t}\n\tif cfg.resource == nil {\n\t\tcfg.resource = resource.Default()\n\t}\n\treturn cfg\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/sampler_env.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/sdk/trace\"\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nconst (\n\ttracesSamplerKey    = \"OTEL_TRACES_SAMPLER\"\n\ttracesSamplerArgKey = \"OTEL_TRACES_SAMPLER_ARG\"\n\n\tsamplerAlwaysOn                = \"always_on\"\n\tsamplerAlwaysOff               = \"always_off\"\n\tsamplerTraceIDRatio            = \"traceidratio\"\n\tsamplerParentBasedAlwaysOn     = \"parentbased_always_on\"\n\tsamplerParsedBasedAlwaysOff    = \"parentbased_always_off\"\n\tsamplerParentBasedTraceIDRatio = \"parentbased_traceidratio\"\n)\n\ntype errUnsupportedSampler string\n\nfunc (e errUnsupportedSampler) Error() string {\n\treturn \"unsupported sampler: \" + string(e)\n}\n\nvar (\n\terrNegativeTraceIDRatio       = errors.New(\"invalid trace ID ratio: less than 0.0\")\n\terrGreaterThanOneTraceIDRatio = errors.New(\"invalid trace ID ratio: greater than 1.0\")\n)\n\ntype samplerArgParseError struct {\n\tparseErr error\n}\n\nfunc (e samplerArgParseError) Error() string {\n\treturn \"parsing sampler argument: \" + e.parseErr.Error()\n}\n\nfunc (e samplerArgParseError) Unwrap() error {\n\treturn e.parseErr\n}\n\nfunc samplerFromEnv() (Sampler, error) {\n\tsampler, ok := os.LookupEnv(tracesSamplerKey)\n\tif !ok {\n\t\treturn nil, nil\n\t}\n\n\tsampler = strings.ToLower(strings.TrimSpace(sampler))\n\tsamplerArg, hasSamplerArg := os.LookupEnv(tracesSamplerArgKey)\n\tsamplerArg = strings.TrimSpace(samplerArg)\n\n\tswitch sampler {\n\tcase samplerAlwaysOn:\n\t\treturn AlwaysSample(), nil\n\tcase samplerAlwaysOff:\n\t\treturn NeverSample(), nil\n\tcase samplerTraceIDRatio:\n\t\tif !hasSamplerArg {\n\t\t\treturn TraceIDRatioBased(1.0), nil\n\t\t}\n\t\treturn parseTraceIDRatio(samplerArg)\n\tcase samplerParentBasedAlwaysOn:\n\t\treturn ParentBased(AlwaysSample()), nil\n\tcase samplerParsedBasedAlwaysOff:\n\t\treturn ParentBased(NeverSample()), nil\n\tcase samplerParentBasedTraceIDRatio:\n\t\tif !hasSamplerArg {\n\t\t\treturn ParentBased(TraceIDRatioBased(1.0)), nil\n\t\t}\n\t\tratio, err := parseTraceIDRatio(samplerArg)\n\t\treturn ParentBased(ratio), err\n\tdefault:\n\t\treturn nil, errUnsupportedSampler(sampler)\n\t}\n}\n\nfunc parseTraceIDRatio(arg string) (Sampler, error) {\n\tv, err := strconv.ParseFloat(arg, 64)\n\tif err != nil {\n\t\treturn TraceIDRatioBased(1.0), samplerArgParseError{err}\n\t}\n\tif v < 0.0 {\n\t\treturn TraceIDRatioBased(1.0), errNegativeTraceIDRatio\n\t}\n\tif v > 1.0 {\n\t\treturn TraceIDRatioBased(1.0), errGreaterThanOneTraceIDRatio\n\t}\n\n\treturn TraceIDRatioBased(v), nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/sampling.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/sdk/trace\"\n\nimport (\n\t\"context\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\n// Sampler decides whether a trace should be sampled and exported.\ntype Sampler interface {\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// ShouldSample returns a SamplingResult based on a decision made from the\n\t// passed parameters.\n\tShouldSample(parameters SamplingParameters) SamplingResult\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Description returns information describing the Sampler.\n\tDescription() string\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n}\n\n// SamplingParameters contains the values passed to a Sampler.\ntype SamplingParameters struct {\n\tParentContext context.Context\n\tTraceID       trace.TraceID\n\tName          string\n\tKind          trace.SpanKind\n\tAttributes    []attribute.KeyValue\n\tLinks         []trace.Link\n}\n\n// SamplingDecision indicates whether a span is dropped, recorded and/or sampled.\ntype SamplingDecision uint8\n\n// Valid sampling decisions.\nconst (\n\t// Drop will not record the span and all attributes/events will be dropped.\n\tDrop SamplingDecision = iota\n\n\t// RecordOnly indicates the span's IsRecording method returns true, but trace.FlagsSampled flag\n\t// must not be set.\n\tRecordOnly\n\n\t// RecordAndSample indicates the span's IsRecording method returns true and trace.FlagsSampled flag\n\t// must be set.\n\tRecordAndSample\n)\n\n// SamplingResult conveys a SamplingDecision, set of Attributes and a Tracestate.\ntype SamplingResult struct {\n\tDecision   SamplingDecision\n\tAttributes []attribute.KeyValue\n\tTracestate trace.TraceState\n}\n\ntype traceIDRatioSampler struct {\n\ttraceIDUpperBound uint64\n\tdescription       string\n}\n\nfunc (ts traceIDRatioSampler) ShouldSample(p SamplingParameters) SamplingResult {\n\tpsc := trace.SpanContextFromContext(p.ParentContext)\n\tx := binary.BigEndian.Uint64(p.TraceID[8:16]) >> 1\n\tif x < ts.traceIDUpperBound {\n\t\treturn SamplingResult{\n\t\t\tDecision:   RecordAndSample,\n\t\t\tTracestate: psc.TraceState(),\n\t\t}\n\t}\n\treturn SamplingResult{\n\t\tDecision:   Drop,\n\t\tTracestate: psc.TraceState(),\n\t}\n}\n\nfunc (ts traceIDRatioSampler) Description() string {\n\treturn ts.description\n}\n\n// TraceIDRatioBased samples a given fraction of traces. Fractions >= 1 will\n// always sample. Fractions < 0 are treated as zero. To respect the\n// parent trace's `SampledFlag`, the `TraceIDRatioBased` sampler should be used\n// as a delegate of a `Parent` sampler.\n//\n//nolint:revive // revive complains about stutter of `trace.TraceIDRatioBased`\nfunc TraceIDRatioBased(fraction float64) Sampler {\n\tif fraction >= 1 {\n\t\treturn AlwaysSample()\n\t}\n\n\tif fraction <= 0 {\n\t\tfraction = 0\n\t}\n\n\treturn &traceIDRatioSampler{\n\t\ttraceIDUpperBound: uint64(fraction * (1 << 63)),\n\t\tdescription:       fmt.Sprintf(\"TraceIDRatioBased{%g}\", fraction),\n\t}\n}\n\ntype alwaysOnSampler struct{}\n\nfunc (alwaysOnSampler) ShouldSample(p SamplingParameters) SamplingResult {\n\treturn SamplingResult{\n\t\tDecision:   RecordAndSample,\n\t\tTracestate: trace.SpanContextFromContext(p.ParentContext).TraceState(),\n\t}\n}\n\nfunc (alwaysOnSampler) Description() string {\n\treturn \"AlwaysOnSampler\"\n}\n\n// AlwaysSample returns a Sampler that samples every trace.\n// Be careful about using this sampler in a production application with\n// significant traffic: a new trace will be started and exported for every\n// request.\nfunc AlwaysSample() Sampler {\n\treturn alwaysOnSampler{}\n}\n\ntype alwaysOffSampler struct{}\n\nfunc (alwaysOffSampler) ShouldSample(p SamplingParameters) SamplingResult {\n\treturn SamplingResult{\n\t\tDecision:   Drop,\n\t\tTracestate: trace.SpanContextFromContext(p.ParentContext).TraceState(),\n\t}\n}\n\nfunc (alwaysOffSampler) Description() string {\n\treturn \"AlwaysOffSampler\"\n}\n\n// NeverSample returns a Sampler that samples no traces.\nfunc NeverSample() Sampler {\n\treturn alwaysOffSampler{}\n}\n\n// ParentBased returns a sampler decorator which behaves differently,\n// based on the parent of the span. If the span has no parent,\n// the decorated sampler is used to make sampling decision. If the span has\n// a parent, depending on whether the parent is remote and whether it\n// is sampled, one of the following samplers will apply:\n//   - remoteParentSampled(Sampler) (default: AlwaysOn)\n//   - remoteParentNotSampled(Sampler) (default: AlwaysOff)\n//   - localParentSampled(Sampler) (default: AlwaysOn)\n//   - localParentNotSampled(Sampler) (default: AlwaysOff)\nfunc ParentBased(root Sampler, samplers ...ParentBasedSamplerOption) Sampler {\n\treturn parentBased{\n\t\troot:   root,\n\t\tconfig: configureSamplersForParentBased(samplers),\n\t}\n}\n\ntype parentBased struct {\n\troot   Sampler\n\tconfig samplerConfig\n}\n\nfunc configureSamplersForParentBased(samplers []ParentBasedSamplerOption) samplerConfig {\n\tc := samplerConfig{\n\t\tremoteParentSampled:    AlwaysSample(),\n\t\tremoteParentNotSampled: NeverSample(),\n\t\tlocalParentSampled:     AlwaysSample(),\n\t\tlocalParentNotSampled:  NeverSample(),\n\t}\n\n\tfor _, so := range samplers {\n\t\tc = so.apply(c)\n\t}\n\n\treturn c\n}\n\n// samplerConfig is a group of options for parentBased sampler.\ntype samplerConfig struct {\n\tremoteParentSampled, remoteParentNotSampled Sampler\n\tlocalParentSampled, localParentNotSampled   Sampler\n}\n\n// ParentBasedSamplerOption configures the sampler for a particular sampling case.\ntype ParentBasedSamplerOption interface {\n\tapply(samplerConfig) samplerConfig\n}\n\n// WithRemoteParentSampled sets the sampler for the case of sampled remote parent.\nfunc WithRemoteParentSampled(s Sampler) ParentBasedSamplerOption {\n\treturn remoteParentSampledOption{s}\n}\n\ntype remoteParentSampledOption struct {\n\ts Sampler\n}\n\nfunc (o remoteParentSampledOption) apply(config samplerConfig) samplerConfig {\n\tconfig.remoteParentSampled = o.s\n\treturn config\n}\n\n// WithRemoteParentNotSampled sets the sampler for the case of remote parent\n// which is not sampled.\nfunc WithRemoteParentNotSampled(s Sampler) ParentBasedSamplerOption {\n\treturn remoteParentNotSampledOption{s}\n}\n\ntype remoteParentNotSampledOption struct {\n\ts Sampler\n}\n\nfunc (o remoteParentNotSampledOption) apply(config samplerConfig) samplerConfig {\n\tconfig.remoteParentNotSampled = o.s\n\treturn config\n}\n\n// WithLocalParentSampled sets the sampler for the case of sampled local parent.\nfunc WithLocalParentSampled(s Sampler) ParentBasedSamplerOption {\n\treturn localParentSampledOption{s}\n}\n\ntype localParentSampledOption struct {\n\ts Sampler\n}\n\nfunc (o localParentSampledOption) apply(config samplerConfig) samplerConfig {\n\tconfig.localParentSampled = o.s\n\treturn config\n}\n\n// WithLocalParentNotSampled sets the sampler for the case of local parent\n// which is not sampled.\nfunc WithLocalParentNotSampled(s Sampler) ParentBasedSamplerOption {\n\treturn localParentNotSampledOption{s}\n}\n\ntype localParentNotSampledOption struct {\n\ts Sampler\n}\n\nfunc (o localParentNotSampledOption) apply(config samplerConfig) samplerConfig {\n\tconfig.localParentNotSampled = o.s\n\treturn config\n}\n\nfunc (pb parentBased) ShouldSample(p SamplingParameters) SamplingResult {\n\tpsc := trace.SpanContextFromContext(p.ParentContext)\n\tif psc.IsValid() {\n\t\tif psc.IsRemote() {\n\t\t\tif psc.IsSampled() {\n\t\t\t\treturn pb.config.remoteParentSampled.ShouldSample(p)\n\t\t\t}\n\t\t\treturn pb.config.remoteParentNotSampled.ShouldSample(p)\n\t\t}\n\n\t\tif psc.IsSampled() {\n\t\t\treturn pb.config.localParentSampled.ShouldSample(p)\n\t\t}\n\t\treturn pb.config.localParentNotSampled.ShouldSample(p)\n\t}\n\treturn pb.root.ShouldSample(p)\n}\n\nfunc (pb parentBased) Description() string {\n\treturn fmt.Sprintf(\"ParentBased{root:%s,remoteParentSampled:%s,\"+\n\t\t\"remoteParentNotSampled:%s,localParentSampled:%s,localParentNotSampled:%s}\",\n\t\tpb.root.Description(),\n\t\tpb.config.remoteParentSampled.Description(),\n\t\tpb.config.remoteParentNotSampled.Description(),\n\t\tpb.config.localParentSampled.Description(),\n\t\tpb.config.localParentNotSampled.Description(),\n\t)\n}\n\n// AlwaysRecord returns a sampler decorator which ensures that every span\n// is passed to the SpanProcessor, even those that would be normally dropped.\n// It converts `Drop` decisions from the root sampler into `RecordOnly` decisions,\n// allowing processors to see all spans without sending them to exporters. This is\n// typically used to enable accurate span-to-metrics processing.\nfunc AlwaysRecord(root Sampler) Sampler {\n\treturn alwaysRecord{root}\n}\n\ntype alwaysRecord struct {\n\troot Sampler\n}\n\nfunc (ar alwaysRecord) ShouldSample(p SamplingParameters) SamplingResult {\n\trootSamplerSamplingResult := ar.root.ShouldSample(p)\n\tif rootSamplerSamplingResult.Decision == Drop {\n\t\treturn SamplingResult{\n\t\t\tDecision:   RecordOnly,\n\t\t\tTracestate: trace.SpanContextFromContext(p.ParentContext).TraceState(),\n\t\t}\n\t}\n\treturn rootSamplerSamplingResult\n}\n\nfunc (ar alwaysRecord) Description() string {\n\treturn \"AlwaysRecord{root:\" + ar.root.Description() + \"}\"\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/sdk/trace\"\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\t\"go.opentelemetry.io/otel\"\n\t\"go.opentelemetry.io/otel/internal/global\"\n\t\"go.opentelemetry.io/otel/sdk/trace/internal/observ\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\n// simpleSpanProcessor is a SpanProcessor that synchronously sends all\n// completed Spans to a trace.Exporter immediately.\ntype simpleSpanProcessor struct {\n\texporterMu sync.Mutex\n\texporter   SpanExporter\n\tstopOnce   sync.Once\n\n\tinst *observ.SSP\n}\n\nvar _ SpanProcessor = (*simpleSpanProcessor)(nil)\n\n// NewSimpleSpanProcessor returns a new SpanProcessor that will synchronously\n// send completed spans to the exporter immediately.\n//\n// This SpanProcessor is not recommended for production use. The synchronous\n// nature of this SpanProcessor makes it good for testing, debugging, or showing\n// examples of other features, but it will be slow and have a high computation\n// resource usage overhead. The BatchSpanProcessor is recommended for production\n// use instead.\nfunc NewSimpleSpanProcessor(exporter SpanExporter) SpanProcessor {\n\tssp := &simpleSpanProcessor{\n\t\texporter: exporter,\n\t}\n\n\tvar err error\n\tssp.inst, err = observ.NewSSP(nextSimpleProcessorID())\n\tif err != nil {\n\t\totel.Handle(err)\n\t}\n\n\tglobal.Warn(\"SimpleSpanProcessor is not recommended for production use, consider using BatchSpanProcessor instead.\")\n\n\treturn ssp\n}\n\nvar simpleProcessorIDCounter atomic.Int64\n\n// nextSimpleProcessorID returns an identifier for this simple span processor,\n// starting with 0 and incrementing by 1 each time it is called.\nfunc nextSimpleProcessorID() int64 {\n\treturn simpleProcessorIDCounter.Add(1) - 1\n}\n\n// OnStart does nothing.\nfunc (*simpleSpanProcessor) OnStart(context.Context, ReadWriteSpan) {}\n\n// OnEnd immediately exports a ReadOnlySpan.\nfunc (ssp *simpleSpanProcessor) OnEnd(s ReadOnlySpan) {\n\tssp.exporterMu.Lock()\n\tdefer ssp.exporterMu.Unlock()\n\n\tvar err error\n\tif ssp.exporter != nil && s.SpanContext().TraceFlags().IsSampled() {\n\t\terr = ssp.exporter.ExportSpans(context.Background(), []ReadOnlySpan{s})\n\t\tif err != nil {\n\t\t\totel.Handle(err)\n\t\t}\n\t}\n\n\tif ssp.inst != nil {\n\t\t// Add the span to the context to ensure the metric is recorded\n\t\t// with the correct span context.\n\t\tctx := trace.ContextWithSpanContext(context.Background(), s.SpanContext())\n\t\tssp.inst.SpanProcessed(ctx, err)\n\t}\n}\n\n// Shutdown shuts down the exporter this SimpleSpanProcessor exports to.\nfunc (ssp *simpleSpanProcessor) Shutdown(ctx context.Context) error {\n\tvar err error\n\tssp.stopOnce.Do(func() {\n\t\tstopFunc := func(exp SpanExporter) (<-chan error, func()) {\n\t\t\tdone := make(chan error, 1)\n\t\t\treturn done, func() { done <- exp.Shutdown(ctx) }\n\t\t}\n\n\t\t// The exporter field of the simpleSpanProcessor needs to be zeroed to\n\t\t// signal it is shut down, meaning all subsequent calls to OnEnd will\n\t\t// be gracefully ignored. This needs to be done synchronously to avoid\n\t\t// any race condition.\n\t\t//\n\t\t// A closure is used to keep reference to the exporter and then the\n\t\t// field is zeroed. This ensures the simpleSpanProcessor is shut down\n\t\t// before the exporter. This order is important as it avoids a potential\n\t\t// deadlock. If the exporter shut down operation generates a span, that\n\t\t// span would need to be exported. Meaning, OnEnd would be called and\n\t\t// try acquiring the lock that is held here.\n\t\tssp.exporterMu.Lock()\n\t\tdone, shutdown := stopFunc(ssp.exporter)\n\t\tssp.exporter = nil\n\t\tssp.exporterMu.Unlock()\n\n\t\tgo shutdown()\n\n\t\t// Wait for the exporter to shut down or the deadline to expire.\n\t\tselect {\n\t\tcase err = <-done:\n\t\tcase <-ctx.Done():\n\t\t\t// It is possible for the exporter to have immediately shut down and\n\t\t\t// the context to be done simultaneously. In that case this outer\n\t\t\t// select statement will randomly choose a case. This will result in\n\t\t\t// a different returned error for similar scenarios. Instead, double\n\t\t\t// check if the exporter shut down at the same time and return that\n\t\t\t// error if so. This will ensure consistency as well as ensure\n\t\t\t// the caller knows the exporter shut down successfully (they can\n\t\t\t// already determine if the deadline is expired given they passed\n\t\t\t// the context).\n\t\t\tselect {\n\t\t\tcase err = <-done:\n\t\t\tdefault:\n\t\t\t\terr = ctx.Err()\n\t\t\t}\n\t\t}\n\t})\n\treturn err\n}\n\n// ForceFlush does nothing as there is no data to flush.\nfunc (*simpleSpanProcessor) ForceFlush(context.Context) error {\n\treturn nil\n}\n\n// MarshalLog is the marshaling function used by the logging system to represent\n// this Span Processor.\nfunc (ssp *simpleSpanProcessor) MarshalLog() any {\n\treturn struct {\n\t\tType     string\n\t\tExporter SpanExporter\n\t}{\n\t\tType:     \"SimpleSpanProcessor\",\n\t\tExporter: ssp.exporter,\n\t}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/snapshot.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/sdk/trace\"\n\nimport (\n\t\"time\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/sdk/instrumentation\"\n\t\"go.opentelemetry.io/otel/sdk/resource\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\n// snapshot is an record of a spans state at a particular checkpointed time.\n// It is used as a read-only representation of that state.\ntype snapshot struct {\n\tname                  string\n\tspanContext           trace.SpanContext\n\tparent                trace.SpanContext\n\tspanKind              trace.SpanKind\n\tstartTime             time.Time\n\tendTime               time.Time\n\tattributes            []attribute.KeyValue\n\tevents                []Event\n\tlinks                 []Link\n\tstatus                Status\n\tchildSpanCount        int\n\tdroppedAttributeCount int\n\tdroppedEventCount     int\n\tdroppedLinkCount      int\n\tresource              *resource.Resource\n\tinstrumentationScope  instrumentation.Scope\n}\n\nvar _ ReadOnlySpan = snapshot{}\n\nfunc (snapshot) private() {}\n\n// Name returns the name of the span.\nfunc (s snapshot) Name() string {\n\treturn s.name\n}\n\n// SpanContext returns the unique SpanContext that identifies the span.\nfunc (s snapshot) SpanContext() trace.SpanContext {\n\treturn s.spanContext\n}\n\n// Parent returns the unique SpanContext that identifies the parent of the\n// span if one exists. If the span has no parent the returned SpanContext\n// will be invalid.\nfunc (s snapshot) Parent() trace.SpanContext {\n\treturn s.parent\n}\n\n// SpanKind returns the role the span plays in a Trace.\nfunc (s snapshot) SpanKind() trace.SpanKind {\n\treturn s.spanKind\n}\n\n// StartTime returns the time the span started recording.\nfunc (s snapshot) StartTime() time.Time {\n\treturn s.startTime\n}\n\n// EndTime returns the time the span stopped recording. It will be zero if\n// the span has not ended.\nfunc (s snapshot) EndTime() time.Time {\n\treturn s.endTime\n}\n\n// Attributes returns the defining attributes of the span.\nfunc (s snapshot) Attributes() []attribute.KeyValue {\n\treturn s.attributes\n}\n\n// Links returns all the links the span has to other spans.\nfunc (s snapshot) Links() []Link {\n\treturn s.links\n}\n\n// Events returns all the events that occurred within in the spans\n// lifetime.\nfunc (s snapshot) Events() []Event {\n\treturn s.events\n}\n\n// Status returns the spans status.\nfunc (s snapshot) Status() Status {\n\treturn s.status\n}\n\n// InstrumentationScope returns information about the instrumentation\n// scope that created the span.\nfunc (s snapshot) InstrumentationScope() instrumentation.Scope {\n\treturn s.instrumentationScope\n}\n\n// InstrumentationLibrary returns information about the instrumentation\n// library that created the span.\nfunc (s snapshot) InstrumentationLibrary() instrumentation.Library { //nolint:staticcheck // This method needs to be define for backwards compatibility\n\treturn s.instrumentationScope\n}\n\n// Resource returns information about the entity that produced the span.\nfunc (s snapshot) Resource() *resource.Resource {\n\treturn s.resource\n}\n\n// DroppedAttributes returns the number of attributes dropped by the span\n// due to limits being reached.\nfunc (s snapshot) DroppedAttributes() int {\n\treturn s.droppedAttributeCount\n}\n\n// DroppedLinks returns the number of links dropped by the span due to limits\n// being reached.\nfunc (s snapshot) DroppedLinks() int {\n\treturn s.droppedLinkCount\n}\n\n// DroppedEvents returns the number of events dropped by the span due to\n// limits being reached.\nfunc (s snapshot) DroppedEvents() int {\n\treturn s.droppedEventCount\n}\n\n// ChildSpanCount returns the count of spans that consider the span a\n// direct parent.\nfunc (s snapshot) ChildSpanCount() int {\n\treturn s.childSpanCount\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/span.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/sdk/trace\"\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"runtime\"\n\trt \"runtime/trace\"\n\t\"slices\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\t\"unicode/utf8\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n\t\"go.opentelemetry.io/otel/internal/global\"\n\t\"go.opentelemetry.io/otel/sdk/instrumentation\"\n\t\"go.opentelemetry.io/otel/sdk/resource\"\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.39.0\"\n\t\"go.opentelemetry.io/otel/trace\"\n\t\"go.opentelemetry.io/otel/trace/embedded\"\n)\n\n// ReadOnlySpan allows reading information from the data structure underlying a\n// trace.Span. It is used in places where reading information from a span is\n// necessary but changing the span isn't necessary or allowed.\n//\n// Warning: methods may be added to this interface in minor releases.\ntype ReadOnlySpan interface {\n\t// Name returns the name of the span.\n\tName() string\n\t// SpanContext returns the unique SpanContext that identifies the span.\n\tSpanContext() trace.SpanContext\n\t// Parent returns the unique SpanContext that identifies the parent of the\n\t// span if one exists. If the span has no parent the returned SpanContext\n\t// will be invalid.\n\tParent() trace.SpanContext\n\t// SpanKind returns the role the span plays in a Trace.\n\tSpanKind() trace.SpanKind\n\t// StartTime returns the time the span started recording.\n\tStartTime() time.Time\n\t// EndTime returns the time the span stopped recording. It will be zero if\n\t// the span has not ended.\n\tEndTime() time.Time\n\t// Attributes returns the defining attributes of the span.\n\t// The order of the returned attributes is not guaranteed to be stable across invocations.\n\tAttributes() []attribute.KeyValue\n\t// Links returns all the links the span has to other spans.\n\tLinks() []Link\n\t// Events returns all the events that occurred within in the spans\n\t// lifetime.\n\tEvents() []Event\n\t// Status returns the spans status.\n\tStatus() Status\n\t// InstrumentationScope returns information about the instrumentation\n\t// scope that created the span.\n\tInstrumentationScope() instrumentation.Scope\n\t// InstrumentationLibrary returns information about the instrumentation\n\t// library that created the span.\n\t//\n\t// Deprecated: please use InstrumentationScope instead.\n\tInstrumentationLibrary() instrumentation.Library //nolint:staticcheck // This method needs to be define for backwards compatibility\n\t// Resource returns information about the entity that produced the span.\n\tResource() *resource.Resource\n\t// DroppedAttributes returns the number of attributes dropped by the span\n\t// due to limits being reached.\n\tDroppedAttributes() int\n\t// DroppedLinks returns the number of links dropped by the span due to\n\t// limits being reached.\n\tDroppedLinks() int\n\t// DroppedEvents returns the number of events dropped by the span due to\n\t// limits being reached.\n\tDroppedEvents() int\n\t// ChildSpanCount returns the count of spans that consider the span a\n\t// direct parent.\n\tChildSpanCount() int\n\n\t// A private method to prevent users implementing the\n\t// interface and so future additions to it will not\n\t// violate compatibility.\n\tprivate()\n}\n\n// ReadWriteSpan exposes the same methods as trace.Span and in addition allows\n// reading information from the underlying data structure.\n// This interface exposes the union of the methods of trace.Span (which is a\n// \"write-only\" span) and ReadOnlySpan. New methods for writing or reading span\n// information should be added under trace.Span or ReadOnlySpan, respectively.\n//\n// Warning: methods may be added to this interface in minor releases.\ntype ReadWriteSpan interface {\n\ttrace.Span\n\tReadOnlySpan\n}\n\n// recordingSpan is an implementation of the OpenTelemetry Span API\n// representing the individual component of a trace that is sampled.\ntype recordingSpan struct {\n\tembedded.Span\n\n\t// mu protects the contents of this span.\n\tmu sync.Mutex\n\n\t// parent holds the parent span of this span as a trace.SpanContext.\n\tparent trace.SpanContext\n\n\t// spanKind represents the kind of this span as a trace.SpanKind.\n\tspanKind trace.SpanKind\n\n\t// name is the name of this span.\n\tname string\n\n\t// startTime is the time at which this span was started.\n\tstartTime time.Time\n\n\t// endTime is the time at which this span was ended. It contains the zero\n\t// value of time.Time until the span is ended.\n\tendTime time.Time\n\n\t// status is the status of this span.\n\tstatus Status\n\n\t// childSpanCount holds the number of child spans created for this span.\n\tchildSpanCount int\n\n\t// spanContext holds the SpanContext of this span.\n\tspanContext trace.SpanContext\n\n\t// attributes is a collection of user provided key/values. The collection\n\t// is constrained by a configurable maximum held by the parent\n\t// TracerProvider. When additional attributes are added after this maximum\n\t// is reached these attributes the user is attempting to add are dropped.\n\t// This dropped number of attributes is tracked and reported in the\n\t// ReadOnlySpan exported when the span ends.\n\tattributes        []attribute.KeyValue\n\tdroppedAttributes int\n\tlogDropAttrsOnce  sync.Once\n\n\t// events are stored in FIFO queue capped by configured limit.\n\tevents evictedQueue[Event]\n\n\t// links are stored in FIFO queue capped by configured limit.\n\tlinks evictedQueue[Link]\n\n\t// executionTracerTaskEnd ends the execution tracer span.\n\texecutionTracerTaskEnd func()\n\n\t// tracer is the SDK tracer that created this span.\n\ttracer *tracer\n\n\t// origCtx is the context used when starting this span that has the\n\t// recordingSpan instance set as the active span. If not nil, it is used\n\t// when ending the span to ensure any metrics are recorded with a context\n\t// containing this span without requiring an additional allocation.\n\torigCtx context.Context\n}\n\nvar (\n\t_ ReadWriteSpan = (*recordingSpan)(nil)\n\t_ runtimeTracer = (*recordingSpan)(nil)\n)\n\nfunc (s *recordingSpan) setOrigCtx(ctx context.Context) {\n\ts.origCtx = ctx\n}\n\n// SpanContext returns the SpanContext of this span.\nfunc (s *recordingSpan) SpanContext() trace.SpanContext {\n\tif s == nil {\n\t\treturn trace.SpanContext{}\n\t}\n\treturn s.spanContext\n}\n\n// IsRecording reports whether this span is being recorded. If this span has ended\n// this will return false.\nfunc (s *recordingSpan) IsRecording() bool {\n\tif s == nil {\n\t\treturn false\n\t}\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\treturn s.isRecording()\n}\n\n// isRecording reports whether this span is being recorded. If this span has ended\n// this will return false.\n//\n// This method assumes s.mu.Lock is held by the caller.\nfunc (s *recordingSpan) isRecording() bool {\n\tif s == nil {\n\t\treturn false\n\t}\n\treturn s.endTime.IsZero()\n}\n\n// SetStatus sets the status of the Span in the form of a code and a\n// description, overriding previous values set. The description is only\n// included in the set status when the code is for an error. If this span is\n// not being recorded than this method does nothing.\nfunc (s *recordingSpan) SetStatus(code codes.Code, description string) {\n\tif s == nil {\n\t\treturn\n\t}\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\tif !s.isRecording() {\n\t\treturn\n\t}\n\tif s.status.Code > code {\n\t\treturn\n\t}\n\n\tstatus := Status{Code: code}\n\tif code == codes.Error {\n\t\tstatus.Description = description\n\t}\n\n\ts.status = status\n}\n\n// SetAttributes sets attributes of this span.\n//\n// If a key from attributes already exists the value associated with that key\n// will be overwritten with the value contained in attributes.\n//\n// If this span is not being recorded than this method does nothing.\n//\n// If adding attributes to the span would exceed the maximum amount of\n// attributes the span is configured to have, the last added attributes will\n// be dropped.\nfunc (s *recordingSpan) SetAttributes(attributes ...attribute.KeyValue) {\n\tif s == nil || len(attributes) == 0 {\n\t\treturn\n\t}\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\tif !s.isRecording() {\n\t\treturn\n\t}\n\n\tlimit := s.tracer.provider.spanLimits.AttributeCountLimit\n\tif limit == 0 {\n\t\t// No attributes allowed.\n\t\ts.addDroppedAttr(len(attributes))\n\t\treturn\n\t}\n\n\t// If adding these attributes could exceed the capacity of s perform a\n\t// de-duplication and truncation while adding to avoid over allocation.\n\tif limit > 0 && len(s.attributes)+len(attributes) > limit {\n\t\ts.addOverCapAttrs(limit, attributes)\n\t\treturn\n\t}\n\n\t// Otherwise, add without deduplication. When attributes are read they\n\t// will be deduplicated, optimizing the operation.\n\ts.attributes = slices.Grow(s.attributes, len(attributes))\n\tfor _, a := range attributes {\n\t\tif !a.Valid() {\n\t\t\t// Drop all invalid attributes.\n\t\t\ts.addDroppedAttr(1)\n\t\t\tcontinue\n\t\t}\n\t\ta = truncateAttr(s.tracer.provider.spanLimits.AttributeValueLengthLimit, a)\n\t\ts.attributes = append(s.attributes, a)\n\t}\n}\n\n// Declared as a var so tests can override.\nvar logDropAttrs = func() {\n\tglobal.Warn(\"limit reached: dropping trace Span attributes\")\n}\n\n// addDroppedAttr adds incr to the count of dropped attributes.\n//\n// The first, and only the first, time this method is called a warning will be\n// logged.\n//\n// This method assumes s.mu.Lock is held by the caller.\nfunc (s *recordingSpan) addDroppedAttr(incr int) {\n\ts.droppedAttributes += incr\n\ts.logDropAttrsOnce.Do(logDropAttrs)\n}\n\n// addOverCapAttrs adds the attributes attrs to the span s while\n// de-duplicating the attributes of s and attrs and dropping attributes that\n// exceed the limit.\n//\n// This method assumes s.mu.Lock is held by the caller.\n//\n// This method should only be called when there is a possibility that adding\n// attrs to s will exceed the limit. Otherwise, attrs should be added to s\n// without checking for duplicates and all retrieval methods of the attributes\n// for s will de-duplicate as needed.\n//\n// This method assumes limit is a value > 0. The argument should be validated\n// by the caller.\nfunc (s *recordingSpan) addOverCapAttrs(limit int, attrs []attribute.KeyValue) {\n\t// In order to not allocate more capacity to s.attributes than needed,\n\t// prune and truncate this addition of attributes while adding.\n\n\t// Do not set a capacity when creating this map. Benchmark testing has\n\t// showed this to only add unused memory allocations in general use.\n\texists := make(map[attribute.Key]int, len(s.attributes))\n\ts.dedupeAttrsFromRecord(exists)\n\n\t// Now that s.attributes is deduplicated, adding unique attributes up to\n\t// the capacity of s will not over allocate s.attributes.\n\n\t// max size = limit\n\tmaxCap := min(len(attrs)+len(s.attributes), limit)\n\tif cap(s.attributes) < maxCap {\n\t\ts.attributes = slices.Grow(s.attributes, maxCap-cap(s.attributes))\n\t}\n\tfor _, a := range attrs {\n\t\tif !a.Valid() {\n\t\t\t// Drop all invalid attributes.\n\t\t\ts.addDroppedAttr(1)\n\t\t\tcontinue\n\t\t}\n\n\t\tif idx, ok := exists[a.Key]; ok {\n\t\t\t// Perform all updates before dropping, even when at capacity.\n\t\t\ta = truncateAttr(s.tracer.provider.spanLimits.AttributeValueLengthLimit, a)\n\t\t\ts.attributes[idx] = a\n\t\t\tcontinue\n\t\t}\n\n\t\tif len(s.attributes) >= limit {\n\t\t\t// Do not just drop all of the remaining attributes, make sure\n\t\t\t// updates are checked and performed.\n\t\t\ts.addDroppedAttr(1)\n\t\t} else {\n\t\t\ta = truncateAttr(s.tracer.provider.spanLimits.AttributeValueLengthLimit, a)\n\t\t\ts.attributes = append(s.attributes, a)\n\t\t\texists[a.Key] = len(s.attributes) - 1\n\t\t}\n\t}\n}\n\n// truncateAttr returns a truncated version of attr. Only string and string\n// slice attribute values are truncated. String values are truncated to at\n// most a length of limit. Each string slice value is truncated in this fashion\n// (the slice length itself is unaffected).\n//\n// No truncation is performed for a negative limit.\nfunc truncateAttr(limit int, attr attribute.KeyValue) attribute.KeyValue {\n\tif limit < 0 {\n\t\treturn attr\n\t}\n\tswitch attr.Value.Type() {\n\tcase attribute.STRING:\n\t\tv := attr.Value.AsString()\n\t\treturn attr.Key.String(truncate(limit, v))\n\tcase attribute.STRINGSLICE:\n\t\tv := attr.Value.AsStringSlice()\n\t\tfor i := range v {\n\t\t\tv[i] = truncate(limit, v[i])\n\t\t}\n\t\treturn attr.Key.StringSlice(v)\n\t}\n\treturn attr\n}\n\n// truncate returns a truncated version of s such that it contains less than\n// the limit number of characters. Truncation is applied by returning the limit\n// number of valid characters contained in s.\n//\n// If limit is negative, it returns the original string.\n//\n// UTF-8 is supported. When truncating, all invalid characters are dropped\n// before applying truncation.\n//\n// If s already contains less than the limit number of bytes, it is returned\n// unchanged. No invalid characters are removed.\nfunc truncate(limit int, s string) string {\n\t// This prioritize performance in the following order based on the most\n\t// common expected use-cases.\n\t//\n\t//  - Short values less than the default limit (128).\n\t//  - Strings with valid encodings that exceed the limit.\n\t//  - No limit.\n\t//  - Strings with invalid encodings that exceed the limit.\n\tif limit < 0 || len(s) <= limit {\n\t\treturn s\n\t}\n\n\t// Optimistically, assume all valid UTF-8.\n\tvar b strings.Builder\n\tcount := 0\n\tfor i, c := range s {\n\t\tif c != utf8.RuneError {\n\t\t\tcount++\n\t\t\tif count > limit {\n\t\t\t\treturn s[:i]\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t_, size := utf8.DecodeRuneInString(s[i:])\n\t\tif size == 1 {\n\t\t\t// Invalid encoding.\n\t\t\tb.Grow(len(s) - 1)\n\t\t\t_, _ = b.WriteString(s[:i])\n\t\t\ts = s[i:]\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Fast-path, no invalid input.\n\tif b.Cap() == 0 {\n\t\treturn s\n\t}\n\n\t// Truncate while validating UTF-8.\n\tfor i := 0; i < len(s) && count < limit; {\n\t\tc := s[i]\n\t\tif c < utf8.RuneSelf {\n\t\t\t// Optimization for single byte runes (common case).\n\t\t\t_ = b.WriteByte(c)\n\t\t\ti++\n\t\t\tcount++\n\t\t\tcontinue\n\t\t}\n\n\t\t_, size := utf8.DecodeRuneInString(s[i:])\n\t\tif size == 1 {\n\t\t\t// We checked for all 1-byte runes above, this is a RuneError.\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\n\t\t_, _ = b.WriteString(s[i : i+size])\n\t\ti += size\n\t\tcount++\n\t}\n\n\treturn b.String()\n}\n\n// End ends the span. This method does nothing if the span is already ended or\n// is not being recorded.\n//\n// The only SpanEndOption currently supported are [trace.WithTimestamp], and\n// [trace.WithStackTrace].\n//\n// If this method is called while panicking an error event is added to the\n// Span before ending it and the panic is continued.\nfunc (s *recordingSpan) End(options ...trace.SpanEndOption) {\n\t// Do not start by checking if the span is being recorded which requires\n\t// acquiring a lock. Make a minimal check that the span is not nil.\n\tif s == nil {\n\t\treturn\n\t}\n\n\t// Store the end time as soon as possible to avoid artificially increasing\n\t// the span's duration in case some operation below takes a while.\n\tet := monotonicEndTime(s.startTime)\n\n\t// Lock the span now that we have an end time and see if we need to do any more processing.\n\ts.mu.Lock()\n\tif !s.isRecording() {\n\t\ts.mu.Unlock()\n\t\treturn\n\t}\n\n\tconfig := trace.NewSpanEndConfig(options...)\n\tif recovered := recover(); recovered != nil {\n\t\t// Record but don't stop the panic.\n\t\tdefer panic(recovered)\n\t\topts := []trace.EventOption{\n\t\t\ttrace.WithAttributes(\n\t\t\t\tsemconv.ExceptionType(typeStr(recovered)),\n\t\t\t\tsemconv.ExceptionMessage(fmt.Sprint(recovered)),\n\t\t\t),\n\t\t}\n\n\t\tif config.StackTrace() {\n\t\t\topts = append(opts, trace.WithAttributes(\n\t\t\t\tsemconv.ExceptionStacktrace(recordStackTrace()),\n\t\t\t))\n\t\t}\n\n\t\ts.addEvent(semconv.ExceptionEventName, opts...)\n\t}\n\n\tif s.executionTracerTaskEnd != nil {\n\t\ts.mu.Unlock()\n\t\ts.executionTracerTaskEnd()\n\t\ts.mu.Lock()\n\t}\n\n\t// Setting endTime to non-zero marks the span as ended and not recording.\n\tif config.Timestamp().IsZero() {\n\t\ts.endTime = et\n\t} else {\n\t\ts.endTime = config.Timestamp()\n\t}\n\ts.mu.Unlock()\n\n\tif s.tracer.inst.Enabled() {\n\t\tctx := s.origCtx\n\t\tif ctx == nil {\n\t\t\t// This should not happen as the origCtx should be set, but\n\t\t\t// ensure trace information is propagated in the case of an\n\t\t\t// error.\n\t\t\tctx = trace.ContextWithSpan(context.Background(), s)\n\t\t}\n\t\tdefer s.tracer.inst.SpanEnded(ctx, s)\n\t}\n\n\tsps := s.tracer.provider.getSpanProcessors()\n\tif len(sps) == 0 {\n\t\treturn\n\t}\n\tsnap := s.snapshot()\n\tfor _, sp := range sps {\n\t\tsp.sp.OnEnd(snap)\n\t}\n}\n\n// monotonicEndTime returns the end time at present but offset from start,\n// monotonically.\n//\n// The monotonic clock is used in subtractions hence the duration since start\n// added back to start gives end as a monotonic time. See\n// https://golang.org/pkg/time/#hdr-Monotonic_Clocks\nfunc monotonicEndTime(start time.Time) time.Time {\n\treturn start.Add(time.Since(start))\n}\n\n// RecordError will record err as a span event for this span. An additional call to\n// SetStatus is required if the Status of the Span should be set to Error, this method\n// does not change the Span status. If this span is not being recorded or err is nil\n// than this method does nothing.\nfunc (s *recordingSpan) RecordError(err error, opts ...trace.EventOption) {\n\tif s == nil || err == nil {\n\t\treturn\n\t}\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\tif !s.isRecording() {\n\t\treturn\n\t}\n\n\topts = append(opts, trace.WithAttributes(\n\t\tsemconv.ExceptionType(typeStr(err)),\n\t\tsemconv.ExceptionMessage(err.Error()),\n\t))\n\n\tc := trace.NewEventConfig(opts...)\n\tif c.StackTrace() {\n\t\topts = append(opts, trace.WithAttributes(\n\t\t\tsemconv.ExceptionStacktrace(recordStackTrace()),\n\t\t))\n\t}\n\n\ts.addEvent(semconv.ExceptionEventName, opts...)\n}\n\nfunc typeStr(i any) string {\n\tt := reflect.TypeOf(i)\n\tif t.PkgPath() == \"\" && t.Name() == \"\" {\n\t\t// Likely a builtin type.\n\t\treturn t.String()\n\t}\n\treturn fmt.Sprintf(\"%s.%s\", t.PkgPath(), t.Name())\n}\n\nfunc recordStackTrace() string {\n\tstackTrace := make([]byte, 2048)\n\tn := runtime.Stack(stackTrace, false)\n\n\treturn string(stackTrace[0:n])\n}\n\n// AddEvent adds an event with the provided name and options. If this span is\n// not being recorded then this method does nothing.\nfunc (s *recordingSpan) AddEvent(name string, o ...trace.EventOption) {\n\tif s == nil {\n\t\treturn\n\t}\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\tif !s.isRecording() {\n\t\treturn\n\t}\n\ts.addEvent(name, o...)\n}\n\n// addEvent adds an event with the provided name and options.\n//\n// This method assumes s.mu.Lock is held by the caller.\nfunc (s *recordingSpan) addEvent(name string, o ...trace.EventOption) {\n\tc := trace.NewEventConfig(o...)\n\te := Event{Name: name, Attributes: c.Attributes(), Time: c.Timestamp()}\n\n\t// Discard attributes over limit.\n\tlimit := s.tracer.provider.spanLimits.AttributePerEventCountLimit\n\tif limit == 0 {\n\t\t// Drop all attributes.\n\t\te.DroppedAttributeCount = len(e.Attributes)\n\t\te.Attributes = nil\n\t} else if limit > 0 && len(e.Attributes) > limit {\n\t\t// Drop over capacity.\n\t\te.DroppedAttributeCount = len(e.Attributes) - limit\n\t\te.Attributes = e.Attributes[:limit]\n\t}\n\n\ts.events.add(e)\n}\n\n// SetName sets the name of this span. If this span is not being recorded than\n// this method does nothing.\nfunc (s *recordingSpan) SetName(name string) {\n\tif s == nil {\n\t\treturn\n\t}\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\tif !s.isRecording() {\n\t\treturn\n\t}\n\ts.name = name\n}\n\n// Name returns the name of this span.\nfunc (s *recordingSpan) Name() string {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.name\n}\n\n// Name returns the SpanContext of this span's parent span.\nfunc (s *recordingSpan) Parent() trace.SpanContext {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.parent\n}\n\n// SpanKind returns the SpanKind of this span.\nfunc (s *recordingSpan) SpanKind() trace.SpanKind {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.spanKind\n}\n\n// StartTime returns the time this span started.\nfunc (s *recordingSpan) StartTime() time.Time {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.startTime\n}\n\n// EndTime returns the time this span ended. For spans that have not yet\n// ended, the returned value will be the zero value of time.Time.\nfunc (s *recordingSpan) EndTime() time.Time {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.endTime\n}\n\n// Attributes returns the attributes of this span.\n//\n// The order of the returned attributes is not guaranteed to be stable.\nfunc (s *recordingSpan) Attributes() []attribute.KeyValue {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.dedupeAttrs()\n\treturn s.attributes\n}\n\n// dedupeAttrs deduplicates the attributes of s to fit capacity.\n//\n// This method assumes s.mu.Lock is held by the caller.\nfunc (s *recordingSpan) dedupeAttrs() {\n\t// Do not set a capacity when creating this map. Benchmark testing has\n\t// showed this to only add unused memory allocations in general use.\n\texists := make(map[attribute.Key]int, len(s.attributes))\n\ts.dedupeAttrsFromRecord(exists)\n}\n\n// dedupeAttrsFromRecord deduplicates the attributes of s to fit capacity\n// using record as the record of unique attribute keys to their index.\n//\n// This method assumes s.mu.Lock is held by the caller.\nfunc (s *recordingSpan) dedupeAttrsFromRecord(record map[attribute.Key]int) {\n\t// Use the fact that slices share the same backing array.\n\tunique := s.attributes[:0]\n\tfor _, a := range s.attributes {\n\t\tif idx, ok := record[a.Key]; ok {\n\t\t\tunique[idx] = a\n\t\t} else {\n\t\t\tunique = append(unique, a)\n\t\t\trecord[a.Key] = len(unique) - 1\n\t\t}\n\t}\n\tclear(s.attributes[len(unique):]) // Erase unneeded elements to let GC collect objects.\n\ts.attributes = unique\n}\n\n// Links returns the links of this span.\nfunc (s *recordingSpan) Links() []Link {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\tif len(s.links.queue) == 0 {\n\t\treturn []Link{}\n\t}\n\treturn s.links.copy()\n}\n\n// Events returns the events of this span.\nfunc (s *recordingSpan) Events() []Event {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\tif len(s.events.queue) == 0 {\n\t\treturn []Event{}\n\t}\n\treturn s.events.copy()\n}\n\n// Status returns the status of this span.\nfunc (s *recordingSpan) Status() Status {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.status\n}\n\n// InstrumentationScope returns the instrumentation.Scope associated with\n// the Tracer that created this span.\nfunc (s *recordingSpan) InstrumentationScope() instrumentation.Scope {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.tracer.instrumentationScope\n}\n\n// InstrumentationLibrary returns the instrumentation.Library associated with\n// the Tracer that created this span.\nfunc (s *recordingSpan) InstrumentationLibrary() instrumentation.Library { //nolint:staticcheck // This method needs to be define for backwards compatibility\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.tracer.instrumentationScope\n}\n\n// Resource returns the Resource associated with the Tracer that created this\n// span.\nfunc (s *recordingSpan) Resource() *resource.Resource {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.tracer.provider.resource\n}\n\nfunc (s *recordingSpan) AddLink(link trace.Link) {\n\tif s == nil {\n\t\treturn\n\t}\n\tif !link.SpanContext.IsValid() && len(link.Attributes) == 0 &&\n\t\tlink.SpanContext.TraceState().Len() == 0 {\n\t\treturn\n\t}\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\tif !s.isRecording() {\n\t\treturn\n\t}\n\n\tl := Link{SpanContext: link.SpanContext, Attributes: link.Attributes}\n\n\t// Discard attributes over limit.\n\tlimit := s.tracer.provider.spanLimits.AttributePerLinkCountLimit\n\tif limit == 0 {\n\t\t// Drop all attributes.\n\t\tl.DroppedAttributeCount = len(l.Attributes)\n\t\tl.Attributes = nil\n\t} else if limit > 0 && len(l.Attributes) > limit {\n\t\tl.DroppedAttributeCount = len(l.Attributes) - limit\n\t\tl.Attributes = l.Attributes[:limit]\n\t}\n\n\ts.links.add(l)\n}\n\n// DroppedAttributes returns the number of attributes dropped by the span\n// due to limits being reached.\nfunc (s *recordingSpan) DroppedAttributes() int {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.droppedAttributes\n}\n\n// DroppedLinks returns the number of links dropped by the span due to limits\n// being reached.\nfunc (s *recordingSpan) DroppedLinks() int {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.links.droppedCount\n}\n\n// DroppedEvents returns the number of events dropped by the span due to\n// limits being reached.\nfunc (s *recordingSpan) DroppedEvents() int {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.events.droppedCount\n}\n\n// ChildSpanCount returns the count of spans that consider the span a\n// direct parent.\nfunc (s *recordingSpan) ChildSpanCount() int {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.childSpanCount\n}\n\n// TracerProvider returns a trace.TracerProvider that can be used to generate\n// additional Spans on the same telemetry pipeline as the current Span.\nfunc (s *recordingSpan) TracerProvider() trace.TracerProvider {\n\treturn s.tracer.provider\n}\n\n// snapshot creates a read-only copy of the current state of the span.\nfunc (s *recordingSpan) snapshot() ReadOnlySpan {\n\tvar sd snapshot\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tsd.endTime = s.endTime\n\tsd.instrumentationScope = s.tracer.instrumentationScope\n\tsd.name = s.name\n\tsd.parent = s.parent\n\tsd.resource = s.tracer.provider.resource\n\tsd.spanContext = s.spanContext\n\tsd.spanKind = s.spanKind\n\tsd.startTime = s.startTime\n\tsd.status = s.status\n\tsd.childSpanCount = s.childSpanCount\n\n\tif len(s.attributes) > 0 {\n\t\ts.dedupeAttrs()\n\t\tsd.attributes = s.attributes\n\t}\n\tsd.droppedAttributeCount = s.droppedAttributes\n\tif len(s.events.queue) > 0 {\n\t\tsd.events = s.events.copy()\n\t\tsd.droppedEventCount = s.events.droppedCount\n\t}\n\tif len(s.links.queue) > 0 {\n\t\tsd.links = s.links.copy()\n\t\tsd.droppedLinkCount = s.links.droppedCount\n\t}\n\treturn &sd\n}\n\nfunc (s *recordingSpan) addChild() {\n\tif s == nil {\n\t\treturn\n\t}\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\tif !s.isRecording() {\n\t\treturn\n\t}\n\ts.childSpanCount++\n}\n\nfunc (*recordingSpan) private() {}\n\n// runtimeTrace starts a \"runtime/trace\".Task for the span and returns a\n// context containing the task.\nfunc (s *recordingSpan) runtimeTrace(ctx context.Context) context.Context {\n\tif !rt.IsEnabled() {\n\t\t// Avoid additional overhead if runtime/trace is not enabled.\n\t\treturn ctx\n\t}\n\tnctx, task := rt.NewTask(ctx, s.name)\n\n\ts.mu.Lock()\n\ts.executionTracerTaskEnd = task.End\n\ts.mu.Unlock()\n\n\treturn nctx\n}\n\n// nonRecordingSpan is a minimal implementation of the OpenTelemetry Span API\n// that wraps a SpanContext. It performs no operations other than to return\n// the wrapped SpanContext or TracerProvider that created it.\ntype nonRecordingSpan struct {\n\tembedded.Span\n\n\t// tracer is the SDK tracer that created this span.\n\ttracer *tracer\n\tsc     trace.SpanContext\n}\n\nvar _ trace.Span = nonRecordingSpan{}\n\n// SpanContext returns the wrapped SpanContext.\nfunc (s nonRecordingSpan) SpanContext() trace.SpanContext { return s.sc }\n\n// IsRecording always returns false.\nfunc (nonRecordingSpan) IsRecording() bool { return false }\n\n// SetStatus does nothing.\nfunc (nonRecordingSpan) SetStatus(codes.Code, string) {}\n\n// SetError does nothing.\nfunc (nonRecordingSpan) SetError(bool) {}\n\n// SetAttributes does nothing.\nfunc (nonRecordingSpan) SetAttributes(...attribute.KeyValue) {}\n\n// End does nothing.\nfunc (nonRecordingSpan) End(...trace.SpanEndOption) {}\n\n// RecordError does nothing.\nfunc (nonRecordingSpan) RecordError(error, ...trace.EventOption) {}\n\n// AddEvent does nothing.\nfunc (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {}\n\n// AddLink does nothing.\nfunc (nonRecordingSpan) AddLink(trace.Link) {}\n\n// SetName does nothing.\nfunc (nonRecordingSpan) SetName(string) {}\n\n// TracerProvider returns the trace.TracerProvider that provided the Tracer\n// that created this span.\nfunc (s nonRecordingSpan) TracerProvider() trace.TracerProvider { return s.tracer.provider }\n\nfunc isRecording(s SamplingResult) bool {\n\treturn s.Decision == RecordOnly || s.Decision == RecordAndSample\n}\n\nfunc isSampled(s SamplingResult) bool {\n\treturn s.Decision == RecordAndSample\n}\n\n// Status is the classified state of a Span.\ntype Status struct {\n\t// Code is an identifier of a Spans state classification.\n\tCode codes.Code\n\t// Description is a user hint about why that status was set. It is only\n\t// applicable when Code is Error.\n\tDescription string\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/sdk/trace\"\n\nimport \"context\"\n\n// SpanExporter handles the delivery of spans to external receivers. This is\n// the final component in the trace export pipeline.\ntype SpanExporter interface {\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// ExportSpans exports a batch of spans.\n\t//\n\t// This function is called synchronously, so there is no concurrency\n\t// safety requirement. However, due to the synchronous calling pattern,\n\t// it is critical that all timeouts and cancellations contained in the\n\t// passed context must be honored.\n\t//\n\t// Any retry logic must be contained in this function. The SDK that\n\t// calls this function will not implement any retry logic. All errors\n\t// returned by this function are considered unrecoverable and will be\n\t// reported to a configured error Handler.\n\tExportSpans(ctx context.Context, spans []ReadOnlySpan) error\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Shutdown notifies the exporter of a pending halt to operations. The\n\t// exporter is expected to perform any cleanup or synchronization it\n\t// requires while honoring all timeouts and cancellations contained in\n\t// the passed context.\n\tShutdown(ctx context.Context) error\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/span_limits.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/sdk/trace\"\n\nimport \"go.opentelemetry.io/otel/sdk/trace/internal/env\"\n\nconst (\n\t// DefaultAttributeValueLengthLimit is the default maximum allowed\n\t// attribute value length, unlimited.\n\tDefaultAttributeValueLengthLimit = -1\n\n\t// DefaultAttributeCountLimit is the default maximum number of attributes\n\t// a span can have.\n\tDefaultAttributeCountLimit = 128\n\n\t// DefaultEventCountLimit is the default maximum number of events a span\n\t// can have.\n\tDefaultEventCountLimit = 128\n\n\t// DefaultLinkCountLimit is the default maximum number of links a span can\n\t// have.\n\tDefaultLinkCountLimit = 128\n\n\t// DefaultAttributePerEventCountLimit is the default maximum number of\n\t// attributes a span event can have.\n\tDefaultAttributePerEventCountLimit = 128\n\n\t// DefaultAttributePerLinkCountLimit is the default maximum number of\n\t// attributes a span link can have.\n\tDefaultAttributePerLinkCountLimit = 128\n)\n\n// SpanLimits represents the limits of a span.\ntype SpanLimits struct {\n\t// AttributeValueLengthLimit is the maximum allowed attribute value length.\n\t//\n\t// This limit only applies to string and string slice attribute values.\n\t// Any string longer than this value will be truncated to this length.\n\t//\n\t// Setting this to a negative value means no limit is applied.\n\tAttributeValueLengthLimit int\n\n\t// AttributeCountLimit is the maximum allowed span attribute count. Any\n\t// attribute added to a span once this limit is reached will be dropped.\n\t//\n\t// Setting this to zero means no attributes will be recorded.\n\t//\n\t// Setting this to a negative value means no limit is applied.\n\tAttributeCountLimit int\n\n\t// EventCountLimit is the maximum allowed span event count. Any event\n\t// added to a span once this limit is reached means it will be added but\n\t// the oldest event will be dropped.\n\t//\n\t// Setting this to zero means no events we be recorded.\n\t//\n\t// Setting this to a negative value means no limit is applied.\n\tEventCountLimit int\n\n\t// LinkCountLimit is the maximum allowed span link count. Any link added\n\t// to a span once this limit is reached means it will be added but the\n\t// oldest link will be dropped.\n\t//\n\t// Setting this to zero means no links we be recorded.\n\t//\n\t// Setting this to a negative value means no limit is applied.\n\tLinkCountLimit int\n\n\t// AttributePerEventCountLimit is the maximum number of attributes allowed\n\t// per span event. Any attribute added after this limit reached will be\n\t// dropped.\n\t//\n\t// Setting this to zero means no attributes will be recorded for events.\n\t//\n\t// Setting this to a negative value means no limit is applied.\n\tAttributePerEventCountLimit int\n\n\t// AttributePerLinkCountLimit is the maximum number of attributes allowed\n\t// per span link. Any attribute added after this limit reached will be\n\t// dropped.\n\t//\n\t// Setting this to zero means no attributes will be recorded for links.\n\t//\n\t// Setting this to a negative value means no limit is applied.\n\tAttributePerLinkCountLimit int\n}\n\n// NewSpanLimits returns a SpanLimits with all limits set to the value their\n// corresponding environment variable holds, or the default if unset.\n//\n// • AttributeValueLengthLimit: OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT\n// (default: unlimited)\n//\n// • AttributeCountLimit: OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT (default: 128)\n//\n// • EventCountLimit: OTEL_SPAN_EVENT_COUNT_LIMIT (default: 128)\n//\n// • AttributePerEventCountLimit: OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT (default:\n// 128)\n//\n// • LinkCountLimit: OTEL_SPAN_LINK_COUNT_LIMIT (default: 128)\n//\n// • AttributePerLinkCountLimit: OTEL_LINK_ATTRIBUTE_COUNT_LIMIT (default: 128)\nfunc NewSpanLimits() SpanLimits {\n\treturn SpanLimits{\n\t\tAttributeValueLengthLimit:   env.SpanAttributeValueLength(DefaultAttributeValueLengthLimit),\n\t\tAttributeCountLimit:         env.SpanAttributeCount(DefaultAttributeCountLimit),\n\t\tEventCountLimit:             env.SpanEventCount(DefaultEventCountLimit),\n\t\tLinkCountLimit:              env.SpanLinkCount(DefaultLinkCountLimit),\n\t\tAttributePerEventCountLimit: env.SpanEventAttributeCount(DefaultAttributePerEventCountLimit),\n\t\tAttributePerLinkCountLimit:  env.SpanLinkAttributeCount(DefaultAttributePerLinkCountLimit),\n\t}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/sdk/trace\"\n\nimport (\n\t\"context\"\n\t\"sync\"\n)\n\n// SpanProcessor is a processing pipeline for spans in the trace signal.\n// SpanProcessors registered with a TracerProvider and are called at the start\n// and end of a Span's lifecycle, and are called in the order they are\n// registered.\ntype SpanProcessor interface {\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// OnStart is called when a span is started. It is called synchronously\n\t// and should not block.\n\tOnStart(parent context.Context, s ReadWriteSpan)\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// OnEnd is called when span is finished. It is called synchronously and\n\t// hence not block.\n\tOnEnd(s ReadOnlySpan)\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Shutdown is called when the SDK shuts down. Any cleanup or release of\n\t// resources held by the processor should be done in this call.\n\t//\n\t// Calls to OnStart, OnEnd, or ForceFlush after this has been called\n\t// should be ignored.\n\t//\n\t// All timeouts and cancellations contained in ctx must be honored, this\n\t// should not block indefinitely.\n\tShutdown(ctx context.Context) error\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// ForceFlush exports all ended spans to the configured Exporter that have not yet\n\t// been exported.  It should only be called when absolutely necessary, such as when\n\t// using a FaaS provider that may suspend the process after an invocation, but before\n\t// the Processor can export the completed spans.\n\tForceFlush(ctx context.Context) error\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n}\n\ntype spanProcessorState struct {\n\tsp    SpanProcessor\n\tstate sync.Once\n}\n\nfunc newSpanProcessorState(sp SpanProcessor) *spanProcessorState {\n\treturn &spanProcessorState{sp: sp}\n}\n\ntype spanProcessorStates []*spanProcessorState\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/sdk/trace\"\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"go.opentelemetry.io/otel/sdk/instrumentation\"\n\t\"go.opentelemetry.io/otel/sdk/trace/internal/observ\"\n\t\"go.opentelemetry.io/otel/trace\"\n\t\"go.opentelemetry.io/otel/trace/embedded\"\n)\n\ntype tracer struct {\n\tembedded.Tracer\n\n\tprovider             *TracerProvider\n\tinstrumentationScope instrumentation.Scope\n\n\tinst observ.Tracer\n}\n\nvar _ trace.Tracer = &tracer{}\n\n// Start starts a Span and returns it along with a context containing it.\n//\n// The Span is created with the provided name and as a child of any existing\n// span context found in the passed context. The created Span will be\n// configured appropriately by any SpanOption passed.\nfunc (tr *tracer) Start(\n\tctx context.Context,\n\tname string,\n\toptions ...trace.SpanStartOption,\n) (context.Context, trace.Span) {\n\tconfig := trace.NewSpanStartConfig(options...)\n\n\tif ctx == nil {\n\t\t// Prevent trace.ContextWithSpan from panicking.\n\t\tctx = context.Background()\n\t}\n\n\t// For local spans created by this SDK, track child span count.\n\tif p := trace.SpanFromContext(ctx); p != nil {\n\t\tif sdkSpan, ok := p.(*recordingSpan); ok {\n\t\t\tsdkSpan.addChild()\n\t\t}\n\t}\n\n\ts := tr.newSpan(ctx, name, &config)\n\tnewCtx := trace.ContextWithSpan(ctx, s)\n\tif tr.inst.Enabled() {\n\t\tif o, ok := s.(interface{ setOrigCtx(context.Context) }); ok {\n\t\t\t// If this is a recording span, store the original context.\n\t\t\t// This allows later retrieval of baggage and other information\n\t\t\t// that may have been stored in the context at span start time and\n\t\t\t// to avoid the allocation of repeatedly calling\n\t\t\t// trace.ContextWithSpan.\n\t\t\to.setOrigCtx(newCtx)\n\t\t}\n\t\tpsc := trace.SpanContextFromContext(ctx)\n\t\ttr.inst.SpanStarted(newCtx, psc, s)\n\t}\n\n\tif rw, ok := s.(ReadWriteSpan); ok && s.IsRecording() {\n\t\tsps := tr.provider.getSpanProcessors()\n\t\tfor _, sp := range sps {\n\t\t\t// Use original context.\n\t\t\tsp.sp.OnStart(ctx, rw)\n\t\t}\n\t}\n\tif rtt, ok := s.(runtimeTracer); ok {\n\t\tnewCtx = rtt.runtimeTrace(newCtx)\n\t}\n\n\treturn newCtx, s\n}\n\ntype runtimeTracer interface {\n\t// runtimeTrace starts a \"runtime/trace\".Task for the span and\n\t// returns a context containing the task.\n\truntimeTrace(ctx context.Context) context.Context\n}\n\n// newSpan returns a new configured span.\nfunc (tr *tracer) newSpan(ctx context.Context, name string, config *trace.SpanConfig) trace.Span {\n\t// If told explicitly to make this a new root use a zero value SpanContext\n\t// as a parent which contains an invalid trace ID and is not remote.\n\tvar psc trace.SpanContext\n\tif config.NewRoot() {\n\t\tctx = trace.ContextWithSpanContext(ctx, psc)\n\t} else {\n\t\tpsc = trace.SpanContextFromContext(ctx)\n\t}\n\n\t// If there is a valid parent trace ID, use it to ensure the continuity of\n\t// the trace. Always generate a new span ID so other components can rely\n\t// on a unique span ID, even if the Span is non-recording.\n\tvar tid trace.TraceID\n\tvar sid trace.SpanID\n\tif !psc.TraceID().IsValid() {\n\t\ttid, sid = tr.provider.idGenerator.NewIDs(ctx)\n\t} else {\n\t\ttid = psc.TraceID()\n\t\tsid = tr.provider.idGenerator.NewSpanID(ctx, tid)\n\t}\n\n\tsamplingResult := tr.provider.sampler.ShouldSample(SamplingParameters{\n\t\tParentContext: ctx,\n\t\tTraceID:       tid,\n\t\tName:          name,\n\t\tKind:          config.SpanKind(),\n\t\tAttributes:    config.Attributes(),\n\t\tLinks:         config.Links(),\n\t})\n\n\tscc := trace.SpanContextConfig{\n\t\tTraceID:    tid,\n\t\tSpanID:     sid,\n\t\tTraceState: samplingResult.Tracestate,\n\t}\n\tif isSampled(samplingResult) {\n\t\tscc.TraceFlags = psc.TraceFlags() | trace.FlagsSampled\n\t} else {\n\t\tscc.TraceFlags = psc.TraceFlags() &^ trace.FlagsSampled\n\t}\n\tsc := trace.NewSpanContext(scc)\n\n\tif !isRecording(samplingResult) {\n\t\treturn tr.newNonRecordingSpan(sc)\n\t}\n\treturn tr.newRecordingSpan(ctx, psc, sc, name, samplingResult, config)\n}\n\n// newRecordingSpan returns a new configured recordingSpan.\nfunc (tr *tracer) newRecordingSpan(\n\tctx context.Context,\n\tpsc, sc trace.SpanContext,\n\tname string,\n\tsr SamplingResult,\n\tconfig *trace.SpanConfig,\n) *recordingSpan {\n\tstartTime := config.Timestamp()\n\tif startTime.IsZero() {\n\t\tstartTime = time.Now()\n\t}\n\n\ts := &recordingSpan{\n\t\t// Do not pre-allocate the attributes slice here! Doing so will\n\t\t// allocate memory that is likely never going to be used, or if used,\n\t\t// will be over-sized. The default Go compiler has been tested to\n\t\t// dynamically allocate needed space very well. Benchmarking has shown\n\t\t// it to be more performant than what we can predetermine here,\n\t\t// especially for the common use case of few to no added\n\t\t// attributes.\n\n\t\tparent:      psc,\n\t\tspanContext: sc,\n\t\tspanKind:    trace.ValidateSpanKind(config.SpanKind()),\n\t\tname:        name,\n\t\tstartTime:   startTime,\n\t\tevents:      newEvictedQueueEvent(tr.provider.spanLimits.EventCountLimit),\n\t\tlinks:       newEvictedQueueLink(tr.provider.spanLimits.LinkCountLimit),\n\t\ttracer:      tr,\n\t}\n\n\tfor _, l := range config.Links() {\n\t\ts.AddLink(l)\n\t}\n\n\ts.SetAttributes(sr.Attributes...)\n\ts.SetAttributes(config.Attributes()...)\n\n\tif tr.inst.Enabled() {\n\t\t// Propagate any existing values from the context with the new span to\n\t\t// the measurement context.\n\t\tctx = trace.ContextWithSpan(ctx, s)\n\t\ttr.inst.SpanLive(ctx, s)\n\t}\n\n\treturn s\n}\n\n// newNonRecordingSpan returns a new configured nonRecordingSpan.\nfunc (tr *tracer) newNonRecordingSpan(sc trace.SpanContext) nonRecordingSpan {\n\treturn nonRecordingSpan{tracer: tr, sc: sc}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/sdk/version.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package sdk provides the OpenTelemetry default SDK for Go.\npackage sdk // import \"go.opentelemetry.io/otel/sdk\"\n\n// Version is the current release version of the OpenTelemetry SDK in use.\nfunc Version() string {\n\treturn \"1.40.0\"\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/internal/http.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package internal provides common semconv functionality.\npackage internal // import \"go.opentelemetry.io/otel/semconv/internal\"\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\n// SemanticConventions are the semantic convention values defined for a\n// version of the OpenTelemetry specification.\ntype SemanticConventions struct {\n\tEnduserIDKey                attribute.Key\n\tHTTPClientIPKey             attribute.Key\n\tHTTPFlavorKey               attribute.Key\n\tHTTPHostKey                 attribute.Key\n\tHTTPMethodKey               attribute.Key\n\tHTTPRequestContentLengthKey attribute.Key\n\tHTTPRouteKey                attribute.Key\n\tHTTPSchemeHTTP              attribute.KeyValue\n\tHTTPSchemeHTTPS             attribute.KeyValue\n\tHTTPServerNameKey           attribute.Key\n\tHTTPStatusCodeKey           attribute.Key\n\tHTTPTargetKey               attribute.Key\n\tHTTPURLKey                  attribute.Key\n\tHTTPUserAgentKey            attribute.Key\n\tNetHostIPKey                attribute.Key\n\tNetHostNameKey              attribute.Key\n\tNetHostPortKey              attribute.Key\n\tNetPeerIPKey                attribute.Key\n\tNetPeerNameKey              attribute.Key\n\tNetPeerPortKey              attribute.Key\n\tNetTransportIP              attribute.KeyValue\n\tNetTransportOther           attribute.KeyValue\n\tNetTransportTCP             attribute.KeyValue\n\tNetTransportUDP             attribute.KeyValue\n\tNetTransportUnix            attribute.KeyValue\n}\n\n// NetAttributesFromHTTPRequest generates attributes of the net\n// namespace as specified by the OpenTelemetry specification for a\n// span.  The network parameter is a string that net.Dial function\n// from standard library can understand.\nfunc (sc *SemanticConventions) NetAttributesFromHTTPRequest(\n\tnetwork string,\n\trequest *http.Request,\n) []attribute.KeyValue {\n\tattrs := []attribute.KeyValue{}\n\n\tswitch network {\n\tcase \"tcp\", \"tcp4\", \"tcp6\":\n\t\tattrs = append(attrs, sc.NetTransportTCP)\n\tcase \"udp\", \"udp4\", \"udp6\":\n\t\tattrs = append(attrs, sc.NetTransportUDP)\n\tcase \"ip\", \"ip4\", \"ip6\":\n\t\tattrs = append(attrs, sc.NetTransportIP)\n\tcase \"unix\", \"unixgram\", \"unixpacket\":\n\t\tattrs = append(attrs, sc.NetTransportUnix)\n\tdefault:\n\t\tattrs = append(attrs, sc.NetTransportOther)\n\t}\n\n\tpeerIP, peerName, peerPort := hostIPNamePort(request.RemoteAddr)\n\tif peerIP != \"\" {\n\t\tattrs = append(attrs, sc.NetPeerIPKey.String(peerIP))\n\t}\n\tif peerName != \"\" {\n\t\tattrs = append(attrs, sc.NetPeerNameKey.String(peerName))\n\t}\n\tif peerPort != 0 {\n\t\tattrs = append(attrs, sc.NetPeerPortKey.Int(peerPort))\n\t}\n\n\thostIP, hostName, hostPort := \"\", \"\", 0\n\tfor _, someHost := range []string{request.Host, request.Header.Get(\"Host\"), request.URL.Host} {\n\t\thostIP, hostName, hostPort = hostIPNamePort(someHost)\n\t\tif hostIP != \"\" || hostName != \"\" || hostPort != 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\tif hostIP != \"\" {\n\t\tattrs = append(attrs, sc.NetHostIPKey.String(hostIP))\n\t}\n\tif hostName != \"\" {\n\t\tattrs = append(attrs, sc.NetHostNameKey.String(hostName))\n\t}\n\tif hostPort != 0 {\n\t\tattrs = append(attrs, sc.NetHostPortKey.Int(hostPort))\n\t}\n\n\treturn attrs\n}\n\n// hostIPNamePort extracts the IP address, name and (optional) port from hostWithPort.\n// It handles both IPv4 and IPv6 addresses. If the host portion is not recognized\n// as a valid IPv4 or IPv6 address, the `ip` result will be empty and the\n// host portion will instead be returned in `name`.\nfunc hostIPNamePort(hostWithPort string) (ip, name string, port int) {\n\tvar (\n\t\thostPart, portPart string\n\t\tparsedPort         uint64\n\t\terr                error\n\t)\n\tif hostPart, portPart, err = net.SplitHostPort(hostWithPort); err != nil {\n\t\thostPart, portPart = hostWithPort, \"\"\n\t}\n\tif parsedIP := net.ParseIP(hostPart); parsedIP != nil {\n\t\tip = parsedIP.String()\n\t} else {\n\t\tname = hostPart\n\t}\n\tif parsedPort, err = strconv.ParseUint(portPart, 10, 16); err == nil {\n\t\tport = int(parsedPort) // nolint: gosec  // Bit size of 16 checked above.\n\t}\n\treturn ip, name, port\n}\n\n// EndUserAttributesFromHTTPRequest generates attributes of the\n// enduser namespace as specified by the OpenTelemetry specification\n// for a span.\nfunc (sc *SemanticConventions) EndUserAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {\n\tif username, _, ok := request.BasicAuth(); ok {\n\t\treturn []attribute.KeyValue{sc.EnduserIDKey.String(username)}\n\t}\n\treturn nil\n}\n\n// HTTPClientAttributesFromHTTPRequest generates attributes of the\n// http namespace as specified by the OpenTelemetry specification for\n// a span on the client side.\nfunc (sc *SemanticConventions) HTTPClientAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {\n\tattrs := []attribute.KeyValue{}\n\n\t// remove any username/password info that may be in the URL\n\t// before adding it to the attributes\n\tuserinfo := request.URL.User\n\trequest.URL.User = nil\n\n\tattrs = append(attrs, sc.HTTPURLKey.String(request.URL.String()))\n\n\t// restore any username/password info that was removed\n\trequest.URL.User = userinfo\n\n\treturn append(attrs, sc.httpCommonAttributesFromHTTPRequest(request)...)\n}\n\nfunc (sc *SemanticConventions) httpCommonAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {\n\tattrs := []attribute.KeyValue{}\n\tif ua := request.UserAgent(); ua != \"\" {\n\t\tattrs = append(attrs, sc.HTTPUserAgentKey.String(ua))\n\t}\n\tif request.ContentLength > 0 {\n\t\tattrs = append(attrs, sc.HTTPRequestContentLengthKey.Int64(request.ContentLength))\n\t}\n\n\treturn append(attrs, sc.httpBasicAttributesFromHTTPRequest(request)...)\n}\n\nfunc (sc *SemanticConventions) httpBasicAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {\n\t// as these attributes are used by HTTPServerMetricAttributesFromHTTPRequest, they should be low-cardinality\n\tattrs := []attribute.KeyValue{}\n\n\tif request.TLS != nil {\n\t\tattrs = append(attrs, sc.HTTPSchemeHTTPS)\n\t} else {\n\t\tattrs = append(attrs, sc.HTTPSchemeHTTP)\n\t}\n\n\tif request.Host != \"\" {\n\t\tattrs = append(attrs, sc.HTTPHostKey.String(request.Host))\n\t} else if request.URL != nil && request.URL.Host != \"\" {\n\t\tattrs = append(attrs, sc.HTTPHostKey.String(request.URL.Host))\n\t}\n\n\tflavor := \"\"\n\tswitch request.ProtoMajor {\n\tcase 1:\n\t\tflavor = fmt.Sprintf(\"1.%d\", request.ProtoMinor)\n\tcase 2:\n\t\tflavor = \"2\"\n\t}\n\tif flavor != \"\" {\n\t\tattrs = append(attrs, sc.HTTPFlavorKey.String(flavor))\n\t}\n\n\tif request.Method != \"\" {\n\t\tattrs = append(attrs, sc.HTTPMethodKey.String(request.Method))\n\t} else {\n\t\tattrs = append(attrs, sc.HTTPMethodKey.String(http.MethodGet))\n\t}\n\n\treturn attrs\n}\n\n// HTTPServerMetricAttributesFromHTTPRequest generates low-cardinality attributes\n// to be used with server-side HTTP metrics.\nfunc (sc *SemanticConventions) HTTPServerMetricAttributesFromHTTPRequest(\n\tserverName string,\n\trequest *http.Request,\n) []attribute.KeyValue {\n\tattrs := []attribute.KeyValue{}\n\tif serverName != \"\" {\n\t\tattrs = append(attrs, sc.HTTPServerNameKey.String(serverName))\n\t}\n\treturn append(attrs, sc.httpBasicAttributesFromHTTPRequest(request)...)\n}\n\n// HTTPServerAttributesFromHTTPRequest generates attributes of the\n// http namespace as specified by the OpenTelemetry specification for\n// a span on the server side. Currently, only basic authentication is\n// supported.\nfunc (sc *SemanticConventions) HTTPServerAttributesFromHTTPRequest(\n\tserverName, route string,\n\trequest *http.Request,\n) []attribute.KeyValue {\n\tattrs := []attribute.KeyValue{\n\t\tsc.HTTPTargetKey.String(request.RequestURI),\n\t}\n\n\tif serverName != \"\" {\n\t\tattrs = append(attrs, sc.HTTPServerNameKey.String(serverName))\n\t}\n\tif route != \"\" {\n\t\tattrs = append(attrs, sc.HTTPRouteKey.String(route))\n\t}\n\tif values := request.Header[\"X-Forwarded-For\"]; len(values) > 0 {\n\t\taddr := values[0]\n\t\tif i := strings.Index(addr, \",\"); i > 0 {\n\t\t\taddr = addr[:i]\n\t\t}\n\t\tattrs = append(attrs, sc.HTTPClientIPKey.String(addr))\n\t}\n\n\treturn append(attrs, sc.httpCommonAttributesFromHTTPRequest(request)...)\n}\n\n// HTTPAttributesFromHTTPStatusCode generates attributes of the http\n// namespace as specified by the OpenTelemetry specification for a\n// span.\nfunc (sc *SemanticConventions) HTTPAttributesFromHTTPStatusCode(code int) []attribute.KeyValue {\n\tattrs := []attribute.KeyValue{\n\t\tsc.HTTPStatusCodeKey.Int(code),\n\t}\n\treturn attrs\n}\n\ntype codeRange struct {\n\tfromInclusive int\n\ttoInclusive   int\n}\n\nfunc (r codeRange) contains(code int) bool {\n\treturn r.fromInclusive <= code && code <= r.toInclusive\n}\n\nvar validRangesPerCategory = map[int][]codeRange{\n\t1: {\n\t\t{http.StatusContinue, http.StatusEarlyHints},\n\t},\n\t2: {\n\t\t{http.StatusOK, http.StatusAlreadyReported},\n\t\t{http.StatusIMUsed, http.StatusIMUsed},\n\t},\n\t3: {\n\t\t{http.StatusMultipleChoices, http.StatusUseProxy},\n\t\t{http.StatusTemporaryRedirect, http.StatusPermanentRedirect},\n\t},\n\t4: {\n\t\t{http.StatusBadRequest, http.StatusTeapot}, // yes, teapot is so useful…\n\t\t{http.StatusMisdirectedRequest, http.StatusUpgradeRequired},\n\t\t{http.StatusPreconditionRequired, http.StatusTooManyRequests},\n\t\t{http.StatusRequestHeaderFieldsTooLarge, http.StatusRequestHeaderFieldsTooLarge},\n\t\t{http.StatusUnavailableForLegalReasons, http.StatusUnavailableForLegalReasons},\n\t},\n\t5: {\n\t\t{http.StatusInternalServerError, http.StatusLoopDetected},\n\t\t{http.StatusNotExtended, http.StatusNetworkAuthenticationRequired},\n\t},\n}\n\n// SpanStatusFromHTTPStatusCode generates a status code and a message\n// as specified by the OpenTelemetry specification for a span.\nfunc SpanStatusFromHTTPStatusCode(code int) (codes.Code, string) {\n\tspanCode, valid := validateHTTPStatusCode(code)\n\tif !valid {\n\t\treturn spanCode, fmt.Sprintf(\"Invalid HTTP status code %d\", code)\n\t}\n\treturn spanCode, \"\"\n}\n\n// SpanStatusFromHTTPStatusCodeAndSpanKind generates a status code and a message\n// as specified by the OpenTelemetry specification for a span.\n// Exclude 4xx for SERVER to set the appropriate status.\nfunc SpanStatusFromHTTPStatusCodeAndSpanKind(code int, spanKind trace.SpanKind) (codes.Code, string) {\n\tspanCode, valid := validateHTTPStatusCode(code)\n\tif !valid {\n\t\treturn spanCode, fmt.Sprintf(\"Invalid HTTP status code %d\", code)\n\t}\n\tcategory := code / 100\n\tif spanKind == trace.SpanKindServer && category == 4 {\n\t\treturn codes.Unset, \"\"\n\t}\n\treturn spanCode, \"\"\n}\n\n// validateHTTPStatusCode validates the HTTP status code and returns\n// corresponding span status code. If the `code` is not a valid HTTP status\n// code, returns span status Error and false.\nfunc validateHTTPStatusCode(code int) (codes.Code, bool) {\n\tcategory := code / 100\n\tranges, ok := validRangesPerCategory[category]\n\tif !ok {\n\t\treturn codes.Error, false\n\t}\n\tok = false\n\tfor _, crange := range ranges {\n\t\tok = crange.contains(code)\n\t\tif ok {\n\t\t\tbreak\n\t\t}\n\t}\n\tif !ok {\n\t\treturn codes.Error, false\n\t}\n\tif category > 0 && category < 4 {\n\t\treturn codes.Unset, true\n\t}\n\treturn codes.Error, true\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.37.0/MIGRATION.md",
    "content": "<!-- Generated. DO NOT MODIFY. -->\n# Migration from v1.36.0 to v1.37.0\n\nThe `go.opentelemetry.io/otel/semconv/v1.37.0` package should be a drop-in replacement for `go.opentelemetry.io/otel/semconv/v1.36.0` with the following exceptions.\n\n## Removed\n\nThe following declarations have been removed.\nRefer to the [OpenTelemetry Semantic Conventions documentation] for deprecation instructions.\n\nIf the type is not listed in the documentation as deprecated, it has been removed in this version due to lack of applicability or use.\nIf you use any of these non-deprecated declarations in your Go application, please [open an issue] describing your use-case.\n\n- `ContainerRuntime`\n- `ContainerRuntimeKey`\n- `GenAIOpenAIRequestServiceTierAuto`\n- `GenAIOpenAIRequestServiceTierDefault`\n- `GenAIOpenAIRequestServiceTierKey`\n- `GenAIOpenAIResponseServiceTier`\n- `GenAIOpenAIResponseServiceTierKey`\n- `GenAIOpenAIResponseSystemFingerprint`\n- `GenAIOpenAIResponseSystemFingerprintKey`\n- `GenAISystemAWSBedrock`\n- `GenAISystemAnthropic`\n- `GenAISystemAzureAIInference`\n- `GenAISystemAzureAIOpenAI`\n- `GenAISystemCohere`\n- `GenAISystemDeepseek`\n- `GenAISystemGCPGemini`\n- `GenAISystemGCPGenAI`\n- `GenAISystemGCPVertexAI`\n- `GenAISystemGroq`\n- `GenAISystemIBMWatsonxAI`\n- `GenAISystemKey`\n- `GenAISystemMistralAI`\n- `GenAISystemOpenAI`\n- `GenAISystemPerplexity`\n- `GenAISystemXai`\n\n[OpenTelemetry Semantic Conventions documentation]: https://github.com/open-telemetry/semantic-conventions\n[open an issue]: https://github.com/open-telemetry/opentelemetry-go/issues/new?template=Blank+issue\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.37.0/README.md",
    "content": "# Semconv v1.37.0\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/semconv/v1.37.0)](https://pkg.go.dev/go.opentelemetry.io/otel/semconv/v1.37.0)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.37.0/attribute_group.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Code generated from semantic convention specification. DO NOT EDIT.\n\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.37.0\"\n\nimport \"go.opentelemetry.io/otel/attribute\"\n\n// Namespace: android\nconst (\n\t// AndroidAppStateKey is the attribute Key conforming to the \"android.app.state\"\n\t// semantic conventions. It represents the this attribute represents the state\n\t// of the application.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"created\"\n\t// Note: The Android lifecycle states are defined in\n\t// [Activity lifecycle callbacks], and from which the `OS identifiers` are\n\t// derived.\n\t//\n\t// [Activity lifecycle callbacks]: https://developer.android.com/guide/components/activities/activity-lifecycle#lc\n\tAndroidAppStateKey = attribute.Key(\"android.app.state\")\n\n\t// AndroidOSAPILevelKey is the attribute Key conforming to the\n\t// \"android.os.api_level\" semantic conventions. It represents the uniquely\n\t// identifies the framework API revision offered by a version (`os.version`) of\n\t// the android operating system. More information can be found in the\n\t// [Android API levels documentation].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"33\", \"32\"\n\t//\n\t// [Android API levels documentation]: https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels\n\tAndroidOSAPILevelKey = attribute.Key(\"android.os.api_level\")\n)\n\n// AndroidOSAPILevel returns an attribute KeyValue conforming to the\n// \"android.os.api_level\" semantic conventions. It represents the uniquely\n// identifies the framework API revision offered by a version (`os.version`) of\n// the android operating system. More information can be found in the\n// [Android API levels documentation].\n//\n// [Android API levels documentation]: https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels\nfunc AndroidOSAPILevel(val string) attribute.KeyValue {\n\treturn AndroidOSAPILevelKey.String(val)\n}\n\n// Enum values for android.app.state\nvar (\n\t// Any time before Activity.onResume() or, if the app has no Activity,\n\t// Context.startService() has been called in the app for the first time.\n\t//\n\t// Stability: development\n\tAndroidAppStateCreated = AndroidAppStateKey.String(\"created\")\n\t// Any time after Activity.onPause() or, if the app has no Activity,\n\t// Context.stopService() has been called when the app was in the foreground\n\t// state.\n\t//\n\t// Stability: development\n\tAndroidAppStateBackground = AndroidAppStateKey.String(\"background\")\n\t// Any time after Activity.onResume() or, if the app has no Activity,\n\t// Context.startService() has been called when the app was in either the created\n\t// or background states.\n\t//\n\t// Stability: development\n\tAndroidAppStateForeground = AndroidAppStateKey.String(\"foreground\")\n)\n\n// Namespace: app\nconst (\n\t// AppBuildIDKey is the attribute Key conforming to the \"app.build_id\" semantic\n\t// conventions. It represents the unique identifier for a particular build or\n\t// compilation of the application.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"6cff0a7e-cefc-4668-96f5-1273d8b334d0\",\n\t// \"9f2b833506aa6973a92fde9733e6271f\", \"my-app-1.0.0-code-123\"\n\tAppBuildIDKey = attribute.Key(\"app.build_id\")\n\n\t// AppInstallationIDKey is the attribute Key conforming to the\n\t// \"app.installation.id\" semantic conventions. It represents a unique identifier\n\t// representing the installation of an application on a specific device.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2ab2916d-a51f-4ac8-80ee-45ac31a28092\"\n\t// Note: Its value SHOULD persist across launches of the same application\n\t// installation, including through application upgrades.\n\t// It SHOULD change if the application is uninstalled or if all applications of\n\t// the vendor are uninstalled.\n\t// Additionally, users might be able to reset this value (e.g. by clearing\n\t// application data).\n\t// If an app is installed multiple times on the same device (e.g. in different\n\t// accounts on Android), each `app.installation.id` SHOULD have a different\n\t// value.\n\t// If multiple OpenTelemetry SDKs are used within the same application, they\n\t// SHOULD use the same value for `app.installation.id`.\n\t// Hardware IDs (e.g. serial number, IMEI, MAC address) MUST NOT be used as the\n\t// `app.installation.id`.\n\t//\n\t// For iOS, this value SHOULD be equal to the [vendor identifier].\n\t//\n\t// For Android, examples of `app.installation.id` implementations include:\n\t//\n\t//   - [Firebase Installation ID].\n\t//   - A globally unique UUID which is persisted across sessions in your\n\t//     application.\n\t//   - [App set ID].\n\t//   - [`Settings.getString(Settings.Secure.ANDROID_ID)`].\n\t//\n\t// More information about Android identifier best practices can be found in the\n\t// [Android user data IDs guide].\n\t//\n\t// [vendor identifier]: https://developer.apple.com/documentation/uikit/uidevice/identifierforvendor\n\t// [Firebase Installation ID]: https://firebase.google.com/docs/projects/manage-installations\n\t// [App set ID]: https://developer.android.com/identity/app-set-id\n\t// [`Settings.getString(Settings.Secure.ANDROID_ID)`]: https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID\n\t// [Android user data IDs guide]: https://developer.android.com/training/articles/user-data-ids\n\tAppInstallationIDKey = attribute.Key(\"app.installation.id\")\n\n\t// AppJankFrameCountKey is the attribute Key conforming to the\n\t// \"app.jank.frame_count\" semantic conventions. It represents a number of frame\n\t// renders that experienced jank.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 9, 42\n\t// Note: Depending on platform limitations, the value provided MAY be\n\t// approximation.\n\tAppJankFrameCountKey = attribute.Key(\"app.jank.frame_count\")\n\n\t// AppJankPeriodKey is the attribute Key conforming to the \"app.jank.period\"\n\t// semantic conventions. It represents the time period, in seconds, for which\n\t// this jank is being reported.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1.0, 5.0, 10.24\n\tAppJankPeriodKey = attribute.Key(\"app.jank.period\")\n\n\t// AppJankThresholdKey is the attribute Key conforming to the\n\t// \"app.jank.threshold\" semantic conventions. It represents the minimum\n\t// rendering threshold for this jank, in seconds.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0.016, 0.7, 1.024\n\tAppJankThresholdKey = attribute.Key(\"app.jank.threshold\")\n\n\t// AppScreenCoordinateXKey is the attribute Key conforming to the\n\t// \"app.screen.coordinate.x\" semantic conventions. It represents the x\n\t// (horizontal) coordinate of a screen coordinate, in screen pixels.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0, 131\n\tAppScreenCoordinateXKey = attribute.Key(\"app.screen.coordinate.x\")\n\n\t// AppScreenCoordinateYKey is the attribute Key conforming to the\n\t// \"app.screen.coordinate.y\" semantic conventions. It represents the y\n\t// (vertical) component of a screen coordinate, in screen pixels.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 12, 99\n\tAppScreenCoordinateYKey = attribute.Key(\"app.screen.coordinate.y\")\n\n\t// AppWidgetIDKey is the attribute Key conforming to the \"app.widget.id\"\n\t// semantic conventions. It represents an identifier that uniquely\n\t// differentiates this widget from other widgets in the same application.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"f9bc787d-ff05-48ad-90e1-fca1d46130b3\", \"submit_order_1829\"\n\t// Note: A widget is an application component, typically an on-screen visual GUI\n\t// element.\n\tAppWidgetIDKey = attribute.Key(\"app.widget.id\")\n\n\t// AppWidgetNameKey is the attribute Key conforming to the \"app.widget.name\"\n\t// semantic conventions. It represents the name of an application widget.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"submit\", \"attack\", \"Clear Cart\"\n\t// Note: A widget is an application component, typically an on-screen visual GUI\n\t// element.\n\tAppWidgetNameKey = attribute.Key(\"app.widget.name\")\n)\n\n// AppBuildID returns an attribute KeyValue conforming to the \"app.build_id\"\n// semantic conventions. It represents the unique identifier for a particular\n// build or compilation of the application.\nfunc AppBuildID(val string) attribute.KeyValue {\n\treturn AppBuildIDKey.String(val)\n}\n\n// AppInstallationID returns an attribute KeyValue conforming to the\n// \"app.installation.id\" semantic conventions. It represents a unique identifier\n// representing the installation of an application on a specific device.\nfunc AppInstallationID(val string) attribute.KeyValue {\n\treturn AppInstallationIDKey.String(val)\n}\n\n// AppJankFrameCount returns an attribute KeyValue conforming to the\n// \"app.jank.frame_count\" semantic conventions. It represents a number of frame\n// renders that experienced jank.\nfunc AppJankFrameCount(val int) attribute.KeyValue {\n\treturn AppJankFrameCountKey.Int(val)\n}\n\n// AppJankPeriod returns an attribute KeyValue conforming to the\n// \"app.jank.period\" semantic conventions. It represents the time period, in\n// seconds, for which this jank is being reported.\nfunc AppJankPeriod(val float64) attribute.KeyValue {\n\treturn AppJankPeriodKey.Float64(val)\n}\n\n// AppJankThreshold returns an attribute KeyValue conforming to the\n// \"app.jank.threshold\" semantic conventions. It represents the minimum rendering\n// threshold for this jank, in seconds.\nfunc AppJankThreshold(val float64) attribute.KeyValue {\n\treturn AppJankThresholdKey.Float64(val)\n}\n\n// AppScreenCoordinateX returns an attribute KeyValue conforming to the\n// \"app.screen.coordinate.x\" semantic conventions. It represents the x\n// (horizontal) coordinate of a screen coordinate, in screen pixels.\nfunc AppScreenCoordinateX(val int) attribute.KeyValue {\n\treturn AppScreenCoordinateXKey.Int(val)\n}\n\n// AppScreenCoordinateY returns an attribute KeyValue conforming to the\n// \"app.screen.coordinate.y\" semantic conventions. It represents the y (vertical)\n// component of a screen coordinate, in screen pixels.\nfunc AppScreenCoordinateY(val int) attribute.KeyValue {\n\treturn AppScreenCoordinateYKey.Int(val)\n}\n\n// AppWidgetID returns an attribute KeyValue conforming to the \"app.widget.id\"\n// semantic conventions. It represents an identifier that uniquely differentiates\n// this widget from other widgets in the same application.\nfunc AppWidgetID(val string) attribute.KeyValue {\n\treturn AppWidgetIDKey.String(val)\n}\n\n// AppWidgetName returns an attribute KeyValue conforming to the\n// \"app.widget.name\" semantic conventions. It represents the name of an\n// application widget.\nfunc AppWidgetName(val string) attribute.KeyValue {\n\treturn AppWidgetNameKey.String(val)\n}\n\n// Namespace: artifact\nconst (\n\t// ArtifactAttestationFilenameKey is the attribute Key conforming to the\n\t// \"artifact.attestation.filename\" semantic conventions. It represents the\n\t// provenance filename of the built attestation which directly relates to the\n\t// build artifact filename. This filename SHOULD accompany the artifact at\n\t// publish time. See the [SLSA Relationship] specification for more information.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"golang-binary-amd64-v0.1.0.attestation\",\n\t// \"docker-image-amd64-v0.1.0.intoto.json1\", \"release-1.tar.gz.attestation\",\n\t// \"file-name-package.tar.gz.intoto.json1\"\n\t//\n\t// [SLSA Relationship]: https://slsa.dev/spec/v1.0/distributing-provenance#relationship-between-artifacts-and-attestations\n\tArtifactAttestationFilenameKey = attribute.Key(\"artifact.attestation.filename\")\n\n\t// ArtifactAttestationHashKey is the attribute Key conforming to the\n\t// \"artifact.attestation.hash\" semantic conventions. It represents the full\n\t// [hash value (see glossary)], of the built attestation. Some envelopes in the\n\t// [software attestation space] also refer to this as the **digest**.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1b31dfcd5b7f9267bf2ff47651df1cfb9147b9e4df1f335accf65b4cda498408\"\n\t//\n\t// [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf\n\t// [software attestation space]: https://github.com/in-toto/attestation/tree/main/spec\n\tArtifactAttestationHashKey = attribute.Key(\"artifact.attestation.hash\")\n\n\t// ArtifactAttestationIDKey is the attribute Key conforming to the\n\t// \"artifact.attestation.id\" semantic conventions. It represents the id of the\n\t// build [software attestation].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"123\"\n\t//\n\t// [software attestation]: https://slsa.dev/attestation-model\n\tArtifactAttestationIDKey = attribute.Key(\"artifact.attestation.id\")\n\n\t// ArtifactFilenameKey is the attribute Key conforming to the\n\t// \"artifact.filename\" semantic conventions. It represents the human readable\n\t// file name of the artifact, typically generated during build and release\n\t// processes. Often includes the package name and version in the file name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"golang-binary-amd64-v0.1.0\", \"docker-image-amd64-v0.1.0\",\n\t// \"release-1.tar.gz\", \"file-name-package.tar.gz\"\n\t// Note: This file name can also act as the [Package Name]\n\t// in cases where the package ecosystem maps accordingly.\n\t// Additionally, the artifact [can be published]\n\t// for others, but that is not a guarantee.\n\t//\n\t// [Package Name]: https://slsa.dev/spec/v1.0/terminology#package-model\n\t// [can be published]: https://slsa.dev/spec/v1.0/terminology#software-supply-chain\n\tArtifactFilenameKey = attribute.Key(\"artifact.filename\")\n\n\t// ArtifactHashKey is the attribute Key conforming to the \"artifact.hash\"\n\t// semantic conventions. It represents the full [hash value (see glossary)],\n\t// often found in checksum.txt on a release of the artifact and used to verify\n\t// package integrity.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"9ff4c52759e2c4ac70b7d517bc7fcdc1cda631ca0045271ddd1b192544f8a3e9\"\n\t// Note: The specific algorithm used to create the cryptographic hash value is\n\t// not defined. In situations where an artifact has multiple\n\t// cryptographic hashes, it is up to the implementer to choose which\n\t// hash value to set here; this should be the most secure hash algorithm\n\t// that is suitable for the situation and consistent with the\n\t// corresponding attestation. The implementer can then provide the other\n\t// hash values through an additional set of attribute extensions as they\n\t// deem necessary.\n\t//\n\t// [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf\n\tArtifactHashKey = attribute.Key(\"artifact.hash\")\n\n\t// ArtifactPurlKey is the attribute Key conforming to the \"artifact.purl\"\n\t// semantic conventions. It represents the [Package URL] of the\n\t// [package artifact] provides a standard way to identify and locate the\n\t// packaged artifact.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"pkg:github/package-url/purl-spec@1209109710924\",\n\t// \"pkg:npm/foo@12.12.3\"\n\t//\n\t// [Package URL]: https://github.com/package-url/purl-spec\n\t// [package artifact]: https://slsa.dev/spec/v1.0/terminology#package-model\n\tArtifactPurlKey = attribute.Key(\"artifact.purl\")\n\n\t// ArtifactVersionKey is the attribute Key conforming to the \"artifact.version\"\n\t// semantic conventions. It represents the version of the artifact.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"v0.1.0\", \"1.2.1\", \"122691-build\"\n\tArtifactVersionKey = attribute.Key(\"artifact.version\")\n)\n\n// ArtifactAttestationFilename returns an attribute KeyValue conforming to the\n// \"artifact.attestation.filename\" semantic conventions. It represents the\n// provenance filename of the built attestation which directly relates to the\n// build artifact filename. This filename SHOULD accompany the artifact at\n// publish time. See the [SLSA Relationship] specification for more information.\n//\n// [SLSA Relationship]: https://slsa.dev/spec/v1.0/distributing-provenance#relationship-between-artifacts-and-attestations\nfunc ArtifactAttestationFilename(val string) attribute.KeyValue {\n\treturn ArtifactAttestationFilenameKey.String(val)\n}\n\n// ArtifactAttestationHash returns an attribute KeyValue conforming to the\n// \"artifact.attestation.hash\" semantic conventions. It represents the full\n// [hash value (see glossary)], of the built attestation. Some envelopes in the\n// [software attestation space] also refer to this as the **digest**.\n//\n// [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf\n// [software attestation space]: https://github.com/in-toto/attestation/tree/main/spec\nfunc ArtifactAttestationHash(val string) attribute.KeyValue {\n\treturn ArtifactAttestationHashKey.String(val)\n}\n\n// ArtifactAttestationID returns an attribute KeyValue conforming to the\n// \"artifact.attestation.id\" semantic conventions. It represents the id of the\n// build [software attestation].\n//\n// [software attestation]: https://slsa.dev/attestation-model\nfunc ArtifactAttestationID(val string) attribute.KeyValue {\n\treturn ArtifactAttestationIDKey.String(val)\n}\n\n// ArtifactFilename returns an attribute KeyValue conforming to the\n// \"artifact.filename\" semantic conventions. It represents the human readable\n// file name of the artifact, typically generated during build and release\n// processes. Often includes the package name and version in the file name.\nfunc ArtifactFilename(val string) attribute.KeyValue {\n\treturn ArtifactFilenameKey.String(val)\n}\n\n// ArtifactHash returns an attribute KeyValue conforming to the \"artifact.hash\"\n// semantic conventions. It represents the full [hash value (see glossary)],\n// often found in checksum.txt on a release of the artifact and used to verify\n// package integrity.\n//\n// [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf\nfunc ArtifactHash(val string) attribute.KeyValue {\n\treturn ArtifactHashKey.String(val)\n}\n\n// ArtifactPurl returns an attribute KeyValue conforming to the \"artifact.purl\"\n// semantic conventions. It represents the [Package URL] of the\n// [package artifact] provides a standard way to identify and locate the packaged\n// artifact.\n//\n// [Package URL]: https://github.com/package-url/purl-spec\n// [package artifact]: https://slsa.dev/spec/v1.0/terminology#package-model\nfunc ArtifactPurl(val string) attribute.KeyValue {\n\treturn ArtifactPurlKey.String(val)\n}\n\n// ArtifactVersion returns an attribute KeyValue conforming to the\n// \"artifact.version\" semantic conventions. It represents the version of the\n// artifact.\nfunc ArtifactVersion(val string) attribute.KeyValue {\n\treturn ArtifactVersionKey.String(val)\n}\n\n// Namespace: aws\nconst (\n\t// AWSBedrockGuardrailIDKey is the attribute Key conforming to the\n\t// \"aws.bedrock.guardrail.id\" semantic conventions. It represents the unique\n\t// identifier of the AWS Bedrock Guardrail. A [guardrail] helps safeguard and\n\t// prevent unwanted behavior from model responses or user messages.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"sgi5gkybzqak\"\n\t//\n\t// [guardrail]: https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html\n\tAWSBedrockGuardrailIDKey = attribute.Key(\"aws.bedrock.guardrail.id\")\n\n\t// AWSBedrockKnowledgeBaseIDKey is the attribute Key conforming to the\n\t// \"aws.bedrock.knowledge_base.id\" semantic conventions. It represents the\n\t// unique identifier of the AWS Bedrock Knowledge base. A [knowledge base] is a\n\t// bank of information that can be queried by models to generate more relevant\n\t// responses and augment prompts.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"XFWUPB9PAW\"\n\t//\n\t// [knowledge base]: https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base.html\n\tAWSBedrockKnowledgeBaseIDKey = attribute.Key(\"aws.bedrock.knowledge_base.id\")\n\n\t// AWSDynamoDBAttributeDefinitionsKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.attribute_definitions\" semantic conventions. It represents the\n\t// JSON-serialized value of each item in the `AttributeDefinitions` request\n\t// field.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"{ \"AttributeName\": \"string\", \"AttributeType\": \"string\" }\"\n\tAWSDynamoDBAttributeDefinitionsKey = attribute.Key(\"aws.dynamodb.attribute_definitions\")\n\n\t// AWSDynamoDBAttributesToGetKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.attributes_to_get\" semantic conventions. It represents the\n\t// value of the `AttributesToGet` request parameter.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"lives\", \"id\"\n\tAWSDynamoDBAttributesToGetKey = attribute.Key(\"aws.dynamodb.attributes_to_get\")\n\n\t// AWSDynamoDBConsistentReadKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.consistent_read\" semantic conventions. It represents the value\n\t// of the `ConsistentRead` request parameter.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tAWSDynamoDBConsistentReadKey = attribute.Key(\"aws.dynamodb.consistent_read\")\n\n\t// AWSDynamoDBConsumedCapacityKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.consumed_capacity\" semantic conventions. It represents the\n\t// JSON-serialized value of each item in the `ConsumedCapacity` response field.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"{ \"CapacityUnits\": number, \"GlobalSecondaryIndexes\": { \"string\" :\n\t// { \"CapacityUnits\": number, \"ReadCapacityUnits\": number, \"WriteCapacityUnits\":\n\t// number } }, \"LocalSecondaryIndexes\": { \"string\" : { \"CapacityUnits\": number,\n\t// \"ReadCapacityUnits\": number, \"WriteCapacityUnits\": number } },\n\t// \"ReadCapacityUnits\": number, \"Table\": { \"CapacityUnits\": number,\n\t// \"ReadCapacityUnits\": number, \"WriteCapacityUnits\": number }, \"TableName\":\n\t// \"string\", \"WriteCapacityUnits\": number }\"\n\tAWSDynamoDBConsumedCapacityKey = attribute.Key(\"aws.dynamodb.consumed_capacity\")\n\n\t// AWSDynamoDBCountKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.count\" semantic conventions. It represents the value of the\n\t// `Count` response parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 10\n\tAWSDynamoDBCountKey = attribute.Key(\"aws.dynamodb.count\")\n\n\t// AWSDynamoDBExclusiveStartTableKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.exclusive_start_table\" semantic conventions. It represents the\n\t// value of the `ExclusiveStartTableName` request parameter.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Users\", \"CatsTable\"\n\tAWSDynamoDBExclusiveStartTableKey = attribute.Key(\"aws.dynamodb.exclusive_start_table\")\n\n\t// AWSDynamoDBGlobalSecondaryIndexUpdatesKey is the attribute Key conforming to\n\t// the \"aws.dynamodb.global_secondary_index_updates\" semantic conventions. It\n\t// represents the JSON-serialized value of each item in the\n\t// `GlobalSecondaryIndexUpdates` request field.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"{ \"Create\": { \"IndexName\": \"string\", \"KeySchema\": [ {\n\t// \"AttributeName\": \"string\", \"KeyType\": \"string\" } ], \"Projection\": {\n\t// \"NonKeyAttributes\": [ \"string\" ], \"ProjectionType\": \"string\" },\n\t// \"ProvisionedThroughput\": { \"ReadCapacityUnits\": number, \"WriteCapacityUnits\":\n\t// number } }\"\n\tAWSDynamoDBGlobalSecondaryIndexUpdatesKey = attribute.Key(\"aws.dynamodb.global_secondary_index_updates\")\n\n\t// AWSDynamoDBGlobalSecondaryIndexesKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.global_secondary_indexes\" semantic conventions. It represents\n\t// the JSON-serialized value of each item of the `GlobalSecondaryIndexes`\n\t// request field.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"{ \"IndexName\": \"string\", \"KeySchema\": [ { \"AttributeName\":\n\t// \"string\", \"KeyType\": \"string\" } ], \"Projection\": { \"NonKeyAttributes\": [\n\t// \"string\" ], \"ProjectionType\": \"string\" }, \"ProvisionedThroughput\": {\n\t// \"ReadCapacityUnits\": number, \"WriteCapacityUnits\": number } }\"\n\tAWSDynamoDBGlobalSecondaryIndexesKey = attribute.Key(\"aws.dynamodb.global_secondary_indexes\")\n\n\t// AWSDynamoDBIndexNameKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.index_name\" semantic conventions. It represents the value of\n\t// the `IndexName` request parameter.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"name_to_group\"\n\tAWSDynamoDBIndexNameKey = attribute.Key(\"aws.dynamodb.index_name\")\n\n\t// AWSDynamoDBItemCollectionMetricsKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.item_collection_metrics\" semantic conventions. It represents\n\t// the JSON-serialized value of the `ItemCollectionMetrics` response field.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"{ \"string\" : [ { \"ItemCollectionKey\": { \"string\" : { \"B\": blob,\n\t// \"BOOL\": boolean, \"BS\": [ blob ], \"L\": [ \"AttributeValue\" ], \"M\": { \"string\" :\n\t// \"AttributeValue\" }, \"N\": \"string\", \"NS\": [ \"string\" ], \"NULL\": boolean, \"S\":\n\t// \"string\", \"SS\": [ \"string\" ] } }, \"SizeEstimateRangeGB\": [ number ] } ] }\"\n\tAWSDynamoDBItemCollectionMetricsKey = attribute.Key(\"aws.dynamodb.item_collection_metrics\")\n\n\t// AWSDynamoDBLimitKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.limit\" semantic conventions. It represents the value of the\n\t// `Limit` request parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 10\n\tAWSDynamoDBLimitKey = attribute.Key(\"aws.dynamodb.limit\")\n\n\t// AWSDynamoDBLocalSecondaryIndexesKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.local_secondary_indexes\" semantic conventions. It represents\n\t// the JSON-serialized value of each item of the `LocalSecondaryIndexes` request\n\t// field.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"{ \"IndexArn\": \"string\", \"IndexName\": \"string\", \"IndexSizeBytes\":\n\t// number, \"ItemCount\": number, \"KeySchema\": [ { \"AttributeName\": \"string\",\n\t// \"KeyType\": \"string\" } ], \"Projection\": { \"NonKeyAttributes\": [ \"string\" ],\n\t// \"ProjectionType\": \"string\" } }\"\n\tAWSDynamoDBLocalSecondaryIndexesKey = attribute.Key(\"aws.dynamodb.local_secondary_indexes\")\n\n\t// AWSDynamoDBProjectionKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.projection\" semantic conventions. It represents the value of\n\t// the `ProjectionExpression` request parameter.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Title\", \"Title, Price, Color\", \"Title, Description, RelatedItems,\n\t// ProductReviews\"\n\tAWSDynamoDBProjectionKey = attribute.Key(\"aws.dynamodb.projection\")\n\n\t// AWSDynamoDBProvisionedReadCapacityKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.provisioned_read_capacity\" semantic conventions. It represents\n\t// the value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1.0, 2.0\n\tAWSDynamoDBProvisionedReadCapacityKey = attribute.Key(\"aws.dynamodb.provisioned_read_capacity\")\n\n\t// AWSDynamoDBProvisionedWriteCapacityKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.provisioned_write_capacity\" semantic conventions. It represents\n\t// the value of the `ProvisionedThroughput.WriteCapacityUnits` request\n\t// parameter.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1.0, 2.0\n\tAWSDynamoDBProvisionedWriteCapacityKey = attribute.Key(\"aws.dynamodb.provisioned_write_capacity\")\n\n\t// AWSDynamoDBScanForwardKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.scan_forward\" semantic conventions. It represents the value of\n\t// the `ScanIndexForward` request parameter.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tAWSDynamoDBScanForwardKey = attribute.Key(\"aws.dynamodb.scan_forward\")\n\n\t// AWSDynamoDBScannedCountKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.scanned_count\" semantic conventions. It represents the value of\n\t// the `ScannedCount` response parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 50\n\tAWSDynamoDBScannedCountKey = attribute.Key(\"aws.dynamodb.scanned_count\")\n\n\t// AWSDynamoDBSegmentKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.segment\" semantic conventions. It represents the value of the\n\t// `Segment` request parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 10\n\tAWSDynamoDBSegmentKey = attribute.Key(\"aws.dynamodb.segment\")\n\n\t// AWSDynamoDBSelectKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.select\" semantic conventions. It represents the value of the\n\t// `Select` request parameter.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"ALL_ATTRIBUTES\", \"COUNT\"\n\tAWSDynamoDBSelectKey = attribute.Key(\"aws.dynamodb.select\")\n\n\t// AWSDynamoDBTableCountKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.table_count\" semantic conventions. It represents the number of\n\t// items in the `TableNames` response parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 20\n\tAWSDynamoDBTableCountKey = attribute.Key(\"aws.dynamodb.table_count\")\n\n\t// AWSDynamoDBTableNamesKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.table_names\" semantic conventions. It represents the keys in\n\t// the `RequestItems` object field.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Users\", \"Cats\"\n\tAWSDynamoDBTableNamesKey = attribute.Key(\"aws.dynamodb.table_names\")\n\n\t// AWSDynamoDBTotalSegmentsKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.total_segments\" semantic conventions. It represents the value\n\t// of the `TotalSegments` request parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 100\n\tAWSDynamoDBTotalSegmentsKey = attribute.Key(\"aws.dynamodb.total_segments\")\n\n\t// AWSECSClusterARNKey is the attribute Key conforming to the\n\t// \"aws.ecs.cluster.arn\" semantic conventions. It represents the ARN of an\n\t// [ECS cluster].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster\"\n\t//\n\t// [ECS cluster]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html\n\tAWSECSClusterARNKey = attribute.Key(\"aws.ecs.cluster.arn\")\n\n\t// AWSECSContainerARNKey is the attribute Key conforming to the\n\t// \"aws.ecs.container.arn\" semantic conventions. It represents the Amazon\n\t// Resource Name (ARN) of an [ECS container instance].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9\"\n\t//\n\t// [ECS container instance]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html\n\tAWSECSContainerARNKey = attribute.Key(\"aws.ecs.container.arn\")\n\n\t// AWSECSLaunchtypeKey is the attribute Key conforming to the\n\t// \"aws.ecs.launchtype\" semantic conventions. It represents the [launch type]\n\t// for an ECS task.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t//\n\t// [launch type]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html\n\tAWSECSLaunchtypeKey = attribute.Key(\"aws.ecs.launchtype\")\n\n\t// AWSECSTaskARNKey is the attribute Key conforming to the \"aws.ecs.task.arn\"\n\t// semantic conventions. It represents the ARN of a running [ECS task].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b\",\n\t// \"arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd\"\n\t//\n\t// [ECS task]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids\n\tAWSECSTaskARNKey = attribute.Key(\"aws.ecs.task.arn\")\n\n\t// AWSECSTaskFamilyKey is the attribute Key conforming to the\n\t// \"aws.ecs.task.family\" semantic conventions. It represents the family name of\n\t// the [ECS task definition] used to create the ECS task.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry-family\"\n\t//\n\t// [ECS task definition]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html\n\tAWSECSTaskFamilyKey = attribute.Key(\"aws.ecs.task.family\")\n\n\t// AWSECSTaskIDKey is the attribute Key conforming to the \"aws.ecs.task.id\"\n\t// semantic conventions. It represents the ID of a running ECS task. The ID MUST\n\t// be extracted from `task.arn`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"10838bed-421f-43ef-870a-f43feacbbb5b\",\n\t// \"23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd\"\n\tAWSECSTaskIDKey = attribute.Key(\"aws.ecs.task.id\")\n\n\t// AWSECSTaskRevisionKey is the attribute Key conforming to the\n\t// \"aws.ecs.task.revision\" semantic conventions. It represents the revision for\n\t// the task definition used to create the ECS task.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"8\", \"26\"\n\tAWSECSTaskRevisionKey = attribute.Key(\"aws.ecs.task.revision\")\n\n\t// AWSEKSClusterARNKey is the attribute Key conforming to the\n\t// \"aws.eks.cluster.arn\" semantic conventions. It represents the ARN of an EKS\n\t// cluster.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster\"\n\tAWSEKSClusterARNKey = attribute.Key(\"aws.eks.cluster.arn\")\n\n\t// AWSExtendedRequestIDKey is the attribute Key conforming to the\n\t// \"aws.extended_request_id\" semantic conventions. It represents the AWS\n\t// extended request ID as returned in the response header `x-amz-id-2`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"wzHcyEWfmOGDIE5QOhTAqFDoDWP3y8IUvpNINCwL9N4TEHbUw0/gZJ+VZTmCNCWR7fezEN3eCiQ=\"\n\tAWSExtendedRequestIDKey = attribute.Key(\"aws.extended_request_id\")\n\n\t// AWSKinesisStreamNameKey is the attribute Key conforming to the\n\t// \"aws.kinesis.stream_name\" semantic conventions. It represents the name of the\n\t// AWS Kinesis [stream] the request refers to. Corresponds to the\n\t// `--stream-name` parameter of the Kinesis [describe-stream] operation.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"some-stream-name\"\n\t//\n\t// [stream]: https://docs.aws.amazon.com/streams/latest/dev/introduction.html\n\t// [describe-stream]: https://docs.aws.amazon.com/cli/latest/reference/kinesis/describe-stream.html\n\tAWSKinesisStreamNameKey = attribute.Key(\"aws.kinesis.stream_name\")\n\n\t// AWSLambdaInvokedARNKey is the attribute Key conforming to the\n\t// \"aws.lambda.invoked_arn\" semantic conventions. It represents the full invoked\n\t// ARN as provided on the `Context` passed to the function (\n\t// `Lambda-Runtime-Invoked-Function-Arn` header on the\n\t// `/runtime/invocation/next` applicable).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"arn:aws:lambda:us-east-1:123456:function:myfunction:myalias\"\n\t// Note: This may be different from `cloud.resource_id` if an alias is involved.\n\tAWSLambdaInvokedARNKey = attribute.Key(\"aws.lambda.invoked_arn\")\n\n\t// AWSLambdaResourceMappingIDKey is the attribute Key conforming to the\n\t// \"aws.lambda.resource_mapping.id\" semantic conventions. It represents the UUID\n\t// of the [AWS Lambda EvenSource Mapping]. An event source is mapped to a lambda\n\t// function. It's contents are read by Lambda and used to trigger a function.\n\t// This isn't available in the lambda execution context or the lambda runtime\n\t// environtment. This is going to be populated by the AWS SDK for each language\n\t// when that UUID is present. Some of these operations are\n\t// Create/Delete/Get/List/Update EventSourceMapping.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"587ad24b-03b9-4413-8202-bbd56b36e5b7\"\n\t//\n\t// [AWS Lambda EvenSource Mapping]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html\n\tAWSLambdaResourceMappingIDKey = attribute.Key(\"aws.lambda.resource_mapping.id\")\n\n\t// AWSLogGroupARNsKey is the attribute Key conforming to the\n\t// \"aws.log.group.arns\" semantic conventions. It represents the Amazon Resource\n\t// Name(s) (ARN) of the AWS log group(s).\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*\"\n\t// Note: See the [log group ARN format documentation].\n\t//\n\t// [log group ARN format documentation]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format\n\tAWSLogGroupARNsKey = attribute.Key(\"aws.log.group.arns\")\n\n\t// AWSLogGroupNamesKey is the attribute Key conforming to the\n\t// \"aws.log.group.names\" semantic conventions. It represents the name(s) of the\n\t// AWS log group(s) an application is writing to.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/aws/lambda/my-function\", \"opentelemetry-service\"\n\t// Note: Multiple log groups must be supported for cases like multi-container\n\t// applications, where a single application has sidecar containers, and each\n\t// write to their own log group.\n\tAWSLogGroupNamesKey = attribute.Key(\"aws.log.group.names\")\n\n\t// AWSLogStreamARNsKey is the attribute Key conforming to the\n\t// \"aws.log.stream.arns\" semantic conventions. It represents the ARN(s) of the\n\t// AWS log stream(s).\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b\"\n\t// Note: See the [log stream ARN format documentation]. One log group can\n\t// contain several log streams, so these ARNs necessarily identify both a log\n\t// group and a log stream.\n\t//\n\t// [log stream ARN format documentation]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format\n\tAWSLogStreamARNsKey = attribute.Key(\"aws.log.stream.arns\")\n\n\t// AWSLogStreamNamesKey is the attribute Key conforming to the\n\t// \"aws.log.stream.names\" semantic conventions. It represents the name(s) of the\n\t// AWS log stream(s) an application is writing to.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"logs/main/10838bed-421f-43ef-870a-f43feacbbb5b\"\n\tAWSLogStreamNamesKey = attribute.Key(\"aws.log.stream.names\")\n\n\t// AWSRequestIDKey is the attribute Key conforming to the \"aws.request_id\"\n\t// semantic conventions. It represents the AWS request ID as returned in the\n\t// response headers `x-amzn-requestid`, `x-amzn-request-id` or\n\t// `x-amz-request-id`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"79b9da39-b7ae-508a-a6bc-864b2829c622\", \"C9ER4AJX75574TDJ\"\n\tAWSRequestIDKey = attribute.Key(\"aws.request_id\")\n\n\t// AWSS3BucketKey is the attribute Key conforming to the \"aws.s3.bucket\"\n\t// semantic conventions. It represents the S3 bucket name the request refers to.\n\t// Corresponds to the `--bucket` parameter of the [S3 API] operations.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"some-bucket-name\"\n\t// Note: The `bucket` attribute is applicable to all S3 operations that\n\t// reference a bucket, i.e. that require the bucket name as a mandatory\n\t// parameter.\n\t// This applies to almost all S3 operations except `list-buckets`.\n\t//\n\t// [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html\n\tAWSS3BucketKey = attribute.Key(\"aws.s3.bucket\")\n\n\t// AWSS3CopySourceKey is the attribute Key conforming to the\n\t// \"aws.s3.copy_source\" semantic conventions. It represents the source object\n\t// (in the form `bucket`/`key`) for the copy operation.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"someFile.yml\"\n\t// Note: The `copy_source` attribute applies to S3 copy operations and\n\t// corresponds to the `--copy-source` parameter\n\t// of the [copy-object operation within the S3 API].\n\t// This applies in particular to the following operations:\n\t//\n\t//   - [copy-object]\n\t//   - [upload-part-copy]\n\t//\n\t//\n\t// [copy-object operation within the S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html\n\t// [copy-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html\n\t// [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html\n\tAWSS3CopySourceKey = attribute.Key(\"aws.s3.copy_source\")\n\n\t// AWSS3DeleteKey is the attribute Key conforming to the \"aws.s3.delete\"\n\t// semantic conventions. It represents the delete request container that\n\t// specifies the objects to be deleted.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean\"\n\t// Note: The `delete` attribute is only applicable to the [delete-object]\n\t// operation.\n\t// The `delete` attribute corresponds to the `--delete` parameter of the\n\t// [delete-objects operation within the S3 API].\n\t//\n\t// [delete-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html\n\t// [delete-objects operation within the S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html\n\tAWSS3DeleteKey = attribute.Key(\"aws.s3.delete\")\n\n\t// AWSS3KeyKey is the attribute Key conforming to the \"aws.s3.key\" semantic\n\t// conventions. It represents the S3 object key the request refers to.\n\t// Corresponds to the `--key` parameter of the [S3 API] operations.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"someFile.yml\"\n\t// Note: The `key` attribute is applicable to all object-related S3 operations,\n\t// i.e. that require the object key as a mandatory parameter.\n\t// This applies in particular to the following operations:\n\t//\n\t//   - [copy-object]\n\t//   - [delete-object]\n\t//   - [get-object]\n\t//   - [head-object]\n\t//   - [put-object]\n\t//   - [restore-object]\n\t//   - [select-object-content]\n\t//   - [abort-multipart-upload]\n\t//   - [complete-multipart-upload]\n\t//   - [create-multipart-upload]\n\t//   - [list-parts]\n\t//   - [upload-part]\n\t//   - [upload-part-copy]\n\t//\n\t//\n\t// [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html\n\t// [copy-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html\n\t// [delete-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html\n\t// [get-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/get-object.html\n\t// [head-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/head-object.html\n\t// [put-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.html\n\t// [restore-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/restore-object.html\n\t// [select-object-content]: https://docs.aws.amazon.com/cli/latest/reference/s3api/select-object-content.html\n\t// [abort-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html\n\t// [complete-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html\n\t// [create-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/create-multipart-upload.html\n\t// [list-parts]: https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html\n\t// [upload-part]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html\n\t// [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html\n\tAWSS3KeyKey = attribute.Key(\"aws.s3.key\")\n\n\t// AWSS3PartNumberKey is the attribute Key conforming to the\n\t// \"aws.s3.part_number\" semantic conventions. It represents the part number of\n\t// the part being uploaded in a multipart-upload operation. This is a positive\n\t// integer between 1 and 10,000.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 3456\n\t// Note: The `part_number` attribute is only applicable to the [upload-part]\n\t// and [upload-part-copy] operations.\n\t// The `part_number` attribute corresponds to the `--part-number` parameter of\n\t// the\n\t// [upload-part operation within the S3 API].\n\t//\n\t// [upload-part]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html\n\t// [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html\n\t// [upload-part operation within the S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html\n\tAWSS3PartNumberKey = attribute.Key(\"aws.s3.part_number\")\n\n\t// AWSS3UploadIDKey is the attribute Key conforming to the \"aws.s3.upload_id\"\n\t// semantic conventions. It represents the upload ID that identifies the\n\t// multipart upload.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ\"\n\t// Note: The `upload_id` attribute applies to S3 multipart-upload operations and\n\t// corresponds to the `--upload-id` parameter\n\t// of the [S3 API] multipart operations.\n\t// This applies in particular to the following operations:\n\t//\n\t//   - [abort-multipart-upload]\n\t//   - [complete-multipart-upload]\n\t//   - [list-parts]\n\t//   - [upload-part]\n\t//   - [upload-part-copy]\n\t//\n\t//\n\t// [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html\n\t// [abort-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html\n\t// [complete-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html\n\t// [list-parts]: https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html\n\t// [upload-part]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html\n\t// [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html\n\tAWSS3UploadIDKey = attribute.Key(\"aws.s3.upload_id\")\n\n\t// AWSSecretsmanagerSecretARNKey is the attribute Key conforming to the\n\t// \"aws.secretsmanager.secret.arn\" semantic conventions. It represents the ARN\n\t// of the Secret stored in the Secrets Mangger.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"arn:aws:secretsmanager:us-east-1:123456789012:secret:SecretName-6RandomCharacters\"\n\tAWSSecretsmanagerSecretARNKey = attribute.Key(\"aws.secretsmanager.secret.arn\")\n\n\t// AWSSNSTopicARNKey is the attribute Key conforming to the \"aws.sns.topic.arn\"\n\t// semantic conventions. It represents the ARN of the AWS SNS Topic. An Amazon\n\t// SNS [topic] is a logical access point that acts as a communication channel.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"arn:aws:sns:us-east-1:123456789012:mystack-mytopic-NZJ5JSMVGFIE\"\n\t//\n\t// [topic]: https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html\n\tAWSSNSTopicARNKey = attribute.Key(\"aws.sns.topic.arn\")\n\n\t// AWSSQSQueueURLKey is the attribute Key conforming to the \"aws.sqs.queue.url\"\n\t// semantic conventions. It represents the URL of the AWS SQS Queue. It's a\n\t// unique identifier for a queue in Amazon Simple Queue Service (SQS) and is\n\t// used to access the queue and perform actions on it.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue\"\n\tAWSSQSQueueURLKey = attribute.Key(\"aws.sqs.queue.url\")\n\n\t// AWSStepFunctionsActivityARNKey is the attribute Key conforming to the\n\t// \"aws.step_functions.activity.arn\" semantic conventions. It represents the ARN\n\t// of the AWS Step Functions Activity.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"arn:aws:states:us-east-1:123456789012:activity:get-greeting\"\n\tAWSStepFunctionsActivityARNKey = attribute.Key(\"aws.step_functions.activity.arn\")\n\n\t// AWSStepFunctionsStateMachineARNKey is the attribute Key conforming to the\n\t// \"aws.step_functions.state_machine.arn\" semantic conventions. It represents\n\t// the ARN of the AWS Step Functions State Machine.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"arn:aws:states:us-east-1:123456789012:stateMachine:myStateMachine:1\"\n\tAWSStepFunctionsStateMachineARNKey = attribute.Key(\"aws.step_functions.state_machine.arn\")\n)\n\n// AWSBedrockGuardrailID returns an attribute KeyValue conforming to the\n// \"aws.bedrock.guardrail.id\" semantic conventions. It represents the unique\n// identifier of the AWS Bedrock Guardrail. A [guardrail] helps safeguard and\n// prevent unwanted behavior from model responses or user messages.\n//\n// [guardrail]: https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html\nfunc AWSBedrockGuardrailID(val string) attribute.KeyValue {\n\treturn AWSBedrockGuardrailIDKey.String(val)\n}\n\n// AWSBedrockKnowledgeBaseID returns an attribute KeyValue conforming to the\n// \"aws.bedrock.knowledge_base.id\" semantic conventions. It represents the unique\n// identifier of the AWS Bedrock Knowledge base. A [knowledge base] is a bank of\n// information that can be queried by models to generate more relevant responses\n// and augment prompts.\n//\n// [knowledge base]: https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base.html\nfunc AWSBedrockKnowledgeBaseID(val string) attribute.KeyValue {\n\treturn AWSBedrockKnowledgeBaseIDKey.String(val)\n}\n\n// AWSDynamoDBAttributeDefinitions returns an attribute KeyValue conforming to\n// the \"aws.dynamodb.attribute_definitions\" semantic conventions. It represents\n// the JSON-serialized value of each item in the `AttributeDefinitions` request\n// field.\nfunc AWSDynamoDBAttributeDefinitions(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBAttributeDefinitionsKey.StringSlice(val)\n}\n\n// AWSDynamoDBAttributesToGet returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.attributes_to_get\" semantic conventions. It represents the value\n// of the `AttributesToGet` request parameter.\nfunc AWSDynamoDBAttributesToGet(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBAttributesToGetKey.StringSlice(val)\n}\n\n// AWSDynamoDBConsistentRead returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.consistent_read\" semantic conventions. It represents the value\n// of the `ConsistentRead` request parameter.\nfunc AWSDynamoDBConsistentRead(val bool) attribute.KeyValue {\n\treturn AWSDynamoDBConsistentReadKey.Bool(val)\n}\n\n// AWSDynamoDBConsumedCapacity returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.consumed_capacity\" semantic conventions. It represents the\n// JSON-serialized value of each item in the `ConsumedCapacity` response field.\nfunc AWSDynamoDBConsumedCapacity(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBConsumedCapacityKey.StringSlice(val)\n}\n\n// AWSDynamoDBCount returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.count\" semantic conventions. It represents the value of the\n// `Count` response parameter.\nfunc AWSDynamoDBCount(val int) attribute.KeyValue {\n\treturn AWSDynamoDBCountKey.Int(val)\n}\n\n// AWSDynamoDBExclusiveStartTable returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.exclusive_start_table\" semantic conventions. It represents the\n// value of the `ExclusiveStartTableName` request parameter.\nfunc AWSDynamoDBExclusiveStartTable(val string) attribute.KeyValue {\n\treturn AWSDynamoDBExclusiveStartTableKey.String(val)\n}\n\n// AWSDynamoDBGlobalSecondaryIndexUpdates returns an attribute KeyValue\n// conforming to the \"aws.dynamodb.global_secondary_index_updates\" semantic\n// conventions. It represents the JSON-serialized value of each item in the\n// `GlobalSecondaryIndexUpdates` request field.\nfunc AWSDynamoDBGlobalSecondaryIndexUpdates(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBGlobalSecondaryIndexUpdatesKey.StringSlice(val)\n}\n\n// AWSDynamoDBGlobalSecondaryIndexes returns an attribute KeyValue conforming to\n// the \"aws.dynamodb.global_secondary_indexes\" semantic conventions. It\n// represents the JSON-serialized value of each item of the\n// `GlobalSecondaryIndexes` request field.\nfunc AWSDynamoDBGlobalSecondaryIndexes(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBGlobalSecondaryIndexesKey.StringSlice(val)\n}\n\n// AWSDynamoDBIndexName returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.index_name\" semantic conventions. It represents the value of the\n// `IndexName` request parameter.\nfunc AWSDynamoDBIndexName(val string) attribute.KeyValue {\n\treturn AWSDynamoDBIndexNameKey.String(val)\n}\n\n// AWSDynamoDBItemCollectionMetrics returns an attribute KeyValue conforming to\n// the \"aws.dynamodb.item_collection_metrics\" semantic conventions. It represents\n// the JSON-serialized value of the `ItemCollectionMetrics` response field.\nfunc AWSDynamoDBItemCollectionMetrics(val string) attribute.KeyValue {\n\treturn AWSDynamoDBItemCollectionMetricsKey.String(val)\n}\n\n// AWSDynamoDBLimit returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.limit\" semantic conventions. It represents the value of the\n// `Limit` request parameter.\nfunc AWSDynamoDBLimit(val int) attribute.KeyValue {\n\treturn AWSDynamoDBLimitKey.Int(val)\n}\n\n// AWSDynamoDBLocalSecondaryIndexes returns an attribute KeyValue conforming to\n// the \"aws.dynamodb.local_secondary_indexes\" semantic conventions. It represents\n// the JSON-serialized value of each item of the `LocalSecondaryIndexes` request\n// field.\nfunc AWSDynamoDBLocalSecondaryIndexes(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBLocalSecondaryIndexesKey.StringSlice(val)\n}\n\n// AWSDynamoDBProjection returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.projection\" semantic conventions. It represents the value of the\n// `ProjectionExpression` request parameter.\nfunc AWSDynamoDBProjection(val string) attribute.KeyValue {\n\treturn AWSDynamoDBProjectionKey.String(val)\n}\n\n// AWSDynamoDBProvisionedReadCapacity returns an attribute KeyValue conforming to\n// the \"aws.dynamodb.provisioned_read_capacity\" semantic conventions. It\n// represents the value of the `ProvisionedThroughput.ReadCapacityUnits` request\n// parameter.\nfunc AWSDynamoDBProvisionedReadCapacity(val float64) attribute.KeyValue {\n\treturn AWSDynamoDBProvisionedReadCapacityKey.Float64(val)\n}\n\n// AWSDynamoDBProvisionedWriteCapacity returns an attribute KeyValue conforming\n// to the \"aws.dynamodb.provisioned_write_capacity\" semantic conventions. It\n// represents the value of the `ProvisionedThroughput.WriteCapacityUnits` request\n// parameter.\nfunc AWSDynamoDBProvisionedWriteCapacity(val float64) attribute.KeyValue {\n\treturn AWSDynamoDBProvisionedWriteCapacityKey.Float64(val)\n}\n\n// AWSDynamoDBScanForward returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.scan_forward\" semantic conventions. It represents the value of\n// the `ScanIndexForward` request parameter.\nfunc AWSDynamoDBScanForward(val bool) attribute.KeyValue {\n\treturn AWSDynamoDBScanForwardKey.Bool(val)\n}\n\n// AWSDynamoDBScannedCount returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.scanned_count\" semantic conventions. It represents the value of\n// the `ScannedCount` response parameter.\nfunc AWSDynamoDBScannedCount(val int) attribute.KeyValue {\n\treturn AWSDynamoDBScannedCountKey.Int(val)\n}\n\n// AWSDynamoDBSegment returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.segment\" semantic conventions. It represents the value of the\n// `Segment` request parameter.\nfunc AWSDynamoDBSegment(val int) attribute.KeyValue {\n\treturn AWSDynamoDBSegmentKey.Int(val)\n}\n\n// AWSDynamoDBSelect returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.select\" semantic conventions. It represents the value of the\n// `Select` request parameter.\nfunc AWSDynamoDBSelect(val string) attribute.KeyValue {\n\treturn AWSDynamoDBSelectKey.String(val)\n}\n\n// AWSDynamoDBTableCount returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.table_count\" semantic conventions. It represents the number of\n// items in the `TableNames` response parameter.\nfunc AWSDynamoDBTableCount(val int) attribute.KeyValue {\n\treturn AWSDynamoDBTableCountKey.Int(val)\n}\n\n// AWSDynamoDBTableNames returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.table_names\" semantic conventions. It represents the keys in the\n// `RequestItems` object field.\nfunc AWSDynamoDBTableNames(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBTableNamesKey.StringSlice(val)\n}\n\n// AWSDynamoDBTotalSegments returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.total_segments\" semantic conventions. It represents the value of\n// the `TotalSegments` request parameter.\nfunc AWSDynamoDBTotalSegments(val int) attribute.KeyValue {\n\treturn AWSDynamoDBTotalSegmentsKey.Int(val)\n}\n\n// AWSECSClusterARN returns an attribute KeyValue conforming to the\n// \"aws.ecs.cluster.arn\" semantic conventions. It represents the ARN of an\n// [ECS cluster].\n//\n// [ECS cluster]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html\nfunc AWSECSClusterARN(val string) attribute.KeyValue {\n\treturn AWSECSClusterARNKey.String(val)\n}\n\n// AWSECSContainerARN returns an attribute KeyValue conforming to the\n// \"aws.ecs.container.arn\" semantic conventions. It represents the Amazon\n// Resource Name (ARN) of an [ECS container instance].\n//\n// [ECS container instance]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html\nfunc AWSECSContainerARN(val string) attribute.KeyValue {\n\treturn AWSECSContainerARNKey.String(val)\n}\n\n// AWSECSTaskARN returns an attribute KeyValue conforming to the\n// \"aws.ecs.task.arn\" semantic conventions. It represents the ARN of a running\n// [ECS task].\n//\n// [ECS task]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids\nfunc AWSECSTaskARN(val string) attribute.KeyValue {\n\treturn AWSECSTaskARNKey.String(val)\n}\n\n// AWSECSTaskFamily returns an attribute KeyValue conforming to the\n// \"aws.ecs.task.family\" semantic conventions. It represents the family name of\n// the [ECS task definition] used to create the ECS task.\n//\n// [ECS task definition]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html\nfunc AWSECSTaskFamily(val string) attribute.KeyValue {\n\treturn AWSECSTaskFamilyKey.String(val)\n}\n\n// AWSECSTaskID returns an attribute KeyValue conforming to the \"aws.ecs.task.id\"\n// semantic conventions. It represents the ID of a running ECS task. The ID MUST\n// be extracted from `task.arn`.\nfunc AWSECSTaskID(val string) attribute.KeyValue {\n\treturn AWSECSTaskIDKey.String(val)\n}\n\n// AWSECSTaskRevision returns an attribute KeyValue conforming to the\n// \"aws.ecs.task.revision\" semantic conventions. It represents the revision for\n// the task definition used to create the ECS task.\nfunc AWSECSTaskRevision(val string) attribute.KeyValue {\n\treturn AWSECSTaskRevisionKey.String(val)\n}\n\n// AWSEKSClusterARN returns an attribute KeyValue conforming to the\n// \"aws.eks.cluster.arn\" semantic conventions. It represents the ARN of an EKS\n// cluster.\nfunc AWSEKSClusterARN(val string) attribute.KeyValue {\n\treturn AWSEKSClusterARNKey.String(val)\n}\n\n// AWSExtendedRequestID returns an attribute KeyValue conforming to the\n// \"aws.extended_request_id\" semantic conventions. It represents the AWS extended\n// request ID as returned in the response header `x-amz-id-2`.\nfunc AWSExtendedRequestID(val string) attribute.KeyValue {\n\treturn AWSExtendedRequestIDKey.String(val)\n}\n\n// AWSKinesisStreamName returns an attribute KeyValue conforming to the\n// \"aws.kinesis.stream_name\" semantic conventions. It represents the name of the\n// AWS Kinesis [stream] the request refers to. Corresponds to the `--stream-name`\n//  parameter of the Kinesis [describe-stream] operation.\n//\n// [stream]: https://docs.aws.amazon.com/streams/latest/dev/introduction.html\n// [describe-stream]: https://docs.aws.amazon.com/cli/latest/reference/kinesis/describe-stream.html\nfunc AWSKinesisStreamName(val string) attribute.KeyValue {\n\treturn AWSKinesisStreamNameKey.String(val)\n}\n\n// AWSLambdaInvokedARN returns an attribute KeyValue conforming to the\n// \"aws.lambda.invoked_arn\" semantic conventions. It represents the full invoked\n// ARN as provided on the `Context` passed to the function (\n// `Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next`\n//  applicable).\nfunc AWSLambdaInvokedARN(val string) attribute.KeyValue {\n\treturn AWSLambdaInvokedARNKey.String(val)\n}\n\n// AWSLambdaResourceMappingID returns an attribute KeyValue conforming to the\n// \"aws.lambda.resource_mapping.id\" semantic conventions. It represents the UUID\n// of the [AWS Lambda EvenSource Mapping]. An event source is mapped to a lambda\n// function. It's contents are read by Lambda and used to trigger a function.\n// This isn't available in the lambda execution context or the lambda runtime\n// environtment. This is going to be populated by the AWS SDK for each language\n// when that UUID is present. Some of these operations are\n// Create/Delete/Get/List/Update EventSourceMapping.\n//\n// [AWS Lambda EvenSource Mapping]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html\nfunc AWSLambdaResourceMappingID(val string) attribute.KeyValue {\n\treturn AWSLambdaResourceMappingIDKey.String(val)\n}\n\n// AWSLogGroupARNs returns an attribute KeyValue conforming to the\n// \"aws.log.group.arns\" semantic conventions. It represents the Amazon Resource\n// Name(s) (ARN) of the AWS log group(s).\nfunc AWSLogGroupARNs(val ...string) attribute.KeyValue {\n\treturn AWSLogGroupARNsKey.StringSlice(val)\n}\n\n// AWSLogGroupNames returns an attribute KeyValue conforming to the\n// \"aws.log.group.names\" semantic conventions. It represents the name(s) of the\n// AWS log group(s) an application is writing to.\nfunc AWSLogGroupNames(val ...string) attribute.KeyValue {\n\treturn AWSLogGroupNamesKey.StringSlice(val)\n}\n\n// AWSLogStreamARNs returns an attribute KeyValue conforming to the\n// \"aws.log.stream.arns\" semantic conventions. It represents the ARN(s) of the\n// AWS log stream(s).\nfunc AWSLogStreamARNs(val ...string) attribute.KeyValue {\n\treturn AWSLogStreamARNsKey.StringSlice(val)\n}\n\n// AWSLogStreamNames returns an attribute KeyValue conforming to the\n// \"aws.log.stream.names\" semantic conventions. It represents the name(s) of the\n// AWS log stream(s) an application is writing to.\nfunc AWSLogStreamNames(val ...string) attribute.KeyValue {\n\treturn AWSLogStreamNamesKey.StringSlice(val)\n}\n\n// AWSRequestID returns an attribute KeyValue conforming to the \"aws.request_id\"\n// semantic conventions. It represents the AWS request ID as returned in the\n// response headers `x-amzn-requestid`, `x-amzn-request-id` or `x-amz-request-id`\n// .\nfunc AWSRequestID(val string) attribute.KeyValue {\n\treturn AWSRequestIDKey.String(val)\n}\n\n// AWSS3Bucket returns an attribute KeyValue conforming to the \"aws.s3.bucket\"\n// semantic conventions. It represents the S3 bucket name the request refers to.\n// Corresponds to the `--bucket` parameter of the [S3 API] operations.\n//\n// [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html\nfunc AWSS3Bucket(val string) attribute.KeyValue {\n\treturn AWSS3BucketKey.String(val)\n}\n\n// AWSS3CopySource returns an attribute KeyValue conforming to the\n// \"aws.s3.copy_source\" semantic conventions. It represents the source object (in\n// the form `bucket`/`key`) for the copy operation.\nfunc AWSS3CopySource(val string) attribute.KeyValue {\n\treturn AWSS3CopySourceKey.String(val)\n}\n\n// AWSS3Delete returns an attribute KeyValue conforming to the \"aws.s3.delete\"\n// semantic conventions. It represents the delete request container that\n// specifies the objects to be deleted.\nfunc AWSS3Delete(val string) attribute.KeyValue {\n\treturn AWSS3DeleteKey.String(val)\n}\n\n// AWSS3Key returns an attribute KeyValue conforming to the \"aws.s3.key\" semantic\n// conventions. It represents the S3 object key the request refers to.\n// Corresponds to the `--key` parameter of the [S3 API] operations.\n//\n// [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html\nfunc AWSS3Key(val string) attribute.KeyValue {\n\treturn AWSS3KeyKey.String(val)\n}\n\n// AWSS3PartNumber returns an attribute KeyValue conforming to the\n// \"aws.s3.part_number\" semantic conventions. It represents the part number of\n// the part being uploaded in a multipart-upload operation. This is a positive\n// integer between 1 and 10,000.\nfunc AWSS3PartNumber(val int) attribute.KeyValue {\n\treturn AWSS3PartNumberKey.Int(val)\n}\n\n// AWSS3UploadID returns an attribute KeyValue conforming to the\n// \"aws.s3.upload_id\" semantic conventions. It represents the upload ID that\n// identifies the multipart upload.\nfunc AWSS3UploadID(val string) attribute.KeyValue {\n\treturn AWSS3UploadIDKey.String(val)\n}\n\n// AWSSecretsmanagerSecretARN returns an attribute KeyValue conforming to the\n// \"aws.secretsmanager.secret.arn\" semantic conventions. It represents the ARN of\n// the Secret stored in the Secrets Mangger.\nfunc AWSSecretsmanagerSecretARN(val string) attribute.KeyValue {\n\treturn AWSSecretsmanagerSecretARNKey.String(val)\n}\n\n// AWSSNSTopicARN returns an attribute KeyValue conforming to the\n// \"aws.sns.topic.arn\" semantic conventions. It represents the ARN of the AWS SNS\n// Topic. An Amazon SNS [topic] is a logical access point that acts as a\n// communication channel.\n//\n// [topic]: https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html\nfunc AWSSNSTopicARN(val string) attribute.KeyValue {\n\treturn AWSSNSTopicARNKey.String(val)\n}\n\n// AWSSQSQueueURL returns an attribute KeyValue conforming to the\n// \"aws.sqs.queue.url\" semantic conventions. It represents the URL of the AWS SQS\n// Queue. It's a unique identifier for a queue in Amazon Simple Queue Service\n// (SQS) and is used to access the queue and perform actions on it.\nfunc AWSSQSQueueURL(val string) attribute.KeyValue {\n\treturn AWSSQSQueueURLKey.String(val)\n}\n\n// AWSStepFunctionsActivityARN returns an attribute KeyValue conforming to the\n// \"aws.step_functions.activity.arn\" semantic conventions. It represents the ARN\n// of the AWS Step Functions Activity.\nfunc AWSStepFunctionsActivityARN(val string) attribute.KeyValue {\n\treturn AWSStepFunctionsActivityARNKey.String(val)\n}\n\n// AWSStepFunctionsStateMachineARN returns an attribute KeyValue conforming to\n// the \"aws.step_functions.state_machine.arn\" semantic conventions. It represents\n// the ARN of the AWS Step Functions State Machine.\nfunc AWSStepFunctionsStateMachineARN(val string) attribute.KeyValue {\n\treturn AWSStepFunctionsStateMachineARNKey.String(val)\n}\n\n// Enum values for aws.ecs.launchtype\nvar (\n\t// Amazon EC2\n\t// Stability: development\n\tAWSECSLaunchtypeEC2 = AWSECSLaunchtypeKey.String(\"ec2\")\n\t// Amazon Fargate\n\t// Stability: development\n\tAWSECSLaunchtypeFargate = AWSECSLaunchtypeKey.String(\"fargate\")\n)\n\n// Namespace: azure\nconst (\n\t// AzureClientIDKey is the attribute Key conforming to the \"azure.client.id\"\n\t// semantic conventions. It represents the unique identifier of the client\n\t// instance.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"3ba4827d-4422-483f-b59f-85b74211c11d\", \"storage-client-1\"\n\tAzureClientIDKey = attribute.Key(\"azure.client.id\")\n\n\t// AzureCosmosDBConnectionModeKey is the attribute Key conforming to the\n\t// \"azure.cosmosdb.connection.mode\" semantic conventions. It represents the\n\t// cosmos client connection mode.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tAzureCosmosDBConnectionModeKey = attribute.Key(\"azure.cosmosdb.connection.mode\")\n\n\t// AzureCosmosDBConsistencyLevelKey is the attribute Key conforming to the\n\t// \"azure.cosmosdb.consistency.level\" semantic conventions. It represents the\n\t// account or request [consistency level].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Eventual\", \"ConsistentPrefix\", \"BoundedStaleness\", \"Strong\",\n\t// \"Session\"\n\t//\n\t// [consistency level]: https://learn.microsoft.com/azure/cosmos-db/consistency-levels\n\tAzureCosmosDBConsistencyLevelKey = attribute.Key(\"azure.cosmosdb.consistency.level\")\n\n\t// AzureCosmosDBOperationContactedRegionsKey is the attribute Key conforming to\n\t// the \"azure.cosmosdb.operation.contacted_regions\" semantic conventions. It\n\t// represents the list of regions contacted during operation in the order that\n\t// they were contacted. If there is more than one region listed, it indicates\n\t// that the operation was performed on multiple regions i.e. cross-regional\n\t// call.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"North Central US\", \"Australia East\", \"Australia Southeast\"\n\t// Note: Region name matches the format of `displayName` in [Azure Location API]\n\t//\n\t// [Azure Location API]: https://learn.microsoft.com/rest/api/subscription/subscriptions/list-locations?view=rest-subscription-2021-10-01&tabs=HTTP#location\n\tAzureCosmosDBOperationContactedRegionsKey = attribute.Key(\"azure.cosmosdb.operation.contacted_regions\")\n\n\t// AzureCosmosDBOperationRequestChargeKey is the attribute Key conforming to the\n\t// \"azure.cosmosdb.operation.request_charge\" semantic conventions. It represents\n\t// the number of request units consumed by the operation.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 46.18, 1.0\n\tAzureCosmosDBOperationRequestChargeKey = attribute.Key(\"azure.cosmosdb.operation.request_charge\")\n\n\t// AzureCosmosDBRequestBodySizeKey is the attribute Key conforming to the\n\t// \"azure.cosmosdb.request.body.size\" semantic conventions. It represents the\n\t// request payload size in bytes.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tAzureCosmosDBRequestBodySizeKey = attribute.Key(\"azure.cosmosdb.request.body.size\")\n\n\t// AzureCosmosDBResponseSubStatusCodeKey is the attribute Key conforming to the\n\t// \"azure.cosmosdb.response.sub_status_code\" semantic conventions. It represents\n\t// the cosmos DB sub status code.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1000, 1002\n\tAzureCosmosDBResponseSubStatusCodeKey = attribute.Key(\"azure.cosmosdb.response.sub_status_code\")\n\n\t// AzureResourceProviderNamespaceKey is the attribute Key conforming to the\n\t// \"azure.resource_provider.namespace\" semantic conventions. It represents the\n\t// [Azure Resource Provider Namespace] as recognized by the client.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Microsoft.Storage\", \"Microsoft.KeyVault\", \"Microsoft.ServiceBus\"\n\t//\n\t// [Azure Resource Provider Namespace]: https://learn.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers\n\tAzureResourceProviderNamespaceKey = attribute.Key(\"azure.resource_provider.namespace\")\n\n\t// AzureServiceRequestIDKey is the attribute Key conforming to the\n\t// \"azure.service.request.id\" semantic conventions. It represents the unique\n\t// identifier of the service request. It's generated by the Azure service and\n\t// returned with the response.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"00000000-0000-0000-0000-000000000000\"\n\tAzureServiceRequestIDKey = attribute.Key(\"azure.service.request.id\")\n)\n\n// AzureClientID returns an attribute KeyValue conforming to the\n// \"azure.client.id\" semantic conventions. It represents the unique identifier of\n// the client instance.\nfunc AzureClientID(val string) attribute.KeyValue {\n\treturn AzureClientIDKey.String(val)\n}\n\n// AzureCosmosDBOperationContactedRegions returns an attribute KeyValue\n// conforming to the \"azure.cosmosdb.operation.contacted_regions\" semantic\n// conventions. It represents the list of regions contacted during operation in\n// the order that they were contacted. If there is more than one region listed,\n// it indicates that the operation was performed on multiple regions i.e.\n// cross-regional call.\nfunc AzureCosmosDBOperationContactedRegions(val ...string) attribute.KeyValue {\n\treturn AzureCosmosDBOperationContactedRegionsKey.StringSlice(val)\n}\n\n// AzureCosmosDBOperationRequestCharge returns an attribute KeyValue conforming\n// to the \"azure.cosmosdb.operation.request_charge\" semantic conventions. It\n// represents the number of request units consumed by the operation.\nfunc AzureCosmosDBOperationRequestCharge(val float64) attribute.KeyValue {\n\treturn AzureCosmosDBOperationRequestChargeKey.Float64(val)\n}\n\n// AzureCosmosDBRequestBodySize returns an attribute KeyValue conforming to the\n// \"azure.cosmosdb.request.body.size\" semantic conventions. It represents the\n// request payload size in bytes.\nfunc AzureCosmosDBRequestBodySize(val int) attribute.KeyValue {\n\treturn AzureCosmosDBRequestBodySizeKey.Int(val)\n}\n\n// AzureCosmosDBResponseSubStatusCode returns an attribute KeyValue conforming to\n// the \"azure.cosmosdb.response.sub_status_code\" semantic conventions. It\n// represents the cosmos DB sub status code.\nfunc AzureCosmosDBResponseSubStatusCode(val int) attribute.KeyValue {\n\treturn AzureCosmosDBResponseSubStatusCodeKey.Int(val)\n}\n\n// AzureResourceProviderNamespace returns an attribute KeyValue conforming to the\n// \"azure.resource_provider.namespace\" semantic conventions. It represents the\n// [Azure Resource Provider Namespace] as recognized by the client.\n//\n// [Azure Resource Provider Namespace]: https://learn.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers\nfunc AzureResourceProviderNamespace(val string) attribute.KeyValue {\n\treturn AzureResourceProviderNamespaceKey.String(val)\n}\n\n// AzureServiceRequestID returns an attribute KeyValue conforming to the\n// \"azure.service.request.id\" semantic conventions. It represents the unique\n// identifier of the service request. It's generated by the Azure service and\n// returned with the response.\nfunc AzureServiceRequestID(val string) attribute.KeyValue {\n\treturn AzureServiceRequestIDKey.String(val)\n}\n\n// Enum values for azure.cosmosdb.connection.mode\nvar (\n\t// Gateway (HTTP) connection.\n\t// Stability: development\n\tAzureCosmosDBConnectionModeGateway = AzureCosmosDBConnectionModeKey.String(\"gateway\")\n\t// Direct connection.\n\t// Stability: development\n\tAzureCosmosDBConnectionModeDirect = AzureCosmosDBConnectionModeKey.String(\"direct\")\n)\n\n// Enum values for azure.cosmosdb.consistency.level\nvar (\n\t// Strong\n\t// Stability: development\n\tAzureCosmosDBConsistencyLevelStrong = AzureCosmosDBConsistencyLevelKey.String(\"Strong\")\n\t// Bounded Staleness\n\t// Stability: development\n\tAzureCosmosDBConsistencyLevelBoundedStaleness = AzureCosmosDBConsistencyLevelKey.String(\"BoundedStaleness\")\n\t// Session\n\t// Stability: development\n\tAzureCosmosDBConsistencyLevelSession = AzureCosmosDBConsistencyLevelKey.String(\"Session\")\n\t// Eventual\n\t// Stability: development\n\tAzureCosmosDBConsistencyLevelEventual = AzureCosmosDBConsistencyLevelKey.String(\"Eventual\")\n\t// Consistent Prefix\n\t// Stability: development\n\tAzureCosmosDBConsistencyLevelConsistentPrefix = AzureCosmosDBConsistencyLevelKey.String(\"ConsistentPrefix\")\n)\n\n// Namespace: browser\nconst (\n\t// BrowserBrandsKey is the attribute Key conforming to the \"browser.brands\"\n\t// semantic conventions. It represents the array of brand name and version\n\t// separated by a space.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \" Not A;Brand 99\", \"Chromium 99\", \"Chrome 99\"\n\t// Note: This value is intended to be taken from the [UA client hints API] (\n\t// `navigator.userAgentData.brands`).\n\t//\n\t// [UA client hints API]: https://wicg.github.io/ua-client-hints/#interface\n\tBrowserBrandsKey = attribute.Key(\"browser.brands\")\n\n\t// BrowserLanguageKey is the attribute Key conforming to the \"browser.language\"\n\t// semantic conventions. It represents the preferred language of the user using\n\t// the browser.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"en\", \"en-US\", \"fr\", \"fr-FR\"\n\t// Note: This value is intended to be taken from the Navigator API\n\t// `navigator.language`.\n\tBrowserLanguageKey = attribute.Key(\"browser.language\")\n\n\t// BrowserMobileKey is the attribute Key conforming to the \"browser.mobile\"\n\t// semantic conventions. It represents a boolean that is true if the browser is\n\t// running on a mobile device.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: This value is intended to be taken from the [UA client hints API] (\n\t// `navigator.userAgentData.mobile`). If unavailable, this attribute SHOULD be\n\t// left unset.\n\t//\n\t// [UA client hints API]: https://wicg.github.io/ua-client-hints/#interface\n\tBrowserMobileKey = attribute.Key(\"browser.mobile\")\n\n\t// BrowserPlatformKey is the attribute Key conforming to the \"browser.platform\"\n\t// semantic conventions. It represents the platform on which the browser is\n\t// running.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Windows\", \"macOS\", \"Android\"\n\t// Note: This value is intended to be taken from the [UA client hints API] (\n\t// `navigator.userAgentData.platform`). If unavailable, the legacy\n\t// `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD\n\t// be left unset in order for the values to be consistent.\n\t// The list of possible values is defined in the\n\t// [W3C User-Agent Client Hints specification]. Note that some (but not all) of\n\t// these values can overlap with values in the\n\t// [`os.type` and `os.name` attributes]. However, for consistency, the values in\n\t// the `browser.platform` attribute should capture the exact value that the user\n\t// agent provides.\n\t//\n\t// [UA client hints API]: https://wicg.github.io/ua-client-hints/#interface\n\t// [W3C User-Agent Client Hints specification]: https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform\n\t// [`os.type` and `os.name` attributes]: ./os.md\n\tBrowserPlatformKey = attribute.Key(\"browser.platform\")\n)\n\n// BrowserBrands returns an attribute KeyValue conforming to the \"browser.brands\"\n// semantic conventions. It represents the array of brand name and version\n// separated by a space.\nfunc BrowserBrands(val ...string) attribute.KeyValue {\n\treturn BrowserBrandsKey.StringSlice(val)\n}\n\n// BrowserLanguage returns an attribute KeyValue conforming to the\n// \"browser.language\" semantic conventions. It represents the preferred language\n// of the user using the browser.\nfunc BrowserLanguage(val string) attribute.KeyValue {\n\treturn BrowserLanguageKey.String(val)\n}\n\n// BrowserMobile returns an attribute KeyValue conforming to the \"browser.mobile\"\n// semantic conventions. It represents a boolean that is true if the browser is\n// running on a mobile device.\nfunc BrowserMobile(val bool) attribute.KeyValue {\n\treturn BrowserMobileKey.Bool(val)\n}\n\n// BrowserPlatform returns an attribute KeyValue conforming to the\n// \"browser.platform\" semantic conventions. It represents the platform on which\n// the browser is running.\nfunc BrowserPlatform(val string) attribute.KeyValue {\n\treturn BrowserPlatformKey.String(val)\n}\n\n// Namespace: cassandra\nconst (\n\t// CassandraConsistencyLevelKey is the attribute Key conforming to the\n\t// \"cassandra.consistency.level\" semantic conventions. It represents the\n\t// consistency level of the query. Based on consistency values from [CQL].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t//\n\t// [CQL]: https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html\n\tCassandraConsistencyLevelKey = attribute.Key(\"cassandra.consistency.level\")\n\n\t// CassandraCoordinatorDCKey is the attribute Key conforming to the\n\t// \"cassandra.coordinator.dc\" semantic conventions. It represents the data\n\t// center of the coordinating node for a query.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: us-west-2\n\tCassandraCoordinatorDCKey = attribute.Key(\"cassandra.coordinator.dc\")\n\n\t// CassandraCoordinatorIDKey is the attribute Key conforming to the\n\t// \"cassandra.coordinator.id\" semantic conventions. It represents the ID of the\n\t// coordinating node for a query.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: be13faa2-8574-4d71-926d-27f16cf8a7af\n\tCassandraCoordinatorIDKey = attribute.Key(\"cassandra.coordinator.id\")\n\n\t// CassandraPageSizeKey is the attribute Key conforming to the\n\t// \"cassandra.page.size\" semantic conventions. It represents the fetch size used\n\t// for paging, i.e. how many rows will be returned at once.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 5000\n\tCassandraPageSizeKey = attribute.Key(\"cassandra.page.size\")\n\n\t// CassandraQueryIdempotentKey is the attribute Key conforming to the\n\t// \"cassandra.query.idempotent\" semantic conventions. It represents the whether\n\t// or not the query is idempotent.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tCassandraQueryIdempotentKey = attribute.Key(\"cassandra.query.idempotent\")\n\n\t// CassandraSpeculativeExecutionCountKey is the attribute Key conforming to the\n\t// \"cassandra.speculative_execution.count\" semantic conventions. It represents\n\t// the number of times a query was speculatively executed. Not set or `0` if the\n\t// query was not executed speculatively.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0, 2\n\tCassandraSpeculativeExecutionCountKey = attribute.Key(\"cassandra.speculative_execution.count\")\n)\n\n// CassandraCoordinatorDC returns an attribute KeyValue conforming to the\n// \"cassandra.coordinator.dc\" semantic conventions. It represents the data center\n// of the coordinating node for a query.\nfunc CassandraCoordinatorDC(val string) attribute.KeyValue {\n\treturn CassandraCoordinatorDCKey.String(val)\n}\n\n// CassandraCoordinatorID returns an attribute KeyValue conforming to the\n// \"cassandra.coordinator.id\" semantic conventions. It represents the ID of the\n// coordinating node for a query.\nfunc CassandraCoordinatorID(val string) attribute.KeyValue {\n\treturn CassandraCoordinatorIDKey.String(val)\n}\n\n// CassandraPageSize returns an attribute KeyValue conforming to the\n// \"cassandra.page.size\" semantic conventions. It represents the fetch size used\n// for paging, i.e. how many rows will be returned at once.\nfunc CassandraPageSize(val int) attribute.KeyValue {\n\treturn CassandraPageSizeKey.Int(val)\n}\n\n// CassandraQueryIdempotent returns an attribute KeyValue conforming to the\n// \"cassandra.query.idempotent\" semantic conventions. It represents the whether\n// or not the query is idempotent.\nfunc CassandraQueryIdempotent(val bool) attribute.KeyValue {\n\treturn CassandraQueryIdempotentKey.Bool(val)\n}\n\n// CassandraSpeculativeExecutionCount returns an attribute KeyValue conforming to\n// the \"cassandra.speculative_execution.count\" semantic conventions. It\n// represents the number of times a query was speculatively executed. Not set or\n// `0` if the query was not executed speculatively.\nfunc CassandraSpeculativeExecutionCount(val int) attribute.KeyValue {\n\treturn CassandraSpeculativeExecutionCountKey.Int(val)\n}\n\n// Enum values for cassandra.consistency.level\nvar (\n\t// All\n\t// Stability: development\n\tCassandraConsistencyLevelAll = CassandraConsistencyLevelKey.String(\"all\")\n\t// Each Quorum\n\t// Stability: development\n\tCassandraConsistencyLevelEachQuorum = CassandraConsistencyLevelKey.String(\"each_quorum\")\n\t// Quorum\n\t// Stability: development\n\tCassandraConsistencyLevelQuorum = CassandraConsistencyLevelKey.String(\"quorum\")\n\t// Local Quorum\n\t// Stability: development\n\tCassandraConsistencyLevelLocalQuorum = CassandraConsistencyLevelKey.String(\"local_quorum\")\n\t// One\n\t// Stability: development\n\tCassandraConsistencyLevelOne = CassandraConsistencyLevelKey.String(\"one\")\n\t// Two\n\t// Stability: development\n\tCassandraConsistencyLevelTwo = CassandraConsistencyLevelKey.String(\"two\")\n\t// Three\n\t// Stability: development\n\tCassandraConsistencyLevelThree = CassandraConsistencyLevelKey.String(\"three\")\n\t// Local One\n\t// Stability: development\n\tCassandraConsistencyLevelLocalOne = CassandraConsistencyLevelKey.String(\"local_one\")\n\t// Any\n\t// Stability: development\n\tCassandraConsistencyLevelAny = CassandraConsistencyLevelKey.String(\"any\")\n\t// Serial\n\t// Stability: development\n\tCassandraConsistencyLevelSerial = CassandraConsistencyLevelKey.String(\"serial\")\n\t// Local Serial\n\t// Stability: development\n\tCassandraConsistencyLevelLocalSerial = CassandraConsistencyLevelKey.String(\"local_serial\")\n)\n\n// Namespace: cicd\nconst (\n\t// CICDPipelineActionNameKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.action.name\" semantic conventions. It represents the kind of\n\t// action a pipeline run is performing.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"BUILD\", \"RUN\", \"SYNC\"\n\tCICDPipelineActionNameKey = attribute.Key(\"cicd.pipeline.action.name\")\n\n\t// CICDPipelineNameKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.name\" semantic conventions. It represents the human readable\n\t// name of the pipeline within a CI/CD system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Build and Test\", \"Lint\", \"Deploy Go Project\",\n\t// \"deploy_to_environment\"\n\tCICDPipelineNameKey = attribute.Key(\"cicd.pipeline.name\")\n\n\t// CICDPipelineResultKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.result\" semantic conventions. It represents the result of a\n\t// pipeline run.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"success\", \"failure\", \"timeout\", \"skipped\"\n\tCICDPipelineResultKey = attribute.Key(\"cicd.pipeline.result\")\n\n\t// CICDPipelineRunIDKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.run.id\" semantic conventions. It represents the unique\n\t// identifier of a pipeline run within a CI/CD system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"120912\"\n\tCICDPipelineRunIDKey = attribute.Key(\"cicd.pipeline.run.id\")\n\n\t// CICDPipelineRunStateKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.run.state\" semantic conventions. It represents the pipeline\n\t// run goes through these states during its lifecycle.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"pending\", \"executing\", \"finalizing\"\n\tCICDPipelineRunStateKey = attribute.Key(\"cicd.pipeline.run.state\")\n\n\t// CICDPipelineRunURLFullKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.run.url.full\" semantic conventions. It represents the [URL] of\n\t// the pipeline run, providing the complete address in order to locate and\n\t// identify the pipeline run.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"https://github.com/open-telemetry/semantic-conventions/actions/runs/9753949763?pr=1075\"\n\t//\n\t// [URL]: https://wikipedia.org/wiki/URL\n\tCICDPipelineRunURLFullKey = attribute.Key(\"cicd.pipeline.run.url.full\")\n\n\t// CICDPipelineTaskNameKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.task.name\" semantic conventions. It represents the human\n\t// readable name of a task within a pipeline. Task here most closely aligns with\n\t// a [computing process] in a pipeline. Other terms for tasks include commands,\n\t// steps, and procedures.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Run GoLang Linter\", \"Go Build\", \"go-test\", \"deploy_binary\"\n\t//\n\t// [computing process]: https://wikipedia.org/wiki/Pipeline_(computing)\n\tCICDPipelineTaskNameKey = attribute.Key(\"cicd.pipeline.task.name\")\n\n\t// CICDPipelineTaskRunIDKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.task.run.id\" semantic conventions. It represents the unique\n\t// identifier of a task run within a pipeline.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"12097\"\n\tCICDPipelineTaskRunIDKey = attribute.Key(\"cicd.pipeline.task.run.id\")\n\n\t// CICDPipelineTaskRunResultKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.task.run.result\" semantic conventions. It represents the\n\t// result of a task run.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"success\", \"failure\", \"timeout\", \"skipped\"\n\tCICDPipelineTaskRunResultKey = attribute.Key(\"cicd.pipeline.task.run.result\")\n\n\t// CICDPipelineTaskRunURLFullKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.task.run.url.full\" semantic conventions. It represents the\n\t// [URL] of the pipeline task run, providing the complete address in order to\n\t// locate and identify the pipeline task run.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"https://github.com/open-telemetry/semantic-conventions/actions/runs/9753949763/job/26920038674?pr=1075\"\n\t//\n\t// [URL]: https://wikipedia.org/wiki/URL\n\tCICDPipelineTaskRunURLFullKey = attribute.Key(\"cicd.pipeline.task.run.url.full\")\n\n\t// CICDPipelineTaskTypeKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.task.type\" semantic conventions. It represents the type of the\n\t// task within a pipeline.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"build\", \"test\", \"deploy\"\n\tCICDPipelineTaskTypeKey = attribute.Key(\"cicd.pipeline.task.type\")\n\n\t// CICDSystemComponentKey is the attribute Key conforming to the\n\t// \"cicd.system.component\" semantic conventions. It represents the name of a\n\t// component of the CICD system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"controller\", \"scheduler\", \"agent\"\n\tCICDSystemComponentKey = attribute.Key(\"cicd.system.component\")\n\n\t// CICDWorkerIDKey is the attribute Key conforming to the \"cicd.worker.id\"\n\t// semantic conventions. It represents the unique identifier of a worker within\n\t// a CICD system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"abc123\", \"10.0.1.2\", \"controller\"\n\tCICDWorkerIDKey = attribute.Key(\"cicd.worker.id\")\n\n\t// CICDWorkerNameKey is the attribute Key conforming to the \"cicd.worker.name\"\n\t// semantic conventions. It represents the name of a worker within a CICD\n\t// system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"agent-abc\", \"controller\", \"Ubuntu LTS\"\n\tCICDWorkerNameKey = attribute.Key(\"cicd.worker.name\")\n\n\t// CICDWorkerStateKey is the attribute Key conforming to the \"cicd.worker.state\"\n\t// semantic conventions. It represents the state of a CICD worker / agent.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"idle\", \"busy\", \"down\"\n\tCICDWorkerStateKey = attribute.Key(\"cicd.worker.state\")\n\n\t// CICDWorkerURLFullKey is the attribute Key conforming to the\n\t// \"cicd.worker.url.full\" semantic conventions. It represents the [URL] of the\n\t// worker, providing the complete address in order to locate and identify the\n\t// worker.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"https://cicd.example.org/worker/abc123\"\n\t//\n\t// [URL]: https://wikipedia.org/wiki/URL\n\tCICDWorkerURLFullKey = attribute.Key(\"cicd.worker.url.full\")\n)\n\n// CICDPipelineName returns an attribute KeyValue conforming to the\n// \"cicd.pipeline.name\" semantic conventions. It represents the human readable\n// name of the pipeline within a CI/CD system.\nfunc CICDPipelineName(val string) attribute.KeyValue {\n\treturn CICDPipelineNameKey.String(val)\n}\n\n// CICDPipelineRunID returns an attribute KeyValue conforming to the\n// \"cicd.pipeline.run.id\" semantic conventions. It represents the unique\n// identifier of a pipeline run within a CI/CD system.\nfunc CICDPipelineRunID(val string) attribute.KeyValue {\n\treturn CICDPipelineRunIDKey.String(val)\n}\n\n// CICDPipelineRunURLFull returns an attribute KeyValue conforming to the\n// \"cicd.pipeline.run.url.full\" semantic conventions. It represents the [URL] of\n// the pipeline run, providing the complete address in order to locate and\n// identify the pipeline run.\n//\n// [URL]: https://wikipedia.org/wiki/URL\nfunc CICDPipelineRunURLFull(val string) attribute.KeyValue {\n\treturn CICDPipelineRunURLFullKey.String(val)\n}\n\n// CICDPipelineTaskName returns an attribute KeyValue conforming to the\n// \"cicd.pipeline.task.name\" semantic conventions. It represents the human\n// readable name of a task within a pipeline. Task here most closely aligns with\n// a [computing process] in a pipeline. Other terms for tasks include commands,\n// steps, and procedures.\n//\n// [computing process]: https://wikipedia.org/wiki/Pipeline_(computing)\nfunc CICDPipelineTaskName(val string) attribute.KeyValue {\n\treturn CICDPipelineTaskNameKey.String(val)\n}\n\n// CICDPipelineTaskRunID returns an attribute KeyValue conforming to the\n// \"cicd.pipeline.task.run.id\" semantic conventions. It represents the unique\n// identifier of a task run within a pipeline.\nfunc CICDPipelineTaskRunID(val string) attribute.KeyValue {\n\treturn CICDPipelineTaskRunIDKey.String(val)\n}\n\n// CICDPipelineTaskRunURLFull returns an attribute KeyValue conforming to the\n// \"cicd.pipeline.task.run.url.full\" semantic conventions. It represents the\n// [URL] of the pipeline task run, providing the complete address in order to\n// locate and identify the pipeline task run.\n//\n// [URL]: https://wikipedia.org/wiki/URL\nfunc CICDPipelineTaskRunURLFull(val string) attribute.KeyValue {\n\treturn CICDPipelineTaskRunURLFullKey.String(val)\n}\n\n// CICDSystemComponent returns an attribute KeyValue conforming to the\n// \"cicd.system.component\" semantic conventions. It represents the name of a\n// component of the CICD system.\nfunc CICDSystemComponent(val string) attribute.KeyValue {\n\treturn CICDSystemComponentKey.String(val)\n}\n\n// CICDWorkerID returns an attribute KeyValue conforming to the \"cicd.worker.id\"\n// semantic conventions. It represents the unique identifier of a worker within a\n// CICD system.\nfunc CICDWorkerID(val string) attribute.KeyValue {\n\treturn CICDWorkerIDKey.String(val)\n}\n\n// CICDWorkerName returns an attribute KeyValue conforming to the\n// \"cicd.worker.name\" semantic conventions. It represents the name of a worker\n// within a CICD system.\nfunc CICDWorkerName(val string) attribute.KeyValue {\n\treturn CICDWorkerNameKey.String(val)\n}\n\n// CICDWorkerURLFull returns an attribute KeyValue conforming to the\n// \"cicd.worker.url.full\" semantic conventions. It represents the [URL] of the\n// worker, providing the complete address in order to locate and identify the\n// worker.\n//\n// [URL]: https://wikipedia.org/wiki/URL\nfunc CICDWorkerURLFull(val string) attribute.KeyValue {\n\treturn CICDWorkerURLFullKey.String(val)\n}\n\n// Enum values for cicd.pipeline.action.name\nvar (\n\t// The pipeline run is executing a build.\n\t// Stability: development\n\tCICDPipelineActionNameBuild = CICDPipelineActionNameKey.String(\"BUILD\")\n\t// The pipeline run is executing.\n\t// Stability: development\n\tCICDPipelineActionNameRun = CICDPipelineActionNameKey.String(\"RUN\")\n\t// The pipeline run is executing a sync.\n\t// Stability: development\n\tCICDPipelineActionNameSync = CICDPipelineActionNameKey.String(\"SYNC\")\n)\n\n// Enum values for cicd.pipeline.result\nvar (\n\t// The pipeline run finished successfully.\n\t// Stability: development\n\tCICDPipelineResultSuccess = CICDPipelineResultKey.String(\"success\")\n\t// The pipeline run did not finish successfully, eg. due to a compile error or a\n\t// failing test. Such failures are usually detected by non-zero exit codes of\n\t// the tools executed in the pipeline run.\n\t// Stability: development\n\tCICDPipelineResultFailure = CICDPipelineResultKey.String(\"failure\")\n\t// The pipeline run failed due to an error in the CICD system, eg. due to the\n\t// worker being killed.\n\t// Stability: development\n\tCICDPipelineResultError = CICDPipelineResultKey.String(\"error\")\n\t// A timeout caused the pipeline run to be interrupted.\n\t// Stability: development\n\tCICDPipelineResultTimeout = CICDPipelineResultKey.String(\"timeout\")\n\t// The pipeline run was cancelled, eg. by a user manually cancelling the\n\t// pipeline run.\n\t// Stability: development\n\tCICDPipelineResultCancellation = CICDPipelineResultKey.String(\"cancellation\")\n\t// The pipeline run was skipped, eg. due to a precondition not being met.\n\t// Stability: development\n\tCICDPipelineResultSkip = CICDPipelineResultKey.String(\"skip\")\n)\n\n// Enum values for cicd.pipeline.run.state\nvar (\n\t// The run pending state spans from the event triggering the pipeline run until\n\t// the execution of the run starts (eg. time spent in a queue, provisioning\n\t// agents, creating run resources).\n\t//\n\t// Stability: development\n\tCICDPipelineRunStatePending = CICDPipelineRunStateKey.String(\"pending\")\n\t// The executing state spans the execution of any run tasks (eg. build, test).\n\t// Stability: development\n\tCICDPipelineRunStateExecuting = CICDPipelineRunStateKey.String(\"executing\")\n\t// The finalizing state spans from when the run has finished executing (eg.\n\t// cleanup of run resources).\n\t// Stability: development\n\tCICDPipelineRunStateFinalizing = CICDPipelineRunStateKey.String(\"finalizing\")\n)\n\n// Enum values for cicd.pipeline.task.run.result\nvar (\n\t// The task run finished successfully.\n\t// Stability: development\n\tCICDPipelineTaskRunResultSuccess = CICDPipelineTaskRunResultKey.String(\"success\")\n\t// The task run did not finish successfully, eg. due to a compile error or a\n\t// failing test. Such failures are usually detected by non-zero exit codes of\n\t// the tools executed in the task run.\n\t// Stability: development\n\tCICDPipelineTaskRunResultFailure = CICDPipelineTaskRunResultKey.String(\"failure\")\n\t// The task run failed due to an error in the CICD system, eg. due to the worker\n\t// being killed.\n\t// Stability: development\n\tCICDPipelineTaskRunResultError = CICDPipelineTaskRunResultKey.String(\"error\")\n\t// A timeout caused the task run to be interrupted.\n\t// Stability: development\n\tCICDPipelineTaskRunResultTimeout = CICDPipelineTaskRunResultKey.String(\"timeout\")\n\t// The task run was cancelled, eg. by a user manually cancelling the task run.\n\t// Stability: development\n\tCICDPipelineTaskRunResultCancellation = CICDPipelineTaskRunResultKey.String(\"cancellation\")\n\t// The task run was skipped, eg. due to a precondition not being met.\n\t// Stability: development\n\tCICDPipelineTaskRunResultSkip = CICDPipelineTaskRunResultKey.String(\"skip\")\n)\n\n// Enum values for cicd.pipeline.task.type\nvar (\n\t// build\n\t// Stability: development\n\tCICDPipelineTaskTypeBuild = CICDPipelineTaskTypeKey.String(\"build\")\n\t// test\n\t// Stability: development\n\tCICDPipelineTaskTypeTest = CICDPipelineTaskTypeKey.String(\"test\")\n\t// deploy\n\t// Stability: development\n\tCICDPipelineTaskTypeDeploy = CICDPipelineTaskTypeKey.String(\"deploy\")\n)\n\n// Enum values for cicd.worker.state\nvar (\n\t// The worker is not performing work for the CICD system. It is available to the\n\t// CICD system to perform work on (online / idle).\n\t// Stability: development\n\tCICDWorkerStateAvailable = CICDWorkerStateKey.String(\"available\")\n\t// The worker is performing work for the CICD system.\n\t// Stability: development\n\tCICDWorkerStateBusy = CICDWorkerStateKey.String(\"busy\")\n\t// The worker is not available to the CICD system (disconnected / down).\n\t// Stability: development\n\tCICDWorkerStateOffline = CICDWorkerStateKey.String(\"offline\")\n)\n\n// Namespace: client\nconst (\n\t// ClientAddressKey is the attribute Key conforming to the \"client.address\"\n\t// semantic conventions. It represents the client address - domain name if\n\t// available without reverse DNS lookup; otherwise, IP address or Unix domain\n\t// socket name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"client.example.com\", \"10.1.2.80\", \"/tmp/my.sock\"\n\t// Note: When observed from the server side, and when communicating through an\n\t// intermediary, `client.address` SHOULD represent the client address behind any\n\t// intermediaries, for example proxies, if it's available.\n\tClientAddressKey = attribute.Key(\"client.address\")\n\n\t// ClientPortKey is the attribute Key conforming to the \"client.port\" semantic\n\t// conventions. It represents the client port number.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: 65123\n\t// Note: When observed from the server side, and when communicating through an\n\t// intermediary, `client.port` SHOULD represent the client port behind any\n\t// intermediaries, for example proxies, if it's available.\n\tClientPortKey = attribute.Key(\"client.port\")\n)\n\n// ClientAddress returns an attribute KeyValue conforming to the \"client.address\"\n// semantic conventions. It represents the client address - domain name if\n// available without reverse DNS lookup; otherwise, IP address or Unix domain\n// socket name.\nfunc ClientAddress(val string) attribute.KeyValue {\n\treturn ClientAddressKey.String(val)\n}\n\n// ClientPort returns an attribute KeyValue conforming to the \"client.port\"\n// semantic conventions. It represents the client port number.\nfunc ClientPort(val int) attribute.KeyValue {\n\treturn ClientPortKey.Int(val)\n}\n\n// Namespace: cloud\nconst (\n\t// CloudAccountIDKey is the attribute Key conforming to the \"cloud.account.id\"\n\t// semantic conventions. It represents the cloud account ID the resource is\n\t// assigned to.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"111111111111\", \"opentelemetry\"\n\tCloudAccountIDKey = attribute.Key(\"cloud.account.id\")\n\n\t// CloudAvailabilityZoneKey is the attribute Key conforming to the\n\t// \"cloud.availability_zone\" semantic conventions. It represents the cloud\n\t// regions often have multiple, isolated locations known as zones to increase\n\t// availability. Availability zone represents the zone where the resource is\n\t// running.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"us-east-1c\"\n\t// Note: Availability zones are called \"zones\" on Alibaba Cloud and Google\n\t// Cloud.\n\tCloudAvailabilityZoneKey = attribute.Key(\"cloud.availability_zone\")\n\n\t// CloudPlatformKey is the attribute Key conforming to the \"cloud.platform\"\n\t// semantic conventions. It represents the cloud platform in use.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: The prefix of the service SHOULD match the one specified in\n\t// `cloud.provider`.\n\tCloudPlatformKey = attribute.Key(\"cloud.platform\")\n\n\t// CloudProviderKey is the attribute Key conforming to the \"cloud.provider\"\n\t// semantic conventions. It represents the name of the cloud provider.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tCloudProviderKey = attribute.Key(\"cloud.provider\")\n\n\t// CloudRegionKey is the attribute Key conforming to the \"cloud.region\" semantic\n\t// conventions. It represents the geographical region within a cloud provider.\n\t// When associated with a resource, this attribute specifies the region where\n\t// the resource operates. When calling services or APIs deployed on a cloud,\n\t// this attribute identifies the region where the called destination is\n\t// deployed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"us-central1\", \"us-east-1\"\n\t// Note: Refer to your provider's docs to see the available regions, for example\n\t// [Alibaba Cloud regions], [AWS regions], [Azure regions],\n\t// [Google Cloud regions], or [Tencent Cloud regions].\n\t//\n\t// [Alibaba Cloud regions]: https://www.alibabacloud.com/help/doc-detail/40654.htm\n\t// [AWS regions]: https://aws.amazon.com/about-aws/global-infrastructure/regions_az/\n\t// [Azure regions]: https://azure.microsoft.com/global-infrastructure/geographies/\n\t// [Google Cloud regions]: https://cloud.google.com/about/locations\n\t// [Tencent Cloud regions]: https://www.tencentcloud.com/document/product/213/6091\n\tCloudRegionKey = attribute.Key(\"cloud.region\")\n\n\t// CloudResourceIDKey is the attribute Key conforming to the \"cloud.resource_id\"\n\t// semantic conventions. It represents the cloud provider-specific native\n\t// identifier of the monitored cloud resource (e.g. an [ARN] on AWS, a\n\t// [fully qualified resource ID] on Azure, a [full resource name] on GCP).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function\",\n\t// \"//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID\",\n\t// \"/subscriptions/<SUBSCRIPTION_GUID>/resourceGroups/<RG>\n\t// /providers/Microsoft.Web/sites/<FUNCAPP>/functions/<FUNC>\"\n\t// Note: On some cloud providers, it may not be possible to determine the full\n\t// ID at startup,\n\t// so it may be necessary to set `cloud.resource_id` as a span attribute\n\t// instead.\n\t//\n\t// The exact value to use for `cloud.resource_id` depends on the cloud provider.\n\t// The following well-known definitions MUST be used if you set this attribute\n\t// and they apply:\n\t//\n\t//   - **AWS Lambda:** The function [ARN].\n\t//     Take care not to use the \"invoked ARN\" directly but replace any\n\t//     [alias suffix]\n\t//     with the resolved function version, as the same runtime instance may be\n\t//     invocable with\n\t//     multiple different aliases.\n\t//   - **GCP:** The [URI of the resource]\n\t//   - **Azure:** The [Fully Qualified Resource ID] of the invoked function,\n\t//     *not* the function app, having the form\n\t//\n\t//     `/subscriptions/<SUBSCRIPTION_GUID>/resourceGroups/<RG>/providers/Microsoft.Web/sites/<FUNCAPP>/functions/<FUNC>`\n\t//     .\n\t//     This means that a span attribute MUST be used, as an Azure function app\n\t//     can host multiple functions that would usually share\n\t//     a TracerProvider.\n\t//\n\t//\n\t// [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html\n\t// [fully qualified resource ID]: https://learn.microsoft.com/rest/api/resources/resources/get-by-id\n\t// [full resource name]: https://google.aip.dev/122#full-resource-names\n\t// [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html\n\t// [alias suffix]: https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html\n\t// [URI of the resource]: https://cloud.google.com/iam/docs/full-resource-names\n\t// [Fully Qualified Resource ID]: https://learn.microsoft.com/rest/api/resources/resources/get-by-id\n\tCloudResourceIDKey = attribute.Key(\"cloud.resource_id\")\n)\n\n// CloudAccountID returns an attribute KeyValue conforming to the\n// \"cloud.account.id\" semantic conventions. It represents the cloud account ID\n// the resource is assigned to.\nfunc CloudAccountID(val string) attribute.KeyValue {\n\treturn CloudAccountIDKey.String(val)\n}\n\n// CloudAvailabilityZone returns an attribute KeyValue conforming to the\n// \"cloud.availability_zone\" semantic conventions. It represents the cloud\n// regions often have multiple, isolated locations known as zones to increase\n// availability. Availability zone represents the zone where the resource is\n// running.\nfunc CloudAvailabilityZone(val string) attribute.KeyValue {\n\treturn CloudAvailabilityZoneKey.String(val)\n}\n\n// CloudRegion returns an attribute KeyValue conforming to the \"cloud.region\"\n// semantic conventions. It represents the geographical region within a cloud\n// provider. When associated with a resource, this attribute specifies the region\n// where the resource operates. When calling services or APIs deployed on a\n// cloud, this attribute identifies the region where the called destination is\n// deployed.\nfunc CloudRegion(val string) attribute.KeyValue {\n\treturn CloudRegionKey.String(val)\n}\n\n// CloudResourceID returns an attribute KeyValue conforming to the\n// \"cloud.resource_id\" semantic conventions. It represents the cloud\n// provider-specific native identifier of the monitored cloud resource (e.g. an\n// [ARN] on AWS, a [fully qualified resource ID] on Azure, a [full resource name]\n//  on GCP).\n//\n// [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html\n// [fully qualified resource ID]: https://learn.microsoft.com/rest/api/resources/resources/get-by-id\n// [full resource name]: https://google.aip.dev/122#full-resource-names\nfunc CloudResourceID(val string) attribute.KeyValue {\n\treturn CloudResourceIDKey.String(val)\n}\n\n// Enum values for cloud.platform\nvar (\n\t// Alibaba Cloud Elastic Compute Service\n\t// Stability: development\n\tCloudPlatformAlibabaCloudECS = CloudPlatformKey.String(\"alibaba_cloud_ecs\")\n\t// Alibaba Cloud Function Compute\n\t// Stability: development\n\tCloudPlatformAlibabaCloudFC = CloudPlatformKey.String(\"alibaba_cloud_fc\")\n\t// Red Hat OpenShift on Alibaba Cloud\n\t// Stability: development\n\tCloudPlatformAlibabaCloudOpenShift = CloudPlatformKey.String(\"alibaba_cloud_openshift\")\n\t// AWS Elastic Compute Cloud\n\t// Stability: development\n\tCloudPlatformAWSEC2 = CloudPlatformKey.String(\"aws_ec2\")\n\t// AWS Elastic Container Service\n\t// Stability: development\n\tCloudPlatformAWSECS = CloudPlatformKey.String(\"aws_ecs\")\n\t// AWS Elastic Kubernetes Service\n\t// Stability: development\n\tCloudPlatformAWSEKS = CloudPlatformKey.String(\"aws_eks\")\n\t// AWS Lambda\n\t// Stability: development\n\tCloudPlatformAWSLambda = CloudPlatformKey.String(\"aws_lambda\")\n\t// AWS Elastic Beanstalk\n\t// Stability: development\n\tCloudPlatformAWSElasticBeanstalk = CloudPlatformKey.String(\"aws_elastic_beanstalk\")\n\t// AWS App Runner\n\t// Stability: development\n\tCloudPlatformAWSAppRunner = CloudPlatformKey.String(\"aws_app_runner\")\n\t// Red Hat OpenShift on AWS (ROSA)\n\t// Stability: development\n\tCloudPlatformAWSOpenShift = CloudPlatformKey.String(\"aws_openshift\")\n\t// Azure Virtual Machines\n\t// Stability: development\n\tCloudPlatformAzureVM = CloudPlatformKey.String(\"azure.vm\")\n\t// Azure Container Apps\n\t// Stability: development\n\tCloudPlatformAzureContainerApps = CloudPlatformKey.String(\"azure.container_apps\")\n\t// Azure Container Instances\n\t// Stability: development\n\tCloudPlatformAzureContainerInstances = CloudPlatformKey.String(\"azure.container_instances\")\n\t// Azure Kubernetes Service\n\t// Stability: development\n\tCloudPlatformAzureAKS = CloudPlatformKey.String(\"azure.aks\")\n\t// Azure Functions\n\t// Stability: development\n\tCloudPlatformAzureFunctions = CloudPlatformKey.String(\"azure.functions\")\n\t// Azure App Service\n\t// Stability: development\n\tCloudPlatformAzureAppService = CloudPlatformKey.String(\"azure.app_service\")\n\t// Azure Red Hat OpenShift\n\t// Stability: development\n\tCloudPlatformAzureOpenShift = CloudPlatformKey.String(\"azure.openshift\")\n\t// Google Bare Metal Solution (BMS)\n\t// Stability: development\n\tCloudPlatformGCPBareMetalSolution = CloudPlatformKey.String(\"gcp_bare_metal_solution\")\n\t// Google Cloud Compute Engine (GCE)\n\t// Stability: development\n\tCloudPlatformGCPComputeEngine = CloudPlatformKey.String(\"gcp_compute_engine\")\n\t// Google Cloud Run\n\t// Stability: development\n\tCloudPlatformGCPCloudRun = CloudPlatformKey.String(\"gcp_cloud_run\")\n\t// Google Cloud Kubernetes Engine (GKE)\n\t// Stability: development\n\tCloudPlatformGCPKubernetesEngine = CloudPlatformKey.String(\"gcp_kubernetes_engine\")\n\t// Google Cloud Functions (GCF)\n\t// Stability: development\n\tCloudPlatformGCPCloudFunctions = CloudPlatformKey.String(\"gcp_cloud_functions\")\n\t// Google Cloud App Engine (GAE)\n\t// Stability: development\n\tCloudPlatformGCPAppEngine = CloudPlatformKey.String(\"gcp_app_engine\")\n\t// Red Hat OpenShift on Google Cloud\n\t// Stability: development\n\tCloudPlatformGCPOpenShift = CloudPlatformKey.String(\"gcp_openshift\")\n\t// Red Hat OpenShift on IBM Cloud\n\t// Stability: development\n\tCloudPlatformIBMCloudOpenShift = CloudPlatformKey.String(\"ibm_cloud_openshift\")\n\t// Compute on Oracle Cloud Infrastructure (OCI)\n\t// Stability: development\n\tCloudPlatformOracleCloudCompute = CloudPlatformKey.String(\"oracle_cloud_compute\")\n\t// Kubernetes Engine (OKE) on Oracle Cloud Infrastructure (OCI)\n\t// Stability: development\n\tCloudPlatformOracleCloudOKE = CloudPlatformKey.String(\"oracle_cloud_oke\")\n\t// Tencent Cloud Cloud Virtual Machine (CVM)\n\t// Stability: development\n\tCloudPlatformTencentCloudCVM = CloudPlatformKey.String(\"tencent_cloud_cvm\")\n\t// Tencent Cloud Elastic Kubernetes Service (EKS)\n\t// Stability: development\n\tCloudPlatformTencentCloudEKS = CloudPlatformKey.String(\"tencent_cloud_eks\")\n\t// Tencent Cloud Serverless Cloud Function (SCF)\n\t// Stability: development\n\tCloudPlatformTencentCloudSCF = CloudPlatformKey.String(\"tencent_cloud_scf\")\n)\n\n// Enum values for cloud.provider\nvar (\n\t// Alibaba Cloud\n\t// Stability: development\n\tCloudProviderAlibabaCloud = CloudProviderKey.String(\"alibaba_cloud\")\n\t// Amazon Web Services\n\t// Stability: development\n\tCloudProviderAWS = CloudProviderKey.String(\"aws\")\n\t// Microsoft Azure\n\t// Stability: development\n\tCloudProviderAzure = CloudProviderKey.String(\"azure\")\n\t// Google Cloud Platform\n\t// Stability: development\n\tCloudProviderGCP = CloudProviderKey.String(\"gcp\")\n\t// Heroku Platform as a Service\n\t// Stability: development\n\tCloudProviderHeroku = CloudProviderKey.String(\"heroku\")\n\t// IBM Cloud\n\t// Stability: development\n\tCloudProviderIBMCloud = CloudProviderKey.String(\"ibm_cloud\")\n\t// Oracle Cloud Infrastructure (OCI)\n\t// Stability: development\n\tCloudProviderOracleCloud = CloudProviderKey.String(\"oracle_cloud\")\n\t// Tencent Cloud\n\t// Stability: development\n\tCloudProviderTencentCloud = CloudProviderKey.String(\"tencent_cloud\")\n)\n\n// Namespace: cloudevents\nconst (\n\t// CloudEventsEventIDKey is the attribute Key conforming to the\n\t// \"cloudevents.event_id\" semantic conventions. It represents the [event_id]\n\t// uniquely identifies the event.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"123e4567-e89b-12d3-a456-426614174000\", \"0001\"\n\t//\n\t// [event_id]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id\n\tCloudEventsEventIDKey = attribute.Key(\"cloudevents.event_id\")\n\n\t// CloudEventsEventSourceKey is the attribute Key conforming to the\n\t// \"cloudevents.event_source\" semantic conventions. It represents the [source]\n\t// identifies the context in which an event happened.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"https://github.com/cloudevents\", \"/cloudevents/spec/pull/123\",\n\t// \"my-service\"\n\t//\n\t// [source]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1\n\tCloudEventsEventSourceKey = attribute.Key(\"cloudevents.event_source\")\n\n\t// CloudEventsEventSpecVersionKey is the attribute Key conforming to the\n\t// \"cloudevents.event_spec_version\" semantic conventions. It represents the\n\t// [version of the CloudEvents specification] which the event uses.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1.0\n\t//\n\t// [version of the CloudEvents specification]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion\n\tCloudEventsEventSpecVersionKey = attribute.Key(\"cloudevents.event_spec_version\")\n\n\t// CloudEventsEventSubjectKey is the attribute Key conforming to the\n\t// \"cloudevents.event_subject\" semantic conventions. It represents the [subject]\n\t//  of the event in the context of the event producer (identified by source).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: mynewfile.jpg\n\t//\n\t// [subject]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject\n\tCloudEventsEventSubjectKey = attribute.Key(\"cloudevents.event_subject\")\n\n\t// CloudEventsEventTypeKey is the attribute Key conforming to the\n\t// \"cloudevents.event_type\" semantic conventions. It represents the [event_type]\n\t//  contains a value describing the type of event related to the originating\n\t// occurrence.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"com.github.pull_request.opened\", \"com.example.object.deleted.v2\"\n\t//\n\t// [event_type]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type\n\tCloudEventsEventTypeKey = attribute.Key(\"cloudevents.event_type\")\n)\n\n// CloudEventsEventID returns an attribute KeyValue conforming to the\n// \"cloudevents.event_id\" semantic conventions. It represents the [event_id]\n// uniquely identifies the event.\n//\n// [event_id]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id\nfunc CloudEventsEventID(val string) attribute.KeyValue {\n\treturn CloudEventsEventIDKey.String(val)\n}\n\n// CloudEventsEventSource returns an attribute KeyValue conforming to the\n// \"cloudevents.event_source\" semantic conventions. It represents the [source]\n// identifies the context in which an event happened.\n//\n// [source]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1\nfunc CloudEventsEventSource(val string) attribute.KeyValue {\n\treturn CloudEventsEventSourceKey.String(val)\n}\n\n// CloudEventsEventSpecVersion returns an attribute KeyValue conforming to the\n// \"cloudevents.event_spec_version\" semantic conventions. It represents the\n// [version of the CloudEvents specification] which the event uses.\n//\n// [version of the CloudEvents specification]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion\nfunc CloudEventsEventSpecVersion(val string) attribute.KeyValue {\n\treturn CloudEventsEventSpecVersionKey.String(val)\n}\n\n// CloudEventsEventSubject returns an attribute KeyValue conforming to the\n// \"cloudevents.event_subject\" semantic conventions. It represents the [subject]\n// of the event in the context of the event producer (identified by source).\n//\n// [subject]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject\nfunc CloudEventsEventSubject(val string) attribute.KeyValue {\n\treturn CloudEventsEventSubjectKey.String(val)\n}\n\n// CloudEventsEventType returns an attribute KeyValue conforming to the\n// \"cloudevents.event_type\" semantic conventions. It represents the [event_type]\n// contains a value describing the type of event related to the originating\n// occurrence.\n//\n// [event_type]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type\nfunc CloudEventsEventType(val string) attribute.KeyValue {\n\treturn CloudEventsEventTypeKey.String(val)\n}\n\n// Namespace: cloudfoundry\nconst (\n\t// CloudFoundryAppIDKey is the attribute Key conforming to the\n\t// \"cloudfoundry.app.id\" semantic conventions. It represents the guid of the\n\t// application.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"218fc5a9-a5f1-4b54-aa05-46717d0ab26d\"\n\t// Note: Application instrumentation should use the value from environment\n\t// variable `VCAP_APPLICATION.application_id`. This is the same value as\n\t// reported by `cf app <app-name> --guid`.\n\tCloudFoundryAppIDKey = attribute.Key(\"cloudfoundry.app.id\")\n\n\t// CloudFoundryAppInstanceIDKey is the attribute Key conforming to the\n\t// \"cloudfoundry.app.instance.id\" semantic conventions. It represents the index\n\t// of the application instance. 0 when just one instance is active.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"0\", \"1\"\n\t// Note: CloudFoundry defines the `instance_id` in the [Loggregator v2 envelope]\n\t// .\n\t// It is used for logs and metrics emitted by CloudFoundry. It is\n\t// supposed to contain the application instance index for applications\n\t// deployed on the runtime.\n\t//\n\t// Application instrumentation should use the value from environment\n\t// variable `CF_INSTANCE_INDEX`.\n\t//\n\t// [Loggregator v2 envelope]: https://github.com/cloudfoundry/loggregator-api#v2-envelope\n\tCloudFoundryAppInstanceIDKey = attribute.Key(\"cloudfoundry.app.instance.id\")\n\n\t// CloudFoundryAppNameKey is the attribute Key conforming to the\n\t// \"cloudfoundry.app.name\" semantic conventions. It represents the name of the\n\t// application.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-app-name\"\n\t// Note: Application instrumentation should use the value from environment\n\t// variable `VCAP_APPLICATION.application_name`. This is the same value\n\t// as reported by `cf apps`.\n\tCloudFoundryAppNameKey = attribute.Key(\"cloudfoundry.app.name\")\n\n\t// CloudFoundryOrgIDKey is the attribute Key conforming to the\n\t// \"cloudfoundry.org.id\" semantic conventions. It represents the guid of the\n\t// CloudFoundry org the application is running in.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"218fc5a9-a5f1-4b54-aa05-46717d0ab26d\"\n\t// Note: Application instrumentation should use the value from environment\n\t// variable `VCAP_APPLICATION.org_id`. This is the same value as\n\t// reported by `cf org <org-name> --guid`.\n\tCloudFoundryOrgIDKey = attribute.Key(\"cloudfoundry.org.id\")\n\n\t// CloudFoundryOrgNameKey is the attribute Key conforming to the\n\t// \"cloudfoundry.org.name\" semantic conventions. It represents the name of the\n\t// CloudFoundry organization the app is running in.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-org-name\"\n\t// Note: Application instrumentation should use the value from environment\n\t// variable `VCAP_APPLICATION.org_name`. This is the same value as\n\t// reported by `cf orgs`.\n\tCloudFoundryOrgNameKey = attribute.Key(\"cloudfoundry.org.name\")\n\n\t// CloudFoundryProcessIDKey is the attribute Key conforming to the\n\t// \"cloudfoundry.process.id\" semantic conventions. It represents the UID\n\t// identifying the process.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"218fc5a9-a5f1-4b54-aa05-46717d0ab26d\"\n\t// Note: Application instrumentation should use the value from environment\n\t// variable `VCAP_APPLICATION.process_id`. It is supposed to be equal to\n\t// `VCAP_APPLICATION.app_id` for applications deployed to the runtime.\n\t// For system components, this could be the actual PID.\n\tCloudFoundryProcessIDKey = attribute.Key(\"cloudfoundry.process.id\")\n\n\t// CloudFoundryProcessTypeKey is the attribute Key conforming to the\n\t// \"cloudfoundry.process.type\" semantic conventions. It represents the type of\n\t// process.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"web\"\n\t// Note: CloudFoundry applications can consist of multiple jobs. Usually the\n\t// main process will be of type `web`. There can be additional background\n\t// tasks or side-cars with different process types.\n\tCloudFoundryProcessTypeKey = attribute.Key(\"cloudfoundry.process.type\")\n\n\t// CloudFoundrySpaceIDKey is the attribute Key conforming to the\n\t// \"cloudfoundry.space.id\" semantic conventions. It represents the guid of the\n\t// CloudFoundry space the application is running in.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"218fc5a9-a5f1-4b54-aa05-46717d0ab26d\"\n\t// Note: Application instrumentation should use the value from environment\n\t// variable `VCAP_APPLICATION.space_id`. This is the same value as\n\t// reported by `cf space <space-name> --guid`.\n\tCloudFoundrySpaceIDKey = attribute.Key(\"cloudfoundry.space.id\")\n\n\t// CloudFoundrySpaceNameKey is the attribute Key conforming to the\n\t// \"cloudfoundry.space.name\" semantic conventions. It represents the name of the\n\t// CloudFoundry space the application is running in.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-space-name\"\n\t// Note: Application instrumentation should use the value from environment\n\t// variable `VCAP_APPLICATION.space_name`. This is the same value as\n\t// reported by `cf spaces`.\n\tCloudFoundrySpaceNameKey = attribute.Key(\"cloudfoundry.space.name\")\n\n\t// CloudFoundrySystemIDKey is the attribute Key conforming to the\n\t// \"cloudfoundry.system.id\" semantic conventions. It represents a guid or\n\t// another name describing the event source.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"cf/gorouter\"\n\t// Note: CloudFoundry defines the `source_id` in the [Loggregator v2 envelope].\n\t// It is used for logs and metrics emitted by CloudFoundry. It is\n\t// supposed to contain the component name, e.g. \"gorouter\", for\n\t// CloudFoundry components.\n\t//\n\t// When system components are instrumented, values from the\n\t// [Bosh spec]\n\t// should be used. The `system.id` should be set to\n\t// `spec.deployment/spec.name`.\n\t//\n\t// [Loggregator v2 envelope]: https://github.com/cloudfoundry/loggregator-api#v2-envelope\n\t// [Bosh spec]: https://bosh.io/docs/jobs/#properties-spec\n\tCloudFoundrySystemIDKey = attribute.Key(\"cloudfoundry.system.id\")\n\n\t// CloudFoundrySystemInstanceIDKey is the attribute Key conforming to the\n\t// \"cloudfoundry.system.instance.id\" semantic conventions. It represents a guid\n\t// describing the concrete instance of the event source.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"218fc5a9-a5f1-4b54-aa05-46717d0ab26d\"\n\t// Note: CloudFoundry defines the `instance_id` in the [Loggregator v2 envelope]\n\t// .\n\t// It is used for logs and metrics emitted by CloudFoundry. It is\n\t// supposed to contain the vm id for CloudFoundry components.\n\t//\n\t// When system components are instrumented, values from the\n\t// [Bosh spec]\n\t// should be used. The `system.instance.id` should be set to `spec.id`.\n\t//\n\t// [Loggregator v2 envelope]: https://github.com/cloudfoundry/loggregator-api#v2-envelope\n\t// [Bosh spec]: https://bosh.io/docs/jobs/#properties-spec\n\tCloudFoundrySystemInstanceIDKey = attribute.Key(\"cloudfoundry.system.instance.id\")\n)\n\n// CloudFoundryAppID returns an attribute KeyValue conforming to the\n// \"cloudfoundry.app.id\" semantic conventions. It represents the guid of the\n// application.\nfunc CloudFoundryAppID(val string) attribute.KeyValue {\n\treturn CloudFoundryAppIDKey.String(val)\n}\n\n// CloudFoundryAppInstanceID returns an attribute KeyValue conforming to the\n// \"cloudfoundry.app.instance.id\" semantic conventions. It represents the index\n// of the application instance. 0 when just one instance is active.\nfunc CloudFoundryAppInstanceID(val string) attribute.KeyValue {\n\treturn CloudFoundryAppInstanceIDKey.String(val)\n}\n\n// CloudFoundryAppName returns an attribute KeyValue conforming to the\n// \"cloudfoundry.app.name\" semantic conventions. It represents the name of the\n// application.\nfunc CloudFoundryAppName(val string) attribute.KeyValue {\n\treturn CloudFoundryAppNameKey.String(val)\n}\n\n// CloudFoundryOrgID returns an attribute KeyValue conforming to the\n// \"cloudfoundry.org.id\" semantic conventions. It represents the guid of the\n// CloudFoundry org the application is running in.\nfunc CloudFoundryOrgID(val string) attribute.KeyValue {\n\treturn CloudFoundryOrgIDKey.String(val)\n}\n\n// CloudFoundryOrgName returns an attribute KeyValue conforming to the\n// \"cloudfoundry.org.name\" semantic conventions. It represents the name of the\n// CloudFoundry organization the app is running in.\nfunc CloudFoundryOrgName(val string) attribute.KeyValue {\n\treturn CloudFoundryOrgNameKey.String(val)\n}\n\n// CloudFoundryProcessID returns an attribute KeyValue conforming to the\n// \"cloudfoundry.process.id\" semantic conventions. It represents the UID\n// identifying the process.\nfunc CloudFoundryProcessID(val string) attribute.KeyValue {\n\treturn CloudFoundryProcessIDKey.String(val)\n}\n\n// CloudFoundryProcessType returns an attribute KeyValue conforming to the\n// \"cloudfoundry.process.type\" semantic conventions. It represents the type of\n// process.\nfunc CloudFoundryProcessType(val string) attribute.KeyValue {\n\treturn CloudFoundryProcessTypeKey.String(val)\n}\n\n// CloudFoundrySpaceID returns an attribute KeyValue conforming to the\n// \"cloudfoundry.space.id\" semantic conventions. It represents the guid of the\n// CloudFoundry space the application is running in.\nfunc CloudFoundrySpaceID(val string) attribute.KeyValue {\n\treturn CloudFoundrySpaceIDKey.String(val)\n}\n\n// CloudFoundrySpaceName returns an attribute KeyValue conforming to the\n// \"cloudfoundry.space.name\" semantic conventions. It represents the name of the\n// CloudFoundry space the application is running in.\nfunc CloudFoundrySpaceName(val string) attribute.KeyValue {\n\treturn CloudFoundrySpaceNameKey.String(val)\n}\n\n// CloudFoundrySystemID returns an attribute KeyValue conforming to the\n// \"cloudfoundry.system.id\" semantic conventions. It represents a guid or another\n// name describing the event source.\nfunc CloudFoundrySystemID(val string) attribute.KeyValue {\n\treturn CloudFoundrySystemIDKey.String(val)\n}\n\n// CloudFoundrySystemInstanceID returns an attribute KeyValue conforming to the\n// \"cloudfoundry.system.instance.id\" semantic conventions. It represents a guid\n// describing the concrete instance of the event source.\nfunc CloudFoundrySystemInstanceID(val string) attribute.KeyValue {\n\treturn CloudFoundrySystemInstanceIDKey.String(val)\n}\n\n// Namespace: code\nconst (\n\t// CodeColumnNumberKey is the attribute Key conforming to the\n\t// \"code.column.number\" semantic conventions. It represents the column number in\n\t// `code.file.path` best representing the operation. It SHOULD point within the\n\t// code unit named in `code.function.name`. This attribute MUST NOT be used on\n\t// the Profile signal since the data is already captured in 'message Line'. This\n\t// constraint is imposed to prevent redundancy and maintain data integrity.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\tCodeColumnNumberKey = attribute.Key(\"code.column.number\")\n\n\t// CodeFilePathKey is the attribute Key conforming to the \"code.file.path\"\n\t// semantic conventions. It represents the source code file name that identifies\n\t// the code unit as uniquely as possible (preferably an absolute file path).\n\t// This attribute MUST NOT be used on the Profile signal since the data is\n\t// already captured in 'message Function'. This constraint is imposed to prevent\n\t// redundancy and maintain data integrity.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: /usr/local/MyApplication/content_root/app/index.php\n\tCodeFilePathKey = attribute.Key(\"code.file.path\")\n\n\t// CodeFunctionNameKey is the attribute Key conforming to the\n\t// \"code.function.name\" semantic conventions. It represents the method or\n\t// function fully-qualified name without arguments. The value should fit the\n\t// natural representation of the language runtime, which is also likely the same\n\t// used within `code.stacktrace` attribute value. This attribute MUST NOT be\n\t// used on the Profile signal since the data is already captured in 'message\n\t// Function'. This constraint is imposed to prevent redundancy and maintain data\n\t// integrity.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"com.example.MyHttpService.serveRequest\",\n\t// \"GuzzleHttp\\Client::transfer\", \"fopen\"\n\t// Note: Values and format depends on each language runtime, thus it is\n\t// impossible to provide an exhaustive list of examples.\n\t// The values are usually the same (or prefixes of) the ones found in native\n\t// stack trace representation stored in\n\t// `code.stacktrace` without information on arguments.\n\t//\n\t// Examples:\n\t//\n\t//   - Java method: `com.example.MyHttpService.serveRequest`\n\t//   - Java anonymous class method: `com.mycompany.Main$1.myMethod`\n\t//   - Java lambda method:\n\t//     `com.mycompany.Main$$Lambda/0x0000748ae4149c00.myMethod`\n\t//   - PHP function: `GuzzleHttp\\Client::transfer`\n\t//   - Go function: `github.com/my/repo/pkg.foo.func5`\n\t//   - Elixir: `OpenTelemetry.Ctx.new`\n\t//   - Erlang: `opentelemetry_ctx:new`\n\t//   - Rust: `playground::my_module::my_cool_func`\n\t//   - C function: `fopen`\n\tCodeFunctionNameKey = attribute.Key(\"code.function.name\")\n\n\t// CodeLineNumberKey is the attribute Key conforming to the \"code.line.number\"\n\t// semantic conventions. It represents the line number in `code.file.path` best\n\t// representing the operation. It SHOULD point within the code unit named in\n\t// `code.function.name`. This attribute MUST NOT be used on the Profile signal\n\t// since the data is already captured in 'message Line'. This constraint is\n\t// imposed to prevent redundancy and maintain data integrity.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\tCodeLineNumberKey = attribute.Key(\"code.line.number\")\n\n\t// CodeStacktraceKey is the attribute Key conforming to the \"code.stacktrace\"\n\t// semantic conventions. It represents a stacktrace as a string in the natural\n\t// representation for the language runtime. The representation is identical to\n\t// [`exception.stacktrace`]. This attribute MUST NOT be used on the Profile\n\t// signal since the data is already captured in 'message Location'. This\n\t// constraint is imposed to prevent redundancy and maintain data integrity.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\\n at\n\t// com.example.GenerateTrace.methodA(GenerateTrace.java:9)\\n at\n\t// com.example.GenerateTrace.main(GenerateTrace.java:5)\n\t//\n\t// [`exception.stacktrace`]: /docs/exceptions/exceptions-spans.md#stacktrace-representation\n\tCodeStacktraceKey = attribute.Key(\"code.stacktrace\")\n)\n\n// CodeColumnNumber returns an attribute KeyValue conforming to the\n// \"code.column.number\" semantic conventions. It represents the column number in\n// `code.file.path` best representing the operation. It SHOULD point within the\n// code unit named in `code.function.name`. This attribute MUST NOT be used on\n// the Profile signal since the data is already captured in 'message Line'. This\n// constraint is imposed to prevent redundancy and maintain data integrity.\nfunc CodeColumnNumber(val int) attribute.KeyValue {\n\treturn CodeColumnNumberKey.Int(val)\n}\n\n// CodeFilePath returns an attribute KeyValue conforming to the \"code.file.path\"\n// semantic conventions. It represents the source code file name that identifies\n// the code unit as uniquely as possible (preferably an absolute file path). This\n// attribute MUST NOT be used on the Profile signal since the data is already\n// captured in 'message Function'. This constraint is imposed to prevent\n// redundancy and maintain data integrity.\nfunc CodeFilePath(val string) attribute.KeyValue {\n\treturn CodeFilePathKey.String(val)\n}\n\n// CodeFunctionName returns an attribute KeyValue conforming to the\n// \"code.function.name\" semantic conventions. It represents the method or\n// function fully-qualified name without arguments. The value should fit the\n// natural representation of the language runtime, which is also likely the same\n// used within `code.stacktrace` attribute value. This attribute MUST NOT be used\n// on the Profile signal since the data is already captured in 'message\n// Function'. This constraint is imposed to prevent redundancy and maintain data\n// integrity.\nfunc CodeFunctionName(val string) attribute.KeyValue {\n\treturn CodeFunctionNameKey.String(val)\n}\n\n// CodeLineNumber returns an attribute KeyValue conforming to the\n// \"code.line.number\" semantic conventions. It represents the line number in\n// `code.file.path` best representing the operation. It SHOULD point within the\n// code unit named in `code.function.name`. This attribute MUST NOT be used on\n// the Profile signal since the data is already captured in 'message Line'. This\n// constraint is imposed to prevent redundancy and maintain data integrity.\nfunc CodeLineNumber(val int) attribute.KeyValue {\n\treturn CodeLineNumberKey.Int(val)\n}\n\n// CodeStacktrace returns an attribute KeyValue conforming to the\n// \"code.stacktrace\" semantic conventions. It represents a stacktrace as a string\n// in the natural representation for the language runtime. The representation is\n// identical to [`exception.stacktrace`]. This attribute MUST NOT be used on the\n// Profile signal since the data is already captured in 'message Location'. This\n// constraint is imposed to prevent redundancy and maintain data integrity.\n//\n// [`exception.stacktrace`]: /docs/exceptions/exceptions-spans.md#stacktrace-representation\nfunc CodeStacktrace(val string) attribute.KeyValue {\n\treturn CodeStacktraceKey.String(val)\n}\n\n// Namespace: container\nconst (\n\t// ContainerCommandKey is the attribute Key conforming to the\n\t// \"container.command\" semantic conventions. It represents the command used to\n\t// run the container (i.e. the command name).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"otelcontribcol\"\n\t// Note: If using embedded credentials or sensitive data, it is recommended to\n\t// remove them to prevent potential leakage.\n\tContainerCommandKey = attribute.Key(\"container.command\")\n\n\t// ContainerCommandArgsKey is the attribute Key conforming to the\n\t// \"container.command_args\" semantic conventions. It represents the all the\n\t// command arguments (including the command/executable itself) run by the\n\t// container.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"otelcontribcol\", \"--config\", \"config.yaml\"\n\tContainerCommandArgsKey = attribute.Key(\"container.command_args\")\n\n\t// ContainerCommandLineKey is the attribute Key conforming to the\n\t// \"container.command_line\" semantic conventions. It represents the full command\n\t// run by the container as a single string representing the full command.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"otelcontribcol --config config.yaml\"\n\tContainerCommandLineKey = attribute.Key(\"container.command_line\")\n\n\t// ContainerCSIPluginNameKey is the attribute Key conforming to the\n\t// \"container.csi.plugin.name\" semantic conventions. It represents the name of\n\t// the CSI ([Container Storage Interface]) plugin used by the volume.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"pd.csi.storage.gke.io\"\n\t// Note: This can sometimes be referred to as a \"driver\" in CSI implementations.\n\t// This should represent the `name` field of the GetPluginInfo RPC.\n\t//\n\t// [Container Storage Interface]: https://github.com/container-storage-interface/spec\n\tContainerCSIPluginNameKey = attribute.Key(\"container.csi.plugin.name\")\n\n\t// ContainerCSIVolumeIDKey is the attribute Key conforming to the\n\t// \"container.csi.volume.id\" semantic conventions. It represents the unique\n\t// volume ID returned by the CSI ([Container Storage Interface]) plugin.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"projects/my-gcp-project/zones/my-gcp-zone/disks/my-gcp-disk\"\n\t// Note: This can sometimes be referred to as a \"volume handle\" in CSI\n\t// implementations. This should represent the `Volume.volume_id` field in CSI\n\t// spec.\n\t//\n\t// [Container Storage Interface]: https://github.com/container-storage-interface/spec\n\tContainerCSIVolumeIDKey = attribute.Key(\"container.csi.volume.id\")\n\n\t// ContainerIDKey is the attribute Key conforming to the \"container.id\" semantic\n\t// conventions. It represents the container ID. Usually a UUID, as for example\n\t// used to [identify Docker containers]. The UUID might be abbreviated.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"a3bf90e006b2\"\n\t//\n\t// [identify Docker containers]: https://docs.docker.com/engine/containers/run/#container-identification\n\tContainerIDKey = attribute.Key(\"container.id\")\n\n\t// ContainerImageIDKey is the attribute Key conforming to the\n\t// \"container.image.id\" semantic conventions. It represents the runtime specific\n\t// image identifier. Usually a hash algorithm followed by a UUID.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f\"\n\t// Note: Docker defines a sha256 of the image id; `container.image.id`\n\t// corresponds to the `Image` field from the Docker container inspect [API]\n\t// endpoint.\n\t// K8s defines a link to the container registry repository with digest\n\t// `\"imageID\": \"registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625\"`\n\t// .\n\t// The ID is assigned by the container runtime and can vary in different\n\t// environments. Consider using `oci.manifest.digest` if it is important to\n\t// identify the same image in different environments/runtimes.\n\t//\n\t// [API]: https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect\n\tContainerImageIDKey = attribute.Key(\"container.image.id\")\n\n\t// ContainerImageNameKey is the attribute Key conforming to the\n\t// \"container.image.name\" semantic conventions. It represents the name of the\n\t// image the container was built on.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"gcr.io/opentelemetry/operator\"\n\tContainerImageNameKey = attribute.Key(\"container.image.name\")\n\n\t// ContainerImageRepoDigestsKey is the attribute Key conforming to the\n\t// \"container.image.repo_digests\" semantic conventions. It represents the repo\n\t// digests of the container image as provided by the container runtime.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb\",\n\t// \"internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578\"\n\t// Note: [Docker] and [CRI] report those under the `RepoDigests` field.\n\t//\n\t// [Docker]: https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect\n\t// [CRI]: https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238\n\tContainerImageRepoDigestsKey = attribute.Key(\"container.image.repo_digests\")\n\n\t// ContainerImageTagsKey is the attribute Key conforming to the\n\t// \"container.image.tags\" semantic conventions. It represents the container\n\t// image tags. An example can be found in [Docker Image Inspect]. Should be only\n\t// the `<tag>` section of the full name for example from\n\t// `registry.example.com/my-org/my-image:<tag>`.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"v1.27.1\", \"3.5.7-0\"\n\t//\n\t// [Docker Image Inspect]: https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect\n\tContainerImageTagsKey = attribute.Key(\"container.image.tags\")\n\n\t// ContainerNameKey is the attribute Key conforming to the \"container.name\"\n\t// semantic conventions. It represents the container name used by container\n\t// runtime.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry-autoconf\"\n\tContainerNameKey = attribute.Key(\"container.name\")\n\n\t// ContainerRuntimeDescriptionKey is the attribute Key conforming to the\n\t// \"container.runtime.description\" semantic conventions. It represents a\n\t// description about the runtime which could include, for example details about\n\t// the CRI/API version being used or other customisations.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"docker://19.3.1 - CRI: 1.22.0\"\n\tContainerRuntimeDescriptionKey = attribute.Key(\"container.runtime.description\")\n\n\t// ContainerRuntimeNameKey is the attribute Key conforming to the\n\t// \"container.runtime.name\" semantic conventions. It represents the container\n\t// runtime managing this container.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"docker\", \"containerd\", \"rkt\"\n\tContainerRuntimeNameKey = attribute.Key(\"container.runtime.name\")\n\n\t// ContainerRuntimeVersionKey is the attribute Key conforming to the\n\t// \"container.runtime.version\" semantic conventions. It represents the version\n\t// of the runtime of this process, as returned by the runtime without\n\t// modification.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1.0.0\n\tContainerRuntimeVersionKey = attribute.Key(\"container.runtime.version\")\n)\n\n// ContainerCommand returns an attribute KeyValue conforming to the\n// \"container.command\" semantic conventions. It represents the command used to\n// run the container (i.e. the command name).\nfunc ContainerCommand(val string) attribute.KeyValue {\n\treturn ContainerCommandKey.String(val)\n}\n\n// ContainerCommandArgs returns an attribute KeyValue conforming to the\n// \"container.command_args\" semantic conventions. It represents the all the\n// command arguments (including the command/executable itself) run by the\n// container.\nfunc ContainerCommandArgs(val ...string) attribute.KeyValue {\n\treturn ContainerCommandArgsKey.StringSlice(val)\n}\n\n// ContainerCommandLine returns an attribute KeyValue conforming to the\n// \"container.command_line\" semantic conventions. It represents the full command\n// run by the container as a single string representing the full command.\nfunc ContainerCommandLine(val string) attribute.KeyValue {\n\treturn ContainerCommandLineKey.String(val)\n}\n\n// ContainerCSIPluginName returns an attribute KeyValue conforming to the\n// \"container.csi.plugin.name\" semantic conventions. It represents the name of\n// the CSI ([Container Storage Interface]) plugin used by the volume.\n//\n// [Container Storage Interface]: https://github.com/container-storage-interface/spec\nfunc ContainerCSIPluginName(val string) attribute.KeyValue {\n\treturn ContainerCSIPluginNameKey.String(val)\n}\n\n// ContainerCSIVolumeID returns an attribute KeyValue conforming to the\n// \"container.csi.volume.id\" semantic conventions. It represents the unique\n// volume ID returned by the CSI ([Container Storage Interface]) plugin.\n//\n// [Container Storage Interface]: https://github.com/container-storage-interface/spec\nfunc ContainerCSIVolumeID(val string) attribute.KeyValue {\n\treturn ContainerCSIVolumeIDKey.String(val)\n}\n\n// ContainerID returns an attribute KeyValue conforming to the \"container.id\"\n// semantic conventions. It represents the container ID. Usually a UUID, as for\n// example used to [identify Docker containers]. The UUID might be abbreviated.\n//\n// [identify Docker containers]: https://docs.docker.com/engine/containers/run/#container-identification\nfunc ContainerID(val string) attribute.KeyValue {\n\treturn ContainerIDKey.String(val)\n}\n\n// ContainerImageID returns an attribute KeyValue conforming to the\n// \"container.image.id\" semantic conventions. It represents the runtime specific\n// image identifier. Usually a hash algorithm followed by a UUID.\nfunc ContainerImageID(val string) attribute.KeyValue {\n\treturn ContainerImageIDKey.String(val)\n}\n\n// ContainerImageName returns an attribute KeyValue conforming to the\n// \"container.image.name\" semantic conventions. It represents the name of the\n// image the container was built on.\nfunc ContainerImageName(val string) attribute.KeyValue {\n\treturn ContainerImageNameKey.String(val)\n}\n\n// ContainerImageRepoDigests returns an attribute KeyValue conforming to the\n// \"container.image.repo_digests\" semantic conventions. It represents the repo\n// digests of the container image as provided by the container runtime.\nfunc ContainerImageRepoDigests(val ...string) attribute.KeyValue {\n\treturn ContainerImageRepoDigestsKey.StringSlice(val)\n}\n\n// ContainerImageTags returns an attribute KeyValue conforming to the\n// \"container.image.tags\" semantic conventions. It represents the container image\n// tags. An example can be found in [Docker Image Inspect]. Should be only the\n// `<tag>` section of the full name for example from\n// `registry.example.com/my-org/my-image:<tag>`.\n//\n// [Docker Image Inspect]: https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect\nfunc ContainerImageTags(val ...string) attribute.KeyValue {\n\treturn ContainerImageTagsKey.StringSlice(val)\n}\n\n// ContainerLabel returns an attribute KeyValue conforming to the\n// \"container.label\" semantic conventions. It represents the container labels,\n// `<key>` being the label name, the value being the label value.\nfunc ContainerLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"container.label.\"+key, val)\n}\n\n// ContainerName returns an attribute KeyValue conforming to the \"container.name\"\n// semantic conventions. It represents the container name used by container\n// runtime.\nfunc ContainerName(val string) attribute.KeyValue {\n\treturn ContainerNameKey.String(val)\n}\n\n// ContainerRuntimeDescription returns an attribute KeyValue conforming to the\n// \"container.runtime.description\" semantic conventions. It represents a\n// description about the runtime which could include, for example details about\n// the CRI/API version being used or other customisations.\nfunc ContainerRuntimeDescription(val string) attribute.KeyValue {\n\treturn ContainerRuntimeDescriptionKey.String(val)\n}\n\n// ContainerRuntimeName returns an attribute KeyValue conforming to the\n// \"container.runtime.name\" semantic conventions. It represents the container\n// runtime managing this container.\nfunc ContainerRuntimeName(val string) attribute.KeyValue {\n\treturn ContainerRuntimeNameKey.String(val)\n}\n\n// ContainerRuntimeVersion returns an attribute KeyValue conforming to the\n// \"container.runtime.version\" semantic conventions. It represents the version of\n// the runtime of this process, as returned by the runtime without modification.\nfunc ContainerRuntimeVersion(val string) attribute.KeyValue {\n\treturn ContainerRuntimeVersionKey.String(val)\n}\n\n// Namespace: cpu\nconst (\n\t// CPULogicalNumberKey is the attribute Key conforming to the\n\t// \"cpu.logical_number\" semantic conventions. It represents the logical CPU\n\t// number [0..n-1].\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1\n\tCPULogicalNumberKey = attribute.Key(\"cpu.logical_number\")\n\n\t// CPUModeKey is the attribute Key conforming to the \"cpu.mode\" semantic\n\t// conventions. It represents the mode of the CPU.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"user\", \"system\"\n\tCPUModeKey = attribute.Key(\"cpu.mode\")\n)\n\n// CPULogicalNumber returns an attribute KeyValue conforming to the\n// \"cpu.logical_number\" semantic conventions. It represents the logical CPU\n// number [0..n-1].\nfunc CPULogicalNumber(val int) attribute.KeyValue {\n\treturn CPULogicalNumberKey.Int(val)\n}\n\n// Enum values for cpu.mode\nvar (\n\t// User\n\t// Stability: development\n\tCPUModeUser = CPUModeKey.String(\"user\")\n\t// System\n\t// Stability: development\n\tCPUModeSystem = CPUModeKey.String(\"system\")\n\t// Nice\n\t// Stability: development\n\tCPUModeNice = CPUModeKey.String(\"nice\")\n\t// Idle\n\t// Stability: development\n\tCPUModeIdle = CPUModeKey.String(\"idle\")\n\t// IO Wait\n\t// Stability: development\n\tCPUModeIOWait = CPUModeKey.String(\"iowait\")\n\t// Interrupt\n\t// Stability: development\n\tCPUModeInterrupt = CPUModeKey.String(\"interrupt\")\n\t// Steal\n\t// Stability: development\n\tCPUModeSteal = CPUModeKey.String(\"steal\")\n\t// Kernel\n\t// Stability: development\n\tCPUModeKernel = CPUModeKey.String(\"kernel\")\n)\n\n// Namespace: db\nconst (\n\t// DBClientConnectionPoolNameKey is the attribute Key conforming to the\n\t// \"db.client.connection.pool.name\" semantic conventions. It represents the name\n\t// of the connection pool; unique within the instrumented application. In case\n\t// the connection pool implementation doesn't provide a name, instrumentation\n\t// SHOULD use a combination of parameters that would make the name unique, for\n\t// example, combining attributes `server.address`, `server.port`, and\n\t// `db.namespace`, formatted as `server.address:server.port/db.namespace`.\n\t// Instrumentations that generate connection pool name following different\n\t// patterns SHOULD document it.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"myDataSource\"\n\tDBClientConnectionPoolNameKey = attribute.Key(\"db.client.connection.pool.name\")\n\n\t// DBClientConnectionStateKey is the attribute Key conforming to the\n\t// \"db.client.connection.state\" semantic conventions. It represents the state of\n\t// a connection in the pool.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"idle\"\n\tDBClientConnectionStateKey = attribute.Key(\"db.client.connection.state\")\n\n\t// DBCollectionNameKey is the attribute Key conforming to the\n\t// \"db.collection.name\" semantic conventions. It represents the name of a\n\t// collection (table, container) within the database.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"public.users\", \"customers\"\n\t// Note: It is RECOMMENDED to capture the value as provided by the application\n\t// without attempting to do any case normalization.\n\t//\n\t// The collection name SHOULD NOT be extracted from `db.query.text`,\n\t// when the database system supports query text with multiple collections\n\t// in non-batch operations.\n\t//\n\t// For batch operations, if the individual operations are known to have the same\n\t// collection name then that collection name SHOULD be used.\n\tDBCollectionNameKey = attribute.Key(\"db.collection.name\")\n\n\t// DBNamespaceKey is the attribute Key conforming to the \"db.namespace\" semantic\n\t// conventions. It represents the name of the database, fully qualified within\n\t// the server address and port.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"customers\", \"test.users\"\n\t// Note: If a database system has multiple namespace components, they SHOULD be\n\t// concatenated from the most general to the most specific namespace component,\n\t// using `|` as a separator between the components. Any missing components (and\n\t// their associated separators) SHOULD be omitted.\n\t// Semantic conventions for individual database systems SHOULD document what\n\t// `db.namespace` means in the context of that system.\n\t// It is RECOMMENDED to capture the value as provided by the application without\n\t// attempting to do any case normalization.\n\tDBNamespaceKey = attribute.Key(\"db.namespace\")\n\n\t// DBOperationBatchSizeKey is the attribute Key conforming to the\n\t// \"db.operation.batch.size\" semantic conventions. It represents the number of\n\t// queries included in a batch operation.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: 2, 3, 4\n\t// Note: Operations are only considered batches when they contain two or more\n\t// operations, and so `db.operation.batch.size` SHOULD never be `1`.\n\tDBOperationBatchSizeKey = attribute.Key(\"db.operation.batch.size\")\n\n\t// DBOperationNameKey is the attribute Key conforming to the \"db.operation.name\"\n\t// semantic conventions. It represents the name of the operation or command\n\t// being executed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"findAndModify\", \"HMSET\", \"SELECT\"\n\t// Note: It is RECOMMENDED to capture the value as provided by the application\n\t// without attempting to do any case normalization.\n\t//\n\t// The operation name SHOULD NOT be extracted from `db.query.text`,\n\t// when the database system supports query text with multiple operations\n\t// in non-batch operations.\n\t//\n\t// If spaces can occur in the operation name, multiple consecutive spaces\n\t// SHOULD be normalized to a single space.\n\t//\n\t// For batch operations, if the individual operations are known to have the same\n\t// operation name\n\t// then that operation name SHOULD be used prepended by `BATCH `,\n\t// otherwise `db.operation.name` SHOULD be `BATCH` or some other database\n\t// system specific term if more applicable.\n\tDBOperationNameKey = attribute.Key(\"db.operation.name\")\n\n\t// DBQuerySummaryKey is the attribute Key conforming to the \"db.query.summary\"\n\t// semantic conventions. It represents the low cardinality summary of a database\n\t// query.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"SELECT wuser_table\", \"INSERT shipping_details SELECT orders\", \"get\n\t// user by id\"\n\t// Note: The query summary describes a class of database queries and is useful\n\t// as a grouping key, especially when analyzing telemetry for database\n\t// calls involving complex queries.\n\t//\n\t// Summary may be available to the instrumentation through\n\t// instrumentation hooks or other means. If it is not available,\n\t// instrumentations\n\t// that support query parsing SHOULD generate a summary following\n\t// [Generating query summary]\n\t// section.\n\t//\n\t// [Generating query summary]: /docs/database/database-spans.md#generating-a-summary-of-the-query\n\tDBQuerySummaryKey = attribute.Key(\"db.query.summary\")\n\n\t// DBQueryTextKey is the attribute Key conforming to the \"db.query.text\"\n\t// semantic conventions. It represents the database query being executed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"SELECT * FROM wuser_table where username = ?\", \"SET mykey ?\"\n\t// Note: For sanitization see [Sanitization of `db.query.text`].\n\t// For batch operations, if the individual operations are known to have the same\n\t// query text then that query text SHOULD be used, otherwise all of the\n\t// individual query texts SHOULD be concatenated with separator `; ` or some\n\t// other database system specific separator if more applicable.\n\t// Parameterized query text SHOULD NOT be sanitized. Even though parameterized\n\t// query text can potentially have sensitive data, by using a parameterized\n\t// query the user is giving a strong signal that any sensitive data will be\n\t// passed as parameter values, and the benefit to observability of capturing the\n\t// static part of the query text by default outweighs the risk.\n\t//\n\t// [Sanitization of `db.query.text`]: /docs/database/database-spans.md#sanitization-of-dbquerytext\n\tDBQueryTextKey = attribute.Key(\"db.query.text\")\n\n\t// DBResponseReturnedRowsKey is the attribute Key conforming to the\n\t// \"db.response.returned_rows\" semantic conventions. It represents the number of\n\t// rows returned by the operation.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 10, 30, 1000\n\tDBResponseReturnedRowsKey = attribute.Key(\"db.response.returned_rows\")\n\n\t// DBResponseStatusCodeKey is the attribute Key conforming to the\n\t// \"db.response.status_code\" semantic conventions. It represents the database\n\t// response status code.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"102\", \"ORA-17002\", \"08P01\", \"404\"\n\t// Note: The status code returned by the database. Usually it represents an\n\t// error code, but may also represent partial success, warning, or differentiate\n\t// between various types of successful outcomes.\n\t// Semantic conventions for individual database systems SHOULD document what\n\t// `db.response.status_code` means in the context of that system.\n\tDBResponseStatusCodeKey = attribute.Key(\"db.response.status_code\")\n\n\t// DBStoredProcedureNameKey is the attribute Key conforming to the\n\t// \"db.stored_procedure.name\" semantic conventions. It represents the name of a\n\t// stored procedure within the database.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"GetCustomer\"\n\t// Note: It is RECOMMENDED to capture the value as provided by the application\n\t// without attempting to do any case normalization.\n\t//\n\t// For batch operations, if the individual operations are known to have the same\n\t// stored procedure name then that stored procedure name SHOULD be used.\n\tDBStoredProcedureNameKey = attribute.Key(\"db.stored_procedure.name\")\n\n\t// DBSystemNameKey is the attribute Key conforming to the \"db.system.name\"\n\t// semantic conventions. It represents the database management system (DBMS)\n\t// product as identified by the client instrumentation.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples:\n\t// Note: The actual DBMS may differ from the one identified by the client. For\n\t// example, when using PostgreSQL client libraries to connect to a CockroachDB,\n\t// the `db.system.name` is set to `postgresql` based on the instrumentation's\n\t// best knowledge.\n\tDBSystemNameKey = attribute.Key(\"db.system.name\")\n)\n\n// DBClientConnectionPoolName returns an attribute KeyValue conforming to the\n// \"db.client.connection.pool.name\" semantic conventions. It represents the name\n// of the connection pool; unique within the instrumented application. In case\n// the connection pool implementation doesn't provide a name, instrumentation\n// SHOULD use a combination of parameters that would make the name unique, for\n// example, combining attributes `server.address`, `server.port`, and\n// `db.namespace`, formatted as `server.address:server.port/db.namespace`.\n// Instrumentations that generate connection pool name following different\n// patterns SHOULD document it.\nfunc DBClientConnectionPoolName(val string) attribute.KeyValue {\n\treturn DBClientConnectionPoolNameKey.String(val)\n}\n\n// DBCollectionName returns an attribute KeyValue conforming to the\n// \"db.collection.name\" semantic conventions. It represents the name of a\n// collection (table, container) within the database.\nfunc DBCollectionName(val string) attribute.KeyValue {\n\treturn DBCollectionNameKey.String(val)\n}\n\n// DBNamespace returns an attribute KeyValue conforming to the \"db.namespace\"\n// semantic conventions. It represents the name of the database, fully qualified\n// within the server address and port.\nfunc DBNamespace(val string) attribute.KeyValue {\n\treturn DBNamespaceKey.String(val)\n}\n\n// DBOperationBatchSize returns an attribute KeyValue conforming to the\n// \"db.operation.batch.size\" semantic conventions. It represents the number of\n// queries included in a batch operation.\nfunc DBOperationBatchSize(val int) attribute.KeyValue {\n\treturn DBOperationBatchSizeKey.Int(val)\n}\n\n// DBOperationName returns an attribute KeyValue conforming to the\n// \"db.operation.name\" semantic conventions. It represents the name of the\n// operation or command being executed.\nfunc DBOperationName(val string) attribute.KeyValue {\n\treturn DBOperationNameKey.String(val)\n}\n\n// DBOperationParameter returns an attribute KeyValue conforming to the\n// \"db.operation.parameter\" semantic conventions. It represents a database\n// operation parameter, with `<key>` being the parameter name, and the attribute\n// value being a string representation of the parameter value.\nfunc DBOperationParameter(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"db.operation.parameter.\"+key, val)\n}\n\n// DBQueryParameter returns an attribute KeyValue conforming to the\n// \"db.query.parameter\" semantic conventions. It represents a database query\n// parameter, with `<key>` being the parameter name, and the attribute value\n// being a string representation of the parameter value.\nfunc DBQueryParameter(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"db.query.parameter.\"+key, val)\n}\n\n// DBQuerySummary returns an attribute KeyValue conforming to the\n// \"db.query.summary\" semantic conventions. It represents the low cardinality\n// summary of a database query.\nfunc DBQuerySummary(val string) attribute.KeyValue {\n\treturn DBQuerySummaryKey.String(val)\n}\n\n// DBQueryText returns an attribute KeyValue conforming to the \"db.query.text\"\n// semantic conventions. It represents the database query being executed.\nfunc DBQueryText(val string) attribute.KeyValue {\n\treturn DBQueryTextKey.String(val)\n}\n\n// DBResponseReturnedRows returns an attribute KeyValue conforming to the\n// \"db.response.returned_rows\" semantic conventions. It represents the number of\n// rows returned by the operation.\nfunc DBResponseReturnedRows(val int) attribute.KeyValue {\n\treturn DBResponseReturnedRowsKey.Int(val)\n}\n\n// DBResponseStatusCode returns an attribute KeyValue conforming to the\n// \"db.response.status_code\" semantic conventions. It represents the database\n// response status code.\nfunc DBResponseStatusCode(val string) attribute.KeyValue {\n\treturn DBResponseStatusCodeKey.String(val)\n}\n\n// DBStoredProcedureName returns an attribute KeyValue conforming to the\n// \"db.stored_procedure.name\" semantic conventions. It represents the name of a\n// stored procedure within the database.\nfunc DBStoredProcedureName(val string) attribute.KeyValue {\n\treturn DBStoredProcedureNameKey.String(val)\n}\n\n// Enum values for db.client.connection.state\nvar (\n\t// idle\n\t// Stability: development\n\tDBClientConnectionStateIdle = DBClientConnectionStateKey.String(\"idle\")\n\t// used\n\t// Stability: development\n\tDBClientConnectionStateUsed = DBClientConnectionStateKey.String(\"used\")\n)\n\n// Enum values for db.system.name\nvar (\n\t// Some other SQL database. Fallback only.\n\t// Stability: development\n\tDBSystemNameOtherSQL = DBSystemNameKey.String(\"other_sql\")\n\t// [Adabas (Adaptable Database System)]\n\t// Stability: development\n\t//\n\t// [Adabas (Adaptable Database System)]: https://documentation.softwareag.com/?pf=adabas\n\tDBSystemNameSoftwareagAdabas = DBSystemNameKey.String(\"softwareag.adabas\")\n\t// [Actian Ingres]\n\t// Stability: development\n\t//\n\t// [Actian Ingres]: https://www.actian.com/databases/ingres/\n\tDBSystemNameActianIngres = DBSystemNameKey.String(\"actian.ingres\")\n\t// [Amazon DynamoDB]\n\t// Stability: development\n\t//\n\t// [Amazon DynamoDB]: https://aws.amazon.com/pm/dynamodb/\n\tDBSystemNameAWSDynamoDB = DBSystemNameKey.String(\"aws.dynamodb\")\n\t// [Amazon Redshift]\n\t// Stability: development\n\t//\n\t// [Amazon Redshift]: https://aws.amazon.com/redshift/\n\tDBSystemNameAWSRedshift = DBSystemNameKey.String(\"aws.redshift\")\n\t// [Azure Cosmos DB]\n\t// Stability: development\n\t//\n\t// [Azure Cosmos DB]: https://learn.microsoft.com/azure/cosmos-db\n\tDBSystemNameAzureCosmosDB = DBSystemNameKey.String(\"azure.cosmosdb\")\n\t// [InterSystems Caché]\n\t// Stability: development\n\t//\n\t// [InterSystems Caché]: https://www.intersystems.com/products/cache/\n\tDBSystemNameIntersystemsCache = DBSystemNameKey.String(\"intersystems.cache\")\n\t// [Apache Cassandra]\n\t// Stability: development\n\t//\n\t// [Apache Cassandra]: https://cassandra.apache.org/\n\tDBSystemNameCassandra = DBSystemNameKey.String(\"cassandra\")\n\t// [ClickHouse]\n\t// Stability: development\n\t//\n\t// [ClickHouse]: https://clickhouse.com/\n\tDBSystemNameClickHouse = DBSystemNameKey.String(\"clickhouse\")\n\t// [CockroachDB]\n\t// Stability: development\n\t//\n\t// [CockroachDB]: https://www.cockroachlabs.com/\n\tDBSystemNameCockroachDB = DBSystemNameKey.String(\"cockroachdb\")\n\t// [Couchbase]\n\t// Stability: development\n\t//\n\t// [Couchbase]: https://www.couchbase.com/\n\tDBSystemNameCouchbase = DBSystemNameKey.String(\"couchbase\")\n\t// [Apache CouchDB]\n\t// Stability: development\n\t//\n\t// [Apache CouchDB]: https://couchdb.apache.org/\n\tDBSystemNameCouchDB = DBSystemNameKey.String(\"couchdb\")\n\t// [Apache Derby]\n\t// Stability: development\n\t//\n\t// [Apache Derby]: https://db.apache.org/derby/\n\tDBSystemNameDerby = DBSystemNameKey.String(\"derby\")\n\t// [Elasticsearch]\n\t// Stability: development\n\t//\n\t// [Elasticsearch]: https://www.elastic.co/elasticsearch\n\tDBSystemNameElasticsearch = DBSystemNameKey.String(\"elasticsearch\")\n\t// [Firebird]\n\t// Stability: development\n\t//\n\t// [Firebird]: https://www.firebirdsql.org/\n\tDBSystemNameFirebirdSQL = DBSystemNameKey.String(\"firebirdsql\")\n\t// [Google Cloud Spanner]\n\t// Stability: development\n\t//\n\t// [Google Cloud Spanner]: https://cloud.google.com/spanner\n\tDBSystemNameGCPSpanner = DBSystemNameKey.String(\"gcp.spanner\")\n\t// [Apache Geode]\n\t// Stability: development\n\t//\n\t// [Apache Geode]: https://geode.apache.org/\n\tDBSystemNameGeode = DBSystemNameKey.String(\"geode\")\n\t// [H2 Database]\n\t// Stability: development\n\t//\n\t// [H2 Database]: https://h2database.com/\n\tDBSystemNameH2database = DBSystemNameKey.String(\"h2database\")\n\t// [Apache HBase]\n\t// Stability: development\n\t//\n\t// [Apache HBase]: https://hbase.apache.org/\n\tDBSystemNameHBase = DBSystemNameKey.String(\"hbase\")\n\t// [Apache Hive]\n\t// Stability: development\n\t//\n\t// [Apache Hive]: https://hive.apache.org/\n\tDBSystemNameHive = DBSystemNameKey.String(\"hive\")\n\t// [HyperSQL Database]\n\t// Stability: development\n\t//\n\t// [HyperSQL Database]: https://hsqldb.org/\n\tDBSystemNameHSQLDB = DBSystemNameKey.String(\"hsqldb\")\n\t// [IBM Db2]\n\t// Stability: development\n\t//\n\t// [IBM Db2]: https://www.ibm.com/db2\n\tDBSystemNameIBMDB2 = DBSystemNameKey.String(\"ibm.db2\")\n\t// [IBM Informix]\n\t// Stability: development\n\t//\n\t// [IBM Informix]: https://www.ibm.com/products/informix\n\tDBSystemNameIBMInformix = DBSystemNameKey.String(\"ibm.informix\")\n\t// [IBM Netezza]\n\t// Stability: development\n\t//\n\t// [IBM Netezza]: https://www.ibm.com/products/netezza\n\tDBSystemNameIBMNetezza = DBSystemNameKey.String(\"ibm.netezza\")\n\t// [InfluxDB]\n\t// Stability: development\n\t//\n\t// [InfluxDB]: https://www.influxdata.com/\n\tDBSystemNameInfluxDB = DBSystemNameKey.String(\"influxdb\")\n\t// [Instant]\n\t// Stability: development\n\t//\n\t// [Instant]: https://www.instantdb.com/\n\tDBSystemNameInstantDB = DBSystemNameKey.String(\"instantdb\")\n\t// [MariaDB]\n\t// Stability: stable\n\t//\n\t// [MariaDB]: https://mariadb.org/\n\tDBSystemNameMariaDB = DBSystemNameKey.String(\"mariadb\")\n\t// [Memcached]\n\t// Stability: development\n\t//\n\t// [Memcached]: https://memcached.org/\n\tDBSystemNameMemcached = DBSystemNameKey.String(\"memcached\")\n\t// [MongoDB]\n\t// Stability: development\n\t//\n\t// [MongoDB]: https://www.mongodb.com/\n\tDBSystemNameMongoDB = DBSystemNameKey.String(\"mongodb\")\n\t// [Microsoft SQL Server]\n\t// Stability: stable\n\t//\n\t// [Microsoft SQL Server]: https://www.microsoft.com/sql-server\n\tDBSystemNameMicrosoftSQLServer = DBSystemNameKey.String(\"microsoft.sql_server\")\n\t// [MySQL]\n\t// Stability: stable\n\t//\n\t// [MySQL]: https://www.mysql.com/\n\tDBSystemNameMySQL = DBSystemNameKey.String(\"mysql\")\n\t// [Neo4j]\n\t// Stability: development\n\t//\n\t// [Neo4j]: https://neo4j.com/\n\tDBSystemNameNeo4j = DBSystemNameKey.String(\"neo4j\")\n\t// [OpenSearch]\n\t// Stability: development\n\t//\n\t// [OpenSearch]: https://opensearch.org/\n\tDBSystemNameOpenSearch = DBSystemNameKey.String(\"opensearch\")\n\t// [Oracle Database]\n\t// Stability: development\n\t//\n\t// [Oracle Database]: https://www.oracle.com/database/\n\tDBSystemNameOracleDB = DBSystemNameKey.String(\"oracle.db\")\n\t// [PostgreSQL]\n\t// Stability: stable\n\t//\n\t// [PostgreSQL]: https://www.postgresql.org/\n\tDBSystemNamePostgreSQL = DBSystemNameKey.String(\"postgresql\")\n\t// [Redis]\n\t// Stability: development\n\t//\n\t// [Redis]: https://redis.io/\n\tDBSystemNameRedis = DBSystemNameKey.String(\"redis\")\n\t// [SAP HANA]\n\t// Stability: development\n\t//\n\t// [SAP HANA]: https://www.sap.com/products/technology-platform/hana/what-is-sap-hana.html\n\tDBSystemNameSAPHANA = DBSystemNameKey.String(\"sap.hana\")\n\t// [SAP MaxDB]\n\t// Stability: development\n\t//\n\t// [SAP MaxDB]: https://maxdb.sap.com/\n\tDBSystemNameSAPMaxDB = DBSystemNameKey.String(\"sap.maxdb\")\n\t// [SQLite]\n\t// Stability: development\n\t//\n\t// [SQLite]: https://www.sqlite.org/\n\tDBSystemNameSQLite = DBSystemNameKey.String(\"sqlite\")\n\t// [Teradata]\n\t// Stability: development\n\t//\n\t// [Teradata]: https://www.teradata.com/\n\tDBSystemNameTeradata = DBSystemNameKey.String(\"teradata\")\n\t// [Trino]\n\t// Stability: development\n\t//\n\t// [Trino]: https://trino.io/\n\tDBSystemNameTrino = DBSystemNameKey.String(\"trino\")\n)\n\n// Namespace: deployment\nconst (\n\t// DeploymentEnvironmentNameKey is the attribute Key conforming to the\n\t// \"deployment.environment.name\" semantic conventions. It represents the name of\n\t// the [deployment environment] (aka deployment tier).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"staging\", \"production\"\n\t// Note: `deployment.environment.name` does not affect the uniqueness\n\t// constraints defined through\n\t// the `service.namespace`, `service.name` and `service.instance.id` resource\n\t// attributes.\n\t// This implies that resources carrying the following attribute combinations\n\t// MUST be\n\t// considered to be identifying the same service:\n\t//\n\t//   - `service.name=frontend`, `deployment.environment.name=production`\n\t//   - `service.name=frontend`, `deployment.environment.name=staging`.\n\t//\n\t//\n\t// [deployment environment]: https://wikipedia.org/wiki/Deployment_environment\n\tDeploymentEnvironmentNameKey = attribute.Key(\"deployment.environment.name\")\n\n\t// DeploymentIDKey is the attribute Key conforming to the \"deployment.id\"\n\t// semantic conventions. It represents the id of the deployment.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1208\"\n\tDeploymentIDKey = attribute.Key(\"deployment.id\")\n\n\t// DeploymentNameKey is the attribute Key conforming to the \"deployment.name\"\n\t// semantic conventions. It represents the name of the deployment.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"deploy my app\", \"deploy-frontend\"\n\tDeploymentNameKey = attribute.Key(\"deployment.name\")\n\n\t// DeploymentStatusKey is the attribute Key conforming to the\n\t// \"deployment.status\" semantic conventions. It represents the status of the\n\t// deployment.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tDeploymentStatusKey = attribute.Key(\"deployment.status\")\n)\n\n// DeploymentEnvironmentName returns an attribute KeyValue conforming to the\n// \"deployment.environment.name\" semantic conventions. It represents the name of\n// the [deployment environment] (aka deployment tier).\n//\n// [deployment environment]: https://wikipedia.org/wiki/Deployment_environment\nfunc DeploymentEnvironmentName(val string) attribute.KeyValue {\n\treturn DeploymentEnvironmentNameKey.String(val)\n}\n\n// DeploymentID returns an attribute KeyValue conforming to the \"deployment.id\"\n// semantic conventions. It represents the id of the deployment.\nfunc DeploymentID(val string) attribute.KeyValue {\n\treturn DeploymentIDKey.String(val)\n}\n\n// DeploymentName returns an attribute KeyValue conforming to the\n// \"deployment.name\" semantic conventions. It represents the name of the\n// deployment.\nfunc DeploymentName(val string) attribute.KeyValue {\n\treturn DeploymentNameKey.String(val)\n}\n\n// Enum values for deployment.status\nvar (\n\t// failed\n\t// Stability: development\n\tDeploymentStatusFailed = DeploymentStatusKey.String(\"failed\")\n\t// succeeded\n\t// Stability: development\n\tDeploymentStatusSucceeded = DeploymentStatusKey.String(\"succeeded\")\n)\n\n// Namespace: destination\nconst (\n\t// DestinationAddressKey is the attribute Key conforming to the\n\t// \"destination.address\" semantic conventions. It represents the destination\n\t// address - domain name if available without reverse DNS lookup; otherwise, IP\n\t// address or Unix domain socket name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"destination.example.com\", \"10.1.2.80\", \"/tmp/my.sock\"\n\t// Note: When observed from the source side, and when communicating through an\n\t// intermediary, `destination.address` SHOULD represent the destination address\n\t// behind any intermediaries, for example proxies, if it's available.\n\tDestinationAddressKey = attribute.Key(\"destination.address\")\n\n\t// DestinationPortKey is the attribute Key conforming to the \"destination.port\"\n\t// semantic conventions. It represents the destination port number.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 3389, 2888\n\tDestinationPortKey = attribute.Key(\"destination.port\")\n)\n\n// DestinationAddress returns an attribute KeyValue conforming to the\n// \"destination.address\" semantic conventions. It represents the destination\n// address - domain name if available without reverse DNS lookup; otherwise, IP\n// address or Unix domain socket name.\nfunc DestinationAddress(val string) attribute.KeyValue {\n\treturn DestinationAddressKey.String(val)\n}\n\n// DestinationPort returns an attribute KeyValue conforming to the\n// \"destination.port\" semantic conventions. It represents the destination port\n// number.\nfunc DestinationPort(val int) attribute.KeyValue {\n\treturn DestinationPortKey.Int(val)\n}\n\n// Namespace: device\nconst (\n\t// DeviceIDKey is the attribute Key conforming to the \"device.id\" semantic\n\t// conventions. It represents a unique identifier representing the device.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"123456789012345\", \"01:23:45:67:89:AB\"\n\t// Note: Its value SHOULD be identical for all apps on a device and it SHOULD\n\t// NOT change if an app is uninstalled and re-installed.\n\t// However, it might be resettable by the user for all apps on a device.\n\t// Hardware IDs (e.g. vendor-specific serial number, IMEI or MAC address) MAY be\n\t// used as values.\n\t//\n\t// More information about Android identifier best practices can be found in the\n\t// [Android user data IDs guide].\n\t//\n\t// > [!WARNING]> This attribute may contain sensitive (PII) information. Caution\n\t// > should be taken when storing personal data or anything which can identify a\n\t// > user. GDPR and data protection laws may apply,\n\t// > ensure you do your own due diligence.> Due to these reasons, this\n\t// > identifier is not recommended for consumer applications and will likely\n\t// > result in rejection from both Google Play and App Store.\n\t// > However, it may be appropriate for specific enterprise scenarios, such as\n\t// > kiosk devices or enterprise-managed devices, with appropriate compliance\n\t// > clearance.\n\t// > Any instrumentation providing this identifier MUST implement it as an\n\t// > opt-in feature.> See [`app.installation.id`]>  for a more\n\t// > privacy-preserving alternative.\n\t//\n\t// [Android user data IDs guide]: https://developer.android.com/training/articles/user-data-ids\n\t// [`app.installation.id`]: /docs/registry/attributes/app.md#app-installation-id\n\tDeviceIDKey = attribute.Key(\"device.id\")\n\n\t// DeviceManufacturerKey is the attribute Key conforming to the\n\t// \"device.manufacturer\" semantic conventions. It represents the name of the\n\t// device manufacturer.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Apple\", \"Samsung\"\n\t// Note: The Android OS provides this field via [Build]. iOS apps SHOULD\n\t// hardcode the value `Apple`.\n\t//\n\t// [Build]: https://developer.android.com/reference/android/os/Build#MANUFACTURER\n\tDeviceManufacturerKey = attribute.Key(\"device.manufacturer\")\n\n\t// DeviceModelIdentifierKey is the attribute Key conforming to the\n\t// \"device.model.identifier\" semantic conventions. It represents the model\n\t// identifier for the device.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"iPhone3,4\", \"SM-G920F\"\n\t// Note: It's recommended this value represents a machine-readable version of\n\t// the model identifier rather than the market or consumer-friendly name of the\n\t// device.\n\tDeviceModelIdentifierKey = attribute.Key(\"device.model.identifier\")\n\n\t// DeviceModelNameKey is the attribute Key conforming to the \"device.model.name\"\n\t// semantic conventions. It represents the marketing name for the device model.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"iPhone 6s Plus\", \"Samsung Galaxy S6\"\n\t// Note: It's recommended this value represents a human-readable version of the\n\t// device model rather than a machine-readable alternative.\n\tDeviceModelNameKey = attribute.Key(\"device.model.name\")\n)\n\n// DeviceID returns an attribute KeyValue conforming to the \"device.id\" semantic\n// conventions. It represents a unique identifier representing the device.\nfunc DeviceID(val string) attribute.KeyValue {\n\treturn DeviceIDKey.String(val)\n}\n\n// DeviceManufacturer returns an attribute KeyValue conforming to the\n// \"device.manufacturer\" semantic conventions. It represents the name of the\n// device manufacturer.\nfunc DeviceManufacturer(val string) attribute.KeyValue {\n\treturn DeviceManufacturerKey.String(val)\n}\n\n// DeviceModelIdentifier returns an attribute KeyValue conforming to the\n// \"device.model.identifier\" semantic conventions. It represents the model\n// identifier for the device.\nfunc DeviceModelIdentifier(val string) attribute.KeyValue {\n\treturn DeviceModelIdentifierKey.String(val)\n}\n\n// DeviceModelName returns an attribute KeyValue conforming to the\n// \"device.model.name\" semantic conventions. It represents the marketing name for\n// the device model.\nfunc DeviceModelName(val string) attribute.KeyValue {\n\treturn DeviceModelNameKey.String(val)\n}\n\n// Namespace: disk\nconst (\n\t// DiskIODirectionKey is the attribute Key conforming to the \"disk.io.direction\"\n\t// semantic conventions. It represents the disk IO operation direction.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"read\"\n\tDiskIODirectionKey = attribute.Key(\"disk.io.direction\")\n)\n\n// Enum values for disk.io.direction\nvar (\n\t// read\n\t// Stability: development\n\tDiskIODirectionRead = DiskIODirectionKey.String(\"read\")\n\t// write\n\t// Stability: development\n\tDiskIODirectionWrite = DiskIODirectionKey.String(\"write\")\n)\n\n// Namespace: dns\nconst (\n\t// DNSAnswersKey is the attribute Key conforming to the \"dns.answers\" semantic\n\t// conventions. It represents the list of IPv4 or IPv6 addresses resolved during\n\t// DNS lookup.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"10.0.0.1\", \"2001:0db8:85a3:0000:0000:8a2e:0370:7334\"\n\tDNSAnswersKey = attribute.Key(\"dns.answers\")\n\n\t// DNSQuestionNameKey is the attribute Key conforming to the \"dns.question.name\"\n\t// semantic conventions. It represents the name being queried.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"www.example.com\", \"opentelemetry.io\"\n\t// Note: If the name field contains non-printable characters (below 32 or above\n\t// 126), those characters should be represented as escaped base 10 integers\n\t// (\\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns,\n\t// and line feeds should be converted to \\t, \\r, and \\n respectively.\n\tDNSQuestionNameKey = attribute.Key(\"dns.question.name\")\n)\n\n// DNSAnswers returns an attribute KeyValue conforming to the \"dns.answers\"\n// semantic conventions. It represents the list of IPv4 or IPv6 addresses\n// resolved during DNS lookup.\nfunc DNSAnswers(val ...string) attribute.KeyValue {\n\treturn DNSAnswersKey.StringSlice(val)\n}\n\n// DNSQuestionName returns an attribute KeyValue conforming to the\n// \"dns.question.name\" semantic conventions. It represents the name being\n// queried.\nfunc DNSQuestionName(val string) attribute.KeyValue {\n\treturn DNSQuestionNameKey.String(val)\n}\n\n// Namespace: elasticsearch\nconst (\n\t// ElasticsearchNodeNameKey is the attribute Key conforming to the\n\t// \"elasticsearch.node.name\" semantic conventions. It represents the represents\n\t// the human-readable identifier of the node/instance to which a request was\n\t// routed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"instance-0000000001\"\n\tElasticsearchNodeNameKey = attribute.Key(\"elasticsearch.node.name\")\n)\n\n// ElasticsearchNodeName returns an attribute KeyValue conforming to the\n// \"elasticsearch.node.name\" semantic conventions. It represents the represents\n// the human-readable identifier of the node/instance to which a request was\n// routed.\nfunc ElasticsearchNodeName(val string) attribute.KeyValue {\n\treturn ElasticsearchNodeNameKey.String(val)\n}\n\n// Namespace: enduser\nconst (\n\t// EnduserIDKey is the attribute Key conforming to the \"enduser.id\" semantic\n\t// conventions. It represents the unique identifier of an end user in the\n\t// system. It maybe a username, email address, or other identifier.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"username\"\n\t// Note: Unique identifier of an end user in the system.\n\t//\n\t// > [!Warning]\n\t// > This field contains sensitive (PII) information.\n\tEnduserIDKey = attribute.Key(\"enduser.id\")\n\n\t// EnduserPseudoIDKey is the attribute Key conforming to the \"enduser.pseudo.id\"\n\t// semantic conventions. It represents the pseudonymous identifier of an end\n\t// user. This identifier should be a random value that is not directly linked or\n\t// associated with the end user's actual identity.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"QdH5CAWJgqVT4rOr0qtumf\"\n\t// Note: Pseudonymous identifier of an end user.\n\t//\n\t// > [!Warning]\n\t// > This field contains sensitive (linkable PII) information.\n\tEnduserPseudoIDKey = attribute.Key(\"enduser.pseudo.id\")\n)\n\n// EnduserID returns an attribute KeyValue conforming to the \"enduser.id\"\n// semantic conventions. It represents the unique identifier of an end user in\n// the system. It maybe a username, email address, or other identifier.\nfunc EnduserID(val string) attribute.KeyValue {\n\treturn EnduserIDKey.String(val)\n}\n\n// EnduserPseudoID returns an attribute KeyValue conforming to the\n// \"enduser.pseudo.id\" semantic conventions. It represents the pseudonymous\n// identifier of an end user. This identifier should be a random value that is\n// not directly linked or associated with the end user's actual identity.\nfunc EnduserPseudoID(val string) attribute.KeyValue {\n\treturn EnduserPseudoIDKey.String(val)\n}\n\n// Namespace: error\nconst (\n\t// ErrorMessageKey is the attribute Key conforming to the \"error.message\"\n\t// semantic conventions. It represents a message providing more detail about an\n\t// error in human-readable form.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Unexpected input type: string\", \"The user has exceeded their\n\t// storage quota\"\n\t// Note: `error.message` should provide additional context and detail about an\n\t// error.\n\t// It is NOT RECOMMENDED to duplicate the value of `error.type` in\n\t// `error.message`.\n\t// It is also NOT RECOMMENDED to duplicate the value of `exception.message` in\n\t// `error.message`.\n\t//\n\t// `error.message` is NOT RECOMMENDED for metrics or spans due to its unbounded\n\t// cardinality and overlap with span status.\n\tErrorMessageKey = attribute.Key(\"error.message\")\n\n\t// ErrorTypeKey is the attribute Key conforming to the \"error.type\" semantic\n\t// conventions. It represents the describes a class of error the operation ended\n\t// with.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"timeout\", \"java.net.UnknownHostException\",\n\t// \"server_certificate_invalid\", \"500\"\n\t// Note: The `error.type` SHOULD be predictable, and SHOULD have low\n\t// cardinality.\n\t//\n\t// When `error.type` is set to a type (e.g., an exception type), its\n\t// canonical class name identifying the type within the artifact SHOULD be used.\n\t//\n\t// Instrumentations SHOULD document the list of errors they report.\n\t//\n\t// The cardinality of `error.type` within one instrumentation library SHOULD be\n\t// low.\n\t// Telemetry consumers that aggregate data from multiple instrumentation\n\t// libraries and applications\n\t// should be prepared for `error.type` to have high cardinality at query time\n\t// when no\n\t// additional filters are applied.\n\t//\n\t// If the operation has completed successfully, instrumentations SHOULD NOT set\n\t// `error.type`.\n\t//\n\t// If a specific domain defines its own set of error identifiers (such as HTTP\n\t// or gRPC status codes),\n\t// it's RECOMMENDED to:\n\t//\n\t//   - Use a domain-specific attribute\n\t//   - Set `error.type` to capture all errors, regardless of whether they are\n\t//     defined within the domain-specific set or not.\n\tErrorTypeKey = attribute.Key(\"error.type\")\n)\n\n// ErrorMessage returns an attribute KeyValue conforming to the \"error.message\"\n// semantic conventions. It represents a message providing more detail about an\n// error in human-readable form.\nfunc ErrorMessage(val string) attribute.KeyValue {\n\treturn ErrorMessageKey.String(val)\n}\n\n// Enum values for error.type\nvar (\n\t// A fallback error value to be used when the instrumentation doesn't define a\n\t// custom value.\n\t//\n\t// Stability: stable\n\tErrorTypeOther = ErrorTypeKey.String(\"_OTHER\")\n)\n\n// Namespace: exception\nconst (\n\t// ExceptionMessageKey is the attribute Key conforming to the\n\t// \"exception.message\" semantic conventions. It represents the exception\n\t// message.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"Division by zero\", \"Can't convert 'int' object to str implicitly\"\n\tExceptionMessageKey = attribute.Key(\"exception.message\")\n\n\t// ExceptionStacktraceKey is the attribute Key conforming to the\n\t// \"exception.stacktrace\" semantic conventions. It represents a stacktrace as a\n\t// string in the natural representation for the language runtime. The\n\t// representation is to be determined and documented by each language SIG.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: Exception in thread \"main\" java.lang.RuntimeException: Test\n\t// exception\\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\\n at\n\t// com.example.GenerateTrace.methodA(GenerateTrace.java:9)\\n at\n\t// com.example.GenerateTrace.main(GenerateTrace.java:5)\n\tExceptionStacktraceKey = attribute.Key(\"exception.stacktrace\")\n\n\t// ExceptionTypeKey is the attribute Key conforming to the \"exception.type\"\n\t// semantic conventions. It represents the type of the exception (its\n\t// fully-qualified class name, if applicable). The dynamic type of the exception\n\t// should be preferred over the static type in languages that support it.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"java.net.ConnectException\", \"OSError\"\n\tExceptionTypeKey = attribute.Key(\"exception.type\")\n)\n\n// ExceptionMessage returns an attribute KeyValue conforming to the\n// \"exception.message\" semantic conventions. It represents the exception message.\nfunc ExceptionMessage(val string) attribute.KeyValue {\n\treturn ExceptionMessageKey.String(val)\n}\n\n// ExceptionStacktrace returns an attribute KeyValue conforming to the\n// \"exception.stacktrace\" semantic conventions. It represents a stacktrace as a\n// string in the natural representation for the language runtime. The\n// representation is to be determined and documented by each language SIG.\nfunc ExceptionStacktrace(val string) attribute.KeyValue {\n\treturn ExceptionStacktraceKey.String(val)\n}\n\n// ExceptionType returns an attribute KeyValue conforming to the \"exception.type\"\n// semantic conventions. It represents the type of the exception (its\n// fully-qualified class name, if applicable). The dynamic type of the exception\n// should be preferred over the static type in languages that support it.\nfunc ExceptionType(val string) attribute.KeyValue {\n\treturn ExceptionTypeKey.String(val)\n}\n\n// Namespace: faas\nconst (\n\t// FaaSColdstartKey is the attribute Key conforming to the \"faas.coldstart\"\n\t// semantic conventions. It represents a boolean that is true if the serverless\n\t// function is executed for the first time (aka cold-start).\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tFaaSColdstartKey = attribute.Key(\"faas.coldstart\")\n\n\t// FaaSCronKey is the attribute Key conforming to the \"faas.cron\" semantic\n\t// conventions. It represents a string containing the schedule period as\n\t// [Cron Expression].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0/5 * * * ? *\n\t//\n\t// [Cron Expression]: https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm\n\tFaaSCronKey = attribute.Key(\"faas.cron\")\n\n\t// FaaSDocumentCollectionKey is the attribute Key conforming to the\n\t// \"faas.document.collection\" semantic conventions. It represents the name of\n\t// the source on which the triggering operation was performed. For example, in\n\t// Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the\n\t// database name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"myBucketName\", \"myDbName\"\n\tFaaSDocumentCollectionKey = attribute.Key(\"faas.document.collection\")\n\n\t// FaaSDocumentNameKey is the attribute Key conforming to the\n\t// \"faas.document.name\" semantic conventions. It represents the document\n\t// name/table subjected to the operation. For example, in Cloud Storage or S3 is\n\t// the name of the file, and in Cosmos DB the table name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"myFile.txt\", \"myTableName\"\n\tFaaSDocumentNameKey = attribute.Key(\"faas.document.name\")\n\n\t// FaaSDocumentOperationKey is the attribute Key conforming to the\n\t// \"faas.document.operation\" semantic conventions. It represents the describes\n\t// the type of the operation that was performed on the data.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tFaaSDocumentOperationKey = attribute.Key(\"faas.document.operation\")\n\n\t// FaaSDocumentTimeKey is the attribute Key conforming to the\n\t// \"faas.document.time\" semantic conventions. It represents a string containing\n\t// the time when the data was accessed in the [ISO 8601] format expressed in\n\t// [UTC].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 2020-01-23T13:47:06Z\n\t//\n\t// [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html\n\t// [UTC]: https://www.w3.org/TR/NOTE-datetime\n\tFaaSDocumentTimeKey = attribute.Key(\"faas.document.time\")\n\n\t// FaaSInstanceKey is the attribute Key conforming to the \"faas.instance\"\n\t// semantic conventions. It represents the execution environment ID as a string,\n\t// that will be potentially reused for other invocations to the same\n\t// function/function version.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de\"\n\t// Note: - **AWS Lambda:** Use the (full) log stream name.\n\tFaaSInstanceKey = attribute.Key(\"faas.instance\")\n\n\t// FaaSInvocationIDKey is the attribute Key conforming to the\n\t// \"faas.invocation_id\" semantic conventions. It represents the invocation ID of\n\t// the current function invocation.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: af9d5aa4-a685-4c5f-a22b-444f80b3cc28\n\tFaaSInvocationIDKey = attribute.Key(\"faas.invocation_id\")\n\n\t// FaaSInvokedNameKey is the attribute Key conforming to the \"faas.invoked_name\"\n\t// semantic conventions. It represents the name of the invoked function.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: my-function\n\t// Note: SHOULD be equal to the `faas.name` resource attribute of the invoked\n\t// function.\n\tFaaSInvokedNameKey = attribute.Key(\"faas.invoked_name\")\n\n\t// FaaSInvokedProviderKey is the attribute Key conforming to the\n\t// \"faas.invoked_provider\" semantic conventions. It represents the cloud\n\t// provider of the invoked function.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: SHOULD be equal to the `cloud.provider` resource attribute of the\n\t// invoked function.\n\tFaaSInvokedProviderKey = attribute.Key(\"faas.invoked_provider\")\n\n\t// FaaSInvokedRegionKey is the attribute Key conforming to the\n\t// \"faas.invoked_region\" semantic conventions. It represents the cloud region of\n\t// the invoked function.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: eu-central-1\n\t// Note: SHOULD be equal to the `cloud.region` resource attribute of the invoked\n\t// function.\n\tFaaSInvokedRegionKey = attribute.Key(\"faas.invoked_region\")\n\n\t// FaaSMaxMemoryKey is the attribute Key conforming to the \"faas.max_memory\"\n\t// semantic conventions. It represents the amount of memory available to the\n\t// serverless function converted to Bytes.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Note: It's recommended to set this attribute since e.g. too little memory can\n\t// easily stop a Java AWS Lambda function from working correctly. On AWS Lambda,\n\t// the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this\n\t// information (which must be multiplied by 1,048,576).\n\tFaaSMaxMemoryKey = attribute.Key(\"faas.max_memory\")\n\n\t// FaaSNameKey is the attribute Key conforming to the \"faas.name\" semantic\n\t// conventions. It represents the name of the single function that this runtime\n\t// instance executes.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-function\", \"myazurefunctionapp/some-function-name\"\n\t// Note: This is the name of the function as configured/deployed on the FaaS\n\t// platform and is usually different from the name of the callback\n\t// function (which may be stored in the\n\t// [`code.namespace`/`code.function.name`]\n\t// span attributes).\n\t//\n\t// For some cloud providers, the above definition is ambiguous. The following\n\t// definition of function name MUST be used for this attribute\n\t// (and consequently the span name) for the listed cloud providers/products:\n\t//\n\t//   - **Azure:** The full name `<FUNCAPP>/<FUNC>`, i.e., function app name\n\t//     followed by a forward slash followed by the function name (this form\n\t//     can also be seen in the resource JSON for the function).\n\t//     This means that a span attribute MUST be used, as an Azure function\n\t//     app can host multiple functions that would usually share\n\t//     a TracerProvider (see also the `cloud.resource_id` attribute).\n\t//\n\t//\n\t// [`code.namespace`/`code.function.name`]: /docs/general/attributes.md#source-code-attributes\n\tFaaSNameKey = attribute.Key(\"faas.name\")\n\n\t// FaaSTimeKey is the attribute Key conforming to the \"faas.time\" semantic\n\t// conventions. It represents a string containing the function invocation time\n\t// in the [ISO 8601] format expressed in [UTC].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 2020-01-23T13:47:06Z\n\t//\n\t// [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html\n\t// [UTC]: https://www.w3.org/TR/NOTE-datetime\n\tFaaSTimeKey = attribute.Key(\"faas.time\")\n\n\t// FaaSTriggerKey is the attribute Key conforming to the \"faas.trigger\" semantic\n\t// conventions. It represents the type of the trigger which caused this function\n\t// invocation.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tFaaSTriggerKey = attribute.Key(\"faas.trigger\")\n\n\t// FaaSVersionKey is the attribute Key conforming to the \"faas.version\" semantic\n\t// conventions. It represents the immutable version of the function being\n\t// executed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"26\", \"pinkfroid-00002\"\n\t// Note: Depending on the cloud provider and platform, use:\n\t//\n\t//   - **AWS Lambda:** The [function version]\n\t//     (an integer represented as a decimal string).\n\t//   - **Google Cloud Run (Services):** The [revision]\n\t//     (i.e., the function name plus the revision suffix).\n\t//   - **Google Cloud Functions:** The value of the\n\t//     [`K_REVISION` environment variable].\n\t//   - **Azure Functions:** Not applicable. Do not set this attribute.\n\t//\n\t//\n\t// [function version]: https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html\n\t// [revision]: https://cloud.google.com/run/docs/managing/revisions\n\t// [`K_REVISION` environment variable]: https://cloud.google.com/functions/docs/env-var#runtime_environment_variables_set_automatically\n\tFaaSVersionKey = attribute.Key(\"faas.version\")\n)\n\n// FaaSColdstart returns an attribute KeyValue conforming to the \"faas.coldstart\"\n// semantic conventions. It represents a boolean that is true if the serverless\n// function is executed for the first time (aka cold-start).\nfunc FaaSColdstart(val bool) attribute.KeyValue {\n\treturn FaaSColdstartKey.Bool(val)\n}\n\n// FaaSCron returns an attribute KeyValue conforming to the \"faas.cron\" semantic\n// conventions. It represents a string containing the schedule period as\n// [Cron Expression].\n//\n// [Cron Expression]: https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm\nfunc FaaSCron(val string) attribute.KeyValue {\n\treturn FaaSCronKey.String(val)\n}\n\n// FaaSDocumentCollection returns an attribute KeyValue conforming to the\n// \"faas.document.collection\" semantic conventions. It represents the name of the\n// source on which the triggering operation was performed. For example, in Cloud\n// Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database\n// name.\nfunc FaaSDocumentCollection(val string) attribute.KeyValue {\n\treturn FaaSDocumentCollectionKey.String(val)\n}\n\n// FaaSDocumentName returns an attribute KeyValue conforming to the\n// \"faas.document.name\" semantic conventions. It represents the document\n// name/table subjected to the operation. For example, in Cloud Storage or S3 is\n// the name of the file, and in Cosmos DB the table name.\nfunc FaaSDocumentName(val string) attribute.KeyValue {\n\treturn FaaSDocumentNameKey.String(val)\n}\n\n// FaaSDocumentTime returns an attribute KeyValue conforming to the\n// \"faas.document.time\" semantic conventions. It represents a string containing\n// the time when the data was accessed in the [ISO 8601] format expressed in\n// [UTC].\n//\n// [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html\n// [UTC]: https://www.w3.org/TR/NOTE-datetime\nfunc FaaSDocumentTime(val string) attribute.KeyValue {\n\treturn FaaSDocumentTimeKey.String(val)\n}\n\n// FaaSInstance returns an attribute KeyValue conforming to the \"faas.instance\"\n// semantic conventions. It represents the execution environment ID as a string,\n// that will be potentially reused for other invocations to the same\n// function/function version.\nfunc FaaSInstance(val string) attribute.KeyValue {\n\treturn FaaSInstanceKey.String(val)\n}\n\n// FaaSInvocationID returns an attribute KeyValue conforming to the\n// \"faas.invocation_id\" semantic conventions. It represents the invocation ID of\n// the current function invocation.\nfunc FaaSInvocationID(val string) attribute.KeyValue {\n\treturn FaaSInvocationIDKey.String(val)\n}\n\n// FaaSInvokedName returns an attribute KeyValue conforming to the\n// \"faas.invoked_name\" semantic conventions. It represents the name of the\n// invoked function.\nfunc FaaSInvokedName(val string) attribute.KeyValue {\n\treturn FaaSInvokedNameKey.String(val)\n}\n\n// FaaSInvokedRegion returns an attribute KeyValue conforming to the\n// \"faas.invoked_region\" semantic conventions. It represents the cloud region of\n// the invoked function.\nfunc FaaSInvokedRegion(val string) attribute.KeyValue {\n\treturn FaaSInvokedRegionKey.String(val)\n}\n\n// FaaSMaxMemory returns an attribute KeyValue conforming to the\n// \"faas.max_memory\" semantic conventions. It represents the amount of memory\n// available to the serverless function converted to Bytes.\nfunc FaaSMaxMemory(val int) attribute.KeyValue {\n\treturn FaaSMaxMemoryKey.Int(val)\n}\n\n// FaaSName returns an attribute KeyValue conforming to the \"faas.name\" semantic\n// conventions. It represents the name of the single function that this runtime\n// instance executes.\nfunc FaaSName(val string) attribute.KeyValue {\n\treturn FaaSNameKey.String(val)\n}\n\n// FaaSTime returns an attribute KeyValue conforming to the \"faas.time\" semantic\n// conventions. It represents a string containing the function invocation time in\n// the [ISO 8601] format expressed in [UTC].\n//\n// [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html\n// [UTC]: https://www.w3.org/TR/NOTE-datetime\nfunc FaaSTime(val string) attribute.KeyValue {\n\treturn FaaSTimeKey.String(val)\n}\n\n// FaaSVersion returns an attribute KeyValue conforming to the \"faas.version\"\n// semantic conventions. It represents the immutable version of the function\n// being executed.\nfunc FaaSVersion(val string) attribute.KeyValue {\n\treturn FaaSVersionKey.String(val)\n}\n\n// Enum values for faas.document.operation\nvar (\n\t// When a new object is created.\n\t// Stability: development\n\tFaaSDocumentOperationInsert = FaaSDocumentOperationKey.String(\"insert\")\n\t// When an object is modified.\n\t// Stability: development\n\tFaaSDocumentOperationEdit = FaaSDocumentOperationKey.String(\"edit\")\n\t// When an object is deleted.\n\t// Stability: development\n\tFaaSDocumentOperationDelete = FaaSDocumentOperationKey.String(\"delete\")\n)\n\n// Enum values for faas.invoked_provider\nvar (\n\t// Alibaba Cloud\n\t// Stability: development\n\tFaaSInvokedProviderAlibabaCloud = FaaSInvokedProviderKey.String(\"alibaba_cloud\")\n\t// Amazon Web Services\n\t// Stability: development\n\tFaaSInvokedProviderAWS = FaaSInvokedProviderKey.String(\"aws\")\n\t// Microsoft Azure\n\t// Stability: development\n\tFaaSInvokedProviderAzure = FaaSInvokedProviderKey.String(\"azure\")\n\t// Google Cloud Platform\n\t// Stability: development\n\tFaaSInvokedProviderGCP = FaaSInvokedProviderKey.String(\"gcp\")\n\t// Tencent Cloud\n\t// Stability: development\n\tFaaSInvokedProviderTencentCloud = FaaSInvokedProviderKey.String(\"tencent_cloud\")\n)\n\n// Enum values for faas.trigger\nvar (\n\t// A response to some data source operation such as a database or filesystem\n\t// read/write\n\t// Stability: development\n\tFaaSTriggerDatasource = FaaSTriggerKey.String(\"datasource\")\n\t// To provide an answer to an inbound HTTP request\n\t// Stability: development\n\tFaaSTriggerHTTP = FaaSTriggerKey.String(\"http\")\n\t// A function is set to be executed when messages are sent to a messaging system\n\t// Stability: development\n\tFaaSTriggerPubSub = FaaSTriggerKey.String(\"pubsub\")\n\t// A function is scheduled to be executed regularly\n\t// Stability: development\n\tFaaSTriggerTimer = FaaSTriggerKey.String(\"timer\")\n\t// If none of the others apply\n\t// Stability: development\n\tFaaSTriggerOther = FaaSTriggerKey.String(\"other\")\n)\n\n// Namespace: feature_flag\nconst (\n\t// FeatureFlagContextIDKey is the attribute Key conforming to the\n\t// \"feature_flag.context.id\" semantic conventions. It represents the unique\n\t// identifier for the flag evaluation context. For example, the targeting key.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Release_Candidate\n\t//\n\t// Examples: \"5157782b-2203-4c80-a857-dbbd5e7761db\"\n\tFeatureFlagContextIDKey = attribute.Key(\"feature_flag.context.id\")\n\n\t// FeatureFlagKeyKey is the attribute Key conforming to the \"feature_flag.key\"\n\t// semantic conventions. It represents the lookup key of the feature flag.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Release_Candidate\n\t//\n\t// Examples: \"logo-color\"\n\tFeatureFlagKeyKey = attribute.Key(\"feature_flag.key\")\n\n\t// FeatureFlagProviderNameKey is the attribute Key conforming to the\n\t// \"feature_flag.provider.name\" semantic conventions. It represents the\n\t// identifies the feature flag provider.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Release_Candidate\n\t//\n\t// Examples: \"Flag Manager\"\n\tFeatureFlagProviderNameKey = attribute.Key(\"feature_flag.provider.name\")\n\n\t// FeatureFlagResultReasonKey is the attribute Key conforming to the\n\t// \"feature_flag.result.reason\" semantic conventions. It represents the reason\n\t// code which shows how a feature flag value was determined.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Release_Candidate\n\t//\n\t// Examples: \"static\", \"targeting_match\", \"error\", \"default\"\n\tFeatureFlagResultReasonKey = attribute.Key(\"feature_flag.result.reason\")\n\n\t// FeatureFlagResultValueKey is the attribute Key conforming to the\n\t// \"feature_flag.result.value\" semantic conventions. It represents the evaluated\n\t// value of the feature flag.\n\t//\n\t// Type: any\n\t// RequirementLevel: Recommended\n\t// Stability: Release_Candidate\n\t//\n\t// Examples: \"#ff0000\", true, 3\n\t// Note: With some feature flag providers, feature flag results can be quite\n\t// large or contain private or sensitive details.\n\t// Because of this, `feature_flag.result.variant` is often the preferred\n\t// attribute if it is available.\n\t//\n\t// It may be desirable to redact or otherwise limit the size and scope of\n\t// `feature_flag.result.value` if possible.\n\t// Because the evaluated flag value is unstructured and may be any type, it is\n\t// left to the instrumentation author to determine how best to achieve this.\n\tFeatureFlagResultValueKey = attribute.Key(\"feature_flag.result.value\")\n\n\t// FeatureFlagResultVariantKey is the attribute Key conforming to the\n\t// \"feature_flag.result.variant\" semantic conventions. It represents a semantic\n\t// identifier for an evaluated flag value.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Release_Candidate\n\t//\n\t// Examples: \"red\", \"true\", \"on\"\n\t// Note: A semantic identifier, commonly referred to as a variant, provides a\n\t// means\n\t// for referring to a value without including the value itself. This can\n\t// provide additional context for understanding the meaning behind a value.\n\t// For example, the variant `red` maybe be used for the value `#c05543`.\n\tFeatureFlagResultVariantKey = attribute.Key(\"feature_flag.result.variant\")\n\n\t// FeatureFlagSetIDKey is the attribute Key conforming to the\n\t// \"feature_flag.set.id\" semantic conventions. It represents the identifier of\n\t// the [flag set] to which the feature flag belongs.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Release_Candidate\n\t//\n\t// Examples: \"proj-1\", \"ab98sgs\", \"service1/dev\"\n\t//\n\t// [flag set]: https://openfeature.dev/specification/glossary/#flag-set\n\tFeatureFlagSetIDKey = attribute.Key(\"feature_flag.set.id\")\n\n\t// FeatureFlagVersionKey is the attribute Key conforming to the\n\t// \"feature_flag.version\" semantic conventions. It represents the version of the\n\t// ruleset used during the evaluation. This may be any stable value which\n\t// uniquely identifies the ruleset.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Release_Candidate\n\t//\n\t// Examples: \"1\", \"01ABCDEF\"\n\tFeatureFlagVersionKey = attribute.Key(\"feature_flag.version\")\n)\n\n// FeatureFlagContextID returns an attribute KeyValue conforming to the\n// \"feature_flag.context.id\" semantic conventions. It represents the unique\n// identifier for the flag evaluation context. For example, the targeting key.\nfunc FeatureFlagContextID(val string) attribute.KeyValue {\n\treturn FeatureFlagContextIDKey.String(val)\n}\n\n// FeatureFlagKey returns an attribute KeyValue conforming to the\n// \"feature_flag.key\" semantic conventions. It represents the lookup key of the\n// feature flag.\nfunc FeatureFlagKey(val string) attribute.KeyValue {\n\treturn FeatureFlagKeyKey.String(val)\n}\n\n// FeatureFlagProviderName returns an attribute KeyValue conforming to the\n// \"feature_flag.provider.name\" semantic conventions. It represents the\n// identifies the feature flag provider.\nfunc FeatureFlagProviderName(val string) attribute.KeyValue {\n\treturn FeatureFlagProviderNameKey.String(val)\n}\n\n// FeatureFlagResultVariant returns an attribute KeyValue conforming to the\n// \"feature_flag.result.variant\" semantic conventions. It represents a semantic\n// identifier for an evaluated flag value.\nfunc FeatureFlagResultVariant(val string) attribute.KeyValue {\n\treturn FeatureFlagResultVariantKey.String(val)\n}\n\n// FeatureFlagSetID returns an attribute KeyValue conforming to the\n// \"feature_flag.set.id\" semantic conventions. It represents the identifier of\n// the [flag set] to which the feature flag belongs.\n//\n// [flag set]: https://openfeature.dev/specification/glossary/#flag-set\nfunc FeatureFlagSetID(val string) attribute.KeyValue {\n\treturn FeatureFlagSetIDKey.String(val)\n}\n\n// FeatureFlagVersion returns an attribute KeyValue conforming to the\n// \"feature_flag.version\" semantic conventions. It represents the version of the\n// ruleset used during the evaluation. This may be any stable value which\n// uniquely identifies the ruleset.\nfunc FeatureFlagVersion(val string) attribute.KeyValue {\n\treturn FeatureFlagVersionKey.String(val)\n}\n\n// Enum values for feature_flag.result.reason\nvar (\n\t// The resolved value is static (no dynamic evaluation).\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonStatic = FeatureFlagResultReasonKey.String(\"static\")\n\t// The resolved value fell back to a pre-configured value (no dynamic evaluation\n\t// occurred or dynamic evaluation yielded no result).\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonDefault = FeatureFlagResultReasonKey.String(\"default\")\n\t// The resolved value was the result of a dynamic evaluation, such as a rule or\n\t// specific user-targeting.\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonTargetingMatch = FeatureFlagResultReasonKey.String(\"targeting_match\")\n\t// The resolved value was the result of pseudorandom assignment.\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonSplit = FeatureFlagResultReasonKey.String(\"split\")\n\t// The resolved value was retrieved from cache.\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonCached = FeatureFlagResultReasonKey.String(\"cached\")\n\t// The resolved value was the result of the flag being disabled in the\n\t// management system.\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonDisabled = FeatureFlagResultReasonKey.String(\"disabled\")\n\t// The reason for the resolved value could not be determined.\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonUnknown = FeatureFlagResultReasonKey.String(\"unknown\")\n\t// The resolved value is non-authoritative or possibly out of date\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonStale = FeatureFlagResultReasonKey.String(\"stale\")\n\t// The resolved value was the result of an error.\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonError = FeatureFlagResultReasonKey.String(\"error\")\n)\n\n// Namespace: file\nconst (\n\t// FileAccessedKey is the attribute Key conforming to the \"file.accessed\"\n\t// semantic conventions. It represents the time when the file was last accessed,\n\t// in ISO 8601 format.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2021-01-01T12:00:00Z\"\n\t// Note: This attribute might not be supported by some file systems — NFS,\n\t// FAT32, in embedded OS, etc.\n\tFileAccessedKey = attribute.Key(\"file.accessed\")\n\n\t// FileAttributesKey is the attribute Key conforming to the \"file.attributes\"\n\t// semantic conventions. It represents the array of file attributes.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"readonly\", \"hidden\"\n\t// Note: Attributes names depend on the OS or file system. Here’s a\n\t// non-exhaustive list of values expected for this attribute: `archive`,\n\t// `compressed`, `directory`, `encrypted`, `execute`, `hidden`, `immutable`,\n\t// `journaled`, `read`, `readonly`, `symbolic link`, `system`, `temporary`,\n\t// `write`.\n\tFileAttributesKey = attribute.Key(\"file.attributes\")\n\n\t// FileChangedKey is the attribute Key conforming to the \"file.changed\" semantic\n\t// conventions. It represents the time when the file attributes or metadata was\n\t// last changed, in ISO 8601 format.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2021-01-01T12:00:00Z\"\n\t// Note: `file.changed` captures the time when any of the file's properties or\n\t// attributes (including the content) are changed, while `file.modified`\n\t// captures the timestamp when the file content is modified.\n\tFileChangedKey = attribute.Key(\"file.changed\")\n\n\t// FileCreatedKey is the attribute Key conforming to the \"file.created\" semantic\n\t// conventions. It represents the time when the file was created, in ISO 8601\n\t// format.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2021-01-01T12:00:00Z\"\n\t// Note: This attribute might not be supported by some file systems — NFS,\n\t// FAT32, in embedded OS, etc.\n\tFileCreatedKey = attribute.Key(\"file.created\")\n\n\t// FileDirectoryKey is the attribute Key conforming to the \"file.directory\"\n\t// semantic conventions. It represents the directory where the file is located.\n\t// It should include the drive letter, when appropriate.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/home/user\", \"C:\\Program Files\\MyApp\"\n\tFileDirectoryKey = attribute.Key(\"file.directory\")\n\n\t// FileExtensionKey is the attribute Key conforming to the \"file.extension\"\n\t// semantic conventions. It represents the file extension, excluding the leading\n\t// dot.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"png\", \"gz\"\n\t// Note: When the file name has multiple extensions (example.tar.gz), only the\n\t// last one should be captured (\"gz\", not \"tar.gz\").\n\tFileExtensionKey = attribute.Key(\"file.extension\")\n\n\t// FileForkNameKey is the attribute Key conforming to the \"file.fork_name\"\n\t// semantic conventions. It represents the name of the fork. A fork is\n\t// additional data associated with a filesystem object.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Zone.Identifier\"\n\t// Note: On Linux, a resource fork is used to store additional data with a\n\t// filesystem object. A file always has at least one fork for the data portion,\n\t// and additional forks may exist.\n\t// On NTFS, this is analogous to an Alternate Data Stream (ADS), and the default\n\t// data stream for a file is just called $DATA. Zone.Identifier is commonly used\n\t// by Windows to track contents downloaded from the Internet. An ADS is\n\t// typically of the form: C:\\path\\to\\filename.extension:some_fork_name, and\n\t// some_fork_name is the value that should populate `fork_name`.\n\t// `filename.extension` should populate `file.name`, and `extension` should\n\t// populate `file.extension`. The full path, `file.path`, will include the fork\n\t// name.\n\tFileForkNameKey = attribute.Key(\"file.fork_name\")\n\n\t// FileGroupIDKey is the attribute Key conforming to the \"file.group.id\"\n\t// semantic conventions. It represents the primary Group ID (GID) of the file.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1000\"\n\tFileGroupIDKey = attribute.Key(\"file.group.id\")\n\n\t// FileGroupNameKey is the attribute Key conforming to the \"file.group.name\"\n\t// semantic conventions. It represents the primary group name of the file.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"users\"\n\tFileGroupNameKey = attribute.Key(\"file.group.name\")\n\n\t// FileInodeKey is the attribute Key conforming to the \"file.inode\" semantic\n\t// conventions. It represents the inode representing the file in the filesystem.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"256383\"\n\tFileInodeKey = attribute.Key(\"file.inode\")\n\n\t// FileModeKey is the attribute Key conforming to the \"file.mode\" semantic\n\t// conventions. It represents the mode of the file in octal representation.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"0640\"\n\tFileModeKey = attribute.Key(\"file.mode\")\n\n\t// FileModifiedKey is the attribute Key conforming to the \"file.modified\"\n\t// semantic conventions. It represents the time when the file content was last\n\t// modified, in ISO 8601 format.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2021-01-01T12:00:00Z\"\n\tFileModifiedKey = attribute.Key(\"file.modified\")\n\n\t// FileNameKey is the attribute Key conforming to the \"file.name\" semantic\n\t// conventions. It represents the name of the file including the extension,\n\t// without the directory.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"example.png\"\n\tFileNameKey = attribute.Key(\"file.name\")\n\n\t// FileOwnerIDKey is the attribute Key conforming to the \"file.owner.id\"\n\t// semantic conventions. It represents the user ID (UID) or security identifier\n\t// (SID) of the file owner.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1000\"\n\tFileOwnerIDKey = attribute.Key(\"file.owner.id\")\n\n\t// FileOwnerNameKey is the attribute Key conforming to the \"file.owner.name\"\n\t// semantic conventions. It represents the username of the file owner.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"root\"\n\tFileOwnerNameKey = attribute.Key(\"file.owner.name\")\n\n\t// FilePathKey is the attribute Key conforming to the \"file.path\" semantic\n\t// conventions. It represents the full path to the file, including the file\n\t// name. It should include the drive letter, when appropriate.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/home/alice/example.png\", \"C:\\Program Files\\MyApp\\myapp.exe\"\n\tFilePathKey = attribute.Key(\"file.path\")\n\n\t// FileSizeKey is the attribute Key conforming to the \"file.size\" semantic\n\t// conventions. It represents the file size in bytes.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tFileSizeKey = attribute.Key(\"file.size\")\n\n\t// FileSymbolicLinkTargetPathKey is the attribute Key conforming to the\n\t// \"file.symbolic_link.target_path\" semantic conventions. It represents the path\n\t// to the target of a symbolic link.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/usr/bin/python3\"\n\t// Note: This attribute is only applicable to symbolic links.\n\tFileSymbolicLinkTargetPathKey = attribute.Key(\"file.symbolic_link.target_path\")\n)\n\n// FileAccessed returns an attribute KeyValue conforming to the \"file.accessed\"\n// semantic conventions. It represents the time when the file was last accessed,\n// in ISO 8601 format.\nfunc FileAccessed(val string) attribute.KeyValue {\n\treturn FileAccessedKey.String(val)\n}\n\n// FileAttributes returns an attribute KeyValue conforming to the\n// \"file.attributes\" semantic conventions. It represents the array of file\n// attributes.\nfunc FileAttributes(val ...string) attribute.KeyValue {\n\treturn FileAttributesKey.StringSlice(val)\n}\n\n// FileChanged returns an attribute KeyValue conforming to the \"file.changed\"\n// semantic conventions. It represents the time when the file attributes or\n// metadata was last changed, in ISO 8601 format.\nfunc FileChanged(val string) attribute.KeyValue {\n\treturn FileChangedKey.String(val)\n}\n\n// FileCreated returns an attribute KeyValue conforming to the \"file.created\"\n// semantic conventions. It represents the time when the file was created, in ISO\n// 8601 format.\nfunc FileCreated(val string) attribute.KeyValue {\n\treturn FileCreatedKey.String(val)\n}\n\n// FileDirectory returns an attribute KeyValue conforming to the \"file.directory\"\n// semantic conventions. It represents the directory where the file is located.\n// It should include the drive letter, when appropriate.\nfunc FileDirectory(val string) attribute.KeyValue {\n\treturn FileDirectoryKey.String(val)\n}\n\n// FileExtension returns an attribute KeyValue conforming to the \"file.extension\"\n// semantic conventions. It represents the file extension, excluding the leading\n// dot.\nfunc FileExtension(val string) attribute.KeyValue {\n\treturn FileExtensionKey.String(val)\n}\n\n// FileForkName returns an attribute KeyValue conforming to the \"file.fork_name\"\n// semantic conventions. It represents the name of the fork. A fork is additional\n// data associated with a filesystem object.\nfunc FileForkName(val string) attribute.KeyValue {\n\treturn FileForkNameKey.String(val)\n}\n\n// FileGroupID returns an attribute KeyValue conforming to the \"file.group.id\"\n// semantic conventions. It represents the primary Group ID (GID) of the file.\nfunc FileGroupID(val string) attribute.KeyValue {\n\treturn FileGroupIDKey.String(val)\n}\n\n// FileGroupName returns an attribute KeyValue conforming to the\n// \"file.group.name\" semantic conventions. It represents the primary group name\n// of the file.\nfunc FileGroupName(val string) attribute.KeyValue {\n\treturn FileGroupNameKey.String(val)\n}\n\n// FileInode returns an attribute KeyValue conforming to the \"file.inode\"\n// semantic conventions. It represents the inode representing the file in the\n// filesystem.\nfunc FileInode(val string) attribute.KeyValue {\n\treturn FileInodeKey.String(val)\n}\n\n// FileMode returns an attribute KeyValue conforming to the \"file.mode\" semantic\n// conventions. It represents the mode of the file in octal representation.\nfunc FileMode(val string) attribute.KeyValue {\n\treturn FileModeKey.String(val)\n}\n\n// FileModified returns an attribute KeyValue conforming to the \"file.modified\"\n// semantic conventions. It represents the time when the file content was last\n// modified, in ISO 8601 format.\nfunc FileModified(val string) attribute.KeyValue {\n\treturn FileModifiedKey.String(val)\n}\n\n// FileName returns an attribute KeyValue conforming to the \"file.name\" semantic\n// conventions. It represents the name of the file including the extension,\n// without the directory.\nfunc FileName(val string) attribute.KeyValue {\n\treturn FileNameKey.String(val)\n}\n\n// FileOwnerID returns an attribute KeyValue conforming to the \"file.owner.id\"\n// semantic conventions. It represents the user ID (UID) or security identifier\n// (SID) of the file owner.\nfunc FileOwnerID(val string) attribute.KeyValue {\n\treturn FileOwnerIDKey.String(val)\n}\n\n// FileOwnerName returns an attribute KeyValue conforming to the\n// \"file.owner.name\" semantic conventions. It represents the username of the file\n// owner.\nfunc FileOwnerName(val string) attribute.KeyValue {\n\treturn FileOwnerNameKey.String(val)\n}\n\n// FilePath returns an attribute KeyValue conforming to the \"file.path\" semantic\n// conventions. It represents the full path to the file, including the file name.\n// It should include the drive letter, when appropriate.\nfunc FilePath(val string) attribute.KeyValue {\n\treturn FilePathKey.String(val)\n}\n\n// FileSize returns an attribute KeyValue conforming to the \"file.size\" semantic\n// conventions. It represents the file size in bytes.\nfunc FileSize(val int) attribute.KeyValue {\n\treturn FileSizeKey.Int(val)\n}\n\n// FileSymbolicLinkTargetPath returns an attribute KeyValue conforming to the\n// \"file.symbolic_link.target_path\" semantic conventions. It represents the path\n// to the target of a symbolic link.\nfunc FileSymbolicLinkTargetPath(val string) attribute.KeyValue {\n\treturn FileSymbolicLinkTargetPathKey.String(val)\n}\n\n// Namespace: gcp\nconst (\n\t// GCPAppHubApplicationContainerKey is the attribute Key conforming to the\n\t// \"gcp.apphub.application.container\" semantic conventions. It represents the\n\t// container within GCP where the AppHub application is defined.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"projects/my-container-project\"\n\tGCPAppHubApplicationContainerKey = attribute.Key(\"gcp.apphub.application.container\")\n\n\t// GCPAppHubApplicationIDKey is the attribute Key conforming to the\n\t// \"gcp.apphub.application.id\" semantic conventions. It represents the name of\n\t// the application as configured in AppHub.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-application\"\n\tGCPAppHubApplicationIDKey = attribute.Key(\"gcp.apphub.application.id\")\n\n\t// GCPAppHubApplicationLocationKey is the attribute Key conforming to the\n\t// \"gcp.apphub.application.location\" semantic conventions. It represents the GCP\n\t// zone or region where the application is defined.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"us-central1\"\n\tGCPAppHubApplicationLocationKey = attribute.Key(\"gcp.apphub.application.location\")\n\n\t// GCPAppHubServiceCriticalityTypeKey is the attribute Key conforming to the\n\t// \"gcp.apphub.service.criticality_type\" semantic conventions. It represents the\n\t// criticality of a service indicates its importance to the business.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: [See AppHub type enum]\n\t//\n\t// [See AppHub type enum]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type\n\tGCPAppHubServiceCriticalityTypeKey = attribute.Key(\"gcp.apphub.service.criticality_type\")\n\n\t// GCPAppHubServiceEnvironmentTypeKey is the attribute Key conforming to the\n\t// \"gcp.apphub.service.environment_type\" semantic conventions. It represents the\n\t// environment of a service is the stage of a software lifecycle.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: [See AppHub environment type]\n\t//\n\t// [See AppHub environment type]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1\n\tGCPAppHubServiceEnvironmentTypeKey = attribute.Key(\"gcp.apphub.service.environment_type\")\n\n\t// GCPAppHubServiceIDKey is the attribute Key conforming to the\n\t// \"gcp.apphub.service.id\" semantic conventions. It represents the name of the\n\t// service as configured in AppHub.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-service\"\n\tGCPAppHubServiceIDKey = attribute.Key(\"gcp.apphub.service.id\")\n\n\t// GCPAppHubWorkloadCriticalityTypeKey is the attribute Key conforming to the\n\t// \"gcp.apphub.workload.criticality_type\" semantic conventions. It represents\n\t// the criticality of a workload indicates its importance to the business.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: [See AppHub type enum]\n\t//\n\t// [See AppHub type enum]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type\n\tGCPAppHubWorkloadCriticalityTypeKey = attribute.Key(\"gcp.apphub.workload.criticality_type\")\n\n\t// GCPAppHubWorkloadEnvironmentTypeKey is the attribute Key conforming to the\n\t// \"gcp.apphub.workload.environment_type\" semantic conventions. It represents\n\t// the environment of a workload is the stage of a software lifecycle.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: [See AppHub environment type]\n\t//\n\t// [See AppHub environment type]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1\n\tGCPAppHubWorkloadEnvironmentTypeKey = attribute.Key(\"gcp.apphub.workload.environment_type\")\n\n\t// GCPAppHubWorkloadIDKey is the attribute Key conforming to the\n\t// \"gcp.apphub.workload.id\" semantic conventions. It represents the name of the\n\t// workload as configured in AppHub.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-workload\"\n\tGCPAppHubWorkloadIDKey = attribute.Key(\"gcp.apphub.workload.id\")\n\n\t// GCPClientServiceKey is the attribute Key conforming to the\n\t// \"gcp.client.service\" semantic conventions. It represents the identifies the\n\t// Google Cloud service for which the official client library is intended.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"appengine\", \"run\", \"firestore\", \"alloydb\", \"spanner\"\n\t// Note: Intended to be a stable identifier for Google Cloud client libraries\n\t// that is uniform across implementation languages. The value should be derived\n\t// from the canonical service domain for the service; for example,\n\t// 'foo.googleapis.com' should result in a value of 'foo'.\n\tGCPClientServiceKey = attribute.Key(\"gcp.client.service\")\n\n\t// GCPCloudRunJobExecutionKey is the attribute Key conforming to the\n\t// \"gcp.cloud_run.job.execution\" semantic conventions. It represents the name of\n\t// the Cloud Run [execution] being run for the Job, as set by the\n\t// [`CLOUD_RUN_EXECUTION`] environment variable.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"job-name-xxxx\", \"sample-job-mdw84\"\n\t//\n\t// [execution]: https://cloud.google.com/run/docs/managing/job-executions\n\t// [`CLOUD_RUN_EXECUTION`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars\n\tGCPCloudRunJobExecutionKey = attribute.Key(\"gcp.cloud_run.job.execution\")\n\n\t// GCPCloudRunJobTaskIndexKey is the attribute Key conforming to the\n\t// \"gcp.cloud_run.job.task_index\" semantic conventions. It represents the index\n\t// for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`]\n\t// environment variable.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0, 1\n\t//\n\t// [`CLOUD_RUN_TASK_INDEX`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars\n\tGCPCloudRunJobTaskIndexKey = attribute.Key(\"gcp.cloud_run.job.task_index\")\n\n\t// GCPGCEInstanceHostnameKey is the attribute Key conforming to the\n\t// \"gcp.gce.instance.hostname\" semantic conventions. It represents the hostname\n\t// of a GCE instance. This is the full value of the default or [custom hostname]\n\t// .\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-host1234.example.com\",\n\t// \"sample-vm.us-west1-b.c.my-project.internal\"\n\t//\n\t// [custom hostname]: https://cloud.google.com/compute/docs/instances/custom-hostname-vm\n\tGCPGCEInstanceHostnameKey = attribute.Key(\"gcp.gce.instance.hostname\")\n\n\t// GCPGCEInstanceNameKey is the attribute Key conforming to the\n\t// \"gcp.gce.instance.name\" semantic conventions. It represents the instance name\n\t// of a GCE instance. This is the value provided by `host.name`, the visible\n\t// name of the instance in the Cloud Console UI, and the prefix for the default\n\t// hostname of the instance as defined by the [default internal DNS name].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"instance-1\", \"my-vm-name\"\n\t//\n\t// [default internal DNS name]: https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names\n\tGCPGCEInstanceNameKey = attribute.Key(\"gcp.gce.instance.name\")\n)\n\n// GCPAppHubApplicationContainer returns an attribute KeyValue conforming to the\n// \"gcp.apphub.application.container\" semantic conventions. It represents the\n// container within GCP where the AppHub application is defined.\nfunc GCPAppHubApplicationContainer(val string) attribute.KeyValue {\n\treturn GCPAppHubApplicationContainerKey.String(val)\n}\n\n// GCPAppHubApplicationID returns an attribute KeyValue conforming to the\n// \"gcp.apphub.application.id\" semantic conventions. It represents the name of\n// the application as configured in AppHub.\nfunc GCPAppHubApplicationID(val string) attribute.KeyValue {\n\treturn GCPAppHubApplicationIDKey.String(val)\n}\n\n// GCPAppHubApplicationLocation returns an attribute KeyValue conforming to the\n// \"gcp.apphub.application.location\" semantic conventions. It represents the GCP\n// zone or region where the application is defined.\nfunc GCPAppHubApplicationLocation(val string) attribute.KeyValue {\n\treturn GCPAppHubApplicationLocationKey.String(val)\n}\n\n// GCPAppHubServiceID returns an attribute KeyValue conforming to the\n// \"gcp.apphub.service.id\" semantic conventions. It represents the name of the\n// service as configured in AppHub.\nfunc GCPAppHubServiceID(val string) attribute.KeyValue {\n\treturn GCPAppHubServiceIDKey.String(val)\n}\n\n// GCPAppHubWorkloadID returns an attribute KeyValue conforming to the\n// \"gcp.apphub.workload.id\" semantic conventions. It represents the name of the\n// workload as configured in AppHub.\nfunc GCPAppHubWorkloadID(val string) attribute.KeyValue {\n\treturn GCPAppHubWorkloadIDKey.String(val)\n}\n\n// GCPClientService returns an attribute KeyValue conforming to the\n// \"gcp.client.service\" semantic conventions. It represents the identifies the\n// Google Cloud service for which the official client library is intended.\nfunc GCPClientService(val string) attribute.KeyValue {\n\treturn GCPClientServiceKey.String(val)\n}\n\n// GCPCloudRunJobExecution returns an attribute KeyValue conforming to the\n// \"gcp.cloud_run.job.execution\" semantic conventions. It represents the name of\n// the Cloud Run [execution] being run for the Job, as set by the\n// [`CLOUD_RUN_EXECUTION`] environment variable.\n//\n// [execution]: https://cloud.google.com/run/docs/managing/job-executions\n// [`CLOUD_RUN_EXECUTION`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars\nfunc GCPCloudRunJobExecution(val string) attribute.KeyValue {\n\treturn GCPCloudRunJobExecutionKey.String(val)\n}\n\n// GCPCloudRunJobTaskIndex returns an attribute KeyValue conforming to the\n// \"gcp.cloud_run.job.task_index\" semantic conventions. It represents the index\n// for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`]\n// environment variable.\n//\n// [`CLOUD_RUN_TASK_INDEX`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars\nfunc GCPCloudRunJobTaskIndex(val int) attribute.KeyValue {\n\treturn GCPCloudRunJobTaskIndexKey.Int(val)\n}\n\n// GCPGCEInstanceHostname returns an attribute KeyValue conforming to the\n// \"gcp.gce.instance.hostname\" semantic conventions. It represents the hostname\n// of a GCE instance. This is the full value of the default or [custom hostname]\n// .\n//\n// [custom hostname]: https://cloud.google.com/compute/docs/instances/custom-hostname-vm\nfunc GCPGCEInstanceHostname(val string) attribute.KeyValue {\n\treturn GCPGCEInstanceHostnameKey.String(val)\n}\n\n// GCPGCEInstanceName returns an attribute KeyValue conforming to the\n// \"gcp.gce.instance.name\" semantic conventions. It represents the instance name\n// of a GCE instance. This is the value provided by `host.name`, the visible name\n// of the instance in the Cloud Console UI, and the prefix for the default\n// hostname of the instance as defined by the [default internal DNS name].\n//\n// [default internal DNS name]: https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names\nfunc GCPGCEInstanceName(val string) attribute.KeyValue {\n\treturn GCPGCEInstanceNameKey.String(val)\n}\n\n// Enum values for gcp.apphub.service.criticality_type\nvar (\n\t// Mission critical service.\n\t// Stability: development\n\tGCPAppHubServiceCriticalityTypeMissionCritical = GCPAppHubServiceCriticalityTypeKey.String(\"MISSION_CRITICAL\")\n\t// High impact.\n\t// Stability: development\n\tGCPAppHubServiceCriticalityTypeHigh = GCPAppHubServiceCriticalityTypeKey.String(\"HIGH\")\n\t// Medium impact.\n\t// Stability: development\n\tGCPAppHubServiceCriticalityTypeMedium = GCPAppHubServiceCriticalityTypeKey.String(\"MEDIUM\")\n\t// Low impact.\n\t// Stability: development\n\tGCPAppHubServiceCriticalityTypeLow = GCPAppHubServiceCriticalityTypeKey.String(\"LOW\")\n)\n\n// Enum values for gcp.apphub.service.environment_type\nvar (\n\t// Production environment.\n\t// Stability: development\n\tGCPAppHubServiceEnvironmentTypeProduction = GCPAppHubServiceEnvironmentTypeKey.String(\"PRODUCTION\")\n\t// Staging environment.\n\t// Stability: development\n\tGCPAppHubServiceEnvironmentTypeStaging = GCPAppHubServiceEnvironmentTypeKey.String(\"STAGING\")\n\t// Test environment.\n\t// Stability: development\n\tGCPAppHubServiceEnvironmentTypeTest = GCPAppHubServiceEnvironmentTypeKey.String(\"TEST\")\n\t// Development environment.\n\t// Stability: development\n\tGCPAppHubServiceEnvironmentTypeDevelopment = GCPAppHubServiceEnvironmentTypeKey.String(\"DEVELOPMENT\")\n)\n\n// Enum values for gcp.apphub.workload.criticality_type\nvar (\n\t// Mission critical service.\n\t// Stability: development\n\tGCPAppHubWorkloadCriticalityTypeMissionCritical = GCPAppHubWorkloadCriticalityTypeKey.String(\"MISSION_CRITICAL\")\n\t// High impact.\n\t// Stability: development\n\tGCPAppHubWorkloadCriticalityTypeHigh = GCPAppHubWorkloadCriticalityTypeKey.String(\"HIGH\")\n\t// Medium impact.\n\t// Stability: development\n\tGCPAppHubWorkloadCriticalityTypeMedium = GCPAppHubWorkloadCriticalityTypeKey.String(\"MEDIUM\")\n\t// Low impact.\n\t// Stability: development\n\tGCPAppHubWorkloadCriticalityTypeLow = GCPAppHubWorkloadCriticalityTypeKey.String(\"LOW\")\n)\n\n// Enum values for gcp.apphub.workload.environment_type\nvar (\n\t// Production environment.\n\t// Stability: development\n\tGCPAppHubWorkloadEnvironmentTypeProduction = GCPAppHubWorkloadEnvironmentTypeKey.String(\"PRODUCTION\")\n\t// Staging environment.\n\t// Stability: development\n\tGCPAppHubWorkloadEnvironmentTypeStaging = GCPAppHubWorkloadEnvironmentTypeKey.String(\"STAGING\")\n\t// Test environment.\n\t// Stability: development\n\tGCPAppHubWorkloadEnvironmentTypeTest = GCPAppHubWorkloadEnvironmentTypeKey.String(\"TEST\")\n\t// Development environment.\n\t// Stability: development\n\tGCPAppHubWorkloadEnvironmentTypeDevelopment = GCPAppHubWorkloadEnvironmentTypeKey.String(\"DEVELOPMENT\")\n)\n\n// Namespace: gen_ai\nconst (\n\t// GenAIAgentDescriptionKey is the attribute Key conforming to the\n\t// \"gen_ai.agent.description\" semantic conventions. It represents the free-form\n\t// description of the GenAI agent provided by the application.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Helps with math problems\", \"Generates fiction stories\"\n\tGenAIAgentDescriptionKey = attribute.Key(\"gen_ai.agent.description\")\n\n\t// GenAIAgentIDKey is the attribute Key conforming to the \"gen_ai.agent.id\"\n\t// semantic conventions. It represents the unique identifier of the GenAI agent.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"asst_5j66UpCpwteGg4YSxUnt7lPY\"\n\tGenAIAgentIDKey = attribute.Key(\"gen_ai.agent.id\")\n\n\t// GenAIAgentNameKey is the attribute Key conforming to the \"gen_ai.agent.name\"\n\t// semantic conventions. It represents the human-readable name of the GenAI\n\t// agent provided by the application.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Math Tutor\", \"Fiction Writer\"\n\tGenAIAgentNameKey = attribute.Key(\"gen_ai.agent.name\")\n\n\t// GenAIConversationIDKey is the attribute Key conforming to the\n\t// \"gen_ai.conversation.id\" semantic conventions. It represents the unique\n\t// identifier for a conversation (session, thread), used to store and correlate\n\t// messages within this conversation.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"conv_5j66UpCpwteGg4YSxUnt7lPY\"\n\tGenAIConversationIDKey = attribute.Key(\"gen_ai.conversation.id\")\n\n\t// GenAIDataSourceIDKey is the attribute Key conforming to the\n\t// \"gen_ai.data_source.id\" semantic conventions. It represents the data source\n\t// identifier.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"H7STPQYOND\"\n\t// Note: Data sources are used by AI agents and RAG applications to store\n\t// grounding data. A data source may be an external database, object store,\n\t// document collection, website, or any other storage system used by the GenAI\n\t// agent or application. The `gen_ai.data_source.id` SHOULD match the identifier\n\t// used by the GenAI system rather than a name specific to the external storage,\n\t// such as a database or object store. Semantic conventions referencing\n\t// `gen_ai.data_source.id` MAY also leverage additional attributes, such as\n\t// `db.*`, to further identify and describe the data source.\n\tGenAIDataSourceIDKey = attribute.Key(\"gen_ai.data_source.id\")\n\n\t// GenAIInputMessagesKey is the attribute Key conforming to the\n\t// \"gen_ai.input.messages\" semantic conventions. It represents the chat history\n\t// provided to the model as an input.\n\t//\n\t// Type: any\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"[\\n {\\n \"role\": \"user\",\\n \"parts\": [\\n {\\n \"type\": \"text\",\\n\n\t// \"content\": \"Weather in Paris?\"\\n }\\n ]\\n },\\n {\\n \"role\": \"assistant\",\\n\n\t// \"parts\": [\\n {\\n \"type\": \"tool_call\",\\n \"id\":\n\t// \"call_VSPygqKTWdrhaFErNvMV18Yl\",\\n \"name\": \"get_weather\",\\n \"arguments\": {\\n\n\t// \"location\": \"Paris\"\\n }\\n }\\n ]\\n },\\n {\\n \"role\": \"tool\",\\n \"parts\": [\\n {\\n\n\t// \"type\": \"tool_call_response\",\\n \"id\": \" call_VSPygqKTWdrhaFErNvMV18Yl\",\\n\n\t// \"result\": \"rainy, 57°F\"\\n }\\n ]\\n }\\n]\\n\"\n\t// Note: Instrumentations MUST follow [Input messages JSON schema].\n\t// When the attribute is recorded on events, it MUST be recorded in structured\n\t// form. When recorded on spans, it MAY be recorded as a JSON string if\n\t// structured\n\t// format is not supported and SHOULD be recorded in structured form otherwise.\n\t//\n\t// Messages MUST be provided in the order they were sent to the model.\n\t// Instrumentations MAY provide a way for users to filter or truncate\n\t// input messages.\n\t//\n\t// > [!Warning]\n\t// > This attribute is likely to contain sensitive information including\n\t// > user/PII data.\n\t//\n\t// See [Recording content on attributes]\n\t// section for more details.\n\t//\n\t// [Input messages JSON schema]: /docs/gen-ai/gen-ai-input-messages.json\n\t// [Recording content on attributes]: /docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes\n\tGenAIInputMessagesKey = attribute.Key(\"gen_ai.input.messages\")\n\n\t// GenAIOperationNameKey is the attribute Key conforming to the\n\t// \"gen_ai.operation.name\" semantic conventions. It represents the name of the\n\t// operation being performed.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: If one of the predefined values applies, but specific system uses a\n\t// different name it's RECOMMENDED to document it in the semantic conventions\n\t// for specific GenAI system and use system-specific name in the\n\t// instrumentation. If a different name is not documented, instrumentation\n\t// libraries SHOULD use applicable predefined value.\n\tGenAIOperationNameKey = attribute.Key(\"gen_ai.operation.name\")\n\n\t// GenAIOutputMessagesKey is the attribute Key conforming to the\n\t// \"gen_ai.output.messages\" semantic conventions. It represents the messages\n\t// returned by the model where each message represents a specific model response\n\t// (choice, candidate).\n\t//\n\t// Type: any\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"[\\n {\\n \"role\": \"assistant\",\\n \"parts\": [\\n {\\n \"type\": \"text\",\\n\n\t// \"content\": \"The weather in Paris is currently rainy with a temperature of\n\t// 57°F.\"\\n }\\n ],\\n \"finish_reason\": \"stop\"\\n }\\n]\\n\"\n\t// Note: Instrumentations MUST follow [Output messages JSON schema]\n\t//\n\t// Each message represents a single output choice/candidate generated by\n\t// the model. Each message corresponds to exactly one generation\n\t// (choice/candidate) and vice versa - one choice cannot be split across\n\t// multiple messages or one message cannot contain parts from multiple choices.\n\t//\n\t// When the attribute is recorded on events, it MUST be recorded in structured\n\t// form. When recorded on spans, it MAY be recorded as a JSON string if\n\t// structured\n\t// format is not supported and SHOULD be recorded in structured form otherwise.\n\t//\n\t// Instrumentations MAY provide a way for users to filter or truncate\n\t// output messages.\n\t//\n\t// > [!Warning]\n\t// > This attribute is likely to contain sensitive information including\n\t// > user/PII data.\n\t//\n\t// See [Recording content on attributes]\n\t// section for more details.\n\t//\n\t// [Output messages JSON schema]: /docs/gen-ai/gen-ai-output-messages.json\n\t// [Recording content on attributes]: /docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes\n\tGenAIOutputMessagesKey = attribute.Key(\"gen_ai.output.messages\")\n\n\t// GenAIOutputTypeKey is the attribute Key conforming to the\n\t// \"gen_ai.output.type\" semantic conventions. It represents the represents the\n\t// content type requested by the client.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: This attribute SHOULD be used when the client requests output of a\n\t// specific type. The model may return zero or more outputs of this type.\n\t// This attribute specifies the output modality and not the actual output\n\t// format. For example, if an image is requested, the actual output could be a\n\t// URL pointing to an image file.\n\t// Additional output format details may be recorded in the future in the\n\t// `gen_ai.output.{type}.*` attributes.\n\tGenAIOutputTypeKey = attribute.Key(\"gen_ai.output.type\")\n\n\t// GenAIProviderNameKey is the attribute Key conforming to the\n\t// \"gen_ai.provider.name\" semantic conventions. It represents the Generative AI\n\t// provider as identified by the client or server instrumentation.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: The attribute SHOULD be set based on the instrumentation's best\n\t// knowledge and may differ from the actual model provider.\n\t//\n\t// Multiple providers, including Azure OpenAI, Gemini, and AI hosting platforms\n\t// are accessible using the OpenAI REST API and corresponding client libraries,\n\t// but may proxy or host models from different providers.\n\t//\n\t// The `gen_ai.request.model`, `gen_ai.response.model`, and `server.address`\n\t// attributes may help identify the actual system in use.\n\t//\n\t// The `gen_ai.provider.name` attribute acts as a discriminator that\n\t// identifies the GenAI telemetry format flavor specific to that provider\n\t// within GenAI semantic conventions.\n\t// It SHOULD be set consistently with provider-specific attributes and signals.\n\t// For example, GenAI spans, metrics, and events related to AWS Bedrock\n\t// should have the `gen_ai.provider.name` set to `aws.bedrock` and include\n\t// applicable `aws.bedrock.*` attributes and are not expected to include\n\t// `openai.*` attributes.\n\tGenAIProviderNameKey = attribute.Key(\"gen_ai.provider.name\")\n\n\t// GenAIRequestChoiceCountKey is the attribute Key conforming to the\n\t// \"gen_ai.request.choice.count\" semantic conventions. It represents the target\n\t// number of candidate completions to return.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 3\n\tGenAIRequestChoiceCountKey = attribute.Key(\"gen_ai.request.choice.count\")\n\n\t// GenAIRequestEncodingFormatsKey is the attribute Key conforming to the\n\t// \"gen_ai.request.encoding_formats\" semantic conventions. It represents the\n\t// encoding formats requested in an embeddings operation, if specified.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"base64\"], [\"float\", \"binary\"\n\t// Note: In some GenAI systems the encoding formats are called embedding types.\n\t// Also, some GenAI systems only accept a single format per request.\n\tGenAIRequestEncodingFormatsKey = attribute.Key(\"gen_ai.request.encoding_formats\")\n\n\t// GenAIRequestFrequencyPenaltyKey is the attribute Key conforming to the\n\t// \"gen_ai.request.frequency_penalty\" semantic conventions. It represents the\n\t// frequency penalty setting for the GenAI request.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0.1\n\tGenAIRequestFrequencyPenaltyKey = attribute.Key(\"gen_ai.request.frequency_penalty\")\n\n\t// GenAIRequestMaxTokensKey is the attribute Key conforming to the\n\t// \"gen_ai.request.max_tokens\" semantic conventions. It represents the maximum\n\t// number of tokens the model generates for a request.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 100\n\tGenAIRequestMaxTokensKey = attribute.Key(\"gen_ai.request.max_tokens\")\n\n\t// GenAIRequestModelKey is the attribute Key conforming to the\n\t// \"gen_ai.request.model\" semantic conventions. It represents the name of the\n\t// GenAI model a request is being made to.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: gpt-4\n\tGenAIRequestModelKey = attribute.Key(\"gen_ai.request.model\")\n\n\t// GenAIRequestPresencePenaltyKey is the attribute Key conforming to the\n\t// \"gen_ai.request.presence_penalty\" semantic conventions. It represents the\n\t// presence penalty setting for the GenAI request.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0.1\n\tGenAIRequestPresencePenaltyKey = attribute.Key(\"gen_ai.request.presence_penalty\")\n\n\t// GenAIRequestSeedKey is the attribute Key conforming to the\n\t// \"gen_ai.request.seed\" semantic conventions. It represents the requests with\n\t// same seed value more likely to return same result.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 100\n\tGenAIRequestSeedKey = attribute.Key(\"gen_ai.request.seed\")\n\n\t// GenAIRequestStopSequencesKey is the attribute Key conforming to the\n\t// \"gen_ai.request.stop_sequences\" semantic conventions. It represents the list\n\t// of sequences that the model will use to stop generating further tokens.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"forest\", \"lived\"\n\tGenAIRequestStopSequencesKey = attribute.Key(\"gen_ai.request.stop_sequences\")\n\n\t// GenAIRequestTemperatureKey is the attribute Key conforming to the\n\t// \"gen_ai.request.temperature\" semantic conventions. It represents the\n\t// temperature setting for the GenAI request.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0.0\n\tGenAIRequestTemperatureKey = attribute.Key(\"gen_ai.request.temperature\")\n\n\t// GenAIRequestTopKKey is the attribute Key conforming to the\n\t// \"gen_ai.request.top_k\" semantic conventions. It represents the top_k sampling\n\t// setting for the GenAI request.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1.0\n\tGenAIRequestTopKKey = attribute.Key(\"gen_ai.request.top_k\")\n\n\t// GenAIRequestTopPKey is the attribute Key conforming to the\n\t// \"gen_ai.request.top_p\" semantic conventions. It represents the top_p sampling\n\t// setting for the GenAI request.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1.0\n\tGenAIRequestTopPKey = attribute.Key(\"gen_ai.request.top_p\")\n\n\t// GenAIResponseFinishReasonsKey is the attribute Key conforming to the\n\t// \"gen_ai.response.finish_reasons\" semantic conventions. It represents the\n\t// array of reasons the model stopped generating tokens, corresponding to each\n\t// generation received.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"stop\"], [\"stop\", \"length\"\n\tGenAIResponseFinishReasonsKey = attribute.Key(\"gen_ai.response.finish_reasons\")\n\n\t// GenAIResponseIDKey is the attribute Key conforming to the\n\t// \"gen_ai.response.id\" semantic conventions. It represents the unique\n\t// identifier for the completion.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"chatcmpl-123\"\n\tGenAIResponseIDKey = attribute.Key(\"gen_ai.response.id\")\n\n\t// GenAIResponseModelKey is the attribute Key conforming to the\n\t// \"gen_ai.response.model\" semantic conventions. It represents the name of the\n\t// model that generated the response.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"gpt-4-0613\"\n\tGenAIResponseModelKey = attribute.Key(\"gen_ai.response.model\")\n\n\t// GenAISystemInstructionsKey is the attribute Key conforming to the\n\t// \"gen_ai.system_instructions\" semantic conventions. It represents the system\n\t// message or instructions provided to the GenAI model separately from the chat\n\t// history.\n\t//\n\t// Type: any\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"[\\n {\\n \"type\": \"text\",\\n \"content\": \"You are an Agent that greet\n\t// users, always use greetings tool to respond\"\\n }\\n]\\n\", \"[\\n {\\n \"type\":\n\t// \"text\",\\n \"content\": \"You are a language translator.\"\\n },\\n {\\n \"type\":\n\t// \"text\",\\n \"content\": \"Your mission is to translate text in English to\n\t// French.\"\\n }\\n]\\n\"\n\t// Note: This attribute SHOULD be used when the corresponding provider or API\n\t// allows to provide system instructions or messages separately from the\n\t// chat history.\n\t//\n\t// Instructions that are part of the chat history SHOULD be recorded in\n\t// `gen_ai.input.messages` attribute instead.\n\t//\n\t// Instrumentations MUST follow [System instructions JSON schema].\n\t//\n\t// When recorded on spans, it MAY be recorded as a JSON string if structured\n\t// format is not supported and SHOULD be recorded in structured form otherwise.\n\t//\n\t// Instrumentations MAY provide a way for users to filter or truncate\n\t// system instructions.\n\t//\n\t// > [!Warning]\n\t// > This attribute may contain sensitive information.\n\t//\n\t// See [Recording content on attributes]\n\t// section for more details.\n\t//\n\t// [System instructions JSON schema]: /docs/gen-ai/gen-ai-system-instructions.json\n\t// [Recording content on attributes]: /docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes\n\tGenAISystemInstructionsKey = attribute.Key(\"gen_ai.system_instructions\")\n\n\t// GenAITokenTypeKey is the attribute Key conforming to the \"gen_ai.token.type\"\n\t// semantic conventions. It represents the type of token being counted.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"input\", \"output\"\n\tGenAITokenTypeKey = attribute.Key(\"gen_ai.token.type\")\n\n\t// GenAIToolCallIDKey is the attribute Key conforming to the\n\t// \"gen_ai.tool.call.id\" semantic conventions. It represents the tool call\n\t// identifier.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"call_mszuSIzqtI65i1wAUOE8w5H4\"\n\tGenAIToolCallIDKey = attribute.Key(\"gen_ai.tool.call.id\")\n\n\t// GenAIToolDescriptionKey is the attribute Key conforming to the\n\t// \"gen_ai.tool.description\" semantic conventions. It represents the tool\n\t// description.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Multiply two numbers\"\n\tGenAIToolDescriptionKey = attribute.Key(\"gen_ai.tool.description\")\n\n\t// GenAIToolNameKey is the attribute Key conforming to the \"gen_ai.tool.name\"\n\t// semantic conventions. It represents the name of the tool utilized by the\n\t// agent.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Flights\"\n\tGenAIToolNameKey = attribute.Key(\"gen_ai.tool.name\")\n\n\t// GenAIToolTypeKey is the attribute Key conforming to the \"gen_ai.tool.type\"\n\t// semantic conventions. It represents the type of the tool utilized by the\n\t// agent.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"function\", \"extension\", \"datastore\"\n\t// Note: Extension: A tool executed on the agent-side to directly call external\n\t// APIs, bridging the gap between the agent and real-world systems.\n\t// Agent-side operations involve actions that are performed by the agent on the\n\t// server or within the agent's controlled environment.\n\t// Function: A tool executed on the client-side, where the agent generates\n\t// parameters for a predefined function, and the client executes the logic.\n\t// Client-side operations are actions taken on the user's end or within the\n\t// client application.\n\t// Datastore: A tool used by the agent to access and query structured or\n\t// unstructured external data for retrieval-augmented tasks or knowledge\n\t// updates.\n\tGenAIToolTypeKey = attribute.Key(\"gen_ai.tool.type\")\n\n\t// GenAIUsageInputTokensKey is the attribute Key conforming to the\n\t// \"gen_ai.usage.input_tokens\" semantic conventions. It represents the number of\n\t// tokens used in the GenAI input (prompt).\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 100\n\tGenAIUsageInputTokensKey = attribute.Key(\"gen_ai.usage.input_tokens\")\n\n\t// GenAIUsageOutputTokensKey is the attribute Key conforming to the\n\t// \"gen_ai.usage.output_tokens\" semantic conventions. It represents the number\n\t// of tokens used in the GenAI response (completion).\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 180\n\tGenAIUsageOutputTokensKey = attribute.Key(\"gen_ai.usage.output_tokens\")\n)\n\n// GenAIAgentDescription returns an attribute KeyValue conforming to the\n// \"gen_ai.agent.description\" semantic conventions. It represents the free-form\n// description of the GenAI agent provided by the application.\nfunc GenAIAgentDescription(val string) attribute.KeyValue {\n\treturn GenAIAgentDescriptionKey.String(val)\n}\n\n// GenAIAgentID returns an attribute KeyValue conforming to the \"gen_ai.agent.id\"\n// semantic conventions. It represents the unique identifier of the GenAI agent.\nfunc GenAIAgentID(val string) attribute.KeyValue {\n\treturn GenAIAgentIDKey.String(val)\n}\n\n// GenAIAgentName returns an attribute KeyValue conforming to the\n// \"gen_ai.agent.name\" semantic conventions. It represents the human-readable\n// name of the GenAI agent provided by the application.\nfunc GenAIAgentName(val string) attribute.KeyValue {\n\treturn GenAIAgentNameKey.String(val)\n}\n\n// GenAIConversationID returns an attribute KeyValue conforming to the\n// \"gen_ai.conversation.id\" semantic conventions. It represents the unique\n// identifier for a conversation (session, thread), used to store and correlate\n// messages within this conversation.\nfunc GenAIConversationID(val string) attribute.KeyValue {\n\treturn GenAIConversationIDKey.String(val)\n}\n\n// GenAIDataSourceID returns an attribute KeyValue conforming to the\n// \"gen_ai.data_source.id\" semantic conventions. It represents the data source\n// identifier.\nfunc GenAIDataSourceID(val string) attribute.KeyValue {\n\treturn GenAIDataSourceIDKey.String(val)\n}\n\n// GenAIRequestChoiceCount returns an attribute KeyValue conforming to the\n// \"gen_ai.request.choice.count\" semantic conventions. It represents the target\n// number of candidate completions to return.\nfunc GenAIRequestChoiceCount(val int) attribute.KeyValue {\n\treturn GenAIRequestChoiceCountKey.Int(val)\n}\n\n// GenAIRequestEncodingFormats returns an attribute KeyValue conforming to the\n// \"gen_ai.request.encoding_formats\" semantic conventions. It represents the\n// encoding formats requested in an embeddings operation, if specified.\nfunc GenAIRequestEncodingFormats(val ...string) attribute.KeyValue {\n\treturn GenAIRequestEncodingFormatsKey.StringSlice(val)\n}\n\n// GenAIRequestFrequencyPenalty returns an attribute KeyValue conforming to the\n// \"gen_ai.request.frequency_penalty\" semantic conventions. It represents the\n// frequency penalty setting for the GenAI request.\nfunc GenAIRequestFrequencyPenalty(val float64) attribute.KeyValue {\n\treturn GenAIRequestFrequencyPenaltyKey.Float64(val)\n}\n\n// GenAIRequestMaxTokens returns an attribute KeyValue conforming to the\n// \"gen_ai.request.max_tokens\" semantic conventions. It represents the maximum\n// number of tokens the model generates for a request.\nfunc GenAIRequestMaxTokens(val int) attribute.KeyValue {\n\treturn GenAIRequestMaxTokensKey.Int(val)\n}\n\n// GenAIRequestModel returns an attribute KeyValue conforming to the\n// \"gen_ai.request.model\" semantic conventions. It represents the name of the\n// GenAI model a request is being made to.\nfunc GenAIRequestModel(val string) attribute.KeyValue {\n\treturn GenAIRequestModelKey.String(val)\n}\n\n// GenAIRequestPresencePenalty returns an attribute KeyValue conforming to the\n// \"gen_ai.request.presence_penalty\" semantic conventions. It represents the\n// presence penalty setting for the GenAI request.\nfunc GenAIRequestPresencePenalty(val float64) attribute.KeyValue {\n\treturn GenAIRequestPresencePenaltyKey.Float64(val)\n}\n\n// GenAIRequestSeed returns an attribute KeyValue conforming to the\n// \"gen_ai.request.seed\" semantic conventions. It represents the requests with\n// same seed value more likely to return same result.\nfunc GenAIRequestSeed(val int) attribute.KeyValue {\n\treturn GenAIRequestSeedKey.Int(val)\n}\n\n// GenAIRequestStopSequences returns an attribute KeyValue conforming to the\n// \"gen_ai.request.stop_sequences\" semantic conventions. It represents the list\n// of sequences that the model will use to stop generating further tokens.\nfunc GenAIRequestStopSequences(val ...string) attribute.KeyValue {\n\treturn GenAIRequestStopSequencesKey.StringSlice(val)\n}\n\n// GenAIRequestTemperature returns an attribute KeyValue conforming to the\n// \"gen_ai.request.temperature\" semantic conventions. It represents the\n// temperature setting for the GenAI request.\nfunc GenAIRequestTemperature(val float64) attribute.KeyValue {\n\treturn GenAIRequestTemperatureKey.Float64(val)\n}\n\n// GenAIRequestTopK returns an attribute KeyValue conforming to the\n// \"gen_ai.request.top_k\" semantic conventions. It represents the top_k sampling\n// setting for the GenAI request.\nfunc GenAIRequestTopK(val float64) attribute.KeyValue {\n\treturn GenAIRequestTopKKey.Float64(val)\n}\n\n// GenAIRequestTopP returns an attribute KeyValue conforming to the\n// \"gen_ai.request.top_p\" semantic conventions. It represents the top_p sampling\n// setting for the GenAI request.\nfunc GenAIRequestTopP(val float64) attribute.KeyValue {\n\treturn GenAIRequestTopPKey.Float64(val)\n}\n\n// GenAIResponseFinishReasons returns an attribute KeyValue conforming to the\n// \"gen_ai.response.finish_reasons\" semantic conventions. It represents the array\n// of reasons the model stopped generating tokens, corresponding to each\n// generation received.\nfunc GenAIResponseFinishReasons(val ...string) attribute.KeyValue {\n\treturn GenAIResponseFinishReasonsKey.StringSlice(val)\n}\n\n// GenAIResponseID returns an attribute KeyValue conforming to the\n// \"gen_ai.response.id\" semantic conventions. It represents the unique identifier\n// for the completion.\nfunc GenAIResponseID(val string) attribute.KeyValue {\n\treturn GenAIResponseIDKey.String(val)\n}\n\n// GenAIResponseModel returns an attribute KeyValue conforming to the\n// \"gen_ai.response.model\" semantic conventions. It represents the name of the\n// model that generated the response.\nfunc GenAIResponseModel(val string) attribute.KeyValue {\n\treturn GenAIResponseModelKey.String(val)\n}\n\n// GenAIToolCallID returns an attribute KeyValue conforming to the\n// \"gen_ai.tool.call.id\" semantic conventions. It represents the tool call\n// identifier.\nfunc GenAIToolCallID(val string) attribute.KeyValue {\n\treturn GenAIToolCallIDKey.String(val)\n}\n\n// GenAIToolDescription returns an attribute KeyValue conforming to the\n// \"gen_ai.tool.description\" semantic conventions. It represents the tool\n// description.\nfunc GenAIToolDescription(val string) attribute.KeyValue {\n\treturn GenAIToolDescriptionKey.String(val)\n}\n\n// GenAIToolName returns an attribute KeyValue conforming to the\n// \"gen_ai.tool.name\" semantic conventions. It represents the name of the tool\n// utilized by the agent.\nfunc GenAIToolName(val string) attribute.KeyValue {\n\treturn GenAIToolNameKey.String(val)\n}\n\n// GenAIToolType returns an attribute KeyValue conforming to the\n// \"gen_ai.tool.type\" semantic conventions. It represents the type of the tool\n// utilized by the agent.\nfunc GenAIToolType(val string) attribute.KeyValue {\n\treturn GenAIToolTypeKey.String(val)\n}\n\n// GenAIUsageInputTokens returns an attribute KeyValue conforming to the\n// \"gen_ai.usage.input_tokens\" semantic conventions. It represents the number of\n// tokens used in the GenAI input (prompt).\nfunc GenAIUsageInputTokens(val int) attribute.KeyValue {\n\treturn GenAIUsageInputTokensKey.Int(val)\n}\n\n// GenAIUsageOutputTokens returns an attribute KeyValue conforming to the\n// \"gen_ai.usage.output_tokens\" semantic conventions. It represents the number of\n// tokens used in the GenAI response (completion).\nfunc GenAIUsageOutputTokens(val int) attribute.KeyValue {\n\treturn GenAIUsageOutputTokensKey.Int(val)\n}\n\n// Enum values for gen_ai.operation.name\nvar (\n\t// Chat completion operation such as [OpenAI Chat API]\n\t// Stability: development\n\t//\n\t// [OpenAI Chat API]: https://platform.openai.com/docs/api-reference/chat\n\tGenAIOperationNameChat = GenAIOperationNameKey.String(\"chat\")\n\t// Multimodal content generation operation such as [Gemini Generate Content]\n\t// Stability: development\n\t//\n\t// [Gemini Generate Content]: https://ai.google.dev/api/generate-content\n\tGenAIOperationNameGenerateContent = GenAIOperationNameKey.String(\"generate_content\")\n\t// Text completions operation such as [OpenAI Completions API (Legacy)]\n\t// Stability: development\n\t//\n\t// [OpenAI Completions API (Legacy)]: https://platform.openai.com/docs/api-reference/completions\n\tGenAIOperationNameTextCompletion = GenAIOperationNameKey.String(\"text_completion\")\n\t// Embeddings operation such as [OpenAI Create embeddings API]\n\t// Stability: development\n\t//\n\t// [OpenAI Create embeddings API]: https://platform.openai.com/docs/api-reference/embeddings/create\n\tGenAIOperationNameEmbeddings = GenAIOperationNameKey.String(\"embeddings\")\n\t// Create GenAI agent\n\t// Stability: development\n\tGenAIOperationNameCreateAgent = GenAIOperationNameKey.String(\"create_agent\")\n\t// Invoke GenAI agent\n\t// Stability: development\n\tGenAIOperationNameInvokeAgent = GenAIOperationNameKey.String(\"invoke_agent\")\n\t// Execute a tool\n\t// Stability: development\n\tGenAIOperationNameExecuteTool = GenAIOperationNameKey.String(\"execute_tool\")\n)\n\n// Enum values for gen_ai.output.type\nvar (\n\t// Plain text\n\t// Stability: development\n\tGenAIOutputTypeText = GenAIOutputTypeKey.String(\"text\")\n\t// JSON object with known or unknown schema\n\t// Stability: development\n\tGenAIOutputTypeJSON = GenAIOutputTypeKey.String(\"json\")\n\t// Image\n\t// Stability: development\n\tGenAIOutputTypeImage = GenAIOutputTypeKey.String(\"image\")\n\t// Speech\n\t// Stability: development\n\tGenAIOutputTypeSpeech = GenAIOutputTypeKey.String(\"speech\")\n)\n\n// Enum values for gen_ai.provider.name\nvar (\n\t// [OpenAI]\n\t// Stability: development\n\t//\n\t// [OpenAI]: https://openai.com/\n\tGenAIProviderNameOpenAI = GenAIProviderNameKey.String(\"openai\")\n\t// Any Google generative AI endpoint\n\t// Stability: development\n\tGenAIProviderNameGCPGenAI = GenAIProviderNameKey.String(\"gcp.gen_ai\")\n\t// [Vertex AI]\n\t// Stability: development\n\t//\n\t// [Vertex AI]: https://cloud.google.com/vertex-ai\n\tGenAIProviderNameGCPVertexAI = GenAIProviderNameKey.String(\"gcp.vertex_ai\")\n\t// [Gemini]\n\t// Stability: development\n\t//\n\t// [Gemini]: https://cloud.google.com/products/gemini\n\tGenAIProviderNameGCPGemini = GenAIProviderNameKey.String(\"gcp.gemini\")\n\t// [Anthropic]\n\t// Stability: development\n\t//\n\t// [Anthropic]: https://www.anthropic.com/\n\tGenAIProviderNameAnthropic = GenAIProviderNameKey.String(\"anthropic\")\n\t// [Cohere]\n\t// Stability: development\n\t//\n\t// [Cohere]: https://cohere.com/\n\tGenAIProviderNameCohere = GenAIProviderNameKey.String(\"cohere\")\n\t// Azure AI Inference\n\t// Stability: development\n\tGenAIProviderNameAzureAIInference = GenAIProviderNameKey.String(\"azure.ai.inference\")\n\t// [Azure OpenAI]\n\t// Stability: development\n\t//\n\t// [Azure OpenAI]: https://azure.microsoft.com/products/ai-services/openai-service/\n\tGenAIProviderNameAzureAIOpenAI = GenAIProviderNameKey.String(\"azure.ai.openai\")\n\t// [IBM Watsonx AI]\n\t// Stability: development\n\t//\n\t// [IBM Watsonx AI]: https://www.ibm.com/products/watsonx-ai\n\tGenAIProviderNameIBMWatsonxAI = GenAIProviderNameKey.String(\"ibm.watsonx.ai\")\n\t// [AWS Bedrock]\n\t// Stability: development\n\t//\n\t// [AWS Bedrock]: https://aws.amazon.com/bedrock\n\tGenAIProviderNameAWSBedrock = GenAIProviderNameKey.String(\"aws.bedrock\")\n\t// [Perplexity]\n\t// Stability: development\n\t//\n\t// [Perplexity]: https://www.perplexity.ai/\n\tGenAIProviderNamePerplexity = GenAIProviderNameKey.String(\"perplexity\")\n\t// [xAI]\n\t// Stability: development\n\t//\n\t// [xAI]: https://x.ai/\n\tGenAIProviderNameXAI = GenAIProviderNameKey.String(\"x_ai\")\n\t// [DeepSeek]\n\t// Stability: development\n\t//\n\t// [DeepSeek]: https://www.deepseek.com/\n\tGenAIProviderNameDeepseek = GenAIProviderNameKey.String(\"deepseek\")\n\t// [Groq]\n\t// Stability: development\n\t//\n\t// [Groq]: https://groq.com/\n\tGenAIProviderNameGroq = GenAIProviderNameKey.String(\"groq\")\n\t// [Mistral AI]\n\t// Stability: development\n\t//\n\t// [Mistral AI]: https://mistral.ai/\n\tGenAIProviderNameMistralAI = GenAIProviderNameKey.String(\"mistral_ai\")\n)\n\n// Enum values for gen_ai.token.type\nvar (\n\t// Input tokens (prompt, input, etc.)\n\t// Stability: development\n\tGenAITokenTypeInput = GenAITokenTypeKey.String(\"input\")\n\t// Output tokens (completion, response, etc.)\n\t// Stability: development\n\tGenAITokenTypeOutput = GenAITokenTypeKey.String(\"output\")\n)\n\n// Namespace: geo\nconst (\n\t// GeoContinentCodeKey is the attribute Key conforming to the\n\t// \"geo.continent.code\" semantic conventions. It represents the two-letter code\n\t// representing continent’s name.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tGeoContinentCodeKey = attribute.Key(\"geo.continent.code\")\n\n\t// GeoCountryISOCodeKey is the attribute Key conforming to the\n\t// \"geo.country.iso_code\" semantic conventions. It represents the two-letter ISO\n\t// Country Code ([ISO 3166-1 alpha2]).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"CA\"\n\t//\n\t// [ISO 3166-1 alpha2]: https://wikipedia.org/wiki/ISO_3166-1#Codes\n\tGeoCountryISOCodeKey = attribute.Key(\"geo.country.iso_code\")\n\n\t// GeoLocalityNameKey is the attribute Key conforming to the \"geo.locality.name\"\n\t// semantic conventions. It represents the locality name. Represents the name of\n\t// a city, town, village, or similar populated place.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Montreal\", \"Berlin\"\n\tGeoLocalityNameKey = attribute.Key(\"geo.locality.name\")\n\n\t// GeoLocationLatKey is the attribute Key conforming to the \"geo.location.lat\"\n\t// semantic conventions. It represents the latitude of the geo location in\n\t// [WGS84].\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 45.505918\n\t//\n\t// [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84\n\tGeoLocationLatKey = attribute.Key(\"geo.location.lat\")\n\n\t// GeoLocationLonKey is the attribute Key conforming to the \"geo.location.lon\"\n\t// semantic conventions. It represents the longitude of the geo location in\n\t// [WGS84].\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: -73.61483\n\t//\n\t// [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84\n\tGeoLocationLonKey = attribute.Key(\"geo.location.lon\")\n\n\t// GeoPostalCodeKey is the attribute Key conforming to the \"geo.postal_code\"\n\t// semantic conventions. It represents the postal code associated with the\n\t// location. Values appropriate for this field may also be known as a postcode\n\t// or ZIP code and will vary widely from country to country.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"94040\"\n\tGeoPostalCodeKey = attribute.Key(\"geo.postal_code\")\n\n\t// GeoRegionISOCodeKey is the attribute Key conforming to the\n\t// \"geo.region.iso_code\" semantic conventions. It represents the region ISO code\n\t// ([ISO 3166-2]).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"CA-QC\"\n\t//\n\t// [ISO 3166-2]: https://wikipedia.org/wiki/ISO_3166-2\n\tGeoRegionISOCodeKey = attribute.Key(\"geo.region.iso_code\")\n)\n\n// GeoCountryISOCode returns an attribute KeyValue conforming to the\n// \"geo.country.iso_code\" semantic conventions. It represents the two-letter ISO\n// Country Code ([ISO 3166-1 alpha2]).\n//\n// [ISO 3166-1 alpha2]: https://wikipedia.org/wiki/ISO_3166-1#Codes\nfunc GeoCountryISOCode(val string) attribute.KeyValue {\n\treturn GeoCountryISOCodeKey.String(val)\n}\n\n// GeoLocalityName returns an attribute KeyValue conforming to the\n// \"geo.locality.name\" semantic conventions. It represents the locality name.\n// Represents the name of a city, town, village, or similar populated place.\nfunc GeoLocalityName(val string) attribute.KeyValue {\n\treturn GeoLocalityNameKey.String(val)\n}\n\n// GeoLocationLat returns an attribute KeyValue conforming to the\n// \"geo.location.lat\" semantic conventions. It represents the latitude of the geo\n// location in [WGS84].\n//\n// [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84\nfunc GeoLocationLat(val float64) attribute.KeyValue {\n\treturn GeoLocationLatKey.Float64(val)\n}\n\n// GeoLocationLon returns an attribute KeyValue conforming to the\n// \"geo.location.lon\" semantic conventions. It represents the longitude of the\n// geo location in [WGS84].\n//\n// [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84\nfunc GeoLocationLon(val float64) attribute.KeyValue {\n\treturn GeoLocationLonKey.Float64(val)\n}\n\n// GeoPostalCode returns an attribute KeyValue conforming to the\n// \"geo.postal_code\" semantic conventions. It represents the postal code\n// associated with the location. Values appropriate for this field may also be\n// known as a postcode or ZIP code and will vary widely from country to country.\nfunc GeoPostalCode(val string) attribute.KeyValue {\n\treturn GeoPostalCodeKey.String(val)\n}\n\n// GeoRegionISOCode returns an attribute KeyValue conforming to the\n// \"geo.region.iso_code\" semantic conventions. It represents the region ISO code\n// ([ISO 3166-2]).\n//\n// [ISO 3166-2]: https://wikipedia.org/wiki/ISO_3166-2\nfunc GeoRegionISOCode(val string) attribute.KeyValue {\n\treturn GeoRegionISOCodeKey.String(val)\n}\n\n// Enum values for geo.continent.code\nvar (\n\t// Africa\n\t// Stability: development\n\tGeoContinentCodeAf = GeoContinentCodeKey.String(\"AF\")\n\t// Antarctica\n\t// Stability: development\n\tGeoContinentCodeAn = GeoContinentCodeKey.String(\"AN\")\n\t// Asia\n\t// Stability: development\n\tGeoContinentCodeAs = GeoContinentCodeKey.String(\"AS\")\n\t// Europe\n\t// Stability: development\n\tGeoContinentCodeEu = GeoContinentCodeKey.String(\"EU\")\n\t// North America\n\t// Stability: development\n\tGeoContinentCodeNa = GeoContinentCodeKey.String(\"NA\")\n\t// Oceania\n\t// Stability: development\n\tGeoContinentCodeOc = GeoContinentCodeKey.String(\"OC\")\n\t// South America\n\t// Stability: development\n\tGeoContinentCodeSa = GeoContinentCodeKey.String(\"SA\")\n)\n\n// Namespace: go\nconst (\n\t// GoMemoryTypeKey is the attribute Key conforming to the \"go.memory.type\"\n\t// semantic conventions. It represents the type of memory.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"other\", \"stack\"\n\tGoMemoryTypeKey = attribute.Key(\"go.memory.type\")\n)\n\n// Enum values for go.memory.type\nvar (\n\t// Memory allocated from the heap that is reserved for stack space, whether or\n\t// not it is currently in-use.\n\t// Stability: development\n\tGoMemoryTypeStack = GoMemoryTypeKey.String(\"stack\")\n\t// Memory used by the Go runtime, excluding other categories of memory usage\n\t// described in this enumeration.\n\t// Stability: development\n\tGoMemoryTypeOther = GoMemoryTypeKey.String(\"other\")\n)\n\n// Namespace: graphql\nconst (\n\t// GraphQLDocumentKey is the attribute Key conforming to the \"graphql.document\"\n\t// semantic conventions. It represents the GraphQL document being executed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: query findBookById { bookById(id: ?) { name } }\n\t// Note: The value may be sanitized to exclude sensitive information.\n\tGraphQLDocumentKey = attribute.Key(\"graphql.document\")\n\n\t// GraphQLOperationNameKey is the attribute Key conforming to the\n\t// \"graphql.operation.name\" semantic conventions. It represents the name of the\n\t// operation being executed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: findBookById\n\tGraphQLOperationNameKey = attribute.Key(\"graphql.operation.name\")\n\n\t// GraphQLOperationTypeKey is the attribute Key conforming to the\n\t// \"graphql.operation.type\" semantic conventions. It represents the type of the\n\t// operation being executed.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"query\", \"mutation\", \"subscription\"\n\tGraphQLOperationTypeKey = attribute.Key(\"graphql.operation.type\")\n)\n\n// GraphQLDocument returns an attribute KeyValue conforming to the\n// \"graphql.document\" semantic conventions. It represents the GraphQL document\n// being executed.\nfunc GraphQLDocument(val string) attribute.KeyValue {\n\treturn GraphQLDocumentKey.String(val)\n}\n\n// GraphQLOperationName returns an attribute KeyValue conforming to the\n// \"graphql.operation.name\" semantic conventions. It represents the name of the\n// operation being executed.\nfunc GraphQLOperationName(val string) attribute.KeyValue {\n\treturn GraphQLOperationNameKey.String(val)\n}\n\n// Enum values for graphql.operation.type\nvar (\n\t// GraphQL query\n\t// Stability: development\n\tGraphQLOperationTypeQuery = GraphQLOperationTypeKey.String(\"query\")\n\t// GraphQL mutation\n\t// Stability: development\n\tGraphQLOperationTypeMutation = GraphQLOperationTypeKey.String(\"mutation\")\n\t// GraphQL subscription\n\t// Stability: development\n\tGraphQLOperationTypeSubscription = GraphQLOperationTypeKey.String(\"subscription\")\n)\n\n// Namespace: heroku\nconst (\n\t// HerokuAppIDKey is the attribute Key conforming to the \"heroku.app.id\"\n\t// semantic conventions. It represents the unique identifier for the\n\t// application.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2daa2797-e42b-4624-9322-ec3f968df4da\"\n\tHerokuAppIDKey = attribute.Key(\"heroku.app.id\")\n\n\t// HerokuReleaseCommitKey is the attribute Key conforming to the\n\t// \"heroku.release.commit\" semantic conventions. It represents the commit hash\n\t// for the current release.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"e6134959463efd8966b20e75b913cafe3f5ec\"\n\tHerokuReleaseCommitKey = attribute.Key(\"heroku.release.commit\")\n\n\t// HerokuReleaseCreationTimestampKey is the attribute Key conforming to the\n\t// \"heroku.release.creation_timestamp\" semantic conventions. It represents the\n\t// time and date the release was created.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2022-10-23T18:00:42Z\"\n\tHerokuReleaseCreationTimestampKey = attribute.Key(\"heroku.release.creation_timestamp\")\n)\n\n// HerokuAppID returns an attribute KeyValue conforming to the \"heroku.app.id\"\n// semantic conventions. It represents the unique identifier for the application.\nfunc HerokuAppID(val string) attribute.KeyValue {\n\treturn HerokuAppIDKey.String(val)\n}\n\n// HerokuReleaseCommit returns an attribute KeyValue conforming to the\n// \"heroku.release.commit\" semantic conventions. It represents the commit hash\n// for the current release.\nfunc HerokuReleaseCommit(val string) attribute.KeyValue {\n\treturn HerokuReleaseCommitKey.String(val)\n}\n\n// HerokuReleaseCreationTimestamp returns an attribute KeyValue conforming to the\n// \"heroku.release.creation_timestamp\" semantic conventions. It represents the\n// time and date the release was created.\nfunc HerokuReleaseCreationTimestamp(val string) attribute.KeyValue {\n\treturn HerokuReleaseCreationTimestampKey.String(val)\n}\n\n// Namespace: host\nconst (\n\t// HostArchKey is the attribute Key conforming to the \"host.arch\" semantic\n\t// conventions. It represents the CPU architecture the host system is running\n\t// on.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tHostArchKey = attribute.Key(\"host.arch\")\n\n\t// HostCPUCacheL2SizeKey is the attribute Key conforming to the\n\t// \"host.cpu.cache.l2.size\" semantic conventions. It represents the amount of\n\t// level 2 memory cache available to the processor (in Bytes).\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 12288000\n\tHostCPUCacheL2SizeKey = attribute.Key(\"host.cpu.cache.l2.size\")\n\n\t// HostCPUFamilyKey is the attribute Key conforming to the \"host.cpu.family\"\n\t// semantic conventions. It represents the family or generation of the CPU.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"6\", \"PA-RISC 1.1e\"\n\tHostCPUFamilyKey = attribute.Key(\"host.cpu.family\")\n\n\t// HostCPUModelIDKey is the attribute Key conforming to the \"host.cpu.model.id\"\n\t// semantic conventions. It represents the model identifier. It provides more\n\t// granular information about the CPU, distinguishing it from other CPUs within\n\t// the same family.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"6\", \"9000/778/B180L\"\n\tHostCPUModelIDKey = attribute.Key(\"host.cpu.model.id\")\n\n\t// HostCPUModelNameKey is the attribute Key conforming to the\n\t// \"host.cpu.model.name\" semantic conventions. It represents the model\n\t// designation of the processor.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz\"\n\tHostCPUModelNameKey = attribute.Key(\"host.cpu.model.name\")\n\n\t// HostCPUSteppingKey is the attribute Key conforming to the \"host.cpu.stepping\"\n\t// semantic conventions. It represents the stepping or core revisions.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1\", \"r1p1\"\n\tHostCPUSteppingKey = attribute.Key(\"host.cpu.stepping\")\n\n\t// HostCPUVendorIDKey is the attribute Key conforming to the\n\t// \"host.cpu.vendor.id\" semantic conventions. It represents the processor\n\t// manufacturer identifier. A maximum 12-character string.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"GenuineIntel\"\n\t// Note: [CPUID] command returns the vendor ID string in EBX, EDX and ECX\n\t// registers. Writing these to memory in this order results in a 12-character\n\t// string.\n\t//\n\t// [CPUID]: https://wiki.osdev.org/CPUID\n\tHostCPUVendorIDKey = attribute.Key(\"host.cpu.vendor.id\")\n\n\t// HostIDKey is the attribute Key conforming to the \"host.id\" semantic\n\t// conventions. It represents the unique host ID. For Cloud, this must be the\n\t// instance_id assigned by the cloud provider. For non-containerized systems,\n\t// this should be the `machine-id`. See the table below for the sources to use\n\t// to determine the `machine-id` based on operating system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"fdbf79e8af94cb7f9e8df36789187052\"\n\tHostIDKey = attribute.Key(\"host.id\")\n\n\t// HostImageIDKey is the attribute Key conforming to the \"host.image.id\"\n\t// semantic conventions. It represents the VM image ID or host OS image ID. For\n\t// Cloud, this value is from the provider.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"ami-07b06b442921831e5\"\n\tHostImageIDKey = attribute.Key(\"host.image.id\")\n\n\t// HostImageNameKey is the attribute Key conforming to the \"host.image.name\"\n\t// semantic conventions. It represents the name of the VM image or OS install\n\t// the host was instantiated from.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"infra-ami-eks-worker-node-7d4ec78312\", \"CentOS-8-x86_64-1905\"\n\tHostImageNameKey = attribute.Key(\"host.image.name\")\n\n\t// HostImageVersionKey is the attribute Key conforming to the\n\t// \"host.image.version\" semantic conventions. It represents the version string\n\t// of the VM image or host OS as defined in [Version Attributes].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"0.1\"\n\t//\n\t// [Version Attributes]: /docs/resource/README.md#version-attributes\n\tHostImageVersionKey = attribute.Key(\"host.image.version\")\n\n\t// HostIPKey is the attribute Key conforming to the \"host.ip\" semantic\n\t// conventions. It represents the available IP addresses of the host, excluding\n\t// loopback interfaces.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"192.168.1.140\", \"fe80::abc2:4a28:737a:609e\"\n\t// Note: IPv4 Addresses MUST be specified in dotted-quad notation. IPv6\n\t// addresses MUST be specified in the [RFC 5952] format.\n\t//\n\t// [RFC 5952]: https://www.rfc-editor.org/rfc/rfc5952.html\n\tHostIPKey = attribute.Key(\"host.ip\")\n\n\t// HostMacKey is the attribute Key conforming to the \"host.mac\" semantic\n\t// conventions. It represents the available MAC addresses of the host, excluding\n\t// loopback interfaces.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"AC-DE-48-23-45-67\", \"AC-DE-48-23-45-67-01-9F\"\n\t// Note: MAC Addresses MUST be represented in [IEEE RA hexadecimal form]: as\n\t// hyphen-separated octets in uppercase hexadecimal form from most to least\n\t// significant.\n\t//\n\t// [IEEE RA hexadecimal form]: https://standards.ieee.org/wp-content/uploads/import/documents/tutorials/eui.pdf\n\tHostMacKey = attribute.Key(\"host.mac\")\n\n\t// HostNameKey is the attribute Key conforming to the \"host.name\" semantic\n\t// conventions. It represents the name of the host. On Unix systems, it may\n\t// contain what the hostname command returns, or the fully qualified hostname,\n\t// or another name specified by the user.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry-test\"\n\tHostNameKey = attribute.Key(\"host.name\")\n\n\t// HostTypeKey is the attribute Key conforming to the \"host.type\" semantic\n\t// conventions. It represents the type of host. For Cloud, this must be the\n\t// machine type.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"n1-standard-1\"\n\tHostTypeKey = attribute.Key(\"host.type\")\n)\n\n// HostCPUCacheL2Size returns an attribute KeyValue conforming to the\n// \"host.cpu.cache.l2.size\" semantic conventions. It represents the amount of\n// level 2 memory cache available to the processor (in Bytes).\nfunc HostCPUCacheL2Size(val int) attribute.KeyValue {\n\treturn HostCPUCacheL2SizeKey.Int(val)\n}\n\n// HostCPUFamily returns an attribute KeyValue conforming to the\n// \"host.cpu.family\" semantic conventions. It represents the family or generation\n// of the CPU.\nfunc HostCPUFamily(val string) attribute.KeyValue {\n\treturn HostCPUFamilyKey.String(val)\n}\n\n// HostCPUModelID returns an attribute KeyValue conforming to the\n// \"host.cpu.model.id\" semantic conventions. It represents the model identifier.\n// It provides more granular information about the CPU, distinguishing it from\n// other CPUs within the same family.\nfunc HostCPUModelID(val string) attribute.KeyValue {\n\treturn HostCPUModelIDKey.String(val)\n}\n\n// HostCPUModelName returns an attribute KeyValue conforming to the\n// \"host.cpu.model.name\" semantic conventions. It represents the model\n// designation of the processor.\nfunc HostCPUModelName(val string) attribute.KeyValue {\n\treturn HostCPUModelNameKey.String(val)\n}\n\n// HostCPUStepping returns an attribute KeyValue conforming to the\n// \"host.cpu.stepping\" semantic conventions. It represents the stepping or core\n// revisions.\nfunc HostCPUStepping(val string) attribute.KeyValue {\n\treturn HostCPUSteppingKey.String(val)\n}\n\n// HostCPUVendorID returns an attribute KeyValue conforming to the\n// \"host.cpu.vendor.id\" semantic conventions. It represents the processor\n// manufacturer identifier. A maximum 12-character string.\nfunc HostCPUVendorID(val string) attribute.KeyValue {\n\treturn HostCPUVendorIDKey.String(val)\n}\n\n// HostID returns an attribute KeyValue conforming to the \"host.id\" semantic\n// conventions. It represents the unique host ID. For Cloud, this must be the\n// instance_id assigned by the cloud provider. For non-containerized systems,\n// this should be the `machine-id`. See the table below for the sources to use to\n// determine the `machine-id` based on operating system.\nfunc HostID(val string) attribute.KeyValue {\n\treturn HostIDKey.String(val)\n}\n\n// HostImageID returns an attribute KeyValue conforming to the \"host.image.id\"\n// semantic conventions. It represents the VM image ID or host OS image ID. For\n// Cloud, this value is from the provider.\nfunc HostImageID(val string) attribute.KeyValue {\n\treturn HostImageIDKey.String(val)\n}\n\n// HostImageName returns an attribute KeyValue conforming to the\n// \"host.image.name\" semantic conventions. It represents the name of the VM image\n// or OS install the host was instantiated from.\nfunc HostImageName(val string) attribute.KeyValue {\n\treturn HostImageNameKey.String(val)\n}\n\n// HostImageVersion returns an attribute KeyValue conforming to the\n// \"host.image.version\" semantic conventions. It represents the version string of\n// the VM image or host OS as defined in [Version Attributes].\n//\n// [Version Attributes]: /docs/resource/README.md#version-attributes\nfunc HostImageVersion(val string) attribute.KeyValue {\n\treturn HostImageVersionKey.String(val)\n}\n\n// HostIP returns an attribute KeyValue conforming to the \"host.ip\" semantic\n// conventions. It represents the available IP addresses of the host, excluding\n// loopback interfaces.\nfunc HostIP(val ...string) attribute.KeyValue {\n\treturn HostIPKey.StringSlice(val)\n}\n\n// HostMac returns an attribute KeyValue conforming to the \"host.mac\" semantic\n// conventions. It represents the available MAC addresses of the host, excluding\n// loopback interfaces.\nfunc HostMac(val ...string) attribute.KeyValue {\n\treturn HostMacKey.StringSlice(val)\n}\n\n// HostName returns an attribute KeyValue conforming to the \"host.name\" semantic\n// conventions. It represents the name of the host. On Unix systems, it may\n// contain what the hostname command returns, or the fully qualified hostname, or\n// another name specified by the user.\nfunc HostName(val string) attribute.KeyValue {\n\treturn HostNameKey.String(val)\n}\n\n// HostType returns an attribute KeyValue conforming to the \"host.type\" semantic\n// conventions. It represents the type of host. For Cloud, this must be the\n// machine type.\nfunc HostType(val string) attribute.KeyValue {\n\treturn HostTypeKey.String(val)\n}\n\n// Enum values for host.arch\nvar (\n\t// AMD64\n\t// Stability: development\n\tHostArchAMD64 = HostArchKey.String(\"amd64\")\n\t// ARM32\n\t// Stability: development\n\tHostArchARM32 = HostArchKey.String(\"arm32\")\n\t// ARM64\n\t// Stability: development\n\tHostArchARM64 = HostArchKey.String(\"arm64\")\n\t// Itanium\n\t// Stability: development\n\tHostArchIA64 = HostArchKey.String(\"ia64\")\n\t// 32-bit PowerPC\n\t// Stability: development\n\tHostArchPPC32 = HostArchKey.String(\"ppc32\")\n\t// 64-bit PowerPC\n\t// Stability: development\n\tHostArchPPC64 = HostArchKey.String(\"ppc64\")\n\t// IBM z/Architecture\n\t// Stability: development\n\tHostArchS390x = HostArchKey.String(\"s390x\")\n\t// 32-bit x86\n\t// Stability: development\n\tHostArchX86 = HostArchKey.String(\"x86\")\n)\n\n// Namespace: http\nconst (\n\t// HTTPConnectionStateKey is the attribute Key conforming to the\n\t// \"http.connection.state\" semantic conventions. It represents the state of the\n\t// HTTP connection in the HTTP connection pool.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"active\", \"idle\"\n\tHTTPConnectionStateKey = attribute.Key(\"http.connection.state\")\n\n\t// HTTPRequestBodySizeKey is the attribute Key conforming to the\n\t// \"http.request.body.size\" semantic conventions. It represents the size of the\n\t// request payload body in bytes. This is the number of bytes transferred\n\t// excluding headers and is often, but not always, present as the\n\t// [Content-Length] header. For requests using transport encoding, this should\n\t// be the compressed size.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length\n\tHTTPRequestBodySizeKey = attribute.Key(\"http.request.body.size\")\n\n\t// HTTPRequestMethodKey is the attribute Key conforming to the\n\t// \"http.request.method\" semantic conventions. It represents the HTTP request\n\t// method.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"GET\", \"POST\", \"HEAD\"\n\t// Note: HTTP request method value SHOULD be \"known\" to the instrumentation.\n\t// By default, this convention defines \"known\" methods as the ones listed in\n\t// [RFC9110]\n\t// and the PATCH method defined in [RFC5789].\n\t//\n\t// If the HTTP request method is not known to instrumentation, it MUST set the\n\t// `http.request.method` attribute to `_OTHER`.\n\t//\n\t// If the HTTP instrumentation could end up converting valid HTTP request\n\t// methods to `_OTHER`, then it MUST provide a way to override\n\t// the list of known HTTP methods. If this override is done via environment\n\t// variable, then the environment variable MUST be named\n\t// OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of\n\t// case-sensitive known HTTP methods\n\t// (this list MUST be a full override of the default known method, it is not a\n\t// list of known methods in addition to the defaults).\n\t//\n\t// HTTP method names are case-sensitive and `http.request.method` attribute\n\t// value MUST match a known HTTP method name exactly.\n\t// Instrumentations for specific web frameworks that consider HTTP methods to be\n\t// case insensitive, SHOULD populate a canonical equivalent.\n\t// Tracing instrumentations that do so, MUST also set\n\t// `http.request.method_original` to the original value.\n\t//\n\t// [RFC9110]: https://www.rfc-editor.org/rfc/rfc9110.html#name-methods\n\t// [RFC5789]: https://www.rfc-editor.org/rfc/rfc5789.html\n\tHTTPRequestMethodKey = attribute.Key(\"http.request.method\")\n\n\t// HTTPRequestMethodOriginalKey is the attribute Key conforming to the\n\t// \"http.request.method_original\" semantic conventions. It represents the\n\t// original HTTP method sent by the client in the request line.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"GeT\", \"ACL\", \"foo\"\n\tHTTPRequestMethodOriginalKey = attribute.Key(\"http.request.method_original\")\n\n\t// HTTPRequestResendCountKey is the attribute Key conforming to the\n\t// \"http.request.resend_count\" semantic conventions. It represents the ordinal\n\t// number of request resending attempt (for any reason, including redirects).\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Note: The resend count SHOULD be updated each time an HTTP request gets\n\t// resent by the client, regardless of what was the cause of the resending (e.g.\n\t// redirection, authorization failure, 503 Server Unavailable, network issues,\n\t// or any other).\n\tHTTPRequestResendCountKey = attribute.Key(\"http.request.resend_count\")\n\n\t// HTTPRequestSizeKey is the attribute Key conforming to the \"http.request.size\"\n\t// semantic conventions. It represents the total size of the request in bytes.\n\t// This should be the total number of bytes sent over the wire, including the\n\t// request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request\n\t// body if any.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tHTTPRequestSizeKey = attribute.Key(\"http.request.size\")\n\n\t// HTTPResponseBodySizeKey is the attribute Key conforming to the\n\t// \"http.response.body.size\" semantic conventions. It represents the size of the\n\t// response payload body in bytes. This is the number of bytes transferred\n\t// excluding headers and is often, but not always, present as the\n\t// [Content-Length] header. For requests using transport encoding, this should\n\t// be the compressed size.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length\n\tHTTPResponseBodySizeKey = attribute.Key(\"http.response.body.size\")\n\n\t// HTTPResponseSizeKey is the attribute Key conforming to the\n\t// \"http.response.size\" semantic conventions. It represents the total size of\n\t// the response in bytes. This should be the total number of bytes sent over the\n\t// wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3),\n\t// headers, and response body and trailers if any.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tHTTPResponseSizeKey = attribute.Key(\"http.response.size\")\n\n\t// HTTPResponseStatusCodeKey is the attribute Key conforming to the\n\t// \"http.response.status_code\" semantic conventions. It represents the\n\t// [HTTP response status code].\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: 200\n\t//\n\t// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6\n\tHTTPResponseStatusCodeKey = attribute.Key(\"http.response.status_code\")\n\n\t// HTTPRouteKey is the attribute Key conforming to the \"http.route\" semantic\n\t// conventions. It represents the matched route, that is, the path template in\n\t// the format used by the respective server framework.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"/users/:userID?\", \"{controller}/{action}/{id?}\"\n\t// Note: MUST NOT be populated when this is not supported by the HTTP server\n\t// framework as the route attribute should have low-cardinality and the URI path\n\t// can NOT substitute it.\n\t// SHOULD include the [application root] if there is one.\n\t//\n\t// [application root]: /docs/http/http-spans.md#http-server-definitions\n\tHTTPRouteKey = attribute.Key(\"http.route\")\n)\n\n// HTTPRequestBodySize returns an attribute KeyValue conforming to the\n// \"http.request.body.size\" semantic conventions. It represents the size of the\n// request payload body in bytes. This is the number of bytes transferred\n// excluding headers and is often, but not always, present as the\n// [Content-Length] header. For requests using transport encoding, this should be\n// the compressed size.\n//\n// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length\nfunc HTTPRequestBodySize(val int) attribute.KeyValue {\n\treturn HTTPRequestBodySizeKey.Int(val)\n}\n\n// HTTPRequestHeader returns an attribute KeyValue conforming to the\n// \"http.request.header\" semantic conventions. It represents the HTTP request\n// headers, `<key>` being the normalized HTTP Header name (lowercase), the value\n// being the header values.\nfunc HTTPRequestHeader(key string, val ...string) attribute.KeyValue {\n\treturn attribute.StringSlice(\"http.request.header.\"+key, val)\n}\n\n// HTTPRequestMethodOriginal returns an attribute KeyValue conforming to the\n// \"http.request.method_original\" semantic conventions. It represents the\n// original HTTP method sent by the client in the request line.\nfunc HTTPRequestMethodOriginal(val string) attribute.KeyValue {\n\treturn HTTPRequestMethodOriginalKey.String(val)\n}\n\n// HTTPRequestResendCount returns an attribute KeyValue conforming to the\n// \"http.request.resend_count\" semantic conventions. It represents the ordinal\n// number of request resending attempt (for any reason, including redirects).\nfunc HTTPRequestResendCount(val int) attribute.KeyValue {\n\treturn HTTPRequestResendCountKey.Int(val)\n}\n\n// HTTPRequestSize returns an attribute KeyValue conforming to the\n// \"http.request.size\" semantic conventions. It represents the total size of the\n// request in bytes. This should be the total number of bytes sent over the wire,\n// including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers,\n// and request body if any.\nfunc HTTPRequestSize(val int) attribute.KeyValue {\n\treturn HTTPRequestSizeKey.Int(val)\n}\n\n// HTTPResponseBodySize returns an attribute KeyValue conforming to the\n// \"http.response.body.size\" semantic conventions. It represents the size of the\n// response payload body in bytes. This is the number of bytes transferred\n// excluding headers and is often, but not always, present as the\n// [Content-Length] header. For requests using transport encoding, this should be\n// the compressed size.\n//\n// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length\nfunc HTTPResponseBodySize(val int) attribute.KeyValue {\n\treturn HTTPResponseBodySizeKey.Int(val)\n}\n\n// HTTPResponseHeader returns an attribute KeyValue conforming to the\n// \"http.response.header\" semantic conventions. It represents the HTTP response\n// headers, `<key>` being the normalized HTTP Header name (lowercase), the value\n// being the header values.\nfunc HTTPResponseHeader(key string, val ...string) attribute.KeyValue {\n\treturn attribute.StringSlice(\"http.response.header.\"+key, val)\n}\n\n// HTTPResponseSize returns an attribute KeyValue conforming to the\n// \"http.response.size\" semantic conventions. It represents the total size of the\n// response in bytes. This should be the total number of bytes sent over the\n// wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3),\n// headers, and response body and trailers if any.\nfunc HTTPResponseSize(val int) attribute.KeyValue {\n\treturn HTTPResponseSizeKey.Int(val)\n}\n\n// HTTPResponseStatusCode returns an attribute KeyValue conforming to the\n// \"http.response.status_code\" semantic conventions. It represents the\n// [HTTP response status code].\n//\n// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6\nfunc HTTPResponseStatusCode(val int) attribute.KeyValue {\n\treturn HTTPResponseStatusCodeKey.Int(val)\n}\n\n// HTTPRoute returns an attribute KeyValue conforming to the \"http.route\"\n// semantic conventions. It represents the matched route, that is, the path\n// template in the format used by the respective server framework.\nfunc HTTPRoute(val string) attribute.KeyValue {\n\treturn HTTPRouteKey.String(val)\n}\n\n// Enum values for http.connection.state\nvar (\n\t// active state.\n\t// Stability: development\n\tHTTPConnectionStateActive = HTTPConnectionStateKey.String(\"active\")\n\t// idle state.\n\t// Stability: development\n\tHTTPConnectionStateIdle = HTTPConnectionStateKey.String(\"idle\")\n)\n\n// Enum values for http.request.method\nvar (\n\t// CONNECT method.\n\t// Stability: stable\n\tHTTPRequestMethodConnect = HTTPRequestMethodKey.String(\"CONNECT\")\n\t// DELETE method.\n\t// Stability: stable\n\tHTTPRequestMethodDelete = HTTPRequestMethodKey.String(\"DELETE\")\n\t// GET method.\n\t// Stability: stable\n\tHTTPRequestMethodGet = HTTPRequestMethodKey.String(\"GET\")\n\t// HEAD method.\n\t// Stability: stable\n\tHTTPRequestMethodHead = HTTPRequestMethodKey.String(\"HEAD\")\n\t// OPTIONS method.\n\t// Stability: stable\n\tHTTPRequestMethodOptions = HTTPRequestMethodKey.String(\"OPTIONS\")\n\t// PATCH method.\n\t// Stability: stable\n\tHTTPRequestMethodPatch = HTTPRequestMethodKey.String(\"PATCH\")\n\t// POST method.\n\t// Stability: stable\n\tHTTPRequestMethodPost = HTTPRequestMethodKey.String(\"POST\")\n\t// PUT method.\n\t// Stability: stable\n\tHTTPRequestMethodPut = HTTPRequestMethodKey.String(\"PUT\")\n\t// TRACE method.\n\t// Stability: stable\n\tHTTPRequestMethodTrace = HTTPRequestMethodKey.String(\"TRACE\")\n\t// Any HTTP method that the instrumentation has no prior knowledge of.\n\t// Stability: stable\n\tHTTPRequestMethodOther = HTTPRequestMethodKey.String(\"_OTHER\")\n)\n\n// Namespace: hw\nconst (\n\t// HwBatteryCapacityKey is the attribute Key conforming to the\n\t// \"hw.battery.capacity\" semantic conventions. It represents the design capacity\n\t// in Watts-hours or Amper-hours.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"9.3Ah\", \"50Wh\"\n\tHwBatteryCapacityKey = attribute.Key(\"hw.battery.capacity\")\n\n\t// HwBatteryChemistryKey is the attribute Key conforming to the\n\t// \"hw.battery.chemistry\" semantic conventions. It represents the battery\n\t// [chemistry], e.g. Lithium-Ion, Nickel-Cadmium, etc.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Li-ion\", \"NiMH\"\n\t//\n\t// [chemistry]: https://schemas.dmtf.org/wbem/cim-html/2.31.0/CIM_Battery.html\n\tHwBatteryChemistryKey = attribute.Key(\"hw.battery.chemistry\")\n\n\t// HwBatteryStateKey is the attribute Key conforming to the \"hw.battery.state\"\n\t// semantic conventions. It represents the current state of the battery.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tHwBatteryStateKey = attribute.Key(\"hw.battery.state\")\n\n\t// HwBiosVersionKey is the attribute Key conforming to the \"hw.bios_version\"\n\t// semantic conventions. It represents the BIOS version of the hardware\n\t// component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1.2.3\"\n\tHwBiosVersionKey = attribute.Key(\"hw.bios_version\")\n\n\t// HwDriverVersionKey is the attribute Key conforming to the \"hw.driver_version\"\n\t// semantic conventions. It represents the driver version for the hardware\n\t// component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"10.2.1-3\"\n\tHwDriverVersionKey = attribute.Key(\"hw.driver_version\")\n\n\t// HwEnclosureTypeKey is the attribute Key conforming to the \"hw.enclosure.type\"\n\t// semantic conventions. It represents the type of the enclosure (useful for\n\t// modular systems).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Computer\", \"Storage\", \"Switch\"\n\tHwEnclosureTypeKey = attribute.Key(\"hw.enclosure.type\")\n\n\t// HwFirmwareVersionKey is the attribute Key conforming to the\n\t// \"hw.firmware_version\" semantic conventions. It represents the firmware\n\t// version of the hardware component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2.0.1\"\n\tHwFirmwareVersionKey = attribute.Key(\"hw.firmware_version\")\n\n\t// HwGpuTaskKey is the attribute Key conforming to the \"hw.gpu.task\" semantic\n\t// conventions. It represents the type of task the GPU is performing.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tHwGpuTaskKey = attribute.Key(\"hw.gpu.task\")\n\n\t// HwIDKey is the attribute Key conforming to the \"hw.id\" semantic conventions.\n\t// It represents an identifier for the hardware component, unique within the\n\t// monitored host.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"win32battery_battery_testsysa33_1\"\n\tHwIDKey = attribute.Key(\"hw.id\")\n\n\t// HwLimitTypeKey is the attribute Key conforming to the \"hw.limit_type\"\n\t// semantic conventions. It represents the type of limit for hardware\n\t// components.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tHwLimitTypeKey = attribute.Key(\"hw.limit_type\")\n\n\t// HwLogicalDiskRaidLevelKey is the attribute Key conforming to the\n\t// \"hw.logical_disk.raid_level\" semantic conventions. It represents the RAID\n\t// Level of the logical disk.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"RAID0+1\", \"RAID5\", \"RAID10\"\n\tHwLogicalDiskRaidLevelKey = attribute.Key(\"hw.logical_disk.raid_level\")\n\n\t// HwLogicalDiskStateKey is the attribute Key conforming to the\n\t// \"hw.logical_disk.state\" semantic conventions. It represents the state of the\n\t// logical disk space usage.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tHwLogicalDiskStateKey = attribute.Key(\"hw.logical_disk.state\")\n\n\t// HwMemoryTypeKey is the attribute Key conforming to the \"hw.memory.type\"\n\t// semantic conventions. It represents the type of the memory module.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"DDR4\", \"DDR5\", \"LPDDR5\"\n\tHwMemoryTypeKey = attribute.Key(\"hw.memory.type\")\n\n\t// HwModelKey is the attribute Key conforming to the \"hw.model\" semantic\n\t// conventions. It represents the descriptive model name of the hardware\n\t// component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"PERC H740P\", \"Intel(R) Core(TM) i7-10700K\", \"Dell XPS 15 Battery\"\n\tHwModelKey = attribute.Key(\"hw.model\")\n\n\t// HwNameKey is the attribute Key conforming to the \"hw.name\" semantic\n\t// conventions. It represents an easily-recognizable name for the hardware\n\t// component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"eth0\"\n\tHwNameKey = attribute.Key(\"hw.name\")\n\n\t// HwNetworkLogicalAddressesKey is the attribute Key conforming to the\n\t// \"hw.network.logical_addresses\" semantic conventions. It represents the\n\t// logical addresses of the adapter (e.g. IP address, or WWPN).\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"172.16.8.21\", \"57.11.193.42\"\n\tHwNetworkLogicalAddressesKey = attribute.Key(\"hw.network.logical_addresses\")\n\n\t// HwNetworkPhysicalAddressKey is the attribute Key conforming to the\n\t// \"hw.network.physical_address\" semantic conventions. It represents the\n\t// physical address of the adapter (e.g. MAC address, or WWNN).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"00-90-F5-E9-7B-36\"\n\tHwNetworkPhysicalAddressKey = attribute.Key(\"hw.network.physical_address\")\n\n\t// HwParentKey is the attribute Key conforming to the \"hw.parent\" semantic\n\t// conventions. It represents the unique identifier of the parent component\n\t// (typically the `hw.id` attribute of the enclosure, or disk controller).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"dellStorage_perc_0\"\n\tHwParentKey = attribute.Key(\"hw.parent\")\n\n\t// HwPhysicalDiskSmartAttributeKey is the attribute Key conforming to the\n\t// \"hw.physical_disk.smart_attribute\" semantic conventions. It represents the\n\t// [S.M.A.R.T.] (Self-Monitoring, Analysis, and Reporting Technology) attribute\n\t// of the physical disk.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Spin Retry Count\", \"Seek Error Rate\", \"Raw Read Error Rate\"\n\t//\n\t// [S.M.A.R.T.]: https://wikipedia.org/wiki/S.M.A.R.T.\n\tHwPhysicalDiskSmartAttributeKey = attribute.Key(\"hw.physical_disk.smart_attribute\")\n\n\t// HwPhysicalDiskStateKey is the attribute Key conforming to the\n\t// \"hw.physical_disk.state\" semantic conventions. It represents the state of the\n\t// physical disk endurance utilization.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tHwPhysicalDiskStateKey = attribute.Key(\"hw.physical_disk.state\")\n\n\t// HwPhysicalDiskTypeKey is the attribute Key conforming to the\n\t// \"hw.physical_disk.type\" semantic conventions. It represents the type of the\n\t// physical disk.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"HDD\", \"SSD\", \"10K\"\n\tHwPhysicalDiskTypeKey = attribute.Key(\"hw.physical_disk.type\")\n\n\t// HwSensorLocationKey is the attribute Key conforming to the\n\t// \"hw.sensor_location\" semantic conventions. It represents the location of the\n\t// sensor.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"cpu0\", \"ps1\", \"INLET\", \"CPU0_DIE\", \"AMBIENT\", \"MOTHERBOARD\", \"PS0\n\t// V3_3\", \"MAIN_12V\", \"CPU_VCORE\"\n\tHwSensorLocationKey = attribute.Key(\"hw.sensor_location\")\n\n\t// HwSerialNumberKey is the attribute Key conforming to the \"hw.serial_number\"\n\t// semantic conventions. It represents the serial number of the hardware\n\t// component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"CNFCP0123456789\"\n\tHwSerialNumberKey = attribute.Key(\"hw.serial_number\")\n\n\t// HwStateKey is the attribute Key conforming to the \"hw.state\" semantic\n\t// conventions. It represents the current state of the component.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tHwStateKey = attribute.Key(\"hw.state\")\n\n\t// HwTapeDriveOperationTypeKey is the attribute Key conforming to the\n\t// \"hw.tape_drive.operation_type\" semantic conventions. It represents the type\n\t// of tape drive operation.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tHwTapeDriveOperationTypeKey = attribute.Key(\"hw.tape_drive.operation_type\")\n\n\t// HwTypeKey is the attribute Key conforming to the \"hw.type\" semantic\n\t// conventions. It represents the type of the component.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: Describes the category of the hardware component for which `hw.state`\n\t// is being reported. For example, `hw.type=temperature` along with\n\t// `hw.state=degraded` would indicate that the temperature of the hardware\n\t// component has been reported as `degraded`.\n\tHwTypeKey = attribute.Key(\"hw.type\")\n\n\t// HwVendorKey is the attribute Key conforming to the \"hw.vendor\" semantic\n\t// conventions. It represents the vendor name of the hardware component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Dell\", \"HP\", \"Intel\", \"AMD\", \"LSI\", \"Lenovo\"\n\tHwVendorKey = attribute.Key(\"hw.vendor\")\n)\n\n// HwBatteryCapacity returns an attribute KeyValue conforming to the\n// \"hw.battery.capacity\" semantic conventions. It represents the design capacity\n// in Watts-hours or Amper-hours.\nfunc HwBatteryCapacity(val string) attribute.KeyValue {\n\treturn HwBatteryCapacityKey.String(val)\n}\n\n// HwBatteryChemistry returns an attribute KeyValue conforming to the\n// \"hw.battery.chemistry\" semantic conventions. It represents the battery\n// [chemistry], e.g. Lithium-Ion, Nickel-Cadmium, etc.\n//\n// [chemistry]: https://schemas.dmtf.org/wbem/cim-html/2.31.0/CIM_Battery.html\nfunc HwBatteryChemistry(val string) attribute.KeyValue {\n\treturn HwBatteryChemistryKey.String(val)\n}\n\n// HwBiosVersion returns an attribute KeyValue conforming to the\n// \"hw.bios_version\" semantic conventions. It represents the BIOS version of the\n// hardware component.\nfunc HwBiosVersion(val string) attribute.KeyValue {\n\treturn HwBiosVersionKey.String(val)\n}\n\n// HwDriverVersion returns an attribute KeyValue conforming to the\n// \"hw.driver_version\" semantic conventions. It represents the driver version for\n// the hardware component.\nfunc HwDriverVersion(val string) attribute.KeyValue {\n\treturn HwDriverVersionKey.String(val)\n}\n\n// HwEnclosureType returns an attribute KeyValue conforming to the\n// \"hw.enclosure.type\" semantic conventions. It represents the type of the\n// enclosure (useful for modular systems).\nfunc HwEnclosureType(val string) attribute.KeyValue {\n\treturn HwEnclosureTypeKey.String(val)\n}\n\n// HwFirmwareVersion returns an attribute KeyValue conforming to the\n// \"hw.firmware_version\" semantic conventions. It represents the firmware version\n// of the hardware component.\nfunc HwFirmwareVersion(val string) attribute.KeyValue {\n\treturn HwFirmwareVersionKey.String(val)\n}\n\n// HwID returns an attribute KeyValue conforming to the \"hw.id\" semantic\n// conventions. It represents an identifier for the hardware component, unique\n// within the monitored host.\nfunc HwID(val string) attribute.KeyValue {\n\treturn HwIDKey.String(val)\n}\n\n// HwLogicalDiskRaidLevel returns an attribute KeyValue conforming to the\n// \"hw.logical_disk.raid_level\" semantic conventions. It represents the RAID\n// Level of the logical disk.\nfunc HwLogicalDiskRaidLevel(val string) attribute.KeyValue {\n\treturn HwLogicalDiskRaidLevelKey.String(val)\n}\n\n// HwMemoryType returns an attribute KeyValue conforming to the \"hw.memory.type\"\n// semantic conventions. It represents the type of the memory module.\nfunc HwMemoryType(val string) attribute.KeyValue {\n\treturn HwMemoryTypeKey.String(val)\n}\n\n// HwModel returns an attribute KeyValue conforming to the \"hw.model\" semantic\n// conventions. It represents the descriptive model name of the hardware\n// component.\nfunc HwModel(val string) attribute.KeyValue {\n\treturn HwModelKey.String(val)\n}\n\n// HwName returns an attribute KeyValue conforming to the \"hw.name\" semantic\n// conventions. It represents an easily-recognizable name for the hardware\n// component.\nfunc HwName(val string) attribute.KeyValue {\n\treturn HwNameKey.String(val)\n}\n\n// HwNetworkLogicalAddresses returns an attribute KeyValue conforming to the\n// \"hw.network.logical_addresses\" semantic conventions. It represents the logical\n// addresses of the adapter (e.g. IP address, or WWPN).\nfunc HwNetworkLogicalAddresses(val ...string) attribute.KeyValue {\n\treturn HwNetworkLogicalAddressesKey.StringSlice(val)\n}\n\n// HwNetworkPhysicalAddress returns an attribute KeyValue conforming to the\n// \"hw.network.physical_address\" semantic conventions. It represents the physical\n// address of the adapter (e.g. MAC address, or WWNN).\nfunc HwNetworkPhysicalAddress(val string) attribute.KeyValue {\n\treturn HwNetworkPhysicalAddressKey.String(val)\n}\n\n// HwParent returns an attribute KeyValue conforming to the \"hw.parent\" semantic\n// conventions. It represents the unique identifier of the parent component\n// (typically the `hw.id` attribute of the enclosure, or disk controller).\nfunc HwParent(val string) attribute.KeyValue {\n\treturn HwParentKey.String(val)\n}\n\n// HwPhysicalDiskSmartAttribute returns an attribute KeyValue conforming to the\n// \"hw.physical_disk.smart_attribute\" semantic conventions. It represents the\n// [S.M.A.R.T.] (Self-Monitoring, Analysis, and Reporting Technology) attribute\n// of the physical disk.\n//\n// [S.M.A.R.T.]: https://wikipedia.org/wiki/S.M.A.R.T.\nfunc HwPhysicalDiskSmartAttribute(val string) attribute.KeyValue {\n\treturn HwPhysicalDiskSmartAttributeKey.String(val)\n}\n\n// HwPhysicalDiskType returns an attribute KeyValue conforming to the\n// \"hw.physical_disk.type\" semantic conventions. It represents the type of the\n// physical disk.\nfunc HwPhysicalDiskType(val string) attribute.KeyValue {\n\treturn HwPhysicalDiskTypeKey.String(val)\n}\n\n// HwSensorLocation returns an attribute KeyValue conforming to the\n// \"hw.sensor_location\" semantic conventions. It represents the location of the\n// sensor.\nfunc HwSensorLocation(val string) attribute.KeyValue {\n\treturn HwSensorLocationKey.String(val)\n}\n\n// HwSerialNumber returns an attribute KeyValue conforming to the\n// \"hw.serial_number\" semantic conventions. It represents the serial number of\n// the hardware component.\nfunc HwSerialNumber(val string) attribute.KeyValue {\n\treturn HwSerialNumberKey.String(val)\n}\n\n// HwVendor returns an attribute KeyValue conforming to the \"hw.vendor\" semantic\n// conventions. It represents the vendor name of the hardware component.\nfunc HwVendor(val string) attribute.KeyValue {\n\treturn HwVendorKey.String(val)\n}\n\n// Enum values for hw.battery.state\nvar (\n\t// Charging\n\t// Stability: development\n\tHwBatteryStateCharging = HwBatteryStateKey.String(\"charging\")\n\t// Discharging\n\t// Stability: development\n\tHwBatteryStateDischarging = HwBatteryStateKey.String(\"discharging\")\n)\n\n// Enum values for hw.gpu.task\nvar (\n\t// Decoder\n\t// Stability: development\n\tHwGpuTaskDecoder = HwGpuTaskKey.String(\"decoder\")\n\t// Encoder\n\t// Stability: development\n\tHwGpuTaskEncoder = HwGpuTaskKey.String(\"encoder\")\n\t// General\n\t// Stability: development\n\tHwGpuTaskGeneral = HwGpuTaskKey.String(\"general\")\n)\n\n// Enum values for hw.limit_type\nvar (\n\t// Critical\n\t// Stability: development\n\tHwLimitTypeCritical = HwLimitTypeKey.String(\"critical\")\n\t// Degraded\n\t// Stability: development\n\tHwLimitTypeDegraded = HwLimitTypeKey.String(\"degraded\")\n\t// High Critical\n\t// Stability: development\n\tHwLimitTypeHighCritical = HwLimitTypeKey.String(\"high.critical\")\n\t// High Degraded\n\t// Stability: development\n\tHwLimitTypeHighDegraded = HwLimitTypeKey.String(\"high.degraded\")\n\t// Low Critical\n\t// Stability: development\n\tHwLimitTypeLowCritical = HwLimitTypeKey.String(\"low.critical\")\n\t// Low Degraded\n\t// Stability: development\n\tHwLimitTypeLowDegraded = HwLimitTypeKey.String(\"low.degraded\")\n\t// Maximum\n\t// Stability: development\n\tHwLimitTypeMax = HwLimitTypeKey.String(\"max\")\n\t// Throttled\n\t// Stability: development\n\tHwLimitTypeThrottled = HwLimitTypeKey.String(\"throttled\")\n\t// Turbo\n\t// Stability: development\n\tHwLimitTypeTurbo = HwLimitTypeKey.String(\"turbo\")\n)\n\n// Enum values for hw.logical_disk.state\nvar (\n\t// Used\n\t// Stability: development\n\tHwLogicalDiskStateUsed = HwLogicalDiskStateKey.String(\"used\")\n\t// Free\n\t// Stability: development\n\tHwLogicalDiskStateFree = HwLogicalDiskStateKey.String(\"free\")\n)\n\n// Enum values for hw.physical_disk.state\nvar (\n\t// Remaining\n\t// Stability: development\n\tHwPhysicalDiskStateRemaining = HwPhysicalDiskStateKey.String(\"remaining\")\n)\n\n// Enum values for hw.state\nvar (\n\t// Degraded\n\t// Stability: development\n\tHwStateDegraded = HwStateKey.String(\"degraded\")\n\t// Failed\n\t// Stability: development\n\tHwStateFailed = HwStateKey.String(\"failed\")\n\t// Needs Cleaning\n\t// Stability: development\n\tHwStateNeedsCleaning = HwStateKey.String(\"needs_cleaning\")\n\t// OK\n\t// Stability: development\n\tHwStateOk = HwStateKey.String(\"ok\")\n\t// Predicted Failure\n\t// Stability: development\n\tHwStatePredictedFailure = HwStateKey.String(\"predicted_failure\")\n)\n\n// Enum values for hw.tape_drive.operation_type\nvar (\n\t// Mount\n\t// Stability: development\n\tHwTapeDriveOperationTypeMount = HwTapeDriveOperationTypeKey.String(\"mount\")\n\t// Unmount\n\t// Stability: development\n\tHwTapeDriveOperationTypeUnmount = HwTapeDriveOperationTypeKey.String(\"unmount\")\n\t// Clean\n\t// Stability: development\n\tHwTapeDriveOperationTypeClean = HwTapeDriveOperationTypeKey.String(\"clean\")\n)\n\n// Enum values for hw.type\nvar (\n\t// Battery\n\t// Stability: development\n\tHwTypeBattery = HwTypeKey.String(\"battery\")\n\t// CPU\n\t// Stability: development\n\tHwTypeCPU = HwTypeKey.String(\"cpu\")\n\t// Disk controller\n\t// Stability: development\n\tHwTypeDiskController = HwTypeKey.String(\"disk_controller\")\n\t// Enclosure\n\t// Stability: development\n\tHwTypeEnclosure = HwTypeKey.String(\"enclosure\")\n\t// Fan\n\t// Stability: development\n\tHwTypeFan = HwTypeKey.String(\"fan\")\n\t// GPU\n\t// Stability: development\n\tHwTypeGpu = HwTypeKey.String(\"gpu\")\n\t// Logical disk\n\t// Stability: development\n\tHwTypeLogicalDisk = HwTypeKey.String(\"logical_disk\")\n\t// Memory\n\t// Stability: development\n\tHwTypeMemory = HwTypeKey.String(\"memory\")\n\t// Network\n\t// Stability: development\n\tHwTypeNetwork = HwTypeKey.String(\"network\")\n\t// Physical disk\n\t// Stability: development\n\tHwTypePhysicalDisk = HwTypeKey.String(\"physical_disk\")\n\t// Power supply\n\t// Stability: development\n\tHwTypePowerSupply = HwTypeKey.String(\"power_supply\")\n\t// Tape drive\n\t// Stability: development\n\tHwTypeTapeDrive = HwTypeKey.String(\"tape_drive\")\n\t// Temperature\n\t// Stability: development\n\tHwTypeTemperature = HwTypeKey.String(\"temperature\")\n\t// Voltage\n\t// Stability: development\n\tHwTypeVoltage = HwTypeKey.String(\"voltage\")\n)\n\n// Namespace: ios\nconst (\n\t// IOSAppStateKey is the attribute Key conforming to the \"ios.app.state\"\n\t// semantic conventions. It represents the this attribute represents the state\n\t// of the application.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: The iOS lifecycle states are defined in the\n\t// [UIApplicationDelegate documentation], and from which the `OS terminology`\n\t// column values are derived.\n\t//\n\t// [UIApplicationDelegate documentation]: https://developer.apple.com/documentation/uikit/uiapplicationdelegate\n\tIOSAppStateKey = attribute.Key(\"ios.app.state\")\n)\n\n// Enum values for ios.app.state\nvar (\n\t// The app has become `active`. Associated with UIKit notification\n\t// `applicationDidBecomeActive`.\n\t//\n\t// Stability: development\n\tIOSAppStateActive = IOSAppStateKey.String(\"active\")\n\t// The app is now `inactive`. Associated with UIKit notification\n\t// `applicationWillResignActive`.\n\t//\n\t// Stability: development\n\tIOSAppStateInactive = IOSAppStateKey.String(\"inactive\")\n\t// The app is now in the background. This value is associated with UIKit\n\t// notification `applicationDidEnterBackground`.\n\t//\n\t// Stability: development\n\tIOSAppStateBackground = IOSAppStateKey.String(\"background\")\n\t// The app is now in the foreground. This value is associated with UIKit\n\t// notification `applicationWillEnterForeground`.\n\t//\n\t// Stability: development\n\tIOSAppStateForeground = IOSAppStateKey.String(\"foreground\")\n\t// The app is about to terminate. Associated with UIKit notification\n\t// `applicationWillTerminate`.\n\t//\n\t// Stability: development\n\tIOSAppStateTerminate = IOSAppStateKey.String(\"terminate\")\n)\n\n// Namespace: k8s\nconst (\n\t// K8SClusterNameKey is the attribute Key conforming to the \"k8s.cluster.name\"\n\t// semantic conventions. It represents the name of the cluster.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry-cluster\"\n\tK8SClusterNameKey = attribute.Key(\"k8s.cluster.name\")\n\n\t// K8SClusterUIDKey is the attribute Key conforming to the \"k8s.cluster.uid\"\n\t// semantic conventions. It represents a pseudo-ID for the cluster, set to the\n\t// UID of the `kube-system` namespace.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"218fc5a9-a5f1-4b54-aa05-46717d0ab26d\"\n\t// Note: K8s doesn't have support for obtaining a cluster ID. If this is ever\n\t// added, we will recommend collecting the `k8s.cluster.uid` through the\n\t// official APIs. In the meantime, we are able to use the `uid` of the\n\t// `kube-system` namespace as a proxy for cluster ID. Read on for the\n\t// rationale.\n\t//\n\t// Every object created in a K8s cluster is assigned a distinct UID. The\n\t// `kube-system` namespace is used by Kubernetes itself and will exist\n\t// for the lifetime of the cluster. Using the `uid` of the `kube-system`\n\t// namespace is a reasonable proxy for the K8s ClusterID as it will only\n\t// change if the cluster is rebuilt. Furthermore, Kubernetes UIDs are\n\t// UUIDs as standardized by\n\t// [ISO/IEC 9834-8 and ITU-T X.667].\n\t// Which states:\n\t//\n\t// > If generated according to one of the mechanisms defined in Rec.\n\t// > ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be\n\t// > different from all other UUIDs generated before 3603 A.D., or is\n\t// > extremely likely to be different (depending on the mechanism chosen).\n\t//\n\t// Therefore, UIDs between clusters should be extremely unlikely to\n\t// conflict.\n\t//\n\t// [ISO/IEC 9834-8 and ITU-T X.667]: https://www.itu.int/ITU-T/studygroups/com17/oid.html\n\tK8SClusterUIDKey = attribute.Key(\"k8s.cluster.uid\")\n\n\t// K8SContainerNameKey is the attribute Key conforming to the\n\t// \"k8s.container.name\" semantic conventions. It represents the name of the\n\t// Container from Pod specification, must be unique within a Pod. Container\n\t// runtime usually uses different globally unique name (`container.name`).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"redis\"\n\tK8SContainerNameKey = attribute.Key(\"k8s.container.name\")\n\n\t// K8SContainerRestartCountKey is the attribute Key conforming to the\n\t// \"k8s.container.restart_count\" semantic conventions. It represents the number\n\t// of times the container was restarted. This attribute can be used to identify\n\t// a particular container (running or stopped) within a container spec.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tK8SContainerRestartCountKey = attribute.Key(\"k8s.container.restart_count\")\n\n\t// K8SContainerStatusLastTerminatedReasonKey is the attribute Key conforming to\n\t// the \"k8s.container.status.last_terminated_reason\" semantic conventions. It\n\t// represents the last terminated reason of the Container.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Evicted\", \"Error\"\n\tK8SContainerStatusLastTerminatedReasonKey = attribute.Key(\"k8s.container.status.last_terminated_reason\")\n\n\t// K8SContainerStatusReasonKey is the attribute Key conforming to the\n\t// \"k8s.container.status.reason\" semantic conventions. It represents the reason\n\t// for the container state. Corresponds to the `reason` field of the:\n\t// [K8s ContainerStateWaiting] or [K8s ContainerStateTerminated].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"ContainerCreating\", \"CrashLoopBackOff\",\n\t// \"CreateContainerConfigError\", \"ErrImagePull\", \"ImagePullBackOff\",\n\t// \"OOMKilled\", \"Completed\", \"Error\", \"ContainerCannotRun\"\n\t//\n\t// [K8s ContainerStateWaiting]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#containerstatewaiting-v1-core\n\t// [K8s ContainerStateTerminated]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#containerstateterminated-v1-core\n\tK8SContainerStatusReasonKey = attribute.Key(\"k8s.container.status.reason\")\n\n\t// K8SContainerStatusStateKey is the attribute Key conforming to the\n\t// \"k8s.container.status.state\" semantic conventions. It represents the state of\n\t// the container. [K8s ContainerState].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"terminated\", \"running\", \"waiting\"\n\t//\n\t// [K8s ContainerState]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#containerstate-v1-core\n\tK8SContainerStatusStateKey = attribute.Key(\"k8s.container.status.state\")\n\n\t// K8SCronJobNameKey is the attribute Key conforming to the \"k8s.cronjob.name\"\n\t// semantic conventions. It represents the name of the CronJob.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SCronJobNameKey = attribute.Key(\"k8s.cronjob.name\")\n\n\t// K8SCronJobUIDKey is the attribute Key conforming to the \"k8s.cronjob.uid\"\n\t// semantic conventions. It represents the UID of the CronJob.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SCronJobUIDKey = attribute.Key(\"k8s.cronjob.uid\")\n\n\t// K8SDaemonSetNameKey is the attribute Key conforming to the\n\t// \"k8s.daemonset.name\" semantic conventions. It represents the name of the\n\t// DaemonSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SDaemonSetNameKey = attribute.Key(\"k8s.daemonset.name\")\n\n\t// K8SDaemonSetUIDKey is the attribute Key conforming to the \"k8s.daemonset.uid\"\n\t// semantic conventions. It represents the UID of the DaemonSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SDaemonSetUIDKey = attribute.Key(\"k8s.daemonset.uid\")\n\n\t// K8SDeploymentNameKey is the attribute Key conforming to the\n\t// \"k8s.deployment.name\" semantic conventions. It represents the name of the\n\t// Deployment.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SDeploymentNameKey = attribute.Key(\"k8s.deployment.name\")\n\n\t// K8SDeploymentUIDKey is the attribute Key conforming to the\n\t// \"k8s.deployment.uid\" semantic conventions. It represents the UID of the\n\t// Deployment.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SDeploymentUIDKey = attribute.Key(\"k8s.deployment.uid\")\n\n\t// K8SHPAMetricTypeKey is the attribute Key conforming to the\n\t// \"k8s.hpa.metric.type\" semantic conventions. It represents the type of metric\n\t// source for the horizontal pod autoscaler.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Resource\", \"ContainerResource\"\n\t// Note: This attribute reflects the `type` field of spec.metrics[] in the HPA.\n\tK8SHPAMetricTypeKey = attribute.Key(\"k8s.hpa.metric.type\")\n\n\t// K8SHPANameKey is the attribute Key conforming to the \"k8s.hpa.name\" semantic\n\t// conventions. It represents the name of the horizontal pod autoscaler.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SHPANameKey = attribute.Key(\"k8s.hpa.name\")\n\n\t// K8SHPAScaletargetrefAPIVersionKey is the attribute Key conforming to the\n\t// \"k8s.hpa.scaletargetref.api_version\" semantic conventions. It represents the\n\t// API version of the target resource to scale for the HorizontalPodAutoscaler.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"apps/v1\", \"autoscaling/v2\"\n\t// Note: This maps to the `apiVersion` field in the `scaleTargetRef` of the HPA\n\t// spec.\n\tK8SHPAScaletargetrefAPIVersionKey = attribute.Key(\"k8s.hpa.scaletargetref.api_version\")\n\n\t// K8SHPAScaletargetrefKindKey is the attribute Key conforming to the\n\t// \"k8s.hpa.scaletargetref.kind\" semantic conventions. It represents the kind of\n\t// the target resource to scale for the HorizontalPodAutoscaler.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Deployment\", \"StatefulSet\"\n\t// Note: This maps to the `kind` field in the `scaleTargetRef` of the HPA spec.\n\tK8SHPAScaletargetrefKindKey = attribute.Key(\"k8s.hpa.scaletargetref.kind\")\n\n\t// K8SHPAScaletargetrefNameKey is the attribute Key conforming to the\n\t// \"k8s.hpa.scaletargetref.name\" semantic conventions. It represents the name of\n\t// the target resource to scale for the HorizontalPodAutoscaler.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-deployment\", \"my-statefulset\"\n\t// Note: This maps to the `name` field in the `scaleTargetRef` of the HPA spec.\n\tK8SHPAScaletargetrefNameKey = attribute.Key(\"k8s.hpa.scaletargetref.name\")\n\n\t// K8SHPAUIDKey is the attribute Key conforming to the \"k8s.hpa.uid\" semantic\n\t// conventions. It represents the UID of the horizontal pod autoscaler.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SHPAUIDKey = attribute.Key(\"k8s.hpa.uid\")\n\n\t// K8SHugepageSizeKey is the attribute Key conforming to the \"k8s.hugepage.size\"\n\t// semantic conventions. It represents the size (identifier) of the K8s huge\n\t// page.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2Mi\"\n\tK8SHugepageSizeKey = attribute.Key(\"k8s.hugepage.size\")\n\n\t// K8SJobNameKey is the attribute Key conforming to the \"k8s.job.name\" semantic\n\t// conventions. It represents the name of the Job.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SJobNameKey = attribute.Key(\"k8s.job.name\")\n\n\t// K8SJobUIDKey is the attribute Key conforming to the \"k8s.job.uid\" semantic\n\t// conventions. It represents the UID of the Job.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SJobUIDKey = attribute.Key(\"k8s.job.uid\")\n\n\t// K8SNamespaceNameKey is the attribute Key conforming to the\n\t// \"k8s.namespace.name\" semantic conventions. It represents the name of the\n\t// namespace that the pod is running in.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"default\"\n\tK8SNamespaceNameKey = attribute.Key(\"k8s.namespace.name\")\n\n\t// K8SNamespacePhaseKey is the attribute Key conforming to the\n\t// \"k8s.namespace.phase\" semantic conventions. It represents the phase of the\n\t// K8s namespace.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"active\", \"terminating\"\n\t// Note: This attribute aligns with the `phase` field of the\n\t// [K8s NamespaceStatus]\n\t//\n\t// [K8s NamespaceStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#namespacestatus-v1-core\n\tK8SNamespacePhaseKey = attribute.Key(\"k8s.namespace.phase\")\n\n\t// K8SNodeConditionStatusKey is the attribute Key conforming to the\n\t// \"k8s.node.condition.status\" semantic conventions. It represents the status of\n\t// the condition, one of True, False, Unknown.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"true\", \"false\", \"unknown\"\n\t// Note: This attribute aligns with the `status` field of the\n\t// [NodeCondition]\n\t//\n\t// [NodeCondition]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#nodecondition-v1-core\n\tK8SNodeConditionStatusKey = attribute.Key(\"k8s.node.condition.status\")\n\n\t// K8SNodeConditionTypeKey is the attribute Key conforming to the\n\t// \"k8s.node.condition.type\" semantic conventions. It represents the condition\n\t// type of a K8s Node.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Ready\", \"DiskPressure\"\n\t// Note: K8s Node conditions as described\n\t// by [K8s documentation].\n\t//\n\t// This attribute aligns with the `type` field of the\n\t// [NodeCondition]\n\t//\n\t// The set of possible values is not limited to those listed here. Managed\n\t// Kubernetes environments,\n\t// or custom controllers MAY introduce additional node condition types.\n\t// When this occurs, the exact value as reported by the Kubernetes API SHOULD be\n\t// used.\n\t//\n\t// [K8s documentation]: https://v1-32.docs.kubernetes.io/docs/reference/node/node-status/#condition\n\t// [NodeCondition]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#nodecondition-v1-core\n\tK8SNodeConditionTypeKey = attribute.Key(\"k8s.node.condition.type\")\n\n\t// K8SNodeNameKey is the attribute Key conforming to the \"k8s.node.name\"\n\t// semantic conventions. It represents the name of the Node.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"node-1\"\n\tK8SNodeNameKey = attribute.Key(\"k8s.node.name\")\n\n\t// K8SNodeUIDKey is the attribute Key conforming to the \"k8s.node.uid\" semantic\n\t// conventions. It represents the UID of the Node.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2\"\n\tK8SNodeUIDKey = attribute.Key(\"k8s.node.uid\")\n\n\t// K8SPodNameKey is the attribute Key conforming to the \"k8s.pod.name\" semantic\n\t// conventions. It represents the name of the Pod.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry-pod-autoconf\"\n\tK8SPodNameKey = attribute.Key(\"k8s.pod.name\")\n\n\t// K8SPodUIDKey is the attribute Key conforming to the \"k8s.pod.uid\" semantic\n\t// conventions. It represents the UID of the Pod.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SPodUIDKey = attribute.Key(\"k8s.pod.uid\")\n\n\t// K8SReplicaSetNameKey is the attribute Key conforming to the\n\t// \"k8s.replicaset.name\" semantic conventions. It represents the name of the\n\t// ReplicaSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SReplicaSetNameKey = attribute.Key(\"k8s.replicaset.name\")\n\n\t// K8SReplicaSetUIDKey is the attribute Key conforming to the\n\t// \"k8s.replicaset.uid\" semantic conventions. It represents the UID of the\n\t// ReplicaSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SReplicaSetUIDKey = attribute.Key(\"k8s.replicaset.uid\")\n\n\t// K8SReplicationControllerNameKey is the attribute Key conforming to the\n\t// \"k8s.replicationcontroller.name\" semantic conventions. It represents the name\n\t// of the replication controller.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SReplicationControllerNameKey = attribute.Key(\"k8s.replicationcontroller.name\")\n\n\t// K8SReplicationControllerUIDKey is the attribute Key conforming to the\n\t// \"k8s.replicationcontroller.uid\" semantic conventions. It represents the UID\n\t// of the replication controller.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SReplicationControllerUIDKey = attribute.Key(\"k8s.replicationcontroller.uid\")\n\n\t// K8SResourceQuotaNameKey is the attribute Key conforming to the\n\t// \"k8s.resourcequota.name\" semantic conventions. It represents the name of the\n\t// resource quota.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SResourceQuotaNameKey = attribute.Key(\"k8s.resourcequota.name\")\n\n\t// K8SResourceQuotaResourceNameKey is the attribute Key conforming to the\n\t// \"k8s.resourcequota.resource_name\" semantic conventions. It represents the\n\t// name of the K8s resource a resource quota defines.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"count/replicationcontrollers\"\n\t// Note: The value for this attribute can be either the full\n\t// `count/<resource>[.<group>]` string (e.g., count/deployments.apps,\n\t// count/pods), or, for certain core Kubernetes resources, just the resource\n\t// name (e.g., pods, services, configmaps). Both forms are supported by\n\t// Kubernetes for object count quotas. See\n\t// [Kubernetes Resource Quotas documentation] for more details.\n\t//\n\t// [Kubernetes Resource Quotas documentation]: https://kubernetes.io/docs/concepts/policy/resource-quotas/#object-count-quota\n\tK8SResourceQuotaResourceNameKey = attribute.Key(\"k8s.resourcequota.resource_name\")\n\n\t// K8SResourceQuotaUIDKey is the attribute Key conforming to the\n\t// \"k8s.resourcequota.uid\" semantic conventions. It represents the UID of the\n\t// resource quota.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SResourceQuotaUIDKey = attribute.Key(\"k8s.resourcequota.uid\")\n\n\t// K8SStatefulSetNameKey is the attribute Key conforming to the\n\t// \"k8s.statefulset.name\" semantic conventions. It represents the name of the\n\t// StatefulSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SStatefulSetNameKey = attribute.Key(\"k8s.statefulset.name\")\n\n\t// K8SStatefulSetUIDKey is the attribute Key conforming to the\n\t// \"k8s.statefulset.uid\" semantic conventions. It represents the UID of the\n\t// StatefulSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SStatefulSetUIDKey = attribute.Key(\"k8s.statefulset.uid\")\n\n\t// K8SStorageclassNameKey is the attribute Key conforming to the\n\t// \"k8s.storageclass.name\" semantic conventions. It represents the name of K8s\n\t// [StorageClass] object.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"gold.storageclass.storage.k8s.io\"\n\t//\n\t// [StorageClass]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#storageclass-v1-storage-k8s-io\n\tK8SStorageclassNameKey = attribute.Key(\"k8s.storageclass.name\")\n\n\t// K8SVolumeNameKey is the attribute Key conforming to the \"k8s.volume.name\"\n\t// semantic conventions. It represents the name of the K8s volume.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"volume0\"\n\tK8SVolumeNameKey = attribute.Key(\"k8s.volume.name\")\n\n\t// K8SVolumeTypeKey is the attribute Key conforming to the \"k8s.volume.type\"\n\t// semantic conventions. It represents the type of the K8s volume.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"emptyDir\", \"persistentVolumeClaim\"\n\tK8SVolumeTypeKey = attribute.Key(\"k8s.volume.type\")\n)\n\n// K8SClusterName returns an attribute KeyValue conforming to the\n// \"k8s.cluster.name\" semantic conventions. It represents the name of the\n// cluster.\nfunc K8SClusterName(val string) attribute.KeyValue {\n\treturn K8SClusterNameKey.String(val)\n}\n\n// K8SClusterUID returns an attribute KeyValue conforming to the\n// \"k8s.cluster.uid\" semantic conventions. It represents a pseudo-ID for the\n// cluster, set to the UID of the `kube-system` namespace.\nfunc K8SClusterUID(val string) attribute.KeyValue {\n\treturn K8SClusterUIDKey.String(val)\n}\n\n// K8SContainerName returns an attribute KeyValue conforming to the\n// \"k8s.container.name\" semantic conventions. It represents the name of the\n// Container from Pod specification, must be unique within a Pod. Container\n// runtime usually uses different globally unique name (`container.name`).\nfunc K8SContainerName(val string) attribute.KeyValue {\n\treturn K8SContainerNameKey.String(val)\n}\n\n// K8SContainerRestartCount returns an attribute KeyValue conforming to the\n// \"k8s.container.restart_count\" semantic conventions. It represents the number\n// of times the container was restarted. This attribute can be used to identify a\n// particular container (running or stopped) within a container spec.\nfunc K8SContainerRestartCount(val int) attribute.KeyValue {\n\treturn K8SContainerRestartCountKey.Int(val)\n}\n\n// K8SContainerStatusLastTerminatedReason returns an attribute KeyValue\n// conforming to the \"k8s.container.status.last_terminated_reason\" semantic\n// conventions. It represents the last terminated reason of the Container.\nfunc K8SContainerStatusLastTerminatedReason(val string) attribute.KeyValue {\n\treturn K8SContainerStatusLastTerminatedReasonKey.String(val)\n}\n\n// K8SCronJobAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.cronjob.annotation\" semantic conventions. It represents the cronjob\n// annotation placed on the CronJob, the `<key>` being the annotation name, the\n// value being the annotation value.\nfunc K8SCronJobAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.cronjob.annotation.\"+key, val)\n}\n\n// K8SCronJobLabel returns an attribute KeyValue conforming to the\n// \"k8s.cronjob.label\" semantic conventions. It represents the label placed on\n// the CronJob, the `<key>` being the label name, the value being the label\n// value.\nfunc K8SCronJobLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.cronjob.label.\"+key, val)\n}\n\n// K8SCronJobName returns an attribute KeyValue conforming to the\n// \"k8s.cronjob.name\" semantic conventions. It represents the name of the\n// CronJob.\nfunc K8SCronJobName(val string) attribute.KeyValue {\n\treturn K8SCronJobNameKey.String(val)\n}\n\n// K8SCronJobUID returns an attribute KeyValue conforming to the\n// \"k8s.cronjob.uid\" semantic conventions. It represents the UID of the CronJob.\nfunc K8SCronJobUID(val string) attribute.KeyValue {\n\treturn K8SCronJobUIDKey.String(val)\n}\n\n// K8SDaemonSetAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.daemonset.annotation\" semantic conventions. It represents the annotation\n// placed on the DaemonSet, the `<key>` being the annotation name, the value\n// being the annotation value, even if the value is empty.\nfunc K8SDaemonSetAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.daemonset.annotation.\"+key, val)\n}\n\n// K8SDaemonSetLabel returns an attribute KeyValue conforming to the\n// \"k8s.daemonset.label\" semantic conventions. It represents the label placed on\n// the DaemonSet, the `<key>` being the label name, the value being the label\n// value, even if the value is empty.\nfunc K8SDaemonSetLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.daemonset.label.\"+key, val)\n}\n\n// K8SDaemonSetName returns an attribute KeyValue conforming to the\n// \"k8s.daemonset.name\" semantic conventions. It represents the name of the\n// DaemonSet.\nfunc K8SDaemonSetName(val string) attribute.KeyValue {\n\treturn K8SDaemonSetNameKey.String(val)\n}\n\n// K8SDaemonSetUID returns an attribute KeyValue conforming to the\n// \"k8s.daemonset.uid\" semantic conventions. It represents the UID of the\n// DaemonSet.\nfunc K8SDaemonSetUID(val string) attribute.KeyValue {\n\treturn K8SDaemonSetUIDKey.String(val)\n}\n\n// K8SDeploymentAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.deployment.annotation\" semantic conventions. It represents the annotation\n// placed on the Deployment, the `<key>` being the annotation name, the value\n// being the annotation value, even if the value is empty.\nfunc K8SDeploymentAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.deployment.annotation.\"+key, val)\n}\n\n// K8SDeploymentLabel returns an attribute KeyValue conforming to the\n// \"k8s.deployment.label\" semantic conventions. It represents the label placed on\n// the Deployment, the `<key>` being the label name, the value being the label\n// value, even if the value is empty.\nfunc K8SDeploymentLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.deployment.label.\"+key, val)\n}\n\n// K8SDeploymentName returns an attribute KeyValue conforming to the\n// \"k8s.deployment.name\" semantic conventions. It represents the name of the\n// Deployment.\nfunc K8SDeploymentName(val string) attribute.KeyValue {\n\treturn K8SDeploymentNameKey.String(val)\n}\n\n// K8SDeploymentUID returns an attribute KeyValue conforming to the\n// \"k8s.deployment.uid\" semantic conventions. It represents the UID of the\n// Deployment.\nfunc K8SDeploymentUID(val string) attribute.KeyValue {\n\treturn K8SDeploymentUIDKey.String(val)\n}\n\n// K8SHPAMetricType returns an attribute KeyValue conforming to the\n// \"k8s.hpa.metric.type\" semantic conventions. It represents the type of metric\n// source for the horizontal pod autoscaler.\nfunc K8SHPAMetricType(val string) attribute.KeyValue {\n\treturn K8SHPAMetricTypeKey.String(val)\n}\n\n// K8SHPAName returns an attribute KeyValue conforming to the \"k8s.hpa.name\"\n// semantic conventions. It represents the name of the horizontal pod autoscaler.\nfunc K8SHPAName(val string) attribute.KeyValue {\n\treturn K8SHPANameKey.String(val)\n}\n\n// K8SHPAScaletargetrefAPIVersion returns an attribute KeyValue conforming to the\n// \"k8s.hpa.scaletargetref.api_version\" semantic conventions. It represents the\n// API version of the target resource to scale for the HorizontalPodAutoscaler.\nfunc K8SHPAScaletargetrefAPIVersion(val string) attribute.KeyValue {\n\treturn K8SHPAScaletargetrefAPIVersionKey.String(val)\n}\n\n// K8SHPAScaletargetrefKind returns an attribute KeyValue conforming to the\n// \"k8s.hpa.scaletargetref.kind\" semantic conventions. It represents the kind of\n// the target resource to scale for the HorizontalPodAutoscaler.\nfunc K8SHPAScaletargetrefKind(val string) attribute.KeyValue {\n\treturn K8SHPAScaletargetrefKindKey.String(val)\n}\n\n// K8SHPAScaletargetrefName returns an attribute KeyValue conforming to the\n// \"k8s.hpa.scaletargetref.name\" semantic conventions. It represents the name of\n// the target resource to scale for the HorizontalPodAutoscaler.\nfunc K8SHPAScaletargetrefName(val string) attribute.KeyValue {\n\treturn K8SHPAScaletargetrefNameKey.String(val)\n}\n\n// K8SHPAUID returns an attribute KeyValue conforming to the \"k8s.hpa.uid\"\n// semantic conventions. It represents the UID of the horizontal pod autoscaler.\nfunc K8SHPAUID(val string) attribute.KeyValue {\n\treturn K8SHPAUIDKey.String(val)\n}\n\n// K8SHugepageSize returns an attribute KeyValue conforming to the\n// \"k8s.hugepage.size\" semantic conventions. It represents the size (identifier)\n// of the K8s huge page.\nfunc K8SHugepageSize(val string) attribute.KeyValue {\n\treturn K8SHugepageSizeKey.String(val)\n}\n\n// K8SJobAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.job.annotation\" semantic conventions. It represents the annotation placed\n// on the Job, the `<key>` being the annotation name, the value being the\n// annotation value, even if the value is empty.\nfunc K8SJobAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.job.annotation.\"+key, val)\n}\n\n// K8SJobLabel returns an attribute KeyValue conforming to the \"k8s.job.label\"\n// semantic conventions. It represents the label placed on the Job, the `<key>`\n// being the label name, the value being the label value, even if the value is\n// empty.\nfunc K8SJobLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.job.label.\"+key, val)\n}\n\n// K8SJobName returns an attribute KeyValue conforming to the \"k8s.job.name\"\n// semantic conventions. It represents the name of the Job.\nfunc K8SJobName(val string) attribute.KeyValue {\n\treturn K8SJobNameKey.String(val)\n}\n\n// K8SJobUID returns an attribute KeyValue conforming to the \"k8s.job.uid\"\n// semantic conventions. It represents the UID of the Job.\nfunc K8SJobUID(val string) attribute.KeyValue {\n\treturn K8SJobUIDKey.String(val)\n}\n\n// K8SNamespaceAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.namespace.annotation\" semantic conventions. It represents the annotation\n// placed on the Namespace, the `<key>` being the annotation name, the value\n// being the annotation value, even if the value is empty.\nfunc K8SNamespaceAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.namespace.annotation.\"+key, val)\n}\n\n// K8SNamespaceLabel returns an attribute KeyValue conforming to the\n// \"k8s.namespace.label\" semantic conventions. It represents the label placed on\n// the Namespace, the `<key>` being the label name, the value being the label\n// value, even if the value is empty.\nfunc K8SNamespaceLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.namespace.label.\"+key, val)\n}\n\n// K8SNamespaceName returns an attribute KeyValue conforming to the\n// \"k8s.namespace.name\" semantic conventions. It represents the name of the\n// namespace that the pod is running in.\nfunc K8SNamespaceName(val string) attribute.KeyValue {\n\treturn K8SNamespaceNameKey.String(val)\n}\n\n// K8SNodeAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.node.annotation\" semantic conventions. It represents the annotation\n// placed on the Node, the `<key>` being the annotation name, the value being the\n// annotation value, even if the value is empty.\nfunc K8SNodeAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.node.annotation.\"+key, val)\n}\n\n// K8SNodeLabel returns an attribute KeyValue conforming to the \"k8s.node.label\"\n// semantic conventions. It represents the label placed on the Node, the `<key>`\n// being the label name, the value being the label value, even if the value is\n// empty.\nfunc K8SNodeLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.node.label.\"+key, val)\n}\n\n// K8SNodeName returns an attribute KeyValue conforming to the \"k8s.node.name\"\n// semantic conventions. It represents the name of the Node.\nfunc K8SNodeName(val string) attribute.KeyValue {\n\treturn K8SNodeNameKey.String(val)\n}\n\n// K8SNodeUID returns an attribute KeyValue conforming to the \"k8s.node.uid\"\n// semantic conventions. It represents the UID of the Node.\nfunc K8SNodeUID(val string) attribute.KeyValue {\n\treturn K8SNodeUIDKey.String(val)\n}\n\n// K8SPodAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.pod.annotation\" semantic conventions. It represents the annotation placed\n// on the Pod, the `<key>` being the annotation name, the value being the\n// annotation value.\nfunc K8SPodAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.pod.annotation.\"+key, val)\n}\n\n// K8SPodLabel returns an attribute KeyValue conforming to the \"k8s.pod.label\"\n// semantic conventions. It represents the label placed on the Pod, the `<key>`\n// being the label name, the value being the label value.\nfunc K8SPodLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.pod.label.\"+key, val)\n}\n\n// K8SPodName returns an attribute KeyValue conforming to the \"k8s.pod.name\"\n// semantic conventions. It represents the name of the Pod.\nfunc K8SPodName(val string) attribute.KeyValue {\n\treturn K8SPodNameKey.String(val)\n}\n\n// K8SPodUID returns an attribute KeyValue conforming to the \"k8s.pod.uid\"\n// semantic conventions. It represents the UID of the Pod.\nfunc K8SPodUID(val string) attribute.KeyValue {\n\treturn K8SPodUIDKey.String(val)\n}\n\n// K8SReplicaSetAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.replicaset.annotation\" semantic conventions. It represents the annotation\n// placed on the ReplicaSet, the `<key>` being the annotation name, the value\n// being the annotation value, even if the value is empty.\nfunc K8SReplicaSetAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.replicaset.annotation.\"+key, val)\n}\n\n// K8SReplicaSetLabel returns an attribute KeyValue conforming to the\n// \"k8s.replicaset.label\" semantic conventions. It represents the label placed on\n// the ReplicaSet, the `<key>` being the label name, the value being the label\n// value, even if the value is empty.\nfunc K8SReplicaSetLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.replicaset.label.\"+key, val)\n}\n\n// K8SReplicaSetName returns an attribute KeyValue conforming to the\n// \"k8s.replicaset.name\" semantic conventions. It represents the name of the\n// ReplicaSet.\nfunc K8SReplicaSetName(val string) attribute.KeyValue {\n\treturn K8SReplicaSetNameKey.String(val)\n}\n\n// K8SReplicaSetUID returns an attribute KeyValue conforming to the\n// \"k8s.replicaset.uid\" semantic conventions. It represents the UID of the\n// ReplicaSet.\nfunc K8SReplicaSetUID(val string) attribute.KeyValue {\n\treturn K8SReplicaSetUIDKey.String(val)\n}\n\n// K8SReplicationControllerName returns an attribute KeyValue conforming to the\n// \"k8s.replicationcontroller.name\" semantic conventions. It represents the name\n// of the replication controller.\nfunc K8SReplicationControllerName(val string) attribute.KeyValue {\n\treturn K8SReplicationControllerNameKey.String(val)\n}\n\n// K8SReplicationControllerUID returns an attribute KeyValue conforming to the\n// \"k8s.replicationcontroller.uid\" semantic conventions. It represents the UID of\n// the replication controller.\nfunc K8SReplicationControllerUID(val string) attribute.KeyValue {\n\treturn K8SReplicationControllerUIDKey.String(val)\n}\n\n// K8SResourceQuotaName returns an attribute KeyValue conforming to the\n// \"k8s.resourcequota.name\" semantic conventions. It represents the name of the\n// resource quota.\nfunc K8SResourceQuotaName(val string) attribute.KeyValue {\n\treturn K8SResourceQuotaNameKey.String(val)\n}\n\n// K8SResourceQuotaResourceName returns an attribute KeyValue conforming to the\n// \"k8s.resourcequota.resource_name\" semantic conventions. It represents the name\n// of the K8s resource a resource quota defines.\nfunc K8SResourceQuotaResourceName(val string) attribute.KeyValue {\n\treturn K8SResourceQuotaResourceNameKey.String(val)\n}\n\n// K8SResourceQuotaUID returns an attribute KeyValue conforming to the\n// \"k8s.resourcequota.uid\" semantic conventions. It represents the UID of the\n// resource quota.\nfunc K8SResourceQuotaUID(val string) attribute.KeyValue {\n\treturn K8SResourceQuotaUIDKey.String(val)\n}\n\n// K8SStatefulSetAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.statefulset.annotation\" semantic conventions. It represents the\n// annotation placed on the StatefulSet, the `<key>` being the annotation name,\n// the value being the annotation value, even if the value is empty.\nfunc K8SStatefulSetAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.statefulset.annotation.\"+key, val)\n}\n\n// K8SStatefulSetLabel returns an attribute KeyValue conforming to the\n// \"k8s.statefulset.label\" semantic conventions. It represents the label placed\n// on the StatefulSet, the `<key>` being the label name, the value being the\n// label value, even if the value is empty.\nfunc K8SStatefulSetLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.statefulset.label.\"+key, val)\n}\n\n// K8SStatefulSetName returns an attribute KeyValue conforming to the\n// \"k8s.statefulset.name\" semantic conventions. It represents the name of the\n// StatefulSet.\nfunc K8SStatefulSetName(val string) attribute.KeyValue {\n\treturn K8SStatefulSetNameKey.String(val)\n}\n\n// K8SStatefulSetUID returns an attribute KeyValue conforming to the\n// \"k8s.statefulset.uid\" semantic conventions. It represents the UID of the\n// StatefulSet.\nfunc K8SStatefulSetUID(val string) attribute.KeyValue {\n\treturn K8SStatefulSetUIDKey.String(val)\n}\n\n// K8SStorageclassName returns an attribute KeyValue conforming to the\n// \"k8s.storageclass.name\" semantic conventions. It represents the name of K8s\n// [StorageClass] object.\n//\n// [StorageClass]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#storageclass-v1-storage-k8s-io\nfunc K8SStorageclassName(val string) attribute.KeyValue {\n\treturn K8SStorageclassNameKey.String(val)\n}\n\n// K8SVolumeName returns an attribute KeyValue conforming to the\n// \"k8s.volume.name\" semantic conventions. It represents the name of the K8s\n// volume.\nfunc K8SVolumeName(val string) attribute.KeyValue {\n\treturn K8SVolumeNameKey.String(val)\n}\n\n// Enum values for k8s.container.status.reason\nvar (\n\t// The container is being created.\n\t// Stability: development\n\tK8SContainerStatusReasonContainerCreating = K8SContainerStatusReasonKey.String(\"ContainerCreating\")\n\t// The container is in a crash loop back off state.\n\t// Stability: development\n\tK8SContainerStatusReasonCrashLoopBackOff = K8SContainerStatusReasonKey.String(\"CrashLoopBackOff\")\n\t// There was an error creating the container configuration.\n\t// Stability: development\n\tK8SContainerStatusReasonCreateContainerConfigError = K8SContainerStatusReasonKey.String(\"CreateContainerConfigError\")\n\t// There was an error pulling the container image.\n\t// Stability: development\n\tK8SContainerStatusReasonErrImagePull = K8SContainerStatusReasonKey.String(\"ErrImagePull\")\n\t// The container image pull is in back off state.\n\t// Stability: development\n\tK8SContainerStatusReasonImagePullBackOff = K8SContainerStatusReasonKey.String(\"ImagePullBackOff\")\n\t// The container was killed due to out of memory.\n\t// Stability: development\n\tK8SContainerStatusReasonOomKilled = K8SContainerStatusReasonKey.String(\"OOMKilled\")\n\t// The container has completed execution.\n\t// Stability: development\n\tK8SContainerStatusReasonCompleted = K8SContainerStatusReasonKey.String(\"Completed\")\n\t// There was an error with the container.\n\t// Stability: development\n\tK8SContainerStatusReasonError = K8SContainerStatusReasonKey.String(\"Error\")\n\t// The container cannot run.\n\t// Stability: development\n\tK8SContainerStatusReasonContainerCannotRun = K8SContainerStatusReasonKey.String(\"ContainerCannotRun\")\n)\n\n// Enum values for k8s.container.status.state\nvar (\n\t// The container has terminated.\n\t// Stability: development\n\tK8SContainerStatusStateTerminated = K8SContainerStatusStateKey.String(\"terminated\")\n\t// The container is running.\n\t// Stability: development\n\tK8SContainerStatusStateRunning = K8SContainerStatusStateKey.String(\"running\")\n\t// The container is waiting.\n\t// Stability: development\n\tK8SContainerStatusStateWaiting = K8SContainerStatusStateKey.String(\"waiting\")\n)\n\n// Enum values for k8s.namespace.phase\nvar (\n\t// Active namespace phase as described by [K8s API]\n\t// Stability: development\n\t//\n\t// [K8s API]: https://pkg.go.dev/k8s.io/api@v0.31.3/core/v1#NamespacePhase\n\tK8SNamespacePhaseActive = K8SNamespacePhaseKey.String(\"active\")\n\t// Terminating namespace phase as described by [K8s API]\n\t// Stability: development\n\t//\n\t// [K8s API]: https://pkg.go.dev/k8s.io/api@v0.31.3/core/v1#NamespacePhase\n\tK8SNamespacePhaseTerminating = K8SNamespacePhaseKey.String(\"terminating\")\n)\n\n// Enum values for k8s.node.condition.status\nvar (\n\t// condition_true\n\t// Stability: development\n\tK8SNodeConditionStatusConditionTrue = K8SNodeConditionStatusKey.String(\"true\")\n\t// condition_false\n\t// Stability: development\n\tK8SNodeConditionStatusConditionFalse = K8SNodeConditionStatusKey.String(\"false\")\n\t// condition_unknown\n\t// Stability: development\n\tK8SNodeConditionStatusConditionUnknown = K8SNodeConditionStatusKey.String(\"unknown\")\n)\n\n// Enum values for k8s.node.condition.type\nvar (\n\t// The node is healthy and ready to accept pods\n\t// Stability: development\n\tK8SNodeConditionTypeReady = K8SNodeConditionTypeKey.String(\"Ready\")\n\t// Pressure exists on the disk size—that is, if the disk capacity is low\n\t// Stability: development\n\tK8SNodeConditionTypeDiskPressure = K8SNodeConditionTypeKey.String(\"DiskPressure\")\n\t// Pressure exists on the node memory—that is, if the node memory is low\n\t// Stability: development\n\tK8SNodeConditionTypeMemoryPressure = K8SNodeConditionTypeKey.String(\"MemoryPressure\")\n\t// Pressure exists on the processes—that is, if there are too many processes\n\t// on the node\n\t// Stability: development\n\tK8SNodeConditionTypePIDPressure = K8SNodeConditionTypeKey.String(\"PIDPressure\")\n\t// The network for the node is not correctly configured\n\t// Stability: development\n\tK8SNodeConditionTypeNetworkUnavailable = K8SNodeConditionTypeKey.String(\"NetworkUnavailable\")\n)\n\n// Enum values for k8s.volume.type\nvar (\n\t// A [persistentVolumeClaim] volume\n\t// Stability: development\n\t//\n\t// [persistentVolumeClaim]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#persistentvolumeclaim\n\tK8SVolumeTypePersistentVolumeClaim = K8SVolumeTypeKey.String(\"persistentVolumeClaim\")\n\t// A [configMap] volume\n\t// Stability: development\n\t//\n\t// [configMap]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#configmap\n\tK8SVolumeTypeConfigMap = K8SVolumeTypeKey.String(\"configMap\")\n\t// A [downwardAPI] volume\n\t// Stability: development\n\t//\n\t// [downwardAPI]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#downwardapi\n\tK8SVolumeTypeDownwardAPI = K8SVolumeTypeKey.String(\"downwardAPI\")\n\t// An [emptyDir] volume\n\t// Stability: development\n\t//\n\t// [emptyDir]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#emptydir\n\tK8SVolumeTypeEmptyDir = K8SVolumeTypeKey.String(\"emptyDir\")\n\t// A [secret] volume\n\t// Stability: development\n\t//\n\t// [secret]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#secret\n\tK8SVolumeTypeSecret = K8SVolumeTypeKey.String(\"secret\")\n\t// A [local] volume\n\t// Stability: development\n\t//\n\t// [local]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#local\n\tK8SVolumeTypeLocal = K8SVolumeTypeKey.String(\"local\")\n)\n\n// Namespace: linux\nconst (\n\t// LinuxMemorySlabStateKey is the attribute Key conforming to the\n\t// \"linux.memory.slab.state\" semantic conventions. It represents the Linux Slab\n\t// memory state.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"reclaimable\", \"unreclaimable\"\n\tLinuxMemorySlabStateKey = attribute.Key(\"linux.memory.slab.state\")\n)\n\n// Enum values for linux.memory.slab.state\nvar (\n\t// reclaimable\n\t// Stability: development\n\tLinuxMemorySlabStateReclaimable = LinuxMemorySlabStateKey.String(\"reclaimable\")\n\t// unreclaimable\n\t// Stability: development\n\tLinuxMemorySlabStateUnreclaimable = LinuxMemorySlabStateKey.String(\"unreclaimable\")\n)\n\n// Namespace: log\nconst (\n\t// LogFileNameKey is the attribute Key conforming to the \"log.file.name\"\n\t// semantic conventions. It represents the basename of the file.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"audit.log\"\n\tLogFileNameKey = attribute.Key(\"log.file.name\")\n\n\t// LogFileNameResolvedKey is the attribute Key conforming to the\n\t// \"log.file.name_resolved\" semantic conventions. It represents the basename of\n\t// the file, with symlinks resolved.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"uuid.log\"\n\tLogFileNameResolvedKey = attribute.Key(\"log.file.name_resolved\")\n\n\t// LogFilePathKey is the attribute Key conforming to the \"log.file.path\"\n\t// semantic conventions. It represents the full path to the file.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/var/log/mysql/audit.log\"\n\tLogFilePathKey = attribute.Key(\"log.file.path\")\n\n\t// LogFilePathResolvedKey is the attribute Key conforming to the\n\t// \"log.file.path_resolved\" semantic conventions. It represents the full path to\n\t// the file, with symlinks resolved.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/var/lib/docker/uuid.log\"\n\tLogFilePathResolvedKey = attribute.Key(\"log.file.path_resolved\")\n\n\t// LogIostreamKey is the attribute Key conforming to the \"log.iostream\" semantic\n\t// conventions. It represents the stream associated with the log. See below for\n\t// a list of well-known values.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tLogIostreamKey = attribute.Key(\"log.iostream\")\n\n\t// LogRecordOriginalKey is the attribute Key conforming to the\n\t// \"log.record.original\" semantic conventions. It represents the complete\n\t// original Log Record.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"77 <86>1 2015-08-06T21:58:59.694Z 192.168.2.133 inactive - - -\n\t// Something happened\", \"[INFO] 8/3/24 12:34:56 Something happened\"\n\t// Note: This value MAY be added when processing a Log Record which was\n\t// originally transmitted as a string or equivalent data type AND the Body field\n\t// of the Log Record does not contain the same value. (e.g. a syslog or a log\n\t// record read from a file.)\n\tLogRecordOriginalKey = attribute.Key(\"log.record.original\")\n\n\t// LogRecordUIDKey is the attribute Key conforming to the \"log.record.uid\"\n\t// semantic conventions. It represents a unique identifier for the Log Record.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"01ARZ3NDEKTSV4RRFFQ69G5FAV\"\n\t// Note: If an id is provided, other log records with the same id will be\n\t// considered duplicates and can be removed safely. This means, that two\n\t// distinguishable log records MUST have different values.\n\t// The id MAY be an\n\t// [Universally Unique Lexicographically Sortable Identifier (ULID)], but other\n\t// identifiers (e.g. UUID) may be used as needed.\n\t//\n\t// [Universally Unique Lexicographically Sortable Identifier (ULID)]: https://github.com/ulid/spec\n\tLogRecordUIDKey = attribute.Key(\"log.record.uid\")\n)\n\n// LogFileName returns an attribute KeyValue conforming to the \"log.file.name\"\n// semantic conventions. It represents the basename of the file.\nfunc LogFileName(val string) attribute.KeyValue {\n\treturn LogFileNameKey.String(val)\n}\n\n// LogFileNameResolved returns an attribute KeyValue conforming to the\n// \"log.file.name_resolved\" semantic conventions. It represents the basename of\n// the file, with symlinks resolved.\nfunc LogFileNameResolved(val string) attribute.KeyValue {\n\treturn LogFileNameResolvedKey.String(val)\n}\n\n// LogFilePath returns an attribute KeyValue conforming to the \"log.file.path\"\n// semantic conventions. It represents the full path to the file.\nfunc LogFilePath(val string) attribute.KeyValue {\n\treturn LogFilePathKey.String(val)\n}\n\n// LogFilePathResolved returns an attribute KeyValue conforming to the\n// \"log.file.path_resolved\" semantic conventions. It represents the full path to\n// the file, with symlinks resolved.\nfunc LogFilePathResolved(val string) attribute.KeyValue {\n\treturn LogFilePathResolvedKey.String(val)\n}\n\n// LogRecordOriginal returns an attribute KeyValue conforming to the\n// \"log.record.original\" semantic conventions. It represents the complete\n// original Log Record.\nfunc LogRecordOriginal(val string) attribute.KeyValue {\n\treturn LogRecordOriginalKey.String(val)\n}\n\n// LogRecordUID returns an attribute KeyValue conforming to the \"log.record.uid\"\n// semantic conventions. It represents a unique identifier for the Log Record.\nfunc LogRecordUID(val string) attribute.KeyValue {\n\treturn LogRecordUIDKey.String(val)\n}\n\n// Enum values for log.iostream\nvar (\n\t// Logs from stdout stream\n\t// Stability: development\n\tLogIostreamStdout = LogIostreamKey.String(\"stdout\")\n\t// Events from stderr stream\n\t// Stability: development\n\tLogIostreamStderr = LogIostreamKey.String(\"stderr\")\n)\n\n// Namespace: mainframe\nconst (\n\t// MainframeLparNameKey is the attribute Key conforming to the\n\t// \"mainframe.lpar.name\" semantic conventions. It represents the name of the\n\t// logical partition that hosts a systems with a mainframe operating system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"LPAR01\"\n\tMainframeLparNameKey = attribute.Key(\"mainframe.lpar.name\")\n)\n\n// MainframeLparName returns an attribute KeyValue conforming to the\n// \"mainframe.lpar.name\" semantic conventions. It represents the name of the\n// logical partition that hosts a systems with a mainframe operating system.\nfunc MainframeLparName(val string) attribute.KeyValue {\n\treturn MainframeLparNameKey.String(val)\n}\n\n// Namespace: messaging\nconst (\n\t// MessagingBatchMessageCountKey is the attribute Key conforming to the\n\t// \"messaging.batch.message_count\" semantic conventions. It represents the\n\t// number of messages sent, received, or processed in the scope of the batching\n\t// operation.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0, 1, 2\n\t// Note: Instrumentations SHOULD NOT set `messaging.batch.message_count` on\n\t// spans that operate with a single message. When a messaging client library\n\t// supports both batch and single-message API for the same operation,\n\t// instrumentations SHOULD use `messaging.batch.message_count` for batching APIs\n\t// and SHOULD NOT use it for single-message APIs.\n\tMessagingBatchMessageCountKey = attribute.Key(\"messaging.batch.message_count\")\n\n\t// MessagingClientIDKey is the attribute Key conforming to the\n\t// \"messaging.client.id\" semantic conventions. It represents a unique identifier\n\t// for the client that consumes or produces a message.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"client-5\", \"myhost@8742@s8083jm\"\n\tMessagingClientIDKey = attribute.Key(\"messaging.client.id\")\n\n\t// MessagingConsumerGroupNameKey is the attribute Key conforming to the\n\t// \"messaging.consumer.group.name\" semantic conventions. It represents the name\n\t// of the consumer group with which a consumer is associated.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-group\", \"indexer\"\n\t// Note: Semantic conventions for individual messaging systems SHOULD document\n\t// whether `messaging.consumer.group.name` is applicable and what it means in\n\t// the context of that system.\n\tMessagingConsumerGroupNameKey = attribute.Key(\"messaging.consumer.group.name\")\n\n\t// MessagingDestinationAnonymousKey is the attribute Key conforming to the\n\t// \"messaging.destination.anonymous\" semantic conventions. It represents a\n\t// boolean that is true if the message destination is anonymous (could be\n\t// unnamed or have auto-generated name).\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tMessagingDestinationAnonymousKey = attribute.Key(\"messaging.destination.anonymous\")\n\n\t// MessagingDestinationNameKey is the attribute Key conforming to the\n\t// \"messaging.destination.name\" semantic conventions. It represents the message\n\t// destination name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"MyQueue\", \"MyTopic\"\n\t// Note: Destination name SHOULD uniquely identify a specific queue, topic or\n\t// other entity within the broker. If\n\t// the broker doesn't have such notion, the destination name SHOULD uniquely\n\t// identify the broker.\n\tMessagingDestinationNameKey = attribute.Key(\"messaging.destination.name\")\n\n\t// MessagingDestinationPartitionIDKey is the attribute Key conforming to the\n\t// \"messaging.destination.partition.id\" semantic conventions. It represents the\n\t// identifier of the partition messages are sent to or received from, unique\n\t// within the `messaging.destination.name`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1\n\tMessagingDestinationPartitionIDKey = attribute.Key(\"messaging.destination.partition.id\")\n\n\t// MessagingDestinationSubscriptionNameKey is the attribute Key conforming to\n\t// the \"messaging.destination.subscription.name\" semantic conventions. It\n\t// represents the name of the destination subscription from which a message is\n\t// consumed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"subscription-a\"\n\t// Note: Semantic conventions for individual messaging systems SHOULD document\n\t// whether `messaging.destination.subscription.name` is applicable and what it\n\t// means in the context of that system.\n\tMessagingDestinationSubscriptionNameKey = attribute.Key(\"messaging.destination.subscription.name\")\n\n\t// MessagingDestinationTemplateKey is the attribute Key conforming to the\n\t// \"messaging.destination.template\" semantic conventions. It represents the low\n\t// cardinality representation of the messaging destination name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/customers/{customerId}\"\n\t// Note: Destination names could be constructed from templates. An example would\n\t// be a destination name involving a user name or product id. Although the\n\t// destination name in this case is of high cardinality, the underlying template\n\t// is of low cardinality and can be effectively used for grouping and\n\t// aggregation.\n\tMessagingDestinationTemplateKey = attribute.Key(\"messaging.destination.template\")\n\n\t// MessagingDestinationTemporaryKey is the attribute Key conforming to the\n\t// \"messaging.destination.temporary\" semantic conventions. It represents a\n\t// boolean that is true if the message destination is temporary and might not\n\t// exist anymore after messages are processed.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tMessagingDestinationTemporaryKey = attribute.Key(\"messaging.destination.temporary\")\n\n\t// MessagingEventHubsMessageEnqueuedTimeKey is the attribute Key conforming to\n\t// the \"messaging.eventhubs.message.enqueued_time\" semantic conventions. It\n\t// represents the UTC epoch seconds at which the message has been accepted and\n\t// stored in the entity.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingEventHubsMessageEnqueuedTimeKey = attribute.Key(\"messaging.eventhubs.message.enqueued_time\")\n\n\t// MessagingGCPPubSubMessageAckDeadlineKey is the attribute Key conforming to\n\t// the \"messaging.gcp_pubsub.message.ack_deadline\" semantic conventions. It\n\t// represents the ack deadline in seconds set for the modify ack deadline\n\t// request.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingGCPPubSubMessageAckDeadlineKey = attribute.Key(\"messaging.gcp_pubsub.message.ack_deadline\")\n\n\t// MessagingGCPPubSubMessageAckIDKey is the attribute Key conforming to the\n\t// \"messaging.gcp_pubsub.message.ack_id\" semantic conventions. It represents the\n\t// ack id for a given message.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: ack_id\n\tMessagingGCPPubSubMessageAckIDKey = attribute.Key(\"messaging.gcp_pubsub.message.ack_id\")\n\n\t// MessagingGCPPubSubMessageDeliveryAttemptKey is the attribute Key conforming\n\t// to the \"messaging.gcp_pubsub.message.delivery_attempt\" semantic conventions.\n\t// It represents the delivery attempt for a given message.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingGCPPubSubMessageDeliveryAttemptKey = attribute.Key(\"messaging.gcp_pubsub.message.delivery_attempt\")\n\n\t// MessagingGCPPubSubMessageOrderingKeyKey is the attribute Key conforming to\n\t// the \"messaging.gcp_pubsub.message.ordering_key\" semantic conventions. It\n\t// represents the ordering key for a given message. If the attribute is not\n\t// present, the message does not have an ordering key.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: ordering_key\n\tMessagingGCPPubSubMessageOrderingKeyKey = attribute.Key(\"messaging.gcp_pubsub.message.ordering_key\")\n\n\t// MessagingKafkaMessageKeyKey is the attribute Key conforming to the\n\t// \"messaging.kafka.message.key\" semantic conventions. It represents the message\n\t// keys in Kafka are used for grouping alike messages to ensure they're\n\t// processed on the same partition. They differ from `messaging.message.id` in\n\t// that they're not unique. If the key is `null`, the attribute MUST NOT be set.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: myKey\n\t// Note: If the key type is not string, it's string representation has to be\n\t// supplied for the attribute. If the key has no unambiguous, canonical string\n\t// form, don't include its value.\n\tMessagingKafkaMessageKeyKey = attribute.Key(\"messaging.kafka.message.key\")\n\n\t// MessagingKafkaMessageTombstoneKey is the attribute Key conforming to the\n\t// \"messaging.kafka.message.tombstone\" semantic conventions. It represents a\n\t// boolean that is true if the message is a tombstone.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tMessagingKafkaMessageTombstoneKey = attribute.Key(\"messaging.kafka.message.tombstone\")\n\n\t// MessagingKafkaOffsetKey is the attribute Key conforming to the\n\t// \"messaging.kafka.offset\" semantic conventions. It represents the offset of a\n\t// record in the corresponding Kafka partition.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingKafkaOffsetKey = attribute.Key(\"messaging.kafka.offset\")\n\n\t// MessagingMessageBodySizeKey is the attribute Key conforming to the\n\t// \"messaging.message.body.size\" semantic conventions. It represents the size of\n\t// the message body in bytes.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Note: This can refer to both the compressed or uncompressed body size. If\n\t// both sizes are known, the uncompressed\n\t// body size should be used.\n\tMessagingMessageBodySizeKey = attribute.Key(\"messaging.message.body.size\")\n\n\t// MessagingMessageConversationIDKey is the attribute Key conforming to the\n\t// \"messaging.message.conversation_id\" semantic conventions. It represents the\n\t// conversation ID identifying the conversation to which the message belongs,\n\t// represented as a string. Sometimes called \"Correlation ID\".\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: MyConversationId\n\tMessagingMessageConversationIDKey = attribute.Key(\"messaging.message.conversation_id\")\n\n\t// MessagingMessageEnvelopeSizeKey is the attribute Key conforming to the\n\t// \"messaging.message.envelope.size\" semantic conventions. It represents the\n\t// size of the message body and metadata in bytes.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Note: This can refer to both the compressed or uncompressed size. If both\n\t// sizes are known, the uncompressed\n\t// size should be used.\n\tMessagingMessageEnvelopeSizeKey = attribute.Key(\"messaging.message.envelope.size\")\n\n\t// MessagingMessageIDKey is the attribute Key conforming to the\n\t// \"messaging.message.id\" semantic conventions. It represents a value used by\n\t// the messaging system as an identifier for the message, represented as a\n\t// string.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 452a7c7c7c7048c2f887f61572b18fc2\n\tMessagingMessageIDKey = attribute.Key(\"messaging.message.id\")\n\n\t// MessagingOperationNameKey is the attribute Key conforming to the\n\t// \"messaging.operation.name\" semantic conventions. It represents the\n\t// system-specific name of the messaging operation.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"ack\", \"nack\", \"send\"\n\tMessagingOperationNameKey = attribute.Key(\"messaging.operation.name\")\n\n\t// MessagingOperationTypeKey is the attribute Key conforming to the\n\t// \"messaging.operation.type\" semantic conventions. It represents a string\n\t// identifying the type of the messaging operation.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: If a custom value is used, it MUST be of low cardinality.\n\tMessagingOperationTypeKey = attribute.Key(\"messaging.operation.type\")\n\n\t// MessagingRabbitMQDestinationRoutingKeyKey is the attribute Key conforming to\n\t// the \"messaging.rabbitmq.destination.routing_key\" semantic conventions. It\n\t// represents the rabbitMQ message routing key.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: myKey\n\tMessagingRabbitMQDestinationRoutingKeyKey = attribute.Key(\"messaging.rabbitmq.destination.routing_key\")\n\n\t// MessagingRabbitMQMessageDeliveryTagKey is the attribute Key conforming to the\n\t// \"messaging.rabbitmq.message.delivery_tag\" semantic conventions. It represents\n\t// the rabbitMQ message delivery tag.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingRabbitMQMessageDeliveryTagKey = attribute.Key(\"messaging.rabbitmq.message.delivery_tag\")\n\n\t// MessagingRocketMQConsumptionModelKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.consumption_model\" semantic conventions. It represents\n\t// the model of message consumption. This only applies to consumer spans.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tMessagingRocketMQConsumptionModelKey = attribute.Key(\"messaging.rocketmq.consumption_model\")\n\n\t// MessagingRocketMQMessageDelayTimeLevelKey is the attribute Key conforming to\n\t// the \"messaging.rocketmq.message.delay_time_level\" semantic conventions. It\n\t// represents the delay time level for delay message, which determines the\n\t// message delay time.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingRocketMQMessageDelayTimeLevelKey = attribute.Key(\"messaging.rocketmq.message.delay_time_level\")\n\n\t// MessagingRocketMQMessageDeliveryTimestampKey is the attribute Key conforming\n\t// to the \"messaging.rocketmq.message.delivery_timestamp\" semantic conventions.\n\t// It represents the timestamp in milliseconds that the delay message is\n\t// expected to be delivered to consumer.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingRocketMQMessageDeliveryTimestampKey = attribute.Key(\"messaging.rocketmq.message.delivery_timestamp\")\n\n\t// MessagingRocketMQMessageGroupKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.message.group\" semantic conventions. It represents the it\n\t// is essential for FIFO message. Messages that belong to the same message group\n\t// are always processed one by one within the same consumer group.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: myMessageGroup\n\tMessagingRocketMQMessageGroupKey = attribute.Key(\"messaging.rocketmq.message.group\")\n\n\t// MessagingRocketMQMessageKeysKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.message.keys\" semantic conventions. It represents the\n\t// key(s) of message, another way to mark message besides message id.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"keyA\", \"keyB\"\n\tMessagingRocketMQMessageKeysKey = attribute.Key(\"messaging.rocketmq.message.keys\")\n\n\t// MessagingRocketMQMessageTagKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.message.tag\" semantic conventions. It represents the\n\t// secondary classifier of message besides topic.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: tagA\n\tMessagingRocketMQMessageTagKey = attribute.Key(\"messaging.rocketmq.message.tag\")\n\n\t// MessagingRocketMQMessageTypeKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.message.type\" semantic conventions. It represents the\n\t// type of message.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tMessagingRocketMQMessageTypeKey = attribute.Key(\"messaging.rocketmq.message.type\")\n\n\t// MessagingRocketMQNamespaceKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.namespace\" semantic conventions. It represents the\n\t// namespace of RocketMQ resources, resources in different namespaces are\n\t// individual.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: myNamespace\n\tMessagingRocketMQNamespaceKey = attribute.Key(\"messaging.rocketmq.namespace\")\n\n\t// MessagingServiceBusDispositionStatusKey is the attribute Key conforming to\n\t// the \"messaging.servicebus.disposition_status\" semantic conventions. It\n\t// represents the describes the [settlement type].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t//\n\t// [settlement type]: https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock\n\tMessagingServiceBusDispositionStatusKey = attribute.Key(\"messaging.servicebus.disposition_status\")\n\n\t// MessagingServiceBusMessageDeliveryCountKey is the attribute Key conforming to\n\t// the \"messaging.servicebus.message.delivery_count\" semantic conventions. It\n\t// represents the number of deliveries that have been attempted for this\n\t// message.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingServiceBusMessageDeliveryCountKey = attribute.Key(\"messaging.servicebus.message.delivery_count\")\n\n\t// MessagingServiceBusMessageEnqueuedTimeKey is the attribute Key conforming to\n\t// the \"messaging.servicebus.message.enqueued_time\" semantic conventions. It\n\t// represents the UTC epoch seconds at which the message has been accepted and\n\t// stored in the entity.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingServiceBusMessageEnqueuedTimeKey = attribute.Key(\"messaging.servicebus.message.enqueued_time\")\n\n\t// MessagingSystemKey is the attribute Key conforming to the \"messaging.system\"\n\t// semantic conventions. It represents the messaging system as identified by the\n\t// client instrumentation.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: The actual messaging system may differ from the one known by the\n\t// client. For example, when using Kafka client libraries to communicate with\n\t// Azure Event Hubs, the `messaging.system` is set to `kafka` based on the\n\t// instrumentation's best knowledge.\n\tMessagingSystemKey = attribute.Key(\"messaging.system\")\n)\n\n// MessagingBatchMessageCount returns an attribute KeyValue conforming to the\n// \"messaging.batch.message_count\" semantic conventions. It represents the number\n// of messages sent, received, or processed in the scope of the batching\n// operation.\nfunc MessagingBatchMessageCount(val int) attribute.KeyValue {\n\treturn MessagingBatchMessageCountKey.Int(val)\n}\n\n// MessagingClientID returns an attribute KeyValue conforming to the\n// \"messaging.client.id\" semantic conventions. It represents a unique identifier\n// for the client that consumes or produces a message.\nfunc MessagingClientID(val string) attribute.KeyValue {\n\treturn MessagingClientIDKey.String(val)\n}\n\n// MessagingConsumerGroupName returns an attribute KeyValue conforming to the\n// \"messaging.consumer.group.name\" semantic conventions. It represents the name\n// of the consumer group with which a consumer is associated.\nfunc MessagingConsumerGroupName(val string) attribute.KeyValue {\n\treturn MessagingConsumerGroupNameKey.String(val)\n}\n\n// MessagingDestinationAnonymous returns an attribute KeyValue conforming to the\n// \"messaging.destination.anonymous\" semantic conventions. It represents a\n// boolean that is true if the message destination is anonymous (could be unnamed\n// or have auto-generated name).\nfunc MessagingDestinationAnonymous(val bool) attribute.KeyValue {\n\treturn MessagingDestinationAnonymousKey.Bool(val)\n}\n\n// MessagingDestinationName returns an attribute KeyValue conforming to the\n// \"messaging.destination.name\" semantic conventions. It represents the message\n// destination name.\nfunc MessagingDestinationName(val string) attribute.KeyValue {\n\treturn MessagingDestinationNameKey.String(val)\n}\n\n// MessagingDestinationPartitionID returns an attribute KeyValue conforming to\n// the \"messaging.destination.partition.id\" semantic conventions. It represents\n// the identifier of the partition messages are sent to or received from, unique\n// within the `messaging.destination.name`.\nfunc MessagingDestinationPartitionID(val string) attribute.KeyValue {\n\treturn MessagingDestinationPartitionIDKey.String(val)\n}\n\n// MessagingDestinationSubscriptionName returns an attribute KeyValue conforming\n// to the \"messaging.destination.subscription.name\" semantic conventions. It\n// represents the name of the destination subscription from which a message is\n// consumed.\nfunc MessagingDestinationSubscriptionName(val string) attribute.KeyValue {\n\treturn MessagingDestinationSubscriptionNameKey.String(val)\n}\n\n// MessagingDestinationTemplate returns an attribute KeyValue conforming to the\n// \"messaging.destination.template\" semantic conventions. It represents the low\n// cardinality representation of the messaging destination name.\nfunc MessagingDestinationTemplate(val string) attribute.KeyValue {\n\treturn MessagingDestinationTemplateKey.String(val)\n}\n\n// MessagingDestinationTemporary returns an attribute KeyValue conforming to the\n// \"messaging.destination.temporary\" semantic conventions. It represents a\n// boolean that is true if the message destination is temporary and might not\n// exist anymore after messages are processed.\nfunc MessagingDestinationTemporary(val bool) attribute.KeyValue {\n\treturn MessagingDestinationTemporaryKey.Bool(val)\n}\n\n// MessagingEventHubsMessageEnqueuedTime returns an attribute KeyValue conforming\n// to the \"messaging.eventhubs.message.enqueued_time\" semantic conventions. It\n// represents the UTC epoch seconds at which the message has been accepted and\n// stored in the entity.\nfunc MessagingEventHubsMessageEnqueuedTime(val int) attribute.KeyValue {\n\treturn MessagingEventHubsMessageEnqueuedTimeKey.Int(val)\n}\n\n// MessagingGCPPubSubMessageAckDeadline returns an attribute KeyValue conforming\n// to the \"messaging.gcp_pubsub.message.ack_deadline\" semantic conventions. It\n// represents the ack deadline in seconds set for the modify ack deadline\n// request.\nfunc MessagingGCPPubSubMessageAckDeadline(val int) attribute.KeyValue {\n\treturn MessagingGCPPubSubMessageAckDeadlineKey.Int(val)\n}\n\n// MessagingGCPPubSubMessageAckID returns an attribute KeyValue conforming to the\n// \"messaging.gcp_pubsub.message.ack_id\" semantic conventions. It represents the\n// ack id for a given message.\nfunc MessagingGCPPubSubMessageAckID(val string) attribute.KeyValue {\n\treturn MessagingGCPPubSubMessageAckIDKey.String(val)\n}\n\n// MessagingGCPPubSubMessageDeliveryAttempt returns an attribute KeyValue\n// conforming to the \"messaging.gcp_pubsub.message.delivery_attempt\" semantic\n// conventions. It represents the delivery attempt for a given message.\nfunc MessagingGCPPubSubMessageDeliveryAttempt(val int) attribute.KeyValue {\n\treturn MessagingGCPPubSubMessageDeliveryAttemptKey.Int(val)\n}\n\n// MessagingGCPPubSubMessageOrderingKey returns an attribute KeyValue conforming\n// to the \"messaging.gcp_pubsub.message.ordering_key\" semantic conventions. It\n// represents the ordering key for a given message. If the attribute is not\n// present, the message does not have an ordering key.\nfunc MessagingGCPPubSubMessageOrderingKey(val string) attribute.KeyValue {\n\treturn MessagingGCPPubSubMessageOrderingKeyKey.String(val)\n}\n\n// MessagingKafkaMessageKey returns an attribute KeyValue conforming to the\n// \"messaging.kafka.message.key\" semantic conventions. It represents the message\n// keys in Kafka are used for grouping alike messages to ensure they're processed\n// on the same partition. They differ from `messaging.message.id` in that they're\n// not unique. If the key is `null`, the attribute MUST NOT be set.\nfunc MessagingKafkaMessageKey(val string) attribute.KeyValue {\n\treturn MessagingKafkaMessageKeyKey.String(val)\n}\n\n// MessagingKafkaMessageTombstone returns an attribute KeyValue conforming to the\n// \"messaging.kafka.message.tombstone\" semantic conventions. It represents a\n// boolean that is true if the message is a tombstone.\nfunc MessagingKafkaMessageTombstone(val bool) attribute.KeyValue {\n\treturn MessagingKafkaMessageTombstoneKey.Bool(val)\n}\n\n// MessagingKafkaOffset returns an attribute KeyValue conforming to the\n// \"messaging.kafka.offset\" semantic conventions. It represents the offset of a\n// record in the corresponding Kafka partition.\nfunc MessagingKafkaOffset(val int) attribute.KeyValue {\n\treturn MessagingKafkaOffsetKey.Int(val)\n}\n\n// MessagingMessageBodySize returns an attribute KeyValue conforming to the\n// \"messaging.message.body.size\" semantic conventions. It represents the size of\n// the message body in bytes.\nfunc MessagingMessageBodySize(val int) attribute.KeyValue {\n\treturn MessagingMessageBodySizeKey.Int(val)\n}\n\n// MessagingMessageConversationID returns an attribute KeyValue conforming to the\n// \"messaging.message.conversation_id\" semantic conventions. It represents the\n// conversation ID identifying the conversation to which the message belongs,\n// represented as a string. Sometimes called \"Correlation ID\".\nfunc MessagingMessageConversationID(val string) attribute.KeyValue {\n\treturn MessagingMessageConversationIDKey.String(val)\n}\n\n// MessagingMessageEnvelopeSize returns an attribute KeyValue conforming to the\n// \"messaging.message.envelope.size\" semantic conventions. It represents the size\n// of the message body and metadata in bytes.\nfunc MessagingMessageEnvelopeSize(val int) attribute.KeyValue {\n\treturn MessagingMessageEnvelopeSizeKey.Int(val)\n}\n\n// MessagingMessageID returns an attribute KeyValue conforming to the\n// \"messaging.message.id\" semantic conventions. It represents a value used by the\n// messaging system as an identifier for the message, represented as a string.\nfunc MessagingMessageID(val string) attribute.KeyValue {\n\treturn MessagingMessageIDKey.String(val)\n}\n\n// MessagingOperationName returns an attribute KeyValue conforming to the\n// \"messaging.operation.name\" semantic conventions. It represents the\n// system-specific name of the messaging operation.\nfunc MessagingOperationName(val string) attribute.KeyValue {\n\treturn MessagingOperationNameKey.String(val)\n}\n\n// MessagingRabbitMQDestinationRoutingKey returns an attribute KeyValue\n// conforming to the \"messaging.rabbitmq.destination.routing_key\" semantic\n// conventions. It represents the rabbitMQ message routing key.\nfunc MessagingRabbitMQDestinationRoutingKey(val string) attribute.KeyValue {\n\treturn MessagingRabbitMQDestinationRoutingKeyKey.String(val)\n}\n\n// MessagingRabbitMQMessageDeliveryTag returns an attribute KeyValue conforming\n// to the \"messaging.rabbitmq.message.delivery_tag\" semantic conventions. It\n// represents the rabbitMQ message delivery tag.\nfunc MessagingRabbitMQMessageDeliveryTag(val int) attribute.KeyValue {\n\treturn MessagingRabbitMQMessageDeliveryTagKey.Int(val)\n}\n\n// MessagingRocketMQMessageDelayTimeLevel returns an attribute KeyValue\n// conforming to the \"messaging.rocketmq.message.delay_time_level\" semantic\n// conventions. It represents the delay time level for delay message, which\n// determines the message delay time.\nfunc MessagingRocketMQMessageDelayTimeLevel(val int) attribute.KeyValue {\n\treturn MessagingRocketMQMessageDelayTimeLevelKey.Int(val)\n}\n\n// MessagingRocketMQMessageDeliveryTimestamp returns an attribute KeyValue\n// conforming to the \"messaging.rocketmq.message.delivery_timestamp\" semantic\n// conventions. It represents the timestamp in milliseconds that the delay\n// message is expected to be delivered to consumer.\nfunc MessagingRocketMQMessageDeliveryTimestamp(val int) attribute.KeyValue {\n\treturn MessagingRocketMQMessageDeliveryTimestampKey.Int(val)\n}\n\n// MessagingRocketMQMessageGroup returns an attribute KeyValue conforming to the\n// \"messaging.rocketmq.message.group\" semantic conventions. It represents the it\n// is essential for FIFO message. Messages that belong to the same message group\n// are always processed one by one within the same consumer group.\nfunc MessagingRocketMQMessageGroup(val string) attribute.KeyValue {\n\treturn MessagingRocketMQMessageGroupKey.String(val)\n}\n\n// MessagingRocketMQMessageKeys returns an attribute KeyValue conforming to the\n// \"messaging.rocketmq.message.keys\" semantic conventions. It represents the\n// key(s) of message, another way to mark message besides message id.\nfunc MessagingRocketMQMessageKeys(val ...string) attribute.KeyValue {\n\treturn MessagingRocketMQMessageKeysKey.StringSlice(val)\n}\n\n// MessagingRocketMQMessageTag returns an attribute KeyValue conforming to the\n// \"messaging.rocketmq.message.tag\" semantic conventions. It represents the\n// secondary classifier of message besides topic.\nfunc MessagingRocketMQMessageTag(val string) attribute.KeyValue {\n\treturn MessagingRocketMQMessageTagKey.String(val)\n}\n\n// MessagingRocketMQNamespace returns an attribute KeyValue conforming to the\n// \"messaging.rocketmq.namespace\" semantic conventions. It represents the\n// namespace of RocketMQ resources, resources in different namespaces are\n// individual.\nfunc MessagingRocketMQNamespace(val string) attribute.KeyValue {\n\treturn MessagingRocketMQNamespaceKey.String(val)\n}\n\n// MessagingServiceBusMessageDeliveryCount returns an attribute KeyValue\n// conforming to the \"messaging.servicebus.message.delivery_count\" semantic\n// conventions. It represents the number of deliveries that have been attempted\n// for this message.\nfunc MessagingServiceBusMessageDeliveryCount(val int) attribute.KeyValue {\n\treturn MessagingServiceBusMessageDeliveryCountKey.Int(val)\n}\n\n// MessagingServiceBusMessageEnqueuedTime returns an attribute KeyValue\n// conforming to the \"messaging.servicebus.message.enqueued_time\" semantic\n// conventions. It represents the UTC epoch seconds at which the message has been\n// accepted and stored in the entity.\nfunc MessagingServiceBusMessageEnqueuedTime(val int) attribute.KeyValue {\n\treturn MessagingServiceBusMessageEnqueuedTimeKey.Int(val)\n}\n\n// Enum values for messaging.operation.type\nvar (\n\t// A message is created. \"Create\" spans always refer to a single message and are\n\t// used to provide a unique creation context for messages in batch sending\n\t// scenarios.\n\t//\n\t// Stability: development\n\tMessagingOperationTypeCreate = MessagingOperationTypeKey.String(\"create\")\n\t// One or more messages are provided for sending to an intermediary. If a single\n\t// message is sent, the context of the \"Send\" span can be used as the creation\n\t// context and no \"Create\" span needs to be created.\n\t//\n\t// Stability: development\n\tMessagingOperationTypeSend = MessagingOperationTypeKey.String(\"send\")\n\t// One or more messages are requested by a consumer. This operation refers to\n\t// pull-based scenarios, where consumers explicitly call methods of messaging\n\t// SDKs to receive messages.\n\t//\n\t// Stability: development\n\tMessagingOperationTypeReceive = MessagingOperationTypeKey.String(\"receive\")\n\t// One or more messages are processed by a consumer.\n\t//\n\t// Stability: development\n\tMessagingOperationTypeProcess = MessagingOperationTypeKey.String(\"process\")\n\t// One or more messages are settled.\n\t//\n\t// Stability: development\n\tMessagingOperationTypeSettle = MessagingOperationTypeKey.String(\"settle\")\n)\n\n// Enum values for messaging.rocketmq.consumption_model\nvar (\n\t// Clustering consumption model\n\t// Stability: development\n\tMessagingRocketMQConsumptionModelClustering = MessagingRocketMQConsumptionModelKey.String(\"clustering\")\n\t// Broadcasting consumption model\n\t// Stability: development\n\tMessagingRocketMQConsumptionModelBroadcasting = MessagingRocketMQConsumptionModelKey.String(\"broadcasting\")\n)\n\n// Enum values for messaging.rocketmq.message.type\nvar (\n\t// Normal message\n\t// Stability: development\n\tMessagingRocketMQMessageTypeNormal = MessagingRocketMQMessageTypeKey.String(\"normal\")\n\t// FIFO message\n\t// Stability: development\n\tMessagingRocketMQMessageTypeFifo = MessagingRocketMQMessageTypeKey.String(\"fifo\")\n\t// Delay message\n\t// Stability: development\n\tMessagingRocketMQMessageTypeDelay = MessagingRocketMQMessageTypeKey.String(\"delay\")\n\t// Transaction message\n\t// Stability: development\n\tMessagingRocketMQMessageTypeTransaction = MessagingRocketMQMessageTypeKey.String(\"transaction\")\n)\n\n// Enum values for messaging.servicebus.disposition_status\nvar (\n\t// Message is completed\n\t// Stability: development\n\tMessagingServiceBusDispositionStatusComplete = MessagingServiceBusDispositionStatusKey.String(\"complete\")\n\t// Message is abandoned\n\t// Stability: development\n\tMessagingServiceBusDispositionStatusAbandon = MessagingServiceBusDispositionStatusKey.String(\"abandon\")\n\t// Message is sent to dead letter queue\n\t// Stability: development\n\tMessagingServiceBusDispositionStatusDeadLetter = MessagingServiceBusDispositionStatusKey.String(\"dead_letter\")\n\t// Message is deferred\n\t// Stability: development\n\tMessagingServiceBusDispositionStatusDefer = MessagingServiceBusDispositionStatusKey.String(\"defer\")\n)\n\n// Enum values for messaging.system\nvar (\n\t// Apache ActiveMQ\n\t// Stability: development\n\tMessagingSystemActiveMQ = MessagingSystemKey.String(\"activemq\")\n\t// Amazon Simple Notification Service (SNS)\n\t// Stability: development\n\tMessagingSystemAWSSNS = MessagingSystemKey.String(\"aws.sns\")\n\t// Amazon Simple Queue Service (SQS)\n\t// Stability: development\n\tMessagingSystemAWSSQS = MessagingSystemKey.String(\"aws_sqs\")\n\t// Azure Event Grid\n\t// Stability: development\n\tMessagingSystemEventGrid = MessagingSystemKey.String(\"eventgrid\")\n\t// Azure Event Hubs\n\t// Stability: development\n\tMessagingSystemEventHubs = MessagingSystemKey.String(\"eventhubs\")\n\t// Azure Service Bus\n\t// Stability: development\n\tMessagingSystemServiceBus = MessagingSystemKey.String(\"servicebus\")\n\t// Google Cloud Pub/Sub\n\t// Stability: development\n\tMessagingSystemGCPPubSub = MessagingSystemKey.String(\"gcp_pubsub\")\n\t// Java Message Service\n\t// Stability: development\n\tMessagingSystemJMS = MessagingSystemKey.String(\"jms\")\n\t// Apache Kafka\n\t// Stability: development\n\tMessagingSystemKafka = MessagingSystemKey.String(\"kafka\")\n\t// RabbitMQ\n\t// Stability: development\n\tMessagingSystemRabbitMQ = MessagingSystemKey.String(\"rabbitmq\")\n\t// Apache RocketMQ\n\t// Stability: development\n\tMessagingSystemRocketMQ = MessagingSystemKey.String(\"rocketmq\")\n\t// Apache Pulsar\n\t// Stability: development\n\tMessagingSystemPulsar = MessagingSystemKey.String(\"pulsar\")\n)\n\n// Namespace: network\nconst (\n\t// NetworkCarrierICCKey is the attribute Key conforming to the\n\t// \"network.carrier.icc\" semantic conventions. It represents the ISO 3166-1\n\t// alpha-2 2-character country code associated with the mobile carrier network.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: DE\n\tNetworkCarrierICCKey = attribute.Key(\"network.carrier.icc\")\n\n\t// NetworkCarrierMCCKey is the attribute Key conforming to the\n\t// \"network.carrier.mcc\" semantic conventions. It represents the mobile carrier\n\t// country code.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 310\n\tNetworkCarrierMCCKey = attribute.Key(\"network.carrier.mcc\")\n\n\t// NetworkCarrierMNCKey is the attribute Key conforming to the\n\t// \"network.carrier.mnc\" semantic conventions. It represents the mobile carrier\n\t// network code.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 001\n\tNetworkCarrierMNCKey = attribute.Key(\"network.carrier.mnc\")\n\n\t// NetworkCarrierNameKey is the attribute Key conforming to the\n\t// \"network.carrier.name\" semantic conventions. It represents the name of the\n\t// mobile carrier.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: sprint\n\tNetworkCarrierNameKey = attribute.Key(\"network.carrier.name\")\n\n\t// NetworkConnectionStateKey is the attribute Key conforming to the\n\t// \"network.connection.state\" semantic conventions. It represents the state of\n\t// network connection.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"close_wait\"\n\t// Note: Connection states are defined as part of the [rfc9293]\n\t//\n\t// [rfc9293]: https://datatracker.ietf.org/doc/html/rfc9293#section-3.3.2\n\tNetworkConnectionStateKey = attribute.Key(\"network.connection.state\")\n\n\t// NetworkConnectionSubtypeKey is the attribute Key conforming to the\n\t// \"network.connection.subtype\" semantic conventions. It represents the this\n\t// describes more details regarding the connection.type. It may be the type of\n\t// cell technology connection, but it could be used for describing details about\n\t// a wifi connection.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: LTE\n\tNetworkConnectionSubtypeKey = attribute.Key(\"network.connection.subtype\")\n\n\t// NetworkConnectionTypeKey is the attribute Key conforming to the\n\t// \"network.connection.type\" semantic conventions. It represents the internet\n\t// connection type.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: wifi\n\tNetworkConnectionTypeKey = attribute.Key(\"network.connection.type\")\n\n\t// NetworkInterfaceNameKey is the attribute Key conforming to the\n\t// \"network.interface.name\" semantic conventions. It represents the network\n\t// interface name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"lo\", \"eth0\"\n\tNetworkInterfaceNameKey = attribute.Key(\"network.interface.name\")\n\n\t// NetworkIODirectionKey is the attribute Key conforming to the\n\t// \"network.io.direction\" semantic conventions. It represents the network IO\n\t// operation direction.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"transmit\"\n\tNetworkIODirectionKey = attribute.Key(\"network.io.direction\")\n\n\t// NetworkLocalAddressKey is the attribute Key conforming to the\n\t// \"network.local.address\" semantic conventions. It represents the local address\n\t// of the network connection - IP address or Unix domain socket name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"10.1.2.80\", \"/tmp/my.sock\"\n\tNetworkLocalAddressKey = attribute.Key(\"network.local.address\")\n\n\t// NetworkLocalPortKey is the attribute Key conforming to the\n\t// \"network.local.port\" semantic conventions. It represents the local port\n\t// number of the network connection.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: 65123\n\tNetworkLocalPortKey = attribute.Key(\"network.local.port\")\n\n\t// NetworkPeerAddressKey is the attribute Key conforming to the\n\t// \"network.peer.address\" semantic conventions. It represents the peer address\n\t// of the network connection - IP address or Unix domain socket name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"10.1.2.80\", \"/tmp/my.sock\"\n\tNetworkPeerAddressKey = attribute.Key(\"network.peer.address\")\n\n\t// NetworkPeerPortKey is the attribute Key conforming to the \"network.peer.port\"\n\t// semantic conventions. It represents the peer port number of the network\n\t// connection.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: 65123\n\tNetworkPeerPortKey = attribute.Key(\"network.peer.port\")\n\n\t// NetworkProtocolNameKey is the attribute Key conforming to the\n\t// \"network.protocol.name\" semantic conventions. It represents the\n\t// [OSI application layer] or non-OSI equivalent.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"amqp\", \"http\", \"mqtt\"\n\t// Note: The value SHOULD be normalized to lowercase.\n\t//\n\t// [OSI application layer]: https://wikipedia.org/wiki/Application_layer\n\tNetworkProtocolNameKey = attribute.Key(\"network.protocol.name\")\n\n\t// NetworkProtocolVersionKey is the attribute Key conforming to the\n\t// \"network.protocol.version\" semantic conventions. It represents the actual\n\t// version of the protocol used for network communication.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"1.1\", \"2\"\n\t// Note: If protocol version is subject to negotiation (for example using [ALPN]\n\t// ), this attribute SHOULD be set to the negotiated version. If the actual\n\t// protocol version is not known, this attribute SHOULD NOT be set.\n\t//\n\t// [ALPN]: https://www.rfc-editor.org/rfc/rfc7301.html\n\tNetworkProtocolVersionKey = attribute.Key(\"network.protocol.version\")\n\n\t// NetworkTransportKey is the attribute Key conforming to the\n\t// \"network.transport\" semantic conventions. It represents the\n\t// [OSI transport layer] or [inter-process communication method].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"tcp\", \"udp\"\n\t// Note: The value SHOULD be normalized to lowercase.\n\t//\n\t// Consider always setting the transport when setting a port number, since\n\t// a port number is ambiguous without knowing the transport. For example\n\t// different processes could be listening on TCP port 12345 and UDP port 12345.\n\t//\n\t// [OSI transport layer]: https://wikipedia.org/wiki/Transport_layer\n\t// [inter-process communication method]: https://wikipedia.org/wiki/Inter-process_communication\n\tNetworkTransportKey = attribute.Key(\"network.transport\")\n\n\t// NetworkTypeKey is the attribute Key conforming to the \"network.type\" semantic\n\t// conventions. It represents the [OSI network layer] or non-OSI equivalent.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"ipv4\", \"ipv6\"\n\t// Note: The value SHOULD be normalized to lowercase.\n\t//\n\t// [OSI network layer]: https://wikipedia.org/wiki/Network_layer\n\tNetworkTypeKey = attribute.Key(\"network.type\")\n)\n\n// NetworkCarrierICC returns an attribute KeyValue conforming to the\n// \"network.carrier.icc\" semantic conventions. It represents the ISO 3166-1\n// alpha-2 2-character country code associated with the mobile carrier network.\nfunc NetworkCarrierICC(val string) attribute.KeyValue {\n\treturn NetworkCarrierICCKey.String(val)\n}\n\n// NetworkCarrierMCC returns an attribute KeyValue conforming to the\n// \"network.carrier.mcc\" semantic conventions. It represents the mobile carrier\n// country code.\nfunc NetworkCarrierMCC(val string) attribute.KeyValue {\n\treturn NetworkCarrierMCCKey.String(val)\n}\n\n// NetworkCarrierMNC returns an attribute KeyValue conforming to the\n// \"network.carrier.mnc\" semantic conventions. It represents the mobile carrier\n// network code.\nfunc NetworkCarrierMNC(val string) attribute.KeyValue {\n\treturn NetworkCarrierMNCKey.String(val)\n}\n\n// NetworkCarrierName returns an attribute KeyValue conforming to the\n// \"network.carrier.name\" semantic conventions. It represents the name of the\n// mobile carrier.\nfunc NetworkCarrierName(val string) attribute.KeyValue {\n\treturn NetworkCarrierNameKey.String(val)\n}\n\n// NetworkInterfaceName returns an attribute KeyValue conforming to the\n// \"network.interface.name\" semantic conventions. It represents the network\n// interface name.\nfunc NetworkInterfaceName(val string) attribute.KeyValue {\n\treturn NetworkInterfaceNameKey.String(val)\n}\n\n// NetworkLocalAddress returns an attribute KeyValue conforming to the\n// \"network.local.address\" semantic conventions. It represents the local address\n// of the network connection - IP address or Unix domain socket name.\nfunc NetworkLocalAddress(val string) attribute.KeyValue {\n\treturn NetworkLocalAddressKey.String(val)\n}\n\n// NetworkLocalPort returns an attribute KeyValue conforming to the\n// \"network.local.port\" semantic conventions. It represents the local port number\n// of the network connection.\nfunc NetworkLocalPort(val int) attribute.KeyValue {\n\treturn NetworkLocalPortKey.Int(val)\n}\n\n// NetworkPeerAddress returns an attribute KeyValue conforming to the\n// \"network.peer.address\" semantic conventions. It represents the peer address of\n// the network connection - IP address or Unix domain socket name.\nfunc NetworkPeerAddress(val string) attribute.KeyValue {\n\treturn NetworkPeerAddressKey.String(val)\n}\n\n// NetworkPeerPort returns an attribute KeyValue conforming to the\n// \"network.peer.port\" semantic conventions. It represents the peer port number\n// of the network connection.\nfunc NetworkPeerPort(val int) attribute.KeyValue {\n\treturn NetworkPeerPortKey.Int(val)\n}\n\n// NetworkProtocolName returns an attribute KeyValue conforming to the\n// \"network.protocol.name\" semantic conventions. It represents the\n// [OSI application layer] or non-OSI equivalent.\n//\n// [OSI application layer]: https://wikipedia.org/wiki/Application_layer\nfunc NetworkProtocolName(val string) attribute.KeyValue {\n\treturn NetworkProtocolNameKey.String(val)\n}\n\n// NetworkProtocolVersion returns an attribute KeyValue conforming to the\n// \"network.protocol.version\" semantic conventions. It represents the actual\n// version of the protocol used for network communication.\nfunc NetworkProtocolVersion(val string) attribute.KeyValue {\n\treturn NetworkProtocolVersionKey.String(val)\n}\n\n// Enum values for network.connection.state\nvar (\n\t// closed\n\t// Stability: development\n\tNetworkConnectionStateClosed = NetworkConnectionStateKey.String(\"closed\")\n\t// close_wait\n\t// Stability: development\n\tNetworkConnectionStateCloseWait = NetworkConnectionStateKey.String(\"close_wait\")\n\t// closing\n\t// Stability: development\n\tNetworkConnectionStateClosing = NetworkConnectionStateKey.String(\"closing\")\n\t// established\n\t// Stability: development\n\tNetworkConnectionStateEstablished = NetworkConnectionStateKey.String(\"established\")\n\t// fin_wait_1\n\t// Stability: development\n\tNetworkConnectionStateFinWait1 = NetworkConnectionStateKey.String(\"fin_wait_1\")\n\t// fin_wait_2\n\t// Stability: development\n\tNetworkConnectionStateFinWait2 = NetworkConnectionStateKey.String(\"fin_wait_2\")\n\t// last_ack\n\t// Stability: development\n\tNetworkConnectionStateLastAck = NetworkConnectionStateKey.String(\"last_ack\")\n\t// listen\n\t// Stability: development\n\tNetworkConnectionStateListen = NetworkConnectionStateKey.String(\"listen\")\n\t// syn_received\n\t// Stability: development\n\tNetworkConnectionStateSynReceived = NetworkConnectionStateKey.String(\"syn_received\")\n\t// syn_sent\n\t// Stability: development\n\tNetworkConnectionStateSynSent = NetworkConnectionStateKey.String(\"syn_sent\")\n\t// time_wait\n\t// Stability: development\n\tNetworkConnectionStateTimeWait = NetworkConnectionStateKey.String(\"time_wait\")\n)\n\n// Enum values for network.connection.subtype\nvar (\n\t// GPRS\n\t// Stability: development\n\tNetworkConnectionSubtypeGprs = NetworkConnectionSubtypeKey.String(\"gprs\")\n\t// EDGE\n\t// Stability: development\n\tNetworkConnectionSubtypeEdge = NetworkConnectionSubtypeKey.String(\"edge\")\n\t// UMTS\n\t// Stability: development\n\tNetworkConnectionSubtypeUmts = NetworkConnectionSubtypeKey.String(\"umts\")\n\t// CDMA\n\t// Stability: development\n\tNetworkConnectionSubtypeCdma = NetworkConnectionSubtypeKey.String(\"cdma\")\n\t// EVDO Rel. 0\n\t// Stability: development\n\tNetworkConnectionSubtypeEvdo0 = NetworkConnectionSubtypeKey.String(\"evdo_0\")\n\t// EVDO Rev. A\n\t// Stability: development\n\tNetworkConnectionSubtypeEvdoA = NetworkConnectionSubtypeKey.String(\"evdo_a\")\n\t// CDMA2000 1XRTT\n\t// Stability: development\n\tNetworkConnectionSubtypeCdma20001xrtt = NetworkConnectionSubtypeKey.String(\"cdma2000_1xrtt\")\n\t// HSDPA\n\t// Stability: development\n\tNetworkConnectionSubtypeHsdpa = NetworkConnectionSubtypeKey.String(\"hsdpa\")\n\t// HSUPA\n\t// Stability: development\n\tNetworkConnectionSubtypeHsupa = NetworkConnectionSubtypeKey.String(\"hsupa\")\n\t// HSPA\n\t// Stability: development\n\tNetworkConnectionSubtypeHspa = NetworkConnectionSubtypeKey.String(\"hspa\")\n\t// IDEN\n\t// Stability: development\n\tNetworkConnectionSubtypeIden = NetworkConnectionSubtypeKey.String(\"iden\")\n\t// EVDO Rev. B\n\t// Stability: development\n\tNetworkConnectionSubtypeEvdoB = NetworkConnectionSubtypeKey.String(\"evdo_b\")\n\t// LTE\n\t// Stability: development\n\tNetworkConnectionSubtypeLte = NetworkConnectionSubtypeKey.String(\"lte\")\n\t// EHRPD\n\t// Stability: development\n\tNetworkConnectionSubtypeEhrpd = NetworkConnectionSubtypeKey.String(\"ehrpd\")\n\t// HSPAP\n\t// Stability: development\n\tNetworkConnectionSubtypeHspap = NetworkConnectionSubtypeKey.String(\"hspap\")\n\t// GSM\n\t// Stability: development\n\tNetworkConnectionSubtypeGsm = NetworkConnectionSubtypeKey.String(\"gsm\")\n\t// TD-SCDMA\n\t// Stability: development\n\tNetworkConnectionSubtypeTdScdma = NetworkConnectionSubtypeKey.String(\"td_scdma\")\n\t// IWLAN\n\t// Stability: development\n\tNetworkConnectionSubtypeIwlan = NetworkConnectionSubtypeKey.String(\"iwlan\")\n\t// 5G NR (New Radio)\n\t// Stability: development\n\tNetworkConnectionSubtypeNr = NetworkConnectionSubtypeKey.String(\"nr\")\n\t// 5G NRNSA (New Radio Non-Standalone)\n\t// Stability: development\n\tNetworkConnectionSubtypeNrnsa = NetworkConnectionSubtypeKey.String(\"nrnsa\")\n\t// LTE CA\n\t// Stability: development\n\tNetworkConnectionSubtypeLteCa = NetworkConnectionSubtypeKey.String(\"lte_ca\")\n)\n\n// Enum values for network.connection.type\nvar (\n\t// wifi\n\t// Stability: development\n\tNetworkConnectionTypeWifi = NetworkConnectionTypeKey.String(\"wifi\")\n\t// wired\n\t// Stability: development\n\tNetworkConnectionTypeWired = NetworkConnectionTypeKey.String(\"wired\")\n\t// cell\n\t// Stability: development\n\tNetworkConnectionTypeCell = NetworkConnectionTypeKey.String(\"cell\")\n\t// unavailable\n\t// Stability: development\n\tNetworkConnectionTypeUnavailable = NetworkConnectionTypeKey.String(\"unavailable\")\n\t// unknown\n\t// Stability: development\n\tNetworkConnectionTypeUnknown = NetworkConnectionTypeKey.String(\"unknown\")\n)\n\n// Enum values for network.io.direction\nvar (\n\t// transmit\n\t// Stability: development\n\tNetworkIODirectionTransmit = NetworkIODirectionKey.String(\"transmit\")\n\t// receive\n\t// Stability: development\n\tNetworkIODirectionReceive = NetworkIODirectionKey.String(\"receive\")\n)\n\n// Enum values for network.transport\nvar (\n\t// TCP\n\t// Stability: stable\n\tNetworkTransportTCP = NetworkTransportKey.String(\"tcp\")\n\t// UDP\n\t// Stability: stable\n\tNetworkTransportUDP = NetworkTransportKey.String(\"udp\")\n\t// Named or anonymous pipe.\n\t// Stability: stable\n\tNetworkTransportPipe = NetworkTransportKey.String(\"pipe\")\n\t// Unix domain socket\n\t// Stability: stable\n\tNetworkTransportUnix = NetworkTransportKey.String(\"unix\")\n\t// QUIC\n\t// Stability: stable\n\tNetworkTransportQUIC = NetworkTransportKey.String(\"quic\")\n)\n\n// Enum values for network.type\nvar (\n\t// IPv4\n\t// Stability: stable\n\tNetworkTypeIPv4 = NetworkTypeKey.String(\"ipv4\")\n\t// IPv6\n\t// Stability: stable\n\tNetworkTypeIPv6 = NetworkTypeKey.String(\"ipv6\")\n)\n\n// Namespace: oci\nconst (\n\t// OCIManifestDigestKey is the attribute Key conforming to the\n\t// \"oci.manifest.digest\" semantic conventions. It represents the digest of the\n\t// OCI image manifest. For container images specifically is the digest by which\n\t// the container image is known.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4\"\n\t// Note: Follows [OCI Image Manifest Specification], and specifically the\n\t// [Digest property].\n\t// An example can be found in [Example Image Manifest].\n\t//\n\t// [OCI Image Manifest Specification]: https://github.com/opencontainers/image-spec/blob/main/manifest.md\n\t// [Digest property]: https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests\n\t// [Example Image Manifest]: https://github.com/opencontainers/image-spec/blob/main/manifest.md#example-image-manifest\n\tOCIManifestDigestKey = attribute.Key(\"oci.manifest.digest\")\n)\n\n// OCIManifestDigest returns an attribute KeyValue conforming to the\n// \"oci.manifest.digest\" semantic conventions. It represents the digest of the\n// OCI image manifest. For container images specifically is the digest by which\n// the container image is known.\nfunc OCIManifestDigest(val string) attribute.KeyValue {\n\treturn OCIManifestDigestKey.String(val)\n}\n\n// Namespace: openai\nconst (\n\t// OpenAIRequestServiceTierKey is the attribute Key conforming to the\n\t// \"openai.request.service_tier\" semantic conventions. It represents the service\n\t// tier requested. May be a specific tier, default, or auto.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"auto\", \"default\"\n\tOpenAIRequestServiceTierKey = attribute.Key(\"openai.request.service_tier\")\n\n\t// OpenAIResponseServiceTierKey is the attribute Key conforming to the\n\t// \"openai.response.service_tier\" semantic conventions. It represents the\n\t// service tier used for the response.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"scale\", \"default\"\n\tOpenAIResponseServiceTierKey = attribute.Key(\"openai.response.service_tier\")\n\n\t// OpenAIResponseSystemFingerprintKey is the attribute Key conforming to the\n\t// \"openai.response.system_fingerprint\" semantic conventions. It represents a\n\t// fingerprint to track any eventual change in the Generative AI environment.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"fp_44709d6fcb\"\n\tOpenAIResponseSystemFingerprintKey = attribute.Key(\"openai.response.system_fingerprint\")\n)\n\n// OpenAIResponseServiceTier returns an attribute KeyValue conforming to the\n// \"openai.response.service_tier\" semantic conventions. It represents the service\n// tier used for the response.\nfunc OpenAIResponseServiceTier(val string) attribute.KeyValue {\n\treturn OpenAIResponseServiceTierKey.String(val)\n}\n\n// OpenAIResponseSystemFingerprint returns an attribute KeyValue conforming to\n// the \"openai.response.system_fingerprint\" semantic conventions. It represents a\n// fingerprint to track any eventual change in the Generative AI environment.\nfunc OpenAIResponseSystemFingerprint(val string) attribute.KeyValue {\n\treturn OpenAIResponseSystemFingerprintKey.String(val)\n}\n\n// Enum values for openai.request.service_tier\nvar (\n\t// The system will utilize scale tier credits until they are exhausted.\n\t// Stability: development\n\tOpenAIRequestServiceTierAuto = OpenAIRequestServiceTierKey.String(\"auto\")\n\t// The system will utilize the default scale tier.\n\t// Stability: development\n\tOpenAIRequestServiceTierDefault = OpenAIRequestServiceTierKey.String(\"default\")\n)\n\n// Namespace: opentracing\nconst (\n\t// OpenTracingRefTypeKey is the attribute Key conforming to the\n\t// \"opentracing.ref_type\" semantic conventions. It represents the parent-child\n\t// Reference type.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: The causal relationship between a child Span and a parent Span.\n\tOpenTracingRefTypeKey = attribute.Key(\"opentracing.ref_type\")\n)\n\n// Enum values for opentracing.ref_type\nvar (\n\t// The parent Span depends on the child Span in some capacity\n\t// Stability: development\n\tOpenTracingRefTypeChildOf = OpenTracingRefTypeKey.String(\"child_of\")\n\t// The parent Span doesn't depend in any way on the result of the child Span\n\t// Stability: development\n\tOpenTracingRefTypeFollowsFrom = OpenTracingRefTypeKey.String(\"follows_from\")\n)\n\n// Namespace: os\nconst (\n\t// OSBuildIDKey is the attribute Key conforming to the \"os.build_id\" semantic\n\t// conventions. It represents the unique identifier for a particular build or\n\t// compilation of the operating system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"TQ3C.230805.001.B2\", \"20E247\", \"22621\"\n\tOSBuildIDKey = attribute.Key(\"os.build_id\")\n\n\t// OSDescriptionKey is the attribute Key conforming to the \"os.description\"\n\t// semantic conventions. It represents the human readable (not intended to be\n\t// parsed) OS version information, like e.g. reported by `ver` or\n\t// `lsb_release -a` commands.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Microsoft Windows [Version 10.0.18363.778]\", \"Ubuntu 18.04.1 LTS\"\n\tOSDescriptionKey = attribute.Key(\"os.description\")\n\n\t// OSNameKey is the attribute Key conforming to the \"os.name\" semantic\n\t// conventions. It represents the human readable operating system name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"iOS\", \"Android\", \"Ubuntu\"\n\tOSNameKey = attribute.Key(\"os.name\")\n\n\t// OSTypeKey is the attribute Key conforming to the \"os.type\" semantic\n\t// conventions. It represents the operating system type.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tOSTypeKey = attribute.Key(\"os.type\")\n\n\t// OSVersionKey is the attribute Key conforming to the \"os.version\" semantic\n\t// conventions. It represents the version string of the operating system as\n\t// defined in [Version Attributes].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"14.2.1\", \"18.04.1\"\n\t//\n\t// [Version Attributes]: /docs/resource/README.md#version-attributes\n\tOSVersionKey = attribute.Key(\"os.version\")\n)\n\n// OSBuildID returns an attribute KeyValue conforming to the \"os.build_id\"\n// semantic conventions. It represents the unique identifier for a particular\n// build or compilation of the operating system.\nfunc OSBuildID(val string) attribute.KeyValue {\n\treturn OSBuildIDKey.String(val)\n}\n\n// OSDescription returns an attribute KeyValue conforming to the \"os.description\"\n// semantic conventions. It represents the human readable (not intended to be\n// parsed) OS version information, like e.g. reported by `ver` or\n// `lsb_release -a` commands.\nfunc OSDescription(val string) attribute.KeyValue {\n\treturn OSDescriptionKey.String(val)\n}\n\n// OSName returns an attribute KeyValue conforming to the \"os.name\" semantic\n// conventions. It represents the human readable operating system name.\nfunc OSName(val string) attribute.KeyValue {\n\treturn OSNameKey.String(val)\n}\n\n// OSVersion returns an attribute KeyValue conforming to the \"os.version\"\n// semantic conventions. It represents the version string of the operating system\n// as defined in [Version Attributes].\n//\n// [Version Attributes]: /docs/resource/README.md#version-attributes\nfunc OSVersion(val string) attribute.KeyValue {\n\treturn OSVersionKey.String(val)\n}\n\n// Enum values for os.type\nvar (\n\t// Microsoft Windows\n\t// Stability: development\n\tOSTypeWindows = OSTypeKey.String(\"windows\")\n\t// Linux\n\t// Stability: development\n\tOSTypeLinux = OSTypeKey.String(\"linux\")\n\t// Apple Darwin\n\t// Stability: development\n\tOSTypeDarwin = OSTypeKey.String(\"darwin\")\n\t// FreeBSD\n\t// Stability: development\n\tOSTypeFreeBSD = OSTypeKey.String(\"freebsd\")\n\t// NetBSD\n\t// Stability: development\n\tOSTypeNetBSD = OSTypeKey.String(\"netbsd\")\n\t// OpenBSD\n\t// Stability: development\n\tOSTypeOpenBSD = OSTypeKey.String(\"openbsd\")\n\t// DragonFly BSD\n\t// Stability: development\n\tOSTypeDragonflyBSD = OSTypeKey.String(\"dragonflybsd\")\n\t// HP-UX (Hewlett Packard Unix)\n\t// Stability: development\n\tOSTypeHPUX = OSTypeKey.String(\"hpux\")\n\t// AIX (Advanced Interactive eXecutive)\n\t// Stability: development\n\tOSTypeAIX = OSTypeKey.String(\"aix\")\n\t// SunOS, Oracle Solaris\n\t// Stability: development\n\tOSTypeSolaris = OSTypeKey.String(\"solaris\")\n\t// IBM z/OS\n\t// Stability: development\n\tOSTypeZOS = OSTypeKey.String(\"zos\")\n)\n\n// Namespace: otel\nconst (\n\t// OTelComponentNameKey is the attribute Key conforming to the\n\t// \"otel.component.name\" semantic conventions. It represents a name uniquely\n\t// identifying the instance of the OpenTelemetry component within its containing\n\t// SDK instance.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"otlp_grpc_span_exporter/0\", \"custom-name\"\n\t// Note: Implementations SHOULD ensure a low cardinality for this attribute,\n\t// even across application or SDK restarts.\n\t// E.g. implementations MUST NOT use UUIDs as values for this attribute.\n\t//\n\t// Implementations MAY achieve these goals by following a\n\t// `<otel.component.type>/<instance-counter>` pattern, e.g.\n\t// `batching_span_processor/0`.\n\t// Hereby `otel.component.type` refers to the corresponding attribute value of\n\t// the component.\n\t//\n\t// The value of `instance-counter` MAY be automatically assigned by the\n\t// component and uniqueness within the enclosing SDK instance MUST be\n\t// guaranteed.\n\t// For example, `<instance-counter>` MAY be implemented by using a monotonically\n\t// increasing counter (starting with `0`), which is incremented every time an\n\t// instance of the given component type is started.\n\t//\n\t// With this implementation, for example the first Batching Span Processor would\n\t// have `batching_span_processor/0`\n\t// as `otel.component.name`, the second one `batching_span_processor/1` and so\n\t// on.\n\t// These values will therefore be reused in the case of an application restart.\n\tOTelComponentNameKey = attribute.Key(\"otel.component.name\")\n\n\t// OTelComponentTypeKey is the attribute Key conforming to the\n\t// \"otel.component.type\" semantic conventions. It represents a name identifying\n\t// the type of the OpenTelemetry component.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"batching_span_processor\", \"com.example.MySpanExporter\"\n\t// Note: If none of the standardized values apply, implementations SHOULD use\n\t// the language-defined name of the type.\n\t// E.g. for Java the fully qualified classname SHOULD be used in this case.\n\tOTelComponentTypeKey = attribute.Key(\"otel.component.type\")\n\n\t// OTelScopeNameKey is the attribute Key conforming to the \"otel.scope.name\"\n\t// semantic conventions. It represents the name of the instrumentation scope - (\n\t// `InstrumentationScope.Name` in OTLP).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"io.opentelemetry.contrib.mongodb\"\n\tOTelScopeNameKey = attribute.Key(\"otel.scope.name\")\n\n\t// OTelScopeSchemaURLKey is the attribute Key conforming to the\n\t// \"otel.scope.schema_url\" semantic conventions. It represents the schema URL of\n\t// the instrumentation scope.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"https://opentelemetry.io/schemas/1.31.0\"\n\tOTelScopeSchemaURLKey = attribute.Key(\"otel.scope.schema_url\")\n\n\t// OTelScopeVersionKey is the attribute Key conforming to the\n\t// \"otel.scope.version\" semantic conventions. It represents the version of the\n\t// instrumentation scope - (`InstrumentationScope.Version` in OTLP).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"1.0.0\"\n\tOTelScopeVersionKey = attribute.Key(\"otel.scope.version\")\n\n\t// OTelSpanParentOriginKey is the attribute Key conforming to the\n\t// \"otel.span.parent.origin\" semantic conventions. It represents the determines\n\t// whether the span has a parent span, and if so,\n\t// [whether it is a remote parent].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t//\n\t// [whether it is a remote parent]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote\n\tOTelSpanParentOriginKey = attribute.Key(\"otel.span.parent.origin\")\n\n\t// OTelSpanSamplingResultKey is the attribute Key conforming to the\n\t// \"otel.span.sampling_result\" semantic conventions. It represents the result\n\t// value of the sampler for this span.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tOTelSpanSamplingResultKey = attribute.Key(\"otel.span.sampling_result\")\n\n\t// OTelStatusCodeKey is the attribute Key conforming to the \"otel.status_code\"\n\t// semantic conventions. It represents the name of the code, either \"OK\" or\n\t// \"ERROR\". MUST NOT be set if the status code is UNSET.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples:\n\tOTelStatusCodeKey = attribute.Key(\"otel.status_code\")\n\n\t// OTelStatusDescriptionKey is the attribute Key conforming to the\n\t// \"otel.status_description\" semantic conventions. It represents the description\n\t// of the Status if it has a value, otherwise not set.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"resource not found\"\n\tOTelStatusDescriptionKey = attribute.Key(\"otel.status_description\")\n)\n\n// OTelComponentName returns an attribute KeyValue conforming to the\n// \"otel.component.name\" semantic conventions. It represents a name uniquely\n// identifying the instance of the OpenTelemetry component within its containing\n// SDK instance.\nfunc OTelComponentName(val string) attribute.KeyValue {\n\treturn OTelComponentNameKey.String(val)\n}\n\n// OTelScopeName returns an attribute KeyValue conforming to the\n// \"otel.scope.name\" semantic conventions. It represents the name of the\n// instrumentation scope - (`InstrumentationScope.Name` in OTLP).\nfunc OTelScopeName(val string) attribute.KeyValue {\n\treturn OTelScopeNameKey.String(val)\n}\n\n// OTelScopeSchemaURL returns an attribute KeyValue conforming to the\n// \"otel.scope.schema_url\" semantic conventions. It represents the schema URL of\n// the instrumentation scope.\nfunc OTelScopeSchemaURL(val string) attribute.KeyValue {\n\treturn OTelScopeSchemaURLKey.String(val)\n}\n\n// OTelScopeVersion returns an attribute KeyValue conforming to the\n// \"otel.scope.version\" semantic conventions. It represents the version of the\n// instrumentation scope - (`InstrumentationScope.Version` in OTLP).\nfunc OTelScopeVersion(val string) attribute.KeyValue {\n\treturn OTelScopeVersionKey.String(val)\n}\n\n// OTelStatusDescription returns an attribute KeyValue conforming to the\n// \"otel.status_description\" semantic conventions. It represents the description\n// of the Status if it has a value, otherwise not set.\nfunc OTelStatusDescription(val string) attribute.KeyValue {\n\treturn OTelStatusDescriptionKey.String(val)\n}\n\n// Enum values for otel.component.type\nvar (\n\t// The builtin SDK batching span processor\n\t//\n\t// Stability: development\n\tOTelComponentTypeBatchingSpanProcessor = OTelComponentTypeKey.String(\"batching_span_processor\")\n\t// The builtin SDK simple span processor\n\t//\n\t// Stability: development\n\tOTelComponentTypeSimpleSpanProcessor = OTelComponentTypeKey.String(\"simple_span_processor\")\n\t// The builtin SDK batching log record processor\n\t//\n\t// Stability: development\n\tOTelComponentTypeBatchingLogProcessor = OTelComponentTypeKey.String(\"batching_log_processor\")\n\t// The builtin SDK simple log record processor\n\t//\n\t// Stability: development\n\tOTelComponentTypeSimpleLogProcessor = OTelComponentTypeKey.String(\"simple_log_processor\")\n\t// OTLP span exporter over gRPC with protobuf serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpGRPCSpanExporter = OTelComponentTypeKey.String(\"otlp_grpc_span_exporter\")\n\t// OTLP span exporter over HTTP with protobuf serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpHTTPSpanExporter = OTelComponentTypeKey.String(\"otlp_http_span_exporter\")\n\t// OTLP span exporter over HTTP with JSON serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpHTTPJSONSpanExporter = OTelComponentTypeKey.String(\"otlp_http_json_span_exporter\")\n\t// Zipkin span exporter over HTTP\n\t//\n\t// Stability: development\n\tOTelComponentTypeZipkinHTTPSpanExporter = OTelComponentTypeKey.String(\"zipkin_http_span_exporter\")\n\t// OTLP log record exporter over gRPC with protobuf serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpGRPCLogExporter = OTelComponentTypeKey.String(\"otlp_grpc_log_exporter\")\n\t// OTLP log record exporter over HTTP with protobuf serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpHTTPLogExporter = OTelComponentTypeKey.String(\"otlp_http_log_exporter\")\n\t// OTLP log record exporter over HTTP with JSON serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpHTTPJSONLogExporter = OTelComponentTypeKey.String(\"otlp_http_json_log_exporter\")\n\t// The builtin SDK periodically exporting metric reader\n\t//\n\t// Stability: development\n\tOTelComponentTypePeriodicMetricReader = OTelComponentTypeKey.String(\"periodic_metric_reader\")\n\t// OTLP metric exporter over gRPC with protobuf serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpGRPCMetricExporter = OTelComponentTypeKey.String(\"otlp_grpc_metric_exporter\")\n\t// OTLP metric exporter over HTTP with protobuf serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpHTTPMetricExporter = OTelComponentTypeKey.String(\"otlp_http_metric_exporter\")\n\t// OTLP metric exporter over HTTP with JSON serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpHTTPJSONMetricExporter = OTelComponentTypeKey.String(\"otlp_http_json_metric_exporter\")\n\t// Prometheus metric exporter over HTTP with the default text-based format\n\t//\n\t// Stability: development\n\tOTelComponentTypePrometheusHTTPTextMetricExporter = OTelComponentTypeKey.String(\"prometheus_http_text_metric_exporter\")\n)\n\n// Enum values for otel.span.parent.origin\nvar (\n\t// The span does not have a parent, it is a root span\n\t// Stability: development\n\tOTelSpanParentOriginNone = OTelSpanParentOriginKey.String(\"none\")\n\t// The span has a parent and the parent's span context [isRemote()] is false\n\t// Stability: development\n\t//\n\t// [isRemote()]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote\n\tOTelSpanParentOriginLocal = OTelSpanParentOriginKey.String(\"local\")\n\t// The span has a parent and the parent's span context [isRemote()] is true\n\t// Stability: development\n\t//\n\t// [isRemote()]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote\n\tOTelSpanParentOriginRemote = OTelSpanParentOriginKey.String(\"remote\")\n)\n\n// Enum values for otel.span.sampling_result\nvar (\n\t// The span is not sampled and not recording\n\t// Stability: development\n\tOTelSpanSamplingResultDrop = OTelSpanSamplingResultKey.String(\"DROP\")\n\t// The span is not sampled, but recording\n\t// Stability: development\n\tOTelSpanSamplingResultRecordOnly = OTelSpanSamplingResultKey.String(\"RECORD_ONLY\")\n\t// The span is sampled and recording\n\t// Stability: development\n\tOTelSpanSamplingResultRecordAndSample = OTelSpanSamplingResultKey.String(\"RECORD_AND_SAMPLE\")\n)\n\n// Enum values for otel.status_code\nvar (\n\t// The operation has been validated by an Application developer or Operator to\n\t// have completed successfully.\n\t// Stability: stable\n\tOTelStatusCodeOk = OTelStatusCodeKey.String(\"OK\")\n\t// The operation contains an error.\n\t// Stability: stable\n\tOTelStatusCodeError = OTelStatusCodeKey.String(\"ERROR\")\n)\n\n// Namespace: peer\nconst (\n\t// PeerServiceKey is the attribute Key conforming to the \"peer.service\" semantic\n\t// conventions. It represents the [`service.name`] of the remote service. SHOULD\n\t// be equal to the actual `service.name` resource attribute of the remote\n\t// service if any.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: AuthTokenCache\n\t//\n\t// [`service.name`]: /docs/resource/README.md#service\n\tPeerServiceKey = attribute.Key(\"peer.service\")\n)\n\n// PeerService returns an attribute KeyValue conforming to the \"peer.service\"\n// semantic conventions. It represents the [`service.name`] of the remote\n// service. SHOULD be equal to the actual `service.name` resource attribute of\n// the remote service if any.\n//\n// [`service.name`]: /docs/resource/README.md#service\nfunc PeerService(val string) attribute.KeyValue {\n\treturn PeerServiceKey.String(val)\n}\n\n// Namespace: process\nconst (\n\t// ProcessArgsCountKey is the attribute Key conforming to the\n\t// \"process.args_count\" semantic conventions. It represents the length of the\n\t// process.command_args array.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 4\n\t// Note: This field can be useful for querying or performing bucket analysis on\n\t// how many arguments were provided to start a process. More arguments may be an\n\t// indication of suspicious activity.\n\tProcessArgsCountKey = attribute.Key(\"process.args_count\")\n\n\t// ProcessCommandKey is the attribute Key conforming to the \"process.command\"\n\t// semantic conventions. It represents the command used to launch the process\n\t// (i.e. the command name). On Linux based systems, can be set to the zeroth\n\t// string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter\n\t// extracted from `GetCommandLineW`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"cmd/otelcol\"\n\tProcessCommandKey = attribute.Key(\"process.command\")\n\n\t// ProcessCommandArgsKey is the attribute Key conforming to the\n\t// \"process.command_args\" semantic conventions. It represents the all the\n\t// command arguments (including the command/executable itself) as received by\n\t// the process. On Linux-based systems (and some other Unixoid systems\n\t// supporting procfs), can be set according to the list of null-delimited\n\t// strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this\n\t// would be the full argv vector passed to `main`. SHOULD NOT be collected by\n\t// default unless there is sanitization that excludes sensitive data.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"cmd/otecol\", \"--config=config.yaml\"\n\tProcessCommandArgsKey = attribute.Key(\"process.command_args\")\n\n\t// ProcessCommandLineKey is the attribute Key conforming to the\n\t// \"process.command_line\" semantic conventions. It represents the full command\n\t// used to launch the process as a single string representing the full command.\n\t// On Windows, can be set to the result of `GetCommandLineW`. Do not set this if\n\t// you have to assemble it just for monitoring; use `process.command_args`\n\t// instead. SHOULD NOT be collected by default unless there is sanitization that\n\t// excludes sensitive data.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"C:\\cmd\\otecol --config=\"my directory\\config.yaml\"\"\n\tProcessCommandLineKey = attribute.Key(\"process.command_line\")\n\n\t// ProcessContextSwitchTypeKey is the attribute Key conforming to the\n\t// \"process.context_switch_type\" semantic conventions. It represents the\n\t// specifies whether the context switches for this data point were voluntary or\n\t// involuntary.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tProcessContextSwitchTypeKey = attribute.Key(\"process.context_switch_type\")\n\n\t// ProcessCreationTimeKey is the attribute Key conforming to the\n\t// \"process.creation.time\" semantic conventions. It represents the date and time\n\t// the process was created, in ISO 8601 format.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2023-11-21T09:25:34.853Z\"\n\tProcessCreationTimeKey = attribute.Key(\"process.creation.time\")\n\n\t// ProcessExecutableBuildIDGNUKey is the attribute Key conforming to the\n\t// \"process.executable.build_id.gnu\" semantic conventions. It represents the GNU\n\t// build ID as found in the `.note.gnu.build-id` ELF section (hex string).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"c89b11207f6479603b0d49bf291c092c2b719293\"\n\tProcessExecutableBuildIDGNUKey = attribute.Key(\"process.executable.build_id.gnu\")\n\n\t// ProcessExecutableBuildIDGoKey is the attribute Key conforming to the\n\t// \"process.executable.build_id.go\" semantic conventions. It represents the Go\n\t// build ID as retrieved by `go tool buildid <go executable>`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"foh3mEXu7BLZjsN9pOwG/kATcXlYVCDEFouRMQed_/WwRFB1hPo9LBkekthSPG/x8hMC8emW2cCjXD0_1aY\"\n\tProcessExecutableBuildIDGoKey = attribute.Key(\"process.executable.build_id.go\")\n\n\t// ProcessExecutableBuildIDHtlhashKey is the attribute Key conforming to the\n\t// \"process.executable.build_id.htlhash\" semantic conventions. It represents the\n\t// profiling specific build ID for executables. See the OTel specification for\n\t// Profiles for more information.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"600DCAFE4A110000F2BF38C493F5FB92\"\n\tProcessExecutableBuildIDHtlhashKey = attribute.Key(\"process.executable.build_id.htlhash\")\n\n\t// ProcessExecutableNameKey is the attribute Key conforming to the\n\t// \"process.executable.name\" semantic conventions. It represents the name of the\n\t// process executable. On Linux based systems, this SHOULD be set to the base\n\t// name of the target of `/proc/[pid]/exe`. On Windows, this SHOULD be set to\n\t// the base name of `GetProcessImageFileNameW`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"otelcol\"\n\tProcessExecutableNameKey = attribute.Key(\"process.executable.name\")\n\n\t// ProcessExecutablePathKey is the attribute Key conforming to the\n\t// \"process.executable.path\" semantic conventions. It represents the full path\n\t// to the process executable. On Linux based systems, can be set to the target\n\t// of `proc/[pid]/exe`. On Windows, can be set to the result of\n\t// `GetProcessImageFileNameW`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/usr/bin/cmd/otelcol\"\n\tProcessExecutablePathKey = attribute.Key(\"process.executable.path\")\n\n\t// ProcessExitCodeKey is the attribute Key conforming to the \"process.exit.code\"\n\t// semantic conventions. It represents the exit code of the process.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 127\n\tProcessExitCodeKey = attribute.Key(\"process.exit.code\")\n\n\t// ProcessExitTimeKey is the attribute Key conforming to the \"process.exit.time\"\n\t// semantic conventions. It represents the date and time the process exited, in\n\t// ISO 8601 format.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2023-11-21T09:26:12.315Z\"\n\tProcessExitTimeKey = attribute.Key(\"process.exit.time\")\n\n\t// ProcessGroupLeaderPIDKey is the attribute Key conforming to the\n\t// \"process.group_leader.pid\" semantic conventions. It represents the PID of the\n\t// process's group leader. This is also the process group ID (PGID) of the\n\t// process.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 23\n\tProcessGroupLeaderPIDKey = attribute.Key(\"process.group_leader.pid\")\n\n\t// ProcessInteractiveKey is the attribute Key conforming to the\n\t// \"process.interactive\" semantic conventions. It represents the whether the\n\t// process is connected to an interactive shell.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tProcessInteractiveKey = attribute.Key(\"process.interactive\")\n\n\t// ProcessLinuxCgroupKey is the attribute Key conforming to the\n\t// \"process.linux.cgroup\" semantic conventions. It represents the control group\n\t// associated with the process.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1:name=systemd:/user.slice/user-1000.slice/session-3.scope\",\n\t// \"0::/user.slice/user-1000.slice/user@1000.service/tmux-spawn-0267755b-4639-4a27-90ed-f19f88e53748.scope\"\n\t// Note: Control groups (cgroups) are a kernel feature used to organize and\n\t// manage process resources. This attribute provides the path(s) to the\n\t// cgroup(s) associated with the process, which should match the contents of the\n\t// [/proc/[PID]/cgroup] file.\n\t//\n\t// [/proc/[PID]/cgroup]: https://man7.org/linux/man-pages/man7/cgroups.7.html\n\tProcessLinuxCgroupKey = attribute.Key(\"process.linux.cgroup\")\n\n\t// ProcessOwnerKey is the attribute Key conforming to the \"process.owner\"\n\t// semantic conventions. It represents the username of the user that owns the\n\t// process.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"root\"\n\tProcessOwnerKey = attribute.Key(\"process.owner\")\n\n\t// ProcessPagingFaultTypeKey is the attribute Key conforming to the\n\t// \"process.paging.fault_type\" semantic conventions. It represents the type of\n\t// page fault for this data point. Type `major` is for major/hard page faults,\n\t// and `minor` is for minor/soft page faults.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tProcessPagingFaultTypeKey = attribute.Key(\"process.paging.fault_type\")\n\n\t// ProcessParentPIDKey is the attribute Key conforming to the\n\t// \"process.parent_pid\" semantic conventions. It represents the parent Process\n\t// identifier (PPID).\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 111\n\tProcessParentPIDKey = attribute.Key(\"process.parent_pid\")\n\n\t// ProcessPIDKey is the attribute Key conforming to the \"process.pid\" semantic\n\t// conventions. It represents the process identifier (PID).\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1234\n\tProcessPIDKey = attribute.Key(\"process.pid\")\n\n\t// ProcessRealUserIDKey is the attribute Key conforming to the\n\t// \"process.real_user.id\" semantic conventions. It represents the real user ID\n\t// (RUID) of the process.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1000\n\tProcessRealUserIDKey = attribute.Key(\"process.real_user.id\")\n\n\t// ProcessRealUserNameKey is the attribute Key conforming to the\n\t// \"process.real_user.name\" semantic conventions. It represents the username of\n\t// the real user of the process.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"operator\"\n\tProcessRealUserNameKey = attribute.Key(\"process.real_user.name\")\n\n\t// ProcessRuntimeDescriptionKey is the attribute Key conforming to the\n\t// \"process.runtime.description\" semantic conventions. It represents an\n\t// additional description about the runtime of the process, for example a\n\t// specific vendor customization of the runtime environment.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0\n\tProcessRuntimeDescriptionKey = attribute.Key(\"process.runtime.description\")\n\n\t// ProcessRuntimeNameKey is the attribute Key conforming to the\n\t// \"process.runtime.name\" semantic conventions. It represents the name of the\n\t// runtime of this process.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"OpenJDK Runtime Environment\"\n\tProcessRuntimeNameKey = attribute.Key(\"process.runtime.name\")\n\n\t// ProcessRuntimeVersionKey is the attribute Key conforming to the\n\t// \"process.runtime.version\" semantic conventions. It represents the version of\n\t// the runtime of this process, as returned by the runtime without modification.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 14.0.2\n\tProcessRuntimeVersionKey = attribute.Key(\"process.runtime.version\")\n\n\t// ProcessSavedUserIDKey is the attribute Key conforming to the\n\t// \"process.saved_user.id\" semantic conventions. It represents the saved user ID\n\t// (SUID) of the process.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1002\n\tProcessSavedUserIDKey = attribute.Key(\"process.saved_user.id\")\n\n\t// ProcessSavedUserNameKey is the attribute Key conforming to the\n\t// \"process.saved_user.name\" semantic conventions. It represents the username of\n\t// the saved user.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"operator\"\n\tProcessSavedUserNameKey = attribute.Key(\"process.saved_user.name\")\n\n\t// ProcessSessionLeaderPIDKey is the attribute Key conforming to the\n\t// \"process.session_leader.pid\" semantic conventions. It represents the PID of\n\t// the process's session leader. This is also the session ID (SID) of the\n\t// process.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 14\n\tProcessSessionLeaderPIDKey = attribute.Key(\"process.session_leader.pid\")\n\n\t// ProcessTitleKey is the attribute Key conforming to the \"process.title\"\n\t// semantic conventions. It represents the process title (proctitle).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"cat /etc/hostname\", \"xfce4-session\", \"bash\"\n\t// Note: In many Unix-like systems, process title (proctitle), is the string\n\t// that represents the name or command line of a running process, displayed by\n\t// system monitoring tools like ps, top, and htop.\n\tProcessTitleKey = attribute.Key(\"process.title\")\n\n\t// ProcessUserIDKey is the attribute Key conforming to the \"process.user.id\"\n\t// semantic conventions. It represents the effective user ID (EUID) of the\n\t// process.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1001\n\tProcessUserIDKey = attribute.Key(\"process.user.id\")\n\n\t// ProcessUserNameKey is the attribute Key conforming to the \"process.user.name\"\n\t// semantic conventions. It represents the username of the effective user of the\n\t// process.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"root\"\n\tProcessUserNameKey = attribute.Key(\"process.user.name\")\n\n\t// ProcessVpidKey is the attribute Key conforming to the \"process.vpid\" semantic\n\t// conventions. It represents the virtual process identifier.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 12\n\t// Note: The process ID within a PID namespace. This is not necessarily unique\n\t// across all processes on the host but it is unique within the process\n\t// namespace that the process exists within.\n\tProcessVpidKey = attribute.Key(\"process.vpid\")\n\n\t// ProcessWorkingDirectoryKey is the attribute Key conforming to the\n\t// \"process.working_directory\" semantic conventions. It represents the working\n\t// directory of the process.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/root\"\n\tProcessWorkingDirectoryKey = attribute.Key(\"process.working_directory\")\n)\n\n// ProcessArgsCount returns an attribute KeyValue conforming to the\n// \"process.args_count\" semantic conventions. It represents the length of the\n// process.command_args array.\nfunc ProcessArgsCount(val int) attribute.KeyValue {\n\treturn ProcessArgsCountKey.Int(val)\n}\n\n// ProcessCommand returns an attribute KeyValue conforming to the\n// \"process.command\" semantic conventions. It represents the command used to\n// launch the process (i.e. the command name). On Linux based systems, can be set\n// to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the\n// first parameter extracted from `GetCommandLineW`.\nfunc ProcessCommand(val string) attribute.KeyValue {\n\treturn ProcessCommandKey.String(val)\n}\n\n// ProcessCommandArgs returns an attribute KeyValue conforming to the\n// \"process.command_args\" semantic conventions. It represents the all the command\n// arguments (including the command/executable itself) as received by the\n// process. On Linux-based systems (and some other Unixoid systems supporting\n// procfs), can be set according to the list of null-delimited strings extracted\n// from `proc/[pid]/cmdline`. For libc-based executables, this would be the full\n// argv vector passed to `main`. SHOULD NOT be collected by default unless there\n// is sanitization that excludes sensitive data.\nfunc ProcessCommandArgs(val ...string) attribute.KeyValue {\n\treturn ProcessCommandArgsKey.StringSlice(val)\n}\n\n// ProcessCommandLine returns an attribute KeyValue conforming to the\n// \"process.command_line\" semantic conventions. It represents the full command\n// used to launch the process as a single string representing the full command.\n// On Windows, can be set to the result of `GetCommandLineW`. Do not set this if\n// you have to assemble it just for monitoring; use `process.command_args`\n// instead. SHOULD NOT be collected by default unless there is sanitization that\n// excludes sensitive data.\nfunc ProcessCommandLine(val string) attribute.KeyValue {\n\treturn ProcessCommandLineKey.String(val)\n}\n\n// ProcessCreationTime returns an attribute KeyValue conforming to the\n// \"process.creation.time\" semantic conventions. It represents the date and time\n// the process was created, in ISO 8601 format.\nfunc ProcessCreationTime(val string) attribute.KeyValue {\n\treturn ProcessCreationTimeKey.String(val)\n}\n\n// ProcessEnvironmentVariable returns an attribute KeyValue conforming to the\n// \"process.environment_variable\" semantic conventions. It represents the process\n// environment variables, `<key>` being the environment variable name, the value\n// being the environment variable value.\nfunc ProcessEnvironmentVariable(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"process.environment_variable.\"+key, val)\n}\n\n// ProcessExecutableBuildIDGNU returns an attribute KeyValue conforming to the\n// \"process.executable.build_id.gnu\" semantic conventions. It represents the GNU\n// build ID as found in the `.note.gnu.build-id` ELF section (hex string).\nfunc ProcessExecutableBuildIDGNU(val string) attribute.KeyValue {\n\treturn ProcessExecutableBuildIDGNUKey.String(val)\n}\n\n// ProcessExecutableBuildIDGo returns an attribute KeyValue conforming to the\n// \"process.executable.build_id.go\" semantic conventions. It represents the Go\n// build ID as retrieved by `go tool buildid <go executable>`.\nfunc ProcessExecutableBuildIDGo(val string) attribute.KeyValue {\n\treturn ProcessExecutableBuildIDGoKey.String(val)\n}\n\n// ProcessExecutableBuildIDHtlhash returns an attribute KeyValue conforming to\n// the \"process.executable.build_id.htlhash\" semantic conventions. It represents\n// the profiling specific build ID for executables. See the OTel specification\n// for Profiles for more information.\nfunc ProcessExecutableBuildIDHtlhash(val string) attribute.KeyValue {\n\treturn ProcessExecutableBuildIDHtlhashKey.String(val)\n}\n\n// ProcessExecutableName returns an attribute KeyValue conforming to the\n// \"process.executable.name\" semantic conventions. It represents the name of the\n// process executable. On Linux based systems, this SHOULD be set to the base\n// name of the target of `/proc/[pid]/exe`. On Windows, this SHOULD be set to the\n// base name of `GetProcessImageFileNameW`.\nfunc ProcessExecutableName(val string) attribute.KeyValue {\n\treturn ProcessExecutableNameKey.String(val)\n}\n\n// ProcessExecutablePath returns an attribute KeyValue conforming to the\n// \"process.executable.path\" semantic conventions. It represents the full path to\n// the process executable. On Linux based systems, can be set to the target of\n// `proc/[pid]/exe`. On Windows, can be set to the result of\n// `GetProcessImageFileNameW`.\nfunc ProcessExecutablePath(val string) attribute.KeyValue {\n\treturn ProcessExecutablePathKey.String(val)\n}\n\n// ProcessExitCode returns an attribute KeyValue conforming to the\n// \"process.exit.code\" semantic conventions. It represents the exit code of the\n// process.\nfunc ProcessExitCode(val int) attribute.KeyValue {\n\treturn ProcessExitCodeKey.Int(val)\n}\n\n// ProcessExitTime returns an attribute KeyValue conforming to the\n// \"process.exit.time\" semantic conventions. It represents the date and time the\n// process exited, in ISO 8601 format.\nfunc ProcessExitTime(val string) attribute.KeyValue {\n\treturn ProcessExitTimeKey.String(val)\n}\n\n// ProcessGroupLeaderPID returns an attribute KeyValue conforming to the\n// \"process.group_leader.pid\" semantic conventions. It represents the PID of the\n// process's group leader. This is also the process group ID (PGID) of the\n// process.\nfunc ProcessGroupLeaderPID(val int) attribute.KeyValue {\n\treturn ProcessGroupLeaderPIDKey.Int(val)\n}\n\n// ProcessInteractive returns an attribute KeyValue conforming to the\n// \"process.interactive\" semantic conventions. It represents the whether the\n// process is connected to an interactive shell.\nfunc ProcessInteractive(val bool) attribute.KeyValue {\n\treturn ProcessInteractiveKey.Bool(val)\n}\n\n// ProcessLinuxCgroup returns an attribute KeyValue conforming to the\n// \"process.linux.cgroup\" semantic conventions. It represents the control group\n// associated with the process.\nfunc ProcessLinuxCgroup(val string) attribute.KeyValue {\n\treturn ProcessLinuxCgroupKey.String(val)\n}\n\n// ProcessOwner returns an attribute KeyValue conforming to the \"process.owner\"\n// semantic conventions. It represents the username of the user that owns the\n// process.\nfunc ProcessOwner(val string) attribute.KeyValue {\n\treturn ProcessOwnerKey.String(val)\n}\n\n// ProcessParentPID returns an attribute KeyValue conforming to the\n// \"process.parent_pid\" semantic conventions. It represents the parent Process\n// identifier (PPID).\nfunc ProcessParentPID(val int) attribute.KeyValue {\n\treturn ProcessParentPIDKey.Int(val)\n}\n\n// ProcessPID returns an attribute KeyValue conforming to the \"process.pid\"\n// semantic conventions. It represents the process identifier (PID).\nfunc ProcessPID(val int) attribute.KeyValue {\n\treturn ProcessPIDKey.Int(val)\n}\n\n// ProcessRealUserID returns an attribute KeyValue conforming to the\n// \"process.real_user.id\" semantic conventions. It represents the real user ID\n// (RUID) of the process.\nfunc ProcessRealUserID(val int) attribute.KeyValue {\n\treturn ProcessRealUserIDKey.Int(val)\n}\n\n// ProcessRealUserName returns an attribute KeyValue conforming to the\n// \"process.real_user.name\" semantic conventions. It represents the username of\n// the real user of the process.\nfunc ProcessRealUserName(val string) attribute.KeyValue {\n\treturn ProcessRealUserNameKey.String(val)\n}\n\n// ProcessRuntimeDescription returns an attribute KeyValue conforming to the\n// \"process.runtime.description\" semantic conventions. It represents an\n// additional description about the runtime of the process, for example a\n// specific vendor customization of the runtime environment.\nfunc ProcessRuntimeDescription(val string) attribute.KeyValue {\n\treturn ProcessRuntimeDescriptionKey.String(val)\n}\n\n// ProcessRuntimeName returns an attribute KeyValue conforming to the\n// \"process.runtime.name\" semantic conventions. It represents the name of the\n// runtime of this process.\nfunc ProcessRuntimeName(val string) attribute.KeyValue {\n\treturn ProcessRuntimeNameKey.String(val)\n}\n\n// ProcessRuntimeVersion returns an attribute KeyValue conforming to the\n// \"process.runtime.version\" semantic conventions. It represents the version of\n// the runtime of this process, as returned by the runtime without modification.\nfunc ProcessRuntimeVersion(val string) attribute.KeyValue {\n\treturn ProcessRuntimeVersionKey.String(val)\n}\n\n// ProcessSavedUserID returns an attribute KeyValue conforming to the\n// \"process.saved_user.id\" semantic conventions. It represents the saved user ID\n// (SUID) of the process.\nfunc ProcessSavedUserID(val int) attribute.KeyValue {\n\treturn ProcessSavedUserIDKey.Int(val)\n}\n\n// ProcessSavedUserName returns an attribute KeyValue conforming to the\n// \"process.saved_user.name\" semantic conventions. It represents the username of\n// the saved user.\nfunc ProcessSavedUserName(val string) attribute.KeyValue {\n\treturn ProcessSavedUserNameKey.String(val)\n}\n\n// ProcessSessionLeaderPID returns an attribute KeyValue conforming to the\n// \"process.session_leader.pid\" semantic conventions. It represents the PID of\n// the process's session leader. This is also the session ID (SID) of the\n// process.\nfunc ProcessSessionLeaderPID(val int) attribute.KeyValue {\n\treturn ProcessSessionLeaderPIDKey.Int(val)\n}\n\n// ProcessTitle returns an attribute KeyValue conforming to the \"process.title\"\n// semantic conventions. It represents the process title (proctitle).\nfunc ProcessTitle(val string) attribute.KeyValue {\n\treturn ProcessTitleKey.String(val)\n}\n\n// ProcessUserID returns an attribute KeyValue conforming to the\n// \"process.user.id\" semantic conventions. It represents the effective user ID\n// (EUID) of the process.\nfunc ProcessUserID(val int) attribute.KeyValue {\n\treturn ProcessUserIDKey.Int(val)\n}\n\n// ProcessUserName returns an attribute KeyValue conforming to the\n// \"process.user.name\" semantic conventions. It represents the username of the\n// effective user of the process.\nfunc ProcessUserName(val string) attribute.KeyValue {\n\treturn ProcessUserNameKey.String(val)\n}\n\n// ProcessVpid returns an attribute KeyValue conforming to the \"process.vpid\"\n// semantic conventions. It represents the virtual process identifier.\nfunc ProcessVpid(val int) attribute.KeyValue {\n\treturn ProcessVpidKey.Int(val)\n}\n\n// ProcessWorkingDirectory returns an attribute KeyValue conforming to the\n// \"process.working_directory\" semantic conventions. It represents the working\n// directory of the process.\nfunc ProcessWorkingDirectory(val string) attribute.KeyValue {\n\treturn ProcessWorkingDirectoryKey.String(val)\n}\n\n// Enum values for process.context_switch_type\nvar (\n\t// voluntary\n\t// Stability: development\n\tProcessContextSwitchTypeVoluntary = ProcessContextSwitchTypeKey.String(\"voluntary\")\n\t// involuntary\n\t// Stability: development\n\tProcessContextSwitchTypeInvoluntary = ProcessContextSwitchTypeKey.String(\"involuntary\")\n)\n\n// Enum values for process.paging.fault_type\nvar (\n\t// major\n\t// Stability: development\n\tProcessPagingFaultTypeMajor = ProcessPagingFaultTypeKey.String(\"major\")\n\t// minor\n\t// Stability: development\n\tProcessPagingFaultTypeMinor = ProcessPagingFaultTypeKey.String(\"minor\")\n)\n\n// Namespace: profile\nconst (\n\t// ProfileFrameTypeKey is the attribute Key conforming to the\n\t// \"profile.frame.type\" semantic conventions. It represents the describes the\n\t// interpreter or compiler of a single frame.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"cpython\"\n\tProfileFrameTypeKey = attribute.Key(\"profile.frame.type\")\n)\n\n// Enum values for profile.frame.type\nvar (\n\t// [.NET]\n\t//\n\t// Stability: development\n\t//\n\t// [.NET]: https://wikipedia.org/wiki/.NET\n\tProfileFrameTypeDotnet = ProfileFrameTypeKey.String(\"dotnet\")\n\t// [JVM]\n\t//\n\t// Stability: development\n\t//\n\t// [JVM]: https://wikipedia.org/wiki/Java_virtual_machine\n\tProfileFrameTypeJVM = ProfileFrameTypeKey.String(\"jvm\")\n\t// [Kernel]\n\t//\n\t// Stability: development\n\t//\n\t// [Kernel]: https://wikipedia.org/wiki/Kernel_(operating_system)\n\tProfileFrameTypeKernel = ProfileFrameTypeKey.String(\"kernel\")\n\t// Can be one of but not limited to [C], [C++], [Go] or [Rust]. If possible, a\n\t// more precise value MUST be used.\n\t//\n\t// Stability: development\n\t//\n\t// [C]: https://wikipedia.org/wiki/C_(programming_language)\n\t// [C++]: https://wikipedia.org/wiki/C%2B%2B\n\t// [Go]: https://wikipedia.org/wiki/Go_(programming_language)\n\t// [Rust]: https://wikipedia.org/wiki/Rust_(programming_language)\n\tProfileFrameTypeNative = ProfileFrameTypeKey.String(\"native\")\n\t// [Perl]\n\t//\n\t// Stability: development\n\t//\n\t// [Perl]: https://wikipedia.org/wiki/Perl\n\tProfileFrameTypePerl = ProfileFrameTypeKey.String(\"perl\")\n\t// [PHP]\n\t//\n\t// Stability: development\n\t//\n\t// [PHP]: https://wikipedia.org/wiki/PHP\n\tProfileFrameTypePHP = ProfileFrameTypeKey.String(\"php\")\n\t// [Python]\n\t//\n\t// Stability: development\n\t//\n\t// [Python]: https://wikipedia.org/wiki/Python_(programming_language)\n\tProfileFrameTypeCpython = ProfileFrameTypeKey.String(\"cpython\")\n\t// [Ruby]\n\t//\n\t// Stability: development\n\t//\n\t// [Ruby]: https://wikipedia.org/wiki/Ruby_(programming_language)\n\tProfileFrameTypeRuby = ProfileFrameTypeKey.String(\"ruby\")\n\t// [V8JS]\n\t//\n\t// Stability: development\n\t//\n\t// [V8JS]: https://wikipedia.org/wiki/V8_(JavaScript_engine)\n\tProfileFrameTypeV8JS = ProfileFrameTypeKey.String(\"v8js\")\n\t// [Erlang]\n\t//\n\t// Stability: development\n\t//\n\t// [Erlang]: https://en.wikipedia.org/wiki/BEAM_(Erlang_virtual_machine)\n\tProfileFrameTypeBeam = ProfileFrameTypeKey.String(\"beam\")\n\t// [Go],\n\t//\n\t// Stability: development\n\t//\n\t// [Go]: https://wikipedia.org/wiki/Go_(programming_language)\n\tProfileFrameTypeGo = ProfileFrameTypeKey.String(\"go\")\n\t// [Rust]\n\t//\n\t// Stability: development\n\t//\n\t// [Rust]: https://wikipedia.org/wiki/Rust_(programming_language)\n\tProfileFrameTypeRust = ProfileFrameTypeKey.String(\"rust\")\n)\n\n// Namespace: rpc\nconst (\n\t// RPCConnectRPCErrorCodeKey is the attribute Key conforming to the\n\t// \"rpc.connect_rpc.error_code\" semantic conventions. It represents the\n\t// [error codes] of the Connect request. Error codes are always string values.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t//\n\t// [error codes]: https://connectrpc.com//docs/protocol/#error-codes\n\tRPCConnectRPCErrorCodeKey = attribute.Key(\"rpc.connect_rpc.error_code\")\n\n\t// RPCGRPCStatusCodeKey is the attribute Key conforming to the\n\t// \"rpc.grpc.status_code\" semantic conventions. It represents the\n\t// [numeric status code] of the gRPC request.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t//\n\t// [numeric status code]: https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md\n\tRPCGRPCStatusCodeKey = attribute.Key(\"rpc.grpc.status_code\")\n\n\t// RPCJSONRPCErrorCodeKey is the attribute Key conforming to the\n\t// \"rpc.jsonrpc.error_code\" semantic conventions. It represents the `error.code`\n\t//  property of response if it is an error response.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: -32700, 100\n\tRPCJSONRPCErrorCodeKey = attribute.Key(\"rpc.jsonrpc.error_code\")\n\n\t// RPCJSONRPCErrorMessageKey is the attribute Key conforming to the\n\t// \"rpc.jsonrpc.error_message\" semantic conventions. It represents the\n\t// `error.message` property of response if it is an error response.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Parse error\", \"User already exists\"\n\tRPCJSONRPCErrorMessageKey = attribute.Key(\"rpc.jsonrpc.error_message\")\n\n\t// RPCJSONRPCRequestIDKey is the attribute Key conforming to the\n\t// \"rpc.jsonrpc.request_id\" semantic conventions. It represents the `id`\n\t// property of request or response. Since protocol allows id to be int, string,\n\t// `null` or missing (for notifications), value is expected to be cast to string\n\t// for simplicity. Use empty string in case of `null` value. Omit entirely if\n\t// this is a notification.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"10\", \"request-7\", \"\"\n\tRPCJSONRPCRequestIDKey = attribute.Key(\"rpc.jsonrpc.request_id\")\n\n\t// RPCJSONRPCVersionKey is the attribute Key conforming to the\n\t// \"rpc.jsonrpc.version\" semantic conventions. It represents the protocol\n\t// version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0\n\t// doesn't specify this, the value can be omitted.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2.0\", \"1.0\"\n\tRPCJSONRPCVersionKey = attribute.Key(\"rpc.jsonrpc.version\")\n\n\t// RPCMessageCompressedSizeKey is the attribute Key conforming to the\n\t// \"rpc.message.compressed_size\" semantic conventions. It represents the\n\t// compressed size of the message in bytes.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tRPCMessageCompressedSizeKey = attribute.Key(\"rpc.message.compressed_size\")\n\n\t// RPCMessageIDKey is the attribute Key conforming to the \"rpc.message.id\"\n\t// semantic conventions. It MUST be calculated as two different counters\n\t// starting from `1` one for sent messages and one for received message..\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: This way we guarantee that the values will be consistent between\n\t// different implementations.\n\tRPCMessageIDKey = attribute.Key(\"rpc.message.id\")\n\n\t// RPCMessageTypeKey is the attribute Key conforming to the \"rpc.message.type\"\n\t// semantic conventions. It represents the whether this is a received or sent\n\t// message.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tRPCMessageTypeKey = attribute.Key(\"rpc.message.type\")\n\n\t// RPCMessageUncompressedSizeKey is the attribute Key conforming to the\n\t// \"rpc.message.uncompressed_size\" semantic conventions. It represents the\n\t// uncompressed size of the message in bytes.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tRPCMessageUncompressedSizeKey = attribute.Key(\"rpc.message.uncompressed_size\")\n\n\t// RPCMethodKey is the attribute Key conforming to the \"rpc.method\" semantic\n\t// conventions. It represents the name of the (logical) method being called,\n\t// must be equal to the $method part in the span name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: exampleMethod\n\t// Note: This is the logical name of the method from the RPC interface\n\t// perspective, which can be different from the name of any implementing\n\t// method/function. The `code.function.name` attribute may be used to store the\n\t// latter (e.g., method actually executing the call on the server side, RPC\n\t// client stub method on the client side).\n\tRPCMethodKey = attribute.Key(\"rpc.method\")\n\n\t// RPCServiceKey is the attribute Key conforming to the \"rpc.service\" semantic\n\t// conventions. It represents the full (logical) name of the service being\n\t// called, including its package name, if applicable.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: myservice.EchoService\n\t// Note: This is the logical name of the service from the RPC interface\n\t// perspective, which can be different from the name of any implementing class.\n\t// The `code.namespace` attribute may be used to store the latter (despite the\n\t// attribute name, it may include a class name; e.g., class with method actually\n\t// executing the call on the server side, RPC client stub class on the client\n\t// side).\n\tRPCServiceKey = attribute.Key(\"rpc.service\")\n\n\t// RPCSystemKey is the attribute Key conforming to the \"rpc.system\" semantic\n\t// conventions. It represents a string identifying the remoting system. See\n\t// below for a list of well-known identifiers.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tRPCSystemKey = attribute.Key(\"rpc.system\")\n)\n\n// RPCConnectRPCRequestMetadata returns an attribute KeyValue conforming to the\n// \"rpc.connect_rpc.request.metadata\" semantic conventions. It represents the\n// connect request metadata, `<key>` being the normalized Connect Metadata key\n// (lowercase), the value being the metadata values.\nfunc RPCConnectRPCRequestMetadata(key string, val ...string) attribute.KeyValue {\n\treturn attribute.StringSlice(\"rpc.connect_rpc.request.metadata.\"+key, val)\n}\n\n// RPCConnectRPCResponseMetadata returns an attribute KeyValue conforming to the\n// \"rpc.connect_rpc.response.metadata\" semantic conventions. It represents the\n// connect response metadata, `<key>` being the normalized Connect Metadata key\n// (lowercase), the value being the metadata values.\nfunc RPCConnectRPCResponseMetadata(key string, val ...string) attribute.KeyValue {\n\treturn attribute.StringSlice(\"rpc.connect_rpc.response.metadata.\"+key, val)\n}\n\n// RPCGRPCRequestMetadata returns an attribute KeyValue conforming to the\n// \"rpc.grpc.request.metadata\" semantic conventions. It represents the gRPC\n// request metadata, `<key>` being the normalized gRPC Metadata key (lowercase),\n// the value being the metadata values.\nfunc RPCGRPCRequestMetadata(key string, val ...string) attribute.KeyValue {\n\treturn attribute.StringSlice(\"rpc.grpc.request.metadata.\"+key, val)\n}\n\n// RPCGRPCResponseMetadata returns an attribute KeyValue conforming to the\n// \"rpc.grpc.response.metadata\" semantic conventions. It represents the gRPC\n// response metadata, `<key>` being the normalized gRPC Metadata key (lowercase),\n// the value being the metadata values.\nfunc RPCGRPCResponseMetadata(key string, val ...string) attribute.KeyValue {\n\treturn attribute.StringSlice(\"rpc.grpc.response.metadata.\"+key, val)\n}\n\n// RPCJSONRPCErrorCode returns an attribute KeyValue conforming to the\n// \"rpc.jsonrpc.error_code\" semantic conventions. It represents the `error.code`\n// property of response if it is an error response.\nfunc RPCJSONRPCErrorCode(val int) attribute.KeyValue {\n\treturn RPCJSONRPCErrorCodeKey.Int(val)\n}\n\n// RPCJSONRPCErrorMessage returns an attribute KeyValue conforming to the\n// \"rpc.jsonrpc.error_message\" semantic conventions. It represents the\n// `error.message` property of response if it is an error response.\nfunc RPCJSONRPCErrorMessage(val string) attribute.KeyValue {\n\treturn RPCJSONRPCErrorMessageKey.String(val)\n}\n\n// RPCJSONRPCRequestID returns an attribute KeyValue conforming to the\n// \"rpc.jsonrpc.request_id\" semantic conventions. It represents the `id` property\n// of request or response. Since protocol allows id to be int, string, `null` or\n// missing (for notifications), value is expected to be cast to string for\n// simplicity. Use empty string in case of `null` value. Omit entirely if this is\n// a notification.\nfunc RPCJSONRPCRequestID(val string) attribute.KeyValue {\n\treturn RPCJSONRPCRequestIDKey.String(val)\n}\n\n// RPCJSONRPCVersion returns an attribute KeyValue conforming to the\n// \"rpc.jsonrpc.version\" semantic conventions. It represents the protocol version\n// as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 doesn't\n// specify this, the value can be omitted.\nfunc RPCJSONRPCVersion(val string) attribute.KeyValue {\n\treturn RPCJSONRPCVersionKey.String(val)\n}\n\n// RPCMessageCompressedSize returns an attribute KeyValue conforming to the\n// \"rpc.message.compressed_size\" semantic conventions. It represents the\n// compressed size of the message in bytes.\nfunc RPCMessageCompressedSize(val int) attribute.KeyValue {\n\treturn RPCMessageCompressedSizeKey.Int(val)\n}\n\n// RPCMessageID returns an attribute KeyValue conforming to the \"rpc.message.id\"\n// semantic conventions. It MUST be calculated as two different counters starting\n// from `1` one for sent messages and one for received message..\nfunc RPCMessageID(val int) attribute.KeyValue {\n\treturn RPCMessageIDKey.Int(val)\n}\n\n// RPCMessageUncompressedSize returns an attribute KeyValue conforming to the\n// \"rpc.message.uncompressed_size\" semantic conventions. It represents the\n// uncompressed size of the message in bytes.\nfunc RPCMessageUncompressedSize(val int) attribute.KeyValue {\n\treturn RPCMessageUncompressedSizeKey.Int(val)\n}\n\n// RPCMethod returns an attribute KeyValue conforming to the \"rpc.method\"\n// semantic conventions. It represents the name of the (logical) method being\n// called, must be equal to the $method part in the span name.\nfunc RPCMethod(val string) attribute.KeyValue {\n\treturn RPCMethodKey.String(val)\n}\n\n// RPCService returns an attribute KeyValue conforming to the \"rpc.service\"\n// semantic conventions. It represents the full (logical) name of the service\n// being called, including its package name, if applicable.\nfunc RPCService(val string) attribute.KeyValue {\n\treturn RPCServiceKey.String(val)\n}\n\n// Enum values for rpc.connect_rpc.error_code\nvar (\n\t// cancelled\n\t// Stability: development\n\tRPCConnectRPCErrorCodeCancelled = RPCConnectRPCErrorCodeKey.String(\"cancelled\")\n\t// unknown\n\t// Stability: development\n\tRPCConnectRPCErrorCodeUnknown = RPCConnectRPCErrorCodeKey.String(\"unknown\")\n\t// invalid_argument\n\t// Stability: development\n\tRPCConnectRPCErrorCodeInvalidArgument = RPCConnectRPCErrorCodeKey.String(\"invalid_argument\")\n\t// deadline_exceeded\n\t// Stability: development\n\tRPCConnectRPCErrorCodeDeadlineExceeded = RPCConnectRPCErrorCodeKey.String(\"deadline_exceeded\")\n\t// not_found\n\t// Stability: development\n\tRPCConnectRPCErrorCodeNotFound = RPCConnectRPCErrorCodeKey.String(\"not_found\")\n\t// already_exists\n\t// Stability: development\n\tRPCConnectRPCErrorCodeAlreadyExists = RPCConnectRPCErrorCodeKey.String(\"already_exists\")\n\t// permission_denied\n\t// Stability: development\n\tRPCConnectRPCErrorCodePermissionDenied = RPCConnectRPCErrorCodeKey.String(\"permission_denied\")\n\t// resource_exhausted\n\t// Stability: development\n\tRPCConnectRPCErrorCodeResourceExhausted = RPCConnectRPCErrorCodeKey.String(\"resource_exhausted\")\n\t// failed_precondition\n\t// Stability: development\n\tRPCConnectRPCErrorCodeFailedPrecondition = RPCConnectRPCErrorCodeKey.String(\"failed_precondition\")\n\t// aborted\n\t// Stability: development\n\tRPCConnectRPCErrorCodeAborted = RPCConnectRPCErrorCodeKey.String(\"aborted\")\n\t// out_of_range\n\t// Stability: development\n\tRPCConnectRPCErrorCodeOutOfRange = RPCConnectRPCErrorCodeKey.String(\"out_of_range\")\n\t// unimplemented\n\t// Stability: development\n\tRPCConnectRPCErrorCodeUnimplemented = RPCConnectRPCErrorCodeKey.String(\"unimplemented\")\n\t// internal\n\t// Stability: development\n\tRPCConnectRPCErrorCodeInternal = RPCConnectRPCErrorCodeKey.String(\"internal\")\n\t// unavailable\n\t// Stability: development\n\tRPCConnectRPCErrorCodeUnavailable = RPCConnectRPCErrorCodeKey.String(\"unavailable\")\n\t// data_loss\n\t// Stability: development\n\tRPCConnectRPCErrorCodeDataLoss = RPCConnectRPCErrorCodeKey.String(\"data_loss\")\n\t// unauthenticated\n\t// Stability: development\n\tRPCConnectRPCErrorCodeUnauthenticated = RPCConnectRPCErrorCodeKey.String(\"unauthenticated\")\n)\n\n// Enum values for rpc.grpc.status_code\nvar (\n\t// OK\n\t// Stability: development\n\tRPCGRPCStatusCodeOk = RPCGRPCStatusCodeKey.Int(0)\n\t// CANCELLED\n\t// Stability: development\n\tRPCGRPCStatusCodeCancelled = RPCGRPCStatusCodeKey.Int(1)\n\t// UNKNOWN\n\t// Stability: development\n\tRPCGRPCStatusCodeUnknown = RPCGRPCStatusCodeKey.Int(2)\n\t// INVALID_ARGUMENT\n\t// Stability: development\n\tRPCGRPCStatusCodeInvalidArgument = RPCGRPCStatusCodeKey.Int(3)\n\t// DEADLINE_EXCEEDED\n\t// Stability: development\n\tRPCGRPCStatusCodeDeadlineExceeded = RPCGRPCStatusCodeKey.Int(4)\n\t// NOT_FOUND\n\t// Stability: development\n\tRPCGRPCStatusCodeNotFound = RPCGRPCStatusCodeKey.Int(5)\n\t// ALREADY_EXISTS\n\t// Stability: development\n\tRPCGRPCStatusCodeAlreadyExists = RPCGRPCStatusCodeKey.Int(6)\n\t// PERMISSION_DENIED\n\t// Stability: development\n\tRPCGRPCStatusCodePermissionDenied = RPCGRPCStatusCodeKey.Int(7)\n\t// RESOURCE_EXHAUSTED\n\t// Stability: development\n\tRPCGRPCStatusCodeResourceExhausted = RPCGRPCStatusCodeKey.Int(8)\n\t// FAILED_PRECONDITION\n\t// Stability: development\n\tRPCGRPCStatusCodeFailedPrecondition = RPCGRPCStatusCodeKey.Int(9)\n\t// ABORTED\n\t// Stability: development\n\tRPCGRPCStatusCodeAborted = RPCGRPCStatusCodeKey.Int(10)\n\t// OUT_OF_RANGE\n\t// Stability: development\n\tRPCGRPCStatusCodeOutOfRange = RPCGRPCStatusCodeKey.Int(11)\n\t// UNIMPLEMENTED\n\t// Stability: development\n\tRPCGRPCStatusCodeUnimplemented = RPCGRPCStatusCodeKey.Int(12)\n\t// INTERNAL\n\t// Stability: development\n\tRPCGRPCStatusCodeInternal = RPCGRPCStatusCodeKey.Int(13)\n\t// UNAVAILABLE\n\t// Stability: development\n\tRPCGRPCStatusCodeUnavailable = RPCGRPCStatusCodeKey.Int(14)\n\t// DATA_LOSS\n\t// Stability: development\n\tRPCGRPCStatusCodeDataLoss = RPCGRPCStatusCodeKey.Int(15)\n\t// UNAUTHENTICATED\n\t// Stability: development\n\tRPCGRPCStatusCodeUnauthenticated = RPCGRPCStatusCodeKey.Int(16)\n)\n\n// Enum values for rpc.message.type\nvar (\n\t// sent\n\t// Stability: development\n\tRPCMessageTypeSent = RPCMessageTypeKey.String(\"SENT\")\n\t// received\n\t// Stability: development\n\tRPCMessageTypeReceived = RPCMessageTypeKey.String(\"RECEIVED\")\n)\n\n// Enum values for rpc.system\nvar (\n\t// gRPC\n\t// Stability: development\n\tRPCSystemGRPC = RPCSystemKey.String(\"grpc\")\n\t// Java RMI\n\t// Stability: development\n\tRPCSystemJavaRmi = RPCSystemKey.String(\"java_rmi\")\n\t// .NET WCF\n\t// Stability: development\n\tRPCSystemDotnetWcf = RPCSystemKey.String(\"dotnet_wcf\")\n\t// Apache Dubbo\n\t// Stability: development\n\tRPCSystemApacheDubbo = RPCSystemKey.String(\"apache_dubbo\")\n\t// Connect RPC\n\t// Stability: development\n\tRPCSystemConnectRPC = RPCSystemKey.String(\"connect_rpc\")\n)\n\n// Namespace: security_rule\nconst (\n\t// SecurityRuleCategoryKey is the attribute Key conforming to the\n\t// \"security_rule.category\" semantic conventions. It represents a categorization\n\t// value keyword used by the entity using the rule for detection of this event.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Attempted Information Leak\"\n\tSecurityRuleCategoryKey = attribute.Key(\"security_rule.category\")\n\n\t// SecurityRuleDescriptionKey is the attribute Key conforming to the\n\t// \"security_rule.description\" semantic conventions. It represents the\n\t// description of the rule generating the event.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Block requests to public DNS over HTTPS / TLS protocols\"\n\tSecurityRuleDescriptionKey = attribute.Key(\"security_rule.description\")\n\n\t// SecurityRuleLicenseKey is the attribute Key conforming to the\n\t// \"security_rule.license\" semantic conventions. It represents the name of the\n\t// license under which the rule used to generate this event is made available.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Apache 2.0\"\n\tSecurityRuleLicenseKey = attribute.Key(\"security_rule.license\")\n\n\t// SecurityRuleNameKey is the attribute Key conforming to the\n\t// \"security_rule.name\" semantic conventions. It represents the name of the rule\n\t// or signature generating the event.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"BLOCK_DNS_over_TLS\"\n\tSecurityRuleNameKey = attribute.Key(\"security_rule.name\")\n\n\t// SecurityRuleReferenceKey is the attribute Key conforming to the\n\t// \"security_rule.reference\" semantic conventions. It represents the reference\n\t// URL to additional information about the rule used to generate this event.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"https://en.wikipedia.org/wiki/DNS_over_TLS\"\n\t// Note: The URL can point to the vendor’s documentation about the rule. If\n\t// that’s not available, it can also be a link to a more general page\n\t// describing this type of alert.\n\tSecurityRuleReferenceKey = attribute.Key(\"security_rule.reference\")\n\n\t// SecurityRuleRulesetNameKey is the attribute Key conforming to the\n\t// \"security_rule.ruleset.name\" semantic conventions. It represents the name of\n\t// the ruleset, policy, group, or parent category in which the rule used to\n\t// generate this event is a member.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Standard_Protocol_Filters\"\n\tSecurityRuleRulesetNameKey = attribute.Key(\"security_rule.ruleset.name\")\n\n\t// SecurityRuleUUIDKey is the attribute Key conforming to the\n\t// \"security_rule.uuid\" semantic conventions. It represents a rule ID that is\n\t// unique within the scope of a set or group of agents, observers, or other\n\t// entities using the rule for detection of this event.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"550e8400-e29b-41d4-a716-446655440000\", \"1100110011\"\n\tSecurityRuleUUIDKey = attribute.Key(\"security_rule.uuid\")\n\n\t// SecurityRuleVersionKey is the attribute Key conforming to the\n\t// \"security_rule.version\" semantic conventions. It represents the version /\n\t// revision of the rule being used for analysis.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1.0.0\"\n\tSecurityRuleVersionKey = attribute.Key(\"security_rule.version\")\n)\n\n// SecurityRuleCategory returns an attribute KeyValue conforming to the\n// \"security_rule.category\" semantic conventions. It represents a categorization\n// value keyword used by the entity using the rule for detection of this event.\nfunc SecurityRuleCategory(val string) attribute.KeyValue {\n\treturn SecurityRuleCategoryKey.String(val)\n}\n\n// SecurityRuleDescription returns an attribute KeyValue conforming to the\n// \"security_rule.description\" semantic conventions. It represents the\n// description of the rule generating the event.\nfunc SecurityRuleDescription(val string) attribute.KeyValue {\n\treturn SecurityRuleDescriptionKey.String(val)\n}\n\n// SecurityRuleLicense returns an attribute KeyValue conforming to the\n// \"security_rule.license\" semantic conventions. It represents the name of the\n// license under which the rule used to generate this event is made available.\nfunc SecurityRuleLicense(val string) attribute.KeyValue {\n\treturn SecurityRuleLicenseKey.String(val)\n}\n\n// SecurityRuleName returns an attribute KeyValue conforming to the\n// \"security_rule.name\" semantic conventions. It represents the name of the rule\n// or signature generating the event.\nfunc SecurityRuleName(val string) attribute.KeyValue {\n\treturn SecurityRuleNameKey.String(val)\n}\n\n// SecurityRuleReference returns an attribute KeyValue conforming to the\n// \"security_rule.reference\" semantic conventions. It represents the reference\n// URL to additional information about the rule used to generate this event.\nfunc SecurityRuleReference(val string) attribute.KeyValue {\n\treturn SecurityRuleReferenceKey.String(val)\n}\n\n// SecurityRuleRulesetName returns an attribute KeyValue conforming to the\n// \"security_rule.ruleset.name\" semantic conventions. It represents the name of\n// the ruleset, policy, group, or parent category in which the rule used to\n// generate this event is a member.\nfunc SecurityRuleRulesetName(val string) attribute.KeyValue {\n\treturn SecurityRuleRulesetNameKey.String(val)\n}\n\n// SecurityRuleUUID returns an attribute KeyValue conforming to the\n// \"security_rule.uuid\" semantic conventions. It represents a rule ID that is\n// unique within the scope of a set or group of agents, observers, or other\n// entities using the rule for detection of this event.\nfunc SecurityRuleUUID(val string) attribute.KeyValue {\n\treturn SecurityRuleUUIDKey.String(val)\n}\n\n// SecurityRuleVersion returns an attribute KeyValue conforming to the\n// \"security_rule.version\" semantic conventions. It represents the version /\n// revision of the rule being used for analysis.\nfunc SecurityRuleVersion(val string) attribute.KeyValue {\n\treturn SecurityRuleVersionKey.String(val)\n}\n\n// Namespace: server\nconst (\n\t// ServerAddressKey is the attribute Key conforming to the \"server.address\"\n\t// semantic conventions. It represents the server domain name if available\n\t// without reverse DNS lookup; otherwise, IP address or Unix domain socket name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"example.com\", \"10.1.2.80\", \"/tmp/my.sock\"\n\t// Note: When observed from the client side, and when communicating through an\n\t// intermediary, `server.address` SHOULD represent the server address behind any\n\t// intermediaries, for example proxies, if it's available.\n\tServerAddressKey = attribute.Key(\"server.address\")\n\n\t// ServerPortKey is the attribute Key conforming to the \"server.port\" semantic\n\t// conventions. It represents the server port number.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: 80, 8080, 443\n\t// Note: When observed from the client side, and when communicating through an\n\t// intermediary, `server.port` SHOULD represent the server port behind any\n\t// intermediaries, for example proxies, if it's available.\n\tServerPortKey = attribute.Key(\"server.port\")\n)\n\n// ServerAddress returns an attribute KeyValue conforming to the \"server.address\"\n// semantic conventions. It represents the server domain name if available\n// without reverse DNS lookup; otherwise, IP address or Unix domain socket name.\nfunc ServerAddress(val string) attribute.KeyValue {\n\treturn ServerAddressKey.String(val)\n}\n\n// ServerPort returns an attribute KeyValue conforming to the \"server.port\"\n// semantic conventions. It represents the server port number.\nfunc ServerPort(val int) attribute.KeyValue {\n\treturn ServerPortKey.Int(val)\n}\n\n// Namespace: service\nconst (\n\t// ServiceInstanceIDKey is the attribute Key conforming to the\n\t// \"service.instance.id\" semantic conventions. It represents the string ID of\n\t// the service instance.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"627cc493-f310-47de-96bd-71410b7dec09\"\n\t// Note: MUST be unique for each instance of the same\n\t// `service.namespace,service.name` pair (in other words\n\t// `service.namespace,service.name,service.instance.id` triplet MUST be globally\n\t// unique). The ID helps to\n\t// distinguish instances of the same service that exist at the same time (e.g.\n\t// instances of a horizontally scaled\n\t// service).\n\t//\n\t// Implementations, such as SDKs, are recommended to generate a random Version 1\n\t// or Version 4 [RFC\n\t// 4122] UUID, but are free to use an inherent unique ID as\n\t// the source of\n\t// this value if stability is desirable. In that case, the ID SHOULD be used as\n\t// source of a UUID Version 5 and\n\t// SHOULD use the following UUID as the namespace:\n\t// `4d63009a-8d0f-11ee-aad7-4c796ed8e320`.\n\t//\n\t// UUIDs are typically recommended, as only an opaque value for the purposes of\n\t// identifying a service instance is\n\t// needed. Similar to what can be seen in the man page for the\n\t// [`/etc/machine-id`] file, the underlying\n\t// data, such as pod name and namespace should be treated as confidential, being\n\t// the user's choice to expose it\n\t// or not via another resource attribute.\n\t//\n\t// For applications running behind an application server (like unicorn), we do\n\t// not recommend using one identifier\n\t// for all processes participating in the application. Instead, it's recommended\n\t// each division (e.g. a worker\n\t// thread in unicorn) to have its own instance.id.\n\t//\n\t// It's not recommended for a Collector to set `service.instance.id` if it can't\n\t// unambiguously determine the\n\t// service instance that is generating that telemetry. For instance, creating an\n\t// UUID based on `pod.name` will\n\t// likely be wrong, as the Collector might not know from which container within\n\t// that pod the telemetry originated.\n\t// However, Collectors can set the `service.instance.id` if they can\n\t// unambiguously determine the service instance\n\t// for that telemetry. This is typically the case for scraping receivers, as\n\t// they know the target address and\n\t// port.\n\t//\n\t// [RFC\n\t// 4122]: https://www.ietf.org/rfc/rfc4122.txt\n\t// [`/etc/machine-id`]: https://www.freedesktop.org/software/systemd/man/latest/machine-id.html\n\tServiceInstanceIDKey = attribute.Key(\"service.instance.id\")\n\n\t// ServiceNameKey is the attribute Key conforming to the \"service.name\" semantic\n\t// conventions. It represents the logical name of the service.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"shoppingcart\"\n\t// Note: MUST be the same for all instances of horizontally scaled services. If\n\t// the value was not specified, SDKs MUST fallback to `unknown_service:`\n\t// concatenated with [`process.executable.name`], e.g. `unknown_service:bash`.\n\t// If `process.executable.name` is not available, the value MUST be set to\n\t// `unknown_service`.\n\t//\n\t// [`process.executable.name`]: process.md\n\tServiceNameKey = attribute.Key(\"service.name\")\n\n\t// ServiceNamespaceKey is the attribute Key conforming to the\n\t// \"service.namespace\" semantic conventions. It represents a namespace for\n\t// `service.name`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Shop\"\n\t// Note: A string value having a meaning that helps to distinguish a group of\n\t// services, for example the team name that owns a group of services.\n\t// `service.name` is expected to be unique within the same namespace. If\n\t// `service.namespace` is not specified in the Resource then `service.name` is\n\t// expected to be unique for all services that have no explicit namespace\n\t// defined (so the empty/unspecified namespace is simply one more valid\n\t// namespace). Zero-length namespace string is assumed equal to unspecified\n\t// namespace.\n\tServiceNamespaceKey = attribute.Key(\"service.namespace\")\n\n\t// ServiceVersionKey is the attribute Key conforming to the \"service.version\"\n\t// semantic conventions. It represents the version string of the service API or\n\t// implementation. The format is not defined by these conventions.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"2.0.0\", \"a01dbef8a\"\n\tServiceVersionKey = attribute.Key(\"service.version\")\n)\n\n// ServiceInstanceID returns an attribute KeyValue conforming to the\n// \"service.instance.id\" semantic conventions. It represents the string ID of the\n// service instance.\nfunc ServiceInstanceID(val string) attribute.KeyValue {\n\treturn ServiceInstanceIDKey.String(val)\n}\n\n// ServiceName returns an attribute KeyValue conforming to the \"service.name\"\n// semantic conventions. It represents the logical name of the service.\nfunc ServiceName(val string) attribute.KeyValue {\n\treturn ServiceNameKey.String(val)\n}\n\n// ServiceNamespace returns an attribute KeyValue conforming to the\n// \"service.namespace\" semantic conventions. It represents a namespace for\n// `service.name`.\nfunc ServiceNamespace(val string) attribute.KeyValue {\n\treturn ServiceNamespaceKey.String(val)\n}\n\n// ServiceVersion returns an attribute KeyValue conforming to the\n// \"service.version\" semantic conventions. It represents the version string of\n// the service API or implementation. The format is not defined by these\n// conventions.\nfunc ServiceVersion(val string) attribute.KeyValue {\n\treturn ServiceVersionKey.String(val)\n}\n\n// Namespace: session\nconst (\n\t// SessionIDKey is the attribute Key conforming to the \"session.id\" semantic\n\t// conventions. It represents a unique id to identify a session.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 00112233-4455-6677-8899-aabbccddeeff\n\tSessionIDKey = attribute.Key(\"session.id\")\n\n\t// SessionPreviousIDKey is the attribute Key conforming to the\n\t// \"session.previous_id\" semantic conventions. It represents the previous\n\t// `session.id` for this user, when known.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 00112233-4455-6677-8899-aabbccddeeff\n\tSessionPreviousIDKey = attribute.Key(\"session.previous_id\")\n)\n\n// SessionID returns an attribute KeyValue conforming to the \"session.id\"\n// semantic conventions. It represents a unique id to identify a session.\nfunc SessionID(val string) attribute.KeyValue {\n\treturn SessionIDKey.String(val)\n}\n\n// SessionPreviousID returns an attribute KeyValue conforming to the\n// \"session.previous_id\" semantic conventions. It represents the previous\n// `session.id` for this user, when known.\nfunc SessionPreviousID(val string) attribute.KeyValue {\n\treturn SessionPreviousIDKey.String(val)\n}\n\n// Namespace: signalr\nconst (\n\t// SignalRConnectionStatusKey is the attribute Key conforming to the\n\t// \"signalr.connection.status\" semantic conventions. It represents the signalR\n\t// HTTP connection closure status.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"app_shutdown\", \"timeout\"\n\tSignalRConnectionStatusKey = attribute.Key(\"signalr.connection.status\")\n\n\t// SignalRTransportKey is the attribute Key conforming to the\n\t// \"signalr.transport\" semantic conventions. It represents the\n\t// [SignalR transport type].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"web_sockets\", \"long_polling\"\n\t//\n\t// [SignalR transport type]: https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md\n\tSignalRTransportKey = attribute.Key(\"signalr.transport\")\n)\n\n// Enum values for signalr.connection.status\nvar (\n\t// The connection was closed normally.\n\t// Stability: stable\n\tSignalRConnectionStatusNormalClosure = SignalRConnectionStatusKey.String(\"normal_closure\")\n\t// The connection was closed due to a timeout.\n\t// Stability: stable\n\tSignalRConnectionStatusTimeout = SignalRConnectionStatusKey.String(\"timeout\")\n\t// The connection was closed because the app is shutting down.\n\t// Stability: stable\n\tSignalRConnectionStatusAppShutdown = SignalRConnectionStatusKey.String(\"app_shutdown\")\n)\n\n// Enum values for signalr.transport\nvar (\n\t// ServerSentEvents protocol\n\t// Stability: stable\n\tSignalRTransportServerSentEvents = SignalRTransportKey.String(\"server_sent_events\")\n\t// LongPolling protocol\n\t// Stability: stable\n\tSignalRTransportLongPolling = SignalRTransportKey.String(\"long_polling\")\n\t// WebSockets protocol\n\t// Stability: stable\n\tSignalRTransportWebSockets = SignalRTransportKey.String(\"web_sockets\")\n)\n\n// Namespace: source\nconst (\n\t// SourceAddressKey is the attribute Key conforming to the \"source.address\"\n\t// semantic conventions. It represents the source address - domain name if\n\t// available without reverse DNS lookup; otherwise, IP address or Unix domain\n\t// socket name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"source.example.com\", \"10.1.2.80\", \"/tmp/my.sock\"\n\t// Note: When observed from the destination side, and when communicating through\n\t// an intermediary, `source.address` SHOULD represent the source address behind\n\t// any intermediaries, for example proxies, if it's available.\n\tSourceAddressKey = attribute.Key(\"source.address\")\n\n\t// SourcePortKey is the attribute Key conforming to the \"source.port\" semantic\n\t// conventions. It represents the source port number.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 3389, 2888\n\tSourcePortKey = attribute.Key(\"source.port\")\n)\n\n// SourceAddress returns an attribute KeyValue conforming to the \"source.address\"\n// semantic conventions. It represents the source address - domain name if\n// available without reverse DNS lookup; otherwise, IP address or Unix domain\n// socket name.\nfunc SourceAddress(val string) attribute.KeyValue {\n\treturn SourceAddressKey.String(val)\n}\n\n// SourcePort returns an attribute KeyValue conforming to the \"source.port\"\n// semantic conventions. It represents the source port number.\nfunc SourcePort(val int) attribute.KeyValue {\n\treturn SourcePortKey.Int(val)\n}\n\n// Namespace: system\nconst (\n\t// SystemCPULogicalNumberKey is the attribute Key conforming to the\n\t// \"system.cpu.logical_number\" semantic conventions. It represents the\n\t// deprecated, use `cpu.logical_number` instead.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1\n\tSystemCPULogicalNumberKey = attribute.Key(\"system.cpu.logical_number\")\n\n\t// SystemDeviceKey is the attribute Key conforming to the \"system.device\"\n\t// semantic conventions. It represents the device identifier.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"(identifier)\"\n\tSystemDeviceKey = attribute.Key(\"system.device\")\n\n\t// SystemFilesystemModeKey is the attribute Key conforming to the\n\t// \"system.filesystem.mode\" semantic conventions. It represents the filesystem\n\t// mode.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"rw, ro\"\n\tSystemFilesystemModeKey = attribute.Key(\"system.filesystem.mode\")\n\n\t// SystemFilesystemMountpointKey is the attribute Key conforming to the\n\t// \"system.filesystem.mountpoint\" semantic conventions. It represents the\n\t// filesystem mount path.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/mnt/data\"\n\tSystemFilesystemMountpointKey = attribute.Key(\"system.filesystem.mountpoint\")\n\n\t// SystemFilesystemStateKey is the attribute Key conforming to the\n\t// \"system.filesystem.state\" semantic conventions. It represents the filesystem\n\t// state.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"used\"\n\tSystemFilesystemStateKey = attribute.Key(\"system.filesystem.state\")\n\n\t// SystemFilesystemTypeKey is the attribute Key conforming to the\n\t// \"system.filesystem.type\" semantic conventions. It represents the filesystem\n\t// type.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"ext4\"\n\tSystemFilesystemTypeKey = attribute.Key(\"system.filesystem.type\")\n\n\t// SystemMemoryStateKey is the attribute Key conforming to the\n\t// \"system.memory.state\" semantic conventions. It represents the memory state.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"free\", \"cached\"\n\tSystemMemoryStateKey = attribute.Key(\"system.memory.state\")\n\n\t// SystemPagingDirectionKey is the attribute Key conforming to the\n\t// \"system.paging.direction\" semantic conventions. It represents the paging\n\t// access direction.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"in\"\n\tSystemPagingDirectionKey = attribute.Key(\"system.paging.direction\")\n\n\t// SystemPagingStateKey is the attribute Key conforming to the\n\t// \"system.paging.state\" semantic conventions. It represents the memory paging\n\t// state.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"free\"\n\tSystemPagingStateKey = attribute.Key(\"system.paging.state\")\n\n\t// SystemPagingTypeKey is the attribute Key conforming to the\n\t// \"system.paging.type\" semantic conventions. It represents the memory paging\n\t// type.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"minor\"\n\tSystemPagingTypeKey = attribute.Key(\"system.paging.type\")\n\n\t// SystemProcessStatusKey is the attribute Key conforming to the\n\t// \"system.process.status\" semantic conventions. It represents the process\n\t// state, e.g., [Linux Process State Codes].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"running\"\n\t//\n\t// [Linux Process State Codes]: https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES\n\tSystemProcessStatusKey = attribute.Key(\"system.process.status\")\n)\n\n// SystemCPULogicalNumber returns an attribute KeyValue conforming to the\n// \"system.cpu.logical_number\" semantic conventions. It represents the\n// deprecated, use `cpu.logical_number` instead.\nfunc SystemCPULogicalNumber(val int) attribute.KeyValue {\n\treturn SystemCPULogicalNumberKey.Int(val)\n}\n\n// SystemDevice returns an attribute KeyValue conforming to the \"system.device\"\n// semantic conventions. It represents the device identifier.\nfunc SystemDevice(val string) attribute.KeyValue {\n\treturn SystemDeviceKey.String(val)\n}\n\n// SystemFilesystemMode returns an attribute KeyValue conforming to the\n// \"system.filesystem.mode\" semantic conventions. It represents the filesystem\n// mode.\nfunc SystemFilesystemMode(val string) attribute.KeyValue {\n\treturn SystemFilesystemModeKey.String(val)\n}\n\n// SystemFilesystemMountpoint returns an attribute KeyValue conforming to the\n// \"system.filesystem.mountpoint\" semantic conventions. It represents the\n// filesystem mount path.\nfunc SystemFilesystemMountpoint(val string) attribute.KeyValue {\n\treturn SystemFilesystemMountpointKey.String(val)\n}\n\n// Enum values for system.filesystem.state\nvar (\n\t// used\n\t// Stability: development\n\tSystemFilesystemStateUsed = SystemFilesystemStateKey.String(\"used\")\n\t// free\n\t// Stability: development\n\tSystemFilesystemStateFree = SystemFilesystemStateKey.String(\"free\")\n\t// reserved\n\t// Stability: development\n\tSystemFilesystemStateReserved = SystemFilesystemStateKey.String(\"reserved\")\n)\n\n// Enum values for system.filesystem.type\nvar (\n\t// fat32\n\t// Stability: development\n\tSystemFilesystemTypeFat32 = SystemFilesystemTypeKey.String(\"fat32\")\n\t// exfat\n\t// Stability: development\n\tSystemFilesystemTypeExfat = SystemFilesystemTypeKey.String(\"exfat\")\n\t// ntfs\n\t// Stability: development\n\tSystemFilesystemTypeNtfs = SystemFilesystemTypeKey.String(\"ntfs\")\n\t// refs\n\t// Stability: development\n\tSystemFilesystemTypeRefs = SystemFilesystemTypeKey.String(\"refs\")\n\t// hfsplus\n\t// Stability: development\n\tSystemFilesystemTypeHfsplus = SystemFilesystemTypeKey.String(\"hfsplus\")\n\t// ext4\n\t// Stability: development\n\tSystemFilesystemTypeExt4 = SystemFilesystemTypeKey.String(\"ext4\")\n)\n\n// Enum values for system.memory.state\nvar (\n\t// Actual used virtual memory in bytes.\n\t// Stability: development\n\tSystemMemoryStateUsed = SystemMemoryStateKey.String(\"used\")\n\t// free\n\t// Stability: development\n\tSystemMemoryStateFree = SystemMemoryStateKey.String(\"free\")\n\t// buffers\n\t// Stability: development\n\tSystemMemoryStateBuffers = SystemMemoryStateKey.String(\"buffers\")\n\t// cached\n\t// Stability: development\n\tSystemMemoryStateCached = SystemMemoryStateKey.String(\"cached\")\n)\n\n// Enum values for system.paging.direction\nvar (\n\t// in\n\t// Stability: development\n\tSystemPagingDirectionIn = SystemPagingDirectionKey.String(\"in\")\n\t// out\n\t// Stability: development\n\tSystemPagingDirectionOut = SystemPagingDirectionKey.String(\"out\")\n)\n\n// Enum values for system.paging.state\nvar (\n\t// used\n\t// Stability: development\n\tSystemPagingStateUsed = SystemPagingStateKey.String(\"used\")\n\t// free\n\t// Stability: development\n\tSystemPagingStateFree = SystemPagingStateKey.String(\"free\")\n)\n\n// Enum values for system.paging.type\nvar (\n\t// major\n\t// Stability: development\n\tSystemPagingTypeMajor = SystemPagingTypeKey.String(\"major\")\n\t// minor\n\t// Stability: development\n\tSystemPagingTypeMinor = SystemPagingTypeKey.String(\"minor\")\n)\n\n// Enum values for system.process.status\nvar (\n\t// running\n\t// Stability: development\n\tSystemProcessStatusRunning = SystemProcessStatusKey.String(\"running\")\n\t// sleeping\n\t// Stability: development\n\tSystemProcessStatusSleeping = SystemProcessStatusKey.String(\"sleeping\")\n\t// stopped\n\t// Stability: development\n\tSystemProcessStatusStopped = SystemProcessStatusKey.String(\"stopped\")\n\t// defunct\n\t// Stability: development\n\tSystemProcessStatusDefunct = SystemProcessStatusKey.String(\"defunct\")\n)\n\n// Namespace: telemetry\nconst (\n\t// TelemetryDistroNameKey is the attribute Key conforming to the\n\t// \"telemetry.distro.name\" semantic conventions. It represents the name of the\n\t// auto instrumentation agent or distribution, if used.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"parts-unlimited-java\"\n\t// Note: Official auto instrumentation agents and distributions SHOULD set the\n\t// `telemetry.distro.name` attribute to\n\t// a string starting with `opentelemetry-`, e.g.\n\t// `opentelemetry-java-instrumentation`.\n\tTelemetryDistroNameKey = attribute.Key(\"telemetry.distro.name\")\n\n\t// TelemetryDistroVersionKey is the attribute Key conforming to the\n\t// \"telemetry.distro.version\" semantic conventions. It represents the version\n\t// string of the auto instrumentation agent or distribution, if used.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1.2.3\"\n\tTelemetryDistroVersionKey = attribute.Key(\"telemetry.distro.version\")\n\n\t// TelemetrySDKLanguageKey is the attribute Key conforming to the\n\t// \"telemetry.sdk.language\" semantic conventions. It represents the language of\n\t// the telemetry SDK.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples:\n\tTelemetrySDKLanguageKey = attribute.Key(\"telemetry.sdk.language\")\n\n\t// TelemetrySDKNameKey is the attribute Key conforming to the\n\t// \"telemetry.sdk.name\" semantic conventions. It represents the name of the\n\t// telemetry SDK as defined above.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"opentelemetry\"\n\t// Note: The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to\n\t// `opentelemetry`.\n\t// If another SDK, like a fork or a vendor-provided implementation, is used,\n\t// this SDK MUST set the\n\t// `telemetry.sdk.name` attribute to the fully-qualified class or module name of\n\t// this SDK's main entry point\n\t// or another suitable identifier depending on the language.\n\t// The identifier `opentelemetry` is reserved and MUST NOT be used in this case.\n\t// All custom identifiers SHOULD be stable across different versions of an\n\t// implementation.\n\tTelemetrySDKNameKey = attribute.Key(\"telemetry.sdk.name\")\n\n\t// TelemetrySDKVersionKey is the attribute Key conforming to the\n\t// \"telemetry.sdk.version\" semantic conventions. It represents the version\n\t// string of the telemetry SDK.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"1.2.3\"\n\tTelemetrySDKVersionKey = attribute.Key(\"telemetry.sdk.version\")\n)\n\n// TelemetryDistroName returns an attribute KeyValue conforming to the\n// \"telemetry.distro.name\" semantic conventions. It represents the name of the\n// auto instrumentation agent or distribution, if used.\nfunc TelemetryDistroName(val string) attribute.KeyValue {\n\treturn TelemetryDistroNameKey.String(val)\n}\n\n// TelemetryDistroVersion returns an attribute KeyValue conforming to the\n// \"telemetry.distro.version\" semantic conventions. It represents the version\n// string of the auto instrumentation agent or distribution, if used.\nfunc TelemetryDistroVersion(val string) attribute.KeyValue {\n\treturn TelemetryDistroVersionKey.String(val)\n}\n\n// TelemetrySDKName returns an attribute KeyValue conforming to the\n// \"telemetry.sdk.name\" semantic conventions. It represents the name of the\n// telemetry SDK as defined above.\nfunc TelemetrySDKName(val string) attribute.KeyValue {\n\treturn TelemetrySDKNameKey.String(val)\n}\n\n// TelemetrySDKVersion returns an attribute KeyValue conforming to the\n// \"telemetry.sdk.version\" semantic conventions. It represents the version string\n// of the telemetry SDK.\nfunc TelemetrySDKVersion(val string) attribute.KeyValue {\n\treturn TelemetrySDKVersionKey.String(val)\n}\n\n// Enum values for telemetry.sdk.language\nvar (\n\t// cpp\n\t// Stability: stable\n\tTelemetrySDKLanguageCPP = TelemetrySDKLanguageKey.String(\"cpp\")\n\t// dotnet\n\t// Stability: stable\n\tTelemetrySDKLanguageDotnet = TelemetrySDKLanguageKey.String(\"dotnet\")\n\t// erlang\n\t// Stability: stable\n\tTelemetrySDKLanguageErlang = TelemetrySDKLanguageKey.String(\"erlang\")\n\t// go\n\t// Stability: stable\n\tTelemetrySDKLanguageGo = TelemetrySDKLanguageKey.String(\"go\")\n\t// java\n\t// Stability: stable\n\tTelemetrySDKLanguageJava = TelemetrySDKLanguageKey.String(\"java\")\n\t// nodejs\n\t// Stability: stable\n\tTelemetrySDKLanguageNodejs = TelemetrySDKLanguageKey.String(\"nodejs\")\n\t// php\n\t// Stability: stable\n\tTelemetrySDKLanguagePHP = TelemetrySDKLanguageKey.String(\"php\")\n\t// python\n\t// Stability: stable\n\tTelemetrySDKLanguagePython = TelemetrySDKLanguageKey.String(\"python\")\n\t// ruby\n\t// Stability: stable\n\tTelemetrySDKLanguageRuby = TelemetrySDKLanguageKey.String(\"ruby\")\n\t// rust\n\t// Stability: stable\n\tTelemetrySDKLanguageRust = TelemetrySDKLanguageKey.String(\"rust\")\n\t// swift\n\t// Stability: stable\n\tTelemetrySDKLanguageSwift = TelemetrySDKLanguageKey.String(\"swift\")\n\t// webjs\n\t// Stability: stable\n\tTelemetrySDKLanguageWebJS = TelemetrySDKLanguageKey.String(\"webjs\")\n)\n\n// Namespace: test\nconst (\n\t// TestCaseNameKey is the attribute Key conforming to the \"test.case.name\"\n\t// semantic conventions. It represents the fully qualified human readable name\n\t// of the [test case].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"org.example.TestCase1.test1\", \"example/tests/TestCase1.test1\",\n\t// \"ExampleTestCase1_test1\"\n\t//\n\t// [test case]: https://wikipedia.org/wiki/Test_case\n\tTestCaseNameKey = attribute.Key(\"test.case.name\")\n\n\t// TestCaseResultStatusKey is the attribute Key conforming to the\n\t// \"test.case.result.status\" semantic conventions. It represents the status of\n\t// the actual test case result from test execution.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"pass\", \"fail\"\n\tTestCaseResultStatusKey = attribute.Key(\"test.case.result.status\")\n\n\t// TestSuiteNameKey is the attribute Key conforming to the \"test.suite.name\"\n\t// semantic conventions. It represents the human readable name of a [test suite]\n\t// .\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"TestSuite1\"\n\t//\n\t// [test suite]: https://wikipedia.org/wiki/Test_suite\n\tTestSuiteNameKey = attribute.Key(\"test.suite.name\")\n\n\t// TestSuiteRunStatusKey is the attribute Key conforming to the\n\t// \"test.suite.run.status\" semantic conventions. It represents the status of the\n\t// test suite run.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"success\", \"failure\", \"skipped\", \"aborted\", \"timed_out\",\n\t// \"in_progress\"\n\tTestSuiteRunStatusKey = attribute.Key(\"test.suite.run.status\")\n)\n\n// TestCaseName returns an attribute KeyValue conforming to the \"test.case.name\"\n// semantic conventions. It represents the fully qualified human readable name of\n// the [test case].\n//\n// [test case]: https://wikipedia.org/wiki/Test_case\nfunc TestCaseName(val string) attribute.KeyValue {\n\treturn TestCaseNameKey.String(val)\n}\n\n// TestSuiteName returns an attribute KeyValue conforming to the\n// \"test.suite.name\" semantic conventions. It represents the human readable name\n// of a [test suite].\n//\n// [test suite]: https://wikipedia.org/wiki/Test_suite\nfunc TestSuiteName(val string) attribute.KeyValue {\n\treturn TestSuiteNameKey.String(val)\n}\n\n// Enum values for test.case.result.status\nvar (\n\t// pass\n\t// Stability: development\n\tTestCaseResultStatusPass = TestCaseResultStatusKey.String(\"pass\")\n\t// fail\n\t// Stability: development\n\tTestCaseResultStatusFail = TestCaseResultStatusKey.String(\"fail\")\n)\n\n// Enum values for test.suite.run.status\nvar (\n\t// success\n\t// Stability: development\n\tTestSuiteRunStatusSuccess = TestSuiteRunStatusKey.String(\"success\")\n\t// failure\n\t// Stability: development\n\tTestSuiteRunStatusFailure = TestSuiteRunStatusKey.String(\"failure\")\n\t// skipped\n\t// Stability: development\n\tTestSuiteRunStatusSkipped = TestSuiteRunStatusKey.String(\"skipped\")\n\t// aborted\n\t// Stability: development\n\tTestSuiteRunStatusAborted = TestSuiteRunStatusKey.String(\"aborted\")\n\t// timed_out\n\t// Stability: development\n\tTestSuiteRunStatusTimedOut = TestSuiteRunStatusKey.String(\"timed_out\")\n\t// in_progress\n\t// Stability: development\n\tTestSuiteRunStatusInProgress = TestSuiteRunStatusKey.String(\"in_progress\")\n)\n\n// Namespace: thread\nconst (\n\t// ThreadIDKey is the attribute Key conforming to the \"thread.id\" semantic\n\t// conventions. It represents the current \"managed\" thread ID (as opposed to OS\n\t// thread ID).\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tThreadIDKey = attribute.Key(\"thread.id\")\n\n\t// ThreadNameKey is the attribute Key conforming to the \"thread.name\" semantic\n\t// conventions. It represents the current thread name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: main\n\tThreadNameKey = attribute.Key(\"thread.name\")\n)\n\n// ThreadID returns an attribute KeyValue conforming to the \"thread.id\" semantic\n// conventions. It represents the current \"managed\" thread ID (as opposed to OS\n// thread ID).\nfunc ThreadID(val int) attribute.KeyValue {\n\treturn ThreadIDKey.Int(val)\n}\n\n// ThreadName returns an attribute KeyValue conforming to the \"thread.name\"\n// semantic conventions. It represents the current thread name.\nfunc ThreadName(val string) attribute.KeyValue {\n\treturn ThreadNameKey.String(val)\n}\n\n// Namespace: tls\nconst (\n\t// TLSCipherKey is the attribute Key conforming to the \"tls.cipher\" semantic\n\t// conventions. It represents the string indicating the [cipher] used during the\n\t// current connection.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"TLS_RSA_WITH_3DES_EDE_CBC_SHA\",\n\t// \"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256\"\n\t// Note: The values allowed for `tls.cipher` MUST be one of the `Descriptions`\n\t// of the [registered TLS Cipher Suits].\n\t//\n\t// [cipher]: https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5\n\t// [registered TLS Cipher Suits]: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#table-tls-parameters-4\n\tTLSCipherKey = attribute.Key(\"tls.cipher\")\n\n\t// TLSClientCertificateKey is the attribute Key conforming to the\n\t// \"tls.client.certificate\" semantic conventions. It represents the PEM-encoded\n\t// stand-alone certificate offered by the client. This is usually\n\t// mutually-exclusive of `client.certificate_chain` since this value also exists\n\t// in that list.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"MII...\"\n\tTLSClientCertificateKey = attribute.Key(\"tls.client.certificate\")\n\n\t// TLSClientCertificateChainKey is the attribute Key conforming to the\n\t// \"tls.client.certificate_chain\" semantic conventions. It represents the array\n\t// of PEM-encoded certificates that make up the certificate chain offered by the\n\t// client. This is usually mutually-exclusive of `client.certificate` since that\n\t// value should be the first certificate in the chain.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"MII...\", \"MI...\"\n\tTLSClientCertificateChainKey = attribute.Key(\"tls.client.certificate_chain\")\n\n\t// TLSClientHashMd5Key is the attribute Key conforming to the\n\t// \"tls.client.hash.md5\" semantic conventions. It represents the certificate\n\t// fingerprint using the MD5 digest of DER-encoded version of certificate\n\t// offered by the client. For consistency with other hash values, this value\n\t// should be formatted as an uppercase hash.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC\"\n\tTLSClientHashMd5Key = attribute.Key(\"tls.client.hash.md5\")\n\n\t// TLSClientHashSha1Key is the attribute Key conforming to the\n\t// \"tls.client.hash.sha1\" semantic conventions. It represents the certificate\n\t// fingerprint using the SHA1 digest of DER-encoded version of certificate\n\t// offered by the client. For consistency with other hash values, this value\n\t// should be formatted as an uppercase hash.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"9E393D93138888D288266C2D915214D1D1CCEB2A\"\n\tTLSClientHashSha1Key = attribute.Key(\"tls.client.hash.sha1\")\n\n\t// TLSClientHashSha256Key is the attribute Key conforming to the\n\t// \"tls.client.hash.sha256\" semantic conventions. It represents the certificate\n\t// fingerprint using the SHA256 digest of DER-encoded version of certificate\n\t// offered by the client. For consistency with other hash values, this value\n\t// should be formatted as an uppercase hash.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0\"\n\tTLSClientHashSha256Key = attribute.Key(\"tls.client.hash.sha256\")\n\n\t// TLSClientIssuerKey is the attribute Key conforming to the \"tls.client.issuer\"\n\t// semantic conventions. It represents the distinguished name of [subject] of\n\t// the issuer of the x.509 certificate presented by the client.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com\"\n\t//\n\t// [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6\n\tTLSClientIssuerKey = attribute.Key(\"tls.client.issuer\")\n\n\t// TLSClientJa3Key is the attribute Key conforming to the \"tls.client.ja3\"\n\t// semantic conventions. It represents a hash that identifies clients based on\n\t// how they perform an SSL/TLS handshake.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"d4e5b18d6b55c71272893221c96ba240\"\n\tTLSClientJa3Key = attribute.Key(\"tls.client.ja3\")\n\n\t// TLSClientNotAfterKey is the attribute Key conforming to the\n\t// \"tls.client.not_after\" semantic conventions. It represents the date/Time\n\t// indicating when client certificate is no longer considered valid.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2021-01-01T00:00:00.000Z\"\n\tTLSClientNotAfterKey = attribute.Key(\"tls.client.not_after\")\n\n\t// TLSClientNotBeforeKey is the attribute Key conforming to the\n\t// \"tls.client.not_before\" semantic conventions. It represents the date/Time\n\t// indicating when client certificate is first considered valid.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1970-01-01T00:00:00.000Z\"\n\tTLSClientNotBeforeKey = attribute.Key(\"tls.client.not_before\")\n\n\t// TLSClientSubjectKey is the attribute Key conforming to the\n\t// \"tls.client.subject\" semantic conventions. It represents the distinguished\n\t// name of subject of the x.509 certificate presented by the client.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"CN=myclient, OU=Documentation Team, DC=example, DC=com\"\n\tTLSClientSubjectKey = attribute.Key(\"tls.client.subject\")\n\n\t// TLSClientSupportedCiphersKey is the attribute Key conforming to the\n\t// \"tls.client.supported_ciphers\" semantic conventions. It represents the array\n\t// of ciphers offered by the client during the client hello.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\",\n\t// \"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\"\n\tTLSClientSupportedCiphersKey = attribute.Key(\"tls.client.supported_ciphers\")\n\n\t// TLSCurveKey is the attribute Key conforming to the \"tls.curve\" semantic\n\t// conventions. It represents the string indicating the curve used for the given\n\t// cipher, when applicable.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"secp256r1\"\n\tTLSCurveKey = attribute.Key(\"tls.curve\")\n\n\t// TLSEstablishedKey is the attribute Key conforming to the \"tls.established\"\n\t// semantic conventions. It represents the boolean flag indicating if the TLS\n\t// negotiation was successful and transitioned to an encrypted tunnel.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: true\n\tTLSEstablishedKey = attribute.Key(\"tls.established\")\n\n\t// TLSNextProtocolKey is the attribute Key conforming to the \"tls.next_protocol\"\n\t// semantic conventions. It represents the string indicating the protocol being\n\t// tunneled. Per the values in the [IANA registry], this string should be lower\n\t// case.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"http/1.1\"\n\t//\n\t// [IANA registry]: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids\n\tTLSNextProtocolKey = attribute.Key(\"tls.next_protocol\")\n\n\t// TLSProtocolNameKey is the attribute Key conforming to the \"tls.protocol.name\"\n\t// semantic conventions. It represents the normalized lowercase protocol name\n\t// parsed from original string of the negotiated [SSL/TLS protocol version].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t//\n\t// [SSL/TLS protocol version]: https://docs.openssl.org/1.1.1/man3/SSL_get_version/#return-values\n\tTLSProtocolNameKey = attribute.Key(\"tls.protocol.name\")\n\n\t// TLSProtocolVersionKey is the attribute Key conforming to the\n\t// \"tls.protocol.version\" semantic conventions. It represents the numeric part\n\t// of the version parsed from the original string of the negotiated\n\t// [SSL/TLS protocol version].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1.2\", \"3\"\n\t//\n\t// [SSL/TLS protocol version]: https://docs.openssl.org/1.1.1/man3/SSL_get_version/#return-values\n\tTLSProtocolVersionKey = attribute.Key(\"tls.protocol.version\")\n\n\t// TLSResumedKey is the attribute Key conforming to the \"tls.resumed\" semantic\n\t// conventions. It represents the boolean flag indicating if this TLS connection\n\t// was resumed from an existing TLS negotiation.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: true\n\tTLSResumedKey = attribute.Key(\"tls.resumed\")\n\n\t// TLSServerCertificateKey is the attribute Key conforming to the\n\t// \"tls.server.certificate\" semantic conventions. It represents the PEM-encoded\n\t// stand-alone certificate offered by the server. This is usually\n\t// mutually-exclusive of `server.certificate_chain` since this value also exists\n\t// in that list.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"MII...\"\n\tTLSServerCertificateKey = attribute.Key(\"tls.server.certificate\")\n\n\t// TLSServerCertificateChainKey is the attribute Key conforming to the\n\t// \"tls.server.certificate_chain\" semantic conventions. It represents the array\n\t// of PEM-encoded certificates that make up the certificate chain offered by the\n\t// server. This is usually mutually-exclusive of `server.certificate` since that\n\t// value should be the first certificate in the chain.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"MII...\", \"MI...\"\n\tTLSServerCertificateChainKey = attribute.Key(\"tls.server.certificate_chain\")\n\n\t// TLSServerHashMd5Key is the attribute Key conforming to the\n\t// \"tls.server.hash.md5\" semantic conventions. It represents the certificate\n\t// fingerprint using the MD5 digest of DER-encoded version of certificate\n\t// offered by the server. For consistency with other hash values, this value\n\t// should be formatted as an uppercase hash.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC\"\n\tTLSServerHashMd5Key = attribute.Key(\"tls.server.hash.md5\")\n\n\t// TLSServerHashSha1Key is the attribute Key conforming to the\n\t// \"tls.server.hash.sha1\" semantic conventions. It represents the certificate\n\t// fingerprint using the SHA1 digest of DER-encoded version of certificate\n\t// offered by the server. For consistency with other hash values, this value\n\t// should be formatted as an uppercase hash.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"9E393D93138888D288266C2D915214D1D1CCEB2A\"\n\tTLSServerHashSha1Key = attribute.Key(\"tls.server.hash.sha1\")\n\n\t// TLSServerHashSha256Key is the attribute Key conforming to the\n\t// \"tls.server.hash.sha256\" semantic conventions. It represents the certificate\n\t// fingerprint using the SHA256 digest of DER-encoded version of certificate\n\t// offered by the server. For consistency with other hash values, this value\n\t// should be formatted as an uppercase hash.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0\"\n\tTLSServerHashSha256Key = attribute.Key(\"tls.server.hash.sha256\")\n\n\t// TLSServerIssuerKey is the attribute Key conforming to the \"tls.server.issuer\"\n\t// semantic conventions. It represents the distinguished name of [subject] of\n\t// the issuer of the x.509 certificate presented by the client.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com\"\n\t//\n\t// [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6\n\tTLSServerIssuerKey = attribute.Key(\"tls.server.issuer\")\n\n\t// TLSServerJa3sKey is the attribute Key conforming to the \"tls.server.ja3s\"\n\t// semantic conventions. It represents a hash that identifies servers based on\n\t// how they perform an SSL/TLS handshake.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"d4e5b18d6b55c71272893221c96ba240\"\n\tTLSServerJa3sKey = attribute.Key(\"tls.server.ja3s\")\n\n\t// TLSServerNotAfterKey is the attribute Key conforming to the\n\t// \"tls.server.not_after\" semantic conventions. It represents the date/Time\n\t// indicating when server certificate is no longer considered valid.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2021-01-01T00:00:00.000Z\"\n\tTLSServerNotAfterKey = attribute.Key(\"tls.server.not_after\")\n\n\t// TLSServerNotBeforeKey is the attribute Key conforming to the\n\t// \"tls.server.not_before\" semantic conventions. It represents the date/Time\n\t// indicating when server certificate is first considered valid.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1970-01-01T00:00:00.000Z\"\n\tTLSServerNotBeforeKey = attribute.Key(\"tls.server.not_before\")\n\n\t// TLSServerSubjectKey is the attribute Key conforming to the\n\t// \"tls.server.subject\" semantic conventions. It represents the distinguished\n\t// name of subject of the x.509 certificate presented by the server.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"CN=myserver, OU=Documentation Team, DC=example, DC=com\"\n\tTLSServerSubjectKey = attribute.Key(\"tls.server.subject\")\n)\n\n// TLSCipher returns an attribute KeyValue conforming to the \"tls.cipher\"\n// semantic conventions. It represents the string indicating the [cipher] used\n// during the current connection.\n//\n// [cipher]: https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5\nfunc TLSCipher(val string) attribute.KeyValue {\n\treturn TLSCipherKey.String(val)\n}\n\n// TLSClientCertificate returns an attribute KeyValue conforming to the\n// \"tls.client.certificate\" semantic conventions. It represents the PEM-encoded\n// stand-alone certificate offered by the client. This is usually\n// mutually-exclusive of `client.certificate_chain` since this value also exists\n// in that list.\nfunc TLSClientCertificate(val string) attribute.KeyValue {\n\treturn TLSClientCertificateKey.String(val)\n}\n\n// TLSClientCertificateChain returns an attribute KeyValue conforming to the\n// \"tls.client.certificate_chain\" semantic conventions. It represents the array\n// of PEM-encoded certificates that make up the certificate chain offered by the\n// client. This is usually mutually-exclusive of `client.certificate` since that\n// value should be the first certificate in the chain.\nfunc TLSClientCertificateChain(val ...string) attribute.KeyValue {\n\treturn TLSClientCertificateChainKey.StringSlice(val)\n}\n\n// TLSClientHashMd5 returns an attribute KeyValue conforming to the\n// \"tls.client.hash.md5\" semantic conventions. It represents the certificate\n// fingerprint using the MD5 digest of DER-encoded version of certificate offered\n// by the client. For consistency with other hash values, this value should be\n// formatted as an uppercase hash.\nfunc TLSClientHashMd5(val string) attribute.KeyValue {\n\treturn TLSClientHashMd5Key.String(val)\n}\n\n// TLSClientHashSha1 returns an attribute KeyValue conforming to the\n// \"tls.client.hash.sha1\" semantic conventions. It represents the certificate\n// fingerprint using the SHA1 digest of DER-encoded version of certificate\n// offered by the client. For consistency with other hash values, this value\n// should be formatted as an uppercase hash.\nfunc TLSClientHashSha1(val string) attribute.KeyValue {\n\treturn TLSClientHashSha1Key.String(val)\n}\n\n// TLSClientHashSha256 returns an attribute KeyValue conforming to the\n// \"tls.client.hash.sha256\" semantic conventions. It represents the certificate\n// fingerprint using the SHA256 digest of DER-encoded version of certificate\n// offered by the client. For consistency with other hash values, this value\n// should be formatted as an uppercase hash.\nfunc TLSClientHashSha256(val string) attribute.KeyValue {\n\treturn TLSClientHashSha256Key.String(val)\n}\n\n// TLSClientIssuer returns an attribute KeyValue conforming to the\n// \"tls.client.issuer\" semantic conventions. It represents the distinguished name\n// of [subject] of the issuer of the x.509 certificate presented by the client.\n//\n// [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6\nfunc TLSClientIssuer(val string) attribute.KeyValue {\n\treturn TLSClientIssuerKey.String(val)\n}\n\n// TLSClientJa3 returns an attribute KeyValue conforming to the \"tls.client.ja3\"\n// semantic conventions. It represents a hash that identifies clients based on\n// how they perform an SSL/TLS handshake.\nfunc TLSClientJa3(val string) attribute.KeyValue {\n\treturn TLSClientJa3Key.String(val)\n}\n\n// TLSClientNotAfter returns an attribute KeyValue conforming to the\n// \"tls.client.not_after\" semantic conventions. It represents the date/Time\n// indicating when client certificate is no longer considered valid.\nfunc TLSClientNotAfter(val string) attribute.KeyValue {\n\treturn TLSClientNotAfterKey.String(val)\n}\n\n// TLSClientNotBefore returns an attribute KeyValue conforming to the\n// \"tls.client.not_before\" semantic conventions. It represents the date/Time\n// indicating when client certificate is first considered valid.\nfunc TLSClientNotBefore(val string) attribute.KeyValue {\n\treturn TLSClientNotBeforeKey.String(val)\n}\n\n// TLSClientSubject returns an attribute KeyValue conforming to the\n// \"tls.client.subject\" semantic conventions. It represents the distinguished\n// name of subject of the x.509 certificate presented by the client.\nfunc TLSClientSubject(val string) attribute.KeyValue {\n\treturn TLSClientSubjectKey.String(val)\n}\n\n// TLSClientSupportedCiphers returns an attribute KeyValue conforming to the\n// \"tls.client.supported_ciphers\" semantic conventions. It represents the array\n// of ciphers offered by the client during the client hello.\nfunc TLSClientSupportedCiphers(val ...string) attribute.KeyValue {\n\treturn TLSClientSupportedCiphersKey.StringSlice(val)\n}\n\n// TLSCurve returns an attribute KeyValue conforming to the \"tls.curve\" semantic\n// conventions. It represents the string indicating the curve used for the given\n// cipher, when applicable.\nfunc TLSCurve(val string) attribute.KeyValue {\n\treturn TLSCurveKey.String(val)\n}\n\n// TLSEstablished returns an attribute KeyValue conforming to the\n// \"tls.established\" semantic conventions. It represents the boolean flag\n// indicating if the TLS negotiation was successful and transitioned to an\n// encrypted tunnel.\nfunc TLSEstablished(val bool) attribute.KeyValue {\n\treturn TLSEstablishedKey.Bool(val)\n}\n\n// TLSNextProtocol returns an attribute KeyValue conforming to the\n// \"tls.next_protocol\" semantic conventions. It represents the string indicating\n// the protocol being tunneled. Per the values in the [IANA registry], this\n// string should be lower case.\n//\n// [IANA registry]: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids\nfunc TLSNextProtocol(val string) attribute.KeyValue {\n\treturn TLSNextProtocolKey.String(val)\n}\n\n// TLSProtocolVersion returns an attribute KeyValue conforming to the\n// \"tls.protocol.version\" semantic conventions. It represents the numeric part of\n// the version parsed from the original string of the negotiated\n// [SSL/TLS protocol version].\n//\n// [SSL/TLS protocol version]: https://docs.openssl.org/1.1.1/man3/SSL_get_version/#return-values\nfunc TLSProtocolVersion(val string) attribute.KeyValue {\n\treturn TLSProtocolVersionKey.String(val)\n}\n\n// TLSResumed returns an attribute KeyValue conforming to the \"tls.resumed\"\n// semantic conventions. It represents the boolean flag indicating if this TLS\n// connection was resumed from an existing TLS negotiation.\nfunc TLSResumed(val bool) attribute.KeyValue {\n\treturn TLSResumedKey.Bool(val)\n}\n\n// TLSServerCertificate returns an attribute KeyValue conforming to the\n// \"tls.server.certificate\" semantic conventions. It represents the PEM-encoded\n// stand-alone certificate offered by the server. This is usually\n// mutually-exclusive of `server.certificate_chain` since this value also exists\n// in that list.\nfunc TLSServerCertificate(val string) attribute.KeyValue {\n\treturn TLSServerCertificateKey.String(val)\n}\n\n// TLSServerCertificateChain returns an attribute KeyValue conforming to the\n// \"tls.server.certificate_chain\" semantic conventions. It represents the array\n// of PEM-encoded certificates that make up the certificate chain offered by the\n// server. This is usually mutually-exclusive of `server.certificate` since that\n// value should be the first certificate in the chain.\nfunc TLSServerCertificateChain(val ...string) attribute.KeyValue {\n\treturn TLSServerCertificateChainKey.StringSlice(val)\n}\n\n// TLSServerHashMd5 returns an attribute KeyValue conforming to the\n// \"tls.server.hash.md5\" semantic conventions. It represents the certificate\n// fingerprint using the MD5 digest of DER-encoded version of certificate offered\n// by the server. For consistency with other hash values, this value should be\n// formatted as an uppercase hash.\nfunc TLSServerHashMd5(val string) attribute.KeyValue {\n\treturn TLSServerHashMd5Key.String(val)\n}\n\n// TLSServerHashSha1 returns an attribute KeyValue conforming to the\n// \"tls.server.hash.sha1\" semantic conventions. It represents the certificate\n// fingerprint using the SHA1 digest of DER-encoded version of certificate\n// offered by the server. For consistency with other hash values, this value\n// should be formatted as an uppercase hash.\nfunc TLSServerHashSha1(val string) attribute.KeyValue {\n\treturn TLSServerHashSha1Key.String(val)\n}\n\n// TLSServerHashSha256 returns an attribute KeyValue conforming to the\n// \"tls.server.hash.sha256\" semantic conventions. It represents the certificate\n// fingerprint using the SHA256 digest of DER-encoded version of certificate\n// offered by the server. For consistency with other hash values, this value\n// should be formatted as an uppercase hash.\nfunc TLSServerHashSha256(val string) attribute.KeyValue {\n\treturn TLSServerHashSha256Key.String(val)\n}\n\n// TLSServerIssuer returns an attribute KeyValue conforming to the\n// \"tls.server.issuer\" semantic conventions. It represents the distinguished name\n// of [subject] of the issuer of the x.509 certificate presented by the client.\n//\n// [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6\nfunc TLSServerIssuer(val string) attribute.KeyValue {\n\treturn TLSServerIssuerKey.String(val)\n}\n\n// TLSServerJa3s returns an attribute KeyValue conforming to the\n// \"tls.server.ja3s\" semantic conventions. It represents a hash that identifies\n// servers based on how they perform an SSL/TLS handshake.\nfunc TLSServerJa3s(val string) attribute.KeyValue {\n\treturn TLSServerJa3sKey.String(val)\n}\n\n// TLSServerNotAfter returns an attribute KeyValue conforming to the\n// \"tls.server.not_after\" semantic conventions. It represents the date/Time\n// indicating when server certificate is no longer considered valid.\nfunc TLSServerNotAfter(val string) attribute.KeyValue {\n\treturn TLSServerNotAfterKey.String(val)\n}\n\n// TLSServerNotBefore returns an attribute KeyValue conforming to the\n// \"tls.server.not_before\" semantic conventions. It represents the date/Time\n// indicating when server certificate is first considered valid.\nfunc TLSServerNotBefore(val string) attribute.KeyValue {\n\treturn TLSServerNotBeforeKey.String(val)\n}\n\n// TLSServerSubject returns an attribute KeyValue conforming to the\n// \"tls.server.subject\" semantic conventions. It represents the distinguished\n// name of subject of the x.509 certificate presented by the server.\nfunc TLSServerSubject(val string) attribute.KeyValue {\n\treturn TLSServerSubjectKey.String(val)\n}\n\n// Enum values for tls.protocol.name\nvar (\n\t// ssl\n\t// Stability: development\n\tTLSProtocolNameSsl = TLSProtocolNameKey.String(\"ssl\")\n\t// tls\n\t// Stability: development\n\tTLSProtocolNameTLS = TLSProtocolNameKey.String(\"tls\")\n)\n\n// Namespace: url\nconst (\n\t// URLDomainKey is the attribute Key conforming to the \"url.domain\" semantic\n\t// conventions. It represents the domain extracted from the `url.full`, such as\n\t// \"opentelemetry.io\".\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"www.foo.bar\", \"opentelemetry.io\", \"3.12.167.2\",\n\t// \"[1080:0:0:0:8:800:200C:417A]\"\n\t// Note: In some cases a URL may refer to an IP and/or port directly, without a\n\t// domain name. In this case, the IP address would go to the domain field. If\n\t// the URL contains a [literal IPv6 address] enclosed by `[` and `]`, the `[`\n\t// and `]` characters should also be captured in the domain field.\n\t//\n\t// [literal IPv6 address]: https://www.rfc-editor.org/rfc/rfc2732#section-2\n\tURLDomainKey = attribute.Key(\"url.domain\")\n\n\t// URLExtensionKey is the attribute Key conforming to the \"url.extension\"\n\t// semantic conventions. It represents the file extension extracted from the\n\t// `url.full`, excluding the leading dot.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"png\", \"gz\"\n\t// Note: The file extension is only set if it exists, as not every url has a\n\t// file extension. When the file name has multiple extensions `example.tar.gz`,\n\t// only the last one should be captured `gz`, not `tar.gz`.\n\tURLExtensionKey = attribute.Key(\"url.extension\")\n\n\t// URLFragmentKey is the attribute Key conforming to the \"url.fragment\" semantic\n\t// conventions. It represents the [URI fragment] component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"SemConv\"\n\t//\n\t// [URI fragment]: https://www.rfc-editor.org/rfc/rfc3986#section-3.5\n\tURLFragmentKey = attribute.Key(\"url.fragment\")\n\n\t// URLFullKey is the attribute Key conforming to the \"url.full\" semantic\n\t// conventions. It represents the absolute URL describing a network resource\n\t// according to [RFC3986].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"https://www.foo.bar/search?q=OpenTelemetry#SemConv\", \"//localhost\"\n\t// Note: For network calls, URL usually has\n\t// `scheme://host[:port][path][?query][#fragment]` format, where the fragment\n\t// is not transmitted over HTTP, but if it is known, it SHOULD be included\n\t// nevertheless.\n\t//\n\t// `url.full` MUST NOT contain credentials passed via URL in form of\n\t// `https://username:password@www.example.com/`.\n\t// In such case username and password SHOULD be redacted and attribute's value\n\t// SHOULD be `https://REDACTED:REDACTED@www.example.com/`.\n\t//\n\t// `url.full` SHOULD capture the absolute URL when it is available (or can be\n\t// reconstructed).\n\t//\n\t// Sensitive content provided in `url.full` SHOULD be scrubbed when\n\t// instrumentations can identify it.\n\t//\n\t//\n\t// Query string values for the following keys SHOULD be redacted by default and\n\t// replaced by the\n\t// value `REDACTED`:\n\t//\n\t//   - [`AWSAccessKeyId`]\n\t//   - [`Signature`]\n\t//   - [`sig`]\n\t//   - [`X-Goog-Signature`]\n\t//\n\t// This list is subject to change over time.\n\t//\n\t// When a query string value is redacted, the query string key SHOULD still be\n\t// preserved, e.g.\n\t// `https://www.example.com/path?color=blue&sig=REDACTED`.\n\t//\n\t// [RFC3986]: https://www.rfc-editor.org/rfc/rfc3986\n\t// [`AWSAccessKeyId`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth\n\t// [`Signature`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth\n\t// [`sig`]: https://learn.microsoft.com/azure/storage/common/storage-sas-overview#sas-token\n\t// [`X-Goog-Signature`]: https://cloud.google.com/storage/docs/access-control/signed-urls\n\tURLFullKey = attribute.Key(\"url.full\")\n\n\t// URLOriginalKey is the attribute Key conforming to the \"url.original\" semantic\n\t// conventions. It represents the unmodified original URL as seen in the event\n\t// source.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"https://www.foo.bar/search?q=OpenTelemetry#SemConv\",\n\t// \"search?q=OpenTelemetry\"\n\t// Note: In network monitoring, the observed URL may be a full URL, whereas in\n\t// access logs, the URL is often just represented as a path. This field is meant\n\t// to represent the URL as it was observed, complete or not.\n\t// `url.original` might contain credentials passed via URL in form of\n\t// `https://username:password@www.example.com/`. In such case password and\n\t// username SHOULD NOT be redacted and attribute's value SHOULD remain the same.\n\tURLOriginalKey = attribute.Key(\"url.original\")\n\n\t// URLPathKey is the attribute Key conforming to the \"url.path\" semantic\n\t// conventions. It represents the [URI path] component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"/search\"\n\t// Note: Sensitive content provided in `url.path` SHOULD be scrubbed when\n\t// instrumentations can identify it.\n\t//\n\t// [URI path]: https://www.rfc-editor.org/rfc/rfc3986#section-3.3\n\tURLPathKey = attribute.Key(\"url.path\")\n\n\t// URLPortKey is the attribute Key conforming to the \"url.port\" semantic\n\t// conventions. It represents the port extracted from the `url.full`.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 443\n\tURLPortKey = attribute.Key(\"url.port\")\n\n\t// URLQueryKey is the attribute Key conforming to the \"url.query\" semantic\n\t// conventions. It represents the [URI query] component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"q=OpenTelemetry\"\n\t// Note: Sensitive content provided in `url.query` SHOULD be scrubbed when\n\t// instrumentations can identify it.\n\t//\n\t//\n\t// Query string values for the following keys SHOULD be redacted by default and\n\t// replaced by the value `REDACTED`:\n\t//\n\t//   - [`AWSAccessKeyId`]\n\t//   - [`Signature`]\n\t//   - [`sig`]\n\t//   - [`X-Goog-Signature`]\n\t//\n\t// This list is subject to change over time.\n\t//\n\t// When a query string value is redacted, the query string key SHOULD still be\n\t// preserved, e.g.\n\t// `q=OpenTelemetry&sig=REDACTED`.\n\t//\n\t// [URI query]: https://www.rfc-editor.org/rfc/rfc3986#section-3.4\n\t// [`AWSAccessKeyId`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth\n\t// [`Signature`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth\n\t// [`sig`]: https://learn.microsoft.com/azure/storage/common/storage-sas-overview#sas-token\n\t// [`X-Goog-Signature`]: https://cloud.google.com/storage/docs/access-control/signed-urls\n\tURLQueryKey = attribute.Key(\"url.query\")\n\n\t// URLRegisteredDomainKey is the attribute Key conforming to the\n\t// \"url.registered_domain\" semantic conventions. It represents the highest\n\t// registered url domain, stripped of the subdomain.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"example.com\", \"foo.co.uk\"\n\t// Note: This value can be determined precisely with the [public suffix list].\n\t// For example, the registered domain for `foo.example.com` is `example.com`.\n\t// Trying to approximate this by simply taking the last two labels will not work\n\t// well for TLDs such as `co.uk`.\n\t//\n\t// [public suffix list]: https://publicsuffix.org/\n\tURLRegisteredDomainKey = attribute.Key(\"url.registered_domain\")\n\n\t// URLSchemeKey is the attribute Key conforming to the \"url.scheme\" semantic\n\t// conventions. It represents the [URI scheme] component identifying the used\n\t// protocol.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"https\", \"ftp\", \"telnet\"\n\t//\n\t// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1\n\tURLSchemeKey = attribute.Key(\"url.scheme\")\n\n\t// URLSubdomainKey is the attribute Key conforming to the \"url.subdomain\"\n\t// semantic conventions. It represents the subdomain portion of a fully\n\t// qualified domain name includes all of the names except the host name under\n\t// the registered_domain. In a partially qualified domain, or if the\n\t// qualification level of the full name cannot be determined, subdomain contains\n\t// all of the names below the registered domain.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"east\", \"sub2.sub1\"\n\t// Note: The subdomain portion of `www.east.mydomain.co.uk` is `east`. If the\n\t// domain has multiple levels of subdomain, such as `sub2.sub1.example.com`, the\n\t// subdomain field should contain `sub2.sub1`, with no trailing period.\n\tURLSubdomainKey = attribute.Key(\"url.subdomain\")\n\n\t// URLTemplateKey is the attribute Key conforming to the \"url.template\" semantic\n\t// conventions. It represents the low-cardinality template of an\n\t// [absolute path reference].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/users/{id}\", \"/users/:id\", \"/users?id={id}\"\n\t//\n\t// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2\n\tURLTemplateKey = attribute.Key(\"url.template\")\n\n\t// URLTopLevelDomainKey is the attribute Key conforming to the\n\t// \"url.top_level_domain\" semantic conventions. It represents the effective top\n\t// level domain (eTLD), also known as the domain suffix, is the last part of the\n\t// domain name. For example, the top level domain for example.com is `com`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"com\", \"co.uk\"\n\t// Note: This value can be determined precisely with the [public suffix list].\n\t//\n\t// [public suffix list]: https://publicsuffix.org/\n\tURLTopLevelDomainKey = attribute.Key(\"url.top_level_domain\")\n)\n\n// URLDomain returns an attribute KeyValue conforming to the \"url.domain\"\n// semantic conventions. It represents the domain extracted from the `url.full`,\n// such as \"opentelemetry.io\".\nfunc URLDomain(val string) attribute.KeyValue {\n\treturn URLDomainKey.String(val)\n}\n\n// URLExtension returns an attribute KeyValue conforming to the \"url.extension\"\n// semantic conventions. It represents the file extension extracted from the\n// `url.full`, excluding the leading dot.\nfunc URLExtension(val string) attribute.KeyValue {\n\treturn URLExtensionKey.String(val)\n}\n\n// URLFragment returns an attribute KeyValue conforming to the \"url.fragment\"\n// semantic conventions. It represents the [URI fragment] component.\n//\n// [URI fragment]: https://www.rfc-editor.org/rfc/rfc3986#section-3.5\nfunc URLFragment(val string) attribute.KeyValue {\n\treturn URLFragmentKey.String(val)\n}\n\n// URLFull returns an attribute KeyValue conforming to the \"url.full\" semantic\n// conventions. It represents the absolute URL describing a network resource\n// according to [RFC3986].\n//\n// [RFC3986]: https://www.rfc-editor.org/rfc/rfc3986\nfunc URLFull(val string) attribute.KeyValue {\n\treturn URLFullKey.String(val)\n}\n\n// URLOriginal returns an attribute KeyValue conforming to the \"url.original\"\n// semantic conventions. It represents the unmodified original URL as seen in the\n// event source.\nfunc URLOriginal(val string) attribute.KeyValue {\n\treturn URLOriginalKey.String(val)\n}\n\n// URLPath returns an attribute KeyValue conforming to the \"url.path\" semantic\n// conventions. It represents the [URI path] component.\n//\n// [URI path]: https://www.rfc-editor.org/rfc/rfc3986#section-3.3\nfunc URLPath(val string) attribute.KeyValue {\n\treturn URLPathKey.String(val)\n}\n\n// URLPort returns an attribute KeyValue conforming to the \"url.port\" semantic\n// conventions. It represents the port extracted from the `url.full`.\nfunc URLPort(val int) attribute.KeyValue {\n\treturn URLPortKey.Int(val)\n}\n\n// URLQuery returns an attribute KeyValue conforming to the \"url.query\" semantic\n// conventions. It represents the [URI query] component.\n//\n// [URI query]: https://www.rfc-editor.org/rfc/rfc3986#section-3.4\nfunc URLQuery(val string) attribute.KeyValue {\n\treturn URLQueryKey.String(val)\n}\n\n// URLRegisteredDomain returns an attribute KeyValue conforming to the\n// \"url.registered_domain\" semantic conventions. It represents the highest\n// registered url domain, stripped of the subdomain.\nfunc URLRegisteredDomain(val string) attribute.KeyValue {\n\treturn URLRegisteredDomainKey.String(val)\n}\n\n// URLScheme returns an attribute KeyValue conforming to the \"url.scheme\"\n// semantic conventions. It represents the [URI scheme] component identifying the\n// used protocol.\n//\n// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1\nfunc URLScheme(val string) attribute.KeyValue {\n\treturn URLSchemeKey.String(val)\n}\n\n// URLSubdomain returns an attribute KeyValue conforming to the \"url.subdomain\"\n// semantic conventions. It represents the subdomain portion of a fully qualified\n// domain name includes all of the names except the host name under the\n// registered_domain. In a partially qualified domain, or if the qualification\n// level of the full name cannot be determined, subdomain contains all of the\n// names below the registered domain.\nfunc URLSubdomain(val string) attribute.KeyValue {\n\treturn URLSubdomainKey.String(val)\n}\n\n// URLTemplate returns an attribute KeyValue conforming to the \"url.template\"\n// semantic conventions. It represents the low-cardinality template of an\n// [absolute path reference].\n//\n// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2\nfunc URLTemplate(val string) attribute.KeyValue {\n\treturn URLTemplateKey.String(val)\n}\n\n// URLTopLevelDomain returns an attribute KeyValue conforming to the\n// \"url.top_level_domain\" semantic conventions. It represents the effective top\n// level domain (eTLD), also known as the domain suffix, is the last part of the\n// domain name. For example, the top level domain for example.com is `com`.\nfunc URLTopLevelDomain(val string) attribute.KeyValue {\n\treturn URLTopLevelDomainKey.String(val)\n}\n\n// Namespace: user\nconst (\n\t// UserEmailKey is the attribute Key conforming to the \"user.email\" semantic\n\t// conventions. It represents the user email address.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"a.einstein@example.com\"\n\tUserEmailKey = attribute.Key(\"user.email\")\n\n\t// UserFullNameKey is the attribute Key conforming to the \"user.full_name\"\n\t// semantic conventions. It represents the user's full name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Albert Einstein\"\n\tUserFullNameKey = attribute.Key(\"user.full_name\")\n\n\t// UserHashKey is the attribute Key conforming to the \"user.hash\" semantic\n\t// conventions. It represents the unique user hash to correlate information for\n\t// a user in anonymized form.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"364fc68eaf4c8acec74a4e52d7d1feaa\"\n\t// Note: Useful if `user.id` or `user.name` contain confidential information and\n\t// cannot be used.\n\tUserHashKey = attribute.Key(\"user.hash\")\n\n\t// UserIDKey is the attribute Key conforming to the \"user.id\" semantic\n\t// conventions. It represents the unique identifier of the user.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"S-1-5-21-202424912787-2692429404-2351956786-1000\"\n\tUserIDKey = attribute.Key(\"user.id\")\n\n\t// UserNameKey is the attribute Key conforming to the \"user.name\" semantic\n\t// conventions. It represents the short name or login/username of the user.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"a.einstein\"\n\tUserNameKey = attribute.Key(\"user.name\")\n\n\t// UserRolesKey is the attribute Key conforming to the \"user.roles\" semantic\n\t// conventions. It represents the array of user roles at the time of the event.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"admin\", \"reporting_user\"\n\tUserRolesKey = attribute.Key(\"user.roles\")\n)\n\n// UserEmail returns an attribute KeyValue conforming to the \"user.email\"\n// semantic conventions. It represents the user email address.\nfunc UserEmail(val string) attribute.KeyValue {\n\treturn UserEmailKey.String(val)\n}\n\n// UserFullName returns an attribute KeyValue conforming to the \"user.full_name\"\n// semantic conventions. It represents the user's full name.\nfunc UserFullName(val string) attribute.KeyValue {\n\treturn UserFullNameKey.String(val)\n}\n\n// UserHash returns an attribute KeyValue conforming to the \"user.hash\" semantic\n// conventions. It represents the unique user hash to correlate information for a\n// user in anonymized form.\nfunc UserHash(val string) attribute.KeyValue {\n\treturn UserHashKey.String(val)\n}\n\n// UserID returns an attribute KeyValue conforming to the \"user.id\" semantic\n// conventions. It represents the unique identifier of the user.\nfunc UserID(val string) attribute.KeyValue {\n\treturn UserIDKey.String(val)\n}\n\n// UserName returns an attribute KeyValue conforming to the \"user.name\" semantic\n// conventions. It represents the short name or login/username of the user.\nfunc UserName(val string) attribute.KeyValue {\n\treturn UserNameKey.String(val)\n}\n\n// UserRoles returns an attribute KeyValue conforming to the \"user.roles\"\n// semantic conventions. It represents the array of user roles at the time of the\n// event.\nfunc UserRoles(val ...string) attribute.KeyValue {\n\treturn UserRolesKey.StringSlice(val)\n}\n\n// Namespace: user_agent\nconst (\n\t// UserAgentNameKey is the attribute Key conforming to the \"user_agent.name\"\n\t// semantic conventions. It represents the name of the user-agent extracted from\n\t// original. Usually refers to the browser's name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Safari\", \"YourApp\"\n\t// Note: [Example] of extracting browser's name from original string. In the\n\t// case of using a user-agent for non-browser products, such as microservices\n\t// with multiple names/versions inside the `user_agent.original`, the most\n\t// significant name SHOULD be selected. In such a scenario it should align with\n\t// `user_agent.version`\n\t//\n\t// [Example]: https://www.whatsmyua.info\n\tUserAgentNameKey = attribute.Key(\"user_agent.name\")\n\n\t// UserAgentOriginalKey is the attribute Key conforming to the\n\t// \"user_agent.original\" semantic conventions. It represents the value of the\n\t// [HTTP User-Agent] header sent by the client.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"CERN-LineMode/2.15 libwww/2.17b3\", \"Mozilla/5.0 (iPhone; CPU\n\t// iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko)\n\t// Version/14.1.2 Mobile/15E148 Safari/604.1\", \"YourApp/1.0.0\n\t// grpc-java-okhttp/1.27.2\"\n\t//\n\t// [HTTP User-Agent]: https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent\n\tUserAgentOriginalKey = attribute.Key(\"user_agent.original\")\n\n\t// UserAgentOSNameKey is the attribute Key conforming to the\n\t// \"user_agent.os.name\" semantic conventions. It represents the human readable\n\t// operating system name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"iOS\", \"Android\", \"Ubuntu\"\n\t// Note: For mapping user agent strings to OS names, libraries such as\n\t// [ua-parser] can be utilized.\n\t//\n\t// [ua-parser]: https://github.com/ua-parser\n\tUserAgentOSNameKey = attribute.Key(\"user_agent.os.name\")\n\n\t// UserAgentOSVersionKey is the attribute Key conforming to the\n\t// \"user_agent.os.version\" semantic conventions. It represents the version\n\t// string of the operating system as defined in [Version Attributes].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"14.2.1\", \"18.04.1\"\n\t// Note: For mapping user agent strings to OS versions, libraries such as\n\t// [ua-parser] can be utilized.\n\t//\n\t// [Version Attributes]: /docs/resource/README.md#version-attributes\n\t// [ua-parser]: https://github.com/ua-parser\n\tUserAgentOSVersionKey = attribute.Key(\"user_agent.os.version\")\n\n\t// UserAgentSyntheticTypeKey is the attribute Key conforming to the\n\t// \"user_agent.synthetic.type\" semantic conventions. It represents the specifies\n\t// the category of synthetic traffic, such as tests or bots.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: This attribute MAY be derived from the contents of the\n\t// `user_agent.original` attribute. Components that populate the attribute are\n\t// responsible for determining what they consider to be synthetic bot or test\n\t// traffic. This attribute can either be set for self-identification purposes,\n\t// or on telemetry detected to be generated as a result of a synthetic request.\n\t// This attribute is useful for distinguishing between genuine client traffic\n\t// and synthetic traffic generated by bots or tests.\n\tUserAgentSyntheticTypeKey = attribute.Key(\"user_agent.synthetic.type\")\n\n\t// UserAgentVersionKey is the attribute Key conforming to the\n\t// \"user_agent.version\" semantic conventions. It represents the version of the\n\t// user-agent extracted from original. Usually refers to the browser's version.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"14.1.2\", \"1.0.0\"\n\t// Note: [Example] of extracting browser's version from original string. In the\n\t// case of using a user-agent for non-browser products, such as microservices\n\t// with multiple names/versions inside the `user_agent.original`, the most\n\t// significant version SHOULD be selected. In such a scenario it should align\n\t// with `user_agent.name`\n\t//\n\t// [Example]: https://www.whatsmyua.info\n\tUserAgentVersionKey = attribute.Key(\"user_agent.version\")\n)\n\n// UserAgentName returns an attribute KeyValue conforming to the\n// \"user_agent.name\" semantic conventions. It represents the name of the\n// user-agent extracted from original. Usually refers to the browser's name.\nfunc UserAgentName(val string) attribute.KeyValue {\n\treturn UserAgentNameKey.String(val)\n}\n\n// UserAgentOriginal returns an attribute KeyValue conforming to the\n// \"user_agent.original\" semantic conventions. It represents the value of the\n// [HTTP User-Agent] header sent by the client.\n//\n// [HTTP User-Agent]: https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent\nfunc UserAgentOriginal(val string) attribute.KeyValue {\n\treturn UserAgentOriginalKey.String(val)\n}\n\n// UserAgentOSName returns an attribute KeyValue conforming to the\n// \"user_agent.os.name\" semantic conventions. It represents the human readable\n// operating system name.\nfunc UserAgentOSName(val string) attribute.KeyValue {\n\treturn UserAgentOSNameKey.String(val)\n}\n\n// UserAgentOSVersion returns an attribute KeyValue conforming to the\n// \"user_agent.os.version\" semantic conventions. It represents the version string\n// of the operating system as defined in [Version Attributes].\n//\n// [Version Attributes]: /docs/resource/README.md#version-attributes\nfunc UserAgentOSVersion(val string) attribute.KeyValue {\n\treturn UserAgentOSVersionKey.String(val)\n}\n\n// UserAgentVersion returns an attribute KeyValue conforming to the\n// \"user_agent.version\" semantic conventions. It represents the version of the\n// user-agent extracted from original. Usually refers to the browser's version.\nfunc UserAgentVersion(val string) attribute.KeyValue {\n\treturn UserAgentVersionKey.String(val)\n}\n\n// Enum values for user_agent.synthetic.type\nvar (\n\t// Bot source.\n\t// Stability: development\n\tUserAgentSyntheticTypeBot = UserAgentSyntheticTypeKey.String(\"bot\")\n\t// Synthetic test source.\n\t// Stability: development\n\tUserAgentSyntheticTypeTest = UserAgentSyntheticTypeKey.String(\"test\")\n)\n\n// Namespace: vcs\nconst (\n\t// VCSChangeIDKey is the attribute Key conforming to the \"vcs.change.id\"\n\t// semantic conventions. It represents the ID of the change (pull request/merge\n\t// request/changelist) if applicable. This is usually a unique (within\n\t// repository) identifier generated by the VCS system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"123\"\n\tVCSChangeIDKey = attribute.Key(\"vcs.change.id\")\n\n\t// VCSChangeStateKey is the attribute Key conforming to the \"vcs.change.state\"\n\t// semantic conventions. It represents the state of the change (pull\n\t// request/merge request/changelist).\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"open\", \"closed\", \"merged\"\n\tVCSChangeStateKey = attribute.Key(\"vcs.change.state\")\n\n\t// VCSChangeTitleKey is the attribute Key conforming to the \"vcs.change.title\"\n\t// semantic conventions. It represents the human readable title of the change\n\t// (pull request/merge request/changelist). This title is often a brief summary\n\t// of the change and may get merged in to a ref as the commit summary.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Fixes broken thing\", \"feat: add my new feature\", \"[chore] update\n\t// dependency\"\n\tVCSChangeTitleKey = attribute.Key(\"vcs.change.title\")\n\n\t// VCSLineChangeTypeKey is the attribute Key conforming to the\n\t// \"vcs.line_change.type\" semantic conventions. It represents the type of line\n\t// change being measured on a branch or change.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"added\", \"removed\"\n\tVCSLineChangeTypeKey = attribute.Key(\"vcs.line_change.type\")\n\n\t// VCSOwnerNameKey is the attribute Key conforming to the \"vcs.owner.name\"\n\t// semantic conventions. It represents the group owner within the version\n\t// control system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-org\", \"myteam\", \"business-unit\"\n\tVCSOwnerNameKey = attribute.Key(\"vcs.owner.name\")\n\n\t// VCSProviderNameKey is the attribute Key conforming to the \"vcs.provider.name\"\n\t// semantic conventions. It represents the name of the version control system\n\t// provider.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"github\", \"gitlab\", \"gitea\", \"bitbucket\"\n\tVCSProviderNameKey = attribute.Key(\"vcs.provider.name\")\n\n\t// VCSRefBaseNameKey is the attribute Key conforming to the \"vcs.ref.base.name\"\n\t// semantic conventions. It represents the name of the [reference] such as\n\t// **branch** or **tag** in the repository.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-feature-branch\", \"tag-1-test\"\n\t// Note: `base` refers to the starting point of a change. For example, `main`\n\t// would be the base reference of type branch if you've created a new\n\t// reference of type branch from it and created new commits.\n\t//\n\t// [reference]: https://git-scm.com/docs/gitglossary#def_ref\n\tVCSRefBaseNameKey = attribute.Key(\"vcs.ref.base.name\")\n\n\t// VCSRefBaseRevisionKey is the attribute Key conforming to the\n\t// \"vcs.ref.base.revision\" semantic conventions. It represents the revision,\n\t// literally [revised version], The revision most often refers to a commit\n\t// object in Git, or a revision number in SVN.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"9d59409acf479dfa0df1aa568182e43e43df8bbe28d60fcf2bc52e30068802cc\",\n\t// \"main\", \"123\", \"HEAD\"\n\t// Note: `base` refers to the starting point of a change. For example, `main`\n\t// would be the base reference of type branch if you've created a new\n\t// reference of type branch from it and created new commits. The\n\t// revision can be a full [hash value (see\n\t// glossary)],\n\t// of the recorded change to a ref within a repository pointing to a\n\t// commit [commit] object. It does\n\t// not necessarily have to be a hash; it can simply define a [revision\n\t// number]\n\t// which is an integer that is monotonically increasing. In cases where\n\t// it is identical to the `ref.base.name`, it SHOULD still be included.\n\t// It is up to the implementer to decide which value to set as the\n\t// revision based on the VCS system and situational context.\n\t//\n\t// [revised version]: https://www.merriam-webster.com/dictionary/revision\n\t// [hash value (see\n\t// glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf\n\t// [commit]: https://git-scm.com/docs/git-commit\n\t// [revision\n\t// number]: https://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html\n\tVCSRefBaseRevisionKey = attribute.Key(\"vcs.ref.base.revision\")\n\n\t// VCSRefBaseTypeKey is the attribute Key conforming to the \"vcs.ref.base.type\"\n\t// semantic conventions. It represents the type of the [reference] in the\n\t// repository.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"branch\", \"tag\"\n\t// Note: `base` refers to the starting point of a change. For example, `main`\n\t// would be the base reference of type branch if you've created a new\n\t// reference of type branch from it and created new commits.\n\t//\n\t// [reference]: https://git-scm.com/docs/gitglossary#def_ref\n\tVCSRefBaseTypeKey = attribute.Key(\"vcs.ref.base.type\")\n\n\t// VCSRefHeadNameKey is the attribute Key conforming to the \"vcs.ref.head.name\"\n\t// semantic conventions. It represents the name of the [reference] such as\n\t// **branch** or **tag** in the repository.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-feature-branch\", \"tag-1-test\"\n\t// Note: `head` refers to where you are right now; the current reference at a\n\t// given time.\n\t//\n\t// [reference]: https://git-scm.com/docs/gitglossary#def_ref\n\tVCSRefHeadNameKey = attribute.Key(\"vcs.ref.head.name\")\n\n\t// VCSRefHeadRevisionKey is the attribute Key conforming to the\n\t// \"vcs.ref.head.revision\" semantic conventions. It represents the revision,\n\t// literally [revised version], The revision most often refers to a commit\n\t// object in Git, or a revision number in SVN.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"9d59409acf479dfa0df1aa568182e43e43df8bbe28d60fcf2bc52e30068802cc\",\n\t// \"main\", \"123\", \"HEAD\"\n\t// Note: `head` refers to where you are right now; the current reference at a\n\t// given time.The revision can be a full [hash value (see\n\t// glossary)],\n\t// of the recorded change to a ref within a repository pointing to a\n\t// commit [commit] object. It does\n\t// not necessarily have to be a hash; it can simply define a [revision\n\t// number]\n\t// which is an integer that is monotonically increasing. In cases where\n\t// it is identical to the `ref.head.name`, it SHOULD still be included.\n\t// It is up to the implementer to decide which value to set as the\n\t// revision based on the VCS system and situational context.\n\t//\n\t// [revised version]: https://www.merriam-webster.com/dictionary/revision\n\t// [hash value (see\n\t// glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf\n\t// [commit]: https://git-scm.com/docs/git-commit\n\t// [revision\n\t// number]: https://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html\n\tVCSRefHeadRevisionKey = attribute.Key(\"vcs.ref.head.revision\")\n\n\t// VCSRefHeadTypeKey is the attribute Key conforming to the \"vcs.ref.head.type\"\n\t// semantic conventions. It represents the type of the [reference] in the\n\t// repository.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"branch\", \"tag\"\n\t// Note: `head` refers to where you are right now; the current reference at a\n\t// given time.\n\t//\n\t// [reference]: https://git-scm.com/docs/gitglossary#def_ref\n\tVCSRefHeadTypeKey = attribute.Key(\"vcs.ref.head.type\")\n\n\t// VCSRefTypeKey is the attribute Key conforming to the \"vcs.ref.type\" semantic\n\t// conventions. It represents the type of the [reference] in the repository.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"branch\", \"tag\"\n\t//\n\t// [reference]: https://git-scm.com/docs/gitglossary#def_ref\n\tVCSRefTypeKey = attribute.Key(\"vcs.ref.type\")\n\n\t// VCSRepositoryNameKey is the attribute Key conforming to the\n\t// \"vcs.repository.name\" semantic conventions. It represents the human readable\n\t// name of the repository. It SHOULD NOT include any additional identifier like\n\t// Group/SubGroup in GitLab or organization in GitHub.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"semantic-conventions\", \"my-cool-repo\"\n\t// Note: Due to it only being the name, it can clash with forks of the same\n\t// repository if collecting telemetry across multiple orgs or groups in\n\t// the same backends.\n\tVCSRepositoryNameKey = attribute.Key(\"vcs.repository.name\")\n\n\t// VCSRepositoryURLFullKey is the attribute Key conforming to the\n\t// \"vcs.repository.url.full\" semantic conventions. It represents the\n\t// [canonical URL] of the repository providing the complete HTTP(S) address in\n\t// order to locate and identify the repository through a browser.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"https://github.com/opentelemetry/open-telemetry-collector-contrib\",\n\t// \"https://gitlab.com/my-org/my-project/my-projects-project/repo\"\n\t// Note: In Git Version Control Systems, the canonical URL SHOULD NOT include\n\t// the `.git` extension.\n\t//\n\t// [canonical URL]: https://support.google.com/webmasters/answer/10347851?hl=en#:~:text=A%20canonical%20URL%20is%20the,Google%20chooses%20one%20as%20canonical.\n\tVCSRepositoryURLFullKey = attribute.Key(\"vcs.repository.url.full\")\n\n\t// VCSRevisionDeltaDirectionKey is the attribute Key conforming to the\n\t// \"vcs.revision_delta.direction\" semantic conventions. It represents the type\n\t// of revision comparison.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"ahead\", \"behind\"\n\tVCSRevisionDeltaDirectionKey = attribute.Key(\"vcs.revision_delta.direction\")\n)\n\n// VCSChangeID returns an attribute KeyValue conforming to the \"vcs.change.id\"\n// semantic conventions. It represents the ID of the change (pull request/merge\n// request/changelist) if applicable. This is usually a unique (within\n// repository) identifier generated by the VCS system.\nfunc VCSChangeID(val string) attribute.KeyValue {\n\treturn VCSChangeIDKey.String(val)\n}\n\n// VCSChangeTitle returns an attribute KeyValue conforming to the\n// \"vcs.change.title\" semantic conventions. It represents the human readable\n// title of the change (pull request/merge request/changelist). This title is\n// often a brief summary of the change and may get merged in to a ref as the\n// commit summary.\nfunc VCSChangeTitle(val string) attribute.KeyValue {\n\treturn VCSChangeTitleKey.String(val)\n}\n\n// VCSOwnerName returns an attribute KeyValue conforming to the \"vcs.owner.name\"\n// semantic conventions. It represents the group owner within the version control\n// system.\nfunc VCSOwnerName(val string) attribute.KeyValue {\n\treturn VCSOwnerNameKey.String(val)\n}\n\n// VCSRefBaseName returns an attribute KeyValue conforming to the\n// \"vcs.ref.base.name\" semantic conventions. It represents the name of the\n// [reference] such as **branch** or **tag** in the repository.\n//\n// [reference]: https://git-scm.com/docs/gitglossary#def_ref\nfunc VCSRefBaseName(val string) attribute.KeyValue {\n\treturn VCSRefBaseNameKey.String(val)\n}\n\n// VCSRefBaseRevision returns an attribute KeyValue conforming to the\n// \"vcs.ref.base.revision\" semantic conventions. It represents the revision,\n// literally [revised version], The revision most often refers to a commit object\n// in Git, or a revision number in SVN.\n//\n// [revised version]: https://www.merriam-webster.com/dictionary/revision\nfunc VCSRefBaseRevision(val string) attribute.KeyValue {\n\treturn VCSRefBaseRevisionKey.String(val)\n}\n\n// VCSRefHeadName returns an attribute KeyValue conforming to the\n// \"vcs.ref.head.name\" semantic conventions. It represents the name of the\n// [reference] such as **branch** or **tag** in the repository.\n//\n// [reference]: https://git-scm.com/docs/gitglossary#def_ref\nfunc VCSRefHeadName(val string) attribute.KeyValue {\n\treturn VCSRefHeadNameKey.String(val)\n}\n\n// VCSRefHeadRevision returns an attribute KeyValue conforming to the\n// \"vcs.ref.head.revision\" semantic conventions. It represents the revision,\n// literally [revised version], The revision most often refers to a commit object\n// in Git, or a revision number in SVN.\n//\n// [revised version]: https://www.merriam-webster.com/dictionary/revision\nfunc VCSRefHeadRevision(val string) attribute.KeyValue {\n\treturn VCSRefHeadRevisionKey.String(val)\n}\n\n// VCSRepositoryName returns an attribute KeyValue conforming to the\n// \"vcs.repository.name\" semantic conventions. It represents the human readable\n// name of the repository. It SHOULD NOT include any additional identifier like\n// Group/SubGroup in GitLab or organization in GitHub.\nfunc VCSRepositoryName(val string) attribute.KeyValue {\n\treturn VCSRepositoryNameKey.String(val)\n}\n\n// VCSRepositoryURLFull returns an attribute KeyValue conforming to the\n// \"vcs.repository.url.full\" semantic conventions. It represents the\n// [canonical URL] of the repository providing the complete HTTP(S) address in\n// order to locate and identify the repository through a browser.\n//\n// [canonical URL]: https://support.google.com/webmasters/answer/10347851?hl=en#:~:text=A%20canonical%20URL%20is%20the,Google%20chooses%20one%20as%20canonical.\nfunc VCSRepositoryURLFull(val string) attribute.KeyValue {\n\treturn VCSRepositoryURLFullKey.String(val)\n}\n\n// Enum values for vcs.change.state\nvar (\n\t// Open means the change is currently active and under review. It hasn't been\n\t// merged into the target branch yet, and it's still possible to make changes or\n\t// add comments.\n\t// Stability: development\n\tVCSChangeStateOpen = VCSChangeStateKey.String(\"open\")\n\t// WIP (work-in-progress, draft) means the change is still in progress and not\n\t// yet ready for a full review. It might still undergo significant changes.\n\t// Stability: development\n\tVCSChangeStateWip = VCSChangeStateKey.String(\"wip\")\n\t// Closed means the merge request has been closed without merging. This can\n\t// happen for various reasons, such as the changes being deemed unnecessary, the\n\t// issue being resolved in another way, or the author deciding to withdraw the\n\t// request.\n\t// Stability: development\n\tVCSChangeStateClosed = VCSChangeStateKey.String(\"closed\")\n\t// Merged indicates that the change has been successfully integrated into the\n\t// target codebase.\n\t// Stability: development\n\tVCSChangeStateMerged = VCSChangeStateKey.String(\"merged\")\n)\n\n// Enum values for vcs.line_change.type\nvar (\n\t// How many lines were added.\n\t// Stability: development\n\tVCSLineChangeTypeAdded = VCSLineChangeTypeKey.String(\"added\")\n\t// How many lines were removed.\n\t// Stability: development\n\tVCSLineChangeTypeRemoved = VCSLineChangeTypeKey.String(\"removed\")\n)\n\n// Enum values for vcs.provider.name\nvar (\n\t// [GitHub]\n\t// Stability: development\n\t//\n\t// [GitHub]: https://github.com\n\tVCSProviderNameGithub = VCSProviderNameKey.String(\"github\")\n\t// [GitLab]\n\t// Stability: development\n\t//\n\t// [GitLab]: https://gitlab.com\n\tVCSProviderNameGitlab = VCSProviderNameKey.String(\"gitlab\")\n\t// [Gitea]\n\t// Stability: development\n\t//\n\t// [Gitea]: https://gitea.io\n\tVCSProviderNameGitea = VCSProviderNameKey.String(\"gitea\")\n\t// [Bitbucket]\n\t// Stability: development\n\t//\n\t// [Bitbucket]: https://bitbucket.org\n\tVCSProviderNameBitbucket = VCSProviderNameKey.String(\"bitbucket\")\n)\n\n// Enum values for vcs.ref.base.type\nvar (\n\t// [branch]\n\t// Stability: development\n\t//\n\t// [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch\n\tVCSRefBaseTypeBranch = VCSRefBaseTypeKey.String(\"branch\")\n\t// [tag]\n\t// Stability: development\n\t//\n\t// [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag\n\tVCSRefBaseTypeTag = VCSRefBaseTypeKey.String(\"tag\")\n)\n\n// Enum values for vcs.ref.head.type\nvar (\n\t// [branch]\n\t// Stability: development\n\t//\n\t// [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch\n\tVCSRefHeadTypeBranch = VCSRefHeadTypeKey.String(\"branch\")\n\t// [tag]\n\t// Stability: development\n\t//\n\t// [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag\n\tVCSRefHeadTypeTag = VCSRefHeadTypeKey.String(\"tag\")\n)\n\n// Enum values for vcs.ref.type\nvar (\n\t// [branch]\n\t// Stability: development\n\t//\n\t// [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch\n\tVCSRefTypeBranch = VCSRefTypeKey.String(\"branch\")\n\t// [tag]\n\t// Stability: development\n\t//\n\t// [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag\n\tVCSRefTypeTag = VCSRefTypeKey.String(\"tag\")\n)\n\n// Enum values for vcs.revision_delta.direction\nvar (\n\t// How many revisions the change is behind the target ref.\n\t// Stability: development\n\tVCSRevisionDeltaDirectionBehind = VCSRevisionDeltaDirectionKey.String(\"behind\")\n\t// How many revisions the change is ahead of the target ref.\n\t// Stability: development\n\tVCSRevisionDeltaDirectionAhead = VCSRevisionDeltaDirectionKey.String(\"ahead\")\n)\n\n// Namespace: webengine\nconst (\n\t// WebEngineDescriptionKey is the attribute Key conforming to the\n\t// \"webengine.description\" semantic conventions. It represents the additional\n\t// description of the web engine (e.g. detailed version and edition\n\t// information).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) -\n\t// 2.2.2.Final\"\n\tWebEngineDescriptionKey = attribute.Key(\"webengine.description\")\n\n\t// WebEngineNameKey is the attribute Key conforming to the \"webengine.name\"\n\t// semantic conventions. It represents the name of the web engine.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"WildFly\"\n\tWebEngineNameKey = attribute.Key(\"webengine.name\")\n\n\t// WebEngineVersionKey is the attribute Key conforming to the\n\t// \"webengine.version\" semantic conventions. It represents the version of the\n\t// web engine.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"21.0.0\"\n\tWebEngineVersionKey = attribute.Key(\"webengine.version\")\n)\n\n// WebEngineDescription returns an attribute KeyValue conforming to the\n// \"webengine.description\" semantic conventions. It represents the additional\n// description of the web engine (e.g. detailed version and edition information).\nfunc WebEngineDescription(val string) attribute.KeyValue {\n\treturn WebEngineDescriptionKey.String(val)\n}\n\n// WebEngineName returns an attribute KeyValue conforming to the \"webengine.name\"\n// semantic conventions. It represents the name of the web engine.\nfunc WebEngineName(val string) attribute.KeyValue {\n\treturn WebEngineNameKey.String(val)\n}\n\n// WebEngineVersion returns an attribute KeyValue conforming to the\n// \"webengine.version\" semantic conventions. It represents the version of the web\n// engine.\nfunc WebEngineVersion(val string) attribute.KeyValue {\n\treturn WebEngineVersionKey.String(val)\n}\n\n// Namespace: zos\nconst (\n\t// ZOSSmfIDKey is the attribute Key conforming to the \"zos.smf.id\" semantic\n\t// conventions. It represents the System Management Facility (SMF) Identifier\n\t// uniquely identified a z/OS system within a SYSPLEX or mainframe environment\n\t// and is used for system and performance analysis.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"SYS1\"\n\tZOSSmfIDKey = attribute.Key(\"zos.smf.id\")\n\n\t// ZOSSysplexNameKey is the attribute Key conforming to the \"zos.sysplex.name\"\n\t// semantic conventions. It represents the name of the SYSPLEX to which the z/OS\n\t// system belongs too.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"SYSPLEX1\"\n\tZOSSysplexNameKey = attribute.Key(\"zos.sysplex.name\")\n)\n\n// ZOSSmfID returns an attribute KeyValue conforming to the \"zos.smf.id\" semantic\n// conventions. It represents the System Management Facility (SMF) Identifier\n// uniquely identified a z/OS system within a SYSPLEX or mainframe environment\n// and is used for system and performance analysis.\nfunc ZOSSmfID(val string) attribute.KeyValue {\n\treturn ZOSSmfIDKey.String(val)\n}\n\n// ZOSSysplexName returns an attribute KeyValue conforming to the\n// \"zos.sysplex.name\" semantic conventions. It represents the name of the SYSPLEX\n// to which the z/OS system belongs too.\nfunc ZOSSysplexName(val string) attribute.KeyValue {\n\treturn ZOSSysplexNameKey.String(val)\n}"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.37.0/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package semconv implements OpenTelemetry semantic conventions.\n//\n// OpenTelemetry semantic conventions are agreed standardized naming\n// patterns for OpenTelemetry things. This package represents the v1.37.0\n// version of the OpenTelemetry semantic conventions.\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.37.0\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.37.0/error_type.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.37.0\"\n\nimport (\n\t\"reflect\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n)\n\n// ErrorType returns an [attribute.KeyValue] identifying the error type of err.\n//\n// If err is nil, the returned attribute has the default value\n// [ErrorTypeOther].\n//\n// If err's type has the method\n//\n//\tErrorType() string\n//\n// then the returned attribute has the value of err.ErrorType(). Otherwise, the\n// returned attribute has a value derived from the concrete type of err.\n//\n// The key of the returned attribute is [ErrorTypeKey].\nfunc ErrorType(err error) attribute.KeyValue {\n\tif err == nil {\n\t\treturn ErrorTypeOther\n\t}\n\n\treturn ErrorTypeKey.String(errorType(err))\n}\n\nfunc errorType(err error) string {\n\tvar s string\n\tif et, ok := err.(interface{ ErrorType() string }); ok {\n\t\t// Prioritize the ErrorType method if available.\n\t\ts = et.ErrorType()\n\t}\n\tif s == \"\" {\n\t\t// Fallback to reflection if the ErrorType method is not supported or\n\t\t// returns an empty value.\n\n\t\tt := reflect.TypeOf(err)\n\t\tpkg, name := t.PkgPath(), t.Name()\n\t\tif pkg != \"\" && name != \"\" {\n\t\t\ts = pkg + \".\" + name\n\t\t} else {\n\t\t\t// The type has no package path or name (predeclared, not-defined,\n\t\t\t// or alias for a not-defined type).\n\t\t\t//\n\t\t\t// This is not guaranteed to be unique, but is a best effort.\n\t\t\ts = t.String()\n\t\t}\n\t}\n\treturn s\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.37.0/exception.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.37.0\"\n\nconst (\n\t// ExceptionEventName is the name of the Span event representing an exception.\n\tExceptionEventName = \"exception\"\n)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.37.0/schema.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.37.0\"\n\n// SchemaURL is the schema URL that matches the version of the semantic conventions\n// that this package defines. Semconv packages starting from v1.4.0 must declare\n// non-empty schema URL in the form https://opentelemetry.io/schemas/<version>\nconst SchemaURL = \"https://opentelemetry.io/schemas/1.37.0\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.39.0/MIGRATION.md",
    "content": "<!-- Generated. DO NOT MODIFY. -->\n# Migration from v1.38.0 to v1.39.0\n\nThe `go.opentelemetry.io/otel/semconv/v1.39.0` package should be a drop-in replacement for `go.opentelemetry.io/otel/semconv/v1.38.0` with the following exceptions.\n\n## Removed\n\nThe following declarations have been removed.\nRefer to the [OpenTelemetry Semantic Conventions documentation] for deprecation instructions.\n\nIf the type is not listed in the documentation as deprecated, it has been removed in this version due to lack of applicability or use.\nIf you use any of these non-deprecated declarations in your Go application, please [open an issue] describing your use-case.\n\n- `LinuxMemorySlabStateKey`\n- `LinuxMemorySlabStateReclaimable`\n- `LinuxMemorySlabStateUnreclaimable`\n- `PeerService`\n- `PeerServiceKey`\n- `RPCConnectRPCErrorCodeAborted`\n- `RPCConnectRPCErrorCodeAlreadyExists`\n- `RPCConnectRPCErrorCodeCancelled`\n- `RPCConnectRPCErrorCodeDataLoss`\n- `RPCConnectRPCErrorCodeDeadlineExceeded`\n- `RPCConnectRPCErrorCodeFailedPrecondition`\n- `RPCConnectRPCErrorCodeInternal`\n- `RPCConnectRPCErrorCodeInvalidArgument`\n- `RPCConnectRPCErrorCodeKey`\n- `RPCConnectRPCErrorCodeNotFound`\n- `RPCConnectRPCErrorCodeOutOfRange`\n- `RPCConnectRPCErrorCodePermissionDenied`\n- `RPCConnectRPCErrorCodeResourceExhausted`\n- `RPCConnectRPCErrorCodeUnauthenticated`\n- `RPCConnectRPCErrorCodeUnavailable`\n- `RPCConnectRPCErrorCodeUnimplemented`\n- `RPCConnectRPCErrorCodeUnknown`\n- `RPCConnectRPCRequestMetadata`\n- `RPCConnectRPCResponseMetadata`\n- `RPCGRPCRequestMetadata`\n- `RPCGRPCResponseMetadata`\n- `RPCGRPCStatusCodeAborted`\n- `RPCGRPCStatusCodeAlreadyExists`\n- `RPCGRPCStatusCodeCancelled`\n- `RPCGRPCStatusCodeDataLoss`\n- `RPCGRPCStatusCodeDeadlineExceeded`\n- `RPCGRPCStatusCodeFailedPrecondition`\n- `RPCGRPCStatusCodeInternal`\n- `RPCGRPCStatusCodeInvalidArgument`\n- `RPCGRPCStatusCodeKey`\n- `RPCGRPCStatusCodeNotFound`\n- `RPCGRPCStatusCodeOk`\n- `RPCGRPCStatusCodeOutOfRange`\n- `RPCGRPCStatusCodePermissionDenied`\n- `RPCGRPCStatusCodeResourceExhausted`\n- `RPCGRPCStatusCodeUnauthenticated`\n- `RPCGRPCStatusCodeUnavailable`\n- `RPCGRPCStatusCodeUnimplemented`\n- `RPCGRPCStatusCodeUnknown`\n- `RPCJSONRPCErrorCode`\n- `RPCJSONRPCErrorCodeKey`\n- `RPCJSONRPCErrorMessage`\n- `RPCJSONRPCErrorMessageKey`\n- `RPCJSONRPCRequestID`\n- `RPCJSONRPCRequestIDKey`\n- `RPCJSONRPCVersion`\n- `RPCJSONRPCVersionKey`\n- `RPCService`\n- `RPCServiceKey`\n- `RPCSystemApacheDubbo`\n- `RPCSystemConnectRPC`\n- `RPCSystemDotnetWcf`\n- `RPCSystemGRPC`\n- `RPCSystemJSONRPC`\n- `RPCSystemJavaRmi`\n- `RPCSystemKey`\n- `RPCSystemOncRPC`\n\n[OpenTelemetry Semantic Conventions documentation]: https://github.com/open-telemetry/semantic-conventions\n[open an issue]: https://github.com/open-telemetry/opentelemetry-go/issues/new?template=Blank+issue\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.39.0/README.md",
    "content": "# Semconv v1.39.0\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/semconv/v1.39.0)](https://pkg.go.dev/go.opentelemetry.io/otel/semconv/v1.39.0)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.39.0/attribute_group.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Code generated from semantic convention specification. DO NOT EDIT.\n\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.39.0\"\n\nimport \"go.opentelemetry.io/otel/attribute\"\n\n// Namespace: android\nconst (\n\t// AndroidAppStateKey is the attribute Key conforming to the \"android.app.state\"\n\t// semantic conventions. It represents the this attribute represents the state\n\t// of the application.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"created\"\n\t// Note: The Android lifecycle states are defined in\n\t// [Activity lifecycle callbacks], and from which the `OS identifiers` are\n\t// derived.\n\t//\n\t// [Activity lifecycle callbacks]: https://developer.android.com/guide/components/activities/activity-lifecycle#lc\n\tAndroidAppStateKey = attribute.Key(\"android.app.state\")\n\n\t// AndroidOSAPILevelKey is the attribute Key conforming to the\n\t// \"android.os.api_level\" semantic conventions. It represents the uniquely\n\t// identifies the framework API revision offered by a version (`os.version`) of\n\t// the android operating system. More information can be found in the\n\t// [Android API levels documentation].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"33\", \"32\"\n\t//\n\t// [Android API levels documentation]: https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels\n\tAndroidOSAPILevelKey = attribute.Key(\"android.os.api_level\")\n)\n\n// AndroidOSAPILevel returns an attribute KeyValue conforming to the\n// \"android.os.api_level\" semantic conventions. It represents the uniquely\n// identifies the framework API revision offered by a version (`os.version`) of\n// the android operating system. More information can be found in the\n// [Android API levels documentation].\n//\n// [Android API levels documentation]: https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels\nfunc AndroidOSAPILevel(val string) attribute.KeyValue {\n\treturn AndroidOSAPILevelKey.String(val)\n}\n\n// Enum values for android.app.state\nvar (\n\t// Any time before Activity.onResume() or, if the app has no Activity,\n\t// Context.startService() has been called in the app for the first time.\n\t//\n\t// Stability: development\n\tAndroidAppStateCreated = AndroidAppStateKey.String(\"created\")\n\t// Any time after Activity.onPause() or, if the app has no Activity,\n\t// Context.stopService() has been called when the app was in the foreground\n\t// state.\n\t//\n\t// Stability: development\n\tAndroidAppStateBackground = AndroidAppStateKey.String(\"background\")\n\t// Any time after Activity.onResume() or, if the app has no Activity,\n\t// Context.startService() has been called when the app was in either the created\n\t// or background states.\n\t//\n\t// Stability: development\n\tAndroidAppStateForeground = AndroidAppStateKey.String(\"foreground\")\n)\n\n// Namespace: app\nconst (\n\t// AppBuildIDKey is the attribute Key conforming to the \"app.build_id\" semantic\n\t// conventions. It represents the unique identifier for a particular build or\n\t// compilation of the application.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"6cff0a7e-cefc-4668-96f5-1273d8b334d0\",\n\t// \"9f2b833506aa6973a92fde9733e6271f\", \"my-app-1.0.0-code-123\"\n\tAppBuildIDKey = attribute.Key(\"app.build_id\")\n\n\t// AppInstallationIDKey is the attribute Key conforming to the\n\t// \"app.installation.id\" semantic conventions. It represents a unique identifier\n\t// representing the installation of an application on a specific device.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2ab2916d-a51f-4ac8-80ee-45ac31a28092\"\n\t// Note: Its value SHOULD persist across launches of the same application\n\t// installation, including through application upgrades.\n\t// It SHOULD change if the application is uninstalled or if all applications of\n\t// the vendor are uninstalled.\n\t// Additionally, users might be able to reset this value (e.g. by clearing\n\t// application data).\n\t// If an app is installed multiple times on the same device (e.g. in different\n\t// accounts on Android), each `app.installation.id` SHOULD have a different\n\t// value.\n\t// If multiple OpenTelemetry SDKs are used within the same application, they\n\t// SHOULD use the same value for `app.installation.id`.\n\t// Hardware IDs (e.g. serial number, IMEI, MAC address) MUST NOT be used as the\n\t// `app.installation.id`.\n\t//\n\t// For iOS, this value SHOULD be equal to the [vendor identifier].\n\t//\n\t// For Android, examples of `app.installation.id` implementations include:\n\t//\n\t//   - [Firebase Installation ID].\n\t//   - A globally unique UUID which is persisted across sessions in your\n\t//     application.\n\t//   - [App set ID].\n\t//   - [`Settings.getString(Settings.Secure.ANDROID_ID)`].\n\t//\n\t// More information about Android identifier best practices can be found in the\n\t// [Android user data IDs guide].\n\t//\n\t// [vendor identifier]: https://developer.apple.com/documentation/uikit/uidevice/identifierforvendor\n\t// [Firebase Installation ID]: https://firebase.google.com/docs/projects/manage-installations\n\t// [App set ID]: https://developer.android.com/identity/app-set-id\n\t// [`Settings.getString(Settings.Secure.ANDROID_ID)`]: https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID\n\t// [Android user data IDs guide]: https://developer.android.com/training/articles/user-data-ids\n\tAppInstallationIDKey = attribute.Key(\"app.installation.id\")\n\n\t// AppJankFrameCountKey is the attribute Key conforming to the\n\t// \"app.jank.frame_count\" semantic conventions. It represents a number of frame\n\t// renders that experienced jank.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 9, 42\n\t// Note: Depending on platform limitations, the value provided MAY be\n\t// approximation.\n\tAppJankFrameCountKey = attribute.Key(\"app.jank.frame_count\")\n\n\t// AppJankPeriodKey is the attribute Key conforming to the \"app.jank.period\"\n\t// semantic conventions. It represents the time period, in seconds, for which\n\t// this jank is being reported.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1.0, 5.0, 10.24\n\tAppJankPeriodKey = attribute.Key(\"app.jank.period\")\n\n\t// AppJankThresholdKey is the attribute Key conforming to the\n\t// \"app.jank.threshold\" semantic conventions. It represents the minimum\n\t// rendering threshold for this jank, in seconds.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0.016, 0.7, 1.024\n\tAppJankThresholdKey = attribute.Key(\"app.jank.threshold\")\n\n\t// AppScreenCoordinateXKey is the attribute Key conforming to the\n\t// \"app.screen.coordinate.x\" semantic conventions. It represents the x\n\t// (horizontal) coordinate of a screen coordinate, in screen pixels.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0, 131\n\tAppScreenCoordinateXKey = attribute.Key(\"app.screen.coordinate.x\")\n\n\t// AppScreenCoordinateYKey is the attribute Key conforming to the\n\t// \"app.screen.coordinate.y\" semantic conventions. It represents the y\n\t// (vertical) component of a screen coordinate, in screen pixels.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 12, 99\n\tAppScreenCoordinateYKey = attribute.Key(\"app.screen.coordinate.y\")\n\n\t// AppScreenIDKey is the attribute Key conforming to the \"app.screen.id\"\n\t// semantic conventions. It represents an identifier that uniquely\n\t// differentiates this screen from other screens in the same application.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"f9bc787d-ff05-48ad-90e1-fca1d46130b3\",\n\t// \"com.example.app.MainActivity\", \"com.example.shop.ProductDetailFragment\",\n\t// \"MyApp.ProfileView\", \"MyApp.ProfileViewController\"\n\t// Note: A screen represents only the part of the device display drawn by the\n\t// app. It typically contains multiple widgets or UI components and is larger in\n\t// scope than individual widgets. Multiple screens can coexist on the same\n\t// display simultaneously (e.g., split view on tablets).\n\tAppScreenIDKey = attribute.Key(\"app.screen.id\")\n\n\t// AppScreenNameKey is the attribute Key conforming to the \"app.screen.name\"\n\t// semantic conventions. It represents the name of an application screen.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"MainActivity\", \"ProductDetailFragment\", \"ProfileView\",\n\t// \"ProfileViewController\"\n\t// Note: A screen represents only the part of the device display drawn by the\n\t// app. It typically contains multiple widgets or UI components and is larger in\n\t// scope than individual widgets. Multiple screens can coexist on the same\n\t// display simultaneously (e.g., split view on tablets).\n\tAppScreenNameKey = attribute.Key(\"app.screen.name\")\n\n\t// AppWidgetIDKey is the attribute Key conforming to the \"app.widget.id\"\n\t// semantic conventions. It represents an identifier that uniquely\n\t// differentiates this widget from other widgets in the same application.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"f9bc787d-ff05-48ad-90e1-fca1d46130b3\", \"submit_order_1829\"\n\t// Note: A widget is an application component, typically an on-screen visual GUI\n\t// element.\n\tAppWidgetIDKey = attribute.Key(\"app.widget.id\")\n\n\t// AppWidgetNameKey is the attribute Key conforming to the \"app.widget.name\"\n\t// semantic conventions. It represents the name of an application widget.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"submit\", \"attack\", \"Clear Cart\"\n\t// Note: A widget is an application component, typically an on-screen visual GUI\n\t// element.\n\tAppWidgetNameKey = attribute.Key(\"app.widget.name\")\n)\n\n// AppBuildID returns an attribute KeyValue conforming to the \"app.build_id\"\n// semantic conventions. It represents the unique identifier for a particular\n// build or compilation of the application.\nfunc AppBuildID(val string) attribute.KeyValue {\n\treturn AppBuildIDKey.String(val)\n}\n\n// AppInstallationID returns an attribute KeyValue conforming to the\n// \"app.installation.id\" semantic conventions. It represents a unique identifier\n// representing the installation of an application on a specific device.\nfunc AppInstallationID(val string) attribute.KeyValue {\n\treturn AppInstallationIDKey.String(val)\n}\n\n// AppJankFrameCount returns an attribute KeyValue conforming to the\n// \"app.jank.frame_count\" semantic conventions. It represents a number of frame\n// renders that experienced jank.\nfunc AppJankFrameCount(val int) attribute.KeyValue {\n\treturn AppJankFrameCountKey.Int(val)\n}\n\n// AppJankPeriod returns an attribute KeyValue conforming to the\n// \"app.jank.period\" semantic conventions. It represents the time period, in\n// seconds, for which this jank is being reported.\nfunc AppJankPeriod(val float64) attribute.KeyValue {\n\treturn AppJankPeriodKey.Float64(val)\n}\n\n// AppJankThreshold returns an attribute KeyValue conforming to the\n// \"app.jank.threshold\" semantic conventions. It represents the minimum rendering\n// threshold for this jank, in seconds.\nfunc AppJankThreshold(val float64) attribute.KeyValue {\n\treturn AppJankThresholdKey.Float64(val)\n}\n\n// AppScreenCoordinateX returns an attribute KeyValue conforming to the\n// \"app.screen.coordinate.x\" semantic conventions. It represents the x\n// (horizontal) coordinate of a screen coordinate, in screen pixels.\nfunc AppScreenCoordinateX(val int) attribute.KeyValue {\n\treturn AppScreenCoordinateXKey.Int(val)\n}\n\n// AppScreenCoordinateY returns an attribute KeyValue conforming to the\n// \"app.screen.coordinate.y\" semantic conventions. It represents the y (vertical)\n// component of a screen coordinate, in screen pixels.\nfunc AppScreenCoordinateY(val int) attribute.KeyValue {\n\treturn AppScreenCoordinateYKey.Int(val)\n}\n\n// AppScreenID returns an attribute KeyValue conforming to the \"app.screen.id\"\n// semantic conventions. It represents an identifier that uniquely differentiates\n// this screen from other screens in the same application.\nfunc AppScreenID(val string) attribute.KeyValue {\n\treturn AppScreenIDKey.String(val)\n}\n\n// AppScreenName returns an attribute KeyValue conforming to the\n// \"app.screen.name\" semantic conventions. It represents the name of an\n// application screen.\nfunc AppScreenName(val string) attribute.KeyValue {\n\treturn AppScreenNameKey.String(val)\n}\n\n// AppWidgetID returns an attribute KeyValue conforming to the \"app.widget.id\"\n// semantic conventions. It represents an identifier that uniquely differentiates\n// this widget from other widgets in the same application.\nfunc AppWidgetID(val string) attribute.KeyValue {\n\treturn AppWidgetIDKey.String(val)\n}\n\n// AppWidgetName returns an attribute KeyValue conforming to the\n// \"app.widget.name\" semantic conventions. It represents the name of an\n// application widget.\nfunc AppWidgetName(val string) attribute.KeyValue {\n\treturn AppWidgetNameKey.String(val)\n}\n\n// Namespace: artifact\nconst (\n\t// ArtifactAttestationFilenameKey is the attribute Key conforming to the\n\t// \"artifact.attestation.filename\" semantic conventions. It represents the\n\t// provenance filename of the built attestation which directly relates to the\n\t// build artifact filename. This filename SHOULD accompany the artifact at\n\t// publish time. See the [SLSA Relationship] specification for more information.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"golang-binary-amd64-v0.1.0.attestation\",\n\t// \"docker-image-amd64-v0.1.0.intoto.json1\", \"release-1.tar.gz.attestation\",\n\t// \"file-name-package.tar.gz.intoto.json1\"\n\t//\n\t// [SLSA Relationship]: https://slsa.dev/spec/v1.0/distributing-provenance#relationship-between-artifacts-and-attestations\n\tArtifactAttestationFilenameKey = attribute.Key(\"artifact.attestation.filename\")\n\n\t// ArtifactAttestationHashKey is the attribute Key conforming to the\n\t// \"artifact.attestation.hash\" semantic conventions. It represents the full\n\t// [hash value (see glossary)], of the built attestation. Some envelopes in the\n\t// [software attestation space] also refer to this as the **digest**.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1b31dfcd5b7f9267bf2ff47651df1cfb9147b9e4df1f335accf65b4cda498408\"\n\t//\n\t// [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf\n\t// [software attestation space]: https://github.com/in-toto/attestation/tree/main/spec\n\tArtifactAttestationHashKey = attribute.Key(\"artifact.attestation.hash\")\n\n\t// ArtifactAttestationIDKey is the attribute Key conforming to the\n\t// \"artifact.attestation.id\" semantic conventions. It represents the id of the\n\t// build [software attestation].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"123\"\n\t//\n\t// [software attestation]: https://slsa.dev/attestation-model\n\tArtifactAttestationIDKey = attribute.Key(\"artifact.attestation.id\")\n\n\t// ArtifactFilenameKey is the attribute Key conforming to the\n\t// \"artifact.filename\" semantic conventions. It represents the human readable\n\t// file name of the artifact, typically generated during build and release\n\t// processes. Often includes the package name and version in the file name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"golang-binary-amd64-v0.1.0\", \"docker-image-amd64-v0.1.0\",\n\t// \"release-1.tar.gz\", \"file-name-package.tar.gz\"\n\t// Note: This file name can also act as the [Package Name]\n\t// in cases where the package ecosystem maps accordingly.\n\t// Additionally, the artifact [can be published]\n\t// for others, but that is not a guarantee.\n\t//\n\t// [Package Name]: https://slsa.dev/spec/v1.0/terminology#package-model\n\t// [can be published]: https://slsa.dev/spec/v1.0/terminology#software-supply-chain\n\tArtifactFilenameKey = attribute.Key(\"artifact.filename\")\n\n\t// ArtifactHashKey is the attribute Key conforming to the \"artifact.hash\"\n\t// semantic conventions. It represents the full [hash value (see glossary)],\n\t// often found in checksum.txt on a release of the artifact and used to verify\n\t// package integrity.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"9ff4c52759e2c4ac70b7d517bc7fcdc1cda631ca0045271ddd1b192544f8a3e9\"\n\t// Note: The specific algorithm used to create the cryptographic hash value is\n\t// not defined. In situations where an artifact has multiple\n\t// cryptographic hashes, it is up to the implementer to choose which\n\t// hash value to set here; this should be the most secure hash algorithm\n\t// that is suitable for the situation and consistent with the\n\t// corresponding attestation. The implementer can then provide the other\n\t// hash values through an additional set of attribute extensions as they\n\t// deem necessary.\n\t//\n\t// [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf\n\tArtifactHashKey = attribute.Key(\"artifact.hash\")\n\n\t// ArtifactPurlKey is the attribute Key conforming to the \"artifact.purl\"\n\t// semantic conventions. It represents the [Package URL] of the\n\t// [package artifact] provides a standard way to identify and locate the\n\t// packaged artifact.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"pkg:github/package-url/purl-spec@1209109710924\",\n\t// \"pkg:npm/foo@12.12.3\"\n\t//\n\t// [Package URL]: https://github.com/package-url/purl-spec\n\t// [package artifact]: https://slsa.dev/spec/v1.0/terminology#package-model\n\tArtifactPurlKey = attribute.Key(\"artifact.purl\")\n\n\t// ArtifactVersionKey is the attribute Key conforming to the \"artifact.version\"\n\t// semantic conventions. It represents the version of the artifact.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"v0.1.0\", \"1.2.1\", \"122691-build\"\n\tArtifactVersionKey = attribute.Key(\"artifact.version\")\n)\n\n// ArtifactAttestationFilename returns an attribute KeyValue conforming to the\n// \"artifact.attestation.filename\" semantic conventions. It represents the\n// provenance filename of the built attestation which directly relates to the\n// build artifact filename. This filename SHOULD accompany the artifact at\n// publish time. See the [SLSA Relationship] specification for more information.\n//\n// [SLSA Relationship]: https://slsa.dev/spec/v1.0/distributing-provenance#relationship-between-artifacts-and-attestations\nfunc ArtifactAttestationFilename(val string) attribute.KeyValue {\n\treturn ArtifactAttestationFilenameKey.String(val)\n}\n\n// ArtifactAttestationHash returns an attribute KeyValue conforming to the\n// \"artifact.attestation.hash\" semantic conventions. It represents the full\n// [hash value (see glossary)], of the built attestation. Some envelopes in the\n// [software attestation space] also refer to this as the **digest**.\n//\n// [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf\n// [software attestation space]: https://github.com/in-toto/attestation/tree/main/spec\nfunc ArtifactAttestationHash(val string) attribute.KeyValue {\n\treturn ArtifactAttestationHashKey.String(val)\n}\n\n// ArtifactAttestationID returns an attribute KeyValue conforming to the\n// \"artifact.attestation.id\" semantic conventions. It represents the id of the\n// build [software attestation].\n//\n// [software attestation]: https://slsa.dev/attestation-model\nfunc ArtifactAttestationID(val string) attribute.KeyValue {\n\treturn ArtifactAttestationIDKey.String(val)\n}\n\n// ArtifactFilename returns an attribute KeyValue conforming to the\n// \"artifact.filename\" semantic conventions. It represents the human readable\n// file name of the artifact, typically generated during build and release\n// processes. Often includes the package name and version in the file name.\nfunc ArtifactFilename(val string) attribute.KeyValue {\n\treturn ArtifactFilenameKey.String(val)\n}\n\n// ArtifactHash returns an attribute KeyValue conforming to the \"artifact.hash\"\n// semantic conventions. It represents the full [hash value (see glossary)],\n// often found in checksum.txt on a release of the artifact and used to verify\n// package integrity.\n//\n// [hash value (see glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf\nfunc ArtifactHash(val string) attribute.KeyValue {\n\treturn ArtifactHashKey.String(val)\n}\n\n// ArtifactPurl returns an attribute KeyValue conforming to the \"artifact.purl\"\n// semantic conventions. It represents the [Package URL] of the\n// [package artifact] provides a standard way to identify and locate the packaged\n// artifact.\n//\n// [Package URL]: https://github.com/package-url/purl-spec\n// [package artifact]: https://slsa.dev/spec/v1.0/terminology#package-model\nfunc ArtifactPurl(val string) attribute.KeyValue {\n\treturn ArtifactPurlKey.String(val)\n}\n\n// ArtifactVersion returns an attribute KeyValue conforming to the\n// \"artifact.version\" semantic conventions. It represents the version of the\n// artifact.\nfunc ArtifactVersion(val string) attribute.KeyValue {\n\treturn ArtifactVersionKey.String(val)\n}\n\n// Namespace: aws\nconst (\n\t// AWSBedrockGuardrailIDKey is the attribute Key conforming to the\n\t// \"aws.bedrock.guardrail.id\" semantic conventions. It represents the unique\n\t// identifier of the AWS Bedrock Guardrail. A [guardrail] helps safeguard and\n\t// prevent unwanted behavior from model responses or user messages.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"sgi5gkybzqak\"\n\t//\n\t// [guardrail]: https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html\n\tAWSBedrockGuardrailIDKey = attribute.Key(\"aws.bedrock.guardrail.id\")\n\n\t// AWSBedrockKnowledgeBaseIDKey is the attribute Key conforming to the\n\t// \"aws.bedrock.knowledge_base.id\" semantic conventions. It represents the\n\t// unique identifier of the AWS Bedrock Knowledge base. A [knowledge base] is a\n\t// bank of information that can be queried by models to generate more relevant\n\t// responses and augment prompts.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"XFWUPB9PAW\"\n\t//\n\t// [knowledge base]: https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base.html\n\tAWSBedrockKnowledgeBaseIDKey = attribute.Key(\"aws.bedrock.knowledge_base.id\")\n\n\t// AWSDynamoDBAttributeDefinitionsKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.attribute_definitions\" semantic conventions. It represents the\n\t// JSON-serialized value of each item in the `AttributeDefinitions` request\n\t// field.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"{ \"AttributeName\": \"string\", \"AttributeType\": \"string\" }\"\n\tAWSDynamoDBAttributeDefinitionsKey = attribute.Key(\"aws.dynamodb.attribute_definitions\")\n\n\t// AWSDynamoDBAttributesToGetKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.attributes_to_get\" semantic conventions. It represents the\n\t// value of the `AttributesToGet` request parameter.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"lives\", \"id\"\n\tAWSDynamoDBAttributesToGetKey = attribute.Key(\"aws.dynamodb.attributes_to_get\")\n\n\t// AWSDynamoDBConsistentReadKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.consistent_read\" semantic conventions. It represents the value\n\t// of the `ConsistentRead` request parameter.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tAWSDynamoDBConsistentReadKey = attribute.Key(\"aws.dynamodb.consistent_read\")\n\n\t// AWSDynamoDBConsumedCapacityKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.consumed_capacity\" semantic conventions. It represents the\n\t// JSON-serialized value of each item in the `ConsumedCapacity` response field.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"{ \"CapacityUnits\": number, \"GlobalSecondaryIndexes\": { \"string\" :\n\t// { \"CapacityUnits\": number, \"ReadCapacityUnits\": number, \"WriteCapacityUnits\":\n\t// number } }, \"LocalSecondaryIndexes\": { \"string\" : { \"CapacityUnits\": number,\n\t// \"ReadCapacityUnits\": number, \"WriteCapacityUnits\": number } },\n\t// \"ReadCapacityUnits\": number, \"Table\": { \"CapacityUnits\": number,\n\t// \"ReadCapacityUnits\": number, \"WriteCapacityUnits\": number }, \"TableName\":\n\t// \"string\", \"WriteCapacityUnits\": number }\"\n\tAWSDynamoDBConsumedCapacityKey = attribute.Key(\"aws.dynamodb.consumed_capacity\")\n\n\t// AWSDynamoDBCountKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.count\" semantic conventions. It represents the value of the\n\t// `Count` response parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 10\n\tAWSDynamoDBCountKey = attribute.Key(\"aws.dynamodb.count\")\n\n\t// AWSDynamoDBExclusiveStartTableKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.exclusive_start_table\" semantic conventions. It represents the\n\t// value of the `ExclusiveStartTableName` request parameter.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Users\", \"CatsTable\"\n\tAWSDynamoDBExclusiveStartTableKey = attribute.Key(\"aws.dynamodb.exclusive_start_table\")\n\n\t// AWSDynamoDBGlobalSecondaryIndexUpdatesKey is the attribute Key conforming to\n\t// the \"aws.dynamodb.global_secondary_index_updates\" semantic conventions. It\n\t// represents the JSON-serialized value of each item in the\n\t// `GlobalSecondaryIndexUpdates` request field.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"{ \"Create\": { \"IndexName\": \"string\", \"KeySchema\": [ {\n\t// \"AttributeName\": \"string\", \"KeyType\": \"string\" } ], \"Projection\": {\n\t// \"NonKeyAttributes\": [ \"string\" ], \"ProjectionType\": \"string\" },\n\t// \"ProvisionedThroughput\": { \"ReadCapacityUnits\": number, \"WriteCapacityUnits\":\n\t// number } }\"\n\tAWSDynamoDBGlobalSecondaryIndexUpdatesKey = attribute.Key(\"aws.dynamodb.global_secondary_index_updates\")\n\n\t// AWSDynamoDBGlobalSecondaryIndexesKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.global_secondary_indexes\" semantic conventions. It represents\n\t// the JSON-serialized value of each item of the `GlobalSecondaryIndexes`\n\t// request field.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"{ \"IndexName\": \"string\", \"KeySchema\": [ { \"AttributeName\":\n\t// \"string\", \"KeyType\": \"string\" } ], \"Projection\": { \"NonKeyAttributes\": [\n\t// \"string\" ], \"ProjectionType\": \"string\" }, \"ProvisionedThroughput\": {\n\t// \"ReadCapacityUnits\": number, \"WriteCapacityUnits\": number } }\"\n\tAWSDynamoDBGlobalSecondaryIndexesKey = attribute.Key(\"aws.dynamodb.global_secondary_indexes\")\n\n\t// AWSDynamoDBIndexNameKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.index_name\" semantic conventions. It represents the value of\n\t// the `IndexName` request parameter.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"name_to_group\"\n\tAWSDynamoDBIndexNameKey = attribute.Key(\"aws.dynamodb.index_name\")\n\n\t// AWSDynamoDBItemCollectionMetricsKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.item_collection_metrics\" semantic conventions. It represents\n\t// the JSON-serialized value of the `ItemCollectionMetrics` response field.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"{ \"string\" : [ { \"ItemCollectionKey\": { \"string\" : { \"B\": blob,\n\t// \"BOOL\": boolean, \"BS\": [ blob ], \"L\": [ \"AttributeValue\" ], \"M\": { \"string\" :\n\t// \"AttributeValue\" }, \"N\": \"string\", \"NS\": [ \"string\" ], \"NULL\": boolean, \"S\":\n\t// \"string\", \"SS\": [ \"string\" ] } }, \"SizeEstimateRangeGB\": [ number ] } ] }\"\n\tAWSDynamoDBItemCollectionMetricsKey = attribute.Key(\"aws.dynamodb.item_collection_metrics\")\n\n\t// AWSDynamoDBLimitKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.limit\" semantic conventions. It represents the value of the\n\t// `Limit` request parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 10\n\tAWSDynamoDBLimitKey = attribute.Key(\"aws.dynamodb.limit\")\n\n\t// AWSDynamoDBLocalSecondaryIndexesKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.local_secondary_indexes\" semantic conventions. It represents\n\t// the JSON-serialized value of each item of the `LocalSecondaryIndexes` request\n\t// field.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"{ \"IndexArn\": \"string\", \"IndexName\": \"string\", \"IndexSizeBytes\":\n\t// number, \"ItemCount\": number, \"KeySchema\": [ { \"AttributeName\": \"string\",\n\t// \"KeyType\": \"string\" } ], \"Projection\": { \"NonKeyAttributes\": [ \"string\" ],\n\t// \"ProjectionType\": \"string\" } }\"\n\tAWSDynamoDBLocalSecondaryIndexesKey = attribute.Key(\"aws.dynamodb.local_secondary_indexes\")\n\n\t// AWSDynamoDBProjectionKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.projection\" semantic conventions. It represents the value of\n\t// the `ProjectionExpression` request parameter.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Title\", \"Title, Price, Color\", \"Title, Description, RelatedItems,\n\t// ProductReviews\"\n\tAWSDynamoDBProjectionKey = attribute.Key(\"aws.dynamodb.projection\")\n\n\t// AWSDynamoDBProvisionedReadCapacityKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.provisioned_read_capacity\" semantic conventions. It represents\n\t// the value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1.0, 2.0\n\tAWSDynamoDBProvisionedReadCapacityKey = attribute.Key(\"aws.dynamodb.provisioned_read_capacity\")\n\n\t// AWSDynamoDBProvisionedWriteCapacityKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.provisioned_write_capacity\" semantic conventions. It represents\n\t// the value of the `ProvisionedThroughput.WriteCapacityUnits` request\n\t// parameter.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1.0, 2.0\n\tAWSDynamoDBProvisionedWriteCapacityKey = attribute.Key(\"aws.dynamodb.provisioned_write_capacity\")\n\n\t// AWSDynamoDBScanForwardKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.scan_forward\" semantic conventions. It represents the value of\n\t// the `ScanIndexForward` request parameter.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tAWSDynamoDBScanForwardKey = attribute.Key(\"aws.dynamodb.scan_forward\")\n\n\t// AWSDynamoDBScannedCountKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.scanned_count\" semantic conventions. It represents the value of\n\t// the `ScannedCount` response parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 50\n\tAWSDynamoDBScannedCountKey = attribute.Key(\"aws.dynamodb.scanned_count\")\n\n\t// AWSDynamoDBSegmentKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.segment\" semantic conventions. It represents the value of the\n\t// `Segment` request parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 10\n\tAWSDynamoDBSegmentKey = attribute.Key(\"aws.dynamodb.segment\")\n\n\t// AWSDynamoDBSelectKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.select\" semantic conventions. It represents the value of the\n\t// `Select` request parameter.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"ALL_ATTRIBUTES\", \"COUNT\"\n\tAWSDynamoDBSelectKey = attribute.Key(\"aws.dynamodb.select\")\n\n\t// AWSDynamoDBTableCountKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.table_count\" semantic conventions. It represents the number of\n\t// items in the `TableNames` response parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 20\n\tAWSDynamoDBTableCountKey = attribute.Key(\"aws.dynamodb.table_count\")\n\n\t// AWSDynamoDBTableNamesKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.table_names\" semantic conventions. It represents the keys in\n\t// the `RequestItems` object field.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Users\", \"Cats\"\n\tAWSDynamoDBTableNamesKey = attribute.Key(\"aws.dynamodb.table_names\")\n\n\t// AWSDynamoDBTotalSegmentsKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.total_segments\" semantic conventions. It represents the value\n\t// of the `TotalSegments` request parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 100\n\tAWSDynamoDBTotalSegmentsKey = attribute.Key(\"aws.dynamodb.total_segments\")\n\n\t// AWSECSClusterARNKey is the attribute Key conforming to the\n\t// \"aws.ecs.cluster.arn\" semantic conventions. It represents the ARN of an\n\t// [ECS cluster].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster\"\n\t//\n\t// [ECS cluster]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html\n\tAWSECSClusterARNKey = attribute.Key(\"aws.ecs.cluster.arn\")\n\n\t// AWSECSContainerARNKey is the attribute Key conforming to the\n\t// \"aws.ecs.container.arn\" semantic conventions. It represents the Amazon\n\t// Resource Name (ARN) of an [ECS container instance].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9\"\n\t//\n\t// [ECS container instance]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html\n\tAWSECSContainerARNKey = attribute.Key(\"aws.ecs.container.arn\")\n\n\t// AWSECSLaunchtypeKey is the attribute Key conforming to the\n\t// \"aws.ecs.launchtype\" semantic conventions. It represents the [launch type]\n\t// for an ECS task.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t//\n\t// [launch type]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html\n\tAWSECSLaunchtypeKey = attribute.Key(\"aws.ecs.launchtype\")\n\n\t// AWSECSTaskARNKey is the attribute Key conforming to the \"aws.ecs.task.arn\"\n\t// semantic conventions. It represents the ARN of a running [ECS task].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b\",\n\t// \"arn:aws:ecs:us-west-1:123456789123:task/my-cluster/task-id/23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd\"\n\t//\n\t// [ECS task]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids\n\tAWSECSTaskARNKey = attribute.Key(\"aws.ecs.task.arn\")\n\n\t// AWSECSTaskFamilyKey is the attribute Key conforming to the\n\t// \"aws.ecs.task.family\" semantic conventions. It represents the family name of\n\t// the [ECS task definition] used to create the ECS task.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry-family\"\n\t//\n\t// [ECS task definition]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html\n\tAWSECSTaskFamilyKey = attribute.Key(\"aws.ecs.task.family\")\n\n\t// AWSECSTaskIDKey is the attribute Key conforming to the \"aws.ecs.task.id\"\n\t// semantic conventions. It represents the ID of a running ECS task. The ID MUST\n\t// be extracted from `task.arn`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"10838bed-421f-43ef-870a-f43feacbbb5b\",\n\t// \"23ebb8ac-c18f-46c6-8bbe-d55d0e37cfbd\"\n\tAWSECSTaskIDKey = attribute.Key(\"aws.ecs.task.id\")\n\n\t// AWSECSTaskRevisionKey is the attribute Key conforming to the\n\t// \"aws.ecs.task.revision\" semantic conventions. It represents the revision for\n\t// the task definition used to create the ECS task.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"8\", \"26\"\n\tAWSECSTaskRevisionKey = attribute.Key(\"aws.ecs.task.revision\")\n\n\t// AWSEKSClusterARNKey is the attribute Key conforming to the\n\t// \"aws.eks.cluster.arn\" semantic conventions. It represents the ARN of an EKS\n\t// cluster.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster\"\n\tAWSEKSClusterARNKey = attribute.Key(\"aws.eks.cluster.arn\")\n\n\t// AWSExtendedRequestIDKey is the attribute Key conforming to the\n\t// \"aws.extended_request_id\" semantic conventions. It represents the AWS\n\t// extended request ID as returned in the response header `x-amz-id-2`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"wzHcyEWfmOGDIE5QOhTAqFDoDWP3y8IUvpNINCwL9N4TEHbUw0/gZJ+VZTmCNCWR7fezEN3eCiQ=\"\n\tAWSExtendedRequestIDKey = attribute.Key(\"aws.extended_request_id\")\n\n\t// AWSKinesisStreamNameKey is the attribute Key conforming to the\n\t// \"aws.kinesis.stream_name\" semantic conventions. It represents the name of the\n\t// AWS Kinesis [stream] the request refers to. Corresponds to the\n\t// `--stream-name` parameter of the Kinesis [describe-stream] operation.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"some-stream-name\"\n\t//\n\t// [stream]: https://docs.aws.amazon.com/streams/latest/dev/introduction.html\n\t// [describe-stream]: https://docs.aws.amazon.com/cli/latest/reference/kinesis/describe-stream.html\n\tAWSKinesisStreamNameKey = attribute.Key(\"aws.kinesis.stream_name\")\n\n\t// AWSLambdaInvokedARNKey is the attribute Key conforming to the\n\t// \"aws.lambda.invoked_arn\" semantic conventions. It represents the full invoked\n\t// ARN as provided on the `Context` passed to the function (\n\t// `Lambda-Runtime-Invoked-Function-Arn` header on the\n\t// `/runtime/invocation/next` applicable).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"arn:aws:lambda:us-east-1:123456:function:myfunction:myalias\"\n\t// Note: This may be different from `cloud.resource_id` if an alias is involved.\n\tAWSLambdaInvokedARNKey = attribute.Key(\"aws.lambda.invoked_arn\")\n\n\t// AWSLambdaResourceMappingIDKey is the attribute Key conforming to the\n\t// \"aws.lambda.resource_mapping.id\" semantic conventions. It represents the UUID\n\t// of the [AWS Lambda EvenSource Mapping]. An event source is mapped to a lambda\n\t// function. It's contents are read by Lambda and used to trigger a function.\n\t// This isn't available in the lambda execution context or the lambda runtime\n\t// environtment. This is going to be populated by the AWS SDK for each language\n\t// when that UUID is present. Some of these operations are\n\t// Create/Delete/Get/List/Update EventSourceMapping.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"587ad24b-03b9-4413-8202-bbd56b36e5b7\"\n\t//\n\t// [AWS Lambda EvenSource Mapping]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html\n\tAWSLambdaResourceMappingIDKey = attribute.Key(\"aws.lambda.resource_mapping.id\")\n\n\t// AWSLogGroupARNsKey is the attribute Key conforming to the\n\t// \"aws.log.group.arns\" semantic conventions. It represents the Amazon Resource\n\t// Name(s) (ARN) of the AWS log group(s).\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*\"\n\t// Note: See the [log group ARN format documentation].\n\t//\n\t// [log group ARN format documentation]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format\n\tAWSLogGroupARNsKey = attribute.Key(\"aws.log.group.arns\")\n\n\t// AWSLogGroupNamesKey is the attribute Key conforming to the\n\t// \"aws.log.group.names\" semantic conventions. It represents the name(s) of the\n\t// AWS log group(s) an application is writing to.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/aws/lambda/my-function\", \"opentelemetry-service\"\n\t// Note: Multiple log groups must be supported for cases like multi-container\n\t// applications, where a single application has sidecar containers, and each\n\t// write to their own log group.\n\tAWSLogGroupNamesKey = attribute.Key(\"aws.log.group.names\")\n\n\t// AWSLogStreamARNsKey is the attribute Key conforming to the\n\t// \"aws.log.stream.arns\" semantic conventions. It represents the ARN(s) of the\n\t// AWS log stream(s).\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b\"\n\t// Note: See the [log stream ARN format documentation]. One log group can\n\t// contain several log streams, so these ARNs necessarily identify both a log\n\t// group and a log stream.\n\t//\n\t// [log stream ARN format documentation]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format\n\tAWSLogStreamARNsKey = attribute.Key(\"aws.log.stream.arns\")\n\n\t// AWSLogStreamNamesKey is the attribute Key conforming to the\n\t// \"aws.log.stream.names\" semantic conventions. It represents the name(s) of the\n\t// AWS log stream(s) an application is writing to.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"logs/main/10838bed-421f-43ef-870a-f43feacbbb5b\"\n\tAWSLogStreamNamesKey = attribute.Key(\"aws.log.stream.names\")\n\n\t// AWSRequestIDKey is the attribute Key conforming to the \"aws.request_id\"\n\t// semantic conventions. It represents the AWS request ID as returned in the\n\t// response headers `x-amzn-requestid`, `x-amzn-request-id` or\n\t// `x-amz-request-id`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"79b9da39-b7ae-508a-a6bc-864b2829c622\", \"C9ER4AJX75574TDJ\"\n\tAWSRequestIDKey = attribute.Key(\"aws.request_id\")\n\n\t// AWSS3BucketKey is the attribute Key conforming to the \"aws.s3.bucket\"\n\t// semantic conventions. It represents the S3 bucket name the request refers to.\n\t// Corresponds to the `--bucket` parameter of the [S3 API] operations.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"some-bucket-name\"\n\t// Note: The `bucket` attribute is applicable to all S3 operations that\n\t// reference a bucket, i.e. that require the bucket name as a mandatory\n\t// parameter.\n\t// This applies to almost all S3 operations except `list-buckets`.\n\t//\n\t// [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html\n\tAWSS3BucketKey = attribute.Key(\"aws.s3.bucket\")\n\n\t// AWSS3CopySourceKey is the attribute Key conforming to the\n\t// \"aws.s3.copy_source\" semantic conventions. It represents the source object\n\t// (in the form `bucket`/`key`) for the copy operation.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"someFile.yml\"\n\t// Note: The `copy_source` attribute applies to S3 copy operations and\n\t// corresponds to the `--copy-source` parameter\n\t// of the [copy-object operation within the S3 API].\n\t// This applies in particular to the following operations:\n\t//\n\t//   - [copy-object]\n\t//   - [upload-part-copy]\n\t//\n\t//\n\t// [copy-object operation within the S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html\n\t// [copy-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html\n\t// [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html\n\tAWSS3CopySourceKey = attribute.Key(\"aws.s3.copy_source\")\n\n\t// AWSS3DeleteKey is the attribute Key conforming to the \"aws.s3.delete\"\n\t// semantic conventions. It represents the delete request container that\n\t// specifies the objects to be deleted.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"Objects=[{Key=string,VersionId=string},{Key=string,VersionId=string}],Quiet=boolean\"\n\t// Note: The `delete` attribute is only applicable to the [delete-object]\n\t// operation.\n\t// The `delete` attribute corresponds to the `--delete` parameter of the\n\t// [delete-objects operation within the S3 API].\n\t//\n\t// [delete-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html\n\t// [delete-objects operation within the S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html\n\tAWSS3DeleteKey = attribute.Key(\"aws.s3.delete\")\n\n\t// AWSS3KeyKey is the attribute Key conforming to the \"aws.s3.key\" semantic\n\t// conventions. It represents the S3 object key the request refers to.\n\t// Corresponds to the `--key` parameter of the [S3 API] operations.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"someFile.yml\"\n\t// Note: The `key` attribute is applicable to all object-related S3 operations,\n\t// i.e. that require the object key as a mandatory parameter.\n\t// This applies in particular to the following operations:\n\t//\n\t//   - [copy-object]\n\t//   - [delete-object]\n\t//   - [get-object]\n\t//   - [head-object]\n\t//   - [put-object]\n\t//   - [restore-object]\n\t//   - [select-object-content]\n\t//   - [abort-multipart-upload]\n\t//   - [complete-multipart-upload]\n\t//   - [create-multipart-upload]\n\t//   - [list-parts]\n\t//   - [upload-part]\n\t//   - [upload-part-copy]\n\t//\n\t//\n\t// [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html\n\t// [copy-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html\n\t// [delete-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html\n\t// [get-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/get-object.html\n\t// [head-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/head-object.html\n\t// [put-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.html\n\t// [restore-object]: https://docs.aws.amazon.com/cli/latest/reference/s3api/restore-object.html\n\t// [select-object-content]: https://docs.aws.amazon.com/cli/latest/reference/s3api/select-object-content.html\n\t// [abort-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html\n\t// [complete-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html\n\t// [create-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/create-multipart-upload.html\n\t// [list-parts]: https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html\n\t// [upload-part]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html\n\t// [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html\n\tAWSS3KeyKey = attribute.Key(\"aws.s3.key\")\n\n\t// AWSS3PartNumberKey is the attribute Key conforming to the\n\t// \"aws.s3.part_number\" semantic conventions. It represents the part number of\n\t// the part being uploaded in a multipart-upload operation. This is a positive\n\t// integer between 1 and 10,000.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 3456\n\t// Note: The `part_number` attribute is only applicable to the [upload-part]\n\t// and [upload-part-copy] operations.\n\t// The `part_number` attribute corresponds to the `--part-number` parameter of\n\t// the\n\t// [upload-part operation within the S3 API].\n\t//\n\t// [upload-part]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html\n\t// [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html\n\t// [upload-part operation within the S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html\n\tAWSS3PartNumberKey = attribute.Key(\"aws.s3.part_number\")\n\n\t// AWSS3UploadIDKey is the attribute Key conforming to the \"aws.s3.upload_id\"\n\t// semantic conventions. It represents the upload ID that identifies the\n\t// multipart upload.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"dfRtDYWFbkRONycy.Yxwh66Yjlx.cph0gtNBtJ\"\n\t// Note: The `upload_id` attribute applies to S3 multipart-upload operations and\n\t// corresponds to the `--upload-id` parameter\n\t// of the [S3 API] multipart operations.\n\t// This applies in particular to the following operations:\n\t//\n\t//   - [abort-multipart-upload]\n\t//   - [complete-multipart-upload]\n\t//   - [list-parts]\n\t//   - [upload-part]\n\t//   - [upload-part-copy]\n\t//\n\t//\n\t// [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html\n\t// [abort-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html\n\t// [complete-multipart-upload]: https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html\n\t// [list-parts]: https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html\n\t// [upload-part]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html\n\t// [upload-part-copy]: https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html\n\tAWSS3UploadIDKey = attribute.Key(\"aws.s3.upload_id\")\n\n\t// AWSSecretsmanagerSecretARNKey is the attribute Key conforming to the\n\t// \"aws.secretsmanager.secret.arn\" semantic conventions. It represents the ARN\n\t// of the Secret stored in the Secrets Mangger.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"arn:aws:secretsmanager:us-east-1:123456789012:secret:SecretName-6RandomCharacters\"\n\tAWSSecretsmanagerSecretARNKey = attribute.Key(\"aws.secretsmanager.secret.arn\")\n\n\t// AWSSNSTopicARNKey is the attribute Key conforming to the \"aws.sns.topic.arn\"\n\t// semantic conventions. It represents the ARN of the AWS SNS Topic. An Amazon\n\t// SNS [topic] is a logical access point that acts as a communication channel.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"arn:aws:sns:us-east-1:123456789012:mystack-mytopic-NZJ5JSMVGFIE\"\n\t//\n\t// [topic]: https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html\n\tAWSSNSTopicARNKey = attribute.Key(\"aws.sns.topic.arn\")\n\n\t// AWSSQSQueueURLKey is the attribute Key conforming to the \"aws.sqs.queue.url\"\n\t// semantic conventions. It represents the URL of the AWS SQS Queue. It's a\n\t// unique identifier for a queue in Amazon Simple Queue Service (SQS) and is\n\t// used to access the queue and perform actions on it.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue\"\n\tAWSSQSQueueURLKey = attribute.Key(\"aws.sqs.queue.url\")\n\n\t// AWSStepFunctionsActivityARNKey is the attribute Key conforming to the\n\t// \"aws.step_functions.activity.arn\" semantic conventions. It represents the ARN\n\t// of the AWS Step Functions Activity.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"arn:aws:states:us-east-1:123456789012:activity:get-greeting\"\n\tAWSStepFunctionsActivityARNKey = attribute.Key(\"aws.step_functions.activity.arn\")\n\n\t// AWSStepFunctionsStateMachineARNKey is the attribute Key conforming to the\n\t// \"aws.step_functions.state_machine.arn\" semantic conventions. It represents\n\t// the ARN of the AWS Step Functions State Machine.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"arn:aws:states:us-east-1:123456789012:stateMachine:myStateMachine:1\"\n\tAWSStepFunctionsStateMachineARNKey = attribute.Key(\"aws.step_functions.state_machine.arn\")\n)\n\n// AWSBedrockGuardrailID returns an attribute KeyValue conforming to the\n// \"aws.bedrock.guardrail.id\" semantic conventions. It represents the unique\n// identifier of the AWS Bedrock Guardrail. A [guardrail] helps safeguard and\n// prevent unwanted behavior from model responses or user messages.\n//\n// [guardrail]: https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html\nfunc AWSBedrockGuardrailID(val string) attribute.KeyValue {\n\treturn AWSBedrockGuardrailIDKey.String(val)\n}\n\n// AWSBedrockKnowledgeBaseID returns an attribute KeyValue conforming to the\n// \"aws.bedrock.knowledge_base.id\" semantic conventions. It represents the unique\n// identifier of the AWS Bedrock Knowledge base. A [knowledge base] is a bank of\n// information that can be queried by models to generate more relevant responses\n// and augment prompts.\n//\n// [knowledge base]: https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base.html\nfunc AWSBedrockKnowledgeBaseID(val string) attribute.KeyValue {\n\treturn AWSBedrockKnowledgeBaseIDKey.String(val)\n}\n\n// AWSDynamoDBAttributeDefinitions returns an attribute KeyValue conforming to\n// the \"aws.dynamodb.attribute_definitions\" semantic conventions. It represents\n// the JSON-serialized value of each item in the `AttributeDefinitions` request\n// field.\nfunc AWSDynamoDBAttributeDefinitions(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBAttributeDefinitionsKey.StringSlice(val)\n}\n\n// AWSDynamoDBAttributesToGet returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.attributes_to_get\" semantic conventions. It represents the value\n// of the `AttributesToGet` request parameter.\nfunc AWSDynamoDBAttributesToGet(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBAttributesToGetKey.StringSlice(val)\n}\n\n// AWSDynamoDBConsistentRead returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.consistent_read\" semantic conventions. It represents the value\n// of the `ConsistentRead` request parameter.\nfunc AWSDynamoDBConsistentRead(val bool) attribute.KeyValue {\n\treturn AWSDynamoDBConsistentReadKey.Bool(val)\n}\n\n// AWSDynamoDBConsumedCapacity returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.consumed_capacity\" semantic conventions. It represents the\n// JSON-serialized value of each item in the `ConsumedCapacity` response field.\nfunc AWSDynamoDBConsumedCapacity(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBConsumedCapacityKey.StringSlice(val)\n}\n\n// AWSDynamoDBCount returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.count\" semantic conventions. It represents the value of the\n// `Count` response parameter.\nfunc AWSDynamoDBCount(val int) attribute.KeyValue {\n\treturn AWSDynamoDBCountKey.Int(val)\n}\n\n// AWSDynamoDBExclusiveStartTable returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.exclusive_start_table\" semantic conventions. It represents the\n// value of the `ExclusiveStartTableName` request parameter.\nfunc AWSDynamoDBExclusiveStartTable(val string) attribute.KeyValue {\n\treturn AWSDynamoDBExclusiveStartTableKey.String(val)\n}\n\n// AWSDynamoDBGlobalSecondaryIndexUpdates returns an attribute KeyValue\n// conforming to the \"aws.dynamodb.global_secondary_index_updates\" semantic\n// conventions. It represents the JSON-serialized value of each item in the\n// `GlobalSecondaryIndexUpdates` request field.\nfunc AWSDynamoDBGlobalSecondaryIndexUpdates(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBGlobalSecondaryIndexUpdatesKey.StringSlice(val)\n}\n\n// AWSDynamoDBGlobalSecondaryIndexes returns an attribute KeyValue conforming to\n// the \"aws.dynamodb.global_secondary_indexes\" semantic conventions. It\n// represents the JSON-serialized value of each item of the\n// `GlobalSecondaryIndexes` request field.\nfunc AWSDynamoDBGlobalSecondaryIndexes(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBGlobalSecondaryIndexesKey.StringSlice(val)\n}\n\n// AWSDynamoDBIndexName returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.index_name\" semantic conventions. It represents the value of the\n// `IndexName` request parameter.\nfunc AWSDynamoDBIndexName(val string) attribute.KeyValue {\n\treturn AWSDynamoDBIndexNameKey.String(val)\n}\n\n// AWSDynamoDBItemCollectionMetrics returns an attribute KeyValue conforming to\n// the \"aws.dynamodb.item_collection_metrics\" semantic conventions. It represents\n// the JSON-serialized value of the `ItemCollectionMetrics` response field.\nfunc AWSDynamoDBItemCollectionMetrics(val string) attribute.KeyValue {\n\treturn AWSDynamoDBItemCollectionMetricsKey.String(val)\n}\n\n// AWSDynamoDBLimit returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.limit\" semantic conventions. It represents the value of the\n// `Limit` request parameter.\nfunc AWSDynamoDBLimit(val int) attribute.KeyValue {\n\treturn AWSDynamoDBLimitKey.Int(val)\n}\n\n// AWSDynamoDBLocalSecondaryIndexes returns an attribute KeyValue conforming to\n// the \"aws.dynamodb.local_secondary_indexes\" semantic conventions. It represents\n// the JSON-serialized value of each item of the `LocalSecondaryIndexes` request\n// field.\nfunc AWSDynamoDBLocalSecondaryIndexes(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBLocalSecondaryIndexesKey.StringSlice(val)\n}\n\n// AWSDynamoDBProjection returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.projection\" semantic conventions. It represents the value of the\n// `ProjectionExpression` request parameter.\nfunc AWSDynamoDBProjection(val string) attribute.KeyValue {\n\treturn AWSDynamoDBProjectionKey.String(val)\n}\n\n// AWSDynamoDBProvisionedReadCapacity returns an attribute KeyValue conforming to\n// the \"aws.dynamodb.provisioned_read_capacity\" semantic conventions. It\n// represents the value of the `ProvisionedThroughput.ReadCapacityUnits` request\n// parameter.\nfunc AWSDynamoDBProvisionedReadCapacity(val float64) attribute.KeyValue {\n\treturn AWSDynamoDBProvisionedReadCapacityKey.Float64(val)\n}\n\n// AWSDynamoDBProvisionedWriteCapacity returns an attribute KeyValue conforming\n// to the \"aws.dynamodb.provisioned_write_capacity\" semantic conventions. It\n// represents the value of the `ProvisionedThroughput.WriteCapacityUnits` request\n// parameter.\nfunc AWSDynamoDBProvisionedWriteCapacity(val float64) attribute.KeyValue {\n\treturn AWSDynamoDBProvisionedWriteCapacityKey.Float64(val)\n}\n\n// AWSDynamoDBScanForward returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.scan_forward\" semantic conventions. It represents the value of\n// the `ScanIndexForward` request parameter.\nfunc AWSDynamoDBScanForward(val bool) attribute.KeyValue {\n\treturn AWSDynamoDBScanForwardKey.Bool(val)\n}\n\n// AWSDynamoDBScannedCount returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.scanned_count\" semantic conventions. It represents the value of\n// the `ScannedCount` response parameter.\nfunc AWSDynamoDBScannedCount(val int) attribute.KeyValue {\n\treturn AWSDynamoDBScannedCountKey.Int(val)\n}\n\n// AWSDynamoDBSegment returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.segment\" semantic conventions. It represents the value of the\n// `Segment` request parameter.\nfunc AWSDynamoDBSegment(val int) attribute.KeyValue {\n\treturn AWSDynamoDBSegmentKey.Int(val)\n}\n\n// AWSDynamoDBSelect returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.select\" semantic conventions. It represents the value of the\n// `Select` request parameter.\nfunc AWSDynamoDBSelect(val string) attribute.KeyValue {\n\treturn AWSDynamoDBSelectKey.String(val)\n}\n\n// AWSDynamoDBTableCount returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.table_count\" semantic conventions. It represents the number of\n// items in the `TableNames` response parameter.\nfunc AWSDynamoDBTableCount(val int) attribute.KeyValue {\n\treturn AWSDynamoDBTableCountKey.Int(val)\n}\n\n// AWSDynamoDBTableNames returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.table_names\" semantic conventions. It represents the keys in the\n// `RequestItems` object field.\nfunc AWSDynamoDBTableNames(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBTableNamesKey.StringSlice(val)\n}\n\n// AWSDynamoDBTotalSegments returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.total_segments\" semantic conventions. It represents the value of\n// the `TotalSegments` request parameter.\nfunc AWSDynamoDBTotalSegments(val int) attribute.KeyValue {\n\treturn AWSDynamoDBTotalSegmentsKey.Int(val)\n}\n\n// AWSECSClusterARN returns an attribute KeyValue conforming to the\n// \"aws.ecs.cluster.arn\" semantic conventions. It represents the ARN of an\n// [ECS cluster].\n//\n// [ECS cluster]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html\nfunc AWSECSClusterARN(val string) attribute.KeyValue {\n\treturn AWSECSClusterARNKey.String(val)\n}\n\n// AWSECSContainerARN returns an attribute KeyValue conforming to the\n// \"aws.ecs.container.arn\" semantic conventions. It represents the Amazon\n// Resource Name (ARN) of an [ECS container instance].\n//\n// [ECS container instance]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html\nfunc AWSECSContainerARN(val string) attribute.KeyValue {\n\treturn AWSECSContainerARNKey.String(val)\n}\n\n// AWSECSTaskARN returns an attribute KeyValue conforming to the\n// \"aws.ecs.task.arn\" semantic conventions. It represents the ARN of a running\n// [ECS task].\n//\n// [ECS task]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids\nfunc AWSECSTaskARN(val string) attribute.KeyValue {\n\treturn AWSECSTaskARNKey.String(val)\n}\n\n// AWSECSTaskFamily returns an attribute KeyValue conforming to the\n// \"aws.ecs.task.family\" semantic conventions. It represents the family name of\n// the [ECS task definition] used to create the ECS task.\n//\n// [ECS task definition]: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html\nfunc AWSECSTaskFamily(val string) attribute.KeyValue {\n\treturn AWSECSTaskFamilyKey.String(val)\n}\n\n// AWSECSTaskID returns an attribute KeyValue conforming to the \"aws.ecs.task.id\"\n// semantic conventions. It represents the ID of a running ECS task. The ID MUST\n// be extracted from `task.arn`.\nfunc AWSECSTaskID(val string) attribute.KeyValue {\n\treturn AWSECSTaskIDKey.String(val)\n}\n\n// AWSECSTaskRevision returns an attribute KeyValue conforming to the\n// \"aws.ecs.task.revision\" semantic conventions. It represents the revision for\n// the task definition used to create the ECS task.\nfunc AWSECSTaskRevision(val string) attribute.KeyValue {\n\treturn AWSECSTaskRevisionKey.String(val)\n}\n\n// AWSEKSClusterARN returns an attribute KeyValue conforming to the\n// \"aws.eks.cluster.arn\" semantic conventions. It represents the ARN of an EKS\n// cluster.\nfunc AWSEKSClusterARN(val string) attribute.KeyValue {\n\treturn AWSEKSClusterARNKey.String(val)\n}\n\n// AWSExtendedRequestID returns an attribute KeyValue conforming to the\n// \"aws.extended_request_id\" semantic conventions. It represents the AWS extended\n// request ID as returned in the response header `x-amz-id-2`.\nfunc AWSExtendedRequestID(val string) attribute.KeyValue {\n\treturn AWSExtendedRequestIDKey.String(val)\n}\n\n// AWSKinesisStreamName returns an attribute KeyValue conforming to the\n// \"aws.kinesis.stream_name\" semantic conventions. It represents the name of the\n// AWS Kinesis [stream] the request refers to. Corresponds to the `--stream-name`\n//  parameter of the Kinesis [describe-stream] operation.\n//\n// [stream]: https://docs.aws.amazon.com/streams/latest/dev/introduction.html\n// [describe-stream]: https://docs.aws.amazon.com/cli/latest/reference/kinesis/describe-stream.html\nfunc AWSKinesisStreamName(val string) attribute.KeyValue {\n\treturn AWSKinesisStreamNameKey.String(val)\n}\n\n// AWSLambdaInvokedARN returns an attribute KeyValue conforming to the\n// \"aws.lambda.invoked_arn\" semantic conventions. It represents the full invoked\n// ARN as provided on the `Context` passed to the function (\n// `Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next`\n//  applicable).\nfunc AWSLambdaInvokedARN(val string) attribute.KeyValue {\n\treturn AWSLambdaInvokedARNKey.String(val)\n}\n\n// AWSLambdaResourceMappingID returns an attribute KeyValue conforming to the\n// \"aws.lambda.resource_mapping.id\" semantic conventions. It represents the UUID\n// of the [AWS Lambda EvenSource Mapping]. An event source is mapped to a lambda\n// function. It's contents are read by Lambda and used to trigger a function.\n// This isn't available in the lambda execution context or the lambda runtime\n// environtment. This is going to be populated by the AWS SDK for each language\n// when that UUID is present. Some of these operations are\n// Create/Delete/Get/List/Update EventSourceMapping.\n//\n// [AWS Lambda EvenSource Mapping]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html\nfunc AWSLambdaResourceMappingID(val string) attribute.KeyValue {\n\treturn AWSLambdaResourceMappingIDKey.String(val)\n}\n\n// AWSLogGroupARNs returns an attribute KeyValue conforming to the\n// \"aws.log.group.arns\" semantic conventions. It represents the Amazon Resource\n// Name(s) (ARN) of the AWS log group(s).\nfunc AWSLogGroupARNs(val ...string) attribute.KeyValue {\n\treturn AWSLogGroupARNsKey.StringSlice(val)\n}\n\n// AWSLogGroupNames returns an attribute KeyValue conforming to the\n// \"aws.log.group.names\" semantic conventions. It represents the name(s) of the\n// AWS log group(s) an application is writing to.\nfunc AWSLogGroupNames(val ...string) attribute.KeyValue {\n\treturn AWSLogGroupNamesKey.StringSlice(val)\n}\n\n// AWSLogStreamARNs returns an attribute KeyValue conforming to the\n// \"aws.log.stream.arns\" semantic conventions. It represents the ARN(s) of the\n// AWS log stream(s).\nfunc AWSLogStreamARNs(val ...string) attribute.KeyValue {\n\treturn AWSLogStreamARNsKey.StringSlice(val)\n}\n\n// AWSLogStreamNames returns an attribute KeyValue conforming to the\n// \"aws.log.stream.names\" semantic conventions. It represents the name(s) of the\n// AWS log stream(s) an application is writing to.\nfunc AWSLogStreamNames(val ...string) attribute.KeyValue {\n\treturn AWSLogStreamNamesKey.StringSlice(val)\n}\n\n// AWSRequestID returns an attribute KeyValue conforming to the \"aws.request_id\"\n// semantic conventions. It represents the AWS request ID as returned in the\n// response headers `x-amzn-requestid`, `x-amzn-request-id` or `x-amz-request-id`\n// .\nfunc AWSRequestID(val string) attribute.KeyValue {\n\treturn AWSRequestIDKey.String(val)\n}\n\n// AWSS3Bucket returns an attribute KeyValue conforming to the \"aws.s3.bucket\"\n// semantic conventions. It represents the S3 bucket name the request refers to.\n// Corresponds to the `--bucket` parameter of the [S3 API] operations.\n//\n// [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html\nfunc AWSS3Bucket(val string) attribute.KeyValue {\n\treturn AWSS3BucketKey.String(val)\n}\n\n// AWSS3CopySource returns an attribute KeyValue conforming to the\n// \"aws.s3.copy_source\" semantic conventions. It represents the source object (in\n// the form `bucket`/`key`) for the copy operation.\nfunc AWSS3CopySource(val string) attribute.KeyValue {\n\treturn AWSS3CopySourceKey.String(val)\n}\n\n// AWSS3Delete returns an attribute KeyValue conforming to the \"aws.s3.delete\"\n// semantic conventions. It represents the delete request container that\n// specifies the objects to be deleted.\nfunc AWSS3Delete(val string) attribute.KeyValue {\n\treturn AWSS3DeleteKey.String(val)\n}\n\n// AWSS3Key returns an attribute KeyValue conforming to the \"aws.s3.key\" semantic\n// conventions. It represents the S3 object key the request refers to.\n// Corresponds to the `--key` parameter of the [S3 API] operations.\n//\n// [S3 API]: https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html\nfunc AWSS3Key(val string) attribute.KeyValue {\n\treturn AWSS3KeyKey.String(val)\n}\n\n// AWSS3PartNumber returns an attribute KeyValue conforming to the\n// \"aws.s3.part_number\" semantic conventions. It represents the part number of\n// the part being uploaded in a multipart-upload operation. This is a positive\n// integer between 1 and 10,000.\nfunc AWSS3PartNumber(val int) attribute.KeyValue {\n\treturn AWSS3PartNumberKey.Int(val)\n}\n\n// AWSS3UploadID returns an attribute KeyValue conforming to the\n// \"aws.s3.upload_id\" semantic conventions. It represents the upload ID that\n// identifies the multipart upload.\nfunc AWSS3UploadID(val string) attribute.KeyValue {\n\treturn AWSS3UploadIDKey.String(val)\n}\n\n// AWSSecretsmanagerSecretARN returns an attribute KeyValue conforming to the\n// \"aws.secretsmanager.secret.arn\" semantic conventions. It represents the ARN of\n// the Secret stored in the Secrets Mangger.\nfunc AWSSecretsmanagerSecretARN(val string) attribute.KeyValue {\n\treturn AWSSecretsmanagerSecretARNKey.String(val)\n}\n\n// AWSSNSTopicARN returns an attribute KeyValue conforming to the\n// \"aws.sns.topic.arn\" semantic conventions. It represents the ARN of the AWS SNS\n// Topic. An Amazon SNS [topic] is a logical access point that acts as a\n// communication channel.\n//\n// [topic]: https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html\nfunc AWSSNSTopicARN(val string) attribute.KeyValue {\n\treturn AWSSNSTopicARNKey.String(val)\n}\n\n// AWSSQSQueueURL returns an attribute KeyValue conforming to the\n// \"aws.sqs.queue.url\" semantic conventions. It represents the URL of the AWS SQS\n// Queue. It's a unique identifier for a queue in Amazon Simple Queue Service\n// (SQS) and is used to access the queue and perform actions on it.\nfunc AWSSQSQueueURL(val string) attribute.KeyValue {\n\treturn AWSSQSQueueURLKey.String(val)\n}\n\n// AWSStepFunctionsActivityARN returns an attribute KeyValue conforming to the\n// \"aws.step_functions.activity.arn\" semantic conventions. It represents the ARN\n// of the AWS Step Functions Activity.\nfunc AWSStepFunctionsActivityARN(val string) attribute.KeyValue {\n\treturn AWSStepFunctionsActivityARNKey.String(val)\n}\n\n// AWSStepFunctionsStateMachineARN returns an attribute KeyValue conforming to\n// the \"aws.step_functions.state_machine.arn\" semantic conventions. It represents\n// the ARN of the AWS Step Functions State Machine.\nfunc AWSStepFunctionsStateMachineARN(val string) attribute.KeyValue {\n\treturn AWSStepFunctionsStateMachineARNKey.String(val)\n}\n\n// Enum values for aws.ecs.launchtype\nvar (\n\t// Amazon EC2\n\t// Stability: development\n\tAWSECSLaunchtypeEC2 = AWSECSLaunchtypeKey.String(\"ec2\")\n\t// Amazon Fargate\n\t// Stability: development\n\tAWSECSLaunchtypeFargate = AWSECSLaunchtypeKey.String(\"fargate\")\n)\n\n// Namespace: azure\nconst (\n\t// AzureClientIDKey is the attribute Key conforming to the \"azure.client.id\"\n\t// semantic conventions. It represents the unique identifier of the client\n\t// instance.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"3ba4827d-4422-483f-b59f-85b74211c11d\", \"storage-client-1\"\n\tAzureClientIDKey = attribute.Key(\"azure.client.id\")\n\n\t// AzureCosmosDBConnectionModeKey is the attribute Key conforming to the\n\t// \"azure.cosmosdb.connection.mode\" semantic conventions. It represents the\n\t// cosmos client connection mode.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tAzureCosmosDBConnectionModeKey = attribute.Key(\"azure.cosmosdb.connection.mode\")\n\n\t// AzureCosmosDBConsistencyLevelKey is the attribute Key conforming to the\n\t// \"azure.cosmosdb.consistency.level\" semantic conventions. It represents the\n\t// account or request [consistency level].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Eventual\", \"ConsistentPrefix\", \"BoundedStaleness\", \"Strong\",\n\t// \"Session\"\n\t//\n\t// [consistency level]: https://learn.microsoft.com/azure/cosmos-db/consistency-levels\n\tAzureCosmosDBConsistencyLevelKey = attribute.Key(\"azure.cosmosdb.consistency.level\")\n\n\t// AzureCosmosDBOperationContactedRegionsKey is the attribute Key conforming to\n\t// the \"azure.cosmosdb.operation.contacted_regions\" semantic conventions. It\n\t// represents the list of regions contacted during operation in the order that\n\t// they were contacted. If there is more than one region listed, it indicates\n\t// that the operation was performed on multiple regions i.e. cross-regional\n\t// call.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"North Central US\", \"Australia East\", \"Australia Southeast\"\n\t// Note: Region name matches the format of `displayName` in [Azure Location API]\n\t//\n\t// [Azure Location API]: https://learn.microsoft.com/rest/api/resources/subscriptions/list-locations\n\tAzureCosmosDBOperationContactedRegionsKey = attribute.Key(\"azure.cosmosdb.operation.contacted_regions\")\n\n\t// AzureCosmosDBOperationRequestChargeKey is the attribute Key conforming to the\n\t// \"azure.cosmosdb.operation.request_charge\" semantic conventions. It represents\n\t// the number of request units consumed by the operation.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 46.18, 1.0\n\tAzureCosmosDBOperationRequestChargeKey = attribute.Key(\"azure.cosmosdb.operation.request_charge\")\n\n\t// AzureCosmosDBRequestBodySizeKey is the attribute Key conforming to the\n\t// \"azure.cosmosdb.request.body.size\" semantic conventions. It represents the\n\t// request payload size in bytes.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tAzureCosmosDBRequestBodySizeKey = attribute.Key(\"azure.cosmosdb.request.body.size\")\n\n\t// AzureCosmosDBResponseSubStatusCodeKey is the attribute Key conforming to the\n\t// \"azure.cosmosdb.response.sub_status_code\" semantic conventions. It represents\n\t// the cosmos DB sub status code.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1000, 1002\n\tAzureCosmosDBResponseSubStatusCodeKey = attribute.Key(\"azure.cosmosdb.response.sub_status_code\")\n\n\t// AzureResourceProviderNamespaceKey is the attribute Key conforming to the\n\t// \"azure.resource_provider.namespace\" semantic conventions. It represents the\n\t// [Azure Resource Provider Namespace] as recognized by the client.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Microsoft.Storage\", \"Microsoft.KeyVault\", \"Microsoft.ServiceBus\"\n\t//\n\t// [Azure Resource Provider Namespace]: https://learn.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers\n\tAzureResourceProviderNamespaceKey = attribute.Key(\"azure.resource_provider.namespace\")\n\n\t// AzureServiceRequestIDKey is the attribute Key conforming to the\n\t// \"azure.service.request.id\" semantic conventions. It represents the unique\n\t// identifier of the service request. It's generated by the Azure service and\n\t// returned with the response.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"00000000-0000-0000-0000-000000000000\"\n\tAzureServiceRequestIDKey = attribute.Key(\"azure.service.request.id\")\n)\n\n// AzureClientID returns an attribute KeyValue conforming to the\n// \"azure.client.id\" semantic conventions. It represents the unique identifier of\n// the client instance.\nfunc AzureClientID(val string) attribute.KeyValue {\n\treturn AzureClientIDKey.String(val)\n}\n\n// AzureCosmosDBOperationContactedRegions returns an attribute KeyValue\n// conforming to the \"azure.cosmosdb.operation.contacted_regions\" semantic\n// conventions. It represents the list of regions contacted during operation in\n// the order that they were contacted. If there is more than one region listed,\n// it indicates that the operation was performed on multiple regions i.e.\n// cross-regional call.\nfunc AzureCosmosDBOperationContactedRegions(val ...string) attribute.KeyValue {\n\treturn AzureCosmosDBOperationContactedRegionsKey.StringSlice(val)\n}\n\n// AzureCosmosDBOperationRequestCharge returns an attribute KeyValue conforming\n// to the \"azure.cosmosdb.operation.request_charge\" semantic conventions. It\n// represents the number of request units consumed by the operation.\nfunc AzureCosmosDBOperationRequestCharge(val float64) attribute.KeyValue {\n\treturn AzureCosmosDBOperationRequestChargeKey.Float64(val)\n}\n\n// AzureCosmosDBRequestBodySize returns an attribute KeyValue conforming to the\n// \"azure.cosmosdb.request.body.size\" semantic conventions. It represents the\n// request payload size in bytes.\nfunc AzureCosmosDBRequestBodySize(val int) attribute.KeyValue {\n\treturn AzureCosmosDBRequestBodySizeKey.Int(val)\n}\n\n// AzureCosmosDBResponseSubStatusCode returns an attribute KeyValue conforming to\n// the \"azure.cosmosdb.response.sub_status_code\" semantic conventions. It\n// represents the cosmos DB sub status code.\nfunc AzureCosmosDBResponseSubStatusCode(val int) attribute.KeyValue {\n\treturn AzureCosmosDBResponseSubStatusCodeKey.Int(val)\n}\n\n// AzureResourceProviderNamespace returns an attribute KeyValue conforming to the\n// \"azure.resource_provider.namespace\" semantic conventions. It represents the\n// [Azure Resource Provider Namespace] as recognized by the client.\n//\n// [Azure Resource Provider Namespace]: https://learn.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers\nfunc AzureResourceProviderNamespace(val string) attribute.KeyValue {\n\treturn AzureResourceProviderNamespaceKey.String(val)\n}\n\n// AzureServiceRequestID returns an attribute KeyValue conforming to the\n// \"azure.service.request.id\" semantic conventions. It represents the unique\n// identifier of the service request. It's generated by the Azure service and\n// returned with the response.\nfunc AzureServiceRequestID(val string) attribute.KeyValue {\n\treturn AzureServiceRequestIDKey.String(val)\n}\n\n// Enum values for azure.cosmosdb.connection.mode\nvar (\n\t// Gateway (HTTP) connection.\n\t// Stability: development\n\tAzureCosmosDBConnectionModeGateway = AzureCosmosDBConnectionModeKey.String(\"gateway\")\n\t// Direct connection.\n\t// Stability: development\n\tAzureCosmosDBConnectionModeDirect = AzureCosmosDBConnectionModeKey.String(\"direct\")\n)\n\n// Enum values for azure.cosmosdb.consistency.level\nvar (\n\t// Strong\n\t// Stability: development\n\tAzureCosmosDBConsistencyLevelStrong = AzureCosmosDBConsistencyLevelKey.String(\"Strong\")\n\t// Bounded Staleness\n\t// Stability: development\n\tAzureCosmosDBConsistencyLevelBoundedStaleness = AzureCosmosDBConsistencyLevelKey.String(\"BoundedStaleness\")\n\t// Session\n\t// Stability: development\n\tAzureCosmosDBConsistencyLevelSession = AzureCosmosDBConsistencyLevelKey.String(\"Session\")\n\t// Eventual\n\t// Stability: development\n\tAzureCosmosDBConsistencyLevelEventual = AzureCosmosDBConsistencyLevelKey.String(\"Eventual\")\n\t// Consistent Prefix\n\t// Stability: development\n\tAzureCosmosDBConsistencyLevelConsistentPrefix = AzureCosmosDBConsistencyLevelKey.String(\"ConsistentPrefix\")\n)\n\n// Namespace: browser\nconst (\n\t// BrowserBrandsKey is the attribute Key conforming to the \"browser.brands\"\n\t// semantic conventions. It represents the array of brand name and version\n\t// separated by a space.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \" Not A;Brand 99\", \"Chromium 99\", \"Chrome 99\"\n\t// Note: This value is intended to be taken from the [UA client hints API] (\n\t// `navigator.userAgentData.brands`).\n\t//\n\t// [UA client hints API]: https://wicg.github.io/ua-client-hints/#interface\n\tBrowserBrandsKey = attribute.Key(\"browser.brands\")\n\n\t// BrowserLanguageKey is the attribute Key conforming to the \"browser.language\"\n\t// semantic conventions. It represents the preferred language of the user using\n\t// the browser.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"en\", \"en-US\", \"fr\", \"fr-FR\"\n\t// Note: This value is intended to be taken from the Navigator API\n\t// `navigator.language`.\n\tBrowserLanguageKey = attribute.Key(\"browser.language\")\n\n\t// BrowserMobileKey is the attribute Key conforming to the \"browser.mobile\"\n\t// semantic conventions. It represents a boolean that is true if the browser is\n\t// running on a mobile device.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: This value is intended to be taken from the [UA client hints API] (\n\t// `navigator.userAgentData.mobile`). If unavailable, this attribute SHOULD be\n\t// left unset.\n\t//\n\t// [UA client hints API]: https://wicg.github.io/ua-client-hints/#interface\n\tBrowserMobileKey = attribute.Key(\"browser.mobile\")\n\n\t// BrowserPlatformKey is the attribute Key conforming to the \"browser.platform\"\n\t// semantic conventions. It represents the platform on which the browser is\n\t// running.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Windows\", \"macOS\", \"Android\"\n\t// Note: This value is intended to be taken from the [UA client hints API] (\n\t// `navigator.userAgentData.platform`). If unavailable, the legacy\n\t// `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD\n\t// be left unset in order for the values to be consistent.\n\t// The list of possible values is defined in the\n\t// [W3C User-Agent Client Hints specification]. Note that some (but not all) of\n\t// these values can overlap with values in the\n\t// [`os.type` and `os.name` attributes]. However, for consistency, the values in\n\t// the `browser.platform` attribute should capture the exact value that the user\n\t// agent provides.\n\t//\n\t// [UA client hints API]: https://wicg.github.io/ua-client-hints/#interface\n\t// [W3C User-Agent Client Hints specification]: https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform\n\t// [`os.type` and `os.name` attributes]: ./os.md\n\tBrowserPlatformKey = attribute.Key(\"browser.platform\")\n)\n\n// BrowserBrands returns an attribute KeyValue conforming to the \"browser.brands\"\n// semantic conventions. It represents the array of brand name and version\n// separated by a space.\nfunc BrowserBrands(val ...string) attribute.KeyValue {\n\treturn BrowserBrandsKey.StringSlice(val)\n}\n\n// BrowserLanguage returns an attribute KeyValue conforming to the\n// \"browser.language\" semantic conventions. It represents the preferred language\n// of the user using the browser.\nfunc BrowserLanguage(val string) attribute.KeyValue {\n\treturn BrowserLanguageKey.String(val)\n}\n\n// BrowserMobile returns an attribute KeyValue conforming to the \"browser.mobile\"\n// semantic conventions. It represents a boolean that is true if the browser is\n// running on a mobile device.\nfunc BrowserMobile(val bool) attribute.KeyValue {\n\treturn BrowserMobileKey.Bool(val)\n}\n\n// BrowserPlatform returns an attribute KeyValue conforming to the\n// \"browser.platform\" semantic conventions. It represents the platform on which\n// the browser is running.\nfunc BrowserPlatform(val string) attribute.KeyValue {\n\treturn BrowserPlatformKey.String(val)\n}\n\n// Namespace: cassandra\nconst (\n\t// CassandraConsistencyLevelKey is the attribute Key conforming to the\n\t// \"cassandra.consistency.level\" semantic conventions. It represents the\n\t// consistency level of the query. Based on consistency values from [CQL].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t//\n\t// [CQL]: https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html\n\tCassandraConsistencyLevelKey = attribute.Key(\"cassandra.consistency.level\")\n\n\t// CassandraCoordinatorDCKey is the attribute Key conforming to the\n\t// \"cassandra.coordinator.dc\" semantic conventions. It represents the data\n\t// center of the coordinating node for a query.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: us-west-2\n\tCassandraCoordinatorDCKey = attribute.Key(\"cassandra.coordinator.dc\")\n\n\t// CassandraCoordinatorIDKey is the attribute Key conforming to the\n\t// \"cassandra.coordinator.id\" semantic conventions. It represents the ID of the\n\t// coordinating node for a query.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: be13faa2-8574-4d71-926d-27f16cf8a7af\n\tCassandraCoordinatorIDKey = attribute.Key(\"cassandra.coordinator.id\")\n\n\t// CassandraPageSizeKey is the attribute Key conforming to the\n\t// \"cassandra.page.size\" semantic conventions. It represents the fetch size used\n\t// for paging, i.e. how many rows will be returned at once.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 5000\n\tCassandraPageSizeKey = attribute.Key(\"cassandra.page.size\")\n\n\t// CassandraQueryIdempotentKey is the attribute Key conforming to the\n\t// \"cassandra.query.idempotent\" semantic conventions. It represents the whether\n\t// or not the query is idempotent.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tCassandraQueryIdempotentKey = attribute.Key(\"cassandra.query.idempotent\")\n\n\t// CassandraSpeculativeExecutionCountKey is the attribute Key conforming to the\n\t// \"cassandra.speculative_execution.count\" semantic conventions. It represents\n\t// the number of times a query was speculatively executed. Not set or `0` if the\n\t// query was not executed speculatively.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0, 2\n\tCassandraSpeculativeExecutionCountKey = attribute.Key(\"cassandra.speculative_execution.count\")\n)\n\n// CassandraCoordinatorDC returns an attribute KeyValue conforming to the\n// \"cassandra.coordinator.dc\" semantic conventions. It represents the data center\n// of the coordinating node for a query.\nfunc CassandraCoordinatorDC(val string) attribute.KeyValue {\n\treturn CassandraCoordinatorDCKey.String(val)\n}\n\n// CassandraCoordinatorID returns an attribute KeyValue conforming to the\n// \"cassandra.coordinator.id\" semantic conventions. It represents the ID of the\n// coordinating node for a query.\nfunc CassandraCoordinatorID(val string) attribute.KeyValue {\n\treturn CassandraCoordinatorIDKey.String(val)\n}\n\n// CassandraPageSize returns an attribute KeyValue conforming to the\n// \"cassandra.page.size\" semantic conventions. It represents the fetch size used\n// for paging, i.e. how many rows will be returned at once.\nfunc CassandraPageSize(val int) attribute.KeyValue {\n\treturn CassandraPageSizeKey.Int(val)\n}\n\n// CassandraQueryIdempotent returns an attribute KeyValue conforming to the\n// \"cassandra.query.idempotent\" semantic conventions. It represents the whether\n// or not the query is idempotent.\nfunc CassandraQueryIdempotent(val bool) attribute.KeyValue {\n\treturn CassandraQueryIdempotentKey.Bool(val)\n}\n\n// CassandraSpeculativeExecutionCount returns an attribute KeyValue conforming to\n// the \"cassandra.speculative_execution.count\" semantic conventions. It\n// represents the number of times a query was speculatively executed. Not set or\n// `0` if the query was not executed speculatively.\nfunc CassandraSpeculativeExecutionCount(val int) attribute.KeyValue {\n\treturn CassandraSpeculativeExecutionCountKey.Int(val)\n}\n\n// Enum values for cassandra.consistency.level\nvar (\n\t// All\n\t// Stability: development\n\tCassandraConsistencyLevelAll = CassandraConsistencyLevelKey.String(\"all\")\n\t// Each Quorum\n\t// Stability: development\n\tCassandraConsistencyLevelEachQuorum = CassandraConsistencyLevelKey.String(\"each_quorum\")\n\t// Quorum\n\t// Stability: development\n\tCassandraConsistencyLevelQuorum = CassandraConsistencyLevelKey.String(\"quorum\")\n\t// Local Quorum\n\t// Stability: development\n\tCassandraConsistencyLevelLocalQuorum = CassandraConsistencyLevelKey.String(\"local_quorum\")\n\t// One\n\t// Stability: development\n\tCassandraConsistencyLevelOne = CassandraConsistencyLevelKey.String(\"one\")\n\t// Two\n\t// Stability: development\n\tCassandraConsistencyLevelTwo = CassandraConsistencyLevelKey.String(\"two\")\n\t// Three\n\t// Stability: development\n\tCassandraConsistencyLevelThree = CassandraConsistencyLevelKey.String(\"three\")\n\t// Local One\n\t// Stability: development\n\tCassandraConsistencyLevelLocalOne = CassandraConsistencyLevelKey.String(\"local_one\")\n\t// Any\n\t// Stability: development\n\tCassandraConsistencyLevelAny = CassandraConsistencyLevelKey.String(\"any\")\n\t// Serial\n\t// Stability: development\n\tCassandraConsistencyLevelSerial = CassandraConsistencyLevelKey.String(\"serial\")\n\t// Local Serial\n\t// Stability: development\n\tCassandraConsistencyLevelLocalSerial = CassandraConsistencyLevelKey.String(\"local_serial\")\n)\n\n// Namespace: cicd\nconst (\n\t// CICDPipelineActionNameKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.action.name\" semantic conventions. It represents the kind of\n\t// action a pipeline run is performing.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"BUILD\", \"RUN\", \"SYNC\"\n\tCICDPipelineActionNameKey = attribute.Key(\"cicd.pipeline.action.name\")\n\n\t// CICDPipelineNameKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.name\" semantic conventions. It represents the human readable\n\t// name of the pipeline within a CI/CD system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Build and Test\", \"Lint\", \"Deploy Go Project\",\n\t// \"deploy_to_environment\"\n\tCICDPipelineNameKey = attribute.Key(\"cicd.pipeline.name\")\n\n\t// CICDPipelineResultKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.result\" semantic conventions. It represents the result of a\n\t// pipeline run.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"success\", \"failure\", \"timeout\", \"skipped\"\n\tCICDPipelineResultKey = attribute.Key(\"cicd.pipeline.result\")\n\n\t// CICDPipelineRunIDKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.run.id\" semantic conventions. It represents the unique\n\t// identifier of a pipeline run within a CI/CD system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"120912\"\n\tCICDPipelineRunIDKey = attribute.Key(\"cicd.pipeline.run.id\")\n\n\t// CICDPipelineRunStateKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.run.state\" semantic conventions. It represents the pipeline\n\t// run goes through these states during its lifecycle.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"pending\", \"executing\", \"finalizing\"\n\tCICDPipelineRunStateKey = attribute.Key(\"cicd.pipeline.run.state\")\n\n\t// CICDPipelineRunURLFullKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.run.url.full\" semantic conventions. It represents the [URL] of\n\t// the pipeline run, providing the complete address in order to locate and\n\t// identify the pipeline run.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"https://github.com/open-telemetry/semantic-conventions/actions/runs/9753949763?pr=1075\"\n\t//\n\t// [URL]: https://wikipedia.org/wiki/URL\n\tCICDPipelineRunURLFullKey = attribute.Key(\"cicd.pipeline.run.url.full\")\n\n\t// CICDPipelineTaskNameKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.task.name\" semantic conventions. It represents the human\n\t// readable name of a task within a pipeline. Task here most closely aligns with\n\t// a [computing process] in a pipeline. Other terms for tasks include commands,\n\t// steps, and procedures.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Run GoLang Linter\", \"Go Build\", \"go-test\", \"deploy_binary\"\n\t//\n\t// [computing process]: https://wikipedia.org/wiki/Pipeline_(computing)\n\tCICDPipelineTaskNameKey = attribute.Key(\"cicd.pipeline.task.name\")\n\n\t// CICDPipelineTaskRunIDKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.task.run.id\" semantic conventions. It represents the unique\n\t// identifier of a task run within a pipeline.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"12097\"\n\tCICDPipelineTaskRunIDKey = attribute.Key(\"cicd.pipeline.task.run.id\")\n\n\t// CICDPipelineTaskRunResultKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.task.run.result\" semantic conventions. It represents the\n\t// result of a task run.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"success\", \"failure\", \"timeout\", \"skipped\"\n\tCICDPipelineTaskRunResultKey = attribute.Key(\"cicd.pipeline.task.run.result\")\n\n\t// CICDPipelineTaskRunURLFullKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.task.run.url.full\" semantic conventions. It represents the\n\t// [URL] of the pipeline task run, providing the complete address in order to\n\t// locate and identify the pipeline task run.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"https://github.com/open-telemetry/semantic-conventions/actions/runs/9753949763/job/26920038674?pr=1075\"\n\t//\n\t// [URL]: https://wikipedia.org/wiki/URL\n\tCICDPipelineTaskRunURLFullKey = attribute.Key(\"cicd.pipeline.task.run.url.full\")\n\n\t// CICDPipelineTaskTypeKey is the attribute Key conforming to the\n\t// \"cicd.pipeline.task.type\" semantic conventions. It represents the type of the\n\t// task within a pipeline.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"build\", \"test\", \"deploy\"\n\tCICDPipelineTaskTypeKey = attribute.Key(\"cicd.pipeline.task.type\")\n\n\t// CICDSystemComponentKey is the attribute Key conforming to the\n\t// \"cicd.system.component\" semantic conventions. It represents the name of a\n\t// component of the CICD system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"controller\", \"scheduler\", \"agent\"\n\tCICDSystemComponentKey = attribute.Key(\"cicd.system.component\")\n\n\t// CICDWorkerIDKey is the attribute Key conforming to the \"cicd.worker.id\"\n\t// semantic conventions. It represents the unique identifier of a worker within\n\t// a CICD system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"abc123\", \"10.0.1.2\", \"controller\"\n\tCICDWorkerIDKey = attribute.Key(\"cicd.worker.id\")\n\n\t// CICDWorkerNameKey is the attribute Key conforming to the \"cicd.worker.name\"\n\t// semantic conventions. It represents the name of a worker within a CICD\n\t// system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"agent-abc\", \"controller\", \"Ubuntu LTS\"\n\tCICDWorkerNameKey = attribute.Key(\"cicd.worker.name\")\n\n\t// CICDWorkerStateKey is the attribute Key conforming to the \"cicd.worker.state\"\n\t// semantic conventions. It represents the state of a CICD worker / agent.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"idle\", \"busy\", \"down\"\n\tCICDWorkerStateKey = attribute.Key(\"cicd.worker.state\")\n\n\t// CICDWorkerURLFullKey is the attribute Key conforming to the\n\t// \"cicd.worker.url.full\" semantic conventions. It represents the [URL] of the\n\t// worker, providing the complete address in order to locate and identify the\n\t// worker.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"https://cicd.example.org/worker/abc123\"\n\t//\n\t// [URL]: https://wikipedia.org/wiki/URL\n\tCICDWorkerURLFullKey = attribute.Key(\"cicd.worker.url.full\")\n)\n\n// CICDPipelineName returns an attribute KeyValue conforming to the\n// \"cicd.pipeline.name\" semantic conventions. It represents the human readable\n// name of the pipeline within a CI/CD system.\nfunc CICDPipelineName(val string) attribute.KeyValue {\n\treturn CICDPipelineNameKey.String(val)\n}\n\n// CICDPipelineRunID returns an attribute KeyValue conforming to the\n// \"cicd.pipeline.run.id\" semantic conventions. It represents the unique\n// identifier of a pipeline run within a CI/CD system.\nfunc CICDPipelineRunID(val string) attribute.KeyValue {\n\treturn CICDPipelineRunIDKey.String(val)\n}\n\n// CICDPipelineRunURLFull returns an attribute KeyValue conforming to the\n// \"cicd.pipeline.run.url.full\" semantic conventions. It represents the [URL] of\n// the pipeline run, providing the complete address in order to locate and\n// identify the pipeline run.\n//\n// [URL]: https://wikipedia.org/wiki/URL\nfunc CICDPipelineRunURLFull(val string) attribute.KeyValue {\n\treturn CICDPipelineRunURLFullKey.String(val)\n}\n\n// CICDPipelineTaskName returns an attribute KeyValue conforming to the\n// \"cicd.pipeline.task.name\" semantic conventions. It represents the human\n// readable name of a task within a pipeline. Task here most closely aligns with\n// a [computing process] in a pipeline. Other terms for tasks include commands,\n// steps, and procedures.\n//\n// [computing process]: https://wikipedia.org/wiki/Pipeline_(computing)\nfunc CICDPipelineTaskName(val string) attribute.KeyValue {\n\treturn CICDPipelineTaskNameKey.String(val)\n}\n\n// CICDPipelineTaskRunID returns an attribute KeyValue conforming to the\n// \"cicd.pipeline.task.run.id\" semantic conventions. It represents the unique\n// identifier of a task run within a pipeline.\nfunc CICDPipelineTaskRunID(val string) attribute.KeyValue {\n\treturn CICDPipelineTaskRunIDKey.String(val)\n}\n\n// CICDPipelineTaskRunURLFull returns an attribute KeyValue conforming to the\n// \"cicd.pipeline.task.run.url.full\" semantic conventions. It represents the\n// [URL] of the pipeline task run, providing the complete address in order to\n// locate and identify the pipeline task run.\n//\n// [URL]: https://wikipedia.org/wiki/URL\nfunc CICDPipelineTaskRunURLFull(val string) attribute.KeyValue {\n\treturn CICDPipelineTaskRunURLFullKey.String(val)\n}\n\n// CICDSystemComponent returns an attribute KeyValue conforming to the\n// \"cicd.system.component\" semantic conventions. It represents the name of a\n// component of the CICD system.\nfunc CICDSystemComponent(val string) attribute.KeyValue {\n\treturn CICDSystemComponentKey.String(val)\n}\n\n// CICDWorkerID returns an attribute KeyValue conforming to the \"cicd.worker.id\"\n// semantic conventions. It represents the unique identifier of a worker within a\n// CICD system.\nfunc CICDWorkerID(val string) attribute.KeyValue {\n\treturn CICDWorkerIDKey.String(val)\n}\n\n// CICDWorkerName returns an attribute KeyValue conforming to the\n// \"cicd.worker.name\" semantic conventions. It represents the name of a worker\n// within a CICD system.\nfunc CICDWorkerName(val string) attribute.KeyValue {\n\treturn CICDWorkerNameKey.String(val)\n}\n\n// CICDWorkerURLFull returns an attribute KeyValue conforming to the\n// \"cicd.worker.url.full\" semantic conventions. It represents the [URL] of the\n// worker, providing the complete address in order to locate and identify the\n// worker.\n//\n// [URL]: https://wikipedia.org/wiki/URL\nfunc CICDWorkerURLFull(val string) attribute.KeyValue {\n\treturn CICDWorkerURLFullKey.String(val)\n}\n\n// Enum values for cicd.pipeline.action.name\nvar (\n\t// The pipeline run is executing a build.\n\t// Stability: development\n\tCICDPipelineActionNameBuild = CICDPipelineActionNameKey.String(\"BUILD\")\n\t// The pipeline run is executing.\n\t// Stability: development\n\tCICDPipelineActionNameRun = CICDPipelineActionNameKey.String(\"RUN\")\n\t// The pipeline run is executing a sync.\n\t// Stability: development\n\tCICDPipelineActionNameSync = CICDPipelineActionNameKey.String(\"SYNC\")\n)\n\n// Enum values for cicd.pipeline.result\nvar (\n\t// The pipeline run finished successfully.\n\t// Stability: development\n\tCICDPipelineResultSuccess = CICDPipelineResultKey.String(\"success\")\n\t// The pipeline run did not finish successfully, eg. due to a compile error or a\n\t// failing test. Such failures are usually detected by non-zero exit codes of\n\t// the tools executed in the pipeline run.\n\t// Stability: development\n\tCICDPipelineResultFailure = CICDPipelineResultKey.String(\"failure\")\n\t// The pipeline run failed due to an error in the CICD system, eg. due to the\n\t// worker being killed.\n\t// Stability: development\n\tCICDPipelineResultError = CICDPipelineResultKey.String(\"error\")\n\t// A timeout caused the pipeline run to be interrupted.\n\t// Stability: development\n\tCICDPipelineResultTimeout = CICDPipelineResultKey.String(\"timeout\")\n\t// The pipeline run was cancelled, eg. by a user manually cancelling the\n\t// pipeline run.\n\t// Stability: development\n\tCICDPipelineResultCancellation = CICDPipelineResultKey.String(\"cancellation\")\n\t// The pipeline run was skipped, eg. due to a precondition not being met.\n\t// Stability: development\n\tCICDPipelineResultSkip = CICDPipelineResultKey.String(\"skip\")\n)\n\n// Enum values for cicd.pipeline.run.state\nvar (\n\t// The run pending state spans from the event triggering the pipeline run until\n\t// the execution of the run starts (eg. time spent in a queue, provisioning\n\t// agents, creating run resources).\n\t//\n\t// Stability: development\n\tCICDPipelineRunStatePending = CICDPipelineRunStateKey.String(\"pending\")\n\t// The executing state spans the execution of any run tasks (eg. build, test).\n\t// Stability: development\n\tCICDPipelineRunStateExecuting = CICDPipelineRunStateKey.String(\"executing\")\n\t// The finalizing state spans from when the run has finished executing (eg.\n\t// cleanup of run resources).\n\t// Stability: development\n\tCICDPipelineRunStateFinalizing = CICDPipelineRunStateKey.String(\"finalizing\")\n)\n\n// Enum values for cicd.pipeline.task.run.result\nvar (\n\t// The task run finished successfully.\n\t// Stability: development\n\tCICDPipelineTaskRunResultSuccess = CICDPipelineTaskRunResultKey.String(\"success\")\n\t// The task run did not finish successfully, eg. due to a compile error or a\n\t// failing test. Such failures are usually detected by non-zero exit codes of\n\t// the tools executed in the task run.\n\t// Stability: development\n\tCICDPipelineTaskRunResultFailure = CICDPipelineTaskRunResultKey.String(\"failure\")\n\t// The task run failed due to an error in the CICD system, eg. due to the worker\n\t// being killed.\n\t// Stability: development\n\tCICDPipelineTaskRunResultError = CICDPipelineTaskRunResultKey.String(\"error\")\n\t// A timeout caused the task run to be interrupted.\n\t// Stability: development\n\tCICDPipelineTaskRunResultTimeout = CICDPipelineTaskRunResultKey.String(\"timeout\")\n\t// The task run was cancelled, eg. by a user manually cancelling the task run.\n\t// Stability: development\n\tCICDPipelineTaskRunResultCancellation = CICDPipelineTaskRunResultKey.String(\"cancellation\")\n\t// The task run was skipped, eg. due to a precondition not being met.\n\t// Stability: development\n\tCICDPipelineTaskRunResultSkip = CICDPipelineTaskRunResultKey.String(\"skip\")\n)\n\n// Enum values for cicd.pipeline.task.type\nvar (\n\t// build\n\t// Stability: development\n\tCICDPipelineTaskTypeBuild = CICDPipelineTaskTypeKey.String(\"build\")\n\t// test\n\t// Stability: development\n\tCICDPipelineTaskTypeTest = CICDPipelineTaskTypeKey.String(\"test\")\n\t// deploy\n\t// Stability: development\n\tCICDPipelineTaskTypeDeploy = CICDPipelineTaskTypeKey.String(\"deploy\")\n)\n\n// Enum values for cicd.worker.state\nvar (\n\t// The worker is not performing work for the CICD system. It is available to the\n\t// CICD system to perform work on (online / idle).\n\t// Stability: development\n\tCICDWorkerStateAvailable = CICDWorkerStateKey.String(\"available\")\n\t// The worker is performing work for the CICD system.\n\t// Stability: development\n\tCICDWorkerStateBusy = CICDWorkerStateKey.String(\"busy\")\n\t// The worker is not available to the CICD system (disconnected / down).\n\t// Stability: development\n\tCICDWorkerStateOffline = CICDWorkerStateKey.String(\"offline\")\n)\n\n// Namespace: client\nconst (\n\t// ClientAddressKey is the attribute Key conforming to the \"client.address\"\n\t// semantic conventions. It represents the client address - domain name if\n\t// available without reverse DNS lookup; otherwise, IP address or Unix domain\n\t// socket name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"client.example.com\", \"10.1.2.80\", \"/tmp/my.sock\"\n\t// Note: When observed from the server side, and when communicating through an\n\t// intermediary, `client.address` SHOULD represent the client address behind any\n\t// intermediaries, for example proxies, if it's available.\n\tClientAddressKey = attribute.Key(\"client.address\")\n\n\t// ClientPortKey is the attribute Key conforming to the \"client.port\" semantic\n\t// conventions. It represents the client port number.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: 65123\n\t// Note: When observed from the server side, and when communicating through an\n\t// intermediary, `client.port` SHOULD represent the client port behind any\n\t// intermediaries, for example proxies, if it's available.\n\tClientPortKey = attribute.Key(\"client.port\")\n)\n\n// ClientAddress returns an attribute KeyValue conforming to the \"client.address\"\n// semantic conventions. It represents the client address - domain name if\n// available without reverse DNS lookup; otherwise, IP address or Unix domain\n// socket name.\nfunc ClientAddress(val string) attribute.KeyValue {\n\treturn ClientAddressKey.String(val)\n}\n\n// ClientPort returns an attribute KeyValue conforming to the \"client.port\"\n// semantic conventions. It represents the client port number.\nfunc ClientPort(val int) attribute.KeyValue {\n\treturn ClientPortKey.Int(val)\n}\n\n// Namespace: cloud\nconst (\n\t// CloudAccountIDKey is the attribute Key conforming to the \"cloud.account.id\"\n\t// semantic conventions. It represents the cloud account ID the resource is\n\t// assigned to.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"111111111111\", \"opentelemetry\"\n\tCloudAccountIDKey = attribute.Key(\"cloud.account.id\")\n\n\t// CloudAvailabilityZoneKey is the attribute Key conforming to the\n\t// \"cloud.availability_zone\" semantic conventions. It represents the cloud\n\t// regions often have multiple, isolated locations known as zones to increase\n\t// availability. Availability zone represents the zone where the resource is\n\t// running.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"us-east-1c\"\n\t// Note: Availability zones are called \"zones\" on Alibaba Cloud and Google\n\t// Cloud.\n\tCloudAvailabilityZoneKey = attribute.Key(\"cloud.availability_zone\")\n\n\t// CloudPlatformKey is the attribute Key conforming to the \"cloud.platform\"\n\t// semantic conventions. It represents the cloud platform in use.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: The prefix of the service SHOULD match the one specified in\n\t// `cloud.provider`.\n\tCloudPlatformKey = attribute.Key(\"cloud.platform\")\n\n\t// CloudProviderKey is the attribute Key conforming to the \"cloud.provider\"\n\t// semantic conventions. It represents the name of the cloud provider.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tCloudProviderKey = attribute.Key(\"cloud.provider\")\n\n\t// CloudRegionKey is the attribute Key conforming to the \"cloud.region\" semantic\n\t// conventions. It represents the geographical region within a cloud provider.\n\t// When associated with a resource, this attribute specifies the region where\n\t// the resource operates. When calling services or APIs deployed on a cloud,\n\t// this attribute identifies the region where the called destination is\n\t// deployed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"us-central1\", \"us-east-1\"\n\t// Note: Refer to your provider's docs to see the available regions, for example\n\t// [Alibaba Cloud regions], [AWS regions], [Azure regions],\n\t// [Google Cloud regions], or [Tencent Cloud regions].\n\t//\n\t// [Alibaba Cloud regions]: https://www.alibabacloud.com/help/doc-detail/40654.htm\n\t// [AWS regions]: https://aws.amazon.com/about-aws/global-infrastructure/regions_az/\n\t// [Azure regions]: https://azure.microsoft.com/global-infrastructure/geographies/\n\t// [Google Cloud regions]: https://cloud.google.com/about/locations\n\t// [Tencent Cloud regions]: https://www.tencentcloud.com/document/product/213/6091\n\tCloudRegionKey = attribute.Key(\"cloud.region\")\n\n\t// CloudResourceIDKey is the attribute Key conforming to the \"cloud.resource_id\"\n\t// semantic conventions. It represents the cloud provider-specific native\n\t// identifier of the monitored cloud resource (e.g. an [ARN] on AWS, a\n\t// [fully qualified resource ID] on Azure, a [full resource name] on GCP).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"arn:aws:lambda:REGION:ACCOUNT_ID:function:my-function\",\n\t// \"//run.googleapis.com/projects/PROJECT_ID/locations/LOCATION_ID/services/SERVICE_ID\",\n\t// \"/subscriptions/<SUBSCRIPTION_GUID>/resourceGroups/<RG>\n\t// /providers/Microsoft.Web/sites/<FUNCAPP>/functions/<FUNC>\"\n\t// Note: On some cloud providers, it may not be possible to determine the full\n\t// ID at startup,\n\t// so it may be necessary to set `cloud.resource_id` as a span attribute\n\t// instead.\n\t//\n\t// The exact value to use for `cloud.resource_id` depends on the cloud provider.\n\t// The following well-known definitions MUST be used if you set this attribute\n\t// and they apply:\n\t//\n\t//   - **AWS Lambda:** The function [ARN].\n\t//     Take care not to use the \"invoked ARN\" directly but replace any\n\t//     [alias suffix]\n\t//     with the resolved function version, as the same runtime instance may be\n\t//     invocable with\n\t//     multiple different aliases.\n\t//   - **GCP:** The [URI of the resource]\n\t//   - **Azure:** The [Fully Qualified Resource ID] of the invoked function,\n\t//     *not* the function app, having the form\n\t//\n\t//     `/subscriptions/<SUBSCRIPTION_GUID>/resourceGroups/<RG>/providers/Microsoft.Web/sites/<FUNCAPP>/functions/<FUNC>`\n\t//     .\n\t//     This means that a span attribute MUST be used, as an Azure function app\n\t//     can host multiple functions that would usually share\n\t//     a TracerProvider.\n\t//\n\t//\n\t// [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html\n\t// [fully qualified resource ID]: https://learn.microsoft.com/rest/api/resources/resources/get-by-id\n\t// [full resource name]: https://google.aip.dev/122#full-resource-names\n\t// [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html\n\t// [alias suffix]: https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html\n\t// [URI of the resource]: https://cloud.google.com/iam/docs/full-resource-names\n\t// [Fully Qualified Resource ID]: https://learn.microsoft.com/rest/api/resources/resources/get-by-id\n\tCloudResourceIDKey = attribute.Key(\"cloud.resource_id\")\n)\n\n// CloudAccountID returns an attribute KeyValue conforming to the\n// \"cloud.account.id\" semantic conventions. It represents the cloud account ID\n// the resource is assigned to.\nfunc CloudAccountID(val string) attribute.KeyValue {\n\treturn CloudAccountIDKey.String(val)\n}\n\n// CloudAvailabilityZone returns an attribute KeyValue conforming to the\n// \"cloud.availability_zone\" semantic conventions. It represents the cloud\n// regions often have multiple, isolated locations known as zones to increase\n// availability. Availability zone represents the zone where the resource is\n// running.\nfunc CloudAvailabilityZone(val string) attribute.KeyValue {\n\treturn CloudAvailabilityZoneKey.String(val)\n}\n\n// CloudRegion returns an attribute KeyValue conforming to the \"cloud.region\"\n// semantic conventions. It represents the geographical region within a cloud\n// provider. When associated with a resource, this attribute specifies the region\n// where the resource operates. When calling services or APIs deployed on a\n// cloud, this attribute identifies the region where the called destination is\n// deployed.\nfunc CloudRegion(val string) attribute.KeyValue {\n\treturn CloudRegionKey.String(val)\n}\n\n// CloudResourceID returns an attribute KeyValue conforming to the\n// \"cloud.resource_id\" semantic conventions. It represents the cloud\n// provider-specific native identifier of the monitored cloud resource (e.g. an\n// [ARN] on AWS, a [fully qualified resource ID] on Azure, a [full resource name]\n//  on GCP).\n//\n// [ARN]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html\n// [fully qualified resource ID]: https://learn.microsoft.com/rest/api/resources/resources/get-by-id\n// [full resource name]: https://google.aip.dev/122#full-resource-names\nfunc CloudResourceID(val string) attribute.KeyValue {\n\treturn CloudResourceIDKey.String(val)\n}\n\n// Enum values for cloud.platform\nvar (\n\t// Akamai Cloud Compute\n\t// Stability: development\n\tCloudPlatformAkamaiCloudCompute = CloudPlatformKey.String(\"akamai_cloud.compute\")\n\t// Alibaba Cloud Elastic Compute Service\n\t// Stability: development\n\tCloudPlatformAlibabaCloudECS = CloudPlatformKey.String(\"alibaba_cloud_ecs\")\n\t// Alibaba Cloud Function Compute\n\t// Stability: development\n\tCloudPlatformAlibabaCloudFC = CloudPlatformKey.String(\"alibaba_cloud_fc\")\n\t// Red Hat OpenShift on Alibaba Cloud\n\t// Stability: development\n\tCloudPlatformAlibabaCloudOpenShift = CloudPlatformKey.String(\"alibaba_cloud_openshift\")\n\t// AWS Elastic Compute Cloud\n\t// Stability: development\n\tCloudPlatformAWSEC2 = CloudPlatformKey.String(\"aws_ec2\")\n\t// AWS Elastic Container Service\n\t// Stability: development\n\tCloudPlatformAWSECS = CloudPlatformKey.String(\"aws_ecs\")\n\t// AWS Elastic Kubernetes Service\n\t// Stability: development\n\tCloudPlatformAWSEKS = CloudPlatformKey.String(\"aws_eks\")\n\t// AWS Lambda\n\t// Stability: development\n\tCloudPlatformAWSLambda = CloudPlatformKey.String(\"aws_lambda\")\n\t// AWS Elastic Beanstalk\n\t// Stability: development\n\tCloudPlatformAWSElasticBeanstalk = CloudPlatformKey.String(\"aws_elastic_beanstalk\")\n\t// AWS App Runner\n\t// Stability: development\n\tCloudPlatformAWSAppRunner = CloudPlatformKey.String(\"aws_app_runner\")\n\t// Red Hat OpenShift on AWS (ROSA)\n\t// Stability: development\n\tCloudPlatformAWSOpenShift = CloudPlatformKey.String(\"aws_openshift\")\n\t// Azure Virtual Machines\n\t// Stability: development\n\tCloudPlatformAzureVM = CloudPlatformKey.String(\"azure.vm\")\n\t// Azure Container Apps\n\t// Stability: development\n\tCloudPlatformAzureContainerApps = CloudPlatformKey.String(\"azure.container_apps\")\n\t// Azure Container Instances\n\t// Stability: development\n\tCloudPlatformAzureContainerInstances = CloudPlatformKey.String(\"azure.container_instances\")\n\t// Azure Kubernetes Service\n\t// Stability: development\n\tCloudPlatformAzureAKS = CloudPlatformKey.String(\"azure.aks\")\n\t// Azure Functions\n\t// Stability: development\n\tCloudPlatformAzureFunctions = CloudPlatformKey.String(\"azure.functions\")\n\t// Azure App Service\n\t// Stability: development\n\tCloudPlatformAzureAppService = CloudPlatformKey.String(\"azure.app_service\")\n\t// Azure Red Hat OpenShift\n\t// Stability: development\n\tCloudPlatformAzureOpenShift = CloudPlatformKey.String(\"azure.openshift\")\n\t// Google Vertex AI Agent Engine\n\t// Stability: development\n\tCloudPlatformGCPAgentEngine = CloudPlatformKey.String(\"gcp.agent_engine\")\n\t// Google Bare Metal Solution (BMS)\n\t// Stability: development\n\tCloudPlatformGCPBareMetalSolution = CloudPlatformKey.String(\"gcp_bare_metal_solution\")\n\t// Google Cloud Compute Engine (GCE)\n\t// Stability: development\n\tCloudPlatformGCPComputeEngine = CloudPlatformKey.String(\"gcp_compute_engine\")\n\t// Google Cloud Run\n\t// Stability: development\n\tCloudPlatformGCPCloudRun = CloudPlatformKey.String(\"gcp_cloud_run\")\n\t// Google Cloud Kubernetes Engine (GKE)\n\t// Stability: development\n\tCloudPlatformGCPKubernetesEngine = CloudPlatformKey.String(\"gcp_kubernetes_engine\")\n\t// Google Cloud Functions (GCF)\n\t// Stability: development\n\tCloudPlatformGCPCloudFunctions = CloudPlatformKey.String(\"gcp_cloud_functions\")\n\t// Google Cloud App Engine (GAE)\n\t// Stability: development\n\tCloudPlatformGCPAppEngine = CloudPlatformKey.String(\"gcp_app_engine\")\n\t// Red Hat OpenShift on Google Cloud\n\t// Stability: development\n\tCloudPlatformGCPOpenShift = CloudPlatformKey.String(\"gcp_openshift\")\n\t// Server on Hetzner Cloud\n\t// Stability: development\n\tCloudPlatformHetznerCloudServer = CloudPlatformKey.String(\"hetzner.cloud_server\")\n\t// Red Hat OpenShift on IBM Cloud\n\t// Stability: development\n\tCloudPlatformIBMCloudOpenShift = CloudPlatformKey.String(\"ibm_cloud_openshift\")\n\t// Compute on Oracle Cloud Infrastructure (OCI)\n\t// Stability: development\n\tCloudPlatformOracleCloudCompute = CloudPlatformKey.String(\"oracle_cloud_compute\")\n\t// Kubernetes Engine (OKE) on Oracle Cloud Infrastructure (OCI)\n\t// Stability: development\n\tCloudPlatformOracleCloudOKE = CloudPlatformKey.String(\"oracle_cloud_oke\")\n\t// Tencent Cloud Cloud Virtual Machine (CVM)\n\t// Stability: development\n\tCloudPlatformTencentCloudCVM = CloudPlatformKey.String(\"tencent_cloud_cvm\")\n\t// Tencent Cloud Elastic Kubernetes Service (EKS)\n\t// Stability: development\n\tCloudPlatformTencentCloudEKS = CloudPlatformKey.String(\"tencent_cloud_eks\")\n\t// Tencent Cloud Serverless Cloud Function (SCF)\n\t// Stability: development\n\tCloudPlatformTencentCloudSCF = CloudPlatformKey.String(\"tencent_cloud_scf\")\n\t// Vultr Cloud Compute\n\t// Stability: development\n\tCloudPlatformVultrCloudCompute = CloudPlatformKey.String(\"vultr.cloud_compute\")\n)\n\n// Enum values for cloud.provider\nvar (\n\t// Akamai Cloud\n\t// Stability: development\n\tCloudProviderAkamaiCloud = CloudProviderKey.String(\"akamai_cloud\")\n\t// Alibaba Cloud\n\t// Stability: development\n\tCloudProviderAlibabaCloud = CloudProviderKey.String(\"alibaba_cloud\")\n\t// Amazon Web Services\n\t// Stability: development\n\tCloudProviderAWS = CloudProviderKey.String(\"aws\")\n\t// Microsoft Azure\n\t// Stability: development\n\tCloudProviderAzure = CloudProviderKey.String(\"azure\")\n\t// Google Cloud Platform\n\t// Stability: development\n\tCloudProviderGCP = CloudProviderKey.String(\"gcp\")\n\t// Heroku Platform as a Service\n\t// Stability: development\n\tCloudProviderHeroku = CloudProviderKey.String(\"heroku\")\n\t// Hetzner\n\t// Stability: development\n\tCloudProviderHetzner = CloudProviderKey.String(\"hetzner\")\n\t// IBM Cloud\n\t// Stability: development\n\tCloudProviderIBMCloud = CloudProviderKey.String(\"ibm_cloud\")\n\t// Oracle Cloud Infrastructure (OCI)\n\t// Stability: development\n\tCloudProviderOracleCloud = CloudProviderKey.String(\"oracle_cloud\")\n\t// Tencent Cloud\n\t// Stability: development\n\tCloudProviderTencentCloud = CloudProviderKey.String(\"tencent_cloud\")\n\t// Vultr\n\t// Stability: development\n\tCloudProviderVultr = CloudProviderKey.String(\"vultr\")\n)\n\n// Namespace: cloudevents\nconst (\n\t// CloudEventsEventIDKey is the attribute Key conforming to the\n\t// \"cloudevents.event_id\" semantic conventions. It represents the [event_id]\n\t// uniquely identifies the event.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"123e4567-e89b-12d3-a456-426614174000\", \"0001\"\n\t//\n\t// [event_id]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id\n\tCloudEventsEventIDKey = attribute.Key(\"cloudevents.event_id\")\n\n\t// CloudEventsEventSourceKey is the attribute Key conforming to the\n\t// \"cloudevents.event_source\" semantic conventions. It represents the [source]\n\t// identifies the context in which an event happened.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"https://github.com/cloudevents\", \"/cloudevents/spec/pull/123\",\n\t// \"my-service\"\n\t//\n\t// [source]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1\n\tCloudEventsEventSourceKey = attribute.Key(\"cloudevents.event_source\")\n\n\t// CloudEventsEventSpecVersionKey is the attribute Key conforming to the\n\t// \"cloudevents.event_spec_version\" semantic conventions. It represents the\n\t// [version of the CloudEvents specification] which the event uses.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1.0\n\t//\n\t// [version of the CloudEvents specification]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion\n\tCloudEventsEventSpecVersionKey = attribute.Key(\"cloudevents.event_spec_version\")\n\n\t// CloudEventsEventSubjectKey is the attribute Key conforming to the\n\t// \"cloudevents.event_subject\" semantic conventions. It represents the [subject]\n\t//  of the event in the context of the event producer (identified by source).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: mynewfile.jpg\n\t//\n\t// [subject]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject\n\tCloudEventsEventSubjectKey = attribute.Key(\"cloudevents.event_subject\")\n\n\t// CloudEventsEventTypeKey is the attribute Key conforming to the\n\t// \"cloudevents.event_type\" semantic conventions. It represents the [event_type]\n\t//  contains a value describing the type of event related to the originating\n\t// occurrence.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"com.github.pull_request.opened\", \"com.example.object.deleted.v2\"\n\t//\n\t// [event_type]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type\n\tCloudEventsEventTypeKey = attribute.Key(\"cloudevents.event_type\")\n)\n\n// CloudEventsEventID returns an attribute KeyValue conforming to the\n// \"cloudevents.event_id\" semantic conventions. It represents the [event_id]\n// uniquely identifies the event.\n//\n// [event_id]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id\nfunc CloudEventsEventID(val string) attribute.KeyValue {\n\treturn CloudEventsEventIDKey.String(val)\n}\n\n// CloudEventsEventSource returns an attribute KeyValue conforming to the\n// \"cloudevents.event_source\" semantic conventions. It represents the [source]\n// identifies the context in which an event happened.\n//\n// [source]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1\nfunc CloudEventsEventSource(val string) attribute.KeyValue {\n\treturn CloudEventsEventSourceKey.String(val)\n}\n\n// CloudEventsEventSpecVersion returns an attribute KeyValue conforming to the\n// \"cloudevents.event_spec_version\" semantic conventions. It represents the\n// [version of the CloudEvents specification] which the event uses.\n//\n// [version of the CloudEvents specification]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion\nfunc CloudEventsEventSpecVersion(val string) attribute.KeyValue {\n\treturn CloudEventsEventSpecVersionKey.String(val)\n}\n\n// CloudEventsEventSubject returns an attribute KeyValue conforming to the\n// \"cloudevents.event_subject\" semantic conventions. It represents the [subject]\n// of the event in the context of the event producer (identified by source).\n//\n// [subject]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject\nfunc CloudEventsEventSubject(val string) attribute.KeyValue {\n\treturn CloudEventsEventSubjectKey.String(val)\n}\n\n// CloudEventsEventType returns an attribute KeyValue conforming to the\n// \"cloudevents.event_type\" semantic conventions. It represents the [event_type]\n// contains a value describing the type of event related to the originating\n// occurrence.\n//\n// [event_type]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type\nfunc CloudEventsEventType(val string) attribute.KeyValue {\n\treturn CloudEventsEventTypeKey.String(val)\n}\n\n// Namespace: cloudfoundry\nconst (\n\t// CloudFoundryAppIDKey is the attribute Key conforming to the\n\t// \"cloudfoundry.app.id\" semantic conventions. It represents the guid of the\n\t// application.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"218fc5a9-a5f1-4b54-aa05-46717d0ab26d\"\n\t// Note: Application instrumentation should use the value from environment\n\t// variable `VCAP_APPLICATION.application_id`. This is the same value as\n\t// reported by `cf app <app-name> --guid`.\n\tCloudFoundryAppIDKey = attribute.Key(\"cloudfoundry.app.id\")\n\n\t// CloudFoundryAppInstanceIDKey is the attribute Key conforming to the\n\t// \"cloudfoundry.app.instance.id\" semantic conventions. It represents the index\n\t// of the application instance. 0 when just one instance is active.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"0\", \"1\"\n\t// Note: CloudFoundry defines the `instance_id` in the [Loggregator v2 envelope]\n\t// .\n\t// It is used for logs and metrics emitted by CloudFoundry. It is\n\t// supposed to contain the application instance index for applications\n\t// deployed on the runtime.\n\t//\n\t// Application instrumentation should use the value from environment\n\t// variable `CF_INSTANCE_INDEX`.\n\t//\n\t// [Loggregator v2 envelope]: https://github.com/cloudfoundry/loggregator-api#v2-envelope\n\tCloudFoundryAppInstanceIDKey = attribute.Key(\"cloudfoundry.app.instance.id\")\n\n\t// CloudFoundryAppNameKey is the attribute Key conforming to the\n\t// \"cloudfoundry.app.name\" semantic conventions. It represents the name of the\n\t// application.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-app-name\"\n\t// Note: Application instrumentation should use the value from environment\n\t// variable `VCAP_APPLICATION.application_name`. This is the same value\n\t// as reported by `cf apps`.\n\tCloudFoundryAppNameKey = attribute.Key(\"cloudfoundry.app.name\")\n\n\t// CloudFoundryOrgIDKey is the attribute Key conforming to the\n\t// \"cloudfoundry.org.id\" semantic conventions. It represents the guid of the\n\t// CloudFoundry org the application is running in.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"218fc5a9-a5f1-4b54-aa05-46717d0ab26d\"\n\t// Note: Application instrumentation should use the value from environment\n\t// variable `VCAP_APPLICATION.org_id`. This is the same value as\n\t// reported by `cf org <org-name> --guid`.\n\tCloudFoundryOrgIDKey = attribute.Key(\"cloudfoundry.org.id\")\n\n\t// CloudFoundryOrgNameKey is the attribute Key conforming to the\n\t// \"cloudfoundry.org.name\" semantic conventions. It represents the name of the\n\t// CloudFoundry organization the app is running in.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-org-name\"\n\t// Note: Application instrumentation should use the value from environment\n\t// variable `VCAP_APPLICATION.org_name`. This is the same value as\n\t// reported by `cf orgs`.\n\tCloudFoundryOrgNameKey = attribute.Key(\"cloudfoundry.org.name\")\n\n\t// CloudFoundryProcessIDKey is the attribute Key conforming to the\n\t// \"cloudfoundry.process.id\" semantic conventions. It represents the UID\n\t// identifying the process.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"218fc5a9-a5f1-4b54-aa05-46717d0ab26d\"\n\t// Note: Application instrumentation should use the value from environment\n\t// variable `VCAP_APPLICATION.process_id`. It is supposed to be equal to\n\t// `VCAP_APPLICATION.app_id` for applications deployed to the runtime.\n\t// For system components, this could be the actual PID.\n\tCloudFoundryProcessIDKey = attribute.Key(\"cloudfoundry.process.id\")\n\n\t// CloudFoundryProcessTypeKey is the attribute Key conforming to the\n\t// \"cloudfoundry.process.type\" semantic conventions. It represents the type of\n\t// process.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"web\"\n\t// Note: CloudFoundry applications can consist of multiple jobs. Usually the\n\t// main process will be of type `web`. There can be additional background\n\t// tasks or side-cars with different process types.\n\tCloudFoundryProcessTypeKey = attribute.Key(\"cloudfoundry.process.type\")\n\n\t// CloudFoundrySpaceIDKey is the attribute Key conforming to the\n\t// \"cloudfoundry.space.id\" semantic conventions. It represents the guid of the\n\t// CloudFoundry space the application is running in.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"218fc5a9-a5f1-4b54-aa05-46717d0ab26d\"\n\t// Note: Application instrumentation should use the value from environment\n\t// variable `VCAP_APPLICATION.space_id`. This is the same value as\n\t// reported by `cf space <space-name> --guid`.\n\tCloudFoundrySpaceIDKey = attribute.Key(\"cloudfoundry.space.id\")\n\n\t// CloudFoundrySpaceNameKey is the attribute Key conforming to the\n\t// \"cloudfoundry.space.name\" semantic conventions. It represents the name of the\n\t// CloudFoundry space the application is running in.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-space-name\"\n\t// Note: Application instrumentation should use the value from environment\n\t// variable `VCAP_APPLICATION.space_name`. This is the same value as\n\t// reported by `cf spaces`.\n\tCloudFoundrySpaceNameKey = attribute.Key(\"cloudfoundry.space.name\")\n\n\t// CloudFoundrySystemIDKey is the attribute Key conforming to the\n\t// \"cloudfoundry.system.id\" semantic conventions. It represents a guid or\n\t// another name describing the event source.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"cf/gorouter\"\n\t// Note: CloudFoundry defines the `source_id` in the [Loggregator v2 envelope].\n\t// It is used for logs and metrics emitted by CloudFoundry. It is\n\t// supposed to contain the component name, e.g. \"gorouter\", for\n\t// CloudFoundry components.\n\t//\n\t// When system components are instrumented, values from the\n\t// [Bosh spec]\n\t// should be used. The `system.id` should be set to\n\t// `spec.deployment/spec.name`.\n\t//\n\t// [Loggregator v2 envelope]: https://github.com/cloudfoundry/loggregator-api#v2-envelope\n\t// [Bosh spec]: https://bosh.io/docs/jobs/#properties-spec\n\tCloudFoundrySystemIDKey = attribute.Key(\"cloudfoundry.system.id\")\n\n\t// CloudFoundrySystemInstanceIDKey is the attribute Key conforming to the\n\t// \"cloudfoundry.system.instance.id\" semantic conventions. It represents a guid\n\t// describing the concrete instance of the event source.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"218fc5a9-a5f1-4b54-aa05-46717d0ab26d\"\n\t// Note: CloudFoundry defines the `instance_id` in the [Loggregator v2 envelope]\n\t// .\n\t// It is used for logs and metrics emitted by CloudFoundry. It is\n\t// supposed to contain the vm id for CloudFoundry components.\n\t//\n\t// When system components are instrumented, values from the\n\t// [Bosh spec]\n\t// should be used. The `system.instance.id` should be set to `spec.id`.\n\t//\n\t// [Loggregator v2 envelope]: https://github.com/cloudfoundry/loggregator-api#v2-envelope\n\t// [Bosh spec]: https://bosh.io/docs/jobs/#properties-spec\n\tCloudFoundrySystemInstanceIDKey = attribute.Key(\"cloudfoundry.system.instance.id\")\n)\n\n// CloudFoundryAppID returns an attribute KeyValue conforming to the\n// \"cloudfoundry.app.id\" semantic conventions. It represents the guid of the\n// application.\nfunc CloudFoundryAppID(val string) attribute.KeyValue {\n\treturn CloudFoundryAppIDKey.String(val)\n}\n\n// CloudFoundryAppInstanceID returns an attribute KeyValue conforming to the\n// \"cloudfoundry.app.instance.id\" semantic conventions. It represents the index\n// of the application instance. 0 when just one instance is active.\nfunc CloudFoundryAppInstanceID(val string) attribute.KeyValue {\n\treturn CloudFoundryAppInstanceIDKey.String(val)\n}\n\n// CloudFoundryAppName returns an attribute KeyValue conforming to the\n// \"cloudfoundry.app.name\" semantic conventions. It represents the name of the\n// application.\nfunc CloudFoundryAppName(val string) attribute.KeyValue {\n\treturn CloudFoundryAppNameKey.String(val)\n}\n\n// CloudFoundryOrgID returns an attribute KeyValue conforming to the\n// \"cloudfoundry.org.id\" semantic conventions. It represents the guid of the\n// CloudFoundry org the application is running in.\nfunc CloudFoundryOrgID(val string) attribute.KeyValue {\n\treturn CloudFoundryOrgIDKey.String(val)\n}\n\n// CloudFoundryOrgName returns an attribute KeyValue conforming to the\n// \"cloudfoundry.org.name\" semantic conventions. It represents the name of the\n// CloudFoundry organization the app is running in.\nfunc CloudFoundryOrgName(val string) attribute.KeyValue {\n\treturn CloudFoundryOrgNameKey.String(val)\n}\n\n// CloudFoundryProcessID returns an attribute KeyValue conforming to the\n// \"cloudfoundry.process.id\" semantic conventions. It represents the UID\n// identifying the process.\nfunc CloudFoundryProcessID(val string) attribute.KeyValue {\n\treturn CloudFoundryProcessIDKey.String(val)\n}\n\n// CloudFoundryProcessType returns an attribute KeyValue conforming to the\n// \"cloudfoundry.process.type\" semantic conventions. It represents the type of\n// process.\nfunc CloudFoundryProcessType(val string) attribute.KeyValue {\n\treturn CloudFoundryProcessTypeKey.String(val)\n}\n\n// CloudFoundrySpaceID returns an attribute KeyValue conforming to the\n// \"cloudfoundry.space.id\" semantic conventions. It represents the guid of the\n// CloudFoundry space the application is running in.\nfunc CloudFoundrySpaceID(val string) attribute.KeyValue {\n\treturn CloudFoundrySpaceIDKey.String(val)\n}\n\n// CloudFoundrySpaceName returns an attribute KeyValue conforming to the\n// \"cloudfoundry.space.name\" semantic conventions. It represents the name of the\n// CloudFoundry space the application is running in.\nfunc CloudFoundrySpaceName(val string) attribute.KeyValue {\n\treturn CloudFoundrySpaceNameKey.String(val)\n}\n\n// CloudFoundrySystemID returns an attribute KeyValue conforming to the\n// \"cloudfoundry.system.id\" semantic conventions. It represents a guid or another\n// name describing the event source.\nfunc CloudFoundrySystemID(val string) attribute.KeyValue {\n\treturn CloudFoundrySystemIDKey.String(val)\n}\n\n// CloudFoundrySystemInstanceID returns an attribute KeyValue conforming to the\n// \"cloudfoundry.system.instance.id\" semantic conventions. It represents a guid\n// describing the concrete instance of the event source.\nfunc CloudFoundrySystemInstanceID(val string) attribute.KeyValue {\n\treturn CloudFoundrySystemInstanceIDKey.String(val)\n}\n\n// Namespace: code\nconst (\n\t// CodeColumnNumberKey is the attribute Key conforming to the\n\t// \"code.column.number\" semantic conventions. It represents the column number in\n\t// `code.file.path` best representing the operation. It SHOULD point within the\n\t// code unit named in `code.function.name`. This attribute MUST NOT be used on\n\t// the Profile signal since the data is already captured in 'message Line'. This\n\t// constraint is imposed to prevent redundancy and maintain data integrity.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\tCodeColumnNumberKey = attribute.Key(\"code.column.number\")\n\n\t// CodeFilePathKey is the attribute Key conforming to the \"code.file.path\"\n\t// semantic conventions. It represents the source code file name that identifies\n\t// the code unit as uniquely as possible (preferably an absolute file path).\n\t// This attribute MUST NOT be used on the Profile signal since the data is\n\t// already captured in 'message Function'. This constraint is imposed to prevent\n\t// redundancy and maintain data integrity.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: /usr/local/MyApplication/content_root/app/index.php\n\tCodeFilePathKey = attribute.Key(\"code.file.path\")\n\n\t// CodeFunctionNameKey is the attribute Key conforming to the\n\t// \"code.function.name\" semantic conventions. It represents the method or\n\t// function fully-qualified name without arguments. The value should fit the\n\t// natural representation of the language runtime, which is also likely the same\n\t// used within `code.stacktrace` attribute value. This attribute MUST NOT be\n\t// used on the Profile signal since the data is already captured in 'message\n\t// Function'. This constraint is imposed to prevent redundancy and maintain data\n\t// integrity.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"com.example.MyHttpService.serveRequest\",\n\t// \"GuzzleHttp\\Client::transfer\", \"fopen\"\n\t// Note: Values and format depends on each language runtime, thus it is\n\t// impossible to provide an exhaustive list of examples.\n\t// The values are usually the same (or prefixes of) the ones found in native\n\t// stack trace representation stored in\n\t// `code.stacktrace` without information on arguments.\n\t//\n\t// Examples:\n\t//\n\t//   - Java method: `com.example.MyHttpService.serveRequest`\n\t//   - Java anonymous class method: `com.mycompany.Main$1.myMethod`\n\t//   - Java lambda method:\n\t//     `com.mycompany.Main$$Lambda/0x0000748ae4149c00.myMethod`\n\t//   - PHP function: `GuzzleHttp\\Client::transfer`\n\t//   - Go function: `github.com/my/repo/pkg.foo.func5`\n\t//   - Elixir: `OpenTelemetry.Ctx.new`\n\t//   - Erlang: `opentelemetry_ctx:new`\n\t//   - Rust: `playground::my_module::my_cool_func`\n\t//   - C function: `fopen`\n\tCodeFunctionNameKey = attribute.Key(\"code.function.name\")\n\n\t// CodeLineNumberKey is the attribute Key conforming to the \"code.line.number\"\n\t// semantic conventions. It represents the line number in `code.file.path` best\n\t// representing the operation. It SHOULD point within the code unit named in\n\t// `code.function.name`. This attribute MUST NOT be used on the Profile signal\n\t// since the data is already captured in 'message Line'. This constraint is\n\t// imposed to prevent redundancy and maintain data integrity.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\tCodeLineNumberKey = attribute.Key(\"code.line.number\")\n\n\t// CodeStacktraceKey is the attribute Key conforming to the \"code.stacktrace\"\n\t// semantic conventions. It represents a stacktrace as a string in the natural\n\t// representation for the language runtime. The representation is identical to\n\t// [`exception.stacktrace`]. This attribute MUST NOT be used on the Profile\n\t// signal since the data is already captured in 'message Location'. This\n\t// constraint is imposed to prevent redundancy and maintain data integrity.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\\n at\n\t// com.example.GenerateTrace.methodA(GenerateTrace.java:9)\\n at\n\t// com.example.GenerateTrace.main(GenerateTrace.java:5)\n\t//\n\t// [`exception.stacktrace`]: /docs/exceptions/exceptions-spans.md#stacktrace-representation\n\tCodeStacktraceKey = attribute.Key(\"code.stacktrace\")\n)\n\n// CodeColumnNumber returns an attribute KeyValue conforming to the\n// \"code.column.number\" semantic conventions. It represents the column number in\n// `code.file.path` best representing the operation. It SHOULD point within the\n// code unit named in `code.function.name`. This attribute MUST NOT be used on\n// the Profile signal since the data is already captured in 'message Line'. This\n// constraint is imposed to prevent redundancy and maintain data integrity.\nfunc CodeColumnNumber(val int) attribute.KeyValue {\n\treturn CodeColumnNumberKey.Int(val)\n}\n\n// CodeFilePath returns an attribute KeyValue conforming to the \"code.file.path\"\n// semantic conventions. It represents the source code file name that identifies\n// the code unit as uniquely as possible (preferably an absolute file path). This\n// attribute MUST NOT be used on the Profile signal since the data is already\n// captured in 'message Function'. This constraint is imposed to prevent\n// redundancy and maintain data integrity.\nfunc CodeFilePath(val string) attribute.KeyValue {\n\treturn CodeFilePathKey.String(val)\n}\n\n// CodeFunctionName returns an attribute KeyValue conforming to the\n// \"code.function.name\" semantic conventions. It represents the method or\n// function fully-qualified name without arguments. The value should fit the\n// natural representation of the language runtime, which is also likely the same\n// used within `code.stacktrace` attribute value. This attribute MUST NOT be used\n// on the Profile signal since the data is already captured in 'message\n// Function'. This constraint is imposed to prevent redundancy and maintain data\n// integrity.\nfunc CodeFunctionName(val string) attribute.KeyValue {\n\treturn CodeFunctionNameKey.String(val)\n}\n\n// CodeLineNumber returns an attribute KeyValue conforming to the\n// \"code.line.number\" semantic conventions. It represents the line number in\n// `code.file.path` best representing the operation. It SHOULD point within the\n// code unit named in `code.function.name`. This attribute MUST NOT be used on\n// the Profile signal since the data is already captured in 'message Line'. This\n// constraint is imposed to prevent redundancy and maintain data integrity.\nfunc CodeLineNumber(val int) attribute.KeyValue {\n\treturn CodeLineNumberKey.Int(val)\n}\n\n// CodeStacktrace returns an attribute KeyValue conforming to the\n// \"code.stacktrace\" semantic conventions. It represents a stacktrace as a string\n// in the natural representation for the language runtime. The representation is\n// identical to [`exception.stacktrace`]. This attribute MUST NOT be used on the\n// Profile signal since the data is already captured in 'message Location'. This\n// constraint is imposed to prevent redundancy and maintain data integrity.\n//\n// [`exception.stacktrace`]: /docs/exceptions/exceptions-spans.md#stacktrace-representation\nfunc CodeStacktrace(val string) attribute.KeyValue {\n\treturn CodeStacktraceKey.String(val)\n}\n\n// Namespace: container\nconst (\n\t// ContainerCommandKey is the attribute Key conforming to the\n\t// \"container.command\" semantic conventions. It represents the command used to\n\t// run the container (i.e. the command name).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"otelcontribcol\"\n\t// Note: If using embedded credentials or sensitive data, it is recommended to\n\t// remove them to prevent potential leakage.\n\tContainerCommandKey = attribute.Key(\"container.command\")\n\n\t// ContainerCommandArgsKey is the attribute Key conforming to the\n\t// \"container.command_args\" semantic conventions. It represents the all the\n\t// command arguments (including the command/executable itself) run by the\n\t// container.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"otelcontribcol\", \"--config\", \"config.yaml\"\n\tContainerCommandArgsKey = attribute.Key(\"container.command_args\")\n\n\t// ContainerCommandLineKey is the attribute Key conforming to the\n\t// \"container.command_line\" semantic conventions. It represents the full command\n\t// run by the container as a single string representing the full command.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"otelcontribcol --config config.yaml\"\n\tContainerCommandLineKey = attribute.Key(\"container.command_line\")\n\n\t// ContainerCSIPluginNameKey is the attribute Key conforming to the\n\t// \"container.csi.plugin.name\" semantic conventions. It represents the name of\n\t// the CSI ([Container Storage Interface]) plugin used by the volume.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"pd.csi.storage.gke.io\"\n\t// Note: This can sometimes be referred to as a \"driver\" in CSI implementations.\n\t// This should represent the `name` field of the GetPluginInfo RPC.\n\t//\n\t// [Container Storage Interface]: https://github.com/container-storage-interface/spec\n\tContainerCSIPluginNameKey = attribute.Key(\"container.csi.plugin.name\")\n\n\t// ContainerCSIVolumeIDKey is the attribute Key conforming to the\n\t// \"container.csi.volume.id\" semantic conventions. It represents the unique\n\t// volume ID returned by the CSI ([Container Storage Interface]) plugin.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"projects/my-gcp-project/zones/my-gcp-zone/disks/my-gcp-disk\"\n\t// Note: This can sometimes be referred to as a \"volume handle\" in CSI\n\t// implementations. This should represent the `Volume.volume_id` field in CSI\n\t// spec.\n\t//\n\t// [Container Storage Interface]: https://github.com/container-storage-interface/spec\n\tContainerCSIVolumeIDKey = attribute.Key(\"container.csi.volume.id\")\n\n\t// ContainerIDKey is the attribute Key conforming to the \"container.id\" semantic\n\t// conventions. It represents the container ID. Usually a UUID, as for example\n\t// used to [identify Docker containers]. The UUID might be abbreviated.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"a3bf90e006b2\"\n\t//\n\t// [identify Docker containers]: https://docs.docker.com/engine/containers/run/#container-identification\n\tContainerIDKey = attribute.Key(\"container.id\")\n\n\t// ContainerImageIDKey is the attribute Key conforming to the\n\t// \"container.image.id\" semantic conventions. It represents the runtime specific\n\t// image identifier. Usually a hash algorithm followed by a UUID.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"sha256:19c92d0a00d1b66d897bceaa7319bee0dd38a10a851c60bcec9474aa3f01e50f\"\n\t// Note: Docker defines a sha256 of the image id; `container.image.id`\n\t// corresponds to the `Image` field from the Docker container inspect [API]\n\t// endpoint.\n\t// K8s defines a link to the container registry repository with digest\n\t// `\"imageID\": \"registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625\"`\n\t// .\n\t// The ID is assigned by the container runtime and can vary in different\n\t// environments. Consider using `oci.manifest.digest` if it is important to\n\t// identify the same image in different environments/runtimes.\n\t//\n\t// [API]: https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Container/operation/ContainerInspect\n\tContainerImageIDKey = attribute.Key(\"container.image.id\")\n\n\t// ContainerImageNameKey is the attribute Key conforming to the\n\t// \"container.image.name\" semantic conventions. It represents the name of the\n\t// image the container was built on.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"gcr.io/opentelemetry/operator\"\n\tContainerImageNameKey = attribute.Key(\"container.image.name\")\n\n\t// ContainerImageRepoDigestsKey is the attribute Key conforming to the\n\t// \"container.image.repo_digests\" semantic conventions. It represents the repo\n\t// digests of the container image as provided by the container runtime.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples:\n\t// \"example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb\",\n\t// \"internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578\"\n\t// Note: [Docker] and [CRI] report those under the `RepoDigests` field.\n\t//\n\t// [Docker]: https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Image/operation/ImageInspect\n\t// [CRI]: https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238\n\tContainerImageRepoDigestsKey = attribute.Key(\"container.image.repo_digests\")\n\n\t// ContainerImageTagsKey is the attribute Key conforming to the\n\t// \"container.image.tags\" semantic conventions. It represents the container\n\t// image tags. An example can be found in [Docker Image Inspect]. Should be only\n\t// the `<tag>` section of the full name for example from\n\t// `registry.example.com/my-org/my-image:<tag>`.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"v1.27.1\", \"3.5.7-0\"\n\t//\n\t// [Docker Image Inspect]: https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Image/operation/ImageInspect\n\tContainerImageTagsKey = attribute.Key(\"container.image.tags\")\n\n\t// ContainerNameKey is the attribute Key conforming to the \"container.name\"\n\t// semantic conventions. It represents the container name used by container\n\t// runtime.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry-autoconf\"\n\tContainerNameKey = attribute.Key(\"container.name\")\n\n\t// ContainerRuntimeDescriptionKey is the attribute Key conforming to the\n\t// \"container.runtime.description\" semantic conventions. It represents a\n\t// description about the runtime which could include, for example details about\n\t// the CRI/API version being used or other customisations.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"docker://19.3.1 - CRI: 1.22.0\"\n\tContainerRuntimeDescriptionKey = attribute.Key(\"container.runtime.description\")\n\n\t// ContainerRuntimeNameKey is the attribute Key conforming to the\n\t// \"container.runtime.name\" semantic conventions. It represents the container\n\t// runtime managing this container.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"docker\", \"containerd\", \"rkt\"\n\tContainerRuntimeNameKey = attribute.Key(\"container.runtime.name\")\n\n\t// ContainerRuntimeVersionKey is the attribute Key conforming to the\n\t// \"container.runtime.version\" semantic conventions. It represents the version\n\t// of the runtime of this process, as returned by the runtime without\n\t// modification.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1.0.0\n\tContainerRuntimeVersionKey = attribute.Key(\"container.runtime.version\")\n)\n\n// ContainerCommand returns an attribute KeyValue conforming to the\n// \"container.command\" semantic conventions. It represents the command used to\n// run the container (i.e. the command name).\nfunc ContainerCommand(val string) attribute.KeyValue {\n\treturn ContainerCommandKey.String(val)\n}\n\n// ContainerCommandArgs returns an attribute KeyValue conforming to the\n// \"container.command_args\" semantic conventions. It represents the all the\n// command arguments (including the command/executable itself) run by the\n// container.\nfunc ContainerCommandArgs(val ...string) attribute.KeyValue {\n\treturn ContainerCommandArgsKey.StringSlice(val)\n}\n\n// ContainerCommandLine returns an attribute KeyValue conforming to the\n// \"container.command_line\" semantic conventions. It represents the full command\n// run by the container as a single string representing the full command.\nfunc ContainerCommandLine(val string) attribute.KeyValue {\n\treturn ContainerCommandLineKey.String(val)\n}\n\n// ContainerCSIPluginName returns an attribute KeyValue conforming to the\n// \"container.csi.plugin.name\" semantic conventions. It represents the name of\n// the CSI ([Container Storage Interface]) plugin used by the volume.\n//\n// [Container Storage Interface]: https://github.com/container-storage-interface/spec\nfunc ContainerCSIPluginName(val string) attribute.KeyValue {\n\treturn ContainerCSIPluginNameKey.String(val)\n}\n\n// ContainerCSIVolumeID returns an attribute KeyValue conforming to the\n// \"container.csi.volume.id\" semantic conventions. It represents the unique\n// volume ID returned by the CSI ([Container Storage Interface]) plugin.\n//\n// [Container Storage Interface]: https://github.com/container-storage-interface/spec\nfunc ContainerCSIVolumeID(val string) attribute.KeyValue {\n\treturn ContainerCSIVolumeIDKey.String(val)\n}\n\n// ContainerID returns an attribute KeyValue conforming to the \"container.id\"\n// semantic conventions. It represents the container ID. Usually a UUID, as for\n// example used to [identify Docker containers]. The UUID might be abbreviated.\n//\n// [identify Docker containers]: https://docs.docker.com/engine/containers/run/#container-identification\nfunc ContainerID(val string) attribute.KeyValue {\n\treturn ContainerIDKey.String(val)\n}\n\n// ContainerImageID returns an attribute KeyValue conforming to the\n// \"container.image.id\" semantic conventions. It represents the runtime specific\n// image identifier. Usually a hash algorithm followed by a UUID.\nfunc ContainerImageID(val string) attribute.KeyValue {\n\treturn ContainerImageIDKey.String(val)\n}\n\n// ContainerImageName returns an attribute KeyValue conforming to the\n// \"container.image.name\" semantic conventions. It represents the name of the\n// image the container was built on.\nfunc ContainerImageName(val string) attribute.KeyValue {\n\treturn ContainerImageNameKey.String(val)\n}\n\n// ContainerImageRepoDigests returns an attribute KeyValue conforming to the\n// \"container.image.repo_digests\" semantic conventions. It represents the repo\n// digests of the container image as provided by the container runtime.\nfunc ContainerImageRepoDigests(val ...string) attribute.KeyValue {\n\treturn ContainerImageRepoDigestsKey.StringSlice(val)\n}\n\n// ContainerImageTags returns an attribute KeyValue conforming to the\n// \"container.image.tags\" semantic conventions. It represents the container image\n// tags. An example can be found in [Docker Image Inspect]. Should be only the\n// `<tag>` section of the full name for example from\n// `registry.example.com/my-org/my-image:<tag>`.\n//\n// [Docker Image Inspect]: https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Image/operation/ImageInspect\nfunc ContainerImageTags(val ...string) attribute.KeyValue {\n\treturn ContainerImageTagsKey.StringSlice(val)\n}\n\n// ContainerLabel returns an attribute KeyValue conforming to the\n// \"container.label\" semantic conventions. It represents the container labels,\n// `<key>` being the label name, the value being the label value.\nfunc ContainerLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"container.label.\"+key, val)\n}\n\n// ContainerName returns an attribute KeyValue conforming to the \"container.name\"\n// semantic conventions. It represents the container name used by container\n// runtime.\nfunc ContainerName(val string) attribute.KeyValue {\n\treturn ContainerNameKey.String(val)\n}\n\n// ContainerRuntimeDescription returns an attribute KeyValue conforming to the\n// \"container.runtime.description\" semantic conventions. It represents a\n// description about the runtime which could include, for example details about\n// the CRI/API version being used or other customisations.\nfunc ContainerRuntimeDescription(val string) attribute.KeyValue {\n\treturn ContainerRuntimeDescriptionKey.String(val)\n}\n\n// ContainerRuntimeName returns an attribute KeyValue conforming to the\n// \"container.runtime.name\" semantic conventions. It represents the container\n// runtime managing this container.\nfunc ContainerRuntimeName(val string) attribute.KeyValue {\n\treturn ContainerRuntimeNameKey.String(val)\n}\n\n// ContainerRuntimeVersion returns an attribute KeyValue conforming to the\n// \"container.runtime.version\" semantic conventions. It represents the version of\n// the runtime of this process, as returned by the runtime without modification.\nfunc ContainerRuntimeVersion(val string) attribute.KeyValue {\n\treturn ContainerRuntimeVersionKey.String(val)\n}\n\n// Namespace: cpu\nconst (\n\t// CPULogicalNumberKey is the attribute Key conforming to the\n\t// \"cpu.logical_number\" semantic conventions. It represents the logical CPU\n\t// number [0..n-1].\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1\n\tCPULogicalNumberKey = attribute.Key(\"cpu.logical_number\")\n\n\t// CPUModeKey is the attribute Key conforming to the \"cpu.mode\" semantic\n\t// conventions. It represents the mode of the CPU.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"user\", \"system\"\n\tCPUModeKey = attribute.Key(\"cpu.mode\")\n)\n\n// CPULogicalNumber returns an attribute KeyValue conforming to the\n// \"cpu.logical_number\" semantic conventions. It represents the logical CPU\n// number [0..n-1].\nfunc CPULogicalNumber(val int) attribute.KeyValue {\n\treturn CPULogicalNumberKey.Int(val)\n}\n\n// Enum values for cpu.mode\nvar (\n\t// User\n\t// Stability: development\n\tCPUModeUser = CPUModeKey.String(\"user\")\n\t// System\n\t// Stability: development\n\tCPUModeSystem = CPUModeKey.String(\"system\")\n\t// Nice\n\t// Stability: development\n\tCPUModeNice = CPUModeKey.String(\"nice\")\n\t// Idle\n\t// Stability: development\n\tCPUModeIdle = CPUModeKey.String(\"idle\")\n\t// IO Wait\n\t// Stability: development\n\tCPUModeIOWait = CPUModeKey.String(\"iowait\")\n\t// Interrupt\n\t// Stability: development\n\tCPUModeInterrupt = CPUModeKey.String(\"interrupt\")\n\t// Steal\n\t// Stability: development\n\tCPUModeSteal = CPUModeKey.String(\"steal\")\n\t// Kernel\n\t// Stability: development\n\tCPUModeKernel = CPUModeKey.String(\"kernel\")\n)\n\n// Namespace: db\nconst (\n\t// DBClientConnectionPoolNameKey is the attribute Key conforming to the\n\t// \"db.client.connection.pool.name\" semantic conventions. It represents the name\n\t// of the connection pool; unique within the instrumented application. In case\n\t// the connection pool implementation doesn't provide a name, instrumentation\n\t// SHOULD use a combination of parameters that would make the name unique, for\n\t// example, combining attributes `server.address`, `server.port`, and\n\t// `db.namespace`, formatted as `server.address:server.port/db.namespace`.\n\t// Instrumentations that generate connection pool name following different\n\t// patterns SHOULD document it.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"myDataSource\"\n\tDBClientConnectionPoolNameKey = attribute.Key(\"db.client.connection.pool.name\")\n\n\t// DBClientConnectionStateKey is the attribute Key conforming to the\n\t// \"db.client.connection.state\" semantic conventions. It represents the state of\n\t// a connection in the pool.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"idle\"\n\tDBClientConnectionStateKey = attribute.Key(\"db.client.connection.state\")\n\n\t// DBCollectionNameKey is the attribute Key conforming to the\n\t// \"db.collection.name\" semantic conventions. It represents the name of a\n\t// collection (table, container) within the database.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"public.users\", \"customers\"\n\t// Note: It is RECOMMENDED to capture the value as provided by the application\n\t// without attempting to do any case normalization.\n\t//\n\t// The collection name SHOULD NOT be extracted from `db.query.text`,\n\t// when the database system supports query text with multiple collections\n\t// in non-batch operations.\n\t//\n\t// For batch operations, if the individual operations are known to have the same\n\t// collection name then that collection name SHOULD be used.\n\tDBCollectionNameKey = attribute.Key(\"db.collection.name\")\n\n\t// DBNamespaceKey is the attribute Key conforming to the \"db.namespace\" semantic\n\t// conventions. It represents the name of the database, fully qualified within\n\t// the server address and port.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"customers\", \"test.users\"\n\t// Note: If a database system has multiple namespace components, they SHOULD be\n\t// concatenated from the most general to the most specific namespace component,\n\t// using `|` as a separator between the components. Any missing components (and\n\t// their associated separators) SHOULD be omitted.\n\t// Semantic conventions for individual database systems SHOULD document what\n\t// `db.namespace` means in the context of that system.\n\t// It is RECOMMENDED to capture the value as provided by the application without\n\t// attempting to do any case normalization.\n\tDBNamespaceKey = attribute.Key(\"db.namespace\")\n\n\t// DBOperationBatchSizeKey is the attribute Key conforming to the\n\t// \"db.operation.batch.size\" semantic conventions. It represents the number of\n\t// queries included in a batch operation.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: 2, 3, 4\n\t// Note: Operations are only considered batches when they contain two or more\n\t// operations, and so `db.operation.batch.size` SHOULD never be `1`.\n\tDBOperationBatchSizeKey = attribute.Key(\"db.operation.batch.size\")\n\n\t// DBOperationNameKey is the attribute Key conforming to the \"db.operation.name\"\n\t// semantic conventions. It represents the name of the operation or command\n\t// being executed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"findAndModify\", \"HMSET\", \"SELECT\"\n\t// Note: It is RECOMMENDED to capture the value as provided by the application\n\t// without attempting to do any case normalization.\n\t//\n\t// The operation name SHOULD NOT be extracted from `db.query.text`,\n\t// when the database system supports query text with multiple operations\n\t// in non-batch operations.\n\t//\n\t// If spaces can occur in the operation name, multiple consecutive spaces\n\t// SHOULD be normalized to a single space.\n\t//\n\t// For batch operations, if the individual operations are known to have the same\n\t// operation name\n\t// then that operation name SHOULD be used prepended by `BATCH `,\n\t// otherwise `db.operation.name` SHOULD be `BATCH` or some other database\n\t// system specific term if more applicable.\n\tDBOperationNameKey = attribute.Key(\"db.operation.name\")\n\n\t// DBQuerySummaryKey is the attribute Key conforming to the \"db.query.summary\"\n\t// semantic conventions. It represents the low cardinality summary of a database\n\t// query.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"SELECT wuser_table\", \"INSERT shipping_details SELECT orders\", \"get\n\t// user by id\"\n\t// Note: The query summary describes a class of database queries and is useful\n\t// as a grouping key, especially when analyzing telemetry for database\n\t// calls involving complex queries.\n\t//\n\t// Summary may be available to the instrumentation through\n\t// instrumentation hooks or other means. If it is not available,\n\t// instrumentations\n\t// that support query parsing SHOULD generate a summary following\n\t// [Generating query summary]\n\t// section.\n\t//\n\t// [Generating query summary]: /docs/db/database-spans.md#generating-a-summary-of-the-query\n\tDBQuerySummaryKey = attribute.Key(\"db.query.summary\")\n\n\t// DBQueryTextKey is the attribute Key conforming to the \"db.query.text\"\n\t// semantic conventions. It represents the database query being executed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"SELECT * FROM wuser_table where username = ?\", \"SET mykey ?\"\n\t// Note: For sanitization see [Sanitization of `db.query.text`].\n\t// For batch operations, if the individual operations are known to have the same\n\t// query text then that query text SHOULD be used, otherwise all of the\n\t// individual query texts SHOULD be concatenated with separator `; ` or some\n\t// other database system specific separator if more applicable.\n\t// Parameterized query text SHOULD NOT be sanitized. Even though parameterized\n\t// query text can potentially have sensitive data, by using a parameterized\n\t// query the user is giving a strong signal that any sensitive data will be\n\t// passed as parameter values, and the benefit to observability of capturing the\n\t// static part of the query text by default outweighs the risk.\n\t//\n\t// [Sanitization of `db.query.text`]: /docs/db/database-spans.md#sanitization-of-dbquerytext\n\tDBQueryTextKey = attribute.Key(\"db.query.text\")\n\n\t// DBResponseReturnedRowsKey is the attribute Key conforming to the\n\t// \"db.response.returned_rows\" semantic conventions. It represents the number of\n\t// rows returned by the operation.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 10, 30, 1000\n\tDBResponseReturnedRowsKey = attribute.Key(\"db.response.returned_rows\")\n\n\t// DBResponseStatusCodeKey is the attribute Key conforming to the\n\t// \"db.response.status_code\" semantic conventions. It represents the database\n\t// response status code.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"102\", \"ORA-17002\", \"08P01\", \"404\"\n\t// Note: The status code returned by the database. Usually it represents an\n\t// error code, but may also represent partial success, warning, or differentiate\n\t// between various types of successful outcomes.\n\t// Semantic conventions for individual database systems SHOULD document what\n\t// `db.response.status_code` means in the context of that system.\n\tDBResponseStatusCodeKey = attribute.Key(\"db.response.status_code\")\n\n\t// DBStoredProcedureNameKey is the attribute Key conforming to the\n\t// \"db.stored_procedure.name\" semantic conventions. It represents the name of a\n\t// stored procedure within the database.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"GetCustomer\"\n\t// Note: It is RECOMMENDED to capture the value as provided by the application\n\t// without attempting to do any case normalization.\n\t//\n\t// For batch operations, if the individual operations are known to have the same\n\t// stored procedure name then that stored procedure name SHOULD be used.\n\tDBStoredProcedureNameKey = attribute.Key(\"db.stored_procedure.name\")\n\n\t// DBSystemNameKey is the attribute Key conforming to the \"db.system.name\"\n\t// semantic conventions. It represents the database management system (DBMS)\n\t// product as identified by the client instrumentation.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples:\n\t// Note: The actual DBMS may differ from the one identified by the client. For\n\t// example, when using PostgreSQL client libraries to connect to a CockroachDB,\n\t// the `db.system.name` is set to `postgresql` based on the instrumentation's\n\t// best knowledge.\n\tDBSystemNameKey = attribute.Key(\"db.system.name\")\n)\n\n// DBClientConnectionPoolName returns an attribute KeyValue conforming to the\n// \"db.client.connection.pool.name\" semantic conventions. It represents the name\n// of the connection pool; unique within the instrumented application. In case\n// the connection pool implementation doesn't provide a name, instrumentation\n// SHOULD use a combination of parameters that would make the name unique, for\n// example, combining attributes `server.address`, `server.port`, and\n// `db.namespace`, formatted as `server.address:server.port/db.namespace`.\n// Instrumentations that generate connection pool name following different\n// patterns SHOULD document it.\nfunc DBClientConnectionPoolName(val string) attribute.KeyValue {\n\treturn DBClientConnectionPoolNameKey.String(val)\n}\n\n// DBCollectionName returns an attribute KeyValue conforming to the\n// \"db.collection.name\" semantic conventions. It represents the name of a\n// collection (table, container) within the database.\nfunc DBCollectionName(val string) attribute.KeyValue {\n\treturn DBCollectionNameKey.String(val)\n}\n\n// DBNamespace returns an attribute KeyValue conforming to the \"db.namespace\"\n// semantic conventions. It represents the name of the database, fully qualified\n// within the server address and port.\nfunc DBNamespace(val string) attribute.KeyValue {\n\treturn DBNamespaceKey.String(val)\n}\n\n// DBOperationBatchSize returns an attribute KeyValue conforming to the\n// \"db.operation.batch.size\" semantic conventions. It represents the number of\n// queries included in a batch operation.\nfunc DBOperationBatchSize(val int) attribute.KeyValue {\n\treturn DBOperationBatchSizeKey.Int(val)\n}\n\n// DBOperationName returns an attribute KeyValue conforming to the\n// \"db.operation.name\" semantic conventions. It represents the name of the\n// operation or command being executed.\nfunc DBOperationName(val string) attribute.KeyValue {\n\treturn DBOperationNameKey.String(val)\n}\n\n// DBOperationParameter returns an attribute KeyValue conforming to the\n// \"db.operation.parameter\" semantic conventions. It represents a database\n// operation parameter, with `<key>` being the parameter name, and the attribute\n// value being a string representation of the parameter value.\nfunc DBOperationParameter(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"db.operation.parameter.\"+key, val)\n}\n\n// DBQueryParameter returns an attribute KeyValue conforming to the\n// \"db.query.parameter\" semantic conventions. It represents a database query\n// parameter, with `<key>` being the parameter name, and the attribute value\n// being a string representation of the parameter value.\nfunc DBQueryParameter(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"db.query.parameter.\"+key, val)\n}\n\n// DBQuerySummary returns an attribute KeyValue conforming to the\n// \"db.query.summary\" semantic conventions. It represents the low cardinality\n// summary of a database query.\nfunc DBQuerySummary(val string) attribute.KeyValue {\n\treturn DBQuerySummaryKey.String(val)\n}\n\n// DBQueryText returns an attribute KeyValue conforming to the \"db.query.text\"\n// semantic conventions. It represents the database query being executed.\nfunc DBQueryText(val string) attribute.KeyValue {\n\treturn DBQueryTextKey.String(val)\n}\n\n// DBResponseReturnedRows returns an attribute KeyValue conforming to the\n// \"db.response.returned_rows\" semantic conventions. It represents the number of\n// rows returned by the operation.\nfunc DBResponseReturnedRows(val int) attribute.KeyValue {\n\treturn DBResponseReturnedRowsKey.Int(val)\n}\n\n// DBResponseStatusCode returns an attribute KeyValue conforming to the\n// \"db.response.status_code\" semantic conventions. It represents the database\n// response status code.\nfunc DBResponseStatusCode(val string) attribute.KeyValue {\n\treturn DBResponseStatusCodeKey.String(val)\n}\n\n// DBStoredProcedureName returns an attribute KeyValue conforming to the\n// \"db.stored_procedure.name\" semantic conventions. It represents the name of a\n// stored procedure within the database.\nfunc DBStoredProcedureName(val string) attribute.KeyValue {\n\treturn DBStoredProcedureNameKey.String(val)\n}\n\n// Enum values for db.client.connection.state\nvar (\n\t// idle\n\t// Stability: development\n\tDBClientConnectionStateIdle = DBClientConnectionStateKey.String(\"idle\")\n\t// used\n\t// Stability: development\n\tDBClientConnectionStateUsed = DBClientConnectionStateKey.String(\"used\")\n)\n\n// Enum values for db.system.name\nvar (\n\t// Some other SQL database. Fallback only.\n\t// Stability: development\n\tDBSystemNameOtherSQL = DBSystemNameKey.String(\"other_sql\")\n\t// [Adabas (Adaptable Database System)]\n\t// Stability: development\n\t//\n\t// [Adabas (Adaptable Database System)]: https://documentation.softwareag.com/?pf=adabas\n\tDBSystemNameSoftwareagAdabas = DBSystemNameKey.String(\"softwareag.adabas\")\n\t// [Actian Ingres]\n\t// Stability: development\n\t//\n\t// [Actian Ingres]: https://www.actian.com/databases/ingres/\n\tDBSystemNameActianIngres = DBSystemNameKey.String(\"actian.ingres\")\n\t// [Amazon DynamoDB]\n\t// Stability: development\n\t//\n\t// [Amazon DynamoDB]: https://aws.amazon.com/pm/dynamodb/\n\tDBSystemNameAWSDynamoDB = DBSystemNameKey.String(\"aws.dynamodb\")\n\t// [Amazon Redshift]\n\t// Stability: development\n\t//\n\t// [Amazon Redshift]: https://aws.amazon.com/redshift/\n\tDBSystemNameAWSRedshift = DBSystemNameKey.String(\"aws.redshift\")\n\t// [Azure Cosmos DB]\n\t// Stability: development\n\t//\n\t// [Azure Cosmos DB]: https://learn.microsoft.com/azure/cosmos-db\n\tDBSystemNameAzureCosmosDB = DBSystemNameKey.String(\"azure.cosmosdb\")\n\t// [InterSystems Caché]\n\t// Stability: development\n\t//\n\t// [InterSystems Caché]: https://www.intersystems.com/products/cache/\n\tDBSystemNameIntersystemsCache = DBSystemNameKey.String(\"intersystems.cache\")\n\t// [Apache Cassandra]\n\t// Stability: development\n\t//\n\t// [Apache Cassandra]: https://cassandra.apache.org/\n\tDBSystemNameCassandra = DBSystemNameKey.String(\"cassandra\")\n\t// [ClickHouse]\n\t// Stability: development\n\t//\n\t// [ClickHouse]: https://clickhouse.com/\n\tDBSystemNameClickHouse = DBSystemNameKey.String(\"clickhouse\")\n\t// [CockroachDB]\n\t// Stability: development\n\t//\n\t// [CockroachDB]: https://www.cockroachlabs.com/\n\tDBSystemNameCockroachDB = DBSystemNameKey.String(\"cockroachdb\")\n\t// [Couchbase]\n\t// Stability: development\n\t//\n\t// [Couchbase]: https://www.couchbase.com/\n\tDBSystemNameCouchbase = DBSystemNameKey.String(\"couchbase\")\n\t// [Apache CouchDB]\n\t// Stability: development\n\t//\n\t// [Apache CouchDB]: https://couchdb.apache.org/\n\tDBSystemNameCouchDB = DBSystemNameKey.String(\"couchdb\")\n\t// [Apache Derby]\n\t// Stability: development\n\t//\n\t// [Apache Derby]: https://db.apache.org/derby/\n\tDBSystemNameDerby = DBSystemNameKey.String(\"derby\")\n\t// [Elasticsearch]\n\t// Stability: development\n\t//\n\t// [Elasticsearch]: https://www.elastic.co/elasticsearch\n\tDBSystemNameElasticsearch = DBSystemNameKey.String(\"elasticsearch\")\n\t// [Firebird]\n\t// Stability: development\n\t//\n\t// [Firebird]: https://www.firebirdsql.org/\n\tDBSystemNameFirebirdSQL = DBSystemNameKey.String(\"firebirdsql\")\n\t// [Google Cloud Spanner]\n\t// Stability: development\n\t//\n\t// [Google Cloud Spanner]: https://cloud.google.com/spanner\n\tDBSystemNameGCPSpanner = DBSystemNameKey.String(\"gcp.spanner\")\n\t// [Apache Geode]\n\t// Stability: development\n\t//\n\t// [Apache Geode]: https://geode.apache.org/\n\tDBSystemNameGeode = DBSystemNameKey.String(\"geode\")\n\t// [H2 Database]\n\t// Stability: development\n\t//\n\t// [H2 Database]: https://h2database.com/\n\tDBSystemNameH2database = DBSystemNameKey.String(\"h2database\")\n\t// [Apache HBase]\n\t// Stability: development\n\t//\n\t// [Apache HBase]: https://hbase.apache.org/\n\tDBSystemNameHBase = DBSystemNameKey.String(\"hbase\")\n\t// [Apache Hive]\n\t// Stability: development\n\t//\n\t// [Apache Hive]: https://hive.apache.org/\n\tDBSystemNameHive = DBSystemNameKey.String(\"hive\")\n\t// [HyperSQL Database]\n\t// Stability: development\n\t//\n\t// [HyperSQL Database]: https://hsqldb.org/\n\tDBSystemNameHSQLDB = DBSystemNameKey.String(\"hsqldb\")\n\t// [IBM Db2]\n\t// Stability: development\n\t//\n\t// [IBM Db2]: https://www.ibm.com/db2\n\tDBSystemNameIBMDB2 = DBSystemNameKey.String(\"ibm.db2\")\n\t// [IBM Informix]\n\t// Stability: development\n\t//\n\t// [IBM Informix]: https://www.ibm.com/products/informix\n\tDBSystemNameIBMInformix = DBSystemNameKey.String(\"ibm.informix\")\n\t// [IBM Netezza]\n\t// Stability: development\n\t//\n\t// [IBM Netezza]: https://www.ibm.com/products/netezza\n\tDBSystemNameIBMNetezza = DBSystemNameKey.String(\"ibm.netezza\")\n\t// [InfluxDB]\n\t// Stability: development\n\t//\n\t// [InfluxDB]: https://www.influxdata.com/\n\tDBSystemNameInfluxDB = DBSystemNameKey.String(\"influxdb\")\n\t// [Instant]\n\t// Stability: development\n\t//\n\t// [Instant]: https://www.instantdb.com/\n\tDBSystemNameInstantDB = DBSystemNameKey.String(\"instantdb\")\n\t// [MariaDB]\n\t// Stability: stable\n\t//\n\t// [MariaDB]: https://mariadb.org/\n\tDBSystemNameMariaDB = DBSystemNameKey.String(\"mariadb\")\n\t// [Memcached]\n\t// Stability: development\n\t//\n\t// [Memcached]: https://memcached.org/\n\tDBSystemNameMemcached = DBSystemNameKey.String(\"memcached\")\n\t// [MongoDB]\n\t// Stability: development\n\t//\n\t// [MongoDB]: https://www.mongodb.com/\n\tDBSystemNameMongoDB = DBSystemNameKey.String(\"mongodb\")\n\t// [Microsoft SQL Server]\n\t// Stability: stable\n\t//\n\t// [Microsoft SQL Server]: https://www.microsoft.com/sql-server\n\tDBSystemNameMicrosoftSQLServer = DBSystemNameKey.String(\"microsoft.sql_server\")\n\t// [MySQL]\n\t// Stability: stable\n\t//\n\t// [MySQL]: https://www.mysql.com/\n\tDBSystemNameMySQL = DBSystemNameKey.String(\"mysql\")\n\t// [Neo4j]\n\t// Stability: development\n\t//\n\t// [Neo4j]: https://neo4j.com/\n\tDBSystemNameNeo4j = DBSystemNameKey.String(\"neo4j\")\n\t// [OpenSearch]\n\t// Stability: development\n\t//\n\t// [OpenSearch]: https://opensearch.org/\n\tDBSystemNameOpenSearch = DBSystemNameKey.String(\"opensearch\")\n\t// [Oracle Database]\n\t// Stability: development\n\t//\n\t// [Oracle Database]: https://www.oracle.com/database/\n\tDBSystemNameOracleDB = DBSystemNameKey.String(\"oracle.db\")\n\t// [PostgreSQL]\n\t// Stability: stable\n\t//\n\t// [PostgreSQL]: https://www.postgresql.org/\n\tDBSystemNamePostgreSQL = DBSystemNameKey.String(\"postgresql\")\n\t// [Redis]\n\t// Stability: development\n\t//\n\t// [Redis]: https://redis.io/\n\tDBSystemNameRedis = DBSystemNameKey.String(\"redis\")\n\t// [SAP HANA]\n\t// Stability: development\n\t//\n\t// [SAP HANA]: https://www.sap.com/products/technology-platform/hana/what-is-sap-hana.html\n\tDBSystemNameSAPHANA = DBSystemNameKey.String(\"sap.hana\")\n\t// [SAP MaxDB]\n\t// Stability: development\n\t//\n\t// [SAP MaxDB]: https://maxdb.sap.com/\n\tDBSystemNameSAPMaxDB = DBSystemNameKey.String(\"sap.maxdb\")\n\t// [SQLite]\n\t// Stability: development\n\t//\n\t// [SQLite]: https://www.sqlite.org/\n\tDBSystemNameSQLite = DBSystemNameKey.String(\"sqlite\")\n\t// [Teradata]\n\t// Stability: development\n\t//\n\t// [Teradata]: https://www.teradata.com/\n\tDBSystemNameTeradata = DBSystemNameKey.String(\"teradata\")\n\t// [Trino]\n\t// Stability: development\n\t//\n\t// [Trino]: https://trino.io/\n\tDBSystemNameTrino = DBSystemNameKey.String(\"trino\")\n)\n\n// Namespace: deployment\nconst (\n\t// DeploymentEnvironmentNameKey is the attribute Key conforming to the\n\t// \"deployment.environment.name\" semantic conventions. It represents the name of\n\t// the [deployment environment] (aka deployment tier).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"staging\", \"production\"\n\t// Note: `deployment.environment.name` does not affect the uniqueness\n\t// constraints defined through\n\t// the `service.namespace`, `service.name` and `service.instance.id` resource\n\t// attributes.\n\t// This implies that resources carrying the following attribute combinations\n\t// MUST be\n\t// considered to be identifying the same service:\n\t//\n\t//   - `service.name=frontend`, `deployment.environment.name=production`\n\t//   - `service.name=frontend`, `deployment.environment.name=staging`.\n\t//\n\t//\n\t// [deployment environment]: https://wikipedia.org/wiki/Deployment_environment\n\tDeploymentEnvironmentNameKey = attribute.Key(\"deployment.environment.name\")\n\n\t// DeploymentIDKey is the attribute Key conforming to the \"deployment.id\"\n\t// semantic conventions. It represents the id of the deployment.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1208\"\n\tDeploymentIDKey = attribute.Key(\"deployment.id\")\n\n\t// DeploymentNameKey is the attribute Key conforming to the \"deployment.name\"\n\t// semantic conventions. It represents the name of the deployment.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"deploy my app\", \"deploy-frontend\"\n\tDeploymentNameKey = attribute.Key(\"deployment.name\")\n\n\t// DeploymentStatusKey is the attribute Key conforming to the\n\t// \"deployment.status\" semantic conventions. It represents the status of the\n\t// deployment.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tDeploymentStatusKey = attribute.Key(\"deployment.status\")\n)\n\n// DeploymentEnvironmentName returns an attribute KeyValue conforming to the\n// \"deployment.environment.name\" semantic conventions. It represents the name of\n// the [deployment environment] (aka deployment tier).\n//\n// [deployment environment]: https://wikipedia.org/wiki/Deployment_environment\nfunc DeploymentEnvironmentName(val string) attribute.KeyValue {\n\treturn DeploymentEnvironmentNameKey.String(val)\n}\n\n// DeploymentID returns an attribute KeyValue conforming to the \"deployment.id\"\n// semantic conventions. It represents the id of the deployment.\nfunc DeploymentID(val string) attribute.KeyValue {\n\treturn DeploymentIDKey.String(val)\n}\n\n// DeploymentName returns an attribute KeyValue conforming to the\n// \"deployment.name\" semantic conventions. It represents the name of the\n// deployment.\nfunc DeploymentName(val string) attribute.KeyValue {\n\treturn DeploymentNameKey.String(val)\n}\n\n// Enum values for deployment.status\nvar (\n\t// failed\n\t// Stability: development\n\tDeploymentStatusFailed = DeploymentStatusKey.String(\"failed\")\n\t// succeeded\n\t// Stability: development\n\tDeploymentStatusSucceeded = DeploymentStatusKey.String(\"succeeded\")\n)\n\n// Namespace: destination\nconst (\n\t// DestinationAddressKey is the attribute Key conforming to the\n\t// \"destination.address\" semantic conventions. It represents the destination\n\t// address - domain name if available without reverse DNS lookup; otherwise, IP\n\t// address or Unix domain socket name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"destination.example.com\", \"10.1.2.80\", \"/tmp/my.sock\"\n\t// Note: When observed from the source side, and when communicating through an\n\t// intermediary, `destination.address` SHOULD represent the destination address\n\t// behind any intermediaries, for example proxies, if it's available.\n\tDestinationAddressKey = attribute.Key(\"destination.address\")\n\n\t// DestinationPortKey is the attribute Key conforming to the \"destination.port\"\n\t// semantic conventions. It represents the destination port number.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 3389, 2888\n\tDestinationPortKey = attribute.Key(\"destination.port\")\n)\n\n// DestinationAddress returns an attribute KeyValue conforming to the\n// \"destination.address\" semantic conventions. It represents the destination\n// address - domain name if available without reverse DNS lookup; otherwise, IP\n// address or Unix domain socket name.\nfunc DestinationAddress(val string) attribute.KeyValue {\n\treturn DestinationAddressKey.String(val)\n}\n\n// DestinationPort returns an attribute KeyValue conforming to the\n// \"destination.port\" semantic conventions. It represents the destination port\n// number.\nfunc DestinationPort(val int) attribute.KeyValue {\n\treturn DestinationPortKey.Int(val)\n}\n\n// Namespace: device\nconst (\n\t// DeviceIDKey is the attribute Key conforming to the \"device.id\" semantic\n\t// conventions. It represents a unique identifier representing the device.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"123456789012345\", \"01:23:45:67:89:AB\"\n\t// Note: Its value SHOULD be identical for all apps on a device and it SHOULD\n\t// NOT change if an app is uninstalled and re-installed.\n\t// However, it might be resettable by the user for all apps on a device.\n\t// Hardware IDs (e.g. vendor-specific serial number, IMEI or MAC address) MAY be\n\t// used as values.\n\t//\n\t// More information about Android identifier best practices can be found in the\n\t// [Android user data IDs guide].\n\t//\n\t// > [!WARNING]> This attribute may contain sensitive (PII) information. Caution\n\t// > should be taken when storing personal data or anything which can identify a\n\t// > user. GDPR and data protection laws may apply,\n\t// > ensure you do your own due diligence.> Due to these reasons, this\n\t// > identifier is not recommended for consumer applications and will likely\n\t// > result in rejection from both Google Play and App Store.\n\t// > However, it may be appropriate for specific enterprise scenarios, such as\n\t// > kiosk devices or enterprise-managed devices, with appropriate compliance\n\t// > clearance.\n\t// > Any instrumentation providing this identifier MUST implement it as an\n\t// > opt-in feature.> See [`app.installation.id`]>  for a more\n\t// > privacy-preserving alternative.\n\t//\n\t// [Android user data IDs guide]: https://developer.android.com/training/articles/user-data-ids\n\t// [`app.installation.id`]: /docs/registry/attributes/app.md#app-installation-id\n\tDeviceIDKey = attribute.Key(\"device.id\")\n\n\t// DeviceManufacturerKey is the attribute Key conforming to the\n\t// \"device.manufacturer\" semantic conventions. It represents the name of the\n\t// device manufacturer.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Apple\", \"Samsung\"\n\t// Note: The Android OS provides this field via [Build]. iOS apps SHOULD\n\t// hardcode the value `Apple`.\n\t//\n\t// [Build]: https://developer.android.com/reference/android/os/Build#MANUFACTURER\n\tDeviceManufacturerKey = attribute.Key(\"device.manufacturer\")\n\n\t// DeviceModelIdentifierKey is the attribute Key conforming to the\n\t// \"device.model.identifier\" semantic conventions. It represents the model\n\t// identifier for the device.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"iPhone3,4\", \"SM-G920F\"\n\t// Note: It's recommended this value represents a machine-readable version of\n\t// the model identifier rather than the market or consumer-friendly name of the\n\t// device.\n\tDeviceModelIdentifierKey = attribute.Key(\"device.model.identifier\")\n\n\t// DeviceModelNameKey is the attribute Key conforming to the \"device.model.name\"\n\t// semantic conventions. It represents the marketing name for the device model.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"iPhone 6s Plus\", \"Samsung Galaxy S6\"\n\t// Note: It's recommended this value represents a human-readable version of the\n\t// device model rather than a machine-readable alternative.\n\tDeviceModelNameKey = attribute.Key(\"device.model.name\")\n)\n\n// DeviceID returns an attribute KeyValue conforming to the \"device.id\" semantic\n// conventions. It represents a unique identifier representing the device.\nfunc DeviceID(val string) attribute.KeyValue {\n\treturn DeviceIDKey.String(val)\n}\n\n// DeviceManufacturer returns an attribute KeyValue conforming to the\n// \"device.manufacturer\" semantic conventions. It represents the name of the\n// device manufacturer.\nfunc DeviceManufacturer(val string) attribute.KeyValue {\n\treturn DeviceManufacturerKey.String(val)\n}\n\n// DeviceModelIdentifier returns an attribute KeyValue conforming to the\n// \"device.model.identifier\" semantic conventions. It represents the model\n// identifier for the device.\nfunc DeviceModelIdentifier(val string) attribute.KeyValue {\n\treturn DeviceModelIdentifierKey.String(val)\n}\n\n// DeviceModelName returns an attribute KeyValue conforming to the\n// \"device.model.name\" semantic conventions. It represents the marketing name for\n// the device model.\nfunc DeviceModelName(val string) attribute.KeyValue {\n\treturn DeviceModelNameKey.String(val)\n}\n\n// Namespace: disk\nconst (\n\t// DiskIODirectionKey is the attribute Key conforming to the \"disk.io.direction\"\n\t// semantic conventions. It represents the disk IO operation direction.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"read\"\n\tDiskIODirectionKey = attribute.Key(\"disk.io.direction\")\n)\n\n// Enum values for disk.io.direction\nvar (\n\t// read\n\t// Stability: development\n\tDiskIODirectionRead = DiskIODirectionKey.String(\"read\")\n\t// write\n\t// Stability: development\n\tDiskIODirectionWrite = DiskIODirectionKey.String(\"write\")\n)\n\n// Namespace: dns\nconst (\n\t// DNSAnswersKey is the attribute Key conforming to the \"dns.answers\" semantic\n\t// conventions. It represents the list of IPv4 or IPv6 addresses resolved during\n\t// DNS lookup.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"10.0.0.1\", \"2001:0db8:85a3:0000:0000:8a2e:0370:7334\"\n\tDNSAnswersKey = attribute.Key(\"dns.answers\")\n\n\t// DNSQuestionNameKey is the attribute Key conforming to the \"dns.question.name\"\n\t// semantic conventions. It represents the name being queried.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"www.example.com\", \"opentelemetry.io\"\n\t// Note: The name represents the queried domain name as it appears in the DNS\n\t// query without any additional normalization.\n\tDNSQuestionNameKey = attribute.Key(\"dns.question.name\")\n)\n\n// DNSAnswers returns an attribute KeyValue conforming to the \"dns.answers\"\n// semantic conventions. It represents the list of IPv4 or IPv6 addresses\n// resolved during DNS lookup.\nfunc DNSAnswers(val ...string) attribute.KeyValue {\n\treturn DNSAnswersKey.StringSlice(val)\n}\n\n// DNSQuestionName returns an attribute KeyValue conforming to the\n// \"dns.question.name\" semantic conventions. It represents the name being\n// queried.\nfunc DNSQuestionName(val string) attribute.KeyValue {\n\treturn DNSQuestionNameKey.String(val)\n}\n\n// Namespace: elasticsearch\nconst (\n\t// ElasticsearchNodeNameKey is the attribute Key conforming to the\n\t// \"elasticsearch.node.name\" semantic conventions. It represents the represents\n\t// the human-readable identifier of the node/instance to which a request was\n\t// routed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"instance-0000000001\"\n\tElasticsearchNodeNameKey = attribute.Key(\"elasticsearch.node.name\")\n)\n\n// ElasticsearchNodeName returns an attribute KeyValue conforming to the\n// \"elasticsearch.node.name\" semantic conventions. It represents the represents\n// the human-readable identifier of the node/instance to which a request was\n// routed.\nfunc ElasticsearchNodeName(val string) attribute.KeyValue {\n\treturn ElasticsearchNodeNameKey.String(val)\n}\n\n// Namespace: enduser\nconst (\n\t// EnduserIDKey is the attribute Key conforming to the \"enduser.id\" semantic\n\t// conventions. It represents the unique identifier of an end user in the\n\t// system. It maybe a username, email address, or other identifier.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"username\"\n\t// Note: Unique identifier of an end user in the system.\n\t//\n\t// > [!Warning]\n\t// > This field contains sensitive (PII) information.\n\tEnduserIDKey = attribute.Key(\"enduser.id\")\n\n\t// EnduserPseudoIDKey is the attribute Key conforming to the \"enduser.pseudo.id\"\n\t// semantic conventions. It represents the pseudonymous identifier of an end\n\t// user. This identifier should be a random value that is not directly linked or\n\t// associated with the end user's actual identity.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"QdH5CAWJgqVT4rOr0qtumf\"\n\t// Note: Pseudonymous identifier of an end user.\n\t//\n\t// > [!Warning]\n\t// > This field contains sensitive (linkable PII) information.\n\tEnduserPseudoIDKey = attribute.Key(\"enduser.pseudo.id\")\n)\n\n// EnduserID returns an attribute KeyValue conforming to the \"enduser.id\"\n// semantic conventions. It represents the unique identifier of an end user in\n// the system. It maybe a username, email address, or other identifier.\nfunc EnduserID(val string) attribute.KeyValue {\n\treturn EnduserIDKey.String(val)\n}\n\n// EnduserPseudoID returns an attribute KeyValue conforming to the\n// \"enduser.pseudo.id\" semantic conventions. It represents the pseudonymous\n// identifier of an end user. This identifier should be a random value that is\n// not directly linked or associated with the end user's actual identity.\nfunc EnduserPseudoID(val string) attribute.KeyValue {\n\treturn EnduserPseudoIDKey.String(val)\n}\n\n// Namespace: error\nconst (\n\t// ErrorMessageKey is the attribute Key conforming to the \"error.message\"\n\t// semantic conventions. It represents a message providing more detail about an\n\t// error in human-readable form.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Unexpected input type: string\", \"The user has exceeded their\n\t// storage quota\"\n\t// Note: `error.message` should provide additional context and detail about an\n\t// error.\n\t// It is NOT RECOMMENDED to duplicate the value of `error.type` in\n\t// `error.message`.\n\t// It is also NOT RECOMMENDED to duplicate the value of `exception.message` in\n\t// `error.message`.\n\t//\n\t// `error.message` is NOT RECOMMENDED for metrics or spans due to its unbounded\n\t// cardinality and overlap with span status.\n\tErrorMessageKey = attribute.Key(\"error.message\")\n\n\t// ErrorTypeKey is the attribute Key conforming to the \"error.type\" semantic\n\t// conventions. It represents the describes a class of error the operation ended\n\t// with.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"timeout\", \"java.net.UnknownHostException\",\n\t// \"server_certificate_invalid\", \"500\"\n\t// Note: The `error.type` SHOULD be predictable, and SHOULD have low\n\t// cardinality.\n\t//\n\t// When `error.type` is set to a type (e.g., an exception type), its\n\t// canonical class name identifying the type within the artifact SHOULD be used.\n\t//\n\t// Instrumentations SHOULD document the list of errors they report.\n\t//\n\t// The cardinality of `error.type` within one instrumentation library SHOULD be\n\t// low.\n\t// Telemetry consumers that aggregate data from multiple instrumentation\n\t// libraries and applications\n\t// should be prepared for `error.type` to have high cardinality at query time\n\t// when no\n\t// additional filters are applied.\n\t//\n\t// If the operation has completed successfully, instrumentations SHOULD NOT set\n\t// `error.type`.\n\t//\n\t// If a specific domain defines its own set of error identifiers (such as HTTP\n\t// or RPC status codes),\n\t// it's RECOMMENDED to:\n\t//\n\t//   - Use a domain-specific attribute\n\t//   - Set `error.type` to capture all errors, regardless of whether they are\n\t//     defined within the domain-specific set or not.\n\tErrorTypeKey = attribute.Key(\"error.type\")\n)\n\n// ErrorMessage returns an attribute KeyValue conforming to the \"error.message\"\n// semantic conventions. It represents a message providing more detail about an\n// error in human-readable form.\nfunc ErrorMessage(val string) attribute.KeyValue {\n\treturn ErrorMessageKey.String(val)\n}\n\n// Enum values for error.type\nvar (\n\t// A fallback error value to be used when the instrumentation doesn't define a\n\t// custom value.\n\t//\n\t// Stability: stable\n\tErrorTypeOther = ErrorTypeKey.String(\"_OTHER\")\n)\n\n// Namespace: exception\nconst (\n\t// ExceptionMessageKey is the attribute Key conforming to the\n\t// \"exception.message\" semantic conventions. It represents the exception\n\t// message.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"Division by zero\", \"Can't convert 'int' object to str implicitly\"\n\tExceptionMessageKey = attribute.Key(\"exception.message\")\n\n\t// ExceptionStacktraceKey is the attribute Key conforming to the\n\t// \"exception.stacktrace\" semantic conventions. It represents a stacktrace as a\n\t// string in the natural representation for the language runtime. The\n\t// representation is to be determined and documented by each language SIG.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: Exception in thread \"main\" java.lang.RuntimeException: Test\n\t// exception\\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\\n at\n\t// com.example.GenerateTrace.methodA(GenerateTrace.java:9)\\n at\n\t// com.example.GenerateTrace.main(GenerateTrace.java:5)\n\tExceptionStacktraceKey = attribute.Key(\"exception.stacktrace\")\n\n\t// ExceptionTypeKey is the attribute Key conforming to the \"exception.type\"\n\t// semantic conventions. It represents the type of the exception (its\n\t// fully-qualified class name, if applicable). The dynamic type of the exception\n\t// should be preferred over the static type in languages that support it.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"java.net.ConnectException\", \"OSError\"\n\tExceptionTypeKey = attribute.Key(\"exception.type\")\n)\n\n// ExceptionMessage returns an attribute KeyValue conforming to the\n// \"exception.message\" semantic conventions. It represents the exception message.\nfunc ExceptionMessage(val string) attribute.KeyValue {\n\treturn ExceptionMessageKey.String(val)\n}\n\n// ExceptionStacktrace returns an attribute KeyValue conforming to the\n// \"exception.stacktrace\" semantic conventions. It represents a stacktrace as a\n// string in the natural representation for the language runtime. The\n// representation is to be determined and documented by each language SIG.\nfunc ExceptionStacktrace(val string) attribute.KeyValue {\n\treturn ExceptionStacktraceKey.String(val)\n}\n\n// ExceptionType returns an attribute KeyValue conforming to the \"exception.type\"\n// semantic conventions. It represents the type of the exception (its\n// fully-qualified class name, if applicable). The dynamic type of the exception\n// should be preferred over the static type in languages that support it.\nfunc ExceptionType(val string) attribute.KeyValue {\n\treturn ExceptionTypeKey.String(val)\n}\n\n// Namespace: faas\nconst (\n\t// FaaSColdstartKey is the attribute Key conforming to the \"faas.coldstart\"\n\t// semantic conventions. It represents a boolean that is true if the serverless\n\t// function is executed for the first time (aka cold-start).\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tFaaSColdstartKey = attribute.Key(\"faas.coldstart\")\n\n\t// FaaSCronKey is the attribute Key conforming to the \"faas.cron\" semantic\n\t// conventions. It represents a string containing the schedule period as\n\t// [Cron Expression].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0/5 * * * ? *\n\t//\n\t// [Cron Expression]: https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm\n\tFaaSCronKey = attribute.Key(\"faas.cron\")\n\n\t// FaaSDocumentCollectionKey is the attribute Key conforming to the\n\t// \"faas.document.collection\" semantic conventions. It represents the name of\n\t// the source on which the triggering operation was performed. For example, in\n\t// Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the\n\t// database name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"myBucketName\", \"myDbName\"\n\tFaaSDocumentCollectionKey = attribute.Key(\"faas.document.collection\")\n\n\t// FaaSDocumentNameKey is the attribute Key conforming to the\n\t// \"faas.document.name\" semantic conventions. It represents the document\n\t// name/table subjected to the operation. For example, in Cloud Storage or S3 is\n\t// the name of the file, and in Cosmos DB the table name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"myFile.txt\", \"myTableName\"\n\tFaaSDocumentNameKey = attribute.Key(\"faas.document.name\")\n\n\t// FaaSDocumentOperationKey is the attribute Key conforming to the\n\t// \"faas.document.operation\" semantic conventions. It represents the describes\n\t// the type of the operation that was performed on the data.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tFaaSDocumentOperationKey = attribute.Key(\"faas.document.operation\")\n\n\t// FaaSDocumentTimeKey is the attribute Key conforming to the\n\t// \"faas.document.time\" semantic conventions. It represents a string containing\n\t// the time when the data was accessed in the [ISO 8601] format expressed in\n\t// [UTC].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 2020-01-23T13:47:06Z\n\t//\n\t// [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html\n\t// [UTC]: https://www.w3.org/TR/NOTE-datetime\n\tFaaSDocumentTimeKey = attribute.Key(\"faas.document.time\")\n\n\t// FaaSInstanceKey is the attribute Key conforming to the \"faas.instance\"\n\t// semantic conventions. It represents the execution environment ID as a string,\n\t// that will be potentially reused for other invocations to the same\n\t// function/function version.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de\"\n\t// Note: - **AWS Lambda:** Use the (full) log stream name.\n\tFaaSInstanceKey = attribute.Key(\"faas.instance\")\n\n\t// FaaSInvocationIDKey is the attribute Key conforming to the\n\t// \"faas.invocation_id\" semantic conventions. It represents the invocation ID of\n\t// the current function invocation.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: af9d5aa4-a685-4c5f-a22b-444f80b3cc28\n\tFaaSInvocationIDKey = attribute.Key(\"faas.invocation_id\")\n\n\t// FaaSInvokedNameKey is the attribute Key conforming to the \"faas.invoked_name\"\n\t// semantic conventions. It represents the name of the invoked function.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: my-function\n\t// Note: SHOULD be equal to the `faas.name` resource attribute of the invoked\n\t// function.\n\tFaaSInvokedNameKey = attribute.Key(\"faas.invoked_name\")\n\n\t// FaaSInvokedProviderKey is the attribute Key conforming to the\n\t// \"faas.invoked_provider\" semantic conventions. It represents the cloud\n\t// provider of the invoked function.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: SHOULD be equal to the `cloud.provider` resource attribute of the\n\t// invoked function.\n\tFaaSInvokedProviderKey = attribute.Key(\"faas.invoked_provider\")\n\n\t// FaaSInvokedRegionKey is the attribute Key conforming to the\n\t// \"faas.invoked_region\" semantic conventions. It represents the cloud region of\n\t// the invoked function.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: eu-central-1\n\t// Note: SHOULD be equal to the `cloud.region` resource attribute of the invoked\n\t// function.\n\tFaaSInvokedRegionKey = attribute.Key(\"faas.invoked_region\")\n\n\t// FaaSMaxMemoryKey is the attribute Key conforming to the \"faas.max_memory\"\n\t// semantic conventions. It represents the amount of memory available to the\n\t// serverless function converted to Bytes.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Note: It's recommended to set this attribute since e.g. too little memory can\n\t// easily stop a Java AWS Lambda function from working correctly. On AWS Lambda,\n\t// the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this\n\t// information (which must be multiplied by 1,048,576).\n\tFaaSMaxMemoryKey = attribute.Key(\"faas.max_memory\")\n\n\t// FaaSNameKey is the attribute Key conforming to the \"faas.name\" semantic\n\t// conventions. It represents the name of the single function that this runtime\n\t// instance executes.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-function\", \"myazurefunctionapp/some-function-name\"\n\t// Note: This is the name of the function as configured/deployed on the FaaS\n\t// platform and is usually different from the name of the callback\n\t// function (which may be stored in the\n\t// [`code.namespace`/`code.function.name`]\n\t// span attributes).\n\t//\n\t// For some cloud providers, the above definition is ambiguous. The following\n\t// definition of function name MUST be used for this attribute\n\t// (and consequently the span name) for the listed cloud providers/products:\n\t//\n\t//   - **Azure:** The full name `<FUNCAPP>/<FUNC>`, i.e., function app name\n\t//     followed by a forward slash followed by the function name (this form\n\t//     can also be seen in the resource JSON for the function).\n\t//     This means that a span attribute MUST be used, as an Azure function\n\t//     app can host multiple functions that would usually share\n\t//     a TracerProvider (see also the `cloud.resource_id` attribute).\n\t//\n\t//\n\t// [`code.namespace`/`code.function.name`]: /docs/general/attributes.md#source-code-attributes\n\tFaaSNameKey = attribute.Key(\"faas.name\")\n\n\t// FaaSTimeKey is the attribute Key conforming to the \"faas.time\" semantic\n\t// conventions. It represents a string containing the function invocation time\n\t// in the [ISO 8601] format expressed in [UTC].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 2020-01-23T13:47:06Z\n\t//\n\t// [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html\n\t// [UTC]: https://www.w3.org/TR/NOTE-datetime\n\tFaaSTimeKey = attribute.Key(\"faas.time\")\n\n\t// FaaSTriggerKey is the attribute Key conforming to the \"faas.trigger\" semantic\n\t// conventions. It represents the type of the trigger which caused this function\n\t// invocation.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tFaaSTriggerKey = attribute.Key(\"faas.trigger\")\n\n\t// FaaSVersionKey is the attribute Key conforming to the \"faas.version\" semantic\n\t// conventions. It represents the immutable version of the function being\n\t// executed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"26\", \"pinkfroid-00002\"\n\t// Note: Depending on the cloud provider and platform, use:\n\t//\n\t//   - **AWS Lambda:** The [function version]\n\t//     (an integer represented as a decimal string).\n\t//   - **Google Cloud Run (Services):** The [revision]\n\t//     (i.e., the function name plus the revision suffix).\n\t//   - **Google Cloud Functions:** The value of the\n\t//     [`K_REVISION` environment variable].\n\t//   - **Azure Functions:** Not applicable. Do not set this attribute.\n\t//\n\t//\n\t// [function version]: https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html\n\t// [revision]: https://cloud.google.com/run/docs/managing/revisions\n\t// [`K_REVISION` environment variable]: https://cloud.google.com/run/docs/container-contract#services-env-vars\n\tFaaSVersionKey = attribute.Key(\"faas.version\")\n)\n\n// FaaSColdstart returns an attribute KeyValue conforming to the \"faas.coldstart\"\n// semantic conventions. It represents a boolean that is true if the serverless\n// function is executed for the first time (aka cold-start).\nfunc FaaSColdstart(val bool) attribute.KeyValue {\n\treturn FaaSColdstartKey.Bool(val)\n}\n\n// FaaSCron returns an attribute KeyValue conforming to the \"faas.cron\" semantic\n// conventions. It represents a string containing the schedule period as\n// [Cron Expression].\n//\n// [Cron Expression]: https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm\nfunc FaaSCron(val string) attribute.KeyValue {\n\treturn FaaSCronKey.String(val)\n}\n\n// FaaSDocumentCollection returns an attribute KeyValue conforming to the\n// \"faas.document.collection\" semantic conventions. It represents the name of the\n// source on which the triggering operation was performed. For example, in Cloud\n// Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database\n// name.\nfunc FaaSDocumentCollection(val string) attribute.KeyValue {\n\treturn FaaSDocumentCollectionKey.String(val)\n}\n\n// FaaSDocumentName returns an attribute KeyValue conforming to the\n// \"faas.document.name\" semantic conventions. It represents the document\n// name/table subjected to the operation. For example, in Cloud Storage or S3 is\n// the name of the file, and in Cosmos DB the table name.\nfunc FaaSDocumentName(val string) attribute.KeyValue {\n\treturn FaaSDocumentNameKey.String(val)\n}\n\n// FaaSDocumentTime returns an attribute KeyValue conforming to the\n// \"faas.document.time\" semantic conventions. It represents a string containing\n// the time when the data was accessed in the [ISO 8601] format expressed in\n// [UTC].\n//\n// [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html\n// [UTC]: https://www.w3.org/TR/NOTE-datetime\nfunc FaaSDocumentTime(val string) attribute.KeyValue {\n\treturn FaaSDocumentTimeKey.String(val)\n}\n\n// FaaSInstance returns an attribute KeyValue conforming to the \"faas.instance\"\n// semantic conventions. It represents the execution environment ID as a string,\n// that will be potentially reused for other invocations to the same\n// function/function version.\nfunc FaaSInstance(val string) attribute.KeyValue {\n\treturn FaaSInstanceKey.String(val)\n}\n\n// FaaSInvocationID returns an attribute KeyValue conforming to the\n// \"faas.invocation_id\" semantic conventions. It represents the invocation ID of\n// the current function invocation.\nfunc FaaSInvocationID(val string) attribute.KeyValue {\n\treturn FaaSInvocationIDKey.String(val)\n}\n\n// FaaSInvokedName returns an attribute KeyValue conforming to the\n// \"faas.invoked_name\" semantic conventions. It represents the name of the\n// invoked function.\nfunc FaaSInvokedName(val string) attribute.KeyValue {\n\treturn FaaSInvokedNameKey.String(val)\n}\n\n// FaaSInvokedRegion returns an attribute KeyValue conforming to the\n// \"faas.invoked_region\" semantic conventions. It represents the cloud region of\n// the invoked function.\nfunc FaaSInvokedRegion(val string) attribute.KeyValue {\n\treturn FaaSInvokedRegionKey.String(val)\n}\n\n// FaaSMaxMemory returns an attribute KeyValue conforming to the\n// \"faas.max_memory\" semantic conventions. It represents the amount of memory\n// available to the serverless function converted to Bytes.\nfunc FaaSMaxMemory(val int) attribute.KeyValue {\n\treturn FaaSMaxMemoryKey.Int(val)\n}\n\n// FaaSName returns an attribute KeyValue conforming to the \"faas.name\" semantic\n// conventions. It represents the name of the single function that this runtime\n// instance executes.\nfunc FaaSName(val string) attribute.KeyValue {\n\treturn FaaSNameKey.String(val)\n}\n\n// FaaSTime returns an attribute KeyValue conforming to the \"faas.time\" semantic\n// conventions. It represents a string containing the function invocation time in\n// the [ISO 8601] format expressed in [UTC].\n//\n// [ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html\n// [UTC]: https://www.w3.org/TR/NOTE-datetime\nfunc FaaSTime(val string) attribute.KeyValue {\n\treturn FaaSTimeKey.String(val)\n}\n\n// FaaSVersion returns an attribute KeyValue conforming to the \"faas.version\"\n// semantic conventions. It represents the immutable version of the function\n// being executed.\nfunc FaaSVersion(val string) attribute.KeyValue {\n\treturn FaaSVersionKey.String(val)\n}\n\n// Enum values for faas.document.operation\nvar (\n\t// When a new object is created.\n\t// Stability: development\n\tFaaSDocumentOperationInsert = FaaSDocumentOperationKey.String(\"insert\")\n\t// When an object is modified.\n\t// Stability: development\n\tFaaSDocumentOperationEdit = FaaSDocumentOperationKey.String(\"edit\")\n\t// When an object is deleted.\n\t// Stability: development\n\tFaaSDocumentOperationDelete = FaaSDocumentOperationKey.String(\"delete\")\n)\n\n// Enum values for faas.invoked_provider\nvar (\n\t// Alibaba Cloud\n\t// Stability: development\n\tFaaSInvokedProviderAlibabaCloud = FaaSInvokedProviderKey.String(\"alibaba_cloud\")\n\t// Amazon Web Services\n\t// Stability: development\n\tFaaSInvokedProviderAWS = FaaSInvokedProviderKey.String(\"aws\")\n\t// Microsoft Azure\n\t// Stability: development\n\tFaaSInvokedProviderAzure = FaaSInvokedProviderKey.String(\"azure\")\n\t// Google Cloud Platform\n\t// Stability: development\n\tFaaSInvokedProviderGCP = FaaSInvokedProviderKey.String(\"gcp\")\n\t// Tencent Cloud\n\t// Stability: development\n\tFaaSInvokedProviderTencentCloud = FaaSInvokedProviderKey.String(\"tencent_cloud\")\n)\n\n// Enum values for faas.trigger\nvar (\n\t// A response to some data source operation such as a database or filesystem\n\t// read/write\n\t// Stability: development\n\tFaaSTriggerDatasource = FaaSTriggerKey.String(\"datasource\")\n\t// To provide an answer to an inbound HTTP request\n\t// Stability: development\n\tFaaSTriggerHTTP = FaaSTriggerKey.String(\"http\")\n\t// A function is set to be executed when messages are sent to a messaging system\n\t// Stability: development\n\tFaaSTriggerPubSub = FaaSTriggerKey.String(\"pubsub\")\n\t// A function is scheduled to be executed regularly\n\t// Stability: development\n\tFaaSTriggerTimer = FaaSTriggerKey.String(\"timer\")\n\t// If none of the others apply\n\t// Stability: development\n\tFaaSTriggerOther = FaaSTriggerKey.String(\"other\")\n)\n\n// Namespace: feature_flag\nconst (\n\t// FeatureFlagContextIDKey is the attribute Key conforming to the\n\t// \"feature_flag.context.id\" semantic conventions. It represents the unique\n\t// identifier for the flag evaluation context. For example, the targeting key.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Release_Candidate\n\t//\n\t// Examples: \"5157782b-2203-4c80-a857-dbbd5e7761db\"\n\tFeatureFlagContextIDKey = attribute.Key(\"feature_flag.context.id\")\n\n\t// FeatureFlagKeyKey is the attribute Key conforming to the \"feature_flag.key\"\n\t// semantic conventions. It represents the lookup key of the feature flag.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Release_Candidate\n\t//\n\t// Examples: \"logo-color\"\n\tFeatureFlagKeyKey = attribute.Key(\"feature_flag.key\")\n\n\t// FeatureFlagProviderNameKey is the attribute Key conforming to the\n\t// \"feature_flag.provider.name\" semantic conventions. It represents the\n\t// identifies the feature flag provider.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Release_Candidate\n\t//\n\t// Examples: \"Flag Manager\"\n\tFeatureFlagProviderNameKey = attribute.Key(\"feature_flag.provider.name\")\n\n\t// FeatureFlagResultReasonKey is the attribute Key conforming to the\n\t// \"feature_flag.result.reason\" semantic conventions. It represents the reason\n\t// code which shows how a feature flag value was determined.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Release_Candidate\n\t//\n\t// Examples: \"static\", \"targeting_match\", \"error\", \"default\"\n\tFeatureFlagResultReasonKey = attribute.Key(\"feature_flag.result.reason\")\n\n\t// FeatureFlagResultValueKey is the attribute Key conforming to the\n\t// \"feature_flag.result.value\" semantic conventions. It represents the evaluated\n\t// value of the feature flag.\n\t//\n\t// Type: any\n\t// RequirementLevel: Recommended\n\t// Stability: Release_Candidate\n\t//\n\t// Examples: \"#ff0000\", true, 3\n\t// Note: With some feature flag providers, feature flag results can be quite\n\t// large or contain private or sensitive details.\n\t// Because of this, `feature_flag.result.variant` is often the preferred\n\t// attribute if it is available.\n\t//\n\t// It may be desirable to redact or otherwise limit the size and scope of\n\t// `feature_flag.result.value` if possible.\n\t// Because the evaluated flag value is unstructured and may be any type, it is\n\t// left to the instrumentation author to determine how best to achieve this.\n\tFeatureFlagResultValueKey = attribute.Key(\"feature_flag.result.value\")\n\n\t// FeatureFlagResultVariantKey is the attribute Key conforming to the\n\t// \"feature_flag.result.variant\" semantic conventions. It represents a semantic\n\t// identifier for an evaluated flag value.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Release_Candidate\n\t//\n\t// Examples: \"red\", \"true\", \"on\"\n\t// Note: A semantic identifier, commonly referred to as a variant, provides a\n\t// means\n\t// for referring to a value without including the value itself. This can\n\t// provide additional context for understanding the meaning behind a value.\n\t// For example, the variant `red` maybe be used for the value `#c05543`.\n\tFeatureFlagResultVariantKey = attribute.Key(\"feature_flag.result.variant\")\n\n\t// FeatureFlagSetIDKey is the attribute Key conforming to the\n\t// \"feature_flag.set.id\" semantic conventions. It represents the identifier of\n\t// the [flag set] to which the feature flag belongs.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Release_Candidate\n\t//\n\t// Examples: \"proj-1\", \"ab98sgs\", \"service1/dev\"\n\t//\n\t// [flag set]: https://openfeature.dev/specification/glossary/#flag-set\n\tFeatureFlagSetIDKey = attribute.Key(\"feature_flag.set.id\")\n\n\t// FeatureFlagVersionKey is the attribute Key conforming to the\n\t// \"feature_flag.version\" semantic conventions. It represents the version of the\n\t// ruleset used during the evaluation. This may be any stable value which\n\t// uniquely identifies the ruleset.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Release_Candidate\n\t//\n\t// Examples: \"1\", \"01ABCDEF\"\n\tFeatureFlagVersionKey = attribute.Key(\"feature_flag.version\")\n)\n\n// FeatureFlagContextID returns an attribute KeyValue conforming to the\n// \"feature_flag.context.id\" semantic conventions. It represents the unique\n// identifier for the flag evaluation context. For example, the targeting key.\nfunc FeatureFlagContextID(val string) attribute.KeyValue {\n\treturn FeatureFlagContextIDKey.String(val)\n}\n\n// FeatureFlagKey returns an attribute KeyValue conforming to the\n// \"feature_flag.key\" semantic conventions. It represents the lookup key of the\n// feature flag.\nfunc FeatureFlagKey(val string) attribute.KeyValue {\n\treturn FeatureFlagKeyKey.String(val)\n}\n\n// FeatureFlagProviderName returns an attribute KeyValue conforming to the\n// \"feature_flag.provider.name\" semantic conventions. It represents the\n// identifies the feature flag provider.\nfunc FeatureFlagProviderName(val string) attribute.KeyValue {\n\treturn FeatureFlagProviderNameKey.String(val)\n}\n\n// FeatureFlagResultVariant returns an attribute KeyValue conforming to the\n// \"feature_flag.result.variant\" semantic conventions. It represents a semantic\n// identifier for an evaluated flag value.\nfunc FeatureFlagResultVariant(val string) attribute.KeyValue {\n\treturn FeatureFlagResultVariantKey.String(val)\n}\n\n// FeatureFlagSetID returns an attribute KeyValue conforming to the\n// \"feature_flag.set.id\" semantic conventions. It represents the identifier of\n// the [flag set] to which the feature flag belongs.\n//\n// [flag set]: https://openfeature.dev/specification/glossary/#flag-set\nfunc FeatureFlagSetID(val string) attribute.KeyValue {\n\treturn FeatureFlagSetIDKey.String(val)\n}\n\n// FeatureFlagVersion returns an attribute KeyValue conforming to the\n// \"feature_flag.version\" semantic conventions. It represents the version of the\n// ruleset used during the evaluation. This may be any stable value which\n// uniquely identifies the ruleset.\nfunc FeatureFlagVersion(val string) attribute.KeyValue {\n\treturn FeatureFlagVersionKey.String(val)\n}\n\n// Enum values for feature_flag.result.reason\nvar (\n\t// The resolved value is static (no dynamic evaluation).\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonStatic = FeatureFlagResultReasonKey.String(\"static\")\n\t// The resolved value fell back to a pre-configured value (no dynamic evaluation\n\t// occurred or dynamic evaluation yielded no result).\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonDefault = FeatureFlagResultReasonKey.String(\"default\")\n\t// The resolved value was the result of a dynamic evaluation, such as a rule or\n\t// specific user-targeting.\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonTargetingMatch = FeatureFlagResultReasonKey.String(\"targeting_match\")\n\t// The resolved value was the result of pseudorandom assignment.\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonSplit = FeatureFlagResultReasonKey.String(\"split\")\n\t// The resolved value was retrieved from cache.\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonCached = FeatureFlagResultReasonKey.String(\"cached\")\n\t// The resolved value was the result of the flag being disabled in the\n\t// management system.\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonDisabled = FeatureFlagResultReasonKey.String(\"disabled\")\n\t// The reason for the resolved value could not be determined.\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonUnknown = FeatureFlagResultReasonKey.String(\"unknown\")\n\t// The resolved value is non-authoritative or possibly out of date\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonStale = FeatureFlagResultReasonKey.String(\"stale\")\n\t// The resolved value was the result of an error.\n\t// Stability: release_candidate\n\tFeatureFlagResultReasonError = FeatureFlagResultReasonKey.String(\"error\")\n)\n\n// Namespace: file\nconst (\n\t// FileAccessedKey is the attribute Key conforming to the \"file.accessed\"\n\t// semantic conventions. It represents the time when the file was last accessed,\n\t// in ISO 8601 format.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2021-01-01T12:00:00Z\"\n\t// Note: This attribute might not be supported by some file systems — NFS,\n\t// FAT32, in embedded OS, etc.\n\tFileAccessedKey = attribute.Key(\"file.accessed\")\n\n\t// FileAttributesKey is the attribute Key conforming to the \"file.attributes\"\n\t// semantic conventions. It represents the array of file attributes.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"readonly\", \"hidden\"\n\t// Note: Attributes names depend on the OS or file system. Here’s a\n\t// non-exhaustive list of values expected for this attribute: `archive`,\n\t// `compressed`, `directory`, `encrypted`, `execute`, `hidden`, `immutable`,\n\t// `journaled`, `read`, `readonly`, `symbolic link`, `system`, `temporary`,\n\t// `write`.\n\tFileAttributesKey = attribute.Key(\"file.attributes\")\n\n\t// FileChangedKey is the attribute Key conforming to the \"file.changed\" semantic\n\t// conventions. It represents the time when the file attributes or metadata was\n\t// last changed, in ISO 8601 format.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2021-01-01T12:00:00Z\"\n\t// Note: `file.changed` captures the time when any of the file's properties or\n\t// attributes (including the content) are changed, while `file.modified`\n\t// captures the timestamp when the file content is modified.\n\tFileChangedKey = attribute.Key(\"file.changed\")\n\n\t// FileCreatedKey is the attribute Key conforming to the \"file.created\" semantic\n\t// conventions. It represents the time when the file was created, in ISO 8601\n\t// format.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2021-01-01T12:00:00Z\"\n\t// Note: This attribute might not be supported by some file systems — NFS,\n\t// FAT32, in embedded OS, etc.\n\tFileCreatedKey = attribute.Key(\"file.created\")\n\n\t// FileDirectoryKey is the attribute Key conforming to the \"file.directory\"\n\t// semantic conventions. It represents the directory where the file is located.\n\t// It should include the drive letter, when appropriate.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/home/user\", \"C:\\Program Files\\MyApp\"\n\tFileDirectoryKey = attribute.Key(\"file.directory\")\n\n\t// FileExtensionKey is the attribute Key conforming to the \"file.extension\"\n\t// semantic conventions. It represents the file extension, excluding the leading\n\t// dot.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"png\", \"gz\"\n\t// Note: When the file name has multiple extensions (example.tar.gz), only the\n\t// last one should be captured (\"gz\", not \"tar.gz\").\n\tFileExtensionKey = attribute.Key(\"file.extension\")\n\n\t// FileForkNameKey is the attribute Key conforming to the \"file.fork_name\"\n\t// semantic conventions. It represents the name of the fork. A fork is\n\t// additional data associated with a filesystem object.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Zone.Identifier\"\n\t// Note: On Linux, a resource fork is used to store additional data with a\n\t// filesystem object. A file always has at least one fork for the data portion,\n\t// and additional forks may exist.\n\t// On NTFS, this is analogous to an Alternate Data Stream (ADS), and the default\n\t// data stream for a file is just called $DATA. Zone.Identifier is commonly used\n\t// by Windows to track contents downloaded from the Internet. An ADS is\n\t// typically of the form: C:\\path\\to\\filename.extension:some_fork_name, and\n\t// some_fork_name is the value that should populate `fork_name`.\n\t// `filename.extension` should populate `file.name`, and `extension` should\n\t// populate `file.extension`. The full path, `file.path`, will include the fork\n\t// name.\n\tFileForkNameKey = attribute.Key(\"file.fork_name\")\n\n\t// FileGroupIDKey is the attribute Key conforming to the \"file.group.id\"\n\t// semantic conventions. It represents the primary Group ID (GID) of the file.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1000\"\n\tFileGroupIDKey = attribute.Key(\"file.group.id\")\n\n\t// FileGroupNameKey is the attribute Key conforming to the \"file.group.name\"\n\t// semantic conventions. It represents the primary group name of the file.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"users\"\n\tFileGroupNameKey = attribute.Key(\"file.group.name\")\n\n\t// FileInodeKey is the attribute Key conforming to the \"file.inode\" semantic\n\t// conventions. It represents the inode representing the file in the filesystem.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"256383\"\n\tFileInodeKey = attribute.Key(\"file.inode\")\n\n\t// FileModeKey is the attribute Key conforming to the \"file.mode\" semantic\n\t// conventions. It represents the mode of the file in octal representation.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"0640\"\n\tFileModeKey = attribute.Key(\"file.mode\")\n\n\t// FileModifiedKey is the attribute Key conforming to the \"file.modified\"\n\t// semantic conventions. It represents the time when the file content was last\n\t// modified, in ISO 8601 format.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2021-01-01T12:00:00Z\"\n\tFileModifiedKey = attribute.Key(\"file.modified\")\n\n\t// FileNameKey is the attribute Key conforming to the \"file.name\" semantic\n\t// conventions. It represents the name of the file including the extension,\n\t// without the directory.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"example.png\"\n\tFileNameKey = attribute.Key(\"file.name\")\n\n\t// FileOwnerIDKey is the attribute Key conforming to the \"file.owner.id\"\n\t// semantic conventions. It represents the user ID (UID) or security identifier\n\t// (SID) of the file owner.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1000\"\n\tFileOwnerIDKey = attribute.Key(\"file.owner.id\")\n\n\t// FileOwnerNameKey is the attribute Key conforming to the \"file.owner.name\"\n\t// semantic conventions. It represents the username of the file owner.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"root\"\n\tFileOwnerNameKey = attribute.Key(\"file.owner.name\")\n\n\t// FilePathKey is the attribute Key conforming to the \"file.path\" semantic\n\t// conventions. It represents the full path to the file, including the file\n\t// name. It should include the drive letter, when appropriate.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/home/alice/example.png\", \"C:\\Program Files\\MyApp\\myapp.exe\"\n\tFilePathKey = attribute.Key(\"file.path\")\n\n\t// FileSizeKey is the attribute Key conforming to the \"file.size\" semantic\n\t// conventions. It represents the file size in bytes.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tFileSizeKey = attribute.Key(\"file.size\")\n\n\t// FileSymbolicLinkTargetPathKey is the attribute Key conforming to the\n\t// \"file.symbolic_link.target_path\" semantic conventions. It represents the path\n\t// to the target of a symbolic link.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/usr/bin/python3\"\n\t// Note: This attribute is only applicable to symbolic links.\n\tFileSymbolicLinkTargetPathKey = attribute.Key(\"file.symbolic_link.target_path\")\n)\n\n// FileAccessed returns an attribute KeyValue conforming to the \"file.accessed\"\n// semantic conventions. It represents the time when the file was last accessed,\n// in ISO 8601 format.\nfunc FileAccessed(val string) attribute.KeyValue {\n\treturn FileAccessedKey.String(val)\n}\n\n// FileAttributes returns an attribute KeyValue conforming to the\n// \"file.attributes\" semantic conventions. It represents the array of file\n// attributes.\nfunc FileAttributes(val ...string) attribute.KeyValue {\n\treturn FileAttributesKey.StringSlice(val)\n}\n\n// FileChanged returns an attribute KeyValue conforming to the \"file.changed\"\n// semantic conventions. It represents the time when the file attributes or\n// metadata was last changed, in ISO 8601 format.\nfunc FileChanged(val string) attribute.KeyValue {\n\treturn FileChangedKey.String(val)\n}\n\n// FileCreated returns an attribute KeyValue conforming to the \"file.created\"\n// semantic conventions. It represents the time when the file was created, in ISO\n// 8601 format.\nfunc FileCreated(val string) attribute.KeyValue {\n\treturn FileCreatedKey.String(val)\n}\n\n// FileDirectory returns an attribute KeyValue conforming to the \"file.directory\"\n// semantic conventions. It represents the directory where the file is located.\n// It should include the drive letter, when appropriate.\nfunc FileDirectory(val string) attribute.KeyValue {\n\treturn FileDirectoryKey.String(val)\n}\n\n// FileExtension returns an attribute KeyValue conforming to the \"file.extension\"\n// semantic conventions. It represents the file extension, excluding the leading\n// dot.\nfunc FileExtension(val string) attribute.KeyValue {\n\treturn FileExtensionKey.String(val)\n}\n\n// FileForkName returns an attribute KeyValue conforming to the \"file.fork_name\"\n// semantic conventions. It represents the name of the fork. A fork is additional\n// data associated with a filesystem object.\nfunc FileForkName(val string) attribute.KeyValue {\n\treturn FileForkNameKey.String(val)\n}\n\n// FileGroupID returns an attribute KeyValue conforming to the \"file.group.id\"\n// semantic conventions. It represents the primary Group ID (GID) of the file.\nfunc FileGroupID(val string) attribute.KeyValue {\n\treturn FileGroupIDKey.String(val)\n}\n\n// FileGroupName returns an attribute KeyValue conforming to the\n// \"file.group.name\" semantic conventions. It represents the primary group name\n// of the file.\nfunc FileGroupName(val string) attribute.KeyValue {\n\treturn FileGroupNameKey.String(val)\n}\n\n// FileInode returns an attribute KeyValue conforming to the \"file.inode\"\n// semantic conventions. It represents the inode representing the file in the\n// filesystem.\nfunc FileInode(val string) attribute.KeyValue {\n\treturn FileInodeKey.String(val)\n}\n\n// FileMode returns an attribute KeyValue conforming to the \"file.mode\" semantic\n// conventions. It represents the mode of the file in octal representation.\nfunc FileMode(val string) attribute.KeyValue {\n\treturn FileModeKey.String(val)\n}\n\n// FileModified returns an attribute KeyValue conforming to the \"file.modified\"\n// semantic conventions. It represents the time when the file content was last\n// modified, in ISO 8601 format.\nfunc FileModified(val string) attribute.KeyValue {\n\treturn FileModifiedKey.String(val)\n}\n\n// FileName returns an attribute KeyValue conforming to the \"file.name\" semantic\n// conventions. It represents the name of the file including the extension,\n// without the directory.\nfunc FileName(val string) attribute.KeyValue {\n\treturn FileNameKey.String(val)\n}\n\n// FileOwnerID returns an attribute KeyValue conforming to the \"file.owner.id\"\n// semantic conventions. It represents the user ID (UID) or security identifier\n// (SID) of the file owner.\nfunc FileOwnerID(val string) attribute.KeyValue {\n\treturn FileOwnerIDKey.String(val)\n}\n\n// FileOwnerName returns an attribute KeyValue conforming to the\n// \"file.owner.name\" semantic conventions. It represents the username of the file\n// owner.\nfunc FileOwnerName(val string) attribute.KeyValue {\n\treturn FileOwnerNameKey.String(val)\n}\n\n// FilePath returns an attribute KeyValue conforming to the \"file.path\" semantic\n// conventions. It represents the full path to the file, including the file name.\n// It should include the drive letter, when appropriate.\nfunc FilePath(val string) attribute.KeyValue {\n\treturn FilePathKey.String(val)\n}\n\n// FileSize returns an attribute KeyValue conforming to the \"file.size\" semantic\n// conventions. It represents the file size in bytes.\nfunc FileSize(val int) attribute.KeyValue {\n\treturn FileSizeKey.Int(val)\n}\n\n// FileSymbolicLinkTargetPath returns an attribute KeyValue conforming to the\n// \"file.symbolic_link.target_path\" semantic conventions. It represents the path\n// to the target of a symbolic link.\nfunc FileSymbolicLinkTargetPath(val string) attribute.KeyValue {\n\treturn FileSymbolicLinkTargetPathKey.String(val)\n}\n\n// Namespace: gcp\nconst (\n\t// GCPAppHubApplicationContainerKey is the attribute Key conforming to the\n\t// \"gcp.apphub.application.container\" semantic conventions. It represents the\n\t// container within GCP where the AppHub application is defined.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"projects/my-container-project\"\n\tGCPAppHubApplicationContainerKey = attribute.Key(\"gcp.apphub.application.container\")\n\n\t// GCPAppHubApplicationIDKey is the attribute Key conforming to the\n\t// \"gcp.apphub.application.id\" semantic conventions. It represents the name of\n\t// the application as configured in AppHub.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-application\"\n\tGCPAppHubApplicationIDKey = attribute.Key(\"gcp.apphub.application.id\")\n\n\t// GCPAppHubApplicationLocationKey is the attribute Key conforming to the\n\t// \"gcp.apphub.application.location\" semantic conventions. It represents the GCP\n\t// zone or region where the application is defined.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"us-central1\"\n\tGCPAppHubApplicationLocationKey = attribute.Key(\"gcp.apphub.application.location\")\n\n\t// GCPAppHubServiceCriticalityTypeKey is the attribute Key conforming to the\n\t// \"gcp.apphub.service.criticality_type\" semantic conventions. It represents the\n\t// criticality of a service indicates its importance to the business.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: [See AppHub type enum]\n\t//\n\t// [See AppHub type enum]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type\n\tGCPAppHubServiceCriticalityTypeKey = attribute.Key(\"gcp.apphub.service.criticality_type\")\n\n\t// GCPAppHubServiceEnvironmentTypeKey is the attribute Key conforming to the\n\t// \"gcp.apphub.service.environment_type\" semantic conventions. It represents the\n\t// environment of a service is the stage of a software lifecycle.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: [See AppHub environment type]\n\t//\n\t// [See AppHub environment type]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1\n\tGCPAppHubServiceEnvironmentTypeKey = attribute.Key(\"gcp.apphub.service.environment_type\")\n\n\t// GCPAppHubServiceIDKey is the attribute Key conforming to the\n\t// \"gcp.apphub.service.id\" semantic conventions. It represents the name of the\n\t// service as configured in AppHub.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-service\"\n\tGCPAppHubServiceIDKey = attribute.Key(\"gcp.apphub.service.id\")\n\n\t// GCPAppHubWorkloadCriticalityTypeKey is the attribute Key conforming to the\n\t// \"gcp.apphub.workload.criticality_type\" semantic conventions. It represents\n\t// the criticality of a workload indicates its importance to the business.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: [See AppHub type enum]\n\t//\n\t// [See AppHub type enum]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type\n\tGCPAppHubWorkloadCriticalityTypeKey = attribute.Key(\"gcp.apphub.workload.criticality_type\")\n\n\t// GCPAppHubWorkloadEnvironmentTypeKey is the attribute Key conforming to the\n\t// \"gcp.apphub.workload.environment_type\" semantic conventions. It represents\n\t// the environment of a workload is the stage of a software lifecycle.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: [See AppHub environment type]\n\t//\n\t// [See AppHub environment type]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1\n\tGCPAppHubWorkloadEnvironmentTypeKey = attribute.Key(\"gcp.apphub.workload.environment_type\")\n\n\t// GCPAppHubWorkloadIDKey is the attribute Key conforming to the\n\t// \"gcp.apphub.workload.id\" semantic conventions. It represents the name of the\n\t// workload as configured in AppHub.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-workload\"\n\tGCPAppHubWorkloadIDKey = attribute.Key(\"gcp.apphub.workload.id\")\n\n\t// GCPAppHubDestinationApplicationContainerKey is the attribute Key conforming\n\t// to the \"gcp.apphub_destination.application.container\" semantic conventions.\n\t// It represents the container within GCP where the AppHub destination\n\t// application is defined.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"projects/my-container-project\"\n\tGCPAppHubDestinationApplicationContainerKey = attribute.Key(\"gcp.apphub_destination.application.container\")\n\n\t// GCPAppHubDestinationApplicationIDKey is the attribute Key conforming to the\n\t// \"gcp.apphub_destination.application.id\" semantic conventions. It represents\n\t// the name of the destination application as configured in AppHub.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-application\"\n\tGCPAppHubDestinationApplicationIDKey = attribute.Key(\"gcp.apphub_destination.application.id\")\n\n\t// GCPAppHubDestinationApplicationLocationKey is the attribute Key conforming to\n\t// the \"gcp.apphub_destination.application.location\" semantic conventions. It\n\t// represents the GCP zone or region where the destination application is\n\t// defined.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"us-central1\"\n\tGCPAppHubDestinationApplicationLocationKey = attribute.Key(\"gcp.apphub_destination.application.location\")\n\n\t// GCPAppHubDestinationServiceCriticalityTypeKey is the attribute Key conforming\n\t// to the \"gcp.apphub_destination.service.criticality_type\" semantic\n\t// conventions. It represents the criticality of a destination workload\n\t// indicates its importance to the business as specified in [AppHub type enum].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t//\n\t// [AppHub type enum]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type\n\tGCPAppHubDestinationServiceCriticalityTypeKey = attribute.Key(\"gcp.apphub_destination.service.criticality_type\")\n\n\t// GCPAppHubDestinationServiceEnvironmentTypeKey is the attribute Key conforming\n\t// to the \"gcp.apphub_destination.service.environment_type\" semantic\n\t// conventions. It represents the software lifecycle stage of a destination\n\t// service as defined [AppHub environment type].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t//\n\t// [AppHub environment type]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1\n\tGCPAppHubDestinationServiceEnvironmentTypeKey = attribute.Key(\"gcp.apphub_destination.service.environment_type\")\n\n\t// GCPAppHubDestinationServiceIDKey is the attribute Key conforming to the\n\t// \"gcp.apphub_destination.service.id\" semantic conventions. It represents the\n\t// name of the destination service as configured in AppHub.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-service\"\n\tGCPAppHubDestinationServiceIDKey = attribute.Key(\"gcp.apphub_destination.service.id\")\n\n\t// GCPAppHubDestinationWorkloadCriticalityTypeKey is the attribute Key\n\t// conforming to the \"gcp.apphub_destination.workload.criticality_type\" semantic\n\t// conventions. It represents the criticality of a destination workload\n\t// indicates its importance to the business as specified in [AppHub type enum].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t//\n\t// [AppHub type enum]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type\n\tGCPAppHubDestinationWorkloadCriticalityTypeKey = attribute.Key(\"gcp.apphub_destination.workload.criticality_type\")\n\n\t// GCPAppHubDestinationWorkloadEnvironmentTypeKey is the attribute Key\n\t// conforming to the \"gcp.apphub_destination.workload.environment_type\" semantic\n\t// conventions. It represents the environment of a destination workload is the\n\t// stage of a software lifecycle as provided in the [AppHub environment type].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t//\n\t// [AppHub environment type]: https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1\n\tGCPAppHubDestinationWorkloadEnvironmentTypeKey = attribute.Key(\"gcp.apphub_destination.workload.environment_type\")\n\n\t// GCPAppHubDestinationWorkloadIDKey is the attribute Key conforming to the\n\t// \"gcp.apphub_destination.workload.id\" semantic conventions. It represents the\n\t// name of the destination workload as configured in AppHub.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-workload\"\n\tGCPAppHubDestinationWorkloadIDKey = attribute.Key(\"gcp.apphub_destination.workload.id\")\n\n\t// GCPClientServiceKey is the attribute Key conforming to the\n\t// \"gcp.client.service\" semantic conventions. It represents the identifies the\n\t// Google Cloud service for which the official client library is intended.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"appengine\", \"run\", \"firestore\", \"alloydb\", \"spanner\"\n\t// Note: Intended to be a stable identifier for Google Cloud client libraries\n\t// that is uniform across implementation languages. The value should be derived\n\t// from the canonical service domain for the service; for example,\n\t// 'foo.googleapis.com' should result in a value of 'foo'.\n\tGCPClientServiceKey = attribute.Key(\"gcp.client.service\")\n\n\t// GCPCloudRunJobExecutionKey is the attribute Key conforming to the\n\t// \"gcp.cloud_run.job.execution\" semantic conventions. It represents the name of\n\t// the Cloud Run [execution] being run for the Job, as set by the\n\t// [`CLOUD_RUN_EXECUTION`] environment variable.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"job-name-xxxx\", \"sample-job-mdw84\"\n\t//\n\t// [execution]: https://cloud.google.com/run/docs/managing/job-executions\n\t// [`CLOUD_RUN_EXECUTION`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars\n\tGCPCloudRunJobExecutionKey = attribute.Key(\"gcp.cloud_run.job.execution\")\n\n\t// GCPCloudRunJobTaskIndexKey is the attribute Key conforming to the\n\t// \"gcp.cloud_run.job.task_index\" semantic conventions. It represents the index\n\t// for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`]\n\t// environment variable.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0, 1\n\t//\n\t// [`CLOUD_RUN_TASK_INDEX`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars\n\tGCPCloudRunJobTaskIndexKey = attribute.Key(\"gcp.cloud_run.job.task_index\")\n\n\t// GCPGCEInstanceHostnameKey is the attribute Key conforming to the\n\t// \"gcp.gce.instance.hostname\" semantic conventions. It represents the hostname\n\t// of a GCE instance. This is the full value of the default or [custom hostname]\n\t// .\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-host1234.example.com\",\n\t// \"sample-vm.us-west1-b.c.my-project.internal\"\n\t//\n\t// [custom hostname]: https://cloud.google.com/compute/docs/instances/custom-hostname-vm\n\tGCPGCEInstanceHostnameKey = attribute.Key(\"gcp.gce.instance.hostname\")\n\n\t// GCPGCEInstanceNameKey is the attribute Key conforming to the\n\t// \"gcp.gce.instance.name\" semantic conventions. It represents the instance name\n\t// of a GCE instance. This is the value provided by `host.name`, the visible\n\t// name of the instance in the Cloud Console UI, and the prefix for the default\n\t// hostname of the instance as defined by the [default internal DNS name].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"instance-1\", \"my-vm-name\"\n\t//\n\t// [default internal DNS name]: https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names\n\tGCPGCEInstanceNameKey = attribute.Key(\"gcp.gce.instance.name\")\n)\n\n// GCPAppHubApplicationContainer returns an attribute KeyValue conforming to the\n// \"gcp.apphub.application.container\" semantic conventions. It represents the\n// container within GCP where the AppHub application is defined.\nfunc GCPAppHubApplicationContainer(val string) attribute.KeyValue {\n\treturn GCPAppHubApplicationContainerKey.String(val)\n}\n\n// GCPAppHubApplicationID returns an attribute KeyValue conforming to the\n// \"gcp.apphub.application.id\" semantic conventions. It represents the name of\n// the application as configured in AppHub.\nfunc GCPAppHubApplicationID(val string) attribute.KeyValue {\n\treturn GCPAppHubApplicationIDKey.String(val)\n}\n\n// GCPAppHubApplicationLocation returns an attribute KeyValue conforming to the\n// \"gcp.apphub.application.location\" semantic conventions. It represents the GCP\n// zone or region where the application is defined.\nfunc GCPAppHubApplicationLocation(val string) attribute.KeyValue {\n\treturn GCPAppHubApplicationLocationKey.String(val)\n}\n\n// GCPAppHubServiceID returns an attribute KeyValue conforming to the\n// \"gcp.apphub.service.id\" semantic conventions. It represents the name of the\n// service as configured in AppHub.\nfunc GCPAppHubServiceID(val string) attribute.KeyValue {\n\treturn GCPAppHubServiceIDKey.String(val)\n}\n\n// GCPAppHubWorkloadID returns an attribute KeyValue conforming to the\n// \"gcp.apphub.workload.id\" semantic conventions. It represents the name of the\n// workload as configured in AppHub.\nfunc GCPAppHubWorkloadID(val string) attribute.KeyValue {\n\treturn GCPAppHubWorkloadIDKey.String(val)\n}\n\n// GCPAppHubDestinationApplicationContainer returns an attribute KeyValue\n// conforming to the \"gcp.apphub_destination.application.container\" semantic\n// conventions. It represents the container within GCP where the AppHub\n// destination application is defined.\nfunc GCPAppHubDestinationApplicationContainer(val string) attribute.KeyValue {\n\treturn GCPAppHubDestinationApplicationContainerKey.String(val)\n}\n\n// GCPAppHubDestinationApplicationID returns an attribute KeyValue conforming to\n// the \"gcp.apphub_destination.application.id\" semantic conventions. It\n// represents the name of the destination application as configured in AppHub.\nfunc GCPAppHubDestinationApplicationID(val string) attribute.KeyValue {\n\treturn GCPAppHubDestinationApplicationIDKey.String(val)\n}\n\n// GCPAppHubDestinationApplicationLocation returns an attribute KeyValue\n// conforming to the \"gcp.apphub_destination.application.location\" semantic\n// conventions. It represents the GCP zone or region where the destination\n// application is defined.\nfunc GCPAppHubDestinationApplicationLocation(val string) attribute.KeyValue {\n\treturn GCPAppHubDestinationApplicationLocationKey.String(val)\n}\n\n// GCPAppHubDestinationServiceID returns an attribute KeyValue conforming to the\n// \"gcp.apphub_destination.service.id\" semantic conventions. It represents the\n// name of the destination service as configured in AppHub.\nfunc GCPAppHubDestinationServiceID(val string) attribute.KeyValue {\n\treturn GCPAppHubDestinationServiceIDKey.String(val)\n}\n\n// GCPAppHubDestinationWorkloadID returns an attribute KeyValue conforming to the\n// \"gcp.apphub_destination.workload.id\" semantic conventions. It represents the\n// name of the destination workload as configured in AppHub.\nfunc GCPAppHubDestinationWorkloadID(val string) attribute.KeyValue {\n\treturn GCPAppHubDestinationWorkloadIDKey.String(val)\n}\n\n// GCPClientService returns an attribute KeyValue conforming to the\n// \"gcp.client.service\" semantic conventions. It represents the identifies the\n// Google Cloud service for which the official client library is intended.\nfunc GCPClientService(val string) attribute.KeyValue {\n\treturn GCPClientServiceKey.String(val)\n}\n\n// GCPCloudRunJobExecution returns an attribute KeyValue conforming to the\n// \"gcp.cloud_run.job.execution\" semantic conventions. It represents the name of\n// the Cloud Run [execution] being run for the Job, as set by the\n// [`CLOUD_RUN_EXECUTION`] environment variable.\n//\n// [execution]: https://cloud.google.com/run/docs/managing/job-executions\n// [`CLOUD_RUN_EXECUTION`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars\nfunc GCPCloudRunJobExecution(val string) attribute.KeyValue {\n\treturn GCPCloudRunJobExecutionKey.String(val)\n}\n\n// GCPCloudRunJobTaskIndex returns an attribute KeyValue conforming to the\n// \"gcp.cloud_run.job.task_index\" semantic conventions. It represents the index\n// for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`]\n// environment variable.\n//\n// [`CLOUD_RUN_TASK_INDEX`]: https://cloud.google.com/run/docs/container-contract#jobs-env-vars\nfunc GCPCloudRunJobTaskIndex(val int) attribute.KeyValue {\n\treturn GCPCloudRunJobTaskIndexKey.Int(val)\n}\n\n// GCPGCEInstanceHostname returns an attribute KeyValue conforming to the\n// \"gcp.gce.instance.hostname\" semantic conventions. It represents the hostname\n// of a GCE instance. This is the full value of the default or [custom hostname]\n// .\n//\n// [custom hostname]: https://cloud.google.com/compute/docs/instances/custom-hostname-vm\nfunc GCPGCEInstanceHostname(val string) attribute.KeyValue {\n\treturn GCPGCEInstanceHostnameKey.String(val)\n}\n\n// GCPGCEInstanceName returns an attribute KeyValue conforming to the\n// \"gcp.gce.instance.name\" semantic conventions. It represents the instance name\n// of a GCE instance. This is the value provided by `host.name`, the visible name\n// of the instance in the Cloud Console UI, and the prefix for the default\n// hostname of the instance as defined by the [default internal DNS name].\n//\n// [default internal DNS name]: https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names\nfunc GCPGCEInstanceName(val string) attribute.KeyValue {\n\treturn GCPGCEInstanceNameKey.String(val)\n}\n\n// Enum values for gcp.apphub.service.criticality_type\nvar (\n\t// Mission critical service.\n\t// Stability: development\n\tGCPAppHubServiceCriticalityTypeMissionCritical = GCPAppHubServiceCriticalityTypeKey.String(\"MISSION_CRITICAL\")\n\t// High impact.\n\t// Stability: development\n\tGCPAppHubServiceCriticalityTypeHigh = GCPAppHubServiceCriticalityTypeKey.String(\"HIGH\")\n\t// Medium impact.\n\t// Stability: development\n\tGCPAppHubServiceCriticalityTypeMedium = GCPAppHubServiceCriticalityTypeKey.String(\"MEDIUM\")\n\t// Low impact.\n\t// Stability: development\n\tGCPAppHubServiceCriticalityTypeLow = GCPAppHubServiceCriticalityTypeKey.String(\"LOW\")\n)\n\n// Enum values for gcp.apphub.service.environment_type\nvar (\n\t// Production environment.\n\t// Stability: development\n\tGCPAppHubServiceEnvironmentTypeProduction = GCPAppHubServiceEnvironmentTypeKey.String(\"PRODUCTION\")\n\t// Staging environment.\n\t// Stability: development\n\tGCPAppHubServiceEnvironmentTypeStaging = GCPAppHubServiceEnvironmentTypeKey.String(\"STAGING\")\n\t// Test environment.\n\t// Stability: development\n\tGCPAppHubServiceEnvironmentTypeTest = GCPAppHubServiceEnvironmentTypeKey.String(\"TEST\")\n\t// Development environment.\n\t// Stability: development\n\tGCPAppHubServiceEnvironmentTypeDevelopment = GCPAppHubServiceEnvironmentTypeKey.String(\"DEVELOPMENT\")\n)\n\n// Enum values for gcp.apphub.workload.criticality_type\nvar (\n\t// Mission critical service.\n\t// Stability: development\n\tGCPAppHubWorkloadCriticalityTypeMissionCritical = GCPAppHubWorkloadCriticalityTypeKey.String(\"MISSION_CRITICAL\")\n\t// High impact.\n\t// Stability: development\n\tGCPAppHubWorkloadCriticalityTypeHigh = GCPAppHubWorkloadCriticalityTypeKey.String(\"HIGH\")\n\t// Medium impact.\n\t// Stability: development\n\tGCPAppHubWorkloadCriticalityTypeMedium = GCPAppHubWorkloadCriticalityTypeKey.String(\"MEDIUM\")\n\t// Low impact.\n\t// Stability: development\n\tGCPAppHubWorkloadCriticalityTypeLow = GCPAppHubWorkloadCriticalityTypeKey.String(\"LOW\")\n)\n\n// Enum values for gcp.apphub.workload.environment_type\nvar (\n\t// Production environment.\n\t// Stability: development\n\tGCPAppHubWorkloadEnvironmentTypeProduction = GCPAppHubWorkloadEnvironmentTypeKey.String(\"PRODUCTION\")\n\t// Staging environment.\n\t// Stability: development\n\tGCPAppHubWorkloadEnvironmentTypeStaging = GCPAppHubWorkloadEnvironmentTypeKey.String(\"STAGING\")\n\t// Test environment.\n\t// Stability: development\n\tGCPAppHubWorkloadEnvironmentTypeTest = GCPAppHubWorkloadEnvironmentTypeKey.String(\"TEST\")\n\t// Development environment.\n\t// Stability: development\n\tGCPAppHubWorkloadEnvironmentTypeDevelopment = GCPAppHubWorkloadEnvironmentTypeKey.String(\"DEVELOPMENT\")\n)\n\n// Enum values for gcp.apphub_destination.service.criticality_type\nvar (\n\t// Mission critical service.\n\t// Stability: development\n\tGCPAppHubDestinationServiceCriticalityTypeMissionCritical = GCPAppHubDestinationServiceCriticalityTypeKey.String(\"MISSION_CRITICAL\")\n\t// High impact.\n\t// Stability: development\n\tGCPAppHubDestinationServiceCriticalityTypeHigh = GCPAppHubDestinationServiceCriticalityTypeKey.String(\"HIGH\")\n\t// Medium impact.\n\t// Stability: development\n\tGCPAppHubDestinationServiceCriticalityTypeMedium = GCPAppHubDestinationServiceCriticalityTypeKey.String(\"MEDIUM\")\n\t// Low impact.\n\t// Stability: development\n\tGCPAppHubDestinationServiceCriticalityTypeLow = GCPAppHubDestinationServiceCriticalityTypeKey.String(\"LOW\")\n)\n\n// Enum values for gcp.apphub_destination.service.environment_type\nvar (\n\t// Production environment.\n\t// Stability: development\n\tGCPAppHubDestinationServiceEnvironmentTypeProduction = GCPAppHubDestinationServiceEnvironmentTypeKey.String(\"PRODUCTION\")\n\t// Staging environment.\n\t// Stability: development\n\tGCPAppHubDestinationServiceEnvironmentTypeStaging = GCPAppHubDestinationServiceEnvironmentTypeKey.String(\"STAGING\")\n\t// Test environment.\n\t// Stability: development\n\tGCPAppHubDestinationServiceEnvironmentTypeTest = GCPAppHubDestinationServiceEnvironmentTypeKey.String(\"TEST\")\n\t// Development environment.\n\t// Stability: development\n\tGCPAppHubDestinationServiceEnvironmentTypeDevelopment = GCPAppHubDestinationServiceEnvironmentTypeKey.String(\"DEVELOPMENT\")\n)\n\n// Enum values for gcp.apphub_destination.workload.criticality_type\nvar (\n\t// Mission critical service.\n\t// Stability: development\n\tGCPAppHubDestinationWorkloadCriticalityTypeMissionCritical = GCPAppHubDestinationWorkloadCriticalityTypeKey.String(\"MISSION_CRITICAL\")\n\t// High impact.\n\t// Stability: development\n\tGCPAppHubDestinationWorkloadCriticalityTypeHigh = GCPAppHubDestinationWorkloadCriticalityTypeKey.String(\"HIGH\")\n\t// Medium impact.\n\t// Stability: development\n\tGCPAppHubDestinationWorkloadCriticalityTypeMedium = GCPAppHubDestinationWorkloadCriticalityTypeKey.String(\"MEDIUM\")\n\t// Low impact.\n\t// Stability: development\n\tGCPAppHubDestinationWorkloadCriticalityTypeLow = GCPAppHubDestinationWorkloadCriticalityTypeKey.String(\"LOW\")\n)\n\n// Enum values for gcp.apphub_destination.workload.environment_type\nvar (\n\t// Production environment.\n\t// Stability: development\n\tGCPAppHubDestinationWorkloadEnvironmentTypeProduction = GCPAppHubDestinationWorkloadEnvironmentTypeKey.String(\"PRODUCTION\")\n\t// Staging environment.\n\t// Stability: development\n\tGCPAppHubDestinationWorkloadEnvironmentTypeStaging = GCPAppHubDestinationWorkloadEnvironmentTypeKey.String(\"STAGING\")\n\t// Test environment.\n\t// Stability: development\n\tGCPAppHubDestinationWorkloadEnvironmentTypeTest = GCPAppHubDestinationWorkloadEnvironmentTypeKey.String(\"TEST\")\n\t// Development environment.\n\t// Stability: development\n\tGCPAppHubDestinationWorkloadEnvironmentTypeDevelopment = GCPAppHubDestinationWorkloadEnvironmentTypeKey.String(\"DEVELOPMENT\")\n)\n\n// Namespace: gen_ai\nconst (\n\t// GenAIAgentDescriptionKey is the attribute Key conforming to the\n\t// \"gen_ai.agent.description\" semantic conventions. It represents the free-form\n\t// description of the GenAI agent provided by the application.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Helps with math problems\", \"Generates fiction stories\"\n\tGenAIAgentDescriptionKey = attribute.Key(\"gen_ai.agent.description\")\n\n\t// GenAIAgentIDKey is the attribute Key conforming to the \"gen_ai.agent.id\"\n\t// semantic conventions. It represents the unique identifier of the GenAI agent.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"asst_5j66UpCpwteGg4YSxUnt7lPY\"\n\tGenAIAgentIDKey = attribute.Key(\"gen_ai.agent.id\")\n\n\t// GenAIAgentNameKey is the attribute Key conforming to the \"gen_ai.agent.name\"\n\t// semantic conventions. It represents the human-readable name of the GenAI\n\t// agent provided by the application.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Math Tutor\", \"Fiction Writer\"\n\tGenAIAgentNameKey = attribute.Key(\"gen_ai.agent.name\")\n\n\t// GenAIConversationIDKey is the attribute Key conforming to the\n\t// \"gen_ai.conversation.id\" semantic conventions. It represents the unique\n\t// identifier for a conversation (session, thread), used to store and correlate\n\t// messages within this conversation.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"conv_5j66UpCpwteGg4YSxUnt7lPY\"\n\tGenAIConversationIDKey = attribute.Key(\"gen_ai.conversation.id\")\n\n\t// GenAIDataSourceIDKey is the attribute Key conforming to the\n\t// \"gen_ai.data_source.id\" semantic conventions. It represents the data source\n\t// identifier.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"H7STPQYOND\"\n\t// Note: Data sources are used by AI agents and RAG applications to store\n\t// grounding data. A data source may be an external database, object store,\n\t// document collection, website, or any other storage system used by the GenAI\n\t// agent or application. The `gen_ai.data_source.id` SHOULD match the identifier\n\t// used by the GenAI system rather than a name specific to the external storage,\n\t// such as a database or object store. Semantic conventions referencing\n\t// `gen_ai.data_source.id` MAY also leverage additional attributes, such as\n\t// `db.*`, to further identify and describe the data source.\n\tGenAIDataSourceIDKey = attribute.Key(\"gen_ai.data_source.id\")\n\n\t// GenAIEmbeddingsDimensionCountKey is the attribute Key conforming to the\n\t// \"gen_ai.embeddings.dimension.count\" semantic conventions. It represents the\n\t// number of dimensions the resulting output embeddings should have.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 512, 1024\n\tGenAIEmbeddingsDimensionCountKey = attribute.Key(\"gen_ai.embeddings.dimension.count\")\n\n\t// GenAIEvaluationExplanationKey is the attribute Key conforming to the\n\t// \"gen_ai.evaluation.explanation\" semantic conventions. It represents a\n\t// free-form explanation for the assigned score provided by the evaluator.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"The response is factually accurate but lacks sufficient detail to\n\t// fully address the question.\"\n\tGenAIEvaluationExplanationKey = attribute.Key(\"gen_ai.evaluation.explanation\")\n\n\t// GenAIEvaluationNameKey is the attribute Key conforming to the\n\t// \"gen_ai.evaluation.name\" semantic conventions. It represents the name of the\n\t// evaluation metric used for the GenAI response.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Relevance\", \"IntentResolution\"\n\tGenAIEvaluationNameKey = attribute.Key(\"gen_ai.evaluation.name\")\n\n\t// GenAIEvaluationScoreLabelKey is the attribute Key conforming to the\n\t// \"gen_ai.evaluation.score.label\" semantic conventions. It represents the human\n\t// readable label for evaluation.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"relevant\", \"not_relevant\", \"correct\", \"incorrect\", \"pass\", \"fail\"\n\t// Note: This attribute provides a human-readable interpretation of the\n\t// evaluation score produced by an evaluator. For example, a score value of 1\n\t// could mean \"relevant\" in one evaluation system and \"not relevant\" in another,\n\t// depending on the scoring range and evaluator. The label SHOULD have low\n\t// cardinality. Possible values depend on the evaluation metric and evaluator\n\t// used; implementations SHOULD document the possible values.\n\tGenAIEvaluationScoreLabelKey = attribute.Key(\"gen_ai.evaluation.score.label\")\n\n\t// GenAIEvaluationScoreValueKey is the attribute Key conforming to the\n\t// \"gen_ai.evaluation.score.value\" semantic conventions. It represents the\n\t// evaluation score returned by the evaluator.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 4.0\n\tGenAIEvaluationScoreValueKey = attribute.Key(\"gen_ai.evaluation.score.value\")\n\n\t// GenAIInputMessagesKey is the attribute Key conforming to the\n\t// \"gen_ai.input.messages\" semantic conventions. It represents the chat history\n\t// provided to the model as an input.\n\t//\n\t// Type: any\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"[\\n {\\n \"role\": \"user\",\\n \"parts\": [\\n {\\n \"type\": \"text\",\\n\n\t// \"content\": \"Weather in Paris?\"\\n }\\n ]\\n },\\n {\\n \"role\": \"assistant\",\\n\n\t// \"parts\": [\\n {\\n \"type\": \"tool_call\",\\n \"id\":\n\t// \"call_VSPygqKTWdrhaFErNvMV18Yl\",\\n \"name\": \"get_weather\",\\n \"arguments\": {\\n\n\t// \"location\": \"Paris\"\\n }\\n }\\n ]\\n },\\n {\\n \"role\": \"tool\",\\n \"parts\": [\\n {\\n\n\t// \"type\": \"tool_call_response\",\\n \"id\": \" call_VSPygqKTWdrhaFErNvMV18Yl\",\\n\n\t// \"result\": \"rainy, 57°F\"\\n }\\n ]\\n }\\n]\\n\"\n\t// Note: Instrumentations MUST follow [Input messages JSON schema].\n\t// When the attribute is recorded on events, it MUST be recorded in structured\n\t// form. When recorded on spans, it MAY be recorded as a JSON string if\n\t// structured\n\t// format is not supported and SHOULD be recorded in structured form otherwise.\n\t//\n\t// Messages MUST be provided in the order they were sent to the model.\n\t// Instrumentations MAY provide a way for users to filter or truncate\n\t// input messages.\n\t//\n\t// > [!Warning]\n\t// > This attribute is likely to contain sensitive information including\n\t// > user/PII data.\n\t//\n\t// See [Recording content on attributes]\n\t// section for more details.\n\t//\n\t// [Input messages JSON schema]: /docs/gen-ai/gen-ai-input-messages.json\n\t// [Recording content on attributes]: /docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes\n\tGenAIInputMessagesKey = attribute.Key(\"gen_ai.input.messages\")\n\n\t// GenAIOperationNameKey is the attribute Key conforming to the\n\t// \"gen_ai.operation.name\" semantic conventions. It represents the name of the\n\t// operation being performed.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: If one of the predefined values applies, but specific system uses a\n\t// different name it's RECOMMENDED to document it in the semantic conventions\n\t// for specific GenAI system and use system-specific name in the\n\t// instrumentation. If a different name is not documented, instrumentation\n\t// libraries SHOULD use applicable predefined value.\n\tGenAIOperationNameKey = attribute.Key(\"gen_ai.operation.name\")\n\n\t// GenAIOutputMessagesKey is the attribute Key conforming to the\n\t// \"gen_ai.output.messages\" semantic conventions. It represents the messages\n\t// returned by the model where each message represents a specific model response\n\t// (choice, candidate).\n\t//\n\t// Type: any\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"[\\n {\\n \"role\": \"assistant\",\\n \"parts\": [\\n {\\n \"type\": \"text\",\\n\n\t// \"content\": \"The weather in Paris is currently rainy with a temperature of\n\t// 57°F.\"\\n }\\n ],\\n \"finish_reason\": \"stop\"\\n }\\n]\\n\"\n\t// Note: Instrumentations MUST follow [Output messages JSON schema]\n\t//\n\t// Each message represents a single output choice/candidate generated by\n\t// the model. Each message corresponds to exactly one generation\n\t// (choice/candidate) and vice versa - one choice cannot be split across\n\t// multiple messages or one message cannot contain parts from multiple choices.\n\t//\n\t// When the attribute is recorded on events, it MUST be recorded in structured\n\t// form. When recorded on spans, it MAY be recorded as a JSON string if\n\t// structured\n\t// format is not supported and SHOULD be recorded in structured form otherwise.\n\t//\n\t// Instrumentations MAY provide a way for users to filter or truncate\n\t// output messages.\n\t//\n\t// > [!Warning]\n\t// > This attribute is likely to contain sensitive information including\n\t// > user/PII data.\n\t//\n\t// See [Recording content on attributes]\n\t// section for more details.\n\t//\n\t// [Output messages JSON schema]: /docs/gen-ai/gen-ai-output-messages.json\n\t// [Recording content on attributes]: /docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes\n\tGenAIOutputMessagesKey = attribute.Key(\"gen_ai.output.messages\")\n\n\t// GenAIOutputTypeKey is the attribute Key conforming to the\n\t// \"gen_ai.output.type\" semantic conventions. It represents the represents the\n\t// content type requested by the client.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: This attribute SHOULD be used when the client requests output of a\n\t// specific type. The model may return zero or more outputs of this type.\n\t// This attribute specifies the output modality and not the actual output\n\t// format. For example, if an image is requested, the actual output could be a\n\t// URL pointing to an image file.\n\t// Additional output format details may be recorded in the future in the\n\t// `gen_ai.output.{type}.*` attributes.\n\tGenAIOutputTypeKey = attribute.Key(\"gen_ai.output.type\")\n\n\t// GenAIPromptNameKey is the attribute Key conforming to the\n\t// \"gen_ai.prompt.name\" semantic conventions. It represents the name of the\n\t// prompt that uniquely identifies it.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"analyze-code\"\n\tGenAIPromptNameKey = attribute.Key(\"gen_ai.prompt.name\")\n\n\t// GenAIProviderNameKey is the attribute Key conforming to the\n\t// \"gen_ai.provider.name\" semantic conventions. It represents the Generative AI\n\t// provider as identified by the client or server instrumentation.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: The attribute SHOULD be set based on the instrumentation's best\n\t// knowledge and may differ from the actual model provider.\n\t//\n\t// Multiple providers, including Azure OpenAI, Gemini, and AI hosting platforms\n\t// are accessible using the OpenAI REST API and corresponding client libraries,\n\t// but may proxy or host models from different providers.\n\t//\n\t// The `gen_ai.request.model`, `gen_ai.response.model`, and `server.address`\n\t// attributes may help identify the actual system in use.\n\t//\n\t// The `gen_ai.provider.name` attribute acts as a discriminator that\n\t// identifies the GenAI telemetry format flavor specific to that provider\n\t// within GenAI semantic conventions.\n\t// It SHOULD be set consistently with provider-specific attributes and signals.\n\t// For example, GenAI spans, metrics, and events related to AWS Bedrock\n\t// should have the `gen_ai.provider.name` set to `aws.bedrock` and include\n\t// applicable `aws.bedrock.*` attributes and are not expected to include\n\t// `openai.*` attributes.\n\tGenAIProviderNameKey = attribute.Key(\"gen_ai.provider.name\")\n\n\t// GenAIRequestChoiceCountKey is the attribute Key conforming to the\n\t// \"gen_ai.request.choice.count\" semantic conventions. It represents the target\n\t// number of candidate completions to return.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 3\n\tGenAIRequestChoiceCountKey = attribute.Key(\"gen_ai.request.choice.count\")\n\n\t// GenAIRequestEncodingFormatsKey is the attribute Key conforming to the\n\t// \"gen_ai.request.encoding_formats\" semantic conventions. It represents the\n\t// encoding formats requested in an embeddings operation, if specified.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"base64\"], [\"float\", \"binary\"\n\t// Note: In some GenAI systems the encoding formats are called embedding types.\n\t// Also, some GenAI systems only accept a single format per request.\n\tGenAIRequestEncodingFormatsKey = attribute.Key(\"gen_ai.request.encoding_formats\")\n\n\t// GenAIRequestFrequencyPenaltyKey is the attribute Key conforming to the\n\t// \"gen_ai.request.frequency_penalty\" semantic conventions. It represents the\n\t// frequency penalty setting for the GenAI request.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0.1\n\tGenAIRequestFrequencyPenaltyKey = attribute.Key(\"gen_ai.request.frequency_penalty\")\n\n\t// GenAIRequestMaxTokensKey is the attribute Key conforming to the\n\t// \"gen_ai.request.max_tokens\" semantic conventions. It represents the maximum\n\t// number of tokens the model generates for a request.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 100\n\tGenAIRequestMaxTokensKey = attribute.Key(\"gen_ai.request.max_tokens\")\n\n\t// GenAIRequestModelKey is the attribute Key conforming to the\n\t// \"gen_ai.request.model\" semantic conventions. It represents the name of the\n\t// GenAI model a request is being made to.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: gpt-4\n\tGenAIRequestModelKey = attribute.Key(\"gen_ai.request.model\")\n\n\t// GenAIRequestPresencePenaltyKey is the attribute Key conforming to the\n\t// \"gen_ai.request.presence_penalty\" semantic conventions. It represents the\n\t// presence penalty setting for the GenAI request.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0.1\n\tGenAIRequestPresencePenaltyKey = attribute.Key(\"gen_ai.request.presence_penalty\")\n\n\t// GenAIRequestSeedKey is the attribute Key conforming to the\n\t// \"gen_ai.request.seed\" semantic conventions. It represents the requests with\n\t// same seed value more likely to return same result.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 100\n\tGenAIRequestSeedKey = attribute.Key(\"gen_ai.request.seed\")\n\n\t// GenAIRequestStopSequencesKey is the attribute Key conforming to the\n\t// \"gen_ai.request.stop_sequences\" semantic conventions. It represents the list\n\t// of sequences that the model will use to stop generating further tokens.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"forest\", \"lived\"\n\tGenAIRequestStopSequencesKey = attribute.Key(\"gen_ai.request.stop_sequences\")\n\n\t// GenAIRequestTemperatureKey is the attribute Key conforming to the\n\t// \"gen_ai.request.temperature\" semantic conventions. It represents the\n\t// temperature setting for the GenAI request.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0.0\n\tGenAIRequestTemperatureKey = attribute.Key(\"gen_ai.request.temperature\")\n\n\t// GenAIRequestTopKKey is the attribute Key conforming to the\n\t// \"gen_ai.request.top_k\" semantic conventions. It represents the top_k sampling\n\t// setting for the GenAI request.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1.0\n\tGenAIRequestTopKKey = attribute.Key(\"gen_ai.request.top_k\")\n\n\t// GenAIRequestTopPKey is the attribute Key conforming to the\n\t// \"gen_ai.request.top_p\" semantic conventions. It represents the top_p sampling\n\t// setting for the GenAI request.\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1.0\n\tGenAIRequestTopPKey = attribute.Key(\"gen_ai.request.top_p\")\n\n\t// GenAIResponseFinishReasonsKey is the attribute Key conforming to the\n\t// \"gen_ai.response.finish_reasons\" semantic conventions. It represents the\n\t// array of reasons the model stopped generating tokens, corresponding to each\n\t// generation received.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"stop\"], [\"stop\", \"length\"\n\tGenAIResponseFinishReasonsKey = attribute.Key(\"gen_ai.response.finish_reasons\")\n\n\t// GenAIResponseIDKey is the attribute Key conforming to the\n\t// \"gen_ai.response.id\" semantic conventions. It represents the unique\n\t// identifier for the completion.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"chatcmpl-123\"\n\tGenAIResponseIDKey = attribute.Key(\"gen_ai.response.id\")\n\n\t// GenAIResponseModelKey is the attribute Key conforming to the\n\t// \"gen_ai.response.model\" semantic conventions. It represents the name of the\n\t// model that generated the response.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"gpt-4-0613\"\n\tGenAIResponseModelKey = attribute.Key(\"gen_ai.response.model\")\n\n\t// GenAISystemInstructionsKey is the attribute Key conforming to the\n\t// \"gen_ai.system_instructions\" semantic conventions. It represents the system\n\t// message or instructions provided to the GenAI model separately from the chat\n\t// history.\n\t//\n\t// Type: any\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"[\\n {\\n \"type\": \"text\",\\n \"content\": \"You are an Agent that greet\n\t// users, always use greetings tool to respond\"\\n }\\n]\\n\", \"[\\n {\\n \"type\":\n\t// \"text\",\\n \"content\": \"You are a language translator.\"\\n },\\n {\\n \"type\":\n\t// \"text\",\\n \"content\": \"Your mission is to translate text in English to\n\t// French.\"\\n }\\n]\\n\"\n\t// Note: This attribute SHOULD be used when the corresponding provider or API\n\t// allows to provide system instructions or messages separately from the\n\t// chat history.\n\t//\n\t// Instructions that are part of the chat history SHOULD be recorded in\n\t// `gen_ai.input.messages` attribute instead.\n\t//\n\t// Instrumentations MUST follow [System instructions JSON schema].\n\t//\n\t// When recorded on spans, it MAY be recorded as a JSON string if structured\n\t// format is not supported and SHOULD be recorded in structured form otherwise.\n\t//\n\t// Instrumentations MAY provide a way for users to filter or truncate\n\t// system instructions.\n\t//\n\t// > [!Warning]\n\t// > This attribute may contain sensitive information.\n\t//\n\t// See [Recording content on attributes]\n\t// section for more details.\n\t//\n\t// [System instructions JSON schema]: /docs/gen-ai/gen-ai-system-instructions.json\n\t// [Recording content on attributes]: /docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes\n\tGenAISystemInstructionsKey = attribute.Key(\"gen_ai.system_instructions\")\n\n\t// GenAITokenTypeKey is the attribute Key conforming to the \"gen_ai.token.type\"\n\t// semantic conventions. It represents the type of token being counted.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"input\", \"output\"\n\tGenAITokenTypeKey = attribute.Key(\"gen_ai.token.type\")\n\n\t// GenAIToolCallArgumentsKey is the attribute Key conforming to the\n\t// \"gen_ai.tool.call.arguments\" semantic conventions. It represents the\n\t// parameters passed to the tool call.\n\t//\n\t// Type: any\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"{\\n \"location\": \"San Francisco?\",\\n \"date\": \"2025-10-01\"\\n}\\n\"\n\t// Note: > [!WARNING]\n\t//\n\t// > This attribute may contain sensitive information.\n\t//\n\t// It's expected to be an object - in case a serialized string is available\n\t// to the instrumentation, the instrumentation SHOULD do the best effort to\n\t// deserialize it to an object. When recorded on spans, it MAY be recorded as a\n\t// JSON string if structured format is not supported and SHOULD be recorded in\n\t// structured form otherwise.\n\tGenAIToolCallArgumentsKey = attribute.Key(\"gen_ai.tool.call.arguments\")\n\n\t// GenAIToolCallIDKey is the attribute Key conforming to the\n\t// \"gen_ai.tool.call.id\" semantic conventions. It represents the tool call\n\t// identifier.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"call_mszuSIzqtI65i1wAUOE8w5H4\"\n\tGenAIToolCallIDKey = attribute.Key(\"gen_ai.tool.call.id\")\n\n\t// GenAIToolCallResultKey is the attribute Key conforming to the\n\t// \"gen_ai.tool.call.result\" semantic conventions. It represents the result\n\t// returned by the tool call (if any and if execution was successful).\n\t//\n\t// Type: any\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"{\\n \"temperature_range\": {\\n \"high\": 75,\\n \"low\": 60\\n },\\n\n\t// \"conditions\": \"sunny\"\\n}\\n\"\n\t// Note: > [!WARNING]\n\t//\n\t// > This attribute may contain sensitive information.\n\t//\n\t// It's expected to be an object - in case a serialized string is available\n\t// to the instrumentation, the instrumentation SHOULD do the best effort to\n\t// deserialize it to an object. When recorded on spans, it MAY be recorded as a\n\t// JSON string if structured format is not supported and SHOULD be recorded in\n\t// structured form otherwise.\n\tGenAIToolCallResultKey = attribute.Key(\"gen_ai.tool.call.result\")\n\n\t// GenAIToolDefinitionsKey is the attribute Key conforming to the\n\t// \"gen_ai.tool.definitions\" semantic conventions. It represents the list of\n\t// source system tool definitions available to the GenAI agent or model.\n\t//\n\t// Type: any\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"[\\n {\\n \"type\": \"function\",\\n \"name\": \"get_current_weather\",\\n\n\t// \"description\": \"Get the current weather in a given location\",\\n \"parameters\":\n\t// {\\n \"type\": \"object\",\\n \"properties\": {\\n \"location\": {\\n \"type\": \"string\",\\n\n\t// \"description\": \"The city and state, e.g. San Francisco, CA\"\\n },\\n \"unit\":\n\t// {\\n \"type\": \"string\",\\n \"enum\": [\\n \"celsius\",\\n \"fahrenheit\"\\n ]\\n }\\n },\\n\n\t// \"required\": [\\n \"location\",\\n \"unit\"\\n ]\\n }\\n }\\n]\\n\"\n\t// Note: The value of this attribute matches source system tool definition\n\t// format.\n\t//\n\t// It's expected to be an array of objects where each object represents a tool\n\t// definition. In case a serialized string is available\n\t// to the instrumentation, the instrumentation SHOULD do the best effort to\n\t// deserialize it to an array. When recorded on spans, it MAY be recorded as a\n\t// JSON string if structured format is not supported and SHOULD be recorded in\n\t// structured form otherwise.\n\t//\n\t// Since this attribute could be large, it's NOT RECOMMENDED to populate\n\t// it by default. Instrumentations MAY provide a way to enable\n\t// populating this attribute.\n\tGenAIToolDefinitionsKey = attribute.Key(\"gen_ai.tool.definitions\")\n\n\t// GenAIToolDescriptionKey is the attribute Key conforming to the\n\t// \"gen_ai.tool.description\" semantic conventions. It represents the tool\n\t// description.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Multiply two numbers\"\n\tGenAIToolDescriptionKey = attribute.Key(\"gen_ai.tool.description\")\n\n\t// GenAIToolNameKey is the attribute Key conforming to the \"gen_ai.tool.name\"\n\t// semantic conventions. It represents the name of the tool utilized by the\n\t// agent.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Flights\"\n\tGenAIToolNameKey = attribute.Key(\"gen_ai.tool.name\")\n\n\t// GenAIToolTypeKey is the attribute Key conforming to the \"gen_ai.tool.type\"\n\t// semantic conventions. It represents the type of the tool utilized by the\n\t// agent.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"function\", \"extension\", \"datastore\"\n\t// Note: Extension: A tool executed on the agent-side to directly call external\n\t// APIs, bridging the gap between the agent and real-world systems.\n\t// Agent-side operations involve actions that are performed by the agent on the\n\t// server or within the agent's controlled environment.\n\t// Function: A tool executed on the client-side, where the agent generates\n\t// parameters for a predefined function, and the client executes the logic.\n\t// Client-side operations are actions taken on the user's end or within the\n\t// client application.\n\t// Datastore: A tool used by the agent to access and query structured or\n\t// unstructured external data for retrieval-augmented tasks or knowledge\n\t// updates.\n\tGenAIToolTypeKey = attribute.Key(\"gen_ai.tool.type\")\n\n\t// GenAIUsageInputTokensKey is the attribute Key conforming to the\n\t// \"gen_ai.usage.input_tokens\" semantic conventions. It represents the number of\n\t// tokens used in the GenAI input (prompt).\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 100\n\tGenAIUsageInputTokensKey = attribute.Key(\"gen_ai.usage.input_tokens\")\n\n\t// GenAIUsageOutputTokensKey is the attribute Key conforming to the\n\t// \"gen_ai.usage.output_tokens\" semantic conventions. It represents the number\n\t// of tokens used in the GenAI response (completion).\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 180\n\tGenAIUsageOutputTokensKey = attribute.Key(\"gen_ai.usage.output_tokens\")\n)\n\n// GenAIAgentDescription returns an attribute KeyValue conforming to the\n// \"gen_ai.agent.description\" semantic conventions. It represents the free-form\n// description of the GenAI agent provided by the application.\nfunc GenAIAgentDescription(val string) attribute.KeyValue {\n\treturn GenAIAgentDescriptionKey.String(val)\n}\n\n// GenAIAgentID returns an attribute KeyValue conforming to the \"gen_ai.agent.id\"\n// semantic conventions. It represents the unique identifier of the GenAI agent.\nfunc GenAIAgentID(val string) attribute.KeyValue {\n\treturn GenAIAgentIDKey.String(val)\n}\n\n// GenAIAgentName returns an attribute KeyValue conforming to the\n// \"gen_ai.agent.name\" semantic conventions. It represents the human-readable\n// name of the GenAI agent provided by the application.\nfunc GenAIAgentName(val string) attribute.KeyValue {\n\treturn GenAIAgentNameKey.String(val)\n}\n\n// GenAIConversationID returns an attribute KeyValue conforming to the\n// \"gen_ai.conversation.id\" semantic conventions. It represents the unique\n// identifier for a conversation (session, thread), used to store and correlate\n// messages within this conversation.\nfunc GenAIConversationID(val string) attribute.KeyValue {\n\treturn GenAIConversationIDKey.String(val)\n}\n\n// GenAIDataSourceID returns an attribute KeyValue conforming to the\n// \"gen_ai.data_source.id\" semantic conventions. It represents the data source\n// identifier.\nfunc GenAIDataSourceID(val string) attribute.KeyValue {\n\treturn GenAIDataSourceIDKey.String(val)\n}\n\n// GenAIEmbeddingsDimensionCount returns an attribute KeyValue conforming to the\n// \"gen_ai.embeddings.dimension.count\" semantic conventions. It represents the\n// number of dimensions the resulting output embeddings should have.\nfunc GenAIEmbeddingsDimensionCount(val int) attribute.KeyValue {\n\treturn GenAIEmbeddingsDimensionCountKey.Int(val)\n}\n\n// GenAIEvaluationExplanation returns an attribute KeyValue conforming to the\n// \"gen_ai.evaluation.explanation\" semantic conventions. It represents a\n// free-form explanation for the assigned score provided by the evaluator.\nfunc GenAIEvaluationExplanation(val string) attribute.KeyValue {\n\treturn GenAIEvaluationExplanationKey.String(val)\n}\n\n// GenAIEvaluationName returns an attribute KeyValue conforming to the\n// \"gen_ai.evaluation.name\" semantic conventions. It represents the name of the\n// evaluation metric used for the GenAI response.\nfunc GenAIEvaluationName(val string) attribute.KeyValue {\n\treturn GenAIEvaluationNameKey.String(val)\n}\n\n// GenAIEvaluationScoreLabel returns an attribute KeyValue conforming to the\n// \"gen_ai.evaluation.score.label\" semantic conventions. It represents the human\n// readable label for evaluation.\nfunc GenAIEvaluationScoreLabel(val string) attribute.KeyValue {\n\treturn GenAIEvaluationScoreLabelKey.String(val)\n}\n\n// GenAIEvaluationScoreValue returns an attribute KeyValue conforming to the\n// \"gen_ai.evaluation.score.value\" semantic conventions. It represents the\n// evaluation score returned by the evaluator.\nfunc GenAIEvaluationScoreValue(val float64) attribute.KeyValue {\n\treturn GenAIEvaluationScoreValueKey.Float64(val)\n}\n\n// GenAIPromptName returns an attribute KeyValue conforming to the\n// \"gen_ai.prompt.name\" semantic conventions. It represents the name of the\n// prompt that uniquely identifies it.\nfunc GenAIPromptName(val string) attribute.KeyValue {\n\treturn GenAIPromptNameKey.String(val)\n}\n\n// GenAIRequestChoiceCount returns an attribute KeyValue conforming to the\n// \"gen_ai.request.choice.count\" semantic conventions. It represents the target\n// number of candidate completions to return.\nfunc GenAIRequestChoiceCount(val int) attribute.KeyValue {\n\treturn GenAIRequestChoiceCountKey.Int(val)\n}\n\n// GenAIRequestEncodingFormats returns an attribute KeyValue conforming to the\n// \"gen_ai.request.encoding_formats\" semantic conventions. It represents the\n// encoding formats requested in an embeddings operation, if specified.\nfunc GenAIRequestEncodingFormats(val ...string) attribute.KeyValue {\n\treturn GenAIRequestEncodingFormatsKey.StringSlice(val)\n}\n\n// GenAIRequestFrequencyPenalty returns an attribute KeyValue conforming to the\n// \"gen_ai.request.frequency_penalty\" semantic conventions. It represents the\n// frequency penalty setting for the GenAI request.\nfunc GenAIRequestFrequencyPenalty(val float64) attribute.KeyValue {\n\treturn GenAIRequestFrequencyPenaltyKey.Float64(val)\n}\n\n// GenAIRequestMaxTokens returns an attribute KeyValue conforming to the\n// \"gen_ai.request.max_tokens\" semantic conventions. It represents the maximum\n// number of tokens the model generates for a request.\nfunc GenAIRequestMaxTokens(val int) attribute.KeyValue {\n\treturn GenAIRequestMaxTokensKey.Int(val)\n}\n\n// GenAIRequestModel returns an attribute KeyValue conforming to the\n// \"gen_ai.request.model\" semantic conventions. It represents the name of the\n// GenAI model a request is being made to.\nfunc GenAIRequestModel(val string) attribute.KeyValue {\n\treturn GenAIRequestModelKey.String(val)\n}\n\n// GenAIRequestPresencePenalty returns an attribute KeyValue conforming to the\n// \"gen_ai.request.presence_penalty\" semantic conventions. It represents the\n// presence penalty setting for the GenAI request.\nfunc GenAIRequestPresencePenalty(val float64) attribute.KeyValue {\n\treturn GenAIRequestPresencePenaltyKey.Float64(val)\n}\n\n// GenAIRequestSeed returns an attribute KeyValue conforming to the\n// \"gen_ai.request.seed\" semantic conventions. It represents the requests with\n// same seed value more likely to return same result.\nfunc GenAIRequestSeed(val int) attribute.KeyValue {\n\treturn GenAIRequestSeedKey.Int(val)\n}\n\n// GenAIRequestStopSequences returns an attribute KeyValue conforming to the\n// \"gen_ai.request.stop_sequences\" semantic conventions. It represents the list\n// of sequences that the model will use to stop generating further tokens.\nfunc GenAIRequestStopSequences(val ...string) attribute.KeyValue {\n\treturn GenAIRequestStopSequencesKey.StringSlice(val)\n}\n\n// GenAIRequestTemperature returns an attribute KeyValue conforming to the\n// \"gen_ai.request.temperature\" semantic conventions. It represents the\n// temperature setting for the GenAI request.\nfunc GenAIRequestTemperature(val float64) attribute.KeyValue {\n\treturn GenAIRequestTemperatureKey.Float64(val)\n}\n\n// GenAIRequestTopK returns an attribute KeyValue conforming to the\n// \"gen_ai.request.top_k\" semantic conventions. It represents the top_k sampling\n// setting for the GenAI request.\nfunc GenAIRequestTopK(val float64) attribute.KeyValue {\n\treturn GenAIRequestTopKKey.Float64(val)\n}\n\n// GenAIRequestTopP returns an attribute KeyValue conforming to the\n// \"gen_ai.request.top_p\" semantic conventions. It represents the top_p sampling\n// setting for the GenAI request.\nfunc GenAIRequestTopP(val float64) attribute.KeyValue {\n\treturn GenAIRequestTopPKey.Float64(val)\n}\n\n// GenAIResponseFinishReasons returns an attribute KeyValue conforming to the\n// \"gen_ai.response.finish_reasons\" semantic conventions. It represents the array\n// of reasons the model stopped generating tokens, corresponding to each\n// generation received.\nfunc GenAIResponseFinishReasons(val ...string) attribute.KeyValue {\n\treturn GenAIResponseFinishReasonsKey.StringSlice(val)\n}\n\n// GenAIResponseID returns an attribute KeyValue conforming to the\n// \"gen_ai.response.id\" semantic conventions. It represents the unique identifier\n// for the completion.\nfunc GenAIResponseID(val string) attribute.KeyValue {\n\treturn GenAIResponseIDKey.String(val)\n}\n\n// GenAIResponseModel returns an attribute KeyValue conforming to the\n// \"gen_ai.response.model\" semantic conventions. It represents the name of the\n// model that generated the response.\nfunc GenAIResponseModel(val string) attribute.KeyValue {\n\treturn GenAIResponseModelKey.String(val)\n}\n\n// GenAIToolCallID returns an attribute KeyValue conforming to the\n// \"gen_ai.tool.call.id\" semantic conventions. It represents the tool call\n// identifier.\nfunc GenAIToolCallID(val string) attribute.KeyValue {\n\treturn GenAIToolCallIDKey.String(val)\n}\n\n// GenAIToolDescription returns an attribute KeyValue conforming to the\n// \"gen_ai.tool.description\" semantic conventions. It represents the tool\n// description.\nfunc GenAIToolDescription(val string) attribute.KeyValue {\n\treturn GenAIToolDescriptionKey.String(val)\n}\n\n// GenAIToolName returns an attribute KeyValue conforming to the\n// \"gen_ai.tool.name\" semantic conventions. It represents the name of the tool\n// utilized by the agent.\nfunc GenAIToolName(val string) attribute.KeyValue {\n\treturn GenAIToolNameKey.String(val)\n}\n\n// GenAIToolType returns an attribute KeyValue conforming to the\n// \"gen_ai.tool.type\" semantic conventions. It represents the type of the tool\n// utilized by the agent.\nfunc GenAIToolType(val string) attribute.KeyValue {\n\treturn GenAIToolTypeKey.String(val)\n}\n\n// GenAIUsageInputTokens returns an attribute KeyValue conforming to the\n// \"gen_ai.usage.input_tokens\" semantic conventions. It represents the number of\n// tokens used in the GenAI input (prompt).\nfunc GenAIUsageInputTokens(val int) attribute.KeyValue {\n\treturn GenAIUsageInputTokensKey.Int(val)\n}\n\n// GenAIUsageOutputTokens returns an attribute KeyValue conforming to the\n// \"gen_ai.usage.output_tokens\" semantic conventions. It represents the number of\n// tokens used in the GenAI response (completion).\nfunc GenAIUsageOutputTokens(val int) attribute.KeyValue {\n\treturn GenAIUsageOutputTokensKey.Int(val)\n}\n\n// Enum values for gen_ai.operation.name\nvar (\n\t// Chat completion operation such as [OpenAI Chat API]\n\t// Stability: development\n\t//\n\t// [OpenAI Chat API]: https://platform.openai.com/docs/api-reference/chat\n\tGenAIOperationNameChat = GenAIOperationNameKey.String(\"chat\")\n\t// Multimodal content generation operation such as [Gemini Generate Content]\n\t// Stability: development\n\t//\n\t// [Gemini Generate Content]: https://ai.google.dev/api/generate-content\n\tGenAIOperationNameGenerateContent = GenAIOperationNameKey.String(\"generate_content\")\n\t// Text completions operation such as [OpenAI Completions API (Legacy)]\n\t// Stability: development\n\t//\n\t// [OpenAI Completions API (Legacy)]: https://platform.openai.com/docs/api-reference/completions\n\tGenAIOperationNameTextCompletion = GenAIOperationNameKey.String(\"text_completion\")\n\t// Embeddings operation such as [OpenAI Create embeddings API]\n\t// Stability: development\n\t//\n\t// [OpenAI Create embeddings API]: https://platform.openai.com/docs/api-reference/embeddings/create\n\tGenAIOperationNameEmbeddings = GenAIOperationNameKey.String(\"embeddings\")\n\t// Create GenAI agent\n\t// Stability: development\n\tGenAIOperationNameCreateAgent = GenAIOperationNameKey.String(\"create_agent\")\n\t// Invoke GenAI agent\n\t// Stability: development\n\tGenAIOperationNameInvokeAgent = GenAIOperationNameKey.String(\"invoke_agent\")\n\t// Execute a tool\n\t// Stability: development\n\tGenAIOperationNameExecuteTool = GenAIOperationNameKey.String(\"execute_tool\")\n)\n\n// Enum values for gen_ai.output.type\nvar (\n\t// Plain text\n\t// Stability: development\n\tGenAIOutputTypeText = GenAIOutputTypeKey.String(\"text\")\n\t// JSON object with known or unknown schema\n\t// Stability: development\n\tGenAIOutputTypeJSON = GenAIOutputTypeKey.String(\"json\")\n\t// Image\n\t// Stability: development\n\tGenAIOutputTypeImage = GenAIOutputTypeKey.String(\"image\")\n\t// Speech\n\t// Stability: development\n\tGenAIOutputTypeSpeech = GenAIOutputTypeKey.String(\"speech\")\n)\n\n// Enum values for gen_ai.provider.name\nvar (\n\t// [OpenAI]\n\t// Stability: development\n\t//\n\t// [OpenAI]: https://openai.com/\n\tGenAIProviderNameOpenAI = GenAIProviderNameKey.String(\"openai\")\n\t// Any Google generative AI endpoint\n\t// Stability: development\n\tGenAIProviderNameGCPGenAI = GenAIProviderNameKey.String(\"gcp.gen_ai\")\n\t// [Vertex AI]\n\t// Stability: development\n\t//\n\t// [Vertex AI]: https://cloud.google.com/vertex-ai\n\tGenAIProviderNameGCPVertexAI = GenAIProviderNameKey.String(\"gcp.vertex_ai\")\n\t// [Gemini]\n\t// Stability: development\n\t//\n\t// [Gemini]: https://cloud.google.com/products/gemini\n\tGenAIProviderNameGCPGemini = GenAIProviderNameKey.String(\"gcp.gemini\")\n\t// [Anthropic]\n\t// Stability: development\n\t//\n\t// [Anthropic]: https://www.anthropic.com/\n\tGenAIProviderNameAnthropic = GenAIProviderNameKey.String(\"anthropic\")\n\t// [Cohere]\n\t// Stability: development\n\t//\n\t// [Cohere]: https://cohere.com/\n\tGenAIProviderNameCohere = GenAIProviderNameKey.String(\"cohere\")\n\t// Azure AI Inference\n\t// Stability: development\n\tGenAIProviderNameAzureAIInference = GenAIProviderNameKey.String(\"azure.ai.inference\")\n\t// [Azure OpenAI]\n\t// Stability: development\n\t//\n\t// [Azure OpenAI]: https://azure.microsoft.com/products/ai-services/openai-service/\n\tGenAIProviderNameAzureAIOpenAI = GenAIProviderNameKey.String(\"azure.ai.openai\")\n\t// [IBM Watsonx AI]\n\t// Stability: development\n\t//\n\t// [IBM Watsonx AI]: https://www.ibm.com/products/watsonx-ai\n\tGenAIProviderNameIBMWatsonxAI = GenAIProviderNameKey.String(\"ibm.watsonx.ai\")\n\t// [AWS Bedrock]\n\t// Stability: development\n\t//\n\t// [AWS Bedrock]: https://aws.amazon.com/bedrock\n\tGenAIProviderNameAWSBedrock = GenAIProviderNameKey.String(\"aws.bedrock\")\n\t// [Perplexity]\n\t// Stability: development\n\t//\n\t// [Perplexity]: https://www.perplexity.ai/\n\tGenAIProviderNamePerplexity = GenAIProviderNameKey.String(\"perplexity\")\n\t// [xAI]\n\t// Stability: development\n\t//\n\t// [xAI]: https://x.ai/\n\tGenAIProviderNameXAI = GenAIProviderNameKey.String(\"x_ai\")\n\t// [DeepSeek]\n\t// Stability: development\n\t//\n\t// [DeepSeek]: https://www.deepseek.com/\n\tGenAIProviderNameDeepseek = GenAIProviderNameKey.String(\"deepseek\")\n\t// [Groq]\n\t// Stability: development\n\t//\n\t// [Groq]: https://groq.com/\n\tGenAIProviderNameGroq = GenAIProviderNameKey.String(\"groq\")\n\t// [Mistral AI]\n\t// Stability: development\n\t//\n\t// [Mistral AI]: https://mistral.ai/\n\tGenAIProviderNameMistralAI = GenAIProviderNameKey.String(\"mistral_ai\")\n)\n\n// Enum values for gen_ai.token.type\nvar (\n\t// Input tokens (prompt, input, etc.)\n\t// Stability: development\n\tGenAITokenTypeInput = GenAITokenTypeKey.String(\"input\")\n\t// Output tokens (completion, response, etc.)\n\t// Stability: development\n\tGenAITokenTypeOutput = GenAITokenTypeKey.String(\"output\")\n)\n\n// Namespace: geo\nconst (\n\t// GeoContinentCodeKey is the attribute Key conforming to the\n\t// \"geo.continent.code\" semantic conventions. It represents the two-letter code\n\t// representing continent’s name.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tGeoContinentCodeKey = attribute.Key(\"geo.continent.code\")\n\n\t// GeoCountryISOCodeKey is the attribute Key conforming to the\n\t// \"geo.country.iso_code\" semantic conventions. It represents the two-letter ISO\n\t// Country Code ([ISO 3166-1 alpha2]).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"CA\"\n\t//\n\t// [ISO 3166-1 alpha2]: https://wikipedia.org/wiki/ISO_3166-1#Codes\n\tGeoCountryISOCodeKey = attribute.Key(\"geo.country.iso_code\")\n\n\t// GeoLocalityNameKey is the attribute Key conforming to the \"geo.locality.name\"\n\t// semantic conventions. It represents the locality name. Represents the name of\n\t// a city, town, village, or similar populated place.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Montreal\", \"Berlin\"\n\tGeoLocalityNameKey = attribute.Key(\"geo.locality.name\")\n\n\t// GeoLocationLatKey is the attribute Key conforming to the \"geo.location.lat\"\n\t// semantic conventions. It represents the latitude of the geo location in\n\t// [WGS84].\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 45.505918\n\t//\n\t// [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84\n\tGeoLocationLatKey = attribute.Key(\"geo.location.lat\")\n\n\t// GeoLocationLonKey is the attribute Key conforming to the \"geo.location.lon\"\n\t// semantic conventions. It represents the longitude of the geo location in\n\t// [WGS84].\n\t//\n\t// Type: double\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: -73.61483\n\t//\n\t// [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84\n\tGeoLocationLonKey = attribute.Key(\"geo.location.lon\")\n\n\t// GeoPostalCodeKey is the attribute Key conforming to the \"geo.postal_code\"\n\t// semantic conventions. It represents the postal code associated with the\n\t// location. Values appropriate for this field may also be known as a postcode\n\t// or ZIP code and will vary widely from country to country.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"94040\"\n\tGeoPostalCodeKey = attribute.Key(\"geo.postal_code\")\n\n\t// GeoRegionISOCodeKey is the attribute Key conforming to the\n\t// \"geo.region.iso_code\" semantic conventions. It represents the region ISO code\n\t// ([ISO 3166-2]).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"CA-QC\"\n\t//\n\t// [ISO 3166-2]: https://wikipedia.org/wiki/ISO_3166-2\n\tGeoRegionISOCodeKey = attribute.Key(\"geo.region.iso_code\")\n)\n\n// GeoCountryISOCode returns an attribute KeyValue conforming to the\n// \"geo.country.iso_code\" semantic conventions. It represents the two-letter ISO\n// Country Code ([ISO 3166-1 alpha2]).\n//\n// [ISO 3166-1 alpha2]: https://wikipedia.org/wiki/ISO_3166-1#Codes\nfunc GeoCountryISOCode(val string) attribute.KeyValue {\n\treturn GeoCountryISOCodeKey.String(val)\n}\n\n// GeoLocalityName returns an attribute KeyValue conforming to the\n// \"geo.locality.name\" semantic conventions. It represents the locality name.\n// Represents the name of a city, town, village, or similar populated place.\nfunc GeoLocalityName(val string) attribute.KeyValue {\n\treturn GeoLocalityNameKey.String(val)\n}\n\n// GeoLocationLat returns an attribute KeyValue conforming to the\n// \"geo.location.lat\" semantic conventions. It represents the latitude of the geo\n// location in [WGS84].\n//\n// [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84\nfunc GeoLocationLat(val float64) attribute.KeyValue {\n\treturn GeoLocationLatKey.Float64(val)\n}\n\n// GeoLocationLon returns an attribute KeyValue conforming to the\n// \"geo.location.lon\" semantic conventions. It represents the longitude of the\n// geo location in [WGS84].\n//\n// [WGS84]: https://wikipedia.org/wiki/World_Geodetic_System#WGS84\nfunc GeoLocationLon(val float64) attribute.KeyValue {\n\treturn GeoLocationLonKey.Float64(val)\n}\n\n// GeoPostalCode returns an attribute KeyValue conforming to the\n// \"geo.postal_code\" semantic conventions. It represents the postal code\n// associated with the location. Values appropriate for this field may also be\n// known as a postcode or ZIP code and will vary widely from country to country.\nfunc GeoPostalCode(val string) attribute.KeyValue {\n\treturn GeoPostalCodeKey.String(val)\n}\n\n// GeoRegionISOCode returns an attribute KeyValue conforming to the\n// \"geo.region.iso_code\" semantic conventions. It represents the region ISO code\n// ([ISO 3166-2]).\n//\n// [ISO 3166-2]: https://wikipedia.org/wiki/ISO_3166-2\nfunc GeoRegionISOCode(val string) attribute.KeyValue {\n\treturn GeoRegionISOCodeKey.String(val)\n}\n\n// Enum values for geo.continent.code\nvar (\n\t// Africa\n\t// Stability: development\n\tGeoContinentCodeAf = GeoContinentCodeKey.String(\"AF\")\n\t// Antarctica\n\t// Stability: development\n\tGeoContinentCodeAn = GeoContinentCodeKey.String(\"AN\")\n\t// Asia\n\t// Stability: development\n\tGeoContinentCodeAs = GeoContinentCodeKey.String(\"AS\")\n\t// Europe\n\t// Stability: development\n\tGeoContinentCodeEu = GeoContinentCodeKey.String(\"EU\")\n\t// North America\n\t// Stability: development\n\tGeoContinentCodeNa = GeoContinentCodeKey.String(\"NA\")\n\t// Oceania\n\t// Stability: development\n\tGeoContinentCodeOc = GeoContinentCodeKey.String(\"OC\")\n\t// South America\n\t// Stability: development\n\tGeoContinentCodeSa = GeoContinentCodeKey.String(\"SA\")\n)\n\n// Namespace: go\nconst (\n\t// GoMemoryTypeKey is the attribute Key conforming to the \"go.memory.type\"\n\t// semantic conventions. It represents the type of memory.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"other\", \"stack\"\n\tGoMemoryTypeKey = attribute.Key(\"go.memory.type\")\n)\n\n// Enum values for go.memory.type\nvar (\n\t// Memory allocated from the heap that is reserved for stack space, whether or\n\t// not it is currently in-use.\n\t// Stability: development\n\tGoMemoryTypeStack = GoMemoryTypeKey.String(\"stack\")\n\t// Memory used by the Go runtime, excluding other categories of memory usage\n\t// described in this enumeration.\n\t// Stability: development\n\tGoMemoryTypeOther = GoMemoryTypeKey.String(\"other\")\n)\n\n// Namespace: graphql\nconst (\n\t// GraphQLDocumentKey is the attribute Key conforming to the \"graphql.document\"\n\t// semantic conventions. It represents the GraphQL document being executed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: query findBookById { bookById(id: ?) { name } }\n\t// Note: The value may be sanitized to exclude sensitive information.\n\tGraphQLDocumentKey = attribute.Key(\"graphql.document\")\n\n\t// GraphQLOperationNameKey is the attribute Key conforming to the\n\t// \"graphql.operation.name\" semantic conventions. It represents the name of the\n\t// operation being executed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: findBookById\n\tGraphQLOperationNameKey = attribute.Key(\"graphql.operation.name\")\n\n\t// GraphQLOperationTypeKey is the attribute Key conforming to the\n\t// \"graphql.operation.type\" semantic conventions. It represents the type of the\n\t// operation being executed.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"query\", \"mutation\", \"subscription\"\n\tGraphQLOperationTypeKey = attribute.Key(\"graphql.operation.type\")\n)\n\n// GraphQLDocument returns an attribute KeyValue conforming to the\n// \"graphql.document\" semantic conventions. It represents the GraphQL document\n// being executed.\nfunc GraphQLDocument(val string) attribute.KeyValue {\n\treturn GraphQLDocumentKey.String(val)\n}\n\n// GraphQLOperationName returns an attribute KeyValue conforming to the\n// \"graphql.operation.name\" semantic conventions. It represents the name of the\n// operation being executed.\nfunc GraphQLOperationName(val string) attribute.KeyValue {\n\treturn GraphQLOperationNameKey.String(val)\n}\n\n// Enum values for graphql.operation.type\nvar (\n\t// GraphQL query\n\t// Stability: development\n\tGraphQLOperationTypeQuery = GraphQLOperationTypeKey.String(\"query\")\n\t// GraphQL mutation\n\t// Stability: development\n\tGraphQLOperationTypeMutation = GraphQLOperationTypeKey.String(\"mutation\")\n\t// GraphQL subscription\n\t// Stability: development\n\tGraphQLOperationTypeSubscription = GraphQLOperationTypeKey.String(\"subscription\")\n)\n\n// Namespace: heroku\nconst (\n\t// HerokuAppIDKey is the attribute Key conforming to the \"heroku.app.id\"\n\t// semantic conventions. It represents the unique identifier for the\n\t// application.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2daa2797-e42b-4624-9322-ec3f968df4da\"\n\tHerokuAppIDKey = attribute.Key(\"heroku.app.id\")\n\n\t// HerokuReleaseCommitKey is the attribute Key conforming to the\n\t// \"heroku.release.commit\" semantic conventions. It represents the commit hash\n\t// for the current release.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"e6134959463efd8966b20e75b913cafe3f5ec\"\n\tHerokuReleaseCommitKey = attribute.Key(\"heroku.release.commit\")\n\n\t// HerokuReleaseCreationTimestampKey is the attribute Key conforming to the\n\t// \"heroku.release.creation_timestamp\" semantic conventions. It represents the\n\t// time and date the release was created.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2022-10-23T18:00:42Z\"\n\tHerokuReleaseCreationTimestampKey = attribute.Key(\"heroku.release.creation_timestamp\")\n)\n\n// HerokuAppID returns an attribute KeyValue conforming to the \"heroku.app.id\"\n// semantic conventions. It represents the unique identifier for the application.\nfunc HerokuAppID(val string) attribute.KeyValue {\n\treturn HerokuAppIDKey.String(val)\n}\n\n// HerokuReleaseCommit returns an attribute KeyValue conforming to the\n// \"heroku.release.commit\" semantic conventions. It represents the commit hash\n// for the current release.\nfunc HerokuReleaseCommit(val string) attribute.KeyValue {\n\treturn HerokuReleaseCommitKey.String(val)\n}\n\n// HerokuReleaseCreationTimestamp returns an attribute KeyValue conforming to the\n// \"heroku.release.creation_timestamp\" semantic conventions. It represents the\n// time and date the release was created.\nfunc HerokuReleaseCreationTimestamp(val string) attribute.KeyValue {\n\treturn HerokuReleaseCreationTimestampKey.String(val)\n}\n\n// Namespace: host\nconst (\n\t// HostArchKey is the attribute Key conforming to the \"host.arch\" semantic\n\t// conventions. It represents the CPU architecture the host system is running\n\t// on.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tHostArchKey = attribute.Key(\"host.arch\")\n\n\t// HostCPUCacheL2SizeKey is the attribute Key conforming to the\n\t// \"host.cpu.cache.l2.size\" semantic conventions. It represents the amount of\n\t// level 2 memory cache available to the processor (in Bytes).\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 12288000\n\tHostCPUCacheL2SizeKey = attribute.Key(\"host.cpu.cache.l2.size\")\n\n\t// HostCPUFamilyKey is the attribute Key conforming to the \"host.cpu.family\"\n\t// semantic conventions. It represents the family or generation of the CPU.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"6\", \"PA-RISC 1.1e\"\n\tHostCPUFamilyKey = attribute.Key(\"host.cpu.family\")\n\n\t// HostCPUModelIDKey is the attribute Key conforming to the \"host.cpu.model.id\"\n\t// semantic conventions. It represents the model identifier. It provides more\n\t// granular information about the CPU, distinguishing it from other CPUs within\n\t// the same family.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"6\", \"9000/778/B180L\"\n\tHostCPUModelIDKey = attribute.Key(\"host.cpu.model.id\")\n\n\t// HostCPUModelNameKey is the attribute Key conforming to the\n\t// \"host.cpu.model.name\" semantic conventions. It represents the model\n\t// designation of the processor.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz\"\n\tHostCPUModelNameKey = attribute.Key(\"host.cpu.model.name\")\n\n\t// HostCPUSteppingKey is the attribute Key conforming to the \"host.cpu.stepping\"\n\t// semantic conventions. It represents the stepping or core revisions.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1\", \"r1p1\"\n\tHostCPUSteppingKey = attribute.Key(\"host.cpu.stepping\")\n\n\t// HostCPUVendorIDKey is the attribute Key conforming to the\n\t// \"host.cpu.vendor.id\" semantic conventions. It represents the processor\n\t// manufacturer identifier. A maximum 12-character string.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"GenuineIntel\"\n\t// Note: [CPUID] command returns the vendor ID string in EBX, EDX and ECX\n\t// registers. Writing these to memory in this order results in a 12-character\n\t// string.\n\t//\n\t// [CPUID]: https://wiki.osdev.org/CPUID\n\tHostCPUVendorIDKey = attribute.Key(\"host.cpu.vendor.id\")\n\n\t// HostIDKey is the attribute Key conforming to the \"host.id\" semantic\n\t// conventions. It represents the unique host ID. For Cloud, this must be the\n\t// instance_id assigned by the cloud provider. For non-containerized systems,\n\t// this should be the `machine-id`. See the table below for the sources to use\n\t// to determine the `machine-id` based on operating system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"fdbf79e8af94cb7f9e8df36789187052\"\n\tHostIDKey = attribute.Key(\"host.id\")\n\n\t// HostImageIDKey is the attribute Key conforming to the \"host.image.id\"\n\t// semantic conventions. It represents the VM image ID or host OS image ID. For\n\t// Cloud, this value is from the provider.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"ami-07b06b442921831e5\"\n\tHostImageIDKey = attribute.Key(\"host.image.id\")\n\n\t// HostImageNameKey is the attribute Key conforming to the \"host.image.name\"\n\t// semantic conventions. It represents the name of the VM image or OS install\n\t// the host was instantiated from.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"infra-ami-eks-worker-node-7d4ec78312\", \"CentOS-8-x86_64-1905\"\n\tHostImageNameKey = attribute.Key(\"host.image.name\")\n\n\t// HostImageVersionKey is the attribute Key conforming to the\n\t// \"host.image.version\" semantic conventions. It represents the version string\n\t// of the VM image or host OS as defined in [Version Attributes].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"0.1\"\n\t//\n\t// [Version Attributes]: /docs/resource/README.md#version-attributes\n\tHostImageVersionKey = attribute.Key(\"host.image.version\")\n\n\t// HostIPKey is the attribute Key conforming to the \"host.ip\" semantic\n\t// conventions. It represents the available IP addresses of the host, excluding\n\t// loopback interfaces.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"192.168.1.140\", \"fe80::abc2:4a28:737a:609e\"\n\t// Note: IPv4 Addresses MUST be specified in dotted-quad notation. IPv6\n\t// addresses MUST be specified in the [RFC 5952] format.\n\t//\n\t// [RFC 5952]: https://www.rfc-editor.org/rfc/rfc5952.html\n\tHostIPKey = attribute.Key(\"host.ip\")\n\n\t// HostMacKey is the attribute Key conforming to the \"host.mac\" semantic\n\t// conventions. It represents the available MAC addresses of the host, excluding\n\t// loopback interfaces.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"AC-DE-48-23-45-67\", \"AC-DE-48-23-45-67-01-9F\"\n\t// Note: MAC Addresses MUST be represented in [IEEE RA hexadecimal form]: as\n\t// hyphen-separated octets in uppercase hexadecimal form from most to least\n\t// significant.\n\t//\n\t// [IEEE RA hexadecimal form]: https://standards.ieee.org/wp-content/uploads/import/documents/tutorials/eui.pdf\n\tHostMacKey = attribute.Key(\"host.mac\")\n\n\t// HostNameKey is the attribute Key conforming to the \"host.name\" semantic\n\t// conventions. It represents the name of the host. On Unix systems, it may\n\t// contain what the hostname command returns, or the fully qualified hostname,\n\t// or another name specified by the user.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry-test\"\n\tHostNameKey = attribute.Key(\"host.name\")\n\n\t// HostTypeKey is the attribute Key conforming to the \"host.type\" semantic\n\t// conventions. It represents the type of host. For Cloud, this must be the\n\t// machine type.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"n1-standard-1\"\n\tHostTypeKey = attribute.Key(\"host.type\")\n)\n\n// HostCPUCacheL2Size returns an attribute KeyValue conforming to the\n// \"host.cpu.cache.l2.size\" semantic conventions. It represents the amount of\n// level 2 memory cache available to the processor (in Bytes).\nfunc HostCPUCacheL2Size(val int) attribute.KeyValue {\n\treturn HostCPUCacheL2SizeKey.Int(val)\n}\n\n// HostCPUFamily returns an attribute KeyValue conforming to the\n// \"host.cpu.family\" semantic conventions. It represents the family or generation\n// of the CPU.\nfunc HostCPUFamily(val string) attribute.KeyValue {\n\treturn HostCPUFamilyKey.String(val)\n}\n\n// HostCPUModelID returns an attribute KeyValue conforming to the\n// \"host.cpu.model.id\" semantic conventions. It represents the model identifier.\n// It provides more granular information about the CPU, distinguishing it from\n// other CPUs within the same family.\nfunc HostCPUModelID(val string) attribute.KeyValue {\n\treturn HostCPUModelIDKey.String(val)\n}\n\n// HostCPUModelName returns an attribute KeyValue conforming to the\n// \"host.cpu.model.name\" semantic conventions. It represents the model\n// designation of the processor.\nfunc HostCPUModelName(val string) attribute.KeyValue {\n\treturn HostCPUModelNameKey.String(val)\n}\n\n// HostCPUStepping returns an attribute KeyValue conforming to the\n// \"host.cpu.stepping\" semantic conventions. It represents the stepping or core\n// revisions.\nfunc HostCPUStepping(val string) attribute.KeyValue {\n\treturn HostCPUSteppingKey.String(val)\n}\n\n// HostCPUVendorID returns an attribute KeyValue conforming to the\n// \"host.cpu.vendor.id\" semantic conventions. It represents the processor\n// manufacturer identifier. A maximum 12-character string.\nfunc HostCPUVendorID(val string) attribute.KeyValue {\n\treturn HostCPUVendorIDKey.String(val)\n}\n\n// HostID returns an attribute KeyValue conforming to the \"host.id\" semantic\n// conventions. It represents the unique host ID. For Cloud, this must be the\n// instance_id assigned by the cloud provider. For non-containerized systems,\n// this should be the `machine-id`. See the table below for the sources to use to\n// determine the `machine-id` based on operating system.\nfunc HostID(val string) attribute.KeyValue {\n\treturn HostIDKey.String(val)\n}\n\n// HostImageID returns an attribute KeyValue conforming to the \"host.image.id\"\n// semantic conventions. It represents the VM image ID or host OS image ID. For\n// Cloud, this value is from the provider.\nfunc HostImageID(val string) attribute.KeyValue {\n\treturn HostImageIDKey.String(val)\n}\n\n// HostImageName returns an attribute KeyValue conforming to the\n// \"host.image.name\" semantic conventions. It represents the name of the VM image\n// or OS install the host was instantiated from.\nfunc HostImageName(val string) attribute.KeyValue {\n\treturn HostImageNameKey.String(val)\n}\n\n// HostImageVersion returns an attribute KeyValue conforming to the\n// \"host.image.version\" semantic conventions. It represents the version string of\n// the VM image or host OS as defined in [Version Attributes].\n//\n// [Version Attributes]: /docs/resource/README.md#version-attributes\nfunc HostImageVersion(val string) attribute.KeyValue {\n\treturn HostImageVersionKey.String(val)\n}\n\n// HostIP returns an attribute KeyValue conforming to the \"host.ip\" semantic\n// conventions. It represents the available IP addresses of the host, excluding\n// loopback interfaces.\nfunc HostIP(val ...string) attribute.KeyValue {\n\treturn HostIPKey.StringSlice(val)\n}\n\n// HostMac returns an attribute KeyValue conforming to the \"host.mac\" semantic\n// conventions. It represents the available MAC addresses of the host, excluding\n// loopback interfaces.\nfunc HostMac(val ...string) attribute.KeyValue {\n\treturn HostMacKey.StringSlice(val)\n}\n\n// HostName returns an attribute KeyValue conforming to the \"host.name\" semantic\n// conventions. It represents the name of the host. On Unix systems, it may\n// contain what the hostname command returns, or the fully qualified hostname, or\n// another name specified by the user.\nfunc HostName(val string) attribute.KeyValue {\n\treturn HostNameKey.String(val)\n}\n\n// HostType returns an attribute KeyValue conforming to the \"host.type\" semantic\n// conventions. It represents the type of host. For Cloud, this must be the\n// machine type.\nfunc HostType(val string) attribute.KeyValue {\n\treturn HostTypeKey.String(val)\n}\n\n// Enum values for host.arch\nvar (\n\t// AMD64\n\t// Stability: development\n\tHostArchAMD64 = HostArchKey.String(\"amd64\")\n\t// ARM32\n\t// Stability: development\n\tHostArchARM32 = HostArchKey.String(\"arm32\")\n\t// ARM64\n\t// Stability: development\n\tHostArchARM64 = HostArchKey.String(\"arm64\")\n\t// Itanium\n\t// Stability: development\n\tHostArchIA64 = HostArchKey.String(\"ia64\")\n\t// 32-bit PowerPC\n\t// Stability: development\n\tHostArchPPC32 = HostArchKey.String(\"ppc32\")\n\t// 64-bit PowerPC\n\t// Stability: development\n\tHostArchPPC64 = HostArchKey.String(\"ppc64\")\n\t// IBM z/Architecture\n\t// Stability: development\n\tHostArchS390x = HostArchKey.String(\"s390x\")\n\t// 32-bit x86\n\t// Stability: development\n\tHostArchX86 = HostArchKey.String(\"x86\")\n)\n\n// Namespace: http\nconst (\n\t// HTTPConnectionStateKey is the attribute Key conforming to the\n\t// \"http.connection.state\" semantic conventions. It represents the state of the\n\t// HTTP connection in the HTTP connection pool.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"active\", \"idle\"\n\tHTTPConnectionStateKey = attribute.Key(\"http.connection.state\")\n\n\t// HTTPRequestBodySizeKey is the attribute Key conforming to the\n\t// \"http.request.body.size\" semantic conventions. It represents the size of the\n\t// request payload body in bytes. This is the number of bytes transferred\n\t// excluding headers and is often, but not always, present as the\n\t// [Content-Length] header. For requests using transport encoding, this should\n\t// be the compressed size.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length\n\tHTTPRequestBodySizeKey = attribute.Key(\"http.request.body.size\")\n\n\t// HTTPRequestMethodKey is the attribute Key conforming to the\n\t// \"http.request.method\" semantic conventions. It represents the HTTP request\n\t// method.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"GET\", \"POST\", \"HEAD\"\n\t// Note: HTTP request method value SHOULD be \"known\" to the instrumentation.\n\t// By default, this convention defines \"known\" methods as the ones listed in\n\t// [RFC9110],\n\t// the PATCH method defined in [RFC5789]\n\t// and the QUERY method defined in [httpbis-safe-method-w-body].\n\t//\n\t// If the HTTP request method is not known to instrumentation, it MUST set the\n\t// `http.request.method` attribute to `_OTHER`.\n\t//\n\t// If the HTTP instrumentation could end up converting valid HTTP request\n\t// methods to `_OTHER`, then it MUST provide a way to override\n\t// the list of known HTTP methods. If this override is done via environment\n\t// variable, then the environment variable MUST be named\n\t// OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of\n\t// case-sensitive known HTTP methods\n\t// (this list MUST be a full override of the default known method, it is not a\n\t// list of known methods in addition to the defaults).\n\t//\n\t// HTTP method names are case-sensitive and `http.request.method` attribute\n\t// value MUST match a known HTTP method name exactly.\n\t// Instrumentations for specific web frameworks that consider HTTP methods to be\n\t// case insensitive, SHOULD populate a canonical equivalent.\n\t// Tracing instrumentations that do so, MUST also set\n\t// `http.request.method_original` to the original value.\n\t//\n\t// [RFC9110]: https://www.rfc-editor.org/rfc/rfc9110.html#name-methods\n\t// [RFC5789]: https://www.rfc-editor.org/rfc/rfc5789.html\n\t// [httpbis-safe-method-w-body]: https://datatracker.ietf.org/doc/draft-ietf-httpbis-safe-method-w-body/?include_text=1\n\tHTTPRequestMethodKey = attribute.Key(\"http.request.method\")\n\n\t// HTTPRequestMethodOriginalKey is the attribute Key conforming to the\n\t// \"http.request.method_original\" semantic conventions. It represents the\n\t// original HTTP method sent by the client in the request line.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"GeT\", \"ACL\", \"foo\"\n\tHTTPRequestMethodOriginalKey = attribute.Key(\"http.request.method_original\")\n\n\t// HTTPRequestResendCountKey is the attribute Key conforming to the\n\t// \"http.request.resend_count\" semantic conventions. It represents the ordinal\n\t// number of request resending attempt (for any reason, including redirects).\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Note: The resend count SHOULD be updated each time an HTTP request gets\n\t// resent by the client, regardless of what was the cause of the resending (e.g.\n\t// redirection, authorization failure, 503 Server Unavailable, network issues,\n\t// or any other).\n\tHTTPRequestResendCountKey = attribute.Key(\"http.request.resend_count\")\n\n\t// HTTPRequestSizeKey is the attribute Key conforming to the \"http.request.size\"\n\t// semantic conventions. It represents the total size of the request in bytes.\n\t// This should be the total number of bytes sent over the wire, including the\n\t// request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request\n\t// body if any.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tHTTPRequestSizeKey = attribute.Key(\"http.request.size\")\n\n\t// HTTPResponseBodySizeKey is the attribute Key conforming to the\n\t// \"http.response.body.size\" semantic conventions. It represents the size of the\n\t// response payload body in bytes. This is the number of bytes transferred\n\t// excluding headers and is often, but not always, present as the\n\t// [Content-Length] header. For requests using transport encoding, this should\n\t// be the compressed size.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length\n\tHTTPResponseBodySizeKey = attribute.Key(\"http.response.body.size\")\n\n\t// HTTPResponseSizeKey is the attribute Key conforming to the\n\t// \"http.response.size\" semantic conventions. It represents the total size of\n\t// the response in bytes. This should be the total number of bytes sent over the\n\t// wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3),\n\t// headers, and response body and trailers if any.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tHTTPResponseSizeKey = attribute.Key(\"http.response.size\")\n\n\t// HTTPResponseStatusCodeKey is the attribute Key conforming to the\n\t// \"http.response.status_code\" semantic conventions. It represents the\n\t// [HTTP response status code].\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: 200\n\t//\n\t// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6\n\tHTTPResponseStatusCodeKey = attribute.Key(\"http.response.status_code\")\n\n\t// HTTPRouteKey is the attribute Key conforming to the \"http.route\" semantic\n\t// conventions. It represents the matched route template for the request. This\n\t// MUST be low-cardinality and include all static path segments, with dynamic\n\t// path segments represented with placeholders.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"/users/:userID?\", \"my-controller/my-action/{id?}\"\n\t// Note: MUST NOT be populated when this is not supported by the HTTP server\n\t// framework as the route attribute should have low-cardinality and the URI path\n\t// can NOT substitute it.\n\t// SHOULD include the [application root] if there is one.\n\t//\n\t// A static path segment is a part of the route template with a fixed,\n\t// low-cardinality value. This includes literal strings like `/users/` and\n\t// placeholders that\n\t// are constrained to a finite, predefined set of values, e.g. `{controller}` or\n\t// `{action}`.\n\t//\n\t// A dynamic path segment is a placeholder for a value that can have high\n\t// cardinality and is not constrained to a predefined list like static path\n\t// segments.\n\t//\n\t// Instrumentations SHOULD use routing information provided by the corresponding\n\t// web framework. They SHOULD pick the most precise source of routing\n\t// information and MAY\n\t// support custom route formatting. Instrumentations SHOULD document the format\n\t// and the API used to obtain the route string.\n\t//\n\t// [application root]: /docs/http/http-spans.md#http-server-definitions\n\tHTTPRouteKey = attribute.Key(\"http.route\")\n)\n\n// HTTPRequestBodySize returns an attribute KeyValue conforming to the\n// \"http.request.body.size\" semantic conventions. It represents the size of the\n// request payload body in bytes. This is the number of bytes transferred\n// excluding headers and is often, but not always, present as the\n// [Content-Length] header. For requests using transport encoding, this should be\n// the compressed size.\n//\n// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length\nfunc HTTPRequestBodySize(val int) attribute.KeyValue {\n\treturn HTTPRequestBodySizeKey.Int(val)\n}\n\n// HTTPRequestHeader returns an attribute KeyValue conforming to the\n// \"http.request.header\" semantic conventions. It represents the HTTP request\n// headers, `<key>` being the normalized HTTP Header name (lowercase), the value\n// being the header values.\nfunc HTTPRequestHeader(key string, val ...string) attribute.KeyValue {\n\treturn attribute.StringSlice(\"http.request.header.\"+key, val)\n}\n\n// HTTPRequestMethodOriginal returns an attribute KeyValue conforming to the\n// \"http.request.method_original\" semantic conventions. It represents the\n// original HTTP method sent by the client in the request line.\nfunc HTTPRequestMethodOriginal(val string) attribute.KeyValue {\n\treturn HTTPRequestMethodOriginalKey.String(val)\n}\n\n// HTTPRequestResendCount returns an attribute KeyValue conforming to the\n// \"http.request.resend_count\" semantic conventions. It represents the ordinal\n// number of request resending attempt (for any reason, including redirects).\nfunc HTTPRequestResendCount(val int) attribute.KeyValue {\n\treturn HTTPRequestResendCountKey.Int(val)\n}\n\n// HTTPRequestSize returns an attribute KeyValue conforming to the\n// \"http.request.size\" semantic conventions. It represents the total size of the\n// request in bytes. This should be the total number of bytes sent over the wire,\n// including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers,\n// and request body if any.\nfunc HTTPRequestSize(val int) attribute.KeyValue {\n\treturn HTTPRequestSizeKey.Int(val)\n}\n\n// HTTPResponseBodySize returns an attribute KeyValue conforming to the\n// \"http.response.body.size\" semantic conventions. It represents the size of the\n// response payload body in bytes. This is the number of bytes transferred\n// excluding headers and is often, but not always, present as the\n// [Content-Length] header. For requests using transport encoding, this should be\n// the compressed size.\n//\n// [Content-Length]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length\nfunc HTTPResponseBodySize(val int) attribute.KeyValue {\n\treturn HTTPResponseBodySizeKey.Int(val)\n}\n\n// HTTPResponseHeader returns an attribute KeyValue conforming to the\n// \"http.response.header\" semantic conventions. It represents the HTTP response\n// headers, `<key>` being the normalized HTTP Header name (lowercase), the value\n// being the header values.\nfunc HTTPResponseHeader(key string, val ...string) attribute.KeyValue {\n\treturn attribute.StringSlice(\"http.response.header.\"+key, val)\n}\n\n// HTTPResponseSize returns an attribute KeyValue conforming to the\n// \"http.response.size\" semantic conventions. It represents the total size of the\n// response in bytes. This should be the total number of bytes sent over the\n// wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3),\n// headers, and response body and trailers if any.\nfunc HTTPResponseSize(val int) attribute.KeyValue {\n\treturn HTTPResponseSizeKey.Int(val)\n}\n\n// HTTPResponseStatusCode returns an attribute KeyValue conforming to the\n// \"http.response.status_code\" semantic conventions. It represents the\n// [HTTP response status code].\n//\n// [HTTP response status code]: https://tools.ietf.org/html/rfc7231#section-6\nfunc HTTPResponseStatusCode(val int) attribute.KeyValue {\n\treturn HTTPResponseStatusCodeKey.Int(val)\n}\n\n// HTTPRoute returns an attribute KeyValue conforming to the \"http.route\"\n// semantic conventions. It represents the matched route template for the\n// request. This MUST be low-cardinality and include all static path segments,\n// with dynamic path segments represented with placeholders.\nfunc HTTPRoute(val string) attribute.KeyValue {\n\treturn HTTPRouteKey.String(val)\n}\n\n// Enum values for http.connection.state\nvar (\n\t// active state.\n\t// Stability: development\n\tHTTPConnectionStateActive = HTTPConnectionStateKey.String(\"active\")\n\t// idle state.\n\t// Stability: development\n\tHTTPConnectionStateIdle = HTTPConnectionStateKey.String(\"idle\")\n)\n\n// Enum values for http.request.method\nvar (\n\t// CONNECT method.\n\t// Stability: stable\n\tHTTPRequestMethodConnect = HTTPRequestMethodKey.String(\"CONNECT\")\n\t// DELETE method.\n\t// Stability: stable\n\tHTTPRequestMethodDelete = HTTPRequestMethodKey.String(\"DELETE\")\n\t// GET method.\n\t// Stability: stable\n\tHTTPRequestMethodGet = HTTPRequestMethodKey.String(\"GET\")\n\t// HEAD method.\n\t// Stability: stable\n\tHTTPRequestMethodHead = HTTPRequestMethodKey.String(\"HEAD\")\n\t// OPTIONS method.\n\t// Stability: stable\n\tHTTPRequestMethodOptions = HTTPRequestMethodKey.String(\"OPTIONS\")\n\t// PATCH method.\n\t// Stability: stable\n\tHTTPRequestMethodPatch = HTTPRequestMethodKey.String(\"PATCH\")\n\t// POST method.\n\t// Stability: stable\n\tHTTPRequestMethodPost = HTTPRequestMethodKey.String(\"POST\")\n\t// PUT method.\n\t// Stability: stable\n\tHTTPRequestMethodPut = HTTPRequestMethodKey.String(\"PUT\")\n\t// TRACE method.\n\t// Stability: stable\n\tHTTPRequestMethodTrace = HTTPRequestMethodKey.String(\"TRACE\")\n\t// QUERY method.\n\t// Stability: development\n\tHTTPRequestMethodQuery = HTTPRequestMethodKey.String(\"QUERY\")\n\t// Any HTTP method that the instrumentation has no prior knowledge of.\n\t// Stability: stable\n\tHTTPRequestMethodOther = HTTPRequestMethodKey.String(\"_OTHER\")\n)\n\n// Namespace: hw\nconst (\n\t// HwBatteryCapacityKey is the attribute Key conforming to the\n\t// \"hw.battery.capacity\" semantic conventions. It represents the design capacity\n\t// in Watts-hours or Amper-hours.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"9.3Ah\", \"50Wh\"\n\tHwBatteryCapacityKey = attribute.Key(\"hw.battery.capacity\")\n\n\t// HwBatteryChemistryKey is the attribute Key conforming to the\n\t// \"hw.battery.chemistry\" semantic conventions. It represents the battery\n\t// [chemistry], e.g. Lithium-Ion, Nickel-Cadmium, etc.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Li-ion\", \"NiMH\"\n\t//\n\t// [chemistry]: https://schemas.dmtf.org/wbem/cim-html/2.31.0/CIM_Battery.html\n\tHwBatteryChemistryKey = attribute.Key(\"hw.battery.chemistry\")\n\n\t// HwBatteryStateKey is the attribute Key conforming to the \"hw.battery.state\"\n\t// semantic conventions. It represents the current state of the battery.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tHwBatteryStateKey = attribute.Key(\"hw.battery.state\")\n\n\t// HwBiosVersionKey is the attribute Key conforming to the \"hw.bios_version\"\n\t// semantic conventions. It represents the BIOS version of the hardware\n\t// component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1.2.3\"\n\tHwBiosVersionKey = attribute.Key(\"hw.bios_version\")\n\n\t// HwDriverVersionKey is the attribute Key conforming to the \"hw.driver_version\"\n\t// semantic conventions. It represents the driver version for the hardware\n\t// component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"10.2.1-3\"\n\tHwDriverVersionKey = attribute.Key(\"hw.driver_version\")\n\n\t// HwEnclosureTypeKey is the attribute Key conforming to the \"hw.enclosure.type\"\n\t// semantic conventions. It represents the type of the enclosure (useful for\n\t// modular systems).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Computer\", \"Storage\", \"Switch\"\n\tHwEnclosureTypeKey = attribute.Key(\"hw.enclosure.type\")\n\n\t// HwFirmwareVersionKey is the attribute Key conforming to the\n\t// \"hw.firmware_version\" semantic conventions. It represents the firmware\n\t// version of the hardware component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2.0.1\"\n\tHwFirmwareVersionKey = attribute.Key(\"hw.firmware_version\")\n\n\t// HwGpuTaskKey is the attribute Key conforming to the \"hw.gpu.task\" semantic\n\t// conventions. It represents the type of task the GPU is performing.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tHwGpuTaskKey = attribute.Key(\"hw.gpu.task\")\n\n\t// HwIDKey is the attribute Key conforming to the \"hw.id\" semantic conventions.\n\t// It represents an identifier for the hardware component, unique within the\n\t// monitored host.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"win32battery_battery_testsysa33_1\"\n\tHwIDKey = attribute.Key(\"hw.id\")\n\n\t// HwLimitTypeKey is the attribute Key conforming to the \"hw.limit_type\"\n\t// semantic conventions. It represents the type of limit for hardware\n\t// components.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tHwLimitTypeKey = attribute.Key(\"hw.limit_type\")\n\n\t// HwLogicalDiskRaidLevelKey is the attribute Key conforming to the\n\t// \"hw.logical_disk.raid_level\" semantic conventions. It represents the RAID\n\t// Level of the logical disk.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"RAID0+1\", \"RAID5\", \"RAID10\"\n\tHwLogicalDiskRaidLevelKey = attribute.Key(\"hw.logical_disk.raid_level\")\n\n\t// HwLogicalDiskStateKey is the attribute Key conforming to the\n\t// \"hw.logical_disk.state\" semantic conventions. It represents the state of the\n\t// logical disk space usage.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tHwLogicalDiskStateKey = attribute.Key(\"hw.logical_disk.state\")\n\n\t// HwMemoryTypeKey is the attribute Key conforming to the \"hw.memory.type\"\n\t// semantic conventions. It represents the type of the memory module.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"DDR4\", \"DDR5\", \"LPDDR5\"\n\tHwMemoryTypeKey = attribute.Key(\"hw.memory.type\")\n\n\t// HwModelKey is the attribute Key conforming to the \"hw.model\" semantic\n\t// conventions. It represents the descriptive model name of the hardware\n\t// component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"PERC H740P\", \"Intel(R) Core(TM) i7-10700K\", \"Dell XPS 15 Battery\"\n\tHwModelKey = attribute.Key(\"hw.model\")\n\n\t// HwNameKey is the attribute Key conforming to the \"hw.name\" semantic\n\t// conventions. It represents an easily-recognizable name for the hardware\n\t// component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"eth0\"\n\tHwNameKey = attribute.Key(\"hw.name\")\n\n\t// HwNetworkLogicalAddressesKey is the attribute Key conforming to the\n\t// \"hw.network.logical_addresses\" semantic conventions. It represents the\n\t// logical addresses of the adapter (e.g. IP address, or WWPN).\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"172.16.8.21\", \"57.11.193.42\"\n\tHwNetworkLogicalAddressesKey = attribute.Key(\"hw.network.logical_addresses\")\n\n\t// HwNetworkPhysicalAddressKey is the attribute Key conforming to the\n\t// \"hw.network.physical_address\" semantic conventions. It represents the\n\t// physical address of the adapter (e.g. MAC address, or WWNN).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"00-90-F5-E9-7B-36\"\n\tHwNetworkPhysicalAddressKey = attribute.Key(\"hw.network.physical_address\")\n\n\t// HwParentKey is the attribute Key conforming to the \"hw.parent\" semantic\n\t// conventions. It represents the unique identifier of the parent component\n\t// (typically the `hw.id` attribute of the enclosure, or disk controller).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"dellStorage_perc_0\"\n\tHwParentKey = attribute.Key(\"hw.parent\")\n\n\t// HwPhysicalDiskSmartAttributeKey is the attribute Key conforming to the\n\t// \"hw.physical_disk.smart_attribute\" semantic conventions. It represents the\n\t// [S.M.A.R.T.] (Self-Monitoring, Analysis, and Reporting Technology) attribute\n\t// of the physical disk.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Spin Retry Count\", \"Seek Error Rate\", \"Raw Read Error Rate\"\n\t//\n\t// [S.M.A.R.T.]: https://wikipedia.org/wiki/S.M.A.R.T.\n\tHwPhysicalDiskSmartAttributeKey = attribute.Key(\"hw.physical_disk.smart_attribute\")\n\n\t// HwPhysicalDiskStateKey is the attribute Key conforming to the\n\t// \"hw.physical_disk.state\" semantic conventions. It represents the state of the\n\t// physical disk endurance utilization.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tHwPhysicalDiskStateKey = attribute.Key(\"hw.physical_disk.state\")\n\n\t// HwPhysicalDiskTypeKey is the attribute Key conforming to the\n\t// \"hw.physical_disk.type\" semantic conventions. It represents the type of the\n\t// physical disk.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"HDD\", \"SSD\", \"10K\"\n\tHwPhysicalDiskTypeKey = attribute.Key(\"hw.physical_disk.type\")\n\n\t// HwSensorLocationKey is the attribute Key conforming to the\n\t// \"hw.sensor_location\" semantic conventions. It represents the location of the\n\t// sensor.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"cpu0\", \"ps1\", \"INLET\", \"CPU0_DIE\", \"AMBIENT\", \"MOTHERBOARD\", \"PS0\n\t// V3_3\", \"MAIN_12V\", \"CPU_VCORE\"\n\tHwSensorLocationKey = attribute.Key(\"hw.sensor_location\")\n\n\t// HwSerialNumberKey is the attribute Key conforming to the \"hw.serial_number\"\n\t// semantic conventions. It represents the serial number of the hardware\n\t// component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"CNFCP0123456789\"\n\tHwSerialNumberKey = attribute.Key(\"hw.serial_number\")\n\n\t// HwStateKey is the attribute Key conforming to the \"hw.state\" semantic\n\t// conventions. It represents the current state of the component.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tHwStateKey = attribute.Key(\"hw.state\")\n\n\t// HwTapeDriveOperationTypeKey is the attribute Key conforming to the\n\t// \"hw.tape_drive.operation_type\" semantic conventions. It represents the type\n\t// of tape drive operation.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tHwTapeDriveOperationTypeKey = attribute.Key(\"hw.tape_drive.operation_type\")\n\n\t// HwTypeKey is the attribute Key conforming to the \"hw.type\" semantic\n\t// conventions. It represents the type of the component.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: Describes the category of the hardware component for which `hw.state`\n\t// is being reported. For example, `hw.type=temperature` along with\n\t// `hw.state=degraded` would indicate that the temperature of the hardware\n\t// component has been reported as `degraded`.\n\tHwTypeKey = attribute.Key(\"hw.type\")\n\n\t// HwVendorKey is the attribute Key conforming to the \"hw.vendor\" semantic\n\t// conventions. It represents the vendor name of the hardware component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Dell\", \"HP\", \"Intel\", \"AMD\", \"LSI\", \"Lenovo\"\n\tHwVendorKey = attribute.Key(\"hw.vendor\")\n)\n\n// HwBatteryCapacity returns an attribute KeyValue conforming to the\n// \"hw.battery.capacity\" semantic conventions. It represents the design capacity\n// in Watts-hours or Amper-hours.\nfunc HwBatteryCapacity(val string) attribute.KeyValue {\n\treturn HwBatteryCapacityKey.String(val)\n}\n\n// HwBatteryChemistry returns an attribute KeyValue conforming to the\n// \"hw.battery.chemistry\" semantic conventions. It represents the battery\n// [chemistry], e.g. Lithium-Ion, Nickel-Cadmium, etc.\n//\n// [chemistry]: https://schemas.dmtf.org/wbem/cim-html/2.31.0/CIM_Battery.html\nfunc HwBatteryChemistry(val string) attribute.KeyValue {\n\treturn HwBatteryChemistryKey.String(val)\n}\n\n// HwBiosVersion returns an attribute KeyValue conforming to the\n// \"hw.bios_version\" semantic conventions. It represents the BIOS version of the\n// hardware component.\nfunc HwBiosVersion(val string) attribute.KeyValue {\n\treturn HwBiosVersionKey.String(val)\n}\n\n// HwDriverVersion returns an attribute KeyValue conforming to the\n// \"hw.driver_version\" semantic conventions. It represents the driver version for\n// the hardware component.\nfunc HwDriverVersion(val string) attribute.KeyValue {\n\treturn HwDriverVersionKey.String(val)\n}\n\n// HwEnclosureType returns an attribute KeyValue conforming to the\n// \"hw.enclosure.type\" semantic conventions. It represents the type of the\n// enclosure (useful for modular systems).\nfunc HwEnclosureType(val string) attribute.KeyValue {\n\treturn HwEnclosureTypeKey.String(val)\n}\n\n// HwFirmwareVersion returns an attribute KeyValue conforming to the\n// \"hw.firmware_version\" semantic conventions. It represents the firmware version\n// of the hardware component.\nfunc HwFirmwareVersion(val string) attribute.KeyValue {\n\treturn HwFirmwareVersionKey.String(val)\n}\n\n// HwID returns an attribute KeyValue conforming to the \"hw.id\" semantic\n// conventions. It represents an identifier for the hardware component, unique\n// within the monitored host.\nfunc HwID(val string) attribute.KeyValue {\n\treturn HwIDKey.String(val)\n}\n\n// HwLogicalDiskRaidLevel returns an attribute KeyValue conforming to the\n// \"hw.logical_disk.raid_level\" semantic conventions. It represents the RAID\n// Level of the logical disk.\nfunc HwLogicalDiskRaidLevel(val string) attribute.KeyValue {\n\treturn HwLogicalDiskRaidLevelKey.String(val)\n}\n\n// HwMemoryType returns an attribute KeyValue conforming to the \"hw.memory.type\"\n// semantic conventions. It represents the type of the memory module.\nfunc HwMemoryType(val string) attribute.KeyValue {\n\treturn HwMemoryTypeKey.String(val)\n}\n\n// HwModel returns an attribute KeyValue conforming to the \"hw.model\" semantic\n// conventions. It represents the descriptive model name of the hardware\n// component.\nfunc HwModel(val string) attribute.KeyValue {\n\treturn HwModelKey.String(val)\n}\n\n// HwName returns an attribute KeyValue conforming to the \"hw.name\" semantic\n// conventions. It represents an easily-recognizable name for the hardware\n// component.\nfunc HwName(val string) attribute.KeyValue {\n\treturn HwNameKey.String(val)\n}\n\n// HwNetworkLogicalAddresses returns an attribute KeyValue conforming to the\n// \"hw.network.logical_addresses\" semantic conventions. It represents the logical\n// addresses of the adapter (e.g. IP address, or WWPN).\nfunc HwNetworkLogicalAddresses(val ...string) attribute.KeyValue {\n\treturn HwNetworkLogicalAddressesKey.StringSlice(val)\n}\n\n// HwNetworkPhysicalAddress returns an attribute KeyValue conforming to the\n// \"hw.network.physical_address\" semantic conventions. It represents the physical\n// address of the adapter (e.g. MAC address, or WWNN).\nfunc HwNetworkPhysicalAddress(val string) attribute.KeyValue {\n\treturn HwNetworkPhysicalAddressKey.String(val)\n}\n\n// HwParent returns an attribute KeyValue conforming to the \"hw.parent\" semantic\n// conventions. It represents the unique identifier of the parent component\n// (typically the `hw.id` attribute of the enclosure, or disk controller).\nfunc HwParent(val string) attribute.KeyValue {\n\treturn HwParentKey.String(val)\n}\n\n// HwPhysicalDiskSmartAttribute returns an attribute KeyValue conforming to the\n// \"hw.physical_disk.smart_attribute\" semantic conventions. It represents the\n// [S.M.A.R.T.] (Self-Monitoring, Analysis, and Reporting Technology) attribute\n// of the physical disk.\n//\n// [S.M.A.R.T.]: https://wikipedia.org/wiki/S.M.A.R.T.\nfunc HwPhysicalDiskSmartAttribute(val string) attribute.KeyValue {\n\treturn HwPhysicalDiskSmartAttributeKey.String(val)\n}\n\n// HwPhysicalDiskType returns an attribute KeyValue conforming to the\n// \"hw.physical_disk.type\" semantic conventions. It represents the type of the\n// physical disk.\nfunc HwPhysicalDiskType(val string) attribute.KeyValue {\n\treturn HwPhysicalDiskTypeKey.String(val)\n}\n\n// HwSensorLocation returns an attribute KeyValue conforming to the\n// \"hw.sensor_location\" semantic conventions. It represents the location of the\n// sensor.\nfunc HwSensorLocation(val string) attribute.KeyValue {\n\treturn HwSensorLocationKey.String(val)\n}\n\n// HwSerialNumber returns an attribute KeyValue conforming to the\n// \"hw.serial_number\" semantic conventions. It represents the serial number of\n// the hardware component.\nfunc HwSerialNumber(val string) attribute.KeyValue {\n\treturn HwSerialNumberKey.String(val)\n}\n\n// HwVendor returns an attribute KeyValue conforming to the \"hw.vendor\" semantic\n// conventions. It represents the vendor name of the hardware component.\nfunc HwVendor(val string) attribute.KeyValue {\n\treturn HwVendorKey.String(val)\n}\n\n// Enum values for hw.battery.state\nvar (\n\t// Charging\n\t// Stability: development\n\tHwBatteryStateCharging = HwBatteryStateKey.String(\"charging\")\n\t// Discharging\n\t// Stability: development\n\tHwBatteryStateDischarging = HwBatteryStateKey.String(\"discharging\")\n)\n\n// Enum values for hw.gpu.task\nvar (\n\t// Decoder\n\t// Stability: development\n\tHwGpuTaskDecoder = HwGpuTaskKey.String(\"decoder\")\n\t// Encoder\n\t// Stability: development\n\tHwGpuTaskEncoder = HwGpuTaskKey.String(\"encoder\")\n\t// General\n\t// Stability: development\n\tHwGpuTaskGeneral = HwGpuTaskKey.String(\"general\")\n)\n\n// Enum values for hw.limit_type\nvar (\n\t// Critical\n\t// Stability: development\n\tHwLimitTypeCritical = HwLimitTypeKey.String(\"critical\")\n\t// Degraded\n\t// Stability: development\n\tHwLimitTypeDegraded = HwLimitTypeKey.String(\"degraded\")\n\t// High Critical\n\t// Stability: development\n\tHwLimitTypeHighCritical = HwLimitTypeKey.String(\"high.critical\")\n\t// High Degraded\n\t// Stability: development\n\tHwLimitTypeHighDegraded = HwLimitTypeKey.String(\"high.degraded\")\n\t// Low Critical\n\t// Stability: development\n\tHwLimitTypeLowCritical = HwLimitTypeKey.String(\"low.critical\")\n\t// Low Degraded\n\t// Stability: development\n\tHwLimitTypeLowDegraded = HwLimitTypeKey.String(\"low.degraded\")\n\t// Maximum\n\t// Stability: development\n\tHwLimitTypeMax = HwLimitTypeKey.String(\"max\")\n\t// Throttled\n\t// Stability: development\n\tHwLimitTypeThrottled = HwLimitTypeKey.String(\"throttled\")\n\t// Turbo\n\t// Stability: development\n\tHwLimitTypeTurbo = HwLimitTypeKey.String(\"turbo\")\n)\n\n// Enum values for hw.logical_disk.state\nvar (\n\t// Used\n\t// Stability: development\n\tHwLogicalDiskStateUsed = HwLogicalDiskStateKey.String(\"used\")\n\t// Free\n\t// Stability: development\n\tHwLogicalDiskStateFree = HwLogicalDiskStateKey.String(\"free\")\n)\n\n// Enum values for hw.physical_disk.state\nvar (\n\t// Remaining\n\t// Stability: development\n\tHwPhysicalDiskStateRemaining = HwPhysicalDiskStateKey.String(\"remaining\")\n)\n\n// Enum values for hw.state\nvar (\n\t// Degraded\n\t// Stability: development\n\tHwStateDegraded = HwStateKey.String(\"degraded\")\n\t// Failed\n\t// Stability: development\n\tHwStateFailed = HwStateKey.String(\"failed\")\n\t// Needs Cleaning\n\t// Stability: development\n\tHwStateNeedsCleaning = HwStateKey.String(\"needs_cleaning\")\n\t// OK\n\t// Stability: development\n\tHwStateOk = HwStateKey.String(\"ok\")\n\t// Predicted Failure\n\t// Stability: development\n\tHwStatePredictedFailure = HwStateKey.String(\"predicted_failure\")\n)\n\n// Enum values for hw.tape_drive.operation_type\nvar (\n\t// Mount\n\t// Stability: development\n\tHwTapeDriveOperationTypeMount = HwTapeDriveOperationTypeKey.String(\"mount\")\n\t// Unmount\n\t// Stability: development\n\tHwTapeDriveOperationTypeUnmount = HwTapeDriveOperationTypeKey.String(\"unmount\")\n\t// Clean\n\t// Stability: development\n\tHwTapeDriveOperationTypeClean = HwTapeDriveOperationTypeKey.String(\"clean\")\n)\n\n// Enum values for hw.type\nvar (\n\t// Battery\n\t// Stability: development\n\tHwTypeBattery = HwTypeKey.String(\"battery\")\n\t// CPU\n\t// Stability: development\n\tHwTypeCPU = HwTypeKey.String(\"cpu\")\n\t// Disk controller\n\t// Stability: development\n\tHwTypeDiskController = HwTypeKey.String(\"disk_controller\")\n\t// Enclosure\n\t// Stability: development\n\tHwTypeEnclosure = HwTypeKey.String(\"enclosure\")\n\t// Fan\n\t// Stability: development\n\tHwTypeFan = HwTypeKey.String(\"fan\")\n\t// GPU\n\t// Stability: development\n\tHwTypeGpu = HwTypeKey.String(\"gpu\")\n\t// Logical disk\n\t// Stability: development\n\tHwTypeLogicalDisk = HwTypeKey.String(\"logical_disk\")\n\t// Memory\n\t// Stability: development\n\tHwTypeMemory = HwTypeKey.String(\"memory\")\n\t// Network\n\t// Stability: development\n\tHwTypeNetwork = HwTypeKey.String(\"network\")\n\t// Physical disk\n\t// Stability: development\n\tHwTypePhysicalDisk = HwTypeKey.String(\"physical_disk\")\n\t// Power supply\n\t// Stability: development\n\tHwTypePowerSupply = HwTypeKey.String(\"power_supply\")\n\t// Tape drive\n\t// Stability: development\n\tHwTypeTapeDrive = HwTypeKey.String(\"tape_drive\")\n\t// Temperature\n\t// Stability: development\n\tHwTypeTemperature = HwTypeKey.String(\"temperature\")\n\t// Voltage\n\t// Stability: development\n\tHwTypeVoltage = HwTypeKey.String(\"voltage\")\n)\n\n// Namespace: ios\nconst (\n\t// IOSAppStateKey is the attribute Key conforming to the \"ios.app.state\"\n\t// semantic conventions. It represents the this attribute represents the state\n\t// of the application.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: The iOS lifecycle states are defined in the\n\t// [UIApplicationDelegate documentation], and from which the `OS terminology`\n\t// column values are derived.\n\t//\n\t// [UIApplicationDelegate documentation]: https://developer.apple.com/documentation/uikit/uiapplicationdelegate\n\tIOSAppStateKey = attribute.Key(\"ios.app.state\")\n)\n\n// Enum values for ios.app.state\nvar (\n\t// The app has become `active`. Associated with UIKit notification\n\t// `applicationDidBecomeActive`.\n\t//\n\t// Stability: development\n\tIOSAppStateActive = IOSAppStateKey.String(\"active\")\n\t// The app is now `inactive`. Associated with UIKit notification\n\t// `applicationWillResignActive`.\n\t//\n\t// Stability: development\n\tIOSAppStateInactive = IOSAppStateKey.String(\"inactive\")\n\t// The app is now in the background. This value is associated with UIKit\n\t// notification `applicationDidEnterBackground`.\n\t//\n\t// Stability: development\n\tIOSAppStateBackground = IOSAppStateKey.String(\"background\")\n\t// The app is now in the foreground. This value is associated with UIKit\n\t// notification `applicationWillEnterForeground`.\n\t//\n\t// Stability: development\n\tIOSAppStateForeground = IOSAppStateKey.String(\"foreground\")\n\t// The app is about to terminate. Associated with UIKit notification\n\t// `applicationWillTerminate`.\n\t//\n\t// Stability: development\n\tIOSAppStateTerminate = IOSAppStateKey.String(\"terminate\")\n)\n\n// Namespace: jsonrpc\nconst (\n\t// JSONRPCProtocolVersionKey is the attribute Key conforming to the\n\t// \"jsonrpc.protocol.version\" semantic conventions. It represents the protocol\n\t// version, as specified in the `jsonrpc` property of the request and its\n\t// corresponding response.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2.0\", \"1.0\"\n\tJSONRPCProtocolVersionKey = attribute.Key(\"jsonrpc.protocol.version\")\n\n\t// JSONRPCRequestIDKey is the attribute Key conforming to the\n\t// \"jsonrpc.request.id\" semantic conventions. It represents a string\n\t// representation of the `id` property of the request and its corresponding\n\t// response.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"10\", \"request-7\"\n\t// Note: Under the [JSON-RPC specification], the `id` property may be a string,\n\t// number, null, or omitted entirely. When omitted, the request is treated as a\n\t// notification. Using `null` is not equivalent to omitting the `id`, but it is\n\t// discouraged.\n\t// Instrumentations SHOULD NOT capture this attribute when the `id` is `null` or\n\t// omitted.\n\t//\n\t// [JSON-RPC specification]: https://www.jsonrpc.org/specification\n\tJSONRPCRequestIDKey = attribute.Key(\"jsonrpc.request.id\")\n)\n\n// JSONRPCProtocolVersion returns an attribute KeyValue conforming to the\n// \"jsonrpc.protocol.version\" semantic conventions. It represents the protocol\n// version, as specified in the `jsonrpc` property of the request and its\n// corresponding response.\nfunc JSONRPCProtocolVersion(val string) attribute.KeyValue {\n\treturn JSONRPCProtocolVersionKey.String(val)\n}\n\n// JSONRPCRequestID returns an attribute KeyValue conforming to the\n// \"jsonrpc.request.id\" semantic conventions. It represents a string\n// representation of the `id` property of the request and its corresponding\n// response.\nfunc JSONRPCRequestID(val string) attribute.KeyValue {\n\treturn JSONRPCRequestIDKey.String(val)\n}\n\n// Namespace: k8s\nconst (\n\t// K8SClusterNameKey is the attribute Key conforming to the \"k8s.cluster.name\"\n\t// semantic conventions. It represents the name of the cluster.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"opentelemetry-cluster\"\n\tK8SClusterNameKey = attribute.Key(\"k8s.cluster.name\")\n\n\t// K8SClusterUIDKey is the attribute Key conforming to the \"k8s.cluster.uid\"\n\t// semantic conventions. It represents a pseudo-ID for the cluster, set to the\n\t// UID of the `kube-system` namespace.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"218fc5a9-a5f1-4b54-aa05-46717d0ab26d\"\n\t// Note: K8s doesn't have support for obtaining a cluster ID. If this is ever\n\t// added, we will recommend collecting the `k8s.cluster.uid` through the\n\t// official APIs. In the meantime, we are able to use the `uid` of the\n\t// `kube-system` namespace as a proxy for cluster ID. Read on for the\n\t// rationale.\n\t//\n\t// Every object created in a K8s cluster is assigned a distinct UID. The\n\t// `kube-system` namespace is used by Kubernetes itself and will exist\n\t// for the lifetime of the cluster. Using the `uid` of the `kube-system`\n\t// namespace is a reasonable proxy for the K8s ClusterID as it will only\n\t// change if the cluster is rebuilt. Furthermore, Kubernetes UIDs are\n\t// UUIDs as standardized by\n\t// [ISO/IEC 9834-8 and ITU-T X.667].\n\t// Which states:\n\t//\n\t// > If generated according to one of the mechanisms defined in Rec.\n\t// > ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be\n\t// > different from all other UUIDs generated before 3603 A.D., or is\n\t// > extremely likely to be different (depending on the mechanism chosen).\n\t//\n\t// Therefore, UIDs between clusters should be extremely unlikely to\n\t// conflict.\n\t//\n\t// [ISO/IEC 9834-8 and ITU-T X.667]: https://www.itu.int/ITU-T/studygroups/com17/oid.html\n\tK8SClusterUIDKey = attribute.Key(\"k8s.cluster.uid\")\n\n\t// K8SContainerNameKey is the attribute Key conforming to the\n\t// \"k8s.container.name\" semantic conventions. It represents the name of the\n\t// Container from Pod specification, must be unique within a Pod. Container\n\t// runtime usually uses different globally unique name (`container.name`).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"redis\"\n\tK8SContainerNameKey = attribute.Key(\"k8s.container.name\")\n\n\t// K8SContainerRestartCountKey is the attribute Key conforming to the\n\t// \"k8s.container.restart_count\" semantic conventions. It represents the number\n\t// of times the container was restarted. This attribute can be used to identify\n\t// a particular container (running or stopped) within a container spec.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples:\n\tK8SContainerRestartCountKey = attribute.Key(\"k8s.container.restart_count\")\n\n\t// K8SContainerStatusLastTerminatedReasonKey is the attribute Key conforming to\n\t// the \"k8s.container.status.last_terminated_reason\" semantic conventions. It\n\t// represents the last terminated reason of the Container.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Evicted\", \"Error\"\n\tK8SContainerStatusLastTerminatedReasonKey = attribute.Key(\"k8s.container.status.last_terminated_reason\")\n\n\t// K8SContainerStatusReasonKey is the attribute Key conforming to the\n\t// \"k8s.container.status.reason\" semantic conventions. It represents the reason\n\t// for the container state. Corresponds to the `reason` field of the:\n\t// [K8s ContainerStateWaiting] or [K8s ContainerStateTerminated].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"ContainerCreating\", \"CrashLoopBackOff\",\n\t// \"CreateContainerConfigError\", \"ErrImagePull\", \"ImagePullBackOff\",\n\t// \"OOMKilled\", \"Completed\", \"Error\", \"ContainerCannotRun\"\n\t//\n\t// [K8s ContainerStateWaiting]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#containerstatewaiting-v1-core\n\t// [K8s ContainerStateTerminated]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#containerstateterminated-v1-core\n\tK8SContainerStatusReasonKey = attribute.Key(\"k8s.container.status.reason\")\n\n\t// K8SContainerStatusStateKey is the attribute Key conforming to the\n\t// \"k8s.container.status.state\" semantic conventions. It represents the state of\n\t// the container. [K8s ContainerState].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"terminated\", \"running\", \"waiting\"\n\t//\n\t// [K8s ContainerState]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#containerstate-v1-core\n\tK8SContainerStatusStateKey = attribute.Key(\"k8s.container.status.state\")\n\n\t// K8SCronJobNameKey is the attribute Key conforming to the \"k8s.cronjob.name\"\n\t// semantic conventions. It represents the name of the CronJob.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SCronJobNameKey = attribute.Key(\"k8s.cronjob.name\")\n\n\t// K8SCronJobUIDKey is the attribute Key conforming to the \"k8s.cronjob.uid\"\n\t// semantic conventions. It represents the UID of the CronJob.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SCronJobUIDKey = attribute.Key(\"k8s.cronjob.uid\")\n\n\t// K8SDaemonSetNameKey is the attribute Key conforming to the\n\t// \"k8s.daemonset.name\" semantic conventions. It represents the name of the\n\t// DaemonSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SDaemonSetNameKey = attribute.Key(\"k8s.daemonset.name\")\n\n\t// K8SDaemonSetUIDKey is the attribute Key conforming to the \"k8s.daemonset.uid\"\n\t// semantic conventions. It represents the UID of the DaemonSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SDaemonSetUIDKey = attribute.Key(\"k8s.daemonset.uid\")\n\n\t// K8SDeploymentNameKey is the attribute Key conforming to the\n\t// \"k8s.deployment.name\" semantic conventions. It represents the name of the\n\t// Deployment.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SDeploymentNameKey = attribute.Key(\"k8s.deployment.name\")\n\n\t// K8SDeploymentUIDKey is the attribute Key conforming to the\n\t// \"k8s.deployment.uid\" semantic conventions. It represents the UID of the\n\t// Deployment.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SDeploymentUIDKey = attribute.Key(\"k8s.deployment.uid\")\n\n\t// K8SHPAMetricTypeKey is the attribute Key conforming to the\n\t// \"k8s.hpa.metric.type\" semantic conventions. It represents the type of metric\n\t// source for the horizontal pod autoscaler.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Resource\", \"ContainerResource\"\n\t// Note: This attribute reflects the `type` field of spec.metrics[] in the HPA.\n\tK8SHPAMetricTypeKey = attribute.Key(\"k8s.hpa.metric.type\")\n\n\t// K8SHPANameKey is the attribute Key conforming to the \"k8s.hpa.name\" semantic\n\t// conventions. It represents the name of the horizontal pod autoscaler.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SHPANameKey = attribute.Key(\"k8s.hpa.name\")\n\n\t// K8SHPAScaletargetrefAPIVersionKey is the attribute Key conforming to the\n\t// \"k8s.hpa.scaletargetref.api_version\" semantic conventions. It represents the\n\t// API version of the target resource to scale for the HorizontalPodAutoscaler.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"apps/v1\", \"autoscaling/v2\"\n\t// Note: This maps to the `apiVersion` field in the `scaleTargetRef` of the HPA\n\t// spec.\n\tK8SHPAScaletargetrefAPIVersionKey = attribute.Key(\"k8s.hpa.scaletargetref.api_version\")\n\n\t// K8SHPAScaletargetrefKindKey is the attribute Key conforming to the\n\t// \"k8s.hpa.scaletargetref.kind\" semantic conventions. It represents the kind of\n\t// the target resource to scale for the HorizontalPodAutoscaler.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Deployment\", \"StatefulSet\"\n\t// Note: This maps to the `kind` field in the `scaleTargetRef` of the HPA spec.\n\tK8SHPAScaletargetrefKindKey = attribute.Key(\"k8s.hpa.scaletargetref.kind\")\n\n\t// K8SHPAScaletargetrefNameKey is the attribute Key conforming to the\n\t// \"k8s.hpa.scaletargetref.name\" semantic conventions. It represents the name of\n\t// the target resource to scale for the HorizontalPodAutoscaler.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-deployment\", \"my-statefulset\"\n\t// Note: This maps to the `name` field in the `scaleTargetRef` of the HPA spec.\n\tK8SHPAScaletargetrefNameKey = attribute.Key(\"k8s.hpa.scaletargetref.name\")\n\n\t// K8SHPAUIDKey is the attribute Key conforming to the \"k8s.hpa.uid\" semantic\n\t// conventions. It represents the UID of the horizontal pod autoscaler.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SHPAUIDKey = attribute.Key(\"k8s.hpa.uid\")\n\n\t// K8SHugepageSizeKey is the attribute Key conforming to the \"k8s.hugepage.size\"\n\t// semantic conventions. It represents the size (identifier) of the K8s huge\n\t// page.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2Mi\"\n\tK8SHugepageSizeKey = attribute.Key(\"k8s.hugepage.size\")\n\n\t// K8SJobNameKey is the attribute Key conforming to the \"k8s.job.name\" semantic\n\t// conventions. It represents the name of the Job.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SJobNameKey = attribute.Key(\"k8s.job.name\")\n\n\t// K8SJobUIDKey is the attribute Key conforming to the \"k8s.job.uid\" semantic\n\t// conventions. It represents the UID of the Job.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SJobUIDKey = attribute.Key(\"k8s.job.uid\")\n\n\t// K8SNamespaceNameKey is the attribute Key conforming to the\n\t// \"k8s.namespace.name\" semantic conventions. It represents the name of the\n\t// namespace that the pod is running in.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"default\"\n\tK8SNamespaceNameKey = attribute.Key(\"k8s.namespace.name\")\n\n\t// K8SNamespacePhaseKey is the attribute Key conforming to the\n\t// \"k8s.namespace.phase\" semantic conventions. It represents the phase of the\n\t// K8s namespace.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"active\", \"terminating\"\n\t// Note: This attribute aligns with the `phase` field of the\n\t// [K8s NamespaceStatus]\n\t//\n\t// [K8s NamespaceStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#namespacestatus-v1-core\n\tK8SNamespacePhaseKey = attribute.Key(\"k8s.namespace.phase\")\n\n\t// K8SNodeConditionStatusKey is the attribute Key conforming to the\n\t// \"k8s.node.condition.status\" semantic conventions. It represents the status of\n\t// the condition, one of True, False, Unknown.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"true\", \"false\", \"unknown\"\n\t// Note: This attribute aligns with the `status` field of the\n\t// [NodeCondition]\n\t//\n\t// [NodeCondition]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#nodecondition-v1-core\n\tK8SNodeConditionStatusKey = attribute.Key(\"k8s.node.condition.status\")\n\n\t// K8SNodeConditionTypeKey is the attribute Key conforming to the\n\t// \"k8s.node.condition.type\" semantic conventions. It represents the condition\n\t// type of a K8s Node.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Ready\", \"DiskPressure\"\n\t// Note: K8s Node conditions as described\n\t// by [K8s documentation].\n\t//\n\t// This attribute aligns with the `type` field of the\n\t// [NodeCondition]\n\t//\n\t// The set of possible values is not limited to those listed here. Managed\n\t// Kubernetes environments,\n\t// or custom controllers MAY introduce additional node condition types.\n\t// When this occurs, the exact value as reported by the Kubernetes API SHOULD be\n\t// used.\n\t//\n\t// [K8s documentation]: https://v1-32.docs.kubernetes.io/docs/reference/node/node-status/#condition\n\t// [NodeCondition]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#nodecondition-v1-core\n\tK8SNodeConditionTypeKey = attribute.Key(\"k8s.node.condition.type\")\n\n\t// K8SNodeNameKey is the attribute Key conforming to the \"k8s.node.name\"\n\t// semantic conventions. It represents the name of the Node.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"node-1\"\n\tK8SNodeNameKey = attribute.Key(\"k8s.node.name\")\n\n\t// K8SNodeUIDKey is the attribute Key conforming to the \"k8s.node.uid\" semantic\n\t// conventions. It represents the UID of the Node.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2\"\n\tK8SNodeUIDKey = attribute.Key(\"k8s.node.uid\")\n\n\t// K8SPodHostnameKey is the attribute Key conforming to the \"k8s.pod.hostname\"\n\t// semantic conventions. It represents the specifies the hostname of the Pod.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"collector-gateway\"\n\t// Note: The K8s Pod spec has an optional hostname field, which can be used to\n\t// specify a hostname.\n\t// Refer to [K8s docs]\n\t// for more information about this field.\n\t//\n\t// This attribute aligns with the `hostname` field of the\n\t// [K8s PodSpec].\n\t//\n\t// [K8s docs]: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-hostname-and-subdomain-field\n\t// [K8s PodSpec]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#podspec-v1-core\n\tK8SPodHostnameKey = attribute.Key(\"k8s.pod.hostname\")\n\n\t// K8SPodIPKey is the attribute Key conforming to the \"k8s.pod.ip\" semantic\n\t// conventions. It represents the IP address allocated to the Pod.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"172.18.0.2\"\n\t// Note: This attribute aligns with the `podIP` field of the\n\t// [K8s PodStatus].\n\t//\n\t// [K8s PodStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#podstatus-v1-core\n\tK8SPodIPKey = attribute.Key(\"k8s.pod.ip\")\n\n\t// K8SPodNameKey is the attribute Key conforming to the \"k8s.pod.name\" semantic\n\t// conventions. It represents the name of the Pod.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"opentelemetry-pod-autoconf\"\n\tK8SPodNameKey = attribute.Key(\"k8s.pod.name\")\n\n\t// K8SPodStartTimeKey is the attribute Key conforming to the\n\t// \"k8s.pod.start_time\" semantic conventions. It represents the start timestamp\n\t// of the Pod.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"2025-12-04T08:41:03Z\"\n\t// Note: Date and time at which the object was acknowledged by the Kubelet.\n\t// This is before the Kubelet pulled the container image(s) for the pod.\n\t//\n\t// This attribute aligns with the `startTime` field of the\n\t// [K8s PodStatus],\n\t// in ISO 8601 (RFC 3339 compatible) format.\n\t//\n\t// [K8s PodStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#podstatus-v1-core\n\tK8SPodStartTimeKey = attribute.Key(\"k8s.pod.start_time\")\n\n\t// K8SPodStatusPhaseKey is the attribute Key conforming to the\n\t// \"k8s.pod.status.phase\" semantic conventions. It represents the phase for the\n\t// pod. Corresponds to the `phase` field of the: [K8s PodStatus].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Pending\", \"Running\"\n\t//\n\t// [K8s PodStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#podstatus-v1-core\n\tK8SPodStatusPhaseKey = attribute.Key(\"k8s.pod.status.phase\")\n\n\t// K8SPodStatusReasonKey is the attribute Key conforming to the\n\t// \"k8s.pod.status.reason\" semantic conventions. It represents the reason for\n\t// the pod state. Corresponds to the `reason` field of the: [K8s PodStatus].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Evicted\", \"NodeAffinity\"\n\t//\n\t// [K8s PodStatus]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#podstatus-v1-core\n\tK8SPodStatusReasonKey = attribute.Key(\"k8s.pod.status.reason\")\n\n\t// K8SPodUIDKey is the attribute Key conforming to the \"k8s.pod.uid\" semantic\n\t// conventions. It represents the UID of the Pod.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SPodUIDKey = attribute.Key(\"k8s.pod.uid\")\n\n\t// K8SReplicaSetNameKey is the attribute Key conforming to the\n\t// \"k8s.replicaset.name\" semantic conventions. It represents the name of the\n\t// ReplicaSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SReplicaSetNameKey = attribute.Key(\"k8s.replicaset.name\")\n\n\t// K8SReplicaSetUIDKey is the attribute Key conforming to the\n\t// \"k8s.replicaset.uid\" semantic conventions. It represents the UID of the\n\t// ReplicaSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SReplicaSetUIDKey = attribute.Key(\"k8s.replicaset.uid\")\n\n\t// K8SReplicationControllerNameKey is the attribute Key conforming to the\n\t// \"k8s.replicationcontroller.name\" semantic conventions. It represents the name\n\t// of the replication controller.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SReplicationControllerNameKey = attribute.Key(\"k8s.replicationcontroller.name\")\n\n\t// K8SReplicationControllerUIDKey is the attribute Key conforming to the\n\t// \"k8s.replicationcontroller.uid\" semantic conventions. It represents the UID\n\t// of the replication controller.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SReplicationControllerUIDKey = attribute.Key(\"k8s.replicationcontroller.uid\")\n\n\t// K8SResourceQuotaNameKey is the attribute Key conforming to the\n\t// \"k8s.resourcequota.name\" semantic conventions. It represents the name of the\n\t// resource quota.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SResourceQuotaNameKey = attribute.Key(\"k8s.resourcequota.name\")\n\n\t// K8SResourceQuotaResourceNameKey is the attribute Key conforming to the\n\t// \"k8s.resourcequota.resource_name\" semantic conventions. It represents the\n\t// name of the K8s resource a resource quota defines.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"count/replicationcontrollers\"\n\t// Note: The value for this attribute can be either the full\n\t// `count/<resource>[.<group>]` string (e.g., count/deployments.apps,\n\t// count/pods), or, for certain core Kubernetes resources, just the resource\n\t// name (e.g., pods, services, configmaps). Both forms are supported by\n\t// Kubernetes for object count quotas. See\n\t// [Kubernetes Resource Quotas documentation] for more details.\n\t//\n\t// [Kubernetes Resource Quotas documentation]: https://kubernetes.io/docs/concepts/policy/resource-quotas/#quota-on-object-count\n\tK8SResourceQuotaResourceNameKey = attribute.Key(\"k8s.resourcequota.resource_name\")\n\n\t// K8SResourceQuotaUIDKey is the attribute Key conforming to the\n\t// \"k8s.resourcequota.uid\" semantic conventions. It represents the UID of the\n\t// resource quota.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SResourceQuotaUIDKey = attribute.Key(\"k8s.resourcequota.uid\")\n\n\t// K8SStatefulSetNameKey is the attribute Key conforming to the\n\t// \"k8s.statefulset.name\" semantic conventions. It represents the name of the\n\t// StatefulSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"opentelemetry\"\n\tK8SStatefulSetNameKey = attribute.Key(\"k8s.statefulset.name\")\n\n\t// K8SStatefulSetUIDKey is the attribute Key conforming to the\n\t// \"k8s.statefulset.uid\" semantic conventions. It represents the UID of the\n\t// StatefulSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Alpha\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tK8SStatefulSetUIDKey = attribute.Key(\"k8s.statefulset.uid\")\n\n\t// K8SStorageclassNameKey is the attribute Key conforming to the\n\t// \"k8s.storageclass.name\" semantic conventions. It represents the name of K8s\n\t// [StorageClass] object.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"gold.storageclass.storage.k8s.io\"\n\t//\n\t// [StorageClass]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#storageclass-v1-storage-k8s-io\n\tK8SStorageclassNameKey = attribute.Key(\"k8s.storageclass.name\")\n\n\t// K8SVolumeNameKey is the attribute Key conforming to the \"k8s.volume.name\"\n\t// semantic conventions. It represents the name of the K8s volume.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"volume0\"\n\tK8SVolumeNameKey = attribute.Key(\"k8s.volume.name\")\n\n\t// K8SVolumeTypeKey is the attribute Key conforming to the \"k8s.volume.type\"\n\t// semantic conventions. It represents the type of the K8s volume.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"emptyDir\", \"persistentVolumeClaim\"\n\tK8SVolumeTypeKey = attribute.Key(\"k8s.volume.type\")\n)\n\n// K8SClusterName returns an attribute KeyValue conforming to the\n// \"k8s.cluster.name\" semantic conventions. It represents the name of the\n// cluster.\nfunc K8SClusterName(val string) attribute.KeyValue {\n\treturn K8SClusterNameKey.String(val)\n}\n\n// K8SClusterUID returns an attribute KeyValue conforming to the\n// \"k8s.cluster.uid\" semantic conventions. It represents a pseudo-ID for the\n// cluster, set to the UID of the `kube-system` namespace.\nfunc K8SClusterUID(val string) attribute.KeyValue {\n\treturn K8SClusterUIDKey.String(val)\n}\n\n// K8SContainerName returns an attribute KeyValue conforming to the\n// \"k8s.container.name\" semantic conventions. It represents the name of the\n// Container from Pod specification, must be unique within a Pod. Container\n// runtime usually uses different globally unique name (`container.name`).\nfunc K8SContainerName(val string) attribute.KeyValue {\n\treturn K8SContainerNameKey.String(val)\n}\n\n// K8SContainerRestartCount returns an attribute KeyValue conforming to the\n// \"k8s.container.restart_count\" semantic conventions. It represents the number\n// of times the container was restarted. This attribute can be used to identify a\n// particular container (running or stopped) within a container spec.\nfunc K8SContainerRestartCount(val int) attribute.KeyValue {\n\treturn K8SContainerRestartCountKey.Int(val)\n}\n\n// K8SContainerStatusLastTerminatedReason returns an attribute KeyValue\n// conforming to the \"k8s.container.status.last_terminated_reason\" semantic\n// conventions. It represents the last terminated reason of the Container.\nfunc K8SContainerStatusLastTerminatedReason(val string) attribute.KeyValue {\n\treturn K8SContainerStatusLastTerminatedReasonKey.String(val)\n}\n\n// K8SCronJobAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.cronjob.annotation\" semantic conventions. It represents the cronjob\n// annotation placed on the CronJob, the `<key>` being the annotation name, the\n// value being the annotation value.\nfunc K8SCronJobAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.cronjob.annotation.\"+key, val)\n}\n\n// K8SCronJobLabel returns an attribute KeyValue conforming to the\n// \"k8s.cronjob.label\" semantic conventions. It represents the label placed on\n// the CronJob, the `<key>` being the label name, the value being the label\n// value.\nfunc K8SCronJobLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.cronjob.label.\"+key, val)\n}\n\n// K8SCronJobName returns an attribute KeyValue conforming to the\n// \"k8s.cronjob.name\" semantic conventions. It represents the name of the\n// CronJob.\nfunc K8SCronJobName(val string) attribute.KeyValue {\n\treturn K8SCronJobNameKey.String(val)\n}\n\n// K8SCronJobUID returns an attribute KeyValue conforming to the\n// \"k8s.cronjob.uid\" semantic conventions. It represents the UID of the CronJob.\nfunc K8SCronJobUID(val string) attribute.KeyValue {\n\treturn K8SCronJobUIDKey.String(val)\n}\n\n// K8SDaemonSetAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.daemonset.annotation\" semantic conventions. It represents the annotation\n// placed on the DaemonSet, the `<key>` being the annotation name, the value\n// being the annotation value, even if the value is empty.\nfunc K8SDaemonSetAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.daemonset.annotation.\"+key, val)\n}\n\n// K8SDaemonSetLabel returns an attribute KeyValue conforming to the\n// \"k8s.daemonset.label\" semantic conventions. It represents the label placed on\n// the DaemonSet, the `<key>` being the label name, the value being the label\n// value, even if the value is empty.\nfunc K8SDaemonSetLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.daemonset.label.\"+key, val)\n}\n\n// K8SDaemonSetName returns an attribute KeyValue conforming to the\n// \"k8s.daemonset.name\" semantic conventions. It represents the name of the\n// DaemonSet.\nfunc K8SDaemonSetName(val string) attribute.KeyValue {\n\treturn K8SDaemonSetNameKey.String(val)\n}\n\n// K8SDaemonSetUID returns an attribute KeyValue conforming to the\n// \"k8s.daemonset.uid\" semantic conventions. It represents the UID of the\n// DaemonSet.\nfunc K8SDaemonSetUID(val string) attribute.KeyValue {\n\treturn K8SDaemonSetUIDKey.String(val)\n}\n\n// K8SDeploymentAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.deployment.annotation\" semantic conventions. It represents the annotation\n// placed on the Deployment, the `<key>` being the annotation name, the value\n// being the annotation value, even if the value is empty.\nfunc K8SDeploymentAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.deployment.annotation.\"+key, val)\n}\n\n// K8SDeploymentLabel returns an attribute KeyValue conforming to the\n// \"k8s.deployment.label\" semantic conventions. It represents the label placed on\n// the Deployment, the `<key>` being the label name, the value being the label\n// value, even if the value is empty.\nfunc K8SDeploymentLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.deployment.label.\"+key, val)\n}\n\n// K8SDeploymentName returns an attribute KeyValue conforming to the\n// \"k8s.deployment.name\" semantic conventions. It represents the name of the\n// Deployment.\nfunc K8SDeploymentName(val string) attribute.KeyValue {\n\treturn K8SDeploymentNameKey.String(val)\n}\n\n// K8SDeploymentUID returns an attribute KeyValue conforming to the\n// \"k8s.deployment.uid\" semantic conventions. It represents the UID of the\n// Deployment.\nfunc K8SDeploymentUID(val string) attribute.KeyValue {\n\treturn K8SDeploymentUIDKey.String(val)\n}\n\n// K8SHPAMetricType returns an attribute KeyValue conforming to the\n// \"k8s.hpa.metric.type\" semantic conventions. It represents the type of metric\n// source for the horizontal pod autoscaler.\nfunc K8SHPAMetricType(val string) attribute.KeyValue {\n\treturn K8SHPAMetricTypeKey.String(val)\n}\n\n// K8SHPAName returns an attribute KeyValue conforming to the \"k8s.hpa.name\"\n// semantic conventions. It represents the name of the horizontal pod autoscaler.\nfunc K8SHPAName(val string) attribute.KeyValue {\n\treturn K8SHPANameKey.String(val)\n}\n\n// K8SHPAScaletargetrefAPIVersion returns an attribute KeyValue conforming to the\n// \"k8s.hpa.scaletargetref.api_version\" semantic conventions. It represents the\n// API version of the target resource to scale for the HorizontalPodAutoscaler.\nfunc K8SHPAScaletargetrefAPIVersion(val string) attribute.KeyValue {\n\treturn K8SHPAScaletargetrefAPIVersionKey.String(val)\n}\n\n// K8SHPAScaletargetrefKind returns an attribute KeyValue conforming to the\n// \"k8s.hpa.scaletargetref.kind\" semantic conventions. It represents the kind of\n// the target resource to scale for the HorizontalPodAutoscaler.\nfunc K8SHPAScaletargetrefKind(val string) attribute.KeyValue {\n\treturn K8SHPAScaletargetrefKindKey.String(val)\n}\n\n// K8SHPAScaletargetrefName returns an attribute KeyValue conforming to the\n// \"k8s.hpa.scaletargetref.name\" semantic conventions. It represents the name of\n// the target resource to scale for the HorizontalPodAutoscaler.\nfunc K8SHPAScaletargetrefName(val string) attribute.KeyValue {\n\treturn K8SHPAScaletargetrefNameKey.String(val)\n}\n\n// K8SHPAUID returns an attribute KeyValue conforming to the \"k8s.hpa.uid\"\n// semantic conventions. It represents the UID of the horizontal pod autoscaler.\nfunc K8SHPAUID(val string) attribute.KeyValue {\n\treturn K8SHPAUIDKey.String(val)\n}\n\n// K8SHugepageSize returns an attribute KeyValue conforming to the\n// \"k8s.hugepage.size\" semantic conventions. It represents the size (identifier)\n// of the K8s huge page.\nfunc K8SHugepageSize(val string) attribute.KeyValue {\n\treturn K8SHugepageSizeKey.String(val)\n}\n\n// K8SJobAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.job.annotation\" semantic conventions. It represents the annotation placed\n// on the Job, the `<key>` being the annotation name, the value being the\n// annotation value, even if the value is empty.\nfunc K8SJobAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.job.annotation.\"+key, val)\n}\n\n// K8SJobLabel returns an attribute KeyValue conforming to the \"k8s.job.label\"\n// semantic conventions. It represents the label placed on the Job, the `<key>`\n// being the label name, the value being the label value, even if the value is\n// empty.\nfunc K8SJobLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.job.label.\"+key, val)\n}\n\n// K8SJobName returns an attribute KeyValue conforming to the \"k8s.job.name\"\n// semantic conventions. It represents the name of the Job.\nfunc K8SJobName(val string) attribute.KeyValue {\n\treturn K8SJobNameKey.String(val)\n}\n\n// K8SJobUID returns an attribute KeyValue conforming to the \"k8s.job.uid\"\n// semantic conventions. It represents the UID of the Job.\nfunc K8SJobUID(val string) attribute.KeyValue {\n\treturn K8SJobUIDKey.String(val)\n}\n\n// K8SNamespaceAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.namespace.annotation\" semantic conventions. It represents the annotation\n// placed on the Namespace, the `<key>` being the annotation name, the value\n// being the annotation value, even if the value is empty.\nfunc K8SNamespaceAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.namespace.annotation.\"+key, val)\n}\n\n// K8SNamespaceLabel returns an attribute KeyValue conforming to the\n// \"k8s.namespace.label\" semantic conventions. It represents the label placed on\n// the Namespace, the `<key>` being the label name, the value being the label\n// value, even if the value is empty.\nfunc K8SNamespaceLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.namespace.label.\"+key, val)\n}\n\n// K8SNamespaceName returns an attribute KeyValue conforming to the\n// \"k8s.namespace.name\" semantic conventions. It represents the name of the\n// namespace that the pod is running in.\nfunc K8SNamespaceName(val string) attribute.KeyValue {\n\treturn K8SNamespaceNameKey.String(val)\n}\n\n// K8SNodeAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.node.annotation\" semantic conventions. It represents the annotation\n// placed on the Node, the `<key>` being the annotation name, the value being the\n// annotation value, even if the value is empty.\nfunc K8SNodeAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.node.annotation.\"+key, val)\n}\n\n// K8SNodeLabel returns an attribute KeyValue conforming to the \"k8s.node.label\"\n// semantic conventions. It represents the label placed on the Node, the `<key>`\n// being the label name, the value being the label value, even if the value is\n// empty.\nfunc K8SNodeLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.node.label.\"+key, val)\n}\n\n// K8SNodeName returns an attribute KeyValue conforming to the \"k8s.node.name\"\n// semantic conventions. It represents the name of the Node.\nfunc K8SNodeName(val string) attribute.KeyValue {\n\treturn K8SNodeNameKey.String(val)\n}\n\n// K8SNodeUID returns an attribute KeyValue conforming to the \"k8s.node.uid\"\n// semantic conventions. It represents the UID of the Node.\nfunc K8SNodeUID(val string) attribute.KeyValue {\n\treturn K8SNodeUIDKey.String(val)\n}\n\n// K8SPodAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.pod.annotation\" semantic conventions. It represents the annotation placed\n// on the Pod, the `<key>` being the annotation name, the value being the\n// annotation value.\nfunc K8SPodAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.pod.annotation.\"+key, val)\n}\n\n// K8SPodHostname returns an attribute KeyValue conforming to the\n// \"k8s.pod.hostname\" semantic conventions. It represents the specifies the\n// hostname of the Pod.\nfunc K8SPodHostname(val string) attribute.KeyValue {\n\treturn K8SPodHostnameKey.String(val)\n}\n\n// K8SPodIP returns an attribute KeyValue conforming to the \"k8s.pod.ip\" semantic\n// conventions. It represents the IP address allocated to the Pod.\nfunc K8SPodIP(val string) attribute.KeyValue {\n\treturn K8SPodIPKey.String(val)\n}\n\n// K8SPodLabel returns an attribute KeyValue conforming to the \"k8s.pod.label\"\n// semantic conventions. It represents the label placed on the Pod, the `<key>`\n// being the label name, the value being the label value.\nfunc K8SPodLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.pod.label.\"+key, val)\n}\n\n// K8SPodName returns an attribute KeyValue conforming to the \"k8s.pod.name\"\n// semantic conventions. It represents the name of the Pod.\nfunc K8SPodName(val string) attribute.KeyValue {\n\treturn K8SPodNameKey.String(val)\n}\n\n// K8SPodStartTime returns an attribute KeyValue conforming to the\n// \"k8s.pod.start_time\" semantic conventions. It represents the start timestamp\n// of the Pod.\nfunc K8SPodStartTime(val string) attribute.KeyValue {\n\treturn K8SPodStartTimeKey.String(val)\n}\n\n// K8SPodUID returns an attribute KeyValue conforming to the \"k8s.pod.uid\"\n// semantic conventions. It represents the UID of the Pod.\nfunc K8SPodUID(val string) attribute.KeyValue {\n\treturn K8SPodUIDKey.String(val)\n}\n\n// K8SReplicaSetAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.replicaset.annotation\" semantic conventions. It represents the annotation\n// placed on the ReplicaSet, the `<key>` being the annotation name, the value\n// being the annotation value, even if the value is empty.\nfunc K8SReplicaSetAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.replicaset.annotation.\"+key, val)\n}\n\n// K8SReplicaSetLabel returns an attribute KeyValue conforming to the\n// \"k8s.replicaset.label\" semantic conventions. It represents the label placed on\n// the ReplicaSet, the `<key>` being the label name, the value being the label\n// value, even if the value is empty.\nfunc K8SReplicaSetLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.replicaset.label.\"+key, val)\n}\n\n// K8SReplicaSetName returns an attribute KeyValue conforming to the\n// \"k8s.replicaset.name\" semantic conventions. It represents the name of the\n// ReplicaSet.\nfunc K8SReplicaSetName(val string) attribute.KeyValue {\n\treturn K8SReplicaSetNameKey.String(val)\n}\n\n// K8SReplicaSetUID returns an attribute KeyValue conforming to the\n// \"k8s.replicaset.uid\" semantic conventions. It represents the UID of the\n// ReplicaSet.\nfunc K8SReplicaSetUID(val string) attribute.KeyValue {\n\treturn K8SReplicaSetUIDKey.String(val)\n}\n\n// K8SReplicationControllerName returns an attribute KeyValue conforming to the\n// \"k8s.replicationcontroller.name\" semantic conventions. It represents the name\n// of the replication controller.\nfunc K8SReplicationControllerName(val string) attribute.KeyValue {\n\treturn K8SReplicationControllerNameKey.String(val)\n}\n\n// K8SReplicationControllerUID returns an attribute KeyValue conforming to the\n// \"k8s.replicationcontroller.uid\" semantic conventions. It represents the UID of\n// the replication controller.\nfunc K8SReplicationControllerUID(val string) attribute.KeyValue {\n\treturn K8SReplicationControllerUIDKey.String(val)\n}\n\n// K8SResourceQuotaName returns an attribute KeyValue conforming to the\n// \"k8s.resourcequota.name\" semantic conventions. It represents the name of the\n// resource quota.\nfunc K8SResourceQuotaName(val string) attribute.KeyValue {\n\treturn K8SResourceQuotaNameKey.String(val)\n}\n\n// K8SResourceQuotaResourceName returns an attribute KeyValue conforming to the\n// \"k8s.resourcequota.resource_name\" semantic conventions. It represents the name\n// of the K8s resource a resource quota defines.\nfunc K8SResourceQuotaResourceName(val string) attribute.KeyValue {\n\treturn K8SResourceQuotaResourceNameKey.String(val)\n}\n\n// K8SResourceQuotaUID returns an attribute KeyValue conforming to the\n// \"k8s.resourcequota.uid\" semantic conventions. It represents the UID of the\n// resource quota.\nfunc K8SResourceQuotaUID(val string) attribute.KeyValue {\n\treturn K8SResourceQuotaUIDKey.String(val)\n}\n\n// K8SStatefulSetAnnotation returns an attribute KeyValue conforming to the\n// \"k8s.statefulset.annotation\" semantic conventions. It represents the\n// annotation placed on the StatefulSet, the `<key>` being the annotation name,\n// the value being the annotation value, even if the value is empty.\nfunc K8SStatefulSetAnnotation(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.statefulset.annotation.\"+key, val)\n}\n\n// K8SStatefulSetLabel returns an attribute KeyValue conforming to the\n// \"k8s.statefulset.label\" semantic conventions. It represents the label placed\n// on the StatefulSet, the `<key>` being the label name, the value being the\n// label value, even if the value is empty.\nfunc K8SStatefulSetLabel(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"k8s.statefulset.label.\"+key, val)\n}\n\n// K8SStatefulSetName returns an attribute KeyValue conforming to the\n// \"k8s.statefulset.name\" semantic conventions. It represents the name of the\n// StatefulSet.\nfunc K8SStatefulSetName(val string) attribute.KeyValue {\n\treturn K8SStatefulSetNameKey.String(val)\n}\n\n// K8SStatefulSetUID returns an attribute KeyValue conforming to the\n// \"k8s.statefulset.uid\" semantic conventions. It represents the UID of the\n// StatefulSet.\nfunc K8SStatefulSetUID(val string) attribute.KeyValue {\n\treturn K8SStatefulSetUIDKey.String(val)\n}\n\n// K8SStorageclassName returns an attribute KeyValue conforming to the\n// \"k8s.storageclass.name\" semantic conventions. It represents the name of K8s\n// [StorageClass] object.\n//\n// [StorageClass]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#storageclass-v1-storage-k8s-io\nfunc K8SStorageclassName(val string) attribute.KeyValue {\n\treturn K8SStorageclassNameKey.String(val)\n}\n\n// K8SVolumeName returns an attribute KeyValue conforming to the\n// \"k8s.volume.name\" semantic conventions. It represents the name of the K8s\n// volume.\nfunc K8SVolumeName(val string) attribute.KeyValue {\n\treturn K8SVolumeNameKey.String(val)\n}\n\n// Enum values for k8s.container.status.reason\nvar (\n\t// The container is being created.\n\t// Stability: development\n\tK8SContainerStatusReasonContainerCreating = K8SContainerStatusReasonKey.String(\"ContainerCreating\")\n\t// The container is in a crash loop back off state.\n\t// Stability: development\n\tK8SContainerStatusReasonCrashLoopBackOff = K8SContainerStatusReasonKey.String(\"CrashLoopBackOff\")\n\t// There was an error creating the container configuration.\n\t// Stability: development\n\tK8SContainerStatusReasonCreateContainerConfigError = K8SContainerStatusReasonKey.String(\"CreateContainerConfigError\")\n\t// There was an error pulling the container image.\n\t// Stability: development\n\tK8SContainerStatusReasonErrImagePull = K8SContainerStatusReasonKey.String(\"ErrImagePull\")\n\t// The container image pull is in back off state.\n\t// Stability: development\n\tK8SContainerStatusReasonImagePullBackOff = K8SContainerStatusReasonKey.String(\"ImagePullBackOff\")\n\t// The container was killed due to out of memory.\n\t// Stability: development\n\tK8SContainerStatusReasonOomKilled = K8SContainerStatusReasonKey.String(\"OOMKilled\")\n\t// The container has completed execution.\n\t// Stability: development\n\tK8SContainerStatusReasonCompleted = K8SContainerStatusReasonKey.String(\"Completed\")\n\t// There was an error with the container.\n\t// Stability: development\n\tK8SContainerStatusReasonError = K8SContainerStatusReasonKey.String(\"Error\")\n\t// The container cannot run.\n\t// Stability: development\n\tK8SContainerStatusReasonContainerCannotRun = K8SContainerStatusReasonKey.String(\"ContainerCannotRun\")\n)\n\n// Enum values for k8s.container.status.state\nvar (\n\t// The container has terminated.\n\t// Stability: development\n\tK8SContainerStatusStateTerminated = K8SContainerStatusStateKey.String(\"terminated\")\n\t// The container is running.\n\t// Stability: development\n\tK8SContainerStatusStateRunning = K8SContainerStatusStateKey.String(\"running\")\n\t// The container is waiting.\n\t// Stability: development\n\tK8SContainerStatusStateWaiting = K8SContainerStatusStateKey.String(\"waiting\")\n)\n\n// Enum values for k8s.namespace.phase\nvar (\n\t// Active namespace phase as described by [K8s API]\n\t// Stability: development\n\t//\n\t// [K8s API]: https://pkg.go.dev/k8s.io/api@v0.31.3/core/v1#NamespacePhase\n\tK8SNamespacePhaseActive = K8SNamespacePhaseKey.String(\"active\")\n\t// Terminating namespace phase as described by [K8s API]\n\t// Stability: development\n\t//\n\t// [K8s API]: https://pkg.go.dev/k8s.io/api@v0.31.3/core/v1#NamespacePhase\n\tK8SNamespacePhaseTerminating = K8SNamespacePhaseKey.String(\"terminating\")\n)\n\n// Enum values for k8s.node.condition.status\nvar (\n\t// condition_true\n\t// Stability: development\n\tK8SNodeConditionStatusConditionTrue = K8SNodeConditionStatusKey.String(\"true\")\n\t// condition_false\n\t// Stability: development\n\tK8SNodeConditionStatusConditionFalse = K8SNodeConditionStatusKey.String(\"false\")\n\t// condition_unknown\n\t// Stability: development\n\tK8SNodeConditionStatusConditionUnknown = K8SNodeConditionStatusKey.String(\"unknown\")\n)\n\n// Enum values for k8s.node.condition.type\nvar (\n\t// The node is healthy and ready to accept pods\n\t// Stability: development\n\tK8SNodeConditionTypeReady = K8SNodeConditionTypeKey.String(\"Ready\")\n\t// Pressure exists on the disk size—that is, if the disk capacity is low\n\t// Stability: development\n\tK8SNodeConditionTypeDiskPressure = K8SNodeConditionTypeKey.String(\"DiskPressure\")\n\t// Pressure exists on the node memory—that is, if the node memory is low\n\t// Stability: development\n\tK8SNodeConditionTypeMemoryPressure = K8SNodeConditionTypeKey.String(\"MemoryPressure\")\n\t// Pressure exists on the processes—that is, if there are too many processes\n\t// on the node\n\t// Stability: development\n\tK8SNodeConditionTypePIDPressure = K8SNodeConditionTypeKey.String(\"PIDPressure\")\n\t// The network for the node is not correctly configured\n\t// Stability: development\n\tK8SNodeConditionTypeNetworkUnavailable = K8SNodeConditionTypeKey.String(\"NetworkUnavailable\")\n)\n\n// Enum values for k8s.pod.status.phase\nvar (\n\t// The pod has been accepted by the system, but one or more of the containers\n\t// has not been started. This includes time before being bound to a node, as\n\t// well as time spent pulling images onto the host.\n\t//\n\t// Stability: development\n\tK8SPodStatusPhasePending = K8SPodStatusPhaseKey.String(\"Pending\")\n\t// The pod has been bound to a node and all of the containers have been started.\n\t// At least one container is still running or is in the process of being\n\t// restarted.\n\t//\n\t// Stability: development\n\tK8SPodStatusPhaseRunning = K8SPodStatusPhaseKey.String(\"Running\")\n\t// All containers in the pod have voluntarily terminated with a container exit\n\t// code of 0, and the system is not going to restart any of these containers.\n\t//\n\t// Stability: development\n\tK8SPodStatusPhaseSucceeded = K8SPodStatusPhaseKey.String(\"Succeeded\")\n\t// All containers in the pod have terminated, and at least one container has\n\t// terminated in a failure (exited with a non-zero exit code or was stopped by\n\t// the system).\n\t//\n\t// Stability: development\n\tK8SPodStatusPhaseFailed = K8SPodStatusPhaseKey.String(\"Failed\")\n\t// For some reason the state of the pod could not be obtained, typically due to\n\t// an error in communicating with the host of the pod.\n\t//\n\t// Stability: development\n\tK8SPodStatusPhaseUnknown = K8SPodStatusPhaseKey.String(\"Unknown\")\n)\n\n// Enum values for k8s.pod.status.reason\nvar (\n\t// The pod is evicted.\n\t// Stability: development\n\tK8SPodStatusReasonEvicted = K8SPodStatusReasonKey.String(\"Evicted\")\n\t// The pod is in a status because of its node affinity\n\t// Stability: development\n\tK8SPodStatusReasonNodeAffinity = K8SPodStatusReasonKey.String(\"NodeAffinity\")\n\t// The reason on a pod when its state cannot be confirmed as kubelet is\n\t// unresponsive on the node it is (was) running.\n\t//\n\t// Stability: development\n\tK8SPodStatusReasonNodeLost = K8SPodStatusReasonKey.String(\"NodeLost\")\n\t// The node is shutdown\n\t// Stability: development\n\tK8SPodStatusReasonShutdown = K8SPodStatusReasonKey.String(\"Shutdown\")\n\t// The pod was rejected admission to the node because of an error during\n\t// admission that could not be categorized.\n\t//\n\t// Stability: development\n\tK8SPodStatusReasonUnexpectedAdmissionError = K8SPodStatusReasonKey.String(\"UnexpectedAdmissionError\")\n)\n\n// Enum values for k8s.volume.type\nvar (\n\t// A [persistentVolumeClaim] volume\n\t// Stability: development\n\t//\n\t// [persistentVolumeClaim]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#persistentvolumeclaim\n\tK8SVolumeTypePersistentVolumeClaim = K8SVolumeTypeKey.String(\"persistentVolumeClaim\")\n\t// A [configMap] volume\n\t// Stability: development\n\t//\n\t// [configMap]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#configmap\n\tK8SVolumeTypeConfigMap = K8SVolumeTypeKey.String(\"configMap\")\n\t// A [downwardAPI] volume\n\t// Stability: development\n\t//\n\t// [downwardAPI]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#downwardapi\n\tK8SVolumeTypeDownwardAPI = K8SVolumeTypeKey.String(\"downwardAPI\")\n\t// An [emptyDir] volume\n\t// Stability: development\n\t//\n\t// [emptyDir]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#emptydir\n\tK8SVolumeTypeEmptyDir = K8SVolumeTypeKey.String(\"emptyDir\")\n\t// A [secret] volume\n\t// Stability: development\n\t//\n\t// [secret]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#secret\n\tK8SVolumeTypeSecret = K8SVolumeTypeKey.String(\"secret\")\n\t// A [local] volume\n\t// Stability: development\n\t//\n\t// [local]: https://v1-30.docs.kubernetes.io/docs/concepts/storage/volumes/#local\n\tK8SVolumeTypeLocal = K8SVolumeTypeKey.String(\"local\")\n)\n\n// Namespace: log\nconst (\n\t// LogFileNameKey is the attribute Key conforming to the \"log.file.name\"\n\t// semantic conventions. It represents the basename of the file.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"audit.log\"\n\tLogFileNameKey = attribute.Key(\"log.file.name\")\n\n\t// LogFileNameResolvedKey is the attribute Key conforming to the\n\t// \"log.file.name_resolved\" semantic conventions. It represents the basename of\n\t// the file, with symlinks resolved.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"uuid.log\"\n\tLogFileNameResolvedKey = attribute.Key(\"log.file.name_resolved\")\n\n\t// LogFilePathKey is the attribute Key conforming to the \"log.file.path\"\n\t// semantic conventions. It represents the full path to the file.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/var/log/mysql/audit.log\"\n\tLogFilePathKey = attribute.Key(\"log.file.path\")\n\n\t// LogFilePathResolvedKey is the attribute Key conforming to the\n\t// \"log.file.path_resolved\" semantic conventions. It represents the full path to\n\t// the file, with symlinks resolved.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/var/lib/docker/uuid.log\"\n\tLogFilePathResolvedKey = attribute.Key(\"log.file.path_resolved\")\n\n\t// LogIostreamKey is the attribute Key conforming to the \"log.iostream\" semantic\n\t// conventions. It represents the stream associated with the log. See below for\n\t// a list of well-known values.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tLogIostreamKey = attribute.Key(\"log.iostream\")\n\n\t// LogRecordOriginalKey is the attribute Key conforming to the\n\t// \"log.record.original\" semantic conventions. It represents the complete\n\t// original Log Record.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"77 <86>1 2015-08-06T21:58:59.694Z 192.168.2.133 inactive - - -\n\t// Something happened\", \"[INFO] 8/3/24 12:34:56 Something happened\"\n\t// Note: This value MAY be added when processing a Log Record which was\n\t// originally transmitted as a string or equivalent data type AND the Body field\n\t// of the Log Record does not contain the same value. (e.g. a syslog or a log\n\t// record read from a file.)\n\tLogRecordOriginalKey = attribute.Key(\"log.record.original\")\n\n\t// LogRecordUIDKey is the attribute Key conforming to the \"log.record.uid\"\n\t// semantic conventions. It represents a unique identifier for the Log Record.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"01ARZ3NDEKTSV4RRFFQ69G5FAV\"\n\t// Note: If an id is provided, other log records with the same id will be\n\t// considered duplicates and can be removed safely. This means, that two\n\t// distinguishable log records MUST have different values.\n\t// The id MAY be an\n\t// [Universally Unique Lexicographically Sortable Identifier (ULID)], but other\n\t// identifiers (e.g. UUID) may be used as needed.\n\t//\n\t// [Universally Unique Lexicographically Sortable Identifier (ULID)]: https://github.com/ulid/spec\n\tLogRecordUIDKey = attribute.Key(\"log.record.uid\")\n)\n\n// LogFileName returns an attribute KeyValue conforming to the \"log.file.name\"\n// semantic conventions. It represents the basename of the file.\nfunc LogFileName(val string) attribute.KeyValue {\n\treturn LogFileNameKey.String(val)\n}\n\n// LogFileNameResolved returns an attribute KeyValue conforming to the\n// \"log.file.name_resolved\" semantic conventions. It represents the basename of\n// the file, with symlinks resolved.\nfunc LogFileNameResolved(val string) attribute.KeyValue {\n\treturn LogFileNameResolvedKey.String(val)\n}\n\n// LogFilePath returns an attribute KeyValue conforming to the \"log.file.path\"\n// semantic conventions. It represents the full path to the file.\nfunc LogFilePath(val string) attribute.KeyValue {\n\treturn LogFilePathKey.String(val)\n}\n\n// LogFilePathResolved returns an attribute KeyValue conforming to the\n// \"log.file.path_resolved\" semantic conventions. It represents the full path to\n// the file, with symlinks resolved.\nfunc LogFilePathResolved(val string) attribute.KeyValue {\n\treturn LogFilePathResolvedKey.String(val)\n}\n\n// LogRecordOriginal returns an attribute KeyValue conforming to the\n// \"log.record.original\" semantic conventions. It represents the complete\n// original Log Record.\nfunc LogRecordOriginal(val string) attribute.KeyValue {\n\treturn LogRecordOriginalKey.String(val)\n}\n\n// LogRecordUID returns an attribute KeyValue conforming to the \"log.record.uid\"\n// semantic conventions. It represents a unique identifier for the Log Record.\nfunc LogRecordUID(val string) attribute.KeyValue {\n\treturn LogRecordUIDKey.String(val)\n}\n\n// Enum values for log.iostream\nvar (\n\t// Logs from stdout stream\n\t// Stability: development\n\tLogIostreamStdout = LogIostreamKey.String(\"stdout\")\n\t// Events from stderr stream\n\t// Stability: development\n\tLogIostreamStderr = LogIostreamKey.String(\"stderr\")\n)\n\n// Namespace: mainframe\nconst (\n\t// MainframeLparNameKey is the attribute Key conforming to the\n\t// \"mainframe.lpar.name\" semantic conventions. It represents the name of the\n\t// logical partition that hosts a systems with a mainframe operating system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"LPAR01\"\n\tMainframeLparNameKey = attribute.Key(\"mainframe.lpar.name\")\n)\n\n// MainframeLparName returns an attribute KeyValue conforming to the\n// \"mainframe.lpar.name\" semantic conventions. It represents the name of the\n// logical partition that hosts a systems with a mainframe operating system.\nfunc MainframeLparName(val string) attribute.KeyValue {\n\treturn MainframeLparNameKey.String(val)\n}\n\n// Namespace: mcp\nconst (\n\t// McpMethodNameKey is the attribute Key conforming to the \"mcp.method.name\"\n\t// semantic conventions. It represents the name of the request or notification\n\t// method.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tMcpMethodNameKey = attribute.Key(\"mcp.method.name\")\n\n\t// McpProtocolVersionKey is the attribute Key conforming to the\n\t// \"mcp.protocol.version\" semantic conventions. It represents the [version] of\n\t// the Model Context Protocol used.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2025-06-18\"\n\t//\n\t// [version]: https://modelcontextprotocol.io/specification/versioning\n\tMcpProtocolVersionKey = attribute.Key(\"mcp.protocol.version\")\n\n\t// McpResourceURIKey is the attribute Key conforming to the \"mcp.resource.uri\"\n\t// semantic conventions. It represents the value of the resource uri.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"postgres://database/customers/schema\",\n\t// \"file:///home/user/documents/report.pdf\"\n\t// Note: This is a URI of the resource provided in the following requests or\n\t// notifications: `resources/read`, `resources/subscribe`,\n\t// `resources/unsubscribe`, or `notifications/resources/updated`.\n\tMcpResourceURIKey = attribute.Key(\"mcp.resource.uri\")\n\n\t// McpSessionIDKey is the attribute Key conforming to the \"mcp.session.id\"\n\t// semantic conventions. It represents the identifies [MCP session].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"191c4850af6c49e08843a3f6c80e5046\"\n\t//\n\t// [MCP session]: https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management\n\tMcpSessionIDKey = attribute.Key(\"mcp.session.id\")\n)\n\n// McpProtocolVersion returns an attribute KeyValue conforming to the\n// \"mcp.protocol.version\" semantic conventions. It represents the [version] of\n// the Model Context Protocol used.\n//\n// [version]: https://modelcontextprotocol.io/specification/versioning\nfunc McpProtocolVersion(val string) attribute.KeyValue {\n\treturn McpProtocolVersionKey.String(val)\n}\n\n// McpResourceURI returns an attribute KeyValue conforming to the\n// \"mcp.resource.uri\" semantic conventions. It represents the value of the\n// resource uri.\nfunc McpResourceURI(val string) attribute.KeyValue {\n\treturn McpResourceURIKey.String(val)\n}\n\n// McpSessionID returns an attribute KeyValue conforming to the \"mcp.session.id\"\n// semantic conventions. It represents the identifies [MCP session].\n//\n// [MCP session]: https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management\nfunc McpSessionID(val string) attribute.KeyValue {\n\treturn McpSessionIDKey.String(val)\n}\n\n// Enum values for mcp.method.name\nvar (\n\t// Notification cancelling a previously-issued request.\n\t//\n\t// Stability: development\n\tMcpMethodNameNotificationsCancelled = McpMethodNameKey.String(\"notifications/cancelled\")\n\t// Request to initialize the MCP client.\n\t//\n\t// Stability: development\n\tMcpMethodNameInitialize = McpMethodNameKey.String(\"initialize\")\n\t// Notification indicating that the MCP client has been initialized.\n\t//\n\t// Stability: development\n\tMcpMethodNameNotificationsInitialized = McpMethodNameKey.String(\"notifications/initialized\")\n\t// Notification indicating the progress for a long-running operation.\n\t//\n\t// Stability: development\n\tMcpMethodNameNotificationsProgress = McpMethodNameKey.String(\"notifications/progress\")\n\t// Request to check that the other party is still alive.\n\t//\n\t// Stability: development\n\tMcpMethodNamePing = McpMethodNameKey.String(\"ping\")\n\t// Request to list resources available on server.\n\t//\n\t// Stability: development\n\tMcpMethodNameResourcesList = McpMethodNameKey.String(\"resources/list\")\n\t// Request to list resource templates available on server.\n\t//\n\t// Stability: development\n\tMcpMethodNameResourcesTemplatesList = McpMethodNameKey.String(\"resources/templates/list\")\n\t// Request to read a resource.\n\t//\n\t// Stability: development\n\tMcpMethodNameResourcesRead = McpMethodNameKey.String(\"resources/read\")\n\t// Notification indicating that the list of resources has changed.\n\t//\n\t// Stability: development\n\tMcpMethodNameNotificationsResourcesListChanged = McpMethodNameKey.String(\"notifications/resources/list_changed\")\n\t// Request to subscribe to a resource.\n\t//\n\t// Stability: development\n\tMcpMethodNameResourcesSubscribe = McpMethodNameKey.String(\"resources/subscribe\")\n\t// Request to unsubscribe from resource updates.\n\t//\n\t// Stability: development\n\tMcpMethodNameResourcesUnsubscribe = McpMethodNameKey.String(\"resources/unsubscribe\")\n\t// Notification indicating that a resource has been updated.\n\t//\n\t// Stability: development\n\tMcpMethodNameNotificationsResourcesUpdated = McpMethodNameKey.String(\"notifications/resources/updated\")\n\t// Request to list prompts available on server.\n\t//\n\t// Stability: development\n\tMcpMethodNamePromptsList = McpMethodNameKey.String(\"prompts/list\")\n\t// Request to get a prompt.\n\t//\n\t// Stability: development\n\tMcpMethodNamePromptsGet = McpMethodNameKey.String(\"prompts/get\")\n\t// Notification indicating that the list of prompts has changed.\n\t//\n\t// Stability: development\n\tMcpMethodNameNotificationsPromptsListChanged = McpMethodNameKey.String(\"notifications/prompts/list_changed\")\n\t// Request to list tools available on server.\n\t//\n\t// Stability: development\n\tMcpMethodNameToolsList = McpMethodNameKey.String(\"tools/list\")\n\t// Request to call a tool.\n\t//\n\t// Stability: development\n\tMcpMethodNameToolsCall = McpMethodNameKey.String(\"tools/call\")\n\t// Notification indicating that the list of tools has changed.\n\t//\n\t// Stability: development\n\tMcpMethodNameNotificationsToolsListChanged = McpMethodNameKey.String(\"notifications/tools/list_changed\")\n\t// Request to set the logging level.\n\t//\n\t// Stability: development\n\tMcpMethodNameLoggingSetLevel = McpMethodNameKey.String(\"logging/setLevel\")\n\t// Notification indicating that a message has been received.\n\t//\n\t// Stability: development\n\tMcpMethodNameNotificationsMessage = McpMethodNameKey.String(\"notifications/message\")\n\t// Request to create a sampling message.\n\t//\n\t// Stability: development\n\tMcpMethodNameSamplingCreateMessage = McpMethodNameKey.String(\"sampling/createMessage\")\n\t// Request to complete a prompt.\n\t//\n\t// Stability: development\n\tMcpMethodNameCompletionComplete = McpMethodNameKey.String(\"completion/complete\")\n\t// Request to list roots available on server.\n\t//\n\t// Stability: development\n\tMcpMethodNameRootsList = McpMethodNameKey.String(\"roots/list\")\n\t// Notification indicating that the list of roots has changed.\n\t//\n\t// Stability: development\n\tMcpMethodNameNotificationsRootsListChanged = McpMethodNameKey.String(\"notifications/roots/list_changed\")\n\t// Request from the server to elicit additional information from the user via\n\t// the client\n\t//\n\t// Stability: development\n\tMcpMethodNameElicitationCreate = McpMethodNameKey.String(\"elicitation/create\")\n)\n\n// Namespace: messaging\nconst (\n\t// MessagingBatchMessageCountKey is the attribute Key conforming to the\n\t// \"messaging.batch.message_count\" semantic conventions. It represents the\n\t// number of messages sent, received, or processed in the scope of the batching\n\t// operation.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 0, 1, 2\n\t// Note: Instrumentations SHOULD NOT set `messaging.batch.message_count` on\n\t// spans that operate with a single message. When a messaging client library\n\t// supports both batch and single-message API for the same operation,\n\t// instrumentations SHOULD use `messaging.batch.message_count` for batching APIs\n\t// and SHOULD NOT use it for single-message APIs.\n\tMessagingBatchMessageCountKey = attribute.Key(\"messaging.batch.message_count\")\n\n\t// MessagingClientIDKey is the attribute Key conforming to the\n\t// \"messaging.client.id\" semantic conventions. It represents a unique identifier\n\t// for the client that consumes or produces a message.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"client-5\", \"myhost@8742@s8083jm\"\n\tMessagingClientIDKey = attribute.Key(\"messaging.client.id\")\n\n\t// MessagingConsumerGroupNameKey is the attribute Key conforming to the\n\t// \"messaging.consumer.group.name\" semantic conventions. It represents the name\n\t// of the consumer group with which a consumer is associated.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-group\", \"indexer\"\n\t// Note: Semantic conventions for individual messaging systems SHOULD document\n\t// whether `messaging.consumer.group.name` is applicable and what it means in\n\t// the context of that system.\n\tMessagingConsumerGroupNameKey = attribute.Key(\"messaging.consumer.group.name\")\n\n\t// MessagingDestinationAnonymousKey is the attribute Key conforming to the\n\t// \"messaging.destination.anonymous\" semantic conventions. It represents a\n\t// boolean that is true if the message destination is anonymous (could be\n\t// unnamed or have auto-generated name).\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tMessagingDestinationAnonymousKey = attribute.Key(\"messaging.destination.anonymous\")\n\n\t// MessagingDestinationNameKey is the attribute Key conforming to the\n\t// \"messaging.destination.name\" semantic conventions. It represents the message\n\t// destination name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"MyQueue\", \"MyTopic\"\n\t// Note: Destination name SHOULD uniquely identify a specific queue, topic or\n\t// other entity within the broker. If\n\t// the broker doesn't have such notion, the destination name SHOULD uniquely\n\t// identify the broker.\n\tMessagingDestinationNameKey = attribute.Key(\"messaging.destination.name\")\n\n\t// MessagingDestinationPartitionIDKey is the attribute Key conforming to the\n\t// \"messaging.destination.partition.id\" semantic conventions. It represents the\n\t// identifier of the partition messages are sent to or received from, unique\n\t// within the `messaging.destination.name`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1\n\tMessagingDestinationPartitionIDKey = attribute.Key(\"messaging.destination.partition.id\")\n\n\t// MessagingDestinationSubscriptionNameKey is the attribute Key conforming to\n\t// the \"messaging.destination.subscription.name\" semantic conventions. It\n\t// represents the name of the destination subscription from which a message is\n\t// consumed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"subscription-a\"\n\t// Note: Semantic conventions for individual messaging systems SHOULD document\n\t// whether `messaging.destination.subscription.name` is applicable and what it\n\t// means in the context of that system.\n\tMessagingDestinationSubscriptionNameKey = attribute.Key(\"messaging.destination.subscription.name\")\n\n\t// MessagingDestinationTemplateKey is the attribute Key conforming to the\n\t// \"messaging.destination.template\" semantic conventions. It represents the low\n\t// cardinality representation of the messaging destination name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/customers/{customerId}\"\n\t// Note: Destination names could be constructed from templates. An example would\n\t// be a destination name involving a user name or product id. Although the\n\t// destination name in this case is of high cardinality, the underlying template\n\t// is of low cardinality and can be effectively used for grouping and\n\t// aggregation.\n\tMessagingDestinationTemplateKey = attribute.Key(\"messaging.destination.template\")\n\n\t// MessagingDestinationTemporaryKey is the attribute Key conforming to the\n\t// \"messaging.destination.temporary\" semantic conventions. It represents a\n\t// boolean that is true if the message destination is temporary and might not\n\t// exist anymore after messages are processed.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tMessagingDestinationTemporaryKey = attribute.Key(\"messaging.destination.temporary\")\n\n\t// MessagingEventHubsMessageEnqueuedTimeKey is the attribute Key conforming to\n\t// the \"messaging.eventhubs.message.enqueued_time\" semantic conventions. It\n\t// represents the UTC epoch seconds at which the message has been accepted and\n\t// stored in the entity.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingEventHubsMessageEnqueuedTimeKey = attribute.Key(\"messaging.eventhubs.message.enqueued_time\")\n\n\t// MessagingGCPPubSubMessageAckDeadlineKey is the attribute Key conforming to\n\t// the \"messaging.gcp_pubsub.message.ack_deadline\" semantic conventions. It\n\t// represents the ack deadline in seconds set for the modify ack deadline\n\t// request.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingGCPPubSubMessageAckDeadlineKey = attribute.Key(\"messaging.gcp_pubsub.message.ack_deadline\")\n\n\t// MessagingGCPPubSubMessageAckIDKey is the attribute Key conforming to the\n\t// \"messaging.gcp_pubsub.message.ack_id\" semantic conventions. It represents the\n\t// ack id for a given message.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: ack_id\n\tMessagingGCPPubSubMessageAckIDKey = attribute.Key(\"messaging.gcp_pubsub.message.ack_id\")\n\n\t// MessagingGCPPubSubMessageDeliveryAttemptKey is the attribute Key conforming\n\t// to the \"messaging.gcp_pubsub.message.delivery_attempt\" semantic conventions.\n\t// It represents the delivery attempt for a given message.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingGCPPubSubMessageDeliveryAttemptKey = attribute.Key(\"messaging.gcp_pubsub.message.delivery_attempt\")\n\n\t// MessagingGCPPubSubMessageOrderingKeyKey is the attribute Key conforming to\n\t// the \"messaging.gcp_pubsub.message.ordering_key\" semantic conventions. It\n\t// represents the ordering key for a given message. If the attribute is not\n\t// present, the message does not have an ordering key.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: ordering_key\n\tMessagingGCPPubSubMessageOrderingKeyKey = attribute.Key(\"messaging.gcp_pubsub.message.ordering_key\")\n\n\t// MessagingKafkaMessageKeyKey is the attribute Key conforming to the\n\t// \"messaging.kafka.message.key\" semantic conventions. It represents the message\n\t// keys in Kafka are used for grouping alike messages to ensure they're\n\t// processed on the same partition. They differ from `messaging.message.id` in\n\t// that they're not unique. If the key is `null`, the attribute MUST NOT be set.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: myKey\n\t// Note: If the key type is not string, it's string representation has to be\n\t// supplied for the attribute. If the key has no unambiguous, canonical string\n\t// form, don't include its value.\n\tMessagingKafkaMessageKeyKey = attribute.Key(\"messaging.kafka.message.key\")\n\n\t// MessagingKafkaMessageTombstoneKey is the attribute Key conforming to the\n\t// \"messaging.kafka.message.tombstone\" semantic conventions. It represents a\n\t// boolean that is true if the message is a tombstone.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tMessagingKafkaMessageTombstoneKey = attribute.Key(\"messaging.kafka.message.tombstone\")\n\n\t// MessagingKafkaOffsetKey is the attribute Key conforming to the\n\t// \"messaging.kafka.offset\" semantic conventions. It represents the offset of a\n\t// record in the corresponding Kafka partition.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingKafkaOffsetKey = attribute.Key(\"messaging.kafka.offset\")\n\n\t// MessagingMessageBodySizeKey is the attribute Key conforming to the\n\t// \"messaging.message.body.size\" semantic conventions. It represents the size of\n\t// the message body in bytes.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Note: This can refer to both the compressed or uncompressed body size. If\n\t// both sizes are known, the uncompressed\n\t// body size should be used.\n\tMessagingMessageBodySizeKey = attribute.Key(\"messaging.message.body.size\")\n\n\t// MessagingMessageConversationIDKey is the attribute Key conforming to the\n\t// \"messaging.message.conversation_id\" semantic conventions. It represents the\n\t// conversation ID identifying the conversation to which the message belongs,\n\t// represented as a string. Sometimes called \"Correlation ID\".\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: MyConversationId\n\tMessagingMessageConversationIDKey = attribute.Key(\"messaging.message.conversation_id\")\n\n\t// MessagingMessageEnvelopeSizeKey is the attribute Key conforming to the\n\t// \"messaging.message.envelope.size\" semantic conventions. It represents the\n\t// size of the message body and metadata in bytes.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Note: This can refer to both the compressed or uncompressed size. If both\n\t// sizes are known, the uncompressed\n\t// size should be used.\n\tMessagingMessageEnvelopeSizeKey = attribute.Key(\"messaging.message.envelope.size\")\n\n\t// MessagingMessageIDKey is the attribute Key conforming to the\n\t// \"messaging.message.id\" semantic conventions. It represents a value used by\n\t// the messaging system as an identifier for the message, represented as a\n\t// string.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 452a7c7c7c7048c2f887f61572b18fc2\n\tMessagingMessageIDKey = attribute.Key(\"messaging.message.id\")\n\n\t// MessagingOperationNameKey is the attribute Key conforming to the\n\t// \"messaging.operation.name\" semantic conventions. It represents the\n\t// system-specific name of the messaging operation.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"ack\", \"nack\", \"send\"\n\tMessagingOperationNameKey = attribute.Key(\"messaging.operation.name\")\n\n\t// MessagingOperationTypeKey is the attribute Key conforming to the\n\t// \"messaging.operation.type\" semantic conventions. It represents a string\n\t// identifying the type of the messaging operation.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: If a custom value is used, it MUST be of low cardinality.\n\tMessagingOperationTypeKey = attribute.Key(\"messaging.operation.type\")\n\n\t// MessagingRabbitMQDestinationRoutingKeyKey is the attribute Key conforming to\n\t// the \"messaging.rabbitmq.destination.routing_key\" semantic conventions. It\n\t// represents the rabbitMQ message routing key.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: myKey\n\tMessagingRabbitMQDestinationRoutingKeyKey = attribute.Key(\"messaging.rabbitmq.destination.routing_key\")\n\n\t// MessagingRabbitMQMessageDeliveryTagKey is the attribute Key conforming to the\n\t// \"messaging.rabbitmq.message.delivery_tag\" semantic conventions. It represents\n\t// the rabbitMQ message delivery tag.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingRabbitMQMessageDeliveryTagKey = attribute.Key(\"messaging.rabbitmq.message.delivery_tag\")\n\n\t// MessagingRocketMQConsumptionModelKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.consumption_model\" semantic conventions. It represents\n\t// the model of message consumption. This only applies to consumer spans.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tMessagingRocketMQConsumptionModelKey = attribute.Key(\"messaging.rocketmq.consumption_model\")\n\n\t// MessagingRocketMQMessageDelayTimeLevelKey is the attribute Key conforming to\n\t// the \"messaging.rocketmq.message.delay_time_level\" semantic conventions. It\n\t// represents the delay time level for delay message, which determines the\n\t// message delay time.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingRocketMQMessageDelayTimeLevelKey = attribute.Key(\"messaging.rocketmq.message.delay_time_level\")\n\n\t// MessagingRocketMQMessageDeliveryTimestampKey is the attribute Key conforming\n\t// to the \"messaging.rocketmq.message.delivery_timestamp\" semantic conventions.\n\t// It represents the timestamp in milliseconds that the delay message is\n\t// expected to be delivered to consumer.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingRocketMQMessageDeliveryTimestampKey = attribute.Key(\"messaging.rocketmq.message.delivery_timestamp\")\n\n\t// MessagingRocketMQMessageGroupKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.message.group\" semantic conventions. It represents the it\n\t// is essential for FIFO message. Messages that belong to the same message group\n\t// are always processed one by one within the same consumer group.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: myMessageGroup\n\tMessagingRocketMQMessageGroupKey = attribute.Key(\"messaging.rocketmq.message.group\")\n\n\t// MessagingRocketMQMessageKeysKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.message.keys\" semantic conventions. It represents the\n\t// key(s) of message, another way to mark message besides message id.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"keyA\", \"keyB\"\n\tMessagingRocketMQMessageKeysKey = attribute.Key(\"messaging.rocketmq.message.keys\")\n\n\t// MessagingRocketMQMessageTagKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.message.tag\" semantic conventions. It represents the\n\t// secondary classifier of message besides topic.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: tagA\n\tMessagingRocketMQMessageTagKey = attribute.Key(\"messaging.rocketmq.message.tag\")\n\n\t// MessagingRocketMQMessageTypeKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.message.type\" semantic conventions. It represents the\n\t// type of message.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tMessagingRocketMQMessageTypeKey = attribute.Key(\"messaging.rocketmq.message.type\")\n\n\t// MessagingRocketMQNamespaceKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.namespace\" semantic conventions. It represents the\n\t// namespace of RocketMQ resources, resources in different namespaces are\n\t// individual.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: myNamespace\n\tMessagingRocketMQNamespaceKey = attribute.Key(\"messaging.rocketmq.namespace\")\n\n\t// MessagingServiceBusDispositionStatusKey is the attribute Key conforming to\n\t// the \"messaging.servicebus.disposition_status\" semantic conventions. It\n\t// represents the describes the [settlement type].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t//\n\t// [settlement type]: https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock\n\tMessagingServiceBusDispositionStatusKey = attribute.Key(\"messaging.servicebus.disposition_status\")\n\n\t// MessagingServiceBusMessageDeliveryCountKey is the attribute Key conforming to\n\t// the \"messaging.servicebus.message.delivery_count\" semantic conventions. It\n\t// represents the number of deliveries that have been attempted for this\n\t// message.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingServiceBusMessageDeliveryCountKey = attribute.Key(\"messaging.servicebus.message.delivery_count\")\n\n\t// MessagingServiceBusMessageEnqueuedTimeKey is the attribute Key conforming to\n\t// the \"messaging.servicebus.message.enqueued_time\" semantic conventions. It\n\t// represents the UTC epoch seconds at which the message has been accepted and\n\t// stored in the entity.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\tMessagingServiceBusMessageEnqueuedTimeKey = attribute.Key(\"messaging.servicebus.message.enqueued_time\")\n\n\t// MessagingSystemKey is the attribute Key conforming to the \"messaging.system\"\n\t// semantic conventions. It represents the messaging system as identified by the\n\t// client instrumentation.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: The actual messaging system may differ from the one known by the\n\t// client. For example, when using Kafka client libraries to communicate with\n\t// Azure Event Hubs, the `messaging.system` is set to `kafka` based on the\n\t// instrumentation's best knowledge.\n\tMessagingSystemKey = attribute.Key(\"messaging.system\")\n)\n\n// MessagingBatchMessageCount returns an attribute KeyValue conforming to the\n// \"messaging.batch.message_count\" semantic conventions. It represents the number\n// of messages sent, received, or processed in the scope of the batching\n// operation.\nfunc MessagingBatchMessageCount(val int) attribute.KeyValue {\n\treturn MessagingBatchMessageCountKey.Int(val)\n}\n\n// MessagingClientID returns an attribute KeyValue conforming to the\n// \"messaging.client.id\" semantic conventions. It represents a unique identifier\n// for the client that consumes or produces a message.\nfunc MessagingClientID(val string) attribute.KeyValue {\n\treturn MessagingClientIDKey.String(val)\n}\n\n// MessagingConsumerGroupName returns an attribute KeyValue conforming to the\n// \"messaging.consumer.group.name\" semantic conventions. It represents the name\n// of the consumer group with which a consumer is associated.\nfunc MessagingConsumerGroupName(val string) attribute.KeyValue {\n\treturn MessagingConsumerGroupNameKey.String(val)\n}\n\n// MessagingDestinationAnonymous returns an attribute KeyValue conforming to the\n// \"messaging.destination.anonymous\" semantic conventions. It represents a\n// boolean that is true if the message destination is anonymous (could be unnamed\n// or have auto-generated name).\nfunc MessagingDestinationAnonymous(val bool) attribute.KeyValue {\n\treturn MessagingDestinationAnonymousKey.Bool(val)\n}\n\n// MessagingDestinationName returns an attribute KeyValue conforming to the\n// \"messaging.destination.name\" semantic conventions. It represents the message\n// destination name.\nfunc MessagingDestinationName(val string) attribute.KeyValue {\n\treturn MessagingDestinationNameKey.String(val)\n}\n\n// MessagingDestinationPartitionID returns an attribute KeyValue conforming to\n// the \"messaging.destination.partition.id\" semantic conventions. It represents\n// the identifier of the partition messages are sent to or received from, unique\n// within the `messaging.destination.name`.\nfunc MessagingDestinationPartitionID(val string) attribute.KeyValue {\n\treturn MessagingDestinationPartitionIDKey.String(val)\n}\n\n// MessagingDestinationSubscriptionName returns an attribute KeyValue conforming\n// to the \"messaging.destination.subscription.name\" semantic conventions. It\n// represents the name of the destination subscription from which a message is\n// consumed.\nfunc MessagingDestinationSubscriptionName(val string) attribute.KeyValue {\n\treturn MessagingDestinationSubscriptionNameKey.String(val)\n}\n\n// MessagingDestinationTemplate returns an attribute KeyValue conforming to the\n// \"messaging.destination.template\" semantic conventions. It represents the low\n// cardinality representation of the messaging destination name.\nfunc MessagingDestinationTemplate(val string) attribute.KeyValue {\n\treturn MessagingDestinationTemplateKey.String(val)\n}\n\n// MessagingDestinationTemporary returns an attribute KeyValue conforming to the\n// \"messaging.destination.temporary\" semantic conventions. It represents a\n// boolean that is true if the message destination is temporary and might not\n// exist anymore after messages are processed.\nfunc MessagingDestinationTemporary(val bool) attribute.KeyValue {\n\treturn MessagingDestinationTemporaryKey.Bool(val)\n}\n\n// MessagingEventHubsMessageEnqueuedTime returns an attribute KeyValue conforming\n// to the \"messaging.eventhubs.message.enqueued_time\" semantic conventions. It\n// represents the UTC epoch seconds at which the message has been accepted and\n// stored in the entity.\nfunc MessagingEventHubsMessageEnqueuedTime(val int) attribute.KeyValue {\n\treturn MessagingEventHubsMessageEnqueuedTimeKey.Int(val)\n}\n\n// MessagingGCPPubSubMessageAckDeadline returns an attribute KeyValue conforming\n// to the \"messaging.gcp_pubsub.message.ack_deadline\" semantic conventions. It\n// represents the ack deadline in seconds set for the modify ack deadline\n// request.\nfunc MessagingGCPPubSubMessageAckDeadline(val int) attribute.KeyValue {\n\treturn MessagingGCPPubSubMessageAckDeadlineKey.Int(val)\n}\n\n// MessagingGCPPubSubMessageAckID returns an attribute KeyValue conforming to the\n// \"messaging.gcp_pubsub.message.ack_id\" semantic conventions. It represents the\n// ack id for a given message.\nfunc MessagingGCPPubSubMessageAckID(val string) attribute.KeyValue {\n\treturn MessagingGCPPubSubMessageAckIDKey.String(val)\n}\n\n// MessagingGCPPubSubMessageDeliveryAttempt returns an attribute KeyValue\n// conforming to the \"messaging.gcp_pubsub.message.delivery_attempt\" semantic\n// conventions. It represents the delivery attempt for a given message.\nfunc MessagingGCPPubSubMessageDeliveryAttempt(val int) attribute.KeyValue {\n\treturn MessagingGCPPubSubMessageDeliveryAttemptKey.Int(val)\n}\n\n// MessagingGCPPubSubMessageOrderingKey returns an attribute KeyValue conforming\n// to the \"messaging.gcp_pubsub.message.ordering_key\" semantic conventions. It\n// represents the ordering key for a given message. If the attribute is not\n// present, the message does not have an ordering key.\nfunc MessagingGCPPubSubMessageOrderingKey(val string) attribute.KeyValue {\n\treturn MessagingGCPPubSubMessageOrderingKeyKey.String(val)\n}\n\n// MessagingKafkaMessageKey returns an attribute KeyValue conforming to the\n// \"messaging.kafka.message.key\" semantic conventions. It represents the message\n// keys in Kafka are used for grouping alike messages to ensure they're processed\n// on the same partition. They differ from `messaging.message.id` in that they're\n// not unique. If the key is `null`, the attribute MUST NOT be set.\nfunc MessagingKafkaMessageKey(val string) attribute.KeyValue {\n\treturn MessagingKafkaMessageKeyKey.String(val)\n}\n\n// MessagingKafkaMessageTombstone returns an attribute KeyValue conforming to the\n// \"messaging.kafka.message.tombstone\" semantic conventions. It represents a\n// boolean that is true if the message is a tombstone.\nfunc MessagingKafkaMessageTombstone(val bool) attribute.KeyValue {\n\treturn MessagingKafkaMessageTombstoneKey.Bool(val)\n}\n\n// MessagingKafkaOffset returns an attribute KeyValue conforming to the\n// \"messaging.kafka.offset\" semantic conventions. It represents the offset of a\n// record in the corresponding Kafka partition.\nfunc MessagingKafkaOffset(val int) attribute.KeyValue {\n\treturn MessagingKafkaOffsetKey.Int(val)\n}\n\n// MessagingMessageBodySize returns an attribute KeyValue conforming to the\n// \"messaging.message.body.size\" semantic conventions. It represents the size of\n// the message body in bytes.\nfunc MessagingMessageBodySize(val int) attribute.KeyValue {\n\treturn MessagingMessageBodySizeKey.Int(val)\n}\n\n// MessagingMessageConversationID returns an attribute KeyValue conforming to the\n// \"messaging.message.conversation_id\" semantic conventions. It represents the\n// conversation ID identifying the conversation to which the message belongs,\n// represented as a string. Sometimes called \"Correlation ID\".\nfunc MessagingMessageConversationID(val string) attribute.KeyValue {\n\treturn MessagingMessageConversationIDKey.String(val)\n}\n\n// MessagingMessageEnvelopeSize returns an attribute KeyValue conforming to the\n// \"messaging.message.envelope.size\" semantic conventions. It represents the size\n// of the message body and metadata in bytes.\nfunc MessagingMessageEnvelopeSize(val int) attribute.KeyValue {\n\treturn MessagingMessageEnvelopeSizeKey.Int(val)\n}\n\n// MessagingMessageID returns an attribute KeyValue conforming to the\n// \"messaging.message.id\" semantic conventions. It represents a value used by the\n// messaging system as an identifier for the message, represented as a string.\nfunc MessagingMessageID(val string) attribute.KeyValue {\n\treturn MessagingMessageIDKey.String(val)\n}\n\n// MessagingOperationName returns an attribute KeyValue conforming to the\n// \"messaging.operation.name\" semantic conventions. It represents the\n// system-specific name of the messaging operation.\nfunc MessagingOperationName(val string) attribute.KeyValue {\n\treturn MessagingOperationNameKey.String(val)\n}\n\n// MessagingRabbitMQDestinationRoutingKey returns an attribute KeyValue\n// conforming to the \"messaging.rabbitmq.destination.routing_key\" semantic\n// conventions. It represents the rabbitMQ message routing key.\nfunc MessagingRabbitMQDestinationRoutingKey(val string) attribute.KeyValue {\n\treturn MessagingRabbitMQDestinationRoutingKeyKey.String(val)\n}\n\n// MessagingRabbitMQMessageDeliveryTag returns an attribute KeyValue conforming\n// to the \"messaging.rabbitmq.message.delivery_tag\" semantic conventions. It\n// represents the rabbitMQ message delivery tag.\nfunc MessagingRabbitMQMessageDeliveryTag(val int) attribute.KeyValue {\n\treturn MessagingRabbitMQMessageDeliveryTagKey.Int(val)\n}\n\n// MessagingRocketMQMessageDelayTimeLevel returns an attribute KeyValue\n// conforming to the \"messaging.rocketmq.message.delay_time_level\" semantic\n// conventions. It represents the delay time level for delay message, which\n// determines the message delay time.\nfunc MessagingRocketMQMessageDelayTimeLevel(val int) attribute.KeyValue {\n\treturn MessagingRocketMQMessageDelayTimeLevelKey.Int(val)\n}\n\n// MessagingRocketMQMessageDeliveryTimestamp returns an attribute KeyValue\n// conforming to the \"messaging.rocketmq.message.delivery_timestamp\" semantic\n// conventions. It represents the timestamp in milliseconds that the delay\n// message is expected to be delivered to consumer.\nfunc MessagingRocketMQMessageDeliveryTimestamp(val int) attribute.KeyValue {\n\treturn MessagingRocketMQMessageDeliveryTimestampKey.Int(val)\n}\n\n// MessagingRocketMQMessageGroup returns an attribute KeyValue conforming to the\n// \"messaging.rocketmq.message.group\" semantic conventions. It represents the it\n// is essential for FIFO message. Messages that belong to the same message group\n// are always processed one by one within the same consumer group.\nfunc MessagingRocketMQMessageGroup(val string) attribute.KeyValue {\n\treturn MessagingRocketMQMessageGroupKey.String(val)\n}\n\n// MessagingRocketMQMessageKeys returns an attribute KeyValue conforming to the\n// \"messaging.rocketmq.message.keys\" semantic conventions. It represents the\n// key(s) of message, another way to mark message besides message id.\nfunc MessagingRocketMQMessageKeys(val ...string) attribute.KeyValue {\n\treturn MessagingRocketMQMessageKeysKey.StringSlice(val)\n}\n\n// MessagingRocketMQMessageTag returns an attribute KeyValue conforming to the\n// \"messaging.rocketmq.message.tag\" semantic conventions. It represents the\n// secondary classifier of message besides topic.\nfunc MessagingRocketMQMessageTag(val string) attribute.KeyValue {\n\treturn MessagingRocketMQMessageTagKey.String(val)\n}\n\n// MessagingRocketMQNamespace returns an attribute KeyValue conforming to the\n// \"messaging.rocketmq.namespace\" semantic conventions. It represents the\n// namespace of RocketMQ resources, resources in different namespaces are\n// individual.\nfunc MessagingRocketMQNamespace(val string) attribute.KeyValue {\n\treturn MessagingRocketMQNamespaceKey.String(val)\n}\n\n// MessagingServiceBusMessageDeliveryCount returns an attribute KeyValue\n// conforming to the \"messaging.servicebus.message.delivery_count\" semantic\n// conventions. It represents the number of deliveries that have been attempted\n// for this message.\nfunc MessagingServiceBusMessageDeliveryCount(val int) attribute.KeyValue {\n\treturn MessagingServiceBusMessageDeliveryCountKey.Int(val)\n}\n\n// MessagingServiceBusMessageEnqueuedTime returns an attribute KeyValue\n// conforming to the \"messaging.servicebus.message.enqueued_time\" semantic\n// conventions. It represents the UTC epoch seconds at which the message has been\n// accepted and stored in the entity.\nfunc MessagingServiceBusMessageEnqueuedTime(val int) attribute.KeyValue {\n\treturn MessagingServiceBusMessageEnqueuedTimeKey.Int(val)\n}\n\n// Enum values for messaging.operation.type\nvar (\n\t// A message is created. \"Create\" spans always refer to a single message and are\n\t// used to provide a unique creation context for messages in batch sending\n\t// scenarios.\n\t//\n\t// Stability: development\n\tMessagingOperationTypeCreate = MessagingOperationTypeKey.String(\"create\")\n\t// One or more messages are provided for sending to an intermediary. If a single\n\t// message is sent, the context of the \"Send\" span can be used as the creation\n\t// context and no \"Create\" span needs to be created.\n\t//\n\t// Stability: development\n\tMessagingOperationTypeSend = MessagingOperationTypeKey.String(\"send\")\n\t// One or more messages are requested by a consumer. This operation refers to\n\t// pull-based scenarios, where consumers explicitly call methods of messaging\n\t// SDKs to receive messages.\n\t//\n\t// Stability: development\n\tMessagingOperationTypeReceive = MessagingOperationTypeKey.String(\"receive\")\n\t// One or more messages are processed by a consumer.\n\t//\n\t// Stability: development\n\tMessagingOperationTypeProcess = MessagingOperationTypeKey.String(\"process\")\n\t// One or more messages are settled.\n\t//\n\t// Stability: development\n\tMessagingOperationTypeSettle = MessagingOperationTypeKey.String(\"settle\")\n)\n\n// Enum values for messaging.rocketmq.consumption_model\nvar (\n\t// Clustering consumption model\n\t// Stability: development\n\tMessagingRocketMQConsumptionModelClustering = MessagingRocketMQConsumptionModelKey.String(\"clustering\")\n\t// Broadcasting consumption model\n\t// Stability: development\n\tMessagingRocketMQConsumptionModelBroadcasting = MessagingRocketMQConsumptionModelKey.String(\"broadcasting\")\n)\n\n// Enum values for messaging.rocketmq.message.type\nvar (\n\t// Normal message\n\t// Stability: development\n\tMessagingRocketMQMessageTypeNormal = MessagingRocketMQMessageTypeKey.String(\"normal\")\n\t// FIFO message\n\t// Stability: development\n\tMessagingRocketMQMessageTypeFifo = MessagingRocketMQMessageTypeKey.String(\"fifo\")\n\t// Delay message\n\t// Stability: development\n\tMessagingRocketMQMessageTypeDelay = MessagingRocketMQMessageTypeKey.String(\"delay\")\n\t// Transaction message\n\t// Stability: development\n\tMessagingRocketMQMessageTypeTransaction = MessagingRocketMQMessageTypeKey.String(\"transaction\")\n)\n\n// Enum values for messaging.servicebus.disposition_status\nvar (\n\t// Message is completed\n\t// Stability: development\n\tMessagingServiceBusDispositionStatusComplete = MessagingServiceBusDispositionStatusKey.String(\"complete\")\n\t// Message is abandoned\n\t// Stability: development\n\tMessagingServiceBusDispositionStatusAbandon = MessagingServiceBusDispositionStatusKey.String(\"abandon\")\n\t// Message is sent to dead letter queue\n\t// Stability: development\n\tMessagingServiceBusDispositionStatusDeadLetter = MessagingServiceBusDispositionStatusKey.String(\"dead_letter\")\n\t// Message is deferred\n\t// Stability: development\n\tMessagingServiceBusDispositionStatusDefer = MessagingServiceBusDispositionStatusKey.String(\"defer\")\n)\n\n// Enum values for messaging.system\nvar (\n\t// Apache ActiveMQ\n\t// Stability: development\n\tMessagingSystemActiveMQ = MessagingSystemKey.String(\"activemq\")\n\t// Amazon Simple Notification Service (SNS)\n\t// Stability: development\n\tMessagingSystemAWSSNS = MessagingSystemKey.String(\"aws.sns\")\n\t// Amazon Simple Queue Service (SQS)\n\t// Stability: development\n\tMessagingSystemAWSSQS = MessagingSystemKey.String(\"aws_sqs\")\n\t// Azure Event Grid\n\t// Stability: development\n\tMessagingSystemEventGrid = MessagingSystemKey.String(\"eventgrid\")\n\t// Azure Event Hubs\n\t// Stability: development\n\tMessagingSystemEventHubs = MessagingSystemKey.String(\"eventhubs\")\n\t// Azure Service Bus\n\t// Stability: development\n\tMessagingSystemServiceBus = MessagingSystemKey.String(\"servicebus\")\n\t// Google Cloud Pub/Sub\n\t// Stability: development\n\tMessagingSystemGCPPubSub = MessagingSystemKey.String(\"gcp_pubsub\")\n\t// Java Message Service\n\t// Stability: development\n\tMessagingSystemJMS = MessagingSystemKey.String(\"jms\")\n\t// Apache Kafka\n\t// Stability: development\n\tMessagingSystemKafka = MessagingSystemKey.String(\"kafka\")\n\t// RabbitMQ\n\t// Stability: development\n\tMessagingSystemRabbitMQ = MessagingSystemKey.String(\"rabbitmq\")\n\t// Apache RocketMQ\n\t// Stability: development\n\tMessagingSystemRocketMQ = MessagingSystemKey.String(\"rocketmq\")\n\t// Apache Pulsar\n\t// Stability: development\n\tMessagingSystemPulsar = MessagingSystemKey.String(\"pulsar\")\n)\n\n// Namespace: network\nconst (\n\t// NetworkCarrierICCKey is the attribute Key conforming to the\n\t// \"network.carrier.icc\" semantic conventions. It represents the ISO 3166-1\n\t// alpha-2 2-character country code associated with the mobile carrier network.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: DE\n\tNetworkCarrierICCKey = attribute.Key(\"network.carrier.icc\")\n\n\t// NetworkCarrierMCCKey is the attribute Key conforming to the\n\t// \"network.carrier.mcc\" semantic conventions. It represents the mobile carrier\n\t// country code.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 310\n\tNetworkCarrierMCCKey = attribute.Key(\"network.carrier.mcc\")\n\n\t// NetworkCarrierMNCKey is the attribute Key conforming to the\n\t// \"network.carrier.mnc\" semantic conventions. It represents the mobile carrier\n\t// network code.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 001\n\tNetworkCarrierMNCKey = attribute.Key(\"network.carrier.mnc\")\n\n\t// NetworkCarrierNameKey is the attribute Key conforming to the\n\t// \"network.carrier.name\" semantic conventions. It represents the name of the\n\t// mobile carrier.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: sprint\n\tNetworkCarrierNameKey = attribute.Key(\"network.carrier.name\")\n\n\t// NetworkConnectionStateKey is the attribute Key conforming to the\n\t// \"network.connection.state\" semantic conventions. It represents the state of\n\t// network connection.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"close_wait\"\n\t// Note: Connection states are defined as part of the [rfc9293]\n\t//\n\t// [rfc9293]: https://datatracker.ietf.org/doc/html/rfc9293#section-3.3.2\n\tNetworkConnectionStateKey = attribute.Key(\"network.connection.state\")\n\n\t// NetworkConnectionSubtypeKey is the attribute Key conforming to the\n\t// \"network.connection.subtype\" semantic conventions. It represents the this\n\t// describes more details regarding the connection.type. It may be the type of\n\t// cell technology connection, but it could be used for describing details about\n\t// a wifi connection.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: LTE\n\tNetworkConnectionSubtypeKey = attribute.Key(\"network.connection.subtype\")\n\n\t// NetworkConnectionTypeKey is the attribute Key conforming to the\n\t// \"network.connection.type\" semantic conventions. It represents the internet\n\t// connection type.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: wifi\n\tNetworkConnectionTypeKey = attribute.Key(\"network.connection.type\")\n\n\t// NetworkInterfaceNameKey is the attribute Key conforming to the\n\t// \"network.interface.name\" semantic conventions. It represents the network\n\t// interface name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"lo\", \"eth0\"\n\tNetworkInterfaceNameKey = attribute.Key(\"network.interface.name\")\n\n\t// NetworkIODirectionKey is the attribute Key conforming to the\n\t// \"network.io.direction\" semantic conventions. It represents the network IO\n\t// operation direction.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"transmit\"\n\tNetworkIODirectionKey = attribute.Key(\"network.io.direction\")\n\n\t// NetworkLocalAddressKey is the attribute Key conforming to the\n\t// \"network.local.address\" semantic conventions. It represents the local address\n\t// of the network connection - IP address or Unix domain socket name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"10.1.2.80\", \"/tmp/my.sock\"\n\tNetworkLocalAddressKey = attribute.Key(\"network.local.address\")\n\n\t// NetworkLocalPortKey is the attribute Key conforming to the\n\t// \"network.local.port\" semantic conventions. It represents the local port\n\t// number of the network connection.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: 65123\n\tNetworkLocalPortKey = attribute.Key(\"network.local.port\")\n\n\t// NetworkPeerAddressKey is the attribute Key conforming to the\n\t// \"network.peer.address\" semantic conventions. It represents the peer address\n\t// of the network connection - IP address or Unix domain socket name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"10.1.2.80\", \"/tmp/my.sock\"\n\tNetworkPeerAddressKey = attribute.Key(\"network.peer.address\")\n\n\t// NetworkPeerPortKey is the attribute Key conforming to the \"network.peer.port\"\n\t// semantic conventions. It represents the peer port number of the network\n\t// connection.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: 65123\n\tNetworkPeerPortKey = attribute.Key(\"network.peer.port\")\n\n\t// NetworkProtocolNameKey is the attribute Key conforming to the\n\t// \"network.protocol.name\" semantic conventions. It represents the\n\t// [OSI application layer] or non-OSI equivalent.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"amqp\", \"http\", \"mqtt\"\n\t// Note: The value SHOULD be normalized to lowercase.\n\t//\n\t// [OSI application layer]: https://wikipedia.org/wiki/Application_layer\n\tNetworkProtocolNameKey = attribute.Key(\"network.protocol.name\")\n\n\t// NetworkProtocolVersionKey is the attribute Key conforming to the\n\t// \"network.protocol.version\" semantic conventions. It represents the actual\n\t// version of the protocol used for network communication.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"1.1\", \"2\"\n\t// Note: If protocol version is subject to negotiation (for example using [ALPN]\n\t// ), this attribute SHOULD be set to the negotiated version. If the actual\n\t// protocol version is not known, this attribute SHOULD NOT be set.\n\t//\n\t// [ALPN]: https://www.rfc-editor.org/rfc/rfc7301.html\n\tNetworkProtocolVersionKey = attribute.Key(\"network.protocol.version\")\n\n\t// NetworkTransportKey is the attribute Key conforming to the\n\t// \"network.transport\" semantic conventions. It represents the\n\t// [OSI transport layer] or [inter-process communication method].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"tcp\", \"udp\"\n\t// Note: The value SHOULD be normalized to lowercase.\n\t//\n\t// Consider always setting the transport when setting a port number, since\n\t// a port number is ambiguous without knowing the transport. For example\n\t// different processes could be listening on TCP port 12345 and UDP port 12345.\n\t//\n\t// [OSI transport layer]: https://wikipedia.org/wiki/Transport_layer\n\t// [inter-process communication method]: https://wikipedia.org/wiki/Inter-process_communication\n\tNetworkTransportKey = attribute.Key(\"network.transport\")\n\n\t// NetworkTypeKey is the attribute Key conforming to the \"network.type\" semantic\n\t// conventions. It represents the [OSI network layer] or non-OSI equivalent.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"ipv4\", \"ipv6\"\n\t// Note: The value SHOULD be normalized to lowercase.\n\t//\n\t// [OSI network layer]: https://wikipedia.org/wiki/Network_layer\n\tNetworkTypeKey = attribute.Key(\"network.type\")\n)\n\n// NetworkCarrierICC returns an attribute KeyValue conforming to the\n// \"network.carrier.icc\" semantic conventions. It represents the ISO 3166-1\n// alpha-2 2-character country code associated with the mobile carrier network.\nfunc NetworkCarrierICC(val string) attribute.KeyValue {\n\treturn NetworkCarrierICCKey.String(val)\n}\n\n// NetworkCarrierMCC returns an attribute KeyValue conforming to the\n// \"network.carrier.mcc\" semantic conventions. It represents the mobile carrier\n// country code.\nfunc NetworkCarrierMCC(val string) attribute.KeyValue {\n\treturn NetworkCarrierMCCKey.String(val)\n}\n\n// NetworkCarrierMNC returns an attribute KeyValue conforming to the\n// \"network.carrier.mnc\" semantic conventions. It represents the mobile carrier\n// network code.\nfunc NetworkCarrierMNC(val string) attribute.KeyValue {\n\treturn NetworkCarrierMNCKey.String(val)\n}\n\n// NetworkCarrierName returns an attribute KeyValue conforming to the\n// \"network.carrier.name\" semantic conventions. It represents the name of the\n// mobile carrier.\nfunc NetworkCarrierName(val string) attribute.KeyValue {\n\treturn NetworkCarrierNameKey.String(val)\n}\n\n// NetworkInterfaceName returns an attribute KeyValue conforming to the\n// \"network.interface.name\" semantic conventions. It represents the network\n// interface name.\nfunc NetworkInterfaceName(val string) attribute.KeyValue {\n\treturn NetworkInterfaceNameKey.String(val)\n}\n\n// NetworkLocalAddress returns an attribute KeyValue conforming to the\n// \"network.local.address\" semantic conventions. It represents the local address\n// of the network connection - IP address or Unix domain socket name.\nfunc NetworkLocalAddress(val string) attribute.KeyValue {\n\treturn NetworkLocalAddressKey.String(val)\n}\n\n// NetworkLocalPort returns an attribute KeyValue conforming to the\n// \"network.local.port\" semantic conventions. It represents the local port number\n// of the network connection.\nfunc NetworkLocalPort(val int) attribute.KeyValue {\n\treturn NetworkLocalPortKey.Int(val)\n}\n\n// NetworkPeerAddress returns an attribute KeyValue conforming to the\n// \"network.peer.address\" semantic conventions. It represents the peer address of\n// the network connection - IP address or Unix domain socket name.\nfunc NetworkPeerAddress(val string) attribute.KeyValue {\n\treturn NetworkPeerAddressKey.String(val)\n}\n\n// NetworkPeerPort returns an attribute KeyValue conforming to the\n// \"network.peer.port\" semantic conventions. It represents the peer port number\n// of the network connection.\nfunc NetworkPeerPort(val int) attribute.KeyValue {\n\treturn NetworkPeerPortKey.Int(val)\n}\n\n// NetworkProtocolName returns an attribute KeyValue conforming to the\n// \"network.protocol.name\" semantic conventions. It represents the\n// [OSI application layer] or non-OSI equivalent.\n//\n// [OSI application layer]: https://wikipedia.org/wiki/Application_layer\nfunc NetworkProtocolName(val string) attribute.KeyValue {\n\treturn NetworkProtocolNameKey.String(val)\n}\n\n// NetworkProtocolVersion returns an attribute KeyValue conforming to the\n// \"network.protocol.version\" semantic conventions. It represents the actual\n// version of the protocol used for network communication.\nfunc NetworkProtocolVersion(val string) attribute.KeyValue {\n\treturn NetworkProtocolVersionKey.String(val)\n}\n\n// Enum values for network.connection.state\nvar (\n\t// closed\n\t// Stability: development\n\tNetworkConnectionStateClosed = NetworkConnectionStateKey.String(\"closed\")\n\t// close_wait\n\t// Stability: development\n\tNetworkConnectionStateCloseWait = NetworkConnectionStateKey.String(\"close_wait\")\n\t// closing\n\t// Stability: development\n\tNetworkConnectionStateClosing = NetworkConnectionStateKey.String(\"closing\")\n\t// established\n\t// Stability: development\n\tNetworkConnectionStateEstablished = NetworkConnectionStateKey.String(\"established\")\n\t// fin_wait_1\n\t// Stability: development\n\tNetworkConnectionStateFinWait1 = NetworkConnectionStateKey.String(\"fin_wait_1\")\n\t// fin_wait_2\n\t// Stability: development\n\tNetworkConnectionStateFinWait2 = NetworkConnectionStateKey.String(\"fin_wait_2\")\n\t// last_ack\n\t// Stability: development\n\tNetworkConnectionStateLastAck = NetworkConnectionStateKey.String(\"last_ack\")\n\t// listen\n\t// Stability: development\n\tNetworkConnectionStateListen = NetworkConnectionStateKey.String(\"listen\")\n\t// syn_received\n\t// Stability: development\n\tNetworkConnectionStateSynReceived = NetworkConnectionStateKey.String(\"syn_received\")\n\t// syn_sent\n\t// Stability: development\n\tNetworkConnectionStateSynSent = NetworkConnectionStateKey.String(\"syn_sent\")\n\t// time_wait\n\t// Stability: development\n\tNetworkConnectionStateTimeWait = NetworkConnectionStateKey.String(\"time_wait\")\n)\n\n// Enum values for network.connection.subtype\nvar (\n\t// GPRS\n\t// Stability: development\n\tNetworkConnectionSubtypeGprs = NetworkConnectionSubtypeKey.String(\"gprs\")\n\t// EDGE\n\t// Stability: development\n\tNetworkConnectionSubtypeEdge = NetworkConnectionSubtypeKey.String(\"edge\")\n\t// UMTS\n\t// Stability: development\n\tNetworkConnectionSubtypeUmts = NetworkConnectionSubtypeKey.String(\"umts\")\n\t// CDMA\n\t// Stability: development\n\tNetworkConnectionSubtypeCdma = NetworkConnectionSubtypeKey.String(\"cdma\")\n\t// EVDO Rel. 0\n\t// Stability: development\n\tNetworkConnectionSubtypeEvdo0 = NetworkConnectionSubtypeKey.String(\"evdo_0\")\n\t// EVDO Rev. A\n\t// Stability: development\n\tNetworkConnectionSubtypeEvdoA = NetworkConnectionSubtypeKey.String(\"evdo_a\")\n\t// CDMA2000 1XRTT\n\t// Stability: development\n\tNetworkConnectionSubtypeCdma20001xrtt = NetworkConnectionSubtypeKey.String(\"cdma2000_1xrtt\")\n\t// HSDPA\n\t// Stability: development\n\tNetworkConnectionSubtypeHsdpa = NetworkConnectionSubtypeKey.String(\"hsdpa\")\n\t// HSUPA\n\t// Stability: development\n\tNetworkConnectionSubtypeHsupa = NetworkConnectionSubtypeKey.String(\"hsupa\")\n\t// HSPA\n\t// Stability: development\n\tNetworkConnectionSubtypeHspa = NetworkConnectionSubtypeKey.String(\"hspa\")\n\t// IDEN\n\t// Stability: development\n\tNetworkConnectionSubtypeIden = NetworkConnectionSubtypeKey.String(\"iden\")\n\t// EVDO Rev. B\n\t// Stability: development\n\tNetworkConnectionSubtypeEvdoB = NetworkConnectionSubtypeKey.String(\"evdo_b\")\n\t// LTE\n\t// Stability: development\n\tNetworkConnectionSubtypeLte = NetworkConnectionSubtypeKey.String(\"lte\")\n\t// EHRPD\n\t// Stability: development\n\tNetworkConnectionSubtypeEhrpd = NetworkConnectionSubtypeKey.String(\"ehrpd\")\n\t// HSPAP\n\t// Stability: development\n\tNetworkConnectionSubtypeHspap = NetworkConnectionSubtypeKey.String(\"hspap\")\n\t// GSM\n\t// Stability: development\n\tNetworkConnectionSubtypeGsm = NetworkConnectionSubtypeKey.String(\"gsm\")\n\t// TD-SCDMA\n\t// Stability: development\n\tNetworkConnectionSubtypeTdScdma = NetworkConnectionSubtypeKey.String(\"td_scdma\")\n\t// IWLAN\n\t// Stability: development\n\tNetworkConnectionSubtypeIwlan = NetworkConnectionSubtypeKey.String(\"iwlan\")\n\t// 5G NR (New Radio)\n\t// Stability: development\n\tNetworkConnectionSubtypeNr = NetworkConnectionSubtypeKey.String(\"nr\")\n\t// 5G NRNSA (New Radio Non-Standalone)\n\t// Stability: development\n\tNetworkConnectionSubtypeNrnsa = NetworkConnectionSubtypeKey.String(\"nrnsa\")\n\t// LTE CA\n\t// Stability: development\n\tNetworkConnectionSubtypeLteCa = NetworkConnectionSubtypeKey.String(\"lte_ca\")\n)\n\n// Enum values for network.connection.type\nvar (\n\t// wifi\n\t// Stability: development\n\tNetworkConnectionTypeWifi = NetworkConnectionTypeKey.String(\"wifi\")\n\t// wired\n\t// Stability: development\n\tNetworkConnectionTypeWired = NetworkConnectionTypeKey.String(\"wired\")\n\t// cell\n\t// Stability: development\n\tNetworkConnectionTypeCell = NetworkConnectionTypeKey.String(\"cell\")\n\t// unavailable\n\t// Stability: development\n\tNetworkConnectionTypeUnavailable = NetworkConnectionTypeKey.String(\"unavailable\")\n\t// unknown\n\t// Stability: development\n\tNetworkConnectionTypeUnknown = NetworkConnectionTypeKey.String(\"unknown\")\n)\n\n// Enum values for network.io.direction\nvar (\n\t// transmit\n\t// Stability: development\n\tNetworkIODirectionTransmit = NetworkIODirectionKey.String(\"transmit\")\n\t// receive\n\t// Stability: development\n\tNetworkIODirectionReceive = NetworkIODirectionKey.String(\"receive\")\n)\n\n// Enum values for network.transport\nvar (\n\t// TCP\n\t// Stability: stable\n\tNetworkTransportTCP = NetworkTransportKey.String(\"tcp\")\n\t// UDP\n\t// Stability: stable\n\tNetworkTransportUDP = NetworkTransportKey.String(\"udp\")\n\t// Named or anonymous pipe.\n\t// Stability: stable\n\tNetworkTransportPipe = NetworkTransportKey.String(\"pipe\")\n\t// Unix domain socket\n\t// Stability: stable\n\tNetworkTransportUnix = NetworkTransportKey.String(\"unix\")\n\t// QUIC\n\t// Stability: stable\n\tNetworkTransportQUIC = NetworkTransportKey.String(\"quic\")\n)\n\n// Enum values for network.type\nvar (\n\t// IPv4\n\t// Stability: stable\n\tNetworkTypeIPv4 = NetworkTypeKey.String(\"ipv4\")\n\t// IPv6\n\t// Stability: stable\n\tNetworkTypeIPv6 = NetworkTypeKey.String(\"ipv6\")\n)\n\n// Namespace: nfs\nconst (\n\t// NfsOperationNameKey is the attribute Key conforming to the\n\t// \"nfs.operation.name\" semantic conventions. It represents the NFSv4+ operation\n\t// name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"OPEN\", \"READ\", \"GETATTR\"\n\tNfsOperationNameKey = attribute.Key(\"nfs.operation.name\")\n\n\t// NfsServerRepcacheStatusKey is the attribute Key conforming to the\n\t// \"nfs.server.repcache.status\" semantic conventions. It represents the linux:\n\t// one of \"hit\" (NFSD_STATS_RC_HITS), \"miss\" (NFSD_STATS_RC_MISSES), or\n\t// \"nocache\" (NFSD_STATS_RC_NOCACHE -- uncacheable).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: hit\n\tNfsServerRepcacheStatusKey = attribute.Key(\"nfs.server.repcache.status\")\n)\n\n// NfsOperationName returns an attribute KeyValue conforming to the\n// \"nfs.operation.name\" semantic conventions. It represents the NFSv4+ operation\n// name.\nfunc NfsOperationName(val string) attribute.KeyValue {\n\treturn NfsOperationNameKey.String(val)\n}\n\n// NfsServerRepcacheStatus returns an attribute KeyValue conforming to the\n// \"nfs.server.repcache.status\" semantic conventions. It represents the linux:\n// one of \"hit\" (NFSD_STATS_RC_HITS), \"miss\" (NFSD_STATS_RC_MISSES), or \"nocache\"\n// (NFSD_STATS_RC_NOCACHE -- uncacheable).\nfunc NfsServerRepcacheStatus(val string) attribute.KeyValue {\n\treturn NfsServerRepcacheStatusKey.String(val)\n}\n\n// Namespace: oci\nconst (\n\t// OCIManifestDigestKey is the attribute Key conforming to the\n\t// \"oci.manifest.digest\" semantic conventions. It represents the digest of the\n\t// OCI image manifest. For container images specifically is the digest by which\n\t// the container image is known.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"sha256:e4ca62c0d62f3e886e684806dfe9d4e0cda60d54986898173c1083856cfda0f4\"\n\t// Note: Follows [OCI Image Manifest Specification], and specifically the\n\t// [Digest property].\n\t// An example can be found in [Example Image Manifest].\n\t//\n\t// [OCI Image Manifest Specification]: https://github.com/opencontainers/image-spec/blob/main/manifest.md\n\t// [Digest property]: https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests\n\t// [Example Image Manifest]: https://github.com/opencontainers/image-spec/blob/main/manifest.md#example-image-manifest\n\tOCIManifestDigestKey = attribute.Key(\"oci.manifest.digest\")\n)\n\n// OCIManifestDigest returns an attribute KeyValue conforming to the\n// \"oci.manifest.digest\" semantic conventions. It represents the digest of the\n// OCI image manifest. For container images specifically is the digest by which\n// the container image is known.\nfunc OCIManifestDigest(val string) attribute.KeyValue {\n\treturn OCIManifestDigestKey.String(val)\n}\n\n// Namespace: onc_rpc\nconst (\n\t// OncRPCProcedureNameKey is the attribute Key conforming to the\n\t// \"onc_rpc.procedure.name\" semantic conventions. It represents the ONC/Sun RPC\n\t// procedure name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"OPEN\", \"READ\", \"GETATTR\"\n\tOncRPCProcedureNameKey = attribute.Key(\"onc_rpc.procedure.name\")\n\n\t// OncRPCProcedureNumberKey is the attribute Key conforming to the\n\t// \"onc_rpc.procedure.number\" semantic conventions. It represents the ONC/Sun\n\t// RPC procedure number.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tOncRPCProcedureNumberKey = attribute.Key(\"onc_rpc.procedure.number\")\n\n\t// OncRPCProgramNameKey is the attribute Key conforming to the\n\t// \"onc_rpc.program.name\" semantic conventions. It represents the ONC/Sun RPC\n\t// program name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"portmapper\", \"nfs\"\n\tOncRPCProgramNameKey = attribute.Key(\"onc_rpc.program.name\")\n\n\t// OncRPCVersionKey is the attribute Key conforming to the \"onc_rpc.version\"\n\t// semantic conventions. It represents the ONC/Sun RPC program version.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tOncRPCVersionKey = attribute.Key(\"onc_rpc.version\")\n)\n\n// OncRPCProcedureName returns an attribute KeyValue conforming to the\n// \"onc_rpc.procedure.name\" semantic conventions. It represents the ONC/Sun RPC\n// procedure name.\nfunc OncRPCProcedureName(val string) attribute.KeyValue {\n\treturn OncRPCProcedureNameKey.String(val)\n}\n\n// OncRPCProcedureNumber returns an attribute KeyValue conforming to the\n// \"onc_rpc.procedure.number\" semantic conventions. It represents the ONC/Sun RPC\n// procedure number.\nfunc OncRPCProcedureNumber(val int) attribute.KeyValue {\n\treturn OncRPCProcedureNumberKey.Int(val)\n}\n\n// OncRPCProgramName returns an attribute KeyValue conforming to the\n// \"onc_rpc.program.name\" semantic conventions. It represents the ONC/Sun RPC\n// program name.\nfunc OncRPCProgramName(val string) attribute.KeyValue {\n\treturn OncRPCProgramNameKey.String(val)\n}\n\n// OncRPCVersion returns an attribute KeyValue conforming to the\n// \"onc_rpc.version\" semantic conventions. It represents the ONC/Sun RPC program\n// version.\nfunc OncRPCVersion(val int) attribute.KeyValue {\n\treturn OncRPCVersionKey.Int(val)\n}\n\n// Namespace: openai\nconst (\n\t// OpenAIRequestServiceTierKey is the attribute Key conforming to the\n\t// \"openai.request.service_tier\" semantic conventions. It represents the service\n\t// tier requested. May be a specific tier, default, or auto.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"auto\", \"default\"\n\tOpenAIRequestServiceTierKey = attribute.Key(\"openai.request.service_tier\")\n\n\t// OpenAIResponseServiceTierKey is the attribute Key conforming to the\n\t// \"openai.response.service_tier\" semantic conventions. It represents the\n\t// service tier used for the response.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"scale\", \"default\"\n\tOpenAIResponseServiceTierKey = attribute.Key(\"openai.response.service_tier\")\n\n\t// OpenAIResponseSystemFingerprintKey is the attribute Key conforming to the\n\t// \"openai.response.system_fingerprint\" semantic conventions. It represents a\n\t// fingerprint to track any eventual change in the Generative AI environment.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"fp_44709d6fcb\"\n\tOpenAIResponseSystemFingerprintKey = attribute.Key(\"openai.response.system_fingerprint\")\n)\n\n// OpenAIResponseServiceTier returns an attribute KeyValue conforming to the\n// \"openai.response.service_tier\" semantic conventions. It represents the service\n// tier used for the response.\nfunc OpenAIResponseServiceTier(val string) attribute.KeyValue {\n\treturn OpenAIResponseServiceTierKey.String(val)\n}\n\n// OpenAIResponseSystemFingerprint returns an attribute KeyValue conforming to\n// the \"openai.response.system_fingerprint\" semantic conventions. It represents a\n// fingerprint to track any eventual change in the Generative AI environment.\nfunc OpenAIResponseSystemFingerprint(val string) attribute.KeyValue {\n\treturn OpenAIResponseSystemFingerprintKey.String(val)\n}\n\n// Enum values for openai.request.service_tier\nvar (\n\t// The system will utilize scale tier credits until they are exhausted.\n\t// Stability: development\n\tOpenAIRequestServiceTierAuto = OpenAIRequestServiceTierKey.String(\"auto\")\n\t// The system will utilize the default scale tier.\n\t// Stability: development\n\tOpenAIRequestServiceTierDefault = OpenAIRequestServiceTierKey.String(\"default\")\n)\n\n// Namespace: openshift\nconst (\n\t// OpenShiftClusterquotaNameKey is the attribute Key conforming to the\n\t// \"openshift.clusterquota.name\" semantic conventions. It represents the name of\n\t// the cluster quota.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"opentelemetry\"\n\tOpenShiftClusterquotaNameKey = attribute.Key(\"openshift.clusterquota.name\")\n\n\t// OpenShiftClusterquotaUIDKey is the attribute Key conforming to the\n\t// \"openshift.clusterquota.uid\" semantic conventions. It represents the UID of\n\t// the cluster quota.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"275ecb36-5aa8-4c2a-9c47-d8bb681b9aff\"\n\tOpenShiftClusterquotaUIDKey = attribute.Key(\"openshift.clusterquota.uid\")\n)\n\n// OpenShiftClusterquotaName returns an attribute KeyValue conforming to the\n// \"openshift.clusterquota.name\" semantic conventions. It represents the name of\n// the cluster quota.\nfunc OpenShiftClusterquotaName(val string) attribute.KeyValue {\n\treturn OpenShiftClusterquotaNameKey.String(val)\n}\n\n// OpenShiftClusterquotaUID returns an attribute KeyValue conforming to the\n// \"openshift.clusterquota.uid\" semantic conventions. It represents the UID of\n// the cluster quota.\nfunc OpenShiftClusterquotaUID(val string) attribute.KeyValue {\n\treturn OpenShiftClusterquotaUIDKey.String(val)\n}\n\n// Namespace: opentracing\nconst (\n\t// OpenTracingRefTypeKey is the attribute Key conforming to the\n\t// \"opentracing.ref_type\" semantic conventions. It represents the parent-child\n\t// Reference type.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: The causal relationship between a child Span and a parent Span.\n\tOpenTracingRefTypeKey = attribute.Key(\"opentracing.ref_type\")\n)\n\n// Enum values for opentracing.ref_type\nvar (\n\t// The parent Span depends on the child Span in some capacity\n\t// Stability: development\n\tOpenTracingRefTypeChildOf = OpenTracingRefTypeKey.String(\"child_of\")\n\t// The parent Span doesn't depend in any way on the result of the child Span\n\t// Stability: development\n\tOpenTracingRefTypeFollowsFrom = OpenTracingRefTypeKey.String(\"follows_from\")\n)\n\n// Namespace: os\nconst (\n\t// OSBuildIDKey is the attribute Key conforming to the \"os.build_id\" semantic\n\t// conventions. It represents the unique identifier for a particular build or\n\t// compilation of the operating system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"TQ3C.230805.001.B2\", \"20E247\", \"22621\"\n\tOSBuildIDKey = attribute.Key(\"os.build_id\")\n\n\t// OSDescriptionKey is the attribute Key conforming to the \"os.description\"\n\t// semantic conventions. It represents the human readable (not intended to be\n\t// parsed) OS version information, like e.g. reported by `ver` or\n\t// `lsb_release -a` commands.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Microsoft Windows [Version 10.0.18363.778]\", \"Ubuntu 18.04.1 LTS\"\n\tOSDescriptionKey = attribute.Key(\"os.description\")\n\n\t// OSNameKey is the attribute Key conforming to the \"os.name\" semantic\n\t// conventions. It represents the human readable operating system name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"iOS\", \"Android\", \"Ubuntu\"\n\tOSNameKey = attribute.Key(\"os.name\")\n\n\t// OSTypeKey is the attribute Key conforming to the \"os.type\" semantic\n\t// conventions. It represents the operating system type.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tOSTypeKey = attribute.Key(\"os.type\")\n\n\t// OSVersionKey is the attribute Key conforming to the \"os.version\" semantic\n\t// conventions. It represents the version string of the operating system as\n\t// defined in [Version Attributes].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"14.2.1\", \"18.04.1\"\n\t//\n\t// [Version Attributes]: /docs/resource/README.md#version-attributes\n\tOSVersionKey = attribute.Key(\"os.version\")\n)\n\n// OSBuildID returns an attribute KeyValue conforming to the \"os.build_id\"\n// semantic conventions. It represents the unique identifier for a particular\n// build or compilation of the operating system.\nfunc OSBuildID(val string) attribute.KeyValue {\n\treturn OSBuildIDKey.String(val)\n}\n\n// OSDescription returns an attribute KeyValue conforming to the \"os.description\"\n// semantic conventions. It represents the human readable (not intended to be\n// parsed) OS version information, like e.g. reported by `ver` or\n// `lsb_release -a` commands.\nfunc OSDescription(val string) attribute.KeyValue {\n\treturn OSDescriptionKey.String(val)\n}\n\n// OSName returns an attribute KeyValue conforming to the \"os.name\" semantic\n// conventions. It represents the human readable operating system name.\nfunc OSName(val string) attribute.KeyValue {\n\treturn OSNameKey.String(val)\n}\n\n// OSVersion returns an attribute KeyValue conforming to the \"os.version\"\n// semantic conventions. It represents the version string of the operating system\n// as defined in [Version Attributes].\n//\n// [Version Attributes]: /docs/resource/README.md#version-attributes\nfunc OSVersion(val string) attribute.KeyValue {\n\treturn OSVersionKey.String(val)\n}\n\n// Enum values for os.type\nvar (\n\t// Microsoft Windows\n\t// Stability: development\n\tOSTypeWindows = OSTypeKey.String(\"windows\")\n\t// Linux\n\t// Stability: development\n\tOSTypeLinux = OSTypeKey.String(\"linux\")\n\t// Apple Darwin\n\t// Stability: development\n\tOSTypeDarwin = OSTypeKey.String(\"darwin\")\n\t// FreeBSD\n\t// Stability: development\n\tOSTypeFreeBSD = OSTypeKey.String(\"freebsd\")\n\t// NetBSD\n\t// Stability: development\n\tOSTypeNetBSD = OSTypeKey.String(\"netbsd\")\n\t// OpenBSD\n\t// Stability: development\n\tOSTypeOpenBSD = OSTypeKey.String(\"openbsd\")\n\t// DragonFly BSD\n\t// Stability: development\n\tOSTypeDragonflyBSD = OSTypeKey.String(\"dragonflybsd\")\n\t// HP-UX (Hewlett Packard Unix)\n\t// Stability: development\n\tOSTypeHPUX = OSTypeKey.String(\"hpux\")\n\t// AIX (Advanced Interactive eXecutive)\n\t// Stability: development\n\tOSTypeAIX = OSTypeKey.String(\"aix\")\n\t// SunOS, Oracle Solaris\n\t// Stability: development\n\tOSTypeSolaris = OSTypeKey.String(\"solaris\")\n\t// IBM z/OS\n\t// Stability: development\n\tOSTypeZOS = OSTypeKey.String(\"zos\")\n)\n\n// Namespace: otel\nconst (\n\t// OTelComponentNameKey is the attribute Key conforming to the\n\t// \"otel.component.name\" semantic conventions. It represents a name uniquely\n\t// identifying the instance of the OpenTelemetry component within its containing\n\t// SDK instance.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"otlp_grpc_span_exporter/0\", \"custom-name\"\n\t// Note: Implementations SHOULD ensure a low cardinality for this attribute,\n\t// even across application or SDK restarts.\n\t// E.g. implementations MUST NOT use UUIDs as values for this attribute.\n\t//\n\t// Implementations MAY achieve these goals by following a\n\t// `<otel.component.type>/<instance-counter>` pattern, e.g.\n\t// `batching_span_processor/0`.\n\t// Hereby `otel.component.type` refers to the corresponding attribute value of\n\t// the component.\n\t//\n\t// The value of `instance-counter` MAY be automatically assigned by the\n\t// component and uniqueness within the enclosing SDK instance MUST be\n\t// guaranteed.\n\t// For example, `<instance-counter>` MAY be implemented by using a monotonically\n\t// increasing counter (starting with `0`), which is incremented every time an\n\t// instance of the given component type is started.\n\t//\n\t// With this implementation, for example the first Batching Span Processor would\n\t// have `batching_span_processor/0`\n\t// as `otel.component.name`, the second one `batching_span_processor/1` and so\n\t// on.\n\t// These values will therefore be reused in the case of an application restart.\n\tOTelComponentNameKey = attribute.Key(\"otel.component.name\")\n\n\t// OTelComponentTypeKey is the attribute Key conforming to the\n\t// \"otel.component.type\" semantic conventions. It represents a name identifying\n\t// the type of the OpenTelemetry component.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"batching_span_processor\", \"com.example.MySpanExporter\"\n\t// Note: If none of the standardized values apply, implementations SHOULD use\n\t// the language-defined name of the type.\n\t// E.g. for Java the fully qualified classname SHOULD be used in this case.\n\tOTelComponentTypeKey = attribute.Key(\"otel.component.type\")\n\n\t// OTelEventNameKey is the attribute Key conforming to the \"otel.event.name\"\n\t// semantic conventions. It represents the identifies the class / type of event.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"browser.mouse.click\", \"device.app.lifecycle\"\n\t// Note: This attribute SHOULD be used by non-OTLP exporters when destination\n\t// does not support `EventName` or equivalent field. This attribute MAY be used\n\t// by applications using existing logging libraries so that it can be used to\n\t// set the `EventName` field by Collector or SDK components.\n\tOTelEventNameKey = attribute.Key(\"otel.event.name\")\n\n\t// OTelScopeNameKey is the attribute Key conforming to the \"otel.scope.name\"\n\t// semantic conventions. It represents the name of the instrumentation scope - (\n\t// `InstrumentationScope.Name` in OTLP).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"io.opentelemetry.contrib.mongodb\"\n\tOTelScopeNameKey = attribute.Key(\"otel.scope.name\")\n\n\t// OTelScopeSchemaURLKey is the attribute Key conforming to the\n\t// \"otel.scope.schema_url\" semantic conventions. It represents the schema URL of\n\t// the instrumentation scope.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"https://opentelemetry.io/schemas/1.31.0\"\n\tOTelScopeSchemaURLKey = attribute.Key(\"otel.scope.schema_url\")\n\n\t// OTelScopeVersionKey is the attribute Key conforming to the\n\t// \"otel.scope.version\" semantic conventions. It represents the version of the\n\t// instrumentation scope - (`InstrumentationScope.Version` in OTLP).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"1.0.0\"\n\tOTelScopeVersionKey = attribute.Key(\"otel.scope.version\")\n\n\t// OTelSpanParentOriginKey is the attribute Key conforming to the\n\t// \"otel.span.parent.origin\" semantic conventions. It represents the determines\n\t// whether the span has a parent span, and if so,\n\t// [whether it is a remote parent].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t//\n\t// [whether it is a remote parent]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote\n\tOTelSpanParentOriginKey = attribute.Key(\"otel.span.parent.origin\")\n\n\t// OTelSpanSamplingResultKey is the attribute Key conforming to the\n\t// \"otel.span.sampling_result\" semantic conventions. It represents the result\n\t// value of the sampler for this span.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tOTelSpanSamplingResultKey = attribute.Key(\"otel.span.sampling_result\")\n\n\t// OTelStatusCodeKey is the attribute Key conforming to the \"otel.status_code\"\n\t// semantic conventions. It represents the name of the code, either \"OK\" or\n\t// \"ERROR\". MUST NOT be set if the status code is UNSET.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples:\n\tOTelStatusCodeKey = attribute.Key(\"otel.status_code\")\n\n\t// OTelStatusDescriptionKey is the attribute Key conforming to the\n\t// \"otel.status_description\" semantic conventions. It represents the description\n\t// of the Status if it has a value, otherwise not set.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"resource not found\"\n\tOTelStatusDescriptionKey = attribute.Key(\"otel.status_description\")\n)\n\n// OTelComponentName returns an attribute KeyValue conforming to the\n// \"otel.component.name\" semantic conventions. It represents a name uniquely\n// identifying the instance of the OpenTelemetry component within its containing\n// SDK instance.\nfunc OTelComponentName(val string) attribute.KeyValue {\n\treturn OTelComponentNameKey.String(val)\n}\n\n// OTelEventName returns an attribute KeyValue conforming to the\n// \"otel.event.name\" semantic conventions. It represents the identifies the class\n// / type of event.\nfunc OTelEventName(val string) attribute.KeyValue {\n\treturn OTelEventNameKey.String(val)\n}\n\n// OTelScopeName returns an attribute KeyValue conforming to the\n// \"otel.scope.name\" semantic conventions. It represents the name of the\n// instrumentation scope - (`InstrumentationScope.Name` in OTLP).\nfunc OTelScopeName(val string) attribute.KeyValue {\n\treturn OTelScopeNameKey.String(val)\n}\n\n// OTelScopeSchemaURL returns an attribute KeyValue conforming to the\n// \"otel.scope.schema_url\" semantic conventions. It represents the schema URL of\n// the instrumentation scope.\nfunc OTelScopeSchemaURL(val string) attribute.KeyValue {\n\treturn OTelScopeSchemaURLKey.String(val)\n}\n\n// OTelScopeVersion returns an attribute KeyValue conforming to the\n// \"otel.scope.version\" semantic conventions. It represents the version of the\n// instrumentation scope - (`InstrumentationScope.Version` in OTLP).\nfunc OTelScopeVersion(val string) attribute.KeyValue {\n\treturn OTelScopeVersionKey.String(val)\n}\n\n// OTelStatusDescription returns an attribute KeyValue conforming to the\n// \"otel.status_description\" semantic conventions. It represents the description\n// of the Status if it has a value, otherwise not set.\nfunc OTelStatusDescription(val string) attribute.KeyValue {\n\treturn OTelStatusDescriptionKey.String(val)\n}\n\n// Enum values for otel.component.type\nvar (\n\t// The builtin SDK batching span processor\n\t//\n\t// Stability: development\n\tOTelComponentTypeBatchingSpanProcessor = OTelComponentTypeKey.String(\"batching_span_processor\")\n\t// The builtin SDK simple span processor\n\t//\n\t// Stability: development\n\tOTelComponentTypeSimpleSpanProcessor = OTelComponentTypeKey.String(\"simple_span_processor\")\n\t// The builtin SDK batching log record processor\n\t//\n\t// Stability: development\n\tOTelComponentTypeBatchingLogProcessor = OTelComponentTypeKey.String(\"batching_log_processor\")\n\t// The builtin SDK simple log record processor\n\t//\n\t// Stability: development\n\tOTelComponentTypeSimpleLogProcessor = OTelComponentTypeKey.String(\"simple_log_processor\")\n\t// OTLP span exporter over gRPC with protobuf serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpGRPCSpanExporter = OTelComponentTypeKey.String(\"otlp_grpc_span_exporter\")\n\t// OTLP span exporter over HTTP with protobuf serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpHTTPSpanExporter = OTelComponentTypeKey.String(\"otlp_http_span_exporter\")\n\t// OTLP span exporter over HTTP with JSON serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpHTTPJSONSpanExporter = OTelComponentTypeKey.String(\"otlp_http_json_span_exporter\")\n\t// Zipkin span exporter over HTTP\n\t//\n\t// Stability: development\n\tOTelComponentTypeZipkinHTTPSpanExporter = OTelComponentTypeKey.String(\"zipkin_http_span_exporter\")\n\t// OTLP log record exporter over gRPC with protobuf serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpGRPCLogExporter = OTelComponentTypeKey.String(\"otlp_grpc_log_exporter\")\n\t// OTLP log record exporter over HTTP with protobuf serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpHTTPLogExporter = OTelComponentTypeKey.String(\"otlp_http_log_exporter\")\n\t// OTLP log record exporter over HTTP with JSON serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpHTTPJSONLogExporter = OTelComponentTypeKey.String(\"otlp_http_json_log_exporter\")\n\t// The builtin SDK periodically exporting metric reader\n\t//\n\t// Stability: development\n\tOTelComponentTypePeriodicMetricReader = OTelComponentTypeKey.String(\"periodic_metric_reader\")\n\t// OTLP metric exporter over gRPC with protobuf serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpGRPCMetricExporter = OTelComponentTypeKey.String(\"otlp_grpc_metric_exporter\")\n\t// OTLP metric exporter over HTTP with protobuf serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpHTTPMetricExporter = OTelComponentTypeKey.String(\"otlp_http_metric_exporter\")\n\t// OTLP metric exporter over HTTP with JSON serialization\n\t//\n\t// Stability: development\n\tOTelComponentTypeOtlpHTTPJSONMetricExporter = OTelComponentTypeKey.String(\"otlp_http_json_metric_exporter\")\n\t// Prometheus metric exporter over HTTP with the default text-based format\n\t//\n\t// Stability: development\n\tOTelComponentTypePrometheusHTTPTextMetricExporter = OTelComponentTypeKey.String(\"prometheus_http_text_metric_exporter\")\n)\n\n// Enum values for otel.span.parent.origin\nvar (\n\t// The span does not have a parent, it is a root span\n\t// Stability: development\n\tOTelSpanParentOriginNone = OTelSpanParentOriginKey.String(\"none\")\n\t// The span has a parent and the parent's span context [isRemote()] is false\n\t// Stability: development\n\t//\n\t// [isRemote()]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote\n\tOTelSpanParentOriginLocal = OTelSpanParentOriginKey.String(\"local\")\n\t// The span has a parent and the parent's span context [isRemote()] is true\n\t// Stability: development\n\t//\n\t// [isRemote()]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote\n\tOTelSpanParentOriginRemote = OTelSpanParentOriginKey.String(\"remote\")\n)\n\n// Enum values for otel.span.sampling_result\nvar (\n\t// The span is not sampled and not recording\n\t// Stability: development\n\tOTelSpanSamplingResultDrop = OTelSpanSamplingResultKey.String(\"DROP\")\n\t// The span is not sampled, but recording\n\t// Stability: development\n\tOTelSpanSamplingResultRecordOnly = OTelSpanSamplingResultKey.String(\"RECORD_ONLY\")\n\t// The span is sampled and recording\n\t// Stability: development\n\tOTelSpanSamplingResultRecordAndSample = OTelSpanSamplingResultKey.String(\"RECORD_AND_SAMPLE\")\n)\n\n// Enum values for otel.status_code\nvar (\n\t// The operation has been validated by an Application developer or Operator to\n\t// have completed successfully.\n\t// Stability: stable\n\tOTelStatusCodeOk = OTelStatusCodeKey.String(\"OK\")\n\t// The operation contains an error.\n\t// Stability: stable\n\tOTelStatusCodeError = OTelStatusCodeKey.String(\"ERROR\")\n)\n\n// Namespace: pprof\nconst (\n\t// PprofLocationIsFoldedKey is the attribute Key conforming to the\n\t// \"pprof.location.is_folded\" semantic conventions. It represents the provides\n\t// an indication that multiple symbols map to this location's address, for\n\t// example due to identical code folding by the linker. In that case the line\n\t// information represents one of the multiple symbols. This field must be\n\t// recomputed when the symbolization state of the profile changes.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tPprofLocationIsFoldedKey = attribute.Key(\"pprof.location.is_folded\")\n\n\t// PprofMappingHasFilenamesKey is the attribute Key conforming to the\n\t// \"pprof.mapping.has_filenames\" semantic conventions. It represents the\n\t// indicates that there are filenames related to this mapping.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tPprofMappingHasFilenamesKey = attribute.Key(\"pprof.mapping.has_filenames\")\n\n\t// PprofMappingHasFunctionsKey is the attribute Key conforming to the\n\t// \"pprof.mapping.has_functions\" semantic conventions. It represents the\n\t// indicates that there are functions related to this mapping.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tPprofMappingHasFunctionsKey = attribute.Key(\"pprof.mapping.has_functions\")\n\n\t// PprofMappingHasInlineFramesKey is the attribute Key conforming to the\n\t// \"pprof.mapping.has_inline_frames\" semantic conventions. It represents the\n\t// indicates that there are inline frames related to this mapping.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tPprofMappingHasInlineFramesKey = attribute.Key(\"pprof.mapping.has_inline_frames\")\n\n\t// PprofMappingHasLineNumbersKey is the attribute Key conforming to the\n\t// \"pprof.mapping.has_line_numbers\" semantic conventions. It represents the\n\t// indicates that there are line numbers related to this mapping.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tPprofMappingHasLineNumbersKey = attribute.Key(\"pprof.mapping.has_line_numbers\")\n\n\t// PprofProfileCommentKey is the attribute Key conforming to the\n\t// \"pprof.profile.comment\" semantic conventions. It represents the free-form\n\t// text associated with the profile. This field should not be used to store any\n\t// machine-readable information, it is only for human-friendly content.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"hello world\", \"bazinga\"\n\tPprofProfileCommentKey = attribute.Key(\"pprof.profile.comment\")\n\n\t// PprofProfileDocURLKey is the attribute Key conforming to the\n\t// \"pprof.profile.doc_url\" semantic conventions. It represents the documentation\n\t// link for this profile type.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"http://pprof.example.com/cpu-profile.html\"\n\t// Note: The URL must be absolute and may be missing if the profile was\n\t// generated by code that did not supply a link\n\tPprofProfileDocURLKey = attribute.Key(\"pprof.profile.doc_url\")\n\n\t// PprofProfileDropFramesKey is the attribute Key conforming to the\n\t// \"pprof.profile.drop_frames\" semantic conventions. It represents the frames\n\t// with Function.function_name fully matching the regexp will be dropped from\n\t// the samples, along with their successors.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/foobar/\"\n\tPprofProfileDropFramesKey = attribute.Key(\"pprof.profile.drop_frames\")\n\n\t// PprofProfileKeepFramesKey is the attribute Key conforming to the\n\t// \"pprof.profile.keep_frames\" semantic conventions. It represents the frames\n\t// with Function.function_name fully matching the regexp will be kept, even if\n\t// it matches drop_frames.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/bazinga/\"\n\tPprofProfileKeepFramesKey = attribute.Key(\"pprof.profile.keep_frames\")\n)\n\n// PprofLocationIsFolded returns an attribute KeyValue conforming to the\n// \"pprof.location.is_folded\" semantic conventions. It represents the provides an\n// indication that multiple symbols map to this location's address, for example\n// due to identical code folding by the linker. In that case the line information\n// represents one of the multiple symbols. This field must be recomputed when the\n// symbolization state of the profile changes.\nfunc PprofLocationIsFolded(val bool) attribute.KeyValue {\n\treturn PprofLocationIsFoldedKey.Bool(val)\n}\n\n// PprofMappingHasFilenames returns an attribute KeyValue conforming to the\n// \"pprof.mapping.has_filenames\" semantic conventions. It represents the\n// indicates that there are filenames related to this mapping.\nfunc PprofMappingHasFilenames(val bool) attribute.KeyValue {\n\treturn PprofMappingHasFilenamesKey.Bool(val)\n}\n\n// PprofMappingHasFunctions returns an attribute KeyValue conforming to the\n// \"pprof.mapping.has_functions\" semantic conventions. It represents the\n// indicates that there are functions related to this mapping.\nfunc PprofMappingHasFunctions(val bool) attribute.KeyValue {\n\treturn PprofMappingHasFunctionsKey.Bool(val)\n}\n\n// PprofMappingHasInlineFrames returns an attribute KeyValue conforming to the\n// \"pprof.mapping.has_inline_frames\" semantic conventions. It represents the\n// indicates that there are inline frames related to this mapping.\nfunc PprofMappingHasInlineFrames(val bool) attribute.KeyValue {\n\treturn PprofMappingHasInlineFramesKey.Bool(val)\n}\n\n// PprofMappingHasLineNumbers returns an attribute KeyValue conforming to the\n// \"pprof.mapping.has_line_numbers\" semantic conventions. It represents the\n// indicates that there are line numbers related to this mapping.\nfunc PprofMappingHasLineNumbers(val bool) attribute.KeyValue {\n\treturn PprofMappingHasLineNumbersKey.Bool(val)\n}\n\n// PprofProfileComment returns an attribute KeyValue conforming to the\n// \"pprof.profile.comment\" semantic conventions. It represents the free-form text\n// associated with the profile. This field should not be used to store any\n// machine-readable information, it is only for human-friendly content.\nfunc PprofProfileComment(val ...string) attribute.KeyValue {\n\treturn PprofProfileCommentKey.StringSlice(val)\n}\n\n// PprofProfileDocURL returns an attribute KeyValue conforming to the\n// \"pprof.profile.doc_url\" semantic conventions. It represents the documentation\n// link for this profile type.\nfunc PprofProfileDocURL(val string) attribute.KeyValue {\n\treturn PprofProfileDocURLKey.String(val)\n}\n\n// PprofProfileDropFrames returns an attribute KeyValue conforming to the\n// \"pprof.profile.drop_frames\" semantic conventions. It represents the frames\n// with Function.function_name fully matching the regexp will be dropped from the\n// samples, along with their successors.\nfunc PprofProfileDropFrames(val string) attribute.KeyValue {\n\treturn PprofProfileDropFramesKey.String(val)\n}\n\n// PprofProfileKeepFrames returns an attribute KeyValue conforming to the\n// \"pprof.profile.keep_frames\" semantic conventions. It represents the frames\n// with Function.function_name fully matching the regexp will be kept, even if it\n// matches drop_frames.\nfunc PprofProfileKeepFrames(val string) attribute.KeyValue {\n\treturn PprofProfileKeepFramesKey.String(val)\n}\n\n// Namespace: process\nconst (\n\t// ProcessArgsCountKey is the attribute Key conforming to the\n\t// \"process.args_count\" semantic conventions. It represents the length of the\n\t// process.command_args array.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 4\n\t// Note: This field can be useful for querying or performing bucket analysis on\n\t// how many arguments were provided to start a process. More arguments may be an\n\t// indication of suspicious activity.\n\tProcessArgsCountKey = attribute.Key(\"process.args_count\")\n\n\t// ProcessCommandKey is the attribute Key conforming to the \"process.command\"\n\t// semantic conventions. It represents the command used to launch the process\n\t// (i.e. the command name). On Linux based systems, can be set to the zeroth\n\t// string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter\n\t// extracted from `GetCommandLineW`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"cmd/otelcol\"\n\tProcessCommandKey = attribute.Key(\"process.command\")\n\n\t// ProcessCommandArgsKey is the attribute Key conforming to the\n\t// \"process.command_args\" semantic conventions. It represents the all the\n\t// command arguments (including the command/executable itself) as received by\n\t// the process. On Linux-based systems (and some other Unixoid systems\n\t// supporting procfs), can be set according to the list of null-delimited\n\t// strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this\n\t// would be the full argv vector passed to `main`. SHOULD NOT be collected by\n\t// default unless there is sanitization that excludes sensitive data.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"cmd/otecol\", \"--config=config.yaml\"\n\tProcessCommandArgsKey = attribute.Key(\"process.command_args\")\n\n\t// ProcessCommandLineKey is the attribute Key conforming to the\n\t// \"process.command_line\" semantic conventions. It represents the full command\n\t// used to launch the process as a single string representing the full command.\n\t// On Windows, can be set to the result of `GetCommandLineW`. Do not set this if\n\t// you have to assemble it just for monitoring; use `process.command_args`\n\t// instead. SHOULD NOT be collected by default unless there is sanitization that\n\t// excludes sensitive data.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"C:\\cmd\\otecol --config=\"my directory\\config.yaml\"\"\n\tProcessCommandLineKey = attribute.Key(\"process.command_line\")\n\n\t// ProcessContextSwitchTypeKey is the attribute Key conforming to the\n\t// \"process.context_switch.type\" semantic conventions. It represents the\n\t// specifies whether the context switches for this data point were voluntary or\n\t// involuntary.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tProcessContextSwitchTypeKey = attribute.Key(\"process.context_switch.type\")\n\n\t// ProcessCreationTimeKey is the attribute Key conforming to the\n\t// \"process.creation.time\" semantic conventions. It represents the date and time\n\t// the process was created, in ISO 8601 format.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2023-11-21T09:25:34.853Z\"\n\tProcessCreationTimeKey = attribute.Key(\"process.creation.time\")\n\n\t// ProcessExecutableBuildIDGNUKey is the attribute Key conforming to the\n\t// \"process.executable.build_id.gnu\" semantic conventions. It represents the GNU\n\t// build ID as found in the `.note.gnu.build-id` ELF section (hex string).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"c89b11207f6479603b0d49bf291c092c2b719293\"\n\tProcessExecutableBuildIDGNUKey = attribute.Key(\"process.executable.build_id.gnu\")\n\n\t// ProcessExecutableBuildIDGoKey is the attribute Key conforming to the\n\t// \"process.executable.build_id.go\" semantic conventions. It represents the Go\n\t// build ID as retrieved by `go tool buildid <go executable>`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"foh3mEXu7BLZjsN9pOwG/kATcXlYVCDEFouRMQed_/WwRFB1hPo9LBkekthSPG/x8hMC8emW2cCjXD0_1aY\"\n\tProcessExecutableBuildIDGoKey = attribute.Key(\"process.executable.build_id.go\")\n\n\t// ProcessExecutableBuildIDHtlhashKey is the attribute Key conforming to the\n\t// \"process.executable.build_id.htlhash\" semantic conventions. It represents the\n\t// profiling specific build ID for executables. See the OTel specification for\n\t// Profiles for more information.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"600DCAFE4A110000F2BF38C493F5FB92\"\n\tProcessExecutableBuildIDHtlhashKey = attribute.Key(\"process.executable.build_id.htlhash\")\n\n\t// ProcessExecutableNameKey is the attribute Key conforming to the\n\t// \"process.executable.name\" semantic conventions. It represents the name of the\n\t// process executable. On Linux based systems, this SHOULD be set to the base\n\t// name of the target of `/proc/[pid]/exe`. On Windows, this SHOULD be set to\n\t// the base name of `GetProcessImageFileNameW`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"otelcol\"\n\tProcessExecutableNameKey = attribute.Key(\"process.executable.name\")\n\n\t// ProcessExecutablePathKey is the attribute Key conforming to the\n\t// \"process.executable.path\" semantic conventions. It represents the full path\n\t// to the process executable. On Linux based systems, can be set to the target\n\t// of `proc/[pid]/exe`. On Windows, can be set to the result of\n\t// `GetProcessImageFileNameW`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/usr/bin/cmd/otelcol\"\n\tProcessExecutablePathKey = attribute.Key(\"process.executable.path\")\n\n\t// ProcessExitCodeKey is the attribute Key conforming to the \"process.exit.code\"\n\t// semantic conventions. It represents the exit code of the process.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 127\n\tProcessExitCodeKey = attribute.Key(\"process.exit.code\")\n\n\t// ProcessExitTimeKey is the attribute Key conforming to the \"process.exit.time\"\n\t// semantic conventions. It represents the date and time the process exited, in\n\t// ISO 8601 format.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2023-11-21T09:26:12.315Z\"\n\tProcessExitTimeKey = attribute.Key(\"process.exit.time\")\n\n\t// ProcessGroupLeaderPIDKey is the attribute Key conforming to the\n\t// \"process.group_leader.pid\" semantic conventions. It represents the PID of the\n\t// process's group leader. This is also the process group ID (PGID) of the\n\t// process.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 23\n\tProcessGroupLeaderPIDKey = attribute.Key(\"process.group_leader.pid\")\n\n\t// ProcessInteractiveKey is the attribute Key conforming to the\n\t// \"process.interactive\" semantic conventions. It represents the whether the\n\t// process is connected to an interactive shell.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tProcessInteractiveKey = attribute.Key(\"process.interactive\")\n\n\t// ProcessLinuxCgroupKey is the attribute Key conforming to the\n\t// \"process.linux.cgroup\" semantic conventions. It represents the control group\n\t// associated with the process.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1:name=systemd:/user.slice/user-1000.slice/session-3.scope\",\n\t// \"0::/user.slice/user-1000.slice/user@1000.service/tmux-spawn-0267755b-4639-4a27-90ed-f19f88e53748.scope\"\n\t// Note: Control groups (cgroups) are a kernel feature used to organize and\n\t// manage process resources. This attribute provides the path(s) to the\n\t// cgroup(s) associated with the process, which should match the contents of the\n\t// [/proc/[PID]/cgroup] file.\n\t//\n\t// [/proc/[PID]/cgroup]: https://man7.org/linux/man-pages/man7/cgroups.7.html\n\tProcessLinuxCgroupKey = attribute.Key(\"process.linux.cgroup\")\n\n\t// ProcessOwnerKey is the attribute Key conforming to the \"process.owner\"\n\t// semantic conventions. It represents the username of the user that owns the\n\t// process.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"root\"\n\tProcessOwnerKey = attribute.Key(\"process.owner\")\n\n\t// ProcessParentPIDKey is the attribute Key conforming to the\n\t// \"process.parent_pid\" semantic conventions. It represents the parent Process\n\t// identifier (PPID).\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 111\n\tProcessParentPIDKey = attribute.Key(\"process.parent_pid\")\n\n\t// ProcessPIDKey is the attribute Key conforming to the \"process.pid\" semantic\n\t// conventions. It represents the process identifier (PID).\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1234\n\tProcessPIDKey = attribute.Key(\"process.pid\")\n\n\t// ProcessRealUserIDKey is the attribute Key conforming to the\n\t// \"process.real_user.id\" semantic conventions. It represents the real user ID\n\t// (RUID) of the process.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1000\n\tProcessRealUserIDKey = attribute.Key(\"process.real_user.id\")\n\n\t// ProcessRealUserNameKey is the attribute Key conforming to the\n\t// \"process.real_user.name\" semantic conventions. It represents the username of\n\t// the real user of the process.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"operator\"\n\tProcessRealUserNameKey = attribute.Key(\"process.real_user.name\")\n\n\t// ProcessRuntimeDescriptionKey is the attribute Key conforming to the\n\t// \"process.runtime.description\" semantic conventions. It represents an\n\t// additional description about the runtime of the process, for example a\n\t// specific vendor customization of the runtime environment.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0\n\tProcessRuntimeDescriptionKey = attribute.Key(\"process.runtime.description\")\n\n\t// ProcessRuntimeNameKey is the attribute Key conforming to the\n\t// \"process.runtime.name\" semantic conventions. It represents the name of the\n\t// runtime of this process.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"OpenJDK Runtime Environment\"\n\tProcessRuntimeNameKey = attribute.Key(\"process.runtime.name\")\n\n\t// ProcessRuntimeVersionKey is the attribute Key conforming to the\n\t// \"process.runtime.version\" semantic conventions. It represents the version of\n\t// the runtime of this process, as returned by the runtime without modification.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 14.0.2\n\tProcessRuntimeVersionKey = attribute.Key(\"process.runtime.version\")\n\n\t// ProcessSavedUserIDKey is the attribute Key conforming to the\n\t// \"process.saved_user.id\" semantic conventions. It represents the saved user ID\n\t// (SUID) of the process.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1002\n\tProcessSavedUserIDKey = attribute.Key(\"process.saved_user.id\")\n\n\t// ProcessSavedUserNameKey is the attribute Key conforming to the\n\t// \"process.saved_user.name\" semantic conventions. It represents the username of\n\t// the saved user.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"operator\"\n\tProcessSavedUserNameKey = attribute.Key(\"process.saved_user.name\")\n\n\t// ProcessSessionLeaderPIDKey is the attribute Key conforming to the\n\t// \"process.session_leader.pid\" semantic conventions. It represents the PID of\n\t// the process's session leader. This is also the session ID (SID) of the\n\t// process.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 14\n\tProcessSessionLeaderPIDKey = attribute.Key(\"process.session_leader.pid\")\n\n\t// ProcessStateKey is the attribute Key conforming to the \"process.state\"\n\t// semantic conventions. It represents the process state, e.g.,\n\t// [Linux Process State Codes].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"running\"\n\t//\n\t// [Linux Process State Codes]: https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES\n\tProcessStateKey = attribute.Key(\"process.state\")\n\n\t// ProcessTitleKey is the attribute Key conforming to the \"process.title\"\n\t// semantic conventions. It represents the process title (proctitle).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"cat /etc/hostname\", \"xfce4-session\", \"bash\"\n\t// Note: In many Unix-like systems, process title (proctitle), is the string\n\t// that represents the name or command line of a running process, displayed by\n\t// system monitoring tools like ps, top, and htop.\n\tProcessTitleKey = attribute.Key(\"process.title\")\n\n\t// ProcessUserIDKey is the attribute Key conforming to the \"process.user.id\"\n\t// semantic conventions. It represents the effective user ID (EUID) of the\n\t// process.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 1001\n\tProcessUserIDKey = attribute.Key(\"process.user.id\")\n\n\t// ProcessUserNameKey is the attribute Key conforming to the \"process.user.name\"\n\t// semantic conventions. It represents the username of the effective user of the\n\t// process.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"root\"\n\tProcessUserNameKey = attribute.Key(\"process.user.name\")\n\n\t// ProcessVpidKey is the attribute Key conforming to the \"process.vpid\" semantic\n\t// conventions. It represents the virtual process identifier.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 12\n\t// Note: The process ID within a PID namespace. This is not necessarily unique\n\t// across all processes on the host but it is unique within the process\n\t// namespace that the process exists within.\n\tProcessVpidKey = attribute.Key(\"process.vpid\")\n\n\t// ProcessWorkingDirectoryKey is the attribute Key conforming to the\n\t// \"process.working_directory\" semantic conventions. It represents the working\n\t// directory of the process.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/root\"\n\tProcessWorkingDirectoryKey = attribute.Key(\"process.working_directory\")\n)\n\n// ProcessArgsCount returns an attribute KeyValue conforming to the\n// \"process.args_count\" semantic conventions. It represents the length of the\n// process.command_args array.\nfunc ProcessArgsCount(val int) attribute.KeyValue {\n\treturn ProcessArgsCountKey.Int(val)\n}\n\n// ProcessCommand returns an attribute KeyValue conforming to the\n// \"process.command\" semantic conventions. It represents the command used to\n// launch the process (i.e. the command name). On Linux based systems, can be set\n// to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the\n// first parameter extracted from `GetCommandLineW`.\nfunc ProcessCommand(val string) attribute.KeyValue {\n\treturn ProcessCommandKey.String(val)\n}\n\n// ProcessCommandArgs returns an attribute KeyValue conforming to the\n// \"process.command_args\" semantic conventions. It represents the all the command\n// arguments (including the command/executable itself) as received by the\n// process. On Linux-based systems (and some other Unixoid systems supporting\n// procfs), can be set according to the list of null-delimited strings extracted\n// from `proc/[pid]/cmdline`. For libc-based executables, this would be the full\n// argv vector passed to `main`. SHOULD NOT be collected by default unless there\n// is sanitization that excludes sensitive data.\nfunc ProcessCommandArgs(val ...string) attribute.KeyValue {\n\treturn ProcessCommandArgsKey.StringSlice(val)\n}\n\n// ProcessCommandLine returns an attribute KeyValue conforming to the\n// \"process.command_line\" semantic conventions. It represents the full command\n// used to launch the process as a single string representing the full command.\n// On Windows, can be set to the result of `GetCommandLineW`. Do not set this if\n// you have to assemble it just for monitoring; use `process.command_args`\n// instead. SHOULD NOT be collected by default unless there is sanitization that\n// excludes sensitive data.\nfunc ProcessCommandLine(val string) attribute.KeyValue {\n\treturn ProcessCommandLineKey.String(val)\n}\n\n// ProcessCreationTime returns an attribute KeyValue conforming to the\n// \"process.creation.time\" semantic conventions. It represents the date and time\n// the process was created, in ISO 8601 format.\nfunc ProcessCreationTime(val string) attribute.KeyValue {\n\treturn ProcessCreationTimeKey.String(val)\n}\n\n// ProcessEnvironmentVariable returns an attribute KeyValue conforming to the\n// \"process.environment_variable\" semantic conventions. It represents the process\n// environment variables, `<key>` being the environment variable name, the value\n// being the environment variable value.\nfunc ProcessEnvironmentVariable(key string, val string) attribute.KeyValue {\n\treturn attribute.String(\"process.environment_variable.\"+key, val)\n}\n\n// ProcessExecutableBuildIDGNU returns an attribute KeyValue conforming to the\n// \"process.executable.build_id.gnu\" semantic conventions. It represents the GNU\n// build ID as found in the `.note.gnu.build-id` ELF section (hex string).\nfunc ProcessExecutableBuildIDGNU(val string) attribute.KeyValue {\n\treturn ProcessExecutableBuildIDGNUKey.String(val)\n}\n\n// ProcessExecutableBuildIDGo returns an attribute KeyValue conforming to the\n// \"process.executable.build_id.go\" semantic conventions. It represents the Go\n// build ID as retrieved by `go tool buildid <go executable>`.\nfunc ProcessExecutableBuildIDGo(val string) attribute.KeyValue {\n\treturn ProcessExecutableBuildIDGoKey.String(val)\n}\n\n// ProcessExecutableBuildIDHtlhash returns an attribute KeyValue conforming to\n// the \"process.executable.build_id.htlhash\" semantic conventions. It represents\n// the profiling specific build ID for executables. See the OTel specification\n// for Profiles for more information.\nfunc ProcessExecutableBuildIDHtlhash(val string) attribute.KeyValue {\n\treturn ProcessExecutableBuildIDHtlhashKey.String(val)\n}\n\n// ProcessExecutableName returns an attribute KeyValue conforming to the\n// \"process.executable.name\" semantic conventions. It represents the name of the\n// process executable. On Linux based systems, this SHOULD be set to the base\n// name of the target of `/proc/[pid]/exe`. On Windows, this SHOULD be set to the\n// base name of `GetProcessImageFileNameW`.\nfunc ProcessExecutableName(val string) attribute.KeyValue {\n\treturn ProcessExecutableNameKey.String(val)\n}\n\n// ProcessExecutablePath returns an attribute KeyValue conforming to the\n// \"process.executable.path\" semantic conventions. It represents the full path to\n// the process executable. On Linux based systems, can be set to the target of\n// `proc/[pid]/exe`. On Windows, can be set to the result of\n// `GetProcessImageFileNameW`.\nfunc ProcessExecutablePath(val string) attribute.KeyValue {\n\treturn ProcessExecutablePathKey.String(val)\n}\n\n// ProcessExitCode returns an attribute KeyValue conforming to the\n// \"process.exit.code\" semantic conventions. It represents the exit code of the\n// process.\nfunc ProcessExitCode(val int) attribute.KeyValue {\n\treturn ProcessExitCodeKey.Int(val)\n}\n\n// ProcessExitTime returns an attribute KeyValue conforming to the\n// \"process.exit.time\" semantic conventions. It represents the date and time the\n// process exited, in ISO 8601 format.\nfunc ProcessExitTime(val string) attribute.KeyValue {\n\treturn ProcessExitTimeKey.String(val)\n}\n\n// ProcessGroupLeaderPID returns an attribute KeyValue conforming to the\n// \"process.group_leader.pid\" semantic conventions. It represents the PID of the\n// process's group leader. This is also the process group ID (PGID) of the\n// process.\nfunc ProcessGroupLeaderPID(val int) attribute.KeyValue {\n\treturn ProcessGroupLeaderPIDKey.Int(val)\n}\n\n// ProcessInteractive returns an attribute KeyValue conforming to the\n// \"process.interactive\" semantic conventions. It represents the whether the\n// process is connected to an interactive shell.\nfunc ProcessInteractive(val bool) attribute.KeyValue {\n\treturn ProcessInteractiveKey.Bool(val)\n}\n\n// ProcessLinuxCgroup returns an attribute KeyValue conforming to the\n// \"process.linux.cgroup\" semantic conventions. It represents the control group\n// associated with the process.\nfunc ProcessLinuxCgroup(val string) attribute.KeyValue {\n\treturn ProcessLinuxCgroupKey.String(val)\n}\n\n// ProcessOwner returns an attribute KeyValue conforming to the \"process.owner\"\n// semantic conventions. It represents the username of the user that owns the\n// process.\nfunc ProcessOwner(val string) attribute.KeyValue {\n\treturn ProcessOwnerKey.String(val)\n}\n\n// ProcessParentPID returns an attribute KeyValue conforming to the\n// \"process.parent_pid\" semantic conventions. It represents the parent Process\n// identifier (PPID).\nfunc ProcessParentPID(val int) attribute.KeyValue {\n\treturn ProcessParentPIDKey.Int(val)\n}\n\n// ProcessPID returns an attribute KeyValue conforming to the \"process.pid\"\n// semantic conventions. It represents the process identifier (PID).\nfunc ProcessPID(val int) attribute.KeyValue {\n\treturn ProcessPIDKey.Int(val)\n}\n\n// ProcessRealUserID returns an attribute KeyValue conforming to the\n// \"process.real_user.id\" semantic conventions. It represents the real user ID\n// (RUID) of the process.\nfunc ProcessRealUserID(val int) attribute.KeyValue {\n\treturn ProcessRealUserIDKey.Int(val)\n}\n\n// ProcessRealUserName returns an attribute KeyValue conforming to the\n// \"process.real_user.name\" semantic conventions. It represents the username of\n// the real user of the process.\nfunc ProcessRealUserName(val string) attribute.KeyValue {\n\treturn ProcessRealUserNameKey.String(val)\n}\n\n// ProcessRuntimeDescription returns an attribute KeyValue conforming to the\n// \"process.runtime.description\" semantic conventions. It represents an\n// additional description about the runtime of the process, for example a\n// specific vendor customization of the runtime environment.\nfunc ProcessRuntimeDescription(val string) attribute.KeyValue {\n\treturn ProcessRuntimeDescriptionKey.String(val)\n}\n\n// ProcessRuntimeName returns an attribute KeyValue conforming to the\n// \"process.runtime.name\" semantic conventions. It represents the name of the\n// runtime of this process.\nfunc ProcessRuntimeName(val string) attribute.KeyValue {\n\treturn ProcessRuntimeNameKey.String(val)\n}\n\n// ProcessRuntimeVersion returns an attribute KeyValue conforming to the\n// \"process.runtime.version\" semantic conventions. It represents the version of\n// the runtime of this process, as returned by the runtime without modification.\nfunc ProcessRuntimeVersion(val string) attribute.KeyValue {\n\treturn ProcessRuntimeVersionKey.String(val)\n}\n\n// ProcessSavedUserID returns an attribute KeyValue conforming to the\n// \"process.saved_user.id\" semantic conventions. It represents the saved user ID\n// (SUID) of the process.\nfunc ProcessSavedUserID(val int) attribute.KeyValue {\n\treturn ProcessSavedUserIDKey.Int(val)\n}\n\n// ProcessSavedUserName returns an attribute KeyValue conforming to the\n// \"process.saved_user.name\" semantic conventions. It represents the username of\n// the saved user.\nfunc ProcessSavedUserName(val string) attribute.KeyValue {\n\treturn ProcessSavedUserNameKey.String(val)\n}\n\n// ProcessSessionLeaderPID returns an attribute KeyValue conforming to the\n// \"process.session_leader.pid\" semantic conventions. It represents the PID of\n// the process's session leader. This is also the session ID (SID) of the\n// process.\nfunc ProcessSessionLeaderPID(val int) attribute.KeyValue {\n\treturn ProcessSessionLeaderPIDKey.Int(val)\n}\n\n// ProcessTitle returns an attribute KeyValue conforming to the \"process.title\"\n// semantic conventions. It represents the process title (proctitle).\nfunc ProcessTitle(val string) attribute.KeyValue {\n\treturn ProcessTitleKey.String(val)\n}\n\n// ProcessUserID returns an attribute KeyValue conforming to the\n// \"process.user.id\" semantic conventions. It represents the effective user ID\n// (EUID) of the process.\nfunc ProcessUserID(val int) attribute.KeyValue {\n\treturn ProcessUserIDKey.Int(val)\n}\n\n// ProcessUserName returns an attribute KeyValue conforming to the\n// \"process.user.name\" semantic conventions. It represents the username of the\n// effective user of the process.\nfunc ProcessUserName(val string) attribute.KeyValue {\n\treturn ProcessUserNameKey.String(val)\n}\n\n// ProcessVpid returns an attribute KeyValue conforming to the \"process.vpid\"\n// semantic conventions. It represents the virtual process identifier.\nfunc ProcessVpid(val int) attribute.KeyValue {\n\treturn ProcessVpidKey.Int(val)\n}\n\n// ProcessWorkingDirectory returns an attribute KeyValue conforming to the\n// \"process.working_directory\" semantic conventions. It represents the working\n// directory of the process.\nfunc ProcessWorkingDirectory(val string) attribute.KeyValue {\n\treturn ProcessWorkingDirectoryKey.String(val)\n}\n\n// Enum values for process.context_switch.type\nvar (\n\t// voluntary\n\t// Stability: development\n\tProcessContextSwitchTypeVoluntary = ProcessContextSwitchTypeKey.String(\"voluntary\")\n\t// involuntary\n\t// Stability: development\n\tProcessContextSwitchTypeInvoluntary = ProcessContextSwitchTypeKey.String(\"involuntary\")\n)\n\n// Enum values for process.state\nvar (\n\t// running\n\t// Stability: development\n\tProcessStateRunning = ProcessStateKey.String(\"running\")\n\t// sleeping\n\t// Stability: development\n\tProcessStateSleeping = ProcessStateKey.String(\"sleeping\")\n\t// stopped\n\t// Stability: development\n\tProcessStateStopped = ProcessStateKey.String(\"stopped\")\n\t// defunct\n\t// Stability: development\n\tProcessStateDefunct = ProcessStateKey.String(\"defunct\")\n)\n\n// Namespace: profile\nconst (\n\t// ProfileFrameTypeKey is the attribute Key conforming to the\n\t// \"profile.frame.type\" semantic conventions. It represents the describes the\n\t// interpreter or compiler of a single frame.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"cpython\"\n\tProfileFrameTypeKey = attribute.Key(\"profile.frame.type\")\n)\n\n// Enum values for profile.frame.type\nvar (\n\t// [.NET]\n\t//\n\t// Stability: development\n\t//\n\t// [.NET]: https://wikipedia.org/wiki/.NET\n\tProfileFrameTypeDotnet = ProfileFrameTypeKey.String(\"dotnet\")\n\t// [JVM]\n\t//\n\t// Stability: development\n\t//\n\t// [JVM]: https://wikipedia.org/wiki/Java_virtual_machine\n\tProfileFrameTypeJVM = ProfileFrameTypeKey.String(\"jvm\")\n\t// [Kernel]\n\t//\n\t// Stability: development\n\t//\n\t// [Kernel]: https://wikipedia.org/wiki/Kernel_(operating_system)\n\tProfileFrameTypeKernel = ProfileFrameTypeKey.String(\"kernel\")\n\t// Can be one of but not limited to [C], [C++], [Go] or [Rust]. If possible, a\n\t// more precise value MUST be used.\n\t//\n\t// Stability: development\n\t//\n\t// [C]: https://wikipedia.org/wiki/C_(programming_language)\n\t// [C++]: https://wikipedia.org/wiki/C%2B%2B\n\t// [Go]: https://wikipedia.org/wiki/Go_(programming_language)\n\t// [Rust]: https://wikipedia.org/wiki/Rust_(programming_language)\n\tProfileFrameTypeNative = ProfileFrameTypeKey.String(\"native\")\n\t// [Perl]\n\t//\n\t// Stability: development\n\t//\n\t// [Perl]: https://wikipedia.org/wiki/Perl\n\tProfileFrameTypePerl = ProfileFrameTypeKey.String(\"perl\")\n\t// [PHP]\n\t//\n\t// Stability: development\n\t//\n\t// [PHP]: https://wikipedia.org/wiki/PHP\n\tProfileFrameTypePHP = ProfileFrameTypeKey.String(\"php\")\n\t// [Python]\n\t//\n\t// Stability: development\n\t//\n\t// [Python]: https://wikipedia.org/wiki/Python_(programming_language)\n\tProfileFrameTypeCpython = ProfileFrameTypeKey.String(\"cpython\")\n\t// [Ruby]\n\t//\n\t// Stability: development\n\t//\n\t// [Ruby]: https://wikipedia.org/wiki/Ruby_(programming_language)\n\tProfileFrameTypeRuby = ProfileFrameTypeKey.String(\"ruby\")\n\t// [V8JS]\n\t//\n\t// Stability: development\n\t//\n\t// [V8JS]: https://wikipedia.org/wiki/V8_(JavaScript_engine)\n\tProfileFrameTypeV8JS = ProfileFrameTypeKey.String(\"v8js\")\n\t// [Erlang]\n\t//\n\t// Stability: development\n\t//\n\t// [Erlang]: https://en.wikipedia.org/wiki/BEAM_(Erlang_virtual_machine)\n\tProfileFrameTypeBeam = ProfileFrameTypeKey.String(\"beam\")\n\t// [Go],\n\t//\n\t// Stability: development\n\t//\n\t// [Go]: https://wikipedia.org/wiki/Go_(programming_language)\n\tProfileFrameTypeGo = ProfileFrameTypeKey.String(\"go\")\n\t// [Rust]\n\t//\n\t// Stability: development\n\t//\n\t// [Rust]: https://wikipedia.org/wiki/Rust_(programming_language)\n\tProfileFrameTypeRust = ProfileFrameTypeKey.String(\"rust\")\n)\n\n// Namespace: rpc\nconst (\n\t// RPCMessageCompressedSizeKey is the attribute Key conforming to the\n\t// \"rpc.message.compressed_size\" semantic conventions. It represents the\n\t// compressed size of the message in bytes.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tRPCMessageCompressedSizeKey = attribute.Key(\"rpc.message.compressed_size\")\n\n\t// RPCMessageIDKey is the attribute Key conforming to the \"rpc.message.id\"\n\t// semantic conventions. It MUST be calculated as two different counters\n\t// starting from `1` one for sent messages and one for received message..\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: This way we guarantee that the values will be consistent between\n\t// different implementations.\n\tRPCMessageIDKey = attribute.Key(\"rpc.message.id\")\n\n\t// RPCMessageTypeKey is the attribute Key conforming to the \"rpc.message.type\"\n\t// semantic conventions. It represents the whether this is a received or sent\n\t// message.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tRPCMessageTypeKey = attribute.Key(\"rpc.message.type\")\n\n\t// RPCMessageUncompressedSizeKey is the attribute Key conforming to the\n\t// \"rpc.message.uncompressed_size\" semantic conventions. It represents the\n\t// uncompressed size of the message in bytes.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\tRPCMessageUncompressedSizeKey = attribute.Key(\"rpc.message.uncompressed_size\")\n\n\t// RPCMethodKey is the attribute Key conforming to the \"rpc.method\" semantic\n\t// conventions. It represents the fully-qualified logical name of the method\n\t// from the RPC interface perspective.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"com.example.ExampleService/exampleMethod\", \"EchoService/Echo\",\n\t// \"_OTHER\"\n\t// Note: The method name MAY have unbounded cardinality in edge or error cases.\n\t//\n\t// Some RPC frameworks or libraries provide a fixed set of recognized methods\n\t// for client stubs and server implementations. Instrumentations for such\n\t// frameworks MUST set this attribute to the original method name only\n\t// when the method is recognized by the framework or library.\n\t//\n\t// When the method is not recognized, for example, when the server receives\n\t// a request for a method that is not predefined on the server, or when\n\t// instrumentation is not able to reliably detect if the method is predefined,\n\t// the attribute MUST be set to `_OTHER`. In such cases, tracing\n\t// instrumentations MUST also set `rpc.method_original` attribute to\n\t// the original method value.\n\t//\n\t// If the RPC instrumentation could end up converting valid RPC methods to\n\t// `_OTHER`, then it SHOULD provide a way to configure the list of recognized\n\t// RPC methods.\n\t//\n\t// The `rpc.method` can be different from the name of any implementing\n\t// method/function.\n\t// The `code.function.name` attribute may be used to record the fully-qualified\n\t// method actually executing the call on the server side, or the\n\t// RPC client stub method on the client side.\n\tRPCMethodKey = attribute.Key(\"rpc.method\")\n\n\t// RPCMethodOriginalKey is the attribute Key conforming to the\n\t// \"rpc.method_original\" semantic conventions. It represents the original name\n\t// of the method used by the client.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"com.myservice.EchoService/catchAll\",\n\t// \"com.myservice.EchoService/unknownMethod\", \"InvalidMethod\"\n\tRPCMethodOriginalKey = attribute.Key(\"rpc.method_original\")\n\n\t// RPCResponseStatusCodeKey is the attribute Key conforming to the\n\t// \"rpc.response.status_code\" semantic conventions. It represents the status\n\t// code of the RPC returned by the RPC server or generated by the client.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"OK\", \"DEADLINE_EXCEEDED\", \"-32602\"\n\t// Note: Usually it represents an error code, but may also represent partial\n\t// success, warning, or differentiate between various types of successful\n\t// outcomes.\n\t// Semantic conventions for individual RPC frameworks SHOULD document what\n\t// `rpc.response.status_code` means in the context of that system and which\n\t// values are considered to represent errors.\n\tRPCResponseStatusCodeKey = attribute.Key(\"rpc.response.status_code\")\n\n\t// RPCSystemNameKey is the attribute Key conforming to the \"rpc.system.name\"\n\t// semantic conventions. It represents the Remote Procedure Call (RPC) system.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: The client and server RPC systems may differ for the same RPC\n\t// interaction. For example, a client may use Apache Dubbo or Connect RPC to\n\t// communicate with a server that uses gRPC since both protocols provide\n\t// compatibility with gRPC.\n\tRPCSystemNameKey = attribute.Key(\"rpc.system.name\")\n)\n\n// RPCMessageCompressedSize returns an attribute KeyValue conforming to the\n// \"rpc.message.compressed_size\" semantic conventions. It represents the\n// compressed size of the message in bytes.\nfunc RPCMessageCompressedSize(val int) attribute.KeyValue {\n\treturn RPCMessageCompressedSizeKey.Int(val)\n}\n\n// RPCMessageID returns an attribute KeyValue conforming to the \"rpc.message.id\"\n// semantic conventions. It MUST be calculated as two different counters starting\n// from `1` one for sent messages and one for received message..\nfunc RPCMessageID(val int) attribute.KeyValue {\n\treturn RPCMessageIDKey.Int(val)\n}\n\n// RPCMessageUncompressedSize returns an attribute KeyValue conforming to the\n// \"rpc.message.uncompressed_size\" semantic conventions. It represents the\n// uncompressed size of the message in bytes.\nfunc RPCMessageUncompressedSize(val int) attribute.KeyValue {\n\treturn RPCMessageUncompressedSizeKey.Int(val)\n}\n\n// RPCMethod returns an attribute KeyValue conforming to the \"rpc.method\"\n// semantic conventions. It represents the fully-qualified logical name of the\n// method from the RPC interface perspective.\nfunc RPCMethod(val string) attribute.KeyValue {\n\treturn RPCMethodKey.String(val)\n}\n\n// RPCMethodOriginal returns an attribute KeyValue conforming to the\n// \"rpc.method_original\" semantic conventions. It represents the original name of\n// the method used by the client.\nfunc RPCMethodOriginal(val string) attribute.KeyValue {\n\treturn RPCMethodOriginalKey.String(val)\n}\n\n// RPCRequestMetadata returns an attribute KeyValue conforming to the\n// \"rpc.request.metadata\" semantic conventions. It represents the RPC request\n// metadata, `<key>` being the normalized RPC metadata key (lowercase), the value\n// being the metadata values.\nfunc RPCRequestMetadata(key string, val ...string) attribute.KeyValue {\n\treturn attribute.StringSlice(\"rpc.request.metadata.\"+key, val)\n}\n\n// RPCResponseMetadata returns an attribute KeyValue conforming to the\n// \"rpc.response.metadata\" semantic conventions. It represents the RPC response\n// metadata, `<key>` being the normalized RPC metadata key (lowercase), the value\n// being the metadata values.\nfunc RPCResponseMetadata(key string, val ...string) attribute.KeyValue {\n\treturn attribute.StringSlice(\"rpc.response.metadata.\"+key, val)\n}\n\n// RPCResponseStatusCode returns an attribute KeyValue conforming to the\n// \"rpc.response.status_code\" semantic conventions. It represents the status code\n// of the RPC returned by the RPC server or generated by the client.\nfunc RPCResponseStatusCode(val string) attribute.KeyValue {\n\treturn RPCResponseStatusCodeKey.String(val)\n}\n\n// Enum values for rpc.message.type\nvar (\n\t// sent\n\t// Stability: development\n\tRPCMessageTypeSent = RPCMessageTypeKey.String(\"SENT\")\n\t// received\n\t// Stability: development\n\tRPCMessageTypeReceived = RPCMessageTypeKey.String(\"RECEIVED\")\n)\n\n// Enum values for rpc.system.name\nvar (\n\t// [gRPC]\n\t// Stability: development\n\t//\n\t// [gRPC]: https://grpc.io/\n\tRPCSystemNameGRPC = RPCSystemNameKey.String(\"grpc\")\n\t// [Apache Dubbo]\n\t// Stability: development\n\t//\n\t// [Apache Dubbo]: https://dubbo.apache.org/\n\tRPCSystemNameDubbo = RPCSystemNameKey.String(\"dubbo\")\n\t// [Connect RPC]\n\t// Stability: development\n\t//\n\t// [Connect RPC]: https://connectrpc.com/\n\tRPCSystemNameConnectrpc = RPCSystemNameKey.String(\"connectrpc\")\n\t// [JSON-RPC]\n\t// Stability: development\n\t//\n\t// [JSON-RPC]: https://www.jsonrpc.org/\n\tRPCSystemNameJSONRPC = RPCSystemNameKey.String(\"jsonrpc\")\n)\n\n// Namespace: security_rule\nconst (\n\t// SecurityRuleCategoryKey is the attribute Key conforming to the\n\t// \"security_rule.category\" semantic conventions. It represents a categorization\n\t// value keyword used by the entity using the rule for detection of this event.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Attempted Information Leak\"\n\tSecurityRuleCategoryKey = attribute.Key(\"security_rule.category\")\n\n\t// SecurityRuleDescriptionKey is the attribute Key conforming to the\n\t// \"security_rule.description\" semantic conventions. It represents the\n\t// description of the rule generating the event.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Block requests to public DNS over HTTPS / TLS protocols\"\n\tSecurityRuleDescriptionKey = attribute.Key(\"security_rule.description\")\n\n\t// SecurityRuleLicenseKey is the attribute Key conforming to the\n\t// \"security_rule.license\" semantic conventions. It represents the name of the\n\t// license under which the rule used to generate this event is made available.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Apache 2.0\"\n\tSecurityRuleLicenseKey = attribute.Key(\"security_rule.license\")\n\n\t// SecurityRuleNameKey is the attribute Key conforming to the\n\t// \"security_rule.name\" semantic conventions. It represents the name of the rule\n\t// or signature generating the event.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"BLOCK_DNS_over_TLS\"\n\tSecurityRuleNameKey = attribute.Key(\"security_rule.name\")\n\n\t// SecurityRuleReferenceKey is the attribute Key conforming to the\n\t// \"security_rule.reference\" semantic conventions. It represents the reference\n\t// URL to additional information about the rule used to generate this event.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"https://en.wikipedia.org/wiki/DNS_over_TLS\"\n\t// Note: The URL can point to the vendor’s documentation about the rule. If\n\t// that’s not available, it can also be a link to a more general page\n\t// describing this type of alert.\n\tSecurityRuleReferenceKey = attribute.Key(\"security_rule.reference\")\n\n\t// SecurityRuleRulesetNameKey is the attribute Key conforming to the\n\t// \"security_rule.ruleset.name\" semantic conventions. It represents the name of\n\t// the ruleset, policy, group, or parent category in which the rule used to\n\t// generate this event is a member.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Standard_Protocol_Filters\"\n\tSecurityRuleRulesetNameKey = attribute.Key(\"security_rule.ruleset.name\")\n\n\t// SecurityRuleUUIDKey is the attribute Key conforming to the\n\t// \"security_rule.uuid\" semantic conventions. It represents a rule ID that is\n\t// unique within the scope of a set or group of agents, observers, or other\n\t// entities using the rule for detection of this event.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"550e8400-e29b-41d4-a716-446655440000\", \"1100110011\"\n\tSecurityRuleUUIDKey = attribute.Key(\"security_rule.uuid\")\n\n\t// SecurityRuleVersionKey is the attribute Key conforming to the\n\t// \"security_rule.version\" semantic conventions. It represents the version /\n\t// revision of the rule being used for analysis.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1.0.0\"\n\tSecurityRuleVersionKey = attribute.Key(\"security_rule.version\")\n)\n\n// SecurityRuleCategory returns an attribute KeyValue conforming to the\n// \"security_rule.category\" semantic conventions. It represents a categorization\n// value keyword used by the entity using the rule for detection of this event.\nfunc SecurityRuleCategory(val string) attribute.KeyValue {\n\treturn SecurityRuleCategoryKey.String(val)\n}\n\n// SecurityRuleDescription returns an attribute KeyValue conforming to the\n// \"security_rule.description\" semantic conventions. It represents the\n// description of the rule generating the event.\nfunc SecurityRuleDescription(val string) attribute.KeyValue {\n\treturn SecurityRuleDescriptionKey.String(val)\n}\n\n// SecurityRuleLicense returns an attribute KeyValue conforming to the\n// \"security_rule.license\" semantic conventions. It represents the name of the\n// license under which the rule used to generate this event is made available.\nfunc SecurityRuleLicense(val string) attribute.KeyValue {\n\treturn SecurityRuleLicenseKey.String(val)\n}\n\n// SecurityRuleName returns an attribute KeyValue conforming to the\n// \"security_rule.name\" semantic conventions. It represents the name of the rule\n// or signature generating the event.\nfunc SecurityRuleName(val string) attribute.KeyValue {\n\treturn SecurityRuleNameKey.String(val)\n}\n\n// SecurityRuleReference returns an attribute KeyValue conforming to the\n// \"security_rule.reference\" semantic conventions. It represents the reference\n// URL to additional information about the rule used to generate this event.\nfunc SecurityRuleReference(val string) attribute.KeyValue {\n\treturn SecurityRuleReferenceKey.String(val)\n}\n\n// SecurityRuleRulesetName returns an attribute KeyValue conforming to the\n// \"security_rule.ruleset.name\" semantic conventions. It represents the name of\n// the ruleset, policy, group, or parent category in which the rule used to\n// generate this event is a member.\nfunc SecurityRuleRulesetName(val string) attribute.KeyValue {\n\treturn SecurityRuleRulesetNameKey.String(val)\n}\n\n// SecurityRuleUUID returns an attribute KeyValue conforming to the\n// \"security_rule.uuid\" semantic conventions. It represents a rule ID that is\n// unique within the scope of a set or group of agents, observers, or other\n// entities using the rule for detection of this event.\nfunc SecurityRuleUUID(val string) attribute.KeyValue {\n\treturn SecurityRuleUUIDKey.String(val)\n}\n\n// SecurityRuleVersion returns an attribute KeyValue conforming to the\n// \"security_rule.version\" semantic conventions. It represents the version /\n// revision of the rule being used for analysis.\nfunc SecurityRuleVersion(val string) attribute.KeyValue {\n\treturn SecurityRuleVersionKey.String(val)\n}\n\n// Namespace: server\nconst (\n\t// ServerAddressKey is the attribute Key conforming to the \"server.address\"\n\t// semantic conventions. It represents the server domain name if available\n\t// without reverse DNS lookup; otherwise, IP address or Unix domain socket name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"example.com\", \"10.1.2.80\", \"/tmp/my.sock\"\n\t// Note: When observed from the client side, and when communicating through an\n\t// intermediary, `server.address` SHOULD represent the server address behind any\n\t// intermediaries, for example proxies, if it's available.\n\tServerAddressKey = attribute.Key(\"server.address\")\n\n\t// ServerPortKey is the attribute Key conforming to the \"server.port\" semantic\n\t// conventions. It represents the server port number.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: 80, 8080, 443\n\t// Note: When observed from the client side, and when communicating through an\n\t// intermediary, `server.port` SHOULD represent the server port behind any\n\t// intermediaries, for example proxies, if it's available.\n\tServerPortKey = attribute.Key(\"server.port\")\n)\n\n// ServerAddress returns an attribute KeyValue conforming to the \"server.address\"\n// semantic conventions. It represents the server domain name if available\n// without reverse DNS lookup; otherwise, IP address or Unix domain socket name.\nfunc ServerAddress(val string) attribute.KeyValue {\n\treturn ServerAddressKey.String(val)\n}\n\n// ServerPort returns an attribute KeyValue conforming to the \"server.port\"\n// semantic conventions. It represents the server port number.\nfunc ServerPort(val int) attribute.KeyValue {\n\treturn ServerPortKey.Int(val)\n}\n\n// Namespace: service\nconst (\n\t// ServiceInstanceIDKey is the attribute Key conforming to the\n\t// \"service.instance.id\" semantic conventions. It represents the string ID of\n\t// the service instance.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"627cc493-f310-47de-96bd-71410b7dec09\"\n\t// Note: MUST be unique for each instance of the same\n\t// `service.namespace,service.name` pair (in other words\n\t// `service.namespace,service.name,service.instance.id` triplet MUST be globally\n\t// unique). The ID helps to\n\t// distinguish instances of the same service that exist at the same time (e.g.\n\t// instances of a horizontally scaled\n\t// service).\n\t//\n\t// Implementations, such as SDKs, are recommended to generate a random Version 1\n\t// or Version 4 [RFC\n\t// 4122] UUID, but are free to use an inherent unique ID as\n\t// the source of\n\t// this value if stability is desirable. In that case, the ID SHOULD be used as\n\t// source of a UUID Version 5 and\n\t// SHOULD use the following UUID as the namespace:\n\t// `4d63009a-8d0f-11ee-aad7-4c796ed8e320`.\n\t//\n\t// UUIDs are typically recommended, as only an opaque value for the purposes of\n\t// identifying a service instance is\n\t// needed. Similar to what can be seen in the man page for the\n\t// [`/etc/machine-id`] file, the underlying\n\t// data, such as pod name and namespace should be treated as confidential, being\n\t// the user's choice to expose it\n\t// or not via another resource attribute.\n\t//\n\t// For applications running behind an application server (like unicorn), we do\n\t// not recommend using one identifier\n\t// for all processes participating in the application. Instead, it's recommended\n\t// each division (e.g. a worker\n\t// thread in unicorn) to have its own instance.id.\n\t//\n\t// It's not recommended for a Collector to set `service.instance.id` if it can't\n\t// unambiguously determine the\n\t// service instance that is generating that telemetry. For instance, creating an\n\t// UUID based on `pod.name` will\n\t// likely be wrong, as the Collector might not know from which container within\n\t// that pod the telemetry originated.\n\t// However, Collectors can set the `service.instance.id` if they can\n\t// unambiguously determine the service instance\n\t// for that telemetry. This is typically the case for scraping receivers, as\n\t// they know the target address and\n\t// port.\n\t//\n\t// [RFC\n\t// 4122]: https://www.ietf.org/rfc/rfc4122.txt\n\t// [`/etc/machine-id`]: https://www.freedesktop.org/software/systemd/man/latest/machine-id.html\n\tServiceInstanceIDKey = attribute.Key(\"service.instance.id\")\n\n\t// ServiceNameKey is the attribute Key conforming to the \"service.name\" semantic\n\t// conventions. It represents the logical name of the service.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"shoppingcart\"\n\t// Note: MUST be the same for all instances of horizontally scaled services. If\n\t// the value was not specified, SDKs MUST fallback to `unknown_service:`\n\t// concatenated with [`process.executable.name`], e.g. `unknown_service:bash`.\n\t// If `process.executable.name` is not available, the value MUST be set to\n\t// `unknown_service`.\n\t//\n\t// [`process.executable.name`]: process.md\n\tServiceNameKey = attribute.Key(\"service.name\")\n\n\t// ServiceNamespaceKey is the attribute Key conforming to the\n\t// \"service.namespace\" semantic conventions. It represents a namespace for\n\t// `service.name`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Shop\"\n\t// Note: A string value having a meaning that helps to distinguish a group of\n\t// services, for example the team name that owns a group of services.\n\t// `service.name` is expected to be unique within the same namespace. If\n\t// `service.namespace` is not specified in the Resource then `service.name` is\n\t// expected to be unique for all services that have no explicit namespace\n\t// defined (so the empty/unspecified namespace is simply one more valid\n\t// namespace). Zero-length namespace string is assumed equal to unspecified\n\t// namespace.\n\tServiceNamespaceKey = attribute.Key(\"service.namespace\")\n\n\t// ServicePeerNameKey is the attribute Key conforming to the \"service.peer.name\"\n\t// semantic conventions. It represents the logical name of the service on the\n\t// other side of the connection. SHOULD be equal to the actual [`service.name`]\n\t// resource attribute of the remote service if any.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"shoppingcart\"\n\t//\n\t// [`service.name`]: /docs/resource/README.md#service\n\tServicePeerNameKey = attribute.Key(\"service.peer.name\")\n\n\t// ServicePeerNamespaceKey is the attribute Key conforming to the\n\t// \"service.peer.namespace\" semantic conventions. It represents the logical\n\t// namespace of the service on the other side of the connection. SHOULD be equal\n\t// to the actual [`service.namespace`] resource attribute of the remote service\n\t// if any.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Shop\"\n\t//\n\t// [`service.namespace`]: /docs/resource/README.md#service\n\tServicePeerNamespaceKey = attribute.Key(\"service.peer.namespace\")\n\n\t// ServiceVersionKey is the attribute Key conforming to the \"service.version\"\n\t// semantic conventions. It represents the version string of the service\n\t// component. The format is not defined by these conventions.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"2.0.0\", \"a01dbef8a\"\n\tServiceVersionKey = attribute.Key(\"service.version\")\n)\n\n// ServiceInstanceID returns an attribute KeyValue conforming to the\n// \"service.instance.id\" semantic conventions. It represents the string ID of the\n// service instance.\nfunc ServiceInstanceID(val string) attribute.KeyValue {\n\treturn ServiceInstanceIDKey.String(val)\n}\n\n// ServiceName returns an attribute KeyValue conforming to the \"service.name\"\n// semantic conventions. It represents the logical name of the service.\nfunc ServiceName(val string) attribute.KeyValue {\n\treturn ServiceNameKey.String(val)\n}\n\n// ServiceNamespace returns an attribute KeyValue conforming to the\n// \"service.namespace\" semantic conventions. It represents a namespace for\n// `service.name`.\nfunc ServiceNamespace(val string) attribute.KeyValue {\n\treturn ServiceNamespaceKey.String(val)\n}\n\n// ServicePeerName returns an attribute KeyValue conforming to the\n// \"service.peer.name\" semantic conventions. It represents the logical name of\n// the service on the other side of the connection. SHOULD be equal to the actual\n// [`service.name`] resource attribute of the remote service if any.\n//\n// [`service.name`]: /docs/resource/README.md#service\nfunc ServicePeerName(val string) attribute.KeyValue {\n\treturn ServicePeerNameKey.String(val)\n}\n\n// ServicePeerNamespace returns an attribute KeyValue conforming to the\n// \"service.peer.namespace\" semantic conventions. It represents the logical\n// namespace of the service on the other side of the connection. SHOULD be equal\n// to the actual [`service.namespace`] resource attribute of the remote service\n// if any.\n//\n// [`service.namespace`]: /docs/resource/README.md#service\nfunc ServicePeerNamespace(val string) attribute.KeyValue {\n\treturn ServicePeerNamespaceKey.String(val)\n}\n\n// ServiceVersion returns an attribute KeyValue conforming to the\n// \"service.version\" semantic conventions. It represents the version string of\n// the service component. The format is not defined by these conventions.\nfunc ServiceVersion(val string) attribute.KeyValue {\n\treturn ServiceVersionKey.String(val)\n}\n\n// Namespace: session\nconst (\n\t// SessionIDKey is the attribute Key conforming to the \"session.id\" semantic\n\t// conventions. It represents a unique id to identify a session.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 00112233-4455-6677-8899-aabbccddeeff\n\tSessionIDKey = attribute.Key(\"session.id\")\n\n\t// SessionPreviousIDKey is the attribute Key conforming to the\n\t// \"session.previous_id\" semantic conventions. It represents the previous\n\t// `session.id` for this user, when known.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 00112233-4455-6677-8899-aabbccddeeff\n\tSessionPreviousIDKey = attribute.Key(\"session.previous_id\")\n)\n\n// SessionID returns an attribute KeyValue conforming to the \"session.id\"\n// semantic conventions. It represents a unique id to identify a session.\nfunc SessionID(val string) attribute.KeyValue {\n\treturn SessionIDKey.String(val)\n}\n\n// SessionPreviousID returns an attribute KeyValue conforming to the\n// \"session.previous_id\" semantic conventions. It represents the previous\n// `session.id` for this user, when known.\nfunc SessionPreviousID(val string) attribute.KeyValue {\n\treturn SessionPreviousIDKey.String(val)\n}\n\n// Namespace: signalr\nconst (\n\t// SignalRConnectionStatusKey is the attribute Key conforming to the\n\t// \"signalr.connection.status\" semantic conventions. It represents the signalR\n\t// HTTP connection closure status.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"app_shutdown\", \"timeout\"\n\tSignalRConnectionStatusKey = attribute.Key(\"signalr.connection.status\")\n\n\t// SignalRTransportKey is the attribute Key conforming to the\n\t// \"signalr.transport\" semantic conventions. It represents the\n\t// [SignalR transport type].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"web_sockets\", \"long_polling\"\n\t//\n\t// [SignalR transport type]: https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/TransportProtocols.md\n\tSignalRTransportKey = attribute.Key(\"signalr.transport\")\n)\n\n// Enum values for signalr.connection.status\nvar (\n\t// The connection was closed normally.\n\t// Stability: stable\n\tSignalRConnectionStatusNormalClosure = SignalRConnectionStatusKey.String(\"normal_closure\")\n\t// The connection was closed due to a timeout.\n\t// Stability: stable\n\tSignalRConnectionStatusTimeout = SignalRConnectionStatusKey.String(\"timeout\")\n\t// The connection was closed because the app is shutting down.\n\t// Stability: stable\n\tSignalRConnectionStatusAppShutdown = SignalRConnectionStatusKey.String(\"app_shutdown\")\n)\n\n// Enum values for signalr.transport\nvar (\n\t// ServerSentEvents protocol\n\t// Stability: stable\n\tSignalRTransportServerSentEvents = SignalRTransportKey.String(\"server_sent_events\")\n\t// LongPolling protocol\n\t// Stability: stable\n\tSignalRTransportLongPolling = SignalRTransportKey.String(\"long_polling\")\n\t// WebSockets protocol\n\t// Stability: stable\n\tSignalRTransportWebSockets = SignalRTransportKey.String(\"web_sockets\")\n)\n\n// Namespace: source\nconst (\n\t// SourceAddressKey is the attribute Key conforming to the \"source.address\"\n\t// semantic conventions. It represents the source address - domain name if\n\t// available without reverse DNS lookup; otherwise, IP address or Unix domain\n\t// socket name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"source.example.com\", \"10.1.2.80\", \"/tmp/my.sock\"\n\t// Note: When observed from the destination side, and when communicating through\n\t// an intermediary, `source.address` SHOULD represent the source address behind\n\t// any intermediaries, for example proxies, if it's available.\n\tSourceAddressKey = attribute.Key(\"source.address\")\n\n\t// SourcePortKey is the attribute Key conforming to the \"source.port\" semantic\n\t// conventions. It represents the source port number.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 3389, 2888\n\tSourcePortKey = attribute.Key(\"source.port\")\n)\n\n// SourceAddress returns an attribute KeyValue conforming to the \"source.address\"\n// semantic conventions. It represents the source address - domain name if\n// available without reverse DNS lookup; otherwise, IP address or Unix domain\n// socket name.\nfunc SourceAddress(val string) attribute.KeyValue {\n\treturn SourceAddressKey.String(val)\n}\n\n// SourcePort returns an attribute KeyValue conforming to the \"source.port\"\n// semantic conventions. It represents the source port number.\nfunc SourcePort(val int) attribute.KeyValue {\n\treturn SourcePortKey.Int(val)\n}\n\n// Namespace: system\nconst (\n\t// SystemDeviceKey is the attribute Key conforming to the \"system.device\"\n\t// semantic conventions. It represents the device identifier.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"(identifier)\"\n\tSystemDeviceKey = attribute.Key(\"system.device\")\n\n\t// SystemFilesystemModeKey is the attribute Key conforming to the\n\t// \"system.filesystem.mode\" semantic conventions. It represents the filesystem\n\t// mode.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"rw, ro\"\n\tSystemFilesystemModeKey = attribute.Key(\"system.filesystem.mode\")\n\n\t// SystemFilesystemMountpointKey is the attribute Key conforming to the\n\t// \"system.filesystem.mountpoint\" semantic conventions. It represents the\n\t// filesystem mount path.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/mnt/data\"\n\tSystemFilesystemMountpointKey = attribute.Key(\"system.filesystem.mountpoint\")\n\n\t// SystemFilesystemStateKey is the attribute Key conforming to the\n\t// \"system.filesystem.state\" semantic conventions. It represents the filesystem\n\t// state.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"used\"\n\tSystemFilesystemStateKey = attribute.Key(\"system.filesystem.state\")\n\n\t// SystemFilesystemTypeKey is the attribute Key conforming to the\n\t// \"system.filesystem.type\" semantic conventions. It represents the filesystem\n\t// type.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"ext4\"\n\tSystemFilesystemTypeKey = attribute.Key(\"system.filesystem.type\")\n\n\t// SystemMemoryLinuxSlabStateKey is the attribute Key conforming to the\n\t// \"system.memory.linux.slab.state\" semantic conventions. It represents the\n\t// Linux Slab memory state.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"reclaimable\", \"unreclaimable\"\n\tSystemMemoryLinuxSlabStateKey = attribute.Key(\"system.memory.linux.slab.state\")\n\n\t// SystemMemoryStateKey is the attribute Key conforming to the\n\t// \"system.memory.state\" semantic conventions. It represents the memory state.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"free\", \"cached\"\n\tSystemMemoryStateKey = attribute.Key(\"system.memory.state\")\n\n\t// SystemPagingDirectionKey is the attribute Key conforming to the\n\t// \"system.paging.direction\" semantic conventions. It represents the paging\n\t// access direction.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"in\"\n\tSystemPagingDirectionKey = attribute.Key(\"system.paging.direction\")\n\n\t// SystemPagingFaultTypeKey is the attribute Key conforming to the\n\t// \"system.paging.fault.type\" semantic conventions. It represents the paging\n\t// fault type.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"minor\"\n\tSystemPagingFaultTypeKey = attribute.Key(\"system.paging.fault.type\")\n\n\t// SystemPagingStateKey is the attribute Key conforming to the\n\t// \"system.paging.state\" semantic conventions. It represents the memory paging\n\t// state.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"free\"\n\tSystemPagingStateKey = attribute.Key(\"system.paging.state\")\n)\n\n// SystemDevice returns an attribute KeyValue conforming to the \"system.device\"\n// semantic conventions. It represents the device identifier.\nfunc SystemDevice(val string) attribute.KeyValue {\n\treturn SystemDeviceKey.String(val)\n}\n\n// SystemFilesystemMode returns an attribute KeyValue conforming to the\n// \"system.filesystem.mode\" semantic conventions. It represents the filesystem\n// mode.\nfunc SystemFilesystemMode(val string) attribute.KeyValue {\n\treturn SystemFilesystemModeKey.String(val)\n}\n\n// SystemFilesystemMountpoint returns an attribute KeyValue conforming to the\n// \"system.filesystem.mountpoint\" semantic conventions. It represents the\n// filesystem mount path.\nfunc SystemFilesystemMountpoint(val string) attribute.KeyValue {\n\treturn SystemFilesystemMountpointKey.String(val)\n}\n\n// Enum values for system.filesystem.state\nvar (\n\t// used\n\t// Stability: development\n\tSystemFilesystemStateUsed = SystemFilesystemStateKey.String(\"used\")\n\t// free\n\t// Stability: development\n\tSystemFilesystemStateFree = SystemFilesystemStateKey.String(\"free\")\n\t// reserved\n\t// Stability: development\n\tSystemFilesystemStateReserved = SystemFilesystemStateKey.String(\"reserved\")\n)\n\n// Enum values for system.filesystem.type\nvar (\n\t// fat32\n\t// Stability: development\n\tSystemFilesystemTypeFat32 = SystemFilesystemTypeKey.String(\"fat32\")\n\t// exfat\n\t// Stability: development\n\tSystemFilesystemTypeExfat = SystemFilesystemTypeKey.String(\"exfat\")\n\t// ntfs\n\t// Stability: development\n\tSystemFilesystemTypeNtfs = SystemFilesystemTypeKey.String(\"ntfs\")\n\t// refs\n\t// Stability: development\n\tSystemFilesystemTypeRefs = SystemFilesystemTypeKey.String(\"refs\")\n\t// hfsplus\n\t// Stability: development\n\tSystemFilesystemTypeHfsplus = SystemFilesystemTypeKey.String(\"hfsplus\")\n\t// ext4\n\t// Stability: development\n\tSystemFilesystemTypeExt4 = SystemFilesystemTypeKey.String(\"ext4\")\n)\n\n// Enum values for system.memory.linux.slab.state\nvar (\n\t// reclaimable\n\t// Stability: development\n\tSystemMemoryLinuxSlabStateReclaimable = SystemMemoryLinuxSlabStateKey.String(\"reclaimable\")\n\t// unreclaimable\n\t// Stability: development\n\tSystemMemoryLinuxSlabStateUnreclaimable = SystemMemoryLinuxSlabStateKey.String(\"unreclaimable\")\n)\n\n// Enum values for system.memory.state\nvar (\n\t// Actual used virtual memory in bytes.\n\t// Stability: development\n\tSystemMemoryStateUsed = SystemMemoryStateKey.String(\"used\")\n\t// free\n\t// Stability: development\n\tSystemMemoryStateFree = SystemMemoryStateKey.String(\"free\")\n\t// buffers\n\t// Stability: development\n\tSystemMemoryStateBuffers = SystemMemoryStateKey.String(\"buffers\")\n\t// cached\n\t// Stability: development\n\tSystemMemoryStateCached = SystemMemoryStateKey.String(\"cached\")\n)\n\n// Enum values for system.paging.direction\nvar (\n\t// in\n\t// Stability: development\n\tSystemPagingDirectionIn = SystemPagingDirectionKey.String(\"in\")\n\t// out\n\t// Stability: development\n\tSystemPagingDirectionOut = SystemPagingDirectionKey.String(\"out\")\n)\n\n// Enum values for system.paging.fault.type\nvar (\n\t// major\n\t// Stability: development\n\tSystemPagingFaultTypeMajor = SystemPagingFaultTypeKey.String(\"major\")\n\t// minor\n\t// Stability: development\n\tSystemPagingFaultTypeMinor = SystemPagingFaultTypeKey.String(\"minor\")\n)\n\n// Enum values for system.paging.state\nvar (\n\t// used\n\t// Stability: development\n\tSystemPagingStateUsed = SystemPagingStateKey.String(\"used\")\n\t// free\n\t// Stability: development\n\tSystemPagingStateFree = SystemPagingStateKey.String(\"free\")\n)\n\n// Namespace: telemetry\nconst (\n\t// TelemetryDistroNameKey is the attribute Key conforming to the\n\t// \"telemetry.distro.name\" semantic conventions. It represents the name of the\n\t// auto instrumentation agent or distribution, if used.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"parts-unlimited-java\"\n\t// Note: Official auto instrumentation agents and distributions SHOULD set the\n\t// `telemetry.distro.name` attribute to\n\t// a string starting with `opentelemetry-`, e.g.\n\t// `opentelemetry-java-instrumentation`.\n\tTelemetryDistroNameKey = attribute.Key(\"telemetry.distro.name\")\n\n\t// TelemetryDistroVersionKey is the attribute Key conforming to the\n\t// \"telemetry.distro.version\" semantic conventions. It represents the version\n\t// string of the auto instrumentation agent or distribution, if used.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1.2.3\"\n\tTelemetryDistroVersionKey = attribute.Key(\"telemetry.distro.version\")\n\n\t// TelemetrySDKLanguageKey is the attribute Key conforming to the\n\t// \"telemetry.sdk.language\" semantic conventions. It represents the language of\n\t// the telemetry SDK.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples:\n\tTelemetrySDKLanguageKey = attribute.Key(\"telemetry.sdk.language\")\n\n\t// TelemetrySDKNameKey is the attribute Key conforming to the\n\t// \"telemetry.sdk.name\" semantic conventions. It represents the name of the\n\t// telemetry SDK as defined above.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"opentelemetry\"\n\t// Note: The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to\n\t// `opentelemetry`.\n\t// If another SDK, like a fork or a vendor-provided implementation, is used,\n\t// this SDK MUST set the\n\t// `telemetry.sdk.name` attribute to the fully-qualified class or module name of\n\t// this SDK's main entry point\n\t// or another suitable identifier depending on the language.\n\t// The identifier `opentelemetry` is reserved and MUST NOT be used in this case.\n\t// All custom identifiers SHOULD be stable across different versions of an\n\t// implementation.\n\tTelemetrySDKNameKey = attribute.Key(\"telemetry.sdk.name\")\n\n\t// TelemetrySDKVersionKey is the attribute Key conforming to the\n\t// \"telemetry.sdk.version\" semantic conventions. It represents the version\n\t// string of the telemetry SDK.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"1.2.3\"\n\tTelemetrySDKVersionKey = attribute.Key(\"telemetry.sdk.version\")\n)\n\n// TelemetryDistroName returns an attribute KeyValue conforming to the\n// \"telemetry.distro.name\" semantic conventions. It represents the name of the\n// auto instrumentation agent or distribution, if used.\nfunc TelemetryDistroName(val string) attribute.KeyValue {\n\treturn TelemetryDistroNameKey.String(val)\n}\n\n// TelemetryDistroVersion returns an attribute KeyValue conforming to the\n// \"telemetry.distro.version\" semantic conventions. It represents the version\n// string of the auto instrumentation agent or distribution, if used.\nfunc TelemetryDistroVersion(val string) attribute.KeyValue {\n\treturn TelemetryDistroVersionKey.String(val)\n}\n\n// TelemetrySDKName returns an attribute KeyValue conforming to the\n// \"telemetry.sdk.name\" semantic conventions. It represents the name of the\n// telemetry SDK as defined above.\nfunc TelemetrySDKName(val string) attribute.KeyValue {\n\treturn TelemetrySDKNameKey.String(val)\n}\n\n// TelemetrySDKVersion returns an attribute KeyValue conforming to the\n// \"telemetry.sdk.version\" semantic conventions. It represents the version string\n// of the telemetry SDK.\nfunc TelemetrySDKVersion(val string) attribute.KeyValue {\n\treturn TelemetrySDKVersionKey.String(val)\n}\n\n// Enum values for telemetry.sdk.language\nvar (\n\t// cpp\n\t// Stability: stable\n\tTelemetrySDKLanguageCPP = TelemetrySDKLanguageKey.String(\"cpp\")\n\t// dotnet\n\t// Stability: stable\n\tTelemetrySDKLanguageDotnet = TelemetrySDKLanguageKey.String(\"dotnet\")\n\t// erlang\n\t// Stability: stable\n\tTelemetrySDKLanguageErlang = TelemetrySDKLanguageKey.String(\"erlang\")\n\t// go\n\t// Stability: stable\n\tTelemetrySDKLanguageGo = TelemetrySDKLanguageKey.String(\"go\")\n\t// java\n\t// Stability: stable\n\tTelemetrySDKLanguageJava = TelemetrySDKLanguageKey.String(\"java\")\n\t// nodejs\n\t// Stability: stable\n\tTelemetrySDKLanguageNodejs = TelemetrySDKLanguageKey.String(\"nodejs\")\n\t// php\n\t// Stability: stable\n\tTelemetrySDKLanguagePHP = TelemetrySDKLanguageKey.String(\"php\")\n\t// python\n\t// Stability: stable\n\tTelemetrySDKLanguagePython = TelemetrySDKLanguageKey.String(\"python\")\n\t// ruby\n\t// Stability: stable\n\tTelemetrySDKLanguageRuby = TelemetrySDKLanguageKey.String(\"ruby\")\n\t// rust\n\t// Stability: stable\n\tTelemetrySDKLanguageRust = TelemetrySDKLanguageKey.String(\"rust\")\n\t// swift\n\t// Stability: stable\n\tTelemetrySDKLanguageSwift = TelemetrySDKLanguageKey.String(\"swift\")\n\t// webjs\n\t// Stability: stable\n\tTelemetrySDKLanguageWebJS = TelemetrySDKLanguageKey.String(\"webjs\")\n)\n\n// Namespace: test\nconst (\n\t// TestCaseNameKey is the attribute Key conforming to the \"test.case.name\"\n\t// semantic conventions. It represents the fully qualified human readable name\n\t// of the [test case].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"org.example.TestCase1.test1\", \"example/tests/TestCase1.test1\",\n\t// \"ExampleTestCase1_test1\"\n\t//\n\t// [test case]: https://wikipedia.org/wiki/Test_case\n\tTestCaseNameKey = attribute.Key(\"test.case.name\")\n\n\t// TestCaseResultStatusKey is the attribute Key conforming to the\n\t// \"test.case.result.status\" semantic conventions. It represents the status of\n\t// the actual test case result from test execution.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"pass\", \"fail\"\n\tTestCaseResultStatusKey = attribute.Key(\"test.case.result.status\")\n\n\t// TestSuiteNameKey is the attribute Key conforming to the \"test.suite.name\"\n\t// semantic conventions. It represents the human readable name of a [test suite]\n\t// .\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"TestSuite1\"\n\t//\n\t// [test suite]: https://wikipedia.org/wiki/Test_suite\n\tTestSuiteNameKey = attribute.Key(\"test.suite.name\")\n\n\t// TestSuiteRunStatusKey is the attribute Key conforming to the\n\t// \"test.suite.run.status\" semantic conventions. It represents the status of the\n\t// test suite run.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"success\", \"failure\", \"skipped\", \"aborted\", \"timed_out\",\n\t// \"in_progress\"\n\tTestSuiteRunStatusKey = attribute.Key(\"test.suite.run.status\")\n)\n\n// TestCaseName returns an attribute KeyValue conforming to the \"test.case.name\"\n// semantic conventions. It represents the fully qualified human readable name of\n// the [test case].\n//\n// [test case]: https://wikipedia.org/wiki/Test_case\nfunc TestCaseName(val string) attribute.KeyValue {\n\treturn TestCaseNameKey.String(val)\n}\n\n// TestSuiteName returns an attribute KeyValue conforming to the\n// \"test.suite.name\" semantic conventions. It represents the human readable name\n// of a [test suite].\n//\n// [test suite]: https://wikipedia.org/wiki/Test_suite\nfunc TestSuiteName(val string) attribute.KeyValue {\n\treturn TestSuiteNameKey.String(val)\n}\n\n// Enum values for test.case.result.status\nvar (\n\t// pass\n\t// Stability: development\n\tTestCaseResultStatusPass = TestCaseResultStatusKey.String(\"pass\")\n\t// fail\n\t// Stability: development\n\tTestCaseResultStatusFail = TestCaseResultStatusKey.String(\"fail\")\n)\n\n// Enum values for test.suite.run.status\nvar (\n\t// success\n\t// Stability: development\n\tTestSuiteRunStatusSuccess = TestSuiteRunStatusKey.String(\"success\")\n\t// failure\n\t// Stability: development\n\tTestSuiteRunStatusFailure = TestSuiteRunStatusKey.String(\"failure\")\n\t// skipped\n\t// Stability: development\n\tTestSuiteRunStatusSkipped = TestSuiteRunStatusKey.String(\"skipped\")\n\t// aborted\n\t// Stability: development\n\tTestSuiteRunStatusAborted = TestSuiteRunStatusKey.String(\"aborted\")\n\t// timed_out\n\t// Stability: development\n\tTestSuiteRunStatusTimedOut = TestSuiteRunStatusKey.String(\"timed_out\")\n\t// in_progress\n\t// Stability: development\n\tTestSuiteRunStatusInProgress = TestSuiteRunStatusKey.String(\"in_progress\")\n)\n\n// Namespace: thread\nconst (\n\t// ThreadIDKey is the attribute Key conforming to the \"thread.id\" semantic\n\t// conventions. It represents the current \"managed\" thread ID (as opposed to OS\n\t// thread ID).\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Note:\n\t// Examples of where the value can be extracted from:\n\t//\n\t// | Language or platform | Source |\n\t// | --- | --- |\n\t// | JVM | `Thread.currentThread().threadId()` |\n\t// | .NET | `Thread.CurrentThread.ManagedThreadId` |\n\t// | Python | `threading.current_thread().ident` |\n\t// | Ruby | `Thread.current.object_id` |\n\t// | C++ | `std::this_thread::get_id()` |\n\t// | Erlang | `erlang:self()` |\n\tThreadIDKey = attribute.Key(\"thread.id\")\n\n\t// ThreadNameKey is the attribute Key conforming to the \"thread.name\" semantic\n\t// conventions. It represents the current thread name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: main\n\t// Note:\n\t// Examples of where the value can be extracted from:\n\t//\n\t// | Language or platform | Source |\n\t// | --- | --- |\n\t// | JVM | `Thread.currentThread().getName()` |\n\t// | .NET | `Thread.CurrentThread.Name` |\n\t// | Python | `threading.current_thread().name` |\n\t// | Ruby | `Thread.current.name` |\n\t// | Erlang | `erlang:process_info(self(), registered_name)` |\n\tThreadNameKey = attribute.Key(\"thread.name\")\n)\n\n// ThreadID returns an attribute KeyValue conforming to the \"thread.id\" semantic\n// conventions. It represents the current \"managed\" thread ID (as opposed to OS\n// thread ID).\nfunc ThreadID(val int) attribute.KeyValue {\n\treturn ThreadIDKey.Int(val)\n}\n\n// ThreadName returns an attribute KeyValue conforming to the \"thread.name\"\n// semantic conventions. It represents the current thread name.\nfunc ThreadName(val string) attribute.KeyValue {\n\treturn ThreadNameKey.String(val)\n}\n\n// Namespace: tls\nconst (\n\t// TLSCipherKey is the attribute Key conforming to the \"tls.cipher\" semantic\n\t// conventions. It represents the string indicating the [cipher] used during the\n\t// current connection.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"TLS_RSA_WITH_3DES_EDE_CBC_SHA\",\n\t// \"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256\"\n\t// Note: The values allowed for `tls.cipher` MUST be one of the `Descriptions`\n\t// of the [registered TLS Cipher Suits].\n\t//\n\t// [cipher]: https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5\n\t// [registered TLS Cipher Suits]: https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#table-tls-parameters-4\n\tTLSCipherKey = attribute.Key(\"tls.cipher\")\n\n\t// TLSClientCertificateKey is the attribute Key conforming to the\n\t// \"tls.client.certificate\" semantic conventions. It represents the PEM-encoded\n\t// stand-alone certificate offered by the client. This is usually\n\t// mutually-exclusive of `client.certificate_chain` since this value also exists\n\t// in that list.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"MII...\"\n\tTLSClientCertificateKey = attribute.Key(\"tls.client.certificate\")\n\n\t// TLSClientCertificateChainKey is the attribute Key conforming to the\n\t// \"tls.client.certificate_chain\" semantic conventions. It represents the array\n\t// of PEM-encoded certificates that make up the certificate chain offered by the\n\t// client. This is usually mutually-exclusive of `client.certificate` since that\n\t// value should be the first certificate in the chain.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"MII...\", \"MI...\"\n\tTLSClientCertificateChainKey = attribute.Key(\"tls.client.certificate_chain\")\n\n\t// TLSClientHashMd5Key is the attribute Key conforming to the\n\t// \"tls.client.hash.md5\" semantic conventions. It represents the certificate\n\t// fingerprint using the MD5 digest of DER-encoded version of certificate\n\t// offered by the client. For consistency with other hash values, this value\n\t// should be formatted as an uppercase hash.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC\"\n\tTLSClientHashMd5Key = attribute.Key(\"tls.client.hash.md5\")\n\n\t// TLSClientHashSha1Key is the attribute Key conforming to the\n\t// \"tls.client.hash.sha1\" semantic conventions. It represents the certificate\n\t// fingerprint using the SHA1 digest of DER-encoded version of certificate\n\t// offered by the client. For consistency with other hash values, this value\n\t// should be formatted as an uppercase hash.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"9E393D93138888D288266C2D915214D1D1CCEB2A\"\n\tTLSClientHashSha1Key = attribute.Key(\"tls.client.hash.sha1\")\n\n\t// TLSClientHashSha256Key is the attribute Key conforming to the\n\t// \"tls.client.hash.sha256\" semantic conventions. It represents the certificate\n\t// fingerprint using the SHA256 digest of DER-encoded version of certificate\n\t// offered by the client. For consistency with other hash values, this value\n\t// should be formatted as an uppercase hash.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0\"\n\tTLSClientHashSha256Key = attribute.Key(\"tls.client.hash.sha256\")\n\n\t// TLSClientIssuerKey is the attribute Key conforming to the \"tls.client.issuer\"\n\t// semantic conventions. It represents the distinguished name of [subject] of\n\t// the issuer of the x.509 certificate presented by the client.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com\"\n\t//\n\t// [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6\n\tTLSClientIssuerKey = attribute.Key(\"tls.client.issuer\")\n\n\t// TLSClientJa3Key is the attribute Key conforming to the \"tls.client.ja3\"\n\t// semantic conventions. It represents a hash that identifies clients based on\n\t// how they perform an SSL/TLS handshake.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"d4e5b18d6b55c71272893221c96ba240\"\n\tTLSClientJa3Key = attribute.Key(\"tls.client.ja3\")\n\n\t// TLSClientNotAfterKey is the attribute Key conforming to the\n\t// \"tls.client.not_after\" semantic conventions. It represents the date/Time\n\t// indicating when client certificate is no longer considered valid.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2021-01-01T00:00:00.000Z\"\n\tTLSClientNotAfterKey = attribute.Key(\"tls.client.not_after\")\n\n\t// TLSClientNotBeforeKey is the attribute Key conforming to the\n\t// \"tls.client.not_before\" semantic conventions. It represents the date/Time\n\t// indicating when client certificate is first considered valid.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1970-01-01T00:00:00.000Z\"\n\tTLSClientNotBeforeKey = attribute.Key(\"tls.client.not_before\")\n\n\t// TLSClientSubjectKey is the attribute Key conforming to the\n\t// \"tls.client.subject\" semantic conventions. It represents the distinguished\n\t// name of subject of the x.509 certificate presented by the client.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"CN=myclient, OU=Documentation Team, DC=example, DC=com\"\n\tTLSClientSubjectKey = attribute.Key(\"tls.client.subject\")\n\n\t// TLSClientSupportedCiphersKey is the attribute Key conforming to the\n\t// \"tls.client.supported_ciphers\" semantic conventions. It represents the array\n\t// of ciphers offered by the client during the client hello.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\",\n\t// \"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\"\n\tTLSClientSupportedCiphersKey = attribute.Key(\"tls.client.supported_ciphers\")\n\n\t// TLSCurveKey is the attribute Key conforming to the \"tls.curve\" semantic\n\t// conventions. It represents the string indicating the curve used for the given\n\t// cipher, when applicable.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"secp256r1\"\n\tTLSCurveKey = attribute.Key(\"tls.curve\")\n\n\t// TLSEstablishedKey is the attribute Key conforming to the \"tls.established\"\n\t// semantic conventions. It represents the boolean flag indicating if the TLS\n\t// negotiation was successful and transitioned to an encrypted tunnel.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: true\n\tTLSEstablishedKey = attribute.Key(\"tls.established\")\n\n\t// TLSNextProtocolKey is the attribute Key conforming to the \"tls.next_protocol\"\n\t// semantic conventions. It represents the string indicating the protocol being\n\t// tunneled. Per the values in the [IANA registry], this string should be lower\n\t// case.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"http/1.1\"\n\t//\n\t// [IANA registry]: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids\n\tTLSNextProtocolKey = attribute.Key(\"tls.next_protocol\")\n\n\t// TLSProtocolNameKey is the attribute Key conforming to the \"tls.protocol.name\"\n\t// semantic conventions. It represents the normalized lowercase protocol name\n\t// parsed from original string of the negotiated [SSL/TLS protocol version].\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t//\n\t// [SSL/TLS protocol version]: https://docs.openssl.org/1.1.1/man3/SSL_get_version/#return-values\n\tTLSProtocolNameKey = attribute.Key(\"tls.protocol.name\")\n\n\t// TLSProtocolVersionKey is the attribute Key conforming to the\n\t// \"tls.protocol.version\" semantic conventions. It represents the numeric part\n\t// of the version parsed from the original string of the negotiated\n\t// [SSL/TLS protocol version].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1.2\", \"3\"\n\t//\n\t// [SSL/TLS protocol version]: https://docs.openssl.org/1.1.1/man3/SSL_get_version/#return-values\n\tTLSProtocolVersionKey = attribute.Key(\"tls.protocol.version\")\n\n\t// TLSResumedKey is the attribute Key conforming to the \"tls.resumed\" semantic\n\t// conventions. It represents the boolean flag indicating if this TLS connection\n\t// was resumed from an existing TLS negotiation.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: true\n\tTLSResumedKey = attribute.Key(\"tls.resumed\")\n\n\t// TLSServerCertificateKey is the attribute Key conforming to the\n\t// \"tls.server.certificate\" semantic conventions. It represents the PEM-encoded\n\t// stand-alone certificate offered by the server. This is usually\n\t// mutually-exclusive of `server.certificate_chain` since this value also exists\n\t// in that list.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"MII...\"\n\tTLSServerCertificateKey = attribute.Key(\"tls.server.certificate\")\n\n\t// TLSServerCertificateChainKey is the attribute Key conforming to the\n\t// \"tls.server.certificate_chain\" semantic conventions. It represents the array\n\t// of PEM-encoded certificates that make up the certificate chain offered by the\n\t// server. This is usually mutually-exclusive of `server.certificate` since that\n\t// value should be the first certificate in the chain.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"MII...\", \"MI...\"\n\tTLSServerCertificateChainKey = attribute.Key(\"tls.server.certificate_chain\")\n\n\t// TLSServerHashMd5Key is the attribute Key conforming to the\n\t// \"tls.server.hash.md5\" semantic conventions. It represents the certificate\n\t// fingerprint using the MD5 digest of DER-encoded version of certificate\n\t// offered by the server. For consistency with other hash values, this value\n\t// should be formatted as an uppercase hash.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"0F76C7F2C55BFD7D8E8B8F4BFBF0C9EC\"\n\tTLSServerHashMd5Key = attribute.Key(\"tls.server.hash.md5\")\n\n\t// TLSServerHashSha1Key is the attribute Key conforming to the\n\t// \"tls.server.hash.sha1\" semantic conventions. It represents the certificate\n\t// fingerprint using the SHA1 digest of DER-encoded version of certificate\n\t// offered by the server. For consistency with other hash values, this value\n\t// should be formatted as an uppercase hash.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"9E393D93138888D288266C2D915214D1D1CCEB2A\"\n\tTLSServerHashSha1Key = attribute.Key(\"tls.server.hash.sha1\")\n\n\t// TLSServerHashSha256Key is the attribute Key conforming to the\n\t// \"tls.server.hash.sha256\" semantic conventions. It represents the certificate\n\t// fingerprint using the SHA256 digest of DER-encoded version of certificate\n\t// offered by the server. For consistency with other hash values, this value\n\t// should be formatted as an uppercase hash.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"0687F666A054EF17A08E2F2162EAB4CBC0D265E1D7875BE74BF3C712CA92DAF0\"\n\tTLSServerHashSha256Key = attribute.Key(\"tls.server.hash.sha256\")\n\n\t// TLSServerIssuerKey is the attribute Key conforming to the \"tls.server.issuer\"\n\t// semantic conventions. It represents the distinguished name of [subject] of\n\t// the issuer of the x.509 certificate presented by the client.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"CN=Example Root CA, OU=Infrastructure Team, DC=example, DC=com\"\n\t//\n\t// [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6\n\tTLSServerIssuerKey = attribute.Key(\"tls.server.issuer\")\n\n\t// TLSServerJa3sKey is the attribute Key conforming to the \"tls.server.ja3s\"\n\t// semantic conventions. It represents a hash that identifies servers based on\n\t// how they perform an SSL/TLS handshake.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"d4e5b18d6b55c71272893221c96ba240\"\n\tTLSServerJa3sKey = attribute.Key(\"tls.server.ja3s\")\n\n\t// TLSServerNotAfterKey is the attribute Key conforming to the\n\t// \"tls.server.not_after\" semantic conventions. It represents the date/Time\n\t// indicating when server certificate is no longer considered valid.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"2021-01-01T00:00:00.000Z\"\n\tTLSServerNotAfterKey = attribute.Key(\"tls.server.not_after\")\n\n\t// TLSServerNotBeforeKey is the attribute Key conforming to the\n\t// \"tls.server.not_before\" semantic conventions. It represents the date/Time\n\t// indicating when server certificate is first considered valid.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"1970-01-01T00:00:00.000Z\"\n\tTLSServerNotBeforeKey = attribute.Key(\"tls.server.not_before\")\n\n\t// TLSServerSubjectKey is the attribute Key conforming to the\n\t// \"tls.server.subject\" semantic conventions. It represents the distinguished\n\t// name of subject of the x.509 certificate presented by the server.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"CN=myserver, OU=Documentation Team, DC=example, DC=com\"\n\tTLSServerSubjectKey = attribute.Key(\"tls.server.subject\")\n)\n\n// TLSCipher returns an attribute KeyValue conforming to the \"tls.cipher\"\n// semantic conventions. It represents the string indicating the [cipher] used\n// during the current connection.\n//\n// [cipher]: https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5\nfunc TLSCipher(val string) attribute.KeyValue {\n\treturn TLSCipherKey.String(val)\n}\n\n// TLSClientCertificate returns an attribute KeyValue conforming to the\n// \"tls.client.certificate\" semantic conventions. It represents the PEM-encoded\n// stand-alone certificate offered by the client. This is usually\n// mutually-exclusive of `client.certificate_chain` since this value also exists\n// in that list.\nfunc TLSClientCertificate(val string) attribute.KeyValue {\n\treturn TLSClientCertificateKey.String(val)\n}\n\n// TLSClientCertificateChain returns an attribute KeyValue conforming to the\n// \"tls.client.certificate_chain\" semantic conventions. It represents the array\n// of PEM-encoded certificates that make up the certificate chain offered by the\n// client. This is usually mutually-exclusive of `client.certificate` since that\n// value should be the first certificate in the chain.\nfunc TLSClientCertificateChain(val ...string) attribute.KeyValue {\n\treturn TLSClientCertificateChainKey.StringSlice(val)\n}\n\n// TLSClientHashMd5 returns an attribute KeyValue conforming to the\n// \"tls.client.hash.md5\" semantic conventions. It represents the certificate\n// fingerprint using the MD5 digest of DER-encoded version of certificate offered\n// by the client. For consistency with other hash values, this value should be\n// formatted as an uppercase hash.\nfunc TLSClientHashMd5(val string) attribute.KeyValue {\n\treturn TLSClientHashMd5Key.String(val)\n}\n\n// TLSClientHashSha1 returns an attribute KeyValue conforming to the\n// \"tls.client.hash.sha1\" semantic conventions. It represents the certificate\n// fingerprint using the SHA1 digest of DER-encoded version of certificate\n// offered by the client. For consistency with other hash values, this value\n// should be formatted as an uppercase hash.\nfunc TLSClientHashSha1(val string) attribute.KeyValue {\n\treturn TLSClientHashSha1Key.String(val)\n}\n\n// TLSClientHashSha256 returns an attribute KeyValue conforming to the\n// \"tls.client.hash.sha256\" semantic conventions. It represents the certificate\n// fingerprint using the SHA256 digest of DER-encoded version of certificate\n// offered by the client. For consistency with other hash values, this value\n// should be formatted as an uppercase hash.\nfunc TLSClientHashSha256(val string) attribute.KeyValue {\n\treturn TLSClientHashSha256Key.String(val)\n}\n\n// TLSClientIssuer returns an attribute KeyValue conforming to the\n// \"tls.client.issuer\" semantic conventions. It represents the distinguished name\n// of [subject] of the issuer of the x.509 certificate presented by the client.\n//\n// [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6\nfunc TLSClientIssuer(val string) attribute.KeyValue {\n\treturn TLSClientIssuerKey.String(val)\n}\n\n// TLSClientJa3 returns an attribute KeyValue conforming to the \"tls.client.ja3\"\n// semantic conventions. It represents a hash that identifies clients based on\n// how they perform an SSL/TLS handshake.\nfunc TLSClientJa3(val string) attribute.KeyValue {\n\treturn TLSClientJa3Key.String(val)\n}\n\n// TLSClientNotAfter returns an attribute KeyValue conforming to the\n// \"tls.client.not_after\" semantic conventions. It represents the date/Time\n// indicating when client certificate is no longer considered valid.\nfunc TLSClientNotAfter(val string) attribute.KeyValue {\n\treturn TLSClientNotAfterKey.String(val)\n}\n\n// TLSClientNotBefore returns an attribute KeyValue conforming to the\n// \"tls.client.not_before\" semantic conventions. It represents the date/Time\n// indicating when client certificate is first considered valid.\nfunc TLSClientNotBefore(val string) attribute.KeyValue {\n\treturn TLSClientNotBeforeKey.String(val)\n}\n\n// TLSClientSubject returns an attribute KeyValue conforming to the\n// \"tls.client.subject\" semantic conventions. It represents the distinguished\n// name of subject of the x.509 certificate presented by the client.\nfunc TLSClientSubject(val string) attribute.KeyValue {\n\treturn TLSClientSubjectKey.String(val)\n}\n\n// TLSClientSupportedCiphers returns an attribute KeyValue conforming to the\n// \"tls.client.supported_ciphers\" semantic conventions. It represents the array\n// of ciphers offered by the client during the client hello.\nfunc TLSClientSupportedCiphers(val ...string) attribute.KeyValue {\n\treturn TLSClientSupportedCiphersKey.StringSlice(val)\n}\n\n// TLSCurve returns an attribute KeyValue conforming to the \"tls.curve\" semantic\n// conventions. It represents the string indicating the curve used for the given\n// cipher, when applicable.\nfunc TLSCurve(val string) attribute.KeyValue {\n\treturn TLSCurveKey.String(val)\n}\n\n// TLSEstablished returns an attribute KeyValue conforming to the\n// \"tls.established\" semantic conventions. It represents the boolean flag\n// indicating if the TLS negotiation was successful and transitioned to an\n// encrypted tunnel.\nfunc TLSEstablished(val bool) attribute.KeyValue {\n\treturn TLSEstablishedKey.Bool(val)\n}\n\n// TLSNextProtocol returns an attribute KeyValue conforming to the\n// \"tls.next_protocol\" semantic conventions. It represents the string indicating\n// the protocol being tunneled. Per the values in the [IANA registry], this\n// string should be lower case.\n//\n// [IANA registry]: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids\nfunc TLSNextProtocol(val string) attribute.KeyValue {\n\treturn TLSNextProtocolKey.String(val)\n}\n\n// TLSProtocolVersion returns an attribute KeyValue conforming to the\n// \"tls.protocol.version\" semantic conventions. It represents the numeric part of\n// the version parsed from the original string of the negotiated\n// [SSL/TLS protocol version].\n//\n// [SSL/TLS protocol version]: https://docs.openssl.org/1.1.1/man3/SSL_get_version/#return-values\nfunc TLSProtocolVersion(val string) attribute.KeyValue {\n\treturn TLSProtocolVersionKey.String(val)\n}\n\n// TLSResumed returns an attribute KeyValue conforming to the \"tls.resumed\"\n// semantic conventions. It represents the boolean flag indicating if this TLS\n// connection was resumed from an existing TLS negotiation.\nfunc TLSResumed(val bool) attribute.KeyValue {\n\treturn TLSResumedKey.Bool(val)\n}\n\n// TLSServerCertificate returns an attribute KeyValue conforming to the\n// \"tls.server.certificate\" semantic conventions. It represents the PEM-encoded\n// stand-alone certificate offered by the server. This is usually\n// mutually-exclusive of `server.certificate_chain` since this value also exists\n// in that list.\nfunc TLSServerCertificate(val string) attribute.KeyValue {\n\treturn TLSServerCertificateKey.String(val)\n}\n\n// TLSServerCertificateChain returns an attribute KeyValue conforming to the\n// \"tls.server.certificate_chain\" semantic conventions. It represents the array\n// of PEM-encoded certificates that make up the certificate chain offered by the\n// server. This is usually mutually-exclusive of `server.certificate` since that\n// value should be the first certificate in the chain.\nfunc TLSServerCertificateChain(val ...string) attribute.KeyValue {\n\treturn TLSServerCertificateChainKey.StringSlice(val)\n}\n\n// TLSServerHashMd5 returns an attribute KeyValue conforming to the\n// \"tls.server.hash.md5\" semantic conventions. It represents the certificate\n// fingerprint using the MD5 digest of DER-encoded version of certificate offered\n// by the server. For consistency with other hash values, this value should be\n// formatted as an uppercase hash.\nfunc TLSServerHashMd5(val string) attribute.KeyValue {\n\treturn TLSServerHashMd5Key.String(val)\n}\n\n// TLSServerHashSha1 returns an attribute KeyValue conforming to the\n// \"tls.server.hash.sha1\" semantic conventions. It represents the certificate\n// fingerprint using the SHA1 digest of DER-encoded version of certificate\n// offered by the server. For consistency with other hash values, this value\n// should be formatted as an uppercase hash.\nfunc TLSServerHashSha1(val string) attribute.KeyValue {\n\treturn TLSServerHashSha1Key.String(val)\n}\n\n// TLSServerHashSha256 returns an attribute KeyValue conforming to the\n// \"tls.server.hash.sha256\" semantic conventions. It represents the certificate\n// fingerprint using the SHA256 digest of DER-encoded version of certificate\n// offered by the server. For consistency with other hash values, this value\n// should be formatted as an uppercase hash.\nfunc TLSServerHashSha256(val string) attribute.KeyValue {\n\treturn TLSServerHashSha256Key.String(val)\n}\n\n// TLSServerIssuer returns an attribute KeyValue conforming to the\n// \"tls.server.issuer\" semantic conventions. It represents the distinguished name\n// of [subject] of the issuer of the x.509 certificate presented by the client.\n//\n// [subject]: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6\nfunc TLSServerIssuer(val string) attribute.KeyValue {\n\treturn TLSServerIssuerKey.String(val)\n}\n\n// TLSServerJa3s returns an attribute KeyValue conforming to the\n// \"tls.server.ja3s\" semantic conventions. It represents a hash that identifies\n// servers based on how they perform an SSL/TLS handshake.\nfunc TLSServerJa3s(val string) attribute.KeyValue {\n\treturn TLSServerJa3sKey.String(val)\n}\n\n// TLSServerNotAfter returns an attribute KeyValue conforming to the\n// \"tls.server.not_after\" semantic conventions. It represents the date/Time\n// indicating when server certificate is no longer considered valid.\nfunc TLSServerNotAfter(val string) attribute.KeyValue {\n\treturn TLSServerNotAfterKey.String(val)\n}\n\n// TLSServerNotBefore returns an attribute KeyValue conforming to the\n// \"tls.server.not_before\" semantic conventions. It represents the date/Time\n// indicating when server certificate is first considered valid.\nfunc TLSServerNotBefore(val string) attribute.KeyValue {\n\treturn TLSServerNotBeforeKey.String(val)\n}\n\n// TLSServerSubject returns an attribute KeyValue conforming to the\n// \"tls.server.subject\" semantic conventions. It represents the distinguished\n// name of subject of the x.509 certificate presented by the server.\nfunc TLSServerSubject(val string) attribute.KeyValue {\n\treturn TLSServerSubjectKey.String(val)\n}\n\n// Enum values for tls.protocol.name\nvar (\n\t// ssl\n\t// Stability: development\n\tTLSProtocolNameSsl = TLSProtocolNameKey.String(\"ssl\")\n\t// tls\n\t// Stability: development\n\tTLSProtocolNameTLS = TLSProtocolNameKey.String(\"tls\")\n)\n\n// Namespace: url\nconst (\n\t// URLDomainKey is the attribute Key conforming to the \"url.domain\" semantic\n\t// conventions. It represents the domain extracted from the `url.full`, such as\n\t// \"opentelemetry.io\".\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"www.foo.bar\", \"opentelemetry.io\", \"3.12.167.2\",\n\t// \"[1080:0:0:0:8:800:200C:417A]\"\n\t// Note: In some cases a URL may refer to an IP and/or port directly, without a\n\t// domain name. In this case, the IP address would go to the domain field. If\n\t// the URL contains a [literal IPv6 address] enclosed by `[` and `]`, the `[`\n\t// and `]` characters should also be captured in the domain field.\n\t//\n\t// [literal IPv6 address]: https://www.rfc-editor.org/rfc/rfc2732#section-2\n\tURLDomainKey = attribute.Key(\"url.domain\")\n\n\t// URLExtensionKey is the attribute Key conforming to the \"url.extension\"\n\t// semantic conventions. It represents the file extension extracted from the\n\t// `url.full`, excluding the leading dot.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"png\", \"gz\"\n\t// Note: The file extension is only set if it exists, as not every url has a\n\t// file extension. When the file name has multiple extensions `example.tar.gz`,\n\t// only the last one should be captured `gz`, not `tar.gz`.\n\tURLExtensionKey = attribute.Key(\"url.extension\")\n\n\t// URLFragmentKey is the attribute Key conforming to the \"url.fragment\" semantic\n\t// conventions. It represents the [URI fragment] component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"SemConv\"\n\t//\n\t// [URI fragment]: https://www.rfc-editor.org/rfc/rfc3986#section-3.5\n\tURLFragmentKey = attribute.Key(\"url.fragment\")\n\n\t// URLFullKey is the attribute Key conforming to the \"url.full\" semantic\n\t// conventions. It represents the absolute URL describing a network resource\n\t// according to [RFC3986].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"https://www.foo.bar/search?q=OpenTelemetry#SemConv\", \"//localhost\"\n\t// Note: For network calls, URL usually has\n\t// `scheme://host[:port][path][?query][#fragment]` format, where the fragment\n\t// is not transmitted over HTTP, but if it is known, it SHOULD be included\n\t// nevertheless.\n\t//\n\t// `url.full` MUST NOT contain credentials passed via URL in form of\n\t// `https://username:password@www.example.com/`.\n\t// In such case username and password SHOULD be redacted and attribute's value\n\t// SHOULD be `https://REDACTED:REDACTED@www.example.com/`.\n\t//\n\t// `url.full` SHOULD capture the absolute URL when it is available (or can be\n\t// reconstructed).\n\t//\n\t// Sensitive content provided in `url.full` SHOULD be scrubbed when\n\t// instrumentations can identify it.\n\t//\n\t//\n\t// Query string values for the following keys SHOULD be redacted by default and\n\t// replaced by the\n\t// value `REDACTED`:\n\t//\n\t//   - [`AWSAccessKeyId`]\n\t//   - [`Signature`]\n\t//   - [`sig`]\n\t//   - [`X-Goog-Signature`]\n\t//\n\t// This list is subject to change over time.\n\t//\n\t// When a query string value is redacted, the query string key SHOULD still be\n\t// preserved, e.g.\n\t// `https://www.example.com/path?color=blue&sig=REDACTED`.\n\t//\n\t// [RFC3986]: https://www.rfc-editor.org/rfc/rfc3986\n\t// [`AWSAccessKeyId`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth\n\t// [`Signature`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth\n\t// [`sig`]: https://learn.microsoft.com/azure/storage/common/storage-sas-overview#sas-token\n\t// [`X-Goog-Signature`]: https://cloud.google.com/storage/docs/access-control/signed-urls\n\tURLFullKey = attribute.Key(\"url.full\")\n\n\t// URLOriginalKey is the attribute Key conforming to the \"url.original\" semantic\n\t// conventions. It represents the unmodified original URL as seen in the event\n\t// source.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"https://www.foo.bar/search?q=OpenTelemetry#SemConv\",\n\t// \"search?q=OpenTelemetry\"\n\t// Note: In network monitoring, the observed URL may be a full URL, whereas in\n\t// access logs, the URL is often just represented as a path. This field is meant\n\t// to represent the URL as it was observed, complete or not.\n\t// `url.original` might contain credentials passed via URL in form of\n\t// `https://username:password@www.example.com/`. In such case password and\n\t// username SHOULD NOT be redacted and attribute's value SHOULD remain the same.\n\tURLOriginalKey = attribute.Key(\"url.original\")\n\n\t// URLPathKey is the attribute Key conforming to the \"url.path\" semantic\n\t// conventions. It represents the [URI path] component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"/search\"\n\t// Note: Sensitive content provided in `url.path` SHOULD be scrubbed when\n\t// instrumentations can identify it.\n\t//\n\t// [URI path]: https://www.rfc-editor.org/rfc/rfc3986#section-3.3\n\tURLPathKey = attribute.Key(\"url.path\")\n\n\t// URLPortKey is the attribute Key conforming to the \"url.port\" semantic\n\t// conventions. It represents the port extracted from the `url.full`.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: 443\n\tURLPortKey = attribute.Key(\"url.port\")\n\n\t// URLQueryKey is the attribute Key conforming to the \"url.query\" semantic\n\t// conventions. It represents the [URI query] component.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"q=OpenTelemetry\"\n\t// Note: Sensitive content provided in `url.query` SHOULD be scrubbed when\n\t// instrumentations can identify it.\n\t//\n\t//\n\t// Query string values for the following keys SHOULD be redacted by default and\n\t// replaced by the value `REDACTED`:\n\t//\n\t//   - [`AWSAccessKeyId`]\n\t//   - [`Signature`]\n\t//   - [`sig`]\n\t//   - [`X-Goog-Signature`]\n\t//\n\t// This list is subject to change over time.\n\t//\n\t// When a query string value is redacted, the query string key SHOULD still be\n\t// preserved, e.g.\n\t// `q=OpenTelemetry&sig=REDACTED`.\n\t//\n\t// [URI query]: https://www.rfc-editor.org/rfc/rfc3986#section-3.4\n\t// [`AWSAccessKeyId`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth\n\t// [`Signature`]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html#RESTAuthenticationQueryStringAuth\n\t// [`sig`]: https://learn.microsoft.com/azure/storage/common/storage-sas-overview#sas-token\n\t// [`X-Goog-Signature`]: https://cloud.google.com/storage/docs/access-control/signed-urls\n\tURLQueryKey = attribute.Key(\"url.query\")\n\n\t// URLRegisteredDomainKey is the attribute Key conforming to the\n\t// \"url.registered_domain\" semantic conventions. It represents the highest\n\t// registered url domain, stripped of the subdomain.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"example.com\", \"foo.co.uk\"\n\t// Note: This value can be determined precisely with the [public suffix list].\n\t// For example, the registered domain for `foo.example.com` is `example.com`.\n\t// Trying to approximate this by simply taking the last two labels will not work\n\t// well for TLDs such as `co.uk`.\n\t//\n\t// [public suffix list]: https://publicsuffix.org/\n\tURLRegisteredDomainKey = attribute.Key(\"url.registered_domain\")\n\n\t// URLSchemeKey is the attribute Key conforming to the \"url.scheme\" semantic\n\t// conventions. It represents the [URI scheme] component identifying the used\n\t// protocol.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"https\", \"ftp\", \"telnet\"\n\t//\n\t// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1\n\tURLSchemeKey = attribute.Key(\"url.scheme\")\n\n\t// URLSubdomainKey is the attribute Key conforming to the \"url.subdomain\"\n\t// semantic conventions. It represents the subdomain portion of a fully\n\t// qualified domain name includes all of the names except the host name under\n\t// the registered_domain. In a partially qualified domain, or if the\n\t// qualification level of the full name cannot be determined, subdomain contains\n\t// all of the names below the registered domain.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"east\", \"sub2.sub1\"\n\t// Note: The subdomain portion of `www.east.mydomain.co.uk` is `east`. If the\n\t// domain has multiple levels of subdomain, such as `sub2.sub1.example.com`, the\n\t// subdomain field should contain `sub2.sub1`, with no trailing period.\n\tURLSubdomainKey = attribute.Key(\"url.subdomain\")\n\n\t// URLTemplateKey is the attribute Key conforming to the \"url.template\" semantic\n\t// conventions. It represents the low-cardinality template of an\n\t// [absolute path reference].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"/users/{id}\", \"/users/:id\", \"/users?id={id}\"\n\t//\n\t// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2\n\tURLTemplateKey = attribute.Key(\"url.template\")\n\n\t// URLTopLevelDomainKey is the attribute Key conforming to the\n\t// \"url.top_level_domain\" semantic conventions. It represents the effective top\n\t// level domain (eTLD), also known as the domain suffix, is the last part of the\n\t// domain name. For example, the top level domain for example.com is `com`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"com\", \"co.uk\"\n\t// Note: This value can be determined precisely with the [public suffix list].\n\t//\n\t// [public suffix list]: https://publicsuffix.org/\n\tURLTopLevelDomainKey = attribute.Key(\"url.top_level_domain\")\n)\n\n// URLDomain returns an attribute KeyValue conforming to the \"url.domain\"\n// semantic conventions. It represents the domain extracted from the `url.full`,\n// such as \"opentelemetry.io\".\nfunc URLDomain(val string) attribute.KeyValue {\n\treturn URLDomainKey.String(val)\n}\n\n// URLExtension returns an attribute KeyValue conforming to the \"url.extension\"\n// semantic conventions. It represents the file extension extracted from the\n// `url.full`, excluding the leading dot.\nfunc URLExtension(val string) attribute.KeyValue {\n\treturn URLExtensionKey.String(val)\n}\n\n// URLFragment returns an attribute KeyValue conforming to the \"url.fragment\"\n// semantic conventions. It represents the [URI fragment] component.\n//\n// [URI fragment]: https://www.rfc-editor.org/rfc/rfc3986#section-3.5\nfunc URLFragment(val string) attribute.KeyValue {\n\treturn URLFragmentKey.String(val)\n}\n\n// URLFull returns an attribute KeyValue conforming to the \"url.full\" semantic\n// conventions. It represents the absolute URL describing a network resource\n// according to [RFC3986].\n//\n// [RFC3986]: https://www.rfc-editor.org/rfc/rfc3986\nfunc URLFull(val string) attribute.KeyValue {\n\treturn URLFullKey.String(val)\n}\n\n// URLOriginal returns an attribute KeyValue conforming to the \"url.original\"\n// semantic conventions. It represents the unmodified original URL as seen in the\n// event source.\nfunc URLOriginal(val string) attribute.KeyValue {\n\treturn URLOriginalKey.String(val)\n}\n\n// URLPath returns an attribute KeyValue conforming to the \"url.path\" semantic\n// conventions. It represents the [URI path] component.\n//\n// [URI path]: https://www.rfc-editor.org/rfc/rfc3986#section-3.3\nfunc URLPath(val string) attribute.KeyValue {\n\treturn URLPathKey.String(val)\n}\n\n// URLPort returns an attribute KeyValue conforming to the \"url.port\" semantic\n// conventions. It represents the port extracted from the `url.full`.\nfunc URLPort(val int) attribute.KeyValue {\n\treturn URLPortKey.Int(val)\n}\n\n// URLQuery returns an attribute KeyValue conforming to the \"url.query\" semantic\n// conventions. It represents the [URI query] component.\n//\n// [URI query]: https://www.rfc-editor.org/rfc/rfc3986#section-3.4\nfunc URLQuery(val string) attribute.KeyValue {\n\treturn URLQueryKey.String(val)\n}\n\n// URLRegisteredDomain returns an attribute KeyValue conforming to the\n// \"url.registered_domain\" semantic conventions. It represents the highest\n// registered url domain, stripped of the subdomain.\nfunc URLRegisteredDomain(val string) attribute.KeyValue {\n\treturn URLRegisteredDomainKey.String(val)\n}\n\n// URLScheme returns an attribute KeyValue conforming to the \"url.scheme\"\n// semantic conventions. It represents the [URI scheme] component identifying the\n// used protocol.\n//\n// [URI scheme]: https://www.rfc-editor.org/rfc/rfc3986#section-3.1\nfunc URLScheme(val string) attribute.KeyValue {\n\treturn URLSchemeKey.String(val)\n}\n\n// URLSubdomain returns an attribute KeyValue conforming to the \"url.subdomain\"\n// semantic conventions. It represents the subdomain portion of a fully qualified\n// domain name includes all of the names except the host name under the\n// registered_domain. In a partially qualified domain, or if the qualification\n// level of the full name cannot be determined, subdomain contains all of the\n// names below the registered domain.\nfunc URLSubdomain(val string) attribute.KeyValue {\n\treturn URLSubdomainKey.String(val)\n}\n\n// URLTemplate returns an attribute KeyValue conforming to the \"url.template\"\n// semantic conventions. It represents the low-cardinality template of an\n// [absolute path reference].\n//\n// [absolute path reference]: https://www.rfc-editor.org/rfc/rfc3986#section-4.2\nfunc URLTemplate(val string) attribute.KeyValue {\n\treturn URLTemplateKey.String(val)\n}\n\n// URLTopLevelDomain returns an attribute KeyValue conforming to the\n// \"url.top_level_domain\" semantic conventions. It represents the effective top\n// level domain (eTLD), also known as the domain suffix, is the last part of the\n// domain name. For example, the top level domain for example.com is `com`.\nfunc URLTopLevelDomain(val string) attribute.KeyValue {\n\treturn URLTopLevelDomainKey.String(val)\n}\n\n// Namespace: user\nconst (\n\t// UserEmailKey is the attribute Key conforming to the \"user.email\" semantic\n\t// conventions. It represents the user email address.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"a.einstein@example.com\"\n\tUserEmailKey = attribute.Key(\"user.email\")\n\n\t// UserFullNameKey is the attribute Key conforming to the \"user.full_name\"\n\t// semantic conventions. It represents the user's full name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Albert Einstein\"\n\tUserFullNameKey = attribute.Key(\"user.full_name\")\n\n\t// UserHashKey is the attribute Key conforming to the \"user.hash\" semantic\n\t// conventions. It represents the unique user hash to correlate information for\n\t// a user in anonymized form.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"364fc68eaf4c8acec74a4e52d7d1feaa\"\n\t// Note: Useful if `user.id` or `user.name` contain confidential information and\n\t// cannot be used.\n\tUserHashKey = attribute.Key(\"user.hash\")\n\n\t// UserIDKey is the attribute Key conforming to the \"user.id\" semantic\n\t// conventions. It represents the unique identifier of the user.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"S-1-5-21-202424912787-2692429404-2351956786-1000\"\n\tUserIDKey = attribute.Key(\"user.id\")\n\n\t// UserNameKey is the attribute Key conforming to the \"user.name\" semantic\n\t// conventions. It represents the short name or login/username of the user.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"a.einstein\"\n\tUserNameKey = attribute.Key(\"user.name\")\n\n\t// UserRolesKey is the attribute Key conforming to the \"user.roles\" semantic\n\t// conventions. It represents the array of user roles at the time of the event.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"admin\", \"reporting_user\"\n\tUserRolesKey = attribute.Key(\"user.roles\")\n)\n\n// UserEmail returns an attribute KeyValue conforming to the \"user.email\"\n// semantic conventions. It represents the user email address.\nfunc UserEmail(val string) attribute.KeyValue {\n\treturn UserEmailKey.String(val)\n}\n\n// UserFullName returns an attribute KeyValue conforming to the \"user.full_name\"\n// semantic conventions. It represents the user's full name.\nfunc UserFullName(val string) attribute.KeyValue {\n\treturn UserFullNameKey.String(val)\n}\n\n// UserHash returns an attribute KeyValue conforming to the \"user.hash\" semantic\n// conventions. It represents the unique user hash to correlate information for a\n// user in anonymized form.\nfunc UserHash(val string) attribute.KeyValue {\n\treturn UserHashKey.String(val)\n}\n\n// UserID returns an attribute KeyValue conforming to the \"user.id\" semantic\n// conventions. It represents the unique identifier of the user.\nfunc UserID(val string) attribute.KeyValue {\n\treturn UserIDKey.String(val)\n}\n\n// UserName returns an attribute KeyValue conforming to the \"user.name\" semantic\n// conventions. It represents the short name or login/username of the user.\nfunc UserName(val string) attribute.KeyValue {\n\treturn UserNameKey.String(val)\n}\n\n// UserRoles returns an attribute KeyValue conforming to the \"user.roles\"\n// semantic conventions. It represents the array of user roles at the time of the\n// event.\nfunc UserRoles(val ...string) attribute.KeyValue {\n\treturn UserRolesKey.StringSlice(val)\n}\n\n// Namespace: user_agent\nconst (\n\t// UserAgentNameKey is the attribute Key conforming to the \"user_agent.name\"\n\t// semantic conventions. It represents the name of the user-agent extracted from\n\t// original. Usually refers to the browser's name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Safari\", \"YourApp\"\n\t// Note: [Example] of extracting browser's name from original string. In the\n\t// case of using a user-agent for non-browser products, such as microservices\n\t// with multiple names/versions inside the `user_agent.original`, the most\n\t// significant name SHOULD be selected. In such a scenario it should align with\n\t// `user_agent.version`\n\t//\n\t// [Example]: https://uaparser.dev/#demo\n\tUserAgentNameKey = attribute.Key(\"user_agent.name\")\n\n\t// UserAgentOriginalKey is the attribute Key conforming to the\n\t// \"user_agent.original\" semantic conventions. It represents the value of the\n\t// [HTTP User-Agent] header sent by the client.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Stable\n\t//\n\t// Examples: \"CERN-LineMode/2.15 libwww/2.17b3\", \"Mozilla/5.0 (iPhone; CPU\n\t// iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko)\n\t// Version/14.1.2 Mobile/15E148 Safari/604.1\", \"YourApp/1.0.0\n\t// grpc-java-okhttp/1.27.2\"\n\t//\n\t// [HTTP User-Agent]: https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent\n\tUserAgentOriginalKey = attribute.Key(\"user_agent.original\")\n\n\t// UserAgentOSNameKey is the attribute Key conforming to the\n\t// \"user_agent.os.name\" semantic conventions. It represents the human readable\n\t// operating system name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"iOS\", \"Android\", \"Ubuntu\"\n\t// Note: For mapping user agent strings to OS names, libraries such as\n\t// [ua-parser] can be utilized.\n\t//\n\t// [ua-parser]: https://github.com/ua-parser\n\tUserAgentOSNameKey = attribute.Key(\"user_agent.os.name\")\n\n\t// UserAgentOSVersionKey is the attribute Key conforming to the\n\t// \"user_agent.os.version\" semantic conventions. It represents the version\n\t// string of the operating system as defined in [Version Attributes].\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"14.2.1\", \"18.04.1\"\n\t// Note: For mapping user agent strings to OS versions, libraries such as\n\t// [ua-parser] can be utilized.\n\t//\n\t// [Version Attributes]: /docs/resource/README.md#version-attributes\n\t// [ua-parser]: https://github.com/ua-parser\n\tUserAgentOSVersionKey = attribute.Key(\"user_agent.os.version\")\n\n\t// UserAgentSyntheticTypeKey is the attribute Key conforming to the\n\t// \"user_agent.synthetic.type\" semantic conventions. It represents the specifies\n\t// the category of synthetic traffic, such as tests or bots.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// Note: This attribute MAY be derived from the contents of the\n\t// `user_agent.original` attribute. Components that populate the attribute are\n\t// responsible for determining what they consider to be synthetic bot or test\n\t// traffic. This attribute can either be set for self-identification purposes,\n\t// or on telemetry detected to be generated as a result of a synthetic request.\n\t// This attribute is useful for distinguishing between genuine client traffic\n\t// and synthetic traffic generated by bots or tests.\n\tUserAgentSyntheticTypeKey = attribute.Key(\"user_agent.synthetic.type\")\n\n\t// UserAgentVersionKey is the attribute Key conforming to the\n\t// \"user_agent.version\" semantic conventions. It represents the version of the\n\t// user-agent extracted from original. Usually refers to the browser's version.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"14.1.2\", \"1.0.0\"\n\t// Note: [Example] of extracting browser's version from original string. In the\n\t// case of using a user-agent for non-browser products, such as microservices\n\t// with multiple names/versions inside the `user_agent.original`, the most\n\t// significant version SHOULD be selected. In such a scenario it should align\n\t// with `user_agent.name`\n\t//\n\t// [Example]: https://uaparser.dev/#demo\n\tUserAgentVersionKey = attribute.Key(\"user_agent.version\")\n)\n\n// UserAgentName returns an attribute KeyValue conforming to the\n// \"user_agent.name\" semantic conventions. It represents the name of the\n// user-agent extracted from original. Usually refers to the browser's name.\nfunc UserAgentName(val string) attribute.KeyValue {\n\treturn UserAgentNameKey.String(val)\n}\n\n// UserAgentOriginal returns an attribute KeyValue conforming to the\n// \"user_agent.original\" semantic conventions. It represents the value of the\n// [HTTP User-Agent] header sent by the client.\n//\n// [HTTP User-Agent]: https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent\nfunc UserAgentOriginal(val string) attribute.KeyValue {\n\treturn UserAgentOriginalKey.String(val)\n}\n\n// UserAgentOSName returns an attribute KeyValue conforming to the\n// \"user_agent.os.name\" semantic conventions. It represents the human readable\n// operating system name.\nfunc UserAgentOSName(val string) attribute.KeyValue {\n\treturn UserAgentOSNameKey.String(val)\n}\n\n// UserAgentOSVersion returns an attribute KeyValue conforming to the\n// \"user_agent.os.version\" semantic conventions. It represents the version string\n// of the operating system as defined in [Version Attributes].\n//\n// [Version Attributes]: /docs/resource/README.md#version-attributes\nfunc UserAgentOSVersion(val string) attribute.KeyValue {\n\treturn UserAgentOSVersionKey.String(val)\n}\n\n// UserAgentVersion returns an attribute KeyValue conforming to the\n// \"user_agent.version\" semantic conventions. It represents the version of the\n// user-agent extracted from original. Usually refers to the browser's version.\nfunc UserAgentVersion(val string) attribute.KeyValue {\n\treturn UserAgentVersionKey.String(val)\n}\n\n// Enum values for user_agent.synthetic.type\nvar (\n\t// Bot source.\n\t// Stability: development\n\tUserAgentSyntheticTypeBot = UserAgentSyntheticTypeKey.String(\"bot\")\n\t// Synthetic test source.\n\t// Stability: development\n\tUserAgentSyntheticTypeTest = UserAgentSyntheticTypeKey.String(\"test\")\n)\n\n// Namespace: vcs\nconst (\n\t// VCSChangeIDKey is the attribute Key conforming to the \"vcs.change.id\"\n\t// semantic conventions. It represents the ID of the change (pull request/merge\n\t// request/changelist) if applicable. This is usually a unique (within\n\t// repository) identifier generated by the VCS system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"123\"\n\tVCSChangeIDKey = attribute.Key(\"vcs.change.id\")\n\n\t// VCSChangeStateKey is the attribute Key conforming to the \"vcs.change.state\"\n\t// semantic conventions. It represents the state of the change (pull\n\t// request/merge request/changelist).\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"open\", \"closed\", \"merged\"\n\tVCSChangeStateKey = attribute.Key(\"vcs.change.state\")\n\n\t// VCSChangeTitleKey is the attribute Key conforming to the \"vcs.change.title\"\n\t// semantic conventions. It represents the human readable title of the change\n\t// (pull request/merge request/changelist). This title is often a brief summary\n\t// of the change and may get merged in to a ref as the commit summary.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"Fixes broken thing\", \"feat: add my new feature\", \"[chore] update\n\t// dependency\"\n\tVCSChangeTitleKey = attribute.Key(\"vcs.change.title\")\n\n\t// VCSLineChangeTypeKey is the attribute Key conforming to the\n\t// \"vcs.line_change.type\" semantic conventions. It represents the type of line\n\t// change being measured on a branch or change.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"added\", \"removed\"\n\tVCSLineChangeTypeKey = attribute.Key(\"vcs.line_change.type\")\n\n\t// VCSOwnerNameKey is the attribute Key conforming to the \"vcs.owner.name\"\n\t// semantic conventions. It represents the group owner within the version\n\t// control system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-org\", \"myteam\", \"business-unit\"\n\tVCSOwnerNameKey = attribute.Key(\"vcs.owner.name\")\n\n\t// VCSProviderNameKey is the attribute Key conforming to the \"vcs.provider.name\"\n\t// semantic conventions. It represents the name of the version control system\n\t// provider.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"github\", \"gitlab\", \"gitea\", \"bitbucket\"\n\tVCSProviderNameKey = attribute.Key(\"vcs.provider.name\")\n\n\t// VCSRefBaseNameKey is the attribute Key conforming to the \"vcs.ref.base.name\"\n\t// semantic conventions. It represents the name of the [reference] such as\n\t// **branch** or **tag** in the repository.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-feature-branch\", \"tag-1-test\"\n\t// Note: `base` refers to the starting point of a change. For example, `main`\n\t// would be the base reference of type branch if you've created a new\n\t// reference of type branch from it and created new commits.\n\t//\n\t// [reference]: https://git-scm.com/docs/gitglossary#def_ref\n\tVCSRefBaseNameKey = attribute.Key(\"vcs.ref.base.name\")\n\n\t// VCSRefBaseRevisionKey is the attribute Key conforming to the\n\t// \"vcs.ref.base.revision\" semantic conventions. It represents the revision,\n\t// literally [revised version], The revision most often refers to a commit\n\t// object in Git, or a revision number in SVN.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"9d59409acf479dfa0df1aa568182e43e43df8bbe28d60fcf2bc52e30068802cc\",\n\t// \"main\", \"123\", \"HEAD\"\n\t// Note: `base` refers to the starting point of a change. For example, `main`\n\t// would be the base reference of type branch if you've created a new\n\t// reference of type branch from it and created new commits. The\n\t// revision can be a full [hash value (see\n\t// glossary)],\n\t// of the recorded change to a ref within a repository pointing to a\n\t// commit [commit] object. It does\n\t// not necessarily have to be a hash; it can simply define a [revision\n\t// number]\n\t// which is an integer that is monotonically increasing. In cases where\n\t// it is identical to the `ref.base.name`, it SHOULD still be included.\n\t// It is up to the implementer to decide which value to set as the\n\t// revision based on the VCS system and situational context.\n\t//\n\t// [revised version]: https://www.merriam-webster.com/dictionary/revision\n\t// [hash value (see\n\t// glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf\n\t// [commit]: https://git-scm.com/docs/git-commit\n\t// [revision\n\t// number]: https://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html\n\tVCSRefBaseRevisionKey = attribute.Key(\"vcs.ref.base.revision\")\n\n\t// VCSRefBaseTypeKey is the attribute Key conforming to the \"vcs.ref.base.type\"\n\t// semantic conventions. It represents the type of the [reference] in the\n\t// repository.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"branch\", \"tag\"\n\t// Note: `base` refers to the starting point of a change. For example, `main`\n\t// would be the base reference of type branch if you've created a new\n\t// reference of type branch from it and created new commits.\n\t//\n\t// [reference]: https://git-scm.com/docs/gitglossary#def_ref\n\tVCSRefBaseTypeKey = attribute.Key(\"vcs.ref.base.type\")\n\n\t// VCSRefHeadNameKey is the attribute Key conforming to the \"vcs.ref.head.name\"\n\t// semantic conventions. It represents the name of the [reference] such as\n\t// **branch** or **tag** in the repository.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"my-feature-branch\", \"tag-1-test\"\n\t// Note: `head` refers to where you are right now; the current reference at a\n\t// given time.\n\t//\n\t// [reference]: https://git-scm.com/docs/gitglossary#def_ref\n\tVCSRefHeadNameKey = attribute.Key(\"vcs.ref.head.name\")\n\n\t// VCSRefHeadRevisionKey is the attribute Key conforming to the\n\t// \"vcs.ref.head.revision\" semantic conventions. It represents the revision,\n\t// literally [revised version], The revision most often refers to a commit\n\t// object in Git, or a revision number in SVN.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"9d59409acf479dfa0df1aa568182e43e43df8bbe28d60fcf2bc52e30068802cc\",\n\t// \"main\", \"123\", \"HEAD\"\n\t// Note: `head` refers to where you are right now; the current reference at a\n\t// given time.The revision can be a full [hash value (see\n\t// glossary)],\n\t// of the recorded change to a ref within a repository pointing to a\n\t// commit [commit] object. It does\n\t// not necessarily have to be a hash; it can simply define a [revision\n\t// number]\n\t// which is an integer that is monotonically increasing. In cases where\n\t// it is identical to the `ref.head.name`, it SHOULD still be included.\n\t// It is up to the implementer to decide which value to set as the\n\t// revision based on the VCS system and situational context.\n\t//\n\t// [revised version]: https://www.merriam-webster.com/dictionary/revision\n\t// [hash value (see\n\t// glossary)]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf\n\t// [commit]: https://git-scm.com/docs/git-commit\n\t// [revision\n\t// number]: https://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html\n\tVCSRefHeadRevisionKey = attribute.Key(\"vcs.ref.head.revision\")\n\n\t// VCSRefHeadTypeKey is the attribute Key conforming to the \"vcs.ref.head.type\"\n\t// semantic conventions. It represents the type of the [reference] in the\n\t// repository.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"branch\", \"tag\"\n\t// Note: `head` refers to where you are right now; the current reference at a\n\t// given time.\n\t//\n\t// [reference]: https://git-scm.com/docs/gitglossary#def_ref\n\tVCSRefHeadTypeKey = attribute.Key(\"vcs.ref.head.type\")\n\n\t// VCSRefTypeKey is the attribute Key conforming to the \"vcs.ref.type\" semantic\n\t// conventions. It represents the type of the [reference] in the repository.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"branch\", \"tag\"\n\t//\n\t// [reference]: https://git-scm.com/docs/gitglossary#def_ref\n\tVCSRefTypeKey = attribute.Key(\"vcs.ref.type\")\n\n\t// VCSRepositoryNameKey is the attribute Key conforming to the\n\t// \"vcs.repository.name\" semantic conventions. It represents the human readable\n\t// name of the repository. It SHOULD NOT include any additional identifier like\n\t// Group/SubGroup in GitLab or organization in GitHub.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"semantic-conventions\", \"my-cool-repo\"\n\t// Note: Due to it only being the name, it can clash with forks of the same\n\t// repository if collecting telemetry across multiple orgs or groups in\n\t// the same backends.\n\tVCSRepositoryNameKey = attribute.Key(\"vcs.repository.name\")\n\n\t// VCSRepositoryURLFullKey is the attribute Key conforming to the\n\t// \"vcs.repository.url.full\" semantic conventions. It represents the\n\t// [canonical URL] of the repository providing the complete HTTP(S) address in\n\t// order to locate and identify the repository through a browser.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples:\n\t// \"https://github.com/opentelemetry/open-telemetry-collector-contrib\",\n\t// \"https://gitlab.com/my-org/my-project/my-projects-project/repo\"\n\t// Note: In Git Version Control Systems, the canonical URL SHOULD NOT include\n\t// the `.git` extension.\n\t//\n\t// [canonical URL]: https://support.google.com/webmasters/answer/10347851\n\tVCSRepositoryURLFullKey = attribute.Key(\"vcs.repository.url.full\")\n\n\t// VCSRevisionDeltaDirectionKey is the attribute Key conforming to the\n\t// \"vcs.revision_delta.direction\" semantic conventions. It represents the type\n\t// of revision comparison.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"ahead\", \"behind\"\n\tVCSRevisionDeltaDirectionKey = attribute.Key(\"vcs.revision_delta.direction\")\n)\n\n// VCSChangeID returns an attribute KeyValue conforming to the \"vcs.change.id\"\n// semantic conventions. It represents the ID of the change (pull request/merge\n// request/changelist) if applicable. This is usually a unique (within\n// repository) identifier generated by the VCS system.\nfunc VCSChangeID(val string) attribute.KeyValue {\n\treturn VCSChangeIDKey.String(val)\n}\n\n// VCSChangeTitle returns an attribute KeyValue conforming to the\n// \"vcs.change.title\" semantic conventions. It represents the human readable\n// title of the change (pull request/merge request/changelist). This title is\n// often a brief summary of the change and may get merged in to a ref as the\n// commit summary.\nfunc VCSChangeTitle(val string) attribute.KeyValue {\n\treturn VCSChangeTitleKey.String(val)\n}\n\n// VCSOwnerName returns an attribute KeyValue conforming to the \"vcs.owner.name\"\n// semantic conventions. It represents the group owner within the version control\n// system.\nfunc VCSOwnerName(val string) attribute.KeyValue {\n\treturn VCSOwnerNameKey.String(val)\n}\n\n// VCSRefBaseName returns an attribute KeyValue conforming to the\n// \"vcs.ref.base.name\" semantic conventions. It represents the name of the\n// [reference] such as **branch** or **tag** in the repository.\n//\n// [reference]: https://git-scm.com/docs/gitglossary#def_ref\nfunc VCSRefBaseName(val string) attribute.KeyValue {\n\treturn VCSRefBaseNameKey.String(val)\n}\n\n// VCSRefBaseRevision returns an attribute KeyValue conforming to the\n// \"vcs.ref.base.revision\" semantic conventions. It represents the revision,\n// literally [revised version], The revision most often refers to a commit object\n// in Git, or a revision number in SVN.\n//\n// [revised version]: https://www.merriam-webster.com/dictionary/revision\nfunc VCSRefBaseRevision(val string) attribute.KeyValue {\n\treturn VCSRefBaseRevisionKey.String(val)\n}\n\n// VCSRefHeadName returns an attribute KeyValue conforming to the\n// \"vcs.ref.head.name\" semantic conventions. It represents the name of the\n// [reference] such as **branch** or **tag** in the repository.\n//\n// [reference]: https://git-scm.com/docs/gitglossary#def_ref\nfunc VCSRefHeadName(val string) attribute.KeyValue {\n\treturn VCSRefHeadNameKey.String(val)\n}\n\n// VCSRefHeadRevision returns an attribute KeyValue conforming to the\n// \"vcs.ref.head.revision\" semantic conventions. It represents the revision,\n// literally [revised version], The revision most often refers to a commit object\n// in Git, or a revision number in SVN.\n//\n// [revised version]: https://www.merriam-webster.com/dictionary/revision\nfunc VCSRefHeadRevision(val string) attribute.KeyValue {\n\treturn VCSRefHeadRevisionKey.String(val)\n}\n\n// VCSRepositoryName returns an attribute KeyValue conforming to the\n// \"vcs.repository.name\" semantic conventions. It represents the human readable\n// name of the repository. It SHOULD NOT include any additional identifier like\n// Group/SubGroup in GitLab or organization in GitHub.\nfunc VCSRepositoryName(val string) attribute.KeyValue {\n\treturn VCSRepositoryNameKey.String(val)\n}\n\n// VCSRepositoryURLFull returns an attribute KeyValue conforming to the\n// \"vcs.repository.url.full\" semantic conventions. It represents the\n// [canonical URL] of the repository providing the complete HTTP(S) address in\n// order to locate and identify the repository through a browser.\n//\n// [canonical URL]: https://support.google.com/webmasters/answer/10347851\nfunc VCSRepositoryURLFull(val string) attribute.KeyValue {\n\treturn VCSRepositoryURLFullKey.String(val)\n}\n\n// Enum values for vcs.change.state\nvar (\n\t// Open means the change is currently active and under review. It hasn't been\n\t// merged into the target branch yet, and it's still possible to make changes or\n\t// add comments.\n\t// Stability: development\n\tVCSChangeStateOpen = VCSChangeStateKey.String(\"open\")\n\t// WIP (work-in-progress, draft) means the change is still in progress and not\n\t// yet ready for a full review. It might still undergo significant changes.\n\t// Stability: development\n\tVCSChangeStateWip = VCSChangeStateKey.String(\"wip\")\n\t// Closed means the merge request has been closed without merging. This can\n\t// happen for various reasons, such as the changes being deemed unnecessary, the\n\t// issue being resolved in another way, or the author deciding to withdraw the\n\t// request.\n\t// Stability: development\n\tVCSChangeStateClosed = VCSChangeStateKey.String(\"closed\")\n\t// Merged indicates that the change has been successfully integrated into the\n\t// target codebase.\n\t// Stability: development\n\tVCSChangeStateMerged = VCSChangeStateKey.String(\"merged\")\n)\n\n// Enum values for vcs.line_change.type\nvar (\n\t// How many lines were added.\n\t// Stability: development\n\tVCSLineChangeTypeAdded = VCSLineChangeTypeKey.String(\"added\")\n\t// How many lines were removed.\n\t// Stability: development\n\tVCSLineChangeTypeRemoved = VCSLineChangeTypeKey.String(\"removed\")\n)\n\n// Enum values for vcs.provider.name\nvar (\n\t// [GitHub]\n\t// Stability: development\n\t//\n\t// [GitHub]: https://github.com\n\tVCSProviderNameGithub = VCSProviderNameKey.String(\"github\")\n\t// [GitLab]\n\t// Stability: development\n\t//\n\t// [GitLab]: https://gitlab.com\n\tVCSProviderNameGitlab = VCSProviderNameKey.String(\"gitlab\")\n\t// [Gitea]\n\t// Stability: development\n\t//\n\t// [Gitea]: https://gitea.io\n\tVCSProviderNameGitea = VCSProviderNameKey.String(\"gitea\")\n\t// [Bitbucket]\n\t// Stability: development\n\t//\n\t// [Bitbucket]: https://bitbucket.org\n\tVCSProviderNameBitbucket = VCSProviderNameKey.String(\"bitbucket\")\n)\n\n// Enum values for vcs.ref.base.type\nvar (\n\t// [branch]\n\t// Stability: development\n\t//\n\t// [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch\n\tVCSRefBaseTypeBranch = VCSRefBaseTypeKey.String(\"branch\")\n\t// [tag]\n\t// Stability: development\n\t//\n\t// [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag\n\tVCSRefBaseTypeTag = VCSRefBaseTypeKey.String(\"tag\")\n)\n\n// Enum values for vcs.ref.head.type\nvar (\n\t// [branch]\n\t// Stability: development\n\t//\n\t// [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch\n\tVCSRefHeadTypeBranch = VCSRefHeadTypeKey.String(\"branch\")\n\t// [tag]\n\t// Stability: development\n\t//\n\t// [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag\n\tVCSRefHeadTypeTag = VCSRefHeadTypeKey.String(\"tag\")\n)\n\n// Enum values for vcs.ref.type\nvar (\n\t// [branch]\n\t// Stability: development\n\t//\n\t// [branch]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch\n\tVCSRefTypeBranch = VCSRefTypeKey.String(\"branch\")\n\t// [tag]\n\t// Stability: development\n\t//\n\t// [tag]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag\n\tVCSRefTypeTag = VCSRefTypeKey.String(\"tag\")\n)\n\n// Enum values for vcs.revision_delta.direction\nvar (\n\t// How many revisions the change is behind the target ref.\n\t// Stability: development\n\tVCSRevisionDeltaDirectionBehind = VCSRevisionDeltaDirectionKey.String(\"behind\")\n\t// How many revisions the change is ahead of the target ref.\n\t// Stability: development\n\tVCSRevisionDeltaDirectionAhead = VCSRevisionDeltaDirectionKey.String(\"ahead\")\n)\n\n// Namespace: webengine\nconst (\n\t// WebEngineDescriptionKey is the attribute Key conforming to the\n\t// \"webengine.description\" semantic conventions. It represents the additional\n\t// description of the web engine (e.g. detailed version and edition\n\t// information).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) -\n\t// 2.2.2.Final\"\n\tWebEngineDescriptionKey = attribute.Key(\"webengine.description\")\n\n\t// WebEngineNameKey is the attribute Key conforming to the \"webengine.name\"\n\t// semantic conventions. It represents the name of the web engine.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"WildFly\"\n\tWebEngineNameKey = attribute.Key(\"webengine.name\")\n\n\t// WebEngineVersionKey is the attribute Key conforming to the\n\t// \"webengine.version\" semantic conventions. It represents the version of the\n\t// web engine.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"21.0.0\"\n\tWebEngineVersionKey = attribute.Key(\"webengine.version\")\n)\n\n// WebEngineDescription returns an attribute KeyValue conforming to the\n// \"webengine.description\" semantic conventions. It represents the additional\n// description of the web engine (e.g. detailed version and edition information).\nfunc WebEngineDescription(val string) attribute.KeyValue {\n\treturn WebEngineDescriptionKey.String(val)\n}\n\n// WebEngineName returns an attribute KeyValue conforming to the \"webengine.name\"\n// semantic conventions. It represents the name of the web engine.\nfunc WebEngineName(val string) attribute.KeyValue {\n\treturn WebEngineNameKey.String(val)\n}\n\n// WebEngineVersion returns an attribute KeyValue conforming to the\n// \"webengine.version\" semantic conventions. It represents the version of the web\n// engine.\nfunc WebEngineVersion(val string) attribute.KeyValue {\n\treturn WebEngineVersionKey.String(val)\n}\n\n// Namespace: zos\nconst (\n\t// ZOSSmfIDKey is the attribute Key conforming to the \"zos.smf.id\" semantic\n\t// conventions. It represents the System Management Facility (SMF) Identifier\n\t// uniquely identified a z/OS system within a SYSPLEX or mainframe environment\n\t// and is used for system and performance analysis.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"SYS1\"\n\tZOSSmfIDKey = attribute.Key(\"zos.smf.id\")\n\n\t// ZOSSysplexNameKey is the attribute Key conforming to the \"zos.sysplex.name\"\n\t// semantic conventions. It represents the name of the SYSPLEX to which the z/OS\n\t// system belongs too.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: Development\n\t//\n\t// Examples: \"SYSPLEX1\"\n\tZOSSysplexNameKey = attribute.Key(\"zos.sysplex.name\")\n)\n\n// ZOSSmfID returns an attribute KeyValue conforming to the \"zos.smf.id\" semantic\n// conventions. It represents the System Management Facility (SMF) Identifier\n// uniquely identified a z/OS system within a SYSPLEX or mainframe environment\n// and is used for system and performance analysis.\nfunc ZOSSmfID(val string) attribute.KeyValue {\n\treturn ZOSSmfIDKey.String(val)\n}\n\n// ZOSSysplexName returns an attribute KeyValue conforming to the\n// \"zos.sysplex.name\" semantic conventions. It represents the name of the SYSPLEX\n// to which the z/OS system belongs too.\nfunc ZOSSysplexName(val string) attribute.KeyValue {\n\treturn ZOSSysplexNameKey.String(val)\n}"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.39.0/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package semconv implements OpenTelemetry semantic conventions.\n//\n// OpenTelemetry semantic conventions are agreed standardized naming\n// patterns for OpenTelemetry things. This package represents the v1.39.0\n// version of the OpenTelemetry semantic conventions.\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.39.0\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.39.0/error_type.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.39.0\"\n\nimport (\n\t\"reflect\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n)\n\n// ErrorType returns an [attribute.KeyValue] identifying the error type of err.\n//\n// If err is nil, the returned attribute has the default value\n// [ErrorTypeOther].\n//\n// If err's type has the method\n//\n//\tErrorType() string\n//\n// then the returned attribute has the value of err.ErrorType(). Otherwise, the\n// returned attribute has a value derived from the concrete type of err.\n//\n// The key of the returned attribute is [ErrorTypeKey].\nfunc ErrorType(err error) attribute.KeyValue {\n\tif err == nil {\n\t\treturn ErrorTypeOther\n\t}\n\n\treturn ErrorTypeKey.String(errorType(err))\n}\n\nfunc errorType(err error) string {\n\tvar s string\n\tif et, ok := err.(interface{ ErrorType() string }); ok {\n\t\t// Prioritize the ErrorType method if available.\n\t\ts = et.ErrorType()\n\t}\n\tif s == \"\" {\n\t\t// Fallback to reflection if the ErrorType method is not supported or\n\t\t// returns an empty value.\n\n\t\tt := reflect.TypeOf(err)\n\t\tpkg, name := t.PkgPath(), t.Name()\n\t\tif pkg != \"\" && name != \"\" {\n\t\t\ts = pkg + \".\" + name\n\t\t} else {\n\t\t\t// The type has no package path or name (predeclared, not-defined,\n\t\t\t// or alias for a not-defined type).\n\t\t\t//\n\t\t\t// This is not guaranteed to be unique, but is a best effort.\n\t\t\ts = t.String()\n\t\t}\n\t}\n\treturn s\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.39.0/exception.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.39.0\"\n\nconst (\n\t// ExceptionEventName is the name of the Span event representing an exception.\n\tExceptionEventName = \"exception\"\n)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.39.0/otelconv/metric.go",
    "content": "// Code generated from semantic convention specification. DO NOT EDIT.\n\n// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package otelconv provides types and functionality for OpenTelemetry semantic\n// conventions in the \"otel\" namespace.\npackage otelconv\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/metric\"\n\t\"go.opentelemetry.io/otel/metric/noop\"\n)\n\nvar (\n\taddOptPool = &sync.Pool{New: func() any { return &[]metric.AddOption{} }}\n\trecOptPool = &sync.Pool{New: func() any { return &[]metric.RecordOption{} }}\n)\n\n// ErrorTypeAttr is an attribute conforming to the error.type semantic\n// conventions. It represents the describes a class of error the operation ended\n// with.\ntype ErrorTypeAttr string\n\nvar (\n\t// ErrorTypeOther is a fallback error value to be used when the instrumentation\n\t// doesn't define a custom value.\n\tErrorTypeOther ErrorTypeAttr = \"_OTHER\"\n)\n\n// ComponentTypeAttr is an attribute conforming to the otel.component.type\n// semantic conventions. It represents a name identifying the type of the\n// OpenTelemetry component.\ntype ComponentTypeAttr string\n\nvar (\n\t// ComponentTypeBatchingSpanProcessor is the builtin SDK batching span\n\t// processor.\n\tComponentTypeBatchingSpanProcessor ComponentTypeAttr = \"batching_span_processor\"\n\t// ComponentTypeSimpleSpanProcessor is the builtin SDK simple span processor.\n\tComponentTypeSimpleSpanProcessor ComponentTypeAttr = \"simple_span_processor\"\n\t// ComponentTypeBatchingLogProcessor is the builtin SDK batching log record\n\t// processor.\n\tComponentTypeBatchingLogProcessor ComponentTypeAttr = \"batching_log_processor\"\n\t// ComponentTypeSimpleLogProcessor is the builtin SDK simple log record\n\t// processor.\n\tComponentTypeSimpleLogProcessor ComponentTypeAttr = \"simple_log_processor\"\n\t// ComponentTypeOtlpGRPCSpanExporter is the OTLP span exporter over gRPC with\n\t// protobuf serialization.\n\tComponentTypeOtlpGRPCSpanExporter ComponentTypeAttr = \"otlp_grpc_span_exporter\"\n\t// ComponentTypeOtlpHTTPSpanExporter is the OTLP span exporter over HTTP with\n\t// protobuf serialization.\n\tComponentTypeOtlpHTTPSpanExporter ComponentTypeAttr = \"otlp_http_span_exporter\"\n\t// ComponentTypeOtlpHTTPJSONSpanExporter is the OTLP span exporter over HTTP\n\t// with JSON serialization.\n\tComponentTypeOtlpHTTPJSONSpanExporter ComponentTypeAttr = \"otlp_http_json_span_exporter\"\n\t// ComponentTypeZipkinHTTPSpanExporter is the zipkin span exporter over HTTP.\n\tComponentTypeZipkinHTTPSpanExporter ComponentTypeAttr = \"zipkin_http_span_exporter\"\n\t// ComponentTypeOtlpGRPCLogExporter is the OTLP log record exporter over gRPC\n\t// with protobuf serialization.\n\tComponentTypeOtlpGRPCLogExporter ComponentTypeAttr = \"otlp_grpc_log_exporter\"\n\t// ComponentTypeOtlpHTTPLogExporter is the OTLP log record exporter over HTTP\n\t// with protobuf serialization.\n\tComponentTypeOtlpHTTPLogExporter ComponentTypeAttr = \"otlp_http_log_exporter\"\n\t// ComponentTypeOtlpHTTPJSONLogExporter is the OTLP log record exporter over\n\t// HTTP with JSON serialization.\n\tComponentTypeOtlpHTTPJSONLogExporter ComponentTypeAttr = \"otlp_http_json_log_exporter\"\n\t// ComponentTypePeriodicMetricReader is the builtin SDK periodically exporting\n\t// metric reader.\n\tComponentTypePeriodicMetricReader ComponentTypeAttr = \"periodic_metric_reader\"\n\t// ComponentTypeOtlpGRPCMetricExporter is the OTLP metric exporter over gRPC\n\t// with protobuf serialization.\n\tComponentTypeOtlpGRPCMetricExporter ComponentTypeAttr = \"otlp_grpc_metric_exporter\"\n\t// ComponentTypeOtlpHTTPMetricExporter is the OTLP metric exporter over HTTP\n\t// with protobuf serialization.\n\tComponentTypeOtlpHTTPMetricExporter ComponentTypeAttr = \"otlp_http_metric_exporter\"\n\t// ComponentTypeOtlpHTTPJSONMetricExporter is the OTLP metric exporter over HTTP\n\t// with JSON serialization.\n\tComponentTypeOtlpHTTPJSONMetricExporter ComponentTypeAttr = \"otlp_http_json_metric_exporter\"\n\t// ComponentTypePrometheusHTTPTextMetricExporter is the prometheus metric\n\t// exporter over HTTP with the default text-based format.\n\tComponentTypePrometheusHTTPTextMetricExporter ComponentTypeAttr = \"prometheus_http_text_metric_exporter\"\n)\n\n// SpanParentOriginAttr is an attribute conforming to the otel.span.parent.origin\n// semantic conventions. It represents the determines whether the span has a\n// parent span, and if so, [whether it is a remote parent].\n//\n// [whether it is a remote parent]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote\ntype SpanParentOriginAttr string\n\nvar (\n\t// SpanParentOriginNone is the span does not have a parent, it is a root span.\n\tSpanParentOriginNone SpanParentOriginAttr = \"none\"\n\t// SpanParentOriginLocal is the span has a parent and the parent's span context\n\t// [isRemote()] is false.\n\t//\n\t// [isRemote()]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote\n\tSpanParentOriginLocal SpanParentOriginAttr = \"local\"\n\t// SpanParentOriginRemote is the span has a parent and the parent's span context\n\t// [isRemote()] is true.\n\t//\n\t// [isRemote()]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote\n\tSpanParentOriginRemote SpanParentOriginAttr = \"remote\"\n)\n\n// SpanSamplingResultAttr is an attribute conforming to the\n// otel.span.sampling_result semantic conventions. It represents the result value\n// of the sampler for this span.\ntype SpanSamplingResultAttr string\n\nvar (\n\t// SpanSamplingResultDrop is the span is not sampled and not recording.\n\tSpanSamplingResultDrop SpanSamplingResultAttr = \"DROP\"\n\t// SpanSamplingResultRecordOnly is the span is not sampled, but recording.\n\tSpanSamplingResultRecordOnly SpanSamplingResultAttr = \"RECORD_ONLY\"\n\t// SpanSamplingResultRecordAndSample is the span is sampled and recording.\n\tSpanSamplingResultRecordAndSample SpanSamplingResultAttr = \"RECORD_AND_SAMPLE\"\n)\n\n// SDKExporterLogExported is an instrument used to record metric values\n// conforming to the \"otel.sdk.exporter.log.exported\" semantic conventions. It\n// represents the number of log records for which the export has finished, either\n// successful or failed.\ntype SDKExporterLogExported struct {\n\tmetric.Int64Counter\n}\n\nvar newSDKExporterLogExportedOpts = []metric.Int64CounterOption{\n\tmetric.WithDescription(\"The number of log records for which the export has finished, either successful or failed.\"),\n\tmetric.WithUnit(\"{log_record}\"),\n}\n\n// NewSDKExporterLogExported returns a new SDKExporterLogExported instrument.\nfunc NewSDKExporterLogExported(\n\tm metric.Meter,\n\topt ...metric.Int64CounterOption,\n) (SDKExporterLogExported, error) {\n\t// Check if the meter is nil.\n\tif m == nil {\n\t\treturn SDKExporterLogExported{noop.Int64Counter{}}, nil\n\t}\n\n\tif len(opt) == 0 {\n\t\topt = newSDKExporterLogExportedOpts\n\t} else {\n\t\topt = append(opt, newSDKExporterLogExportedOpts...)\n\t}\n\n\ti, err := m.Int64Counter(\n\t\t\"otel.sdk.exporter.log.exported\",\n\t\topt...,\n\t)\n\tif err != nil {\n\t\treturn SDKExporterLogExported{noop.Int64Counter{}}, err\n\t}\n\treturn SDKExporterLogExported{i}, nil\n}\n\n// Inst returns the underlying metric instrument.\nfunc (m SDKExporterLogExported) Inst() metric.Int64Counter {\n\treturn m.Int64Counter\n}\n\n// Name returns the semantic convention name of the instrument.\nfunc (SDKExporterLogExported) Name() string {\n\treturn \"otel.sdk.exporter.log.exported\"\n}\n\n// Unit returns the semantic convention unit of the instrument\nfunc (SDKExporterLogExported) Unit() string {\n\treturn \"{log_record}\"\n}\n\n// Description returns the semantic convention description of the instrument\nfunc (SDKExporterLogExported) Description() string {\n\treturn \"The number of log records for which the export has finished, either successful or failed.\"\n}\n\n// Add adds incr to the existing count for attrs.\n//\n// All additional attrs passed are included in the recorded value.\n//\n// For successful exports, `error.type` MUST NOT be set. For failed exports,\n// `error.type` MUST contain the failure cause.\n// For exporters with partial success semantics (e.g. OTLP with\n// `rejected_log_records`), rejected log records MUST count as failed and only\n// non-rejected log records count as success.\n// If no rejection reason is available, `rejected` SHOULD be used as value for\n// `error.type`.\nfunc (m SDKExporterLogExported) Add(\n\tctx context.Context,\n\tincr int64,\n\tattrs ...attribute.KeyValue,\n) {\n\tif len(attrs) == 0 {\n\t\tm.Int64Counter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(\n\t\t*o,\n\t\tmetric.WithAttributes(\n\t\t\tattrs...,\n\t\t),\n\t)\n\n\tm.Int64Counter.Add(ctx, incr, *o...)\n}\n\n// AddSet adds incr to the existing count for set.\n//\n// For successful exports, `error.type` MUST NOT be set. For failed exports,\n// `error.type` MUST contain the failure cause.\n// For exporters with partial success semantics (e.g. OTLP with\n// `rejected_log_records`), rejected log records MUST count as failed and only\n// non-rejected log records count as success.\n// If no rejection reason is available, `rejected` SHOULD be used as value for\n// `error.type`.\nfunc (m SDKExporterLogExported) AddSet(ctx context.Context, incr int64, set attribute.Set) {\n\tif set.Len() == 0 {\n\t\tm.Int64Counter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(*o, metric.WithAttributeSet(set))\n\tm.Int64Counter.Add(ctx, incr, *o...)\n}\n\n// AttrErrorType returns an optional attribute for the \"error.type\" semantic\n// convention. It represents the describes a class of error the operation ended\n// with.\nfunc (SDKExporterLogExported) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"error.type\", string(val))\n}\n\n// AttrComponentName returns an optional attribute for the \"otel.component.name\"\n// semantic convention. It represents a name uniquely identifying the instance of\n// the OpenTelemetry component within its containing SDK instance.\nfunc (SDKExporterLogExported) AttrComponentName(val string) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.name\", val)\n}\n\n// AttrComponentType returns an optional attribute for the \"otel.component.type\"\n// semantic convention. It represents a name identifying the type of the\n// OpenTelemetry component.\nfunc (SDKExporterLogExported) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.type\", string(val))\n}\n\n// AttrServerAddress returns an optional attribute for the \"server.address\"\n// semantic convention. It represents the server domain name if available without\n// reverse DNS lookup; otherwise, IP address or Unix domain socket name.\nfunc (SDKExporterLogExported) AttrServerAddress(val string) attribute.KeyValue {\n\treturn attribute.String(\"server.address\", val)\n}\n\n// AttrServerPort returns an optional attribute for the \"server.port\" semantic\n// convention. It represents the server port number.\nfunc (SDKExporterLogExported) AttrServerPort(val int) attribute.KeyValue {\n\treturn attribute.Int(\"server.port\", val)\n}\n\n// SDKExporterLogInflight is an instrument used to record metric values\n// conforming to the \"otel.sdk.exporter.log.inflight\" semantic conventions. It\n// represents the number of log records which were passed to the exporter, but\n// that have not been exported yet (neither successful, nor failed).\ntype SDKExporterLogInflight struct {\n\tmetric.Int64UpDownCounter\n}\n\nvar newSDKExporterLogInflightOpts = []metric.Int64UpDownCounterOption{\n\tmetric.WithDescription(\"The number of log records which were passed to the exporter, but that have not been exported yet (neither successful, nor failed).\"),\n\tmetric.WithUnit(\"{log_record}\"),\n}\n\n// NewSDKExporterLogInflight returns a new SDKExporterLogInflight instrument.\nfunc NewSDKExporterLogInflight(\n\tm metric.Meter,\n\topt ...metric.Int64UpDownCounterOption,\n) (SDKExporterLogInflight, error) {\n\t// Check if the meter is nil.\n\tif m == nil {\n\t\treturn SDKExporterLogInflight{noop.Int64UpDownCounter{}}, nil\n\t}\n\n\tif len(opt) == 0 {\n\t\topt = newSDKExporterLogInflightOpts\n\t} else {\n\t\topt = append(opt, newSDKExporterLogInflightOpts...)\n\t}\n\n\ti, err := m.Int64UpDownCounter(\n\t\t\"otel.sdk.exporter.log.inflight\",\n\t\topt...,\n\t)\n\tif err != nil {\n\t\treturn SDKExporterLogInflight{noop.Int64UpDownCounter{}}, err\n\t}\n\treturn SDKExporterLogInflight{i}, nil\n}\n\n// Inst returns the underlying metric instrument.\nfunc (m SDKExporterLogInflight) Inst() metric.Int64UpDownCounter {\n\treturn m.Int64UpDownCounter\n}\n\n// Name returns the semantic convention name of the instrument.\nfunc (SDKExporterLogInflight) Name() string {\n\treturn \"otel.sdk.exporter.log.inflight\"\n}\n\n// Unit returns the semantic convention unit of the instrument\nfunc (SDKExporterLogInflight) Unit() string {\n\treturn \"{log_record}\"\n}\n\n// Description returns the semantic convention description of the instrument\nfunc (SDKExporterLogInflight) Description() string {\n\treturn \"The number of log records which were passed to the exporter, but that have not been exported yet (neither successful, nor failed).\"\n}\n\n// Add adds incr to the existing count for attrs.\n//\n// All additional attrs passed are included in the recorded value.\n//\n// For successful exports, `error.type` MUST NOT be set. For failed exports,\n// `error.type` MUST contain the failure cause.\nfunc (m SDKExporterLogInflight) Add(\n\tctx context.Context,\n\tincr int64,\n\tattrs ...attribute.KeyValue,\n) {\n\tif len(attrs) == 0 {\n\t\tm.Int64UpDownCounter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(\n\t\t*o,\n\t\tmetric.WithAttributes(\n\t\t\tattrs...,\n\t\t),\n\t)\n\n\tm.Int64UpDownCounter.Add(ctx, incr, *o...)\n}\n\n// AddSet adds incr to the existing count for set.\n//\n// For successful exports, `error.type` MUST NOT be set. For failed exports,\n// `error.type` MUST contain the failure cause.\nfunc (m SDKExporterLogInflight) AddSet(ctx context.Context, incr int64, set attribute.Set) {\n\tif set.Len() == 0 {\n\t\tm.Int64UpDownCounter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(*o, metric.WithAttributeSet(set))\n\tm.Int64UpDownCounter.Add(ctx, incr, *o...)\n}\n\n// AttrComponentName returns an optional attribute for the \"otel.component.name\"\n// semantic convention. It represents a name uniquely identifying the instance of\n// the OpenTelemetry component within its containing SDK instance.\nfunc (SDKExporterLogInflight) AttrComponentName(val string) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.name\", val)\n}\n\n// AttrComponentType returns an optional attribute for the \"otel.component.type\"\n// semantic convention. It represents a name identifying the type of the\n// OpenTelemetry component.\nfunc (SDKExporterLogInflight) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.type\", string(val))\n}\n\n// AttrServerAddress returns an optional attribute for the \"server.address\"\n// semantic convention. It represents the server domain name if available without\n// reverse DNS lookup; otherwise, IP address or Unix domain socket name.\nfunc (SDKExporterLogInflight) AttrServerAddress(val string) attribute.KeyValue {\n\treturn attribute.String(\"server.address\", val)\n}\n\n// AttrServerPort returns an optional attribute for the \"server.port\" semantic\n// convention. It represents the server port number.\nfunc (SDKExporterLogInflight) AttrServerPort(val int) attribute.KeyValue {\n\treturn attribute.Int(\"server.port\", val)\n}\n\n// SDKExporterMetricDataPointExported is an instrument used to record metric\n// values conforming to the \"otel.sdk.exporter.metric_data_point.exported\"\n// semantic conventions. It represents the number of metric data points for which\n// the export has finished, either successful or failed.\ntype SDKExporterMetricDataPointExported struct {\n\tmetric.Int64Counter\n}\n\nvar newSDKExporterMetricDataPointExportedOpts = []metric.Int64CounterOption{\n\tmetric.WithDescription(\"The number of metric data points for which the export has finished, either successful or failed.\"),\n\tmetric.WithUnit(\"{data_point}\"),\n}\n\n// NewSDKExporterMetricDataPointExported returns a new\n// SDKExporterMetricDataPointExported instrument.\nfunc NewSDKExporterMetricDataPointExported(\n\tm metric.Meter,\n\topt ...metric.Int64CounterOption,\n) (SDKExporterMetricDataPointExported, error) {\n\t// Check if the meter is nil.\n\tif m == nil {\n\t\treturn SDKExporterMetricDataPointExported{noop.Int64Counter{}}, nil\n\t}\n\n\tif len(opt) == 0 {\n\t\topt = newSDKExporterMetricDataPointExportedOpts\n\t} else {\n\t\topt = append(opt, newSDKExporterMetricDataPointExportedOpts...)\n\t}\n\n\ti, err := m.Int64Counter(\n\t\t\"otel.sdk.exporter.metric_data_point.exported\",\n\t\topt...,\n\t)\n\tif err != nil {\n\t\treturn SDKExporterMetricDataPointExported{noop.Int64Counter{}}, err\n\t}\n\treturn SDKExporterMetricDataPointExported{i}, nil\n}\n\n// Inst returns the underlying metric instrument.\nfunc (m SDKExporterMetricDataPointExported) Inst() metric.Int64Counter {\n\treturn m.Int64Counter\n}\n\n// Name returns the semantic convention name of the instrument.\nfunc (SDKExporterMetricDataPointExported) Name() string {\n\treturn \"otel.sdk.exporter.metric_data_point.exported\"\n}\n\n// Unit returns the semantic convention unit of the instrument\nfunc (SDKExporterMetricDataPointExported) Unit() string {\n\treturn \"{data_point}\"\n}\n\n// Description returns the semantic convention description of the instrument\nfunc (SDKExporterMetricDataPointExported) Description() string {\n\treturn \"The number of metric data points for which the export has finished, either successful or failed.\"\n}\n\n// Add adds incr to the existing count for attrs.\n//\n// All additional attrs passed are included in the recorded value.\n//\n// For successful exports, `error.type` MUST NOT be set. For failed exports,\n// `error.type` MUST contain the failure cause.\n// For exporters with partial success semantics (e.g. OTLP with\n// `rejected_data_points`), rejected data points MUST count as failed and only\n// non-rejected data points count as success.\n// If no rejection reason is available, `rejected` SHOULD be used as value for\n// `error.type`.\nfunc (m SDKExporterMetricDataPointExported) Add(\n\tctx context.Context,\n\tincr int64,\n\tattrs ...attribute.KeyValue,\n) {\n\tif len(attrs) == 0 {\n\t\tm.Int64Counter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(\n\t\t*o,\n\t\tmetric.WithAttributes(\n\t\t\tattrs...,\n\t\t),\n\t)\n\n\tm.Int64Counter.Add(ctx, incr, *o...)\n}\n\n// AddSet adds incr to the existing count for set.\n//\n// For successful exports, `error.type` MUST NOT be set. For failed exports,\n// `error.type` MUST contain the failure cause.\n// For exporters with partial success semantics (e.g. OTLP with\n// `rejected_data_points`), rejected data points MUST count as failed and only\n// non-rejected data points count as success.\n// If no rejection reason is available, `rejected` SHOULD be used as value for\n// `error.type`.\nfunc (m SDKExporterMetricDataPointExported) AddSet(ctx context.Context, incr int64, set attribute.Set) {\n\tif set.Len() == 0 {\n\t\tm.Int64Counter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(*o, metric.WithAttributeSet(set))\n\tm.Int64Counter.Add(ctx, incr, *o...)\n}\n\n// AttrErrorType returns an optional attribute for the \"error.type\" semantic\n// convention. It represents the describes a class of error the operation ended\n// with.\nfunc (SDKExporterMetricDataPointExported) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"error.type\", string(val))\n}\n\n// AttrComponentName returns an optional attribute for the \"otel.component.name\"\n// semantic convention. It represents a name uniquely identifying the instance of\n// the OpenTelemetry component within its containing SDK instance.\nfunc (SDKExporterMetricDataPointExported) AttrComponentName(val string) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.name\", val)\n}\n\n// AttrComponentType returns an optional attribute for the \"otel.component.type\"\n// semantic convention. It represents a name identifying the type of the\n// OpenTelemetry component.\nfunc (SDKExporterMetricDataPointExported) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.type\", string(val))\n}\n\n// AttrServerAddress returns an optional attribute for the \"server.address\"\n// semantic convention. It represents the server domain name if available without\n// reverse DNS lookup; otherwise, IP address or Unix domain socket name.\nfunc (SDKExporterMetricDataPointExported) AttrServerAddress(val string) attribute.KeyValue {\n\treturn attribute.String(\"server.address\", val)\n}\n\n// AttrServerPort returns an optional attribute for the \"server.port\" semantic\n// convention. It represents the server port number.\nfunc (SDKExporterMetricDataPointExported) AttrServerPort(val int) attribute.KeyValue {\n\treturn attribute.Int(\"server.port\", val)\n}\n\n// SDKExporterMetricDataPointInflight is an instrument used to record metric\n// values conforming to the \"otel.sdk.exporter.metric_data_point.inflight\"\n// semantic conventions. It represents the number of metric data points which\n// were passed to the exporter, but that have not been exported yet (neither\n// successful, nor failed).\ntype SDKExporterMetricDataPointInflight struct {\n\tmetric.Int64UpDownCounter\n}\n\nvar newSDKExporterMetricDataPointInflightOpts = []metric.Int64UpDownCounterOption{\n\tmetric.WithDescription(\"The number of metric data points which were passed to the exporter, but that have not been exported yet (neither successful, nor failed).\"),\n\tmetric.WithUnit(\"{data_point}\"),\n}\n\n// NewSDKExporterMetricDataPointInflight returns a new\n// SDKExporterMetricDataPointInflight instrument.\nfunc NewSDKExporterMetricDataPointInflight(\n\tm metric.Meter,\n\topt ...metric.Int64UpDownCounterOption,\n) (SDKExporterMetricDataPointInflight, error) {\n\t// Check if the meter is nil.\n\tif m == nil {\n\t\treturn SDKExporterMetricDataPointInflight{noop.Int64UpDownCounter{}}, nil\n\t}\n\n\tif len(opt) == 0 {\n\t\topt = newSDKExporterMetricDataPointInflightOpts\n\t} else {\n\t\topt = append(opt, newSDKExporterMetricDataPointInflightOpts...)\n\t}\n\n\ti, err := m.Int64UpDownCounter(\n\t\t\"otel.sdk.exporter.metric_data_point.inflight\",\n\t\topt...,\n\t)\n\tif err != nil {\n\t\treturn SDKExporterMetricDataPointInflight{noop.Int64UpDownCounter{}}, err\n\t}\n\treturn SDKExporterMetricDataPointInflight{i}, nil\n}\n\n// Inst returns the underlying metric instrument.\nfunc (m SDKExporterMetricDataPointInflight) Inst() metric.Int64UpDownCounter {\n\treturn m.Int64UpDownCounter\n}\n\n// Name returns the semantic convention name of the instrument.\nfunc (SDKExporterMetricDataPointInflight) Name() string {\n\treturn \"otel.sdk.exporter.metric_data_point.inflight\"\n}\n\n// Unit returns the semantic convention unit of the instrument\nfunc (SDKExporterMetricDataPointInflight) Unit() string {\n\treturn \"{data_point}\"\n}\n\n// Description returns the semantic convention description of the instrument\nfunc (SDKExporterMetricDataPointInflight) Description() string {\n\treturn \"The number of metric data points which were passed to the exporter, but that have not been exported yet (neither successful, nor failed).\"\n}\n\n// Add adds incr to the existing count for attrs.\n//\n// All additional attrs passed are included in the recorded value.\n//\n// For successful exports, `error.type` MUST NOT be set. For failed exports,\n// `error.type` MUST contain the failure cause.\nfunc (m SDKExporterMetricDataPointInflight) Add(\n\tctx context.Context,\n\tincr int64,\n\tattrs ...attribute.KeyValue,\n) {\n\tif len(attrs) == 0 {\n\t\tm.Int64UpDownCounter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(\n\t\t*o,\n\t\tmetric.WithAttributes(\n\t\t\tattrs...,\n\t\t),\n\t)\n\n\tm.Int64UpDownCounter.Add(ctx, incr, *o...)\n}\n\n// AddSet adds incr to the existing count for set.\n//\n// For successful exports, `error.type` MUST NOT be set. For failed exports,\n// `error.type` MUST contain the failure cause.\nfunc (m SDKExporterMetricDataPointInflight) AddSet(ctx context.Context, incr int64, set attribute.Set) {\n\tif set.Len() == 0 {\n\t\tm.Int64UpDownCounter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(*o, metric.WithAttributeSet(set))\n\tm.Int64UpDownCounter.Add(ctx, incr, *o...)\n}\n\n// AttrComponentName returns an optional attribute for the \"otel.component.name\"\n// semantic convention. It represents a name uniquely identifying the instance of\n// the OpenTelemetry component within its containing SDK instance.\nfunc (SDKExporterMetricDataPointInflight) AttrComponentName(val string) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.name\", val)\n}\n\n// AttrComponentType returns an optional attribute for the \"otel.component.type\"\n// semantic convention. It represents a name identifying the type of the\n// OpenTelemetry component.\nfunc (SDKExporterMetricDataPointInflight) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.type\", string(val))\n}\n\n// AttrServerAddress returns an optional attribute for the \"server.address\"\n// semantic convention. It represents the server domain name if available without\n// reverse DNS lookup; otherwise, IP address or Unix domain socket name.\nfunc (SDKExporterMetricDataPointInflight) AttrServerAddress(val string) attribute.KeyValue {\n\treturn attribute.String(\"server.address\", val)\n}\n\n// AttrServerPort returns an optional attribute for the \"server.port\" semantic\n// convention. It represents the server port number.\nfunc (SDKExporterMetricDataPointInflight) AttrServerPort(val int) attribute.KeyValue {\n\treturn attribute.Int(\"server.port\", val)\n}\n\n// SDKExporterOperationDuration is an instrument used to record metric values\n// conforming to the \"otel.sdk.exporter.operation.duration\" semantic conventions.\n// It represents the duration of exporting a batch of telemetry records.\ntype SDKExporterOperationDuration struct {\n\tmetric.Float64Histogram\n}\n\nvar newSDKExporterOperationDurationOpts = []metric.Float64HistogramOption{\n\tmetric.WithDescription(\"The duration of exporting a batch of telemetry records.\"),\n\tmetric.WithUnit(\"s\"),\n}\n\n// NewSDKExporterOperationDuration returns a new SDKExporterOperationDuration\n// instrument.\nfunc NewSDKExporterOperationDuration(\n\tm metric.Meter,\n\topt ...metric.Float64HistogramOption,\n) (SDKExporterOperationDuration, error) {\n\t// Check if the meter is nil.\n\tif m == nil {\n\t\treturn SDKExporterOperationDuration{noop.Float64Histogram{}}, nil\n\t}\n\n\tif len(opt) == 0 {\n\t\topt = newSDKExporterOperationDurationOpts\n\t} else {\n\t\topt = append(opt, newSDKExporterOperationDurationOpts...)\n\t}\n\n\ti, err := m.Float64Histogram(\n\t\t\"otel.sdk.exporter.operation.duration\",\n\t\topt...,\n\t)\n\tif err != nil {\n\t\treturn SDKExporterOperationDuration{noop.Float64Histogram{}}, err\n\t}\n\treturn SDKExporterOperationDuration{i}, nil\n}\n\n// Inst returns the underlying metric instrument.\nfunc (m SDKExporterOperationDuration) Inst() metric.Float64Histogram {\n\treturn m.Float64Histogram\n}\n\n// Name returns the semantic convention name of the instrument.\nfunc (SDKExporterOperationDuration) Name() string {\n\treturn \"otel.sdk.exporter.operation.duration\"\n}\n\n// Unit returns the semantic convention unit of the instrument\nfunc (SDKExporterOperationDuration) Unit() string {\n\treturn \"s\"\n}\n\n// Description returns the semantic convention description of the instrument\nfunc (SDKExporterOperationDuration) Description() string {\n\treturn \"The duration of exporting a batch of telemetry records.\"\n}\n\n// Record records val to the current distribution for attrs.\n//\n// All additional attrs passed are included in the recorded value.\n//\n// This metric defines successful operations using the full success definitions\n// for [http]\n// and [grpc]. Anything else is defined as an unsuccessful operation. For\n// successful\n// operations, `error.type` MUST NOT be set. For unsuccessful export operations,\n// `error.type` MUST contain a relevant failure cause.\n//\n// [http]: https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success-1\n// [grpc]: https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success\nfunc (m SDKExporterOperationDuration) Record(\n\tctx context.Context,\n\tval float64,\n\tattrs ...attribute.KeyValue,\n) {\n\tif len(attrs) == 0 {\n\t\tm.Float64Histogram.Record(ctx, val)\n\t\treturn\n\t}\n\n\to := recOptPool.Get().(*[]metric.RecordOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\trecOptPool.Put(o)\n\t}()\n\n\t*o = append(\n\t\t*o,\n\t\tmetric.WithAttributes(\n\t\t\tattrs...,\n\t\t),\n\t)\n\n\tm.Float64Histogram.Record(ctx, val, *o...)\n}\n\n// RecordSet records val to the current distribution for set.\n//\n// This metric defines successful operations using the full success definitions\n// for [http]\n// and [grpc]. Anything else is defined as an unsuccessful operation. For\n// successful\n// operations, `error.type` MUST NOT be set. For unsuccessful export operations,\n// `error.type` MUST contain a relevant failure cause.\n//\n// [http]: https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success-1\n// [grpc]: https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success\nfunc (m SDKExporterOperationDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) {\n\tif set.Len() == 0 {\n\t\tm.Float64Histogram.Record(ctx, val)\n\t\treturn\n\t}\n\n\to := recOptPool.Get().(*[]metric.RecordOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\trecOptPool.Put(o)\n\t}()\n\n\t*o = append(*o, metric.WithAttributeSet(set))\n\tm.Float64Histogram.Record(ctx, val, *o...)\n}\n\n// AttrErrorType returns an optional attribute for the \"error.type\" semantic\n// convention. It represents the describes a class of error the operation ended\n// with.\nfunc (SDKExporterOperationDuration) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"error.type\", string(val))\n}\n\n// AttrHTTPResponseStatusCode returns an optional attribute for the\n// \"http.response.status_code\" semantic convention. It represents the HTTP status\n// code of the last HTTP request performed in scope of this export call.\nfunc (SDKExporterOperationDuration) AttrHTTPResponseStatusCode(val int) attribute.KeyValue {\n\treturn attribute.Int(\"http.response.status_code\", val)\n}\n\n// AttrComponentName returns an optional attribute for the \"otel.component.name\"\n// semantic convention. It represents a name uniquely identifying the instance of\n// the OpenTelemetry component within its containing SDK instance.\nfunc (SDKExporterOperationDuration) AttrComponentName(val string) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.name\", val)\n}\n\n// AttrComponentType returns an optional attribute for the \"otel.component.type\"\n// semantic convention. It represents a name identifying the type of the\n// OpenTelemetry component.\nfunc (SDKExporterOperationDuration) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.type\", string(val))\n}\n\n// AttrRPCResponseStatusCode returns an optional attribute for the\n// \"rpc.response.status_code\" semantic convention. It represents the gRPC status\n// code of the last gRPC request performed in scope of this export call.\nfunc (SDKExporterOperationDuration) AttrRPCResponseStatusCode(val string) attribute.KeyValue {\n\treturn attribute.String(\"rpc.response.status_code\", val)\n}\n\n// AttrServerAddress returns an optional attribute for the \"server.address\"\n// semantic convention. It represents the server domain name if available without\n// reverse DNS lookup; otherwise, IP address or Unix domain socket name.\nfunc (SDKExporterOperationDuration) AttrServerAddress(val string) attribute.KeyValue {\n\treturn attribute.String(\"server.address\", val)\n}\n\n// AttrServerPort returns an optional attribute for the \"server.port\" semantic\n// convention. It represents the server port number.\nfunc (SDKExporterOperationDuration) AttrServerPort(val int) attribute.KeyValue {\n\treturn attribute.Int(\"server.port\", val)\n}\n\n// SDKExporterSpanExported is an instrument used to record metric values\n// conforming to the \"otel.sdk.exporter.span.exported\" semantic conventions. It\n// represents the number of spans for which the export has finished, either\n// successful or failed.\ntype SDKExporterSpanExported struct {\n\tmetric.Int64Counter\n}\n\nvar newSDKExporterSpanExportedOpts = []metric.Int64CounterOption{\n\tmetric.WithDescription(\"The number of spans for which the export has finished, either successful or failed.\"),\n\tmetric.WithUnit(\"{span}\"),\n}\n\n// NewSDKExporterSpanExported returns a new SDKExporterSpanExported instrument.\nfunc NewSDKExporterSpanExported(\n\tm metric.Meter,\n\topt ...metric.Int64CounterOption,\n) (SDKExporterSpanExported, error) {\n\t// Check if the meter is nil.\n\tif m == nil {\n\t\treturn SDKExporterSpanExported{noop.Int64Counter{}}, nil\n\t}\n\n\tif len(opt) == 0 {\n\t\topt = newSDKExporterSpanExportedOpts\n\t} else {\n\t\topt = append(opt, newSDKExporterSpanExportedOpts...)\n\t}\n\n\ti, err := m.Int64Counter(\n\t\t\"otel.sdk.exporter.span.exported\",\n\t\topt...,\n\t)\n\tif err != nil {\n\t\treturn SDKExporterSpanExported{noop.Int64Counter{}}, err\n\t}\n\treturn SDKExporterSpanExported{i}, nil\n}\n\n// Inst returns the underlying metric instrument.\nfunc (m SDKExporterSpanExported) Inst() metric.Int64Counter {\n\treturn m.Int64Counter\n}\n\n// Name returns the semantic convention name of the instrument.\nfunc (SDKExporterSpanExported) Name() string {\n\treturn \"otel.sdk.exporter.span.exported\"\n}\n\n// Unit returns the semantic convention unit of the instrument\nfunc (SDKExporterSpanExported) Unit() string {\n\treturn \"{span}\"\n}\n\n// Description returns the semantic convention description of the instrument\nfunc (SDKExporterSpanExported) Description() string {\n\treturn \"The number of spans for which the export has finished, either successful or failed.\"\n}\n\n// Add adds incr to the existing count for attrs.\n//\n// All additional attrs passed are included in the recorded value.\n//\n// For successful exports, `error.type` MUST NOT be set. For failed exports,\n// `error.type` MUST contain the failure cause.\n// For exporters with partial success semantics (e.g. OTLP with `rejected_spans`\n// ), rejected spans MUST count as failed and only non-rejected spans count as\n// success.\n// If no rejection reason is available, `rejected` SHOULD be used as value for\n// `error.type`.\nfunc (m SDKExporterSpanExported) Add(\n\tctx context.Context,\n\tincr int64,\n\tattrs ...attribute.KeyValue,\n) {\n\tif len(attrs) == 0 {\n\t\tm.Int64Counter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(\n\t\t*o,\n\t\tmetric.WithAttributes(\n\t\t\tattrs...,\n\t\t),\n\t)\n\n\tm.Int64Counter.Add(ctx, incr, *o...)\n}\n\n// AddSet adds incr to the existing count for set.\n//\n// For successful exports, `error.type` MUST NOT be set. For failed exports,\n// `error.type` MUST contain the failure cause.\n// For exporters with partial success semantics (e.g. OTLP with `rejected_spans`\n// ), rejected spans MUST count as failed and only non-rejected spans count as\n// success.\n// If no rejection reason is available, `rejected` SHOULD be used as value for\n// `error.type`.\nfunc (m SDKExporterSpanExported) AddSet(ctx context.Context, incr int64, set attribute.Set) {\n\tif set.Len() == 0 {\n\t\tm.Int64Counter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(*o, metric.WithAttributeSet(set))\n\tm.Int64Counter.Add(ctx, incr, *o...)\n}\n\n// AttrErrorType returns an optional attribute for the \"error.type\" semantic\n// convention. It represents the describes a class of error the operation ended\n// with.\nfunc (SDKExporterSpanExported) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"error.type\", string(val))\n}\n\n// AttrComponentName returns an optional attribute for the \"otel.component.name\"\n// semantic convention. It represents a name uniquely identifying the instance of\n// the OpenTelemetry component within its containing SDK instance.\nfunc (SDKExporterSpanExported) AttrComponentName(val string) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.name\", val)\n}\n\n// AttrComponentType returns an optional attribute for the \"otel.component.type\"\n// semantic convention. It represents a name identifying the type of the\n// OpenTelemetry component.\nfunc (SDKExporterSpanExported) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.type\", string(val))\n}\n\n// AttrServerAddress returns an optional attribute for the \"server.address\"\n// semantic convention. It represents the server domain name if available without\n// reverse DNS lookup; otherwise, IP address or Unix domain socket name.\nfunc (SDKExporterSpanExported) AttrServerAddress(val string) attribute.KeyValue {\n\treturn attribute.String(\"server.address\", val)\n}\n\n// AttrServerPort returns an optional attribute for the \"server.port\" semantic\n// convention. It represents the server port number.\nfunc (SDKExporterSpanExported) AttrServerPort(val int) attribute.KeyValue {\n\treturn attribute.Int(\"server.port\", val)\n}\n\n// SDKExporterSpanInflight is an instrument used to record metric values\n// conforming to the \"otel.sdk.exporter.span.inflight\" semantic conventions. It\n// represents the number of spans which were passed to the exporter, but that\n// have not been exported yet (neither successful, nor failed).\ntype SDKExporterSpanInflight struct {\n\tmetric.Int64UpDownCounter\n}\n\nvar newSDKExporterSpanInflightOpts = []metric.Int64UpDownCounterOption{\n\tmetric.WithDescription(\"The number of spans which were passed to the exporter, but that have not been exported yet (neither successful, nor failed).\"),\n\tmetric.WithUnit(\"{span}\"),\n}\n\n// NewSDKExporterSpanInflight returns a new SDKExporterSpanInflight instrument.\nfunc NewSDKExporterSpanInflight(\n\tm metric.Meter,\n\topt ...metric.Int64UpDownCounterOption,\n) (SDKExporterSpanInflight, error) {\n\t// Check if the meter is nil.\n\tif m == nil {\n\t\treturn SDKExporterSpanInflight{noop.Int64UpDownCounter{}}, nil\n\t}\n\n\tif len(opt) == 0 {\n\t\topt = newSDKExporterSpanInflightOpts\n\t} else {\n\t\topt = append(opt, newSDKExporterSpanInflightOpts...)\n\t}\n\n\ti, err := m.Int64UpDownCounter(\n\t\t\"otel.sdk.exporter.span.inflight\",\n\t\topt...,\n\t)\n\tif err != nil {\n\t\treturn SDKExporterSpanInflight{noop.Int64UpDownCounter{}}, err\n\t}\n\treturn SDKExporterSpanInflight{i}, nil\n}\n\n// Inst returns the underlying metric instrument.\nfunc (m SDKExporterSpanInflight) Inst() metric.Int64UpDownCounter {\n\treturn m.Int64UpDownCounter\n}\n\n// Name returns the semantic convention name of the instrument.\nfunc (SDKExporterSpanInflight) Name() string {\n\treturn \"otel.sdk.exporter.span.inflight\"\n}\n\n// Unit returns the semantic convention unit of the instrument\nfunc (SDKExporterSpanInflight) Unit() string {\n\treturn \"{span}\"\n}\n\n// Description returns the semantic convention description of the instrument\nfunc (SDKExporterSpanInflight) Description() string {\n\treturn \"The number of spans which were passed to the exporter, but that have not been exported yet (neither successful, nor failed).\"\n}\n\n// Add adds incr to the existing count for attrs.\n//\n// All additional attrs passed are included in the recorded value.\n//\n// For successful exports, `error.type` MUST NOT be set. For failed exports,\n// `error.type` MUST contain the failure cause.\nfunc (m SDKExporterSpanInflight) Add(\n\tctx context.Context,\n\tincr int64,\n\tattrs ...attribute.KeyValue,\n) {\n\tif len(attrs) == 0 {\n\t\tm.Int64UpDownCounter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(\n\t\t*o,\n\t\tmetric.WithAttributes(\n\t\t\tattrs...,\n\t\t),\n\t)\n\n\tm.Int64UpDownCounter.Add(ctx, incr, *o...)\n}\n\n// AddSet adds incr to the existing count for set.\n//\n// For successful exports, `error.type` MUST NOT be set. For failed exports,\n// `error.type` MUST contain the failure cause.\nfunc (m SDKExporterSpanInflight) AddSet(ctx context.Context, incr int64, set attribute.Set) {\n\tif set.Len() == 0 {\n\t\tm.Int64UpDownCounter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(*o, metric.WithAttributeSet(set))\n\tm.Int64UpDownCounter.Add(ctx, incr, *o...)\n}\n\n// AttrComponentName returns an optional attribute for the \"otel.component.name\"\n// semantic convention. It represents a name uniquely identifying the instance of\n// the OpenTelemetry component within its containing SDK instance.\nfunc (SDKExporterSpanInflight) AttrComponentName(val string) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.name\", val)\n}\n\n// AttrComponentType returns an optional attribute for the \"otel.component.type\"\n// semantic convention. It represents a name identifying the type of the\n// OpenTelemetry component.\nfunc (SDKExporterSpanInflight) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.type\", string(val))\n}\n\n// AttrServerAddress returns an optional attribute for the \"server.address\"\n// semantic convention. It represents the server domain name if available without\n// reverse DNS lookup; otherwise, IP address or Unix domain socket name.\nfunc (SDKExporterSpanInflight) AttrServerAddress(val string) attribute.KeyValue {\n\treturn attribute.String(\"server.address\", val)\n}\n\n// AttrServerPort returns an optional attribute for the \"server.port\" semantic\n// convention. It represents the server port number.\nfunc (SDKExporterSpanInflight) AttrServerPort(val int) attribute.KeyValue {\n\treturn attribute.Int(\"server.port\", val)\n}\n\n// SDKLogCreated is an instrument used to record metric values conforming to the\n// \"otel.sdk.log.created\" semantic conventions. It represents the number of logs\n// submitted to enabled SDK Loggers.\ntype SDKLogCreated struct {\n\tmetric.Int64Counter\n}\n\nvar newSDKLogCreatedOpts = []metric.Int64CounterOption{\n\tmetric.WithDescription(\"The number of logs submitted to enabled SDK Loggers.\"),\n\tmetric.WithUnit(\"{log_record}\"),\n}\n\n// NewSDKLogCreated returns a new SDKLogCreated instrument.\nfunc NewSDKLogCreated(\n\tm metric.Meter,\n\topt ...metric.Int64CounterOption,\n) (SDKLogCreated, error) {\n\t// Check if the meter is nil.\n\tif m == nil {\n\t\treturn SDKLogCreated{noop.Int64Counter{}}, nil\n\t}\n\n\tif len(opt) == 0 {\n\t\topt = newSDKLogCreatedOpts\n\t} else {\n\t\topt = append(opt, newSDKLogCreatedOpts...)\n\t}\n\n\ti, err := m.Int64Counter(\n\t\t\"otel.sdk.log.created\",\n\t\topt...,\n\t)\n\tif err != nil {\n\t\treturn SDKLogCreated{noop.Int64Counter{}}, err\n\t}\n\treturn SDKLogCreated{i}, nil\n}\n\n// Inst returns the underlying metric instrument.\nfunc (m SDKLogCreated) Inst() metric.Int64Counter {\n\treturn m.Int64Counter\n}\n\n// Name returns the semantic convention name of the instrument.\nfunc (SDKLogCreated) Name() string {\n\treturn \"otel.sdk.log.created\"\n}\n\n// Unit returns the semantic convention unit of the instrument\nfunc (SDKLogCreated) Unit() string {\n\treturn \"{log_record}\"\n}\n\n// Description returns the semantic convention description of the instrument\nfunc (SDKLogCreated) Description() string {\n\treturn \"The number of logs submitted to enabled SDK Loggers.\"\n}\n\n// Add adds incr to the existing count for attrs.\nfunc (m SDKLogCreated) Add(ctx context.Context, incr int64, attrs ...attribute.KeyValue) {\n\tif len(attrs) == 0 {\n\t\tm.Int64Counter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(*o, metric.WithAttributes(attrs...))\n\tm.Int64Counter.Add(ctx, incr, *o...)\n}\n\n// AddSet adds incr to the existing count for set.\nfunc (m SDKLogCreated) AddSet(ctx context.Context, incr int64, set attribute.Set) {\n\tif set.Len() == 0 {\n\t\tm.Int64Counter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(*o, metric.WithAttributeSet(set))\n\tm.Int64Counter.Add(ctx, incr, *o...)\n}\n\n// SDKMetricReaderCollectionDuration is an instrument used to record metric\n// values conforming to the \"otel.sdk.metric_reader.collection.duration\" semantic\n// conventions. It represents the duration of the collect operation of the metric\n// reader.\ntype SDKMetricReaderCollectionDuration struct {\n\tmetric.Float64Histogram\n}\n\nvar newSDKMetricReaderCollectionDurationOpts = []metric.Float64HistogramOption{\n\tmetric.WithDescription(\"The duration of the collect operation of the metric reader.\"),\n\tmetric.WithUnit(\"s\"),\n}\n\n// NewSDKMetricReaderCollectionDuration returns a new\n// SDKMetricReaderCollectionDuration instrument.\nfunc NewSDKMetricReaderCollectionDuration(\n\tm metric.Meter,\n\topt ...metric.Float64HistogramOption,\n) (SDKMetricReaderCollectionDuration, error) {\n\t// Check if the meter is nil.\n\tif m == nil {\n\t\treturn SDKMetricReaderCollectionDuration{noop.Float64Histogram{}}, nil\n\t}\n\n\tif len(opt) == 0 {\n\t\topt = newSDKMetricReaderCollectionDurationOpts\n\t} else {\n\t\topt = append(opt, newSDKMetricReaderCollectionDurationOpts...)\n\t}\n\n\ti, err := m.Float64Histogram(\n\t\t\"otel.sdk.metric_reader.collection.duration\",\n\t\topt...,\n\t)\n\tif err != nil {\n\t\treturn SDKMetricReaderCollectionDuration{noop.Float64Histogram{}}, err\n\t}\n\treturn SDKMetricReaderCollectionDuration{i}, nil\n}\n\n// Inst returns the underlying metric instrument.\nfunc (m SDKMetricReaderCollectionDuration) Inst() metric.Float64Histogram {\n\treturn m.Float64Histogram\n}\n\n// Name returns the semantic convention name of the instrument.\nfunc (SDKMetricReaderCollectionDuration) Name() string {\n\treturn \"otel.sdk.metric_reader.collection.duration\"\n}\n\n// Unit returns the semantic convention unit of the instrument\nfunc (SDKMetricReaderCollectionDuration) Unit() string {\n\treturn \"s\"\n}\n\n// Description returns the semantic convention description of the instrument\nfunc (SDKMetricReaderCollectionDuration) Description() string {\n\treturn \"The duration of the collect operation of the metric reader.\"\n}\n\n// Record records val to the current distribution for attrs.\n//\n// All additional attrs passed are included in the recorded value.\n//\n// For successful collections, `error.type` MUST NOT be set. For failed\n// collections, `error.type` SHOULD contain the failure cause.\n// It can happen that metrics collection is successful for some MetricProducers,\n// while others fail. In that case `error.type` SHOULD be set to any of the\n// failure causes.\nfunc (m SDKMetricReaderCollectionDuration) Record(\n\tctx context.Context,\n\tval float64,\n\tattrs ...attribute.KeyValue,\n) {\n\tif len(attrs) == 0 {\n\t\tm.Float64Histogram.Record(ctx, val)\n\t\treturn\n\t}\n\n\to := recOptPool.Get().(*[]metric.RecordOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\trecOptPool.Put(o)\n\t}()\n\n\t*o = append(\n\t\t*o,\n\t\tmetric.WithAttributes(\n\t\t\tattrs...,\n\t\t),\n\t)\n\n\tm.Float64Histogram.Record(ctx, val, *o...)\n}\n\n// RecordSet records val to the current distribution for set.\n//\n// For successful collections, `error.type` MUST NOT be set. For failed\n// collections, `error.type` SHOULD contain the failure cause.\n// It can happen that metrics collection is successful for some MetricProducers,\n// while others fail. In that case `error.type` SHOULD be set to any of the\n// failure causes.\nfunc (m SDKMetricReaderCollectionDuration) RecordSet(ctx context.Context, val float64, set attribute.Set) {\n\tif set.Len() == 0 {\n\t\tm.Float64Histogram.Record(ctx, val)\n\t\treturn\n\t}\n\n\to := recOptPool.Get().(*[]metric.RecordOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\trecOptPool.Put(o)\n\t}()\n\n\t*o = append(*o, metric.WithAttributeSet(set))\n\tm.Float64Histogram.Record(ctx, val, *o...)\n}\n\n// AttrErrorType returns an optional attribute for the \"error.type\" semantic\n// convention. It represents the describes a class of error the operation ended\n// with.\nfunc (SDKMetricReaderCollectionDuration) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"error.type\", string(val))\n}\n\n// AttrComponentName returns an optional attribute for the \"otel.component.name\"\n// semantic convention. It represents a name uniquely identifying the instance of\n// the OpenTelemetry component within its containing SDK instance.\nfunc (SDKMetricReaderCollectionDuration) AttrComponentName(val string) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.name\", val)\n}\n\n// AttrComponentType returns an optional attribute for the \"otel.component.type\"\n// semantic convention. It represents a name identifying the type of the\n// OpenTelemetry component.\nfunc (SDKMetricReaderCollectionDuration) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.type\", string(val))\n}\n\n// SDKProcessorLogProcessed is an instrument used to record metric values\n// conforming to the \"otel.sdk.processor.log.processed\" semantic conventions. It\n// represents the number of log records for which the processing has finished,\n// either successful or failed.\ntype SDKProcessorLogProcessed struct {\n\tmetric.Int64Counter\n}\n\nvar newSDKProcessorLogProcessedOpts = []metric.Int64CounterOption{\n\tmetric.WithDescription(\"The number of log records for which the processing has finished, either successful or failed.\"),\n\tmetric.WithUnit(\"{log_record}\"),\n}\n\n// NewSDKProcessorLogProcessed returns a new SDKProcessorLogProcessed instrument.\nfunc NewSDKProcessorLogProcessed(\n\tm metric.Meter,\n\topt ...metric.Int64CounterOption,\n) (SDKProcessorLogProcessed, error) {\n\t// Check if the meter is nil.\n\tif m == nil {\n\t\treturn SDKProcessorLogProcessed{noop.Int64Counter{}}, nil\n\t}\n\n\tif len(opt) == 0 {\n\t\topt = newSDKProcessorLogProcessedOpts\n\t} else {\n\t\topt = append(opt, newSDKProcessorLogProcessedOpts...)\n\t}\n\n\ti, err := m.Int64Counter(\n\t\t\"otel.sdk.processor.log.processed\",\n\t\topt...,\n\t)\n\tif err != nil {\n\t\treturn SDKProcessorLogProcessed{noop.Int64Counter{}}, err\n\t}\n\treturn SDKProcessorLogProcessed{i}, nil\n}\n\n// Inst returns the underlying metric instrument.\nfunc (m SDKProcessorLogProcessed) Inst() metric.Int64Counter {\n\treturn m.Int64Counter\n}\n\n// Name returns the semantic convention name of the instrument.\nfunc (SDKProcessorLogProcessed) Name() string {\n\treturn \"otel.sdk.processor.log.processed\"\n}\n\n// Unit returns the semantic convention unit of the instrument\nfunc (SDKProcessorLogProcessed) Unit() string {\n\treturn \"{log_record}\"\n}\n\n// Description returns the semantic convention description of the instrument\nfunc (SDKProcessorLogProcessed) Description() string {\n\treturn \"The number of log records for which the processing has finished, either successful or failed.\"\n}\n\n// Add adds incr to the existing count for attrs.\n//\n// All additional attrs passed are included in the recorded value.\n//\n// For successful processing, `error.type` MUST NOT be set. For failed\n// processing, `error.type` MUST contain the failure cause.\n// For the SDK Simple and Batching Log Record Processor a log record is\n// considered to be processed already when it has been submitted to the exporter,\n// not when the corresponding export call has finished.\nfunc (m SDKProcessorLogProcessed) Add(\n\tctx context.Context,\n\tincr int64,\n\tattrs ...attribute.KeyValue,\n) {\n\tif len(attrs) == 0 {\n\t\tm.Int64Counter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(\n\t\t*o,\n\t\tmetric.WithAttributes(\n\t\t\tattrs...,\n\t\t),\n\t)\n\n\tm.Int64Counter.Add(ctx, incr, *o...)\n}\n\n// AddSet adds incr to the existing count for set.\n//\n// For successful processing, `error.type` MUST NOT be set. For failed\n// processing, `error.type` MUST contain the failure cause.\n// For the SDK Simple and Batching Log Record Processor a log record is\n// considered to be processed already when it has been submitted to the exporter,\n// not when the corresponding export call has finished.\nfunc (m SDKProcessorLogProcessed) AddSet(ctx context.Context, incr int64, set attribute.Set) {\n\tif set.Len() == 0 {\n\t\tm.Int64Counter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(*o, metric.WithAttributeSet(set))\n\tm.Int64Counter.Add(ctx, incr, *o...)\n}\n\n// AttrErrorType returns an optional attribute for the \"error.type\" semantic\n// convention. It represents a low-cardinality description of the failure reason.\n// SDK Batching Log Record Processors MUST use `queue_full` for log records\n// dropped due to a full queue.\nfunc (SDKProcessorLogProcessed) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"error.type\", string(val))\n}\n\n// AttrComponentName returns an optional attribute for the \"otel.component.name\"\n// semantic convention. It represents a name uniquely identifying the instance of\n// the OpenTelemetry component within its containing SDK instance.\nfunc (SDKProcessorLogProcessed) AttrComponentName(val string) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.name\", val)\n}\n\n// AttrComponentType returns an optional attribute for the \"otel.component.type\"\n// semantic convention. It represents a name identifying the type of the\n// OpenTelemetry component.\nfunc (SDKProcessorLogProcessed) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.type\", string(val))\n}\n\n// SDKProcessorLogQueueCapacity is an instrument used to record metric values\n// conforming to the \"otel.sdk.processor.log.queue.capacity\" semantic\n// conventions. It represents the maximum number of log records the queue of a\n// given instance of an SDK Log Record processor can hold.\ntype SDKProcessorLogQueueCapacity struct {\n\tmetric.Int64ObservableUpDownCounter\n}\n\nvar newSDKProcessorLogQueueCapacityOpts = []metric.Int64ObservableUpDownCounterOption{\n\tmetric.WithDescription(\"The maximum number of log records the queue of a given instance of an SDK Log Record processor can hold.\"),\n\tmetric.WithUnit(\"{log_record}\"),\n}\n\n// NewSDKProcessorLogQueueCapacity returns a new SDKProcessorLogQueueCapacity\n// instrument.\nfunc NewSDKProcessorLogQueueCapacity(\n\tm metric.Meter,\n\topt ...metric.Int64ObservableUpDownCounterOption,\n) (SDKProcessorLogQueueCapacity, error) {\n\t// Check if the meter is nil.\n\tif m == nil {\n\t\treturn SDKProcessorLogQueueCapacity{noop.Int64ObservableUpDownCounter{}}, nil\n\t}\n\n\tif len(opt) == 0 {\n\t\topt = newSDKProcessorLogQueueCapacityOpts\n\t} else {\n\t\topt = append(opt, newSDKProcessorLogQueueCapacityOpts...)\n\t}\n\n\ti, err := m.Int64ObservableUpDownCounter(\n\t\t\"otel.sdk.processor.log.queue.capacity\",\n\t\topt...,\n\t)\n\tif err != nil {\n\t\treturn SDKProcessorLogQueueCapacity{noop.Int64ObservableUpDownCounter{}}, err\n\t}\n\treturn SDKProcessorLogQueueCapacity{i}, nil\n}\n\n// Inst returns the underlying metric instrument.\nfunc (m SDKProcessorLogQueueCapacity) Inst() metric.Int64ObservableUpDownCounter {\n\treturn m.Int64ObservableUpDownCounter\n}\n\n// Name returns the semantic convention name of the instrument.\nfunc (SDKProcessorLogQueueCapacity) Name() string {\n\treturn \"otel.sdk.processor.log.queue.capacity\"\n}\n\n// Unit returns the semantic convention unit of the instrument\nfunc (SDKProcessorLogQueueCapacity) Unit() string {\n\treturn \"{log_record}\"\n}\n\n// Description returns the semantic convention description of the instrument\nfunc (SDKProcessorLogQueueCapacity) Description() string {\n\treturn \"The maximum number of log records the queue of a given instance of an SDK Log Record processor can hold.\"\n}\n\n// AttrComponentName returns an optional attribute for the \"otel.component.name\"\n// semantic convention. It represents a name uniquely identifying the instance of\n// the OpenTelemetry component within its containing SDK instance.\nfunc (SDKProcessorLogQueueCapacity) AttrComponentName(val string) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.name\", val)\n}\n\n// AttrComponentType returns an optional attribute for the \"otel.component.type\"\n// semantic convention. It represents a name identifying the type of the\n// OpenTelemetry component.\nfunc (SDKProcessorLogQueueCapacity) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.type\", string(val))\n}\n\n// SDKProcessorLogQueueSize is an instrument used to record metric values\n// conforming to the \"otel.sdk.processor.log.queue.size\" semantic conventions. It\n// represents the number of log records in the queue of a given instance of an\n// SDK log processor.\ntype SDKProcessorLogQueueSize struct {\n\tmetric.Int64ObservableUpDownCounter\n}\n\nvar newSDKProcessorLogQueueSizeOpts = []metric.Int64ObservableUpDownCounterOption{\n\tmetric.WithDescription(\"The number of log records in the queue of a given instance of an SDK log processor.\"),\n\tmetric.WithUnit(\"{log_record}\"),\n}\n\n// NewSDKProcessorLogQueueSize returns a new SDKProcessorLogQueueSize instrument.\nfunc NewSDKProcessorLogQueueSize(\n\tm metric.Meter,\n\topt ...metric.Int64ObservableUpDownCounterOption,\n) (SDKProcessorLogQueueSize, error) {\n\t// Check if the meter is nil.\n\tif m == nil {\n\t\treturn SDKProcessorLogQueueSize{noop.Int64ObservableUpDownCounter{}}, nil\n\t}\n\n\tif len(opt) == 0 {\n\t\topt = newSDKProcessorLogQueueSizeOpts\n\t} else {\n\t\topt = append(opt, newSDKProcessorLogQueueSizeOpts...)\n\t}\n\n\ti, err := m.Int64ObservableUpDownCounter(\n\t\t\"otel.sdk.processor.log.queue.size\",\n\t\topt...,\n\t)\n\tif err != nil {\n\t\treturn SDKProcessorLogQueueSize{noop.Int64ObservableUpDownCounter{}}, err\n\t}\n\treturn SDKProcessorLogQueueSize{i}, nil\n}\n\n// Inst returns the underlying metric instrument.\nfunc (m SDKProcessorLogQueueSize) Inst() metric.Int64ObservableUpDownCounter {\n\treturn m.Int64ObservableUpDownCounter\n}\n\n// Name returns the semantic convention name of the instrument.\nfunc (SDKProcessorLogQueueSize) Name() string {\n\treturn \"otel.sdk.processor.log.queue.size\"\n}\n\n// Unit returns the semantic convention unit of the instrument\nfunc (SDKProcessorLogQueueSize) Unit() string {\n\treturn \"{log_record}\"\n}\n\n// Description returns the semantic convention description of the instrument\nfunc (SDKProcessorLogQueueSize) Description() string {\n\treturn \"The number of log records in the queue of a given instance of an SDK log processor.\"\n}\n\n// AttrComponentName returns an optional attribute for the \"otel.component.name\"\n// semantic convention. It represents a name uniquely identifying the instance of\n// the OpenTelemetry component within its containing SDK instance.\nfunc (SDKProcessorLogQueueSize) AttrComponentName(val string) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.name\", val)\n}\n\n// AttrComponentType returns an optional attribute for the \"otel.component.type\"\n// semantic convention. It represents a name identifying the type of the\n// OpenTelemetry component.\nfunc (SDKProcessorLogQueueSize) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.type\", string(val))\n}\n\n// SDKProcessorSpanProcessed is an instrument used to record metric values\n// conforming to the \"otel.sdk.processor.span.processed\" semantic conventions. It\n// represents the number of spans for which the processing has finished, either\n// successful or failed.\ntype SDKProcessorSpanProcessed struct {\n\tmetric.Int64Counter\n}\n\nvar newSDKProcessorSpanProcessedOpts = []metric.Int64CounterOption{\n\tmetric.WithDescription(\"The number of spans for which the processing has finished, either successful or failed.\"),\n\tmetric.WithUnit(\"{span}\"),\n}\n\n// NewSDKProcessorSpanProcessed returns a new SDKProcessorSpanProcessed\n// instrument.\nfunc NewSDKProcessorSpanProcessed(\n\tm metric.Meter,\n\topt ...metric.Int64CounterOption,\n) (SDKProcessorSpanProcessed, error) {\n\t// Check if the meter is nil.\n\tif m == nil {\n\t\treturn SDKProcessorSpanProcessed{noop.Int64Counter{}}, nil\n\t}\n\n\tif len(opt) == 0 {\n\t\topt = newSDKProcessorSpanProcessedOpts\n\t} else {\n\t\topt = append(opt, newSDKProcessorSpanProcessedOpts...)\n\t}\n\n\ti, err := m.Int64Counter(\n\t\t\"otel.sdk.processor.span.processed\",\n\t\topt...,\n\t)\n\tif err != nil {\n\t\treturn SDKProcessorSpanProcessed{noop.Int64Counter{}}, err\n\t}\n\treturn SDKProcessorSpanProcessed{i}, nil\n}\n\n// Inst returns the underlying metric instrument.\nfunc (m SDKProcessorSpanProcessed) Inst() metric.Int64Counter {\n\treturn m.Int64Counter\n}\n\n// Name returns the semantic convention name of the instrument.\nfunc (SDKProcessorSpanProcessed) Name() string {\n\treturn \"otel.sdk.processor.span.processed\"\n}\n\n// Unit returns the semantic convention unit of the instrument\nfunc (SDKProcessorSpanProcessed) Unit() string {\n\treturn \"{span}\"\n}\n\n// Description returns the semantic convention description of the instrument\nfunc (SDKProcessorSpanProcessed) Description() string {\n\treturn \"The number of spans for which the processing has finished, either successful or failed.\"\n}\n\n// Add adds incr to the existing count for attrs.\n//\n// All additional attrs passed are included in the recorded value.\n//\n// For successful processing, `error.type` MUST NOT be set. For failed\n// processing, `error.type` MUST contain the failure cause.\n// For the SDK Simple and Batching Span Processor a span is considered to be\n// processed already when it has been submitted to the exporter, not when the\n// corresponding export call has finished.\nfunc (m SDKProcessorSpanProcessed) Add(\n\tctx context.Context,\n\tincr int64,\n\tattrs ...attribute.KeyValue,\n) {\n\tif len(attrs) == 0 {\n\t\tm.Int64Counter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(\n\t\t*o,\n\t\tmetric.WithAttributes(\n\t\t\tattrs...,\n\t\t),\n\t)\n\n\tm.Int64Counter.Add(ctx, incr, *o...)\n}\n\n// AddSet adds incr to the existing count for set.\n//\n// For successful processing, `error.type` MUST NOT be set. For failed\n// processing, `error.type` MUST contain the failure cause.\n// For the SDK Simple and Batching Span Processor a span is considered to be\n// processed already when it has been submitted to the exporter, not when the\n// corresponding export call has finished.\nfunc (m SDKProcessorSpanProcessed) AddSet(ctx context.Context, incr int64, set attribute.Set) {\n\tif set.Len() == 0 {\n\t\tm.Int64Counter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(*o, metric.WithAttributeSet(set))\n\tm.Int64Counter.Add(ctx, incr, *o...)\n}\n\n// AttrErrorType returns an optional attribute for the \"error.type\" semantic\n// convention. It represents a low-cardinality description of the failure reason.\n// SDK Batching Span Processors MUST use `queue_full` for spans dropped due to a\n// full queue.\nfunc (SDKProcessorSpanProcessed) AttrErrorType(val ErrorTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"error.type\", string(val))\n}\n\n// AttrComponentName returns an optional attribute for the \"otel.component.name\"\n// semantic convention. It represents a name uniquely identifying the instance of\n// the OpenTelemetry component within its containing SDK instance.\nfunc (SDKProcessorSpanProcessed) AttrComponentName(val string) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.name\", val)\n}\n\n// AttrComponentType returns an optional attribute for the \"otel.component.type\"\n// semantic convention. It represents a name identifying the type of the\n// OpenTelemetry component.\nfunc (SDKProcessorSpanProcessed) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.type\", string(val))\n}\n\n// SDKProcessorSpanQueueCapacity is an instrument used to record metric values\n// conforming to the \"otel.sdk.processor.span.queue.capacity\" semantic\n// conventions. It represents the maximum number of spans the queue of a given\n// instance of an SDK span processor can hold.\ntype SDKProcessorSpanQueueCapacity struct {\n\tmetric.Int64ObservableUpDownCounter\n}\n\nvar newSDKProcessorSpanQueueCapacityOpts = []metric.Int64ObservableUpDownCounterOption{\n\tmetric.WithDescription(\"The maximum number of spans the queue of a given instance of an SDK span processor can hold.\"),\n\tmetric.WithUnit(\"{span}\"),\n}\n\n// NewSDKProcessorSpanQueueCapacity returns a new SDKProcessorSpanQueueCapacity\n// instrument.\nfunc NewSDKProcessorSpanQueueCapacity(\n\tm metric.Meter,\n\topt ...metric.Int64ObservableUpDownCounterOption,\n) (SDKProcessorSpanQueueCapacity, error) {\n\t// Check if the meter is nil.\n\tif m == nil {\n\t\treturn SDKProcessorSpanQueueCapacity{noop.Int64ObservableUpDownCounter{}}, nil\n\t}\n\n\tif len(opt) == 0 {\n\t\topt = newSDKProcessorSpanQueueCapacityOpts\n\t} else {\n\t\topt = append(opt, newSDKProcessorSpanQueueCapacityOpts...)\n\t}\n\n\ti, err := m.Int64ObservableUpDownCounter(\n\t\t\"otel.sdk.processor.span.queue.capacity\",\n\t\topt...,\n\t)\n\tif err != nil {\n\t\treturn SDKProcessorSpanQueueCapacity{noop.Int64ObservableUpDownCounter{}}, err\n\t}\n\treturn SDKProcessorSpanQueueCapacity{i}, nil\n}\n\n// Inst returns the underlying metric instrument.\nfunc (m SDKProcessorSpanQueueCapacity) Inst() metric.Int64ObservableUpDownCounter {\n\treturn m.Int64ObservableUpDownCounter\n}\n\n// Name returns the semantic convention name of the instrument.\nfunc (SDKProcessorSpanQueueCapacity) Name() string {\n\treturn \"otel.sdk.processor.span.queue.capacity\"\n}\n\n// Unit returns the semantic convention unit of the instrument\nfunc (SDKProcessorSpanQueueCapacity) Unit() string {\n\treturn \"{span}\"\n}\n\n// Description returns the semantic convention description of the instrument\nfunc (SDKProcessorSpanQueueCapacity) Description() string {\n\treturn \"The maximum number of spans the queue of a given instance of an SDK span processor can hold.\"\n}\n\n// AttrComponentName returns an optional attribute for the \"otel.component.name\"\n// semantic convention. It represents a name uniquely identifying the instance of\n// the OpenTelemetry component within its containing SDK instance.\nfunc (SDKProcessorSpanQueueCapacity) AttrComponentName(val string) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.name\", val)\n}\n\n// AttrComponentType returns an optional attribute for the \"otel.component.type\"\n// semantic convention. It represents a name identifying the type of the\n// OpenTelemetry component.\nfunc (SDKProcessorSpanQueueCapacity) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.type\", string(val))\n}\n\n// SDKProcessorSpanQueueSize is an instrument used to record metric values\n// conforming to the \"otel.sdk.processor.span.queue.size\" semantic conventions.\n// It represents the number of spans in the queue of a given instance of an SDK\n// span processor.\ntype SDKProcessorSpanQueueSize struct {\n\tmetric.Int64ObservableUpDownCounter\n}\n\nvar newSDKProcessorSpanQueueSizeOpts = []metric.Int64ObservableUpDownCounterOption{\n\tmetric.WithDescription(\"The number of spans in the queue of a given instance of an SDK span processor.\"),\n\tmetric.WithUnit(\"{span}\"),\n}\n\n// NewSDKProcessorSpanQueueSize returns a new SDKProcessorSpanQueueSize\n// instrument.\nfunc NewSDKProcessorSpanQueueSize(\n\tm metric.Meter,\n\topt ...metric.Int64ObservableUpDownCounterOption,\n) (SDKProcessorSpanQueueSize, error) {\n\t// Check if the meter is nil.\n\tif m == nil {\n\t\treturn SDKProcessorSpanQueueSize{noop.Int64ObservableUpDownCounter{}}, nil\n\t}\n\n\tif len(opt) == 0 {\n\t\topt = newSDKProcessorSpanQueueSizeOpts\n\t} else {\n\t\topt = append(opt, newSDKProcessorSpanQueueSizeOpts...)\n\t}\n\n\ti, err := m.Int64ObservableUpDownCounter(\n\t\t\"otel.sdk.processor.span.queue.size\",\n\t\topt...,\n\t)\n\tif err != nil {\n\t\treturn SDKProcessorSpanQueueSize{noop.Int64ObservableUpDownCounter{}}, err\n\t}\n\treturn SDKProcessorSpanQueueSize{i}, nil\n}\n\n// Inst returns the underlying metric instrument.\nfunc (m SDKProcessorSpanQueueSize) Inst() metric.Int64ObservableUpDownCounter {\n\treturn m.Int64ObservableUpDownCounter\n}\n\n// Name returns the semantic convention name of the instrument.\nfunc (SDKProcessorSpanQueueSize) Name() string {\n\treturn \"otel.sdk.processor.span.queue.size\"\n}\n\n// Unit returns the semantic convention unit of the instrument\nfunc (SDKProcessorSpanQueueSize) Unit() string {\n\treturn \"{span}\"\n}\n\n// Description returns the semantic convention description of the instrument\nfunc (SDKProcessorSpanQueueSize) Description() string {\n\treturn \"The number of spans in the queue of a given instance of an SDK span processor.\"\n}\n\n// AttrComponentName returns an optional attribute for the \"otel.component.name\"\n// semantic convention. It represents a name uniquely identifying the instance of\n// the OpenTelemetry component within its containing SDK instance.\nfunc (SDKProcessorSpanQueueSize) AttrComponentName(val string) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.name\", val)\n}\n\n// AttrComponentType returns an optional attribute for the \"otel.component.type\"\n// semantic convention. It represents a name identifying the type of the\n// OpenTelemetry component.\nfunc (SDKProcessorSpanQueueSize) AttrComponentType(val ComponentTypeAttr) attribute.KeyValue {\n\treturn attribute.String(\"otel.component.type\", string(val))\n}\n\n// SDKSpanLive is an instrument used to record metric values conforming to the\n// \"otel.sdk.span.live\" semantic conventions. It represents the number of created\n// spans with `recording=true` for which the end operation has not been called\n// yet.\ntype SDKSpanLive struct {\n\tmetric.Int64UpDownCounter\n}\n\nvar newSDKSpanLiveOpts = []metric.Int64UpDownCounterOption{\n\tmetric.WithDescription(\"The number of created spans with `recording=true` for which the end operation has not been called yet.\"),\n\tmetric.WithUnit(\"{span}\"),\n}\n\n// NewSDKSpanLive returns a new SDKSpanLive instrument.\nfunc NewSDKSpanLive(\n\tm metric.Meter,\n\topt ...metric.Int64UpDownCounterOption,\n) (SDKSpanLive, error) {\n\t// Check if the meter is nil.\n\tif m == nil {\n\t\treturn SDKSpanLive{noop.Int64UpDownCounter{}}, nil\n\t}\n\n\tif len(opt) == 0 {\n\t\topt = newSDKSpanLiveOpts\n\t} else {\n\t\topt = append(opt, newSDKSpanLiveOpts...)\n\t}\n\n\ti, err := m.Int64UpDownCounter(\n\t\t\"otel.sdk.span.live\",\n\t\topt...,\n\t)\n\tif err != nil {\n\t\treturn SDKSpanLive{noop.Int64UpDownCounter{}}, err\n\t}\n\treturn SDKSpanLive{i}, nil\n}\n\n// Inst returns the underlying metric instrument.\nfunc (m SDKSpanLive) Inst() metric.Int64UpDownCounter {\n\treturn m.Int64UpDownCounter\n}\n\n// Name returns the semantic convention name of the instrument.\nfunc (SDKSpanLive) Name() string {\n\treturn \"otel.sdk.span.live\"\n}\n\n// Unit returns the semantic convention unit of the instrument\nfunc (SDKSpanLive) Unit() string {\n\treturn \"{span}\"\n}\n\n// Description returns the semantic convention description of the instrument\nfunc (SDKSpanLive) Description() string {\n\treturn \"The number of created spans with `recording=true` for which the end operation has not been called yet.\"\n}\n\n// Add adds incr to the existing count for attrs.\n//\n// All additional attrs passed are included in the recorded value.\nfunc (m SDKSpanLive) Add(\n\tctx context.Context,\n\tincr int64,\n\tattrs ...attribute.KeyValue,\n) {\n\tif len(attrs) == 0 {\n\t\tm.Int64UpDownCounter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(\n\t\t*o,\n\t\tmetric.WithAttributes(\n\t\t\tattrs...,\n\t\t),\n\t)\n\n\tm.Int64UpDownCounter.Add(ctx, incr, *o...)\n}\n\n// AddSet adds incr to the existing count for set.\nfunc (m SDKSpanLive) AddSet(ctx context.Context, incr int64, set attribute.Set) {\n\tif set.Len() == 0 {\n\t\tm.Int64UpDownCounter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(*o, metric.WithAttributeSet(set))\n\tm.Int64UpDownCounter.Add(ctx, incr, *o...)\n}\n\n// AttrSpanSamplingResult returns an optional attribute for the\n// \"otel.span.sampling_result\" semantic convention. It represents the result\n// value of the sampler for this span.\nfunc (SDKSpanLive) AttrSpanSamplingResult(val SpanSamplingResultAttr) attribute.KeyValue {\n\treturn attribute.String(\"otel.span.sampling_result\", string(val))\n}\n\n// SDKSpanStarted is an instrument used to record metric values conforming to the\n// \"otel.sdk.span.started\" semantic conventions. It represents the number of\n// created spans.\ntype SDKSpanStarted struct {\n\tmetric.Int64Counter\n}\n\nvar newSDKSpanStartedOpts = []metric.Int64CounterOption{\n\tmetric.WithDescription(\"The number of created spans.\"),\n\tmetric.WithUnit(\"{span}\"),\n}\n\n// NewSDKSpanStarted returns a new SDKSpanStarted instrument.\nfunc NewSDKSpanStarted(\n\tm metric.Meter,\n\topt ...metric.Int64CounterOption,\n) (SDKSpanStarted, error) {\n\t// Check if the meter is nil.\n\tif m == nil {\n\t\treturn SDKSpanStarted{noop.Int64Counter{}}, nil\n\t}\n\n\tif len(opt) == 0 {\n\t\topt = newSDKSpanStartedOpts\n\t} else {\n\t\topt = append(opt, newSDKSpanStartedOpts...)\n\t}\n\n\ti, err := m.Int64Counter(\n\t\t\"otel.sdk.span.started\",\n\t\topt...,\n\t)\n\tif err != nil {\n\t\treturn SDKSpanStarted{noop.Int64Counter{}}, err\n\t}\n\treturn SDKSpanStarted{i}, nil\n}\n\n// Inst returns the underlying metric instrument.\nfunc (m SDKSpanStarted) Inst() metric.Int64Counter {\n\treturn m.Int64Counter\n}\n\n// Name returns the semantic convention name of the instrument.\nfunc (SDKSpanStarted) Name() string {\n\treturn \"otel.sdk.span.started\"\n}\n\n// Unit returns the semantic convention unit of the instrument\nfunc (SDKSpanStarted) Unit() string {\n\treturn \"{span}\"\n}\n\n// Description returns the semantic convention description of the instrument\nfunc (SDKSpanStarted) Description() string {\n\treturn \"The number of created spans.\"\n}\n\n// Add adds incr to the existing count for attrs.\n//\n// All additional attrs passed are included in the recorded value.\n//\n// Implementations MUST record this metric for all spans, even for non-recording\n// ones.\nfunc (m SDKSpanStarted) Add(\n\tctx context.Context,\n\tincr int64,\n\tattrs ...attribute.KeyValue,\n) {\n\tif len(attrs) == 0 {\n\t\tm.Int64Counter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(\n\t\t*o,\n\t\tmetric.WithAttributes(\n\t\t\tattrs...,\n\t\t),\n\t)\n\n\tm.Int64Counter.Add(ctx, incr, *o...)\n}\n\n// AddSet adds incr to the existing count for set.\n//\n// Implementations MUST record this metric for all spans, even for non-recording\n// ones.\nfunc (m SDKSpanStarted) AddSet(ctx context.Context, incr int64, set attribute.Set) {\n\tif set.Len() == 0 {\n\t\tm.Int64Counter.Add(ctx, incr)\n\t\treturn\n\t}\n\n\to := addOptPool.Get().(*[]metric.AddOption)\n\tdefer func() {\n\t\t*o = (*o)[:0]\n\t\taddOptPool.Put(o)\n\t}()\n\n\t*o = append(*o, metric.WithAttributeSet(set))\n\tm.Int64Counter.Add(ctx, incr, *o...)\n}\n\n// AttrSpanParentOrigin returns an optional attribute for the\n// \"otel.span.parent.origin\" semantic convention. It represents the determines\n// whether the span has a parent span, and if so, [whether it is a remote parent]\n// .\n//\n// [whether it is a remote parent]: https://opentelemetry.io/docs/specs/otel/trace/api/#isremote\nfunc (SDKSpanStarted) AttrSpanParentOrigin(val SpanParentOriginAttr) attribute.KeyValue {\n\treturn attribute.String(\"otel.span.parent.origin\", string(val))\n}\n\n// AttrSpanSamplingResult returns an optional attribute for the\n// \"otel.span.sampling_result\" semantic convention. It represents the result\n// value of the sampler for this span.\nfunc (SDKSpanStarted) AttrSpanSamplingResult(val SpanSamplingResultAttr) attribute.KeyValue {\n\treturn attribute.String(\"otel.span.sampling_result\", string(val))\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.39.0/schema.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.39.0\"\n\n// SchemaURL is the schema URL that matches the version of the semantic conventions\n// that this package defines. Semconv packages starting from v1.4.0 must declare\n// non-empty schema URL in the form https://opentelemetry.io/schemas/<version>\nconst SchemaURL = \"https://opentelemetry.io/schemas/1.39.0\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.7.0/README.md",
    "content": "# Semconv v1.7.0\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/semconv/v1.7.0)](https://pkg.go.dev/go.opentelemetry.io/otel/semconv/v1.7.0)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.7.0/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package semconv implements OpenTelemetry semantic conventions.\n//\n// OpenTelemetry semantic conventions are agreed standardized naming\n// patterns for OpenTelemetry things. This package represents the conventions\n// as of the v1.7.0 version of the OpenTelemetry specification.\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.7.0\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.7.0/exception.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.7.0\"\n\nconst (\n\t// ExceptionEventName is the name of the Span event representing an exception.\n\tExceptionEventName = \"exception\"\n)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.7.0/http.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.7.0\"\n\nimport (\n\t\"net/http\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n\t\"go.opentelemetry.io/otel/semconv/internal\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\n// HTTP scheme attributes.\nvar (\n\tHTTPSchemeHTTP  = HTTPSchemeKey.String(\"http\")\n\tHTTPSchemeHTTPS = HTTPSchemeKey.String(\"https\")\n)\n\nvar sc = &internal.SemanticConventions{\n\tEnduserIDKey:                EnduserIDKey,\n\tHTTPClientIPKey:             HTTPClientIPKey,\n\tHTTPFlavorKey:               HTTPFlavorKey,\n\tHTTPHostKey:                 HTTPHostKey,\n\tHTTPMethodKey:               HTTPMethodKey,\n\tHTTPRequestContentLengthKey: HTTPRequestContentLengthKey,\n\tHTTPRouteKey:                HTTPRouteKey,\n\tHTTPSchemeHTTP:              HTTPSchemeHTTP,\n\tHTTPSchemeHTTPS:             HTTPSchemeHTTPS,\n\tHTTPServerNameKey:           HTTPServerNameKey,\n\tHTTPStatusCodeKey:           HTTPStatusCodeKey,\n\tHTTPTargetKey:               HTTPTargetKey,\n\tHTTPURLKey:                  HTTPURLKey,\n\tHTTPUserAgentKey:            HTTPUserAgentKey,\n\tNetHostIPKey:                NetHostIPKey,\n\tNetHostNameKey:              NetHostNameKey,\n\tNetHostPortKey:              NetHostPortKey,\n\tNetPeerIPKey:                NetPeerIPKey,\n\tNetPeerNameKey:              NetPeerNameKey,\n\tNetPeerPortKey:              NetPeerPortKey,\n\tNetTransportIP:              NetTransportIP,\n\tNetTransportOther:           NetTransportOther,\n\tNetTransportTCP:             NetTransportTCP,\n\tNetTransportUDP:             NetTransportUDP,\n\tNetTransportUnix:            NetTransportUnix,\n}\n\n// NetAttributesFromHTTPRequest generates attributes of the net\n// namespace as specified by the OpenTelemetry specification for a\n// span.  The network parameter is a string that net.Dial function\n// from standard library can understand.\nfunc NetAttributesFromHTTPRequest(network string, request *http.Request) []attribute.KeyValue {\n\treturn sc.NetAttributesFromHTTPRequest(network, request)\n}\n\n// EndUserAttributesFromHTTPRequest generates attributes of the\n// enduser namespace as specified by the OpenTelemetry specification\n// for a span.\nfunc EndUserAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {\n\treturn sc.EndUserAttributesFromHTTPRequest(request)\n}\n\n// HTTPClientAttributesFromHTTPRequest generates attributes of the\n// http namespace as specified by the OpenTelemetry specification for\n// a span on the client side.\nfunc HTTPClientAttributesFromHTTPRequest(request *http.Request) []attribute.KeyValue {\n\treturn sc.HTTPClientAttributesFromHTTPRequest(request)\n}\n\n// HTTPServerMetricAttributesFromHTTPRequest generates low-cardinality attributes\n// to be used with server-side HTTP metrics.\nfunc HTTPServerMetricAttributesFromHTTPRequest(serverName string, request *http.Request) []attribute.KeyValue {\n\treturn sc.HTTPServerMetricAttributesFromHTTPRequest(serverName, request)\n}\n\n// HTTPServerAttributesFromHTTPRequest generates attributes of the\n// http namespace as specified by the OpenTelemetry specification for\n// a span on the server side. Currently, only basic authentication is\n// supported.\nfunc HTTPServerAttributesFromHTTPRequest(serverName, route string, request *http.Request) []attribute.KeyValue {\n\treturn sc.HTTPServerAttributesFromHTTPRequest(serverName, route, request)\n}\n\n// HTTPAttributesFromHTTPStatusCode generates attributes of the http\n// namespace as specified by the OpenTelemetry specification for a\n// span.\nfunc HTTPAttributesFromHTTPStatusCode(code int) []attribute.KeyValue {\n\treturn sc.HTTPAttributesFromHTTPStatusCode(code)\n}\n\n// SpanStatusFromHTTPStatusCode generates a status code and a message\n// as specified by the OpenTelemetry specification for a span.\nfunc SpanStatusFromHTTPStatusCode(code int) (codes.Code, string) {\n\treturn internal.SpanStatusFromHTTPStatusCode(code)\n}\n\n// SpanStatusFromHTTPStatusCodeAndSpanKind generates a status code and a message\n// as specified by the OpenTelemetry specification for a span.\n// Exclude 4xx for SERVER to set the appropriate status.\nfunc SpanStatusFromHTTPStatusCodeAndSpanKind(code int, spanKind trace.SpanKind) (codes.Code, string) {\n\treturn internal.SpanStatusFromHTTPStatusCodeAndSpanKind(code, spanKind)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.7.0/resource.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Code generated from semantic convention specification. DO NOT EDIT.\n\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.7.0\"\n\nimport \"go.opentelemetry.io/otel/attribute\"\n\n// A cloud environment (e.g. GCP, Azure, AWS)\nconst (\n\t// Name of the cloud provider.\n\t//\n\t// Type: Enum\n\t// Required: No\n\t// Stability: stable\n\tCloudProviderKey = attribute.Key(\"cloud.provider\")\n\t// The cloud account ID the resource is assigned to.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '111111111111', 'opentelemetry'\n\tCloudAccountIDKey = attribute.Key(\"cloud.account.id\")\n\t// The geographical region the resource is running. Refer to your provider's docs\n\t// to see the available regions, for example [Alibaba Cloud\n\t// regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS\n\t// regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/),\n\t// [Azure regions](https://azure.microsoft.com/en-us/global-\n\t// infrastructure/geographies/), or [Google Cloud\n\t// regions](https://cloud.google.com/about/locations).\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'us-central1', 'us-east-1'\n\tCloudRegionKey = attribute.Key(\"cloud.region\")\n\t// Cloud regions often have multiple, isolated locations known as zones to\n\t// increase availability. Availability zone represents the zone where the resource\n\t// is running.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'us-east-1c'\n\t// Note: Availability zones are called \"zones\" on Alibaba Cloud and Google Cloud.\n\tCloudAvailabilityZoneKey = attribute.Key(\"cloud.availability_zone\")\n\t// The cloud platform in use.\n\t//\n\t// Type: Enum\n\t// Required: No\n\t// Stability: stable\n\t// Note: The prefix of the service SHOULD match the one specified in\n\t// `cloud.provider`.\n\tCloudPlatformKey = attribute.Key(\"cloud.platform\")\n)\n\nvar (\n\t// Alibaba Cloud\n\tCloudProviderAlibabaCloud = CloudProviderKey.String(\"alibaba_cloud\")\n\t// Amazon Web Services\n\tCloudProviderAWS = CloudProviderKey.String(\"aws\")\n\t// Microsoft Azure\n\tCloudProviderAzure = CloudProviderKey.String(\"azure\")\n\t// Google Cloud Platform\n\tCloudProviderGCP = CloudProviderKey.String(\"gcp\")\n)\n\nvar (\n\t// Alibaba Cloud Elastic Compute Service\n\tCloudPlatformAlibabaCloudECS = CloudPlatformKey.String(\"alibaba_cloud_ecs\")\n\t// Alibaba Cloud Function Compute\n\tCloudPlatformAlibabaCloudFc = CloudPlatformKey.String(\"alibaba_cloud_fc\")\n\t// AWS Elastic Compute Cloud\n\tCloudPlatformAWSEC2 = CloudPlatformKey.String(\"aws_ec2\")\n\t// AWS Elastic Container Service\n\tCloudPlatformAWSECS = CloudPlatformKey.String(\"aws_ecs\")\n\t// AWS Elastic Kubernetes Service\n\tCloudPlatformAWSEKS = CloudPlatformKey.String(\"aws_eks\")\n\t// AWS Lambda\n\tCloudPlatformAWSLambda = CloudPlatformKey.String(\"aws_lambda\")\n\t// AWS Elastic Beanstalk\n\tCloudPlatformAWSElasticBeanstalk = CloudPlatformKey.String(\"aws_elastic_beanstalk\")\n\t// Azure Virtual Machines\n\tCloudPlatformAzureVM = CloudPlatformKey.String(\"azure_vm\")\n\t// Azure Container Instances\n\tCloudPlatformAzureContainerInstances = CloudPlatformKey.String(\"azure_container_instances\")\n\t// Azure Kubernetes Service\n\tCloudPlatformAzureAKS = CloudPlatformKey.String(\"azure_aks\")\n\t// Azure Functions\n\tCloudPlatformAzureFunctions = CloudPlatformKey.String(\"azure_functions\")\n\t// Azure App Service\n\tCloudPlatformAzureAppService = CloudPlatformKey.String(\"azure_app_service\")\n\t// Google Cloud Compute Engine (GCE)\n\tCloudPlatformGCPComputeEngine = CloudPlatformKey.String(\"gcp_compute_engine\")\n\t// Google Cloud Run\n\tCloudPlatformGCPCloudRun = CloudPlatformKey.String(\"gcp_cloud_run\")\n\t// Google Cloud Kubernetes Engine (GKE)\n\tCloudPlatformGCPKubernetesEngine = CloudPlatformKey.String(\"gcp_kubernetes_engine\")\n\t// Google Cloud Functions (GCF)\n\tCloudPlatformGCPCloudFunctions = CloudPlatformKey.String(\"gcp_cloud_functions\")\n\t// Google Cloud App Engine (GAE)\n\tCloudPlatformGCPAppEngine = CloudPlatformKey.String(\"gcp_app_engine\")\n)\n\n// Resources used by AWS Elastic Container Service (ECS).\nconst (\n\t// The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.\n\t// amazon.com/AmazonECS/latest/developerguide/ECS_instances.html).\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'arn:aws:ecs:us-\n\t// west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9'\n\tAWSECSContainerARNKey = attribute.Key(\"aws.ecs.container.arn\")\n\t// The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/develo\n\t// perguide/clusters.html).\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'\n\tAWSECSClusterARNKey = attribute.Key(\"aws.ecs.cluster.arn\")\n\t// The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/l\n\t// aunch_types.html) for an ECS task.\n\t//\n\t// Type: Enum\n\t// Required: No\n\t// Stability: stable\n\tAWSECSLaunchtypeKey = attribute.Key(\"aws.ecs.launchtype\")\n\t// The ARN of an [ECS task definition](https://docs.aws.amazon.com/AmazonECS/lates\n\t// t/developerguide/task_definitions.html).\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'arn:aws:ecs:us-\n\t// west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b'\n\tAWSECSTaskARNKey = attribute.Key(\"aws.ecs.task.arn\")\n\t// The task definition family this task definition is a member of.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'opentelemetry-family'\n\tAWSECSTaskFamilyKey = attribute.Key(\"aws.ecs.task.family\")\n\t// The revision for this task definition.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '8', '26'\n\tAWSECSTaskRevisionKey = attribute.Key(\"aws.ecs.task.revision\")\n)\n\nvar (\n\t// ec2\n\tAWSECSLaunchtypeEC2 = AWSECSLaunchtypeKey.String(\"ec2\")\n\t// fargate\n\tAWSECSLaunchtypeFargate = AWSECSLaunchtypeKey.String(\"fargate\")\n)\n\n// Resources used by AWS Elastic Kubernetes Service (EKS).\nconst (\n\t// The ARN of an EKS cluster.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'\n\tAWSEKSClusterARNKey = attribute.Key(\"aws.eks.cluster.arn\")\n)\n\n// Resources specific to Amazon Web Services.\nconst (\n\t// The name(s) of the AWS log group(s) an application is writing to.\n\t//\n\t// Type: string[]\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '/aws/lambda/my-function', 'opentelemetry-service'\n\t// Note: Multiple log groups must be supported for cases like multi-container\n\t// applications, where a single application has sidecar containers, and each write\n\t// to their own log group.\n\tAWSLogGroupNamesKey = attribute.Key(\"aws.log.group.names\")\n\t// The Amazon Resource Name(s) (ARN) of the AWS log group(s).\n\t//\n\t// Type: string[]\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*'\n\t// Note: See the [log group ARN format\n\t// documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-\n\t// access-control-overview-cwl.html#CWL_ARN_Format).\n\tAWSLogGroupARNsKey = attribute.Key(\"aws.log.group.arns\")\n\t// The name(s) of the AWS log stream(s) an application is writing to.\n\t//\n\t// Type: string[]\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'\n\tAWSLogStreamNamesKey = attribute.Key(\"aws.log.stream.names\")\n\t// The ARN(s) of the AWS log stream(s).\n\t//\n\t// Type: string[]\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-\n\t// stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'\n\t// Note: See the [log stream ARN format\n\t// documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-\n\t// access-control-overview-cwl.html#CWL_ARN_Format). One log group can contain\n\t// several log streams, so these ARNs necessarily identify both a log group and a\n\t// log stream.\n\tAWSLogStreamARNsKey = attribute.Key(\"aws.log.stream.arns\")\n)\n\n// A container instance.\nconst (\n\t// Container name.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'opentelemetry-autoconf'\n\tContainerNameKey = attribute.Key(\"container.name\")\n\t// Container ID. Usually a UUID, as for example used to [identify Docker\n\t// containers](https://docs.docker.com/engine/reference/run/#container-\n\t// identification). The UUID might be abbreviated.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'a3bf90e006b2'\n\tContainerIDKey = attribute.Key(\"container.id\")\n\t// The container runtime managing this container.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'docker', 'containerd', 'rkt'\n\tContainerRuntimeKey = attribute.Key(\"container.runtime\")\n\t// Name of the image the container was built on.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'gcr.io/opentelemetry/operator'\n\tContainerImageNameKey = attribute.Key(\"container.image.name\")\n\t// Container image tag.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '0.1'\n\tContainerImageTagKey = attribute.Key(\"container.image.tag\")\n)\n\n// The software deployment.\nconst (\n\t// Name of the [deployment\n\t// environment](https://en.wikipedia.org/wiki/Deployment_environment) (aka\n\t// deployment tier).\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'staging', 'production'\n\tDeploymentEnvironmentKey = attribute.Key(\"deployment.environment\")\n)\n\n// The device on which the process represented by this resource is running.\nconst (\n\t// A unique identifier representing the device\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '2ab2916d-a51f-4ac8-80ee-45ac31a28092'\n\t// Note: The device identifier MUST only be defined using the values outlined\n\t// below. This value is not an advertising identifier and MUST NOT be used as\n\t// such. On iOS (Swift or Objective-C), this value MUST be equal to the [vendor id\n\t// entifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-iden\n\t// tifierforvendor). On Android (Java or Kotlin), this value MUST be equal to the\n\t// Firebase Installation ID or a globally unique UUID which is persisted across\n\t// sessions in your application. More information can be found\n\t// [here](https://developer.android.com/training/articles/user-data-ids) on best\n\t// practices and exact implementation details. Caution should be taken when\n\t// storing personal data or anything which can identify a user. GDPR and data\n\t// protection laws may apply, ensure you do your own due diligence.\n\tDeviceIDKey = attribute.Key(\"device.id\")\n\t// The model identifier for the device\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'iPhone3,4', 'SM-G920F'\n\t// Note: It's recommended this value represents a machine readable version of the\n\t// model identifier rather than the market or consumer-friendly name of the\n\t// device.\n\tDeviceModelIdentifierKey = attribute.Key(\"device.model.identifier\")\n\t// The marketing name for the device model\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'iPhone 6s Plus', 'Samsung Galaxy S6'\n\t// Note: It's recommended this value represents a human readable version of the\n\t// device model rather than a machine readable alternative.\n\tDeviceModelNameKey = attribute.Key(\"device.model.name\")\n)\n\n// A serverless instance.\nconst (\n\t// The name of the single function that this runtime instance executes.\n\t//\n\t// Type: string\n\t// Required: Always\n\t// Stability: stable\n\t// Examples: 'my-function'\n\t// Note: This is the name of the function as configured/deployed on the FaaS\n\t// platform and is usually different from the name of the callback function (which\n\t// may be stored in the\n\t// [`code.namespace`/`code.function`](../../trace/semantic_conventions/span-\n\t// general.md#source-code-attributes) span attributes).\n\tFaaSNameKey = attribute.Key(\"faas.name\")\n\t// The unique ID of the single function that this runtime instance executes.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'arn:aws:lambda:us-west-2:123456789012:function:my-function'\n\t// Note: Depending on the cloud provider, use:\n\n\t// * **AWS Lambda:** The function\n\t// [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-\n\t// namespaces.html).\n\t// Take care not to use the \"invoked ARN\" directly but replace any\n\t// [alias suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-\n\t// aliases.html) with the resolved function version, as the same runtime instance\n\t// may be invokable with multiple\n\t// different aliases.\n\t// * **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-\n\t// resource-names)\n\t// * **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/en-\n\t// us/rest/api/resources/resources/get-by-id).\n\n\t// On some providers, it may not be possible to determine the full ID at startup,\n\t// which is why this field cannot be made required. For example, on AWS the\n\t// account ID\n\t// part of the ARN is not available without calling another AWS API\n\t// which may be deemed too slow for a short-running lambda function.\n\t// As an alternative, consider setting `faas.id` as a span attribute instead.\n\tFaaSIDKey = attribute.Key(\"faas.id\")\n\t// The immutable version of the function being executed.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '26', 'pinkfroid-00002'\n\t// Note: Depending on the cloud provider and platform, use:\n\n\t// * **AWS Lambda:** The [function\n\t// version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-\n\t// versions.html)\n\t//   (an integer represented as a decimal string).\n\t// * **Google Cloud Run:** The\n\t// [revision](https://cloud.google.com/run/docs/managing/revisions)\n\t//   (i.e., the function name plus the revision suffix).\n\t// * **Google Cloud Functions:** The value of the\n\t//   [`K_REVISION` environment\n\t// variable](https://cloud.google.com/functions/docs/env-\n\t// var#runtime_environment_variables_set_automatically).\n\t// * **Azure Functions:** Not applicable. Do not set this attribute.\n\tFaaSVersionKey = attribute.Key(\"faas.version\")\n\t// The execution environment ID as a string, that will be potentially reused for\n\t// other invocations to the same function/function version.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de'\n\t// Note: * **AWS Lambda:** Use the (full) log stream name.\n\tFaaSInstanceKey = attribute.Key(\"faas.instance\")\n\t// The amount of memory available to the serverless function in MiB.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 128\n\t// Note: It's recommended to set this attribute since e.g. too little memory can\n\t// easily stop a Java AWS Lambda function from working correctly. On AWS Lambda,\n\t// the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this\n\t// information.\n\tFaaSMaxMemoryKey = attribute.Key(\"faas.max_memory\")\n)\n\n// A host is defined as a general computing instance.\nconst (\n\t// Unique host ID. For Cloud, this must be the instance_id assigned by the cloud\n\t// provider.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'opentelemetry-test'\n\tHostIDKey = attribute.Key(\"host.id\")\n\t// Name of the host. On Unix systems, it may contain what the hostname command\n\t// returns, or the fully qualified hostname, or another name specified by the\n\t// user.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'opentelemetry-test'\n\tHostNameKey = attribute.Key(\"host.name\")\n\t// Type of host. For Cloud, this must be the machine type.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'n1-standard-1'\n\tHostTypeKey = attribute.Key(\"host.type\")\n\t// The CPU architecture the host system is running on.\n\t//\n\t// Type: Enum\n\t// Required: No\n\t// Stability: stable\n\tHostArchKey = attribute.Key(\"host.arch\")\n\t// Name of the VM image or OS install the host was instantiated from.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'infra-ami-eks-worker-node-7d4ec78312', 'CentOS-8-x86_64-1905'\n\tHostImageNameKey = attribute.Key(\"host.image.name\")\n\t// VM image ID. For Cloud, this value is from the provider.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'ami-07b06b442921831e5'\n\tHostImageIDKey = attribute.Key(\"host.image.id\")\n\t// The version string of the VM image as defined in [Version\n\t// Attributes](README.md#version-attributes).\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '0.1'\n\tHostImageVersionKey = attribute.Key(\"host.image.version\")\n)\n\nvar (\n\t// AMD64\n\tHostArchAMD64 = HostArchKey.String(\"amd64\")\n\t// ARM32\n\tHostArchARM32 = HostArchKey.String(\"arm32\")\n\t// ARM64\n\tHostArchARM64 = HostArchKey.String(\"arm64\")\n\t// Itanium\n\tHostArchIA64 = HostArchKey.String(\"ia64\")\n\t// 32-bit PowerPC\n\tHostArchPPC32 = HostArchKey.String(\"ppc32\")\n\t// 64-bit PowerPC\n\tHostArchPPC64 = HostArchKey.String(\"ppc64\")\n\t// 32-bit x86\n\tHostArchX86 = HostArchKey.String(\"x86\")\n)\n\n// A Kubernetes Cluster.\nconst (\n\t// The name of the cluster.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'opentelemetry-cluster'\n\tK8SClusterNameKey = attribute.Key(\"k8s.cluster.name\")\n)\n\n// A Kubernetes Node object.\nconst (\n\t// The name of the Node.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'node-1'\n\tK8SNodeNameKey = attribute.Key(\"k8s.node.name\")\n\t// The UID of the Node.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2'\n\tK8SNodeUIDKey = attribute.Key(\"k8s.node.uid\")\n)\n\n// A Kubernetes Namespace.\nconst (\n\t// The name of the namespace that the pod is running in.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'default'\n\tK8SNamespaceNameKey = attribute.Key(\"k8s.namespace.name\")\n)\n\n// A Kubernetes Pod object.\nconst (\n\t// The UID of the Pod.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'\n\tK8SPodUIDKey = attribute.Key(\"k8s.pod.uid\")\n\t// The name of the Pod.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'opentelemetry-pod-autoconf'\n\tK8SPodNameKey = attribute.Key(\"k8s.pod.name\")\n)\n\n// A container in a [PodTemplate](https://kubernetes.io/docs/concepts/workloads/pods/#pod-templates).\nconst (\n\t// The name of the Container in a Pod template.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'redis'\n\tK8SContainerNameKey = attribute.Key(\"k8s.container.name\")\n)\n\n// A Kubernetes ReplicaSet object.\nconst (\n\t// The UID of the ReplicaSet.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'\n\tK8SReplicaSetUIDKey = attribute.Key(\"k8s.replicaset.uid\")\n\t// The name of the ReplicaSet.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'opentelemetry'\n\tK8SReplicaSetNameKey = attribute.Key(\"k8s.replicaset.name\")\n)\n\n// A Kubernetes Deployment object.\nconst (\n\t// The UID of the Deployment.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'\n\tK8SDeploymentUIDKey = attribute.Key(\"k8s.deployment.uid\")\n\t// The name of the Deployment.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'opentelemetry'\n\tK8SDeploymentNameKey = attribute.Key(\"k8s.deployment.name\")\n)\n\n// A Kubernetes StatefulSet object.\nconst (\n\t// The UID of the StatefulSet.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'\n\tK8SStatefulSetUIDKey = attribute.Key(\"k8s.statefulset.uid\")\n\t// The name of the StatefulSet.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'opentelemetry'\n\tK8SStatefulSetNameKey = attribute.Key(\"k8s.statefulset.name\")\n)\n\n// A Kubernetes DaemonSet object.\nconst (\n\t// The UID of the DaemonSet.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'\n\tK8SDaemonSetUIDKey = attribute.Key(\"k8s.daemonset.uid\")\n\t// The name of the DaemonSet.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'opentelemetry'\n\tK8SDaemonSetNameKey = attribute.Key(\"k8s.daemonset.name\")\n)\n\n// A Kubernetes Job object.\nconst (\n\t// The UID of the Job.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'\n\tK8SJobUIDKey = attribute.Key(\"k8s.job.uid\")\n\t// The name of the Job.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'opentelemetry'\n\tK8SJobNameKey = attribute.Key(\"k8s.job.name\")\n)\n\n// A Kubernetes CronJob object.\nconst (\n\t// The UID of the CronJob.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'\n\tK8SCronJobUIDKey = attribute.Key(\"k8s.cronjob.uid\")\n\t// The name of the CronJob.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'opentelemetry'\n\tK8SCronJobNameKey = attribute.Key(\"k8s.cronjob.name\")\n)\n\n// The operating system (OS) on which the process represented by this resource is running.\nconst (\n\t// The operating system type.\n\t//\n\t// Type: Enum\n\t// Required: Always\n\t// Stability: stable\n\tOSTypeKey = attribute.Key(\"os.type\")\n\t// Human readable (not intended to be parsed) OS version information, like e.g.\n\t// reported by `ver` or `lsb_release -a` commands.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'Microsoft Windows [Version 10.0.18363.778]', 'Ubuntu 18.04.1 LTS'\n\tOSDescriptionKey = attribute.Key(\"os.description\")\n\t// Human readable operating system name.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'iOS', 'Android', 'Ubuntu'\n\tOSNameKey = attribute.Key(\"os.name\")\n\t// The version string of the operating system as defined in [Version\n\t// Attributes](../../resource/semantic_conventions/README.md#version-attributes).\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '14.2.1', '18.04.1'\n\tOSVersionKey = attribute.Key(\"os.version\")\n)\n\nvar (\n\t// Microsoft Windows\n\tOSTypeWindows = OSTypeKey.String(\"windows\")\n\t// Linux\n\tOSTypeLinux = OSTypeKey.String(\"linux\")\n\t// Apple Darwin\n\tOSTypeDarwin = OSTypeKey.String(\"darwin\")\n\t// FreeBSD\n\tOSTypeFreeBSD = OSTypeKey.String(\"freebsd\")\n\t// NetBSD\n\tOSTypeNetBSD = OSTypeKey.String(\"netbsd\")\n\t// OpenBSD\n\tOSTypeOpenBSD = OSTypeKey.String(\"openbsd\")\n\t// DragonFly BSD\n\tOSTypeDragonflyBSD = OSTypeKey.String(\"dragonflybsd\")\n\t// HP-UX (Hewlett Packard Unix)\n\tOSTypeHPUX = OSTypeKey.String(\"hpux\")\n\t// AIX (Advanced Interactive eXecutive)\n\tOSTypeAIX = OSTypeKey.String(\"aix\")\n\t// Oracle Solaris\n\tOSTypeSolaris = OSTypeKey.String(\"solaris\")\n\t// IBM z/OS\n\tOSTypeZOS = OSTypeKey.String(\"z_os\")\n)\n\n// An operating system process.\nconst (\n\t// Process identifier (PID).\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 1234\n\tProcessPIDKey = attribute.Key(\"process.pid\")\n\t// The name of the process executable. On Linux based systems, can be set to the\n\t// `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of\n\t// `GetProcessImageFileNameW`.\n\t//\n\t// Type: string\n\t// Required: See below\n\t// Stability: stable\n\t// Examples: 'otelcol'\n\tProcessExecutableNameKey = attribute.Key(\"process.executable.name\")\n\t// The full path to the process executable. On Linux based systems, can be set to\n\t// the target of `proc/[pid]/exe`. On Windows, can be set to the result of\n\t// `GetProcessImageFileNameW`.\n\t//\n\t// Type: string\n\t// Required: See below\n\t// Stability: stable\n\t// Examples: '/usr/bin/cmd/otelcol'\n\tProcessExecutablePathKey = attribute.Key(\"process.executable.path\")\n\t// The command used to launch the process (i.e. the command name). On Linux based\n\t// systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows,\n\t// can be set to the first parameter extracted from `GetCommandLineW`.\n\t//\n\t// Type: string\n\t// Required: See below\n\t// Stability: stable\n\t// Examples: 'cmd/otelcol'\n\tProcessCommandKey = attribute.Key(\"process.command\")\n\t// The full command used to launch the process as a single string representing the\n\t// full command. On Windows, can be set to the result of `GetCommandLineW`. Do not\n\t// set this if you have to assemble it just for monitoring; use\n\t// `process.command_args` instead.\n\t//\n\t// Type: string\n\t// Required: See below\n\t// Stability: stable\n\t// Examples: 'C:\\\\cmd\\\\otecol --config=\"my directory\\\\config.yaml\"'\n\tProcessCommandLineKey = attribute.Key(\"process.command_line\")\n\t// All the command arguments (including the command/executable itself) as received\n\t// by the process. On Linux-based systems (and some other Unixoid systems\n\t// supporting procfs), can be set according to the list of null-delimited strings\n\t// extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be\n\t// the full argv vector passed to `main`.\n\t//\n\t// Type: string[]\n\t// Required: See below\n\t// Stability: stable\n\t// Examples: 'cmd/otecol', '--config=config.yaml'\n\tProcessCommandArgsKey = attribute.Key(\"process.command_args\")\n\t// The username of the user that owns the process.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'root'\n\tProcessOwnerKey = attribute.Key(\"process.owner\")\n)\n\n// The single (language) runtime instance which is monitored.\nconst (\n\t// The name of the runtime of this process. For compiled native binaries, this\n\t// SHOULD be the name of the compiler.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'OpenJDK Runtime Environment'\n\tProcessRuntimeNameKey = attribute.Key(\"process.runtime.name\")\n\t// The version of the runtime of this process, as returned by the runtime without\n\t// modification.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '14.0.2'\n\tProcessRuntimeVersionKey = attribute.Key(\"process.runtime.version\")\n\t// An additional description about the runtime of the process, for example a\n\t// specific vendor customization of the runtime environment.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0'\n\tProcessRuntimeDescriptionKey = attribute.Key(\"process.runtime.description\")\n)\n\n// A service instance.\nconst (\n\t// Logical name of the service.\n\t//\n\t// Type: string\n\t// Required: Always\n\t// Stability: stable\n\t// Examples: 'shoppingcart'\n\t// Note: MUST be the same for all instances of horizontally scaled services. If\n\t// the value was not specified, SDKs MUST fallback to `unknown_service:`\n\t// concatenated with [`process.executable.name`](process.md#process), e.g.\n\t// `unknown_service:bash`. If `process.executable.name` is not available, the\n\t// value MUST be set to `unknown_service`.\n\tServiceNameKey = attribute.Key(\"service.name\")\n\t// A namespace for `service.name`.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'Shop'\n\t// Note: A string value having a meaning that helps to distinguish a group of\n\t// services, for example the team name that owns a group of services.\n\t// `service.name` is expected to be unique within the same namespace. If\n\t// `service.namespace` is not specified in the Resource then `service.name` is\n\t// expected to be unique for all services that have no explicit namespace defined\n\t// (so the empty/unspecified namespace is simply one more valid namespace). Zero-\n\t// length namespace string is assumed equal to unspecified namespace.\n\tServiceNamespaceKey = attribute.Key(\"service.namespace\")\n\t// The string ID of the service instance.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '627cc493-f310-47de-96bd-71410b7dec09'\n\t// Note: MUST be unique for each instance of the same\n\t// `service.namespace,service.name` pair (in other words\n\t// `service.namespace,service.name,service.instance.id` triplet MUST be globally\n\t// unique). The ID helps to distinguish instances of the same service that exist\n\t// at the same time (e.g. instances of a horizontally scaled service). It is\n\t// preferable for the ID to be persistent and stay the same for the lifetime of\n\t// the service instance, however it is acceptable that the ID is ephemeral and\n\t// changes during important lifetime events for the service (e.g. service\n\t// restarts). If the service has no inherent unique ID that can be used as the\n\t// value of this attribute it is recommended to generate a random Version 1 or\n\t// Version 4 RFC 4122 UUID (services aiming for reproducible UUIDs may also use\n\t// Version 5, see RFC 4122 for more recommendations).\n\tServiceInstanceIDKey = attribute.Key(\"service.instance.id\")\n\t// The version string of the service API or implementation.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '2.0.0'\n\tServiceVersionKey = attribute.Key(\"service.version\")\n)\n\n// The telemetry SDK used to capture data recorded by the instrumentation libraries.\nconst (\n\t// The name of the telemetry SDK as defined above.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'opentelemetry'\n\tTelemetrySDKNameKey = attribute.Key(\"telemetry.sdk.name\")\n\t// The language of the telemetry SDK.\n\t//\n\t// Type: Enum\n\t// Required: No\n\t// Stability: stable\n\tTelemetrySDKLanguageKey = attribute.Key(\"telemetry.sdk.language\")\n\t// The version string of the telemetry SDK.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '1.2.3'\n\tTelemetrySDKVersionKey = attribute.Key(\"telemetry.sdk.version\")\n\t// The version string of the auto instrumentation agent, if used.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '1.2.3'\n\tTelemetryAutoVersionKey = attribute.Key(\"telemetry.auto.version\")\n)\n\nvar (\n\t// cpp\n\tTelemetrySDKLanguageCPP = TelemetrySDKLanguageKey.String(\"cpp\")\n\t// dotnet\n\tTelemetrySDKLanguageDotnet = TelemetrySDKLanguageKey.String(\"dotnet\")\n\t// erlang\n\tTelemetrySDKLanguageErlang = TelemetrySDKLanguageKey.String(\"erlang\")\n\t// go\n\tTelemetrySDKLanguageGo = TelemetrySDKLanguageKey.String(\"go\")\n\t// java\n\tTelemetrySDKLanguageJava = TelemetrySDKLanguageKey.String(\"java\")\n\t// nodejs\n\tTelemetrySDKLanguageNodejs = TelemetrySDKLanguageKey.String(\"nodejs\")\n\t// php\n\tTelemetrySDKLanguagePHP = TelemetrySDKLanguageKey.String(\"php\")\n\t// python\n\tTelemetrySDKLanguagePython = TelemetrySDKLanguageKey.String(\"python\")\n\t// ruby\n\tTelemetrySDKLanguageRuby = TelemetrySDKLanguageKey.String(\"ruby\")\n\t// webjs\n\tTelemetrySDKLanguageWebjs = TelemetrySDKLanguageKey.String(\"webjs\")\n)\n\n// Resource describing the packaged software running the application code. Web engines are typically executed using process.runtime.\nconst (\n\t// The name of the web engine.\n\t//\n\t// Type: string\n\t// Required: Always\n\t// Stability: stable\n\t// Examples: 'WildFly'\n\tWebEngineNameKey = attribute.Key(\"webengine.name\")\n\t// The version of the web engine.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '21.0.0'\n\tWebEngineVersionKey = attribute.Key(\"webengine.version\")\n\t// Additional description of the web engine (e.g. detailed version and edition\n\t// information).\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final'\n\tWebEngineDescriptionKey = attribute.Key(\"webengine.description\")\n)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.7.0/schema.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.7.0\"\n\n// SchemaURL is the schema URL that matches the version of the semantic conventions\n// that this package defines. Semconv packages starting from v1.4.0 must declare\n// non-empty schema URL in the form https://opentelemetry.io/schemas/<version>\nconst SchemaURL = \"https://opentelemetry.io/schemas/1.7.0\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.7.0/trace.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Code generated from semantic convention specification. DO NOT EDIT.\n\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.7.0\"\n\nimport \"go.opentelemetry.io/otel/attribute\"\n\n// Span attributes used by AWS Lambda (in addition to general `faas` attributes).\nconst (\n\t// The full invoked ARN as provided on the `Context` passed to the function\n\t// (`Lambda-Runtime-Invoked-Function-ARN` header on the `/runtime/invocation/next`\n\t// applicable).\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'arn:aws:lambda:us-east-1:123456:function:myfunction:myalias'\n\t// Note: This may be different from `faas.id` if an alias is involved.\n\tAWSLambdaInvokedARNKey = attribute.Key(\"aws.lambda.invoked_arn\")\n)\n\n// This document defines the attributes used to perform database client calls.\nconst (\n\t// An identifier for the database management system (DBMS) product being used. See\n\t// below for a list of well-known identifiers.\n\t//\n\t// Type: Enum\n\t// Required: Always\n\t// Stability: stable\n\tDBSystemKey = attribute.Key(\"db.system\")\n\t// The connection string used to connect to the database. It is recommended to\n\t// remove embedded credentials.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'Server=(localdb)\\\\v11.0;Integrated Security=true;'\n\tDBConnectionStringKey = attribute.Key(\"db.connection_string\")\n\t// Username for accessing the database.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'readonly_user', 'reporting_user'\n\tDBUserKey = attribute.Key(\"db.user\")\n\t// The fully-qualified class name of the [Java Database Connectivity\n\t// (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver\n\t// used to connect.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'org.postgresql.Driver',\n\t// 'com.microsoft.sqlserver.jdbc.SQLServerDriver'\n\tDBJDBCDriverClassnameKey = attribute.Key(\"db.jdbc.driver_classname\")\n\t// If no [tech-specific attribute](#call-level-attributes-for-specific-\n\t// technologies) is defined, this attribute is used to report the name of the\n\t// database being accessed. For commands that switch the database, this should be\n\t// set to the target database (even if the command fails).\n\t//\n\t// Type: string\n\t// Required: Required, if applicable and no more-specific attribute is defined.\n\t// Stability: stable\n\t// Examples: 'customers', 'main'\n\t// Note: In some SQL databases, the database name to be used is called \"schema\n\t// name\".\n\tDBNameKey = attribute.Key(\"db.name\")\n\t// The database statement being executed.\n\t//\n\t// Type: string\n\t// Required: Required if applicable and not explicitly disabled via\n\t// instrumentation configuration.\n\t// Stability: stable\n\t// Examples: 'SELECT * FROM wuser_table', 'SET mykey \"WuValue\"'\n\t// Note: The value may be sanitized to exclude sensitive information.\n\tDBStatementKey = attribute.Key(\"db.statement\")\n\t// The name of the operation being executed, e.g. the [MongoDB command\n\t// name](https://docs.mongodb.com/manual/reference/command/#database-operations)\n\t// such as `findAndModify`, or the SQL keyword.\n\t//\n\t// Type: string\n\t// Required: Required, if `db.statement` is not applicable.\n\t// Stability: stable\n\t// Examples: 'findAndModify', 'HMSET', 'SELECT'\n\t// Note: When setting this to an SQL keyword, it is not recommended to attempt any\n\t// client-side parsing of `db.statement` just to get this property, but it should\n\t// be set if the operation name is provided by the library being instrumented. If\n\t// the SQL statement has an ambiguous operation, or performs more than one\n\t// operation, this value may be omitted.\n\tDBOperationKey = attribute.Key(\"db.operation\")\n)\n\nvar (\n\t// Some other SQL database. Fallback only. See notes\n\tDBSystemOtherSQL = DBSystemKey.String(\"other_sql\")\n\t// Microsoft SQL Server\n\tDBSystemMSSQL = DBSystemKey.String(\"mssql\")\n\t// MySQL\n\tDBSystemMySQL = DBSystemKey.String(\"mysql\")\n\t// Oracle Database\n\tDBSystemOracle = DBSystemKey.String(\"oracle\")\n\t// IBM DB2\n\tDBSystemDB2 = DBSystemKey.String(\"db2\")\n\t// PostgreSQL\n\tDBSystemPostgreSQL = DBSystemKey.String(\"postgresql\")\n\t// Amazon Redshift\n\tDBSystemRedshift = DBSystemKey.String(\"redshift\")\n\t// Apache Hive\n\tDBSystemHive = DBSystemKey.String(\"hive\")\n\t// Cloudscape\n\tDBSystemCloudscape = DBSystemKey.String(\"cloudscape\")\n\t// HyperSQL DataBase\n\tDBSystemHSQLDB = DBSystemKey.String(\"hsqldb\")\n\t// Progress Database\n\tDBSystemProgress = DBSystemKey.String(\"progress\")\n\t// SAP MaxDB\n\tDBSystemMaxDB = DBSystemKey.String(\"maxdb\")\n\t// SAP HANA\n\tDBSystemHanaDB = DBSystemKey.String(\"hanadb\")\n\t// Ingres\n\tDBSystemIngres = DBSystemKey.String(\"ingres\")\n\t// FirstSQL\n\tDBSystemFirstSQL = DBSystemKey.String(\"firstsql\")\n\t// EnterpriseDB\n\tDBSystemEDB = DBSystemKey.String(\"edb\")\n\t// InterSystems Caché\n\tDBSystemCache = DBSystemKey.String(\"cache\")\n\t// Adabas (Adaptable Database System)\n\tDBSystemAdabas = DBSystemKey.String(\"adabas\")\n\t// Firebird\n\tDBSystemFirebird = DBSystemKey.String(\"firebird\")\n\t// Apache Derby\n\tDBSystemDerby = DBSystemKey.String(\"derby\")\n\t// FileMaker\n\tDBSystemFilemaker = DBSystemKey.String(\"filemaker\")\n\t// Informix\n\tDBSystemInformix = DBSystemKey.String(\"informix\")\n\t// InstantDB\n\tDBSystemInstantDB = DBSystemKey.String(\"instantdb\")\n\t// InterBase\n\tDBSystemInterbase = DBSystemKey.String(\"interbase\")\n\t// MariaDB\n\tDBSystemMariaDB = DBSystemKey.String(\"mariadb\")\n\t// Netezza\n\tDBSystemNetezza = DBSystemKey.String(\"netezza\")\n\t// Pervasive PSQL\n\tDBSystemPervasive = DBSystemKey.String(\"pervasive\")\n\t// PointBase\n\tDBSystemPointbase = DBSystemKey.String(\"pointbase\")\n\t// SQLite\n\tDBSystemSqlite = DBSystemKey.String(\"sqlite\")\n\t// Sybase\n\tDBSystemSybase = DBSystemKey.String(\"sybase\")\n\t// Teradata\n\tDBSystemTeradata = DBSystemKey.String(\"teradata\")\n\t// Vertica\n\tDBSystemVertica = DBSystemKey.String(\"vertica\")\n\t// H2\n\tDBSystemH2 = DBSystemKey.String(\"h2\")\n\t// ColdFusion IMQ\n\tDBSystemColdfusion = DBSystemKey.String(\"coldfusion\")\n\t// Apache Cassandra\n\tDBSystemCassandra = DBSystemKey.String(\"cassandra\")\n\t// Apache HBase\n\tDBSystemHBase = DBSystemKey.String(\"hbase\")\n\t// MongoDB\n\tDBSystemMongoDB = DBSystemKey.String(\"mongodb\")\n\t// Redis\n\tDBSystemRedis = DBSystemKey.String(\"redis\")\n\t// Couchbase\n\tDBSystemCouchbase = DBSystemKey.String(\"couchbase\")\n\t// CouchDB\n\tDBSystemCouchDB = DBSystemKey.String(\"couchdb\")\n\t// Microsoft Azure Cosmos DB\n\tDBSystemCosmosDB = DBSystemKey.String(\"cosmosdb\")\n\t// Amazon DynamoDB\n\tDBSystemDynamoDB = DBSystemKey.String(\"dynamodb\")\n\t// Neo4j\n\tDBSystemNeo4j = DBSystemKey.String(\"neo4j\")\n\t// Apache Geode\n\tDBSystemGeode = DBSystemKey.String(\"geode\")\n\t// Elasticsearch\n\tDBSystemElasticsearch = DBSystemKey.String(\"elasticsearch\")\n\t// Memcached\n\tDBSystemMemcached = DBSystemKey.String(\"memcached\")\n\t// CockroachDB\n\tDBSystemCockroachdb = DBSystemKey.String(\"cockroachdb\")\n)\n\n// Connection-level attributes for Microsoft SQL Server\nconst (\n\t// The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-\n\t// us/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15)\n\t// connecting to. This name is used to determine the port of a named instance.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'MSSQLSERVER'\n\t// Note: If setting a `db.mssql.instance_name`, `net.peer.port` is no longer\n\t// required (but still recommended if non-standard).\n\tDBMSSQLInstanceNameKey = attribute.Key(\"db.mssql.instance_name\")\n)\n\n// Call-level attributes for Cassandra\nconst (\n\t// The name of the keyspace being accessed. To be used instead of the generic\n\t// `db.name` attribute.\n\t//\n\t// Type: string\n\t// Required: Always\n\t// Stability: stable\n\t// Examples: 'mykeyspace'\n\tDBCassandraKeyspaceKey = attribute.Key(\"db.cassandra.keyspace\")\n\t// The fetch size used for paging, i.e. how many rows will be returned at once.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 5000\n\tDBCassandraPageSizeKey = attribute.Key(\"db.cassandra.page_size\")\n\t// The consistency level of the query. Based on consistency values from\n\t// [CQL](https://docs.datastax.com/en/cassandra-\n\t// oss/3.0/cassandra/dml/dmlConfigConsistency.html).\n\t//\n\t// Type: Enum\n\t// Required: No\n\t// Stability: stable\n\tDBCassandraConsistencyLevelKey = attribute.Key(\"db.cassandra.consistency_level\")\n\t// The name of the primary table that the operation is acting upon, including the\n\t// schema name (if applicable).\n\t//\n\t// Type: string\n\t// Required: Recommended if available.\n\t// Stability: stable\n\t// Examples: 'mytable'\n\t// Note: This mirrors the db.sql.table attribute but references cassandra rather\n\t// than sql. It is not recommended to attempt any client-side parsing of\n\t// `db.statement` just to get this property, but it should be set if it is\n\t// provided by the library being instrumented. If the operation is acting upon an\n\t// anonymous table, or more than one table, this value MUST NOT be set.\n\tDBCassandraTableKey = attribute.Key(\"db.cassandra.table\")\n\t// Whether or not the query is idempotent.\n\t//\n\t// Type: boolean\n\t// Required: No\n\t// Stability: stable\n\tDBCassandraIdempotenceKey = attribute.Key(\"db.cassandra.idempotence\")\n\t// The number of times a query was speculatively executed. Not set or `0` if the\n\t// query was not executed speculatively.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 0, 2\n\tDBCassandraSpeculativeExecutionCountKey = attribute.Key(\"db.cassandra.speculative_execution_count\")\n\t// The ID of the coordinating node for a query.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'be13faa2-8574-4d71-926d-27f16cf8a7af'\n\tDBCassandraCoordinatorIDKey = attribute.Key(\"db.cassandra.coordinator.id\")\n\t// The data center of the coordinating node for a query.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'us-west-2'\n\tDBCassandraCoordinatorDCKey = attribute.Key(\"db.cassandra.coordinator.dc\")\n)\n\nvar (\n\t// all\n\tDBCassandraConsistencyLevelAll = DBCassandraConsistencyLevelKey.String(\"all\")\n\t// each_quorum\n\tDBCassandraConsistencyLevelEachQuorum = DBCassandraConsistencyLevelKey.String(\"each_quorum\")\n\t// quorum\n\tDBCassandraConsistencyLevelQuorum = DBCassandraConsistencyLevelKey.String(\"quorum\")\n\t// local_quorum\n\tDBCassandraConsistencyLevelLocalQuorum = DBCassandraConsistencyLevelKey.String(\"local_quorum\")\n\t// one\n\tDBCassandraConsistencyLevelOne = DBCassandraConsistencyLevelKey.String(\"one\")\n\t// two\n\tDBCassandraConsistencyLevelTwo = DBCassandraConsistencyLevelKey.String(\"two\")\n\t// three\n\tDBCassandraConsistencyLevelThree = DBCassandraConsistencyLevelKey.String(\"three\")\n\t// local_one\n\tDBCassandraConsistencyLevelLocalOne = DBCassandraConsistencyLevelKey.String(\"local_one\")\n\t// any\n\tDBCassandraConsistencyLevelAny = DBCassandraConsistencyLevelKey.String(\"any\")\n\t// serial\n\tDBCassandraConsistencyLevelSerial = DBCassandraConsistencyLevelKey.String(\"serial\")\n\t// local_serial\n\tDBCassandraConsistencyLevelLocalSerial = DBCassandraConsistencyLevelKey.String(\"local_serial\")\n)\n\n// Call-level attributes for Apache HBase\nconst (\n\t// The [HBase namespace](https://hbase.apache.org/book.html#_namespace) being\n\t// accessed. To be used instead of the generic `db.name` attribute.\n\t//\n\t// Type: string\n\t// Required: Always\n\t// Stability: stable\n\t// Examples: 'default'\n\tDBHBaseNamespaceKey = attribute.Key(\"db.hbase.namespace\")\n)\n\n// Call-level attributes for Redis\nconst (\n\t// The index of the database being accessed as used in the [`SELECT`\n\t// command](https://redis.io/commands/select), provided as an integer. To be used\n\t// instead of the generic `db.name` attribute.\n\t//\n\t// Type: int\n\t// Required: Required, if other than the default database (`0`).\n\t// Stability: stable\n\t// Examples: 0, 1, 15\n\tDBRedisDBIndexKey = attribute.Key(\"db.redis.database_index\")\n)\n\n// Call-level attributes for MongoDB\nconst (\n\t// The collection being accessed within the database stated in `db.name`.\n\t//\n\t// Type: string\n\t// Required: Always\n\t// Stability: stable\n\t// Examples: 'customers', 'products'\n\tDBMongoDBCollectionKey = attribute.Key(\"db.mongodb.collection\")\n)\n\n// Call-level attrbiutes for SQL databases\nconst (\n\t// The name of the primary table that the operation is acting upon, including the\n\t// schema name (if applicable).\n\t//\n\t// Type: string\n\t// Required: Recommended if available.\n\t// Stability: stable\n\t// Examples: 'public.users', 'customers'\n\t// Note: It is not recommended to attempt any client-side parsing of\n\t// `db.statement` just to get this property, but it should be set if it is\n\t// provided by the library being instrumented. If the operation is acting upon an\n\t// anonymous table, or more than one table, this value MUST NOT be set.\n\tDBSQLTableKey = attribute.Key(\"db.sql.table\")\n)\n\n// This document defines the attributes used to report a single exception associated with a span.\nconst (\n\t// The type of the exception (its fully-qualified class name, if applicable). The\n\t// dynamic type of the exception should be preferred over the static type in\n\t// languages that support it.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'java.net.ConnectException', 'OSError'\n\tExceptionTypeKey = attribute.Key(\"exception.type\")\n\t// The exception message.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'Division by zero', \"Can't convert 'int' object to str implicitly\"\n\tExceptionMessageKey = attribute.Key(\"exception.message\")\n\t// A stacktrace as a string in the natural representation for the language\n\t// runtime. The representation is to be determined and documented by each language\n\t// SIG.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'Exception in thread \"main\" java.lang.RuntimeException: Test\n\t// exception\\\\n at '\n\t//  'com.example.GenerateTrace.methodB(GenerateTrace.java:13)\\\\n at '\n\t//  'com.example.GenerateTrace.methodA(GenerateTrace.java:9)\\\\n at '\n\t//  'com.example.GenerateTrace.main(GenerateTrace.java:5)'\n\tExceptionStacktraceKey = attribute.Key(\"exception.stacktrace\")\n\t// SHOULD be set to true if the exception event is recorded at a point where it is\n\t// known that the exception is escaping the scope of the span.\n\t//\n\t// Type: boolean\n\t// Required: No\n\t// Stability: stable\n\t// Note: An exception is considered to have escaped (or left) the scope of a span,\n\t// if that span is ended while the exception is still logically \"in flight\".\n\t// This may be actually \"in flight\" in some languages (e.g. if the exception\n\t// is passed to a Context manager's `__exit__` method in Python) but will\n\t// usually be caught at the point of recording the exception in most languages.\n\n\t// It is usually not possible to determine at the point where an exception is\n\t// thrown\n\t// whether it will escape the scope of a span.\n\t// However, it is trivial to know that an exception\n\t// will escape, if one checks for an active exception just before ending the span,\n\t// as done in the [example above](#exception-end-example).\n\n\t// It follows that an exception may still escape the scope of the span\n\t// even if the `exception.escaped` attribute was not set or set to false,\n\t// since the event might have been recorded at a time where it was not\n\t// clear whether the exception will escape.\n\tExceptionEscapedKey = attribute.Key(\"exception.escaped\")\n)\n\n// This semantic convention describes an instance of a function that runs without provisioning or managing of servers (also known as serverless functions or Function as a Service (FaaS)) with spans.\nconst (\n\t// Type of the trigger on which the function is executed.\n\t//\n\t// Type: Enum\n\t// Required: On FaaS instances, faas.trigger MUST be set on incoming invocations.\n\t// Clients invoking FaaS instances MUST set `faas.trigger` on outgoing\n\t// invocations, if it is known to the client. This is, for example, not the case,\n\t// when the transport layer is abstracted in a FaaS client framework without\n\t// access to its configuration.\n\t// Stability: stable\n\tFaaSTriggerKey = attribute.Key(\"faas.trigger\")\n\t// The execution ID of the current function execution.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28'\n\tFaaSExecutionKey = attribute.Key(\"faas.execution\")\n)\n\nvar (\n\t// A response to some data source operation such as a database or filesystem read/write\n\tFaaSTriggerDatasource = FaaSTriggerKey.String(\"datasource\")\n\t// To provide an answer to an inbound HTTP request\n\tFaaSTriggerHTTP = FaaSTriggerKey.String(\"http\")\n\t// A function is set to be executed when messages are sent to a messaging system\n\tFaaSTriggerPubsub = FaaSTriggerKey.String(\"pubsub\")\n\t// A function is scheduled to be executed regularly\n\tFaaSTriggerTimer = FaaSTriggerKey.String(\"timer\")\n\t// If none of the others apply\n\tFaaSTriggerOther = FaaSTriggerKey.String(\"other\")\n)\n\n// Semantic Convention for FaaS triggered as a response to some data source operation such as a database or filesystem read/write.\nconst (\n\t// The name of the source on which the triggering operation was performed. For\n\t// example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos\n\t// DB to the database name.\n\t//\n\t// Type: string\n\t// Required: Always\n\t// Stability: stable\n\t// Examples: 'myBucketName', 'myDBName'\n\tFaaSDocumentCollectionKey = attribute.Key(\"faas.document.collection\")\n\t// Describes the type of the operation that was performed on the data.\n\t//\n\t// Type: Enum\n\t// Required: Always\n\t// Stability: stable\n\tFaaSDocumentOperationKey = attribute.Key(\"faas.document.operation\")\n\t// A string containing the time when the data was accessed in the [ISO\n\t// 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed\n\t// in [UTC](https://www.w3.org/TR/NOTE-datetime).\n\t//\n\t// Type: string\n\t// Required: Always\n\t// Stability: stable\n\t// Examples: '2020-01-23T13:47:06Z'\n\tFaaSDocumentTimeKey = attribute.Key(\"faas.document.time\")\n\t// The document name/table subjected to the operation. For example, in Cloud\n\t// Storage or S3 is the name of the file, and in Cosmos DB the table name.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'myFile.txt', 'myTableName'\n\tFaaSDocumentNameKey = attribute.Key(\"faas.document.name\")\n)\n\nvar (\n\t// When a new object is created\n\tFaaSDocumentOperationInsert = FaaSDocumentOperationKey.String(\"insert\")\n\t// When an object is modified\n\tFaaSDocumentOperationEdit = FaaSDocumentOperationKey.String(\"edit\")\n\t// When an object is deleted\n\tFaaSDocumentOperationDelete = FaaSDocumentOperationKey.String(\"delete\")\n)\n\n// Semantic Convention for FaaS scheduled to be executed regularly.\nconst (\n\t// A string containing the function invocation time in the [ISO\n\t// 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed\n\t// in [UTC](https://www.w3.org/TR/NOTE-datetime).\n\t//\n\t// Type: string\n\t// Required: Always\n\t// Stability: stable\n\t// Examples: '2020-01-23T13:47:06Z'\n\tFaaSTimeKey = attribute.Key(\"faas.time\")\n\t// A string containing the schedule period as [Cron Expression](https://docs.oracl\n\t// e.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm).\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '0/5 * * * ? *'\n\tFaaSCronKey = attribute.Key(\"faas.cron\")\n)\n\n// Contains additional attributes for incoming FaaS spans.\nconst (\n\t// A boolean that is true if the serverless function is executed for the first\n\t// time (aka cold-start).\n\t//\n\t// Type: boolean\n\t// Required: No\n\t// Stability: stable\n\tFaaSColdstartKey = attribute.Key(\"faas.coldstart\")\n)\n\n// Contains additional attributes for outgoing FaaS spans.\nconst (\n\t// The name of the invoked function.\n\t//\n\t// Type: string\n\t// Required: Always\n\t// Stability: stable\n\t// Examples: 'my-function'\n\t// Note: SHOULD be equal to the `faas.name` resource attribute of the invoked\n\t// function.\n\tFaaSInvokedNameKey = attribute.Key(\"faas.invoked_name\")\n\t// The cloud provider of the invoked function.\n\t//\n\t// Type: Enum\n\t// Required: Always\n\t// Stability: stable\n\t// Note: SHOULD be equal to the `cloud.provider` resource attribute of the invoked\n\t// function.\n\tFaaSInvokedProviderKey = attribute.Key(\"faas.invoked_provider\")\n\t// The cloud region of the invoked function.\n\t//\n\t// Type: string\n\t// Required: For some cloud providers, like AWS or GCP, the region in which a\n\t// function is hosted is essential to uniquely identify the function and also part\n\t// of its endpoint. Since it's part of the endpoint being called, the region is\n\t// always known to clients. In these cases, `faas.invoked_region` MUST be set\n\t// accordingly. If the region is unknown to the client or not required for\n\t// identifying the invoked function, setting `faas.invoked_region` is optional.\n\t// Stability: stable\n\t// Examples: 'eu-central-1'\n\t// Note: SHOULD be equal to the `cloud.region` resource attribute of the invoked\n\t// function.\n\tFaaSInvokedRegionKey = attribute.Key(\"faas.invoked_region\")\n)\n\nvar (\n\t// Alibaba Cloud\n\tFaaSInvokedProviderAlibabaCloud = FaaSInvokedProviderKey.String(\"alibaba_cloud\")\n\t// Amazon Web Services\n\tFaaSInvokedProviderAWS = FaaSInvokedProviderKey.String(\"aws\")\n\t// Microsoft Azure\n\tFaaSInvokedProviderAzure = FaaSInvokedProviderKey.String(\"azure\")\n\t// Google Cloud Platform\n\tFaaSInvokedProviderGCP = FaaSInvokedProviderKey.String(\"gcp\")\n)\n\n// These attributes may be used for any network related operation.\nconst (\n\t// Transport protocol used. See note below.\n\t//\n\t// Type: Enum\n\t// Required: No\n\t// Stability: stable\n\tNetTransportKey = attribute.Key(\"net.transport\")\n\t// Remote address of the peer (dotted decimal for IPv4 or\n\t// [RFC5952](https://tools.ietf.org/html/rfc5952) for IPv6)\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '127.0.0.1'\n\tNetPeerIPKey = attribute.Key(\"net.peer.ip\")\n\t// Remote port number.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 80, 8080, 443\n\tNetPeerPortKey = attribute.Key(\"net.peer.port\")\n\t// Remote hostname or similar, see note below.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'example.com'\n\tNetPeerNameKey = attribute.Key(\"net.peer.name\")\n\t// Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '192.168.0.1'\n\tNetHostIPKey = attribute.Key(\"net.host.ip\")\n\t// Like `net.peer.port` but for the host port.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 35555\n\tNetHostPortKey = attribute.Key(\"net.host.port\")\n\t// Local hostname or similar, see note below.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'localhost'\n\tNetHostNameKey = attribute.Key(\"net.host.name\")\n\t// The internet connection type currently being used by the host.\n\t//\n\t// Type: Enum\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'wifi'\n\tNetHostConnectionTypeKey = attribute.Key(\"net.host.connection.type\")\n\t// This describes more details regarding the connection.type. It may be the type\n\t// of cell technology connection, but it could be used for describing details\n\t// about a wifi connection.\n\t//\n\t// Type: Enum\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'LTE'\n\tNetHostConnectionSubtypeKey = attribute.Key(\"net.host.connection.subtype\")\n\t// The name of the mobile carrier.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'sprint'\n\tNetHostCarrierNameKey = attribute.Key(\"net.host.carrier.name\")\n\t// The mobile carrier country code.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '310'\n\tNetHostCarrierMccKey = attribute.Key(\"net.host.carrier.mcc\")\n\t// The mobile carrier network code.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '001'\n\tNetHostCarrierMncKey = attribute.Key(\"net.host.carrier.mnc\")\n\t// The ISO 3166-1 alpha-2 2-character country code associated with the mobile\n\t// carrier network.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'DE'\n\tNetHostCarrierIccKey = attribute.Key(\"net.host.carrier.icc\")\n)\n\nvar (\n\t// ip_tcp\n\tNetTransportTCP = NetTransportKey.String(\"ip_tcp\")\n\t// ip_udp\n\tNetTransportUDP = NetTransportKey.String(\"ip_udp\")\n\t// Another IP-based protocol\n\tNetTransportIP = NetTransportKey.String(\"ip\")\n\t// Unix Domain socket. See below\n\tNetTransportUnix = NetTransportKey.String(\"unix\")\n\t// Named or anonymous pipe. See note below\n\tNetTransportPipe = NetTransportKey.String(\"pipe\")\n\t// In-process communication\n\tNetTransportInProc = NetTransportKey.String(\"inproc\")\n\t// Something else (non IP-based)\n\tNetTransportOther = NetTransportKey.String(\"other\")\n)\n\nvar (\n\t// wifi\n\tNetHostConnectionTypeWifi = NetHostConnectionTypeKey.String(\"wifi\")\n\t// wired\n\tNetHostConnectionTypeWired = NetHostConnectionTypeKey.String(\"wired\")\n\t// cell\n\tNetHostConnectionTypeCell = NetHostConnectionTypeKey.String(\"cell\")\n\t// unavailable\n\tNetHostConnectionTypeUnavailable = NetHostConnectionTypeKey.String(\"unavailable\")\n\t// unknown\n\tNetHostConnectionTypeUnknown = NetHostConnectionTypeKey.String(\"unknown\")\n)\n\nvar (\n\t// GPRS\n\tNetHostConnectionSubtypeGprs = NetHostConnectionSubtypeKey.String(\"gprs\")\n\t// EDGE\n\tNetHostConnectionSubtypeEdge = NetHostConnectionSubtypeKey.String(\"edge\")\n\t// UMTS\n\tNetHostConnectionSubtypeUmts = NetHostConnectionSubtypeKey.String(\"umts\")\n\t// CDMA\n\tNetHostConnectionSubtypeCdma = NetHostConnectionSubtypeKey.String(\"cdma\")\n\t// EVDO Rel. 0\n\tNetHostConnectionSubtypeEvdo0 = NetHostConnectionSubtypeKey.String(\"evdo_0\")\n\t// EVDO Rev. A\n\tNetHostConnectionSubtypeEvdoA = NetHostConnectionSubtypeKey.String(\"evdo_a\")\n\t// CDMA2000 1XRTT\n\tNetHostConnectionSubtypeCdma20001xrtt = NetHostConnectionSubtypeKey.String(\"cdma2000_1xrtt\")\n\t// HSDPA\n\tNetHostConnectionSubtypeHsdpa = NetHostConnectionSubtypeKey.String(\"hsdpa\")\n\t// HSUPA\n\tNetHostConnectionSubtypeHsupa = NetHostConnectionSubtypeKey.String(\"hsupa\")\n\t// HSPA\n\tNetHostConnectionSubtypeHspa = NetHostConnectionSubtypeKey.String(\"hspa\")\n\t// IDEN\n\tNetHostConnectionSubtypeIden = NetHostConnectionSubtypeKey.String(\"iden\")\n\t// EVDO Rev. B\n\tNetHostConnectionSubtypeEvdoB = NetHostConnectionSubtypeKey.String(\"evdo_b\")\n\t// LTE\n\tNetHostConnectionSubtypeLte = NetHostConnectionSubtypeKey.String(\"lte\")\n\t// EHRPD\n\tNetHostConnectionSubtypeEhrpd = NetHostConnectionSubtypeKey.String(\"ehrpd\")\n\t// HSPAP\n\tNetHostConnectionSubtypeHspap = NetHostConnectionSubtypeKey.String(\"hspap\")\n\t// GSM\n\tNetHostConnectionSubtypeGsm = NetHostConnectionSubtypeKey.String(\"gsm\")\n\t// TD-SCDMA\n\tNetHostConnectionSubtypeTdScdma = NetHostConnectionSubtypeKey.String(\"td_scdma\")\n\t// IWLAN\n\tNetHostConnectionSubtypeIwlan = NetHostConnectionSubtypeKey.String(\"iwlan\")\n\t// 5G NR (New Radio)\n\tNetHostConnectionSubtypeNr = NetHostConnectionSubtypeKey.String(\"nr\")\n\t// 5G NRNSA (New Radio Non-Standalone)\n\tNetHostConnectionSubtypeNrnsa = NetHostConnectionSubtypeKey.String(\"nrnsa\")\n\t// LTE CA\n\tNetHostConnectionSubtypeLteCa = NetHostConnectionSubtypeKey.String(\"lte_ca\")\n)\n\n// Operations that access some remote service.\nconst (\n\t// The [`service.name`](../../resource/semantic_conventions/README.md#service) of\n\t// the remote service. SHOULD be equal to the actual `service.name` resource\n\t// attribute of the remote service if any.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'AuthTokenCache'\n\tPeerServiceKey = attribute.Key(\"peer.service\")\n)\n\n// These attributes may be used for any operation with an authenticated and/or authorized enduser.\nconst (\n\t// Username or client_id extracted from the access token or\n\t// [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the\n\t// inbound request from outside the system.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'username'\n\tEnduserIDKey = attribute.Key(\"enduser.id\")\n\t// Actual/assumed role the client is making the request under extracted from token\n\t// or application security context.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'admin'\n\tEnduserRoleKey = attribute.Key(\"enduser.role\")\n\t// Scopes or granted authorities the client currently possesses extracted from\n\t// token or application security context. The value would come from the scope\n\t// associated with an [OAuth 2.0 Access\n\t// Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute value\n\t// in a [SAML 2.0 Assertion](http://docs.oasis-\n\t// open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html).\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'read:message, write:files'\n\tEnduserScopeKey = attribute.Key(\"enduser.scope\")\n)\n\n// These attributes may be used for any operation to store information about a thread that started a span.\nconst (\n\t// Current \"managed\" thread ID (as opposed to OS thread ID).\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 42\n\tThreadIDKey = attribute.Key(\"thread.id\")\n\t// Current thread name.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'main'\n\tThreadNameKey = attribute.Key(\"thread.name\")\n)\n\n// These attributes allow to report this unit of code and therefore to provide more context about the span.\nconst (\n\t// The method or function name, or equivalent (usually rightmost part of the code\n\t// unit's name).\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'serveRequest'\n\tCodeFunctionKey = attribute.Key(\"code.function\")\n\t// The \"namespace\" within which `code.function` is defined. Usually the qualified\n\t// class or module name, such that `code.namespace` + some separator +\n\t// `code.function` form a unique identifier for the code unit.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'com.example.MyHTTPService'\n\tCodeNamespaceKey = attribute.Key(\"code.namespace\")\n\t// The source code file name that identifies the code unit as uniquely as possible\n\t// (preferably an absolute file path).\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '/usr/local/MyApplication/content_root/app/index.php'\n\tCodeFilepathKey = attribute.Key(\"code.filepath\")\n\t// The line number in `code.filepath` best representing the operation. It SHOULD\n\t// point within the code unit named in `code.function`.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 42\n\tCodeLineNumberKey = attribute.Key(\"code.lineno\")\n)\n\n// This document defines semantic conventions for HTTP client and server Spans.\nconst (\n\t// HTTP request method.\n\t//\n\t// Type: string\n\t// Required: Always\n\t// Stability: stable\n\t// Examples: 'GET', 'POST', 'HEAD'\n\tHTTPMethodKey = attribute.Key(\"http.method\")\n\t// Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`.\n\t// Usually the fragment is not transmitted over HTTP, but if it is known, it\n\t// should be included nevertheless.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'https://www.foo.bar/search?q=OpenTelemetry#SemConv'\n\t// Note: `http.url` MUST NOT contain credentials passed via URL in form of\n\t// `https://username:password@www.example.com/`. In such case the attribute's\n\t// value should be `https://www.example.com/`.\n\tHTTPURLKey = attribute.Key(\"http.url\")\n\t// The full request target as passed in a HTTP request line or equivalent.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '/path/12314/?q=ddds#123'\n\tHTTPTargetKey = attribute.Key(\"http.target\")\n\t// The value of the [HTTP host\n\t// header](https://tools.ietf.org/html/rfc7230#section-5.4). An empty Host header\n\t// should also be reported, see note.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'www.example.org'\n\t// Note: When the header is present but empty the attribute SHOULD be set to the\n\t// empty string. Note that this is a valid situation that is expected in certain\n\t// cases, according the aforementioned [section of RFC\n\t// 7230](https://tools.ietf.org/html/rfc7230#section-5.4). When the header is not\n\t// set the attribute MUST NOT be set.\n\tHTTPHostKey = attribute.Key(\"http.host\")\n\t// The URI scheme identifying the used protocol.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'http', 'https'\n\tHTTPSchemeKey = attribute.Key(\"http.scheme\")\n\t// [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).\n\t//\n\t// Type: int\n\t// Required: If and only if one was received/sent.\n\t// Stability: stable\n\t// Examples: 200\n\tHTTPStatusCodeKey = attribute.Key(\"http.status_code\")\n\t// Kind of HTTP protocol used.\n\t//\n\t// Type: Enum\n\t// Required: No\n\t// Stability: stable\n\t// Note: If `net.transport` is not specified, it can be assumed to be `IP.TCP`\n\t// except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed.\n\tHTTPFlavorKey = attribute.Key(\"http.flavor\")\n\t// Value of the [HTTP User-\n\t// Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) header sent by the\n\t// client.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'CERN-LineMode/2.15 libwww/2.17b3'\n\tHTTPUserAgentKey = attribute.Key(\"http.user_agent\")\n\t// The size of the request payload body in bytes. This is the number of bytes\n\t// transferred excluding headers and is often, but not always, present as the\n\t// [Content-Length](https://tools.ietf.org/html/rfc7230#section-3.3.2) header. For\n\t// requests using transport encoding, this should be the compressed size.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 3495\n\tHTTPRequestContentLengthKey = attribute.Key(\"http.request_content_length\")\n\t// The size of the uncompressed request payload body after transport decoding. Not\n\t// set if transport encoding not used.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 5493\n\tHTTPRequestContentLengthUncompressedKey = attribute.Key(\"http.request_content_length_uncompressed\")\n\t// The size of the response payload body in bytes. This is the number of bytes\n\t// transferred excluding headers and is often, but not always, present as the\n\t// [Content-Length](https://tools.ietf.org/html/rfc7230#section-3.3.2) header. For\n\t// requests using transport encoding, this should be the compressed size.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 3495\n\tHTTPResponseContentLengthKey = attribute.Key(\"http.response_content_length\")\n\t// The size of the uncompressed response payload body after transport decoding.\n\t// Not set if transport encoding not used.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 5493\n\tHTTPResponseContentLengthUncompressedKey = attribute.Key(\"http.response_content_length_uncompressed\")\n)\n\nvar (\n\t// HTTP 1.0\n\tHTTPFlavorHTTP10 = HTTPFlavorKey.String(\"1.0\")\n\t// HTTP 1.1\n\tHTTPFlavorHTTP11 = HTTPFlavorKey.String(\"1.1\")\n\t// HTTP 2\n\tHTTPFlavorHTTP20 = HTTPFlavorKey.String(\"2.0\")\n\t// SPDY protocol\n\tHTTPFlavorSPDY = HTTPFlavorKey.String(\"SPDY\")\n\t// QUIC protocol\n\tHTTPFlavorQUIC = HTTPFlavorKey.String(\"QUIC\")\n)\n\n// Semantic Convention for HTTP Server\nconst (\n\t// The primary server name of the matched virtual host. This should be obtained\n\t// via configuration. If no such configuration can be obtained, this attribute\n\t// MUST NOT be set ( `net.host.name` should be used instead).\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'example.com'\n\t// Note: `http.url` is usually not readily available on the server side but would\n\t// have to be assembled in a cumbersome and sometimes lossy process from other\n\t// information (see e.g. open-telemetry/opentelemetry-python/pull/148). It is thus\n\t// preferred to supply the raw data that is available.\n\tHTTPServerNameKey = attribute.Key(\"http.server_name\")\n\t// The matched route (path template).\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '/users/:userID?'\n\tHTTPRouteKey = attribute.Key(\"http.route\")\n\t// The IP address of the original client behind all proxies, if known (e.g. from\n\t// [X-Forwarded-For](https://developer.mozilla.org/en-\n\t// US/docs/Web/HTTP/Headers/X-Forwarded-For)).\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '83.164.160.102'\n\t// Note: This is not necessarily the same as `net.peer.ip`, which would\n\t// identify the network-level peer, which may be a proxy.\n\n\t// This attribute should be set when a source of information different\n\t// from the one used for `net.peer.ip`, is available even if that other\n\t// source just confirms the same value as `net.peer.ip`.\n\t// Rationale: For `net.peer.ip`, one typically does not know if it\n\t// comes from a proxy, reverse proxy, or the actual client. Setting\n\t// `http.client_ip` when it's the same as `net.peer.ip` means that\n\t// one is at least somewhat confident that the address is not that of\n\t// the closest proxy.\n\tHTTPClientIPKey = attribute.Key(\"http.client_ip\")\n)\n\n// Attributes that exist for multiple DynamoDB request types.\nconst (\n\t// The keys in the `RequestItems` object field.\n\t//\n\t// Type: string[]\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'Users', 'Cats'\n\tAWSDynamoDBTableNamesKey = attribute.Key(\"aws.dynamodb.table_names\")\n\t// The JSON-serialized value of each item in the `ConsumedCapacity` response\n\t// field.\n\t//\n\t// Type: string[]\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '{ \"CapacityUnits\": number, \"GlobalSecondaryIndexes\": { \"string\" : {\n\t// \"CapacityUnits\": number, \"ReadCapacityUnits\": number, \"WriteCapacityUnits\":\n\t// number } }, \"LocalSecondaryIndexes\": { \"string\" : { \"CapacityUnits\": number,\n\t// \"ReadCapacityUnits\": number, \"WriteCapacityUnits\": number } },\n\t// \"ReadCapacityUnits\": number, \"Table\": { \"CapacityUnits\": number,\n\t// \"ReadCapacityUnits\": number, \"WriteCapacityUnits\": number }, \"TableName\":\n\t// \"string\", \"WriteCapacityUnits\": number }'\n\tAWSDynamoDBConsumedCapacityKey = attribute.Key(\"aws.dynamodb.consumed_capacity\")\n\t// The JSON-serialized value of the `ItemCollectionMetrics` response field.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '{ \"string\" : [ { \"ItemCollectionKey\": { \"string\" : { \"B\": blob,\n\t// \"BOOL\": boolean, \"BS\": [ blob ], \"L\": [ \"AttributeValue\" ], \"M\": { \"string\" :\n\t// \"AttributeValue\" }, \"N\": \"string\", \"NS\": [ \"string\" ], \"NULL\": boolean, \"S\":\n\t// \"string\", \"SS\": [ \"string\" ] } }, \"SizeEstimateRangeGB\": [ number ] } ] }'\n\tAWSDynamoDBItemCollectionMetricsKey = attribute.Key(\"aws.dynamodb.item_collection_metrics\")\n\t// The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter.\n\t//\n\t// Type: double\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 1.0, 2.0\n\tAWSDynamoDBProvisionedReadCapacityKey = attribute.Key(\"aws.dynamodb.provisioned_read_capacity\")\n\t// The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter.\n\t//\n\t// Type: double\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 1.0, 2.0\n\tAWSDynamoDBProvisionedWriteCapacityKey = attribute.Key(\"aws.dynamodb.provisioned_write_capacity\")\n\t// The value of the `ConsistentRead` request parameter.\n\t//\n\t// Type: boolean\n\t// Required: No\n\t// Stability: stable\n\tAWSDynamoDBConsistentReadKey = attribute.Key(\"aws.dynamodb.consistent_read\")\n\t// The value of the `ProjectionExpression` request parameter.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'Title', 'Title, Price, Color', 'Title, Description, RelatedItems,\n\t// ProductReviews'\n\tAWSDynamoDBProjectionKey = attribute.Key(\"aws.dynamodb.projection\")\n\t// The value of the `Limit` request parameter.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 10\n\tAWSDynamoDBLimitKey = attribute.Key(\"aws.dynamodb.limit\")\n\t// The value of the `AttributesToGet` request parameter.\n\t//\n\t// Type: string[]\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'lives', 'id'\n\tAWSDynamoDBAttributesToGetKey = attribute.Key(\"aws.dynamodb.attributes_to_get\")\n\t// The value of the `IndexName` request parameter.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'name_to_group'\n\tAWSDynamoDBIndexNameKey = attribute.Key(\"aws.dynamodb.index_name\")\n\t// The value of the `Select` request parameter.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'ALL_ATTRIBUTES', 'COUNT'\n\tAWSDynamoDBSelectKey = attribute.Key(\"aws.dynamodb.select\")\n)\n\n// DynamoDB.CreateTable\nconst (\n\t// The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request\n\t// field\n\t//\n\t// Type: string[]\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '{ \"IndexName\": \"string\", \"KeySchema\": [ { \"AttributeName\": \"string\",\n\t// \"KeyType\": \"string\" } ], \"Projection\": { \"NonKeyAttributes\": [ \"string\" ],\n\t// \"ProjectionType\": \"string\" }, \"ProvisionedThroughput\": { \"ReadCapacityUnits\":\n\t// number, \"WriteCapacityUnits\": number } }'\n\tAWSDynamoDBGlobalSecondaryIndexesKey = attribute.Key(\"aws.dynamodb.global_secondary_indexes\")\n\t// The JSON-serialized value of each item of the `LocalSecondaryIndexes` request\n\t// field.\n\t//\n\t// Type: string[]\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '{ \"IndexARN\": \"string\", \"IndexName\": \"string\", \"IndexSizeBytes\":\n\t// number, \"ItemCount\": number, \"KeySchema\": [ { \"AttributeName\": \"string\",\n\t// \"KeyType\": \"string\" } ], \"Projection\": { \"NonKeyAttributes\": [ \"string\" ],\n\t// \"ProjectionType\": \"string\" } }'\n\tAWSDynamoDBLocalSecondaryIndexesKey = attribute.Key(\"aws.dynamodb.local_secondary_indexes\")\n)\n\n// DynamoDB.ListTables\nconst (\n\t// The value of the `ExclusiveStartTableName` request parameter.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'Users', 'CatsTable'\n\tAWSDynamoDBExclusiveStartTableKey = attribute.Key(\"aws.dynamodb.exclusive_start_table\")\n\t// The number of items in the `TableNames` response parameter.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 20\n\tAWSDynamoDBTableCountKey = attribute.Key(\"aws.dynamodb.table_count\")\n)\n\n// DynamoDB.Query\nconst (\n\t// The value of the `ScanIndexForward` request parameter.\n\t//\n\t// Type: boolean\n\t// Required: No\n\t// Stability: stable\n\tAWSDynamoDBScanForwardKey = attribute.Key(\"aws.dynamodb.scan_forward\")\n)\n\n// DynamoDB.Scan\nconst (\n\t// The value of the `Segment` request parameter.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 10\n\tAWSDynamoDBSegmentKey = attribute.Key(\"aws.dynamodb.segment\")\n\t// The value of the `TotalSegments` request parameter.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 100\n\tAWSDynamoDBTotalSegmentsKey = attribute.Key(\"aws.dynamodb.total_segments\")\n\t// The value of the `Count` response parameter.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 10\n\tAWSDynamoDBCountKey = attribute.Key(\"aws.dynamodb.count\")\n\t// The value of the `ScannedCount` response parameter.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 50\n\tAWSDynamoDBScannedCountKey = attribute.Key(\"aws.dynamodb.scanned_count\")\n)\n\n// DynamoDB.UpdateTable\nconst (\n\t// The JSON-serialized value of each item in the `AttributeDefinitions` request\n\t// field.\n\t//\n\t// Type: string[]\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '{ \"AttributeName\": \"string\", \"AttributeType\": \"string\" }'\n\tAWSDynamoDBAttributeDefinitionsKey = attribute.Key(\"aws.dynamodb.attribute_definitions\")\n\t// The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates`\n\t// request field.\n\t//\n\t// Type: string[]\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '{ \"Create\": { \"IndexName\": \"string\", \"KeySchema\": [ {\n\t// \"AttributeName\": \"string\", \"KeyType\": \"string\" } ], \"Projection\": {\n\t// \"NonKeyAttributes\": [ \"string\" ], \"ProjectionType\": \"string\" },\n\t// \"ProvisionedThroughput\": { \"ReadCapacityUnits\": number, \"WriteCapacityUnits\":\n\t// number } }'\n\tAWSDynamoDBGlobalSecondaryIndexUpdatesKey = attribute.Key(\"aws.dynamodb.global_secondary_index_updates\")\n)\n\n// This document defines the attributes used in messaging systems.\nconst (\n\t// A string identifying the messaging system.\n\t//\n\t// Type: string\n\t// Required: Always\n\t// Stability: stable\n\t// Examples: 'kafka', 'rabbitmq', 'activemq', 'AmazonSQS'\n\tMessagingSystemKey = attribute.Key(\"messaging.system\")\n\t// The message destination name. This might be equal to the span name but is\n\t// required nevertheless.\n\t//\n\t// Type: string\n\t// Required: Always\n\t// Stability: stable\n\t// Examples: 'MyQueue', 'MyTopic'\n\tMessagingDestinationKey = attribute.Key(\"messaging.destination\")\n\t// The kind of message destination\n\t//\n\t// Type: Enum\n\t// Required: Required only if the message destination is either a `queue` or\n\t// `topic`.\n\t// Stability: stable\n\tMessagingDestinationKindKey = attribute.Key(\"messaging.destination_kind\")\n\t// A boolean that is true if the message destination is temporary.\n\t//\n\t// Type: boolean\n\t// Required: If missing, it is assumed to be false.\n\t// Stability: stable\n\tMessagingTempDestinationKey = attribute.Key(\"messaging.temp_destination\")\n\t// The name of the transport protocol.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'AMQP', 'MQTT'\n\tMessagingProtocolKey = attribute.Key(\"messaging.protocol\")\n\t// The version of the transport protocol.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '0.9.1'\n\tMessagingProtocolVersionKey = attribute.Key(\"messaging.protocol_version\")\n\t// Connection string.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'tibjmsnaming://localhost:7222',\n\t// 'https://queue.amazonaws.com/80398EXAMPLE/MyQueue'\n\tMessagingURLKey = attribute.Key(\"messaging.url\")\n\t// A value used by the messaging system as an identifier for the message,\n\t// represented as a string.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '452a7c7c7c7048c2f887f61572b18fc2'\n\tMessagingMessageIDKey = attribute.Key(\"messaging.message_id\")\n\t// The [conversation ID](#conversations) identifying the conversation to which the\n\t// message belongs, represented as a string. Sometimes called \"Correlation ID\".\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'MyConversationID'\n\tMessagingConversationIDKey = attribute.Key(\"messaging.conversation_id\")\n\t// The (uncompressed) size of the message payload in bytes. Also use this\n\t// attribute if it is unknown whether the compressed or uncompressed payload size\n\t// is reported.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 2738\n\tMessagingMessagePayloadSizeBytesKey = attribute.Key(\"messaging.message_payload_size_bytes\")\n\t// The compressed size of the message payload in bytes.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 2048\n\tMessagingMessagePayloadCompressedSizeBytesKey = attribute.Key(\"messaging.message_payload_compressed_size_bytes\")\n)\n\nvar (\n\t// A message sent to a queue\n\tMessagingDestinationKindQueue = MessagingDestinationKindKey.String(\"queue\")\n\t// A message sent to a topic\n\tMessagingDestinationKindTopic = MessagingDestinationKindKey.String(\"topic\")\n)\n\n// Semantic convention for a consumer of messages received from a messaging system\nconst (\n\t// A string identifying the kind of message consumption as defined in the\n\t// [Operation names](#operation-names) section above. If the operation is \"send\",\n\t// this attribute MUST NOT be set, since the operation can be inferred from the\n\t// span kind in that case.\n\t//\n\t// Type: Enum\n\t// Required: No\n\t// Stability: stable\n\tMessagingOperationKey = attribute.Key(\"messaging.operation\")\n\t// The identifier for the consumer receiving a message. For Kafka, set it to\n\t// `{messaging.kafka.consumer_group} - {messaging.kafka.client_id}`, if both are\n\t// present, or only `messaging.kafka.consumer_group`. For brokers, such as\n\t// RabbitMQ and Artemis, set it to the `client_id` of the client consuming the\n\t// message.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'mygroup - client-6'\n\tMessagingConsumerIDKey = attribute.Key(\"messaging.consumer_id\")\n)\n\nvar (\n\t// receive\n\tMessagingOperationReceive = MessagingOperationKey.String(\"receive\")\n\t// process\n\tMessagingOperationProcess = MessagingOperationKey.String(\"process\")\n)\n\n// Attributes for RabbitMQ\nconst (\n\t// RabbitMQ message routing key.\n\t//\n\t// Type: string\n\t// Required: Unless it is empty.\n\t// Stability: stable\n\t// Examples: 'myKey'\n\tMessagingRabbitmqRoutingKeyKey = attribute.Key(\"messaging.rabbitmq.routing_key\")\n)\n\n// Attributes for Apache Kafka\nconst (\n\t// Message keys in Kafka are used for grouping alike messages to ensure they're\n\t// processed on the same partition. They differ from `messaging.message_id` in\n\t// that they're not unique. If the key is `null`, the attribute MUST NOT be set.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'myKey'\n\t// Note: If the key type is not string, it's string representation has to be\n\t// supplied for the attribute. If the key has no unambiguous, canonical string\n\t// form, don't include its value.\n\tMessagingKafkaMessageKeyKey = attribute.Key(\"messaging.kafka.message_key\")\n\t// Name of the Kafka Consumer Group that is handling the message. Only applies to\n\t// consumers, not producers.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'my-group'\n\tMessagingKafkaConsumerGroupKey = attribute.Key(\"messaging.kafka.consumer_group\")\n\t// Client ID for the Consumer or Producer that is handling the message.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'client-5'\n\tMessagingKafkaClientIDKey = attribute.Key(\"messaging.kafka.client_id\")\n\t// Partition the message is sent to.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 2\n\tMessagingKafkaPartitionKey = attribute.Key(\"messaging.kafka.partition\")\n\t// A boolean that is true if the message is a tombstone.\n\t//\n\t// Type: boolean\n\t// Required: If missing, it is assumed to be false.\n\t// Stability: stable\n\tMessagingKafkaTombstoneKey = attribute.Key(\"messaging.kafka.tombstone\")\n)\n\n// This document defines semantic conventions for remote procedure calls.\nconst (\n\t// A string identifying the remoting system.\n\t//\n\t// Type: string\n\t// Required: Always\n\t// Stability: stable\n\t// Examples: 'grpc', 'java_rmi', 'wcf'\n\tRPCSystemKey = attribute.Key(\"rpc.system\")\n\t// The full (logical) name of the service being called, including its package\n\t// name, if applicable.\n\t//\n\t// Type: string\n\t// Required: No, but recommended\n\t// Stability: stable\n\t// Examples: 'myservice.EchoService'\n\t// Note: This is the logical name of the service from the RPC interface\n\t// perspective, which can be different from the name of any implementing class.\n\t// The `code.namespace` attribute may be used to store the latter (despite the\n\t// attribute name, it may include a class name; e.g., class with method actually\n\t// executing the call on the server side, RPC client stub class on the client\n\t// side).\n\tRPCServiceKey = attribute.Key(\"rpc.service\")\n\t// The name of the (logical) method being called, must be equal to the $method\n\t// part in the span name.\n\t//\n\t// Type: string\n\t// Required: No, but recommended\n\t// Stability: stable\n\t// Examples: 'exampleMethod'\n\t// Note: This is the logical name of the method from the RPC interface\n\t// perspective, which can be different from the name of any implementing\n\t// method/function. The `code.function` attribute may be used to store the latter\n\t// (e.g., method actually executing the call on the server side, RPC client stub\n\t// method on the client side).\n\tRPCMethodKey = attribute.Key(\"rpc.method\")\n)\n\n// Tech-specific attributes for gRPC.\nconst (\n\t// The [numeric status\n\t// code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC\n\t// request.\n\t//\n\t// Type: Enum\n\t// Required: Always\n\t// Stability: stable\n\tRPCGRPCStatusCodeKey = attribute.Key(\"rpc.grpc.status_code\")\n)\n\nvar (\n\t// OK\n\tRPCGRPCStatusCodeOk = RPCGRPCStatusCodeKey.Int(0)\n\t// CANCELLED\n\tRPCGRPCStatusCodeCancelled = RPCGRPCStatusCodeKey.Int(1)\n\t// UNKNOWN\n\tRPCGRPCStatusCodeUnknown = RPCGRPCStatusCodeKey.Int(2)\n\t// INVALID_ARGUMENT\n\tRPCGRPCStatusCodeInvalidArgument = RPCGRPCStatusCodeKey.Int(3)\n\t// DEADLINE_EXCEEDED\n\tRPCGRPCStatusCodeDeadlineExceeded = RPCGRPCStatusCodeKey.Int(4)\n\t// NOT_FOUND\n\tRPCGRPCStatusCodeNotFound = RPCGRPCStatusCodeKey.Int(5)\n\t// ALREADY_EXISTS\n\tRPCGRPCStatusCodeAlreadyExists = RPCGRPCStatusCodeKey.Int(6)\n\t// PERMISSION_DENIED\n\tRPCGRPCStatusCodePermissionDenied = RPCGRPCStatusCodeKey.Int(7)\n\t// RESOURCE_EXHAUSTED\n\tRPCGRPCStatusCodeResourceExhausted = RPCGRPCStatusCodeKey.Int(8)\n\t// FAILED_PRECONDITION\n\tRPCGRPCStatusCodeFailedPrecondition = RPCGRPCStatusCodeKey.Int(9)\n\t// ABORTED\n\tRPCGRPCStatusCodeAborted = RPCGRPCStatusCodeKey.Int(10)\n\t// OUT_OF_RANGE\n\tRPCGRPCStatusCodeOutOfRange = RPCGRPCStatusCodeKey.Int(11)\n\t// UNIMPLEMENTED\n\tRPCGRPCStatusCodeUnimplemented = RPCGRPCStatusCodeKey.Int(12)\n\t// INTERNAL\n\tRPCGRPCStatusCodeInternal = RPCGRPCStatusCodeKey.Int(13)\n\t// UNAVAILABLE\n\tRPCGRPCStatusCodeUnavailable = RPCGRPCStatusCodeKey.Int(14)\n\t// DATA_LOSS\n\tRPCGRPCStatusCodeDataLoss = RPCGRPCStatusCodeKey.Int(15)\n\t// UNAUTHENTICATED\n\tRPCGRPCStatusCodeUnauthenticated = RPCGRPCStatusCodeKey.Int(16)\n)\n\n// Tech-specific attributes for [JSON RPC](https://www.jsonrpc.org/).\nconst (\n\t// Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC\n\t// 1.0 does not specify this, the value can be omitted.\n\t//\n\t// Type: string\n\t// Required: If missing, it is assumed to be \"1.0\".\n\t// Stability: stable\n\t// Examples: '2.0', '1.0'\n\tRPCJsonrpcVersionKey = attribute.Key(\"rpc.jsonrpc.version\")\n\t// `id` property of request or response. Since protocol allows id to be int,\n\t// string, `null` or missing (for notifications), value is expected to be cast to\n\t// string for simplicity. Use empty string in case of `null` value. Omit entirely\n\t// if this is a notification.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: '10', 'request-7', ''\n\tRPCJsonrpcRequestIDKey = attribute.Key(\"rpc.jsonrpc.request_id\")\n\t// `error.code` property of response if it is an error response.\n\t//\n\t// Type: int\n\t// Required: If missing, response is assumed to be successful.\n\t// Stability: stable\n\t// Examples: -32700, 100\n\tRPCJsonrpcErrorCodeKey = attribute.Key(\"rpc.jsonrpc.error_code\")\n\t// `error.message` property of response if it is an error response.\n\t//\n\t// Type: string\n\t// Required: No\n\t// Stability: stable\n\t// Examples: 'Parse error', 'User already exists'\n\tRPCJsonrpcErrorMessageKey = attribute.Key(\"rpc.jsonrpc.error_message\")\n)\n\n// RPC received/sent message.\nconst (\n\t// Whether this is a received or sent message.\n\t//\n\t// Type: Enum\n\t// Required: No\n\t// Stability: stable\n\tMessageTypeKey = attribute.Key(\"message.type\")\n\t// MUST be calculated as two different counters starting from `1` one for sent\n\t// messages and one for received message.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\t// Note: This way we guarantee that the values will be consistent between\n\t// different implementations.\n\tMessageIDKey = attribute.Key(\"message.id\")\n\t// Compressed size of the message in bytes.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\tMessageCompressedSizeKey = attribute.Key(\"message.compressed_size\")\n\t// Uncompressed size of the message in bytes.\n\t//\n\t// Type: int\n\t// Required: No\n\t// Stability: stable\n\tMessageUncompressedSizeKey = attribute.Key(\"message.uncompressed_size\")\n)\n\nvar (\n\t// sent\n\tMessageTypeSent = MessageTypeKey.String(\"SENT\")\n\t// received\n\tMessageTypeReceived = MessageTypeKey.String(\"RECEIVED\")\n)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n--------------------------------------------------------------------------------\n\nCopyright 2009 The Go Authors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google LLC nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/README.md",
    "content": "# Trace API\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/trace)](https://pkg.go.dev/go.opentelemetry.io/otel/trace)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/auto.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"math\"\n\t\"os\"\n\t\"reflect\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\t\"unicode/utf8\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.39.0\"\n\t\"go.opentelemetry.io/otel/trace/embedded\"\n\t\"go.opentelemetry.io/otel/trace/internal/telemetry\"\n)\n\n// newAutoTracerProvider returns an auto-instrumentable [trace.TracerProvider].\n// If an [go.opentelemetry.io/auto.Instrumentation] is configured to instrument\n// the process using the returned TracerProvider, all of the telemetry it\n// produces will be processed and handled by that Instrumentation. By default,\n// if no Instrumentation instruments the TracerProvider it will not generate\n// any trace telemetry.\nfunc newAutoTracerProvider() TracerProvider { return tracerProviderInstance }\n\nvar tracerProviderInstance = new(autoTracerProvider)\n\ntype autoTracerProvider struct{ embedded.TracerProvider }\n\nvar _ TracerProvider = autoTracerProvider{}\n\nfunc (autoTracerProvider) Tracer(name string, opts ...TracerOption) Tracer {\n\tcfg := NewTracerConfig(opts...)\n\treturn autoTracer{\n\t\tname:      name,\n\t\tversion:   cfg.InstrumentationVersion(),\n\t\tschemaURL: cfg.SchemaURL(),\n\t}\n}\n\ntype autoTracer struct {\n\tembedded.Tracer\n\n\tname, schemaURL, version string\n}\n\nvar _ Tracer = autoTracer{}\n\nfunc (t autoTracer) Start(ctx context.Context, name string, opts ...SpanStartOption) (context.Context, Span) {\n\tvar psc, sc SpanContext\n\tsampled := true\n\tspan := new(autoSpan)\n\n\t// Ask eBPF for sampling decision and span context info.\n\tt.start(ctx, span, &psc, &sampled, &sc)\n\n\tspan.sampled.Store(sampled)\n\tspan.spanContext = sc\n\n\tctx = ContextWithSpan(ctx, span)\n\n\tif sampled {\n\t\t// Only build traces if sampled.\n\t\tcfg := NewSpanStartConfig(opts...)\n\t\tspan.traces, span.span = t.traces(name, cfg, span.spanContext, psc)\n\t}\n\n\treturn ctx, span\n}\n\n// Expected to be implemented in eBPF.\n//\n//go:noinline\nfunc (*autoTracer) start(\n\tctx context.Context,\n\tspanPtr *autoSpan,\n\tpsc *SpanContext,\n\tsampled *bool,\n\tsc *SpanContext,\n) {\n\tstart(ctx, spanPtr, psc, sampled, sc)\n}\n\n// start is used for testing.\nvar start = func(context.Context, *autoSpan, *SpanContext, *bool, *SpanContext) {}\n\nfunc (t autoTracer) traces(name string, cfg SpanConfig, sc, psc SpanContext) (*telemetry.Traces, *telemetry.Span) {\n\tspan := &telemetry.Span{\n\t\tTraceID:      telemetry.TraceID(sc.TraceID()),\n\t\tSpanID:       telemetry.SpanID(sc.SpanID()),\n\t\tFlags:        uint32(sc.TraceFlags()),\n\t\tTraceState:   sc.TraceState().String(),\n\t\tParentSpanID: telemetry.SpanID(psc.SpanID()),\n\t\tName:         name,\n\t\tKind:         spanKind(cfg.SpanKind()),\n\t}\n\n\tspan.Attrs, span.DroppedAttrs = convCappedAttrs(maxSpan.Attrs, cfg.Attributes())\n\n\tlinks := cfg.Links()\n\tif limit := maxSpan.Links; limit == 0 {\n\t\tn := int64(len(links))\n\t\tif n > 0 {\n\t\t\tspan.DroppedLinks = uint32(min(n, math.MaxUint32)) // nolint: gosec  // Bounds checked.\n\t\t}\n\t} else {\n\t\tif limit > 0 {\n\t\t\tn := int64(max(len(links)-limit, 0))\n\t\t\tspan.DroppedLinks = uint32(min(n, math.MaxUint32)) // nolint: gosec  // Bounds checked.\n\t\t\tlinks = links[n:]\n\t\t}\n\t\tspan.Links = convLinks(links)\n\t}\n\n\tif t := cfg.Timestamp(); !t.IsZero() {\n\t\tspan.StartTime = cfg.Timestamp()\n\t} else {\n\t\tspan.StartTime = time.Now()\n\t}\n\n\treturn &telemetry.Traces{\n\t\tResourceSpans: []*telemetry.ResourceSpans{\n\t\t\t{\n\t\t\t\tScopeSpans: []*telemetry.ScopeSpans{\n\t\t\t\t\t{\n\t\t\t\t\t\tScope: &telemetry.Scope{\n\t\t\t\t\t\t\tName:    t.name,\n\t\t\t\t\t\t\tVersion: t.version,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tSpans:     []*telemetry.Span{span},\n\t\t\t\t\t\tSchemaURL: t.schemaURL,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}, span\n}\n\nfunc spanKind(kind SpanKind) telemetry.SpanKind {\n\tswitch kind {\n\tcase SpanKindInternal:\n\t\treturn telemetry.SpanKindInternal\n\tcase SpanKindServer:\n\t\treturn telemetry.SpanKindServer\n\tcase SpanKindClient:\n\t\treturn telemetry.SpanKindClient\n\tcase SpanKindProducer:\n\t\treturn telemetry.SpanKindProducer\n\tcase SpanKindConsumer:\n\t\treturn telemetry.SpanKindConsumer\n\t}\n\treturn telemetry.SpanKind(0) // undefined.\n}\n\ntype autoSpan struct {\n\tembedded.Span\n\n\tspanContext SpanContext\n\tsampled     atomic.Bool\n\n\tmu     sync.Mutex\n\ttraces *telemetry.Traces\n\tspan   *telemetry.Span\n}\n\nfunc (s *autoSpan) SpanContext() SpanContext {\n\tif s == nil {\n\t\treturn SpanContext{}\n\t}\n\t// s.spanContext is immutable, do not acquire lock s.mu.\n\treturn s.spanContext\n}\n\nfunc (s *autoSpan) IsRecording() bool {\n\tif s == nil {\n\t\treturn false\n\t}\n\n\treturn s.sampled.Load()\n}\n\nfunc (s *autoSpan) SetStatus(c codes.Code, msg string) {\n\tif s == nil || !s.sampled.Load() {\n\t\treturn\n\t}\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tif s.span.Status == nil {\n\t\ts.span.Status = new(telemetry.Status)\n\t}\n\n\ts.span.Status.Message = msg\n\n\tswitch c {\n\tcase codes.Unset:\n\t\ts.span.Status.Code = telemetry.StatusCodeUnset\n\tcase codes.Error:\n\t\ts.span.Status.Code = telemetry.StatusCodeError\n\tcase codes.Ok:\n\t\ts.span.Status.Code = telemetry.StatusCodeOK\n\t}\n}\n\nfunc (s *autoSpan) SetAttributes(attrs ...attribute.KeyValue) {\n\tif s == nil || !s.sampled.Load() {\n\t\treturn\n\t}\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tlimit := maxSpan.Attrs\n\tif limit == 0 {\n\t\t// No attributes allowed.\n\t\tn := int64(len(attrs))\n\t\tif n > 0 {\n\t\t\ts.span.DroppedAttrs += uint32(min(n, math.MaxUint32)) // nolint: gosec  // Bounds checked.\n\t\t}\n\t\treturn\n\t}\n\n\tm := make(map[string]int)\n\tfor i, a := range s.span.Attrs {\n\t\tm[a.Key] = i\n\t}\n\n\tfor _, a := range attrs {\n\t\tval := convAttrValue(a.Value)\n\t\tif val.Empty() {\n\t\t\ts.span.DroppedAttrs++\n\t\t\tcontinue\n\t\t}\n\n\t\tif idx, ok := m[string(a.Key)]; ok {\n\t\t\ts.span.Attrs[idx] = telemetry.Attr{\n\t\t\t\tKey:   string(a.Key),\n\t\t\t\tValue: val,\n\t\t\t}\n\t\t} else if limit < 0 || len(s.span.Attrs) < limit {\n\t\t\ts.span.Attrs = append(s.span.Attrs, telemetry.Attr{\n\t\t\t\tKey:   string(a.Key),\n\t\t\t\tValue: val,\n\t\t\t})\n\t\t\tm[string(a.Key)] = len(s.span.Attrs) - 1\n\t\t} else {\n\t\t\ts.span.DroppedAttrs++\n\t\t}\n\t}\n}\n\n// convCappedAttrs converts up to limit attrs into a []telemetry.Attr. The\n// number of dropped attributes is also returned.\nfunc convCappedAttrs(limit int, attrs []attribute.KeyValue) ([]telemetry.Attr, uint32) {\n\tn := len(attrs)\n\tif limit == 0 {\n\t\tvar out uint32\n\t\tif n > 0 {\n\t\t\tout = uint32(min(int64(n), math.MaxUint32)) // nolint: gosec  // Bounds checked.\n\t\t}\n\t\treturn nil, out\n\t}\n\n\tif limit < 0 {\n\t\t// Unlimited.\n\t\treturn convAttrs(attrs), 0\n\t}\n\n\tif n < 0 {\n\t\tn = 0\n\t}\n\n\tlimit = min(n, limit)\n\treturn convAttrs(attrs[:limit]), uint32(n - limit) // nolint: gosec  // Bounds checked.\n}\n\nfunc convAttrs(attrs []attribute.KeyValue) []telemetry.Attr {\n\tif len(attrs) == 0 {\n\t\t// Avoid allocations if not necessary.\n\t\treturn nil\n\t}\n\n\tout := make([]telemetry.Attr, 0, len(attrs))\n\tfor _, attr := range attrs {\n\t\tkey := string(attr.Key)\n\t\tval := convAttrValue(attr.Value)\n\t\tif val.Empty() {\n\t\t\tcontinue\n\t\t}\n\t\tout = append(out, telemetry.Attr{Key: key, Value: val})\n\t}\n\treturn out\n}\n\nfunc convAttrValue(value attribute.Value) telemetry.Value {\n\tswitch value.Type() {\n\tcase attribute.BOOL:\n\t\treturn telemetry.BoolValue(value.AsBool())\n\tcase attribute.INT64:\n\t\treturn telemetry.Int64Value(value.AsInt64())\n\tcase attribute.FLOAT64:\n\t\treturn telemetry.Float64Value(value.AsFloat64())\n\tcase attribute.STRING:\n\t\tv := truncate(maxSpan.AttrValueLen, value.AsString())\n\t\treturn telemetry.StringValue(v)\n\tcase attribute.BOOLSLICE:\n\t\tslice := value.AsBoolSlice()\n\t\tout := make([]telemetry.Value, 0, len(slice))\n\t\tfor _, v := range slice {\n\t\t\tout = append(out, telemetry.BoolValue(v))\n\t\t}\n\t\treturn telemetry.SliceValue(out...)\n\tcase attribute.INT64SLICE:\n\t\tslice := value.AsInt64Slice()\n\t\tout := make([]telemetry.Value, 0, len(slice))\n\t\tfor _, v := range slice {\n\t\t\tout = append(out, telemetry.Int64Value(v))\n\t\t}\n\t\treturn telemetry.SliceValue(out...)\n\tcase attribute.FLOAT64SLICE:\n\t\tslice := value.AsFloat64Slice()\n\t\tout := make([]telemetry.Value, 0, len(slice))\n\t\tfor _, v := range slice {\n\t\t\tout = append(out, telemetry.Float64Value(v))\n\t\t}\n\t\treturn telemetry.SliceValue(out...)\n\tcase attribute.STRINGSLICE:\n\t\tslice := value.AsStringSlice()\n\t\tout := make([]telemetry.Value, 0, len(slice))\n\t\tfor _, v := range slice {\n\t\t\tv = truncate(maxSpan.AttrValueLen, v)\n\t\t\tout = append(out, telemetry.StringValue(v))\n\t\t}\n\t\treturn telemetry.SliceValue(out...)\n\t}\n\treturn telemetry.Value{}\n}\n\n// truncate returns a truncated version of s such that it contains less than\n// the limit number of characters. Truncation is applied by returning the limit\n// number of valid characters contained in s.\n//\n// If limit is negative, it returns the original string.\n//\n// UTF-8 is supported. When truncating, all invalid characters are dropped\n// before applying truncation.\n//\n// If s already contains less than the limit number of bytes, it is returned\n// unchanged. No invalid characters are removed.\nfunc truncate(limit int, s string) string {\n\t// This prioritize performance in the following order based on the most\n\t// common expected use-cases.\n\t//\n\t//  - Short values less than the default limit (128).\n\t//  - Strings with valid encodings that exceed the limit.\n\t//  - No limit.\n\t//  - Strings with invalid encodings that exceed the limit.\n\tif limit < 0 || len(s) <= limit {\n\t\treturn s\n\t}\n\n\t// Optimistically, assume all valid UTF-8.\n\tvar b strings.Builder\n\tcount := 0\n\tfor i, c := range s {\n\t\tif c != utf8.RuneError {\n\t\t\tcount++\n\t\t\tif count > limit {\n\t\t\t\treturn s[:i]\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t_, size := utf8.DecodeRuneInString(s[i:])\n\t\tif size == 1 {\n\t\t\t// Invalid encoding.\n\t\t\tb.Grow(len(s) - 1)\n\t\t\t_, _ = b.WriteString(s[:i])\n\t\t\ts = s[i:]\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Fast-path, no invalid input.\n\tif b.Cap() == 0 {\n\t\treturn s\n\t}\n\n\t// Truncate while validating UTF-8.\n\tfor i := 0; i < len(s) && count < limit; {\n\t\tc := s[i]\n\t\tif c < utf8.RuneSelf {\n\t\t\t// Optimization for single byte runes (common case).\n\t\t\t_ = b.WriteByte(c)\n\t\t\ti++\n\t\t\tcount++\n\t\t\tcontinue\n\t\t}\n\n\t\t_, size := utf8.DecodeRuneInString(s[i:])\n\t\tif size == 1 {\n\t\t\t// We checked for all 1-byte runes above, this is a RuneError.\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\n\t\t_, _ = b.WriteString(s[i : i+size])\n\t\ti += size\n\t\tcount++\n\t}\n\n\treturn b.String()\n}\n\nfunc (s *autoSpan) End(opts ...SpanEndOption) {\n\tif s == nil || !s.sampled.Swap(false) {\n\t\treturn\n\t}\n\n\t// s.end exists so the lock (s.mu) is not held while s.ended is called.\n\ts.ended(s.end(opts))\n}\n\nfunc (s *autoSpan) end(opts []SpanEndOption) []byte {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tcfg := NewSpanEndConfig(opts...)\n\tif t := cfg.Timestamp(); !t.IsZero() {\n\t\ts.span.EndTime = cfg.Timestamp()\n\t} else {\n\t\ts.span.EndTime = time.Now()\n\t}\n\n\tb, _ := json.Marshal(s.traces) // TODO: do not ignore this error.\n\treturn b\n}\n\n// Expected to be implemented in eBPF.\n//\n//go:noinline\nfunc (*autoSpan) ended(buf []byte) { ended(buf) }\n\n// ended is used for testing.\nvar ended = func([]byte) {}\n\nfunc (s *autoSpan) RecordError(err error, opts ...EventOption) {\n\tif s == nil || err == nil || !s.sampled.Load() {\n\t\treturn\n\t}\n\n\tcfg := NewEventConfig(opts...)\n\n\tattrs := cfg.Attributes()\n\tattrs = append(attrs,\n\t\tsemconv.ExceptionType(typeStr(err)),\n\t\tsemconv.ExceptionMessage(err.Error()),\n\t)\n\tif cfg.StackTrace() {\n\t\tbuf := make([]byte, 2048)\n\t\tn := runtime.Stack(buf, false)\n\t\tattrs = append(attrs, semconv.ExceptionStacktrace(string(buf[0:n])))\n\t}\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\ts.addEvent(semconv.ExceptionEventName, cfg.Timestamp(), attrs)\n}\n\nfunc typeStr(i any) string {\n\tt := reflect.TypeOf(i)\n\tif t.PkgPath() == \"\" && t.Name() == \"\" {\n\t\t// Likely a builtin type.\n\t\treturn t.String()\n\t}\n\treturn fmt.Sprintf(\"%s.%s\", t.PkgPath(), t.Name())\n}\n\nfunc (s *autoSpan) AddEvent(name string, opts ...EventOption) {\n\tif s == nil || !s.sampled.Load() {\n\t\treturn\n\t}\n\n\tcfg := NewEventConfig(opts...)\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\ts.addEvent(name, cfg.Timestamp(), cfg.Attributes())\n}\n\n// addEvent adds an event with name and attrs at tStamp to the span. The span\n// lock (s.mu) needs to be held by the caller.\nfunc (s *autoSpan) addEvent(name string, tStamp time.Time, attrs []attribute.KeyValue) {\n\tlimit := maxSpan.Events\n\n\tif limit == 0 {\n\t\ts.span.DroppedEvents++\n\t\treturn\n\t}\n\n\tif limit > 0 && len(s.span.Events) == limit {\n\t\t// Drop head while avoiding allocation of more capacity.\n\t\tcopy(s.span.Events[:limit-1], s.span.Events[1:])\n\t\ts.span.Events = s.span.Events[:limit-1]\n\t\ts.span.DroppedEvents++\n\t}\n\n\te := &telemetry.SpanEvent{Time: tStamp, Name: name}\n\te.Attrs, e.DroppedAttrs = convCappedAttrs(maxSpan.EventAttrs, attrs)\n\n\ts.span.Events = append(s.span.Events, e)\n}\n\nfunc (s *autoSpan) AddLink(link Link) {\n\tif s == nil || !s.sampled.Load() {\n\t\treturn\n\t}\n\n\tl := maxSpan.Links\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tif l == 0 {\n\t\ts.span.DroppedLinks++\n\t\treturn\n\t}\n\n\tif l > 0 && len(s.span.Links) == l {\n\t\t// Drop head while avoiding allocation of more capacity.\n\t\tcopy(s.span.Links[:l-1], s.span.Links[1:])\n\t\ts.span.Links = s.span.Links[:l-1]\n\t\ts.span.DroppedLinks++\n\t}\n\n\ts.span.Links = append(s.span.Links, convLink(link))\n}\n\nfunc convLinks(links []Link) []*telemetry.SpanLink {\n\tout := make([]*telemetry.SpanLink, 0, len(links))\n\tfor _, link := range links {\n\t\tout = append(out, convLink(link))\n\t}\n\treturn out\n}\n\nfunc convLink(link Link) *telemetry.SpanLink {\n\tl := &telemetry.SpanLink{\n\t\tTraceID:    telemetry.TraceID(link.SpanContext.TraceID()),\n\t\tSpanID:     telemetry.SpanID(link.SpanContext.SpanID()),\n\t\tTraceState: link.SpanContext.TraceState().String(),\n\t\tFlags:      uint32(link.SpanContext.TraceFlags()),\n\t}\n\tl.Attrs, l.DroppedAttrs = convCappedAttrs(maxSpan.LinkAttrs, link.Attributes)\n\n\treturn l\n}\n\nfunc (s *autoSpan) SetName(name string) {\n\tif s == nil || !s.sampled.Load() {\n\t\treturn\n\t}\n\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\ts.span.Name = name\n}\n\nfunc (*autoSpan) TracerProvider() TracerProvider { return newAutoTracerProvider() }\n\n// maxSpan are the span limits resolved during startup.\nvar maxSpan = newSpanLimits()\n\ntype spanLimits struct {\n\t// Attrs is the number of allowed attributes for a span.\n\t//\n\t// This is resolved from the environment variable value for the\n\t// OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT key if it exists. Otherwise, the\n\t// environment variable value for OTEL_ATTRIBUTE_COUNT_LIMIT, or 128 if\n\t// that is not set, is used.\n\tAttrs int\n\t// AttrValueLen is the maximum attribute value length allowed for a span.\n\t//\n\t// This is resolved from the environment variable value for the\n\t// OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT key if it exists. Otherwise, the\n\t// environment variable value for OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT, or -1\n\t// if that is not set, is used.\n\tAttrValueLen int\n\t// Events is the number of allowed events for a span.\n\t//\n\t// This is resolved from the environment variable value for the\n\t// OTEL_SPAN_EVENT_COUNT_LIMIT key, or 128 is used if that is not set.\n\tEvents int\n\t// EventAttrs is the number of allowed attributes for a span event.\n\t//\n\t// The is resolved from the environment variable value for the\n\t// OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT key, or 128 is used if that is not set.\n\tEventAttrs int\n\t// Links is the number of allowed Links for a span.\n\t//\n\t// This is resolved from the environment variable value for the\n\t// OTEL_SPAN_LINK_COUNT_LIMIT, or 128 is used if that is not set.\n\tLinks int\n\t// LinkAttrs is the number of allowed attributes for a span link.\n\t//\n\t// This is resolved from the environment variable value for the\n\t// OTEL_LINK_ATTRIBUTE_COUNT_LIMIT, or 128 is used if that is not set.\n\tLinkAttrs int\n}\n\nfunc newSpanLimits() spanLimits {\n\treturn spanLimits{\n\t\tAttrs: firstEnv(\n\t\t\t128,\n\t\t\t\"OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT\",\n\t\t\t\"OTEL_ATTRIBUTE_COUNT_LIMIT\",\n\t\t),\n\t\tAttrValueLen: firstEnv(\n\t\t\t-1, // Unlimited.\n\t\t\t\"OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT\",\n\t\t\t\"OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT\",\n\t\t),\n\t\tEvents:     firstEnv(128, \"OTEL_SPAN_EVENT_COUNT_LIMIT\"),\n\t\tEventAttrs: firstEnv(128, \"OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT\"),\n\t\tLinks:      firstEnv(128, \"OTEL_SPAN_LINK_COUNT_LIMIT\"),\n\t\tLinkAttrs:  firstEnv(128, \"OTEL_LINK_ATTRIBUTE_COUNT_LIMIT\"),\n\t}\n}\n\n// firstEnv returns the parsed integer value of the first matching environment\n// variable from keys. The defaultVal is returned if the value is not an\n// integer or no match is found.\nfunc firstEnv(defaultVal int, keys ...string) int {\n\tfor _, key := range keys {\n\t\tstrV := os.Getenv(key)\n\t\tif strV == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tv, err := strconv.Atoi(strV)\n\t\tif err == nil {\n\t\t\treturn v\n\t\t}\n\t\t// Ignore invalid environment variable.\n\t}\n\n\treturn defaultVal\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/config.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n\nimport (\n\t\"slices\"\n\t\"time\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n)\n\n// TracerConfig is a group of options for a Tracer.\ntype TracerConfig struct {\n\tinstrumentationVersion string\n\t// Schema URL of the telemetry emitted by the Tracer.\n\tschemaURL string\n\tattrs     attribute.Set\n}\n\n// InstrumentationVersion returns the version of the library providing instrumentation.\nfunc (t *TracerConfig) InstrumentationVersion() string {\n\treturn t.instrumentationVersion\n}\n\n// InstrumentationAttributes returns the attributes associated with the library\n// providing instrumentation.\nfunc (t *TracerConfig) InstrumentationAttributes() attribute.Set {\n\treturn t.attrs\n}\n\n// SchemaURL returns the Schema URL of the telemetry emitted by the Tracer.\nfunc (t *TracerConfig) SchemaURL() string {\n\treturn t.schemaURL\n}\n\n// NewTracerConfig applies all the options to a returned TracerConfig.\nfunc NewTracerConfig(options ...TracerOption) TracerConfig {\n\tvar config TracerConfig\n\tfor _, option := range options {\n\t\tconfig = option.apply(config)\n\t}\n\treturn config\n}\n\n// TracerOption applies an option to a TracerConfig.\ntype TracerOption interface {\n\tapply(TracerConfig) TracerConfig\n}\n\ntype tracerOptionFunc func(TracerConfig) TracerConfig\n\nfunc (fn tracerOptionFunc) apply(cfg TracerConfig) TracerConfig {\n\treturn fn(cfg)\n}\n\n// SpanConfig is a group of options for a Span.\ntype SpanConfig struct {\n\tattributes []attribute.KeyValue\n\ttimestamp  time.Time\n\tlinks      []Link\n\tnewRoot    bool\n\tspanKind   SpanKind\n\tstackTrace bool\n}\n\n// Attributes describe the associated qualities of a Span.\nfunc (cfg *SpanConfig) Attributes() []attribute.KeyValue {\n\treturn cfg.attributes\n}\n\n// Timestamp is a time in a Span life-cycle.\nfunc (cfg *SpanConfig) Timestamp() time.Time {\n\treturn cfg.timestamp\n}\n\n// StackTrace reports whether stack trace capturing is enabled.\nfunc (cfg *SpanConfig) StackTrace() bool {\n\treturn cfg.stackTrace\n}\n\n// Links are the associations a Span has with other Spans.\nfunc (cfg *SpanConfig) Links() []Link {\n\treturn cfg.links\n}\n\n// NewRoot identifies a Span as the root Span for a new trace. This is\n// commonly used when an existing trace crosses trust boundaries and the\n// remote parent span context should be ignored for security.\nfunc (cfg *SpanConfig) NewRoot() bool {\n\treturn cfg.newRoot\n}\n\n// SpanKind is the role a Span has in a trace.\nfunc (cfg *SpanConfig) SpanKind() SpanKind {\n\treturn cfg.spanKind\n}\n\n// NewSpanStartConfig applies all the options to a returned SpanConfig.\n// No validation is performed on the returned SpanConfig (e.g. no uniqueness\n// checking or bounding of data), it is left to the SDK to perform this\n// action.\nfunc NewSpanStartConfig(options ...SpanStartOption) SpanConfig {\n\tvar c SpanConfig\n\tfor _, option := range options {\n\t\tc = option.applySpanStart(c)\n\t}\n\treturn c\n}\n\n// NewSpanEndConfig applies all the options to a returned SpanConfig.\n// No validation is performed on the returned SpanConfig (e.g. no uniqueness\n// checking or bounding of data), it is left to the SDK to perform this\n// action.\nfunc NewSpanEndConfig(options ...SpanEndOption) SpanConfig {\n\tvar c SpanConfig\n\tfor _, option := range options {\n\t\tc = option.applySpanEnd(c)\n\t}\n\treturn c\n}\n\n// SpanStartOption applies an option to a SpanConfig. These options are applicable\n// only when the span is created.\ntype SpanStartOption interface {\n\tapplySpanStart(SpanConfig) SpanConfig\n}\n\ntype spanOptionFunc func(SpanConfig) SpanConfig\n\nfunc (fn spanOptionFunc) applySpanStart(cfg SpanConfig) SpanConfig {\n\treturn fn(cfg)\n}\n\n// SpanEndOption applies an option to a SpanConfig. These options are\n// applicable only when the span is ended.\ntype SpanEndOption interface {\n\tapplySpanEnd(SpanConfig) SpanConfig\n}\n\n// EventConfig is a group of options for an Event.\ntype EventConfig struct {\n\tattributes []attribute.KeyValue\n\ttimestamp  time.Time\n\tstackTrace bool\n}\n\n// Attributes describe the associated qualities of an Event.\nfunc (cfg *EventConfig) Attributes() []attribute.KeyValue {\n\treturn cfg.attributes\n}\n\n// Timestamp is a time in an Event life-cycle.\nfunc (cfg *EventConfig) Timestamp() time.Time {\n\treturn cfg.timestamp\n}\n\n// StackTrace reports whether stack trace capturing is enabled.\nfunc (cfg *EventConfig) StackTrace() bool {\n\treturn cfg.stackTrace\n}\n\n// NewEventConfig applies all the EventOptions to a returned EventConfig. If no\n// timestamp option is passed, the returned EventConfig will have a Timestamp\n// set to the call time, otherwise no validation is performed on the returned\n// EventConfig.\nfunc NewEventConfig(options ...EventOption) EventConfig {\n\tvar c EventConfig\n\tfor _, option := range options {\n\t\tc = option.applyEvent(c)\n\t}\n\tif c.timestamp.IsZero() {\n\t\tc.timestamp = time.Now()\n\t}\n\treturn c\n}\n\n// EventOption applies span event options to an EventConfig.\ntype EventOption interface {\n\tapplyEvent(EventConfig) EventConfig\n}\n\n// SpanOption are options that can be used at both the beginning and end of a span.\ntype SpanOption interface {\n\tSpanStartOption\n\tSpanEndOption\n}\n\n// SpanStartEventOption are options that can be used at the start of a span, or with an event.\ntype SpanStartEventOption interface {\n\tSpanStartOption\n\tEventOption\n}\n\n// SpanEndEventOption are options that can be used at the end of a span, or with an event.\ntype SpanEndEventOption interface {\n\tSpanEndOption\n\tEventOption\n}\n\ntype attributeOption []attribute.KeyValue\n\nfunc (o attributeOption) applySpan(c SpanConfig) SpanConfig {\n\tc.attributes = append(c.attributes, []attribute.KeyValue(o)...)\n\treturn c\n}\nfunc (o attributeOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) }\nfunc (o attributeOption) applyEvent(c EventConfig) EventConfig {\n\tc.attributes = append(c.attributes, []attribute.KeyValue(o)...)\n\treturn c\n}\n\nvar _ SpanStartEventOption = attributeOption{}\n\n// WithAttributes adds the attributes related to a span life-cycle event.\n// These attributes are used to describe the work a Span represents when this\n// option is provided to a Span's start event. Otherwise, these\n// attributes provide additional information about the event being recorded\n// (e.g. error, state change, processing progress, system event).\n//\n// If multiple of these options are passed the attributes of each successive\n// option will extend the attributes instead of overwriting. There is no\n// guarantee of uniqueness in the resulting attributes.\nfunc WithAttributes(attributes ...attribute.KeyValue) SpanStartEventOption {\n\treturn attributeOption(attributes)\n}\n\n// SpanEventOption are options that can be used with an event or a span.\ntype SpanEventOption interface {\n\tSpanOption\n\tEventOption\n}\n\ntype timestampOption time.Time\n\nfunc (o timestampOption) applySpan(c SpanConfig) SpanConfig {\n\tc.timestamp = time.Time(o)\n\treturn c\n}\nfunc (o timestampOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) }\nfunc (o timestampOption) applySpanEnd(c SpanConfig) SpanConfig   { return o.applySpan(c) }\nfunc (o timestampOption) applyEvent(c EventConfig) EventConfig {\n\tc.timestamp = time.Time(o)\n\treturn c\n}\n\nvar _ SpanEventOption = timestampOption{}\n\n// WithTimestamp sets the time of a Span or Event life-cycle moment (e.g.\n// started, stopped, errored).\nfunc WithTimestamp(t time.Time) SpanEventOption {\n\treturn timestampOption(t)\n}\n\ntype stackTraceOption bool\n\nfunc (o stackTraceOption) applyEvent(c EventConfig) EventConfig {\n\tc.stackTrace = bool(o)\n\treturn c\n}\n\nfunc (o stackTraceOption) applySpan(c SpanConfig) SpanConfig {\n\tc.stackTrace = bool(o)\n\treturn c\n}\nfunc (o stackTraceOption) applySpanEnd(c SpanConfig) SpanConfig { return o.applySpan(c) }\n\n// WithStackTrace sets the flag to capture the error with stack trace (e.g. true, false).\nfunc WithStackTrace(b bool) SpanEndEventOption {\n\treturn stackTraceOption(b)\n}\n\n// WithLinks adds links to a Span. The links are added to the existing Span\n// links, i.e. this does not overwrite. Links with invalid span context are ignored.\nfunc WithLinks(links ...Link) SpanStartOption {\n\treturn spanOptionFunc(func(cfg SpanConfig) SpanConfig {\n\t\tcfg.links = append(cfg.links, links...)\n\t\treturn cfg\n\t})\n}\n\n// WithNewRoot specifies that the Span should be treated as a root Span. Any\n// existing parent span context will be ignored when defining the Span's trace\n// identifiers.\nfunc WithNewRoot() SpanStartOption {\n\treturn spanOptionFunc(func(cfg SpanConfig) SpanConfig {\n\t\tcfg.newRoot = true\n\t\treturn cfg\n\t})\n}\n\n// WithSpanKind sets the SpanKind of a Span.\nfunc WithSpanKind(kind SpanKind) SpanStartOption {\n\treturn spanOptionFunc(func(cfg SpanConfig) SpanConfig {\n\t\tcfg.spanKind = kind\n\t\treturn cfg\n\t})\n}\n\n// WithInstrumentationVersion sets the instrumentation version.\nfunc WithInstrumentationVersion(version string) TracerOption {\n\treturn tracerOptionFunc(func(cfg TracerConfig) TracerConfig {\n\t\tcfg.instrumentationVersion = version\n\t\treturn cfg\n\t})\n}\n\n// mergeSets returns the union of keys between a and b. Any duplicate keys will\n// use the value associated with b.\nfunc mergeSets(a, b attribute.Set) attribute.Set {\n\t// NewMergeIterator uses the first value for any duplicates.\n\titer := attribute.NewMergeIterator(&b, &a)\n\tmerged := make([]attribute.KeyValue, 0, a.Len()+b.Len())\n\tfor iter.Next() {\n\t\tmerged = append(merged, iter.Attribute())\n\t}\n\treturn attribute.NewSet(merged...)\n}\n\n// WithInstrumentationAttributes adds the instrumentation attributes.\n//\n// This is equivalent to calling [WithInstrumentationAttributeSet] with an\n// [attribute.Set] created from a clone of the passed attributes.\n// [WithInstrumentationAttributeSet] is recommended for more control.\n//\n// If multiple [WithInstrumentationAttributes] or [WithInstrumentationAttributeSet]\n// options are passed, the attributes will be merged together in the order\n// they are passed. Attributes with duplicate keys will use the last value passed.\nfunc WithInstrumentationAttributes(attr ...attribute.KeyValue) TracerOption {\n\tset := attribute.NewSet(slices.Clone(attr)...)\n\treturn WithInstrumentationAttributeSet(set)\n}\n\n// WithInstrumentationAttributeSet adds the instrumentation attributes.\n//\n// If multiple [WithInstrumentationAttributes] or [WithInstrumentationAttributeSet]\n// options are passed, the attributes will be merged together in the order\n// they are passed. Attributes with duplicate keys will use the last value passed.\nfunc WithInstrumentationAttributeSet(set attribute.Set) TracerOption {\n\tif set.Len() == 0 {\n\t\treturn tracerOptionFunc(func(config TracerConfig) TracerConfig {\n\t\t\treturn config\n\t\t})\n\t}\n\n\treturn tracerOptionFunc(func(config TracerConfig) TracerConfig {\n\t\tif config.attrs.Len() == 0 {\n\t\t\tconfig.attrs = set\n\t\t} else {\n\t\t\tconfig.attrs = mergeSets(config.attrs, set)\n\t\t}\n\t\treturn config\n\t})\n}\n\n// WithSchemaURL sets the schema URL for the Tracer.\nfunc WithSchemaURL(schemaURL string) TracerOption {\n\treturn tracerOptionFunc(func(cfg TracerConfig) TracerConfig {\n\t\tcfg.schemaURL = schemaURL\n\t\treturn cfg\n\t})\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/context.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n\nimport \"context\"\n\ntype traceContextKeyType int\n\nconst currentSpanKey traceContextKeyType = iota\n\n// ContextWithSpan returns a copy of parent with span set as the current Span.\nfunc ContextWithSpan(parent context.Context, span Span) context.Context {\n\treturn context.WithValue(parent, currentSpanKey, span)\n}\n\n// ContextWithSpanContext returns a copy of parent with sc as the current\n// Span. The Span implementation that wraps sc is non-recording and performs\n// no operations other than to return sc as the SpanContext from the\n// SpanContext method.\nfunc ContextWithSpanContext(parent context.Context, sc SpanContext) context.Context {\n\treturn ContextWithSpan(parent, nonRecordingSpan{sc: sc})\n}\n\n// ContextWithRemoteSpanContext returns a copy of parent with rsc set explicitly\n// as a remote SpanContext and as the current Span. The Span implementation\n// that wraps rsc is non-recording and performs no operations other than to\n// return rsc as the SpanContext from the SpanContext method.\nfunc ContextWithRemoteSpanContext(parent context.Context, rsc SpanContext) context.Context {\n\treturn ContextWithSpanContext(parent, rsc.WithRemote(true))\n}\n\n// SpanFromContext returns the current Span from ctx.\n//\n// If no Span is currently set in ctx an implementation of a Span that\n// performs no operations is returned.\nfunc SpanFromContext(ctx context.Context) Span {\n\tif ctx == nil {\n\t\treturn noopSpanInstance\n\t}\n\tif span, ok := ctx.Value(currentSpanKey).(Span); ok {\n\t\treturn span\n\t}\n\treturn noopSpanInstance\n}\n\n// SpanContextFromContext returns the current Span's SpanContext.\nfunc SpanContextFromContext(ctx context.Context) SpanContext {\n\treturn SpanFromContext(ctx).SpanContext()\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n/*\nPackage trace provides an implementation of the tracing part of the\nOpenTelemetry API.\n\nTo participate in distributed traces a Span needs to be created for the\noperation being performed as part of a traced workflow. In its simplest form:\n\n\tvar tracer trace.Tracer\n\n\tfunc init() {\n\t\ttracer = otel.Tracer(\"instrumentation/package/name\")\n\t}\n\n\tfunc operation(ctx context.Context) {\n\t\tvar span trace.Span\n\t\tctx, span = tracer.Start(ctx, \"operation\")\n\t\tdefer span.End()\n\t\t// ...\n\t}\n\nA Tracer is unique to the instrumentation and is used to create Spans.\nInstrumentation should be designed to accept a TracerProvider from which it\ncan create its own unique Tracer. Alternatively, the registered global\nTracerProvider from the go.opentelemetry.io/otel package can be used as\na default.\n\n\tconst (\n\t\tname    = \"instrumentation/package/name\"\n\t\tversion = \"0.1.0\"\n\t)\n\n\ttype Instrumentation struct {\n\t\ttracer trace.Tracer\n\t}\n\n\tfunc NewInstrumentation(tp trace.TracerProvider) *Instrumentation {\n\t\tif tp == nil {\n\t\t\ttp = otel.TracerProvider()\n\t\t}\n\t\treturn &Instrumentation{\n\t\t\ttracer: tp.Tracer(name, trace.WithInstrumentationVersion(version)),\n\t\t}\n\t}\n\n\tfunc operation(ctx context.Context, inst *Instrumentation) {\n\t\tvar span trace.Span\n\t\tctx, span = inst.tracer.Start(ctx, \"operation\")\n\t\tdefer span.End()\n\t\t// ...\n\t}\n\n# API Implementations\n\nThis package does not conform to the standard Go versioning policy; all of its\ninterfaces may have methods added to them without a package major version bump.\nThis non-standard API evolution could surprise an uninformed implementation\nauthor. They could unknowingly build their implementation in a way that would\nresult in a runtime panic for their users that update to the new API.\n\nThe API is designed to help inform an instrumentation author about this\nnon-standard API evolution. It requires them to choose a default behavior for\nunimplemented interface methods. There are three behavior choices they can\nmake:\n\n  - Compilation failure\n  - Panic\n  - Default to another implementation\n\nAll interfaces in this API embed a corresponding interface from\n[go.opentelemetry.io/otel/trace/embedded]. If an author wants the default\nbehavior of their implementations to be a compilation failure, signaling to\ntheir users they need to update to the latest version of that implementation,\nthey need to embed the corresponding interface from\n[go.opentelemetry.io/otel/trace/embedded] in their implementation. For\nexample,\n\n\timport \"go.opentelemetry.io/otel/trace/embedded\"\n\n\ttype TracerProvider struct {\n\t\tembedded.TracerProvider\n\t\t// ...\n\t}\n\nIf an author wants the default behavior of their implementations to panic, they\ncan embed the API interface directly.\n\n\timport \"go.opentelemetry.io/otel/trace\"\n\n\ttype TracerProvider struct {\n\t\ttrace.TracerProvider\n\t\t// ...\n\t}\n\nThis option is not recommended. It will lead to publishing packages that\ncontain runtime panics when users update to newer versions of\n[go.opentelemetry.io/otel/trace], which may be done with a transitive\ndependency.\n\nFinally, an author can embed another implementation in theirs. The embedded\nimplementation will be used for methods not defined by the author. For example,\nan author who wants to default to silently dropping the call can use\n[go.opentelemetry.io/otel/trace/noop]:\n\n\timport \"go.opentelemetry.io/otel/trace/noop\"\n\n\ttype TracerProvider struct {\n\t\tnoop.TracerProvider\n\t\t// ...\n\t}\n\nIt is strongly recommended that authors only embed\n[go.opentelemetry.io/otel/trace/noop] if they choose this default behavior.\nThat implementation is the only one OpenTelemetry authors can guarantee will\nfully implement all the API interfaces when a user updates their API.\n*/\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/embedded/README.md",
    "content": "# Trace Embedded\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/trace/embedded)](https://pkg.go.dev/go.opentelemetry.io/otel/trace/embedded)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/embedded/embedded.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package embedded provides interfaces embedded within the [OpenTelemetry\n// trace API].\n//\n// Implementers of the [OpenTelemetry trace API] can embed the relevant type\n// from this package into their implementation directly. Doing so will result\n// in a compilation error for users when the [OpenTelemetry trace API] is\n// extended (which is something that can happen without a major version bump of\n// the API package).\n//\n// [OpenTelemetry trace API]: https://pkg.go.dev/go.opentelemetry.io/otel/trace\npackage embedded // import \"go.opentelemetry.io/otel/trace/embedded\"\n\n// TracerProvider is embedded in\n// [go.opentelemetry.io/otel/trace.TracerProvider].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/trace.TracerProvider] if you want users to\n// experience a compilation error, signaling they need to update to your latest\n// implementation, when the [go.opentelemetry.io/otel/trace.TracerProvider]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype TracerProvider interface{ tracerProvider() }\n\n// Tracer is embedded in [go.opentelemetry.io/otel/trace.Tracer].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/trace.Tracer] if you want users to experience a\n// compilation error, signaling they need to update to your latest\n// implementation, when the [go.opentelemetry.io/otel/trace.Tracer] interface\n// is extended (which is something that can happen without a major version bump\n// of the API package).\ntype Tracer interface{ tracer() }\n\n// Span is embedded in [go.opentelemetry.io/otel/trace.Span].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/trace.Span] if you want users to experience a\n// compilation error, signaling they need to update to your latest\n// implementation, when the [go.opentelemetry.io/otel/trace.Span] interface is\n// extended (which is something that can happen without a major version bump of\n// the API package).\ntype Span interface{ span() }\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/hex.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n\nconst (\n\t// hexLU is a hex lookup table of the 16 lowercase hex digits.\n\t// The character values of the string are indexed at the equivalent\n\t// hexadecimal value they represent. This table efficiently encodes byte data\n\t// into a string representation of hexadecimal.\n\thexLU = \"0123456789abcdef\"\n\n\t// hexRev is a reverse hex lookup table for lowercase hex digits.\n\t// The table is efficiently decodes a hexadecimal string into bytes.\n\t// Valid hexadecimal characters are indexed at their respective values. All\n\t// other invalid ASCII characters are represented with '\\xff'.\n\t//\n\t// The '\\xff' character is used as invalid because no valid character has\n\t// the upper 4 bits set. Meaning, an efficient validation can be performed\n\t// over multiple character parsing by checking these bits remain zero.\n\thexRev = \"\" +\n\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\" +\n\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\" +\n\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\" +\n\t\t\"\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\xff\\xff\\xff\\xff\\xff\\xff\" +\n\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\" +\n\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\" +\n\t\t\"\\xff\\x0a\\x0b\\x0c\\x0d\\x0e\\x0f\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\" +\n\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\" +\n\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\" +\n\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\" +\n\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\" +\n\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\" +\n\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\" +\n\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\" +\n\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\" +\n\t\t\"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\"\n)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/internal/telemetry/attr.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry // import \"go.opentelemetry.io/otel/trace/internal/telemetry\"\n\n// Attr is a key-value pair.\ntype Attr struct {\n\tKey   string `json:\"key,omitempty\"`\n\tValue Value  `json:\"value,omitempty\"`\n}\n\n// String returns an Attr for a string value.\nfunc String(key, value string) Attr {\n\treturn Attr{key, StringValue(value)}\n}\n\n// Int64 returns an Attr for an int64 value.\nfunc Int64(key string, value int64) Attr {\n\treturn Attr{key, Int64Value(value)}\n}\n\n// Int returns an Attr for an int value.\nfunc Int(key string, value int) Attr {\n\treturn Int64(key, int64(value))\n}\n\n// Float64 returns an Attr for a float64 value.\nfunc Float64(key string, value float64) Attr {\n\treturn Attr{key, Float64Value(value)}\n}\n\n// Bool returns an Attr for a bool value.\nfunc Bool(key string, value bool) Attr {\n\treturn Attr{key, BoolValue(value)}\n}\n\n// Bytes returns an Attr for a []byte value.\n// The passed slice must not be changed after it is passed.\nfunc Bytes(key string, value []byte) Attr {\n\treturn Attr{key, BytesValue(value)}\n}\n\n// Slice returns an Attr for a []Value value.\n// The passed slice must not be changed after it is passed.\nfunc Slice(key string, value ...Value) Attr {\n\treturn Attr{key, SliceValue(value...)}\n}\n\n// Map returns an Attr for a map value.\n// The passed slice must not be changed after it is passed.\nfunc Map(key string, value ...Attr) Attr {\n\treturn Attr{key, MapValue(value...)}\n}\n\n// Equal reports whether a is equal to b.\nfunc (a Attr) Equal(b Attr) bool {\n\treturn a.Key == b.Key && a.Value.Equal(b.Value)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/internal/telemetry/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n/*\nPackage telemetry provides a lightweight representations of OpenTelemetry\ntelemetry that is compatible with the OTLP JSON protobuf encoding.\n*/\npackage telemetry // import \"go.opentelemetry.io/otel/trace/internal/telemetry\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/internal/telemetry/id.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry // import \"go.opentelemetry.io/otel/trace/internal/telemetry\"\n\nimport (\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n)\n\nconst (\n\ttraceIDSize = 16\n\tspanIDSize  = 8\n)\n\n// TraceID is a custom data type that is used for all trace IDs.\ntype TraceID [traceIDSize]byte\n\n// String returns the hex string representation form of a TraceID.\nfunc (tid TraceID) String() string {\n\treturn hex.EncodeToString(tid[:])\n}\n\n// IsEmpty reports whether the TraceID contains only zero bytes.\nfunc (tid TraceID) IsEmpty() bool {\n\treturn tid == [traceIDSize]byte{}\n}\n\n// MarshalJSON converts the trace ID into a hex string enclosed in quotes.\nfunc (tid TraceID) MarshalJSON() ([]byte, error) {\n\tif tid.IsEmpty() {\n\t\treturn []byte(`\"\"`), nil\n\t}\n\treturn marshalJSON(tid[:])\n}\n\n// UnmarshalJSON inflates the trace ID from hex string, possibly enclosed in\n// quotes.\nfunc (tid *TraceID) UnmarshalJSON(data []byte) error {\n\t*tid = [traceIDSize]byte{}\n\treturn unmarshalJSON(tid[:], data)\n}\n\n// SpanID is a custom data type that is used for all span IDs.\ntype SpanID [spanIDSize]byte\n\n// String returns the hex string representation form of a SpanID.\nfunc (sid SpanID) String() string {\n\treturn hex.EncodeToString(sid[:])\n}\n\n// IsEmpty reports whether the SpanID contains only zero bytes.\nfunc (sid SpanID) IsEmpty() bool {\n\treturn sid == [spanIDSize]byte{}\n}\n\n// MarshalJSON converts span ID into a hex string enclosed in quotes.\nfunc (sid SpanID) MarshalJSON() ([]byte, error) {\n\tif sid.IsEmpty() {\n\t\treturn []byte(`\"\"`), nil\n\t}\n\treturn marshalJSON(sid[:])\n}\n\n// UnmarshalJSON decodes span ID from hex string, possibly enclosed in quotes.\nfunc (sid *SpanID) UnmarshalJSON(data []byte) error {\n\t*sid = [spanIDSize]byte{}\n\treturn unmarshalJSON(sid[:], data)\n}\n\n// marshalJSON converts id into a hex string enclosed in quotes.\nfunc marshalJSON(id []byte) ([]byte, error) {\n\t// Plus 2 quote chars at the start and end.\n\thexLen := hex.EncodedLen(len(id)) + 2\n\n\tb := make([]byte, hexLen)\n\thex.Encode(b[1:hexLen-1], id)\n\tb[0], b[hexLen-1] = '\"', '\"'\n\n\treturn b, nil\n}\n\n// unmarshalJSON inflates trace id from hex string, possibly enclosed in quotes.\nfunc unmarshalJSON(dst, src []byte) error {\n\tif l := len(src); l >= 2 && src[0] == '\"' && src[l-1] == '\"' {\n\t\tsrc = src[1 : l-1]\n\t}\n\tnLen := len(src)\n\tif nLen == 0 {\n\t\treturn nil\n\t}\n\n\tif len(dst) != hex.DecodedLen(nLen) {\n\t\treturn errors.New(\"invalid length for ID\")\n\t}\n\n\t_, err := hex.Decode(dst, src)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot unmarshal ID from string '%s': %w\", string(src), err)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/internal/telemetry/number.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry // import \"go.opentelemetry.io/otel/trace/internal/telemetry\"\n\nimport (\n\t\"encoding/json\"\n\t\"strconv\"\n)\n\n// protoInt64 represents the protobuf encoding of integers which can be either\n// strings or integers.\ntype protoInt64 int64\n\n// Int64 returns the protoInt64 as an int64.\nfunc (i *protoInt64) Int64() int64 { return int64(*i) }\n\n// UnmarshalJSON decodes both strings and integers.\nfunc (i *protoInt64) UnmarshalJSON(data []byte) error {\n\tif data[0] == '\"' {\n\t\tvar str string\n\t\tif err := json.Unmarshal(data, &str); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tparsedInt, err := strconv.ParseInt(str, 10, 64)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t*i = protoInt64(parsedInt)\n\t} else {\n\t\tvar parsedInt int64\n\t\tif err := json.Unmarshal(data, &parsedInt); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t*i = protoInt64(parsedInt)\n\t}\n\treturn nil\n}\n\n// protoUint64 represents the protobuf encoding of integers which can be either\n// strings or integers.\ntype protoUint64 uint64\n\n// Int64 returns the protoUint64 as a uint64.\nfunc (i *protoUint64) Uint64() uint64 { return uint64(*i) }\n\n// UnmarshalJSON decodes both strings and integers.\nfunc (i *protoUint64) UnmarshalJSON(data []byte) error {\n\tif data[0] == '\"' {\n\t\tvar str string\n\t\tif err := json.Unmarshal(data, &str); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tparsedUint, err := strconv.ParseUint(str, 10, 64)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t*i = protoUint64(parsedUint)\n\t} else {\n\t\tvar parsedUint uint64\n\t\tif err := json.Unmarshal(data, &parsedUint); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t*i = protoUint64(parsedUint)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/internal/telemetry/resource.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry // import \"go.opentelemetry.io/otel/trace/internal/telemetry\"\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\n// Resource information.\ntype Resource struct {\n\t// Attrs are the set of attributes that describe the resource. Attribute\n\t// keys MUST be unique (it is not allowed to have more than one attribute\n\t// with the same key).\n\tAttrs []Attr `json:\"attributes,omitempty\"`\n\t// DroppedAttrs is the number of dropped attributes. If the value\n\t// is 0, then no attributes were dropped.\n\tDroppedAttrs uint32 `json:\"droppedAttributesCount,omitempty\"`\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into r.\nfunc (r *Resource) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid Resource type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid Resource field: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"attributes\":\n\t\t\terr = decoder.Decode(&r.Attrs)\n\t\tcase \"droppedAttributesCount\", \"dropped_attributes_count\":\n\t\t\terr = decoder.Decode(&r.DroppedAttrs)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/internal/telemetry/scope.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry // import \"go.opentelemetry.io/otel/trace/internal/telemetry\"\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\n// Scope is the identifying values of the instrumentation scope.\ntype Scope struct {\n\tName         string `json:\"name,omitempty\"`\n\tVersion      string `json:\"version,omitempty\"`\n\tAttrs        []Attr `json:\"attributes,omitempty\"`\n\tDroppedAttrs uint32 `json:\"droppedAttributesCount,omitempty\"`\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into r.\nfunc (s *Scope) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid Scope type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid Scope field: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"name\":\n\t\t\terr = decoder.Decode(&s.Name)\n\t\tcase \"version\":\n\t\t\terr = decoder.Decode(&s.Version)\n\t\tcase \"attributes\":\n\t\t\terr = decoder.Decode(&s.Attrs)\n\t\tcase \"droppedAttributesCount\", \"dropped_attributes_count\":\n\t\t\terr = decoder.Decode(&s.DroppedAttrs)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/internal/telemetry/span.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry // import \"go.opentelemetry.io/otel/trace/internal/telemetry\"\n\nimport (\n\t\"bytes\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"time\"\n)\n\n// A Span represents a single operation performed by a single component of the\n// system.\ntype Span struct {\n\t// A unique identifier for a trace. All spans from the same trace share\n\t// the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes OR\n\t// of length other than 16 bytes is considered invalid (empty string in OTLP/JSON\n\t// is zero-length and thus is also invalid).\n\t//\n\t// This field is required.\n\tTraceID TraceID `json:\"traceId,omitempty\"`\n\t// A unique identifier for a span within a trace, assigned when the span\n\t// is created. The ID is an 8-byte array. An ID with all zeroes OR of length\n\t// other than 8 bytes is considered invalid (empty string in OTLP/JSON\n\t// is zero-length and thus is also invalid).\n\t//\n\t// This field is required.\n\tSpanID SpanID `json:\"spanId,omitempty\"`\n\t// trace_state conveys information about request position in multiple distributed tracing graphs.\n\t// It is a trace_state in w3c-trace-context format: https://www.w3.org/TR/trace-context/#tracestate-header\n\t// See also https://github.com/w3c/distributed-tracing for more details about this field.\n\tTraceState string `json:\"traceState,omitempty\"`\n\t// The `span_id` of this span's parent span. If this is a root span, then this\n\t// field must be empty. The ID is an 8-byte array.\n\tParentSpanID SpanID `json:\"parentSpanId,omitempty\"`\n\t// Flags, a bit field.\n\t//\n\t// Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C Trace\n\t// Context specification. To read the 8-bit W3C trace flag, use\n\t// `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`.\n\t//\n\t// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions.\n\t//\n\t// Bits 8 and 9 represent the 3 states of whether a span's parent\n\t// is remote. The states are (unknown, is not remote, is remote).\n\t// To read whether the value is known, use `(flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`.\n\t// To read whether the span is remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`.\n\t//\n\t// When creating span messages, if the message is logically forwarded from another source\n\t// with an equivalent flags fields (i.e., usually another OTLP span message), the field SHOULD\n\t// be copied as-is. If creating from a source that does not have an equivalent flags field\n\t// (such as a runtime representation of an OpenTelemetry span), the high 22 bits MUST\n\t// be set to zero.\n\t// Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero.\n\t//\n\t// [Optional].\n\tFlags uint32 `json:\"flags,omitempty\"`\n\t// A description of the span's operation.\n\t//\n\t// For example, the name can be a qualified method name or a file name\n\t// and a line number where the operation is called. A best practice is to use\n\t// the same display name at the same call point in an application.\n\t// This makes it easier to correlate spans in different traces.\n\t//\n\t// This field is semantically required to be set to non-empty string.\n\t// Empty value is equivalent to an unknown span name.\n\t//\n\t// This field is required.\n\tName string `json:\"name\"`\n\t// Distinguishes between spans generated in a particular context. For example,\n\t// two spans with the same name may be distinguished using `CLIENT` (caller)\n\t// and `SERVER` (callee) to identify queueing latency associated with the span.\n\tKind SpanKind `json:\"kind,omitempty\"`\n\t// start_time_unix_nano is the start time of the span. On the client side, this is the time\n\t// kept by the local machine where the span execution starts. On the server side, this\n\t// is the time when the server's application handler starts running.\n\t// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970.\n\t//\n\t// This field is semantically required and it is expected that end_time >= start_time.\n\tStartTime time.Time `json:\"startTimeUnixNano,omitempty\"`\n\t// end_time_unix_nano is the end time of the span. On the client side, this is the time\n\t// kept by the local machine where the span execution ends. On the server side, this\n\t// is the time when the server application handler stops running.\n\t// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970.\n\t//\n\t// This field is semantically required and it is expected that end_time >= start_time.\n\tEndTime time.Time `json:\"endTimeUnixNano,omitempty\"`\n\t// attributes is a collection of key/value pairs. Note, global attributes\n\t// like server name can be set using the resource API. Examples of attributes:\n\t//\n\t//     \"/http/user_agent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36\"\n\t//     \"/http/server_latency\": 300\n\t//     \"example.com/myattribute\": true\n\t//     \"example.com/score\": 10.239\n\t//\n\t// The OpenTelemetry API specification further restricts the allowed value types:\n\t// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute\n\t// Attribute keys MUST be unique (it is not allowed to have more than one\n\t// attribute with the same key).\n\tAttrs []Attr `json:\"attributes,omitempty\"`\n\t// dropped_attributes_count is the number of attributes that were discarded. Attributes\n\t// can be discarded because their keys are too long or because there are too many\n\t// attributes. If this value is 0, then no attributes were dropped.\n\tDroppedAttrs uint32 `json:\"droppedAttributesCount,omitempty\"`\n\t// events is a collection of Event items.\n\tEvents []*SpanEvent `json:\"events,omitempty\"`\n\t// dropped_events_count is the number of dropped events. If the value is 0, then no\n\t// events were dropped.\n\tDroppedEvents uint32 `json:\"droppedEventsCount,omitempty\"`\n\t// links is a collection of Links, which are references from this span to a span\n\t// in the same or different trace.\n\tLinks []*SpanLink `json:\"links,omitempty\"`\n\t// dropped_links_count is the number of dropped links after the maximum size was\n\t// enforced. If this value is 0, then no links were dropped.\n\tDroppedLinks uint32 `json:\"droppedLinksCount,omitempty\"`\n\t// An optional final status for this span. Semantically when Status isn't set, it means\n\t// span's status code is unset, i.e. assume STATUS_CODE_UNSET (code = 0).\n\tStatus *Status `json:\"status,omitempty\"`\n}\n\n// MarshalJSON encodes s into OTLP formatted JSON.\nfunc (s Span) MarshalJSON() ([]byte, error) {\n\tstartT := s.StartTime.UnixNano()\n\tif s.StartTime.IsZero() || startT < 0 {\n\t\tstartT = 0\n\t}\n\n\tendT := s.EndTime.UnixNano()\n\tif s.EndTime.IsZero() || endT < 0 {\n\t\tendT = 0\n\t}\n\n\t// Override non-empty default SpanID marshal and omitempty.\n\tvar parentSpanId string\n\tif !s.ParentSpanID.IsEmpty() {\n\t\tb := make([]byte, hex.EncodedLen(spanIDSize))\n\t\thex.Encode(b, s.ParentSpanID[:])\n\t\tparentSpanId = string(b)\n\t}\n\n\ttype Alias Span\n\treturn json.Marshal(struct {\n\t\tAlias\n\t\tParentSpanID string `json:\"parentSpanId,omitempty\"`\n\t\tStartTime    uint64 `json:\"startTimeUnixNano,omitempty\"`\n\t\tEndTime      uint64 `json:\"endTimeUnixNano,omitempty\"`\n\t}{\n\t\tAlias:        Alias(s),\n\t\tParentSpanID: parentSpanId,\n\t\tStartTime:    uint64(startT), // nolint:gosec  // >0 checked above.\n\t\tEndTime:      uint64(endT),   // nolint:gosec  // >0 checked above.\n\t})\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into s.\nfunc (s *Span) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid Span type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid Span field: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"traceId\", \"trace_id\":\n\t\t\terr = decoder.Decode(&s.TraceID)\n\t\tcase \"spanId\", \"span_id\":\n\t\t\terr = decoder.Decode(&s.SpanID)\n\t\tcase \"traceState\", \"trace_state\":\n\t\t\terr = decoder.Decode(&s.TraceState)\n\t\tcase \"parentSpanId\", \"parent_span_id\":\n\t\t\terr = decoder.Decode(&s.ParentSpanID)\n\t\tcase \"flags\":\n\t\t\terr = decoder.Decode(&s.Flags)\n\t\tcase \"name\":\n\t\t\terr = decoder.Decode(&s.Name)\n\t\tcase \"kind\":\n\t\t\terr = decoder.Decode(&s.Kind)\n\t\tcase \"startTimeUnixNano\", \"start_time_unix_nano\":\n\t\t\tvar val protoUint64\n\t\t\terr = decoder.Decode(&val)\n\t\t\tv := int64(min(val.Uint64(), math.MaxInt64)) // nolint: gosec  // Overflow checked.\n\t\t\ts.StartTime = time.Unix(0, v)\n\t\tcase \"endTimeUnixNano\", \"end_time_unix_nano\":\n\t\t\tvar val protoUint64\n\t\t\terr = decoder.Decode(&val)\n\t\t\tv := int64(min(val.Uint64(), math.MaxInt64)) // nolint: gosec  // Overflow checked.\n\t\t\ts.EndTime = time.Unix(0, v)\n\t\tcase \"attributes\":\n\t\t\terr = decoder.Decode(&s.Attrs)\n\t\tcase \"droppedAttributesCount\", \"dropped_attributes_count\":\n\t\t\terr = decoder.Decode(&s.DroppedAttrs)\n\t\tcase \"events\":\n\t\t\terr = decoder.Decode(&s.Events)\n\t\tcase \"droppedEventsCount\", \"dropped_events_count\":\n\t\t\terr = decoder.Decode(&s.DroppedEvents)\n\t\tcase \"links\":\n\t\t\terr = decoder.Decode(&s.Links)\n\t\tcase \"droppedLinksCount\", \"dropped_links_count\":\n\t\t\terr = decoder.Decode(&s.DroppedLinks)\n\t\tcase \"status\":\n\t\t\terr = decoder.Decode(&s.Status)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// SpanFlags represents constants used to interpret the\n// Span.flags field, which is protobuf 'fixed32' type and is to\n// be used as bit-fields. Each non-zero value defined in this enum is\n// a bit-mask.  To extract the bit-field, for example, use an\n// expression like:\n//\n//\t(span.flags & SPAN_FLAGS_TRACE_FLAGS_MASK)\n//\n// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions.\n//\n// Note that Span flags were introduced in version 1.1 of the\n// OpenTelemetry protocol.  Older Span producers do not set this\n// field, consequently consumers should not rely on the absence of a\n// particular flag bit to indicate the presence of a particular feature.\ntype SpanFlags int32\n\nconst (\n\t// SpanFlagsTraceFlagsMask is a mask for trace-flags.\n\t//\n\t// Bits 0-7 are used for trace flags.\n\tSpanFlagsTraceFlagsMask SpanFlags = 255\n\t// SpanFlagsContextHasIsRemoteMask is a mask for HAS_IS_REMOTE status.\n\t//\n\t// Bits 8 and 9 are used to indicate that the parent span or link span is\n\t// remote. Bit 8 (`HAS_IS_REMOTE`) indicates whether the value is known.\n\tSpanFlagsContextHasIsRemoteMask SpanFlags = 256\n\t// SpanFlagsContextIsRemoteMask is a mask for IS_REMOTE status.\n\t//\n\t// Bits 8 and 9 are used to indicate that the parent span or link span is\n\t// remote. Bit 9 (`IS_REMOTE`) indicates whether the span or link is\n\t// remote.\n\tSpanFlagsContextIsRemoteMask SpanFlags = 512\n)\n\n// SpanKind is the type of span. Can be used to specify additional relationships between spans\n// in addition to a parent/child relationship.\ntype SpanKind int32\n\nconst (\n\t// SpanKindInternal indicates that the span represents an internal\n\t// operation within an application, as opposed to an operation happening at\n\t// the boundaries.\n\tSpanKindInternal SpanKind = 1\n\t// SpanKindServer indicates that the span covers server-side handling of an\n\t// RPC or other remote network request.\n\tSpanKindServer SpanKind = 2\n\t// SpanKindClient indicates that the span describes a request to some\n\t// remote service.\n\tSpanKindClient SpanKind = 3\n\t// SpanKindProducer indicates that the span describes a producer sending a\n\t// message to a broker. Unlike SpanKindClient and SpanKindServer, there is\n\t// often no direct critical path latency relationship between producer and\n\t// consumer spans. A SpanKindProducer span ends when the message was\n\t// accepted by the broker while the logical processing of the message might\n\t// span a much longer time.\n\tSpanKindProducer SpanKind = 4\n\t// SpanKindConsumer indicates that the span describes a consumer receiving\n\t// a message from a broker. Like SpanKindProducer, there is often no direct\n\t// critical path latency relationship between producer and consumer spans.\n\tSpanKindConsumer SpanKind = 5\n)\n\n// SpanEvent is a time-stamped annotation of the span, consisting of\n// user-supplied text description and key-value pairs.\ntype SpanEvent struct {\n\t// time_unix_nano is the time the event occurred.\n\tTime time.Time `json:\"timeUnixNano,omitempty\"`\n\t// name of the event.\n\t// This field is semantically required to be set to non-empty string.\n\tName string `json:\"name,omitempty\"`\n\t// attributes is a collection of attribute key/value pairs on the event.\n\t// Attribute keys MUST be unique (it is not allowed to have more than one\n\t// attribute with the same key).\n\tAttrs []Attr `json:\"attributes,omitempty\"`\n\t// dropped_attributes_count is the number of dropped attributes. If the value is 0,\n\t// then no attributes were dropped.\n\tDroppedAttrs uint32 `json:\"droppedAttributesCount,omitempty\"`\n}\n\n// MarshalJSON encodes e into OTLP formatted JSON.\nfunc (e SpanEvent) MarshalJSON() ([]byte, error) {\n\tt := e.Time.UnixNano()\n\tif e.Time.IsZero() || t < 0 {\n\t\tt = 0\n\t}\n\n\ttype Alias SpanEvent\n\treturn json.Marshal(struct {\n\t\tAlias\n\t\tTime uint64 `json:\"timeUnixNano,omitempty\"`\n\t}{\n\t\tAlias: Alias(e),\n\t\tTime:  uint64(t), // nolint: gosec  // >0 checked above\n\t})\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into se.\nfunc (se *SpanEvent) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid SpanEvent type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid SpanEvent field: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"timeUnixNano\", \"time_unix_nano\":\n\t\t\tvar val protoUint64\n\t\t\terr = decoder.Decode(&val)\n\t\t\tv := int64(min(val.Uint64(), math.MaxInt64)) // nolint: gosec  // Overflow checked.\n\t\t\tse.Time = time.Unix(0, v)\n\t\tcase \"name\":\n\t\t\terr = decoder.Decode(&se.Name)\n\t\tcase \"attributes\":\n\t\t\terr = decoder.Decode(&se.Attrs)\n\t\tcase \"droppedAttributesCount\", \"dropped_attributes_count\":\n\t\t\terr = decoder.Decode(&se.DroppedAttrs)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// SpanLink is a reference from the current span to another span in the same\n// trace or in a different trace. For example, this can be used in batching\n// operations, where a single batch handler processes multiple requests from\n// different traces or when the handler receives a request from a different\n// project.\ntype SpanLink struct {\n\t// A unique identifier of a trace that this linked span is part of. The ID is a\n\t// 16-byte array.\n\tTraceID TraceID `json:\"traceId,omitempty\"`\n\t// A unique identifier for the linked span. The ID is an 8-byte array.\n\tSpanID SpanID `json:\"spanId,omitempty\"`\n\t// The trace_state associated with the link.\n\tTraceState string `json:\"traceState,omitempty\"`\n\t// attributes is a collection of attribute key/value pairs on the link.\n\t// Attribute keys MUST be unique (it is not allowed to have more than one\n\t// attribute with the same key).\n\tAttrs []Attr `json:\"attributes,omitempty\"`\n\t// dropped_attributes_count is the number of dropped attributes. If the value is 0,\n\t// then no attributes were dropped.\n\tDroppedAttrs uint32 `json:\"droppedAttributesCount,omitempty\"`\n\t// Flags, a bit field.\n\t//\n\t// Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C Trace\n\t// Context specification. To read the 8-bit W3C trace flag, use\n\t// `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`.\n\t//\n\t// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions.\n\t//\n\t// Bits 8 and 9 represent the 3 states of whether the link is remote.\n\t// The states are (unknown, is not remote, is remote).\n\t// To read whether the value is known, use `(flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`.\n\t// To read whether the link is remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`.\n\t//\n\t// Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero.\n\t// When creating new spans, bits 10-31 (most-significant 22-bits) MUST be zero.\n\t//\n\t// [Optional].\n\tFlags uint32 `json:\"flags,omitempty\"`\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into sl.\nfunc (sl *SpanLink) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid SpanLink type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid SpanLink field: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"traceId\", \"trace_id\":\n\t\t\terr = decoder.Decode(&sl.TraceID)\n\t\tcase \"spanId\", \"span_id\":\n\t\t\terr = decoder.Decode(&sl.SpanID)\n\t\tcase \"traceState\", \"trace_state\":\n\t\t\terr = decoder.Decode(&sl.TraceState)\n\t\tcase \"attributes\":\n\t\t\terr = decoder.Decode(&sl.Attrs)\n\t\tcase \"droppedAttributesCount\", \"dropped_attributes_count\":\n\t\t\terr = decoder.Decode(&sl.DroppedAttrs)\n\t\tcase \"flags\":\n\t\t\terr = decoder.Decode(&sl.Flags)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/internal/telemetry/status.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry // import \"go.opentelemetry.io/otel/trace/internal/telemetry\"\n\n// StatusCode is the status of a Span.\n//\n// For the semantics of status codes see\n// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status\ntype StatusCode int32\n\nconst (\n\t// StatusCodeUnset is the default status.\n\tStatusCodeUnset StatusCode = 0\n\t// StatusCodeOK is used when the Span has been validated by an Application\n\t// developer or Operator to have completed successfully.\n\tStatusCodeOK StatusCode = 1\n\t// StatusCodeError is used when the Span contains an error.\n\tStatusCodeError StatusCode = 2\n)\n\nvar statusCodeStrings = []string{\n\t\"Unset\",\n\t\"OK\",\n\t\"Error\",\n}\n\nfunc (s StatusCode) String() string {\n\tif s >= 0 && int(s) < len(statusCodeStrings) {\n\t\treturn statusCodeStrings[s]\n\t}\n\treturn \"<unknown telemetry.StatusCode>\"\n}\n\n// Status defines a logical error model that is suitable for different\n// programming environments, including REST APIs and RPC APIs.\ntype Status struct {\n\t// A developer-facing human readable error message.\n\tMessage string `json:\"message,omitempty\"`\n\t// The status code.\n\tCode StatusCode `json:\"code,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/internal/telemetry/traces.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry // import \"go.opentelemetry.io/otel/trace/internal/telemetry\"\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\n// Traces represents the traces data that can be stored in a persistent storage,\n// OR can be embedded by other protocols that transfer OTLP traces data but do\n// not implement the OTLP protocol.\n//\n// The main difference between this message and collector protocol is that\n// in this message there will not be any \"control\" or \"metadata\" specific to\n// OTLP protocol.\n//\n// When new fields are added into this message, the OTLP request MUST be updated\n// as well.\ntype Traces struct {\n\t// An array of ResourceSpans.\n\t// For data coming from a single resource this array will typically contain\n\t// one element. Intermediary nodes that receive data from multiple origins\n\t// typically batch the data before forwarding further and in that case this\n\t// array will contain multiple elements.\n\tResourceSpans []*ResourceSpans `json:\"resourceSpans,omitempty\"`\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into td.\nfunc (td *Traces) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid TracesData type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid TracesData field: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"resourceSpans\", \"resource_spans\":\n\t\t\terr = decoder.Decode(&td.ResourceSpans)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// ResourceSpans is a collection of ScopeSpans from a Resource.\ntype ResourceSpans struct {\n\t// The resource for the spans in this message.\n\t// If this field is not set then no resource info is known.\n\tResource Resource `json:\"resource\"`\n\t// A list of ScopeSpans that originate from a resource.\n\tScopeSpans []*ScopeSpans `json:\"scopeSpans,omitempty\"`\n\t// This schema_url applies to the data in the \"resource\" field. It does not apply\n\t// to the data in the \"scope_spans\" field which have their own schema_url field.\n\tSchemaURL string `json:\"schemaUrl,omitempty\"`\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into rs.\nfunc (rs *ResourceSpans) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid ResourceSpans type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid ResourceSpans field: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"resource\":\n\t\t\terr = decoder.Decode(&rs.Resource)\n\t\tcase \"scopeSpans\", \"scope_spans\":\n\t\t\terr = decoder.Decode(&rs.ScopeSpans)\n\t\tcase \"schemaUrl\", \"schema_url\":\n\t\t\terr = decoder.Decode(&rs.SchemaURL)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// ScopeSpans is a collection of Spans produced by an InstrumentationScope.\ntype ScopeSpans struct {\n\t// The instrumentation scope information for the spans in this message.\n\t// Semantically when InstrumentationScope isn't set, it is equivalent with\n\t// an empty instrumentation scope name (unknown).\n\tScope *Scope `json:\"scope\"`\n\t// A list of Spans that originate from an instrumentation scope.\n\tSpans []*Span `json:\"spans,omitempty\"`\n\t// The Schema URL, if known. This is the identifier of the Schema that the span data\n\t// is recorded in. To learn more about Schema URL see\n\t// https://opentelemetry.io/docs/specs/otel/schemas/#schema-url\n\t// This schema_url applies to all spans and span events in the \"spans\" field.\n\tSchemaURL string `json:\"schemaUrl,omitempty\"`\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into ss.\nfunc (ss *ScopeSpans) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid ScopeSpans type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid ScopeSpans field: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"scope\":\n\t\t\terr = decoder.Decode(&ss.Scope)\n\t\tcase \"spans\":\n\t\t\terr = decoder.Decode(&ss.Spans)\n\t\tcase \"schemaUrl\", \"schema_url\":\n\t\t\terr = decoder.Decode(&ss.SchemaURL)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/internal/telemetry/value.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage telemetry // import \"go.opentelemetry.io/otel/trace/internal/telemetry\"\n\nimport (\n\t\"bytes\"\n\t\"cmp\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"slices\"\n\t\"strconv\"\n\t\"unsafe\"\n)\n\n// A Value represents a structured value.\n// A zero value is valid and represents an empty value.\ntype Value struct {\n\t// Ensure forward compatibility by explicitly making this not comparable.\n\tnoCmp [0]func() //nolint: unused  // This is indeed used.\n\n\t// num holds the value for Int64, Float64, and Bool. It holds the length\n\t// for String, Bytes, Slice, Map.\n\tnum uint64\n\t// any holds either the KindBool, KindInt64, KindFloat64, stringptr,\n\t// bytesptr, sliceptr, or mapptr. If KindBool, KindInt64, or KindFloat64\n\t// then the value of Value is in num as described above. Otherwise, it\n\t// contains the value wrapped in the appropriate type.\n\tany any\n}\n\ntype (\n\t// sliceptr represents a value in Value.any for KindString Values.\n\tstringptr *byte\n\t// bytesptr represents a value in Value.any for KindBytes Values.\n\tbytesptr *byte\n\t// sliceptr represents a value in Value.any for KindSlice Values.\n\tsliceptr *Value\n\t// mapptr represents a value in Value.any for KindMap Values.\n\tmapptr *Attr\n)\n\n// ValueKind is the kind of a [Value].\ntype ValueKind int\n\n// ValueKind values.\nconst (\n\tValueKindEmpty ValueKind = iota\n\tValueKindBool\n\tValueKindFloat64\n\tValueKindInt64\n\tValueKindString\n\tValueKindBytes\n\tValueKindSlice\n\tValueKindMap\n)\n\nvar valueKindStrings = []string{\n\t\"Empty\",\n\t\"Bool\",\n\t\"Float64\",\n\t\"Int64\",\n\t\"String\",\n\t\"Bytes\",\n\t\"Slice\",\n\t\"Map\",\n}\n\nfunc (k ValueKind) String() string {\n\tif k >= 0 && int(k) < len(valueKindStrings) {\n\t\treturn valueKindStrings[k]\n\t}\n\treturn \"<unknown telemetry.ValueKind>\"\n}\n\n// StringValue returns a new [Value] for a string.\nfunc StringValue(v string) Value {\n\treturn Value{\n\t\tnum: uint64(len(v)),\n\t\tany: stringptr(unsafe.StringData(v)),\n\t}\n}\n\n// IntValue returns a [Value] for an int.\nfunc IntValue(v int) Value { return Int64Value(int64(v)) }\n\n// Int64Value returns a [Value] for an int64.\nfunc Int64Value(v int64) Value {\n\treturn Value{\n\t\tnum: uint64(v), // nolint: gosec  // Store raw bytes.\n\t\tany: ValueKindInt64,\n\t}\n}\n\n// Float64Value returns a [Value] for a float64.\nfunc Float64Value(v float64) Value {\n\treturn Value{num: math.Float64bits(v), any: ValueKindFloat64}\n}\n\n// BoolValue returns a [Value] for a bool.\nfunc BoolValue(v bool) Value { //nolint:revive // Not a control flag.\n\tvar n uint64\n\tif v {\n\t\tn = 1\n\t}\n\treturn Value{num: n, any: ValueKindBool}\n}\n\n// BytesValue returns a [Value] for a byte slice. The passed slice must not be\n// changed after it is passed.\nfunc BytesValue(v []byte) Value {\n\treturn Value{\n\t\tnum: uint64(len(v)),\n\t\tany: bytesptr(unsafe.SliceData(v)),\n\t}\n}\n\n// SliceValue returns a [Value] for a slice of [Value]. The passed slice must\n// not be changed after it is passed.\nfunc SliceValue(vs ...Value) Value {\n\treturn Value{\n\t\tnum: uint64(len(vs)),\n\t\tany: sliceptr(unsafe.SliceData(vs)),\n\t}\n}\n\n// MapValue returns a new [Value] for a slice of key-value pairs. The passed\n// slice must not be changed after it is passed.\nfunc MapValue(kvs ...Attr) Value {\n\treturn Value{\n\t\tnum: uint64(len(kvs)),\n\t\tany: mapptr(unsafe.SliceData(kvs)),\n\t}\n}\n\n// AsString returns the value held by v as a string.\nfunc (v Value) AsString() string {\n\tif sp, ok := v.any.(stringptr); ok {\n\t\treturn unsafe.String(sp, v.num)\n\t}\n\t// TODO: error handle\n\treturn \"\"\n}\n\n// asString returns the value held by v as a string. It will panic if the Value\n// is not KindString.\nfunc (v Value) asString() string {\n\treturn unsafe.String(v.any.(stringptr), v.num)\n}\n\n// AsInt64 returns the value held by v as an int64.\nfunc (v Value) AsInt64() int64 {\n\tif v.Kind() != ValueKindInt64 {\n\t\t// TODO: error handle\n\t\treturn 0\n\t}\n\treturn v.asInt64()\n}\n\n// asInt64 returns the value held by v as an int64. If v is not of KindInt64,\n// this will return garbage.\nfunc (v Value) asInt64() int64 {\n\t// Assumes v.num was a valid int64 (overflow not checked).\n\treturn int64(v.num) // nolint: gosec\n}\n\n// AsBool returns the value held by v as a bool.\nfunc (v Value) AsBool() bool {\n\tif v.Kind() != ValueKindBool {\n\t\t// TODO: error handle\n\t\treturn false\n\t}\n\treturn v.asBool()\n}\n\n// asBool returns the value held by v as a bool. If v is not of KindBool, this\n// will return garbage.\nfunc (v Value) asBool() bool { return v.num == 1 }\n\n// AsFloat64 returns the value held by v as a float64.\nfunc (v Value) AsFloat64() float64 {\n\tif v.Kind() != ValueKindFloat64 {\n\t\t// TODO: error handle\n\t\treturn 0\n\t}\n\treturn v.asFloat64()\n}\n\n// asFloat64 returns the value held by v as a float64. If v is not of\n// KindFloat64, this will return garbage.\nfunc (v Value) asFloat64() float64 { return math.Float64frombits(v.num) }\n\n// AsBytes returns the value held by v as a []byte.\nfunc (v Value) AsBytes() []byte {\n\tif sp, ok := v.any.(bytesptr); ok {\n\t\treturn unsafe.Slice((*byte)(sp), v.num)\n\t}\n\t// TODO: error handle\n\treturn nil\n}\n\n// asBytes returns the value held by v as a []byte. It will panic if the Value\n// is not KindBytes.\nfunc (v Value) asBytes() []byte {\n\treturn unsafe.Slice((*byte)(v.any.(bytesptr)), v.num)\n}\n\n// AsSlice returns the value held by v as a []Value.\nfunc (v Value) AsSlice() []Value {\n\tif sp, ok := v.any.(sliceptr); ok {\n\t\treturn unsafe.Slice((*Value)(sp), v.num)\n\t}\n\t// TODO: error handle\n\treturn nil\n}\n\n// asSlice returns the value held by v as a []Value. It will panic if the Value\n// is not KindSlice.\nfunc (v Value) asSlice() []Value {\n\treturn unsafe.Slice((*Value)(v.any.(sliceptr)), v.num)\n}\n\n// AsMap returns the value held by v as a []Attr.\nfunc (v Value) AsMap() []Attr {\n\tif sp, ok := v.any.(mapptr); ok {\n\t\treturn unsafe.Slice((*Attr)(sp), v.num)\n\t}\n\t// TODO: error handle\n\treturn nil\n}\n\n// asMap returns the value held by v as a []Attr. It will panic if the\n// Value is not KindMap.\nfunc (v Value) asMap() []Attr {\n\treturn unsafe.Slice((*Attr)(v.any.(mapptr)), v.num)\n}\n\n// Kind returns the Kind of v.\nfunc (v Value) Kind() ValueKind {\n\tswitch x := v.any.(type) {\n\tcase ValueKind:\n\t\treturn x\n\tcase stringptr:\n\t\treturn ValueKindString\n\tcase bytesptr:\n\t\treturn ValueKindBytes\n\tcase sliceptr:\n\t\treturn ValueKindSlice\n\tcase mapptr:\n\t\treturn ValueKindMap\n\tdefault:\n\t\treturn ValueKindEmpty\n\t}\n}\n\n// Empty reports whether v does not hold any value.\nfunc (v Value) Empty() bool { return v.Kind() == ValueKindEmpty }\n\n// Equal reports whether v is equal to w.\nfunc (v Value) Equal(w Value) bool {\n\tk1 := v.Kind()\n\tk2 := w.Kind()\n\tif k1 != k2 {\n\t\treturn false\n\t}\n\tswitch k1 {\n\tcase ValueKindInt64, ValueKindBool:\n\t\treturn v.num == w.num\n\tcase ValueKindString:\n\t\treturn v.asString() == w.asString()\n\tcase ValueKindFloat64:\n\t\treturn v.asFloat64() == w.asFloat64()\n\tcase ValueKindSlice:\n\t\treturn slices.EqualFunc(v.asSlice(), w.asSlice(), Value.Equal)\n\tcase ValueKindMap:\n\t\tsv := sortMap(v.asMap())\n\t\tsw := sortMap(w.asMap())\n\t\treturn slices.EqualFunc(sv, sw, Attr.Equal)\n\tcase ValueKindBytes:\n\t\treturn bytes.Equal(v.asBytes(), w.asBytes())\n\tcase ValueKindEmpty:\n\t\treturn true\n\tdefault:\n\t\t// TODO: error handle\n\t\treturn false\n\t}\n}\n\nfunc sortMap(m []Attr) []Attr {\n\tsm := make([]Attr, len(m))\n\tcopy(sm, m)\n\tslices.SortFunc(sm, func(a, b Attr) int {\n\t\treturn cmp.Compare(a.Key, b.Key)\n\t})\n\n\treturn sm\n}\n\n// String returns Value's value as a string, formatted like [fmt.Sprint].\n//\n// The returned string is meant for debugging;\n// the string representation is not stable.\nfunc (v Value) String() string {\n\tswitch v.Kind() {\n\tcase ValueKindString:\n\t\treturn v.asString()\n\tcase ValueKindInt64:\n\t\t// Assumes v.num was a valid int64 (overflow not checked).\n\t\treturn strconv.FormatInt(int64(v.num), 10) // nolint: gosec\n\tcase ValueKindFloat64:\n\t\treturn strconv.FormatFloat(v.asFloat64(), 'g', -1, 64)\n\tcase ValueKindBool:\n\t\treturn strconv.FormatBool(v.asBool())\n\tcase ValueKindBytes:\n\t\treturn string(v.asBytes())\n\tcase ValueKindMap:\n\t\treturn fmt.Sprint(v.asMap())\n\tcase ValueKindSlice:\n\t\treturn fmt.Sprint(v.asSlice())\n\tcase ValueKindEmpty:\n\t\treturn \"<nil>\"\n\tdefault:\n\t\t// Try to handle this as gracefully as possible.\n\t\t//\n\t\t// Don't panic here. The goal here is to have developers find this\n\t\t// first if a slog.Kind is is not handled. It is\n\t\t// preferable to have user's open issue asking why their attributes\n\t\t// have a \"unhandled: \" prefix than say that their code is panicking.\n\t\treturn fmt.Sprintf(\"<unhandled telemetry.ValueKind: %s>\", v.Kind())\n\t}\n}\n\n// MarshalJSON encodes v into OTLP formatted JSON.\nfunc (v *Value) MarshalJSON() ([]byte, error) {\n\tswitch v.Kind() {\n\tcase ValueKindString:\n\t\treturn json.Marshal(struct {\n\t\t\tValue string `json:\"stringValue\"`\n\t\t}{v.asString()})\n\tcase ValueKindInt64:\n\t\treturn json.Marshal(struct {\n\t\t\tValue string `json:\"intValue\"`\n\t\t}{strconv.FormatInt(int64(v.num), 10)}) // nolint: gosec  // From raw bytes.\n\tcase ValueKindFloat64:\n\t\treturn json.Marshal(struct {\n\t\t\tValue float64 `json:\"doubleValue\"`\n\t\t}{v.asFloat64()})\n\tcase ValueKindBool:\n\t\treturn json.Marshal(struct {\n\t\t\tValue bool `json:\"boolValue\"`\n\t\t}{v.asBool()})\n\tcase ValueKindBytes:\n\t\treturn json.Marshal(struct {\n\t\t\tValue []byte `json:\"bytesValue\"`\n\t\t}{v.asBytes()})\n\tcase ValueKindMap:\n\t\treturn json.Marshal(struct {\n\t\t\tValue struct {\n\t\t\t\tValues []Attr `json:\"values\"`\n\t\t\t} `json:\"kvlistValue\"`\n\t\t}{struct {\n\t\t\tValues []Attr `json:\"values\"`\n\t\t}{v.asMap()}})\n\tcase ValueKindSlice:\n\t\treturn json.Marshal(struct {\n\t\t\tValue struct {\n\t\t\t\tValues []Value `json:\"values\"`\n\t\t\t} `json:\"arrayValue\"`\n\t\t}{struct {\n\t\t\tValues []Value `json:\"values\"`\n\t\t}{v.asSlice()}})\n\tcase ValueKindEmpty:\n\t\treturn nil, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown Value kind: %s\", v.Kind().String())\n\t}\n}\n\n// UnmarshalJSON decodes the OTLP formatted JSON contained in data into v.\nfunc (v *Value) UnmarshalJSON(data []byte) error {\n\tdecoder := json.NewDecoder(bytes.NewReader(data))\n\n\tt, err := decoder.Token()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif t != json.Delim('{') {\n\t\treturn errors.New(\"invalid Value type\")\n\t}\n\n\tfor decoder.More() {\n\t\tkeyIface, err := decoder.Token()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t// Empty.\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tkey, ok := keyIface.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid Value key: %#v\", keyIface)\n\t\t}\n\n\t\tswitch key {\n\t\tcase \"stringValue\", \"string_value\":\n\t\t\tvar val string\n\t\t\terr = decoder.Decode(&val)\n\t\t\t*v = StringValue(val)\n\t\tcase \"boolValue\", \"bool_value\":\n\t\t\tvar val bool\n\t\t\terr = decoder.Decode(&val)\n\t\t\t*v = BoolValue(val)\n\t\tcase \"intValue\", \"int_value\":\n\t\t\tvar val protoInt64\n\t\t\terr = decoder.Decode(&val)\n\t\t\t*v = Int64Value(val.Int64())\n\t\tcase \"doubleValue\", \"double_value\":\n\t\t\tvar val float64\n\t\t\terr = decoder.Decode(&val)\n\t\t\t*v = Float64Value(val)\n\t\tcase \"bytesValue\", \"bytes_value\":\n\t\t\tvar val64 string\n\t\t\tif err := decoder.Decode(&val64); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tvar val []byte\n\t\t\tval, err = base64.StdEncoding.DecodeString(val64)\n\t\t\t*v = BytesValue(val)\n\t\tcase \"arrayValue\", \"array_value\":\n\t\t\tvar val struct{ Values []Value }\n\t\t\terr = decoder.Decode(&val)\n\t\t\t*v = SliceValue(val.Values...)\n\t\tcase \"kvlistValue\", \"kvlist_value\":\n\t\t\tvar val struct{ Values []Attr }\n\t\t\terr = decoder.Decode(&val)\n\t\t\t*v = MapValue(val.Values...)\n\t\tdefault:\n\t\t\t// Skip unknown.\n\t\t\tcontinue\n\t\t}\n\t\t// Use first valid. Ignore the rest.\n\t\treturn err\n\t}\n\n\t// Only unknown fields. Return nil without unmarshaling any value.\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/nonrecording.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n\n// nonRecordingSpan is a minimal implementation of a Span that wraps a\n// SpanContext. It performs no operations other than to return the wrapped\n// SpanContext.\ntype nonRecordingSpan struct {\n\tnoopSpan\n\n\tsc SpanContext\n}\n\n// SpanContext returns the wrapped SpanContext.\nfunc (s nonRecordingSpan) SpanContext() SpanContext { return s.sc }\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/noop/README.md",
    "content": "# Trace Noop\n\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/trace/noop)](https://pkg.go.dev/go.opentelemetry.io/otel/trace/noop)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/noop/noop.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\n// Package noop provides an implementation of the OpenTelemetry trace API that\n// produces no telemetry and minimizes used computation resources.\n//\n// Using this package to implement the OpenTelemetry trace API will effectively\n// disable OpenTelemetry.\n//\n// This implementation can be embedded in other implementations of the\n// OpenTelemetry trace API. Doing so will mean the implementation defaults to\n// no operation for methods it does not implement.\npackage noop // import \"go.opentelemetry.io/otel/trace/noop\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n\t\"go.opentelemetry.io/otel/trace\"\n\t\"go.opentelemetry.io/otel/trace/embedded\"\n)\n\nvar (\n\t// Compile-time check this implements the OpenTelemetry API.\n\n\t_ trace.TracerProvider = TracerProvider{}\n\t_ trace.Tracer         = Tracer{}\n\t_ trace.Span           = Span{}\n)\n\n// TracerProvider is an OpenTelemetry No-Op TracerProvider.\ntype TracerProvider struct{ embedded.TracerProvider }\n\n// NewTracerProvider returns a TracerProvider that does not record any telemetry.\nfunc NewTracerProvider() TracerProvider {\n\treturn TracerProvider{}\n}\n\n// Tracer returns an OpenTelemetry Tracer that does not record any telemetry.\nfunc (TracerProvider) Tracer(string, ...trace.TracerOption) trace.Tracer {\n\treturn Tracer{}\n}\n\n// Tracer is an OpenTelemetry No-Op Tracer.\ntype Tracer struct{ embedded.Tracer }\n\n// Start creates a span. The created span will be set in a child context of ctx\n// and returned with the span.\n//\n// If ctx contains a span context, the returned span will also contain that\n// span context. If the span context in ctx is for a non-recording span, that\n// span instance will be returned directly.\nfunc (Tracer) Start(ctx context.Context, _ string, _ ...trace.SpanStartOption) (context.Context, trace.Span) {\n\tspan := trace.SpanFromContext(ctx)\n\n\t// If the parent context contains a non-zero span context, that span\n\t// context needs to be returned as a non-recording span\n\t// (https://github.com/open-telemetry/opentelemetry-specification/blob/3a1dde966a4ce87cce5adf464359fe369741bbea/specification/trace/api.md#behavior-of-the-api-in-the-absence-of-an-installed-sdk).\n\tvar zeroSC trace.SpanContext\n\tif sc := span.SpanContext(); !sc.Equal(zeroSC) {\n\t\tif !span.IsRecording() {\n\t\t\t// If the span is not recording return it directly.\n\t\t\treturn ctx, span\n\t\t}\n\t\t// Otherwise, return the span context needs in a non-recording span.\n\t\tspan = Span{sc: sc}\n\t} else {\n\t\t// No parent, return a No-Op span with an empty span context.\n\t\tspan = noopSpanInstance\n\t}\n\treturn trace.ContextWithSpan(ctx, span), span\n}\n\nvar noopSpanInstance trace.Span = Span{}\n\n// Span is an OpenTelemetry No-Op Span.\ntype Span struct {\n\tembedded.Span\n\n\tsc trace.SpanContext\n}\n\n// SpanContext returns an empty span context.\nfunc (s Span) SpanContext() trace.SpanContext { return s.sc }\n\n// IsRecording always returns false.\nfunc (Span) IsRecording() bool { return false }\n\n// SetStatus does nothing.\nfunc (Span) SetStatus(codes.Code, string) {}\n\n// SetAttributes does nothing.\nfunc (Span) SetAttributes(...attribute.KeyValue) {}\n\n// End does nothing.\nfunc (Span) End(...trace.SpanEndOption) {}\n\n// RecordError does nothing.\nfunc (Span) RecordError(error, ...trace.EventOption) {}\n\n// AddEvent does nothing.\nfunc (Span) AddEvent(string, ...trace.EventOption) {}\n\n// AddLink does nothing.\nfunc (Span) AddLink(trace.Link) {}\n\n// SetName does nothing.\nfunc (Span) SetName(string) {}\n\n// TracerProvider returns a No-Op TracerProvider.\nfunc (Span) TracerProvider() trace.TracerProvider { return TracerProvider{} }\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/noop.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n\t\"go.opentelemetry.io/otel/trace/embedded\"\n)\n\n// NewNoopTracerProvider returns an implementation of TracerProvider that\n// performs no operations. The Tracer and Spans created from the returned\n// TracerProvider also perform no operations.\n//\n// Deprecated: Use [go.opentelemetry.io/otel/trace/noop.NewTracerProvider]\n// instead.\nfunc NewNoopTracerProvider() TracerProvider {\n\treturn noopTracerProvider{}\n}\n\ntype noopTracerProvider struct{ embedded.TracerProvider }\n\nvar _ TracerProvider = noopTracerProvider{}\n\n// Tracer returns noop implementation of Tracer.\nfunc (noopTracerProvider) Tracer(string, ...TracerOption) Tracer {\n\treturn noopTracer{}\n}\n\n// noopTracer is an implementation of Tracer that performs no operations.\ntype noopTracer struct{ embedded.Tracer }\n\nvar _ Tracer = noopTracer{}\n\n// Start carries forward a non-recording Span, if one is present in the context, otherwise it\n// creates a no-op Span.\nfunc (noopTracer) Start(ctx context.Context, _ string, _ ...SpanStartOption) (context.Context, Span) {\n\tspan := SpanFromContext(ctx)\n\tif _, ok := span.(nonRecordingSpan); !ok {\n\t\t// span is likely already a noopSpan, but let's be sure\n\t\tspan = noopSpanInstance\n\t}\n\treturn ContextWithSpan(ctx, span), span\n}\n\n// noopSpan is an implementation of Span that performs no operations.\ntype noopSpan struct{ embedded.Span }\n\nvar noopSpanInstance Span = noopSpan{}\n\n// SpanContext returns an empty span context.\nfunc (noopSpan) SpanContext() SpanContext { return SpanContext{} }\n\n// IsRecording always returns false.\nfunc (noopSpan) IsRecording() bool { return false }\n\n// SetStatus does nothing.\nfunc (noopSpan) SetStatus(codes.Code, string) {}\n\n// SetError does nothing.\nfunc (noopSpan) SetError(bool) {}\n\n// SetAttributes does nothing.\nfunc (noopSpan) SetAttributes(...attribute.KeyValue) {}\n\n// End does nothing.\nfunc (noopSpan) End(...SpanEndOption) {}\n\n// RecordError does nothing.\nfunc (noopSpan) RecordError(error, ...EventOption) {}\n\n// AddEvent does nothing.\nfunc (noopSpan) AddEvent(string, ...EventOption) {}\n\n// AddLink does nothing.\nfunc (noopSpan) AddLink(Link) {}\n\n// SetName does nothing.\nfunc (noopSpan) SetName(string) {}\n\n// TracerProvider returns a no-op TracerProvider.\nfunc (s noopSpan) TracerProvider() TracerProvider {\n\treturn s.tracerProvider(autoInstEnabled)\n}\n\n// autoInstEnabled defines if the auto-instrumentation SDK is enabled.\n//\n// The auto-instrumentation is expected to overwrite this value to true when it\n// attaches to the process.\nvar autoInstEnabled = new(bool)\n\n// tracerProvider return a noopTracerProvider if autoEnabled is false,\n// otherwise it will return a TracerProvider from the sdk package used in\n// auto-instrumentation.\n//\n//go:noinline\nfunc (noopSpan) tracerProvider(autoEnabled *bool) TracerProvider {\n\tif *autoEnabled {\n\t\treturn newAutoTracerProvider()\n\t}\n\treturn noopTracerProvider{}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/provider.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n\nimport \"go.opentelemetry.io/otel/trace/embedded\"\n\n// TracerProvider provides Tracers that are used by instrumentation code to\n// trace computational workflows.\n//\n// A TracerProvider is the collection destination of all Spans from Tracers it\n// provides, it represents a unique telemetry collection pipeline. How that\n// pipeline is defined, meaning how those Spans are collected, processed, and\n// where they are exported, depends on its implementation. Instrumentation\n// authors do not need to define this implementation, rather just use the\n// provided Tracers to instrument code.\n//\n// Commonly, instrumentation code will accept a TracerProvider implementation\n// at runtime from its users or it can simply use the globally registered one\n// (see https://pkg.go.dev/go.opentelemetry.io/otel#GetTracerProvider).\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype TracerProvider interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.TracerProvider\n\n\t// Tracer returns a unique Tracer scoped to be used by instrumentation code\n\t// to trace computational workflows. The scope and identity of that\n\t// instrumentation code is uniquely defined by the name and options passed.\n\t//\n\t// The passed name needs to uniquely identify instrumentation code.\n\t// Therefore, it is recommended that name is the Go package name of the\n\t// library providing instrumentation (note: not the code being\n\t// instrumented). Instrumentation libraries can have multiple versions,\n\t// therefore, the WithInstrumentationVersion option should be used to\n\t// distinguish these different codebases. Additionally, instrumentation\n\t// libraries may sometimes use traces to communicate different domains of\n\t// workflow data (i.e. using spans to communicate workflow events only). If\n\t// this is the case, the WithScopeAttributes option should be used to\n\t// uniquely identify Tracers that handle the different domains of workflow\n\t// data.\n\t//\n\t// If the same name and options are passed multiple times, the same Tracer\n\t// will be returned (it is up to the implementation if this will be the\n\t// same underlying instance of that Tracer or not). It is not necessary to\n\t// call this multiple times with the same name and options to get an\n\t// up-to-date Tracer. All implementations will ensure any TracerProvider\n\t// configuration changes are propagated to all provided Tracers.\n\t//\n\t// If name is empty, then an implementation defined default name will be\n\t// used instead.\n\t//\n\t// This method is safe to call concurrently.\n\tTracer(name string, options ...TracerOption) Tracer\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/span.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n\t\"go.opentelemetry.io/otel/trace/embedded\"\n)\n\n// Span is the individual component of a trace. It represents a single named\n// and timed operation of a workflow that is traced. A Tracer is used to\n// create a Span and it is then up to the operation the Span represents to\n// properly end the Span when the operation itself ends.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Span interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Span\n\n\t// End completes the Span. The Span is considered complete and ready to be\n\t// delivered through the rest of the telemetry pipeline after this method\n\t// is called. Therefore, updates to the Span are not allowed after this\n\t// method has been called.\n\tEnd(options ...SpanEndOption)\n\n\t// AddEvent adds an event with the provided name and options.\n\tAddEvent(name string, options ...EventOption)\n\n\t// AddLink adds a link.\n\t// Adding links at span creation using WithLinks is preferred to calling AddLink\n\t// later, for contexts that are available during span creation, because head\n\t// sampling decisions can only consider information present during span creation.\n\tAddLink(link Link)\n\n\t// IsRecording returns the recording state of the Span. It will return\n\t// true if the Span is active and events can be recorded.\n\tIsRecording() bool\n\n\t// RecordError will record err as an exception span event for this span. An\n\t// additional call to SetStatus is required if the Status of the Span should\n\t// be set to Error, as this method does not change the Span status. If this\n\t// span is not being recorded or err is nil then this method does nothing.\n\tRecordError(err error, options ...EventOption)\n\n\t// SpanContext returns the SpanContext of the Span. The returned SpanContext\n\t// is usable even after the End method has been called for the Span.\n\tSpanContext() SpanContext\n\n\t// SetStatus sets the status of the Span in the form of a code and a\n\t// description, provided the status hasn't already been set to a higher\n\t// value before (OK > Error > Unset). The description is only included in a\n\t// status when the code is for an error.\n\tSetStatus(code codes.Code, description string)\n\n\t// SetName sets the Span name.\n\tSetName(name string)\n\n\t// SetAttributes sets kv as attributes of the Span. If a key from kv\n\t// already exists for an attribute of the Span it will be overwritten with\n\t// the value contained in kv.\n\t//\n\t// Note that adding attributes at span creation using [WithAttributes] is preferred\n\t// to calling SetAttribute later, as samplers can only consider information\n\t// already present during span creation.\n\tSetAttributes(kv ...attribute.KeyValue)\n\n\t// TracerProvider returns a TracerProvider that can be used to generate\n\t// additional Spans on the same telemetry pipeline as the current Span.\n\tTracerProvider() TracerProvider\n}\n\n// Link is the relationship between two Spans. The relationship can be within\n// the same Trace or across different Traces.\n//\n// For example, a Link is used in the following situations:\n//\n//  1. Batch Processing: A batch of operations may contain operations\n//     associated with one or more traces/spans. Since there can only be one\n//     parent SpanContext, a Link is used to keep reference to the\n//     SpanContext of all operations in the batch.\n//  2. Public Endpoint: A SpanContext for an in incoming client request on a\n//     public endpoint should be considered untrusted. In such a case, a new\n//     trace with its own identity and sampling decision needs to be created,\n//     but this new trace needs to be related to the original trace in some\n//     form. A Link is used to keep reference to the original SpanContext and\n//     track the relationship.\ntype Link struct {\n\t// SpanContext of the linked Span.\n\tSpanContext SpanContext\n\n\t// Attributes describe the aspects of the link.\n\tAttributes []attribute.KeyValue\n}\n\n// LinkFromContext returns a link encapsulating the SpanContext in the provided\n// ctx.\nfunc LinkFromContext(ctx context.Context, attrs ...attribute.KeyValue) Link {\n\treturn Link{\n\t\tSpanContext: SpanContextFromContext(ctx),\n\t\tAttributes:  attrs,\n\t}\n}\n\n// SpanKind is the role a Span plays in a Trace.\ntype SpanKind int\n\n// As a convenience, these match the proto definition, see\n// https://github.com/open-telemetry/opentelemetry-proto/blob/30d237e1ff3ab7aa50e0922b5bebdd93505090af/opentelemetry/proto/trace/v1/trace.proto#L101-L129\n//\n// The unspecified value is not a valid `SpanKind`. Use `ValidateSpanKind()`\n// to coerce a span kind to a valid value.\nconst (\n\t// SpanKindUnspecified is an unspecified SpanKind and is not a valid\n\t// SpanKind. SpanKindUnspecified should be replaced with SpanKindInternal\n\t// if it is received.\n\tSpanKindUnspecified SpanKind = 0\n\t// SpanKindInternal is a SpanKind for a Span that represents an internal\n\t// operation within an application.\n\tSpanKindInternal SpanKind = 1\n\t// SpanKindServer is a SpanKind for a Span that represents the operation\n\t// of handling a request from a client.\n\tSpanKindServer SpanKind = 2\n\t// SpanKindClient is a SpanKind for a Span that represents the operation\n\t// of client making a request to a server.\n\tSpanKindClient SpanKind = 3\n\t// SpanKindProducer is a SpanKind for a Span that represents the operation\n\t// of a producer sending a message to a message broker. Unlike\n\t// SpanKindClient and SpanKindServer, there is often no direct\n\t// relationship between this kind of Span and a SpanKindConsumer kind. A\n\t// SpanKindProducer Span will end once the message is accepted by the\n\t// message broker which might not overlap with the processing of that\n\t// message.\n\tSpanKindProducer SpanKind = 4\n\t// SpanKindConsumer is a SpanKind for a Span that represents the operation\n\t// of a consumer receiving a message from a message broker. Like\n\t// SpanKindProducer Spans, there is often no direct relationship between\n\t// this Span and the Span that produced the message.\n\tSpanKindConsumer SpanKind = 5\n)\n\n// ValidateSpanKind returns a valid span kind value.  This will coerce\n// invalid values into the default value, SpanKindInternal.\nfunc ValidateSpanKind(spanKind SpanKind) SpanKind {\n\tswitch spanKind {\n\tcase SpanKindInternal,\n\t\tSpanKindServer,\n\t\tSpanKindClient,\n\t\tSpanKindProducer,\n\t\tSpanKindConsumer:\n\t\t// valid\n\t\treturn spanKind\n\tdefault:\n\t\treturn SpanKindInternal\n\t}\n}\n\n// String returns the specified name of the SpanKind in lower-case.\nfunc (sk SpanKind) String() string {\n\tswitch sk {\n\tcase SpanKindInternal:\n\t\treturn \"internal\"\n\tcase SpanKindServer:\n\t\treturn \"server\"\n\tcase SpanKindClient:\n\t\treturn \"client\"\n\tcase SpanKindProducer:\n\t\treturn \"producer\"\n\tcase SpanKindConsumer:\n\t\treturn \"consumer\"\n\tdefault:\n\t\treturn \"unspecified\"\n\t}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/trace.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n\nimport (\n\t\"encoding/json\"\n)\n\nconst (\n\t// FlagsSampled is a bitmask with the sampled bit set. A SpanContext\n\t// with the sampling bit set means the span is sampled.\n\tFlagsSampled = TraceFlags(0x01)\n\n\terrInvalidHexID errorConst = \"trace-id and span-id can only contain [0-9a-f] characters, all lowercase\"\n\n\terrInvalidTraceIDLength errorConst = \"hex encoded trace-id must have length equals to 32\"\n\terrNilTraceID           errorConst = \"trace-id can't be all zero\"\n\n\terrInvalidSpanIDLength errorConst = \"hex encoded span-id must have length equals to 16\"\n\terrNilSpanID           errorConst = \"span-id can't be all zero\"\n)\n\ntype errorConst string\n\nfunc (e errorConst) Error() string {\n\treturn string(e)\n}\n\n// TraceID is a unique identity of a trace.\n// nolint:revive // revive complains about stutter of `trace.TraceID`.\ntype TraceID [16]byte\n\nvar (\n\tnilTraceID TraceID\n\t_          json.Marshaler = nilTraceID\n)\n\n// IsValid reports whether the trace TraceID is valid. A valid trace ID does\n// not consist of zeros only.\nfunc (t TraceID) IsValid() bool {\n\treturn t != nilTraceID\n}\n\n// MarshalJSON implements a custom marshal function to encode TraceID\n// as a hex string.\nfunc (t TraceID) MarshalJSON() ([]byte, error) {\n\tb := [32 + 2]byte{0: '\"', 33: '\"'}\n\th := t.hexBytes()\n\tcopy(b[1:], h[:])\n\treturn b[:], nil\n}\n\n// String returns the hex string representation form of a TraceID.\nfunc (t TraceID) String() string {\n\th := t.hexBytes()\n\treturn string(h[:])\n}\n\n// hexBytes returns the hex string representation form of a TraceID.\nfunc (t TraceID) hexBytes() [32]byte {\n\treturn [32]byte{\n\t\thexLU[t[0x0]>>4], hexLU[t[0x0]&0xf],\n\t\thexLU[t[0x1]>>4], hexLU[t[0x1]&0xf],\n\t\thexLU[t[0x2]>>4], hexLU[t[0x2]&0xf],\n\t\thexLU[t[0x3]>>4], hexLU[t[0x3]&0xf],\n\t\thexLU[t[0x4]>>4], hexLU[t[0x4]&0xf],\n\t\thexLU[t[0x5]>>4], hexLU[t[0x5]&0xf],\n\t\thexLU[t[0x6]>>4], hexLU[t[0x6]&0xf],\n\t\thexLU[t[0x7]>>4], hexLU[t[0x7]&0xf],\n\t\thexLU[t[0x8]>>4], hexLU[t[0x8]&0xf],\n\t\thexLU[t[0x9]>>4], hexLU[t[0x9]&0xf],\n\t\thexLU[t[0xa]>>4], hexLU[t[0xa]&0xf],\n\t\thexLU[t[0xb]>>4], hexLU[t[0xb]&0xf],\n\t\thexLU[t[0xc]>>4], hexLU[t[0xc]&0xf],\n\t\thexLU[t[0xd]>>4], hexLU[t[0xd]&0xf],\n\t\thexLU[t[0xe]>>4], hexLU[t[0xe]&0xf],\n\t\thexLU[t[0xf]>>4], hexLU[t[0xf]&0xf],\n\t}\n}\n\n// SpanID is a unique identity of a span in a trace.\ntype SpanID [8]byte\n\nvar (\n\tnilSpanID SpanID\n\t_         json.Marshaler = nilSpanID\n)\n\n// IsValid reports whether the SpanID is valid. A valid SpanID does not consist\n// of zeros only.\nfunc (s SpanID) IsValid() bool {\n\treturn s != nilSpanID\n}\n\n// MarshalJSON implements a custom marshal function to encode SpanID\n// as a hex string.\nfunc (s SpanID) MarshalJSON() ([]byte, error) {\n\tb := [16 + 2]byte{0: '\"', 17: '\"'}\n\th := s.hexBytes()\n\tcopy(b[1:], h[:])\n\treturn b[:], nil\n}\n\n// String returns the hex string representation form of a SpanID.\nfunc (s SpanID) String() string {\n\tb := s.hexBytes()\n\treturn string(b[:])\n}\n\nfunc (s SpanID) hexBytes() [16]byte {\n\treturn [16]byte{\n\t\thexLU[s[0]>>4], hexLU[s[0]&0xf],\n\t\thexLU[s[1]>>4], hexLU[s[1]&0xf],\n\t\thexLU[s[2]>>4], hexLU[s[2]&0xf],\n\t\thexLU[s[3]>>4], hexLU[s[3]&0xf],\n\t\thexLU[s[4]>>4], hexLU[s[4]&0xf],\n\t\thexLU[s[5]>>4], hexLU[s[5]&0xf],\n\t\thexLU[s[6]>>4], hexLU[s[6]&0xf],\n\t\thexLU[s[7]>>4], hexLU[s[7]&0xf],\n\t}\n}\n\n// TraceIDFromHex returns a TraceID from a hex string if it is compliant with\n// the W3C trace-context specification.  See more at\n// https://www.w3.org/TR/trace-context/#trace-id\n// nolint:revive // revive complains about stutter of `trace.TraceIDFromHex`.\nfunc TraceIDFromHex(h string) (TraceID, error) {\n\tif len(h) != 32 {\n\t\treturn [16]byte{}, errInvalidTraceIDLength\n\t}\n\tvar b [16]byte\n\tinvalidMark := byte(0)\n\tfor i := 0; i < len(h); i += 4 {\n\t\tb[i/2] = (hexRev[h[i]] << 4) | hexRev[h[i+1]]\n\t\tb[i/2+1] = (hexRev[h[i+2]] << 4) | hexRev[h[i+3]]\n\t\tinvalidMark |= hexRev[h[i]] | hexRev[h[i+1]] | hexRev[h[i+2]] | hexRev[h[i+3]]\n\t}\n\t// If the upper 4 bits of any byte are not zero, there was an invalid hex\n\t// character since invalid hex characters are 0xff in hexRev.\n\tif invalidMark&0xf0 != 0 {\n\t\treturn [16]byte{}, errInvalidHexID\n\t}\n\t// If we didn't set any bits, then h was all zeros.\n\tif invalidMark == 0 {\n\t\treturn [16]byte{}, errNilTraceID\n\t}\n\treturn b, nil\n}\n\n// SpanIDFromHex returns a SpanID from a hex string if it is compliant\n// with the w3c trace-context specification.\n// See more at https://www.w3.org/TR/trace-context/#parent-id\nfunc SpanIDFromHex(h string) (SpanID, error) {\n\tif len(h) != 16 {\n\t\treturn [8]byte{}, errInvalidSpanIDLength\n\t}\n\tvar b [8]byte\n\tinvalidMark := byte(0)\n\tfor i := 0; i < len(h); i += 4 {\n\t\tb[i/2] = (hexRev[h[i]] << 4) | hexRev[h[i+1]]\n\t\tb[i/2+1] = (hexRev[h[i+2]] << 4) | hexRev[h[i+3]]\n\t\tinvalidMark |= hexRev[h[i]] | hexRev[h[i+1]] | hexRev[h[i+2]] | hexRev[h[i+3]]\n\t}\n\t// If the upper 4 bits of any byte are not zero, there was an invalid hex\n\t// character since invalid hex characters are 0xff in hexRev.\n\tif invalidMark&0xf0 != 0 {\n\t\treturn [8]byte{}, errInvalidHexID\n\t}\n\t// If we didn't set any bits, then h was all zeros.\n\tif invalidMark == 0 {\n\t\treturn [8]byte{}, errNilSpanID\n\t}\n\treturn b, nil\n}\n\n// TraceFlags contains flags that can be set on a SpanContext.\ntype TraceFlags byte //nolint:revive // revive complains about stutter of `trace.TraceFlags`.\n\n// IsSampled reports whether the sampling bit is set in the TraceFlags.\nfunc (tf TraceFlags) IsSampled() bool {\n\treturn tf&FlagsSampled == FlagsSampled\n}\n\n// WithSampled sets the sampling bit in a new copy of the TraceFlags.\nfunc (tf TraceFlags) WithSampled(sampled bool) TraceFlags { // nolint:revive  // sampled is not a control flag.\n\tif sampled {\n\t\treturn tf | FlagsSampled\n\t}\n\n\treturn tf &^ FlagsSampled\n}\n\n// MarshalJSON implements a custom marshal function to encode TraceFlags\n// as a hex string.\nfunc (tf TraceFlags) MarshalJSON() ([]byte, error) {\n\tb := [2 + 2]byte{0: '\"', 3: '\"'}\n\th := tf.hexBytes()\n\tcopy(b[1:], h[:])\n\treturn b[:], nil\n}\n\n// String returns the hex string representation form of TraceFlags.\nfunc (tf TraceFlags) String() string {\n\th := tf.hexBytes()\n\treturn string(h[:])\n}\n\nfunc (tf TraceFlags) hexBytes() [2]byte {\n\treturn [2]byte{hexLU[tf>>4], hexLU[tf&0xf]}\n}\n\n// SpanContextConfig contains mutable fields usable for constructing\n// an immutable SpanContext.\ntype SpanContextConfig struct {\n\tTraceID    TraceID\n\tSpanID     SpanID\n\tTraceFlags TraceFlags\n\tTraceState TraceState\n\tRemote     bool\n}\n\n// NewSpanContext constructs a SpanContext using values from the provided\n// SpanContextConfig.\nfunc NewSpanContext(config SpanContextConfig) SpanContext {\n\treturn SpanContext{\n\t\ttraceID:    config.TraceID,\n\t\tspanID:     config.SpanID,\n\t\ttraceFlags: config.TraceFlags,\n\t\ttraceState: config.TraceState,\n\t\tremote:     config.Remote,\n\t}\n}\n\n// SpanContext contains identifying trace information about a Span.\ntype SpanContext struct {\n\ttraceID    TraceID\n\tspanID     SpanID\n\ttraceFlags TraceFlags\n\ttraceState TraceState\n\tremote     bool\n}\n\nvar _ json.Marshaler = SpanContext{}\n\n// IsValid reports whether the SpanContext is valid. A valid span context has a\n// valid TraceID and SpanID.\nfunc (sc SpanContext) IsValid() bool {\n\treturn sc.HasTraceID() && sc.HasSpanID()\n}\n\n// IsRemote reports whether the SpanContext represents a remotely-created Span.\nfunc (sc SpanContext) IsRemote() bool {\n\treturn sc.remote\n}\n\n// WithRemote returns a copy of sc with the Remote property set to remote.\nfunc (sc SpanContext) WithRemote(remote bool) SpanContext {\n\treturn SpanContext{\n\t\ttraceID:    sc.traceID,\n\t\tspanID:     sc.spanID,\n\t\ttraceFlags: sc.traceFlags,\n\t\ttraceState: sc.traceState,\n\t\tremote:     remote,\n\t}\n}\n\n// TraceID returns the TraceID from the SpanContext.\nfunc (sc SpanContext) TraceID() TraceID {\n\treturn sc.traceID\n}\n\n// HasTraceID reports whether the SpanContext has a valid TraceID.\nfunc (sc SpanContext) HasTraceID() bool {\n\treturn sc.traceID.IsValid()\n}\n\n// WithTraceID returns a new SpanContext with the TraceID replaced.\nfunc (sc SpanContext) WithTraceID(traceID TraceID) SpanContext {\n\treturn SpanContext{\n\t\ttraceID:    traceID,\n\t\tspanID:     sc.spanID,\n\t\ttraceFlags: sc.traceFlags,\n\t\ttraceState: sc.traceState,\n\t\tremote:     sc.remote,\n\t}\n}\n\n// SpanID returns the SpanID from the SpanContext.\nfunc (sc SpanContext) SpanID() SpanID {\n\treturn sc.spanID\n}\n\n// HasSpanID reports whether the SpanContext has a valid SpanID.\nfunc (sc SpanContext) HasSpanID() bool {\n\treturn sc.spanID.IsValid()\n}\n\n// WithSpanID returns a new SpanContext with the SpanID replaced.\nfunc (sc SpanContext) WithSpanID(spanID SpanID) SpanContext {\n\treturn SpanContext{\n\t\ttraceID:    sc.traceID,\n\t\tspanID:     spanID,\n\t\ttraceFlags: sc.traceFlags,\n\t\ttraceState: sc.traceState,\n\t\tremote:     sc.remote,\n\t}\n}\n\n// TraceFlags returns the flags from the SpanContext.\nfunc (sc SpanContext) TraceFlags() TraceFlags {\n\treturn sc.traceFlags\n}\n\n// IsSampled reports whether the sampling bit is set in the SpanContext's TraceFlags.\nfunc (sc SpanContext) IsSampled() bool {\n\treturn sc.traceFlags.IsSampled()\n}\n\n// WithTraceFlags returns a new SpanContext with the TraceFlags replaced.\nfunc (sc SpanContext) WithTraceFlags(flags TraceFlags) SpanContext {\n\treturn SpanContext{\n\t\ttraceID:    sc.traceID,\n\t\tspanID:     sc.spanID,\n\t\ttraceFlags: flags,\n\t\ttraceState: sc.traceState,\n\t\tremote:     sc.remote,\n\t}\n}\n\n// TraceState returns the TraceState from the SpanContext.\nfunc (sc SpanContext) TraceState() TraceState {\n\treturn sc.traceState\n}\n\n// WithTraceState returns a new SpanContext with the TraceState replaced.\nfunc (sc SpanContext) WithTraceState(state TraceState) SpanContext {\n\treturn SpanContext{\n\t\ttraceID:    sc.traceID,\n\t\tspanID:     sc.spanID,\n\t\ttraceFlags: sc.traceFlags,\n\t\ttraceState: state,\n\t\tremote:     sc.remote,\n\t}\n}\n\n// Equal reports whether two SpanContext values are equal.\nfunc (sc SpanContext) Equal(other SpanContext) bool {\n\treturn sc.traceID == other.traceID &&\n\t\tsc.spanID == other.spanID &&\n\t\tsc.traceFlags == other.traceFlags &&\n\t\tsc.traceState.String() == other.traceState.String() &&\n\t\tsc.remote == other.remote\n}\n\n// MarshalJSON implements a custom marshal function to encode a SpanContext.\nfunc (sc SpanContext) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(SpanContextConfig{\n\t\tTraceID:    sc.traceID,\n\t\tSpanID:     sc.spanID,\n\t\tTraceFlags: sc.traceFlags,\n\t\tTraceState: sc.traceState,\n\t\tRemote:     sc.remote,\n\t})\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/tracer.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/trace/embedded\"\n)\n\n// Tracer is the creator of Spans.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Tracer interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Tracer\n\n\t// Start creates a span and a context.Context containing the newly-created span.\n\t//\n\t// If the context.Context provided in `ctx` contains a Span then the newly-created\n\t// Span will be a child of that span, otherwise it will be a root span. This behavior\n\t// can be overridden by providing `WithNewRoot()` as a SpanOption, causing the\n\t// newly-created Span to be a root span even if `ctx` contains a Span.\n\t//\n\t// When creating a Span it is recommended to provide all known span attributes using\n\t// the `WithAttributes()` SpanOption as samplers will only have access to the\n\t// attributes provided when a Span is created.\n\t//\n\t// Any Span that is created MUST also be ended. This is the responsibility of the user.\n\t// Implementations of this API may leak memory or other resources if Spans are not ended.\n\tStart(ctx context.Context, spanName string, opts ...SpanStartOption) (context.Context, Span)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/tracestate.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n)\n\nconst (\n\tmaxListMembers = 32\n\n\tlistDelimiters  = \",\"\n\tmemberDelimiter = \"=\"\n\n\terrInvalidKey    errorConst = \"invalid tracestate key\"\n\terrInvalidValue  errorConst = \"invalid tracestate value\"\n\terrInvalidMember errorConst = \"invalid tracestate list-member\"\n\terrMemberNumber  errorConst = \"too many list-members in tracestate\"\n\terrDuplicate     errorConst = \"duplicate list-member in tracestate\"\n)\n\ntype member struct {\n\tKey   string\n\tValue string\n}\n\n// according to (chr = %x20 / (nblk-char = %x21-2B / %x2D-3C / %x3E-7E) )\n// means (chr = %x20-2B / %x2D-3C / %x3E-7E) .\nfunc checkValueChar(v byte) bool {\n\treturn v >= '\\x20' && v <= '\\x7e' && v != '\\x2c' && v != '\\x3d'\n}\n\n// according to (nblk-chr = %x21-2B / %x2D-3C / %x3E-7E) .\nfunc checkValueLast(v byte) bool {\n\treturn v >= '\\x21' && v <= '\\x7e' && v != '\\x2c' && v != '\\x3d'\n}\n\n// based on the W3C Trace Context specification\n//\n//\tvalue    = (0*255(chr)) nblk-chr\n//\tnblk-chr = %x21-2B / %x2D-3C / %x3E-7E\n//\tchr      = %x20 / nblk-chr\n//\n// see https://www.w3.org/TR/trace-context-1/#value\nfunc checkValue(val string) bool {\n\tn := len(val)\n\tif n == 0 || n > 256 {\n\t\treturn false\n\t}\n\tfor i := 0; i < n-1; i++ {\n\t\tif !checkValueChar(val[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn checkValueLast(val[n-1])\n}\n\nfunc checkKeyRemain(key string) bool {\n\t// ( lcalpha / DIGIT / \"_\" / \"-\"/ \"*\" / \"/\" )\n\tfor _, v := range key {\n\t\tif isAlphaNum(byte(v)) {\n\t\t\tcontinue\n\t\t}\n\t\tswitch v {\n\t\tcase '_', '-', '*', '/':\n\t\t\tcontinue\n\t\t}\n\t\treturn false\n\t}\n\treturn true\n}\n\n// according to\n//\n//\tsimple-key = lcalpha (0*255( lcalpha / DIGIT / \"_\" / \"-\"/ \"*\" / \"/\" ))\n//\tsystem-id = lcalpha (0*13( lcalpha / DIGIT / \"_\" / \"-\"/ \"*\" / \"/\" ))\n//\n// param n is remain part length, should be 255 in simple-key or 13 in system-id.\nfunc checkKeyPart(key string, n int) bool {\n\tif key == \"\" {\n\t\treturn false\n\t}\n\tfirst := key[0] // key's first char\n\tret := len(key[1:]) <= n\n\tret = ret && first >= 'a' && first <= 'z'\n\treturn ret && checkKeyRemain(key[1:])\n}\n\nfunc isAlphaNum(c byte) bool {\n\tif c >= 'a' && c <= 'z' {\n\t\treturn true\n\t}\n\treturn c >= '0' && c <= '9'\n}\n\n// according to\n//\n//\ttenant-id = ( lcalpha / DIGIT ) 0*240( lcalpha / DIGIT / \"_\" / \"-\"/ \"*\" / \"/\" )\n//\n// param n is remain part length, should be 240 exactly.\nfunc checkKeyTenant(key string, n int) bool {\n\tif key == \"\" {\n\t\treturn false\n\t}\n\treturn isAlphaNum(key[0]) && len(key[1:]) <= n && checkKeyRemain(key[1:])\n}\n\n// based on the W3C Trace Context specification\n//\n//\tkey = simple-key / multi-tenant-key\n//\tsimple-key = lcalpha (0*255( lcalpha / DIGIT / \"_\" / \"-\"/ \"*\" / \"/\" ))\n//\tmulti-tenant-key = tenant-id \"@\" system-id\n//\ttenant-id = ( lcalpha / DIGIT ) (0*240( lcalpha / DIGIT / \"_\" / \"-\"/ \"*\" / \"/\" ))\n//\tsystem-id = lcalpha (0*13( lcalpha / DIGIT / \"_\" / \"-\"/ \"*\" / \"/\" ))\n//\tlcalpha    = %x61-7A ; a-z\n//\n// see https://www.w3.org/TR/trace-context-1/#tracestate-header.\nfunc checkKey(key string) bool {\n\ttenant, system, ok := strings.Cut(key, \"@\")\n\tif !ok {\n\t\treturn checkKeyPart(key, 255)\n\t}\n\treturn checkKeyTenant(tenant, 240) && checkKeyPart(system, 13)\n}\n\nfunc newMember(key, value string) (member, error) {\n\tif !checkKey(key) {\n\t\treturn member{}, errInvalidKey\n\t}\n\tif !checkValue(value) {\n\t\treturn member{}, errInvalidValue\n\t}\n\treturn member{Key: key, Value: value}, nil\n}\n\nfunc parseMember(m string) (member, error) {\n\tkey, val, ok := strings.Cut(m, memberDelimiter)\n\tif !ok {\n\t\treturn member{}, fmt.Errorf(\"%w: %s\", errInvalidMember, m)\n\t}\n\tkey = strings.TrimLeft(key, \" \\t\")\n\tval = strings.TrimRight(val, \" \\t\")\n\tresult, e := newMember(key, val)\n\tif e != nil {\n\t\treturn member{}, fmt.Errorf(\"%w: %s\", errInvalidMember, m)\n\t}\n\treturn result, nil\n}\n\n// String encodes member into a string compliant with the W3C Trace Context\n// specification.\nfunc (m member) String() string {\n\treturn m.Key + \"=\" + m.Value\n}\n\n// TraceState provides additional vendor-specific trace identification\n// information across different distributed tracing systems. It represents an\n// immutable list consisting of key/value pairs, each pair is referred to as a\n// list-member.\n//\n// TraceState conforms to the W3C Trace Context specification\n// (https://www.w3.org/TR/trace-context-1). All operations that create or copy\n// a TraceState do so by validating all input and will only produce TraceState\n// that conform to the specification. Specifically, this means that all\n// list-member's key/value pairs are valid, no duplicate list-members exist,\n// and the maximum number of list-members (32) is not exceeded.\ntype TraceState struct { //nolint:revive // revive complains about stutter of `trace.TraceState`\n\t// list is the members in order.\n\tlist []member\n}\n\nvar _ json.Marshaler = TraceState{}\n\n// ParseTraceState attempts to decode a TraceState from the passed\n// string. It returns an error if the input is invalid according to the W3C\n// Trace Context specification.\nfunc ParseTraceState(ts string) (TraceState, error) {\n\tif ts == \"\" {\n\t\treturn TraceState{}, nil\n\t}\n\n\twrapErr := func(err error) error {\n\t\treturn fmt.Errorf(\"failed to parse tracestate: %w\", err)\n\t}\n\n\tvar members []member\n\tfound := make(map[string]struct{})\n\tfor ts != \"\" {\n\t\tvar memberStr string\n\t\tmemberStr, ts, _ = strings.Cut(ts, listDelimiters)\n\t\tif memberStr == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tm, err := parseMember(memberStr)\n\t\tif err != nil {\n\t\t\treturn TraceState{}, wrapErr(err)\n\t\t}\n\n\t\tif _, ok := found[m.Key]; ok {\n\t\t\treturn TraceState{}, wrapErr(errDuplicate)\n\t\t}\n\t\tfound[m.Key] = struct{}{}\n\n\t\tmembers = append(members, m)\n\t\tif n := len(members); n > maxListMembers {\n\t\t\treturn TraceState{}, wrapErr(errMemberNumber)\n\t\t}\n\t}\n\n\treturn TraceState{list: members}, nil\n}\n\n// MarshalJSON marshals the TraceState into JSON.\nfunc (ts TraceState) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(ts.String())\n}\n\n// String encodes the TraceState into a string compliant with the W3C\n// Trace Context specification. The returned string will be invalid if the\n// TraceState contains any invalid members.\nfunc (ts TraceState) String() string {\n\tif len(ts.list) == 0 {\n\t\treturn \"\"\n\t}\n\tvar n int\n\tn += len(ts.list)     // member delimiters: '='\n\tn += len(ts.list) - 1 // list delimiters: ','\n\tfor _, mem := range ts.list {\n\t\tn += len(mem.Key)\n\t\tn += len(mem.Value)\n\t}\n\n\tvar sb strings.Builder\n\tsb.Grow(n)\n\t_, _ = sb.WriteString(ts.list[0].Key)\n\t_ = sb.WriteByte('=')\n\t_, _ = sb.WriteString(ts.list[0].Value)\n\tfor i := 1; i < len(ts.list); i++ {\n\t\t_ = sb.WriteByte(listDelimiters[0])\n\t\t_, _ = sb.WriteString(ts.list[i].Key)\n\t\t_ = sb.WriteByte('=')\n\t\t_, _ = sb.WriteString(ts.list[i].Value)\n\t}\n\treturn sb.String()\n}\n\n// Get returns the value paired with key from the corresponding TraceState\n// list-member if it exists, otherwise an empty string is returned.\nfunc (ts TraceState) Get(key string) string {\n\tfor _, member := range ts.list {\n\t\tif member.Key == key {\n\t\t\treturn member.Value\n\t\t}\n\t}\n\n\treturn \"\"\n}\n\n// Walk walks all key value pairs in the TraceState by calling f\n// Iteration stops if f returns false.\nfunc (ts TraceState) Walk(f func(key, value string) bool) {\n\tfor _, m := range ts.list {\n\t\tif !f(m.Key, m.Value) {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n// Insert adds a new list-member defined by the key/value pair to the\n// TraceState. If a list-member already exists for the given key, that\n// list-member's value is updated. The new or updated list-member is always\n// moved to the beginning of the TraceState as specified by the W3C Trace\n// Context specification.\n//\n// If key or value are invalid according to the W3C Trace Context\n// specification an error is returned with the original TraceState.\n//\n// If adding a new list-member means the TraceState would have more members\n// then is allowed, the new list-member will be inserted and the right-most\n// list-member will be dropped in the returned TraceState.\nfunc (ts TraceState) Insert(key, value string) (TraceState, error) {\n\tm, err := newMember(key, value)\n\tif err != nil {\n\t\treturn ts, err\n\t}\n\tn := len(ts.list)\n\tfound := n\n\tfor i := range ts.list {\n\t\tif ts.list[i].Key == key {\n\t\t\tfound = i\n\t\t}\n\t}\n\tcTS := TraceState{}\n\tif found == n && n < maxListMembers {\n\t\tcTS.list = make([]member, n+1)\n\t} else {\n\t\tcTS.list = make([]member, n)\n\t}\n\tcTS.list[0] = m\n\t// When the number of members exceeds capacity, drop the \"right-most\".\n\tcopy(cTS.list[1:], ts.list[0:found])\n\tif found < n {\n\t\tcopy(cTS.list[1+found:], ts.list[found+1:])\n\t}\n\treturn cTS, nil\n}\n\n// Delete returns a copy of the TraceState with the list-member identified by\n// key removed.\nfunc (ts TraceState) Delete(key string) TraceState {\n\tmembers := make([]member, ts.Len())\n\tcopy(members, ts.list)\n\tfor i, member := range ts.list {\n\t\tif member.Key == key {\n\t\t\tmembers = append(members[:i], members[i+1:]...)\n\t\t\t// TraceState should contain no duplicate members.\n\t\t\tbreak\n\t\t}\n\t}\n\treturn TraceState{list: members}\n}\n\n// Len returns the number of list-members in the TraceState.\nfunc (ts TraceState) Len() int {\n\treturn len(ts.list)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage otel // import \"go.opentelemetry.io/otel\"\n\nimport (\n\t\"go.opentelemetry.io/otel/internal/global\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\n// Tracer creates a named tracer that implements Tracer interface.\n// If the name is an empty string then provider uses default name.\n//\n// This is short for GetTracerProvider().Tracer(name, opts...)\nfunc Tracer(name string, opts ...trace.TracerOption) trace.Tracer {\n\treturn GetTracerProvider().Tracer(name, opts...)\n}\n\n// GetTracerProvider returns the registered global trace provider.\n// If none is registered then an instance of NoopTracerProvider is returned.\n//\n// Use the trace provider to create a named tracer. E.g.\n//\n//\ttracer := otel.GetTracerProvider().Tracer(\"example.com/foo\")\n//\n// or\n//\n//\ttracer := otel.Tracer(\"example.com/foo\")\nfunc GetTracerProvider() trace.TracerProvider {\n\treturn global.TracerProvider()\n}\n\n// SetTracerProvider registers `tp` as the global trace provider.\nfunc SetTracerProvider(tp trace.TracerProvider) {\n\tglobal.SetTracerProvider(tp)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/verify_released_changelog.sh",
    "content": "#!/bin/bash\n\n# Copyright The OpenTelemetry Authors\n# SPDX-License-Identifier: Apache-2.0\n\nset -euo pipefail\n\nTARGET=\"${1:?Must provide target ref}\"\n\nFILE=\"CHANGELOG.md\"\nTEMP_DIR=$(mktemp -d)\necho \"Temp folder: $TEMP_DIR\"\n\n# Only the latest commit of the feature branch is available\n# automatically. To diff with the base branch, we need to\n# fetch that too (and we only need its latest commit).\ngit fetch origin \"${TARGET}\" --depth=1\n\n# Checkout the previous version on the base branch of the changelog to tmpfolder\ngit --work-tree=\"$TEMP_DIR\" checkout FETCH_HEAD $FILE\n\nPREVIOUS_FILE=\"$TEMP_DIR/$FILE\"\nCURRENT_FILE=\"$FILE\"\nPREVIOUS_LOCKED_FILE=\"$TEMP_DIR/previous_locked_section.md\"\nCURRENT_LOCKED_FILE=\"$TEMP_DIR/current_locked_section.md\"\n\n# Extract released sections from the previous version\nawk '/^<!-- Released section -->/ {flag=1} /^<!-- Released section ended -->/ {flag=0} flag' \"$PREVIOUS_FILE\" > \"$PREVIOUS_LOCKED_FILE\"\n\n# Extract released sections from the current version\nawk '/^<!-- Released section -->/ {flag=1} /^<!-- Released section ended -->/ {flag=0} flag' \"$CURRENT_FILE\" > \"$CURRENT_LOCKED_FILE\"\n\n# Compare the released sections\nif ! diff -q \"$PREVIOUS_LOCKED_FILE\" \"$CURRENT_LOCKED_FILE\"; then\n    echo \"Error: The released sections of the changelog file have been modified.\"\n    diff \"$PREVIOUS_LOCKED_FILE\" \"$CURRENT_LOCKED_FILE\"\n    rm -rf \"$TEMP_DIR\"\n    false\nfi\n\nrm -rf \"$TEMP_DIR\"\necho \"The released sections remain unchanged.\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/version.go",
    "content": "// Copyright The OpenTelemetry Authors\n// SPDX-License-Identifier: Apache-2.0\n\npackage otel // import \"go.opentelemetry.io/otel\"\n\n// Version is the current release version of OpenTelemetry in use.\nfunc Version() string {\n\treturn \"1.40.0\"\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/versions.yaml",
    "content": "# Copyright The OpenTelemetry Authors\n# SPDX-License-Identifier: Apache-2.0\n\nmodule-sets:\n  stable-v1:\n    version: v1.40.0\n    modules:\n      - go.opentelemetry.io/otel\n      - go.opentelemetry.io/otel/bridge/opencensus\n      - go.opentelemetry.io/otel/bridge/opencensus/test\n      - go.opentelemetry.io/otel/bridge/opentracing\n      - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc\n      - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp\n      - go.opentelemetry.io/otel/exporters/otlp/otlptrace\n      - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc\n      - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp\n      - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric\n      - go.opentelemetry.io/otel/exporters/stdout/stdouttrace\n      - go.opentelemetry.io/otel/exporters/zipkin\n      - go.opentelemetry.io/otel/metric\n      - go.opentelemetry.io/otel/sdk\n      - go.opentelemetry.io/otel/sdk/metric\n      - go.opentelemetry.io/otel/trace\n  experimental-metrics:\n    version: v0.62.0\n    modules:\n      - go.opentelemetry.io/otel/exporters/prometheus\n  experimental-logs:\n    version: v0.16.0\n    modules:\n      - go.opentelemetry.io/otel/log\n      - go.opentelemetry.io/otel/log/logtest\n      - go.opentelemetry.io/otel/sdk/log\n      - go.opentelemetry.io/otel/sdk/log/logtest\n      - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc\n      - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp\n      - go.opentelemetry.io/otel/exporters/stdout/stdoutlog\n  experimental-schema:\n    version: v0.0.14\n    modules:\n      - go.opentelemetry.io/otel/schema\nexcluded-modules:\n  - go.opentelemetry.io/otel/internal/tools\n  - go.opentelemetry.io/otel/trace/internal/telemetry/test\nmodules:\n  go.opentelemetry.io/otel/exporters/stdout/stdouttrace:\n    version-refs:\n      - ./internal/version.go\n  go.opentelemetry.io/otel/exporters/stdout/stdoutmetric:\n    version-refs:\n      - ./internal/version.go\n  go.opentelemetry.io/otel/exporters/prometheus:\n    version-refs:\n      - ./internal/version.go\n  go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc:\n    version-refs:\n      - ./internal/version.go\n  go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc:\n    version-refs:\n      - ./internal/version.go\n  go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp:\n    version-refs:\n      - ./internal/version.go\n  go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp:\n    version-refs:\n      - ./internal/version.go\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/proto/otlp/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service.pb.go",
    "content": "// Copyright 2019, OpenTelemetry Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.26.0\n// \tprotoc        v3.21.6\n// source: opentelemetry/proto/collector/trace/v1/trace_service.proto\n\npackage v1\n\nimport (\n\tv1 \"go.opentelemetry.io/proto/otlp/trace/v1\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\ntype ExportTraceServiceRequest struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// An array of ResourceSpans.\n\t// For data coming from a single resource this array will typically contain one\n\t// element. Intermediary nodes (such as OpenTelemetry Collector) that receive\n\t// data from multiple origins typically batch the data before forwarding further and\n\t// in that case this array will contain multiple elements.\n\tResourceSpans []*v1.ResourceSpans `protobuf:\"bytes,1,rep,name=resource_spans,json=resourceSpans,proto3\" json:\"resource_spans,omitempty\"`\n}\n\nfunc (x *ExportTraceServiceRequest) Reset() {\n\t*x = ExportTraceServiceRequest{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_opentelemetry_proto_collector_trace_v1_trace_service_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ExportTraceServiceRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ExportTraceServiceRequest) ProtoMessage() {}\n\nfunc (x *ExportTraceServiceRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_opentelemetry_proto_collector_trace_v1_trace_service_proto_msgTypes[0]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use ExportTraceServiceRequest.ProtoReflect.Descriptor instead.\nfunc (*ExportTraceServiceRequest) Descriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *ExportTraceServiceRequest) GetResourceSpans() []*v1.ResourceSpans {\n\tif x != nil {\n\t\treturn x.ResourceSpans\n\t}\n\treturn nil\n}\n\ntype ExportTraceServiceResponse struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// The details of a partially successful export request.\n\t//\n\t// If the request is only partially accepted\n\t// (i.e. when the server accepts only parts of the data and rejects the rest)\n\t// the server MUST initialize the `partial_success` field and MUST\n\t// set the `rejected_<signal>` with the number of items it rejected.\n\t//\n\t// Servers MAY also make use of the `partial_success` field to convey\n\t// warnings/suggestions to senders even when the request was fully accepted.\n\t// In such cases, the `rejected_<signal>` MUST have a value of `0` and\n\t// the `error_message` MUST be non-empty.\n\t//\n\t// A `partial_success` message with an empty value (rejected_<signal> = 0 and\n\t// `error_message` = \"\") is equivalent to it not being set/present. Senders\n\t// SHOULD interpret it the same way as in the full success case.\n\tPartialSuccess *ExportTracePartialSuccess `protobuf:\"bytes,1,opt,name=partial_success,json=partialSuccess,proto3\" json:\"partial_success,omitempty\"`\n}\n\nfunc (x *ExportTraceServiceResponse) Reset() {\n\t*x = ExportTraceServiceResponse{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_opentelemetry_proto_collector_trace_v1_trace_service_proto_msgTypes[1]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ExportTraceServiceResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ExportTraceServiceResponse) ProtoMessage() {}\n\nfunc (x *ExportTraceServiceResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_opentelemetry_proto_collector_trace_v1_trace_service_proto_msgTypes[1]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use ExportTraceServiceResponse.ProtoReflect.Descriptor instead.\nfunc (*ExportTraceServiceResponse) Descriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ExportTraceServiceResponse) GetPartialSuccess() *ExportTracePartialSuccess {\n\tif x != nil {\n\t\treturn x.PartialSuccess\n\t}\n\treturn nil\n}\n\ntype ExportTracePartialSuccess struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// The number of rejected spans.\n\t//\n\t// A `rejected_<signal>` field holding a `0` value indicates that the\n\t// request was fully accepted.\n\tRejectedSpans int64 `protobuf:\"varint,1,opt,name=rejected_spans,json=rejectedSpans,proto3\" json:\"rejected_spans,omitempty\"`\n\t// A developer-facing human-readable message in English. It should be used\n\t// either to explain why the server rejected parts of the data during a partial\n\t// success or to convey warnings/suggestions during a full success. The message\n\t// should offer guidance on how users can address such issues.\n\t//\n\t// error_message is an optional field. An error_message with an empty value\n\t// is equivalent to it not being set.\n\tErrorMessage string `protobuf:\"bytes,2,opt,name=error_message,json=errorMessage,proto3\" json:\"error_message,omitempty\"`\n}\n\nfunc (x *ExportTracePartialSuccess) Reset() {\n\t*x = ExportTracePartialSuccess{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_opentelemetry_proto_collector_trace_v1_trace_service_proto_msgTypes[2]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ExportTracePartialSuccess) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ExportTracePartialSuccess) ProtoMessage() {}\n\nfunc (x *ExportTracePartialSuccess) ProtoReflect() protoreflect.Message {\n\tmi := &file_opentelemetry_proto_collector_trace_v1_trace_service_proto_msgTypes[2]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use ExportTracePartialSuccess.ProtoReflect.Descriptor instead.\nfunc (*ExportTracePartialSuccess) Descriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *ExportTracePartialSuccess) GetRejectedSpans() int64 {\n\tif x != nil {\n\t\treturn x.RejectedSpans\n\t}\n\treturn 0\n}\n\nfunc (x *ExportTracePartialSuccess) GetErrorMessage() string {\n\tif x != nil {\n\t\treturn x.ErrorMessage\n\t}\n\treturn \"\"\n}\n\nvar File_opentelemetry_proto_collector_trace_v1_trace_service_proto protoreflect.FileDescriptor\n\nvar file_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDesc = []byte{\n\t0x0a, 0x3a, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2f,\n\t0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2f,\n\t0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x73,\n\t0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x26, 0x6f, 0x70,\n\t0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74,\n\t0x6f, 0x2e, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x74, 0x72, 0x61, 0x63,\n\t0x65, 0x2e, 0x76, 0x31, 0x1a, 0x28, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65,\n\t0x74, 0x72, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f,\n\t0x76, 0x31, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6f,\n\t0x0a, 0x19, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72,\n\t0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x52, 0x0a, 0x0e, 0x72,\n\t0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x18, 0x01, 0x20,\n\t0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65,\n\t0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e,\n\t0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73,\n\t0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x22,\n\t0x88, 0x01, 0x0a, 0x1a, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53,\n\t0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a,\n\t0x0a, 0x0f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73,\n\t0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65,\n\t0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f,\n\t0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31,\n\t0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x74,\n\t0x69, 0x61, 0x6c, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x0e, 0x70, 0x61, 0x72, 0x74,\n\t0x69, 0x61, 0x6c, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x67, 0x0a, 0x19, 0x45, 0x78,\n\t0x70, 0x6f, 0x72, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c,\n\t0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x6a, 0x65, 0x63,\n\t0x74, 0x65, 0x64, 0x5f, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,\n\t0x0d, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x12, 0x23,\n\t0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18,\n\t0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73,\n\t0x61, 0x67, 0x65, 0x32, 0xa2, 0x01, 0x0a, 0x0c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72,\n\t0x76, 0x69, 0x63, 0x65, 0x12, 0x91, 0x01, 0x0a, 0x06, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12,\n\t0x41, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e,\n\t0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e,\n\t0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x54,\n\t0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,\n\t0x73, 0x74, 0x1a, 0x42, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74,\n\t0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,\n\t0x6f, 0x72, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f,\n\t0x72, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65,\n\t0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x9c, 0x01, 0x0a, 0x29, 0x69, 0x6f, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72,\n\t0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x74, 0x72,\n\t0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x11, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72,\n\t0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x6f, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x69, 0x6f,\n\t0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6f, 0x74, 0x6c, 0x70, 0x2f, 0x63, 0x6f, 0x6c, 0x6c,\n\t0x65, 0x63, 0x74, 0x6f, 0x72, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, 0x76, 0x31, 0xaa, 0x02,\n\t0x26, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x50,\n\t0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x54,\n\t0x72, 0x61, 0x63, 0x65, 0x2e, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,\n}\n\nvar (\n\tfile_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDescOnce sync.Once\n\tfile_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDescData = file_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDesc\n)\n\nfunc file_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDescGZIP() []byte {\n\tfile_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDescOnce.Do(func() {\n\t\tfile_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDescData)\n\t})\n\treturn file_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDescData\n}\n\nvar file_opentelemetry_proto_collector_trace_v1_trace_service_proto_msgTypes = make([]protoimpl.MessageInfo, 3)\nvar file_opentelemetry_proto_collector_trace_v1_trace_service_proto_goTypes = []interface{}{\n\t(*ExportTraceServiceRequest)(nil),  // 0: opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest\n\t(*ExportTraceServiceResponse)(nil), // 1: opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse\n\t(*ExportTracePartialSuccess)(nil),  // 2: opentelemetry.proto.collector.trace.v1.ExportTracePartialSuccess\n\t(*v1.ResourceSpans)(nil),           // 3: opentelemetry.proto.trace.v1.ResourceSpans\n}\nvar file_opentelemetry_proto_collector_trace_v1_trace_service_proto_depIdxs = []int32{\n\t3, // 0: opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest.resource_spans:type_name -> opentelemetry.proto.trace.v1.ResourceSpans\n\t2, // 1: opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse.partial_success:type_name -> opentelemetry.proto.collector.trace.v1.ExportTracePartialSuccess\n\t0, // 2: opentelemetry.proto.collector.trace.v1.TraceService.Export:input_type -> opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest\n\t1, // 3: opentelemetry.proto.collector.trace.v1.TraceService.Export:output_type -> opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse\n\t3, // [3:4] is the sub-list for method output_type\n\t2, // [2:3] is the sub-list for method input_type\n\t2, // [2:2] is the sub-list for extension type_name\n\t2, // [2:2] is the sub-list for extension extendee\n\t0, // [0:2] is the sub-list for field type_name\n}\n\nfunc init() { file_opentelemetry_proto_collector_trace_v1_trace_service_proto_init() }\nfunc file_opentelemetry_proto_collector_trace_v1_trace_service_proto_init() {\n\tif File_opentelemetry_proto_collector_trace_v1_trace_service_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_opentelemetry_proto_collector_trace_v1_trace_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ExportTraceServiceRequest); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_opentelemetry_proto_collector_trace_v1_trace_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ExportTraceServiceResponse); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_opentelemetry_proto_collector_trace_v1_trace_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ExportTracePartialSuccess); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: file_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDesc,\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   3,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   1,\n\t\t},\n\t\tGoTypes:           file_opentelemetry_proto_collector_trace_v1_trace_service_proto_goTypes,\n\t\tDependencyIndexes: file_opentelemetry_proto_collector_trace_v1_trace_service_proto_depIdxs,\n\t\tMessageInfos:      file_opentelemetry_proto_collector_trace_v1_trace_service_proto_msgTypes,\n\t}.Build()\n\tFile_opentelemetry_proto_collector_trace_v1_trace_service_proto = out.File\n\tfile_opentelemetry_proto_collector_trace_v1_trace_service_proto_rawDesc = nil\n\tfile_opentelemetry_proto_collector_trace_v1_trace_service_proto_goTypes = nil\n\tfile_opentelemetry_proto_collector_trace_v1_trace_service_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service.pb.gw.go",
    "content": "// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.\n// source: opentelemetry/proto/collector/trace/v1/trace_service.proto\n\n/*\nPackage v1 is a reverse proxy.\n\nIt translates gRPC into RESTful JSON APIs.\n*/\npackage v1\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\n\t\"github.com/grpc-ecosystem/grpc-gateway/v2/runtime\"\n\t\"github.com/grpc-ecosystem/grpc-gateway/v2/utilities\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/grpclog\"\n\t\"google.golang.org/grpc/metadata\"\n\t\"google.golang.org/grpc/status\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\n// Suppress \"imported and not used\" errors\nvar _ codes.Code\nvar _ io.Reader\nvar _ status.Status\nvar _ = runtime.String\nvar _ = utilities.NewDoubleArray\nvar _ = metadata.Join\n\nfunc request_TraceService_Export_0(ctx context.Context, marshaler runtime.Marshaler, client TraceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {\n\tvar protoReq ExportTraceServiceRequest\n\tvar metadata runtime.ServerMetadata\n\n\tnewReader, berr := utilities.IOReaderFactory(req.Body)\n\tif berr != nil {\n\t\treturn nil, metadata, status.Errorf(codes.InvalidArgument, \"%v\", berr)\n\t}\n\tif err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {\n\t\treturn nil, metadata, status.Errorf(codes.InvalidArgument, \"%v\", err)\n\t}\n\n\tmsg, err := client.Export(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))\n\treturn msg, metadata, err\n\n}\n\nfunc local_request_TraceService_Export_0(ctx context.Context, marshaler runtime.Marshaler, server TraceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {\n\tvar protoReq ExportTraceServiceRequest\n\tvar metadata runtime.ServerMetadata\n\n\tnewReader, berr := utilities.IOReaderFactory(req.Body)\n\tif berr != nil {\n\t\treturn nil, metadata, status.Errorf(codes.InvalidArgument, \"%v\", berr)\n\t}\n\tif err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {\n\t\treturn nil, metadata, status.Errorf(codes.InvalidArgument, \"%v\", err)\n\t}\n\n\tmsg, err := server.Export(ctx, &protoReq)\n\treturn msg, metadata, err\n\n}\n\n// RegisterTraceServiceHandlerServer registers the http handlers for service TraceService to \"mux\".\n// UnaryRPC     :call TraceServiceServer directly.\n// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.\n// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterTraceServiceHandlerFromEndpoint instead.\nfunc RegisterTraceServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server TraceServiceServer) error {\n\n\tmux.Handle(\"POST\", pattern_TraceService_Export_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {\n\t\tctx, cancel := context.WithCancel(req.Context())\n\t\tdefer cancel()\n\t\tvar stream runtime.ServerTransportStream\n\t\tctx = grpc.NewContextWithServerTransportStream(ctx, &stream)\n\t\tinboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)\n\t\tvar err error\n\t\tvar annotatedContext context.Context\n\t\tannotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, \"/opentelemetry.proto.collector.trace.v1.TraceService/Export\", runtime.WithHTTPPathPattern(\"/v1/traces\"))\n\t\tif err != nil {\n\t\t\truntime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)\n\t\t\treturn\n\t\t}\n\t\tresp, md, err := local_request_TraceService_Export_0(annotatedContext, inboundMarshaler, server, req, pathParams)\n\t\tmd.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())\n\t\tannotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)\n\t\tif err != nil {\n\t\t\truntime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)\n\t\t\treturn\n\t\t}\n\n\t\tforward_TraceService_Export_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)\n\n\t})\n\n\treturn nil\n}\n\n// RegisterTraceServiceHandlerFromEndpoint is same as RegisterTraceServiceHandler but\n// automatically dials to \"endpoint\" and closes the connection when \"ctx\" gets done.\nfunc RegisterTraceServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {\n\tconn, err := grpc.Dial(endpoint, opts...)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer func() {\n\t\tif err != nil {\n\t\t\tif cerr := conn.Close(); cerr != nil {\n\t\t\t\tgrpclog.Infof(\"Failed to close conn to %s: %v\", endpoint, cerr)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tgo func() {\n\t\t\t<-ctx.Done()\n\t\t\tif cerr := conn.Close(); cerr != nil {\n\t\t\t\tgrpclog.Infof(\"Failed to close conn to %s: %v\", endpoint, cerr)\n\t\t\t}\n\t\t}()\n\t}()\n\n\treturn RegisterTraceServiceHandler(ctx, mux, conn)\n}\n\n// RegisterTraceServiceHandler registers the http handlers for service TraceService to \"mux\".\n// The handlers forward requests to the grpc endpoint over \"conn\".\nfunc RegisterTraceServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {\n\treturn RegisterTraceServiceHandlerClient(ctx, mux, NewTraceServiceClient(conn))\n}\n\n// RegisterTraceServiceHandlerClient registers the http handlers for service TraceService\n// to \"mux\". The handlers forward requests to the grpc endpoint over the given implementation of \"TraceServiceClient\".\n// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in \"TraceServiceClient\"\n// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in\n// \"TraceServiceClient\" to call the correct interceptors.\nfunc RegisterTraceServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client TraceServiceClient) error {\n\n\tmux.Handle(\"POST\", pattern_TraceService_Export_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {\n\t\tctx, cancel := context.WithCancel(req.Context())\n\t\tdefer cancel()\n\t\tinboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)\n\t\tvar err error\n\t\tvar annotatedContext context.Context\n\t\tannotatedContext, err = runtime.AnnotateContext(ctx, mux, req, \"/opentelemetry.proto.collector.trace.v1.TraceService/Export\", runtime.WithHTTPPathPattern(\"/v1/traces\"))\n\t\tif err != nil {\n\t\t\truntime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)\n\t\t\treturn\n\t\t}\n\t\tresp, md, err := request_TraceService_Export_0(annotatedContext, inboundMarshaler, client, req, pathParams)\n\t\tannotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)\n\t\tif err != nil {\n\t\t\truntime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)\n\t\t\treturn\n\t\t}\n\n\t\tforward_TraceService_Export_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)\n\n\t})\n\n\treturn nil\n}\n\nvar (\n\tpattern_TraceService_Export_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{\"v1\", \"traces\"}, \"\"))\n)\n\nvar (\n\tforward_TraceService_Export_0 = runtime.ForwardResponseMessage\n)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/proto/otlp/collector/trace/v1/trace_service_grpc.pb.go",
    "content": "// Code generated by protoc-gen-go-grpc. DO NOT EDIT.\n// versions:\n// - protoc-gen-go-grpc v1.1.0\n// - protoc             v3.21.6\n// source: opentelemetry/proto/collector/trace/v1/trace_service.proto\n\npackage v1\n\nimport (\n\tcontext \"context\"\n\tgrpc \"google.golang.org/grpc\"\n\tcodes \"google.golang.org/grpc/codes\"\n\tstatus \"google.golang.org/grpc/status\"\n)\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the grpc package it is being compiled against.\n// Requires gRPC-Go v1.32.0 or later.\nconst _ = grpc.SupportPackageIsVersion7\n\n// TraceServiceClient is the client API for TraceService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.\ntype TraceServiceClient interface {\n\t// For performance reasons, it is recommended to keep this RPC\n\t// alive for the entire life of the application.\n\tExport(ctx context.Context, in *ExportTraceServiceRequest, opts ...grpc.CallOption) (*ExportTraceServiceResponse, error)\n}\n\ntype traceServiceClient struct {\n\tcc grpc.ClientConnInterface\n}\n\nfunc NewTraceServiceClient(cc grpc.ClientConnInterface) TraceServiceClient {\n\treturn &traceServiceClient{cc}\n}\n\nfunc (c *traceServiceClient) Export(ctx context.Context, in *ExportTraceServiceRequest, opts ...grpc.CallOption) (*ExportTraceServiceResponse, error) {\n\tout := new(ExportTraceServiceResponse)\n\terr := c.cc.Invoke(ctx, \"/opentelemetry.proto.collector.trace.v1.TraceService/Export\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// TraceServiceServer is the server API for TraceService service.\n// All implementations must embed UnimplementedTraceServiceServer\n// for forward compatibility\ntype TraceServiceServer interface {\n\t// For performance reasons, it is recommended to keep this RPC\n\t// alive for the entire life of the application.\n\tExport(context.Context, *ExportTraceServiceRequest) (*ExportTraceServiceResponse, error)\n\tmustEmbedUnimplementedTraceServiceServer()\n}\n\n// UnimplementedTraceServiceServer must be embedded to have forward compatible implementations.\ntype UnimplementedTraceServiceServer struct {\n}\n\nfunc (UnimplementedTraceServiceServer) Export(context.Context, *ExportTraceServiceRequest) (*ExportTraceServiceResponse, error) {\n\treturn nil, status.Errorf(codes.Unimplemented, \"method Export not implemented\")\n}\nfunc (UnimplementedTraceServiceServer) mustEmbedUnimplementedTraceServiceServer() {}\n\n// UnsafeTraceServiceServer may be embedded to opt out of forward compatibility for this service.\n// Use of this interface is not recommended, as added methods to TraceServiceServer will\n// result in compilation errors.\ntype UnsafeTraceServiceServer interface {\n\tmustEmbedUnimplementedTraceServiceServer()\n}\n\nfunc RegisterTraceServiceServer(s grpc.ServiceRegistrar, srv TraceServiceServer) {\n\ts.RegisterService(&TraceService_ServiceDesc, srv)\n}\n\nfunc _TraceService_Export_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(ExportTraceServiceRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(TraceServiceServer).Export(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/opentelemetry.proto.collector.trace.v1.TraceService/Export\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(TraceServiceServer).Export(ctx, req.(*ExportTraceServiceRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\n// TraceService_ServiceDesc is the grpc.ServiceDesc for TraceService service.\n// It's only intended for direct use with grpc.RegisterService,\n// and not to be introspected or modified (even as a copy)\nvar TraceService_ServiceDesc = grpc.ServiceDesc{\n\tServiceName: \"opentelemetry.proto.collector.trace.v1.TraceService\",\n\tHandlerType: (*TraceServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"Export\",\n\t\t\tHandler:    _TraceService_Export_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"opentelemetry/proto/collector/trace/v1/trace_service.proto\",\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/proto/otlp/common/v1/common.pb.go",
    "content": "// Copyright 2019, OpenTelemetry Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.26.0\n// \tprotoc        v3.21.6\n// source: opentelemetry/proto/common/v1/common.proto\n\npackage v1\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\n// AnyValue is used to represent any type of attribute value. AnyValue may contain a\n// primitive value such as a string or integer or it may contain an arbitrary nested\n// object containing arrays, key-value lists and primitives.\ntype AnyValue struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// The value is one of the listed fields. It is valid for all values to be unspecified\n\t// in which case this AnyValue is considered to be \"empty\".\n\t//\n\t// Types that are assignable to Value:\n\t//\t*AnyValue_StringValue\n\t//\t*AnyValue_BoolValue\n\t//\t*AnyValue_IntValue\n\t//\t*AnyValue_DoubleValue\n\t//\t*AnyValue_ArrayValue\n\t//\t*AnyValue_KvlistValue\n\t//\t*AnyValue_BytesValue\n\tValue isAnyValue_Value `protobuf_oneof:\"value\"`\n}\n\nfunc (x *AnyValue) Reset() {\n\t*x = AnyValue{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_opentelemetry_proto_common_v1_common_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *AnyValue) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AnyValue) ProtoMessage() {}\n\nfunc (x *AnyValue) ProtoReflect() protoreflect.Message {\n\tmi := &file_opentelemetry_proto_common_v1_common_proto_msgTypes[0]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use AnyValue.ProtoReflect.Descriptor instead.\nfunc (*AnyValue) Descriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_common_v1_common_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (m *AnyValue) GetValue() isAnyValue_Value {\n\tif m != nil {\n\t\treturn m.Value\n\t}\n\treturn nil\n}\n\nfunc (x *AnyValue) GetStringValue() string {\n\tif x, ok := x.GetValue().(*AnyValue_StringValue); ok {\n\t\treturn x.StringValue\n\t}\n\treturn \"\"\n}\n\nfunc (x *AnyValue) GetBoolValue() bool {\n\tif x, ok := x.GetValue().(*AnyValue_BoolValue); ok {\n\t\treturn x.BoolValue\n\t}\n\treturn false\n}\n\nfunc (x *AnyValue) GetIntValue() int64 {\n\tif x, ok := x.GetValue().(*AnyValue_IntValue); ok {\n\t\treturn x.IntValue\n\t}\n\treturn 0\n}\n\nfunc (x *AnyValue) GetDoubleValue() float64 {\n\tif x, ok := x.GetValue().(*AnyValue_DoubleValue); ok {\n\t\treturn x.DoubleValue\n\t}\n\treturn 0\n}\n\nfunc (x *AnyValue) GetArrayValue() *ArrayValue {\n\tif x, ok := x.GetValue().(*AnyValue_ArrayValue); ok {\n\t\treturn x.ArrayValue\n\t}\n\treturn nil\n}\n\nfunc (x *AnyValue) GetKvlistValue() *KeyValueList {\n\tif x, ok := x.GetValue().(*AnyValue_KvlistValue); ok {\n\t\treturn x.KvlistValue\n\t}\n\treturn nil\n}\n\nfunc (x *AnyValue) GetBytesValue() []byte {\n\tif x, ok := x.GetValue().(*AnyValue_BytesValue); ok {\n\t\treturn x.BytesValue\n\t}\n\treturn nil\n}\n\ntype isAnyValue_Value interface {\n\tisAnyValue_Value()\n}\n\ntype AnyValue_StringValue struct {\n\tStringValue string `protobuf:\"bytes,1,opt,name=string_value,json=stringValue,proto3,oneof\"`\n}\n\ntype AnyValue_BoolValue struct {\n\tBoolValue bool `protobuf:\"varint,2,opt,name=bool_value,json=boolValue,proto3,oneof\"`\n}\n\ntype AnyValue_IntValue struct {\n\tIntValue int64 `protobuf:\"varint,3,opt,name=int_value,json=intValue,proto3,oneof\"`\n}\n\ntype AnyValue_DoubleValue struct {\n\tDoubleValue float64 `protobuf:\"fixed64,4,opt,name=double_value,json=doubleValue,proto3,oneof\"`\n}\n\ntype AnyValue_ArrayValue struct {\n\tArrayValue *ArrayValue `protobuf:\"bytes,5,opt,name=array_value,json=arrayValue,proto3,oneof\"`\n}\n\ntype AnyValue_KvlistValue struct {\n\tKvlistValue *KeyValueList `protobuf:\"bytes,6,opt,name=kvlist_value,json=kvlistValue,proto3,oneof\"`\n}\n\ntype AnyValue_BytesValue struct {\n\tBytesValue []byte `protobuf:\"bytes,7,opt,name=bytes_value,json=bytesValue,proto3,oneof\"`\n}\n\nfunc (*AnyValue_StringValue) isAnyValue_Value() {}\n\nfunc (*AnyValue_BoolValue) isAnyValue_Value() {}\n\nfunc (*AnyValue_IntValue) isAnyValue_Value() {}\n\nfunc (*AnyValue_DoubleValue) isAnyValue_Value() {}\n\nfunc (*AnyValue_ArrayValue) isAnyValue_Value() {}\n\nfunc (*AnyValue_KvlistValue) isAnyValue_Value() {}\n\nfunc (*AnyValue_BytesValue) isAnyValue_Value() {}\n\n// ArrayValue is a list of AnyValue messages. We need ArrayValue as a message\n// since oneof in AnyValue does not allow repeated fields.\ntype ArrayValue struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Array of values. The array may be empty (contain 0 elements).\n\tValues []*AnyValue `protobuf:\"bytes,1,rep,name=values,proto3\" json:\"values,omitempty\"`\n}\n\nfunc (x *ArrayValue) Reset() {\n\t*x = ArrayValue{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_opentelemetry_proto_common_v1_common_proto_msgTypes[1]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ArrayValue) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ArrayValue) ProtoMessage() {}\n\nfunc (x *ArrayValue) ProtoReflect() protoreflect.Message {\n\tmi := &file_opentelemetry_proto_common_v1_common_proto_msgTypes[1]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use ArrayValue.ProtoReflect.Descriptor instead.\nfunc (*ArrayValue) Descriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_common_v1_common_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ArrayValue) GetValues() []*AnyValue {\n\tif x != nil {\n\t\treturn x.Values\n\t}\n\treturn nil\n}\n\n// KeyValueList is a list of KeyValue messages. We need KeyValueList as a message\n// since `oneof` in AnyValue does not allow repeated fields. Everywhere else where we need\n// a list of KeyValue messages (e.g. in Span) we use `repeated KeyValue` directly to\n// avoid unnecessary extra wrapping (which slows down the protocol). The 2 approaches\n// are semantically equivalent.\ntype KeyValueList struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// A collection of key/value pairs of key-value pairs. The list may be empty (may\n\t// contain 0 elements).\n\t// The keys MUST be unique (it is not allowed to have more than one\n\t// value with the same key).\n\tValues []*KeyValue `protobuf:\"bytes,1,rep,name=values,proto3\" json:\"values,omitempty\"`\n}\n\nfunc (x *KeyValueList) Reset() {\n\t*x = KeyValueList{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_opentelemetry_proto_common_v1_common_proto_msgTypes[2]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *KeyValueList) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*KeyValueList) ProtoMessage() {}\n\nfunc (x *KeyValueList) ProtoReflect() protoreflect.Message {\n\tmi := &file_opentelemetry_proto_common_v1_common_proto_msgTypes[2]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use KeyValueList.ProtoReflect.Descriptor instead.\nfunc (*KeyValueList) Descriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_common_v1_common_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *KeyValueList) GetValues() []*KeyValue {\n\tif x != nil {\n\t\treturn x.Values\n\t}\n\treturn nil\n}\n\n// KeyValue is a key-value pair that is used to store Span attributes, Link\n// attributes, etc.\ntype KeyValue struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tKey   string    `protobuf:\"bytes,1,opt,name=key,proto3\" json:\"key,omitempty\"`\n\tValue *AnyValue `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *KeyValue) Reset() {\n\t*x = KeyValue{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_opentelemetry_proto_common_v1_common_proto_msgTypes[3]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *KeyValue) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*KeyValue) ProtoMessage() {}\n\nfunc (x *KeyValue) ProtoReflect() protoreflect.Message {\n\tmi := &file_opentelemetry_proto_common_v1_common_proto_msgTypes[3]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use KeyValue.ProtoReflect.Descriptor instead.\nfunc (*KeyValue) Descriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_common_v1_common_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *KeyValue) GetKey() string {\n\tif x != nil {\n\t\treturn x.Key\n\t}\n\treturn \"\"\n}\n\nfunc (x *KeyValue) GetValue() *AnyValue {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// InstrumentationScope is a message representing the instrumentation scope information\n// such as the fully qualified name and version.\ntype InstrumentationScope struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// An empty instrumentation scope name means the name is unknown.\n\tName    string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tVersion string `protobuf:\"bytes,2,opt,name=version,proto3\" json:\"version,omitempty\"`\n\t// Additional attributes that describe the scope. [Optional].\n\t// Attribute keys MUST be unique (it is not allowed to have more than one\n\t// attribute with the same key).\n\tAttributes             []*KeyValue `protobuf:\"bytes,3,rep,name=attributes,proto3\" json:\"attributes,omitempty\"`\n\tDroppedAttributesCount uint32      `protobuf:\"varint,4,opt,name=dropped_attributes_count,json=droppedAttributesCount,proto3\" json:\"dropped_attributes_count,omitempty\"`\n}\n\nfunc (x *InstrumentationScope) Reset() {\n\t*x = InstrumentationScope{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_opentelemetry_proto_common_v1_common_proto_msgTypes[4]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *InstrumentationScope) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*InstrumentationScope) ProtoMessage() {}\n\nfunc (x *InstrumentationScope) ProtoReflect() protoreflect.Message {\n\tmi := &file_opentelemetry_proto_common_v1_common_proto_msgTypes[4]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use InstrumentationScope.ProtoReflect.Descriptor instead.\nfunc (*InstrumentationScope) Descriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_common_v1_common_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *InstrumentationScope) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *InstrumentationScope) GetVersion() string {\n\tif x != nil {\n\t\treturn x.Version\n\t}\n\treturn \"\"\n}\n\nfunc (x *InstrumentationScope) GetAttributes() []*KeyValue {\n\tif x != nil {\n\t\treturn x.Attributes\n\t}\n\treturn nil\n}\n\nfunc (x *InstrumentationScope) GetDroppedAttributesCount() uint32 {\n\tif x != nil {\n\t\treturn x.DroppedAttributesCount\n\t}\n\treturn 0\n}\n\nvar File_opentelemetry_proto_common_v1_common_proto protoreflect.FileDescriptor\n\nvar file_opentelemetry_proto_common_v1_common_proto_rawDesc = []byte{\n\t0x0a, 0x2a, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2f,\n\t0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f,\n\t0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x6f, 0x70,\n\t0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74,\n\t0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x22, 0xe0, 0x02, 0x0a, 0x08,\n\t0x41, 0x6e, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69,\n\t0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00,\n\t0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a,\n\t0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,\n\t0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1d,\n\t0x0a, 0x09, 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,\n\t0x03, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a,\n\t0x0c, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20,\n\t0x01, 0x28, 0x01, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c,\n\t0x75, 0x65, 0x12, 0x4c, 0x0a, 0x0b, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75,\n\t0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65,\n\t0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f,\n\t0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x72, 0x72, 0x61, 0x79, 0x56, 0x61, 0x6c,\n\t0x75, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x72, 0x72, 0x61, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65,\n\t0x12, 0x50, 0x0a, 0x0c, 0x6b, 0x76, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65,\n\t0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c,\n\t0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d,\n\t0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4c,\n\t0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x6b, 0x76, 0x6c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c,\n\t0x75, 0x65, 0x12, 0x21, 0x0a, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x75,\n\t0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73,\n\t0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x4d,\n\t0x0a, 0x0a, 0x41, 0x72, 0x72, 0x61, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3f, 0x0a, 0x06,\n\t0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f,\n\t0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f,\n\t0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x79,\n\t0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x4f, 0x0a,\n\t0x0c, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3f, 0x0a,\n\t0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72,\n\t0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65,\n\t0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x5b,\n\t0x0a, 0x08, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,\n\t0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x05,\n\t0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74,\n\t0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x79, 0x56,\n\t0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xc7, 0x01, 0x0a, 0x14,\n\t0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53,\n\t0x63, 0x6f, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,\n\t0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73,\n\t0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,\n\t0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73,\n\t0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c,\n\t0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d,\n\t0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52,\n\t0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x64,\n\t0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,\n\t0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x16, 0x64,\n\t0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73,\n\t0x43, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x7b, 0x0a, 0x20, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,\n\t0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f,\n\t0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x28, 0x67, 0x6f, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x69, 0x6f, 0x2f, 0x70, 0x72,\n\t0x6f, 0x74, 0x6f, 0x2f, 0x6f, 0x74, 0x6c, 0x70, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f,\n\t0x76, 0x31, 0xaa, 0x02, 0x1d, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74,\n\t0x72, 0x79, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,\n\t0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,\n}\n\nvar (\n\tfile_opentelemetry_proto_common_v1_common_proto_rawDescOnce sync.Once\n\tfile_opentelemetry_proto_common_v1_common_proto_rawDescData = file_opentelemetry_proto_common_v1_common_proto_rawDesc\n)\n\nfunc file_opentelemetry_proto_common_v1_common_proto_rawDescGZIP() []byte {\n\tfile_opentelemetry_proto_common_v1_common_proto_rawDescOnce.Do(func() {\n\t\tfile_opentelemetry_proto_common_v1_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_opentelemetry_proto_common_v1_common_proto_rawDescData)\n\t})\n\treturn file_opentelemetry_proto_common_v1_common_proto_rawDescData\n}\n\nvar file_opentelemetry_proto_common_v1_common_proto_msgTypes = make([]protoimpl.MessageInfo, 5)\nvar file_opentelemetry_proto_common_v1_common_proto_goTypes = []interface{}{\n\t(*AnyValue)(nil),             // 0: opentelemetry.proto.common.v1.AnyValue\n\t(*ArrayValue)(nil),           // 1: opentelemetry.proto.common.v1.ArrayValue\n\t(*KeyValueList)(nil),         // 2: opentelemetry.proto.common.v1.KeyValueList\n\t(*KeyValue)(nil),             // 3: opentelemetry.proto.common.v1.KeyValue\n\t(*InstrumentationScope)(nil), // 4: opentelemetry.proto.common.v1.InstrumentationScope\n}\nvar file_opentelemetry_proto_common_v1_common_proto_depIdxs = []int32{\n\t1, // 0: opentelemetry.proto.common.v1.AnyValue.array_value:type_name -> opentelemetry.proto.common.v1.ArrayValue\n\t2, // 1: opentelemetry.proto.common.v1.AnyValue.kvlist_value:type_name -> opentelemetry.proto.common.v1.KeyValueList\n\t0, // 2: opentelemetry.proto.common.v1.ArrayValue.values:type_name -> opentelemetry.proto.common.v1.AnyValue\n\t3, // 3: opentelemetry.proto.common.v1.KeyValueList.values:type_name -> opentelemetry.proto.common.v1.KeyValue\n\t0, // 4: opentelemetry.proto.common.v1.KeyValue.value:type_name -> opentelemetry.proto.common.v1.AnyValue\n\t3, // 5: opentelemetry.proto.common.v1.InstrumentationScope.attributes:type_name -> opentelemetry.proto.common.v1.KeyValue\n\t6, // [6:6] is the sub-list for method output_type\n\t6, // [6:6] is the sub-list for method input_type\n\t6, // [6:6] is the sub-list for extension type_name\n\t6, // [6:6] is the sub-list for extension extendee\n\t0, // [0:6] is the sub-list for field type_name\n}\n\nfunc init() { file_opentelemetry_proto_common_v1_common_proto_init() }\nfunc file_opentelemetry_proto_common_v1_common_proto_init() {\n\tif File_opentelemetry_proto_common_v1_common_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_opentelemetry_proto_common_v1_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*AnyValue); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_opentelemetry_proto_common_v1_common_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ArrayValue); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_opentelemetry_proto_common_v1_common_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*KeyValueList); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_opentelemetry_proto_common_v1_common_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*KeyValue); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_opentelemetry_proto_common_v1_common_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*InstrumentationScope); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\tfile_opentelemetry_proto_common_v1_common_proto_msgTypes[0].OneofWrappers = []interface{}{\n\t\t(*AnyValue_StringValue)(nil),\n\t\t(*AnyValue_BoolValue)(nil),\n\t\t(*AnyValue_IntValue)(nil),\n\t\t(*AnyValue_DoubleValue)(nil),\n\t\t(*AnyValue_ArrayValue)(nil),\n\t\t(*AnyValue_KvlistValue)(nil),\n\t\t(*AnyValue_BytesValue)(nil),\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: file_opentelemetry_proto_common_v1_common_proto_rawDesc,\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   5,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_opentelemetry_proto_common_v1_common_proto_goTypes,\n\t\tDependencyIndexes: file_opentelemetry_proto_common_v1_common_proto_depIdxs,\n\t\tMessageInfos:      file_opentelemetry_proto_common_v1_common_proto_msgTypes,\n\t}.Build()\n\tFile_opentelemetry_proto_common_v1_common_proto = out.File\n\tfile_opentelemetry_proto_common_v1_common_proto_rawDesc = nil\n\tfile_opentelemetry_proto_common_v1_common_proto_goTypes = nil\n\tfile_opentelemetry_proto_common_v1_common_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/proto/otlp/resource/v1/resource.pb.go",
    "content": "// Copyright 2019, OpenTelemetry Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.26.0\n// \tprotoc        v3.21.6\n// source: opentelemetry/proto/resource/v1/resource.proto\n\npackage v1\n\nimport (\n\tv1 \"go.opentelemetry.io/proto/otlp/common/v1\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\n// Resource information.\ntype Resource struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Set of attributes that describe the resource.\n\t// Attribute keys MUST be unique (it is not allowed to have more than one\n\t// attribute with the same key).\n\tAttributes []*v1.KeyValue `protobuf:\"bytes,1,rep,name=attributes,proto3\" json:\"attributes,omitempty\"`\n\t// dropped_attributes_count is the number of dropped attributes. If the value is 0, then\n\t// no attributes were dropped.\n\tDroppedAttributesCount uint32 `protobuf:\"varint,2,opt,name=dropped_attributes_count,json=droppedAttributesCount,proto3\" json:\"dropped_attributes_count,omitempty\"`\n}\n\nfunc (x *Resource) Reset() {\n\t*x = Resource{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_opentelemetry_proto_resource_v1_resource_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Resource) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Resource) ProtoMessage() {}\n\nfunc (x *Resource) ProtoReflect() protoreflect.Message {\n\tmi := &file_opentelemetry_proto_resource_v1_resource_proto_msgTypes[0]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Resource.ProtoReflect.Descriptor instead.\nfunc (*Resource) Descriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_resource_v1_resource_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Resource) GetAttributes() []*v1.KeyValue {\n\tif x != nil {\n\t\treturn x.Attributes\n\t}\n\treturn nil\n}\n\nfunc (x *Resource) GetDroppedAttributesCount() uint32 {\n\tif x != nil {\n\t\treturn x.DroppedAttributesCount\n\t}\n\treturn 0\n}\n\nvar File_opentelemetry_proto_resource_v1_resource_proto protoreflect.FileDescriptor\n\nvar file_opentelemetry_proto_resource_v1_resource_proto_rawDesc = []byte{\n\t0x0a, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2f,\n\t0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x76,\n\t0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,\n\t0x12, 0x1f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e,\n\t0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x76,\n\t0x31, 0x1a, 0x2a, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79,\n\t0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31,\n\t0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8d, 0x01,\n\t0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x47, 0x0a, 0x0a, 0x61, 0x74,\n\t0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70,\n\t0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4b,\n\t0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,\n\t0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x61,\n\t0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18,\n\t0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x16, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x41, 0x74,\n\t0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x42, 0x83, 0x01,\n\t0x0a, 0x22, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74,\n\t0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,\n\t0x65, 0x2e, 0x76, 0x31, 0x42, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72,\n\t0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2a, 0x67, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65,\n\t0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x69, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,\n\t0x2f, 0x6f, 0x74, 0x6c, 0x70, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x76,\n\t0x31, 0xaa, 0x02, 0x1f, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72,\n\t0x79, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,\n\t0x2e, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,\n}\n\nvar (\n\tfile_opentelemetry_proto_resource_v1_resource_proto_rawDescOnce sync.Once\n\tfile_opentelemetry_proto_resource_v1_resource_proto_rawDescData = file_opentelemetry_proto_resource_v1_resource_proto_rawDesc\n)\n\nfunc file_opentelemetry_proto_resource_v1_resource_proto_rawDescGZIP() []byte {\n\tfile_opentelemetry_proto_resource_v1_resource_proto_rawDescOnce.Do(func() {\n\t\tfile_opentelemetry_proto_resource_v1_resource_proto_rawDescData = protoimpl.X.CompressGZIP(file_opentelemetry_proto_resource_v1_resource_proto_rawDescData)\n\t})\n\treturn file_opentelemetry_proto_resource_v1_resource_proto_rawDescData\n}\n\nvar file_opentelemetry_proto_resource_v1_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_opentelemetry_proto_resource_v1_resource_proto_goTypes = []interface{}{\n\t(*Resource)(nil),    // 0: opentelemetry.proto.resource.v1.Resource\n\t(*v1.KeyValue)(nil), // 1: opentelemetry.proto.common.v1.KeyValue\n}\nvar file_opentelemetry_proto_resource_v1_resource_proto_depIdxs = []int32{\n\t1, // 0: opentelemetry.proto.resource.v1.Resource.attributes:type_name -> opentelemetry.proto.common.v1.KeyValue\n\t1, // [1:1] is the sub-list for method output_type\n\t1, // [1:1] is the sub-list for method input_type\n\t1, // [1:1] is the sub-list for extension type_name\n\t1, // [1:1] is the sub-list for extension extendee\n\t0, // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_opentelemetry_proto_resource_v1_resource_proto_init() }\nfunc file_opentelemetry_proto_resource_v1_resource_proto_init() {\n\tif File_opentelemetry_proto_resource_v1_resource_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_opentelemetry_proto_resource_v1_resource_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Resource); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: file_opentelemetry_proto_resource_v1_resource_proto_rawDesc,\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_opentelemetry_proto_resource_v1_resource_proto_goTypes,\n\t\tDependencyIndexes: file_opentelemetry_proto_resource_v1_resource_proto_depIdxs,\n\t\tMessageInfos:      file_opentelemetry_proto_resource_v1_resource_proto_msgTypes,\n\t}.Build()\n\tFile_opentelemetry_proto_resource_v1_resource_proto = out.File\n\tfile_opentelemetry_proto_resource_v1_resource_proto_rawDesc = nil\n\tfile_opentelemetry_proto_resource_v1_resource_proto_goTypes = nil\n\tfile_opentelemetry_proto_resource_v1_resource_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/proto/otlp/trace/v1/trace.pb.go",
    "content": "// Copyright 2019, OpenTelemetry Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.26.0\n// \tprotoc        v3.21.6\n// source: opentelemetry/proto/trace/v1/trace.proto\n\npackage v1\n\nimport (\n\tv11 \"go.opentelemetry.io/proto/otlp/common/v1\"\n\tv1 \"go.opentelemetry.io/proto/otlp/resource/v1\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\n// SpanFlags represents constants used to interpret the\n// Span.flags field, which is protobuf 'fixed32' type and is to\n// be used as bit-fields. Each non-zero value defined in this enum is\n// a bit-mask.  To extract the bit-field, for example, use an\n// expression like:\n//\n//   (span.flags & SPAN_FLAGS_TRACE_FLAGS_MASK)\n//\n// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions.\n//\n// Note that Span flags were introduced in version 1.1 of the\n// OpenTelemetry protocol.  Older Span producers do not set this\n// field, consequently consumers should not rely on the absence of a\n// particular flag bit to indicate the presence of a particular feature.\ntype SpanFlags int32\n\nconst (\n\t// The zero value for the enum. Should not be used for comparisons.\n\t// Instead use bitwise \"and\" with the appropriate mask as shown above.\n\tSpanFlags_SPAN_FLAGS_DO_NOT_USE SpanFlags = 0\n\t// Bits 0-7 are used for trace flags.\n\tSpanFlags_SPAN_FLAGS_TRACE_FLAGS_MASK SpanFlags = 255\n\t// Bits 8 and 9 are used to indicate that the parent span or link span is remote.\n\t// Bit 8 (`HAS_IS_REMOTE`) indicates whether the value is known.\n\t// Bit 9 (`IS_REMOTE`) indicates whether the span or link is remote.\n\tSpanFlags_SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK SpanFlags = 256\n\tSpanFlags_SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK     SpanFlags = 512\n)\n\n// Enum value maps for SpanFlags.\nvar (\n\tSpanFlags_name = map[int32]string{\n\t\t0:   \"SPAN_FLAGS_DO_NOT_USE\",\n\t\t255: \"SPAN_FLAGS_TRACE_FLAGS_MASK\",\n\t\t256: \"SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK\",\n\t\t512: \"SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK\",\n\t}\n\tSpanFlags_value = map[string]int32{\n\t\t\"SPAN_FLAGS_DO_NOT_USE\":                 0,\n\t\t\"SPAN_FLAGS_TRACE_FLAGS_MASK\":           255,\n\t\t\"SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK\": 256,\n\t\t\"SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK\":     512,\n\t}\n)\n\nfunc (x SpanFlags) Enum() *SpanFlags {\n\tp := new(SpanFlags)\n\t*p = x\n\treturn p\n}\n\nfunc (x SpanFlags) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (SpanFlags) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_opentelemetry_proto_trace_v1_trace_proto_enumTypes[0].Descriptor()\n}\n\nfunc (SpanFlags) Type() protoreflect.EnumType {\n\treturn &file_opentelemetry_proto_trace_v1_trace_proto_enumTypes[0]\n}\n\nfunc (x SpanFlags) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use SpanFlags.Descriptor instead.\nfunc (SpanFlags) EnumDescriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{0}\n}\n\n// SpanKind is the type of span. Can be used to specify additional relationships between spans\n// in addition to a parent/child relationship.\ntype Span_SpanKind int32\n\nconst (\n\t// Unspecified. Do NOT use as default.\n\t// Implementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED.\n\tSpan_SPAN_KIND_UNSPECIFIED Span_SpanKind = 0\n\t// Indicates that the span represents an internal operation within an application,\n\t// as opposed to an operation happening at the boundaries. Default value.\n\tSpan_SPAN_KIND_INTERNAL Span_SpanKind = 1\n\t// Indicates that the span covers server-side handling of an RPC or other\n\t// remote network request.\n\tSpan_SPAN_KIND_SERVER Span_SpanKind = 2\n\t// Indicates that the span describes a request to some remote service.\n\tSpan_SPAN_KIND_CLIENT Span_SpanKind = 3\n\t// Indicates that the span describes a producer sending a message to a broker.\n\t// Unlike CLIENT and SERVER, there is often no direct critical path latency relationship\n\t// between producer and consumer spans. A PRODUCER span ends when the message was accepted\n\t// by the broker while the logical processing of the message might span a much longer time.\n\tSpan_SPAN_KIND_PRODUCER Span_SpanKind = 4\n\t// Indicates that the span describes consumer receiving a message from a broker.\n\t// Like the PRODUCER kind, there is often no direct critical path latency relationship\n\t// between producer and consumer spans.\n\tSpan_SPAN_KIND_CONSUMER Span_SpanKind = 5\n)\n\n// Enum value maps for Span_SpanKind.\nvar (\n\tSpan_SpanKind_name = map[int32]string{\n\t\t0: \"SPAN_KIND_UNSPECIFIED\",\n\t\t1: \"SPAN_KIND_INTERNAL\",\n\t\t2: \"SPAN_KIND_SERVER\",\n\t\t3: \"SPAN_KIND_CLIENT\",\n\t\t4: \"SPAN_KIND_PRODUCER\",\n\t\t5: \"SPAN_KIND_CONSUMER\",\n\t}\n\tSpan_SpanKind_value = map[string]int32{\n\t\t\"SPAN_KIND_UNSPECIFIED\": 0,\n\t\t\"SPAN_KIND_INTERNAL\":    1,\n\t\t\"SPAN_KIND_SERVER\":      2,\n\t\t\"SPAN_KIND_CLIENT\":      3,\n\t\t\"SPAN_KIND_PRODUCER\":    4,\n\t\t\"SPAN_KIND_CONSUMER\":    5,\n\t}\n)\n\nfunc (x Span_SpanKind) Enum() *Span_SpanKind {\n\tp := new(Span_SpanKind)\n\t*p = x\n\treturn p\n}\n\nfunc (x Span_SpanKind) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (Span_SpanKind) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_opentelemetry_proto_trace_v1_trace_proto_enumTypes[1].Descriptor()\n}\n\nfunc (Span_SpanKind) Type() protoreflect.EnumType {\n\treturn &file_opentelemetry_proto_trace_v1_trace_proto_enumTypes[1]\n}\n\nfunc (x Span_SpanKind) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use Span_SpanKind.Descriptor instead.\nfunc (Span_SpanKind) EnumDescriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{3, 0}\n}\n\n// For the semantics of status codes see\n// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status\ntype Status_StatusCode int32\n\nconst (\n\t// The default status.\n\tStatus_STATUS_CODE_UNSET Status_StatusCode = 0\n\t// The Span has been validated by an Application developer or Operator to\n\t// have completed successfully.\n\tStatus_STATUS_CODE_OK Status_StatusCode = 1\n\t// The Span contains an error.\n\tStatus_STATUS_CODE_ERROR Status_StatusCode = 2\n)\n\n// Enum value maps for Status_StatusCode.\nvar (\n\tStatus_StatusCode_name = map[int32]string{\n\t\t0: \"STATUS_CODE_UNSET\",\n\t\t1: \"STATUS_CODE_OK\",\n\t\t2: \"STATUS_CODE_ERROR\",\n\t}\n\tStatus_StatusCode_value = map[string]int32{\n\t\t\"STATUS_CODE_UNSET\": 0,\n\t\t\"STATUS_CODE_OK\":    1,\n\t\t\"STATUS_CODE_ERROR\": 2,\n\t}\n)\n\nfunc (x Status_StatusCode) Enum() *Status_StatusCode {\n\tp := new(Status_StatusCode)\n\t*p = x\n\treturn p\n}\n\nfunc (x Status_StatusCode) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (Status_StatusCode) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_opentelemetry_proto_trace_v1_trace_proto_enumTypes[2].Descriptor()\n}\n\nfunc (Status_StatusCode) Type() protoreflect.EnumType {\n\treturn &file_opentelemetry_proto_trace_v1_trace_proto_enumTypes[2]\n}\n\nfunc (x Status_StatusCode) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use Status_StatusCode.Descriptor instead.\nfunc (Status_StatusCode) EnumDescriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{4, 0}\n}\n\n// TracesData represents the traces data that can be stored in a persistent storage,\n// OR can be embedded by other protocols that transfer OTLP traces data but do\n// not implement the OTLP protocol.\n//\n// The main difference between this message and collector protocol is that\n// in this message there will not be any \"control\" or \"metadata\" specific to\n// OTLP protocol.\n//\n// When new fields are added into this message, the OTLP request MUST be updated\n// as well.\ntype TracesData struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// An array of ResourceSpans.\n\t// For data coming from a single resource this array will typically contain\n\t// one element. Intermediary nodes that receive data from multiple origins\n\t// typically batch the data before forwarding further and in that case this\n\t// array will contain multiple elements.\n\tResourceSpans []*ResourceSpans `protobuf:\"bytes,1,rep,name=resource_spans,json=resourceSpans,proto3\" json:\"resource_spans,omitempty\"`\n}\n\nfunc (x *TracesData) Reset() {\n\t*x = TracesData{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *TracesData) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*TracesData) ProtoMessage() {}\n\nfunc (x *TracesData) ProtoReflect() protoreflect.Message {\n\tmi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[0]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use TracesData.ProtoReflect.Descriptor instead.\nfunc (*TracesData) Descriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *TracesData) GetResourceSpans() []*ResourceSpans {\n\tif x != nil {\n\t\treturn x.ResourceSpans\n\t}\n\treturn nil\n}\n\n// A collection of ScopeSpans from a Resource.\ntype ResourceSpans struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// The resource for the spans in this message.\n\t// If this field is not set then no resource info is known.\n\tResource *v1.Resource `protobuf:\"bytes,1,opt,name=resource,proto3\" json:\"resource,omitempty\"`\n\t// A list of ScopeSpans that originate from a resource.\n\tScopeSpans []*ScopeSpans `protobuf:\"bytes,2,rep,name=scope_spans,json=scopeSpans,proto3\" json:\"scope_spans,omitempty\"`\n\t// The Schema URL, if known. This is the identifier of the Schema that the resource data\n\t// is recorded in. To learn more about Schema URL see\n\t// https://opentelemetry.io/docs/specs/otel/schemas/#schema-url\n\t// This schema_url applies to the data in the \"resource\" field. It does not apply\n\t// to the data in the \"scope_spans\" field which have their own schema_url field.\n\tSchemaUrl string `protobuf:\"bytes,3,opt,name=schema_url,json=schemaUrl,proto3\" json:\"schema_url,omitempty\"`\n}\n\nfunc (x *ResourceSpans) Reset() {\n\t*x = ResourceSpans{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[1]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ResourceSpans) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ResourceSpans) ProtoMessage() {}\n\nfunc (x *ResourceSpans) ProtoReflect() protoreflect.Message {\n\tmi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[1]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use ResourceSpans.ProtoReflect.Descriptor instead.\nfunc (*ResourceSpans) Descriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ResourceSpans) GetResource() *v1.Resource {\n\tif x != nil {\n\t\treturn x.Resource\n\t}\n\treturn nil\n}\n\nfunc (x *ResourceSpans) GetScopeSpans() []*ScopeSpans {\n\tif x != nil {\n\t\treturn x.ScopeSpans\n\t}\n\treturn nil\n}\n\nfunc (x *ResourceSpans) GetSchemaUrl() string {\n\tif x != nil {\n\t\treturn x.SchemaUrl\n\t}\n\treturn \"\"\n}\n\n// A collection of Spans produced by an InstrumentationScope.\ntype ScopeSpans struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// The instrumentation scope information for the spans in this message.\n\t// Semantically when InstrumentationScope isn't set, it is equivalent with\n\t// an empty instrumentation scope name (unknown).\n\tScope *v11.InstrumentationScope `protobuf:\"bytes,1,opt,name=scope,proto3\" json:\"scope,omitempty\"`\n\t// A list of Spans that originate from an instrumentation scope.\n\tSpans []*Span `protobuf:\"bytes,2,rep,name=spans,proto3\" json:\"spans,omitempty\"`\n\t// The Schema URL, if known. This is the identifier of the Schema that the span data\n\t// is recorded in. To learn more about Schema URL see\n\t// https://opentelemetry.io/docs/specs/otel/schemas/#schema-url\n\t// This schema_url applies to all spans and span events in the \"spans\" field.\n\tSchemaUrl string `protobuf:\"bytes,3,opt,name=schema_url,json=schemaUrl,proto3\" json:\"schema_url,omitempty\"`\n}\n\nfunc (x *ScopeSpans) Reset() {\n\t*x = ScopeSpans{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[2]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ScopeSpans) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ScopeSpans) ProtoMessage() {}\n\nfunc (x *ScopeSpans) ProtoReflect() protoreflect.Message {\n\tmi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[2]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use ScopeSpans.ProtoReflect.Descriptor instead.\nfunc (*ScopeSpans) Descriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *ScopeSpans) GetScope() *v11.InstrumentationScope {\n\tif x != nil {\n\t\treturn x.Scope\n\t}\n\treturn nil\n}\n\nfunc (x *ScopeSpans) GetSpans() []*Span {\n\tif x != nil {\n\t\treturn x.Spans\n\t}\n\treturn nil\n}\n\nfunc (x *ScopeSpans) GetSchemaUrl() string {\n\tif x != nil {\n\t\treturn x.SchemaUrl\n\t}\n\treturn \"\"\n}\n\n// A Span represents a single operation performed by a single component of the system.\n//\n// The next available field id is 17.\ntype Span struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// A unique identifier for a trace. All spans from the same trace share\n\t// the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes OR\n\t// of length other than 16 bytes is considered invalid (empty string in OTLP/JSON\n\t// is zero-length and thus is also invalid).\n\t//\n\t// This field is required.\n\tTraceId []byte `protobuf:\"bytes,1,opt,name=trace_id,json=traceId,proto3\" json:\"trace_id,omitempty\"`\n\t// A unique identifier for a span within a trace, assigned when the span\n\t// is created. The ID is an 8-byte array. An ID with all zeroes OR of length\n\t// other than 8 bytes is considered invalid (empty string in OTLP/JSON\n\t// is zero-length and thus is also invalid).\n\t//\n\t// This field is required.\n\tSpanId []byte `protobuf:\"bytes,2,opt,name=span_id,json=spanId,proto3\" json:\"span_id,omitempty\"`\n\t// trace_state conveys information about request position in multiple distributed tracing graphs.\n\t// It is a trace_state in w3c-trace-context format: https://www.w3.org/TR/trace-context/#tracestate-header\n\t// See also https://github.com/w3c/distributed-tracing for more details about this field.\n\tTraceState string `protobuf:\"bytes,3,opt,name=trace_state,json=traceState,proto3\" json:\"trace_state,omitempty\"`\n\t// The `span_id` of this span's parent span. If this is a root span, then this\n\t// field must be empty. The ID is an 8-byte array.\n\tParentSpanId []byte `protobuf:\"bytes,4,opt,name=parent_span_id,json=parentSpanId,proto3\" json:\"parent_span_id,omitempty\"`\n\t// Flags, a bit field.\n\t//\n\t// Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C Trace\n\t// Context specification. To read the 8-bit W3C trace flag, use\n\t// `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`.\n\t//\n\t// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions.\n\t//\n\t// Bits 8 and 9 represent the 3 states of whether a span's parent\n\t// is remote. The states are (unknown, is not remote, is remote).\n\t// To read whether the value is known, use `(flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`.\n\t// To read whether the span is remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`.\n\t//\n\t// When creating span messages, if the message is logically forwarded from another source\n\t// with an equivalent flags fields (i.e., usually another OTLP span message), the field SHOULD\n\t// be copied as-is. If creating from a source that does not have an equivalent flags field\n\t// (such as a runtime representation of an OpenTelemetry span), the high 22 bits MUST\n\t// be set to zero.\n\t// Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero.\n\t//\n\t// [Optional].\n\tFlags uint32 `protobuf:\"fixed32,16,opt,name=flags,proto3\" json:\"flags,omitempty\"`\n\t// A description of the span's operation.\n\t//\n\t// For example, the name can be a qualified method name or a file name\n\t// and a line number where the operation is called. A best practice is to use\n\t// the same display name at the same call point in an application.\n\t// This makes it easier to correlate spans in different traces.\n\t//\n\t// This field is semantically required to be set to non-empty string.\n\t// Empty value is equivalent to an unknown span name.\n\t//\n\t// This field is required.\n\tName string `protobuf:\"bytes,5,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Distinguishes between spans generated in a particular context. For example,\n\t// two spans with the same name may be distinguished using `CLIENT` (caller)\n\t// and `SERVER` (callee) to identify queueing latency associated with the span.\n\tKind Span_SpanKind `protobuf:\"varint,6,opt,name=kind,proto3,enum=opentelemetry.proto.trace.v1.Span_SpanKind\" json:\"kind,omitempty\"`\n\t// start_time_unix_nano is the start time of the span. On the client side, this is the time\n\t// kept by the local machine where the span execution starts. On the server side, this\n\t// is the time when the server's application handler starts running.\n\t// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970.\n\t//\n\t// This field is semantically required and it is expected that end_time >= start_time.\n\tStartTimeUnixNano uint64 `protobuf:\"fixed64,7,opt,name=start_time_unix_nano,json=startTimeUnixNano,proto3\" json:\"start_time_unix_nano,omitempty\"`\n\t// end_time_unix_nano is the end time of the span. On the client side, this is the time\n\t// kept by the local machine where the span execution ends. On the server side, this\n\t// is the time when the server application handler stops running.\n\t// Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970.\n\t//\n\t// This field is semantically required and it is expected that end_time >= start_time.\n\tEndTimeUnixNano uint64 `protobuf:\"fixed64,8,opt,name=end_time_unix_nano,json=endTimeUnixNano,proto3\" json:\"end_time_unix_nano,omitempty\"`\n\t// attributes is a collection of key/value pairs. Note, global attributes\n\t// like server name can be set using the resource API. Examples of attributes:\n\t//\n\t//     \"/http/user_agent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36\"\n\t//     \"/http/server_latency\": 300\n\t//     \"example.com/myattribute\": true\n\t//     \"example.com/score\": 10.239\n\t//\n\t// The OpenTelemetry API specification further restricts the allowed value types:\n\t// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute\n\t// Attribute keys MUST be unique (it is not allowed to have more than one\n\t// attribute with the same key).\n\tAttributes []*v11.KeyValue `protobuf:\"bytes,9,rep,name=attributes,proto3\" json:\"attributes,omitempty\"`\n\t// dropped_attributes_count is the number of attributes that were discarded. Attributes\n\t// can be discarded because their keys are too long or because there are too many\n\t// attributes. If this value is 0, then no attributes were dropped.\n\tDroppedAttributesCount uint32 `protobuf:\"varint,10,opt,name=dropped_attributes_count,json=droppedAttributesCount,proto3\" json:\"dropped_attributes_count,omitempty\"`\n\t// events is a collection of Event items.\n\tEvents []*Span_Event `protobuf:\"bytes,11,rep,name=events,proto3\" json:\"events,omitempty\"`\n\t// dropped_events_count is the number of dropped events. If the value is 0, then no\n\t// events were dropped.\n\tDroppedEventsCount uint32 `protobuf:\"varint,12,opt,name=dropped_events_count,json=droppedEventsCount,proto3\" json:\"dropped_events_count,omitempty\"`\n\t// links is a collection of Links, which are references from this span to a span\n\t// in the same or different trace.\n\tLinks []*Span_Link `protobuf:\"bytes,13,rep,name=links,proto3\" json:\"links,omitempty\"`\n\t// dropped_links_count is the number of dropped links after the maximum size was\n\t// enforced. If this value is 0, then no links were dropped.\n\tDroppedLinksCount uint32 `protobuf:\"varint,14,opt,name=dropped_links_count,json=droppedLinksCount,proto3\" json:\"dropped_links_count,omitempty\"`\n\t// An optional final status for this span. Semantically when Status isn't set, it means\n\t// span's status code is unset, i.e. assume STATUS_CODE_UNSET (code = 0).\n\tStatus *Status `protobuf:\"bytes,15,opt,name=status,proto3\" json:\"status,omitempty\"`\n}\n\nfunc (x *Span) Reset() {\n\t*x = Span{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[3]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Span) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Span) ProtoMessage() {}\n\nfunc (x *Span) ProtoReflect() protoreflect.Message {\n\tmi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[3]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Span.ProtoReflect.Descriptor instead.\nfunc (*Span) Descriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *Span) GetTraceId() []byte {\n\tif x != nil {\n\t\treturn x.TraceId\n\t}\n\treturn nil\n}\n\nfunc (x *Span) GetSpanId() []byte {\n\tif x != nil {\n\t\treturn x.SpanId\n\t}\n\treturn nil\n}\n\nfunc (x *Span) GetTraceState() string {\n\tif x != nil {\n\t\treturn x.TraceState\n\t}\n\treturn \"\"\n}\n\nfunc (x *Span) GetParentSpanId() []byte {\n\tif x != nil {\n\t\treturn x.ParentSpanId\n\t}\n\treturn nil\n}\n\nfunc (x *Span) GetFlags() uint32 {\n\tif x != nil {\n\t\treturn x.Flags\n\t}\n\treturn 0\n}\n\nfunc (x *Span) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *Span) GetKind() Span_SpanKind {\n\tif x != nil {\n\t\treturn x.Kind\n\t}\n\treturn Span_SPAN_KIND_UNSPECIFIED\n}\n\nfunc (x *Span) GetStartTimeUnixNano() uint64 {\n\tif x != nil {\n\t\treturn x.StartTimeUnixNano\n\t}\n\treturn 0\n}\n\nfunc (x *Span) GetEndTimeUnixNano() uint64 {\n\tif x != nil {\n\t\treturn x.EndTimeUnixNano\n\t}\n\treturn 0\n}\n\nfunc (x *Span) GetAttributes() []*v11.KeyValue {\n\tif x != nil {\n\t\treturn x.Attributes\n\t}\n\treturn nil\n}\n\nfunc (x *Span) GetDroppedAttributesCount() uint32 {\n\tif x != nil {\n\t\treturn x.DroppedAttributesCount\n\t}\n\treturn 0\n}\n\nfunc (x *Span) GetEvents() []*Span_Event {\n\tif x != nil {\n\t\treturn x.Events\n\t}\n\treturn nil\n}\n\nfunc (x *Span) GetDroppedEventsCount() uint32 {\n\tif x != nil {\n\t\treturn x.DroppedEventsCount\n\t}\n\treturn 0\n}\n\nfunc (x *Span) GetLinks() []*Span_Link {\n\tif x != nil {\n\t\treturn x.Links\n\t}\n\treturn nil\n}\n\nfunc (x *Span) GetDroppedLinksCount() uint32 {\n\tif x != nil {\n\t\treturn x.DroppedLinksCount\n\t}\n\treturn 0\n}\n\nfunc (x *Span) GetStatus() *Status {\n\tif x != nil {\n\t\treturn x.Status\n\t}\n\treturn nil\n}\n\n// The Status type defines a logical error model that is suitable for different\n// programming environments, including REST APIs and RPC APIs.\ntype Status struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// A developer-facing human readable error message.\n\tMessage string `protobuf:\"bytes,2,opt,name=message,proto3\" json:\"message,omitempty\"`\n\t// The status code.\n\tCode Status_StatusCode `protobuf:\"varint,3,opt,name=code,proto3,enum=opentelemetry.proto.trace.v1.Status_StatusCode\" json:\"code,omitempty\"`\n}\n\nfunc (x *Status) Reset() {\n\t*x = Status{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[4]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Status) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Status) ProtoMessage() {}\n\nfunc (x *Status) ProtoReflect() protoreflect.Message {\n\tmi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[4]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Status.ProtoReflect.Descriptor instead.\nfunc (*Status) Descriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *Status) GetMessage() string {\n\tif x != nil {\n\t\treturn x.Message\n\t}\n\treturn \"\"\n}\n\nfunc (x *Status) GetCode() Status_StatusCode {\n\tif x != nil {\n\t\treturn x.Code\n\t}\n\treturn Status_STATUS_CODE_UNSET\n}\n\n// Event is a time-stamped annotation of the span, consisting of user-supplied\n// text description and key-value pairs.\ntype Span_Event struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// time_unix_nano is the time the event occurred.\n\tTimeUnixNano uint64 `protobuf:\"fixed64,1,opt,name=time_unix_nano,json=timeUnixNano,proto3\" json:\"time_unix_nano,omitempty\"`\n\t// name of the event.\n\t// This field is semantically required to be set to non-empty string.\n\tName string `protobuf:\"bytes,2,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// attributes is a collection of attribute key/value pairs on the event.\n\t// Attribute keys MUST be unique (it is not allowed to have more than one\n\t// attribute with the same key).\n\tAttributes []*v11.KeyValue `protobuf:\"bytes,3,rep,name=attributes,proto3\" json:\"attributes,omitempty\"`\n\t// dropped_attributes_count is the number of dropped attributes. If the value is 0,\n\t// then no attributes were dropped.\n\tDroppedAttributesCount uint32 `protobuf:\"varint,4,opt,name=dropped_attributes_count,json=droppedAttributesCount,proto3\" json:\"dropped_attributes_count,omitempty\"`\n}\n\nfunc (x *Span_Event) Reset() {\n\t*x = Span_Event{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[5]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Span_Event) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Span_Event) ProtoMessage() {}\n\nfunc (x *Span_Event) ProtoReflect() protoreflect.Message {\n\tmi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[5]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Span_Event.ProtoReflect.Descriptor instead.\nfunc (*Span_Event) Descriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{3, 0}\n}\n\nfunc (x *Span_Event) GetTimeUnixNano() uint64 {\n\tif x != nil {\n\t\treturn x.TimeUnixNano\n\t}\n\treturn 0\n}\n\nfunc (x *Span_Event) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *Span_Event) GetAttributes() []*v11.KeyValue {\n\tif x != nil {\n\t\treturn x.Attributes\n\t}\n\treturn nil\n}\n\nfunc (x *Span_Event) GetDroppedAttributesCount() uint32 {\n\tif x != nil {\n\t\treturn x.DroppedAttributesCount\n\t}\n\treturn 0\n}\n\n// A pointer from the current span to another span in the same trace or in a\n// different trace. For example, this can be used in batching operations,\n// where a single batch handler processes multiple requests from different\n// traces or when the handler receives a request from a different project.\ntype Span_Link struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// A unique identifier of a trace that this linked span is part of. The ID is a\n\t// 16-byte array.\n\tTraceId []byte `protobuf:\"bytes,1,opt,name=trace_id,json=traceId,proto3\" json:\"trace_id,omitempty\"`\n\t// A unique identifier for the linked span. The ID is an 8-byte array.\n\tSpanId []byte `protobuf:\"bytes,2,opt,name=span_id,json=spanId,proto3\" json:\"span_id,omitempty\"`\n\t// The trace_state associated with the link.\n\tTraceState string `protobuf:\"bytes,3,opt,name=trace_state,json=traceState,proto3\" json:\"trace_state,omitempty\"`\n\t// attributes is a collection of attribute key/value pairs on the link.\n\t// Attribute keys MUST be unique (it is not allowed to have more than one\n\t// attribute with the same key).\n\tAttributes []*v11.KeyValue `protobuf:\"bytes,4,rep,name=attributes,proto3\" json:\"attributes,omitempty\"`\n\t// dropped_attributes_count is the number of dropped attributes. If the value is 0,\n\t// then no attributes were dropped.\n\tDroppedAttributesCount uint32 `protobuf:\"varint,5,opt,name=dropped_attributes_count,json=droppedAttributesCount,proto3\" json:\"dropped_attributes_count,omitempty\"`\n\t// Flags, a bit field.\n\t//\n\t// Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C Trace\n\t// Context specification. To read the 8-bit W3C trace flag, use\n\t// `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`.\n\t//\n\t// See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions.\n\t//\n\t// Bits 8 and 9 represent the 3 states of whether the link is remote.\n\t// The states are (unknown, is not remote, is remote).\n\t// To read whether the value is known, use `(flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`.\n\t// To read whether the link is remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`.\n\t//\n\t// Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero.\n\t// When creating new spans, bits 10-31 (most-significant 22-bits) MUST be zero.\n\t//\n\t// [Optional].\n\tFlags uint32 `protobuf:\"fixed32,6,opt,name=flags,proto3\" json:\"flags,omitempty\"`\n}\n\nfunc (x *Span_Link) Reset() {\n\t*x = Span_Link{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[6]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Span_Link) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Span_Link) ProtoMessage() {}\n\nfunc (x *Span_Link) ProtoReflect() protoreflect.Message {\n\tmi := &file_opentelemetry_proto_trace_v1_trace_proto_msgTypes[6]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Span_Link.ProtoReflect.Descriptor instead.\nfunc (*Span_Link) Descriptor() ([]byte, []int) {\n\treturn file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP(), []int{3, 1}\n}\n\nfunc (x *Span_Link) GetTraceId() []byte {\n\tif x != nil {\n\t\treturn x.TraceId\n\t}\n\treturn nil\n}\n\nfunc (x *Span_Link) GetSpanId() []byte {\n\tif x != nil {\n\t\treturn x.SpanId\n\t}\n\treturn nil\n}\n\nfunc (x *Span_Link) GetTraceState() string {\n\tif x != nil {\n\t\treturn x.TraceState\n\t}\n\treturn \"\"\n}\n\nfunc (x *Span_Link) GetAttributes() []*v11.KeyValue {\n\tif x != nil {\n\t\treturn x.Attributes\n\t}\n\treturn nil\n}\n\nfunc (x *Span_Link) GetDroppedAttributesCount() uint32 {\n\tif x != nil {\n\t\treturn x.DroppedAttributesCount\n\t}\n\treturn 0\n}\n\nfunc (x *Span_Link) GetFlags() uint32 {\n\tif x != nil {\n\t\treturn x.Flags\n\t}\n\treturn 0\n}\n\nvar File_opentelemetry_proto_trace_v1_trace_proto protoreflect.FileDescriptor\n\nvar file_opentelemetry_proto_trace_v1_trace_proto_rawDesc = []byte{\n\t0x0a, 0x28, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2f,\n\t0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x74,\n\t0x72, 0x61, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x6f, 0x70, 0x65, 0x6e,\n\t0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,\n\t0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x2a, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65,\n\t0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f,\n\t0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70,\n\t0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65,\n\t0x74, 0x72, 0x79, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,\n\t0x63, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70,\n\t0x72, 0x6f, 0x74, 0x6f, 0x22, 0x60, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x44, 0x61,\n\t0x74, 0x61, 0x12, 0x52, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73,\n\t0x70, 0x61, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,\n\t0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72,\n\t0x63, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,\n\t0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x22, 0xc8, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75,\n\t0x72, 0x63, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x12, 0x45, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f,\n\t0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,\n\t0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73,\n\t0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12,\n\t0x49, 0x0a, 0x0b, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x18, 0x02,\n\t0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d,\n\t0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65,\n\t0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x52, 0x0a,\n\t0x73, 0x63, 0x6f, 0x70, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x63,\n\t0x68, 0x65, 0x6d, 0x61, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,\n\t0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x72, 0x6c, 0x4a, 0x06, 0x08, 0xe8, 0x07, 0x10, 0xe9,\n\t0x07, 0x22, 0xb0, 0x01, 0x0a, 0x0a, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73,\n\t0x12, 0x49, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x33, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e,\n\t0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e,\n\t0x49, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53,\n\t0x63, 0x6f, 0x70, 0x65, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x38, 0x0a, 0x05, 0x73,\n\t0x70, 0x61, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,\n\t0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x52, 0x05,\n\t0x73, 0x70, 0x61, 0x6e, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f,\n\t0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x63, 0x68, 0x65, 0x6d,\n\t0x61, 0x55, 0x72, 0x6c, 0x22, 0xc8, 0x0a, 0x0a, 0x04, 0x53, 0x70, 0x61, 0x6e, 0x12, 0x19, 0x0a,\n\t0x08, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,\n\t0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x70, 0x61, 0x6e,\n\t0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x70, 0x61, 0x6e, 0x49,\n\t0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65,\n\t0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x72, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61,\n\t0x74, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x70, 0x61,\n\t0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x65,\n\t0x6e, 0x74, 0x53, 0x70, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67,\n\t0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x07, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x12,\n\t0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,\n\t0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e,\n\t0x32, 0x2b, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79,\n\t0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e,\n\t0x53, 0x70, 0x61, 0x6e, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, 0x6b,\n\t0x69, 0x6e, 0x64, 0x12, 0x2f, 0x0a, 0x14, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d,\n\t0x65, 0x5f, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28,\n\t0x06, 0x52, 0x11, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78,\n\t0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x2b, 0x0a, 0x12, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65,\n\t0x5f, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x08, 0x20, 0x01, 0x28, 0x06,\n\t0x52, 0x0f, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e,\n\t0x6f, 0x12, 0x47, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18,\n\t0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65,\n\t0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,\n\t0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a,\n\t0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x64, 0x72,\n\t0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73,\n\t0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x16, 0x64, 0x72,\n\t0x6f, 0x70, 0x70, 0x65, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x43,\n\t0x6f, 0x75, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x0b,\n\t0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d,\n\t0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65,\n\t0x2e, 0x76, 0x31, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06,\n\t0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65,\n\t0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0c,\n\t0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x45, 0x76, 0x65,\n\t0x6e, 0x74, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b,\n\t0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65,\n\t0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72,\n\t0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x4c, 0x69, 0x6e, 0x6b,\n\t0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x72, 0x6f, 0x70, 0x70,\n\t0x65, 0x64, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e,\n\t0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x4c, 0x69, 0x6e,\n\t0x6b, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,\n\t0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65,\n\t0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72,\n\t0x61, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73,\n\t0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, 0xc4, 0x01, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12,\n\t0x24, 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x6e, 0x61, 0x6e,\n\t0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x06, 0x52, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69,\n\t0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,\n\t0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x47, 0x0a, 0x0a, 0x61, 0x74, 0x74,\n\t0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70, 0x72,\n\t0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4b, 0x65,\n\t0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,\n\t0x65, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x61, 0x74,\n\t0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04,\n\t0x20, 0x01, 0x28, 0x0d, 0x52, 0x16, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x41, 0x74, 0x74,\n\t0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0xf4, 0x01, 0x0a,\n\t0x04, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x69,\n\t0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64,\n\t0x12, 0x17, 0x0a, 0x07, 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,\n\t0x0c, 0x52, 0x06, 0x73, 0x70, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x72, 0x61,\n\t0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,\n\t0x74, 0x72, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x47, 0x0a, 0x0a, 0x61, 0x74,\n\t0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x70,\n\t0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4b,\n\t0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,\n\t0x74, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x61,\n\t0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18,\n\t0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x16, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x41, 0x74,\n\t0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x14, 0x0a,\n\t0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x07, 0x52, 0x05, 0x66, 0x6c,\n\t0x61, 0x67, 0x73, 0x22, 0x99, 0x01, 0x0a, 0x08, 0x53, 0x70, 0x61, 0x6e, 0x4b, 0x69, 0x6e, 0x64,\n\t0x12, 0x19, 0x0a, 0x15, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e,\n\t0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x53,\n\t0x50, 0x41, 0x4e, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41,\n\t0x4c, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x4b, 0x49, 0x4e, 0x44,\n\t0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x50, 0x41,\n\t0x4e, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x12,\n\t0x16, 0x0a, 0x12, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x50, 0x52, 0x4f,\n\t0x44, 0x55, 0x43, 0x45, 0x52, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x50, 0x41, 0x4e, 0x5f,\n\t0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x55, 0x4d, 0x45, 0x52, 0x10, 0x05, 0x22,\n\t0xbd, 0x01, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65,\n\t0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73,\n\t0x73, 0x61, 0x67, 0x65, 0x12, 0x43, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01,\n\t0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74,\n\t0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76,\n\t0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43,\n\t0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x4e, 0x0a, 0x0a, 0x53, 0x74, 0x61,\n\t0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x55,\n\t0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x12,\n\t0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x4f, 0x4b,\n\t0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x44,\n\t0x45, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x2a,\n\t0x9c, 0x01, 0x0a, 0x09, 0x53, 0x70, 0x61, 0x6e, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x19, 0x0a,\n\t0x15, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x4f, 0x5f, 0x4e,\n\t0x4f, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x10, 0x00, 0x12, 0x20, 0x0a, 0x1b, 0x53, 0x50, 0x41, 0x4e,\n\t0x5f, 0x46, 0x4c, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x43, 0x45, 0x5f, 0x46, 0x4c, 0x41,\n\t0x47, 0x53, 0x5f, 0x4d, 0x41, 0x53, 0x4b, 0x10, 0xff, 0x01, 0x12, 0x2a, 0x0a, 0x25, 0x53, 0x50,\n\t0x41, 0x4e, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x53, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x45, 0x58, 0x54,\n\t0x5f, 0x48, 0x41, 0x53, 0x5f, 0x49, 0x53, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x54, 0x45, 0x5f, 0x4d,\n\t0x41, 0x53, 0x4b, 0x10, 0x80, 0x02, 0x12, 0x26, 0x0a, 0x21, 0x53, 0x50, 0x41, 0x4e, 0x5f, 0x46,\n\t0x4c, 0x41, 0x47, 0x53, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x45, 0x58, 0x54, 0x5f, 0x49, 0x53, 0x5f,\n\t0x52, 0x45, 0x4d, 0x4f, 0x54, 0x45, 0x5f, 0x4d, 0x41, 0x53, 0x4b, 0x10, 0x80, 0x04, 0x42, 0x77,\n\t0x0a, 0x1f, 0x69, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74,\n\t0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x76,\n\t0x31, 0x42, 0x0a, 0x54, 0x72, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a,\n\t0x27, 0x67, 0x6f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72,\n\t0x79, 0x2e, 0x69, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6f, 0x74, 0x6c, 0x70, 0x2f,\n\t0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, 0x76, 0x31, 0xaa, 0x02, 0x1c, 0x4f, 0x70, 0x65, 0x6e, 0x54,\n\t0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54,\n\t0x72, 0x61, 0x63, 0x65, 0x2e, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,\n}\n\nvar (\n\tfile_opentelemetry_proto_trace_v1_trace_proto_rawDescOnce sync.Once\n\tfile_opentelemetry_proto_trace_v1_trace_proto_rawDescData = file_opentelemetry_proto_trace_v1_trace_proto_rawDesc\n)\n\nfunc file_opentelemetry_proto_trace_v1_trace_proto_rawDescGZIP() []byte {\n\tfile_opentelemetry_proto_trace_v1_trace_proto_rawDescOnce.Do(func() {\n\t\tfile_opentelemetry_proto_trace_v1_trace_proto_rawDescData = protoimpl.X.CompressGZIP(file_opentelemetry_proto_trace_v1_trace_proto_rawDescData)\n\t})\n\treturn file_opentelemetry_proto_trace_v1_trace_proto_rawDescData\n}\n\nvar file_opentelemetry_proto_trace_v1_trace_proto_enumTypes = make([]protoimpl.EnumInfo, 3)\nvar file_opentelemetry_proto_trace_v1_trace_proto_msgTypes = make([]protoimpl.MessageInfo, 7)\nvar file_opentelemetry_proto_trace_v1_trace_proto_goTypes = []interface{}{\n\t(SpanFlags)(0),                   // 0: opentelemetry.proto.trace.v1.SpanFlags\n\t(Span_SpanKind)(0),               // 1: opentelemetry.proto.trace.v1.Span.SpanKind\n\t(Status_StatusCode)(0),           // 2: opentelemetry.proto.trace.v1.Status.StatusCode\n\t(*TracesData)(nil),               // 3: opentelemetry.proto.trace.v1.TracesData\n\t(*ResourceSpans)(nil),            // 4: opentelemetry.proto.trace.v1.ResourceSpans\n\t(*ScopeSpans)(nil),               // 5: opentelemetry.proto.trace.v1.ScopeSpans\n\t(*Span)(nil),                     // 6: opentelemetry.proto.trace.v1.Span\n\t(*Status)(nil),                   // 7: opentelemetry.proto.trace.v1.Status\n\t(*Span_Event)(nil),               // 8: opentelemetry.proto.trace.v1.Span.Event\n\t(*Span_Link)(nil),                // 9: opentelemetry.proto.trace.v1.Span.Link\n\t(*v1.Resource)(nil),              // 10: opentelemetry.proto.resource.v1.Resource\n\t(*v11.InstrumentationScope)(nil), // 11: opentelemetry.proto.common.v1.InstrumentationScope\n\t(*v11.KeyValue)(nil),             // 12: opentelemetry.proto.common.v1.KeyValue\n}\nvar file_opentelemetry_proto_trace_v1_trace_proto_depIdxs = []int32{\n\t4,  // 0: opentelemetry.proto.trace.v1.TracesData.resource_spans:type_name -> opentelemetry.proto.trace.v1.ResourceSpans\n\t10, // 1: opentelemetry.proto.trace.v1.ResourceSpans.resource:type_name -> opentelemetry.proto.resource.v1.Resource\n\t5,  // 2: opentelemetry.proto.trace.v1.ResourceSpans.scope_spans:type_name -> opentelemetry.proto.trace.v1.ScopeSpans\n\t11, // 3: opentelemetry.proto.trace.v1.ScopeSpans.scope:type_name -> opentelemetry.proto.common.v1.InstrumentationScope\n\t6,  // 4: opentelemetry.proto.trace.v1.ScopeSpans.spans:type_name -> opentelemetry.proto.trace.v1.Span\n\t1,  // 5: opentelemetry.proto.trace.v1.Span.kind:type_name -> opentelemetry.proto.trace.v1.Span.SpanKind\n\t12, // 6: opentelemetry.proto.trace.v1.Span.attributes:type_name -> opentelemetry.proto.common.v1.KeyValue\n\t8,  // 7: opentelemetry.proto.trace.v1.Span.events:type_name -> opentelemetry.proto.trace.v1.Span.Event\n\t9,  // 8: opentelemetry.proto.trace.v1.Span.links:type_name -> opentelemetry.proto.trace.v1.Span.Link\n\t7,  // 9: opentelemetry.proto.trace.v1.Span.status:type_name -> opentelemetry.proto.trace.v1.Status\n\t2,  // 10: opentelemetry.proto.trace.v1.Status.code:type_name -> opentelemetry.proto.trace.v1.Status.StatusCode\n\t12, // 11: opentelemetry.proto.trace.v1.Span.Event.attributes:type_name -> opentelemetry.proto.common.v1.KeyValue\n\t12, // 12: opentelemetry.proto.trace.v1.Span.Link.attributes:type_name -> opentelemetry.proto.common.v1.KeyValue\n\t13, // [13:13] is the sub-list for method output_type\n\t13, // [13:13] is the sub-list for method input_type\n\t13, // [13:13] is the sub-list for extension type_name\n\t13, // [13:13] is the sub-list for extension extendee\n\t0,  // [0:13] is the sub-list for field type_name\n}\n\nfunc init() { file_opentelemetry_proto_trace_v1_trace_proto_init() }\nfunc file_opentelemetry_proto_trace_v1_trace_proto_init() {\n\tif File_opentelemetry_proto_trace_v1_trace_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_opentelemetry_proto_trace_v1_trace_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*TracesData); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_opentelemetry_proto_trace_v1_trace_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ResourceSpans); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_opentelemetry_proto_trace_v1_trace_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ScopeSpans); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_opentelemetry_proto_trace_v1_trace_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Span); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_opentelemetry_proto_trace_v1_trace_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Status); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_opentelemetry_proto_trace_v1_trace_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Span_Event); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_opentelemetry_proto_trace_v1_trace_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Span_Link); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: file_opentelemetry_proto_trace_v1_trace_proto_rawDesc,\n\t\t\tNumEnums:      3,\n\t\t\tNumMessages:   7,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_opentelemetry_proto_trace_v1_trace_proto_goTypes,\n\t\tDependencyIndexes: file_opentelemetry_proto_trace_v1_trace_proto_depIdxs,\n\t\tEnumInfos:         file_opentelemetry_proto_trace_v1_trace_proto_enumTypes,\n\t\tMessageInfos:      file_opentelemetry_proto_trace_v1_trace_proto_msgTypes,\n\t}.Build()\n\tFile_opentelemetry_proto_trace_v1_trace_proto = out.File\n\tfile_opentelemetry_proto_trace_v1_trace_proto_rawDesc = nil\n\tfile_opentelemetry_proto_trace_v1_trace_proto_goTypes = nil\n\tfile_opentelemetry_proto_trace_v1_trace_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "vendor/go.uber.org/mock/AUTHORS",
    "content": "# This is the official list of GoMock authors for copyright purposes.\n# This file is distinct from the CONTRIBUTORS files.\n# See the latter for an explanation.\n\n# Names should be added to this file as\n#\tName or Organization <email address>\n# The email address is not required for organizations.\n\n# Please keep the list sorted.\n\nAlex Reece <awreece@gmail.com>\nGoogle Inc.\n"
  },
  {
    "path": "vendor/go.uber.org/mock/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "vendor/go.uber.org/mock/gomock/call.go",
    "content": "// Copyright 2010 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage gomock\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Call represents an expected call to a mock.\ntype Call struct {\n\tt TestHelper // for triggering test failures on invalid call setup\n\n\treceiver   any          // the receiver of the method call\n\tmethod     string       // the name of the method\n\tmethodType reflect.Type // the type of the method\n\targs       []Matcher    // the args\n\torigin     string       // file and line number of call setup\n\n\tpreReqs []*Call // prerequisite calls\n\n\t// Expectations\n\tminCalls, maxCalls int\n\n\tnumCalls int // actual number made\n\n\t// actions are called when this Call is called. Each action gets the args and\n\t// can set the return values by returning a non-nil slice. Actions run in the\n\t// order they are created.\n\tactions []func([]any) []any\n}\n\n// newCall creates a *Call. It requires the method type in order to support\n// unexported methods.\nfunc newCall(t TestHelper, receiver any, method string, methodType reflect.Type, args ...any) *Call {\n\tt.Helper()\n\n\t// TODO: check arity, types.\n\tmArgs := make([]Matcher, len(args))\n\tfor i, arg := range args {\n\t\tif m, ok := arg.(Matcher); ok {\n\t\t\tmArgs[i] = m\n\t\t} else if arg == nil {\n\t\t\t// Handle nil specially so that passing a nil interface value\n\t\t\t// will match the typed nils of concrete args.\n\t\t\tmArgs[i] = Nil()\n\t\t} else {\n\t\t\tmArgs[i] = Eq(arg)\n\t\t}\n\t}\n\n\t// callerInfo's skip should be updated if the number of calls between the user's test\n\t// and this line changes, i.e. this code is wrapped in another anonymous function.\n\t// 0 is us, 1 is RecordCallWithMethodType(), 2 is the generated recorder, and 3 is the user's test.\n\torigin := callerInfo(3)\n\tactions := []func([]any) []any{func([]any) []any {\n\t\t// Synthesize the zero value for each of the return args' types.\n\t\trets := make([]any, methodType.NumOut())\n\t\tfor i := 0; i < methodType.NumOut(); i++ {\n\t\t\trets[i] = reflect.Zero(methodType.Out(i)).Interface()\n\t\t}\n\t\treturn rets\n\t}}\n\treturn &Call{\n\t\tt: t, receiver: receiver, method: method, methodType: methodType,\n\t\targs: mArgs, origin: origin, minCalls: 1, maxCalls: 1, actions: actions,\n\t}\n}\n\n// AnyTimes allows the expectation to be called 0 or more times\nfunc (c *Call) AnyTimes() *Call {\n\tc.minCalls, c.maxCalls = 0, 1e8 // close enough to infinity\n\treturn c\n}\n\n// MinTimes requires the call to occur at least n times. If AnyTimes or MaxTimes have not been called or if MaxTimes\n// was previously called with 1, MinTimes also sets the maximum number of calls to infinity.\nfunc (c *Call) MinTimes(n int) *Call {\n\tc.minCalls = n\n\tif c.maxCalls == 1 {\n\t\tc.maxCalls = 1e8\n\t}\n\treturn c\n}\n\n// MaxTimes limits the number of calls to n times. If AnyTimes or MinTimes have not been called or if MinTimes was\n// previously called with 1, MaxTimes also sets the minimum number of calls to 0.\nfunc (c *Call) MaxTimes(n int) *Call {\n\tc.maxCalls = n\n\tif c.minCalls == 1 {\n\t\tc.minCalls = 0\n\t}\n\treturn c\n}\n\n// DoAndReturn declares the action to run when the call is matched.\n// The return values from this function are returned by the mocked function.\n// It takes an any argument to support n-arity functions.\n// The anonymous function must match the function signature mocked method.\nfunc (c *Call) DoAndReturn(f any) *Call {\n\t// TODO: Check arity and types here, rather than dying badly elsewhere.\n\tv := reflect.ValueOf(f)\n\n\tc.addAction(func(args []any) []any {\n\t\tc.t.Helper()\n\t\tft := v.Type()\n\t\tif c.methodType.NumIn() != ft.NumIn() {\n\t\t\tif ft.IsVariadic() {\n\t\t\t\tc.t.Fatalf(\"wrong number of arguments in DoAndReturn func for %T.%v The function signature must match the mocked method, a variadic function cannot be used.\",\n\t\t\t\t\tc.receiver, c.method)\n\t\t\t} else {\n\t\t\t\tc.t.Fatalf(\"wrong number of arguments in DoAndReturn func for %T.%v: got %d, want %d [%s]\",\n\t\t\t\t\tc.receiver, c.method, ft.NumIn(), c.methodType.NumIn(), c.origin)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t\tvArgs := make([]reflect.Value, len(args))\n\t\tfor i := 0; i < len(args); i++ {\n\t\t\tif args[i] != nil {\n\t\t\t\tvArgs[i] = reflect.ValueOf(args[i])\n\t\t\t} else {\n\t\t\t\t// Use the zero value for the arg.\n\t\t\t\tvArgs[i] = reflect.Zero(ft.In(i))\n\t\t\t}\n\t\t}\n\t\tvRets := v.Call(vArgs)\n\t\trets := make([]any, len(vRets))\n\t\tfor i, ret := range vRets {\n\t\t\trets[i] = ret.Interface()\n\t\t}\n\t\treturn rets\n\t})\n\treturn c\n}\n\n// Do declares the action to run when the call is matched. The function's\n// return values are ignored to retain backward compatibility. To use the\n// return values call DoAndReturn.\n// It takes an any argument to support n-arity functions.\n// The anonymous function must match the function signature mocked method.\nfunc (c *Call) Do(f any) *Call {\n\t// TODO: Check arity and types here, rather than dying badly elsewhere.\n\tv := reflect.ValueOf(f)\n\n\tc.addAction(func(args []any) []any {\n\t\tc.t.Helper()\n\t\tft := v.Type()\n\t\tif c.methodType.NumIn() != ft.NumIn() {\n\t\t\tif ft.IsVariadic() {\n\t\t\t\tc.t.Fatalf(\"wrong number of arguments in Do func for %T.%v The function signature must match the mocked method, a variadic function cannot be used.\",\n\t\t\t\t\tc.receiver, c.method)\n\t\t\t} else {\n\t\t\t\tc.t.Fatalf(\"wrong number of arguments in Do func for %T.%v: got %d, want %d [%s]\",\n\t\t\t\t\tc.receiver, c.method, ft.NumIn(), c.methodType.NumIn(), c.origin)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t\tvArgs := make([]reflect.Value, len(args))\n\t\tfor i := 0; i < len(args); i++ {\n\t\t\tif args[i] != nil {\n\t\t\t\tvArgs[i] = reflect.ValueOf(args[i])\n\t\t\t} else {\n\t\t\t\t// Use the zero value for the arg.\n\t\t\t\tvArgs[i] = reflect.Zero(ft.In(i))\n\t\t\t}\n\t\t}\n\t\tv.Call(vArgs)\n\t\treturn nil\n\t})\n\treturn c\n}\n\n// Return declares the values to be returned by the mocked function call.\nfunc (c *Call) Return(rets ...any) *Call {\n\tc.t.Helper()\n\n\tmt := c.methodType\n\tif len(rets) != mt.NumOut() {\n\t\tc.t.Fatalf(\"wrong number of arguments to Return for %T.%v: got %d, want %d [%s]\",\n\t\t\tc.receiver, c.method, len(rets), mt.NumOut(), c.origin)\n\t}\n\tfor i, ret := range rets {\n\t\tif got, want := reflect.TypeOf(ret), mt.Out(i); got == want {\n\t\t\t// Identical types; nothing to do.\n\t\t} else if got == nil {\n\t\t\t// Nil needs special handling.\n\t\t\tswitch want.Kind() {\n\t\t\tcase reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:\n\t\t\t\t// ok\n\t\t\tdefault:\n\t\t\t\tc.t.Fatalf(\"argument %d to Return for %T.%v is nil, but %v is not nillable [%s]\",\n\t\t\t\t\ti, c.receiver, c.method, want, c.origin)\n\t\t\t}\n\t\t} else if got.AssignableTo(want) {\n\t\t\t// Assignable type relation. Make the assignment now so that the generated code\n\t\t\t// can return the values with a type assertion.\n\t\t\tv := reflect.New(want).Elem()\n\t\t\tv.Set(reflect.ValueOf(ret))\n\t\t\trets[i] = v.Interface()\n\t\t} else {\n\t\t\tc.t.Fatalf(\"wrong type of argument %d to Return for %T.%v: %v is not assignable to %v [%s]\",\n\t\t\t\ti, c.receiver, c.method, got, want, c.origin)\n\t\t}\n\t}\n\n\tc.addAction(func([]any) []any {\n\t\treturn rets\n\t})\n\n\treturn c\n}\n\n// Times declares the exact number of times a function call is expected to be executed.\nfunc (c *Call) Times(n int) *Call {\n\tc.minCalls, c.maxCalls = n, n\n\treturn c\n}\n\n// SetArg declares an action that will set the nth argument's value,\n// indirected through a pointer. Or, in the case of a slice and map, SetArg\n// will copy value's elements/key-value pairs into the nth argument.\nfunc (c *Call) SetArg(n int, value any) *Call {\n\tc.t.Helper()\n\n\tmt := c.methodType\n\t// TODO: This will break on variadic methods.\n\t// We will need to check those at invocation time.\n\tif n < 0 || n >= mt.NumIn() {\n\t\tc.t.Fatalf(\"SetArg(%d, ...) called for a method with %d args [%s]\",\n\t\t\tn, mt.NumIn(), c.origin)\n\t}\n\t// Permit setting argument through an interface.\n\t// In the interface case, we don't (nay, can't) check the type here.\n\tat := mt.In(n)\n\tswitch at.Kind() {\n\tcase reflect.Ptr:\n\t\tdt := at.Elem()\n\t\tif vt := reflect.TypeOf(value); !vt.AssignableTo(dt) {\n\t\t\tc.t.Fatalf(\"SetArg(%d, ...) argument is a %v, not assignable to %v [%s]\",\n\t\t\t\tn, vt, dt, c.origin)\n\t\t}\n\tcase reflect.Interface, reflect.Slice, reflect.Map:\n\t\t// nothing to do\n\tdefault:\n\t\tc.t.Fatalf(\"SetArg(%d, ...) referring to argument of non-pointer non-interface non-slice non-map type %v [%s]\",\n\t\t\tn, at, c.origin)\n\t}\n\n\tc.addAction(func(args []any) []any {\n\t\tv := reflect.ValueOf(value)\n\t\tswitch reflect.TypeOf(args[n]).Kind() {\n\t\tcase reflect.Slice:\n\t\t\tsetSlice(args[n], v)\n\t\tcase reflect.Map:\n\t\t\tsetMap(args[n], v)\n\t\tdefault:\n\t\t\treflect.ValueOf(args[n]).Elem().Set(v)\n\t\t}\n\t\treturn nil\n\t})\n\treturn c\n}\n\n// isPreReq returns true if other is a direct or indirect prerequisite to c.\nfunc (c *Call) isPreReq(other *Call) bool {\n\tfor _, preReq := range c.preReqs {\n\t\tif other == preReq || preReq.isPreReq(other) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// After declares that the call may only match after preReq has been exhausted.\nfunc (c *Call) After(preReq *Call) *Call {\n\tc.t.Helper()\n\n\tif c == preReq {\n\t\tc.t.Fatalf(\"A call isn't allowed to be its own prerequisite\")\n\t}\n\tif preReq.isPreReq(c) {\n\t\tc.t.Fatalf(\"Loop in call order: %v is a prerequisite to %v (possibly indirectly).\", c, preReq)\n\t}\n\n\tc.preReqs = append(c.preReqs, preReq)\n\treturn c\n}\n\n// Returns true if the minimum number of calls have been made.\nfunc (c *Call) satisfied() bool {\n\treturn c.numCalls >= c.minCalls\n}\n\n// Returns true if the maximum number of calls have been made.\nfunc (c *Call) exhausted() bool {\n\treturn c.numCalls >= c.maxCalls\n}\n\nfunc (c *Call) String() string {\n\targs := make([]string, len(c.args))\n\tfor i, arg := range c.args {\n\t\targs[i] = arg.String()\n\t}\n\targuments := strings.Join(args, \", \")\n\treturn fmt.Sprintf(\"%T.%v(%s) %s\", c.receiver, c.method, arguments, c.origin)\n}\n\n// Tests if the given call matches the expected call.\n// If yes, returns nil. If no, returns error with message explaining why it does not match.\nfunc (c *Call) matches(args []any) error {\n\tif !c.methodType.IsVariadic() {\n\t\tif len(args) != len(c.args) {\n\t\t\treturn fmt.Errorf(\"expected call at %s has the wrong number of arguments. Got: %d, want: %d\",\n\t\t\t\tc.origin, len(args), len(c.args))\n\t\t}\n\n\t\tfor i, m := range c.args {\n\t\t\tif !m.Matches(args[i]) {\n\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\"expected call at %s doesn't match the argument at index %d.\\nGot: %v\\nWant: %v\",\n\t\t\t\t\tc.origin, i, formatGottenArg(m, args[i]), m,\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif len(c.args) < c.methodType.NumIn()-1 {\n\t\t\treturn fmt.Errorf(\"expected call at %s has the wrong number of matchers. Got: %d, want: %d\",\n\t\t\t\tc.origin, len(c.args), c.methodType.NumIn()-1)\n\t\t}\n\t\tif len(c.args) != c.methodType.NumIn() && len(args) != len(c.args) {\n\t\t\treturn fmt.Errorf(\"expected call at %s has the wrong number of arguments. Got: %d, want: %d\",\n\t\t\t\tc.origin, len(args), len(c.args))\n\t\t}\n\t\tif len(args) < len(c.args)-1 {\n\t\t\treturn fmt.Errorf(\"expected call at %s has the wrong number of arguments. Got: %d, want: greater than or equal to %d\",\n\t\t\t\tc.origin, len(args), len(c.args)-1)\n\t\t}\n\n\t\tfor i, m := range c.args {\n\t\t\tif i < c.methodType.NumIn()-1 {\n\t\t\t\t// Non-variadic args\n\t\t\t\tif !m.Matches(args[i]) {\n\t\t\t\t\treturn fmt.Errorf(\"expected call at %s doesn't match the argument at index %s.\\nGot: %v\\nWant: %v\",\n\t\t\t\t\t\tc.origin, strconv.Itoa(i), formatGottenArg(m, args[i]), m)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// The last arg has a possibility of a variadic argument, so let it branch\n\n\t\t\t// sample: Foo(a int, b int, c ...int)\n\t\t\tif i < len(c.args) && i < len(args) {\n\t\t\t\tif m.Matches(args[i]) {\n\t\t\t\t\t// Got Foo(a, b, c) want Foo(matcherA, matcherB, gomock.Any())\n\t\t\t\t\t// Got Foo(a, b, c) want Foo(matcherA, matcherB, someSliceMatcher)\n\t\t\t\t\t// Got Foo(a, b, c) want Foo(matcherA, matcherB, matcherC)\n\t\t\t\t\t// Got Foo(a, b) want Foo(matcherA, matcherB)\n\t\t\t\t\t// Got Foo(a, b, c, d) want Foo(matcherA, matcherB, matcherC, matcherD)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// The number of actual args don't match the number of matchers,\n\t\t\t// or the last matcher is a slice and the last arg is not.\n\t\t\t// If this function still matches it is because the last matcher\n\t\t\t// matches all the remaining arguments or the lack of any.\n\t\t\t// Convert the remaining arguments, if any, into a slice of the\n\t\t\t// expected type.\n\t\t\tvArgsType := c.methodType.In(c.methodType.NumIn() - 1)\n\t\t\tvArgs := reflect.MakeSlice(vArgsType, 0, len(args)-i)\n\t\t\tfor _, arg := range args[i:] {\n\t\t\t\tvArgs = reflect.Append(vArgs, reflect.ValueOf(arg))\n\t\t\t}\n\t\t\tif m.Matches(vArgs.Interface()) {\n\t\t\t\t// Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, gomock.Any())\n\t\t\t\t// Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, someSliceMatcher)\n\t\t\t\t// Got Foo(a, b) want Foo(matcherA, matcherB, gomock.Any())\n\t\t\t\t// Got Foo(a, b) want Foo(matcherA, matcherB, someEmptySliceMatcher)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t// Wrong number of matchers or not match. Fail.\n\t\t\t// Got Foo(a, b) want Foo(matcherA, matcherB, matcherC, matcherD)\n\t\t\t// Got Foo(a, b, c) want Foo(matcherA, matcherB, matcherC, matcherD)\n\t\t\t// Got Foo(a, b, c, d) want Foo(matcherA, matcherB, matcherC, matcherD, matcherE)\n\t\t\t// Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, matcherC, matcherD)\n\t\t\t// Got Foo(a, b, c) want Foo(matcherA, matcherB)\n\n\t\t\treturn fmt.Errorf(\"expected call at %s doesn't match the argument at index %s.\\nGot: %v\\nWant: %v\",\n\t\t\t\tc.origin, strconv.Itoa(i), formatGottenArg(m, args[i:]), c.args[i])\n\t\t}\n\t}\n\n\t// Check that all prerequisite calls have been satisfied.\n\tfor _, preReqCall := range c.preReqs {\n\t\tif !preReqCall.satisfied() {\n\t\t\treturn fmt.Errorf(\"expected call at %s doesn't have a prerequisite call satisfied:\\n%v\\nshould be called before:\\n%v\",\n\t\t\t\tc.origin, preReqCall, c)\n\t\t}\n\t}\n\n\t// Check that the call is not exhausted.\n\tif c.exhausted() {\n\t\treturn fmt.Errorf(\"expected call at %s has already been called the max number of times\", c.origin)\n\t}\n\n\treturn nil\n}\n\n// dropPrereqs tells the expected Call to not re-check prerequisite calls any\n// longer, and to return its current set.\nfunc (c *Call) dropPrereqs() (preReqs []*Call) {\n\tpreReqs = c.preReqs\n\tc.preReqs = nil\n\treturn\n}\n\nfunc (c *Call) call() []func([]any) []any {\n\tc.numCalls++\n\treturn c.actions\n}\n\n// InOrder declares that the given calls should occur in order.\n// It panics if the type of any of the arguments isn't *Call or a generated\n// mock with an embedded *Call.\nfunc InOrder(args ...any) {\n\tcalls := make([]*Call, 0, len(args))\n\tfor i := 0; i < len(args); i++ {\n\t\tif call := getCall(args[i]); call != nil {\n\t\t\tcalls = append(calls, call)\n\t\t\tcontinue\n\t\t}\n\t\tpanic(fmt.Sprintf(\n\t\t\t\"invalid argument at position %d of type %T, InOrder expects *gomock.Call or generated mock types with an embedded *gomock.Call\",\n\t\t\ti,\n\t\t\targs[i],\n\t\t))\n\t}\n\tfor i := 1; i < len(calls); i++ {\n\t\tcalls[i].After(calls[i-1])\n\t}\n}\n\n// getCall checks if the parameter is a *Call or a generated struct\n// that wraps a *Call and returns the *Call pointer - if neither, it returns nil.\nfunc getCall(arg any) *Call {\n\tif call, ok := arg.(*Call); ok {\n\t\treturn call\n\t}\n\tt := reflect.ValueOf(arg)\n\tif t.Kind() != reflect.Ptr && t.Kind() != reflect.Interface {\n\t\treturn nil\n\t}\n\tt = t.Elem()\n\tfor i := 0; i < t.NumField(); i++ {\n\t\tf := t.Field(i)\n\t\tif !f.CanInterface() {\n\t\t\tcontinue\n\t\t}\n\t\tif call, ok := f.Interface().(*Call); ok {\n\t\t\treturn call\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc setSlice(arg any, v reflect.Value) {\n\tva := reflect.ValueOf(arg)\n\tfor i := 0; i < v.Len(); i++ {\n\t\tva.Index(i).Set(v.Index(i))\n\t}\n}\n\nfunc setMap(arg any, v reflect.Value) {\n\tva := reflect.ValueOf(arg)\n\tfor _, e := range va.MapKeys() {\n\t\tva.SetMapIndex(e, reflect.Value{})\n\t}\n\tfor _, e := range v.MapKeys() {\n\t\tva.SetMapIndex(e, v.MapIndex(e))\n\t}\n}\n\nfunc (c *Call) addAction(action func([]any) []any) {\n\tc.actions = append(c.actions, action)\n}\n\nfunc formatGottenArg(m Matcher, arg any) string {\n\tgot := fmt.Sprintf(\"%v (%T)\", arg, arg)\n\tif gs, ok := m.(GotFormatter); ok {\n\t\tgot = gs.Got(arg)\n\t}\n\treturn got\n}\n"
  },
  {
    "path": "vendor/go.uber.org/mock/gomock/callset.go",
    "content": "// Copyright 2011 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage gomock\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n)\n\n// callSet represents a set of expected calls, indexed by receiver and method\n// name.\ntype callSet struct {\n\t// Calls that are still expected.\n\texpected   map[callSetKey][]*Call\n\texpectedMu *sync.Mutex\n\t// Calls that have been exhausted.\n\texhausted map[callSetKey][]*Call\n\t// when set to true, existing call expectations are overridden when new call expectations are made\n\tallowOverride bool\n}\n\n// callSetKey is the key in the maps in callSet\ntype callSetKey struct {\n\treceiver any\n\tfname    string\n}\n\nfunc newCallSet() *callSet {\n\treturn &callSet{\n\t\texpected:   make(map[callSetKey][]*Call),\n\t\texpectedMu: &sync.Mutex{},\n\t\texhausted:  make(map[callSetKey][]*Call),\n\t}\n}\n\nfunc newOverridableCallSet() *callSet {\n\treturn &callSet{\n\t\texpected:      make(map[callSetKey][]*Call),\n\t\texpectedMu:    &sync.Mutex{},\n\t\texhausted:     make(map[callSetKey][]*Call),\n\t\tallowOverride: true,\n\t}\n}\n\n// Add adds a new expected call.\nfunc (cs callSet) Add(call *Call) {\n\tkey := callSetKey{call.receiver, call.method}\n\n\tcs.expectedMu.Lock()\n\tdefer cs.expectedMu.Unlock()\n\n\tm := cs.expected\n\tif call.exhausted() {\n\t\tm = cs.exhausted\n\t}\n\tif cs.allowOverride {\n\t\tm[key] = make([]*Call, 0)\n\t}\n\n\tm[key] = append(m[key], call)\n}\n\n// Remove removes an expected call.\nfunc (cs callSet) Remove(call *Call) {\n\tkey := callSetKey{call.receiver, call.method}\n\n\tcs.expectedMu.Lock()\n\tdefer cs.expectedMu.Unlock()\n\n\tcalls := cs.expected[key]\n\tfor i, c := range calls {\n\t\tif c == call {\n\t\t\t// maintain order for remaining calls\n\t\t\tcs.expected[key] = append(calls[:i], calls[i+1:]...)\n\t\t\tcs.exhausted[key] = append(cs.exhausted[key], call)\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n// FindMatch searches for a matching call. Returns error with explanation message if no call matched.\nfunc (cs callSet) FindMatch(receiver any, method string, args []any) (*Call, error) {\n\tkey := callSetKey{receiver, method}\n\n\tcs.expectedMu.Lock()\n\tdefer cs.expectedMu.Unlock()\n\n\t// Search through the expected calls.\n\texpected := cs.expected[key]\n\tvar callsErrors bytes.Buffer\n\tfor _, call := range expected {\n\t\terr := call.matches(args)\n\t\tif err != nil {\n\t\t\t_, _ = fmt.Fprintf(&callsErrors, \"\\n%v\", err)\n\t\t} else {\n\t\t\treturn call, nil\n\t\t}\n\t}\n\n\t// If we haven't found a match then search through the exhausted calls so we\n\t// get useful error messages.\n\texhausted := cs.exhausted[key]\n\tfor _, call := range exhausted {\n\t\tif err := call.matches(args); err != nil {\n\t\t\t_, _ = fmt.Fprintf(&callsErrors, \"\\n%v\", err)\n\t\t\tcontinue\n\t\t}\n\t\t_, _ = fmt.Fprintf(\n\t\t\t&callsErrors, \"all expected calls for method %q have been exhausted\", method,\n\t\t)\n\t}\n\n\tif len(expected)+len(exhausted) == 0 {\n\t\t_, _ = fmt.Fprintf(&callsErrors, \"there are no expected calls of the method %q for that receiver\", method)\n\t}\n\n\treturn nil, errors.New(callsErrors.String())\n}\n\n// Failures returns the calls that are not satisfied.\nfunc (cs callSet) Failures() []*Call {\n\tcs.expectedMu.Lock()\n\tdefer cs.expectedMu.Unlock()\n\n\tfailures := make([]*Call, 0, len(cs.expected))\n\tfor _, calls := range cs.expected {\n\t\tfor _, call := range calls {\n\t\t\tif !call.satisfied() {\n\t\t\t\tfailures = append(failures, call)\n\t\t\t}\n\t\t}\n\t}\n\treturn failures\n}\n\n// Satisfied returns true in case all expected calls in this callSet are satisfied.\nfunc (cs callSet) Satisfied() bool {\n\tcs.expectedMu.Lock()\n\tdefer cs.expectedMu.Unlock()\n\n\tfor _, calls := range cs.expected {\n\t\tfor _, call := range calls {\n\t\t\tif !call.satisfied() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true\n}\n"
  },
  {
    "path": "vendor/go.uber.org/mock/gomock/controller.go",
    "content": "// Copyright 2010 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage gomock\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"runtime\"\n\t\"sync\"\n)\n\n// A TestReporter is something that can be used to report test failures.  It\n// is satisfied by the standard library's *testing.T.\ntype TestReporter interface {\n\tErrorf(format string, args ...any)\n\tFatalf(format string, args ...any)\n}\n\n// TestHelper is a TestReporter that has the Helper method.  It is satisfied\n// by the standard library's *testing.T.\ntype TestHelper interface {\n\tTestReporter\n\tHelper()\n}\n\n// cleanuper is used to check if TestHelper also has the `Cleanup` method. A\n// common pattern is to pass in a `*testing.T` to\n// `NewController(t TestReporter)`. In Go 1.14+, `*testing.T` has a cleanup\n// method. This can be utilized to call `Finish()` so the caller of this library\n// does not have to.\ntype cleanuper interface {\n\tCleanup(func())\n}\n\n// A Controller represents the top-level control of a mock ecosystem.  It\n// defines the scope and lifetime of mock objects, as well as their\n// expectations.  It is safe to call Controller's methods from multiple\n// goroutines. Each test should create a new Controller.\n//\n//\tfunc TestFoo(t *testing.T) {\n//\t  ctrl := gomock.NewController(t)\n//\t  // ..\n//\t}\n//\n//\tfunc TestBar(t *testing.T) {\n//\t  t.Run(\"Sub-Test-1\", st) {\n//\t    ctrl := gomock.NewController(st)\n//\t    // ..\n//\t  })\n//\t  t.Run(\"Sub-Test-2\", st) {\n//\t    ctrl := gomock.NewController(st)\n//\t    // ..\n//\t  })\n//\t})\ntype Controller struct {\n\t// T should only be called within a generated mock. It is not intended to\n\t// be used in user code and may be changed in future versions. T is the\n\t// TestReporter passed in when creating the Controller via NewController.\n\t// If the TestReporter does not implement a TestHelper it will be wrapped\n\t// with a nopTestHelper.\n\tT             TestHelper\n\tmu            sync.Mutex\n\texpectedCalls *callSet\n\tfinished      bool\n}\n\n// NewController returns a new Controller. It is the preferred way to create a Controller.\n//\n// Passing [*testing.T] registers cleanup function to automatically call [Controller.Finish]\n// when the test and all its subtests complete.\nfunc NewController(t TestReporter, opts ...ControllerOption) *Controller {\n\th, ok := t.(TestHelper)\n\tif !ok {\n\t\th = &nopTestHelper{t}\n\t}\n\tctrl := &Controller{\n\t\tT:             h,\n\t\texpectedCalls: newCallSet(),\n\t}\n\tfor _, opt := range opts {\n\t\topt.apply(ctrl)\n\t}\n\tif c, ok := isCleanuper(ctrl.T); ok {\n\t\tc.Cleanup(func() {\n\t\t\tctrl.T.Helper()\n\t\t\tctrl.finish(true, nil)\n\t\t})\n\t}\n\n\treturn ctrl\n}\n\n// ControllerOption configures how a Controller should behave.\ntype ControllerOption interface {\n\tapply(*Controller)\n}\n\ntype overridableExpectationsOption struct{}\n\n// WithOverridableExpectations allows for overridable call expectations\n// i.e., subsequent call expectations override existing call expectations\nfunc WithOverridableExpectations() overridableExpectationsOption {\n\treturn overridableExpectationsOption{}\n}\n\nfunc (o overridableExpectationsOption) apply(ctrl *Controller) {\n\tctrl.expectedCalls = newOverridableCallSet()\n}\n\ntype cancelReporter struct {\n\tt      TestHelper\n\tcancel func()\n}\n\nfunc (r *cancelReporter) Errorf(format string, args ...any) {\n\tr.t.Errorf(format, args...)\n}\n\nfunc (r *cancelReporter) Fatalf(format string, args ...any) {\n\tdefer r.cancel()\n\tr.t.Fatalf(format, args...)\n}\n\nfunc (r *cancelReporter) Helper() {\n\tr.t.Helper()\n}\n\n// WithContext returns a new Controller and a Context, which is cancelled on any\n// fatal failure.\nfunc WithContext(ctx context.Context, t TestReporter) (*Controller, context.Context) {\n\th, ok := t.(TestHelper)\n\tif !ok {\n\t\th = &nopTestHelper{t: t}\n\t}\n\n\tctx, cancel := context.WithCancel(ctx)\n\treturn NewController(&cancelReporter{t: h, cancel: cancel}), ctx\n}\n\ntype nopTestHelper struct {\n\tt TestReporter\n}\n\nfunc (h *nopTestHelper) Errorf(format string, args ...any) {\n\th.t.Errorf(format, args...)\n}\n\nfunc (h *nopTestHelper) Fatalf(format string, args ...any) {\n\th.t.Fatalf(format, args...)\n}\n\nfunc (h nopTestHelper) Helper() {}\n\n// RecordCall is called by a mock. It should not be called by user code.\nfunc (ctrl *Controller) RecordCall(receiver any, method string, args ...any) *Call {\n\tctrl.T.Helper()\n\n\trecv := reflect.ValueOf(receiver)\n\tfor i := 0; i < recv.Type().NumMethod(); i++ {\n\t\tif recv.Type().Method(i).Name == method {\n\t\t\treturn ctrl.RecordCallWithMethodType(receiver, method, recv.Method(i).Type(), args...)\n\t\t}\n\t}\n\tctrl.T.Fatalf(\"gomock: failed finding method %s on %T\", method, receiver)\n\tpanic(\"unreachable\")\n}\n\n// RecordCallWithMethodType is called by a mock. It should not be called by user code.\nfunc (ctrl *Controller) RecordCallWithMethodType(receiver any, method string, methodType reflect.Type, args ...any) *Call {\n\tctrl.T.Helper()\n\n\tcall := newCall(ctrl.T, receiver, method, methodType, args...)\n\n\tctrl.mu.Lock()\n\tdefer ctrl.mu.Unlock()\n\tctrl.expectedCalls.Add(call)\n\n\treturn call\n}\n\n// Call is called by a mock. It should not be called by user code.\nfunc (ctrl *Controller) Call(receiver any, method string, args ...any) []any {\n\tctrl.T.Helper()\n\n\t// Nest this code so we can use defer to make sure the lock is released.\n\tactions := func() []func([]any) []any {\n\t\tctrl.T.Helper()\n\t\tctrl.mu.Lock()\n\t\tdefer ctrl.mu.Unlock()\n\n\t\texpected, err := ctrl.expectedCalls.FindMatch(receiver, method, args)\n\t\tif err != nil {\n\t\t\t// callerInfo's skip should be updated if the number of calls between the user's test\n\t\t\t// and this line changes, i.e. this code is wrapped in another anonymous function.\n\t\t\t// 0 is us, 1 is controller.Call(), 2 is the generated mock, and 3 is the user's test.\n\t\t\torigin := callerInfo(3)\n\t\t\tstringArgs := make([]string, len(args))\n\t\t\tfor i, arg := range args {\n\t\t\t\tstringArgs[i] = getString(arg)\n\t\t\t}\n\t\t\tctrl.T.Fatalf(\"Unexpected call to %T.%v(%v) at %s because: %s\", receiver, method, stringArgs, origin, err)\n\t\t}\n\n\t\t// Two things happen here:\n\t\t// * the matching call no longer needs to check prerequisite calls,\n\t\t// * and the prerequisite calls are no longer expected, so remove them.\n\t\tpreReqCalls := expected.dropPrereqs()\n\t\tfor _, preReqCall := range preReqCalls {\n\t\t\tctrl.expectedCalls.Remove(preReqCall)\n\t\t}\n\n\t\tactions := expected.call()\n\t\tif expected.exhausted() {\n\t\t\tctrl.expectedCalls.Remove(expected)\n\t\t}\n\t\treturn actions\n\t}()\n\n\tvar rets []any\n\tfor _, action := range actions {\n\t\tif r := action(args); r != nil {\n\t\t\trets = r\n\t\t}\n\t}\n\n\treturn rets\n}\n\n// Finish checks to see if all the methods that were expected to be called were called.\n// It is not idempotent and therefore can only be invoked once.\n//\n// Note: If you pass a *testing.T into [NewController], you no longer\n// need to call ctrl.Finish() in your test methods.\nfunc (ctrl *Controller) Finish() {\n\t// If we're currently panicking, probably because this is a deferred call.\n\t// This must be recovered in the deferred function.\n\terr := recover()\n\tctrl.finish(false, err)\n}\n\n// Satisfied returns whether all expected calls bound to this Controller have been satisfied.\n// Calling Finish is then guaranteed to not fail due to missing calls.\nfunc (ctrl *Controller) Satisfied() bool {\n\tctrl.mu.Lock()\n\tdefer ctrl.mu.Unlock()\n\treturn ctrl.expectedCalls.Satisfied()\n}\n\nfunc (ctrl *Controller) finish(cleanup bool, panicErr any) {\n\tctrl.T.Helper()\n\n\tctrl.mu.Lock()\n\tdefer ctrl.mu.Unlock()\n\n\tif ctrl.finished {\n\t\tif _, ok := isCleanuper(ctrl.T); !ok {\n\t\t\tctrl.T.Fatalf(\"Controller.Finish was called more than once. It has to be called exactly once.\")\n\t\t}\n\t\treturn\n\t}\n\tctrl.finished = true\n\n\t// Short-circuit, pass through the panic.\n\tif panicErr != nil {\n\t\tpanic(panicErr)\n\t}\n\n\t// Check that all remaining expected calls are satisfied.\n\tfailures := ctrl.expectedCalls.Failures()\n\tfor _, call := range failures {\n\t\tctrl.T.Errorf(\"missing call(s) to %v\", call)\n\t}\n\tif len(failures) != 0 {\n\t\tif !cleanup {\n\t\t\tctrl.T.Fatalf(\"aborting test due to missing call(s)\")\n\t\t\treturn\n\t\t}\n\t\tctrl.T.Errorf(\"aborting test due to missing call(s)\")\n\t}\n}\n\n// callerInfo returns the file:line of the call site. skip is the number\n// of stack frames to skip when reporting. 0 is callerInfo's call site.\nfunc callerInfo(skip int) string {\n\tif _, file, line, ok := runtime.Caller(skip + 1); ok {\n\t\treturn fmt.Sprintf(\"%s:%d\", file, line)\n\t}\n\treturn \"unknown file\"\n}\n\n// isCleanuper checks it if t's base TestReporter has a Cleanup method.\nfunc isCleanuper(t TestReporter) (cleanuper, bool) {\n\ttr := unwrapTestReporter(t)\n\tc, ok := tr.(cleanuper)\n\treturn c, ok\n}\n\n// unwrapTestReporter unwraps TestReporter to the base implementation.\nfunc unwrapTestReporter(t TestReporter) TestReporter {\n\ttr := t\n\tswitch nt := t.(type) {\n\tcase *cancelReporter:\n\t\ttr = nt.t\n\t\tif h, check := tr.(*nopTestHelper); check {\n\t\t\ttr = h.t\n\t\t}\n\tcase *nopTestHelper:\n\t\ttr = nt.t\n\tdefault:\n\t\t// not wrapped\n\t}\n\treturn tr\n}\n"
  },
  {
    "path": "vendor/go.uber.org/mock/gomock/doc.go",
    "content": "// Copyright 2022 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Package gomock is a mock framework for Go.\n//\n// Standard usage:\n//\n//\t(1) Define an interface that you wish to mock.\n//\t      type MyInterface interface {\n//\t        SomeMethod(x int64, y string)\n//\t      }\n//\t(2) Use mockgen to generate a mock from the interface.\n//\t(3) Use the mock in a test:\n//\t      func TestMyThing(t *testing.T) {\n//\t        mockCtrl := gomock.NewController(t)\n//\t        mockObj := something.NewMockMyInterface(mockCtrl)\n//\t        mockObj.EXPECT().SomeMethod(4, \"blah\")\n//\t        // pass mockObj to a real object and play with it.\n//\t      }\n//\n// By default, expected calls are not enforced to run in any particular order.\n// Call order dependency can be enforced by use of InOrder and/or Call.After.\n// Call.After can create more varied call order dependencies, but InOrder is\n// often more convenient.\n//\n// The following examples create equivalent call order dependencies.\n//\n// Example of using Call.After to chain expected call order:\n//\n//\tfirstCall := mockObj.EXPECT().SomeMethod(1, \"first\")\n//\tsecondCall := mockObj.EXPECT().SomeMethod(2, \"second\").After(firstCall)\n//\tmockObj.EXPECT().SomeMethod(3, \"third\").After(secondCall)\n//\n// Example of using InOrder to declare expected call order:\n//\n//\tgomock.InOrder(\n//\t    mockObj.EXPECT().SomeMethod(1, \"first\"),\n//\t    mockObj.EXPECT().SomeMethod(2, \"second\"),\n//\t    mockObj.EXPECT().SomeMethod(3, \"third\"),\n//\t)\n//\n// The standard TestReporter most users will pass to `NewController` is a\n// `*testing.T` from the context of the test. Note that this will use the\n// standard `t.Error` and `t.Fatal` methods to report what happened in the test.\n// In some cases this can leave your testing package in a weird state if global\n// state is used since `t.Fatal` is like calling panic in the middle of a\n// function. In these cases it is recommended that you pass in your own\n// `TestReporter`.\npackage gomock\n"
  },
  {
    "path": "vendor/go.uber.org/mock/gomock/matchers.go",
    "content": "// Copyright 2010 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage gomock\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strings\"\n)\n\n// A Matcher is a representation of a class of values.\n// It is used to represent the valid or expected arguments to a mocked method.\ntype Matcher interface {\n\t// Matches returns whether x is a match.\n\tMatches(x any) bool\n\n\t// String describes what the matcher matches.\n\tString() string\n}\n\n// WantFormatter modifies the given Matcher's String() method to the given\n// Stringer. This allows for control on how the \"Want\" is formatted when\n// printing .\nfunc WantFormatter(s fmt.Stringer, m Matcher) Matcher {\n\ttype matcher interface {\n\t\tMatches(x any) bool\n\t}\n\n\treturn struct {\n\t\tmatcher\n\t\tfmt.Stringer\n\t}{\n\t\tmatcher:  m,\n\t\tStringer: s,\n\t}\n}\n\n// StringerFunc type is an adapter to allow the use of ordinary functions as\n// a Stringer. If f is a function with the appropriate signature,\n// StringerFunc(f) is a Stringer that calls f.\ntype StringerFunc func() string\n\n// String implements fmt.Stringer.\nfunc (f StringerFunc) String() string {\n\treturn f()\n}\n\n// GotFormatter is used to better print failure messages. If a matcher\n// implements GotFormatter, it will use the result from Got when printing\n// the failure message.\ntype GotFormatter interface {\n\t// Got is invoked with the received value. The result is used when\n\t// printing the failure message.\n\tGot(got any) string\n}\n\n// GotFormatterFunc type is an adapter to allow the use of ordinary\n// functions as a GotFormatter. If f is a function with the appropriate\n// signature, GotFormatterFunc(f) is a GotFormatter that calls f.\ntype GotFormatterFunc func(got any) string\n\n// Got implements GotFormatter.\nfunc (f GotFormatterFunc) Got(got any) string {\n\treturn f(got)\n}\n\n// GotFormatterAdapter attaches a GotFormatter to a Matcher.\nfunc GotFormatterAdapter(s GotFormatter, m Matcher) Matcher {\n\treturn struct {\n\t\tGotFormatter\n\t\tMatcher\n\t}{\n\t\tGotFormatter: s,\n\t\tMatcher:      m,\n\t}\n}\n\ntype anyMatcher struct{}\n\nfunc (anyMatcher) Matches(any) bool {\n\treturn true\n}\n\nfunc (anyMatcher) String() string {\n\treturn \"is anything\"\n}\n\ntype condMatcher[T any] struct {\n\tfn func(x T) bool\n}\n\nfunc (c condMatcher[T]) Matches(x any) bool {\n\ttyped, ok := x.(T)\n\tif !ok {\n\t\treturn false\n\t}\n\treturn c.fn(typed)\n}\n\nfunc (c condMatcher[T]) String() string {\n\treturn \"adheres to a custom condition\"\n}\n\ntype eqMatcher struct {\n\tx any\n}\n\nfunc (e eqMatcher) Matches(x any) bool {\n\t// In case, some value is nil\n\tif e.x == nil || x == nil {\n\t\treturn reflect.DeepEqual(e.x, x)\n\t}\n\n\t// Check if types assignable and convert them to common type\n\tx1Val := reflect.ValueOf(e.x)\n\tx2Val := reflect.ValueOf(x)\n\n\tif x1Val.Type().AssignableTo(x2Val.Type()) {\n\t\tx1ValConverted := x1Val.Convert(x2Val.Type())\n\t\treturn reflect.DeepEqual(x1ValConverted.Interface(), x2Val.Interface())\n\t}\n\n\treturn false\n}\n\nfunc (e eqMatcher) String() string {\n\treturn fmt.Sprintf(\"is equal to %s (%T)\", getString(e.x), e.x)\n}\n\ntype nilMatcher struct{}\n\nfunc (nilMatcher) Matches(x any) bool {\n\tif x == nil {\n\t\treturn true\n\t}\n\n\tv := reflect.ValueOf(x)\n\tswitch v.Kind() {\n\tcase reflect.Chan, reflect.Func, reflect.Interface, reflect.Map,\n\t\treflect.Ptr, reflect.Slice:\n\t\treturn v.IsNil()\n\t}\n\n\treturn false\n}\n\nfunc (nilMatcher) String() string {\n\treturn \"is nil\"\n}\n\ntype notMatcher struct {\n\tm Matcher\n}\n\nfunc (n notMatcher) Matches(x any) bool {\n\treturn !n.m.Matches(x)\n}\n\nfunc (n notMatcher) String() string {\n\treturn \"not(\" + n.m.String() + \")\"\n}\n\ntype regexMatcher struct {\n\tregex *regexp.Regexp\n}\n\nfunc (m regexMatcher) Matches(x any) bool {\n\tswitch t := x.(type) {\n\tcase string:\n\t\treturn m.regex.MatchString(t)\n\tcase []byte:\n\t\treturn m.regex.Match(t)\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc (m regexMatcher) String() string {\n\treturn \"matches regex \" + m.regex.String()\n}\n\ntype assignableToTypeOfMatcher struct {\n\ttargetType reflect.Type\n}\n\nfunc (m assignableToTypeOfMatcher) Matches(x any) bool {\n\treturn reflect.TypeOf(x).AssignableTo(m.targetType)\n}\n\nfunc (m assignableToTypeOfMatcher) String() string {\n\treturn \"is assignable to \" + m.targetType.Name()\n}\n\ntype anyOfMatcher struct {\n\tmatchers []Matcher\n}\n\nfunc (am anyOfMatcher) Matches(x any) bool {\n\tfor _, m := range am.matchers {\n\t\tif m.Matches(x) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (am anyOfMatcher) String() string {\n\tss := make([]string, 0, len(am.matchers))\n\tfor _, matcher := range am.matchers {\n\t\tss = append(ss, matcher.String())\n\t}\n\treturn strings.Join(ss, \" | \")\n}\n\ntype allMatcher struct {\n\tmatchers []Matcher\n}\n\nfunc (am allMatcher) Matches(x any) bool {\n\tfor _, m := range am.matchers {\n\t\tif !m.Matches(x) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (am allMatcher) String() string {\n\tss := make([]string, 0, len(am.matchers))\n\tfor _, matcher := range am.matchers {\n\t\tss = append(ss, matcher.String())\n\t}\n\treturn strings.Join(ss, \"; \")\n}\n\ntype lenMatcher struct {\n\ti int\n}\n\nfunc (m lenMatcher) Matches(x any) bool {\n\tv := reflect.ValueOf(x)\n\tswitch v.Kind() {\n\tcase reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:\n\t\treturn v.Len() == m.i\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc (m lenMatcher) String() string {\n\treturn fmt.Sprintf(\"has length %d\", m.i)\n}\n\ntype inAnyOrderMatcher struct {\n\tx any\n}\n\nfunc (m inAnyOrderMatcher) Matches(x any) bool {\n\tgiven, ok := m.prepareValue(x)\n\tif !ok {\n\t\treturn false\n\t}\n\twanted, ok := m.prepareValue(m.x)\n\tif !ok {\n\t\treturn false\n\t}\n\n\tif given.Len() != wanted.Len() {\n\t\treturn false\n\t}\n\n\tusedFromGiven := make([]bool, given.Len())\n\tfoundFromWanted := make([]bool, wanted.Len())\n\tfor i := 0; i < wanted.Len(); i++ {\n\t\twantedMatcher := Eq(wanted.Index(i).Interface())\n\t\tfor j := 0; j < given.Len(); j++ {\n\t\t\tif usedFromGiven[j] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif wantedMatcher.Matches(given.Index(j).Interface()) {\n\t\t\t\tfoundFromWanted[i] = true\n\t\t\t\tusedFromGiven[j] = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tmissingFromWanted := 0\n\tfor _, found := range foundFromWanted {\n\t\tif !found {\n\t\t\tmissingFromWanted++\n\t\t}\n\t}\n\textraInGiven := 0\n\tfor _, used := range usedFromGiven {\n\t\tif !used {\n\t\t\textraInGiven++\n\t\t}\n\t}\n\n\treturn extraInGiven == 0 && missingFromWanted == 0\n}\n\nfunc (m inAnyOrderMatcher) prepareValue(x any) (reflect.Value, bool) {\n\txValue := reflect.ValueOf(x)\n\tswitch xValue.Kind() {\n\tcase reflect.Slice, reflect.Array:\n\t\treturn xValue, true\n\tdefault:\n\t\treturn reflect.Value{}, false\n\t}\n}\n\nfunc (m inAnyOrderMatcher) String() string {\n\treturn fmt.Sprintf(\"has the same elements as %v\", m.x)\n}\n\n// Constructors\n\n// All returns a composite Matcher that returns true if and only all of the\n// matchers return true.\nfunc All(ms ...Matcher) Matcher { return allMatcher{ms} }\n\n// Any returns a matcher that always matches.\nfunc Any() Matcher { return anyMatcher{} }\n\n// Cond returns a matcher that matches when the given function returns true\n// after passing it the parameter to the mock function.\n// This is particularly useful in case you want to match over a field of a custom struct, or dynamic logic.\n//\n// Example usage:\n//\n//\tCond(func(x int){return x == 1}).Matches(1) // returns true\n//\tCond(func(x int){return x == 2}).Matches(1) // returns false\nfunc Cond[T any](fn func(x T) bool) Matcher { return condMatcher[T]{fn} }\n\n// AnyOf returns a composite Matcher that returns true if at least one of the\n// matchers returns true.\n//\n// Example usage:\n//\n//\tAnyOf(1, 2, 3).Matches(2) // returns true\n//\tAnyOf(1, 2, 3).Matches(10) // returns false\n//\tAnyOf(Nil(), Len(2)).Matches(nil) // returns true\n//\tAnyOf(Nil(), Len(2)).Matches(\"hi\") // returns true\n//\tAnyOf(Nil(), Len(2)).Matches(\"hello\") // returns false\nfunc AnyOf(xs ...any) Matcher {\n\tms := make([]Matcher, 0, len(xs))\n\tfor _, x := range xs {\n\t\tif m, ok := x.(Matcher); ok {\n\t\t\tms = append(ms, m)\n\t\t} else {\n\t\t\tms = append(ms, Eq(x))\n\t\t}\n\t}\n\treturn anyOfMatcher{ms}\n}\n\n// Eq returns a matcher that matches on equality.\n//\n// Example usage:\n//\n//\tEq(5).Matches(5) // returns true\n//\tEq(5).Matches(4) // returns false\nfunc Eq(x any) Matcher { return eqMatcher{x} }\n\n// Len returns a matcher that matches on length. This matcher returns false if\n// is compared to a type that is not an array, chan, map, slice, or string.\nfunc Len(i int) Matcher {\n\treturn lenMatcher{i}\n}\n\n// Nil returns a matcher that matches if the received value is nil.\n//\n// Example usage:\n//\n//\tvar x *bytes.Buffer\n//\tNil().Matches(x) // returns true\n//\tx = &bytes.Buffer{}\n//\tNil().Matches(x) // returns false\nfunc Nil() Matcher { return nilMatcher{} }\n\n// Not reverses the results of its given child matcher.\n//\n// Example usage:\n//\n//\tNot(Eq(5)).Matches(4) // returns true\n//\tNot(Eq(5)).Matches(5) // returns false\nfunc Not(x any) Matcher {\n\tif m, ok := x.(Matcher); ok {\n\t\treturn notMatcher{m}\n\t}\n\treturn notMatcher{Eq(x)}\n}\n\n// Regex checks whether parameter matches the associated regex.\n//\n// Example usage:\n//\n//\tRegex(\"[0-9]{2}:[0-9]{2}\").Matches(\"23:02\") // returns true\n//\tRegex(\"[0-9]{2}:[0-9]{2}\").Matches([]byte{'2', '3', ':', '0', '2'}) // returns true\n//\tRegex(\"[0-9]{2}:[0-9]{2}\").Matches(\"hello world\") // returns false\n//\tRegex(\"[0-9]{2}\").Matches(21) // returns false as it's not a valid type\nfunc Regex(regexStr string) Matcher {\n\treturn regexMatcher{regex: regexp.MustCompile(regexStr)}\n}\n\n// AssignableToTypeOf is a Matcher that matches if the parameter to the mock\n// function is assignable to the type of the parameter to this function.\n//\n// Example usage:\n//\n//\tvar s fmt.Stringer = &bytes.Buffer{}\n//\tAssignableToTypeOf(s).Matches(time.Second) // returns true\n//\tAssignableToTypeOf(s).Matches(99) // returns false\n//\n//\tvar ctx = reflect.TypeOf((*context.Context)(nil)).Elem()\n//\tAssignableToTypeOf(ctx).Matches(context.Background()) // returns true\nfunc AssignableToTypeOf(x any) Matcher {\n\tif xt, ok := x.(reflect.Type); ok {\n\t\treturn assignableToTypeOfMatcher{xt}\n\t}\n\treturn assignableToTypeOfMatcher{reflect.TypeOf(x)}\n}\n\n// InAnyOrder is a Matcher that returns true for collections of the same elements ignoring the order.\n//\n// Example usage:\n//\n//\tInAnyOrder([]int{1, 2, 3}).Matches([]int{1, 3, 2}) // returns true\n//\tInAnyOrder([]int{1, 2, 3}).Matches([]int{1, 2}) // returns false\nfunc InAnyOrder(x any) Matcher {\n\treturn inAnyOrderMatcher{x}\n}\n"
  },
  {
    "path": "vendor/go.uber.org/mock/gomock/string.go",
    "content": "package gomock\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\n// getString is a safe way to convert a value to a string for printing results\n// If the value is a a mock, getString avoids calling the mocked String() method,\n// which avoids potential deadlocks\nfunc getString(x any) string {\n\tif isGeneratedMock(x) {\n\t\treturn fmt.Sprintf(\"%T\", x)\n\t}\n\tif s, ok := x.(fmt.Stringer); ok {\n\t\treturn s.String()\n\t}\n\treturn fmt.Sprintf(\"%v\", x)\n}\n\n// isGeneratedMock checks if the given type has a \"isgomock\" field,\n// indicating it is a generated mock.\nfunc isGeneratedMock(x any) bool {\n\ttyp := reflect.TypeOf(x)\n\tif typ == nil {\n\t\treturn false\n\t}\n\tif typ.Kind() == reflect.Ptr {\n\t\ttyp = typ.Elem()\n\t}\n\tif typ.Kind() != reflect.Struct {\n\t\treturn false\n\t}\n\t_, isgomock := typ.FieldByName(\"isgomock\")\n\treturn isgomock\n}\n"
  },
  {
    "path": "vendor/go.uber.org/mock/mockgen/deprecated.go",
    "content": "package main\n\nimport (\n\t\"flag\"\n\t\"log\"\n\t\"os\"\n)\n\nconst (\n\tdeprecatedFlagProgOnly = \"prog_only\"\n\tdeprecatedFlagExecOnly = \"exec_only\"\n)\n\nvar (\n\t_ = flag.Bool(\"prog_only\", false, \"DEPRECATED (reflect mode) Only generate the reflection program; write it to stdout and exit.\")\n\t_ = flag.String(\"exec_only\", \"\", \"DEPRECATED (reflect mode) If set, execute this reflection program.\")\n)\n\n// notifyAboutDeprecatedFlags prints a warning message for a deprecated flags if they are set.\nfunc notifyAboutDeprecatedFlags() {\n\tconst resetColorPostfix = \"\\033[0m\"\n\tlogger := initWarningLogger()\n\n\tflag.Visit(func(f *flag.Flag) {\n\t\tswitch f.Name {\n\t\tcase deprecatedFlagProgOnly:\n\t\t\tlogger.Println(\"The -prog_only flag is deprecated and has no effect.\", resetColorPostfix)\n\t\tcase deprecatedFlagExecOnly:\n\t\t\tlogger.Println(\"The -exec_only flag is deprecated and has no effect.\", resetColorPostfix)\n\t\t}\n\t})\n}\n\nfunc initWarningLogger() *log.Logger {\n\tconst (\n\t\tyellowColor   = \"\\033[33m\"\n\t\twarningPrefix = yellowColor + \"WARNING: \"\n\t)\n\n\treturn log.New(os.Stdout, warningPrefix, log.Ldate|log.Ltime)\n}\n"
  },
  {
    "path": "vendor/go.uber.org/mock/mockgen/generic.go",
    "content": "// Copyright 2022 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"go/ast\"\n\t\"go/token\"\n\n\t\"go.uber.org/mock/mockgen/model\"\n)\n\nfunc getTypeSpecTypeParams(ts *ast.TypeSpec) []*ast.Field {\n\tif ts == nil || ts.TypeParams == nil {\n\t\treturn nil\n\t}\n\treturn ts.TypeParams.List\n}\n\nfunc (p *fileParser) parseGenericType(pkg string, typ ast.Expr, tps map[string]model.Type) (model.Type, error) {\n\tswitch v := typ.(type) {\n\tcase *ast.IndexExpr:\n\t\tm, err := p.parseType(pkg, v.X, tps)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tnm, ok := m.(*model.NamedType)\n\t\tif !ok {\n\t\t\treturn m, nil\n\t\t}\n\t\tt, err := p.parseType(pkg, v.Index, tps)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tnm.TypeParams = &model.TypeParametersType{TypeParameters: []model.Type{t}}\n\t\treturn m, nil\n\tcase *ast.IndexListExpr:\n\t\tm, err := p.parseType(pkg, v.X, tps)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tnm, ok := m.(*model.NamedType)\n\t\tif !ok {\n\t\t\treturn m, nil\n\t\t}\n\t\tvar ts []model.Type\n\t\tfor _, expr := range v.Indices {\n\t\t\tt, err := p.parseType(pkg, expr, tps)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tts = append(ts, t)\n\t\t}\n\t\tnm.TypeParams = &model.TypeParametersType{TypeParameters: ts}\n\t\treturn m, nil\n\t}\n\treturn nil, nil\n}\n\nfunc (p *fileParser) parseGenericMethod(field *ast.Field, it *namedInterface, iface *model.Interface, pkg string, tps map[string]model.Type) ([]*model.Method, error) {\n\tvar indices []ast.Expr\n\tvar typ ast.Expr\n\tswitch v := field.Type.(type) {\n\tcase *ast.IndexExpr:\n\t\tindices = []ast.Expr{v.Index}\n\t\ttyp = v.X\n\tcase *ast.IndexListExpr:\n\t\tindices = v.Indices\n\t\ttyp = v.X\n\tcase *ast.UnaryExpr:\n\t\tif v.Op == token.TILDE {\n\t\t\treturn nil, errConstraintInterface\n\t\t}\n\t\treturn nil, fmt.Errorf(\"~T may only appear as constraint for %T\", field.Type)\n\tcase *ast.BinaryExpr:\n\t\tif v.Op == token.OR {\n\t\t\treturn nil, errConstraintInterface\n\t\t}\n\t\treturn nil, fmt.Errorf(\"A|B may only appear as constraint for %T\", field.Type)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"don't know how to mock method of type %T\", field.Type)\n\t}\n\n\tnf := &ast.Field{\n\t\tDoc:     field.Comment,\n\t\tNames:   field.Names,\n\t\tType:    typ,\n\t\tTag:     field.Tag,\n\t\tComment: field.Comment,\n\t}\n\n\tit.embeddedInstTypeParams = indices\n\n\treturn p.parseMethod(nf, it, iface, pkg, tps)\n}\n\nvar errConstraintInterface = errors.New(\"interface contains constraints\")\n"
  },
  {
    "path": "vendor/go.uber.org/mock/mockgen/gob.go",
    "content": "package main\n\nimport (\n\t\"encoding/gob\"\n\t\"os\"\n\n\t\"go.uber.org/mock/mockgen/model\"\n)\n\nfunc gobMode(path string) (*model.Package, error) {\n\tin, err := os.Open(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer in.Close()\n\tvar pkg model.Package\n\tif err := gob.NewDecoder(in).Decode(&pkg); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &pkg, nil\n}\n"
  },
  {
    "path": "vendor/go.uber.org/mock/mockgen/mockgen.go",
    "content": "// Copyright 2010 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// MockGen generates mock implementations of Go interfaces.\npackage main\n\n// TODO: This does not support recursive embedded interfaces.\n// TODO: This does not support embedding package-local interfaces in a separate file.\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"flag\"\n\t\"fmt\"\n\t\"go/token\"\n\t\"io\"\n\t\"log\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\"golang.org/x/mod/modfile\"\n\ttoolsimports \"golang.org/x/tools/imports\"\n\n\t\"go.uber.org/mock/mockgen/model\"\n)\n\nconst (\n\tgomockImportPath = \"go.uber.org/mock/gomock\"\n)\n\nvar (\n\tversion = \"\"\n\tcommit  = \"none\"\n\tdate    = \"unknown\"\n)\n\nvar (\n\tsource                 = flag.String(\"source\", \"\", \"(source mode) Input Go source file; enables source mode.\")\n\tdestination            = flag.String(\"destination\", \"\", \"Output file; defaults to stdout.\")\n\tmockNames              = flag.String(\"mock_names\", \"\", \"Comma-separated interfaceName=mockName pairs of explicit mock names to use. Mock names default to 'Mock'+ interfaceName suffix.\")\n\tpackageOut             = flag.String(\"package\", \"\", \"Package of the generated code; defaults to the package of the input with a 'mock_' prefix.\")\n\tselfPackage            = flag.String(\"self_package\", \"\", \"The full package import path for the generated code. The purpose of this flag is to prevent import cycles in the generated code by trying to include its own package. This can happen if the mock's package is set to one of its inputs (usually the main one) and the output is stdio so mockgen cannot detect the final output package. Setting this flag will then tell mockgen which import to exclude.\")\n\twriteCmdComment        = flag.Bool(\"write_command_comment\", true, \"Writes the command used as a comment if true.\")\n\twritePkgComment        = flag.Bool(\"write_package_comment\", true, \"Writes package documentation comment (godoc) if true.\")\n\twriteSourceComment     = flag.Bool(\"write_source_comment\", true, \"Writes original file (source mode) or interface names (package mode) comment if true.\")\n\twriteGenerateDirective = flag.Bool(\"write_generate_directive\", false, \"Add //go:generate directive to regenerate the mock\")\n\tcopyrightFile          = flag.String(\"copyright_file\", \"\", \"Copyright file used to add copyright header\")\n\tbuildConstraint        = flag.String(\"build_constraint\", \"\", \"If non-empty, added as //go:build <constraint>\")\n\ttyped                  = flag.Bool(\"typed\", false, \"Generate Type-safe 'Return', 'Do', 'DoAndReturn' function\")\n\timports                = flag.String(\"imports\", \"\", \"(source mode) Comma-separated name=path pairs of explicit imports to use.\")\n\tauxFiles               = flag.String(\"aux_files\", \"\", \"(source mode) Comma-separated pkg=path pairs of auxiliary Go source files.\")\n\texcludeInterfaces      = flag.String(\"exclude_interfaces\", \"\", \"(source mode) Comma-separated names of interfaces to be excluded\")\n\tmodelGob               = flag.String(\"model_gob\", \"\", \"Skip package/source loading entirely and use the gob encoded model.Package at the given path\")\n\n\tdebugParser = flag.Bool(\"debug_parser\", false, \"Print out parser results only.\")\n\tshowVersion = flag.Bool(\"version\", false, \"Print version.\")\n)\n\nfunc main() {\n\tflag.Usage = usage\n\tflag.Parse()\n\n\tnotifyAboutDeprecatedFlags()\n\n\tif *showVersion {\n\t\tprintVersion()\n\t\treturn\n\t}\n\n\tvar pkg *model.Package\n\tvar err error\n\tvar packageName string\n\tif *modelGob != \"\" {\n\t\tpkg, err = gobMode(*modelGob)\n\t} else if *source != \"\" {\n\t\tpkg, err = sourceMode(*source)\n\t} else {\n\t\tif flag.NArg() != 2 {\n\t\t\tusage()\n\t\t\tlog.Fatal(\"Expected exactly two arguments\")\n\t\t}\n\t\tpackageName = flag.Arg(0)\n\t\tinterfaces := strings.Split(flag.Arg(1), \",\")\n\t\tif packageName == \".\" {\n\t\t\tdir, err := os.Getwd()\n\t\t\tif err != nil {\n\t\t\t\tlog.Fatalf(\"Get current directory failed: %v\", err)\n\t\t\t}\n\t\t\tpackageName, err = packageNameOfDir(dir)\n\t\t\tif err != nil {\n\t\t\t\tlog.Fatalf(\"Parse package name failed: %v\", err)\n\t\t\t}\n\t\t}\n\t\tparser := packageModeParser{}\n\t\tpkg, err = parser.parsePackage(packageName, interfaces)\n\t}\n\tif err != nil {\n\t\tlog.Fatalf(\"Loading input failed: %v\", err)\n\t}\n\n\tif *debugParser {\n\t\tpkg.Print(os.Stdout)\n\t\treturn\n\t}\n\n\toutputPackageName := *packageOut\n\tif outputPackageName == \"\" {\n\t\t// pkg.Name in package mode is the base name of the import path,\n\t\t// which might have characters that are illegal to have in package names.\n\t\toutputPackageName = \"mock_\" + sanitize(pkg.Name)\n\t}\n\n\t// outputPackagePath represents the fully qualified name of the package of\n\t// the generated code. Its purposes are to prevent the module from importing\n\t// itself and to prevent qualifying type names that come from its own\n\t// package (i.e. if there is a type called X then we want to print \"X\" not\n\t// \"package.X\" since \"package\" is this package). This can happen if the mock\n\t// is output into an already existing package.\n\toutputPackagePath := *selfPackage\n\tif outputPackagePath == \"\" && *destination != \"\" {\n\t\tdstPath, err := filepath.Abs(filepath.Dir(*destination))\n\t\tif err == nil {\n\t\t\tpkgPath, err := parsePackageImport(dstPath)\n\t\t\tif err == nil {\n\t\t\t\toutputPackagePath = pkgPath\n\t\t\t} else {\n\t\t\t\tlog.Println(\"Unable to infer -self_package from destination file path:\", err)\n\t\t\t}\n\t\t} else {\n\t\t\tlog.Println(\"Unable to determine destination file path:\", err)\n\t\t}\n\t}\n\n\tg := &generator{\n\t\tbuildConstraint: *buildConstraint,\n\t}\n\tif *source != \"\" {\n\t\tg.filename = *source\n\t} else {\n\t\tg.srcPackage = packageName\n\t\tg.srcInterfaces = flag.Arg(1)\n\t}\n\tg.destination = *destination\n\n\tif *mockNames != \"\" {\n\t\tg.mockNames = parseMockNames(*mockNames)\n\t}\n\tif *copyrightFile != \"\" {\n\t\theader, err := os.ReadFile(*copyrightFile)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"Failed reading copyright file: %v\", err)\n\t\t}\n\n\t\tg.copyrightHeader = string(header)\n\t}\n\tif err := g.Generate(pkg, outputPackageName, outputPackagePath); err != nil {\n\t\tlog.Fatalf(\"Failed generating mock: %v\", err)\n\t}\n\toutput := g.Output()\n\tdst := os.Stdout\n\tif len(*destination) > 0 {\n\t\tif err := os.MkdirAll(filepath.Dir(*destination), os.ModePerm); err != nil {\n\t\t\tlog.Fatalf(\"Unable to create directory: %v\", err)\n\t\t}\n\t\texisting, err := os.ReadFile(*destination)\n\t\tif err != nil && !errors.Is(err, os.ErrNotExist) {\n\t\t\tlog.Fatalf(\"Failed reading pre-exiting destination file: %v\", err)\n\t\t}\n\t\tif len(existing) == len(output) && bytes.Equal(existing, output) {\n\t\t\treturn\n\t\t}\n\t\tf, err := os.Create(*destination)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"Failed opening destination file: %v\", err)\n\t\t}\n\t\tdefer f.Close()\n\t\tdst = f\n\t}\n\tif _, err := dst.Write(output); err != nil {\n\t\tlog.Fatalf(\"Failed writing to destination: %v\", err)\n\t}\n}\n\nfunc parseMockNames(names string) map[string]string {\n\tmocksMap := make(map[string]string)\n\tfor _, kv := range strings.Split(names, \",\") {\n\t\tparts := strings.SplitN(kv, \"=\", 2)\n\t\tif len(parts) != 2 || parts[1] == \"\" {\n\t\t\tlog.Fatalf(\"bad mock names spec: %v\", kv)\n\t\t}\n\t\tmocksMap[parts[0]] = parts[1]\n\t}\n\treturn mocksMap\n}\n\nfunc parseExcludeInterfaces(names string) map[string]struct{} {\n\tsplitNames := strings.Split(names, \",\")\n\tnamesSet := make(map[string]struct{}, len(splitNames))\n\tfor _, name := range splitNames {\n\t\tif name == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tnamesSet[name] = struct{}{}\n\t}\n\n\tif len(namesSet) == 0 {\n\t\treturn nil\n\t}\n\n\treturn namesSet\n}\n\nfunc usage() {\n\t_, _ = io.WriteString(os.Stderr, usageText)\n\tflag.PrintDefaults()\n}\n\nconst usageText = `mockgen has two modes of operation: source and package.\n\nSource mode generates mock interfaces from a source file.\nIt is enabled by using the -source flag. Other flags that\nmay be useful in this mode are -imports, -aux_files and -exclude_interfaces.\nExample:\n\tmockgen -source=foo.go [other options]\n\nPackage mode works by specifying the package and interface names.\nIt is enabled by passing two non-flag arguments: an import path, and a\ncomma-separated list of symbols. \nYou can use \".\" to refer to the current path's package.\nExample:\n\tmockgen database/sql/driver Conn,Driver\n\tmockgen . SomeInterface\n\n`\n\ntype generator struct {\n\tbuf                       bytes.Buffer\n\tindent                    string\n\tmockNames                 map[string]string // may be empty\n\tfilename                  string            // may be empty\n\tdestination               string            // may be empty\n\tsrcPackage, srcInterfaces string            // may be empty\n\tcopyrightHeader           string\n\tbuildConstraint           string // may be empty\n\n\tpackageMap map[string]string // map from import path to package name\n}\n\nfunc (g *generator) p(format string, args ...any) {\n\t_, _ = fmt.Fprintf(&g.buf, g.indent+format+\"\\n\", args...)\n}\n\nfunc (g *generator) in() {\n\tg.indent += \"\\t\"\n}\n\nfunc (g *generator) out() {\n\tif len(g.indent) > 0 {\n\t\tg.indent = g.indent[0 : len(g.indent)-1]\n\t}\n}\n\n// sanitize cleans up a string to make a suitable package name.\nfunc sanitize(s string) string {\n\tt := \"\"\n\tfor _, r := range s {\n\t\tif t == \"\" {\n\t\t\tif unicode.IsLetter(r) || r == '_' {\n\t\t\t\tt += string(r)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t} else {\n\t\t\tif unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' {\n\t\t\t\tt += string(r)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tt += \"_\"\n\t}\n\tif t == \"_\" {\n\t\tt = \"x\"\n\t}\n\treturn t\n}\n\nfunc (g *generator) Generate(pkg *model.Package, outputPkgName string, outputPackagePath string) error {\n\tif outputPkgName != pkg.Name && *selfPackage == \"\" {\n\t\t// reset outputPackagePath if it's not passed in through -self_package\n\t\toutputPackagePath = \"\"\n\t}\n\n\tif g.copyrightHeader != \"\" {\n\t\tlines := strings.Split(g.copyrightHeader, \"\\n\")\n\t\tfor _, line := range lines {\n\t\t\tg.p(\"// %s\", line)\n\t\t}\n\t\tg.p(\"\")\n\t}\n\n\tif g.buildConstraint != \"\" {\n\t\tg.p(\"//go:build %s\", g.buildConstraint)\n\t\t// https://pkg.go.dev/cmd/go#hdr-Build_constraints:~:text=a%20build%20constraint%20should%20be%20followed%20by%20a%20blank%20line\n\t\tg.p(\"\")\n\t}\n\n\tg.p(\"// Code generated by MockGen. DO NOT EDIT.\")\n\tif *writeSourceComment {\n\t\tif g.filename != \"\" {\n\t\t\tg.p(\"// Source: %v\", g.filename)\n\t\t} else {\n\t\t\tg.p(\"// Source: %v (interfaces: %v)\", g.srcPackage, g.srcInterfaces)\n\t\t}\n\t}\n\tif *writeCmdComment {\n\t\tg.p(\"//\")\n\t\tg.p(\"// Generated by this command:\")\n\t\tg.p(\"//\")\n\t\t// only log the name of the executable, not the full path\n\t\tname := filepath.Base(os.Args[0])\n\t\tif runtime.GOOS == \"windows\" {\n\t\t\tname = strings.TrimSuffix(name, \".exe\")\n\t\t}\n\t\tg.p(\"//\\t%v\", strings.Join(append([]string{name}, os.Args[1:]...), \" \"))\n\t\tg.p(\"//\")\n\t}\n\n\t// Get all required imports, and generate unique names for them all.\n\tim := pkg.Imports()\n\tim[gomockImportPath] = true\n\n\t// Only import reflect if it's used. We only use reflect in mocked methods\n\t// so only import if any of the mocked interfaces have methods.\n\tfor _, intf := range pkg.Interfaces {\n\t\tif len(intf.Methods) > 0 {\n\t\t\tim[\"reflect\"] = true\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Sort keys to make import alias generation predictable\n\tsortedPaths := make([]string, len(im))\n\tx := 0\n\tfor pth := range im {\n\t\tsortedPaths[x] = pth\n\t\tx++\n\t}\n\tsort.Strings(sortedPaths)\n\n\tpackagesName := createPackageMap(sortedPaths)\n\n\tdefinedImports := make(map[string]string, len(im))\n\tif *imports != \"\" {\n\t\tfor _, kv := range strings.Split(*imports, \",\") {\n\t\t\teq := strings.Index(kv, \"=\")\n\t\t\tif k, v := kv[:eq], kv[eq+1:]; k != \".\" {\n\t\t\t\tdefinedImports[v] = k\n\t\t\t}\n\t\t}\n\t}\n\n\tg.packageMap = make(map[string]string, len(im))\n\tlocalNames := make(map[string]bool, len(im))\n\tfor _, pth := range sortedPaths {\n\t\tbase, ok := packagesName[pth]\n\t\tif !ok {\n\t\t\tbase = sanitize(path.Base(pth))\n\t\t}\n\n\t\t// Local names for an imported package can usually be the basename of the import path.\n\t\t// A couple of situations don't permit that, such as duplicate local names\n\t\t// (e.g. importing \"html/template\" and \"text/template\"), or where the basename is\n\t\t// a keyword (e.g. \"foo/case\") or when defining a name for that by using the -imports flag.\n\t\t// try base0, base1, ...\n\t\tpkgName := base\n\n\t\tif _, ok := definedImports[pth]; ok {\n\t\t\tpkgName = definedImports[pth]\n\t\t}\n\n\t\ti := 0\n\t\tfor localNames[pkgName] || token.Lookup(pkgName).IsKeyword() || pkgName == \"any\" {\n\t\t\tpkgName = base + strconv.Itoa(i)\n\t\t\ti++\n\t\t}\n\n\t\t// Avoid importing package if source pkg == output pkg\n\t\tif pth == pkg.PkgPath && outputPackagePath == pkg.PkgPath {\n\t\t\tcontinue\n\t\t}\n\n\t\tg.packageMap[pth] = pkgName\n\t\tlocalNames[pkgName] = true\n\t}\n\n\t// Ensure there is an empty line between “generated by” block and\n\t// package documentation comments to follow the recommendations:\n\t// https://go.dev/wiki/CodeReviewComments#package-comments\n\t// That is, “generated by” should not be a package comment.\n\tg.p(\"\")\n\n\tif *writePkgComment {\n\t\tg.p(\"// Package %v is a generated GoMock package.\", outputPkgName)\n\t}\n\tg.p(\"package %v\", outputPkgName)\n\tg.p(\"\")\n\tg.p(\"import (\")\n\tg.in()\n\tfor pkgPath, pkgName := range g.packageMap {\n\t\tif pkgPath == outputPackagePath {\n\t\t\tcontinue\n\t\t}\n\t\tg.p(\"%v %q\", pkgName, pkgPath)\n\t}\n\tfor _, pkgPath := range pkg.DotImports {\n\t\tg.p(\". %q\", pkgPath)\n\t}\n\tg.out()\n\tg.p(\")\")\n\n\tif *writeGenerateDirective {\n\t\tg.p(\"//go:generate %v\", strings.Join(os.Args, \" \"))\n\t}\n\n\tfor _, intf := range pkg.Interfaces {\n\t\tif err := g.GenerateMockInterface(intf, outputPackagePath); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// The name of the mock type to use for the given interface identifier.\nfunc (g *generator) mockName(typeName string) string {\n\tif mockName, ok := g.mockNames[typeName]; ok {\n\t\treturn mockName\n\t}\n\n\treturn \"Mock\" + typeName\n}\n\n// formattedTypeParams returns a long and short form of type param info used for\n// printing. If analyzing a interface with type param [I any, O any] the result\n// will be:\n// \"[I any, O any]\", \"[I, O]\"\nfunc (g *generator) formattedTypeParams(it *model.Interface, pkgOverride string) (string, string) {\n\tif len(it.TypeParams) == 0 {\n\t\treturn \"\", \"\"\n\t}\n\tvar long, short strings.Builder\n\tlong.WriteString(\"[\")\n\tshort.WriteString(\"[\")\n\tfor i, v := range it.TypeParams {\n\t\tif i != 0 {\n\t\t\tlong.WriteString(\", \")\n\t\t\tshort.WriteString(\", \")\n\t\t}\n\t\tlong.WriteString(v.Name)\n\t\tshort.WriteString(v.Name)\n\t\tlong.WriteString(fmt.Sprintf(\" %s\", v.Type.String(g.packageMap, pkgOverride)))\n\t}\n\tlong.WriteString(\"]\")\n\tshort.WriteString(\"]\")\n\treturn long.String(), short.String()\n}\n\nfunc (g *generator) GenerateMockInterface(intf *model.Interface, outputPackagePath string) error {\n\tmockType := g.mockName(intf.Name)\n\tlongTp, shortTp := g.formattedTypeParams(intf, outputPackagePath)\n\n\tg.p(\"\")\n\tg.p(\"// %v is a mock of %v interface.\", mockType, intf.Name)\n\tg.p(\"type %v%v struct {\", mockType, longTp)\n\tg.in()\n\tg.p(\"ctrl     *gomock.Controller\")\n\tg.p(\"recorder *%vMockRecorder%v\", mockType, shortTp)\n\tg.p(\"isgomock struct{}\")\n\tg.out()\n\tg.p(\"}\")\n\tg.p(\"\")\n\n\tg.p(\"// %vMockRecorder is the mock recorder for %v.\", mockType, mockType)\n\tg.p(\"type %vMockRecorder%v struct {\", mockType, longTp)\n\tg.in()\n\tg.p(\"mock *%v%v\", mockType, shortTp)\n\tg.out()\n\tg.p(\"}\")\n\tg.p(\"\")\n\n\tg.p(\"// New%v creates a new mock instance.\", mockType)\n\tg.p(\"func New%v%v(ctrl *gomock.Controller) *%v%v {\", mockType, longTp, mockType, shortTp)\n\tg.in()\n\tg.p(\"mock := &%v%v{ctrl: ctrl}\", mockType, shortTp)\n\tg.p(\"mock.recorder = &%vMockRecorder%v{mock}\", mockType, shortTp)\n\tg.p(\"return mock\")\n\tg.out()\n\tg.p(\"}\")\n\tg.p(\"\")\n\n\t// XXX: possible name collision here if someone has EXPECT in their interface.\n\tg.p(\"// EXPECT returns an object that allows the caller to indicate expected use.\")\n\tg.p(\"func (m *%v%v) EXPECT() *%vMockRecorder%v {\", mockType, shortTp, mockType, shortTp)\n\tg.in()\n\tg.p(\"return m.recorder\")\n\tg.out()\n\tg.p(\"}\")\n\n\tg.GenerateMockMethods(mockType, intf, outputPackagePath, longTp, shortTp, *typed)\n\n\treturn nil\n}\n\ntype byMethodName []*model.Method\n\nfunc (b byMethodName) Len() int           { return len(b) }\nfunc (b byMethodName) Swap(i, j int)      { b[i], b[j] = b[j], b[i] }\nfunc (b byMethodName) Less(i, j int) bool { return b[i].Name < b[j].Name }\n\nfunc (g *generator) GenerateMockMethods(mockType string, intf *model.Interface, pkgOverride, longTp, shortTp string, typed bool) {\n\tsort.Sort(byMethodName(intf.Methods))\n\tfor _, m := range intf.Methods {\n\t\tg.p(\"\")\n\t\t_ = g.GenerateMockMethod(mockType, m, pkgOverride, shortTp)\n\t\tg.p(\"\")\n\t\t_ = g.GenerateMockRecorderMethod(intf, m, shortTp, typed)\n\t\tif typed {\n\t\t\tg.p(\"\")\n\t\t\t_ = g.GenerateMockReturnCallMethod(intf, m, pkgOverride, longTp, shortTp)\n\t\t}\n\t}\n}\n\nfunc makeArgString(argNames, argTypes []string) string {\n\targs := make([]string, len(argNames))\n\tfor i, name := range argNames {\n\t\t// specify the type only once for consecutive args of the same type\n\t\tif i+1 < len(argTypes) && argTypes[i] == argTypes[i+1] {\n\t\t\targs[i] = name\n\t\t} else {\n\t\t\targs[i] = name + \" \" + argTypes[i]\n\t\t}\n\t}\n\treturn strings.Join(args, \", \")\n}\n\n// GenerateMockMethod generates a mock method implementation.\n// If non-empty, pkgOverride is the package in which unqualified types reside.\nfunc (g *generator) GenerateMockMethod(mockType string, m *model.Method, pkgOverride, shortTp string) error {\n\targNames := g.getArgNames(m, true /* in */)\n\targTypes := g.getArgTypes(m, pkgOverride, true /* in */)\n\targString := makeArgString(argNames, argTypes)\n\n\trets := make([]string, len(m.Out))\n\tfor i, p := range m.Out {\n\t\trets[i] = p.Type.String(g.packageMap, pkgOverride)\n\t}\n\tretString := strings.Join(rets, \", \")\n\tif len(rets) > 1 {\n\t\tretString = \"(\" + retString + \")\"\n\t}\n\tif retString != \"\" {\n\t\tretString = \" \" + retString\n\t}\n\n\tia := newIdentifierAllocator(argNames)\n\tidRecv := ia.allocateIdentifier(\"m\")\n\n\tg.p(\"// %v mocks base method.\", m.Name)\n\tg.p(\"func (%v *%v%v) %v(%v)%v {\", idRecv, mockType, shortTp, m.Name, argString, retString)\n\tg.in()\n\tg.p(\"%s.ctrl.T.Helper()\", idRecv)\n\n\tvar callArgs string\n\tif m.Variadic == nil {\n\t\tif len(argNames) > 0 {\n\t\t\tcallArgs = \", \" + strings.Join(argNames, \", \")\n\t\t}\n\t} else {\n\t\t// Non-trivial. The generated code must build a []any,\n\t\t// but the variadic argument may be any type.\n\t\tidVarArgs := ia.allocateIdentifier(\"varargs\")\n\t\tidVArg := ia.allocateIdentifier(\"a\")\n\t\tg.p(\"%s := []any{%s}\", idVarArgs, strings.Join(argNames[:len(argNames)-1], \", \"))\n\t\tg.p(\"for _, %s := range %s {\", idVArg, argNames[len(argNames)-1])\n\t\tg.in()\n\t\tg.p(\"%s = append(%s, %s)\", idVarArgs, idVarArgs, idVArg)\n\t\tg.out()\n\t\tg.p(\"}\")\n\t\tcallArgs = \", \" + idVarArgs + \"...\"\n\t}\n\tif len(m.Out) == 0 {\n\t\tg.p(`%v.ctrl.Call(%v, %q%v)`, idRecv, idRecv, m.Name, callArgs)\n\t} else {\n\t\tidRet := ia.allocateIdentifier(\"ret\")\n\t\tg.p(`%v := %v.ctrl.Call(%v, %q%v)`, idRet, idRecv, idRecv, m.Name, callArgs)\n\n\t\t// Go does not allow \"naked\" type assertions on nil values, so we use the two-value form here.\n\t\t// The value of that is either (x.(T), true) or (Z, false), where Z is the zero value for T.\n\t\t// Happily, this coincides with the semantics we want here.\n\t\tretNames := make([]string, len(rets))\n\t\tfor i, t := range rets {\n\t\t\tretNames[i] = ia.allocateIdentifier(fmt.Sprintf(\"ret%d\", i))\n\t\t\tg.p(\"%s, _ := %s[%d].(%s)\", retNames[i], idRet, i, t)\n\t\t}\n\t\tg.p(\"return \" + strings.Join(retNames, \", \"))\n\t}\n\n\tg.out()\n\tg.p(\"}\")\n\treturn nil\n}\n\nfunc (g *generator) GenerateMockRecorderMethod(intf *model.Interface, m *model.Method, shortTp string, typed bool) error {\n\tmockType := g.mockName(intf.Name)\n\targNames := g.getArgNames(m, true)\n\n\tvar argString string\n\tif m.Variadic == nil {\n\t\targString = strings.Join(argNames, \", \")\n\t} else {\n\t\targString = strings.Join(argNames[:len(argNames)-1], \", \")\n\t}\n\tif argString != \"\" {\n\t\targString += \" any\"\n\t}\n\n\tif m.Variadic != nil {\n\t\tif argString != \"\" {\n\t\t\targString += \", \"\n\t\t}\n\t\targString += fmt.Sprintf(\"%s ...any\", argNames[len(argNames)-1])\n\t}\n\n\tia := newIdentifierAllocator(argNames)\n\tidRecv := ia.allocateIdentifier(\"mr\")\n\n\tg.p(\"// %v indicates an expected call of %v.\", m.Name, m.Name)\n\tif typed {\n\t\tg.p(\"func (%s *%vMockRecorder%v) %v(%v) *%s%sCall%s {\", idRecv, mockType, shortTp, m.Name, argString, mockType, m.Name, shortTp)\n\t} else {\n\t\tg.p(\"func (%s *%vMockRecorder%v) %v(%v) *gomock.Call {\", idRecv, mockType, shortTp, m.Name, argString)\n\t}\n\n\tg.in()\n\tg.p(\"%s.mock.ctrl.T.Helper()\", idRecv)\n\n\tvar callArgs string\n\tif m.Variadic == nil {\n\t\tif len(argNames) > 0 {\n\t\t\tcallArgs = \", \" + strings.Join(argNames, \", \")\n\t\t}\n\t} else {\n\t\tif len(argNames) == 1 {\n\t\t\t// Easy: just use ... to push the arguments through.\n\t\t\tcallArgs = \", \" + argNames[0] + \"...\"\n\t\t} else {\n\t\t\t// Hard: create a temporary slice.\n\t\t\tidVarArgs := ia.allocateIdentifier(\"varargs\")\n\t\t\tg.p(\"%s := append([]any{%s}, %s...)\",\n\t\t\t\tidVarArgs,\n\t\t\t\tstrings.Join(argNames[:len(argNames)-1], \", \"),\n\t\t\t\targNames[len(argNames)-1])\n\t\t\tcallArgs = \", \" + idVarArgs + \"...\"\n\t\t}\n\t}\n\tif typed {\n\t\tg.p(`call := %s.mock.ctrl.RecordCallWithMethodType(%s.mock, \"%s\", reflect.TypeOf((*%s%s)(nil).%s)%s)`, idRecv, idRecv, m.Name, mockType, shortTp, m.Name, callArgs)\n\t\tg.p(`return &%s%sCall%s{Call: call}`, mockType, m.Name, shortTp)\n\t} else {\n\t\tg.p(`return %s.mock.ctrl.RecordCallWithMethodType(%s.mock, \"%s\", reflect.TypeOf((*%s%s)(nil).%s)%s)`, idRecv, idRecv, m.Name, mockType, shortTp, m.Name, callArgs)\n\t}\n\n\tg.out()\n\tg.p(\"}\")\n\treturn nil\n}\n\nfunc (g *generator) GenerateMockReturnCallMethod(intf *model.Interface, m *model.Method, pkgOverride, longTp, shortTp string) error {\n\tmockType := g.mockName(intf.Name)\n\targNames := g.getArgNames(m, true /* in */)\n\tretNames := g.getArgNames(m, false /* out */)\n\targTypes := g.getArgTypes(m, pkgOverride, true /* in */)\n\tretTypes := g.getArgTypes(m, pkgOverride, false /* out */)\n\targString := strings.Join(argTypes, \", \")\n\n\trets := make([]string, len(m.Out))\n\tfor i, p := range m.Out {\n\t\trets[i] = p.Type.String(g.packageMap, pkgOverride)\n\t}\n\n\tvar retString string\n\tswitch {\n\tcase len(rets) == 1:\n\t\tretString = \" \" + rets[0]\n\tcase len(rets) > 1:\n\t\tretString = \" (\" + strings.Join(rets, \", \") + \")\"\n\t}\n\n\tia := newIdentifierAllocator(argNames)\n\tidRecv := ia.allocateIdentifier(\"c\")\n\n\trecvStructName := mockType + m.Name\n\n\tg.p(\"// %s%sCall wrap *gomock.Call\", mockType, m.Name)\n\tg.p(\"type %s%sCall%s struct{\", mockType, m.Name, longTp)\n\tg.in()\n\tg.p(\"*gomock.Call\")\n\tg.out()\n\tg.p(\"}\")\n\n\tg.p(\"// Return rewrite *gomock.Call.Return\")\n\tg.p(\"func (%s *%sCall%s) Return(%v) *%sCall%s {\", idRecv, recvStructName, shortTp, makeArgString(retNames, retTypes), recvStructName, shortTp)\n\tg.in()\n\tvar retArgs string\n\tif len(retNames) > 0 {\n\t\tretArgs = strings.Join(retNames, \", \")\n\t}\n\tg.p(`%s.Call =  %v.Call.Return(%v)`, idRecv, idRecv, retArgs)\n\tg.p(\"return %s\", idRecv)\n\tg.out()\n\tg.p(\"}\")\n\n\tg.p(\"// Do rewrite *gomock.Call.Do\")\n\tg.p(\"func (%s *%sCall%s) Do(f func(%v)%v) *%sCall%s {\", idRecv, recvStructName, shortTp, argString, retString, recvStructName, shortTp)\n\tg.in()\n\tg.p(`%s.Call = %v.Call.Do(f)`, idRecv, idRecv)\n\tg.p(\"return %s\", idRecv)\n\tg.out()\n\tg.p(\"}\")\n\n\tg.p(\"// DoAndReturn rewrite *gomock.Call.DoAndReturn\")\n\tg.p(\"func (%s *%sCall%s) DoAndReturn(f func(%v)%v) *%sCall%s {\", idRecv, recvStructName, shortTp, argString, retString, recvStructName, shortTp)\n\tg.in()\n\tg.p(`%s.Call = %v.Call.DoAndReturn(f)`, idRecv, idRecv)\n\tg.p(\"return %s\", idRecv)\n\tg.out()\n\tg.p(\"}\")\n\treturn nil\n}\n\n// nameExistsAsPackage returns true if the name exists as a package name.\n// This is used to avoid name collisions when generating mock method arguments.\nfunc (g *generator) nameExistsAsPackage(name string) bool {\n\tfor _, symbolName := range g.packageMap {\n\t\tif symbolName == name {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (g *generator) getArgNames(m *model.Method, in bool) []string {\n\tvar params []*model.Parameter\n\tif in {\n\t\tparams = m.In\n\t} else {\n\t\tparams = m.Out\n\t}\n\targNames := make([]string, len(params))\n\n\tfor i, p := range params {\n\t\tname := p.Name\n\n\t\tif name == \"\" || name == \"_\" || g.nameExistsAsPackage(name) {\n\t\t\tname = fmt.Sprintf(\"arg%d\", i)\n\t\t}\n\t\targNames[i] = name\n\t}\n\tif m.Variadic != nil && in {\n\t\tname := m.Variadic.Name\n\n\t\tif name == \"\" || g.nameExistsAsPackage(name) {\n\t\t\tname = fmt.Sprintf(\"arg%d\", len(params))\n\t\t}\n\t\targNames = append(argNames, name)\n\t}\n\treturn argNames\n}\n\nfunc (g *generator) getArgTypes(m *model.Method, pkgOverride string, in bool) []string {\n\tvar params []*model.Parameter\n\tif in {\n\t\tparams = m.In\n\t} else {\n\t\tparams = m.Out\n\t}\n\targTypes := make([]string, len(params))\n\tfor i, p := range params {\n\t\targTypes[i] = p.Type.String(g.packageMap, pkgOverride)\n\t}\n\tif m.Variadic != nil {\n\t\targTypes = append(argTypes, \"...\"+m.Variadic.Type.String(g.packageMap, pkgOverride))\n\t}\n\treturn argTypes\n}\n\ntype identifierAllocator map[string]struct{}\n\nfunc newIdentifierAllocator(taken []string) identifierAllocator {\n\ta := make(identifierAllocator, len(taken))\n\tfor _, s := range taken {\n\t\ta[s] = struct{}{}\n\t}\n\treturn a\n}\n\nfunc (o identifierAllocator) allocateIdentifier(want string) string {\n\tid := want\n\tfor i := 2; ; i++ {\n\t\tif _, ok := o[id]; !ok {\n\t\t\to[id] = struct{}{}\n\t\t\treturn id\n\t\t}\n\t\tid = want + \"_\" + strconv.Itoa(i)\n\t}\n}\n\n// Output returns the generator's output, formatted in the standard Go style.\nfunc (g *generator) Output() []byte {\n\tsrc, err := toolsimports.Process(g.destination, g.buf.Bytes(), nil)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to format generated source code: %s\\n%s\", err, g.buf.String())\n\t}\n\treturn src\n}\n\n// createPackageMap returns a map of import path to package name\n// for specified importPaths.\nfunc createPackageMap(importPaths []string) map[string]string {\n\tvar pkg struct {\n\t\tName       string\n\t\tImportPath string\n\t}\n\tpkgMap := make(map[string]string)\n\tb := bytes.NewBuffer(nil)\n\targs := []string{\"list\", \"-json=ImportPath,Name\"}\n\targs = append(args, importPaths...)\n\tcmd := exec.Command(\"go\", args...)\n\tcmd.Stdout = b\n\tcmd.Run()\n\tdec := json.NewDecoder(b)\n\tfor dec.More() {\n\t\terr := dec.Decode(&pkg)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"failed to decode 'go list' output: %v\", err)\n\t\t\tcontinue\n\t\t}\n\t\tpkgMap[pkg.ImportPath] = pkg.Name\n\t}\n\treturn pkgMap\n}\n\nfunc printVersion() {\n\tif version != \"\" {\n\t\tfmt.Printf(\"v%s\\nCommit: %s\\nDate: %s\\n\", version, commit, date)\n\t} else {\n\t\tprintModuleVersion()\n\t}\n}\n\n// parseImportPackage get package import path via source file\n// an alternative implementation is to use:\n// cfg := &packages.Config{Mode: packages.NeedName, Tests: true, Dir: srcDir}\n// pkgs, err := packages.Load(cfg, \"file=\"+source)\n// However, it will call \"go list\" and slow down the performance\nfunc parsePackageImport(srcDir string) (string, error) {\n\tmoduleMode := os.Getenv(\"GO111MODULE\")\n\t// trying to find the module\n\tif moduleMode != \"off\" {\n\t\tcurrentDir := srcDir\n\t\tfor {\n\t\t\tdat, err := os.ReadFile(filepath.Join(currentDir, \"go.mod\"))\n\t\t\tif os.IsNotExist(err) {\n\t\t\t\tif currentDir == filepath.Dir(currentDir) {\n\t\t\t\t\t// at the root\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcurrentDir = filepath.Dir(currentDir)\n\t\t\t\tcontinue\n\t\t\t} else if err != nil {\n\t\t\t\treturn \"\", err\n\t\t\t}\n\t\t\tmodulePath := modfile.ModulePath(dat)\n\t\t\treturn filepath.ToSlash(filepath.Join(modulePath, strings.TrimPrefix(srcDir, currentDir))), nil\n\t\t}\n\t}\n\t// fall back to GOPATH mode\n\tgoPaths := os.Getenv(\"GOPATH\")\n\tif goPaths == \"\" {\n\t\treturn \"\", fmt.Errorf(\"GOPATH is not set\")\n\t}\n\tgoPathList := strings.Split(goPaths, string(os.PathListSeparator))\n\tfor _, goPath := range goPathList {\n\t\tsourceRoot := filepath.Join(goPath, \"src\") + string(os.PathSeparator)\n\t\tif strings.HasPrefix(srcDir, sourceRoot) {\n\t\t\treturn filepath.ToSlash(strings.TrimPrefix(srcDir, sourceRoot)), nil\n\t\t}\n\t}\n\treturn \"\", errOutsideGoPath\n}\n"
  },
  {
    "path": "vendor/go.uber.org/mock/mockgen/model/model.go",
    "content": "// Copyright 2012 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Package model contains the data model necessary for generating mock implementations.\npackage model\n\nimport (\n\t\"encoding/gob\"\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\t\"strings\"\n)\n\n// pkgPath is the importable path for package model\nconst pkgPath = \"go.uber.org/mock/mockgen/model\"\n\n// Package is a Go package. It may be a subset.\ntype Package struct {\n\tName       string\n\tPkgPath    string\n\tInterfaces []*Interface\n\tDotImports []string\n}\n\n// Print writes the package name and its exported interfaces.\nfunc (pkg *Package) Print(w io.Writer) {\n\t_, _ = fmt.Fprintf(w, \"package %s\\n\", pkg.Name)\n\tfor _, intf := range pkg.Interfaces {\n\t\tintf.Print(w)\n\t}\n}\n\n// Imports returns the imports needed by the Package as a set of import paths.\nfunc (pkg *Package) Imports() map[string]bool {\n\tim := make(map[string]bool)\n\tfor _, intf := range pkg.Interfaces {\n\t\tintf.addImports(im)\n\t\tfor _, tp := range intf.TypeParams {\n\t\t\ttp.Type.addImports(im)\n\t\t}\n\t}\n\treturn im\n}\n\n// Interface is a Go interface.\ntype Interface struct {\n\tName       string\n\tMethods    []*Method\n\tTypeParams []*Parameter\n}\n\n// Print writes the interface name and its methods.\nfunc (intf *Interface) Print(w io.Writer) {\n\t_, _ = fmt.Fprintf(w, \"interface %s\\n\", intf.Name)\n\tfor _, m := range intf.Methods {\n\t\tm.Print(w)\n\t}\n}\n\nfunc (intf *Interface) addImports(im map[string]bool) {\n\tfor _, m := range intf.Methods {\n\t\tm.addImports(im)\n\t}\n}\n\n// AddMethod adds a new method, de-duplicating by method name.\nfunc (intf *Interface) AddMethod(m *Method) {\n\tfor _, me := range intf.Methods {\n\t\tif me.Name == m.Name {\n\t\t\treturn\n\t\t}\n\t}\n\tintf.Methods = append(intf.Methods, m)\n}\n\n// Method is a single method of an interface.\ntype Method struct {\n\tName     string\n\tIn, Out  []*Parameter\n\tVariadic *Parameter // may be nil\n}\n\n// Print writes the method name and its signature.\nfunc (m *Method) Print(w io.Writer) {\n\t_, _ = fmt.Fprintf(w, \"  - method %s\\n\", m.Name)\n\tif len(m.In) > 0 {\n\t\t_, _ = fmt.Fprintf(w, \"    in:\\n\")\n\t\tfor _, p := range m.In {\n\t\t\tp.Print(w)\n\t\t}\n\t}\n\tif m.Variadic != nil {\n\t\t_, _ = fmt.Fprintf(w, \"    ...:\\n\")\n\t\tm.Variadic.Print(w)\n\t}\n\tif len(m.Out) > 0 {\n\t\t_, _ = fmt.Fprintf(w, \"    out:\\n\")\n\t\tfor _, p := range m.Out {\n\t\t\tp.Print(w)\n\t\t}\n\t}\n}\n\nfunc (m *Method) addImports(im map[string]bool) {\n\tfor _, p := range m.In {\n\t\tp.Type.addImports(im)\n\t}\n\tif m.Variadic != nil {\n\t\tm.Variadic.Type.addImports(im)\n\t}\n\tfor _, p := range m.Out {\n\t\tp.Type.addImports(im)\n\t}\n}\n\n// Parameter is an argument or return parameter of a method.\ntype Parameter struct {\n\tName string // may be empty\n\tType Type\n}\n\n// Print writes a method parameter.\nfunc (p *Parameter) Print(w io.Writer) {\n\tn := p.Name\n\tif n == \"\" {\n\t\tn = `\"\"`\n\t}\n\t_, _ = fmt.Fprintf(w, \"    - %v: %v\\n\", n, p.Type.String(nil, \"\"))\n}\n\n// Type is a Go type.\ntype Type interface {\n\tString(pm map[string]string, pkgOverride string) string\n\taddImports(im map[string]bool)\n}\n\nfunc init() {\n\t// Call gob.RegisterName with pkgPath as prefix to avoid conflicting with\n\t// github.com/golang/mock/mockgen/model 's registration.\n\tgob.RegisterName(pkgPath+\".ArrayType\", &ArrayType{})\n\tgob.RegisterName(pkgPath+\".ChanType\", &ChanType{})\n\tgob.RegisterName(pkgPath+\".FuncType\", &FuncType{})\n\tgob.RegisterName(pkgPath+\".MapType\", &MapType{})\n\tgob.RegisterName(pkgPath+\".NamedType\", &NamedType{})\n\tgob.RegisterName(pkgPath+\".PointerType\", &PointerType{})\n\n\t// Call gob.RegisterName to make sure it has the consistent name registered\n\t// for both gob decoder and encoder.\n\t//\n\t// For a non-pointer type, gob.Register will try to get package full path by\n\t// calling rt.PkgPath() for a name to register. If your project has vendor\n\t// directory, it is possible that PkgPath will get a path like this:\n\t//     ../../../vendor/go.uber.org/mock/mockgen/model\n\tgob.RegisterName(pkgPath+\".PredeclaredType\", PredeclaredType(\"\"))\n}\n\n// ArrayType is an array or slice type.\ntype ArrayType struct {\n\tLen  int // -1 for slices, >= 0 for arrays\n\tType Type\n}\n\nfunc (at *ArrayType) String(pm map[string]string, pkgOverride string) string {\n\ts := \"[]\"\n\tif at.Len > -1 {\n\t\ts = fmt.Sprintf(\"[%d]\", at.Len)\n\t}\n\treturn s + at.Type.String(pm, pkgOverride)\n}\n\nfunc (at *ArrayType) addImports(im map[string]bool) { at.Type.addImports(im) }\n\n// ChanType is a channel type.\ntype ChanType struct {\n\tDir  ChanDir // 0, 1 or 2\n\tType Type\n}\n\nfunc (ct *ChanType) String(pm map[string]string, pkgOverride string) string {\n\ts := ct.Type.String(pm, pkgOverride)\n\tif ct.Dir == RecvDir {\n\t\treturn \"<-chan \" + s\n\t}\n\tif ct.Dir == SendDir {\n\t\treturn \"chan<- \" + s\n\t}\n\treturn \"chan \" + s\n}\n\nfunc (ct *ChanType) addImports(im map[string]bool) { ct.Type.addImports(im) }\n\n// ChanDir is a channel direction.\ntype ChanDir int\n\n// Constants for channel directions.\nconst (\n\tRecvDir ChanDir = 1\n\tSendDir ChanDir = 2\n)\n\n// FuncType is a function type.\ntype FuncType struct {\n\tIn, Out  []*Parameter\n\tVariadic *Parameter // may be nil\n}\n\nfunc (ft *FuncType) String(pm map[string]string, pkgOverride string) string {\n\targs := make([]string, len(ft.In))\n\tfor i, p := range ft.In {\n\t\targs[i] = p.Type.String(pm, pkgOverride)\n\t}\n\tif ft.Variadic != nil {\n\t\targs = append(args, \"...\"+ft.Variadic.Type.String(pm, pkgOverride))\n\t}\n\trets := make([]string, len(ft.Out))\n\tfor i, p := range ft.Out {\n\t\trets[i] = p.Type.String(pm, pkgOverride)\n\t}\n\tretString := strings.Join(rets, \", \")\n\tif nOut := len(ft.Out); nOut == 1 {\n\t\tretString = \" \" + retString\n\t} else if nOut > 1 {\n\t\tretString = \" (\" + retString + \")\"\n\t}\n\treturn \"func(\" + strings.Join(args, \", \") + \")\" + retString\n}\n\nfunc (ft *FuncType) addImports(im map[string]bool) {\n\tfor _, p := range ft.In {\n\t\tp.Type.addImports(im)\n\t}\n\tif ft.Variadic != nil {\n\t\tft.Variadic.Type.addImports(im)\n\t}\n\tfor _, p := range ft.Out {\n\t\tp.Type.addImports(im)\n\t}\n}\n\n// MapType is a map type.\ntype MapType struct {\n\tKey, Value Type\n}\n\nfunc (mt *MapType) String(pm map[string]string, pkgOverride string) string {\n\treturn \"map[\" + mt.Key.String(pm, pkgOverride) + \"]\" + mt.Value.String(pm, pkgOverride)\n}\n\nfunc (mt *MapType) addImports(im map[string]bool) {\n\tmt.Key.addImports(im)\n\tmt.Value.addImports(im)\n}\n\n// NamedType is an exported type in a package.\ntype NamedType struct {\n\tPackage    string // may be empty\n\tType       string\n\tTypeParams *TypeParametersType\n}\n\nfunc (nt *NamedType) String(pm map[string]string, pkgOverride string) string {\n\tif pkgOverride == nt.Package {\n\t\treturn nt.Type + nt.TypeParams.String(pm, pkgOverride)\n\t}\n\tprefix := pm[nt.Package]\n\tif prefix != \"\" {\n\t\treturn prefix + \".\" + nt.Type + nt.TypeParams.String(pm, pkgOverride)\n\t}\n\n\treturn nt.Type + nt.TypeParams.String(pm, pkgOverride)\n}\n\nfunc (nt *NamedType) addImports(im map[string]bool) {\n\tif nt.Package != \"\" {\n\t\tim[nt.Package] = true\n\t}\n\tnt.TypeParams.addImports(im)\n}\n\n// PointerType is a pointer to another type.\ntype PointerType struct {\n\tType Type\n}\n\nfunc (pt *PointerType) String(pm map[string]string, pkgOverride string) string {\n\treturn \"*\" + pt.Type.String(pm, pkgOverride)\n}\nfunc (pt *PointerType) addImports(im map[string]bool) { pt.Type.addImports(im) }\n\n// PredeclaredType is a predeclared type such as \"int\".\ntype PredeclaredType string\n\nfunc (pt PredeclaredType) String(map[string]string, string) string { return string(pt) }\nfunc (pt PredeclaredType) addImports(map[string]bool)              {}\n\n// TypeParametersType contains type parameters for a NamedType.\ntype TypeParametersType struct {\n\tTypeParameters []Type\n}\n\nfunc (tp *TypeParametersType) String(pm map[string]string, pkgOverride string) string {\n\tif tp == nil || len(tp.TypeParameters) == 0 {\n\t\treturn \"\"\n\t}\n\tvar sb strings.Builder\n\tsb.WriteString(\"[\")\n\tfor i, v := range tp.TypeParameters {\n\t\tif i != 0 {\n\t\t\tsb.WriteString(\", \")\n\t\t}\n\t\tsb.WriteString(v.String(pm, pkgOverride))\n\t}\n\tsb.WriteString(\"]\")\n\treturn sb.String()\n}\n\nfunc (tp *TypeParametersType) addImports(im map[string]bool) {\n\tif tp == nil {\n\t\treturn\n\t}\n\tfor _, v := range tp.TypeParameters {\n\t\tv.addImports(im)\n\t}\n}\n\n// The following code is intended to be called by the program generated by ../reflect.go.\n\n// InterfaceFromInterfaceType returns a pointer to an interface for the\n// given reflection interface type.\nfunc InterfaceFromInterfaceType(it reflect.Type) (*Interface, error) {\n\tif it.Kind() != reflect.Interface {\n\t\treturn nil, fmt.Errorf(\"%v is not an interface\", it)\n\t}\n\tintf := &Interface{}\n\n\tfor i := 0; i < it.NumMethod(); i++ {\n\t\tmt := it.Method(i)\n\t\t// TODO: need to skip unexported methods? or just raise an error?\n\t\tm := &Method{\n\t\t\tName: mt.Name,\n\t\t}\n\n\t\tvar err error\n\t\tm.In, m.Variadic, m.Out, err = funcArgsFromType(mt.Type)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tintf.AddMethod(m)\n\t}\n\n\treturn intf, nil\n}\n\n// t's Kind must be a reflect.Func.\nfunc funcArgsFromType(t reflect.Type) (in []*Parameter, variadic *Parameter, out []*Parameter, err error) {\n\tnin := t.NumIn()\n\tif t.IsVariadic() {\n\t\tnin--\n\t}\n\tvar p *Parameter\n\tfor i := 0; i < nin; i++ {\n\t\tp, err = parameterFromType(t.In(i))\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tin = append(in, p)\n\t}\n\tif t.IsVariadic() {\n\t\tp, err = parameterFromType(t.In(nin).Elem())\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tvariadic = p\n\t}\n\tfor i := 0; i < t.NumOut(); i++ {\n\t\tp, err = parameterFromType(t.Out(i))\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tout = append(out, p)\n\t}\n\treturn\n}\n\nfunc parameterFromType(t reflect.Type) (*Parameter, error) {\n\ttt, err := typeFromType(t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Parameter{Type: tt}, nil\n}\n\nvar errorType = reflect.TypeOf((*error)(nil)).Elem()\n\nvar byteType = reflect.TypeOf(byte(0))\n\nfunc typeFromType(t reflect.Type) (Type, error) {\n\t// Hack workaround for https://golang.org/issue/3853.\n\t// This explicit check should not be necessary.\n\tif t == byteType {\n\t\treturn PredeclaredType(\"byte\"), nil\n\t}\n\n\tif imp := t.PkgPath(); imp != \"\" {\n\t\treturn &NamedType{\n\t\t\tPackage: impPath(imp),\n\t\t\tType:    t.Name(),\n\t\t}, nil\n\t}\n\n\t// only unnamed or predeclared types after here\n\n\t// Lots of types have element types. Let's do the parsing and error checking for all of them.\n\tvar elemType Type\n\tswitch t.Kind() {\n\tcase reflect.Array, reflect.Chan, reflect.Map, reflect.Ptr, reflect.Slice:\n\t\tvar err error\n\t\telemType, err = typeFromType(t.Elem())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tswitch t.Kind() {\n\tcase reflect.Array:\n\t\treturn &ArrayType{\n\t\t\tLen:  t.Len(),\n\t\t\tType: elemType,\n\t\t}, nil\n\tcase reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,\n\t\treflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,\n\t\treflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.String:\n\t\treturn PredeclaredType(t.Kind().String()), nil\n\tcase reflect.Chan:\n\t\tvar dir ChanDir\n\t\tswitch t.ChanDir() {\n\t\tcase reflect.RecvDir:\n\t\t\tdir = RecvDir\n\t\tcase reflect.SendDir:\n\t\t\tdir = SendDir\n\t\t}\n\t\treturn &ChanType{\n\t\t\tDir:  dir,\n\t\t\tType: elemType,\n\t\t}, nil\n\tcase reflect.Func:\n\t\tin, variadic, out, err := funcArgsFromType(t)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &FuncType{\n\t\t\tIn:       in,\n\t\t\tOut:      out,\n\t\t\tVariadic: variadic,\n\t\t}, nil\n\tcase reflect.Interface:\n\t\t// Two special interfaces.\n\t\tif t.NumMethod() == 0 {\n\t\t\treturn PredeclaredType(\"any\"), nil\n\t\t}\n\t\tif t == errorType {\n\t\t\treturn PredeclaredType(\"error\"), nil\n\t\t}\n\tcase reflect.Map:\n\t\tkt, err := typeFromType(t.Key())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &MapType{\n\t\t\tKey:   kt,\n\t\t\tValue: elemType,\n\t\t}, nil\n\tcase reflect.Ptr:\n\t\treturn &PointerType{\n\t\t\tType: elemType,\n\t\t}, nil\n\tcase reflect.Slice:\n\t\treturn &ArrayType{\n\t\t\tLen:  -1,\n\t\t\tType: elemType,\n\t\t}, nil\n\tcase reflect.Struct:\n\t\tif t.NumField() == 0 {\n\t\t\treturn PredeclaredType(\"struct{}\"), nil\n\t\t}\n\t}\n\n\t// TODO: Struct, UnsafePointer\n\treturn nil, fmt.Errorf(\"can't yet turn %v (%v) into a model.Type\", t, t.Kind())\n}\n\n// impPath sanitizes the package path returned by `PkgPath` method of a reflect Type so that\n// it is importable. PkgPath might return a path that includes \"vendor\". These paths do not\n// compile, so we need to remove everything up to and including \"/vendor/\".\n// See https://github.com/golang/go/issues/12019.\nfunc impPath(imp string) string {\n\tif strings.HasPrefix(imp, \"vendor/\") {\n\t\timp = \"/\" + imp\n\t}\n\tif i := strings.LastIndex(imp, \"/vendor/\"); i != -1 {\n\t\timp = imp[i+len(\"/vendor/\"):]\n\t}\n\treturn imp\n}\n\n// ErrorInterface represent built-in error interface.\nvar ErrorInterface = Interface{\n\tName: \"error\",\n\tMethods: []*Method{\n\t\t{\n\t\t\tName: \"Error\",\n\t\t\tOut: []*Parameter{\n\t\t\t\t{\n\t\t\t\t\tName: \"\",\n\t\t\t\t\tType: PredeclaredType(\"string\"),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n}\n"
  },
  {
    "path": "vendor/go.uber.org/mock/mockgen/package_mode.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"flag\"\n\t\"fmt\"\n\t\"go/ast\"\n\t\"go/types\"\n\t\"strings\"\n\n\t\"go.uber.org/mock/mockgen/model\"\n\t\"golang.org/x/tools/go/packages\"\n)\n\nvar (\n\tbuildFlags = flag.String(\"build_flags\", \"\", \"(package mode) Additional flags for go build.\")\n)\n\ntype packageModeParser struct {\n\tpkgName string\n\n\t// Mapping from underlying types to aliases used within the package source.\n\t//\n\t// We prefer to use aliases used in the source rather than underlying type names\n\t// as those may be unexported or internal.\n\t// TODO(joaks): Once mock is Go1.23+ only, we can remove this\n\t// as the casing for types.Alias will automatically handle this\n\t// in all cases.\n\taliasReplacements map[types.Type]aliasReplacement\n}\n\ntype aliasReplacement struct {\n\tname string\n\tpkg  string\n}\n\nfunc (p *packageModeParser) parsePackage(packageName string, ifaces []string) (*model.Package, error) {\n\tp.pkgName = packageName\n\n\tpkg, err := p.loadPackage(packageName)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"load package: %w\", err)\n\t}\n\n\tp.buildAliasReplacements(pkg)\n\n\tinterfaces, err := p.extractInterfacesFromPackage(pkg, ifaces)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"extract interfaces from package: %w\", err)\n\t}\n\n\treturn &model.Package{\n\t\tName:       pkg.Types.Name(),\n\t\tPkgPath:    packageName,\n\t\tInterfaces: interfaces,\n\t}, nil\n}\n\n// buildAliasReplacements finds and records any references to aliases\n// within the given package's source.\n// These aliases will be preferred when parsing types\n// over the underlying name counterparts, as those may be unexported / internal.\n//\n// If a type has more than one alias within the source package,\n// the latest one to be inspected will be the one used for mapping.\n// This is fine, since all aliases and their underlying types are interchangeable\n// from a type-checking standpoint.\nfunc (p *packageModeParser) buildAliasReplacements(pkg *packages.Package) {\n\tp.aliasReplacements = make(map[types.Type]aliasReplacement)\n\n\t// checkIdent checks if the given identifier exists\n\t// in the given package as an alias, and adds it to\n\t// the alias replacements map if so.\n\tcheckIdent := func(pkg *types.Package, ident string) bool {\n\t\tscope := pkg.Scope()\n\t\tif scope == nil {\n\t\t\treturn true\n\t\t}\n\t\tobj := scope.Lookup(ident)\n\t\tif obj == nil {\n\t\t\treturn true\n\t\t}\n\t\tobjTypeName, ok := obj.(*types.TypeName)\n\t\tif !ok {\n\t\t\treturn true\n\t\t}\n\t\tif !objTypeName.IsAlias() {\n\t\t\treturn true\n\t\t}\n\t\ttyp := objTypeName.Type()\n\t\tif typ == nil {\n\t\t\treturn true\n\t\t}\n\t\tp.aliasReplacements[typ] = aliasReplacement{\n\t\t\tname: objTypeName.Name(),\n\t\t\tpkg:  pkg.Path(),\n\t\t}\n\t\treturn false\n\n\t}\n\n\tfor _, f := range pkg.Syntax {\n\t\tfileScope, ok := pkg.TypesInfo.Scopes[f]\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tast.Inspect(f, func(node ast.Node) bool {\n\n\t\t\t// Simple identifiers: check if it is an alias\n\t\t\t// from the source package.\n\t\t\tif ident, ok := node.(*ast.Ident); ok {\n\t\t\t\treturn checkIdent(pkg.Types, ident.String())\n\t\t\t}\n\n\t\t\t// Selector expressions: check if it is an alias\n\t\t\t// from the package represented by the qualifier.\n\t\t\tselExpr, ok := node.(*ast.SelectorExpr)\n\t\t\tif !ok {\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\tx, sel := selExpr.X, selExpr.Sel\n\t\t\txident, ok := x.(*ast.Ident)\n\t\t\tif !ok {\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\txObj := fileScope.Lookup(xident.String())\n\t\t\tpkgName, ok := xObj.(*types.PkgName)\n\t\t\tif !ok {\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\txPkg := pkgName.Imported()\n\t\t\tif xPkg == nil {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn checkIdent(xPkg, sel.String())\n\t\t})\n\t}\n}\n\nfunc (p *packageModeParser) loadPackage(packageName string) (*packages.Package, error) {\n\tvar buildFlagsSet []string\n\tif *buildFlags != \"\" {\n\t\tbuildFlagsSet = strings.Split(*buildFlags, \" \")\n\t}\n\n\tcfg := &packages.Config{\n\t\tMode:       packages.NeedDeps | packages.NeedImports | packages.NeedTypes | packages.NeedTypesInfo | packages.NeedEmbedFiles | packages.LoadSyntax,\n\t\tBuildFlags: buildFlagsSet,\n\t}\n\tpkgs, err := packages.Load(cfg, packageName)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"load packages: %w\", err)\n\t}\n\n\tif len(pkgs) != 1 {\n\t\treturn nil, fmt.Errorf(\"packages length must be 1: %d\", len(pkgs))\n\t}\n\n\tif len(pkgs[0].Errors) > 0 {\n\t\terrs := make([]error, len(pkgs[0].Errors))\n\t\tfor i, err := range pkgs[0].Errors {\n\t\t\terrs[i] = err\n\t\t}\n\n\t\treturn nil, errors.Join(errs...)\n\t}\n\n\treturn pkgs[0], nil\n}\n\nfunc (p *packageModeParser) extractInterfacesFromPackage(pkg *packages.Package, ifaces []string) ([]*model.Interface, error) {\n\tinterfaces := make([]*model.Interface, len(ifaces))\n\tfor i, iface := range ifaces {\n\t\tobj := pkg.Types.Scope().Lookup(iface)\n\t\tif obj == nil {\n\t\t\treturn nil, fmt.Errorf(\"interface %s does not exist\", iface)\n\t\t}\n\n\t\tmodelIface, err := p.parseInterface(obj)\n\t\tif err != nil {\n\t\t\treturn nil, newParseTypeError(\"parse interface\", obj.Name(), err)\n\t\t}\n\n\t\tinterfaces[i] = modelIface\n\t}\n\n\treturn interfaces, nil\n}\n\nfunc (p *packageModeParser) parseInterface(obj types.Object) (*model.Interface, error) {\n\tnamed, ok := types.Unalias(obj.Type()).(*types.Named)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"%s is not an interface. it is a %T\", obj.Name(), obj.Type().Underlying())\n\t}\n\n\tiface, ok := named.Underlying().(*types.Interface)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"%s is not an interface. it is a %T\", obj.Name(), obj.Type().Underlying())\n\t}\n\n\tif p.isConstraint(iface) {\n\t\treturn nil, fmt.Errorf(\"interface %s is a constraint\", obj.Name())\n\t}\n\n\tmethods := make([]*model.Method, iface.NumMethods())\n\tfor i := range iface.NumMethods() {\n\t\tmethod := iface.Method(i)\n\t\ttypedMethod, ok := method.Type().(*types.Signature)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"method %s is not a signature\", method.Name())\n\t\t}\n\n\t\tmodelFunc, err := p.parseFunc(typedMethod)\n\t\tif err != nil {\n\t\t\treturn nil, newParseTypeError(\"parse method\", typedMethod.String(), err)\n\t\t}\n\n\t\tmethods[i] = &model.Method{\n\t\t\tName:     method.Name(),\n\t\t\tIn:       modelFunc.In,\n\t\t\tOut:      modelFunc.Out,\n\t\t\tVariadic: modelFunc.Variadic,\n\t\t}\n\t}\n\n\tif named.TypeParams() == nil {\n\t\treturn &model.Interface{Name: obj.Name(), Methods: methods}, nil\n\t}\n\n\ttypeParams := make([]*model.Parameter, named.TypeParams().Len())\n\tfor i := range named.TypeParams().Len() {\n\t\tparam := named.TypeParams().At(i)\n\t\ttypeParam, err := p.parseConstraint(param)\n\t\tif err != nil {\n\t\t\treturn nil, newParseTypeError(\"parse type parameter\", param.String(), err)\n\t\t}\n\n\t\ttypeParams[i] = &model.Parameter{Name: param.Obj().Name(), Type: typeParam}\n\t}\n\n\treturn &model.Interface{Name: obj.Name(), Methods: methods, TypeParams: typeParams}, nil\n}\n\nfunc (o *packageModeParser) isConstraint(t *types.Interface) bool {\n\tfor i := range t.NumEmbeddeds() {\n\t\tembed := t.EmbeddedType(i)\n\t\tif _, ok := embed.Underlying().(*types.Interface); !ok {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc (p *packageModeParser) parseType(t types.Type) (model.Type, error) {\n\tswitch t := t.(type) {\n\tcase *types.Array:\n\t\telementType, err := p.parseType(t.Elem())\n\t\tif err != nil {\n\t\t\treturn nil, newParseTypeError(\"parse array type\", t.Elem().String(), err)\n\t\t}\n\t\treturn &model.ArrayType{Len: int(t.Len()), Type: elementType}, nil\n\tcase *types.Slice:\n\t\telementType, err := p.parseType(t.Elem())\n\t\tif err != nil {\n\t\t\treturn nil, newParseTypeError(\"parse slice type\", t.Elem().String(), err)\n\t\t}\n\n\t\treturn &model.ArrayType{Len: -1, Type: elementType}, nil\n\tcase *types.Chan:\n\t\tvar dir model.ChanDir\n\t\tswitch t.Dir() {\n\t\tcase types.RecvOnly:\n\t\t\tdir = model.RecvDir\n\t\tcase types.SendOnly:\n\t\t\tdir = model.SendDir\n\t\t}\n\n\t\tchanType, err := p.parseType(t.Elem())\n\t\tif err != nil {\n\t\t\treturn nil, newParseTypeError(\"parse chan type\", t.Elem().String(), err)\n\t\t}\n\n\t\treturn &model.ChanType{Dir: dir, Type: chanType}, nil\n\tcase *types.Signature:\n\t\tsig, err := p.parseFunc(t)\n\t\tif err != nil {\n\t\t\treturn nil, newParseTypeError(\"parse signature\", t.String(), err)\n\t\t}\n\n\t\treturn sig, nil\n\tcase *types.Named, *types.Alias:\n\t\tobject := t.(interface{ Obj() *types.TypeName })\n\t\tname := object.Obj().Name()\n\t\tvar pkg string\n\t\tif object.Obj().Pkg() != nil {\n\t\t\tpkg = object.Obj().Pkg().Path()\n\t\t}\n\n\t\t// If there was an alias to this type used somewhere in the source,\n\t\t// use that alias instead of the underlying type,\n\t\t// since the underlying type might be unexported.\n\t\tif alias, ok := p.aliasReplacements[t]; ok {\n\t\t\tname = alias.name\n\t\t\tpkg = alias.pkg\n\t\t}\n\n\t\t// TypeArgs method not available for aliases in go1.22\n\t\tgenericType, ok := t.(interface{ TypeArgs() *types.TypeList })\n\t\tif !ok || genericType.TypeArgs() == nil {\n\t\t\treturn &model.NamedType{\n\t\t\t\tPackage: pkg,\n\t\t\t\tType:    name,\n\t\t\t}, nil\n\t\t}\n\n\t\ttypeParams := &model.TypeParametersType{TypeParameters: make([]model.Type, genericType.TypeArgs().Len())}\n\t\tfor i := range genericType.TypeArgs().Len() {\n\t\t\ttypeParam := genericType.TypeArgs().At(i)\n\t\t\ttypedParam, err := p.parseType(typeParam)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, newParseTypeError(\"parse type parameter\", typeParam.String(), err)\n\t\t\t}\n\n\t\t\ttypeParams.TypeParameters[i] = typedParam\n\t\t}\n\n\t\treturn &model.NamedType{\n\t\t\tPackage:    pkg,\n\t\t\tType:       name,\n\t\t\tTypeParams: typeParams,\n\t\t}, nil\n\tcase *types.Interface:\n\t\tif t.Empty() {\n\t\t\treturn model.PredeclaredType(\"any\"), nil\n\t\t}\n\n\t\treturn nil, fmt.Errorf(\"cannot handle non-empty unnamed interfaces\")\n\tcase *types.Map:\n\t\tkey, err := p.parseType(t.Key())\n\t\tif err != nil {\n\t\t\treturn nil, newParseTypeError(\"parse map key\", t.Key().String(), err)\n\t\t}\n\t\tvalue, err := p.parseType(t.Elem())\n\t\tif err != nil {\n\t\t\treturn nil, newParseTypeError(\"parse map value\", t.Elem().String(), err)\n\t\t}\n\n\t\treturn &model.MapType{Key: key, Value: value}, nil\n\tcase *types.Pointer:\n\t\tvalueType, err := p.parseType(t.Elem())\n\t\tif err != nil {\n\t\t\treturn nil, newParseTypeError(\"parse pointer type\", t.Elem().String(), err)\n\t\t}\n\n\t\treturn &model.PointerType{Type: valueType}, nil\n\tcase *types.Struct:\n\t\tif t.NumFields() > 0 {\n\t\t\treturn nil, fmt.Errorf(\"cannot handle non-empty unnamed structs\")\n\t\t}\n\n\t\treturn model.PredeclaredType(\"struct{}\"), nil\n\tcase *types.Basic:\n\t\treturn model.PredeclaredType(t.Name()), nil\n\tcase *types.Tuple:\n\t\tpanic(\"tuple field\") // TODO\n\tcase *types.TypeParam:\n\t\treturn &model.NamedType{Type: t.Obj().Name()}, nil\n\tdefault:\n\t\tpanic(\"unknown type\") // TODO\n\t}\n}\n\nfunc (p *packageModeParser) parseFunc(sig *types.Signature) (*model.FuncType, error) {\n\tvar variadic *model.Parameter\n\tparams := make([]*model.Parameter, 0, sig.Params().Len())\n\tfor i := range sig.Params().Len() {\n\t\tparam := sig.Params().At(i)\n\n\t\tisVariadicParam := i == sig.Params().Len()-1 && sig.Variadic()\n\t\tparseType := param.Type()\n\t\tif isVariadicParam {\n\t\t\tsliceType, ok := param.Type().(*types.Slice)\n\t\t\tif !ok {\n\t\t\t\treturn nil, newParseTypeError(\"variadic parameter is not a slice\", param.String(), nil)\n\t\t\t}\n\n\t\t\tparseType = sliceType.Elem()\n\t\t}\n\n\t\tparamType, err := p.parseType(parseType)\n\t\tif err != nil {\n\t\t\treturn nil, newParseTypeError(\"parse parameter type\", parseType.String(), err)\n\t\t}\n\n\t\tmodelParameter := &model.Parameter{Type: paramType, Name: param.Name()}\n\n\t\tif isVariadicParam {\n\t\t\tvariadic = modelParameter\n\t\t} else {\n\t\t\tparams = append(params, modelParameter)\n\t\t}\n\t}\n\n\tif len(params) == 0 {\n\t\tparams = nil\n\t}\n\n\tresults := make([]*model.Parameter, sig.Results().Len())\n\tfor i := range sig.Results().Len() {\n\t\tresult := sig.Results().At(i)\n\n\t\tresultType, err := p.parseType(result.Type())\n\t\tif err != nil {\n\t\t\treturn nil, newParseTypeError(\"parse result type\", result.Type().String(), err)\n\t\t}\n\n\t\tresults[i] = &model.Parameter{Type: resultType, Name: result.Name()}\n\t}\n\n\tif len(results) == 0 {\n\t\tresults = nil\n\t}\n\n\treturn &model.FuncType{\n\t\tIn:       params,\n\t\tOut:      results,\n\t\tVariadic: variadic,\n\t}, nil\n}\n\nfunc (p *packageModeParser) parseConstraint(t *types.TypeParam) (model.Type, error) {\n\tif t == nil {\n\t\treturn nil, fmt.Errorf(\"nil type param\")\n\t}\n\n\ttypeParam, err := p.parseType(t.Constraint())\n\tif err != nil {\n\t\treturn nil, newParseTypeError(\"parse constraint type\", t.Constraint().String(), err)\n\t}\n\n\treturn typeParam, nil\n}\n\ntype parseTypeError struct {\n\tmessage    string\n\ttypeString string\n\terror      error\n}\n\nfunc newParseTypeError(message string, typeString string, error error) *parseTypeError {\n\treturn &parseTypeError{typeString: typeString, error: error, message: message}\n}\n\nfunc (p parseTypeError) Error() string {\n\tif p.error != nil {\n\t\treturn fmt.Sprintf(\"%s: error parsing %s: %s\", p.message, p.typeString, p.error)\n\t}\n\n\treturn fmt.Sprintf(\"%s: error parsing type %s\", p.message, p.typeString)\n}\n\nfunc (p parseTypeError) Unwrap() error {\n\treturn p.error\n}\n"
  },
  {
    "path": "vendor/go.uber.org/mock/mockgen/parse.go",
    "content": "// Copyright 2012 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\n// This file contains the model construction by parsing source files.\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"go/ast\"\n\t\"go/build\"\n\t\"go/importer\"\n\t\"go/parser\"\n\t\"go/token\"\n\t\"go/types\"\n\t\"log\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"go.uber.org/mock/mockgen/model\"\n)\n\n// sourceMode generates mocks via source file.\nfunc sourceMode(source string) (*model.Package, error) {\n\tsrcDir, err := filepath.Abs(filepath.Dir(source))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed getting source directory: %v\", err)\n\t}\n\n\tpackageImport, err := parsePackageImport(srcDir)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfs := token.NewFileSet()\n\tfile, err := parser.ParseFile(fs, source, nil, 0)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed parsing source file %v: %v\", source, err)\n\t}\n\n\tp := &fileParser{\n\t\tfileSet:            fs,\n\t\timports:            make(map[string]importedPackage),\n\t\timportedInterfaces: newInterfaceCache(),\n\t\tauxInterfaces:      newInterfaceCache(),\n\t\tsrcDir:             srcDir,\n\t}\n\n\t// Handle -imports.\n\tdotImports := make(map[string]bool)\n\tif *imports != \"\" {\n\t\tfor _, kv := range strings.Split(*imports, \",\") {\n\t\t\teq := strings.Index(kv, \"=\")\n\t\t\tk, v := kv[:eq], kv[eq+1:]\n\t\t\tif k == \".\" {\n\t\t\t\tdotImports[v] = true\n\t\t\t} else {\n\t\t\t\tp.imports[k] = importedPkg{path: v}\n\t\t\t}\n\t\t}\n\t}\n\n\tif *excludeInterfaces != \"\" {\n\t\tp.excludeNamesSet = parseExcludeInterfaces(*excludeInterfaces)\n\t}\n\n\t// Handle -aux_files.\n\tif err := p.parseAuxFiles(*auxFiles); err != nil {\n\t\treturn nil, err\n\t}\n\tp.addAuxInterfacesFromFile(packageImport, file) // this file\n\n\tpkg, err := p.parseFile(packageImport, file)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfor pkgPath := range dotImports {\n\t\tpkg.DotImports = append(pkg.DotImports, pkgPath)\n\t}\n\treturn pkg, nil\n}\n\ntype importedPackage interface {\n\tPath() string\n\tParser() *fileParser\n}\n\ntype importedPkg struct {\n\tpath   string\n\tparser *fileParser\n}\n\nfunc (i importedPkg) Path() string        { return i.path }\nfunc (i importedPkg) Parser() *fileParser { return i.parser }\n\n// duplicateImport is a bit of a misnomer. Currently the parser can't\n// handle cases of multi-file packages importing different packages\n// under the same name. Often these imports would not be problematic,\n// so this type lets us defer raising an error unless the package name\n// is actually used.\ntype duplicateImport struct {\n\tname       string\n\tduplicates []string\n}\n\nfunc (d duplicateImport) Error() string {\n\treturn fmt.Sprintf(\"%q is ambiguous because of duplicate imports: %v\", d.name, d.duplicates)\n}\n\nfunc (d duplicateImport) Path() string        { log.Fatal(d.Error()); return \"\" }\nfunc (d duplicateImport) Parser() *fileParser { log.Fatal(d.Error()); return nil }\n\ntype interfaceCache struct {\n\tm map[string]map[string]*namedInterface\n}\n\nfunc newInterfaceCache() *interfaceCache {\n\treturn &interfaceCache{\n\t\tm: make(map[string]map[string]*namedInterface),\n\t}\n}\n\nfunc (i *interfaceCache) Set(pkg, name string, it *namedInterface) {\n\tif _, ok := i.m[pkg]; !ok {\n\t\ti.m[pkg] = make(map[string]*namedInterface)\n\t}\n\ti.m[pkg][name] = it\n}\n\nfunc (i *interfaceCache) Get(pkg, name string) *namedInterface {\n\tif _, ok := i.m[pkg]; !ok {\n\t\treturn nil\n\t}\n\treturn i.m[pkg][name]\n}\n\nfunc (i *interfaceCache) GetASTIface(pkg, name string) *ast.InterfaceType {\n\tif _, ok := i.m[pkg]; !ok {\n\t\treturn nil\n\t}\n\tit, ok := i.m[pkg][name]\n\tif !ok {\n\t\treturn nil\n\t}\n\treturn it.it\n}\n\ntype fileParser struct {\n\tfileSet            *token.FileSet\n\timports            map[string]importedPackage // package name => imported package\n\timportedInterfaces *interfaceCache\n\tauxFiles           []*ast.File\n\tauxInterfaces      *interfaceCache\n\tsrcDir             string\n\texcludeNamesSet    map[string]struct{}\n}\n\nfunc (p *fileParser) errorf(pos token.Pos, format string, args ...any) error {\n\tps := p.fileSet.Position(pos)\n\tformat = \"%s:%d:%d: \" + format\n\targs = append([]any{ps.Filename, ps.Line, ps.Column}, args...)\n\treturn fmt.Errorf(format, args...)\n}\n\nfunc (p *fileParser) parseAuxFiles(auxFiles string) error {\n\tauxFiles = strings.TrimSpace(auxFiles)\n\tif auxFiles == \"\" {\n\t\treturn nil\n\t}\n\tfor _, kv := range strings.Split(auxFiles, \",\") {\n\t\tparts := strings.SplitN(kv, \"=\", 2)\n\t\tif len(parts) != 2 {\n\t\t\treturn fmt.Errorf(\"bad aux file spec: %v\", kv)\n\t\t}\n\t\tpkg, fpath := parts[0], parts[1]\n\n\t\tfile, err := parser.ParseFile(p.fileSet, fpath, nil, 0)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tp.auxFiles = append(p.auxFiles, file)\n\t\tp.addAuxInterfacesFromFile(pkg, file)\n\t}\n\treturn nil\n}\n\nfunc (p *fileParser) addAuxInterfacesFromFile(pkg string, file *ast.File) {\n\tfor ni := range iterInterfaces(file) {\n\t\tp.auxInterfaces.Set(pkg, ni.name.Name, ni)\n\t}\n}\n\n// parseFile loads all file imports and auxiliary files import into the\n// fileParser, parses all file interfaces and returns package model.\nfunc (p *fileParser) parseFile(importPath string, file *ast.File) (*model.Package, error) {\n\tallImports, dotImports := importsOfFile(file)\n\t// Don't stomp imports provided by -imports. Those should take precedence.\n\tfor pkg, pkgI := range allImports {\n\t\tif _, ok := p.imports[pkg]; !ok {\n\t\t\tp.imports[pkg] = pkgI\n\t\t}\n\t}\n\t// Add imports from auxiliary files, which might be needed for embedded interfaces.\n\t// Don't stomp any other imports.\n\tfor _, f := range p.auxFiles {\n\t\tauxImports, _ := importsOfFile(f)\n\t\tfor pkg, pkgI := range auxImports {\n\t\t\tif _, ok := p.imports[pkg]; !ok {\n\t\t\t\tp.imports[pkg] = pkgI\n\t\t\t}\n\t\t}\n\t}\n\n\tvar is []*model.Interface\n\tfor ni := range iterInterfaces(file) {\n\t\tif _, ok := p.excludeNamesSet[ni.name.String()]; ok {\n\t\t\tcontinue\n\t\t}\n\t\ti, err := p.parseInterface(ni.name.String(), importPath, ni)\n\t\tif errors.Is(err, errConstraintInterface) {\n\t\t\tcontinue\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tis = append(is, i)\n\t}\n\treturn &model.Package{\n\t\tName:       file.Name.String(),\n\t\tPkgPath:    importPath,\n\t\tInterfaces: is,\n\t\tDotImports: dotImports,\n\t}, nil\n}\n\n// parsePackage loads package specified by path, parses it and returns\n// a new fileParser with the parsed imports and interfaces.\nfunc (p *fileParser) parsePackage(path string) (*fileParser, error) {\n\tnewP := &fileParser{\n\t\tfileSet:            token.NewFileSet(),\n\t\timports:            make(map[string]importedPackage),\n\t\timportedInterfaces: newInterfaceCache(),\n\t\tauxInterfaces:      newInterfaceCache(),\n\t\tsrcDir:             p.srcDir,\n\t}\n\n\tvar pkgs map[string]*ast.Package\n\tif imp, err := build.Import(path, newP.srcDir, build.FindOnly); err != nil {\n\t\treturn nil, err\n\t} else if pkgs, err = parser.ParseDir(newP.fileSet, imp.Dir, nil, 0); err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, pkg := range pkgs {\n\t\tfile := ast.MergePackageFiles(pkg, ast.FilterFuncDuplicates|ast.FilterUnassociatedComments|ast.FilterImportDuplicates)\n\t\tfor ni := range iterInterfaces(file) {\n\t\t\tnewP.importedInterfaces.Set(path, ni.name.Name, ni)\n\t\t}\n\t\timports, _ := importsOfFile(file)\n\t\tfor pkgName, pkgI := range imports {\n\t\t\tnewP.imports[pkgName] = pkgI\n\t\t}\n\t}\n\treturn newP, nil\n}\n\nfunc (p *fileParser) constructInstParams(pkg string, params []*ast.Field, instParams []model.Type, embeddedInstParams []ast.Expr, tps map[string]model.Type) ([]model.Type, error) {\n\tpm := make(map[string]int)\n\tvar i int\n\tfor _, v := range params {\n\t\tfor _, n := range v.Names {\n\t\t\tpm[n.Name] = i\n\t\t\tinstParams = append(instParams, model.PredeclaredType(n.Name))\n\t\t\ti++\n\t\t}\n\t}\n\n\tvar runtimeInstParams []model.Type\n\tfor _, instParam := range embeddedInstParams {\n\t\tswitch t := instParam.(type) {\n\t\tcase *ast.Ident:\n\t\t\tif idx, ok := pm[t.Name]; ok {\n\t\t\t\truntimeInstParams = append(runtimeInstParams, instParams[idx])\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tmodelType, err := p.parseType(pkg, instParam, tps)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\truntimeInstParams = append(runtimeInstParams, modelType)\n\t}\n\n\treturn runtimeInstParams, nil\n}\n\nfunc (p *fileParser) constructTps(it *namedInterface) (tps map[string]model.Type) {\n\ttps = make(map[string]model.Type)\n\tn := 0\n\tfor _, tp := range it.typeParams {\n\t\tfor _, tm := range tp.Names {\n\t\t\ttps[tm.Name] = nil\n\t\t\tif len(it.instTypes) != 0 {\n\t\t\t\ttps[tm.Name] = it.instTypes[n]\n\t\t\t\tn++\n\t\t\t}\n\t\t}\n\t}\n\treturn tps\n}\n\n// parseInterface loads interface specified by pkg and name, parses it and returns\n// a new model with the parsed.\nfunc (p *fileParser) parseInterface(name, pkg string, it *namedInterface) (*model.Interface, error) {\n\tiface := &model.Interface{Name: name}\n\ttps := p.constructTps(it)\n\ttp, err := p.parseFieldList(pkg, it.typeParams, tps)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to parse interface type parameters: %v\", name)\n\t}\n\n\tiface.TypeParams = tp\n\tfor _, field := range it.it.Methods.List {\n\t\tvar methods []*model.Method\n\t\tif methods, err = p.parseMethod(field, it, iface, pkg, tps); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfor _, m := range methods {\n\t\t\tiface.AddMethod(m)\n\t\t}\n\t}\n\treturn iface, nil\n}\n\nfunc (p *fileParser) parseMethod(field *ast.Field, it *namedInterface, iface *model.Interface, pkg string, tps map[string]model.Type) ([]*model.Method, error) {\n\t// {} for git diff\n\t{\n\t\tswitch v := field.Type.(type) {\n\t\tcase *ast.FuncType:\n\t\t\tif nn := len(field.Names); nn != 1 {\n\t\t\t\treturn nil, fmt.Errorf(\"expected one name for interface %v, got %d\", iface.Name, nn)\n\t\t\t}\n\t\t\tm := &model.Method{\n\t\t\t\tName: field.Names[0].String(),\n\t\t\t}\n\t\t\tvar err error\n\t\t\tm.In, m.Variadic, m.Out, err = p.parseFunc(pkg, v, tps)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn []*model.Method{m}, nil\n\t\tcase *ast.Ident:\n\t\t\t// Embedded interface in this package.\n\t\t\tembeddedIfaceType := p.auxInterfaces.Get(pkg, v.String())\n\t\t\tif embeddedIfaceType == nil {\n\t\t\t\tembeddedIfaceType = p.importedInterfaces.Get(pkg, v.String())\n\t\t\t}\n\n\t\t\tvar embeddedIface *model.Interface\n\t\t\tif embeddedIfaceType != nil {\n\t\t\t\tvar err error\n\t\t\t\tembeddedIfaceType.instTypes, err = p.constructInstParams(pkg, it.typeParams, it.instTypes, it.embeddedInstTypeParams, tps)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tembeddedIface, err = p.parseInterface(v.String(), pkg, embeddedIfaceType)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\t// This is built-in error interface.\n\t\t\t\tif v.String() == model.ErrorInterface.Name {\n\t\t\t\t\tembeddedIface = &model.ErrorInterface\n\t\t\t\t} else {\n\t\t\t\t\tip, err := p.parsePackage(pkg)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, p.errorf(v.Pos(), \"could not parse package %s: %v\", pkg, err)\n\t\t\t\t\t}\n\n\t\t\t\t\tif embeddedIfaceType = ip.importedInterfaces.Get(pkg, v.String()); embeddedIfaceType == nil {\n\t\t\t\t\t\treturn nil, p.errorf(v.Pos(), \"unknown embedded interface %s.%s\", pkg, v.String())\n\t\t\t\t\t}\n\n\t\t\t\t\tembeddedIfaceType.instTypes, err = p.constructInstParams(pkg, it.typeParams, it.instTypes, it.embeddedInstTypeParams, tps)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\t\t\t\t\tembeddedIface, err = ip.parseInterface(v.String(), pkg, embeddedIfaceType)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn embeddedIface.Methods, nil\n\t\tcase *ast.SelectorExpr:\n\t\t\t// Embedded interface in another package.\n\t\t\tfilePkg, sel := v.X.(*ast.Ident).String(), v.Sel.String()\n\t\t\tembeddedPkg, ok := p.imports[filePkg]\n\t\t\tif !ok {\n\t\t\t\treturn nil, p.errorf(v.X.Pos(), \"unknown package %s\", filePkg)\n\t\t\t}\n\n\t\t\tvar embeddedIface *model.Interface\n\t\t\tvar err error\n\t\t\tembeddedIfaceType := p.auxInterfaces.Get(filePkg, sel)\n\t\t\tif embeddedIfaceType != nil {\n\t\t\t\tembeddedIfaceType.instTypes, err = p.constructInstParams(pkg, it.typeParams, it.instTypes, it.embeddedInstTypeParams, tps)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tembeddedIface, err = p.parseInterface(sel, filePkg, embeddedIfaceType)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpath := embeddedPkg.Path()\n\t\t\t\tparser := embeddedPkg.Parser()\n\t\t\t\tif parser == nil {\n\t\t\t\t\tip, err := p.parsePackage(path)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, p.errorf(v.Pos(), \"could not parse package %s: %v\", path, err)\n\t\t\t\t\t}\n\t\t\t\t\tparser = ip\n\t\t\t\t\tp.imports[filePkg] = importedPkg{\n\t\t\t\t\t\tpath:   embeddedPkg.Path(),\n\t\t\t\t\t\tparser: parser,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif embeddedIfaceType = parser.importedInterfaces.Get(path, sel); embeddedIfaceType == nil {\n\t\t\t\t\treturn nil, p.errorf(v.Pos(), \"unknown embedded interface %s.%s\", path, sel)\n\t\t\t\t}\n\n\t\t\t\tembeddedIfaceType.instTypes, err = p.constructInstParams(pkg, it.typeParams, it.instTypes, it.embeddedInstTypeParams, tps)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tembeddedIface, err = parser.parseInterface(sel, path, embeddedIfaceType)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t}\n\t\t\t// TODO: apply shadowing rules.\n\t\t\treturn embeddedIface.Methods, nil\n\t\tdefault:\n\t\t\treturn p.parseGenericMethod(field, it, iface, pkg, tps)\n\t\t}\n\t}\n}\n\nfunc (p *fileParser) parseFunc(pkg string, f *ast.FuncType, tps map[string]model.Type) (inParam []*model.Parameter, variadic *model.Parameter, outParam []*model.Parameter, err error) {\n\tif f.Params != nil {\n\t\tregParams := f.Params.List\n\t\tif isVariadic(f) {\n\t\t\tn := len(regParams)\n\t\t\tvarParams := regParams[n-1:]\n\t\t\tregParams = regParams[:n-1]\n\t\t\tvp, err := p.parseFieldList(pkg, varParams, tps)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, nil, nil, p.errorf(varParams[0].Pos(), \"failed parsing variadic argument: %v\", err)\n\t\t\t}\n\t\t\tvariadic = vp[0]\n\t\t}\n\t\tinParam, err = p.parseFieldList(pkg, regParams, tps)\n\t\tif err != nil {\n\t\t\treturn nil, nil, nil, p.errorf(f.Pos(), \"failed parsing arguments: %v\", err)\n\t\t}\n\t}\n\tif f.Results != nil {\n\t\toutParam, err = p.parseFieldList(pkg, f.Results.List, tps)\n\t\tif err != nil {\n\t\t\treturn nil, nil, nil, p.errorf(f.Pos(), \"failed parsing returns: %v\", err)\n\t\t}\n\t}\n\treturn\n}\n\nfunc (p *fileParser) parseFieldList(pkg string, fields []*ast.Field, tps map[string]model.Type) ([]*model.Parameter, error) {\n\tnf := 0\n\tfor _, f := range fields {\n\t\tnn := len(f.Names)\n\t\tif nn == 0 {\n\t\t\tnn = 1 // anonymous parameter\n\t\t}\n\t\tnf += nn\n\t}\n\tif nf == 0 {\n\t\treturn nil, nil\n\t}\n\tps := make([]*model.Parameter, nf)\n\ti := 0 // destination index\n\tfor _, f := range fields {\n\t\tt, err := p.parseType(pkg, f.Type, tps)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif len(f.Names) == 0 {\n\t\t\t// anonymous arg\n\t\t\tps[i] = &model.Parameter{Type: t}\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\t\tfor _, name := range f.Names {\n\t\t\tps[i] = &model.Parameter{Name: name.Name, Type: t}\n\t\t\ti++\n\t\t}\n\t}\n\treturn ps, nil\n}\n\nfunc (p *fileParser) parseType(pkg string, typ ast.Expr, tps map[string]model.Type) (model.Type, error) {\n\tswitch v := typ.(type) {\n\tcase *ast.ArrayType:\n\t\tln := -1\n\t\tif v.Len != nil {\n\t\t\tvalue, err := p.parseArrayLength(v.Len)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tln, err = strconv.Atoi(value)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, p.errorf(v.Len.Pos(), \"bad array size: %v\", err)\n\t\t\t}\n\t\t}\n\t\tt, err := p.parseType(pkg, v.Elt, tps)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &model.ArrayType{Len: ln, Type: t}, nil\n\tcase *ast.ChanType:\n\t\tt, err := p.parseType(pkg, v.Value, tps)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvar dir model.ChanDir\n\t\tif v.Dir == ast.SEND {\n\t\t\tdir = model.SendDir\n\t\t}\n\t\tif v.Dir == ast.RECV {\n\t\t\tdir = model.RecvDir\n\t\t}\n\t\treturn &model.ChanType{Dir: dir, Type: t}, nil\n\tcase *ast.Ellipsis:\n\t\t// assume we're parsing a variadic argument\n\t\treturn p.parseType(pkg, v.Elt, tps)\n\tcase *ast.FuncType:\n\t\tin, variadic, out, err := p.parseFunc(pkg, v, tps)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &model.FuncType{In: in, Out: out, Variadic: variadic}, nil\n\tcase *ast.Ident:\n\t\tit, ok := tps[v.Name]\n\t\tif v.IsExported() && !ok {\n\t\t\t// `pkg` may be an aliased imported pkg\n\t\t\t// if so, patch the import w/ the fully qualified import\n\t\t\tmaybeImportedPkg, ok := p.imports[pkg]\n\t\t\tif ok {\n\t\t\t\tpkg = maybeImportedPkg.Path()\n\t\t\t}\n\t\t\t// assume type in this package\n\t\t\treturn &model.NamedType{Package: pkg, Type: v.Name}, nil\n\t\t}\n\t\tif ok && it != nil {\n\t\t\treturn it, nil\n\t\t}\n\t\t// assume predeclared type\n\t\treturn model.PredeclaredType(v.Name), nil\n\tcase *ast.InterfaceType:\n\t\tif v.Methods != nil && len(v.Methods.List) > 0 {\n\t\t\treturn nil, p.errorf(v.Pos(), \"can't handle non-empty unnamed interface types\")\n\t\t}\n\t\treturn model.PredeclaredType(\"any\"), nil\n\tcase *ast.MapType:\n\t\tkey, err := p.parseType(pkg, v.Key, tps)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalue, err := p.parseType(pkg, v.Value, tps)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &model.MapType{Key: key, Value: value}, nil\n\tcase *ast.SelectorExpr:\n\t\tpkgName := v.X.(*ast.Ident).String()\n\t\tpkg, ok := p.imports[pkgName]\n\t\tif !ok {\n\t\t\treturn nil, p.errorf(v.Pos(), \"unknown package %q\", pkgName)\n\t\t}\n\t\treturn &model.NamedType{Package: pkg.Path(), Type: v.Sel.String()}, nil\n\tcase *ast.StarExpr:\n\t\tt, err := p.parseType(pkg, v.X, tps)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &model.PointerType{Type: t}, nil\n\tcase *ast.StructType:\n\t\tif v.Fields != nil && len(v.Fields.List) > 0 {\n\t\t\treturn nil, p.errorf(v.Pos(), \"can't handle non-empty unnamed struct types\")\n\t\t}\n\t\treturn model.PredeclaredType(\"struct{}\"), nil\n\tcase *ast.ParenExpr:\n\t\treturn p.parseType(pkg, v.X, tps)\n\tdefault:\n\t\tmt, err := p.parseGenericType(pkg, typ, tps)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif mt == nil {\n\t\t\tbreak\n\t\t}\n\t\treturn mt, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"don't know how to parse type %T\", typ)\n}\n\nfunc (p *fileParser) parseArrayLength(expr ast.Expr) (string, error) {\n\tswitch val := expr.(type) {\n\tcase (*ast.BasicLit):\n\t\treturn val.Value, nil\n\tcase (*ast.Ident):\n\t\t// when the length is a const defined locally\n\t\treturn val.Obj.Decl.(*ast.ValueSpec).Values[0].(*ast.BasicLit).Value, nil\n\tcase (*ast.SelectorExpr):\n\t\t// when the length is a const defined in an external package\n\t\tusedPkg, err := importer.Default().Import(fmt.Sprintf(\"%s\", val.X))\n\t\tif err != nil {\n\t\t\treturn \"\", p.errorf(expr.Pos(), \"unknown package in array length: %v\", err)\n\t\t}\n\t\tev, err := types.Eval(token.NewFileSet(), usedPkg, token.NoPos, val.Sel.Name)\n\t\tif err != nil {\n\t\t\treturn \"\", p.errorf(expr.Pos(), \"unknown constant in array length: %v\", err)\n\t\t}\n\t\treturn ev.Value.String(), nil\n\tcase (*ast.ParenExpr):\n\t\treturn p.parseArrayLength(val.X)\n\tcase (*ast.BinaryExpr):\n\t\tx, err := p.parseArrayLength(val.X)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\ty, err := p.parseArrayLength(val.Y)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tbiExpr := fmt.Sprintf(\"%s%v%s\", x, val.Op, y)\n\t\ttv, err := types.Eval(token.NewFileSet(), nil, token.NoPos, biExpr)\n\t\tif err != nil {\n\t\t\treturn \"\", p.errorf(expr.Pos(), \"invalid expression in array length: %v\", err)\n\t\t}\n\t\treturn tv.Value.String(), nil\n\tdefault:\n\t\treturn \"\", p.errorf(expr.Pos(), \"invalid expression in array length: %v\", val)\n\t}\n}\n\n// importsOfFile returns a map of package name to import path\n// of the imports in file.\nfunc importsOfFile(file *ast.File) (normalImports map[string]importedPackage, dotImports []string) {\n\tvar importPaths []string\n\tfor _, is := range file.Imports {\n\t\tif is.Name != nil {\n\t\t\tcontinue\n\t\t}\n\t\timportPath := is.Path.Value[1 : len(is.Path.Value)-1] // remove quotes\n\t\timportPaths = append(importPaths, importPath)\n\t}\n\tpackagesName := createPackageMap(importPaths)\n\tnormalImports = make(map[string]importedPackage)\n\tdotImports = make([]string, 0)\n\tfor _, is := range file.Imports {\n\t\tvar pkgName string\n\t\timportPath := is.Path.Value[1 : len(is.Path.Value)-1] // remove quotes\n\n\t\tif is.Name != nil {\n\t\t\t// Named imports are always certain.\n\t\t\tif is.Name.Name == \"_\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tpkgName = is.Name.Name\n\t\t} else {\n\t\t\tpkg, ok := packagesName[importPath]\n\t\t\tif !ok {\n\t\t\t\t// Fallback to import path suffix. Note that this is uncertain.\n\t\t\t\t_, last := path.Split(importPath)\n\t\t\t\t// If the last path component has dots, the first dot-delimited\n\t\t\t\t// field is used as the name.\n\t\t\t\tpkgName = strings.SplitN(last, \".\", 2)[0]\n\t\t\t} else {\n\t\t\t\tpkgName = pkg\n\t\t\t}\n\t\t}\n\n\t\tif pkgName == \".\" {\n\t\t\tdotImports = append(dotImports, importPath)\n\t\t} else {\n\t\t\tif pkg, ok := normalImports[pkgName]; ok {\n\t\t\t\tswitch p := pkg.(type) {\n\t\t\t\tcase duplicateImport:\n\t\t\t\t\tnormalImports[pkgName] = duplicateImport{\n\t\t\t\t\t\tname:       p.name,\n\t\t\t\t\t\tduplicates: append([]string{importPath}, p.duplicates...),\n\t\t\t\t\t}\n\t\t\t\tcase importedPkg:\n\t\t\t\t\tnormalImports[pkgName] = duplicateImport{\n\t\t\t\t\t\tname:       pkgName,\n\t\t\t\t\t\tduplicates: []string{p.path, importPath},\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnormalImports[pkgName] = importedPkg{path: importPath}\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\ntype namedInterface struct {\n\tname                   *ast.Ident\n\tit                     *ast.InterfaceType\n\ttypeParams             []*ast.Field\n\tembeddedInstTypeParams []ast.Expr\n\tinstTypes              []model.Type\n}\n\n// Create an iterator over all interfaces in file.\nfunc iterInterfaces(file *ast.File) <-chan *namedInterface {\n\tch := make(chan *namedInterface)\n\tgo func() {\n\t\tfor _, decl := range file.Decls {\n\t\t\tgd, ok := decl.(*ast.GenDecl)\n\t\t\tif !ok || gd.Tok != token.TYPE {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfor _, spec := range gd.Specs {\n\t\t\t\tts, ok := spec.(*ast.TypeSpec)\n\t\t\t\tif !ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tit, ok := ts.Type.(*ast.InterfaceType)\n\t\t\t\tif !ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tch <- &namedInterface{name: ts.Name, it: it, typeParams: getTypeSpecTypeParams(ts)}\n\t\t\t}\n\t\t}\n\t\tclose(ch)\n\t}()\n\treturn ch\n}\n\n// isVariadic returns whether the function is variadic.\nfunc isVariadic(f *ast.FuncType) bool {\n\tnargs := len(f.Params.List)\n\tif nargs == 0 {\n\t\treturn false\n\t}\n\t_, ok := f.Params.List[nargs-1].Type.(*ast.Ellipsis)\n\treturn ok\n}\n\n// packageNameOfDir get package import path via dir\nfunc packageNameOfDir(srcDir string) (string, error) {\n\tfiles, err := os.ReadDir(srcDir)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tvar goFilePath string\n\tfor _, file := range files {\n\t\tif !file.IsDir() && strings.HasSuffix(file.Name(), \".go\") {\n\t\t\tgoFilePath = file.Name()\n\t\t\tbreak\n\t\t}\n\t}\n\tif goFilePath == \"\" {\n\t\treturn \"\", fmt.Errorf(\"go source file not found %s\", srcDir)\n\t}\n\n\tpackageImport, err := parsePackageImport(srcDir)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn packageImport, nil\n}\n\nvar errOutsideGoPath = errors.New(\"source directory is outside GOPATH\")\n"
  },
  {
    "path": "vendor/go.uber.org/mock/mockgen/version.go",
    "content": "// Copyright 2022 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"runtime/debug\"\n)\n\nfunc printModuleVersion() {\n\tif bi, exists := debug.ReadBuildInfo(); exists {\n\t\tfmt.Println(bi.Main.Version)\n\t} else {\n\t\tlog.Printf(\"No version information found. Make sure to use \" +\n\t\t\t\"GO111MODULE=on when running 'go get' in order to use specific \" +\n\t\t\t\"version of the binary.\")\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/LICENSE",
    "content": "Copyright 2009 The Go Authors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google LLC nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(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": "vendor/golang.org/x/crypto/PATENTS",
    "content": "Additional IP Rights Grant (Patents)\n\n\"This implementation\" means the copyrightable works distributed by\nGoogle as part of the Go project.\n\nGoogle hereby grants to You a perpetual, worldwide, non-exclusive,\nno-charge, royalty-free, irrevocable (except as stated in this section)\npatent license to make, have made, use, offer to sell, sell, import,\ntransfer and otherwise run, modify and propagate the contents of this\nimplementation of Go, where such license applies only to those patent\nclaims, both currently owned or controlled by Google and acquired in\nthe future, licensable by Google that are necessarily infringed by this\nimplementation of Go.  This grant does not include claims that would be\ninfringed only as a consequence of further modification of this\nimplementation.  If you or your agent or exclusive licensee institute or\norder or agree to the institution of patent litigation against any\nentity (including a cross-claim or counterclaim in a lawsuit) alleging\nthat this implementation of Go or any code incorporated within this\nimplementation of Go constitutes direct or contributory patent\ninfringement, or inducement of patent infringement, then any patent\nrights granted to you under this License for this implementation of Go\nshall terminate as of the date such litigation is filed.\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/blake2b/blake2b.go",
    "content": "// Copyright 2016 The Go 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\n// Package blake2b implements the BLAKE2b hash algorithm defined by RFC 7693\n// and the extendable output function (XOF) BLAKE2Xb.\n//\n// BLAKE2b is optimized for 64-bit platforms—including NEON-enabled ARMs—and\n// produces digests of any size between 1 and 64 bytes.\n// For a detailed specification of BLAKE2b see https://blake2.net/blake2.pdf\n// and for BLAKE2Xb see https://blake2.net/blake2x.pdf\n//\n// If you aren't sure which function you need, use BLAKE2b (Sum512 or New512).\n// If you need a secret-key MAC (message authentication code), use the New512\n// function with a non-nil key.\n//\n// BLAKE2X is a construction to compute hash values larger than 64 bytes. It\n// can produce hash values between 0 and 4 GiB.\npackage blake2b\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"hash\"\n)\n\nconst (\n\t// The blocksize of BLAKE2b in bytes.\n\tBlockSize = 128\n\t// The hash size of BLAKE2b-512 in bytes.\n\tSize = 64\n\t// The hash size of BLAKE2b-384 in bytes.\n\tSize384 = 48\n\t// The hash size of BLAKE2b-256 in bytes.\n\tSize256 = 32\n)\n\nvar (\n\tuseAVX2 bool\n\tuseAVX  bool\n\tuseSSE4 bool\n)\n\nvar (\n\terrKeySize  = errors.New(\"blake2b: invalid key size\")\n\terrHashSize = errors.New(\"blake2b: invalid hash size\")\n)\n\nvar iv = [8]uint64{\n\t0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,\n\t0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,\n}\n\n// Sum512 returns the BLAKE2b-512 checksum of the data.\nfunc Sum512(data []byte) [Size]byte {\n\tvar sum [Size]byte\n\tcheckSum(&sum, Size, data)\n\treturn sum\n}\n\n// Sum384 returns the BLAKE2b-384 checksum of the data.\nfunc Sum384(data []byte) [Size384]byte {\n\tvar sum [Size]byte\n\tvar sum384 [Size384]byte\n\tcheckSum(&sum, Size384, data)\n\tcopy(sum384[:], sum[:Size384])\n\treturn sum384\n}\n\n// Sum256 returns the BLAKE2b-256 checksum of the data.\nfunc Sum256(data []byte) [Size256]byte {\n\tvar sum [Size]byte\n\tvar sum256 [Size256]byte\n\tcheckSum(&sum, Size256, data)\n\tcopy(sum256[:], sum[:Size256])\n\treturn sum256\n}\n\n// New512 returns a new hash.Hash computing the BLAKE2b-512 checksum. A non-nil\n// key turns the hash into a MAC. The key must be between zero and 64 bytes long.\nfunc New512(key []byte) (hash.Hash, error) { return newDigest(Size, key) }\n\n// New384 returns a new hash.Hash computing the BLAKE2b-384 checksum. A non-nil\n// key turns the hash into a MAC. The key must be between zero and 64 bytes long.\nfunc New384(key []byte) (hash.Hash, error) { return newDigest(Size384, key) }\n\n// New256 returns a new hash.Hash computing the BLAKE2b-256 checksum. A non-nil\n// key turns the hash into a MAC. The key must be between zero and 64 bytes long.\nfunc New256(key []byte) (hash.Hash, error) { return newDigest(Size256, key) }\n\n// New returns a new hash.Hash computing the BLAKE2b checksum with a custom length.\n// A non-nil key turns the hash into a MAC. The key must be between zero and 64 bytes long.\n// The hash size can be a value between 1 and 64 but it is highly recommended to use\n// values equal or greater than:\n// - 32 if BLAKE2b is used as a hash function (The key is zero bytes long).\n// - 16 if BLAKE2b is used as a MAC function (The key is at least 16 bytes long).\n// When the key is nil, the returned hash.Hash implements BinaryMarshaler\n// and BinaryUnmarshaler for state (de)serialization as documented by hash.Hash.\nfunc New(size int, key []byte) (hash.Hash, error) { return newDigest(size, key) }\n\nfunc newDigest(hashSize int, key []byte) (*digest, error) {\n\tif hashSize < 1 || hashSize > Size {\n\t\treturn nil, errHashSize\n\t}\n\tif len(key) > Size {\n\t\treturn nil, errKeySize\n\t}\n\td := &digest{\n\t\tsize:   hashSize,\n\t\tkeyLen: len(key),\n\t}\n\tcopy(d.key[:], key)\n\td.Reset()\n\treturn d, nil\n}\n\nfunc checkSum(sum *[Size]byte, hashSize int, data []byte) {\n\th := iv\n\th[0] ^= uint64(hashSize) | (1 << 16) | (1 << 24)\n\tvar c [2]uint64\n\n\tif length := len(data); length > BlockSize {\n\t\tn := length &^ (BlockSize - 1)\n\t\tif length == n {\n\t\t\tn -= BlockSize\n\t\t}\n\t\thashBlocks(&h, &c, 0, data[:n])\n\t\tdata = data[n:]\n\t}\n\n\tvar block [BlockSize]byte\n\toffset := copy(block[:], data)\n\tremaining := uint64(BlockSize - offset)\n\tif c[0] < remaining {\n\t\tc[1]--\n\t}\n\tc[0] -= remaining\n\n\thashBlocks(&h, &c, 0xFFFFFFFFFFFFFFFF, block[:])\n\n\tfor i, v := range h[:(hashSize+7)/8] {\n\t\tbinary.LittleEndian.PutUint64(sum[8*i:], v)\n\t}\n}\n\ntype digest struct {\n\th      [8]uint64\n\tc      [2]uint64\n\tsize   int\n\tblock  [BlockSize]byte\n\toffset int\n\n\tkey    [BlockSize]byte\n\tkeyLen int\n}\n\nconst (\n\tmagic         = \"b2b\"\n\tmarshaledSize = len(magic) + 8*8 + 2*8 + 1 + BlockSize + 1\n)\n\nfunc (d *digest) MarshalBinary() ([]byte, error) {\n\tif d.keyLen != 0 {\n\t\treturn nil, errors.New(\"crypto/blake2b: cannot marshal MACs\")\n\t}\n\tb := make([]byte, 0, marshaledSize)\n\tb = append(b, magic...)\n\tfor i := 0; i < 8; i++ {\n\t\tb = appendUint64(b, d.h[i])\n\t}\n\tb = appendUint64(b, d.c[0])\n\tb = appendUint64(b, d.c[1])\n\t// Maximum value for size is 64\n\tb = append(b, byte(d.size))\n\tb = append(b, d.block[:]...)\n\tb = append(b, byte(d.offset))\n\treturn b, nil\n}\n\nfunc (d *digest) UnmarshalBinary(b []byte) error {\n\tif len(b) < len(magic) || string(b[:len(magic)]) != magic {\n\t\treturn errors.New(\"crypto/blake2b: invalid hash state identifier\")\n\t}\n\tif len(b) != marshaledSize {\n\t\treturn errors.New(\"crypto/blake2b: invalid hash state size\")\n\t}\n\tb = b[len(magic):]\n\tfor i := 0; i < 8; i++ {\n\t\tb, d.h[i] = consumeUint64(b)\n\t}\n\tb, d.c[0] = consumeUint64(b)\n\tb, d.c[1] = consumeUint64(b)\n\td.size = int(b[0])\n\tb = b[1:]\n\tcopy(d.block[:], b[:BlockSize])\n\tb = b[BlockSize:]\n\td.offset = int(b[0])\n\treturn nil\n}\n\nfunc (d *digest) BlockSize() int { return BlockSize }\n\nfunc (d *digest) Size() int { return d.size }\n\nfunc (d *digest) Reset() {\n\td.h = iv\n\td.h[0] ^= uint64(d.size) | (uint64(d.keyLen) << 8) | (1 << 16) | (1 << 24)\n\td.offset, d.c[0], d.c[1] = 0, 0, 0\n\tif d.keyLen > 0 {\n\t\td.block = d.key\n\t\td.offset = BlockSize\n\t}\n}\n\nfunc (d *digest) Write(p []byte) (n int, err error) {\n\tn = len(p)\n\n\tif d.offset > 0 {\n\t\tremaining := BlockSize - d.offset\n\t\tif n <= remaining {\n\t\t\td.offset += copy(d.block[d.offset:], p)\n\t\t\treturn\n\t\t}\n\t\tcopy(d.block[d.offset:], p[:remaining])\n\t\thashBlocks(&d.h, &d.c, 0, d.block[:])\n\t\td.offset = 0\n\t\tp = p[remaining:]\n\t}\n\n\tif length := len(p); length > BlockSize {\n\t\tnn := length &^ (BlockSize - 1)\n\t\tif length == nn {\n\t\t\tnn -= BlockSize\n\t\t}\n\t\thashBlocks(&d.h, &d.c, 0, p[:nn])\n\t\tp = p[nn:]\n\t}\n\n\tif len(p) > 0 {\n\t\td.offset += copy(d.block[:], p)\n\t}\n\n\treturn\n}\n\nfunc (d *digest) Sum(sum []byte) []byte {\n\tvar hash [Size]byte\n\td.finalize(&hash)\n\treturn append(sum, hash[:d.size]...)\n}\n\nfunc (d *digest) finalize(hash *[Size]byte) {\n\tvar block [BlockSize]byte\n\tcopy(block[:], d.block[:d.offset])\n\tremaining := uint64(BlockSize - d.offset)\n\n\tc := d.c\n\tif c[0] < remaining {\n\t\tc[1]--\n\t}\n\tc[0] -= remaining\n\n\th := d.h\n\thashBlocks(&h, &c, 0xFFFFFFFFFFFFFFFF, block[:])\n\n\tfor i, v := range h {\n\t\tbinary.LittleEndian.PutUint64(hash[8*i:], v)\n\t}\n}\n\nfunc appendUint64(b []byte, x uint64) []byte {\n\tvar a [8]byte\n\tbinary.BigEndian.PutUint64(a[:], x)\n\treturn append(b, a[:]...)\n}\n\nfunc appendUint32(b []byte, x uint32) []byte {\n\tvar a [4]byte\n\tbinary.BigEndian.PutUint32(a[:], x)\n\treturn append(b, a[:]...)\n}\n\nfunc consumeUint64(b []byte) ([]byte, uint64) {\n\tx := binary.BigEndian.Uint64(b)\n\treturn b[8:], x\n}\n\nfunc consumeUint32(b []byte) ([]byte, uint32) {\n\tx := binary.BigEndian.Uint32(b)\n\treturn b[4:], x\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.go",
    "content": "// Copyright 2016 The Go 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\n//go:build amd64 && gc && !purego\n\npackage blake2b\n\nimport \"golang.org/x/sys/cpu\"\n\nfunc init() {\n\tuseAVX2 = cpu.X86.HasAVX2\n\tuseAVX = cpu.X86.HasAVX\n\tuseSSE4 = cpu.X86.HasSSE41\n}\n\n//go:noescape\nfunc hashBlocksAVX2(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)\n\n//go:noescape\nfunc hashBlocksAVX(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)\n\n//go:noescape\nfunc hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)\n\nfunc hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {\n\tswitch {\n\tcase useAVX2:\n\t\thashBlocksAVX2(h, c, flag, blocks)\n\tcase useAVX:\n\t\thashBlocksAVX(h, c, flag, blocks)\n\tcase useSSE4:\n\t\thashBlocksSSE4(h, c, flag, blocks)\n\tdefault:\n\t\thashBlocksGeneric(h, c, flag, blocks)\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/blake2b/blake2bAVX2_amd64.s",
    "content": "// Code generated by command: go run blake2bAVX2_amd64_asm.go -out ../../blake2bAVX2_amd64.s -pkg blake2b. DO NOT EDIT.\n\n//go:build amd64 && gc && !purego\n\n#include \"textflag.h\"\n\n// func hashBlocksAVX2(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)\n// Requires: AVX, AVX2\nTEXT ·hashBlocksAVX2(SB), NOSPLIT, $320-48\n\tMOVQ    h+0(FP), AX\n\tMOVQ    c+8(FP), BX\n\tMOVQ    flag+16(FP), CX\n\tMOVQ    blocks_base+24(FP), SI\n\tMOVQ    blocks_len+32(FP), DI\n\tMOVQ    SP, DX\n\tADDQ    $+31, DX\n\tANDQ    $-32, DX\n\tMOVQ    CX, 16(DX)\n\tXORQ    CX, CX\n\tMOVQ    CX, 24(DX)\n\tVMOVDQU ·AVX2_c40<>+0(SB), Y4\n\tVMOVDQU ·AVX2_c48<>+0(SB), Y5\n\tVMOVDQU (AX), Y8\n\tVMOVDQU 32(AX), Y9\n\tVMOVDQU ·AVX2_iv0<>+0(SB), Y6\n\tVMOVDQU ·AVX2_iv1<>+0(SB), Y7\n\tMOVQ    (BX), R8\n\tMOVQ    8(BX), R9\n\tMOVQ    R9, 8(DX)\n\nloop:\n\tADDQ $0x80, R8\n\tMOVQ R8, (DX)\n\tCMPQ R8, $0x80\n\tJGE  noinc\n\tINCQ R9\n\tMOVQ R9, 8(DX)\n\nnoinc:\n\tVMOVDQA     Y8, Y0\n\tVMOVDQA     Y9, Y1\n\tVMOVDQA     Y6, Y2\n\tVPXOR       (DX), Y7, Y3\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x26\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x20\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x99\n\tBYTE        $0x22\n\tBYTE        $0x66\n\tBYTE        $0x10\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x30\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y12, Y12\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x6e\n\tBYTE        $0x08\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x28\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x91\n\tBYTE        $0x22\n\tBYTE        $0x6e\n\tBYTE        $0x18\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x38\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y13, Y13\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x76\n\tBYTE        $0x40\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x60\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x89\n\tBYTE        $0x22\n\tBYTE        $0x76\n\tBYTE        $0x50\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x70\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y14, Y14\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x7e\n\tBYTE        $0x48\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x68\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x81\n\tBYTE        $0x22\n\tBYTE        $0x7e\n\tBYTE        $0x58\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x78\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y15, Y15\n\tVMOVDQA     Y12, 32(DX)\n\tVMOVDQA     Y13, 64(DX)\n\tVMOVDQA     Y14, 96(DX)\n\tVMOVDQA     Y15, 128(DX)\n\tVPADDQ      Y12, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y13, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x93\n\tVPADDQ      Y14, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y15, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x93\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x66\n\tBYTE        $0x70\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x48\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x99\n\tBYTE        $0x22\n\tBYTE        $0x66\n\tBYTE        $0x20\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x68\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y12, Y12\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x6e\n\tBYTE        $0x50\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x78\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x91\n\tBYTE        $0x22\n\tBYTE        $0x6e\n\tBYTE        $0x40\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x30\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y13, Y13\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x58\n\tVPSHUFD     $0x4e, (SI), X14\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x28\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y14, Y14\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x7e\n\tBYTE        $0x60\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x38\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x81\n\tBYTE        $0x22\n\tBYTE        $0x7e\n\tBYTE        $0x10\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x18\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y15, Y15\n\tVMOVDQA     Y12, 160(DX)\n\tVMOVDQA     Y13, 192(DX)\n\tVMOVDQA     Y14, 224(DX)\n\tVMOVDQA     Y15, 256(DX)\n\tVPADDQ      Y12, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y13, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x93\n\tVPADDQ      Y14, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y15, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x93\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x28\n\tVMOVDQU     88(SI), X12\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x78\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y12, Y12\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x6e\n\tBYTE        $0x40\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x10\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x91\n\tBYTE        $0x22\n\tBYTE        $0x2e\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x68\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y13, Y13\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x76\n\tBYTE        $0x50\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x38\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x89\n\tBYTE        $0x22\n\tBYTE        $0x76\n\tBYTE        $0x18\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x48\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y14, Y14\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x7e\n\tBYTE        $0x70\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x08\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x81\n\tBYTE        $0x22\n\tBYTE        $0x7e\n\tBYTE        $0x30\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x20\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y15, Y15\n\tVPADDQ      Y12, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y13, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x93\n\tVPADDQ      Y14, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y15, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x93\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x66\n\tBYTE        $0x38\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x68\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x99\n\tBYTE        $0x22\n\tBYTE        $0x66\n\tBYTE        $0x18\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x58\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y12, Y12\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x6e\n\tBYTE        $0x48\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x60\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x91\n\tBYTE        $0x22\n\tBYTE        $0x6e\n\tBYTE        $0x08\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x70\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y13, Y13\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x76\n\tBYTE        $0x10\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x20\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x89\n\tBYTE        $0x22\n\tBYTE        $0x76\n\tBYTE        $0x28\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x78\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y14, Y14\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x7e\n\tBYTE        $0x30\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x1e\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x81\n\tBYTE        $0x22\n\tBYTE        $0x7e\n\tBYTE        $0x50\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x40\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y15, Y15\n\tVPADDQ      Y12, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y13, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x93\n\tVPADDQ      Y14, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y15, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x93\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x66\n\tBYTE        $0x48\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x10\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x99\n\tBYTE        $0x22\n\tBYTE        $0x66\n\tBYTE        $0x28\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x50\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y12, Y12\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x2e\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x20\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x91\n\tBYTE        $0x22\n\tBYTE        $0x6e\n\tBYTE        $0x38\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x78\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y13, Y13\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x76\n\tBYTE        $0x70\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x30\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x89\n\tBYTE        $0x22\n\tBYTE        $0x76\n\tBYTE        $0x58\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x18\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y14, Y14\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x7e\n\tBYTE        $0x08\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x40\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x81\n\tBYTE        $0x22\n\tBYTE        $0x7e\n\tBYTE        $0x60\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x68\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y15, Y15\n\tVPADDQ      Y12, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y13, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x93\n\tVPADDQ      Y14, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y15, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x93\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x66\n\tBYTE        $0x10\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x1e\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x99\n\tBYTE        $0x22\n\tBYTE        $0x66\n\tBYTE        $0x30\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x40\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y12, Y12\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x6e\n\tBYTE        $0x60\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x58\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x91\n\tBYTE        $0x22\n\tBYTE        $0x6e\n\tBYTE        $0x50\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x18\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y13, Y13\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x76\n\tBYTE        $0x20\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x78\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x89\n\tBYTE        $0x22\n\tBYTE        $0x76\n\tBYTE        $0x38\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x08\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y14, Y14\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x7e\n\tBYTE        $0x68\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x70\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x81\n\tBYTE        $0x22\n\tBYTE        $0x7e\n\tBYTE        $0x28\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x48\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y15, Y15\n\tVPADDQ      Y12, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y13, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x93\n\tVPADDQ      Y14, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y15, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x93\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x66\n\tBYTE        $0x60\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x70\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x99\n\tBYTE        $0x22\n\tBYTE        $0x66\n\tBYTE        $0x08\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x20\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y12, Y12\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x6e\n\tBYTE        $0x28\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x68\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x91\n\tBYTE        $0x22\n\tBYTE        $0x6e\n\tBYTE        $0x78\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x50\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y13, Y13\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x36\n\tVPSHUFD     $0x4e, 64(SI), X11\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x89\n\tBYTE        $0x22\n\tBYTE        $0x76\n\tBYTE        $0x30\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y14, Y14\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x7e\n\tBYTE        $0x38\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x10\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x81\n\tBYTE        $0x22\n\tBYTE        $0x7e\n\tBYTE        $0x18\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x58\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y15, Y15\n\tVPADDQ      Y12, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y13, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x93\n\tVPADDQ      Y14, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y15, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x93\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x66\n\tBYTE        $0x68\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x60\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x99\n\tBYTE        $0x22\n\tBYTE        $0x66\n\tBYTE        $0x38\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x18\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y12, Y12\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x6e\n\tBYTE        $0x58\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x08\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x91\n\tBYTE        $0x22\n\tBYTE        $0x6e\n\tBYTE        $0x70\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x48\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y13, Y13\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x76\n\tBYTE        $0x28\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x40\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x89\n\tBYTE        $0x22\n\tBYTE        $0x76\n\tBYTE        $0x78\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x10\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y14, Y14\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x3e\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x30\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x81\n\tBYTE        $0x22\n\tBYTE        $0x7e\n\tBYTE        $0x20\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x50\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y15, Y15\n\tVPADDQ      Y12, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y13, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x93\n\tVPADDQ      Y14, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y15, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x93\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x66\n\tBYTE        $0x30\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x58\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x99\n\tBYTE        $0x22\n\tBYTE        $0x66\n\tBYTE        $0x70\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x1e\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y12, Y12\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x6e\n\tBYTE        $0x78\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x18\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x91\n\tBYTE        $0x22\n\tBYTE        $0x6e\n\tBYTE        $0x48\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x40\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y13, Y13\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x08\n\tVMOVDQU     96(SI), X14\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x50\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y14, Y14\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x7e\n\tBYTE        $0x10\n\tVMOVDQU     32(SI), X11\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x81\n\tBYTE        $0x22\n\tBYTE        $0x7e\n\tBYTE        $0x38\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y15, Y15\n\tVPADDQ      Y12, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y13, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x93\n\tVPADDQ      Y14, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y15, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x93\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x66\n\tBYTE        $0x50\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x38\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x99\n\tBYTE        $0x22\n\tBYTE        $0x66\n\tBYTE        $0x40\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x08\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y12, Y12\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x6e\n\tBYTE        $0x10\n\tVPSHUFD     $0x4e, 40(SI), X11\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x91\n\tBYTE        $0x22\n\tBYTE        $0x6e\n\tBYTE        $0x20\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y13, Y13\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x76\n\tBYTE        $0x78\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x18\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x89\n\tBYTE        $0x22\n\tBYTE        $0x76\n\tBYTE        $0x48\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x5e\n\tBYTE        $0x68\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y14, Y14\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x7e\n\tBYTE        $0x58\n\tBYTE        $0xc5\n\tBYTE        $0x7a\n\tBYTE        $0x7e\n\tBYTE        $0x5e\n\tBYTE        $0x60\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0x81\n\tBYTE        $0x22\n\tBYTE        $0x7e\n\tBYTE        $0x70\n\tBYTE        $0x01\n\tBYTE        $0xc4\n\tBYTE        $0x63\n\tBYTE        $0xa1\n\tBYTE        $0x22\n\tBYTE        $0x1e\n\tBYTE        $0x01\n\tVINSERTI128 $0x01, X11, Y15, Y15\n\tVPADDQ      Y12, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y13, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x93\n\tVPADDQ      Y14, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      Y15, Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x93\n\tVPADDQ      32(DX), Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      64(DX), Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x93\n\tVPADDQ      96(DX), Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      128(DX), Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x93\n\tVPADDQ      160(DX), Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      192(DX), Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x93\n\tVPADDQ      224(DX), Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFD     $-79, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPSHUFB     Y4, Y1, Y1\n\tVPADDQ      256(DX), Y0, Y0\n\tVPADDQ      Y1, Y0, Y0\n\tVPXOR       Y0, Y3, Y3\n\tVPSHUFB     Y5, Y3, Y3\n\tVPADDQ      Y3, Y2, Y2\n\tVPXOR       Y2, Y1, Y1\n\tVPADDQ      Y1, Y1, Y10\n\tVPSRLQ      $0x3f, Y1, Y1\n\tVPXOR       Y10, Y1, Y1\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xdb\n\tBYTE        $0x39\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xd2\n\tBYTE        $0x4e\n\tBYTE        $0xc4\n\tBYTE        $0xe3\n\tBYTE        $0xfd\n\tBYTE        $0x00\n\tBYTE        $0xc9\n\tBYTE        $0x93\n\tVPXOR       Y0, Y8, Y8\n\tVPXOR       Y1, Y9, Y9\n\tVPXOR       Y2, Y8, Y8\n\tVPXOR       Y3, Y9, Y9\n\tLEAQ        128(SI), SI\n\tSUBQ        $0x80, DI\n\tJNE         loop\n\tMOVQ        R8, (BX)\n\tMOVQ        R9, 8(BX)\n\tVMOVDQU     Y8, (AX)\n\tVMOVDQU     Y9, 32(AX)\n\tVZEROUPPER\n\tRET\n\nDATA ·AVX2_c40<>+0(SB)/8, $0x0201000706050403\nDATA ·AVX2_c40<>+8(SB)/8, $0x0a09080f0e0d0c0b\nDATA ·AVX2_c40<>+16(SB)/8, $0x0201000706050403\nDATA ·AVX2_c40<>+24(SB)/8, $0x0a09080f0e0d0c0b\nGLOBL ·AVX2_c40<>(SB), RODATA|NOPTR, $32\n\nDATA ·AVX2_c48<>+0(SB)/8, $0x0100070605040302\nDATA ·AVX2_c48<>+8(SB)/8, $0x09080f0e0d0c0b0a\nDATA ·AVX2_c48<>+16(SB)/8, $0x0100070605040302\nDATA ·AVX2_c48<>+24(SB)/8, $0x09080f0e0d0c0b0a\nGLOBL ·AVX2_c48<>(SB), RODATA|NOPTR, $32\n\nDATA ·AVX2_iv0<>+0(SB)/8, $0x6a09e667f3bcc908\nDATA ·AVX2_iv0<>+8(SB)/8, $0xbb67ae8584caa73b\nDATA ·AVX2_iv0<>+16(SB)/8, $0x3c6ef372fe94f82b\nDATA ·AVX2_iv0<>+24(SB)/8, $0xa54ff53a5f1d36f1\nGLOBL ·AVX2_iv0<>(SB), RODATA|NOPTR, $32\n\nDATA ·AVX2_iv1<>+0(SB)/8, $0x510e527fade682d1\nDATA ·AVX2_iv1<>+8(SB)/8, $0x9b05688c2b3e6c1f\nDATA ·AVX2_iv1<>+16(SB)/8, $0x1f83d9abfb41bd6b\nDATA ·AVX2_iv1<>+24(SB)/8, $0x5be0cd19137e2179\nGLOBL ·AVX2_iv1<>(SB), RODATA|NOPTR, $32\n\n// func hashBlocksAVX(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)\n// Requires: AVX, SSE2\nTEXT ·hashBlocksAVX(SB), NOSPLIT, $288-48\n\tMOVQ    h+0(FP), AX\n\tMOVQ    c+8(FP), BX\n\tMOVQ    flag+16(FP), CX\n\tMOVQ    blocks_base+24(FP), SI\n\tMOVQ    blocks_len+32(FP), DI\n\tMOVQ    SP, R10\n\tADDQ    $0x0f, R10\n\tANDQ    $-16, R10\n\tVMOVDQU ·AVX_c40<>+0(SB), X0\n\tVMOVDQU ·AVX_c48<>+0(SB), X1\n\tVMOVDQA X0, X8\n\tVMOVDQA X1, X9\n\tVMOVDQU ·AVX_iv3<>+0(SB), X0\n\tVMOVDQA X0, (R10)\n\tXORQ    CX, (R10)\n\tVMOVDQU (AX), X10\n\tVMOVDQU 16(AX), X11\n\tVMOVDQU 32(AX), X2\n\tVMOVDQU 48(AX), X3\n\tMOVQ    (BX), R8\n\tMOVQ    8(BX), R9\n\nloop:\n\tADDQ $0x80, R8\n\tCMPQ R8, $0x80\n\tJGE  noinc\n\tINCQ R9\n\nnoinc:\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0xf9\n\tBYTE    $0x6e\n\tBYTE    $0xf8\n\tBYTE    $0xc4\n\tBYTE    $0x43\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0xf9\n\tBYTE    $0x01\n\tVMOVDQA X10, X0\n\tVMOVDQA X11, X1\n\tVMOVDQU ·AVX_iv0<>+0(SB), X4\n\tVMOVDQU ·AVX_iv1<>+0(SB), X5\n\tVMOVDQU ·AVX_iv2<>+0(SB), X6\n\tVPXOR   X15, X6, X6\n\tVMOVDQA (R10), X7\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x26\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x6e\n\tBYTE    $0x20\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x76\n\tBYTE    $0x08\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x7e\n\tBYTE    $0x28\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x99\n\tBYTE    $0x22\n\tBYTE    $0x66\n\tBYTE    $0x10\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x30\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x18\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x38\n\tBYTE    $0x01\n\tVMOVDQA X12, 16(R10)\n\tVMOVDQA X13, 32(R10)\n\tVMOVDQA X14, 48(R10)\n\tVMOVDQA X15, 64(R10)\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X6, X13\n\tVMOVDQA X2, X14\n\tVMOVDQA X4, X6\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x11\n\tBYTE    $0x6c\n\tBYTE    $0xfd\n\tVMOVDQA X5, X4\n\tVMOVDQA X6, X5\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x69\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x66\n\tBYTE    $0x40\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x6e\n\tBYTE    $0x60\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x76\n\tBYTE    $0x48\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x7e\n\tBYTE    $0x68\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x99\n\tBYTE    $0x22\n\tBYTE    $0x66\n\tBYTE    $0x50\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x70\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x58\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x78\n\tBYTE    $0x01\n\tVMOVDQA X12, 80(R10)\n\tVMOVDQA X13, 96(R10)\n\tVMOVDQA X14, 112(R10)\n\tVMOVDQA X15, 128(R10)\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X2, X13\n\tVMOVDQA X4, X14\n\tBYTE    $0xc5\n\tBYTE    $0x69\n\tBYTE    $0x6c\n\tBYTE    $0xfa\n\tVMOVDQA X5, X4\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tVMOVDQA X14, X5\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tVMOVDQA X6, X14\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x49\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x66\n\tBYTE    $0x70\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x6e\n\tBYTE    $0x48\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x76\n\tBYTE    $0x50\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x7e\n\tBYTE    $0x78\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x99\n\tBYTE    $0x22\n\tBYTE    $0x66\n\tBYTE    $0x20\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x68\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x40\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x30\n\tBYTE    $0x01\n\tVMOVDQA X12, 144(R10)\n\tVMOVDQA X13, 160(R10)\n\tVMOVDQA X14, 176(R10)\n\tVMOVDQA X15, 192(R10)\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X6, X13\n\tVMOVDQA X2, X14\n\tVMOVDQA X4, X6\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x11\n\tBYTE    $0x6c\n\tBYTE    $0xfd\n\tVMOVDQA X5, X4\n\tVMOVDQA X6, X5\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x69\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tVPSHUFD $0x4e, (SI), X12\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x6e\n\tBYTE    $0x58\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x76\n\tBYTE    $0x60\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x7e\n\tBYTE    $0x38\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x28\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x10\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x18\n\tBYTE    $0x01\n\tVMOVDQA X12, 208(R10)\n\tVMOVDQA X13, 224(R10)\n\tVMOVDQA X14, 240(R10)\n\tVMOVDQA X15, 256(R10)\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X2, X13\n\tVMOVDQA X4, X14\n\tBYTE    $0xc5\n\tBYTE    $0x69\n\tBYTE    $0x6c\n\tBYTE    $0xfa\n\tVMOVDQA X5, X4\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tVMOVDQA X14, X5\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tVMOVDQA X6, X14\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x49\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tVMOVDQU 88(SI), X12\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x6e\n\tBYTE    $0x28\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x76\n\tBYTE    $0x40\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x7e\n\tBYTE    $0x10\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x78\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x36\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x68\n\tBYTE    $0x01\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X6, X13\n\tVMOVDQA X2, X14\n\tVMOVDQA X4, X6\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x11\n\tBYTE    $0x6c\n\tBYTE    $0xfd\n\tVMOVDQA X5, X4\n\tVMOVDQA X6, X5\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x69\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x66\n\tBYTE    $0x50\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x6e\n\tBYTE    $0x38\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x76\n\tBYTE    $0x70\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x7e\n\tBYTE    $0x08\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x99\n\tBYTE    $0x22\n\tBYTE    $0x66\n\tBYTE    $0x18\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x48\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x30\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x20\n\tBYTE    $0x01\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X2, X13\n\tVMOVDQA X4, X14\n\tBYTE    $0xc5\n\tBYTE    $0x69\n\tBYTE    $0x6c\n\tBYTE    $0xfa\n\tVMOVDQA X5, X4\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tVMOVDQA X14, X5\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tVMOVDQA X6, X14\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x49\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x66\n\tBYTE    $0x38\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x6e\n\tBYTE    $0x68\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x76\n\tBYTE    $0x48\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x7e\n\tBYTE    $0x60\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x99\n\tBYTE    $0x22\n\tBYTE    $0x66\n\tBYTE    $0x18\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x58\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x08\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x70\n\tBYTE    $0x01\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X6, X13\n\tVMOVDQA X2, X14\n\tVMOVDQA X4, X6\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x11\n\tBYTE    $0x6c\n\tBYTE    $0xfd\n\tVMOVDQA X5, X4\n\tVMOVDQA X6, X5\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x69\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x66\n\tBYTE    $0x10\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x6e\n\tBYTE    $0x20\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x76\n\tBYTE    $0x30\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x3e\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x99\n\tBYTE    $0x22\n\tBYTE    $0x66\n\tBYTE    $0x28\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x78\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x50\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x40\n\tBYTE    $0x01\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X2, X13\n\tVMOVDQA X4, X14\n\tBYTE    $0xc5\n\tBYTE    $0x69\n\tBYTE    $0x6c\n\tBYTE    $0xfa\n\tVMOVDQA X5, X4\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tVMOVDQA X14, X5\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tVMOVDQA X6, X14\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x49\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x66\n\tBYTE    $0x48\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x6e\n\tBYTE    $0x10\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x36\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x7e\n\tBYTE    $0x20\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x99\n\tBYTE    $0x22\n\tBYTE    $0x66\n\tBYTE    $0x28\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x50\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x38\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x78\n\tBYTE    $0x01\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X6, X13\n\tVMOVDQA X2, X14\n\tVMOVDQA X4, X6\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x11\n\tBYTE    $0x6c\n\tBYTE    $0xfd\n\tVMOVDQA X5, X4\n\tVMOVDQA X6, X5\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x69\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x66\n\tBYTE    $0x70\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x6e\n\tBYTE    $0x30\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x76\n\tBYTE    $0x08\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x7e\n\tBYTE    $0x40\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x99\n\tBYTE    $0x22\n\tBYTE    $0x66\n\tBYTE    $0x58\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x18\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x60\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x68\n\tBYTE    $0x01\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X2, X13\n\tVMOVDQA X4, X14\n\tBYTE    $0xc5\n\tBYTE    $0x69\n\tBYTE    $0x6c\n\tBYTE    $0xfa\n\tVMOVDQA X5, X4\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tVMOVDQA X14, X5\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tVMOVDQA X6, X14\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x49\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x66\n\tBYTE    $0x10\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x2e\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x76\n\tBYTE    $0x60\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x7e\n\tBYTE    $0x58\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x99\n\tBYTE    $0x22\n\tBYTE    $0x66\n\tBYTE    $0x30\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x40\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x50\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x18\n\tBYTE    $0x01\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X6, X13\n\tVMOVDQA X2, X14\n\tVMOVDQA X4, X6\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x11\n\tBYTE    $0x6c\n\tBYTE    $0xfd\n\tVMOVDQA X5, X4\n\tVMOVDQA X6, X5\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x69\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x66\n\tBYTE    $0x20\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x6e\n\tBYTE    $0x78\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x76\n\tBYTE    $0x68\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x7e\n\tBYTE    $0x70\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x99\n\tBYTE    $0x22\n\tBYTE    $0x66\n\tBYTE    $0x38\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x08\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x28\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x48\n\tBYTE    $0x01\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X2, X13\n\tVMOVDQA X4, X14\n\tBYTE    $0xc5\n\tBYTE    $0x69\n\tBYTE    $0x6c\n\tBYTE    $0xfa\n\tVMOVDQA X5, X4\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tVMOVDQA X14, X5\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tVMOVDQA X6, X14\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x49\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x66\n\tBYTE    $0x60\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x6e\n\tBYTE    $0x70\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x76\n\tBYTE    $0x28\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x7e\n\tBYTE    $0x68\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x99\n\tBYTE    $0x22\n\tBYTE    $0x66\n\tBYTE    $0x08\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x20\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x78\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x50\n\tBYTE    $0x01\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X6, X13\n\tVMOVDQA X2, X14\n\tVMOVDQA X4, X6\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x11\n\tBYTE    $0x6c\n\tBYTE    $0xfd\n\tVMOVDQA X5, X4\n\tVMOVDQA X6, X5\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x69\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tMOVQ    (SI), X12\n\tVPSHUFD $0x4e, 64(SI), X13\n\tMOVQ    56(SI), X14\n\tMOVQ    16(SI), X15\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x99\n\tBYTE    $0x22\n\tBYTE    $0x66\n\tBYTE    $0x30\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x18\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x58\n\tBYTE    $0x01\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X2, X13\n\tVMOVDQA X4, X14\n\tBYTE    $0xc5\n\tBYTE    $0x69\n\tBYTE    $0x6c\n\tBYTE    $0xfa\n\tVMOVDQA X5, X4\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tVMOVDQA X14, X5\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tVMOVDQA X6, X14\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x49\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x66\n\tBYTE    $0x68\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x6e\n\tBYTE    $0x60\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x76\n\tBYTE    $0x58\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x7e\n\tBYTE    $0x08\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x99\n\tBYTE    $0x22\n\tBYTE    $0x66\n\tBYTE    $0x38\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x18\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x70\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x48\n\tBYTE    $0x01\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X6, X13\n\tVMOVDQA X2, X14\n\tVMOVDQA X4, X6\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x11\n\tBYTE    $0x6c\n\tBYTE    $0xfd\n\tVMOVDQA X5, X4\n\tVMOVDQA X6, X5\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x69\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tMOVQ    40(SI), X12\n\tMOVQ    64(SI), X13\n\tMOVQ    (SI), X14\n\tMOVQ    48(SI), X15\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x99\n\tBYTE    $0x22\n\tBYTE    $0x66\n\tBYTE    $0x78\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x10\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x20\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x50\n\tBYTE    $0x01\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X2, X13\n\tVMOVDQA X4, X14\n\tBYTE    $0xc5\n\tBYTE    $0x69\n\tBYTE    $0x6c\n\tBYTE    $0xfa\n\tVMOVDQA X5, X4\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tVMOVDQA X14, X5\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tVMOVDQA X6, X14\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x49\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tMOVQ    48(SI), X12\n\tMOVQ    88(SI), X13\n\tMOVQ    120(SI), X14\n\tMOVQ    24(SI), X15\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x99\n\tBYTE    $0x22\n\tBYTE    $0x66\n\tBYTE    $0x70\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x2e\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x48\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x40\n\tBYTE    $0x01\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X6, X13\n\tVMOVDQA X2, X14\n\tVMOVDQA X4, X6\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x11\n\tBYTE    $0x6c\n\tBYTE    $0xfd\n\tVMOVDQA X5, X4\n\tVMOVDQA X6, X5\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x69\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tVMOVDQU 96(SI), X12\n\tMOVQ    8(SI), X13\n\tMOVQ    16(SI), X14\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x50\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x38\n\tBYTE    $0x01\n\tVMOVDQU 32(SI), X15\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X2, X13\n\tVMOVDQA X4, X14\n\tBYTE    $0xc5\n\tBYTE    $0x69\n\tBYTE    $0x6c\n\tBYTE    $0xfa\n\tVMOVDQA X5, X4\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tVMOVDQA X14, X5\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tVMOVDQA X6, X14\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x49\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x66\n\tBYTE    $0x50\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x6e\n\tBYTE    $0x38\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x76\n\tBYTE    $0x10\n\tBYTE    $0xc5\n\tBYTE    $0x7a\n\tBYTE    $0x7e\n\tBYTE    $0x7e\n\tBYTE    $0x30\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x99\n\tBYTE    $0x22\n\tBYTE    $0x66\n\tBYTE    $0x40\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x08\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x20\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x7e\n\tBYTE    $0x28\n\tBYTE    $0x01\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X6, X13\n\tVMOVDQA X2, X14\n\tVMOVDQA X4, X6\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x11\n\tBYTE    $0x6c\n\tBYTE    $0xfd\n\tVMOVDQA X5, X4\n\tVMOVDQA X6, X5\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x69\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tMOVQ    120(SI), X12\n\tMOVQ    24(SI), X13\n\tMOVQ    88(SI), X14\n\tMOVQ    96(SI), X15\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x99\n\tBYTE    $0x22\n\tBYTE    $0x66\n\tBYTE    $0x48\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x91\n\tBYTE    $0x22\n\tBYTE    $0x6e\n\tBYTE    $0x68\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x89\n\tBYTE    $0x22\n\tBYTE    $0x76\n\tBYTE    $0x70\n\tBYTE    $0x01\n\tBYTE    $0xc4\n\tBYTE    $0x63\n\tBYTE    $0x81\n\tBYTE    $0x22\n\tBYTE    $0x3e\n\tBYTE    $0x01\n\tVPADDQ  X12, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X13, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  X14, X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  X15, X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X2, X13\n\tVMOVDQA X4, X14\n\tBYTE    $0xc5\n\tBYTE    $0x69\n\tBYTE    $0x6c\n\tBYTE    $0xfa\n\tVMOVDQA X5, X4\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tVMOVDQA X14, X5\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tVMOVDQA X6, X14\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x49\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tVPADDQ  16(R10), X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  32(R10), X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  48(R10), X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  64(R10), X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X6, X13\n\tVMOVDQA X2, X14\n\tVMOVDQA X4, X6\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x11\n\tBYTE    $0x6c\n\tBYTE    $0xfd\n\tVMOVDQA X5, X4\n\tVMOVDQA X6, X5\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x69\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tVPADDQ  80(R10), X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  96(R10), X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  112(R10), X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  128(R10), X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X2, X13\n\tVMOVDQA X4, X14\n\tBYTE    $0xc5\n\tBYTE    $0x69\n\tBYTE    $0x6c\n\tBYTE    $0xfa\n\tVMOVDQA X5, X4\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tVMOVDQA X14, X5\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tVMOVDQA X6, X14\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x49\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tVPADDQ  144(R10), X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  160(R10), X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  176(R10), X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  192(R10), X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X6, X13\n\tVMOVDQA X2, X14\n\tVMOVDQA X4, X6\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x11\n\tBYTE    $0x6c\n\tBYTE    $0xfd\n\tVMOVDQA X5, X4\n\tVMOVDQA X6, X5\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x69\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tVPADDQ  208(R10), X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  224(R10), X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFD $-79, X6, X6\n\tVPSHUFD $-79, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPSHUFB X8, X2, X2\n\tVPSHUFB X8, X3, X3\n\tVPADDQ  240(R10), X0, X0\n\tVPADDQ  X2, X0, X0\n\tVPADDQ  256(R10), X1, X1\n\tVPADDQ  X3, X1, X1\n\tVPXOR   X0, X6, X6\n\tVPXOR   X1, X7, X7\n\tVPSHUFB X9, X6, X6\n\tVPSHUFB X9, X7, X7\n\tVPADDQ  X6, X4, X4\n\tVPADDQ  X7, X5, X5\n\tVPXOR   X4, X2, X2\n\tVPXOR   X5, X3, X3\n\tVPADDQ  X2, X2, X15\n\tVPSRLQ  $0x3f, X2, X2\n\tVPXOR   X15, X2, X2\n\tVPADDQ  X3, X3, X15\n\tVPSRLQ  $0x3f, X3, X3\n\tVPXOR   X15, X3, X3\n\tVMOVDQA X2, X13\n\tVMOVDQA X4, X14\n\tBYTE    $0xc5\n\tBYTE    $0x69\n\tBYTE    $0x6c\n\tBYTE    $0xfa\n\tVMOVDQA X5, X4\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x61\n\tBYTE    $0x6d\n\tBYTE    $0xd7\n\tVMOVDQA X14, X5\n\tBYTE    $0xc5\n\tBYTE    $0x61\n\tBYTE    $0x6c\n\tBYTE    $0xfb\n\tVMOVDQA X6, X14\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x11\n\tBYTE    $0x6d\n\tBYTE    $0xdf\n\tBYTE    $0xc5\n\tBYTE    $0x41\n\tBYTE    $0x6c\n\tBYTE    $0xff\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x49\n\tBYTE    $0x6d\n\tBYTE    $0xf7\n\tBYTE    $0xc4\n\tBYTE    $0x41\n\tBYTE    $0x09\n\tBYTE    $0x6c\n\tBYTE    $0xfe\n\tBYTE    $0xc4\n\tBYTE    $0xc1\n\tBYTE    $0x41\n\tBYTE    $0x6d\n\tBYTE    $0xff\n\tVMOVDQU 32(AX), X14\n\tVMOVDQU 48(AX), X15\n\tVPXOR   X0, X10, X10\n\tVPXOR   X1, X11, X11\n\tVPXOR   X2, X14, X14\n\tVPXOR   X3, X15, X15\n\tVPXOR   X4, X10, X10\n\tVPXOR   X5, X11, X11\n\tVPXOR   X6, X14, X2\n\tVPXOR   X7, X15, X3\n\tVMOVDQU X2, 32(AX)\n\tVMOVDQU X3, 48(AX)\n\tLEAQ    128(SI), SI\n\tSUBQ    $0x80, DI\n\tJNE     loop\n\tVMOVDQU X10, (AX)\n\tVMOVDQU X11, 16(AX)\n\tMOVQ    R8, (BX)\n\tMOVQ    R9, 8(BX)\n\tVZEROUPPER\n\tRET\n\nDATA ·AVX_c40<>+0(SB)/8, $0x0201000706050403\nDATA ·AVX_c40<>+8(SB)/8, $0x0a09080f0e0d0c0b\nGLOBL ·AVX_c40<>(SB), RODATA|NOPTR, $16\n\nDATA ·AVX_c48<>+0(SB)/8, $0x0100070605040302\nDATA ·AVX_c48<>+8(SB)/8, $0x09080f0e0d0c0b0a\nGLOBL ·AVX_c48<>(SB), RODATA|NOPTR, $16\n\nDATA ·AVX_iv3<>+0(SB)/8, $0x1f83d9abfb41bd6b\nDATA ·AVX_iv3<>+8(SB)/8, $0x5be0cd19137e2179\nGLOBL ·AVX_iv3<>(SB), RODATA|NOPTR, $16\n\nDATA ·AVX_iv0<>+0(SB)/8, $0x6a09e667f3bcc908\nDATA ·AVX_iv0<>+8(SB)/8, $0xbb67ae8584caa73b\nGLOBL ·AVX_iv0<>(SB), RODATA|NOPTR, $16\n\nDATA ·AVX_iv1<>+0(SB)/8, $0x3c6ef372fe94f82b\nDATA ·AVX_iv1<>+8(SB)/8, $0xa54ff53a5f1d36f1\nGLOBL ·AVX_iv1<>(SB), RODATA|NOPTR, $16\n\nDATA ·AVX_iv2<>+0(SB)/8, $0x510e527fade682d1\nDATA ·AVX_iv2<>+8(SB)/8, $0x9b05688c2b3e6c1f\nGLOBL ·AVX_iv2<>(SB), RODATA|NOPTR, $16\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/blake2b/blake2b_amd64.s",
    "content": "// Code generated by command: go run blake2b_amd64_asm.go -out ../../blake2b_amd64.s -pkg blake2b. DO NOT EDIT.\n\n//go:build amd64 && gc && !purego\n\n#include \"textflag.h\"\n\n// func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)\n// Requires: SSE2, SSE4.1, SSSE3\nTEXT ·hashBlocksSSE4(SB), NOSPLIT, $288-48\n\tMOVQ  h+0(FP), AX\n\tMOVQ  c+8(FP), BX\n\tMOVQ  flag+16(FP), CX\n\tMOVQ  blocks_base+24(FP), SI\n\tMOVQ  blocks_len+32(FP), DI\n\tMOVQ  SP, R10\n\tADDQ  $0x0f, R10\n\tANDQ  $-16, R10\n\tMOVOU ·iv3<>+0(SB), X0\n\tMOVO  X0, (R10)\n\tXORQ  CX, (R10)\n\tMOVOU ·c40<>+0(SB), X13\n\tMOVOU ·c48<>+0(SB), X14\n\tMOVOU (AX), X12\n\tMOVOU 16(AX), X15\n\tMOVQ  (BX), R8\n\tMOVQ  8(BX), R9\n\nloop:\n\tADDQ $0x80, R8\n\tCMPQ R8, $0x80\n\tJGE  noinc\n\tINCQ R9\n\nnoinc:\n\tMOVQ       R8, X8\n\tPINSRQ     $0x01, R9, X8\n\tMOVO       X12, X0\n\tMOVO       X15, X1\n\tMOVOU      32(AX), X2\n\tMOVOU      48(AX), X3\n\tMOVOU      ·iv0<>+0(SB), X4\n\tMOVOU      ·iv1<>+0(SB), X5\n\tMOVOU      ·iv2<>+0(SB), X6\n\tPXOR       X8, X6\n\tMOVO       (R10), X7\n\tMOVQ       (SI), X8\n\tPINSRQ     $0x01, 16(SI), X8\n\tMOVQ       32(SI), X9\n\tPINSRQ     $0x01, 48(SI), X9\n\tMOVQ       8(SI), X10\n\tPINSRQ     $0x01, 24(SI), X10\n\tMOVQ       40(SI), X11\n\tPINSRQ     $0x01, 56(SI), X11\n\tMOVO       X8, 16(R10)\n\tMOVO       X9, 32(R10)\n\tMOVO       X10, 48(R10)\n\tMOVO       X11, 64(R10)\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X6, X8\n\tPUNPCKLQDQ X6, X9\n\tPUNPCKHQDQ X7, X6\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X7, X9\n\tMOVO       X8, X7\n\tMOVO       X2, X8\n\tPUNPCKHQDQ X9, X7\n\tPUNPCKLQDQ X3, X9\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X3\n\tMOVQ       64(SI), X8\n\tPINSRQ     $0x01, 80(SI), X8\n\tMOVQ       96(SI), X9\n\tPINSRQ     $0x01, 112(SI), X9\n\tMOVQ       72(SI), X10\n\tPINSRQ     $0x01, 88(SI), X10\n\tMOVQ       104(SI), X11\n\tPINSRQ     $0x01, 120(SI), X11\n\tMOVO       X8, 80(R10)\n\tMOVO       X9, 96(R10)\n\tMOVO       X10, 112(R10)\n\tMOVO       X11, 128(R10)\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X2, X8\n\tPUNPCKLQDQ X2, X9\n\tPUNPCKHQDQ X3, X2\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X3, X9\n\tMOVO       X8, X3\n\tMOVO       X6, X8\n\tPUNPCKHQDQ X9, X3\n\tPUNPCKLQDQ X7, X9\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X7\n\tMOVQ       112(SI), X8\n\tPINSRQ     $0x01, 32(SI), X8\n\tMOVQ       72(SI), X9\n\tPINSRQ     $0x01, 104(SI), X9\n\tMOVQ       80(SI), X10\n\tPINSRQ     $0x01, 64(SI), X10\n\tMOVQ       120(SI), X11\n\tPINSRQ     $0x01, 48(SI), X11\n\tMOVO       X8, 144(R10)\n\tMOVO       X9, 160(R10)\n\tMOVO       X10, 176(R10)\n\tMOVO       X11, 192(R10)\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X6, X8\n\tPUNPCKLQDQ X6, X9\n\tPUNPCKHQDQ X7, X6\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X7, X9\n\tMOVO       X8, X7\n\tMOVO       X2, X8\n\tPUNPCKHQDQ X9, X7\n\tPUNPCKLQDQ X3, X9\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X3\n\tMOVQ       8(SI), X8\n\tPINSRQ     $0x01, (SI), X8\n\tMOVQ       88(SI), X9\n\tPINSRQ     $0x01, 40(SI), X9\n\tMOVQ       96(SI), X10\n\tPINSRQ     $0x01, 16(SI), X10\n\tMOVQ       56(SI), X11\n\tPINSRQ     $0x01, 24(SI), X11\n\tMOVO       X8, 208(R10)\n\tMOVO       X9, 224(R10)\n\tMOVO       X10, 240(R10)\n\tMOVO       X11, 256(R10)\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X2, X8\n\tPUNPCKLQDQ X2, X9\n\tPUNPCKHQDQ X3, X2\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X3, X9\n\tMOVO       X8, X3\n\tMOVO       X6, X8\n\tPUNPCKHQDQ X9, X3\n\tPUNPCKLQDQ X7, X9\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X7\n\tMOVQ       88(SI), X8\n\tPINSRQ     $0x01, 96(SI), X8\n\tMOVQ       40(SI), X9\n\tPINSRQ     $0x01, 120(SI), X9\n\tMOVQ       64(SI), X10\n\tPINSRQ     $0x01, (SI), X10\n\tMOVQ       16(SI), X11\n\tPINSRQ     $0x01, 104(SI), X11\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X6, X8\n\tPUNPCKLQDQ X6, X9\n\tPUNPCKHQDQ X7, X6\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X7, X9\n\tMOVO       X8, X7\n\tMOVO       X2, X8\n\tPUNPCKHQDQ X9, X7\n\tPUNPCKLQDQ X3, X9\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X3\n\tMOVQ       80(SI), X8\n\tPINSRQ     $0x01, 24(SI), X8\n\tMOVQ       56(SI), X9\n\tPINSRQ     $0x01, 72(SI), X9\n\tMOVQ       112(SI), X10\n\tPINSRQ     $0x01, 48(SI), X10\n\tMOVQ       8(SI), X11\n\tPINSRQ     $0x01, 32(SI), X11\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X2, X8\n\tPUNPCKLQDQ X2, X9\n\tPUNPCKHQDQ X3, X2\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X3, X9\n\tMOVO       X8, X3\n\tMOVO       X6, X8\n\tPUNPCKHQDQ X9, X3\n\tPUNPCKLQDQ X7, X9\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X7\n\tMOVQ       56(SI), X8\n\tPINSRQ     $0x01, 24(SI), X8\n\tMOVQ       104(SI), X9\n\tPINSRQ     $0x01, 88(SI), X9\n\tMOVQ       72(SI), X10\n\tPINSRQ     $0x01, 8(SI), X10\n\tMOVQ       96(SI), X11\n\tPINSRQ     $0x01, 112(SI), X11\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X6, X8\n\tPUNPCKLQDQ X6, X9\n\tPUNPCKHQDQ X7, X6\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X7, X9\n\tMOVO       X8, X7\n\tMOVO       X2, X8\n\tPUNPCKHQDQ X9, X7\n\tPUNPCKLQDQ X3, X9\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X3\n\tMOVQ       16(SI), X8\n\tPINSRQ     $0x01, 40(SI), X8\n\tMOVQ       32(SI), X9\n\tPINSRQ     $0x01, 120(SI), X9\n\tMOVQ       48(SI), X10\n\tPINSRQ     $0x01, 80(SI), X10\n\tMOVQ       (SI), X11\n\tPINSRQ     $0x01, 64(SI), X11\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X2, X8\n\tPUNPCKLQDQ X2, X9\n\tPUNPCKHQDQ X3, X2\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X3, X9\n\tMOVO       X8, X3\n\tMOVO       X6, X8\n\tPUNPCKHQDQ X9, X3\n\tPUNPCKLQDQ X7, X9\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X7\n\tMOVQ       72(SI), X8\n\tPINSRQ     $0x01, 40(SI), X8\n\tMOVQ       16(SI), X9\n\tPINSRQ     $0x01, 80(SI), X9\n\tMOVQ       (SI), X10\n\tPINSRQ     $0x01, 56(SI), X10\n\tMOVQ       32(SI), X11\n\tPINSRQ     $0x01, 120(SI), X11\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X6, X8\n\tPUNPCKLQDQ X6, X9\n\tPUNPCKHQDQ X7, X6\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X7, X9\n\tMOVO       X8, X7\n\tMOVO       X2, X8\n\tPUNPCKHQDQ X9, X7\n\tPUNPCKLQDQ X3, X9\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X3\n\tMOVQ       112(SI), X8\n\tPINSRQ     $0x01, 88(SI), X8\n\tMOVQ       48(SI), X9\n\tPINSRQ     $0x01, 24(SI), X9\n\tMOVQ       8(SI), X10\n\tPINSRQ     $0x01, 96(SI), X10\n\tMOVQ       64(SI), X11\n\tPINSRQ     $0x01, 104(SI), X11\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X2, X8\n\tPUNPCKLQDQ X2, X9\n\tPUNPCKHQDQ X3, X2\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X3, X9\n\tMOVO       X8, X3\n\tMOVO       X6, X8\n\tPUNPCKHQDQ X9, X3\n\tPUNPCKLQDQ X7, X9\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X7\n\tMOVQ       16(SI), X8\n\tPINSRQ     $0x01, 48(SI), X8\n\tMOVQ       (SI), X9\n\tPINSRQ     $0x01, 64(SI), X9\n\tMOVQ       96(SI), X10\n\tPINSRQ     $0x01, 80(SI), X10\n\tMOVQ       88(SI), X11\n\tPINSRQ     $0x01, 24(SI), X11\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X6, X8\n\tPUNPCKLQDQ X6, X9\n\tPUNPCKHQDQ X7, X6\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X7, X9\n\tMOVO       X8, X7\n\tMOVO       X2, X8\n\tPUNPCKHQDQ X9, X7\n\tPUNPCKLQDQ X3, X9\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X3\n\tMOVQ       32(SI), X8\n\tPINSRQ     $0x01, 56(SI), X8\n\tMOVQ       120(SI), X9\n\tPINSRQ     $0x01, 8(SI), X9\n\tMOVQ       104(SI), X10\n\tPINSRQ     $0x01, 40(SI), X10\n\tMOVQ       112(SI), X11\n\tPINSRQ     $0x01, 72(SI), X11\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X2, X8\n\tPUNPCKLQDQ X2, X9\n\tPUNPCKHQDQ X3, X2\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X3, X9\n\tMOVO       X8, X3\n\tMOVO       X6, X8\n\tPUNPCKHQDQ X9, X3\n\tPUNPCKLQDQ X7, X9\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X7\n\tMOVQ       96(SI), X8\n\tPINSRQ     $0x01, 8(SI), X8\n\tMOVQ       112(SI), X9\n\tPINSRQ     $0x01, 32(SI), X9\n\tMOVQ       40(SI), X10\n\tPINSRQ     $0x01, 120(SI), X10\n\tMOVQ       104(SI), X11\n\tPINSRQ     $0x01, 80(SI), X11\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X6, X8\n\tPUNPCKLQDQ X6, X9\n\tPUNPCKHQDQ X7, X6\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X7, X9\n\tMOVO       X8, X7\n\tMOVO       X2, X8\n\tPUNPCKHQDQ X9, X7\n\tPUNPCKLQDQ X3, X9\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X3\n\tMOVQ       (SI), X8\n\tPINSRQ     $0x01, 48(SI), X8\n\tMOVQ       72(SI), X9\n\tPINSRQ     $0x01, 64(SI), X9\n\tMOVQ       56(SI), X10\n\tPINSRQ     $0x01, 24(SI), X10\n\tMOVQ       16(SI), X11\n\tPINSRQ     $0x01, 88(SI), X11\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X2, X8\n\tPUNPCKLQDQ X2, X9\n\tPUNPCKHQDQ X3, X2\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X3, X9\n\tMOVO       X8, X3\n\tMOVO       X6, X8\n\tPUNPCKHQDQ X9, X3\n\tPUNPCKLQDQ X7, X9\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X7\n\tMOVQ       104(SI), X8\n\tPINSRQ     $0x01, 56(SI), X8\n\tMOVQ       96(SI), X9\n\tPINSRQ     $0x01, 24(SI), X9\n\tMOVQ       88(SI), X10\n\tPINSRQ     $0x01, 112(SI), X10\n\tMOVQ       8(SI), X11\n\tPINSRQ     $0x01, 72(SI), X11\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X6, X8\n\tPUNPCKLQDQ X6, X9\n\tPUNPCKHQDQ X7, X6\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X7, X9\n\tMOVO       X8, X7\n\tMOVO       X2, X8\n\tPUNPCKHQDQ X9, X7\n\tPUNPCKLQDQ X3, X9\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X3\n\tMOVQ       40(SI), X8\n\tPINSRQ     $0x01, 120(SI), X8\n\tMOVQ       64(SI), X9\n\tPINSRQ     $0x01, 16(SI), X9\n\tMOVQ       (SI), X10\n\tPINSRQ     $0x01, 32(SI), X10\n\tMOVQ       48(SI), X11\n\tPINSRQ     $0x01, 80(SI), X11\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X2, X8\n\tPUNPCKLQDQ X2, X9\n\tPUNPCKHQDQ X3, X2\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X3, X9\n\tMOVO       X8, X3\n\tMOVO       X6, X8\n\tPUNPCKHQDQ X9, X3\n\tPUNPCKLQDQ X7, X9\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X7\n\tMOVQ       48(SI), X8\n\tPINSRQ     $0x01, 112(SI), X8\n\tMOVQ       88(SI), X9\n\tPINSRQ     $0x01, (SI), X9\n\tMOVQ       120(SI), X10\n\tPINSRQ     $0x01, 72(SI), X10\n\tMOVQ       24(SI), X11\n\tPINSRQ     $0x01, 64(SI), X11\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X6, X8\n\tPUNPCKLQDQ X6, X9\n\tPUNPCKHQDQ X7, X6\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X7, X9\n\tMOVO       X8, X7\n\tMOVO       X2, X8\n\tPUNPCKHQDQ X9, X7\n\tPUNPCKLQDQ X3, X9\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X3\n\tMOVQ       96(SI), X8\n\tPINSRQ     $0x01, 104(SI), X8\n\tMOVQ       8(SI), X9\n\tPINSRQ     $0x01, 80(SI), X9\n\tMOVQ       16(SI), X10\n\tPINSRQ     $0x01, 56(SI), X10\n\tMOVQ       32(SI), X11\n\tPINSRQ     $0x01, 40(SI), X11\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X2, X8\n\tPUNPCKLQDQ X2, X9\n\tPUNPCKHQDQ X3, X2\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X3, X9\n\tMOVO       X8, X3\n\tMOVO       X6, X8\n\tPUNPCKHQDQ X9, X3\n\tPUNPCKLQDQ X7, X9\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X7\n\tMOVQ       80(SI), X8\n\tPINSRQ     $0x01, 64(SI), X8\n\tMOVQ       56(SI), X9\n\tPINSRQ     $0x01, 8(SI), X9\n\tMOVQ       16(SI), X10\n\tPINSRQ     $0x01, 32(SI), X10\n\tMOVQ       48(SI), X11\n\tPINSRQ     $0x01, 40(SI), X11\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X6, X8\n\tPUNPCKLQDQ X6, X9\n\tPUNPCKHQDQ X7, X6\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X7, X9\n\tMOVO       X8, X7\n\tMOVO       X2, X8\n\tPUNPCKHQDQ X9, X7\n\tPUNPCKLQDQ X3, X9\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X3\n\tMOVQ       120(SI), X8\n\tPINSRQ     $0x01, 72(SI), X8\n\tMOVQ       24(SI), X9\n\tPINSRQ     $0x01, 104(SI), X9\n\tMOVQ       88(SI), X10\n\tPINSRQ     $0x01, 112(SI), X10\n\tMOVQ       96(SI), X11\n\tPINSRQ     $0x01, (SI), X11\n\tPADDQ      X8, X0\n\tPADDQ      X9, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      X10, X0\n\tPADDQ      X11, X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X2, X8\n\tPUNPCKLQDQ X2, X9\n\tPUNPCKHQDQ X3, X2\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X3, X9\n\tMOVO       X8, X3\n\tMOVO       X6, X8\n\tPUNPCKHQDQ X9, X3\n\tPUNPCKLQDQ X7, X9\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X7\n\tPADDQ      16(R10), X0\n\tPADDQ      32(R10), X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      48(R10), X0\n\tPADDQ      64(R10), X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X6, X8\n\tPUNPCKLQDQ X6, X9\n\tPUNPCKHQDQ X7, X6\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X7, X9\n\tMOVO       X8, X7\n\tMOVO       X2, X8\n\tPUNPCKHQDQ X9, X7\n\tPUNPCKLQDQ X3, X9\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X3\n\tPADDQ      80(R10), X0\n\tPADDQ      96(R10), X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      112(R10), X0\n\tPADDQ      128(R10), X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X2, X8\n\tPUNPCKLQDQ X2, X9\n\tPUNPCKHQDQ X3, X2\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X3, X9\n\tMOVO       X8, X3\n\tMOVO       X6, X8\n\tPUNPCKHQDQ X9, X3\n\tPUNPCKLQDQ X7, X9\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X7\n\tPADDQ      144(R10), X0\n\tPADDQ      160(R10), X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      176(R10), X0\n\tPADDQ      192(R10), X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X6, X8\n\tPUNPCKLQDQ X6, X9\n\tPUNPCKHQDQ X7, X6\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X7, X9\n\tMOVO       X8, X7\n\tMOVO       X2, X8\n\tPUNPCKHQDQ X9, X7\n\tPUNPCKLQDQ X3, X9\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X3\n\tPADDQ      208(R10), X0\n\tPADDQ      224(R10), X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFD     $0xb1, X6, X6\n\tPSHUFD     $0xb1, X7, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tPSHUFB     X13, X2\n\tPSHUFB     X13, X3\n\tPADDQ      240(R10), X0\n\tPADDQ      256(R10), X1\n\tPADDQ      X2, X0\n\tPADDQ      X3, X1\n\tPXOR       X0, X6\n\tPXOR       X1, X7\n\tPSHUFB     X14, X6\n\tPSHUFB     X14, X7\n\tPADDQ      X6, X4\n\tPADDQ      X7, X5\n\tPXOR       X4, X2\n\tPXOR       X5, X3\n\tMOVOU      X2, X11\n\tPADDQ      X2, X11\n\tPSRLQ      $0x3f, X2\n\tPXOR       X11, X2\n\tMOVOU      X3, X11\n\tPADDQ      X3, X11\n\tPSRLQ      $0x3f, X3\n\tPXOR       X11, X3\n\tMOVO       X4, X8\n\tMOVO       X5, X4\n\tMOVO       X8, X5\n\tMOVO       X2, X8\n\tPUNPCKLQDQ X2, X9\n\tPUNPCKHQDQ X3, X2\n\tPUNPCKHQDQ X9, X2\n\tPUNPCKLQDQ X3, X9\n\tMOVO       X8, X3\n\tMOVO       X6, X8\n\tPUNPCKHQDQ X9, X3\n\tPUNPCKLQDQ X7, X9\n\tPUNPCKHQDQ X9, X6\n\tPUNPCKLQDQ X8, X9\n\tPUNPCKHQDQ X9, X7\n\tMOVOU      32(AX), X10\n\tMOVOU      48(AX), X11\n\tPXOR       X0, X12\n\tPXOR       X1, X15\n\tPXOR       X2, X10\n\tPXOR       X3, X11\n\tPXOR       X4, X12\n\tPXOR       X5, X15\n\tPXOR       X6, X10\n\tPXOR       X7, X11\n\tMOVOU      X10, 32(AX)\n\tMOVOU      X11, 48(AX)\n\tLEAQ       128(SI), SI\n\tSUBQ       $0x80, DI\n\tJNE        loop\n\tMOVOU      X12, (AX)\n\tMOVOU      X15, 16(AX)\n\tMOVQ       R8, (BX)\n\tMOVQ       R9, 8(BX)\n\tRET\n\nDATA ·iv3<>+0(SB)/8, $0x1f83d9abfb41bd6b\nDATA ·iv3<>+8(SB)/8, $0x5be0cd19137e2179\nGLOBL ·iv3<>(SB), RODATA|NOPTR, $16\n\nDATA ·c40<>+0(SB)/8, $0x0201000706050403\nDATA ·c40<>+8(SB)/8, $0x0a09080f0e0d0c0b\nGLOBL ·c40<>(SB), RODATA|NOPTR, $16\n\nDATA ·c48<>+0(SB)/8, $0x0100070605040302\nDATA ·c48<>+8(SB)/8, $0x09080f0e0d0c0b0a\nGLOBL ·c48<>(SB), RODATA|NOPTR, $16\n\nDATA ·iv0<>+0(SB)/8, $0x6a09e667f3bcc908\nDATA ·iv0<>+8(SB)/8, $0xbb67ae8584caa73b\nGLOBL ·iv0<>(SB), RODATA|NOPTR, $16\n\nDATA ·iv1<>+0(SB)/8, $0x3c6ef372fe94f82b\nDATA ·iv1<>+8(SB)/8, $0xa54ff53a5f1d36f1\nGLOBL ·iv1<>(SB), RODATA|NOPTR, $16\n\nDATA ·iv2<>+0(SB)/8, $0x510e527fade682d1\nDATA ·iv2<>+8(SB)/8, $0x9b05688c2b3e6c1f\nGLOBL ·iv2<>(SB), RODATA|NOPTR, $16\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/blake2b/blake2b_generic.go",
    "content": "// Copyright 2016 The Go 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 blake2b\n\nimport (\n\t\"encoding/binary\"\n\t\"math/bits\"\n)\n\n// the precomputed values for BLAKE2b\n// there are 12 16-byte arrays - one for each round\n// the entries are calculated from the sigma constants.\nvar precomputed = [12][16]byte{\n\t{0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15},\n\t{14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3},\n\t{11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4},\n\t{7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8},\n\t{9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13},\n\t{2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9},\n\t{12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11},\n\t{13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10},\n\t{6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5},\n\t{10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0},\n\t{0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15}, // equal to the first\n\t{14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3}, // equal to the second\n}\n\nfunc hashBlocksGeneric(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {\n\tvar m [16]uint64\n\tc0, c1 := c[0], c[1]\n\n\tfor i := 0; i < len(blocks); {\n\t\tc0 += BlockSize\n\t\tif c0 < BlockSize {\n\t\t\tc1++\n\t\t}\n\n\t\tv0, v1, v2, v3, v4, v5, v6, v7 := h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]\n\t\tv8, v9, v10, v11, v12, v13, v14, v15 := iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]\n\t\tv12 ^= c0\n\t\tv13 ^= c1\n\t\tv14 ^= flag\n\n\t\tfor j := range m {\n\t\t\tm[j] = binary.LittleEndian.Uint64(blocks[i:])\n\t\t\ti += 8\n\t\t}\n\n\t\tfor j := range precomputed {\n\t\t\ts := &(precomputed[j])\n\n\t\t\tv0 += m[s[0]]\n\t\t\tv0 += v4\n\t\t\tv12 ^= v0\n\t\t\tv12 = bits.RotateLeft64(v12, -32)\n\t\t\tv8 += v12\n\t\t\tv4 ^= v8\n\t\t\tv4 = bits.RotateLeft64(v4, -24)\n\t\t\tv1 += m[s[1]]\n\t\t\tv1 += v5\n\t\t\tv13 ^= v1\n\t\t\tv13 = bits.RotateLeft64(v13, -32)\n\t\t\tv9 += v13\n\t\t\tv5 ^= v9\n\t\t\tv5 = bits.RotateLeft64(v5, -24)\n\t\t\tv2 += m[s[2]]\n\t\t\tv2 += v6\n\t\t\tv14 ^= v2\n\t\t\tv14 = bits.RotateLeft64(v14, -32)\n\t\t\tv10 += v14\n\t\t\tv6 ^= v10\n\t\t\tv6 = bits.RotateLeft64(v6, -24)\n\t\t\tv3 += m[s[3]]\n\t\t\tv3 += v7\n\t\t\tv15 ^= v3\n\t\t\tv15 = bits.RotateLeft64(v15, -32)\n\t\t\tv11 += v15\n\t\t\tv7 ^= v11\n\t\t\tv7 = bits.RotateLeft64(v7, -24)\n\n\t\t\tv0 += m[s[4]]\n\t\t\tv0 += v4\n\t\t\tv12 ^= v0\n\t\t\tv12 = bits.RotateLeft64(v12, -16)\n\t\t\tv8 += v12\n\t\t\tv4 ^= v8\n\t\t\tv4 = bits.RotateLeft64(v4, -63)\n\t\t\tv1 += m[s[5]]\n\t\t\tv1 += v5\n\t\t\tv13 ^= v1\n\t\t\tv13 = bits.RotateLeft64(v13, -16)\n\t\t\tv9 += v13\n\t\t\tv5 ^= v9\n\t\t\tv5 = bits.RotateLeft64(v5, -63)\n\t\t\tv2 += m[s[6]]\n\t\t\tv2 += v6\n\t\t\tv14 ^= v2\n\t\t\tv14 = bits.RotateLeft64(v14, -16)\n\t\t\tv10 += v14\n\t\t\tv6 ^= v10\n\t\t\tv6 = bits.RotateLeft64(v6, -63)\n\t\t\tv3 += m[s[7]]\n\t\t\tv3 += v7\n\t\t\tv15 ^= v3\n\t\t\tv15 = bits.RotateLeft64(v15, -16)\n\t\t\tv11 += v15\n\t\t\tv7 ^= v11\n\t\t\tv7 = bits.RotateLeft64(v7, -63)\n\n\t\t\tv0 += m[s[8]]\n\t\t\tv0 += v5\n\t\t\tv15 ^= v0\n\t\t\tv15 = bits.RotateLeft64(v15, -32)\n\t\t\tv10 += v15\n\t\t\tv5 ^= v10\n\t\t\tv5 = bits.RotateLeft64(v5, -24)\n\t\t\tv1 += m[s[9]]\n\t\t\tv1 += v6\n\t\t\tv12 ^= v1\n\t\t\tv12 = bits.RotateLeft64(v12, -32)\n\t\t\tv11 += v12\n\t\t\tv6 ^= v11\n\t\t\tv6 = bits.RotateLeft64(v6, -24)\n\t\t\tv2 += m[s[10]]\n\t\t\tv2 += v7\n\t\t\tv13 ^= v2\n\t\t\tv13 = bits.RotateLeft64(v13, -32)\n\t\t\tv8 += v13\n\t\t\tv7 ^= v8\n\t\t\tv7 = bits.RotateLeft64(v7, -24)\n\t\t\tv3 += m[s[11]]\n\t\t\tv3 += v4\n\t\t\tv14 ^= v3\n\t\t\tv14 = bits.RotateLeft64(v14, -32)\n\t\t\tv9 += v14\n\t\t\tv4 ^= v9\n\t\t\tv4 = bits.RotateLeft64(v4, -24)\n\n\t\t\tv0 += m[s[12]]\n\t\t\tv0 += v5\n\t\t\tv15 ^= v0\n\t\t\tv15 = bits.RotateLeft64(v15, -16)\n\t\t\tv10 += v15\n\t\t\tv5 ^= v10\n\t\t\tv5 = bits.RotateLeft64(v5, -63)\n\t\t\tv1 += m[s[13]]\n\t\t\tv1 += v6\n\t\t\tv12 ^= v1\n\t\t\tv12 = bits.RotateLeft64(v12, -16)\n\t\t\tv11 += v12\n\t\t\tv6 ^= v11\n\t\t\tv6 = bits.RotateLeft64(v6, -63)\n\t\t\tv2 += m[s[14]]\n\t\t\tv2 += v7\n\t\t\tv13 ^= v2\n\t\t\tv13 = bits.RotateLeft64(v13, -16)\n\t\t\tv8 += v13\n\t\t\tv7 ^= v8\n\t\t\tv7 = bits.RotateLeft64(v7, -63)\n\t\t\tv3 += m[s[15]]\n\t\t\tv3 += v4\n\t\t\tv14 ^= v3\n\t\t\tv14 = bits.RotateLeft64(v14, -16)\n\t\t\tv9 += v14\n\t\t\tv4 ^= v9\n\t\t\tv4 = bits.RotateLeft64(v4, -63)\n\n\t\t}\n\n\t\th[0] ^= v0 ^ v8\n\t\th[1] ^= v1 ^ v9\n\t\th[2] ^= v2 ^ v10\n\t\th[3] ^= v3 ^ v11\n\t\th[4] ^= v4 ^ v12\n\t\th[5] ^= v5 ^ v13\n\t\th[6] ^= v6 ^ v14\n\t\th[7] ^= v7 ^ v15\n\t}\n\tc[0], c[1] = c0, c1\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/blake2b/blake2b_ref.go",
    "content": "// Copyright 2016 The Go 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\n//go:build !amd64 || purego || !gc\n\npackage blake2b\n\nfunc hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {\n\thashBlocksGeneric(h, c, flag, blocks)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/blake2b/blake2x.go",
    "content": "// Copyright 2017 The Go 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 blake2b\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"io\"\n)\n\n// XOF defines the interface to hash functions that\n// support arbitrary-length output.\ntype XOF interface {\n\t// Write absorbs more data into the hash's state. It panics if called\n\t// after Read.\n\tio.Writer\n\n\t// Read reads more output from the hash. It returns io.EOF if the limit\n\t// has been reached.\n\tio.Reader\n\n\t// Clone returns a copy of the XOF in its current state.\n\tClone() XOF\n\n\t// Reset resets the XOF to its initial state.\n\tReset()\n}\n\n// OutputLengthUnknown can be used as the size argument to NewXOF to indicate\n// the length of the output is not known in advance.\nconst OutputLengthUnknown = 0\n\n// magicUnknownOutputLength is a magic value for the output size that indicates\n// an unknown number of output bytes.\nconst magicUnknownOutputLength = (1 << 32) - 1\n\n// maxOutputLength is the absolute maximum number of bytes to produce when the\n// number of output bytes is unknown.\nconst maxOutputLength = (1 << 32) * 64\n\n// NewXOF creates a new variable-output-length hash. The hash either produce a\n// known number of bytes (1 <= size < 2**32-1), or an unknown number of bytes\n// (size == OutputLengthUnknown). In the latter case, an absolute limit of\n// 256GiB applies.\n//\n// A non-nil key turns the hash into a MAC. The key must between\n// zero and 32 bytes long.\nfunc NewXOF(size uint32, key []byte) (XOF, error) {\n\tif len(key) > Size {\n\t\treturn nil, errKeySize\n\t}\n\tif size == magicUnknownOutputLength {\n\t\t// 2^32-1 indicates an unknown number of bytes and thus isn't a\n\t\t// valid length.\n\t\treturn nil, errors.New(\"blake2b: XOF length too large\")\n\t}\n\tif size == OutputLengthUnknown {\n\t\tsize = magicUnknownOutputLength\n\t}\n\tx := &xof{\n\t\td: digest{\n\t\t\tsize:   Size,\n\t\t\tkeyLen: len(key),\n\t\t},\n\t\tlength: size,\n\t}\n\tcopy(x.d.key[:], key)\n\tx.Reset()\n\treturn x, nil\n}\n\ntype xof struct {\n\td                digest\n\tlength           uint32\n\tremaining        uint64\n\tcfg, root, block [Size]byte\n\toffset           int\n\tnodeOffset       uint32\n\treadMode         bool\n}\n\nfunc (x *xof) Write(p []byte) (n int, err error) {\n\tif x.readMode {\n\t\tpanic(\"blake2b: write to XOF after read\")\n\t}\n\treturn x.d.Write(p)\n}\n\nfunc (x *xof) Clone() XOF {\n\tclone := *x\n\treturn &clone\n}\n\nfunc (x *xof) Reset() {\n\tx.cfg[0] = byte(Size)\n\tbinary.LittleEndian.PutUint32(x.cfg[4:], uint32(Size)) // leaf length\n\tbinary.LittleEndian.PutUint32(x.cfg[12:], x.length)    // XOF length\n\tx.cfg[17] = byte(Size)                                 // inner hash size\n\n\tx.d.Reset()\n\tx.d.h[1] ^= uint64(x.length) << 32\n\n\tx.remaining = uint64(x.length)\n\tif x.remaining == magicUnknownOutputLength {\n\t\tx.remaining = maxOutputLength\n\t}\n\tx.offset, x.nodeOffset = 0, 0\n\tx.readMode = false\n}\n\nfunc (x *xof) Read(p []byte) (n int, err error) {\n\tif !x.readMode {\n\t\tx.d.finalize(&x.root)\n\t\tx.readMode = true\n\t}\n\n\tif x.remaining == 0 {\n\t\treturn 0, io.EOF\n\t}\n\n\tn = len(p)\n\tif uint64(n) > x.remaining {\n\t\tn = int(x.remaining)\n\t\tp = p[:n]\n\t}\n\n\tif x.offset > 0 {\n\t\tblockRemaining := Size - x.offset\n\t\tif n < blockRemaining {\n\t\t\tx.offset += copy(p, x.block[x.offset:])\n\t\t\tx.remaining -= uint64(n)\n\t\t\treturn\n\t\t}\n\t\tcopy(p, x.block[x.offset:])\n\t\tp = p[blockRemaining:]\n\t\tx.offset = 0\n\t\tx.remaining -= uint64(blockRemaining)\n\t}\n\n\tfor len(p) >= Size {\n\t\tbinary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset)\n\t\tx.nodeOffset++\n\n\t\tx.d.initConfig(&x.cfg)\n\t\tx.d.Write(x.root[:])\n\t\tx.d.finalize(&x.block)\n\n\t\tcopy(p, x.block[:])\n\t\tp = p[Size:]\n\t\tx.remaining -= uint64(Size)\n\t}\n\n\tif todo := len(p); todo > 0 {\n\t\tif x.remaining < uint64(Size) {\n\t\t\tx.cfg[0] = byte(x.remaining)\n\t\t}\n\t\tbinary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset)\n\t\tx.nodeOffset++\n\n\t\tx.d.initConfig(&x.cfg)\n\t\tx.d.Write(x.root[:])\n\t\tx.d.finalize(&x.block)\n\n\t\tx.offset = copy(p, x.block[:todo])\n\t\tx.remaining -= uint64(todo)\n\t}\n\treturn\n}\n\nfunc (d *digest) initConfig(cfg *[Size]byte) {\n\td.offset, d.c[0], d.c[1] = 0, 0, 0\n\tfor i := range d.h {\n\t\td.h[i] = iv[i] ^ binary.LittleEndian.Uint64(cfg[i*8:])\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/blake2b/register.go",
    "content": "// Copyright 2017 The Go 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 blake2b\n\nimport (\n\t\"crypto\"\n\t\"hash\"\n)\n\nfunc init() {\n\tnewHash256 := func() hash.Hash {\n\t\th, _ := New256(nil)\n\t\treturn h\n\t}\n\tnewHash384 := func() hash.Hash {\n\t\th, _ := New384(nil)\n\t\treturn h\n\t}\n\n\tnewHash512 := func() hash.Hash {\n\t\th, _ := New512(nil)\n\t\treturn h\n\t}\n\n\tcrypto.RegisterHash(crypto.BLAKE2b_256, newHash256)\n\tcrypto.RegisterHash(crypto.BLAKE2b_384, newHash384)\n\tcrypto.RegisterHash(crypto.BLAKE2b_512, newHash512)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/blowfish/block.go",
    "content": "// Copyright 2010 The Go 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 blowfish\n\n// getNextWord returns the next big-endian uint32 value from the byte slice\n// at the given position in a circular manner, updating the position.\nfunc getNextWord(b []byte, pos *int) uint32 {\n\tvar w uint32\n\tj := *pos\n\tfor i := 0; i < 4; i++ {\n\t\tw = w<<8 | uint32(b[j])\n\t\tj++\n\t\tif j >= len(b) {\n\t\t\tj = 0\n\t\t}\n\t}\n\t*pos = j\n\treturn w\n}\n\n// ExpandKey performs a key expansion on the given *Cipher. Specifically, it\n// performs the Blowfish algorithm's key schedule which sets up the *Cipher's\n// pi and substitution tables for calls to Encrypt. This is used, primarily,\n// by the bcrypt package to reuse the Blowfish key schedule during its\n// set up. It's unlikely that you need to use this directly.\nfunc ExpandKey(key []byte, c *Cipher) {\n\tj := 0\n\tfor i := 0; i < 18; i++ {\n\t\t// Using inlined getNextWord for performance.\n\t\tvar d uint32\n\t\tfor k := 0; k < 4; k++ {\n\t\t\td = d<<8 | uint32(key[j])\n\t\t\tj++\n\t\t\tif j >= len(key) {\n\t\t\t\tj = 0\n\t\t\t}\n\t\t}\n\t\tc.p[i] ^= d\n\t}\n\n\tvar l, r uint32\n\tfor i := 0; i < 18; i += 2 {\n\t\tl, r = encryptBlock(l, r, c)\n\t\tc.p[i], c.p[i+1] = l, r\n\t}\n\n\tfor i := 0; i < 256; i += 2 {\n\t\tl, r = encryptBlock(l, r, c)\n\t\tc.s0[i], c.s0[i+1] = l, r\n\t}\n\tfor i := 0; i < 256; i += 2 {\n\t\tl, r = encryptBlock(l, r, c)\n\t\tc.s1[i], c.s1[i+1] = l, r\n\t}\n\tfor i := 0; i < 256; i += 2 {\n\t\tl, r = encryptBlock(l, r, c)\n\t\tc.s2[i], c.s2[i+1] = l, r\n\t}\n\tfor i := 0; i < 256; i += 2 {\n\t\tl, r = encryptBlock(l, r, c)\n\t\tc.s3[i], c.s3[i+1] = l, r\n\t}\n}\n\n// This is similar to ExpandKey, but folds the salt during the key\n// schedule. While ExpandKey is essentially expandKeyWithSalt with an all-zero\n// salt passed in, reusing ExpandKey turns out to be a place of inefficiency\n// and specializing it here is useful.\nfunc expandKeyWithSalt(key []byte, salt []byte, c *Cipher) {\n\tj := 0\n\tfor i := 0; i < 18; i++ {\n\t\tc.p[i] ^= getNextWord(key, &j)\n\t}\n\n\tj = 0\n\tvar l, r uint32\n\tfor i := 0; i < 18; i += 2 {\n\t\tl ^= getNextWord(salt, &j)\n\t\tr ^= getNextWord(salt, &j)\n\t\tl, r = encryptBlock(l, r, c)\n\t\tc.p[i], c.p[i+1] = l, r\n\t}\n\n\tfor i := 0; i < 256; i += 2 {\n\t\tl ^= getNextWord(salt, &j)\n\t\tr ^= getNextWord(salt, &j)\n\t\tl, r = encryptBlock(l, r, c)\n\t\tc.s0[i], c.s0[i+1] = l, r\n\t}\n\n\tfor i := 0; i < 256; i += 2 {\n\t\tl ^= getNextWord(salt, &j)\n\t\tr ^= getNextWord(salt, &j)\n\t\tl, r = encryptBlock(l, r, c)\n\t\tc.s1[i], c.s1[i+1] = l, r\n\t}\n\n\tfor i := 0; i < 256; i += 2 {\n\t\tl ^= getNextWord(salt, &j)\n\t\tr ^= getNextWord(salt, &j)\n\t\tl, r = encryptBlock(l, r, c)\n\t\tc.s2[i], c.s2[i+1] = l, r\n\t}\n\n\tfor i := 0; i < 256; i += 2 {\n\t\tl ^= getNextWord(salt, &j)\n\t\tr ^= getNextWord(salt, &j)\n\t\tl, r = encryptBlock(l, r, c)\n\t\tc.s3[i], c.s3[i+1] = l, r\n\t}\n}\n\nfunc encryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {\n\txl, xr := l, r\n\txl ^= c.p[0]\n\txr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[1]\n\txl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[2]\n\txr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[3]\n\txl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[4]\n\txr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[5]\n\txl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[6]\n\txr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[7]\n\txl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[8]\n\txr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[9]\n\txl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[10]\n\txr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[11]\n\txl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[12]\n\txr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[13]\n\txl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[14]\n\txr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[15]\n\txl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[16]\n\txr ^= c.p[17]\n\treturn xr, xl\n}\n\nfunc decryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {\n\txl, xr := l, r\n\txl ^= c.p[17]\n\txr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[16]\n\txl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[15]\n\txr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[14]\n\txl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[13]\n\txr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[12]\n\txl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[11]\n\txr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[10]\n\txl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[9]\n\txr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[8]\n\txl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[7]\n\txr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[6]\n\txl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[5]\n\txr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[4]\n\txl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[3]\n\txr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[2]\n\txl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[1]\n\txr ^= c.p[0]\n\treturn xr, xl\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/blowfish/cipher.go",
    "content": "// Copyright 2010 The Go 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\n// Package blowfish implements Bruce Schneier's Blowfish encryption algorithm.\n//\n// Blowfish is a legacy cipher and its short block size makes it vulnerable to\n// birthday bound attacks (see https://sweet32.info). It should only be used\n// where compatibility with legacy systems, not security, is the goal.\n//\n// Deprecated: any new system should use AES (from crypto/aes, if necessary in\n// an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from\n// golang.org/x/crypto/chacha20poly1305).\npackage blowfish\n\n// The code is a port of Bruce Schneier's C implementation.\n// See https://www.schneier.com/blowfish.html.\n\nimport \"strconv\"\n\n// The Blowfish block size in bytes.\nconst BlockSize = 8\n\n// A Cipher is an instance of Blowfish encryption using a particular key.\ntype Cipher struct {\n\tp              [18]uint32\n\ts0, s1, s2, s3 [256]uint32\n}\n\ntype KeySizeError int\n\nfunc (k KeySizeError) Error() string {\n\treturn \"crypto/blowfish: invalid key size \" + strconv.Itoa(int(k))\n}\n\n// NewCipher creates and returns a Cipher.\n// The key argument should be the Blowfish key, from 1 to 56 bytes.\nfunc NewCipher(key []byte) (*Cipher, error) {\n\tvar result Cipher\n\tif k := len(key); k < 1 || k > 56 {\n\t\treturn nil, KeySizeError(k)\n\t}\n\tinitCipher(&result)\n\tExpandKey(key, &result)\n\treturn &result, nil\n}\n\n// NewSaltedCipher creates a returns a Cipher that folds a salt into its key\n// schedule. For most purposes, NewCipher, instead of NewSaltedCipher, is\n// sufficient and desirable. For bcrypt compatibility, the key can be over 56\n// bytes.\nfunc NewSaltedCipher(key, salt []byte) (*Cipher, error) {\n\tif len(salt) == 0 {\n\t\treturn NewCipher(key)\n\t}\n\tvar result Cipher\n\tif k := len(key); k < 1 {\n\t\treturn nil, KeySizeError(k)\n\t}\n\tinitCipher(&result)\n\texpandKeyWithSalt(key, salt, &result)\n\treturn &result, nil\n}\n\n// BlockSize returns the Blowfish block size, 8 bytes.\n// It is necessary to satisfy the Block interface in the\n// package \"crypto/cipher\".\nfunc (c *Cipher) BlockSize() int { return BlockSize }\n\n// Encrypt encrypts the 8-byte buffer src using the key k\n// and stores the result in dst.\n// Note that for amounts of data larger than a block,\n// it is not safe to just call Encrypt on successive blocks;\n// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).\nfunc (c *Cipher) Encrypt(dst, src []byte) {\n\tl := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])\n\tr := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])\n\tl, r = encryptBlock(l, r, c)\n\tdst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)\n\tdst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r)\n}\n\n// Decrypt decrypts the 8-byte buffer src using the key k\n// and stores the result in dst.\nfunc (c *Cipher) Decrypt(dst, src []byte) {\n\tl := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])\n\tr := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])\n\tl, r = decryptBlock(l, r, c)\n\tdst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)\n\tdst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r)\n}\n\nfunc initCipher(c *Cipher) {\n\tcopy(c.p[0:], p[0:])\n\tcopy(c.s0[0:], s0[0:])\n\tcopy(c.s1[0:], s1[0:])\n\tcopy(c.s2[0:], s2[0:])\n\tcopy(c.s3[0:], s3[0:])\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/blowfish/const.go",
    "content": "// Copyright 2010 The Go 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\n// The startup permutation array and substitution boxes.\n// They are the hexadecimal digits of PI; see:\n// https://www.schneier.com/code/constants.txt.\n\npackage blowfish\n\nvar s0 = [256]uint32{\n\t0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,\n\t0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,\n\t0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,\n\t0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,\n\t0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,\n\t0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,\n\t0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6,\n\t0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,\n\t0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,\n\t0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,\n\t0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1,\n\t0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,\n\t0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a,\n\t0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,\n\t0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,\n\t0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,\n\t0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706,\n\t0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,\n\t0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b,\n\t0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,\n\t0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,\n\t0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,\n\t0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a,\n\t0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,\n\t0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,\n\t0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,\n\t0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,\n\t0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,\n\t0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33,\n\t0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,\n\t0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0,\n\t0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,\n\t0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,\n\t0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,\n\t0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,\n\t0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,\n\t0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e,\n\t0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,\n\t0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,\n\t0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,\n\t0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f,\n\t0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,\n\t0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,\n}\n\nvar s1 = [256]uint32{\n\t0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d,\n\t0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,\n\t0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65,\n\t0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,\n\t0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9,\n\t0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,\n\t0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d,\n\t0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,\n\t0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc,\n\t0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,\n\t0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908,\n\t0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,\n\t0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124,\n\t0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,\n\t0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908,\n\t0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,\n\t0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b,\n\t0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,\n\t0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa,\n\t0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,\n\t0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d,\n\t0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,\n\t0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5,\n\t0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,\n\t0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96,\n\t0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,\n\t0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca,\n\t0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,\n\t0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77,\n\t0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,\n\t0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054,\n\t0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,\n\t0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea,\n\t0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,\n\t0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646,\n\t0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,\n\t0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea,\n\t0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,\n\t0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e,\n\t0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,\n\t0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd,\n\t0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,\n\t0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,\n}\n\nvar s2 = [256]uint32{\n\t0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7,\n\t0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,\n\t0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af,\n\t0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,\n\t0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4,\n\t0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,\n\t0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec,\n\t0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,\n\t0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332,\n\t0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,\n\t0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58,\n\t0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,\n\t0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22,\n\t0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,\n\t0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60,\n\t0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,\n\t0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99,\n\t0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,\n\t0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74,\n\t0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,\n\t0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3,\n\t0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,\n\t0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979,\n\t0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,\n\t0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa,\n\t0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,\n\t0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086,\n\t0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,\n\t0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24,\n\t0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,\n\t0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84,\n\t0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,\n\t0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09,\n\t0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,\n\t0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe,\n\t0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,\n\t0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0,\n\t0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,\n\t0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188,\n\t0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,\n\t0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8,\n\t0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,\n\t0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,\n}\n\nvar s3 = [256]uint32{\n\t0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742,\n\t0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,\n\t0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,\n\t0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,\n\t0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a,\n\t0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,\n\t0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,\n\t0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,\n\t0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,\n\t0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,\n\t0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6,\n\t0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,\n\t0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba,\n\t0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,\n\t0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,\n\t0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,\n\t0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,\n\t0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,\n\t0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd,\n\t0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,\n\t0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,\n\t0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,\n\t0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc,\n\t0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,\n\t0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc,\n\t0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,\n\t0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,\n\t0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,\n\t0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a,\n\t0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,\n\t0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b,\n\t0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,\n\t0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,\n\t0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,\n\t0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623,\n\t0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,\n\t0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,\n\t0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,\n\t0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,\n\t0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,\n\t0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c,\n\t0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,\n\t0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,\n}\n\nvar p = [18]uint32{\n\t0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,\n\t0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,\n\t0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b,\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/chacha20/chacha_arm64.go",
    "content": "// Copyright 2018 The Go 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\n//go:build gc && !purego\n\npackage chacha20\n\nconst bufSize = 256\n\n//go:noescape\nfunc xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)\n\nfunc (c *Cipher) xorKeyStreamBlocks(dst, src []byte) {\n\txorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/chacha20/chacha_arm64.s",
    "content": "// Copyright 2018 The Go 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\n//go:build gc && !purego\n\n#include \"textflag.h\"\n\n#define NUM_ROUNDS 10\n\n// func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)\nTEXT ·xorKeyStreamVX(SB), NOSPLIT, $0\n\tMOVD\tdst+0(FP), R1\n\tMOVD\tsrc+24(FP), R2\n\tMOVD\tsrc_len+32(FP), R3\n\tMOVD\tkey+48(FP), R4\n\tMOVD\tnonce+56(FP), R6\n\tMOVD\tcounter+64(FP), R7\n\n\tMOVD\t$·constants(SB), R10\n\tMOVD\t$·incRotMatrix(SB), R11\n\n\tMOVW\t(R7), R20\n\n\tAND\t$~255, R3, R13\n\tADD\tR2, R13, R12 // R12 for block end\n\tAND\t$255, R3, R13\nloop:\n\tMOVD\t$NUM_ROUNDS, R21\n\tVLD1\t(R11), [V30.S4, V31.S4]\n\n\t// load contants\n\t// VLD4R (R10), [V0.S4, V1.S4, V2.S4, V3.S4]\n\tWORD\t$0x4D60E940\n\n\t// load keys\n\t// VLD4R 16(R4), [V4.S4, V5.S4, V6.S4, V7.S4]\n\tWORD\t$0x4DFFE884\n\t// VLD4R 16(R4), [V8.S4, V9.S4, V10.S4, V11.S4]\n\tWORD\t$0x4DFFE888\n\tSUB\t$32, R4\n\n\t// load counter + nonce\n\t// VLD1R (R7), [V12.S4]\n\tWORD\t$0x4D40C8EC\n\n\t// VLD3R (R6), [V13.S4, V14.S4, V15.S4]\n\tWORD\t$0x4D40E8CD\n\n\t// update counter\n\tVADD\tV30.S4, V12.S4, V12.S4\n\nchacha:\n\t// V0..V3 += V4..V7\n\t// V12..V15 <<<= ((V12..V15 XOR V0..V3), 16)\n\tVADD\tV0.S4, V4.S4, V0.S4\n\tVADD\tV1.S4, V5.S4, V1.S4\n\tVADD\tV2.S4, V6.S4, V2.S4\n\tVADD\tV3.S4, V7.S4, V3.S4\n\tVEOR\tV12.B16, V0.B16, V12.B16\n\tVEOR\tV13.B16, V1.B16, V13.B16\n\tVEOR\tV14.B16, V2.B16, V14.B16\n\tVEOR\tV15.B16, V3.B16, V15.B16\n\tVREV32\tV12.H8, V12.H8\n\tVREV32\tV13.H8, V13.H8\n\tVREV32\tV14.H8, V14.H8\n\tVREV32\tV15.H8, V15.H8\n\t// V8..V11 += V12..V15\n\t// V4..V7 <<<= ((V4..V7 XOR V8..V11), 12)\n\tVADD\tV8.S4, V12.S4, V8.S4\n\tVADD\tV9.S4, V13.S4, V9.S4\n\tVADD\tV10.S4, V14.S4, V10.S4\n\tVADD\tV11.S4, V15.S4, V11.S4\n\tVEOR\tV8.B16, V4.B16, V16.B16\n\tVEOR\tV9.B16, V5.B16, V17.B16\n\tVEOR\tV10.B16, V6.B16, V18.B16\n\tVEOR\tV11.B16, V7.B16, V19.B16\n\tVSHL\t$12, V16.S4, V4.S4\n\tVSHL\t$12, V17.S4, V5.S4\n\tVSHL\t$12, V18.S4, V6.S4\n\tVSHL\t$12, V19.S4, V7.S4\n\tVSRI\t$20, V16.S4, V4.S4\n\tVSRI\t$20, V17.S4, V5.S4\n\tVSRI\t$20, V18.S4, V6.S4\n\tVSRI\t$20, V19.S4, V7.S4\n\n\t// V0..V3 += V4..V7\n\t// V12..V15 <<<= ((V12..V15 XOR V0..V3), 8)\n\tVADD\tV0.S4, V4.S4, V0.S4\n\tVADD\tV1.S4, V5.S4, V1.S4\n\tVADD\tV2.S4, V6.S4, V2.S4\n\tVADD\tV3.S4, V7.S4, V3.S4\n\tVEOR\tV12.B16, V0.B16, V12.B16\n\tVEOR\tV13.B16, V1.B16, V13.B16\n\tVEOR\tV14.B16, V2.B16, V14.B16\n\tVEOR\tV15.B16, V3.B16, V15.B16\n\tVTBL\tV31.B16, [V12.B16], V12.B16\n\tVTBL\tV31.B16, [V13.B16], V13.B16\n\tVTBL\tV31.B16, [V14.B16], V14.B16\n\tVTBL\tV31.B16, [V15.B16], V15.B16\n\n\t// V8..V11 += V12..V15\n\t// V4..V7 <<<= ((V4..V7 XOR V8..V11), 7)\n\tVADD\tV12.S4, V8.S4, V8.S4\n\tVADD\tV13.S4, V9.S4, V9.S4\n\tVADD\tV14.S4, V10.S4, V10.S4\n\tVADD\tV15.S4, V11.S4, V11.S4\n\tVEOR\tV8.B16, V4.B16, V16.B16\n\tVEOR\tV9.B16, V5.B16, V17.B16\n\tVEOR\tV10.B16, V6.B16, V18.B16\n\tVEOR\tV11.B16, V7.B16, V19.B16\n\tVSHL\t$7, V16.S4, V4.S4\n\tVSHL\t$7, V17.S4, V5.S4\n\tVSHL\t$7, V18.S4, V6.S4\n\tVSHL\t$7, V19.S4, V7.S4\n\tVSRI\t$25, V16.S4, V4.S4\n\tVSRI\t$25, V17.S4, V5.S4\n\tVSRI\t$25, V18.S4, V6.S4\n\tVSRI\t$25, V19.S4, V7.S4\n\n\t// V0..V3 += V5..V7, V4\n\t// V15,V12-V14 <<<= ((V15,V12-V14 XOR V0..V3), 16)\n\tVADD\tV0.S4, V5.S4, V0.S4\n\tVADD\tV1.S4, V6.S4, V1.S4\n\tVADD\tV2.S4, V7.S4, V2.S4\n\tVADD\tV3.S4, V4.S4, V3.S4\n\tVEOR\tV15.B16, V0.B16, V15.B16\n\tVEOR\tV12.B16, V1.B16, V12.B16\n\tVEOR\tV13.B16, V2.B16, V13.B16\n\tVEOR\tV14.B16, V3.B16, V14.B16\n\tVREV32\tV12.H8, V12.H8\n\tVREV32\tV13.H8, V13.H8\n\tVREV32\tV14.H8, V14.H8\n\tVREV32\tV15.H8, V15.H8\n\n\t// V10 += V15; V5 <<<= ((V10 XOR V5), 12)\n\t// ...\n\tVADD\tV15.S4, V10.S4, V10.S4\n\tVADD\tV12.S4, V11.S4, V11.S4\n\tVADD\tV13.S4, V8.S4, V8.S4\n\tVADD\tV14.S4, V9.S4, V9.S4\n\tVEOR\tV10.B16, V5.B16, V16.B16\n\tVEOR\tV11.B16, V6.B16, V17.B16\n\tVEOR\tV8.B16, V7.B16, V18.B16\n\tVEOR\tV9.B16, V4.B16, V19.B16\n\tVSHL\t$12, V16.S4, V5.S4\n\tVSHL\t$12, V17.S4, V6.S4\n\tVSHL\t$12, V18.S4, V7.S4\n\tVSHL\t$12, V19.S4, V4.S4\n\tVSRI\t$20, V16.S4, V5.S4\n\tVSRI\t$20, V17.S4, V6.S4\n\tVSRI\t$20, V18.S4, V7.S4\n\tVSRI\t$20, V19.S4, V4.S4\n\n\t// V0 += V5; V15 <<<= ((V0 XOR V15), 8)\n\t// ...\n\tVADD\tV5.S4, V0.S4, V0.S4\n\tVADD\tV6.S4, V1.S4, V1.S4\n\tVADD\tV7.S4, V2.S4, V2.S4\n\tVADD\tV4.S4, V3.S4, V3.S4\n\tVEOR\tV0.B16, V15.B16, V15.B16\n\tVEOR\tV1.B16, V12.B16, V12.B16\n\tVEOR\tV2.B16, V13.B16, V13.B16\n\tVEOR\tV3.B16, V14.B16, V14.B16\n\tVTBL\tV31.B16, [V12.B16], V12.B16\n\tVTBL\tV31.B16, [V13.B16], V13.B16\n\tVTBL\tV31.B16, [V14.B16], V14.B16\n\tVTBL\tV31.B16, [V15.B16], V15.B16\n\n\t// V10 += V15; V5 <<<= ((V10 XOR V5), 7)\n\t// ...\n\tVADD\tV15.S4, V10.S4, V10.S4\n\tVADD\tV12.S4, V11.S4, V11.S4\n\tVADD\tV13.S4, V8.S4, V8.S4\n\tVADD\tV14.S4, V9.S4, V9.S4\n\tVEOR\tV10.B16, V5.B16, V16.B16\n\tVEOR\tV11.B16, V6.B16, V17.B16\n\tVEOR\tV8.B16, V7.B16, V18.B16\n\tVEOR\tV9.B16, V4.B16, V19.B16\n\tVSHL\t$7, V16.S4, V5.S4\n\tVSHL\t$7, V17.S4, V6.S4\n\tVSHL\t$7, V18.S4, V7.S4\n\tVSHL\t$7, V19.S4, V4.S4\n\tVSRI\t$25, V16.S4, V5.S4\n\tVSRI\t$25, V17.S4, V6.S4\n\tVSRI\t$25, V18.S4, V7.S4\n\tVSRI\t$25, V19.S4, V4.S4\n\n\tSUB\t$1, R21\n\tCBNZ\tR21, chacha\n\n\t// VLD4R (R10), [V16.S4, V17.S4, V18.S4, V19.S4]\n\tWORD\t$0x4D60E950\n\n\t// VLD4R 16(R4), [V20.S4, V21.S4, V22.S4, V23.S4]\n\tWORD\t$0x4DFFE894\n\tVADD\tV30.S4, V12.S4, V12.S4\n\tVADD\tV16.S4, V0.S4, V0.S4\n\tVADD\tV17.S4, V1.S4, V1.S4\n\tVADD\tV18.S4, V2.S4, V2.S4\n\tVADD\tV19.S4, V3.S4, V3.S4\n\t// VLD4R 16(R4), [V24.S4, V25.S4, V26.S4, V27.S4]\n\tWORD\t$0x4DFFE898\n\t// restore R4\n\tSUB\t$32, R4\n\n\t// load counter + nonce\n\t// VLD1R (R7), [V28.S4]\n\tWORD\t$0x4D40C8FC\n\t// VLD3R (R6), [V29.S4, V30.S4, V31.S4]\n\tWORD\t$0x4D40E8DD\n\n\tVADD\tV20.S4, V4.S4, V4.S4\n\tVADD\tV21.S4, V5.S4, V5.S4\n\tVADD\tV22.S4, V6.S4, V6.S4\n\tVADD\tV23.S4, V7.S4, V7.S4\n\tVADD\tV24.S4, V8.S4, V8.S4\n\tVADD\tV25.S4, V9.S4, V9.S4\n\tVADD\tV26.S4, V10.S4, V10.S4\n\tVADD\tV27.S4, V11.S4, V11.S4\n\tVADD\tV28.S4, V12.S4, V12.S4\n\tVADD\tV29.S4, V13.S4, V13.S4\n\tVADD\tV30.S4, V14.S4, V14.S4\n\tVADD\tV31.S4, V15.S4, V15.S4\n\n\tVZIP1\tV1.S4, V0.S4, V16.S4\n\tVZIP2\tV1.S4, V0.S4, V17.S4\n\tVZIP1\tV3.S4, V2.S4, V18.S4\n\tVZIP2\tV3.S4, V2.S4, V19.S4\n\tVZIP1\tV5.S4, V4.S4, V20.S4\n\tVZIP2\tV5.S4, V4.S4, V21.S4\n\tVZIP1\tV7.S4, V6.S4, V22.S4\n\tVZIP2\tV7.S4, V6.S4, V23.S4\n\tVZIP1\tV9.S4, V8.S4, V24.S4\n\tVZIP2\tV9.S4, V8.S4, V25.S4\n\tVZIP1\tV11.S4, V10.S4, V26.S4\n\tVZIP2\tV11.S4, V10.S4, V27.S4\n\tVZIP1\tV13.S4, V12.S4, V28.S4\n\tVZIP2\tV13.S4, V12.S4, V29.S4\n\tVZIP1\tV15.S4, V14.S4, V30.S4\n\tVZIP2\tV15.S4, V14.S4, V31.S4\n\tVZIP1\tV18.D2, V16.D2, V0.D2\n\tVZIP2\tV18.D2, V16.D2, V4.D2\n\tVZIP1\tV19.D2, V17.D2, V8.D2\n\tVZIP2\tV19.D2, V17.D2, V12.D2\n\tVLD1.P\t64(R2), [V16.B16, V17.B16, V18.B16, V19.B16]\n\n\tVZIP1\tV22.D2, V20.D2, V1.D2\n\tVZIP2\tV22.D2, V20.D2, V5.D2\n\tVZIP1\tV23.D2, V21.D2, V9.D2\n\tVZIP2\tV23.D2, V21.D2, V13.D2\n\tVLD1.P\t64(R2), [V20.B16, V21.B16, V22.B16, V23.B16]\n\tVZIP1\tV26.D2, V24.D2, V2.D2\n\tVZIP2\tV26.D2, V24.D2, V6.D2\n\tVZIP1\tV27.D2, V25.D2, V10.D2\n\tVZIP2\tV27.D2, V25.D2, V14.D2\n\tVLD1.P\t64(R2), [V24.B16, V25.B16, V26.B16, V27.B16]\n\tVZIP1\tV30.D2, V28.D2, V3.D2\n\tVZIP2\tV30.D2, V28.D2, V7.D2\n\tVZIP1\tV31.D2, V29.D2, V11.D2\n\tVZIP2\tV31.D2, V29.D2, V15.D2\n\tVLD1.P\t64(R2), [V28.B16, V29.B16, V30.B16, V31.B16]\n\tVEOR\tV0.B16, V16.B16, V16.B16\n\tVEOR\tV1.B16, V17.B16, V17.B16\n\tVEOR\tV2.B16, V18.B16, V18.B16\n\tVEOR\tV3.B16, V19.B16, V19.B16\n\tVST1.P\t[V16.B16, V17.B16, V18.B16, V19.B16], 64(R1)\n\tVEOR\tV4.B16, V20.B16, V20.B16\n\tVEOR\tV5.B16, V21.B16, V21.B16\n\tVEOR\tV6.B16, V22.B16, V22.B16\n\tVEOR\tV7.B16, V23.B16, V23.B16\n\tVST1.P\t[V20.B16, V21.B16, V22.B16, V23.B16], 64(R1)\n\tVEOR\tV8.B16, V24.B16, V24.B16\n\tVEOR\tV9.B16, V25.B16, V25.B16\n\tVEOR\tV10.B16, V26.B16, V26.B16\n\tVEOR\tV11.B16, V27.B16, V27.B16\n\tVST1.P\t[V24.B16, V25.B16, V26.B16, V27.B16], 64(R1)\n\tVEOR\tV12.B16, V28.B16, V28.B16\n\tVEOR\tV13.B16, V29.B16, V29.B16\n\tVEOR\tV14.B16, V30.B16, V30.B16\n\tVEOR\tV15.B16, V31.B16, V31.B16\n\tVST1.P\t[V28.B16, V29.B16, V30.B16, V31.B16], 64(R1)\n\n\tADD\t$4, R20\n\tMOVW\tR20, (R7) // update counter\n\n\tCMP\tR2, R12\n\tBGT\tloop\n\n\tRET\n\n\nDATA\t·constants+0x00(SB)/4, $0x61707865\nDATA\t·constants+0x04(SB)/4, $0x3320646e\nDATA\t·constants+0x08(SB)/4, $0x79622d32\nDATA\t·constants+0x0c(SB)/4, $0x6b206574\nGLOBL\t·constants(SB), NOPTR|RODATA, $32\n\nDATA\t·incRotMatrix+0x00(SB)/4, $0x00000000\nDATA\t·incRotMatrix+0x04(SB)/4, $0x00000001\nDATA\t·incRotMatrix+0x08(SB)/4, $0x00000002\nDATA\t·incRotMatrix+0x0c(SB)/4, $0x00000003\nDATA\t·incRotMatrix+0x10(SB)/4, $0x02010003\nDATA\t·incRotMatrix+0x14(SB)/4, $0x06050407\nDATA\t·incRotMatrix+0x18(SB)/4, $0x0A09080B\nDATA\t·incRotMatrix+0x1c(SB)/4, $0x0E0D0C0F\nGLOBL\t·incRotMatrix(SB), NOPTR|RODATA, $32\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/chacha20/chacha_generic.go",
    "content": "// Copyright 2016 The Go 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\n// Package chacha20 implements the ChaCha20 and XChaCha20 encryption algorithms\n// as specified in RFC 8439 and draft-irtf-cfrg-xchacha-01.\npackage chacha20\n\nimport (\n\t\"crypto/cipher\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"math/bits\"\n\n\t\"golang.org/x/crypto/internal/alias\"\n)\n\nconst (\n\t// KeySize is the size of the key used by this cipher, in bytes.\n\tKeySize = 32\n\n\t// NonceSize is the size of the nonce used with the standard variant of this\n\t// cipher, in bytes.\n\t//\n\t// Note that this is too short to be safely generated at random if the same\n\t// key is reused more than 2³² times.\n\tNonceSize = 12\n\n\t// NonceSizeX is the size of the nonce used with the XChaCha20 variant of\n\t// this cipher, in bytes.\n\tNonceSizeX = 24\n)\n\n// Cipher is a stateful instance of ChaCha20 or XChaCha20 using a particular key\n// and nonce. A *Cipher implements the cipher.Stream interface.\ntype Cipher struct {\n\t// The ChaCha20 state is 16 words: 4 constant, 8 of key, 1 of counter\n\t// (incremented after each block), and 3 of nonce.\n\tkey     [8]uint32\n\tcounter uint32\n\tnonce   [3]uint32\n\n\t// The last len bytes of buf are leftover key stream bytes from the previous\n\t// XORKeyStream invocation. The size of buf depends on how many blocks are\n\t// computed at a time by xorKeyStreamBlocks.\n\tbuf [bufSize]byte\n\tlen int\n\n\t// overflow is set when the counter overflowed, no more blocks can be\n\t// generated, and the next XORKeyStream call should panic.\n\toverflow bool\n\n\t// The counter-independent results of the first round are cached after they\n\t// are computed the first time.\n\tprecompDone      bool\n\tp1, p5, p9, p13  uint32\n\tp2, p6, p10, p14 uint32\n\tp3, p7, p11, p15 uint32\n}\n\nvar _ cipher.Stream = (*Cipher)(nil)\n\n// NewUnauthenticatedCipher creates a new ChaCha20 stream cipher with the given\n// 32 bytes key and a 12 or 24 bytes nonce. If a nonce of 24 bytes is provided,\n// the XChaCha20 construction will be used. It returns an error if key or nonce\n// have any other length.\n//\n// Note that ChaCha20, like all stream ciphers, is not authenticated and allows\n// attackers to silently tamper with the plaintext. For this reason, it is more\n// appropriate as a building block than as a standalone encryption mechanism.\n// Instead, consider using package golang.org/x/crypto/chacha20poly1305.\nfunc NewUnauthenticatedCipher(key, nonce []byte) (*Cipher, error) {\n\t// This function is split into a wrapper so that the Cipher allocation will\n\t// be inlined, and depending on how the caller uses the return value, won't\n\t// escape to the heap.\n\tc := &Cipher{}\n\treturn newUnauthenticatedCipher(c, key, nonce)\n}\n\nfunc newUnauthenticatedCipher(c *Cipher, key, nonce []byte) (*Cipher, error) {\n\tif len(key) != KeySize {\n\t\treturn nil, errors.New(\"chacha20: wrong key size\")\n\t}\n\tif len(nonce) == NonceSizeX {\n\t\t// XChaCha20 uses the ChaCha20 core to mix 16 bytes of the nonce into a\n\t\t// derived key, allowing it to operate on a nonce of 24 bytes. See\n\t\t// draft-irtf-cfrg-xchacha-01, Section 2.3.\n\t\tkey, _ = HChaCha20(key, nonce[0:16])\n\t\tcNonce := make([]byte, NonceSize)\n\t\tcopy(cNonce[4:12], nonce[16:24])\n\t\tnonce = cNonce\n\t} else if len(nonce) != NonceSize {\n\t\treturn nil, errors.New(\"chacha20: wrong nonce size\")\n\t}\n\n\tkey, nonce = key[:KeySize], nonce[:NonceSize] // bounds check elimination hint\n\tc.key = [8]uint32{\n\t\tbinary.LittleEndian.Uint32(key[0:4]),\n\t\tbinary.LittleEndian.Uint32(key[4:8]),\n\t\tbinary.LittleEndian.Uint32(key[8:12]),\n\t\tbinary.LittleEndian.Uint32(key[12:16]),\n\t\tbinary.LittleEndian.Uint32(key[16:20]),\n\t\tbinary.LittleEndian.Uint32(key[20:24]),\n\t\tbinary.LittleEndian.Uint32(key[24:28]),\n\t\tbinary.LittleEndian.Uint32(key[28:32]),\n\t}\n\tc.nonce = [3]uint32{\n\t\tbinary.LittleEndian.Uint32(nonce[0:4]),\n\t\tbinary.LittleEndian.Uint32(nonce[4:8]),\n\t\tbinary.LittleEndian.Uint32(nonce[8:12]),\n\t}\n\treturn c, nil\n}\n\n// The constant first 4 words of the ChaCha20 state.\nconst (\n\tj0 uint32 = 0x61707865 // expa\n\tj1 uint32 = 0x3320646e // nd 3\n\tj2 uint32 = 0x79622d32 // 2-by\n\tj3 uint32 = 0x6b206574 // te k\n)\n\nconst blockSize = 64\n\n// quarterRound is the core of ChaCha20. It shuffles the bits of 4 state words.\n// It's executed 4 times for each of the 20 ChaCha20 rounds, operating on all 16\n// words each round, in columnar or diagonal groups of 4 at a time.\nfunc quarterRound(a, b, c, d uint32) (uint32, uint32, uint32, uint32) {\n\ta += b\n\td ^= a\n\td = bits.RotateLeft32(d, 16)\n\tc += d\n\tb ^= c\n\tb = bits.RotateLeft32(b, 12)\n\ta += b\n\td ^= a\n\td = bits.RotateLeft32(d, 8)\n\tc += d\n\tb ^= c\n\tb = bits.RotateLeft32(b, 7)\n\treturn a, b, c, d\n}\n\n// SetCounter sets the Cipher counter. The next invocation of XORKeyStream will\n// behave as if (64 * counter) bytes had been encrypted so far.\n//\n// To prevent accidental counter reuse, SetCounter panics if counter is less\n// than the current value.\n//\n// Note that the execution time of XORKeyStream is not independent of the\n// counter value.\nfunc (s *Cipher) SetCounter(counter uint32) {\n\t// Internally, s may buffer multiple blocks, which complicates this\n\t// implementation slightly. When checking whether the counter has rolled\n\t// back, we must use both s.counter and s.len to determine how many blocks\n\t// we have already output.\n\toutputCounter := s.counter - uint32(s.len)/blockSize\n\tif s.overflow || counter < outputCounter {\n\t\tpanic(\"chacha20: SetCounter attempted to rollback counter\")\n\t}\n\n\t// In the general case, we set the new counter value and reset s.len to 0,\n\t// causing the next call to XORKeyStream to refill the buffer. However, if\n\t// we're advancing within the existing buffer, we can save work by simply\n\t// setting s.len.\n\tif counter < s.counter {\n\t\ts.len = int(s.counter-counter) * blockSize\n\t} else {\n\t\ts.counter = counter\n\t\ts.len = 0\n\t}\n}\n\n// XORKeyStream XORs each byte in the given slice with a byte from the\n// cipher's key stream. Dst and src must overlap entirely or not at all.\n//\n// If len(dst) < len(src), XORKeyStream will panic. It is acceptable\n// to pass a dst bigger than src, and in that case, XORKeyStream will\n// only update dst[:len(src)] and will not touch the rest of dst.\n//\n// Multiple calls to XORKeyStream behave as if the concatenation of\n// the src buffers was passed in a single run. That is, Cipher\n// maintains state and does not reset at each XORKeyStream call.\nfunc (s *Cipher) XORKeyStream(dst, src []byte) {\n\tif len(src) == 0 {\n\t\treturn\n\t}\n\tif len(dst) < len(src) {\n\t\tpanic(\"chacha20: output smaller than input\")\n\t}\n\tdst = dst[:len(src)]\n\tif alias.InexactOverlap(dst, src) {\n\t\tpanic(\"chacha20: invalid buffer overlap\")\n\t}\n\n\t// First, drain any remaining key stream from a previous XORKeyStream.\n\tif s.len != 0 {\n\t\tkeyStream := s.buf[bufSize-s.len:]\n\t\tif len(src) < len(keyStream) {\n\t\t\tkeyStream = keyStream[:len(src)]\n\t\t}\n\t\t_ = src[len(keyStream)-1] // bounds check elimination hint\n\t\tfor i, b := range keyStream {\n\t\t\tdst[i] = src[i] ^ b\n\t\t}\n\t\ts.len -= len(keyStream)\n\t\tdst, src = dst[len(keyStream):], src[len(keyStream):]\n\t}\n\tif len(src) == 0 {\n\t\treturn\n\t}\n\n\t// If we'd need to let the counter overflow and keep generating output,\n\t// panic immediately. If instead we'd only reach the last block, remember\n\t// not to generate any more output after the buffer is drained.\n\tnumBlocks := (uint64(len(src)) + blockSize - 1) / blockSize\n\tif s.overflow || uint64(s.counter)+numBlocks > 1<<32 {\n\t\tpanic(\"chacha20: counter overflow\")\n\t} else if uint64(s.counter)+numBlocks == 1<<32 {\n\t\ts.overflow = true\n\t}\n\n\t// xorKeyStreamBlocks implementations expect input lengths that are a\n\t// multiple of bufSize. Platform-specific ones process multiple blocks at a\n\t// time, so have bufSizes that are a multiple of blockSize.\n\n\tfull := len(src) - len(src)%bufSize\n\tif full > 0 {\n\t\ts.xorKeyStreamBlocks(dst[:full], src[:full])\n\t}\n\tdst, src = dst[full:], src[full:]\n\n\t// If using a multi-block xorKeyStreamBlocks would overflow, use the generic\n\t// one that does one block at a time.\n\tconst blocksPerBuf = bufSize / blockSize\n\tif uint64(s.counter)+blocksPerBuf > 1<<32 {\n\t\ts.buf = [bufSize]byte{}\n\t\tnumBlocks := (len(src) + blockSize - 1) / blockSize\n\t\tbuf := s.buf[bufSize-numBlocks*blockSize:]\n\t\tcopy(buf, src)\n\t\ts.xorKeyStreamBlocksGeneric(buf, buf)\n\t\ts.len = len(buf) - copy(dst, buf)\n\t\treturn\n\t}\n\n\t// If we have a partial (multi-)block, pad it for xorKeyStreamBlocks, and\n\t// keep the leftover keystream for the next XORKeyStream invocation.\n\tif len(src) > 0 {\n\t\ts.buf = [bufSize]byte{}\n\t\tcopy(s.buf[:], src)\n\t\ts.xorKeyStreamBlocks(s.buf[:], s.buf[:])\n\t\ts.len = bufSize - copy(dst, s.buf[:])\n\t}\n}\n\nfunc (s *Cipher) xorKeyStreamBlocksGeneric(dst, src []byte) {\n\tif len(dst) != len(src) || len(dst)%blockSize != 0 {\n\t\tpanic(\"chacha20: internal error: wrong dst and/or src length\")\n\t}\n\n\t// To generate each block of key stream, the initial cipher state\n\t// (represented below) is passed through 20 rounds of shuffling,\n\t// alternatively applying quarterRounds by columns (like 1, 5, 9, 13)\n\t// or by diagonals (like 1, 6, 11, 12).\n\t//\n\t//      0:cccccccc   1:cccccccc   2:cccccccc   3:cccccccc\n\t//      4:kkkkkkkk   5:kkkkkkkk   6:kkkkkkkk   7:kkkkkkkk\n\t//      8:kkkkkkkk   9:kkkkkkkk  10:kkkkkkkk  11:kkkkkkkk\n\t//     12:bbbbbbbb  13:nnnnnnnn  14:nnnnnnnn  15:nnnnnnnn\n\t//\n\t//            c=constant k=key b=blockcount n=nonce\n\tvar (\n\t\tc0, c1, c2, c3   = j0, j1, j2, j3\n\t\tc4, c5, c6, c7   = s.key[0], s.key[1], s.key[2], s.key[3]\n\t\tc8, c9, c10, c11 = s.key[4], s.key[5], s.key[6], s.key[7]\n\t\t_, c13, c14, c15 = s.counter, s.nonce[0], s.nonce[1], s.nonce[2]\n\t)\n\n\t// Three quarters of the first round don't depend on the counter, so we can\n\t// calculate them here, and reuse them for multiple blocks in the loop, and\n\t// for future XORKeyStream invocations.\n\tif !s.precompDone {\n\t\ts.p1, s.p5, s.p9, s.p13 = quarterRound(c1, c5, c9, c13)\n\t\ts.p2, s.p6, s.p10, s.p14 = quarterRound(c2, c6, c10, c14)\n\t\ts.p3, s.p7, s.p11, s.p15 = quarterRound(c3, c7, c11, c15)\n\t\ts.precompDone = true\n\t}\n\n\t// A condition of len(src) > 0 would be sufficient, but this also\n\t// acts as a bounds check elimination hint.\n\tfor len(src) >= 64 && len(dst) >= 64 {\n\t\t// The remainder of the first column round.\n\t\tfcr0, fcr4, fcr8, fcr12 := quarterRound(c0, c4, c8, s.counter)\n\n\t\t// The second diagonal round.\n\t\tx0, x5, x10, x15 := quarterRound(fcr0, s.p5, s.p10, s.p15)\n\t\tx1, x6, x11, x12 := quarterRound(s.p1, s.p6, s.p11, fcr12)\n\t\tx2, x7, x8, x13 := quarterRound(s.p2, s.p7, fcr8, s.p13)\n\t\tx3, x4, x9, x14 := quarterRound(s.p3, fcr4, s.p9, s.p14)\n\n\t\t// The remaining 18 rounds.\n\t\tfor i := 0; i < 9; i++ {\n\t\t\t// Column round.\n\t\t\tx0, x4, x8, x12 = quarterRound(x0, x4, x8, x12)\n\t\t\tx1, x5, x9, x13 = quarterRound(x1, x5, x9, x13)\n\t\t\tx2, x6, x10, x14 = quarterRound(x2, x6, x10, x14)\n\t\t\tx3, x7, x11, x15 = quarterRound(x3, x7, x11, x15)\n\n\t\t\t// Diagonal round.\n\t\t\tx0, x5, x10, x15 = quarterRound(x0, x5, x10, x15)\n\t\t\tx1, x6, x11, x12 = quarterRound(x1, x6, x11, x12)\n\t\t\tx2, x7, x8, x13 = quarterRound(x2, x7, x8, x13)\n\t\t\tx3, x4, x9, x14 = quarterRound(x3, x4, x9, x14)\n\t\t}\n\n\t\t// Add back the initial state to generate the key stream, then\n\t\t// XOR the key stream with the source and write out the result.\n\t\taddXor(dst[0:4], src[0:4], x0, c0)\n\t\taddXor(dst[4:8], src[4:8], x1, c1)\n\t\taddXor(dst[8:12], src[8:12], x2, c2)\n\t\taddXor(dst[12:16], src[12:16], x3, c3)\n\t\taddXor(dst[16:20], src[16:20], x4, c4)\n\t\taddXor(dst[20:24], src[20:24], x5, c5)\n\t\taddXor(dst[24:28], src[24:28], x6, c6)\n\t\taddXor(dst[28:32], src[28:32], x7, c7)\n\t\taddXor(dst[32:36], src[32:36], x8, c8)\n\t\taddXor(dst[36:40], src[36:40], x9, c9)\n\t\taddXor(dst[40:44], src[40:44], x10, c10)\n\t\taddXor(dst[44:48], src[44:48], x11, c11)\n\t\taddXor(dst[48:52], src[48:52], x12, s.counter)\n\t\taddXor(dst[52:56], src[52:56], x13, c13)\n\t\taddXor(dst[56:60], src[56:60], x14, c14)\n\t\taddXor(dst[60:64], src[60:64], x15, c15)\n\n\t\ts.counter += 1\n\n\t\tsrc, dst = src[blockSize:], dst[blockSize:]\n\t}\n}\n\n// HChaCha20 uses the ChaCha20 core to generate a derived key from a 32 bytes\n// key and a 16 bytes nonce. It returns an error if key or nonce have any other\n// length. It is used as part of the XChaCha20 construction.\nfunc HChaCha20(key, nonce []byte) ([]byte, error) {\n\t// This function is split into a wrapper so that the slice allocation will\n\t// be inlined, and depending on how the caller uses the return value, won't\n\t// escape to the heap.\n\tout := make([]byte, 32)\n\treturn hChaCha20(out, key, nonce)\n}\n\nfunc hChaCha20(out, key, nonce []byte) ([]byte, error) {\n\tif len(key) != KeySize {\n\t\treturn nil, errors.New(\"chacha20: wrong HChaCha20 key size\")\n\t}\n\tif len(nonce) != 16 {\n\t\treturn nil, errors.New(\"chacha20: wrong HChaCha20 nonce size\")\n\t}\n\n\tx0, x1, x2, x3 := j0, j1, j2, j3\n\tx4 := binary.LittleEndian.Uint32(key[0:4])\n\tx5 := binary.LittleEndian.Uint32(key[4:8])\n\tx6 := binary.LittleEndian.Uint32(key[8:12])\n\tx7 := binary.LittleEndian.Uint32(key[12:16])\n\tx8 := binary.LittleEndian.Uint32(key[16:20])\n\tx9 := binary.LittleEndian.Uint32(key[20:24])\n\tx10 := binary.LittleEndian.Uint32(key[24:28])\n\tx11 := binary.LittleEndian.Uint32(key[28:32])\n\tx12 := binary.LittleEndian.Uint32(nonce[0:4])\n\tx13 := binary.LittleEndian.Uint32(nonce[4:8])\n\tx14 := binary.LittleEndian.Uint32(nonce[8:12])\n\tx15 := binary.LittleEndian.Uint32(nonce[12:16])\n\n\tfor i := 0; i < 10; i++ {\n\t\t// Diagonal round.\n\t\tx0, x4, x8, x12 = quarterRound(x0, x4, x8, x12)\n\t\tx1, x5, x9, x13 = quarterRound(x1, x5, x9, x13)\n\t\tx2, x6, x10, x14 = quarterRound(x2, x6, x10, x14)\n\t\tx3, x7, x11, x15 = quarterRound(x3, x7, x11, x15)\n\n\t\t// Column round.\n\t\tx0, x5, x10, x15 = quarterRound(x0, x5, x10, x15)\n\t\tx1, x6, x11, x12 = quarterRound(x1, x6, x11, x12)\n\t\tx2, x7, x8, x13 = quarterRound(x2, x7, x8, x13)\n\t\tx3, x4, x9, x14 = quarterRound(x3, x4, x9, x14)\n\t}\n\n\t_ = out[31] // bounds check elimination hint\n\tbinary.LittleEndian.PutUint32(out[0:4], x0)\n\tbinary.LittleEndian.PutUint32(out[4:8], x1)\n\tbinary.LittleEndian.PutUint32(out[8:12], x2)\n\tbinary.LittleEndian.PutUint32(out[12:16], x3)\n\tbinary.LittleEndian.PutUint32(out[16:20], x12)\n\tbinary.LittleEndian.PutUint32(out[20:24], x13)\n\tbinary.LittleEndian.PutUint32(out[24:28], x14)\n\tbinary.LittleEndian.PutUint32(out[28:32], x15)\n\treturn out, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/chacha20/chacha_noasm.go",
    "content": "// Copyright 2018 The Go 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\n//go:build (!arm64 && !s390x && !ppc64 && !ppc64le) || !gc || purego\n\npackage chacha20\n\nconst bufSize = blockSize\n\nfunc (s *Cipher) xorKeyStreamBlocks(dst, src []byte) {\n\ts.xorKeyStreamBlocksGeneric(dst, src)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/chacha20/chacha_ppc64x.go",
    "content": "// Copyright 2019 The Go 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\n//go:build gc && !purego && (ppc64 || ppc64le)\n\npackage chacha20\n\nconst bufSize = 256\n\n//go:noescape\nfunc chaCha20_ctr32_vsx(out, inp *byte, len int, key *[8]uint32, counter *uint32)\n\nfunc (c *Cipher) xorKeyStreamBlocks(dst, src []byte) {\n\tchaCha20_ctr32_vsx(&dst[0], &src[0], len(src), &c.key, &c.counter)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/chacha20/chacha_ppc64x.s",
    "content": "// Copyright 2019 The Go 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\n// Based on CRYPTOGAMS code with the following comment:\n// # ====================================================================\n// # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL\n// # project. The module is, however, dual licensed under OpenSSL and\n// # CRYPTOGAMS licenses depending on where you obtain it. For further\n// # details see http://www.openssl.org/~appro/cryptogams/.\n// # ====================================================================\n\n// Code for the perl script that generates the ppc64 assembler\n// can be found in the cryptogams repository at the link below. It is based on\n// the original from openssl.\n\n// https://github.com/dot-asm/cryptogams/commit/a60f5b50ed908e91\n\n// The differences in this and the original implementation are\n// due to the calling conventions and initialization of constants.\n\n//go:build gc && !purego && (ppc64 || ppc64le)\n\n#include \"textflag.h\"\n\n#define OUT  R3\n#define INP  R4\n#define LEN  R5\n#define KEY  R6\n#define CNT  R7\n#define TMP  R15\n\n#define CONSTBASE  R16\n#define BLOCKS R17\n\n// for VPERMXOR\n#define MASK  R18\n\nDATA consts<>+0x00(SB)/4, $0x61707865\nDATA consts<>+0x04(SB)/4, $0x3320646e\nDATA consts<>+0x08(SB)/4, $0x79622d32\nDATA consts<>+0x0c(SB)/4, $0x6b206574\nDATA consts<>+0x10(SB)/4, $0x00000001\nDATA consts<>+0x14(SB)/4, $0x00000000\nDATA consts<>+0x18(SB)/4, $0x00000000\nDATA consts<>+0x1c(SB)/4, $0x00000000\nDATA consts<>+0x20(SB)/4, $0x00000004\nDATA consts<>+0x24(SB)/4, $0x00000000\nDATA consts<>+0x28(SB)/4, $0x00000000\nDATA consts<>+0x2c(SB)/4, $0x00000000\nDATA consts<>+0x30(SB)/4, $0x0e0f0c0d\nDATA consts<>+0x34(SB)/4, $0x0a0b0809\nDATA consts<>+0x38(SB)/4, $0x06070405\nDATA consts<>+0x3c(SB)/4, $0x02030001\nDATA consts<>+0x40(SB)/4, $0x0d0e0f0c\nDATA consts<>+0x44(SB)/4, $0x090a0b08\nDATA consts<>+0x48(SB)/4, $0x05060704\nDATA consts<>+0x4c(SB)/4, $0x01020300\nDATA consts<>+0x50(SB)/4, $0x61707865\nDATA consts<>+0x54(SB)/4, $0x61707865\nDATA consts<>+0x58(SB)/4, $0x61707865\nDATA consts<>+0x5c(SB)/4, $0x61707865\nDATA consts<>+0x60(SB)/4, $0x3320646e\nDATA consts<>+0x64(SB)/4, $0x3320646e\nDATA consts<>+0x68(SB)/4, $0x3320646e\nDATA consts<>+0x6c(SB)/4, $0x3320646e\nDATA consts<>+0x70(SB)/4, $0x79622d32\nDATA consts<>+0x74(SB)/4, $0x79622d32\nDATA consts<>+0x78(SB)/4, $0x79622d32\nDATA consts<>+0x7c(SB)/4, $0x79622d32\nDATA consts<>+0x80(SB)/4, $0x6b206574\nDATA consts<>+0x84(SB)/4, $0x6b206574\nDATA consts<>+0x88(SB)/4, $0x6b206574\nDATA consts<>+0x8c(SB)/4, $0x6b206574\nDATA consts<>+0x90(SB)/4, $0x00000000\nDATA consts<>+0x94(SB)/4, $0x00000001\nDATA consts<>+0x98(SB)/4, $0x00000002\nDATA consts<>+0x9c(SB)/4, $0x00000003\nDATA consts<>+0xa0(SB)/4, $0x11223300\nDATA consts<>+0xa4(SB)/4, $0x55667744\nDATA consts<>+0xa8(SB)/4, $0x99aabb88\nDATA consts<>+0xac(SB)/4, $0xddeeffcc\nDATA consts<>+0xb0(SB)/4, $0x22330011\nDATA consts<>+0xb4(SB)/4, $0x66774455\nDATA consts<>+0xb8(SB)/4, $0xaabb8899\nDATA consts<>+0xbc(SB)/4, $0xeeffccdd\nGLOBL consts<>(SB), RODATA, $0xc0\n\n#ifdef GOARCH_ppc64\n#define BE_XXBRW_INIT() \\\n\t\tLVSL (R0)(R0), V24 \\\n\t\tVSPLTISB $3, V25   \\\n\t\tVXOR V24, V25, V24 \\\n\n#define BE_XXBRW(vr) VPERM vr, vr, V24, vr\n#else\n#define BE_XXBRW_INIT()\n#define BE_XXBRW(vr)\n#endif\n\n//func chaCha20_ctr32_vsx(out, inp *byte, len int, key *[8]uint32, counter *uint32)\nTEXT ·chaCha20_ctr32_vsx(SB),NOSPLIT,$64-40\n\tMOVD out+0(FP), OUT\n\tMOVD inp+8(FP), INP\n\tMOVD len+16(FP), LEN\n\tMOVD key+24(FP), KEY\n\tMOVD counter+32(FP), CNT\n\n\t// Addressing for constants\n\tMOVD $consts<>+0x00(SB), CONSTBASE\n\tMOVD $16, R8\n\tMOVD $32, R9\n\tMOVD $48, R10\n\tMOVD $64, R11\n\tSRD $6, LEN, BLOCKS\n\t// for VPERMXOR\n\tMOVD $consts<>+0xa0(SB), MASK\n\tMOVD $16, R20\n\t// V16\n\tLXVW4X (CONSTBASE)(R0), VS48\n\tADD $80,CONSTBASE\n\n\t// Load key into V17,V18\n\tLXVW4X (KEY)(R0), VS49\n\tLXVW4X (KEY)(R8), VS50\n\n\t// Load CNT, NONCE into V19\n\tLXVW4X (CNT)(R0), VS51\n\n\t// Clear V27\n\tVXOR V27, V27, V27\n\n\tBE_XXBRW_INIT()\n\n\t// V28\n\tLXVW4X (CONSTBASE)(R11), VS60\n\n\t// Load mask constants for VPERMXOR\n\tLXVW4X (MASK)(R0), V20\n\tLXVW4X (MASK)(R20), V21\n\n\t// splat slot from V19 -> V26\n\tVSPLTW $0, V19, V26\n\n\tVSLDOI $4, V19, V27, V19\n\tVSLDOI $12, V27, V19, V19\n\n\tVADDUWM V26, V28, V26\n\n\tMOVD $10, R14\n\tMOVD R14, CTR\n\tPCALIGN $16\nloop_outer_vsx:\n\t// V0, V1, V2, V3\n\tLXVW4X (R0)(CONSTBASE), VS32\n\tLXVW4X (R8)(CONSTBASE), VS33\n\tLXVW4X (R9)(CONSTBASE), VS34\n\tLXVW4X (R10)(CONSTBASE), VS35\n\n\t// splat values from V17, V18 into V4-V11\n\tVSPLTW $0, V17, V4\n\tVSPLTW $1, V17, V5\n\tVSPLTW $2, V17, V6\n\tVSPLTW $3, V17, V7\n\tVSPLTW $0, V18, V8\n\tVSPLTW $1, V18, V9\n\tVSPLTW $2, V18, V10\n\tVSPLTW $3, V18, V11\n\n\t// VOR\n\tVOR V26, V26, V12\n\n\t// splat values from V19 -> V13, V14, V15\n\tVSPLTW $1, V19, V13\n\tVSPLTW $2, V19, V14\n\tVSPLTW $3, V19, V15\n\n\t// splat   const values\n\tVSPLTISW $-16, V27\n\tVSPLTISW $12, V28\n\tVSPLTISW $8, V29\n\tVSPLTISW $7, V30\n\tPCALIGN $16\nloop_vsx:\n\tVADDUWM V0, V4, V0\n\tVADDUWM V1, V5, V1\n\tVADDUWM V2, V6, V2\n\tVADDUWM V3, V7, V3\n\n\tVPERMXOR V12, V0, V21, V12\n\tVPERMXOR V13, V1, V21, V13\n\tVPERMXOR V14, V2, V21, V14\n\tVPERMXOR V15, V3, V21, V15\n\n\tVADDUWM V8, V12, V8\n\tVADDUWM V9, V13, V9\n\tVADDUWM V10, V14, V10\n\tVADDUWM V11, V15, V11\n\n\tVXOR V4, V8, V4\n\tVXOR V5, V9, V5\n\tVXOR V6, V10, V6\n\tVXOR V7, V11, V7\n\n\tVRLW V4, V28, V4\n\tVRLW V5, V28, V5\n\tVRLW V6, V28, V6\n\tVRLW V7, V28, V7\n\n\tVADDUWM V0, V4, V0\n\tVADDUWM V1, V5, V1\n\tVADDUWM V2, V6, V2\n\tVADDUWM V3, V7, V3\n\n\tVPERMXOR V12, V0, V20, V12\n\tVPERMXOR V13, V1, V20, V13\n\tVPERMXOR V14, V2, V20, V14\n\tVPERMXOR V15, V3, V20, V15\n\n\tVADDUWM V8, V12, V8\n\tVADDUWM V9, V13, V9\n\tVADDUWM V10, V14, V10\n\tVADDUWM V11, V15, V11\n\n\tVXOR V4, V8, V4\n\tVXOR V5, V9, V5\n\tVXOR V6, V10, V6\n\tVXOR V7, V11, V7\n\n\tVRLW V4, V30, V4\n\tVRLW V5, V30, V5\n\tVRLW V6, V30, V6\n\tVRLW V7, V30, V7\n\n\tVADDUWM V0, V5, V0\n\tVADDUWM V1, V6, V1\n\tVADDUWM V2, V7, V2\n\tVADDUWM V3, V4, V3\n\n\tVPERMXOR V15, V0, V21, V15\n\tVPERMXOR V12, V1, V21, V12\n\tVPERMXOR V13, V2, V21, V13\n\tVPERMXOR V14, V3, V21, V14\n\n\tVADDUWM V10, V15, V10\n\tVADDUWM V11, V12, V11\n\tVADDUWM V8, V13, V8\n\tVADDUWM V9, V14, V9\n\n\tVXOR V5, V10, V5\n\tVXOR V6, V11, V6\n\tVXOR V7, V8, V7\n\tVXOR V4, V9, V4\n\n\tVRLW V5, V28, V5\n\tVRLW V6, V28, V6\n\tVRLW V7, V28, V7\n\tVRLW V4, V28, V4\n\n\tVADDUWM V0, V5, V0\n\tVADDUWM V1, V6, V1\n\tVADDUWM V2, V7, V2\n\tVADDUWM V3, V4, V3\n\n\tVPERMXOR V15, V0, V20, V15\n\tVPERMXOR V12, V1, V20, V12\n\tVPERMXOR V13, V2, V20, V13\n\tVPERMXOR V14, V3, V20, V14\n\n\tVADDUWM V10, V15, V10\n\tVADDUWM V11, V12, V11\n\tVADDUWM V8, V13, V8\n\tVADDUWM V9, V14, V9\n\n\tVXOR V5, V10, V5\n\tVXOR V6, V11, V6\n\tVXOR V7, V8, V7\n\tVXOR V4, V9, V4\n\n\tVRLW V5, V30, V5\n\tVRLW V6, V30, V6\n\tVRLW V7, V30, V7\n\tVRLW V4, V30, V4\n\tBDNZ   loop_vsx\n\n\tVADDUWM V12, V26, V12\n\n\tVMRGEW V0, V1, V27\n\tVMRGEW V2, V3, V28\n\n\tVMRGOW V0, V1, V0\n\tVMRGOW V2, V3, V2\n\n\tVMRGEW V4, V5, V29\n\tVMRGEW V6, V7, V30\n\n\tXXPERMDI VS32, VS34, $0, VS33\n\tXXPERMDI VS32, VS34, $3, VS35\n\tXXPERMDI VS59, VS60, $0, VS32\n\tXXPERMDI VS59, VS60, $3, VS34\n\n\tVMRGOW V4, V5, V4\n\tVMRGOW V6, V7, V6\n\n\tVMRGEW V8, V9, V27\n\tVMRGEW V10, V11, V28\n\n\tXXPERMDI VS36, VS38, $0, VS37\n\tXXPERMDI VS36, VS38, $3, VS39\n\tXXPERMDI VS61, VS62, $0, VS36\n\tXXPERMDI VS61, VS62, $3, VS38\n\n\tVMRGOW V8, V9, V8\n\tVMRGOW V10, V11, V10\n\n\tVMRGEW V12, V13, V29\n\tVMRGEW V14, V15, V30\n\n\tXXPERMDI VS40, VS42, $0, VS41\n\tXXPERMDI VS40, VS42, $3, VS43\n\tXXPERMDI VS59, VS60, $0, VS40\n\tXXPERMDI VS59, VS60, $3, VS42\n\n\tVMRGOW V12, V13, V12\n\tVMRGOW V14, V15, V14\n\n\tVSPLTISW $4, V27\n\tVADDUWM V26, V27, V26\n\n\tXXPERMDI VS44, VS46, $0, VS45\n\tXXPERMDI VS44, VS46, $3, VS47\n\tXXPERMDI VS61, VS62, $0, VS44\n\tXXPERMDI VS61, VS62, $3, VS46\n\n\tVADDUWM V0, V16, V0\n\tVADDUWM V4, V17, V4\n\tVADDUWM V8, V18, V8\n\tVADDUWM V12, V19, V12\n\n\tBE_XXBRW(V0)\n\tBE_XXBRW(V4)\n\tBE_XXBRW(V8)\n\tBE_XXBRW(V12)\n\n\tCMPU LEN, $64\n\tBLT tail_vsx\n\n\t// Bottom of loop\n\tLXVW4X (INP)(R0), VS59\n\tLXVW4X (INP)(R8), VS60\n\tLXVW4X (INP)(R9), VS61\n\tLXVW4X (INP)(R10), VS62\n\n\tVXOR V27, V0, V27\n\tVXOR V28, V4, V28\n\tVXOR V29, V8, V29\n\tVXOR V30, V12, V30\n\n\tSTXVW4X VS59, (OUT)(R0)\n\tSTXVW4X VS60, (OUT)(R8)\n\tADD     $64, INP\n\tSTXVW4X VS61, (OUT)(R9)\n\tADD     $-64, LEN\n\tSTXVW4X VS62, (OUT)(R10)\n\tADD     $64, OUT\n\tBEQ     done_vsx\n\n\tVADDUWM V1, V16, V0\n\tVADDUWM V5, V17, V4\n\tVADDUWM V9, V18, V8\n\tVADDUWM V13, V19, V12\n\n\tBE_XXBRW(V0)\n\tBE_XXBRW(V4)\n\tBE_XXBRW(V8)\n\tBE_XXBRW(V12)\n\n\tCMPU  LEN, $64\n\tBLT   tail_vsx\n\n\tLXVW4X (INP)(R0), VS59\n\tLXVW4X (INP)(R8), VS60\n\tLXVW4X (INP)(R9), VS61\n\tLXVW4X (INP)(R10), VS62\n\n\tVXOR V27, V0, V27\n\tVXOR V28, V4, V28\n\tVXOR V29, V8, V29\n\tVXOR V30, V12, V30\n\n\tSTXVW4X VS59, (OUT)(R0)\n\tSTXVW4X VS60, (OUT)(R8)\n\tADD     $64, INP\n\tSTXVW4X VS61, (OUT)(R9)\n\tADD     $-64, LEN\n\tSTXVW4X VS62, (OUT)(V10)\n\tADD     $64, OUT\n\tBEQ     done_vsx\n\n\tVADDUWM V2, V16, V0\n\tVADDUWM V6, V17, V4\n\tVADDUWM V10, V18, V8\n\tVADDUWM V14, V19, V12\n\n\tBE_XXBRW(V0)\n\tBE_XXBRW(V4)\n\tBE_XXBRW(V8)\n\tBE_XXBRW(V12)\n\n\tCMPU LEN, $64\n\tBLT  tail_vsx\n\n\tLXVW4X (INP)(R0), VS59\n\tLXVW4X (INP)(R8), VS60\n\tLXVW4X (INP)(R9), VS61\n\tLXVW4X (INP)(R10), VS62\n\n\tVXOR V27, V0, V27\n\tVXOR V28, V4, V28\n\tVXOR V29, V8, V29\n\tVXOR V30, V12, V30\n\n\tSTXVW4X VS59, (OUT)(R0)\n\tSTXVW4X VS60, (OUT)(R8)\n\tADD     $64, INP\n\tSTXVW4X VS61, (OUT)(R9)\n\tADD     $-64, LEN\n\tSTXVW4X VS62, (OUT)(R10)\n\tADD     $64, OUT\n\tBEQ     done_vsx\n\n\tVADDUWM V3, V16, V0\n\tVADDUWM V7, V17, V4\n\tVADDUWM V11, V18, V8\n\tVADDUWM V15, V19, V12\n\n\tBE_XXBRW(V0)\n\tBE_XXBRW(V4)\n\tBE_XXBRW(V8)\n\tBE_XXBRW(V12)\n\n\tCMPU  LEN, $64\n\tBLT   tail_vsx\n\n\tLXVW4X (INP)(R0), VS59\n\tLXVW4X (INP)(R8), VS60\n\tLXVW4X (INP)(R9), VS61\n\tLXVW4X (INP)(R10), VS62\n\n\tVXOR V27, V0, V27\n\tVXOR V28, V4, V28\n\tVXOR V29, V8, V29\n\tVXOR V30, V12, V30\n\n\tSTXVW4X VS59, (OUT)(R0)\n\tSTXVW4X VS60, (OUT)(R8)\n\tADD     $64, INP\n\tSTXVW4X VS61, (OUT)(R9)\n\tADD     $-64, LEN\n\tSTXVW4X VS62, (OUT)(R10)\n\tADD     $64, OUT\n\n\tMOVD $10, R14\n\tMOVD R14, CTR\n\tBNE  loop_outer_vsx\n\ndone_vsx:\n\t// Increment counter by number of 64 byte blocks\n\tMOVWZ (CNT), R14\n\tADD  BLOCKS, R14\n\tMOVWZ R14, (CNT)\n\tRET\n\ntail_vsx:\n\tADD  $32, R1, R11\n\tMOVD LEN, CTR\n\n\t// Save values on stack to copy from\n\tSTXVW4X VS32, (R11)(R0)\n\tSTXVW4X VS36, (R11)(R8)\n\tSTXVW4X VS40, (R11)(R9)\n\tSTXVW4X VS44, (R11)(R10)\n\tADD $-1, R11, R12\n\tADD $-1, INP\n\tADD $-1, OUT\n\tPCALIGN $16\nlooptail_vsx:\n\t// Copying the result to OUT\n\t// in bytes.\n\tMOVBZU 1(R12), KEY\n\tMOVBZU 1(INP), TMP\n\tXOR    KEY, TMP, KEY\n\tMOVBU  KEY, 1(OUT)\n\tBDNZ   looptail_vsx\n\n\t// Clear the stack values\n\tSTXVW4X VS48, (R11)(R0)\n\tSTXVW4X VS48, (R11)(R8)\n\tSTXVW4X VS48, (R11)(R9)\n\tSTXVW4X VS48, (R11)(R10)\n\tBR      done_vsx\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/chacha20/chacha_s390x.go",
    "content": "// Copyright 2018 The Go 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\n//go:build gc && !purego\n\npackage chacha20\n\nimport \"golang.org/x/sys/cpu\"\n\nvar haveAsm = cpu.S390X.HasVX\n\nconst bufSize = 256\n\n// xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only\n// be called when the vector facility is available. Implementation in asm_s390x.s.\n//\n//go:noescape\nfunc xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)\n\nfunc (c *Cipher) xorKeyStreamBlocks(dst, src []byte) {\n\tif cpu.S390X.HasVX {\n\t\txorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter)\n\t} else {\n\t\tc.xorKeyStreamBlocksGeneric(dst, src)\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/chacha20/chacha_s390x.s",
    "content": "// Copyright 2018 The Go 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\n//go:build gc && !purego\n\n#include \"go_asm.h\"\n#include \"textflag.h\"\n\n// This is an implementation of the ChaCha20 encryption algorithm as\n// specified in RFC 7539. It uses vector instructions to compute\n// 4 keystream blocks in parallel (256 bytes) which are then XORed\n// with the bytes in the input slice.\n\nGLOBL ·constants<>(SB), RODATA|NOPTR, $32\n// BSWAP: swap bytes in each 4-byte element\nDATA ·constants<>+0x00(SB)/4, $0x03020100\nDATA ·constants<>+0x04(SB)/4, $0x07060504\nDATA ·constants<>+0x08(SB)/4, $0x0b0a0908\nDATA ·constants<>+0x0c(SB)/4, $0x0f0e0d0c\n// J0: [j0, j1, j2, j3]\nDATA ·constants<>+0x10(SB)/4, $0x61707865\nDATA ·constants<>+0x14(SB)/4, $0x3320646e\nDATA ·constants<>+0x18(SB)/4, $0x79622d32\nDATA ·constants<>+0x1c(SB)/4, $0x6b206574\n\n#define BSWAP V5\n#define J0    V6\n#define KEY0  V7\n#define KEY1  V8\n#define NONCE V9\n#define CTR   V10\n#define M0    V11\n#define M1    V12\n#define M2    V13\n#define M3    V14\n#define INC   V15\n#define X0    V16\n#define X1    V17\n#define X2    V18\n#define X3    V19\n#define X4    V20\n#define X5    V21\n#define X6    V22\n#define X7    V23\n#define X8    V24\n#define X9    V25\n#define X10   V26\n#define X11   V27\n#define X12   V28\n#define X13   V29\n#define X14   V30\n#define X15   V31\n\n#define NUM_ROUNDS 20\n\n#define ROUND4(a0, a1, a2, a3, b0, b1, b2, b3, c0, c1, c2, c3, d0, d1, d2, d3) \\\n\tVAF    a1, a0, a0  \\\n\tVAF    b1, b0, b0  \\\n\tVAF    c1, c0, c0  \\\n\tVAF    d1, d0, d0  \\\n\tVX     a0, a2, a2  \\\n\tVX     b0, b2, b2  \\\n\tVX     c0, c2, c2  \\\n\tVX     d0, d2, d2  \\\n\tVERLLF $16, a2, a2 \\\n\tVERLLF $16, b2, b2 \\\n\tVERLLF $16, c2, c2 \\\n\tVERLLF $16, d2, d2 \\\n\tVAF    a2, a3, a3  \\\n\tVAF    b2, b3, b3  \\\n\tVAF    c2, c3, c3  \\\n\tVAF    d2, d3, d3  \\\n\tVX     a3, a1, a1  \\\n\tVX     b3, b1, b1  \\\n\tVX     c3, c1, c1  \\\n\tVX     d3, d1, d1  \\\n\tVERLLF $12, a1, a1 \\\n\tVERLLF $12, b1, b1 \\\n\tVERLLF $12, c1, c1 \\\n\tVERLLF $12, d1, d1 \\\n\tVAF    a1, a0, a0  \\\n\tVAF    b1, b0, b0  \\\n\tVAF    c1, c0, c0  \\\n\tVAF    d1, d0, d0  \\\n\tVX     a0, a2, a2  \\\n\tVX     b0, b2, b2  \\\n\tVX     c0, c2, c2  \\\n\tVX     d0, d2, d2  \\\n\tVERLLF $8, a2, a2  \\\n\tVERLLF $8, b2, b2  \\\n\tVERLLF $8, c2, c2  \\\n\tVERLLF $8, d2, d2  \\\n\tVAF    a2, a3, a3  \\\n\tVAF    b2, b3, b3  \\\n\tVAF    c2, c3, c3  \\\n\tVAF    d2, d3, d3  \\\n\tVX     a3, a1, a1  \\\n\tVX     b3, b1, b1  \\\n\tVX     c3, c1, c1  \\\n\tVX     d3, d1, d1  \\\n\tVERLLF $7, a1, a1  \\\n\tVERLLF $7, b1, b1  \\\n\tVERLLF $7, c1, c1  \\\n\tVERLLF $7, d1, d1\n\n#define PERMUTE(mask, v0, v1, v2, v3) \\\n\tVPERM v0, v0, mask, v0 \\\n\tVPERM v1, v1, mask, v1 \\\n\tVPERM v2, v2, mask, v2 \\\n\tVPERM v3, v3, mask, v3\n\n#define ADDV(x, v0, v1, v2, v3) \\\n\tVAF x, v0, v0 \\\n\tVAF x, v1, v1 \\\n\tVAF x, v2, v2 \\\n\tVAF x, v3, v3\n\n#define XORV(off, dst, src, v0, v1, v2, v3) \\\n\tVLM  off(src), M0, M3          \\\n\tPERMUTE(BSWAP, v0, v1, v2, v3) \\\n\tVX   v0, M0, M0                \\\n\tVX   v1, M1, M1                \\\n\tVX   v2, M2, M2                \\\n\tVX   v3, M3, M3                \\\n\tVSTM M0, M3, off(dst)\n\n#define SHUFFLE(a, b, c, d, t, u, v, w) \\\n\tVMRHF a, c, t \\ // t = {a[0], c[0], a[1], c[1]}\n\tVMRHF b, d, u \\ // u = {b[0], d[0], b[1], d[1]}\n\tVMRLF a, c, v \\ // v = {a[2], c[2], a[3], c[3]}\n\tVMRLF b, d, w \\ // w = {b[2], d[2], b[3], d[3]}\n\tVMRHF t, u, a \\ // a = {a[0], b[0], c[0], d[0]}\n\tVMRLF t, u, b \\ // b = {a[1], b[1], c[1], d[1]}\n\tVMRHF v, w, c \\ // c = {a[2], b[2], c[2], d[2]}\n\tVMRLF v, w, d // d = {a[3], b[3], c[3], d[3]}\n\n// func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)\nTEXT ·xorKeyStreamVX(SB), NOSPLIT, $0\n\tMOVD $·constants<>(SB), R1\n\tMOVD dst+0(FP), R2         // R2=&dst[0]\n\tLMG  src+24(FP), R3, R4    // R3=&src[0] R4=len(src)\n\tMOVD key+48(FP), R5        // R5=key\n\tMOVD nonce+56(FP), R6      // R6=nonce\n\tMOVD counter+64(FP), R7    // R7=counter\n\n\t// load BSWAP and J0\n\tVLM (R1), BSWAP, J0\n\n\t// setup\n\tMOVD  $95, R0\n\tVLM   (R5), KEY0, KEY1\n\tVLL   R0, (R6), NONCE\n\tVZERO M0\n\tVLEIB $7, $32, M0\n\tVSRLB M0, NONCE, NONCE\n\n\t// initialize counter values\n\tVLREPF (R7), CTR\n\tVZERO  INC\n\tVLEIF  $1, $1, INC\n\tVLEIF  $2, $2, INC\n\tVLEIF  $3, $3, INC\n\tVAF    INC, CTR, CTR\n\tVREPIF $4, INC\n\nchacha:\n\tVREPF $0, J0, X0\n\tVREPF $1, J0, X1\n\tVREPF $2, J0, X2\n\tVREPF $3, J0, X3\n\tVREPF $0, KEY0, X4\n\tVREPF $1, KEY0, X5\n\tVREPF $2, KEY0, X6\n\tVREPF $3, KEY0, X7\n\tVREPF $0, KEY1, X8\n\tVREPF $1, KEY1, X9\n\tVREPF $2, KEY1, X10\n\tVREPF $3, KEY1, X11\n\tVLR   CTR, X12\n\tVREPF $1, NONCE, X13\n\tVREPF $2, NONCE, X14\n\tVREPF $3, NONCE, X15\n\n\tMOVD $(NUM_ROUNDS/2), R1\n\nloop:\n\tROUND4(X0, X4, X12,  X8, X1, X5, X13,  X9, X2, X6, X14, X10, X3, X7, X15, X11)\n\tROUND4(X0, X5, X15, X10, X1, X6, X12, X11, X2, X7, X13, X8,  X3, X4, X14, X9)\n\n\tADD $-1, R1\n\tBNE loop\n\n\t// decrement length\n\tADD $-256, R4\n\n\t// rearrange vectors\n\tSHUFFLE(X0, X1, X2, X3, M0, M1, M2, M3)\n\tADDV(J0, X0, X1, X2, X3)\n\tSHUFFLE(X4, X5, X6, X7, M0, M1, M2, M3)\n\tADDV(KEY0, X4, X5, X6, X7)\n\tSHUFFLE(X8, X9, X10, X11, M0, M1, M2, M3)\n\tADDV(KEY1, X8, X9, X10, X11)\n\tVAF CTR, X12, X12\n\tSHUFFLE(X12, X13, X14, X15, M0, M1, M2, M3)\n\tADDV(NONCE, X12, X13, X14, X15)\n\n\t// increment counters\n\tVAF INC, CTR, CTR\n\n\t// xor keystream with plaintext\n\tXORV(0*64, R2, R3, X0, X4,  X8, X12)\n\tXORV(1*64, R2, R3, X1, X5,  X9, X13)\n\tXORV(2*64, R2, R3, X2, X6, X10, X14)\n\tXORV(3*64, R2, R3, X3, X7, X11, X15)\n\n\t// increment pointers\n\tMOVD $256(R2), R2\n\tMOVD $256(R3), R3\n\n\tCMPBNE  R4, $0, chacha\n\n\tVSTEF $0, CTR, (R7)\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/chacha20/xor.go",
    "content": "// Copyright 2018 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found src the LICENSE file.\n\npackage chacha20\n\nimport \"runtime\"\n\n// Platforms that have fast unaligned 32-bit little endian accesses.\nconst unaligned = runtime.GOARCH == \"386\" ||\n\truntime.GOARCH == \"amd64\" ||\n\truntime.GOARCH == \"arm64\" ||\n\truntime.GOARCH == \"ppc64le\" ||\n\truntime.GOARCH == \"s390x\"\n\n// addXor reads a little endian uint32 from src, XORs it with (a + b) and\n// places the result in little endian byte order in dst.\nfunc addXor(dst, src []byte, a, b uint32) {\n\t_, _ = src[3], dst[3] // bounds check elimination hint\n\tif unaligned {\n\t\t// The compiler should optimize this code into\n\t\t// 32-bit unaligned little endian loads and stores.\n\t\t// TODO: delete once the compiler does a reliably\n\t\t// good job with the generic code below.\n\t\t// See issue #25111 for more details.\n\t\tv := uint32(src[0])\n\t\tv |= uint32(src[1]) << 8\n\t\tv |= uint32(src[2]) << 16\n\t\tv |= uint32(src[3]) << 24\n\t\tv ^= a + b\n\t\tdst[0] = byte(v)\n\t\tdst[1] = byte(v >> 8)\n\t\tdst[2] = byte(v >> 16)\n\t\tdst[3] = byte(v >> 24)\n\t} else {\n\t\ta += b\n\t\tdst[0] = src[0] ^ byte(a)\n\t\tdst[1] = src[1] ^ byte(a>>8)\n\t\tdst[2] = src[2] ^ byte(a>>16)\n\t\tdst[3] = src[3] ^ byte(a>>24)\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go",
    "content": "// Copyright 2016 The Go 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\n// Package chacha20poly1305 implements the ChaCha20-Poly1305 AEAD and its\n// extended nonce variant XChaCha20-Poly1305, as specified in RFC 8439 and\n// draft-irtf-cfrg-xchacha-01.\npackage chacha20poly1305\n\nimport (\n\t\"crypto/cipher\"\n\t\"errors\"\n)\n\nconst (\n\t// KeySize is the size of the key used by this AEAD, in bytes.\n\tKeySize = 32\n\n\t// NonceSize is the size of the nonce used with the standard variant of this\n\t// AEAD, in bytes.\n\t//\n\t// Note that this is too short to be safely generated at random if the same\n\t// key is reused more than 2³² times.\n\tNonceSize = 12\n\n\t// NonceSizeX is the size of the nonce used with the XChaCha20-Poly1305\n\t// variant of this AEAD, in bytes.\n\tNonceSizeX = 24\n\n\t// Overhead is the size of the Poly1305 authentication tag, and the\n\t// difference between a ciphertext length and its plaintext.\n\tOverhead = 16\n)\n\ntype chacha20poly1305 struct {\n\tkey [KeySize]byte\n}\n\n// New returns a ChaCha20-Poly1305 AEAD that uses the given 256-bit key.\nfunc New(key []byte) (cipher.AEAD, error) {\n\tif len(key) != KeySize {\n\t\treturn nil, errors.New(\"chacha20poly1305: bad key length\")\n\t}\n\tret := new(chacha20poly1305)\n\tcopy(ret.key[:], key)\n\treturn ret, nil\n}\n\nfunc (c *chacha20poly1305) NonceSize() int {\n\treturn NonceSize\n}\n\nfunc (c *chacha20poly1305) Overhead() int {\n\treturn Overhead\n}\n\nfunc (c *chacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte {\n\tif len(nonce) != NonceSize {\n\t\tpanic(\"chacha20poly1305: bad nonce length passed to Seal\")\n\t}\n\n\tif uint64(len(plaintext)) > (1<<38)-64 {\n\t\tpanic(\"chacha20poly1305: plaintext too large\")\n\t}\n\n\treturn c.seal(dst, nonce, plaintext, additionalData)\n}\n\nvar errOpen = errors.New(\"chacha20poly1305: message authentication failed\")\n\nfunc (c *chacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {\n\tif len(nonce) != NonceSize {\n\t\tpanic(\"chacha20poly1305: bad nonce length passed to Open\")\n\t}\n\tif len(ciphertext) < 16 {\n\t\treturn nil, errOpen\n\t}\n\tif uint64(len(ciphertext)) > (1<<38)-48 {\n\t\tpanic(\"chacha20poly1305: ciphertext too large\")\n\t}\n\n\treturn c.open(dst, nonce, ciphertext, additionalData)\n}\n\n// sliceForAppend takes a slice and a requested number of bytes. It returns a\n// slice with the contents of the given slice followed by that many bytes and a\n// second slice that aliases into it and contains only the extra bytes. If the\n// original slice has sufficient capacity then no allocation is performed.\nfunc sliceForAppend(in []byte, n int) (head, tail []byte) {\n\tif total := len(in) + n; cap(in) >= total {\n\t\thead = in[:total]\n\t} else {\n\t\thead = make([]byte, total)\n\t\tcopy(head, in)\n\t}\n\ttail = head[len(in):]\n\treturn\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go",
    "content": "// Copyright 2016 The Go 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\n//go:build gc && !purego\n\npackage chacha20poly1305\n\nimport (\n\t\"encoding/binary\"\n\n\t\"golang.org/x/crypto/internal/alias\"\n\t\"golang.org/x/sys/cpu\"\n)\n\n//go:noescape\nfunc chacha20Poly1305Open(dst []byte, key []uint32, src, ad []byte) bool\n\n//go:noescape\nfunc chacha20Poly1305Seal(dst []byte, key []uint32, src, ad []byte)\n\nvar (\n\tuseAVX2 = cpu.X86.HasAVX2 && cpu.X86.HasBMI2\n)\n\n// setupState writes a ChaCha20 input matrix to state. See\n// https://tools.ietf.org/html/rfc7539#section-2.3.\nfunc setupState(state *[16]uint32, key *[32]byte, nonce []byte) {\n\tstate[0] = 0x61707865\n\tstate[1] = 0x3320646e\n\tstate[2] = 0x79622d32\n\tstate[3] = 0x6b206574\n\n\tstate[4] = binary.LittleEndian.Uint32(key[0:4])\n\tstate[5] = binary.LittleEndian.Uint32(key[4:8])\n\tstate[6] = binary.LittleEndian.Uint32(key[8:12])\n\tstate[7] = binary.LittleEndian.Uint32(key[12:16])\n\tstate[8] = binary.LittleEndian.Uint32(key[16:20])\n\tstate[9] = binary.LittleEndian.Uint32(key[20:24])\n\tstate[10] = binary.LittleEndian.Uint32(key[24:28])\n\tstate[11] = binary.LittleEndian.Uint32(key[28:32])\n\n\tstate[12] = 0\n\tstate[13] = binary.LittleEndian.Uint32(nonce[0:4])\n\tstate[14] = binary.LittleEndian.Uint32(nonce[4:8])\n\tstate[15] = binary.LittleEndian.Uint32(nonce[8:12])\n}\n\nfunc (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []byte {\n\tif !cpu.X86.HasSSSE3 {\n\t\treturn c.sealGeneric(dst, nonce, plaintext, additionalData)\n\t}\n\n\tvar state [16]uint32\n\tsetupState(&state, &c.key, nonce)\n\n\tret, out := sliceForAppend(dst, len(plaintext)+16)\n\tif alias.InexactOverlap(out, plaintext) {\n\t\tpanic(\"chacha20poly1305: invalid buffer overlap\")\n\t}\n\tchacha20Poly1305Seal(out[:], state[:], plaintext, additionalData)\n\treturn ret\n}\n\nfunc (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {\n\tif !cpu.X86.HasSSSE3 {\n\t\treturn c.openGeneric(dst, nonce, ciphertext, additionalData)\n\t}\n\n\tvar state [16]uint32\n\tsetupState(&state, &c.key, nonce)\n\n\tciphertext = ciphertext[:len(ciphertext)-16]\n\tret, out := sliceForAppend(dst, len(ciphertext))\n\tif alias.InexactOverlap(out, ciphertext) {\n\t\tpanic(\"chacha20poly1305: invalid buffer overlap\")\n\t}\n\tif !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) {\n\t\tfor i := range out {\n\t\t\tout[i] = 0\n\t\t}\n\t\treturn nil, errOpen\n\t}\n\n\treturn ret, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s",
    "content": "// Code generated by command: go run chacha20poly1305_amd64_asm.go -out ../chacha20poly1305_amd64.s -pkg chacha20poly1305. DO NOT EDIT.\n\n//go:build gc && !purego\n\n#include \"textflag.h\"\n\n// func polyHashADInternal<>()\nTEXT polyHashADInternal<>(SB), NOSPLIT, $0\n\t// Hack: Must declare #define macros inside of a function due to Avo constraints\n\t// ROL rotates the uint32s in register R left by N bits, using temporary T.\n\t#define ROL(N, R, T) \\\n\t\tMOVO R, T; \\\n\t\tPSLLL $(N), T; \\\n\t\tPSRLL $(32-(N)), R; \\\n\t\tPXOR T, R\n\n\t// ROL8 rotates the uint32s in register R left by 8, using temporary T if needed.\n\t#ifdef GOAMD64_v2\n\t\t#define ROL8(R, T) PSHUFB ·rol8<>(SB), R\n\t#else\n\t\t#define ROL8(R, T) ROL(8, R, T)\n\t#endif\n\n\t// ROL16 rotates the uint32s in register R left by 16, using temporary T if needed.\n\t#ifdef GOAMD64_v2\n\t\t#define ROL16(R, T) PSHUFB ·rol16<>(SB), R\n\t#else\n\t\t#define ROL16(R, T) ROL(16, R, T)\n\t#endif\n\tXORQ  R10, R10\n\tXORQ  R11, R11\n\tXORQ  R12, R12\n\tCMPQ  R9, $0x0d\n\tJNE   hashADLoop\n\tMOVQ  (CX), R10\n\tMOVQ  5(CX), R11\n\tSHRQ  $0x18, R11\n\tMOVQ  $0x00000001, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tRET\n\nhashADLoop:\n\t// Hash in 16 byte chunks\n\tCMPQ  R9, $0x10\n\tJB    hashADTail\n\tADDQ  (CX), R10\n\tADCQ  8(CX), R11\n\tADCQ  $0x01, R12\n\tLEAQ  16(CX), CX\n\tSUBQ  $0x10, R9\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tJMP   hashADLoop\n\nhashADTail:\n\tCMPQ R9, $0x00\n\tJE   hashADDone\n\n\t// Hash last < 16 byte tail\n\tXORQ R13, R13\n\tXORQ R14, R14\n\tXORQ R15, R15\n\tADDQ R9, CX\n\nhashADTailLoop:\n\tSHLQ  $0x08, R13, R14\n\tSHLQ  $0x08, R13\n\tMOVB  -1(CX), R15\n\tXORQ  R15, R13\n\tDECQ  CX\n\tDECQ  R9\n\tJNE   hashADTailLoop\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\nhashADDone:\n\tRET\n\n// func chacha20Poly1305Open(dst []byte, key []uint32, src []byte, ad []byte) bool\n// Requires: AVX, AVX2, BMI2, CMOV, SSE2\nTEXT ·chacha20Poly1305Open(SB), $288-97\n\t// For aligned stack access\n\tMOVQ SP, BP\n\tADDQ $0x20, BP\n\tANDQ $-32, BP\n\tMOVQ dst_base+0(FP), DI\n\tMOVQ key_base+24(FP), R8\n\tMOVQ src_base+48(FP), SI\n\tMOVQ src_len+56(FP), BX\n\tMOVQ ad_base+72(FP), CX\n\n\t// Check for AVX2 support\n\tCMPB ·useAVX2+0(SB), $0x01\n\tJE   chacha20Poly1305Open_AVX2\n\n\t// Special optimization, for very short buffers\n\tCMPQ BX, $0x80\n\tJBE  openSSE128\n\n\t// For long buffers, prepare the poly key first\n\tMOVOU ·chacha20Constants<>+0(SB), X0\n\tMOVOU 16(R8), X3\n\tMOVOU 32(R8), X6\n\tMOVOU 48(R8), X9\n\tMOVO  X9, X13\n\n\t// Store state on stack for future use\n\tMOVO X3, 32(BP)\n\tMOVO X6, 48(BP)\n\tMOVO X9, 128(BP)\n\tMOVQ $0x0000000a, R9\n\nopenSSEPreparePolyKey:\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X3\n\tPXOR  X12, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X3\n\tPXOR  X12, X3\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x0c\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X3\n\tPXOR  X12, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X3\n\tPXOR  X12, X3\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x04\n\tDECQ  R9\n\tJNE   openSSEPreparePolyKey\n\n\t// A0|B0 hold the Poly1305 32-byte key, C0,D0 can be discarded\n\tPADDL ·chacha20Constants<>+0(SB), X0\n\tPADDL 32(BP), X3\n\n\t// Clamp and store the key\n\tPAND ·polyClampMask<>+0(SB), X0\n\tMOVO X0, (BP)\n\tMOVO X3, 16(BP)\n\n\t// Hash AAD\n\tMOVQ ad_len+80(FP), R9\n\tCALL polyHashADInternal<>(SB)\n\nopenSSEMainLoop:\n\tCMPQ BX, $0x00000100\n\tJB   openSSEMainLoopDone\n\n\t// Load state, increment counter blocks\n\tMOVO  ·chacha20Constants<>+0(SB), X0\n\tMOVO  32(BP), X3\n\tMOVO  48(BP), X6\n\tMOVO  128(BP), X9\n\tPADDL ·sseIncMask<>+0(SB), X9\n\tMOVO  X0, X1\n\tMOVO  X3, X4\n\tMOVO  X6, X7\n\tMOVO  X9, X10\n\tPADDL ·sseIncMask<>+0(SB), X10\n\tMOVO  X1, X2\n\tMOVO  X4, X5\n\tMOVO  X7, X8\n\tMOVO  X10, X11\n\tPADDL ·sseIncMask<>+0(SB), X11\n\tMOVO  X2, X12\n\tMOVO  X5, X13\n\tMOVO  X8, X14\n\tMOVO  X11, X15\n\tPADDL ·sseIncMask<>+0(SB), X15\n\n\t// Store counters\n\tMOVO X9, 80(BP)\n\tMOVO X10, 96(BP)\n\tMOVO X11, 112(BP)\n\tMOVO X15, 128(BP)\n\n\t// There are 10 ChaCha20 iterations of 2QR each, so for 6 iterations we hash\n\t// 2 blocks, and for the remaining 4 only 1 block - for a total of 16\n\tMOVQ $0x00000004, CX\n\tMOVQ SI, R9\n\nopenSSEInternalLoop:\n\tMOVO  X14, 64(BP)\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X14)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X3\n\tPXOR  X14, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X14)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X3\n\tPXOR  X14, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X14)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X4\n\tPXOR  X14, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X14)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X4\n\tPXOR  X14, X4\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL16(X11, X14)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X5\n\tPXOR  X14, X5\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL8(X11, X14)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X5\n\tPXOR  X14, X5\n\tMOVO  64(BP), X14\n\tMOVO  X7, 64(BP)\n\tPADDD X13, X12\n\tPXOR  X12, X15\n\tROL16(X15, X7)\n\tPADDD X15, X14\n\tPXOR  X14, X13\n\tMOVO  X13, X7\n\tPSLLL $0x0c, X7\n\tPSRLL $0x14, X13\n\tPXOR  X7, X13\n\tPADDD X13, X12\n\tPXOR  X12, X15\n\tROL8(X15, X7)\n\tPADDD X15, X14\n\tPXOR  X14, X13\n\tMOVO  X13, X7\n\tPSLLL $0x07, X7\n\tPSRLL $0x19, X13\n\tPXOR  X7, X13\n\tMOVO  64(BP), X7\n\tADDQ  (R9), R10\n\tADCQ  8(R9), R11\n\tADCQ  $0x01, R12\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc0\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x0c\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tLEAQ  16(R9), R9\n\tMOVO  X14, 64(BP)\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X14)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X3\n\tPXOR  X14, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X14)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X3\n\tPXOR  X14, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X14)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X4\n\tPXOR  X14, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X14)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X4\n\tPXOR  X14, X4\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL16(X11, X14)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X5\n\tPXOR  X14, X5\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL8(X11, X14)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X5\n\tPXOR  X14, X5\n\tMOVO  64(BP), X14\n\tMOVO  X7, 64(BP)\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tPADDD X13, X12\n\tPXOR  X12, X15\n\tROL16(X15, X7)\n\tPADDD X15, X14\n\tPXOR  X14, X13\n\tMOVO  X13, X7\n\tPSLLL $0x0c, X7\n\tPSRLL $0x14, X13\n\tPXOR  X7, X13\n\tPADDD X13, X12\n\tPXOR  X12, X15\n\tROL8(X15, X7)\n\tPADDD X15, X14\n\tPXOR  X14, X13\n\tMOVO  X13, X7\n\tPSLLL $0x07, X7\n\tPSRLL $0x19, X13\n\tPXOR  X7, X13\n\tMOVO  64(BP), X7\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc0\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x04\n\tDECQ  CX\n\tJGE   openSSEInternalLoop\n\tADDQ  (R9), R10\n\tADCQ  8(R9), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(R9), R9\n\tCMPQ  CX, $-6\n\tJG    openSSEInternalLoop\n\n\t// Add in the state\n\tPADDD ·chacha20Constants<>+0(SB), X0\n\tPADDD ·chacha20Constants<>+0(SB), X1\n\tPADDD ·chacha20Constants<>+0(SB), X2\n\tPADDD ·chacha20Constants<>+0(SB), X12\n\tPADDD 32(BP), X3\n\tPADDD 32(BP), X4\n\tPADDD 32(BP), X5\n\tPADDD 32(BP), X13\n\tPADDD 48(BP), X6\n\tPADDD 48(BP), X7\n\tPADDD 48(BP), X8\n\tPADDD 48(BP), X14\n\tPADDD 80(BP), X9\n\tPADDD 96(BP), X10\n\tPADDD 112(BP), X11\n\tPADDD 128(BP), X15\n\n\t// Load - xor - store\n\tMOVO  X15, 64(BP)\n\tMOVOU (SI), X15\n\tPXOR  X15, X0\n\tMOVOU X0, (DI)\n\tMOVOU 16(SI), X15\n\tPXOR  X15, X3\n\tMOVOU X3, 16(DI)\n\tMOVOU 32(SI), X15\n\tPXOR  X15, X6\n\tMOVOU X6, 32(DI)\n\tMOVOU 48(SI), X15\n\tPXOR  X15, X9\n\tMOVOU X9, 48(DI)\n\tMOVOU 64(SI), X9\n\tPXOR  X9, X1\n\tMOVOU X1, 64(DI)\n\tMOVOU 80(SI), X9\n\tPXOR  X9, X4\n\tMOVOU X4, 80(DI)\n\tMOVOU 96(SI), X9\n\tPXOR  X9, X7\n\tMOVOU X7, 96(DI)\n\tMOVOU 112(SI), X9\n\tPXOR  X9, X10\n\tMOVOU X10, 112(DI)\n\tMOVOU 128(SI), X9\n\tPXOR  X9, X2\n\tMOVOU X2, 128(DI)\n\tMOVOU 144(SI), X9\n\tPXOR  X9, X5\n\tMOVOU X5, 144(DI)\n\tMOVOU 160(SI), X9\n\tPXOR  X9, X8\n\tMOVOU X8, 160(DI)\n\tMOVOU 176(SI), X9\n\tPXOR  X9, X11\n\tMOVOU X11, 176(DI)\n\tMOVOU 192(SI), X9\n\tPXOR  X9, X12\n\tMOVOU X12, 192(DI)\n\tMOVOU 208(SI), X9\n\tPXOR  X9, X13\n\tMOVOU X13, 208(DI)\n\tMOVOU 224(SI), X9\n\tPXOR  X9, X14\n\tMOVOU X14, 224(DI)\n\tMOVOU 240(SI), X9\n\tPXOR  64(BP), X9\n\tMOVOU X9, 240(DI)\n\tLEAQ  256(SI), SI\n\tLEAQ  256(DI), DI\n\tSUBQ  $0x00000100, BX\n\tJMP   openSSEMainLoop\n\nopenSSEMainLoopDone:\n\t// Handle the various tail sizes efficiently\n\tTESTQ BX, BX\n\tJE    openSSEFinalize\n\tCMPQ  BX, $0x40\n\tJBE   openSSETail64\n\tCMPQ  BX, $0x80\n\tJBE   openSSETail128\n\tCMPQ  BX, $0xc0\n\tJBE   openSSETail192\n\tJMP   openSSETail256\n\nopenSSEFinalize:\n\t// Hash in the PT, AAD lengths\n\tADDQ  ad_len+80(FP), R10\n\tADCQ  src_len+56(FP), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\n\t// Final reduce\n\tMOVQ    R10, R13\n\tMOVQ    R11, R14\n\tMOVQ    R12, R15\n\tSUBQ    $-5, R10\n\tSBBQ    $-1, R11\n\tSBBQ    $0x03, R12\n\tCMOVQCS R13, R10\n\tCMOVQCS R14, R11\n\tCMOVQCS R15, R12\n\n\t// Add in the \"s\" part of the key\n\tADDQ 16(BP), R10\n\tADCQ 24(BP), R11\n\n\t// Finally, constant time compare to the tag at the end of the message\n\tXORQ    AX, AX\n\tMOVQ    $0x00000001, DX\n\tXORQ    (SI), R10\n\tXORQ    8(SI), R11\n\tORQ     R11, R10\n\tCMOVQEQ DX, AX\n\n\t// Return true iff tags are equal\n\tMOVB AX, ret+96(FP)\n\tRET\n\nopenSSE128:\n\tMOVOU ·chacha20Constants<>+0(SB), X0\n\tMOVOU 16(R8), X3\n\tMOVOU 32(R8), X6\n\tMOVOU 48(R8), X9\n\tMOVO  X0, X1\n\tMOVO  X3, X4\n\tMOVO  X6, X7\n\tMOVO  X9, X10\n\tPADDL ·sseIncMask<>+0(SB), X10\n\tMOVO  X1, X2\n\tMOVO  X4, X5\n\tMOVO  X7, X8\n\tMOVO  X10, X11\n\tPADDL ·sseIncMask<>+0(SB), X11\n\tMOVO  X3, X13\n\tMOVO  X6, X14\n\tMOVO  X10, X15\n\tMOVQ  $0x0000000a, R9\n\nopenSSE128InnerCipherLoop:\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X3\n\tPXOR  X12, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X3\n\tPXOR  X12, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X4\n\tPXOR  X12, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X4\n\tPXOR  X12, X4\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL16(X11, X12)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X5\n\tPXOR  X12, X5\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL8(X11, X12)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X5\n\tPXOR  X12, X5\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc0\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X3\n\tPXOR  X12, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X3\n\tPXOR  X12, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X4\n\tPXOR  X12, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X4\n\tPXOR  X12, X4\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL16(X11, X12)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X5\n\tPXOR  X12, X5\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL8(X11, X12)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X5\n\tPXOR  X12, X5\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc0\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tDECQ  R9\n\tJNE   openSSE128InnerCipherLoop\n\n\t// A0|B0 hold the Poly1305 32-byte key, C0,D0 can be discarded\n\tPADDL ·chacha20Constants<>+0(SB), X0\n\tPADDL ·chacha20Constants<>+0(SB), X1\n\tPADDL ·chacha20Constants<>+0(SB), X2\n\tPADDL X13, X3\n\tPADDL X13, X4\n\tPADDL X13, X5\n\tPADDL X14, X7\n\tPADDL X14, X8\n\tPADDL X15, X10\n\tPADDL ·sseIncMask<>+0(SB), X15\n\tPADDL X15, X11\n\n\t// Clamp and store the key\n\tPAND  ·polyClampMask<>+0(SB), X0\n\tMOVOU X0, (BP)\n\tMOVOU X3, 16(BP)\n\n\t// Hash\n\tMOVQ ad_len+80(FP), R9\n\tCALL polyHashADInternal<>(SB)\n\nopenSSE128Open:\n\tCMPQ BX, $0x10\n\tJB   openSSETail16\n\tSUBQ $0x10, BX\n\n\t// Load for hashing\n\tADDQ (SI), R10\n\tADCQ 8(SI), R11\n\tADCQ $0x01, R12\n\n\t// Load for decryption\n\tMOVOU (SI), X12\n\tPXOR  X12, X1\n\tMOVOU X1, (DI)\n\tLEAQ  16(SI), SI\n\tLEAQ  16(DI), DI\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\n\t// Shift the stream \"left\"\n\tMOVO X4, X1\n\tMOVO X7, X4\n\tMOVO X10, X7\n\tMOVO X2, X10\n\tMOVO X5, X2\n\tMOVO X8, X5\n\tMOVO X11, X8\n\tJMP  openSSE128Open\n\nopenSSETail16:\n\tTESTQ BX, BX\n\tJE    openSSEFinalize\n\n\t// We can safely load the CT from the end, because it is padded with the MAC\n\tMOVQ  BX, R9\n\tSHLQ  $0x04, R9\n\tLEAQ  ·andMask<>+0(SB), R13\n\tMOVOU (SI), X12\n\tADDQ  BX, SI\n\tPAND  -16(R13)(R9*1), X12\n\tMOVO  X12, 64(BP)\n\tMOVQ  X12, R13\n\tMOVQ  72(BP), R14\n\tPXOR  X1, X12\n\n\t// We can only store one byte at a time, since plaintext can be shorter than 16 bytes\nopenSSETail16Store:\n\tMOVQ   X12, R8\n\tMOVB   R8, (DI)\n\tPSRLDQ $0x01, X12\n\tINCQ   DI\n\tDECQ   BX\n\tJNE    openSSETail16Store\n\tADDQ   R13, R10\n\tADCQ   R14, R11\n\tADCQ   $0x01, R12\n\tMOVQ   (BP), AX\n\tMOVQ   AX, R15\n\tMULQ   R10\n\tMOVQ   AX, R13\n\tMOVQ   DX, R14\n\tMOVQ   (BP), AX\n\tMULQ   R11\n\tIMULQ  R12, R15\n\tADDQ   AX, R14\n\tADCQ   DX, R15\n\tMOVQ   8(BP), AX\n\tMOVQ   AX, R8\n\tMULQ   R10\n\tADDQ   AX, R14\n\tADCQ   $0x00, DX\n\tMOVQ   DX, R10\n\tMOVQ   8(BP), AX\n\tMULQ   R11\n\tADDQ   AX, R15\n\tADCQ   $0x00, DX\n\tIMULQ  R12, R8\n\tADDQ   R10, R15\n\tADCQ   DX, R8\n\tMOVQ   R13, R10\n\tMOVQ   R14, R11\n\tMOVQ   R15, R12\n\tANDQ   $0x03, R12\n\tMOVQ   R15, R13\n\tANDQ   $-4, R13\n\tMOVQ   R8, R14\n\tSHRQ   $0x02, R8, R15\n\tSHRQ   $0x02, R8\n\tADDQ   R13, R10\n\tADCQ   R14, R11\n\tADCQ   $0x00, R12\n\tADDQ   R15, R10\n\tADCQ   R8, R11\n\tADCQ   $0x00, R12\n\tJMP    openSSEFinalize\n\nopenSSETail64:\n\tMOVO  ·chacha20Constants<>+0(SB), X0\n\tMOVO  32(BP), X3\n\tMOVO  48(BP), X6\n\tMOVO  128(BP), X9\n\tPADDL ·sseIncMask<>+0(SB), X9\n\tMOVO  X9, 80(BP)\n\tXORQ  R9, R9\n\tMOVQ  BX, CX\n\tCMPQ  CX, $0x10\n\tJB    openSSETail64LoopB\n\nopenSSETail64LoopA:\n\tADDQ  (SI)(R9*1), R10\n\tADCQ  8(SI)(R9*1), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tSUBQ  $0x10, CX\n\nopenSSETail64LoopB:\n\tADDQ  $0x10, R9\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X3\n\tPXOR  X12, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X3\n\tPXOR  X12, X3\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x0c\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X3\n\tPXOR  X12, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X3\n\tPXOR  X12, X3\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x04\n\tCMPQ  CX, $0x10\n\tJAE   openSSETail64LoopA\n\tCMPQ  R9, $0xa0\n\tJNE   openSSETail64LoopB\n\tPADDL ·chacha20Constants<>+0(SB), X0\n\tPADDL 32(BP), X3\n\tPADDL 48(BP), X6\n\tPADDL 80(BP), X9\n\nopenSSETail64DecLoop:\n\tCMPQ  BX, $0x10\n\tJB    openSSETail64DecLoopDone\n\tSUBQ  $0x10, BX\n\tMOVOU (SI), X12\n\tPXOR  X12, X0\n\tMOVOU X0, (DI)\n\tLEAQ  16(SI), SI\n\tLEAQ  16(DI), DI\n\tMOVO  X3, X0\n\tMOVO  X6, X3\n\tMOVO  X9, X6\n\tJMP   openSSETail64DecLoop\n\nopenSSETail64DecLoopDone:\n\tMOVO X0, X1\n\tJMP  openSSETail16\n\nopenSSETail128:\n\tMOVO  ·chacha20Constants<>+0(SB), X1\n\tMOVO  32(BP), X4\n\tMOVO  48(BP), X7\n\tMOVO  128(BP), X10\n\tPADDL ·sseIncMask<>+0(SB), X10\n\tMOVO  X10, 80(BP)\n\tMOVO  X1, X0\n\tMOVO  X4, X3\n\tMOVO  X7, X6\n\tMOVO  X10, X9\n\tPADDL ·sseIncMask<>+0(SB), X9\n\tMOVO  X9, 96(BP)\n\tXORQ  R9, R9\n\tMOVQ  BX, CX\n\tANDQ  $-16, CX\n\nopenSSETail128LoopA:\n\tADDQ  (SI)(R9*1), R10\n\tADCQ  8(SI)(R9*1), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\nopenSSETail128LoopB:\n\tADDQ  $0x10, R9\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X3\n\tPXOR  X12, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X3\n\tPXOR  X12, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X4\n\tPXOR  X12, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X4\n\tPXOR  X12, X4\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x0c\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X3\n\tPXOR  X12, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X3\n\tPXOR  X12, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X4\n\tPXOR  X12, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X4\n\tPXOR  X12, X4\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x04\n\tCMPQ  R9, CX\n\tJB    openSSETail128LoopA\n\tCMPQ  R9, $0xa0\n\tJNE   openSSETail128LoopB\n\tPADDL ·chacha20Constants<>+0(SB), X0\n\tPADDL ·chacha20Constants<>+0(SB), X1\n\tPADDL 32(BP), X3\n\tPADDL 32(BP), X4\n\tPADDL 48(BP), X6\n\tPADDL 48(BP), X7\n\tPADDL 96(BP), X9\n\tPADDL 80(BP), X10\n\tMOVOU (SI), X12\n\tMOVOU 16(SI), X13\n\tMOVOU 32(SI), X14\n\tMOVOU 48(SI), X15\n\tPXOR  X12, X1\n\tPXOR  X13, X4\n\tPXOR  X14, X7\n\tPXOR  X15, X10\n\tMOVOU X1, (DI)\n\tMOVOU X4, 16(DI)\n\tMOVOU X7, 32(DI)\n\tMOVOU X10, 48(DI)\n\tSUBQ  $0x40, BX\n\tLEAQ  64(SI), SI\n\tLEAQ  64(DI), DI\n\tJMP   openSSETail64DecLoop\n\nopenSSETail192:\n\tMOVO    ·chacha20Constants<>+0(SB), X2\n\tMOVO    32(BP), X5\n\tMOVO    48(BP), X8\n\tMOVO    128(BP), X11\n\tPADDL   ·sseIncMask<>+0(SB), X11\n\tMOVO    X11, 80(BP)\n\tMOVO    X2, X1\n\tMOVO    X5, X4\n\tMOVO    X8, X7\n\tMOVO    X11, X10\n\tPADDL   ·sseIncMask<>+0(SB), X10\n\tMOVO    X10, 96(BP)\n\tMOVO    X1, X0\n\tMOVO    X4, X3\n\tMOVO    X7, X6\n\tMOVO    X10, X9\n\tPADDL   ·sseIncMask<>+0(SB), X9\n\tMOVO    X9, 112(BP)\n\tMOVQ    BX, CX\n\tMOVQ    $0x000000a0, R9\n\tCMPQ    CX, $0xa0\n\tCMOVQGT R9, CX\n\tANDQ    $-16, CX\n\tXORQ    R9, R9\n\nopenSSLTail192LoopA:\n\tADDQ  (SI)(R9*1), R10\n\tADCQ  8(SI)(R9*1), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\nopenSSLTail192LoopB:\n\tADDQ  $0x10, R9\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X3\n\tPXOR  X12, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X3\n\tPXOR  X12, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X4\n\tPXOR  X12, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X4\n\tPXOR  X12, X4\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL16(X11, X12)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X5\n\tPXOR  X12, X5\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL8(X11, X12)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X5\n\tPXOR  X12, X5\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc0\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X3\n\tPXOR  X12, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X3\n\tPXOR  X12, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X4\n\tPXOR  X12, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X4\n\tPXOR  X12, X4\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL16(X11, X12)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X5\n\tPXOR  X12, X5\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL8(X11, X12)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X5\n\tPXOR  X12, X5\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc0\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tCMPQ  R9, CX\n\tJB    openSSLTail192LoopA\n\tCMPQ  R9, $0xa0\n\tJNE   openSSLTail192LoopB\n\tCMPQ  BX, $0xb0\n\tJB    openSSLTail192Store\n\tADDQ  160(SI), R10\n\tADCQ  168(SI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tCMPQ  BX, $0xc0\n\tJB    openSSLTail192Store\n\tADDQ  176(SI), R10\n\tADCQ  184(SI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\nopenSSLTail192Store:\n\tPADDL ·chacha20Constants<>+0(SB), X0\n\tPADDL ·chacha20Constants<>+0(SB), X1\n\tPADDL ·chacha20Constants<>+0(SB), X2\n\tPADDL 32(BP), X3\n\tPADDL 32(BP), X4\n\tPADDL 32(BP), X5\n\tPADDL 48(BP), X6\n\tPADDL 48(BP), X7\n\tPADDL 48(BP), X8\n\tPADDL 112(BP), X9\n\tPADDL 96(BP), X10\n\tPADDL 80(BP), X11\n\tMOVOU (SI), X12\n\tMOVOU 16(SI), X13\n\tMOVOU 32(SI), X14\n\tMOVOU 48(SI), X15\n\tPXOR  X12, X2\n\tPXOR  X13, X5\n\tPXOR  X14, X8\n\tPXOR  X15, X11\n\tMOVOU X2, (DI)\n\tMOVOU X5, 16(DI)\n\tMOVOU X8, 32(DI)\n\tMOVOU X11, 48(DI)\n\tMOVOU 64(SI), X12\n\tMOVOU 80(SI), X13\n\tMOVOU 96(SI), X14\n\tMOVOU 112(SI), X15\n\tPXOR  X12, X1\n\tPXOR  X13, X4\n\tPXOR  X14, X7\n\tPXOR  X15, X10\n\tMOVOU X1, 64(DI)\n\tMOVOU X4, 80(DI)\n\tMOVOU X7, 96(DI)\n\tMOVOU X10, 112(DI)\n\tSUBQ  $0x80, BX\n\tLEAQ  128(SI), SI\n\tLEAQ  128(DI), DI\n\tJMP   openSSETail64DecLoop\n\nopenSSETail256:\n\tMOVO  ·chacha20Constants<>+0(SB), X0\n\tMOVO  32(BP), X3\n\tMOVO  48(BP), X6\n\tMOVO  128(BP), X9\n\tPADDL ·sseIncMask<>+0(SB), X9\n\tMOVO  X0, X1\n\tMOVO  X3, X4\n\tMOVO  X6, X7\n\tMOVO  X9, X10\n\tPADDL ·sseIncMask<>+0(SB), X10\n\tMOVO  X1, X2\n\tMOVO  X4, X5\n\tMOVO  X7, X8\n\tMOVO  X10, X11\n\tPADDL ·sseIncMask<>+0(SB), X11\n\tMOVO  X2, X12\n\tMOVO  X5, X13\n\tMOVO  X8, X14\n\tMOVO  X11, X15\n\tPADDL ·sseIncMask<>+0(SB), X15\n\n\t// Store counters\n\tMOVO X9, 80(BP)\n\tMOVO X10, 96(BP)\n\tMOVO X11, 112(BP)\n\tMOVO X15, 128(BP)\n\tXORQ R9, R9\n\nopenSSETail256Loop:\n\tADDQ  (SI)(R9*1), R10\n\tADCQ  8(SI)(R9*1), R11\n\tADCQ  $0x01, R12\n\tMOVO  X14, 64(BP)\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X14)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X3\n\tPXOR  X14, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X14)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X3\n\tPXOR  X14, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X14)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X4\n\tPXOR  X14, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X14)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X4\n\tPXOR  X14, X4\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL16(X11, X14)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X5\n\tPXOR  X14, X5\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL8(X11, X14)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X5\n\tPXOR  X14, X5\n\tMOVO  64(BP), X14\n\tMOVO  X7, 64(BP)\n\tPADDD X13, X12\n\tPXOR  X12, X15\n\tROL16(X15, X7)\n\tPADDD X15, X14\n\tPXOR  X14, X13\n\tMOVO  X13, X7\n\tPSLLL $0x0c, X7\n\tPSRLL $0x14, X13\n\tPXOR  X7, X13\n\tPADDD X13, X12\n\tPXOR  X12, X15\n\tROL8(X15, X7)\n\tPADDD X15, X14\n\tPXOR  X14, X13\n\tMOVO  X13, X7\n\tPSLLL $0x07, X7\n\tPSRLL $0x19, X13\n\tPXOR  X7, X13\n\tMOVO  64(BP), X7\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc0\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x0c\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tMOVO  X14, 64(BP)\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X14)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X3\n\tPXOR  X14, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X14)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X3\n\tPXOR  X14, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X14)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X4\n\tPXOR  X14, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X14)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X4\n\tPXOR  X14, X4\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL16(X11, X14)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X5\n\tPXOR  X14, X5\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL8(X11, X14)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X5\n\tPXOR  X14, X5\n\tMOVO  64(BP), X14\n\tMOVO  X7, 64(BP)\n\tPADDD X13, X12\n\tPXOR  X12, X15\n\tROL16(X15, X7)\n\tPADDD X15, X14\n\tPXOR  X14, X13\n\tMOVO  X13, X7\n\tPSLLL $0x0c, X7\n\tPSRLL $0x14, X13\n\tPXOR  X7, X13\n\tPADDD X13, X12\n\tPXOR  X12, X15\n\tROL8(X15, X7)\n\tPADDD X15, X14\n\tPXOR  X14, X13\n\tMOVO  X13, X7\n\tPSLLL $0x07, X7\n\tPSRLL $0x19, X13\n\tPXOR  X7, X13\n\tMOVO  64(BP), X7\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc0\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x04\n\tADDQ  $0x10, R9\n\tCMPQ  R9, $0xa0\n\tJB    openSSETail256Loop\n\tMOVQ  BX, CX\n\tANDQ  $-16, CX\n\nopenSSETail256HashLoop:\n\tADDQ  (SI)(R9*1), R10\n\tADCQ  8(SI)(R9*1), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tADDQ  $0x10, R9\n\tCMPQ  R9, CX\n\tJB    openSSETail256HashLoop\n\n\t// Add in the state\n\tPADDD ·chacha20Constants<>+0(SB), X0\n\tPADDD ·chacha20Constants<>+0(SB), X1\n\tPADDD ·chacha20Constants<>+0(SB), X2\n\tPADDD ·chacha20Constants<>+0(SB), X12\n\tPADDD 32(BP), X3\n\tPADDD 32(BP), X4\n\tPADDD 32(BP), X5\n\tPADDD 32(BP), X13\n\tPADDD 48(BP), X6\n\tPADDD 48(BP), X7\n\tPADDD 48(BP), X8\n\tPADDD 48(BP), X14\n\tPADDD 80(BP), X9\n\tPADDD 96(BP), X10\n\tPADDD 112(BP), X11\n\tPADDD 128(BP), X15\n\tMOVO  X15, 64(BP)\n\n\t// Load - xor - store\n\tMOVOU (SI), X15\n\tPXOR  X15, X0\n\tMOVOU 16(SI), X15\n\tPXOR  X15, X3\n\tMOVOU 32(SI), X15\n\tPXOR  X15, X6\n\tMOVOU 48(SI), X15\n\tPXOR  X15, X9\n\tMOVOU X0, (DI)\n\tMOVOU X3, 16(DI)\n\tMOVOU X6, 32(DI)\n\tMOVOU X9, 48(DI)\n\tMOVOU 64(SI), X0\n\tMOVOU 80(SI), X3\n\tMOVOU 96(SI), X6\n\tMOVOU 112(SI), X9\n\tPXOR  X0, X1\n\tPXOR  X3, X4\n\tPXOR  X6, X7\n\tPXOR  X9, X10\n\tMOVOU X1, 64(DI)\n\tMOVOU X4, 80(DI)\n\tMOVOU X7, 96(DI)\n\tMOVOU X10, 112(DI)\n\tMOVOU 128(SI), X0\n\tMOVOU 144(SI), X3\n\tMOVOU 160(SI), X6\n\tMOVOU 176(SI), X9\n\tPXOR  X0, X2\n\tPXOR  X3, X5\n\tPXOR  X6, X8\n\tPXOR  X9, X11\n\tMOVOU X2, 128(DI)\n\tMOVOU X5, 144(DI)\n\tMOVOU X8, 160(DI)\n\tMOVOU X11, 176(DI)\n\tLEAQ  192(SI), SI\n\tLEAQ  192(DI), DI\n\tSUBQ  $0xc0, BX\n\tMOVO  X12, X0\n\tMOVO  X13, X3\n\tMOVO  X14, X6\n\tMOVO  64(BP), X9\n\tJMP   openSSETail64DecLoop\n\nchacha20Poly1305Open_AVX2:\n\tVZEROUPPER\n\tVMOVDQU ·chacha20Constants<>+0(SB), Y0\n\tBYTE    $0xc4\n\tBYTE    $0x42\n\tBYTE    $0x7d\n\tBYTE    $0x5a\n\tBYTE    $0x70\n\tBYTE    $0x10\n\tBYTE    $0xc4\n\tBYTE    $0x42\n\tBYTE    $0x7d\n\tBYTE    $0x5a\n\tBYTE    $0x60\n\tBYTE    $0x20\n\tBYTE    $0xc4\n\tBYTE    $0xc2\n\tBYTE    $0x7d\n\tBYTE    $0x5a\n\tBYTE    $0x60\n\tBYTE    $0x30\n\tVPADDD  ·avx2InitMask<>+0(SB), Y4, Y4\n\n\t// Special optimization, for very short buffers\n\tCMPQ BX, $0xc0\n\tJBE  openAVX2192\n\tCMPQ BX, $0x00000140\n\tJBE  openAVX2320\n\n\t// For the general key prepare the key first - as a byproduct we have 64 bytes of cipher stream\n\tVMOVDQA Y14, 32(BP)\n\tVMOVDQA Y12, 64(BP)\n\tVMOVDQA Y4, 192(BP)\n\tMOVQ    $0x0000000a, R9\n\nopenAVX2PreparePolyKey:\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol16<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x0c, Y14, Y3\n\tVPSRLD     $0x14, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol8<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x07, Y14, Y3\n\tVPSRLD     $0x19, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPALIGNR   $0x04, Y14, Y14, Y14\n\tVPALIGNR   $0x08, Y12, Y12, Y12\n\tVPALIGNR   $0x0c, Y4, Y4, Y4\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol16<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x0c, Y14, Y3\n\tVPSRLD     $0x14, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol8<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x07, Y14, Y3\n\tVPSRLD     $0x19, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPALIGNR   $0x0c, Y14, Y14, Y14\n\tVPALIGNR   $0x08, Y12, Y12, Y12\n\tVPALIGNR   $0x04, Y4, Y4, Y4\n\tDECQ       R9\n\tJNE        openAVX2PreparePolyKey\n\tVPADDD     ·chacha20Constants<>+0(SB), Y0, Y0\n\tVPADDD     32(BP), Y14, Y14\n\tVPADDD     64(BP), Y12, Y12\n\tVPADDD     192(BP), Y4, Y4\n\tVPERM2I128 $0x02, Y0, Y14, Y3\n\n\t// Clamp and store poly key\n\tVPAND   ·polyClampMask<>+0(SB), Y3, Y3\n\tVMOVDQA Y3, (BP)\n\n\t// Stream for the first 64 bytes\n\tVPERM2I128 $0x13, Y0, Y14, Y0\n\tVPERM2I128 $0x13, Y12, Y4, Y14\n\n\t// Hash AD + first 64 bytes\n\tMOVQ ad_len+80(FP), R9\n\tCALL polyHashADInternal<>(SB)\n\tXORQ CX, CX\n\nopenAVX2InitialHash64:\n\tADDQ  (SI)(CX*1), R10\n\tADCQ  8(SI)(CX*1), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), DX\n\tMOVQ  DX, R15\n\tMULXQ R10, R13, R14\n\tIMULQ R12, R15\n\tMULXQ R11, AX, DX\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), DX\n\tMULXQ R10, R10, AX\n\tADDQ  R10, R14\n\tMULXQ R11, R11, R8\n\tADCQ  R11, R15\n\tADCQ  $0x00, R8\n\tIMULQ R12, DX\n\tADDQ  AX, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tADDQ  $0x10, CX\n\tCMPQ  CX, $0x40\n\tJNE   openAVX2InitialHash64\n\n\t// Decrypt the first 64 bytes\n\tVPXOR   (SI), Y0, Y0\n\tVPXOR   32(SI), Y14, Y14\n\tVMOVDQU Y0, (DI)\n\tVMOVDQU Y14, 32(DI)\n\tLEAQ    64(SI), SI\n\tLEAQ    64(DI), DI\n\tSUBQ    $0x40, BX\n\nopenAVX2MainLoop:\n\tCMPQ BX, $0x00000200\n\tJB   openAVX2MainLoopDone\n\n\t// Load state, increment counter blocks, store the incremented counters\n\tVMOVDQU ·chacha20Constants<>+0(SB), Y0\n\tVMOVDQA Y0, Y5\n\tVMOVDQA Y0, Y6\n\tVMOVDQA Y0, Y7\n\tVMOVDQA 32(BP), Y14\n\tVMOVDQA Y14, Y9\n\tVMOVDQA Y14, Y10\n\tVMOVDQA Y14, Y11\n\tVMOVDQA 64(BP), Y12\n\tVMOVDQA Y12, Y13\n\tVMOVDQA Y12, Y8\n\tVMOVDQA Y12, Y15\n\tVMOVDQA 192(BP), Y4\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y4\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y1\n\tVPADDD  ·avx2IncMask<>+0(SB), Y1, Y2\n\tVPADDD  ·avx2IncMask<>+0(SB), Y2, Y3\n\tVMOVDQA Y4, 96(BP)\n\tVMOVDQA Y1, 128(BP)\n\tVMOVDQA Y2, 160(BP)\n\tVMOVDQA Y3, 192(BP)\n\tXORQ    CX, CX\n\nopenAVX2InternalLoop:\n\tADDQ     (SI)(CX*1), R10\n\tADCQ     8(SI)(CX*1), R11\n\tADCQ     $0x01, R12\n\tVPADDD   Y14, Y0, Y0\n\tVPADDD   Y9, Y5, Y5\n\tVPADDD   Y10, Y6, Y6\n\tVPADDD   Y11, Y7, Y7\n\tMOVQ     (BP), DX\n\tMOVQ     DX, R15\n\tMULXQ    R10, R13, R14\n\tIMULQ    R12, R15\n\tMULXQ    R11, AX, DX\n\tADDQ     AX, R14\n\tADCQ     DX, R15\n\tVPXOR    Y0, Y4, Y4\n\tVPXOR    Y5, Y1, Y1\n\tVPXOR    Y6, Y2, Y2\n\tVPXOR    Y7, Y3, Y3\n\tVPSHUFB  ·rol16<>+0(SB), Y4, Y4\n\tVPSHUFB  ·rol16<>+0(SB), Y1, Y1\n\tVPSHUFB  ·rol16<>+0(SB), Y2, Y2\n\tVPSHUFB  ·rol16<>+0(SB), Y3, Y3\n\tMOVQ     8(BP), DX\n\tMULXQ    R10, R10, AX\n\tADDQ     R10, R14\n\tMULXQ    R11, R11, R8\n\tADCQ     R11, R15\n\tADCQ     $0x00, R8\n\tVPADDD   Y4, Y12, Y12\n\tVPADDD   Y1, Y13, Y13\n\tVPADDD   Y2, Y8, Y8\n\tVPADDD   Y3, Y15, Y15\n\tVPXOR    Y12, Y14, Y14\n\tVPXOR    Y13, Y9, Y9\n\tVPXOR    Y8, Y10, Y10\n\tVPXOR    Y15, Y11, Y11\n\tIMULQ    R12, DX\n\tADDQ     AX, R15\n\tADCQ     DX, R8\n\tVMOVDQA  Y15, 224(BP)\n\tVPSLLD   $0x0c, Y14, Y15\n\tVPSRLD   $0x14, Y14, Y14\n\tVPXOR    Y15, Y14, Y14\n\tVPSLLD   $0x0c, Y9, Y15\n\tVPSRLD   $0x14, Y9, Y9\n\tVPXOR    Y15, Y9, Y9\n\tVPSLLD   $0x0c, Y10, Y15\n\tVPSRLD   $0x14, Y10, Y10\n\tVPXOR    Y15, Y10, Y10\n\tVPSLLD   $0x0c, Y11, Y15\n\tVPSRLD   $0x14, Y11, Y11\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  224(BP), Y15\n\tMOVQ     R13, R10\n\tMOVQ     R14, R11\n\tMOVQ     R15, R12\n\tANDQ     $0x03, R12\n\tMOVQ     R15, R13\n\tANDQ     $-4, R13\n\tMOVQ     R8, R14\n\tSHRQ     $0x02, R8, R15\n\tSHRQ     $0x02, R8\n\tADDQ     R13, R10\n\tADCQ     R14, R11\n\tADCQ     $0x00, R12\n\tADDQ     R15, R10\n\tADCQ     R8, R11\n\tADCQ     $0x00, R12\n\tVPADDD   Y14, Y0, Y0\n\tVPADDD   Y9, Y5, Y5\n\tVPADDD   Y10, Y6, Y6\n\tVPADDD   Y11, Y7, Y7\n\tVPXOR    Y0, Y4, Y4\n\tVPXOR    Y5, Y1, Y1\n\tVPXOR    Y6, Y2, Y2\n\tVPXOR    Y7, Y3, Y3\n\tVPSHUFB  ·rol8<>+0(SB), Y4, Y4\n\tVPSHUFB  ·rol8<>+0(SB), Y1, Y1\n\tVPSHUFB  ·rol8<>+0(SB), Y2, Y2\n\tVPSHUFB  ·rol8<>+0(SB), Y3, Y3\n\tADDQ     16(SI)(CX*1), R10\n\tADCQ     24(SI)(CX*1), R11\n\tADCQ     $0x01, R12\n\tVPADDD   Y4, Y12, Y12\n\tVPADDD   Y1, Y13, Y13\n\tVPADDD   Y2, Y8, Y8\n\tVPADDD   Y3, Y15, Y15\n\tMOVQ     (BP), DX\n\tMOVQ     DX, R15\n\tMULXQ    R10, R13, R14\n\tIMULQ    R12, R15\n\tMULXQ    R11, AX, DX\n\tADDQ     AX, R14\n\tADCQ     DX, R15\n\tVPXOR    Y12, Y14, Y14\n\tVPXOR    Y13, Y9, Y9\n\tVPXOR    Y8, Y10, Y10\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  Y15, 224(BP)\n\tVPSLLD   $0x07, Y14, Y15\n\tVPSRLD   $0x19, Y14, Y14\n\tVPXOR    Y15, Y14, Y14\n\tVPSLLD   $0x07, Y9, Y15\n\tVPSRLD   $0x19, Y9, Y9\n\tVPXOR    Y15, Y9, Y9\n\tVPSLLD   $0x07, Y10, Y15\n\tVPSRLD   $0x19, Y10, Y10\n\tVPXOR    Y15, Y10, Y10\n\tVPSLLD   $0x07, Y11, Y15\n\tVPSRLD   $0x19, Y11, Y11\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  224(BP), Y15\n\tMOVQ     8(BP), DX\n\tMULXQ    R10, R10, AX\n\tADDQ     R10, R14\n\tMULXQ    R11, R11, R8\n\tADCQ     R11, R15\n\tADCQ     $0x00, R8\n\tVPALIGNR $0x04, Y14, Y14, Y14\n\tVPALIGNR $0x04, Y9, Y9, Y9\n\tVPALIGNR $0x04, Y10, Y10, Y10\n\tVPALIGNR $0x04, Y11, Y11, Y11\n\tVPALIGNR $0x08, Y12, Y12, Y12\n\tVPALIGNR $0x08, Y13, Y13, Y13\n\tVPALIGNR $0x08, Y8, Y8, Y8\n\tVPALIGNR $0x08, Y15, Y15, Y15\n\tVPALIGNR $0x0c, Y4, Y4, Y4\n\tVPALIGNR $0x0c, Y1, Y1, Y1\n\tVPALIGNR $0x0c, Y2, Y2, Y2\n\tVPALIGNR $0x0c, Y3, Y3, Y3\n\tVPADDD   Y14, Y0, Y0\n\tVPADDD   Y9, Y5, Y5\n\tVPADDD   Y10, Y6, Y6\n\tVPADDD   Y11, Y7, Y7\n\tIMULQ    R12, DX\n\tADDQ     AX, R15\n\tADCQ     DX, R8\n\tVPXOR    Y0, Y4, Y4\n\tVPXOR    Y5, Y1, Y1\n\tVPXOR    Y6, Y2, Y2\n\tVPXOR    Y7, Y3, Y3\n\tVPSHUFB  ·rol16<>+0(SB), Y4, Y4\n\tVPSHUFB  ·rol16<>+0(SB), Y1, Y1\n\tVPSHUFB  ·rol16<>+0(SB), Y2, Y2\n\tVPSHUFB  ·rol16<>+0(SB), Y3, Y3\n\tMOVQ     R13, R10\n\tMOVQ     R14, R11\n\tMOVQ     R15, R12\n\tANDQ     $0x03, R12\n\tMOVQ     R15, R13\n\tANDQ     $-4, R13\n\tMOVQ     R8, R14\n\tSHRQ     $0x02, R8, R15\n\tSHRQ     $0x02, R8\n\tADDQ     R13, R10\n\tADCQ     R14, R11\n\tADCQ     $0x00, R12\n\tADDQ     R15, R10\n\tADCQ     R8, R11\n\tADCQ     $0x00, R12\n\tVPADDD   Y4, Y12, Y12\n\tVPADDD   Y1, Y13, Y13\n\tVPADDD   Y2, Y8, Y8\n\tVPADDD   Y3, Y15, Y15\n\tVPXOR    Y12, Y14, Y14\n\tVPXOR    Y13, Y9, Y9\n\tVPXOR    Y8, Y10, Y10\n\tVPXOR    Y15, Y11, Y11\n\tADDQ     32(SI)(CX*1), R10\n\tADCQ     40(SI)(CX*1), R11\n\tADCQ     $0x01, R12\n\tLEAQ     48(CX), CX\n\tVMOVDQA  Y15, 224(BP)\n\tVPSLLD   $0x0c, Y14, Y15\n\tVPSRLD   $0x14, Y14, Y14\n\tVPXOR    Y15, Y14, Y14\n\tVPSLLD   $0x0c, Y9, Y15\n\tVPSRLD   $0x14, Y9, Y9\n\tVPXOR    Y15, Y9, Y9\n\tVPSLLD   $0x0c, Y10, Y15\n\tVPSRLD   $0x14, Y10, Y10\n\tVPXOR    Y15, Y10, Y10\n\tVPSLLD   $0x0c, Y11, Y15\n\tVPSRLD   $0x14, Y11, Y11\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  224(BP), Y15\n\tMOVQ     (BP), DX\n\tMOVQ     DX, R15\n\tMULXQ    R10, R13, R14\n\tIMULQ    R12, R15\n\tMULXQ    R11, AX, DX\n\tADDQ     AX, R14\n\tADCQ     DX, R15\n\tVPADDD   Y14, Y0, Y0\n\tVPADDD   Y9, Y5, Y5\n\tVPADDD   Y10, Y6, Y6\n\tVPADDD   Y11, Y7, Y7\n\tVPXOR    Y0, Y4, Y4\n\tVPXOR    Y5, Y1, Y1\n\tVPXOR    Y6, Y2, Y2\n\tVPXOR    Y7, Y3, Y3\n\tMOVQ     8(BP), DX\n\tMULXQ    R10, R10, AX\n\tADDQ     R10, R14\n\tMULXQ    R11, R11, R8\n\tADCQ     R11, R15\n\tADCQ     $0x00, R8\n\tVPSHUFB  ·rol8<>+0(SB), Y4, Y4\n\tVPSHUFB  ·rol8<>+0(SB), Y1, Y1\n\tVPSHUFB  ·rol8<>+0(SB), Y2, Y2\n\tVPSHUFB  ·rol8<>+0(SB), Y3, Y3\n\tVPADDD   Y4, Y12, Y12\n\tVPADDD   Y1, Y13, Y13\n\tVPADDD   Y2, Y8, Y8\n\tVPADDD   Y3, Y15, Y15\n\tIMULQ    R12, DX\n\tADDQ     AX, R15\n\tADCQ     DX, R8\n\tVPXOR    Y12, Y14, Y14\n\tVPXOR    Y13, Y9, Y9\n\tVPXOR    Y8, Y10, Y10\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  Y15, 224(BP)\n\tVPSLLD   $0x07, Y14, Y15\n\tVPSRLD   $0x19, Y14, Y14\n\tVPXOR    Y15, Y14, Y14\n\tVPSLLD   $0x07, Y9, Y15\n\tVPSRLD   $0x19, Y9, Y9\n\tVPXOR    Y15, Y9, Y9\n\tVPSLLD   $0x07, Y10, Y15\n\tVPSRLD   $0x19, Y10, Y10\n\tVPXOR    Y15, Y10, Y10\n\tVPSLLD   $0x07, Y11, Y15\n\tVPSRLD   $0x19, Y11, Y11\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  224(BP), Y15\n\tMOVQ     R13, R10\n\tMOVQ     R14, R11\n\tMOVQ     R15, R12\n\tANDQ     $0x03, R12\n\tMOVQ     R15, R13\n\tANDQ     $-4, R13\n\tMOVQ     R8, R14\n\tSHRQ     $0x02, R8, R15\n\tSHRQ     $0x02, R8\n\tADDQ     R13, R10\n\tADCQ     R14, R11\n\tADCQ     $0x00, R12\n\tADDQ     R15, R10\n\tADCQ     R8, R11\n\tADCQ     $0x00, R12\n\tVPALIGNR $0x0c, Y14, Y14, Y14\n\tVPALIGNR $0x0c, Y9, Y9, Y9\n\tVPALIGNR $0x0c, Y10, Y10, Y10\n\tVPALIGNR $0x0c, Y11, Y11, Y11\n\tVPALIGNR $0x08, Y12, Y12, Y12\n\tVPALIGNR $0x08, Y13, Y13, Y13\n\tVPALIGNR $0x08, Y8, Y8, Y8\n\tVPALIGNR $0x08, Y15, Y15, Y15\n\tVPALIGNR $0x04, Y4, Y4, Y4\n\tVPALIGNR $0x04, Y1, Y1, Y1\n\tVPALIGNR $0x04, Y2, Y2, Y2\n\tVPALIGNR $0x04, Y3, Y3, Y3\n\tCMPQ     CX, $0x000001e0\n\tJNE      openAVX2InternalLoop\n\tVPADDD   ·chacha20Constants<>+0(SB), Y0, Y0\n\tVPADDD   ·chacha20Constants<>+0(SB), Y5, Y5\n\tVPADDD   ·chacha20Constants<>+0(SB), Y6, Y6\n\tVPADDD   ·chacha20Constants<>+0(SB), Y7, Y7\n\tVPADDD   32(BP), Y14, Y14\n\tVPADDD   32(BP), Y9, Y9\n\tVPADDD   32(BP), Y10, Y10\n\tVPADDD   32(BP), Y11, Y11\n\tVPADDD   64(BP), Y12, Y12\n\tVPADDD   64(BP), Y13, Y13\n\tVPADDD   64(BP), Y8, Y8\n\tVPADDD   64(BP), Y15, Y15\n\tVPADDD   96(BP), Y4, Y4\n\tVPADDD   128(BP), Y1, Y1\n\tVPADDD   160(BP), Y2, Y2\n\tVPADDD   192(BP), Y3, Y3\n\tVMOVDQA  Y15, 224(BP)\n\n\t// We only hashed 480 of the 512 bytes available - hash the remaining 32 here\n\tADDQ       480(SI), R10\n\tADCQ       488(SI), R11\n\tADCQ       $0x01, R12\n\tMOVQ       (BP), DX\n\tMOVQ       DX, R15\n\tMULXQ      R10, R13, R14\n\tIMULQ      R12, R15\n\tMULXQ      R11, AX, DX\n\tADDQ       AX, R14\n\tADCQ       DX, R15\n\tMOVQ       8(BP), DX\n\tMULXQ      R10, R10, AX\n\tADDQ       R10, R14\n\tMULXQ      R11, R11, R8\n\tADCQ       R11, R15\n\tADCQ       $0x00, R8\n\tIMULQ      R12, DX\n\tADDQ       AX, R15\n\tADCQ       DX, R8\n\tMOVQ       R13, R10\n\tMOVQ       R14, R11\n\tMOVQ       R15, R12\n\tANDQ       $0x03, R12\n\tMOVQ       R15, R13\n\tANDQ       $-4, R13\n\tMOVQ       R8, R14\n\tSHRQ       $0x02, R8, R15\n\tSHRQ       $0x02, R8\n\tADDQ       R13, R10\n\tADCQ       R14, R11\n\tADCQ       $0x00, R12\n\tADDQ       R15, R10\n\tADCQ       R8, R11\n\tADCQ       $0x00, R12\n\tVPERM2I128 $0x02, Y0, Y14, Y15\n\tVPERM2I128 $0x13, Y0, Y14, Y14\n\tVPERM2I128 $0x02, Y12, Y4, Y0\n\tVPERM2I128 $0x13, Y12, Y4, Y12\n\tVPXOR      (SI), Y15, Y15\n\tVPXOR      32(SI), Y0, Y0\n\tVPXOR      64(SI), Y14, Y14\n\tVPXOR      96(SI), Y12, Y12\n\tVMOVDQU    Y15, (DI)\n\tVMOVDQU    Y0, 32(DI)\n\tVMOVDQU    Y14, 64(DI)\n\tVMOVDQU    Y12, 96(DI)\n\tVPERM2I128 $0x02, Y5, Y9, Y0\n\tVPERM2I128 $0x02, Y13, Y1, Y14\n\tVPERM2I128 $0x13, Y5, Y9, Y12\n\tVPERM2I128 $0x13, Y13, Y1, Y4\n\tVPXOR      128(SI), Y0, Y0\n\tVPXOR      160(SI), Y14, Y14\n\tVPXOR      192(SI), Y12, Y12\n\tVPXOR      224(SI), Y4, Y4\n\tVMOVDQU    Y0, 128(DI)\n\tVMOVDQU    Y14, 160(DI)\n\tVMOVDQU    Y12, 192(DI)\n\tVMOVDQU    Y4, 224(DI)\n\n\t// and here\n\tADDQ       496(SI), R10\n\tADCQ       504(SI), R11\n\tADCQ       $0x01, R12\n\tMOVQ       (BP), DX\n\tMOVQ       DX, R15\n\tMULXQ      R10, R13, R14\n\tIMULQ      R12, R15\n\tMULXQ      R11, AX, DX\n\tADDQ       AX, R14\n\tADCQ       DX, R15\n\tMOVQ       8(BP), DX\n\tMULXQ      R10, R10, AX\n\tADDQ       R10, R14\n\tMULXQ      R11, R11, R8\n\tADCQ       R11, R15\n\tADCQ       $0x00, R8\n\tIMULQ      R12, DX\n\tADDQ       AX, R15\n\tADCQ       DX, R8\n\tMOVQ       R13, R10\n\tMOVQ       R14, R11\n\tMOVQ       R15, R12\n\tANDQ       $0x03, R12\n\tMOVQ       R15, R13\n\tANDQ       $-4, R13\n\tMOVQ       R8, R14\n\tSHRQ       $0x02, R8, R15\n\tSHRQ       $0x02, R8\n\tADDQ       R13, R10\n\tADCQ       R14, R11\n\tADCQ       $0x00, R12\n\tADDQ       R15, R10\n\tADCQ       R8, R11\n\tADCQ       $0x00, R12\n\tVPERM2I128 $0x02, Y6, Y10, Y0\n\tVPERM2I128 $0x02, Y8, Y2, Y14\n\tVPERM2I128 $0x13, Y6, Y10, Y12\n\tVPERM2I128 $0x13, Y8, Y2, Y4\n\tVPXOR      256(SI), Y0, Y0\n\tVPXOR      288(SI), Y14, Y14\n\tVPXOR      320(SI), Y12, Y12\n\tVPXOR      352(SI), Y4, Y4\n\tVMOVDQU    Y0, 256(DI)\n\tVMOVDQU    Y14, 288(DI)\n\tVMOVDQU    Y12, 320(DI)\n\tVMOVDQU    Y4, 352(DI)\n\tVPERM2I128 $0x02, Y7, Y11, Y0\n\tVPERM2I128 $0x02, 224(BP), Y3, Y14\n\tVPERM2I128 $0x13, Y7, Y11, Y12\n\tVPERM2I128 $0x13, 224(BP), Y3, Y4\n\tVPXOR      384(SI), Y0, Y0\n\tVPXOR      416(SI), Y14, Y14\n\tVPXOR      448(SI), Y12, Y12\n\tVPXOR      480(SI), Y4, Y4\n\tVMOVDQU    Y0, 384(DI)\n\tVMOVDQU    Y14, 416(DI)\n\tVMOVDQU    Y12, 448(DI)\n\tVMOVDQU    Y4, 480(DI)\n\tLEAQ       512(SI), SI\n\tLEAQ       512(DI), DI\n\tSUBQ       $0x00000200, BX\n\tJMP        openAVX2MainLoop\n\nopenAVX2MainLoopDone:\n\t// Handle the various tail sizes efficiently\n\tTESTQ BX, BX\n\tJE    openSSEFinalize\n\tCMPQ  BX, $0x80\n\tJBE   openAVX2Tail128\n\tCMPQ  BX, $0x00000100\n\tJBE   openAVX2Tail256\n\tCMPQ  BX, $0x00000180\n\tJBE   openAVX2Tail384\n\tJMP   openAVX2Tail512\n\nopenAVX2192:\n\tVMOVDQA Y0, Y5\n\tVMOVDQA Y14, Y9\n\tVMOVDQA Y12, Y13\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y1\n\tVMOVDQA Y0, Y6\n\tVMOVDQA Y14, Y10\n\tVMOVDQA Y12, Y8\n\tVMOVDQA Y4, Y2\n\tVMOVDQA Y1, Y15\n\tMOVQ    $0x0000000a, R9\n\nopenAVX2192InnerCipherLoop:\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol16<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x0c, Y14, Y3\n\tVPSRLD     $0x14, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol8<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x07, Y14, Y3\n\tVPSRLD     $0x19, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol16<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x0c, Y9, Y3\n\tVPSRLD     $0x14, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol8<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x07, Y9, Y3\n\tVPSRLD     $0x19, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPALIGNR   $0x04, Y14, Y14, Y14\n\tVPALIGNR   $0x04, Y9, Y9, Y9\n\tVPALIGNR   $0x08, Y12, Y12, Y12\n\tVPALIGNR   $0x08, Y13, Y13, Y13\n\tVPALIGNR   $0x0c, Y4, Y4, Y4\n\tVPALIGNR   $0x0c, Y1, Y1, Y1\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol16<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x0c, Y14, Y3\n\tVPSRLD     $0x14, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol8<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x07, Y14, Y3\n\tVPSRLD     $0x19, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol16<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x0c, Y9, Y3\n\tVPSRLD     $0x14, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol8<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x07, Y9, Y3\n\tVPSRLD     $0x19, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPALIGNR   $0x0c, Y14, Y14, Y14\n\tVPALIGNR   $0x0c, Y9, Y9, Y9\n\tVPALIGNR   $0x08, Y12, Y12, Y12\n\tVPALIGNR   $0x08, Y13, Y13, Y13\n\tVPALIGNR   $0x04, Y4, Y4, Y4\n\tVPALIGNR   $0x04, Y1, Y1, Y1\n\tDECQ       R9\n\tJNE        openAVX2192InnerCipherLoop\n\tVPADDD     Y6, Y0, Y0\n\tVPADDD     Y6, Y5, Y5\n\tVPADDD     Y10, Y14, Y14\n\tVPADDD     Y10, Y9, Y9\n\tVPADDD     Y8, Y12, Y12\n\tVPADDD     Y8, Y13, Y13\n\tVPADDD     Y2, Y4, Y4\n\tVPADDD     Y15, Y1, Y1\n\tVPERM2I128 $0x02, Y0, Y14, Y3\n\n\t// Clamp and store poly key\n\tVPAND   ·polyClampMask<>+0(SB), Y3, Y3\n\tVMOVDQA Y3, (BP)\n\n\t// Stream for up to 192 bytes\n\tVPERM2I128 $0x13, Y0, Y14, Y0\n\tVPERM2I128 $0x13, Y12, Y4, Y14\n\tVPERM2I128 $0x02, Y5, Y9, Y12\n\tVPERM2I128 $0x02, Y13, Y1, Y4\n\tVPERM2I128 $0x13, Y5, Y9, Y5\n\tVPERM2I128 $0x13, Y13, Y1, Y9\n\nopenAVX2ShortOpen:\n\t// Hash\n\tMOVQ ad_len+80(FP), R9\n\tCALL polyHashADInternal<>(SB)\n\nopenAVX2ShortOpenLoop:\n\tCMPQ BX, $0x20\n\tJB   openAVX2ShortTail32\n\tSUBQ $0x20, BX\n\n\t// Load for hashing\n\tADDQ  (SI), R10\n\tADCQ  8(SI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), DX\n\tMOVQ  DX, R15\n\tMULXQ R10, R13, R14\n\tIMULQ R12, R15\n\tMULXQ R11, AX, DX\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), DX\n\tMULXQ R10, R10, AX\n\tADDQ  R10, R14\n\tMULXQ R11, R11, R8\n\tADCQ  R11, R15\n\tADCQ  $0x00, R8\n\tIMULQ R12, DX\n\tADDQ  AX, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tADDQ  16(SI), R10\n\tADCQ  24(SI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), DX\n\tMOVQ  DX, R15\n\tMULXQ R10, R13, R14\n\tIMULQ R12, R15\n\tMULXQ R11, AX, DX\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), DX\n\tMULXQ R10, R10, AX\n\tADDQ  R10, R14\n\tMULXQ R11, R11, R8\n\tADCQ  R11, R15\n\tADCQ  $0x00, R8\n\tIMULQ R12, DX\n\tADDQ  AX, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\n\t// Load for decryption\n\tVPXOR   (SI), Y0, Y0\n\tVMOVDQU Y0, (DI)\n\tLEAQ    32(SI), SI\n\tLEAQ    32(DI), DI\n\n\t// Shift stream left\n\tVMOVDQA Y14, Y0\n\tVMOVDQA Y12, Y14\n\tVMOVDQA Y4, Y12\n\tVMOVDQA Y5, Y4\n\tVMOVDQA Y9, Y5\n\tVMOVDQA Y13, Y9\n\tVMOVDQA Y1, Y13\n\tVMOVDQA Y6, Y1\n\tVMOVDQA Y10, Y6\n\tJMP     openAVX2ShortOpenLoop\n\nopenAVX2ShortTail32:\n\tCMPQ    BX, $0x10\n\tVMOVDQA X0, X1\n\tJB      openAVX2ShortDone\n\tSUBQ    $0x10, BX\n\n\t// Load for hashing\n\tADDQ  (SI), R10\n\tADCQ  8(SI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), DX\n\tMOVQ  DX, R15\n\tMULXQ R10, R13, R14\n\tIMULQ R12, R15\n\tMULXQ R11, AX, DX\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), DX\n\tMULXQ R10, R10, AX\n\tADDQ  R10, R14\n\tMULXQ R11, R11, R8\n\tADCQ  R11, R15\n\tADCQ  $0x00, R8\n\tIMULQ R12, DX\n\tADDQ  AX, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\n\t// Load for decryption\n\tVPXOR      (SI), X0, X12\n\tVMOVDQU    X12, (DI)\n\tLEAQ       16(SI), SI\n\tLEAQ       16(DI), DI\n\tVPERM2I128 $0x11, Y0, Y0, Y0\n\tVMOVDQA    X0, X1\n\nopenAVX2ShortDone:\n\tVZEROUPPER\n\tJMP openSSETail16\n\nopenAVX2320:\n\tVMOVDQA Y0, Y5\n\tVMOVDQA Y14, Y9\n\tVMOVDQA Y12, Y13\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y1\n\tVMOVDQA Y0, Y6\n\tVMOVDQA Y14, Y10\n\tVMOVDQA Y12, Y8\n\tVPADDD  ·avx2IncMask<>+0(SB), Y1, Y2\n\tVMOVDQA Y14, Y7\n\tVMOVDQA Y12, Y11\n\tVMOVDQA Y4, Y15\n\tMOVQ    $0x0000000a, R9\n\nopenAVX2320InnerCipherLoop:\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol16<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x0c, Y14, Y3\n\tVPSRLD   $0x14, Y14, Y14\n\tVPXOR    Y3, Y14, Y14\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol8<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x07, Y14, Y3\n\tVPSRLD   $0x19, Y14, Y14\n\tVPXOR    Y3, Y14, Y14\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol16<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x0c, Y9, Y3\n\tVPSRLD   $0x14, Y9, Y9\n\tVPXOR    Y3, Y9, Y9\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol8<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x07, Y9, Y3\n\tVPSRLD   $0x19, Y9, Y9\n\tVPXOR    Y3, Y9, Y9\n\tVPADDD   Y10, Y6, Y6\n\tVPXOR    Y6, Y2, Y2\n\tVPSHUFB  ·rol16<>+0(SB), Y2, Y2\n\tVPADDD   Y2, Y8, Y8\n\tVPXOR    Y8, Y10, Y10\n\tVPSLLD   $0x0c, Y10, Y3\n\tVPSRLD   $0x14, Y10, Y10\n\tVPXOR    Y3, Y10, Y10\n\tVPADDD   Y10, Y6, Y6\n\tVPXOR    Y6, Y2, Y2\n\tVPSHUFB  ·rol8<>+0(SB), Y2, Y2\n\tVPADDD   Y2, Y8, Y8\n\tVPXOR    Y8, Y10, Y10\n\tVPSLLD   $0x07, Y10, Y3\n\tVPSRLD   $0x19, Y10, Y10\n\tVPXOR    Y3, Y10, Y10\n\tVPALIGNR $0x04, Y14, Y14, Y14\n\tVPALIGNR $0x04, Y9, Y9, Y9\n\tVPALIGNR $0x04, Y10, Y10, Y10\n\tVPALIGNR $0x08, Y12, Y12, Y12\n\tVPALIGNR $0x08, Y13, Y13, Y13\n\tVPALIGNR $0x08, Y8, Y8, Y8\n\tVPALIGNR $0x0c, Y4, Y4, Y4\n\tVPALIGNR $0x0c, Y1, Y1, Y1\n\tVPALIGNR $0x0c, Y2, Y2, Y2\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol16<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x0c, Y14, Y3\n\tVPSRLD   $0x14, Y14, Y14\n\tVPXOR    Y3, Y14, Y14\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol8<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x07, Y14, Y3\n\tVPSRLD   $0x19, Y14, Y14\n\tVPXOR    Y3, Y14, Y14\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol16<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x0c, Y9, Y3\n\tVPSRLD   $0x14, Y9, Y9\n\tVPXOR    Y3, Y9, Y9\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol8<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x07, Y9, Y3\n\tVPSRLD   $0x19, Y9, Y9\n\tVPXOR    Y3, Y9, Y9\n\tVPADDD   Y10, Y6, Y6\n\tVPXOR    Y6, Y2, Y2\n\tVPSHUFB  ·rol16<>+0(SB), Y2, Y2\n\tVPADDD   Y2, Y8, Y8\n\tVPXOR    Y8, Y10, Y10\n\tVPSLLD   $0x0c, Y10, Y3\n\tVPSRLD   $0x14, Y10, Y10\n\tVPXOR    Y3, Y10, Y10\n\tVPADDD   Y10, Y6, Y6\n\tVPXOR    Y6, Y2, Y2\n\tVPSHUFB  ·rol8<>+0(SB), Y2, Y2\n\tVPADDD   Y2, Y8, Y8\n\tVPXOR    Y8, Y10, Y10\n\tVPSLLD   $0x07, Y10, Y3\n\tVPSRLD   $0x19, Y10, Y10\n\tVPXOR    Y3, Y10, Y10\n\tVPALIGNR $0x0c, Y14, Y14, Y14\n\tVPALIGNR $0x0c, Y9, Y9, Y9\n\tVPALIGNR $0x0c, Y10, Y10, Y10\n\tVPALIGNR $0x08, Y12, Y12, Y12\n\tVPALIGNR $0x08, Y13, Y13, Y13\n\tVPALIGNR $0x08, Y8, Y8, Y8\n\tVPALIGNR $0x04, Y4, Y4, Y4\n\tVPALIGNR $0x04, Y1, Y1, Y1\n\tVPALIGNR $0x04, Y2, Y2, Y2\n\tDECQ     R9\n\tJNE      openAVX2320InnerCipherLoop\n\tVMOVDQA  ·chacha20Constants<>+0(SB), Y3\n\tVPADDD   Y3, Y0, Y0\n\tVPADDD   Y3, Y5, Y5\n\tVPADDD   Y3, Y6, Y6\n\tVPADDD   Y7, Y14, Y14\n\tVPADDD   Y7, Y9, Y9\n\tVPADDD   Y7, Y10, Y10\n\tVPADDD   Y11, Y12, Y12\n\tVPADDD   Y11, Y13, Y13\n\tVPADDD   Y11, Y8, Y8\n\tVMOVDQA  ·avx2IncMask<>+0(SB), Y3\n\tVPADDD   Y15, Y4, Y4\n\tVPADDD   Y3, Y15, Y15\n\tVPADDD   Y15, Y1, Y1\n\tVPADDD   Y3, Y15, Y15\n\tVPADDD   Y15, Y2, Y2\n\n\t// Clamp and store poly key\n\tVPERM2I128 $0x02, Y0, Y14, Y3\n\tVPAND      ·polyClampMask<>+0(SB), Y3, Y3\n\tVMOVDQA    Y3, (BP)\n\n\t// Stream for up to 320 bytes\n\tVPERM2I128 $0x13, Y0, Y14, Y0\n\tVPERM2I128 $0x13, Y12, Y4, Y14\n\tVPERM2I128 $0x02, Y5, Y9, Y12\n\tVPERM2I128 $0x02, Y13, Y1, Y4\n\tVPERM2I128 $0x13, Y5, Y9, Y5\n\tVPERM2I128 $0x13, Y13, Y1, Y9\n\tVPERM2I128 $0x02, Y6, Y10, Y13\n\tVPERM2I128 $0x02, Y8, Y2, Y1\n\tVPERM2I128 $0x13, Y6, Y10, Y6\n\tVPERM2I128 $0x13, Y8, Y2, Y10\n\tJMP        openAVX2ShortOpen\n\nopenAVX2Tail128:\n\t// Need to decrypt up to 128 bytes - prepare two blocks\n\tVMOVDQA ·chacha20Constants<>+0(SB), Y5\n\tVMOVDQA 32(BP), Y9\n\tVMOVDQA 64(BP), Y13\n\tVMOVDQA 192(BP), Y1\n\tVPADDD  ·avx2IncMask<>+0(SB), Y1, Y1\n\tVMOVDQA Y1, Y4\n\tXORQ    R9, R9\n\tMOVQ    BX, CX\n\tANDQ    $-16, CX\n\tTESTQ   CX, CX\n\tJE      openAVX2Tail128LoopB\n\nopenAVX2Tail128LoopA:\n\tADDQ  (SI)(R9*1), R10\n\tADCQ  8(SI)(R9*1), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), DX\n\tMOVQ  DX, R15\n\tMULXQ R10, R13, R14\n\tIMULQ R12, R15\n\tMULXQ R11, AX, DX\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), DX\n\tMULXQ R10, R10, AX\n\tADDQ  R10, R14\n\tMULXQ R11, R11, R8\n\tADCQ  R11, R15\n\tADCQ  $0x00, R8\n\tIMULQ R12, DX\n\tADDQ  AX, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\nopenAVX2Tail128LoopB:\n\tADDQ       $0x10, R9\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol16<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x0c, Y9, Y3\n\tVPSRLD     $0x14, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol8<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x07, Y9, Y3\n\tVPSRLD     $0x19, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPALIGNR   $0x04, Y9, Y9, Y9\n\tVPALIGNR   $0x08, Y13, Y13, Y13\n\tVPALIGNR   $0x0c, Y1, Y1, Y1\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol16<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x0c, Y9, Y3\n\tVPSRLD     $0x14, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol8<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x07, Y9, Y3\n\tVPSRLD     $0x19, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPALIGNR   $0x0c, Y9, Y9, Y9\n\tVPALIGNR   $0x08, Y13, Y13, Y13\n\tVPALIGNR   $0x04, Y1, Y1, Y1\n\tCMPQ       R9, CX\n\tJB         openAVX2Tail128LoopA\n\tCMPQ       R9, $0xa0\n\tJNE        openAVX2Tail128LoopB\n\tVPADDD     ·chacha20Constants<>+0(SB), Y5, Y5\n\tVPADDD     32(BP), Y9, Y9\n\tVPADDD     64(BP), Y13, Y13\n\tVPADDD     Y4, Y1, Y1\n\tVPERM2I128 $0x02, Y5, Y9, Y0\n\tVPERM2I128 $0x02, Y13, Y1, Y14\n\tVPERM2I128 $0x13, Y5, Y9, Y12\n\tVPERM2I128 $0x13, Y13, Y1, Y4\n\nopenAVX2TailLoop:\n\tCMPQ BX, $0x20\n\tJB   openAVX2Tail\n\tSUBQ $0x20, BX\n\n\t// Load for decryption\n\tVPXOR   (SI), Y0, Y0\n\tVMOVDQU Y0, (DI)\n\tLEAQ    32(SI), SI\n\tLEAQ    32(DI), DI\n\tVMOVDQA Y14, Y0\n\tVMOVDQA Y12, Y14\n\tVMOVDQA Y4, Y12\n\tJMP     openAVX2TailLoop\n\nopenAVX2Tail:\n\tCMPQ    BX, $0x10\n\tVMOVDQA X0, X1\n\tJB      openAVX2TailDone\n\tSUBQ    $0x10, BX\n\n\t// Load for decryption\n\tVPXOR      (SI), X0, X12\n\tVMOVDQU    X12, (DI)\n\tLEAQ       16(SI), SI\n\tLEAQ       16(DI), DI\n\tVPERM2I128 $0x11, Y0, Y0, Y0\n\tVMOVDQA    X0, X1\n\nopenAVX2TailDone:\n\tVZEROUPPER\n\tJMP openSSETail16\n\nopenAVX2Tail256:\n\tVMOVDQA ·chacha20Constants<>+0(SB), Y0\n\tVMOVDQA Y0, Y5\n\tVMOVDQA 32(BP), Y14\n\tVMOVDQA Y14, Y9\n\tVMOVDQA 64(BP), Y12\n\tVMOVDQA Y12, Y13\n\tVMOVDQA 192(BP), Y4\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y4\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y1\n\tVMOVDQA Y4, Y7\n\tVMOVDQA Y1, Y11\n\n\t// Compute the number of iterations that will hash data\n\tMOVQ    BX, 224(BP)\n\tMOVQ    BX, CX\n\tSUBQ    $0x80, CX\n\tSHRQ    $0x04, CX\n\tMOVQ    $0x0000000a, R9\n\tCMPQ    CX, $0x0a\n\tCMOVQGT R9, CX\n\tMOVQ    SI, BX\n\tXORQ    R9, R9\n\nopenAVX2Tail256LoopA:\n\tADDQ  (BX), R10\n\tADCQ  8(BX), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), DX\n\tMOVQ  DX, R15\n\tMULXQ R10, R13, R14\n\tIMULQ R12, R15\n\tMULXQ R11, AX, DX\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), DX\n\tMULXQ R10, R10, AX\n\tADDQ  R10, R14\n\tMULXQ R11, R11, R8\n\tADCQ  R11, R15\n\tADCQ  $0x00, R8\n\tIMULQ R12, DX\n\tADDQ  AX, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(BX), BX\n\nopenAVX2Tail256LoopB:\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol16<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x0c, Y14, Y3\n\tVPSRLD   $0x14, Y14, Y14\n\tVPXOR    Y3, Y14, Y14\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol8<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x07, Y14, Y3\n\tVPSRLD   $0x19, Y14, Y14\n\tVPXOR    Y3, Y14, Y14\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol16<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x0c, Y9, Y3\n\tVPSRLD   $0x14, Y9, Y9\n\tVPXOR    Y3, Y9, Y9\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol8<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x07, Y9, Y3\n\tVPSRLD   $0x19, Y9, Y9\n\tVPXOR    Y3, Y9, Y9\n\tVPALIGNR $0x04, Y14, Y14, Y14\n\tVPALIGNR $0x04, Y9, Y9, Y9\n\tVPALIGNR $0x08, Y12, Y12, Y12\n\tVPALIGNR $0x08, Y13, Y13, Y13\n\tVPALIGNR $0x0c, Y4, Y4, Y4\n\tVPALIGNR $0x0c, Y1, Y1, Y1\n\tINCQ     R9\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol16<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x0c, Y14, Y3\n\tVPSRLD   $0x14, Y14, Y14\n\tVPXOR    Y3, Y14, Y14\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol8<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x07, Y14, Y3\n\tVPSRLD   $0x19, Y14, Y14\n\tVPXOR    Y3, Y14, Y14\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol16<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x0c, Y9, Y3\n\tVPSRLD   $0x14, Y9, Y9\n\tVPXOR    Y3, Y9, Y9\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol8<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x07, Y9, Y3\n\tVPSRLD   $0x19, Y9, Y9\n\tVPXOR    Y3, Y9, Y9\n\tVPALIGNR $0x0c, Y14, Y14, Y14\n\tVPALIGNR $0x0c, Y9, Y9, Y9\n\tVPALIGNR $0x08, Y12, Y12, Y12\n\tVPALIGNR $0x08, Y13, Y13, Y13\n\tVPALIGNR $0x04, Y4, Y4, Y4\n\tVPALIGNR $0x04, Y1, Y1, Y1\n\tCMPQ     R9, CX\n\tJB       openAVX2Tail256LoopA\n\tCMPQ     R9, $0x0a\n\tJNE      openAVX2Tail256LoopB\n\tMOVQ     BX, R9\n\tSUBQ     SI, BX\n\tMOVQ     BX, CX\n\tMOVQ     224(BP), BX\n\nopenAVX2Tail256Hash:\n\tADDQ  $0x10, CX\n\tCMPQ  CX, BX\n\tJGT   openAVX2Tail256HashEnd\n\tADDQ  (R9), R10\n\tADCQ  8(R9), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), DX\n\tMOVQ  DX, R15\n\tMULXQ R10, R13, R14\n\tIMULQ R12, R15\n\tMULXQ R11, AX, DX\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), DX\n\tMULXQ R10, R10, AX\n\tADDQ  R10, R14\n\tMULXQ R11, R11, R8\n\tADCQ  R11, R15\n\tADCQ  $0x00, R8\n\tIMULQ R12, DX\n\tADDQ  AX, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(R9), R9\n\tJMP   openAVX2Tail256Hash\n\nopenAVX2Tail256HashEnd:\n\tVPADDD     ·chacha20Constants<>+0(SB), Y0, Y0\n\tVPADDD     ·chacha20Constants<>+0(SB), Y5, Y5\n\tVPADDD     32(BP), Y14, Y14\n\tVPADDD     32(BP), Y9, Y9\n\tVPADDD     64(BP), Y12, Y12\n\tVPADDD     64(BP), Y13, Y13\n\tVPADDD     Y7, Y4, Y4\n\tVPADDD     Y11, Y1, Y1\n\tVPERM2I128 $0x02, Y0, Y14, Y6\n\tVPERM2I128 $0x02, Y12, Y4, Y10\n\tVPERM2I128 $0x13, Y0, Y14, Y8\n\tVPERM2I128 $0x13, Y12, Y4, Y2\n\tVPERM2I128 $0x02, Y5, Y9, Y0\n\tVPERM2I128 $0x02, Y13, Y1, Y14\n\tVPERM2I128 $0x13, Y5, Y9, Y12\n\tVPERM2I128 $0x13, Y13, Y1, Y4\n\tVPXOR      (SI), Y6, Y6\n\tVPXOR      32(SI), Y10, Y10\n\tVPXOR      64(SI), Y8, Y8\n\tVPXOR      96(SI), Y2, Y2\n\tVMOVDQU    Y6, (DI)\n\tVMOVDQU    Y10, 32(DI)\n\tVMOVDQU    Y8, 64(DI)\n\tVMOVDQU    Y2, 96(DI)\n\tLEAQ       128(SI), SI\n\tLEAQ       128(DI), DI\n\tSUBQ       $0x80, BX\n\tJMP        openAVX2TailLoop\n\nopenAVX2Tail384:\n\t// Need to decrypt up to 384 bytes - prepare six blocks\n\tVMOVDQA ·chacha20Constants<>+0(SB), Y0\n\tVMOVDQA Y0, Y5\n\tVMOVDQA Y0, Y6\n\tVMOVDQA 32(BP), Y14\n\tVMOVDQA Y14, Y9\n\tVMOVDQA Y14, Y10\n\tVMOVDQA 64(BP), Y12\n\tVMOVDQA Y12, Y13\n\tVMOVDQA Y12, Y8\n\tVMOVDQA 192(BP), Y4\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y4\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y1\n\tVPADDD  ·avx2IncMask<>+0(SB), Y1, Y2\n\tVMOVDQA Y4, 96(BP)\n\tVMOVDQA Y1, 128(BP)\n\tVMOVDQA Y2, 160(BP)\n\n\t// Compute the number of iterations that will hash two blocks of data\n\tMOVQ    BX, 224(BP)\n\tMOVQ    BX, CX\n\tSUBQ    $0x00000100, CX\n\tSHRQ    $0x04, CX\n\tADDQ    $0x06, CX\n\tMOVQ    $0x0000000a, R9\n\tCMPQ    CX, $0x0a\n\tCMOVQGT R9, CX\n\tMOVQ    SI, BX\n\tXORQ    R9, R9\n\nopenAVX2Tail384LoopB:\n\tADDQ  (BX), R10\n\tADCQ  8(BX), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), DX\n\tMOVQ  DX, R15\n\tMULXQ R10, R13, R14\n\tIMULQ R12, R15\n\tMULXQ R11, AX, DX\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), DX\n\tMULXQ R10, R10, AX\n\tADDQ  R10, R14\n\tMULXQ R11, R11, R8\n\tADCQ  R11, R15\n\tADCQ  $0x00, R8\n\tIMULQ R12, DX\n\tADDQ  AX, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(BX), BX\n\nopenAVX2Tail384LoopA:\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol16<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x0c, Y14, Y3\n\tVPSRLD   $0x14, Y14, Y14\n\tVPXOR    Y3, Y14, Y14\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol8<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x07, Y14, Y3\n\tVPSRLD   $0x19, Y14, Y14\n\tVPXOR    Y3, Y14, Y14\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol16<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x0c, Y9, Y3\n\tVPSRLD   $0x14, Y9, Y9\n\tVPXOR    Y3, Y9, Y9\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol8<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x07, Y9, Y3\n\tVPSRLD   $0x19, Y9, Y9\n\tVPXOR    Y3, Y9, Y9\n\tVPADDD   Y10, Y6, Y6\n\tVPXOR    Y6, Y2, Y2\n\tVPSHUFB  ·rol16<>+0(SB), Y2, Y2\n\tVPADDD   Y2, Y8, Y8\n\tVPXOR    Y8, Y10, Y10\n\tVPSLLD   $0x0c, Y10, Y3\n\tVPSRLD   $0x14, Y10, Y10\n\tVPXOR    Y3, Y10, Y10\n\tVPADDD   Y10, Y6, Y6\n\tVPXOR    Y6, Y2, Y2\n\tVPSHUFB  ·rol8<>+0(SB), Y2, Y2\n\tVPADDD   Y2, Y8, Y8\n\tVPXOR    Y8, Y10, Y10\n\tVPSLLD   $0x07, Y10, Y3\n\tVPSRLD   $0x19, Y10, Y10\n\tVPXOR    Y3, Y10, Y10\n\tVPALIGNR $0x04, Y14, Y14, Y14\n\tVPALIGNR $0x04, Y9, Y9, Y9\n\tVPALIGNR $0x04, Y10, Y10, Y10\n\tVPALIGNR $0x08, Y12, Y12, Y12\n\tVPALIGNR $0x08, Y13, Y13, Y13\n\tVPALIGNR $0x08, Y8, Y8, Y8\n\tVPALIGNR $0x0c, Y4, Y4, Y4\n\tVPALIGNR $0x0c, Y1, Y1, Y1\n\tVPALIGNR $0x0c, Y2, Y2, Y2\n\tADDQ     (BX), R10\n\tADCQ     8(BX), R11\n\tADCQ     $0x01, R12\n\tMOVQ     (BP), DX\n\tMOVQ     DX, R15\n\tMULXQ    R10, R13, R14\n\tIMULQ    R12, R15\n\tMULXQ    R11, AX, DX\n\tADDQ     AX, R14\n\tADCQ     DX, R15\n\tMOVQ     8(BP), DX\n\tMULXQ    R10, R10, AX\n\tADDQ     R10, R14\n\tMULXQ    R11, R11, R8\n\tADCQ     R11, R15\n\tADCQ     $0x00, R8\n\tIMULQ    R12, DX\n\tADDQ     AX, R15\n\tADCQ     DX, R8\n\tMOVQ     R13, R10\n\tMOVQ     R14, R11\n\tMOVQ     R15, R12\n\tANDQ     $0x03, R12\n\tMOVQ     R15, R13\n\tANDQ     $-4, R13\n\tMOVQ     R8, R14\n\tSHRQ     $0x02, R8, R15\n\tSHRQ     $0x02, R8\n\tADDQ     R13, R10\n\tADCQ     R14, R11\n\tADCQ     $0x00, R12\n\tADDQ     R15, R10\n\tADCQ     R8, R11\n\tADCQ     $0x00, R12\n\tLEAQ     16(BX), BX\n\tINCQ     R9\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol16<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x0c, Y14, Y3\n\tVPSRLD   $0x14, Y14, Y14\n\tVPXOR    Y3, Y14, Y14\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol8<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x07, Y14, Y3\n\tVPSRLD   $0x19, Y14, Y14\n\tVPXOR    Y3, Y14, Y14\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol16<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x0c, Y9, Y3\n\tVPSRLD   $0x14, Y9, Y9\n\tVPXOR    Y3, Y9, Y9\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol8<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x07, Y9, Y3\n\tVPSRLD   $0x19, Y9, Y9\n\tVPXOR    Y3, Y9, Y9\n\tVPADDD   Y10, Y6, Y6\n\tVPXOR    Y6, Y2, Y2\n\tVPSHUFB  ·rol16<>+0(SB), Y2, Y2\n\tVPADDD   Y2, Y8, Y8\n\tVPXOR    Y8, Y10, Y10\n\tVPSLLD   $0x0c, Y10, Y3\n\tVPSRLD   $0x14, Y10, Y10\n\tVPXOR    Y3, Y10, Y10\n\tVPADDD   Y10, Y6, Y6\n\tVPXOR    Y6, Y2, Y2\n\tVPSHUFB  ·rol8<>+0(SB), Y2, Y2\n\tVPADDD   Y2, Y8, Y8\n\tVPXOR    Y8, Y10, Y10\n\tVPSLLD   $0x07, Y10, Y3\n\tVPSRLD   $0x19, Y10, Y10\n\tVPXOR    Y3, Y10, Y10\n\tVPALIGNR $0x0c, Y14, Y14, Y14\n\tVPALIGNR $0x0c, Y9, Y9, Y9\n\tVPALIGNR $0x0c, Y10, Y10, Y10\n\tVPALIGNR $0x08, Y12, Y12, Y12\n\tVPALIGNR $0x08, Y13, Y13, Y13\n\tVPALIGNR $0x08, Y8, Y8, Y8\n\tVPALIGNR $0x04, Y4, Y4, Y4\n\tVPALIGNR $0x04, Y1, Y1, Y1\n\tVPALIGNR $0x04, Y2, Y2, Y2\n\tCMPQ     R9, CX\n\tJB       openAVX2Tail384LoopB\n\tCMPQ     R9, $0x0a\n\tJNE      openAVX2Tail384LoopA\n\tMOVQ     BX, R9\n\tSUBQ     SI, BX\n\tMOVQ     BX, CX\n\tMOVQ     224(BP), BX\n\nopenAVX2Tail384Hash:\n\tADDQ  $0x10, CX\n\tCMPQ  CX, BX\n\tJGT   openAVX2Tail384HashEnd\n\tADDQ  (R9), R10\n\tADCQ  8(R9), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), DX\n\tMOVQ  DX, R15\n\tMULXQ R10, R13, R14\n\tIMULQ R12, R15\n\tMULXQ R11, AX, DX\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), DX\n\tMULXQ R10, R10, AX\n\tADDQ  R10, R14\n\tMULXQ R11, R11, R8\n\tADCQ  R11, R15\n\tADCQ  $0x00, R8\n\tIMULQ R12, DX\n\tADDQ  AX, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(R9), R9\n\tJMP   openAVX2Tail384Hash\n\nopenAVX2Tail384HashEnd:\n\tVPADDD     ·chacha20Constants<>+0(SB), Y0, Y0\n\tVPADDD     ·chacha20Constants<>+0(SB), Y5, Y5\n\tVPADDD     ·chacha20Constants<>+0(SB), Y6, Y6\n\tVPADDD     32(BP), Y14, Y14\n\tVPADDD     32(BP), Y9, Y9\n\tVPADDD     32(BP), Y10, Y10\n\tVPADDD     64(BP), Y12, Y12\n\tVPADDD     64(BP), Y13, Y13\n\tVPADDD     64(BP), Y8, Y8\n\tVPADDD     96(BP), Y4, Y4\n\tVPADDD     128(BP), Y1, Y1\n\tVPADDD     160(BP), Y2, Y2\n\tVPERM2I128 $0x02, Y0, Y14, Y3\n\tVPERM2I128 $0x02, Y12, Y4, Y7\n\tVPERM2I128 $0x13, Y0, Y14, Y11\n\tVPERM2I128 $0x13, Y12, Y4, Y15\n\tVPXOR      (SI), Y3, Y3\n\tVPXOR      32(SI), Y7, Y7\n\tVPXOR      64(SI), Y11, Y11\n\tVPXOR      96(SI), Y15, Y15\n\tVMOVDQU    Y3, (DI)\n\tVMOVDQU    Y7, 32(DI)\n\tVMOVDQU    Y11, 64(DI)\n\tVMOVDQU    Y15, 96(DI)\n\tVPERM2I128 $0x02, Y5, Y9, Y3\n\tVPERM2I128 $0x02, Y13, Y1, Y7\n\tVPERM2I128 $0x13, Y5, Y9, Y11\n\tVPERM2I128 $0x13, Y13, Y1, Y15\n\tVPXOR      128(SI), Y3, Y3\n\tVPXOR      160(SI), Y7, Y7\n\tVPXOR      192(SI), Y11, Y11\n\tVPXOR      224(SI), Y15, Y15\n\tVMOVDQU    Y3, 128(DI)\n\tVMOVDQU    Y7, 160(DI)\n\tVMOVDQU    Y11, 192(DI)\n\tVMOVDQU    Y15, 224(DI)\n\tVPERM2I128 $0x02, Y6, Y10, Y0\n\tVPERM2I128 $0x02, Y8, Y2, Y14\n\tVPERM2I128 $0x13, Y6, Y10, Y12\n\tVPERM2I128 $0x13, Y8, Y2, Y4\n\tLEAQ       256(SI), SI\n\tLEAQ       256(DI), DI\n\tSUBQ       $0x00000100, BX\n\tJMP        openAVX2TailLoop\n\nopenAVX2Tail512:\n\tVMOVDQU ·chacha20Constants<>+0(SB), Y0\n\tVMOVDQA Y0, Y5\n\tVMOVDQA Y0, Y6\n\tVMOVDQA Y0, Y7\n\tVMOVDQA 32(BP), Y14\n\tVMOVDQA Y14, Y9\n\tVMOVDQA Y14, Y10\n\tVMOVDQA Y14, Y11\n\tVMOVDQA 64(BP), Y12\n\tVMOVDQA Y12, Y13\n\tVMOVDQA Y12, Y8\n\tVMOVDQA Y12, Y15\n\tVMOVDQA 192(BP), Y4\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y4\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y1\n\tVPADDD  ·avx2IncMask<>+0(SB), Y1, Y2\n\tVPADDD  ·avx2IncMask<>+0(SB), Y2, Y3\n\tVMOVDQA Y4, 96(BP)\n\tVMOVDQA Y1, 128(BP)\n\tVMOVDQA Y2, 160(BP)\n\tVMOVDQA Y3, 192(BP)\n\tXORQ    CX, CX\n\tMOVQ    SI, R9\n\nopenAVX2Tail512LoopB:\n\tADDQ  (R9), R10\n\tADCQ  8(R9), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), DX\n\tMOVQ  DX, R15\n\tMULXQ R10, R13, R14\n\tIMULQ R12, R15\n\tMULXQ R11, AX, DX\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), DX\n\tMULXQ R10, R10, AX\n\tADDQ  R10, R14\n\tMULXQ R11, R11, R8\n\tADCQ  R11, R15\n\tADCQ  $0x00, R8\n\tIMULQ R12, DX\n\tADDQ  AX, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(R9), R9\n\nopenAVX2Tail512LoopA:\n\tVPADDD   Y14, Y0, Y0\n\tVPADDD   Y9, Y5, Y5\n\tVPADDD   Y10, Y6, Y6\n\tVPADDD   Y11, Y7, Y7\n\tVPXOR    Y0, Y4, Y4\n\tVPXOR    Y5, Y1, Y1\n\tVPXOR    Y6, Y2, Y2\n\tVPXOR    Y7, Y3, Y3\n\tVPSHUFB  ·rol16<>+0(SB), Y4, Y4\n\tVPSHUFB  ·rol16<>+0(SB), Y1, Y1\n\tVPSHUFB  ·rol16<>+0(SB), Y2, Y2\n\tVPSHUFB  ·rol16<>+0(SB), Y3, Y3\n\tVPADDD   Y4, Y12, Y12\n\tVPADDD   Y1, Y13, Y13\n\tVPADDD   Y2, Y8, Y8\n\tVPADDD   Y3, Y15, Y15\n\tVPXOR    Y12, Y14, Y14\n\tVPXOR    Y13, Y9, Y9\n\tVPXOR    Y8, Y10, Y10\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  Y15, 224(BP)\n\tVPSLLD   $0x0c, Y14, Y15\n\tVPSRLD   $0x14, Y14, Y14\n\tVPXOR    Y15, Y14, Y14\n\tVPSLLD   $0x0c, Y9, Y15\n\tVPSRLD   $0x14, Y9, Y9\n\tVPXOR    Y15, Y9, Y9\n\tVPSLLD   $0x0c, Y10, Y15\n\tVPSRLD   $0x14, Y10, Y10\n\tVPXOR    Y15, Y10, Y10\n\tVPSLLD   $0x0c, Y11, Y15\n\tVPSRLD   $0x14, Y11, Y11\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  224(BP), Y15\n\tADDQ     (R9), R10\n\tADCQ     8(R9), R11\n\tADCQ     $0x01, R12\n\tMOVQ     (BP), DX\n\tMOVQ     DX, R15\n\tMULXQ    R10, R13, R14\n\tIMULQ    R12, R15\n\tMULXQ    R11, AX, DX\n\tADDQ     AX, R14\n\tADCQ     DX, R15\n\tMOVQ     8(BP), DX\n\tMULXQ    R10, R10, AX\n\tADDQ     R10, R14\n\tMULXQ    R11, R11, R8\n\tADCQ     R11, R15\n\tADCQ     $0x00, R8\n\tIMULQ    R12, DX\n\tADDQ     AX, R15\n\tADCQ     DX, R8\n\tMOVQ     R13, R10\n\tMOVQ     R14, R11\n\tMOVQ     R15, R12\n\tANDQ     $0x03, R12\n\tMOVQ     R15, R13\n\tANDQ     $-4, R13\n\tMOVQ     R8, R14\n\tSHRQ     $0x02, R8, R15\n\tSHRQ     $0x02, R8\n\tADDQ     R13, R10\n\tADCQ     R14, R11\n\tADCQ     $0x00, R12\n\tADDQ     R15, R10\n\tADCQ     R8, R11\n\tADCQ     $0x00, R12\n\tVPADDD   Y14, Y0, Y0\n\tVPADDD   Y9, Y5, Y5\n\tVPADDD   Y10, Y6, Y6\n\tVPADDD   Y11, Y7, Y7\n\tVPXOR    Y0, Y4, Y4\n\tVPXOR    Y5, Y1, Y1\n\tVPXOR    Y6, Y2, Y2\n\tVPXOR    Y7, Y3, Y3\n\tVPSHUFB  ·rol8<>+0(SB), Y4, Y4\n\tVPSHUFB  ·rol8<>+0(SB), Y1, Y1\n\tVPSHUFB  ·rol8<>+0(SB), Y2, Y2\n\tVPSHUFB  ·rol8<>+0(SB), Y3, Y3\n\tVPADDD   Y4, Y12, Y12\n\tVPADDD   Y1, Y13, Y13\n\tVPADDD   Y2, Y8, Y8\n\tVPADDD   Y3, Y15, Y15\n\tVPXOR    Y12, Y14, Y14\n\tVPXOR    Y13, Y9, Y9\n\tVPXOR    Y8, Y10, Y10\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  Y15, 224(BP)\n\tVPSLLD   $0x07, Y14, Y15\n\tVPSRLD   $0x19, Y14, Y14\n\tVPXOR    Y15, Y14, Y14\n\tVPSLLD   $0x07, Y9, Y15\n\tVPSRLD   $0x19, Y9, Y9\n\tVPXOR    Y15, Y9, Y9\n\tVPSLLD   $0x07, Y10, Y15\n\tVPSRLD   $0x19, Y10, Y10\n\tVPXOR    Y15, Y10, Y10\n\tVPSLLD   $0x07, Y11, Y15\n\tVPSRLD   $0x19, Y11, Y11\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  224(BP), Y15\n\tVPALIGNR $0x04, Y14, Y14, Y14\n\tVPALIGNR $0x04, Y9, Y9, Y9\n\tVPALIGNR $0x04, Y10, Y10, Y10\n\tVPALIGNR $0x04, Y11, Y11, Y11\n\tVPALIGNR $0x08, Y12, Y12, Y12\n\tVPALIGNR $0x08, Y13, Y13, Y13\n\tVPALIGNR $0x08, Y8, Y8, Y8\n\tVPALIGNR $0x08, Y15, Y15, Y15\n\tVPALIGNR $0x0c, Y4, Y4, Y4\n\tVPALIGNR $0x0c, Y1, Y1, Y1\n\tVPALIGNR $0x0c, Y2, Y2, Y2\n\tVPALIGNR $0x0c, Y3, Y3, Y3\n\tVPADDD   Y14, Y0, Y0\n\tVPADDD   Y9, Y5, Y5\n\tVPADDD   Y10, Y6, Y6\n\tVPADDD   Y11, Y7, Y7\n\tVPXOR    Y0, Y4, Y4\n\tVPXOR    Y5, Y1, Y1\n\tVPXOR    Y6, Y2, Y2\n\tVPXOR    Y7, Y3, Y3\n\tVPSHUFB  ·rol16<>+0(SB), Y4, Y4\n\tVPSHUFB  ·rol16<>+0(SB), Y1, Y1\n\tVPSHUFB  ·rol16<>+0(SB), Y2, Y2\n\tVPSHUFB  ·rol16<>+0(SB), Y3, Y3\n\tVPADDD   Y4, Y12, Y12\n\tVPADDD   Y1, Y13, Y13\n\tVPADDD   Y2, Y8, Y8\n\tVPADDD   Y3, Y15, Y15\n\tVPXOR    Y12, Y14, Y14\n\tVPXOR    Y13, Y9, Y9\n\tVPXOR    Y8, Y10, Y10\n\tVPXOR    Y15, Y11, Y11\n\tADDQ     16(R9), R10\n\tADCQ     24(R9), R11\n\tADCQ     $0x01, R12\n\tMOVQ     (BP), DX\n\tMOVQ     DX, R15\n\tMULXQ    R10, R13, R14\n\tIMULQ    R12, R15\n\tMULXQ    R11, AX, DX\n\tADDQ     AX, R14\n\tADCQ     DX, R15\n\tMOVQ     8(BP), DX\n\tMULXQ    R10, R10, AX\n\tADDQ     R10, R14\n\tMULXQ    R11, R11, R8\n\tADCQ     R11, R15\n\tADCQ     $0x00, R8\n\tIMULQ    R12, DX\n\tADDQ     AX, R15\n\tADCQ     DX, R8\n\tMOVQ     R13, R10\n\tMOVQ     R14, R11\n\tMOVQ     R15, R12\n\tANDQ     $0x03, R12\n\tMOVQ     R15, R13\n\tANDQ     $-4, R13\n\tMOVQ     R8, R14\n\tSHRQ     $0x02, R8, R15\n\tSHRQ     $0x02, R8\n\tADDQ     R13, R10\n\tADCQ     R14, R11\n\tADCQ     $0x00, R12\n\tADDQ     R15, R10\n\tADCQ     R8, R11\n\tADCQ     $0x00, R12\n\tLEAQ     32(R9), R9\n\tVMOVDQA  Y15, 224(BP)\n\tVPSLLD   $0x0c, Y14, Y15\n\tVPSRLD   $0x14, Y14, Y14\n\tVPXOR    Y15, Y14, Y14\n\tVPSLLD   $0x0c, Y9, Y15\n\tVPSRLD   $0x14, Y9, Y9\n\tVPXOR    Y15, Y9, Y9\n\tVPSLLD   $0x0c, Y10, Y15\n\tVPSRLD   $0x14, Y10, Y10\n\tVPXOR    Y15, Y10, Y10\n\tVPSLLD   $0x0c, Y11, Y15\n\tVPSRLD   $0x14, Y11, Y11\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  224(BP), Y15\n\tVPADDD   Y14, Y0, Y0\n\tVPADDD   Y9, Y5, Y5\n\tVPADDD   Y10, Y6, Y6\n\tVPADDD   Y11, Y7, Y7\n\tVPXOR    Y0, Y4, Y4\n\tVPXOR    Y5, Y1, Y1\n\tVPXOR    Y6, Y2, Y2\n\tVPXOR    Y7, Y3, Y3\n\tVPSHUFB  ·rol8<>+0(SB), Y4, Y4\n\tVPSHUFB  ·rol8<>+0(SB), Y1, Y1\n\tVPSHUFB  ·rol8<>+0(SB), Y2, Y2\n\tVPSHUFB  ·rol8<>+0(SB), Y3, Y3\n\tVPADDD   Y4, Y12, Y12\n\tVPADDD   Y1, Y13, Y13\n\tVPADDD   Y2, Y8, Y8\n\tVPADDD   Y3, Y15, Y15\n\tVPXOR    Y12, Y14, Y14\n\tVPXOR    Y13, Y9, Y9\n\tVPXOR    Y8, Y10, Y10\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  Y15, 224(BP)\n\tVPSLLD   $0x07, Y14, Y15\n\tVPSRLD   $0x19, Y14, Y14\n\tVPXOR    Y15, Y14, Y14\n\tVPSLLD   $0x07, Y9, Y15\n\tVPSRLD   $0x19, Y9, Y9\n\tVPXOR    Y15, Y9, Y9\n\tVPSLLD   $0x07, Y10, Y15\n\tVPSRLD   $0x19, Y10, Y10\n\tVPXOR    Y15, Y10, Y10\n\tVPSLLD   $0x07, Y11, Y15\n\tVPSRLD   $0x19, Y11, Y11\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  224(BP), Y15\n\tVPALIGNR $0x0c, Y14, Y14, Y14\n\tVPALIGNR $0x0c, Y9, Y9, Y9\n\tVPALIGNR $0x0c, Y10, Y10, Y10\n\tVPALIGNR $0x0c, Y11, Y11, Y11\n\tVPALIGNR $0x08, Y12, Y12, Y12\n\tVPALIGNR $0x08, Y13, Y13, Y13\n\tVPALIGNR $0x08, Y8, Y8, Y8\n\tVPALIGNR $0x08, Y15, Y15, Y15\n\tVPALIGNR $0x04, Y4, Y4, Y4\n\tVPALIGNR $0x04, Y1, Y1, Y1\n\tVPALIGNR $0x04, Y2, Y2, Y2\n\tVPALIGNR $0x04, Y3, Y3, Y3\n\tINCQ     CX\n\tCMPQ     CX, $0x04\n\tJLT      openAVX2Tail512LoopB\n\tCMPQ     CX, $0x0a\n\tJNE      openAVX2Tail512LoopA\n\tMOVQ     BX, CX\n\tSUBQ     $0x00000180, CX\n\tANDQ     $-16, CX\n\nopenAVX2Tail512HashLoop:\n\tTESTQ CX, CX\n\tJE    openAVX2Tail512HashEnd\n\tADDQ  (R9), R10\n\tADCQ  8(R9), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), DX\n\tMOVQ  DX, R15\n\tMULXQ R10, R13, R14\n\tIMULQ R12, R15\n\tMULXQ R11, AX, DX\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), DX\n\tMULXQ R10, R10, AX\n\tADDQ  R10, R14\n\tMULXQ R11, R11, R8\n\tADCQ  R11, R15\n\tADCQ  $0x00, R8\n\tIMULQ R12, DX\n\tADDQ  AX, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(R9), R9\n\tSUBQ  $0x10, CX\n\tJMP   openAVX2Tail512HashLoop\n\nopenAVX2Tail512HashEnd:\n\tVPADDD     ·chacha20Constants<>+0(SB), Y0, Y0\n\tVPADDD     ·chacha20Constants<>+0(SB), Y5, Y5\n\tVPADDD     ·chacha20Constants<>+0(SB), Y6, Y6\n\tVPADDD     ·chacha20Constants<>+0(SB), Y7, Y7\n\tVPADDD     32(BP), Y14, Y14\n\tVPADDD     32(BP), Y9, Y9\n\tVPADDD     32(BP), Y10, Y10\n\tVPADDD     32(BP), Y11, Y11\n\tVPADDD     64(BP), Y12, Y12\n\tVPADDD     64(BP), Y13, Y13\n\tVPADDD     64(BP), Y8, Y8\n\tVPADDD     64(BP), Y15, Y15\n\tVPADDD     96(BP), Y4, Y4\n\tVPADDD     128(BP), Y1, Y1\n\tVPADDD     160(BP), Y2, Y2\n\tVPADDD     192(BP), Y3, Y3\n\tVMOVDQA    Y15, 224(BP)\n\tVPERM2I128 $0x02, Y0, Y14, Y15\n\tVPERM2I128 $0x13, Y0, Y14, Y14\n\tVPERM2I128 $0x02, Y12, Y4, Y0\n\tVPERM2I128 $0x13, Y12, Y4, Y12\n\tVPXOR      (SI), Y15, Y15\n\tVPXOR      32(SI), Y0, Y0\n\tVPXOR      64(SI), Y14, Y14\n\tVPXOR      96(SI), Y12, Y12\n\tVMOVDQU    Y15, (DI)\n\tVMOVDQU    Y0, 32(DI)\n\tVMOVDQU    Y14, 64(DI)\n\tVMOVDQU    Y12, 96(DI)\n\tVPERM2I128 $0x02, Y5, Y9, Y0\n\tVPERM2I128 $0x02, Y13, Y1, Y14\n\tVPERM2I128 $0x13, Y5, Y9, Y12\n\tVPERM2I128 $0x13, Y13, Y1, Y4\n\tVPXOR      128(SI), Y0, Y0\n\tVPXOR      160(SI), Y14, Y14\n\tVPXOR      192(SI), Y12, Y12\n\tVPXOR      224(SI), Y4, Y4\n\tVMOVDQU    Y0, 128(DI)\n\tVMOVDQU    Y14, 160(DI)\n\tVMOVDQU    Y12, 192(DI)\n\tVMOVDQU    Y4, 224(DI)\n\tVPERM2I128 $0x02, Y6, Y10, Y0\n\tVPERM2I128 $0x02, Y8, Y2, Y14\n\tVPERM2I128 $0x13, Y6, Y10, Y12\n\tVPERM2I128 $0x13, Y8, Y2, Y4\n\tVPXOR      256(SI), Y0, Y0\n\tVPXOR      288(SI), Y14, Y14\n\tVPXOR      320(SI), Y12, Y12\n\tVPXOR      352(SI), Y4, Y4\n\tVMOVDQU    Y0, 256(DI)\n\tVMOVDQU    Y14, 288(DI)\n\tVMOVDQU    Y12, 320(DI)\n\tVMOVDQU    Y4, 352(DI)\n\tVPERM2I128 $0x02, Y7, Y11, Y0\n\tVPERM2I128 $0x02, 224(BP), Y3, Y14\n\tVPERM2I128 $0x13, Y7, Y11, Y12\n\tVPERM2I128 $0x13, 224(BP), Y3, Y4\n\tLEAQ       384(SI), SI\n\tLEAQ       384(DI), DI\n\tSUBQ       $0x00000180, BX\n\tJMP        openAVX2TailLoop\n\nDATA ·chacha20Constants<>+0(SB)/4, $0x61707865\nDATA ·chacha20Constants<>+4(SB)/4, $0x3320646e\nDATA ·chacha20Constants<>+8(SB)/4, $0x79622d32\nDATA ·chacha20Constants<>+12(SB)/4, $0x6b206574\nDATA ·chacha20Constants<>+16(SB)/4, $0x61707865\nDATA ·chacha20Constants<>+20(SB)/4, $0x3320646e\nDATA ·chacha20Constants<>+24(SB)/4, $0x79622d32\nDATA ·chacha20Constants<>+28(SB)/4, $0x6b206574\nGLOBL ·chacha20Constants<>(SB), RODATA|NOPTR, $32\n\nDATA ·polyClampMask<>+0(SB)/8, $0x0ffffffc0fffffff\nDATA ·polyClampMask<>+8(SB)/8, $0x0ffffffc0ffffffc\nDATA ·polyClampMask<>+16(SB)/8, $0xffffffffffffffff\nDATA ·polyClampMask<>+24(SB)/8, $0xffffffffffffffff\nGLOBL ·polyClampMask<>(SB), RODATA|NOPTR, $32\n\nDATA ·sseIncMask<>+0(SB)/8, $0x0000000000000001\nDATA ·sseIncMask<>+8(SB)/8, $0x0000000000000000\nGLOBL ·sseIncMask<>(SB), RODATA|NOPTR, $16\n\nDATA ·andMask<>+0(SB)/8, $0x00000000000000ff\nDATA ·andMask<>+8(SB)/8, $0x0000000000000000\nDATA ·andMask<>+16(SB)/8, $0x000000000000ffff\nDATA ·andMask<>+24(SB)/8, $0x0000000000000000\nDATA ·andMask<>+32(SB)/8, $0x0000000000ffffff\nDATA ·andMask<>+40(SB)/8, $0x0000000000000000\nDATA ·andMask<>+48(SB)/8, $0x00000000ffffffff\nDATA ·andMask<>+56(SB)/8, $0x0000000000000000\nDATA ·andMask<>+64(SB)/8, $0x000000ffffffffff\nDATA ·andMask<>+72(SB)/8, $0x0000000000000000\nDATA ·andMask<>+80(SB)/8, $0x0000ffffffffffff\nDATA ·andMask<>+88(SB)/8, $0x0000000000000000\nDATA ·andMask<>+96(SB)/8, $0x00ffffffffffffff\nDATA ·andMask<>+104(SB)/8, $0x0000000000000000\nDATA ·andMask<>+112(SB)/8, $0xffffffffffffffff\nDATA ·andMask<>+120(SB)/8, $0x0000000000000000\nDATA ·andMask<>+128(SB)/8, $0xffffffffffffffff\nDATA ·andMask<>+136(SB)/8, $0x00000000000000ff\nDATA ·andMask<>+144(SB)/8, $0xffffffffffffffff\nDATA ·andMask<>+152(SB)/8, $0x000000000000ffff\nDATA ·andMask<>+160(SB)/8, $0xffffffffffffffff\nDATA ·andMask<>+168(SB)/8, $0x0000000000ffffff\nDATA ·andMask<>+176(SB)/8, $0xffffffffffffffff\nDATA ·andMask<>+184(SB)/8, $0x00000000ffffffff\nDATA ·andMask<>+192(SB)/8, $0xffffffffffffffff\nDATA ·andMask<>+200(SB)/8, $0x000000ffffffffff\nDATA ·andMask<>+208(SB)/8, $0xffffffffffffffff\nDATA ·andMask<>+216(SB)/8, $0x0000ffffffffffff\nDATA ·andMask<>+224(SB)/8, $0xffffffffffffffff\nDATA ·andMask<>+232(SB)/8, $0x00ffffffffffffff\nGLOBL ·andMask<>(SB), RODATA|NOPTR, $240\n\nDATA ·avx2InitMask<>+0(SB)/8, $0x0000000000000000\nDATA ·avx2InitMask<>+8(SB)/8, $0x0000000000000000\nDATA ·avx2InitMask<>+16(SB)/8, $0x0000000000000001\nDATA ·avx2InitMask<>+24(SB)/8, $0x0000000000000000\nGLOBL ·avx2InitMask<>(SB), RODATA|NOPTR, $32\n\nDATA ·rol16<>+0(SB)/8, $0x0504070601000302\nDATA ·rol16<>+8(SB)/8, $0x0d0c0f0e09080b0a\nDATA ·rol16<>+16(SB)/8, $0x0504070601000302\nDATA ·rol16<>+24(SB)/8, $0x0d0c0f0e09080b0a\nGLOBL ·rol16<>(SB), RODATA|NOPTR, $32\n\nDATA ·rol8<>+0(SB)/8, $0x0605040702010003\nDATA ·rol8<>+8(SB)/8, $0x0e0d0c0f0a09080b\nDATA ·rol8<>+16(SB)/8, $0x0605040702010003\nDATA ·rol8<>+24(SB)/8, $0x0e0d0c0f0a09080b\nGLOBL ·rol8<>(SB), RODATA|NOPTR, $32\n\nDATA ·avx2IncMask<>+0(SB)/8, $0x0000000000000002\nDATA ·avx2IncMask<>+8(SB)/8, $0x0000000000000000\nDATA ·avx2IncMask<>+16(SB)/8, $0x0000000000000002\nDATA ·avx2IncMask<>+24(SB)/8, $0x0000000000000000\nGLOBL ·avx2IncMask<>(SB), RODATA|NOPTR, $32\n\n// func chacha20Poly1305Seal(dst []byte, key []uint32, src []byte, ad []byte)\n// Requires: AVX, AVX2, BMI2, CMOV, SSE2\nTEXT ·chacha20Poly1305Seal(SB), $288-96\n\tMOVQ SP, BP\n\tADDQ $0x20, BP\n\tANDQ $-32, BP\n\tMOVQ dst_base+0(FP), DI\n\tMOVQ key_base+24(FP), R8\n\tMOVQ src_base+48(FP), SI\n\tMOVQ src_len+56(FP), BX\n\tMOVQ ad_base+72(FP), CX\n\tCMPB ·useAVX2+0(SB), $0x01\n\tJE   chacha20Poly1305Seal_AVX2\n\n\t// Special optimization, for very short buffers\n\tCMPQ BX, $0x80\n\tJBE  sealSSE128\n\n\t// In the seal case - prepare the poly key + 3 blocks of stream in the first iteration\n\tMOVOU ·chacha20Constants<>+0(SB), X0\n\tMOVOU 16(R8), X3\n\tMOVOU 32(R8), X6\n\tMOVOU 48(R8), X9\n\n\t// Store state on stack for future use\n\tMOVO X3, 32(BP)\n\tMOVO X6, 48(BP)\n\n\t// Load state, increment counter blocks\n\tMOVO  X0, X1\n\tMOVO  X3, X4\n\tMOVO  X6, X7\n\tMOVO  X9, X10\n\tPADDL ·sseIncMask<>+0(SB), X10\n\tMOVO  X1, X2\n\tMOVO  X4, X5\n\tMOVO  X7, X8\n\tMOVO  X10, X11\n\tPADDL ·sseIncMask<>+0(SB), X11\n\tMOVO  X2, X12\n\tMOVO  X5, X13\n\tMOVO  X8, X14\n\tMOVO  X11, X15\n\tPADDL ·sseIncMask<>+0(SB), X15\n\n\t// Store counters\n\tMOVO X9, 80(BP)\n\tMOVO X10, 96(BP)\n\tMOVO X11, 112(BP)\n\tMOVO X15, 128(BP)\n\tMOVQ $0x0000000a, R9\n\nsealSSEIntroLoop:\n\tMOVO  X14, 64(BP)\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X14)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X3\n\tPXOR  X14, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X14)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X3\n\tPXOR  X14, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X14)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X4\n\tPXOR  X14, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X14)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X4\n\tPXOR  X14, X4\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL16(X11, X14)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X5\n\tPXOR  X14, X5\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL8(X11, X14)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X5\n\tPXOR  X14, X5\n\tMOVO  64(BP), X14\n\tMOVO  X7, 64(BP)\n\tPADDD X13, X12\n\tPXOR  X12, X15\n\tROL16(X15, X7)\n\tPADDD X15, X14\n\tPXOR  X14, X13\n\tMOVO  X13, X7\n\tPSLLL $0x0c, X7\n\tPSRLL $0x14, X13\n\tPXOR  X7, X13\n\tPADDD X13, X12\n\tPXOR  X12, X15\n\tROL8(X15, X7)\n\tPADDD X15, X14\n\tPXOR  X14, X13\n\tMOVO  X13, X7\n\tPSLLL $0x07, X7\n\tPSRLL $0x19, X13\n\tPXOR  X7, X13\n\tMOVO  64(BP), X7\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc0\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x0c\n\tMOVO  X14, 64(BP)\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X14)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X3\n\tPXOR  X14, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X14)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X3\n\tPXOR  X14, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X14)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X4\n\tPXOR  X14, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X14)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X4\n\tPXOR  X14, X4\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL16(X11, X14)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X5\n\tPXOR  X14, X5\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL8(X11, X14)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X5\n\tPXOR  X14, X5\n\tMOVO  64(BP), X14\n\tMOVO  X7, 64(BP)\n\tPADDD X13, X12\n\tPXOR  X12, X15\n\tROL16(X15, X7)\n\tPADDD X15, X14\n\tPXOR  X14, X13\n\tMOVO  X13, X7\n\tPSLLL $0x0c, X7\n\tPSRLL $0x14, X13\n\tPXOR  X7, X13\n\tPADDD X13, X12\n\tPXOR  X12, X15\n\tROL8(X15, X7)\n\tPADDD X15, X14\n\tPXOR  X14, X13\n\tMOVO  X13, X7\n\tPSLLL $0x07, X7\n\tPSRLL $0x19, X13\n\tPXOR  X7, X13\n\tMOVO  64(BP), X7\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc0\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x04\n\tDECQ  R9\n\tJNE   sealSSEIntroLoop\n\n\t// Add in the state\n\tPADDD ·chacha20Constants<>+0(SB), X0\n\tPADDD ·chacha20Constants<>+0(SB), X1\n\tPADDD ·chacha20Constants<>+0(SB), X2\n\tPADDD ·chacha20Constants<>+0(SB), X12\n\tPADDD 32(BP), X3\n\tPADDD 32(BP), X4\n\tPADDD 32(BP), X5\n\tPADDD 32(BP), X13\n\tPADDD 48(BP), X7\n\tPADDD 48(BP), X8\n\tPADDD 48(BP), X14\n\tPADDD 96(BP), X10\n\tPADDD 112(BP), X11\n\tPADDD 128(BP), X15\n\n\t// Clamp and store the key\n\tPAND ·polyClampMask<>+0(SB), X0\n\tMOVO X0, (BP)\n\tMOVO X3, 16(BP)\n\n\t// Hash AAD\n\tMOVQ  ad_len+80(FP), R9\n\tCALL  polyHashADInternal<>(SB)\n\tMOVOU (SI), X0\n\tMOVOU 16(SI), X3\n\tMOVOU 32(SI), X6\n\tMOVOU 48(SI), X9\n\tPXOR  X0, X1\n\tPXOR  X3, X4\n\tPXOR  X6, X7\n\tPXOR  X9, X10\n\tMOVOU X1, (DI)\n\tMOVOU X4, 16(DI)\n\tMOVOU X7, 32(DI)\n\tMOVOU X10, 48(DI)\n\tMOVOU 64(SI), X0\n\tMOVOU 80(SI), X3\n\tMOVOU 96(SI), X6\n\tMOVOU 112(SI), X9\n\tPXOR  X0, X2\n\tPXOR  X3, X5\n\tPXOR  X6, X8\n\tPXOR  X9, X11\n\tMOVOU X2, 64(DI)\n\tMOVOU X5, 80(DI)\n\tMOVOU X8, 96(DI)\n\tMOVOU X11, 112(DI)\n\tMOVQ  $0x00000080, CX\n\tSUBQ  $0x80, BX\n\tLEAQ  128(SI), SI\n\tMOVO  X12, X1\n\tMOVO  X13, X4\n\tMOVO  X14, X7\n\tMOVO  X15, X10\n\tCMPQ  BX, $0x40\n\tJBE   sealSSE128SealHash\n\tMOVOU (SI), X0\n\tMOVOU 16(SI), X3\n\tMOVOU 32(SI), X6\n\tMOVOU 48(SI), X9\n\tPXOR  X0, X12\n\tPXOR  X3, X13\n\tPXOR  X6, X14\n\tPXOR  X9, X15\n\tMOVOU X12, 128(DI)\n\tMOVOU X13, 144(DI)\n\tMOVOU X14, 160(DI)\n\tMOVOU X15, 176(DI)\n\tADDQ  $0x40, CX\n\tSUBQ  $0x40, BX\n\tLEAQ  64(SI), SI\n\tMOVQ  $0x00000002, CX\n\tMOVQ  $0x00000008, R9\n\tCMPQ  BX, $0x40\n\tJBE   sealSSETail64\n\tCMPQ  BX, $0x80\n\tJBE   sealSSETail128\n\tCMPQ  BX, $0xc0\n\tJBE   sealSSETail192\n\nsealSSEMainLoop:\n\t// Load state, increment counter blocks\n\tMOVO  ·chacha20Constants<>+0(SB), X0\n\tMOVO  32(BP), X3\n\tMOVO  48(BP), X6\n\tMOVO  128(BP), X9\n\tPADDL ·sseIncMask<>+0(SB), X9\n\tMOVO  X0, X1\n\tMOVO  X3, X4\n\tMOVO  X6, X7\n\tMOVO  X9, X10\n\tPADDL ·sseIncMask<>+0(SB), X10\n\tMOVO  X1, X2\n\tMOVO  X4, X5\n\tMOVO  X7, X8\n\tMOVO  X10, X11\n\tPADDL ·sseIncMask<>+0(SB), X11\n\tMOVO  X2, X12\n\tMOVO  X5, X13\n\tMOVO  X8, X14\n\tMOVO  X11, X15\n\tPADDL ·sseIncMask<>+0(SB), X15\n\n\t// Store counters\n\tMOVO X9, 80(BP)\n\tMOVO X10, 96(BP)\n\tMOVO X11, 112(BP)\n\tMOVO X15, 128(BP)\n\nsealSSEInnerLoop:\n\tMOVO  X14, 64(BP)\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X14)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X3\n\tPXOR  X14, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X14)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X3\n\tPXOR  X14, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X14)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X4\n\tPXOR  X14, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X14)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X4\n\tPXOR  X14, X4\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL16(X11, X14)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X5\n\tPXOR  X14, X5\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL8(X11, X14)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X5\n\tPXOR  X14, X5\n\tMOVO  64(BP), X14\n\tMOVO  X7, 64(BP)\n\tPADDD X13, X12\n\tPXOR  X12, X15\n\tROL16(X15, X7)\n\tPADDD X15, X14\n\tPXOR  X14, X13\n\tMOVO  X13, X7\n\tPSLLL $0x0c, X7\n\tPSRLL $0x14, X13\n\tPXOR  X7, X13\n\tPADDD X13, X12\n\tPXOR  X12, X15\n\tROL8(X15, X7)\n\tPADDD X15, X14\n\tPXOR  X14, X13\n\tMOVO  X13, X7\n\tPSLLL $0x07, X7\n\tPSRLL $0x19, X13\n\tPXOR  X7, X13\n\tMOVO  64(BP), X7\n\tADDQ  (DI), R10\n\tADCQ  8(DI), R11\n\tADCQ  $0x01, R12\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc0\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x0c\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tLEAQ  16(DI), DI\n\tMOVO  X14, 64(BP)\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X14)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X3\n\tPXOR  X14, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X14)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X3\n\tPXOR  X14, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X14)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X4\n\tPXOR  X14, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X14)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X4\n\tPXOR  X14, X4\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL16(X11, X14)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X14\n\tPSLLL $0x0c, X14\n\tPSRLL $0x14, X5\n\tPXOR  X14, X5\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL8(X11, X14)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X14\n\tPSLLL $0x07, X14\n\tPSRLL $0x19, X5\n\tPXOR  X14, X5\n\tMOVO  64(BP), X14\n\tMOVO  X7, 64(BP)\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tPADDD X13, X12\n\tPXOR  X12, X15\n\tROL16(X15, X7)\n\tPADDD X15, X14\n\tPXOR  X14, X13\n\tMOVO  X13, X7\n\tPSLLL $0x0c, X7\n\tPSRLL $0x14, X13\n\tPXOR  X7, X13\n\tPADDD X13, X12\n\tPXOR  X12, X15\n\tROL8(X15, X7)\n\tPADDD X15, X14\n\tPXOR  X14, X13\n\tMOVO  X13, X7\n\tPSLLL $0x07, X7\n\tPSRLL $0x19, X13\n\tPXOR  X7, X13\n\tMOVO  64(BP), X7\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc0\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x04\n\tDECQ  R9\n\tJGE   sealSSEInnerLoop\n\tADDQ  (DI), R10\n\tADCQ  8(DI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(DI), DI\n\tDECQ  CX\n\tJG    sealSSEInnerLoop\n\n\t// Add in the state\n\tPADDD ·chacha20Constants<>+0(SB), X0\n\tPADDD ·chacha20Constants<>+0(SB), X1\n\tPADDD ·chacha20Constants<>+0(SB), X2\n\tPADDD ·chacha20Constants<>+0(SB), X12\n\tPADDD 32(BP), X3\n\tPADDD 32(BP), X4\n\tPADDD 32(BP), X5\n\tPADDD 32(BP), X13\n\tPADDD 48(BP), X6\n\tPADDD 48(BP), X7\n\tPADDD 48(BP), X8\n\tPADDD 48(BP), X14\n\tPADDD 80(BP), X9\n\tPADDD 96(BP), X10\n\tPADDD 112(BP), X11\n\tPADDD 128(BP), X15\n\tMOVO  X15, 64(BP)\n\n\t// Load - xor - store\n\tMOVOU (SI), X15\n\tPXOR  X15, X0\n\tMOVOU 16(SI), X15\n\tPXOR  X15, X3\n\tMOVOU 32(SI), X15\n\tPXOR  X15, X6\n\tMOVOU 48(SI), X15\n\tPXOR  X15, X9\n\tMOVOU X0, (DI)\n\tMOVOU X3, 16(DI)\n\tMOVOU X6, 32(DI)\n\tMOVOU X9, 48(DI)\n\tMOVO  64(BP), X15\n\tMOVOU 64(SI), X0\n\tMOVOU 80(SI), X3\n\tMOVOU 96(SI), X6\n\tMOVOU 112(SI), X9\n\tPXOR  X0, X1\n\tPXOR  X3, X4\n\tPXOR  X6, X7\n\tPXOR  X9, X10\n\tMOVOU X1, 64(DI)\n\tMOVOU X4, 80(DI)\n\tMOVOU X7, 96(DI)\n\tMOVOU X10, 112(DI)\n\tMOVOU 128(SI), X0\n\tMOVOU 144(SI), X3\n\tMOVOU 160(SI), X6\n\tMOVOU 176(SI), X9\n\tPXOR  X0, X2\n\tPXOR  X3, X5\n\tPXOR  X6, X8\n\tPXOR  X9, X11\n\tMOVOU X2, 128(DI)\n\tMOVOU X5, 144(DI)\n\tMOVOU X8, 160(DI)\n\tMOVOU X11, 176(DI)\n\tADDQ  $0xc0, SI\n\tMOVQ  $0x000000c0, CX\n\tSUBQ  $0xc0, BX\n\tMOVO  X12, X1\n\tMOVO  X13, X4\n\tMOVO  X14, X7\n\tMOVO  X15, X10\n\tCMPQ  BX, $0x40\n\tJBE   sealSSE128SealHash\n\tMOVOU (SI), X0\n\tMOVOU 16(SI), X3\n\tMOVOU 32(SI), X6\n\tMOVOU 48(SI), X9\n\tPXOR  X0, X12\n\tPXOR  X3, X13\n\tPXOR  X6, X14\n\tPXOR  X9, X15\n\tMOVOU X12, 192(DI)\n\tMOVOU X13, 208(DI)\n\tMOVOU X14, 224(DI)\n\tMOVOU X15, 240(DI)\n\tLEAQ  64(SI), SI\n\tSUBQ  $0x40, BX\n\tMOVQ  $0x00000006, CX\n\tMOVQ  $0x00000004, R9\n\tCMPQ  BX, $0xc0\n\tJG    sealSSEMainLoop\n\tMOVQ  BX, CX\n\tTESTQ BX, BX\n\tJE    sealSSE128SealHash\n\tMOVQ  $0x00000006, CX\n\tCMPQ  BX, $0x40\n\tJBE   sealSSETail64\n\tCMPQ  BX, $0x80\n\tJBE   sealSSETail128\n\tJMP   sealSSETail192\n\nsealSSETail64:\n\tMOVO  ·chacha20Constants<>+0(SB), X1\n\tMOVO  32(BP), X4\n\tMOVO  48(BP), X7\n\tMOVO  128(BP), X10\n\tPADDL ·sseIncMask<>+0(SB), X10\n\tMOVO  X10, 80(BP)\n\nsealSSETail64LoopA:\n\tADDQ  (DI), R10\n\tADCQ  8(DI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(DI), DI\n\nsealSSETail64LoopB:\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X13)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X13\n\tPSLLL $0x0c, X13\n\tPSRLL $0x14, X4\n\tPXOR  X13, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X13)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X13\n\tPSLLL $0x07, X13\n\tPSRLL $0x19, X4\n\tPXOR  X13, X4\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x0c\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X13)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X13\n\tPSLLL $0x0c, X13\n\tPSRLL $0x14, X4\n\tPXOR  X13, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X13)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X13\n\tPSLLL $0x07, X13\n\tPSRLL $0x19, X4\n\tPXOR  X13, X4\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x04\n\tADDQ  (DI), R10\n\tADCQ  8(DI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(DI), DI\n\tDECQ  CX\n\tJG    sealSSETail64LoopA\n\tDECQ  R9\n\tJGE   sealSSETail64LoopB\n\tPADDL ·chacha20Constants<>+0(SB), X1\n\tPADDL 32(BP), X4\n\tPADDL 48(BP), X7\n\tPADDL 80(BP), X10\n\tJMP   sealSSE128Seal\n\nsealSSETail128:\n\tMOVO  ·chacha20Constants<>+0(SB), X0\n\tMOVO  32(BP), X3\n\tMOVO  48(BP), X6\n\tMOVO  128(BP), X9\n\tPADDL ·sseIncMask<>+0(SB), X9\n\tMOVO  X9, 80(BP)\n\tMOVO  X0, X1\n\tMOVO  X3, X4\n\tMOVO  X6, X7\n\tMOVO  X9, X10\n\tPADDL ·sseIncMask<>+0(SB), X10\n\tMOVO  X10, 96(BP)\n\nsealSSETail128LoopA:\n\tADDQ  (DI), R10\n\tADCQ  8(DI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(DI), DI\n\nsealSSETail128LoopB:\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X3\n\tPXOR  X12, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X3\n\tPXOR  X12, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X4\n\tPXOR  X12, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X4\n\tPXOR  X12, X4\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x0c\n\tADDQ  (DI), R10\n\tADCQ  8(DI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(DI), DI\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X3\n\tPXOR  X12, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X3\n\tPXOR  X12, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X4\n\tPXOR  X12, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X4\n\tPXOR  X12, X4\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x04\n\tDECQ  CX\n\tJG    sealSSETail128LoopA\n\tDECQ  R9\n\tJGE   sealSSETail128LoopB\n\tPADDL ·chacha20Constants<>+0(SB), X0\n\tPADDL ·chacha20Constants<>+0(SB), X1\n\tPADDL 32(BP), X3\n\tPADDL 32(BP), X4\n\tPADDL 48(BP), X6\n\tPADDL 48(BP), X7\n\tPADDL 80(BP), X9\n\tPADDL 96(BP), X10\n\tMOVOU (SI), X12\n\tMOVOU 16(SI), X13\n\tMOVOU 32(SI), X14\n\tMOVOU 48(SI), X15\n\tPXOR  X12, X0\n\tPXOR  X13, X3\n\tPXOR  X14, X6\n\tPXOR  X15, X9\n\tMOVOU X0, (DI)\n\tMOVOU X3, 16(DI)\n\tMOVOU X6, 32(DI)\n\tMOVOU X9, 48(DI)\n\tMOVQ  $0x00000040, CX\n\tLEAQ  64(SI), SI\n\tSUBQ  $0x40, BX\n\tJMP   sealSSE128SealHash\n\nsealSSETail192:\n\tMOVO  ·chacha20Constants<>+0(SB), X0\n\tMOVO  32(BP), X3\n\tMOVO  48(BP), X6\n\tMOVO  128(BP), X9\n\tPADDL ·sseIncMask<>+0(SB), X9\n\tMOVO  X9, 80(BP)\n\tMOVO  X0, X1\n\tMOVO  X3, X4\n\tMOVO  X6, X7\n\tMOVO  X9, X10\n\tPADDL ·sseIncMask<>+0(SB), X10\n\tMOVO  X10, 96(BP)\n\tMOVO  X1, X2\n\tMOVO  X4, X5\n\tMOVO  X7, X8\n\tMOVO  X10, X11\n\tPADDL ·sseIncMask<>+0(SB), X11\n\tMOVO  X11, 112(BP)\n\nsealSSETail192LoopA:\n\tADDQ  (DI), R10\n\tADCQ  8(DI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(DI), DI\n\nsealSSETail192LoopB:\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X3\n\tPXOR  X12, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X3\n\tPXOR  X12, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X4\n\tPXOR  X12, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X4\n\tPXOR  X12, X4\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL16(X11, X12)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X5\n\tPXOR  X12, X5\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL8(X11, X12)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X5\n\tPXOR  X12, X5\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc0\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tADDQ  (DI), R10\n\tADCQ  8(DI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(DI), DI\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X3\n\tPXOR  X12, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X3\n\tPXOR  X12, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X4\n\tPXOR  X12, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X4\n\tPXOR  X12, X4\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL16(X11, X12)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X5\n\tPXOR  X12, X5\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL8(X11, X12)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X5\n\tPXOR  X12, X5\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc0\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tDECQ  CX\n\tJG    sealSSETail192LoopA\n\tDECQ  R9\n\tJGE   sealSSETail192LoopB\n\tPADDL ·chacha20Constants<>+0(SB), X0\n\tPADDL ·chacha20Constants<>+0(SB), X1\n\tPADDL ·chacha20Constants<>+0(SB), X2\n\tPADDL 32(BP), X3\n\tPADDL 32(BP), X4\n\tPADDL 32(BP), X5\n\tPADDL 48(BP), X6\n\tPADDL 48(BP), X7\n\tPADDL 48(BP), X8\n\tPADDL 80(BP), X9\n\tPADDL 96(BP), X10\n\tPADDL 112(BP), X11\n\tMOVOU (SI), X12\n\tMOVOU 16(SI), X13\n\tMOVOU 32(SI), X14\n\tMOVOU 48(SI), X15\n\tPXOR  X12, X0\n\tPXOR  X13, X3\n\tPXOR  X14, X6\n\tPXOR  X15, X9\n\tMOVOU X0, (DI)\n\tMOVOU X3, 16(DI)\n\tMOVOU X6, 32(DI)\n\tMOVOU X9, 48(DI)\n\tMOVOU 64(SI), X12\n\tMOVOU 80(SI), X13\n\tMOVOU 96(SI), X14\n\tMOVOU 112(SI), X15\n\tPXOR  X12, X1\n\tPXOR  X13, X4\n\tPXOR  X14, X7\n\tPXOR  X15, X10\n\tMOVOU X1, 64(DI)\n\tMOVOU X4, 80(DI)\n\tMOVOU X7, 96(DI)\n\tMOVOU X10, 112(DI)\n\tMOVO  X2, X1\n\tMOVO  X5, X4\n\tMOVO  X8, X7\n\tMOVO  X11, X10\n\tMOVQ  $0x00000080, CX\n\tLEAQ  128(SI), SI\n\tSUBQ  $0x80, BX\n\tJMP   sealSSE128SealHash\n\nsealSSE128:\n\tMOVOU ·chacha20Constants<>+0(SB), X0\n\tMOVOU 16(R8), X3\n\tMOVOU 32(R8), X6\n\tMOVOU 48(R8), X9\n\tMOVO  X0, X1\n\tMOVO  X3, X4\n\tMOVO  X6, X7\n\tMOVO  X9, X10\n\tPADDL ·sseIncMask<>+0(SB), X10\n\tMOVO  X1, X2\n\tMOVO  X4, X5\n\tMOVO  X7, X8\n\tMOVO  X10, X11\n\tPADDL ·sseIncMask<>+0(SB), X11\n\tMOVO  X3, X13\n\tMOVO  X6, X14\n\tMOVO  X10, X15\n\tMOVQ  $0x0000000a, R9\n\nsealSSE128InnerCipherLoop:\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X3\n\tPXOR  X12, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X3\n\tPXOR  X12, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X4\n\tPXOR  X12, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X4\n\tPXOR  X12, X4\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL16(X11, X12)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X5\n\tPXOR  X12, X5\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL8(X11, X12)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X5\n\tPXOR  X12, X5\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc0\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL16(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X3\n\tPXOR  X12, X3\n\tPADDD X3, X0\n\tPXOR  X0, X9\n\tROL8(X9, X12)\n\tPADDD X9, X6\n\tPXOR  X6, X3\n\tMOVO  X3, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X3\n\tPXOR  X12, X3\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL16(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X4\n\tPXOR  X12, X4\n\tPADDD X4, X1\n\tPXOR  X1, X10\n\tROL8(X10, X12)\n\tPADDD X10, X7\n\tPXOR  X7, X4\n\tMOVO  X4, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X4\n\tPXOR  X12, X4\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL16(X11, X12)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X12\n\tPSLLL $0x0c, X12\n\tPSRLL $0x14, X5\n\tPXOR  X12, X5\n\tPADDD X5, X2\n\tPXOR  X2, X11\n\tROL8(X11, X12)\n\tPADDD X11, X8\n\tPXOR  X8, X5\n\tMOVO  X5, X12\n\tPSLLL $0x07, X12\n\tPSRLL $0x19, X5\n\tPXOR  X12, X5\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xe4\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xed\n\tBYTE  $0x0c\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xf6\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xff\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc0\n\tBYTE  $0x08\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xc9\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xd2\n\tBYTE  $0x04\n\tBYTE  $0x66\n\tBYTE  $0x45\n\tBYTE  $0x0f\n\tBYTE  $0x3a\n\tBYTE  $0x0f\n\tBYTE  $0xdb\n\tBYTE  $0x04\n\tDECQ  R9\n\tJNE   sealSSE128InnerCipherLoop\n\n\t// A0|B0 hold the Poly1305 32-byte key, C0,D0 can be discarded\n\tPADDL ·chacha20Constants<>+0(SB), X0\n\tPADDL ·chacha20Constants<>+0(SB), X1\n\tPADDL ·chacha20Constants<>+0(SB), X2\n\tPADDL X13, X3\n\tPADDL X13, X4\n\tPADDL X13, X5\n\tPADDL X14, X7\n\tPADDL X14, X8\n\tPADDL X15, X10\n\tPADDL ·sseIncMask<>+0(SB), X15\n\tPADDL X15, X11\n\tPAND  ·polyClampMask<>+0(SB), X0\n\tMOVOU X0, (BP)\n\tMOVOU X3, 16(BP)\n\n\t// Hash\n\tMOVQ ad_len+80(FP), R9\n\tCALL polyHashADInternal<>(SB)\n\tXORQ CX, CX\n\nsealSSE128SealHash:\n\tCMPQ  CX, $0x10\n\tJB    sealSSE128Seal\n\tADDQ  (DI), R10\n\tADCQ  8(DI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tSUBQ  $0x10, CX\n\tADDQ  $0x10, DI\n\tJMP   sealSSE128SealHash\n\nsealSSE128Seal:\n\tCMPQ BX, $0x10\n\tJB   sealSSETail\n\tSUBQ $0x10, BX\n\n\t// Load for decryption\n\tMOVOU (SI), X12\n\tPXOR  X12, X1\n\tMOVOU X1, (DI)\n\tLEAQ  16(SI), SI\n\tLEAQ  16(DI), DI\n\n\t// Extract for hashing\n\tMOVQ   X1, R13\n\tPSRLDQ $0x08, X1\n\tMOVQ   X1, R14\n\tADDQ   R13, R10\n\tADCQ   R14, R11\n\tADCQ   $0x01, R12\n\tMOVQ   (BP), AX\n\tMOVQ   AX, R15\n\tMULQ   R10\n\tMOVQ   AX, R13\n\tMOVQ   DX, R14\n\tMOVQ   (BP), AX\n\tMULQ   R11\n\tIMULQ  R12, R15\n\tADDQ   AX, R14\n\tADCQ   DX, R15\n\tMOVQ   8(BP), AX\n\tMOVQ   AX, R8\n\tMULQ   R10\n\tADDQ   AX, R14\n\tADCQ   $0x00, DX\n\tMOVQ   DX, R10\n\tMOVQ   8(BP), AX\n\tMULQ   R11\n\tADDQ   AX, R15\n\tADCQ   $0x00, DX\n\tIMULQ  R12, R8\n\tADDQ   R10, R15\n\tADCQ   DX, R8\n\tMOVQ   R13, R10\n\tMOVQ   R14, R11\n\tMOVQ   R15, R12\n\tANDQ   $0x03, R12\n\tMOVQ   R15, R13\n\tANDQ   $-4, R13\n\tMOVQ   R8, R14\n\tSHRQ   $0x02, R8, R15\n\tSHRQ   $0x02, R8\n\tADDQ   R13, R10\n\tADCQ   R14, R11\n\tADCQ   $0x00, R12\n\tADDQ   R15, R10\n\tADCQ   R8, R11\n\tADCQ   $0x00, R12\n\n\t// Shift the stream \"left\"\n\tMOVO X4, X1\n\tMOVO X7, X4\n\tMOVO X10, X7\n\tMOVO X2, X10\n\tMOVO X5, X2\n\tMOVO X8, X5\n\tMOVO X11, X8\n\tJMP  sealSSE128Seal\n\nsealSSETail:\n\tTESTQ BX, BX\n\tJE    sealSSEFinalize\n\n\t// We can only load the PT one byte at a time to avoid read after end of buffer\n\tMOVQ BX, R9\n\tSHLQ $0x04, R9\n\tLEAQ ·andMask<>+0(SB), R13\n\tMOVQ BX, CX\n\tLEAQ -1(SI)(BX*1), SI\n\tXORQ R15, R15\n\tXORQ R8, R8\n\tXORQ AX, AX\n\nsealSSETailLoadLoop:\n\tSHLQ   $0x08, R15, R8\n\tSHLQ   $0x08, R15\n\tMOVB   (SI), AX\n\tXORQ   AX, R15\n\tLEAQ   -1(SI), SI\n\tDECQ   CX\n\tJNE    sealSSETailLoadLoop\n\tMOVQ   R15, 64(BP)\n\tMOVQ   R8, 72(BP)\n\tPXOR   64(BP), X1\n\tMOVOU  X1, (DI)\n\tMOVOU  -16(R13)(R9*1), X12\n\tPAND   X12, X1\n\tMOVQ   X1, R13\n\tPSRLDQ $0x08, X1\n\tMOVQ   X1, R14\n\tADDQ   R13, R10\n\tADCQ   R14, R11\n\tADCQ   $0x01, R12\n\tMOVQ   (BP), AX\n\tMOVQ   AX, R15\n\tMULQ   R10\n\tMOVQ   AX, R13\n\tMOVQ   DX, R14\n\tMOVQ   (BP), AX\n\tMULQ   R11\n\tIMULQ  R12, R15\n\tADDQ   AX, R14\n\tADCQ   DX, R15\n\tMOVQ   8(BP), AX\n\tMOVQ   AX, R8\n\tMULQ   R10\n\tADDQ   AX, R14\n\tADCQ   $0x00, DX\n\tMOVQ   DX, R10\n\tMOVQ   8(BP), AX\n\tMULQ   R11\n\tADDQ   AX, R15\n\tADCQ   $0x00, DX\n\tIMULQ  R12, R8\n\tADDQ   R10, R15\n\tADCQ   DX, R8\n\tMOVQ   R13, R10\n\tMOVQ   R14, R11\n\tMOVQ   R15, R12\n\tANDQ   $0x03, R12\n\tMOVQ   R15, R13\n\tANDQ   $-4, R13\n\tMOVQ   R8, R14\n\tSHRQ   $0x02, R8, R15\n\tSHRQ   $0x02, R8\n\tADDQ   R13, R10\n\tADCQ   R14, R11\n\tADCQ   $0x00, R12\n\tADDQ   R15, R10\n\tADCQ   R8, R11\n\tADCQ   $0x00, R12\n\tADDQ   BX, DI\n\nsealSSEFinalize:\n\t// Hash in the buffer lengths\n\tADDQ  ad_len+80(FP), R10\n\tADCQ  src_len+56(FP), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\n\t// Final reduce\n\tMOVQ    R10, R13\n\tMOVQ    R11, R14\n\tMOVQ    R12, R15\n\tSUBQ    $-5, R10\n\tSBBQ    $-1, R11\n\tSBBQ    $0x03, R12\n\tCMOVQCS R13, R10\n\tCMOVQCS R14, R11\n\tCMOVQCS R15, R12\n\n\t// Add in the \"s\" part of the key\n\tADDQ 16(BP), R10\n\tADCQ 24(BP), R11\n\n\t// Finally store the tag at the end of the message\n\tMOVQ R10, (DI)\n\tMOVQ R11, 8(DI)\n\tRET\n\nchacha20Poly1305Seal_AVX2:\n\tVZEROUPPER\n\tVMOVDQU ·chacha20Constants<>+0(SB), Y0\n\tBYTE    $0xc4\n\tBYTE    $0x42\n\tBYTE    $0x7d\n\tBYTE    $0x5a\n\tBYTE    $0x70\n\tBYTE    $0x10\n\tBYTE    $0xc4\n\tBYTE    $0x42\n\tBYTE    $0x7d\n\tBYTE    $0x5a\n\tBYTE    $0x60\n\tBYTE    $0x20\n\tBYTE    $0xc4\n\tBYTE    $0xc2\n\tBYTE    $0x7d\n\tBYTE    $0x5a\n\tBYTE    $0x60\n\tBYTE    $0x30\n\tVPADDD  ·avx2InitMask<>+0(SB), Y4, Y4\n\n\t// Special optimizations, for very short buffers\n\tCMPQ BX, $0x000000c0\n\tJBE  seal192AVX2\n\tCMPQ BX, $0x00000140\n\tJBE  seal320AVX2\n\n\t// For the general key prepare the key first - as a byproduct we have 64 bytes of cipher stream\n\tVMOVDQA Y0, Y5\n\tVMOVDQA Y0, Y6\n\tVMOVDQA Y0, Y7\n\tVMOVDQA Y14, Y9\n\tVMOVDQA Y14, Y10\n\tVMOVDQA Y14, Y11\n\tVMOVDQA Y14, 32(BP)\n\tVMOVDQA Y12, Y13\n\tVMOVDQA Y12, Y8\n\tVMOVDQA Y12, Y15\n\tVMOVDQA Y12, 64(BP)\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y1\n\tVMOVDQA Y4, 96(BP)\n\tVPADDD  ·avx2IncMask<>+0(SB), Y1, Y2\n\tVMOVDQA Y1, 128(BP)\n\tVPADDD  ·avx2IncMask<>+0(SB), Y2, Y3\n\tVMOVDQA Y2, 160(BP)\n\tVMOVDQA Y3, 192(BP)\n\tMOVQ    $0x0000000a, R9\n\nsealAVX2IntroLoop:\n\tVMOVDQA    Y15, 224(BP)\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol16<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x0c, Y14, Y15\n\tVPSRLD     $0x14, Y14, Y14\n\tVPXOR      Y15, Y14, Y14\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol8<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x07, Y14, Y15\n\tVPSRLD     $0x19, Y14, Y14\n\tVPXOR      Y15, Y14, Y14\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol16<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x0c, Y9, Y15\n\tVPSRLD     $0x14, Y9, Y9\n\tVPXOR      Y15, Y9, Y9\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol8<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x07, Y9, Y15\n\tVPSRLD     $0x19, Y9, Y9\n\tVPXOR      Y15, Y9, Y9\n\tVPADDD     Y10, Y6, Y6\n\tVPXOR      Y6, Y2, Y2\n\tVPSHUFB    ·rol16<>+0(SB), Y2, Y2\n\tVPADDD     Y2, Y8, Y8\n\tVPXOR      Y8, Y10, Y10\n\tVPSLLD     $0x0c, Y10, Y15\n\tVPSRLD     $0x14, Y10, Y10\n\tVPXOR      Y15, Y10, Y10\n\tVPADDD     Y10, Y6, Y6\n\tVPXOR      Y6, Y2, Y2\n\tVPSHUFB    ·rol8<>+0(SB), Y2, Y2\n\tVPADDD     Y2, Y8, Y8\n\tVPXOR      Y8, Y10, Y10\n\tVPSLLD     $0x07, Y10, Y15\n\tVPSRLD     $0x19, Y10, Y10\n\tVPXOR      Y15, Y10, Y10\n\tVMOVDQA    224(BP), Y15\n\tVMOVDQA    Y13, 224(BP)\n\tVPADDD     Y11, Y7, Y7\n\tVPXOR      Y7, Y3, Y3\n\tVPSHUFB    ·rol16<>+0(SB), Y3, Y3\n\tVPADDD     Y3, Y15, Y15\n\tVPXOR      Y15, Y11, Y11\n\tVPSLLD     $0x0c, Y11, Y13\n\tVPSRLD     $0x14, Y11, Y11\n\tVPXOR      Y13, Y11, Y11\n\tVPADDD     Y11, Y7, Y7\n\tVPXOR      Y7, Y3, Y3\n\tVPSHUFB    ·rol8<>+0(SB), Y3, Y3\n\tVPADDD     Y3, Y15, Y15\n\tVPXOR      Y15, Y11, Y11\n\tVPSLLD     $0x07, Y11, Y13\n\tVPSRLD     $0x19, Y11, Y11\n\tVPXOR      Y13, Y11, Y11\n\tVMOVDQA    224(BP), Y13\n\tVPALIGNR   $0x04, Y14, Y14, Y14\n\tVPALIGNR   $0x08, Y12, Y12, Y12\n\tVPALIGNR   $0x0c, Y4, Y4, Y4\n\tVPALIGNR   $0x04, Y9, Y9, Y9\n\tVPALIGNR   $0x08, Y13, Y13, Y13\n\tVPALIGNR   $0x0c, Y1, Y1, Y1\n\tVPALIGNR   $0x04, Y10, Y10, Y10\n\tVPALIGNR   $0x08, Y8, Y8, Y8\n\tVPALIGNR   $0x0c, Y2, Y2, Y2\n\tVPALIGNR   $0x04, Y11, Y11, Y11\n\tVPALIGNR   $0x08, Y15, Y15, Y15\n\tVPALIGNR   $0x0c, Y3, Y3, Y3\n\tVMOVDQA    Y15, 224(BP)\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol16<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x0c, Y14, Y15\n\tVPSRLD     $0x14, Y14, Y14\n\tVPXOR      Y15, Y14, Y14\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol8<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x07, Y14, Y15\n\tVPSRLD     $0x19, Y14, Y14\n\tVPXOR      Y15, Y14, Y14\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol16<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x0c, Y9, Y15\n\tVPSRLD     $0x14, Y9, Y9\n\tVPXOR      Y15, Y9, Y9\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol8<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x07, Y9, Y15\n\tVPSRLD     $0x19, Y9, Y9\n\tVPXOR      Y15, Y9, Y9\n\tVPADDD     Y10, Y6, Y6\n\tVPXOR      Y6, Y2, Y2\n\tVPSHUFB    ·rol16<>+0(SB), Y2, Y2\n\tVPADDD     Y2, Y8, Y8\n\tVPXOR      Y8, Y10, Y10\n\tVPSLLD     $0x0c, Y10, Y15\n\tVPSRLD     $0x14, Y10, Y10\n\tVPXOR      Y15, Y10, Y10\n\tVPADDD     Y10, Y6, Y6\n\tVPXOR      Y6, Y2, Y2\n\tVPSHUFB    ·rol8<>+0(SB), Y2, Y2\n\tVPADDD     Y2, Y8, Y8\n\tVPXOR      Y8, Y10, Y10\n\tVPSLLD     $0x07, Y10, Y15\n\tVPSRLD     $0x19, Y10, Y10\n\tVPXOR      Y15, Y10, Y10\n\tVMOVDQA    224(BP), Y15\n\tVMOVDQA    Y13, 224(BP)\n\tVPADDD     Y11, Y7, Y7\n\tVPXOR      Y7, Y3, Y3\n\tVPSHUFB    ·rol16<>+0(SB), Y3, Y3\n\tVPADDD     Y3, Y15, Y15\n\tVPXOR      Y15, Y11, Y11\n\tVPSLLD     $0x0c, Y11, Y13\n\tVPSRLD     $0x14, Y11, Y11\n\tVPXOR      Y13, Y11, Y11\n\tVPADDD     Y11, Y7, Y7\n\tVPXOR      Y7, Y3, Y3\n\tVPSHUFB    ·rol8<>+0(SB), Y3, Y3\n\tVPADDD     Y3, Y15, Y15\n\tVPXOR      Y15, Y11, Y11\n\tVPSLLD     $0x07, Y11, Y13\n\tVPSRLD     $0x19, Y11, Y11\n\tVPXOR      Y13, Y11, Y11\n\tVMOVDQA    224(BP), Y13\n\tVPALIGNR   $0x0c, Y14, Y14, Y14\n\tVPALIGNR   $0x08, Y12, Y12, Y12\n\tVPALIGNR   $0x04, Y4, Y4, Y4\n\tVPALIGNR   $0x0c, Y9, Y9, Y9\n\tVPALIGNR   $0x08, Y13, Y13, Y13\n\tVPALIGNR   $0x04, Y1, Y1, Y1\n\tVPALIGNR   $0x0c, Y10, Y10, Y10\n\tVPALIGNR   $0x08, Y8, Y8, Y8\n\tVPALIGNR   $0x04, Y2, Y2, Y2\n\tVPALIGNR   $0x0c, Y11, Y11, Y11\n\tVPALIGNR   $0x08, Y15, Y15, Y15\n\tVPALIGNR   $0x04, Y3, Y3, Y3\n\tDECQ       R9\n\tJNE        sealAVX2IntroLoop\n\tVPADDD     ·chacha20Constants<>+0(SB), Y0, Y0\n\tVPADDD     ·chacha20Constants<>+0(SB), Y5, Y5\n\tVPADDD     ·chacha20Constants<>+0(SB), Y6, Y6\n\tVPADDD     ·chacha20Constants<>+0(SB), Y7, Y7\n\tVPADDD     32(BP), Y14, Y14\n\tVPADDD     32(BP), Y9, Y9\n\tVPADDD     32(BP), Y10, Y10\n\tVPADDD     32(BP), Y11, Y11\n\tVPADDD     64(BP), Y12, Y12\n\tVPADDD     64(BP), Y13, Y13\n\tVPADDD     64(BP), Y8, Y8\n\tVPADDD     64(BP), Y15, Y15\n\tVPADDD     96(BP), Y4, Y4\n\tVPADDD     128(BP), Y1, Y1\n\tVPADDD     160(BP), Y2, Y2\n\tVPADDD     192(BP), Y3, Y3\n\tVPERM2I128 $0x13, Y12, Y4, Y12\n\tVPERM2I128 $0x02, Y0, Y14, Y4\n\tVPERM2I128 $0x13, Y0, Y14, Y0\n\n\t// Clamp and store poly key\n\tVPAND   ·polyClampMask<>+0(SB), Y4, Y4\n\tVMOVDQA Y4, (BP)\n\n\t// Hash AD\n\tMOVQ ad_len+80(FP), R9\n\tCALL polyHashADInternal<>(SB)\n\n\t// Can store at least 320 bytes\n\tVPXOR      (SI), Y0, Y0\n\tVPXOR      32(SI), Y12, Y12\n\tVMOVDQU    Y0, (DI)\n\tVMOVDQU    Y12, 32(DI)\n\tVPERM2I128 $0x02, Y5, Y9, Y0\n\tVPERM2I128 $0x02, Y13, Y1, Y14\n\tVPERM2I128 $0x13, Y5, Y9, Y12\n\tVPERM2I128 $0x13, Y13, Y1, Y4\n\tVPXOR      64(SI), Y0, Y0\n\tVPXOR      96(SI), Y14, Y14\n\tVPXOR      128(SI), Y12, Y12\n\tVPXOR      160(SI), Y4, Y4\n\tVMOVDQU    Y0, 64(DI)\n\tVMOVDQU    Y14, 96(DI)\n\tVMOVDQU    Y12, 128(DI)\n\tVMOVDQU    Y4, 160(DI)\n\tVPERM2I128 $0x02, Y6, Y10, Y0\n\tVPERM2I128 $0x02, Y8, Y2, Y14\n\tVPERM2I128 $0x13, Y6, Y10, Y12\n\tVPERM2I128 $0x13, Y8, Y2, Y4\n\tVPXOR      192(SI), Y0, Y0\n\tVPXOR      224(SI), Y14, Y14\n\tVPXOR      256(SI), Y12, Y12\n\tVPXOR      288(SI), Y4, Y4\n\tVMOVDQU    Y0, 192(DI)\n\tVMOVDQU    Y14, 224(DI)\n\tVMOVDQU    Y12, 256(DI)\n\tVMOVDQU    Y4, 288(DI)\n\tMOVQ       $0x00000140, CX\n\tSUBQ       $0x00000140, BX\n\tLEAQ       320(SI), SI\n\tVPERM2I128 $0x02, Y7, Y11, Y0\n\tVPERM2I128 $0x02, Y15, Y3, Y14\n\tVPERM2I128 $0x13, Y7, Y11, Y12\n\tVPERM2I128 $0x13, Y15, Y3, Y4\n\tCMPQ       BX, $0x80\n\tJBE        sealAVX2SealHash\n\tVPXOR      (SI), Y0, Y0\n\tVPXOR      32(SI), Y14, Y14\n\tVPXOR      64(SI), Y12, Y12\n\tVPXOR      96(SI), Y4, Y4\n\tVMOVDQU    Y0, 320(DI)\n\tVMOVDQU    Y14, 352(DI)\n\tVMOVDQU    Y12, 384(DI)\n\tVMOVDQU    Y4, 416(DI)\n\tSUBQ       $0x80, BX\n\tLEAQ       128(SI), SI\n\tMOVQ       $0x00000008, CX\n\tMOVQ       $0x00000002, R9\n\tCMPQ       BX, $0x80\n\tJBE        sealAVX2Tail128\n\tCMPQ       BX, $0x00000100\n\tJBE        sealAVX2Tail256\n\tCMPQ       BX, $0x00000180\n\tJBE        sealAVX2Tail384\n\tCMPQ       BX, $0x00000200\n\tJBE        sealAVX2Tail512\n\n\t// We have 448 bytes to hash, but main loop hashes 512 bytes at a time - perform some rounds, before the main loop\n\tVMOVDQA  ·chacha20Constants<>+0(SB), Y0\n\tVMOVDQA  Y0, Y5\n\tVMOVDQA  Y0, Y6\n\tVMOVDQA  Y0, Y7\n\tVMOVDQA  32(BP), Y14\n\tVMOVDQA  Y14, Y9\n\tVMOVDQA  Y14, Y10\n\tVMOVDQA  Y14, Y11\n\tVMOVDQA  64(BP), Y12\n\tVMOVDQA  Y12, Y13\n\tVMOVDQA  Y12, Y8\n\tVMOVDQA  Y12, Y15\n\tVMOVDQA  192(BP), Y4\n\tVPADDD   ·avx2IncMask<>+0(SB), Y4, Y4\n\tVPADDD   ·avx2IncMask<>+0(SB), Y4, Y1\n\tVPADDD   ·avx2IncMask<>+0(SB), Y1, Y2\n\tVPADDD   ·avx2IncMask<>+0(SB), Y2, Y3\n\tVMOVDQA  Y4, 96(BP)\n\tVMOVDQA  Y1, 128(BP)\n\tVMOVDQA  Y2, 160(BP)\n\tVMOVDQA  Y3, 192(BP)\n\tVMOVDQA  Y15, 224(BP)\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol16<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x0c, Y14, Y15\n\tVPSRLD   $0x14, Y14, Y14\n\tVPXOR    Y15, Y14, Y14\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol8<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x07, Y14, Y15\n\tVPSRLD   $0x19, Y14, Y14\n\tVPXOR    Y15, Y14, Y14\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol16<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x0c, Y9, Y15\n\tVPSRLD   $0x14, Y9, Y9\n\tVPXOR    Y15, Y9, Y9\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol8<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x07, Y9, Y15\n\tVPSRLD   $0x19, Y9, Y9\n\tVPXOR    Y15, Y9, Y9\n\tVPADDD   Y10, Y6, Y6\n\tVPXOR    Y6, Y2, Y2\n\tVPSHUFB  ·rol16<>+0(SB), Y2, Y2\n\tVPADDD   Y2, Y8, Y8\n\tVPXOR    Y8, Y10, Y10\n\tVPSLLD   $0x0c, Y10, Y15\n\tVPSRLD   $0x14, Y10, Y10\n\tVPXOR    Y15, Y10, Y10\n\tVPADDD   Y10, Y6, Y6\n\tVPXOR    Y6, Y2, Y2\n\tVPSHUFB  ·rol8<>+0(SB), Y2, Y2\n\tVPADDD   Y2, Y8, Y8\n\tVPXOR    Y8, Y10, Y10\n\tVPSLLD   $0x07, Y10, Y15\n\tVPSRLD   $0x19, Y10, Y10\n\tVPXOR    Y15, Y10, Y10\n\tVMOVDQA  224(BP), Y15\n\tVMOVDQA  Y13, 224(BP)\n\tVPADDD   Y11, Y7, Y7\n\tVPXOR    Y7, Y3, Y3\n\tVPSHUFB  ·rol16<>+0(SB), Y3, Y3\n\tVPADDD   Y3, Y15, Y15\n\tVPXOR    Y15, Y11, Y11\n\tVPSLLD   $0x0c, Y11, Y13\n\tVPSRLD   $0x14, Y11, Y11\n\tVPXOR    Y13, Y11, Y11\n\tVPADDD   Y11, Y7, Y7\n\tVPXOR    Y7, Y3, Y3\n\tVPSHUFB  ·rol8<>+0(SB), Y3, Y3\n\tVPADDD   Y3, Y15, Y15\n\tVPXOR    Y15, Y11, Y11\n\tVPSLLD   $0x07, Y11, Y13\n\tVPSRLD   $0x19, Y11, Y11\n\tVPXOR    Y13, Y11, Y11\n\tVMOVDQA  224(BP), Y13\n\tVPALIGNR $0x04, Y14, Y14, Y14\n\tVPALIGNR $0x08, Y12, Y12, Y12\n\tVPALIGNR $0x0c, Y4, Y4, Y4\n\tVPALIGNR $0x04, Y9, Y9, Y9\n\tVPALIGNR $0x08, Y13, Y13, Y13\n\tVPALIGNR $0x0c, Y1, Y1, Y1\n\tVPALIGNR $0x04, Y10, Y10, Y10\n\tVPALIGNR $0x08, Y8, Y8, Y8\n\tVPALIGNR $0x0c, Y2, Y2, Y2\n\tVPALIGNR $0x04, Y11, Y11, Y11\n\tVPALIGNR $0x08, Y15, Y15, Y15\n\tVPALIGNR $0x0c, Y3, Y3, Y3\n\tVMOVDQA  Y15, 224(BP)\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol16<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x0c, Y14, Y15\n\tVPSRLD   $0x14, Y14, Y14\n\tVPXOR    Y15, Y14, Y14\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol8<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x07, Y14, Y15\n\tVPSRLD   $0x19, Y14, Y14\n\tVPXOR    Y15, Y14, Y14\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol16<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x0c, Y9, Y15\n\tVPSRLD   $0x14, Y9, Y9\n\tVPXOR    Y15, Y9, Y9\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol8<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x07, Y9, Y15\n\tVPSRLD   $0x19, Y9, Y9\n\tVPXOR    Y15, Y9, Y9\n\tVPADDD   Y10, Y6, Y6\n\tVPXOR    Y6, Y2, Y2\n\tVPSHUFB  ·rol16<>+0(SB), Y2, Y2\n\tVPADDD   Y2, Y8, Y8\n\tVPXOR    Y8, Y10, Y10\n\tVPSLLD   $0x0c, Y10, Y15\n\tVPSRLD   $0x14, Y10, Y10\n\tVPXOR    Y15, Y10, Y10\n\tVPADDD   Y10, Y6, Y6\n\tVPXOR    Y6, Y2, Y2\n\tVPSHUFB  ·rol8<>+0(SB), Y2, Y2\n\tVPADDD   Y2, Y8, Y8\n\tVPXOR    Y8, Y10, Y10\n\tVPSLLD   $0x07, Y10, Y15\n\tVPSRLD   $0x19, Y10, Y10\n\tVPXOR    Y15, Y10, Y10\n\tVMOVDQA  224(BP), Y15\n\tVMOVDQA  Y13, 224(BP)\n\tVPADDD   Y11, Y7, Y7\n\tVPXOR    Y7, Y3, Y3\n\tVPSHUFB  ·rol16<>+0(SB), Y3, Y3\n\tVPADDD   Y3, Y15, Y15\n\tVPXOR    Y15, Y11, Y11\n\tVPSLLD   $0x0c, Y11, Y13\n\tVPSRLD   $0x14, Y11, Y11\n\tVPXOR    Y13, Y11, Y11\n\tVPADDD   Y11, Y7, Y7\n\tVPXOR    Y7, Y3, Y3\n\tVPSHUFB  ·rol8<>+0(SB), Y3, Y3\n\tVPADDD   Y3, Y15, Y15\n\tVPXOR    Y15, Y11, Y11\n\tVPSLLD   $0x07, Y11, Y13\n\tVPSRLD   $0x19, Y11, Y11\n\tVPXOR    Y13, Y11, Y11\n\tVMOVDQA  224(BP), Y13\n\tVPALIGNR $0x0c, Y14, Y14, Y14\n\tVPALIGNR $0x08, Y12, Y12, Y12\n\tVPALIGNR $0x04, Y4, Y4, Y4\n\tVPALIGNR $0x0c, Y9, Y9, Y9\n\tVPALIGNR $0x08, Y13, Y13, Y13\n\tVPALIGNR $0x04, Y1, Y1, Y1\n\tVPALIGNR $0x0c, Y10, Y10, Y10\n\tVPALIGNR $0x08, Y8, Y8, Y8\n\tVPALIGNR $0x04, Y2, Y2, Y2\n\tVPALIGNR $0x0c, Y11, Y11, Y11\n\tVPALIGNR $0x08, Y15, Y15, Y15\n\tVPALIGNR $0x04, Y3, Y3, Y3\n\tVPADDD   Y14, Y0, Y0\n\tVPADDD   Y9, Y5, Y5\n\tVPADDD   Y10, Y6, Y6\n\tVPADDD   Y11, Y7, Y7\n\tVPXOR    Y0, Y4, Y4\n\tVPXOR    Y5, Y1, Y1\n\tVPXOR    Y6, Y2, Y2\n\tVPXOR    Y7, Y3, Y3\n\tVPSHUFB  ·rol16<>+0(SB), Y4, Y4\n\tVPSHUFB  ·rol16<>+0(SB), Y1, Y1\n\tVPSHUFB  ·rol16<>+0(SB), Y2, Y2\n\tVPSHUFB  ·rol16<>+0(SB), Y3, Y3\n\tVPADDD   Y4, Y12, Y12\n\tVPADDD   Y1, Y13, Y13\n\tVPADDD   Y2, Y8, Y8\n\tVPADDD   Y3, Y15, Y15\n\tVPXOR    Y12, Y14, Y14\n\tVPXOR    Y13, Y9, Y9\n\tVPXOR    Y8, Y10, Y10\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  Y15, 224(BP)\n\tVPSLLD   $0x0c, Y14, Y15\n\tVPSRLD   $0x14, Y14, Y14\n\tVPXOR    Y15, Y14, Y14\n\tVPSLLD   $0x0c, Y9, Y15\n\tVPSRLD   $0x14, Y9, Y9\n\tVPXOR    Y15, Y9, Y9\n\tVPSLLD   $0x0c, Y10, Y15\n\tVPSRLD   $0x14, Y10, Y10\n\tVPXOR    Y15, Y10, Y10\n\tVPSLLD   $0x0c, Y11, Y15\n\tVPSRLD   $0x14, Y11, Y11\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  224(BP), Y15\n\tSUBQ     $0x10, DI\n\tMOVQ     $0x00000009, CX\n\tJMP      sealAVX2InternalLoopStart\n\nsealAVX2MainLoop:\n\tVMOVDQU ·chacha20Constants<>+0(SB), Y0\n\tVMOVDQA Y0, Y5\n\tVMOVDQA Y0, Y6\n\tVMOVDQA Y0, Y7\n\tVMOVDQA 32(BP), Y14\n\tVMOVDQA Y14, Y9\n\tVMOVDQA Y14, Y10\n\tVMOVDQA Y14, Y11\n\tVMOVDQA 64(BP), Y12\n\tVMOVDQA Y12, Y13\n\tVMOVDQA Y12, Y8\n\tVMOVDQA Y12, Y15\n\tVMOVDQA 192(BP), Y4\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y4\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y1\n\tVPADDD  ·avx2IncMask<>+0(SB), Y1, Y2\n\tVPADDD  ·avx2IncMask<>+0(SB), Y2, Y3\n\tVMOVDQA Y4, 96(BP)\n\tVMOVDQA Y1, 128(BP)\n\tVMOVDQA Y2, 160(BP)\n\tVMOVDQA Y3, 192(BP)\n\tMOVQ    $0x0000000a, CX\n\nsealAVX2InternalLoop:\n\tADDQ    (DI), R10\n\tADCQ    8(DI), R11\n\tADCQ    $0x01, R12\n\tVPADDD  Y14, Y0, Y0\n\tVPADDD  Y9, Y5, Y5\n\tVPADDD  Y10, Y6, Y6\n\tVPADDD  Y11, Y7, Y7\n\tMOVQ    (BP), DX\n\tMOVQ    DX, R15\n\tMULXQ   R10, R13, R14\n\tIMULQ   R12, R15\n\tMULXQ   R11, AX, DX\n\tADDQ    AX, R14\n\tADCQ    DX, R15\n\tVPXOR   Y0, Y4, Y4\n\tVPXOR   Y5, Y1, Y1\n\tVPXOR   Y6, Y2, Y2\n\tVPXOR   Y7, Y3, Y3\n\tVPSHUFB ·rol16<>+0(SB), Y4, Y4\n\tVPSHUFB ·rol16<>+0(SB), Y1, Y1\n\tVPSHUFB ·rol16<>+0(SB), Y2, Y2\n\tVPSHUFB ·rol16<>+0(SB), Y3, Y3\n\tMOVQ    8(BP), DX\n\tMULXQ   R10, R10, AX\n\tADDQ    R10, R14\n\tMULXQ   R11, R11, R8\n\tADCQ    R11, R15\n\tADCQ    $0x00, R8\n\tVPADDD  Y4, Y12, Y12\n\tVPADDD  Y1, Y13, Y13\n\tVPADDD  Y2, Y8, Y8\n\tVPADDD  Y3, Y15, Y15\n\tVPXOR   Y12, Y14, Y14\n\tVPXOR   Y13, Y9, Y9\n\tVPXOR   Y8, Y10, Y10\n\tVPXOR   Y15, Y11, Y11\n\tIMULQ   R12, DX\n\tADDQ    AX, R15\n\tADCQ    DX, R8\n\tVMOVDQA Y15, 224(BP)\n\tVPSLLD  $0x0c, Y14, Y15\n\tVPSRLD  $0x14, Y14, Y14\n\tVPXOR   Y15, Y14, Y14\n\tVPSLLD  $0x0c, Y9, Y15\n\tVPSRLD  $0x14, Y9, Y9\n\tVPXOR   Y15, Y9, Y9\n\tVPSLLD  $0x0c, Y10, Y15\n\tVPSRLD  $0x14, Y10, Y10\n\tVPXOR   Y15, Y10, Y10\n\tVPSLLD  $0x0c, Y11, Y15\n\tVPSRLD  $0x14, Y11, Y11\n\tVPXOR   Y15, Y11, Y11\n\tVMOVDQA 224(BP), Y15\n\tMOVQ    R13, R10\n\tMOVQ    R14, R11\n\tMOVQ    R15, R12\n\tANDQ    $0x03, R12\n\tMOVQ    R15, R13\n\tANDQ    $-4, R13\n\tMOVQ    R8, R14\n\tSHRQ    $0x02, R8, R15\n\tSHRQ    $0x02, R8\n\tADDQ    R13, R10\n\tADCQ    R14, R11\n\tADCQ    $0x00, R12\n\tADDQ    R15, R10\n\tADCQ    R8, R11\n\tADCQ    $0x00, R12\n\nsealAVX2InternalLoopStart:\n\tVPADDD   Y14, Y0, Y0\n\tVPADDD   Y9, Y5, Y5\n\tVPADDD   Y10, Y6, Y6\n\tVPADDD   Y11, Y7, Y7\n\tVPXOR    Y0, Y4, Y4\n\tVPXOR    Y5, Y1, Y1\n\tVPXOR    Y6, Y2, Y2\n\tVPXOR    Y7, Y3, Y3\n\tVPSHUFB  ·rol8<>+0(SB), Y4, Y4\n\tVPSHUFB  ·rol8<>+0(SB), Y1, Y1\n\tVPSHUFB  ·rol8<>+0(SB), Y2, Y2\n\tVPSHUFB  ·rol8<>+0(SB), Y3, Y3\n\tADDQ     16(DI), R10\n\tADCQ     24(DI), R11\n\tADCQ     $0x01, R12\n\tVPADDD   Y4, Y12, Y12\n\tVPADDD   Y1, Y13, Y13\n\tVPADDD   Y2, Y8, Y8\n\tVPADDD   Y3, Y15, Y15\n\tMOVQ     (BP), DX\n\tMOVQ     DX, R15\n\tMULXQ    R10, R13, R14\n\tIMULQ    R12, R15\n\tMULXQ    R11, AX, DX\n\tADDQ     AX, R14\n\tADCQ     DX, R15\n\tVPXOR    Y12, Y14, Y14\n\tVPXOR    Y13, Y9, Y9\n\tVPXOR    Y8, Y10, Y10\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  Y15, 224(BP)\n\tVPSLLD   $0x07, Y14, Y15\n\tVPSRLD   $0x19, Y14, Y14\n\tVPXOR    Y15, Y14, Y14\n\tVPSLLD   $0x07, Y9, Y15\n\tVPSRLD   $0x19, Y9, Y9\n\tVPXOR    Y15, Y9, Y9\n\tVPSLLD   $0x07, Y10, Y15\n\tVPSRLD   $0x19, Y10, Y10\n\tVPXOR    Y15, Y10, Y10\n\tVPSLLD   $0x07, Y11, Y15\n\tVPSRLD   $0x19, Y11, Y11\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  224(BP), Y15\n\tMOVQ     8(BP), DX\n\tMULXQ    R10, R10, AX\n\tADDQ     R10, R14\n\tMULXQ    R11, R11, R8\n\tADCQ     R11, R15\n\tADCQ     $0x00, R8\n\tVPALIGNR $0x04, Y14, Y14, Y14\n\tVPALIGNR $0x04, Y9, Y9, Y9\n\tVPALIGNR $0x04, Y10, Y10, Y10\n\tVPALIGNR $0x04, Y11, Y11, Y11\n\tVPALIGNR $0x08, Y12, Y12, Y12\n\tVPALIGNR $0x08, Y13, Y13, Y13\n\tVPALIGNR $0x08, Y8, Y8, Y8\n\tVPALIGNR $0x08, Y15, Y15, Y15\n\tVPALIGNR $0x0c, Y4, Y4, Y4\n\tVPALIGNR $0x0c, Y1, Y1, Y1\n\tVPALIGNR $0x0c, Y2, Y2, Y2\n\tVPALIGNR $0x0c, Y3, Y3, Y3\n\tVPADDD   Y14, Y0, Y0\n\tVPADDD   Y9, Y5, Y5\n\tVPADDD   Y10, Y6, Y6\n\tVPADDD   Y11, Y7, Y7\n\tIMULQ    R12, DX\n\tADDQ     AX, R15\n\tADCQ     DX, R8\n\tVPXOR    Y0, Y4, Y4\n\tVPXOR    Y5, Y1, Y1\n\tVPXOR    Y6, Y2, Y2\n\tVPXOR    Y7, Y3, Y3\n\tVPSHUFB  ·rol16<>+0(SB), Y4, Y4\n\tVPSHUFB  ·rol16<>+0(SB), Y1, Y1\n\tVPSHUFB  ·rol16<>+0(SB), Y2, Y2\n\tVPSHUFB  ·rol16<>+0(SB), Y3, Y3\n\tMOVQ     R13, R10\n\tMOVQ     R14, R11\n\tMOVQ     R15, R12\n\tANDQ     $0x03, R12\n\tMOVQ     R15, R13\n\tANDQ     $-4, R13\n\tMOVQ     R8, R14\n\tSHRQ     $0x02, R8, R15\n\tSHRQ     $0x02, R8\n\tADDQ     R13, R10\n\tADCQ     R14, R11\n\tADCQ     $0x00, R12\n\tADDQ     R15, R10\n\tADCQ     R8, R11\n\tADCQ     $0x00, R12\n\tVPADDD   Y4, Y12, Y12\n\tVPADDD   Y1, Y13, Y13\n\tVPADDD   Y2, Y8, Y8\n\tVPADDD   Y3, Y15, Y15\n\tVPXOR    Y12, Y14, Y14\n\tVPXOR    Y13, Y9, Y9\n\tVPXOR    Y8, Y10, Y10\n\tVPXOR    Y15, Y11, Y11\n\tADDQ     32(DI), R10\n\tADCQ     40(DI), R11\n\tADCQ     $0x01, R12\n\tLEAQ     48(DI), DI\n\tVMOVDQA  Y15, 224(BP)\n\tVPSLLD   $0x0c, Y14, Y15\n\tVPSRLD   $0x14, Y14, Y14\n\tVPXOR    Y15, Y14, Y14\n\tVPSLLD   $0x0c, Y9, Y15\n\tVPSRLD   $0x14, Y9, Y9\n\tVPXOR    Y15, Y9, Y9\n\tVPSLLD   $0x0c, Y10, Y15\n\tVPSRLD   $0x14, Y10, Y10\n\tVPXOR    Y15, Y10, Y10\n\tVPSLLD   $0x0c, Y11, Y15\n\tVPSRLD   $0x14, Y11, Y11\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  224(BP), Y15\n\tMOVQ     (BP), DX\n\tMOVQ     DX, R15\n\tMULXQ    R10, R13, R14\n\tIMULQ    R12, R15\n\tMULXQ    R11, AX, DX\n\tADDQ     AX, R14\n\tADCQ     DX, R15\n\tVPADDD   Y14, Y0, Y0\n\tVPADDD   Y9, Y5, Y5\n\tVPADDD   Y10, Y6, Y6\n\tVPADDD   Y11, Y7, Y7\n\tVPXOR    Y0, Y4, Y4\n\tVPXOR    Y5, Y1, Y1\n\tVPXOR    Y6, Y2, Y2\n\tVPXOR    Y7, Y3, Y3\n\tMOVQ     8(BP), DX\n\tMULXQ    R10, R10, AX\n\tADDQ     R10, R14\n\tMULXQ    R11, R11, R8\n\tADCQ     R11, R15\n\tADCQ     $0x00, R8\n\tVPSHUFB  ·rol8<>+0(SB), Y4, Y4\n\tVPSHUFB  ·rol8<>+0(SB), Y1, Y1\n\tVPSHUFB  ·rol8<>+0(SB), Y2, Y2\n\tVPSHUFB  ·rol8<>+0(SB), Y3, Y3\n\tVPADDD   Y4, Y12, Y12\n\tVPADDD   Y1, Y13, Y13\n\tVPADDD   Y2, Y8, Y8\n\tVPADDD   Y3, Y15, Y15\n\tIMULQ    R12, DX\n\tADDQ     AX, R15\n\tADCQ     DX, R8\n\tVPXOR    Y12, Y14, Y14\n\tVPXOR    Y13, Y9, Y9\n\tVPXOR    Y8, Y10, Y10\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  Y15, 224(BP)\n\tVPSLLD   $0x07, Y14, Y15\n\tVPSRLD   $0x19, Y14, Y14\n\tVPXOR    Y15, Y14, Y14\n\tVPSLLD   $0x07, Y9, Y15\n\tVPSRLD   $0x19, Y9, Y9\n\tVPXOR    Y15, Y9, Y9\n\tVPSLLD   $0x07, Y10, Y15\n\tVPSRLD   $0x19, Y10, Y10\n\tVPXOR    Y15, Y10, Y10\n\tVPSLLD   $0x07, Y11, Y15\n\tVPSRLD   $0x19, Y11, Y11\n\tVPXOR    Y15, Y11, Y11\n\tVMOVDQA  224(BP), Y15\n\tMOVQ     R13, R10\n\tMOVQ     R14, R11\n\tMOVQ     R15, R12\n\tANDQ     $0x03, R12\n\tMOVQ     R15, R13\n\tANDQ     $-4, R13\n\tMOVQ     R8, R14\n\tSHRQ     $0x02, R8, R15\n\tSHRQ     $0x02, R8\n\tADDQ     R13, R10\n\tADCQ     R14, R11\n\tADCQ     $0x00, R12\n\tADDQ     R15, R10\n\tADCQ     R8, R11\n\tADCQ     $0x00, R12\n\tVPALIGNR $0x0c, Y14, Y14, Y14\n\tVPALIGNR $0x0c, Y9, Y9, Y9\n\tVPALIGNR $0x0c, Y10, Y10, Y10\n\tVPALIGNR $0x0c, Y11, Y11, Y11\n\tVPALIGNR $0x08, Y12, Y12, Y12\n\tVPALIGNR $0x08, Y13, Y13, Y13\n\tVPALIGNR $0x08, Y8, Y8, Y8\n\tVPALIGNR $0x08, Y15, Y15, Y15\n\tVPALIGNR $0x04, Y4, Y4, Y4\n\tVPALIGNR $0x04, Y1, Y1, Y1\n\tVPALIGNR $0x04, Y2, Y2, Y2\n\tVPALIGNR $0x04, Y3, Y3, Y3\n\tDECQ     CX\n\tJNE      sealAVX2InternalLoop\n\tVPADDD   ·chacha20Constants<>+0(SB), Y0, Y0\n\tVPADDD   ·chacha20Constants<>+0(SB), Y5, Y5\n\tVPADDD   ·chacha20Constants<>+0(SB), Y6, Y6\n\tVPADDD   ·chacha20Constants<>+0(SB), Y7, Y7\n\tVPADDD   32(BP), Y14, Y14\n\tVPADDD   32(BP), Y9, Y9\n\tVPADDD   32(BP), Y10, Y10\n\tVPADDD   32(BP), Y11, Y11\n\tVPADDD   64(BP), Y12, Y12\n\tVPADDD   64(BP), Y13, Y13\n\tVPADDD   64(BP), Y8, Y8\n\tVPADDD   64(BP), Y15, Y15\n\tVPADDD   96(BP), Y4, Y4\n\tVPADDD   128(BP), Y1, Y1\n\tVPADDD   160(BP), Y2, Y2\n\tVPADDD   192(BP), Y3, Y3\n\tVMOVDQA  Y15, 224(BP)\n\n\t// We only hashed 480 of the 512 bytes available - hash the remaining 32 here\n\tADDQ       (DI), R10\n\tADCQ       8(DI), R11\n\tADCQ       $0x01, R12\n\tMOVQ       (BP), DX\n\tMOVQ       DX, R15\n\tMULXQ      R10, R13, R14\n\tIMULQ      R12, R15\n\tMULXQ      R11, AX, DX\n\tADDQ       AX, R14\n\tADCQ       DX, R15\n\tMOVQ       8(BP), DX\n\tMULXQ      R10, R10, AX\n\tADDQ       R10, R14\n\tMULXQ      R11, R11, R8\n\tADCQ       R11, R15\n\tADCQ       $0x00, R8\n\tIMULQ      R12, DX\n\tADDQ       AX, R15\n\tADCQ       DX, R8\n\tMOVQ       R13, R10\n\tMOVQ       R14, R11\n\tMOVQ       R15, R12\n\tANDQ       $0x03, R12\n\tMOVQ       R15, R13\n\tANDQ       $-4, R13\n\tMOVQ       R8, R14\n\tSHRQ       $0x02, R8, R15\n\tSHRQ       $0x02, R8\n\tADDQ       R13, R10\n\tADCQ       R14, R11\n\tADCQ       $0x00, R12\n\tADDQ       R15, R10\n\tADCQ       R8, R11\n\tADCQ       $0x00, R12\n\tLEAQ       32(DI), DI\n\tVPERM2I128 $0x02, Y0, Y14, Y15\n\tVPERM2I128 $0x13, Y0, Y14, Y14\n\tVPERM2I128 $0x02, Y12, Y4, Y0\n\tVPERM2I128 $0x13, Y12, Y4, Y12\n\tVPXOR      (SI), Y15, Y15\n\tVPXOR      32(SI), Y0, Y0\n\tVPXOR      64(SI), Y14, Y14\n\tVPXOR      96(SI), Y12, Y12\n\tVMOVDQU    Y15, (DI)\n\tVMOVDQU    Y0, 32(DI)\n\tVMOVDQU    Y14, 64(DI)\n\tVMOVDQU    Y12, 96(DI)\n\tVPERM2I128 $0x02, Y5, Y9, Y0\n\tVPERM2I128 $0x02, Y13, Y1, Y14\n\tVPERM2I128 $0x13, Y5, Y9, Y12\n\tVPERM2I128 $0x13, Y13, Y1, Y4\n\tVPXOR      128(SI), Y0, Y0\n\tVPXOR      160(SI), Y14, Y14\n\tVPXOR      192(SI), Y12, Y12\n\tVPXOR      224(SI), Y4, Y4\n\tVMOVDQU    Y0, 128(DI)\n\tVMOVDQU    Y14, 160(DI)\n\tVMOVDQU    Y12, 192(DI)\n\tVMOVDQU    Y4, 224(DI)\n\n\t// and here\n\tADDQ       -16(DI), R10\n\tADCQ       -8(DI), R11\n\tADCQ       $0x01, R12\n\tMOVQ       (BP), DX\n\tMOVQ       DX, R15\n\tMULXQ      R10, R13, R14\n\tIMULQ      R12, R15\n\tMULXQ      R11, AX, DX\n\tADDQ       AX, R14\n\tADCQ       DX, R15\n\tMOVQ       8(BP), DX\n\tMULXQ      R10, R10, AX\n\tADDQ       R10, R14\n\tMULXQ      R11, R11, R8\n\tADCQ       R11, R15\n\tADCQ       $0x00, R8\n\tIMULQ      R12, DX\n\tADDQ       AX, R15\n\tADCQ       DX, R8\n\tMOVQ       R13, R10\n\tMOVQ       R14, R11\n\tMOVQ       R15, R12\n\tANDQ       $0x03, R12\n\tMOVQ       R15, R13\n\tANDQ       $-4, R13\n\tMOVQ       R8, R14\n\tSHRQ       $0x02, R8, R15\n\tSHRQ       $0x02, R8\n\tADDQ       R13, R10\n\tADCQ       R14, R11\n\tADCQ       $0x00, R12\n\tADDQ       R15, R10\n\tADCQ       R8, R11\n\tADCQ       $0x00, R12\n\tVPERM2I128 $0x02, Y6, Y10, Y0\n\tVPERM2I128 $0x02, Y8, Y2, Y14\n\tVPERM2I128 $0x13, Y6, Y10, Y12\n\tVPERM2I128 $0x13, Y8, Y2, Y4\n\tVPXOR      256(SI), Y0, Y0\n\tVPXOR      288(SI), Y14, Y14\n\tVPXOR      320(SI), Y12, Y12\n\tVPXOR      352(SI), Y4, Y4\n\tVMOVDQU    Y0, 256(DI)\n\tVMOVDQU    Y14, 288(DI)\n\tVMOVDQU    Y12, 320(DI)\n\tVMOVDQU    Y4, 352(DI)\n\tVPERM2I128 $0x02, Y7, Y11, Y0\n\tVPERM2I128 $0x02, 224(BP), Y3, Y14\n\tVPERM2I128 $0x13, Y7, Y11, Y12\n\tVPERM2I128 $0x13, 224(BP), Y3, Y4\n\tVPXOR      384(SI), Y0, Y0\n\tVPXOR      416(SI), Y14, Y14\n\tVPXOR      448(SI), Y12, Y12\n\tVPXOR      480(SI), Y4, Y4\n\tVMOVDQU    Y0, 384(DI)\n\tVMOVDQU    Y14, 416(DI)\n\tVMOVDQU    Y12, 448(DI)\n\tVMOVDQU    Y4, 480(DI)\n\tLEAQ       512(SI), SI\n\tSUBQ       $0x00000200, BX\n\tCMPQ       BX, $0x00000200\n\tJG         sealAVX2MainLoop\n\n\t// Tail can only hash 480 bytes\n\tADDQ  (DI), R10\n\tADCQ  8(DI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), DX\n\tMOVQ  DX, R15\n\tMULXQ R10, R13, R14\n\tIMULQ R12, R15\n\tMULXQ R11, AX, DX\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), DX\n\tMULXQ R10, R10, AX\n\tADDQ  R10, R14\n\tMULXQ R11, R11, R8\n\tADCQ  R11, R15\n\tADCQ  $0x00, R8\n\tIMULQ R12, DX\n\tADDQ  AX, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tADDQ  16(DI), R10\n\tADCQ  24(DI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), DX\n\tMOVQ  DX, R15\n\tMULXQ R10, R13, R14\n\tIMULQ R12, R15\n\tMULXQ R11, AX, DX\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), DX\n\tMULXQ R10, R10, AX\n\tADDQ  R10, R14\n\tMULXQ R11, R11, R8\n\tADCQ  R11, R15\n\tADCQ  $0x00, R8\n\tIMULQ R12, DX\n\tADDQ  AX, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  32(DI), DI\n\tMOVQ  $0x0000000a, CX\n\tMOVQ  $0x00000000, R9\n\tCMPQ  BX, $0x80\n\tJBE   sealAVX2Tail128\n\tCMPQ  BX, $0x00000100\n\tJBE   sealAVX2Tail256\n\tCMPQ  BX, $0x00000180\n\tJBE   sealAVX2Tail384\n\tJMP   sealAVX2Tail512\n\nseal192AVX2:\n\tVMOVDQA Y0, Y5\n\tVMOVDQA Y14, Y9\n\tVMOVDQA Y12, Y13\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y1\n\tVMOVDQA Y0, Y6\n\tVMOVDQA Y14, Y10\n\tVMOVDQA Y12, Y8\n\tVMOVDQA Y4, Y2\n\tVMOVDQA Y1, Y15\n\tMOVQ    $0x0000000a, R9\n\nsealAVX2192InnerCipherLoop:\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol16<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x0c, Y14, Y3\n\tVPSRLD     $0x14, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol8<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x07, Y14, Y3\n\tVPSRLD     $0x19, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol16<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x0c, Y9, Y3\n\tVPSRLD     $0x14, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol8<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x07, Y9, Y3\n\tVPSRLD     $0x19, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPALIGNR   $0x04, Y14, Y14, Y14\n\tVPALIGNR   $0x04, Y9, Y9, Y9\n\tVPALIGNR   $0x08, Y12, Y12, Y12\n\tVPALIGNR   $0x08, Y13, Y13, Y13\n\tVPALIGNR   $0x0c, Y4, Y4, Y4\n\tVPALIGNR   $0x0c, Y1, Y1, Y1\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol16<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x0c, Y14, Y3\n\tVPSRLD     $0x14, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol8<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x07, Y14, Y3\n\tVPSRLD     $0x19, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol16<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x0c, Y9, Y3\n\tVPSRLD     $0x14, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol8<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x07, Y9, Y3\n\tVPSRLD     $0x19, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPALIGNR   $0x0c, Y14, Y14, Y14\n\tVPALIGNR   $0x0c, Y9, Y9, Y9\n\tVPALIGNR   $0x08, Y12, Y12, Y12\n\tVPALIGNR   $0x08, Y13, Y13, Y13\n\tVPALIGNR   $0x04, Y4, Y4, Y4\n\tVPALIGNR   $0x04, Y1, Y1, Y1\n\tDECQ       R9\n\tJNE        sealAVX2192InnerCipherLoop\n\tVPADDD     Y6, Y0, Y0\n\tVPADDD     Y6, Y5, Y5\n\tVPADDD     Y10, Y14, Y14\n\tVPADDD     Y10, Y9, Y9\n\tVPADDD     Y8, Y12, Y12\n\tVPADDD     Y8, Y13, Y13\n\tVPADDD     Y2, Y4, Y4\n\tVPADDD     Y15, Y1, Y1\n\tVPERM2I128 $0x02, Y0, Y14, Y3\n\n\t// Clamp and store poly key\n\tVPAND   ·polyClampMask<>+0(SB), Y3, Y3\n\tVMOVDQA Y3, (BP)\n\n\t// Stream for up to 192 bytes\n\tVPERM2I128 $0x13, Y0, Y14, Y0\n\tVPERM2I128 $0x13, Y12, Y4, Y14\n\tVPERM2I128 $0x02, Y5, Y9, Y12\n\tVPERM2I128 $0x02, Y13, Y1, Y4\n\tVPERM2I128 $0x13, Y5, Y9, Y5\n\tVPERM2I128 $0x13, Y13, Y1, Y9\n\nsealAVX2ShortSeal:\n\t// Hash aad\n\tMOVQ ad_len+80(FP), R9\n\tCALL polyHashADInternal<>(SB)\n\tXORQ CX, CX\n\nsealAVX2SealHash:\n\t// itr1 holds the number of bytes encrypted but not yet hashed\n\tCMPQ  CX, $0x10\n\tJB    sealAVX2ShortSealLoop\n\tADDQ  (DI), R10\n\tADCQ  8(DI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tSUBQ  $0x10, CX\n\tADDQ  $0x10, DI\n\tJMP   sealAVX2SealHash\n\nsealAVX2ShortSealLoop:\n\tCMPQ BX, $0x20\n\tJB   sealAVX2ShortTail32\n\tSUBQ $0x20, BX\n\n\t// Load for encryption\n\tVPXOR   (SI), Y0, Y0\n\tVMOVDQU Y0, (DI)\n\tLEAQ    32(SI), SI\n\n\t// Now can hash\n\tADDQ  (DI), R10\n\tADCQ  8(DI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), DX\n\tMOVQ  DX, R15\n\tMULXQ R10, R13, R14\n\tIMULQ R12, R15\n\tMULXQ R11, AX, DX\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), DX\n\tMULXQ R10, R10, AX\n\tADDQ  R10, R14\n\tMULXQ R11, R11, R8\n\tADCQ  R11, R15\n\tADCQ  $0x00, R8\n\tIMULQ R12, DX\n\tADDQ  AX, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tADDQ  16(DI), R10\n\tADCQ  24(DI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), DX\n\tMOVQ  DX, R15\n\tMULXQ R10, R13, R14\n\tIMULQ R12, R15\n\tMULXQ R11, AX, DX\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), DX\n\tMULXQ R10, R10, AX\n\tADDQ  R10, R14\n\tMULXQ R11, R11, R8\n\tADCQ  R11, R15\n\tADCQ  $0x00, R8\n\tIMULQ R12, DX\n\tADDQ  AX, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  32(DI), DI\n\n\t// Shift stream left\n\tVMOVDQA Y14, Y0\n\tVMOVDQA Y12, Y14\n\tVMOVDQA Y4, Y12\n\tVMOVDQA Y5, Y4\n\tVMOVDQA Y9, Y5\n\tVMOVDQA Y13, Y9\n\tVMOVDQA Y1, Y13\n\tVMOVDQA Y6, Y1\n\tVMOVDQA Y10, Y6\n\tJMP     sealAVX2ShortSealLoop\n\nsealAVX2ShortTail32:\n\tCMPQ    BX, $0x10\n\tVMOVDQA X0, X1\n\tJB      sealAVX2ShortDone\n\tSUBQ    $0x10, BX\n\n\t// Load for encryption\n\tVPXOR   (SI), X0, X12\n\tVMOVDQU X12, (DI)\n\tLEAQ    16(SI), SI\n\n\t// Hash\n\tADDQ       (DI), R10\n\tADCQ       8(DI), R11\n\tADCQ       $0x01, R12\n\tMOVQ       (BP), DX\n\tMOVQ       DX, R15\n\tMULXQ      R10, R13, R14\n\tIMULQ      R12, R15\n\tMULXQ      R11, AX, DX\n\tADDQ       AX, R14\n\tADCQ       DX, R15\n\tMOVQ       8(BP), DX\n\tMULXQ      R10, R10, AX\n\tADDQ       R10, R14\n\tMULXQ      R11, R11, R8\n\tADCQ       R11, R15\n\tADCQ       $0x00, R8\n\tIMULQ      R12, DX\n\tADDQ       AX, R15\n\tADCQ       DX, R8\n\tMOVQ       R13, R10\n\tMOVQ       R14, R11\n\tMOVQ       R15, R12\n\tANDQ       $0x03, R12\n\tMOVQ       R15, R13\n\tANDQ       $-4, R13\n\tMOVQ       R8, R14\n\tSHRQ       $0x02, R8, R15\n\tSHRQ       $0x02, R8\n\tADDQ       R13, R10\n\tADCQ       R14, R11\n\tADCQ       $0x00, R12\n\tADDQ       R15, R10\n\tADCQ       R8, R11\n\tADCQ       $0x00, R12\n\tLEAQ       16(DI), DI\n\tVPERM2I128 $0x11, Y0, Y0, Y0\n\tVMOVDQA    X0, X1\n\nsealAVX2ShortDone:\n\tVZEROUPPER\n\tJMP sealSSETail\n\nseal320AVX2:\n\tVMOVDQA Y0, Y5\n\tVMOVDQA Y14, Y9\n\tVMOVDQA Y12, Y13\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y1\n\tVMOVDQA Y0, Y6\n\tVMOVDQA Y14, Y10\n\tVMOVDQA Y12, Y8\n\tVPADDD  ·avx2IncMask<>+0(SB), Y1, Y2\n\tVMOVDQA Y14, Y7\n\tVMOVDQA Y12, Y11\n\tVMOVDQA Y4, Y15\n\tMOVQ    $0x0000000a, R9\n\nsealAVX2320InnerCipherLoop:\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol16<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x0c, Y14, Y3\n\tVPSRLD   $0x14, Y14, Y14\n\tVPXOR    Y3, Y14, Y14\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol8<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x07, Y14, Y3\n\tVPSRLD   $0x19, Y14, Y14\n\tVPXOR    Y3, Y14, Y14\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol16<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x0c, Y9, Y3\n\tVPSRLD   $0x14, Y9, Y9\n\tVPXOR    Y3, Y9, Y9\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol8<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x07, Y9, Y3\n\tVPSRLD   $0x19, Y9, Y9\n\tVPXOR    Y3, Y9, Y9\n\tVPADDD   Y10, Y6, Y6\n\tVPXOR    Y6, Y2, Y2\n\tVPSHUFB  ·rol16<>+0(SB), Y2, Y2\n\tVPADDD   Y2, Y8, Y8\n\tVPXOR    Y8, Y10, Y10\n\tVPSLLD   $0x0c, Y10, Y3\n\tVPSRLD   $0x14, Y10, Y10\n\tVPXOR    Y3, Y10, Y10\n\tVPADDD   Y10, Y6, Y6\n\tVPXOR    Y6, Y2, Y2\n\tVPSHUFB  ·rol8<>+0(SB), Y2, Y2\n\tVPADDD   Y2, Y8, Y8\n\tVPXOR    Y8, Y10, Y10\n\tVPSLLD   $0x07, Y10, Y3\n\tVPSRLD   $0x19, Y10, Y10\n\tVPXOR    Y3, Y10, Y10\n\tVPALIGNR $0x04, Y14, Y14, Y14\n\tVPALIGNR $0x04, Y9, Y9, Y9\n\tVPALIGNR $0x04, Y10, Y10, Y10\n\tVPALIGNR $0x08, Y12, Y12, Y12\n\tVPALIGNR $0x08, Y13, Y13, Y13\n\tVPALIGNR $0x08, Y8, Y8, Y8\n\tVPALIGNR $0x0c, Y4, Y4, Y4\n\tVPALIGNR $0x0c, Y1, Y1, Y1\n\tVPALIGNR $0x0c, Y2, Y2, Y2\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol16<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x0c, Y14, Y3\n\tVPSRLD   $0x14, Y14, Y14\n\tVPXOR    Y3, Y14, Y14\n\tVPADDD   Y14, Y0, Y0\n\tVPXOR    Y0, Y4, Y4\n\tVPSHUFB  ·rol8<>+0(SB), Y4, Y4\n\tVPADDD   Y4, Y12, Y12\n\tVPXOR    Y12, Y14, Y14\n\tVPSLLD   $0x07, Y14, Y3\n\tVPSRLD   $0x19, Y14, Y14\n\tVPXOR    Y3, Y14, Y14\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol16<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x0c, Y9, Y3\n\tVPSRLD   $0x14, Y9, Y9\n\tVPXOR    Y3, Y9, Y9\n\tVPADDD   Y9, Y5, Y5\n\tVPXOR    Y5, Y1, Y1\n\tVPSHUFB  ·rol8<>+0(SB), Y1, Y1\n\tVPADDD   Y1, Y13, Y13\n\tVPXOR    Y13, Y9, Y9\n\tVPSLLD   $0x07, Y9, Y3\n\tVPSRLD   $0x19, Y9, Y9\n\tVPXOR    Y3, Y9, Y9\n\tVPADDD   Y10, Y6, Y6\n\tVPXOR    Y6, Y2, Y2\n\tVPSHUFB  ·rol16<>+0(SB), Y2, Y2\n\tVPADDD   Y2, Y8, Y8\n\tVPXOR    Y8, Y10, Y10\n\tVPSLLD   $0x0c, Y10, Y3\n\tVPSRLD   $0x14, Y10, Y10\n\tVPXOR    Y3, Y10, Y10\n\tVPADDD   Y10, Y6, Y6\n\tVPXOR    Y6, Y2, Y2\n\tVPSHUFB  ·rol8<>+0(SB), Y2, Y2\n\tVPADDD   Y2, Y8, Y8\n\tVPXOR    Y8, Y10, Y10\n\tVPSLLD   $0x07, Y10, Y3\n\tVPSRLD   $0x19, Y10, Y10\n\tVPXOR    Y3, Y10, Y10\n\tVPALIGNR $0x0c, Y14, Y14, Y14\n\tVPALIGNR $0x0c, Y9, Y9, Y9\n\tVPALIGNR $0x0c, Y10, Y10, Y10\n\tVPALIGNR $0x08, Y12, Y12, Y12\n\tVPALIGNR $0x08, Y13, Y13, Y13\n\tVPALIGNR $0x08, Y8, Y8, Y8\n\tVPALIGNR $0x04, Y4, Y4, Y4\n\tVPALIGNR $0x04, Y1, Y1, Y1\n\tVPALIGNR $0x04, Y2, Y2, Y2\n\tDECQ     R9\n\tJNE      sealAVX2320InnerCipherLoop\n\tVMOVDQA  ·chacha20Constants<>+0(SB), Y3\n\tVPADDD   Y3, Y0, Y0\n\tVPADDD   Y3, Y5, Y5\n\tVPADDD   Y3, Y6, Y6\n\tVPADDD   Y7, Y14, Y14\n\tVPADDD   Y7, Y9, Y9\n\tVPADDD   Y7, Y10, Y10\n\tVPADDD   Y11, Y12, Y12\n\tVPADDD   Y11, Y13, Y13\n\tVPADDD   Y11, Y8, Y8\n\tVMOVDQA  ·avx2IncMask<>+0(SB), Y3\n\tVPADDD   Y15, Y4, Y4\n\tVPADDD   Y3, Y15, Y15\n\tVPADDD   Y15, Y1, Y1\n\tVPADDD   Y3, Y15, Y15\n\tVPADDD   Y15, Y2, Y2\n\n\t// Clamp and store poly key\n\tVPERM2I128 $0x02, Y0, Y14, Y3\n\tVPAND      ·polyClampMask<>+0(SB), Y3, Y3\n\tVMOVDQA    Y3, (BP)\n\n\t// Stream for up to 320 bytes\n\tVPERM2I128 $0x13, Y0, Y14, Y0\n\tVPERM2I128 $0x13, Y12, Y4, Y14\n\tVPERM2I128 $0x02, Y5, Y9, Y12\n\tVPERM2I128 $0x02, Y13, Y1, Y4\n\tVPERM2I128 $0x13, Y5, Y9, Y5\n\tVPERM2I128 $0x13, Y13, Y1, Y9\n\tVPERM2I128 $0x02, Y6, Y10, Y13\n\tVPERM2I128 $0x02, Y8, Y2, Y1\n\tVPERM2I128 $0x13, Y6, Y10, Y6\n\tVPERM2I128 $0x13, Y8, Y2, Y10\n\tJMP        sealAVX2ShortSeal\n\nsealAVX2Tail128:\n\tVMOVDQA ·chacha20Constants<>+0(SB), Y0\n\tVMOVDQA 32(BP), Y14\n\tVMOVDQA 64(BP), Y12\n\tVMOVDQA 192(BP), Y4\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y4\n\tVMOVDQA Y4, Y1\n\nsealAVX2Tail128LoopA:\n\tADDQ  (DI), R10\n\tADCQ  8(DI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(DI), DI\n\nsealAVX2Tail128LoopB:\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol16<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x0c, Y14, Y3\n\tVPSRLD     $0x14, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol8<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x07, Y14, Y3\n\tVPSRLD     $0x19, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tADDQ       (DI), R10\n\tADCQ       8(DI), R11\n\tADCQ       $0x01, R12\n\tMOVQ       (BP), AX\n\tMOVQ       AX, R15\n\tMULQ       R10\n\tMOVQ       AX, R13\n\tMOVQ       DX, R14\n\tMOVQ       (BP), AX\n\tMULQ       R11\n\tIMULQ      R12, R15\n\tADDQ       AX, R14\n\tADCQ       DX, R15\n\tMOVQ       8(BP), AX\n\tMOVQ       AX, R8\n\tMULQ       R10\n\tADDQ       AX, R14\n\tADCQ       $0x00, DX\n\tMOVQ       DX, R10\n\tMOVQ       8(BP), AX\n\tMULQ       R11\n\tADDQ       AX, R15\n\tADCQ       $0x00, DX\n\tIMULQ      R12, R8\n\tADDQ       R10, R15\n\tADCQ       DX, R8\n\tMOVQ       R13, R10\n\tMOVQ       R14, R11\n\tMOVQ       R15, R12\n\tANDQ       $0x03, R12\n\tMOVQ       R15, R13\n\tANDQ       $-4, R13\n\tMOVQ       R8, R14\n\tSHRQ       $0x02, R8, R15\n\tSHRQ       $0x02, R8\n\tADDQ       R13, R10\n\tADCQ       R14, R11\n\tADCQ       $0x00, R12\n\tADDQ       R15, R10\n\tADCQ       R8, R11\n\tADCQ       $0x00, R12\n\tVPALIGNR   $0x04, Y14, Y14, Y14\n\tVPALIGNR   $0x08, Y12, Y12, Y12\n\tVPALIGNR   $0x0c, Y4, Y4, Y4\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol16<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x0c, Y14, Y3\n\tVPSRLD     $0x14, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol8<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x07, Y14, Y3\n\tVPSRLD     $0x19, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tADDQ       16(DI), R10\n\tADCQ       24(DI), R11\n\tADCQ       $0x01, R12\n\tMOVQ       (BP), AX\n\tMOVQ       AX, R15\n\tMULQ       R10\n\tMOVQ       AX, R13\n\tMOVQ       DX, R14\n\tMOVQ       (BP), AX\n\tMULQ       R11\n\tIMULQ      R12, R15\n\tADDQ       AX, R14\n\tADCQ       DX, R15\n\tMOVQ       8(BP), AX\n\tMOVQ       AX, R8\n\tMULQ       R10\n\tADDQ       AX, R14\n\tADCQ       $0x00, DX\n\tMOVQ       DX, R10\n\tMOVQ       8(BP), AX\n\tMULQ       R11\n\tADDQ       AX, R15\n\tADCQ       $0x00, DX\n\tIMULQ      R12, R8\n\tADDQ       R10, R15\n\tADCQ       DX, R8\n\tMOVQ       R13, R10\n\tMOVQ       R14, R11\n\tMOVQ       R15, R12\n\tANDQ       $0x03, R12\n\tMOVQ       R15, R13\n\tANDQ       $-4, R13\n\tMOVQ       R8, R14\n\tSHRQ       $0x02, R8, R15\n\tSHRQ       $0x02, R8\n\tADDQ       R13, R10\n\tADCQ       R14, R11\n\tADCQ       $0x00, R12\n\tADDQ       R15, R10\n\tADCQ       R8, R11\n\tADCQ       $0x00, R12\n\tLEAQ       32(DI), DI\n\tVPALIGNR   $0x0c, Y14, Y14, Y14\n\tVPALIGNR   $0x08, Y12, Y12, Y12\n\tVPALIGNR   $0x04, Y4, Y4, Y4\n\tDECQ       CX\n\tJG         sealAVX2Tail128LoopA\n\tDECQ       R9\n\tJGE        sealAVX2Tail128LoopB\n\tVPADDD     ·chacha20Constants<>+0(SB), Y0, Y5\n\tVPADDD     32(BP), Y14, Y9\n\tVPADDD     64(BP), Y12, Y13\n\tVPADDD     Y1, Y4, Y1\n\tVPERM2I128 $0x02, Y5, Y9, Y0\n\tVPERM2I128 $0x02, Y13, Y1, Y14\n\tVPERM2I128 $0x13, Y5, Y9, Y12\n\tVPERM2I128 $0x13, Y13, Y1, Y4\n\tJMP        sealAVX2ShortSealLoop\n\nsealAVX2Tail256:\n\tVMOVDQA ·chacha20Constants<>+0(SB), Y0\n\tVMOVDQA ·chacha20Constants<>+0(SB), Y5\n\tVMOVDQA 32(BP), Y14\n\tVMOVDQA 32(BP), Y9\n\tVMOVDQA 64(BP), Y12\n\tVMOVDQA 64(BP), Y13\n\tVMOVDQA 192(BP), Y4\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y4\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y1\n\tVMOVDQA Y4, Y7\n\tVMOVDQA Y1, Y11\n\nsealAVX2Tail256LoopA:\n\tADDQ  (DI), R10\n\tADCQ  8(DI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(DI), DI\n\nsealAVX2Tail256LoopB:\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol16<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x0c, Y14, Y3\n\tVPSRLD     $0x14, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol8<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x07, Y14, Y3\n\tVPSRLD     $0x19, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol16<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x0c, Y9, Y3\n\tVPSRLD     $0x14, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol8<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x07, Y9, Y3\n\tVPSRLD     $0x19, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tADDQ       (DI), R10\n\tADCQ       8(DI), R11\n\tADCQ       $0x01, R12\n\tMOVQ       (BP), AX\n\tMOVQ       AX, R15\n\tMULQ       R10\n\tMOVQ       AX, R13\n\tMOVQ       DX, R14\n\tMOVQ       (BP), AX\n\tMULQ       R11\n\tIMULQ      R12, R15\n\tADDQ       AX, R14\n\tADCQ       DX, R15\n\tMOVQ       8(BP), AX\n\tMOVQ       AX, R8\n\tMULQ       R10\n\tADDQ       AX, R14\n\tADCQ       $0x00, DX\n\tMOVQ       DX, R10\n\tMOVQ       8(BP), AX\n\tMULQ       R11\n\tADDQ       AX, R15\n\tADCQ       $0x00, DX\n\tIMULQ      R12, R8\n\tADDQ       R10, R15\n\tADCQ       DX, R8\n\tMOVQ       R13, R10\n\tMOVQ       R14, R11\n\tMOVQ       R15, R12\n\tANDQ       $0x03, R12\n\tMOVQ       R15, R13\n\tANDQ       $-4, R13\n\tMOVQ       R8, R14\n\tSHRQ       $0x02, R8, R15\n\tSHRQ       $0x02, R8\n\tADDQ       R13, R10\n\tADCQ       R14, R11\n\tADCQ       $0x00, R12\n\tADDQ       R15, R10\n\tADCQ       R8, R11\n\tADCQ       $0x00, R12\n\tVPALIGNR   $0x04, Y14, Y14, Y14\n\tVPALIGNR   $0x04, Y9, Y9, Y9\n\tVPALIGNR   $0x08, Y12, Y12, Y12\n\tVPALIGNR   $0x08, Y13, Y13, Y13\n\tVPALIGNR   $0x0c, Y4, Y4, Y4\n\tVPALIGNR   $0x0c, Y1, Y1, Y1\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol16<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x0c, Y14, Y3\n\tVPSRLD     $0x14, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol8<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x07, Y14, Y3\n\tVPSRLD     $0x19, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol16<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x0c, Y9, Y3\n\tVPSRLD     $0x14, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol8<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x07, Y9, Y3\n\tVPSRLD     $0x19, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tADDQ       16(DI), R10\n\tADCQ       24(DI), R11\n\tADCQ       $0x01, R12\n\tMOVQ       (BP), AX\n\tMOVQ       AX, R15\n\tMULQ       R10\n\tMOVQ       AX, R13\n\tMOVQ       DX, R14\n\tMOVQ       (BP), AX\n\tMULQ       R11\n\tIMULQ      R12, R15\n\tADDQ       AX, R14\n\tADCQ       DX, R15\n\tMOVQ       8(BP), AX\n\tMOVQ       AX, R8\n\tMULQ       R10\n\tADDQ       AX, R14\n\tADCQ       $0x00, DX\n\tMOVQ       DX, R10\n\tMOVQ       8(BP), AX\n\tMULQ       R11\n\tADDQ       AX, R15\n\tADCQ       $0x00, DX\n\tIMULQ      R12, R8\n\tADDQ       R10, R15\n\tADCQ       DX, R8\n\tMOVQ       R13, R10\n\tMOVQ       R14, R11\n\tMOVQ       R15, R12\n\tANDQ       $0x03, R12\n\tMOVQ       R15, R13\n\tANDQ       $-4, R13\n\tMOVQ       R8, R14\n\tSHRQ       $0x02, R8, R15\n\tSHRQ       $0x02, R8\n\tADDQ       R13, R10\n\tADCQ       R14, R11\n\tADCQ       $0x00, R12\n\tADDQ       R15, R10\n\tADCQ       R8, R11\n\tADCQ       $0x00, R12\n\tLEAQ       32(DI), DI\n\tVPALIGNR   $0x0c, Y14, Y14, Y14\n\tVPALIGNR   $0x0c, Y9, Y9, Y9\n\tVPALIGNR   $0x08, Y12, Y12, Y12\n\tVPALIGNR   $0x08, Y13, Y13, Y13\n\tVPALIGNR   $0x04, Y4, Y4, Y4\n\tVPALIGNR   $0x04, Y1, Y1, Y1\n\tDECQ       CX\n\tJG         sealAVX2Tail256LoopA\n\tDECQ       R9\n\tJGE        sealAVX2Tail256LoopB\n\tVPADDD     ·chacha20Constants<>+0(SB), Y0, Y0\n\tVPADDD     ·chacha20Constants<>+0(SB), Y5, Y5\n\tVPADDD     32(BP), Y14, Y14\n\tVPADDD     32(BP), Y9, Y9\n\tVPADDD     64(BP), Y12, Y12\n\tVPADDD     64(BP), Y13, Y13\n\tVPADDD     Y7, Y4, Y4\n\tVPADDD     Y11, Y1, Y1\n\tVPERM2I128 $0x02, Y0, Y14, Y3\n\tVPERM2I128 $0x02, Y12, Y4, Y7\n\tVPERM2I128 $0x13, Y0, Y14, Y11\n\tVPERM2I128 $0x13, Y12, Y4, Y15\n\tVPXOR      (SI), Y3, Y3\n\tVPXOR      32(SI), Y7, Y7\n\tVPXOR      64(SI), Y11, Y11\n\tVPXOR      96(SI), Y15, Y15\n\tVMOVDQU    Y3, (DI)\n\tVMOVDQU    Y7, 32(DI)\n\tVMOVDQU    Y11, 64(DI)\n\tVMOVDQU    Y15, 96(DI)\n\tMOVQ       $0x00000080, CX\n\tLEAQ       128(SI), SI\n\tSUBQ       $0x80, BX\n\tVPERM2I128 $0x02, Y5, Y9, Y0\n\tVPERM2I128 $0x02, Y13, Y1, Y14\n\tVPERM2I128 $0x13, Y5, Y9, Y12\n\tVPERM2I128 $0x13, Y13, Y1, Y4\n\tJMP        sealAVX2SealHash\n\nsealAVX2Tail384:\n\tVMOVDQA ·chacha20Constants<>+0(SB), Y0\n\tVMOVDQA Y0, Y5\n\tVMOVDQA Y0, Y6\n\tVMOVDQA 32(BP), Y14\n\tVMOVDQA Y14, Y9\n\tVMOVDQA Y14, Y10\n\tVMOVDQA 64(BP), Y12\n\tVMOVDQA Y12, Y13\n\tVMOVDQA Y12, Y8\n\tVMOVDQA 192(BP), Y4\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y4\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y1\n\tVPADDD  ·avx2IncMask<>+0(SB), Y1, Y2\n\tVMOVDQA Y4, Y7\n\tVMOVDQA Y1, Y11\n\tVMOVDQA Y2, Y15\n\nsealAVX2Tail384LoopA:\n\tADDQ  (DI), R10\n\tADCQ  8(DI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(DI), DI\n\nsealAVX2Tail384LoopB:\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol16<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x0c, Y14, Y3\n\tVPSRLD     $0x14, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol8<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x07, Y14, Y3\n\tVPSRLD     $0x19, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol16<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x0c, Y9, Y3\n\tVPSRLD     $0x14, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol8<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x07, Y9, Y3\n\tVPSRLD     $0x19, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPADDD     Y10, Y6, Y6\n\tVPXOR      Y6, Y2, Y2\n\tVPSHUFB    ·rol16<>+0(SB), Y2, Y2\n\tVPADDD     Y2, Y8, Y8\n\tVPXOR      Y8, Y10, Y10\n\tVPSLLD     $0x0c, Y10, Y3\n\tVPSRLD     $0x14, Y10, Y10\n\tVPXOR      Y3, Y10, Y10\n\tVPADDD     Y10, Y6, Y6\n\tVPXOR      Y6, Y2, Y2\n\tVPSHUFB    ·rol8<>+0(SB), Y2, Y2\n\tVPADDD     Y2, Y8, Y8\n\tVPXOR      Y8, Y10, Y10\n\tVPSLLD     $0x07, Y10, Y3\n\tVPSRLD     $0x19, Y10, Y10\n\tVPXOR      Y3, Y10, Y10\n\tADDQ       (DI), R10\n\tADCQ       8(DI), R11\n\tADCQ       $0x01, R12\n\tMOVQ       (BP), AX\n\tMOVQ       AX, R15\n\tMULQ       R10\n\tMOVQ       AX, R13\n\tMOVQ       DX, R14\n\tMOVQ       (BP), AX\n\tMULQ       R11\n\tIMULQ      R12, R15\n\tADDQ       AX, R14\n\tADCQ       DX, R15\n\tMOVQ       8(BP), AX\n\tMOVQ       AX, R8\n\tMULQ       R10\n\tADDQ       AX, R14\n\tADCQ       $0x00, DX\n\tMOVQ       DX, R10\n\tMOVQ       8(BP), AX\n\tMULQ       R11\n\tADDQ       AX, R15\n\tADCQ       $0x00, DX\n\tIMULQ      R12, R8\n\tADDQ       R10, R15\n\tADCQ       DX, R8\n\tMOVQ       R13, R10\n\tMOVQ       R14, R11\n\tMOVQ       R15, R12\n\tANDQ       $0x03, R12\n\tMOVQ       R15, R13\n\tANDQ       $-4, R13\n\tMOVQ       R8, R14\n\tSHRQ       $0x02, R8, R15\n\tSHRQ       $0x02, R8\n\tADDQ       R13, R10\n\tADCQ       R14, R11\n\tADCQ       $0x00, R12\n\tADDQ       R15, R10\n\tADCQ       R8, R11\n\tADCQ       $0x00, R12\n\tVPALIGNR   $0x04, Y14, Y14, Y14\n\tVPALIGNR   $0x04, Y9, Y9, Y9\n\tVPALIGNR   $0x04, Y10, Y10, Y10\n\tVPALIGNR   $0x08, Y12, Y12, Y12\n\tVPALIGNR   $0x08, Y13, Y13, Y13\n\tVPALIGNR   $0x08, Y8, Y8, Y8\n\tVPALIGNR   $0x0c, Y4, Y4, Y4\n\tVPALIGNR   $0x0c, Y1, Y1, Y1\n\tVPALIGNR   $0x0c, Y2, Y2, Y2\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol16<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x0c, Y14, Y3\n\tVPSRLD     $0x14, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y14, Y0, Y0\n\tVPXOR      Y0, Y4, Y4\n\tVPSHUFB    ·rol8<>+0(SB), Y4, Y4\n\tVPADDD     Y4, Y12, Y12\n\tVPXOR      Y12, Y14, Y14\n\tVPSLLD     $0x07, Y14, Y3\n\tVPSRLD     $0x19, Y14, Y14\n\tVPXOR      Y3, Y14, Y14\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol16<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x0c, Y9, Y3\n\tVPSRLD     $0x14, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPADDD     Y9, Y5, Y5\n\tVPXOR      Y5, Y1, Y1\n\tVPSHUFB    ·rol8<>+0(SB), Y1, Y1\n\tVPADDD     Y1, Y13, Y13\n\tVPXOR      Y13, Y9, Y9\n\tVPSLLD     $0x07, Y9, Y3\n\tVPSRLD     $0x19, Y9, Y9\n\tVPXOR      Y3, Y9, Y9\n\tVPADDD     Y10, Y6, Y6\n\tVPXOR      Y6, Y2, Y2\n\tVPSHUFB    ·rol16<>+0(SB), Y2, Y2\n\tVPADDD     Y2, Y8, Y8\n\tVPXOR      Y8, Y10, Y10\n\tVPSLLD     $0x0c, Y10, Y3\n\tVPSRLD     $0x14, Y10, Y10\n\tVPXOR      Y3, Y10, Y10\n\tVPADDD     Y10, Y6, Y6\n\tVPXOR      Y6, Y2, Y2\n\tVPSHUFB    ·rol8<>+0(SB), Y2, Y2\n\tVPADDD     Y2, Y8, Y8\n\tVPXOR      Y8, Y10, Y10\n\tVPSLLD     $0x07, Y10, Y3\n\tVPSRLD     $0x19, Y10, Y10\n\tVPXOR      Y3, Y10, Y10\n\tADDQ       16(DI), R10\n\tADCQ       24(DI), R11\n\tADCQ       $0x01, R12\n\tMOVQ       (BP), AX\n\tMOVQ       AX, R15\n\tMULQ       R10\n\tMOVQ       AX, R13\n\tMOVQ       DX, R14\n\tMOVQ       (BP), AX\n\tMULQ       R11\n\tIMULQ      R12, R15\n\tADDQ       AX, R14\n\tADCQ       DX, R15\n\tMOVQ       8(BP), AX\n\tMOVQ       AX, R8\n\tMULQ       R10\n\tADDQ       AX, R14\n\tADCQ       $0x00, DX\n\tMOVQ       DX, R10\n\tMOVQ       8(BP), AX\n\tMULQ       R11\n\tADDQ       AX, R15\n\tADCQ       $0x00, DX\n\tIMULQ      R12, R8\n\tADDQ       R10, R15\n\tADCQ       DX, R8\n\tMOVQ       R13, R10\n\tMOVQ       R14, R11\n\tMOVQ       R15, R12\n\tANDQ       $0x03, R12\n\tMOVQ       R15, R13\n\tANDQ       $-4, R13\n\tMOVQ       R8, R14\n\tSHRQ       $0x02, R8, R15\n\tSHRQ       $0x02, R8\n\tADDQ       R13, R10\n\tADCQ       R14, R11\n\tADCQ       $0x00, R12\n\tADDQ       R15, R10\n\tADCQ       R8, R11\n\tADCQ       $0x00, R12\n\tLEAQ       32(DI), DI\n\tVPALIGNR   $0x0c, Y14, Y14, Y14\n\tVPALIGNR   $0x0c, Y9, Y9, Y9\n\tVPALIGNR   $0x0c, Y10, Y10, Y10\n\tVPALIGNR   $0x08, Y12, Y12, Y12\n\tVPALIGNR   $0x08, Y13, Y13, Y13\n\tVPALIGNR   $0x08, Y8, Y8, Y8\n\tVPALIGNR   $0x04, Y4, Y4, Y4\n\tVPALIGNR   $0x04, Y1, Y1, Y1\n\tVPALIGNR   $0x04, Y2, Y2, Y2\n\tDECQ       CX\n\tJG         sealAVX2Tail384LoopA\n\tDECQ       R9\n\tJGE        sealAVX2Tail384LoopB\n\tVPADDD     ·chacha20Constants<>+0(SB), Y0, Y0\n\tVPADDD     ·chacha20Constants<>+0(SB), Y5, Y5\n\tVPADDD     ·chacha20Constants<>+0(SB), Y6, Y6\n\tVPADDD     32(BP), Y14, Y14\n\tVPADDD     32(BP), Y9, Y9\n\tVPADDD     32(BP), Y10, Y10\n\tVPADDD     64(BP), Y12, Y12\n\tVPADDD     64(BP), Y13, Y13\n\tVPADDD     64(BP), Y8, Y8\n\tVPADDD     Y7, Y4, Y4\n\tVPADDD     Y11, Y1, Y1\n\tVPADDD     Y15, Y2, Y2\n\tVPERM2I128 $0x02, Y0, Y14, Y3\n\tVPERM2I128 $0x02, Y12, Y4, Y7\n\tVPERM2I128 $0x13, Y0, Y14, Y11\n\tVPERM2I128 $0x13, Y12, Y4, Y15\n\tVPXOR      (SI), Y3, Y3\n\tVPXOR      32(SI), Y7, Y7\n\tVPXOR      64(SI), Y11, Y11\n\tVPXOR      96(SI), Y15, Y15\n\tVMOVDQU    Y3, (DI)\n\tVMOVDQU    Y7, 32(DI)\n\tVMOVDQU    Y11, 64(DI)\n\tVMOVDQU    Y15, 96(DI)\n\tVPERM2I128 $0x02, Y5, Y9, Y3\n\tVPERM2I128 $0x02, Y13, Y1, Y7\n\tVPERM2I128 $0x13, Y5, Y9, Y11\n\tVPERM2I128 $0x13, Y13, Y1, Y15\n\tVPXOR      128(SI), Y3, Y3\n\tVPXOR      160(SI), Y7, Y7\n\tVPXOR      192(SI), Y11, Y11\n\tVPXOR      224(SI), Y15, Y15\n\tVMOVDQU    Y3, 128(DI)\n\tVMOVDQU    Y7, 160(DI)\n\tVMOVDQU    Y11, 192(DI)\n\tVMOVDQU    Y15, 224(DI)\n\tMOVQ       $0x00000100, CX\n\tLEAQ       256(SI), SI\n\tSUBQ       $0x00000100, BX\n\tVPERM2I128 $0x02, Y6, Y10, Y0\n\tVPERM2I128 $0x02, Y8, Y2, Y14\n\tVPERM2I128 $0x13, Y6, Y10, Y12\n\tVPERM2I128 $0x13, Y8, Y2, Y4\n\tJMP        sealAVX2SealHash\n\nsealAVX2Tail512:\n\tVMOVDQA ·chacha20Constants<>+0(SB), Y0\n\tVMOVDQA Y0, Y5\n\tVMOVDQA Y0, Y6\n\tVMOVDQA Y0, Y7\n\tVMOVDQA 32(BP), Y14\n\tVMOVDQA Y14, Y9\n\tVMOVDQA Y14, Y10\n\tVMOVDQA Y14, Y11\n\tVMOVDQA 64(BP), Y12\n\tVMOVDQA Y12, Y13\n\tVMOVDQA Y12, Y8\n\tVMOVDQA Y12, Y15\n\tVMOVDQA 192(BP), Y4\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y4\n\tVPADDD  ·avx2IncMask<>+0(SB), Y4, Y1\n\tVPADDD  ·avx2IncMask<>+0(SB), Y1, Y2\n\tVPADDD  ·avx2IncMask<>+0(SB), Y2, Y3\n\tVMOVDQA Y4, 96(BP)\n\tVMOVDQA Y1, 128(BP)\n\tVMOVDQA Y2, 160(BP)\n\tVMOVDQA Y3, 192(BP)\n\nsealAVX2Tail512LoopA:\n\tADDQ  (DI), R10\n\tADCQ  8(DI), R11\n\tADCQ  $0x01, R12\n\tMOVQ  (BP), AX\n\tMOVQ  AX, R15\n\tMULQ  R10\n\tMOVQ  AX, R13\n\tMOVQ  DX, R14\n\tMOVQ  (BP), AX\n\tMULQ  R11\n\tIMULQ R12, R15\n\tADDQ  AX, R14\n\tADCQ  DX, R15\n\tMOVQ  8(BP), AX\n\tMOVQ  AX, R8\n\tMULQ  R10\n\tADDQ  AX, R14\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R10\n\tMOVQ  8(BP), AX\n\tMULQ  R11\n\tADDQ  AX, R15\n\tADCQ  $0x00, DX\n\tIMULQ R12, R8\n\tADDQ  R10, R15\n\tADCQ  DX, R8\n\tMOVQ  R13, R10\n\tMOVQ  R14, R11\n\tMOVQ  R15, R12\n\tANDQ  $0x03, R12\n\tMOVQ  R15, R13\n\tANDQ  $-4, R13\n\tMOVQ  R8, R14\n\tSHRQ  $0x02, R8, R15\n\tSHRQ  $0x02, R8\n\tADDQ  R13, R10\n\tADCQ  R14, R11\n\tADCQ  $0x00, R12\n\tADDQ  R15, R10\n\tADCQ  R8, R11\n\tADCQ  $0x00, R12\n\tLEAQ  16(DI), DI\n\nsealAVX2Tail512LoopB:\n\tVPADDD     Y14, Y0, Y0\n\tVPADDD     Y9, Y5, Y5\n\tVPADDD     Y10, Y6, Y6\n\tVPADDD     Y11, Y7, Y7\n\tVPXOR      Y0, Y4, Y4\n\tVPXOR      Y5, Y1, Y1\n\tVPXOR      Y6, Y2, Y2\n\tVPXOR      Y7, Y3, Y3\n\tVPSHUFB    ·rol16<>+0(SB), Y4, Y4\n\tVPSHUFB    ·rol16<>+0(SB), Y1, Y1\n\tVPSHUFB    ·rol16<>+0(SB), Y2, Y2\n\tVPSHUFB    ·rol16<>+0(SB), Y3, Y3\n\tVPADDD     Y4, Y12, Y12\n\tVPADDD     Y1, Y13, Y13\n\tVPADDD     Y2, Y8, Y8\n\tVPADDD     Y3, Y15, Y15\n\tVPXOR      Y12, Y14, Y14\n\tVPXOR      Y13, Y9, Y9\n\tVPXOR      Y8, Y10, Y10\n\tVPXOR      Y15, Y11, Y11\n\tVMOVDQA    Y15, 224(BP)\n\tVPSLLD     $0x0c, Y14, Y15\n\tVPSRLD     $0x14, Y14, Y14\n\tVPXOR      Y15, Y14, Y14\n\tVPSLLD     $0x0c, Y9, Y15\n\tVPSRLD     $0x14, Y9, Y9\n\tVPXOR      Y15, Y9, Y9\n\tVPSLLD     $0x0c, Y10, Y15\n\tVPSRLD     $0x14, Y10, Y10\n\tVPXOR      Y15, Y10, Y10\n\tVPSLLD     $0x0c, Y11, Y15\n\tVPSRLD     $0x14, Y11, Y11\n\tVPXOR      Y15, Y11, Y11\n\tVMOVDQA    224(BP), Y15\n\tADDQ       (DI), R10\n\tADCQ       8(DI), R11\n\tADCQ       $0x01, R12\n\tMOVQ       (BP), DX\n\tMOVQ       DX, R15\n\tMULXQ      R10, R13, R14\n\tIMULQ      R12, R15\n\tMULXQ      R11, AX, DX\n\tADDQ       AX, R14\n\tADCQ       DX, R15\n\tMOVQ       8(BP), DX\n\tMULXQ      R10, R10, AX\n\tADDQ       R10, R14\n\tMULXQ      R11, R11, R8\n\tADCQ       R11, R15\n\tADCQ       $0x00, R8\n\tIMULQ      R12, DX\n\tADDQ       AX, R15\n\tADCQ       DX, R8\n\tMOVQ       R13, R10\n\tMOVQ       R14, R11\n\tMOVQ       R15, R12\n\tANDQ       $0x03, R12\n\tMOVQ       R15, R13\n\tANDQ       $-4, R13\n\tMOVQ       R8, R14\n\tSHRQ       $0x02, R8, R15\n\tSHRQ       $0x02, R8\n\tADDQ       R13, R10\n\tADCQ       R14, R11\n\tADCQ       $0x00, R12\n\tADDQ       R15, R10\n\tADCQ       R8, R11\n\tADCQ       $0x00, R12\n\tVPADDD     Y14, Y0, Y0\n\tVPADDD     Y9, Y5, Y5\n\tVPADDD     Y10, Y6, Y6\n\tVPADDD     Y11, Y7, Y7\n\tVPXOR      Y0, Y4, Y4\n\tVPXOR      Y5, Y1, Y1\n\tVPXOR      Y6, Y2, Y2\n\tVPXOR      Y7, Y3, Y3\n\tVPSHUFB    ·rol8<>+0(SB), Y4, Y4\n\tVPSHUFB    ·rol8<>+0(SB), Y1, Y1\n\tVPSHUFB    ·rol8<>+0(SB), Y2, Y2\n\tVPSHUFB    ·rol8<>+0(SB), Y3, Y3\n\tVPADDD     Y4, Y12, Y12\n\tVPADDD     Y1, Y13, Y13\n\tVPADDD     Y2, Y8, Y8\n\tVPADDD     Y3, Y15, Y15\n\tVPXOR      Y12, Y14, Y14\n\tVPXOR      Y13, Y9, Y9\n\tVPXOR      Y8, Y10, Y10\n\tVPXOR      Y15, Y11, Y11\n\tVMOVDQA    Y15, 224(BP)\n\tVPSLLD     $0x07, Y14, Y15\n\tVPSRLD     $0x19, Y14, Y14\n\tVPXOR      Y15, Y14, Y14\n\tVPSLLD     $0x07, Y9, Y15\n\tVPSRLD     $0x19, Y9, Y9\n\tVPXOR      Y15, Y9, Y9\n\tVPSLLD     $0x07, Y10, Y15\n\tVPSRLD     $0x19, Y10, Y10\n\tVPXOR      Y15, Y10, Y10\n\tVPSLLD     $0x07, Y11, Y15\n\tVPSRLD     $0x19, Y11, Y11\n\tVPXOR      Y15, Y11, Y11\n\tVMOVDQA    224(BP), Y15\n\tVPALIGNR   $0x04, Y14, Y14, Y14\n\tVPALIGNR   $0x04, Y9, Y9, Y9\n\tVPALIGNR   $0x04, Y10, Y10, Y10\n\tVPALIGNR   $0x04, Y11, Y11, Y11\n\tVPALIGNR   $0x08, Y12, Y12, Y12\n\tVPALIGNR   $0x08, Y13, Y13, Y13\n\tVPALIGNR   $0x08, Y8, Y8, Y8\n\tVPALIGNR   $0x08, Y15, Y15, Y15\n\tVPALIGNR   $0x0c, Y4, Y4, Y4\n\tVPALIGNR   $0x0c, Y1, Y1, Y1\n\tVPALIGNR   $0x0c, Y2, Y2, Y2\n\tVPALIGNR   $0x0c, Y3, Y3, Y3\n\tVPADDD     Y14, Y0, Y0\n\tVPADDD     Y9, Y5, Y5\n\tVPADDD     Y10, Y6, Y6\n\tVPADDD     Y11, Y7, Y7\n\tVPXOR      Y0, Y4, Y4\n\tVPXOR      Y5, Y1, Y1\n\tVPXOR      Y6, Y2, Y2\n\tVPXOR      Y7, Y3, Y3\n\tVPSHUFB    ·rol16<>+0(SB), Y4, Y4\n\tVPSHUFB    ·rol16<>+0(SB), Y1, Y1\n\tVPSHUFB    ·rol16<>+0(SB), Y2, Y2\n\tVPSHUFB    ·rol16<>+0(SB), Y3, Y3\n\tVPADDD     Y4, Y12, Y12\n\tVPADDD     Y1, Y13, Y13\n\tVPADDD     Y2, Y8, Y8\n\tVPADDD     Y3, Y15, Y15\n\tVPXOR      Y12, Y14, Y14\n\tVPXOR      Y13, Y9, Y9\n\tVPXOR      Y8, Y10, Y10\n\tVPXOR      Y15, Y11, Y11\n\tADDQ       16(DI), R10\n\tADCQ       24(DI), R11\n\tADCQ       $0x01, R12\n\tMOVQ       (BP), DX\n\tMOVQ       DX, R15\n\tMULXQ      R10, R13, R14\n\tIMULQ      R12, R15\n\tMULXQ      R11, AX, DX\n\tADDQ       AX, R14\n\tADCQ       DX, R15\n\tMOVQ       8(BP), DX\n\tMULXQ      R10, R10, AX\n\tADDQ       R10, R14\n\tMULXQ      R11, R11, R8\n\tADCQ       R11, R15\n\tADCQ       $0x00, R8\n\tIMULQ      R12, DX\n\tADDQ       AX, R15\n\tADCQ       DX, R8\n\tMOVQ       R13, R10\n\tMOVQ       R14, R11\n\tMOVQ       R15, R12\n\tANDQ       $0x03, R12\n\tMOVQ       R15, R13\n\tANDQ       $-4, R13\n\tMOVQ       R8, R14\n\tSHRQ       $0x02, R8, R15\n\tSHRQ       $0x02, R8\n\tADDQ       R13, R10\n\tADCQ       R14, R11\n\tADCQ       $0x00, R12\n\tADDQ       R15, R10\n\tADCQ       R8, R11\n\tADCQ       $0x00, R12\n\tLEAQ       32(DI), DI\n\tVMOVDQA    Y15, 224(BP)\n\tVPSLLD     $0x0c, Y14, Y15\n\tVPSRLD     $0x14, Y14, Y14\n\tVPXOR      Y15, Y14, Y14\n\tVPSLLD     $0x0c, Y9, Y15\n\tVPSRLD     $0x14, Y9, Y9\n\tVPXOR      Y15, Y9, Y9\n\tVPSLLD     $0x0c, Y10, Y15\n\tVPSRLD     $0x14, Y10, Y10\n\tVPXOR      Y15, Y10, Y10\n\tVPSLLD     $0x0c, Y11, Y15\n\tVPSRLD     $0x14, Y11, Y11\n\tVPXOR      Y15, Y11, Y11\n\tVMOVDQA    224(BP), Y15\n\tVPADDD     Y14, Y0, Y0\n\tVPADDD     Y9, Y5, Y5\n\tVPADDD     Y10, Y6, Y6\n\tVPADDD     Y11, Y7, Y7\n\tVPXOR      Y0, Y4, Y4\n\tVPXOR      Y5, Y1, Y1\n\tVPXOR      Y6, Y2, Y2\n\tVPXOR      Y7, Y3, Y3\n\tVPSHUFB    ·rol8<>+0(SB), Y4, Y4\n\tVPSHUFB    ·rol8<>+0(SB), Y1, Y1\n\tVPSHUFB    ·rol8<>+0(SB), Y2, Y2\n\tVPSHUFB    ·rol8<>+0(SB), Y3, Y3\n\tVPADDD     Y4, Y12, Y12\n\tVPADDD     Y1, Y13, Y13\n\tVPADDD     Y2, Y8, Y8\n\tVPADDD     Y3, Y15, Y15\n\tVPXOR      Y12, Y14, Y14\n\tVPXOR      Y13, Y9, Y9\n\tVPXOR      Y8, Y10, Y10\n\tVPXOR      Y15, Y11, Y11\n\tVMOVDQA    Y15, 224(BP)\n\tVPSLLD     $0x07, Y14, Y15\n\tVPSRLD     $0x19, Y14, Y14\n\tVPXOR      Y15, Y14, Y14\n\tVPSLLD     $0x07, Y9, Y15\n\tVPSRLD     $0x19, Y9, Y9\n\tVPXOR      Y15, Y9, Y9\n\tVPSLLD     $0x07, Y10, Y15\n\tVPSRLD     $0x19, Y10, Y10\n\tVPXOR      Y15, Y10, Y10\n\tVPSLLD     $0x07, Y11, Y15\n\tVPSRLD     $0x19, Y11, Y11\n\tVPXOR      Y15, Y11, Y11\n\tVMOVDQA    224(BP), Y15\n\tVPALIGNR   $0x0c, Y14, Y14, Y14\n\tVPALIGNR   $0x0c, Y9, Y9, Y9\n\tVPALIGNR   $0x0c, Y10, Y10, Y10\n\tVPALIGNR   $0x0c, Y11, Y11, Y11\n\tVPALIGNR   $0x08, Y12, Y12, Y12\n\tVPALIGNR   $0x08, Y13, Y13, Y13\n\tVPALIGNR   $0x08, Y8, Y8, Y8\n\tVPALIGNR   $0x08, Y15, Y15, Y15\n\tVPALIGNR   $0x04, Y4, Y4, Y4\n\tVPALIGNR   $0x04, Y1, Y1, Y1\n\tVPALIGNR   $0x04, Y2, Y2, Y2\n\tVPALIGNR   $0x04, Y3, Y3, Y3\n\tDECQ       CX\n\tJG         sealAVX2Tail512LoopA\n\tDECQ       R9\n\tJGE        sealAVX2Tail512LoopB\n\tVPADDD     ·chacha20Constants<>+0(SB), Y0, Y0\n\tVPADDD     ·chacha20Constants<>+0(SB), Y5, Y5\n\tVPADDD     ·chacha20Constants<>+0(SB), Y6, Y6\n\tVPADDD     ·chacha20Constants<>+0(SB), Y7, Y7\n\tVPADDD     32(BP), Y14, Y14\n\tVPADDD     32(BP), Y9, Y9\n\tVPADDD     32(BP), Y10, Y10\n\tVPADDD     32(BP), Y11, Y11\n\tVPADDD     64(BP), Y12, Y12\n\tVPADDD     64(BP), Y13, Y13\n\tVPADDD     64(BP), Y8, Y8\n\tVPADDD     64(BP), Y15, Y15\n\tVPADDD     96(BP), Y4, Y4\n\tVPADDD     128(BP), Y1, Y1\n\tVPADDD     160(BP), Y2, Y2\n\tVPADDD     192(BP), Y3, Y3\n\tVMOVDQA    Y15, 224(BP)\n\tVPERM2I128 $0x02, Y0, Y14, Y15\n\tVPXOR      (SI), Y15, Y15\n\tVMOVDQU    Y15, (DI)\n\tVPERM2I128 $0x02, Y12, Y4, Y15\n\tVPXOR      32(SI), Y15, Y15\n\tVMOVDQU    Y15, 32(DI)\n\tVPERM2I128 $0x13, Y0, Y14, Y15\n\tVPXOR      64(SI), Y15, Y15\n\tVMOVDQU    Y15, 64(DI)\n\tVPERM2I128 $0x13, Y12, Y4, Y15\n\tVPXOR      96(SI), Y15, Y15\n\tVMOVDQU    Y15, 96(DI)\n\tVPERM2I128 $0x02, Y5, Y9, Y0\n\tVPERM2I128 $0x02, Y13, Y1, Y14\n\tVPERM2I128 $0x13, Y5, Y9, Y12\n\tVPERM2I128 $0x13, Y13, Y1, Y4\n\tVPXOR      128(SI), Y0, Y0\n\tVPXOR      160(SI), Y14, Y14\n\tVPXOR      192(SI), Y12, Y12\n\tVPXOR      224(SI), Y4, Y4\n\tVMOVDQU    Y0, 128(DI)\n\tVMOVDQU    Y14, 160(DI)\n\tVMOVDQU    Y12, 192(DI)\n\tVMOVDQU    Y4, 224(DI)\n\tVPERM2I128 $0x02, Y6, Y10, Y0\n\tVPERM2I128 $0x02, Y8, Y2, Y14\n\tVPERM2I128 $0x13, Y6, Y10, Y12\n\tVPERM2I128 $0x13, Y8, Y2, Y4\n\tVPXOR      256(SI), Y0, Y0\n\tVPXOR      288(SI), Y14, Y14\n\tVPXOR      320(SI), Y12, Y12\n\tVPXOR      352(SI), Y4, Y4\n\tVMOVDQU    Y0, 256(DI)\n\tVMOVDQU    Y14, 288(DI)\n\tVMOVDQU    Y12, 320(DI)\n\tVMOVDQU    Y4, 352(DI)\n\tMOVQ       $0x00000180, CX\n\tLEAQ       384(SI), SI\n\tSUBQ       $0x00000180, BX\n\tVPERM2I128 $0x02, Y7, Y11, Y0\n\tVPERM2I128 $0x02, 224(BP), Y3, Y14\n\tVPERM2I128 $0x13, Y7, Y11, Y12\n\tVPERM2I128 $0x13, 224(BP), Y3, Y4\n\tJMP        sealAVX2SealHash\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go",
    "content": "// Copyright 2016 The Go 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 chacha20poly1305\n\nimport (\n\t\"encoding/binary\"\n\n\t\"golang.org/x/crypto/chacha20\"\n\t\"golang.org/x/crypto/internal/alias\"\n\t\"golang.org/x/crypto/internal/poly1305\"\n)\n\nfunc writeWithPadding(p *poly1305.MAC, b []byte) {\n\tp.Write(b)\n\tif rem := len(b) % 16; rem != 0 {\n\t\tvar buf [16]byte\n\t\tpadLen := 16 - rem\n\t\tp.Write(buf[:padLen])\n\t}\n}\n\nfunc writeUint64(p *poly1305.MAC, n int) {\n\tvar buf [8]byte\n\tbinary.LittleEndian.PutUint64(buf[:], uint64(n))\n\tp.Write(buf[:])\n}\n\nfunc (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte {\n\tret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize)\n\tciphertext, tag := out[:len(plaintext)], out[len(plaintext):]\n\tif alias.InexactOverlap(out, plaintext) {\n\t\tpanic(\"chacha20poly1305: invalid buffer overlap\")\n\t}\n\n\tvar polyKey [32]byte\n\ts, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce)\n\ts.XORKeyStream(polyKey[:], polyKey[:])\n\ts.SetCounter(1) // set the counter to 1, skipping 32 bytes\n\ts.XORKeyStream(ciphertext, plaintext)\n\n\tp := poly1305.New(&polyKey)\n\twriteWithPadding(p, additionalData)\n\twriteWithPadding(p, ciphertext)\n\twriteUint64(p, len(additionalData))\n\twriteUint64(p, len(plaintext))\n\tp.Sum(tag[:0])\n\n\treturn ret\n}\n\nfunc (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {\n\ttag := ciphertext[len(ciphertext)-16:]\n\tciphertext = ciphertext[:len(ciphertext)-16]\n\n\tvar polyKey [32]byte\n\ts, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce)\n\ts.XORKeyStream(polyKey[:], polyKey[:])\n\ts.SetCounter(1) // set the counter to 1, skipping 32 bytes\n\n\tp := poly1305.New(&polyKey)\n\twriteWithPadding(p, additionalData)\n\twriteWithPadding(p, ciphertext)\n\twriteUint64(p, len(additionalData))\n\twriteUint64(p, len(ciphertext))\n\n\tret, out := sliceForAppend(dst, len(ciphertext))\n\tif alias.InexactOverlap(out, ciphertext) {\n\t\tpanic(\"chacha20poly1305: invalid buffer overlap\")\n\t}\n\tif !p.Verify(tag) {\n\t\tfor i := range out {\n\t\t\tout[i] = 0\n\t\t}\n\t\treturn nil, errOpen\n\t}\n\n\ts.XORKeyStream(out, ciphertext)\n\treturn ret, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go",
    "content": "// Copyright 2016 The Go 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\n//go:build !amd64 || !gc || purego\n\npackage chacha20poly1305\n\nfunc (c *chacha20poly1305) seal(dst, nonce, plaintext, additionalData []byte) []byte {\n\treturn c.sealGeneric(dst, nonce, plaintext, additionalData)\n}\n\nfunc (c *chacha20poly1305) open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {\n\treturn c.openGeneric(dst, nonce, ciphertext, additionalData)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go",
    "content": "// Copyright 2018 The Go 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 chacha20poly1305\n\nimport (\n\t\"crypto/cipher\"\n\t\"errors\"\n\n\t\"golang.org/x/crypto/chacha20\"\n)\n\ntype xchacha20poly1305 struct {\n\tkey [KeySize]byte\n}\n\n// NewX returns a XChaCha20-Poly1305 AEAD that uses the given 256-bit key.\n//\n// XChaCha20-Poly1305 is a ChaCha20-Poly1305 variant that takes a longer nonce,\n// suitable to be generated randomly without risk of collisions. It should be\n// preferred when nonce uniqueness cannot be trivially ensured, or whenever\n// nonces are randomly generated.\nfunc NewX(key []byte) (cipher.AEAD, error) {\n\tif len(key) != KeySize {\n\t\treturn nil, errors.New(\"chacha20poly1305: bad key length\")\n\t}\n\tret := new(xchacha20poly1305)\n\tcopy(ret.key[:], key)\n\treturn ret, nil\n}\n\nfunc (*xchacha20poly1305) NonceSize() int {\n\treturn NonceSizeX\n}\n\nfunc (*xchacha20poly1305) Overhead() int {\n\treturn Overhead\n}\n\nfunc (x *xchacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte {\n\tif len(nonce) != NonceSizeX {\n\t\tpanic(\"chacha20poly1305: bad nonce length passed to Seal\")\n\t}\n\n\t// XChaCha20-Poly1305 technically supports a 64-bit counter, so there is no\n\t// size limit. However, since we reuse the ChaCha20-Poly1305 implementation,\n\t// the second half of the counter is not available. This is unlikely to be\n\t// an issue because the cipher.AEAD API requires the entire message to be in\n\t// memory, and the counter overflows at 256 GB.\n\tif uint64(len(plaintext)) > (1<<38)-64 {\n\t\tpanic(\"chacha20poly1305: plaintext too large\")\n\t}\n\n\tc := new(chacha20poly1305)\n\thKey, _ := chacha20.HChaCha20(x.key[:], nonce[0:16])\n\tcopy(c.key[:], hKey)\n\n\t// The first 4 bytes of the final nonce are unused counter space.\n\tcNonce := make([]byte, NonceSize)\n\tcopy(cNonce[4:12], nonce[16:24])\n\n\treturn c.seal(dst, cNonce[:], plaintext, additionalData)\n}\n\nfunc (x *xchacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {\n\tif len(nonce) != NonceSizeX {\n\t\tpanic(\"chacha20poly1305: bad nonce length passed to Open\")\n\t}\n\tif len(ciphertext) < 16 {\n\t\treturn nil, errOpen\n\t}\n\tif uint64(len(ciphertext)) > (1<<38)-48 {\n\t\tpanic(\"chacha20poly1305: ciphertext too large\")\n\t}\n\n\tc := new(chacha20poly1305)\n\thKey, _ := chacha20.HChaCha20(x.key[:], nonce[0:16])\n\tcopy(c.key[:], hKey)\n\n\t// The first 4 bytes of the final nonce are unused counter space.\n\tcNonce := make([]byte, NonceSize)\n\tcopy(cNonce[4:12], nonce[16:24])\n\n\treturn c.open(dst, cNonce[:], ciphertext, additionalData)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/curve25519/curve25519.go",
    "content": "// Copyright 2019 The Go 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\n// Package curve25519 provides an implementation of the X25519 function, which\n// performs scalar multiplication on the elliptic curve known as Curve25519.\n// See RFC 7748.\n//\n// This package is a wrapper for the X25519 implementation\n// in the crypto/ecdh package.\npackage curve25519\n\nimport \"crypto/ecdh\"\n\n// ScalarMult sets dst to the product scalar * point.\n//\n// Deprecated: when provided a low-order point, ScalarMult will set dst to all\n// zeroes, irrespective of the scalar. Instead, use the X25519 function, which\n// will return an error.\nfunc ScalarMult(dst, scalar, point *[32]byte) {\n\tif _, err := x25519(dst, scalar[:], point[:]); err != nil {\n\t\t// The only error condition for x25519 when the inputs are 32 bytes long\n\t\t// is if the output would have been the all-zero value.\n\t\tfor i := range dst {\n\t\t\tdst[i] = 0\n\t\t}\n\t}\n}\n\n// ScalarBaseMult sets dst to the product scalar * base where base is the\n// standard generator.\n//\n// It is recommended to use the X25519 function with Basepoint instead, as\n// copying into fixed size arrays can lead to unexpected bugs.\nfunc ScalarBaseMult(dst, scalar *[32]byte) {\n\tcurve := ecdh.X25519()\n\tpriv, err := curve.NewPrivateKey(scalar[:])\n\tif err != nil {\n\t\tpanic(\"curve25519: internal error: scalarBaseMult was not 32 bytes\")\n\t}\n\tcopy(dst[:], priv.PublicKey().Bytes())\n}\n\nconst (\n\t// ScalarSize is the size of the scalar input to X25519.\n\tScalarSize = 32\n\t// PointSize is the size of the point input to X25519.\n\tPointSize = 32\n)\n\n// Basepoint is the canonical Curve25519 generator.\nvar Basepoint []byte\n\nvar basePoint = [32]byte{9}\n\nfunc init() { Basepoint = basePoint[:] }\n\n// X25519 returns the result of the scalar multiplication (scalar * point),\n// according to RFC 7748, Section 5. scalar, point and the return value are\n// slices of 32 bytes.\n//\n// scalar can be generated at random, for example with crypto/rand. point should\n// be either Basepoint or the output of another X25519 call.\n//\n// If point is Basepoint (but not if it's a different slice with the same\n// contents) a precomputed implementation might be used for performance.\nfunc X25519(scalar, point []byte) ([]byte, error) {\n\t// Outline the body of function, to let the allocation be inlined in the\n\t// caller, and possibly avoid escaping to the heap.\n\tvar dst [32]byte\n\treturn x25519(&dst, scalar, point)\n}\n\nfunc x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {\n\tcurve := ecdh.X25519()\n\tpub, err := curve.NewPublicKey(point)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpriv, err := curve.NewPrivateKey(scalar)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tout, err := priv.ECDH(pub)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcopy(dst[:], out)\n\treturn dst[:], nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/hkdf/hkdf.go",
    "content": "// Copyright 2014 The Go 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\n// Package hkdf implements the HMAC-based Extract-and-Expand Key Derivation\n// Function (HKDF) as defined in RFC 5869.\n//\n// HKDF is a cryptographic key derivation function (KDF) with the goal of\n// expanding limited input keying material into one or more cryptographically\n// strong secret keys.\npackage hkdf\n\nimport (\n\t\"crypto/hmac\"\n\t\"errors\"\n\t\"hash\"\n\t\"io\"\n)\n\n// Extract generates a pseudorandom key for use with Expand from an input secret\n// and an optional independent salt.\n//\n// Only use this function if you need to reuse the extracted key with multiple\n// Expand invocations and different context values. Most common scenarios,\n// including the generation of multiple keys, should use New instead.\nfunc Extract(hash func() hash.Hash, secret, salt []byte) []byte {\n\tif salt == nil {\n\t\tsalt = make([]byte, hash().Size())\n\t}\n\textractor := hmac.New(hash, salt)\n\textractor.Write(secret)\n\treturn extractor.Sum(nil)\n}\n\ntype hkdf struct {\n\texpander hash.Hash\n\tsize     int\n\n\tinfo    []byte\n\tcounter byte\n\n\tprev []byte\n\tbuf  []byte\n}\n\nfunc (f *hkdf) Read(p []byte) (int, error) {\n\t// Check whether enough data can be generated\n\tneed := len(p)\n\tremains := len(f.buf) + int(255-f.counter+1)*f.size\n\tif remains < need {\n\t\treturn 0, errors.New(\"hkdf: entropy limit reached\")\n\t}\n\t// Read any leftover from the buffer\n\tn := copy(p, f.buf)\n\tp = p[n:]\n\n\t// Fill the rest of the buffer\n\tfor len(p) > 0 {\n\t\tif f.counter > 1 {\n\t\t\tf.expander.Reset()\n\t\t}\n\t\tf.expander.Write(f.prev)\n\t\tf.expander.Write(f.info)\n\t\tf.expander.Write([]byte{f.counter})\n\t\tf.prev = f.expander.Sum(f.prev[:0])\n\t\tf.counter++\n\n\t\t// Copy the new batch into p\n\t\tf.buf = f.prev\n\t\tn = copy(p, f.buf)\n\t\tp = p[n:]\n\t}\n\t// Save leftovers for next run\n\tf.buf = f.buf[n:]\n\n\treturn need, nil\n}\n\n// Expand returns a Reader, from which keys can be read, using the given\n// pseudorandom key and optional context info, skipping the extraction step.\n//\n// The pseudorandomKey should have been generated by Extract, or be a uniformly\n// random or pseudorandom cryptographically strong key. See RFC 5869, Section\n// 3.3. Most common scenarios will want to use New instead.\nfunc Expand(hash func() hash.Hash, pseudorandomKey, info []byte) io.Reader {\n\texpander := hmac.New(hash, pseudorandomKey)\n\treturn &hkdf{expander, expander.Size(), info, 1, nil, nil}\n}\n\n// New returns a Reader, from which keys can be read, using the given hash,\n// secret, salt and context info. Salt and info can be nil.\nfunc New(hash func() hash.Hash, secret, salt, info []byte) io.Reader {\n\tprk := Extract(hash, secret, salt)\n\treturn Expand(hash, prk, info)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/internal/alias/alias.go",
    "content": "// Copyright 2018 The Go 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\n//go:build !purego\n\n// Package alias implements memory aliasing tests.\npackage alias\n\nimport \"unsafe\"\n\n// AnyOverlap reports whether x and y share memory at any (not necessarily\n// corresponding) index. The memory beyond the slice length is ignored.\nfunc AnyOverlap(x, y []byte) bool {\n\treturn len(x) > 0 && len(y) > 0 &&\n\t\tuintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&\n\t\tuintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))\n}\n\n// InexactOverlap reports whether x and y share memory at any non-corresponding\n// index. The memory beyond the slice length is ignored. Note that x and y can\n// have different lengths and still not have any inexact overlap.\n//\n// InexactOverlap can be used to implement the requirements of the crypto/cipher\n// AEAD, Block, BlockMode and Stream interfaces.\nfunc InexactOverlap(x, y []byte) bool {\n\tif len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {\n\t\treturn false\n\t}\n\treturn AnyOverlap(x, y)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/internal/alias/alias_purego.go",
    "content": "// Copyright 2018 The Go 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\n//go:build purego\n\n// Package alias implements memory aliasing tests.\npackage alias\n\n// This is the Google App Engine standard variant based on reflect\n// because the unsafe package and cgo are disallowed.\n\nimport \"reflect\"\n\n// AnyOverlap reports whether x and y share memory at any (not necessarily\n// corresponding) index. The memory beyond the slice length is ignored.\nfunc AnyOverlap(x, y []byte) bool {\n\treturn len(x) > 0 && len(y) > 0 &&\n\t\treflect.ValueOf(&x[0]).Pointer() <= reflect.ValueOf(&y[len(y)-1]).Pointer() &&\n\t\treflect.ValueOf(&y[0]).Pointer() <= reflect.ValueOf(&x[len(x)-1]).Pointer()\n}\n\n// InexactOverlap reports whether x and y share memory at any non-corresponding\n// index. The memory beyond the slice length is ignored. Note that x and y can\n// have different lengths and still not have any inexact overlap.\n//\n// InexactOverlap can be used to implement the requirements of the crypto/cipher\n// AEAD, Block, BlockMode and Stream interfaces.\nfunc InexactOverlap(x, y []byte) bool {\n\tif len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {\n\t\treturn false\n\t}\n\treturn AnyOverlap(x, y)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go",
    "content": "// Copyright 2018 The Go 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\n//go:build (!amd64 && !loong64 && !ppc64le && !ppc64 && !s390x) || !gc || purego\n\npackage poly1305\n\ntype mac struct{ macGeneric }\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/internal/poly1305/poly1305.go",
    "content": "// Copyright 2012 The Go 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\n// Package poly1305 implements Poly1305 one-time message authentication code as\n// specified in https://cr.yp.to/mac/poly1305-20050329.pdf.\n//\n// Poly1305 is a fast, one-time authentication function. It is infeasible for an\n// attacker to generate an authenticator for a message without the key. However, a\n// key must only be used for a single message. Authenticating two different\n// messages with the same key allows an attacker to forge authenticators for other\n// messages with the same key.\n//\n// Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was\n// used with a fixed key in order to generate one-time keys from an nonce.\n// However, in this package AES isn't used and the one-time key is specified\n// directly.\npackage poly1305\n\nimport \"crypto/subtle\"\n\n// TagSize is the size, in bytes, of a poly1305 authenticator.\nconst TagSize = 16\n\n// Sum generates an authenticator for msg using a one-time key and puts the\n// 16-byte result into out. Authenticating two different messages with the same\n// key allows an attacker to forge messages at will.\nfunc Sum(out *[16]byte, m []byte, key *[32]byte) {\n\th := New(key)\n\th.Write(m)\n\th.Sum(out[:0])\n}\n\n// Verify returns true if mac is a valid authenticator for m with the given key.\nfunc Verify(mac *[16]byte, m []byte, key *[32]byte) bool {\n\tvar tmp [16]byte\n\tSum(&tmp, m, key)\n\treturn subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1\n}\n\n// New returns a new MAC computing an authentication\n// tag of all data written to it with the given key.\n// This allows writing the message progressively instead\n// of passing it as a single slice. Common users should use\n// the Sum function instead.\n//\n// The key must be unique for each message, as authenticating\n// two different messages with the same key allows an attacker\n// to forge messages at will.\nfunc New(key *[32]byte) *MAC {\n\tm := &MAC{}\n\tinitialize(key, &m.macState)\n\treturn m\n}\n\n// MAC is an io.Writer computing an authentication tag\n// of the data written to it.\n//\n// MAC cannot be used like common hash.Hash implementations,\n// because using a poly1305 key twice breaks its security.\n// Therefore writing data to a running MAC after calling\n// Sum or Verify causes it to panic.\ntype MAC struct {\n\tmac // platform-dependent implementation\n\n\tfinalized bool\n}\n\n// Size returns the number of bytes Sum will return.\nfunc (h *MAC) Size() int { return TagSize }\n\n// Write adds more data to the running message authentication code.\n// It never returns an error.\n//\n// It must not be called after the first call of Sum or Verify.\nfunc (h *MAC) Write(p []byte) (n int, err error) {\n\tif h.finalized {\n\t\tpanic(\"poly1305: write to MAC after Sum or Verify\")\n\t}\n\treturn h.mac.Write(p)\n}\n\n// Sum computes the authenticator of all data written to the\n// message authentication code.\nfunc (h *MAC) Sum(b []byte) []byte {\n\tvar mac [TagSize]byte\n\th.mac.Sum(&mac)\n\th.finalized = true\n\treturn append(b, mac[:]...)\n}\n\n// Verify returns whether the authenticator of all data written to\n// the message authentication code matches the expected value.\nfunc (h *MAC) Verify(expected []byte) bool {\n\tvar mac [TagSize]byte\n\th.mac.Sum(&mac)\n\th.finalized = true\n\treturn subtle.ConstantTimeCompare(expected, mac[:]) == 1\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s",
    "content": "// Code generated by command: go run sum_amd64_asm.go -out ../sum_amd64.s -pkg poly1305. DO NOT EDIT.\n\n//go:build gc && !purego\n\n// func update(state *macState, msg []byte)\nTEXT ·update(SB), $0-32\n\tMOVQ state+0(FP), DI\n\tMOVQ msg_base+8(FP), SI\n\tMOVQ msg_len+16(FP), R15\n\tMOVQ (DI), R8\n\tMOVQ 8(DI), R9\n\tMOVQ 16(DI), R10\n\tMOVQ 24(DI), R11\n\tMOVQ 32(DI), R12\n\tCMPQ R15, $0x10\n\tJB   bytes_between_0_and_15\n\nloop:\n\tADDQ (SI), R8\n\tADCQ 8(SI), R9\n\tADCQ $0x01, R10\n\tLEAQ 16(SI), SI\n\nmultiply:\n\tMOVQ  R11, AX\n\tMULQ  R8\n\tMOVQ  AX, BX\n\tMOVQ  DX, CX\n\tMOVQ  R11, AX\n\tMULQ  R9\n\tADDQ  AX, CX\n\tADCQ  $0x00, DX\n\tMOVQ  R11, R13\n\tIMULQ R10, R13\n\tADDQ  DX, R13\n\tMOVQ  R12, AX\n\tMULQ  R8\n\tADDQ  AX, CX\n\tADCQ  $0x00, DX\n\tMOVQ  DX, R8\n\tMOVQ  R12, R14\n\tIMULQ R10, R14\n\tMOVQ  R12, AX\n\tMULQ  R9\n\tADDQ  AX, R13\n\tADCQ  DX, R14\n\tADDQ  R8, R13\n\tADCQ  $0x00, R14\n\tMOVQ  BX, R8\n\tMOVQ  CX, R9\n\tMOVQ  R13, R10\n\tANDQ  $0x03, R10\n\tMOVQ  R13, BX\n\tANDQ  $-4, BX\n\tADDQ  BX, R8\n\tADCQ  R14, R9\n\tADCQ  $0x00, R10\n\tSHRQ  $0x02, R14, R13\n\tSHRQ  $0x02, R14\n\tADDQ  R13, R8\n\tADCQ  R14, R9\n\tADCQ  $0x00, R10\n\tSUBQ  $0x10, R15\n\tCMPQ  R15, $0x10\n\tJAE   loop\n\nbytes_between_0_and_15:\n\tTESTQ R15, R15\n\tJZ    done\n\tMOVQ  $0x00000001, BX\n\tXORQ  CX, CX\n\tXORQ  R13, R13\n\tADDQ  R15, SI\n\nflush_buffer:\n\tSHLQ $0x08, BX, CX\n\tSHLQ $0x08, BX\n\tMOVB -1(SI), R13\n\tXORQ R13, BX\n\tDECQ SI\n\tDECQ R15\n\tJNZ  flush_buffer\n\tADDQ BX, R8\n\tADCQ CX, R9\n\tADCQ $0x00, R10\n\tMOVQ $0x00000010, R15\n\tJMP  multiply\n\ndone:\n\tMOVQ R8, (DI)\n\tMOVQ R9, 8(DI)\n\tMOVQ R10, 16(DI)\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/internal/poly1305/sum_asm.go",
    "content": "// Copyright 2012 The Go 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\n//go:build gc && !purego && (amd64 || loong64 || ppc64 || ppc64le)\n\npackage poly1305\n\n//go:noescape\nfunc update(state *macState, msg []byte)\n\n// mac is a wrapper for macGeneric that redirects calls that would have gone to\n// updateGeneric to update.\n//\n// Its Write and Sum methods are otherwise identical to the macGeneric ones, but\n// using function pointers would carry a major performance cost.\ntype mac struct{ macGeneric }\n\nfunc (h *mac) Write(p []byte) (int, error) {\n\tnn := len(p)\n\tif h.offset > 0 {\n\t\tn := copy(h.buffer[h.offset:], p)\n\t\tif h.offset+n < TagSize {\n\t\t\th.offset += n\n\t\t\treturn nn, nil\n\t\t}\n\t\tp = p[n:]\n\t\th.offset = 0\n\t\tupdate(&h.macState, h.buffer[:])\n\t}\n\tif n := len(p) - (len(p) % TagSize); n > 0 {\n\t\tupdate(&h.macState, p[:n])\n\t\tp = p[n:]\n\t}\n\tif len(p) > 0 {\n\t\th.offset += copy(h.buffer[h.offset:], p)\n\t}\n\treturn nn, nil\n}\n\nfunc (h *mac) Sum(out *[16]byte) {\n\tstate := h.macState\n\tif h.offset > 0 {\n\t\tupdate(&state, h.buffer[:h.offset])\n\t}\n\tfinalize(out, &state.h, &state.s)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go",
    "content": "// Copyright 2018 The Go 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\n// This file provides the generic implementation of Sum and MAC. Other files\n// might provide optimized assembly implementations of some of this code.\n\npackage poly1305\n\nimport (\n\t\"encoding/binary\"\n\t\"math/bits\"\n)\n\n// Poly1305 [RFC 7539] is a relatively simple algorithm: the authentication tag\n// for a 64 bytes message is approximately\n//\n//     s + m[0:16] * r⁴ + m[16:32] * r³ + m[32:48] * r² + m[48:64] * r  mod  2¹³⁰ - 5\n//\n// for some secret r and s. It can be computed sequentially like\n//\n//     for len(msg) > 0:\n//         h += read(msg, 16)\n//         h *= r\n//         h %= 2¹³⁰ - 5\n//     return h + s\n//\n// All the complexity is about doing performant constant-time math on numbers\n// larger than any available numeric type.\n\nfunc sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) {\n\th := newMACGeneric(key)\n\th.Write(msg)\n\th.Sum(out)\n}\n\nfunc newMACGeneric(key *[32]byte) macGeneric {\n\tm := macGeneric{}\n\tinitialize(key, &m.macState)\n\treturn m\n}\n\n// macState holds numbers in saturated 64-bit little-endian limbs. That is,\n// the value of [x0, x1, x2] is x[0] + x[1] * 2⁶⁴ + x[2] * 2¹²⁸.\ntype macState struct {\n\t// h is the main accumulator. It is to be interpreted modulo 2¹³⁰ - 5, but\n\t// can grow larger during and after rounds. It must, however, remain below\n\t// 2 * (2¹³⁰ - 5).\n\th [3]uint64\n\t// r and s are the private key components.\n\tr [2]uint64\n\ts [2]uint64\n}\n\ntype macGeneric struct {\n\tmacState\n\n\tbuffer [TagSize]byte\n\toffset int\n}\n\n// Write splits the incoming message into TagSize chunks, and passes them to\n// update. It buffers incomplete chunks.\nfunc (h *macGeneric) Write(p []byte) (int, error) {\n\tnn := len(p)\n\tif h.offset > 0 {\n\t\tn := copy(h.buffer[h.offset:], p)\n\t\tif h.offset+n < TagSize {\n\t\t\th.offset += n\n\t\t\treturn nn, nil\n\t\t}\n\t\tp = p[n:]\n\t\th.offset = 0\n\t\tupdateGeneric(&h.macState, h.buffer[:])\n\t}\n\tif n := len(p) - (len(p) % TagSize); n > 0 {\n\t\tupdateGeneric(&h.macState, p[:n])\n\t\tp = p[n:]\n\t}\n\tif len(p) > 0 {\n\t\th.offset += copy(h.buffer[h.offset:], p)\n\t}\n\treturn nn, nil\n}\n\n// Sum flushes the last incomplete chunk from the buffer, if any, and generates\n// the MAC output. It does not modify its state, in order to allow for multiple\n// calls to Sum, even if no Write is allowed after Sum.\nfunc (h *macGeneric) Sum(out *[TagSize]byte) {\n\tstate := h.macState\n\tif h.offset > 0 {\n\t\tupdateGeneric(&state, h.buffer[:h.offset])\n\t}\n\tfinalize(out, &state.h, &state.s)\n}\n\n// [rMask0, rMask1] is the specified Poly1305 clamping mask in little-endian. It\n// clears some bits of the secret coefficient to make it possible to implement\n// multiplication more efficiently.\nconst (\n\trMask0 = 0x0FFFFFFC0FFFFFFF\n\trMask1 = 0x0FFFFFFC0FFFFFFC\n)\n\n// initialize loads the 256-bit key into the two 128-bit secret values r and s.\nfunc initialize(key *[32]byte, m *macState) {\n\tm.r[0] = binary.LittleEndian.Uint64(key[0:8]) & rMask0\n\tm.r[1] = binary.LittleEndian.Uint64(key[8:16]) & rMask1\n\tm.s[0] = binary.LittleEndian.Uint64(key[16:24])\n\tm.s[1] = binary.LittleEndian.Uint64(key[24:32])\n}\n\n// uint128 holds a 128-bit number as two 64-bit limbs, for use with the\n// bits.Mul64 and bits.Add64 intrinsics.\ntype uint128 struct {\n\tlo, hi uint64\n}\n\nfunc mul64(a, b uint64) uint128 {\n\thi, lo := bits.Mul64(a, b)\n\treturn uint128{lo, hi}\n}\n\nfunc add128(a, b uint128) uint128 {\n\tlo, c := bits.Add64(a.lo, b.lo, 0)\n\thi, c := bits.Add64(a.hi, b.hi, c)\n\tif c != 0 {\n\t\tpanic(\"poly1305: unexpected overflow\")\n\t}\n\treturn uint128{lo, hi}\n}\n\nfunc shiftRightBy2(a uint128) uint128 {\n\ta.lo = a.lo>>2 | (a.hi&3)<<62\n\ta.hi = a.hi >> 2\n\treturn a\n}\n\n// updateGeneric absorbs msg into the state.h accumulator. For each chunk m of\n// 128 bits of message, it computes\n//\n//\th₊ = (h + m) * r  mod  2¹³⁰ - 5\n//\n// If the msg length is not a multiple of TagSize, it assumes the last\n// incomplete chunk is the final one.\nfunc updateGeneric(state *macState, msg []byte) {\n\th0, h1, h2 := state.h[0], state.h[1], state.h[2]\n\tr0, r1 := state.r[0], state.r[1]\n\n\tfor len(msg) > 0 {\n\t\tvar c uint64\n\n\t\t// For the first step, h + m, we use a chain of bits.Add64 intrinsics.\n\t\t// The resulting value of h might exceed 2¹³⁰ - 5, but will be partially\n\t\t// reduced at the end of the multiplication below.\n\t\t//\n\t\t// The spec requires us to set a bit just above the message size, not to\n\t\t// hide leading zeroes. For full chunks, that's 1 << 128, so we can just\n\t\t// add 1 to the most significant (2¹²⁸) limb, h2.\n\t\tif len(msg) >= TagSize {\n\t\t\th0, c = bits.Add64(h0, binary.LittleEndian.Uint64(msg[0:8]), 0)\n\t\t\th1, c = bits.Add64(h1, binary.LittleEndian.Uint64(msg[8:16]), c)\n\t\t\th2 += c + 1\n\n\t\t\tmsg = msg[TagSize:]\n\t\t} else {\n\t\t\tvar buf [TagSize]byte\n\t\t\tcopy(buf[:], msg)\n\t\t\tbuf[len(msg)] = 1\n\n\t\t\th0, c = bits.Add64(h0, binary.LittleEndian.Uint64(buf[0:8]), 0)\n\t\t\th1, c = bits.Add64(h1, binary.LittleEndian.Uint64(buf[8:16]), c)\n\t\t\th2 += c\n\n\t\t\tmsg = nil\n\t\t}\n\n\t\t// Multiplication of big number limbs is similar to elementary school\n\t\t// columnar multiplication. Instead of digits, there are 64-bit limbs.\n\t\t//\n\t\t// We are multiplying a 3 limbs number, h, by a 2 limbs number, r.\n\t\t//\n\t\t//                        h2    h1    h0  x\n\t\t//                              r1    r0  =\n\t\t//                       ----------------\n\t\t//                      h2r0  h1r0  h0r0     <-- individual 128-bit products\n\t\t//            +   h2r1  h1r1  h0r1\n\t\t//               ------------------------\n\t\t//                 m3    m2    m1    m0      <-- result in 128-bit overlapping limbs\n\t\t//               ------------------------\n\t\t//         m3.hi m2.hi m1.hi m0.hi           <-- carry propagation\n\t\t//     +         m3.lo m2.lo m1.lo m0.lo\n\t\t//        -------------------------------\n\t\t//           t4    t3    t2    t1    t0      <-- final result in 64-bit limbs\n\t\t//\n\t\t// The main difference from pen-and-paper multiplication is that we do\n\t\t// carry propagation in a separate step, as if we wrote two digit sums\n\t\t// at first (the 128-bit limbs), and then carried the tens all at once.\n\n\t\th0r0 := mul64(h0, r0)\n\t\th1r0 := mul64(h1, r0)\n\t\th2r0 := mul64(h2, r0)\n\t\th0r1 := mul64(h0, r1)\n\t\th1r1 := mul64(h1, r1)\n\t\th2r1 := mul64(h2, r1)\n\n\t\t// Since h2 is known to be at most 7 (5 + 1 + 1), and r0 and r1 have their\n\t\t// top 4 bits cleared by rMask{0,1}, we know that their product is not going\n\t\t// to overflow 64 bits, so we can ignore the high part of the products.\n\t\t//\n\t\t// This also means that the product doesn't have a fifth limb (t4).\n\t\tif h2r0.hi != 0 {\n\t\t\tpanic(\"poly1305: unexpected overflow\")\n\t\t}\n\t\tif h2r1.hi != 0 {\n\t\t\tpanic(\"poly1305: unexpected overflow\")\n\t\t}\n\n\t\tm0 := h0r0\n\t\tm1 := add128(h1r0, h0r1) // These two additions don't overflow thanks again\n\t\tm2 := add128(h2r0, h1r1) // to the 4 masked bits at the top of r0 and r1.\n\t\tm3 := h2r1\n\n\t\tt0 := m0.lo\n\t\tt1, c := bits.Add64(m1.lo, m0.hi, 0)\n\t\tt2, c := bits.Add64(m2.lo, m1.hi, c)\n\t\tt3, _ := bits.Add64(m3.lo, m2.hi, c)\n\n\t\t// Now we have the result as 4 64-bit limbs, and we need to reduce it\n\t\t// modulo 2¹³⁰ - 5. The special shape of this Crandall prime lets us do\n\t\t// a cheap partial reduction according to the reduction identity\n\t\t//\n\t\t//     c * 2¹³⁰ + n  =  c * 5 + n  mod  2¹³⁰ - 5\n\t\t//\n\t\t// because 2¹³⁰ = 5 mod 2¹³⁰ - 5. Partial reduction since the result is\n\t\t// likely to be larger than 2¹³⁰ - 5, but still small enough to fit the\n\t\t// assumptions we make about h in the rest of the code.\n\t\t//\n\t\t// See also https://speakerdeck.com/gtank/engineering-prime-numbers?slide=23\n\n\t\t// We split the final result at the 2¹³⁰ mark into h and cc, the carry.\n\t\t// Note that the carry bits are effectively shifted left by 2, in other\n\t\t// words, cc = c * 4 for the c in the reduction identity.\n\t\th0, h1, h2 = t0, t1, t2&maskLow2Bits\n\t\tcc := uint128{t2 & maskNotLow2Bits, t3}\n\n\t\t// To add c * 5 to h, we first add cc = c * 4, and then add (cc >> 2) = c.\n\n\t\th0, c = bits.Add64(h0, cc.lo, 0)\n\t\th1, c = bits.Add64(h1, cc.hi, c)\n\t\th2 += c\n\n\t\tcc = shiftRightBy2(cc)\n\n\t\th0, c = bits.Add64(h0, cc.lo, 0)\n\t\th1, c = bits.Add64(h1, cc.hi, c)\n\t\th2 += c\n\n\t\t// h2 is at most 3 + 1 + 1 = 5, making the whole of h at most\n\t\t//\n\t\t//     5 * 2¹²⁸ + (2¹²⁸ - 1) = 6 * 2¹²⁸ - 1\n\t}\n\n\tstate.h[0], state.h[1], state.h[2] = h0, h1, h2\n}\n\nconst (\n\tmaskLow2Bits    uint64 = 0x0000000000000003\n\tmaskNotLow2Bits uint64 = ^maskLow2Bits\n)\n\n// select64 returns x if v == 1 and y if v == 0, in constant time.\nfunc select64(v, x, y uint64) uint64 { return ^(v-1)&x | (v-1)&y }\n\n// [p0, p1, p2] is 2¹³⁰ - 5 in little endian order.\nconst (\n\tp0 = 0xFFFFFFFFFFFFFFFB\n\tp1 = 0xFFFFFFFFFFFFFFFF\n\tp2 = 0x0000000000000003\n)\n\n// finalize completes the modular reduction of h and computes\n//\n//\tout = h + s  mod  2¹²⁸\nfunc finalize(out *[TagSize]byte, h *[3]uint64, s *[2]uint64) {\n\th0, h1, h2 := h[0], h[1], h[2]\n\n\t// After the partial reduction in updateGeneric, h might be more than\n\t// 2¹³⁰ - 5, but will be less than 2 * (2¹³⁰ - 5). To complete the reduction\n\t// in constant time, we compute t = h - (2¹³⁰ - 5), and select h as the\n\t// result if the subtraction underflows, and t otherwise.\n\n\thMinusP0, b := bits.Sub64(h0, p0, 0)\n\thMinusP1, b := bits.Sub64(h1, p1, b)\n\t_, b = bits.Sub64(h2, p2, b)\n\n\t// h = h if h < p else h - p\n\th0 = select64(b, h0, hMinusP0)\n\th1 = select64(b, h1, hMinusP1)\n\n\t// Finally, we compute the last Poly1305 step\n\t//\n\t//     tag = h + s  mod  2¹²⁸\n\t//\n\t// by just doing a wide addition with the 128 low bits of h and discarding\n\t// the overflow.\n\th0, c := bits.Add64(h0, s[0], 0)\n\th1, _ = bits.Add64(h1, s[1], c)\n\n\tbinary.LittleEndian.PutUint64(out[0:8], h0)\n\tbinary.LittleEndian.PutUint64(out[8:16], h1)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/internal/poly1305/sum_loong64.s",
    "content": "// Copyright 2025 The Go 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\n//go:build gc && !purego\n\n// func update(state *macState, msg []byte)\nTEXT ·update(SB), $0-32\n\tMOVV\tstate+0(FP), R4\n\tMOVV\tmsg_base+8(FP), R5\n\tMOVV\tmsg_len+16(FP), R6\n\n\tMOVV\t$0x10, R7\n\n\tMOVV\t(R4), R8\t// h0\n\tMOVV\t8(R4), R9\t// h1\n\tMOVV\t16(R4), R10\t// h2\n\tMOVV\t24(R4), R11\t// r0\n\tMOVV\t32(R4), R12\t// r1\n\n\tBLT\tR6, R7, bytes_between_0_and_15\n\nloop:\n\tMOVV\t(R5), R14\t// msg[0:8]\n\tMOVV\t8(R5), R16\t// msg[8:16]\n\tADDV\tR14, R8, R8\t// h0 (x1 + y1 = z1', if z1' < x1 then z1' overflow)\n\tADDV\tR16, R9, R27\n\tSGTU\tR14, R8, R24\t// h0.carry\n\tSGTU\tR9, R27, R28\n\tADDV\tR27, R24, R9\t// h1\n\tSGTU\tR27, R9, R24\n\tOR\tR24, R28, R24\t// h1.carry\n\tADDV\t$0x01, R24, R24\n\tADDV\tR10, R24, R10\t// h2\n\n\tADDV\t$16, R5, R5\t// msg = msg[16:]\n\nmultiply:\n\tMULV\tR8, R11, R14\t// h0r0.lo\n\tMULHVU\tR8, R11, R15\t// h0r0.hi\n\tMULV\tR9, R11, R13\t// h1r0.lo\n\tMULHVU\tR9, R11, R16\t// h1r0.hi\n\tADDV\tR13, R15, R15\n\tSGTU\tR13, R15, R24\n\tADDV\tR24, R16, R16\n\tMULV\tR10, R11, R25\n\tADDV\tR16, R25, R25\n\tMULV\tR8, R12, R13\t// h0r1.lo\n\tMULHVU\tR8, R12, R16\t// h0r1.hi\n\tADDV\tR13, R15, R15\n\tSGTU\tR13, R15, R24\n\tADDV\tR24, R16, R16\n\tMOVV\tR16, R8\n\tMULV\tR10, R12, R26\t// h2r1\n\tMULV\tR9, R12, R13\t// h1r1.lo\n\tMULHVU\tR9, R12, R16\t// h1r1.hi\n\tADDV\tR13, R25, R25\n\tADDV\tR16, R26, R27\n\tSGTU\tR13, R25, R24\n\tADDV\tR27, R24, R26\n\tADDV\tR8, R25, R25\n\tSGTU\tR8, R25, R24\n\tADDV\tR24, R26, R26\n\tAND\t$3, R25, R10\n\tAND\t$-4, R25, R17\n\tADDV\tR17, R14, R8\n\tADDV\tR26, R15, R27\n\tSGTU\tR17, R8, R24\n\tSGTU\tR26, R27, R28\n\tADDV\tR27, R24, R9\n\tSGTU\tR27, R9, R24\n\tOR\tR24, R28, R24\n\tADDV\tR24, R10, R10\n\tSLLV\t$62, R26, R27\n\tSRLV\t$2, R25, R28\n\tSRLV\t$2, R26, R26\n\tOR\tR27, R28, R25\n\tADDV\tR25, R8, R8\n\tADDV\tR26, R9, R27\n\tSGTU\tR25, R8, R24\n\tSGTU\tR26, R27, R28\n\tADDV\tR27, R24, R9\n\tSGTU\tR27, R9, R24\n\tOR\tR24, R28, R24\n\tADDV\tR24, R10, R10\n\n\tSUBV\t$16, R6, R6\n\tBGE\tR6, R7, loop\n\nbytes_between_0_and_15:\n\tBEQ\tR6, R0, done\n\tMOVV\t$1, R14\n\tXOR\tR15, R15\n\tADDV\tR6, R5, R5\n\nflush_buffer:\n\tMOVBU\t-1(R5), R25\n\tSRLV\t$56, R14, R24\n\tSLLV\t$8, R15, R28\n\tSLLV\t$8, R14, R14\n\tOR\tR24, R28, R15\n\tXOR\tR25, R14, R14\n\tSUBV\t$1, R6, R6\n\tSUBV\t$1, R5, R5\n\tBNE\tR6, R0, flush_buffer\n\n\tADDV\tR14, R8, R8\n\tSGTU\tR14, R8, R24\n\tADDV\tR15, R9, R27\n\tSGTU\tR15, R27, R28\n\tADDV\tR27, R24, R9\n\tSGTU\tR27, R9, R24\n\tOR\tR24, R28, R24\n\tADDV\tR10, R24, R10\n\n\tMOVV\t$16, R6\n\tJMP\tmultiply\n\ndone:\n\tMOVV\tR8, (R4)\n\tMOVV\tR9, 8(R4)\n\tMOVV\tR10, 16(R4)\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64x.s",
    "content": "// Copyright 2019 The Go 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\n//go:build gc && !purego && (ppc64 || ppc64le)\n\n#include \"textflag.h\"\n\n// This was ported from the amd64 implementation.\n\n#ifdef GOARCH_ppc64le\n#define LE_MOVD MOVD\n#define LE_MOVWZ MOVWZ\n#define LE_MOVHZ MOVHZ\n#else\n#define LE_MOVD MOVDBR\n#define LE_MOVWZ MOVWBR\n#define LE_MOVHZ MOVHBR\n#endif\n\n#define POLY1305_ADD(msg, h0, h1, h2, t0, t1, t2) \\\n\tLE_MOVD (msg)( R0), t0; \\\n\tLE_MOVD (msg)(R24), t1; \\\n\tMOVD $1, t2;     \\\n\tADDC t0, h0, h0; \\\n\tADDE t1, h1, h1; \\\n\tADDE t2, h2;     \\\n\tADD  $16, msg\n\n#define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3, t4, t5) \\\n\tMULLD  r0, h0, t0;  \\\n\tMULHDU r0, h0, t1;  \\\n\tMULLD  r0, h1, t4;  \\\n\tMULHDU r0, h1, t5;  \\\n\tADDC   t4, t1, t1;  \\\n\tMULLD  r0, h2, t2;  \\\n\tMULHDU r1, h0, t4;  \\\n\tMULLD  r1, h0, h0;  \\\n\tADDE   t5, t2, t2;  \\\n\tADDC   h0, t1, t1;  \\\n\tMULLD  h2, r1, t3;  \\\n\tADDZE  t4, h0;      \\\n\tMULHDU r1, h1, t5;  \\\n\tMULLD  r1, h1, t4;  \\\n\tADDC   t4, t2, t2;  \\\n\tADDE   t5, t3, t3;  \\\n\tADDC   h0, t2, t2;  \\\n\tMOVD   $-4, t4;     \\\n\tADDZE  t3;          \\\n\tRLDICL $0, t2, $62, h2; \\\n\tAND    t2, t4, h0;  \\\n\tADDC   t0, h0, h0;  \\\n\tADDE   t3, t1, h1;  \\\n\tSLD    $62, t3, t4; \\\n\tSRD    $2, t2;      \\\n\tADDZE  h2;          \\\n\tOR     t4, t2, t2;  \\\n\tSRD    $2, t3;      \\\n\tADDC   t2, h0, h0;  \\\n\tADDE   t3, h1, h1;  \\\n\tADDZE  h2\n\n// func update(state *[7]uint64, msg []byte)\nTEXT ·update(SB), $0-32\n\tMOVD state+0(FP), R3\n\tMOVD msg_base+8(FP), R4\n\tMOVD msg_len+16(FP), R5\n\n\tMOVD 0(R3), R8   // h0\n\tMOVD 8(R3), R9   // h1\n\tMOVD 16(R3), R10 // h2\n\tMOVD 24(R3), R11 // r0\n\tMOVD 32(R3), R12 // r1\n\n\tMOVD $8, R24\n\n\tCMP R5, $16\n\tBLT bytes_between_0_and_15\n\nloop:\n\tPOLY1305_ADD(R4, R8, R9, R10, R20, R21, R22)\n\n\tPCALIGN $16\nmultiply:\n\tPOLY1305_MUL(R8, R9, R10, R11, R12, R16, R17, R18, R14, R20, R21)\n\tADD $-16, R5\n\tCMP R5, $16\n\tBGE loop\n\nbytes_between_0_and_15:\n\tCMP  R5, $0\n\tBEQ  done\n\tMOVD $0, R16 // h0\n\tMOVD $0, R17 // h1\n\nflush_buffer:\n\tCMP R5, $8\n\tBLE just1\n\n\tMOVD $8, R21\n\tSUB  R21, R5, R21\n\n\t// Greater than 8 -- load the rightmost remaining bytes in msg\n\t// and put into R17 (h1)\n\tLE_MOVD (R4)(R21), R17\n\tMOVD $16, R22\n\n\t// Find the offset to those bytes\n\tSUB R5, R22, R22\n\tSLD $3, R22\n\n\t// Shift to get only the bytes in msg\n\tSRD R22, R17, R17\n\n\t// Put 1 at high end\n\tMOVD $1, R23\n\tSLD  $3, R21\n\tSLD  R21, R23, R23\n\tOR   R23, R17, R17\n\n\t// Remainder is 8\n\tMOVD $8, R5\n\njust1:\n\tCMP R5, $8\n\tBLT less8\n\n\t// Exactly 8\n\tLE_MOVD (R4), R16\n\n\tCMP R17, $0\n\n\t// Check if we've already set R17; if not\n\t// set 1 to indicate end of msg.\n\tBNE  carry\n\tMOVD $1, R17\n\tBR   carry\n\nless8:\n\tMOVD  $0, R16   // h0\n\tMOVD  $0, R22   // shift count\n\tCMP   R5, $4\n\tBLT   less4\n\tLE_MOVWZ (R4), R16\n\tADD   $4, R4\n\tADD   $-4, R5\n\tMOVD  $32, R22\n\nless4:\n\tCMP   R5, $2\n\tBLT   less2\n\tLE_MOVHZ (R4), R21\n\tSLD   R22, R21, R21\n\tOR    R16, R21, R16\n\tADD   $16, R22\n\tADD   $-2, R5\n\tADD   $2, R4\n\nless2:\n\tCMP   R5, $0\n\tBEQ   insert1\n\tMOVBZ (R4), R21\n\tSLD   R22, R21, R21\n\tOR    R16, R21, R16\n\tADD   $8, R22\n\ninsert1:\n\t// Insert 1 at end of msg\n\tMOVD $1, R21\n\tSLD  R22, R21, R21\n\tOR   R16, R21, R16\n\ncarry:\n\t// Add new values to h0, h1, h2\n\tADDC  R16, R8\n\tADDE  R17, R9\n\tADDZE R10, R10\n\tMOVD  $16, R5\n\tADD   R5, R4\n\tBR    multiply\n\ndone:\n\t// Save h0, h1, h2 in state\n\tMOVD R8, 0(R3)\n\tMOVD R9, 8(R3)\n\tMOVD R10, 16(R3)\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.go",
    "content": "// Copyright 2018 The Go 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\n//go:build gc && !purego\n\npackage poly1305\n\nimport (\n\t\"golang.org/x/sys/cpu\"\n)\n\n// updateVX is an assembly implementation of Poly1305 that uses vector\n// instructions. It must only be called if the vector facility (vx) is\n// available.\n//\n//go:noescape\nfunc updateVX(state *macState, msg []byte)\n\n// mac is a replacement for macGeneric that uses a larger buffer and redirects\n// calls that would have gone to updateGeneric to updateVX if the vector\n// facility is installed.\n//\n// A larger buffer is required for good performance because the vector\n// implementation has a higher fixed cost per call than the generic\n// implementation.\ntype mac struct {\n\tmacState\n\n\tbuffer [16 * TagSize]byte // size must be a multiple of block size (16)\n\toffset int\n}\n\nfunc (h *mac) Write(p []byte) (int, error) {\n\tnn := len(p)\n\tif h.offset > 0 {\n\t\tn := copy(h.buffer[h.offset:], p)\n\t\tif h.offset+n < len(h.buffer) {\n\t\t\th.offset += n\n\t\t\treturn nn, nil\n\t\t}\n\t\tp = p[n:]\n\t\th.offset = 0\n\t\tif cpu.S390X.HasVX {\n\t\t\tupdateVX(&h.macState, h.buffer[:])\n\t\t} else {\n\t\t\tupdateGeneric(&h.macState, h.buffer[:])\n\t\t}\n\t}\n\n\ttail := len(p) % len(h.buffer) // number of bytes to copy into buffer\n\tbody := len(p) - tail          // number of bytes to process now\n\tif body > 0 {\n\t\tif cpu.S390X.HasVX {\n\t\t\tupdateVX(&h.macState, p[:body])\n\t\t} else {\n\t\t\tupdateGeneric(&h.macState, p[:body])\n\t\t}\n\t}\n\th.offset = copy(h.buffer[:], p[body:]) // copy tail bytes - can be 0\n\treturn nn, nil\n}\n\nfunc (h *mac) Sum(out *[TagSize]byte) {\n\tstate := h.macState\n\tremainder := h.buffer[:h.offset]\n\n\t// Use the generic implementation if we have 2 or fewer blocks left\n\t// to sum. The vector implementation has a higher startup time.\n\tif cpu.S390X.HasVX && len(remainder) > 2*TagSize {\n\t\tupdateVX(&state, remainder)\n\t} else if len(remainder) > 0 {\n\t\tupdateGeneric(&state, remainder)\n\t}\n\tfinalize(out, &state.h, &state.s)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/internal/poly1305/sum_s390x.s",
    "content": "// Copyright 2018 The Go 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\n//go:build gc && !purego\n\n#include \"textflag.h\"\n\n// This implementation of Poly1305 uses the vector facility (vx)\n// to process up to 2 blocks (32 bytes) per iteration using an\n// algorithm based on the one described in:\n//\n// NEON crypto, Daniel J. Bernstein & Peter Schwabe\n// https://cryptojedi.org/papers/neoncrypto-20120320.pdf\n//\n// This algorithm uses 5 26-bit limbs to represent a 130-bit\n// value. These limbs are, for the most part, zero extended and\n// placed into 64-bit vector register elements. Each vector\n// register is 128-bits wide and so holds 2 of these elements.\n// Using 26-bit limbs allows us plenty of headroom to accommodate\n// accumulations before and after multiplication without\n// overflowing either 32-bits (before multiplication) or 64-bits\n// (after multiplication).\n//\n// In order to parallelise the operations required to calculate\n// the sum we use two separate accumulators and then sum those\n// in an extra final step. For compatibility with the generic\n// implementation we perform this summation at the end of every\n// updateVX call.\n//\n// To use two accumulators we must multiply the message blocks\n// by r² rather than r. Only the final message block should be\n// multiplied by r.\n//\n// Example:\n//\n// We want to calculate the sum (h) for a 64 byte message (m):\n//\n//   h = m[0:16]r⁴ + m[16:32]r³ + m[32:48]r² + m[48:64]r\n//\n// To do this we split the calculation into the even indices\n// and odd indices of the message. These form our SIMD 'lanes':\n//\n//   h = m[ 0:16]r⁴ + m[32:48]r² +   <- lane 0\n//       m[16:32]r³ + m[48:64]r      <- lane 1\n//\n// To calculate this iteratively we refactor so that both lanes\n// are written in terms of r² and r:\n//\n//   h = (m[ 0:16]r² + m[32:48])r² + <- lane 0\n//       (m[16:32]r² + m[48:64])r    <- lane 1\n//                ^             ^\n//                |             coefficients for second iteration\n//                coefficients for first iteration\n//\n// So in this case we would have two iterations. In the first\n// both lanes are multiplied by r². In the second only the\n// first lane is multiplied by r² and the second lane is\n// instead multiplied by r. This gives use the odd and even\n// powers of r that we need from the original equation.\n//\n// Notation:\n//\n//   h - accumulator\n//   r - key\n//   m - message\n//\n//   [a, b]       - SIMD register holding two 64-bit values\n//   [a, b, c, d] - SIMD register holding four 32-bit values\n//   xᵢ[n]        - limb n of variable x with bit width i\n//\n// Limbs are expressed in little endian order, so for 26-bit\n// limbs x₂₆[4] will be the most significant limb and x₂₆[0]\n// will be the least significant limb.\n\n// masking constants\n#define MOD24 V0 // [0x0000000000ffffff, 0x0000000000ffffff] - mask low 24-bits\n#define MOD26 V1 // [0x0000000003ffffff, 0x0000000003ffffff] - mask low 26-bits\n\n// expansion constants (see EXPAND macro)\n#define EX0 V2\n#define EX1 V3\n#define EX2 V4\n\n// key (r², r or 1 depending on context)\n#define R_0 V5\n#define R_1 V6\n#define R_2 V7\n#define R_3 V8\n#define R_4 V9\n\n// precalculated coefficients (5r², 5r or 0 depending on context)\n#define R5_1 V10\n#define R5_2 V11\n#define R5_3 V12\n#define R5_4 V13\n\n// message block (m)\n#define M_0 V14\n#define M_1 V15\n#define M_2 V16\n#define M_3 V17\n#define M_4 V18\n\n// accumulator (h)\n#define H_0 V19\n#define H_1 V20\n#define H_2 V21\n#define H_3 V22\n#define H_4 V23\n\n// temporary registers (for short-lived values)\n#define T_0 V24\n#define T_1 V25\n#define T_2 V26\n#define T_3 V27\n#define T_4 V28\n\nGLOBL ·constants<>(SB), RODATA, $0x30\n// EX0\nDATA ·constants<>+0x00(SB)/8, $0x0006050403020100\nDATA ·constants<>+0x08(SB)/8, $0x1016151413121110\n// EX1\nDATA ·constants<>+0x10(SB)/8, $0x060c0b0a09080706\nDATA ·constants<>+0x18(SB)/8, $0x161c1b1a19181716\n// EX2\nDATA ·constants<>+0x20(SB)/8, $0x0d0d0d0d0d0f0e0d\nDATA ·constants<>+0x28(SB)/8, $0x1d1d1d1d1d1f1e1d\n\n// MULTIPLY multiplies each lane of f and g, partially reduced\n// modulo 2¹³⁰ - 5. The result, h, consists of partial products\n// in each lane that need to be reduced further to produce the\n// final result.\n//\n//   h₁₃₀ = (f₁₃₀g₁₃₀) % 2¹³⁰ + (5f₁₃₀g₁₃₀) / 2¹³⁰\n//\n// Note that the multiplication by 5 of the high bits is\n// achieved by precalculating the multiplication of four of the\n// g coefficients by 5. These are g51-g54.\n#define MULTIPLY(f0, f1, f2, f3, f4, g0, g1, g2, g3, g4, g51, g52, g53, g54, h0, h1, h2, h3, h4) \\\n\tVMLOF  f0, g0, h0        \\\n\tVMLOF  f0, g3, h3        \\\n\tVMLOF  f0, g1, h1        \\\n\tVMLOF  f0, g4, h4        \\\n\tVMLOF  f0, g2, h2        \\\n\tVMLOF  f1, g54, T_0      \\\n\tVMLOF  f1, g2, T_3       \\\n\tVMLOF  f1, g0, T_1       \\\n\tVMLOF  f1, g3, T_4       \\\n\tVMLOF  f1, g1, T_2       \\\n\tVMALOF f2, g53, h0, h0   \\\n\tVMALOF f2, g1, h3, h3    \\\n\tVMALOF f2, g54, h1, h1   \\\n\tVMALOF f2, g2, h4, h4    \\\n\tVMALOF f2, g0, h2, h2    \\\n\tVMALOF f3, g52, T_0, T_0 \\\n\tVMALOF f3, g0, T_3, T_3  \\\n\tVMALOF f3, g53, T_1, T_1 \\\n\tVMALOF f3, g1, T_4, T_4  \\\n\tVMALOF f3, g54, T_2, T_2 \\\n\tVMALOF f4, g51, h0, h0   \\\n\tVMALOF f4, g54, h3, h3   \\\n\tVMALOF f4, g52, h1, h1   \\\n\tVMALOF f4, g0, h4, h4    \\\n\tVMALOF f4, g53, h2, h2   \\\n\tVAG    T_0, h0, h0       \\\n\tVAG    T_3, h3, h3       \\\n\tVAG    T_1, h1, h1       \\\n\tVAG    T_4, h4, h4       \\\n\tVAG    T_2, h2, h2\n\n// REDUCE performs the following carry operations in four\n// stages, as specified in Bernstein & Schwabe:\n//\n//   1: h₂₆[0]->h₂₆[1] h₂₆[3]->h₂₆[4]\n//   2: h₂₆[1]->h₂₆[2] h₂₆[4]->h₂₆[0]\n//   3: h₂₆[0]->h₂₆[1] h₂₆[2]->h₂₆[3]\n//   4: h₂₆[3]->h₂₆[4]\n//\n// The result is that all of the limbs are limited to 26-bits\n// except for h₂₆[1] and h₂₆[4] which are limited to 27-bits.\n//\n// Note that although each limb is aligned at 26-bit intervals\n// they may contain values that exceed 2²⁶ - 1, hence the need\n// to carry the excess bits in each limb.\n#define REDUCE(h0, h1, h2, h3, h4) \\\n\tVESRLG $26, h0, T_0  \\\n\tVESRLG $26, h3, T_1  \\\n\tVN     MOD26, h0, h0 \\\n\tVN     MOD26, h3, h3 \\\n\tVAG    T_0, h1, h1   \\\n\tVAG    T_1, h4, h4   \\\n\tVESRLG $26, h1, T_2  \\\n\tVESRLG $26, h4, T_3  \\\n\tVN     MOD26, h1, h1 \\\n\tVN     MOD26, h4, h4 \\\n\tVESLG  $2, T_3, T_4  \\\n\tVAG    T_3, T_4, T_4 \\\n\tVAG    T_2, h2, h2   \\\n\tVAG    T_4, h0, h0   \\\n\tVESRLG $26, h2, T_0  \\\n\tVESRLG $26, h0, T_1  \\\n\tVN     MOD26, h2, h2 \\\n\tVN     MOD26, h0, h0 \\\n\tVAG    T_0, h3, h3   \\\n\tVAG    T_1, h1, h1   \\\n\tVESRLG $26, h3, T_2  \\\n\tVN     MOD26, h3, h3 \\\n\tVAG    T_2, h4, h4\n\n// EXPAND splits the 128-bit little-endian values in0 and in1\n// into 26-bit big-endian limbs and places the results into\n// the first and second lane of d₂₆[0:4] respectively.\n//\n// The EX0, EX1 and EX2 constants are arrays of byte indices\n// for permutation. The permutation both reverses the bytes\n// in the input and ensures the bytes are copied into the\n// destination limb ready to be shifted into their final\n// position.\n#define EXPAND(in0, in1, d0, d1, d2, d3, d4) \\\n\tVPERM  in0, in1, EX0, d0 \\\n\tVPERM  in0, in1, EX1, d2 \\\n\tVPERM  in0, in1, EX2, d4 \\\n\tVESRLG $26, d0, d1       \\\n\tVESRLG $30, d2, d3       \\\n\tVESRLG $4, d2, d2        \\\n\tVN     MOD26, d0, d0     \\ // [in0₂₆[0], in1₂₆[0]]\n\tVN     MOD26, d3, d3     \\ // [in0₂₆[3], in1₂₆[3]]\n\tVN     MOD26, d1, d1     \\ // [in0₂₆[1], in1₂₆[1]]\n\tVN     MOD24, d4, d4     \\ // [in0₂₆[4], in1₂₆[4]]\n\tVN     MOD26, d2, d2     // [in0₂₆[2], in1₂₆[2]]\n\n// func updateVX(state *macState, msg []byte)\nTEXT ·updateVX(SB), NOSPLIT, $0\n\tMOVD state+0(FP), R1\n\tLMG  msg+8(FP), R2, R3 // R2=msg_base, R3=msg_len\n\n\t// load EX0, EX1 and EX2\n\tMOVD $·constants<>(SB), R5\n\tVLM  (R5), EX0, EX2\n\n\t// generate masks\n\tVGMG $(64-24), $63, MOD24 // [0x00ffffff, 0x00ffffff]\n\tVGMG $(64-26), $63, MOD26 // [0x03ffffff, 0x03ffffff]\n\n\t// load h (accumulator) and r (key) from state\n\tVZERO T_1               // [0, 0]\n\tVL    0(R1), T_0        // [h₆₄[0], h₆₄[1]]\n\tVLEG  $0, 16(R1), T_1   // [h₆₄[2], 0]\n\tVL    24(R1), T_2       // [r₆₄[0], r₆₄[1]]\n\tVPDI  $0, T_0, T_2, T_3 // [h₆₄[0], r₆₄[0]]\n\tVPDI  $5, T_0, T_2, T_4 // [h₆₄[1], r₆₄[1]]\n\n\t// unpack h and r into 26-bit limbs\n\t// note: h₆₄[2] may have the low 3 bits set, so h₂₆[4] is a 27-bit value\n\tVN     MOD26, T_3, H_0            // [h₂₆[0], r₂₆[0]]\n\tVZERO  H_1                        // [0, 0]\n\tVZERO  H_3                        // [0, 0]\n\tVGMG   $(64-12-14), $(63-12), T_0 // [0x03fff000, 0x03fff000] - 26-bit mask with low 12 bits masked out\n\tVESLG  $24, T_1, T_1              // [h₆₄[2]<<24, 0]\n\tVERIMG $-26&63, T_3, MOD26, H_1   // [h₂₆[1], r₂₆[1]]\n\tVESRLG $+52&63, T_3, H_2          // [h₂₆[2], r₂₆[2]] - low 12 bits only\n\tVERIMG $-14&63, T_4, MOD26, H_3   // [h₂₆[1], r₂₆[1]]\n\tVESRLG $40, T_4, H_4              // [h₂₆[4], r₂₆[4]] - low 24 bits only\n\tVERIMG $+12&63, T_4, T_0, H_2     // [h₂₆[2], r₂₆[2]] - complete\n\tVO     T_1, H_4, H_4              // [h₂₆[4], r₂₆[4]] - complete\n\n\t// replicate r across all 4 vector elements\n\tVREPF $3, H_0, R_0 // [r₂₆[0], r₂₆[0], r₂₆[0], r₂₆[0]]\n\tVREPF $3, H_1, R_1 // [r₂₆[1], r₂₆[1], r₂₆[1], r₂₆[1]]\n\tVREPF $3, H_2, R_2 // [r₂₆[2], r₂₆[2], r₂₆[2], r₂₆[2]]\n\tVREPF $3, H_3, R_3 // [r₂₆[3], r₂₆[3], r₂₆[3], r₂₆[3]]\n\tVREPF $3, H_4, R_4 // [r₂₆[4], r₂₆[4], r₂₆[4], r₂₆[4]]\n\n\t// zero out lane 1 of h\n\tVLEIG $1, $0, H_0 // [h₂₆[0], 0]\n\tVLEIG $1, $0, H_1 // [h₂₆[1], 0]\n\tVLEIG $1, $0, H_2 // [h₂₆[2], 0]\n\tVLEIG $1, $0, H_3 // [h₂₆[3], 0]\n\tVLEIG $1, $0, H_4 // [h₂₆[4], 0]\n\n\t// calculate 5r (ignore least significant limb)\n\tVREPIF $5, T_0\n\tVMLF   T_0, R_1, R5_1 // [5r₂₆[1], 5r₂₆[1], 5r₂₆[1], 5r₂₆[1]]\n\tVMLF   T_0, R_2, R5_2 // [5r₂₆[2], 5r₂₆[2], 5r₂₆[2], 5r₂₆[2]]\n\tVMLF   T_0, R_3, R5_3 // [5r₂₆[3], 5r₂₆[3], 5r₂₆[3], 5r₂₆[3]]\n\tVMLF   T_0, R_4, R5_4 // [5r₂₆[4], 5r₂₆[4], 5r₂₆[4], 5r₂₆[4]]\n\n\t// skip r² calculation if we are only calculating one block\n\tCMPBLE R3, $16, skip\n\n\t// calculate r²\n\tMULTIPLY(R_0, R_1, R_2, R_3, R_4, R_0, R_1, R_2, R_3, R_4, R5_1, R5_2, R5_3, R5_4, M_0, M_1, M_2, M_3, M_4)\n\tREDUCE(M_0, M_1, M_2, M_3, M_4)\n\tVGBM   $0x0f0f, T_0\n\tVERIMG $0, M_0, T_0, R_0 // [r₂₆[0], r²₂₆[0], r₂₆[0], r²₂₆[0]]\n\tVERIMG $0, M_1, T_0, R_1 // [r₂₆[1], r²₂₆[1], r₂₆[1], r²₂₆[1]]\n\tVERIMG $0, M_2, T_0, R_2 // [r₂₆[2], r²₂₆[2], r₂₆[2], r²₂₆[2]]\n\tVERIMG $0, M_3, T_0, R_3 // [r₂₆[3], r²₂₆[3], r₂₆[3], r²₂₆[3]]\n\tVERIMG $0, M_4, T_0, R_4 // [r₂₆[4], r²₂₆[4], r₂₆[4], r²₂₆[4]]\n\n\t// calculate 5r² (ignore least significant limb)\n\tVREPIF $5, T_0\n\tVMLF   T_0, R_1, R5_1 // [5r₂₆[1], 5r²₂₆[1], 5r₂₆[1], 5r²₂₆[1]]\n\tVMLF   T_0, R_2, R5_2 // [5r₂₆[2], 5r²₂₆[2], 5r₂₆[2], 5r²₂₆[2]]\n\tVMLF   T_0, R_3, R5_3 // [5r₂₆[3], 5r²₂₆[3], 5r₂₆[3], 5r²₂₆[3]]\n\tVMLF   T_0, R_4, R5_4 // [5r₂₆[4], 5r²₂₆[4], 5r₂₆[4], 5r²₂₆[4]]\n\nloop:\n\tCMPBLE R3, $32, b2 // 2 or fewer blocks remaining, need to change key coefficients\n\n\t// load next 2 blocks from message\n\tVLM (R2), T_0, T_1\n\n\t// update message slice\n\tSUB  $32, R3\n\tMOVD $32(R2), R2\n\n\t// unpack message blocks into 26-bit big-endian limbs\n\tEXPAND(T_0, T_1, M_0, M_1, M_2, M_3, M_4)\n\n\t// add 2¹²⁸ to each message block value\n\tVLEIB $4, $1, M_4\n\tVLEIB $12, $1, M_4\n\nmultiply:\n\t// accumulate the incoming message\n\tVAG H_0, M_0, M_0\n\tVAG H_3, M_3, M_3\n\tVAG H_1, M_1, M_1\n\tVAG H_4, M_4, M_4\n\tVAG H_2, M_2, M_2\n\n\t// multiply the accumulator by the key coefficient\n\tMULTIPLY(M_0, M_1, M_2, M_3, M_4, R_0, R_1, R_2, R_3, R_4, R5_1, R5_2, R5_3, R5_4, H_0, H_1, H_2, H_3, H_4)\n\n\t// carry and partially reduce the partial products\n\tREDUCE(H_0, H_1, H_2, H_3, H_4)\n\n\tCMPBNE R3, $0, loop\n\nfinish:\n\t// sum lane 0 and lane 1 and put the result in lane 1\n\tVZERO  T_0\n\tVSUMQG H_0, T_0, H_0\n\tVSUMQG H_3, T_0, H_3\n\tVSUMQG H_1, T_0, H_1\n\tVSUMQG H_4, T_0, H_4\n\tVSUMQG H_2, T_0, H_2\n\n\t// reduce again after summation\n\t// TODO(mundaym): there might be a more efficient way to do this\n\t// now that we only have 1 active lane. For example, we could\n\t// simultaneously pack the values as we reduce them.\n\tREDUCE(H_0, H_1, H_2, H_3, H_4)\n\n\t// carry h[1] through to h[4] so that only h[4] can exceed 2²⁶ - 1\n\t// TODO(mundaym): in testing this final carry was unnecessary.\n\t// Needs a proof before it can be removed though.\n\tVESRLG $26, H_1, T_1\n\tVN     MOD26, H_1, H_1\n\tVAQ    T_1, H_2, H_2\n\tVESRLG $26, H_2, T_2\n\tVN     MOD26, H_2, H_2\n\tVAQ    T_2, H_3, H_3\n\tVESRLG $26, H_3, T_3\n\tVN     MOD26, H_3, H_3\n\tVAQ    T_3, H_4, H_4\n\n\t// h is now < 2(2¹³⁰ - 5)\n\t// Pack each lane in h₂₆[0:4] into h₁₂₈[0:1].\n\tVESLG $26, H_1, H_1\n\tVESLG $26, H_3, H_3\n\tVO    H_0, H_1, H_0\n\tVO    H_2, H_3, H_2\n\tVESLG $4, H_2, H_2\n\tVLEIB $7, $48, H_1\n\tVSLB  H_1, H_2, H_2\n\tVO    H_0, H_2, H_0\n\tVLEIB $7, $104, H_1\n\tVSLB  H_1, H_4, H_3\n\tVO    H_3, H_0, H_0\n\tVLEIB $7, $24, H_1\n\tVSRLB H_1, H_4, H_1\n\n\t// update state\n\tVSTEG $1, H_0, 0(R1)\n\tVSTEG $0, H_0, 8(R1)\n\tVSTEG $1, H_1, 16(R1)\n\tRET\n\nb2:  // 2 or fewer blocks remaining\n\tCMPBLE R3, $16, b1\n\n\t// Load the 2 remaining blocks (17-32 bytes remaining).\n\tMOVD $-17(R3), R0    // index of final byte to load modulo 16\n\tVL   (R2), T_0       // load full 16 byte block\n\tVLL  R0, 16(R2), T_1 // load final (possibly partial) block and pad with zeros to 16 bytes\n\n\t// The Poly1305 algorithm requires that a 1 bit be appended to\n\t// each message block. If the final block is less than 16 bytes\n\t// long then it is easiest to insert the 1 before the message\n\t// block is split into 26-bit limbs. If, on the other hand, the\n\t// final message block is 16 bytes long then we append the 1 bit\n\t// after expansion as normal.\n\tMOVBZ  $1, R0\n\tMOVD   $-16(R3), R3   // index of byte in last block to insert 1 at (could be 16)\n\tCMPBEQ R3, $16, 2(PC) // skip the insertion if the final block is 16 bytes long\n\tVLVGB  R3, R0, T_1    // insert 1 into the byte at index R3\n\n\t// Split both blocks into 26-bit limbs in the appropriate lanes.\n\tEXPAND(T_0, T_1, M_0, M_1, M_2, M_3, M_4)\n\n\t// Append a 1 byte to the end of the second to last block.\n\tVLEIB $4, $1, M_4\n\n\t// Append a 1 byte to the end of the last block only if it is a\n\t// full 16 byte block.\n\tCMPBNE R3, $16, 2(PC)\n\tVLEIB  $12, $1, M_4\n\n\t// Finally, set up the coefficients for the final multiplication.\n\t// We have previously saved r and 5r in the 32-bit even indexes\n\t// of the R_[0-4] and R5_[1-4] coefficient registers.\n\t//\n\t// We want lane 0 to be multiplied by r² so that can be kept the\n\t// same. We want lane 1 to be multiplied by r so we need to move\n\t// the saved r value into the 32-bit odd index in lane 1 by\n\t// rotating the 64-bit lane by 32.\n\tVGBM   $0x00ff, T_0         // [0, 0xffffffffffffffff] - mask lane 1 only\n\tVERIMG $32, R_0, T_0, R_0   // [_,  r²₂₆[0], _,  r₂₆[0]]\n\tVERIMG $32, R_1, T_0, R_1   // [_,  r²₂₆[1], _,  r₂₆[1]]\n\tVERIMG $32, R_2, T_0, R_2   // [_,  r²₂₆[2], _,  r₂₆[2]]\n\tVERIMG $32, R_3, T_0, R_3   // [_,  r²₂₆[3], _,  r₂₆[3]]\n\tVERIMG $32, R_4, T_0, R_4   // [_,  r²₂₆[4], _,  r₂₆[4]]\n\tVERIMG $32, R5_1, T_0, R5_1 // [_, 5r²₂₆[1], _, 5r₂₆[1]]\n\tVERIMG $32, R5_2, T_0, R5_2 // [_, 5r²₂₆[2], _, 5r₂₆[2]]\n\tVERIMG $32, R5_3, T_0, R5_3 // [_, 5r²₂₆[3], _, 5r₂₆[3]]\n\tVERIMG $32, R5_4, T_0, R5_4 // [_, 5r²₂₆[4], _, 5r₂₆[4]]\n\n\tMOVD $0, R3\n\tBR   multiply\n\nskip:\n\tCMPBEQ R3, $0, finish\n\nb1:  // 1 block remaining\n\n\t// Load the final block (1-16 bytes). This will be placed into\n\t// lane 0.\n\tMOVD $-1(R3), R0\n\tVLL  R0, (R2), T_0 // pad to 16 bytes with zeros\n\n\t// The Poly1305 algorithm requires that a 1 bit be appended to\n\t// each message block. If the final block is less than 16 bytes\n\t// long then it is easiest to insert the 1 before the message\n\t// block is split into 26-bit limbs. If, on the other hand, the\n\t// final message block is 16 bytes long then we append the 1 bit\n\t// after expansion as normal.\n\tMOVBZ  $1, R0\n\tCMPBEQ R3, $16, 2(PC)\n\tVLVGB  R3, R0, T_0\n\n\t// Set the message block in lane 1 to the value 0 so that it\n\t// can be accumulated without affecting the final result.\n\tVZERO T_1\n\n\t// Split the final message block into 26-bit limbs in lane 0.\n\t// Lane 1 will be contain 0.\n\tEXPAND(T_0, T_1, M_0, M_1, M_2, M_3, M_4)\n\n\t// Append a 1 byte to the end of the last block only if it is a\n\t// full 16 byte block.\n\tCMPBNE R3, $16, 2(PC)\n\tVLEIB  $4, $1, M_4\n\n\t// We have previously saved r and 5r in the 32-bit even indexes\n\t// of the R_[0-4] and R5_[1-4] coefficient registers.\n\t//\n\t// We want lane 0 to be multiplied by r so we need to move the\n\t// saved r value into the 32-bit odd index in lane 0. We want\n\t// lane 1 to be set to the value 1. This makes multiplication\n\t// a no-op. We do this by setting lane 1 in every register to 0\n\t// and then just setting the 32-bit index 3 in R_0 to 1.\n\tVZERO T_0\n\tMOVD  $0, R0\n\tMOVD  $0x10111213, R12\n\tVLVGP R12, R0, T_1         // [_, 0x10111213, _, 0x00000000]\n\tVPERM T_0, R_0, T_1, R_0   // [_,  r₂₆[0], _, 0]\n\tVPERM T_0, R_1, T_1, R_1   // [_,  r₂₆[1], _, 0]\n\tVPERM T_0, R_2, T_1, R_2   // [_,  r₂₆[2], _, 0]\n\tVPERM T_0, R_3, T_1, R_3   // [_,  r₂₆[3], _, 0]\n\tVPERM T_0, R_4, T_1, R_4   // [_,  r₂₆[4], _, 0]\n\tVPERM T_0, R5_1, T_1, R5_1 // [_, 5r₂₆[1], _, 0]\n\tVPERM T_0, R5_2, T_1, R5_2 // [_, 5r₂₆[2], _, 0]\n\tVPERM T_0, R5_3, T_1, R5_3 // [_, 5r₂₆[3], _, 0]\n\tVPERM T_0, R5_4, T_1, R5_4 // [_, 5r₂₆[4], _, 0]\n\n\t// Set the value of lane 1 to be 1.\n\tVLEIF $3, $1, R_0 // [_,  r₂₆[0], _, 1]\n\n\tMOVD $0, R3\n\tBR   multiply\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/nacl/box/box.go",
    "content": "// Copyright 2012 The Go 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\n/*\nPackage box authenticates and encrypts small messages using public-key cryptography.\n\nBox uses Curve25519, XSalsa20 and Poly1305 to encrypt and authenticate\nmessages. The length of messages is not hidden.\n\nIt is the caller's responsibility to ensure the uniqueness of nonces—for\nexample, by using nonce 1 for the first message, nonce 2 for the second\nmessage, etc. Nonces are long enough that randomly generated nonces have\nnegligible risk of collision.\n\nMessages should be small because:\n\n1. The whole message needs to be held in memory to be processed.\n\n2. Using large messages pressures implementations on small machines to decrypt\nand process plaintext before authenticating it. This is very dangerous, and\nthis API does not allow it, but a protocol that uses excessive message sizes\nmight present some implementations with no other choice.\n\n3. Fixed overheads will be sufficiently amortised by messages as small as 8KB.\n\n4. Performance may be improved by working with messages that fit into data caches.\n\nThus large amounts of data should be chunked so that each message is small.\n(Each message still needs a unique nonce.) If in doubt, 16KB is a reasonable\nchunk size.\n\nThis package is interoperable with NaCl: https://nacl.cr.yp.to/box.html.\nAnonymous sealing/opening is an extension of NaCl defined by and interoperable\nwith libsodium:\nhttps://libsodium.gitbook.io/doc/public-key_cryptography/sealed_boxes.\n*/\npackage box\n\nimport (\n\tcryptorand \"crypto/rand\"\n\t\"io\"\n\n\t\"golang.org/x/crypto/blake2b\"\n\t\"golang.org/x/crypto/curve25519\"\n\t\"golang.org/x/crypto/nacl/secretbox\"\n\t\"golang.org/x/crypto/salsa20/salsa\"\n)\n\nconst (\n\t// Overhead is the number of bytes of overhead when boxing a message.\n\tOverhead = secretbox.Overhead\n\n\t// AnonymousOverhead is the number of bytes of overhead when using anonymous\n\t// sealed boxes.\n\tAnonymousOverhead = Overhead + 32\n)\n\n// GenerateKey generates a new public/private key pair suitable for use with\n// Seal and Open.\nfunc GenerateKey(rand io.Reader) (publicKey, privateKey *[32]byte, err error) {\n\tpublicKey = new([32]byte)\n\tprivateKey = new([32]byte)\n\t_, err = io.ReadFull(rand, privateKey[:])\n\tif err != nil {\n\t\tpublicKey = nil\n\t\tprivateKey = nil\n\t\treturn\n\t}\n\n\tcurve25519.ScalarBaseMult(publicKey, privateKey)\n\treturn\n}\n\nvar zeros [16]byte\n\n// Precompute calculates the shared key between peersPublicKey and privateKey\n// and writes it to sharedKey. The shared key can be used with\n// OpenAfterPrecomputation and SealAfterPrecomputation to speed up processing\n// when using the same pair of keys repeatedly.\nfunc Precompute(sharedKey, peersPublicKey, privateKey *[32]byte) {\n\tcurve25519.ScalarMult(sharedKey, privateKey, peersPublicKey)\n\tsalsa.HSalsa20(sharedKey, &zeros, sharedKey, &salsa.Sigma)\n}\n\n// Seal appends an encrypted and authenticated copy of message to out, which\n// will be Overhead bytes longer than the original and must not overlap it. The\n// nonce must be unique for each distinct message for a given pair of keys.\nfunc Seal(out, message []byte, nonce *[24]byte, peersPublicKey, privateKey *[32]byte) []byte {\n\tvar sharedKey [32]byte\n\tPrecompute(&sharedKey, peersPublicKey, privateKey)\n\treturn secretbox.Seal(out, message, nonce, &sharedKey)\n}\n\n// SealAfterPrecomputation performs the same actions as Seal, but takes a\n// shared key as generated by Precompute.\nfunc SealAfterPrecomputation(out, message []byte, nonce *[24]byte, sharedKey *[32]byte) []byte {\n\treturn secretbox.Seal(out, message, nonce, sharedKey)\n}\n\n// Open authenticates and decrypts a box produced by Seal and appends the\n// message to out, which must not overlap box. The output will be Overhead\n// bytes smaller than box.\nfunc Open(out, box []byte, nonce *[24]byte, peersPublicKey, privateKey *[32]byte) ([]byte, bool) {\n\tvar sharedKey [32]byte\n\tPrecompute(&sharedKey, peersPublicKey, privateKey)\n\treturn secretbox.Open(out, box, nonce, &sharedKey)\n}\n\n// OpenAfterPrecomputation performs the same actions as Open, but takes a\n// shared key as generated by Precompute.\nfunc OpenAfterPrecomputation(out, box []byte, nonce *[24]byte, sharedKey *[32]byte) ([]byte, bool) {\n\treturn secretbox.Open(out, box, nonce, sharedKey)\n}\n\n// SealAnonymous appends an encrypted and authenticated copy of message to out,\n// which will be AnonymousOverhead bytes longer than the original and must not\n// overlap it. This differs from Seal in that the sender is not required to\n// provide a private key.\nfunc SealAnonymous(out, message []byte, recipient *[32]byte, rand io.Reader) ([]byte, error) {\n\tif rand == nil {\n\t\trand = cryptorand.Reader\n\t}\n\tephemeralPub, ephemeralPriv, err := GenerateKey(rand)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar nonce [24]byte\n\tif err := sealNonce(ephemeralPub, recipient, &nonce); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif total := len(out) + AnonymousOverhead + len(message); cap(out) < total {\n\t\toriginal := out\n\t\tout = make([]byte, 0, total)\n\t\tout = append(out, original...)\n\t}\n\tout = append(out, ephemeralPub[:]...)\n\n\treturn Seal(out, message, &nonce, recipient, ephemeralPriv), nil\n}\n\n// OpenAnonymous authenticates and decrypts a box produced by SealAnonymous and\n// appends the message to out, which must not overlap box. The output will be\n// AnonymousOverhead bytes smaller than box.\nfunc OpenAnonymous(out, box []byte, publicKey, privateKey *[32]byte) (message []byte, ok bool) {\n\tif len(box) < AnonymousOverhead {\n\t\treturn nil, false\n\t}\n\n\tvar ephemeralPub [32]byte\n\tcopy(ephemeralPub[:], box[:32])\n\n\tvar nonce [24]byte\n\tif err := sealNonce(&ephemeralPub, publicKey, &nonce); err != nil {\n\t\treturn nil, false\n\t}\n\n\treturn Open(out, box[32:], &nonce, &ephemeralPub, privateKey)\n}\n\n// sealNonce generates a 24 byte nonce that is a blake2b digest of the\n// ephemeral public key and the receiver's public key.\nfunc sealNonce(ephemeralPub, peersPublicKey *[32]byte, nonce *[24]byte) error {\n\th, err := blake2b.New(24, nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif _, err = h.Write(ephemeralPub[:]); err != nil {\n\t\treturn err\n\t}\n\n\tif _, err = h.Write(peersPublicKey[:]); err != nil {\n\t\treturn err\n\t}\n\n\th.Sum(nonce[:0])\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go",
    "content": "// Copyright 2012 The Go 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\n/*\nPackage secretbox encrypts and authenticates small messages.\n\nSecretbox uses XSalsa20 and Poly1305 to encrypt and authenticate messages with\nsecret-key cryptography. The length of messages is not hidden.\n\nIt is the caller's responsibility to ensure the uniqueness of nonces—for\nexample, by using nonce 1 for the first message, nonce 2 for the second\nmessage, etc. Nonces are long enough that randomly generated nonces have\nnegligible risk of collision.\n\nMessages should be small because:\n\n1. The whole message needs to be held in memory to be processed.\n\n2. Using large messages pressures implementations on small machines to decrypt\nand process plaintext before authenticating it. This is very dangerous, and\nthis API does not allow it, but a protocol that uses excessive message sizes\nmight present some implementations with no other choice.\n\n3. Fixed overheads will be sufficiently amortised by messages as small as 8KB.\n\n4. Performance may be improved by working with messages that fit into data caches.\n\nThus large amounts of data should be chunked so that each message is small.\n(Each message still needs a unique nonce.) If in doubt, 16KB is a reasonable\nchunk size.\n\nThis package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html.\n*/\npackage secretbox\n\nimport (\n\t\"golang.org/x/crypto/internal/alias\"\n\t\"golang.org/x/crypto/internal/poly1305\"\n\t\"golang.org/x/crypto/salsa20/salsa\"\n)\n\n// Overhead is the number of bytes of overhead when boxing a message.\nconst Overhead = poly1305.TagSize\n\n// setup produces a sub-key and Salsa20 counter given a nonce and key.\nfunc setup(subKey *[32]byte, counter *[16]byte, nonce *[24]byte, key *[32]byte) {\n\t// We use XSalsa20 for encryption so first we need to generate a\n\t// key and nonce with HSalsa20.\n\tvar hNonce [16]byte\n\tcopy(hNonce[:], nonce[:])\n\tsalsa.HSalsa20(subKey, &hNonce, key, &salsa.Sigma)\n\n\t// The final 8 bytes of the original nonce form the new nonce.\n\tcopy(counter[:], nonce[16:])\n}\n\n// sliceForAppend takes a slice and a requested number of bytes. It returns a\n// slice with the contents of the given slice followed by that many bytes and a\n// second slice that aliases into it and contains only the extra bytes. If the\n// original slice has sufficient capacity then no allocation is performed.\nfunc sliceForAppend(in []byte, n int) (head, tail []byte) {\n\tif total := len(in) + n; cap(in) >= total {\n\t\thead = in[:total]\n\t} else {\n\t\thead = make([]byte, total)\n\t\tcopy(head, in)\n\t}\n\ttail = head[len(in):]\n\treturn\n}\n\n// Seal appends an encrypted and authenticated copy of message to out, which\n// must not overlap message. The key and nonce pair must be unique for each\n// distinct message and the output will be Overhead bytes longer than message.\nfunc Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte {\n\tvar subKey [32]byte\n\tvar counter [16]byte\n\tsetup(&subKey, &counter, nonce, key)\n\n\t// The Poly1305 key is generated by encrypting 32 bytes of zeros. Since\n\t// Salsa20 works with 64-byte blocks, we also generate 32 bytes of\n\t// keystream as a side effect.\n\tvar firstBlock [64]byte\n\tsalsa.XORKeyStream(firstBlock[:], firstBlock[:], &counter, &subKey)\n\n\tvar poly1305Key [32]byte\n\tcopy(poly1305Key[:], firstBlock[:])\n\n\tret, out := sliceForAppend(out, len(message)+poly1305.TagSize)\n\tif alias.AnyOverlap(out, message) {\n\t\tpanic(\"nacl: invalid buffer overlap\")\n\t}\n\n\t// We XOR up to 32 bytes of message with the keystream generated from\n\t// the first block.\n\tfirstMessageBlock := message\n\tif len(firstMessageBlock) > 32 {\n\t\tfirstMessageBlock = firstMessageBlock[:32]\n\t}\n\n\ttagOut := out\n\tout = out[poly1305.TagSize:]\n\tfor i, x := range firstMessageBlock {\n\t\tout[i] = firstBlock[32+i] ^ x\n\t}\n\tmessage = message[len(firstMessageBlock):]\n\tciphertext := out\n\tout = out[len(firstMessageBlock):]\n\n\t// Now encrypt the rest.\n\tcounter[8] = 1\n\tsalsa.XORKeyStream(out, message, &counter, &subKey)\n\n\tvar tag [poly1305.TagSize]byte\n\tpoly1305.Sum(&tag, ciphertext, &poly1305Key)\n\tcopy(tagOut, tag[:])\n\n\treturn ret\n}\n\n// Open authenticates and decrypts a box produced by Seal and appends the\n// message to out, which must not overlap box. The output will be Overhead\n// bytes smaller than box.\nfunc Open(out, box []byte, nonce *[24]byte, key *[32]byte) ([]byte, bool) {\n\tif len(box) < Overhead {\n\t\treturn nil, false\n\t}\n\n\tvar subKey [32]byte\n\tvar counter [16]byte\n\tsetup(&subKey, &counter, nonce, key)\n\n\t// The Poly1305 key is generated by encrypting 32 bytes of zeros. Since\n\t// Salsa20 works with 64-byte blocks, we also generate 32 bytes of\n\t// keystream as a side effect.\n\tvar firstBlock [64]byte\n\tsalsa.XORKeyStream(firstBlock[:], firstBlock[:], &counter, &subKey)\n\n\tvar poly1305Key [32]byte\n\tcopy(poly1305Key[:], firstBlock[:])\n\tvar tag [poly1305.TagSize]byte\n\tcopy(tag[:], box)\n\n\tif !poly1305.Verify(&tag, box[poly1305.TagSize:], &poly1305Key) {\n\t\treturn nil, false\n\t}\n\n\tret, out := sliceForAppend(out, len(box)-Overhead)\n\tif alias.AnyOverlap(out, box) {\n\t\tpanic(\"nacl: invalid buffer overlap\")\n\t}\n\n\t// We XOR up to 32 bytes of box with the keystream generated from\n\t// the first block.\n\tbox = box[Overhead:]\n\tfirstMessageBlock := box\n\tif len(firstMessageBlock) > 32 {\n\t\tfirstMessageBlock = firstMessageBlock[:32]\n\t}\n\tfor i, x := range firstMessageBlock {\n\t\tout[i] = firstBlock[32+i] ^ x\n\t}\n\n\tbox = box[len(firstMessageBlock):]\n\tout = out[len(firstMessageBlock):]\n\n\t// Now decrypt the rest.\n\tcounter[8] = 1\n\tsalsa.XORKeyStream(out, box, &counter, &subKey)\n\n\treturn ret, true\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go",
    "content": "// Copyright 2012 The Go 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\n// Package salsa provides low-level access to functions in the Salsa family.\npackage salsa\n\nimport \"math/bits\"\n\n// Sigma is the Salsa20 constant for 256-bit keys.\nvar Sigma = [16]byte{'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', '2', '-', 'b', 'y', 't', 'e', ' ', 'k'}\n\n// HSalsa20 applies the HSalsa20 core function to a 16-byte input in, 32-byte\n// key k, and 16-byte constant c, and puts the result into the 32-byte array\n// out.\nfunc HSalsa20(out *[32]byte, in *[16]byte, k *[32]byte, c *[16]byte) {\n\tx0 := uint32(c[0]) | uint32(c[1])<<8 | uint32(c[2])<<16 | uint32(c[3])<<24\n\tx1 := uint32(k[0]) | uint32(k[1])<<8 | uint32(k[2])<<16 | uint32(k[3])<<24\n\tx2 := uint32(k[4]) | uint32(k[5])<<8 | uint32(k[6])<<16 | uint32(k[7])<<24\n\tx3 := uint32(k[8]) | uint32(k[9])<<8 | uint32(k[10])<<16 | uint32(k[11])<<24\n\tx4 := uint32(k[12]) | uint32(k[13])<<8 | uint32(k[14])<<16 | uint32(k[15])<<24\n\tx5 := uint32(c[4]) | uint32(c[5])<<8 | uint32(c[6])<<16 | uint32(c[7])<<24\n\tx6 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24\n\tx7 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24\n\tx8 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24\n\tx9 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24\n\tx10 := uint32(c[8]) | uint32(c[9])<<8 | uint32(c[10])<<16 | uint32(c[11])<<24\n\tx11 := uint32(k[16]) | uint32(k[17])<<8 | uint32(k[18])<<16 | uint32(k[19])<<24\n\tx12 := uint32(k[20]) | uint32(k[21])<<8 | uint32(k[22])<<16 | uint32(k[23])<<24\n\tx13 := uint32(k[24]) | uint32(k[25])<<8 | uint32(k[26])<<16 | uint32(k[27])<<24\n\tx14 := uint32(k[28]) | uint32(k[29])<<8 | uint32(k[30])<<16 | uint32(k[31])<<24\n\tx15 := uint32(c[12]) | uint32(c[13])<<8 | uint32(c[14])<<16 | uint32(c[15])<<24\n\n\tfor i := 0; i < 20; i += 2 {\n\t\tu := x0 + x12\n\t\tx4 ^= bits.RotateLeft32(u, 7)\n\t\tu = x4 + x0\n\t\tx8 ^= bits.RotateLeft32(u, 9)\n\t\tu = x8 + x4\n\t\tx12 ^= bits.RotateLeft32(u, 13)\n\t\tu = x12 + x8\n\t\tx0 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x5 + x1\n\t\tx9 ^= bits.RotateLeft32(u, 7)\n\t\tu = x9 + x5\n\t\tx13 ^= bits.RotateLeft32(u, 9)\n\t\tu = x13 + x9\n\t\tx1 ^= bits.RotateLeft32(u, 13)\n\t\tu = x1 + x13\n\t\tx5 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x10 + x6\n\t\tx14 ^= bits.RotateLeft32(u, 7)\n\t\tu = x14 + x10\n\t\tx2 ^= bits.RotateLeft32(u, 9)\n\t\tu = x2 + x14\n\t\tx6 ^= bits.RotateLeft32(u, 13)\n\t\tu = x6 + x2\n\t\tx10 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x15 + x11\n\t\tx3 ^= bits.RotateLeft32(u, 7)\n\t\tu = x3 + x15\n\t\tx7 ^= bits.RotateLeft32(u, 9)\n\t\tu = x7 + x3\n\t\tx11 ^= bits.RotateLeft32(u, 13)\n\t\tu = x11 + x7\n\t\tx15 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x0 + x3\n\t\tx1 ^= bits.RotateLeft32(u, 7)\n\t\tu = x1 + x0\n\t\tx2 ^= bits.RotateLeft32(u, 9)\n\t\tu = x2 + x1\n\t\tx3 ^= bits.RotateLeft32(u, 13)\n\t\tu = x3 + x2\n\t\tx0 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x5 + x4\n\t\tx6 ^= bits.RotateLeft32(u, 7)\n\t\tu = x6 + x5\n\t\tx7 ^= bits.RotateLeft32(u, 9)\n\t\tu = x7 + x6\n\t\tx4 ^= bits.RotateLeft32(u, 13)\n\t\tu = x4 + x7\n\t\tx5 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x10 + x9\n\t\tx11 ^= bits.RotateLeft32(u, 7)\n\t\tu = x11 + x10\n\t\tx8 ^= bits.RotateLeft32(u, 9)\n\t\tu = x8 + x11\n\t\tx9 ^= bits.RotateLeft32(u, 13)\n\t\tu = x9 + x8\n\t\tx10 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x15 + x14\n\t\tx12 ^= bits.RotateLeft32(u, 7)\n\t\tu = x12 + x15\n\t\tx13 ^= bits.RotateLeft32(u, 9)\n\t\tu = x13 + x12\n\t\tx14 ^= bits.RotateLeft32(u, 13)\n\t\tu = x14 + x13\n\t\tx15 ^= bits.RotateLeft32(u, 18)\n\t}\n\tout[0] = byte(x0)\n\tout[1] = byte(x0 >> 8)\n\tout[2] = byte(x0 >> 16)\n\tout[3] = byte(x0 >> 24)\n\n\tout[4] = byte(x5)\n\tout[5] = byte(x5 >> 8)\n\tout[6] = byte(x5 >> 16)\n\tout[7] = byte(x5 >> 24)\n\n\tout[8] = byte(x10)\n\tout[9] = byte(x10 >> 8)\n\tout[10] = byte(x10 >> 16)\n\tout[11] = byte(x10 >> 24)\n\n\tout[12] = byte(x15)\n\tout[13] = byte(x15 >> 8)\n\tout[14] = byte(x15 >> 16)\n\tout[15] = byte(x15 >> 24)\n\n\tout[16] = byte(x6)\n\tout[17] = byte(x6 >> 8)\n\tout[18] = byte(x6 >> 16)\n\tout[19] = byte(x6 >> 24)\n\n\tout[20] = byte(x7)\n\tout[21] = byte(x7 >> 8)\n\tout[22] = byte(x7 >> 16)\n\tout[23] = byte(x7 >> 24)\n\n\tout[24] = byte(x8)\n\tout[25] = byte(x8 >> 8)\n\tout[26] = byte(x8 >> 16)\n\tout[27] = byte(x8 >> 24)\n\n\tout[28] = byte(x9)\n\tout[29] = byte(x9 >> 8)\n\tout[30] = byte(x9 >> 16)\n\tout[31] = byte(x9 >> 24)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/salsa20/salsa/salsa208.go",
    "content": "// Copyright 2012 The Go 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 salsa\n\nimport \"math/bits\"\n\n// Core208 applies the Salsa20/8 core function to the 64-byte array in and puts\n// the result into the 64-byte array out. The input and output may be the same array.\nfunc Core208(out *[64]byte, in *[64]byte) {\n\tj0 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24\n\tj1 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24\n\tj2 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24\n\tj3 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24\n\tj4 := uint32(in[16]) | uint32(in[17])<<8 | uint32(in[18])<<16 | uint32(in[19])<<24\n\tj5 := uint32(in[20]) | uint32(in[21])<<8 | uint32(in[22])<<16 | uint32(in[23])<<24\n\tj6 := uint32(in[24]) | uint32(in[25])<<8 | uint32(in[26])<<16 | uint32(in[27])<<24\n\tj7 := uint32(in[28]) | uint32(in[29])<<8 | uint32(in[30])<<16 | uint32(in[31])<<24\n\tj8 := uint32(in[32]) | uint32(in[33])<<8 | uint32(in[34])<<16 | uint32(in[35])<<24\n\tj9 := uint32(in[36]) | uint32(in[37])<<8 | uint32(in[38])<<16 | uint32(in[39])<<24\n\tj10 := uint32(in[40]) | uint32(in[41])<<8 | uint32(in[42])<<16 | uint32(in[43])<<24\n\tj11 := uint32(in[44]) | uint32(in[45])<<8 | uint32(in[46])<<16 | uint32(in[47])<<24\n\tj12 := uint32(in[48]) | uint32(in[49])<<8 | uint32(in[50])<<16 | uint32(in[51])<<24\n\tj13 := uint32(in[52]) | uint32(in[53])<<8 | uint32(in[54])<<16 | uint32(in[55])<<24\n\tj14 := uint32(in[56]) | uint32(in[57])<<8 | uint32(in[58])<<16 | uint32(in[59])<<24\n\tj15 := uint32(in[60]) | uint32(in[61])<<8 | uint32(in[62])<<16 | uint32(in[63])<<24\n\n\tx0, x1, x2, x3, x4, x5, x6, x7, x8 := j0, j1, j2, j3, j4, j5, j6, j7, j8\n\tx9, x10, x11, x12, x13, x14, x15 := j9, j10, j11, j12, j13, j14, j15\n\n\tfor i := 0; i < 8; i += 2 {\n\t\tu := x0 + x12\n\t\tx4 ^= bits.RotateLeft32(u, 7)\n\t\tu = x4 + x0\n\t\tx8 ^= bits.RotateLeft32(u, 9)\n\t\tu = x8 + x4\n\t\tx12 ^= bits.RotateLeft32(u, 13)\n\t\tu = x12 + x8\n\t\tx0 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x5 + x1\n\t\tx9 ^= bits.RotateLeft32(u, 7)\n\t\tu = x9 + x5\n\t\tx13 ^= bits.RotateLeft32(u, 9)\n\t\tu = x13 + x9\n\t\tx1 ^= bits.RotateLeft32(u, 13)\n\t\tu = x1 + x13\n\t\tx5 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x10 + x6\n\t\tx14 ^= bits.RotateLeft32(u, 7)\n\t\tu = x14 + x10\n\t\tx2 ^= bits.RotateLeft32(u, 9)\n\t\tu = x2 + x14\n\t\tx6 ^= bits.RotateLeft32(u, 13)\n\t\tu = x6 + x2\n\t\tx10 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x15 + x11\n\t\tx3 ^= bits.RotateLeft32(u, 7)\n\t\tu = x3 + x15\n\t\tx7 ^= bits.RotateLeft32(u, 9)\n\t\tu = x7 + x3\n\t\tx11 ^= bits.RotateLeft32(u, 13)\n\t\tu = x11 + x7\n\t\tx15 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x0 + x3\n\t\tx1 ^= bits.RotateLeft32(u, 7)\n\t\tu = x1 + x0\n\t\tx2 ^= bits.RotateLeft32(u, 9)\n\t\tu = x2 + x1\n\t\tx3 ^= bits.RotateLeft32(u, 13)\n\t\tu = x3 + x2\n\t\tx0 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x5 + x4\n\t\tx6 ^= bits.RotateLeft32(u, 7)\n\t\tu = x6 + x5\n\t\tx7 ^= bits.RotateLeft32(u, 9)\n\t\tu = x7 + x6\n\t\tx4 ^= bits.RotateLeft32(u, 13)\n\t\tu = x4 + x7\n\t\tx5 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x10 + x9\n\t\tx11 ^= bits.RotateLeft32(u, 7)\n\t\tu = x11 + x10\n\t\tx8 ^= bits.RotateLeft32(u, 9)\n\t\tu = x8 + x11\n\t\tx9 ^= bits.RotateLeft32(u, 13)\n\t\tu = x9 + x8\n\t\tx10 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x15 + x14\n\t\tx12 ^= bits.RotateLeft32(u, 7)\n\t\tu = x12 + x15\n\t\tx13 ^= bits.RotateLeft32(u, 9)\n\t\tu = x13 + x12\n\t\tx14 ^= bits.RotateLeft32(u, 13)\n\t\tu = x14 + x13\n\t\tx15 ^= bits.RotateLeft32(u, 18)\n\t}\n\tx0 += j0\n\tx1 += j1\n\tx2 += j2\n\tx3 += j3\n\tx4 += j4\n\tx5 += j5\n\tx6 += j6\n\tx7 += j7\n\tx8 += j8\n\tx9 += j9\n\tx10 += j10\n\tx11 += j11\n\tx12 += j12\n\tx13 += j13\n\tx14 += j14\n\tx15 += j15\n\n\tout[0] = byte(x0)\n\tout[1] = byte(x0 >> 8)\n\tout[2] = byte(x0 >> 16)\n\tout[3] = byte(x0 >> 24)\n\n\tout[4] = byte(x1)\n\tout[5] = byte(x1 >> 8)\n\tout[6] = byte(x1 >> 16)\n\tout[7] = byte(x1 >> 24)\n\n\tout[8] = byte(x2)\n\tout[9] = byte(x2 >> 8)\n\tout[10] = byte(x2 >> 16)\n\tout[11] = byte(x2 >> 24)\n\n\tout[12] = byte(x3)\n\tout[13] = byte(x3 >> 8)\n\tout[14] = byte(x3 >> 16)\n\tout[15] = byte(x3 >> 24)\n\n\tout[16] = byte(x4)\n\tout[17] = byte(x4 >> 8)\n\tout[18] = byte(x4 >> 16)\n\tout[19] = byte(x4 >> 24)\n\n\tout[20] = byte(x5)\n\tout[21] = byte(x5 >> 8)\n\tout[22] = byte(x5 >> 16)\n\tout[23] = byte(x5 >> 24)\n\n\tout[24] = byte(x6)\n\tout[25] = byte(x6 >> 8)\n\tout[26] = byte(x6 >> 16)\n\tout[27] = byte(x6 >> 24)\n\n\tout[28] = byte(x7)\n\tout[29] = byte(x7 >> 8)\n\tout[30] = byte(x7 >> 16)\n\tout[31] = byte(x7 >> 24)\n\n\tout[32] = byte(x8)\n\tout[33] = byte(x8 >> 8)\n\tout[34] = byte(x8 >> 16)\n\tout[35] = byte(x8 >> 24)\n\n\tout[36] = byte(x9)\n\tout[37] = byte(x9 >> 8)\n\tout[38] = byte(x9 >> 16)\n\tout[39] = byte(x9 >> 24)\n\n\tout[40] = byte(x10)\n\tout[41] = byte(x10 >> 8)\n\tout[42] = byte(x10 >> 16)\n\tout[43] = byte(x10 >> 24)\n\n\tout[44] = byte(x11)\n\tout[45] = byte(x11 >> 8)\n\tout[46] = byte(x11 >> 16)\n\tout[47] = byte(x11 >> 24)\n\n\tout[48] = byte(x12)\n\tout[49] = byte(x12 >> 8)\n\tout[50] = byte(x12 >> 16)\n\tout[51] = byte(x12 >> 24)\n\n\tout[52] = byte(x13)\n\tout[53] = byte(x13 >> 8)\n\tout[54] = byte(x13 >> 16)\n\tout[55] = byte(x13 >> 24)\n\n\tout[56] = byte(x14)\n\tout[57] = byte(x14 >> 8)\n\tout[58] = byte(x14 >> 16)\n\tout[59] = byte(x14 >> 24)\n\n\tout[60] = byte(x15)\n\tout[61] = byte(x15 >> 8)\n\tout[62] = byte(x15 >> 16)\n\tout[63] = byte(x15 >> 24)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go",
    "content": "// Copyright 2012 The Go 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\n//go:build amd64 && !purego && gc\n\npackage salsa\n\n//go:noescape\n\n// salsa2020XORKeyStream is implemented in salsa20_amd64.s.\nfunc salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)\n\n// XORKeyStream crypts bytes from in to out using the given key and counters.\n// In and out must overlap entirely or not at all. Counter\n// contains the raw salsa20 counter bytes (both nonce and block counter).\nfunc XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {\n\tif len(in) == 0 {\n\t\treturn\n\t}\n\t_ = out[len(in)-1]\n\tsalsa2020XORKeyStream(&out[0], &in[0], uint64(len(in)), &counter[0], &key[0])\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.s",
    "content": "// Code generated by command: go run salsa20_amd64_asm.go -out ../salsa20_amd64.s -pkg salsa. DO NOT EDIT.\n\n//go:build amd64 && !purego && gc\n\n// func salsa2020XORKeyStream(out *byte, in *byte, n uint64, nonce *byte, key *byte)\n// Requires: SSE2\nTEXT ·salsa2020XORKeyStream(SB), $456-40\n\t// This needs up to 64 bytes at 360(R12); hence the non-obvious frame size.\n\tMOVQ   out+0(FP), DI\n\tMOVQ   in+8(FP), SI\n\tMOVQ   n+16(FP), DX\n\tMOVQ   nonce+24(FP), CX\n\tMOVQ   key+32(FP), R8\n\tMOVQ   SP, R12\n\tADDQ   $0x1f, R12\n\tANDQ   $-32, R12\n\tMOVQ   DX, R9\n\tMOVQ   CX, DX\n\tMOVQ   R8, R10\n\tCMPQ   R9, $0x00\n\tJBE    DONE\n\tMOVL   20(R10), CX\n\tMOVL   (R10), R8\n\tMOVL   (DX), AX\n\tMOVL   16(R10), R11\n\tMOVL   CX, (R12)\n\tMOVL   R8, 4(R12)\n\tMOVL   AX, 8(R12)\n\tMOVL   R11, 12(R12)\n\tMOVL   8(DX), CX\n\tMOVL   24(R10), R8\n\tMOVL   4(R10), AX\n\tMOVL   4(DX), R11\n\tMOVL   CX, 16(R12)\n\tMOVL   R8, 20(R12)\n\tMOVL   AX, 24(R12)\n\tMOVL   R11, 28(R12)\n\tMOVL   12(DX), CX\n\tMOVL   12(R10), DX\n\tMOVL   28(R10), R8\n\tMOVL   8(R10), AX\n\tMOVL   DX, 32(R12)\n\tMOVL   CX, 36(R12)\n\tMOVL   R8, 40(R12)\n\tMOVL   AX, 44(R12)\n\tMOVQ   $0x61707865, DX\n\tMOVQ   $0x3320646e, CX\n\tMOVQ   $0x79622d32, R8\n\tMOVQ   $0x6b206574, AX\n\tMOVL   DX, 48(R12)\n\tMOVL   CX, 52(R12)\n\tMOVL   R8, 56(R12)\n\tMOVL   AX, 60(R12)\n\tCMPQ   R9, $0x00000100\n\tJB     BYTESBETWEEN1AND255\n\tMOVOA  48(R12), X0\n\tPSHUFL $0x55, X0, X1\n\tPSHUFL $0xaa, X0, X2\n\tPSHUFL $0xff, X0, X3\n\tPSHUFL $0x00, X0, X0\n\tMOVOA  X1, 64(R12)\n\tMOVOA  X2, 80(R12)\n\tMOVOA  X3, 96(R12)\n\tMOVOA  X0, 112(R12)\n\tMOVOA  (R12), X0\n\tPSHUFL $0xaa, X0, X1\n\tPSHUFL $0xff, X0, X2\n\tPSHUFL $0x00, X0, X3\n\tPSHUFL $0x55, X0, X0\n\tMOVOA  X1, 128(R12)\n\tMOVOA  X2, 144(R12)\n\tMOVOA  X3, 160(R12)\n\tMOVOA  X0, 176(R12)\n\tMOVOA  16(R12), X0\n\tPSHUFL $0xff, X0, X1\n\tPSHUFL $0x55, X0, X2\n\tPSHUFL $0xaa, X0, X0\n\tMOVOA  X1, 192(R12)\n\tMOVOA  X2, 208(R12)\n\tMOVOA  X0, 224(R12)\n\tMOVOA  32(R12), X0\n\tPSHUFL $0x00, X0, X1\n\tPSHUFL $0xaa, X0, X2\n\tPSHUFL $0xff, X0, X0\n\tMOVOA  X1, 240(R12)\n\tMOVOA  X2, 256(R12)\n\tMOVOA  X0, 272(R12)\n\nBYTESATLEAST256:\n\tMOVL  16(R12), DX\n\tMOVL  36(R12), CX\n\tMOVL  DX, 288(R12)\n\tMOVL  CX, 304(R12)\n\tSHLQ  $0x20, CX\n\tADDQ  CX, DX\n\tADDQ  $0x01, DX\n\tMOVQ  DX, CX\n\tSHRQ  $0x20, CX\n\tMOVL  DX, 292(R12)\n\tMOVL  CX, 308(R12)\n\tADDQ  $0x01, DX\n\tMOVQ  DX, CX\n\tSHRQ  $0x20, CX\n\tMOVL  DX, 296(R12)\n\tMOVL  CX, 312(R12)\n\tADDQ  $0x01, DX\n\tMOVQ  DX, CX\n\tSHRQ  $0x20, CX\n\tMOVL  DX, 300(R12)\n\tMOVL  CX, 316(R12)\n\tADDQ  $0x01, DX\n\tMOVQ  DX, CX\n\tSHRQ  $0x20, CX\n\tMOVL  DX, 16(R12)\n\tMOVL  CX, 36(R12)\n\tMOVQ  R9, 352(R12)\n\tMOVQ  $0x00000014, DX\n\tMOVOA 64(R12), X0\n\tMOVOA 80(R12), X1\n\tMOVOA 96(R12), X2\n\tMOVOA 256(R12), X3\n\tMOVOA 272(R12), X4\n\tMOVOA 128(R12), X5\n\tMOVOA 144(R12), X6\n\tMOVOA 176(R12), X7\n\tMOVOA 192(R12), X8\n\tMOVOA 208(R12), X9\n\tMOVOA 224(R12), X10\n\tMOVOA 304(R12), X11\n\tMOVOA 112(R12), X12\n\tMOVOA 160(R12), X13\n\tMOVOA 240(R12), X14\n\tMOVOA 288(R12), X15\n\nMAINLOOP1:\n\tMOVOA  X1, 320(R12)\n\tMOVOA  X2, 336(R12)\n\tMOVOA  X13, X1\n\tPADDL  X12, X1\n\tMOVOA  X1, X2\n\tPSLLL  $0x07, X1\n\tPXOR   X1, X14\n\tPSRLL  $0x19, X2\n\tPXOR   X2, X14\n\tMOVOA  X7, X1\n\tPADDL  X0, X1\n\tMOVOA  X1, X2\n\tPSLLL  $0x07, X1\n\tPXOR   X1, X11\n\tPSRLL  $0x19, X2\n\tPXOR   X2, X11\n\tMOVOA  X12, X1\n\tPADDL  X14, X1\n\tMOVOA  X1, X2\n\tPSLLL  $0x09, X1\n\tPXOR   X1, X15\n\tPSRLL  $0x17, X2\n\tPXOR   X2, X15\n\tMOVOA  X0, X1\n\tPADDL  X11, X1\n\tMOVOA  X1, X2\n\tPSLLL  $0x09, X1\n\tPXOR   X1, X9\n\tPSRLL  $0x17, X2\n\tPXOR   X2, X9\n\tMOVOA  X14, X1\n\tPADDL  X15, X1\n\tMOVOA  X1, X2\n\tPSLLL  $0x0d, X1\n\tPXOR   X1, X13\n\tPSRLL  $0x13, X2\n\tPXOR   X2, X13\n\tMOVOA  X11, X1\n\tPADDL  X9, X1\n\tMOVOA  X1, X2\n\tPSLLL  $0x0d, X1\n\tPXOR   X1, X7\n\tPSRLL  $0x13, X2\n\tPXOR   X2, X7\n\tMOVOA  X15, X1\n\tPADDL  X13, X1\n\tMOVOA  X1, X2\n\tPSLLL  $0x12, X1\n\tPXOR   X1, X12\n\tPSRLL  $0x0e, X2\n\tPXOR   X2, X12\n\tMOVOA  320(R12), X1\n\tMOVOA  X12, 320(R12)\n\tMOVOA  X9, X2\n\tPADDL  X7, X2\n\tMOVOA  X2, X12\n\tPSLLL  $0x12, X2\n\tPXOR   X2, X0\n\tPSRLL  $0x0e, X12\n\tPXOR   X12, X0\n\tMOVOA  X5, X2\n\tPADDL  X1, X2\n\tMOVOA  X2, X12\n\tPSLLL  $0x07, X2\n\tPXOR   X2, X3\n\tPSRLL  $0x19, X12\n\tPXOR   X12, X3\n\tMOVOA  336(R12), X2\n\tMOVOA  X0, 336(R12)\n\tMOVOA  X6, X0\n\tPADDL  X2, X0\n\tMOVOA  X0, X12\n\tPSLLL  $0x07, X0\n\tPXOR   X0, X4\n\tPSRLL  $0x19, X12\n\tPXOR   X12, X4\n\tMOVOA  X1, X0\n\tPADDL  X3, X0\n\tMOVOA  X0, X12\n\tPSLLL  $0x09, X0\n\tPXOR   X0, X10\n\tPSRLL  $0x17, X12\n\tPXOR   X12, X10\n\tMOVOA  X2, X0\n\tPADDL  X4, X0\n\tMOVOA  X0, X12\n\tPSLLL  $0x09, X0\n\tPXOR   X0, X8\n\tPSRLL  $0x17, X12\n\tPXOR   X12, X8\n\tMOVOA  X3, X0\n\tPADDL  X10, X0\n\tMOVOA  X0, X12\n\tPSLLL  $0x0d, X0\n\tPXOR   X0, X5\n\tPSRLL  $0x13, X12\n\tPXOR   X12, X5\n\tMOVOA  X4, X0\n\tPADDL  X8, X0\n\tMOVOA  X0, X12\n\tPSLLL  $0x0d, X0\n\tPXOR   X0, X6\n\tPSRLL  $0x13, X12\n\tPXOR   X12, X6\n\tMOVOA  X10, X0\n\tPADDL  X5, X0\n\tMOVOA  X0, X12\n\tPSLLL  $0x12, X0\n\tPXOR   X0, X1\n\tPSRLL  $0x0e, X12\n\tPXOR   X12, X1\n\tMOVOA  320(R12), X0\n\tMOVOA  X1, 320(R12)\n\tMOVOA  X4, X1\n\tPADDL  X0, X1\n\tMOVOA  X1, X12\n\tPSLLL  $0x07, X1\n\tPXOR   X1, X7\n\tPSRLL  $0x19, X12\n\tPXOR   X12, X7\n\tMOVOA  X8, X1\n\tPADDL  X6, X1\n\tMOVOA  X1, X12\n\tPSLLL  $0x12, X1\n\tPXOR   X1, X2\n\tPSRLL  $0x0e, X12\n\tPXOR   X12, X2\n\tMOVOA  336(R12), X12\n\tMOVOA  X2, 336(R12)\n\tMOVOA  X14, X1\n\tPADDL  X12, X1\n\tMOVOA  X1, X2\n\tPSLLL  $0x07, X1\n\tPXOR   X1, X5\n\tPSRLL  $0x19, X2\n\tPXOR   X2, X5\n\tMOVOA  X0, X1\n\tPADDL  X7, X1\n\tMOVOA  X1, X2\n\tPSLLL  $0x09, X1\n\tPXOR   X1, X10\n\tPSRLL  $0x17, X2\n\tPXOR   X2, X10\n\tMOVOA  X12, X1\n\tPADDL  X5, X1\n\tMOVOA  X1, X2\n\tPSLLL  $0x09, X1\n\tPXOR   X1, X8\n\tPSRLL  $0x17, X2\n\tPXOR   X2, X8\n\tMOVOA  X7, X1\n\tPADDL  X10, X1\n\tMOVOA  X1, X2\n\tPSLLL  $0x0d, X1\n\tPXOR   X1, X4\n\tPSRLL  $0x13, X2\n\tPXOR   X2, X4\n\tMOVOA  X5, X1\n\tPADDL  X8, X1\n\tMOVOA  X1, X2\n\tPSLLL  $0x0d, X1\n\tPXOR   X1, X14\n\tPSRLL  $0x13, X2\n\tPXOR   X2, X14\n\tMOVOA  X10, X1\n\tPADDL  X4, X1\n\tMOVOA  X1, X2\n\tPSLLL  $0x12, X1\n\tPXOR   X1, X0\n\tPSRLL  $0x0e, X2\n\tPXOR   X2, X0\n\tMOVOA  320(R12), X1\n\tMOVOA  X0, 320(R12)\n\tMOVOA  X8, X0\n\tPADDL  X14, X0\n\tMOVOA  X0, X2\n\tPSLLL  $0x12, X0\n\tPXOR   X0, X12\n\tPSRLL  $0x0e, X2\n\tPXOR   X2, X12\n\tMOVOA  X11, X0\n\tPADDL  X1, X0\n\tMOVOA  X0, X2\n\tPSLLL  $0x07, X0\n\tPXOR   X0, X6\n\tPSRLL  $0x19, X2\n\tPXOR   X2, X6\n\tMOVOA  336(R12), X2\n\tMOVOA  X12, 336(R12)\n\tMOVOA  X3, X0\n\tPADDL  X2, X0\n\tMOVOA  X0, X12\n\tPSLLL  $0x07, X0\n\tPXOR   X0, X13\n\tPSRLL  $0x19, X12\n\tPXOR   X12, X13\n\tMOVOA  X1, X0\n\tPADDL  X6, X0\n\tMOVOA  X0, X12\n\tPSLLL  $0x09, X0\n\tPXOR   X0, X15\n\tPSRLL  $0x17, X12\n\tPXOR   X12, X15\n\tMOVOA  X2, X0\n\tPADDL  X13, X0\n\tMOVOA  X0, X12\n\tPSLLL  $0x09, X0\n\tPXOR   X0, X9\n\tPSRLL  $0x17, X12\n\tPXOR   X12, X9\n\tMOVOA  X6, X0\n\tPADDL  X15, X0\n\tMOVOA  X0, X12\n\tPSLLL  $0x0d, X0\n\tPXOR   X0, X11\n\tPSRLL  $0x13, X12\n\tPXOR   X12, X11\n\tMOVOA  X13, X0\n\tPADDL  X9, X0\n\tMOVOA  X0, X12\n\tPSLLL  $0x0d, X0\n\tPXOR   X0, X3\n\tPSRLL  $0x13, X12\n\tPXOR   X12, X3\n\tMOVOA  X15, X0\n\tPADDL  X11, X0\n\tMOVOA  X0, X12\n\tPSLLL  $0x12, X0\n\tPXOR   X0, X1\n\tPSRLL  $0x0e, X12\n\tPXOR   X12, X1\n\tMOVOA  X9, X0\n\tPADDL  X3, X0\n\tMOVOA  X0, X12\n\tPSLLL  $0x12, X0\n\tPXOR   X0, X2\n\tPSRLL  $0x0e, X12\n\tPXOR   X12, X2\n\tMOVOA  320(R12), X12\n\tMOVOA  336(R12), X0\n\tSUBQ   $0x02, DX\n\tJA     MAINLOOP1\n\tPADDL  112(R12), X12\n\tPADDL  176(R12), X7\n\tPADDL  224(R12), X10\n\tPADDL  272(R12), X4\n\tMOVD   X12, DX\n\tMOVD   X7, CX\n\tMOVD   X10, R8\n\tMOVD   X4, R9\n\tPSHUFL $0x39, X12, X12\n\tPSHUFL $0x39, X7, X7\n\tPSHUFL $0x39, X10, X10\n\tPSHUFL $0x39, X4, X4\n\tXORL   (SI), DX\n\tXORL   4(SI), CX\n\tXORL   8(SI), R8\n\tXORL   12(SI), R9\n\tMOVL   DX, (DI)\n\tMOVL   CX, 4(DI)\n\tMOVL   R8, 8(DI)\n\tMOVL   R9, 12(DI)\n\tMOVD   X12, DX\n\tMOVD   X7, CX\n\tMOVD   X10, R8\n\tMOVD   X4, R9\n\tPSHUFL $0x39, X12, X12\n\tPSHUFL $0x39, X7, X7\n\tPSHUFL $0x39, X10, X10\n\tPSHUFL $0x39, X4, X4\n\tXORL   64(SI), DX\n\tXORL   68(SI), CX\n\tXORL   72(SI), R8\n\tXORL   76(SI), R9\n\tMOVL   DX, 64(DI)\n\tMOVL   CX, 68(DI)\n\tMOVL   R8, 72(DI)\n\tMOVL   R9, 76(DI)\n\tMOVD   X12, DX\n\tMOVD   X7, CX\n\tMOVD   X10, R8\n\tMOVD   X4, R9\n\tPSHUFL $0x39, X12, X12\n\tPSHUFL $0x39, X7, X7\n\tPSHUFL $0x39, X10, X10\n\tPSHUFL $0x39, X4, X4\n\tXORL   128(SI), DX\n\tXORL   132(SI), CX\n\tXORL   136(SI), R8\n\tXORL   140(SI), R9\n\tMOVL   DX, 128(DI)\n\tMOVL   CX, 132(DI)\n\tMOVL   R8, 136(DI)\n\tMOVL   R9, 140(DI)\n\tMOVD   X12, DX\n\tMOVD   X7, CX\n\tMOVD   X10, R8\n\tMOVD   X4, R9\n\tXORL   192(SI), DX\n\tXORL   196(SI), CX\n\tXORL   200(SI), R8\n\tXORL   204(SI), R9\n\tMOVL   DX, 192(DI)\n\tMOVL   CX, 196(DI)\n\tMOVL   R8, 200(DI)\n\tMOVL   R9, 204(DI)\n\tPADDL  240(R12), X14\n\tPADDL  64(R12), X0\n\tPADDL  128(R12), X5\n\tPADDL  192(R12), X8\n\tMOVD   X14, DX\n\tMOVD   X0, CX\n\tMOVD   X5, R8\n\tMOVD   X8, R9\n\tPSHUFL $0x39, X14, X14\n\tPSHUFL $0x39, X0, X0\n\tPSHUFL $0x39, X5, X5\n\tPSHUFL $0x39, X8, X8\n\tXORL   16(SI), DX\n\tXORL   20(SI), CX\n\tXORL   24(SI), R8\n\tXORL   28(SI), R9\n\tMOVL   DX, 16(DI)\n\tMOVL   CX, 20(DI)\n\tMOVL   R8, 24(DI)\n\tMOVL   R9, 28(DI)\n\tMOVD   X14, DX\n\tMOVD   X0, CX\n\tMOVD   X5, R8\n\tMOVD   X8, R9\n\tPSHUFL $0x39, X14, X14\n\tPSHUFL $0x39, X0, X0\n\tPSHUFL $0x39, X5, X5\n\tPSHUFL $0x39, X8, X8\n\tXORL   80(SI), DX\n\tXORL   84(SI), CX\n\tXORL   88(SI), R8\n\tXORL   92(SI), R9\n\tMOVL   DX, 80(DI)\n\tMOVL   CX, 84(DI)\n\tMOVL   R8, 88(DI)\n\tMOVL   R9, 92(DI)\n\tMOVD   X14, DX\n\tMOVD   X0, CX\n\tMOVD   X5, R8\n\tMOVD   X8, R9\n\tPSHUFL $0x39, X14, X14\n\tPSHUFL $0x39, X0, X0\n\tPSHUFL $0x39, X5, X5\n\tPSHUFL $0x39, X8, X8\n\tXORL   144(SI), DX\n\tXORL   148(SI), CX\n\tXORL   152(SI), R8\n\tXORL   156(SI), R9\n\tMOVL   DX, 144(DI)\n\tMOVL   CX, 148(DI)\n\tMOVL   R8, 152(DI)\n\tMOVL   R9, 156(DI)\n\tMOVD   X14, DX\n\tMOVD   X0, CX\n\tMOVD   X5, R8\n\tMOVD   X8, R9\n\tXORL   208(SI), DX\n\tXORL   212(SI), CX\n\tXORL   216(SI), R8\n\tXORL   220(SI), R9\n\tMOVL   DX, 208(DI)\n\tMOVL   CX, 212(DI)\n\tMOVL   R8, 216(DI)\n\tMOVL   R9, 220(DI)\n\tPADDL  288(R12), X15\n\tPADDL  304(R12), X11\n\tPADDL  80(R12), X1\n\tPADDL  144(R12), X6\n\tMOVD   X15, DX\n\tMOVD   X11, CX\n\tMOVD   X1, R8\n\tMOVD   X6, R9\n\tPSHUFL $0x39, X15, X15\n\tPSHUFL $0x39, X11, X11\n\tPSHUFL $0x39, X1, X1\n\tPSHUFL $0x39, X6, X6\n\tXORL   32(SI), DX\n\tXORL   36(SI), CX\n\tXORL   40(SI), R8\n\tXORL   44(SI), R9\n\tMOVL   DX, 32(DI)\n\tMOVL   CX, 36(DI)\n\tMOVL   R8, 40(DI)\n\tMOVL   R9, 44(DI)\n\tMOVD   X15, DX\n\tMOVD   X11, CX\n\tMOVD   X1, R8\n\tMOVD   X6, R9\n\tPSHUFL $0x39, X15, X15\n\tPSHUFL $0x39, X11, X11\n\tPSHUFL $0x39, X1, X1\n\tPSHUFL $0x39, X6, X6\n\tXORL   96(SI), DX\n\tXORL   100(SI), CX\n\tXORL   104(SI), R8\n\tXORL   108(SI), R9\n\tMOVL   DX, 96(DI)\n\tMOVL   CX, 100(DI)\n\tMOVL   R8, 104(DI)\n\tMOVL   R9, 108(DI)\n\tMOVD   X15, DX\n\tMOVD   X11, CX\n\tMOVD   X1, R8\n\tMOVD   X6, R9\n\tPSHUFL $0x39, X15, X15\n\tPSHUFL $0x39, X11, X11\n\tPSHUFL $0x39, X1, X1\n\tPSHUFL $0x39, X6, X6\n\tXORL   160(SI), DX\n\tXORL   164(SI), CX\n\tXORL   168(SI), R8\n\tXORL   172(SI), R9\n\tMOVL   DX, 160(DI)\n\tMOVL   CX, 164(DI)\n\tMOVL   R8, 168(DI)\n\tMOVL   R9, 172(DI)\n\tMOVD   X15, DX\n\tMOVD   X11, CX\n\tMOVD   X1, R8\n\tMOVD   X6, R9\n\tXORL   224(SI), DX\n\tXORL   228(SI), CX\n\tXORL   232(SI), R8\n\tXORL   236(SI), R9\n\tMOVL   DX, 224(DI)\n\tMOVL   CX, 228(DI)\n\tMOVL   R8, 232(DI)\n\tMOVL   R9, 236(DI)\n\tPADDL  160(R12), X13\n\tPADDL  208(R12), X9\n\tPADDL  256(R12), X3\n\tPADDL  96(R12), X2\n\tMOVD   X13, DX\n\tMOVD   X9, CX\n\tMOVD   X3, R8\n\tMOVD   X2, R9\n\tPSHUFL $0x39, X13, X13\n\tPSHUFL $0x39, X9, X9\n\tPSHUFL $0x39, X3, X3\n\tPSHUFL $0x39, X2, X2\n\tXORL   48(SI), DX\n\tXORL   52(SI), CX\n\tXORL   56(SI), R8\n\tXORL   60(SI), R9\n\tMOVL   DX, 48(DI)\n\tMOVL   CX, 52(DI)\n\tMOVL   R8, 56(DI)\n\tMOVL   R9, 60(DI)\n\tMOVD   X13, DX\n\tMOVD   X9, CX\n\tMOVD   X3, R8\n\tMOVD   X2, R9\n\tPSHUFL $0x39, X13, X13\n\tPSHUFL $0x39, X9, X9\n\tPSHUFL $0x39, X3, X3\n\tPSHUFL $0x39, X2, X2\n\tXORL   112(SI), DX\n\tXORL   116(SI), CX\n\tXORL   120(SI), R8\n\tXORL   124(SI), R9\n\tMOVL   DX, 112(DI)\n\tMOVL   CX, 116(DI)\n\tMOVL   R8, 120(DI)\n\tMOVL   R9, 124(DI)\n\tMOVD   X13, DX\n\tMOVD   X9, CX\n\tMOVD   X3, R8\n\tMOVD   X2, R9\n\tPSHUFL $0x39, X13, X13\n\tPSHUFL $0x39, X9, X9\n\tPSHUFL $0x39, X3, X3\n\tPSHUFL $0x39, X2, X2\n\tXORL   176(SI), DX\n\tXORL   180(SI), CX\n\tXORL   184(SI), R8\n\tXORL   188(SI), R9\n\tMOVL   DX, 176(DI)\n\tMOVL   CX, 180(DI)\n\tMOVL   R8, 184(DI)\n\tMOVL   R9, 188(DI)\n\tMOVD   X13, DX\n\tMOVD   X9, CX\n\tMOVD   X3, R8\n\tMOVD   X2, R9\n\tXORL   240(SI), DX\n\tXORL   244(SI), CX\n\tXORL   248(SI), R8\n\tXORL   252(SI), R9\n\tMOVL   DX, 240(DI)\n\tMOVL   CX, 244(DI)\n\tMOVL   R8, 248(DI)\n\tMOVL   R9, 252(DI)\n\tMOVQ   352(R12), R9\n\tSUBQ   $0x00000100, R9\n\tADDQ   $0x00000100, SI\n\tADDQ   $0x00000100, DI\n\tCMPQ   R9, $0x00000100\n\tJAE    BYTESATLEAST256\n\tCMPQ   R9, $0x00\n\tJBE    DONE\n\nBYTESBETWEEN1AND255:\n\tCMPQ R9, $0x40\n\tJAE  NOCOPY\n\tMOVQ DI, DX\n\tLEAQ 360(R12), DI\n\tMOVQ R9, CX\n\tREP; MOVSB\n\tLEAQ 360(R12), DI\n\tLEAQ 360(R12), SI\n\nNOCOPY:\n\tMOVQ  R9, 352(R12)\n\tMOVOA 48(R12), X0\n\tMOVOA (R12), X1\n\tMOVOA 16(R12), X2\n\tMOVOA 32(R12), X3\n\tMOVOA X1, X4\n\tMOVQ  $0x00000014, CX\n\nMAINLOOP2:\n\tPADDL  X0, X4\n\tMOVOA  X0, X5\n\tMOVOA  X4, X6\n\tPSLLL  $0x07, X4\n\tPSRLL  $0x19, X6\n\tPXOR   X4, X3\n\tPXOR   X6, X3\n\tPADDL  X3, X5\n\tMOVOA  X3, X4\n\tMOVOA  X5, X6\n\tPSLLL  $0x09, X5\n\tPSRLL  $0x17, X6\n\tPXOR   X5, X2\n\tPSHUFL $0x93, X3, X3\n\tPXOR   X6, X2\n\tPADDL  X2, X4\n\tMOVOA  X2, X5\n\tMOVOA  X4, X6\n\tPSLLL  $0x0d, X4\n\tPSRLL  $0x13, X6\n\tPXOR   X4, X1\n\tPSHUFL $0x4e, X2, X2\n\tPXOR   X6, X1\n\tPADDL  X1, X5\n\tMOVOA  X3, X4\n\tMOVOA  X5, X6\n\tPSLLL  $0x12, X5\n\tPSRLL  $0x0e, X6\n\tPXOR   X5, X0\n\tPSHUFL $0x39, X1, X1\n\tPXOR   X6, X0\n\tPADDL  X0, X4\n\tMOVOA  X0, X5\n\tMOVOA  X4, X6\n\tPSLLL  $0x07, X4\n\tPSRLL  $0x19, X6\n\tPXOR   X4, X1\n\tPXOR   X6, X1\n\tPADDL  X1, X5\n\tMOVOA  X1, X4\n\tMOVOA  X5, X6\n\tPSLLL  $0x09, X5\n\tPSRLL  $0x17, X6\n\tPXOR   X5, X2\n\tPSHUFL $0x93, X1, X1\n\tPXOR   X6, X2\n\tPADDL  X2, X4\n\tMOVOA  X2, X5\n\tMOVOA  X4, X6\n\tPSLLL  $0x0d, X4\n\tPSRLL  $0x13, X6\n\tPXOR   X4, X3\n\tPSHUFL $0x4e, X2, X2\n\tPXOR   X6, X3\n\tPADDL  X3, X5\n\tMOVOA  X1, X4\n\tMOVOA  X5, X6\n\tPSLLL  $0x12, X5\n\tPSRLL  $0x0e, X6\n\tPXOR   X5, X0\n\tPSHUFL $0x39, X3, X3\n\tPXOR   X6, X0\n\tPADDL  X0, X4\n\tMOVOA  X0, X5\n\tMOVOA  X4, X6\n\tPSLLL  $0x07, X4\n\tPSRLL  $0x19, X6\n\tPXOR   X4, X3\n\tPXOR   X6, X3\n\tPADDL  X3, X5\n\tMOVOA  X3, X4\n\tMOVOA  X5, X6\n\tPSLLL  $0x09, X5\n\tPSRLL  $0x17, X6\n\tPXOR   X5, X2\n\tPSHUFL $0x93, X3, X3\n\tPXOR   X6, X2\n\tPADDL  X2, X4\n\tMOVOA  X2, X5\n\tMOVOA  X4, X6\n\tPSLLL  $0x0d, X4\n\tPSRLL  $0x13, X6\n\tPXOR   X4, X1\n\tPSHUFL $0x4e, X2, X2\n\tPXOR   X6, X1\n\tPADDL  X1, X5\n\tMOVOA  X3, X4\n\tMOVOA  X5, X6\n\tPSLLL  $0x12, X5\n\tPSRLL  $0x0e, X6\n\tPXOR   X5, X0\n\tPSHUFL $0x39, X1, X1\n\tPXOR   X6, X0\n\tPADDL  X0, X4\n\tMOVOA  X0, X5\n\tMOVOA  X4, X6\n\tPSLLL  $0x07, X4\n\tPSRLL  $0x19, X6\n\tPXOR   X4, X1\n\tPXOR   X6, X1\n\tPADDL  X1, X5\n\tMOVOA  X1, X4\n\tMOVOA  X5, X6\n\tPSLLL  $0x09, X5\n\tPSRLL  $0x17, X6\n\tPXOR   X5, X2\n\tPSHUFL $0x93, X1, X1\n\tPXOR   X6, X2\n\tPADDL  X2, X4\n\tMOVOA  X2, X5\n\tMOVOA  X4, X6\n\tPSLLL  $0x0d, X4\n\tPSRLL  $0x13, X6\n\tPXOR   X4, X3\n\tPSHUFL $0x4e, X2, X2\n\tPXOR   X6, X3\n\tSUBQ   $0x04, CX\n\tPADDL  X3, X5\n\tMOVOA  X1, X4\n\tMOVOA  X5, X6\n\tPSLLL  $0x12, X5\n\tPXOR   X7, X7\n\tPSRLL  $0x0e, X6\n\tPXOR   X5, X0\n\tPSHUFL $0x39, X3, X3\n\tPXOR   X6, X0\n\tJA     MAINLOOP2\n\tPADDL  48(R12), X0\n\tPADDL  (R12), X1\n\tPADDL  16(R12), X2\n\tPADDL  32(R12), X3\n\tMOVD   X0, CX\n\tMOVD   X1, R8\n\tMOVD   X2, R9\n\tMOVD   X3, AX\n\tPSHUFL $0x39, X0, X0\n\tPSHUFL $0x39, X1, X1\n\tPSHUFL $0x39, X2, X2\n\tPSHUFL $0x39, X3, X3\n\tXORL   (SI), CX\n\tXORL   48(SI), R8\n\tXORL   32(SI), R9\n\tXORL   16(SI), AX\n\tMOVL   CX, (DI)\n\tMOVL   R8, 48(DI)\n\tMOVL   R9, 32(DI)\n\tMOVL   AX, 16(DI)\n\tMOVD   X0, CX\n\tMOVD   X1, R8\n\tMOVD   X2, R9\n\tMOVD   X3, AX\n\tPSHUFL $0x39, X0, X0\n\tPSHUFL $0x39, X1, X1\n\tPSHUFL $0x39, X2, X2\n\tPSHUFL $0x39, X3, X3\n\tXORL   20(SI), CX\n\tXORL   4(SI), R8\n\tXORL   52(SI), R9\n\tXORL   36(SI), AX\n\tMOVL   CX, 20(DI)\n\tMOVL   R8, 4(DI)\n\tMOVL   R9, 52(DI)\n\tMOVL   AX, 36(DI)\n\tMOVD   X0, CX\n\tMOVD   X1, R8\n\tMOVD   X2, R9\n\tMOVD   X3, AX\n\tPSHUFL $0x39, X0, X0\n\tPSHUFL $0x39, X1, X1\n\tPSHUFL $0x39, X2, X2\n\tPSHUFL $0x39, X3, X3\n\tXORL   40(SI), CX\n\tXORL   24(SI), R8\n\tXORL   8(SI), R9\n\tXORL   56(SI), AX\n\tMOVL   CX, 40(DI)\n\tMOVL   R8, 24(DI)\n\tMOVL   R9, 8(DI)\n\tMOVL   AX, 56(DI)\n\tMOVD   X0, CX\n\tMOVD   X1, R8\n\tMOVD   X2, R9\n\tMOVD   X3, AX\n\tXORL   60(SI), CX\n\tXORL   44(SI), R8\n\tXORL   28(SI), R9\n\tXORL   12(SI), AX\n\tMOVL   CX, 60(DI)\n\tMOVL   R8, 44(DI)\n\tMOVL   R9, 28(DI)\n\tMOVL   AX, 12(DI)\n\tMOVQ   352(R12), R9\n\tMOVL   16(R12), CX\n\tMOVL   36(R12), R8\n\tADDQ   $0x01, CX\n\tSHLQ   $0x20, R8\n\tADDQ   R8, CX\n\tMOVQ   CX, R8\n\tSHRQ   $0x20, R8\n\tMOVL   CX, 16(R12)\n\tMOVL   R8, 36(R12)\n\tCMPQ   R9, $0x40\n\tJA     BYTESATLEAST65\n\tJAE    BYTESATLEAST64\n\tMOVQ   DI, SI\n\tMOVQ   DX, DI\n\tMOVQ   R9, CX\n\tREP; MOVSB\n\nBYTESATLEAST64:\nDONE:\n\tRET\n\nBYTESATLEAST65:\n\tSUBQ $0x40, R9\n\tADDQ $0x40, DI\n\tADDQ $0x40, SI\n\tJMP  BYTESBETWEEN1AND255\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/salsa20/salsa/salsa20_noasm.go",
    "content": "// Copyright 2019 The Go 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\n//go:build !amd64 || purego || !gc\n\npackage salsa\n\n// XORKeyStream crypts bytes from in to out using the given key and counters.\n// In and out must overlap entirely or not at all. Counter\n// contains the raw salsa20 counter bytes (both nonce and block counter).\nfunc XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {\n\tgenericXORKeyStream(out, in, counter, key)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go",
    "content": "// Copyright 2012 The Go 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 salsa\n\nimport \"math/bits\"\n\nconst rounds = 20\n\n// core applies the Salsa20 core function to 16-byte input in, 32-byte key k,\n// and 16-byte constant c, and puts the result into 64-byte array out.\nfunc core(out *[64]byte, in *[16]byte, k *[32]byte, c *[16]byte) {\n\tj0 := uint32(c[0]) | uint32(c[1])<<8 | uint32(c[2])<<16 | uint32(c[3])<<24\n\tj1 := uint32(k[0]) | uint32(k[1])<<8 | uint32(k[2])<<16 | uint32(k[3])<<24\n\tj2 := uint32(k[4]) | uint32(k[5])<<8 | uint32(k[6])<<16 | uint32(k[7])<<24\n\tj3 := uint32(k[8]) | uint32(k[9])<<8 | uint32(k[10])<<16 | uint32(k[11])<<24\n\tj4 := uint32(k[12]) | uint32(k[13])<<8 | uint32(k[14])<<16 | uint32(k[15])<<24\n\tj5 := uint32(c[4]) | uint32(c[5])<<8 | uint32(c[6])<<16 | uint32(c[7])<<24\n\tj6 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24\n\tj7 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24\n\tj8 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24\n\tj9 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24\n\tj10 := uint32(c[8]) | uint32(c[9])<<8 | uint32(c[10])<<16 | uint32(c[11])<<24\n\tj11 := uint32(k[16]) | uint32(k[17])<<8 | uint32(k[18])<<16 | uint32(k[19])<<24\n\tj12 := uint32(k[20]) | uint32(k[21])<<8 | uint32(k[22])<<16 | uint32(k[23])<<24\n\tj13 := uint32(k[24]) | uint32(k[25])<<8 | uint32(k[26])<<16 | uint32(k[27])<<24\n\tj14 := uint32(k[28]) | uint32(k[29])<<8 | uint32(k[30])<<16 | uint32(k[31])<<24\n\tj15 := uint32(c[12]) | uint32(c[13])<<8 | uint32(c[14])<<16 | uint32(c[15])<<24\n\n\tx0, x1, x2, x3, x4, x5, x6, x7, x8 := j0, j1, j2, j3, j4, j5, j6, j7, j8\n\tx9, x10, x11, x12, x13, x14, x15 := j9, j10, j11, j12, j13, j14, j15\n\n\tfor i := 0; i < rounds; i += 2 {\n\t\tu := x0 + x12\n\t\tx4 ^= bits.RotateLeft32(u, 7)\n\t\tu = x4 + x0\n\t\tx8 ^= bits.RotateLeft32(u, 9)\n\t\tu = x8 + x4\n\t\tx12 ^= bits.RotateLeft32(u, 13)\n\t\tu = x12 + x8\n\t\tx0 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x5 + x1\n\t\tx9 ^= bits.RotateLeft32(u, 7)\n\t\tu = x9 + x5\n\t\tx13 ^= bits.RotateLeft32(u, 9)\n\t\tu = x13 + x9\n\t\tx1 ^= bits.RotateLeft32(u, 13)\n\t\tu = x1 + x13\n\t\tx5 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x10 + x6\n\t\tx14 ^= bits.RotateLeft32(u, 7)\n\t\tu = x14 + x10\n\t\tx2 ^= bits.RotateLeft32(u, 9)\n\t\tu = x2 + x14\n\t\tx6 ^= bits.RotateLeft32(u, 13)\n\t\tu = x6 + x2\n\t\tx10 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x15 + x11\n\t\tx3 ^= bits.RotateLeft32(u, 7)\n\t\tu = x3 + x15\n\t\tx7 ^= bits.RotateLeft32(u, 9)\n\t\tu = x7 + x3\n\t\tx11 ^= bits.RotateLeft32(u, 13)\n\t\tu = x11 + x7\n\t\tx15 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x0 + x3\n\t\tx1 ^= bits.RotateLeft32(u, 7)\n\t\tu = x1 + x0\n\t\tx2 ^= bits.RotateLeft32(u, 9)\n\t\tu = x2 + x1\n\t\tx3 ^= bits.RotateLeft32(u, 13)\n\t\tu = x3 + x2\n\t\tx0 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x5 + x4\n\t\tx6 ^= bits.RotateLeft32(u, 7)\n\t\tu = x6 + x5\n\t\tx7 ^= bits.RotateLeft32(u, 9)\n\t\tu = x7 + x6\n\t\tx4 ^= bits.RotateLeft32(u, 13)\n\t\tu = x4 + x7\n\t\tx5 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x10 + x9\n\t\tx11 ^= bits.RotateLeft32(u, 7)\n\t\tu = x11 + x10\n\t\tx8 ^= bits.RotateLeft32(u, 9)\n\t\tu = x8 + x11\n\t\tx9 ^= bits.RotateLeft32(u, 13)\n\t\tu = x9 + x8\n\t\tx10 ^= bits.RotateLeft32(u, 18)\n\n\t\tu = x15 + x14\n\t\tx12 ^= bits.RotateLeft32(u, 7)\n\t\tu = x12 + x15\n\t\tx13 ^= bits.RotateLeft32(u, 9)\n\t\tu = x13 + x12\n\t\tx14 ^= bits.RotateLeft32(u, 13)\n\t\tu = x14 + x13\n\t\tx15 ^= bits.RotateLeft32(u, 18)\n\t}\n\tx0 += j0\n\tx1 += j1\n\tx2 += j2\n\tx3 += j3\n\tx4 += j4\n\tx5 += j5\n\tx6 += j6\n\tx7 += j7\n\tx8 += j8\n\tx9 += j9\n\tx10 += j10\n\tx11 += j11\n\tx12 += j12\n\tx13 += j13\n\tx14 += j14\n\tx15 += j15\n\n\tout[0] = byte(x0)\n\tout[1] = byte(x0 >> 8)\n\tout[2] = byte(x0 >> 16)\n\tout[3] = byte(x0 >> 24)\n\n\tout[4] = byte(x1)\n\tout[5] = byte(x1 >> 8)\n\tout[6] = byte(x1 >> 16)\n\tout[7] = byte(x1 >> 24)\n\n\tout[8] = byte(x2)\n\tout[9] = byte(x2 >> 8)\n\tout[10] = byte(x2 >> 16)\n\tout[11] = byte(x2 >> 24)\n\n\tout[12] = byte(x3)\n\tout[13] = byte(x3 >> 8)\n\tout[14] = byte(x3 >> 16)\n\tout[15] = byte(x3 >> 24)\n\n\tout[16] = byte(x4)\n\tout[17] = byte(x4 >> 8)\n\tout[18] = byte(x4 >> 16)\n\tout[19] = byte(x4 >> 24)\n\n\tout[20] = byte(x5)\n\tout[21] = byte(x5 >> 8)\n\tout[22] = byte(x5 >> 16)\n\tout[23] = byte(x5 >> 24)\n\n\tout[24] = byte(x6)\n\tout[25] = byte(x6 >> 8)\n\tout[26] = byte(x6 >> 16)\n\tout[27] = byte(x6 >> 24)\n\n\tout[28] = byte(x7)\n\tout[29] = byte(x7 >> 8)\n\tout[30] = byte(x7 >> 16)\n\tout[31] = byte(x7 >> 24)\n\n\tout[32] = byte(x8)\n\tout[33] = byte(x8 >> 8)\n\tout[34] = byte(x8 >> 16)\n\tout[35] = byte(x8 >> 24)\n\n\tout[36] = byte(x9)\n\tout[37] = byte(x9 >> 8)\n\tout[38] = byte(x9 >> 16)\n\tout[39] = byte(x9 >> 24)\n\n\tout[40] = byte(x10)\n\tout[41] = byte(x10 >> 8)\n\tout[42] = byte(x10 >> 16)\n\tout[43] = byte(x10 >> 24)\n\n\tout[44] = byte(x11)\n\tout[45] = byte(x11 >> 8)\n\tout[46] = byte(x11 >> 16)\n\tout[47] = byte(x11 >> 24)\n\n\tout[48] = byte(x12)\n\tout[49] = byte(x12 >> 8)\n\tout[50] = byte(x12 >> 16)\n\tout[51] = byte(x12 >> 24)\n\n\tout[52] = byte(x13)\n\tout[53] = byte(x13 >> 8)\n\tout[54] = byte(x13 >> 16)\n\tout[55] = byte(x13 >> 24)\n\n\tout[56] = byte(x14)\n\tout[57] = byte(x14 >> 8)\n\tout[58] = byte(x14 >> 16)\n\tout[59] = byte(x14 >> 24)\n\n\tout[60] = byte(x15)\n\tout[61] = byte(x15 >> 8)\n\tout[62] = byte(x15 >> 16)\n\tout[63] = byte(x15 >> 24)\n}\n\n// genericXORKeyStream is the generic implementation of XORKeyStream to be used\n// when no assembly implementation is available.\nfunc genericXORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {\n\tvar block [64]byte\n\tvar counterCopy [16]byte\n\tcopy(counterCopy[:], counter[:])\n\n\tfor len(in) >= 64 {\n\t\tcore(&block, &counterCopy, key, &Sigma)\n\t\tfor i, x := range block {\n\t\t\tout[i] = in[i] ^ x\n\t\t}\n\t\tu := uint32(1)\n\t\tfor i := 8; i < 16; i++ {\n\t\t\tu += uint32(counterCopy[i])\n\t\t\tcounterCopy[i] = byte(u)\n\t\t\tu >>= 8\n\t\t}\n\t\tin = in[64:]\n\t\tout = out[64:]\n\t}\n\n\tif len(in) > 0 {\n\t\tcore(&block, &counterCopy, key, &Sigma)\n\t\tfor i, v := range in {\n\t\t\tout[i] = v ^ block[i]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/buffer.go",
    "content": "// Copyright 2012 The Go 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 ssh\n\nimport (\n\t\"io\"\n\t\"sync\"\n)\n\n// buffer provides a linked list buffer for data exchange\n// between producer and consumer. Theoretically the buffer is\n// of unlimited capacity as it does no allocation of its own.\ntype buffer struct {\n\t// protects concurrent access to head, tail and closed\n\t*sync.Cond\n\n\thead *element // the buffer that will be read first\n\ttail *element // the buffer that will be read last\n\n\tclosed bool\n}\n\n// An element represents a single link in a linked list.\ntype element struct {\n\tbuf  []byte\n\tnext *element\n}\n\n// newBuffer returns an empty buffer that is not closed.\nfunc newBuffer() *buffer {\n\te := new(element)\n\tb := &buffer{\n\t\tCond: newCond(),\n\t\thead: e,\n\t\ttail: e,\n\t}\n\treturn b\n}\n\n// write makes buf available for Read to receive.\n// buf must not be modified after the call to write.\nfunc (b *buffer) write(buf []byte) {\n\tb.Cond.L.Lock()\n\te := &element{buf: buf}\n\tb.tail.next = e\n\tb.tail = e\n\tb.Cond.Signal()\n\tb.Cond.L.Unlock()\n}\n\n// eof closes the buffer. Reads from the buffer once all\n// the data has been consumed will receive io.EOF.\nfunc (b *buffer) eof() {\n\tb.Cond.L.Lock()\n\tb.closed = true\n\tb.Cond.Signal()\n\tb.Cond.L.Unlock()\n}\n\n// Read reads data from the internal buffer in buf.  Reads will block\n// if no data is available, or until the buffer is closed.\nfunc (b *buffer) Read(buf []byte) (n int, err error) {\n\tb.Cond.L.Lock()\n\tdefer b.Cond.L.Unlock()\n\n\tfor len(buf) > 0 {\n\t\t// if there is data in b.head, copy it\n\t\tif len(b.head.buf) > 0 {\n\t\t\tr := copy(buf, b.head.buf)\n\t\t\tbuf, b.head.buf = buf[r:], b.head.buf[r:]\n\t\t\tn += r\n\t\t\tcontinue\n\t\t}\n\t\t// if there is a next buffer, make it the head\n\t\tif len(b.head.buf) == 0 && b.head != b.tail {\n\t\t\tb.head = b.head.next\n\t\t\tcontinue\n\t\t}\n\n\t\t// if at least one byte has been copied, return\n\t\tif n > 0 {\n\t\t\tbreak\n\t\t}\n\n\t\t// if nothing was read, and there is nothing outstanding\n\t\t// check to see if the buffer is closed.\n\t\tif b.closed {\n\t\t\terr = io.EOF\n\t\t\tbreak\n\t\t}\n\t\t// out of buffers, wait for producer\n\t\tb.Cond.Wait()\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/certs.go",
    "content": "// Copyright 2012 The Go 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 ssh\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"sort\"\n\t\"time\"\n)\n\n// Certificate algorithm names from [PROTOCOL.certkeys]. These values can appear\n// in Certificate.Type, PublicKey.Type, and ClientConfig.HostKeyAlgorithms.\n// Unlike key algorithm names, these are not passed to AlgorithmSigner nor\n// returned by MultiAlgorithmSigner and don't appear in the Signature.Format\n// field.\nconst (\n\tCertAlgoRSAv01        = \"ssh-rsa-cert-v01@openssh.com\"\n\tCertAlgoDSAv01        = \"ssh-dss-cert-v01@openssh.com\"\n\tCertAlgoECDSA256v01   = \"ecdsa-sha2-nistp256-cert-v01@openssh.com\"\n\tCertAlgoECDSA384v01   = \"ecdsa-sha2-nistp384-cert-v01@openssh.com\"\n\tCertAlgoECDSA521v01   = \"ecdsa-sha2-nistp521-cert-v01@openssh.com\"\n\tCertAlgoSKECDSA256v01 = \"sk-ecdsa-sha2-nistp256-cert-v01@openssh.com\"\n\tCertAlgoED25519v01    = \"ssh-ed25519-cert-v01@openssh.com\"\n\tCertAlgoSKED25519v01  = \"sk-ssh-ed25519-cert-v01@openssh.com\"\n\n\t// CertAlgoRSASHA256v01 and CertAlgoRSASHA512v01 can't appear as a\n\t// Certificate.Type (or PublicKey.Type), but only in\n\t// ClientConfig.HostKeyAlgorithms.\n\tCertAlgoRSASHA256v01 = \"rsa-sha2-256-cert-v01@openssh.com\"\n\tCertAlgoRSASHA512v01 = \"rsa-sha2-512-cert-v01@openssh.com\"\n)\n\nconst (\n\t// Deprecated: use CertAlgoRSAv01.\n\tCertSigAlgoRSAv01 = CertAlgoRSAv01\n\t// Deprecated: use CertAlgoRSASHA256v01.\n\tCertSigAlgoRSASHA2256v01 = CertAlgoRSASHA256v01\n\t// Deprecated: use CertAlgoRSASHA512v01.\n\tCertSigAlgoRSASHA2512v01 = CertAlgoRSASHA512v01\n)\n\n// Certificate types distinguish between host and user\n// certificates. The values can be set in the CertType field of\n// Certificate.\nconst (\n\tUserCert = 1\n\tHostCert = 2\n)\n\n// Signature represents a cryptographic signature.\ntype Signature struct {\n\tFormat string\n\tBlob   []byte\n\tRest   []byte `ssh:\"rest\"`\n}\n\n// CertTimeInfinity can be used for OpenSSHCertV01.ValidBefore to indicate that\n// a certificate does not expire.\nconst CertTimeInfinity = 1<<64 - 1\n\n// An Certificate represents an OpenSSH certificate as defined in\n// [PROTOCOL.certkeys]?rev=1.8. The Certificate type implements the\n// PublicKey interface, so it can be unmarshaled using\n// ParsePublicKey.\ntype Certificate struct {\n\tNonce           []byte\n\tKey             PublicKey\n\tSerial          uint64\n\tCertType        uint32\n\tKeyId           string\n\tValidPrincipals []string\n\tValidAfter      uint64\n\tValidBefore     uint64\n\tPermissions\n\tReserved     []byte\n\tSignatureKey PublicKey\n\tSignature    *Signature\n}\n\n// genericCertData holds the key-independent part of the certificate data.\n// Overall, certificates contain an nonce, public key fields and\n// key-independent fields.\ntype genericCertData struct {\n\tSerial          uint64\n\tCertType        uint32\n\tKeyId           string\n\tValidPrincipals []byte\n\tValidAfter      uint64\n\tValidBefore     uint64\n\tCriticalOptions []byte\n\tExtensions      []byte\n\tReserved        []byte\n\tSignatureKey    []byte\n\tSignature       []byte\n}\n\nfunc marshalStringList(namelist []string) []byte {\n\tvar to []byte\n\tfor _, name := range namelist {\n\t\ts := struct{ N string }{name}\n\t\tto = append(to, Marshal(&s)...)\n\t}\n\treturn to\n}\n\ntype optionsTuple struct {\n\tKey   string\n\tValue []byte\n}\n\ntype optionsTupleValue struct {\n\tValue string\n}\n\n// serialize a map of critical options or extensions\n// issue #10569 - per [PROTOCOL.certkeys] and SSH implementation,\n// we need two length prefixes for a non-empty string value\nfunc marshalTuples(tups map[string]string) []byte {\n\tkeys := make([]string, 0, len(tups))\n\tfor key := range tups {\n\t\tkeys = append(keys, key)\n\t}\n\tsort.Strings(keys)\n\n\tvar ret []byte\n\tfor _, key := range keys {\n\t\ts := optionsTuple{Key: key}\n\t\tif value := tups[key]; len(value) > 0 {\n\t\t\ts.Value = Marshal(&optionsTupleValue{value})\n\t\t}\n\t\tret = append(ret, Marshal(&s)...)\n\t}\n\treturn ret\n}\n\n// issue #10569 - per [PROTOCOL.certkeys] and SSH implementation,\n// we need two length prefixes for a non-empty option value\nfunc parseTuples(in []byte) (map[string]string, error) {\n\ttups := map[string]string{}\n\tvar lastKey string\n\tvar haveLastKey bool\n\n\tfor len(in) > 0 {\n\t\tvar key, val, extra []byte\n\t\tvar ok bool\n\n\t\tif key, in, ok = parseString(in); !ok {\n\t\t\treturn nil, errShortRead\n\t\t}\n\t\tkeyStr := string(key)\n\t\t// according to [PROTOCOL.certkeys], the names must be in\n\t\t// lexical order.\n\t\tif haveLastKey && keyStr <= lastKey {\n\t\t\treturn nil, fmt.Errorf(\"ssh: certificate options are not in lexical order\")\n\t\t}\n\t\tlastKey, haveLastKey = keyStr, true\n\t\t// the next field is a data field, which if non-empty has a string embedded\n\t\tif val, in, ok = parseString(in); !ok {\n\t\t\treturn nil, errShortRead\n\t\t}\n\t\tif len(val) > 0 {\n\t\t\tval, extra, ok = parseString(val)\n\t\t\tif !ok {\n\t\t\t\treturn nil, errShortRead\n\t\t\t}\n\t\t\tif len(extra) > 0 {\n\t\t\t\treturn nil, fmt.Errorf(\"ssh: unexpected trailing data after certificate option value\")\n\t\t\t}\n\t\t\ttups[keyStr] = string(val)\n\t\t} else {\n\t\t\ttups[keyStr] = \"\"\n\t\t}\n\t}\n\treturn tups, nil\n}\n\nfunc parseCert(in []byte, privAlgo string) (*Certificate, error) {\n\tnonce, rest, ok := parseString(in)\n\tif !ok {\n\t\treturn nil, errShortRead\n\t}\n\n\tkey, rest, err := parsePubKey(rest, privAlgo)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar g genericCertData\n\tif err := Unmarshal(rest, &g); err != nil {\n\t\treturn nil, err\n\t}\n\n\tc := &Certificate{\n\t\tNonce:       nonce,\n\t\tKey:         key,\n\t\tSerial:      g.Serial,\n\t\tCertType:    g.CertType,\n\t\tKeyId:       g.KeyId,\n\t\tValidAfter:  g.ValidAfter,\n\t\tValidBefore: g.ValidBefore,\n\t}\n\n\tfor principals := g.ValidPrincipals; len(principals) > 0; {\n\t\tprincipal, rest, ok := parseString(principals)\n\t\tif !ok {\n\t\t\treturn nil, errShortRead\n\t\t}\n\t\tc.ValidPrincipals = append(c.ValidPrincipals, string(principal))\n\t\tprincipals = rest\n\t}\n\n\tc.CriticalOptions, err = parseTuples(g.CriticalOptions)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tc.Extensions, err = parseTuples(g.Extensions)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tc.Reserved = g.Reserved\n\tk, err := ParsePublicKey(g.SignatureKey)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tc.SignatureKey = k\n\tc.Signature, rest, ok = parseSignatureBody(g.Signature)\n\tif !ok || len(rest) > 0 {\n\t\treturn nil, errors.New(\"ssh: signature parse error\")\n\t}\n\n\treturn c, nil\n}\n\ntype openSSHCertSigner struct {\n\tpub    *Certificate\n\tsigner Signer\n}\n\ntype algorithmOpenSSHCertSigner struct {\n\t*openSSHCertSigner\n\talgorithmSigner AlgorithmSigner\n}\n\n// NewCertSigner returns a Signer that signs with the given Certificate, whose\n// private key is held by signer. It returns an error if the public key in cert\n// doesn't match the key used by signer.\nfunc NewCertSigner(cert *Certificate, signer Signer) (Signer, error) {\n\tif !bytes.Equal(cert.Key.Marshal(), signer.PublicKey().Marshal()) {\n\t\treturn nil, errors.New(\"ssh: signer and cert have different public key\")\n\t}\n\n\tswitch s := signer.(type) {\n\tcase MultiAlgorithmSigner:\n\t\treturn &multiAlgorithmSigner{\n\t\t\tAlgorithmSigner: &algorithmOpenSSHCertSigner{\n\t\t\t\t&openSSHCertSigner{cert, signer}, s},\n\t\t\tsupportedAlgorithms: s.Algorithms(),\n\t\t}, nil\n\tcase AlgorithmSigner:\n\t\treturn &algorithmOpenSSHCertSigner{\n\t\t\t&openSSHCertSigner{cert, signer}, s}, nil\n\tdefault:\n\t\treturn &openSSHCertSigner{cert, signer}, nil\n\t}\n}\n\nfunc (s *openSSHCertSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {\n\treturn s.signer.Sign(rand, data)\n}\n\nfunc (s *openSSHCertSigner) PublicKey() PublicKey {\n\treturn s.pub\n}\n\nfunc (s *algorithmOpenSSHCertSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {\n\treturn s.algorithmSigner.SignWithAlgorithm(rand, data, algorithm)\n}\n\nconst sourceAddressCriticalOption = \"source-address\"\n\n// CertChecker does the work of verifying a certificate. Its methods\n// can be plugged into ClientConfig.HostKeyCallback and\n// ServerConfig.PublicKeyCallback. For the CertChecker to work,\n// minimally, the IsAuthority callback should be set.\ntype CertChecker struct {\n\t// SupportedCriticalOptions lists the CriticalOptions that the\n\t// server application layer understands. These are only used\n\t// for user certificates.\n\tSupportedCriticalOptions []string\n\n\t// IsUserAuthority should return true if the key is recognized as an\n\t// authority for the given user certificate. This allows for\n\t// certificates to be signed by other certificates. This must be set\n\t// if this CertChecker will be checking user certificates.\n\tIsUserAuthority func(auth PublicKey) bool\n\n\t// IsHostAuthority should report whether the key is recognized as\n\t// an authority for this host. This allows for certificates to be\n\t// signed by other keys, and for those other keys to only be valid\n\t// signers for particular hostnames. This must be set if this\n\t// CertChecker will be checking host certificates.\n\tIsHostAuthority func(auth PublicKey, address string) bool\n\n\t// Clock is used for verifying time stamps. If nil, time.Now\n\t// is used.\n\tClock func() time.Time\n\n\t// UserKeyFallback is called when CertChecker.Authenticate encounters a\n\t// public key that is not a certificate. It must implement validation\n\t// of user keys or else, if nil, all such keys are rejected.\n\tUserKeyFallback func(conn ConnMetadata, key PublicKey) (*Permissions, error)\n\n\t// HostKeyFallback is called when CertChecker.CheckHostKey encounters a\n\t// public key that is not a certificate. It must implement host key\n\t// validation or else, if nil, all such keys are rejected.\n\tHostKeyFallback HostKeyCallback\n\n\t// IsRevoked is called for each certificate so that revocation checking\n\t// can be implemented. It should return true if the given certificate\n\t// is revoked and false otherwise. If nil, no certificates are\n\t// considered to have been revoked.\n\tIsRevoked func(cert *Certificate) bool\n}\n\n// CheckHostKey checks a host key certificate. This method can be\n// plugged into ClientConfig.HostKeyCallback.\nfunc (c *CertChecker) CheckHostKey(addr string, remote net.Addr, key PublicKey) error {\n\tcert, ok := key.(*Certificate)\n\tif !ok {\n\t\tif c.HostKeyFallback != nil {\n\t\t\treturn c.HostKeyFallback(addr, remote, key)\n\t\t}\n\t\treturn errors.New(\"ssh: non-certificate host key\")\n\t}\n\tif cert.CertType != HostCert {\n\t\treturn fmt.Errorf(\"ssh: certificate presented as a host key has type %d\", cert.CertType)\n\t}\n\tif !c.IsHostAuthority(cert.SignatureKey, addr) {\n\t\treturn fmt.Errorf(\"ssh: no authorities for hostname: %v\", addr)\n\t}\n\n\thostname, _, err := net.SplitHostPort(addr)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Pass hostname only as principal for host certificates (consistent with OpenSSH)\n\treturn c.CheckCert(hostname, cert)\n}\n\n// Authenticate checks a user certificate. Authenticate can be used as\n// a value for ServerConfig.PublicKeyCallback.\nfunc (c *CertChecker) Authenticate(conn ConnMetadata, pubKey PublicKey) (*Permissions, error) {\n\tcert, ok := pubKey.(*Certificate)\n\tif !ok {\n\t\tif c.UserKeyFallback != nil {\n\t\t\treturn c.UserKeyFallback(conn, pubKey)\n\t\t}\n\t\treturn nil, errors.New(\"ssh: normal key pairs not accepted\")\n\t}\n\n\tif cert.CertType != UserCert {\n\t\treturn nil, fmt.Errorf(\"ssh: cert has type %d\", cert.CertType)\n\t}\n\tif !c.IsUserAuthority(cert.SignatureKey) {\n\t\treturn nil, fmt.Errorf(\"ssh: certificate signed by unrecognized authority\")\n\t}\n\n\tif err := c.CheckCert(conn.User(), cert); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &cert.Permissions, nil\n}\n\n// CheckCert checks CriticalOptions, ValidPrincipals, revocation, timestamp and\n// the signature of the certificate.\nfunc (c *CertChecker) CheckCert(principal string, cert *Certificate) error {\n\tif c.IsRevoked != nil && c.IsRevoked(cert) {\n\t\treturn fmt.Errorf(\"ssh: certificate serial %d revoked\", cert.Serial)\n\t}\n\n\tfor opt := range cert.CriticalOptions {\n\t\t// sourceAddressCriticalOption will be enforced by\n\t\t// serverAuthenticate\n\t\tif opt == sourceAddressCriticalOption {\n\t\t\tcontinue\n\t\t}\n\n\t\tfound := false\n\t\tfor _, supp := range c.SupportedCriticalOptions {\n\t\t\tif supp == opt {\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\treturn fmt.Errorf(\"ssh: unsupported critical option %q in certificate\", opt)\n\t\t}\n\t}\n\n\tif len(cert.ValidPrincipals) > 0 {\n\t\t// By default, certs are valid for all users/hosts.\n\t\tfound := false\n\t\tfor _, p := range cert.ValidPrincipals {\n\t\t\tif p == principal {\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\treturn fmt.Errorf(\"ssh: principal %q not in the set of valid principals for given certificate: %q\", principal, cert.ValidPrincipals)\n\t\t}\n\t}\n\n\tclock := c.Clock\n\tif clock == nil {\n\t\tclock = time.Now\n\t}\n\n\tunixNow := clock().Unix()\n\tif after := int64(cert.ValidAfter); after < 0 || unixNow < int64(cert.ValidAfter) {\n\t\treturn fmt.Errorf(\"ssh: cert is not yet valid\")\n\t}\n\tif before := int64(cert.ValidBefore); cert.ValidBefore != uint64(CertTimeInfinity) && (unixNow >= before || before < 0) {\n\t\treturn fmt.Errorf(\"ssh: cert has expired\")\n\t}\n\tif err := cert.SignatureKey.Verify(cert.bytesForSigning(), cert.Signature); err != nil {\n\t\treturn fmt.Errorf(\"ssh: certificate signature does not verify\")\n\t}\n\n\treturn nil\n}\n\n// SignCert signs the certificate with an authority, setting the Nonce,\n// SignatureKey, and Signature fields. If the authority implements the\n// MultiAlgorithmSigner interface the first algorithm in the list is used. This\n// is useful if you want to sign with a specific algorithm.\nfunc (c *Certificate) SignCert(rand io.Reader, authority Signer) error {\n\tc.Nonce = make([]byte, 32)\n\tif _, err := io.ReadFull(rand, c.Nonce); err != nil {\n\t\treturn err\n\t}\n\tc.SignatureKey = authority.PublicKey()\n\n\tif v, ok := authority.(MultiAlgorithmSigner); ok {\n\t\tif len(v.Algorithms()) == 0 {\n\t\t\treturn errors.New(\"the provided authority has no signature algorithm\")\n\t\t}\n\t\t// Use the first algorithm in the list.\n\t\tsig, err := v.SignWithAlgorithm(rand, c.bytesForSigning(), v.Algorithms()[0])\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tc.Signature = sig\n\t\treturn nil\n\t} else if v, ok := authority.(AlgorithmSigner); ok && v.PublicKey().Type() == KeyAlgoRSA {\n\t\t// Default to KeyAlgoRSASHA512 for ssh-rsa signers.\n\t\t// TODO: consider using KeyAlgoRSASHA256 as default.\n\t\tsig, err := v.SignWithAlgorithm(rand, c.bytesForSigning(), KeyAlgoRSASHA512)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tc.Signature = sig\n\t\treturn nil\n\t}\n\n\tsig, err := authority.Sign(rand, c.bytesForSigning())\n\tif err != nil {\n\t\treturn err\n\t}\n\tc.Signature = sig\n\treturn nil\n}\n\n// certKeyAlgoNames is a mapping from known certificate algorithm names to the\n// corresponding public key signature algorithm.\n//\n// This map must be kept in sync with the one in agent/client.go.\nvar certKeyAlgoNames = map[string]string{\n\tCertAlgoRSAv01:        KeyAlgoRSA,\n\tCertAlgoRSASHA256v01:  KeyAlgoRSASHA256,\n\tCertAlgoRSASHA512v01:  KeyAlgoRSASHA512,\n\tCertAlgoDSAv01:        KeyAlgoDSA,\n\tCertAlgoECDSA256v01:   KeyAlgoECDSA256,\n\tCertAlgoECDSA384v01:   KeyAlgoECDSA384,\n\tCertAlgoECDSA521v01:   KeyAlgoECDSA521,\n\tCertAlgoSKECDSA256v01: KeyAlgoSKECDSA256,\n\tCertAlgoED25519v01:    KeyAlgoED25519,\n\tCertAlgoSKED25519v01:  KeyAlgoSKED25519,\n}\n\n// underlyingAlgo returns the signature algorithm associated with algo (which is\n// an advertised or negotiated public key or host key algorithm). These are\n// usually the same, except for certificate algorithms.\nfunc underlyingAlgo(algo string) string {\n\tif a, ok := certKeyAlgoNames[algo]; ok {\n\t\treturn a\n\t}\n\treturn algo\n}\n\n// certificateAlgo returns the certificate algorithms that uses the provided\n// underlying signature algorithm.\nfunc certificateAlgo(algo string) (certAlgo string, ok bool) {\n\tfor certName, algoName := range certKeyAlgoNames {\n\t\tif algoName == algo {\n\t\t\treturn certName, true\n\t\t}\n\t}\n\treturn \"\", false\n}\n\nfunc (cert *Certificate) bytesForSigning() []byte {\n\tc2 := *cert\n\tc2.Signature = nil\n\tout := c2.Marshal()\n\t// Drop trailing signature length.\n\treturn out[:len(out)-4]\n}\n\n// Marshal serializes c into OpenSSH's wire format. It is part of the\n// PublicKey interface.\nfunc (c *Certificate) Marshal() []byte {\n\tgeneric := genericCertData{\n\t\tSerial:          c.Serial,\n\t\tCertType:        c.CertType,\n\t\tKeyId:           c.KeyId,\n\t\tValidPrincipals: marshalStringList(c.ValidPrincipals),\n\t\tValidAfter:      uint64(c.ValidAfter),\n\t\tValidBefore:     uint64(c.ValidBefore),\n\t\tCriticalOptions: marshalTuples(c.CriticalOptions),\n\t\tExtensions:      marshalTuples(c.Extensions),\n\t\tReserved:        c.Reserved,\n\t\tSignatureKey:    c.SignatureKey.Marshal(),\n\t}\n\tif c.Signature != nil {\n\t\tgeneric.Signature = Marshal(c.Signature)\n\t}\n\tgenericBytes := Marshal(&generic)\n\tkeyBytes := c.Key.Marshal()\n\t_, keyBytes, _ = parseString(keyBytes)\n\tprefix := Marshal(&struct {\n\t\tName  string\n\t\tNonce []byte\n\t\tKey   []byte `ssh:\"rest\"`\n\t}{c.Type(), c.Nonce, keyBytes})\n\n\tresult := make([]byte, 0, len(prefix)+len(genericBytes))\n\tresult = append(result, prefix...)\n\tresult = append(result, genericBytes...)\n\treturn result\n}\n\n// Type returns the certificate algorithm name. It is part of the PublicKey interface.\nfunc (c *Certificate) Type() string {\n\tcertName, ok := certificateAlgo(c.Key.Type())\n\tif !ok {\n\t\tpanic(\"unknown certificate type for key type \" + c.Key.Type())\n\t}\n\treturn certName\n}\n\n// Verify verifies a signature against the certificate's public\n// key. It is part of the PublicKey interface.\nfunc (c *Certificate) Verify(data []byte, sig *Signature) error {\n\treturn c.Key.Verify(data, sig)\n}\n\nfunc parseSignatureBody(in []byte) (out *Signature, rest []byte, ok bool) {\n\tformat, in, ok := parseString(in)\n\tif !ok {\n\t\treturn\n\t}\n\n\tout = &Signature{\n\t\tFormat: string(format),\n\t}\n\n\tif out.Blob, in, ok = parseString(in); !ok {\n\t\treturn\n\t}\n\n\tswitch out.Format {\n\tcase KeyAlgoSKECDSA256, CertAlgoSKECDSA256v01, KeyAlgoSKED25519, CertAlgoSKED25519v01:\n\t\tout.Rest = in\n\t\treturn out, nil, ok\n\t}\n\n\treturn out, in, ok\n}\n\nfunc parseSignature(in []byte) (out *Signature, rest []byte, ok bool) {\n\tsigBytes, rest, ok := parseString(in)\n\tif !ok {\n\t\treturn\n\t}\n\n\tout, trailing, ok := parseSignatureBody(sigBytes)\n\tif !ok || len(trailing) > 0 {\n\t\treturn nil, nil, false\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/channel.go",
    "content": "// Copyright 2011 The Go 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 ssh\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"sync\"\n)\n\nconst (\n\tminPacketLength = 9\n\t// channelMaxPacket contains the maximum number of bytes that will be\n\t// sent in a single packet. As per RFC 4253, section 6.1, 32k is also\n\t// the minimum.\n\tchannelMaxPacket = 1 << 15\n\t// We follow OpenSSH here.\n\tchannelWindowSize = 64 * channelMaxPacket\n)\n\n// NewChannel represents an incoming request to a channel. It must either be\n// accepted for use by calling Accept, or rejected by calling Reject.\ntype NewChannel interface {\n\t// Accept accepts the channel creation request. It returns the Channel\n\t// and a Go channel containing SSH requests. The Go channel must be\n\t// serviced otherwise the Channel will hang.\n\tAccept() (Channel, <-chan *Request, error)\n\n\t// Reject rejects the channel creation request. After calling\n\t// this, no other methods on the Channel may be called.\n\tReject(reason RejectionReason, message string) error\n\n\t// ChannelType returns the type of the channel, as supplied by the\n\t// client.\n\tChannelType() string\n\n\t// ExtraData returns the arbitrary payload for this channel, as supplied\n\t// by the client. This data is specific to the channel type.\n\tExtraData() []byte\n}\n\n// A Channel is an ordered, reliable, flow-controlled, duplex stream\n// that is multiplexed over an SSH connection.\ntype Channel interface {\n\t// Read reads up to len(data) bytes from the channel.\n\tRead(data []byte) (int, error)\n\n\t// Write writes len(data) bytes to the channel.\n\tWrite(data []byte) (int, error)\n\n\t// Close signals end of channel use. No data may be sent after this\n\t// call.\n\tClose() error\n\n\t// CloseWrite signals the end of sending in-band\n\t// data. Requests may still be sent, and the other side may\n\t// still send data\n\tCloseWrite() error\n\n\t// SendRequest sends a channel request.  If wantReply is true,\n\t// it will wait for a reply and return the result as a\n\t// boolean, otherwise the return value will be false. Channel\n\t// requests are out-of-band messages so they may be sent even\n\t// if the data stream is closed or blocked by flow control.\n\t// If the channel is closed before a reply is returned, io.EOF\n\t// is returned.\n\tSendRequest(name string, wantReply bool, payload []byte) (bool, error)\n\n\t// Stderr returns an io.ReadWriter that writes to this channel\n\t// with the extended data type set to stderr. Stderr may\n\t// safely be read and written from a different goroutine than\n\t// Read and Write respectively.\n\tStderr() io.ReadWriter\n}\n\n// Request is a request sent outside of the normal stream of\n// data. Requests can either be specific to an SSH channel, or they\n// can be global.\ntype Request struct {\n\tType      string\n\tWantReply bool\n\tPayload   []byte\n\n\tch  *channel\n\tmux *mux\n}\n\n// Reply sends a response to a request. It must be called for all requests\n// where WantReply is true and is a no-op otherwise. The payload argument is\n// ignored for replies to channel-specific requests.\nfunc (r *Request) Reply(ok bool, payload []byte) error {\n\tif !r.WantReply {\n\t\treturn nil\n\t}\n\n\tif r.ch == nil {\n\t\treturn r.mux.ackRequest(ok, payload)\n\t}\n\n\treturn r.ch.ackRequest(ok)\n}\n\n// RejectionReason is an enumeration used when rejecting channel creation\n// requests. See RFC 4254, section 5.1.\ntype RejectionReason uint32\n\nconst (\n\tProhibited RejectionReason = iota + 1\n\tConnectionFailed\n\tUnknownChannelType\n\tResourceShortage\n)\n\n// String converts the rejection reason to human readable form.\nfunc (r RejectionReason) String() string {\n\tswitch r {\n\tcase Prohibited:\n\t\treturn \"administratively prohibited\"\n\tcase ConnectionFailed:\n\t\treturn \"connect failed\"\n\tcase UnknownChannelType:\n\t\treturn \"unknown channel type\"\n\tcase ResourceShortage:\n\t\treturn \"resource shortage\"\n\t}\n\treturn fmt.Sprintf(\"unknown reason %d\", int(r))\n}\n\nfunc min(a uint32, b int) uint32 {\n\tif a < uint32(b) {\n\t\treturn a\n\t}\n\treturn uint32(b)\n}\n\ntype channelDirection uint8\n\nconst (\n\tchannelInbound channelDirection = iota\n\tchannelOutbound\n)\n\n// channel is an implementation of the Channel interface that works\n// with the mux class.\ntype channel struct {\n\t// R/O after creation\n\tchanType          string\n\textraData         []byte\n\tlocalId, remoteId uint32\n\n\t// maxIncomingPayload and maxRemotePayload are the maximum\n\t// payload sizes of normal and extended data packets for\n\t// receiving and sending, respectively. The wire packet will\n\t// be 9 or 13 bytes larger (excluding encryption overhead).\n\tmaxIncomingPayload uint32\n\tmaxRemotePayload   uint32\n\n\tmux *mux\n\n\t// decided is set to true if an accept or reject message has been sent\n\t// (for outbound channels) or received (for inbound channels).\n\tdecided bool\n\n\t// direction contains either channelOutbound, for channels created\n\t// locally, or channelInbound, for channels created by the peer.\n\tdirection channelDirection\n\n\t// Pending internal channel messages.\n\tmsg chan interface{}\n\n\t// Since requests have no ID, there can be only one request\n\t// with WantReply=true outstanding.  This lock is held by a\n\t// goroutine that has such an outgoing request pending.\n\tsentRequestMu sync.Mutex\n\n\tincomingRequests chan *Request\n\n\tsentEOF bool\n\n\t// thread-safe data\n\tremoteWin  window\n\tpending    *buffer\n\textPending *buffer\n\n\t// windowMu protects myWindow, the flow-control window, and myConsumed,\n\t// the number of bytes consumed since we last increased myWindow\n\twindowMu   sync.Mutex\n\tmyWindow   uint32\n\tmyConsumed uint32\n\n\t// writeMu serializes calls to mux.conn.writePacket() and\n\t// protects sentClose and packetPool. This mutex must be\n\t// different from windowMu, as writePacket can block if there\n\t// is a key exchange pending.\n\twriteMu   sync.Mutex\n\tsentClose bool\n\n\t// packetPool has a buffer for each extended channel ID to\n\t// save allocations during writes.\n\tpacketPool map[uint32][]byte\n}\n\n// writePacket sends a packet. If the packet is a channel close, it updates\n// sentClose. This method takes the lock c.writeMu.\nfunc (ch *channel) writePacket(packet []byte) error {\n\tch.writeMu.Lock()\n\tif ch.sentClose {\n\t\tch.writeMu.Unlock()\n\t\treturn io.EOF\n\t}\n\tch.sentClose = (packet[0] == msgChannelClose)\n\terr := ch.mux.conn.writePacket(packet)\n\tch.writeMu.Unlock()\n\treturn err\n}\n\nfunc (ch *channel) sendMessage(msg interface{}) error {\n\tif debugMux {\n\t\tlog.Printf(\"send(%d): %#v\", ch.mux.chanList.offset, msg)\n\t}\n\n\tp := Marshal(msg)\n\tbinary.BigEndian.PutUint32(p[1:], ch.remoteId)\n\treturn ch.writePacket(p)\n}\n\n// WriteExtended writes data to a specific extended stream. These streams are\n// used, for example, for stderr.\nfunc (ch *channel) WriteExtended(data []byte, extendedCode uint32) (n int, err error) {\n\tif ch.sentEOF {\n\t\treturn 0, io.EOF\n\t}\n\t// 1 byte message type, 4 bytes remoteId, 4 bytes data length\n\topCode := byte(msgChannelData)\n\theaderLength := uint32(9)\n\tif extendedCode > 0 {\n\t\theaderLength += 4\n\t\topCode = msgChannelExtendedData\n\t}\n\n\tch.writeMu.Lock()\n\tpacket := ch.packetPool[extendedCode]\n\t// We don't remove the buffer from packetPool, so\n\t// WriteExtended calls from different goroutines will be\n\t// flagged as errors by the race detector.\n\tch.writeMu.Unlock()\n\n\tfor len(data) > 0 {\n\t\tspace := min(ch.maxRemotePayload, len(data))\n\t\tif space, err = ch.remoteWin.reserve(space); err != nil {\n\t\t\treturn n, err\n\t\t}\n\t\tif want := headerLength + space; uint32(cap(packet)) < want {\n\t\t\tpacket = make([]byte, want)\n\t\t} else {\n\t\t\tpacket = packet[:want]\n\t\t}\n\n\t\ttodo := data[:space]\n\n\t\tpacket[0] = opCode\n\t\tbinary.BigEndian.PutUint32(packet[1:], ch.remoteId)\n\t\tif extendedCode > 0 {\n\t\t\tbinary.BigEndian.PutUint32(packet[5:], uint32(extendedCode))\n\t\t}\n\t\tbinary.BigEndian.PutUint32(packet[headerLength-4:], uint32(len(todo)))\n\t\tcopy(packet[headerLength:], todo)\n\t\tif err = ch.writePacket(packet); err != nil {\n\t\t\treturn n, err\n\t\t}\n\n\t\tn += len(todo)\n\t\tdata = data[len(todo):]\n\t}\n\n\tch.writeMu.Lock()\n\tch.packetPool[extendedCode] = packet\n\tch.writeMu.Unlock()\n\n\treturn n, err\n}\n\nfunc (ch *channel) handleData(packet []byte) error {\n\theaderLen := 9\n\tisExtendedData := packet[0] == msgChannelExtendedData\n\tif isExtendedData {\n\t\theaderLen = 13\n\t}\n\tif len(packet) < headerLen {\n\t\t// malformed data packet\n\t\treturn parseError(packet[0])\n\t}\n\n\tvar extended uint32\n\tif isExtendedData {\n\t\textended = binary.BigEndian.Uint32(packet[5:])\n\t}\n\n\tlength := binary.BigEndian.Uint32(packet[headerLen-4 : headerLen])\n\tif length == 0 {\n\t\treturn nil\n\t}\n\tif length > ch.maxIncomingPayload {\n\t\t// TODO(hanwen): should send Disconnect?\n\t\treturn errors.New(\"ssh: incoming packet exceeds maximum payload size\")\n\t}\n\n\tdata := packet[headerLen:]\n\tif length != uint32(len(data)) {\n\t\treturn errors.New(\"ssh: wrong packet length\")\n\t}\n\n\tch.windowMu.Lock()\n\tif ch.myWindow < length {\n\t\tch.windowMu.Unlock()\n\t\t// TODO(hanwen): should send Disconnect with reason?\n\t\treturn errors.New(\"ssh: remote side wrote too much\")\n\t}\n\tch.myWindow -= length\n\tch.windowMu.Unlock()\n\n\tif extended == 1 {\n\t\tch.extPending.write(data)\n\t} else if extended > 0 {\n\t\t// discard other extended data.\n\t} else {\n\t\tch.pending.write(data)\n\t}\n\treturn nil\n}\n\nfunc (c *channel) adjustWindow(adj uint32) error {\n\tc.windowMu.Lock()\n\t// Since myConsumed and myWindow are managed on our side, and can never\n\t// exceed the initial window setting, we don't worry about overflow.\n\tc.myConsumed += adj\n\tvar sendAdj uint32\n\tif (channelWindowSize-c.myWindow > 3*c.maxIncomingPayload) ||\n\t\t(c.myWindow < channelWindowSize/2) {\n\t\tsendAdj = c.myConsumed\n\t\tc.myConsumed = 0\n\t\tc.myWindow += sendAdj\n\t}\n\tc.windowMu.Unlock()\n\tif sendAdj == 0 {\n\t\treturn nil\n\t}\n\treturn c.sendMessage(windowAdjustMsg{\n\t\tAdditionalBytes: sendAdj,\n\t})\n}\n\nfunc (c *channel) ReadExtended(data []byte, extended uint32) (n int, err error) {\n\tswitch extended {\n\tcase 1:\n\t\tn, err = c.extPending.Read(data)\n\tcase 0:\n\t\tn, err = c.pending.Read(data)\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"ssh: extended code %d unimplemented\", extended)\n\t}\n\n\tif n > 0 {\n\t\terr = c.adjustWindow(uint32(n))\n\t\t// sendWindowAdjust can return io.EOF if the remote\n\t\t// peer has closed the connection, however we want to\n\t\t// defer forwarding io.EOF to the caller of Read until\n\t\t// the buffer has been drained.\n\t\tif n > 0 && err == io.EOF {\n\t\t\terr = nil\n\t\t}\n\t}\n\n\treturn n, err\n}\n\nfunc (c *channel) close() {\n\tc.pending.eof()\n\tc.extPending.eof()\n\tclose(c.msg)\n\tclose(c.incomingRequests)\n\tc.writeMu.Lock()\n\t// This is not necessary for a normal channel teardown, but if\n\t// there was another error, it is.\n\tc.sentClose = true\n\tc.writeMu.Unlock()\n\t// Unblock writers.\n\tc.remoteWin.close()\n}\n\n// responseMessageReceived is called when a success or failure message is\n// received on a channel to check that such a message is reasonable for the\n// given channel.\nfunc (ch *channel) responseMessageReceived() error {\n\tif ch.direction == channelInbound {\n\t\treturn errors.New(\"ssh: channel response message received on inbound channel\")\n\t}\n\tif ch.decided {\n\t\treturn errors.New(\"ssh: duplicate response received for channel\")\n\t}\n\tch.decided = true\n\treturn nil\n}\n\nfunc (ch *channel) handlePacket(packet []byte) error {\n\tswitch packet[0] {\n\tcase msgChannelData, msgChannelExtendedData:\n\t\treturn ch.handleData(packet)\n\tcase msgChannelClose:\n\t\tch.sendMessage(channelCloseMsg{PeersID: ch.remoteId})\n\t\tch.mux.chanList.remove(ch.localId)\n\t\tch.close()\n\t\treturn nil\n\tcase msgChannelEOF:\n\t\t// RFC 4254 is mute on how EOF affects dataExt messages but\n\t\t// it is logical to signal EOF at the same time.\n\t\tch.extPending.eof()\n\t\tch.pending.eof()\n\t\treturn nil\n\t}\n\n\tdecoded, err := decode(packet)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tswitch msg := decoded.(type) {\n\tcase *channelOpenFailureMsg:\n\t\tif err := ch.responseMessageReceived(); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tch.mux.chanList.remove(msg.PeersID)\n\t\tch.msg <- msg\n\tcase *channelOpenConfirmMsg:\n\t\tif err := ch.responseMessageReceived(); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif msg.MaxPacketSize < minPacketLength || msg.MaxPacketSize > 1<<31 {\n\t\t\treturn fmt.Errorf(\"ssh: invalid MaxPacketSize %d from peer\", msg.MaxPacketSize)\n\t\t}\n\t\tch.remoteId = msg.MyID\n\t\tch.maxRemotePayload = msg.MaxPacketSize\n\t\tch.remoteWin.add(msg.MyWindow)\n\t\tch.msg <- msg\n\tcase *windowAdjustMsg:\n\t\tif !ch.remoteWin.add(msg.AdditionalBytes) {\n\t\t\treturn fmt.Errorf(\"ssh: invalid window update for %d bytes\", msg.AdditionalBytes)\n\t\t}\n\tcase *channelRequestMsg:\n\t\treq := Request{\n\t\t\tType:      msg.Request,\n\t\t\tWantReply: msg.WantReply,\n\t\t\tPayload:   msg.RequestSpecificData,\n\t\t\tch:        ch,\n\t\t}\n\n\t\tch.incomingRequests <- &req\n\tdefault:\n\t\tch.msg <- msg\n\t}\n\treturn nil\n}\n\nfunc (m *mux) newChannel(chanType string, direction channelDirection, extraData []byte) *channel {\n\tch := &channel{\n\t\tremoteWin:        window{Cond: newCond()},\n\t\tmyWindow:         channelWindowSize,\n\t\tpending:          newBuffer(),\n\t\textPending:       newBuffer(),\n\t\tdirection:        direction,\n\t\tincomingRequests: make(chan *Request, chanSize),\n\t\tmsg:              make(chan interface{}, chanSize),\n\t\tchanType:         chanType,\n\t\textraData:        extraData,\n\t\tmux:              m,\n\t\tpacketPool:       make(map[uint32][]byte),\n\t}\n\tch.localId = m.chanList.add(ch)\n\treturn ch\n}\n\nvar errUndecided = errors.New(\"ssh: must Accept or Reject channel\")\nvar errDecidedAlready = errors.New(\"ssh: can call Accept or Reject only once\")\n\ntype extChannel struct {\n\tcode uint32\n\tch   *channel\n}\n\nfunc (e *extChannel) Write(data []byte) (n int, err error) {\n\treturn e.ch.WriteExtended(data, e.code)\n}\n\nfunc (e *extChannel) Read(data []byte) (n int, err error) {\n\treturn e.ch.ReadExtended(data, e.code)\n}\n\nfunc (ch *channel) Accept() (Channel, <-chan *Request, error) {\n\tif ch.decided {\n\t\treturn nil, nil, errDecidedAlready\n\t}\n\tch.maxIncomingPayload = channelMaxPacket\n\tconfirm := channelOpenConfirmMsg{\n\t\tPeersID:       ch.remoteId,\n\t\tMyID:          ch.localId,\n\t\tMyWindow:      ch.myWindow,\n\t\tMaxPacketSize: ch.maxIncomingPayload,\n\t}\n\tch.decided = true\n\tif err := ch.sendMessage(confirm); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\treturn ch, ch.incomingRequests, nil\n}\n\nfunc (ch *channel) Reject(reason RejectionReason, message string) error {\n\tif ch.decided {\n\t\treturn errDecidedAlready\n\t}\n\treject := channelOpenFailureMsg{\n\t\tPeersID:  ch.remoteId,\n\t\tReason:   reason,\n\t\tMessage:  message,\n\t\tLanguage: \"en\",\n\t}\n\tch.decided = true\n\treturn ch.sendMessage(reject)\n}\n\nfunc (ch *channel) Read(data []byte) (int, error) {\n\tif !ch.decided {\n\t\treturn 0, errUndecided\n\t}\n\treturn ch.ReadExtended(data, 0)\n}\n\nfunc (ch *channel) Write(data []byte) (int, error) {\n\tif !ch.decided {\n\t\treturn 0, errUndecided\n\t}\n\treturn ch.WriteExtended(data, 0)\n}\n\nfunc (ch *channel) CloseWrite() error {\n\tif !ch.decided {\n\t\treturn errUndecided\n\t}\n\tch.sentEOF = true\n\treturn ch.sendMessage(channelEOFMsg{\n\t\tPeersID: ch.remoteId})\n}\n\nfunc (ch *channel) Close() error {\n\tif !ch.decided {\n\t\treturn errUndecided\n\t}\n\n\treturn ch.sendMessage(channelCloseMsg{\n\t\tPeersID: ch.remoteId})\n}\n\n// Extended returns an io.ReadWriter that sends and receives data on the given,\n// SSH extended stream. Such streams are used, for example, for stderr.\nfunc (ch *channel) Extended(code uint32) io.ReadWriter {\n\tif !ch.decided {\n\t\treturn nil\n\t}\n\treturn &extChannel{code, ch}\n}\n\nfunc (ch *channel) Stderr() io.ReadWriter {\n\treturn ch.Extended(1)\n}\n\nfunc (ch *channel) SendRequest(name string, wantReply bool, payload []byte) (bool, error) {\n\tif !ch.decided {\n\t\treturn false, errUndecided\n\t}\n\n\tif wantReply {\n\t\tch.sentRequestMu.Lock()\n\t\tdefer ch.sentRequestMu.Unlock()\n\t}\n\n\tmsg := channelRequestMsg{\n\t\tPeersID:             ch.remoteId,\n\t\tRequest:             name,\n\t\tWantReply:           wantReply,\n\t\tRequestSpecificData: payload,\n\t}\n\n\tif err := ch.sendMessage(msg); err != nil {\n\t\treturn false, err\n\t}\n\n\tif wantReply {\n\t\tm, ok := (<-ch.msg)\n\t\tif !ok {\n\t\t\treturn false, io.EOF\n\t\t}\n\t\tswitch m.(type) {\n\t\tcase *channelRequestFailureMsg:\n\t\t\treturn false, nil\n\t\tcase *channelRequestSuccessMsg:\n\t\t\treturn true, nil\n\t\tdefault:\n\t\t\treturn false, fmt.Errorf(\"ssh: unexpected response to channel request: %#v\", m)\n\t\t}\n\t}\n\n\treturn false, nil\n}\n\n// ackRequest either sends an ack or nack to the channel request.\nfunc (ch *channel) ackRequest(ok bool) error {\n\tif !ch.decided {\n\t\treturn errUndecided\n\t}\n\n\tvar msg interface{}\n\tif !ok {\n\t\tmsg = channelRequestFailureMsg{\n\t\t\tPeersID: ch.remoteId,\n\t\t}\n\t} else {\n\t\tmsg = channelRequestSuccessMsg{\n\t\t\tPeersID: ch.remoteId,\n\t\t}\n\t}\n\treturn ch.sendMessage(msg)\n}\n\nfunc (ch *channel) ChannelType() string {\n\treturn ch.chanType\n}\n\nfunc (ch *channel) ExtraData() []byte {\n\treturn ch.extraData\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/cipher.go",
    "content": "// Copyright 2011 The Go 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 ssh\n\nimport (\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/des\"\n\t\"crypto/rc4\"\n\t\"crypto/subtle\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"hash\"\n\t\"io\"\n\n\t\"golang.org/x/crypto/chacha20\"\n\t\"golang.org/x/crypto/internal/poly1305\"\n)\n\nconst (\n\tpacketSizeMultiple = 16 // TODO(huin) this should be determined by the cipher.\n\n\t// RFC 4253 section 6.1 defines a minimum packet size of 32768 that implementations\n\t// MUST be able to process (plus a few more kilobytes for padding and mac). The RFC\n\t// indicates implementations SHOULD be able to handle larger packet sizes, but then\n\t// waffles on about reasonable limits.\n\t//\n\t// OpenSSH caps their maxPacket at 256kB so we choose to do\n\t// the same. maxPacket is also used to ensure that uint32\n\t// length fields do not overflow, so it should remain well\n\t// below 4G.\n\tmaxPacket = 256 * 1024\n)\n\n// noneCipher implements cipher.Stream and provides no encryption. It is used\n// by the transport before the first key-exchange.\ntype noneCipher struct{}\n\nfunc (c noneCipher) XORKeyStream(dst, src []byte) {\n\tcopy(dst, src)\n}\n\nfunc newAESCTR(key, iv []byte) (cipher.Stream, error) {\n\tc, err := aes.NewCipher(key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn cipher.NewCTR(c, iv), nil\n}\n\nfunc newRC4(key, iv []byte) (cipher.Stream, error) {\n\treturn rc4.NewCipher(key)\n}\n\ntype cipherMode struct {\n\tkeySize int\n\tivSize  int\n\tcreate  func(key, iv []byte, macKey []byte, algs directionAlgorithms) (packetCipher, error)\n}\n\nfunc streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream, error)) func(key, iv []byte, macKey []byte, algs directionAlgorithms) (packetCipher, error) {\n\treturn func(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {\n\t\tstream, err := createFunc(key, iv)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tvar streamDump []byte\n\t\tif skip > 0 {\n\t\t\tstreamDump = make([]byte, 512)\n\t\t}\n\n\t\tfor remainingToDump := skip; remainingToDump > 0; {\n\t\t\tdumpThisTime := remainingToDump\n\t\t\tif dumpThisTime > len(streamDump) {\n\t\t\t\tdumpThisTime = len(streamDump)\n\t\t\t}\n\t\t\tstream.XORKeyStream(streamDump[:dumpThisTime], streamDump[:dumpThisTime])\n\t\t\tremainingToDump -= dumpThisTime\n\t\t}\n\n\t\tmac := macModes[algs.MAC].new(macKey)\n\t\treturn &streamPacketCipher{\n\t\t\tmac:       mac,\n\t\t\tetm:       macModes[algs.MAC].etm,\n\t\t\tmacResult: make([]byte, mac.Size()),\n\t\t\tcipher:    stream,\n\t\t}, nil\n\t}\n}\n\n// cipherModes documents properties of supported ciphers. Ciphers not included\n// are not supported and will not be negotiated, even if explicitly requested in\n// ClientConfig.Crypto.Ciphers.\nvar cipherModes = map[string]*cipherMode{\n\t// Ciphers from RFC 4344, which introduced many CTR-based ciphers. Algorithms\n\t// are defined in the order specified in the RFC.\n\t\"aes128-ctr\": {16, aes.BlockSize, streamCipherMode(0, newAESCTR)},\n\t\"aes192-ctr\": {24, aes.BlockSize, streamCipherMode(0, newAESCTR)},\n\t\"aes256-ctr\": {32, aes.BlockSize, streamCipherMode(0, newAESCTR)},\n\n\t// Ciphers from RFC 4345, which introduces security-improved arcfour ciphers.\n\t// They are defined in the order specified in the RFC.\n\t\"arcfour128\": {16, 0, streamCipherMode(1536, newRC4)},\n\t\"arcfour256\": {32, 0, streamCipherMode(1536, newRC4)},\n\n\t// Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol.\n\t// Note that this cipher is not safe, as stated in RFC 4253: \"Arcfour (and\n\t// RC4) has problems with weak keys, and should be used with caution.\"\n\t// RFC 4345 introduces improved versions of Arcfour.\n\t\"arcfour\": {16, 0, streamCipherMode(0, newRC4)},\n\n\t// AEAD ciphers\n\tgcm128CipherID:     {16, 12, newGCMCipher},\n\tgcm256CipherID:     {32, 12, newGCMCipher},\n\tchacha20Poly1305ID: {64, 0, newChaCha20Cipher},\n\n\t// CBC mode is insecure and so is not included in the default config.\n\t// (See https://www.ieee-security.org/TC/SP2013/papers/4977a526.pdf). If absolutely\n\t// needed, it's possible to specify a custom Config to enable it.\n\t// You should expect that an active attacker can recover plaintext if\n\t// you do.\n\taes128cbcID: {16, aes.BlockSize, newAESCBCCipher},\n\n\t// 3des-cbc is insecure and is not included in the default\n\t// config.\n\ttripledescbcID: {24, des.BlockSize, newTripleDESCBCCipher},\n}\n\n// prefixLen is the length of the packet prefix that contains the packet length\n// and number of padding bytes.\nconst prefixLen = 5\n\n// streamPacketCipher is a packetCipher using a stream cipher.\ntype streamPacketCipher struct {\n\tmac    hash.Hash\n\tcipher cipher.Stream\n\tetm    bool\n\n\t// The following members are to avoid per-packet allocations.\n\tprefix      [prefixLen]byte\n\tseqNumBytes [4]byte\n\tpadding     [2 * packetSizeMultiple]byte\n\tpacketData  []byte\n\tmacResult   []byte\n}\n\n// readCipherPacket reads and decrypt a single packet from the reader argument.\nfunc (s *streamPacketCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error) {\n\tif _, err := io.ReadFull(r, s.prefix[:]); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar encryptedPaddingLength [1]byte\n\tif s.mac != nil && s.etm {\n\t\tcopy(encryptedPaddingLength[:], s.prefix[4:5])\n\t\ts.cipher.XORKeyStream(s.prefix[4:5], s.prefix[4:5])\n\t} else {\n\t\ts.cipher.XORKeyStream(s.prefix[:], s.prefix[:])\n\t}\n\n\tlength := binary.BigEndian.Uint32(s.prefix[0:4])\n\tpaddingLength := uint32(s.prefix[4])\n\n\tvar macSize uint32\n\tif s.mac != nil {\n\t\ts.mac.Reset()\n\t\tbinary.BigEndian.PutUint32(s.seqNumBytes[:], seqNum)\n\t\ts.mac.Write(s.seqNumBytes[:])\n\t\tif s.etm {\n\t\t\ts.mac.Write(s.prefix[:4])\n\t\t\ts.mac.Write(encryptedPaddingLength[:])\n\t\t} else {\n\t\t\ts.mac.Write(s.prefix[:])\n\t\t}\n\t\tmacSize = uint32(s.mac.Size())\n\t}\n\n\tif length <= paddingLength+1 {\n\t\treturn nil, errors.New(\"ssh: invalid packet length, packet too small\")\n\t}\n\n\tif length > maxPacket {\n\t\treturn nil, errors.New(\"ssh: invalid packet length, packet too large\")\n\t}\n\n\t// the maxPacket check above ensures that length-1+macSize\n\t// does not overflow.\n\tif uint32(cap(s.packetData)) < length-1+macSize {\n\t\ts.packetData = make([]byte, length-1+macSize)\n\t} else {\n\t\ts.packetData = s.packetData[:length-1+macSize]\n\t}\n\n\tif _, err := io.ReadFull(r, s.packetData); err != nil {\n\t\treturn nil, err\n\t}\n\tmac := s.packetData[length-1:]\n\tdata := s.packetData[:length-1]\n\n\tif s.mac != nil && s.etm {\n\t\ts.mac.Write(data)\n\t}\n\n\ts.cipher.XORKeyStream(data, data)\n\n\tif s.mac != nil {\n\t\tif !s.etm {\n\t\t\ts.mac.Write(data)\n\t\t}\n\t\ts.macResult = s.mac.Sum(s.macResult[:0])\n\t\tif subtle.ConstantTimeCompare(s.macResult, mac) != 1 {\n\t\t\treturn nil, errors.New(\"ssh: MAC failure\")\n\t\t}\n\t}\n\n\treturn s.packetData[:length-paddingLength-1], nil\n}\n\n// writeCipherPacket encrypts and sends a packet of data to the writer argument\nfunc (s *streamPacketCipher) writeCipherPacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {\n\tif len(packet) > maxPacket {\n\t\treturn errors.New(\"ssh: packet too large\")\n\t}\n\n\taadlen := 0\n\tif s.mac != nil && s.etm {\n\t\t// packet length is not encrypted for EtM modes\n\t\taadlen = 4\n\t}\n\n\tpaddingLength := packetSizeMultiple - (prefixLen+len(packet)-aadlen)%packetSizeMultiple\n\tif paddingLength < 4 {\n\t\tpaddingLength += packetSizeMultiple\n\t}\n\n\tlength := len(packet) + 1 + paddingLength\n\tbinary.BigEndian.PutUint32(s.prefix[:], uint32(length))\n\ts.prefix[4] = byte(paddingLength)\n\tpadding := s.padding[:paddingLength]\n\tif _, err := io.ReadFull(rand, padding); err != nil {\n\t\treturn err\n\t}\n\n\tif s.mac != nil {\n\t\ts.mac.Reset()\n\t\tbinary.BigEndian.PutUint32(s.seqNumBytes[:], seqNum)\n\t\ts.mac.Write(s.seqNumBytes[:])\n\n\t\tif s.etm {\n\t\t\t// For EtM algorithms, the packet length must stay unencrypted,\n\t\t\t// but the following data (padding length) must be encrypted\n\t\t\ts.cipher.XORKeyStream(s.prefix[4:5], s.prefix[4:5])\n\t\t}\n\n\t\ts.mac.Write(s.prefix[:])\n\n\t\tif !s.etm {\n\t\t\t// For non-EtM algorithms, the algorithm is applied on unencrypted data\n\t\t\ts.mac.Write(packet)\n\t\t\ts.mac.Write(padding)\n\t\t}\n\t}\n\n\tif !(s.mac != nil && s.etm) {\n\t\t// For EtM algorithms, the padding length has already been encrypted\n\t\t// and the packet length must remain unencrypted\n\t\ts.cipher.XORKeyStream(s.prefix[:], s.prefix[:])\n\t}\n\n\ts.cipher.XORKeyStream(packet, packet)\n\ts.cipher.XORKeyStream(padding, padding)\n\n\tif s.mac != nil && s.etm {\n\t\t// For EtM algorithms, packet and padding must be encrypted\n\t\ts.mac.Write(packet)\n\t\ts.mac.Write(padding)\n\t}\n\n\tif _, err := w.Write(s.prefix[:]); err != nil {\n\t\treturn err\n\t}\n\tif _, err := w.Write(packet); err != nil {\n\t\treturn err\n\t}\n\tif _, err := w.Write(padding); err != nil {\n\t\treturn err\n\t}\n\n\tif s.mac != nil {\n\t\ts.macResult = s.mac.Sum(s.macResult[:0])\n\t\tif _, err := w.Write(s.macResult); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\ntype gcmCipher struct {\n\taead   cipher.AEAD\n\tprefix [4]byte\n\tiv     []byte\n\tbuf    []byte\n}\n\nfunc newGCMCipher(key, iv, unusedMacKey []byte, unusedAlgs directionAlgorithms) (packetCipher, error) {\n\tc, err := aes.NewCipher(key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\taead, err := cipher.NewGCM(c)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &gcmCipher{\n\t\taead: aead,\n\t\tiv:   iv,\n\t}, nil\n}\n\nconst gcmTagSize = 16\n\nfunc (c *gcmCipher) writeCipherPacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {\n\t// Pad out to multiple of 16 bytes. This is different from the\n\t// stream cipher because that encrypts the length too.\n\tpadding := byte(packetSizeMultiple - (1+len(packet))%packetSizeMultiple)\n\tif padding < 4 {\n\t\tpadding += packetSizeMultiple\n\t}\n\n\tlength := uint32(len(packet) + int(padding) + 1)\n\tbinary.BigEndian.PutUint32(c.prefix[:], length)\n\tif _, err := w.Write(c.prefix[:]); err != nil {\n\t\treturn err\n\t}\n\n\tif cap(c.buf) < int(length) {\n\t\tc.buf = make([]byte, length)\n\t} else {\n\t\tc.buf = c.buf[:length]\n\t}\n\n\tc.buf[0] = padding\n\tcopy(c.buf[1:], packet)\n\tif _, err := io.ReadFull(rand, c.buf[1+len(packet):]); err != nil {\n\t\treturn err\n\t}\n\tc.buf = c.aead.Seal(c.buf[:0], c.iv, c.buf, c.prefix[:])\n\tif _, err := w.Write(c.buf); err != nil {\n\t\treturn err\n\t}\n\tc.incIV()\n\n\treturn nil\n}\n\nfunc (c *gcmCipher) incIV() {\n\tfor i := 4 + 7; i >= 4; i-- {\n\t\tc.iv[i]++\n\t\tif c.iv[i] != 0 {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc (c *gcmCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error) {\n\tif _, err := io.ReadFull(r, c.prefix[:]); err != nil {\n\t\treturn nil, err\n\t}\n\tlength := binary.BigEndian.Uint32(c.prefix[:])\n\tif length > maxPacket {\n\t\treturn nil, errors.New(\"ssh: max packet length exceeded\")\n\t}\n\n\tif cap(c.buf) < int(length+gcmTagSize) {\n\t\tc.buf = make([]byte, length+gcmTagSize)\n\t} else {\n\t\tc.buf = c.buf[:length+gcmTagSize]\n\t}\n\n\tif _, err := io.ReadFull(r, c.buf); err != nil {\n\t\treturn nil, err\n\t}\n\n\tplain, err := c.aead.Open(c.buf[:0], c.iv, c.buf, c.prefix[:])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tc.incIV()\n\n\tif len(plain) == 0 {\n\t\treturn nil, errors.New(\"ssh: empty packet\")\n\t}\n\n\tpadding := plain[0]\n\tif padding < 4 {\n\t\t// padding is a byte, so it automatically satisfies\n\t\t// the maximum size, which is 255.\n\t\treturn nil, fmt.Errorf(\"ssh: illegal padding %d\", padding)\n\t}\n\n\tif int(padding+1) >= len(plain) {\n\t\treturn nil, fmt.Errorf(\"ssh: padding %d too large\", padding)\n\t}\n\tplain = plain[1 : length-uint32(padding)]\n\treturn plain, nil\n}\n\n// cbcCipher implements aes128-cbc cipher defined in RFC 4253 section 6.1\ntype cbcCipher struct {\n\tmac       hash.Hash\n\tmacSize   uint32\n\tdecrypter cipher.BlockMode\n\tencrypter cipher.BlockMode\n\n\t// The following members are to avoid per-packet allocations.\n\tseqNumBytes [4]byte\n\tpacketData  []byte\n\tmacResult   []byte\n\n\t// Amount of data we should still read to hide which\n\t// verification error triggered.\n\toracleCamouflage uint32\n}\n\nfunc newCBCCipher(c cipher.Block, key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {\n\tcbc := &cbcCipher{\n\t\tmac:        macModes[algs.MAC].new(macKey),\n\t\tdecrypter:  cipher.NewCBCDecrypter(c, iv),\n\t\tencrypter:  cipher.NewCBCEncrypter(c, iv),\n\t\tpacketData: make([]byte, 1024),\n\t}\n\tif cbc.mac != nil {\n\t\tcbc.macSize = uint32(cbc.mac.Size())\n\t}\n\n\treturn cbc, nil\n}\n\nfunc newAESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {\n\tc, err := aes.NewCipher(key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcbc, err := newCBCCipher(c, key, iv, macKey, algs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn cbc, nil\n}\n\nfunc newTripleDESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {\n\tc, err := des.NewTripleDESCipher(key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcbc, err := newCBCCipher(c, key, iv, macKey, algs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn cbc, nil\n}\n\nfunc maxUInt32(a, b int) uint32 {\n\tif a > b {\n\t\treturn uint32(a)\n\t}\n\treturn uint32(b)\n}\n\nconst (\n\tcbcMinPacketSizeMultiple = 8\n\tcbcMinPacketSize         = 16\n\tcbcMinPaddingSize        = 4\n)\n\n// cbcError represents a verification error that may leak information.\ntype cbcError string\n\nfunc (e cbcError) Error() string { return string(e) }\n\nfunc (c *cbcCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error) {\n\tp, err := c.readCipherPacketLeaky(seqNum, r)\n\tif err != nil {\n\t\tif _, ok := err.(cbcError); ok {\n\t\t\t// Verification error: read a fixed amount of\n\t\t\t// data, to make distinguishing between\n\t\t\t// failing MAC and failing length check more\n\t\t\t// difficult.\n\t\t\tio.CopyN(io.Discard, r, int64(c.oracleCamouflage))\n\t\t}\n\t}\n\treturn p, err\n}\n\nfunc (c *cbcCipher) readCipherPacketLeaky(seqNum uint32, r io.Reader) ([]byte, error) {\n\tblockSize := c.decrypter.BlockSize()\n\n\t// Read the header, which will include some of the subsequent data in the\n\t// case of block ciphers - this is copied back to the payload later.\n\t// How many bytes of payload/padding will be read with this first read.\n\tfirstBlockLength := uint32((prefixLen + blockSize - 1) / blockSize * blockSize)\n\tfirstBlock := c.packetData[:firstBlockLength]\n\tif _, err := io.ReadFull(r, firstBlock); err != nil {\n\t\treturn nil, err\n\t}\n\n\tc.oracleCamouflage = maxPacket + 4 + c.macSize - firstBlockLength\n\n\tc.decrypter.CryptBlocks(firstBlock, firstBlock)\n\tlength := binary.BigEndian.Uint32(firstBlock[:4])\n\tif length > maxPacket {\n\t\treturn nil, cbcError(\"ssh: packet too large\")\n\t}\n\tif length+4 < maxUInt32(cbcMinPacketSize, blockSize) {\n\t\t// The minimum size of a packet is 16 (or the cipher block size, whichever\n\t\t// is larger) bytes.\n\t\treturn nil, cbcError(\"ssh: packet too small\")\n\t}\n\t// The length of the packet (including the length field but not the MAC) must\n\t// be a multiple of the block size or 8, whichever is larger.\n\tif (length+4)%maxUInt32(cbcMinPacketSizeMultiple, blockSize) != 0 {\n\t\treturn nil, cbcError(\"ssh: invalid packet length multiple\")\n\t}\n\n\tpaddingLength := uint32(firstBlock[4])\n\tif paddingLength < cbcMinPaddingSize || length <= paddingLength+1 {\n\t\treturn nil, cbcError(\"ssh: invalid packet length\")\n\t}\n\n\t// Positions within the c.packetData buffer:\n\tmacStart := 4 + length\n\tpaddingStart := macStart - paddingLength\n\n\t// Entire packet size, starting before length, ending at end of mac.\n\tentirePacketSize := macStart + c.macSize\n\n\t// Ensure c.packetData is large enough for the entire packet data.\n\tif uint32(cap(c.packetData)) < entirePacketSize {\n\t\t// Still need to upsize and copy, but this should be rare at runtime, only\n\t\t// on upsizing the packetData buffer.\n\t\tc.packetData = make([]byte, entirePacketSize)\n\t\tcopy(c.packetData, firstBlock)\n\t} else {\n\t\tc.packetData = c.packetData[:entirePacketSize]\n\t}\n\n\tn, err := io.ReadFull(r, c.packetData[firstBlockLength:])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tc.oracleCamouflage -= uint32(n)\n\n\tremainingCrypted := c.packetData[firstBlockLength:macStart]\n\tc.decrypter.CryptBlocks(remainingCrypted, remainingCrypted)\n\n\tmac := c.packetData[macStart:]\n\tif c.mac != nil {\n\t\tc.mac.Reset()\n\t\tbinary.BigEndian.PutUint32(c.seqNumBytes[:], seqNum)\n\t\tc.mac.Write(c.seqNumBytes[:])\n\t\tc.mac.Write(c.packetData[:macStart])\n\t\tc.macResult = c.mac.Sum(c.macResult[:0])\n\t\tif subtle.ConstantTimeCompare(c.macResult, mac) != 1 {\n\t\t\treturn nil, cbcError(\"ssh: MAC failure\")\n\t\t}\n\t}\n\n\treturn c.packetData[prefixLen:paddingStart], nil\n}\n\nfunc (c *cbcCipher) writeCipherPacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {\n\teffectiveBlockSize := maxUInt32(cbcMinPacketSizeMultiple, c.encrypter.BlockSize())\n\n\t// Length of encrypted portion of the packet (header, payload, padding).\n\t// Enforce minimum padding and packet size.\n\tencLength := maxUInt32(prefixLen+len(packet)+cbcMinPaddingSize, cbcMinPaddingSize)\n\t// Enforce block size.\n\tencLength = (encLength + effectiveBlockSize - 1) / effectiveBlockSize * effectiveBlockSize\n\n\tlength := encLength - 4\n\tpaddingLength := int(length) - (1 + len(packet))\n\n\t// Overall buffer contains: header, payload, padding, mac.\n\t// Space for the MAC is reserved in the capacity but not the slice length.\n\tbufferSize := encLength + c.macSize\n\tif uint32(cap(c.packetData)) < bufferSize {\n\t\tc.packetData = make([]byte, encLength, bufferSize)\n\t} else {\n\t\tc.packetData = c.packetData[:encLength]\n\t}\n\n\tp := c.packetData\n\n\t// Packet header.\n\tbinary.BigEndian.PutUint32(p, length)\n\tp = p[4:]\n\tp[0] = byte(paddingLength)\n\n\t// Payload.\n\tp = p[1:]\n\tcopy(p, packet)\n\n\t// Padding.\n\tp = p[len(packet):]\n\tif _, err := io.ReadFull(rand, p); err != nil {\n\t\treturn err\n\t}\n\n\tif c.mac != nil {\n\t\tc.mac.Reset()\n\t\tbinary.BigEndian.PutUint32(c.seqNumBytes[:], seqNum)\n\t\tc.mac.Write(c.seqNumBytes[:])\n\t\tc.mac.Write(c.packetData)\n\t\t// The MAC is now appended into the capacity reserved for it earlier.\n\t\tc.packetData = c.mac.Sum(c.packetData)\n\t}\n\n\tc.encrypter.CryptBlocks(c.packetData[:encLength], c.packetData[:encLength])\n\n\tif _, err := w.Write(c.packetData); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nconst chacha20Poly1305ID = \"chacha20-poly1305@openssh.com\"\n\n// chacha20Poly1305Cipher implements the chacha20-poly1305@openssh.com\n// AEAD, which is described here:\n//\n//\thttps://tools.ietf.org/html/draft-josefsson-ssh-chacha20-poly1305-openssh-00\n//\n// the methods here also implement padding, which RFC 4253 Section 6\n// also requires of stream ciphers.\ntype chacha20Poly1305Cipher struct {\n\tlengthKey  [32]byte\n\tcontentKey [32]byte\n\tbuf        []byte\n}\n\nfunc newChaCha20Cipher(key, unusedIV, unusedMACKey []byte, unusedAlgs directionAlgorithms) (packetCipher, error) {\n\tif len(key) != 64 {\n\t\tpanic(len(key))\n\t}\n\n\tc := &chacha20Poly1305Cipher{\n\t\tbuf: make([]byte, 256),\n\t}\n\n\tcopy(c.contentKey[:], key[:32])\n\tcopy(c.lengthKey[:], key[32:])\n\treturn c, nil\n}\n\nfunc (c *chacha20Poly1305Cipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error) {\n\tnonce := make([]byte, 12)\n\tbinary.BigEndian.PutUint32(nonce[8:], seqNum)\n\ts, err := chacha20.NewUnauthenticatedCipher(c.contentKey[:], nonce)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar polyKey, discardBuf [32]byte\n\ts.XORKeyStream(polyKey[:], polyKey[:])\n\ts.XORKeyStream(discardBuf[:], discardBuf[:]) // skip the next 32 bytes\n\n\tencryptedLength := c.buf[:4]\n\tif _, err := io.ReadFull(r, encryptedLength); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar lenBytes [4]byte\n\tls, err := chacha20.NewUnauthenticatedCipher(c.lengthKey[:], nonce)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tls.XORKeyStream(lenBytes[:], encryptedLength)\n\n\tlength := binary.BigEndian.Uint32(lenBytes[:])\n\tif length > maxPacket {\n\t\treturn nil, errors.New(\"ssh: invalid packet length, packet too large\")\n\t}\n\n\tcontentEnd := 4 + length\n\tpacketEnd := contentEnd + poly1305.TagSize\n\tif uint32(cap(c.buf)) < packetEnd {\n\t\tc.buf = make([]byte, packetEnd)\n\t\tcopy(c.buf[:], encryptedLength)\n\t} else {\n\t\tc.buf = c.buf[:packetEnd]\n\t}\n\n\tif _, err := io.ReadFull(r, c.buf[4:packetEnd]); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar mac [poly1305.TagSize]byte\n\tcopy(mac[:], c.buf[contentEnd:packetEnd])\n\tif !poly1305.Verify(&mac, c.buf[:contentEnd], &polyKey) {\n\t\treturn nil, errors.New(\"ssh: MAC failure\")\n\t}\n\n\tplain := c.buf[4:contentEnd]\n\ts.XORKeyStream(plain, plain)\n\n\tif len(plain) == 0 {\n\t\treturn nil, errors.New(\"ssh: empty packet\")\n\t}\n\n\tpadding := plain[0]\n\tif padding < 4 {\n\t\t// padding is a byte, so it automatically satisfies\n\t\t// the maximum size, which is 255.\n\t\treturn nil, fmt.Errorf(\"ssh: illegal padding %d\", padding)\n\t}\n\n\tif int(padding)+1 >= len(plain) {\n\t\treturn nil, fmt.Errorf(\"ssh: padding %d too large\", padding)\n\t}\n\n\tplain = plain[1 : len(plain)-int(padding)]\n\n\treturn plain, nil\n}\n\nfunc (c *chacha20Poly1305Cipher) writeCipherPacket(seqNum uint32, w io.Writer, rand io.Reader, payload []byte) error {\n\tnonce := make([]byte, 12)\n\tbinary.BigEndian.PutUint32(nonce[8:], seqNum)\n\ts, err := chacha20.NewUnauthenticatedCipher(c.contentKey[:], nonce)\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar polyKey, discardBuf [32]byte\n\ts.XORKeyStream(polyKey[:], polyKey[:])\n\ts.XORKeyStream(discardBuf[:], discardBuf[:]) // skip the next 32 bytes\n\n\t// There is no blocksize, so fall back to multiple of 8 byte\n\t// padding, as described in RFC 4253, Sec 6.\n\tconst packetSizeMultiple = 8\n\n\tpadding := packetSizeMultiple - (1+len(payload))%packetSizeMultiple\n\tif padding < 4 {\n\t\tpadding += packetSizeMultiple\n\t}\n\n\t// size (4 bytes), padding (1), payload, padding, tag.\n\ttotalLength := 4 + 1 + len(payload) + padding + poly1305.TagSize\n\tif cap(c.buf) < totalLength {\n\t\tc.buf = make([]byte, totalLength)\n\t} else {\n\t\tc.buf = c.buf[:totalLength]\n\t}\n\n\tbinary.BigEndian.PutUint32(c.buf, uint32(1+len(payload)+padding))\n\tls, err := chacha20.NewUnauthenticatedCipher(c.lengthKey[:], nonce)\n\tif err != nil {\n\t\treturn err\n\t}\n\tls.XORKeyStream(c.buf, c.buf[:4])\n\tc.buf[4] = byte(padding)\n\tcopy(c.buf[5:], payload)\n\tpacketEnd := 5 + len(payload) + padding\n\tif _, err := io.ReadFull(rand, c.buf[5+len(payload):packetEnd]); err != nil {\n\t\treturn err\n\t}\n\n\ts.XORKeyStream(c.buf[4:], c.buf[4:packetEnd])\n\n\tvar mac [poly1305.TagSize]byte\n\tpoly1305.Sum(&mac, c.buf[:packetEnd], &polyKey)\n\n\tcopy(c.buf[packetEnd:], mac[:])\n\n\tif _, err := w.Write(c.buf); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/client.go",
    "content": "// Copyright 2011 The Go 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 ssh\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n)\n\n// Client implements a traditional SSH client that supports shells,\n// subprocesses, TCP port/streamlocal forwarding and tunneled dialing.\ntype Client struct {\n\tConn\n\n\thandleForwardsOnce sync.Once // guards calling (*Client).handleForwards\n\n\tforwards        forwardList // forwarded tcpip connections from the remote side\n\tmu              sync.Mutex\n\tchannelHandlers map[string]chan NewChannel\n}\n\n// HandleChannelOpen returns a channel on which NewChannel requests\n// for the given type are sent. If the type already is being handled,\n// nil is returned. The channel is closed when the connection is closed.\nfunc (c *Client) HandleChannelOpen(channelType string) <-chan NewChannel {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\tif c.channelHandlers == nil {\n\t\t// The SSH channel has been closed.\n\t\tc := make(chan NewChannel)\n\t\tclose(c)\n\t\treturn c\n\t}\n\n\tch := c.channelHandlers[channelType]\n\tif ch != nil {\n\t\treturn nil\n\t}\n\n\tch = make(chan NewChannel, chanSize)\n\tc.channelHandlers[channelType] = ch\n\treturn ch\n}\n\n// NewClient creates a Client on top of the given connection.\nfunc NewClient(c Conn, chans <-chan NewChannel, reqs <-chan *Request) *Client {\n\tconn := &Client{\n\t\tConn:            c,\n\t\tchannelHandlers: make(map[string]chan NewChannel, 1),\n\t}\n\n\tgo conn.handleGlobalRequests(reqs)\n\tgo conn.handleChannelOpens(chans)\n\tgo func() {\n\t\tconn.Wait()\n\t\tconn.forwards.closeAll()\n\t}()\n\treturn conn\n}\n\n// NewClientConn establishes an authenticated SSH connection using c\n// as the underlying transport.  The Request and NewChannel channels\n// must be serviced or the connection will hang.\nfunc NewClientConn(c net.Conn, addr string, config *ClientConfig) (Conn, <-chan NewChannel, <-chan *Request, error) {\n\tfullConf := *config\n\tfullConf.SetDefaults()\n\tif fullConf.HostKeyCallback == nil {\n\t\tc.Close()\n\t\treturn nil, nil, nil, errors.New(\"ssh: must specify HostKeyCallback\")\n\t}\n\n\tconn := &connection{\n\t\tsshConn: sshConn{conn: c, user: fullConf.User},\n\t}\n\n\tif err := conn.clientHandshake(addr, &fullConf); err != nil {\n\t\tc.Close()\n\t\treturn nil, nil, nil, fmt.Errorf(\"ssh: handshake failed: %w\", err)\n\t}\n\tconn.mux = newMux(conn.transport)\n\treturn conn, conn.mux.incomingChannels, conn.mux.incomingRequests, nil\n}\n\n// clientHandshake performs the client side key exchange. See RFC 4253 Section\n// 7.\nfunc (c *connection) clientHandshake(dialAddress string, config *ClientConfig) error {\n\tif config.ClientVersion != \"\" {\n\t\tc.clientVersion = []byte(config.ClientVersion)\n\t} else {\n\t\tc.clientVersion = []byte(packageVersion)\n\t}\n\tvar err error\n\tc.serverVersion, err = exchangeVersions(c.sshConn.conn, c.clientVersion)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tc.transport = newClientTransport(\n\t\tnewTransport(c.sshConn.conn, config.Rand, true /* is client */),\n\t\tc.clientVersion, c.serverVersion, config, dialAddress, c.sshConn.RemoteAddr())\n\tif err := c.transport.waitSession(); err != nil {\n\t\treturn err\n\t}\n\n\tc.sessionID = c.transport.getSessionID()\n\treturn c.clientAuthenticate(config)\n}\n\n// verifyHostKeySignature verifies the host key obtained in the key exchange.\n// algo is the negotiated algorithm, and may be a certificate type.\nfunc verifyHostKeySignature(hostKey PublicKey, algo string, result *kexResult) error {\n\tsig, rest, ok := parseSignatureBody(result.Signature)\n\tif len(rest) > 0 || !ok {\n\t\treturn errors.New(\"ssh: signature parse error\")\n\t}\n\n\tif a := underlyingAlgo(algo); sig.Format != a {\n\t\treturn fmt.Errorf(\"ssh: invalid signature algorithm %q, expected %q\", sig.Format, a)\n\t}\n\n\treturn hostKey.Verify(result.H, sig)\n}\n\n// NewSession opens a new Session for this client. (A session is a remote\n// execution of a program.)\nfunc (c *Client) NewSession() (*Session, error) {\n\tch, in, err := c.OpenChannel(\"session\", nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn newSession(ch, in)\n}\n\nfunc (c *Client) handleGlobalRequests(incoming <-chan *Request) {\n\tfor r := range incoming {\n\t\t// This handles keepalive messages and matches\n\t\t// the behaviour of OpenSSH.\n\t\tr.Reply(false, nil)\n\t}\n}\n\n// handleChannelOpens channel open messages from the remote side.\nfunc (c *Client) handleChannelOpens(in <-chan NewChannel) {\n\tfor ch := range in {\n\t\tc.mu.Lock()\n\t\thandler := c.channelHandlers[ch.ChannelType()]\n\t\tc.mu.Unlock()\n\n\t\tif handler != nil {\n\t\t\thandler <- ch\n\t\t} else {\n\t\t\tch.Reject(UnknownChannelType, fmt.Sprintf(\"unknown channel type: %v\", ch.ChannelType()))\n\t\t}\n\t}\n\n\tc.mu.Lock()\n\tfor _, ch := range c.channelHandlers {\n\t\tclose(ch)\n\t}\n\tc.channelHandlers = nil\n\tc.mu.Unlock()\n}\n\n// Dial starts a client connection to the given SSH server. It is a\n// convenience function that connects to the given network address,\n// initiates the SSH handshake, and then sets up a Client.  For access\n// to incoming channels and requests, use net.Dial with NewClientConn\n// instead.\nfunc Dial(network, addr string, config *ClientConfig) (*Client, error) {\n\tconn, err := net.DialTimeout(network, addr, config.Timeout)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tc, chans, reqs, err := NewClientConn(conn, addr, config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn NewClient(c, chans, reqs), nil\n}\n\n// HostKeyCallback is the function type used for verifying server\n// keys.  A HostKeyCallback must return nil if the host key is OK, or\n// an error to reject it. It receives the hostname as passed to Dial\n// or NewClientConn. The remote address is the RemoteAddr of the\n// net.Conn underlying the SSH connection.\ntype HostKeyCallback func(hostname string, remote net.Addr, key PublicKey) error\n\n// BannerCallback is the function type used for treat the banner sent by\n// the server. A BannerCallback receives the message sent by the remote server.\ntype BannerCallback func(message string) error\n\n// A ClientConfig structure is used to configure a Client. It must not be\n// modified after having been passed to an SSH function.\ntype ClientConfig struct {\n\t// Config contains configuration that is shared between clients and\n\t// servers.\n\tConfig\n\n\t// User contains the username to authenticate as.\n\tUser string\n\n\t// Auth contains possible authentication methods to use with the\n\t// server. Only the first instance of a particular RFC 4252 method will\n\t// be used during authentication.\n\tAuth []AuthMethod\n\n\t// HostKeyCallback is called during the cryptographic\n\t// handshake to validate the server's host key. The client\n\t// configuration must supply this callback for the connection\n\t// to succeed. The functions InsecureIgnoreHostKey or\n\t// FixedHostKey can be used for simplistic host key checks.\n\tHostKeyCallback HostKeyCallback\n\n\t// BannerCallback is called during the SSH dance to display a custom\n\t// server's message. The client configuration can supply this callback to\n\t// handle it as wished. The function BannerDisplayStderr can be used for\n\t// simplistic display on Stderr.\n\tBannerCallback BannerCallback\n\n\t// ClientVersion contains the version identification string that will\n\t// be used for the connection. If empty, a reasonable default is used.\n\tClientVersion string\n\n\t// HostKeyAlgorithms lists the public key algorithms that the client will\n\t// accept from the server for host key authentication, in order of\n\t// preference. If empty, a reasonable default is used. Any\n\t// string returned from a PublicKey.Type method may be used, or\n\t// any of the CertAlgo and KeyAlgo constants.\n\tHostKeyAlgorithms []string\n\n\t// Timeout is the maximum amount of time for the TCP connection to establish.\n\t//\n\t// A Timeout of zero means no timeout.\n\tTimeout time.Duration\n}\n\n// InsecureIgnoreHostKey returns a function that can be used for\n// ClientConfig.HostKeyCallback to accept any host key. It should\n// not be used for production code.\nfunc InsecureIgnoreHostKey() HostKeyCallback {\n\treturn func(hostname string, remote net.Addr, key PublicKey) error {\n\t\treturn nil\n\t}\n}\n\ntype fixedHostKey struct {\n\tkey PublicKey\n}\n\nfunc (f *fixedHostKey) check(hostname string, remote net.Addr, key PublicKey) error {\n\tif f.key == nil {\n\t\treturn fmt.Errorf(\"ssh: required host key was nil\")\n\t}\n\tif !bytes.Equal(key.Marshal(), f.key.Marshal()) {\n\t\treturn fmt.Errorf(\"ssh: host key mismatch\")\n\t}\n\treturn nil\n}\n\n// FixedHostKey returns a function for use in\n// ClientConfig.HostKeyCallback to accept only a specific host key.\nfunc FixedHostKey(key PublicKey) HostKeyCallback {\n\thk := &fixedHostKey{key}\n\treturn hk.check\n}\n\n// BannerDisplayStderr returns a function that can be used for\n// ClientConfig.BannerCallback to display banners on os.Stderr.\nfunc BannerDisplayStderr() BannerCallback {\n\treturn func(banner string) error {\n\t\t_, err := os.Stderr.WriteString(banner)\n\n\t\treturn err\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/client_auth.go",
    "content": "// Copyright 2011 The Go 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 ssh\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n)\n\ntype authResult int\n\nconst (\n\tauthFailure authResult = iota\n\tauthPartialSuccess\n\tauthSuccess\n)\n\n// clientAuthenticate authenticates with the remote server. See RFC 4252.\nfunc (c *connection) clientAuthenticate(config *ClientConfig) error {\n\t// initiate user auth session\n\tif err := c.transport.writePacket(Marshal(&serviceRequestMsg{serviceUserAuth})); err != nil {\n\t\treturn err\n\t}\n\tpacket, err := c.transport.readPacket()\n\tif err != nil {\n\t\treturn err\n\t}\n\t// The server may choose to send a SSH_MSG_EXT_INFO at this point (if we\n\t// advertised willingness to receive one, which we always do) or not. See\n\t// RFC 8308, Section 2.4.\n\textensions := make(map[string][]byte)\n\tif len(packet) > 0 && packet[0] == msgExtInfo {\n\t\tvar extInfo extInfoMsg\n\t\tif err := Unmarshal(packet, &extInfo); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tpayload := extInfo.Payload\n\t\tfor i := uint32(0); i < extInfo.NumExtensions; i++ {\n\t\t\tname, rest, ok := parseString(payload)\n\t\t\tif !ok {\n\t\t\t\treturn parseError(msgExtInfo)\n\t\t\t}\n\t\t\tvalue, rest, ok := parseString(rest)\n\t\t\tif !ok {\n\t\t\t\treturn parseError(msgExtInfo)\n\t\t\t}\n\t\t\textensions[string(name)] = value\n\t\t\tpayload = rest\n\t\t}\n\t\tpacket, err = c.transport.readPacket()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tvar serviceAccept serviceAcceptMsg\n\tif err := Unmarshal(packet, &serviceAccept); err != nil {\n\t\treturn err\n\t}\n\n\t// during the authentication phase the client first attempts the \"none\" method\n\t// then any untried methods suggested by the server.\n\tvar tried []string\n\tvar lastMethods []string\n\n\tsessionID := c.transport.getSessionID()\n\tfor auth := AuthMethod(new(noneAuth)); auth != nil; {\n\t\tok, methods, err := auth.auth(sessionID, config.User, c.transport, config.Rand, extensions)\n\t\tif err != nil {\n\t\t\t// On disconnect, return error immediately\n\t\t\tif _, ok := err.(*disconnectMsg); ok {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\t// We return the error later if there is no other method left to\n\t\t\t// try.\n\t\t\tok = authFailure\n\t\t}\n\t\tif ok == authSuccess {\n\t\t\t// success\n\t\t\treturn nil\n\t\t} else if ok == authFailure {\n\t\t\tif m := auth.method(); !contains(tried, m) {\n\t\t\t\ttried = append(tried, m)\n\t\t\t}\n\t\t}\n\t\tif methods == nil {\n\t\t\tmethods = lastMethods\n\t\t}\n\t\tlastMethods = methods\n\n\t\tauth = nil\n\n\tfindNext:\n\t\tfor _, a := range config.Auth {\n\t\t\tcandidateMethod := a.method()\n\t\t\tif contains(tried, candidateMethod) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfor _, meth := range methods {\n\t\t\t\tif meth == candidateMethod {\n\t\t\t\t\tauth = a\n\t\t\t\t\tbreak findNext\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif auth == nil && err != nil {\n\t\t\t// We have an error and there are no other authentication methods to\n\t\t\t// try, so we return it.\n\t\t\treturn err\n\t\t}\n\t}\n\treturn fmt.Errorf(\"ssh: unable to authenticate, attempted methods %v, no supported methods remain\", tried)\n}\n\nfunc contains(list []string, e string) bool {\n\tfor _, s := range list {\n\t\tif s == e {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// An AuthMethod represents an instance of an RFC 4252 authentication method.\ntype AuthMethod interface {\n\t// auth authenticates user over transport t.\n\t// Returns true if authentication is successful.\n\t// If authentication is not successful, a []string of alternative\n\t// method names is returned. If the slice is nil, it will be ignored\n\t// and the previous set of possible methods will be reused.\n\tauth(session []byte, user string, p packetConn, rand io.Reader, extensions map[string][]byte) (authResult, []string, error)\n\n\t// method returns the RFC 4252 method name.\n\tmethod() string\n}\n\n// \"none\" authentication, RFC 4252 section 5.2.\ntype noneAuth int\n\nfunc (n *noneAuth) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {\n\tif err := c.writePacket(Marshal(&userAuthRequestMsg{\n\t\tUser:    user,\n\t\tService: serviceSSH,\n\t\tMethod:  \"none\",\n\t})); err != nil {\n\t\treturn authFailure, nil, err\n\t}\n\n\treturn handleAuthResponse(c)\n}\n\nfunc (n *noneAuth) method() string {\n\treturn \"none\"\n}\n\n// passwordCallback is an AuthMethod that fetches the password through\n// a function call, e.g. by prompting the user.\ntype passwordCallback func() (password string, err error)\n\nfunc (cb passwordCallback) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {\n\ttype passwordAuthMsg struct {\n\t\tUser     string `sshtype:\"50\"`\n\t\tService  string\n\t\tMethod   string\n\t\tReply    bool\n\t\tPassword string\n\t}\n\n\tpw, err := cb()\n\t// REVIEW NOTE: is there a need to support skipping a password attempt?\n\t// The program may only find out that the user doesn't have a password\n\t// when prompting.\n\tif err != nil {\n\t\treturn authFailure, nil, err\n\t}\n\n\tif err := c.writePacket(Marshal(&passwordAuthMsg{\n\t\tUser:     user,\n\t\tService:  serviceSSH,\n\t\tMethod:   cb.method(),\n\t\tReply:    false,\n\t\tPassword: pw,\n\t})); err != nil {\n\t\treturn authFailure, nil, err\n\t}\n\n\treturn handleAuthResponse(c)\n}\n\nfunc (cb passwordCallback) method() string {\n\treturn \"password\"\n}\n\n// Password returns an AuthMethod using the given password.\nfunc Password(secret string) AuthMethod {\n\treturn passwordCallback(func() (string, error) { return secret, nil })\n}\n\n// PasswordCallback returns an AuthMethod that uses a callback for\n// fetching a password.\nfunc PasswordCallback(prompt func() (secret string, err error)) AuthMethod {\n\treturn passwordCallback(prompt)\n}\n\ntype publickeyAuthMsg struct {\n\tUser    string `sshtype:\"50\"`\n\tService string\n\tMethod  string\n\t// HasSig indicates to the receiver packet that the auth request is signed and\n\t// should be used for authentication of the request.\n\tHasSig   bool\n\tAlgoname string\n\tPubKey   []byte\n\t// Sig is tagged with \"rest\" so Marshal will exclude it during\n\t// validateKey\n\tSig []byte `ssh:\"rest\"`\n}\n\n// publicKeyCallback is an AuthMethod that uses a set of key\n// pairs for authentication.\ntype publicKeyCallback func() ([]Signer, error)\n\nfunc (cb publicKeyCallback) method() string {\n\treturn \"publickey\"\n}\n\nfunc pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (MultiAlgorithmSigner, string, error) {\n\tvar as MultiAlgorithmSigner\n\tkeyFormat := signer.PublicKey().Type()\n\n\t// If the signer implements MultiAlgorithmSigner we use the algorithms it\n\t// support, if it implements AlgorithmSigner we assume it supports all\n\t// algorithms, otherwise only the key format one.\n\tswitch s := signer.(type) {\n\tcase MultiAlgorithmSigner:\n\t\tas = s\n\tcase AlgorithmSigner:\n\t\tas = &multiAlgorithmSigner{\n\t\t\tAlgorithmSigner:     s,\n\t\t\tsupportedAlgorithms: algorithmsForKeyFormat(underlyingAlgo(keyFormat)),\n\t\t}\n\tdefault:\n\t\tas = &multiAlgorithmSigner{\n\t\t\tAlgorithmSigner:     algorithmSignerWrapper{signer},\n\t\t\tsupportedAlgorithms: []string{underlyingAlgo(keyFormat)},\n\t\t}\n\t}\n\n\tgetFallbackAlgo := func() (string, error) {\n\t\t// Fallback to use if there is no \"server-sig-algs\" extension or a\n\t\t// common algorithm cannot be found. We use the public key format if the\n\t\t// MultiAlgorithmSigner supports it, otherwise we return an error.\n\t\tif !contains(as.Algorithms(), underlyingAlgo(keyFormat)) {\n\t\t\treturn \"\", fmt.Errorf(\"ssh: no common public key signature algorithm, server only supports %q for key type %q, signer only supports %v\",\n\t\t\t\tunderlyingAlgo(keyFormat), keyFormat, as.Algorithms())\n\t\t}\n\t\treturn keyFormat, nil\n\t}\n\n\textPayload, ok := extensions[\"server-sig-algs\"]\n\tif !ok {\n\t\t// If there is no \"server-sig-algs\" extension use the fallback\n\t\t// algorithm.\n\t\talgo, err := getFallbackAlgo()\n\t\treturn as, algo, err\n\t}\n\n\t// The server-sig-algs extension only carries underlying signature\n\t// algorithm, but we are trying to select a protocol-level public key\n\t// algorithm, which might be a certificate type. Extend the list of server\n\t// supported algorithms to include the corresponding certificate algorithms.\n\tserverAlgos := strings.Split(string(extPayload), \",\")\n\tfor _, algo := range serverAlgos {\n\t\tif certAlgo, ok := certificateAlgo(algo); ok {\n\t\t\tserverAlgos = append(serverAlgos, certAlgo)\n\t\t}\n\t}\n\n\t// Filter algorithms based on those supported by MultiAlgorithmSigner.\n\tvar keyAlgos []string\n\tfor _, algo := range algorithmsForKeyFormat(keyFormat) {\n\t\tif contains(as.Algorithms(), underlyingAlgo(algo)) {\n\t\t\tkeyAlgos = append(keyAlgos, algo)\n\t\t}\n\t}\n\n\talgo, err := findCommon(\"public key signature algorithm\", keyAlgos, serverAlgos)\n\tif err != nil {\n\t\t// If there is no overlap, return the fallback algorithm to support\n\t\t// servers that fail to list all supported algorithms.\n\t\talgo, err := getFallbackAlgo()\n\t\treturn as, algo, err\n\t}\n\treturn as, algo, nil\n}\n\nfunc (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand io.Reader, extensions map[string][]byte) (authResult, []string, error) {\n\t// Authentication is performed by sending an enquiry to test if a key is\n\t// acceptable to the remote. If the key is acceptable, the client will\n\t// attempt to authenticate with the valid key.  If not the client will repeat\n\t// the process with the remaining keys.\n\n\tsigners, err := cb()\n\tif err != nil {\n\t\treturn authFailure, nil, err\n\t}\n\tvar methods []string\n\tvar errSigAlgo error\n\n\torigSignersLen := len(signers)\n\tfor idx := 0; idx < len(signers); idx++ {\n\t\tsigner := signers[idx]\n\t\tpub := signer.PublicKey()\n\t\tas, algo, err := pickSignatureAlgorithm(signer, extensions)\n\t\tif err != nil && errSigAlgo == nil {\n\t\t\t// If we cannot negotiate a signature algorithm store the first\n\t\t\t// error so we can return it to provide a more meaningful message if\n\t\t\t// no other signers work.\n\t\t\terrSigAlgo = err\n\t\t\tcontinue\n\t\t}\n\t\tok, err := validateKey(pub, algo, user, c)\n\t\tif err != nil {\n\t\t\treturn authFailure, nil, err\n\t\t}\n\t\t// OpenSSH 7.2-7.7 advertises support for rsa-sha2-256 and rsa-sha2-512\n\t\t// in the \"server-sig-algs\" extension but doesn't support these\n\t\t// algorithms for certificate authentication, so if the server rejects\n\t\t// the key try to use the obtained algorithm as if \"server-sig-algs\" had\n\t\t// not been implemented if supported from the algorithm signer.\n\t\tif !ok && idx < origSignersLen && isRSACert(algo) && algo != CertAlgoRSAv01 {\n\t\t\tif contains(as.Algorithms(), KeyAlgoRSA) {\n\t\t\t\t// We retry using the compat algorithm after all signers have\n\t\t\t\t// been tried normally.\n\t\t\t\tsigners = append(signers, &multiAlgorithmSigner{\n\t\t\t\t\tAlgorithmSigner:     as,\n\t\t\t\t\tsupportedAlgorithms: []string{KeyAlgoRSA},\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\tpubKey := pub.Marshal()\n\t\tdata := buildDataSignedForAuth(session, userAuthRequestMsg{\n\t\t\tUser:    user,\n\t\t\tService: serviceSSH,\n\t\t\tMethod:  cb.method(),\n\t\t}, algo, pubKey)\n\t\tsign, err := as.SignWithAlgorithm(rand, data, underlyingAlgo(algo))\n\t\tif err != nil {\n\t\t\treturn authFailure, nil, err\n\t\t}\n\n\t\t// manually wrap the serialized signature in a string\n\t\ts := Marshal(sign)\n\t\tsig := make([]byte, stringLength(len(s)))\n\t\tmarshalString(sig, s)\n\t\tmsg := publickeyAuthMsg{\n\t\t\tUser:     user,\n\t\t\tService:  serviceSSH,\n\t\t\tMethod:   cb.method(),\n\t\t\tHasSig:   true,\n\t\t\tAlgoname: algo,\n\t\t\tPubKey:   pubKey,\n\t\t\tSig:      sig,\n\t\t}\n\t\tp := Marshal(&msg)\n\t\tif err := c.writePacket(p); err != nil {\n\t\t\treturn authFailure, nil, err\n\t\t}\n\t\tvar success authResult\n\t\tsuccess, methods, err = handleAuthResponse(c)\n\t\tif err != nil {\n\t\t\treturn authFailure, nil, err\n\t\t}\n\n\t\t// If authentication succeeds or the list of available methods does not\n\t\t// contain the \"publickey\" method, do not attempt to authenticate with any\n\t\t// other keys.  According to RFC 4252 Section 7, the latter can occur when\n\t\t// additional authentication methods are required.\n\t\tif success == authSuccess || !contains(methods, cb.method()) {\n\t\t\treturn success, methods, err\n\t\t}\n\t}\n\n\treturn authFailure, methods, errSigAlgo\n}\n\n// validateKey validates the key provided is acceptable to the server.\nfunc validateKey(key PublicKey, algo string, user string, c packetConn) (bool, error) {\n\tpubKey := key.Marshal()\n\tmsg := publickeyAuthMsg{\n\t\tUser:     user,\n\t\tService:  serviceSSH,\n\t\tMethod:   \"publickey\",\n\t\tHasSig:   false,\n\t\tAlgoname: algo,\n\t\tPubKey:   pubKey,\n\t}\n\tif err := c.writePacket(Marshal(&msg)); err != nil {\n\t\treturn false, err\n\t}\n\n\treturn confirmKeyAck(key, c)\n}\n\nfunc confirmKeyAck(key PublicKey, c packetConn) (bool, error) {\n\tpubKey := key.Marshal()\n\n\tfor {\n\t\tpacket, err := c.readPacket()\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\t\tswitch packet[0] {\n\t\tcase msgUserAuthBanner:\n\t\t\tif err := handleBannerResponse(c, packet); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\tcase msgUserAuthPubKeyOk:\n\t\t\tvar msg userAuthPubKeyOkMsg\n\t\t\tif err := Unmarshal(packet, &msg); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\t// According to RFC 4252 Section 7 the algorithm in\n\t\t\t// SSH_MSG_USERAUTH_PK_OK should match that of the request but some\n\t\t\t// servers send the key type instead. OpenSSH allows any algorithm\n\t\t\t// that matches the public key, so we do the same.\n\t\t\t// https://github.com/openssh/openssh-portable/blob/86bdd385/sshconnect2.c#L709\n\t\t\tif !contains(algorithmsForKeyFormat(key.Type()), msg.Algo) {\n\t\t\t\treturn false, nil\n\t\t\t}\n\t\t\tif !bytes.Equal(msg.PubKey, pubKey) {\n\t\t\t\treturn false, nil\n\t\t\t}\n\t\t\treturn true, nil\n\t\tcase msgUserAuthFailure:\n\t\t\treturn false, nil\n\t\tdefault:\n\t\t\treturn false, unexpectedMessageError(msgUserAuthPubKeyOk, packet[0])\n\t\t}\n\t}\n}\n\n// PublicKeys returns an AuthMethod that uses the given key\n// pairs.\nfunc PublicKeys(signers ...Signer) AuthMethod {\n\treturn publicKeyCallback(func() ([]Signer, error) { return signers, nil })\n}\n\n// PublicKeysCallback returns an AuthMethod that runs the given\n// function to obtain a list of key pairs.\nfunc PublicKeysCallback(getSigners func() (signers []Signer, err error)) AuthMethod {\n\treturn publicKeyCallback(getSigners)\n}\n\n// handleAuthResponse returns whether the preceding authentication request succeeded\n// along with a list of remaining authentication methods to try next and\n// an error if an unexpected response was received.\nfunc handleAuthResponse(c packetConn) (authResult, []string, error) {\n\tgotMsgExtInfo := false\n\tfor {\n\t\tpacket, err := c.readPacket()\n\t\tif err != nil {\n\t\t\treturn authFailure, nil, err\n\t\t}\n\n\t\tswitch packet[0] {\n\t\tcase msgUserAuthBanner:\n\t\t\tif err := handleBannerResponse(c, packet); err != nil {\n\t\t\t\treturn authFailure, nil, err\n\t\t\t}\n\t\tcase msgExtInfo:\n\t\t\t// Ignore post-authentication RFC 8308 extensions, once.\n\t\t\tif gotMsgExtInfo {\n\t\t\t\treturn authFailure, nil, unexpectedMessageError(msgUserAuthSuccess, packet[0])\n\t\t\t}\n\t\t\tgotMsgExtInfo = true\n\t\tcase msgUserAuthFailure:\n\t\t\tvar msg userAuthFailureMsg\n\t\t\tif err := Unmarshal(packet, &msg); err != nil {\n\t\t\t\treturn authFailure, nil, err\n\t\t\t}\n\t\t\tif msg.PartialSuccess {\n\t\t\t\treturn authPartialSuccess, msg.Methods, nil\n\t\t\t}\n\t\t\treturn authFailure, msg.Methods, nil\n\t\tcase msgUserAuthSuccess:\n\t\t\treturn authSuccess, nil, nil\n\t\tdefault:\n\t\t\treturn authFailure, nil, unexpectedMessageError(msgUserAuthSuccess, packet[0])\n\t\t}\n\t}\n}\n\nfunc handleBannerResponse(c packetConn, packet []byte) error {\n\tvar msg userAuthBannerMsg\n\tif err := Unmarshal(packet, &msg); err != nil {\n\t\treturn err\n\t}\n\n\ttransport, ok := c.(*handshakeTransport)\n\tif !ok {\n\t\treturn nil\n\t}\n\n\tif transport.bannerCallback != nil {\n\t\treturn transport.bannerCallback(msg.Message)\n\t}\n\n\treturn nil\n}\n\n// KeyboardInteractiveChallenge should print questions, optionally\n// disabling echoing (e.g. for passwords), and return all the answers.\n// Challenge may be called multiple times in a single session. After\n// successful authentication, the server may send a challenge with no\n// questions, for which the name and instruction messages should be\n// printed.  RFC 4256 section 3.3 details how the UI should behave for\n// both CLI and GUI environments.\ntype KeyboardInteractiveChallenge func(name, instruction string, questions []string, echos []bool) (answers []string, err error)\n\n// KeyboardInteractive returns an AuthMethod using a prompt/response\n// sequence controlled by the server.\nfunc KeyboardInteractive(challenge KeyboardInteractiveChallenge) AuthMethod {\n\treturn challenge\n}\n\nfunc (cb KeyboardInteractiveChallenge) method() string {\n\treturn \"keyboard-interactive\"\n}\n\nfunc (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {\n\ttype initiateMsg struct {\n\t\tUser       string `sshtype:\"50\"`\n\t\tService    string\n\t\tMethod     string\n\t\tLanguage   string\n\t\tSubmethods string\n\t}\n\n\tif err := c.writePacket(Marshal(&initiateMsg{\n\t\tUser:    user,\n\t\tService: serviceSSH,\n\t\tMethod:  \"keyboard-interactive\",\n\t})); err != nil {\n\t\treturn authFailure, nil, err\n\t}\n\n\tgotMsgExtInfo := false\n\tgotUserAuthInfoRequest := false\n\tfor {\n\t\tpacket, err := c.readPacket()\n\t\tif err != nil {\n\t\t\treturn authFailure, nil, err\n\t\t}\n\n\t\t// like handleAuthResponse, but with less options.\n\t\tswitch packet[0] {\n\t\tcase msgUserAuthBanner:\n\t\t\tif err := handleBannerResponse(c, packet); err != nil {\n\t\t\t\treturn authFailure, nil, err\n\t\t\t}\n\t\t\tcontinue\n\t\tcase msgExtInfo:\n\t\t\t// Ignore post-authentication RFC 8308 extensions, once.\n\t\t\tif gotMsgExtInfo {\n\t\t\t\treturn authFailure, nil, unexpectedMessageError(msgUserAuthInfoRequest, packet[0])\n\t\t\t}\n\t\t\tgotMsgExtInfo = true\n\t\t\tcontinue\n\t\tcase msgUserAuthInfoRequest:\n\t\t\t// OK\n\t\tcase msgUserAuthFailure:\n\t\t\tvar msg userAuthFailureMsg\n\t\t\tif err := Unmarshal(packet, &msg); err != nil {\n\t\t\t\treturn authFailure, nil, err\n\t\t\t}\n\t\t\tif msg.PartialSuccess {\n\t\t\t\treturn authPartialSuccess, msg.Methods, nil\n\t\t\t}\n\t\t\tif !gotUserAuthInfoRequest {\n\t\t\t\treturn authFailure, msg.Methods, unexpectedMessageError(msgUserAuthInfoRequest, packet[0])\n\t\t\t}\n\t\t\treturn authFailure, msg.Methods, nil\n\t\tcase msgUserAuthSuccess:\n\t\t\treturn authSuccess, nil, nil\n\t\tdefault:\n\t\t\treturn authFailure, nil, unexpectedMessageError(msgUserAuthInfoRequest, packet[0])\n\t\t}\n\n\t\tvar msg userAuthInfoRequestMsg\n\t\tif err := Unmarshal(packet, &msg); err != nil {\n\t\t\treturn authFailure, nil, err\n\t\t}\n\t\tgotUserAuthInfoRequest = true\n\n\t\t// Manually unpack the prompt/echo pairs.\n\t\trest := msg.Prompts\n\t\tvar prompts []string\n\t\tvar echos []bool\n\t\tfor i := 0; i < int(msg.NumPrompts); i++ {\n\t\t\tprompt, r, ok := parseString(rest)\n\t\t\tif !ok || len(r) == 0 {\n\t\t\t\treturn authFailure, nil, errors.New(\"ssh: prompt format error\")\n\t\t\t}\n\t\t\tprompts = append(prompts, string(prompt))\n\t\t\techos = append(echos, r[0] != 0)\n\t\t\trest = r[1:]\n\t\t}\n\n\t\tif len(rest) != 0 {\n\t\t\treturn authFailure, nil, errors.New(\"ssh: extra data following keyboard-interactive pairs\")\n\t\t}\n\n\t\tanswers, err := cb(msg.Name, msg.Instruction, prompts, echos)\n\t\tif err != nil {\n\t\t\treturn authFailure, nil, err\n\t\t}\n\n\t\tif len(answers) != len(prompts) {\n\t\t\treturn authFailure, nil, fmt.Errorf(\"ssh: incorrect number of answers from keyboard-interactive callback %d (expected %d)\", len(answers), len(prompts))\n\t\t}\n\t\tresponseLength := 1 + 4\n\t\tfor _, a := range answers {\n\t\t\tresponseLength += stringLength(len(a))\n\t\t}\n\t\tserialized := make([]byte, responseLength)\n\t\tp := serialized\n\t\tp[0] = msgUserAuthInfoResponse\n\t\tp = p[1:]\n\t\tp = marshalUint32(p, uint32(len(answers)))\n\t\tfor _, a := range answers {\n\t\t\tp = marshalString(p, []byte(a))\n\t\t}\n\n\t\tif err := c.writePacket(serialized); err != nil {\n\t\t\treturn authFailure, nil, err\n\t\t}\n\t}\n}\n\ntype retryableAuthMethod struct {\n\tauthMethod AuthMethod\n\tmaxTries   int\n}\n\nfunc (r *retryableAuthMethod) auth(session []byte, user string, c packetConn, rand io.Reader, extensions map[string][]byte) (ok authResult, methods []string, err error) {\n\tfor i := 0; r.maxTries <= 0 || i < r.maxTries; i++ {\n\t\tok, methods, err = r.authMethod.auth(session, user, c, rand, extensions)\n\t\tif ok != authFailure || err != nil { // either success, partial success or error terminate\n\t\t\treturn ok, methods, err\n\t\t}\n\t}\n\treturn ok, methods, err\n}\n\nfunc (r *retryableAuthMethod) method() string {\n\treturn r.authMethod.method()\n}\n\n// RetryableAuthMethod is a decorator for other auth methods enabling them to\n// be retried up to maxTries before considering that AuthMethod itself failed.\n// If maxTries is <= 0, will retry indefinitely\n//\n// This is useful for interactive clients using challenge/response type\n// authentication (e.g. Keyboard-Interactive, Password, etc) where the user\n// could mistype their response resulting in the server issuing a\n// SSH_MSG_USERAUTH_FAILURE (rfc4252 #8 [password] and rfc4256 #3.4\n// [keyboard-interactive]); Without this decorator, the non-retryable\n// AuthMethod would be removed from future consideration, and never tried again\n// (and so the user would never be able to retry their entry).\nfunc RetryableAuthMethod(auth AuthMethod, maxTries int) AuthMethod {\n\treturn &retryableAuthMethod{authMethod: auth, maxTries: maxTries}\n}\n\n// GSSAPIWithMICAuthMethod is an AuthMethod with \"gssapi-with-mic\" authentication.\n// See RFC 4462 section 3\n// gssAPIClient is implementation of the GSSAPIClient interface, see the definition of the interface for details.\n// target is the server host you want to log in to.\nfunc GSSAPIWithMICAuthMethod(gssAPIClient GSSAPIClient, target string) AuthMethod {\n\tif gssAPIClient == nil {\n\t\tpanic(\"gss-api client must be not nil with enable gssapi-with-mic\")\n\t}\n\treturn &gssAPIWithMICCallback{gssAPIClient: gssAPIClient, target: target}\n}\n\ntype gssAPIWithMICCallback struct {\n\tgssAPIClient GSSAPIClient\n\ttarget       string\n}\n\nfunc (g *gssAPIWithMICCallback) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {\n\tm := &userAuthRequestMsg{\n\t\tUser:    user,\n\t\tService: serviceSSH,\n\t\tMethod:  g.method(),\n\t}\n\t// The GSS-API authentication method is initiated when the client sends an SSH_MSG_USERAUTH_REQUEST.\n\t// See RFC 4462 section 3.2.\n\tm.Payload = appendU32(m.Payload, 1)\n\tm.Payload = appendString(m.Payload, string(krb5OID))\n\tif err := c.writePacket(Marshal(m)); err != nil {\n\t\treturn authFailure, nil, err\n\t}\n\t// The server responds to the SSH_MSG_USERAUTH_REQUEST with either an\n\t// SSH_MSG_USERAUTH_FAILURE if none of the mechanisms are supported or\n\t// with an SSH_MSG_USERAUTH_GSSAPI_RESPONSE.\n\t// See RFC 4462 section 3.3.\n\t// OpenSSH supports Kerberos V5 mechanism only for GSS-API authentication,so I don't want to check\n\t// selected mech if it is valid.\n\tpacket, err := c.readPacket()\n\tif err != nil {\n\t\treturn authFailure, nil, err\n\t}\n\tuserAuthGSSAPIResp := &userAuthGSSAPIResponse{}\n\tif err := Unmarshal(packet, userAuthGSSAPIResp); err != nil {\n\t\treturn authFailure, nil, err\n\t}\n\t// Start the loop into the exchange token.\n\t// See RFC 4462 section 3.4.\n\tvar token []byte\n\tdefer g.gssAPIClient.DeleteSecContext()\n\tfor {\n\t\t// Initiates the establishment of a security context between the application and a remote peer.\n\t\tnextToken, needContinue, err := g.gssAPIClient.InitSecContext(\"host@\"+g.target, token, false)\n\t\tif err != nil {\n\t\t\treturn authFailure, nil, err\n\t\t}\n\t\tif len(nextToken) > 0 {\n\t\t\tif err := c.writePacket(Marshal(&userAuthGSSAPIToken{\n\t\t\t\tToken: nextToken,\n\t\t\t})); err != nil {\n\t\t\t\treturn authFailure, nil, err\n\t\t\t}\n\t\t}\n\t\tif !needContinue {\n\t\t\tbreak\n\t\t}\n\t\tpacket, err = c.readPacket()\n\t\tif err != nil {\n\t\t\treturn authFailure, nil, err\n\t\t}\n\t\tswitch packet[0] {\n\t\tcase msgUserAuthFailure:\n\t\t\tvar msg userAuthFailureMsg\n\t\t\tif err := Unmarshal(packet, &msg); err != nil {\n\t\t\t\treturn authFailure, nil, err\n\t\t\t}\n\t\t\tif msg.PartialSuccess {\n\t\t\t\treturn authPartialSuccess, msg.Methods, nil\n\t\t\t}\n\t\t\treturn authFailure, msg.Methods, nil\n\t\tcase msgUserAuthGSSAPIError:\n\t\t\tuserAuthGSSAPIErrorResp := &userAuthGSSAPIError{}\n\t\t\tif err := Unmarshal(packet, userAuthGSSAPIErrorResp); err != nil {\n\t\t\t\treturn authFailure, nil, err\n\t\t\t}\n\t\t\treturn authFailure, nil, fmt.Errorf(\"GSS-API Error:\\n\"+\n\t\t\t\t\"Major Status: %d\\n\"+\n\t\t\t\t\"Minor Status: %d\\n\"+\n\t\t\t\t\"Error Message: %s\\n\", userAuthGSSAPIErrorResp.MajorStatus, userAuthGSSAPIErrorResp.MinorStatus,\n\t\t\t\tuserAuthGSSAPIErrorResp.Message)\n\t\tcase msgUserAuthGSSAPIToken:\n\t\t\tuserAuthGSSAPITokenReq := &userAuthGSSAPIToken{}\n\t\t\tif err := Unmarshal(packet, userAuthGSSAPITokenReq); err != nil {\n\t\t\t\treturn authFailure, nil, err\n\t\t\t}\n\t\t\ttoken = userAuthGSSAPITokenReq.Token\n\t\t}\n\t}\n\t// Binding Encryption Keys.\n\t// See RFC 4462 section 3.5.\n\tmicField := buildMIC(string(session), user, \"ssh-connection\", \"gssapi-with-mic\")\n\tmicToken, err := g.gssAPIClient.GetMIC(micField)\n\tif err != nil {\n\t\treturn authFailure, nil, err\n\t}\n\tif err := c.writePacket(Marshal(&userAuthGSSAPIMIC{\n\t\tMIC: micToken,\n\t})); err != nil {\n\t\treturn authFailure, nil, err\n\t}\n\treturn handleAuthResponse(c)\n}\n\nfunc (g *gssAPIWithMICCallback) method() string {\n\treturn \"gssapi-with-mic\"\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/common.go",
    "content": "// Copyright 2011 The Go 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 ssh\n\nimport (\n\t\"crypto\"\n\t\"crypto/rand\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"sync\"\n\n\t_ \"crypto/sha1\"\n\t_ \"crypto/sha256\"\n\t_ \"crypto/sha512\"\n)\n\n// These are string constants in the SSH protocol.\nconst (\n\tcompressionNone = \"none\"\n\tserviceUserAuth = \"ssh-userauth\"\n\tserviceSSH      = \"ssh-connection\"\n)\n\n// supportedCiphers lists ciphers we support but might not recommend.\nvar supportedCiphers = []string{\n\t\"aes128-ctr\", \"aes192-ctr\", \"aes256-ctr\",\n\t\"aes128-gcm@openssh.com\", gcm256CipherID,\n\tchacha20Poly1305ID,\n\t\"arcfour256\", \"arcfour128\", \"arcfour\",\n\taes128cbcID,\n\ttripledescbcID,\n}\n\n// preferredCiphers specifies the default preference for ciphers.\nvar preferredCiphers = []string{\n\t\"aes128-gcm@openssh.com\", gcm256CipherID,\n\tchacha20Poly1305ID,\n\t\"aes128-ctr\", \"aes192-ctr\", \"aes256-ctr\",\n}\n\n// supportedKexAlgos specifies the supported key-exchange algorithms in\n// preference order.\nvar supportedKexAlgos = []string{\n\tkexAlgoCurve25519SHA256, kexAlgoCurve25519SHA256LibSSH,\n\t// P384 and P521 are not constant-time yet, but since we don't\n\t// reuse ephemeral keys, using them for ECDH should be OK.\n\tkexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,\n\tkexAlgoDH14SHA256, kexAlgoDH16SHA512, kexAlgoDH14SHA1,\n\tkexAlgoDH1SHA1,\n}\n\n// serverForbiddenKexAlgos contains key exchange algorithms, that are forbidden\n// for the server half.\nvar serverForbiddenKexAlgos = map[string]struct{}{\n\tkexAlgoDHGEXSHA1:   {}, // server half implementation is only minimal to satisfy the automated tests\n\tkexAlgoDHGEXSHA256: {}, // server half implementation is only minimal to satisfy the automated tests\n}\n\n// preferredKexAlgos specifies the default preference for key-exchange\n// algorithms in preference order. The diffie-hellman-group16-sha512 algorithm\n// is disabled by default because it is a bit slower than the others.\nvar preferredKexAlgos = []string{\n\tkexAlgoCurve25519SHA256, kexAlgoCurve25519SHA256LibSSH,\n\tkexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,\n\tkexAlgoDH14SHA256, kexAlgoDH14SHA1,\n}\n\n// supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods\n// of authenticating servers) in preference order.\nvar supportedHostKeyAlgos = []string{\n\tCertAlgoRSASHA256v01, CertAlgoRSASHA512v01,\n\tCertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01,\n\tCertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01,\n\n\tKeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,\n\tKeyAlgoRSASHA256, KeyAlgoRSASHA512,\n\tKeyAlgoRSA, KeyAlgoDSA,\n\n\tKeyAlgoED25519,\n}\n\n// supportedMACs specifies a default set of MAC algorithms in preference order.\n// This is based on RFC 4253, section 6.4, but with hmac-md5 variants removed\n// because they have reached the end of their useful life.\nvar supportedMACs = []string{\n\t\"hmac-sha2-256-etm@openssh.com\", \"hmac-sha2-512-etm@openssh.com\", \"hmac-sha2-256\", \"hmac-sha2-512\", \"hmac-sha1\", \"hmac-sha1-96\",\n}\n\nvar supportedCompressions = []string{compressionNone}\n\n// hashFuncs keeps the mapping of supported signature algorithms to their\n// respective hashes needed for signing and verification.\nvar hashFuncs = map[string]crypto.Hash{\n\tKeyAlgoRSA:       crypto.SHA1,\n\tKeyAlgoRSASHA256: crypto.SHA256,\n\tKeyAlgoRSASHA512: crypto.SHA512,\n\tKeyAlgoDSA:       crypto.SHA1,\n\tKeyAlgoECDSA256:  crypto.SHA256,\n\tKeyAlgoECDSA384:  crypto.SHA384,\n\tKeyAlgoECDSA521:  crypto.SHA512,\n\t// KeyAlgoED25519 doesn't pre-hash.\n\tKeyAlgoSKECDSA256: crypto.SHA256,\n\tKeyAlgoSKED25519:  crypto.SHA256,\n}\n\n// algorithmsForKeyFormat returns the supported signature algorithms for a given\n// public key format (PublicKey.Type), in order of preference. See RFC 8332,\n// Section 2. See also the note in sendKexInit on backwards compatibility.\nfunc algorithmsForKeyFormat(keyFormat string) []string {\n\tswitch keyFormat {\n\tcase KeyAlgoRSA:\n\t\treturn []string{KeyAlgoRSASHA256, KeyAlgoRSASHA512, KeyAlgoRSA}\n\tcase CertAlgoRSAv01:\n\t\treturn []string{CertAlgoRSASHA256v01, CertAlgoRSASHA512v01, CertAlgoRSAv01}\n\tdefault:\n\t\treturn []string{keyFormat}\n\t}\n}\n\n// isRSA returns whether algo is a supported RSA algorithm, including certificate\n// algorithms.\nfunc isRSA(algo string) bool {\n\talgos := algorithmsForKeyFormat(KeyAlgoRSA)\n\treturn contains(algos, underlyingAlgo(algo))\n}\n\nfunc isRSACert(algo string) bool {\n\t_, ok := certKeyAlgoNames[algo]\n\tif !ok {\n\t\treturn false\n\t}\n\treturn isRSA(algo)\n}\n\n// supportedPubKeyAuthAlgos specifies the supported client public key\n// authentication algorithms. Note that this doesn't include certificate types\n// since those use the underlying algorithm. This list is sent to the client if\n// it supports the server-sig-algs extension. Order is irrelevant.\nvar supportedPubKeyAuthAlgos = []string{\n\tKeyAlgoED25519,\n\tKeyAlgoSKED25519, KeyAlgoSKECDSA256,\n\tKeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,\n\tKeyAlgoRSASHA256, KeyAlgoRSASHA512, KeyAlgoRSA,\n\tKeyAlgoDSA,\n}\n\n// unexpectedMessageError results when the SSH message that we received didn't\n// match what we wanted.\nfunc unexpectedMessageError(expected, got uint8) error {\n\treturn fmt.Errorf(\"ssh: unexpected message type %d (expected %d)\", got, expected)\n}\n\n// parseError results from a malformed SSH message.\nfunc parseError(tag uint8) error {\n\treturn fmt.Errorf(\"ssh: parse error in message type %d\", tag)\n}\n\nfunc findCommon(what string, client []string, server []string) (common string, err error) {\n\tfor _, c := range client {\n\t\tfor _, s := range server {\n\t\t\tif c == s {\n\t\t\t\treturn c, nil\n\t\t\t}\n\t\t}\n\t}\n\treturn \"\", fmt.Errorf(\"ssh: no common algorithm for %s; client offered: %v, server offered: %v\", what, client, server)\n}\n\n// directionAlgorithms records algorithm choices in one direction (either read or write)\ntype directionAlgorithms struct {\n\tCipher      string\n\tMAC         string\n\tCompression string\n}\n\n// rekeyBytes returns a rekeying intervals in bytes.\nfunc (a *directionAlgorithms) rekeyBytes() int64 {\n\t// According to RFC 4344 block ciphers should rekey after\n\t// 2^(BLOCKSIZE/4) blocks. For all AES flavors BLOCKSIZE is\n\t// 128.\n\tswitch a.Cipher {\n\tcase \"aes128-ctr\", \"aes192-ctr\", \"aes256-ctr\", gcm128CipherID, gcm256CipherID, aes128cbcID:\n\t\treturn 16 * (1 << 32)\n\n\t}\n\n\t// For others, stick with RFC 4253 recommendation to rekey after 1 Gb of data.\n\treturn 1 << 30\n}\n\nvar aeadCiphers = map[string]bool{\n\tgcm128CipherID:     true,\n\tgcm256CipherID:     true,\n\tchacha20Poly1305ID: true,\n}\n\ntype algorithms struct {\n\tkex     string\n\thostKey string\n\tw       directionAlgorithms\n\tr       directionAlgorithms\n}\n\nfunc findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMsg) (algs *algorithms, err error) {\n\tresult := &algorithms{}\n\n\tresult.kex, err = findCommon(\"key exchange\", clientKexInit.KexAlgos, serverKexInit.KexAlgos)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tresult.hostKey, err = findCommon(\"host key\", clientKexInit.ServerHostKeyAlgos, serverKexInit.ServerHostKeyAlgos)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tstoc, ctos := &result.w, &result.r\n\tif isClient {\n\t\tctos, stoc = stoc, ctos\n\t}\n\n\tctos.Cipher, err = findCommon(\"client to server cipher\", clientKexInit.CiphersClientServer, serverKexInit.CiphersClientServer)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tstoc.Cipher, err = findCommon(\"server to client cipher\", clientKexInit.CiphersServerClient, serverKexInit.CiphersServerClient)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tif !aeadCiphers[ctos.Cipher] {\n\t\tctos.MAC, err = findCommon(\"client to server MAC\", clientKexInit.MACsClientServer, serverKexInit.MACsClientServer)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tif !aeadCiphers[stoc.Cipher] {\n\t\tstoc.MAC, err = findCommon(\"server to client MAC\", clientKexInit.MACsServerClient, serverKexInit.MACsServerClient)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tctos.Compression, err = findCommon(\"client to server compression\", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tstoc.Compression, err = findCommon(\"server to client compression\", clientKexInit.CompressionServerClient, serverKexInit.CompressionServerClient)\n\tif err != nil {\n\t\treturn\n\t}\n\n\treturn result, nil\n}\n\n// If rekeythreshold is too small, we can't make any progress sending\n// stuff.\nconst minRekeyThreshold uint64 = 256\n\n// Config contains configuration data common to both ServerConfig and\n// ClientConfig.\ntype Config struct {\n\t// Rand provides the source of entropy for cryptographic\n\t// primitives. If Rand is nil, the cryptographic random reader\n\t// in package crypto/rand will be used.\n\tRand io.Reader\n\n\t// The maximum number of bytes sent or received after which a\n\t// new key is negotiated. It must be at least 256. If\n\t// unspecified, a size suitable for the chosen cipher is used.\n\tRekeyThreshold uint64\n\n\t// The allowed key exchanges algorithms. If unspecified then a default set\n\t// of algorithms is used. Unsupported values are silently ignored.\n\tKeyExchanges []string\n\n\t// The allowed cipher algorithms. If unspecified then a sensible default is\n\t// used. Unsupported values are silently ignored.\n\tCiphers []string\n\n\t// The allowed MAC algorithms. If unspecified then a sensible default is\n\t// used. Unsupported values are silently ignored.\n\tMACs []string\n}\n\n// SetDefaults sets sensible values for unset fields in config. This is\n// exported for testing: Configs passed to SSH functions are copied and have\n// default values set automatically.\nfunc (c *Config) SetDefaults() {\n\tif c.Rand == nil {\n\t\tc.Rand = rand.Reader\n\t}\n\tif c.Ciphers == nil {\n\t\tc.Ciphers = preferredCiphers\n\t}\n\tvar ciphers []string\n\tfor _, c := range c.Ciphers {\n\t\tif cipherModes[c] != nil {\n\t\t\t// Ignore the cipher if we have no cipherModes definition.\n\t\t\tciphers = append(ciphers, c)\n\t\t}\n\t}\n\tc.Ciphers = ciphers\n\n\tif c.KeyExchanges == nil {\n\t\tc.KeyExchanges = preferredKexAlgos\n\t}\n\tvar kexs []string\n\tfor _, k := range c.KeyExchanges {\n\t\tif kexAlgoMap[k] != nil {\n\t\t\t// Ignore the KEX if we have no kexAlgoMap definition.\n\t\t\tkexs = append(kexs, k)\n\t\t}\n\t}\n\tc.KeyExchanges = kexs\n\n\tif c.MACs == nil {\n\t\tc.MACs = supportedMACs\n\t}\n\tvar macs []string\n\tfor _, m := range c.MACs {\n\t\tif macModes[m] != nil {\n\t\t\t// Ignore the MAC if we have no macModes definition.\n\t\t\tmacs = append(macs, m)\n\t\t}\n\t}\n\tc.MACs = macs\n\n\tif c.RekeyThreshold == 0 {\n\t\t// cipher specific default\n\t} else if c.RekeyThreshold < minRekeyThreshold {\n\t\tc.RekeyThreshold = minRekeyThreshold\n\t} else if c.RekeyThreshold >= math.MaxInt64 {\n\t\t// Avoid weirdness if somebody uses -1 as a threshold.\n\t\tc.RekeyThreshold = math.MaxInt64\n\t}\n}\n\n// buildDataSignedForAuth returns the data that is signed in order to prove\n// possession of a private key. See RFC 4252, section 7. algo is the advertised\n// algorithm, and may be a certificate type.\nfunc buildDataSignedForAuth(sessionID []byte, req userAuthRequestMsg, algo string, pubKey []byte) []byte {\n\tdata := struct {\n\t\tSession []byte\n\t\tType    byte\n\t\tUser    string\n\t\tService string\n\t\tMethod  string\n\t\tSign    bool\n\t\tAlgo    string\n\t\tPubKey  []byte\n\t}{\n\t\tsessionID,\n\t\tmsgUserAuthRequest,\n\t\treq.User,\n\t\treq.Service,\n\t\treq.Method,\n\t\ttrue,\n\t\talgo,\n\t\tpubKey,\n\t}\n\treturn Marshal(data)\n}\n\nfunc appendU16(buf []byte, n uint16) []byte {\n\treturn append(buf, byte(n>>8), byte(n))\n}\n\nfunc appendU32(buf []byte, n uint32) []byte {\n\treturn append(buf, byte(n>>24), byte(n>>16), byte(n>>8), byte(n))\n}\n\nfunc appendU64(buf []byte, n uint64) []byte {\n\treturn append(buf,\n\t\tbyte(n>>56), byte(n>>48), byte(n>>40), byte(n>>32),\n\t\tbyte(n>>24), byte(n>>16), byte(n>>8), byte(n))\n}\n\nfunc appendInt(buf []byte, n int) []byte {\n\treturn appendU32(buf, uint32(n))\n}\n\nfunc appendString(buf []byte, s string) []byte {\n\tbuf = appendU32(buf, uint32(len(s)))\n\tbuf = append(buf, s...)\n\treturn buf\n}\n\nfunc appendBool(buf []byte, b bool) []byte {\n\tif b {\n\t\treturn append(buf, 1)\n\t}\n\treturn append(buf, 0)\n}\n\n// newCond is a helper to hide the fact that there is no usable zero\n// value for sync.Cond.\nfunc newCond() *sync.Cond { return sync.NewCond(new(sync.Mutex)) }\n\n// window represents the buffer available to clients\n// wishing to write to a channel.\ntype window struct {\n\t*sync.Cond\n\twin          uint32 // RFC 4254 5.2 says the window size can grow to 2^32-1\n\twriteWaiters int\n\tclosed       bool\n}\n\n// add adds win to the amount of window available\n// for consumers.\nfunc (w *window) add(win uint32) bool {\n\t// a zero sized window adjust is a noop.\n\tif win == 0 {\n\t\treturn true\n\t}\n\tw.L.Lock()\n\tif w.win+win < win {\n\t\tw.L.Unlock()\n\t\treturn false\n\t}\n\tw.win += win\n\t// It is unusual that multiple goroutines would be attempting to reserve\n\t// window space, but not guaranteed. Use broadcast to notify all waiters\n\t// that additional window is available.\n\tw.Broadcast()\n\tw.L.Unlock()\n\treturn true\n}\n\n// close sets the window to closed, so all reservations fail\n// immediately.\nfunc (w *window) close() {\n\tw.L.Lock()\n\tw.closed = true\n\tw.Broadcast()\n\tw.L.Unlock()\n}\n\n// reserve reserves win from the available window capacity.\n// If no capacity remains, reserve will block. reserve may\n// return less than requested.\nfunc (w *window) reserve(win uint32) (uint32, error) {\n\tvar err error\n\tw.L.Lock()\n\tw.writeWaiters++\n\tw.Broadcast()\n\tfor w.win == 0 && !w.closed {\n\t\tw.Wait()\n\t}\n\tw.writeWaiters--\n\tif w.win < win {\n\t\twin = w.win\n\t}\n\tw.win -= win\n\tif w.closed {\n\t\terr = io.EOF\n\t}\n\tw.L.Unlock()\n\treturn win, err\n}\n\n// waitWriterBlocked waits until some goroutine is blocked for further\n// writes. It is used in tests only.\nfunc (w *window) waitWriterBlocked() {\n\tw.Cond.L.Lock()\n\tfor w.writeWaiters == 0 {\n\t\tw.Cond.Wait()\n\t}\n\tw.Cond.L.Unlock()\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/connection.go",
    "content": "// Copyright 2013 The Go 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 ssh\n\nimport (\n\t\"fmt\"\n\t\"net\"\n)\n\n// OpenChannelError is returned if the other side rejects an\n// OpenChannel request.\ntype OpenChannelError struct {\n\tReason  RejectionReason\n\tMessage string\n}\n\nfunc (e *OpenChannelError) Error() string {\n\treturn fmt.Sprintf(\"ssh: rejected: %s (%s)\", e.Reason, e.Message)\n}\n\n// ConnMetadata holds metadata for the connection.\ntype ConnMetadata interface {\n\t// User returns the user ID for this connection.\n\tUser() string\n\n\t// SessionID returns the session hash, also denoted by H.\n\tSessionID() []byte\n\n\t// ClientVersion returns the client's version string as hashed\n\t// into the session ID.\n\tClientVersion() []byte\n\n\t// ServerVersion returns the server's version string as hashed\n\t// into the session ID.\n\tServerVersion() []byte\n\n\t// RemoteAddr returns the remote address for this connection.\n\tRemoteAddr() net.Addr\n\n\t// LocalAddr returns the local address for this connection.\n\tLocalAddr() net.Addr\n}\n\n// Conn represents an SSH connection for both server and client roles.\n// Conn is the basis for implementing an application layer, such\n// as ClientConn, which implements the traditional shell access for\n// clients.\ntype Conn interface {\n\tConnMetadata\n\n\t// SendRequest sends a global request, and returns the\n\t// reply. If wantReply is true, it returns the response status\n\t// and payload. See also RFC 4254, section 4.\n\tSendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error)\n\n\t// OpenChannel tries to open an channel. If the request is\n\t// rejected, it returns *OpenChannelError. On success it returns\n\t// the SSH Channel and a Go channel for incoming, out-of-band\n\t// requests. The Go channel must be serviced, or the\n\t// connection will hang.\n\tOpenChannel(name string, data []byte) (Channel, <-chan *Request, error)\n\n\t// Close closes the underlying network connection\n\tClose() error\n\n\t// Wait blocks until the connection has shut down, and returns the\n\t// error causing the shutdown.\n\tWait() error\n\n\t// TODO(hanwen): consider exposing:\n\t//   RequestKeyChange\n\t//   Disconnect\n}\n\n// DiscardRequests consumes and rejects all requests from the\n// passed-in channel.\nfunc DiscardRequests(in <-chan *Request) {\n\tfor req := range in {\n\t\tif req.WantReply {\n\t\t\treq.Reply(false, nil)\n\t\t}\n\t}\n}\n\n// A connection represents an incoming connection.\ntype connection struct {\n\ttransport *handshakeTransport\n\tsshConn\n\n\t// The connection protocol.\n\t*mux\n}\n\nfunc (c *connection) Close() error {\n\treturn c.sshConn.conn.Close()\n}\n\n// sshConn provides net.Conn metadata, but disallows direct reads and\n// writes.\ntype sshConn struct {\n\tconn net.Conn\n\n\tuser          string\n\tsessionID     []byte\n\tclientVersion []byte\n\tserverVersion []byte\n}\n\nfunc dup(src []byte) []byte {\n\tdst := make([]byte, len(src))\n\tcopy(dst, src)\n\treturn dst\n}\n\nfunc (c *sshConn) User() string {\n\treturn c.user\n}\n\nfunc (c *sshConn) RemoteAddr() net.Addr {\n\treturn c.conn.RemoteAddr()\n}\n\nfunc (c *sshConn) Close() error {\n\treturn c.conn.Close()\n}\n\nfunc (c *sshConn) LocalAddr() net.Addr {\n\treturn c.conn.LocalAddr()\n}\n\nfunc (c *sshConn) SessionID() []byte {\n\treturn dup(c.sessionID)\n}\n\nfunc (c *sshConn) ClientVersion() []byte {\n\treturn dup(c.clientVersion)\n}\n\nfunc (c *sshConn) ServerVersion() []byte {\n\treturn dup(c.serverVersion)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/doc.go",
    "content": "// Copyright 2011 The Go 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\n/*\nPackage ssh implements an SSH client and server.\n\nSSH is a transport security protocol, an authentication protocol and a\nfamily of application protocols. The most typical application level\nprotocol is a remote shell and this is specifically implemented.  However,\nthe multiplexed nature of SSH is exposed to users that wish to support\nothers.\n\nReferences:\n\n\t[PROTOCOL]: https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL?rev=HEAD\n\t[PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD\n\t[SSH-PARAMETERS]:    http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1\n\nThis package does not fall under the stability promise of the Go language itself,\nso its API may be changed when pressing needs arise.\n*/\npackage ssh\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/handshake.go",
    "content": "// Copyright 2013 The Go 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 ssh\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"net\"\n\t\"strings\"\n\t\"sync\"\n)\n\n// debugHandshake, if set, prints messages sent and received.  Key\n// exchange messages are printed as if DH were used, so the debug\n// messages are wrong when using ECDH.\nconst debugHandshake = false\n\n// chanSize sets the amount of buffering SSH connections. This is\n// primarily for testing: setting chanSize=0 uncovers deadlocks more\n// quickly.\nconst chanSize = 16\n\n// maxPendingPackets sets the maximum number of packets to queue while waiting\n// for KEX to complete. This limits the total pending data to maxPendingPackets\n// * maxPacket bytes, which is ~16.8MB.\nconst maxPendingPackets = 64\n\n// keyingTransport is a packet based transport that supports key\n// changes. It need not be thread-safe. It should pass through\n// msgNewKeys in both directions.\ntype keyingTransport interface {\n\tpacketConn\n\n\t// prepareKeyChange sets up a key change. The key change for a\n\t// direction will be effected if a msgNewKeys message is sent\n\t// or received.\n\tprepareKeyChange(*algorithms, *kexResult) error\n\n\t// setStrictMode sets the strict KEX mode, notably triggering\n\t// sequence number resets on sending or receiving msgNewKeys.\n\t// If the sequence number is already > 1 when setStrictMode\n\t// is called, an error is returned.\n\tsetStrictMode() error\n\n\t// setInitialKEXDone indicates to the transport that the initial key exchange\n\t// was completed\n\tsetInitialKEXDone()\n}\n\n// handshakeTransport implements rekeying on top of a keyingTransport\n// and offers a thread-safe writePacket() interface.\ntype handshakeTransport struct {\n\tconn   keyingTransport\n\tconfig *Config\n\n\tserverVersion []byte\n\tclientVersion []byte\n\n\t// hostKeys is non-empty if we are the server. In that case,\n\t// it contains all host keys that can be used to sign the\n\t// connection.\n\thostKeys []Signer\n\n\t// publicKeyAuthAlgorithms is non-empty if we are the server. In that case,\n\t// it contains the supported client public key authentication algorithms.\n\tpublicKeyAuthAlgorithms []string\n\n\t// hostKeyAlgorithms is non-empty if we are the client. In that case,\n\t// we accept these key types from the server as host key.\n\thostKeyAlgorithms []string\n\n\t// On read error, incoming is closed, and readError is set.\n\tincoming  chan []byte\n\treadError error\n\n\tmu sync.Mutex\n\t// Condition for the above mutex. It is used to notify a completed key\n\t// exchange or a write failure. Writes can wait for this condition while a\n\t// key exchange is in progress.\n\twriteCond      *sync.Cond\n\twriteError     error\n\tsentInitPacket []byte\n\tsentInitMsg    *kexInitMsg\n\t// Used to queue writes when a key exchange is in progress. The length is\n\t// limited by pendingPacketsSize. Once full, writes will block until the key\n\t// exchange is completed or an error occurs. If not empty, it is emptied\n\t// all at once when the key exchange is completed in kexLoop.\n\tpendingPackets   [][]byte\n\twritePacketsLeft uint32\n\twriteBytesLeft   int64\n\tuserAuthComplete bool // whether the user authentication phase is complete\n\n\t// If the read loop wants to schedule a kex, it pings this\n\t// channel, and the write loop will send out a kex\n\t// message.\n\trequestKex chan struct{}\n\n\t// If the other side requests or confirms a kex, its kexInit\n\t// packet is sent here for the write loop to find it.\n\tstartKex    chan *pendingKex\n\tkexLoopDone chan struct{} // closed (with writeError non-nil) when kexLoop exits\n\n\t// data for host key checking\n\thostKeyCallback HostKeyCallback\n\tdialAddress     string\n\tremoteAddr      net.Addr\n\n\t// bannerCallback is non-empty if we are the client and it has been set in\n\t// ClientConfig. In that case it is called during the user authentication\n\t// dance to handle a custom server's message.\n\tbannerCallback BannerCallback\n\n\t// Algorithms agreed in the last key exchange.\n\talgorithms *algorithms\n\n\t// Counters exclusively owned by readLoop.\n\treadPacketsLeft uint32\n\treadBytesLeft   int64\n\n\t// The session ID or nil if first kex did not complete yet.\n\tsessionID []byte\n\n\t// strictMode indicates if the other side of the handshake indicated\n\t// that we should be following the strict KEX protocol restrictions.\n\tstrictMode bool\n}\n\ntype pendingKex struct {\n\totherInit []byte\n\tdone      chan error\n}\n\nfunc newHandshakeTransport(conn keyingTransport, config *Config, clientVersion, serverVersion []byte) *handshakeTransport {\n\tt := &handshakeTransport{\n\t\tconn:          conn,\n\t\tserverVersion: serverVersion,\n\t\tclientVersion: clientVersion,\n\t\tincoming:      make(chan []byte, chanSize),\n\t\trequestKex:    make(chan struct{}, 1),\n\t\tstartKex:      make(chan *pendingKex),\n\t\tkexLoopDone:   make(chan struct{}),\n\n\t\tconfig: config,\n\t}\n\tt.writeCond = sync.NewCond(&t.mu)\n\tt.resetReadThresholds()\n\tt.resetWriteThresholds()\n\n\t// We always start with a mandatory key exchange.\n\tt.requestKex <- struct{}{}\n\treturn t\n}\n\nfunc newClientTransport(conn keyingTransport, clientVersion, serverVersion []byte, config *ClientConfig, dialAddr string, addr net.Addr) *handshakeTransport {\n\tt := newHandshakeTransport(conn, &config.Config, clientVersion, serverVersion)\n\tt.dialAddress = dialAddr\n\tt.remoteAddr = addr\n\tt.hostKeyCallback = config.HostKeyCallback\n\tt.bannerCallback = config.BannerCallback\n\tif config.HostKeyAlgorithms != nil {\n\t\tt.hostKeyAlgorithms = config.HostKeyAlgorithms\n\t} else {\n\t\tt.hostKeyAlgorithms = supportedHostKeyAlgos\n\t}\n\tgo t.readLoop()\n\tgo t.kexLoop()\n\treturn t\n}\n\nfunc newServerTransport(conn keyingTransport, clientVersion, serverVersion []byte, config *ServerConfig) *handshakeTransport {\n\tt := newHandshakeTransport(conn, &config.Config, clientVersion, serverVersion)\n\tt.hostKeys = config.hostKeys\n\tt.publicKeyAuthAlgorithms = config.PublicKeyAuthAlgorithms\n\tgo t.readLoop()\n\tgo t.kexLoop()\n\treturn t\n}\n\nfunc (t *handshakeTransport) getSessionID() []byte {\n\treturn t.sessionID\n}\n\n// waitSession waits for the session to be established. This should be\n// the first thing to call after instantiating handshakeTransport.\nfunc (t *handshakeTransport) waitSession() error {\n\tp, err := t.readPacket()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif p[0] != msgNewKeys {\n\t\treturn fmt.Errorf(\"ssh: first packet should be msgNewKeys\")\n\t}\n\n\treturn nil\n}\n\nfunc (t *handshakeTransport) id() string {\n\tif len(t.hostKeys) > 0 {\n\t\treturn \"server\"\n\t}\n\treturn \"client\"\n}\n\nfunc (t *handshakeTransport) printPacket(p []byte, write bool) {\n\taction := \"got\"\n\tif write {\n\t\taction = \"sent\"\n\t}\n\n\tif p[0] == msgChannelData || p[0] == msgChannelExtendedData {\n\t\tlog.Printf(\"%s %s data (packet %d bytes)\", t.id(), action, len(p))\n\t} else {\n\t\tmsg, err := decode(p)\n\t\tlog.Printf(\"%s %s %T %v (%v)\", t.id(), action, msg, msg, err)\n\t}\n}\n\nfunc (t *handshakeTransport) readPacket() ([]byte, error) {\n\tp, ok := <-t.incoming\n\tif !ok {\n\t\treturn nil, t.readError\n\t}\n\treturn p, nil\n}\n\nfunc (t *handshakeTransport) readLoop() {\n\tfirst := true\n\tfor {\n\t\tp, err := t.readOnePacket(first)\n\t\tfirst = false\n\t\tif err != nil {\n\t\t\tt.readError = err\n\t\t\tclose(t.incoming)\n\t\t\tbreak\n\t\t}\n\t\t// If this is the first kex, and strict KEX mode is enabled,\n\t\t// we don't ignore any messages, as they may be used to manipulate\n\t\t// the packet sequence numbers.\n\t\tif !(t.sessionID == nil && t.strictMode) && (p[0] == msgIgnore || p[0] == msgDebug) {\n\t\t\tcontinue\n\t\t}\n\t\tt.incoming <- p\n\t}\n\n\t// Stop writers too.\n\tt.recordWriteError(t.readError)\n\n\t// Unblock the writer should it wait for this.\n\tclose(t.startKex)\n\n\t// Don't close t.requestKex; it's also written to from writePacket.\n}\n\nfunc (t *handshakeTransport) pushPacket(p []byte) error {\n\tif debugHandshake {\n\t\tt.printPacket(p, true)\n\t}\n\treturn t.conn.writePacket(p)\n}\n\nfunc (t *handshakeTransport) getWriteError() error {\n\tt.mu.Lock()\n\tdefer t.mu.Unlock()\n\treturn t.writeError\n}\n\nfunc (t *handshakeTransport) recordWriteError(err error) {\n\tt.mu.Lock()\n\tdefer t.mu.Unlock()\n\tif t.writeError == nil && err != nil {\n\t\tt.writeError = err\n\t\tt.writeCond.Broadcast()\n\t}\n}\n\nfunc (t *handshakeTransport) requestKeyExchange() {\n\tselect {\n\tcase t.requestKex <- struct{}{}:\n\tdefault:\n\t\t// something already requested a kex, so do nothing.\n\t}\n}\n\nfunc (t *handshakeTransport) resetWriteThresholds() {\n\tt.writePacketsLeft = packetRekeyThreshold\n\tif t.config.RekeyThreshold > 0 {\n\t\tt.writeBytesLeft = int64(t.config.RekeyThreshold)\n\t} else if t.algorithms != nil {\n\t\tt.writeBytesLeft = t.algorithms.w.rekeyBytes()\n\t} else {\n\t\tt.writeBytesLeft = 1 << 30\n\t}\n}\n\nfunc (t *handshakeTransport) kexLoop() {\n\nwrite:\n\tfor t.getWriteError() == nil {\n\t\tvar request *pendingKex\n\t\tvar sent bool\n\n\t\tfor request == nil || !sent {\n\t\t\tvar ok bool\n\t\t\tselect {\n\t\t\tcase request, ok = <-t.startKex:\n\t\t\t\tif !ok {\n\t\t\t\t\tbreak write\n\t\t\t\t}\n\t\t\tcase <-t.requestKex:\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif !sent {\n\t\t\t\tif err := t.sendKexInit(); err != nil {\n\t\t\t\t\tt.recordWriteError(err)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tsent = true\n\t\t\t}\n\t\t}\n\n\t\tif err := t.getWriteError(); err != nil {\n\t\t\tif request != nil {\n\t\t\t\trequest.done <- err\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\t// We're not servicing t.requestKex, but that is OK:\n\t\t// we never block on sending to t.requestKex.\n\n\t\t// We're not servicing t.startKex, but the remote end\n\t\t// has just sent us a kexInitMsg, so it can't send\n\t\t// another key change request, until we close the done\n\t\t// channel on the pendingKex request.\n\n\t\terr := t.enterKeyExchange(request.otherInit)\n\n\t\tt.mu.Lock()\n\t\tt.writeError = err\n\t\tt.sentInitPacket = nil\n\t\tt.sentInitMsg = nil\n\n\t\tt.resetWriteThresholds()\n\n\t\t// we have completed the key exchange. Since the\n\t\t// reader is still blocked, it is safe to clear out\n\t\t// the requestKex channel. This avoids the situation\n\t\t// where: 1) we consumed our own request for the\n\t\t// initial kex, and 2) the kex from the remote side\n\t\t// caused another send on the requestKex channel,\n\tclear:\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-t.requestKex:\n\t\t\t\t//\n\t\t\tdefault:\n\t\t\t\tbreak clear\n\t\t\t}\n\t\t}\n\n\t\trequest.done <- t.writeError\n\n\t\t// kex finished. Push packets that we received while\n\t\t// the kex was in progress. Don't look at t.startKex\n\t\t// and don't increment writtenSinceKex: if we trigger\n\t\t// another kex while we are still busy with the last\n\t\t// one, things will become very confusing.\n\t\tfor _, p := range t.pendingPackets {\n\t\t\tt.writeError = t.pushPacket(p)\n\t\t\tif t.writeError != nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tt.pendingPackets = t.pendingPackets[:0]\n\t\t// Unblock writePacket if waiting for KEX.\n\t\tt.writeCond.Broadcast()\n\t\tt.mu.Unlock()\n\t}\n\n\t// Unblock reader.\n\tt.conn.Close()\n\n\t// drain startKex channel. We don't service t.requestKex\n\t// because nobody does blocking sends there.\n\tfor request := range t.startKex {\n\t\trequest.done <- t.getWriteError()\n\t}\n\n\t// Mark that the loop is done so that Close can return.\n\tclose(t.kexLoopDone)\n}\n\n// The protocol uses uint32 for packet counters, so we can't let them\n// reach 1<<32.  We will actually read and write more packets than\n// this, though: the other side may send more packets, and after we\n// hit this limit on writing we will send a few more packets for the\n// key exchange itself.\nconst packetRekeyThreshold = (1 << 31)\n\nfunc (t *handshakeTransport) resetReadThresholds() {\n\tt.readPacketsLeft = packetRekeyThreshold\n\tif t.config.RekeyThreshold > 0 {\n\t\tt.readBytesLeft = int64(t.config.RekeyThreshold)\n\t} else if t.algorithms != nil {\n\t\tt.readBytesLeft = t.algorithms.r.rekeyBytes()\n\t} else {\n\t\tt.readBytesLeft = 1 << 30\n\t}\n}\n\nfunc (t *handshakeTransport) readOnePacket(first bool) ([]byte, error) {\n\tp, err := t.conn.readPacket()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif t.readPacketsLeft > 0 {\n\t\tt.readPacketsLeft--\n\t} else {\n\t\tt.requestKeyExchange()\n\t}\n\n\tif t.readBytesLeft > 0 {\n\t\tt.readBytesLeft -= int64(len(p))\n\t} else {\n\t\tt.requestKeyExchange()\n\t}\n\n\tif debugHandshake {\n\t\tt.printPacket(p, false)\n\t}\n\n\tif first && p[0] != msgKexInit {\n\t\treturn nil, fmt.Errorf(\"ssh: first packet should be msgKexInit\")\n\t}\n\n\tif p[0] != msgKexInit {\n\t\treturn p, nil\n\t}\n\n\tfirstKex := t.sessionID == nil\n\n\tkex := pendingKex{\n\t\tdone:      make(chan error, 1),\n\t\totherInit: p,\n\t}\n\tt.startKex <- &kex\n\terr = <-kex.done\n\n\tif debugHandshake {\n\t\tlog.Printf(\"%s exited key exchange (first %v), err %v\", t.id(), firstKex, err)\n\t}\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tt.resetReadThresholds()\n\n\t// By default, a key exchange is hidden from higher layers by\n\t// translating it into msgIgnore.\n\tsuccessPacket := []byte{msgIgnore}\n\tif firstKex {\n\t\t// sendKexInit() for the first kex waits for\n\t\t// msgNewKeys so the authentication process is\n\t\t// guaranteed to happen over an encrypted transport.\n\t\tsuccessPacket = []byte{msgNewKeys}\n\t}\n\n\treturn successPacket, nil\n}\n\nconst (\n\tkexStrictClient = \"kex-strict-c-v00@openssh.com\"\n\tkexStrictServer = \"kex-strict-s-v00@openssh.com\"\n)\n\n// sendKexInit sends a key change message.\nfunc (t *handshakeTransport) sendKexInit() error {\n\tt.mu.Lock()\n\tdefer t.mu.Unlock()\n\tif t.sentInitMsg != nil {\n\t\t// kexInits may be sent either in response to the other side,\n\t\t// or because our side wants to initiate a key change, so we\n\t\t// may have already sent a kexInit. In that case, don't send a\n\t\t// second kexInit.\n\t\treturn nil\n\t}\n\n\tmsg := &kexInitMsg{\n\t\tCiphersClientServer:     t.config.Ciphers,\n\t\tCiphersServerClient:     t.config.Ciphers,\n\t\tMACsClientServer:        t.config.MACs,\n\t\tMACsServerClient:        t.config.MACs,\n\t\tCompressionClientServer: supportedCompressions,\n\t\tCompressionServerClient: supportedCompressions,\n\t}\n\tio.ReadFull(t.config.Rand, msg.Cookie[:])\n\n\t// We mutate the KexAlgos slice, in order to add the kex-strict extension algorithm,\n\t// and possibly to add the ext-info extension algorithm. Since the slice may be the\n\t// user owned KeyExchanges, we create our own slice in order to avoid using user\n\t// owned memory by mistake.\n\tmsg.KexAlgos = make([]string, 0, len(t.config.KeyExchanges)+2) // room for kex-strict and ext-info\n\tmsg.KexAlgos = append(msg.KexAlgos, t.config.KeyExchanges...)\n\n\tisServer := len(t.hostKeys) > 0\n\tif isServer {\n\t\tfor _, k := range t.hostKeys {\n\t\t\t// If k is a MultiAlgorithmSigner, we restrict the signature\n\t\t\t// algorithms. If k is a AlgorithmSigner, presume it supports all\n\t\t\t// signature algorithms associated with the key format. If k is not\n\t\t\t// an AlgorithmSigner, we can only assume it only supports the\n\t\t\t// algorithms that matches the key format. (This means that Sign\n\t\t\t// can't pick a different default).\n\t\t\tkeyFormat := k.PublicKey().Type()\n\n\t\t\tswitch s := k.(type) {\n\t\t\tcase MultiAlgorithmSigner:\n\t\t\t\tfor _, algo := range algorithmsForKeyFormat(keyFormat) {\n\t\t\t\t\tif contains(s.Algorithms(), underlyingAlgo(algo)) {\n\t\t\t\t\t\tmsg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algo)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tcase AlgorithmSigner:\n\t\t\t\tmsg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algorithmsForKeyFormat(keyFormat)...)\n\t\t\tdefault:\n\t\t\t\tmsg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, keyFormat)\n\t\t\t}\n\t\t}\n\n\t\tif t.sessionID == nil {\n\t\t\tmsg.KexAlgos = append(msg.KexAlgos, kexStrictServer)\n\t\t}\n\t} else {\n\t\tmsg.ServerHostKeyAlgos = t.hostKeyAlgorithms\n\n\t\t// As a client we opt in to receiving SSH_MSG_EXT_INFO so we know what\n\t\t// algorithms the server supports for public key authentication. See RFC\n\t\t// 8308, Section 2.1.\n\t\t//\n\t\t// We also send the strict KEX mode extension algorithm, in order to opt\n\t\t// into the strict KEX mode.\n\t\tif firstKeyExchange := t.sessionID == nil; firstKeyExchange {\n\t\t\tmsg.KexAlgos = append(msg.KexAlgos, \"ext-info-c\")\n\t\t\tmsg.KexAlgos = append(msg.KexAlgos, kexStrictClient)\n\t\t}\n\n\t}\n\n\tpacket := Marshal(msg)\n\n\t// writePacket destroys the contents, so save a copy.\n\tpacketCopy := make([]byte, len(packet))\n\tcopy(packetCopy, packet)\n\n\tif err := t.pushPacket(packetCopy); err != nil {\n\t\treturn err\n\t}\n\n\tt.sentInitMsg = msg\n\tt.sentInitPacket = packet\n\n\treturn nil\n}\n\nvar errSendBannerPhase = errors.New(\"ssh: SendAuthBanner outside of authentication phase\")\n\nfunc (t *handshakeTransport) writePacket(p []byte) error {\n\tt.mu.Lock()\n\tdefer t.mu.Unlock()\n\n\tswitch p[0] {\n\tcase msgKexInit:\n\t\treturn errors.New(\"ssh: only handshakeTransport can send kexInit\")\n\tcase msgNewKeys:\n\t\treturn errors.New(\"ssh: only handshakeTransport can send newKeys\")\n\tcase msgUserAuthBanner:\n\t\tif t.userAuthComplete {\n\t\t\treturn errSendBannerPhase\n\t\t}\n\tcase msgUserAuthSuccess:\n\t\tt.userAuthComplete = true\n\t}\n\n\tif t.writeError != nil {\n\t\treturn t.writeError\n\t}\n\n\tif t.sentInitMsg != nil {\n\t\tif len(t.pendingPackets) < maxPendingPackets {\n\t\t\t// Copy the packet so the writer can reuse the buffer.\n\t\t\tcp := make([]byte, len(p))\n\t\t\tcopy(cp, p)\n\t\t\tt.pendingPackets = append(t.pendingPackets, cp)\n\t\t\treturn nil\n\t\t}\n\t\tfor t.sentInitMsg != nil {\n\t\t\t// Block and wait for KEX to complete or an error.\n\t\t\tt.writeCond.Wait()\n\t\t\tif t.writeError != nil {\n\t\t\t\treturn t.writeError\n\t\t\t}\n\t\t}\n\t}\n\n\tif t.writeBytesLeft > 0 {\n\t\tt.writeBytesLeft -= int64(len(p))\n\t} else {\n\t\tt.requestKeyExchange()\n\t}\n\n\tif t.writePacketsLeft > 0 {\n\t\tt.writePacketsLeft--\n\t} else {\n\t\tt.requestKeyExchange()\n\t}\n\n\tif err := t.pushPacket(p); err != nil {\n\t\tt.writeError = err\n\t\tt.writeCond.Broadcast()\n\t}\n\n\treturn nil\n}\n\nfunc (t *handshakeTransport) Close() error {\n\t// Close the connection. This should cause the readLoop goroutine to wake up\n\t// and close t.startKex, which will shut down kexLoop if running.\n\terr := t.conn.Close()\n\n\t// Wait for the kexLoop goroutine to complete.\n\t// At that point we know that the readLoop goroutine is complete too,\n\t// because kexLoop itself waits for readLoop to close the startKex channel.\n\t<-t.kexLoopDone\n\n\treturn err\n}\n\nfunc (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {\n\tif debugHandshake {\n\t\tlog.Printf(\"%s entered key exchange\", t.id())\n\t}\n\n\totherInit := &kexInitMsg{}\n\tif err := Unmarshal(otherInitPacket, otherInit); err != nil {\n\t\treturn err\n\t}\n\n\tmagics := handshakeMagics{\n\t\tclientVersion: t.clientVersion,\n\t\tserverVersion: t.serverVersion,\n\t\tclientKexInit: otherInitPacket,\n\t\tserverKexInit: t.sentInitPacket,\n\t}\n\n\tclientInit := otherInit\n\tserverInit := t.sentInitMsg\n\tisClient := len(t.hostKeys) == 0\n\tif isClient {\n\t\tclientInit, serverInit = serverInit, clientInit\n\n\t\tmagics.clientKexInit = t.sentInitPacket\n\t\tmagics.serverKexInit = otherInitPacket\n\t}\n\n\tvar err error\n\tt.algorithms, err = findAgreedAlgorithms(isClient, clientInit, serverInit)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif t.sessionID == nil && ((isClient && contains(serverInit.KexAlgos, kexStrictServer)) || (!isClient && contains(clientInit.KexAlgos, kexStrictClient))) {\n\t\tt.strictMode = true\n\t\tif err := t.conn.setStrictMode(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// We don't send FirstKexFollows, but we handle receiving it.\n\t//\n\t// RFC 4253 section 7 defines the kex and the agreement method for\n\t// first_kex_packet_follows. It states that the guessed packet\n\t// should be ignored if the \"kex algorithm and/or the host\n\t// key algorithm is guessed wrong (server and client have\n\t// different preferred algorithm), or if any of the other\n\t// algorithms cannot be agreed upon\". The other algorithms have\n\t// already been checked above so the kex algorithm and host key\n\t// algorithm are checked here.\n\tif otherInit.FirstKexFollows && (clientInit.KexAlgos[0] != serverInit.KexAlgos[0] || clientInit.ServerHostKeyAlgos[0] != serverInit.ServerHostKeyAlgos[0]) {\n\t\t// other side sent a kex message for the wrong algorithm,\n\t\t// which we have to ignore.\n\t\tif _, err := t.conn.readPacket(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tkex, ok := kexAlgoMap[t.algorithms.kex]\n\tif !ok {\n\t\treturn fmt.Errorf(\"ssh: unexpected key exchange algorithm %v\", t.algorithms.kex)\n\t}\n\n\tvar result *kexResult\n\tif len(t.hostKeys) > 0 {\n\t\tresult, err = t.server(kex, &magics)\n\t} else {\n\t\tresult, err = t.client(kex, &magics)\n\t}\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfirstKeyExchange := t.sessionID == nil\n\tif firstKeyExchange {\n\t\tt.sessionID = result.H\n\t}\n\tresult.SessionID = t.sessionID\n\n\tif err := t.conn.prepareKeyChange(t.algorithms, result); err != nil {\n\t\treturn err\n\t}\n\tif err = t.conn.writePacket([]byte{msgNewKeys}); err != nil {\n\t\treturn err\n\t}\n\n\t// On the server side, after the first SSH_MSG_NEWKEYS, send a SSH_MSG_EXT_INFO\n\t// message with the server-sig-algs extension if the client supports it. See\n\t// RFC 8308, Sections 2.4 and 3.1, and [PROTOCOL], Section 1.9.\n\tif !isClient && firstKeyExchange && contains(clientInit.KexAlgos, \"ext-info-c\") {\n\t\tsupportedPubKeyAuthAlgosList := strings.Join(t.publicKeyAuthAlgorithms, \",\")\n\t\textInfo := &extInfoMsg{\n\t\t\tNumExtensions: 2,\n\t\t\tPayload:       make([]byte, 0, 4+15+4+len(supportedPubKeyAuthAlgosList)+4+16+4+1),\n\t\t}\n\t\textInfo.Payload = appendInt(extInfo.Payload, len(\"server-sig-algs\"))\n\t\textInfo.Payload = append(extInfo.Payload, \"server-sig-algs\"...)\n\t\textInfo.Payload = appendInt(extInfo.Payload, len(supportedPubKeyAuthAlgosList))\n\t\textInfo.Payload = append(extInfo.Payload, supportedPubKeyAuthAlgosList...)\n\t\textInfo.Payload = appendInt(extInfo.Payload, len(\"ping@openssh.com\"))\n\t\textInfo.Payload = append(extInfo.Payload, \"ping@openssh.com\"...)\n\t\textInfo.Payload = appendInt(extInfo.Payload, 1)\n\t\textInfo.Payload = append(extInfo.Payload, \"0\"...)\n\t\tif err := t.conn.writePacket(Marshal(extInfo)); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif packet, err := t.conn.readPacket(); err != nil {\n\t\treturn err\n\t} else if packet[0] != msgNewKeys {\n\t\treturn unexpectedMessageError(msgNewKeys, packet[0])\n\t}\n\n\tif firstKeyExchange {\n\t\t// Indicates to the transport that the first key exchange is completed\n\t\t// after receiving SSH_MSG_NEWKEYS.\n\t\tt.conn.setInitialKEXDone()\n\t}\n\n\treturn nil\n}\n\n// algorithmSignerWrapper is an AlgorithmSigner that only supports the default\n// key format algorithm.\n//\n// This is technically a violation of the AlgorithmSigner interface, but it\n// should be unreachable given where we use this. Anyway, at least it returns an\n// error instead of panicing or producing an incorrect signature.\ntype algorithmSignerWrapper struct {\n\tSigner\n}\n\nfunc (a algorithmSignerWrapper) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {\n\tif algorithm != underlyingAlgo(a.PublicKey().Type()) {\n\t\treturn nil, errors.New(\"ssh: internal error: algorithmSignerWrapper invoked with non-default algorithm\")\n\t}\n\treturn a.Sign(rand, data)\n}\n\nfunc pickHostKey(hostKeys []Signer, algo string) AlgorithmSigner {\n\tfor _, k := range hostKeys {\n\t\tif s, ok := k.(MultiAlgorithmSigner); ok {\n\t\t\tif !contains(s.Algorithms(), underlyingAlgo(algo)) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tif algo == k.PublicKey().Type() {\n\t\t\treturn algorithmSignerWrapper{k}\n\t\t}\n\n\t\tk, ok := k.(AlgorithmSigner)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, a := range algorithmsForKeyFormat(k.PublicKey().Type()) {\n\t\t\tif algo == a {\n\t\t\t\treturn k\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (t *handshakeTransport) server(kex kexAlgorithm, magics *handshakeMagics) (*kexResult, error) {\n\thostKey := pickHostKey(t.hostKeys, t.algorithms.hostKey)\n\tif hostKey == nil {\n\t\treturn nil, errors.New(\"ssh: internal error: negotiated unsupported signature type\")\n\t}\n\n\tr, err := kex.Server(t.conn, t.config.Rand, magics, hostKey, t.algorithms.hostKey)\n\treturn r, err\n}\n\nfunc (t *handshakeTransport) client(kex kexAlgorithm, magics *handshakeMagics) (*kexResult, error) {\n\tresult, err := kex.Client(t.conn, t.config.Rand, magics)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\thostKey, err := ParsePublicKey(result.HostKey)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := verifyHostKeySignature(hostKey, t.algorithms.hostKey, result); err != nil {\n\t\treturn nil, err\n\t}\n\n\terr = t.hostKeyCallback(t.dialAddress, t.remoteAddr, hostKey)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/internal/bcrypt_pbkdf/bcrypt_pbkdf.go",
    "content": "// Copyright 2014 The Go 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\n// Package bcrypt_pbkdf implements bcrypt_pbkdf(3) from OpenBSD.\n//\n// See https://flak.tedunangst.com/post/bcrypt-pbkdf and\n// https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libutil/bcrypt_pbkdf.c.\npackage bcrypt_pbkdf\n\nimport (\n\t\"crypto/sha512\"\n\t\"errors\"\n\t\"golang.org/x/crypto/blowfish\"\n)\n\nconst blockSize = 32\n\n// Key derives a key from the password, salt and rounds count, returning a\n// []byte of length keyLen that can be used as cryptographic key.\nfunc Key(password, salt []byte, rounds, keyLen int) ([]byte, error) {\n\tif rounds < 1 {\n\t\treturn nil, errors.New(\"bcrypt_pbkdf: number of rounds is too small\")\n\t}\n\tif len(password) == 0 {\n\t\treturn nil, errors.New(\"bcrypt_pbkdf: empty password\")\n\t}\n\tif len(salt) == 0 || len(salt) > 1<<20 {\n\t\treturn nil, errors.New(\"bcrypt_pbkdf: bad salt length\")\n\t}\n\tif keyLen > 1024 {\n\t\treturn nil, errors.New(\"bcrypt_pbkdf: keyLen is too large\")\n\t}\n\n\tnumBlocks := (keyLen + blockSize - 1) / blockSize\n\tkey := make([]byte, numBlocks*blockSize)\n\n\th := sha512.New()\n\th.Write(password)\n\tshapass := h.Sum(nil)\n\n\tshasalt := make([]byte, 0, sha512.Size)\n\tcnt, tmp := make([]byte, 4), make([]byte, blockSize)\n\tfor block := 1; block <= numBlocks; block++ {\n\t\th.Reset()\n\t\th.Write(salt)\n\t\tcnt[0] = byte(block >> 24)\n\t\tcnt[1] = byte(block >> 16)\n\t\tcnt[2] = byte(block >> 8)\n\t\tcnt[3] = byte(block)\n\t\th.Write(cnt)\n\t\tbcryptHash(tmp, shapass, h.Sum(shasalt))\n\n\t\tout := make([]byte, blockSize)\n\t\tcopy(out, tmp)\n\t\tfor i := 2; i <= rounds; i++ {\n\t\t\th.Reset()\n\t\t\th.Write(tmp)\n\t\t\tbcryptHash(tmp, shapass, h.Sum(shasalt))\n\t\t\tfor j := 0; j < len(out); j++ {\n\t\t\t\tout[j] ^= tmp[j]\n\t\t\t}\n\t\t}\n\n\t\tfor i, v := range out {\n\t\t\tkey[i*numBlocks+(block-1)] = v\n\t\t}\n\t}\n\treturn key[:keyLen], nil\n}\n\nvar magic = []byte(\"OxychromaticBlowfishSwatDynamite\")\n\nfunc bcryptHash(out, shapass, shasalt []byte) {\n\tc, err := blowfish.NewSaltedCipher(shapass, shasalt)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfor i := 0; i < 64; i++ {\n\t\tblowfish.ExpandKey(shasalt, c)\n\t\tblowfish.ExpandKey(shapass, c)\n\t}\n\tcopy(out, magic)\n\tfor i := 0; i < 32; i += 8 {\n\t\tfor j := 0; j < 64; j++ {\n\t\t\tc.Encrypt(out[i:i+8], out[i:i+8])\n\t\t}\n\t}\n\t// Swap bytes due to different endianness.\n\tfor i := 0; i < 32; i += 4 {\n\t\tout[i+3], out[i+2], out[i+1], out[i] = out[i], out[i+1], out[i+2], out[i+3]\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/kex.go",
    "content": "// Copyright 2013 The Go 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 ssh\n\nimport (\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"crypto/subtle\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/big\"\n\n\t\"golang.org/x/crypto/curve25519\"\n)\n\nconst (\n\tkexAlgoDH1SHA1                = \"diffie-hellman-group1-sha1\"\n\tkexAlgoDH14SHA1               = \"diffie-hellman-group14-sha1\"\n\tkexAlgoDH14SHA256             = \"diffie-hellman-group14-sha256\"\n\tkexAlgoDH16SHA512             = \"diffie-hellman-group16-sha512\"\n\tkexAlgoECDH256                = \"ecdh-sha2-nistp256\"\n\tkexAlgoECDH384                = \"ecdh-sha2-nistp384\"\n\tkexAlgoECDH521                = \"ecdh-sha2-nistp521\"\n\tkexAlgoCurve25519SHA256LibSSH = \"curve25519-sha256@libssh.org\"\n\tkexAlgoCurve25519SHA256       = \"curve25519-sha256\"\n\n\t// For the following kex only the client half contains a production\n\t// ready implementation. The server half only consists of a minimal\n\t// implementation to satisfy the automated tests.\n\tkexAlgoDHGEXSHA1   = \"diffie-hellman-group-exchange-sha1\"\n\tkexAlgoDHGEXSHA256 = \"diffie-hellman-group-exchange-sha256\"\n)\n\n// kexResult captures the outcome of a key exchange.\ntype kexResult struct {\n\t// Session hash. See also RFC 4253, section 8.\n\tH []byte\n\n\t// Shared secret. See also RFC 4253, section 8.\n\tK []byte\n\n\t// Host key as hashed into H.\n\tHostKey []byte\n\n\t// Signature of H.\n\tSignature []byte\n\n\t// A cryptographic hash function that matches the security\n\t// level of the key exchange algorithm. It is used for\n\t// calculating H, and for deriving keys from H and K.\n\tHash crypto.Hash\n\n\t// The session ID, which is the first H computed. This is used\n\t// to derive key material inside the transport.\n\tSessionID []byte\n}\n\n// handshakeMagics contains data that is always included in the\n// session hash.\ntype handshakeMagics struct {\n\tclientVersion, serverVersion []byte\n\tclientKexInit, serverKexInit []byte\n}\n\nfunc (m *handshakeMagics) write(w io.Writer) {\n\twriteString(w, m.clientVersion)\n\twriteString(w, m.serverVersion)\n\twriteString(w, m.clientKexInit)\n\twriteString(w, m.serverKexInit)\n}\n\n// kexAlgorithm abstracts different key exchange algorithms.\ntype kexAlgorithm interface {\n\t// Server runs server-side key agreement, signing the result\n\t// with a hostkey. algo is the negotiated algorithm, and may\n\t// be a certificate type.\n\tServer(p packetConn, rand io.Reader, magics *handshakeMagics, s AlgorithmSigner, algo string) (*kexResult, error)\n\n\t// Client runs the client-side key agreement. Caller is\n\t// responsible for verifying the host key signature.\n\tClient(p packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error)\n}\n\n// dhGroup is a multiplicative group suitable for implementing Diffie-Hellman key agreement.\ntype dhGroup struct {\n\tg, p, pMinus1 *big.Int\n\thashFunc      crypto.Hash\n}\n\nfunc (group *dhGroup) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, error) {\n\tif theirPublic.Cmp(bigOne) <= 0 || theirPublic.Cmp(group.pMinus1) >= 0 {\n\t\treturn nil, errors.New(\"ssh: DH parameter out of bounds\")\n\t}\n\treturn new(big.Int).Exp(theirPublic, myPrivate, group.p), nil\n}\n\nfunc (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {\n\tvar x *big.Int\n\tfor {\n\t\tvar err error\n\t\tif x, err = rand.Int(randSource, group.pMinus1); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif x.Sign() > 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tX := new(big.Int).Exp(group.g, x, group.p)\n\tkexDHInit := kexDHInitMsg{\n\t\tX: X,\n\t}\n\tif err := c.writePacket(Marshal(&kexDHInit)); err != nil {\n\t\treturn nil, err\n\t}\n\n\tpacket, err := c.readPacket()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar kexDHReply kexDHReplyMsg\n\tif err = Unmarshal(packet, &kexDHReply); err != nil {\n\t\treturn nil, err\n\t}\n\n\tki, err := group.diffieHellman(kexDHReply.Y, x)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\th := group.hashFunc.New()\n\tmagics.write(h)\n\twriteString(h, kexDHReply.HostKey)\n\twriteInt(h, X)\n\twriteInt(h, kexDHReply.Y)\n\tK := make([]byte, intLength(ki))\n\tmarshalInt(K, ki)\n\th.Write(K)\n\n\treturn &kexResult{\n\t\tH:         h.Sum(nil),\n\t\tK:         K,\n\t\tHostKey:   kexDHReply.HostKey,\n\t\tSignature: kexDHReply.Signature,\n\t\tHash:      group.hashFunc,\n\t}, nil\n}\n\nfunc (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {\n\tpacket, err := c.readPacket()\n\tif err != nil {\n\t\treturn\n\t}\n\tvar kexDHInit kexDHInitMsg\n\tif err = Unmarshal(packet, &kexDHInit); err != nil {\n\t\treturn\n\t}\n\n\tvar y *big.Int\n\tfor {\n\t\tif y, err = rand.Int(randSource, group.pMinus1); err != nil {\n\t\t\treturn\n\t\t}\n\t\tif y.Sign() > 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tY := new(big.Int).Exp(group.g, y, group.p)\n\tki, err := group.diffieHellman(kexDHInit.X, y)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\thostKeyBytes := priv.PublicKey().Marshal()\n\n\th := group.hashFunc.New()\n\tmagics.write(h)\n\twriteString(h, hostKeyBytes)\n\twriteInt(h, kexDHInit.X)\n\twriteInt(h, Y)\n\n\tK := make([]byte, intLength(ki))\n\tmarshalInt(K, ki)\n\th.Write(K)\n\n\tH := h.Sum(nil)\n\n\t// H is already a hash, but the hostkey signing will apply its\n\t// own key-specific hash algorithm.\n\tsig, err := signAndMarshal(priv, randSource, H, algo)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tkexDHReply := kexDHReplyMsg{\n\t\tHostKey:   hostKeyBytes,\n\t\tY:         Y,\n\t\tSignature: sig,\n\t}\n\tpacket = Marshal(&kexDHReply)\n\n\terr = c.writePacket(packet)\n\treturn &kexResult{\n\t\tH:         H,\n\t\tK:         K,\n\t\tHostKey:   hostKeyBytes,\n\t\tSignature: sig,\n\t\tHash:      group.hashFunc,\n\t}, err\n}\n\n// ecdh performs Elliptic Curve Diffie-Hellman key exchange as\n// described in RFC 5656, section 4.\ntype ecdh struct {\n\tcurve elliptic.Curve\n}\n\nfunc (kex *ecdh) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) {\n\tephKey, err := ecdsa.GenerateKey(kex.curve, rand)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tkexInit := kexECDHInitMsg{\n\t\tClientPubKey: elliptic.Marshal(kex.curve, ephKey.PublicKey.X, ephKey.PublicKey.Y),\n\t}\n\n\tserialized := Marshal(&kexInit)\n\tif err := c.writePacket(serialized); err != nil {\n\t\treturn nil, err\n\t}\n\n\tpacket, err := c.readPacket()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar reply kexECDHReplyMsg\n\tif err = Unmarshal(packet, &reply); err != nil {\n\t\treturn nil, err\n\t}\n\n\tx, y, err := unmarshalECKey(kex.curve, reply.EphemeralPubKey)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// generate shared secret\n\tsecret, _ := kex.curve.ScalarMult(x, y, ephKey.D.Bytes())\n\n\th := ecHash(kex.curve).New()\n\tmagics.write(h)\n\twriteString(h, reply.HostKey)\n\twriteString(h, kexInit.ClientPubKey)\n\twriteString(h, reply.EphemeralPubKey)\n\tK := make([]byte, intLength(secret))\n\tmarshalInt(K, secret)\n\th.Write(K)\n\n\treturn &kexResult{\n\t\tH:         h.Sum(nil),\n\t\tK:         K,\n\t\tHostKey:   reply.HostKey,\n\t\tSignature: reply.Signature,\n\t\tHash:      ecHash(kex.curve),\n\t}, nil\n}\n\n// unmarshalECKey parses and checks an EC key.\nfunc unmarshalECKey(curve elliptic.Curve, pubkey []byte) (x, y *big.Int, err error) {\n\tx, y = elliptic.Unmarshal(curve, pubkey)\n\tif x == nil {\n\t\treturn nil, nil, errors.New(\"ssh: elliptic.Unmarshal failure\")\n\t}\n\tif !validateECPublicKey(curve, x, y) {\n\t\treturn nil, nil, errors.New(\"ssh: public key not on curve\")\n\t}\n\treturn x, y, nil\n}\n\n// validateECPublicKey checks that the point is a valid public key for\n// the given curve. See [SEC1], 3.2.2\nfunc validateECPublicKey(curve elliptic.Curve, x, y *big.Int) bool {\n\tif x.Sign() == 0 && y.Sign() == 0 {\n\t\treturn false\n\t}\n\n\tif x.Cmp(curve.Params().P) >= 0 {\n\t\treturn false\n\t}\n\n\tif y.Cmp(curve.Params().P) >= 0 {\n\t\treturn false\n\t}\n\n\tif !curve.IsOnCurve(x, y) {\n\t\treturn false\n\t}\n\n\t// We don't check if N * PubKey == 0, since\n\t//\n\t// - the NIST curves have cofactor = 1, so this is implicit.\n\t// (We don't foresee an implementation that supports non NIST\n\t// curves)\n\t//\n\t// - for ephemeral keys, we don't need to worry about small\n\t// subgroup attacks.\n\treturn true\n}\n\nfunc (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {\n\tpacket, err := c.readPacket()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar kexECDHInit kexECDHInitMsg\n\tif err = Unmarshal(packet, &kexECDHInit); err != nil {\n\t\treturn nil, err\n\t}\n\n\tclientX, clientY, err := unmarshalECKey(kex.curve, kexECDHInit.ClientPubKey)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// We could cache this key across multiple users/multiple\n\t// connection attempts, but the benefit is small. OpenSSH\n\t// generates a new key for each incoming connection.\n\tephKey, err := ecdsa.GenerateKey(kex.curve, rand)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\thostKeyBytes := priv.PublicKey().Marshal()\n\n\tserializedEphKey := elliptic.Marshal(kex.curve, ephKey.PublicKey.X, ephKey.PublicKey.Y)\n\n\t// generate shared secret\n\tsecret, _ := kex.curve.ScalarMult(clientX, clientY, ephKey.D.Bytes())\n\n\th := ecHash(kex.curve).New()\n\tmagics.write(h)\n\twriteString(h, hostKeyBytes)\n\twriteString(h, kexECDHInit.ClientPubKey)\n\twriteString(h, serializedEphKey)\n\n\tK := make([]byte, intLength(secret))\n\tmarshalInt(K, secret)\n\th.Write(K)\n\n\tH := h.Sum(nil)\n\n\t// H is already a hash, but the hostkey signing will apply its\n\t// own key-specific hash algorithm.\n\tsig, err := signAndMarshal(priv, rand, H, algo)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treply := kexECDHReplyMsg{\n\t\tEphemeralPubKey: serializedEphKey,\n\t\tHostKey:         hostKeyBytes,\n\t\tSignature:       sig,\n\t}\n\n\tserialized := Marshal(&reply)\n\tif err := c.writePacket(serialized); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &kexResult{\n\t\tH:         H,\n\t\tK:         K,\n\t\tHostKey:   reply.HostKey,\n\t\tSignature: sig,\n\t\tHash:      ecHash(kex.curve),\n\t}, nil\n}\n\n// ecHash returns the hash to match the given elliptic curve, see RFC\n// 5656, section 6.2.1\nfunc ecHash(curve elliptic.Curve) crypto.Hash {\n\tbitSize := curve.Params().BitSize\n\tswitch {\n\tcase bitSize <= 256:\n\t\treturn crypto.SHA256\n\tcase bitSize <= 384:\n\t\treturn crypto.SHA384\n\t}\n\treturn crypto.SHA512\n}\n\nvar kexAlgoMap = map[string]kexAlgorithm{}\n\nfunc init() {\n\t// This is the group called diffie-hellman-group1-sha1 in\n\t// RFC 4253 and Oakley Group 2 in RFC 2409.\n\tp, _ := new(big.Int).SetString(\"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF\", 16)\n\tkexAlgoMap[kexAlgoDH1SHA1] = &dhGroup{\n\t\tg:        new(big.Int).SetInt64(2),\n\t\tp:        p,\n\t\tpMinus1:  new(big.Int).Sub(p, bigOne),\n\t\thashFunc: crypto.SHA1,\n\t}\n\n\t// This are the groups called diffie-hellman-group14-sha1 and\n\t// diffie-hellman-group14-sha256 in RFC 4253 and RFC 8268,\n\t// and Oakley Group 14 in RFC 3526.\n\tp, _ = new(big.Int).SetString(\"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF\", 16)\n\tgroup14 := &dhGroup{\n\t\tg:       new(big.Int).SetInt64(2),\n\t\tp:       p,\n\t\tpMinus1: new(big.Int).Sub(p, bigOne),\n\t}\n\n\tkexAlgoMap[kexAlgoDH14SHA1] = &dhGroup{\n\t\tg: group14.g, p: group14.p, pMinus1: group14.pMinus1,\n\t\thashFunc: crypto.SHA1,\n\t}\n\tkexAlgoMap[kexAlgoDH14SHA256] = &dhGroup{\n\t\tg: group14.g, p: group14.p, pMinus1: group14.pMinus1,\n\t\thashFunc: crypto.SHA256,\n\t}\n\n\t// This is the group called diffie-hellman-group16-sha512 in RFC\n\t// 8268 and Oakley Group 16 in RFC 3526.\n\tp, _ = new(big.Int).SetString(\"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF\", 16)\n\n\tkexAlgoMap[kexAlgoDH16SHA512] = &dhGroup{\n\t\tg:        new(big.Int).SetInt64(2),\n\t\tp:        p,\n\t\tpMinus1:  new(big.Int).Sub(p, bigOne),\n\t\thashFunc: crypto.SHA512,\n\t}\n\n\tkexAlgoMap[kexAlgoECDH521] = &ecdh{elliptic.P521()}\n\tkexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()}\n\tkexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()}\n\tkexAlgoMap[kexAlgoCurve25519SHA256] = &curve25519sha256{}\n\tkexAlgoMap[kexAlgoCurve25519SHA256LibSSH] = &curve25519sha256{}\n\tkexAlgoMap[kexAlgoDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1}\n\tkexAlgoMap[kexAlgoDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256}\n}\n\n// curve25519sha256 implements the curve25519-sha256 (formerly known as\n// curve25519-sha256@libssh.org) key exchange method, as described in RFC 8731.\ntype curve25519sha256 struct{}\n\ntype curve25519KeyPair struct {\n\tpriv [32]byte\n\tpub  [32]byte\n}\n\nfunc (kp *curve25519KeyPair) generate(rand io.Reader) error {\n\tif _, err := io.ReadFull(rand, kp.priv[:]); err != nil {\n\t\treturn err\n\t}\n\tcurve25519.ScalarBaseMult(&kp.pub, &kp.priv)\n\treturn nil\n}\n\n// curve25519Zeros is just an array of 32 zero bytes so that we have something\n// convenient to compare against in order to reject curve25519 points with the\n// wrong order.\nvar curve25519Zeros [32]byte\n\nfunc (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) {\n\tvar kp curve25519KeyPair\n\tif err := kp.generate(rand); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := c.writePacket(Marshal(&kexECDHInitMsg{kp.pub[:]})); err != nil {\n\t\treturn nil, err\n\t}\n\n\tpacket, err := c.readPacket()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar reply kexECDHReplyMsg\n\tif err = Unmarshal(packet, &reply); err != nil {\n\t\treturn nil, err\n\t}\n\tif len(reply.EphemeralPubKey) != 32 {\n\t\treturn nil, errors.New(\"ssh: peer's curve25519 public value has wrong length\")\n\t}\n\n\tvar servPub, secret [32]byte\n\tcopy(servPub[:], reply.EphemeralPubKey)\n\tcurve25519.ScalarMult(&secret, &kp.priv, &servPub)\n\tif subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 {\n\t\treturn nil, errors.New(\"ssh: peer's curve25519 public value has wrong order\")\n\t}\n\n\th := crypto.SHA256.New()\n\tmagics.write(h)\n\twriteString(h, reply.HostKey)\n\twriteString(h, kp.pub[:])\n\twriteString(h, reply.EphemeralPubKey)\n\n\tki := new(big.Int).SetBytes(secret[:])\n\tK := make([]byte, intLength(ki))\n\tmarshalInt(K, ki)\n\th.Write(K)\n\n\treturn &kexResult{\n\t\tH:         h.Sum(nil),\n\t\tK:         K,\n\t\tHostKey:   reply.HostKey,\n\t\tSignature: reply.Signature,\n\t\tHash:      crypto.SHA256,\n\t}, nil\n}\n\nfunc (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {\n\tpacket, err := c.readPacket()\n\tif err != nil {\n\t\treturn\n\t}\n\tvar kexInit kexECDHInitMsg\n\tif err = Unmarshal(packet, &kexInit); err != nil {\n\t\treturn\n\t}\n\n\tif len(kexInit.ClientPubKey) != 32 {\n\t\treturn nil, errors.New(\"ssh: peer's curve25519 public value has wrong length\")\n\t}\n\n\tvar kp curve25519KeyPair\n\tif err := kp.generate(rand); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar clientPub, secret [32]byte\n\tcopy(clientPub[:], kexInit.ClientPubKey)\n\tcurve25519.ScalarMult(&secret, &kp.priv, &clientPub)\n\tif subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 {\n\t\treturn nil, errors.New(\"ssh: peer's curve25519 public value has wrong order\")\n\t}\n\n\thostKeyBytes := priv.PublicKey().Marshal()\n\n\th := crypto.SHA256.New()\n\tmagics.write(h)\n\twriteString(h, hostKeyBytes)\n\twriteString(h, kexInit.ClientPubKey)\n\twriteString(h, kp.pub[:])\n\n\tki := new(big.Int).SetBytes(secret[:])\n\tK := make([]byte, intLength(ki))\n\tmarshalInt(K, ki)\n\th.Write(K)\n\n\tH := h.Sum(nil)\n\n\tsig, err := signAndMarshal(priv, rand, H, algo)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treply := kexECDHReplyMsg{\n\t\tEphemeralPubKey: kp.pub[:],\n\t\tHostKey:         hostKeyBytes,\n\t\tSignature:       sig,\n\t}\n\tif err := c.writePacket(Marshal(&reply)); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &kexResult{\n\t\tH:         H,\n\t\tK:         K,\n\t\tHostKey:   hostKeyBytes,\n\t\tSignature: sig,\n\t\tHash:      crypto.SHA256,\n\t}, nil\n}\n\n// dhGEXSHA implements the diffie-hellman-group-exchange-sha1 and\n// diffie-hellman-group-exchange-sha256 key agreement protocols,\n// as described in RFC 4419\ntype dhGEXSHA struct {\n\thashFunc crypto.Hash\n}\n\nconst (\n\tdhGroupExchangeMinimumBits   = 2048\n\tdhGroupExchangePreferredBits = 2048\n\tdhGroupExchangeMaximumBits   = 8192\n)\n\nfunc (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {\n\t// Send GexRequest\n\tkexDHGexRequest := kexDHGexRequestMsg{\n\t\tMinBits:      dhGroupExchangeMinimumBits,\n\t\tPreferedBits: dhGroupExchangePreferredBits,\n\t\tMaxBits:      dhGroupExchangeMaximumBits,\n\t}\n\tif err := c.writePacket(Marshal(&kexDHGexRequest)); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Receive GexGroup\n\tpacket, err := c.readPacket()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar msg kexDHGexGroupMsg\n\tif err = Unmarshal(packet, &msg); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// reject if p's bit length < dhGroupExchangeMinimumBits or > dhGroupExchangeMaximumBits\n\tif msg.P.BitLen() < dhGroupExchangeMinimumBits || msg.P.BitLen() > dhGroupExchangeMaximumBits {\n\t\treturn nil, fmt.Errorf(\"ssh: server-generated gex p is out of range (%d bits)\", msg.P.BitLen())\n\t}\n\n\t// Check if g is safe by verifying that 1 < g < p-1\n\tpMinusOne := new(big.Int).Sub(msg.P, bigOne)\n\tif msg.G.Cmp(bigOne) <= 0 || msg.G.Cmp(pMinusOne) >= 0 {\n\t\treturn nil, fmt.Errorf(\"ssh: server provided gex g is not safe\")\n\t}\n\n\t// Send GexInit\n\tpHalf := new(big.Int).Rsh(msg.P, 1)\n\tx, err := rand.Int(randSource, pHalf)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tX := new(big.Int).Exp(msg.G, x, msg.P)\n\tkexDHGexInit := kexDHGexInitMsg{\n\t\tX: X,\n\t}\n\tif err := c.writePacket(Marshal(&kexDHGexInit)); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Receive GexReply\n\tpacket, err = c.readPacket()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar kexDHGexReply kexDHGexReplyMsg\n\tif err = Unmarshal(packet, &kexDHGexReply); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif kexDHGexReply.Y.Cmp(bigOne) <= 0 || kexDHGexReply.Y.Cmp(pMinusOne) >= 0 {\n\t\treturn nil, errors.New(\"ssh: DH parameter out of bounds\")\n\t}\n\tkInt := new(big.Int).Exp(kexDHGexReply.Y, x, msg.P)\n\n\t// Check if k is safe by verifying that k > 1 and k < p - 1\n\tif kInt.Cmp(bigOne) <= 0 || kInt.Cmp(pMinusOne) >= 0 {\n\t\treturn nil, fmt.Errorf(\"ssh: derived k is not safe\")\n\t}\n\n\th := gex.hashFunc.New()\n\tmagics.write(h)\n\twriteString(h, kexDHGexReply.HostKey)\n\tbinary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMinimumBits))\n\tbinary.Write(h, binary.BigEndian, uint32(dhGroupExchangePreferredBits))\n\tbinary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMaximumBits))\n\twriteInt(h, msg.P)\n\twriteInt(h, msg.G)\n\twriteInt(h, X)\n\twriteInt(h, kexDHGexReply.Y)\n\tK := make([]byte, intLength(kInt))\n\tmarshalInt(K, kInt)\n\th.Write(K)\n\n\treturn &kexResult{\n\t\tH:         h.Sum(nil),\n\t\tK:         K,\n\t\tHostKey:   kexDHGexReply.HostKey,\n\t\tSignature: kexDHGexReply.Signature,\n\t\tHash:      gex.hashFunc,\n\t}, nil\n}\n\n// Server half implementation of the Diffie Hellman Key Exchange with SHA1 and SHA256.\n//\n// This is a minimal implementation to satisfy the automated tests.\nfunc (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {\n\t// Receive GexRequest\n\tpacket, err := c.readPacket()\n\tif err != nil {\n\t\treturn\n\t}\n\tvar kexDHGexRequest kexDHGexRequestMsg\n\tif err = Unmarshal(packet, &kexDHGexRequest); err != nil {\n\t\treturn\n\t}\n\n\t// Send GexGroup\n\t// This is the group called diffie-hellman-group14-sha1 in RFC\n\t// 4253 and Oakley Group 14 in RFC 3526.\n\tp, _ := new(big.Int).SetString(\"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF\", 16)\n\tg := big.NewInt(2)\n\n\tmsg := &kexDHGexGroupMsg{\n\t\tP: p,\n\t\tG: g,\n\t}\n\tif err := c.writePacket(Marshal(msg)); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Receive GexInit\n\tpacket, err = c.readPacket()\n\tif err != nil {\n\t\treturn\n\t}\n\tvar kexDHGexInit kexDHGexInitMsg\n\tif err = Unmarshal(packet, &kexDHGexInit); err != nil {\n\t\treturn\n\t}\n\n\tpHalf := new(big.Int).Rsh(p, 1)\n\n\ty, err := rand.Int(randSource, pHalf)\n\tif err != nil {\n\t\treturn\n\t}\n\tY := new(big.Int).Exp(g, y, p)\n\n\tpMinusOne := new(big.Int).Sub(p, bigOne)\n\tif kexDHGexInit.X.Cmp(bigOne) <= 0 || kexDHGexInit.X.Cmp(pMinusOne) >= 0 {\n\t\treturn nil, errors.New(\"ssh: DH parameter out of bounds\")\n\t}\n\tkInt := new(big.Int).Exp(kexDHGexInit.X, y, p)\n\n\thostKeyBytes := priv.PublicKey().Marshal()\n\n\th := gex.hashFunc.New()\n\tmagics.write(h)\n\twriteString(h, hostKeyBytes)\n\tbinary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMinimumBits))\n\tbinary.Write(h, binary.BigEndian, uint32(dhGroupExchangePreferredBits))\n\tbinary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMaximumBits))\n\twriteInt(h, p)\n\twriteInt(h, g)\n\twriteInt(h, kexDHGexInit.X)\n\twriteInt(h, Y)\n\n\tK := make([]byte, intLength(kInt))\n\tmarshalInt(K, kInt)\n\th.Write(K)\n\n\tH := h.Sum(nil)\n\n\t// H is already a hash, but the hostkey signing will apply its\n\t// own key-specific hash algorithm.\n\tsig, err := signAndMarshal(priv, randSource, H, algo)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tkexDHGexReply := kexDHGexReplyMsg{\n\t\tHostKey:   hostKeyBytes,\n\t\tY:         Y,\n\t\tSignature: sig,\n\t}\n\tpacket = Marshal(&kexDHGexReply)\n\n\terr = c.writePacket(packet)\n\n\treturn &kexResult{\n\t\tH:         H,\n\t\tK:         K,\n\t\tHostKey:   hostKeyBytes,\n\t\tSignature: sig,\n\t\tHash:      gex.hashFunc,\n\t}, err\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/keys.go",
    "content": "// Copyright 2012 The Go 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 ssh\n\nimport (\n\t\"bytes\"\n\t\"crypto\"\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"crypto/dsa\"\n\t\"crypto/ecdsa\"\n\t\"crypto/ed25519\"\n\t\"crypto/elliptic\"\n\t\"crypto/md5\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/sha256\"\n\t\"crypto/x509\"\n\t\"encoding/asn1\"\n\t\"encoding/base64\"\n\t\"encoding/binary\"\n\t\"encoding/hex\"\n\t\"encoding/pem\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/big\"\n\t\"strings\"\n\n\t\"golang.org/x/crypto/ssh/internal/bcrypt_pbkdf\"\n)\n\n// Public key algorithms names. These values can appear in PublicKey.Type,\n// ClientConfig.HostKeyAlgorithms, Signature.Format, or as AlgorithmSigner\n// arguments.\nconst (\n\tKeyAlgoRSA        = \"ssh-rsa\"\n\tKeyAlgoDSA        = \"ssh-dss\"\n\tKeyAlgoECDSA256   = \"ecdsa-sha2-nistp256\"\n\tKeyAlgoSKECDSA256 = \"sk-ecdsa-sha2-nistp256@openssh.com\"\n\tKeyAlgoECDSA384   = \"ecdsa-sha2-nistp384\"\n\tKeyAlgoECDSA521   = \"ecdsa-sha2-nistp521\"\n\tKeyAlgoED25519    = \"ssh-ed25519\"\n\tKeyAlgoSKED25519  = \"sk-ssh-ed25519@openssh.com\"\n\n\t// KeyAlgoRSASHA256 and KeyAlgoRSASHA512 are only public key algorithms, not\n\t// public key formats, so they can't appear as a PublicKey.Type. The\n\t// corresponding PublicKey.Type is KeyAlgoRSA. See RFC 8332, Section 2.\n\tKeyAlgoRSASHA256 = \"rsa-sha2-256\"\n\tKeyAlgoRSASHA512 = \"rsa-sha2-512\"\n)\n\nconst (\n\t// Deprecated: use KeyAlgoRSA.\n\tSigAlgoRSA = KeyAlgoRSA\n\t// Deprecated: use KeyAlgoRSASHA256.\n\tSigAlgoRSASHA2256 = KeyAlgoRSASHA256\n\t// Deprecated: use KeyAlgoRSASHA512.\n\tSigAlgoRSASHA2512 = KeyAlgoRSASHA512\n)\n\n// parsePubKey parses a public key of the given algorithm.\n// Use ParsePublicKey for keys with prepended algorithm.\nfunc parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err error) {\n\tswitch algo {\n\tcase KeyAlgoRSA:\n\t\treturn parseRSA(in)\n\tcase KeyAlgoDSA:\n\t\treturn parseDSA(in)\n\tcase KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:\n\t\treturn parseECDSA(in)\n\tcase KeyAlgoSKECDSA256:\n\t\treturn parseSKECDSA(in)\n\tcase KeyAlgoED25519:\n\t\treturn parseED25519(in)\n\tcase KeyAlgoSKED25519:\n\t\treturn parseSKEd25519(in)\n\tcase CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01:\n\t\tcert, err := parseCert(in, certKeyAlgoNames[algo])\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t\treturn cert, nil, nil\n\t}\n\treturn nil, nil, fmt.Errorf(\"ssh: unknown key algorithm: %v\", algo)\n}\n\n// parseAuthorizedKey parses a public key in OpenSSH authorized_keys format\n// (see sshd(8) manual page) once the options and key type fields have been\n// removed.\nfunc parseAuthorizedKey(in []byte) (out PublicKey, comment string, err error) {\n\tin = bytes.TrimSpace(in)\n\n\ti := bytes.IndexAny(in, \" \\t\")\n\tif i == -1 {\n\t\ti = len(in)\n\t}\n\tbase64Key := in[:i]\n\n\tkey := make([]byte, base64.StdEncoding.DecodedLen(len(base64Key)))\n\tn, err := base64.StdEncoding.Decode(key, base64Key)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\tkey = key[:n]\n\tout, err = ParsePublicKey(key)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\tcomment = string(bytes.TrimSpace(in[i:]))\n\treturn out, comment, nil\n}\n\n// ParseKnownHosts parses an entry in the format of the known_hosts file.\n//\n// The known_hosts format is documented in the sshd(8) manual page. This\n// function will parse a single entry from in. On successful return, marker\n// will contain the optional marker value (i.e. \"cert-authority\" or \"revoked\")\n// or else be empty, hosts will contain the hosts that this entry matches,\n// pubKey will contain the public key and comment will contain any trailing\n// comment at the end of the line. See the sshd(8) manual page for the various\n// forms that a host string can take.\n//\n// The unparsed remainder of the input will be returned in rest. This function\n// can be called repeatedly to parse multiple entries.\n//\n// If no entries were found in the input then err will be io.EOF. Otherwise a\n// non-nil err value indicates a parse error.\nfunc ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey, comment string, rest []byte, err error) {\n\tfor len(in) > 0 {\n\t\tend := bytes.IndexByte(in, '\\n')\n\t\tif end != -1 {\n\t\t\trest = in[end+1:]\n\t\t\tin = in[:end]\n\t\t} else {\n\t\t\trest = nil\n\t\t}\n\n\t\tend = bytes.IndexByte(in, '\\r')\n\t\tif end != -1 {\n\t\t\tin = in[:end]\n\t\t}\n\n\t\tin = bytes.TrimSpace(in)\n\t\tif len(in) == 0 || in[0] == '#' {\n\t\t\tin = rest\n\t\t\tcontinue\n\t\t}\n\n\t\ti := bytes.IndexAny(in, \" \\t\")\n\t\tif i == -1 {\n\t\t\tin = rest\n\t\t\tcontinue\n\t\t}\n\n\t\t// Strip out the beginning of the known_host key.\n\t\t// This is either an optional marker or a (set of) hostname(s).\n\t\tkeyFields := bytes.Fields(in)\n\t\tif len(keyFields) < 3 || len(keyFields) > 5 {\n\t\t\treturn \"\", nil, nil, \"\", nil, errors.New(\"ssh: invalid entry in known_hosts data\")\n\t\t}\n\n\t\t// keyFields[0] is either \"@cert-authority\", \"@revoked\" or a comma separated\n\t\t// list of hosts\n\t\tmarker := \"\"\n\t\tif keyFields[0][0] == '@' {\n\t\t\tmarker = string(keyFields[0][1:])\n\t\t\tkeyFields = keyFields[1:]\n\t\t}\n\n\t\thosts := string(keyFields[0])\n\t\t// keyFields[1] contains the key type (e.g. “ssh-rsa”).\n\t\t// However, that information is duplicated inside the\n\t\t// base64-encoded key and so is ignored here.\n\n\t\tkey := bytes.Join(keyFields[2:], []byte(\" \"))\n\t\tif pubKey, comment, err = parseAuthorizedKey(key); err != nil {\n\t\t\treturn \"\", nil, nil, \"\", nil, err\n\t\t}\n\n\t\treturn marker, strings.Split(hosts, \",\"), pubKey, comment, rest, nil\n\t}\n\n\treturn \"\", nil, nil, \"\", nil, io.EOF\n}\n\n// ParseAuthorizedKey parses a public key from an authorized_keys\n// file used in OpenSSH according to the sshd(8) manual page.\nfunc ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) {\n\tfor len(in) > 0 {\n\t\tend := bytes.IndexByte(in, '\\n')\n\t\tif end != -1 {\n\t\t\trest = in[end+1:]\n\t\t\tin = in[:end]\n\t\t} else {\n\t\t\trest = nil\n\t\t}\n\n\t\tend = bytes.IndexByte(in, '\\r')\n\t\tif end != -1 {\n\t\t\tin = in[:end]\n\t\t}\n\n\t\tin = bytes.TrimSpace(in)\n\t\tif len(in) == 0 || in[0] == '#' {\n\t\t\tin = rest\n\t\t\tcontinue\n\t\t}\n\n\t\ti := bytes.IndexAny(in, \" \\t\")\n\t\tif i == -1 {\n\t\t\tin = rest\n\t\t\tcontinue\n\t\t}\n\n\t\tif out, comment, err = parseAuthorizedKey(in[i:]); err == nil {\n\t\t\treturn out, comment, options, rest, nil\n\t\t}\n\n\t\t// No key type recognised. Maybe there's an options field at\n\t\t// the beginning.\n\t\tvar b byte\n\t\tinQuote := false\n\t\tvar candidateOptions []string\n\t\toptionStart := 0\n\t\tfor i, b = range in {\n\t\t\tisEnd := !inQuote && (b == ' ' || b == '\\t')\n\t\t\tif (b == ',' && !inQuote) || isEnd {\n\t\t\t\tif i-optionStart > 0 {\n\t\t\t\t\tcandidateOptions = append(candidateOptions, string(in[optionStart:i]))\n\t\t\t\t}\n\t\t\t\toptionStart = i + 1\n\t\t\t}\n\t\t\tif isEnd {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif b == '\"' && (i == 0 || (i > 0 && in[i-1] != '\\\\')) {\n\t\t\t\tinQuote = !inQuote\n\t\t\t}\n\t\t}\n\t\tfor i < len(in) && (in[i] == ' ' || in[i] == '\\t') {\n\t\t\ti++\n\t\t}\n\t\tif i == len(in) {\n\t\t\t// Invalid line: unmatched quote\n\t\t\tin = rest\n\t\t\tcontinue\n\t\t}\n\n\t\tin = in[i:]\n\t\ti = bytes.IndexAny(in, \" \\t\")\n\t\tif i == -1 {\n\t\t\tin = rest\n\t\t\tcontinue\n\t\t}\n\n\t\tif out, comment, err = parseAuthorizedKey(in[i:]); err == nil {\n\t\t\toptions = candidateOptions\n\t\t\treturn out, comment, options, rest, nil\n\t\t}\n\n\t\tin = rest\n\t\tcontinue\n\t}\n\n\treturn nil, \"\", nil, nil, errors.New(\"ssh: no key found\")\n}\n\n// ParsePublicKey parses an SSH public key formatted for use in\n// the SSH wire protocol according to RFC 4253, section 6.6.\nfunc ParsePublicKey(in []byte) (out PublicKey, err error) {\n\talgo, in, ok := parseString(in)\n\tif !ok {\n\t\treturn nil, errShortRead\n\t}\n\tvar rest []byte\n\tout, rest, err = parsePubKey(in, string(algo))\n\tif len(rest) > 0 {\n\t\treturn nil, errors.New(\"ssh: trailing junk in public key\")\n\t}\n\n\treturn out, err\n}\n\n// MarshalAuthorizedKey serializes key for inclusion in an OpenSSH\n// authorized_keys file. The return value ends with newline.\nfunc MarshalAuthorizedKey(key PublicKey) []byte {\n\tb := &bytes.Buffer{}\n\tb.WriteString(key.Type())\n\tb.WriteByte(' ')\n\te := base64.NewEncoder(base64.StdEncoding, b)\n\te.Write(key.Marshal())\n\te.Close()\n\tb.WriteByte('\\n')\n\treturn b.Bytes()\n}\n\n// MarshalPrivateKey returns a PEM block with the private key serialized in the\n// OpenSSH format.\nfunc MarshalPrivateKey(key crypto.PrivateKey, comment string) (*pem.Block, error) {\n\treturn marshalOpenSSHPrivateKey(key, comment, unencryptedOpenSSHMarshaler)\n}\n\n// MarshalPrivateKeyWithPassphrase returns a PEM block holding the encrypted\n// private key serialized in the OpenSSH format.\nfunc MarshalPrivateKeyWithPassphrase(key crypto.PrivateKey, comment string, passphrase []byte) (*pem.Block, error) {\n\treturn marshalOpenSSHPrivateKey(key, comment, passphraseProtectedOpenSSHMarshaler(passphrase))\n}\n\n// PublicKey represents a public key using an unspecified algorithm.\n//\n// Some PublicKeys provided by this package also implement CryptoPublicKey.\ntype PublicKey interface {\n\t// Type returns the key format name, e.g. \"ssh-rsa\".\n\tType() string\n\n\t// Marshal returns the serialized key data in SSH wire format, with the name\n\t// prefix. To unmarshal the returned data, use the ParsePublicKey function.\n\tMarshal() []byte\n\n\t// Verify that sig is a signature on the given data using this key. This\n\t// method will hash the data appropriately first. sig.Format is allowed to\n\t// be any signature algorithm compatible with the key type, the caller\n\t// should check if it has more stringent requirements.\n\tVerify(data []byte, sig *Signature) error\n}\n\n// CryptoPublicKey, if implemented by a PublicKey,\n// returns the underlying crypto.PublicKey form of the key.\ntype CryptoPublicKey interface {\n\tCryptoPublicKey() crypto.PublicKey\n}\n\n// A Signer can create signatures that verify against a public key.\n//\n// Some Signers provided by this package also implement MultiAlgorithmSigner.\ntype Signer interface {\n\t// PublicKey returns the associated PublicKey.\n\tPublicKey() PublicKey\n\n\t// Sign returns a signature for the given data. This method will hash the\n\t// data appropriately first. The signature algorithm is expected to match\n\t// the key format returned by the PublicKey.Type method (and not to be any\n\t// alternative algorithm supported by the key format).\n\tSign(rand io.Reader, data []byte) (*Signature, error)\n}\n\n// An AlgorithmSigner is a Signer that also supports specifying an algorithm to\n// use for signing.\n//\n// An AlgorithmSigner can't advertise the algorithms it supports, unless it also\n// implements MultiAlgorithmSigner, so it should be prepared to be invoked with\n// every algorithm supported by the public key format.\ntype AlgorithmSigner interface {\n\tSigner\n\n\t// SignWithAlgorithm is like Signer.Sign, but allows specifying a desired\n\t// signing algorithm. Callers may pass an empty string for the algorithm in\n\t// which case the AlgorithmSigner will use a default algorithm. This default\n\t// doesn't currently control any behavior in this package.\n\tSignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error)\n}\n\n// MultiAlgorithmSigner is an AlgorithmSigner that also reports the algorithms\n// supported by that signer.\ntype MultiAlgorithmSigner interface {\n\tAlgorithmSigner\n\n\t// Algorithms returns the available algorithms in preference order. The list\n\t// must not be empty, and it must not include certificate types.\n\tAlgorithms() []string\n}\n\n// NewSignerWithAlgorithms returns a signer restricted to the specified\n// algorithms. The algorithms must be set in preference order. The list must not\n// be empty, and it must not include certificate types. An error is returned if\n// the specified algorithms are incompatible with the public key type.\nfunc NewSignerWithAlgorithms(signer AlgorithmSigner, algorithms []string) (MultiAlgorithmSigner, error) {\n\tif len(algorithms) == 0 {\n\t\treturn nil, errors.New(\"ssh: please specify at least one valid signing algorithm\")\n\t}\n\tvar signerAlgos []string\n\tsupportedAlgos := algorithmsForKeyFormat(underlyingAlgo(signer.PublicKey().Type()))\n\tif s, ok := signer.(*multiAlgorithmSigner); ok {\n\t\tsignerAlgos = s.Algorithms()\n\t} else {\n\t\tsignerAlgos = supportedAlgos\n\t}\n\n\tfor _, algo := range algorithms {\n\t\tif !contains(supportedAlgos, algo) {\n\t\t\treturn nil, fmt.Errorf(\"ssh: algorithm %q is not supported for key type %q\",\n\t\t\t\talgo, signer.PublicKey().Type())\n\t\t}\n\t\tif !contains(signerAlgos, algo) {\n\t\t\treturn nil, fmt.Errorf(\"ssh: algorithm %q is restricted for the provided signer\", algo)\n\t\t}\n\t}\n\treturn &multiAlgorithmSigner{\n\t\tAlgorithmSigner:     signer,\n\t\tsupportedAlgorithms: algorithms,\n\t}, nil\n}\n\ntype multiAlgorithmSigner struct {\n\tAlgorithmSigner\n\tsupportedAlgorithms []string\n}\n\nfunc (s *multiAlgorithmSigner) Algorithms() []string {\n\treturn s.supportedAlgorithms\n}\n\nfunc (s *multiAlgorithmSigner) isAlgorithmSupported(algorithm string) bool {\n\tif algorithm == \"\" {\n\t\talgorithm = underlyingAlgo(s.PublicKey().Type())\n\t}\n\tfor _, algo := range s.supportedAlgorithms {\n\t\tif algorithm == algo {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (s *multiAlgorithmSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {\n\tif !s.isAlgorithmSupported(algorithm) {\n\t\treturn nil, fmt.Errorf(\"ssh: algorithm %q is not supported: %v\", algorithm, s.supportedAlgorithms)\n\t}\n\treturn s.AlgorithmSigner.SignWithAlgorithm(rand, data, algorithm)\n}\n\ntype rsaPublicKey rsa.PublicKey\n\nfunc (r *rsaPublicKey) Type() string {\n\treturn \"ssh-rsa\"\n}\n\n// parseRSA parses an RSA key according to RFC 4253, section 6.6.\nfunc parseRSA(in []byte) (out PublicKey, rest []byte, err error) {\n\tvar w struct {\n\t\tE    *big.Int\n\t\tN    *big.Int\n\t\tRest []byte `ssh:\"rest\"`\n\t}\n\tif err := Unmarshal(in, &w); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tif w.E.BitLen() > 24 {\n\t\treturn nil, nil, errors.New(\"ssh: exponent too large\")\n\t}\n\te := w.E.Int64()\n\tif e < 3 || e&1 == 0 {\n\t\treturn nil, nil, errors.New(\"ssh: incorrect exponent\")\n\t}\n\n\tvar key rsa.PublicKey\n\tkey.E = int(e)\n\tkey.N = w.N\n\treturn (*rsaPublicKey)(&key), w.Rest, nil\n}\n\nfunc (r *rsaPublicKey) Marshal() []byte {\n\te := new(big.Int).SetInt64(int64(r.E))\n\t// RSA publickey struct layout should match the struct used by\n\t// parseRSACert in the x/crypto/ssh/agent package.\n\twirekey := struct {\n\t\tName string\n\t\tE    *big.Int\n\t\tN    *big.Int\n\t}{\n\t\tKeyAlgoRSA,\n\t\te,\n\t\tr.N,\n\t}\n\treturn Marshal(&wirekey)\n}\n\nfunc (r *rsaPublicKey) Verify(data []byte, sig *Signature) error {\n\tsupportedAlgos := algorithmsForKeyFormat(r.Type())\n\tif !contains(supportedAlgos, sig.Format) {\n\t\treturn fmt.Errorf(\"ssh: signature type %s for key type %s\", sig.Format, r.Type())\n\t}\n\thash := hashFuncs[sig.Format]\n\th := hash.New()\n\th.Write(data)\n\tdigest := h.Sum(nil)\n\n\t// Signatures in PKCS1v15 must match the key's modulus in\n\t// length. However with SSH, some signers provide RSA\n\t// signatures which are missing the MSB 0's of the bignum\n\t// represented. With ssh-rsa signatures, this is encouraged by\n\t// the spec (even though e.g. OpenSSH will give the full\n\t// length unconditionally). With rsa-sha2-* signatures, the\n\t// verifier is allowed to support these, even though they are\n\t// out of spec. See RFC 4253 Section 6.6 for ssh-rsa and RFC\n\t// 8332 Section 3 for rsa-sha2-* details.\n\t//\n\t// In practice:\n\t// * OpenSSH always allows \"short\" signatures:\n\t//   https://github.com/openssh/openssh-portable/blob/V_9_8_P1/ssh-rsa.c#L526\n\t//   but always generates padded signatures:\n\t//   https://github.com/openssh/openssh-portable/blob/V_9_8_P1/ssh-rsa.c#L439\n\t//\n\t// * PuTTY versions 0.81 and earlier will generate short\n\t//   signatures for all RSA signature variants. Note that\n\t//   PuTTY is embedded in other software, such as WinSCP and\n\t//   FileZilla. At the time of writing, a patch has been\n\t//   applied to PuTTY to generate padded signatures for\n\t//   rsa-sha2-*, but not yet released:\n\t//   https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=a5bcf3d384e1bf15a51a6923c3724cbbee022d8e\n\t//\n\t// * SSH.NET versions 2024.0.0 and earlier will generate short\n\t//   signatures for all RSA signature variants, fixed in 2024.1.0:\n\t//   https://github.com/sshnet/SSH.NET/releases/tag/2024.1.0\n\t//\n\t// As a result, we pad these up to the key size by inserting\n\t// leading 0's.\n\t//\n\t// Note that support for short signatures with rsa-sha2-* may\n\t// be removed in the future due to such signatures not being\n\t// allowed by the spec.\n\tblob := sig.Blob\n\tkeySize := (*rsa.PublicKey)(r).Size()\n\tif len(blob) < keySize {\n\t\tpadded := make([]byte, keySize)\n\t\tcopy(padded[keySize-len(blob):], blob)\n\t\tblob = padded\n\t}\n\treturn rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), hash, digest, blob)\n}\n\nfunc (r *rsaPublicKey) CryptoPublicKey() crypto.PublicKey {\n\treturn (*rsa.PublicKey)(r)\n}\n\ntype dsaPublicKey dsa.PublicKey\n\nfunc (k *dsaPublicKey) Type() string {\n\treturn \"ssh-dss\"\n}\n\nfunc checkDSAParams(param *dsa.Parameters) error {\n\t// SSH specifies FIPS 186-2, which only provided a single size\n\t// (1024 bits) DSA key. FIPS 186-3 allows for larger key\n\t// sizes, which would confuse SSH.\n\tif l := param.P.BitLen(); l != 1024 {\n\t\treturn fmt.Errorf(\"ssh: unsupported DSA key size %d\", l)\n\t}\n\n\treturn nil\n}\n\n// parseDSA parses an DSA key according to RFC 4253, section 6.6.\nfunc parseDSA(in []byte) (out PublicKey, rest []byte, err error) {\n\tvar w struct {\n\t\tP, Q, G, Y *big.Int\n\t\tRest       []byte `ssh:\"rest\"`\n\t}\n\tif err := Unmarshal(in, &w); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tparam := dsa.Parameters{\n\t\tP: w.P,\n\t\tQ: w.Q,\n\t\tG: w.G,\n\t}\n\tif err := checkDSAParams(&param); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tkey := &dsaPublicKey{\n\t\tParameters: param,\n\t\tY:          w.Y,\n\t}\n\treturn key, w.Rest, nil\n}\n\nfunc (k *dsaPublicKey) Marshal() []byte {\n\t// DSA publickey struct layout should match the struct used by\n\t// parseDSACert in the x/crypto/ssh/agent package.\n\tw := struct {\n\t\tName       string\n\t\tP, Q, G, Y *big.Int\n\t}{\n\t\tk.Type(),\n\t\tk.P,\n\t\tk.Q,\n\t\tk.G,\n\t\tk.Y,\n\t}\n\n\treturn Marshal(&w)\n}\n\nfunc (k *dsaPublicKey) Verify(data []byte, sig *Signature) error {\n\tif sig.Format != k.Type() {\n\t\treturn fmt.Errorf(\"ssh: signature type %s for key type %s\", sig.Format, k.Type())\n\t}\n\th := hashFuncs[sig.Format].New()\n\th.Write(data)\n\tdigest := h.Sum(nil)\n\n\t// Per RFC 4253, section 6.6,\n\t// The value for 'dss_signature_blob' is encoded as a string containing\n\t// r, followed by s (which are 160-bit integers, without lengths or\n\t// padding, unsigned, and in network byte order).\n\t// For DSS purposes, sig.Blob should be exactly 40 bytes in length.\n\tif len(sig.Blob) != 40 {\n\t\treturn errors.New(\"ssh: DSA signature parse error\")\n\t}\n\tr := new(big.Int).SetBytes(sig.Blob[:20])\n\ts := new(big.Int).SetBytes(sig.Blob[20:])\n\tif dsa.Verify((*dsa.PublicKey)(k), digest, r, s) {\n\t\treturn nil\n\t}\n\treturn errors.New(\"ssh: signature did not verify\")\n}\n\nfunc (k *dsaPublicKey) CryptoPublicKey() crypto.PublicKey {\n\treturn (*dsa.PublicKey)(k)\n}\n\ntype dsaPrivateKey struct {\n\t*dsa.PrivateKey\n}\n\nfunc (k *dsaPrivateKey) PublicKey() PublicKey {\n\treturn (*dsaPublicKey)(&k.PrivateKey.PublicKey)\n}\n\nfunc (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) {\n\treturn k.SignWithAlgorithm(rand, data, k.PublicKey().Type())\n}\n\nfunc (k *dsaPrivateKey) Algorithms() []string {\n\treturn []string{k.PublicKey().Type()}\n}\n\nfunc (k *dsaPrivateKey) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {\n\tif algorithm != \"\" && algorithm != k.PublicKey().Type() {\n\t\treturn nil, fmt.Errorf(\"ssh: unsupported signature algorithm %s\", algorithm)\n\t}\n\n\th := hashFuncs[k.PublicKey().Type()].New()\n\th.Write(data)\n\tdigest := h.Sum(nil)\n\tr, s, err := dsa.Sign(rand, k.PrivateKey, digest)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsig := make([]byte, 40)\n\trb := r.Bytes()\n\tsb := s.Bytes()\n\n\tcopy(sig[20-len(rb):20], rb)\n\tcopy(sig[40-len(sb):], sb)\n\n\treturn &Signature{\n\t\tFormat: k.PublicKey().Type(),\n\t\tBlob:   sig,\n\t}, nil\n}\n\ntype ecdsaPublicKey ecdsa.PublicKey\n\nfunc (k *ecdsaPublicKey) Type() string {\n\treturn \"ecdsa-sha2-\" + k.nistID()\n}\n\nfunc (k *ecdsaPublicKey) nistID() string {\n\tswitch k.Params().BitSize {\n\tcase 256:\n\t\treturn \"nistp256\"\n\tcase 384:\n\t\treturn \"nistp384\"\n\tcase 521:\n\t\treturn \"nistp521\"\n\t}\n\tpanic(\"ssh: unsupported ecdsa key size\")\n}\n\ntype ed25519PublicKey ed25519.PublicKey\n\nfunc (k ed25519PublicKey) Type() string {\n\treturn KeyAlgoED25519\n}\n\nfunc parseED25519(in []byte) (out PublicKey, rest []byte, err error) {\n\tvar w struct {\n\t\tKeyBytes []byte\n\t\tRest     []byte `ssh:\"rest\"`\n\t}\n\n\tif err := Unmarshal(in, &w); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tif l := len(w.KeyBytes); l != ed25519.PublicKeySize {\n\t\treturn nil, nil, fmt.Errorf(\"invalid size %d for Ed25519 public key\", l)\n\t}\n\n\treturn ed25519PublicKey(w.KeyBytes), w.Rest, nil\n}\n\nfunc (k ed25519PublicKey) Marshal() []byte {\n\tw := struct {\n\t\tName     string\n\t\tKeyBytes []byte\n\t}{\n\t\tKeyAlgoED25519,\n\t\t[]byte(k),\n\t}\n\treturn Marshal(&w)\n}\n\nfunc (k ed25519PublicKey) Verify(b []byte, sig *Signature) error {\n\tif sig.Format != k.Type() {\n\t\treturn fmt.Errorf(\"ssh: signature type %s for key type %s\", sig.Format, k.Type())\n\t}\n\tif l := len(k); l != ed25519.PublicKeySize {\n\t\treturn fmt.Errorf(\"ssh: invalid size %d for Ed25519 public key\", l)\n\t}\n\n\tif ok := ed25519.Verify(ed25519.PublicKey(k), b, sig.Blob); !ok {\n\t\treturn errors.New(\"ssh: signature did not verify\")\n\t}\n\n\treturn nil\n}\n\nfunc (k ed25519PublicKey) CryptoPublicKey() crypto.PublicKey {\n\treturn ed25519.PublicKey(k)\n}\n\nfunc supportedEllipticCurve(curve elliptic.Curve) bool {\n\treturn curve == elliptic.P256() || curve == elliptic.P384() || curve == elliptic.P521()\n}\n\n// parseECDSA parses an ECDSA key according to RFC 5656, section 3.1.\nfunc parseECDSA(in []byte) (out PublicKey, rest []byte, err error) {\n\tvar w struct {\n\t\tCurve    string\n\t\tKeyBytes []byte\n\t\tRest     []byte `ssh:\"rest\"`\n\t}\n\n\tif err := Unmarshal(in, &w); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tkey := new(ecdsa.PublicKey)\n\n\tswitch w.Curve {\n\tcase \"nistp256\":\n\t\tkey.Curve = elliptic.P256()\n\tcase \"nistp384\":\n\t\tkey.Curve = elliptic.P384()\n\tcase \"nistp521\":\n\t\tkey.Curve = elliptic.P521()\n\tdefault:\n\t\treturn nil, nil, errors.New(\"ssh: unsupported curve\")\n\t}\n\n\tkey.X, key.Y = elliptic.Unmarshal(key.Curve, w.KeyBytes)\n\tif key.X == nil || key.Y == nil {\n\t\treturn nil, nil, errors.New(\"ssh: invalid curve point\")\n\t}\n\treturn (*ecdsaPublicKey)(key), w.Rest, nil\n}\n\nfunc (k *ecdsaPublicKey) Marshal() []byte {\n\t// See RFC 5656, section 3.1.\n\tkeyBytes := elliptic.Marshal(k.Curve, k.X, k.Y)\n\t// ECDSA publickey struct layout should match the struct used by\n\t// parseECDSACert in the x/crypto/ssh/agent package.\n\tw := struct {\n\t\tName string\n\t\tID   string\n\t\tKey  []byte\n\t}{\n\t\tk.Type(),\n\t\tk.nistID(),\n\t\tkeyBytes,\n\t}\n\n\treturn Marshal(&w)\n}\n\nfunc (k *ecdsaPublicKey) Verify(data []byte, sig *Signature) error {\n\tif sig.Format != k.Type() {\n\t\treturn fmt.Errorf(\"ssh: signature type %s for key type %s\", sig.Format, k.Type())\n\t}\n\n\th := hashFuncs[sig.Format].New()\n\th.Write(data)\n\tdigest := h.Sum(nil)\n\n\t// Per RFC 5656, section 3.1.2,\n\t// The ecdsa_signature_blob value has the following specific encoding:\n\t//    mpint    r\n\t//    mpint    s\n\tvar ecSig struct {\n\t\tR *big.Int\n\t\tS *big.Int\n\t}\n\n\tif err := Unmarshal(sig.Blob, &ecSig); err != nil {\n\t\treturn err\n\t}\n\n\tif ecdsa.Verify((*ecdsa.PublicKey)(k), digest, ecSig.R, ecSig.S) {\n\t\treturn nil\n\t}\n\treturn errors.New(\"ssh: signature did not verify\")\n}\n\nfunc (k *ecdsaPublicKey) CryptoPublicKey() crypto.PublicKey {\n\treturn (*ecdsa.PublicKey)(k)\n}\n\n// skFields holds the additional fields present in U2F/FIDO2 signatures.\n// See openssh/PROTOCOL.u2f 'SSH U2F Signatures' for details.\ntype skFields struct {\n\t// Flags contains U2F/FIDO2 flags such as 'user present'\n\tFlags byte\n\t// Counter is a monotonic signature counter which can be\n\t// used to detect concurrent use of a private key, should\n\t// it be extracted from hardware.\n\tCounter uint32\n}\n\ntype skECDSAPublicKey struct {\n\t// application is a URL-like string, typically \"ssh:\" for SSH.\n\t// see openssh/PROTOCOL.u2f for details.\n\tapplication string\n\tecdsa.PublicKey\n}\n\nfunc (k *skECDSAPublicKey) Type() string {\n\treturn KeyAlgoSKECDSA256\n}\n\nfunc (k *skECDSAPublicKey) nistID() string {\n\treturn \"nistp256\"\n}\n\nfunc parseSKECDSA(in []byte) (out PublicKey, rest []byte, err error) {\n\tvar w struct {\n\t\tCurve       string\n\t\tKeyBytes    []byte\n\t\tApplication string\n\t\tRest        []byte `ssh:\"rest\"`\n\t}\n\n\tif err := Unmarshal(in, &w); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tkey := new(skECDSAPublicKey)\n\tkey.application = w.Application\n\n\tif w.Curve != \"nistp256\" {\n\t\treturn nil, nil, errors.New(\"ssh: unsupported curve\")\n\t}\n\tkey.Curve = elliptic.P256()\n\n\tkey.X, key.Y = elliptic.Unmarshal(key.Curve, w.KeyBytes)\n\tif key.X == nil || key.Y == nil {\n\t\treturn nil, nil, errors.New(\"ssh: invalid curve point\")\n\t}\n\n\treturn key, w.Rest, nil\n}\n\nfunc (k *skECDSAPublicKey) Marshal() []byte {\n\t// See RFC 5656, section 3.1.\n\tkeyBytes := elliptic.Marshal(k.Curve, k.X, k.Y)\n\tw := struct {\n\t\tName        string\n\t\tID          string\n\t\tKey         []byte\n\t\tApplication string\n\t}{\n\t\tk.Type(),\n\t\tk.nistID(),\n\t\tkeyBytes,\n\t\tk.application,\n\t}\n\n\treturn Marshal(&w)\n}\n\nfunc (k *skECDSAPublicKey) Verify(data []byte, sig *Signature) error {\n\tif sig.Format != k.Type() {\n\t\treturn fmt.Errorf(\"ssh: signature type %s for key type %s\", sig.Format, k.Type())\n\t}\n\n\th := hashFuncs[sig.Format].New()\n\th.Write([]byte(k.application))\n\tappDigest := h.Sum(nil)\n\n\th.Reset()\n\th.Write(data)\n\tdataDigest := h.Sum(nil)\n\n\tvar ecSig struct {\n\t\tR *big.Int\n\t\tS *big.Int\n\t}\n\tif err := Unmarshal(sig.Blob, &ecSig); err != nil {\n\t\treturn err\n\t}\n\n\tvar skf skFields\n\tif err := Unmarshal(sig.Rest, &skf); err != nil {\n\t\treturn err\n\t}\n\n\tblob := struct {\n\t\tApplicationDigest []byte `ssh:\"rest\"`\n\t\tFlags             byte\n\t\tCounter           uint32\n\t\tMessageDigest     []byte `ssh:\"rest\"`\n\t}{\n\t\tappDigest,\n\t\tskf.Flags,\n\t\tskf.Counter,\n\t\tdataDigest,\n\t}\n\n\toriginal := Marshal(blob)\n\n\th.Reset()\n\th.Write(original)\n\tdigest := h.Sum(nil)\n\n\tif ecdsa.Verify((*ecdsa.PublicKey)(&k.PublicKey), digest, ecSig.R, ecSig.S) {\n\t\treturn nil\n\t}\n\treturn errors.New(\"ssh: signature did not verify\")\n}\n\nfunc (k *skECDSAPublicKey) CryptoPublicKey() crypto.PublicKey {\n\treturn &k.PublicKey\n}\n\ntype skEd25519PublicKey struct {\n\t// application is a URL-like string, typically \"ssh:\" for SSH.\n\t// see openssh/PROTOCOL.u2f for details.\n\tapplication string\n\ted25519.PublicKey\n}\n\nfunc (k *skEd25519PublicKey) Type() string {\n\treturn KeyAlgoSKED25519\n}\n\nfunc parseSKEd25519(in []byte) (out PublicKey, rest []byte, err error) {\n\tvar w struct {\n\t\tKeyBytes    []byte\n\t\tApplication string\n\t\tRest        []byte `ssh:\"rest\"`\n\t}\n\n\tif err := Unmarshal(in, &w); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tif l := len(w.KeyBytes); l != ed25519.PublicKeySize {\n\t\treturn nil, nil, fmt.Errorf(\"invalid size %d for Ed25519 public key\", l)\n\t}\n\n\tkey := new(skEd25519PublicKey)\n\tkey.application = w.Application\n\tkey.PublicKey = ed25519.PublicKey(w.KeyBytes)\n\n\treturn key, w.Rest, nil\n}\n\nfunc (k *skEd25519PublicKey) Marshal() []byte {\n\tw := struct {\n\t\tName        string\n\t\tKeyBytes    []byte\n\t\tApplication string\n\t}{\n\t\tKeyAlgoSKED25519,\n\t\t[]byte(k.PublicKey),\n\t\tk.application,\n\t}\n\treturn Marshal(&w)\n}\n\nfunc (k *skEd25519PublicKey) Verify(data []byte, sig *Signature) error {\n\tif sig.Format != k.Type() {\n\t\treturn fmt.Errorf(\"ssh: signature type %s for key type %s\", sig.Format, k.Type())\n\t}\n\tif l := len(k.PublicKey); l != ed25519.PublicKeySize {\n\t\treturn fmt.Errorf(\"invalid size %d for Ed25519 public key\", l)\n\t}\n\n\th := hashFuncs[sig.Format].New()\n\th.Write([]byte(k.application))\n\tappDigest := h.Sum(nil)\n\n\th.Reset()\n\th.Write(data)\n\tdataDigest := h.Sum(nil)\n\n\tvar edSig struct {\n\t\tSignature []byte `ssh:\"rest\"`\n\t}\n\n\tif err := Unmarshal(sig.Blob, &edSig); err != nil {\n\t\treturn err\n\t}\n\n\tvar skf skFields\n\tif err := Unmarshal(sig.Rest, &skf); err != nil {\n\t\treturn err\n\t}\n\n\tblob := struct {\n\t\tApplicationDigest []byte `ssh:\"rest\"`\n\t\tFlags             byte\n\t\tCounter           uint32\n\t\tMessageDigest     []byte `ssh:\"rest\"`\n\t}{\n\t\tappDigest,\n\t\tskf.Flags,\n\t\tskf.Counter,\n\t\tdataDigest,\n\t}\n\n\toriginal := Marshal(blob)\n\n\tif ok := ed25519.Verify(k.PublicKey, original, edSig.Signature); !ok {\n\t\treturn errors.New(\"ssh: signature did not verify\")\n\t}\n\n\treturn nil\n}\n\nfunc (k *skEd25519PublicKey) CryptoPublicKey() crypto.PublicKey {\n\treturn k.PublicKey\n}\n\n// NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey,\n// *ecdsa.PrivateKey or any other crypto.Signer and returns a\n// corresponding Signer instance. ECDSA keys must use P-256, P-384 or\n// P-521. DSA keys must use parameter size L1024N160.\nfunc NewSignerFromKey(key interface{}) (Signer, error) {\n\tswitch key := key.(type) {\n\tcase crypto.Signer:\n\t\treturn NewSignerFromSigner(key)\n\tcase *dsa.PrivateKey:\n\t\treturn newDSAPrivateKey(key)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"ssh: unsupported key type %T\", key)\n\t}\n}\n\nfunc newDSAPrivateKey(key *dsa.PrivateKey) (Signer, error) {\n\tif err := checkDSAParams(&key.PublicKey.Parameters); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &dsaPrivateKey{key}, nil\n}\n\ntype wrappedSigner struct {\n\tsigner crypto.Signer\n\tpubKey PublicKey\n}\n\n// NewSignerFromSigner takes any crypto.Signer implementation and\n// returns a corresponding Signer interface. This can be used, for\n// example, with keys kept in hardware modules.\nfunc NewSignerFromSigner(signer crypto.Signer) (Signer, error) {\n\tpubKey, err := NewPublicKey(signer.Public())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &wrappedSigner{signer, pubKey}, nil\n}\n\nfunc (s *wrappedSigner) PublicKey() PublicKey {\n\treturn s.pubKey\n}\n\nfunc (s *wrappedSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {\n\treturn s.SignWithAlgorithm(rand, data, s.pubKey.Type())\n}\n\nfunc (s *wrappedSigner) Algorithms() []string {\n\treturn algorithmsForKeyFormat(s.pubKey.Type())\n}\n\nfunc (s *wrappedSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {\n\tif algorithm == \"\" {\n\t\talgorithm = s.pubKey.Type()\n\t}\n\n\tif !contains(s.Algorithms(), algorithm) {\n\t\treturn nil, fmt.Errorf(\"ssh: unsupported signature algorithm %q for key format %q\", algorithm, s.pubKey.Type())\n\t}\n\n\thashFunc := hashFuncs[algorithm]\n\tvar digest []byte\n\tif hashFunc != 0 {\n\t\th := hashFunc.New()\n\t\th.Write(data)\n\t\tdigest = h.Sum(nil)\n\t} else {\n\t\tdigest = data\n\t}\n\n\tsignature, err := s.signer.Sign(rand, digest, hashFunc)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// crypto.Signer.Sign is expected to return an ASN.1-encoded signature\n\t// for ECDSA and DSA, but that's not the encoding expected by SSH, so\n\t// re-encode.\n\tswitch s.pubKey.(type) {\n\tcase *ecdsaPublicKey, *dsaPublicKey:\n\t\ttype asn1Signature struct {\n\t\t\tR, S *big.Int\n\t\t}\n\t\tasn1Sig := new(asn1Signature)\n\t\t_, err := asn1.Unmarshal(signature, asn1Sig)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tswitch s.pubKey.(type) {\n\t\tcase *ecdsaPublicKey:\n\t\t\tsignature = Marshal(asn1Sig)\n\n\t\tcase *dsaPublicKey:\n\t\t\tsignature = make([]byte, 40)\n\t\t\tr := asn1Sig.R.Bytes()\n\t\t\ts := asn1Sig.S.Bytes()\n\t\t\tcopy(signature[20-len(r):20], r)\n\t\t\tcopy(signature[40-len(s):40], s)\n\t\t}\n\t}\n\n\treturn &Signature{\n\t\tFormat: algorithm,\n\t\tBlob:   signature,\n\t}, nil\n}\n\n// NewPublicKey takes an *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey,\n// or ed25519.PublicKey returns a corresponding PublicKey instance.\n// ECDSA keys must use P-256, P-384 or P-521.\nfunc NewPublicKey(key interface{}) (PublicKey, error) {\n\tswitch key := key.(type) {\n\tcase *rsa.PublicKey:\n\t\treturn (*rsaPublicKey)(key), nil\n\tcase *ecdsa.PublicKey:\n\t\tif !supportedEllipticCurve(key.Curve) {\n\t\t\treturn nil, errors.New(\"ssh: only P-256, P-384 and P-521 EC keys are supported\")\n\t\t}\n\t\treturn (*ecdsaPublicKey)(key), nil\n\tcase *dsa.PublicKey:\n\t\treturn (*dsaPublicKey)(key), nil\n\tcase ed25519.PublicKey:\n\t\tif l := len(key); l != ed25519.PublicKeySize {\n\t\t\treturn nil, fmt.Errorf(\"ssh: invalid size %d for Ed25519 public key\", l)\n\t\t}\n\t\treturn ed25519PublicKey(key), nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"ssh: unsupported key type %T\", key)\n\t}\n}\n\n// ParsePrivateKey returns a Signer from a PEM encoded private key. It supports\n// the same keys as ParseRawPrivateKey. If the private key is encrypted, it\n// will return a PassphraseMissingError.\nfunc ParsePrivateKey(pemBytes []byte) (Signer, error) {\n\tkey, err := ParseRawPrivateKey(pemBytes)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn NewSignerFromKey(key)\n}\n\n// ParsePrivateKeyWithPassphrase returns a Signer from a PEM encoded private\n// key and passphrase. It supports the same keys as\n// ParseRawPrivateKeyWithPassphrase.\nfunc ParsePrivateKeyWithPassphrase(pemBytes, passphrase []byte) (Signer, error) {\n\tkey, err := ParseRawPrivateKeyWithPassphrase(pemBytes, passphrase)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn NewSignerFromKey(key)\n}\n\n// encryptedBlock tells whether a private key is\n// encrypted by examining its Proc-Type header\n// for a mention of ENCRYPTED\n// according to RFC 1421 Section 4.6.1.1.\nfunc encryptedBlock(block *pem.Block) bool {\n\treturn strings.Contains(block.Headers[\"Proc-Type\"], \"ENCRYPTED\")\n}\n\n// A PassphraseMissingError indicates that parsing this private key requires a\n// passphrase. Use ParsePrivateKeyWithPassphrase.\ntype PassphraseMissingError struct {\n\t// PublicKey will be set if the private key format includes an unencrypted\n\t// public key along with the encrypted private key.\n\tPublicKey PublicKey\n}\n\nfunc (*PassphraseMissingError) Error() string {\n\treturn \"ssh: this private key is passphrase protected\"\n}\n\n// ParseRawPrivateKey returns a private key from a PEM encoded private key. It supports\n// RSA, DSA, ECDSA, and Ed25519 private keys in PKCS#1, PKCS#8, OpenSSL, and OpenSSH\n// formats. If the private key is encrypted, it will return a PassphraseMissingError.\nfunc ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {\n\tblock, _ := pem.Decode(pemBytes)\n\tif block == nil {\n\t\treturn nil, errors.New(\"ssh: no key found\")\n\t}\n\n\tif encryptedBlock(block) {\n\t\treturn nil, &PassphraseMissingError{}\n\t}\n\n\tswitch block.Type {\n\tcase \"RSA PRIVATE KEY\":\n\t\treturn x509.ParsePKCS1PrivateKey(block.Bytes)\n\t// RFC5208 - https://tools.ietf.org/html/rfc5208\n\tcase \"PRIVATE KEY\":\n\t\treturn x509.ParsePKCS8PrivateKey(block.Bytes)\n\tcase \"EC PRIVATE KEY\":\n\t\treturn x509.ParseECPrivateKey(block.Bytes)\n\tcase \"DSA PRIVATE KEY\":\n\t\treturn ParseDSAPrivateKey(block.Bytes)\n\tcase \"OPENSSH PRIVATE KEY\":\n\t\treturn parseOpenSSHPrivateKey(block.Bytes, unencryptedOpenSSHKey)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"ssh: unsupported key type %q\", block.Type)\n\t}\n}\n\n// ParseRawPrivateKeyWithPassphrase returns a private key decrypted with\n// passphrase from a PEM encoded private key. If the passphrase is wrong, it\n// will return x509.IncorrectPasswordError.\nfunc ParseRawPrivateKeyWithPassphrase(pemBytes, passphrase []byte) (interface{}, error) {\n\tblock, _ := pem.Decode(pemBytes)\n\tif block == nil {\n\t\treturn nil, errors.New(\"ssh: no key found\")\n\t}\n\n\tif block.Type == \"OPENSSH PRIVATE KEY\" {\n\t\treturn parseOpenSSHPrivateKey(block.Bytes, passphraseProtectedOpenSSHKey(passphrase))\n\t}\n\n\tif !encryptedBlock(block) || !x509.IsEncryptedPEMBlock(block) {\n\t\treturn nil, errors.New(\"ssh: not an encrypted key\")\n\t}\n\n\tbuf, err := x509.DecryptPEMBlock(block, passphrase)\n\tif err != nil {\n\t\tif err == x509.IncorrectPasswordError {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn nil, fmt.Errorf(\"ssh: cannot decode encrypted private keys: %v\", err)\n\t}\n\n\tvar result interface{}\n\n\tswitch block.Type {\n\tcase \"RSA PRIVATE KEY\":\n\t\tresult, err = x509.ParsePKCS1PrivateKey(buf)\n\tcase \"EC PRIVATE KEY\":\n\t\tresult, err = x509.ParseECPrivateKey(buf)\n\tcase \"DSA PRIVATE KEY\":\n\t\tresult, err = ParseDSAPrivateKey(buf)\n\tdefault:\n\t\terr = fmt.Errorf(\"ssh: unsupported key type %q\", block.Type)\n\t}\n\t// Because of deficiencies in the format, DecryptPEMBlock does not always\n\t// detect an incorrect password. In these cases decrypted DER bytes is\n\t// random noise. If the parsing of the key returns an asn1.StructuralError\n\t// we return x509.IncorrectPasswordError.\n\tif _, ok := err.(asn1.StructuralError); ok {\n\t\treturn nil, x509.IncorrectPasswordError\n\t}\n\n\treturn result, err\n}\n\n// ParseDSAPrivateKey returns a DSA private key from its ASN.1 DER encoding, as\n// specified by the OpenSSL DSA man page.\nfunc ParseDSAPrivateKey(der []byte) (*dsa.PrivateKey, error) {\n\tvar k struct {\n\t\tVersion int\n\t\tP       *big.Int\n\t\tQ       *big.Int\n\t\tG       *big.Int\n\t\tPub     *big.Int\n\t\tPriv    *big.Int\n\t}\n\trest, err := asn1.Unmarshal(der, &k)\n\tif err != nil {\n\t\treturn nil, errors.New(\"ssh: failed to parse DSA key: \" + err.Error())\n\t}\n\tif len(rest) > 0 {\n\t\treturn nil, errors.New(\"ssh: garbage after DSA key\")\n\t}\n\n\treturn &dsa.PrivateKey{\n\t\tPublicKey: dsa.PublicKey{\n\t\t\tParameters: dsa.Parameters{\n\t\t\t\tP: k.P,\n\t\t\t\tQ: k.Q,\n\t\t\t\tG: k.G,\n\t\t\t},\n\t\t\tY: k.Pub,\n\t\t},\n\t\tX: k.Priv,\n\t}, nil\n}\n\nfunc unencryptedOpenSSHKey(cipherName, kdfName, kdfOpts string, privKeyBlock []byte) ([]byte, error) {\n\tif kdfName != \"none\" || cipherName != \"none\" {\n\t\treturn nil, &PassphraseMissingError{}\n\t}\n\tif kdfOpts != \"\" {\n\t\treturn nil, errors.New(\"ssh: invalid openssh private key\")\n\t}\n\treturn privKeyBlock, nil\n}\n\nfunc passphraseProtectedOpenSSHKey(passphrase []byte) openSSHDecryptFunc {\n\treturn func(cipherName, kdfName, kdfOpts string, privKeyBlock []byte) ([]byte, error) {\n\t\tif kdfName == \"none\" || cipherName == \"none\" {\n\t\t\treturn nil, errors.New(\"ssh: key is not password protected\")\n\t\t}\n\t\tif kdfName != \"bcrypt\" {\n\t\t\treturn nil, fmt.Errorf(\"ssh: unknown KDF %q, only supports %q\", kdfName, \"bcrypt\")\n\t\t}\n\n\t\tvar opts struct {\n\t\t\tSalt   string\n\t\t\tRounds uint32\n\t\t}\n\t\tif err := Unmarshal([]byte(kdfOpts), &opts); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tk, err := bcrypt_pbkdf.Key(passphrase, []byte(opts.Salt), int(opts.Rounds), 32+16)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tkey, iv := k[:32], k[32:]\n\n\t\tc, err := aes.NewCipher(key)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tswitch cipherName {\n\t\tcase \"aes256-ctr\":\n\t\t\tctr := cipher.NewCTR(c, iv)\n\t\t\tctr.XORKeyStream(privKeyBlock, privKeyBlock)\n\t\tcase \"aes256-cbc\":\n\t\t\tif len(privKeyBlock)%c.BlockSize() != 0 {\n\t\t\t\treturn nil, fmt.Errorf(\"ssh: invalid encrypted private key length, not a multiple of the block size\")\n\t\t\t}\n\t\t\tcbc := cipher.NewCBCDecrypter(c, iv)\n\t\t\tcbc.CryptBlocks(privKeyBlock, privKeyBlock)\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"ssh: unknown cipher %q, only supports %q or %q\", cipherName, \"aes256-ctr\", \"aes256-cbc\")\n\t\t}\n\n\t\treturn privKeyBlock, nil\n\t}\n}\n\nfunc unencryptedOpenSSHMarshaler(privKeyBlock []byte) ([]byte, string, string, string, error) {\n\tkey := generateOpenSSHPadding(privKeyBlock, 8)\n\treturn key, \"none\", \"none\", \"\", nil\n}\n\nfunc passphraseProtectedOpenSSHMarshaler(passphrase []byte) openSSHEncryptFunc {\n\treturn func(privKeyBlock []byte) ([]byte, string, string, string, error) {\n\t\tsalt := make([]byte, 16)\n\t\tif _, err := rand.Read(salt); err != nil {\n\t\t\treturn nil, \"\", \"\", \"\", err\n\t\t}\n\n\t\topts := struct {\n\t\t\tSalt   []byte\n\t\t\tRounds uint32\n\t\t}{salt, 16}\n\n\t\t// Derive key to encrypt the private key block.\n\t\tk, err := bcrypt_pbkdf.Key(passphrase, salt, int(opts.Rounds), 32+aes.BlockSize)\n\t\tif err != nil {\n\t\t\treturn nil, \"\", \"\", \"\", err\n\t\t}\n\n\t\t// Add padding matching the block size of AES.\n\t\tkeyBlock := generateOpenSSHPadding(privKeyBlock, aes.BlockSize)\n\n\t\t// Encrypt the private key using the derived secret.\n\n\t\tdst := make([]byte, len(keyBlock))\n\t\tkey, iv := k[:32], k[32:]\n\t\tblock, err := aes.NewCipher(key)\n\t\tif err != nil {\n\t\t\treturn nil, \"\", \"\", \"\", err\n\t\t}\n\n\t\tstream := cipher.NewCTR(block, iv)\n\t\tstream.XORKeyStream(dst, keyBlock)\n\n\t\treturn dst, \"aes256-ctr\", \"bcrypt\", string(Marshal(opts)), nil\n\t}\n}\n\nconst privateKeyAuthMagic = \"openssh-key-v1\\x00\"\n\ntype openSSHDecryptFunc func(CipherName, KdfName, KdfOpts string, PrivKeyBlock []byte) ([]byte, error)\ntype openSSHEncryptFunc func(PrivKeyBlock []byte) (ProtectedKeyBlock []byte, cipherName, kdfName, kdfOptions string, err error)\n\ntype openSSHEncryptedPrivateKey struct {\n\tCipherName   string\n\tKdfName      string\n\tKdfOpts      string\n\tNumKeys      uint32\n\tPubKey       []byte\n\tPrivKeyBlock []byte\n}\n\ntype openSSHPrivateKey struct {\n\tCheck1  uint32\n\tCheck2  uint32\n\tKeytype string\n\tRest    []byte `ssh:\"rest\"`\n}\n\ntype openSSHRSAPrivateKey struct {\n\tN       *big.Int\n\tE       *big.Int\n\tD       *big.Int\n\tIqmp    *big.Int\n\tP       *big.Int\n\tQ       *big.Int\n\tComment string\n\tPad     []byte `ssh:\"rest\"`\n}\n\ntype openSSHEd25519PrivateKey struct {\n\tPub     []byte\n\tPriv    []byte\n\tComment string\n\tPad     []byte `ssh:\"rest\"`\n}\n\ntype openSSHECDSAPrivateKey struct {\n\tCurve   string\n\tPub     []byte\n\tD       *big.Int\n\tComment string\n\tPad     []byte `ssh:\"rest\"`\n}\n\n// parseOpenSSHPrivateKey parses an OpenSSH private key, using the decrypt\n// function to unwrap the encrypted portion. unencryptedOpenSSHKey can be used\n// as the decrypt function to parse an unencrypted private key. See\n// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key.\nfunc parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.PrivateKey, error) {\n\tif len(key) < len(privateKeyAuthMagic) || string(key[:len(privateKeyAuthMagic)]) != privateKeyAuthMagic {\n\t\treturn nil, errors.New(\"ssh: invalid openssh private key format\")\n\t}\n\tremaining := key[len(privateKeyAuthMagic):]\n\n\tvar w openSSHEncryptedPrivateKey\n\tif err := Unmarshal(remaining, &w); err != nil {\n\t\treturn nil, err\n\t}\n\tif w.NumKeys != 1 {\n\t\t// We only support single key files, and so does OpenSSH.\n\t\t// https://github.com/openssh/openssh-portable/blob/4103a3ec7/sshkey.c#L4171\n\t\treturn nil, errors.New(\"ssh: multi-key files are not supported\")\n\t}\n\n\tprivKeyBlock, err := decrypt(w.CipherName, w.KdfName, w.KdfOpts, w.PrivKeyBlock)\n\tif err != nil {\n\t\tif err, ok := err.(*PassphraseMissingError); ok {\n\t\t\tpub, errPub := ParsePublicKey(w.PubKey)\n\t\t\tif errPub != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"ssh: failed to parse embedded public key: %v\", errPub)\n\t\t\t}\n\t\t\terr.PublicKey = pub\n\t\t}\n\t\treturn nil, err\n\t}\n\n\tvar pk1 openSSHPrivateKey\n\tif err := Unmarshal(privKeyBlock, &pk1); err != nil || pk1.Check1 != pk1.Check2 {\n\t\tif w.CipherName != \"none\" {\n\t\t\treturn nil, x509.IncorrectPasswordError\n\t\t}\n\t\treturn nil, errors.New(\"ssh: malformed OpenSSH key\")\n\t}\n\n\tswitch pk1.Keytype {\n\tcase KeyAlgoRSA:\n\t\tvar key openSSHRSAPrivateKey\n\t\tif err := Unmarshal(pk1.Rest, &key); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif err := checkOpenSSHKeyPadding(key.Pad); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tpk := &rsa.PrivateKey{\n\t\t\tPublicKey: rsa.PublicKey{\n\t\t\t\tN: key.N,\n\t\t\t\tE: int(key.E.Int64()),\n\t\t\t},\n\t\t\tD:      key.D,\n\t\t\tPrimes: []*big.Int{key.P, key.Q},\n\t\t}\n\n\t\tif err := pk.Validate(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tpk.Precompute()\n\n\t\treturn pk, nil\n\tcase KeyAlgoED25519:\n\t\tvar key openSSHEd25519PrivateKey\n\t\tif err := Unmarshal(pk1.Rest, &key); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif len(key.Priv) != ed25519.PrivateKeySize {\n\t\t\treturn nil, errors.New(\"ssh: private key unexpected length\")\n\t\t}\n\n\t\tif err := checkOpenSSHKeyPadding(key.Pad); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tpk := ed25519.PrivateKey(make([]byte, ed25519.PrivateKeySize))\n\t\tcopy(pk, key.Priv)\n\t\treturn &pk, nil\n\tcase KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:\n\t\tvar key openSSHECDSAPrivateKey\n\t\tif err := Unmarshal(pk1.Rest, &key); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif err := checkOpenSSHKeyPadding(key.Pad); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tvar curve elliptic.Curve\n\t\tswitch key.Curve {\n\t\tcase \"nistp256\":\n\t\t\tcurve = elliptic.P256()\n\t\tcase \"nistp384\":\n\t\t\tcurve = elliptic.P384()\n\t\tcase \"nistp521\":\n\t\t\tcurve = elliptic.P521()\n\t\tdefault:\n\t\t\treturn nil, errors.New(\"ssh: unhandled elliptic curve: \" + key.Curve)\n\t\t}\n\n\t\tX, Y := elliptic.Unmarshal(curve, key.Pub)\n\t\tif X == nil || Y == nil {\n\t\t\treturn nil, errors.New(\"ssh: failed to unmarshal public key\")\n\t\t}\n\n\t\tif key.D.Cmp(curve.Params().N) >= 0 {\n\t\t\treturn nil, errors.New(\"ssh: scalar is out of range\")\n\t\t}\n\n\t\tx, y := curve.ScalarBaseMult(key.D.Bytes())\n\t\tif x.Cmp(X) != 0 || y.Cmp(Y) != 0 {\n\t\t\treturn nil, errors.New(\"ssh: public key does not match private key\")\n\t\t}\n\n\t\treturn &ecdsa.PrivateKey{\n\t\t\tPublicKey: ecdsa.PublicKey{\n\t\t\t\tCurve: curve,\n\t\t\t\tX:     X,\n\t\t\t\tY:     Y,\n\t\t\t},\n\t\t\tD: key.D,\n\t\t}, nil\n\tdefault:\n\t\treturn nil, errors.New(\"ssh: unhandled key type\")\n\t}\n}\n\nfunc marshalOpenSSHPrivateKey(key crypto.PrivateKey, comment string, encrypt openSSHEncryptFunc) (*pem.Block, error) {\n\tvar w openSSHEncryptedPrivateKey\n\tvar pk1 openSSHPrivateKey\n\n\t// Random check bytes.\n\tvar check uint32\n\tif err := binary.Read(rand.Reader, binary.BigEndian, &check); err != nil {\n\t\treturn nil, err\n\t}\n\n\tpk1.Check1 = check\n\tpk1.Check2 = check\n\tw.NumKeys = 1\n\n\t// Use a []byte directly on ed25519 keys.\n\tif k, ok := key.(*ed25519.PrivateKey); ok {\n\t\tkey = *k\n\t}\n\n\tswitch k := key.(type) {\n\tcase *rsa.PrivateKey:\n\t\tE := new(big.Int).SetInt64(int64(k.PublicKey.E))\n\t\t// Marshal public key:\n\t\t// E and N are in reversed order in the public and private key.\n\t\tpubKey := struct {\n\t\t\tKeyType string\n\t\t\tE       *big.Int\n\t\t\tN       *big.Int\n\t\t}{\n\t\t\tKeyAlgoRSA,\n\t\t\tE, k.PublicKey.N,\n\t\t}\n\t\tw.PubKey = Marshal(pubKey)\n\n\t\t// Marshal private key.\n\t\tkey := openSSHRSAPrivateKey{\n\t\t\tN:       k.PublicKey.N,\n\t\t\tE:       E,\n\t\t\tD:       k.D,\n\t\t\tIqmp:    k.Precomputed.Qinv,\n\t\t\tP:       k.Primes[0],\n\t\t\tQ:       k.Primes[1],\n\t\t\tComment: comment,\n\t\t}\n\t\tpk1.Keytype = KeyAlgoRSA\n\t\tpk1.Rest = Marshal(key)\n\tcase ed25519.PrivateKey:\n\t\tpub := make([]byte, ed25519.PublicKeySize)\n\t\tpriv := make([]byte, ed25519.PrivateKeySize)\n\t\tcopy(pub, k[32:])\n\t\tcopy(priv, k)\n\n\t\t// Marshal public key.\n\t\tpubKey := struct {\n\t\t\tKeyType string\n\t\t\tPub     []byte\n\t\t}{\n\t\t\tKeyAlgoED25519, pub,\n\t\t}\n\t\tw.PubKey = Marshal(pubKey)\n\n\t\t// Marshal private key.\n\t\tkey := openSSHEd25519PrivateKey{\n\t\t\tPub:     pub,\n\t\t\tPriv:    priv,\n\t\t\tComment: comment,\n\t\t}\n\t\tpk1.Keytype = KeyAlgoED25519\n\t\tpk1.Rest = Marshal(key)\n\tcase *ecdsa.PrivateKey:\n\t\tvar curve, keyType string\n\t\tswitch name := k.Curve.Params().Name; name {\n\t\tcase \"P-256\":\n\t\t\tcurve = \"nistp256\"\n\t\t\tkeyType = KeyAlgoECDSA256\n\t\tcase \"P-384\":\n\t\t\tcurve = \"nistp384\"\n\t\t\tkeyType = KeyAlgoECDSA384\n\t\tcase \"P-521\":\n\t\t\tcurve = \"nistp521\"\n\t\t\tkeyType = KeyAlgoECDSA521\n\t\tdefault:\n\t\t\treturn nil, errors.New(\"ssh: unhandled elliptic curve \" + name)\n\t\t}\n\n\t\tpub := elliptic.Marshal(k.Curve, k.PublicKey.X, k.PublicKey.Y)\n\n\t\t// Marshal public key.\n\t\tpubKey := struct {\n\t\t\tKeyType string\n\t\t\tCurve   string\n\t\t\tPub     []byte\n\t\t}{\n\t\t\tkeyType, curve, pub,\n\t\t}\n\t\tw.PubKey = Marshal(pubKey)\n\n\t\t// Marshal private key.\n\t\tkey := openSSHECDSAPrivateKey{\n\t\t\tCurve:   curve,\n\t\t\tPub:     pub,\n\t\t\tD:       k.D,\n\t\t\tComment: comment,\n\t\t}\n\t\tpk1.Keytype = keyType\n\t\tpk1.Rest = Marshal(key)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"ssh: unsupported key type %T\", k)\n\t}\n\n\tvar err error\n\t// Add padding and encrypt the key if necessary.\n\tw.PrivKeyBlock, w.CipherName, w.KdfName, w.KdfOpts, err = encrypt(Marshal(pk1))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tb := Marshal(w)\n\tblock := &pem.Block{\n\t\tType:  \"OPENSSH PRIVATE KEY\",\n\t\tBytes: append([]byte(privateKeyAuthMagic), b...),\n\t}\n\treturn block, nil\n}\n\nfunc checkOpenSSHKeyPadding(pad []byte) error {\n\tfor i, b := range pad {\n\t\tif int(b) != i+1 {\n\t\t\treturn errors.New(\"ssh: padding not as expected\")\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc generateOpenSSHPadding(block []byte, blockSize int) []byte {\n\tfor i, l := 0, len(block); (l+i)%blockSize != 0; i++ {\n\t\tblock = append(block, byte(i+1))\n\t}\n\treturn block\n}\n\n// FingerprintLegacyMD5 returns the user presentation of the key's\n// fingerprint as described by RFC 4716 section 4.\nfunc FingerprintLegacyMD5(pubKey PublicKey) string {\n\tmd5sum := md5.Sum(pubKey.Marshal())\n\thexarray := make([]string, len(md5sum))\n\tfor i, c := range md5sum {\n\t\thexarray[i] = hex.EncodeToString([]byte{c})\n\t}\n\treturn strings.Join(hexarray, \":\")\n}\n\n// FingerprintSHA256 returns the user presentation of the key's\n// fingerprint as unpadded base64 encoded sha256 hash.\n// This format was introduced from OpenSSH 6.8.\n// https://www.openssh.com/txt/release-6.8\n// https://tools.ietf.org/html/rfc4648#section-3.2 (unpadded base64 encoding)\nfunc FingerprintSHA256(pubKey PublicKey) string {\n\tsha256sum := sha256.Sum256(pubKey.Marshal())\n\thash := base64.RawStdEncoding.EncodeToString(sha256sum[:])\n\treturn \"SHA256:\" + hash\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/mac.go",
    "content": "// Copyright 2012 The Go 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 ssh\n\n// Message authentication support\n\nimport (\n\t\"crypto/hmac\"\n\t\"crypto/sha1\"\n\t\"crypto/sha256\"\n\t\"crypto/sha512\"\n\t\"hash\"\n)\n\ntype macMode struct {\n\tkeySize int\n\tetm     bool\n\tnew     func(key []byte) hash.Hash\n}\n\n// truncatingMAC wraps around a hash.Hash and truncates the output digest to\n// a given size.\ntype truncatingMAC struct {\n\tlength int\n\thmac   hash.Hash\n}\n\nfunc (t truncatingMAC) Write(data []byte) (int, error) {\n\treturn t.hmac.Write(data)\n}\n\nfunc (t truncatingMAC) Sum(in []byte) []byte {\n\tout := t.hmac.Sum(in)\n\treturn out[:len(in)+t.length]\n}\n\nfunc (t truncatingMAC) Reset() {\n\tt.hmac.Reset()\n}\n\nfunc (t truncatingMAC) Size() int {\n\treturn t.length\n}\n\nfunc (t truncatingMAC) BlockSize() int { return t.hmac.BlockSize() }\n\nvar macModes = map[string]*macMode{\n\t\"hmac-sha2-512-etm@openssh.com\": {64, true, func(key []byte) hash.Hash {\n\t\treturn hmac.New(sha512.New, key)\n\t}},\n\t\"hmac-sha2-256-etm@openssh.com\": {32, true, func(key []byte) hash.Hash {\n\t\treturn hmac.New(sha256.New, key)\n\t}},\n\t\"hmac-sha2-512\": {64, false, func(key []byte) hash.Hash {\n\t\treturn hmac.New(sha512.New, key)\n\t}},\n\t\"hmac-sha2-256\": {32, false, func(key []byte) hash.Hash {\n\t\treturn hmac.New(sha256.New, key)\n\t}},\n\t\"hmac-sha1\": {20, false, func(key []byte) hash.Hash {\n\t\treturn hmac.New(sha1.New, key)\n\t}},\n\t\"hmac-sha1-96\": {20, false, func(key []byte) hash.Hash {\n\t\treturn truncatingMAC{12, hmac.New(sha1.New, key)}\n\t}},\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/messages.go",
    "content": "// Copyright 2011 The Go 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 ssh\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/big\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// These are SSH message type numbers. They are scattered around several\n// documents but many were taken from [SSH-PARAMETERS].\nconst (\n\tmsgIgnore        = 2\n\tmsgUnimplemented = 3\n\tmsgDebug         = 4\n\tmsgNewKeys       = 21\n)\n\n// SSH messages:\n//\n// These structures mirror the wire format of the corresponding SSH messages.\n// They are marshaled using reflection with the marshal and unmarshal functions\n// in this file. The only wrinkle is that a final member of type []byte with a\n// ssh tag of \"rest\" receives the remainder of a packet when unmarshaling.\n\n// See RFC 4253, section 11.1.\nconst msgDisconnect = 1\n\n// disconnectMsg is the message that signals a disconnect. It is also\n// the error type returned from mux.Wait()\ntype disconnectMsg struct {\n\tReason   uint32 `sshtype:\"1\"`\n\tMessage  string\n\tLanguage string\n}\n\nfunc (d *disconnectMsg) Error() string {\n\treturn fmt.Sprintf(\"ssh: disconnect, reason %d: %s\", d.Reason, d.Message)\n}\n\n// See RFC 4253, section 7.1.\nconst msgKexInit = 20\n\ntype kexInitMsg struct {\n\tCookie                  [16]byte `sshtype:\"20\"`\n\tKexAlgos                []string\n\tServerHostKeyAlgos      []string\n\tCiphersClientServer     []string\n\tCiphersServerClient     []string\n\tMACsClientServer        []string\n\tMACsServerClient        []string\n\tCompressionClientServer []string\n\tCompressionServerClient []string\n\tLanguagesClientServer   []string\n\tLanguagesServerClient   []string\n\tFirstKexFollows         bool\n\tReserved                uint32\n}\n\n// See RFC 4253, section 8.\n\n// Diffie-Hellman\nconst msgKexDHInit = 30\n\ntype kexDHInitMsg struct {\n\tX *big.Int `sshtype:\"30\"`\n}\n\nconst msgKexECDHInit = 30\n\ntype kexECDHInitMsg struct {\n\tClientPubKey []byte `sshtype:\"30\"`\n}\n\nconst msgKexECDHReply = 31\n\ntype kexECDHReplyMsg struct {\n\tHostKey         []byte `sshtype:\"31\"`\n\tEphemeralPubKey []byte\n\tSignature       []byte\n}\n\nconst msgKexDHReply = 31\n\ntype kexDHReplyMsg struct {\n\tHostKey   []byte `sshtype:\"31\"`\n\tY         *big.Int\n\tSignature []byte\n}\n\n// See RFC 4419, section 5.\nconst msgKexDHGexGroup = 31\n\ntype kexDHGexGroupMsg struct {\n\tP *big.Int `sshtype:\"31\"`\n\tG *big.Int\n}\n\nconst msgKexDHGexInit = 32\n\ntype kexDHGexInitMsg struct {\n\tX *big.Int `sshtype:\"32\"`\n}\n\nconst msgKexDHGexReply = 33\n\ntype kexDHGexReplyMsg struct {\n\tHostKey   []byte `sshtype:\"33\"`\n\tY         *big.Int\n\tSignature []byte\n}\n\nconst msgKexDHGexRequest = 34\n\ntype kexDHGexRequestMsg struct {\n\tMinBits      uint32 `sshtype:\"34\"`\n\tPreferedBits uint32\n\tMaxBits      uint32\n}\n\n// See RFC 4253, section 10.\nconst msgServiceRequest = 5\n\ntype serviceRequestMsg struct {\n\tService string `sshtype:\"5\"`\n}\n\n// See RFC 4253, section 10.\nconst msgServiceAccept = 6\n\ntype serviceAcceptMsg struct {\n\tService string `sshtype:\"6\"`\n}\n\n// See RFC 8308, section 2.3\nconst msgExtInfo = 7\n\ntype extInfoMsg struct {\n\tNumExtensions uint32 `sshtype:\"7\"`\n\tPayload       []byte `ssh:\"rest\"`\n}\n\n// See RFC 4252, section 5.\nconst msgUserAuthRequest = 50\n\ntype userAuthRequestMsg struct {\n\tUser    string `sshtype:\"50\"`\n\tService string\n\tMethod  string\n\tPayload []byte `ssh:\"rest\"`\n}\n\n// Used for debug printouts of packets.\ntype userAuthSuccessMsg struct {\n}\n\n// See RFC 4252, section 5.1\nconst msgUserAuthFailure = 51\n\ntype userAuthFailureMsg struct {\n\tMethods        []string `sshtype:\"51\"`\n\tPartialSuccess bool\n}\n\n// See RFC 4252, section 5.1\nconst msgUserAuthSuccess = 52\n\n// See RFC 4252, section 5.4\nconst msgUserAuthBanner = 53\n\ntype userAuthBannerMsg struct {\n\tMessage string `sshtype:\"53\"`\n\t// unused, but required to allow message parsing\n\tLanguage string\n}\n\n// See RFC 4256, section 3.2\nconst msgUserAuthInfoRequest = 60\nconst msgUserAuthInfoResponse = 61\n\ntype userAuthInfoRequestMsg struct {\n\tName        string `sshtype:\"60\"`\n\tInstruction string\n\tLanguage    string\n\tNumPrompts  uint32\n\tPrompts     []byte `ssh:\"rest\"`\n}\n\n// See RFC 4254, section 5.1.\nconst msgChannelOpen = 90\n\ntype channelOpenMsg struct {\n\tChanType         string `sshtype:\"90\"`\n\tPeersID          uint32\n\tPeersWindow      uint32\n\tMaxPacketSize    uint32\n\tTypeSpecificData []byte `ssh:\"rest\"`\n}\n\nconst msgChannelExtendedData = 95\nconst msgChannelData = 94\n\n// Used for debug print outs of packets.\ntype channelDataMsg struct {\n\tPeersID uint32 `sshtype:\"94\"`\n\tLength  uint32\n\tRest    []byte `ssh:\"rest\"`\n}\n\n// See RFC 4254, section 5.1.\nconst msgChannelOpenConfirm = 91\n\ntype channelOpenConfirmMsg struct {\n\tPeersID          uint32 `sshtype:\"91\"`\n\tMyID             uint32\n\tMyWindow         uint32\n\tMaxPacketSize    uint32\n\tTypeSpecificData []byte `ssh:\"rest\"`\n}\n\n// See RFC 4254, section 5.1.\nconst msgChannelOpenFailure = 92\n\ntype channelOpenFailureMsg struct {\n\tPeersID  uint32 `sshtype:\"92\"`\n\tReason   RejectionReason\n\tMessage  string\n\tLanguage string\n}\n\nconst msgChannelRequest = 98\n\ntype channelRequestMsg struct {\n\tPeersID             uint32 `sshtype:\"98\"`\n\tRequest             string\n\tWantReply           bool\n\tRequestSpecificData []byte `ssh:\"rest\"`\n}\n\n// See RFC 4254, section 5.4.\nconst msgChannelSuccess = 99\n\ntype channelRequestSuccessMsg struct {\n\tPeersID uint32 `sshtype:\"99\"`\n}\n\n// See RFC 4254, section 5.4.\nconst msgChannelFailure = 100\n\ntype channelRequestFailureMsg struct {\n\tPeersID uint32 `sshtype:\"100\"`\n}\n\n// See RFC 4254, section 5.3\nconst msgChannelClose = 97\n\ntype channelCloseMsg struct {\n\tPeersID uint32 `sshtype:\"97\"`\n}\n\n// See RFC 4254, section 5.3\nconst msgChannelEOF = 96\n\ntype channelEOFMsg struct {\n\tPeersID uint32 `sshtype:\"96\"`\n}\n\n// See RFC 4254, section 4\nconst msgGlobalRequest = 80\n\ntype globalRequestMsg struct {\n\tType      string `sshtype:\"80\"`\n\tWantReply bool\n\tData      []byte `ssh:\"rest\"`\n}\n\n// See RFC 4254, section 4\nconst msgRequestSuccess = 81\n\ntype globalRequestSuccessMsg struct {\n\tData []byte `ssh:\"rest\" sshtype:\"81\"`\n}\n\n// See RFC 4254, section 4\nconst msgRequestFailure = 82\n\ntype globalRequestFailureMsg struct {\n\tData []byte `ssh:\"rest\" sshtype:\"82\"`\n}\n\n// See RFC 4254, section 5.2\nconst msgChannelWindowAdjust = 93\n\ntype windowAdjustMsg struct {\n\tPeersID         uint32 `sshtype:\"93\"`\n\tAdditionalBytes uint32\n}\n\n// See RFC 4252, section 7\nconst msgUserAuthPubKeyOk = 60\n\ntype userAuthPubKeyOkMsg struct {\n\tAlgo   string `sshtype:\"60\"`\n\tPubKey []byte\n}\n\n// See RFC 4462, section 3\nconst msgUserAuthGSSAPIResponse = 60\n\ntype userAuthGSSAPIResponse struct {\n\tSupportMech []byte `sshtype:\"60\"`\n}\n\nconst msgUserAuthGSSAPIToken = 61\n\ntype userAuthGSSAPIToken struct {\n\tToken []byte `sshtype:\"61\"`\n}\n\nconst msgUserAuthGSSAPIMIC = 66\n\ntype userAuthGSSAPIMIC struct {\n\tMIC []byte `sshtype:\"66\"`\n}\n\n// See RFC 4462, section 3.9\nconst msgUserAuthGSSAPIErrTok = 64\n\ntype userAuthGSSAPIErrTok struct {\n\tErrorToken []byte `sshtype:\"64\"`\n}\n\n// See RFC 4462, section 3.8\nconst msgUserAuthGSSAPIError = 65\n\ntype userAuthGSSAPIError struct {\n\tMajorStatus uint32 `sshtype:\"65\"`\n\tMinorStatus uint32\n\tMessage     string\n\tLanguageTag string\n}\n\n// Transport layer OpenSSH extension. See [PROTOCOL], section 1.9\nconst msgPing = 192\n\ntype pingMsg struct {\n\tData string `sshtype:\"192\"`\n}\n\n// Transport layer OpenSSH extension. See [PROTOCOL], section 1.9\nconst msgPong = 193\n\ntype pongMsg struct {\n\tData string `sshtype:\"193\"`\n}\n\n// typeTags returns the possible type bytes for the given reflect.Type, which\n// should be a struct. The possible values are separated by a '|' character.\nfunc typeTags(structType reflect.Type) (tags []byte) {\n\ttagStr := structType.Field(0).Tag.Get(\"sshtype\")\n\n\tfor _, tag := range strings.Split(tagStr, \"|\") {\n\t\ti, err := strconv.Atoi(tag)\n\t\tif err == nil {\n\t\t\ttags = append(tags, byte(i))\n\t\t}\n\t}\n\n\treturn tags\n}\n\nfunc fieldError(t reflect.Type, field int, problem string) error {\n\tif problem != \"\" {\n\t\tproblem = \": \" + problem\n\t}\n\treturn fmt.Errorf(\"ssh: unmarshal error for field %s of type %s%s\", t.Field(field).Name, t.Name(), problem)\n}\n\nvar errShortRead = errors.New(\"ssh: short read\")\n\n// Unmarshal parses data in SSH wire format into a structure. The out\n// argument should be a pointer to struct. If the first member of the\n// struct has the \"sshtype\" tag set to a '|'-separated set of numbers\n// in decimal, the packet must start with one of those numbers. In\n// case of error, Unmarshal returns a ParseError or\n// UnexpectedMessageError.\nfunc Unmarshal(data []byte, out interface{}) error {\n\tv := reflect.ValueOf(out).Elem()\n\tstructType := v.Type()\n\texpectedTypes := typeTags(structType)\n\n\tvar expectedType byte\n\tif len(expectedTypes) > 0 {\n\t\texpectedType = expectedTypes[0]\n\t}\n\n\tif len(data) == 0 {\n\t\treturn parseError(expectedType)\n\t}\n\n\tif len(expectedTypes) > 0 {\n\t\tgoodType := false\n\t\tfor _, e := range expectedTypes {\n\t\t\tif e > 0 && data[0] == e {\n\t\t\t\tgoodType = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !goodType {\n\t\t\treturn fmt.Errorf(\"ssh: unexpected message type %d (expected one of %v)\", data[0], expectedTypes)\n\t\t}\n\t\tdata = data[1:]\n\t}\n\n\tvar ok bool\n\tfor i := 0; i < v.NumField(); i++ {\n\t\tfield := v.Field(i)\n\t\tt := field.Type()\n\t\tswitch t.Kind() {\n\t\tcase reflect.Bool:\n\t\t\tif len(data) < 1 {\n\t\t\t\treturn errShortRead\n\t\t\t}\n\t\t\tfield.SetBool(data[0] != 0)\n\t\t\tdata = data[1:]\n\t\tcase reflect.Array:\n\t\t\tif t.Elem().Kind() != reflect.Uint8 {\n\t\t\t\treturn fieldError(structType, i, \"array of unsupported type\")\n\t\t\t}\n\t\t\tif len(data) < t.Len() {\n\t\t\t\treturn errShortRead\n\t\t\t}\n\t\t\tfor j, n := 0, t.Len(); j < n; j++ {\n\t\t\t\tfield.Index(j).Set(reflect.ValueOf(data[j]))\n\t\t\t}\n\t\t\tdata = data[t.Len():]\n\t\tcase reflect.Uint64:\n\t\t\tvar u64 uint64\n\t\t\tif u64, data, ok = parseUint64(data); !ok {\n\t\t\t\treturn errShortRead\n\t\t\t}\n\t\t\tfield.SetUint(u64)\n\t\tcase reflect.Uint32:\n\t\t\tvar u32 uint32\n\t\t\tif u32, data, ok = parseUint32(data); !ok {\n\t\t\t\treturn errShortRead\n\t\t\t}\n\t\t\tfield.SetUint(uint64(u32))\n\t\tcase reflect.Uint8:\n\t\t\tif len(data) < 1 {\n\t\t\t\treturn errShortRead\n\t\t\t}\n\t\t\tfield.SetUint(uint64(data[0]))\n\t\t\tdata = data[1:]\n\t\tcase reflect.String:\n\t\t\tvar s []byte\n\t\t\tif s, data, ok = parseString(data); !ok {\n\t\t\t\treturn fieldError(structType, i, \"\")\n\t\t\t}\n\t\t\tfield.SetString(string(s))\n\t\tcase reflect.Slice:\n\t\t\tswitch t.Elem().Kind() {\n\t\t\tcase reflect.Uint8:\n\t\t\t\tif structType.Field(i).Tag.Get(\"ssh\") == \"rest\" {\n\t\t\t\t\tfield.Set(reflect.ValueOf(data))\n\t\t\t\t\tdata = nil\n\t\t\t\t} else {\n\t\t\t\t\tvar s []byte\n\t\t\t\t\tif s, data, ok = parseString(data); !ok {\n\t\t\t\t\t\treturn errShortRead\n\t\t\t\t\t}\n\t\t\t\t\tfield.Set(reflect.ValueOf(s))\n\t\t\t\t}\n\t\t\tcase reflect.String:\n\t\t\t\tvar nl []string\n\t\t\t\tif nl, data, ok = parseNameList(data); !ok {\n\t\t\t\t\treturn errShortRead\n\t\t\t\t}\n\t\t\t\tfield.Set(reflect.ValueOf(nl))\n\t\t\tdefault:\n\t\t\t\treturn fieldError(structType, i, \"slice of unsupported type\")\n\t\t\t}\n\t\tcase reflect.Ptr:\n\t\t\tif t == bigIntType {\n\t\t\t\tvar n *big.Int\n\t\t\t\tif n, data, ok = parseInt(data); !ok {\n\t\t\t\t\treturn errShortRead\n\t\t\t\t}\n\t\t\t\tfield.Set(reflect.ValueOf(n))\n\t\t\t} else {\n\t\t\t\treturn fieldError(structType, i, \"pointer to unsupported type\")\n\t\t\t}\n\t\tdefault:\n\t\t\treturn fieldError(structType, i, fmt.Sprintf(\"unsupported type: %v\", t))\n\t\t}\n\t}\n\n\tif len(data) != 0 {\n\t\treturn parseError(expectedType)\n\t}\n\n\treturn nil\n}\n\n// Marshal serializes the message in msg to SSH wire format.  The msg\n// argument should be a struct or pointer to struct. If the first\n// member has the \"sshtype\" tag set to a number in decimal, that\n// number is prepended to the result. If the last of member has the\n// \"ssh\" tag set to \"rest\", its contents are appended to the output.\nfunc Marshal(msg interface{}) []byte {\n\tout := make([]byte, 0, 64)\n\treturn marshalStruct(out, msg)\n}\n\nfunc marshalStruct(out []byte, msg interface{}) []byte {\n\tv := reflect.Indirect(reflect.ValueOf(msg))\n\tmsgTypes := typeTags(v.Type())\n\tif len(msgTypes) > 0 {\n\t\tout = append(out, msgTypes[0])\n\t}\n\n\tfor i, n := 0, v.NumField(); i < n; i++ {\n\t\tfield := v.Field(i)\n\t\tswitch t := field.Type(); t.Kind() {\n\t\tcase reflect.Bool:\n\t\t\tvar v uint8\n\t\t\tif field.Bool() {\n\t\t\t\tv = 1\n\t\t\t}\n\t\t\tout = append(out, v)\n\t\tcase reflect.Array:\n\t\t\tif t.Elem().Kind() != reflect.Uint8 {\n\t\t\t\tpanic(fmt.Sprintf(\"array of non-uint8 in field %d: %T\", i, field.Interface()))\n\t\t\t}\n\t\t\tfor j, l := 0, t.Len(); j < l; j++ {\n\t\t\t\tout = append(out, uint8(field.Index(j).Uint()))\n\t\t\t}\n\t\tcase reflect.Uint32:\n\t\t\tout = appendU32(out, uint32(field.Uint()))\n\t\tcase reflect.Uint64:\n\t\t\tout = appendU64(out, uint64(field.Uint()))\n\t\tcase reflect.Uint8:\n\t\t\tout = append(out, uint8(field.Uint()))\n\t\tcase reflect.String:\n\t\t\ts := field.String()\n\t\t\tout = appendInt(out, len(s))\n\t\t\tout = append(out, s...)\n\t\tcase reflect.Slice:\n\t\t\tswitch t.Elem().Kind() {\n\t\t\tcase reflect.Uint8:\n\t\t\t\tif v.Type().Field(i).Tag.Get(\"ssh\") != \"rest\" {\n\t\t\t\t\tout = appendInt(out, field.Len())\n\t\t\t\t}\n\t\t\t\tout = append(out, field.Bytes()...)\n\t\t\tcase reflect.String:\n\t\t\t\toffset := len(out)\n\t\t\t\tout = appendU32(out, 0)\n\t\t\t\tif n := field.Len(); n > 0 {\n\t\t\t\t\tfor j := 0; j < n; j++ {\n\t\t\t\t\t\tf := field.Index(j)\n\t\t\t\t\t\tif j != 0 {\n\t\t\t\t\t\t\tout = append(out, ',')\n\t\t\t\t\t\t}\n\t\t\t\t\t\tout = append(out, f.String()...)\n\t\t\t\t\t}\n\t\t\t\t\t// overwrite length value\n\t\t\t\t\tbinary.BigEndian.PutUint32(out[offset:], uint32(len(out)-offset-4))\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tpanic(fmt.Sprintf(\"slice of unknown type in field %d: %T\", i, field.Interface()))\n\t\t\t}\n\t\tcase reflect.Ptr:\n\t\t\tif t == bigIntType {\n\t\t\t\tvar n *big.Int\n\t\t\t\tnValue := reflect.ValueOf(&n)\n\t\t\t\tnValue.Elem().Set(field)\n\t\t\t\tneeded := intLength(n)\n\t\t\t\toldLength := len(out)\n\n\t\t\t\tif cap(out)-len(out) < needed {\n\t\t\t\t\tnewOut := make([]byte, len(out), 2*(len(out)+needed))\n\t\t\t\t\tcopy(newOut, out)\n\t\t\t\t\tout = newOut\n\t\t\t\t}\n\t\t\t\tout = out[:oldLength+needed]\n\t\t\t\tmarshalInt(out[oldLength:], n)\n\t\t\t} else {\n\t\t\t\tpanic(fmt.Sprintf(\"pointer to unknown type in field %d: %T\", i, field.Interface()))\n\t\t\t}\n\t\t}\n\t}\n\n\treturn out\n}\n\nvar bigOne = big.NewInt(1)\n\nfunc parseString(in []byte) (out, rest []byte, ok bool) {\n\tif len(in) < 4 {\n\t\treturn\n\t}\n\tlength := binary.BigEndian.Uint32(in)\n\tin = in[4:]\n\tif uint32(len(in)) < length {\n\t\treturn\n\t}\n\tout = in[:length]\n\trest = in[length:]\n\tok = true\n\treturn\n}\n\nvar (\n\tcomma         = []byte{','}\n\temptyNameList = []string{}\n)\n\nfunc parseNameList(in []byte) (out []string, rest []byte, ok bool) {\n\tcontents, rest, ok := parseString(in)\n\tif !ok {\n\t\treturn\n\t}\n\tif len(contents) == 0 {\n\t\tout = emptyNameList\n\t\treturn\n\t}\n\tparts := bytes.Split(contents, comma)\n\tout = make([]string, len(parts))\n\tfor i, part := range parts {\n\t\tout[i] = string(part)\n\t}\n\treturn\n}\n\nfunc parseInt(in []byte) (out *big.Int, rest []byte, ok bool) {\n\tcontents, rest, ok := parseString(in)\n\tif !ok {\n\t\treturn\n\t}\n\tout = new(big.Int)\n\n\tif len(contents) > 0 && contents[0]&0x80 == 0x80 {\n\t\t// This is a negative number\n\t\tnotBytes := make([]byte, len(contents))\n\t\tfor i := range notBytes {\n\t\t\tnotBytes[i] = ^contents[i]\n\t\t}\n\t\tout.SetBytes(notBytes)\n\t\tout.Add(out, bigOne)\n\t\tout.Neg(out)\n\t} else {\n\t\t// Positive number\n\t\tout.SetBytes(contents)\n\t}\n\tok = true\n\treturn\n}\n\nfunc parseUint32(in []byte) (uint32, []byte, bool) {\n\tif len(in) < 4 {\n\t\treturn 0, nil, false\n\t}\n\treturn binary.BigEndian.Uint32(in), in[4:], true\n}\n\nfunc parseUint64(in []byte) (uint64, []byte, bool) {\n\tif len(in) < 8 {\n\t\treturn 0, nil, false\n\t}\n\treturn binary.BigEndian.Uint64(in), in[8:], true\n}\n\nfunc intLength(n *big.Int) int {\n\tlength := 4 /* length bytes */\n\tif n.Sign() < 0 {\n\t\tnMinus1 := new(big.Int).Neg(n)\n\t\tnMinus1.Sub(nMinus1, bigOne)\n\t\tbitLen := nMinus1.BitLen()\n\t\tif bitLen%8 == 0 {\n\t\t\t// The number will need 0xff padding\n\t\t\tlength++\n\t\t}\n\t\tlength += (bitLen + 7) / 8\n\t} else if n.Sign() == 0 {\n\t\t// A zero is the zero length string\n\t} else {\n\t\tbitLen := n.BitLen()\n\t\tif bitLen%8 == 0 {\n\t\t\t// The number will need 0x00 padding\n\t\t\tlength++\n\t\t}\n\t\tlength += (bitLen + 7) / 8\n\t}\n\n\treturn length\n}\n\nfunc marshalUint32(to []byte, n uint32) []byte {\n\tbinary.BigEndian.PutUint32(to, n)\n\treturn to[4:]\n}\n\nfunc marshalUint64(to []byte, n uint64) []byte {\n\tbinary.BigEndian.PutUint64(to, n)\n\treturn to[8:]\n}\n\nfunc marshalInt(to []byte, n *big.Int) []byte {\n\tlengthBytes := to\n\tto = to[4:]\n\tlength := 0\n\n\tif n.Sign() < 0 {\n\t\t// A negative number has to be converted to two's-complement\n\t\t// form. So we'll subtract 1 and invert. If the\n\t\t// most-significant-bit isn't set then we'll need to pad the\n\t\t// beginning with 0xff in order to keep the number negative.\n\t\tnMinus1 := new(big.Int).Neg(n)\n\t\tnMinus1.Sub(nMinus1, bigOne)\n\t\tbytes := nMinus1.Bytes()\n\t\tfor i := range bytes {\n\t\t\tbytes[i] ^= 0xff\n\t\t}\n\t\tif len(bytes) == 0 || bytes[0]&0x80 == 0 {\n\t\t\tto[0] = 0xff\n\t\t\tto = to[1:]\n\t\t\tlength++\n\t\t}\n\t\tnBytes := copy(to, bytes)\n\t\tto = to[nBytes:]\n\t\tlength += nBytes\n\t} else if n.Sign() == 0 {\n\t\t// A zero is the zero length string\n\t} else {\n\t\tbytes := n.Bytes()\n\t\tif len(bytes) > 0 && bytes[0]&0x80 != 0 {\n\t\t\t// We'll have to pad this with a 0x00 in order to\n\t\t\t// stop it looking like a negative number.\n\t\t\tto[0] = 0\n\t\t\tto = to[1:]\n\t\t\tlength++\n\t\t}\n\t\tnBytes := copy(to, bytes)\n\t\tto = to[nBytes:]\n\t\tlength += nBytes\n\t}\n\n\tlengthBytes[0] = byte(length >> 24)\n\tlengthBytes[1] = byte(length >> 16)\n\tlengthBytes[2] = byte(length >> 8)\n\tlengthBytes[3] = byte(length)\n\treturn to\n}\n\nfunc writeInt(w io.Writer, n *big.Int) {\n\tlength := intLength(n)\n\tbuf := make([]byte, length)\n\tmarshalInt(buf, n)\n\tw.Write(buf)\n}\n\nfunc writeString(w io.Writer, s []byte) {\n\tvar lengthBytes [4]byte\n\tlengthBytes[0] = byte(len(s) >> 24)\n\tlengthBytes[1] = byte(len(s) >> 16)\n\tlengthBytes[2] = byte(len(s) >> 8)\n\tlengthBytes[3] = byte(len(s))\n\tw.Write(lengthBytes[:])\n\tw.Write(s)\n}\n\nfunc stringLength(n int) int {\n\treturn 4 + n\n}\n\nfunc marshalString(to []byte, s []byte) []byte {\n\tto[0] = byte(len(s) >> 24)\n\tto[1] = byte(len(s) >> 16)\n\tto[2] = byte(len(s) >> 8)\n\tto[3] = byte(len(s))\n\tto = to[4:]\n\tcopy(to, s)\n\treturn to[len(s):]\n}\n\nvar bigIntType = reflect.TypeOf((*big.Int)(nil))\n\n// Decode a packet into its corresponding message.\nfunc decode(packet []byte) (interface{}, error) {\n\tvar msg interface{}\n\tswitch packet[0] {\n\tcase msgDisconnect:\n\t\tmsg = new(disconnectMsg)\n\tcase msgServiceRequest:\n\t\tmsg = new(serviceRequestMsg)\n\tcase msgServiceAccept:\n\t\tmsg = new(serviceAcceptMsg)\n\tcase msgExtInfo:\n\t\tmsg = new(extInfoMsg)\n\tcase msgKexInit:\n\t\tmsg = new(kexInitMsg)\n\tcase msgKexDHInit:\n\t\tmsg = new(kexDHInitMsg)\n\tcase msgKexDHReply:\n\t\tmsg = new(kexDHReplyMsg)\n\tcase msgUserAuthRequest:\n\t\tmsg = new(userAuthRequestMsg)\n\tcase msgUserAuthSuccess:\n\t\treturn new(userAuthSuccessMsg), nil\n\tcase msgUserAuthFailure:\n\t\tmsg = new(userAuthFailureMsg)\n\tcase msgUserAuthBanner:\n\t\tmsg = new(userAuthBannerMsg)\n\tcase msgUserAuthPubKeyOk:\n\t\tmsg = new(userAuthPubKeyOkMsg)\n\tcase msgGlobalRequest:\n\t\tmsg = new(globalRequestMsg)\n\tcase msgRequestSuccess:\n\t\tmsg = new(globalRequestSuccessMsg)\n\tcase msgRequestFailure:\n\t\tmsg = new(globalRequestFailureMsg)\n\tcase msgChannelOpen:\n\t\tmsg = new(channelOpenMsg)\n\tcase msgChannelData:\n\t\tmsg = new(channelDataMsg)\n\tcase msgChannelOpenConfirm:\n\t\tmsg = new(channelOpenConfirmMsg)\n\tcase msgChannelOpenFailure:\n\t\tmsg = new(channelOpenFailureMsg)\n\tcase msgChannelWindowAdjust:\n\t\tmsg = new(windowAdjustMsg)\n\tcase msgChannelEOF:\n\t\tmsg = new(channelEOFMsg)\n\tcase msgChannelClose:\n\t\tmsg = new(channelCloseMsg)\n\tcase msgChannelRequest:\n\t\tmsg = new(channelRequestMsg)\n\tcase msgChannelSuccess:\n\t\tmsg = new(channelRequestSuccessMsg)\n\tcase msgChannelFailure:\n\t\tmsg = new(channelRequestFailureMsg)\n\tcase msgUserAuthGSSAPIToken:\n\t\tmsg = new(userAuthGSSAPIToken)\n\tcase msgUserAuthGSSAPIMIC:\n\t\tmsg = new(userAuthGSSAPIMIC)\n\tcase msgUserAuthGSSAPIErrTok:\n\t\tmsg = new(userAuthGSSAPIErrTok)\n\tcase msgUserAuthGSSAPIError:\n\t\tmsg = new(userAuthGSSAPIError)\n\tdefault:\n\t\treturn nil, unexpectedMessageError(0, packet[0])\n\t}\n\tif err := Unmarshal(packet, msg); err != nil {\n\t\treturn nil, err\n\t}\n\treturn msg, nil\n}\n\nvar packetTypeNames = map[byte]string{\n\tmsgDisconnect:          \"disconnectMsg\",\n\tmsgServiceRequest:      \"serviceRequestMsg\",\n\tmsgServiceAccept:       \"serviceAcceptMsg\",\n\tmsgExtInfo:             \"extInfoMsg\",\n\tmsgKexInit:             \"kexInitMsg\",\n\tmsgKexDHInit:           \"kexDHInitMsg\",\n\tmsgKexDHReply:          \"kexDHReplyMsg\",\n\tmsgUserAuthRequest:     \"userAuthRequestMsg\",\n\tmsgUserAuthSuccess:     \"userAuthSuccessMsg\",\n\tmsgUserAuthFailure:     \"userAuthFailureMsg\",\n\tmsgUserAuthPubKeyOk:    \"userAuthPubKeyOkMsg\",\n\tmsgGlobalRequest:       \"globalRequestMsg\",\n\tmsgRequestSuccess:      \"globalRequestSuccessMsg\",\n\tmsgRequestFailure:      \"globalRequestFailureMsg\",\n\tmsgChannelOpen:         \"channelOpenMsg\",\n\tmsgChannelData:         \"channelDataMsg\",\n\tmsgChannelOpenConfirm:  \"channelOpenConfirmMsg\",\n\tmsgChannelOpenFailure:  \"channelOpenFailureMsg\",\n\tmsgChannelWindowAdjust: \"windowAdjustMsg\",\n\tmsgChannelEOF:          \"channelEOFMsg\",\n\tmsgChannelClose:        \"channelCloseMsg\",\n\tmsgChannelRequest:      \"channelRequestMsg\",\n\tmsgChannelSuccess:      \"channelRequestSuccessMsg\",\n\tmsgChannelFailure:      \"channelRequestFailureMsg\",\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/mlkem.go",
    "content": "// Copyright 2024 The Go 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\n//go:build go1.24\n\npackage ssh\n\nimport (\n\t\"crypto\"\n\t\"crypto/mlkem\"\n\t\"crypto/sha256\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"runtime\"\n\t\"slices\"\n\n\t\"golang.org/x/crypto/curve25519\"\n)\n\nconst (\n\tkexAlgoMLKEM768xCurve25519SHA256 = \"mlkem768x25519-sha256\"\n)\n\nfunc init() {\n\t// After Go 1.24rc1 mlkem swapped the order of return values of Encapsulate.\n\t// See #70950.\n\tif runtime.Version() == \"go1.24rc1\" {\n\t\treturn\n\t}\n\tsupportedKexAlgos = slices.Insert(supportedKexAlgos, 0, kexAlgoMLKEM768xCurve25519SHA256)\n\tpreferredKexAlgos = slices.Insert(preferredKexAlgos, 0, kexAlgoMLKEM768xCurve25519SHA256)\n\tkexAlgoMap[kexAlgoMLKEM768xCurve25519SHA256] = &mlkem768WithCurve25519sha256{}\n}\n\n// mlkem768WithCurve25519sha256 implements the hybrid ML-KEM768 with\n// curve25519-sha256 key exchange method, as described by\n// draft-kampanakis-curdle-ssh-pq-ke-05 section 2.3.3.\ntype mlkem768WithCurve25519sha256 struct{}\n\nfunc (kex *mlkem768WithCurve25519sha256) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) {\n\tvar c25519kp curve25519KeyPair\n\tif err := c25519kp.generate(rand); err != nil {\n\t\treturn nil, err\n\t}\n\n\tseed := make([]byte, mlkem.SeedSize)\n\tif _, err := io.ReadFull(rand, seed); err != nil {\n\t\treturn nil, err\n\t}\n\n\tmlkemDk, err := mlkem.NewDecapsulationKey768(seed)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\thybridKey := append(mlkemDk.EncapsulationKey().Bytes(), c25519kp.pub[:]...)\n\tif err := c.writePacket(Marshal(&kexECDHInitMsg{hybridKey})); err != nil {\n\t\treturn nil, err\n\t}\n\n\tpacket, err := c.readPacket()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar reply kexECDHReplyMsg\n\tif err = Unmarshal(packet, &reply); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif len(reply.EphemeralPubKey) != mlkem.CiphertextSize768+32 {\n\t\treturn nil, errors.New(\"ssh: peer's mlkem768x25519 public value has wrong length\")\n\t}\n\n\t// Perform KEM decapsulate operation to obtain shared key from ML-KEM.\n\tmlkem768Secret, err := mlkemDk.Decapsulate(reply.EphemeralPubKey[:mlkem.CiphertextSize768])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Complete Curve25519 ECDH to obtain its shared key.\n\tc25519Secret, err := curve25519.X25519(c25519kp.priv[:], reply.EphemeralPubKey[mlkem.CiphertextSize768:])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"ssh: peer's mlkem768x25519 public value is not valid: %w\", err)\n\t}\n\t// Compute actual shared key.\n\th := sha256.New()\n\th.Write(mlkem768Secret)\n\th.Write(c25519Secret)\n\tsecret := h.Sum(nil)\n\n\th.Reset()\n\tmagics.write(h)\n\twriteString(h, reply.HostKey)\n\twriteString(h, hybridKey)\n\twriteString(h, reply.EphemeralPubKey)\n\n\tK := make([]byte, stringLength(len(secret)))\n\tmarshalString(K, secret)\n\th.Write(K)\n\n\treturn &kexResult{\n\t\tH:         h.Sum(nil),\n\t\tK:         K,\n\t\tHostKey:   reply.HostKey,\n\t\tSignature: reply.Signature,\n\t\tHash:      crypto.SHA256,\n\t}, nil\n}\n\nfunc (kex *mlkem768WithCurve25519sha256) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (*kexResult, error) {\n\tpacket, err := c.readPacket()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar kexInit kexECDHInitMsg\n\tif err = Unmarshal(packet, &kexInit); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif len(kexInit.ClientPubKey) != mlkem.EncapsulationKeySize768+32 {\n\t\treturn nil, errors.New(\"ssh: peer's ML-KEM768/curve25519 public value has wrong length\")\n\t}\n\n\tencapsulationKey, err := mlkem.NewEncapsulationKey768(kexInit.ClientPubKey[:mlkem.EncapsulationKeySize768])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"ssh: peer's ML-KEM768 encapsulation key is not valid: %w\", err)\n\t}\n\t// Perform KEM encapsulate operation to obtain ciphertext and shared key.\n\tmlkem768Secret, mlkem768Ciphertext := encapsulationKey.Encapsulate()\n\n\t// Perform server side of Curve25519 ECDH to obtain server public value and\n\t// shared key.\n\tvar c25519kp curve25519KeyPair\n\tif err := c25519kp.generate(rand); err != nil {\n\t\treturn nil, err\n\t}\n\tc25519Secret, err := curve25519.X25519(c25519kp.priv[:], kexInit.ClientPubKey[mlkem.EncapsulationKeySize768:])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"ssh: peer's ML-KEM768/curve25519 public value is not valid: %w\", err)\n\t}\n\thybridKey := append(mlkem768Ciphertext, c25519kp.pub[:]...)\n\n\t// Compute actual shared key.\n\th := sha256.New()\n\th.Write(mlkem768Secret)\n\th.Write(c25519Secret)\n\tsecret := h.Sum(nil)\n\n\thostKeyBytes := priv.PublicKey().Marshal()\n\n\th.Reset()\n\tmagics.write(h)\n\twriteString(h, hostKeyBytes)\n\twriteString(h, kexInit.ClientPubKey)\n\twriteString(h, hybridKey)\n\n\tK := make([]byte, stringLength(len(secret)))\n\tmarshalString(K, secret)\n\th.Write(K)\n\n\tH := h.Sum(nil)\n\n\tsig, err := signAndMarshal(priv, rand, H, algo)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treply := kexECDHReplyMsg{\n\t\tEphemeralPubKey: hybridKey,\n\t\tHostKey:         hostKeyBytes,\n\t\tSignature:       sig,\n\t}\n\tif err := c.writePacket(Marshal(&reply)); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &kexResult{\n\t\tH:         H,\n\t\tK:         K,\n\t\tHostKey:   hostKeyBytes,\n\t\tSignature: sig,\n\t\tHash:      crypto.SHA256,\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/mux.go",
    "content": "// Copyright 2013 The Go 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 ssh\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"sync\"\n\t\"sync/atomic\"\n)\n\n// debugMux, if set, causes messages in the connection protocol to be\n// logged.\nconst debugMux = false\n\n// chanList is a thread safe channel list.\ntype chanList struct {\n\t// protects concurrent access to chans\n\tsync.Mutex\n\n\t// chans are indexed by the local id of the channel, which the\n\t// other side should send in the PeersId field.\n\tchans []*channel\n\n\t// This is a debugging aid: it offsets all IDs by this\n\t// amount. This helps distinguish otherwise identical\n\t// server/client muxes\n\toffset uint32\n}\n\n// Assigns a channel ID to the given channel.\nfunc (c *chanList) add(ch *channel) uint32 {\n\tc.Lock()\n\tdefer c.Unlock()\n\tfor i := range c.chans {\n\t\tif c.chans[i] == nil {\n\t\t\tc.chans[i] = ch\n\t\t\treturn uint32(i) + c.offset\n\t\t}\n\t}\n\tc.chans = append(c.chans, ch)\n\treturn uint32(len(c.chans)-1) + c.offset\n}\n\n// getChan returns the channel for the given ID.\nfunc (c *chanList) getChan(id uint32) *channel {\n\tid -= c.offset\n\n\tc.Lock()\n\tdefer c.Unlock()\n\tif id < uint32(len(c.chans)) {\n\t\treturn c.chans[id]\n\t}\n\treturn nil\n}\n\nfunc (c *chanList) remove(id uint32) {\n\tid -= c.offset\n\tc.Lock()\n\tif id < uint32(len(c.chans)) {\n\t\tc.chans[id] = nil\n\t}\n\tc.Unlock()\n}\n\n// dropAll forgets all channels it knows, returning them in a slice.\nfunc (c *chanList) dropAll() []*channel {\n\tc.Lock()\n\tdefer c.Unlock()\n\tvar r []*channel\n\n\tfor _, ch := range c.chans {\n\t\tif ch == nil {\n\t\t\tcontinue\n\t\t}\n\t\tr = append(r, ch)\n\t}\n\tc.chans = nil\n\treturn r\n}\n\n// mux represents the state for the SSH connection protocol, which\n// multiplexes many channels onto a single packet transport.\ntype mux struct {\n\tconn     packetConn\n\tchanList chanList\n\n\tincomingChannels chan NewChannel\n\n\tglobalSentMu     sync.Mutex\n\tglobalResponses  chan interface{}\n\tincomingRequests chan *Request\n\n\terrCond *sync.Cond\n\terr     error\n}\n\n// When debugging, each new chanList instantiation has a different\n// offset.\nvar globalOff uint32\n\nfunc (m *mux) Wait() error {\n\tm.errCond.L.Lock()\n\tdefer m.errCond.L.Unlock()\n\tfor m.err == nil {\n\t\tm.errCond.Wait()\n\t}\n\treturn m.err\n}\n\n// newMux returns a mux that runs over the given connection.\nfunc newMux(p packetConn) *mux {\n\tm := &mux{\n\t\tconn:             p,\n\t\tincomingChannels: make(chan NewChannel, chanSize),\n\t\tglobalResponses:  make(chan interface{}, 1),\n\t\tincomingRequests: make(chan *Request, chanSize),\n\t\terrCond:          newCond(),\n\t}\n\tif debugMux {\n\t\tm.chanList.offset = atomic.AddUint32(&globalOff, 1)\n\t}\n\n\tgo m.loop()\n\treturn m\n}\n\nfunc (m *mux) sendMessage(msg interface{}) error {\n\tp := Marshal(msg)\n\tif debugMux {\n\t\tlog.Printf(\"send global(%d): %#v\", m.chanList.offset, msg)\n\t}\n\treturn m.conn.writePacket(p)\n}\n\nfunc (m *mux) SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error) {\n\tif wantReply {\n\t\tm.globalSentMu.Lock()\n\t\tdefer m.globalSentMu.Unlock()\n\t}\n\n\tif err := m.sendMessage(globalRequestMsg{\n\t\tType:      name,\n\t\tWantReply: wantReply,\n\t\tData:      payload,\n\t}); err != nil {\n\t\treturn false, nil, err\n\t}\n\n\tif !wantReply {\n\t\treturn false, nil, nil\n\t}\n\n\tmsg, ok := <-m.globalResponses\n\tif !ok {\n\t\treturn false, nil, io.EOF\n\t}\n\tswitch msg := msg.(type) {\n\tcase *globalRequestFailureMsg:\n\t\treturn false, msg.Data, nil\n\tcase *globalRequestSuccessMsg:\n\t\treturn true, msg.Data, nil\n\tdefault:\n\t\treturn false, nil, fmt.Errorf(\"ssh: unexpected response to request: %#v\", msg)\n\t}\n}\n\n// ackRequest must be called after processing a global request that\n// has WantReply set.\nfunc (m *mux) ackRequest(ok bool, data []byte) error {\n\tif ok {\n\t\treturn m.sendMessage(globalRequestSuccessMsg{Data: data})\n\t}\n\treturn m.sendMessage(globalRequestFailureMsg{Data: data})\n}\n\nfunc (m *mux) Close() error {\n\treturn m.conn.Close()\n}\n\n// loop runs the connection machine. It will process packets until an\n// error is encountered. To synchronize on loop exit, use mux.Wait.\nfunc (m *mux) loop() {\n\tvar err error\n\tfor err == nil {\n\t\terr = m.onePacket()\n\t}\n\n\tfor _, ch := range m.chanList.dropAll() {\n\t\tch.close()\n\t}\n\n\tclose(m.incomingChannels)\n\tclose(m.incomingRequests)\n\tclose(m.globalResponses)\n\n\tm.conn.Close()\n\n\tm.errCond.L.Lock()\n\tm.err = err\n\tm.errCond.Broadcast()\n\tm.errCond.L.Unlock()\n\n\tif debugMux {\n\t\tlog.Println(\"loop exit\", err)\n\t}\n}\n\n// onePacket reads and processes one packet.\nfunc (m *mux) onePacket() error {\n\tpacket, err := m.conn.readPacket()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif debugMux {\n\t\tif packet[0] == msgChannelData || packet[0] == msgChannelExtendedData {\n\t\t\tlog.Printf(\"decoding(%d): data packet - %d bytes\", m.chanList.offset, len(packet))\n\t\t} else {\n\t\t\tp, _ := decode(packet)\n\t\t\tlog.Printf(\"decoding(%d): %d %#v - %d bytes\", m.chanList.offset, packet[0], p, len(packet))\n\t\t}\n\t}\n\n\tswitch packet[0] {\n\tcase msgChannelOpen:\n\t\treturn m.handleChannelOpen(packet)\n\tcase msgGlobalRequest, msgRequestSuccess, msgRequestFailure:\n\t\treturn m.handleGlobalPacket(packet)\n\tcase msgPing:\n\t\tvar msg pingMsg\n\t\tif err := Unmarshal(packet, &msg); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to unmarshal ping@openssh.com message: %w\", err)\n\t\t}\n\t\treturn m.sendMessage(pongMsg(msg))\n\t}\n\n\t// assume a channel packet.\n\tif len(packet) < 5 {\n\t\treturn parseError(packet[0])\n\t}\n\tid := binary.BigEndian.Uint32(packet[1:])\n\tch := m.chanList.getChan(id)\n\tif ch == nil {\n\t\treturn m.handleUnknownChannelPacket(id, packet)\n\t}\n\n\treturn ch.handlePacket(packet)\n}\n\nfunc (m *mux) handleGlobalPacket(packet []byte) error {\n\tmsg, err := decode(packet)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tswitch msg := msg.(type) {\n\tcase *globalRequestMsg:\n\t\tm.incomingRequests <- &Request{\n\t\t\tType:      msg.Type,\n\t\t\tWantReply: msg.WantReply,\n\t\t\tPayload:   msg.Data,\n\t\t\tmux:       m,\n\t\t}\n\tcase *globalRequestSuccessMsg, *globalRequestFailureMsg:\n\t\tm.globalResponses <- msg\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"not a global message %#v\", msg))\n\t}\n\n\treturn nil\n}\n\n// handleChannelOpen schedules a channel to be Accept()ed.\nfunc (m *mux) handleChannelOpen(packet []byte) error {\n\tvar msg channelOpenMsg\n\tif err := Unmarshal(packet, &msg); err != nil {\n\t\treturn err\n\t}\n\n\tif msg.MaxPacketSize < minPacketLength || msg.MaxPacketSize > 1<<31 {\n\t\tfailMsg := channelOpenFailureMsg{\n\t\t\tPeersID:  msg.PeersID,\n\t\t\tReason:   ConnectionFailed,\n\t\t\tMessage:  \"invalid request\",\n\t\t\tLanguage: \"en_US.UTF-8\",\n\t\t}\n\t\treturn m.sendMessage(failMsg)\n\t}\n\n\tc := m.newChannel(msg.ChanType, channelInbound, msg.TypeSpecificData)\n\tc.remoteId = msg.PeersID\n\tc.maxRemotePayload = msg.MaxPacketSize\n\tc.remoteWin.add(msg.PeersWindow)\n\tm.incomingChannels <- c\n\treturn nil\n}\n\nfunc (m *mux) OpenChannel(chanType string, extra []byte) (Channel, <-chan *Request, error) {\n\tch, err := m.openChannel(chanType, extra)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\treturn ch, ch.incomingRequests, nil\n}\n\nfunc (m *mux) openChannel(chanType string, extra []byte) (*channel, error) {\n\tch := m.newChannel(chanType, channelOutbound, extra)\n\n\tch.maxIncomingPayload = channelMaxPacket\n\n\topen := channelOpenMsg{\n\t\tChanType:         chanType,\n\t\tPeersWindow:      ch.myWindow,\n\t\tMaxPacketSize:    ch.maxIncomingPayload,\n\t\tTypeSpecificData: extra,\n\t\tPeersID:          ch.localId,\n\t}\n\tif err := m.sendMessage(open); err != nil {\n\t\treturn nil, err\n\t}\n\n\tswitch msg := (<-ch.msg).(type) {\n\tcase *channelOpenConfirmMsg:\n\t\treturn ch, nil\n\tcase *channelOpenFailureMsg:\n\t\treturn nil, &OpenChannelError{msg.Reason, msg.Message}\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"ssh: unexpected packet in response to channel open: %T\", msg)\n\t}\n}\n\nfunc (m *mux) handleUnknownChannelPacket(id uint32, packet []byte) error {\n\tmsg, err := decode(packet)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tswitch msg := msg.(type) {\n\t// RFC 4254 section 5.4 says unrecognized channel requests should\n\t// receive a failure response.\n\tcase *channelRequestMsg:\n\t\tif msg.WantReply {\n\t\t\treturn m.sendMessage(channelRequestFailureMsg{\n\t\t\t\tPeersID: msg.PeersID,\n\t\t\t})\n\t\t}\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"ssh: invalid channel %d\", id)\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/server.go",
    "content": "// Copyright 2011 The Go 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 ssh\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"strings\"\n)\n\n// The Permissions type holds fine-grained permissions that are\n// specific to a user or a specific authentication method for a user.\n// The Permissions value for a successful authentication attempt is\n// available in ServerConn, so it can be used to pass information from\n// the user-authentication phase to the application layer.\ntype Permissions struct {\n\t// CriticalOptions indicate restrictions to the default\n\t// permissions, and are typically used in conjunction with\n\t// user certificates. The standard for SSH certificates\n\t// defines \"force-command\" (only allow the given command to\n\t// execute) and \"source-address\" (only allow connections from\n\t// the given address). The SSH package currently only enforces\n\t// the \"source-address\" critical option. It is up to server\n\t// implementations to enforce other critical options, such as\n\t// \"force-command\", by checking them after the SSH handshake\n\t// is successful. In general, SSH servers should reject\n\t// connections that specify critical options that are unknown\n\t// or not supported.\n\tCriticalOptions map[string]string\n\n\t// Extensions are extra functionality that the server may\n\t// offer on authenticated connections. Lack of support for an\n\t// extension does not preclude authenticating a user. Common\n\t// extensions are \"permit-agent-forwarding\",\n\t// \"permit-X11-forwarding\". The Go SSH library currently does\n\t// not act on any extension, and it is up to server\n\t// implementations to honor them. Extensions can be used to\n\t// pass data from the authentication callbacks to the server\n\t// application layer.\n\tExtensions map[string]string\n}\n\ntype GSSAPIWithMICConfig struct {\n\t// AllowLogin, must be set, is called when gssapi-with-mic\n\t// authentication is selected (RFC 4462 section 3). The srcName is from the\n\t// results of the GSS-API authentication. The format is username@DOMAIN.\n\t// GSSAPI just guarantees to the server who the user is, but not if they can log in, and with what permissions.\n\t// This callback is called after the user identity is established with GSSAPI to decide if the user can login with\n\t// which permissions. If the user is allowed to login, it should return a nil error.\n\tAllowLogin func(conn ConnMetadata, srcName string) (*Permissions, error)\n\n\t// Server must be set. It's the implementation\n\t// of the GSSAPIServer interface. See GSSAPIServer interface for details.\n\tServer GSSAPIServer\n}\n\n// SendAuthBanner implements [ServerPreAuthConn].\nfunc (s *connection) SendAuthBanner(msg string) error {\n\treturn s.transport.writePacket(Marshal(&userAuthBannerMsg{\n\t\tMessage: msg,\n\t}))\n}\n\nfunc (*connection) unexportedMethodForFutureProofing() {}\n\n// ServerPreAuthConn is the interface available on an incoming server\n// connection before authentication has completed.\ntype ServerPreAuthConn interface {\n\tunexportedMethodForFutureProofing() // permits growing ServerPreAuthConn safely later, ala testing.TB\n\n\tConnMetadata\n\n\t// SendAuthBanner sends a banner message to the client.\n\t// It returns an error once the authentication phase has ended.\n\tSendAuthBanner(string) error\n}\n\n// ServerConfig holds server specific configuration data.\ntype ServerConfig struct {\n\t// Config contains configuration shared between client and server.\n\tConfig\n\n\t// PublicKeyAuthAlgorithms specifies the supported client public key\n\t// authentication algorithms. Note that this should not include certificate\n\t// types since those use the underlying algorithm. This list is sent to the\n\t// client if it supports the server-sig-algs extension. Order is irrelevant.\n\t// If unspecified then a default set of algorithms is used.\n\tPublicKeyAuthAlgorithms []string\n\n\thostKeys []Signer\n\n\t// NoClientAuth is true if clients are allowed to connect without\n\t// authenticating.\n\t// To determine NoClientAuth at runtime, set NoClientAuth to true\n\t// and the optional NoClientAuthCallback to a non-nil value.\n\tNoClientAuth bool\n\n\t// NoClientAuthCallback, if non-nil, is called when a user\n\t// attempts to authenticate with auth method \"none\".\n\t// NoClientAuth must also be set to true for this be used, or\n\t// this func is unused.\n\tNoClientAuthCallback func(ConnMetadata) (*Permissions, error)\n\n\t// MaxAuthTries specifies the maximum number of authentication attempts\n\t// permitted per connection. If set to a negative number, the number of\n\t// attempts are unlimited. If set to zero, the number of attempts are limited\n\t// to 6.\n\tMaxAuthTries int\n\n\t// PasswordCallback, if non-nil, is called when a user\n\t// attempts to authenticate using a password.\n\tPasswordCallback func(conn ConnMetadata, password []byte) (*Permissions, error)\n\n\t// PublicKeyCallback, if non-nil, is called when a client\n\t// offers a public key for authentication. It must return a nil error\n\t// if the given public key can be used to authenticate the\n\t// given user. For example, see CertChecker.Authenticate. A\n\t// call to this function does not guarantee that the key\n\t// offered is in fact used to authenticate. To record any data\n\t// depending on the public key, store it inside a\n\t// Permissions.Extensions entry.\n\tPublicKeyCallback func(conn ConnMetadata, key PublicKey) (*Permissions, error)\n\n\t// KeyboardInteractiveCallback, if non-nil, is called when\n\t// keyboard-interactive authentication is selected (RFC\n\t// 4256). The client object's Challenge function should be\n\t// used to query the user. The callback may offer multiple\n\t// Challenge rounds. To avoid information leaks, the client\n\t// should be presented a challenge even if the user is\n\t// unknown.\n\tKeyboardInteractiveCallback func(conn ConnMetadata, client KeyboardInteractiveChallenge) (*Permissions, error)\n\n\t// AuthLogCallback, if non-nil, is called to log all authentication\n\t// attempts.\n\tAuthLogCallback func(conn ConnMetadata, method string, err error)\n\n\t// PreAuthConnCallback, if non-nil, is called upon receiving a new connection\n\t// before any authentication has started. The provided ServerPreAuthConn\n\t// can be used at any time before authentication is complete, including\n\t// after this callback has returned.\n\tPreAuthConnCallback func(ServerPreAuthConn)\n\n\t// ServerVersion is the version identification string to announce in\n\t// the public handshake.\n\t// If empty, a reasonable default is used.\n\t// Note that RFC 4253 section 4.2 requires that this string start with\n\t// \"SSH-2.0-\".\n\tServerVersion string\n\n\t// BannerCallback, if present, is called and the return string is sent to\n\t// the client after key exchange completed but before authentication.\n\tBannerCallback func(conn ConnMetadata) string\n\n\t// GSSAPIWithMICConfig includes gssapi server and callback, which if both non-nil, is used\n\t// when gssapi-with-mic authentication is selected (RFC 4462 section 3).\n\tGSSAPIWithMICConfig *GSSAPIWithMICConfig\n}\n\n// AddHostKey adds a private key as a host key. If an existing host\n// key exists with the same public key format, it is replaced. Each server\n// config must have at least one host key.\nfunc (s *ServerConfig) AddHostKey(key Signer) {\n\tfor i, k := range s.hostKeys {\n\t\tif k.PublicKey().Type() == key.PublicKey().Type() {\n\t\t\ts.hostKeys[i] = key\n\t\t\treturn\n\t\t}\n\t}\n\n\ts.hostKeys = append(s.hostKeys, key)\n}\n\n// cachedPubKey contains the results of querying whether a public key is\n// acceptable for a user. This is a FIFO cache.\ntype cachedPubKey struct {\n\tuser       string\n\tpubKeyData []byte\n\tresult     error\n\tperms      *Permissions\n}\n\n// maxCachedPubKeys is the number of cache entries we store.\n//\n// Due to consistent misuse of the PublicKeyCallback API, we have reduced this\n// to 1, such that the only key in the cache is the most recently seen one. This\n// forces the behavior that the last call to PublicKeyCallback will always be\n// with the key that is used for authentication.\nconst maxCachedPubKeys = 1\n\n// pubKeyCache caches tests for public keys.  Since SSH clients\n// will query whether a public key is acceptable before attempting to\n// authenticate with it, we end up with duplicate queries for public\n// key validity.  The cache only applies to a single ServerConn.\ntype pubKeyCache struct {\n\tkeys []cachedPubKey\n}\n\n// get returns the result for a given user/algo/key tuple.\nfunc (c *pubKeyCache) get(user string, pubKeyData []byte) (cachedPubKey, bool) {\n\tfor _, k := range c.keys {\n\t\tif k.user == user && bytes.Equal(k.pubKeyData, pubKeyData) {\n\t\t\treturn k, true\n\t\t}\n\t}\n\treturn cachedPubKey{}, false\n}\n\n// add adds the given tuple to the cache.\nfunc (c *pubKeyCache) add(candidate cachedPubKey) {\n\tif len(c.keys) >= maxCachedPubKeys {\n\t\tc.keys = c.keys[1:]\n\t}\n\tc.keys = append(c.keys, candidate)\n}\n\n// ServerConn is an authenticated SSH connection, as seen from the\n// server\ntype ServerConn struct {\n\tConn\n\n\t// If the succeeding authentication callback returned a\n\t// non-nil Permissions pointer, it is stored here.\n\tPermissions *Permissions\n}\n\n// NewServerConn starts a new SSH server with c as the underlying\n// transport.  It starts with a handshake and, if the handshake is\n// unsuccessful, it closes the connection and returns an error.  The\n// Request and NewChannel channels must be serviced, or the connection\n// will hang.\n//\n// The returned error may be of type *ServerAuthError for\n// authentication errors.\nfunc NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewChannel, <-chan *Request, error) {\n\tfullConf := *config\n\tfullConf.SetDefaults()\n\tif fullConf.MaxAuthTries == 0 {\n\t\tfullConf.MaxAuthTries = 6\n\t}\n\tif len(fullConf.PublicKeyAuthAlgorithms) == 0 {\n\t\tfullConf.PublicKeyAuthAlgorithms = supportedPubKeyAuthAlgos\n\t} else {\n\t\tfor _, algo := range fullConf.PublicKeyAuthAlgorithms {\n\t\t\tif !contains(supportedPubKeyAuthAlgos, algo) {\n\t\t\t\tc.Close()\n\t\t\t\treturn nil, nil, nil, fmt.Errorf(\"ssh: unsupported public key authentication algorithm %s\", algo)\n\t\t\t}\n\t\t}\n\t}\n\t// Check if the config contains any unsupported key exchanges\n\tfor _, kex := range fullConf.KeyExchanges {\n\t\tif _, ok := serverForbiddenKexAlgos[kex]; ok {\n\t\t\tc.Close()\n\t\t\treturn nil, nil, nil, fmt.Errorf(\"ssh: unsupported key exchange %s for server\", kex)\n\t\t}\n\t}\n\n\ts := &connection{\n\t\tsshConn: sshConn{conn: c},\n\t}\n\tperms, err := s.serverHandshake(&fullConf)\n\tif err != nil {\n\t\tc.Close()\n\t\treturn nil, nil, nil, err\n\t}\n\treturn &ServerConn{s, perms}, s.mux.incomingChannels, s.mux.incomingRequests, nil\n}\n\n// signAndMarshal signs the data with the appropriate algorithm,\n// and serializes the result in SSH wire format. algo is the negotiate\n// algorithm and may be a certificate type.\nfunc signAndMarshal(k AlgorithmSigner, rand io.Reader, data []byte, algo string) ([]byte, error) {\n\tsig, err := k.SignWithAlgorithm(rand, data, underlyingAlgo(algo))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn Marshal(sig), nil\n}\n\n// handshake performs key exchange and user authentication.\nfunc (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error) {\n\tif len(config.hostKeys) == 0 {\n\t\treturn nil, errors.New(\"ssh: server has no host keys\")\n\t}\n\n\tif !config.NoClientAuth && config.PasswordCallback == nil && config.PublicKeyCallback == nil &&\n\t\tconfig.KeyboardInteractiveCallback == nil && (config.GSSAPIWithMICConfig == nil ||\n\t\tconfig.GSSAPIWithMICConfig.AllowLogin == nil || config.GSSAPIWithMICConfig.Server == nil) {\n\t\treturn nil, errors.New(\"ssh: no authentication methods configured but NoClientAuth is also false\")\n\t}\n\n\tif config.ServerVersion != \"\" {\n\t\ts.serverVersion = []byte(config.ServerVersion)\n\t} else {\n\t\ts.serverVersion = []byte(packageVersion)\n\t}\n\tvar err error\n\ts.clientVersion, err = exchangeVersions(s.sshConn.conn, s.serverVersion)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttr := newTransport(s.sshConn.conn, config.Rand, false /* not client */)\n\ts.transport = newServerTransport(tr, s.clientVersion, s.serverVersion, config)\n\n\tif err := s.transport.waitSession(); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// We just did the key change, so the session ID is established.\n\ts.sessionID = s.transport.getSessionID()\n\n\tvar packet []byte\n\tif packet, err = s.transport.readPacket(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar serviceRequest serviceRequestMsg\n\tif err = Unmarshal(packet, &serviceRequest); err != nil {\n\t\treturn nil, err\n\t}\n\tif serviceRequest.Service != serviceUserAuth {\n\t\treturn nil, errors.New(\"ssh: requested service '\" + serviceRequest.Service + \"' before authenticating\")\n\t}\n\tserviceAccept := serviceAcceptMsg{\n\t\tService: serviceUserAuth,\n\t}\n\tif err := s.transport.writePacket(Marshal(&serviceAccept)); err != nil {\n\t\treturn nil, err\n\t}\n\n\tperms, err := s.serverAuthenticate(config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ts.mux = newMux(s.transport)\n\treturn perms, err\n}\n\nfunc checkSourceAddress(addr net.Addr, sourceAddrs string) error {\n\tif addr == nil {\n\t\treturn errors.New(\"ssh: no address known for client, but source-address match required\")\n\t}\n\n\ttcpAddr, ok := addr.(*net.TCPAddr)\n\tif !ok {\n\t\treturn fmt.Errorf(\"ssh: remote address %v is not an TCP address when checking source-address match\", addr)\n\t}\n\n\tfor _, sourceAddr := range strings.Split(sourceAddrs, \",\") {\n\t\tif allowedIP := net.ParseIP(sourceAddr); allowedIP != nil {\n\t\t\tif allowedIP.Equal(tcpAddr.IP) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t} else {\n\t\t\t_, ipNet, err := net.ParseCIDR(sourceAddr)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"ssh: error parsing source-address restriction %q: %v\", sourceAddr, err)\n\t\t\t}\n\n\t\t\tif ipNet.Contains(tcpAddr.IP) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fmt.Errorf(\"ssh: remote address %v is not allowed because of source-address restriction\", addr)\n}\n\nfunc gssExchangeToken(gssapiConfig *GSSAPIWithMICConfig, token []byte, s *connection,\n\tsessionID []byte, userAuthReq userAuthRequestMsg) (authErr error, perms *Permissions, err error) {\n\tgssAPIServer := gssapiConfig.Server\n\tdefer gssAPIServer.DeleteSecContext()\n\tvar srcName string\n\tfor {\n\t\tvar (\n\t\t\toutToken     []byte\n\t\t\tneedContinue bool\n\t\t)\n\t\toutToken, srcName, needContinue, err = gssAPIServer.AcceptSecContext(token)\n\t\tif err != nil {\n\t\t\treturn err, nil, nil\n\t\t}\n\t\tif len(outToken) != 0 {\n\t\t\tif err := s.transport.writePacket(Marshal(&userAuthGSSAPIToken{\n\t\t\t\tToken: outToken,\n\t\t\t})); err != nil {\n\t\t\t\treturn nil, nil, err\n\t\t\t}\n\t\t}\n\t\tif !needContinue {\n\t\t\tbreak\n\t\t}\n\t\tpacket, err := s.transport.readPacket()\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t\tuserAuthGSSAPITokenReq := &userAuthGSSAPIToken{}\n\t\tif err := Unmarshal(packet, userAuthGSSAPITokenReq); err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t\ttoken = userAuthGSSAPITokenReq.Token\n\t}\n\tpacket, err := s.transport.readPacket()\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tuserAuthGSSAPIMICReq := &userAuthGSSAPIMIC{}\n\tif err := Unmarshal(packet, userAuthGSSAPIMICReq); err != nil {\n\t\treturn nil, nil, err\n\t}\n\tmic := buildMIC(string(sessionID), userAuthReq.User, userAuthReq.Service, userAuthReq.Method)\n\tif err := gssAPIServer.VerifyMIC(mic, userAuthGSSAPIMICReq.MIC); err != nil {\n\t\treturn err, nil, nil\n\t}\n\tperms, authErr = gssapiConfig.AllowLogin(s, srcName)\n\treturn authErr, perms, nil\n}\n\n// isAlgoCompatible checks if the signature format is compatible with the\n// selected algorithm taking into account edge cases that occur with old\n// clients.\nfunc isAlgoCompatible(algo, sigFormat string) bool {\n\t// Compatibility for old clients.\n\t//\n\t// For certificate authentication with OpenSSH 7.2-7.7 signature format can\n\t// be rsa-sha2-256 or rsa-sha2-512 for the algorithm\n\t// ssh-rsa-cert-v01@openssh.com.\n\t//\n\t// With gpg-agent < 2.2.6 the algorithm can be rsa-sha2-256 or rsa-sha2-512\n\t// for signature format ssh-rsa.\n\tif isRSA(algo) && isRSA(sigFormat) {\n\t\treturn true\n\t}\n\t// Standard case: the underlying algorithm must match the signature format.\n\treturn underlyingAlgo(algo) == sigFormat\n}\n\n// ServerAuthError represents server authentication errors and is\n// sometimes returned by NewServerConn. It appends any authentication\n// errors that may occur, and is returned if all of the authentication\n// methods provided by the user failed to authenticate.\ntype ServerAuthError struct {\n\t// Errors contains authentication errors returned by the authentication\n\t// callback methods. The first entry is typically ErrNoAuth.\n\tErrors []error\n}\n\nfunc (l ServerAuthError) Error() string {\n\tvar errs []string\n\tfor _, err := range l.Errors {\n\t\terrs = append(errs, err.Error())\n\t}\n\treturn \"[\" + strings.Join(errs, \", \") + \"]\"\n}\n\n// ServerAuthCallbacks defines server-side authentication callbacks.\ntype ServerAuthCallbacks struct {\n\t// PasswordCallback behaves like [ServerConfig.PasswordCallback].\n\tPasswordCallback func(conn ConnMetadata, password []byte) (*Permissions, error)\n\n\t// PublicKeyCallback behaves like [ServerConfig.PublicKeyCallback].\n\tPublicKeyCallback func(conn ConnMetadata, key PublicKey) (*Permissions, error)\n\n\t// KeyboardInteractiveCallback behaves like [ServerConfig.KeyboardInteractiveCallback].\n\tKeyboardInteractiveCallback func(conn ConnMetadata, client KeyboardInteractiveChallenge) (*Permissions, error)\n\n\t// GSSAPIWithMICConfig behaves like [ServerConfig.GSSAPIWithMICConfig].\n\tGSSAPIWithMICConfig *GSSAPIWithMICConfig\n}\n\n// PartialSuccessError can be returned by any of the [ServerConfig]\n// authentication callbacks to indicate to the client that authentication has\n// partially succeeded, but further steps are required.\ntype PartialSuccessError struct {\n\t// Next defines the authentication callbacks to apply to further steps. The\n\t// available methods communicated to the client are based on the non-nil\n\t// ServerAuthCallbacks fields.\n\tNext ServerAuthCallbacks\n}\n\nfunc (p *PartialSuccessError) Error() string {\n\treturn \"ssh: authenticated with partial success\"\n}\n\n// ErrNoAuth is the error value returned if no\n// authentication method has been passed yet. This happens as a normal\n// part of the authentication loop, since the client first tries\n// 'none' authentication to discover available methods.\n// It is returned in ServerAuthError.Errors from NewServerConn.\nvar ErrNoAuth = errors.New(\"ssh: no auth passed yet\")\n\n// BannerError is an error that can be returned by authentication handlers in\n// ServerConfig to send a banner message to the client.\ntype BannerError struct {\n\tErr     error\n\tMessage string\n}\n\nfunc (b *BannerError) Unwrap() error {\n\treturn b.Err\n}\n\nfunc (b *BannerError) Error() string {\n\tif b.Err == nil {\n\t\treturn b.Message\n\t}\n\treturn b.Err.Error()\n}\n\nfunc (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, error) {\n\tif config.PreAuthConnCallback != nil {\n\t\tconfig.PreAuthConnCallback(s)\n\t}\n\n\tsessionID := s.transport.getSessionID()\n\tvar cache pubKeyCache\n\tvar perms *Permissions\n\n\tauthFailures := 0\n\tnoneAuthCount := 0\n\tvar authErrs []error\n\tvar calledBannerCallback bool\n\tpartialSuccessReturned := false\n\t// Set the initial authentication callbacks from the config. They can be\n\t// changed if a PartialSuccessError is returned.\n\tauthConfig := ServerAuthCallbacks{\n\t\tPasswordCallback:            config.PasswordCallback,\n\t\tPublicKeyCallback:           config.PublicKeyCallback,\n\t\tKeyboardInteractiveCallback: config.KeyboardInteractiveCallback,\n\t\tGSSAPIWithMICConfig:         config.GSSAPIWithMICConfig,\n\t}\n\nuserAuthLoop:\n\tfor {\n\t\tif authFailures >= config.MaxAuthTries && config.MaxAuthTries > 0 {\n\t\t\tdiscMsg := &disconnectMsg{\n\t\t\t\tReason:  2,\n\t\t\t\tMessage: \"too many authentication failures\",\n\t\t\t}\n\n\t\t\tif err := s.transport.writePacket(Marshal(discMsg)); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tauthErrs = append(authErrs, discMsg)\n\t\t\treturn nil, &ServerAuthError{Errors: authErrs}\n\t\t}\n\n\t\tvar userAuthReq userAuthRequestMsg\n\t\tif packet, err := s.transport.readPacket(); err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\treturn nil, &ServerAuthError{Errors: authErrs}\n\t\t\t}\n\t\t\treturn nil, err\n\t\t} else if err = Unmarshal(packet, &userAuthReq); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif userAuthReq.Service != serviceSSH {\n\t\t\treturn nil, errors.New(\"ssh: client attempted to negotiate for unknown service: \" + userAuthReq.Service)\n\t\t}\n\n\t\tif s.user != userAuthReq.User && partialSuccessReturned {\n\t\t\treturn nil, fmt.Errorf(\"ssh: client changed the user after a partial success authentication, previous user %q, current user %q\",\n\t\t\t\ts.user, userAuthReq.User)\n\t\t}\n\n\t\ts.user = userAuthReq.User\n\n\t\tif !calledBannerCallback && config.BannerCallback != nil {\n\t\t\tcalledBannerCallback = true\n\t\t\tif msg := config.BannerCallback(s); msg != \"\" {\n\t\t\t\tif err := s.SendAuthBanner(msg); err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tperms = nil\n\t\tauthErr := ErrNoAuth\n\n\t\tswitch userAuthReq.Method {\n\t\tcase \"none\":\n\t\t\tnoneAuthCount++\n\t\t\t// We don't allow none authentication after a partial success\n\t\t\t// response.\n\t\t\tif config.NoClientAuth && !partialSuccessReturned {\n\t\t\t\tif config.NoClientAuthCallback != nil {\n\t\t\t\t\tperms, authErr = config.NoClientAuthCallback(s)\n\t\t\t\t} else {\n\t\t\t\t\tauthErr = nil\n\t\t\t\t}\n\t\t\t}\n\t\tcase \"password\":\n\t\t\tif authConfig.PasswordCallback == nil {\n\t\t\t\tauthErr = errors.New(\"ssh: password auth not configured\")\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tpayload := userAuthReq.Payload\n\t\t\tif len(payload) < 1 || payload[0] != 0 {\n\t\t\t\treturn nil, parseError(msgUserAuthRequest)\n\t\t\t}\n\t\t\tpayload = payload[1:]\n\t\t\tpassword, payload, ok := parseString(payload)\n\t\t\tif !ok || len(payload) > 0 {\n\t\t\t\treturn nil, parseError(msgUserAuthRequest)\n\t\t\t}\n\n\t\t\tperms, authErr = authConfig.PasswordCallback(s, password)\n\t\tcase \"keyboard-interactive\":\n\t\t\tif authConfig.KeyboardInteractiveCallback == nil {\n\t\t\t\tauthErr = errors.New(\"ssh: keyboard-interactive auth not configured\")\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tprompter := &sshClientKeyboardInteractive{s}\n\t\t\tperms, authErr = authConfig.KeyboardInteractiveCallback(s, prompter.Challenge)\n\t\tcase \"publickey\":\n\t\t\tif authConfig.PublicKeyCallback == nil {\n\t\t\t\tauthErr = errors.New(\"ssh: publickey auth not configured\")\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tpayload := userAuthReq.Payload\n\t\t\tif len(payload) < 1 {\n\t\t\t\treturn nil, parseError(msgUserAuthRequest)\n\t\t\t}\n\t\t\tisQuery := payload[0] == 0\n\t\t\tpayload = payload[1:]\n\t\t\talgoBytes, payload, ok := parseString(payload)\n\t\t\tif !ok {\n\t\t\t\treturn nil, parseError(msgUserAuthRequest)\n\t\t\t}\n\t\t\talgo := string(algoBytes)\n\t\t\tif !contains(config.PublicKeyAuthAlgorithms, underlyingAlgo(algo)) {\n\t\t\t\tauthErr = fmt.Errorf(\"ssh: algorithm %q not accepted\", algo)\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tpubKeyData, payload, ok := parseString(payload)\n\t\t\tif !ok {\n\t\t\t\treturn nil, parseError(msgUserAuthRequest)\n\t\t\t}\n\n\t\t\tpubKey, err := ParsePublicKey(pubKeyData)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tcandidate, ok := cache.get(s.user, pubKeyData)\n\t\t\tif !ok {\n\t\t\t\tcandidate.user = s.user\n\t\t\t\tcandidate.pubKeyData = pubKeyData\n\t\t\t\tcandidate.perms, candidate.result = authConfig.PublicKeyCallback(s, pubKey)\n\t\t\t\t_, isPartialSuccessError := candidate.result.(*PartialSuccessError)\n\n\t\t\t\tif (candidate.result == nil || isPartialSuccessError) &&\n\t\t\t\t\tcandidate.perms != nil &&\n\t\t\t\t\tcandidate.perms.CriticalOptions != nil &&\n\t\t\t\t\tcandidate.perms.CriticalOptions[sourceAddressCriticalOption] != \"\" {\n\t\t\t\t\tif err := checkSourceAddress(\n\t\t\t\t\t\ts.RemoteAddr(),\n\t\t\t\t\t\tcandidate.perms.CriticalOptions[sourceAddressCriticalOption]); err != nil {\n\t\t\t\t\t\tcandidate.result = err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcache.add(candidate)\n\t\t\t}\n\n\t\t\tif isQuery {\n\t\t\t\t// The client can query if the given public key\n\t\t\t\t// would be okay.\n\n\t\t\t\tif len(payload) > 0 {\n\t\t\t\t\treturn nil, parseError(msgUserAuthRequest)\n\t\t\t\t}\n\t\t\t\t_, isPartialSuccessError := candidate.result.(*PartialSuccessError)\n\t\t\t\tif candidate.result == nil || isPartialSuccessError {\n\t\t\t\t\tokMsg := userAuthPubKeyOkMsg{\n\t\t\t\t\t\tAlgo:   algo,\n\t\t\t\t\t\tPubKey: pubKeyData,\n\t\t\t\t\t}\n\t\t\t\t\tif err = s.transport.writePacket(Marshal(&okMsg)); err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\t\t\t\t\tcontinue userAuthLoop\n\t\t\t\t}\n\t\t\t\tauthErr = candidate.result\n\t\t\t} else {\n\t\t\t\tsig, payload, ok := parseSignature(payload)\n\t\t\t\tif !ok || len(payload) > 0 {\n\t\t\t\t\treturn nil, parseError(msgUserAuthRequest)\n\t\t\t\t}\n\t\t\t\t// Ensure the declared public key algo is compatible with the\n\t\t\t\t// decoded one. This check will ensure we don't accept e.g.\n\t\t\t\t// ssh-rsa-cert-v01@openssh.com algorithm with ssh-rsa public\n\t\t\t\t// key type. The algorithm and public key type must be\n\t\t\t\t// consistent: both must be certificate algorithms, or neither.\n\t\t\t\tif !contains(algorithmsForKeyFormat(pubKey.Type()), algo) {\n\t\t\t\t\tauthErr = fmt.Errorf(\"ssh: public key type %q not compatible with selected algorithm %q\",\n\t\t\t\t\t\tpubKey.Type(), algo)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\t// Ensure the public key algo and signature algo\n\t\t\t\t// are supported.  Compare the private key\n\t\t\t\t// algorithm name that corresponds to algo with\n\t\t\t\t// sig.Format.  This is usually the same, but\n\t\t\t\t// for certs, the names differ.\n\t\t\t\tif !contains(config.PublicKeyAuthAlgorithms, sig.Format) {\n\t\t\t\t\tauthErr = fmt.Errorf(\"ssh: algorithm %q not accepted\", sig.Format)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif !isAlgoCompatible(algo, sig.Format) {\n\t\t\t\t\tauthErr = fmt.Errorf(\"ssh: signature %q not compatible with selected algorithm %q\", sig.Format, algo)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tsignedData := buildDataSignedForAuth(sessionID, userAuthReq, algo, pubKeyData)\n\n\t\t\t\tif err := pubKey.Verify(signedData, sig); err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\n\t\t\t\tauthErr = candidate.result\n\t\t\t\tperms = candidate.perms\n\t\t\t}\n\t\tcase \"gssapi-with-mic\":\n\t\t\tif authConfig.GSSAPIWithMICConfig == nil {\n\t\t\t\tauthErr = errors.New(\"ssh: gssapi-with-mic auth not configured\")\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tgssapiConfig := authConfig.GSSAPIWithMICConfig\n\t\t\tuserAuthRequestGSSAPI, err := parseGSSAPIPayload(userAuthReq.Payload)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, parseError(msgUserAuthRequest)\n\t\t\t}\n\t\t\t// OpenSSH supports Kerberos V5 mechanism only for GSS-API authentication.\n\t\t\tif userAuthRequestGSSAPI.N == 0 {\n\t\t\t\tauthErr = fmt.Errorf(\"ssh: Mechanism negotiation is not supported\")\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tvar i uint32\n\t\t\tpresent := false\n\t\t\tfor i = 0; i < userAuthRequestGSSAPI.N; i++ {\n\t\t\t\tif userAuthRequestGSSAPI.OIDS[i].Equal(krb5Mesh) {\n\t\t\t\t\tpresent = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !present {\n\t\t\t\tauthErr = fmt.Errorf(\"ssh: GSSAPI authentication must use the Kerberos V5 mechanism\")\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t// Initial server response, see RFC 4462 section 3.3.\n\t\t\tif err := s.transport.writePacket(Marshal(&userAuthGSSAPIResponse{\n\t\t\t\tSupportMech: krb5OID,\n\t\t\t})); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\t// Exchange token, see RFC 4462 section 3.4.\n\t\t\tpacket, err := s.transport.readPacket()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tuserAuthGSSAPITokenReq := &userAuthGSSAPIToken{}\n\t\t\tif err := Unmarshal(packet, userAuthGSSAPITokenReq); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tauthErr, perms, err = gssExchangeToken(gssapiConfig, userAuthGSSAPITokenReq.Token, s, sessionID,\n\t\t\t\tuserAuthReq)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\tdefault:\n\t\t\tauthErr = fmt.Errorf(\"ssh: unknown method %q\", userAuthReq.Method)\n\t\t}\n\n\t\tauthErrs = append(authErrs, authErr)\n\n\t\tif config.AuthLogCallback != nil {\n\t\t\tconfig.AuthLogCallback(s, userAuthReq.Method, authErr)\n\t\t}\n\n\t\tvar bannerErr *BannerError\n\t\tif errors.As(authErr, &bannerErr) {\n\t\t\tif bannerErr.Message != \"\" {\n\t\t\t\tif err := s.SendAuthBanner(bannerErr.Message); err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif authErr == nil {\n\t\t\tbreak userAuthLoop\n\t\t}\n\n\t\tvar failureMsg userAuthFailureMsg\n\n\t\tif partialSuccess, ok := authErr.(*PartialSuccessError); ok {\n\t\t\t// After a partial success error we don't allow changing the user\n\t\t\t// name and execute the NoClientAuthCallback.\n\t\t\tpartialSuccessReturned = true\n\n\t\t\t// In case a partial success is returned, the server may send\n\t\t\t// a new set of authentication methods.\n\t\t\tauthConfig = partialSuccess.Next\n\n\t\t\t// Reset pubkey cache, as the new PublicKeyCallback might\n\t\t\t// accept a different set of public keys.\n\t\t\tcache = pubKeyCache{}\n\n\t\t\t// Send back a partial success message to the user.\n\t\t\tfailureMsg.PartialSuccess = true\n\t\t} else {\n\t\t\t// Allow initial attempt of 'none' without penalty.\n\t\t\tif authFailures > 0 || userAuthReq.Method != \"none\" || noneAuthCount != 1 {\n\t\t\t\tauthFailures++\n\t\t\t}\n\t\t\tif config.MaxAuthTries > 0 && authFailures >= config.MaxAuthTries {\n\t\t\t\t// If we have hit the max attempts, don't bother sending the\n\t\t\t\t// final SSH_MSG_USERAUTH_FAILURE message, since there are\n\t\t\t\t// no more authentication methods which can be attempted,\n\t\t\t\t// and this message may cause the client to re-attempt\n\t\t\t\t// authentication while we send the disconnect message.\n\t\t\t\t// Continue, and trigger the disconnect at the start of\n\t\t\t\t// the loop.\n\t\t\t\t//\n\t\t\t\t// The SSH specification is somewhat confusing about this,\n\t\t\t\t// RFC 4252 Section 5.1 requires each authentication failure\n\t\t\t\t// be responded to with a respective SSH_MSG_USERAUTH_FAILURE\n\t\t\t\t// message, but Section 4 says the server should disconnect\n\t\t\t\t// after some number of attempts, but it isn't explicit which\n\t\t\t\t// message should take precedence (i.e. should there be a failure\n\t\t\t\t// message than a disconnect message, or if we are going to\n\t\t\t\t// disconnect, should we only send that message.)\n\t\t\t\t//\n\t\t\t\t// Either way, OpenSSH disconnects immediately after the last\n\t\t\t\t// failed authentication attempt, and given they are typically\n\t\t\t\t// considered the golden implementation it seems reasonable\n\t\t\t\t// to match that behavior.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tif authConfig.PasswordCallback != nil {\n\t\t\tfailureMsg.Methods = append(failureMsg.Methods, \"password\")\n\t\t}\n\t\tif authConfig.PublicKeyCallback != nil {\n\t\t\tfailureMsg.Methods = append(failureMsg.Methods, \"publickey\")\n\t\t}\n\t\tif authConfig.KeyboardInteractiveCallback != nil {\n\t\t\tfailureMsg.Methods = append(failureMsg.Methods, \"keyboard-interactive\")\n\t\t}\n\t\tif authConfig.GSSAPIWithMICConfig != nil && authConfig.GSSAPIWithMICConfig.Server != nil &&\n\t\t\tauthConfig.GSSAPIWithMICConfig.AllowLogin != nil {\n\t\t\tfailureMsg.Methods = append(failureMsg.Methods, \"gssapi-with-mic\")\n\t\t}\n\n\t\tif len(failureMsg.Methods) == 0 {\n\t\t\treturn nil, errors.New(\"ssh: no authentication methods available\")\n\t\t}\n\n\t\tif err := s.transport.writePacket(Marshal(&failureMsg)); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif err := s.transport.writePacket([]byte{msgUserAuthSuccess}); err != nil {\n\t\treturn nil, err\n\t}\n\treturn perms, nil\n}\n\n// sshClientKeyboardInteractive implements a ClientKeyboardInteractive by\n// asking the client on the other side of a ServerConn.\ntype sshClientKeyboardInteractive struct {\n\t*connection\n}\n\nfunc (c *sshClientKeyboardInteractive) Challenge(name, instruction string, questions []string, echos []bool) (answers []string, err error) {\n\tif len(questions) != len(echos) {\n\t\treturn nil, errors.New(\"ssh: echos and questions must have equal length\")\n\t}\n\n\tvar prompts []byte\n\tfor i := range questions {\n\t\tprompts = appendString(prompts, questions[i])\n\t\tprompts = appendBool(prompts, echos[i])\n\t}\n\n\tif err := c.transport.writePacket(Marshal(&userAuthInfoRequestMsg{\n\t\tName:        name,\n\t\tInstruction: instruction,\n\t\tNumPrompts:  uint32(len(questions)),\n\t\tPrompts:     prompts,\n\t})); err != nil {\n\t\treturn nil, err\n\t}\n\n\tpacket, err := c.transport.readPacket()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif packet[0] != msgUserAuthInfoResponse {\n\t\treturn nil, unexpectedMessageError(msgUserAuthInfoResponse, packet[0])\n\t}\n\tpacket = packet[1:]\n\n\tn, packet, ok := parseUint32(packet)\n\tif !ok || int(n) != len(questions) {\n\t\treturn nil, parseError(msgUserAuthInfoResponse)\n\t}\n\n\tfor i := uint32(0); i < n; i++ {\n\t\tans, rest, ok := parseString(packet)\n\t\tif !ok {\n\t\t\treturn nil, parseError(msgUserAuthInfoResponse)\n\t\t}\n\n\t\tanswers = append(answers, string(ans))\n\t\tpacket = rest\n\t}\n\tif len(packet) != 0 {\n\t\treturn nil, errors.New(\"ssh: junk at end of message\")\n\t}\n\n\treturn answers, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/session.go",
    "content": "// Copyright 2011 The Go 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 ssh\n\n// Session implements an interactive session described in\n// \"RFC 4254, section 6\".\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"sync\"\n)\n\ntype Signal string\n\n// POSIX signals as listed in RFC 4254 Section 6.10.\nconst (\n\tSIGABRT Signal = \"ABRT\"\n\tSIGALRM Signal = \"ALRM\"\n\tSIGFPE  Signal = \"FPE\"\n\tSIGHUP  Signal = \"HUP\"\n\tSIGILL  Signal = \"ILL\"\n\tSIGINT  Signal = \"INT\"\n\tSIGKILL Signal = \"KILL\"\n\tSIGPIPE Signal = \"PIPE\"\n\tSIGQUIT Signal = \"QUIT\"\n\tSIGSEGV Signal = \"SEGV\"\n\tSIGTERM Signal = \"TERM\"\n\tSIGUSR1 Signal = \"USR1\"\n\tSIGUSR2 Signal = \"USR2\"\n)\n\nvar signals = map[Signal]int{\n\tSIGABRT: 6,\n\tSIGALRM: 14,\n\tSIGFPE:  8,\n\tSIGHUP:  1,\n\tSIGILL:  4,\n\tSIGINT:  2,\n\tSIGKILL: 9,\n\tSIGPIPE: 13,\n\tSIGQUIT: 3,\n\tSIGSEGV: 11,\n\tSIGTERM: 15,\n}\n\ntype TerminalModes map[uint8]uint32\n\n// POSIX terminal mode flags as listed in RFC 4254 Section 8.\nconst (\n\ttty_OP_END    = 0\n\tVINTR         = 1\n\tVQUIT         = 2\n\tVERASE        = 3\n\tVKILL         = 4\n\tVEOF          = 5\n\tVEOL          = 6\n\tVEOL2         = 7\n\tVSTART        = 8\n\tVSTOP         = 9\n\tVSUSP         = 10\n\tVDSUSP        = 11\n\tVREPRINT      = 12\n\tVWERASE       = 13\n\tVLNEXT        = 14\n\tVFLUSH        = 15\n\tVSWTCH        = 16\n\tVSTATUS       = 17\n\tVDISCARD      = 18\n\tIGNPAR        = 30\n\tPARMRK        = 31\n\tINPCK         = 32\n\tISTRIP        = 33\n\tINLCR         = 34\n\tIGNCR         = 35\n\tICRNL         = 36\n\tIUCLC         = 37\n\tIXON          = 38\n\tIXANY         = 39\n\tIXOFF         = 40\n\tIMAXBEL       = 41\n\tIUTF8         = 42 // RFC 8160\n\tISIG          = 50\n\tICANON        = 51\n\tXCASE         = 52\n\tECHO          = 53\n\tECHOE         = 54\n\tECHOK         = 55\n\tECHONL        = 56\n\tNOFLSH        = 57\n\tTOSTOP        = 58\n\tIEXTEN        = 59\n\tECHOCTL       = 60\n\tECHOKE        = 61\n\tPENDIN        = 62\n\tOPOST         = 70\n\tOLCUC         = 71\n\tONLCR         = 72\n\tOCRNL         = 73\n\tONOCR         = 74\n\tONLRET        = 75\n\tCS7           = 90\n\tCS8           = 91\n\tPARENB        = 92\n\tPARODD        = 93\n\tTTY_OP_ISPEED = 128\n\tTTY_OP_OSPEED = 129\n)\n\n// A Session represents a connection to a remote command or shell.\ntype Session struct {\n\t// Stdin specifies the remote process's standard input.\n\t// If Stdin is nil, the remote process reads from an empty\n\t// bytes.Buffer.\n\tStdin io.Reader\n\n\t// Stdout and Stderr specify the remote process's standard\n\t// output and error.\n\t//\n\t// If either is nil, Run connects the corresponding file\n\t// descriptor to an instance of io.Discard. There is a\n\t// fixed amount of buffering that is shared for the two streams.\n\t// If either blocks it may eventually cause the remote\n\t// command to block.\n\tStdout io.Writer\n\tStderr io.Writer\n\n\tch        Channel // the channel backing this session\n\tstarted   bool    // true once Start, Run or Shell is invoked.\n\tcopyFuncs []func() error\n\terrors    chan error // one send per copyFunc\n\n\t// true if pipe method is active\n\tstdinpipe, stdoutpipe, stderrpipe bool\n\n\t// stdinPipeWriter is non-nil if StdinPipe has not been called\n\t// and Stdin was specified by the user; it is the write end of\n\t// a pipe connecting Session.Stdin to the stdin channel.\n\tstdinPipeWriter io.WriteCloser\n\n\texitStatus chan error\n}\n\n// SendRequest sends an out-of-band channel request on the SSH channel\n// underlying the session.\nfunc (s *Session) SendRequest(name string, wantReply bool, payload []byte) (bool, error) {\n\treturn s.ch.SendRequest(name, wantReply, payload)\n}\n\nfunc (s *Session) Close() error {\n\treturn s.ch.Close()\n}\n\n// RFC 4254 Section 6.4.\ntype setenvRequest struct {\n\tName  string\n\tValue string\n}\n\n// Setenv sets an environment variable that will be applied to any\n// command executed by Shell or Run.\nfunc (s *Session) Setenv(name, value string) error {\n\tmsg := setenvRequest{\n\t\tName:  name,\n\t\tValue: value,\n\t}\n\tok, err := s.ch.SendRequest(\"env\", true, Marshal(&msg))\n\tif err == nil && !ok {\n\t\terr = errors.New(\"ssh: setenv failed\")\n\t}\n\treturn err\n}\n\n// RFC 4254 Section 6.2.\ntype ptyRequestMsg struct {\n\tTerm     string\n\tColumns  uint32\n\tRows     uint32\n\tWidth    uint32\n\tHeight   uint32\n\tModelist string\n}\n\n// RequestPty requests the association of a pty with the session on the remote host.\nfunc (s *Session) RequestPty(term string, h, w int, termmodes TerminalModes) error {\n\tvar tm []byte\n\tfor k, v := range termmodes {\n\t\tkv := struct {\n\t\t\tKey byte\n\t\t\tVal uint32\n\t\t}{k, v}\n\n\t\ttm = append(tm, Marshal(&kv)...)\n\t}\n\ttm = append(tm, tty_OP_END)\n\treq := ptyRequestMsg{\n\t\tTerm:     term,\n\t\tColumns:  uint32(w),\n\t\tRows:     uint32(h),\n\t\tWidth:    uint32(w * 8),\n\t\tHeight:   uint32(h * 8),\n\t\tModelist: string(tm),\n\t}\n\tok, err := s.ch.SendRequest(\"pty-req\", true, Marshal(&req))\n\tif err == nil && !ok {\n\t\terr = errors.New(\"ssh: pty-req failed\")\n\t}\n\treturn err\n}\n\n// RFC 4254 Section 6.5.\ntype subsystemRequestMsg struct {\n\tSubsystem string\n}\n\n// RequestSubsystem requests the association of a subsystem with the session on the remote host.\n// A subsystem is a predefined command that runs in the background when the ssh session is initiated\nfunc (s *Session) RequestSubsystem(subsystem string) error {\n\tmsg := subsystemRequestMsg{\n\t\tSubsystem: subsystem,\n\t}\n\tok, err := s.ch.SendRequest(\"subsystem\", true, Marshal(&msg))\n\tif err == nil && !ok {\n\t\terr = errors.New(\"ssh: subsystem request failed\")\n\t}\n\treturn err\n}\n\n// RFC 4254 Section 6.7.\ntype ptyWindowChangeMsg struct {\n\tColumns uint32\n\tRows    uint32\n\tWidth   uint32\n\tHeight  uint32\n}\n\n// WindowChange informs the remote host about a terminal window dimension change to h rows and w columns.\nfunc (s *Session) WindowChange(h, w int) error {\n\treq := ptyWindowChangeMsg{\n\t\tColumns: uint32(w),\n\t\tRows:    uint32(h),\n\t\tWidth:   uint32(w * 8),\n\t\tHeight:  uint32(h * 8),\n\t}\n\t_, err := s.ch.SendRequest(\"window-change\", false, Marshal(&req))\n\treturn err\n}\n\n// RFC 4254 Section 6.9.\ntype signalMsg struct {\n\tSignal string\n}\n\n// Signal sends the given signal to the remote process.\n// sig is one of the SIG* constants.\nfunc (s *Session) Signal(sig Signal) error {\n\tmsg := signalMsg{\n\t\tSignal: string(sig),\n\t}\n\n\t_, err := s.ch.SendRequest(\"signal\", false, Marshal(&msg))\n\treturn err\n}\n\n// RFC 4254 Section 6.5.\ntype execMsg struct {\n\tCommand string\n}\n\n// Start runs cmd on the remote host. Typically, the remote\n// server passes cmd to the shell for interpretation.\n// A Session only accepts one call to Run, Start or Shell.\nfunc (s *Session) Start(cmd string) error {\n\tif s.started {\n\t\treturn errors.New(\"ssh: session already started\")\n\t}\n\treq := execMsg{\n\t\tCommand: cmd,\n\t}\n\n\tok, err := s.ch.SendRequest(\"exec\", true, Marshal(&req))\n\tif err == nil && !ok {\n\t\terr = fmt.Errorf(\"ssh: command %v failed\", cmd)\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn s.start()\n}\n\n// Run runs cmd on the remote host. Typically, the remote\n// server passes cmd to the shell for interpretation.\n// A Session only accepts one call to Run, Start, Shell, Output,\n// or CombinedOutput.\n//\n// The returned error is nil if the command runs, has no problems\n// copying stdin, stdout, and stderr, and exits with a zero exit\n// status.\n//\n// If the remote server does not send an exit status, an error of type\n// *ExitMissingError is returned. If the command completes\n// unsuccessfully or is interrupted by a signal, the error is of type\n// *ExitError. Other error types may be returned for I/O problems.\nfunc (s *Session) Run(cmd string) error {\n\terr := s.Start(cmd)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn s.Wait()\n}\n\n// Output runs cmd on the remote host and returns its standard output.\nfunc (s *Session) Output(cmd string) ([]byte, error) {\n\tif s.Stdout != nil {\n\t\treturn nil, errors.New(\"ssh: Stdout already set\")\n\t}\n\tvar b bytes.Buffer\n\ts.Stdout = &b\n\terr := s.Run(cmd)\n\treturn b.Bytes(), err\n}\n\ntype singleWriter struct {\n\tb  bytes.Buffer\n\tmu sync.Mutex\n}\n\nfunc (w *singleWriter) Write(p []byte) (int, error) {\n\tw.mu.Lock()\n\tdefer w.mu.Unlock()\n\treturn w.b.Write(p)\n}\n\n// CombinedOutput runs cmd on the remote host and returns its combined\n// standard output and standard error.\nfunc (s *Session) CombinedOutput(cmd string) ([]byte, error) {\n\tif s.Stdout != nil {\n\t\treturn nil, errors.New(\"ssh: Stdout already set\")\n\t}\n\tif s.Stderr != nil {\n\t\treturn nil, errors.New(\"ssh: Stderr already set\")\n\t}\n\tvar b singleWriter\n\ts.Stdout = &b\n\ts.Stderr = &b\n\terr := s.Run(cmd)\n\treturn b.b.Bytes(), err\n}\n\n// Shell starts a login shell on the remote host. A Session only\n// accepts one call to Run, Start, Shell, Output, or CombinedOutput.\nfunc (s *Session) Shell() error {\n\tif s.started {\n\t\treturn errors.New(\"ssh: session already started\")\n\t}\n\n\tok, err := s.ch.SendRequest(\"shell\", true, nil)\n\tif err == nil && !ok {\n\t\treturn errors.New(\"ssh: could not start shell\")\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn s.start()\n}\n\nfunc (s *Session) start() error {\n\ts.started = true\n\n\ttype F func(*Session)\n\tfor _, setupFd := range []F{(*Session).stdin, (*Session).stdout, (*Session).stderr} {\n\t\tsetupFd(s)\n\t}\n\n\ts.errors = make(chan error, len(s.copyFuncs))\n\tfor _, fn := range s.copyFuncs {\n\t\tgo func(fn func() error) {\n\t\t\ts.errors <- fn()\n\t\t}(fn)\n\t}\n\treturn nil\n}\n\n// Wait waits for the remote command to exit.\n//\n// The returned error is nil if the command runs, has no problems\n// copying stdin, stdout, and stderr, and exits with a zero exit\n// status.\n//\n// If the remote server does not send an exit status, an error of type\n// *ExitMissingError is returned. If the command completes\n// unsuccessfully or is interrupted by a signal, the error is of type\n// *ExitError. Other error types may be returned for I/O problems.\nfunc (s *Session) Wait() error {\n\tif !s.started {\n\t\treturn errors.New(\"ssh: session not started\")\n\t}\n\twaitErr := <-s.exitStatus\n\n\tif s.stdinPipeWriter != nil {\n\t\ts.stdinPipeWriter.Close()\n\t}\n\tvar copyError error\n\tfor range s.copyFuncs {\n\t\tif err := <-s.errors; err != nil && copyError == nil {\n\t\t\tcopyError = err\n\t\t}\n\t}\n\tif waitErr != nil {\n\t\treturn waitErr\n\t}\n\treturn copyError\n}\n\nfunc (s *Session) wait(reqs <-chan *Request) error {\n\twm := Waitmsg{status: -1}\n\t// Wait for msg channel to be closed before returning.\n\tfor msg := range reqs {\n\t\tswitch msg.Type {\n\t\tcase \"exit-status\":\n\t\t\twm.status = int(binary.BigEndian.Uint32(msg.Payload))\n\t\tcase \"exit-signal\":\n\t\t\tvar sigval struct {\n\t\t\t\tSignal     string\n\t\t\t\tCoreDumped bool\n\t\t\t\tError      string\n\t\t\t\tLang       string\n\t\t\t}\n\t\t\tif err := Unmarshal(msg.Payload, &sigval); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// Must sanitize strings?\n\t\t\twm.signal = sigval.Signal\n\t\t\twm.msg = sigval.Error\n\t\t\twm.lang = sigval.Lang\n\t\tdefault:\n\t\t\t// This handles keepalives and matches\n\t\t\t// OpenSSH's behaviour.\n\t\t\tif msg.WantReply {\n\t\t\t\tmsg.Reply(false, nil)\n\t\t\t}\n\t\t}\n\t}\n\tif wm.status == 0 {\n\t\treturn nil\n\t}\n\tif wm.status == -1 {\n\t\t// exit-status was never sent from server\n\t\tif wm.signal == \"\" {\n\t\t\t// signal was not sent either.  RFC 4254\n\t\t\t// section 6.10 recommends against this\n\t\t\t// behavior, but it is allowed, so we let\n\t\t\t// clients handle it.\n\t\t\treturn &ExitMissingError{}\n\t\t}\n\t\twm.status = 128\n\t\tif _, ok := signals[Signal(wm.signal)]; ok {\n\t\t\twm.status += signals[Signal(wm.signal)]\n\t\t}\n\t}\n\n\treturn &ExitError{wm}\n}\n\n// ExitMissingError is returned if a session is torn down cleanly, but\n// the server sends no confirmation of the exit status.\ntype ExitMissingError struct{}\n\nfunc (e *ExitMissingError) Error() string {\n\treturn \"wait: remote command exited without exit status or exit signal\"\n}\n\nfunc (s *Session) stdin() {\n\tif s.stdinpipe {\n\t\treturn\n\t}\n\tvar stdin io.Reader\n\tif s.Stdin == nil {\n\t\tstdin = new(bytes.Buffer)\n\t} else {\n\t\tr, w := io.Pipe()\n\t\tgo func() {\n\t\t\t_, err := io.Copy(w, s.Stdin)\n\t\t\tw.CloseWithError(err)\n\t\t}()\n\t\tstdin, s.stdinPipeWriter = r, w\n\t}\n\ts.copyFuncs = append(s.copyFuncs, func() error {\n\t\t_, err := io.Copy(s.ch, stdin)\n\t\tif err1 := s.ch.CloseWrite(); err == nil && err1 != io.EOF {\n\t\t\terr = err1\n\t\t}\n\t\treturn err\n\t})\n}\n\nfunc (s *Session) stdout() {\n\tif s.stdoutpipe {\n\t\treturn\n\t}\n\tif s.Stdout == nil {\n\t\ts.Stdout = io.Discard\n\t}\n\ts.copyFuncs = append(s.copyFuncs, func() error {\n\t\t_, err := io.Copy(s.Stdout, s.ch)\n\t\treturn err\n\t})\n}\n\nfunc (s *Session) stderr() {\n\tif s.stderrpipe {\n\t\treturn\n\t}\n\tif s.Stderr == nil {\n\t\ts.Stderr = io.Discard\n\t}\n\ts.copyFuncs = append(s.copyFuncs, func() error {\n\t\t_, err := io.Copy(s.Stderr, s.ch.Stderr())\n\t\treturn err\n\t})\n}\n\n// sessionStdin reroutes Close to CloseWrite.\ntype sessionStdin struct {\n\tio.Writer\n\tch Channel\n}\n\nfunc (s *sessionStdin) Close() error {\n\treturn s.ch.CloseWrite()\n}\n\n// StdinPipe returns a pipe that will be connected to the\n// remote command's standard input when the command starts.\nfunc (s *Session) StdinPipe() (io.WriteCloser, error) {\n\tif s.Stdin != nil {\n\t\treturn nil, errors.New(\"ssh: Stdin already set\")\n\t}\n\tif s.started {\n\t\treturn nil, errors.New(\"ssh: StdinPipe after process started\")\n\t}\n\ts.stdinpipe = true\n\treturn &sessionStdin{s.ch, s.ch}, nil\n}\n\n// StdoutPipe returns a pipe that will be connected to the\n// remote command's standard output when the command starts.\n// There is a fixed amount of buffering that is shared between\n// stdout and stderr streams. If the StdoutPipe reader is\n// not serviced fast enough it may eventually cause the\n// remote command to block.\nfunc (s *Session) StdoutPipe() (io.Reader, error) {\n\tif s.Stdout != nil {\n\t\treturn nil, errors.New(\"ssh: Stdout already set\")\n\t}\n\tif s.started {\n\t\treturn nil, errors.New(\"ssh: StdoutPipe after process started\")\n\t}\n\ts.stdoutpipe = true\n\treturn s.ch, nil\n}\n\n// StderrPipe returns a pipe that will be connected to the\n// remote command's standard error when the command starts.\n// There is a fixed amount of buffering that is shared between\n// stdout and stderr streams. If the StderrPipe reader is\n// not serviced fast enough it may eventually cause the\n// remote command to block.\nfunc (s *Session) StderrPipe() (io.Reader, error) {\n\tif s.Stderr != nil {\n\t\treturn nil, errors.New(\"ssh: Stderr already set\")\n\t}\n\tif s.started {\n\t\treturn nil, errors.New(\"ssh: StderrPipe after process started\")\n\t}\n\ts.stderrpipe = true\n\treturn s.ch.Stderr(), nil\n}\n\n// newSession returns a new interactive session on the remote host.\nfunc newSession(ch Channel, reqs <-chan *Request) (*Session, error) {\n\ts := &Session{\n\t\tch: ch,\n\t}\n\ts.exitStatus = make(chan error, 1)\n\tgo func() {\n\t\ts.exitStatus <- s.wait(reqs)\n\t}()\n\n\treturn s, nil\n}\n\n// An ExitError reports unsuccessful completion of a remote command.\ntype ExitError struct {\n\tWaitmsg\n}\n\nfunc (e *ExitError) Error() string {\n\treturn e.Waitmsg.String()\n}\n\n// Waitmsg stores the information about an exited remote command\n// as reported by Wait.\ntype Waitmsg struct {\n\tstatus int\n\tsignal string\n\tmsg    string\n\tlang   string\n}\n\n// ExitStatus returns the exit status of the remote command.\nfunc (w Waitmsg) ExitStatus() int {\n\treturn w.status\n}\n\n// Signal returns the exit signal of the remote command if\n// it was terminated violently.\nfunc (w Waitmsg) Signal() string {\n\treturn w.signal\n}\n\n// Msg returns the exit message given by the remote command\nfunc (w Waitmsg) Msg() string {\n\treturn w.msg\n}\n\n// Lang returns the language tag. See RFC 3066\nfunc (w Waitmsg) Lang() string {\n\treturn w.lang\n}\n\nfunc (w Waitmsg) String() string {\n\tstr := fmt.Sprintf(\"Process exited with status %v\", w.status)\n\tif w.signal != \"\" {\n\t\tstr += fmt.Sprintf(\" from signal %v\", w.signal)\n\t}\n\tif w.msg != \"\" {\n\t\tstr += fmt.Sprintf(\". Reason was: %v\", w.msg)\n\t}\n\treturn str\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/ssh_gss.go",
    "content": "// Copyright 2011 The Go 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 ssh\n\nimport (\n\t\"encoding/asn1\"\n\t\"errors\"\n)\n\nvar krb5OID []byte\n\nfunc init() {\n\tkrb5OID, _ = asn1.Marshal(krb5Mesh)\n}\n\n// GSSAPIClient provides the API to plug-in GSSAPI authentication for client logins.\ntype GSSAPIClient interface {\n\t// InitSecContext initiates the establishment of a security context for GSS-API between the\n\t// ssh client and ssh server. Initially the token parameter should be specified as nil.\n\t// The routine may return a outputToken which should be transferred to\n\t// the ssh server, where the ssh server will present it to\n\t// AcceptSecContext. If no token need be sent, InitSecContext will indicate this by setting\n\t// needContinue to false. To complete the context\n\t// establishment, one or more reply tokens may be required from the ssh\n\t// server;if so, InitSecContext will return a needContinue which is true.\n\t// In this case, InitSecContext should be called again when the\n\t// reply token is received from the ssh server, passing the reply\n\t// token to InitSecContext via the token parameters.\n\t// See RFC 2743 section 2.2.1 and RFC 4462 section 3.4.\n\tInitSecContext(target string, token []byte, isGSSDelegCreds bool) (outputToken []byte, needContinue bool, err error)\n\t// GetMIC generates a cryptographic MIC for the SSH2 message, and places\n\t// the MIC in a token for transfer to the ssh server.\n\t// The contents of the MIC field are obtained by calling GSS_GetMIC()\n\t// over the following, using the GSS-API context that was just\n\t// established:\n\t//  string    session identifier\n\t//  byte      SSH_MSG_USERAUTH_REQUEST\n\t//  string    user name\n\t//  string    service\n\t//  string    \"gssapi-with-mic\"\n\t// See RFC 2743 section 2.3.1 and RFC 4462 3.5.\n\tGetMIC(micFiled []byte) ([]byte, error)\n\t// Whenever possible, it should be possible for\n\t// DeleteSecContext() calls to be successfully processed even\n\t// if other calls cannot succeed, thereby enabling context-related\n\t// resources to be released.\n\t// In addition to deleting established security contexts,\n\t// gss_delete_sec_context must also be able to delete \"half-built\"\n\t// security contexts resulting from an incomplete sequence of\n\t// InitSecContext()/AcceptSecContext() calls.\n\t// See RFC 2743 section 2.2.3.\n\tDeleteSecContext() error\n}\n\n// GSSAPIServer provides the API to plug in GSSAPI authentication for server logins.\ntype GSSAPIServer interface {\n\t// AcceptSecContext allows a remotely initiated security context between the application\n\t// and a remote peer to be established by the ssh client. The routine may return a\n\t// outputToken which should be transferred to the ssh client,\n\t// where the ssh client will present it to InitSecContext.\n\t// If no token need be sent, AcceptSecContext will indicate this\n\t// by setting the needContinue to false. To\n\t// complete the context establishment, one or more reply tokens may be\n\t// required from the ssh client. if so, AcceptSecContext\n\t// will return a needContinue which is true, in which case it\n\t// should be called again when the reply token is received from the ssh\n\t// client, passing the token to AcceptSecContext via the\n\t// token parameters.\n\t// The srcName return value is the authenticated username.\n\t// See RFC 2743 section 2.2.2 and RFC 4462 section 3.4.\n\tAcceptSecContext(token []byte) (outputToken []byte, srcName string, needContinue bool, err error)\n\t// VerifyMIC verifies that a cryptographic MIC, contained in the token parameter,\n\t// fits the supplied message is received from the ssh client.\n\t// See RFC 2743 section 2.3.2.\n\tVerifyMIC(micField []byte, micToken []byte) error\n\t// Whenever possible, it should be possible for\n\t// DeleteSecContext() calls to be successfully processed even\n\t// if other calls cannot succeed, thereby enabling context-related\n\t// resources to be released.\n\t// In addition to deleting established security contexts,\n\t// gss_delete_sec_context must also be able to delete \"half-built\"\n\t// security contexts resulting from an incomplete sequence of\n\t// InitSecContext()/AcceptSecContext() calls.\n\t// See RFC 2743 section 2.2.3.\n\tDeleteSecContext() error\n}\n\nvar (\n\t// OpenSSH supports Kerberos V5 mechanism only for GSS-API authentication,\n\t// so we also support the krb5 mechanism only.\n\t// See RFC 1964 section 1.\n\tkrb5Mesh = asn1.ObjectIdentifier{1, 2, 840, 113554, 1, 2, 2}\n)\n\n// The GSS-API authentication method is initiated when the client sends an SSH_MSG_USERAUTH_REQUEST\n// See RFC 4462 section 3.2.\ntype userAuthRequestGSSAPI struct {\n\tN    uint32\n\tOIDS []asn1.ObjectIdentifier\n}\n\nfunc parseGSSAPIPayload(payload []byte) (*userAuthRequestGSSAPI, error) {\n\tn, rest, ok := parseUint32(payload)\n\tif !ok {\n\t\treturn nil, errors.New(\"parse uint32 failed\")\n\t}\n\ts := &userAuthRequestGSSAPI{\n\t\tN:    n,\n\t\tOIDS: make([]asn1.ObjectIdentifier, n),\n\t}\n\tfor i := 0; i < int(n); i++ {\n\t\tvar (\n\t\t\tdesiredMech []byte\n\t\t\terr         error\n\t\t)\n\t\tdesiredMech, rest, ok = parseString(rest)\n\t\tif !ok {\n\t\t\treturn nil, errors.New(\"parse string failed\")\n\t\t}\n\t\tif rest, err = asn1.Unmarshal(desiredMech, &s.OIDS[i]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t}\n\treturn s, nil\n}\n\n// See RFC 4462 section 3.6.\nfunc buildMIC(sessionID string, username string, service string, authMethod string) []byte {\n\tout := make([]byte, 0, 0)\n\tout = appendString(out, sessionID)\n\tout = append(out, msgUserAuthRequest)\n\tout = appendString(out, username)\n\tout = appendString(out, service)\n\tout = appendString(out, authMethod)\n\treturn out\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/streamlocal.go",
    "content": "package ssh\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n)\n\n// streamLocalChannelOpenDirectMsg is a struct used for SSH_MSG_CHANNEL_OPEN message\n// with \"direct-streamlocal@openssh.com\" string.\n//\n// See openssh-portable/PROTOCOL, section 2.4. connection: Unix domain socket forwarding\n// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL#L235\ntype streamLocalChannelOpenDirectMsg struct {\n\tsocketPath string\n\treserved0  string\n\treserved1  uint32\n}\n\n// forwardedStreamLocalPayload is a struct used for SSH_MSG_CHANNEL_OPEN message\n// with \"forwarded-streamlocal@openssh.com\" string.\ntype forwardedStreamLocalPayload struct {\n\tSocketPath string\n\tReserved0  string\n}\n\n// streamLocalChannelForwardMsg is a struct used for SSH2_MSG_GLOBAL_REQUEST message\n// with \"streamlocal-forward@openssh.com\"/\"cancel-streamlocal-forward@openssh.com\" string.\ntype streamLocalChannelForwardMsg struct {\n\tsocketPath string\n}\n\n// ListenUnix is similar to ListenTCP but uses a Unix domain socket.\nfunc (c *Client) ListenUnix(socketPath string) (net.Listener, error) {\n\tc.handleForwardsOnce.Do(c.handleForwards)\n\tm := streamLocalChannelForwardMsg{\n\t\tsocketPath,\n\t}\n\t// send message\n\tok, _, err := c.SendRequest(\"streamlocal-forward@openssh.com\", true, Marshal(&m))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif !ok {\n\t\treturn nil, errors.New(\"ssh: streamlocal-forward@openssh.com request denied by peer\")\n\t}\n\tch := c.forwards.add(&net.UnixAddr{Name: socketPath, Net: \"unix\"})\n\n\treturn &unixListener{socketPath, c, ch}, nil\n}\n\nfunc (c *Client) dialStreamLocal(socketPath string) (Channel, error) {\n\tmsg := streamLocalChannelOpenDirectMsg{\n\t\tsocketPath: socketPath,\n\t}\n\tch, in, err := c.OpenChannel(\"direct-streamlocal@openssh.com\", Marshal(&msg))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tgo DiscardRequests(in)\n\treturn ch, err\n}\n\ntype unixListener struct {\n\tsocketPath string\n\n\tconn *Client\n\tin   <-chan forward\n}\n\n// Accept waits for and returns the next connection to the listener.\nfunc (l *unixListener) Accept() (net.Conn, error) {\n\ts, ok := <-l.in\n\tif !ok {\n\t\treturn nil, io.EOF\n\t}\n\tch, incoming, err := s.newCh.Accept()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tgo DiscardRequests(incoming)\n\n\treturn &chanConn{\n\t\tChannel: ch,\n\t\tladdr: &net.UnixAddr{\n\t\t\tName: l.socketPath,\n\t\t\tNet:  \"unix\",\n\t\t},\n\t\traddr: &net.UnixAddr{\n\t\t\tName: \"@\",\n\t\t\tNet:  \"unix\",\n\t\t},\n\t}, nil\n}\n\n// Close closes the listener.\nfunc (l *unixListener) Close() error {\n\t// this also closes the listener.\n\tl.conn.forwards.remove(&net.UnixAddr{Name: l.socketPath, Net: \"unix\"})\n\tm := streamLocalChannelForwardMsg{\n\t\tl.socketPath,\n\t}\n\tok, _, err := l.conn.SendRequest(\"cancel-streamlocal-forward@openssh.com\", true, Marshal(&m))\n\tif err == nil && !ok {\n\t\terr = errors.New(\"ssh: cancel-streamlocal-forward@openssh.com failed\")\n\t}\n\treturn err\n}\n\n// Addr returns the listener's network address.\nfunc (l *unixListener) Addr() net.Addr {\n\treturn &net.UnixAddr{\n\t\tName: l.socketPath,\n\t\tNet:  \"unix\",\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/tcpip.go",
    "content": "// Copyright 2011 The Go 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 ssh\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/rand\"\n\t\"net\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\n// Listen requests the remote peer open a listening socket on\n// addr. Incoming connections will be available by calling Accept on\n// the returned net.Listener. The listener must be serviced, or the\n// SSH connection may hang.\n// N must be \"tcp\", \"tcp4\", \"tcp6\", or \"unix\".\nfunc (c *Client) Listen(n, addr string) (net.Listener, error) {\n\tswitch n {\n\tcase \"tcp\", \"tcp4\", \"tcp6\":\n\t\tladdr, err := net.ResolveTCPAddr(n, addr)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn c.ListenTCP(laddr)\n\tcase \"unix\":\n\t\treturn c.ListenUnix(addr)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"ssh: unsupported protocol: %s\", n)\n\t}\n}\n\n// Automatic port allocation is broken with OpenSSH before 6.0. See\n// also https://bugzilla.mindrot.org/show_bug.cgi?id=2017.  In\n// particular, OpenSSH 5.9 sends a channelOpenMsg with port number 0,\n// rather than the actual port number. This means you can never open\n// two different listeners with auto allocated ports. We work around\n// this by trying explicit ports until we succeed.\n\nconst openSSHPrefix = \"OpenSSH_\"\n\nvar portRandomizer = rand.New(rand.NewSource(time.Now().UnixNano()))\n\n// isBrokenOpenSSHVersion returns true if the given version string\n// specifies a version of OpenSSH that is known to have a bug in port\n// forwarding.\nfunc isBrokenOpenSSHVersion(versionStr string) bool {\n\ti := strings.Index(versionStr, openSSHPrefix)\n\tif i < 0 {\n\t\treturn false\n\t}\n\ti += len(openSSHPrefix)\n\tj := i\n\tfor ; j < len(versionStr); j++ {\n\t\tif versionStr[j] < '0' || versionStr[j] > '9' {\n\t\t\tbreak\n\t\t}\n\t}\n\tversion, _ := strconv.Atoi(versionStr[i:j])\n\treturn version < 6\n}\n\n// autoPortListenWorkaround simulates automatic port allocation by\n// trying random ports repeatedly.\nfunc (c *Client) autoPortListenWorkaround(laddr *net.TCPAddr) (net.Listener, error) {\n\tvar sshListener net.Listener\n\tvar err error\n\tconst tries = 10\n\tfor i := 0; i < tries; i++ {\n\t\taddr := *laddr\n\t\taddr.Port = 1024 + portRandomizer.Intn(60000)\n\t\tsshListener, err = c.ListenTCP(&addr)\n\t\tif err == nil {\n\t\t\tladdr.Port = addr.Port\n\t\t\treturn sshListener, err\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"ssh: listen on random port failed after %d tries: %v\", tries, err)\n}\n\n// RFC 4254 7.1\ntype channelForwardMsg struct {\n\taddr  string\n\trport uint32\n}\n\n// handleForwards starts goroutines handling forwarded connections.\n// It's called on first use by (*Client).ListenTCP to not launch\n// goroutines until needed.\nfunc (c *Client) handleForwards() {\n\tgo c.forwards.handleChannels(c.HandleChannelOpen(\"forwarded-tcpip\"))\n\tgo c.forwards.handleChannels(c.HandleChannelOpen(\"forwarded-streamlocal@openssh.com\"))\n}\n\n// ListenTCP requests the remote peer open a listening socket\n// on laddr. Incoming connections will be available by calling\n// Accept on the returned net.Listener.\nfunc (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) {\n\tc.handleForwardsOnce.Do(c.handleForwards)\n\tif laddr.Port == 0 && isBrokenOpenSSHVersion(string(c.ServerVersion())) {\n\t\treturn c.autoPortListenWorkaround(laddr)\n\t}\n\n\tm := channelForwardMsg{\n\t\tladdr.IP.String(),\n\t\tuint32(laddr.Port),\n\t}\n\t// send message\n\tok, resp, err := c.SendRequest(\"tcpip-forward\", true, Marshal(&m))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif !ok {\n\t\treturn nil, errors.New(\"ssh: tcpip-forward request denied by peer\")\n\t}\n\n\t// If the original port was 0, then the remote side will\n\t// supply a real port number in the response.\n\tif laddr.Port == 0 {\n\t\tvar p struct {\n\t\t\tPort uint32\n\t\t}\n\t\tif err := Unmarshal(resp, &p); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tladdr.Port = int(p.Port)\n\t}\n\n\t// Register this forward, using the port number we obtained.\n\tch := c.forwards.add(laddr)\n\n\treturn &tcpListener{laddr, c, ch}, nil\n}\n\n// forwardList stores a mapping between remote\n// forward requests and the tcpListeners.\ntype forwardList struct {\n\tsync.Mutex\n\tentries []forwardEntry\n}\n\n// forwardEntry represents an established mapping of a laddr on a\n// remote ssh server to a channel connected to a tcpListener.\ntype forwardEntry struct {\n\tladdr net.Addr\n\tc     chan forward\n}\n\n// forward represents an incoming forwarded tcpip connection. The\n// arguments to add/remove/lookup should be address as specified in\n// the original forward-request.\ntype forward struct {\n\tnewCh NewChannel // the ssh client channel underlying this forward\n\traddr net.Addr   // the raddr of the incoming connection\n}\n\nfunc (l *forwardList) add(addr net.Addr) chan forward {\n\tl.Lock()\n\tdefer l.Unlock()\n\tf := forwardEntry{\n\t\tladdr: addr,\n\t\tc:     make(chan forward, 1),\n\t}\n\tl.entries = append(l.entries, f)\n\treturn f.c\n}\n\n// See RFC 4254, section 7.2\ntype forwardedTCPPayload struct {\n\tAddr       string\n\tPort       uint32\n\tOriginAddr string\n\tOriginPort uint32\n}\n\n// parseTCPAddr parses the originating address from the remote into a *net.TCPAddr.\nfunc parseTCPAddr(addr string, port uint32) (*net.TCPAddr, error) {\n\tif port == 0 || port > 65535 {\n\t\treturn nil, fmt.Errorf(\"ssh: port number out of range: %d\", port)\n\t}\n\tip := net.ParseIP(string(addr))\n\tif ip == nil {\n\t\treturn nil, fmt.Errorf(\"ssh: cannot parse IP address %q\", addr)\n\t}\n\treturn &net.TCPAddr{IP: ip, Port: int(port)}, nil\n}\n\nfunc (l *forwardList) handleChannels(in <-chan NewChannel) {\n\tfor ch := range in {\n\t\tvar (\n\t\t\tladdr net.Addr\n\t\t\traddr net.Addr\n\t\t\terr   error\n\t\t)\n\t\tswitch channelType := ch.ChannelType(); channelType {\n\t\tcase \"forwarded-tcpip\":\n\t\t\tvar payload forwardedTCPPayload\n\t\t\tif err = Unmarshal(ch.ExtraData(), &payload); err != nil {\n\t\t\t\tch.Reject(ConnectionFailed, \"could not parse forwarded-tcpip payload: \"+err.Error())\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// RFC 4254 section 7.2 specifies that incoming\n\t\t\t// addresses should list the address, in string\n\t\t\t// format. It is implied that this should be an IP\n\t\t\t// address, as it would be impossible to connect to it\n\t\t\t// otherwise.\n\t\t\tladdr, err = parseTCPAddr(payload.Addr, payload.Port)\n\t\t\tif err != nil {\n\t\t\t\tch.Reject(ConnectionFailed, err.Error())\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\traddr, err = parseTCPAddr(payload.OriginAddr, payload.OriginPort)\n\t\t\tif err != nil {\n\t\t\t\tch.Reject(ConnectionFailed, err.Error())\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\tcase \"forwarded-streamlocal@openssh.com\":\n\t\t\tvar payload forwardedStreamLocalPayload\n\t\t\tif err = Unmarshal(ch.ExtraData(), &payload); err != nil {\n\t\t\t\tch.Reject(ConnectionFailed, \"could not parse forwarded-streamlocal@openssh.com payload: \"+err.Error())\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tladdr = &net.UnixAddr{\n\t\t\t\tName: payload.SocketPath,\n\t\t\t\tNet:  \"unix\",\n\t\t\t}\n\t\t\traddr = &net.UnixAddr{\n\t\t\t\tName: \"@\",\n\t\t\t\tNet:  \"unix\",\n\t\t\t}\n\t\tdefault:\n\t\t\tpanic(fmt.Errorf(\"ssh: unknown channel type %s\", channelType))\n\t\t}\n\t\tif ok := l.forward(laddr, raddr, ch); !ok {\n\t\t\t// Section 7.2, implementations MUST reject spurious incoming\n\t\t\t// connections.\n\t\t\tch.Reject(Prohibited, \"no forward for address\")\n\t\t\tcontinue\n\t\t}\n\n\t}\n}\n\n// remove removes the forward entry, and the channel feeding its\n// listener.\nfunc (l *forwardList) remove(addr net.Addr) {\n\tl.Lock()\n\tdefer l.Unlock()\n\tfor i, f := range l.entries {\n\t\tif addr.Network() == f.laddr.Network() && addr.String() == f.laddr.String() {\n\t\t\tl.entries = append(l.entries[:i], l.entries[i+1:]...)\n\t\t\tclose(f.c)\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// closeAll closes and clears all forwards.\nfunc (l *forwardList) closeAll() {\n\tl.Lock()\n\tdefer l.Unlock()\n\tfor _, f := range l.entries {\n\t\tclose(f.c)\n\t}\n\tl.entries = nil\n}\n\nfunc (l *forwardList) forward(laddr, raddr net.Addr, ch NewChannel) bool {\n\tl.Lock()\n\tdefer l.Unlock()\n\tfor _, f := range l.entries {\n\t\tif laddr.Network() == f.laddr.Network() && laddr.String() == f.laddr.String() {\n\t\t\tf.c <- forward{newCh: ch, raddr: raddr}\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\ntype tcpListener struct {\n\tladdr *net.TCPAddr\n\n\tconn *Client\n\tin   <-chan forward\n}\n\n// Accept waits for and returns the next connection to the listener.\nfunc (l *tcpListener) Accept() (net.Conn, error) {\n\ts, ok := <-l.in\n\tif !ok {\n\t\treturn nil, io.EOF\n\t}\n\tch, incoming, err := s.newCh.Accept()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tgo DiscardRequests(incoming)\n\n\treturn &chanConn{\n\t\tChannel: ch,\n\t\tladdr:   l.laddr,\n\t\traddr:   s.raddr,\n\t}, nil\n}\n\n// Close closes the listener.\nfunc (l *tcpListener) Close() error {\n\tm := channelForwardMsg{\n\t\tl.laddr.IP.String(),\n\t\tuint32(l.laddr.Port),\n\t}\n\n\t// this also closes the listener.\n\tl.conn.forwards.remove(l.laddr)\n\tok, _, err := l.conn.SendRequest(\"cancel-tcpip-forward\", true, Marshal(&m))\n\tif err == nil && !ok {\n\t\terr = errors.New(\"ssh: cancel-tcpip-forward failed\")\n\t}\n\treturn err\n}\n\n// Addr returns the listener's network address.\nfunc (l *tcpListener) Addr() net.Addr {\n\treturn l.laddr\n}\n\n// DialContext initiates a connection to the addr from the remote host.\n//\n// The provided Context must be non-nil. If the context expires before the\n// connection is complete, an error is returned. Once successfully connected,\n// any expiration of the context will not affect the connection.\n//\n// See func Dial for additional information.\nfunc (c *Client) DialContext(ctx context.Context, n, addr string) (net.Conn, error) {\n\tif err := ctx.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\ttype connErr struct {\n\t\tconn net.Conn\n\t\terr  error\n\t}\n\tch := make(chan connErr)\n\tgo func() {\n\t\tconn, err := c.Dial(n, addr)\n\t\tselect {\n\t\tcase ch <- connErr{conn, err}:\n\t\tcase <-ctx.Done():\n\t\t\tif conn != nil {\n\t\t\t\tconn.Close()\n\t\t\t}\n\t\t}\n\t}()\n\tselect {\n\tcase res := <-ch:\n\t\treturn res.conn, res.err\n\tcase <-ctx.Done():\n\t\treturn nil, ctx.Err()\n\t}\n}\n\n// Dial initiates a connection to the addr from the remote host.\n// The resulting connection has a zero LocalAddr() and RemoteAddr().\nfunc (c *Client) Dial(n, addr string) (net.Conn, error) {\n\tvar ch Channel\n\tswitch n {\n\tcase \"tcp\", \"tcp4\", \"tcp6\":\n\t\t// Parse the address into host and numeric port.\n\t\thost, portString, err := net.SplitHostPort(addr)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tport, err := strconv.ParseUint(portString, 10, 16)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tch, err = c.dial(net.IPv4zero.String(), 0, host, int(port))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// Use a zero address for local and remote address.\n\t\tzeroAddr := &net.TCPAddr{\n\t\t\tIP:   net.IPv4zero,\n\t\t\tPort: 0,\n\t\t}\n\t\treturn &chanConn{\n\t\t\tChannel: ch,\n\t\t\tladdr:   zeroAddr,\n\t\t\traddr:   zeroAddr,\n\t\t}, nil\n\tcase \"unix\":\n\t\tvar err error\n\t\tch, err = c.dialStreamLocal(addr)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn &chanConn{\n\t\t\tChannel: ch,\n\t\t\tladdr: &net.UnixAddr{\n\t\t\t\tName: \"@\",\n\t\t\t\tNet:  \"unix\",\n\t\t\t},\n\t\t\traddr: &net.UnixAddr{\n\t\t\t\tName: addr,\n\t\t\t\tNet:  \"unix\",\n\t\t\t},\n\t\t}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"ssh: unsupported protocol: %s\", n)\n\t}\n}\n\n// DialTCP connects to the remote address raddr on the network net,\n// which must be \"tcp\", \"tcp4\", or \"tcp6\".  If laddr is not nil, it is used\n// as the local address for the connection.\nfunc (c *Client) DialTCP(n string, laddr, raddr *net.TCPAddr) (net.Conn, error) {\n\tif laddr == nil {\n\t\tladdr = &net.TCPAddr{\n\t\t\tIP:   net.IPv4zero,\n\t\t\tPort: 0,\n\t\t}\n\t}\n\tch, err := c.dial(laddr.IP.String(), laddr.Port, raddr.IP.String(), raddr.Port)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &chanConn{\n\t\tChannel: ch,\n\t\tladdr:   laddr,\n\t\traddr:   raddr,\n\t}, nil\n}\n\n// RFC 4254 7.2\ntype channelOpenDirectMsg struct {\n\traddr string\n\trport uint32\n\tladdr string\n\tlport uint32\n}\n\nfunc (c *Client) dial(laddr string, lport int, raddr string, rport int) (Channel, error) {\n\tmsg := channelOpenDirectMsg{\n\t\traddr: raddr,\n\t\trport: uint32(rport),\n\t\tladdr: laddr,\n\t\tlport: uint32(lport),\n\t}\n\tch, in, err := c.OpenChannel(\"direct-tcpip\", Marshal(&msg))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tgo DiscardRequests(in)\n\treturn ch, nil\n}\n\ntype tcpChan struct {\n\tChannel // the backing channel\n}\n\n// chanConn fulfills the net.Conn interface without\n// the tcpChan having to hold laddr or raddr directly.\ntype chanConn struct {\n\tChannel\n\tladdr, raddr net.Addr\n}\n\n// LocalAddr returns the local network address.\nfunc (t *chanConn) LocalAddr() net.Addr {\n\treturn t.laddr\n}\n\n// RemoteAddr returns the remote network address.\nfunc (t *chanConn) RemoteAddr() net.Addr {\n\treturn t.raddr\n}\n\n// SetDeadline sets the read and write deadlines associated\n// with the connection.\nfunc (t *chanConn) SetDeadline(deadline time.Time) error {\n\tif err := t.SetReadDeadline(deadline); err != nil {\n\t\treturn err\n\t}\n\treturn t.SetWriteDeadline(deadline)\n}\n\n// SetReadDeadline sets the read deadline.\n// A zero value for t means Read will not time out.\n// After the deadline, the error from Read will implement net.Error\n// with Timeout() == true.\nfunc (t *chanConn) SetReadDeadline(deadline time.Time) error {\n\t// for compatibility with previous version,\n\t// the error message contains \"tcpChan\"\n\treturn errors.New(\"ssh: tcpChan: deadline not supported\")\n}\n\n// SetWriteDeadline exists to satisfy the net.Conn interface\n// but is not implemented by this type.  It always returns an error.\nfunc (t *chanConn) SetWriteDeadline(deadline time.Time) error {\n\treturn errors.New(\"ssh: tcpChan: deadline not supported\")\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/ssh/transport.go",
    "content": "// Copyright 2011 The Go 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 ssh\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"errors\"\n\t\"io\"\n\t\"log\"\n)\n\n// debugTransport if set, will print packet types as they go over the\n// wire. No message decoding is done, to minimize the impact on timing.\nconst debugTransport = false\n\nconst (\n\tgcm128CipherID = \"aes128-gcm@openssh.com\"\n\tgcm256CipherID = \"aes256-gcm@openssh.com\"\n\taes128cbcID    = \"aes128-cbc\"\n\ttripledescbcID = \"3des-cbc\"\n)\n\n// packetConn represents a transport that implements packet based\n// operations.\ntype packetConn interface {\n\t// Encrypt and send a packet of data to the remote peer.\n\twritePacket(packet []byte) error\n\n\t// Read a packet from the connection. The read is blocking,\n\t// i.e. if error is nil, then the returned byte slice is\n\t// always non-empty.\n\treadPacket() ([]byte, error)\n\n\t// Close closes the write-side of the connection.\n\tClose() error\n}\n\n// transport is the keyingTransport that implements the SSH packet\n// protocol.\ntype transport struct {\n\treader connectionState\n\twriter connectionState\n\n\tbufReader *bufio.Reader\n\tbufWriter *bufio.Writer\n\trand      io.Reader\n\tisClient  bool\n\tio.Closer\n\n\tstrictMode     bool\n\tinitialKEXDone bool\n}\n\n// packetCipher represents a combination of SSH encryption/MAC\n// protocol.  A single instance should be used for one direction only.\ntype packetCipher interface {\n\t// writeCipherPacket encrypts the packet and writes it to w. The\n\t// contents of the packet are generally scrambled.\n\twriteCipherPacket(seqnum uint32, w io.Writer, rand io.Reader, packet []byte) error\n\n\t// readCipherPacket reads and decrypts a packet of data. The\n\t// returned packet may be overwritten by future calls of\n\t// readPacket.\n\treadCipherPacket(seqnum uint32, r io.Reader) ([]byte, error)\n}\n\n// connectionState represents one side (read or write) of the\n// connection. This is necessary because each direction has its own\n// keys, and can even have its own algorithms\ntype connectionState struct {\n\tpacketCipher\n\tseqNum           uint32\n\tdir              direction\n\tpendingKeyChange chan packetCipher\n}\n\nfunc (t *transport) setStrictMode() error {\n\tif t.reader.seqNum != 1 {\n\t\treturn errors.New(\"ssh: sequence number != 1 when strict KEX mode requested\")\n\t}\n\tt.strictMode = true\n\treturn nil\n}\n\nfunc (t *transport) setInitialKEXDone() {\n\tt.initialKEXDone = true\n}\n\n// prepareKeyChange sets up key material for a keychange. The key changes in\n// both directions are triggered by reading and writing a msgNewKey packet\n// respectively.\nfunc (t *transport) prepareKeyChange(algs *algorithms, kexResult *kexResult) error {\n\tciph, err := newPacketCipher(t.reader.dir, algs.r, kexResult)\n\tif err != nil {\n\t\treturn err\n\t}\n\tt.reader.pendingKeyChange <- ciph\n\n\tciph, err = newPacketCipher(t.writer.dir, algs.w, kexResult)\n\tif err != nil {\n\t\treturn err\n\t}\n\tt.writer.pendingKeyChange <- ciph\n\n\treturn nil\n}\n\nfunc (t *transport) printPacket(p []byte, write bool) {\n\tif len(p) == 0 {\n\t\treturn\n\t}\n\twho := \"server\"\n\tif t.isClient {\n\t\twho = \"client\"\n\t}\n\twhat := \"read\"\n\tif write {\n\t\twhat = \"write\"\n\t}\n\n\tlog.Println(what, who, p[0])\n}\n\n// Read and decrypt next packet.\nfunc (t *transport) readPacket() (p []byte, err error) {\n\tfor {\n\t\tp, err = t.reader.readPacket(t.bufReader, t.strictMode)\n\t\tif err != nil {\n\t\t\tbreak\n\t\t}\n\t\t// in strict mode we pass through DEBUG and IGNORE packets only during the initial KEX\n\t\tif len(p) == 0 || (t.strictMode && !t.initialKEXDone) || (p[0] != msgIgnore && p[0] != msgDebug) {\n\t\t\tbreak\n\t\t}\n\t}\n\tif debugTransport {\n\t\tt.printPacket(p, false)\n\t}\n\n\treturn p, err\n}\n\nfunc (s *connectionState) readPacket(r *bufio.Reader, strictMode bool) ([]byte, error) {\n\tpacket, err := s.packetCipher.readCipherPacket(s.seqNum, r)\n\ts.seqNum++\n\tif err == nil && len(packet) == 0 {\n\t\terr = errors.New(\"ssh: zero length packet\")\n\t}\n\n\tif len(packet) > 0 {\n\t\tswitch packet[0] {\n\t\tcase msgNewKeys:\n\t\t\tselect {\n\t\t\tcase cipher := <-s.pendingKeyChange:\n\t\t\t\ts.packetCipher = cipher\n\t\t\t\tif strictMode {\n\t\t\t\t\ts.seqNum = 0\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn nil, errors.New(\"ssh: got bogus newkeys message\")\n\t\t\t}\n\n\t\tcase msgDisconnect:\n\t\t\t// Transform a disconnect message into an\n\t\t\t// error. Since this is lowest level at which\n\t\t\t// we interpret message types, doing it here\n\t\t\t// ensures that we don't have to handle it\n\t\t\t// elsewhere.\n\t\t\tvar msg disconnectMsg\n\t\t\tif err := Unmarshal(packet, &msg); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn nil, &msg\n\t\t}\n\t}\n\n\t// The packet may point to an internal buffer, so copy the\n\t// packet out here.\n\tfresh := make([]byte, len(packet))\n\tcopy(fresh, packet)\n\n\treturn fresh, err\n}\n\nfunc (t *transport) writePacket(packet []byte) error {\n\tif debugTransport {\n\t\tt.printPacket(packet, true)\n\t}\n\treturn t.writer.writePacket(t.bufWriter, t.rand, packet, t.strictMode)\n}\n\nfunc (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []byte, strictMode bool) error {\n\tchangeKeys := len(packet) > 0 && packet[0] == msgNewKeys\n\n\terr := s.packetCipher.writeCipherPacket(s.seqNum, w, rand, packet)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err = w.Flush(); err != nil {\n\t\treturn err\n\t}\n\ts.seqNum++\n\tif changeKeys {\n\t\tselect {\n\t\tcase cipher := <-s.pendingKeyChange:\n\t\t\ts.packetCipher = cipher\n\t\t\tif strictMode {\n\t\t\t\ts.seqNum = 0\n\t\t\t}\n\t\tdefault:\n\t\t\tpanic(\"ssh: no key material for msgNewKeys\")\n\t\t}\n\t}\n\treturn err\n}\n\nfunc newTransport(rwc io.ReadWriteCloser, rand io.Reader, isClient bool) *transport {\n\tt := &transport{\n\t\tbufReader: bufio.NewReader(rwc),\n\t\tbufWriter: bufio.NewWriter(rwc),\n\t\trand:      rand,\n\t\treader: connectionState{\n\t\t\tpacketCipher:     &streamPacketCipher{cipher: noneCipher{}},\n\t\t\tpendingKeyChange: make(chan packetCipher, 1),\n\t\t},\n\t\twriter: connectionState{\n\t\t\tpacketCipher:     &streamPacketCipher{cipher: noneCipher{}},\n\t\t\tpendingKeyChange: make(chan packetCipher, 1),\n\t\t},\n\t\tCloser: rwc,\n\t}\n\tt.isClient = isClient\n\n\tif isClient {\n\t\tt.reader.dir = serverKeys\n\t\tt.writer.dir = clientKeys\n\t} else {\n\t\tt.reader.dir = clientKeys\n\t\tt.writer.dir = serverKeys\n\t}\n\n\treturn t\n}\n\ntype direction struct {\n\tivTag     []byte\n\tkeyTag    []byte\n\tmacKeyTag []byte\n}\n\nvar (\n\tserverKeys = direction{[]byte{'B'}, []byte{'D'}, []byte{'F'}}\n\tclientKeys = direction{[]byte{'A'}, []byte{'C'}, []byte{'E'}}\n)\n\n// setupKeys sets the cipher and MAC keys from kex.K, kex.H and sessionId, as\n// described in RFC 4253, section 6.4. direction should either be serverKeys\n// (to setup server->client keys) or clientKeys (for client->server keys).\nfunc newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (packetCipher, error) {\n\tcipherMode := cipherModes[algs.Cipher]\n\n\tiv := make([]byte, cipherMode.ivSize)\n\tkey := make([]byte, cipherMode.keySize)\n\n\tgenerateKeyMaterial(iv, d.ivTag, kex)\n\tgenerateKeyMaterial(key, d.keyTag, kex)\n\n\tvar macKey []byte\n\tif !aeadCiphers[algs.Cipher] {\n\t\tmacMode := macModes[algs.MAC]\n\t\tmacKey = make([]byte, macMode.keySize)\n\t\tgenerateKeyMaterial(macKey, d.macKeyTag, kex)\n\t}\n\n\treturn cipherModes[algs.Cipher].create(key, iv, macKey, algs)\n}\n\n// generateKeyMaterial fills out with key material generated from tag, K, H\n// and sessionId, as specified in RFC 4253, section 7.2.\nfunc generateKeyMaterial(out, tag []byte, r *kexResult) {\n\tvar digestsSoFar []byte\n\n\th := r.Hash.New()\n\tfor len(out) > 0 {\n\t\th.Reset()\n\t\th.Write(r.K)\n\t\th.Write(r.H)\n\n\t\tif len(digestsSoFar) == 0 {\n\t\t\th.Write(tag)\n\t\t\th.Write(r.SessionID)\n\t\t} else {\n\t\t\th.Write(digestsSoFar)\n\t\t}\n\n\t\tdigest := h.Sum(nil)\n\t\tn := copy(out, digest)\n\t\tout = out[n:]\n\t\tif len(out) > 0 {\n\t\t\tdigestsSoFar = append(digestsSoFar, digest...)\n\t\t}\n\t}\n}\n\nconst packageVersion = \"SSH-2.0-Go\"\n\n// Sends and receives a version line.  The versionLine string should\n// be US ASCII, start with \"SSH-2.0-\", and should not include a\n// newline. exchangeVersions returns the other side's version line.\nfunc exchangeVersions(rw io.ReadWriter, versionLine []byte) (them []byte, err error) {\n\t// Contrary to the RFC, we do not ignore lines that don't\n\t// start with \"SSH-2.0-\" to make the library usable with\n\t// nonconforming servers.\n\tfor _, c := range versionLine {\n\t\t// The spec disallows non US-ASCII chars, and\n\t\t// specifically forbids null chars.\n\t\tif c < 32 {\n\t\t\treturn nil, errors.New(\"ssh: junk character in version line\")\n\t\t}\n\t}\n\tif _, err = rw.Write(append(versionLine, '\\r', '\\n')); err != nil {\n\t\treturn\n\t}\n\n\tthem, err = readVersion(rw)\n\treturn them, err\n}\n\n// maxVersionStringBytes is the maximum number of bytes that we'll\n// accept as a version string. RFC 4253 section 4.2 limits this at 255\n// chars\nconst maxVersionStringBytes = 255\n\n// Read version string as specified by RFC 4253, section 4.2.\nfunc readVersion(r io.Reader) ([]byte, error) {\n\tversionString := make([]byte, 0, 64)\n\tvar ok bool\n\tvar buf [1]byte\n\n\tfor length := 0; length < maxVersionStringBytes; length++ {\n\t\t_, err := io.ReadFull(r, buf[:])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// The RFC says that the version should be terminated with \\r\\n\n\t\t// but several SSH servers actually only send a \\n.\n\t\tif buf[0] == '\\n' {\n\t\t\tif !bytes.HasPrefix(versionString, []byte(\"SSH-\")) {\n\t\t\t\t// RFC 4253 says we need to ignore all version string lines\n\t\t\t\t// except the one containing the SSH version (provided that\n\t\t\t\t// all the lines do not exceed 255 bytes in total).\n\t\t\t\tversionString = versionString[:0]\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tok = true\n\t\t\tbreak\n\t\t}\n\n\t\t// non ASCII chars are disallowed, but we are lenient,\n\t\t// since Go doesn't use null-terminated strings.\n\n\t\t// The RFC allows a comment after a space, however,\n\t\t// all of it (version and comments) goes into the\n\t\t// session hash.\n\t\tversionString = append(versionString, buf[0])\n\t}\n\n\tif !ok {\n\t\treturn nil, errors.New(\"ssh: overflow reading version string\")\n\t}\n\n\t// There might be a '\\r' on the end which we should remove.\n\tif len(versionString) > 0 && versionString[len(versionString)-1] == '\\r' {\n\t\tversionString = versionString[:len(versionString)-1]\n\t}\n\treturn versionString, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/mod/LICENSE",
    "content": "Copyright 2009 The Go Authors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google LLC nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(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": "vendor/golang.org/x/mod/PATENTS",
    "content": "Additional IP Rights Grant (Patents)\n\n\"This implementation\" means the copyrightable works distributed by\nGoogle as part of the Go project.\n\nGoogle hereby grants to You a perpetual, worldwide, non-exclusive,\nno-charge, royalty-free, irrevocable (except as stated in this section)\npatent license to make, have made, use, offer to sell, sell, import,\ntransfer and otherwise run, modify and propagate the contents of this\nimplementation of Go, where such license applies only to those patent\nclaims, both currently owned or controlled by Google and acquired in\nthe future, licensable by Google that are necessarily infringed by this\nimplementation of Go.  This grant does not include claims that would be\ninfringed only as a consequence of further modification of this\nimplementation.  If you or your agent or exclusive licensee institute or\norder or agree to the institution of patent litigation against any\nentity (including a cross-claim or counterclaim in a lawsuit) alleging\nthat this implementation of Go or any code incorporated within this\nimplementation of Go constitutes direct or contributory patent\ninfringement, or inducement of patent infringement, then any patent\nrights granted to you under this License for this implementation of Go\nshall terminate as of the date such litigation is filed.\n"
  },
  {
    "path": "vendor/golang.org/x/mod/internal/lazyregexp/lazyre.go",
    "content": "// Copyright 2018 The Go 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\n// Package lazyregexp is a thin wrapper over regexp, allowing the use of global\n// regexp variables without forcing them to be compiled at init.\npackage lazyregexp\n\nimport (\n\t\"os\"\n\t\"regexp\"\n\t\"strings\"\n\t\"sync\"\n)\n\n// Regexp is a wrapper around [regexp.Regexp], where the underlying regexp will be\n// compiled the first time it is needed.\ntype Regexp struct {\n\tstr  string\n\tonce sync.Once\n\trx   *regexp.Regexp\n}\n\nfunc (r *Regexp) re() *regexp.Regexp {\n\tr.once.Do(r.build)\n\treturn r.rx\n}\n\nfunc (r *Regexp) build() {\n\tr.rx = regexp.MustCompile(r.str)\n\tr.str = \"\"\n}\n\nfunc (r *Regexp) FindSubmatch(s []byte) [][]byte {\n\treturn r.re().FindSubmatch(s)\n}\n\nfunc (r *Regexp) FindStringSubmatch(s string) []string {\n\treturn r.re().FindStringSubmatch(s)\n}\n\nfunc (r *Regexp) FindStringSubmatchIndex(s string) []int {\n\treturn r.re().FindStringSubmatchIndex(s)\n}\n\nfunc (r *Regexp) ReplaceAllString(src, repl string) string {\n\treturn r.re().ReplaceAllString(src, repl)\n}\n\nfunc (r *Regexp) FindString(s string) string {\n\treturn r.re().FindString(s)\n}\n\nfunc (r *Regexp) FindAllString(s string, n int) []string {\n\treturn r.re().FindAllString(s, n)\n}\n\nfunc (r *Regexp) MatchString(s string) bool {\n\treturn r.re().MatchString(s)\n}\n\nfunc (r *Regexp) SubexpNames() []string {\n\treturn r.re().SubexpNames()\n}\n\nvar inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], \".exe\"), \".test\")\n\n// New creates a new lazy regexp, delaying the compiling work until it is first\n// needed. If the code is being run as part of tests, the regexp compiling will\n// happen immediately.\nfunc New(str string) *Regexp {\n\tlr := &Regexp{str: str}\n\tif inTest {\n\t\t// In tests, always compile the regexps early.\n\t\tlr.re()\n\t}\n\treturn lr\n}\n"
  },
  {
    "path": "vendor/golang.org/x/mod/modfile/print.go",
    "content": "// Copyright 2018 The Go 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\n// Module file printer.\n\npackage modfile\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"strings\"\n)\n\n// Format returns a go.mod file as a byte slice, formatted in standard style.\nfunc Format(f *FileSyntax) []byte {\n\tpr := &printer{}\n\tpr.file(f)\n\n\t// remove trailing blank lines\n\tb := pr.Bytes()\n\tfor len(b) > 0 && b[len(b)-1] == '\\n' && (len(b) == 1 || b[len(b)-2] == '\\n') {\n\t\tb = b[:len(b)-1]\n\t}\n\treturn b\n}\n\n// A printer collects the state during printing of a file or expression.\ntype printer struct {\n\tbytes.Buffer           // output buffer\n\tcomment      []Comment // pending end-of-line comments\n\tmargin       int       // left margin (indent), a number of tabs\n}\n\n// printf prints to the buffer.\nfunc (p *printer) printf(format string, args ...interface{}) {\n\tfmt.Fprintf(p, format, args...)\n}\n\n// indent returns the position on the current line, in bytes, 0-indexed.\nfunc (p *printer) indent() int {\n\tb := p.Bytes()\n\tn := 0\n\tfor n < len(b) && b[len(b)-1-n] != '\\n' {\n\t\tn++\n\t}\n\treturn n\n}\n\n// newline ends the current line, flushing end-of-line comments.\nfunc (p *printer) newline() {\n\tif len(p.comment) > 0 {\n\t\tp.printf(\" \")\n\t\tfor i, com := range p.comment {\n\t\t\tif i > 0 {\n\t\t\t\tp.trim()\n\t\t\t\tp.printf(\"\\n\")\n\t\t\t\tfor i := 0; i < p.margin; i++ {\n\t\t\t\t\tp.printf(\"\\t\")\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.printf(\"%s\", strings.TrimSpace(com.Token))\n\t\t}\n\t\tp.comment = p.comment[:0]\n\t}\n\n\tp.trim()\n\tif b := p.Bytes(); len(b) == 0 || (len(b) >= 2 && b[len(b)-1] == '\\n' && b[len(b)-2] == '\\n') {\n\t\t// skip the blank line at top of file or after a blank line\n\t} else {\n\t\tp.printf(\"\\n\")\n\t}\n\tfor i := 0; i < p.margin; i++ {\n\t\tp.printf(\"\\t\")\n\t}\n}\n\n// trim removes trailing spaces and tabs from the current line.\nfunc (p *printer) trim() {\n\t// Remove trailing spaces and tabs from line we're about to end.\n\tb := p.Bytes()\n\tn := len(b)\n\tfor n > 0 && (b[n-1] == '\\t' || b[n-1] == ' ') {\n\t\tn--\n\t}\n\tp.Truncate(n)\n}\n\n// file formats the given file into the print buffer.\nfunc (p *printer) file(f *FileSyntax) {\n\tfor _, com := range f.Before {\n\t\tp.printf(\"%s\", strings.TrimSpace(com.Token))\n\t\tp.newline()\n\t}\n\n\tfor i, stmt := range f.Stmt {\n\t\tswitch x := stmt.(type) {\n\t\tcase *CommentBlock:\n\t\t\t// comments already handled\n\t\t\tp.expr(x)\n\n\t\tdefault:\n\t\t\tp.expr(x)\n\t\t\tp.newline()\n\t\t}\n\n\t\tfor _, com := range stmt.Comment().After {\n\t\t\tp.printf(\"%s\", strings.TrimSpace(com.Token))\n\t\t\tp.newline()\n\t\t}\n\n\t\tif i+1 < len(f.Stmt) {\n\t\t\tp.newline()\n\t\t}\n\t}\n}\n\nfunc (p *printer) expr(x Expr) {\n\t// Emit line-comments preceding this expression.\n\tif before := x.Comment().Before; len(before) > 0 {\n\t\t// Want to print a line comment.\n\t\t// Line comments must be at the current margin.\n\t\tp.trim()\n\t\tif p.indent() > 0 {\n\t\t\t// There's other text on the line. Start a new line.\n\t\t\tp.printf(\"\\n\")\n\t\t}\n\t\t// Re-indent to margin.\n\t\tfor i := 0; i < p.margin; i++ {\n\t\t\tp.printf(\"\\t\")\n\t\t}\n\t\tfor _, com := range before {\n\t\t\tp.printf(\"%s\", strings.TrimSpace(com.Token))\n\t\t\tp.newline()\n\t\t}\n\t}\n\n\tswitch x := x.(type) {\n\tdefault:\n\t\tpanic(fmt.Errorf(\"printer: unexpected type %T\", x))\n\n\tcase *CommentBlock:\n\t\t// done\n\n\tcase *LParen:\n\t\tp.printf(\"(\")\n\tcase *RParen:\n\t\tp.printf(\")\")\n\n\tcase *Line:\n\t\tp.tokens(x.Token)\n\n\tcase *LineBlock:\n\t\tp.tokens(x.Token)\n\t\tp.printf(\" \")\n\t\tp.expr(&x.LParen)\n\t\tp.margin++\n\t\tfor _, l := range x.Line {\n\t\t\tp.newline()\n\t\t\tp.expr(l)\n\t\t}\n\t\tp.margin--\n\t\tp.newline()\n\t\tp.expr(&x.RParen)\n\t}\n\n\t// Queue end-of-line comments for printing when we\n\t// reach the end of the line.\n\tp.comment = append(p.comment, x.Comment().Suffix...)\n}\n\nfunc (p *printer) tokens(tokens []string) {\n\tsep := \"\"\n\tfor _, t := range tokens {\n\t\tif t == \",\" || t == \")\" || t == \"]\" || t == \"}\" {\n\t\t\tsep = \"\"\n\t\t}\n\t\tp.printf(\"%s%s\", sep, t)\n\t\tsep = \" \"\n\t\tif t == \"(\" || t == \"[\" || t == \"{\" {\n\t\t\tsep = \"\"\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/mod/modfile/read.go",
    "content": "// Copyright 2018 The Go 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 modfile\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n)\n\n// A Position describes an arbitrary source position in a file, including the\n// file, line, column, and byte offset.\ntype Position struct {\n\tLine     int // line in input (starting at 1)\n\tLineRune int // rune in line (starting at 1)\n\tByte     int // byte in input (starting at 0)\n}\n\n// add returns the position at the end of s, assuming it starts at p.\nfunc (p Position) add(s string) Position {\n\tp.Byte += len(s)\n\tif n := strings.Count(s, \"\\n\"); n > 0 {\n\t\tp.Line += n\n\t\ts = s[strings.LastIndex(s, \"\\n\")+1:]\n\t\tp.LineRune = 1\n\t}\n\tp.LineRune += utf8.RuneCountInString(s)\n\treturn p\n}\n\n// An Expr represents an input element.\ntype Expr interface {\n\t// Span returns the start and end position of the expression,\n\t// excluding leading or trailing comments.\n\tSpan() (start, end Position)\n\n\t// Comment returns the comments attached to the expression.\n\t// This method would normally be named 'Comments' but that\n\t// would interfere with embedding a type of the same name.\n\tComment() *Comments\n}\n\n// A Comment represents a single // comment.\ntype Comment struct {\n\tStart  Position\n\tToken  string // without trailing newline\n\tSuffix bool   // an end of line (not whole line) comment\n}\n\n// Comments collects the comments associated with an expression.\ntype Comments struct {\n\tBefore []Comment // whole-line comments before this expression\n\tSuffix []Comment // end-of-line comments after this expression\n\n\t// For top-level expressions only, After lists whole-line\n\t// comments following the expression.\n\tAfter []Comment\n}\n\n// Comment returns the receiver. This isn't useful by itself, but\n// a [Comments] struct is embedded into all the expression\n// implementation types, and this gives each of those a Comment\n// method to satisfy the Expr interface.\nfunc (c *Comments) Comment() *Comments {\n\treturn c\n}\n\n// A FileSyntax represents an entire go.mod file.\ntype FileSyntax struct {\n\tName string // file path\n\tComments\n\tStmt []Expr\n}\n\nfunc (x *FileSyntax) Span() (start, end Position) {\n\tif len(x.Stmt) == 0 {\n\t\treturn\n\t}\n\tstart, _ = x.Stmt[0].Span()\n\t_, end = x.Stmt[len(x.Stmt)-1].Span()\n\treturn start, end\n}\n\n// addLine adds a line containing the given tokens to the file.\n//\n// If the first token of the hint matches the first token of the\n// line, the new line is added at the end of the block containing hint,\n// extracting hint into a new block if it is not yet in one.\n//\n// If the hint is non-nil buts its first token does not match,\n// the new line is added after the block containing hint\n// (or hint itself, if not in a block).\n//\n// If no hint is provided, addLine appends the line to the end of\n// the last block with a matching first token,\n// or to the end of the file if no such block exists.\nfunc (x *FileSyntax) addLine(hint Expr, tokens ...string) *Line {\n\tif hint == nil {\n\t\t// If no hint given, add to the last statement of the given type.\n\tLoop:\n\t\tfor i := len(x.Stmt) - 1; i >= 0; i-- {\n\t\t\tstmt := x.Stmt[i]\n\t\t\tswitch stmt := stmt.(type) {\n\t\t\tcase *Line:\n\t\t\t\tif stmt.Token != nil && stmt.Token[0] == tokens[0] {\n\t\t\t\t\thint = stmt\n\t\t\t\t\tbreak Loop\n\t\t\t\t}\n\t\t\tcase *LineBlock:\n\t\t\t\tif stmt.Token[0] == tokens[0] {\n\t\t\t\t\thint = stmt\n\t\t\t\t\tbreak Loop\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tnewLineAfter := func(i int) *Line {\n\t\tnew := &Line{Token: tokens}\n\t\tif i == len(x.Stmt) {\n\t\t\tx.Stmt = append(x.Stmt, new)\n\t\t} else {\n\t\t\tx.Stmt = append(x.Stmt, nil)\n\t\t\tcopy(x.Stmt[i+2:], x.Stmt[i+1:])\n\t\t\tx.Stmt[i+1] = new\n\t\t}\n\t\treturn new\n\t}\n\n\tif hint != nil {\n\t\tfor i, stmt := range x.Stmt {\n\t\t\tswitch stmt := stmt.(type) {\n\t\t\tcase *Line:\n\t\t\t\tif stmt == hint {\n\t\t\t\t\tif stmt.Token == nil || stmt.Token[0] != tokens[0] {\n\t\t\t\t\t\treturn newLineAfter(i)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Convert line to line block.\n\t\t\t\t\tstmt.InBlock = true\n\t\t\t\t\tblock := &LineBlock{Token: stmt.Token[:1], Line: []*Line{stmt}}\n\t\t\t\t\tstmt.Token = stmt.Token[1:]\n\t\t\t\t\tx.Stmt[i] = block\n\t\t\t\t\tnew := &Line{Token: tokens[1:], InBlock: true}\n\t\t\t\t\tblock.Line = append(block.Line, new)\n\t\t\t\t\treturn new\n\t\t\t\t}\n\n\t\t\tcase *LineBlock:\n\t\t\t\tif stmt == hint {\n\t\t\t\t\tif stmt.Token[0] != tokens[0] {\n\t\t\t\t\t\treturn newLineAfter(i)\n\t\t\t\t\t}\n\n\t\t\t\t\tnew := &Line{Token: tokens[1:], InBlock: true}\n\t\t\t\t\tstmt.Line = append(stmt.Line, new)\n\t\t\t\t\treturn new\n\t\t\t\t}\n\n\t\t\t\tfor j, line := range stmt.Line {\n\t\t\t\t\tif line == hint {\n\t\t\t\t\t\tif stmt.Token[0] != tokens[0] {\n\t\t\t\t\t\t\treturn newLineAfter(i)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Add new line after hint within the block.\n\t\t\t\t\t\tstmt.Line = append(stmt.Line, nil)\n\t\t\t\t\t\tcopy(stmt.Line[j+2:], stmt.Line[j+1:])\n\t\t\t\t\t\tnew := &Line{Token: tokens[1:], InBlock: true}\n\t\t\t\t\t\tstmt.Line[j+1] = new\n\t\t\t\t\t\treturn new\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tnew := &Line{Token: tokens}\n\tx.Stmt = append(x.Stmt, new)\n\treturn new\n}\n\nfunc (x *FileSyntax) updateLine(line *Line, tokens ...string) {\n\tif line.InBlock {\n\t\ttokens = tokens[1:]\n\t}\n\tline.Token = tokens\n}\n\n// markRemoved modifies line so that it (and its end-of-line comment, if any)\n// will be dropped by (*FileSyntax).Cleanup.\nfunc (line *Line) markRemoved() {\n\tline.Token = nil\n\tline.Comments.Suffix = nil\n}\n\n// Cleanup cleans up the file syntax x after any edit operations.\n// To avoid quadratic behavior, (*Line).markRemoved marks the line as dead\n// by setting line.Token = nil but does not remove it from the slice\n// in which it appears. After edits have all been indicated,\n// calling Cleanup cleans out the dead lines.\nfunc (x *FileSyntax) Cleanup() {\n\tw := 0\n\tfor _, stmt := range x.Stmt {\n\t\tswitch stmt := stmt.(type) {\n\t\tcase *Line:\n\t\t\tif stmt.Token == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\tcase *LineBlock:\n\t\t\tww := 0\n\t\t\tfor _, line := range stmt.Line {\n\t\t\t\tif line.Token != nil {\n\t\t\t\t\tstmt.Line[ww] = line\n\t\t\t\t\tww++\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ww == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif ww == 1 && len(stmt.RParen.Comments.Before) == 0 {\n\t\t\t\t// Collapse block into single line but keep the Line reference used by the\n\t\t\t\t// parsed File structure.\n\t\t\t\t*stmt.Line[0] = Line{\n\t\t\t\t\tComments: Comments{\n\t\t\t\t\t\tBefore: commentsAdd(stmt.Before, stmt.Line[0].Before),\n\t\t\t\t\t\tSuffix: commentsAdd(stmt.Line[0].Suffix, stmt.Suffix),\n\t\t\t\t\t\tAfter:  commentsAdd(stmt.Line[0].After, stmt.After),\n\t\t\t\t\t},\n\t\t\t\t\tToken: stringsAdd(stmt.Token, stmt.Line[0].Token),\n\t\t\t\t}\n\t\t\t\tx.Stmt[w] = stmt.Line[0]\n\t\t\t\tw++\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tstmt.Line = stmt.Line[:ww]\n\t\t}\n\t\tx.Stmt[w] = stmt\n\t\tw++\n\t}\n\tx.Stmt = x.Stmt[:w]\n}\n\nfunc commentsAdd(x, y []Comment) []Comment {\n\treturn append(x[:len(x):len(x)], y...)\n}\n\nfunc stringsAdd(x, y []string) []string {\n\treturn append(x[:len(x):len(x)], y...)\n}\n\n// A CommentBlock represents a top-level block of comments separate\n// from any rule.\ntype CommentBlock struct {\n\tComments\n\tStart Position\n}\n\nfunc (x *CommentBlock) Span() (start, end Position) {\n\treturn x.Start, x.Start\n}\n\n// A Line is a single line of tokens.\ntype Line struct {\n\tComments\n\tStart   Position\n\tToken   []string\n\tInBlock bool\n\tEnd     Position\n}\n\nfunc (x *Line) Span() (start, end Position) {\n\treturn x.Start, x.End\n}\n\n// A LineBlock is a factored block of lines, like\n//\n//\trequire (\n//\t\t\"x\"\n//\t\t\"y\"\n//\t)\ntype LineBlock struct {\n\tComments\n\tStart  Position\n\tLParen LParen\n\tToken  []string\n\tLine   []*Line\n\tRParen RParen\n}\n\nfunc (x *LineBlock) Span() (start, end Position) {\n\treturn x.Start, x.RParen.Pos.add(\")\")\n}\n\n// An LParen represents the beginning of a parenthesized line block.\n// It is a place to store suffix comments.\ntype LParen struct {\n\tComments\n\tPos Position\n}\n\nfunc (x *LParen) Span() (start, end Position) {\n\treturn x.Pos, x.Pos.add(\")\")\n}\n\n// An RParen represents the end of a parenthesized line block.\n// It is a place to store whole-line (before) comments.\ntype RParen struct {\n\tComments\n\tPos Position\n}\n\nfunc (x *RParen) Span() (start, end Position) {\n\treturn x.Pos, x.Pos.add(\")\")\n}\n\n// An input represents a single input file being parsed.\ntype input struct {\n\t// Lexing state.\n\tfilename   string    // name of input file, for errors\n\tcomplete   []byte    // entire input\n\tremaining  []byte    // remaining input\n\ttokenStart []byte    // token being scanned to end of input\n\ttoken      token     // next token to be returned by lex, peek\n\tpos        Position  // current input position\n\tcomments   []Comment // accumulated comments\n\n\t// Parser state.\n\tfile        *FileSyntax // returned top-level syntax tree\n\tparseErrors ErrorList   // errors encountered during parsing\n\n\t// Comment assignment state.\n\tpre  []Expr // all expressions, in preorder traversal\n\tpost []Expr // all expressions, in postorder traversal\n}\n\nfunc newInput(filename string, data []byte) *input {\n\treturn &input{\n\t\tfilename:  filename,\n\t\tcomplete:  data,\n\t\tremaining: data,\n\t\tpos:       Position{Line: 1, LineRune: 1, Byte: 0},\n\t}\n}\n\n// parse parses the input file.\nfunc parse(file string, data []byte) (f *FileSyntax, err error) {\n\t// The parser panics for both routine errors like syntax errors\n\t// and for programmer bugs like array index errors.\n\t// Turn both into error returns. Catching bug panics is\n\t// especially important when processing many files.\n\tin := newInput(file, data)\n\tdefer func() {\n\t\tif e := recover(); e != nil && e != &in.parseErrors {\n\t\t\tin.parseErrors = append(in.parseErrors, Error{\n\t\t\t\tFilename: in.filename,\n\t\t\t\tPos:      in.pos,\n\t\t\t\tErr:      fmt.Errorf(\"internal error: %v\", e),\n\t\t\t})\n\t\t}\n\t\tif err == nil && len(in.parseErrors) > 0 {\n\t\t\terr = in.parseErrors\n\t\t}\n\t}()\n\n\t// Prime the lexer by reading in the first token. It will be available\n\t// in the next peek() or lex() call.\n\tin.readToken()\n\n\t// Invoke the parser.\n\tin.parseFile()\n\tif len(in.parseErrors) > 0 {\n\t\treturn nil, in.parseErrors\n\t}\n\tin.file.Name = in.filename\n\n\t// Assign comments to nearby syntax.\n\tin.assignComments()\n\n\treturn in.file, nil\n}\n\n// Error is called to report an error.\n// Error does not return: it panics.\nfunc (in *input) Error(s string) {\n\tin.parseErrors = append(in.parseErrors, Error{\n\t\tFilename: in.filename,\n\t\tPos:      in.pos,\n\t\tErr:      errors.New(s),\n\t})\n\tpanic(&in.parseErrors)\n}\n\n// eof reports whether the input has reached end of file.\nfunc (in *input) eof() bool {\n\treturn len(in.remaining) == 0\n}\n\n// peekRune returns the next rune in the input without consuming it.\nfunc (in *input) peekRune() int {\n\tif len(in.remaining) == 0 {\n\t\treturn 0\n\t}\n\tr, _ := utf8.DecodeRune(in.remaining)\n\treturn int(r)\n}\n\n// peekPrefix reports whether the remaining input begins with the given prefix.\nfunc (in *input) peekPrefix(prefix string) bool {\n\t// This is like bytes.HasPrefix(in.remaining, []byte(prefix))\n\t// but without the allocation of the []byte copy of prefix.\n\tfor i := 0; i < len(prefix); i++ {\n\t\tif i >= len(in.remaining) || in.remaining[i] != prefix[i] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// readRune consumes and returns the next rune in the input.\nfunc (in *input) readRune() int {\n\tif len(in.remaining) == 0 {\n\t\tin.Error(\"internal lexer error: readRune at EOF\")\n\t}\n\tr, size := utf8.DecodeRune(in.remaining)\n\tin.remaining = in.remaining[size:]\n\tif r == '\\n' {\n\t\tin.pos.Line++\n\t\tin.pos.LineRune = 1\n\t} else {\n\t\tin.pos.LineRune++\n\t}\n\tin.pos.Byte += size\n\treturn int(r)\n}\n\ntype token struct {\n\tkind   tokenKind\n\tpos    Position\n\tendPos Position\n\ttext   string\n}\n\ntype tokenKind int\n\nconst (\n\t_EOF tokenKind = -(iota + 1)\n\t_EOLCOMMENT\n\t_IDENT\n\t_STRING\n\t_COMMENT\n\n\t// newlines and punctuation tokens are allowed as ASCII codes.\n)\n\nfunc (k tokenKind) isComment() bool {\n\treturn k == _COMMENT || k == _EOLCOMMENT\n}\n\n// isEOL returns whether a token terminates a line.\nfunc (k tokenKind) isEOL() bool {\n\treturn k == _EOF || k == _EOLCOMMENT || k == '\\n'\n}\n\n// startToken marks the beginning of the next input token.\n// It must be followed by a call to endToken, once the token's text has\n// been consumed using readRune.\nfunc (in *input) startToken() {\n\tin.tokenStart = in.remaining\n\tin.token.text = \"\"\n\tin.token.pos = in.pos\n}\n\n// endToken marks the end of an input token.\n// It records the actual token string in tok.text.\n// A single trailing newline (LF or CRLF) will be removed from comment tokens.\nfunc (in *input) endToken(kind tokenKind) {\n\tin.token.kind = kind\n\ttext := string(in.tokenStart[:len(in.tokenStart)-len(in.remaining)])\n\tif kind.isComment() {\n\t\tif strings.HasSuffix(text, \"\\r\\n\") {\n\t\t\ttext = text[:len(text)-2]\n\t\t} else {\n\t\t\ttext = strings.TrimSuffix(text, \"\\n\")\n\t\t}\n\t}\n\tin.token.text = text\n\tin.token.endPos = in.pos\n}\n\n// peek returns the kind of the next token returned by lex.\nfunc (in *input) peek() tokenKind {\n\treturn in.token.kind\n}\n\n// lex is called from the parser to obtain the next input token.\nfunc (in *input) lex() token {\n\ttok := in.token\n\tin.readToken()\n\treturn tok\n}\n\n// readToken lexes the next token from the text and stores it in in.token.\nfunc (in *input) readToken() {\n\t// Skip past spaces, stopping at non-space or EOF.\n\tfor !in.eof() {\n\t\tc := in.peekRune()\n\t\tif c == ' ' || c == '\\t' || c == '\\r' {\n\t\t\tin.readRune()\n\t\t\tcontinue\n\t\t}\n\n\t\t// Comment runs to end of line.\n\t\tif in.peekPrefix(\"//\") {\n\t\t\tin.startToken()\n\n\t\t\t// Is this comment the only thing on its line?\n\t\t\t// Find the last \\n before this // and see if it's all\n\t\t\t// spaces from there to here.\n\t\t\ti := bytes.LastIndex(in.complete[:in.pos.Byte], []byte(\"\\n\"))\n\t\t\tsuffix := len(bytes.TrimSpace(in.complete[i+1:in.pos.Byte])) > 0\n\t\t\tin.readRune()\n\t\t\tin.readRune()\n\n\t\t\t// Consume comment.\n\t\t\tfor len(in.remaining) > 0 && in.readRune() != '\\n' {\n\t\t\t}\n\n\t\t\t// If we are at top level (not in a statement), hand the comment to\n\t\t\t// the parser as a _COMMENT token. The grammar is written\n\t\t\t// to handle top-level comments itself.\n\t\t\tif !suffix {\n\t\t\t\tin.endToken(_COMMENT)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Otherwise, save comment for later attachment to syntax tree.\n\t\t\tin.endToken(_EOLCOMMENT)\n\t\t\tin.comments = append(in.comments, Comment{in.token.pos, in.token.text, suffix})\n\t\t\treturn\n\t\t}\n\n\t\tif in.peekPrefix(\"/*\") {\n\t\t\tin.Error(\"mod files must use // comments (not /* */ comments)\")\n\t\t}\n\n\t\t// Found non-space non-comment.\n\t\tbreak\n\t}\n\n\t// Found the beginning of the next token.\n\tin.startToken()\n\n\t// End of file.\n\tif in.eof() {\n\t\tin.endToken(_EOF)\n\t\treturn\n\t}\n\n\t// Punctuation tokens.\n\tswitch c := in.peekRune(); c {\n\tcase '\\n', '(', ')', '[', ']', '{', '}', ',':\n\t\tin.readRune()\n\t\tin.endToken(tokenKind(c))\n\t\treturn\n\n\tcase '\"', '`': // quoted string\n\t\tquote := c\n\t\tin.readRune()\n\t\tfor {\n\t\t\tif in.eof() {\n\t\t\t\tin.pos = in.token.pos\n\t\t\t\tin.Error(\"unexpected EOF in string\")\n\t\t\t}\n\t\t\tif in.peekRune() == '\\n' {\n\t\t\t\tin.Error(\"unexpected newline in string\")\n\t\t\t}\n\t\t\tc := in.readRune()\n\t\t\tif c == quote {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif c == '\\\\' && quote != '`' {\n\t\t\t\tif in.eof() {\n\t\t\t\t\tin.pos = in.token.pos\n\t\t\t\t\tin.Error(\"unexpected EOF in string\")\n\t\t\t\t}\n\t\t\t\tin.readRune()\n\t\t\t}\n\t\t}\n\t\tin.endToken(_STRING)\n\t\treturn\n\t}\n\n\t// Checked all punctuation. Must be identifier token.\n\tif c := in.peekRune(); !isIdent(c) {\n\t\tin.Error(fmt.Sprintf(\"unexpected input character %#q\", c))\n\t}\n\n\t// Scan over identifier.\n\tfor isIdent(in.peekRune()) {\n\t\tif in.peekPrefix(\"//\") {\n\t\t\tbreak\n\t\t}\n\t\tif in.peekPrefix(\"/*\") {\n\t\t\tin.Error(\"mod files must use // comments (not /* */ comments)\")\n\t\t}\n\t\tin.readRune()\n\t}\n\tin.endToken(_IDENT)\n}\n\n// isIdent reports whether c is an identifier rune.\n// We treat most printable runes as identifier runes, except for a handful of\n// ASCII punctuation characters.\nfunc isIdent(c int) bool {\n\tswitch r := rune(c); r {\n\tcase ' ', '(', ')', '[', ']', '{', '}', ',':\n\t\treturn false\n\tdefault:\n\t\treturn !unicode.IsSpace(r) && unicode.IsPrint(r)\n\t}\n}\n\n// Comment assignment.\n// We build two lists of all subexpressions, preorder and postorder.\n// The preorder list is ordered by start location, with outer expressions first.\n// The postorder list is ordered by end location, with outer expressions last.\n// We use the preorder list to assign each whole-line comment to the syntax\n// immediately following it, and we use the postorder list to assign each\n// end-of-line comment to the syntax immediately preceding it.\n\n// order walks the expression adding it and its subexpressions to the\n// preorder and postorder lists.\nfunc (in *input) order(x Expr) {\n\tif x != nil {\n\t\tin.pre = append(in.pre, x)\n\t}\n\tswitch x := x.(type) {\n\tdefault:\n\t\tpanic(fmt.Errorf(\"order: unexpected type %T\", x))\n\tcase nil:\n\t\t// nothing\n\tcase *LParen, *RParen:\n\t\t// nothing\n\tcase *CommentBlock:\n\t\t// nothing\n\tcase *Line:\n\t\t// nothing\n\tcase *FileSyntax:\n\t\tfor _, stmt := range x.Stmt {\n\t\t\tin.order(stmt)\n\t\t}\n\tcase *LineBlock:\n\t\tin.order(&x.LParen)\n\t\tfor _, l := range x.Line {\n\t\t\tin.order(l)\n\t\t}\n\t\tin.order(&x.RParen)\n\t}\n\tif x != nil {\n\t\tin.post = append(in.post, x)\n\t}\n}\n\n// assignComments attaches comments to nearby syntax.\nfunc (in *input) assignComments() {\n\tconst debug = false\n\n\t// Generate preorder and postorder lists.\n\tin.order(in.file)\n\n\t// Split into whole-line comments and suffix comments.\n\tvar line, suffix []Comment\n\tfor _, com := range in.comments {\n\t\tif com.Suffix {\n\t\t\tsuffix = append(suffix, com)\n\t\t} else {\n\t\t\tline = append(line, com)\n\t\t}\n\t}\n\n\tif debug {\n\t\tfor _, c := range line {\n\t\t\tfmt.Fprintf(os.Stderr, \"LINE %q :%d:%d #%d\\n\", c.Token, c.Start.Line, c.Start.LineRune, c.Start.Byte)\n\t\t}\n\t}\n\n\t// Assign line comments to syntax immediately following.\n\tfor _, x := range in.pre {\n\t\tstart, _ := x.Span()\n\t\tif debug {\n\t\t\tfmt.Fprintf(os.Stderr, \"pre %T :%d:%d #%d\\n\", x, start.Line, start.LineRune, start.Byte)\n\t\t}\n\t\txcom := x.Comment()\n\t\tfor len(line) > 0 && start.Byte >= line[0].Start.Byte {\n\t\t\tif debug {\n\t\t\t\tfmt.Fprintf(os.Stderr, \"ASSIGN LINE %q #%d\\n\", line[0].Token, line[0].Start.Byte)\n\t\t\t}\n\t\t\txcom.Before = append(xcom.Before, line[0])\n\t\t\tline = line[1:]\n\t\t}\n\t}\n\n\t// Remaining line comments go at end of file.\n\tin.file.After = append(in.file.After, line...)\n\n\tif debug {\n\t\tfor _, c := range suffix {\n\t\t\tfmt.Fprintf(os.Stderr, \"SUFFIX %q :%d:%d #%d\\n\", c.Token, c.Start.Line, c.Start.LineRune, c.Start.Byte)\n\t\t}\n\t}\n\n\t// Assign suffix comments to syntax immediately before.\n\tfor i := len(in.post) - 1; i >= 0; i-- {\n\t\tx := in.post[i]\n\n\t\tstart, end := x.Span()\n\t\tif debug {\n\t\t\tfmt.Fprintf(os.Stderr, \"post %T :%d:%d #%d :%d:%d #%d\\n\", x, start.Line, start.LineRune, start.Byte, end.Line, end.LineRune, end.Byte)\n\t\t}\n\n\t\t// Do not assign suffix comments to end of line block or whole file.\n\t\t// Instead assign them to the last element inside.\n\t\tswitch x.(type) {\n\t\tcase *FileSyntax:\n\t\t\tcontinue\n\t\t}\n\n\t\t// Do not assign suffix comments to something that starts\n\t\t// on an earlier line, so that in\n\t\t//\n\t\t//\tx ( y\n\t\t//\t\tz ) // comment\n\t\t//\n\t\t// we assign the comment to z and not to x ( ... ).\n\t\tif start.Line != end.Line {\n\t\t\tcontinue\n\t\t}\n\t\txcom := x.Comment()\n\t\tfor len(suffix) > 0 && end.Byte <= suffix[len(suffix)-1].Start.Byte {\n\t\t\tif debug {\n\t\t\t\tfmt.Fprintf(os.Stderr, \"ASSIGN SUFFIX %q #%d\\n\", suffix[len(suffix)-1].Token, suffix[len(suffix)-1].Start.Byte)\n\t\t\t}\n\t\t\txcom.Suffix = append(xcom.Suffix, suffix[len(suffix)-1])\n\t\t\tsuffix = suffix[:len(suffix)-1]\n\t\t}\n\t}\n\n\t// We assigned suffix comments in reverse.\n\t// If multiple suffix comments were appended to the same\n\t// expression node, they are now in reverse. Fix that.\n\tfor _, x := range in.post {\n\t\treverseComments(x.Comment().Suffix)\n\t}\n\n\t// Remaining suffix comments go at beginning of file.\n\tin.file.Before = append(in.file.Before, suffix...)\n}\n\n// reverseComments reverses the []Comment list.\nfunc reverseComments(list []Comment) {\n\tfor i, j := 0, len(list)-1; i < j; i, j = i+1, j-1 {\n\t\tlist[i], list[j] = list[j], list[i]\n\t}\n}\n\nfunc (in *input) parseFile() {\n\tin.file = new(FileSyntax)\n\tvar cb *CommentBlock\n\tfor {\n\t\tswitch in.peek() {\n\t\tcase '\\n':\n\t\t\tin.lex()\n\t\t\tif cb != nil {\n\t\t\t\tin.file.Stmt = append(in.file.Stmt, cb)\n\t\t\t\tcb = nil\n\t\t\t}\n\t\tcase _COMMENT:\n\t\t\ttok := in.lex()\n\t\t\tif cb == nil {\n\t\t\t\tcb = &CommentBlock{Start: tok.pos}\n\t\t\t}\n\t\t\tcom := cb.Comment()\n\t\t\tcom.Before = append(com.Before, Comment{Start: tok.pos, Token: tok.text})\n\t\tcase _EOF:\n\t\t\tif cb != nil {\n\t\t\t\tin.file.Stmt = append(in.file.Stmt, cb)\n\t\t\t}\n\t\t\treturn\n\t\tdefault:\n\t\t\tin.parseStmt()\n\t\t\tif cb != nil {\n\t\t\t\tin.file.Stmt[len(in.file.Stmt)-1].Comment().Before = cb.Before\n\t\t\t\tcb = nil\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (in *input) parseStmt() {\n\ttok := in.lex()\n\tstart := tok.pos\n\tend := tok.endPos\n\ttokens := []string{tok.text}\n\tfor {\n\t\ttok := in.lex()\n\t\tswitch {\n\t\tcase tok.kind.isEOL():\n\t\t\tin.file.Stmt = append(in.file.Stmt, &Line{\n\t\t\t\tStart: start,\n\t\t\t\tToken: tokens,\n\t\t\t\tEnd:   end,\n\t\t\t})\n\t\t\treturn\n\n\t\tcase tok.kind == '(':\n\t\t\tif next := in.peek(); next.isEOL() {\n\t\t\t\t// Start of block: no more tokens on this line.\n\t\t\t\tin.file.Stmt = append(in.file.Stmt, in.parseLineBlock(start, tokens, tok))\n\t\t\t\treturn\n\t\t\t} else if next == ')' {\n\t\t\t\trparen := in.lex()\n\t\t\t\tif in.peek().isEOL() {\n\t\t\t\t\t// Empty block.\n\t\t\t\t\tin.lex()\n\t\t\t\t\tin.file.Stmt = append(in.file.Stmt, &LineBlock{\n\t\t\t\t\t\tStart:  start,\n\t\t\t\t\t\tToken:  tokens,\n\t\t\t\t\t\tLParen: LParen{Pos: tok.pos},\n\t\t\t\t\t\tRParen: RParen{Pos: rparen.pos},\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t// '( )' in the middle of the line, not a block.\n\t\t\t\ttokens = append(tokens, tok.text, rparen.text)\n\t\t\t} else {\n\t\t\t\t// '(' in the middle of the line, not a block.\n\t\t\t\ttokens = append(tokens, tok.text)\n\t\t\t}\n\n\t\tdefault:\n\t\t\ttokens = append(tokens, tok.text)\n\t\t\tend = tok.endPos\n\t\t}\n\t}\n}\n\nfunc (in *input) parseLineBlock(start Position, token []string, lparen token) *LineBlock {\n\tx := &LineBlock{\n\t\tStart:  start,\n\t\tToken:  token,\n\t\tLParen: LParen{Pos: lparen.pos},\n\t}\n\tvar comments []Comment\n\tfor {\n\t\tswitch in.peek() {\n\t\tcase _EOLCOMMENT:\n\t\t\t// Suffix comment, will be attached later by assignComments.\n\t\t\tin.lex()\n\t\tcase '\\n':\n\t\t\t// Blank line. Add an empty comment to preserve it.\n\t\t\tin.lex()\n\t\t\tif len(comments) == 0 && len(x.Line) > 0 || len(comments) > 0 && comments[len(comments)-1].Token != \"\" {\n\t\t\t\tcomments = append(comments, Comment{})\n\t\t\t}\n\t\tcase _COMMENT:\n\t\t\ttok := in.lex()\n\t\t\tcomments = append(comments, Comment{Start: tok.pos, Token: tok.text})\n\t\tcase _EOF:\n\t\t\tin.Error(fmt.Sprintf(\"syntax error (unterminated block started at %s:%d:%d)\", in.filename, x.Start.Line, x.Start.LineRune))\n\t\tcase ')':\n\t\t\trparen := in.lex()\n\t\t\t// Don't preserve blank lines (denoted by a single empty comment, added above)\n\t\t\t// at the end of the block.\n\t\t\tif len(comments) == 1 && comments[0] == (Comment{}) {\n\t\t\t\tcomments = nil\n\t\t\t}\n\t\t\tx.RParen.Before = comments\n\t\t\tx.RParen.Pos = rparen.pos\n\t\t\tif !in.peek().isEOL() {\n\t\t\t\tin.Error(\"syntax error (expected newline after closing paren)\")\n\t\t\t}\n\t\t\tin.lex()\n\t\t\treturn x\n\t\tdefault:\n\t\t\tl := in.parseLine()\n\t\t\tx.Line = append(x.Line, l)\n\t\t\tl.Comment().Before = comments\n\t\t\tcomments = nil\n\t\t}\n\t}\n}\n\nfunc (in *input) parseLine() *Line {\n\ttok := in.lex()\n\tif tok.kind.isEOL() {\n\t\tin.Error(\"internal parse error: parseLine at end of line\")\n\t}\n\tstart := tok.pos\n\tend := tok.endPos\n\ttokens := []string{tok.text}\n\tfor {\n\t\ttok := in.lex()\n\t\tif tok.kind.isEOL() {\n\t\t\treturn &Line{\n\t\t\t\tStart:   start,\n\t\t\t\tToken:   tokens,\n\t\t\t\tEnd:     end,\n\t\t\t\tInBlock: true,\n\t\t\t}\n\t\t}\n\t\ttokens = append(tokens, tok.text)\n\t\tend = tok.endPos\n\t}\n}\n\nvar (\n\tslashSlash = []byte(\"//\")\n\tmoduleStr  = []byte(\"module\")\n)\n\n// ModulePath returns the module path from the gomod file text.\n// If it cannot find a module path, it returns an empty string.\n// It is tolerant of unrelated problems in the go.mod file.\nfunc ModulePath(mod []byte) string {\n\tfor len(mod) > 0 {\n\t\tline := mod\n\t\tmod = nil\n\t\tif i := bytes.IndexByte(line, '\\n'); i >= 0 {\n\t\t\tline, mod = line[:i], line[i+1:]\n\t\t}\n\t\tif i := bytes.Index(line, slashSlash); i >= 0 {\n\t\t\tline = line[:i]\n\t\t}\n\t\tline = bytes.TrimSpace(line)\n\t\tif !bytes.HasPrefix(line, moduleStr) {\n\t\t\tcontinue\n\t\t}\n\t\tline = line[len(moduleStr):]\n\t\tn := len(line)\n\t\tline = bytes.TrimSpace(line)\n\t\tif len(line) == n || len(line) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tif line[0] == '\"' || line[0] == '`' {\n\t\t\tp, err := strconv.Unquote(string(line))\n\t\t\tif err != nil {\n\t\t\t\treturn \"\" // malformed quoted string or multiline module path\n\t\t\t}\n\t\t\treturn p\n\t\t}\n\n\t\treturn string(line)\n\t}\n\treturn \"\" // missing module path\n}\n"
  },
  {
    "path": "vendor/golang.org/x/mod/modfile/rule.go",
    "content": "// Copyright 2018 The Go 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\n// Package modfile implements a parser and formatter for go.mod files.\n//\n// The go.mod syntax is described in\n// https://pkg.go.dev/cmd/go/#hdr-The_go_mod_file.\n//\n// The [Parse] and [ParseLax] functions both parse a go.mod file and return an\n// abstract syntax tree. ParseLax ignores unknown statements and may be used to\n// parse go.mod files that may have been developed with newer versions of Go.\n//\n// The [File] struct returned by Parse and ParseLax represent an abstract\n// go.mod file. File has several methods like [File.AddNewRequire] and\n// [File.DropReplace] that can be used to programmatically edit a file.\n//\n// The [Format] function formats a File back to a byte slice which can be\n// written to a file.\npackage modfile\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\"golang.org/x/mod/internal/lazyregexp\"\n\t\"golang.org/x/mod/module\"\n\t\"golang.org/x/mod/semver\"\n)\n\n// A File is the parsed, interpreted form of a go.mod file.\ntype File struct {\n\tModule    *Module\n\tGo        *Go\n\tToolchain *Toolchain\n\tGodebug   []*Godebug\n\tRequire   []*Require\n\tExclude   []*Exclude\n\tReplace   []*Replace\n\tRetract   []*Retract\n\tTool      []*Tool\n\n\tSyntax *FileSyntax\n}\n\n// A Module is the module statement.\ntype Module struct {\n\tMod        module.Version\n\tDeprecated string\n\tSyntax     *Line\n}\n\n// A Go is the go statement.\ntype Go struct {\n\tVersion string // \"1.23\"\n\tSyntax  *Line\n}\n\n// A Toolchain is the toolchain statement.\ntype Toolchain struct {\n\tName   string // \"go1.21rc1\"\n\tSyntax *Line\n}\n\n// A Godebug is a single godebug key=value statement.\ntype Godebug struct {\n\tKey    string\n\tValue  string\n\tSyntax *Line\n}\n\n// An Exclude is a single exclude statement.\ntype Exclude struct {\n\tMod    module.Version\n\tSyntax *Line\n}\n\n// A Replace is a single replace statement.\ntype Replace struct {\n\tOld    module.Version\n\tNew    module.Version\n\tSyntax *Line\n}\n\n// A Retract is a single retract statement.\ntype Retract struct {\n\tVersionInterval\n\tRationale string\n\tSyntax    *Line\n}\n\n// A Tool is a single tool statement.\ntype Tool struct {\n\tPath   string\n\tSyntax *Line\n}\n\n// A VersionInterval represents a range of versions with upper and lower bounds.\n// Intervals are closed: both bounds are included. When Low is equal to High,\n// the interval may refer to a single version ('v1.2.3') or an interval\n// ('[v1.2.3, v1.2.3]'); both have the same representation.\ntype VersionInterval struct {\n\tLow, High string\n}\n\n// A Require is a single require statement.\ntype Require struct {\n\tMod      module.Version\n\tIndirect bool // has \"// indirect\" comment\n\tSyntax   *Line\n}\n\nfunc (r *Require) markRemoved() {\n\tr.Syntax.markRemoved()\n\t*r = Require{}\n}\n\nfunc (r *Require) setVersion(v string) {\n\tr.Mod.Version = v\n\n\tif line := r.Syntax; len(line.Token) > 0 {\n\t\tif line.InBlock {\n\t\t\t// If the line is preceded by an empty line, remove it; see\n\t\t\t// https://golang.org/issue/33779.\n\t\t\tif len(line.Comments.Before) == 1 && len(line.Comments.Before[0].Token) == 0 {\n\t\t\t\tline.Comments.Before = line.Comments.Before[:0]\n\t\t\t}\n\t\t\tif len(line.Token) >= 2 { // example.com v1.2.3\n\t\t\t\tline.Token[1] = v\n\t\t\t}\n\t\t} else {\n\t\t\tif len(line.Token) >= 3 { // require example.com v1.2.3\n\t\t\t\tline.Token[2] = v\n\t\t\t}\n\t\t}\n\t}\n}\n\n// setIndirect sets line to have (or not have) a \"// indirect\" comment.\nfunc (r *Require) setIndirect(indirect bool) {\n\tr.Indirect = indirect\n\tline := r.Syntax\n\tif isIndirect(line) == indirect {\n\t\treturn\n\t}\n\tif indirect {\n\t\t// Adding comment.\n\t\tif len(line.Suffix) == 0 {\n\t\t\t// New comment.\n\t\t\tline.Suffix = []Comment{{Token: \"// indirect\", Suffix: true}}\n\t\t\treturn\n\t\t}\n\n\t\tcom := &line.Suffix[0]\n\t\ttext := strings.TrimSpace(strings.TrimPrefix(com.Token, string(slashSlash)))\n\t\tif text == \"\" {\n\t\t\t// Empty comment.\n\t\t\tcom.Token = \"// indirect\"\n\t\t\treturn\n\t\t}\n\n\t\t// Insert at beginning of existing comment.\n\t\tcom.Token = \"// indirect; \" + text\n\t\treturn\n\t}\n\n\t// Removing comment.\n\tf := strings.TrimSpace(strings.TrimPrefix(line.Suffix[0].Token, string(slashSlash)))\n\tif f == \"indirect\" {\n\t\t// Remove whole comment.\n\t\tline.Suffix = nil\n\t\treturn\n\t}\n\n\t// Remove comment prefix.\n\tcom := &line.Suffix[0]\n\ti := strings.Index(com.Token, \"indirect;\")\n\tcom.Token = \"//\" + com.Token[i+len(\"indirect;\"):]\n}\n\n// isIndirect reports whether line has a \"// indirect\" comment,\n// meaning it is in go.mod only for its effect on indirect dependencies,\n// so that it can be dropped entirely once the effective version of the\n// indirect dependency reaches the given minimum version.\nfunc isIndirect(line *Line) bool {\n\tif len(line.Suffix) == 0 {\n\t\treturn false\n\t}\n\tf := strings.Fields(strings.TrimPrefix(line.Suffix[0].Token, string(slashSlash)))\n\treturn (len(f) == 1 && f[0] == \"indirect\" || len(f) > 1 && f[0] == \"indirect;\")\n}\n\nfunc (f *File) AddModuleStmt(path string) error {\n\tif f.Syntax == nil {\n\t\tf.Syntax = new(FileSyntax)\n\t}\n\tif f.Module == nil {\n\t\tf.Module = &Module{\n\t\t\tMod:    module.Version{Path: path},\n\t\t\tSyntax: f.Syntax.addLine(nil, \"module\", AutoQuote(path)),\n\t\t}\n\t} else {\n\t\tf.Module.Mod.Path = path\n\t\tf.Syntax.updateLine(f.Module.Syntax, \"module\", AutoQuote(path))\n\t}\n\treturn nil\n}\n\nfunc (f *File) AddComment(text string) {\n\tif f.Syntax == nil {\n\t\tf.Syntax = new(FileSyntax)\n\t}\n\tf.Syntax.Stmt = append(f.Syntax.Stmt, &CommentBlock{\n\t\tComments: Comments{\n\t\t\tBefore: []Comment{\n\t\t\t\t{\n\t\t\t\t\tToken: text,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n\ntype VersionFixer func(path, version string) (string, error)\n\n// errDontFix is returned by a VersionFixer to indicate the version should be\n// left alone, even if it's not canonical.\nvar dontFixRetract VersionFixer = func(_, vers string) (string, error) {\n\treturn vers, nil\n}\n\n// Parse parses and returns a go.mod file.\n//\n// file is the name of the file, used in positions and errors.\n//\n// data is the content of the file.\n//\n// fix is an optional function that canonicalizes module versions.\n// If fix is nil, all module versions must be canonical ([module.CanonicalVersion]\n// must return the same string).\nfunc Parse(file string, data []byte, fix VersionFixer) (*File, error) {\n\treturn parseToFile(file, data, fix, true)\n}\n\n// ParseLax is like Parse but ignores unknown statements.\n// It is used when parsing go.mod files other than the main module,\n// under the theory that most statement types we add in the future will\n// only apply in the main module, like exclude and replace,\n// and so we get better gradual deployments if old go commands\n// simply ignore those statements when found in go.mod files\n// in dependencies.\nfunc ParseLax(file string, data []byte, fix VersionFixer) (*File, error) {\n\treturn parseToFile(file, data, fix, false)\n}\n\nfunc parseToFile(file string, data []byte, fix VersionFixer, strict bool) (parsed *File, err error) {\n\tfs, err := parse(file, data)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tf := &File{\n\t\tSyntax: fs,\n\t}\n\tvar errs ErrorList\n\n\t// fix versions in retract directives after the file is parsed.\n\t// We need the module path to fix versions, and it might be at the end.\n\tdefer func() {\n\t\toldLen := len(errs)\n\t\tf.fixRetract(fix, &errs)\n\t\tif len(errs) > oldLen {\n\t\t\tparsed, err = nil, errs\n\t\t}\n\t}()\n\n\tfor _, x := range fs.Stmt {\n\t\tswitch x := x.(type) {\n\t\tcase *Line:\n\t\t\tf.add(&errs, nil, x, x.Token[0], x.Token[1:], fix, strict)\n\n\t\tcase *LineBlock:\n\t\t\tif len(x.Token) > 1 {\n\t\t\t\tif strict {\n\t\t\t\t\terrs = append(errs, Error{\n\t\t\t\t\t\tFilename: file,\n\t\t\t\t\t\tPos:      x.Start,\n\t\t\t\t\t\tErr:      fmt.Errorf(\"unknown block type: %s\", strings.Join(x.Token, \" \")),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tswitch x.Token[0] {\n\t\t\tdefault:\n\t\t\t\tif strict {\n\t\t\t\t\terrs = append(errs, Error{\n\t\t\t\t\t\tFilename: file,\n\t\t\t\t\t\tPos:      x.Start,\n\t\t\t\t\t\tErr:      fmt.Errorf(\"unknown block type: %s\", strings.Join(x.Token, \" \")),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\tcase \"module\", \"godebug\", \"require\", \"exclude\", \"replace\", \"retract\", \"tool\":\n\t\t\t\tfor _, l := range x.Line {\n\t\t\t\t\tf.add(&errs, x, l, x.Token[0], l.Token, fix, strict)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(errs) > 0 {\n\t\treturn nil, errs\n\t}\n\treturn f, nil\n}\n\nvar GoVersionRE = lazyregexp.New(`^([1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\.(0|[1-9][0-9]*))?([a-z]+[0-9]+)?$`)\nvar laxGoVersionRE = lazyregexp.New(`^v?(([1-9][0-9]*)\\.(0|[1-9][0-9]*))([^0-9].*)$`)\n\n// Toolchains must be named beginning with `go1`,\n// like \"go1.20.3\" or \"go1.20.3-gccgo\". As a special case, \"default\" is also permitted.\n// Note that this regexp is a much looser condition than go/version.IsValid,\n// for forward compatibility.\n// (This code has to be work to identify new toolchains even if we tweak the syntax in the future.)\nvar ToolchainRE = lazyregexp.New(`^default$|^go1($|\\.)`)\n\nfunc (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, args []string, fix VersionFixer, strict bool) {\n\t// If strict is false, this module is a dependency.\n\t// We ignore all unknown directives as well as main-module-only\n\t// directives like replace and exclude. It will work better for\n\t// forward compatibility if we can depend on modules that have unknown\n\t// statements (presumed relevant only when acting as the main module)\n\t// and simply ignore those statements.\n\tif !strict {\n\t\tswitch verb {\n\t\tcase \"go\", \"module\", \"retract\", \"require\":\n\t\t\t// want these even for dependency go.mods\n\t\tdefault:\n\t\t\treturn\n\t\t}\n\t}\n\n\twrapModPathError := func(modPath string, err error) {\n\t\t*errs = append(*errs, Error{\n\t\t\tFilename: f.Syntax.Name,\n\t\t\tPos:      line.Start,\n\t\t\tModPath:  modPath,\n\t\t\tVerb:     verb,\n\t\t\tErr:      err,\n\t\t})\n\t}\n\twrapError := func(err error) {\n\t\t*errs = append(*errs, Error{\n\t\t\tFilename: f.Syntax.Name,\n\t\t\tPos:      line.Start,\n\t\t\tErr:      err,\n\t\t})\n\t}\n\terrorf := func(format string, args ...interface{}) {\n\t\twrapError(fmt.Errorf(format, args...))\n\t}\n\n\tswitch verb {\n\tdefault:\n\t\terrorf(\"unknown directive: %s\", verb)\n\n\tcase \"go\":\n\t\tif f.Go != nil {\n\t\t\terrorf(\"repeated go statement\")\n\t\t\treturn\n\t\t}\n\t\tif len(args) != 1 {\n\t\t\terrorf(\"go directive expects exactly one argument\")\n\t\t\treturn\n\t\t} else if !GoVersionRE.MatchString(args[0]) {\n\t\t\tfixed := false\n\t\t\tif !strict {\n\t\t\t\tif m := laxGoVersionRE.FindStringSubmatch(args[0]); m != nil {\n\t\t\t\t\targs[0] = m[1]\n\t\t\t\t\tfixed = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !fixed {\n\t\t\t\terrorf(\"invalid go version '%s': must match format 1.23.0\", args[0])\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tf.Go = &Go{Syntax: line}\n\t\tf.Go.Version = args[0]\n\n\tcase \"toolchain\":\n\t\tif f.Toolchain != nil {\n\t\t\terrorf(\"repeated toolchain statement\")\n\t\t\treturn\n\t\t}\n\t\tif len(args) != 1 {\n\t\t\terrorf(\"toolchain directive expects exactly one argument\")\n\t\t\treturn\n\t\t} else if !ToolchainRE.MatchString(args[0]) {\n\t\t\terrorf(\"invalid toolchain version '%s': must match format go1.23.0 or default\", args[0])\n\t\t\treturn\n\t\t}\n\t\tf.Toolchain = &Toolchain{Syntax: line}\n\t\tf.Toolchain.Name = args[0]\n\n\tcase \"module\":\n\t\tif f.Module != nil {\n\t\t\terrorf(\"repeated module statement\")\n\t\t\treturn\n\t\t}\n\t\tdeprecated := parseDeprecation(block, line)\n\t\tf.Module = &Module{\n\t\t\tSyntax:     line,\n\t\t\tDeprecated: deprecated,\n\t\t}\n\t\tif len(args) != 1 {\n\t\t\terrorf(\"usage: module module/path\")\n\t\t\treturn\n\t\t}\n\t\ts, err := parseString(&args[0])\n\t\tif err != nil {\n\t\t\terrorf(\"invalid quoted string: %v\", err)\n\t\t\treturn\n\t\t}\n\t\tf.Module.Mod = module.Version{Path: s}\n\n\tcase \"godebug\":\n\t\tif len(args) != 1 || strings.ContainsAny(args[0], \"\\\"`',\") {\n\t\t\terrorf(\"usage: godebug key=value\")\n\t\t\treturn\n\t\t}\n\t\tkey, value, ok := strings.Cut(args[0], \"=\")\n\t\tif !ok {\n\t\t\terrorf(\"usage: godebug key=value\")\n\t\t\treturn\n\t\t}\n\t\tf.Godebug = append(f.Godebug, &Godebug{\n\t\t\tKey:    key,\n\t\t\tValue:  value,\n\t\t\tSyntax: line,\n\t\t})\n\n\tcase \"require\", \"exclude\":\n\t\tif len(args) != 2 {\n\t\t\terrorf(\"usage: %s module/path v1.2.3\", verb)\n\t\t\treturn\n\t\t}\n\t\ts, err := parseString(&args[0])\n\t\tif err != nil {\n\t\t\terrorf(\"invalid quoted string: %v\", err)\n\t\t\treturn\n\t\t}\n\t\tv, err := parseVersion(verb, s, &args[1], fix)\n\t\tif err != nil {\n\t\t\twrapError(err)\n\t\t\treturn\n\t\t}\n\t\tpathMajor, err := modulePathMajor(s)\n\t\tif err != nil {\n\t\t\twrapError(err)\n\t\t\treturn\n\t\t}\n\t\tif err := module.CheckPathMajor(v, pathMajor); err != nil {\n\t\t\twrapModPathError(s, err)\n\t\t\treturn\n\t\t}\n\t\tif verb == \"require\" {\n\t\t\tf.Require = append(f.Require, &Require{\n\t\t\t\tMod:      module.Version{Path: s, Version: v},\n\t\t\t\tSyntax:   line,\n\t\t\t\tIndirect: isIndirect(line),\n\t\t\t})\n\t\t} else {\n\t\t\tf.Exclude = append(f.Exclude, &Exclude{\n\t\t\t\tMod:    module.Version{Path: s, Version: v},\n\t\t\t\tSyntax: line,\n\t\t\t})\n\t\t}\n\n\tcase \"replace\":\n\t\treplace, wrappederr := parseReplace(f.Syntax.Name, line, verb, args, fix)\n\t\tif wrappederr != nil {\n\t\t\t*errs = append(*errs, *wrappederr)\n\t\t\treturn\n\t\t}\n\t\tf.Replace = append(f.Replace, replace)\n\n\tcase \"retract\":\n\t\trationale := parseDirectiveComment(block, line)\n\t\tvi, err := parseVersionInterval(verb, \"\", &args, dontFixRetract)\n\t\tif err != nil {\n\t\t\tif strict {\n\t\t\t\twrapError(err)\n\t\t\t\treturn\n\t\t\t} else {\n\t\t\t\t// Only report errors parsing intervals in the main module. We may\n\t\t\t\t// support additional syntax in the future, such as open and half-open\n\t\t\t\t// intervals. Those can't be supported now, because they break the\n\t\t\t\t// go.mod parser, even in lax mode.\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tif len(args) > 0 && strict {\n\t\t\t// In the future, there may be additional information after the version.\n\t\t\terrorf(\"unexpected token after version: %q\", args[0])\n\t\t\treturn\n\t\t}\n\t\tretract := &Retract{\n\t\t\tVersionInterval: vi,\n\t\t\tRationale:       rationale,\n\t\t\tSyntax:          line,\n\t\t}\n\t\tf.Retract = append(f.Retract, retract)\n\n\tcase \"tool\":\n\t\tif len(args) != 1 {\n\t\t\terrorf(\"tool directive expects exactly one argument\")\n\t\t\treturn\n\t\t}\n\t\ts, err := parseString(&args[0])\n\t\tif err != nil {\n\t\t\terrorf(\"invalid quoted string: %v\", err)\n\t\t\treturn\n\t\t}\n\t\tf.Tool = append(f.Tool, &Tool{\n\t\t\tPath:   s,\n\t\t\tSyntax: line,\n\t\t})\n\t}\n}\n\nfunc parseReplace(filename string, line *Line, verb string, args []string, fix VersionFixer) (*Replace, *Error) {\n\twrapModPathError := func(modPath string, err error) *Error {\n\t\treturn &Error{\n\t\t\tFilename: filename,\n\t\t\tPos:      line.Start,\n\t\t\tModPath:  modPath,\n\t\t\tVerb:     verb,\n\t\t\tErr:      err,\n\t\t}\n\t}\n\twrapError := func(err error) *Error {\n\t\treturn &Error{\n\t\t\tFilename: filename,\n\t\t\tPos:      line.Start,\n\t\t\tErr:      err,\n\t\t}\n\t}\n\terrorf := func(format string, args ...interface{}) *Error {\n\t\treturn wrapError(fmt.Errorf(format, args...))\n\t}\n\n\tarrow := 2\n\tif len(args) >= 2 && args[1] == \"=>\" {\n\t\tarrow = 1\n\t}\n\tif len(args) < arrow+2 || len(args) > arrow+3 || args[arrow] != \"=>\" {\n\t\treturn nil, errorf(\"usage: %s module/path [v1.2.3] => other/module v1.4\\n\\t or %s module/path [v1.2.3] => ../local/directory\", verb, verb)\n\t}\n\ts, err := parseString(&args[0])\n\tif err != nil {\n\t\treturn nil, errorf(\"invalid quoted string: %v\", err)\n\t}\n\tpathMajor, err := modulePathMajor(s)\n\tif err != nil {\n\t\treturn nil, wrapModPathError(s, err)\n\n\t}\n\tvar v string\n\tif arrow == 2 {\n\t\tv, err = parseVersion(verb, s, &args[1], fix)\n\t\tif err != nil {\n\t\t\treturn nil, wrapError(err)\n\t\t}\n\t\tif err := module.CheckPathMajor(v, pathMajor); err != nil {\n\t\t\treturn nil, wrapModPathError(s, err)\n\t\t}\n\t}\n\tns, err := parseString(&args[arrow+1])\n\tif err != nil {\n\t\treturn nil, errorf(\"invalid quoted string: %v\", err)\n\t}\n\tnv := \"\"\n\tif len(args) == arrow+2 {\n\t\tif !IsDirectoryPath(ns) {\n\t\t\tif strings.Contains(ns, \"@\") {\n\t\t\t\treturn nil, errorf(\"replacement module must match format 'path version', not 'path@version'\")\n\t\t\t}\n\t\t\treturn nil, errorf(\"replacement module without version must be directory path (rooted or starting with . or ..)\")\n\t\t}\n\t\tif filepath.Separator == '/' && strings.Contains(ns, `\\`) {\n\t\t\treturn nil, errorf(\"replacement directory appears to be Windows path (on a non-windows system)\")\n\t\t}\n\t}\n\tif len(args) == arrow+3 {\n\t\tnv, err = parseVersion(verb, ns, &args[arrow+2], fix)\n\t\tif err != nil {\n\t\t\treturn nil, wrapError(err)\n\t\t}\n\t\tif IsDirectoryPath(ns) {\n\t\t\treturn nil, errorf(\"replacement module directory path %q cannot have version\", ns)\n\t\t}\n\t}\n\treturn &Replace{\n\t\tOld:    module.Version{Path: s, Version: v},\n\t\tNew:    module.Version{Path: ns, Version: nv},\n\t\tSyntax: line,\n\t}, nil\n}\n\n// fixRetract applies fix to each retract directive in f, appending any errors\n// to errs.\n//\n// Most versions are fixed as we parse the file, but for retract directives,\n// the relevant module path is the one specified with the module directive,\n// and that might appear at the end of the file (or not at all).\nfunc (f *File) fixRetract(fix VersionFixer, errs *ErrorList) {\n\tif fix == nil {\n\t\treturn\n\t}\n\tpath := \"\"\n\tif f.Module != nil {\n\t\tpath = f.Module.Mod.Path\n\t}\n\tvar r *Retract\n\twrapError := func(err error) {\n\t\t*errs = append(*errs, Error{\n\t\t\tFilename: f.Syntax.Name,\n\t\t\tPos:      r.Syntax.Start,\n\t\t\tErr:      err,\n\t\t})\n\t}\n\n\tfor _, r = range f.Retract {\n\t\tif path == \"\" {\n\t\t\twrapError(errors.New(\"no module directive found, so retract cannot be used\"))\n\t\t\treturn // only print the first one of these\n\t\t}\n\n\t\targs := r.Syntax.Token\n\t\tif args[0] == \"retract\" {\n\t\t\targs = args[1:]\n\t\t}\n\t\tvi, err := parseVersionInterval(\"retract\", path, &args, fix)\n\t\tif err != nil {\n\t\t\twrapError(err)\n\t\t}\n\t\tr.VersionInterval = vi\n\t}\n}\n\nfunc (f *WorkFile) add(errs *ErrorList, line *Line, verb string, args []string, fix VersionFixer) {\n\twrapError := func(err error) {\n\t\t*errs = append(*errs, Error{\n\t\t\tFilename: f.Syntax.Name,\n\t\t\tPos:      line.Start,\n\t\t\tErr:      err,\n\t\t})\n\t}\n\terrorf := func(format string, args ...interface{}) {\n\t\twrapError(fmt.Errorf(format, args...))\n\t}\n\n\tswitch verb {\n\tdefault:\n\t\terrorf(\"unknown directive: %s\", verb)\n\n\tcase \"go\":\n\t\tif f.Go != nil {\n\t\t\terrorf(\"repeated go statement\")\n\t\t\treturn\n\t\t}\n\t\tif len(args) != 1 {\n\t\t\terrorf(\"go directive expects exactly one argument\")\n\t\t\treturn\n\t\t} else if !GoVersionRE.MatchString(args[0]) {\n\t\t\terrorf(\"invalid go version '%s': must match format 1.23.0\", args[0])\n\t\t\treturn\n\t\t}\n\n\t\tf.Go = &Go{Syntax: line}\n\t\tf.Go.Version = args[0]\n\n\tcase \"toolchain\":\n\t\tif f.Toolchain != nil {\n\t\t\terrorf(\"repeated toolchain statement\")\n\t\t\treturn\n\t\t}\n\t\tif len(args) != 1 {\n\t\t\terrorf(\"toolchain directive expects exactly one argument\")\n\t\t\treturn\n\t\t} else if !ToolchainRE.MatchString(args[0]) {\n\t\t\terrorf(\"invalid toolchain version '%s': must match format go1.23.0 or default\", args[0])\n\t\t\treturn\n\t\t}\n\n\t\tf.Toolchain = &Toolchain{Syntax: line}\n\t\tf.Toolchain.Name = args[0]\n\n\tcase \"godebug\":\n\t\tif len(args) != 1 || strings.ContainsAny(args[0], \"\\\"`',\") {\n\t\t\terrorf(\"usage: godebug key=value\")\n\t\t\treturn\n\t\t}\n\t\tkey, value, ok := strings.Cut(args[0], \"=\")\n\t\tif !ok {\n\t\t\terrorf(\"usage: godebug key=value\")\n\t\t\treturn\n\t\t}\n\t\tf.Godebug = append(f.Godebug, &Godebug{\n\t\t\tKey:    key,\n\t\t\tValue:  value,\n\t\t\tSyntax: line,\n\t\t})\n\n\tcase \"use\":\n\t\tif len(args) != 1 {\n\t\t\terrorf(\"usage: %s local/dir\", verb)\n\t\t\treturn\n\t\t}\n\t\ts, err := parseString(&args[0])\n\t\tif err != nil {\n\t\t\terrorf(\"invalid quoted string: %v\", err)\n\t\t\treturn\n\t\t}\n\t\tf.Use = append(f.Use, &Use{\n\t\t\tPath:   s,\n\t\t\tSyntax: line,\n\t\t})\n\n\tcase \"replace\":\n\t\treplace, wrappederr := parseReplace(f.Syntax.Name, line, verb, args, fix)\n\t\tif wrappederr != nil {\n\t\t\t*errs = append(*errs, *wrappederr)\n\t\t\treturn\n\t\t}\n\t\tf.Replace = append(f.Replace, replace)\n\t}\n}\n\n// IsDirectoryPath reports whether the given path should be interpreted as a directory path.\n// Just like on the go command line, relative paths starting with a '.' or '..' path component\n// and rooted paths are directory paths; the rest are module paths.\nfunc IsDirectoryPath(ns string) bool {\n\t// Because go.mod files can move from one system to another,\n\t// we check all known path syntaxes, both Unix and Windows.\n\treturn ns == \".\" || strings.HasPrefix(ns, \"./\") || strings.HasPrefix(ns, `.\\`) ||\n\t\tns == \"..\" || strings.HasPrefix(ns, \"../\") || strings.HasPrefix(ns, `..\\`) ||\n\t\tstrings.HasPrefix(ns, \"/\") || strings.HasPrefix(ns, `\\`) ||\n\t\tlen(ns) >= 2 && ('A' <= ns[0] && ns[0] <= 'Z' || 'a' <= ns[0] && ns[0] <= 'z') && ns[1] == ':'\n}\n\n// MustQuote reports whether s must be quoted in order to appear as\n// a single token in a go.mod line.\nfunc MustQuote(s string) bool {\n\tfor _, r := range s {\n\t\tswitch r {\n\t\tcase ' ', '\"', '\\'', '`':\n\t\t\treturn true\n\n\t\tcase '(', ')', '[', ']', '{', '}', ',':\n\t\t\tif len(s) > 1 {\n\t\t\t\treturn true\n\t\t\t}\n\n\t\tdefault:\n\t\t\tif !unicode.IsPrint(r) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn s == \"\" || strings.Contains(s, \"//\") || strings.Contains(s, \"/*\")\n}\n\n// AutoQuote returns s or, if quoting is required for s to appear in a go.mod,\n// the quotation of s.\nfunc AutoQuote(s string) string {\n\tif MustQuote(s) {\n\t\treturn strconv.Quote(s)\n\t}\n\treturn s\n}\n\nfunc parseVersionInterval(verb string, path string, args *[]string, fix VersionFixer) (VersionInterval, error) {\n\ttoks := *args\n\tif len(toks) == 0 || toks[0] == \"(\" {\n\t\treturn VersionInterval{}, fmt.Errorf(\"expected '[' or version\")\n\t}\n\tif toks[0] != \"[\" {\n\t\tv, err := parseVersion(verb, path, &toks[0], fix)\n\t\tif err != nil {\n\t\t\treturn VersionInterval{}, err\n\t\t}\n\t\t*args = toks[1:]\n\t\treturn VersionInterval{Low: v, High: v}, nil\n\t}\n\ttoks = toks[1:]\n\n\tif len(toks) == 0 {\n\t\treturn VersionInterval{}, fmt.Errorf(\"expected version after '['\")\n\t}\n\tlow, err := parseVersion(verb, path, &toks[0], fix)\n\tif err != nil {\n\t\treturn VersionInterval{}, err\n\t}\n\ttoks = toks[1:]\n\n\tif len(toks) == 0 || toks[0] != \",\" {\n\t\treturn VersionInterval{}, fmt.Errorf(\"expected ',' after version\")\n\t}\n\ttoks = toks[1:]\n\n\tif len(toks) == 0 {\n\t\treturn VersionInterval{}, fmt.Errorf(\"expected version after ','\")\n\t}\n\thigh, err := parseVersion(verb, path, &toks[0], fix)\n\tif err != nil {\n\t\treturn VersionInterval{}, err\n\t}\n\ttoks = toks[1:]\n\n\tif len(toks) == 0 || toks[0] != \"]\" {\n\t\treturn VersionInterval{}, fmt.Errorf(\"expected ']' after version\")\n\t}\n\ttoks = toks[1:]\n\n\t*args = toks\n\treturn VersionInterval{Low: low, High: high}, nil\n}\n\nfunc parseString(s *string) (string, error) {\n\tt := *s\n\tif strings.HasPrefix(t, `\"`) {\n\t\tvar err error\n\t\tif t, err = strconv.Unquote(t); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t} else if strings.ContainsAny(t, \"\\\"'`\") {\n\t\t// Other quotes are reserved both for possible future expansion\n\t\t// and to avoid confusion. For example if someone types 'x'\n\t\t// we want that to be a syntax error and not a literal x in literal quotation marks.\n\t\treturn \"\", fmt.Errorf(\"unquoted string cannot contain quote\")\n\t}\n\t*s = AutoQuote(t)\n\treturn t, nil\n}\n\nvar deprecatedRE = lazyregexp.New(`(?s)(?:^|\\n\\n)Deprecated: *(.*?)(?:$|\\n\\n)`)\n\n// parseDeprecation extracts the text of comments on a \"module\" directive and\n// extracts a deprecation message from that.\n//\n// A deprecation message is contained in a paragraph within a block of comments\n// that starts with \"Deprecated:\" (case sensitive). The message runs until the\n// end of the paragraph and does not include the \"Deprecated:\" prefix. If the\n// comment block has multiple paragraphs that start with \"Deprecated:\",\n// parseDeprecation returns the message from the first.\nfunc parseDeprecation(block *LineBlock, line *Line) string {\n\ttext := parseDirectiveComment(block, line)\n\tm := deprecatedRE.FindStringSubmatch(text)\n\tif m == nil {\n\t\treturn \"\"\n\t}\n\treturn m[1]\n}\n\n// parseDirectiveComment extracts the text of comments on a directive.\n// If the directive's line does not have comments and is part of a block that\n// does have comments, the block's comments are used.\nfunc parseDirectiveComment(block *LineBlock, line *Line) string {\n\tcomments := line.Comment()\n\tif block != nil && len(comments.Before) == 0 && len(comments.Suffix) == 0 {\n\t\tcomments = block.Comment()\n\t}\n\tgroups := [][]Comment{comments.Before, comments.Suffix}\n\tvar lines []string\n\tfor _, g := range groups {\n\t\tfor _, c := range g {\n\t\t\tif !strings.HasPrefix(c.Token, \"//\") {\n\t\t\t\tcontinue // blank line\n\t\t\t}\n\t\t\tlines = append(lines, strings.TrimSpace(strings.TrimPrefix(c.Token, \"//\")))\n\t\t}\n\t}\n\treturn strings.Join(lines, \"\\n\")\n}\n\ntype ErrorList []Error\n\nfunc (e ErrorList) Error() string {\n\terrStrs := make([]string, len(e))\n\tfor i, err := range e {\n\t\terrStrs[i] = err.Error()\n\t}\n\treturn strings.Join(errStrs, \"\\n\")\n}\n\ntype Error struct {\n\tFilename string\n\tPos      Position\n\tVerb     string\n\tModPath  string\n\tErr      error\n}\n\nfunc (e *Error) Error() string {\n\tvar pos string\n\tif e.Pos.LineRune > 1 {\n\t\t// Don't print LineRune if it's 1 (beginning of line).\n\t\t// It's always 1 except in scanner errors, which are rare.\n\t\tpos = fmt.Sprintf(\"%s:%d:%d: \", e.Filename, e.Pos.Line, e.Pos.LineRune)\n\t} else if e.Pos.Line > 0 {\n\t\tpos = fmt.Sprintf(\"%s:%d: \", e.Filename, e.Pos.Line)\n\t} else if e.Filename != \"\" {\n\t\tpos = fmt.Sprintf(\"%s: \", e.Filename)\n\t}\n\n\tvar directive string\n\tif e.ModPath != \"\" {\n\t\tdirective = fmt.Sprintf(\"%s %s: \", e.Verb, e.ModPath)\n\t} else if e.Verb != \"\" {\n\t\tdirective = fmt.Sprintf(\"%s: \", e.Verb)\n\t}\n\n\treturn pos + directive + e.Err.Error()\n}\n\nfunc (e *Error) Unwrap() error { return e.Err }\n\nfunc parseVersion(verb string, path string, s *string, fix VersionFixer) (string, error) {\n\tt, err := parseString(s)\n\tif err != nil {\n\t\treturn \"\", &Error{\n\t\t\tVerb:    verb,\n\t\t\tModPath: path,\n\t\t\tErr: &module.InvalidVersionError{\n\t\t\t\tVersion: *s,\n\t\t\t\tErr:     err,\n\t\t\t},\n\t\t}\n\t}\n\tif fix != nil {\n\t\tfixed, err := fix(path, t)\n\t\tif err != nil {\n\t\t\tif err, ok := err.(*module.ModuleError); ok {\n\t\t\t\treturn \"\", &Error{\n\t\t\t\t\tVerb:    verb,\n\t\t\t\t\tModPath: path,\n\t\t\t\t\tErr:     err.Err,\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn \"\", err\n\t\t}\n\t\tt = fixed\n\t} else {\n\t\tcv := module.CanonicalVersion(t)\n\t\tif cv == \"\" {\n\t\t\treturn \"\", &Error{\n\t\t\t\tVerb:    verb,\n\t\t\t\tModPath: path,\n\t\t\t\tErr: &module.InvalidVersionError{\n\t\t\t\t\tVersion: t,\n\t\t\t\t\tErr:     errors.New(\"must be of the form v1.2.3\"),\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t\tt = cv\n\t}\n\t*s = t\n\treturn *s, nil\n}\n\nfunc modulePathMajor(path string) (string, error) {\n\t_, major, ok := module.SplitPathVersion(path)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"invalid module path\")\n\t}\n\treturn major, nil\n}\n\nfunc (f *File) Format() ([]byte, error) {\n\treturn Format(f.Syntax), nil\n}\n\n// Cleanup cleans up the file f after any edit operations.\n// To avoid quadratic behavior, modifications like [File.DropRequire]\n// clear the entry but do not remove it from the slice.\n// Cleanup cleans out all the cleared entries.\nfunc (f *File) Cleanup() {\n\tw := 0\n\tfor _, g := range f.Godebug {\n\t\tif g.Key != \"\" {\n\t\t\tf.Godebug[w] = g\n\t\t\tw++\n\t\t}\n\t}\n\tf.Godebug = f.Godebug[:w]\n\n\tw = 0\n\tfor _, r := range f.Require {\n\t\tif r.Mod.Path != \"\" {\n\t\t\tf.Require[w] = r\n\t\t\tw++\n\t\t}\n\t}\n\tf.Require = f.Require[:w]\n\n\tw = 0\n\tfor _, x := range f.Exclude {\n\t\tif x.Mod.Path != \"\" {\n\t\t\tf.Exclude[w] = x\n\t\t\tw++\n\t\t}\n\t}\n\tf.Exclude = f.Exclude[:w]\n\n\tw = 0\n\tfor _, r := range f.Replace {\n\t\tif r.Old.Path != \"\" {\n\t\t\tf.Replace[w] = r\n\t\t\tw++\n\t\t}\n\t}\n\tf.Replace = f.Replace[:w]\n\n\tw = 0\n\tfor _, r := range f.Retract {\n\t\tif r.Low != \"\" || r.High != \"\" {\n\t\t\tf.Retract[w] = r\n\t\t\tw++\n\t\t}\n\t}\n\tf.Retract = f.Retract[:w]\n\n\tf.Syntax.Cleanup()\n}\n\nfunc (f *File) AddGoStmt(version string) error {\n\tif !GoVersionRE.MatchString(version) {\n\t\treturn fmt.Errorf(\"invalid language version %q\", version)\n\t}\n\tif f.Go == nil {\n\t\tvar hint Expr\n\t\tif f.Module != nil && f.Module.Syntax != nil {\n\t\t\thint = f.Module.Syntax\n\t\t} else if f.Syntax == nil {\n\t\t\tf.Syntax = new(FileSyntax)\n\t\t}\n\t\tf.Go = &Go{\n\t\t\tVersion: version,\n\t\t\tSyntax:  f.Syntax.addLine(hint, \"go\", version),\n\t\t}\n\t} else {\n\t\tf.Go.Version = version\n\t\tf.Syntax.updateLine(f.Go.Syntax, \"go\", version)\n\t}\n\treturn nil\n}\n\n// DropGoStmt deletes the go statement from the file.\nfunc (f *File) DropGoStmt() {\n\tif f.Go != nil {\n\t\tf.Go.Syntax.markRemoved()\n\t\tf.Go = nil\n\t}\n}\n\n// DropToolchainStmt deletes the toolchain statement from the file.\nfunc (f *File) DropToolchainStmt() {\n\tif f.Toolchain != nil {\n\t\tf.Toolchain.Syntax.markRemoved()\n\t\tf.Toolchain = nil\n\t}\n}\n\nfunc (f *File) AddToolchainStmt(name string) error {\n\tif !ToolchainRE.MatchString(name) {\n\t\treturn fmt.Errorf(\"invalid toolchain name %q\", name)\n\t}\n\tif f.Toolchain == nil {\n\t\tvar hint Expr\n\t\tif f.Go != nil && f.Go.Syntax != nil {\n\t\t\thint = f.Go.Syntax\n\t\t} else if f.Module != nil && f.Module.Syntax != nil {\n\t\t\thint = f.Module.Syntax\n\t\t}\n\t\tf.Toolchain = &Toolchain{\n\t\t\tName:   name,\n\t\t\tSyntax: f.Syntax.addLine(hint, \"toolchain\", name),\n\t\t}\n\t} else {\n\t\tf.Toolchain.Name = name\n\t\tf.Syntax.updateLine(f.Toolchain.Syntax, \"toolchain\", name)\n\t}\n\treturn nil\n}\n\n// AddGodebug sets the first godebug line for key to value,\n// preserving any existing comments for that line and removing all\n// other godebug lines for key.\n//\n// If no line currently exists for key, AddGodebug adds a new line\n// at the end of the last godebug block.\nfunc (f *File) AddGodebug(key, value string) error {\n\tneed := true\n\tfor _, g := range f.Godebug {\n\t\tif g.Key == key {\n\t\t\tif need {\n\t\t\t\tg.Value = value\n\t\t\t\tf.Syntax.updateLine(g.Syntax, \"godebug\", key+\"=\"+value)\n\t\t\t\tneed = false\n\t\t\t} else {\n\t\t\t\tg.Syntax.markRemoved()\n\t\t\t\t*g = Godebug{}\n\t\t\t}\n\t\t}\n\t}\n\n\tif need {\n\t\tf.addNewGodebug(key, value)\n\t}\n\treturn nil\n}\n\n// addNewGodebug adds a new godebug key=value line at the end\n// of the last godebug block, regardless of any existing godebug lines for key.\nfunc (f *File) addNewGodebug(key, value string) {\n\tline := f.Syntax.addLine(nil, \"godebug\", key+\"=\"+value)\n\tg := &Godebug{\n\t\tKey:    key,\n\t\tValue:  value,\n\t\tSyntax: line,\n\t}\n\tf.Godebug = append(f.Godebug, g)\n}\n\n// AddRequire sets the first require line for path to version vers,\n// preserving any existing comments for that line and removing all\n// other lines for path.\n//\n// If no line currently exists for path, AddRequire adds a new line\n// at the end of the last require block.\nfunc (f *File) AddRequire(path, vers string) error {\n\tneed := true\n\tfor _, r := range f.Require {\n\t\tif r.Mod.Path == path {\n\t\t\tif need {\n\t\t\t\tr.Mod.Version = vers\n\t\t\t\tf.Syntax.updateLine(r.Syntax, \"require\", AutoQuote(path), vers)\n\t\t\t\tneed = false\n\t\t\t} else {\n\t\t\t\tr.Syntax.markRemoved()\n\t\t\t\t*r = Require{}\n\t\t\t}\n\t\t}\n\t}\n\n\tif need {\n\t\tf.AddNewRequire(path, vers, false)\n\t}\n\treturn nil\n}\n\n// AddNewRequire adds a new require line for path at version vers at the end of\n// the last require block, regardless of any existing require lines for path.\nfunc (f *File) AddNewRequire(path, vers string, indirect bool) {\n\tline := f.Syntax.addLine(nil, \"require\", AutoQuote(path), vers)\n\tr := &Require{\n\t\tMod:    module.Version{Path: path, Version: vers},\n\t\tSyntax: line,\n\t}\n\tr.setIndirect(indirect)\n\tf.Require = append(f.Require, r)\n}\n\n// SetRequire updates the requirements of f to contain exactly req, preserving\n// the existing block structure and line comment contents (except for 'indirect'\n// markings) for the first requirement on each named module path.\n//\n// The Syntax field is ignored for the requirements in req.\n//\n// Any requirements not already present in the file are added to the block\n// containing the last require line.\n//\n// The requirements in req must specify at most one distinct version for each\n// module path.\n//\n// If any existing requirements may be removed, the caller should call\n// [File.Cleanup] after all edits are complete.\nfunc (f *File) SetRequire(req []*Require) {\n\ttype elem struct {\n\t\tversion  string\n\t\tindirect bool\n\t}\n\tneed := make(map[string]elem)\n\tfor _, r := range req {\n\t\tif prev, dup := need[r.Mod.Path]; dup && prev.version != r.Mod.Version {\n\t\t\tpanic(fmt.Errorf(\"SetRequire called with conflicting versions for path %s (%s and %s)\", r.Mod.Path, prev.version, r.Mod.Version))\n\t\t}\n\t\tneed[r.Mod.Path] = elem{r.Mod.Version, r.Indirect}\n\t}\n\n\t// Update or delete the existing Require entries to preserve\n\t// only the first for each module path in req.\n\tfor _, r := range f.Require {\n\t\te, ok := need[r.Mod.Path]\n\t\tif ok {\n\t\t\tr.setVersion(e.version)\n\t\t\tr.setIndirect(e.indirect)\n\t\t} else {\n\t\t\tr.markRemoved()\n\t\t}\n\t\tdelete(need, r.Mod.Path)\n\t}\n\n\t// Add new entries in the last block of the file for any paths that weren't\n\t// already present.\n\t//\n\t// This step is nondeterministic, but the final result will be deterministic\n\t// because we will sort the block.\n\tfor path, e := range need {\n\t\tf.AddNewRequire(path, e.version, e.indirect)\n\t}\n\n\tf.SortBlocks()\n}\n\n// SetRequireSeparateIndirect updates the requirements of f to contain the given\n// requirements. Comment contents (except for 'indirect' markings) are retained\n// from the first existing requirement for each module path. Like SetRequire,\n// SetRequireSeparateIndirect adds requirements for new paths in req,\n// updates the version and \"// indirect\" comment on existing requirements,\n// and deletes requirements on paths not in req. Existing duplicate requirements\n// are deleted.\n//\n// As its name suggests, SetRequireSeparateIndirect puts direct and indirect\n// requirements into two separate blocks, one containing only direct\n// requirements, and the other containing only indirect requirements.\n// SetRequireSeparateIndirect may move requirements between these two blocks\n// when their indirect markings change. However, SetRequireSeparateIndirect\n// won't move requirements from other blocks, especially blocks with comments.\n//\n// If the file initially has one uncommented block of requirements,\n// SetRequireSeparateIndirect will split it into a direct-only and indirect-only\n// block. This aids in the transition to separate blocks.\nfunc (f *File) SetRequireSeparateIndirect(req []*Require) {\n\t// hasComments returns whether a line or block has comments\n\t// other than \"indirect\".\n\thasComments := func(c Comments) bool {\n\t\treturn len(c.Before) > 0 || len(c.After) > 0 || len(c.Suffix) > 1 ||\n\t\t\t(len(c.Suffix) == 1 &&\n\t\t\t\tstrings.TrimSpace(strings.TrimPrefix(c.Suffix[0].Token, string(slashSlash))) != \"indirect\")\n\t}\n\n\t// moveReq adds r to block. If r was in another block, moveReq deletes\n\t// it from that block and transfers its comments.\n\tmoveReq := func(r *Require, block *LineBlock) {\n\t\tvar line *Line\n\t\tif r.Syntax == nil {\n\t\t\tline = &Line{Token: []string{AutoQuote(r.Mod.Path), r.Mod.Version}}\n\t\t\tr.Syntax = line\n\t\t\tif r.Indirect {\n\t\t\t\tr.setIndirect(true)\n\t\t\t}\n\t\t} else {\n\t\t\tline = new(Line)\n\t\t\t*line = *r.Syntax\n\t\t\tif !line.InBlock && len(line.Token) > 0 && line.Token[0] == \"require\" {\n\t\t\t\tline.Token = line.Token[1:]\n\t\t\t}\n\t\t\tr.Syntax.Token = nil // Cleanup will delete the old line.\n\t\t\tr.Syntax = line\n\t\t}\n\t\tline.InBlock = true\n\t\tblock.Line = append(block.Line, line)\n\t}\n\n\t// Examine existing require lines and blocks.\n\tvar (\n\t\t// We may insert new requirements into the last uncommented\n\t\t// direct-only and indirect-only blocks. We may also move requirements\n\t\t// to the opposite block if their indirect markings change.\n\t\tlastDirectIndex   = -1\n\t\tlastIndirectIndex = -1\n\n\t\t// If there are no direct-only or indirect-only blocks, a new block may\n\t\t// be inserted after the last require line or block.\n\t\tlastRequireIndex = -1\n\n\t\t// If there's only one require line or block, and it's uncommented,\n\t\t// we'll move its requirements to the direct-only or indirect-only blocks.\n\t\trequireLineOrBlockCount = 0\n\n\t\t// Track the block each requirement belongs to (if any) so we can\n\t\t// move them later.\n\t\tlineToBlock = make(map[*Line]*LineBlock)\n\t)\n\tfor i, stmt := range f.Syntax.Stmt {\n\t\tswitch stmt := stmt.(type) {\n\t\tcase *Line:\n\t\t\tif len(stmt.Token) == 0 || stmt.Token[0] != \"require\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tlastRequireIndex = i\n\t\t\trequireLineOrBlockCount++\n\t\t\tif !hasComments(stmt.Comments) {\n\t\t\t\tif isIndirect(stmt) {\n\t\t\t\t\tlastIndirectIndex = i\n\t\t\t\t} else {\n\t\t\t\t\tlastDirectIndex = i\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *LineBlock:\n\t\t\tif len(stmt.Token) == 0 || stmt.Token[0] != \"require\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tlastRequireIndex = i\n\t\t\trequireLineOrBlockCount++\n\t\t\tallDirect := len(stmt.Line) > 0 && !hasComments(stmt.Comments)\n\t\t\tallIndirect := len(stmt.Line) > 0 && !hasComments(stmt.Comments)\n\t\t\tfor _, line := range stmt.Line {\n\t\t\t\tlineToBlock[line] = stmt\n\t\t\t\tif hasComments(line.Comments) {\n\t\t\t\t\tallDirect = false\n\t\t\t\t\tallIndirect = false\n\t\t\t\t} else if isIndirect(line) {\n\t\t\t\t\tallDirect = false\n\t\t\t\t} else {\n\t\t\t\t\tallIndirect = false\n\t\t\t\t}\n\t\t\t}\n\t\t\tif allDirect {\n\t\t\t\tlastDirectIndex = i\n\t\t\t}\n\t\t\tif allIndirect {\n\t\t\t\tlastIndirectIndex = i\n\t\t\t}\n\t\t}\n\t}\n\n\toneFlatUncommentedBlock := requireLineOrBlockCount == 1 &&\n\t\t!hasComments(*f.Syntax.Stmt[lastRequireIndex].Comment())\n\n\t// Create direct and indirect blocks if needed. Convert lines into blocks\n\t// if needed. If we end up with an empty block or a one-line block,\n\t// Cleanup will delete it or convert it to a line later.\n\tinsertBlock := func(i int) *LineBlock {\n\t\tblock := &LineBlock{Token: []string{\"require\"}}\n\t\tf.Syntax.Stmt = append(f.Syntax.Stmt, nil)\n\t\tcopy(f.Syntax.Stmt[i+1:], f.Syntax.Stmt[i:])\n\t\tf.Syntax.Stmt[i] = block\n\t\treturn block\n\t}\n\n\tensureBlock := func(i int) *LineBlock {\n\t\tswitch stmt := f.Syntax.Stmt[i].(type) {\n\t\tcase *LineBlock:\n\t\t\treturn stmt\n\t\tcase *Line:\n\t\t\tblock := &LineBlock{\n\t\t\t\tToken: []string{\"require\"},\n\t\t\t\tLine:  []*Line{stmt},\n\t\t\t}\n\t\t\tstmt.Token = stmt.Token[1:] // remove \"require\"\n\t\t\tstmt.InBlock = true\n\t\t\tf.Syntax.Stmt[i] = block\n\t\t\treturn block\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"unexpected statement: %v\", stmt))\n\t\t}\n\t}\n\n\tvar lastDirectBlock *LineBlock\n\tif lastDirectIndex < 0 {\n\t\tif lastIndirectIndex >= 0 {\n\t\t\tlastDirectIndex = lastIndirectIndex\n\t\t\tlastIndirectIndex++\n\t\t} else if lastRequireIndex >= 0 {\n\t\t\tlastDirectIndex = lastRequireIndex + 1\n\t\t} else {\n\t\t\tlastDirectIndex = len(f.Syntax.Stmt)\n\t\t}\n\t\tlastDirectBlock = insertBlock(lastDirectIndex)\n\t} else {\n\t\tlastDirectBlock = ensureBlock(lastDirectIndex)\n\t}\n\n\tvar lastIndirectBlock *LineBlock\n\tif lastIndirectIndex < 0 {\n\t\tlastIndirectIndex = lastDirectIndex + 1\n\t\tlastIndirectBlock = insertBlock(lastIndirectIndex)\n\t} else {\n\t\tlastIndirectBlock = ensureBlock(lastIndirectIndex)\n\t}\n\n\t// Delete requirements we don't want anymore.\n\t// Update versions and indirect comments on requirements we want to keep.\n\t// If a requirement is in last{Direct,Indirect}Block with the wrong\n\t// indirect marking after this, or if the requirement is in an single\n\t// uncommented mixed block (oneFlatUncommentedBlock), move it to the\n\t// correct block.\n\t//\n\t// Some blocks may be empty after this. Cleanup will remove them.\n\tneed := make(map[string]*Require)\n\tfor _, r := range req {\n\t\tneed[r.Mod.Path] = r\n\t}\n\thave := make(map[string]*Require)\n\tfor _, r := range f.Require {\n\t\tpath := r.Mod.Path\n\t\tif need[path] == nil || have[path] != nil {\n\t\t\t// Requirement not needed, or duplicate requirement. Delete.\n\t\t\tr.markRemoved()\n\t\t\tcontinue\n\t\t}\n\t\thave[r.Mod.Path] = r\n\t\tr.setVersion(need[path].Mod.Version)\n\t\tr.setIndirect(need[path].Indirect)\n\t\tif need[path].Indirect &&\n\t\t\t(oneFlatUncommentedBlock || lineToBlock[r.Syntax] == lastDirectBlock) {\n\t\t\tmoveReq(r, lastIndirectBlock)\n\t\t} else if !need[path].Indirect &&\n\t\t\t(oneFlatUncommentedBlock || lineToBlock[r.Syntax] == lastIndirectBlock) {\n\t\t\tmoveReq(r, lastDirectBlock)\n\t\t}\n\t}\n\n\t// Add new requirements.\n\tfor path, r := range need {\n\t\tif have[path] == nil {\n\t\t\tif r.Indirect {\n\t\t\t\tmoveReq(r, lastIndirectBlock)\n\t\t\t} else {\n\t\t\t\tmoveReq(r, lastDirectBlock)\n\t\t\t}\n\t\t\tf.Require = append(f.Require, r)\n\t\t}\n\t}\n\n\tf.SortBlocks()\n}\n\nfunc (f *File) DropGodebug(key string) error {\n\tfor _, g := range f.Godebug {\n\t\tif g.Key == key {\n\t\t\tg.Syntax.markRemoved()\n\t\t\t*g = Godebug{}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (f *File) DropRequire(path string) error {\n\tfor _, r := range f.Require {\n\t\tif r.Mod.Path == path {\n\t\t\tr.Syntax.markRemoved()\n\t\t\t*r = Require{}\n\t\t}\n\t}\n\treturn nil\n}\n\n// AddExclude adds a exclude statement to the mod file. Errors if the provided\n// version is not a canonical version string\nfunc (f *File) AddExclude(path, vers string) error {\n\tif err := checkCanonicalVersion(path, vers); err != nil {\n\t\treturn err\n\t}\n\n\tvar hint *Line\n\tfor _, x := range f.Exclude {\n\t\tif x.Mod.Path == path && x.Mod.Version == vers {\n\t\t\treturn nil\n\t\t}\n\t\tif x.Mod.Path == path {\n\t\t\thint = x.Syntax\n\t\t}\n\t}\n\n\tf.Exclude = append(f.Exclude, &Exclude{Mod: module.Version{Path: path, Version: vers}, Syntax: f.Syntax.addLine(hint, \"exclude\", AutoQuote(path), vers)})\n\treturn nil\n}\n\nfunc (f *File) DropExclude(path, vers string) error {\n\tfor _, x := range f.Exclude {\n\t\tif x.Mod.Path == path && x.Mod.Version == vers {\n\t\t\tx.Syntax.markRemoved()\n\t\t\t*x = Exclude{}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (f *File) AddReplace(oldPath, oldVers, newPath, newVers string) error {\n\treturn addReplace(f.Syntax, &f.Replace, oldPath, oldVers, newPath, newVers)\n}\n\nfunc addReplace(syntax *FileSyntax, replace *[]*Replace, oldPath, oldVers, newPath, newVers string) error {\n\tneed := true\n\told := module.Version{Path: oldPath, Version: oldVers}\n\tnew := module.Version{Path: newPath, Version: newVers}\n\ttokens := []string{\"replace\", AutoQuote(oldPath)}\n\tif oldVers != \"\" {\n\t\ttokens = append(tokens, oldVers)\n\t}\n\ttokens = append(tokens, \"=>\", AutoQuote(newPath))\n\tif newVers != \"\" {\n\t\ttokens = append(tokens, newVers)\n\t}\n\n\tvar hint *Line\n\tfor _, r := range *replace {\n\t\tif r.Old.Path == oldPath && (oldVers == \"\" || r.Old.Version == oldVers) {\n\t\t\tif need {\n\t\t\t\t// Found replacement for old; update to use new.\n\t\t\t\tr.New = new\n\t\t\t\tsyntax.updateLine(r.Syntax, tokens...)\n\t\t\t\tneed = false\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Already added; delete other replacements for same.\n\t\t\tr.Syntax.markRemoved()\n\t\t\t*r = Replace{}\n\t\t}\n\t\tif r.Old.Path == oldPath {\n\t\t\thint = r.Syntax\n\t\t}\n\t}\n\tif need {\n\t\t*replace = append(*replace, &Replace{Old: old, New: new, Syntax: syntax.addLine(hint, tokens...)})\n\t}\n\treturn nil\n}\n\nfunc (f *File) DropReplace(oldPath, oldVers string) error {\n\tfor _, r := range f.Replace {\n\t\tif r.Old.Path == oldPath && r.Old.Version == oldVers {\n\t\t\tr.Syntax.markRemoved()\n\t\t\t*r = Replace{}\n\t\t}\n\t}\n\treturn nil\n}\n\n// AddRetract adds a retract statement to the mod file. Errors if the provided\n// version interval does not consist of canonical version strings\nfunc (f *File) AddRetract(vi VersionInterval, rationale string) error {\n\tvar path string\n\tif f.Module != nil {\n\t\tpath = f.Module.Mod.Path\n\t}\n\tif err := checkCanonicalVersion(path, vi.High); err != nil {\n\t\treturn err\n\t}\n\tif err := checkCanonicalVersion(path, vi.Low); err != nil {\n\t\treturn err\n\t}\n\n\tr := &Retract{\n\t\tVersionInterval: vi,\n\t}\n\tif vi.Low == vi.High {\n\t\tr.Syntax = f.Syntax.addLine(nil, \"retract\", AutoQuote(vi.Low))\n\t} else {\n\t\tr.Syntax = f.Syntax.addLine(nil, \"retract\", \"[\", AutoQuote(vi.Low), \",\", AutoQuote(vi.High), \"]\")\n\t}\n\tif rationale != \"\" {\n\t\tfor _, line := range strings.Split(rationale, \"\\n\") {\n\t\t\tcom := Comment{Token: \"// \" + line}\n\t\t\tr.Syntax.Comment().Before = append(r.Syntax.Comment().Before, com)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (f *File) DropRetract(vi VersionInterval) error {\n\tfor _, r := range f.Retract {\n\t\tif r.VersionInterval == vi {\n\t\t\tr.Syntax.markRemoved()\n\t\t\t*r = Retract{}\n\t\t}\n\t}\n\treturn nil\n}\n\n// AddTool adds a new tool directive with the given path.\n// It does nothing if the tool line already exists.\nfunc (f *File) AddTool(path string) error {\n\tfor _, t := range f.Tool {\n\t\tif t.Path == path {\n\t\t\treturn nil\n\t\t}\n\t}\n\n\tf.Tool = append(f.Tool, &Tool{\n\t\tPath:   path,\n\t\tSyntax: f.Syntax.addLine(nil, \"tool\", path),\n\t})\n\n\tf.SortBlocks()\n\treturn nil\n}\n\n// RemoveTool removes a tool directive with the given path.\n// It does nothing if no such tool directive exists.\nfunc (f *File) DropTool(path string) error {\n\tfor _, t := range f.Tool {\n\t\tif t.Path == path {\n\t\t\tt.Syntax.markRemoved()\n\t\t\t*t = Tool{}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (f *File) SortBlocks() {\n\tf.removeDups() // otherwise sorting is unsafe\n\n\t// semanticSortForExcludeVersionV is the Go version (plus leading \"v\") at which\n\t// lines in exclude blocks start to use semantic sort instead of lexicographic sort.\n\t// See go.dev/issue/60028.\n\tconst semanticSortForExcludeVersionV = \"v1.21\"\n\tuseSemanticSortForExclude := f.Go != nil && semver.Compare(\"v\"+f.Go.Version, semanticSortForExcludeVersionV) >= 0\n\n\tfor _, stmt := range f.Syntax.Stmt {\n\t\tblock, ok := stmt.(*LineBlock)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tless := lineLess\n\t\tif block.Token[0] == \"exclude\" && useSemanticSortForExclude {\n\t\t\tless = lineExcludeLess\n\t\t} else if block.Token[0] == \"retract\" {\n\t\t\tless = lineRetractLess\n\t\t}\n\t\tsort.SliceStable(block.Line, func(i, j int) bool {\n\t\t\treturn less(block.Line[i], block.Line[j])\n\t\t})\n\t}\n}\n\n// removeDups removes duplicate exclude, replace and tool directives.\n//\n// Earlier exclude and tool directives take priority.\n//\n// Later replace directives take priority.\n//\n// require directives are not de-duplicated. That's left up to higher-level\n// logic (MVS).\n//\n// retract directives are not de-duplicated since comments are\n// meaningful, and versions may be retracted multiple times.\nfunc (f *File) removeDups() {\n\tremoveDups(f.Syntax, &f.Exclude, &f.Replace, &f.Tool)\n}\n\nfunc removeDups(syntax *FileSyntax, exclude *[]*Exclude, replace *[]*Replace, tool *[]*Tool) {\n\tkill := make(map[*Line]bool)\n\n\t// Remove duplicate excludes.\n\tif exclude != nil {\n\t\thaveExclude := make(map[module.Version]bool)\n\t\tfor _, x := range *exclude {\n\t\t\tif haveExclude[x.Mod] {\n\t\t\t\tkill[x.Syntax] = true\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\thaveExclude[x.Mod] = true\n\t\t}\n\t\tvar excl []*Exclude\n\t\tfor _, x := range *exclude {\n\t\t\tif !kill[x.Syntax] {\n\t\t\t\texcl = append(excl, x)\n\t\t\t}\n\t\t}\n\t\t*exclude = excl\n\t}\n\n\t// Remove duplicate replacements.\n\t// Later replacements take priority over earlier ones.\n\thaveReplace := make(map[module.Version]bool)\n\tfor i := len(*replace) - 1; i >= 0; i-- {\n\t\tx := (*replace)[i]\n\t\tif haveReplace[x.Old] {\n\t\t\tkill[x.Syntax] = true\n\t\t\tcontinue\n\t\t}\n\t\thaveReplace[x.Old] = true\n\t}\n\tvar repl []*Replace\n\tfor _, x := range *replace {\n\t\tif !kill[x.Syntax] {\n\t\t\trepl = append(repl, x)\n\t\t}\n\t}\n\t*replace = repl\n\n\tif tool != nil {\n\t\thaveTool := make(map[string]bool)\n\t\tfor _, t := range *tool {\n\t\t\tif haveTool[t.Path] {\n\t\t\t\tkill[t.Syntax] = true\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\thaveTool[t.Path] = true\n\t\t}\n\t\tvar newTool []*Tool\n\t\tfor _, t := range *tool {\n\t\t\tif !kill[t.Syntax] {\n\t\t\t\tnewTool = append(newTool, t)\n\t\t\t}\n\t\t}\n\t\t*tool = newTool\n\t}\n\n\t// Duplicate require and retract directives are not removed.\n\n\t// Drop killed statements from the syntax tree.\n\tvar stmts []Expr\n\tfor _, stmt := range syntax.Stmt {\n\t\tswitch stmt := stmt.(type) {\n\t\tcase *Line:\n\t\t\tif kill[stmt] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\tcase *LineBlock:\n\t\t\tvar lines []*Line\n\t\t\tfor _, line := range stmt.Line {\n\t\t\t\tif !kill[line] {\n\t\t\t\t\tlines = append(lines, line)\n\t\t\t\t}\n\t\t\t}\n\t\t\tstmt.Line = lines\n\t\t\tif len(lines) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tstmts = append(stmts, stmt)\n\t}\n\tsyntax.Stmt = stmts\n}\n\n// lineLess returns whether li should be sorted before lj. It sorts\n// lexicographically without assigning any special meaning to tokens.\nfunc lineLess(li, lj *Line) bool {\n\tfor k := 0; k < len(li.Token) && k < len(lj.Token); k++ {\n\t\tif li.Token[k] != lj.Token[k] {\n\t\t\treturn li.Token[k] < lj.Token[k]\n\t\t}\n\t}\n\treturn len(li.Token) < len(lj.Token)\n}\n\n// lineExcludeLess reports whether li should be sorted before lj for lines in\n// an \"exclude\" block.\nfunc lineExcludeLess(li, lj *Line) bool {\n\tif len(li.Token) != 2 || len(lj.Token) != 2 {\n\t\t// Not a known exclude specification.\n\t\t// Fall back to sorting lexicographically.\n\t\treturn lineLess(li, lj)\n\t}\n\t// An exclude specification has two tokens: ModulePath and Version.\n\t// Compare module path by string order and version by semver rules.\n\tif pi, pj := li.Token[0], lj.Token[0]; pi != pj {\n\t\treturn pi < pj\n\t}\n\treturn semver.Compare(li.Token[1], lj.Token[1]) < 0\n}\n\n// lineRetractLess returns whether li should be sorted before lj for lines in\n// a \"retract\" block. It treats each line as a version interval. Single versions\n// are compared as if they were intervals with the same low and high version.\n// Intervals are sorted in descending order, first by low version, then by\n// high version, using semver.Compare.\nfunc lineRetractLess(li, lj *Line) bool {\n\tinterval := func(l *Line) VersionInterval {\n\t\tif len(l.Token) == 1 {\n\t\t\treturn VersionInterval{Low: l.Token[0], High: l.Token[0]}\n\t\t} else if len(l.Token) == 5 && l.Token[0] == \"[\" && l.Token[2] == \",\" && l.Token[4] == \"]\" {\n\t\t\treturn VersionInterval{Low: l.Token[1], High: l.Token[3]}\n\t\t} else {\n\t\t\t// Line in unknown format. Treat as an invalid version.\n\t\t\treturn VersionInterval{}\n\t\t}\n\t}\n\tvii := interval(li)\n\tvij := interval(lj)\n\tif cmp := semver.Compare(vii.Low, vij.Low); cmp != 0 {\n\t\treturn cmp > 0\n\t}\n\treturn semver.Compare(vii.High, vij.High) > 0\n}\n\n// checkCanonicalVersion returns a non-nil error if vers is not a canonical\n// version string or does not match the major version of path.\n//\n// If path is non-empty, the error text suggests a format with a major version\n// corresponding to the path.\nfunc checkCanonicalVersion(path, vers string) error {\n\t_, pathMajor, pathMajorOk := module.SplitPathVersion(path)\n\n\tif vers == \"\" || vers != module.CanonicalVersion(vers) {\n\t\tif pathMajor == \"\" {\n\t\t\treturn &module.InvalidVersionError{\n\t\t\t\tVersion: vers,\n\t\t\t\tErr:     fmt.Errorf(\"must be of the form v1.2.3\"),\n\t\t\t}\n\t\t}\n\t\treturn &module.InvalidVersionError{\n\t\t\tVersion: vers,\n\t\t\tErr:     fmt.Errorf(\"must be of the form %s.2.3\", module.PathMajorPrefix(pathMajor)),\n\t\t}\n\t}\n\n\tif pathMajorOk {\n\t\tif err := module.CheckPathMajor(vers, pathMajor); err != nil {\n\t\t\tif pathMajor == \"\" {\n\t\t\t\t// In this context, the user probably wrote \"v2.3.4\" when they meant\n\t\t\t\t// \"v2.3.4+incompatible\". Suggest that instead of \"v0 or v1\".\n\t\t\t\treturn &module.InvalidVersionError{\n\t\t\t\t\tVersion: vers,\n\t\t\t\t\tErr:     fmt.Errorf(\"should be %s+incompatible (or module %s/%v)\", vers, path, semver.Major(vers)),\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/mod/modfile/work.go",
    "content": "// Copyright 2021 The Go 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 modfile\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n)\n\n// A WorkFile is the parsed, interpreted form of a go.work file.\ntype WorkFile struct {\n\tGo        *Go\n\tToolchain *Toolchain\n\tGodebug   []*Godebug\n\tUse       []*Use\n\tReplace   []*Replace\n\n\tSyntax *FileSyntax\n}\n\n// A Use is a single directory statement.\ntype Use struct {\n\tPath       string // Use path of module.\n\tModulePath string // Module path in the comment.\n\tSyntax     *Line\n}\n\n// ParseWork parses and returns a go.work file.\n//\n// file is the name of the file, used in positions and errors.\n//\n// data is the content of the file.\n//\n// fix is an optional function that canonicalizes module versions.\n// If fix is nil, all module versions must be canonical ([module.CanonicalVersion]\n// must return the same string).\nfunc ParseWork(file string, data []byte, fix VersionFixer) (*WorkFile, error) {\n\tfs, err := parse(file, data)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tf := &WorkFile{\n\t\tSyntax: fs,\n\t}\n\tvar errs ErrorList\n\n\tfor _, x := range fs.Stmt {\n\t\tswitch x := x.(type) {\n\t\tcase *Line:\n\t\t\tf.add(&errs, x, x.Token[0], x.Token[1:], fix)\n\n\t\tcase *LineBlock:\n\t\t\tif len(x.Token) > 1 {\n\t\t\t\terrs = append(errs, Error{\n\t\t\t\t\tFilename: file,\n\t\t\t\t\tPos:      x.Start,\n\t\t\t\t\tErr:      fmt.Errorf(\"unknown block type: %s\", strings.Join(x.Token, \" \")),\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tswitch x.Token[0] {\n\t\t\tdefault:\n\t\t\t\terrs = append(errs, Error{\n\t\t\t\t\tFilename: file,\n\t\t\t\t\tPos:      x.Start,\n\t\t\t\t\tErr:      fmt.Errorf(\"unknown block type: %s\", strings.Join(x.Token, \" \")),\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\tcase \"godebug\", \"use\", \"replace\":\n\t\t\t\tfor _, l := range x.Line {\n\t\t\t\t\tf.add(&errs, l, x.Token[0], l.Token, fix)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(errs) > 0 {\n\t\treturn nil, errs\n\t}\n\treturn f, nil\n}\n\n// Cleanup cleans up the file f after any edit operations.\n// To avoid quadratic behavior, modifications like [WorkFile.DropRequire]\n// clear the entry but do not remove it from the slice.\n// Cleanup cleans out all the cleared entries.\nfunc (f *WorkFile) Cleanup() {\n\tw := 0\n\tfor _, r := range f.Use {\n\t\tif r.Path != \"\" {\n\t\t\tf.Use[w] = r\n\t\t\tw++\n\t\t}\n\t}\n\tf.Use = f.Use[:w]\n\n\tw = 0\n\tfor _, r := range f.Replace {\n\t\tif r.Old.Path != \"\" {\n\t\t\tf.Replace[w] = r\n\t\t\tw++\n\t\t}\n\t}\n\tf.Replace = f.Replace[:w]\n\n\tf.Syntax.Cleanup()\n}\n\nfunc (f *WorkFile) AddGoStmt(version string) error {\n\tif !GoVersionRE.MatchString(version) {\n\t\treturn fmt.Errorf(\"invalid language version %q\", version)\n\t}\n\tif f.Go == nil {\n\t\tstmt := &Line{Token: []string{\"go\", version}}\n\t\tf.Go = &Go{\n\t\t\tVersion: version,\n\t\t\tSyntax:  stmt,\n\t\t}\n\t\t// Find the first non-comment-only block and add\n\t\t// the go statement before it. That will keep file comments at the top.\n\t\ti := 0\n\t\tfor i = 0; i < len(f.Syntax.Stmt); i++ {\n\t\t\tif _, ok := f.Syntax.Stmt[i].(*CommentBlock); !ok {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tf.Syntax.Stmt = append(append(f.Syntax.Stmt[:i:i], stmt), f.Syntax.Stmt[i:]...)\n\t} else {\n\t\tf.Go.Version = version\n\t\tf.Syntax.updateLine(f.Go.Syntax, \"go\", version)\n\t}\n\treturn nil\n}\n\nfunc (f *WorkFile) AddToolchainStmt(name string) error {\n\tif !ToolchainRE.MatchString(name) {\n\t\treturn fmt.Errorf(\"invalid toolchain name %q\", name)\n\t}\n\tif f.Toolchain == nil {\n\t\tstmt := &Line{Token: []string{\"toolchain\", name}}\n\t\tf.Toolchain = &Toolchain{\n\t\t\tName:   name,\n\t\t\tSyntax: stmt,\n\t\t}\n\t\t// Find the go line and add the toolchain line after it.\n\t\t// Or else find the first non-comment-only block and add\n\t\t// the toolchain line before it. That will keep file comments at the top.\n\t\ti := 0\n\t\tfor i = 0; i < len(f.Syntax.Stmt); i++ {\n\t\t\tif line, ok := f.Syntax.Stmt[i].(*Line); ok && len(line.Token) > 0 && line.Token[0] == \"go\" {\n\t\t\t\ti++\n\t\t\t\tgoto Found\n\t\t\t}\n\t\t}\n\t\tfor i = 0; i < len(f.Syntax.Stmt); i++ {\n\t\t\tif _, ok := f.Syntax.Stmt[i].(*CommentBlock); !ok {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\tFound:\n\t\tf.Syntax.Stmt = append(append(f.Syntax.Stmt[:i:i], stmt), f.Syntax.Stmt[i:]...)\n\t} else {\n\t\tf.Toolchain.Name = name\n\t\tf.Syntax.updateLine(f.Toolchain.Syntax, \"toolchain\", name)\n\t}\n\treturn nil\n}\n\n// DropGoStmt deletes the go statement from the file.\nfunc (f *WorkFile) DropGoStmt() {\n\tif f.Go != nil {\n\t\tf.Go.Syntax.markRemoved()\n\t\tf.Go = nil\n\t}\n}\n\n// DropToolchainStmt deletes the toolchain statement from the file.\nfunc (f *WorkFile) DropToolchainStmt() {\n\tif f.Toolchain != nil {\n\t\tf.Toolchain.Syntax.markRemoved()\n\t\tf.Toolchain = nil\n\t}\n}\n\n// AddGodebug sets the first godebug line for key to value,\n// preserving any existing comments for that line and removing all\n// other godebug lines for key.\n//\n// If no line currently exists for key, AddGodebug adds a new line\n// at the end of the last godebug block.\nfunc (f *WorkFile) AddGodebug(key, value string) error {\n\tneed := true\n\tfor _, g := range f.Godebug {\n\t\tif g.Key == key {\n\t\t\tif need {\n\t\t\t\tg.Value = value\n\t\t\t\tf.Syntax.updateLine(g.Syntax, \"godebug\", key+\"=\"+value)\n\t\t\t\tneed = false\n\t\t\t} else {\n\t\t\t\tg.Syntax.markRemoved()\n\t\t\t\t*g = Godebug{}\n\t\t\t}\n\t\t}\n\t}\n\n\tif need {\n\t\tf.addNewGodebug(key, value)\n\t}\n\treturn nil\n}\n\n// addNewGodebug adds a new godebug key=value line at the end\n// of the last godebug block, regardless of any existing godebug lines for key.\nfunc (f *WorkFile) addNewGodebug(key, value string) {\n\tline := f.Syntax.addLine(nil, \"godebug\", key+\"=\"+value)\n\tg := &Godebug{\n\t\tKey:    key,\n\t\tValue:  value,\n\t\tSyntax: line,\n\t}\n\tf.Godebug = append(f.Godebug, g)\n}\n\nfunc (f *WorkFile) DropGodebug(key string) error {\n\tfor _, g := range f.Godebug {\n\t\tif g.Key == key {\n\t\t\tg.Syntax.markRemoved()\n\t\t\t*g = Godebug{}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (f *WorkFile) AddUse(diskPath, modulePath string) error {\n\tneed := true\n\tfor _, d := range f.Use {\n\t\tif d.Path == diskPath {\n\t\t\tif need {\n\t\t\t\td.ModulePath = modulePath\n\t\t\t\tf.Syntax.updateLine(d.Syntax, \"use\", AutoQuote(diskPath))\n\t\t\t\tneed = false\n\t\t\t} else {\n\t\t\t\td.Syntax.markRemoved()\n\t\t\t\t*d = Use{}\n\t\t\t}\n\t\t}\n\t}\n\n\tif need {\n\t\tf.AddNewUse(diskPath, modulePath)\n\t}\n\treturn nil\n}\n\nfunc (f *WorkFile) AddNewUse(diskPath, modulePath string) {\n\tline := f.Syntax.addLine(nil, \"use\", AutoQuote(diskPath))\n\tf.Use = append(f.Use, &Use{Path: diskPath, ModulePath: modulePath, Syntax: line})\n}\n\nfunc (f *WorkFile) SetUse(dirs []*Use) {\n\tneed := make(map[string]string)\n\tfor _, d := range dirs {\n\t\tneed[d.Path] = d.ModulePath\n\t}\n\n\tfor _, d := range f.Use {\n\t\tif modulePath, ok := need[d.Path]; ok {\n\t\t\td.ModulePath = modulePath\n\t\t} else {\n\t\t\td.Syntax.markRemoved()\n\t\t\t*d = Use{}\n\t\t}\n\t}\n\n\t// TODO(#45713): Add module path to comment.\n\n\tfor diskPath, modulePath := range need {\n\t\tf.AddNewUse(diskPath, modulePath)\n\t}\n\tf.SortBlocks()\n}\n\nfunc (f *WorkFile) DropUse(path string) error {\n\tfor _, d := range f.Use {\n\t\tif d.Path == path {\n\t\t\td.Syntax.markRemoved()\n\t\t\t*d = Use{}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (f *WorkFile) AddReplace(oldPath, oldVers, newPath, newVers string) error {\n\treturn addReplace(f.Syntax, &f.Replace, oldPath, oldVers, newPath, newVers)\n}\n\nfunc (f *WorkFile) DropReplace(oldPath, oldVers string) error {\n\tfor _, r := range f.Replace {\n\t\tif r.Old.Path == oldPath && r.Old.Version == oldVers {\n\t\t\tr.Syntax.markRemoved()\n\t\t\t*r = Replace{}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (f *WorkFile) SortBlocks() {\n\tf.removeDups() // otherwise sorting is unsafe\n\n\tfor _, stmt := range f.Syntax.Stmt {\n\t\tblock, ok := stmt.(*LineBlock)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tsort.SliceStable(block.Line, func(i, j int) bool {\n\t\t\treturn lineLess(block.Line[i], block.Line[j])\n\t\t})\n\t}\n}\n\n// removeDups removes duplicate replace directives.\n//\n// Later replace directives take priority.\n//\n// require directives are not de-duplicated. That's left up to higher-level\n// logic (MVS).\n//\n// retract directives are not de-duplicated since comments are\n// meaningful, and versions may be retracted multiple times.\nfunc (f *WorkFile) removeDups() {\n\tremoveDups(f.Syntax, nil, &f.Replace, nil)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/mod/module/module.go",
    "content": "// Copyright 2018 The Go 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\n// Package module defines the module.Version type along with support code.\n//\n// The [module.Version] type is a simple Path, Version pair:\n//\n//\ttype Version struct {\n//\t\tPath string\n//\t\tVersion string\n//\t}\n//\n// There are no restrictions imposed directly by use of this structure,\n// but additional checking functions, most notably [Check], verify that\n// a particular path, version pair is valid.\n//\n// # Escaped Paths\n//\n// Module paths appear as substrings of file system paths\n// (in the download cache) and of web server URLs in the proxy protocol.\n// In general we cannot rely on file systems to be case-sensitive,\n// nor can we rely on web servers, since they read from file systems.\n// That is, we cannot rely on the file system to keep rsc.io/QUOTE\n// and rsc.io/quote separate. Windows and macOS don't.\n// Instead, we must never require two different casings of a file path.\n// Because we want the download cache to match the proxy protocol,\n// and because we want the proxy protocol to be possible to serve\n// from a tree of static files (which might be stored on a case-insensitive\n// file system), the proxy protocol must never require two different casings\n// of a URL path either.\n//\n// One possibility would be to make the escaped form be the lowercase\n// hexadecimal encoding of the actual path bytes. This would avoid ever\n// needing different casings of a file path, but it would be fairly illegible\n// to most programmers when those paths appeared in the file system\n// (including in file paths in compiler errors and stack traces)\n// in web server logs, and so on. Instead, we want a safe escaped form that\n// leaves most paths unaltered.\n//\n// The safe escaped form is to replace every uppercase letter\n// with an exclamation mark followed by the letter's lowercase equivalent.\n//\n// For example,\n//\n//\tgithub.com/Azure/azure-sdk-for-go ->  github.com/!azure/azure-sdk-for-go.\n//\tgithub.com/GoogleCloudPlatform/cloudsql-proxy -> github.com/!google!cloud!platform/cloudsql-proxy\n//\tgithub.com/Sirupsen/logrus -> github.com/!sirupsen/logrus.\n//\n// Import paths that avoid upper-case letters are left unchanged.\n// Note that because import paths are ASCII-only and avoid various\n// problematic punctuation (like : < and >), the escaped form is also ASCII-only\n// and avoids the same problematic punctuation.\n//\n// Import paths have never allowed exclamation marks, so there is no\n// need to define how to escape a literal !.\n//\n// # Unicode Restrictions\n//\n// Today, paths are disallowed from using Unicode.\n//\n// Although paths are currently disallowed from using Unicode,\n// we would like at some point to allow Unicode letters as well, to assume that\n// file systems and URLs are Unicode-safe (storing UTF-8), and apply\n// the !-for-uppercase convention for escaping them in the file system.\n// But there are at least two subtle considerations.\n//\n// First, note that not all case-fold equivalent distinct runes\n// form an upper/lower pair.\n// For example, U+004B ('K'), U+006B ('k'), and U+212A ('K' for Kelvin)\n// are three distinct runes that case-fold to each other.\n// When we do add Unicode letters, we must not assume that upper/lower\n// are the only case-equivalent pairs.\n// Perhaps the Kelvin symbol would be disallowed entirely, for example.\n// Or perhaps it would escape as \"!!k\", or perhaps as \"(212A)\".\n//\n// Second, it would be nice to allow Unicode marks as well as letters,\n// but marks include combining marks, and then we must deal not\n// only with case folding but also normalization: both U+00E9 ('é')\n// and U+0065 U+0301 ('e' followed by combining acute accent)\n// look the same on the page and are treated by some file systems\n// as the same path. If we do allow Unicode marks in paths, there\n// must be some kind of normalization to allow only one canonical\n// encoding of any character used in an import path.\npackage module\n\n// IMPORTANT NOTE\n//\n// This file essentially defines the set of valid import paths for the go command.\n// There are many subtle considerations, including Unicode ambiguity,\n// security, network, and file system representations.\n//\n// This file also defines the set of valid module path and version combinations,\n// another topic with many subtle considerations.\n//\n// Changes to the semantics in this file require approval from rsc.\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"path\"\n\t\"sort\"\n\t\"strings\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n\n\t\"golang.org/x/mod/semver\"\n)\n\n// A Version (for clients, a module.Version) is defined by a module path and version pair.\n// These are stored in their plain (unescaped) form.\ntype Version struct {\n\t// Path is a module path, like \"golang.org/x/text\" or \"rsc.io/quote/v2\".\n\tPath string\n\n\t// Version is usually a semantic version in canonical form.\n\t// There are three exceptions to this general rule.\n\t// First, the top-level target of a build has no specific version\n\t// and uses Version = \"\".\n\t// Second, during MVS calculations the version \"none\" is used\n\t// to represent the decision to take no version of a given module.\n\t// Third, filesystem paths found in \"replace\" directives are\n\t// represented by a path with an empty version.\n\tVersion string `json:\",omitempty\"`\n}\n\n// String returns a representation of the Version suitable for logging\n// (Path@Version, or just Path if Version is empty).\nfunc (m Version) String() string {\n\tif m.Version == \"\" {\n\t\treturn m.Path\n\t}\n\treturn m.Path + \"@\" + m.Version\n}\n\n// A ModuleError indicates an error specific to a module.\ntype ModuleError struct {\n\tPath    string\n\tVersion string\n\tErr     error\n}\n\n// VersionError returns a [ModuleError] derived from a [Version] and error,\n// or err itself if it is already such an error.\nfunc VersionError(v Version, err error) error {\n\tvar mErr *ModuleError\n\tif errors.As(err, &mErr) && mErr.Path == v.Path && mErr.Version == v.Version {\n\t\treturn err\n\t}\n\treturn &ModuleError{\n\t\tPath:    v.Path,\n\t\tVersion: v.Version,\n\t\tErr:     err,\n\t}\n}\n\nfunc (e *ModuleError) Error() string {\n\tif v, ok := e.Err.(*InvalidVersionError); ok {\n\t\treturn fmt.Sprintf(\"%s@%s: invalid %s: %v\", e.Path, v.Version, v.noun(), v.Err)\n\t}\n\tif e.Version != \"\" {\n\t\treturn fmt.Sprintf(\"%s@%s: %v\", e.Path, e.Version, e.Err)\n\t}\n\treturn fmt.Sprintf(\"module %s: %v\", e.Path, e.Err)\n}\n\nfunc (e *ModuleError) Unwrap() error { return e.Err }\n\n// An InvalidVersionError indicates an error specific to a version, with the\n// module path unknown or specified externally.\n//\n// A [ModuleError] may wrap an InvalidVersionError, but an InvalidVersionError\n// must not wrap a ModuleError.\ntype InvalidVersionError struct {\n\tVersion string\n\tPseudo  bool\n\tErr     error\n}\n\n// noun returns either \"version\" or \"pseudo-version\", depending on whether\n// e.Version is a pseudo-version.\nfunc (e *InvalidVersionError) noun() string {\n\tif e.Pseudo {\n\t\treturn \"pseudo-version\"\n\t}\n\treturn \"version\"\n}\n\nfunc (e *InvalidVersionError) Error() string {\n\treturn fmt.Sprintf(\"%s %q invalid: %s\", e.noun(), e.Version, e.Err)\n}\n\nfunc (e *InvalidVersionError) Unwrap() error { return e.Err }\n\n// An InvalidPathError indicates a module, import, or file path doesn't\n// satisfy all naming constraints. See [CheckPath], [CheckImportPath],\n// and [CheckFilePath] for specific restrictions.\ntype InvalidPathError struct {\n\tKind string // \"module\", \"import\", or \"file\"\n\tPath string\n\tErr  error\n}\n\nfunc (e *InvalidPathError) Error() string {\n\treturn fmt.Sprintf(\"malformed %s path %q: %v\", e.Kind, e.Path, e.Err)\n}\n\nfunc (e *InvalidPathError) Unwrap() error { return e.Err }\n\n// Check checks that a given module path, version pair is valid.\n// In addition to the path being a valid module path\n// and the version being a valid semantic version,\n// the two must correspond.\n// For example, the path \"yaml/v2\" only corresponds to\n// semantic versions beginning with \"v2.\".\nfunc Check(path, version string) error {\n\tif err := CheckPath(path); err != nil {\n\t\treturn err\n\t}\n\tif !semver.IsValid(version) {\n\t\treturn &ModuleError{\n\t\t\tPath: path,\n\t\t\tErr:  &InvalidVersionError{Version: version, Err: errors.New(\"not a semantic version\")},\n\t\t}\n\t}\n\t_, pathMajor, _ := SplitPathVersion(path)\n\tif err := CheckPathMajor(version, pathMajor); err != nil {\n\t\treturn &ModuleError{Path: path, Err: err}\n\t}\n\treturn nil\n}\n\n// firstPathOK reports whether r can appear in the first element of a module path.\n// The first element of the path must be an LDH domain name, at least for now.\n// To avoid case ambiguity, the domain name must be entirely lower case.\nfunc firstPathOK(r rune) bool {\n\treturn r == '-' || r == '.' ||\n\t\t'0' <= r && r <= '9' ||\n\t\t'a' <= r && r <= 'z'\n}\n\n// modPathOK reports whether r can appear in a module path element.\n// Paths can be ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~.\n//\n// This matches what \"go get\" has historically recognized in import paths,\n// and avoids confusing sequences like '%20' or '+' that would change meaning\n// if used in a URL.\n//\n// TODO(rsc): We would like to allow Unicode letters, but that requires additional\n// care in the safe encoding (see \"escaped paths\" above).\nfunc modPathOK(r rune) bool {\n\tif r < utf8.RuneSelf {\n\t\treturn r == '-' || r == '.' || r == '_' || r == '~' ||\n\t\t\t'0' <= r && r <= '9' ||\n\t\t\t'A' <= r && r <= 'Z' ||\n\t\t\t'a' <= r && r <= 'z'\n\t}\n\treturn false\n}\n\n// importPathOK reports whether r can appear in a package import path element.\n//\n// Import paths are intermediate between module paths and file paths: we allow\n// disallow characters that would be confusing or ambiguous as arguments to\n// 'go get' (such as '@' and ' ' ), but allow certain characters that are\n// otherwise-unambiguous on the command line and historically used for some\n// binary names (such as '++' as a suffix for compiler binaries and wrappers).\nfunc importPathOK(r rune) bool {\n\treturn modPathOK(r) || r == '+'\n}\n\n// fileNameOK reports whether r can appear in a file name.\n// For now we allow all Unicode letters but otherwise limit to pathOK plus a few more punctuation characters.\n// If we expand the set of allowed characters here, we have to\n// work harder at detecting potential case-folding and normalization collisions.\n// See note about \"escaped paths\" above.\nfunc fileNameOK(r rune) bool {\n\tif r < utf8.RuneSelf {\n\t\t// Entire set of ASCII punctuation, from which we remove characters:\n\t\t//     ! \" # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \\ ] ^ _ ` { | } ~\n\t\t// We disallow some shell special characters: \" ' * < > ? ` |\n\t\t// (Note that some of those are disallowed by the Windows file system as well.)\n\t\t// We also disallow path separators / : and \\ (fileNameOK is only called on path element characters).\n\t\t// We allow spaces (U+0020) in file names.\n\t\tconst allowed = \"!#$%&()+,-.=@[]^_{}~ \"\n\t\tif '0' <= r && r <= '9' || 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' {\n\t\t\treturn true\n\t\t}\n\t\treturn strings.ContainsRune(allowed, r)\n\t}\n\t// It may be OK to add more ASCII punctuation here, but only carefully.\n\t// For example Windows disallows < > \\, and macOS disallows :, so we must not allow those.\n\treturn unicode.IsLetter(r)\n}\n\n// CheckPath checks that a module path is valid.\n// A valid module path is a valid import path, as checked by [CheckImportPath],\n// with three additional constraints.\n// First, the leading path element (up to the first slash, if any),\n// by convention a domain name, must contain only lower-case ASCII letters,\n// ASCII digits, dots (U+002E), and dashes (U+002D);\n// it must contain at least one dot and cannot start with a dash.\n// Second, for a final path element of the form /vN, where N looks numeric\n// (ASCII digits and dots) must not begin with a leading zero, must not be /v1,\n// and must not contain any dots. For paths beginning with \"gopkg.in/\",\n// this second requirement is replaced by a requirement that the path\n// follow the gopkg.in server's conventions.\n// Third, no path element may begin with a dot.\nfunc CheckPath(path string) (err error) {\n\tdefer func() {\n\t\tif err != nil {\n\t\t\terr = &InvalidPathError{Kind: \"module\", Path: path, Err: err}\n\t\t}\n\t}()\n\n\tif err := checkPath(path, modulePath); err != nil {\n\t\treturn err\n\t}\n\ti := strings.Index(path, \"/\")\n\tif i < 0 {\n\t\ti = len(path)\n\t}\n\tif i == 0 {\n\t\treturn fmt.Errorf(\"leading slash\")\n\t}\n\tif !strings.Contains(path[:i], \".\") {\n\t\treturn fmt.Errorf(\"missing dot in first path element\")\n\t}\n\tif path[0] == '-' {\n\t\treturn fmt.Errorf(\"leading dash in first path element\")\n\t}\n\tfor _, r := range path[:i] {\n\t\tif !firstPathOK(r) {\n\t\t\treturn fmt.Errorf(\"invalid char %q in first path element\", r)\n\t\t}\n\t}\n\tif _, _, ok := SplitPathVersion(path); !ok {\n\t\treturn fmt.Errorf(\"invalid version\")\n\t}\n\treturn nil\n}\n\n// CheckImportPath checks that an import path is valid.\n//\n// A valid import path consists of one or more valid path elements\n// separated by slashes (U+002F). (It must not begin with nor end in a slash.)\n//\n// A valid path element is a non-empty string made up of\n// ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~.\n// It must not end with a dot (U+002E), nor contain two dots in a row.\n//\n// The element prefix up to the first dot must not be a reserved file name\n// on Windows, regardless of case (CON, com1, NuL, and so on). The element\n// must not have a suffix of a tilde followed by one or more ASCII digits\n// (to exclude paths elements that look like Windows short-names).\n//\n// CheckImportPath may be less restrictive in the future, but see the\n// top-level package documentation for additional information about\n// subtleties of Unicode.\nfunc CheckImportPath(path string) error {\n\tif err := checkPath(path, importPath); err != nil {\n\t\treturn &InvalidPathError{Kind: \"import\", Path: path, Err: err}\n\t}\n\treturn nil\n}\n\n// pathKind indicates what kind of path we're checking. Module paths,\n// import paths, and file paths have different restrictions.\ntype pathKind int\n\nconst (\n\tmodulePath pathKind = iota\n\timportPath\n\tfilePath\n)\n\n// checkPath checks that a general path is valid. kind indicates what\n// specific constraints should be applied.\n//\n// checkPath returns an error describing why the path is not valid.\n// Because these checks apply to module, import, and file paths,\n// and because other checks may be applied, the caller is expected to wrap\n// this error with [InvalidPathError].\nfunc checkPath(path string, kind pathKind) error {\n\tif !utf8.ValidString(path) {\n\t\treturn fmt.Errorf(\"invalid UTF-8\")\n\t}\n\tif path == \"\" {\n\t\treturn fmt.Errorf(\"empty string\")\n\t}\n\tif path[0] == '-' && kind != filePath {\n\t\treturn fmt.Errorf(\"leading dash\")\n\t}\n\tif strings.Contains(path, \"//\") {\n\t\treturn fmt.Errorf(\"double slash\")\n\t}\n\tif path[len(path)-1] == '/' {\n\t\treturn fmt.Errorf(\"trailing slash\")\n\t}\n\telemStart := 0\n\tfor i, r := range path {\n\t\tif r == '/' {\n\t\t\tif err := checkElem(path[elemStart:i], kind); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\telemStart = i + 1\n\t\t}\n\t}\n\tif err := checkElem(path[elemStart:], kind); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// checkElem checks whether an individual path element is valid.\nfunc checkElem(elem string, kind pathKind) error {\n\tif elem == \"\" {\n\t\treturn fmt.Errorf(\"empty path element\")\n\t}\n\tif strings.Count(elem, \".\") == len(elem) {\n\t\treturn fmt.Errorf(\"invalid path element %q\", elem)\n\t}\n\tif elem[0] == '.' && kind == modulePath {\n\t\treturn fmt.Errorf(\"leading dot in path element\")\n\t}\n\tif elem[len(elem)-1] == '.' {\n\t\treturn fmt.Errorf(\"trailing dot in path element\")\n\t}\n\tfor _, r := range elem {\n\t\tok := false\n\t\tswitch kind {\n\t\tcase modulePath:\n\t\t\tok = modPathOK(r)\n\t\tcase importPath:\n\t\t\tok = importPathOK(r)\n\t\tcase filePath:\n\t\t\tok = fileNameOK(r)\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"internal error: invalid kind %v\", kind))\n\t\t}\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"invalid char %q\", r)\n\t\t}\n\t}\n\n\t// Windows disallows a bunch of path elements, sadly.\n\t// See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file\n\tshort := elem\n\tif i := strings.Index(short, \".\"); i >= 0 {\n\t\tshort = short[:i]\n\t}\n\tfor _, bad := range badWindowsNames {\n\t\tif strings.EqualFold(bad, short) {\n\t\t\treturn fmt.Errorf(\"%q disallowed as path element component on Windows\", short)\n\t\t}\n\t}\n\n\tif kind == filePath {\n\t\t// don't check for Windows short-names in file names. They're\n\t\t// only an issue for import paths.\n\t\treturn nil\n\t}\n\n\t// Reject path components that look like Windows short-names.\n\t// Those usually end in a tilde followed by one or more ASCII digits.\n\tif tilde := strings.LastIndexByte(short, '~'); tilde >= 0 && tilde < len(short)-1 {\n\t\tsuffix := short[tilde+1:]\n\t\tsuffixIsDigits := true\n\t\tfor _, r := range suffix {\n\t\t\tif r < '0' || r > '9' {\n\t\t\t\tsuffixIsDigits = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif suffixIsDigits {\n\t\t\treturn fmt.Errorf(\"trailing tilde and digits in path element\")\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// CheckFilePath checks that a slash-separated file path is valid.\n// The definition of a valid file path is the same as the definition\n// of a valid import path except that the set of allowed characters is larger:\n// all Unicode letters, ASCII digits, the ASCII space character (U+0020),\n// and the ASCII punctuation characters\n// “!#$%&()+,-.=@[]^_{}~”.\n// (The excluded punctuation characters, \" * < > ? ` ' | / \\ and :,\n// have special meanings in certain shells or operating systems.)\n//\n// CheckFilePath may be less restrictive in the future, but see the\n// top-level package documentation for additional information about\n// subtleties of Unicode.\nfunc CheckFilePath(path string) error {\n\tif err := checkPath(path, filePath); err != nil {\n\t\treturn &InvalidPathError{Kind: \"file\", Path: path, Err: err}\n\t}\n\treturn nil\n}\n\n// badWindowsNames are the reserved file path elements on Windows.\n// See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file\nvar badWindowsNames = []string{\n\t\"CON\",\n\t\"PRN\",\n\t\"AUX\",\n\t\"NUL\",\n\t\"COM1\",\n\t\"COM2\",\n\t\"COM3\",\n\t\"COM4\",\n\t\"COM5\",\n\t\"COM6\",\n\t\"COM7\",\n\t\"COM8\",\n\t\"COM9\",\n\t\"LPT1\",\n\t\"LPT2\",\n\t\"LPT3\",\n\t\"LPT4\",\n\t\"LPT5\",\n\t\"LPT6\",\n\t\"LPT7\",\n\t\"LPT8\",\n\t\"LPT9\",\n}\n\n// SplitPathVersion returns prefix and major version such that prefix+pathMajor == path\n// and version is either empty or \"/vN\" for N >= 2.\n// As a special case, gopkg.in paths are recognized directly;\n// they require \".vN\" instead of \"/vN\", and for all N, not just N >= 2.\n// SplitPathVersion returns with ok = false when presented with\n// a path whose last path element does not satisfy the constraints\n// applied by [CheckPath], such as \"example.com/pkg/v1\" or \"example.com/pkg/v1.2\".\nfunc SplitPathVersion(path string) (prefix, pathMajor string, ok bool) {\n\tif strings.HasPrefix(path, \"gopkg.in/\") {\n\t\treturn splitGopkgIn(path)\n\t}\n\n\ti := len(path)\n\tdot := false\n\tfor i > 0 && ('0' <= path[i-1] && path[i-1] <= '9' || path[i-1] == '.') {\n\t\tif path[i-1] == '.' {\n\t\t\tdot = true\n\t\t}\n\t\ti--\n\t}\n\tif i <= 1 || i == len(path) || path[i-1] != 'v' || path[i-2] != '/' {\n\t\treturn path, \"\", true\n\t}\n\tprefix, pathMajor = path[:i-2], path[i-2:]\n\tif dot || len(pathMajor) <= 2 || pathMajor[2] == '0' || pathMajor == \"/v1\" {\n\t\treturn path, \"\", false\n\t}\n\treturn prefix, pathMajor, true\n}\n\n// splitGopkgIn is like SplitPathVersion but only for gopkg.in paths.\nfunc splitGopkgIn(path string) (prefix, pathMajor string, ok bool) {\n\tif !strings.HasPrefix(path, \"gopkg.in/\") {\n\t\treturn path, \"\", false\n\t}\n\ti := len(path)\n\tif strings.HasSuffix(path, \"-unstable\") {\n\t\ti -= len(\"-unstable\")\n\t}\n\tfor i > 0 && ('0' <= path[i-1] && path[i-1] <= '9') {\n\t\ti--\n\t}\n\tif i <= 1 || path[i-1] != 'v' || path[i-2] != '.' {\n\t\t// All gopkg.in paths must end in vN for some N.\n\t\treturn path, \"\", false\n\t}\n\tprefix, pathMajor = path[:i-2], path[i-2:]\n\tif len(pathMajor) <= 2 || pathMajor[2] == '0' && pathMajor != \".v0\" {\n\t\treturn path, \"\", false\n\t}\n\treturn prefix, pathMajor, true\n}\n\n// MatchPathMajor reports whether the semantic version v\n// matches the path major version pathMajor.\n//\n// MatchPathMajor returns true if and only if [CheckPathMajor] returns nil.\nfunc MatchPathMajor(v, pathMajor string) bool {\n\treturn CheckPathMajor(v, pathMajor) == nil\n}\n\n// CheckPathMajor returns a non-nil error if the semantic version v\n// does not match the path major version pathMajor.\nfunc CheckPathMajor(v, pathMajor string) error {\n\t// TODO(jayconrod): return errors or panic for invalid inputs. This function\n\t// (and others) was covered by integration tests for cmd/go, and surrounding\n\t// code protected against invalid inputs like non-canonical versions.\n\tif strings.HasPrefix(pathMajor, \".v\") && strings.HasSuffix(pathMajor, \"-unstable\") {\n\t\tpathMajor = strings.TrimSuffix(pathMajor, \"-unstable\")\n\t}\n\tif strings.HasPrefix(v, \"v0.0.0-\") && pathMajor == \".v1\" {\n\t\t// Allow old bug in pseudo-versions that generated v0.0.0- pseudoversion for gopkg .v1.\n\t\t// For example, gopkg.in/yaml.v2@v2.2.1's go.mod requires gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405.\n\t\treturn nil\n\t}\n\tm := semver.Major(v)\n\tif pathMajor == \"\" {\n\t\tif m == \"v0\" || m == \"v1\" || semver.Build(v) == \"+incompatible\" {\n\t\t\treturn nil\n\t\t}\n\t\tpathMajor = \"v0 or v1\"\n\t} else if pathMajor[0] == '/' || pathMajor[0] == '.' {\n\t\tif m == pathMajor[1:] {\n\t\t\treturn nil\n\t\t}\n\t\tpathMajor = pathMajor[1:]\n\t}\n\treturn &InvalidVersionError{\n\t\tVersion: v,\n\t\tErr:     fmt.Errorf(\"should be %s, not %s\", pathMajor, semver.Major(v)),\n\t}\n}\n\n// PathMajorPrefix returns the major-version tag prefix implied by pathMajor.\n// An empty PathMajorPrefix allows either v0 or v1.\n//\n// Note that [MatchPathMajor] may accept some versions that do not actually begin\n// with this prefix: namely, it accepts a 'v0.0.0-' prefix for a '.v1'\n// pathMajor, even though that pathMajor implies 'v1' tagging.\nfunc PathMajorPrefix(pathMajor string) string {\n\tif pathMajor == \"\" {\n\t\treturn \"\"\n\t}\n\tif pathMajor[0] != '/' && pathMajor[0] != '.' {\n\t\tpanic(\"pathMajor suffix \" + pathMajor + \" passed to PathMajorPrefix lacks separator\")\n\t}\n\tif strings.HasPrefix(pathMajor, \".v\") && strings.HasSuffix(pathMajor, \"-unstable\") {\n\t\tpathMajor = strings.TrimSuffix(pathMajor, \"-unstable\")\n\t}\n\tm := pathMajor[1:]\n\tif m != semver.Major(m) {\n\t\tpanic(\"pathMajor suffix \" + pathMajor + \"passed to PathMajorPrefix is not a valid major version\")\n\t}\n\treturn m\n}\n\n// CanonicalVersion returns the canonical form of the version string v.\n// It is the same as [semver.Canonical] except that it preserves the special build suffix \"+incompatible\".\nfunc CanonicalVersion(v string) string {\n\tcv := semver.Canonical(v)\n\tif semver.Build(v) == \"+incompatible\" {\n\t\tcv += \"+incompatible\"\n\t}\n\treturn cv\n}\n\n// Sort sorts the list by Path, breaking ties by comparing [Version] fields.\n// The Version fields are interpreted as semantic versions (using [semver.Compare])\n// optionally followed by a tie-breaking suffix introduced by a slash character,\n// like in \"v0.0.1/go.mod\".\nfunc Sort(list []Version) {\n\tsort.Slice(list, func(i, j int) bool {\n\t\tmi := list[i]\n\t\tmj := list[j]\n\t\tif mi.Path != mj.Path {\n\t\t\treturn mi.Path < mj.Path\n\t\t}\n\t\t// To help go.sum formatting, allow version/file.\n\t\t// Compare semver prefix by semver rules,\n\t\t// file by string order.\n\t\tvi := mi.Version\n\t\tvj := mj.Version\n\t\tvar fi, fj string\n\t\tif k := strings.Index(vi, \"/\"); k >= 0 {\n\t\t\tvi, fi = vi[:k], vi[k:]\n\t\t}\n\t\tif k := strings.Index(vj, \"/\"); k >= 0 {\n\t\t\tvj, fj = vj[:k], vj[k:]\n\t\t}\n\t\tif vi != vj {\n\t\t\treturn semver.Compare(vi, vj) < 0\n\t\t}\n\t\treturn fi < fj\n\t})\n}\n\n// EscapePath returns the escaped form of the given module path.\n// It fails if the module path is invalid.\nfunc EscapePath(path string) (escaped string, err error) {\n\tif err := CheckPath(path); err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn escapeString(path)\n}\n\n// EscapeVersion returns the escaped form of the given module version.\n// Versions are allowed to be in non-semver form but must be valid file names\n// and not contain exclamation marks.\nfunc EscapeVersion(v string) (escaped string, err error) {\n\tif err := checkElem(v, filePath); err != nil || strings.Contains(v, \"!\") {\n\t\treturn \"\", &InvalidVersionError{\n\t\t\tVersion: v,\n\t\t\tErr:     fmt.Errorf(\"disallowed version string\"),\n\t\t}\n\t}\n\treturn escapeString(v)\n}\n\nfunc escapeString(s string) (escaped string, err error) {\n\thaveUpper := false\n\tfor _, r := range s {\n\t\tif r == '!' || r >= utf8.RuneSelf {\n\t\t\t// This should be disallowed by CheckPath, but diagnose anyway.\n\t\t\t// The correctness of the escaping loop below depends on it.\n\t\t\treturn \"\", fmt.Errorf(\"internal error: inconsistency in EscapePath\")\n\t\t}\n\t\tif 'A' <= r && r <= 'Z' {\n\t\t\thaveUpper = true\n\t\t}\n\t}\n\n\tif !haveUpper {\n\t\treturn s, nil\n\t}\n\n\tvar buf []byte\n\tfor _, r := range s {\n\t\tif 'A' <= r && r <= 'Z' {\n\t\t\tbuf = append(buf, '!', byte(r+'a'-'A'))\n\t\t} else {\n\t\t\tbuf = append(buf, byte(r))\n\t\t}\n\t}\n\treturn string(buf), nil\n}\n\n// UnescapePath returns the module path for the given escaped path.\n// It fails if the escaped path is invalid or describes an invalid path.\nfunc UnescapePath(escaped string) (path string, err error) {\n\tpath, ok := unescapeString(escaped)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"invalid escaped module path %q\", escaped)\n\t}\n\tif err := CheckPath(path); err != nil {\n\t\treturn \"\", fmt.Errorf(\"invalid escaped module path %q: %v\", escaped, err)\n\t}\n\treturn path, nil\n}\n\n// UnescapeVersion returns the version string for the given escaped version.\n// It fails if the escaped form is invalid or describes an invalid version.\n// Versions are allowed to be in non-semver form but must be valid file names\n// and not contain exclamation marks.\nfunc UnescapeVersion(escaped string) (v string, err error) {\n\tv, ok := unescapeString(escaped)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"invalid escaped version %q\", escaped)\n\t}\n\tif err := checkElem(v, filePath); err != nil {\n\t\treturn \"\", fmt.Errorf(\"invalid escaped version %q: %v\", v, err)\n\t}\n\treturn v, nil\n}\n\nfunc unescapeString(escaped string) (string, bool) {\n\tvar buf []byte\n\n\tbang := false\n\tfor _, r := range escaped {\n\t\tif r >= utf8.RuneSelf {\n\t\t\treturn \"\", false\n\t\t}\n\t\tif bang {\n\t\t\tbang = false\n\t\t\tif r < 'a' || 'z' < r {\n\t\t\t\treturn \"\", false\n\t\t\t}\n\t\t\tbuf = append(buf, byte(r+'A'-'a'))\n\t\t\tcontinue\n\t\t}\n\t\tif r == '!' {\n\t\t\tbang = true\n\t\t\tcontinue\n\t\t}\n\t\tif 'A' <= r && r <= 'Z' {\n\t\t\treturn \"\", false\n\t\t}\n\t\tbuf = append(buf, byte(r))\n\t}\n\tif bang {\n\t\treturn \"\", false\n\t}\n\treturn string(buf), true\n}\n\n// MatchPrefixPatterns reports whether any path prefix of target matches one of\n// the glob patterns (as defined by [path.Match]) in the comma-separated globs\n// list. This implements the algorithm used when matching a module path to the\n// GOPRIVATE environment variable, as described by 'go help module-private'.\n//\n// It ignores any empty or malformed patterns in the list.\n// Trailing slashes on patterns are ignored.\nfunc MatchPrefixPatterns(globs, target string) bool {\n\tfor globs != \"\" {\n\t\t// Extract next non-empty glob in comma-separated list.\n\t\tvar glob string\n\t\tif i := strings.Index(globs, \",\"); i >= 0 {\n\t\t\tglob, globs = globs[:i], globs[i+1:]\n\t\t} else {\n\t\t\tglob, globs = globs, \"\"\n\t\t}\n\t\tglob = strings.TrimSuffix(glob, \"/\")\n\t\tif glob == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\t// A glob with N+1 path elements (N slashes) needs to be matched\n\t\t// against the first N+1 path elements of target,\n\t\t// which end just before the N+1'th slash.\n\t\tn := strings.Count(glob, \"/\")\n\t\tprefix := target\n\t\t// Walk target, counting slashes, truncating at the N+1'th slash.\n\t\tfor i := 0; i < len(target); i++ {\n\t\t\tif target[i] == '/' {\n\t\t\t\tif n == 0 {\n\t\t\t\t\tprefix = target[:i]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tn--\n\t\t\t}\n\t\t}\n\t\tif n > 0 {\n\t\t\t// Not enough prefix elements.\n\t\t\tcontinue\n\t\t}\n\t\tmatched, _ := path.Match(glob, prefix)\n\t\tif matched {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/golang.org/x/mod/module/pseudo.go",
    "content": "// Copyright 2018 The Go 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\n// Pseudo-versions\n//\n// Code authors are expected to tag the revisions they want users to use,\n// including prereleases. However, not all authors tag versions at all,\n// and not all commits a user might want to try will have tags.\n// A pseudo-version is a version with a special form that allows us to\n// address an untagged commit and order that version with respect to\n// other versions we might encounter.\n//\n// A pseudo-version takes one of the general forms:\n//\n//\t(1) vX.0.0-yyyymmddhhmmss-abcdef123456\n//\t(2) vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456\n//\t(3) vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456+incompatible\n//\t(4) vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456\n//\t(5) vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456+incompatible\n//\n// If there is no recently tagged version with the right major version vX,\n// then form (1) is used, creating a space of pseudo-versions at the bottom\n// of the vX version range, less than any tagged version, including the unlikely v0.0.0.\n//\n// If the most recent tagged version before the target commit is vX.Y.Z or vX.Y.Z+incompatible,\n// then the pseudo-version uses form (2) or (3), making it a prerelease for the next\n// possible semantic version after vX.Y.Z. The leading 0 segment in the prerelease string\n// ensures that the pseudo-version compares less than possible future explicit prereleases\n// like vX.Y.(Z+1)-rc1 or vX.Y.(Z+1)-1.\n//\n// If the most recent tagged version before the target commit is vX.Y.Z-pre or vX.Y.Z-pre+incompatible,\n// then the pseudo-version uses form (4) or (5), making it a slightly later prerelease.\n\npackage module\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"golang.org/x/mod/internal/lazyregexp\"\n\t\"golang.org/x/mod/semver\"\n)\n\nvar pseudoVersionRE = lazyregexp.New(`^v[0-9]+\\.(0\\.0-|\\d+\\.\\d+-([^+]*\\.)?0\\.)\\d{14}-[A-Za-z0-9]+(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$`)\n\nconst PseudoVersionTimestampFormat = \"20060102150405\"\n\n// PseudoVersion returns a pseudo-version for the given major version (\"v1\")\n// preexisting older tagged version (\"\" or \"v1.2.3\" or \"v1.2.3-pre\"), revision time,\n// and revision identifier (usually a 12-byte commit hash prefix).\nfunc PseudoVersion(major, older string, t time.Time, rev string) string {\n\tif major == \"\" {\n\t\tmajor = \"v0\"\n\t}\n\tsegment := fmt.Sprintf(\"%s-%s\", t.UTC().Format(PseudoVersionTimestampFormat), rev)\n\tbuild := semver.Build(older)\n\tolder = semver.Canonical(older)\n\tif older == \"\" {\n\t\treturn major + \".0.0-\" + segment // form (1)\n\t}\n\tif semver.Prerelease(older) != \"\" {\n\t\treturn older + \".0.\" + segment + build // form (4), (5)\n\t}\n\n\t// Form (2), (3).\n\t// Extract patch from vMAJOR.MINOR.PATCH\n\ti := strings.LastIndex(older, \".\") + 1\n\tv, patch := older[:i], older[i:]\n\n\t// Reassemble.\n\treturn v + incDecimal(patch) + \"-0.\" + segment + build\n}\n\n// ZeroPseudoVersion returns a pseudo-version with a zero timestamp and\n// revision, which may be used as a placeholder.\nfunc ZeroPseudoVersion(major string) string {\n\treturn PseudoVersion(major, \"\", time.Time{}, \"000000000000\")\n}\n\n// incDecimal returns the decimal string incremented by 1.\nfunc incDecimal(decimal string) string {\n\t// Scan right to left turning 9s to 0s until you find a digit to increment.\n\tdigits := []byte(decimal)\n\ti := len(digits) - 1\n\tfor ; i >= 0 && digits[i] == '9'; i-- {\n\t\tdigits[i] = '0'\n\t}\n\tif i >= 0 {\n\t\tdigits[i]++\n\t} else {\n\t\t// digits is all zeros\n\t\tdigits[0] = '1'\n\t\tdigits = append(digits, '0')\n\t}\n\treturn string(digits)\n}\n\n// decDecimal returns the decimal string decremented by 1, or the empty string\n// if the decimal is all zeroes.\nfunc decDecimal(decimal string) string {\n\t// Scan right to left turning 0s to 9s until you find a digit to decrement.\n\tdigits := []byte(decimal)\n\ti := len(digits) - 1\n\tfor ; i >= 0 && digits[i] == '0'; i-- {\n\t\tdigits[i] = '9'\n\t}\n\tif i < 0 {\n\t\t// decimal is all zeros\n\t\treturn \"\"\n\t}\n\tif i == 0 && digits[i] == '1' && len(digits) > 1 {\n\t\tdigits = digits[1:]\n\t} else {\n\t\tdigits[i]--\n\t}\n\treturn string(digits)\n}\n\n// IsPseudoVersion reports whether v is a pseudo-version.\nfunc IsPseudoVersion(v string) bool {\n\treturn strings.Count(v, \"-\") >= 2 && semver.IsValid(v) && pseudoVersionRE.MatchString(v)\n}\n\n// IsZeroPseudoVersion returns whether v is a pseudo-version with a zero base,\n// timestamp, and revision, as returned by [ZeroPseudoVersion].\nfunc IsZeroPseudoVersion(v string) bool {\n\treturn v == ZeroPseudoVersion(semver.Major(v))\n}\n\n// PseudoVersionTime returns the time stamp of the pseudo-version v.\n// It returns an error if v is not a pseudo-version or if the time stamp\n// embedded in the pseudo-version is not a valid time.\nfunc PseudoVersionTime(v string) (time.Time, error) {\n\t_, timestamp, _, _, err := parsePseudoVersion(v)\n\tif err != nil {\n\t\treturn time.Time{}, err\n\t}\n\tt, err := time.Parse(\"20060102150405\", timestamp)\n\tif err != nil {\n\t\treturn time.Time{}, &InvalidVersionError{\n\t\t\tVersion: v,\n\t\t\tPseudo:  true,\n\t\t\tErr:     fmt.Errorf(\"malformed time %q\", timestamp),\n\t\t}\n\t}\n\treturn t, nil\n}\n\n// PseudoVersionRev returns the revision identifier of the pseudo-version v.\n// It returns an error if v is not a pseudo-version.\nfunc PseudoVersionRev(v string) (rev string, err error) {\n\t_, _, rev, _, err = parsePseudoVersion(v)\n\treturn\n}\n\n// PseudoVersionBase returns the canonical parent version, if any, upon which\n// the pseudo-version v is based.\n//\n// If v has no parent version (that is, if it is \"vX.0.0-[…]\"),\n// PseudoVersionBase returns the empty string and a nil error.\nfunc PseudoVersionBase(v string) (string, error) {\n\tbase, _, _, build, err := parsePseudoVersion(v)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tswitch pre := semver.Prerelease(base); pre {\n\tcase \"\":\n\t\t// vX.0.0-yyyymmddhhmmss-abcdef123456 → \"\"\n\t\tif build != \"\" {\n\t\t\t// Pseudo-versions of the form vX.0.0-yyyymmddhhmmss-abcdef123456+incompatible\n\t\t\t// are nonsensical: the \"vX.0.0-\" prefix implies that there is no parent tag,\n\t\t\t// but the \"+incompatible\" suffix implies that the major version of\n\t\t\t// the parent tag is not compatible with the module's import path.\n\t\t\t//\n\t\t\t// There are a few such entries in the index generated by proxy.golang.org,\n\t\t\t// but we believe those entries were generated by the proxy itself.\n\t\t\treturn \"\", &InvalidVersionError{\n\t\t\t\tVersion: v,\n\t\t\t\tPseudo:  true,\n\t\t\t\tErr:     fmt.Errorf(\"lacks base version, but has build metadata %q\", build),\n\t\t\t}\n\t\t}\n\t\treturn \"\", nil\n\n\tcase \"-0\":\n\t\t// vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456 → vX.Y.Z\n\t\t// vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdef123456+incompatible → vX.Y.Z+incompatible\n\t\tbase = strings.TrimSuffix(base, pre)\n\t\ti := strings.LastIndexByte(base, '.')\n\t\tif i < 0 {\n\t\t\tpanic(\"base from parsePseudoVersion missing patch number: \" + base)\n\t\t}\n\t\tpatch := decDecimal(base[i+1:])\n\t\tif patch == \"\" {\n\t\t\t// vX.0.0-0 is invalid, but has been observed in the wild in the index\n\t\t\t// generated by requests to proxy.golang.org.\n\t\t\t//\n\t\t\t// NOTE(bcmills): I cannot find a historical bug that accounts for\n\t\t\t// pseudo-versions of this form, nor have I seen such versions in any\n\t\t\t// actual go.mod files. If we find actual examples of this form and a\n\t\t\t// reasonable theory of how they came into existence, it seems fine to\n\t\t\t// treat them as equivalent to vX.0.0 (especially since the invalid\n\t\t\t// pseudo-versions have lower precedence than the real ones). For now, we\n\t\t\t// reject them.\n\t\t\treturn \"\", &InvalidVersionError{\n\t\t\t\tVersion: v,\n\t\t\t\tPseudo:  true,\n\t\t\t\tErr:     fmt.Errorf(\"version before %s would have negative patch number\", base),\n\t\t\t}\n\t\t}\n\t\treturn base[:i+1] + patch + build, nil\n\n\tdefault:\n\t\t// vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456 → vX.Y.Z-pre\n\t\t// vX.Y.Z-pre.0.yyyymmddhhmmss-abcdef123456+incompatible → vX.Y.Z-pre+incompatible\n\t\tif !strings.HasSuffix(base, \".0\") {\n\t\t\tpanic(`base from parsePseudoVersion missing \".0\" before date: ` + base)\n\t\t}\n\t\treturn strings.TrimSuffix(base, \".0\") + build, nil\n\t}\n}\n\nvar errPseudoSyntax = errors.New(\"syntax error\")\n\nfunc parsePseudoVersion(v string) (base, timestamp, rev, build string, err error) {\n\tif !IsPseudoVersion(v) {\n\t\treturn \"\", \"\", \"\", \"\", &InvalidVersionError{\n\t\t\tVersion: v,\n\t\t\tPseudo:  true,\n\t\t\tErr:     errPseudoSyntax,\n\t\t}\n\t}\n\tbuild = semver.Build(v)\n\tv = strings.TrimSuffix(v, build)\n\tj := strings.LastIndex(v, \"-\")\n\tv, rev = v[:j], v[j+1:]\n\ti := strings.LastIndex(v, \"-\")\n\tif j := strings.LastIndex(v, \".\"); j > i {\n\t\tbase = v[:j] // \"vX.Y.Z-pre.0\" or \"vX.Y.(Z+1)-0\"\n\t\ttimestamp = v[j+1:]\n\t} else {\n\t\tbase = v[:i] // \"vX.0.0\"\n\t\ttimestamp = v[i+1:]\n\t}\n\treturn base, timestamp, rev, build, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/mod/semver/semver.go",
    "content": "// Copyright 2018 The Go 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\n// Package semver implements comparison of semantic version strings.\n// In this package, semantic version strings must begin with a leading \"v\",\n// as in \"v1.0.0\".\n//\n// The general form of a semantic version string accepted by this package is\n//\n//\tvMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]]\n//\n// where square brackets indicate optional parts of the syntax;\n// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros;\n// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers\n// using only alphanumeric characters and hyphens; and\n// all-numeric PRERELEASE identifiers must not have leading zeros.\n//\n// This package follows Semantic Versioning 2.0.0 (see semver.org)\n// with two exceptions. First, it requires the \"v\" prefix. Second, it recognizes\n// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes)\n// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0.\npackage semver\n\nimport \"sort\"\n\n// parsed returns the parsed form of a semantic version string.\ntype parsed struct {\n\tmajor      string\n\tminor      string\n\tpatch      string\n\tshort      string\n\tprerelease string\n\tbuild      string\n}\n\n// IsValid reports whether v is a valid semantic version string.\nfunc IsValid(v string) bool {\n\t_, ok := parse(v)\n\treturn ok\n}\n\n// Canonical returns the canonical formatting of the semantic version v.\n// It fills in any missing .MINOR or .PATCH and discards build metadata.\n// Two semantic versions compare equal only if their canonical formattings\n// are identical strings.\n// The canonical invalid semantic version is the empty string.\nfunc Canonical(v string) string {\n\tp, ok := parse(v)\n\tif !ok {\n\t\treturn \"\"\n\t}\n\tif p.build != \"\" {\n\t\treturn v[:len(v)-len(p.build)]\n\t}\n\tif p.short != \"\" {\n\t\treturn v + p.short\n\t}\n\treturn v\n}\n\n// Major returns the major version prefix of the semantic version v.\n// For example, Major(\"v2.1.0\") == \"v2\".\n// If v is an invalid semantic version string, Major returns the empty string.\nfunc Major(v string) string {\n\tpv, ok := parse(v)\n\tif !ok {\n\t\treturn \"\"\n\t}\n\treturn v[:1+len(pv.major)]\n}\n\n// MajorMinor returns the major.minor version prefix of the semantic version v.\n// For example, MajorMinor(\"v2.1.0\") == \"v2.1\".\n// If v is an invalid semantic version string, MajorMinor returns the empty string.\nfunc MajorMinor(v string) string {\n\tpv, ok := parse(v)\n\tif !ok {\n\t\treturn \"\"\n\t}\n\ti := 1 + len(pv.major)\n\tif j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor {\n\t\treturn v[:j]\n\t}\n\treturn v[:i] + \".\" + pv.minor\n}\n\n// Prerelease returns the prerelease suffix of the semantic version v.\n// For example, Prerelease(\"v2.1.0-pre+meta\") == \"-pre\".\n// If v is an invalid semantic version string, Prerelease returns the empty string.\nfunc Prerelease(v string) string {\n\tpv, ok := parse(v)\n\tif !ok {\n\t\treturn \"\"\n\t}\n\treturn pv.prerelease\n}\n\n// Build returns the build suffix of the semantic version v.\n// For example, Build(\"v2.1.0+meta\") == \"+meta\".\n// If v is an invalid semantic version string, Build returns the empty string.\nfunc Build(v string) string {\n\tpv, ok := parse(v)\n\tif !ok {\n\t\treturn \"\"\n\t}\n\treturn pv.build\n}\n\n// Compare returns an integer comparing two versions according to\n// semantic version precedence.\n// The result will be 0 if v == w, -1 if v < w, or +1 if v > w.\n//\n// An invalid semantic version string is considered less than a valid one.\n// All invalid semantic version strings compare equal to each other.\nfunc Compare(v, w string) int {\n\tpv, ok1 := parse(v)\n\tpw, ok2 := parse(w)\n\tif !ok1 && !ok2 {\n\t\treturn 0\n\t}\n\tif !ok1 {\n\t\treturn -1\n\t}\n\tif !ok2 {\n\t\treturn +1\n\t}\n\tif c := compareInt(pv.major, pw.major); c != 0 {\n\t\treturn c\n\t}\n\tif c := compareInt(pv.minor, pw.minor); c != 0 {\n\t\treturn c\n\t}\n\tif c := compareInt(pv.patch, pw.patch); c != 0 {\n\t\treturn c\n\t}\n\treturn comparePrerelease(pv.prerelease, pw.prerelease)\n}\n\n// Max canonicalizes its arguments and then returns the version string\n// that compares greater.\n//\n// Deprecated: use [Compare] instead. In most cases, returning a canonicalized\n// version is not expected or desired.\nfunc Max(v, w string) string {\n\tv = Canonical(v)\n\tw = Canonical(w)\n\tif Compare(v, w) > 0 {\n\t\treturn v\n\t}\n\treturn w\n}\n\n// ByVersion implements [sort.Interface] for sorting semantic version strings.\ntype ByVersion []string\n\nfunc (vs ByVersion) Len() int      { return len(vs) }\nfunc (vs ByVersion) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] }\nfunc (vs ByVersion) Less(i, j int) bool {\n\tcmp := Compare(vs[i], vs[j])\n\tif cmp != 0 {\n\t\treturn cmp < 0\n\t}\n\treturn vs[i] < vs[j]\n}\n\n// Sort sorts a list of semantic version strings using [ByVersion].\nfunc Sort(list []string) {\n\tsort.Sort(ByVersion(list))\n}\n\nfunc parse(v string) (p parsed, ok bool) {\n\tif v == \"\" || v[0] != 'v' {\n\t\treturn\n\t}\n\tp.major, v, ok = parseInt(v[1:])\n\tif !ok {\n\t\treturn\n\t}\n\tif v == \"\" {\n\t\tp.minor = \"0\"\n\t\tp.patch = \"0\"\n\t\tp.short = \".0.0\"\n\t\treturn\n\t}\n\tif v[0] != '.' {\n\t\tok = false\n\t\treturn\n\t}\n\tp.minor, v, ok = parseInt(v[1:])\n\tif !ok {\n\t\treturn\n\t}\n\tif v == \"\" {\n\t\tp.patch = \"0\"\n\t\tp.short = \".0\"\n\t\treturn\n\t}\n\tif v[0] != '.' {\n\t\tok = false\n\t\treturn\n\t}\n\tp.patch, v, ok = parseInt(v[1:])\n\tif !ok {\n\t\treturn\n\t}\n\tif len(v) > 0 && v[0] == '-' {\n\t\tp.prerelease, v, ok = parsePrerelease(v)\n\t\tif !ok {\n\t\t\treturn\n\t\t}\n\t}\n\tif len(v) > 0 && v[0] == '+' {\n\t\tp.build, v, ok = parseBuild(v)\n\t\tif !ok {\n\t\t\treturn\n\t\t}\n\t}\n\tif v != \"\" {\n\t\tok = false\n\t\treturn\n\t}\n\tok = true\n\treturn\n}\n\nfunc parseInt(v string) (t, rest string, ok bool) {\n\tif v == \"\" {\n\t\treturn\n\t}\n\tif v[0] < '0' || '9' < v[0] {\n\t\treturn\n\t}\n\ti := 1\n\tfor i < len(v) && '0' <= v[i] && v[i] <= '9' {\n\t\ti++\n\t}\n\tif v[0] == '0' && i != 1 {\n\t\treturn\n\t}\n\treturn v[:i], v[i:], true\n}\n\nfunc parsePrerelease(v string) (t, rest string, ok bool) {\n\t// \"A pre-release version MAY be denoted by appending a hyphen and\n\t// a series of dot separated identifiers immediately following the patch version.\n\t// Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-].\n\t// Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes.\"\n\tif v == \"\" || v[0] != '-' {\n\t\treturn\n\t}\n\ti := 1\n\tstart := 1\n\tfor i < len(v) && v[i] != '+' {\n\t\tif !isIdentChar(v[i]) && v[i] != '.' {\n\t\t\treturn\n\t\t}\n\t\tif v[i] == '.' {\n\t\t\tif start == i || isBadNum(v[start:i]) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tstart = i + 1\n\t\t}\n\t\ti++\n\t}\n\tif start == i || isBadNum(v[start:i]) {\n\t\treturn\n\t}\n\treturn v[:i], v[i:], true\n}\n\nfunc parseBuild(v string) (t, rest string, ok bool) {\n\tif v == \"\" || v[0] != '+' {\n\t\treturn\n\t}\n\ti := 1\n\tstart := 1\n\tfor i < len(v) {\n\t\tif !isIdentChar(v[i]) && v[i] != '.' {\n\t\t\treturn\n\t\t}\n\t\tif v[i] == '.' {\n\t\t\tif start == i {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tstart = i + 1\n\t\t}\n\t\ti++\n\t}\n\tif start == i {\n\t\treturn\n\t}\n\treturn v[:i], v[i:], true\n}\n\nfunc isIdentChar(c byte) bool {\n\treturn 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-'\n}\n\nfunc isBadNum(v string) bool {\n\ti := 0\n\tfor i < len(v) && '0' <= v[i] && v[i] <= '9' {\n\t\ti++\n\t}\n\treturn i == len(v) && i > 1 && v[0] == '0'\n}\n\nfunc isNum(v string) bool {\n\ti := 0\n\tfor i < len(v) && '0' <= v[i] && v[i] <= '9' {\n\t\ti++\n\t}\n\treturn i == len(v)\n}\n\nfunc compareInt(x, y string) int {\n\tif x == y {\n\t\treturn 0\n\t}\n\tif len(x) < len(y) {\n\t\treturn -1\n\t}\n\tif len(x) > len(y) {\n\t\treturn +1\n\t}\n\tif x < y {\n\t\treturn -1\n\t} else {\n\t\treturn +1\n\t}\n}\n\nfunc comparePrerelease(x, y string) int {\n\t// \"When major, minor, and patch are equal, a pre-release version has\n\t// lower precedence than a normal version.\n\t// Example: 1.0.0-alpha < 1.0.0.\n\t// Precedence for two pre-release versions with the same major, minor,\n\t// and patch version MUST be determined by comparing each dot separated\n\t// identifier from left to right until a difference is found as follows:\n\t// identifiers consisting of only digits are compared numerically and\n\t// identifiers with letters or hyphens are compared lexically in ASCII\n\t// sort order. Numeric identifiers always have lower precedence than\n\t// non-numeric identifiers. A larger set of pre-release fields has a\n\t// higher precedence than a smaller set, if all of the preceding\n\t// identifiers are equal.\n\t// Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta <\n\t// 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0.\"\n\tif x == y {\n\t\treturn 0\n\t}\n\tif x == \"\" {\n\t\treturn +1\n\t}\n\tif y == \"\" {\n\t\treturn -1\n\t}\n\tfor x != \"\" && y != \"\" {\n\t\tx = x[1:] // skip - or .\n\t\ty = y[1:] // skip - or .\n\t\tvar dx, dy string\n\t\tdx, x = nextIdent(x)\n\t\tdy, y = nextIdent(y)\n\t\tif dx != dy {\n\t\t\tix := isNum(dx)\n\t\t\tiy := isNum(dy)\n\t\t\tif ix != iy {\n\t\t\t\tif ix {\n\t\t\t\t\treturn -1\n\t\t\t\t} else {\n\t\t\t\t\treturn +1\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ix {\n\t\t\t\tif len(dx) < len(dy) {\n\t\t\t\t\treturn -1\n\t\t\t\t}\n\t\t\t\tif len(dx) > len(dy) {\n\t\t\t\t\treturn +1\n\t\t\t\t}\n\t\t\t}\n\t\t\tif dx < dy {\n\t\t\t\treturn -1\n\t\t\t} else {\n\t\t\t\treturn +1\n\t\t\t}\n\t\t}\n\t}\n\tif x == \"\" {\n\t\treturn -1\n\t} else {\n\t\treturn +1\n\t}\n}\n\nfunc nextIdent(x string) (dx, rest string) {\n\ti := 0\n\tfor i < len(x) && x[i] != '.' {\n\t\ti++\n\t}\n\treturn x[:i], x[i:]\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/LICENSE",
    "content": "Copyright 2009 The Go Authors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google LLC nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(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": "vendor/golang.org/x/net/PATENTS",
    "content": "Additional IP Rights Grant (Patents)\n\n\"This implementation\" means the copyrightable works distributed by\nGoogle as part of the Go project.\n\nGoogle hereby grants to You a perpetual, worldwide, non-exclusive,\nno-charge, royalty-free, irrevocable (except as stated in this section)\npatent license to make, have made, use, offer to sell, sell, import,\ntransfer and otherwise run, modify and propagate the contents of this\nimplementation of Go, where such license applies only to those patent\nclaims, both currently owned or controlled by Google and acquired in\nthe future, licensable by Google that are necessarily infringed by this\nimplementation of Go.  This grant does not include claims that would be\ninfringed only as a consequence of further modification of this\nimplementation.  If you or your agent or exclusive licensee institute or\norder or agree to the institution of patent litigation against any\nentity (including a cross-claim or counterclaim in a lawsuit) alleging\nthat this implementation of Go or any code incorporated within this\nimplementation of Go constitutes direct or contributory patent\ninfringement, or inducement of patent infringement, then any patent\nrights granted to you under this License for this implementation of Go\nshall terminate as of the date such litigation is filed.\n"
  },
  {
    "path": "vendor/golang.org/x/net/bpf/asm.go",
    "content": "// Copyright 2016 The Go 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 bpf\n\nimport \"fmt\"\n\n// Assemble converts insts into raw instructions suitable for loading\n// into a BPF virtual machine.\n//\n// Currently, no optimization is attempted, the assembled program flow\n// is exactly as provided.\nfunc Assemble(insts []Instruction) ([]RawInstruction, error) {\n\tret := make([]RawInstruction, len(insts))\n\tvar err error\n\tfor i, inst := range insts {\n\t\tret[i], err = inst.Assemble()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"assembling instruction %d: %s\", i+1, err)\n\t\t}\n\t}\n\treturn ret, nil\n}\n\n// Disassemble attempts to parse raw back into\n// Instructions. Unrecognized RawInstructions are assumed to be an\n// extension not implemented by this package, and are passed through\n// unchanged to the output. The allDecoded value reports whether insts\n// contains no RawInstructions.\nfunc Disassemble(raw []RawInstruction) (insts []Instruction, allDecoded bool) {\n\tinsts = make([]Instruction, len(raw))\n\tallDecoded = true\n\tfor i, r := range raw {\n\t\tinsts[i] = r.Disassemble()\n\t\tif _, ok := insts[i].(RawInstruction); ok {\n\t\t\tallDecoded = false\n\t\t}\n\t}\n\treturn insts, allDecoded\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/bpf/constants.go",
    "content": "// Copyright 2016 The Go 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 bpf\n\n// A Register is a register of the BPF virtual machine.\ntype Register uint16\n\nconst (\n\t// RegA is the accumulator register. RegA is always the\n\t// destination register of ALU operations.\n\tRegA Register = iota\n\t// RegX is the indirection register, used by LoadIndirect\n\t// operations.\n\tRegX\n)\n\n// An ALUOp is an arithmetic or logic operation.\ntype ALUOp uint16\n\n// ALU binary operation types.\nconst (\n\tALUOpAdd ALUOp = iota << 4\n\tALUOpSub\n\tALUOpMul\n\tALUOpDiv\n\tALUOpOr\n\tALUOpAnd\n\tALUOpShiftLeft\n\tALUOpShiftRight\n\taluOpNeg // Not exported because it's the only unary ALU operation, and gets its own instruction type.\n\tALUOpMod\n\tALUOpXor\n)\n\n// A JumpTest is a comparison operator used in conditional jumps.\ntype JumpTest uint16\n\n// Supported operators for conditional jumps.\n// K can be RegX for JumpIfX\nconst (\n\t// K == A\n\tJumpEqual JumpTest = iota\n\t// K != A\n\tJumpNotEqual\n\t// K > A\n\tJumpGreaterThan\n\t// K < A\n\tJumpLessThan\n\t// K >= A\n\tJumpGreaterOrEqual\n\t// K <= A\n\tJumpLessOrEqual\n\t// K & A != 0\n\tJumpBitsSet\n\t// K & A == 0\n\tJumpBitsNotSet\n)\n\n// An Extension is a function call provided by the kernel that\n// performs advanced operations that are expensive or impossible\n// within the BPF virtual machine.\n//\n// Extensions are only implemented by the Linux kernel.\n//\n// TODO: should we prune this list? Some of these extensions seem\n// either broken or near-impossible to use correctly, whereas other\n// (len, random, ifindex) are quite useful.\ntype Extension int\n\n// Extension functions available in the Linux kernel.\nconst (\n\t// extOffset is the negative maximum number of instructions used\n\t// to load instructions by overloading the K argument.\n\textOffset = -0x1000\n\t// ExtLen returns the length of the packet.\n\tExtLen Extension = 1\n\t// ExtProto returns the packet's L3 protocol type.\n\tExtProto Extension = 0\n\t// ExtType returns the packet's type (skb->pkt_type in the kernel)\n\t//\n\t// TODO: better documentation. How nice an API do we want to\n\t// provide for these esoteric extensions?\n\tExtType Extension = 4\n\t// ExtPayloadOffset returns the offset of the packet payload, or\n\t// the first protocol header that the kernel does not know how to\n\t// parse.\n\tExtPayloadOffset Extension = 52\n\t// ExtInterfaceIndex returns the index of the interface on which\n\t// the packet was received.\n\tExtInterfaceIndex Extension = 8\n\t// ExtNetlinkAttr returns the netlink attribute of type X at\n\t// offset A.\n\tExtNetlinkAttr Extension = 12\n\t// ExtNetlinkAttrNested returns the nested netlink attribute of\n\t// type X at offset A.\n\tExtNetlinkAttrNested Extension = 16\n\t// ExtMark returns the packet's mark value.\n\tExtMark Extension = 20\n\t// ExtQueue returns the packet's assigned hardware queue.\n\tExtQueue Extension = 24\n\t// ExtLinkLayerType returns the packet's hardware address type\n\t// (e.g. Ethernet, Infiniband).\n\tExtLinkLayerType Extension = 28\n\t// ExtRXHash returns the packets receive hash.\n\t//\n\t// TODO: figure out what this rxhash actually is.\n\tExtRXHash Extension = 32\n\t// ExtCPUID returns the ID of the CPU processing the current\n\t// packet.\n\tExtCPUID Extension = 36\n\t// ExtVLANTag returns the packet's VLAN tag.\n\tExtVLANTag Extension = 44\n\t// ExtVLANTagPresent returns non-zero if the packet has a VLAN\n\t// tag.\n\t//\n\t// TODO: I think this might be a lie: it reads bit 0x1000 of the\n\t// VLAN header, which changed meaning in recent revisions of the\n\t// spec - this extension may now return meaningless information.\n\tExtVLANTagPresent Extension = 48\n\t// ExtVLANProto returns 0x8100 if the frame has a VLAN header,\n\t// 0x88a8 if the frame has a \"Q-in-Q\" double VLAN header, or some\n\t// other value if no VLAN information is present.\n\tExtVLANProto Extension = 60\n\t// ExtRand returns a uniformly random uint32.\n\tExtRand Extension = 56\n)\n\n// The following gives names to various bit patterns used in opcode construction.\n\nconst (\n\topMaskCls uint16 = 0x7\n\t// opClsLoad masks\n\topMaskLoadDest  = 0x01\n\topMaskLoadWidth = 0x18\n\topMaskLoadMode  = 0xe0\n\t// opClsALU & opClsJump\n\topMaskOperand  = 0x08\n\topMaskOperator = 0xf0\n)\n\nconst (\n\t// +---------------+-----------------+---+---+---+\n\t// | AddrMode (3b) | LoadWidth (2b)  | 0 | 0 | 0 |\n\t// +---------------+-----------------+---+---+---+\n\topClsLoadA uint16 = iota\n\t// +---------------+-----------------+---+---+---+\n\t// | AddrMode (3b) | LoadWidth (2b)  | 0 | 0 | 1 |\n\t// +---------------+-----------------+---+---+---+\n\topClsLoadX\n\t// +---+---+---+---+---+---+---+---+\n\t// | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |\n\t// +---+---+---+---+---+---+---+---+\n\topClsStoreA\n\t// +---+---+---+---+---+---+---+---+\n\t// | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |\n\t// +---+---+---+---+---+---+---+---+\n\topClsStoreX\n\t// +---------------+-----------------+---+---+---+\n\t// | Operator (4b) | OperandSrc (1b) | 1 | 0 | 0 |\n\t// +---------------+-----------------+---+---+---+\n\topClsALU\n\t// +-----------------------------+---+---+---+---+\n\t// |      TestOperator (4b)      | 0 | 1 | 0 | 1 |\n\t// +-----------------------------+---+---+---+---+\n\topClsJump\n\t// +---+-------------------------+---+---+---+---+\n\t// | 0 | 0 | 0 |   RetSrc (1b)   | 0 | 1 | 1 | 0 |\n\t// +---+-------------------------+---+---+---+---+\n\topClsReturn\n\t// +---+-------------------------+---+---+---+---+\n\t// | 0 | 0 | 0 |  TXAorTAX (1b)  | 0 | 1 | 1 | 1 |\n\t// +---+-------------------------+---+---+---+---+\n\topClsMisc\n)\n\nconst (\n\topAddrModeImmediate uint16 = iota << 5\n\topAddrModeAbsolute\n\topAddrModeIndirect\n\topAddrModeScratch\n\topAddrModePacketLen // actually an extension, not an addressing mode.\n\topAddrModeMemShift\n)\n\nconst (\n\topLoadWidth4 uint16 = iota << 3\n\topLoadWidth2\n\topLoadWidth1\n)\n\n// Operand for ALU and Jump instructions\ntype opOperand uint16\n\n// Supported operand sources.\nconst (\n\topOperandConstant opOperand = iota << 3\n\topOperandX\n)\n\n// An jumpOp is a conditional jump condition.\ntype jumpOp uint16\n\n// Supported jump conditions.\nconst (\n\topJumpAlways jumpOp = iota << 4\n\topJumpEqual\n\topJumpGT\n\topJumpGE\n\topJumpSet\n)\n\nconst (\n\topRetSrcConstant uint16 = iota << 4\n\topRetSrcA\n)\n\nconst (\n\topMiscTAX = 0x00\n\topMiscTXA = 0x80\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/bpf/doc.go",
    "content": "// Copyright 2016 The Go 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\n/*\nPackage bpf implements marshaling and unmarshaling of programs for the\nBerkeley Packet Filter virtual machine, and provides a Go implementation\nof the virtual machine.\n\nBPF's main use is to specify a packet filter for network taps, so that\nthe kernel doesn't have to expensively copy every packet it sees to\nuserspace. However, it's been repurposed to other areas where running\nuser code in-kernel is needed. For example, Linux's seccomp uses BPF\nto apply security policies to system calls. For simplicity, this\ndocumentation refers only to packets, but other uses of BPF have their\nown data payloads.\n\nBPF programs run in a restricted virtual machine. It has almost no\naccess to kernel functions, and while conditional branches are\nallowed, they can only jump forwards, to guarantee that there are no\ninfinite loops.\n\n# The virtual machine\n\nThe BPF VM is an accumulator machine. Its main register, called\nregister A, is an implicit source and destination in all arithmetic\nand logic operations. The machine also has 16 scratch registers for\ntemporary storage, and an indirection register (register X) for\nindirect memory access. All registers are 32 bits wide.\n\nEach run of a BPF program is given one packet, which is placed in the\nVM's read-only \"main memory\". LoadAbsolute and LoadIndirect\ninstructions can fetch up to 32 bits at a time into register A for\nexamination.\n\nThe goal of a BPF program is to produce and return a verdict (uint32),\nwhich tells the kernel what to do with the packet. In the context of\npacket filtering, the returned value is the number of bytes of the\npacket to forward to userspace, or 0 to ignore the packet. Other\ncontexts like seccomp define their own return values.\n\nIn order to simplify programs, attempts to read past the end of the\npacket terminate the program execution with a verdict of 0 (ignore\npacket). This means that the vast majority of BPF programs don't need\nto do any explicit bounds checking.\n\nIn addition to the bytes of the packet, some BPF programs have access\nto extensions, which are essentially calls to kernel utility\nfunctions. Currently, the only extensions supported by this package\nare the Linux packet filter extensions.\n\n# Examples\n\nThis packet filter selects all ARP packets.\n\n\tbpf.Assemble([]bpf.Instruction{\n\t\t// Load \"EtherType\" field from the ethernet header.\n\t\tbpf.LoadAbsolute{Off: 12, Size: 2},\n\t\t// Skip over the next instruction if EtherType is not ARP.\n\t\tbpf.JumpIf{Cond: bpf.JumpNotEqual, Val: 0x0806, SkipTrue: 1},\n\t\t// Verdict is \"send up to 4k of the packet to userspace.\"\n\t\tbpf.RetConstant{Val: 4096},\n\t\t// Verdict is \"ignore packet.\"\n\t\tbpf.RetConstant{Val: 0},\n\t})\n\nThis packet filter captures a random 1% sample of traffic.\n\n\tbpf.Assemble([]bpf.Instruction{\n\t\t// Get a 32-bit random number from the Linux kernel.\n\t\tbpf.LoadExtension{Num: bpf.ExtRand},\n\t\t// 1% dice roll?\n\t\tbpf.JumpIf{Cond: bpf.JumpLessThan, Val: 2^32/100, SkipFalse: 1},\n\t\t// Capture.\n\t\tbpf.RetConstant{Val: 4096},\n\t\t// Ignore.\n\t\tbpf.RetConstant{Val: 0},\n\t})\n*/\npackage bpf // import \"golang.org/x/net/bpf\"\n"
  },
  {
    "path": "vendor/golang.org/x/net/bpf/instructions.go",
    "content": "// Copyright 2016 The Go 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 bpf\n\nimport \"fmt\"\n\n// An Instruction is one instruction executed by the BPF virtual\n// machine.\ntype Instruction interface {\n\t// Assemble assembles the Instruction into a RawInstruction.\n\tAssemble() (RawInstruction, error)\n}\n\n// A RawInstruction is a raw BPF virtual machine instruction.\ntype RawInstruction struct {\n\t// Operation to execute.\n\tOp uint16\n\t// For conditional jump instructions, the number of instructions\n\t// to skip if the condition is true/false.\n\tJt uint8\n\tJf uint8\n\t// Constant parameter. The meaning depends on the Op.\n\tK uint32\n}\n\n// Assemble implements the Instruction Assemble method.\nfunc (ri RawInstruction) Assemble() (RawInstruction, error) { return ri, nil }\n\n// Disassemble parses ri into an Instruction and returns it. If ri is\n// not recognized by this package, ri itself is returned.\nfunc (ri RawInstruction) Disassemble() Instruction {\n\tswitch ri.Op & opMaskCls {\n\tcase opClsLoadA, opClsLoadX:\n\t\treg := Register(ri.Op & opMaskLoadDest)\n\t\tsz := 0\n\t\tswitch ri.Op & opMaskLoadWidth {\n\t\tcase opLoadWidth4:\n\t\t\tsz = 4\n\t\tcase opLoadWidth2:\n\t\t\tsz = 2\n\t\tcase opLoadWidth1:\n\t\t\tsz = 1\n\t\tdefault:\n\t\t\treturn ri\n\t\t}\n\t\tswitch ri.Op & opMaskLoadMode {\n\t\tcase opAddrModeImmediate:\n\t\t\tif sz != 4 {\n\t\t\t\treturn ri\n\t\t\t}\n\t\t\treturn LoadConstant{Dst: reg, Val: ri.K}\n\t\tcase opAddrModeScratch:\n\t\t\tif sz != 4 || ri.K > 15 {\n\t\t\t\treturn ri\n\t\t\t}\n\t\t\treturn LoadScratch{Dst: reg, N: int(ri.K)}\n\t\tcase opAddrModeAbsolute:\n\t\t\tif ri.K > extOffset+0xffffffff {\n\t\t\t\treturn LoadExtension{Num: Extension(-extOffset + ri.K)}\n\t\t\t}\n\t\t\treturn LoadAbsolute{Size: sz, Off: ri.K}\n\t\tcase opAddrModeIndirect:\n\t\t\treturn LoadIndirect{Size: sz, Off: ri.K}\n\t\tcase opAddrModePacketLen:\n\t\t\tif sz != 4 {\n\t\t\t\treturn ri\n\t\t\t}\n\t\t\treturn LoadExtension{Num: ExtLen}\n\t\tcase opAddrModeMemShift:\n\t\t\treturn LoadMemShift{Off: ri.K}\n\t\tdefault:\n\t\t\treturn ri\n\t\t}\n\n\tcase opClsStoreA:\n\t\tif ri.Op != opClsStoreA || ri.K > 15 {\n\t\t\treturn ri\n\t\t}\n\t\treturn StoreScratch{Src: RegA, N: int(ri.K)}\n\n\tcase opClsStoreX:\n\t\tif ri.Op != opClsStoreX || ri.K > 15 {\n\t\t\treturn ri\n\t\t}\n\t\treturn StoreScratch{Src: RegX, N: int(ri.K)}\n\n\tcase opClsALU:\n\t\tswitch op := ALUOp(ri.Op & opMaskOperator); op {\n\t\tcase ALUOpAdd, ALUOpSub, ALUOpMul, ALUOpDiv, ALUOpOr, ALUOpAnd, ALUOpShiftLeft, ALUOpShiftRight, ALUOpMod, ALUOpXor:\n\t\t\tswitch operand := opOperand(ri.Op & opMaskOperand); operand {\n\t\t\tcase opOperandX:\n\t\t\t\treturn ALUOpX{Op: op}\n\t\t\tcase opOperandConstant:\n\t\t\t\treturn ALUOpConstant{Op: op, Val: ri.K}\n\t\t\tdefault:\n\t\t\t\treturn ri\n\t\t\t}\n\t\tcase aluOpNeg:\n\t\t\treturn NegateA{}\n\t\tdefault:\n\t\t\treturn ri\n\t\t}\n\n\tcase opClsJump:\n\t\tswitch op := jumpOp(ri.Op & opMaskOperator); op {\n\t\tcase opJumpAlways:\n\t\t\treturn Jump{Skip: ri.K}\n\t\tcase opJumpEqual, opJumpGT, opJumpGE, opJumpSet:\n\t\t\tcond, skipTrue, skipFalse := jumpOpToTest(op, ri.Jt, ri.Jf)\n\t\t\tswitch operand := opOperand(ri.Op & opMaskOperand); operand {\n\t\t\tcase opOperandX:\n\t\t\t\treturn JumpIfX{Cond: cond, SkipTrue: skipTrue, SkipFalse: skipFalse}\n\t\t\tcase opOperandConstant:\n\t\t\t\treturn JumpIf{Cond: cond, Val: ri.K, SkipTrue: skipTrue, SkipFalse: skipFalse}\n\t\t\tdefault:\n\t\t\t\treturn ri\n\t\t\t}\n\t\tdefault:\n\t\t\treturn ri\n\t\t}\n\n\tcase opClsReturn:\n\t\tswitch ri.Op {\n\t\tcase opClsReturn | opRetSrcA:\n\t\t\treturn RetA{}\n\t\tcase opClsReturn | opRetSrcConstant:\n\t\t\treturn RetConstant{Val: ri.K}\n\t\tdefault:\n\t\t\treturn ri\n\t\t}\n\n\tcase opClsMisc:\n\t\tswitch ri.Op {\n\t\tcase opClsMisc | opMiscTAX:\n\t\t\treturn TAX{}\n\t\tcase opClsMisc | opMiscTXA:\n\t\t\treturn TXA{}\n\t\tdefault:\n\t\t\treturn ri\n\t\t}\n\n\tdefault:\n\t\tpanic(\"unreachable\") // switch is exhaustive on the bit pattern\n\t}\n}\n\nfunc jumpOpToTest(op jumpOp, skipTrue uint8, skipFalse uint8) (JumpTest, uint8, uint8) {\n\tvar test JumpTest\n\n\t// Decode \"fake\" jump conditions that don't appear in machine code\n\t// Ensures the Assemble -> Disassemble stage recreates the same instructions\n\t// See https://github.com/golang/go/issues/18470\n\tif skipTrue == 0 {\n\t\tswitch op {\n\t\tcase opJumpEqual:\n\t\t\ttest = JumpNotEqual\n\t\tcase opJumpGT:\n\t\t\ttest = JumpLessOrEqual\n\t\tcase opJumpGE:\n\t\t\ttest = JumpLessThan\n\t\tcase opJumpSet:\n\t\t\ttest = JumpBitsNotSet\n\t\t}\n\n\t\treturn test, skipFalse, 0\n\t}\n\n\tswitch op {\n\tcase opJumpEqual:\n\t\ttest = JumpEqual\n\tcase opJumpGT:\n\t\ttest = JumpGreaterThan\n\tcase opJumpGE:\n\t\ttest = JumpGreaterOrEqual\n\tcase opJumpSet:\n\t\ttest = JumpBitsSet\n\t}\n\n\treturn test, skipTrue, skipFalse\n}\n\n// LoadConstant loads Val into register Dst.\ntype LoadConstant struct {\n\tDst Register\n\tVal uint32\n}\n\n// Assemble implements the Instruction Assemble method.\nfunc (a LoadConstant) Assemble() (RawInstruction, error) {\n\treturn assembleLoad(a.Dst, 4, opAddrModeImmediate, a.Val)\n}\n\n// String returns the instruction in assembler notation.\nfunc (a LoadConstant) String() string {\n\tswitch a.Dst {\n\tcase RegA:\n\t\treturn fmt.Sprintf(\"ld #%d\", a.Val)\n\tcase RegX:\n\t\treturn fmt.Sprintf(\"ldx #%d\", a.Val)\n\tdefault:\n\t\treturn fmt.Sprintf(\"unknown instruction: %#v\", a)\n\t}\n}\n\n// LoadScratch loads scratch[N] into register Dst.\ntype LoadScratch struct {\n\tDst Register\n\tN   int // 0-15\n}\n\n// Assemble implements the Instruction Assemble method.\nfunc (a LoadScratch) Assemble() (RawInstruction, error) {\n\tif a.N < 0 || a.N > 15 {\n\t\treturn RawInstruction{}, fmt.Errorf(\"invalid scratch slot %d\", a.N)\n\t}\n\treturn assembleLoad(a.Dst, 4, opAddrModeScratch, uint32(a.N))\n}\n\n// String returns the instruction in assembler notation.\nfunc (a LoadScratch) String() string {\n\tswitch a.Dst {\n\tcase RegA:\n\t\treturn fmt.Sprintf(\"ld M[%d]\", a.N)\n\tcase RegX:\n\t\treturn fmt.Sprintf(\"ldx M[%d]\", a.N)\n\tdefault:\n\t\treturn fmt.Sprintf(\"unknown instruction: %#v\", a)\n\t}\n}\n\n// LoadAbsolute loads packet[Off:Off+Size] as an integer value into\n// register A.\ntype LoadAbsolute struct {\n\tOff  uint32\n\tSize int // 1, 2 or 4\n}\n\n// Assemble implements the Instruction Assemble method.\nfunc (a LoadAbsolute) Assemble() (RawInstruction, error) {\n\treturn assembleLoad(RegA, a.Size, opAddrModeAbsolute, a.Off)\n}\n\n// String returns the instruction in assembler notation.\nfunc (a LoadAbsolute) String() string {\n\tswitch a.Size {\n\tcase 1: // byte\n\t\treturn fmt.Sprintf(\"ldb [%d]\", a.Off)\n\tcase 2: // half word\n\t\treturn fmt.Sprintf(\"ldh [%d]\", a.Off)\n\tcase 4: // word\n\t\tif a.Off > extOffset+0xffffffff {\n\t\t\treturn LoadExtension{Num: Extension(a.Off + 0x1000)}.String()\n\t\t}\n\t\treturn fmt.Sprintf(\"ld [%d]\", a.Off)\n\tdefault:\n\t\treturn fmt.Sprintf(\"unknown instruction: %#v\", a)\n\t}\n}\n\n// LoadIndirect loads packet[X+Off:X+Off+Size] as an integer value\n// into register A.\ntype LoadIndirect struct {\n\tOff  uint32\n\tSize int // 1, 2 or 4\n}\n\n// Assemble implements the Instruction Assemble method.\nfunc (a LoadIndirect) Assemble() (RawInstruction, error) {\n\treturn assembleLoad(RegA, a.Size, opAddrModeIndirect, a.Off)\n}\n\n// String returns the instruction in assembler notation.\nfunc (a LoadIndirect) String() string {\n\tswitch a.Size {\n\tcase 1: // byte\n\t\treturn fmt.Sprintf(\"ldb [x + %d]\", a.Off)\n\tcase 2: // half word\n\t\treturn fmt.Sprintf(\"ldh [x + %d]\", a.Off)\n\tcase 4: // word\n\t\treturn fmt.Sprintf(\"ld [x + %d]\", a.Off)\n\tdefault:\n\t\treturn fmt.Sprintf(\"unknown instruction: %#v\", a)\n\t}\n}\n\n// LoadMemShift multiplies the first 4 bits of the byte at packet[Off]\n// by 4 and stores the result in register X.\n//\n// This instruction is mainly useful to load into X the length of an\n// IPv4 packet header in a single instruction, rather than have to do\n// the arithmetic on the header's first byte by hand.\ntype LoadMemShift struct {\n\tOff uint32\n}\n\n// Assemble implements the Instruction Assemble method.\nfunc (a LoadMemShift) Assemble() (RawInstruction, error) {\n\treturn assembleLoad(RegX, 1, opAddrModeMemShift, a.Off)\n}\n\n// String returns the instruction in assembler notation.\nfunc (a LoadMemShift) String() string {\n\treturn fmt.Sprintf(\"ldx 4*([%d]&0xf)\", a.Off)\n}\n\n// LoadExtension invokes a linux-specific extension and stores the\n// result in register A.\ntype LoadExtension struct {\n\tNum Extension\n}\n\n// Assemble implements the Instruction Assemble method.\nfunc (a LoadExtension) Assemble() (RawInstruction, error) {\n\tif a.Num == ExtLen {\n\t\treturn assembleLoad(RegA, 4, opAddrModePacketLen, 0)\n\t}\n\treturn assembleLoad(RegA, 4, opAddrModeAbsolute, uint32(extOffset+a.Num))\n}\n\n// String returns the instruction in assembler notation.\nfunc (a LoadExtension) String() string {\n\tswitch a.Num {\n\tcase ExtLen:\n\t\treturn \"ld #len\"\n\tcase ExtProto:\n\t\treturn \"ld #proto\"\n\tcase ExtType:\n\t\treturn \"ld #type\"\n\tcase ExtPayloadOffset:\n\t\treturn \"ld #poff\"\n\tcase ExtInterfaceIndex:\n\t\treturn \"ld #ifidx\"\n\tcase ExtNetlinkAttr:\n\t\treturn \"ld #nla\"\n\tcase ExtNetlinkAttrNested:\n\t\treturn \"ld #nlan\"\n\tcase ExtMark:\n\t\treturn \"ld #mark\"\n\tcase ExtQueue:\n\t\treturn \"ld #queue\"\n\tcase ExtLinkLayerType:\n\t\treturn \"ld #hatype\"\n\tcase ExtRXHash:\n\t\treturn \"ld #rxhash\"\n\tcase ExtCPUID:\n\t\treturn \"ld #cpu\"\n\tcase ExtVLANTag:\n\t\treturn \"ld #vlan_tci\"\n\tcase ExtVLANTagPresent:\n\t\treturn \"ld #vlan_avail\"\n\tcase ExtVLANProto:\n\t\treturn \"ld #vlan_tpid\"\n\tcase ExtRand:\n\t\treturn \"ld #rand\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"unknown instruction: %#v\", a)\n\t}\n}\n\n// StoreScratch stores register Src into scratch[N].\ntype StoreScratch struct {\n\tSrc Register\n\tN   int // 0-15\n}\n\n// Assemble implements the Instruction Assemble method.\nfunc (a StoreScratch) Assemble() (RawInstruction, error) {\n\tif a.N < 0 || a.N > 15 {\n\t\treturn RawInstruction{}, fmt.Errorf(\"invalid scratch slot %d\", a.N)\n\t}\n\tvar op uint16\n\tswitch a.Src {\n\tcase RegA:\n\t\top = opClsStoreA\n\tcase RegX:\n\t\top = opClsStoreX\n\tdefault:\n\t\treturn RawInstruction{}, fmt.Errorf(\"invalid source register %v\", a.Src)\n\t}\n\n\treturn RawInstruction{\n\t\tOp: op,\n\t\tK:  uint32(a.N),\n\t}, nil\n}\n\n// String returns the instruction in assembler notation.\nfunc (a StoreScratch) String() string {\n\tswitch a.Src {\n\tcase RegA:\n\t\treturn fmt.Sprintf(\"st M[%d]\", a.N)\n\tcase RegX:\n\t\treturn fmt.Sprintf(\"stx M[%d]\", a.N)\n\tdefault:\n\t\treturn fmt.Sprintf(\"unknown instruction: %#v\", a)\n\t}\n}\n\n// ALUOpConstant executes A = A <Op> Val.\ntype ALUOpConstant struct {\n\tOp  ALUOp\n\tVal uint32\n}\n\n// Assemble implements the Instruction Assemble method.\nfunc (a ALUOpConstant) Assemble() (RawInstruction, error) {\n\treturn RawInstruction{\n\t\tOp: opClsALU | uint16(opOperandConstant) | uint16(a.Op),\n\t\tK:  a.Val,\n\t}, nil\n}\n\n// String returns the instruction in assembler notation.\nfunc (a ALUOpConstant) String() string {\n\tswitch a.Op {\n\tcase ALUOpAdd:\n\t\treturn fmt.Sprintf(\"add #%d\", a.Val)\n\tcase ALUOpSub:\n\t\treturn fmt.Sprintf(\"sub #%d\", a.Val)\n\tcase ALUOpMul:\n\t\treturn fmt.Sprintf(\"mul #%d\", a.Val)\n\tcase ALUOpDiv:\n\t\treturn fmt.Sprintf(\"div #%d\", a.Val)\n\tcase ALUOpMod:\n\t\treturn fmt.Sprintf(\"mod #%d\", a.Val)\n\tcase ALUOpAnd:\n\t\treturn fmt.Sprintf(\"and #%d\", a.Val)\n\tcase ALUOpOr:\n\t\treturn fmt.Sprintf(\"or #%d\", a.Val)\n\tcase ALUOpXor:\n\t\treturn fmt.Sprintf(\"xor #%d\", a.Val)\n\tcase ALUOpShiftLeft:\n\t\treturn fmt.Sprintf(\"lsh #%d\", a.Val)\n\tcase ALUOpShiftRight:\n\t\treturn fmt.Sprintf(\"rsh #%d\", a.Val)\n\tdefault:\n\t\treturn fmt.Sprintf(\"unknown instruction: %#v\", a)\n\t}\n}\n\n// ALUOpX executes A = A <Op> X\ntype ALUOpX struct {\n\tOp ALUOp\n}\n\n// Assemble implements the Instruction Assemble method.\nfunc (a ALUOpX) Assemble() (RawInstruction, error) {\n\treturn RawInstruction{\n\t\tOp: opClsALU | uint16(opOperandX) | uint16(a.Op),\n\t}, nil\n}\n\n// String returns the instruction in assembler notation.\nfunc (a ALUOpX) String() string {\n\tswitch a.Op {\n\tcase ALUOpAdd:\n\t\treturn \"add x\"\n\tcase ALUOpSub:\n\t\treturn \"sub x\"\n\tcase ALUOpMul:\n\t\treturn \"mul x\"\n\tcase ALUOpDiv:\n\t\treturn \"div x\"\n\tcase ALUOpMod:\n\t\treturn \"mod x\"\n\tcase ALUOpAnd:\n\t\treturn \"and x\"\n\tcase ALUOpOr:\n\t\treturn \"or x\"\n\tcase ALUOpXor:\n\t\treturn \"xor x\"\n\tcase ALUOpShiftLeft:\n\t\treturn \"lsh x\"\n\tcase ALUOpShiftRight:\n\t\treturn \"rsh x\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"unknown instruction: %#v\", a)\n\t}\n}\n\n// NegateA executes A = -A.\ntype NegateA struct{}\n\n// Assemble implements the Instruction Assemble method.\nfunc (a NegateA) Assemble() (RawInstruction, error) {\n\treturn RawInstruction{\n\t\tOp: opClsALU | uint16(aluOpNeg),\n\t}, nil\n}\n\n// String returns the instruction in assembler notation.\nfunc (a NegateA) String() string {\n\treturn fmt.Sprintf(\"neg\")\n}\n\n// Jump skips the following Skip instructions in the program.\ntype Jump struct {\n\tSkip uint32\n}\n\n// Assemble implements the Instruction Assemble method.\nfunc (a Jump) Assemble() (RawInstruction, error) {\n\treturn RawInstruction{\n\t\tOp: opClsJump | uint16(opJumpAlways),\n\t\tK:  a.Skip,\n\t}, nil\n}\n\n// String returns the instruction in assembler notation.\nfunc (a Jump) String() string {\n\treturn fmt.Sprintf(\"ja %d\", a.Skip)\n}\n\n// JumpIf skips the following Skip instructions in the program if A\n// <Cond> Val is true.\ntype JumpIf struct {\n\tCond      JumpTest\n\tVal       uint32\n\tSkipTrue  uint8\n\tSkipFalse uint8\n}\n\n// Assemble implements the Instruction Assemble method.\nfunc (a JumpIf) Assemble() (RawInstruction, error) {\n\treturn jumpToRaw(a.Cond, opOperandConstant, a.Val, a.SkipTrue, a.SkipFalse)\n}\n\n// String returns the instruction in assembler notation.\nfunc (a JumpIf) String() string {\n\treturn jumpToString(a.Cond, fmt.Sprintf(\"#%d\", a.Val), a.SkipTrue, a.SkipFalse)\n}\n\n// JumpIfX skips the following Skip instructions in the program if A\n// <Cond> X is true.\ntype JumpIfX struct {\n\tCond      JumpTest\n\tSkipTrue  uint8\n\tSkipFalse uint8\n}\n\n// Assemble implements the Instruction Assemble method.\nfunc (a JumpIfX) Assemble() (RawInstruction, error) {\n\treturn jumpToRaw(a.Cond, opOperandX, 0, a.SkipTrue, a.SkipFalse)\n}\n\n// String returns the instruction in assembler notation.\nfunc (a JumpIfX) String() string {\n\treturn jumpToString(a.Cond, \"x\", a.SkipTrue, a.SkipFalse)\n}\n\n// jumpToRaw assembles a jump instruction into a RawInstruction\nfunc jumpToRaw(test JumpTest, operand opOperand, k uint32, skipTrue, skipFalse uint8) (RawInstruction, error) {\n\tvar (\n\t\tcond jumpOp\n\t\tflip bool\n\t)\n\tswitch test {\n\tcase JumpEqual:\n\t\tcond = opJumpEqual\n\tcase JumpNotEqual:\n\t\tcond, flip = opJumpEqual, true\n\tcase JumpGreaterThan:\n\t\tcond = opJumpGT\n\tcase JumpLessThan:\n\t\tcond, flip = opJumpGE, true\n\tcase JumpGreaterOrEqual:\n\t\tcond = opJumpGE\n\tcase JumpLessOrEqual:\n\t\tcond, flip = opJumpGT, true\n\tcase JumpBitsSet:\n\t\tcond = opJumpSet\n\tcase JumpBitsNotSet:\n\t\tcond, flip = opJumpSet, true\n\tdefault:\n\t\treturn RawInstruction{}, fmt.Errorf(\"unknown JumpTest %v\", test)\n\t}\n\tjt, jf := skipTrue, skipFalse\n\tif flip {\n\t\tjt, jf = jf, jt\n\t}\n\treturn RawInstruction{\n\t\tOp: opClsJump | uint16(cond) | uint16(operand),\n\t\tJt: jt,\n\t\tJf: jf,\n\t\tK:  k,\n\t}, nil\n}\n\n// jumpToString converts a jump instruction to assembler notation\nfunc jumpToString(cond JumpTest, operand string, skipTrue, skipFalse uint8) string {\n\tswitch cond {\n\t// K == A\n\tcase JumpEqual:\n\t\treturn conditionalJump(operand, skipTrue, skipFalse, \"jeq\", \"jneq\")\n\t// K != A\n\tcase JumpNotEqual:\n\t\treturn fmt.Sprintf(\"jneq %s,%d\", operand, skipTrue)\n\t// K > A\n\tcase JumpGreaterThan:\n\t\treturn conditionalJump(operand, skipTrue, skipFalse, \"jgt\", \"jle\")\n\t// K < A\n\tcase JumpLessThan:\n\t\treturn fmt.Sprintf(\"jlt %s,%d\", operand, skipTrue)\n\t// K >= A\n\tcase JumpGreaterOrEqual:\n\t\treturn conditionalJump(operand, skipTrue, skipFalse, \"jge\", \"jlt\")\n\t// K <= A\n\tcase JumpLessOrEqual:\n\t\treturn fmt.Sprintf(\"jle %s,%d\", operand, skipTrue)\n\t// K & A != 0\n\tcase JumpBitsSet:\n\t\tif skipFalse > 0 {\n\t\t\treturn fmt.Sprintf(\"jset %s,%d,%d\", operand, skipTrue, skipFalse)\n\t\t}\n\t\treturn fmt.Sprintf(\"jset %s,%d\", operand, skipTrue)\n\t// K & A == 0, there is no assembler instruction for JumpBitNotSet, use JumpBitSet and invert skips\n\tcase JumpBitsNotSet:\n\t\treturn jumpToString(JumpBitsSet, operand, skipFalse, skipTrue)\n\tdefault:\n\t\treturn fmt.Sprintf(\"unknown JumpTest %#v\", cond)\n\t}\n}\n\nfunc conditionalJump(operand string, skipTrue, skipFalse uint8, positiveJump, negativeJump string) string {\n\tif skipTrue > 0 {\n\t\tif skipFalse > 0 {\n\t\t\treturn fmt.Sprintf(\"%s %s,%d,%d\", positiveJump, operand, skipTrue, skipFalse)\n\t\t}\n\t\treturn fmt.Sprintf(\"%s %s,%d\", positiveJump, operand, skipTrue)\n\t}\n\treturn fmt.Sprintf(\"%s %s,%d\", negativeJump, operand, skipFalse)\n}\n\n// RetA exits the BPF program, returning the value of register A.\ntype RetA struct{}\n\n// Assemble implements the Instruction Assemble method.\nfunc (a RetA) Assemble() (RawInstruction, error) {\n\treturn RawInstruction{\n\t\tOp: opClsReturn | opRetSrcA,\n\t}, nil\n}\n\n// String returns the instruction in assembler notation.\nfunc (a RetA) String() string {\n\treturn fmt.Sprintf(\"ret a\")\n}\n\n// RetConstant exits the BPF program, returning a constant value.\ntype RetConstant struct {\n\tVal uint32\n}\n\n// Assemble implements the Instruction Assemble method.\nfunc (a RetConstant) Assemble() (RawInstruction, error) {\n\treturn RawInstruction{\n\t\tOp: opClsReturn | opRetSrcConstant,\n\t\tK:  a.Val,\n\t}, nil\n}\n\n// String returns the instruction in assembler notation.\nfunc (a RetConstant) String() string {\n\treturn fmt.Sprintf(\"ret #%d\", a.Val)\n}\n\n// TXA copies the value of register X to register A.\ntype TXA struct{}\n\n// Assemble implements the Instruction Assemble method.\nfunc (a TXA) Assemble() (RawInstruction, error) {\n\treturn RawInstruction{\n\t\tOp: opClsMisc | opMiscTXA,\n\t}, nil\n}\n\n// String returns the instruction in assembler notation.\nfunc (a TXA) String() string {\n\treturn fmt.Sprintf(\"txa\")\n}\n\n// TAX copies the value of register A to register X.\ntype TAX struct{}\n\n// Assemble implements the Instruction Assemble method.\nfunc (a TAX) Assemble() (RawInstruction, error) {\n\treturn RawInstruction{\n\t\tOp: opClsMisc | opMiscTAX,\n\t}, nil\n}\n\n// String returns the instruction in assembler notation.\nfunc (a TAX) String() string {\n\treturn fmt.Sprintf(\"tax\")\n}\n\nfunc assembleLoad(dst Register, loadSize int, mode uint16, k uint32) (RawInstruction, error) {\n\tvar (\n\t\tcls uint16\n\t\tsz  uint16\n\t)\n\tswitch dst {\n\tcase RegA:\n\t\tcls = opClsLoadA\n\tcase RegX:\n\t\tcls = opClsLoadX\n\tdefault:\n\t\treturn RawInstruction{}, fmt.Errorf(\"invalid target register %v\", dst)\n\t}\n\tswitch loadSize {\n\tcase 1:\n\t\tsz = opLoadWidth1\n\tcase 2:\n\t\tsz = opLoadWidth2\n\tcase 4:\n\t\tsz = opLoadWidth4\n\tdefault:\n\t\treturn RawInstruction{}, fmt.Errorf(\"invalid load byte length %d\", sz)\n\t}\n\treturn RawInstruction{\n\t\tOp: cls | sz | mode,\n\t\tK:  k,\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/bpf/setter.go",
    "content": "// Copyright 2017 The Go 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 bpf\n\n// A Setter is a type which can attach a compiled BPF filter to itself.\ntype Setter interface {\n\tSetBPF(filter []RawInstruction) error\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/bpf/vm.go",
    "content": "// Copyright 2016 The Go 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 bpf\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// A VM is an emulated BPF virtual machine.\ntype VM struct {\n\tfilter []Instruction\n}\n\n// NewVM returns a new VM using the input BPF program.\nfunc NewVM(filter []Instruction) (*VM, error) {\n\tif len(filter) == 0 {\n\t\treturn nil, errors.New(\"one or more Instructions must be specified\")\n\t}\n\n\tfor i, ins := range filter {\n\t\tcheck := len(filter) - (i + 1)\n\t\tswitch ins := ins.(type) {\n\t\t// Check for out-of-bounds jumps in instructions\n\t\tcase Jump:\n\t\t\tif check <= int(ins.Skip) {\n\t\t\t\treturn nil, fmt.Errorf(\"cannot jump %d instructions; jumping past program bounds\", ins.Skip)\n\t\t\t}\n\t\tcase JumpIf:\n\t\t\tif check <= int(ins.SkipTrue) {\n\t\t\t\treturn nil, fmt.Errorf(\"cannot jump %d instructions in true case; jumping past program bounds\", ins.SkipTrue)\n\t\t\t}\n\t\t\tif check <= int(ins.SkipFalse) {\n\t\t\t\treturn nil, fmt.Errorf(\"cannot jump %d instructions in false case; jumping past program bounds\", ins.SkipFalse)\n\t\t\t}\n\t\tcase JumpIfX:\n\t\t\tif check <= int(ins.SkipTrue) {\n\t\t\t\treturn nil, fmt.Errorf(\"cannot jump %d instructions in true case; jumping past program bounds\", ins.SkipTrue)\n\t\t\t}\n\t\t\tif check <= int(ins.SkipFalse) {\n\t\t\t\treturn nil, fmt.Errorf(\"cannot jump %d instructions in false case; jumping past program bounds\", ins.SkipFalse)\n\t\t\t}\n\t\t// Check for division or modulus by zero\n\t\tcase ALUOpConstant:\n\t\t\tif ins.Val != 0 {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tswitch ins.Op {\n\t\t\tcase ALUOpDiv, ALUOpMod:\n\t\t\t\treturn nil, errors.New(\"cannot divide by zero using ALUOpConstant\")\n\t\t\t}\n\t\t// Check for unknown extensions\n\t\tcase LoadExtension:\n\t\t\tswitch ins.Num {\n\t\t\tcase ExtLen:\n\t\t\tdefault:\n\t\t\t\treturn nil, fmt.Errorf(\"extension %d not implemented\", ins.Num)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Make sure last instruction is a return instruction\n\tswitch filter[len(filter)-1].(type) {\n\tcase RetA, RetConstant:\n\tdefault:\n\t\treturn nil, errors.New(\"BPF program must end with RetA or RetConstant\")\n\t}\n\n\t// Though our VM works using disassembled instructions, we\n\t// attempt to assemble the input filter anyway to ensure it is compatible\n\t// with an operating system VM.\n\t_, err := Assemble(filter)\n\n\treturn &VM{\n\t\tfilter: filter,\n\t}, err\n}\n\n// Run runs the VM's BPF program against the input bytes.\n// Run returns the number of bytes accepted by the BPF program, and any errors\n// which occurred while processing the program.\nfunc (v *VM) Run(in []byte) (int, error) {\n\tvar (\n\t\t// Registers of the virtual machine\n\t\tregA       uint32\n\t\tregX       uint32\n\t\tregScratch [16]uint32\n\n\t\t// OK is true if the program should continue processing the next\n\t\t// instruction, or false if not, causing the loop to break\n\t\tok = true\n\t)\n\n\t// TODO(mdlayher): implement:\n\t// - NegateA:\n\t//   - would require a change from uint32 registers to int32\n\t//     registers\n\n\t// TODO(mdlayher): add interop tests that check signedness of ALU\n\t// operations against kernel implementation, and make sure Go\n\t// implementation matches behavior\n\n\tfor i := 0; i < len(v.filter) && ok; i++ {\n\t\tins := v.filter[i]\n\n\t\tswitch ins := ins.(type) {\n\t\tcase ALUOpConstant:\n\t\t\tregA = aluOpConstant(ins, regA)\n\t\tcase ALUOpX:\n\t\t\tregA, ok = aluOpX(ins, regA, regX)\n\t\tcase Jump:\n\t\t\ti += int(ins.Skip)\n\t\tcase JumpIf:\n\t\t\tjump := jumpIf(ins, regA)\n\t\t\ti += jump\n\t\tcase JumpIfX:\n\t\t\tjump := jumpIfX(ins, regA, regX)\n\t\t\ti += jump\n\t\tcase LoadAbsolute:\n\t\t\tregA, ok = loadAbsolute(ins, in)\n\t\tcase LoadConstant:\n\t\t\tregA, regX = loadConstant(ins, regA, regX)\n\t\tcase LoadExtension:\n\t\t\tregA = loadExtension(ins, in)\n\t\tcase LoadIndirect:\n\t\t\tregA, ok = loadIndirect(ins, in, regX)\n\t\tcase LoadMemShift:\n\t\t\tregX, ok = loadMemShift(ins, in)\n\t\tcase LoadScratch:\n\t\t\tregA, regX = loadScratch(ins, regScratch, regA, regX)\n\t\tcase RetA:\n\t\t\treturn int(regA), nil\n\t\tcase RetConstant:\n\t\t\treturn int(ins.Val), nil\n\t\tcase StoreScratch:\n\t\t\tregScratch = storeScratch(ins, regScratch, regA, regX)\n\t\tcase TAX:\n\t\t\tregX = regA\n\t\tcase TXA:\n\t\t\tregA = regX\n\t\tdefault:\n\t\t\treturn 0, fmt.Errorf(\"unknown Instruction at index %d: %T\", i, ins)\n\t\t}\n\t}\n\n\treturn 0, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/bpf/vm_instructions.go",
    "content": "// Copyright 2016 The Go 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 bpf\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n)\n\nfunc aluOpConstant(ins ALUOpConstant, regA uint32) uint32 {\n\treturn aluOpCommon(ins.Op, regA, ins.Val)\n}\n\nfunc aluOpX(ins ALUOpX, regA uint32, regX uint32) (uint32, bool) {\n\t// Guard against division or modulus by zero by terminating\n\t// the program, as the OS BPF VM does\n\tif regX == 0 {\n\t\tswitch ins.Op {\n\t\tcase ALUOpDiv, ALUOpMod:\n\t\t\treturn 0, false\n\t\t}\n\t}\n\n\treturn aluOpCommon(ins.Op, regA, regX), true\n}\n\nfunc aluOpCommon(op ALUOp, regA uint32, value uint32) uint32 {\n\tswitch op {\n\tcase ALUOpAdd:\n\t\treturn regA + value\n\tcase ALUOpSub:\n\t\treturn regA - value\n\tcase ALUOpMul:\n\t\treturn regA * value\n\tcase ALUOpDiv:\n\t\t// Division by zero not permitted by NewVM and aluOpX checks\n\t\treturn regA / value\n\tcase ALUOpOr:\n\t\treturn regA | value\n\tcase ALUOpAnd:\n\t\treturn regA & value\n\tcase ALUOpShiftLeft:\n\t\treturn regA << value\n\tcase ALUOpShiftRight:\n\t\treturn regA >> value\n\tcase ALUOpMod:\n\t\t// Modulus by zero not permitted by NewVM and aluOpX checks\n\t\treturn regA % value\n\tcase ALUOpXor:\n\t\treturn regA ^ value\n\tdefault:\n\t\treturn regA\n\t}\n}\n\nfunc jumpIf(ins JumpIf, regA uint32) int {\n\treturn jumpIfCommon(ins.Cond, ins.SkipTrue, ins.SkipFalse, regA, ins.Val)\n}\n\nfunc jumpIfX(ins JumpIfX, regA uint32, regX uint32) int {\n\treturn jumpIfCommon(ins.Cond, ins.SkipTrue, ins.SkipFalse, regA, regX)\n}\n\nfunc jumpIfCommon(cond JumpTest, skipTrue, skipFalse uint8, regA uint32, value uint32) int {\n\tvar ok bool\n\n\tswitch cond {\n\tcase JumpEqual:\n\t\tok = regA == value\n\tcase JumpNotEqual:\n\t\tok = regA != value\n\tcase JumpGreaterThan:\n\t\tok = regA > value\n\tcase JumpLessThan:\n\t\tok = regA < value\n\tcase JumpGreaterOrEqual:\n\t\tok = regA >= value\n\tcase JumpLessOrEqual:\n\t\tok = regA <= value\n\tcase JumpBitsSet:\n\t\tok = (regA & value) != 0\n\tcase JumpBitsNotSet:\n\t\tok = (regA & value) == 0\n\t}\n\n\tif ok {\n\t\treturn int(skipTrue)\n\t}\n\n\treturn int(skipFalse)\n}\n\nfunc loadAbsolute(ins LoadAbsolute, in []byte) (uint32, bool) {\n\toffset := int(ins.Off)\n\tsize := ins.Size\n\n\treturn loadCommon(in, offset, size)\n}\n\nfunc loadConstant(ins LoadConstant, regA uint32, regX uint32) (uint32, uint32) {\n\tswitch ins.Dst {\n\tcase RegA:\n\t\tregA = ins.Val\n\tcase RegX:\n\t\tregX = ins.Val\n\t}\n\n\treturn regA, regX\n}\n\nfunc loadExtension(ins LoadExtension, in []byte) uint32 {\n\tswitch ins.Num {\n\tcase ExtLen:\n\t\treturn uint32(len(in))\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unimplemented extension: %d\", ins.Num))\n\t}\n}\n\nfunc loadIndirect(ins LoadIndirect, in []byte, regX uint32) (uint32, bool) {\n\toffset := int(ins.Off) + int(regX)\n\tsize := ins.Size\n\n\treturn loadCommon(in, offset, size)\n}\n\nfunc loadMemShift(ins LoadMemShift, in []byte) (uint32, bool) {\n\toffset := int(ins.Off)\n\n\t// Size of LoadMemShift is always 1 byte\n\tif !inBounds(len(in), offset, 1) {\n\t\treturn 0, false\n\t}\n\n\t// Mask off high 4 bits and multiply low 4 bits by 4\n\treturn uint32(in[offset]&0x0f) * 4, true\n}\n\nfunc inBounds(inLen int, offset int, size int) bool {\n\treturn offset+size <= inLen\n}\n\nfunc loadCommon(in []byte, offset int, size int) (uint32, bool) {\n\tif !inBounds(len(in), offset, size) {\n\t\treturn 0, false\n\t}\n\n\tswitch size {\n\tcase 1:\n\t\treturn uint32(in[offset]), true\n\tcase 2:\n\t\treturn uint32(binary.BigEndian.Uint16(in[offset : offset+size])), true\n\tcase 4:\n\t\treturn uint32(binary.BigEndian.Uint32(in[offset : offset+size])), true\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"invalid load size: %d\", size))\n\t}\n}\n\nfunc loadScratch(ins LoadScratch, regScratch [16]uint32, regA uint32, regX uint32) (uint32, uint32) {\n\tswitch ins.Dst {\n\tcase RegA:\n\t\tregA = regScratch[ins.N]\n\tcase RegX:\n\t\tregX = regScratch[ins.N]\n\t}\n\n\treturn regA, regX\n}\n\nfunc storeScratch(ins StoreScratch, regScratch [16]uint32, regA uint32, regX uint32) [16]uint32 {\n\tswitch ins.Src {\n\tcase RegA:\n\t\tregScratch[ins.N] = regA\n\tcase RegX:\n\t\tregScratch[ins.N] = regX\n\t}\n\n\treturn regScratch\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/context/context.go",
    "content": "// Copyright 2014 The Go 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\n// Package context defines the Context type, which carries deadlines,\n// cancellation signals, and other request-scoped values across API boundaries\n// and between processes.\n// As of Go 1.7 this package is available in the standard library under the\n// name [context], and migrating to it can be done automatically with [go fix].\n//\n// Incoming requests to a server should create a [Context], and outgoing\n// calls to servers should accept a Context. The chain of function\n// calls between them must propagate the Context, optionally replacing\n// it with a derived Context created using [WithCancel], [WithDeadline],\n// [WithTimeout], or [WithValue].\n//\n// Programs that use Contexts should follow these rules to keep interfaces\n// consistent across packages and enable static analysis tools to check context\n// propagation:\n//\n// Do not store Contexts inside a struct type; instead, pass a Context\n// explicitly to each function that needs it. This is discussed further in\n// https://go.dev/blog/context-and-structs. The Context should be the first\n// parameter, typically named ctx:\n//\n//\tfunc DoSomething(ctx context.Context, arg Arg) error {\n//\t\t// ... use ctx ...\n//\t}\n//\n// Do not pass a nil [Context], even if a function permits it. Pass [context.TODO]\n// if you are unsure about which Context to use.\n//\n// Use context Values only for request-scoped data that transits processes and\n// APIs, not for passing optional parameters to functions.\n//\n// The same Context may be passed to functions running in different goroutines;\n// Contexts are safe for simultaneous use by multiple goroutines.\n//\n// See https://go.dev/blog/context for example code for a server that uses\n// Contexts.\n//\n// [go fix]: https://go.dev/cmd/go#hdr-Update_packages_to_use_new_APIs\npackage context\n\nimport (\n\t\"context\" // standard library's context, as of Go 1.7\n\t\"time\"\n)\n\n// A Context carries a deadline, a cancellation signal, and other values across\n// API boundaries.\n//\n// Context's methods may be called by multiple goroutines simultaneously.\ntype Context = context.Context\n\n// Canceled is the error returned by [Context.Err] when the context is canceled\n// for some reason other than its deadline passing.\nvar Canceled = context.Canceled\n\n// DeadlineExceeded is the error returned by [Context.Err] when the context is canceled\n// due to its deadline passing.\nvar DeadlineExceeded = context.DeadlineExceeded\n\n// Background returns a non-nil, empty Context. It is never canceled, has no\n// values, and has no deadline. It is typically used by the main function,\n// initialization, and tests, and as the top-level Context for incoming\n// requests.\nfunc Background() Context {\n\treturn background\n}\n\n// TODO returns a non-nil, empty Context. Code should use context.TODO when\n// it's unclear which Context to use or it is not yet available (because the\n// surrounding function has not yet been extended to accept a Context\n// parameter).\nfunc TODO() Context {\n\treturn todo\n}\n\nvar (\n\tbackground = context.Background()\n\ttodo       = context.TODO()\n)\n\n// A CancelFunc tells an operation to abandon its work.\n// A CancelFunc does not wait for the work to stop.\n// A CancelFunc may be called by multiple goroutines simultaneously.\n// After the first call, subsequent calls to a CancelFunc do nothing.\ntype CancelFunc = context.CancelFunc\n\n// WithCancel returns a derived context that points to the parent context\n// but has a new Done channel. The returned context's Done channel is closed\n// when the returned cancel function is called or when the parent context's\n// Done channel is closed, whichever happens first.\n//\n// Canceling this context releases resources associated with it, so code should\n// call cancel as soon as the operations running in this [Context] complete.\nfunc WithCancel(parent Context) (ctx Context, cancel CancelFunc) {\n\treturn context.WithCancel(parent)\n}\n\n// WithDeadline returns a derived context that points to the parent context\n// but has the deadline adjusted to be no later than d. If the parent's\n// deadline is already earlier than d, WithDeadline(parent, d) is semantically\n// equivalent to parent. The returned [Context.Done] channel is closed when\n// the deadline expires, when the returned cancel function is called,\n// or when the parent context's Done channel is closed, whichever happens first.\n//\n// Canceling this context releases resources associated with it, so code should\n// call cancel as soon as the operations running in this [Context] complete.\nfunc WithDeadline(parent Context, d time.Time) (Context, CancelFunc) {\n\treturn context.WithDeadline(parent, d)\n}\n\n// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).\n//\n// Canceling this context releases resources associated with it, so code should\n// call cancel as soon as the operations running in this [Context] complete:\n//\n//\tfunc slowOperationWithTimeout(ctx context.Context) (Result, error) {\n//\t\tctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)\n//\t\tdefer cancel()  // releases resources if slowOperation completes before timeout elapses\n//\t\treturn slowOperation(ctx)\n//\t}\nfunc WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {\n\treturn context.WithTimeout(parent, timeout)\n}\n\n// WithValue returns a derived context that points to the parent Context.\n// In the derived context, the value associated with key is val.\n//\n// Use context Values only for request-scoped data that transits processes and\n// APIs, not for passing optional parameters to functions.\n//\n// The provided key must be comparable and should not be of type\n// string or any other built-in type to avoid collisions between\n// packages using context. Users of WithValue should define their own\n// types for keys. To avoid allocating when assigning to an\n// interface{}, context keys often have concrete type\n// struct{}. Alternatively, exported context key variables' static\n// type should be a pointer or interface.\nfunc WithValue(parent Context, key, val interface{}) Context {\n\treturn context.WithValue(parent, key, val)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http/httpguts/guts.go",
    "content": "// Copyright 2018 The Go 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\n// Package httpguts provides functions implementing various details\n// of the HTTP specification.\n//\n// This package is shared by the standard library (which vendors it)\n// and x/net/http2. It comes with no API stability promise.\npackage httpguts\n\nimport (\n\t\"net/textproto\"\n\t\"strings\"\n)\n\n// ValidTrailerHeader reports whether name is a valid header field name to appear\n// in trailers.\n// See RFC 7230, Section 4.1.2\nfunc ValidTrailerHeader(name string) bool {\n\tname = textproto.CanonicalMIMEHeaderKey(name)\n\tif strings.HasPrefix(name, \"If-\") || badTrailer[name] {\n\t\treturn false\n\t}\n\treturn true\n}\n\nvar badTrailer = map[string]bool{\n\t\"Authorization\":       true,\n\t\"Cache-Control\":       true,\n\t\"Connection\":          true,\n\t\"Content-Encoding\":    true,\n\t\"Content-Length\":      true,\n\t\"Content-Range\":       true,\n\t\"Content-Type\":        true,\n\t\"Expect\":              true,\n\t\"Host\":                true,\n\t\"Keep-Alive\":          true,\n\t\"Max-Forwards\":        true,\n\t\"Pragma\":              true,\n\t\"Proxy-Authenticate\":  true,\n\t\"Proxy-Authorization\": true,\n\t\"Proxy-Connection\":    true,\n\t\"Range\":               true,\n\t\"Realm\":               true,\n\t\"Te\":                  true,\n\t\"Trailer\":             true,\n\t\"Transfer-Encoding\":   true,\n\t\"Www-Authenticate\":    true,\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http/httpguts/httplex.go",
    "content": "// Copyright 2016 The Go 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 httpguts\n\nimport (\n\t\"net\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"golang.org/x/net/idna\"\n)\n\nvar isTokenTable = [256]bool{\n\t'!':  true,\n\t'#':  true,\n\t'$':  true,\n\t'%':  true,\n\t'&':  true,\n\t'\\'': true,\n\t'*':  true,\n\t'+':  true,\n\t'-':  true,\n\t'.':  true,\n\t'0':  true,\n\t'1':  true,\n\t'2':  true,\n\t'3':  true,\n\t'4':  true,\n\t'5':  true,\n\t'6':  true,\n\t'7':  true,\n\t'8':  true,\n\t'9':  true,\n\t'A':  true,\n\t'B':  true,\n\t'C':  true,\n\t'D':  true,\n\t'E':  true,\n\t'F':  true,\n\t'G':  true,\n\t'H':  true,\n\t'I':  true,\n\t'J':  true,\n\t'K':  true,\n\t'L':  true,\n\t'M':  true,\n\t'N':  true,\n\t'O':  true,\n\t'P':  true,\n\t'Q':  true,\n\t'R':  true,\n\t'S':  true,\n\t'T':  true,\n\t'U':  true,\n\t'W':  true,\n\t'V':  true,\n\t'X':  true,\n\t'Y':  true,\n\t'Z':  true,\n\t'^':  true,\n\t'_':  true,\n\t'`':  true,\n\t'a':  true,\n\t'b':  true,\n\t'c':  true,\n\t'd':  true,\n\t'e':  true,\n\t'f':  true,\n\t'g':  true,\n\t'h':  true,\n\t'i':  true,\n\t'j':  true,\n\t'k':  true,\n\t'l':  true,\n\t'm':  true,\n\t'n':  true,\n\t'o':  true,\n\t'p':  true,\n\t'q':  true,\n\t'r':  true,\n\t's':  true,\n\t't':  true,\n\t'u':  true,\n\t'v':  true,\n\t'w':  true,\n\t'x':  true,\n\t'y':  true,\n\t'z':  true,\n\t'|':  true,\n\t'~':  true,\n}\n\nfunc IsTokenRune(r rune) bool {\n\treturn r < utf8.RuneSelf && isTokenTable[byte(r)]\n}\n\n// HeaderValuesContainsToken reports whether any string in values\n// contains the provided token, ASCII case-insensitively.\nfunc HeaderValuesContainsToken(values []string, token string) bool {\n\tfor _, v := range values {\n\t\tif headerValueContainsToken(v, token) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// isOWS reports whether b is an optional whitespace byte, as defined\n// by RFC 7230 section 3.2.3.\nfunc isOWS(b byte) bool { return b == ' ' || b == '\\t' }\n\n// trimOWS returns x with all optional whitespace removes from the\n// beginning and end.\nfunc trimOWS(x string) string {\n\t// TODO: consider using strings.Trim(x, \" \\t\") instead,\n\t// if and when it's fast enough. See issue 10292.\n\t// But this ASCII-only code will probably always beat UTF-8\n\t// aware code.\n\tfor len(x) > 0 && isOWS(x[0]) {\n\t\tx = x[1:]\n\t}\n\tfor len(x) > 0 && isOWS(x[len(x)-1]) {\n\t\tx = x[:len(x)-1]\n\t}\n\treturn x\n}\n\n// headerValueContainsToken reports whether v (assumed to be a\n// 0#element, in the ABNF extension described in RFC 7230 section 7)\n// contains token amongst its comma-separated tokens, ASCII\n// case-insensitively.\nfunc headerValueContainsToken(v string, token string) bool {\n\tfor comma := strings.IndexByte(v, ','); comma != -1; comma = strings.IndexByte(v, ',') {\n\t\tif tokenEqual(trimOWS(v[:comma]), token) {\n\t\t\treturn true\n\t\t}\n\t\tv = v[comma+1:]\n\t}\n\treturn tokenEqual(trimOWS(v), token)\n}\n\n// lowerASCII returns the ASCII lowercase version of b.\nfunc lowerASCII(b byte) byte {\n\tif 'A' <= b && b <= 'Z' {\n\t\treturn b + ('a' - 'A')\n\t}\n\treturn b\n}\n\n// tokenEqual reports whether t1 and t2 are equal, ASCII case-insensitively.\nfunc tokenEqual(t1, t2 string) bool {\n\tif len(t1) != len(t2) {\n\t\treturn false\n\t}\n\tfor i, b := range t1 {\n\t\tif b >= utf8.RuneSelf {\n\t\t\t// No UTF-8 or non-ASCII allowed in tokens.\n\t\t\treturn false\n\t\t}\n\t\tif lowerASCII(byte(b)) != lowerASCII(t2[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// isLWS reports whether b is linear white space, according\n// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2\n//\n//\tLWS            = [CRLF] 1*( SP | HT )\nfunc isLWS(b byte) bool { return b == ' ' || b == '\\t' }\n\n// isCTL reports whether b is a control byte, according\n// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2\n//\n//\tCTL            = <any US-ASCII control character\n//\t                 (octets 0 - 31) and DEL (127)>\nfunc isCTL(b byte) bool {\n\tconst del = 0x7f // a CTL\n\treturn b < ' ' || b == del\n}\n\n// ValidHeaderFieldName reports whether v is a valid HTTP/1.x header name.\n// HTTP/2 imposes the additional restriction that uppercase ASCII\n// letters are not allowed.\n//\n// RFC 7230 says:\n//\n//\theader-field   = field-name \":\" OWS field-value OWS\n//\tfield-name     = token\n//\ttoken          = 1*tchar\n//\ttchar = \"!\" / \"#\" / \"$\" / \"%\" / \"&\" / \"'\" / \"*\" / \"+\" / \"-\" / \".\" /\n//\t        \"^\" / \"_\" / \"`\" / \"|\" / \"~\" / DIGIT / ALPHA\nfunc ValidHeaderFieldName(v string) bool {\n\tif len(v) == 0 {\n\t\treturn false\n\t}\n\tfor i := 0; i < len(v); i++ {\n\t\tif !isTokenTable[v[i]] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// ValidHostHeader reports whether h is a valid host header.\nfunc ValidHostHeader(h string) bool {\n\t// The latest spec is actually this:\n\t//\n\t// http://tools.ietf.org/html/rfc7230#section-5.4\n\t//     Host = uri-host [ \":\" port ]\n\t//\n\t// Where uri-host is:\n\t//     http://tools.ietf.org/html/rfc3986#section-3.2.2\n\t//\n\t// But we're going to be much more lenient for now and just\n\t// search for any byte that's not a valid byte in any of those\n\t// expressions.\n\tfor i := 0; i < len(h); i++ {\n\t\tif !validHostByte[h[i]] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// See the validHostHeader comment.\nvar validHostByte = [256]bool{\n\t'0': true, '1': true, '2': true, '3': true, '4': true, '5': true, '6': true, '7': true,\n\t'8': true, '9': true,\n\n\t'a': true, 'b': true, 'c': true, 'd': true, 'e': true, 'f': true, 'g': true, 'h': true,\n\t'i': true, 'j': true, 'k': true, 'l': true, 'm': true, 'n': true, 'o': true, 'p': true,\n\t'q': true, 'r': true, 's': true, 't': true, 'u': true, 'v': true, 'w': true, 'x': true,\n\t'y': true, 'z': true,\n\n\t'A': true, 'B': true, 'C': true, 'D': true, 'E': true, 'F': true, 'G': true, 'H': true,\n\t'I': true, 'J': true, 'K': true, 'L': true, 'M': true, 'N': true, 'O': true, 'P': true,\n\t'Q': true, 'R': true, 'S': true, 'T': true, 'U': true, 'V': true, 'W': true, 'X': true,\n\t'Y': true, 'Z': true,\n\n\t'!':  true, // sub-delims\n\t'$':  true, // sub-delims\n\t'%':  true, // pct-encoded (and used in IPv6 zones)\n\t'&':  true, // sub-delims\n\t'(':  true, // sub-delims\n\t')':  true, // sub-delims\n\t'*':  true, // sub-delims\n\t'+':  true, // sub-delims\n\t',':  true, // sub-delims\n\t'-':  true, // unreserved\n\t'.':  true, // unreserved\n\t':':  true, // IPv6address + Host expression's optional port\n\t';':  true, // sub-delims\n\t'=':  true, // sub-delims\n\t'[':  true,\n\t'\\'': true, // sub-delims\n\t']':  true,\n\t'_':  true, // unreserved\n\t'~':  true, // unreserved\n}\n\n// ValidHeaderFieldValue reports whether v is a valid \"field-value\" according to\n// http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 :\n//\n//\tmessage-header = field-name \":\" [ field-value ]\n//\tfield-value    = *( field-content | LWS )\n//\tfield-content  = <the OCTETs making up the field-value\n//\t                 and consisting of either *TEXT or combinations\n//\t                 of token, separators, and quoted-string>\n//\n// http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 :\n//\n//\tTEXT           = <any OCTET except CTLs,\n//\t                  but including LWS>\n//\tLWS            = [CRLF] 1*( SP | HT )\n//\tCTL            = <any US-ASCII control character\n//\t                 (octets 0 - 31) and DEL (127)>\n//\n// RFC 7230 says:\n//\n//\tfield-value    = *( field-content / obs-fold )\n//\tobj-fold       =  N/A to http2, and deprecated\n//\tfield-content  = field-vchar [ 1*( SP / HTAB ) field-vchar ]\n//\tfield-vchar    = VCHAR / obs-text\n//\tobs-text       = %x80-FF\n//\tVCHAR          = \"any visible [USASCII] character\"\n//\n// http2 further says: \"Similarly, HTTP/2 allows header field values\n// that are not valid. While most of the values that can be encoded\n// will not alter header field parsing, carriage return (CR, ASCII\n// 0xd), line feed (LF, ASCII 0xa), and the zero character (NUL, ASCII\n// 0x0) might be exploited by an attacker if they are translated\n// verbatim. Any request or response that contains a character not\n// permitted in a header field value MUST be treated as malformed\n// (Section 8.1.2.6). Valid characters are defined by the\n// field-content ABNF rule in Section 3.2 of [RFC7230].\"\n//\n// This function does not (yet?) properly handle the rejection of\n// strings that begin or end with SP or HTAB.\nfunc ValidHeaderFieldValue(v string) bool {\n\tfor i := 0; i < len(v); i++ {\n\t\tb := v[i]\n\t\tif isCTL(b) && !isLWS(b) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc isASCII(s string) bool {\n\tfor i := 0; i < len(s); i++ {\n\t\tif s[i] >= utf8.RuneSelf {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// PunycodeHostPort returns the IDNA Punycode version\n// of the provided \"host\" or \"host:port\" string.\nfunc PunycodeHostPort(v string) (string, error) {\n\tif isASCII(v) {\n\t\treturn v, nil\n\t}\n\n\thost, port, err := net.SplitHostPort(v)\n\tif err != nil {\n\t\t// The input 'v' argument was just a \"host\" argument,\n\t\t// without a port. This error should not be returned\n\t\t// to the caller.\n\t\thost = v\n\t\tport = \"\"\n\t}\n\thost, err = idna.ToASCII(host)\n\tif err != nil {\n\t\t// Non-UTF-8? Not representable in Punycode, in any\n\t\t// case.\n\t\treturn \"\", err\n\t}\n\tif port == \"\" {\n\t\treturn host, nil\n\t}\n\treturn net.JoinHostPort(host, port), nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/.gitignore",
    "content": "*~\nh2i/h2i\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/ascii.go",
    "content": "// Copyright 2021 The Go 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 http2\n\nimport \"strings\"\n\n// The HTTP protocols are defined in terms of ASCII, not Unicode. This file\n// contains helper functions which may use Unicode-aware functions which would\n// otherwise be unsafe and could introduce vulnerabilities if used improperly.\n\n// asciiEqualFold is strings.EqualFold, ASCII only. It reports whether s and t\n// are equal, ASCII-case-insensitively.\nfunc asciiEqualFold(s, t string) bool {\n\tif len(s) != len(t) {\n\t\treturn false\n\t}\n\tfor i := 0; i < len(s); i++ {\n\t\tif lower(s[i]) != lower(t[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// lower returns the ASCII lowercase version of b.\nfunc lower(b byte) byte {\n\tif 'A' <= b && b <= 'Z' {\n\t\treturn b + ('a' - 'A')\n\t}\n\treturn b\n}\n\n// isASCIIPrint returns whether s is ASCII and printable according to\n// https://tools.ietf.org/html/rfc20#section-4.2.\nfunc isASCIIPrint(s string) bool {\n\tfor i := 0; i < len(s); i++ {\n\t\tif s[i] < ' ' || s[i] > '~' {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// asciiToLower returns the lowercase version of s if s is ASCII and printable,\n// and whether or not it was.\nfunc asciiToLower(s string) (lower string, ok bool) {\n\tif !isASCIIPrint(s) {\n\t\treturn \"\", false\n\t}\n\treturn strings.ToLower(s), true\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/ciphers.go",
    "content": "// Copyright 2017 The Go 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 http2\n\n// A list of the possible cipher suite ids. Taken from\n// https://www.iana.org/assignments/tls-parameters/tls-parameters.txt\n\nconst (\n\tcipher_TLS_NULL_WITH_NULL_NULL               uint16 = 0x0000\n\tcipher_TLS_RSA_WITH_NULL_MD5                 uint16 = 0x0001\n\tcipher_TLS_RSA_WITH_NULL_SHA                 uint16 = 0x0002\n\tcipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5        uint16 = 0x0003\n\tcipher_TLS_RSA_WITH_RC4_128_MD5              uint16 = 0x0004\n\tcipher_TLS_RSA_WITH_RC4_128_SHA              uint16 = 0x0005\n\tcipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5    uint16 = 0x0006\n\tcipher_TLS_RSA_WITH_IDEA_CBC_SHA             uint16 = 0x0007\n\tcipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA     uint16 = 0x0008\n\tcipher_TLS_RSA_WITH_DES_CBC_SHA              uint16 = 0x0009\n\tcipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA         uint16 = 0x000A\n\tcipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA  uint16 = 0x000B\n\tcipher_TLS_DH_DSS_WITH_DES_CBC_SHA           uint16 = 0x000C\n\tcipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA      uint16 = 0x000D\n\tcipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA  uint16 = 0x000E\n\tcipher_TLS_DH_RSA_WITH_DES_CBC_SHA           uint16 = 0x000F\n\tcipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA      uint16 = 0x0010\n\tcipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0011\n\tcipher_TLS_DHE_DSS_WITH_DES_CBC_SHA          uint16 = 0x0012\n\tcipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA     uint16 = 0x0013\n\tcipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0014\n\tcipher_TLS_DHE_RSA_WITH_DES_CBC_SHA          uint16 = 0x0015\n\tcipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA     uint16 = 0x0016\n\tcipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5    uint16 = 0x0017\n\tcipher_TLS_DH_anon_WITH_RC4_128_MD5          uint16 = 0x0018\n\tcipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0019\n\tcipher_TLS_DH_anon_WITH_DES_CBC_SHA          uint16 = 0x001A\n\tcipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA     uint16 = 0x001B\n\t// Reserved uint16 =  0x001C-1D\n\tcipher_TLS_KRB5_WITH_DES_CBC_SHA             uint16 = 0x001E\n\tcipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA        uint16 = 0x001F\n\tcipher_TLS_KRB5_WITH_RC4_128_SHA             uint16 = 0x0020\n\tcipher_TLS_KRB5_WITH_IDEA_CBC_SHA            uint16 = 0x0021\n\tcipher_TLS_KRB5_WITH_DES_CBC_MD5             uint16 = 0x0022\n\tcipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5        uint16 = 0x0023\n\tcipher_TLS_KRB5_WITH_RC4_128_MD5             uint16 = 0x0024\n\tcipher_TLS_KRB5_WITH_IDEA_CBC_MD5            uint16 = 0x0025\n\tcipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA   uint16 = 0x0026\n\tcipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA   uint16 = 0x0027\n\tcipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA       uint16 = 0x0028\n\tcipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5   uint16 = 0x0029\n\tcipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5   uint16 = 0x002A\n\tcipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5       uint16 = 0x002B\n\tcipher_TLS_PSK_WITH_NULL_SHA                 uint16 = 0x002C\n\tcipher_TLS_DHE_PSK_WITH_NULL_SHA             uint16 = 0x002D\n\tcipher_TLS_RSA_PSK_WITH_NULL_SHA             uint16 = 0x002E\n\tcipher_TLS_RSA_WITH_AES_128_CBC_SHA          uint16 = 0x002F\n\tcipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA       uint16 = 0x0030\n\tcipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA       uint16 = 0x0031\n\tcipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA      uint16 = 0x0032\n\tcipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA      uint16 = 0x0033\n\tcipher_TLS_DH_anon_WITH_AES_128_CBC_SHA      uint16 = 0x0034\n\tcipher_TLS_RSA_WITH_AES_256_CBC_SHA          uint16 = 0x0035\n\tcipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA       uint16 = 0x0036\n\tcipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA       uint16 = 0x0037\n\tcipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA      uint16 = 0x0038\n\tcipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA      uint16 = 0x0039\n\tcipher_TLS_DH_anon_WITH_AES_256_CBC_SHA      uint16 = 0x003A\n\tcipher_TLS_RSA_WITH_NULL_SHA256              uint16 = 0x003B\n\tcipher_TLS_RSA_WITH_AES_128_CBC_SHA256       uint16 = 0x003C\n\tcipher_TLS_RSA_WITH_AES_256_CBC_SHA256       uint16 = 0x003D\n\tcipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256    uint16 = 0x003E\n\tcipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256    uint16 = 0x003F\n\tcipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256   uint16 = 0x0040\n\tcipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA     uint16 = 0x0041\n\tcipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA  uint16 = 0x0042\n\tcipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA  uint16 = 0x0043\n\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0044\n\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0045\n\tcipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0046\n\t// Reserved uint16 =  0x0047-4F\n\t// Reserved uint16 =  0x0050-58\n\t// Reserved uint16 =  0x0059-5C\n\t// Unassigned uint16 =  0x005D-5F\n\t// Reserved uint16 =  0x0060-66\n\tcipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x0067\n\tcipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256  uint16 = 0x0068\n\tcipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256  uint16 = 0x0069\n\tcipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 uint16 = 0x006A\n\tcipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x006B\n\tcipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256 uint16 = 0x006C\n\tcipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256 uint16 = 0x006D\n\t// Unassigned uint16 =  0x006E-83\n\tcipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA        uint16 = 0x0084\n\tcipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA     uint16 = 0x0085\n\tcipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA     uint16 = 0x0086\n\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA    uint16 = 0x0087\n\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA    uint16 = 0x0088\n\tcipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA    uint16 = 0x0089\n\tcipher_TLS_PSK_WITH_RC4_128_SHA                 uint16 = 0x008A\n\tcipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA            uint16 = 0x008B\n\tcipher_TLS_PSK_WITH_AES_128_CBC_SHA             uint16 = 0x008C\n\tcipher_TLS_PSK_WITH_AES_256_CBC_SHA             uint16 = 0x008D\n\tcipher_TLS_DHE_PSK_WITH_RC4_128_SHA             uint16 = 0x008E\n\tcipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA        uint16 = 0x008F\n\tcipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA         uint16 = 0x0090\n\tcipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA         uint16 = 0x0091\n\tcipher_TLS_RSA_PSK_WITH_RC4_128_SHA             uint16 = 0x0092\n\tcipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA        uint16 = 0x0093\n\tcipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA         uint16 = 0x0094\n\tcipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA         uint16 = 0x0095\n\tcipher_TLS_RSA_WITH_SEED_CBC_SHA                uint16 = 0x0096\n\tcipher_TLS_DH_DSS_WITH_SEED_CBC_SHA             uint16 = 0x0097\n\tcipher_TLS_DH_RSA_WITH_SEED_CBC_SHA             uint16 = 0x0098\n\tcipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA            uint16 = 0x0099\n\tcipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA            uint16 = 0x009A\n\tcipher_TLS_DH_anon_WITH_SEED_CBC_SHA            uint16 = 0x009B\n\tcipher_TLS_RSA_WITH_AES_128_GCM_SHA256          uint16 = 0x009C\n\tcipher_TLS_RSA_WITH_AES_256_GCM_SHA384          uint16 = 0x009D\n\tcipher_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256      uint16 = 0x009E\n\tcipher_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384      uint16 = 0x009F\n\tcipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256       uint16 = 0x00A0\n\tcipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384       uint16 = 0x00A1\n\tcipher_TLS_DHE_DSS_WITH_AES_128_GCM_SHA256      uint16 = 0x00A2\n\tcipher_TLS_DHE_DSS_WITH_AES_256_GCM_SHA384      uint16 = 0x00A3\n\tcipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256       uint16 = 0x00A4\n\tcipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384       uint16 = 0x00A5\n\tcipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256      uint16 = 0x00A6\n\tcipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384      uint16 = 0x00A7\n\tcipher_TLS_PSK_WITH_AES_128_GCM_SHA256          uint16 = 0x00A8\n\tcipher_TLS_PSK_WITH_AES_256_GCM_SHA384          uint16 = 0x00A9\n\tcipher_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256      uint16 = 0x00AA\n\tcipher_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384      uint16 = 0x00AB\n\tcipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256      uint16 = 0x00AC\n\tcipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384      uint16 = 0x00AD\n\tcipher_TLS_PSK_WITH_AES_128_CBC_SHA256          uint16 = 0x00AE\n\tcipher_TLS_PSK_WITH_AES_256_CBC_SHA384          uint16 = 0x00AF\n\tcipher_TLS_PSK_WITH_NULL_SHA256                 uint16 = 0x00B0\n\tcipher_TLS_PSK_WITH_NULL_SHA384                 uint16 = 0x00B1\n\tcipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256      uint16 = 0x00B2\n\tcipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384      uint16 = 0x00B3\n\tcipher_TLS_DHE_PSK_WITH_NULL_SHA256             uint16 = 0x00B4\n\tcipher_TLS_DHE_PSK_WITH_NULL_SHA384             uint16 = 0x00B5\n\tcipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256      uint16 = 0x00B6\n\tcipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384      uint16 = 0x00B7\n\tcipher_TLS_RSA_PSK_WITH_NULL_SHA256             uint16 = 0x00B8\n\tcipher_TLS_RSA_PSK_WITH_NULL_SHA384             uint16 = 0x00B9\n\tcipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256     uint16 = 0x00BA\n\tcipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256  uint16 = 0x00BB\n\tcipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256  uint16 = 0x00BC\n\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BD\n\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BE\n\tcipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BF\n\tcipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256     uint16 = 0x00C0\n\tcipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256  uint16 = 0x00C1\n\tcipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256  uint16 = 0x00C2\n\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C3\n\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C4\n\tcipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C5\n\t// Unassigned uint16 =  0x00C6-FE\n\tcipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV uint16 = 0x00FF\n\t// Unassigned uint16 =  0x01-55,*\n\tcipher_TLS_FALLBACK_SCSV uint16 = 0x5600\n\t// Unassigned                                   uint16 = 0x5601 - 0xC000\n\tcipher_TLS_ECDH_ECDSA_WITH_NULL_SHA                 uint16 = 0xC001\n\tcipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA              uint16 = 0xC002\n\tcipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA         uint16 = 0xC003\n\tcipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA          uint16 = 0xC004\n\tcipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA          uint16 = 0xC005\n\tcipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA                uint16 = 0xC006\n\tcipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA             uint16 = 0xC007\n\tcipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA        uint16 = 0xC008\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA         uint16 = 0xC009\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA         uint16 = 0xC00A\n\tcipher_TLS_ECDH_RSA_WITH_NULL_SHA                   uint16 = 0xC00B\n\tcipher_TLS_ECDH_RSA_WITH_RC4_128_SHA                uint16 = 0xC00C\n\tcipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA           uint16 = 0xC00D\n\tcipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA            uint16 = 0xC00E\n\tcipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA            uint16 = 0xC00F\n\tcipher_TLS_ECDHE_RSA_WITH_NULL_SHA                  uint16 = 0xC010\n\tcipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA               uint16 = 0xC011\n\tcipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA          uint16 = 0xC012\n\tcipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA           uint16 = 0xC013\n\tcipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA           uint16 = 0xC014\n\tcipher_TLS_ECDH_anon_WITH_NULL_SHA                  uint16 = 0xC015\n\tcipher_TLS_ECDH_anon_WITH_RC4_128_SHA               uint16 = 0xC016\n\tcipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA          uint16 = 0xC017\n\tcipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA           uint16 = 0xC018\n\tcipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA           uint16 = 0xC019\n\tcipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA            uint16 = 0xC01A\n\tcipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA        uint16 = 0xC01B\n\tcipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA        uint16 = 0xC01C\n\tcipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA             uint16 = 0xC01D\n\tcipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA         uint16 = 0xC01E\n\tcipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA         uint16 = 0xC01F\n\tcipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA             uint16 = 0xC020\n\tcipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA         uint16 = 0xC021\n\tcipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA         uint16 = 0xC022\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256      uint16 = 0xC023\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384      uint16 = 0xC024\n\tcipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256       uint16 = 0xC025\n\tcipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384       uint16 = 0xC026\n\tcipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256        uint16 = 0xC027\n\tcipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384        uint16 = 0xC028\n\tcipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256         uint16 = 0xC029\n\tcipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384         uint16 = 0xC02A\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256      uint16 = 0xC02B\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384      uint16 = 0xC02C\n\tcipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256       uint16 = 0xC02D\n\tcipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384       uint16 = 0xC02E\n\tcipher_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256        uint16 = 0xC02F\n\tcipher_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384        uint16 = 0xC030\n\tcipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256         uint16 = 0xC031\n\tcipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384         uint16 = 0xC032\n\tcipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA               uint16 = 0xC033\n\tcipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA          uint16 = 0xC034\n\tcipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA           uint16 = 0xC035\n\tcipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA           uint16 = 0xC036\n\tcipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256        uint16 = 0xC037\n\tcipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384        uint16 = 0xC038\n\tcipher_TLS_ECDHE_PSK_WITH_NULL_SHA                  uint16 = 0xC039\n\tcipher_TLS_ECDHE_PSK_WITH_NULL_SHA256               uint16 = 0xC03A\n\tcipher_TLS_ECDHE_PSK_WITH_NULL_SHA384               uint16 = 0xC03B\n\tcipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256             uint16 = 0xC03C\n\tcipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384             uint16 = 0xC03D\n\tcipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256          uint16 = 0xC03E\n\tcipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384          uint16 = 0xC03F\n\tcipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256          uint16 = 0xC040\n\tcipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384          uint16 = 0xC041\n\tcipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256         uint16 = 0xC042\n\tcipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384         uint16 = 0xC043\n\tcipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256         uint16 = 0xC044\n\tcipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384         uint16 = 0xC045\n\tcipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256         uint16 = 0xC046\n\tcipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384         uint16 = 0xC047\n\tcipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256     uint16 = 0xC048\n\tcipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384     uint16 = 0xC049\n\tcipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256      uint16 = 0xC04A\n\tcipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384      uint16 = 0xC04B\n\tcipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256       uint16 = 0xC04C\n\tcipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384       uint16 = 0xC04D\n\tcipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256        uint16 = 0xC04E\n\tcipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384        uint16 = 0xC04F\n\tcipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256             uint16 = 0xC050\n\tcipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384             uint16 = 0xC051\n\tcipher_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256         uint16 = 0xC052\n\tcipher_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384         uint16 = 0xC053\n\tcipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256          uint16 = 0xC054\n\tcipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384          uint16 = 0xC055\n\tcipher_TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256         uint16 = 0xC056\n\tcipher_TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384         uint16 = 0xC057\n\tcipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256          uint16 = 0xC058\n\tcipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384          uint16 = 0xC059\n\tcipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256         uint16 = 0xC05A\n\tcipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384         uint16 = 0xC05B\n\tcipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256     uint16 = 0xC05C\n\tcipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384     uint16 = 0xC05D\n\tcipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256      uint16 = 0xC05E\n\tcipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384      uint16 = 0xC05F\n\tcipher_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256       uint16 = 0xC060\n\tcipher_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384       uint16 = 0xC061\n\tcipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256        uint16 = 0xC062\n\tcipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384        uint16 = 0xC063\n\tcipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256             uint16 = 0xC064\n\tcipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384             uint16 = 0xC065\n\tcipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256         uint16 = 0xC066\n\tcipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384         uint16 = 0xC067\n\tcipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256         uint16 = 0xC068\n\tcipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384         uint16 = 0xC069\n\tcipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256             uint16 = 0xC06A\n\tcipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384             uint16 = 0xC06B\n\tcipher_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256         uint16 = 0xC06C\n\tcipher_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384         uint16 = 0xC06D\n\tcipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256         uint16 = 0xC06E\n\tcipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384         uint16 = 0xC06F\n\tcipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256       uint16 = 0xC070\n\tcipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384       uint16 = 0xC071\n\tcipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC072\n\tcipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC073\n\tcipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256  uint16 = 0xC074\n\tcipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384  uint16 = 0xC075\n\tcipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256   uint16 = 0xC076\n\tcipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384   uint16 = 0xC077\n\tcipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256    uint16 = 0xC078\n\tcipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384    uint16 = 0xC079\n\tcipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256         uint16 = 0xC07A\n\tcipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384         uint16 = 0xC07B\n\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256     uint16 = 0xC07C\n\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384     uint16 = 0xC07D\n\tcipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256      uint16 = 0xC07E\n\tcipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384      uint16 = 0xC07F\n\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256     uint16 = 0xC080\n\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384     uint16 = 0xC081\n\tcipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256      uint16 = 0xC082\n\tcipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384      uint16 = 0xC083\n\tcipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256     uint16 = 0xC084\n\tcipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384     uint16 = 0xC085\n\tcipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC086\n\tcipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC087\n\tcipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256  uint16 = 0xC088\n\tcipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384  uint16 = 0xC089\n\tcipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256   uint16 = 0xC08A\n\tcipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384   uint16 = 0xC08B\n\tcipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256    uint16 = 0xC08C\n\tcipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384    uint16 = 0xC08D\n\tcipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256         uint16 = 0xC08E\n\tcipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384         uint16 = 0xC08F\n\tcipher_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256     uint16 = 0xC090\n\tcipher_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384     uint16 = 0xC091\n\tcipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256     uint16 = 0xC092\n\tcipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384     uint16 = 0xC093\n\tcipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256         uint16 = 0xC094\n\tcipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384         uint16 = 0xC095\n\tcipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256     uint16 = 0xC096\n\tcipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384     uint16 = 0xC097\n\tcipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256     uint16 = 0xC098\n\tcipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384     uint16 = 0xC099\n\tcipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256   uint16 = 0xC09A\n\tcipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384   uint16 = 0xC09B\n\tcipher_TLS_RSA_WITH_AES_128_CCM                     uint16 = 0xC09C\n\tcipher_TLS_RSA_WITH_AES_256_CCM                     uint16 = 0xC09D\n\tcipher_TLS_DHE_RSA_WITH_AES_128_CCM                 uint16 = 0xC09E\n\tcipher_TLS_DHE_RSA_WITH_AES_256_CCM                 uint16 = 0xC09F\n\tcipher_TLS_RSA_WITH_AES_128_CCM_8                   uint16 = 0xC0A0\n\tcipher_TLS_RSA_WITH_AES_256_CCM_8                   uint16 = 0xC0A1\n\tcipher_TLS_DHE_RSA_WITH_AES_128_CCM_8               uint16 = 0xC0A2\n\tcipher_TLS_DHE_RSA_WITH_AES_256_CCM_8               uint16 = 0xC0A3\n\tcipher_TLS_PSK_WITH_AES_128_CCM                     uint16 = 0xC0A4\n\tcipher_TLS_PSK_WITH_AES_256_CCM                     uint16 = 0xC0A5\n\tcipher_TLS_DHE_PSK_WITH_AES_128_CCM                 uint16 = 0xC0A6\n\tcipher_TLS_DHE_PSK_WITH_AES_256_CCM                 uint16 = 0xC0A7\n\tcipher_TLS_PSK_WITH_AES_128_CCM_8                   uint16 = 0xC0A8\n\tcipher_TLS_PSK_WITH_AES_256_CCM_8                   uint16 = 0xC0A9\n\tcipher_TLS_PSK_DHE_WITH_AES_128_CCM_8               uint16 = 0xC0AA\n\tcipher_TLS_PSK_DHE_WITH_AES_256_CCM_8               uint16 = 0xC0AB\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM             uint16 = 0xC0AC\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM             uint16 = 0xC0AD\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8           uint16 = 0xC0AE\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8           uint16 = 0xC0AF\n\t// Unassigned uint16 =  0xC0B0-FF\n\t// Unassigned uint16 =  0xC1-CB,*\n\t// Unassigned uint16 =  0xCC00-A7\n\tcipher_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256   uint16 = 0xCCA8\n\tcipher_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCA9\n\tcipher_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256     uint16 = 0xCCAA\n\tcipher_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256         uint16 = 0xCCAB\n\tcipher_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256   uint16 = 0xCCAC\n\tcipher_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256     uint16 = 0xCCAD\n\tcipher_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256     uint16 = 0xCCAE\n)\n\n// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec.\n// References:\n// https://tools.ietf.org/html/rfc7540#appendix-A\n// Reject cipher suites from Appendix A.\n// \"This list includes those cipher suites that do not\n// offer an ephemeral key exchange and those that are\n// based on the TLS null, stream or block cipher type\"\nfunc isBadCipher(cipher uint16) bool {\n\tswitch cipher {\n\tcase cipher_TLS_NULL_WITH_NULL_NULL,\n\t\tcipher_TLS_RSA_WITH_NULL_MD5,\n\t\tcipher_TLS_RSA_WITH_NULL_SHA,\n\t\tcipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5,\n\t\tcipher_TLS_RSA_WITH_RC4_128_MD5,\n\t\tcipher_TLS_RSA_WITH_RC4_128_SHA,\n\t\tcipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,\n\t\tcipher_TLS_RSA_WITH_IDEA_CBC_SHA,\n\t\tcipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,\n\t\tcipher_TLS_RSA_WITH_DES_CBC_SHA,\n\t\tcipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,\n\t\tcipher_TLS_DH_DSS_WITH_DES_CBC_SHA,\n\t\tcipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,\n\t\tcipher_TLS_DH_RSA_WITH_DES_CBC_SHA,\n\t\tcipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,\n\t\tcipher_TLS_DHE_DSS_WITH_DES_CBC_SHA,\n\t\tcipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_WITH_DES_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5,\n\t\tcipher_TLS_DH_anon_WITH_RC4_128_MD5,\n\t\tcipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA,\n\t\tcipher_TLS_DH_anon_WITH_DES_CBC_SHA,\n\t\tcipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_KRB5_WITH_DES_CBC_SHA,\n\t\tcipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_KRB5_WITH_RC4_128_SHA,\n\t\tcipher_TLS_KRB5_WITH_IDEA_CBC_SHA,\n\t\tcipher_TLS_KRB5_WITH_DES_CBC_MD5,\n\t\tcipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5,\n\t\tcipher_TLS_KRB5_WITH_RC4_128_MD5,\n\t\tcipher_TLS_KRB5_WITH_IDEA_CBC_MD5,\n\t\tcipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA,\n\t\tcipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA,\n\t\tcipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA,\n\t\tcipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5,\n\t\tcipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5,\n\t\tcipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5,\n\t\tcipher_TLS_PSK_WITH_NULL_SHA,\n\t\tcipher_TLS_DHE_PSK_WITH_NULL_SHA,\n\t\tcipher_TLS_RSA_PSK_WITH_NULL_SHA,\n\t\tcipher_TLS_RSA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_DH_anon_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_RSA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_DH_anon_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_RSA_WITH_NULL_SHA256,\n\t\tcipher_TLS_RSA_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_RSA_WITH_AES_256_CBC_SHA256,\n\t\tcipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,\n\t\tcipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA,\n\t\tcipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA,\n\t\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,\n\t\tcipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256,\n\t\tcipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256,\n\t\tcipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,\n\t\tcipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,\n\t\tcipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256,\n\t\tcipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,\n\t\tcipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA,\n\t\tcipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA,\n\t\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,\n\t\tcipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA,\n\t\tcipher_TLS_PSK_WITH_RC4_128_SHA,\n\t\tcipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_PSK_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_PSK_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_DHE_PSK_WITH_RC4_128_SHA,\n\t\tcipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_RSA_PSK_WITH_RC4_128_SHA,\n\t\tcipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_RSA_WITH_SEED_CBC_SHA,\n\t\tcipher_TLS_DH_DSS_WITH_SEED_CBC_SHA,\n\t\tcipher_TLS_DH_RSA_WITH_SEED_CBC_SHA,\n\t\tcipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA,\n\t\tcipher_TLS_DH_anon_WITH_SEED_CBC_SHA,\n\t\tcipher_TLS_RSA_WITH_AES_128_GCM_SHA256,\n\t\tcipher_TLS_RSA_WITH_AES_256_GCM_SHA384,\n\t\tcipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256,\n\t\tcipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384,\n\t\tcipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256,\n\t\tcipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384,\n\t\tcipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256,\n\t\tcipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384,\n\t\tcipher_TLS_PSK_WITH_AES_128_GCM_SHA256,\n\t\tcipher_TLS_PSK_WITH_AES_256_GCM_SHA384,\n\t\tcipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,\n\t\tcipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,\n\t\tcipher_TLS_PSK_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_PSK_WITH_AES_256_CBC_SHA384,\n\t\tcipher_TLS_PSK_WITH_NULL_SHA256,\n\t\tcipher_TLS_PSK_WITH_NULL_SHA384,\n\t\tcipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,\n\t\tcipher_TLS_DHE_PSK_WITH_NULL_SHA256,\n\t\tcipher_TLS_DHE_PSK_WITH_NULL_SHA384,\n\t\tcipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,\n\t\tcipher_TLS_RSA_PSK_WITH_NULL_SHA256,\n\t\tcipher_TLS_RSA_PSK_WITH_NULL_SHA384,\n\t\tcipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,\n\t\tcipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256,\n\t\tcipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256,\n\t\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256,\n\t\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,\n\t\tcipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256,\n\t\tcipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_NULL_SHA,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_ECDH_RSA_WITH_NULL_SHA,\n\t\tcipher_TLS_ECDH_RSA_WITH_RC4_128_SHA,\n\t\tcipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_ECDHE_RSA_WITH_NULL_SHA,\n\t\tcipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA,\n\t\tcipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_ECDH_anon_WITH_NULL_SHA,\n\t\tcipher_TLS_ECDH_anon_WITH_RC4_128_SHA,\n\t\tcipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,\n\t\tcipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,\n\t\tcipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,\n\t\tcipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,\n\t\tcipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,\n\t\tcipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA,\n\t\tcipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,\n\t\tcipher_TLS_ECDHE_PSK_WITH_NULL_SHA,\n\t\tcipher_TLS_ECDHE_PSK_WITH_NULL_SHA256,\n\t\tcipher_TLS_ECDHE_PSK_WITH_NULL_SHA384,\n\t\tcipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256,\n\t\tcipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384,\n\t\tcipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256,\n\t\tcipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384,\n\t\tcipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256,\n\t\tcipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384,\n\t\tcipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256,\n\t\tcipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384,\n\t\tcipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256,\n\t\tcipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384,\n\t\tcipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256,\n\t\tcipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384,\n\t\tcipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,\n\t\tcipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,\n\t\tcipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384,\n\t\tcipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256,\n\t\tcipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384,\n\t\tcipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256,\n\t\tcipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384,\n\t\tcipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256,\n\t\tcipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384,\n\t\tcipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256,\n\t\tcipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,\n\t\tcipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256,\n\t\tcipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384,\n\t\tcipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256,\n\t\tcipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384,\n\t\tcipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256,\n\t\tcipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384,\n\t\tcipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,\n\t\tcipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,\n\t\tcipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,\n\t\tcipher_TLS_RSA_WITH_AES_128_CCM,\n\t\tcipher_TLS_RSA_WITH_AES_256_CCM,\n\t\tcipher_TLS_RSA_WITH_AES_128_CCM_8,\n\t\tcipher_TLS_RSA_WITH_AES_256_CCM_8,\n\t\tcipher_TLS_PSK_WITH_AES_128_CCM,\n\t\tcipher_TLS_PSK_WITH_AES_256_CCM,\n\t\tcipher_TLS_PSK_WITH_AES_128_CCM_8,\n\t\tcipher_TLS_PSK_WITH_AES_256_CCM_8:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/client_conn_pool.go",
    "content": "// Copyright 2015 The Go 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\n// Transport code's client connection pooling.\n\npackage http2\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net\"\n\t\"net/http\"\n\t\"sync\"\n)\n\n// ClientConnPool manages a pool of HTTP/2 client connections.\ntype ClientConnPool interface {\n\t// GetClientConn returns a specific HTTP/2 connection (usually\n\t// a TLS-TCP connection) to an HTTP/2 server. On success, the\n\t// returned ClientConn accounts for the upcoming RoundTrip\n\t// call, so the caller should not omit it. If the caller needs\n\t// to, ClientConn.RoundTrip can be called with a bogus\n\t// new(http.Request) to release the stream reservation.\n\tGetClientConn(req *http.Request, addr string) (*ClientConn, error)\n\tMarkDead(*ClientConn)\n}\n\n// clientConnPoolIdleCloser is the interface implemented by ClientConnPool\n// implementations which can close their idle connections.\ntype clientConnPoolIdleCloser interface {\n\tClientConnPool\n\tcloseIdleConnections()\n}\n\nvar (\n\t_ clientConnPoolIdleCloser = (*clientConnPool)(nil)\n\t_ clientConnPoolIdleCloser = noDialClientConnPool{}\n)\n\n// TODO: use singleflight for dialing and addConnCalls?\ntype clientConnPool struct {\n\tt *Transport\n\n\tmu sync.Mutex // TODO: maybe switch to RWMutex\n\t// TODO: add support for sharing conns based on cert names\n\t// (e.g. share conn for googleapis.com and appspot.com)\n\tconns        map[string][]*ClientConn // key is host:port\n\tdialing      map[string]*dialCall     // currently in-flight dials\n\tkeys         map[*ClientConn][]string\n\taddConnCalls map[string]*addConnCall // in-flight addConnIfNeeded calls\n}\n\nfunc (p *clientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {\n\treturn p.getClientConn(req, addr, dialOnMiss)\n}\n\nconst (\n\tdialOnMiss   = true\n\tnoDialOnMiss = false\n)\n\nfunc (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) {\n\t// TODO(dneil): Dial a new connection when t.DisableKeepAlives is set?\n\tif isConnectionCloseRequest(req) && dialOnMiss {\n\t\t// It gets its own connection.\n\t\ttraceGetConn(req, addr)\n\t\tconst singleUse = true\n\t\tcc, err := p.t.dialClientConn(req.Context(), addr, singleUse)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn cc, nil\n\t}\n\tfor {\n\t\tp.mu.Lock()\n\t\tfor _, cc := range p.conns[addr] {\n\t\t\tif cc.ReserveNewRequest() {\n\t\t\t\t// When a connection is presented to us by the net/http package,\n\t\t\t\t// the GetConn hook has already been called.\n\t\t\t\t// Don't call it a second time here.\n\t\t\t\tif !cc.getConnCalled {\n\t\t\t\t\ttraceGetConn(req, addr)\n\t\t\t\t}\n\t\t\t\tcc.getConnCalled = false\n\t\t\t\tp.mu.Unlock()\n\t\t\t\treturn cc, nil\n\t\t\t}\n\t\t}\n\t\tif !dialOnMiss {\n\t\t\tp.mu.Unlock()\n\t\t\treturn nil, ErrNoCachedConn\n\t\t}\n\t\ttraceGetConn(req, addr)\n\t\tcall := p.getStartDialLocked(req.Context(), addr)\n\t\tp.mu.Unlock()\n\t\t<-call.done\n\t\tif shouldRetryDial(call, req) {\n\t\t\tcontinue\n\t\t}\n\t\tcc, err := call.res, call.err\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif cc.ReserveNewRequest() {\n\t\t\treturn cc, nil\n\t\t}\n\t}\n}\n\n// dialCall is an in-flight Transport dial call to a host.\ntype dialCall struct {\n\t_ incomparable\n\tp *clientConnPool\n\t// the context associated with the request\n\t// that created this dialCall\n\tctx  context.Context\n\tdone chan struct{} // closed when done\n\tres  *ClientConn   // valid after done is closed\n\terr  error         // valid after done is closed\n}\n\n// requires p.mu is held.\nfunc (p *clientConnPool) getStartDialLocked(ctx context.Context, addr string) *dialCall {\n\tif call, ok := p.dialing[addr]; ok {\n\t\t// A dial is already in-flight. Don't start another.\n\t\treturn call\n\t}\n\tcall := &dialCall{p: p, done: make(chan struct{}), ctx: ctx}\n\tif p.dialing == nil {\n\t\tp.dialing = make(map[string]*dialCall)\n\t}\n\tp.dialing[addr] = call\n\tgo call.dial(call.ctx, addr)\n\treturn call\n}\n\n// run in its own goroutine.\nfunc (c *dialCall) dial(ctx context.Context, addr string) {\n\tconst singleUse = false // shared conn\n\tc.res, c.err = c.p.t.dialClientConn(ctx, addr, singleUse)\n\n\tc.p.mu.Lock()\n\tdelete(c.p.dialing, addr)\n\tif c.err == nil {\n\t\tc.p.addConnLocked(addr, c.res)\n\t}\n\tc.p.mu.Unlock()\n\n\tclose(c.done)\n}\n\n// addConnIfNeeded makes a NewClientConn out of c if a connection for key doesn't\n// already exist. It coalesces concurrent calls with the same key.\n// This is used by the http1 Transport code when it creates a new connection. Because\n// the http1 Transport doesn't de-dup TCP dials to outbound hosts (because it doesn't know\n// the protocol), it can get into a situation where it has multiple TLS connections.\n// This code decides which ones live or die.\n// The return value used is whether c was used.\n// c is never closed.\nfunc (p *clientConnPool) addConnIfNeeded(key string, t *Transport, c net.Conn) (used bool, err error) {\n\tp.mu.Lock()\n\tfor _, cc := range p.conns[key] {\n\t\tif cc.CanTakeNewRequest() {\n\t\t\tp.mu.Unlock()\n\t\t\treturn false, nil\n\t\t}\n\t}\n\tcall, dup := p.addConnCalls[key]\n\tif !dup {\n\t\tif p.addConnCalls == nil {\n\t\t\tp.addConnCalls = make(map[string]*addConnCall)\n\t\t}\n\t\tcall = &addConnCall{\n\t\t\tp:    p,\n\t\t\tdone: make(chan struct{}),\n\t\t}\n\t\tp.addConnCalls[key] = call\n\t\tgo call.run(t, key, c)\n\t}\n\tp.mu.Unlock()\n\n\t<-call.done\n\tif call.err != nil {\n\t\treturn false, call.err\n\t}\n\treturn !dup, nil\n}\n\ntype addConnCall struct {\n\t_    incomparable\n\tp    *clientConnPool\n\tdone chan struct{} // closed when done\n\terr  error\n}\n\nfunc (c *addConnCall) run(t *Transport, key string, nc net.Conn) {\n\tcc, err := t.NewClientConn(nc)\n\n\tp := c.p\n\tp.mu.Lock()\n\tif err != nil {\n\t\tc.err = err\n\t} else {\n\t\tcc.getConnCalled = true // already called by the net/http package\n\t\tp.addConnLocked(key, cc)\n\t}\n\tdelete(p.addConnCalls, key)\n\tp.mu.Unlock()\n\tclose(c.done)\n}\n\n// p.mu must be held\nfunc (p *clientConnPool) addConnLocked(key string, cc *ClientConn) {\n\tfor _, v := range p.conns[key] {\n\t\tif v == cc {\n\t\t\treturn\n\t\t}\n\t}\n\tif p.conns == nil {\n\t\tp.conns = make(map[string][]*ClientConn)\n\t}\n\tif p.keys == nil {\n\t\tp.keys = make(map[*ClientConn][]string)\n\t}\n\tp.conns[key] = append(p.conns[key], cc)\n\tp.keys[cc] = append(p.keys[cc], key)\n}\n\nfunc (p *clientConnPool) MarkDead(cc *ClientConn) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tfor _, key := range p.keys[cc] {\n\t\tvv, ok := p.conns[key]\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tnewList := filterOutClientConn(vv, cc)\n\t\tif len(newList) > 0 {\n\t\t\tp.conns[key] = newList\n\t\t} else {\n\t\t\tdelete(p.conns, key)\n\t\t}\n\t}\n\tdelete(p.keys, cc)\n}\n\nfunc (p *clientConnPool) closeIdleConnections() {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\t// TODO: don't close a cc if it was just added to the pool\n\t// milliseconds ago and has never been used. There's currently\n\t// a small race window with the HTTP/1 Transport's integration\n\t// where it can add an idle conn just before using it, and\n\t// somebody else can concurrently call CloseIdleConns and\n\t// break some caller's RoundTrip.\n\tfor _, vv := range p.conns {\n\t\tfor _, cc := range vv {\n\t\t\tcc.closeIfIdle()\n\t\t}\n\t}\n}\n\nfunc filterOutClientConn(in []*ClientConn, exclude *ClientConn) []*ClientConn {\n\tout := in[:0]\n\tfor _, v := range in {\n\t\tif v != exclude {\n\t\t\tout = append(out, v)\n\t\t}\n\t}\n\t// If we filtered it out, zero out the last item to prevent\n\t// the GC from seeing it.\n\tif len(in) != len(out) {\n\t\tin[len(in)-1] = nil\n\t}\n\treturn out\n}\n\n// noDialClientConnPool is an implementation of http2.ClientConnPool\n// which never dials. We let the HTTP/1.1 client dial and use its TLS\n// connection instead.\ntype noDialClientConnPool struct{ *clientConnPool }\n\nfunc (p noDialClientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {\n\treturn p.getClientConn(req, addr, noDialOnMiss)\n}\n\n// shouldRetryDial reports whether the current request should\n// retry dialing after the call finished unsuccessfully, for example\n// if the dial was canceled because of a context cancellation or\n// deadline expiry.\nfunc shouldRetryDial(call *dialCall, req *http.Request) bool {\n\tif call.err == nil {\n\t\t// No error, no need to retry\n\t\treturn false\n\t}\n\tif call.ctx == req.Context() {\n\t\t// If the call has the same context as the request, the dial\n\t\t// should not be retried, since any cancellation will have come\n\t\t// from this request.\n\t\treturn false\n\t}\n\tif !errors.Is(call.err, context.Canceled) && !errors.Is(call.err, context.DeadlineExceeded) {\n\t\t// If the call error is not because of a context cancellation or a deadline expiry,\n\t\t// the dial should not be retried.\n\t\treturn false\n\t}\n\t// Only retry if the error is a context cancellation error or deadline expiry\n\t// and the context associated with the call was canceled or expired.\n\treturn call.ctx.Err() != nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/config.go",
    "content": "// Copyright 2024 The Go 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 http2\n\nimport (\n\t\"math\"\n\t\"net/http\"\n\t\"time\"\n)\n\n// http2Config is a package-internal version of net/http.HTTP2Config.\n//\n// http.HTTP2Config was added in Go 1.24.\n// When running with a version of net/http that includes HTTP2Config,\n// we merge the configuration with the fields in Transport or Server\n// to produce an http2Config.\n//\n// Zero valued fields in http2Config are interpreted as in the\n// net/http.HTTPConfig documentation.\n//\n// Precedence order for reconciling configurations is:\n//\n//   - Use the net/http.{Server,Transport}.HTTP2Config value, when non-zero.\n//   - Otherwise use the http2.{Server.Transport} value.\n//   - If the resulting value is zero or out of range, use a default.\ntype http2Config struct {\n\tMaxConcurrentStreams         uint32\n\tMaxDecoderHeaderTableSize    uint32\n\tMaxEncoderHeaderTableSize    uint32\n\tMaxReadFrameSize             uint32\n\tMaxUploadBufferPerConnection int32\n\tMaxUploadBufferPerStream     int32\n\tSendPingTimeout              time.Duration\n\tPingTimeout                  time.Duration\n\tWriteByteTimeout             time.Duration\n\tPermitProhibitedCipherSuites bool\n\tCountError                   func(errType string)\n}\n\n// configFromServer merges configuration settings from\n// net/http.Server.HTTP2Config and http2.Server.\nfunc configFromServer(h1 *http.Server, h2 *Server) http2Config {\n\tconf := http2Config{\n\t\tMaxConcurrentStreams:         h2.MaxConcurrentStreams,\n\t\tMaxEncoderHeaderTableSize:    h2.MaxEncoderHeaderTableSize,\n\t\tMaxDecoderHeaderTableSize:    h2.MaxDecoderHeaderTableSize,\n\t\tMaxReadFrameSize:             h2.MaxReadFrameSize,\n\t\tMaxUploadBufferPerConnection: h2.MaxUploadBufferPerConnection,\n\t\tMaxUploadBufferPerStream:     h2.MaxUploadBufferPerStream,\n\t\tSendPingTimeout:              h2.ReadIdleTimeout,\n\t\tPingTimeout:                  h2.PingTimeout,\n\t\tWriteByteTimeout:             h2.WriteByteTimeout,\n\t\tPermitProhibitedCipherSuites: h2.PermitProhibitedCipherSuites,\n\t\tCountError:                   h2.CountError,\n\t}\n\tfillNetHTTPServerConfig(&conf, h1)\n\tsetConfigDefaults(&conf, true)\n\treturn conf\n}\n\n// configFromTransport merges configuration settings from h2 and h2.t1.HTTP2\n// (the net/http Transport).\nfunc configFromTransport(h2 *Transport) http2Config {\n\tconf := http2Config{\n\t\tMaxEncoderHeaderTableSize: h2.MaxEncoderHeaderTableSize,\n\t\tMaxDecoderHeaderTableSize: h2.MaxDecoderHeaderTableSize,\n\t\tMaxReadFrameSize:          h2.MaxReadFrameSize,\n\t\tSendPingTimeout:           h2.ReadIdleTimeout,\n\t\tPingTimeout:               h2.PingTimeout,\n\t\tWriteByteTimeout:          h2.WriteByteTimeout,\n\t}\n\n\t// Unlike most config fields, where out-of-range values revert to the default,\n\t// Transport.MaxReadFrameSize clips.\n\tif conf.MaxReadFrameSize < minMaxFrameSize {\n\t\tconf.MaxReadFrameSize = minMaxFrameSize\n\t} else if conf.MaxReadFrameSize > maxFrameSize {\n\t\tconf.MaxReadFrameSize = maxFrameSize\n\t}\n\n\tif h2.t1 != nil {\n\t\tfillNetHTTPTransportConfig(&conf, h2.t1)\n\t}\n\tsetConfigDefaults(&conf, false)\n\treturn conf\n}\n\nfunc setDefault[T ~int | ~int32 | ~uint32 | ~int64](v *T, minval, maxval, defval T) {\n\tif *v < minval || *v > maxval {\n\t\t*v = defval\n\t}\n}\n\nfunc setConfigDefaults(conf *http2Config, server bool) {\n\tsetDefault(&conf.MaxConcurrentStreams, 1, math.MaxUint32, defaultMaxStreams)\n\tsetDefault(&conf.MaxEncoderHeaderTableSize, 1, math.MaxUint32, initialHeaderTableSize)\n\tsetDefault(&conf.MaxDecoderHeaderTableSize, 1, math.MaxUint32, initialHeaderTableSize)\n\tif server {\n\t\tsetDefault(&conf.MaxUploadBufferPerConnection, initialWindowSize, math.MaxInt32, 1<<20)\n\t} else {\n\t\tsetDefault(&conf.MaxUploadBufferPerConnection, initialWindowSize, math.MaxInt32, transportDefaultConnFlow)\n\t}\n\tif server {\n\t\tsetDefault(&conf.MaxUploadBufferPerStream, 1, math.MaxInt32, 1<<20)\n\t} else {\n\t\tsetDefault(&conf.MaxUploadBufferPerStream, 1, math.MaxInt32, transportDefaultStreamFlow)\n\t}\n\tsetDefault(&conf.MaxReadFrameSize, minMaxFrameSize, maxFrameSize, defaultMaxReadFrameSize)\n\tsetDefault(&conf.PingTimeout, 1, math.MaxInt64, 15*time.Second)\n}\n\n// adjustHTTP1MaxHeaderSize converts a limit in bytes on the size of an HTTP/1 header\n// to an HTTP/2 MAX_HEADER_LIST_SIZE value.\nfunc adjustHTTP1MaxHeaderSize(n int64) int64 {\n\t// http2's count is in a slightly different unit and includes 32 bytes per pair.\n\t// So, take the net/http.Server value and pad it up a bit, assuming 10 headers.\n\tconst perFieldOverhead = 32 // per http2 spec\n\tconst typicalHeaders = 10   // conservative\n\treturn n + typicalHeaders*perFieldOverhead\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/config_go124.go",
    "content": "// Copyright 2024 The Go 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\n//go:build go1.24\n\npackage http2\n\nimport \"net/http\"\n\n// fillNetHTTPServerConfig sets fields in conf from srv.HTTP2.\nfunc fillNetHTTPServerConfig(conf *http2Config, srv *http.Server) {\n\tfillNetHTTPConfig(conf, srv.HTTP2)\n}\n\n// fillNetHTTPTransportConfig sets fields in conf from tr.HTTP2.\nfunc fillNetHTTPTransportConfig(conf *http2Config, tr *http.Transport) {\n\tfillNetHTTPConfig(conf, tr.HTTP2)\n}\n\nfunc fillNetHTTPConfig(conf *http2Config, h2 *http.HTTP2Config) {\n\tif h2 == nil {\n\t\treturn\n\t}\n\tif h2.MaxConcurrentStreams != 0 {\n\t\tconf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams)\n\t}\n\tif h2.MaxEncoderHeaderTableSize != 0 {\n\t\tconf.MaxEncoderHeaderTableSize = uint32(h2.MaxEncoderHeaderTableSize)\n\t}\n\tif h2.MaxDecoderHeaderTableSize != 0 {\n\t\tconf.MaxDecoderHeaderTableSize = uint32(h2.MaxDecoderHeaderTableSize)\n\t}\n\tif h2.MaxConcurrentStreams != 0 {\n\t\tconf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams)\n\t}\n\tif h2.MaxReadFrameSize != 0 {\n\t\tconf.MaxReadFrameSize = uint32(h2.MaxReadFrameSize)\n\t}\n\tif h2.MaxReceiveBufferPerConnection != 0 {\n\t\tconf.MaxUploadBufferPerConnection = int32(h2.MaxReceiveBufferPerConnection)\n\t}\n\tif h2.MaxReceiveBufferPerStream != 0 {\n\t\tconf.MaxUploadBufferPerStream = int32(h2.MaxReceiveBufferPerStream)\n\t}\n\tif h2.SendPingTimeout != 0 {\n\t\tconf.SendPingTimeout = h2.SendPingTimeout\n\t}\n\tif h2.PingTimeout != 0 {\n\t\tconf.PingTimeout = h2.PingTimeout\n\t}\n\tif h2.WriteByteTimeout != 0 {\n\t\tconf.WriteByteTimeout = h2.WriteByteTimeout\n\t}\n\tif h2.PermitProhibitedCipherSuites {\n\t\tconf.PermitProhibitedCipherSuites = true\n\t}\n\tif h2.CountError != nil {\n\t\tconf.CountError = h2.CountError\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/config_pre_go124.go",
    "content": "// Copyright 2024 The Go 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\n//go:build !go1.24\n\npackage http2\n\nimport \"net/http\"\n\n// Pre-Go 1.24 fallback.\n// The Server.HTTP2 and Transport.HTTP2 config fields were added in Go 1.24.\n\nfunc fillNetHTTPServerConfig(conf *http2Config, srv *http.Server) {}\n\nfunc fillNetHTTPTransportConfig(conf *http2Config, tr *http.Transport) {}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/databuffer.go",
    "content": "// Copyright 2014 The Go 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 http2\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n)\n\n// Buffer chunks are allocated from a pool to reduce pressure on GC.\n// The maximum wasted space per dataBuffer is 2x the largest size class,\n// which happens when the dataBuffer has multiple chunks and there is\n// one unread byte in both the first and last chunks. We use a few size\n// classes to minimize overheads for servers that typically receive very\n// small request bodies.\n//\n// TODO: Benchmark to determine if the pools are necessary. The GC may have\n// improved enough that we can instead allocate chunks like this:\n// make([]byte, max(16<<10, expectedBytesRemaining))\nvar dataChunkPools = [...]sync.Pool{\n\t{New: func() interface{} { return new([1 << 10]byte) }},\n\t{New: func() interface{} { return new([2 << 10]byte) }},\n\t{New: func() interface{} { return new([4 << 10]byte) }},\n\t{New: func() interface{} { return new([8 << 10]byte) }},\n\t{New: func() interface{} { return new([16 << 10]byte) }},\n}\n\nfunc getDataBufferChunk(size int64) []byte {\n\tswitch {\n\tcase size <= 1<<10:\n\t\treturn dataChunkPools[0].Get().(*[1 << 10]byte)[:]\n\tcase size <= 2<<10:\n\t\treturn dataChunkPools[1].Get().(*[2 << 10]byte)[:]\n\tcase size <= 4<<10:\n\t\treturn dataChunkPools[2].Get().(*[4 << 10]byte)[:]\n\tcase size <= 8<<10:\n\t\treturn dataChunkPools[3].Get().(*[8 << 10]byte)[:]\n\tdefault:\n\t\treturn dataChunkPools[4].Get().(*[16 << 10]byte)[:]\n\t}\n}\n\nfunc putDataBufferChunk(p []byte) {\n\tswitch len(p) {\n\tcase 1 << 10:\n\t\tdataChunkPools[0].Put((*[1 << 10]byte)(p))\n\tcase 2 << 10:\n\t\tdataChunkPools[1].Put((*[2 << 10]byte)(p))\n\tcase 4 << 10:\n\t\tdataChunkPools[2].Put((*[4 << 10]byte)(p))\n\tcase 8 << 10:\n\t\tdataChunkPools[3].Put((*[8 << 10]byte)(p))\n\tcase 16 << 10:\n\t\tdataChunkPools[4].Put((*[16 << 10]byte)(p))\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unexpected buffer len=%v\", len(p)))\n\t}\n}\n\n// dataBuffer is an io.ReadWriter backed by a list of data chunks.\n// Each dataBuffer is used to read DATA frames on a single stream.\n// The buffer is divided into chunks so the server can limit the\n// total memory used by a single connection without limiting the\n// request body size on any single stream.\ntype dataBuffer struct {\n\tchunks   [][]byte\n\tr        int   // next byte to read is chunks[0][r]\n\tw        int   // next byte to write is chunks[len(chunks)-1][w]\n\tsize     int   // total buffered bytes\n\texpected int64 // we expect at least this many bytes in future Write calls (ignored if <= 0)\n}\n\nvar errReadEmpty = errors.New(\"read from empty dataBuffer\")\n\n// Read copies bytes from the buffer into p.\n// It is an error to read when no data is available.\nfunc (b *dataBuffer) Read(p []byte) (int, error) {\n\tif b.size == 0 {\n\t\treturn 0, errReadEmpty\n\t}\n\tvar ntotal int\n\tfor len(p) > 0 && b.size > 0 {\n\t\treadFrom := b.bytesFromFirstChunk()\n\t\tn := copy(p, readFrom)\n\t\tp = p[n:]\n\t\tntotal += n\n\t\tb.r += n\n\t\tb.size -= n\n\t\t// If the first chunk has been consumed, advance to the next chunk.\n\t\tif b.r == len(b.chunks[0]) {\n\t\t\tputDataBufferChunk(b.chunks[0])\n\t\t\tend := len(b.chunks) - 1\n\t\t\tcopy(b.chunks[:end], b.chunks[1:])\n\t\t\tb.chunks[end] = nil\n\t\t\tb.chunks = b.chunks[:end]\n\t\t\tb.r = 0\n\t\t}\n\t}\n\treturn ntotal, nil\n}\n\nfunc (b *dataBuffer) bytesFromFirstChunk() []byte {\n\tif len(b.chunks) == 1 {\n\t\treturn b.chunks[0][b.r:b.w]\n\t}\n\treturn b.chunks[0][b.r:]\n}\n\n// Len returns the number of bytes of the unread portion of the buffer.\nfunc (b *dataBuffer) Len() int {\n\treturn b.size\n}\n\n// Write appends p to the buffer.\nfunc (b *dataBuffer) Write(p []byte) (int, error) {\n\tntotal := len(p)\n\tfor len(p) > 0 {\n\t\t// If the last chunk is empty, allocate a new chunk. Try to allocate\n\t\t// enough to fully copy p plus any additional bytes we expect to\n\t\t// receive. However, this may allocate less than len(p).\n\t\twant := int64(len(p))\n\t\tif b.expected > want {\n\t\t\twant = b.expected\n\t\t}\n\t\tchunk := b.lastChunkOrAlloc(want)\n\t\tn := copy(chunk[b.w:], p)\n\t\tp = p[n:]\n\t\tb.w += n\n\t\tb.size += n\n\t\tb.expected -= int64(n)\n\t}\n\treturn ntotal, nil\n}\n\nfunc (b *dataBuffer) lastChunkOrAlloc(want int64) []byte {\n\tif len(b.chunks) != 0 {\n\t\tlast := b.chunks[len(b.chunks)-1]\n\t\tif b.w < len(last) {\n\t\t\treturn last\n\t\t}\n\t}\n\tchunk := getDataBufferChunk(want)\n\tb.chunks = append(b.chunks, chunk)\n\tb.w = 0\n\treturn chunk\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/errors.go",
    "content": "// Copyright 2014 The Go 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 http2\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// An ErrCode is an unsigned 32-bit error code as defined in the HTTP/2 spec.\ntype ErrCode uint32\n\nconst (\n\tErrCodeNo                 ErrCode = 0x0\n\tErrCodeProtocol           ErrCode = 0x1\n\tErrCodeInternal           ErrCode = 0x2\n\tErrCodeFlowControl        ErrCode = 0x3\n\tErrCodeSettingsTimeout    ErrCode = 0x4\n\tErrCodeStreamClosed       ErrCode = 0x5\n\tErrCodeFrameSize          ErrCode = 0x6\n\tErrCodeRefusedStream      ErrCode = 0x7\n\tErrCodeCancel             ErrCode = 0x8\n\tErrCodeCompression        ErrCode = 0x9\n\tErrCodeConnect            ErrCode = 0xa\n\tErrCodeEnhanceYourCalm    ErrCode = 0xb\n\tErrCodeInadequateSecurity ErrCode = 0xc\n\tErrCodeHTTP11Required     ErrCode = 0xd\n)\n\nvar errCodeName = map[ErrCode]string{\n\tErrCodeNo:                 \"NO_ERROR\",\n\tErrCodeProtocol:           \"PROTOCOL_ERROR\",\n\tErrCodeInternal:           \"INTERNAL_ERROR\",\n\tErrCodeFlowControl:        \"FLOW_CONTROL_ERROR\",\n\tErrCodeSettingsTimeout:    \"SETTINGS_TIMEOUT\",\n\tErrCodeStreamClosed:       \"STREAM_CLOSED\",\n\tErrCodeFrameSize:          \"FRAME_SIZE_ERROR\",\n\tErrCodeRefusedStream:      \"REFUSED_STREAM\",\n\tErrCodeCancel:             \"CANCEL\",\n\tErrCodeCompression:        \"COMPRESSION_ERROR\",\n\tErrCodeConnect:            \"CONNECT_ERROR\",\n\tErrCodeEnhanceYourCalm:    \"ENHANCE_YOUR_CALM\",\n\tErrCodeInadequateSecurity: \"INADEQUATE_SECURITY\",\n\tErrCodeHTTP11Required:     \"HTTP_1_1_REQUIRED\",\n}\n\nfunc (e ErrCode) String() string {\n\tif s, ok := errCodeName[e]; ok {\n\t\treturn s\n\t}\n\treturn fmt.Sprintf(\"unknown error code 0x%x\", uint32(e))\n}\n\nfunc (e ErrCode) stringToken() string {\n\tif s, ok := errCodeName[e]; ok {\n\t\treturn s\n\t}\n\treturn fmt.Sprintf(\"ERR_UNKNOWN_%d\", uint32(e))\n}\n\n// ConnectionError is an error that results in the termination of the\n// entire connection.\ntype ConnectionError ErrCode\n\nfunc (e ConnectionError) Error() string { return fmt.Sprintf(\"connection error: %s\", ErrCode(e)) }\n\n// StreamError is an error that only affects one stream within an\n// HTTP/2 connection.\ntype StreamError struct {\n\tStreamID uint32\n\tCode     ErrCode\n\tCause    error // optional additional detail\n}\n\n// errFromPeer is a sentinel error value for StreamError.Cause to\n// indicate that the StreamError was sent from the peer over the wire\n// and wasn't locally generated in the Transport.\nvar errFromPeer = errors.New(\"received from peer\")\n\nfunc streamError(id uint32, code ErrCode) StreamError {\n\treturn StreamError{StreamID: id, Code: code}\n}\n\nfunc (e StreamError) Error() string {\n\tif e.Cause != nil {\n\t\treturn fmt.Sprintf(\"stream error: stream ID %d; %v; %v\", e.StreamID, e.Code, e.Cause)\n\t}\n\treturn fmt.Sprintf(\"stream error: stream ID %d; %v\", e.StreamID, e.Code)\n}\n\n// 6.9.1 The Flow Control Window\n// \"If a sender receives a WINDOW_UPDATE that causes a flow control\n// window to exceed this maximum it MUST terminate either the stream\n// or the connection, as appropriate. For streams, [...]; for the\n// connection, a GOAWAY frame with a FLOW_CONTROL_ERROR code.\"\ntype goAwayFlowError struct{}\n\nfunc (goAwayFlowError) Error() string { return \"connection exceeded flow control window size\" }\n\n// connError represents an HTTP/2 ConnectionError error code, along\n// with a string (for debugging) explaining why.\n//\n// Errors of this type are only returned by the frame parser functions\n// and converted into ConnectionError(Code), after stashing away\n// the Reason into the Framer's errDetail field, accessible via\n// the (*Framer).ErrorDetail method.\ntype connError struct {\n\tCode   ErrCode // the ConnectionError error code\n\tReason string  // additional reason\n}\n\nfunc (e connError) Error() string {\n\treturn fmt.Sprintf(\"http2: connection error: %v: %v\", e.Code, e.Reason)\n}\n\ntype pseudoHeaderError string\n\nfunc (e pseudoHeaderError) Error() string {\n\treturn fmt.Sprintf(\"invalid pseudo-header %q\", string(e))\n}\n\ntype duplicatePseudoHeaderError string\n\nfunc (e duplicatePseudoHeaderError) Error() string {\n\treturn fmt.Sprintf(\"duplicate pseudo-header %q\", string(e))\n}\n\ntype headerFieldNameError string\n\nfunc (e headerFieldNameError) Error() string {\n\treturn fmt.Sprintf(\"invalid header field name %q\", string(e))\n}\n\ntype headerFieldValueError string\n\nfunc (e headerFieldValueError) Error() string {\n\treturn fmt.Sprintf(\"invalid header field value for %q\", string(e))\n}\n\nvar (\n\terrMixPseudoHeaderTypes = errors.New(\"mix of request and response pseudo headers\")\n\terrPseudoAfterRegular   = errors.New(\"pseudo header field after regular\")\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/flow.go",
    "content": "// Copyright 2014 The Go 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\n// Flow control\n\npackage http2\n\n// inflowMinRefresh is the minimum number of bytes we'll send for a\n// flow control window update.\nconst inflowMinRefresh = 4 << 10\n\n// inflow accounts for an inbound flow control window.\n// It tracks both the latest window sent to the peer (used for enforcement)\n// and the accumulated unsent window.\ntype inflow struct {\n\tavail  int32\n\tunsent int32\n}\n\n// init sets the initial window.\nfunc (f *inflow) init(n int32) {\n\tf.avail = n\n}\n\n// add adds n bytes to the window, with a maximum window size of max,\n// indicating that the peer can now send us more data.\n// For example, the user read from a {Request,Response} body and consumed\n// some of the buffered data, so the peer can now send more.\n// It returns the number of bytes to send in a WINDOW_UPDATE frame to the peer.\n// Window updates are accumulated and sent when the unsent capacity\n// is at least inflowMinRefresh or will at least double the peer's available window.\nfunc (f *inflow) add(n int) (connAdd int32) {\n\tif n < 0 {\n\t\tpanic(\"negative update\")\n\t}\n\tunsent := int64(f.unsent) + int64(n)\n\t// \"A sender MUST NOT allow a flow-control window to exceed 2^31-1 octets.\"\n\t// RFC 7540 Section 6.9.1.\n\tconst maxWindow = 1<<31 - 1\n\tif unsent+int64(f.avail) > maxWindow {\n\t\tpanic(\"flow control update exceeds maximum window size\")\n\t}\n\tf.unsent = int32(unsent)\n\tif f.unsent < inflowMinRefresh && f.unsent < f.avail {\n\t\t// If there aren't at least inflowMinRefresh bytes of window to send,\n\t\t// and this update won't at least double the window, buffer the update for later.\n\t\treturn 0\n\t}\n\tf.avail += f.unsent\n\tf.unsent = 0\n\treturn int32(unsent)\n}\n\n// take attempts to take n bytes from the peer's flow control window.\n// It reports whether the window has available capacity.\nfunc (f *inflow) take(n uint32) bool {\n\tif n > uint32(f.avail) {\n\t\treturn false\n\t}\n\tf.avail -= int32(n)\n\treturn true\n}\n\n// takeInflows attempts to take n bytes from two inflows,\n// typically connection-level and stream-level flows.\n// It reports whether both windows have available capacity.\nfunc takeInflows(f1, f2 *inflow, n uint32) bool {\n\tif n > uint32(f1.avail) || n > uint32(f2.avail) {\n\t\treturn false\n\t}\n\tf1.avail -= int32(n)\n\tf2.avail -= int32(n)\n\treturn true\n}\n\n// outflow is the outbound flow control window's size.\ntype outflow struct {\n\t_ incomparable\n\n\t// n is the number of DATA bytes we're allowed to send.\n\t// An outflow is kept both on a conn and a per-stream.\n\tn int32\n\n\t// conn points to the shared connection-level outflow that is\n\t// shared by all streams on that conn. It is nil for the outflow\n\t// that's on the conn directly.\n\tconn *outflow\n}\n\nfunc (f *outflow) setConnFlow(cf *outflow) { f.conn = cf }\n\nfunc (f *outflow) available() int32 {\n\tn := f.n\n\tif f.conn != nil && f.conn.n < n {\n\t\tn = f.conn.n\n\t}\n\treturn n\n}\n\nfunc (f *outflow) take(n int32) {\n\tif n > f.available() {\n\t\tpanic(\"internal error: took too much\")\n\t}\n\tf.n -= n\n\tif f.conn != nil {\n\t\tf.conn.n -= n\n\t}\n}\n\n// add adds n bytes (positive or negative) to the flow control window.\n// It returns false if the sum would exceed 2^31-1.\nfunc (f *outflow) add(n int32) bool {\n\tsum := f.n + n\n\tif (sum > n) == (f.n > 0) {\n\t\tf.n = sum\n\t\treturn true\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/frame.go",
    "content": "// Copyright 2014 The Go 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 http2\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"golang.org/x/net/http/httpguts\"\n\t\"golang.org/x/net/http2/hpack\"\n)\n\nconst frameHeaderLen = 9\n\nvar padZeros = make([]byte, 255) // zeros for padding\n\n// A FrameType is a registered frame type as defined in\n// https://httpwg.org/specs/rfc7540.html#rfc.section.11.2\ntype FrameType uint8\n\nconst (\n\tFrameData         FrameType = 0x0\n\tFrameHeaders      FrameType = 0x1\n\tFramePriority     FrameType = 0x2\n\tFrameRSTStream    FrameType = 0x3\n\tFrameSettings     FrameType = 0x4\n\tFramePushPromise  FrameType = 0x5\n\tFramePing         FrameType = 0x6\n\tFrameGoAway       FrameType = 0x7\n\tFrameWindowUpdate FrameType = 0x8\n\tFrameContinuation FrameType = 0x9\n)\n\nvar frameName = map[FrameType]string{\n\tFrameData:         \"DATA\",\n\tFrameHeaders:      \"HEADERS\",\n\tFramePriority:     \"PRIORITY\",\n\tFrameRSTStream:    \"RST_STREAM\",\n\tFrameSettings:     \"SETTINGS\",\n\tFramePushPromise:  \"PUSH_PROMISE\",\n\tFramePing:         \"PING\",\n\tFrameGoAway:       \"GOAWAY\",\n\tFrameWindowUpdate: \"WINDOW_UPDATE\",\n\tFrameContinuation: \"CONTINUATION\",\n}\n\nfunc (t FrameType) String() string {\n\tif s, ok := frameName[t]; ok {\n\t\treturn s\n\t}\n\treturn fmt.Sprintf(\"UNKNOWN_FRAME_TYPE_%d\", uint8(t))\n}\n\n// Flags is a bitmask of HTTP/2 flags.\n// The meaning of flags varies depending on the frame type.\ntype Flags uint8\n\n// Has reports whether f contains all (0 or more) flags in v.\nfunc (f Flags) Has(v Flags) bool {\n\treturn (f & v) == v\n}\n\n// Frame-specific FrameHeader flag bits.\nconst (\n\t// Data Frame\n\tFlagDataEndStream Flags = 0x1\n\tFlagDataPadded    Flags = 0x8\n\n\t// Headers Frame\n\tFlagHeadersEndStream  Flags = 0x1\n\tFlagHeadersEndHeaders Flags = 0x4\n\tFlagHeadersPadded     Flags = 0x8\n\tFlagHeadersPriority   Flags = 0x20\n\n\t// Settings Frame\n\tFlagSettingsAck Flags = 0x1\n\n\t// Ping Frame\n\tFlagPingAck Flags = 0x1\n\n\t// Continuation Frame\n\tFlagContinuationEndHeaders Flags = 0x4\n\n\tFlagPushPromiseEndHeaders Flags = 0x4\n\tFlagPushPromisePadded     Flags = 0x8\n)\n\nvar flagName = map[FrameType]map[Flags]string{\n\tFrameData: {\n\t\tFlagDataEndStream: \"END_STREAM\",\n\t\tFlagDataPadded:    \"PADDED\",\n\t},\n\tFrameHeaders: {\n\t\tFlagHeadersEndStream:  \"END_STREAM\",\n\t\tFlagHeadersEndHeaders: \"END_HEADERS\",\n\t\tFlagHeadersPadded:     \"PADDED\",\n\t\tFlagHeadersPriority:   \"PRIORITY\",\n\t},\n\tFrameSettings: {\n\t\tFlagSettingsAck: \"ACK\",\n\t},\n\tFramePing: {\n\t\tFlagPingAck: \"ACK\",\n\t},\n\tFrameContinuation: {\n\t\tFlagContinuationEndHeaders: \"END_HEADERS\",\n\t},\n\tFramePushPromise: {\n\t\tFlagPushPromiseEndHeaders: \"END_HEADERS\",\n\t\tFlagPushPromisePadded:     \"PADDED\",\n\t},\n}\n\n// a frameParser parses a frame given its FrameHeader and payload\n// bytes. The length of payload will always equal fh.Length (which\n// might be 0).\ntype frameParser func(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error)\n\nvar frameParsers = map[FrameType]frameParser{\n\tFrameData:         parseDataFrame,\n\tFrameHeaders:      parseHeadersFrame,\n\tFramePriority:     parsePriorityFrame,\n\tFrameRSTStream:    parseRSTStreamFrame,\n\tFrameSettings:     parseSettingsFrame,\n\tFramePushPromise:  parsePushPromise,\n\tFramePing:         parsePingFrame,\n\tFrameGoAway:       parseGoAwayFrame,\n\tFrameWindowUpdate: parseWindowUpdateFrame,\n\tFrameContinuation: parseContinuationFrame,\n}\n\nfunc typeFrameParser(t FrameType) frameParser {\n\tif f := frameParsers[t]; f != nil {\n\t\treturn f\n\t}\n\treturn parseUnknownFrame\n}\n\n// A FrameHeader is the 9 byte header of all HTTP/2 frames.\n//\n// See https://httpwg.org/specs/rfc7540.html#FrameHeader\ntype FrameHeader struct {\n\tvalid bool // caller can access []byte fields in the Frame\n\n\t// Type is the 1 byte frame type. There are ten standard frame\n\t// types, but extension frame types may be written by WriteRawFrame\n\t// and will be returned by ReadFrame (as UnknownFrame).\n\tType FrameType\n\n\t// Flags are the 1 byte of 8 potential bit flags per frame.\n\t// They are specific to the frame type.\n\tFlags Flags\n\n\t// Length is the length of the frame, not including the 9 byte header.\n\t// The maximum size is one byte less than 16MB (uint24), but only\n\t// frames up to 16KB are allowed without peer agreement.\n\tLength uint32\n\n\t// StreamID is which stream this frame is for. Certain frames\n\t// are not stream-specific, in which case this field is 0.\n\tStreamID uint32\n}\n\n// Header returns h. It exists so FrameHeaders can be embedded in other\n// specific frame types and implement the Frame interface.\nfunc (h FrameHeader) Header() FrameHeader { return h }\n\nfunc (h FrameHeader) String() string {\n\tvar buf bytes.Buffer\n\tbuf.WriteString(\"[FrameHeader \")\n\th.writeDebug(&buf)\n\tbuf.WriteByte(']')\n\treturn buf.String()\n}\n\nfunc (h FrameHeader) writeDebug(buf *bytes.Buffer) {\n\tbuf.WriteString(h.Type.String())\n\tif h.Flags != 0 {\n\t\tbuf.WriteString(\" flags=\")\n\t\tset := 0\n\t\tfor i := uint8(0); i < 8; i++ {\n\t\t\tif h.Flags&(1<<i) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tset++\n\t\t\tif set > 1 {\n\t\t\t\tbuf.WriteByte('|')\n\t\t\t}\n\t\t\tname := flagName[h.Type][Flags(1<<i)]\n\t\t\tif name != \"\" {\n\t\t\t\tbuf.WriteString(name)\n\t\t\t} else {\n\t\t\t\tfmt.Fprintf(buf, \"0x%x\", 1<<i)\n\t\t\t}\n\t\t}\n\t}\n\tif h.StreamID != 0 {\n\t\tfmt.Fprintf(buf, \" stream=%d\", h.StreamID)\n\t}\n\tfmt.Fprintf(buf, \" len=%d\", h.Length)\n}\n\nfunc (h *FrameHeader) checkValid() {\n\tif !h.valid {\n\t\tpanic(\"Frame accessor called on non-owned Frame\")\n\t}\n}\n\nfunc (h *FrameHeader) invalidate() { h.valid = false }\n\n// frame header bytes.\n// Used only by ReadFrameHeader.\nvar fhBytes = sync.Pool{\n\tNew: func() interface{} {\n\t\tbuf := make([]byte, frameHeaderLen)\n\t\treturn &buf\n\t},\n}\n\nfunc invalidHTTP1LookingFrameHeader() FrameHeader {\n\tfh, _ := readFrameHeader(make([]byte, frameHeaderLen), strings.NewReader(\"HTTP/1.1 \"))\n\treturn fh\n}\n\n// ReadFrameHeader reads 9 bytes from r and returns a FrameHeader.\n// Most users should use Framer.ReadFrame instead.\nfunc ReadFrameHeader(r io.Reader) (FrameHeader, error) {\n\tbufp := fhBytes.Get().(*[]byte)\n\tdefer fhBytes.Put(bufp)\n\treturn readFrameHeader(*bufp, r)\n}\n\nfunc readFrameHeader(buf []byte, r io.Reader) (FrameHeader, error) {\n\t_, err := io.ReadFull(r, buf[:frameHeaderLen])\n\tif err != nil {\n\t\treturn FrameHeader{}, err\n\t}\n\treturn FrameHeader{\n\t\tLength:   (uint32(buf[0])<<16 | uint32(buf[1])<<8 | uint32(buf[2])),\n\t\tType:     FrameType(buf[3]),\n\t\tFlags:    Flags(buf[4]),\n\t\tStreamID: binary.BigEndian.Uint32(buf[5:]) & (1<<31 - 1),\n\t\tvalid:    true,\n\t}, nil\n}\n\n// A Frame is the base interface implemented by all frame types.\n// Callers will generally type-assert the specific frame type:\n// *HeadersFrame, *SettingsFrame, *WindowUpdateFrame, etc.\n//\n// Frames are only valid until the next call to Framer.ReadFrame.\ntype Frame interface {\n\tHeader() FrameHeader\n\n\t// invalidate is called by Framer.ReadFrame to make this\n\t// frame's buffers as being invalid, since the subsequent\n\t// frame will reuse them.\n\tinvalidate()\n}\n\n// A Framer reads and writes Frames.\ntype Framer struct {\n\tr         io.Reader\n\tlastFrame Frame\n\terrDetail error\n\n\t// countError is a non-nil func that's called on a frame parse\n\t// error with some unique error path token. It's initialized\n\t// from Transport.CountError or Server.CountError.\n\tcountError func(errToken string)\n\n\t// lastHeaderStream is non-zero if the last frame was an\n\t// unfinished HEADERS/CONTINUATION.\n\tlastHeaderStream uint32\n\n\tmaxReadSize uint32\n\theaderBuf   [frameHeaderLen]byte\n\n\t// TODO: let getReadBuf be configurable, and use a less memory-pinning\n\t// allocator in server.go to minimize memory pinned for many idle conns.\n\t// Will probably also need to make frame invalidation have a hook too.\n\tgetReadBuf func(size uint32) []byte\n\treadBuf    []byte // cache for default getReadBuf\n\n\tmaxWriteSize uint32 // zero means unlimited; TODO: implement\n\n\tw    io.Writer\n\twbuf []byte\n\n\t// AllowIllegalWrites permits the Framer's Write methods to\n\t// write frames that do not conform to the HTTP/2 spec. This\n\t// permits using the Framer to test other HTTP/2\n\t// implementations' conformance to the spec.\n\t// If false, the Write methods will prefer to return an error\n\t// rather than comply.\n\tAllowIllegalWrites bool\n\n\t// AllowIllegalReads permits the Framer's ReadFrame method\n\t// to return non-compliant frames or frame orders.\n\t// This is for testing and permits using the Framer to test\n\t// other HTTP/2 implementations' conformance to the spec.\n\t// It is not compatible with ReadMetaHeaders.\n\tAllowIllegalReads bool\n\n\t// ReadMetaHeaders if non-nil causes ReadFrame to merge\n\t// HEADERS and CONTINUATION frames together and return\n\t// MetaHeadersFrame instead.\n\tReadMetaHeaders *hpack.Decoder\n\n\t// MaxHeaderListSize is the http2 MAX_HEADER_LIST_SIZE.\n\t// It's used only if ReadMetaHeaders is set; 0 means a sane default\n\t// (currently 16MB)\n\t// If the limit is hit, MetaHeadersFrame.Truncated is set true.\n\tMaxHeaderListSize uint32\n\n\t// TODO: track which type of frame & with which flags was sent\n\t// last. Then return an error (unless AllowIllegalWrites) if\n\t// we're in the middle of a header block and a\n\t// non-Continuation or Continuation on a different stream is\n\t// attempted to be written.\n\n\tlogReads, logWrites bool\n\n\tdebugFramer       *Framer // only use for logging written writes\n\tdebugFramerBuf    *bytes.Buffer\n\tdebugReadLoggerf  func(string, ...interface{})\n\tdebugWriteLoggerf func(string, ...interface{})\n\n\tframeCache *frameCache // nil if frames aren't reused (default)\n}\n\nfunc (fr *Framer) maxHeaderListSize() uint32 {\n\tif fr.MaxHeaderListSize == 0 {\n\t\treturn 16 << 20 // sane default, per docs\n\t}\n\treturn fr.MaxHeaderListSize\n}\n\nfunc (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) {\n\t// Write the FrameHeader.\n\tf.wbuf = append(f.wbuf[:0],\n\t\t0, // 3 bytes of length, filled in in endWrite\n\t\t0,\n\t\t0,\n\t\tbyte(ftype),\n\t\tbyte(flags),\n\t\tbyte(streamID>>24),\n\t\tbyte(streamID>>16),\n\t\tbyte(streamID>>8),\n\t\tbyte(streamID))\n}\n\nfunc (f *Framer) endWrite() error {\n\t// Now that we know the final size, fill in the FrameHeader in\n\t// the space previously reserved for it. Abuse append.\n\tlength := len(f.wbuf) - frameHeaderLen\n\tif length >= (1 << 24) {\n\t\treturn ErrFrameTooLarge\n\t}\n\t_ = append(f.wbuf[:0],\n\t\tbyte(length>>16),\n\t\tbyte(length>>8),\n\t\tbyte(length))\n\tif f.logWrites {\n\t\tf.logWrite()\n\t}\n\n\tn, err := f.w.Write(f.wbuf)\n\tif err == nil && n != len(f.wbuf) {\n\t\terr = io.ErrShortWrite\n\t}\n\treturn err\n}\n\nfunc (f *Framer) logWrite() {\n\tif f.debugFramer == nil {\n\t\tf.debugFramerBuf = new(bytes.Buffer)\n\t\tf.debugFramer = NewFramer(nil, f.debugFramerBuf)\n\t\tf.debugFramer.logReads = false // we log it ourselves, saying \"wrote\" below\n\t\t// Let us read anything, even if we accidentally wrote it\n\t\t// in the wrong order:\n\t\tf.debugFramer.AllowIllegalReads = true\n\t}\n\tf.debugFramerBuf.Write(f.wbuf)\n\tfr, err := f.debugFramer.ReadFrame()\n\tif err != nil {\n\t\tf.debugWriteLoggerf(\"http2: Framer %p: failed to decode just-written frame\", f)\n\t\treturn\n\t}\n\tf.debugWriteLoggerf(\"http2: Framer %p: wrote %v\", f, summarizeFrame(fr))\n}\n\nfunc (f *Framer) writeByte(v byte)     { f.wbuf = append(f.wbuf, v) }\nfunc (f *Framer) writeBytes(v []byte)  { f.wbuf = append(f.wbuf, v...) }\nfunc (f *Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) }\nfunc (f *Framer) writeUint32(v uint32) {\n\tf.wbuf = append(f.wbuf, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))\n}\n\nconst (\n\tminMaxFrameSize = 1 << 14\n\tmaxFrameSize    = 1<<24 - 1\n)\n\n// SetReuseFrames allows the Framer to reuse Frames.\n// If called on a Framer, Frames returned by calls to ReadFrame are only\n// valid until the next call to ReadFrame.\nfunc (fr *Framer) SetReuseFrames() {\n\tif fr.frameCache != nil {\n\t\treturn\n\t}\n\tfr.frameCache = &frameCache{}\n}\n\ntype frameCache struct {\n\tdataFrame DataFrame\n}\n\nfunc (fc *frameCache) getDataFrame() *DataFrame {\n\tif fc == nil {\n\t\treturn &DataFrame{}\n\t}\n\treturn &fc.dataFrame\n}\n\n// NewFramer returns a Framer that writes frames to w and reads them from r.\nfunc NewFramer(w io.Writer, r io.Reader) *Framer {\n\tfr := &Framer{\n\t\tw:                 w,\n\t\tr:                 r,\n\t\tcountError:        func(string) {},\n\t\tlogReads:          logFrameReads,\n\t\tlogWrites:         logFrameWrites,\n\t\tdebugReadLoggerf:  log.Printf,\n\t\tdebugWriteLoggerf: log.Printf,\n\t}\n\tfr.getReadBuf = func(size uint32) []byte {\n\t\tif cap(fr.readBuf) >= int(size) {\n\t\t\treturn fr.readBuf[:size]\n\t\t}\n\t\tfr.readBuf = make([]byte, size)\n\t\treturn fr.readBuf\n\t}\n\tfr.SetMaxReadFrameSize(maxFrameSize)\n\treturn fr\n}\n\n// SetMaxReadFrameSize sets the maximum size of a frame\n// that will be read by a subsequent call to ReadFrame.\n// It is the caller's responsibility to advertise this\n// limit with a SETTINGS frame.\nfunc (fr *Framer) SetMaxReadFrameSize(v uint32) {\n\tif v > maxFrameSize {\n\t\tv = maxFrameSize\n\t}\n\tfr.maxReadSize = v\n}\n\n// ErrorDetail returns a more detailed error of the last error\n// returned by Framer.ReadFrame. For instance, if ReadFrame\n// returns a StreamError with code PROTOCOL_ERROR, ErrorDetail\n// will say exactly what was invalid. ErrorDetail is not guaranteed\n// to return a non-nil value and like the rest of the http2 package,\n// its return value is not protected by an API compatibility promise.\n// ErrorDetail is reset after the next call to ReadFrame.\nfunc (fr *Framer) ErrorDetail() error {\n\treturn fr.errDetail\n}\n\n// ErrFrameTooLarge is returned from Framer.ReadFrame when the peer\n// sends a frame that is larger than declared with SetMaxReadFrameSize.\nvar ErrFrameTooLarge = errors.New(\"http2: frame too large\")\n\n// terminalReadFrameError reports whether err is an unrecoverable\n// error from ReadFrame and no other frames should be read.\nfunc terminalReadFrameError(err error) bool {\n\tif _, ok := err.(StreamError); ok {\n\t\treturn false\n\t}\n\treturn err != nil\n}\n\n// ReadFrame reads a single frame. The returned Frame is only valid\n// until the next call to ReadFrame.\n//\n// If the frame is larger than previously set with SetMaxReadFrameSize, the\n// returned error is ErrFrameTooLarge. Other errors may be of type\n// ConnectionError, StreamError, or anything else from the underlying\n// reader.\n//\n// If ReadFrame returns an error and a non-nil Frame, the Frame's StreamID\n// indicates the stream responsible for the error.\nfunc (fr *Framer) ReadFrame() (Frame, error) {\n\tfr.errDetail = nil\n\tif fr.lastFrame != nil {\n\t\tfr.lastFrame.invalidate()\n\t}\n\tfh, err := readFrameHeader(fr.headerBuf[:], fr.r)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif fh.Length > fr.maxReadSize {\n\t\tif fh == invalidHTTP1LookingFrameHeader() {\n\t\t\treturn nil, fmt.Errorf(\"http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header\", err)\n\t\t}\n\t\treturn nil, ErrFrameTooLarge\n\t}\n\tpayload := fr.getReadBuf(fh.Length)\n\tif _, err := io.ReadFull(fr.r, payload); err != nil {\n\t\tif fh == invalidHTTP1LookingFrameHeader() {\n\t\t\treturn nil, fmt.Errorf(\"http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header\", err)\n\t\t}\n\t\treturn nil, err\n\t}\n\tf, err := typeFrameParser(fh.Type)(fr.frameCache, fh, fr.countError, payload)\n\tif err != nil {\n\t\tif ce, ok := err.(connError); ok {\n\t\t\treturn nil, fr.connError(ce.Code, ce.Reason)\n\t\t}\n\t\treturn nil, err\n\t}\n\tif err := fr.checkFrameOrder(f); err != nil {\n\t\treturn nil, err\n\t}\n\tif fr.logReads {\n\t\tfr.debugReadLoggerf(\"http2: Framer %p: read %v\", fr, summarizeFrame(f))\n\t}\n\tif fh.Type == FrameHeaders && fr.ReadMetaHeaders != nil {\n\t\treturn fr.readMetaFrame(f.(*HeadersFrame))\n\t}\n\treturn f, nil\n}\n\n// connError returns ConnectionError(code) but first\n// stashes away a public reason to the caller can optionally relay it\n// to the peer before hanging up on them. This might help others debug\n// their implementations.\nfunc (fr *Framer) connError(code ErrCode, reason string) error {\n\tfr.errDetail = errors.New(reason)\n\treturn ConnectionError(code)\n}\n\n// checkFrameOrder reports an error if f is an invalid frame to return\n// next from ReadFrame. Mostly it checks whether HEADERS and\n// CONTINUATION frames are contiguous.\nfunc (fr *Framer) checkFrameOrder(f Frame) error {\n\tlast := fr.lastFrame\n\tfr.lastFrame = f\n\tif fr.AllowIllegalReads {\n\t\treturn nil\n\t}\n\n\tfh := f.Header()\n\tif fr.lastHeaderStream != 0 {\n\t\tif fh.Type != FrameContinuation {\n\t\t\treturn fr.connError(ErrCodeProtocol,\n\t\t\t\tfmt.Sprintf(\"got %s for stream %d; expected CONTINUATION following %s for stream %d\",\n\t\t\t\t\tfh.Type, fh.StreamID,\n\t\t\t\t\tlast.Header().Type, fr.lastHeaderStream))\n\t\t}\n\t\tif fh.StreamID != fr.lastHeaderStream {\n\t\t\treturn fr.connError(ErrCodeProtocol,\n\t\t\t\tfmt.Sprintf(\"got CONTINUATION for stream %d; expected stream %d\",\n\t\t\t\t\tfh.StreamID, fr.lastHeaderStream))\n\t\t}\n\t} else if fh.Type == FrameContinuation {\n\t\treturn fr.connError(ErrCodeProtocol, fmt.Sprintf(\"unexpected CONTINUATION for stream %d\", fh.StreamID))\n\t}\n\n\tswitch fh.Type {\n\tcase FrameHeaders, FrameContinuation:\n\t\tif fh.Flags.Has(FlagHeadersEndHeaders) {\n\t\t\tfr.lastHeaderStream = 0\n\t\t} else {\n\t\t\tfr.lastHeaderStream = fh.StreamID\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// A DataFrame conveys arbitrary, variable-length sequences of octets\n// associated with a stream.\n// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.1\ntype DataFrame struct {\n\tFrameHeader\n\tdata []byte\n}\n\nfunc (f *DataFrame) StreamEnded() bool {\n\treturn f.FrameHeader.Flags.Has(FlagDataEndStream)\n}\n\n// Data returns the frame's data octets, not including any padding\n// size byte or padding suffix bytes.\n// The caller must not retain the returned memory past the next\n// call to ReadFrame.\nfunc (f *DataFrame) Data() []byte {\n\tf.checkValid()\n\treturn f.data\n}\n\nfunc parseDataFrame(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {\n\tif fh.StreamID == 0 {\n\t\t// DATA frames MUST be associated with a stream. If a\n\t\t// DATA frame is received whose stream identifier\n\t\t// field is 0x0, the recipient MUST respond with a\n\t\t// connection error (Section 5.4.1) of type\n\t\t// PROTOCOL_ERROR.\n\t\tcountError(\"frame_data_stream_0\")\n\t\treturn nil, connError{ErrCodeProtocol, \"DATA frame with stream ID 0\"}\n\t}\n\tf := fc.getDataFrame()\n\tf.FrameHeader = fh\n\n\tvar padSize byte\n\tif fh.Flags.Has(FlagDataPadded) {\n\t\tvar err error\n\t\tpayload, padSize, err = readByte(payload)\n\t\tif err != nil {\n\t\t\tcountError(\"frame_data_pad_byte_short\")\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif int(padSize) > len(payload) {\n\t\t// If the length of the padding is greater than the\n\t\t// length of the frame payload, the recipient MUST\n\t\t// treat this as a connection error.\n\t\t// Filed: https://github.com/http2/http2-spec/issues/610\n\t\tcountError(\"frame_data_pad_too_big\")\n\t\treturn nil, connError{ErrCodeProtocol, \"pad size larger than data payload\"}\n\t}\n\tf.data = payload[:len(payload)-int(padSize)]\n\treturn f, nil\n}\n\nvar (\n\terrStreamID    = errors.New(\"invalid stream ID\")\n\terrDepStreamID = errors.New(\"invalid dependent stream ID\")\n\terrPadLength   = errors.New(\"pad length too large\")\n\terrPadBytes    = errors.New(\"padding bytes must all be zeros unless AllowIllegalWrites is enabled\")\n)\n\nfunc validStreamIDOrZero(streamID uint32) bool {\n\treturn streamID&(1<<31) == 0\n}\n\nfunc validStreamID(streamID uint32) bool {\n\treturn streamID != 0 && streamID&(1<<31) == 0\n}\n\n// WriteData writes a DATA frame.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility not to violate the maximum frame size\n// and to not call other Write methods concurrently.\nfunc (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error {\n\treturn f.WriteDataPadded(streamID, endStream, data, nil)\n}\n\n// WriteDataPadded writes a DATA frame with optional padding.\n//\n// If pad is nil, the padding bit is not sent.\n// The length of pad must not exceed 255 bytes.\n// The bytes of pad must all be zero, unless f.AllowIllegalWrites is set.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility not to violate the maximum frame size\n// and to not call other Write methods concurrently.\nfunc (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error {\n\tif err := f.startWriteDataPadded(streamID, endStream, data, pad); err != nil {\n\t\treturn err\n\t}\n\treturn f.endWrite()\n}\n\n// startWriteDataPadded is WriteDataPadded, but only writes the frame to the Framer's internal buffer.\n// The caller should call endWrite to flush the frame to the underlying writer.\nfunc (f *Framer) startWriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error {\n\tif !validStreamID(streamID) && !f.AllowIllegalWrites {\n\t\treturn errStreamID\n\t}\n\tif len(pad) > 0 {\n\t\tif len(pad) > 255 {\n\t\t\treturn errPadLength\n\t\t}\n\t\tif !f.AllowIllegalWrites {\n\t\t\tfor _, b := range pad {\n\t\t\t\tif b != 0 {\n\t\t\t\t\t// \"Padding octets MUST be set to zero when sending.\"\n\t\t\t\t\treturn errPadBytes\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tvar flags Flags\n\tif endStream {\n\t\tflags |= FlagDataEndStream\n\t}\n\tif pad != nil {\n\t\tflags |= FlagDataPadded\n\t}\n\tf.startWrite(FrameData, flags, streamID)\n\tif pad != nil {\n\t\tf.wbuf = append(f.wbuf, byte(len(pad)))\n\t}\n\tf.wbuf = append(f.wbuf, data...)\n\tf.wbuf = append(f.wbuf, pad...)\n\treturn nil\n}\n\n// A SettingsFrame conveys configuration parameters that affect how\n// endpoints communicate, such as preferences and constraints on peer\n// behavior.\n//\n// See https://httpwg.org/specs/rfc7540.html#SETTINGS\ntype SettingsFrame struct {\n\tFrameHeader\n\tp []byte\n}\n\nfunc parseSettingsFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {\n\tif fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 {\n\t\t// When this (ACK 0x1) bit is set, the payload of the\n\t\t// SETTINGS frame MUST be empty. Receipt of a\n\t\t// SETTINGS frame with the ACK flag set and a length\n\t\t// field value other than 0 MUST be treated as a\n\t\t// connection error (Section 5.4.1) of type\n\t\t// FRAME_SIZE_ERROR.\n\t\tcountError(\"frame_settings_ack_with_length\")\n\t\treturn nil, ConnectionError(ErrCodeFrameSize)\n\t}\n\tif fh.StreamID != 0 {\n\t\t// SETTINGS frames always apply to a connection,\n\t\t// never a single stream. The stream identifier for a\n\t\t// SETTINGS frame MUST be zero (0x0).  If an endpoint\n\t\t// receives a SETTINGS frame whose stream identifier\n\t\t// field is anything other than 0x0, the endpoint MUST\n\t\t// respond with a connection error (Section 5.4.1) of\n\t\t// type PROTOCOL_ERROR.\n\t\tcountError(\"frame_settings_has_stream\")\n\t\treturn nil, ConnectionError(ErrCodeProtocol)\n\t}\n\tif len(p)%6 != 0 {\n\t\tcountError(\"frame_settings_mod_6\")\n\t\t// Expecting even number of 6 byte settings.\n\t\treturn nil, ConnectionError(ErrCodeFrameSize)\n\t}\n\tf := &SettingsFrame{FrameHeader: fh, p: p}\n\tif v, ok := f.Value(SettingInitialWindowSize); ok && v > (1<<31)-1 {\n\t\tcountError(\"frame_settings_window_size_too_big\")\n\t\t// Values above the maximum flow control window size of 2^31 - 1 MUST\n\t\t// be treated as a connection error (Section 5.4.1) of type\n\t\t// FLOW_CONTROL_ERROR.\n\t\treturn nil, ConnectionError(ErrCodeFlowControl)\n\t}\n\treturn f, nil\n}\n\nfunc (f *SettingsFrame) IsAck() bool {\n\treturn f.FrameHeader.Flags.Has(FlagSettingsAck)\n}\n\nfunc (f *SettingsFrame) Value(id SettingID) (v uint32, ok bool) {\n\tf.checkValid()\n\tfor i := 0; i < f.NumSettings(); i++ {\n\t\tif s := f.Setting(i); s.ID == id {\n\t\t\treturn s.Val, true\n\t\t}\n\t}\n\treturn 0, false\n}\n\n// Setting returns the setting from the frame at the given 0-based index.\n// The index must be >= 0 and less than f.NumSettings().\nfunc (f *SettingsFrame) Setting(i int) Setting {\n\tbuf := f.p\n\treturn Setting{\n\t\tID:  SettingID(binary.BigEndian.Uint16(buf[i*6 : i*6+2])),\n\t\tVal: binary.BigEndian.Uint32(buf[i*6+2 : i*6+6]),\n\t}\n}\n\nfunc (f *SettingsFrame) NumSettings() int { return len(f.p) / 6 }\n\n// HasDuplicates reports whether f contains any duplicate setting IDs.\nfunc (f *SettingsFrame) HasDuplicates() bool {\n\tnum := f.NumSettings()\n\tif num == 0 {\n\t\treturn false\n\t}\n\t// If it's small enough (the common case), just do the n^2\n\t// thing and avoid a map allocation.\n\tif num < 10 {\n\t\tfor i := 0; i < num; i++ {\n\t\t\tidi := f.Setting(i).ID\n\t\t\tfor j := i + 1; j < num; j++ {\n\t\t\t\tidj := f.Setting(j).ID\n\t\t\t\tif idi == idj {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\tseen := map[SettingID]bool{}\n\tfor i := 0; i < num; i++ {\n\t\tid := f.Setting(i).ID\n\t\tif seen[id] {\n\t\t\treturn true\n\t\t}\n\t\tseen[id] = true\n\t}\n\treturn false\n}\n\n// ForeachSetting runs fn for each setting.\n// It stops and returns the first error.\nfunc (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error {\n\tf.checkValid()\n\tfor i := 0; i < f.NumSettings(); i++ {\n\t\tif err := fn(f.Setting(i)); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// WriteSettings writes a SETTINGS frame with zero or more settings\n// specified and the ACK bit not set.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility to not call other Write methods concurrently.\nfunc (f *Framer) WriteSettings(settings ...Setting) error {\n\tf.startWrite(FrameSettings, 0, 0)\n\tfor _, s := range settings {\n\t\tf.writeUint16(uint16(s.ID))\n\t\tf.writeUint32(s.Val)\n\t}\n\treturn f.endWrite()\n}\n\n// WriteSettingsAck writes an empty SETTINGS frame with the ACK bit set.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility to not call other Write methods concurrently.\nfunc (f *Framer) WriteSettingsAck() error {\n\tf.startWrite(FrameSettings, FlagSettingsAck, 0)\n\treturn f.endWrite()\n}\n\n// A PingFrame is a mechanism for measuring a minimal round trip time\n// from the sender, as well as determining whether an idle connection\n// is still functional.\n// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.7\ntype PingFrame struct {\n\tFrameHeader\n\tData [8]byte\n}\n\nfunc (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) }\n\nfunc parsePingFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {\n\tif len(payload) != 8 {\n\t\tcountError(\"frame_ping_length\")\n\t\treturn nil, ConnectionError(ErrCodeFrameSize)\n\t}\n\tif fh.StreamID != 0 {\n\t\tcountError(\"frame_ping_has_stream\")\n\t\treturn nil, ConnectionError(ErrCodeProtocol)\n\t}\n\tf := &PingFrame{FrameHeader: fh}\n\tcopy(f.Data[:], payload)\n\treturn f, nil\n}\n\nfunc (f *Framer) WritePing(ack bool, data [8]byte) error {\n\tvar flags Flags\n\tif ack {\n\t\tflags = FlagPingAck\n\t}\n\tf.startWrite(FramePing, flags, 0)\n\tf.writeBytes(data[:])\n\treturn f.endWrite()\n}\n\n// A GoAwayFrame informs the remote peer to stop creating streams on this connection.\n// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.8\ntype GoAwayFrame struct {\n\tFrameHeader\n\tLastStreamID uint32\n\tErrCode      ErrCode\n\tdebugData    []byte\n}\n\n// DebugData returns any debug data in the GOAWAY frame. Its contents\n// are not defined.\n// The caller must not retain the returned memory past the next\n// call to ReadFrame.\nfunc (f *GoAwayFrame) DebugData() []byte {\n\tf.checkValid()\n\treturn f.debugData\n}\n\nfunc parseGoAwayFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {\n\tif fh.StreamID != 0 {\n\t\tcountError(\"frame_goaway_has_stream\")\n\t\treturn nil, ConnectionError(ErrCodeProtocol)\n\t}\n\tif len(p) < 8 {\n\t\tcountError(\"frame_goaway_short\")\n\t\treturn nil, ConnectionError(ErrCodeFrameSize)\n\t}\n\treturn &GoAwayFrame{\n\t\tFrameHeader:  fh,\n\t\tLastStreamID: binary.BigEndian.Uint32(p[:4]) & (1<<31 - 1),\n\t\tErrCode:      ErrCode(binary.BigEndian.Uint32(p[4:8])),\n\t\tdebugData:    p[8:],\n\t}, nil\n}\n\nfunc (f *Framer) WriteGoAway(maxStreamID uint32, code ErrCode, debugData []byte) error {\n\tf.startWrite(FrameGoAway, 0, 0)\n\tf.writeUint32(maxStreamID & (1<<31 - 1))\n\tf.writeUint32(uint32(code))\n\tf.writeBytes(debugData)\n\treturn f.endWrite()\n}\n\n// An UnknownFrame is the frame type returned when the frame type is unknown\n// or no specific frame type parser exists.\ntype UnknownFrame struct {\n\tFrameHeader\n\tp []byte\n}\n\n// Payload returns the frame's payload (after the header).  It is not\n// valid to call this method after a subsequent call to\n// Framer.ReadFrame, nor is it valid to retain the returned slice.\n// The memory is owned by the Framer and is invalidated when the next\n// frame is read.\nfunc (f *UnknownFrame) Payload() []byte {\n\tf.checkValid()\n\treturn f.p\n}\n\nfunc parseUnknownFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {\n\treturn &UnknownFrame{fh, p}, nil\n}\n\n// A WindowUpdateFrame is used to implement flow control.\n// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.9\ntype WindowUpdateFrame struct {\n\tFrameHeader\n\tIncrement uint32 // never read with high bit set\n}\n\nfunc parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {\n\tif len(p) != 4 {\n\t\tcountError(\"frame_windowupdate_bad_len\")\n\t\treturn nil, ConnectionError(ErrCodeFrameSize)\n\t}\n\tinc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit\n\tif inc == 0 {\n\t\t// A receiver MUST treat the receipt of a\n\t\t// WINDOW_UPDATE frame with an flow control window\n\t\t// increment of 0 as a stream error (Section 5.4.2) of\n\t\t// type PROTOCOL_ERROR; errors on the connection flow\n\t\t// control window MUST be treated as a connection\n\t\t// error (Section 5.4.1).\n\t\tif fh.StreamID == 0 {\n\t\t\tcountError(\"frame_windowupdate_zero_inc_conn\")\n\t\t\treturn nil, ConnectionError(ErrCodeProtocol)\n\t\t}\n\t\tcountError(\"frame_windowupdate_zero_inc_stream\")\n\t\treturn nil, streamError(fh.StreamID, ErrCodeProtocol)\n\t}\n\treturn &WindowUpdateFrame{\n\t\tFrameHeader: fh,\n\t\tIncrement:   inc,\n\t}, nil\n}\n\n// WriteWindowUpdate writes a WINDOW_UPDATE frame.\n// The increment value must be between 1 and 2,147,483,647, inclusive.\n// If the Stream ID is zero, the window update applies to the\n// connection as a whole.\nfunc (f *Framer) WriteWindowUpdate(streamID, incr uint32) error {\n\t// \"The legal range for the increment to the flow control window is 1 to 2^31-1 (2,147,483,647) octets.\"\n\tif (incr < 1 || incr > 2147483647) && !f.AllowIllegalWrites {\n\t\treturn errors.New(\"illegal window increment value\")\n\t}\n\tf.startWrite(FrameWindowUpdate, 0, streamID)\n\tf.writeUint32(incr)\n\treturn f.endWrite()\n}\n\n// A HeadersFrame is used to open a stream and additionally carries a\n// header block fragment.\ntype HeadersFrame struct {\n\tFrameHeader\n\n\t// Priority is set if FlagHeadersPriority is set in the FrameHeader.\n\tPriority PriorityParam\n\n\theaderFragBuf []byte // not owned\n}\n\nfunc (f *HeadersFrame) HeaderBlockFragment() []byte {\n\tf.checkValid()\n\treturn f.headerFragBuf\n}\n\nfunc (f *HeadersFrame) HeadersEnded() bool {\n\treturn f.FrameHeader.Flags.Has(FlagHeadersEndHeaders)\n}\n\nfunc (f *HeadersFrame) StreamEnded() bool {\n\treturn f.FrameHeader.Flags.Has(FlagHeadersEndStream)\n}\n\nfunc (f *HeadersFrame) HasPriority() bool {\n\treturn f.FrameHeader.Flags.Has(FlagHeadersPriority)\n}\n\nfunc parseHeadersFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) {\n\thf := &HeadersFrame{\n\t\tFrameHeader: fh,\n\t}\n\tif fh.StreamID == 0 {\n\t\t// HEADERS frames MUST be associated with a stream. If a HEADERS frame\n\t\t// is received whose stream identifier field is 0x0, the recipient MUST\n\t\t// respond with a connection error (Section 5.4.1) of type\n\t\t// PROTOCOL_ERROR.\n\t\tcountError(\"frame_headers_zero_stream\")\n\t\treturn nil, connError{ErrCodeProtocol, \"HEADERS frame with stream ID 0\"}\n\t}\n\tvar padLength uint8\n\tif fh.Flags.Has(FlagHeadersPadded) {\n\t\tif p, padLength, err = readByte(p); err != nil {\n\t\t\tcountError(\"frame_headers_pad_short\")\n\t\t\treturn\n\t\t}\n\t}\n\tif fh.Flags.Has(FlagHeadersPriority) {\n\t\tvar v uint32\n\t\tp, v, err = readUint32(p)\n\t\tif err != nil {\n\t\t\tcountError(\"frame_headers_prio_short\")\n\t\t\treturn nil, err\n\t\t}\n\t\thf.Priority.StreamDep = v & 0x7fffffff\n\t\thf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set\n\t\tp, hf.Priority.Weight, err = readByte(p)\n\t\tif err != nil {\n\t\t\tcountError(\"frame_headers_prio_weight_short\")\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif len(p)-int(padLength) < 0 {\n\t\tcountError(\"frame_headers_pad_too_big\")\n\t\treturn nil, streamError(fh.StreamID, ErrCodeProtocol)\n\t}\n\thf.headerFragBuf = p[:len(p)-int(padLength)]\n\treturn hf, nil\n}\n\n// HeadersFrameParam are the parameters for writing a HEADERS frame.\ntype HeadersFrameParam struct {\n\t// StreamID is the required Stream ID to initiate.\n\tStreamID uint32\n\t// BlockFragment is part (or all) of a Header Block.\n\tBlockFragment []byte\n\n\t// EndStream indicates that the header block is the last that\n\t// the endpoint will send for the identified stream. Setting\n\t// this flag causes the stream to enter one of \"half closed\"\n\t// states.\n\tEndStream bool\n\n\t// EndHeaders indicates that this frame contains an entire\n\t// header block and is not followed by any\n\t// CONTINUATION frames.\n\tEndHeaders bool\n\n\t// PadLength is the optional number of bytes of zeros to add\n\t// to this frame.\n\tPadLength uint8\n\n\t// Priority, if non-zero, includes stream priority information\n\t// in the HEADER frame.\n\tPriority PriorityParam\n}\n\n// WriteHeaders writes a single HEADERS frame.\n//\n// This is a low-level header writing method. Encoding headers and\n// splitting them into any necessary CONTINUATION frames is handled\n// elsewhere.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility to not call other Write methods concurrently.\nfunc (f *Framer) WriteHeaders(p HeadersFrameParam) error {\n\tif !validStreamID(p.StreamID) && !f.AllowIllegalWrites {\n\t\treturn errStreamID\n\t}\n\tvar flags Flags\n\tif p.PadLength != 0 {\n\t\tflags |= FlagHeadersPadded\n\t}\n\tif p.EndStream {\n\t\tflags |= FlagHeadersEndStream\n\t}\n\tif p.EndHeaders {\n\t\tflags |= FlagHeadersEndHeaders\n\t}\n\tif !p.Priority.IsZero() {\n\t\tflags |= FlagHeadersPriority\n\t}\n\tf.startWrite(FrameHeaders, flags, p.StreamID)\n\tif p.PadLength != 0 {\n\t\tf.writeByte(p.PadLength)\n\t}\n\tif !p.Priority.IsZero() {\n\t\tv := p.Priority.StreamDep\n\t\tif !validStreamIDOrZero(v) && !f.AllowIllegalWrites {\n\t\t\treturn errDepStreamID\n\t\t}\n\t\tif p.Priority.Exclusive {\n\t\t\tv |= 1 << 31\n\t\t}\n\t\tf.writeUint32(v)\n\t\tf.writeByte(p.Priority.Weight)\n\t}\n\tf.wbuf = append(f.wbuf, p.BlockFragment...)\n\tf.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)\n\treturn f.endWrite()\n}\n\n// A PriorityFrame specifies the sender-advised priority of a stream.\n// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.3\ntype PriorityFrame struct {\n\tFrameHeader\n\tPriorityParam\n}\n\n// PriorityParam are the stream prioritzation parameters.\ntype PriorityParam struct {\n\t// StreamDep is a 31-bit stream identifier for the\n\t// stream that this stream depends on. Zero means no\n\t// dependency.\n\tStreamDep uint32\n\n\t// Exclusive is whether the dependency is exclusive.\n\tExclusive bool\n\n\t// Weight is the stream's zero-indexed weight. It should be\n\t// set together with StreamDep, or neither should be set. Per\n\t// the spec, \"Add one to the value to obtain a weight between\n\t// 1 and 256.\"\n\tWeight uint8\n}\n\nfunc (p PriorityParam) IsZero() bool {\n\treturn p == PriorityParam{}\n}\n\nfunc parsePriorityFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {\n\tif fh.StreamID == 0 {\n\t\tcountError(\"frame_priority_zero_stream\")\n\t\treturn nil, connError{ErrCodeProtocol, \"PRIORITY frame with stream ID 0\"}\n\t}\n\tif len(payload) != 5 {\n\t\tcountError(\"frame_priority_bad_length\")\n\t\treturn nil, connError{ErrCodeFrameSize, fmt.Sprintf(\"PRIORITY frame payload size was %d; want 5\", len(payload))}\n\t}\n\tv := binary.BigEndian.Uint32(payload[:4])\n\tstreamID := v & 0x7fffffff // mask off high bit\n\treturn &PriorityFrame{\n\t\tFrameHeader: fh,\n\t\tPriorityParam: PriorityParam{\n\t\t\tWeight:    payload[4],\n\t\t\tStreamDep: streamID,\n\t\t\tExclusive: streamID != v, // was high bit set?\n\t\t},\n\t}, nil\n}\n\n// WritePriority writes a PRIORITY frame.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility to not call other Write methods concurrently.\nfunc (f *Framer) WritePriority(streamID uint32, p PriorityParam) error {\n\tif !validStreamID(streamID) && !f.AllowIllegalWrites {\n\t\treturn errStreamID\n\t}\n\tif !validStreamIDOrZero(p.StreamDep) {\n\t\treturn errDepStreamID\n\t}\n\tf.startWrite(FramePriority, 0, streamID)\n\tv := p.StreamDep\n\tif p.Exclusive {\n\t\tv |= 1 << 31\n\t}\n\tf.writeUint32(v)\n\tf.writeByte(p.Weight)\n\treturn f.endWrite()\n}\n\n// A RSTStreamFrame allows for abnormal termination of a stream.\n// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.4\ntype RSTStreamFrame struct {\n\tFrameHeader\n\tErrCode ErrCode\n}\n\nfunc parseRSTStreamFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {\n\tif len(p) != 4 {\n\t\tcountError(\"frame_rststream_bad_len\")\n\t\treturn nil, ConnectionError(ErrCodeFrameSize)\n\t}\n\tif fh.StreamID == 0 {\n\t\tcountError(\"frame_rststream_zero_stream\")\n\t\treturn nil, ConnectionError(ErrCodeProtocol)\n\t}\n\treturn &RSTStreamFrame{fh, ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil\n}\n\n// WriteRSTStream writes a RST_STREAM frame.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility to not call other Write methods concurrently.\nfunc (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error {\n\tif !validStreamID(streamID) && !f.AllowIllegalWrites {\n\t\treturn errStreamID\n\t}\n\tf.startWrite(FrameRSTStream, 0, streamID)\n\tf.writeUint32(uint32(code))\n\treturn f.endWrite()\n}\n\n// A ContinuationFrame is used to continue a sequence of header block fragments.\n// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.10\ntype ContinuationFrame struct {\n\tFrameHeader\n\theaderFragBuf []byte\n}\n\nfunc parseContinuationFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {\n\tif fh.StreamID == 0 {\n\t\tcountError(\"frame_continuation_zero_stream\")\n\t\treturn nil, connError{ErrCodeProtocol, \"CONTINUATION frame with stream ID 0\"}\n\t}\n\treturn &ContinuationFrame{fh, p}, nil\n}\n\nfunc (f *ContinuationFrame) HeaderBlockFragment() []byte {\n\tf.checkValid()\n\treturn f.headerFragBuf\n}\n\nfunc (f *ContinuationFrame) HeadersEnded() bool {\n\treturn f.FrameHeader.Flags.Has(FlagContinuationEndHeaders)\n}\n\n// WriteContinuation writes a CONTINUATION frame.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility to not call other Write methods concurrently.\nfunc (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlockFragment []byte) error {\n\tif !validStreamID(streamID) && !f.AllowIllegalWrites {\n\t\treturn errStreamID\n\t}\n\tvar flags Flags\n\tif endHeaders {\n\t\tflags |= FlagContinuationEndHeaders\n\t}\n\tf.startWrite(FrameContinuation, flags, streamID)\n\tf.wbuf = append(f.wbuf, headerBlockFragment...)\n\treturn f.endWrite()\n}\n\n// A PushPromiseFrame is used to initiate a server stream.\n// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.6\ntype PushPromiseFrame struct {\n\tFrameHeader\n\tPromiseID     uint32\n\theaderFragBuf []byte // not owned\n}\n\nfunc (f *PushPromiseFrame) HeaderBlockFragment() []byte {\n\tf.checkValid()\n\treturn f.headerFragBuf\n}\n\nfunc (f *PushPromiseFrame) HeadersEnded() bool {\n\treturn f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders)\n}\n\nfunc parsePushPromise(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) {\n\tpp := &PushPromiseFrame{\n\t\tFrameHeader: fh,\n\t}\n\tif pp.StreamID == 0 {\n\t\t// PUSH_PROMISE frames MUST be associated with an existing,\n\t\t// peer-initiated stream. The stream identifier of a\n\t\t// PUSH_PROMISE frame indicates the stream it is associated\n\t\t// with. If the stream identifier field specifies the value\n\t\t// 0x0, a recipient MUST respond with a connection error\n\t\t// (Section 5.4.1) of type PROTOCOL_ERROR.\n\t\tcountError(\"frame_pushpromise_zero_stream\")\n\t\treturn nil, ConnectionError(ErrCodeProtocol)\n\t}\n\t// The PUSH_PROMISE frame includes optional padding.\n\t// Padding fields and flags are identical to those defined for DATA frames\n\tvar padLength uint8\n\tif fh.Flags.Has(FlagPushPromisePadded) {\n\t\tif p, padLength, err = readByte(p); err != nil {\n\t\t\tcountError(\"frame_pushpromise_pad_short\")\n\t\t\treturn\n\t\t}\n\t}\n\n\tp, pp.PromiseID, err = readUint32(p)\n\tif err != nil {\n\t\tcountError(\"frame_pushpromise_promiseid_short\")\n\t\treturn\n\t}\n\tpp.PromiseID = pp.PromiseID & (1<<31 - 1)\n\n\tif int(padLength) > len(p) {\n\t\t// like the DATA frame, error out if padding is longer than the body.\n\t\tcountError(\"frame_pushpromise_pad_too_big\")\n\t\treturn nil, ConnectionError(ErrCodeProtocol)\n\t}\n\tpp.headerFragBuf = p[:len(p)-int(padLength)]\n\treturn pp, nil\n}\n\n// PushPromiseParam are the parameters for writing a PUSH_PROMISE frame.\ntype PushPromiseParam struct {\n\t// StreamID is the required Stream ID to initiate.\n\tStreamID uint32\n\n\t// PromiseID is the required Stream ID which this\n\t// Push Promises\n\tPromiseID uint32\n\n\t// BlockFragment is part (or all) of a Header Block.\n\tBlockFragment []byte\n\n\t// EndHeaders indicates that this frame contains an entire\n\t// header block and is not followed by any\n\t// CONTINUATION frames.\n\tEndHeaders bool\n\n\t// PadLength is the optional number of bytes of zeros to add\n\t// to this frame.\n\tPadLength uint8\n}\n\n// WritePushPromise writes a single PushPromise Frame.\n//\n// As with Header Frames, This is the low level call for writing\n// individual frames. Continuation frames are handled elsewhere.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility to not call other Write methods concurrently.\nfunc (f *Framer) WritePushPromise(p PushPromiseParam) error {\n\tif !validStreamID(p.StreamID) && !f.AllowIllegalWrites {\n\t\treturn errStreamID\n\t}\n\tvar flags Flags\n\tif p.PadLength != 0 {\n\t\tflags |= FlagPushPromisePadded\n\t}\n\tif p.EndHeaders {\n\t\tflags |= FlagPushPromiseEndHeaders\n\t}\n\tf.startWrite(FramePushPromise, flags, p.StreamID)\n\tif p.PadLength != 0 {\n\t\tf.writeByte(p.PadLength)\n\t}\n\tif !validStreamID(p.PromiseID) && !f.AllowIllegalWrites {\n\t\treturn errStreamID\n\t}\n\tf.writeUint32(p.PromiseID)\n\tf.wbuf = append(f.wbuf, p.BlockFragment...)\n\tf.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)\n\treturn f.endWrite()\n}\n\n// WriteRawFrame writes a raw frame. This can be used to write\n// extension frames unknown to this package.\nfunc (f *Framer) WriteRawFrame(t FrameType, flags Flags, streamID uint32, payload []byte) error {\n\tf.startWrite(t, flags, streamID)\n\tf.writeBytes(payload)\n\treturn f.endWrite()\n}\n\nfunc readByte(p []byte) (remain []byte, b byte, err error) {\n\tif len(p) == 0 {\n\t\treturn nil, 0, io.ErrUnexpectedEOF\n\t}\n\treturn p[1:], p[0], nil\n}\n\nfunc readUint32(p []byte) (remain []byte, v uint32, err error) {\n\tif len(p) < 4 {\n\t\treturn nil, 0, io.ErrUnexpectedEOF\n\t}\n\treturn p[4:], binary.BigEndian.Uint32(p[:4]), nil\n}\n\ntype streamEnder interface {\n\tStreamEnded() bool\n}\n\ntype headersEnder interface {\n\tHeadersEnded() bool\n}\n\ntype headersOrContinuation interface {\n\theadersEnder\n\tHeaderBlockFragment() []byte\n}\n\n// A MetaHeadersFrame is the representation of one HEADERS frame and\n// zero or more contiguous CONTINUATION frames and the decoding of\n// their HPACK-encoded contents.\n//\n// This type of frame does not appear on the wire and is only returned\n// by the Framer when Framer.ReadMetaHeaders is set.\ntype MetaHeadersFrame struct {\n\t*HeadersFrame\n\n\t// Fields are the fields contained in the HEADERS and\n\t// CONTINUATION frames. The underlying slice is owned by the\n\t// Framer and must not be retained after the next call to\n\t// ReadFrame.\n\t//\n\t// Fields are guaranteed to be in the correct http2 order and\n\t// not have unknown pseudo header fields or invalid header\n\t// field names or values. Required pseudo header fields may be\n\t// missing, however. Use the MetaHeadersFrame.Pseudo accessor\n\t// method access pseudo headers.\n\tFields []hpack.HeaderField\n\n\t// Truncated is whether the max header list size limit was hit\n\t// and Fields is incomplete. The hpack decoder state is still\n\t// valid, however.\n\tTruncated bool\n}\n\n// PseudoValue returns the given pseudo header field's value.\n// The provided pseudo field should not contain the leading colon.\nfunc (mh *MetaHeadersFrame) PseudoValue(pseudo string) string {\n\tfor _, hf := range mh.Fields {\n\t\tif !hf.IsPseudo() {\n\t\t\treturn \"\"\n\t\t}\n\t\tif hf.Name[1:] == pseudo {\n\t\t\treturn hf.Value\n\t\t}\n\t}\n\treturn \"\"\n}\n\n// RegularFields returns the regular (non-pseudo) header fields of mh.\n// The caller does not own the returned slice.\nfunc (mh *MetaHeadersFrame) RegularFields() []hpack.HeaderField {\n\tfor i, hf := range mh.Fields {\n\t\tif !hf.IsPseudo() {\n\t\t\treturn mh.Fields[i:]\n\t\t}\n\t}\n\treturn nil\n}\n\n// PseudoFields returns the pseudo header fields of mh.\n// The caller does not own the returned slice.\nfunc (mh *MetaHeadersFrame) PseudoFields() []hpack.HeaderField {\n\tfor i, hf := range mh.Fields {\n\t\tif !hf.IsPseudo() {\n\t\t\treturn mh.Fields[:i]\n\t\t}\n\t}\n\treturn mh.Fields\n}\n\nfunc (mh *MetaHeadersFrame) checkPseudos() error {\n\tvar isRequest, isResponse bool\n\tpf := mh.PseudoFields()\n\tfor i, hf := range pf {\n\t\tswitch hf.Name {\n\t\tcase \":method\", \":path\", \":scheme\", \":authority\", \":protocol\":\n\t\t\tisRequest = true\n\t\tcase \":status\":\n\t\t\tisResponse = true\n\t\tdefault:\n\t\t\treturn pseudoHeaderError(hf.Name)\n\t\t}\n\t\t// Check for duplicates.\n\t\t// This would be a bad algorithm, but N is 5.\n\t\t// And this doesn't allocate.\n\t\tfor _, hf2 := range pf[:i] {\n\t\t\tif hf.Name == hf2.Name {\n\t\t\t\treturn duplicatePseudoHeaderError(hf.Name)\n\t\t\t}\n\t\t}\n\t}\n\tif isRequest && isResponse {\n\t\treturn errMixPseudoHeaderTypes\n\t}\n\treturn nil\n}\n\nfunc (fr *Framer) maxHeaderStringLen() int {\n\tv := int(fr.maxHeaderListSize())\n\tif v < 0 {\n\t\t// If maxHeaderListSize overflows an int, use no limit (0).\n\t\treturn 0\n\t}\n\treturn v\n}\n\n// readMetaFrame returns 0 or more CONTINUATION frames from fr and\n// merge them into the provided hf and returns a MetaHeadersFrame\n// with the decoded hpack values.\nfunc (fr *Framer) readMetaFrame(hf *HeadersFrame) (Frame, error) {\n\tif fr.AllowIllegalReads {\n\t\treturn nil, errors.New(\"illegal use of AllowIllegalReads with ReadMetaHeaders\")\n\t}\n\tmh := &MetaHeadersFrame{\n\t\tHeadersFrame: hf,\n\t}\n\tvar remainSize = fr.maxHeaderListSize()\n\tvar sawRegular bool\n\n\tvar invalid error // pseudo header field errors\n\thdec := fr.ReadMetaHeaders\n\thdec.SetEmitEnabled(true)\n\thdec.SetMaxStringLength(fr.maxHeaderStringLen())\n\thdec.SetEmitFunc(func(hf hpack.HeaderField) {\n\t\tif VerboseLogs && fr.logReads {\n\t\t\tfr.debugReadLoggerf(\"http2: decoded hpack field %+v\", hf)\n\t\t}\n\t\tif !httpguts.ValidHeaderFieldValue(hf.Value) {\n\t\t\t// Don't include the value in the error, because it may be sensitive.\n\t\t\tinvalid = headerFieldValueError(hf.Name)\n\t\t}\n\t\tisPseudo := strings.HasPrefix(hf.Name, \":\")\n\t\tif isPseudo {\n\t\t\tif sawRegular {\n\t\t\t\tinvalid = errPseudoAfterRegular\n\t\t\t}\n\t\t} else {\n\t\t\tsawRegular = true\n\t\t\tif !validWireHeaderFieldName(hf.Name) {\n\t\t\t\tinvalid = headerFieldNameError(hf.Name)\n\t\t\t}\n\t\t}\n\n\t\tif invalid != nil {\n\t\t\thdec.SetEmitEnabled(false)\n\t\t\treturn\n\t\t}\n\n\t\tsize := hf.Size()\n\t\tif size > remainSize {\n\t\t\thdec.SetEmitEnabled(false)\n\t\t\tmh.Truncated = true\n\t\t\tremainSize = 0\n\t\t\treturn\n\t\t}\n\t\tremainSize -= size\n\n\t\tmh.Fields = append(mh.Fields, hf)\n\t})\n\t// Lose reference to MetaHeadersFrame:\n\tdefer hdec.SetEmitFunc(func(hf hpack.HeaderField) {})\n\n\tvar hc headersOrContinuation = hf\n\tfor {\n\t\tfrag := hc.HeaderBlockFragment()\n\n\t\t// Avoid parsing large amounts of headers that we will then discard.\n\t\t// If the sender exceeds the max header list size by too much,\n\t\t// skip parsing the fragment and close the connection.\n\t\t//\n\t\t// \"Too much\" is either any CONTINUATION frame after we've already\n\t\t// exceeded the max header list size (in which case remainSize is 0),\n\t\t// or a frame whose encoded size is more than twice the remaining\n\t\t// header list bytes we're willing to accept.\n\t\tif int64(len(frag)) > int64(2*remainSize) {\n\t\t\tif VerboseLogs {\n\t\t\t\tlog.Printf(\"http2: header list too large\")\n\t\t\t}\n\t\t\t// It would be nice to send a RST_STREAM before sending the GOAWAY,\n\t\t\t// but the structure of the server's frame writer makes this difficult.\n\t\t\treturn mh, ConnectionError(ErrCodeProtocol)\n\t\t}\n\n\t\t// Also close the connection after any CONTINUATION frame following an\n\t\t// invalid header, since we stop tracking the size of the headers after\n\t\t// an invalid one.\n\t\tif invalid != nil {\n\t\t\tif VerboseLogs {\n\t\t\t\tlog.Printf(\"http2: invalid header: %v\", invalid)\n\t\t\t}\n\t\t\t// It would be nice to send a RST_STREAM before sending the GOAWAY,\n\t\t\t// but the structure of the server's frame writer makes this difficult.\n\t\t\treturn mh, ConnectionError(ErrCodeProtocol)\n\t\t}\n\n\t\tif _, err := hdec.Write(frag); err != nil {\n\t\t\treturn mh, ConnectionError(ErrCodeCompression)\n\t\t}\n\n\t\tif hc.HeadersEnded() {\n\t\t\tbreak\n\t\t}\n\t\tif f, err := fr.ReadFrame(); err != nil {\n\t\t\treturn nil, err\n\t\t} else {\n\t\t\thc = f.(*ContinuationFrame) // guaranteed by checkFrameOrder\n\t\t}\n\t}\n\n\tmh.HeadersFrame.headerFragBuf = nil\n\tmh.HeadersFrame.invalidate()\n\n\tif err := hdec.Close(); err != nil {\n\t\treturn mh, ConnectionError(ErrCodeCompression)\n\t}\n\tif invalid != nil {\n\t\tfr.errDetail = invalid\n\t\tif VerboseLogs {\n\t\t\tlog.Printf(\"http2: invalid header: %v\", invalid)\n\t\t}\n\t\treturn nil, StreamError{mh.StreamID, ErrCodeProtocol, invalid}\n\t}\n\tif err := mh.checkPseudos(); err != nil {\n\t\tfr.errDetail = err\n\t\tif VerboseLogs {\n\t\t\tlog.Printf(\"http2: invalid pseudo headers: %v\", err)\n\t\t}\n\t\treturn nil, StreamError{mh.StreamID, ErrCodeProtocol, err}\n\t}\n\treturn mh, nil\n}\n\nfunc summarizeFrame(f Frame) string {\n\tvar buf bytes.Buffer\n\tf.Header().writeDebug(&buf)\n\tswitch f := f.(type) {\n\tcase *SettingsFrame:\n\t\tn := 0\n\t\tf.ForeachSetting(func(s Setting) error {\n\t\t\tn++\n\t\t\tif n == 1 {\n\t\t\t\tbuf.WriteString(\", settings:\")\n\t\t\t}\n\t\t\tfmt.Fprintf(&buf, \" %v=%v,\", s.ID, s.Val)\n\t\t\treturn nil\n\t\t})\n\t\tif n > 0 {\n\t\t\tbuf.Truncate(buf.Len() - 1) // remove trailing comma\n\t\t}\n\tcase *DataFrame:\n\t\tdata := f.Data()\n\t\tconst max = 256\n\t\tif len(data) > max {\n\t\t\tdata = data[:max]\n\t\t}\n\t\tfmt.Fprintf(&buf, \" data=%q\", data)\n\t\tif len(f.Data()) > max {\n\t\t\tfmt.Fprintf(&buf, \" (%d bytes omitted)\", len(f.Data())-max)\n\t\t}\n\tcase *WindowUpdateFrame:\n\t\tif f.StreamID == 0 {\n\t\t\tbuf.WriteString(\" (conn)\")\n\t\t}\n\t\tfmt.Fprintf(&buf, \" incr=%v\", f.Increment)\n\tcase *PingFrame:\n\t\tfmt.Fprintf(&buf, \" ping=%q\", f.Data[:])\n\tcase *GoAwayFrame:\n\t\tfmt.Fprintf(&buf, \" LastStreamID=%v ErrCode=%v Debug=%q\",\n\t\t\tf.LastStreamID, f.ErrCode, f.debugData)\n\tcase *RSTStreamFrame:\n\t\tfmt.Fprintf(&buf, \" ErrCode=%v\", f.ErrCode)\n\t}\n\treturn buf.String()\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/gotrack.go",
    "content": "// Copyright 2014 The Go 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\n// Defensive debug-only utility to track that functions run on the\n// goroutine that they're supposed to.\n\npackage http2\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"sync\"\n)\n\nvar DebugGoroutines = os.Getenv(\"DEBUG_HTTP2_GOROUTINES\") == \"1\"\n\ntype goroutineLock uint64\n\nfunc newGoroutineLock() goroutineLock {\n\tif !DebugGoroutines {\n\t\treturn 0\n\t}\n\treturn goroutineLock(curGoroutineID())\n}\n\nfunc (g goroutineLock) check() {\n\tif !DebugGoroutines {\n\t\treturn\n\t}\n\tif curGoroutineID() != uint64(g) {\n\t\tpanic(\"running on the wrong goroutine\")\n\t}\n}\n\nfunc (g goroutineLock) checkNotOn() {\n\tif !DebugGoroutines {\n\t\treturn\n\t}\n\tif curGoroutineID() == uint64(g) {\n\t\tpanic(\"running on the wrong goroutine\")\n\t}\n}\n\nvar goroutineSpace = []byte(\"goroutine \")\n\nfunc curGoroutineID() uint64 {\n\tbp := littleBuf.Get().(*[]byte)\n\tdefer littleBuf.Put(bp)\n\tb := *bp\n\tb = b[:runtime.Stack(b, false)]\n\t// Parse the 4707 out of \"goroutine 4707 [\"\n\tb = bytes.TrimPrefix(b, goroutineSpace)\n\ti := bytes.IndexByte(b, ' ')\n\tif i < 0 {\n\t\tpanic(fmt.Sprintf(\"No space found in %q\", b))\n\t}\n\tb = b[:i]\n\tn, err := parseUintBytes(b, 10, 64)\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"Failed to parse goroutine ID out of %q: %v\", b, err))\n\t}\n\treturn n\n}\n\nvar littleBuf = sync.Pool{\n\tNew: func() interface{} {\n\t\tbuf := make([]byte, 64)\n\t\treturn &buf\n\t},\n}\n\n// parseUintBytes is like strconv.ParseUint, but using a []byte.\nfunc parseUintBytes(s []byte, base int, bitSize int) (n uint64, err error) {\n\tvar cutoff, maxVal uint64\n\n\tif bitSize == 0 {\n\t\tbitSize = int(strconv.IntSize)\n\t}\n\n\ts0 := s\n\tswitch {\n\tcase len(s) < 1:\n\t\terr = strconv.ErrSyntax\n\t\tgoto Error\n\n\tcase 2 <= base && base <= 36:\n\t\t// valid base; nothing to do\n\n\tcase base == 0:\n\t\t// Look for octal, hex prefix.\n\t\tswitch {\n\t\tcase s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):\n\t\t\tbase = 16\n\t\t\ts = s[2:]\n\t\t\tif len(s) < 1 {\n\t\t\t\terr = strconv.ErrSyntax\n\t\t\t\tgoto Error\n\t\t\t}\n\t\tcase s[0] == '0':\n\t\t\tbase = 8\n\t\tdefault:\n\t\t\tbase = 10\n\t\t}\n\n\tdefault:\n\t\terr = errors.New(\"invalid base \" + strconv.Itoa(base))\n\t\tgoto Error\n\t}\n\n\tn = 0\n\tcutoff = cutoff64(base)\n\tmaxVal = 1<<uint(bitSize) - 1\n\n\tfor i := 0; i < len(s); i++ {\n\t\tvar v byte\n\t\td := s[i]\n\t\tswitch {\n\t\tcase '0' <= d && d <= '9':\n\t\t\tv = d - '0'\n\t\tcase 'a' <= d && d <= 'z':\n\t\t\tv = d - 'a' + 10\n\t\tcase 'A' <= d && d <= 'Z':\n\t\t\tv = d - 'A' + 10\n\t\tdefault:\n\t\t\tn = 0\n\t\t\terr = strconv.ErrSyntax\n\t\t\tgoto Error\n\t\t}\n\t\tif int(v) >= base {\n\t\t\tn = 0\n\t\t\terr = strconv.ErrSyntax\n\t\t\tgoto Error\n\t\t}\n\n\t\tif n >= cutoff {\n\t\t\t// n*base overflows\n\t\t\tn = 1<<64 - 1\n\t\t\terr = strconv.ErrRange\n\t\t\tgoto Error\n\t\t}\n\t\tn *= uint64(base)\n\n\t\tn1 := n + uint64(v)\n\t\tif n1 < n || n1 > maxVal {\n\t\t\t// n+v overflows\n\t\t\tn = 1<<64 - 1\n\t\t\terr = strconv.ErrRange\n\t\t\tgoto Error\n\t\t}\n\t\tn = n1\n\t}\n\n\treturn n, nil\n\nError:\n\treturn n, &strconv.NumError{Func: \"ParseUint\", Num: string(s0), Err: err}\n}\n\n// Return the first number n such that n*base >= 1<<64.\nfunc cutoff64(base int) uint64 {\n\tif base < 2 {\n\t\treturn 0\n\t}\n\treturn (1<<64-1)/uint64(base) + 1\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/hpack/encode.go",
    "content": "// Copyright 2014 The Go 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 hpack\n\nimport (\n\t\"io\"\n)\n\nconst (\n\tuint32Max              = ^uint32(0)\n\tinitialHeaderTableSize = 4096\n)\n\ntype Encoder struct {\n\tdynTab dynamicTable\n\t// minSize is the minimum table size set by\n\t// SetMaxDynamicTableSize after the previous Header Table Size\n\t// Update.\n\tminSize uint32\n\t// maxSizeLimit is the maximum table size this encoder\n\t// supports. This will protect the encoder from too large\n\t// size.\n\tmaxSizeLimit uint32\n\t// tableSizeUpdate indicates whether \"Header Table Size\n\t// Update\" is required.\n\ttableSizeUpdate bool\n\tw               io.Writer\n\tbuf             []byte\n}\n\n// NewEncoder returns a new Encoder which performs HPACK encoding. An\n// encoded data is written to w.\nfunc NewEncoder(w io.Writer) *Encoder {\n\te := &Encoder{\n\t\tminSize:         uint32Max,\n\t\tmaxSizeLimit:    initialHeaderTableSize,\n\t\ttableSizeUpdate: false,\n\t\tw:               w,\n\t}\n\te.dynTab.table.init()\n\te.dynTab.setMaxSize(initialHeaderTableSize)\n\treturn e\n}\n\n// WriteField encodes f into a single Write to e's underlying Writer.\n// This function may also produce bytes for \"Header Table Size Update\"\n// if necessary. If produced, it is done before encoding f.\nfunc (e *Encoder) WriteField(f HeaderField) error {\n\te.buf = e.buf[:0]\n\n\tif e.tableSizeUpdate {\n\t\te.tableSizeUpdate = false\n\t\tif e.minSize < e.dynTab.maxSize {\n\t\t\te.buf = appendTableSize(e.buf, e.minSize)\n\t\t}\n\t\te.minSize = uint32Max\n\t\te.buf = appendTableSize(e.buf, e.dynTab.maxSize)\n\t}\n\n\tidx, nameValueMatch := e.searchTable(f)\n\tif nameValueMatch {\n\t\te.buf = appendIndexed(e.buf, idx)\n\t} else {\n\t\tindexing := e.shouldIndex(f)\n\t\tif indexing {\n\t\t\te.dynTab.add(f)\n\t\t}\n\n\t\tif idx == 0 {\n\t\t\te.buf = appendNewName(e.buf, f, indexing)\n\t\t} else {\n\t\t\te.buf = appendIndexedName(e.buf, f, idx, indexing)\n\t\t}\n\t}\n\tn, err := e.w.Write(e.buf)\n\tif err == nil && n != len(e.buf) {\n\t\terr = io.ErrShortWrite\n\t}\n\treturn err\n}\n\n// searchTable searches f in both stable and dynamic header tables.\n// The static header table is searched first. Only when there is no\n// exact match for both name and value, the dynamic header table is\n// then searched. If there is no match, i is 0. If both name and value\n// match, i is the matched index and nameValueMatch becomes true. If\n// only name matches, i points to that index and nameValueMatch\n// becomes false.\nfunc (e *Encoder) searchTable(f HeaderField) (i uint64, nameValueMatch bool) {\n\ti, nameValueMatch = staticTable.search(f)\n\tif nameValueMatch {\n\t\treturn i, true\n\t}\n\n\tj, nameValueMatch := e.dynTab.table.search(f)\n\tif nameValueMatch || (i == 0 && j != 0) {\n\t\treturn j + uint64(staticTable.len()), nameValueMatch\n\t}\n\n\treturn i, false\n}\n\n// SetMaxDynamicTableSize changes the dynamic header table size to v.\n// The actual size is bounded by the value passed to\n// SetMaxDynamicTableSizeLimit.\nfunc (e *Encoder) SetMaxDynamicTableSize(v uint32) {\n\tif v > e.maxSizeLimit {\n\t\tv = e.maxSizeLimit\n\t}\n\tif v < e.minSize {\n\t\te.minSize = v\n\t}\n\te.tableSizeUpdate = true\n\te.dynTab.setMaxSize(v)\n}\n\n// MaxDynamicTableSize returns the current dynamic header table size.\nfunc (e *Encoder) MaxDynamicTableSize() (v uint32) {\n\treturn e.dynTab.maxSize\n}\n\n// SetMaxDynamicTableSizeLimit changes the maximum value that can be\n// specified in SetMaxDynamicTableSize to v. By default, it is set to\n// 4096, which is the same size of the default dynamic header table\n// size described in HPACK specification. If the current maximum\n// dynamic header table size is strictly greater than v, \"Header Table\n// Size Update\" will be done in the next WriteField call and the\n// maximum dynamic header table size is truncated to v.\nfunc (e *Encoder) SetMaxDynamicTableSizeLimit(v uint32) {\n\te.maxSizeLimit = v\n\tif e.dynTab.maxSize > v {\n\t\te.tableSizeUpdate = true\n\t\te.dynTab.setMaxSize(v)\n\t}\n}\n\n// shouldIndex reports whether f should be indexed.\nfunc (e *Encoder) shouldIndex(f HeaderField) bool {\n\treturn !f.Sensitive && f.Size() <= e.dynTab.maxSize\n}\n\n// appendIndexed appends index i, as encoded in \"Indexed Header Field\"\n// representation, to dst and returns the extended buffer.\nfunc appendIndexed(dst []byte, i uint64) []byte {\n\tfirst := len(dst)\n\tdst = appendVarInt(dst, 7, i)\n\tdst[first] |= 0x80\n\treturn dst\n}\n\n// appendNewName appends f, as encoded in one of \"Literal Header field\n// - New Name\" representation variants, to dst and returns the\n// extended buffer.\n//\n// If f.Sensitive is true, \"Never Indexed\" representation is used. If\n// f.Sensitive is false and indexing is true, \"Incremental Indexing\"\n// representation is used.\nfunc appendNewName(dst []byte, f HeaderField, indexing bool) []byte {\n\tdst = append(dst, encodeTypeByte(indexing, f.Sensitive))\n\tdst = appendHpackString(dst, f.Name)\n\treturn appendHpackString(dst, f.Value)\n}\n\n// appendIndexedName appends f and index i referring indexed name\n// entry, as encoded in one of \"Literal Header field - Indexed Name\"\n// representation variants, to dst and returns the extended buffer.\n//\n// If f.Sensitive is true, \"Never Indexed\" representation is used. If\n// f.Sensitive is false and indexing is true, \"Incremental Indexing\"\n// representation is used.\nfunc appendIndexedName(dst []byte, f HeaderField, i uint64, indexing bool) []byte {\n\tfirst := len(dst)\n\tvar n byte\n\tif indexing {\n\t\tn = 6\n\t} else {\n\t\tn = 4\n\t}\n\tdst = appendVarInt(dst, n, i)\n\tdst[first] |= encodeTypeByte(indexing, f.Sensitive)\n\treturn appendHpackString(dst, f.Value)\n}\n\n// appendTableSize appends v, as encoded in \"Header Table Size Update\"\n// representation, to dst and returns the extended buffer.\nfunc appendTableSize(dst []byte, v uint32) []byte {\n\tfirst := len(dst)\n\tdst = appendVarInt(dst, 5, uint64(v))\n\tdst[first] |= 0x20\n\treturn dst\n}\n\n// appendVarInt appends i, as encoded in variable integer form using n\n// bit prefix, to dst and returns the extended buffer.\n//\n// See\n// https://httpwg.org/specs/rfc7541.html#integer.representation\nfunc appendVarInt(dst []byte, n byte, i uint64) []byte {\n\tk := uint64((1 << n) - 1)\n\tif i < k {\n\t\treturn append(dst, byte(i))\n\t}\n\tdst = append(dst, byte(k))\n\ti -= k\n\tfor ; i >= 128; i >>= 7 {\n\t\tdst = append(dst, byte(0x80|(i&0x7f)))\n\t}\n\treturn append(dst, byte(i))\n}\n\n// appendHpackString appends s, as encoded in \"String Literal\"\n// representation, to dst and returns the extended buffer.\n//\n// s will be encoded in Huffman codes only when it produces strictly\n// shorter byte string.\nfunc appendHpackString(dst []byte, s string) []byte {\n\thuffmanLength := HuffmanEncodeLength(s)\n\tif huffmanLength < uint64(len(s)) {\n\t\tfirst := len(dst)\n\t\tdst = appendVarInt(dst, 7, huffmanLength)\n\t\tdst = AppendHuffmanString(dst, s)\n\t\tdst[first] |= 0x80\n\t} else {\n\t\tdst = appendVarInt(dst, 7, uint64(len(s)))\n\t\tdst = append(dst, s...)\n\t}\n\treturn dst\n}\n\n// encodeTypeByte returns type byte. If sensitive is true, type byte\n// for \"Never Indexed\" representation is returned. If sensitive is\n// false and indexing is true, type byte for \"Incremental Indexing\"\n// representation is returned. Otherwise, type byte for \"Without\n// Indexing\" is returned.\nfunc encodeTypeByte(indexing, sensitive bool) byte {\n\tif sensitive {\n\t\treturn 0x10\n\t}\n\tif indexing {\n\t\treturn 0x40\n\t}\n\treturn 0\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/hpack/hpack.go",
    "content": "// Copyright 2014 The Go 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\n// Package hpack implements HPACK, a compression format for\n// efficiently representing HTTP header fields in the context of HTTP/2.\n//\n// See http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-09\npackage hpack\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n)\n\n// A DecodingError is something the spec defines as a decoding error.\ntype DecodingError struct {\n\tErr error\n}\n\nfunc (de DecodingError) Error() string {\n\treturn fmt.Sprintf(\"decoding error: %v\", de.Err)\n}\n\n// An InvalidIndexError is returned when an encoder references a table\n// entry before the static table or after the end of the dynamic table.\ntype InvalidIndexError int\n\nfunc (e InvalidIndexError) Error() string {\n\treturn fmt.Sprintf(\"invalid indexed representation index %d\", int(e))\n}\n\n// A HeaderField is a name-value pair. Both the name and value are\n// treated as opaque sequences of octets.\ntype HeaderField struct {\n\tName, Value string\n\n\t// Sensitive means that this header field should never be\n\t// indexed.\n\tSensitive bool\n}\n\n// IsPseudo reports whether the header field is an http2 pseudo header.\n// That is, it reports whether it starts with a colon.\n// It is not otherwise guaranteed to be a valid pseudo header field,\n// though.\nfunc (hf HeaderField) IsPseudo() bool {\n\treturn len(hf.Name) != 0 && hf.Name[0] == ':'\n}\n\nfunc (hf HeaderField) String() string {\n\tvar suffix string\n\tif hf.Sensitive {\n\t\tsuffix = \" (sensitive)\"\n\t}\n\treturn fmt.Sprintf(\"header field %q = %q%s\", hf.Name, hf.Value, suffix)\n}\n\n// Size returns the size of an entry per RFC 7541 section 4.1.\nfunc (hf HeaderField) Size() uint32 {\n\t// https://httpwg.org/specs/rfc7541.html#rfc.section.4.1\n\t// \"The size of the dynamic table is the sum of the size of\n\t// its entries. The size of an entry is the sum of its name's\n\t// length in octets (as defined in Section 5.2), its value's\n\t// length in octets (see Section 5.2), plus 32.  The size of\n\t// an entry is calculated using the length of the name and\n\t// value without any Huffman encoding applied.\"\n\n\t// This can overflow if somebody makes a large HeaderField\n\t// Name and/or Value by hand, but we don't care, because that\n\t// won't happen on the wire because the encoding doesn't allow\n\t// it.\n\treturn uint32(len(hf.Name) + len(hf.Value) + 32)\n}\n\n// A Decoder is the decoding context for incremental processing of\n// header blocks.\ntype Decoder struct {\n\tdynTab dynamicTable\n\temit   func(f HeaderField)\n\n\temitEnabled bool // whether calls to emit are enabled\n\tmaxStrLen   int  // 0 means unlimited\n\n\t// buf is the unparsed buffer. It's only written to\n\t// saveBuf if it was truncated in the middle of a header\n\t// block. Because it's usually not owned, we can only\n\t// process it under Write.\n\tbuf []byte // not owned; only valid during Write\n\n\t// saveBuf is previous data passed to Write which we weren't able\n\t// to fully parse before. Unlike buf, we own this data.\n\tsaveBuf bytes.Buffer\n\n\tfirstField bool // processing the first field of the header block\n}\n\n// NewDecoder returns a new decoder with the provided maximum dynamic\n// table size. The emitFunc will be called for each valid field\n// parsed, in the same goroutine as calls to Write, before Write returns.\nfunc NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decoder {\n\td := &Decoder{\n\t\temit:        emitFunc,\n\t\temitEnabled: true,\n\t\tfirstField:  true,\n\t}\n\td.dynTab.table.init()\n\td.dynTab.allowedMaxSize = maxDynamicTableSize\n\td.dynTab.setMaxSize(maxDynamicTableSize)\n\treturn d\n}\n\n// ErrStringLength is returned by Decoder.Write when the max string length\n// (as configured by Decoder.SetMaxStringLength) would be violated.\nvar ErrStringLength = errors.New(\"hpack: string too long\")\n\n// SetMaxStringLength sets the maximum size of a HeaderField name or\n// value string. If a string exceeds this length (even after any\n// decompression), Write will return ErrStringLength.\n// A value of 0 means unlimited and is the default from NewDecoder.\nfunc (d *Decoder) SetMaxStringLength(n int) {\n\td.maxStrLen = n\n}\n\n// SetEmitFunc changes the callback used when new header fields\n// are decoded.\n// It must be non-nil. It does not affect EmitEnabled.\nfunc (d *Decoder) SetEmitFunc(emitFunc func(f HeaderField)) {\n\td.emit = emitFunc\n}\n\n// SetEmitEnabled controls whether the emitFunc provided to NewDecoder\n// should be called. The default is true.\n//\n// This facility exists to let servers enforce MAX_HEADER_LIST_SIZE\n// while still decoding and keeping in-sync with decoder state, but\n// without doing unnecessary decompression or generating unnecessary\n// garbage for header fields past the limit.\nfunc (d *Decoder) SetEmitEnabled(v bool) { d.emitEnabled = v }\n\n// EmitEnabled reports whether calls to the emitFunc provided to NewDecoder\n// are currently enabled. The default is true.\nfunc (d *Decoder) EmitEnabled() bool { return d.emitEnabled }\n\n// TODO: add method *Decoder.Reset(maxSize, emitFunc) to let callers re-use Decoders and their\n// underlying buffers for garbage reasons.\n\nfunc (d *Decoder) SetMaxDynamicTableSize(v uint32) {\n\td.dynTab.setMaxSize(v)\n}\n\n// SetAllowedMaxDynamicTableSize sets the upper bound that the encoded\n// stream (via dynamic table size updates) may set the maximum size\n// to.\nfunc (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) {\n\td.dynTab.allowedMaxSize = v\n}\n\ntype dynamicTable struct {\n\t// https://httpwg.org/specs/rfc7541.html#rfc.section.2.3.2\n\ttable          headerFieldTable\n\tsize           uint32 // in bytes\n\tmaxSize        uint32 // current maxSize\n\tallowedMaxSize uint32 // maxSize may go up to this, inclusive\n}\n\nfunc (dt *dynamicTable) setMaxSize(v uint32) {\n\tdt.maxSize = v\n\tdt.evict()\n}\n\nfunc (dt *dynamicTable) add(f HeaderField) {\n\tdt.table.addEntry(f)\n\tdt.size += f.Size()\n\tdt.evict()\n}\n\n// If we're too big, evict old stuff.\nfunc (dt *dynamicTable) evict() {\n\tvar n int\n\tfor dt.size > dt.maxSize && n < dt.table.len() {\n\t\tdt.size -= dt.table.ents[n].Size()\n\t\tn++\n\t}\n\tdt.table.evictOldest(n)\n}\n\nfunc (d *Decoder) maxTableIndex() int {\n\t// This should never overflow. RFC 7540 Section 6.5.2 limits the size of\n\t// the dynamic table to 2^32 bytes, where each entry will occupy more than\n\t// one byte. Further, the staticTable has a fixed, small length.\n\treturn d.dynTab.table.len() + staticTable.len()\n}\n\nfunc (d *Decoder) at(i uint64) (hf HeaderField, ok bool) {\n\t// See Section 2.3.3.\n\tif i == 0 {\n\t\treturn\n\t}\n\tif i <= uint64(staticTable.len()) {\n\t\treturn staticTable.ents[i-1], true\n\t}\n\tif i > uint64(d.maxTableIndex()) {\n\t\treturn\n\t}\n\t// In the dynamic table, newer entries have lower indices.\n\t// However, dt.ents[0] is the oldest entry. Hence, dt.ents is\n\t// the reversed dynamic table.\n\tdt := d.dynTab.table\n\treturn dt.ents[dt.len()-(int(i)-staticTable.len())], true\n}\n\n// DecodeFull decodes an entire block.\n//\n// TODO: remove this method and make it incremental later? This is\n// easier for debugging now.\nfunc (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) {\n\tvar hf []HeaderField\n\tsaveFunc := d.emit\n\tdefer func() { d.emit = saveFunc }()\n\td.emit = func(f HeaderField) { hf = append(hf, f) }\n\tif _, err := d.Write(p); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := d.Close(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn hf, nil\n}\n\n// Close declares that the decoding is complete and resets the Decoder\n// to be reused again for a new header block. If there is any remaining\n// data in the decoder's buffer, Close returns an error.\nfunc (d *Decoder) Close() error {\n\tif d.saveBuf.Len() > 0 {\n\t\td.saveBuf.Reset()\n\t\treturn DecodingError{errors.New(\"truncated headers\")}\n\t}\n\td.firstField = true\n\treturn nil\n}\n\nfunc (d *Decoder) Write(p []byte) (n int, err error) {\n\tif len(p) == 0 {\n\t\t// Prevent state machine CPU attacks (making us redo\n\t\t// work up to the point of finding out we don't have\n\t\t// enough data)\n\t\treturn\n\t}\n\t// Only copy the data if we have to. Optimistically assume\n\t// that p will contain a complete header block.\n\tif d.saveBuf.Len() == 0 {\n\t\td.buf = p\n\t} else {\n\t\td.saveBuf.Write(p)\n\t\td.buf = d.saveBuf.Bytes()\n\t\td.saveBuf.Reset()\n\t}\n\n\tfor len(d.buf) > 0 {\n\t\terr = d.parseHeaderFieldRepr()\n\t\tif err == errNeedMore {\n\t\t\t// Extra paranoia, making sure saveBuf won't\n\t\t\t// get too large. All the varint and string\n\t\t\t// reading code earlier should already catch\n\t\t\t// overlong things and return ErrStringLength,\n\t\t\t// but keep this as a last resort.\n\t\t\tconst varIntOverhead = 8 // conservative\n\t\t\tif d.maxStrLen != 0 && int64(len(d.buf)) > 2*(int64(d.maxStrLen)+varIntOverhead) {\n\t\t\t\treturn 0, ErrStringLength\n\t\t\t}\n\t\t\td.saveBuf.Write(d.buf)\n\t\t\treturn len(p), nil\n\t\t}\n\t\td.firstField = false\n\t\tif err != nil {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn len(p), err\n}\n\n// errNeedMore is an internal sentinel error value that means the\n// buffer is truncated and we need to read more data before we can\n// continue parsing.\nvar errNeedMore = errors.New(\"need more data\")\n\ntype indexType int\n\nconst (\n\tindexedTrue indexType = iota\n\tindexedFalse\n\tindexedNever\n)\n\nfunc (v indexType) indexed() bool   { return v == indexedTrue }\nfunc (v indexType) sensitive() bool { return v == indexedNever }\n\n// returns errNeedMore if there isn't enough data available.\n// any other error is fatal.\n// consumes d.buf iff it returns nil.\n// precondition: must be called with len(d.buf) > 0\nfunc (d *Decoder) parseHeaderFieldRepr() error {\n\tb := d.buf[0]\n\tswitch {\n\tcase b&128 != 0:\n\t\t// Indexed representation.\n\t\t// High bit set?\n\t\t// https://httpwg.org/specs/rfc7541.html#rfc.section.6.1\n\t\treturn d.parseFieldIndexed()\n\tcase b&192 == 64:\n\t\t// 6.2.1 Literal Header Field with Incremental Indexing\n\t\t// 0b10xxxxxx: top two bits are 10\n\t\t// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.1\n\t\treturn d.parseFieldLiteral(6, indexedTrue)\n\tcase b&240 == 0:\n\t\t// 6.2.2 Literal Header Field without Indexing\n\t\t// 0b0000xxxx: top four bits are 0000\n\t\t// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.2\n\t\treturn d.parseFieldLiteral(4, indexedFalse)\n\tcase b&240 == 16:\n\t\t// 6.2.3 Literal Header Field never Indexed\n\t\t// 0b0001xxxx: top four bits are 0001\n\t\t// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.3\n\t\treturn d.parseFieldLiteral(4, indexedNever)\n\tcase b&224 == 32:\n\t\t// 6.3 Dynamic Table Size Update\n\t\t// Top three bits are '001'.\n\t\t// https://httpwg.org/specs/rfc7541.html#rfc.section.6.3\n\t\treturn d.parseDynamicTableSizeUpdate()\n\t}\n\n\treturn DecodingError{errors.New(\"invalid encoding\")}\n}\n\n// (same invariants and behavior as parseHeaderFieldRepr)\nfunc (d *Decoder) parseFieldIndexed() error {\n\tbuf := d.buf\n\tidx, buf, err := readVarInt(7, buf)\n\tif err != nil {\n\t\treturn err\n\t}\n\thf, ok := d.at(idx)\n\tif !ok {\n\t\treturn DecodingError{InvalidIndexError(idx)}\n\t}\n\td.buf = buf\n\treturn d.callEmit(HeaderField{Name: hf.Name, Value: hf.Value})\n}\n\n// (same invariants and behavior as parseHeaderFieldRepr)\nfunc (d *Decoder) parseFieldLiteral(n uint8, it indexType) error {\n\tbuf := d.buf\n\tnameIdx, buf, err := readVarInt(n, buf)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar hf HeaderField\n\twantStr := d.emitEnabled || it.indexed()\n\tvar undecodedName undecodedString\n\tif nameIdx > 0 {\n\t\tihf, ok := d.at(nameIdx)\n\t\tif !ok {\n\t\t\treturn DecodingError{InvalidIndexError(nameIdx)}\n\t\t}\n\t\thf.Name = ihf.Name\n\t} else {\n\t\tundecodedName, buf, err = d.readString(buf)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tundecodedValue, buf, err := d.readString(buf)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif wantStr {\n\t\tif nameIdx <= 0 {\n\t\t\thf.Name, err = d.decodeString(undecodedName)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\thf.Value, err = d.decodeString(undecodedValue)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\td.buf = buf\n\tif it.indexed() {\n\t\td.dynTab.add(hf)\n\t}\n\thf.Sensitive = it.sensitive()\n\treturn d.callEmit(hf)\n}\n\nfunc (d *Decoder) callEmit(hf HeaderField) error {\n\tif d.maxStrLen != 0 {\n\t\tif len(hf.Name) > d.maxStrLen || len(hf.Value) > d.maxStrLen {\n\t\t\treturn ErrStringLength\n\t\t}\n\t}\n\tif d.emitEnabled {\n\t\td.emit(hf)\n\t}\n\treturn nil\n}\n\n// (same invariants and behavior as parseHeaderFieldRepr)\nfunc (d *Decoder) parseDynamicTableSizeUpdate() error {\n\t// RFC 7541, sec 4.2: This dynamic table size update MUST occur at the\n\t// beginning of the first header block following the change to the dynamic table size.\n\tif !d.firstField && d.dynTab.size > 0 {\n\t\treturn DecodingError{errors.New(\"dynamic table size update MUST occur at the beginning of a header block\")}\n\t}\n\n\tbuf := d.buf\n\tsize, buf, err := readVarInt(5, buf)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif size > uint64(d.dynTab.allowedMaxSize) {\n\t\treturn DecodingError{errors.New(\"dynamic table size update too large\")}\n\t}\n\td.dynTab.setMaxSize(uint32(size))\n\td.buf = buf\n\treturn nil\n}\n\nvar errVarintOverflow = DecodingError{errors.New(\"varint integer overflow\")}\n\n// readVarInt reads an unsigned variable length integer off the\n// beginning of p. n is the parameter as described in\n// https://httpwg.org/specs/rfc7541.html#rfc.section.5.1.\n//\n// n must always be between 1 and 8.\n//\n// The returned remain buffer is either a smaller suffix of p, or err != nil.\n// The error is errNeedMore if p doesn't contain a complete integer.\nfunc readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) {\n\tif n < 1 || n > 8 {\n\t\tpanic(\"bad n\")\n\t}\n\tif len(p) == 0 {\n\t\treturn 0, p, errNeedMore\n\t}\n\ti = uint64(p[0])\n\tif n < 8 {\n\t\ti &= (1 << uint64(n)) - 1\n\t}\n\tif i < (1<<uint64(n))-1 {\n\t\treturn i, p[1:], nil\n\t}\n\n\torigP := p\n\tp = p[1:]\n\tvar m uint64\n\tfor len(p) > 0 {\n\t\tb := p[0]\n\t\tp = p[1:]\n\t\ti += uint64(b&127) << m\n\t\tif b&128 == 0 {\n\t\t\treturn i, p, nil\n\t\t}\n\t\tm += 7\n\t\tif m >= 63 { // TODO: proper overflow check. making this up.\n\t\t\treturn 0, origP, errVarintOverflow\n\t\t}\n\t}\n\treturn 0, origP, errNeedMore\n}\n\n// readString reads an hpack string from p.\n//\n// It returns a reference to the encoded string data to permit deferring decode costs\n// until after the caller verifies all data is present.\nfunc (d *Decoder) readString(p []byte) (u undecodedString, remain []byte, err error) {\n\tif len(p) == 0 {\n\t\treturn u, p, errNeedMore\n\t}\n\tisHuff := p[0]&128 != 0\n\tstrLen, p, err := readVarInt(7, p)\n\tif err != nil {\n\t\treturn u, p, err\n\t}\n\tif d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) {\n\t\t// Returning an error here means Huffman decoding errors\n\t\t// for non-indexed strings past the maximum string length\n\t\t// are ignored, but the server is returning an error anyway\n\t\t// and because the string is not indexed the error will not\n\t\t// affect the decoding state.\n\t\treturn u, nil, ErrStringLength\n\t}\n\tif uint64(len(p)) < strLen {\n\t\treturn u, p, errNeedMore\n\t}\n\tu.isHuff = isHuff\n\tu.b = p[:strLen]\n\treturn u, p[strLen:], nil\n}\n\ntype undecodedString struct {\n\tisHuff bool\n\tb      []byte\n}\n\nfunc (d *Decoder) decodeString(u undecodedString) (string, error) {\n\tif !u.isHuff {\n\t\treturn string(u.b), nil\n\t}\n\tbuf := bufPool.Get().(*bytes.Buffer)\n\tbuf.Reset() // don't trust others\n\tvar s string\n\terr := huffmanDecode(buf, d.maxStrLen, u.b)\n\tif err == nil {\n\t\ts = buf.String()\n\t}\n\tbuf.Reset() // be nice to GC\n\tbufPool.Put(buf)\n\treturn s, err\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/hpack/huffman.go",
    "content": "// Copyright 2014 The Go 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 hpack\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"io\"\n\t\"sync\"\n)\n\nvar bufPool = sync.Pool{\n\tNew: func() interface{} { return new(bytes.Buffer) },\n}\n\n// HuffmanDecode decodes the string in v and writes the expanded\n// result to w, returning the number of bytes written to w and the\n// Write call's return value. At most one Write call is made.\nfunc HuffmanDecode(w io.Writer, v []byte) (int, error) {\n\tbuf := bufPool.Get().(*bytes.Buffer)\n\tbuf.Reset()\n\tdefer bufPool.Put(buf)\n\tif err := huffmanDecode(buf, 0, v); err != nil {\n\t\treturn 0, err\n\t}\n\treturn w.Write(buf.Bytes())\n}\n\n// HuffmanDecodeToString decodes the string in v.\nfunc HuffmanDecodeToString(v []byte) (string, error) {\n\tbuf := bufPool.Get().(*bytes.Buffer)\n\tbuf.Reset()\n\tdefer bufPool.Put(buf)\n\tif err := huffmanDecode(buf, 0, v); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn buf.String(), nil\n}\n\n// ErrInvalidHuffman is returned for errors found decoding\n// Huffman-encoded strings.\nvar ErrInvalidHuffman = errors.New(\"hpack: invalid Huffman-encoded data\")\n\n// huffmanDecode decodes v to buf.\n// If maxLen is greater than 0, attempts to write more to buf than\n// maxLen bytes will return ErrStringLength.\nfunc huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {\n\trootHuffmanNode := getRootHuffmanNode()\n\tn := rootHuffmanNode\n\t// cur is the bit buffer that has not been fed into n.\n\t// cbits is the number of low order bits in cur that are valid.\n\t// sbits is the number of bits of the symbol prefix being decoded.\n\tcur, cbits, sbits := uint(0), uint8(0), uint8(0)\n\tfor _, b := range v {\n\t\tcur = cur<<8 | uint(b)\n\t\tcbits += 8\n\t\tsbits += 8\n\t\tfor cbits >= 8 {\n\t\t\tidx := byte(cur >> (cbits - 8))\n\t\t\tn = n.children[idx]\n\t\t\tif n == nil {\n\t\t\t\treturn ErrInvalidHuffman\n\t\t\t}\n\t\t\tif n.children == nil {\n\t\t\t\tif maxLen != 0 && buf.Len() == maxLen {\n\t\t\t\t\treturn ErrStringLength\n\t\t\t\t}\n\t\t\t\tbuf.WriteByte(n.sym)\n\t\t\t\tcbits -= n.codeLen\n\t\t\t\tn = rootHuffmanNode\n\t\t\t\tsbits = cbits\n\t\t\t} else {\n\t\t\t\tcbits -= 8\n\t\t\t}\n\t\t}\n\t}\n\tfor cbits > 0 {\n\t\tn = n.children[byte(cur<<(8-cbits))]\n\t\tif n == nil {\n\t\t\treturn ErrInvalidHuffman\n\t\t}\n\t\tif n.children != nil || n.codeLen > cbits {\n\t\t\tbreak\n\t\t}\n\t\tif maxLen != 0 && buf.Len() == maxLen {\n\t\t\treturn ErrStringLength\n\t\t}\n\t\tbuf.WriteByte(n.sym)\n\t\tcbits -= n.codeLen\n\t\tn = rootHuffmanNode\n\t\tsbits = cbits\n\t}\n\tif sbits > 7 {\n\t\t// Either there was an incomplete symbol, or overlong padding.\n\t\t// Both are decoding errors per RFC 7541 section 5.2.\n\t\treturn ErrInvalidHuffman\n\t}\n\tif mask := uint(1<<cbits - 1); cur&mask != mask {\n\t\t// Trailing bits must be a prefix of EOS per RFC 7541 section 5.2.\n\t\treturn ErrInvalidHuffman\n\t}\n\n\treturn nil\n}\n\n// incomparable is a zero-width, non-comparable type. Adding it to a struct\n// makes that struct also non-comparable, and generally doesn't add\n// any size (as long as it's first).\ntype incomparable [0]func()\n\ntype node struct {\n\t_ incomparable\n\n\t// children is non-nil for internal nodes\n\tchildren *[256]*node\n\n\t// The following are only valid if children is nil:\n\tcodeLen uint8 // number of bits that led to the output of sym\n\tsym     byte  // output symbol\n}\n\nfunc newInternalNode() *node {\n\treturn &node{children: new([256]*node)}\n}\n\nvar (\n\tbuildRootOnce       sync.Once\n\tlazyRootHuffmanNode *node\n)\n\nfunc getRootHuffmanNode() *node {\n\tbuildRootOnce.Do(buildRootHuffmanNode)\n\treturn lazyRootHuffmanNode\n}\n\nfunc buildRootHuffmanNode() {\n\tif len(huffmanCodes) != 256 {\n\t\tpanic(\"unexpected size\")\n\t}\n\tlazyRootHuffmanNode = newInternalNode()\n\t// allocate a leaf node for each of the 256 symbols\n\tleaves := new([256]node)\n\n\tfor sym, code := range huffmanCodes {\n\t\tcodeLen := huffmanCodeLen[sym]\n\n\t\tcur := lazyRootHuffmanNode\n\t\tfor codeLen > 8 {\n\t\t\tcodeLen -= 8\n\t\t\ti := uint8(code >> codeLen)\n\t\t\tif cur.children[i] == nil {\n\t\t\t\tcur.children[i] = newInternalNode()\n\t\t\t}\n\t\t\tcur = cur.children[i]\n\t\t}\n\t\tshift := 8 - codeLen\n\t\tstart, end := int(uint8(code<<shift)), int(1<<shift)\n\n\t\tleaves[sym].sym = byte(sym)\n\t\tleaves[sym].codeLen = codeLen\n\t\tfor i := start; i < start+end; i++ {\n\t\t\tcur.children[i] = &leaves[sym]\n\t\t}\n\t}\n}\n\n// AppendHuffmanString appends s, as encoded in Huffman codes, to dst\n// and returns the extended buffer.\nfunc AppendHuffmanString(dst []byte, s string) []byte {\n\t// This relies on the maximum huffman code length being 30 (See tables.go huffmanCodeLen array)\n\t// So if a uint64 buffer has less than 32 valid bits can always accommodate another huffmanCode.\n\tvar (\n\t\tx uint64 // buffer\n\t\tn uint   // number valid of bits present in x\n\t)\n\tfor i := 0; i < len(s); i++ {\n\t\tc := s[i]\n\t\tn += uint(huffmanCodeLen[c])\n\t\tx <<= huffmanCodeLen[c] % 64\n\t\tx |= uint64(huffmanCodes[c])\n\t\tif n >= 32 {\n\t\t\tn %= 32             // Normally would be -= 32 but %= 32 informs compiler 0 <= n <= 31 for upcoming shift\n\t\t\ty := uint32(x >> n) // Compiler doesn't combine memory writes if y isn't uint32\n\t\t\tdst = append(dst, byte(y>>24), byte(y>>16), byte(y>>8), byte(y))\n\t\t}\n\t}\n\t// Add padding bits if necessary\n\tif over := n % 8; over > 0 {\n\t\tconst (\n\t\t\teosCode    = 0x3fffffff\n\t\t\teosNBits   = 30\n\t\t\teosPadByte = eosCode >> (eosNBits - 8)\n\t\t)\n\t\tpad := 8 - over\n\t\tx = (x << pad) | (eosPadByte >> over)\n\t\tn += pad // 8 now divides into n exactly\n\t}\n\t// n in (0, 8, 16, 24, 32)\n\tswitch n / 8 {\n\tcase 0:\n\t\treturn dst\n\tcase 1:\n\t\treturn append(dst, byte(x))\n\tcase 2:\n\t\ty := uint16(x)\n\t\treturn append(dst, byte(y>>8), byte(y))\n\tcase 3:\n\t\ty := uint16(x >> 8)\n\t\treturn append(dst, byte(y>>8), byte(y), byte(x))\n\t}\n\t//\tcase 4:\n\ty := uint32(x)\n\treturn append(dst, byte(y>>24), byte(y>>16), byte(y>>8), byte(y))\n}\n\n// HuffmanEncodeLength returns the number of bytes required to encode\n// s in Huffman codes. The result is round up to byte boundary.\nfunc HuffmanEncodeLength(s string) uint64 {\n\tn := uint64(0)\n\tfor i := 0; i < len(s); i++ {\n\t\tn += uint64(huffmanCodeLen[s[i]])\n\t}\n\treturn (n + 7) / 8\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/hpack/static_table.go",
    "content": "// go generate gen.go\n// Code generated by the command above; DO NOT EDIT.\n\npackage hpack\n\nvar staticTable = &headerFieldTable{\n\tevictCount: 0,\n\tbyName: map[string]uint64{\n\t\t\":authority\":                  1,\n\t\t\":method\":                     3,\n\t\t\":path\":                       5,\n\t\t\":scheme\":                     7,\n\t\t\":status\":                     14,\n\t\t\"accept-charset\":              15,\n\t\t\"accept-encoding\":             16,\n\t\t\"accept-language\":             17,\n\t\t\"accept-ranges\":               18,\n\t\t\"accept\":                      19,\n\t\t\"access-control-allow-origin\": 20,\n\t\t\"age\":                         21,\n\t\t\"allow\":                       22,\n\t\t\"authorization\":               23,\n\t\t\"cache-control\":               24,\n\t\t\"content-disposition\":         25,\n\t\t\"content-encoding\":            26,\n\t\t\"content-language\":            27,\n\t\t\"content-length\":              28,\n\t\t\"content-location\":            29,\n\t\t\"content-range\":               30,\n\t\t\"content-type\":                31,\n\t\t\"cookie\":                      32,\n\t\t\"date\":                        33,\n\t\t\"etag\":                        34,\n\t\t\"expect\":                      35,\n\t\t\"expires\":                     36,\n\t\t\"from\":                        37,\n\t\t\"host\":                        38,\n\t\t\"if-match\":                    39,\n\t\t\"if-modified-since\":           40,\n\t\t\"if-none-match\":               41,\n\t\t\"if-range\":                    42,\n\t\t\"if-unmodified-since\":         43,\n\t\t\"last-modified\":               44,\n\t\t\"link\":                        45,\n\t\t\"location\":                    46,\n\t\t\"max-forwards\":                47,\n\t\t\"proxy-authenticate\":          48,\n\t\t\"proxy-authorization\":         49,\n\t\t\"range\":                       50,\n\t\t\"referer\":                     51,\n\t\t\"refresh\":                     52,\n\t\t\"retry-after\":                 53,\n\t\t\"server\":                      54,\n\t\t\"set-cookie\":                  55,\n\t\t\"strict-transport-security\":   56,\n\t\t\"transfer-encoding\":           57,\n\t\t\"user-agent\":                  58,\n\t\t\"vary\":                        59,\n\t\t\"via\":                         60,\n\t\t\"www-authenticate\":            61,\n\t},\n\tbyNameValue: map[pairNameValue]uint64{\n\t\t{name: \":authority\", value: \"\"}:                   1,\n\t\t{name: \":method\", value: \"GET\"}:                   2,\n\t\t{name: \":method\", value: \"POST\"}:                  3,\n\t\t{name: \":path\", value: \"/\"}:                       4,\n\t\t{name: \":path\", value: \"/index.html\"}:             5,\n\t\t{name: \":scheme\", value: \"http\"}:                  6,\n\t\t{name: \":scheme\", value: \"https\"}:                 7,\n\t\t{name: \":status\", value: \"200\"}:                   8,\n\t\t{name: \":status\", value: \"204\"}:                   9,\n\t\t{name: \":status\", value: \"206\"}:                   10,\n\t\t{name: \":status\", value: \"304\"}:                   11,\n\t\t{name: \":status\", value: \"400\"}:                   12,\n\t\t{name: \":status\", value: \"404\"}:                   13,\n\t\t{name: \":status\", value: \"500\"}:                   14,\n\t\t{name: \"accept-charset\", value: \"\"}:               15,\n\t\t{name: \"accept-encoding\", value: \"gzip, deflate\"}: 16,\n\t\t{name: \"accept-language\", value: \"\"}:              17,\n\t\t{name: \"accept-ranges\", value: \"\"}:                18,\n\t\t{name: \"accept\", value: \"\"}:                       19,\n\t\t{name: \"access-control-allow-origin\", value: \"\"}:  20,\n\t\t{name: \"age\", value: \"\"}:                          21,\n\t\t{name: \"allow\", value: \"\"}:                        22,\n\t\t{name: \"authorization\", value: \"\"}:                23,\n\t\t{name: \"cache-control\", value: \"\"}:                24,\n\t\t{name: \"content-disposition\", value: \"\"}:          25,\n\t\t{name: \"content-encoding\", value: \"\"}:             26,\n\t\t{name: \"content-language\", value: \"\"}:             27,\n\t\t{name: \"content-length\", value: \"\"}:               28,\n\t\t{name: \"content-location\", value: \"\"}:             29,\n\t\t{name: \"content-range\", value: \"\"}:                30,\n\t\t{name: \"content-type\", value: \"\"}:                 31,\n\t\t{name: \"cookie\", value: \"\"}:                       32,\n\t\t{name: \"date\", value: \"\"}:                         33,\n\t\t{name: \"etag\", value: \"\"}:                         34,\n\t\t{name: \"expect\", value: \"\"}:                       35,\n\t\t{name: \"expires\", value: \"\"}:                      36,\n\t\t{name: \"from\", value: \"\"}:                         37,\n\t\t{name: \"host\", value: \"\"}:                         38,\n\t\t{name: \"if-match\", value: \"\"}:                     39,\n\t\t{name: \"if-modified-since\", value: \"\"}:            40,\n\t\t{name: \"if-none-match\", value: \"\"}:                41,\n\t\t{name: \"if-range\", value: \"\"}:                     42,\n\t\t{name: \"if-unmodified-since\", value: \"\"}:          43,\n\t\t{name: \"last-modified\", value: \"\"}:                44,\n\t\t{name: \"link\", value: \"\"}:                         45,\n\t\t{name: \"location\", value: \"\"}:                     46,\n\t\t{name: \"max-forwards\", value: \"\"}:                 47,\n\t\t{name: \"proxy-authenticate\", value: \"\"}:           48,\n\t\t{name: \"proxy-authorization\", value: \"\"}:          49,\n\t\t{name: \"range\", value: \"\"}:                        50,\n\t\t{name: \"referer\", value: \"\"}:                      51,\n\t\t{name: \"refresh\", value: \"\"}:                      52,\n\t\t{name: \"retry-after\", value: \"\"}:                  53,\n\t\t{name: \"server\", value: \"\"}:                       54,\n\t\t{name: \"set-cookie\", value: \"\"}:                   55,\n\t\t{name: \"strict-transport-security\", value: \"\"}:    56,\n\t\t{name: \"transfer-encoding\", value: \"\"}:            57,\n\t\t{name: \"user-agent\", value: \"\"}:                   58,\n\t\t{name: \"vary\", value: \"\"}:                         59,\n\t\t{name: \"via\", value: \"\"}:                          60,\n\t\t{name: \"www-authenticate\", value: \"\"}:             61,\n\t},\n\tents: []HeaderField{\n\t\t{Name: \":authority\", Value: \"\", Sensitive: false},\n\t\t{Name: \":method\", Value: \"GET\", Sensitive: false},\n\t\t{Name: \":method\", Value: \"POST\", Sensitive: false},\n\t\t{Name: \":path\", Value: \"/\", Sensitive: false},\n\t\t{Name: \":path\", Value: \"/index.html\", Sensitive: false},\n\t\t{Name: \":scheme\", Value: \"http\", Sensitive: false},\n\t\t{Name: \":scheme\", Value: \"https\", Sensitive: false},\n\t\t{Name: \":status\", Value: \"200\", Sensitive: false},\n\t\t{Name: \":status\", Value: \"204\", Sensitive: false},\n\t\t{Name: \":status\", Value: \"206\", Sensitive: false},\n\t\t{Name: \":status\", Value: \"304\", Sensitive: false},\n\t\t{Name: \":status\", Value: \"400\", Sensitive: false},\n\t\t{Name: \":status\", Value: \"404\", Sensitive: false},\n\t\t{Name: \":status\", Value: \"500\", Sensitive: false},\n\t\t{Name: \"accept-charset\", Value: \"\", Sensitive: false},\n\t\t{Name: \"accept-encoding\", Value: \"gzip, deflate\", Sensitive: false},\n\t\t{Name: \"accept-language\", Value: \"\", Sensitive: false},\n\t\t{Name: \"accept-ranges\", Value: \"\", Sensitive: false},\n\t\t{Name: \"accept\", Value: \"\", Sensitive: false},\n\t\t{Name: \"access-control-allow-origin\", Value: \"\", Sensitive: false},\n\t\t{Name: \"age\", Value: \"\", Sensitive: false},\n\t\t{Name: \"allow\", Value: \"\", Sensitive: false},\n\t\t{Name: \"authorization\", Value: \"\", Sensitive: false},\n\t\t{Name: \"cache-control\", Value: \"\", Sensitive: false},\n\t\t{Name: \"content-disposition\", Value: \"\", Sensitive: false},\n\t\t{Name: \"content-encoding\", Value: \"\", Sensitive: false},\n\t\t{Name: \"content-language\", Value: \"\", Sensitive: false},\n\t\t{Name: \"content-length\", Value: \"\", Sensitive: false},\n\t\t{Name: \"content-location\", Value: \"\", Sensitive: false},\n\t\t{Name: \"content-range\", Value: \"\", Sensitive: false},\n\t\t{Name: \"content-type\", Value: \"\", Sensitive: false},\n\t\t{Name: \"cookie\", Value: \"\", Sensitive: false},\n\t\t{Name: \"date\", Value: \"\", Sensitive: false},\n\t\t{Name: \"etag\", Value: \"\", Sensitive: false},\n\t\t{Name: \"expect\", Value: \"\", Sensitive: false},\n\t\t{Name: \"expires\", Value: \"\", Sensitive: false},\n\t\t{Name: \"from\", Value: \"\", Sensitive: false},\n\t\t{Name: \"host\", Value: \"\", Sensitive: false},\n\t\t{Name: \"if-match\", Value: \"\", Sensitive: false},\n\t\t{Name: \"if-modified-since\", Value: \"\", Sensitive: false},\n\t\t{Name: \"if-none-match\", Value: \"\", Sensitive: false},\n\t\t{Name: \"if-range\", Value: \"\", Sensitive: false},\n\t\t{Name: \"if-unmodified-since\", Value: \"\", Sensitive: false},\n\t\t{Name: \"last-modified\", Value: \"\", Sensitive: false},\n\t\t{Name: \"link\", Value: \"\", Sensitive: false},\n\t\t{Name: \"location\", Value: \"\", Sensitive: false},\n\t\t{Name: \"max-forwards\", Value: \"\", Sensitive: false},\n\t\t{Name: \"proxy-authenticate\", Value: \"\", Sensitive: false},\n\t\t{Name: \"proxy-authorization\", Value: \"\", Sensitive: false},\n\t\t{Name: \"range\", Value: \"\", Sensitive: false},\n\t\t{Name: \"referer\", Value: \"\", Sensitive: false},\n\t\t{Name: \"refresh\", Value: \"\", Sensitive: false},\n\t\t{Name: \"retry-after\", Value: \"\", Sensitive: false},\n\t\t{Name: \"server\", Value: \"\", Sensitive: false},\n\t\t{Name: \"set-cookie\", Value: \"\", Sensitive: false},\n\t\t{Name: \"strict-transport-security\", Value: \"\", Sensitive: false},\n\t\t{Name: \"transfer-encoding\", Value: \"\", Sensitive: false},\n\t\t{Name: \"user-agent\", Value: \"\", Sensitive: false},\n\t\t{Name: \"vary\", Value: \"\", Sensitive: false},\n\t\t{Name: \"via\", Value: \"\", Sensitive: false},\n\t\t{Name: \"www-authenticate\", Value: \"\", Sensitive: false},\n\t},\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/hpack/tables.go",
    "content": "// Copyright 2014 The Go 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 hpack\n\nimport (\n\t\"fmt\"\n)\n\n// headerFieldTable implements a list of HeaderFields.\n// This is used to implement the static and dynamic tables.\ntype headerFieldTable struct {\n\t// For static tables, entries are never evicted.\n\t//\n\t// For dynamic tables, entries are evicted from ents[0] and added to the end.\n\t// Each entry has a unique id that starts at one and increments for each\n\t// entry that is added. This unique id is stable across evictions, meaning\n\t// it can be used as a pointer to a specific entry. As in hpack, unique ids\n\t// are 1-based. The unique id for ents[k] is k + evictCount + 1.\n\t//\n\t// Zero is not a valid unique id.\n\t//\n\t// evictCount should not overflow in any remotely practical situation. In\n\t// practice, we will have one dynamic table per HTTP/2 connection. If we\n\t// assume a very powerful server that handles 1M QPS per connection and each\n\t// request adds (then evicts) 100 entries from the table, it would still take\n\t// 2M years for evictCount to overflow.\n\tents       []HeaderField\n\tevictCount uint64\n\n\t// byName maps a HeaderField name to the unique id of the newest entry with\n\t// the same name. See above for a definition of \"unique id\".\n\tbyName map[string]uint64\n\n\t// byNameValue maps a HeaderField name/value pair to the unique id of the newest\n\t// entry with the same name and value. See above for a definition of \"unique id\".\n\tbyNameValue map[pairNameValue]uint64\n}\n\ntype pairNameValue struct {\n\tname, value string\n}\n\nfunc (t *headerFieldTable) init() {\n\tt.byName = make(map[string]uint64)\n\tt.byNameValue = make(map[pairNameValue]uint64)\n}\n\n// len reports the number of entries in the table.\nfunc (t *headerFieldTable) len() int {\n\treturn len(t.ents)\n}\n\n// addEntry adds a new entry.\nfunc (t *headerFieldTable) addEntry(f HeaderField) {\n\tid := uint64(t.len()) + t.evictCount + 1\n\tt.byName[f.Name] = id\n\tt.byNameValue[pairNameValue{f.Name, f.Value}] = id\n\tt.ents = append(t.ents, f)\n}\n\n// evictOldest evicts the n oldest entries in the table.\nfunc (t *headerFieldTable) evictOldest(n int) {\n\tif n > t.len() {\n\t\tpanic(fmt.Sprintf(\"evictOldest(%v) on table with %v entries\", n, t.len()))\n\t}\n\tfor k := 0; k < n; k++ {\n\t\tf := t.ents[k]\n\t\tid := t.evictCount + uint64(k) + 1\n\t\tif t.byName[f.Name] == id {\n\t\t\tdelete(t.byName, f.Name)\n\t\t}\n\t\tif p := (pairNameValue{f.Name, f.Value}); t.byNameValue[p] == id {\n\t\t\tdelete(t.byNameValue, p)\n\t\t}\n\t}\n\tcopy(t.ents, t.ents[n:])\n\tfor k := t.len() - n; k < t.len(); k++ {\n\t\tt.ents[k] = HeaderField{} // so strings can be garbage collected\n\t}\n\tt.ents = t.ents[:t.len()-n]\n\tif t.evictCount+uint64(n) < t.evictCount {\n\t\tpanic(\"evictCount overflow\")\n\t}\n\tt.evictCount += uint64(n)\n}\n\n// search finds f in the table. If there is no match, i is 0.\n// If both name and value match, i is the matched index and nameValueMatch\n// becomes true. If only name matches, i points to that index and\n// nameValueMatch becomes false.\n//\n// The returned index is a 1-based HPACK index. For dynamic tables, HPACK says\n// that index 1 should be the newest entry, but t.ents[0] is the oldest entry,\n// meaning t.ents is reversed for dynamic tables. Hence, when t is a dynamic\n// table, the return value i actually refers to the entry t.ents[t.len()-i].\n//\n// All tables are assumed to be a dynamic tables except for the global staticTable.\n//\n// See Section 2.3.3.\nfunc (t *headerFieldTable) search(f HeaderField) (i uint64, nameValueMatch bool) {\n\tif !f.Sensitive {\n\t\tif id := t.byNameValue[pairNameValue{f.Name, f.Value}]; id != 0 {\n\t\t\treturn t.idToIndex(id), true\n\t\t}\n\t}\n\tif id := t.byName[f.Name]; id != 0 {\n\t\treturn t.idToIndex(id), false\n\t}\n\treturn 0, false\n}\n\n// idToIndex converts a unique id to an HPACK index.\n// See Section 2.3.3.\nfunc (t *headerFieldTable) idToIndex(id uint64) uint64 {\n\tif id <= t.evictCount {\n\t\tpanic(fmt.Sprintf(\"id (%v) <= evictCount (%v)\", id, t.evictCount))\n\t}\n\tk := id - t.evictCount - 1 // convert id to an index t.ents[k]\n\tif t != staticTable {\n\t\treturn uint64(t.len()) - k // dynamic table\n\t}\n\treturn k + 1\n}\n\nvar huffmanCodes = [256]uint32{\n\t0x1ff8,\n\t0x7fffd8,\n\t0xfffffe2,\n\t0xfffffe3,\n\t0xfffffe4,\n\t0xfffffe5,\n\t0xfffffe6,\n\t0xfffffe7,\n\t0xfffffe8,\n\t0xffffea,\n\t0x3ffffffc,\n\t0xfffffe9,\n\t0xfffffea,\n\t0x3ffffffd,\n\t0xfffffeb,\n\t0xfffffec,\n\t0xfffffed,\n\t0xfffffee,\n\t0xfffffef,\n\t0xffffff0,\n\t0xffffff1,\n\t0xffffff2,\n\t0x3ffffffe,\n\t0xffffff3,\n\t0xffffff4,\n\t0xffffff5,\n\t0xffffff6,\n\t0xffffff7,\n\t0xffffff8,\n\t0xffffff9,\n\t0xffffffa,\n\t0xffffffb,\n\t0x14,\n\t0x3f8,\n\t0x3f9,\n\t0xffa,\n\t0x1ff9,\n\t0x15,\n\t0xf8,\n\t0x7fa,\n\t0x3fa,\n\t0x3fb,\n\t0xf9,\n\t0x7fb,\n\t0xfa,\n\t0x16,\n\t0x17,\n\t0x18,\n\t0x0,\n\t0x1,\n\t0x2,\n\t0x19,\n\t0x1a,\n\t0x1b,\n\t0x1c,\n\t0x1d,\n\t0x1e,\n\t0x1f,\n\t0x5c,\n\t0xfb,\n\t0x7ffc,\n\t0x20,\n\t0xffb,\n\t0x3fc,\n\t0x1ffa,\n\t0x21,\n\t0x5d,\n\t0x5e,\n\t0x5f,\n\t0x60,\n\t0x61,\n\t0x62,\n\t0x63,\n\t0x64,\n\t0x65,\n\t0x66,\n\t0x67,\n\t0x68,\n\t0x69,\n\t0x6a,\n\t0x6b,\n\t0x6c,\n\t0x6d,\n\t0x6e,\n\t0x6f,\n\t0x70,\n\t0x71,\n\t0x72,\n\t0xfc,\n\t0x73,\n\t0xfd,\n\t0x1ffb,\n\t0x7fff0,\n\t0x1ffc,\n\t0x3ffc,\n\t0x22,\n\t0x7ffd,\n\t0x3,\n\t0x23,\n\t0x4,\n\t0x24,\n\t0x5,\n\t0x25,\n\t0x26,\n\t0x27,\n\t0x6,\n\t0x74,\n\t0x75,\n\t0x28,\n\t0x29,\n\t0x2a,\n\t0x7,\n\t0x2b,\n\t0x76,\n\t0x2c,\n\t0x8,\n\t0x9,\n\t0x2d,\n\t0x77,\n\t0x78,\n\t0x79,\n\t0x7a,\n\t0x7b,\n\t0x7ffe,\n\t0x7fc,\n\t0x3ffd,\n\t0x1ffd,\n\t0xffffffc,\n\t0xfffe6,\n\t0x3fffd2,\n\t0xfffe7,\n\t0xfffe8,\n\t0x3fffd3,\n\t0x3fffd4,\n\t0x3fffd5,\n\t0x7fffd9,\n\t0x3fffd6,\n\t0x7fffda,\n\t0x7fffdb,\n\t0x7fffdc,\n\t0x7fffdd,\n\t0x7fffde,\n\t0xffffeb,\n\t0x7fffdf,\n\t0xffffec,\n\t0xffffed,\n\t0x3fffd7,\n\t0x7fffe0,\n\t0xffffee,\n\t0x7fffe1,\n\t0x7fffe2,\n\t0x7fffe3,\n\t0x7fffe4,\n\t0x1fffdc,\n\t0x3fffd8,\n\t0x7fffe5,\n\t0x3fffd9,\n\t0x7fffe6,\n\t0x7fffe7,\n\t0xffffef,\n\t0x3fffda,\n\t0x1fffdd,\n\t0xfffe9,\n\t0x3fffdb,\n\t0x3fffdc,\n\t0x7fffe8,\n\t0x7fffe9,\n\t0x1fffde,\n\t0x7fffea,\n\t0x3fffdd,\n\t0x3fffde,\n\t0xfffff0,\n\t0x1fffdf,\n\t0x3fffdf,\n\t0x7fffeb,\n\t0x7fffec,\n\t0x1fffe0,\n\t0x1fffe1,\n\t0x3fffe0,\n\t0x1fffe2,\n\t0x7fffed,\n\t0x3fffe1,\n\t0x7fffee,\n\t0x7fffef,\n\t0xfffea,\n\t0x3fffe2,\n\t0x3fffe3,\n\t0x3fffe4,\n\t0x7ffff0,\n\t0x3fffe5,\n\t0x3fffe6,\n\t0x7ffff1,\n\t0x3ffffe0,\n\t0x3ffffe1,\n\t0xfffeb,\n\t0x7fff1,\n\t0x3fffe7,\n\t0x7ffff2,\n\t0x3fffe8,\n\t0x1ffffec,\n\t0x3ffffe2,\n\t0x3ffffe3,\n\t0x3ffffe4,\n\t0x7ffffde,\n\t0x7ffffdf,\n\t0x3ffffe5,\n\t0xfffff1,\n\t0x1ffffed,\n\t0x7fff2,\n\t0x1fffe3,\n\t0x3ffffe6,\n\t0x7ffffe0,\n\t0x7ffffe1,\n\t0x3ffffe7,\n\t0x7ffffe2,\n\t0xfffff2,\n\t0x1fffe4,\n\t0x1fffe5,\n\t0x3ffffe8,\n\t0x3ffffe9,\n\t0xffffffd,\n\t0x7ffffe3,\n\t0x7ffffe4,\n\t0x7ffffe5,\n\t0xfffec,\n\t0xfffff3,\n\t0xfffed,\n\t0x1fffe6,\n\t0x3fffe9,\n\t0x1fffe7,\n\t0x1fffe8,\n\t0x7ffff3,\n\t0x3fffea,\n\t0x3fffeb,\n\t0x1ffffee,\n\t0x1ffffef,\n\t0xfffff4,\n\t0xfffff5,\n\t0x3ffffea,\n\t0x7ffff4,\n\t0x3ffffeb,\n\t0x7ffffe6,\n\t0x3ffffec,\n\t0x3ffffed,\n\t0x7ffffe7,\n\t0x7ffffe8,\n\t0x7ffffe9,\n\t0x7ffffea,\n\t0x7ffffeb,\n\t0xffffffe,\n\t0x7ffffec,\n\t0x7ffffed,\n\t0x7ffffee,\n\t0x7ffffef,\n\t0x7fffff0,\n\t0x3ffffee,\n}\n\nvar huffmanCodeLen = [256]uint8{\n\t13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28,\n\t28, 28, 28, 28, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n\t6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6,\n\t5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 8, 15, 6, 12, 10,\n\t13, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n\t7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 13, 19, 13, 14, 6,\n\t15, 5, 6, 5, 6, 5, 6, 6, 6, 5, 7, 7, 6, 6, 6, 5,\n\t6, 7, 6, 5, 5, 6, 7, 7, 7, 7, 7, 15, 11, 14, 13, 28,\n\t20, 22, 20, 20, 22, 22, 22, 23, 22, 23, 23, 23, 23, 23, 24, 23,\n\t24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23, 24,\n\t22, 21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23,\n\t21, 21, 22, 21, 23, 22, 23, 23, 20, 22, 22, 22, 23, 22, 22, 23,\n\t26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27, 26, 24, 25,\n\t19, 21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27,\n\t20, 24, 20, 21, 22, 21, 21, 23, 22, 22, 25, 25, 24, 24, 26, 23,\n\t26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 26,\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/http2.go",
    "content": "// Copyright 2014 The Go 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\n// Package http2 implements the HTTP/2 protocol.\n//\n// This package is low-level and intended to be used directly by very\n// few people. Most users will use it indirectly through the automatic\n// use by the net/http package (from Go 1.6 and later).\n// For use in earlier Go versions see ConfigureServer. (Transport support\n// requires Go 1.6 or later)\n//\n// See https://http2.github.io/ for more information on HTTP/2.\n//\n// See https://http2.golang.org/ for a test server running this code.\npackage http2 // import \"golang.org/x/net/http2\"\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"golang.org/x/net/http/httpguts\"\n)\n\nvar (\n\tVerboseLogs    bool\n\tlogFrameWrites bool\n\tlogFrameReads  bool\n\tinTests        bool\n\n\t// Enabling extended CONNECT by causes browsers to attempt to use\n\t// WebSockets-over-HTTP/2. This results in problems when the server's websocket\n\t// package doesn't support extended CONNECT.\n\t//\n\t// Disable extended CONNECT by default for now.\n\t//\n\t// Issue #71128.\n\tdisableExtendedConnectProtocol = true\n)\n\nfunc init() {\n\te := os.Getenv(\"GODEBUG\")\n\tif strings.Contains(e, \"http2debug=1\") {\n\t\tVerboseLogs = true\n\t}\n\tif strings.Contains(e, \"http2debug=2\") {\n\t\tVerboseLogs = true\n\t\tlogFrameWrites = true\n\t\tlogFrameReads = true\n\t}\n\tif strings.Contains(e, \"http2xconnect=1\") {\n\t\tdisableExtendedConnectProtocol = false\n\t}\n}\n\nconst (\n\t// ClientPreface is the string that must be sent by new\n\t// connections from clients.\n\tClientPreface = \"PRI * HTTP/2.0\\r\\n\\r\\nSM\\r\\n\\r\\n\"\n\n\t// SETTINGS_MAX_FRAME_SIZE default\n\t// https://httpwg.org/specs/rfc7540.html#rfc.section.6.5.2\n\tinitialMaxFrameSize = 16384\n\n\t// NextProtoTLS is the NPN/ALPN protocol negotiated during\n\t// HTTP/2's TLS setup.\n\tNextProtoTLS = \"h2\"\n\n\t// https://httpwg.org/specs/rfc7540.html#SettingValues\n\tinitialHeaderTableSize = 4096\n\n\tinitialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size\n\n\tdefaultMaxReadFrameSize = 1 << 20\n)\n\nvar (\n\tclientPreface = []byte(ClientPreface)\n)\n\ntype streamState int\n\n// HTTP/2 stream states.\n//\n// See http://tools.ietf.org/html/rfc7540#section-5.1.\n//\n// For simplicity, the server code merges \"reserved (local)\" into\n// \"half-closed (remote)\". This is one less state transition to track.\n// The only downside is that we send PUSH_PROMISEs slightly less\n// liberally than allowable. More discussion here:\n// https://lists.w3.org/Archives/Public/ietf-http-wg/2016JulSep/0599.html\n//\n// \"reserved (remote)\" is omitted since the client code does not\n// support server push.\nconst (\n\tstateIdle streamState = iota\n\tstateOpen\n\tstateHalfClosedLocal\n\tstateHalfClosedRemote\n\tstateClosed\n)\n\nvar stateName = [...]string{\n\tstateIdle:             \"Idle\",\n\tstateOpen:             \"Open\",\n\tstateHalfClosedLocal:  \"HalfClosedLocal\",\n\tstateHalfClosedRemote: \"HalfClosedRemote\",\n\tstateClosed:           \"Closed\",\n}\n\nfunc (st streamState) String() string {\n\treturn stateName[st]\n}\n\n// Setting is a setting parameter: which setting it is, and its value.\ntype Setting struct {\n\t// ID is which setting is being set.\n\t// See https://httpwg.org/specs/rfc7540.html#SettingFormat\n\tID SettingID\n\n\t// Val is the value.\n\tVal uint32\n}\n\nfunc (s Setting) String() string {\n\treturn fmt.Sprintf(\"[%v = %d]\", s.ID, s.Val)\n}\n\n// Valid reports whether the setting is valid.\nfunc (s Setting) Valid() error {\n\t// Limits and error codes from 6.5.2 Defined SETTINGS Parameters\n\tswitch s.ID {\n\tcase SettingEnablePush:\n\t\tif s.Val != 1 && s.Val != 0 {\n\t\t\treturn ConnectionError(ErrCodeProtocol)\n\t\t}\n\tcase SettingInitialWindowSize:\n\t\tif s.Val > 1<<31-1 {\n\t\t\treturn ConnectionError(ErrCodeFlowControl)\n\t\t}\n\tcase SettingMaxFrameSize:\n\t\tif s.Val < 16384 || s.Val > 1<<24-1 {\n\t\t\treturn ConnectionError(ErrCodeProtocol)\n\t\t}\n\tcase SettingEnableConnectProtocol:\n\t\tif s.Val != 1 && s.Val != 0 {\n\t\t\treturn ConnectionError(ErrCodeProtocol)\n\t\t}\n\t}\n\treturn nil\n}\n\n// A SettingID is an HTTP/2 setting as defined in\n// https://httpwg.org/specs/rfc7540.html#iana-settings\ntype SettingID uint16\n\nconst (\n\tSettingHeaderTableSize       SettingID = 0x1\n\tSettingEnablePush            SettingID = 0x2\n\tSettingMaxConcurrentStreams  SettingID = 0x3\n\tSettingInitialWindowSize     SettingID = 0x4\n\tSettingMaxFrameSize          SettingID = 0x5\n\tSettingMaxHeaderListSize     SettingID = 0x6\n\tSettingEnableConnectProtocol SettingID = 0x8\n)\n\nvar settingName = map[SettingID]string{\n\tSettingHeaderTableSize:       \"HEADER_TABLE_SIZE\",\n\tSettingEnablePush:            \"ENABLE_PUSH\",\n\tSettingMaxConcurrentStreams:  \"MAX_CONCURRENT_STREAMS\",\n\tSettingInitialWindowSize:     \"INITIAL_WINDOW_SIZE\",\n\tSettingMaxFrameSize:          \"MAX_FRAME_SIZE\",\n\tSettingMaxHeaderListSize:     \"MAX_HEADER_LIST_SIZE\",\n\tSettingEnableConnectProtocol: \"ENABLE_CONNECT_PROTOCOL\",\n}\n\nfunc (s SettingID) String() string {\n\tif v, ok := settingName[s]; ok {\n\t\treturn v\n\t}\n\treturn fmt.Sprintf(\"UNKNOWN_SETTING_%d\", uint16(s))\n}\n\n// validWireHeaderFieldName reports whether v is a valid header field\n// name (key). See httpguts.ValidHeaderName for the base rules.\n//\n// Further, http2 says:\n//\n//\t\"Just as in HTTP/1.x, header field names are strings of ASCII\n//\tcharacters that are compared in a case-insensitive\n//\tfashion. However, header field names MUST be converted to\n//\tlowercase prior to their encoding in HTTP/2. \"\nfunc validWireHeaderFieldName(v string) bool {\n\tif len(v) == 0 {\n\t\treturn false\n\t}\n\tfor _, r := range v {\n\t\tif !httpguts.IsTokenRune(r) {\n\t\t\treturn false\n\t\t}\n\t\tif 'A' <= r && r <= 'Z' {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc httpCodeString(code int) string {\n\tswitch code {\n\tcase 200:\n\t\treturn \"200\"\n\tcase 404:\n\t\treturn \"404\"\n\t}\n\treturn strconv.Itoa(code)\n}\n\n// from pkg io\ntype stringWriter interface {\n\tWriteString(s string) (n int, err error)\n}\n\n// A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed).\ntype closeWaiter chan struct{}\n\n// Init makes a closeWaiter usable.\n// It exists because so a closeWaiter value can be placed inside a\n// larger struct and have the Mutex and Cond's memory in the same\n// allocation.\nfunc (cw *closeWaiter) Init() {\n\t*cw = make(chan struct{})\n}\n\n// Close marks the closeWaiter as closed and unblocks any waiters.\nfunc (cw closeWaiter) Close() {\n\tclose(cw)\n}\n\n// Wait waits for the closeWaiter to become closed.\nfunc (cw closeWaiter) Wait() {\n\t<-cw\n}\n\n// bufferedWriter is a buffered writer that writes to w.\n// Its buffered writer is lazily allocated as needed, to minimize\n// idle memory usage with many connections.\ntype bufferedWriter struct {\n\t_           incomparable\n\tgroup       synctestGroupInterface // immutable\n\tconn        net.Conn               // immutable\n\tbw          *bufio.Writer          // non-nil when data is buffered\n\tbyteTimeout time.Duration          // immutable, WriteByteTimeout\n}\n\nfunc newBufferedWriter(group synctestGroupInterface, conn net.Conn, timeout time.Duration) *bufferedWriter {\n\treturn &bufferedWriter{\n\t\tgroup:       group,\n\t\tconn:        conn,\n\t\tbyteTimeout: timeout,\n\t}\n}\n\n// bufWriterPoolBufferSize is the size of bufio.Writer's\n// buffers created using bufWriterPool.\n//\n// TODO: pick a less arbitrary value? this is a bit under\n// (3 x typical 1500 byte MTU) at least. Other than that,\n// not much thought went into it.\nconst bufWriterPoolBufferSize = 4 << 10\n\nvar bufWriterPool = sync.Pool{\n\tNew: func() interface{} {\n\t\treturn bufio.NewWriterSize(nil, bufWriterPoolBufferSize)\n\t},\n}\n\nfunc (w *bufferedWriter) Available() int {\n\tif w.bw == nil {\n\t\treturn bufWriterPoolBufferSize\n\t}\n\treturn w.bw.Available()\n}\n\nfunc (w *bufferedWriter) Write(p []byte) (n int, err error) {\n\tif w.bw == nil {\n\t\tbw := bufWriterPool.Get().(*bufio.Writer)\n\t\tbw.Reset((*bufferedWriterTimeoutWriter)(w))\n\t\tw.bw = bw\n\t}\n\treturn w.bw.Write(p)\n}\n\nfunc (w *bufferedWriter) Flush() error {\n\tbw := w.bw\n\tif bw == nil {\n\t\treturn nil\n\t}\n\terr := bw.Flush()\n\tbw.Reset(nil)\n\tbufWriterPool.Put(bw)\n\tw.bw = nil\n\treturn err\n}\n\ntype bufferedWriterTimeoutWriter bufferedWriter\n\nfunc (w *bufferedWriterTimeoutWriter) Write(p []byte) (n int, err error) {\n\treturn writeWithByteTimeout(w.group, w.conn, w.byteTimeout, p)\n}\n\n// writeWithByteTimeout writes to conn.\n// If more than timeout passes without any bytes being written to the connection,\n// the write fails.\nfunc writeWithByteTimeout(group synctestGroupInterface, conn net.Conn, timeout time.Duration, p []byte) (n int, err error) {\n\tif timeout <= 0 {\n\t\treturn conn.Write(p)\n\t}\n\tfor {\n\t\tvar now time.Time\n\t\tif group == nil {\n\t\t\tnow = time.Now()\n\t\t} else {\n\t\t\tnow = group.Now()\n\t\t}\n\t\tconn.SetWriteDeadline(now.Add(timeout))\n\t\tnn, err := conn.Write(p[n:])\n\t\tn += nn\n\t\tif n == len(p) || nn == 0 || !errors.Is(err, os.ErrDeadlineExceeded) {\n\t\t\t// Either we finished the write, made no progress, or hit the deadline.\n\t\t\t// Whichever it is, we're done now.\n\t\t\tconn.SetWriteDeadline(time.Time{})\n\t\t\treturn n, err\n\t\t}\n\t}\n}\n\nfunc mustUint31(v int32) uint32 {\n\tif v < 0 || v > 2147483647 {\n\t\tpanic(\"out of range\")\n\t}\n\treturn uint32(v)\n}\n\n// bodyAllowedForStatus reports whether a given response status code\n// permits a body. See RFC 7230, section 3.3.\nfunc bodyAllowedForStatus(status int) bool {\n\tswitch {\n\tcase status >= 100 && status <= 199:\n\t\treturn false\n\tcase status == 204:\n\t\treturn false\n\tcase status == 304:\n\t\treturn false\n\t}\n\treturn true\n}\n\ntype httpError struct {\n\t_       incomparable\n\tmsg     string\n\ttimeout bool\n}\n\nfunc (e *httpError) Error() string   { return e.msg }\nfunc (e *httpError) Timeout() bool   { return e.timeout }\nfunc (e *httpError) Temporary() bool { return true }\n\nvar errTimeout error = &httpError{msg: \"http2: timeout awaiting response headers\", timeout: true}\n\ntype connectionStater interface {\n\tConnectionState() tls.ConnectionState\n}\n\nvar sorterPool = sync.Pool{New: func() interface{} { return new(sorter) }}\n\ntype sorter struct {\n\tv []string // owned by sorter\n}\n\nfunc (s *sorter) Len() int           { return len(s.v) }\nfunc (s *sorter) Swap(i, j int)      { s.v[i], s.v[j] = s.v[j], s.v[i] }\nfunc (s *sorter) Less(i, j int) bool { return s.v[i] < s.v[j] }\n\n// Keys returns the sorted keys of h.\n//\n// The returned slice is only valid until s used again or returned to\n// its pool.\nfunc (s *sorter) Keys(h http.Header) []string {\n\tkeys := s.v[:0]\n\tfor k := range h {\n\t\tkeys = append(keys, k)\n\t}\n\ts.v = keys\n\tsort.Sort(s)\n\treturn keys\n}\n\nfunc (s *sorter) SortStrings(ss []string) {\n\t// Our sorter works on s.v, which sorter owns, so\n\t// stash it away while we sort the user's buffer.\n\tsave := s.v\n\ts.v = ss\n\tsort.Sort(s)\n\ts.v = save\n}\n\n// incomparable is a zero-width, non-comparable type. Adding it to a struct\n// makes that struct also non-comparable, and generally doesn't add\n// any size (as long as it's first).\ntype incomparable [0]func()\n\n// synctestGroupInterface is the methods of synctestGroup used by Server and Transport.\n// It's defined as an interface here to let us keep synctestGroup entirely test-only\n// and not a part of non-test builds.\ntype synctestGroupInterface interface {\n\tJoin()\n\tNow() time.Time\n\tNewTimer(d time.Duration) timer\n\tAfterFunc(d time.Duration, f func()) timer\n\tContextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/pipe.go",
    "content": "// Copyright 2014 The Go 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 http2\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"sync\"\n)\n\n// pipe is a goroutine-safe io.Reader/io.Writer pair. It's like\n// io.Pipe except there are no PipeReader/PipeWriter halves, and the\n// underlying buffer is an interface. (io.Pipe is always unbuffered)\ntype pipe struct {\n\tmu       sync.Mutex\n\tc        sync.Cond     // c.L lazily initialized to &p.mu\n\tb        pipeBuffer    // nil when done reading\n\tunread   int           // bytes unread when done\n\terr      error         // read error once empty. non-nil means closed.\n\tbreakErr error         // immediate read error (caller doesn't see rest of b)\n\tdonec    chan struct{} // closed on error\n\treadFn   func()        // optional code to run in Read before error\n}\n\ntype pipeBuffer interface {\n\tLen() int\n\tio.Writer\n\tio.Reader\n}\n\n// setBuffer initializes the pipe buffer.\n// It has no effect if the pipe is already closed.\nfunc (p *pipe) setBuffer(b pipeBuffer) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tif p.err != nil || p.breakErr != nil {\n\t\treturn\n\t}\n\tp.b = b\n}\n\nfunc (p *pipe) Len() int {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tif p.b == nil {\n\t\treturn p.unread\n\t}\n\treturn p.b.Len()\n}\n\n// Read waits until data is available and copies bytes\n// from the buffer into p.\nfunc (p *pipe) Read(d []byte) (n int, err error) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tif p.c.L == nil {\n\t\tp.c.L = &p.mu\n\t}\n\tfor {\n\t\tif p.breakErr != nil {\n\t\t\treturn 0, p.breakErr\n\t\t}\n\t\tif p.b != nil && p.b.Len() > 0 {\n\t\t\treturn p.b.Read(d)\n\t\t}\n\t\tif p.err != nil {\n\t\t\tif p.readFn != nil {\n\t\t\t\tp.readFn()     // e.g. copy trailers\n\t\t\t\tp.readFn = nil // not sticky like p.err\n\t\t\t}\n\t\t\tp.b = nil\n\t\t\treturn 0, p.err\n\t\t}\n\t\tp.c.Wait()\n\t}\n}\n\nvar (\n\terrClosedPipeWrite        = errors.New(\"write on closed buffer\")\n\terrUninitializedPipeWrite = errors.New(\"write on uninitialized buffer\")\n)\n\n// Write copies bytes from p into the buffer and wakes a reader.\n// It is an error to write more data than the buffer can hold.\nfunc (p *pipe) Write(d []byte) (n int, err error) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tif p.c.L == nil {\n\t\tp.c.L = &p.mu\n\t}\n\tdefer p.c.Signal()\n\tif p.err != nil || p.breakErr != nil {\n\t\treturn 0, errClosedPipeWrite\n\t}\n\t// pipe.setBuffer is never invoked, leaving the buffer uninitialized.\n\t// We shouldn't try to write to an uninitialized pipe,\n\t// but returning an error is better than panicking.\n\tif p.b == nil {\n\t\treturn 0, errUninitializedPipeWrite\n\t}\n\treturn p.b.Write(d)\n}\n\n// CloseWithError causes the next Read (waking up a current blocked\n// Read if needed) to return the provided err after all data has been\n// read.\n//\n// The error must be non-nil.\nfunc (p *pipe) CloseWithError(err error) { p.closeWithError(&p.err, err, nil) }\n\n// BreakWithError causes the next Read (waking up a current blocked\n// Read if needed) to return the provided err immediately, without\n// waiting for unread data.\nfunc (p *pipe) BreakWithError(err error) { p.closeWithError(&p.breakErr, err, nil) }\n\n// closeWithErrorAndCode is like CloseWithError but also sets some code to run\n// in the caller's goroutine before returning the error.\nfunc (p *pipe) closeWithErrorAndCode(err error, fn func()) { p.closeWithError(&p.err, err, fn) }\n\nfunc (p *pipe) closeWithError(dst *error, err error, fn func()) {\n\tif err == nil {\n\t\tpanic(\"err must be non-nil\")\n\t}\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tif p.c.L == nil {\n\t\tp.c.L = &p.mu\n\t}\n\tdefer p.c.Signal()\n\tif *dst != nil {\n\t\t// Already been done.\n\t\treturn\n\t}\n\tp.readFn = fn\n\tif dst == &p.breakErr {\n\t\tif p.b != nil {\n\t\t\tp.unread += p.b.Len()\n\t\t}\n\t\tp.b = nil\n\t}\n\t*dst = err\n\tp.closeDoneLocked()\n}\n\n// requires p.mu be held.\nfunc (p *pipe) closeDoneLocked() {\n\tif p.donec == nil {\n\t\treturn\n\t}\n\t// Close if unclosed. This isn't racy since we always\n\t// hold p.mu while closing.\n\tselect {\n\tcase <-p.donec:\n\tdefault:\n\t\tclose(p.donec)\n\t}\n}\n\n// Err returns the error (if any) first set by BreakWithError or CloseWithError.\nfunc (p *pipe) Err() error {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tif p.breakErr != nil {\n\t\treturn p.breakErr\n\t}\n\treturn p.err\n}\n\n// Done returns a channel which is closed if and when this pipe is closed\n// with CloseWithError.\nfunc (p *pipe) Done() <-chan struct{} {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tif p.donec == nil {\n\t\tp.donec = make(chan struct{})\n\t\tif p.err != nil || p.breakErr != nil {\n\t\t\t// Already hit an error.\n\t\t\tp.closeDoneLocked()\n\t\t}\n\t}\n\treturn p.donec\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/server.go",
    "content": "// Copyright 2014 The Go 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\n// TODO: turn off the serve goroutine when idle, so\n// an idle conn only has the readFrames goroutine active. (which could\n// also be optimized probably to pin less memory in crypto/tls). This\n// would involve tracking when the serve goroutine is active (atomic\n// int32 read/CAS probably?) and starting it up when frames arrive,\n// and shutting it down when all handlers exit. the occasional PING\n// packets could use time.AfterFunc to call sc.wakeStartServeLoop()\n// (which is a no-op if already running) and then queue the PING write\n// as normal. The serve loop would then exit in most cases (if no\n// Handlers running) and not be woken up again until the PING packet\n// returns.\n\n// TODO (maybe): add a mechanism for Handlers to going into\n// half-closed-local mode (rw.(io.Closer) test?) but not exit their\n// handler, and continue to be able to read from the\n// Request.Body. This would be a somewhat semantic change from HTTP/1\n// (or at least what we expose in net/http), so I'd probably want to\n// add it there too. For now, this package says that returning from\n// the Handler ServeHTTP function means you're both done reading and\n// done writing, without a way to stop just one or the other.\n\npackage http2\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/rand\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"math\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/textproto\"\n\t\"net/url\"\n\t\"os\"\n\t\"reflect\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"golang.org/x/net/http/httpguts\"\n\t\"golang.org/x/net/http2/hpack\"\n\t\"golang.org/x/net/internal/httpcommon\"\n)\n\nconst (\n\tprefaceTimeout        = 10 * time.Second\n\tfirstSettingsTimeout  = 2 * time.Second // should be in-flight with preface anyway\n\thandlerChunkWriteSize = 4 << 10\n\tdefaultMaxStreams     = 250 // TODO: make this 100 as the GFE seems to?\n\n\t// maxQueuedControlFrames is the maximum number of control frames like\n\t// SETTINGS, PING and RST_STREAM that will be queued for writing before\n\t// the connection is closed to prevent memory exhaustion attacks.\n\tmaxQueuedControlFrames = 10000\n)\n\nvar (\n\terrClientDisconnected = errors.New(\"client disconnected\")\n\terrClosedBody         = errors.New(\"body closed by handler\")\n\terrHandlerComplete    = errors.New(\"http2: request body closed due to handler exiting\")\n\terrStreamClosed       = errors.New(\"http2: stream closed\")\n)\n\nvar responseWriterStatePool = sync.Pool{\n\tNew: func() interface{} {\n\t\trws := &responseWriterState{}\n\t\trws.bw = bufio.NewWriterSize(chunkWriter{rws}, handlerChunkWriteSize)\n\t\treturn rws\n\t},\n}\n\n// Test hooks.\nvar (\n\ttestHookOnConn        func()\n\ttestHookGetServerConn func(*serverConn)\n\ttestHookOnPanicMu     *sync.Mutex // nil except in tests\n\ttestHookOnPanic       func(sc *serverConn, panicVal interface{}) (rePanic bool)\n)\n\n// Server is an HTTP/2 server.\ntype Server struct {\n\t// MaxHandlers limits the number of http.Handler ServeHTTP goroutines\n\t// which may run at a time over all connections.\n\t// Negative or zero no limit.\n\t// TODO: implement\n\tMaxHandlers int\n\n\t// MaxConcurrentStreams optionally specifies the number of\n\t// concurrent streams that each client may have open at a\n\t// time. This is unrelated to the number of http.Handler goroutines\n\t// which may be active globally, which is MaxHandlers.\n\t// If zero, MaxConcurrentStreams defaults to at least 100, per\n\t// the HTTP/2 spec's recommendations.\n\tMaxConcurrentStreams uint32\n\n\t// MaxDecoderHeaderTableSize optionally specifies the http2\n\t// SETTINGS_HEADER_TABLE_SIZE to send in the initial settings frame. It\n\t// informs the remote endpoint of the maximum size of the header compression\n\t// table used to decode header blocks, in octets. If zero, the default value\n\t// of 4096 is used.\n\tMaxDecoderHeaderTableSize uint32\n\n\t// MaxEncoderHeaderTableSize optionally specifies an upper limit for the\n\t// header compression table used for encoding request headers. Received\n\t// SETTINGS_HEADER_TABLE_SIZE settings are capped at this limit. If zero,\n\t// the default value of 4096 is used.\n\tMaxEncoderHeaderTableSize uint32\n\n\t// MaxReadFrameSize optionally specifies the largest frame\n\t// this server is willing to read. A valid value is between\n\t// 16k and 16M, inclusive. If zero or otherwise invalid, a\n\t// default value is used.\n\tMaxReadFrameSize uint32\n\n\t// PermitProhibitedCipherSuites, if true, permits the use of\n\t// cipher suites prohibited by the HTTP/2 spec.\n\tPermitProhibitedCipherSuites bool\n\n\t// IdleTimeout specifies how long until idle clients should be\n\t// closed with a GOAWAY frame. PING frames are not considered\n\t// activity for the purposes of IdleTimeout.\n\t// If zero or negative, there is no timeout.\n\tIdleTimeout time.Duration\n\n\t// ReadIdleTimeout is the timeout after which a health check using a ping\n\t// frame will be carried out if no frame is received on the connection.\n\t// If zero, no health check is performed.\n\tReadIdleTimeout time.Duration\n\n\t// PingTimeout is the timeout after which the connection will be closed\n\t// if a response to a ping is not received.\n\t// If zero, a default of 15 seconds is used.\n\tPingTimeout time.Duration\n\n\t// WriteByteTimeout is the timeout after which a connection will be\n\t// closed if no data can be written to it. The timeout begins when data is\n\t// available to write, and is extended whenever any bytes are written.\n\t// If zero or negative, there is no timeout.\n\tWriteByteTimeout time.Duration\n\n\t// MaxUploadBufferPerConnection is the size of the initial flow\n\t// control window for each connections. The HTTP/2 spec does not\n\t// allow this to be smaller than 65535 or larger than 2^32-1.\n\t// If the value is outside this range, a default value will be\n\t// used instead.\n\tMaxUploadBufferPerConnection int32\n\n\t// MaxUploadBufferPerStream is the size of the initial flow control\n\t// window for each stream. The HTTP/2 spec does not allow this to\n\t// be larger than 2^32-1. If the value is zero or larger than the\n\t// maximum, a default value will be used instead.\n\tMaxUploadBufferPerStream int32\n\n\t// NewWriteScheduler constructs a write scheduler for a connection.\n\t// If nil, a default scheduler is chosen.\n\tNewWriteScheduler func() WriteScheduler\n\n\t// CountError, if non-nil, is called on HTTP/2 server errors.\n\t// It's intended to increment a metric for monitoring, such\n\t// as an expvar or Prometheus metric.\n\t// The errType consists of only ASCII word characters.\n\tCountError func(errType string)\n\n\t// Internal state. This is a pointer (rather than embedded directly)\n\t// so that we don't embed a Mutex in this struct, which will make the\n\t// struct non-copyable, which might break some callers.\n\tstate *serverInternalState\n\n\t// Synchronization group used for testing.\n\t// Outside of tests, this is nil.\n\tgroup synctestGroupInterface\n}\n\nfunc (s *Server) markNewGoroutine() {\n\tif s.group != nil {\n\t\ts.group.Join()\n\t}\n}\n\nfunc (s *Server) now() time.Time {\n\tif s.group != nil {\n\t\treturn s.group.Now()\n\t}\n\treturn time.Now()\n}\n\n// newTimer creates a new time.Timer, or a synthetic timer in tests.\nfunc (s *Server) newTimer(d time.Duration) timer {\n\tif s.group != nil {\n\t\treturn s.group.NewTimer(d)\n\t}\n\treturn timeTimer{time.NewTimer(d)}\n}\n\n// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests.\nfunc (s *Server) afterFunc(d time.Duration, f func()) timer {\n\tif s.group != nil {\n\t\treturn s.group.AfterFunc(d, f)\n\t}\n\treturn timeTimer{time.AfterFunc(d, f)}\n}\n\ntype serverInternalState struct {\n\tmu          sync.Mutex\n\tactiveConns map[*serverConn]struct{}\n}\n\nfunc (s *serverInternalState) registerConn(sc *serverConn) {\n\tif s == nil {\n\t\treturn // if the Server was used without calling ConfigureServer\n\t}\n\ts.mu.Lock()\n\ts.activeConns[sc] = struct{}{}\n\ts.mu.Unlock()\n}\n\nfunc (s *serverInternalState) unregisterConn(sc *serverConn) {\n\tif s == nil {\n\t\treturn // if the Server was used without calling ConfigureServer\n\t}\n\ts.mu.Lock()\n\tdelete(s.activeConns, sc)\n\ts.mu.Unlock()\n}\n\nfunc (s *serverInternalState) startGracefulShutdown() {\n\tif s == nil {\n\t\treturn // if the Server was used without calling ConfigureServer\n\t}\n\ts.mu.Lock()\n\tfor sc := range s.activeConns {\n\t\tsc.startGracefulShutdown()\n\t}\n\ts.mu.Unlock()\n}\n\n// ConfigureServer adds HTTP/2 support to a net/http Server.\n//\n// The configuration conf may be nil.\n//\n// ConfigureServer must be called before s begins serving.\nfunc ConfigureServer(s *http.Server, conf *Server) error {\n\tif s == nil {\n\t\tpanic(\"nil *http.Server\")\n\t}\n\tif conf == nil {\n\t\tconf = new(Server)\n\t}\n\tconf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})}\n\tif h1, h2 := s, conf; h2.IdleTimeout == 0 {\n\t\tif h1.IdleTimeout != 0 {\n\t\t\th2.IdleTimeout = h1.IdleTimeout\n\t\t} else {\n\t\t\th2.IdleTimeout = h1.ReadTimeout\n\t\t}\n\t}\n\ts.RegisterOnShutdown(conf.state.startGracefulShutdown)\n\n\tif s.TLSConfig == nil {\n\t\ts.TLSConfig = new(tls.Config)\n\t} else if s.TLSConfig.CipherSuites != nil && s.TLSConfig.MinVersion < tls.VersionTLS13 {\n\t\t// If they already provided a TLS 1.0–1.2 CipherSuite list, return an\n\t\t// error if it is missing ECDHE_RSA_WITH_AES_128_GCM_SHA256 or\n\t\t// ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.\n\t\thaveRequired := false\n\t\tfor _, cs := range s.TLSConfig.CipherSuites {\n\t\t\tswitch cs {\n\t\t\tcase tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n\t\t\t\t// Alternative MTI cipher to not discourage ECDSA-only servers.\n\t\t\t\t// See http://golang.org/cl/30721 for further information.\n\t\t\t\ttls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:\n\t\t\t\thaveRequired = true\n\t\t\t}\n\t\t}\n\t\tif !haveRequired {\n\t\t\treturn fmt.Errorf(\"http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher (need at least one of TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 or TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)\")\n\t\t}\n\t}\n\n\t// Note: not setting MinVersion to tls.VersionTLS12,\n\t// as we don't want to interfere with HTTP/1.1 traffic\n\t// on the user's server. We enforce TLS 1.2 later once\n\t// we accept a connection. Ideally this should be done\n\t// during next-proto selection, but using TLS <1.2 with\n\t// HTTP/2 is still the client's bug.\n\n\ts.TLSConfig.PreferServerCipherSuites = true\n\n\tif !strSliceContains(s.TLSConfig.NextProtos, NextProtoTLS) {\n\t\ts.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, NextProtoTLS)\n\t}\n\tif !strSliceContains(s.TLSConfig.NextProtos, \"http/1.1\") {\n\t\ts.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, \"http/1.1\")\n\t}\n\n\tif s.TLSNextProto == nil {\n\t\ts.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){}\n\t}\n\tprotoHandler := func(hs *http.Server, c net.Conn, h http.Handler, sawClientPreface bool) {\n\t\tif testHookOnConn != nil {\n\t\t\ttestHookOnConn()\n\t\t}\n\t\t// The TLSNextProto interface predates contexts, so\n\t\t// the net/http package passes down its per-connection\n\t\t// base context via an exported but unadvertised\n\t\t// method on the Handler. This is for internal\n\t\t// net/http<=>http2 use only.\n\t\tvar ctx context.Context\n\t\ttype baseContexter interface {\n\t\t\tBaseContext() context.Context\n\t\t}\n\t\tif bc, ok := h.(baseContexter); ok {\n\t\t\tctx = bc.BaseContext()\n\t\t}\n\t\tconf.ServeConn(c, &ServeConnOpts{\n\t\t\tContext:          ctx,\n\t\t\tHandler:          h,\n\t\t\tBaseConfig:       hs,\n\t\t\tSawClientPreface: sawClientPreface,\n\t\t})\n\t}\n\ts.TLSNextProto[NextProtoTLS] = func(hs *http.Server, c *tls.Conn, h http.Handler) {\n\t\tprotoHandler(hs, c, h, false)\n\t}\n\t// The \"unencrypted_http2\" TLSNextProto key is used to pass off non-TLS HTTP/2 conns.\n\t//\n\t// A connection passed in this method has already had the HTTP/2 preface read from it.\n\ts.TLSNextProto[nextProtoUnencryptedHTTP2] = func(hs *http.Server, c *tls.Conn, h http.Handler) {\n\t\tnc, err := unencryptedNetConnFromTLSConn(c)\n\t\tif err != nil {\n\t\t\tif lg := hs.ErrorLog; lg != nil {\n\t\t\t\tlg.Print(err)\n\t\t\t} else {\n\t\t\t\tlog.Print(err)\n\t\t\t}\n\t\t\tgo c.Close()\n\t\t\treturn\n\t\t}\n\t\tprotoHandler(hs, nc, h, true)\n\t}\n\treturn nil\n}\n\n// ServeConnOpts are options for the Server.ServeConn method.\ntype ServeConnOpts struct {\n\t// Context is the base context to use.\n\t// If nil, context.Background is used.\n\tContext context.Context\n\n\t// BaseConfig optionally sets the base configuration\n\t// for values. If nil, defaults are used.\n\tBaseConfig *http.Server\n\n\t// Handler specifies which handler to use for processing\n\t// requests. If nil, BaseConfig.Handler is used. If BaseConfig\n\t// or BaseConfig.Handler is nil, http.DefaultServeMux is used.\n\tHandler http.Handler\n\n\t// UpgradeRequest is an initial request received on a connection\n\t// undergoing an h2c upgrade. The request body must have been\n\t// completely read from the connection before calling ServeConn,\n\t// and the 101 Switching Protocols response written.\n\tUpgradeRequest *http.Request\n\n\t// Settings is the decoded contents of the HTTP2-Settings header\n\t// in an h2c upgrade request.\n\tSettings []byte\n\n\t// SawClientPreface is set if the HTTP/2 connection preface\n\t// has already been read from the connection.\n\tSawClientPreface bool\n}\n\nfunc (o *ServeConnOpts) context() context.Context {\n\tif o != nil && o.Context != nil {\n\t\treturn o.Context\n\t}\n\treturn context.Background()\n}\n\nfunc (o *ServeConnOpts) baseConfig() *http.Server {\n\tif o != nil && o.BaseConfig != nil {\n\t\treturn o.BaseConfig\n\t}\n\treturn new(http.Server)\n}\n\nfunc (o *ServeConnOpts) handler() http.Handler {\n\tif o != nil {\n\t\tif o.Handler != nil {\n\t\t\treturn o.Handler\n\t\t}\n\t\tif o.BaseConfig != nil && o.BaseConfig.Handler != nil {\n\t\t\treturn o.BaseConfig.Handler\n\t\t}\n\t}\n\treturn http.DefaultServeMux\n}\n\n// ServeConn serves HTTP/2 requests on the provided connection and\n// blocks until the connection is no longer readable.\n//\n// ServeConn starts speaking HTTP/2 assuming that c has not had any\n// reads or writes. It writes its initial settings frame and expects\n// to be able to read the preface and settings frame from the\n// client. If c has a ConnectionState method like a *tls.Conn, the\n// ConnectionState is used to verify the TLS ciphersuite and to set\n// the Request.TLS field in Handlers.\n//\n// ServeConn does not support h2c by itself. Any h2c support must be\n// implemented in terms of providing a suitably-behaving net.Conn.\n//\n// The opts parameter is optional. If nil, default values are used.\nfunc (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {\n\ts.serveConn(c, opts, nil)\n}\n\nfunc (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverConn)) {\n\tbaseCtx, cancel := serverConnBaseContext(c, opts)\n\tdefer cancel()\n\n\thttp1srv := opts.baseConfig()\n\tconf := configFromServer(http1srv, s)\n\tsc := &serverConn{\n\t\tsrv:                         s,\n\t\ths:                          http1srv,\n\t\tconn:                        c,\n\t\tbaseCtx:                     baseCtx,\n\t\tremoteAddrStr:               c.RemoteAddr().String(),\n\t\tbw:                          newBufferedWriter(s.group, c, conf.WriteByteTimeout),\n\t\thandler:                     opts.handler(),\n\t\tstreams:                     make(map[uint32]*stream),\n\t\treadFrameCh:                 make(chan readFrameResult),\n\t\twantWriteFrameCh:            make(chan FrameWriteRequest, 8),\n\t\tserveMsgCh:                  make(chan interface{}, 8),\n\t\twroteFrameCh:                make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync\n\t\tbodyReadCh:                  make(chan bodyReadMsg),         // buffering doesn't matter either way\n\t\tdoneServing:                 make(chan struct{}),\n\t\tclientMaxStreams:            math.MaxUint32, // Section 6.5.2: \"Initially, there is no limit to this value\"\n\t\tadvMaxStreams:               conf.MaxConcurrentStreams,\n\t\tinitialStreamSendWindowSize: initialWindowSize,\n\t\tinitialStreamRecvWindowSize: conf.MaxUploadBufferPerStream,\n\t\tmaxFrameSize:                initialMaxFrameSize,\n\t\tpingTimeout:                 conf.PingTimeout,\n\t\tcountErrorFunc:              conf.CountError,\n\t\tserveG:                      newGoroutineLock(),\n\t\tpushEnabled:                 true,\n\t\tsawClientPreface:            opts.SawClientPreface,\n\t}\n\tif newf != nil {\n\t\tnewf(sc)\n\t}\n\n\ts.state.registerConn(sc)\n\tdefer s.state.unregisterConn(sc)\n\n\t// The net/http package sets the write deadline from the\n\t// http.Server.WriteTimeout during the TLS handshake, but then\n\t// passes the connection off to us with the deadline already set.\n\t// Write deadlines are set per stream in serverConn.newStream.\n\t// Disarm the net.Conn write deadline here.\n\tif sc.hs.WriteTimeout > 0 {\n\t\tsc.conn.SetWriteDeadline(time.Time{})\n\t}\n\n\tif s.NewWriteScheduler != nil {\n\t\tsc.writeSched = s.NewWriteScheduler()\n\t} else {\n\t\tsc.writeSched = newRoundRobinWriteScheduler()\n\t}\n\n\t// These start at the RFC-specified defaults. If there is a higher\n\t// configured value for inflow, that will be updated when we send a\n\t// WINDOW_UPDATE shortly after sending SETTINGS.\n\tsc.flow.add(initialWindowSize)\n\tsc.inflow.init(initialWindowSize)\n\tsc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)\n\tsc.hpackEncoder.SetMaxDynamicTableSizeLimit(conf.MaxEncoderHeaderTableSize)\n\n\tfr := NewFramer(sc.bw, c)\n\tif conf.CountError != nil {\n\t\tfr.countError = conf.CountError\n\t}\n\tfr.ReadMetaHeaders = hpack.NewDecoder(conf.MaxDecoderHeaderTableSize, nil)\n\tfr.MaxHeaderListSize = sc.maxHeaderListSize()\n\tfr.SetMaxReadFrameSize(conf.MaxReadFrameSize)\n\tsc.framer = fr\n\n\tif tc, ok := c.(connectionStater); ok {\n\t\tsc.tlsState = new(tls.ConnectionState)\n\t\t*sc.tlsState = tc.ConnectionState()\n\t\t// 9.2 Use of TLS Features\n\t\t// An implementation of HTTP/2 over TLS MUST use TLS\n\t\t// 1.2 or higher with the restrictions on feature set\n\t\t// and cipher suite described in this section. Due to\n\t\t// implementation limitations, it might not be\n\t\t// possible to fail TLS negotiation. An endpoint MUST\n\t\t// immediately terminate an HTTP/2 connection that\n\t\t// does not meet the TLS requirements described in\n\t\t// this section with a connection error (Section\n\t\t// 5.4.1) of type INADEQUATE_SECURITY.\n\t\tif sc.tlsState.Version < tls.VersionTLS12 {\n\t\t\tsc.rejectConn(ErrCodeInadequateSecurity, \"TLS version too low\")\n\t\t\treturn\n\t\t}\n\n\t\tif sc.tlsState.ServerName == \"\" {\n\t\t\t// Client must use SNI, but we don't enforce that anymore,\n\t\t\t// since it was causing problems when connecting to bare IP\n\t\t\t// addresses during development.\n\t\t\t//\n\t\t\t// TODO: optionally enforce? Or enforce at the time we receive\n\t\t\t// a new request, and verify the ServerName matches the :authority?\n\t\t\t// But that precludes proxy situations, perhaps.\n\t\t\t//\n\t\t\t// So for now, do nothing here again.\n\t\t}\n\n\t\tif !conf.PermitProhibitedCipherSuites && isBadCipher(sc.tlsState.CipherSuite) {\n\t\t\t// \"Endpoints MAY choose to generate a connection error\n\t\t\t// (Section 5.4.1) of type INADEQUATE_SECURITY if one of\n\t\t\t// the prohibited cipher suites are negotiated.\"\n\t\t\t//\n\t\t\t// We choose that. In my opinion, the spec is weak\n\t\t\t// here. It also says both parties must support at least\n\t\t\t// TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 so there's no\n\t\t\t// excuses here. If we really must, we could allow an\n\t\t\t// \"AllowInsecureWeakCiphers\" option on the server later.\n\t\t\t// Let's see how it plays out first.\n\t\t\tsc.rejectConn(ErrCodeInadequateSecurity, fmt.Sprintf(\"Prohibited TLS 1.2 Cipher Suite: %x\", sc.tlsState.CipherSuite))\n\t\t\treturn\n\t\t}\n\t}\n\n\tif opts.Settings != nil {\n\t\tfr := &SettingsFrame{\n\t\t\tFrameHeader: FrameHeader{valid: true},\n\t\t\tp:           opts.Settings,\n\t\t}\n\t\tif err := fr.ForeachSetting(sc.processSetting); err != nil {\n\t\t\tsc.rejectConn(ErrCodeProtocol, \"invalid settings\")\n\t\t\treturn\n\t\t}\n\t\topts.Settings = nil\n\t}\n\n\tif hook := testHookGetServerConn; hook != nil {\n\t\thook(sc)\n\t}\n\n\tif opts.UpgradeRequest != nil {\n\t\tsc.upgradeRequest(opts.UpgradeRequest)\n\t\topts.UpgradeRequest = nil\n\t}\n\n\tsc.serve(conf)\n}\n\nfunc serverConnBaseContext(c net.Conn, opts *ServeConnOpts) (ctx context.Context, cancel func()) {\n\tctx, cancel = context.WithCancel(opts.context())\n\tctx = context.WithValue(ctx, http.LocalAddrContextKey, c.LocalAddr())\n\tif hs := opts.baseConfig(); hs != nil {\n\t\tctx = context.WithValue(ctx, http.ServerContextKey, hs)\n\t}\n\treturn\n}\n\nfunc (sc *serverConn) rejectConn(err ErrCode, debug string) {\n\tsc.vlogf(\"http2: server rejecting conn: %v, %s\", err, debug)\n\t// ignoring errors. hanging up anyway.\n\tsc.framer.WriteGoAway(0, err, []byte(debug))\n\tsc.bw.Flush()\n\tsc.conn.Close()\n}\n\ntype serverConn struct {\n\t// Immutable:\n\tsrv              *Server\n\ths               *http.Server\n\tconn             net.Conn\n\tbw               *bufferedWriter // writing to conn\n\thandler          http.Handler\n\tbaseCtx          context.Context\n\tframer           *Framer\n\tdoneServing      chan struct{}          // closed when serverConn.serve ends\n\treadFrameCh      chan readFrameResult   // written by serverConn.readFrames\n\twantWriteFrameCh chan FrameWriteRequest // from handlers -> serve\n\twroteFrameCh     chan frameWriteResult  // from writeFrameAsync -> serve, tickles more frame writes\n\tbodyReadCh       chan bodyReadMsg       // from handlers -> serve\n\tserveMsgCh       chan interface{}       // misc messages & code to send to / run on the serve loop\n\tflow             outflow                // conn-wide (not stream-specific) outbound flow control\n\tinflow           inflow                 // conn-wide inbound flow control\n\ttlsState         *tls.ConnectionState   // shared by all handlers, like net/http\n\tremoteAddrStr    string\n\twriteSched       WriteScheduler\n\tcountErrorFunc   func(errType string)\n\n\t// Everything following is owned by the serve loop; use serveG.check():\n\tserveG                      goroutineLock // used to verify funcs are on serve()\n\tpushEnabled                 bool\n\tsawClientPreface            bool // preface has already been read, used in h2c upgrade\n\tsawFirstSettings            bool // got the initial SETTINGS frame after the preface\n\tneedToSendSettingsAck       bool\n\tunackedSettings             int    // how many SETTINGS have we sent without ACKs?\n\tqueuedControlFrames         int    // control frames in the writeSched queue\n\tclientMaxStreams            uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit)\n\tadvMaxStreams               uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client\n\tcurClientStreams            uint32 // number of open streams initiated by the client\n\tcurPushedStreams            uint32 // number of open streams initiated by server push\n\tcurHandlers                 uint32 // number of running handler goroutines\n\tmaxClientStreamID           uint32 // max ever seen from client (odd), or 0 if there have been no client requests\n\tmaxPushPromiseID            uint32 // ID of the last push promise (even), or 0 if there have been no pushes\n\tstreams                     map[uint32]*stream\n\tunstartedHandlers           []unstartedHandler\n\tinitialStreamSendWindowSize int32\n\tinitialStreamRecvWindowSize int32\n\tmaxFrameSize                int32\n\tpeerMaxHeaderListSize       uint32            // zero means unknown (default)\n\tcanonHeader                 map[string]string // http2-lower-case -> Go-Canonical-Case\n\tcanonHeaderKeysSize         int               // canonHeader keys size in bytes\n\twritingFrame                bool              // started writing a frame (on serve goroutine or separate)\n\twritingFrameAsync           bool              // started a frame on its own goroutine but haven't heard back on wroteFrameCh\n\tneedsFrameFlush             bool              // last frame write wasn't a flush\n\tinGoAway                    bool              // we've started to or sent GOAWAY\n\tinFrameScheduleLoop         bool              // whether we're in the scheduleFrameWrite loop\n\tneedToSendGoAway            bool              // we need to schedule a GOAWAY frame write\n\tpingSent                    bool\n\tsentPingData                [8]byte\n\tgoAwayCode                  ErrCode\n\tshutdownTimer               timer // nil until used\n\tidleTimer                   timer // nil if unused\n\treadIdleTimeout             time.Duration\n\tpingTimeout                 time.Duration\n\treadIdleTimer               timer // nil if unused\n\n\t// Owned by the writeFrameAsync goroutine:\n\theaderWriteBuf bytes.Buffer\n\thpackEncoder   *hpack.Encoder\n\n\t// Used by startGracefulShutdown.\n\tshutdownOnce sync.Once\n}\n\nfunc (sc *serverConn) maxHeaderListSize() uint32 {\n\tn := sc.hs.MaxHeaderBytes\n\tif n <= 0 {\n\t\tn = http.DefaultMaxHeaderBytes\n\t}\n\treturn uint32(adjustHTTP1MaxHeaderSize(int64(n)))\n}\n\nfunc (sc *serverConn) curOpenStreams() uint32 {\n\tsc.serveG.check()\n\treturn sc.curClientStreams + sc.curPushedStreams\n}\n\n// stream represents a stream. This is the minimal metadata needed by\n// the serve goroutine. Most of the actual stream state is owned by\n// the http.Handler's goroutine in the responseWriter. Because the\n// responseWriter's responseWriterState is recycled at the end of a\n// handler, this struct intentionally has no pointer to the\n// *responseWriter{,State} itself, as the Handler ending nils out the\n// responseWriter's state field.\ntype stream struct {\n\t// immutable:\n\tsc        *serverConn\n\tid        uint32\n\tbody      *pipe       // non-nil if expecting DATA frames\n\tcw        closeWaiter // closed wait stream transitions to closed state\n\tctx       context.Context\n\tcancelCtx func()\n\n\t// owned by serverConn's serve loop:\n\tbodyBytes        int64   // body bytes seen so far\n\tdeclBodyBytes    int64   // or -1 if undeclared\n\tflow             outflow // limits writing from Handler to client\n\tinflow           inflow  // what the client is allowed to POST/etc to us\n\tstate            streamState\n\tresetQueued      bool  // RST_STREAM queued for write; set by sc.resetStream\n\tgotTrailerHeader bool  // HEADER frame for trailers was seen\n\twroteHeaders     bool  // whether we wrote headers (not status 100)\n\treadDeadline     timer // nil if unused\n\twriteDeadline    timer // nil if unused\n\tcloseErr         error // set before cw is closed\n\n\ttrailer    http.Header // accumulated trailers\n\treqTrailer http.Header // handler's Request.Trailer\n}\n\nfunc (sc *serverConn) Framer() *Framer  { return sc.framer }\nfunc (sc *serverConn) CloseConn() error { return sc.conn.Close() }\nfunc (sc *serverConn) Flush() error     { return sc.bw.Flush() }\nfunc (sc *serverConn) HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) {\n\treturn sc.hpackEncoder, &sc.headerWriteBuf\n}\n\nfunc (sc *serverConn) state(streamID uint32) (streamState, *stream) {\n\tsc.serveG.check()\n\t// http://tools.ietf.org/html/rfc7540#section-5.1\n\tif st, ok := sc.streams[streamID]; ok {\n\t\treturn st.state, st\n\t}\n\t// \"The first use of a new stream identifier implicitly closes all\n\t// streams in the \"idle\" state that might have been initiated by\n\t// that peer with a lower-valued stream identifier. For example, if\n\t// a client sends a HEADERS frame on stream 7 without ever sending a\n\t// frame on stream 5, then stream 5 transitions to the \"closed\"\n\t// state when the first frame for stream 7 is sent or received.\"\n\tif streamID%2 == 1 {\n\t\tif streamID <= sc.maxClientStreamID {\n\t\t\treturn stateClosed, nil\n\t\t}\n\t} else {\n\t\tif streamID <= sc.maxPushPromiseID {\n\t\t\treturn stateClosed, nil\n\t\t}\n\t}\n\treturn stateIdle, nil\n}\n\n// setConnState calls the net/http ConnState hook for this connection, if configured.\n// Note that the net/http package does StateNew and StateClosed for us.\n// There is currently no plan for StateHijacked or hijacking HTTP/2 connections.\nfunc (sc *serverConn) setConnState(state http.ConnState) {\n\tif sc.hs.ConnState != nil {\n\t\tsc.hs.ConnState(sc.conn, state)\n\t}\n}\n\nfunc (sc *serverConn) vlogf(format string, args ...interface{}) {\n\tif VerboseLogs {\n\t\tsc.logf(format, args...)\n\t}\n}\n\nfunc (sc *serverConn) logf(format string, args ...interface{}) {\n\tif lg := sc.hs.ErrorLog; lg != nil {\n\t\tlg.Printf(format, args...)\n\t} else {\n\t\tlog.Printf(format, args...)\n\t}\n}\n\n// errno returns v's underlying uintptr, else 0.\n//\n// TODO: remove this helper function once http2 can use build\n// tags. See comment in isClosedConnError.\nfunc errno(v error) uintptr {\n\tif rv := reflect.ValueOf(v); rv.Kind() == reflect.Uintptr {\n\t\treturn uintptr(rv.Uint())\n\t}\n\treturn 0\n}\n\n// isClosedConnError reports whether err is an error from use of a closed\n// network connection.\nfunc isClosedConnError(err error) bool {\n\tif err == nil {\n\t\treturn false\n\t}\n\n\tif errors.Is(err, net.ErrClosed) {\n\t\treturn true\n\t}\n\n\t// TODO(bradfitz): x/tools/cmd/bundle doesn't really support\n\t// build tags, so I can't make an http2_windows.go file with\n\t// Windows-specific stuff. Fix that and move this, once we\n\t// have a way to bundle this into std's net/http somehow.\n\tif runtime.GOOS == \"windows\" {\n\t\tif oe, ok := err.(*net.OpError); ok && oe.Op == \"read\" {\n\t\t\tif se, ok := oe.Err.(*os.SyscallError); ok && se.Syscall == \"wsarecv\" {\n\t\t\t\tconst WSAECONNABORTED = 10053\n\t\t\t\tconst WSAECONNRESET = 10054\n\t\t\t\tif n := errno(se.Err); n == WSAECONNRESET || n == WSAECONNABORTED {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (sc *serverConn) condlogf(err error, format string, args ...interface{}) {\n\tif err == nil {\n\t\treturn\n\t}\n\tif err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) || err == errPrefaceTimeout {\n\t\t// Boring, expected errors.\n\t\tsc.vlogf(format, args...)\n\t} else {\n\t\tsc.logf(format, args...)\n\t}\n}\n\n// maxCachedCanonicalHeadersKeysSize is an arbitrarily-chosen limit on the size\n// of the entries in the canonHeader cache.\n// This should be larger than the size of unique, uncommon header keys likely to\n// be sent by the peer, while not so high as to permit unreasonable memory usage\n// if the peer sends an unbounded number of unique header keys.\nconst maxCachedCanonicalHeadersKeysSize = 2048\n\nfunc (sc *serverConn) canonicalHeader(v string) string {\n\tsc.serveG.check()\n\tcv, ok := httpcommon.CachedCanonicalHeader(v)\n\tif ok {\n\t\treturn cv\n\t}\n\tcv, ok = sc.canonHeader[v]\n\tif ok {\n\t\treturn cv\n\t}\n\tif sc.canonHeader == nil {\n\t\tsc.canonHeader = make(map[string]string)\n\t}\n\tcv = http.CanonicalHeaderKey(v)\n\tsize := 100 + len(v)*2 // 100 bytes of map overhead + key + value\n\tif sc.canonHeaderKeysSize+size <= maxCachedCanonicalHeadersKeysSize {\n\t\tsc.canonHeader[v] = cv\n\t\tsc.canonHeaderKeysSize += size\n\t}\n\treturn cv\n}\n\ntype readFrameResult struct {\n\tf   Frame // valid until readMore is called\n\terr error\n\n\t// readMore should be called once the consumer no longer needs or\n\t// retains f. After readMore, f is invalid and more frames can be\n\t// read.\n\treadMore func()\n}\n\n// readFrames is the loop that reads incoming frames.\n// It takes care to only read one frame at a time, blocking until the\n// consumer is done with the frame.\n// It's run on its own goroutine.\nfunc (sc *serverConn) readFrames() {\n\tsc.srv.markNewGoroutine()\n\tgate := make(chan struct{})\n\tgateDone := func() { gate <- struct{}{} }\n\tfor {\n\t\tf, err := sc.framer.ReadFrame()\n\t\tselect {\n\t\tcase sc.readFrameCh <- readFrameResult{f, err, gateDone}:\n\t\tcase <-sc.doneServing:\n\t\t\treturn\n\t\t}\n\t\tselect {\n\t\tcase <-gate:\n\t\tcase <-sc.doneServing:\n\t\t\treturn\n\t\t}\n\t\tif terminalReadFrameError(err) {\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// frameWriteResult is the message passed from writeFrameAsync to the serve goroutine.\ntype frameWriteResult struct {\n\t_   incomparable\n\twr  FrameWriteRequest // what was written (or attempted)\n\terr error             // result of the writeFrame call\n}\n\n// writeFrameAsync runs in its own goroutine and writes a single frame\n// and then reports when it's done.\n// At most one goroutine can be running writeFrameAsync at a time per\n// serverConn.\nfunc (sc *serverConn) writeFrameAsync(wr FrameWriteRequest, wd *writeData) {\n\tsc.srv.markNewGoroutine()\n\tvar err error\n\tif wd == nil {\n\t\terr = wr.write.writeFrame(sc)\n\t} else {\n\t\terr = sc.framer.endWrite()\n\t}\n\tsc.wroteFrameCh <- frameWriteResult{wr: wr, err: err}\n}\n\nfunc (sc *serverConn) closeAllStreamsOnConnClose() {\n\tsc.serveG.check()\n\tfor _, st := range sc.streams {\n\t\tsc.closeStream(st, errClientDisconnected)\n\t}\n}\n\nfunc (sc *serverConn) stopShutdownTimer() {\n\tsc.serveG.check()\n\tif t := sc.shutdownTimer; t != nil {\n\t\tt.Stop()\n\t}\n}\n\nfunc (sc *serverConn) notePanic() {\n\t// Note: this is for serverConn.serve panicking, not http.Handler code.\n\tif testHookOnPanicMu != nil {\n\t\ttestHookOnPanicMu.Lock()\n\t\tdefer testHookOnPanicMu.Unlock()\n\t}\n\tif testHookOnPanic != nil {\n\t\tif e := recover(); e != nil {\n\t\t\tif testHookOnPanic(sc, e) {\n\t\t\t\tpanic(e)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (sc *serverConn) serve(conf http2Config) {\n\tsc.serveG.check()\n\tdefer sc.notePanic()\n\tdefer sc.conn.Close()\n\tdefer sc.closeAllStreamsOnConnClose()\n\tdefer sc.stopShutdownTimer()\n\tdefer close(sc.doneServing) // unblocks handlers trying to send\n\n\tif VerboseLogs {\n\t\tsc.vlogf(\"http2: server connection from %v on %p\", sc.conn.RemoteAddr(), sc.hs)\n\t}\n\n\tsettings := writeSettings{\n\t\t{SettingMaxFrameSize, conf.MaxReadFrameSize},\n\t\t{SettingMaxConcurrentStreams, sc.advMaxStreams},\n\t\t{SettingMaxHeaderListSize, sc.maxHeaderListSize()},\n\t\t{SettingHeaderTableSize, conf.MaxDecoderHeaderTableSize},\n\t\t{SettingInitialWindowSize, uint32(sc.initialStreamRecvWindowSize)},\n\t}\n\tif !disableExtendedConnectProtocol {\n\t\tsettings = append(settings, Setting{SettingEnableConnectProtocol, 1})\n\t}\n\tsc.writeFrame(FrameWriteRequest{\n\t\twrite: settings,\n\t})\n\tsc.unackedSettings++\n\n\t// Each connection starts with initialWindowSize inflow tokens.\n\t// If a higher value is configured, we add more tokens.\n\tif diff := conf.MaxUploadBufferPerConnection - initialWindowSize; diff > 0 {\n\t\tsc.sendWindowUpdate(nil, int(diff))\n\t}\n\n\tif err := sc.readPreface(); err != nil {\n\t\tsc.condlogf(err, \"http2: server: error reading preface from client %v: %v\", sc.conn.RemoteAddr(), err)\n\t\treturn\n\t}\n\t// Now that we've got the preface, get us out of the\n\t// \"StateNew\" state. We can't go directly to idle, though.\n\t// Active means we read some data and anticipate a request. We'll\n\t// do another Active when we get a HEADERS frame.\n\tsc.setConnState(http.StateActive)\n\tsc.setConnState(http.StateIdle)\n\n\tif sc.srv.IdleTimeout > 0 {\n\t\tsc.idleTimer = sc.srv.afterFunc(sc.srv.IdleTimeout, sc.onIdleTimer)\n\t\tdefer sc.idleTimer.Stop()\n\t}\n\n\tif conf.SendPingTimeout > 0 {\n\t\tsc.readIdleTimeout = conf.SendPingTimeout\n\t\tsc.readIdleTimer = sc.srv.afterFunc(conf.SendPingTimeout, sc.onReadIdleTimer)\n\t\tdefer sc.readIdleTimer.Stop()\n\t}\n\n\tgo sc.readFrames() // closed by defer sc.conn.Close above\n\n\tsettingsTimer := sc.srv.afterFunc(firstSettingsTimeout, sc.onSettingsTimer)\n\tdefer settingsTimer.Stop()\n\n\tlastFrameTime := sc.srv.now()\n\tloopNum := 0\n\tfor {\n\t\tloopNum++\n\t\tselect {\n\t\tcase wr := <-sc.wantWriteFrameCh:\n\t\t\tif se, ok := wr.write.(StreamError); ok {\n\t\t\t\tsc.resetStream(se)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tsc.writeFrame(wr)\n\t\tcase res := <-sc.wroteFrameCh:\n\t\t\tsc.wroteFrame(res)\n\t\tcase res := <-sc.readFrameCh:\n\t\t\tlastFrameTime = sc.srv.now()\n\t\t\t// Process any written frames before reading new frames from the client since a\n\t\t\t// written frame could have triggered a new stream to be started.\n\t\t\tif sc.writingFrameAsync {\n\t\t\t\tselect {\n\t\t\t\tcase wroteRes := <-sc.wroteFrameCh:\n\t\t\t\t\tsc.wroteFrame(wroteRes)\n\t\t\t\tdefault:\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !sc.processFrameFromReader(res) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tres.readMore()\n\t\t\tif settingsTimer != nil {\n\t\t\t\tsettingsTimer.Stop()\n\t\t\t\tsettingsTimer = nil\n\t\t\t}\n\t\tcase m := <-sc.bodyReadCh:\n\t\t\tsc.noteBodyRead(m.st, m.n)\n\t\tcase msg := <-sc.serveMsgCh:\n\t\t\tswitch v := msg.(type) {\n\t\t\tcase func(int):\n\t\t\t\tv(loopNum) // for testing\n\t\t\tcase *serverMessage:\n\t\t\t\tswitch v {\n\t\t\t\tcase settingsTimerMsg:\n\t\t\t\t\tsc.logf(\"timeout waiting for SETTINGS frames from %v\", sc.conn.RemoteAddr())\n\t\t\t\t\treturn\n\t\t\t\tcase idleTimerMsg:\n\t\t\t\t\tsc.vlogf(\"connection is idle\")\n\t\t\t\t\tsc.goAway(ErrCodeNo)\n\t\t\t\tcase readIdleTimerMsg:\n\t\t\t\t\tsc.handlePingTimer(lastFrameTime)\n\t\t\t\tcase shutdownTimerMsg:\n\t\t\t\t\tsc.vlogf(\"GOAWAY close timer fired; closing conn from %v\", sc.conn.RemoteAddr())\n\t\t\t\t\treturn\n\t\t\t\tcase gracefulShutdownMsg:\n\t\t\t\t\tsc.startGracefulShutdownInternal()\n\t\t\t\tcase handlerDoneMsg:\n\t\t\t\t\tsc.handlerDone()\n\t\t\t\tdefault:\n\t\t\t\t\tpanic(\"unknown timer\")\n\t\t\t\t}\n\t\t\tcase *startPushRequest:\n\t\t\t\tsc.startPush(v)\n\t\t\tcase func(*serverConn):\n\t\t\t\tv(sc)\n\t\t\tdefault:\n\t\t\t\tpanic(fmt.Sprintf(\"unexpected type %T\", v))\n\t\t\t}\n\t\t}\n\n\t\t// If the peer is causing us to generate a lot of control frames,\n\t\t// but not reading them from us, assume they are trying to make us\n\t\t// run out of memory.\n\t\tif sc.queuedControlFrames > maxQueuedControlFrames {\n\t\t\tsc.vlogf(\"http2: too many control frames in send queue, closing connection\")\n\t\t\treturn\n\t\t}\n\n\t\t// Start the shutdown timer after sending a GOAWAY. When sending GOAWAY\n\t\t// with no error code (graceful shutdown), don't start the timer until\n\t\t// all open streams have been completed.\n\t\tsentGoAway := sc.inGoAway && !sc.needToSendGoAway && !sc.writingFrame\n\t\tgracefulShutdownComplete := sc.goAwayCode == ErrCodeNo && sc.curOpenStreams() == 0\n\t\tif sentGoAway && sc.shutdownTimer == nil && (sc.goAwayCode != ErrCodeNo || gracefulShutdownComplete) {\n\t\t\tsc.shutDownIn(goAwayTimeout)\n\t\t}\n\t}\n}\n\nfunc (sc *serverConn) handlePingTimer(lastFrameReadTime time.Time) {\n\tif sc.pingSent {\n\t\tsc.logf(\"timeout waiting for PING response\")\n\t\tif f := sc.countErrorFunc; f != nil {\n\t\t\tf(\"conn_close_lost_ping\")\n\t\t}\n\t\tsc.conn.Close()\n\t\treturn\n\t}\n\n\tpingAt := lastFrameReadTime.Add(sc.readIdleTimeout)\n\tnow := sc.srv.now()\n\tif pingAt.After(now) {\n\t\t// We received frames since arming the ping timer.\n\t\t// Reset it for the next possible timeout.\n\t\tsc.readIdleTimer.Reset(pingAt.Sub(now))\n\t\treturn\n\t}\n\n\tsc.pingSent = true\n\t// Ignore crypto/rand.Read errors: It generally can't fail, and worse case if it does\n\t// is we send a PING frame containing 0s.\n\t_, _ = rand.Read(sc.sentPingData[:])\n\tsc.writeFrame(FrameWriteRequest{\n\t\twrite: &writePing{data: sc.sentPingData},\n\t})\n\tsc.readIdleTimer.Reset(sc.pingTimeout)\n}\n\ntype serverMessage int\n\n// Message values sent to serveMsgCh.\nvar (\n\tsettingsTimerMsg    = new(serverMessage)\n\tidleTimerMsg        = new(serverMessage)\n\treadIdleTimerMsg    = new(serverMessage)\n\tshutdownTimerMsg    = new(serverMessage)\n\tgracefulShutdownMsg = new(serverMessage)\n\thandlerDoneMsg      = new(serverMessage)\n)\n\nfunc (sc *serverConn) onSettingsTimer() { sc.sendServeMsg(settingsTimerMsg) }\nfunc (sc *serverConn) onIdleTimer()     { sc.sendServeMsg(idleTimerMsg) }\nfunc (sc *serverConn) onReadIdleTimer() { sc.sendServeMsg(readIdleTimerMsg) }\nfunc (sc *serverConn) onShutdownTimer() { sc.sendServeMsg(shutdownTimerMsg) }\n\nfunc (sc *serverConn) sendServeMsg(msg interface{}) {\n\tsc.serveG.checkNotOn() // NOT\n\tselect {\n\tcase sc.serveMsgCh <- msg:\n\tcase <-sc.doneServing:\n\t}\n}\n\nvar errPrefaceTimeout = errors.New(\"timeout waiting for client preface\")\n\n// readPreface reads the ClientPreface greeting from the peer or\n// returns errPrefaceTimeout on timeout, or an error if the greeting\n// is invalid.\nfunc (sc *serverConn) readPreface() error {\n\tif sc.sawClientPreface {\n\t\treturn nil\n\t}\n\terrc := make(chan error, 1)\n\tgo func() {\n\t\t// Read the client preface\n\t\tbuf := make([]byte, len(ClientPreface))\n\t\tif _, err := io.ReadFull(sc.conn, buf); err != nil {\n\t\t\terrc <- err\n\t\t} else if !bytes.Equal(buf, clientPreface) {\n\t\t\terrc <- fmt.Errorf(\"bogus greeting %q\", buf)\n\t\t} else {\n\t\t\terrc <- nil\n\t\t}\n\t}()\n\ttimer := sc.srv.newTimer(prefaceTimeout) // TODO: configurable on *Server?\n\tdefer timer.Stop()\n\tselect {\n\tcase <-timer.C():\n\t\treturn errPrefaceTimeout\n\tcase err := <-errc:\n\t\tif err == nil {\n\t\t\tif VerboseLogs {\n\t\t\t\tsc.vlogf(\"http2: server: client %v said hello\", sc.conn.RemoteAddr())\n\t\t\t}\n\t\t}\n\t\treturn err\n\t}\n}\n\nvar errChanPool = sync.Pool{\n\tNew: func() interface{} { return make(chan error, 1) },\n}\n\nvar writeDataPool = sync.Pool{\n\tNew: func() interface{} { return new(writeData) },\n}\n\n// writeDataFromHandler writes DATA response frames from a handler on\n// the given stream.\nfunc (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStream bool) error {\n\tch := errChanPool.Get().(chan error)\n\twriteArg := writeDataPool.Get().(*writeData)\n\t*writeArg = writeData{stream.id, data, endStream}\n\terr := sc.writeFrameFromHandler(FrameWriteRequest{\n\t\twrite:  writeArg,\n\t\tstream: stream,\n\t\tdone:   ch,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar frameWriteDone bool // the frame write is done (successfully or not)\n\tselect {\n\tcase err = <-ch:\n\t\tframeWriteDone = true\n\tcase <-sc.doneServing:\n\t\treturn errClientDisconnected\n\tcase <-stream.cw:\n\t\t// If both ch and stream.cw were ready (as might\n\t\t// happen on the final Write after an http.Handler\n\t\t// ends), prefer the write result. Otherwise this\n\t\t// might just be us successfully closing the stream.\n\t\t// The writeFrameAsync and serve goroutines guarantee\n\t\t// that the ch send will happen before the stream.cw\n\t\t// close.\n\t\tselect {\n\t\tcase err = <-ch:\n\t\t\tframeWriteDone = true\n\t\tdefault:\n\t\t\treturn errStreamClosed\n\t\t}\n\t}\n\terrChanPool.Put(ch)\n\tif frameWriteDone {\n\t\twriteDataPool.Put(writeArg)\n\t}\n\treturn err\n}\n\n// writeFrameFromHandler sends wr to sc.wantWriteFrameCh, but aborts\n// if the connection has gone away.\n//\n// This must not be run from the serve goroutine itself, else it might\n// deadlock writing to sc.wantWriteFrameCh (which is only mildly\n// buffered and is read by serve itself). If you're on the serve\n// goroutine, call writeFrame instead.\nfunc (sc *serverConn) writeFrameFromHandler(wr FrameWriteRequest) error {\n\tsc.serveG.checkNotOn() // NOT\n\tselect {\n\tcase sc.wantWriteFrameCh <- wr:\n\t\treturn nil\n\tcase <-sc.doneServing:\n\t\t// Serve loop is gone.\n\t\t// Client has closed their connection to the server.\n\t\treturn errClientDisconnected\n\t}\n}\n\n// writeFrame schedules a frame to write and sends it if there's nothing\n// already being written.\n//\n// There is no pushback here (the serve goroutine never blocks). It's\n// the http.Handlers that block, waiting for their previous frames to\n// make it onto the wire\n//\n// If you're not on the serve goroutine, use writeFrameFromHandler instead.\nfunc (sc *serverConn) writeFrame(wr FrameWriteRequest) {\n\tsc.serveG.check()\n\n\t// If true, wr will not be written and wr.done will not be signaled.\n\tvar ignoreWrite bool\n\n\t// We are not allowed to write frames on closed streams. RFC 7540 Section\n\t// 5.1.1 says: \"An endpoint MUST NOT send frames other than PRIORITY on\n\t// a closed stream.\" Our server never sends PRIORITY, so that exception\n\t// does not apply.\n\t//\n\t// The serverConn might close an open stream while the stream's handler\n\t// is still running. For example, the server might close a stream when it\n\t// receives bad data from the client. If this happens, the handler might\n\t// attempt to write a frame after the stream has been closed (since the\n\t// handler hasn't yet been notified of the close). In this case, we simply\n\t// ignore the frame. The handler will notice that the stream is closed when\n\t// it waits for the frame to be written.\n\t//\n\t// As an exception to this rule, we allow sending RST_STREAM after close.\n\t// This allows us to immediately reject new streams without tracking any\n\t// state for those streams (except for the queued RST_STREAM frame). This\n\t// may result in duplicate RST_STREAMs in some cases, but the client should\n\t// ignore those.\n\tif wr.StreamID() != 0 {\n\t\t_, isReset := wr.write.(StreamError)\n\t\tif state, _ := sc.state(wr.StreamID()); state == stateClosed && !isReset {\n\t\t\tignoreWrite = true\n\t\t}\n\t}\n\n\t// Don't send a 100-continue response if we've already sent headers.\n\t// See golang.org/issue/14030.\n\tswitch wr.write.(type) {\n\tcase *writeResHeaders:\n\t\twr.stream.wroteHeaders = true\n\tcase write100ContinueHeadersFrame:\n\t\tif wr.stream.wroteHeaders {\n\t\t\t// We do not need to notify wr.done because this frame is\n\t\t\t// never written with wr.done != nil.\n\t\t\tif wr.done != nil {\n\t\t\t\tpanic(\"wr.done != nil for write100ContinueHeadersFrame\")\n\t\t\t}\n\t\t\tignoreWrite = true\n\t\t}\n\t}\n\n\tif !ignoreWrite {\n\t\tif wr.isControl() {\n\t\t\tsc.queuedControlFrames++\n\t\t\t// For extra safety, detect wraparounds, which should not happen,\n\t\t\t// and pull the plug.\n\t\t\tif sc.queuedControlFrames < 0 {\n\t\t\t\tsc.conn.Close()\n\t\t\t}\n\t\t}\n\t\tsc.writeSched.Push(wr)\n\t}\n\tsc.scheduleFrameWrite()\n}\n\n// startFrameWrite starts a goroutine to write wr (in a separate\n// goroutine since that might block on the network), and updates the\n// serve goroutine's state about the world, updated from info in wr.\nfunc (sc *serverConn) startFrameWrite(wr FrameWriteRequest) {\n\tsc.serveG.check()\n\tif sc.writingFrame {\n\t\tpanic(\"internal error: can only be writing one frame at a time\")\n\t}\n\n\tst := wr.stream\n\tif st != nil {\n\t\tswitch st.state {\n\t\tcase stateHalfClosedLocal:\n\t\t\tswitch wr.write.(type) {\n\t\t\tcase StreamError, handlerPanicRST, writeWindowUpdate:\n\t\t\t\t// RFC 7540 Section 5.1 allows sending RST_STREAM, PRIORITY, and WINDOW_UPDATE\n\t\t\t\t// in this state. (We never send PRIORITY from the server, so that is not checked.)\n\t\t\tdefault:\n\t\t\t\tpanic(fmt.Sprintf(\"internal error: attempt to send frame on a half-closed-local stream: %v\", wr))\n\t\t\t}\n\t\tcase stateClosed:\n\t\t\tpanic(fmt.Sprintf(\"internal error: attempt to send frame on a closed stream: %v\", wr))\n\t\t}\n\t}\n\tif wpp, ok := wr.write.(*writePushPromise); ok {\n\t\tvar err error\n\t\twpp.promisedID, err = wpp.allocatePromisedID()\n\t\tif err != nil {\n\t\t\tsc.writingFrameAsync = false\n\t\t\twr.replyToWriter(err)\n\t\t\treturn\n\t\t}\n\t}\n\n\tsc.writingFrame = true\n\tsc.needsFrameFlush = true\n\tif wr.write.staysWithinBuffer(sc.bw.Available()) {\n\t\tsc.writingFrameAsync = false\n\t\terr := wr.write.writeFrame(sc)\n\t\tsc.wroteFrame(frameWriteResult{wr: wr, err: err})\n\t} else if wd, ok := wr.write.(*writeData); ok {\n\t\t// Encode the frame in the serve goroutine, to ensure we don't have\n\t\t// any lingering asynchronous references to data passed to Write.\n\t\t// See https://go.dev/issue/58446.\n\t\tsc.framer.startWriteDataPadded(wd.streamID, wd.endStream, wd.p, nil)\n\t\tsc.writingFrameAsync = true\n\t\tgo sc.writeFrameAsync(wr, wd)\n\t} else {\n\t\tsc.writingFrameAsync = true\n\t\tgo sc.writeFrameAsync(wr, nil)\n\t}\n}\n\n// errHandlerPanicked is the error given to any callers blocked in a read from\n// Request.Body when the main goroutine panics. Since most handlers read in the\n// main ServeHTTP goroutine, this will show up rarely.\nvar errHandlerPanicked = errors.New(\"http2: handler panicked\")\n\n// wroteFrame is called on the serve goroutine with the result of\n// whatever happened on writeFrameAsync.\nfunc (sc *serverConn) wroteFrame(res frameWriteResult) {\n\tsc.serveG.check()\n\tif !sc.writingFrame {\n\t\tpanic(\"internal error: expected to be already writing a frame\")\n\t}\n\tsc.writingFrame = false\n\tsc.writingFrameAsync = false\n\n\tif res.err != nil {\n\t\tsc.conn.Close()\n\t}\n\n\twr := res.wr\n\n\tif writeEndsStream(wr.write) {\n\t\tst := wr.stream\n\t\tif st == nil {\n\t\t\tpanic(\"internal error: expecting non-nil stream\")\n\t\t}\n\t\tswitch st.state {\n\t\tcase stateOpen:\n\t\t\t// Here we would go to stateHalfClosedLocal in\n\t\t\t// theory, but since our handler is done and\n\t\t\t// the net/http package provides no mechanism\n\t\t\t// for closing a ResponseWriter while still\n\t\t\t// reading data (see possible TODO at top of\n\t\t\t// this file), we go into closed state here\n\t\t\t// anyway, after telling the peer we're\n\t\t\t// hanging up on them. We'll transition to\n\t\t\t// stateClosed after the RST_STREAM frame is\n\t\t\t// written.\n\t\t\tst.state = stateHalfClosedLocal\n\t\t\t// Section 8.1: a server MAY request that the client abort\n\t\t\t// transmission of a request without error by sending a\n\t\t\t// RST_STREAM with an error code of NO_ERROR after sending\n\t\t\t// a complete response.\n\t\t\tsc.resetStream(streamError(st.id, ErrCodeNo))\n\t\tcase stateHalfClosedRemote:\n\t\t\tsc.closeStream(st, errHandlerComplete)\n\t\t}\n\t} else {\n\t\tswitch v := wr.write.(type) {\n\t\tcase StreamError:\n\t\t\t// st may be unknown if the RST_STREAM was generated to reject bad input.\n\t\t\tif st, ok := sc.streams[v.StreamID]; ok {\n\t\t\t\tsc.closeStream(st, v)\n\t\t\t}\n\t\tcase handlerPanicRST:\n\t\t\tsc.closeStream(wr.stream, errHandlerPanicked)\n\t\t}\n\t}\n\n\t// Reply (if requested) to unblock the ServeHTTP goroutine.\n\twr.replyToWriter(res.err)\n\n\tsc.scheduleFrameWrite()\n}\n\n// scheduleFrameWrite tickles the frame writing scheduler.\n//\n// If a frame is already being written, nothing happens. This will be called again\n// when the frame is done being written.\n//\n// If a frame isn't being written and we need to send one, the best frame\n// to send is selected by writeSched.\n//\n// If a frame isn't being written and there's nothing else to send, we\n// flush the write buffer.\nfunc (sc *serverConn) scheduleFrameWrite() {\n\tsc.serveG.check()\n\tif sc.writingFrame || sc.inFrameScheduleLoop {\n\t\treturn\n\t}\n\tsc.inFrameScheduleLoop = true\n\tfor !sc.writingFrameAsync {\n\t\tif sc.needToSendGoAway {\n\t\t\tsc.needToSendGoAway = false\n\t\t\tsc.startFrameWrite(FrameWriteRequest{\n\t\t\t\twrite: &writeGoAway{\n\t\t\t\t\tmaxStreamID: sc.maxClientStreamID,\n\t\t\t\t\tcode:        sc.goAwayCode,\n\t\t\t\t},\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\t\tif sc.needToSendSettingsAck {\n\t\t\tsc.needToSendSettingsAck = false\n\t\t\tsc.startFrameWrite(FrameWriteRequest{write: writeSettingsAck{}})\n\t\t\tcontinue\n\t\t}\n\t\tif !sc.inGoAway || sc.goAwayCode == ErrCodeNo {\n\t\t\tif wr, ok := sc.writeSched.Pop(); ok {\n\t\t\t\tif wr.isControl() {\n\t\t\t\t\tsc.queuedControlFrames--\n\t\t\t\t}\n\t\t\t\tsc.startFrameWrite(wr)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tif sc.needsFrameFlush {\n\t\t\tsc.startFrameWrite(FrameWriteRequest{write: flushFrameWriter{}})\n\t\t\tsc.needsFrameFlush = false // after startFrameWrite, since it sets this true\n\t\t\tcontinue\n\t\t}\n\t\tbreak\n\t}\n\tsc.inFrameScheduleLoop = false\n}\n\n// startGracefulShutdown gracefully shuts down a connection. This\n// sends GOAWAY with ErrCodeNo to tell the client we're gracefully\n// shutting down. The connection isn't closed until all current\n// streams are done.\n//\n// startGracefulShutdown returns immediately; it does not wait until\n// the connection has shut down.\nfunc (sc *serverConn) startGracefulShutdown() {\n\tsc.serveG.checkNotOn() // NOT\n\tsc.shutdownOnce.Do(func() { sc.sendServeMsg(gracefulShutdownMsg) })\n}\n\n// After sending GOAWAY with an error code (non-graceful shutdown), the\n// connection will close after goAwayTimeout.\n//\n// If we close the connection immediately after sending GOAWAY, there may\n// be unsent data in our kernel receive buffer, which will cause the kernel\n// to send a TCP RST on close() instead of a FIN. This RST will abort the\n// connection immediately, whether or not the client had received the GOAWAY.\n//\n// Ideally we should delay for at least 1 RTT + epsilon so the client has\n// a chance to read the GOAWAY and stop sending messages. Measuring RTT\n// is hard, so we approximate with 1 second. See golang.org/issue/18701.\n//\n// This is a var so it can be shorter in tests, where all requests uses the\n// loopback interface making the expected RTT very small.\n//\n// TODO: configurable?\nvar goAwayTimeout = 1 * time.Second\n\nfunc (sc *serverConn) startGracefulShutdownInternal() {\n\tsc.goAway(ErrCodeNo)\n}\n\nfunc (sc *serverConn) goAway(code ErrCode) {\n\tsc.serveG.check()\n\tif sc.inGoAway {\n\t\tif sc.goAwayCode == ErrCodeNo {\n\t\t\tsc.goAwayCode = code\n\t\t}\n\t\treturn\n\t}\n\tsc.inGoAway = true\n\tsc.needToSendGoAway = true\n\tsc.goAwayCode = code\n\tsc.scheduleFrameWrite()\n}\n\nfunc (sc *serverConn) shutDownIn(d time.Duration) {\n\tsc.serveG.check()\n\tsc.shutdownTimer = sc.srv.afterFunc(d, sc.onShutdownTimer)\n}\n\nfunc (sc *serverConn) resetStream(se StreamError) {\n\tsc.serveG.check()\n\tsc.writeFrame(FrameWriteRequest{write: se})\n\tif st, ok := sc.streams[se.StreamID]; ok {\n\t\tst.resetQueued = true\n\t}\n}\n\n// processFrameFromReader processes the serve loop's read from readFrameCh from the\n// frame-reading goroutine.\n// processFrameFromReader returns whether the connection should be kept open.\nfunc (sc *serverConn) processFrameFromReader(res readFrameResult) bool {\n\tsc.serveG.check()\n\terr := res.err\n\tif err != nil {\n\t\tif err == ErrFrameTooLarge {\n\t\t\tsc.goAway(ErrCodeFrameSize)\n\t\t\treturn true // goAway will close the loop\n\t\t}\n\t\tclientGone := err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err)\n\t\tif clientGone {\n\t\t\t// TODO: could we also get into this state if\n\t\t\t// the peer does a half close\n\t\t\t// (e.g. CloseWrite) because they're done\n\t\t\t// sending frames but they're still wanting\n\t\t\t// our open replies?  Investigate.\n\t\t\t// TODO: add CloseWrite to crypto/tls.Conn first\n\t\t\t// so we have a way to test this? I suppose\n\t\t\t// just for testing we could have a non-TLS mode.\n\t\t\treturn false\n\t\t}\n\t} else {\n\t\tf := res.f\n\t\tif VerboseLogs {\n\t\t\tsc.vlogf(\"http2: server read frame %v\", summarizeFrame(f))\n\t\t}\n\t\terr = sc.processFrame(f)\n\t\tif err == nil {\n\t\t\treturn true\n\t\t}\n\t}\n\n\tswitch ev := err.(type) {\n\tcase StreamError:\n\t\tsc.resetStream(ev)\n\t\treturn true\n\tcase goAwayFlowError:\n\t\tsc.goAway(ErrCodeFlowControl)\n\t\treturn true\n\tcase ConnectionError:\n\t\tif res.f != nil {\n\t\t\tif id := res.f.Header().StreamID; id > sc.maxClientStreamID {\n\t\t\t\tsc.maxClientStreamID = id\n\t\t\t}\n\t\t}\n\t\tsc.logf(\"http2: server connection error from %v: %v\", sc.conn.RemoteAddr(), ev)\n\t\tsc.goAway(ErrCode(ev))\n\t\treturn true // goAway will handle shutdown\n\tdefault:\n\t\tif res.err != nil {\n\t\t\tsc.vlogf(\"http2: server closing client connection; error reading frame from client %s: %v\", sc.conn.RemoteAddr(), err)\n\t\t} else {\n\t\t\tsc.logf(\"http2: server closing client connection: %v\", err)\n\t\t}\n\t\treturn false\n\t}\n}\n\nfunc (sc *serverConn) processFrame(f Frame) error {\n\tsc.serveG.check()\n\n\t// First frame received must be SETTINGS.\n\tif !sc.sawFirstSettings {\n\t\tif _, ok := f.(*SettingsFrame); !ok {\n\t\t\treturn sc.countError(\"first_settings\", ConnectionError(ErrCodeProtocol))\n\t\t}\n\t\tsc.sawFirstSettings = true\n\t}\n\n\t// Discard frames for streams initiated after the identified last\n\t// stream sent in a GOAWAY, or all frames after sending an error.\n\t// We still need to return connection-level flow control for DATA frames.\n\t// RFC 9113 Section 6.8.\n\tif sc.inGoAway && (sc.goAwayCode != ErrCodeNo || f.Header().StreamID > sc.maxClientStreamID) {\n\n\t\tif f, ok := f.(*DataFrame); ok {\n\t\t\tif !sc.inflow.take(f.Length) {\n\t\t\t\treturn sc.countError(\"data_flow\", streamError(f.Header().StreamID, ErrCodeFlowControl))\n\t\t\t}\n\t\t\tsc.sendWindowUpdate(nil, int(f.Length)) // conn-level\n\t\t}\n\t\treturn nil\n\t}\n\n\tswitch f := f.(type) {\n\tcase *SettingsFrame:\n\t\treturn sc.processSettings(f)\n\tcase *MetaHeadersFrame:\n\t\treturn sc.processHeaders(f)\n\tcase *WindowUpdateFrame:\n\t\treturn sc.processWindowUpdate(f)\n\tcase *PingFrame:\n\t\treturn sc.processPing(f)\n\tcase *DataFrame:\n\t\treturn sc.processData(f)\n\tcase *RSTStreamFrame:\n\t\treturn sc.processResetStream(f)\n\tcase *PriorityFrame:\n\t\treturn sc.processPriority(f)\n\tcase *GoAwayFrame:\n\t\treturn sc.processGoAway(f)\n\tcase *PushPromiseFrame:\n\t\t// A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE\n\t\t// frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.\n\t\treturn sc.countError(\"push_promise\", ConnectionError(ErrCodeProtocol))\n\tdefault:\n\t\tsc.vlogf(\"http2: server ignoring frame: %v\", f.Header())\n\t\treturn nil\n\t}\n}\n\nfunc (sc *serverConn) processPing(f *PingFrame) error {\n\tsc.serveG.check()\n\tif f.IsAck() {\n\t\tif sc.pingSent && sc.sentPingData == f.Data {\n\t\t\t// This is a response to a PING we sent.\n\t\t\tsc.pingSent = false\n\t\t\tsc.readIdleTimer.Reset(sc.readIdleTimeout)\n\t\t}\n\t\t// 6.7 PING: \" An endpoint MUST NOT respond to PING frames\n\t\t// containing this flag.\"\n\t\treturn nil\n\t}\n\tif f.StreamID != 0 {\n\t\t// \"PING frames are not associated with any individual\n\t\t// stream. If a PING frame is received with a stream\n\t\t// identifier field value other than 0x0, the recipient MUST\n\t\t// respond with a connection error (Section 5.4.1) of type\n\t\t// PROTOCOL_ERROR.\"\n\t\treturn sc.countError(\"ping_on_stream\", ConnectionError(ErrCodeProtocol))\n\t}\n\tsc.writeFrame(FrameWriteRequest{write: writePingAck{f}})\n\treturn nil\n}\n\nfunc (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error {\n\tsc.serveG.check()\n\tswitch {\n\tcase f.StreamID != 0: // stream-level flow control\n\t\tstate, st := sc.state(f.StreamID)\n\t\tif state == stateIdle {\n\t\t\t// Section 5.1: \"Receiving any frame other than HEADERS\n\t\t\t// or PRIORITY on a stream in this state MUST be\n\t\t\t// treated as a connection error (Section 5.4.1) of\n\t\t\t// type PROTOCOL_ERROR.\"\n\t\t\treturn sc.countError(\"stream_idle\", ConnectionError(ErrCodeProtocol))\n\t\t}\n\t\tif st == nil {\n\t\t\t// \"WINDOW_UPDATE can be sent by a peer that has sent a\n\t\t\t// frame bearing the END_STREAM flag. This means that a\n\t\t\t// receiver could receive a WINDOW_UPDATE frame on a \"half\n\t\t\t// closed (remote)\" or \"closed\" stream. A receiver MUST\n\t\t\t// NOT treat this as an error, see Section 5.1.\"\n\t\t\treturn nil\n\t\t}\n\t\tif !st.flow.add(int32(f.Increment)) {\n\t\t\treturn sc.countError(\"bad_flow\", streamError(f.StreamID, ErrCodeFlowControl))\n\t\t}\n\tdefault: // connection-level flow control\n\t\tif !sc.flow.add(int32(f.Increment)) {\n\t\t\treturn goAwayFlowError{}\n\t\t}\n\t}\n\tsc.scheduleFrameWrite()\n\treturn nil\n}\n\nfunc (sc *serverConn) processResetStream(f *RSTStreamFrame) error {\n\tsc.serveG.check()\n\n\tstate, st := sc.state(f.StreamID)\n\tif state == stateIdle {\n\t\t// 6.4 \"RST_STREAM frames MUST NOT be sent for a\n\t\t// stream in the \"idle\" state. If a RST_STREAM frame\n\t\t// identifying an idle stream is received, the\n\t\t// recipient MUST treat this as a connection error\n\t\t// (Section 5.4.1) of type PROTOCOL_ERROR.\n\t\treturn sc.countError(\"reset_idle_stream\", ConnectionError(ErrCodeProtocol))\n\t}\n\tif st != nil {\n\t\tst.cancelCtx()\n\t\tsc.closeStream(st, streamError(f.StreamID, f.ErrCode))\n\t}\n\treturn nil\n}\n\nfunc (sc *serverConn) closeStream(st *stream, err error) {\n\tsc.serveG.check()\n\tif st.state == stateIdle || st.state == stateClosed {\n\t\tpanic(fmt.Sprintf(\"invariant; can't close stream in state %v\", st.state))\n\t}\n\tst.state = stateClosed\n\tif st.readDeadline != nil {\n\t\tst.readDeadline.Stop()\n\t}\n\tif st.writeDeadline != nil {\n\t\tst.writeDeadline.Stop()\n\t}\n\tif st.isPushed() {\n\t\tsc.curPushedStreams--\n\t} else {\n\t\tsc.curClientStreams--\n\t}\n\tdelete(sc.streams, st.id)\n\tif len(sc.streams) == 0 {\n\t\tsc.setConnState(http.StateIdle)\n\t\tif sc.srv.IdleTimeout > 0 && sc.idleTimer != nil {\n\t\t\tsc.idleTimer.Reset(sc.srv.IdleTimeout)\n\t\t}\n\t\tif h1ServerKeepAlivesDisabled(sc.hs) {\n\t\t\tsc.startGracefulShutdownInternal()\n\t\t}\n\t}\n\tif p := st.body; p != nil {\n\t\t// Return any buffered unread bytes worth of conn-level flow control.\n\t\t// See golang.org/issue/16481\n\t\tsc.sendWindowUpdate(nil, p.Len())\n\n\t\tp.CloseWithError(err)\n\t}\n\tif e, ok := err.(StreamError); ok {\n\t\tif e.Cause != nil {\n\t\t\terr = e.Cause\n\t\t} else {\n\t\t\terr = errStreamClosed\n\t\t}\n\t}\n\tst.closeErr = err\n\tst.cancelCtx()\n\tst.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc\n\tsc.writeSched.CloseStream(st.id)\n}\n\nfunc (sc *serverConn) processSettings(f *SettingsFrame) error {\n\tsc.serveG.check()\n\tif f.IsAck() {\n\t\tsc.unackedSettings--\n\t\tif sc.unackedSettings < 0 {\n\t\t\t// Why is the peer ACKing settings we never sent?\n\t\t\t// The spec doesn't mention this case, but\n\t\t\t// hang up on them anyway.\n\t\t\treturn sc.countError(\"ack_mystery\", ConnectionError(ErrCodeProtocol))\n\t\t}\n\t\treturn nil\n\t}\n\tif f.NumSettings() > 100 || f.HasDuplicates() {\n\t\t// This isn't actually in the spec, but hang up on\n\t\t// suspiciously large settings frames or those with\n\t\t// duplicate entries.\n\t\treturn sc.countError(\"settings_big_or_dups\", ConnectionError(ErrCodeProtocol))\n\t}\n\tif err := f.ForeachSetting(sc.processSetting); err != nil {\n\t\treturn err\n\t}\n\t// TODO: judging by RFC 7540, Section 6.5.3 each SETTINGS frame should be\n\t// acknowledged individually, even if multiple are received before the ACK.\n\tsc.needToSendSettingsAck = true\n\tsc.scheduleFrameWrite()\n\treturn nil\n}\n\nfunc (sc *serverConn) processSetting(s Setting) error {\n\tsc.serveG.check()\n\tif err := s.Valid(); err != nil {\n\t\treturn err\n\t}\n\tif VerboseLogs {\n\t\tsc.vlogf(\"http2: server processing setting %v\", s)\n\t}\n\tswitch s.ID {\n\tcase SettingHeaderTableSize:\n\t\tsc.hpackEncoder.SetMaxDynamicTableSize(s.Val)\n\tcase SettingEnablePush:\n\t\tsc.pushEnabled = s.Val != 0\n\tcase SettingMaxConcurrentStreams:\n\t\tsc.clientMaxStreams = s.Val\n\tcase SettingInitialWindowSize:\n\t\treturn sc.processSettingInitialWindowSize(s.Val)\n\tcase SettingMaxFrameSize:\n\t\tsc.maxFrameSize = int32(s.Val) // the maximum valid s.Val is < 2^31\n\tcase SettingMaxHeaderListSize:\n\t\tsc.peerMaxHeaderListSize = s.Val\n\tcase SettingEnableConnectProtocol:\n\t\t// Receipt of this parameter by a server does not\n\t\t// have any impact\n\tdefault:\n\t\t// Unknown setting: \"An endpoint that receives a SETTINGS\n\t\t// frame with any unknown or unsupported identifier MUST\n\t\t// ignore that setting.\"\n\t\tif VerboseLogs {\n\t\t\tsc.vlogf(\"http2: server ignoring unknown setting %v\", s)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (sc *serverConn) processSettingInitialWindowSize(val uint32) error {\n\tsc.serveG.check()\n\t// Note: val already validated to be within range by\n\t// processSetting's Valid call.\n\n\t// \"A SETTINGS frame can alter the initial flow control window\n\t// size for all current streams. When the value of\n\t// SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST\n\t// adjust the size of all stream flow control windows that it\n\t// maintains by the difference between the new value and the\n\t// old value.\"\n\told := sc.initialStreamSendWindowSize\n\tsc.initialStreamSendWindowSize = int32(val)\n\tgrowth := int32(val) - old // may be negative\n\tfor _, st := range sc.streams {\n\t\tif !st.flow.add(growth) {\n\t\t\t// 6.9.2 Initial Flow Control Window Size\n\t\t\t// \"An endpoint MUST treat a change to\n\t\t\t// SETTINGS_INITIAL_WINDOW_SIZE that causes any flow\n\t\t\t// control window to exceed the maximum size as a\n\t\t\t// connection error (Section 5.4.1) of type\n\t\t\t// FLOW_CONTROL_ERROR.\"\n\t\t\treturn sc.countError(\"setting_win_size\", ConnectionError(ErrCodeFlowControl))\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (sc *serverConn) processData(f *DataFrame) error {\n\tsc.serveG.check()\n\tid := f.Header().StreamID\n\n\tdata := f.Data()\n\tstate, st := sc.state(id)\n\tif id == 0 || state == stateIdle {\n\t\t// Section 6.1: \"DATA frames MUST be associated with a\n\t\t// stream. If a DATA frame is received whose stream\n\t\t// identifier field is 0x0, the recipient MUST respond\n\t\t// with a connection error (Section 5.4.1) of type\n\t\t// PROTOCOL_ERROR.\"\n\t\t//\n\t\t// Section 5.1: \"Receiving any frame other than HEADERS\n\t\t// or PRIORITY on a stream in this state MUST be\n\t\t// treated as a connection error (Section 5.4.1) of\n\t\t// type PROTOCOL_ERROR.\"\n\t\treturn sc.countError(\"data_on_idle\", ConnectionError(ErrCodeProtocol))\n\t}\n\n\t// \"If a DATA frame is received whose stream is not in \"open\"\n\t// or \"half closed (local)\" state, the recipient MUST respond\n\t// with a stream error (Section 5.4.2) of type STREAM_CLOSED.\"\n\tif st == nil || state != stateOpen || st.gotTrailerHeader || st.resetQueued {\n\t\t// This includes sending a RST_STREAM if the stream is\n\t\t// in stateHalfClosedLocal (which currently means that\n\t\t// the http.Handler returned, so it's done reading &\n\t\t// done writing). Try to stop the client from sending\n\t\t// more DATA.\n\n\t\t// But still enforce their connection-level flow control,\n\t\t// and return any flow control bytes since we're not going\n\t\t// to consume them.\n\t\tif !sc.inflow.take(f.Length) {\n\t\t\treturn sc.countError(\"data_flow\", streamError(id, ErrCodeFlowControl))\n\t\t}\n\t\tsc.sendWindowUpdate(nil, int(f.Length)) // conn-level\n\n\t\tif st != nil && st.resetQueued {\n\t\t\t// Already have a stream error in flight. Don't send another.\n\t\t\treturn nil\n\t\t}\n\t\treturn sc.countError(\"closed\", streamError(id, ErrCodeStreamClosed))\n\t}\n\tif st.body == nil {\n\t\tpanic(\"internal error: should have a body in this state\")\n\t}\n\n\t// Sender sending more than they'd declared?\n\tif st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {\n\t\tif !sc.inflow.take(f.Length) {\n\t\t\treturn sc.countError(\"data_flow\", streamError(id, ErrCodeFlowControl))\n\t\t}\n\t\tsc.sendWindowUpdate(nil, int(f.Length)) // conn-level\n\n\t\tst.body.CloseWithError(fmt.Errorf(\"sender tried to send more than declared Content-Length of %d bytes\", st.declBodyBytes))\n\t\t// RFC 7540, sec 8.1.2.6: A request or response is also malformed if the\n\t\t// value of a content-length header field does not equal the sum of the\n\t\t// DATA frame payload lengths that form the body.\n\t\treturn sc.countError(\"send_too_much\", streamError(id, ErrCodeProtocol))\n\t}\n\tif f.Length > 0 {\n\t\t// Check whether the client has flow control quota.\n\t\tif !takeInflows(&sc.inflow, &st.inflow, f.Length) {\n\t\t\treturn sc.countError(\"flow_on_data_length\", streamError(id, ErrCodeFlowControl))\n\t\t}\n\n\t\tif len(data) > 0 {\n\t\t\tst.bodyBytes += int64(len(data))\n\t\t\twrote, err := st.body.Write(data)\n\t\t\tif err != nil {\n\t\t\t\t// The handler has closed the request body.\n\t\t\t\t// Return the connection-level flow control for the discarded data,\n\t\t\t\t// but not the stream-level flow control.\n\t\t\t\tsc.sendWindowUpdate(nil, int(f.Length)-wrote)\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tif wrote != len(data) {\n\t\t\t\tpanic(\"internal error: bad Writer\")\n\t\t\t}\n\t\t}\n\n\t\t// Return any padded flow control now, since we won't\n\t\t// refund it later on body reads.\n\t\t// Call sendWindowUpdate even if there is no padding,\n\t\t// to return buffered flow control credit if the sent\n\t\t// window has shrunk.\n\t\tpad := int32(f.Length) - int32(len(data))\n\t\tsc.sendWindowUpdate32(nil, pad)\n\t\tsc.sendWindowUpdate32(st, pad)\n\t}\n\tif f.StreamEnded() {\n\t\tst.endStream()\n\t}\n\treturn nil\n}\n\nfunc (sc *serverConn) processGoAway(f *GoAwayFrame) error {\n\tsc.serveG.check()\n\tif f.ErrCode != ErrCodeNo {\n\t\tsc.logf(\"http2: received GOAWAY %+v, starting graceful shutdown\", f)\n\t} else {\n\t\tsc.vlogf(\"http2: received GOAWAY %+v, starting graceful shutdown\", f)\n\t}\n\tsc.startGracefulShutdownInternal()\n\t// http://tools.ietf.org/html/rfc7540#section-6.8\n\t// We should not create any new streams, which means we should disable push.\n\tsc.pushEnabled = false\n\treturn nil\n}\n\n// isPushed reports whether the stream is server-initiated.\nfunc (st *stream) isPushed() bool {\n\treturn st.id%2 == 0\n}\n\n// endStream closes a Request.Body's pipe. It is called when a DATA\n// frame says a request body is over (or after trailers).\nfunc (st *stream) endStream() {\n\tsc := st.sc\n\tsc.serveG.check()\n\n\tif st.declBodyBytes != -1 && st.declBodyBytes != st.bodyBytes {\n\t\tst.body.CloseWithError(fmt.Errorf(\"request declared a Content-Length of %d but only wrote %d bytes\",\n\t\t\tst.declBodyBytes, st.bodyBytes))\n\t} else {\n\t\tst.body.closeWithErrorAndCode(io.EOF, st.copyTrailersToHandlerRequest)\n\t\tst.body.CloseWithError(io.EOF)\n\t}\n\tst.state = stateHalfClosedRemote\n}\n\n// copyTrailersToHandlerRequest is run in the Handler's goroutine in\n// its Request.Body.Read just before it gets io.EOF.\nfunc (st *stream) copyTrailersToHandlerRequest() {\n\tfor k, vv := range st.trailer {\n\t\tif _, ok := st.reqTrailer[k]; ok {\n\t\t\t// Only copy it over it was pre-declared.\n\t\t\tst.reqTrailer[k] = vv\n\t\t}\n\t}\n}\n\n// onReadTimeout is run on its own goroutine (from time.AfterFunc)\n// when the stream's ReadTimeout has fired.\nfunc (st *stream) onReadTimeout() {\n\tif st.body != nil {\n\t\t// Wrap the ErrDeadlineExceeded to avoid callers depending on us\n\t\t// returning the bare error.\n\t\tst.body.CloseWithError(fmt.Errorf(\"%w\", os.ErrDeadlineExceeded))\n\t}\n}\n\n// onWriteTimeout is run on its own goroutine (from time.AfterFunc)\n// when the stream's WriteTimeout has fired.\nfunc (st *stream) onWriteTimeout() {\n\tst.sc.writeFrameFromHandler(FrameWriteRequest{write: StreamError{\n\t\tStreamID: st.id,\n\t\tCode:     ErrCodeInternal,\n\t\tCause:    os.ErrDeadlineExceeded,\n\t}})\n}\n\nfunc (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {\n\tsc.serveG.check()\n\tid := f.StreamID\n\t// http://tools.ietf.org/html/rfc7540#section-5.1.1\n\t// Streams initiated by a client MUST use odd-numbered stream\n\t// identifiers. [...] An endpoint that receives an unexpected\n\t// stream identifier MUST respond with a connection error\n\t// (Section 5.4.1) of type PROTOCOL_ERROR.\n\tif id%2 != 1 {\n\t\treturn sc.countError(\"headers_even\", ConnectionError(ErrCodeProtocol))\n\t}\n\t// A HEADERS frame can be used to create a new stream or\n\t// send a trailer for an open one. If we already have a stream\n\t// open, let it process its own HEADERS frame (trailers at this\n\t// point, if it's valid).\n\tif st := sc.streams[f.StreamID]; st != nil {\n\t\tif st.resetQueued {\n\t\t\t// We're sending RST_STREAM to close the stream, so don't bother\n\t\t\t// processing this frame.\n\t\t\treturn nil\n\t\t}\n\t\t// RFC 7540, sec 5.1: If an endpoint receives additional frames, other than\n\t\t// WINDOW_UPDATE, PRIORITY, or RST_STREAM, for a stream that is in\n\t\t// this state, it MUST respond with a stream error (Section 5.4.2) of\n\t\t// type STREAM_CLOSED.\n\t\tif st.state == stateHalfClosedRemote {\n\t\t\treturn sc.countError(\"headers_half_closed\", streamError(id, ErrCodeStreamClosed))\n\t\t}\n\t\treturn st.processTrailerHeaders(f)\n\t}\n\n\t// [...] The identifier of a newly established stream MUST be\n\t// numerically greater than all streams that the initiating\n\t// endpoint has opened or reserved. [...]  An endpoint that\n\t// receives an unexpected stream identifier MUST respond with\n\t// a connection error (Section 5.4.1) of type PROTOCOL_ERROR.\n\tif id <= sc.maxClientStreamID {\n\t\treturn sc.countError(\"stream_went_down\", ConnectionError(ErrCodeProtocol))\n\t}\n\tsc.maxClientStreamID = id\n\n\tif sc.idleTimer != nil {\n\t\tsc.idleTimer.Stop()\n\t}\n\n\t// http://tools.ietf.org/html/rfc7540#section-5.1.2\n\t// [...] Endpoints MUST NOT exceed the limit set by their peer. An\n\t// endpoint that receives a HEADERS frame that causes their\n\t// advertised concurrent stream limit to be exceeded MUST treat\n\t// this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR\n\t// or REFUSED_STREAM.\n\tif sc.curClientStreams+1 > sc.advMaxStreams {\n\t\tif sc.unackedSettings == 0 {\n\t\t\t// They should know better.\n\t\t\treturn sc.countError(\"over_max_streams\", streamError(id, ErrCodeProtocol))\n\t\t}\n\t\t// Assume it's a network race, where they just haven't\n\t\t// received our last SETTINGS update. But actually\n\t\t// this can't happen yet, because we don't yet provide\n\t\t// a way for users to adjust server parameters at\n\t\t// runtime.\n\t\treturn sc.countError(\"over_max_streams_race\", streamError(id, ErrCodeRefusedStream))\n\t}\n\n\tinitialState := stateOpen\n\tif f.StreamEnded() {\n\t\tinitialState = stateHalfClosedRemote\n\t}\n\tst := sc.newStream(id, 0, initialState)\n\n\tif f.HasPriority() {\n\t\tif err := sc.checkPriority(f.StreamID, f.Priority); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tsc.writeSched.AdjustStream(st.id, f.Priority)\n\t}\n\n\trw, req, err := sc.newWriterAndRequest(st, f)\n\tif err != nil {\n\t\treturn err\n\t}\n\tst.reqTrailer = req.Trailer\n\tif st.reqTrailer != nil {\n\t\tst.trailer = make(http.Header)\n\t}\n\tst.body = req.Body.(*requestBody).pipe // may be nil\n\tst.declBodyBytes = req.ContentLength\n\n\thandler := sc.handler.ServeHTTP\n\tif f.Truncated {\n\t\t// Their header list was too long. Send a 431 error.\n\t\thandler = handleHeaderListTooLong\n\t} else if err := checkValidHTTP2RequestHeaders(req.Header); err != nil {\n\t\thandler = new400Handler(err)\n\t}\n\n\t// The net/http package sets the read deadline from the\n\t// http.Server.ReadTimeout during the TLS handshake, but then\n\t// passes the connection off to us with the deadline already\n\t// set. Disarm it here after the request headers are read,\n\t// similar to how the http1 server works. Here it's\n\t// technically more like the http1 Server's ReadHeaderTimeout\n\t// (in Go 1.8), though. That's a more sane option anyway.\n\tif sc.hs.ReadTimeout > 0 {\n\t\tsc.conn.SetReadDeadline(time.Time{})\n\t\tst.readDeadline = sc.srv.afterFunc(sc.hs.ReadTimeout, st.onReadTimeout)\n\t}\n\n\treturn sc.scheduleHandler(id, rw, req, handler)\n}\n\nfunc (sc *serverConn) upgradeRequest(req *http.Request) {\n\tsc.serveG.check()\n\tid := uint32(1)\n\tsc.maxClientStreamID = id\n\tst := sc.newStream(id, 0, stateHalfClosedRemote)\n\tst.reqTrailer = req.Trailer\n\tif st.reqTrailer != nil {\n\t\tst.trailer = make(http.Header)\n\t}\n\trw := sc.newResponseWriter(st, req)\n\n\t// Disable any read deadline set by the net/http package\n\t// prior to the upgrade.\n\tif sc.hs.ReadTimeout > 0 {\n\t\tsc.conn.SetReadDeadline(time.Time{})\n\t}\n\n\t// This is the first request on the connection,\n\t// so start the handler directly rather than going\n\t// through scheduleHandler.\n\tsc.curHandlers++\n\tgo sc.runHandler(rw, req, sc.handler.ServeHTTP)\n}\n\nfunc (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error {\n\tsc := st.sc\n\tsc.serveG.check()\n\tif st.gotTrailerHeader {\n\t\treturn sc.countError(\"dup_trailers\", ConnectionError(ErrCodeProtocol))\n\t}\n\tst.gotTrailerHeader = true\n\tif !f.StreamEnded() {\n\t\treturn sc.countError(\"trailers_not_ended\", streamError(st.id, ErrCodeProtocol))\n\t}\n\n\tif len(f.PseudoFields()) > 0 {\n\t\treturn sc.countError(\"trailers_pseudo\", streamError(st.id, ErrCodeProtocol))\n\t}\n\tif st.trailer != nil {\n\t\tfor _, hf := range f.RegularFields() {\n\t\t\tkey := sc.canonicalHeader(hf.Name)\n\t\t\tif !httpguts.ValidTrailerHeader(key) {\n\t\t\t\t// TODO: send more details to the peer somehow. But http2 has\n\t\t\t\t// no way to send debug data at a stream level. Discuss with\n\t\t\t\t// HTTP folk.\n\t\t\t\treturn sc.countError(\"trailers_bogus\", streamError(st.id, ErrCodeProtocol))\n\t\t\t}\n\t\t\tst.trailer[key] = append(st.trailer[key], hf.Value)\n\t\t}\n\t}\n\tst.endStream()\n\treturn nil\n}\n\nfunc (sc *serverConn) checkPriority(streamID uint32, p PriorityParam) error {\n\tif streamID == p.StreamDep {\n\t\t// Section 5.3.1: \"A stream cannot depend on itself. An endpoint MUST treat\n\t\t// this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR.\"\n\t\t// Section 5.3.3 says that a stream can depend on one of its dependencies,\n\t\t// so it's only self-dependencies that are forbidden.\n\t\treturn sc.countError(\"priority\", streamError(streamID, ErrCodeProtocol))\n\t}\n\treturn nil\n}\n\nfunc (sc *serverConn) processPriority(f *PriorityFrame) error {\n\tif err := sc.checkPriority(f.StreamID, f.PriorityParam); err != nil {\n\t\treturn err\n\t}\n\tsc.writeSched.AdjustStream(f.StreamID, f.PriorityParam)\n\treturn nil\n}\n\nfunc (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream {\n\tsc.serveG.check()\n\tif id == 0 {\n\t\tpanic(\"internal error: cannot create stream with id 0\")\n\t}\n\n\tctx, cancelCtx := context.WithCancel(sc.baseCtx)\n\tst := &stream{\n\t\tsc:        sc,\n\t\tid:        id,\n\t\tstate:     state,\n\t\tctx:       ctx,\n\t\tcancelCtx: cancelCtx,\n\t}\n\tst.cw.Init()\n\tst.flow.conn = &sc.flow // link to conn-level counter\n\tst.flow.add(sc.initialStreamSendWindowSize)\n\tst.inflow.init(sc.initialStreamRecvWindowSize)\n\tif sc.hs.WriteTimeout > 0 {\n\t\tst.writeDeadline = sc.srv.afterFunc(sc.hs.WriteTimeout, st.onWriteTimeout)\n\t}\n\n\tsc.streams[id] = st\n\tsc.writeSched.OpenStream(st.id, OpenStreamOptions{PusherID: pusherID})\n\tif st.isPushed() {\n\t\tsc.curPushedStreams++\n\t} else {\n\t\tsc.curClientStreams++\n\t}\n\tif sc.curOpenStreams() == 1 {\n\t\tsc.setConnState(http.StateActive)\n\t}\n\n\treturn st\n}\n\nfunc (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*responseWriter, *http.Request, error) {\n\tsc.serveG.check()\n\n\trp := httpcommon.ServerRequestParam{\n\t\tMethod:    f.PseudoValue(\"method\"),\n\t\tScheme:    f.PseudoValue(\"scheme\"),\n\t\tAuthority: f.PseudoValue(\"authority\"),\n\t\tPath:      f.PseudoValue(\"path\"),\n\t\tProtocol:  f.PseudoValue(\"protocol\"),\n\t}\n\n\t// extended connect is disabled, so we should not see :protocol\n\tif disableExtendedConnectProtocol && rp.Protocol != \"\" {\n\t\treturn nil, nil, sc.countError(\"bad_connect\", streamError(f.StreamID, ErrCodeProtocol))\n\t}\n\n\tisConnect := rp.Method == \"CONNECT\"\n\tif isConnect {\n\t\tif rp.Protocol == \"\" && (rp.Path != \"\" || rp.Scheme != \"\" || rp.Authority == \"\") {\n\t\t\treturn nil, nil, sc.countError(\"bad_connect\", streamError(f.StreamID, ErrCodeProtocol))\n\t\t}\n\t} else if rp.Method == \"\" || rp.Path == \"\" || (rp.Scheme != \"https\" && rp.Scheme != \"http\") {\n\t\t// See 8.1.2.6 Malformed Requests and Responses:\n\t\t//\n\t\t// Malformed requests or responses that are detected\n\t\t// MUST be treated as a stream error (Section 5.4.2)\n\t\t// of type PROTOCOL_ERROR.\"\n\t\t//\n\t\t// 8.1.2.3 Request Pseudo-Header Fields\n\t\t// \"All HTTP/2 requests MUST include exactly one valid\n\t\t// value for the :method, :scheme, and :path\n\t\t// pseudo-header fields\"\n\t\treturn nil, nil, sc.countError(\"bad_path_method\", streamError(f.StreamID, ErrCodeProtocol))\n\t}\n\n\theader := make(http.Header)\n\trp.Header = header\n\tfor _, hf := range f.RegularFields() {\n\t\theader.Add(sc.canonicalHeader(hf.Name), hf.Value)\n\t}\n\tif rp.Authority == \"\" {\n\t\trp.Authority = header.Get(\"Host\")\n\t}\n\tif rp.Protocol != \"\" {\n\t\theader.Set(\":protocol\", rp.Protocol)\n\t}\n\n\trw, req, err := sc.newWriterAndRequestNoBody(st, rp)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tbodyOpen := !f.StreamEnded()\n\tif bodyOpen {\n\t\tif vv, ok := rp.Header[\"Content-Length\"]; ok {\n\t\t\tif cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil {\n\t\t\t\treq.ContentLength = int64(cl)\n\t\t\t} else {\n\t\t\t\treq.ContentLength = 0\n\t\t\t}\n\t\t} else {\n\t\t\treq.ContentLength = -1\n\t\t}\n\t\treq.Body.(*requestBody).pipe = &pipe{\n\t\t\tb: &dataBuffer{expected: req.ContentLength},\n\t\t}\n\t}\n\treturn rw, req, nil\n}\n\nfunc (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp httpcommon.ServerRequestParam) (*responseWriter, *http.Request, error) {\n\tsc.serveG.check()\n\n\tvar tlsState *tls.ConnectionState // nil if not scheme https\n\tif rp.Scheme == \"https\" {\n\t\ttlsState = sc.tlsState\n\t}\n\n\tres := httpcommon.NewServerRequest(rp)\n\tif res.InvalidReason != \"\" {\n\t\treturn nil, nil, sc.countError(res.InvalidReason, streamError(st.id, ErrCodeProtocol))\n\t}\n\n\tbody := &requestBody{\n\t\tconn:          sc,\n\t\tstream:        st,\n\t\tneedsContinue: res.NeedsContinue,\n\t}\n\treq := (&http.Request{\n\t\tMethod:     rp.Method,\n\t\tURL:        res.URL,\n\t\tRemoteAddr: sc.remoteAddrStr,\n\t\tHeader:     rp.Header,\n\t\tRequestURI: res.RequestURI,\n\t\tProto:      \"HTTP/2.0\",\n\t\tProtoMajor: 2,\n\t\tProtoMinor: 0,\n\t\tTLS:        tlsState,\n\t\tHost:       rp.Authority,\n\t\tBody:       body,\n\t\tTrailer:    res.Trailer,\n\t}).WithContext(st.ctx)\n\trw := sc.newResponseWriter(st, req)\n\treturn rw, req, nil\n}\n\nfunc (sc *serverConn) newResponseWriter(st *stream, req *http.Request) *responseWriter {\n\trws := responseWriterStatePool.Get().(*responseWriterState)\n\tbwSave := rws.bw\n\t*rws = responseWriterState{} // zero all the fields\n\trws.conn = sc\n\trws.bw = bwSave\n\trws.bw.Reset(chunkWriter{rws})\n\trws.stream = st\n\trws.req = req\n\treturn &responseWriter{rws: rws}\n}\n\ntype unstartedHandler struct {\n\tstreamID uint32\n\trw       *responseWriter\n\treq      *http.Request\n\thandler  func(http.ResponseWriter, *http.Request)\n}\n\n// scheduleHandler starts a handler goroutine,\n// or schedules one to start as soon as an existing handler finishes.\nfunc (sc *serverConn) scheduleHandler(streamID uint32, rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) error {\n\tsc.serveG.check()\n\tmaxHandlers := sc.advMaxStreams\n\tif sc.curHandlers < maxHandlers {\n\t\tsc.curHandlers++\n\t\tgo sc.runHandler(rw, req, handler)\n\t\treturn nil\n\t}\n\tif len(sc.unstartedHandlers) > int(4*sc.advMaxStreams) {\n\t\treturn sc.countError(\"too_many_early_resets\", ConnectionError(ErrCodeEnhanceYourCalm))\n\t}\n\tsc.unstartedHandlers = append(sc.unstartedHandlers, unstartedHandler{\n\t\tstreamID: streamID,\n\t\trw:       rw,\n\t\treq:      req,\n\t\thandler:  handler,\n\t})\n\treturn nil\n}\n\nfunc (sc *serverConn) handlerDone() {\n\tsc.serveG.check()\n\tsc.curHandlers--\n\ti := 0\n\tmaxHandlers := sc.advMaxStreams\n\tfor ; i < len(sc.unstartedHandlers); i++ {\n\t\tu := sc.unstartedHandlers[i]\n\t\tif sc.streams[u.streamID] == nil {\n\t\t\t// This stream was reset before its goroutine had a chance to start.\n\t\t\tcontinue\n\t\t}\n\t\tif sc.curHandlers >= maxHandlers {\n\t\t\tbreak\n\t\t}\n\t\tsc.curHandlers++\n\t\tgo sc.runHandler(u.rw, u.req, u.handler)\n\t\tsc.unstartedHandlers[i] = unstartedHandler{} // don't retain references\n\t}\n\tsc.unstartedHandlers = sc.unstartedHandlers[i:]\n\tif len(sc.unstartedHandlers) == 0 {\n\t\tsc.unstartedHandlers = nil\n\t}\n}\n\n// Run on its own goroutine.\nfunc (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) {\n\tsc.srv.markNewGoroutine()\n\tdefer sc.sendServeMsg(handlerDoneMsg)\n\tdidPanic := true\n\tdefer func() {\n\t\trw.rws.stream.cancelCtx()\n\t\tif req.MultipartForm != nil {\n\t\t\treq.MultipartForm.RemoveAll()\n\t\t}\n\t\tif didPanic {\n\t\t\te := recover()\n\t\t\tsc.writeFrameFromHandler(FrameWriteRequest{\n\t\t\t\twrite:  handlerPanicRST{rw.rws.stream.id},\n\t\t\t\tstream: rw.rws.stream,\n\t\t\t})\n\t\t\t// Same as net/http:\n\t\t\tif e != nil && e != http.ErrAbortHandler {\n\t\t\t\tconst size = 64 << 10\n\t\t\t\tbuf := make([]byte, size)\n\t\t\t\tbuf = buf[:runtime.Stack(buf, false)]\n\t\t\t\tsc.logf(\"http2: panic serving %v: %v\\n%s\", sc.conn.RemoteAddr(), e, buf)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\trw.handlerDone()\n\t}()\n\thandler(rw, req)\n\tdidPanic = false\n}\n\nfunc handleHeaderListTooLong(w http.ResponseWriter, r *http.Request) {\n\t// 10.5.1 Limits on Header Block Size:\n\t// .. \"A server that receives a larger header block than it is\n\t// willing to handle can send an HTTP 431 (Request Header Fields Too\n\t// Large) status code\"\n\tconst statusRequestHeaderFieldsTooLarge = 431 // only in Go 1.6+\n\tw.WriteHeader(statusRequestHeaderFieldsTooLarge)\n\tio.WriteString(w, \"<h1>HTTP Error 431</h1><p>Request Header Field(s) Too Large</p>\")\n}\n\n// called from handler goroutines.\n// h may be nil.\nfunc (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) error {\n\tsc.serveG.checkNotOn() // NOT on\n\tvar errc chan error\n\tif headerData.h != nil {\n\t\t// If there's a header map (which we don't own), so we have to block on\n\t\t// waiting for this frame to be written, so an http.Flush mid-handler\n\t\t// writes out the correct value of keys, before a handler later potentially\n\t\t// mutates it.\n\t\terrc = errChanPool.Get().(chan error)\n\t}\n\tif err := sc.writeFrameFromHandler(FrameWriteRequest{\n\t\twrite:  headerData,\n\t\tstream: st,\n\t\tdone:   errc,\n\t}); err != nil {\n\t\treturn err\n\t}\n\tif errc != nil {\n\t\tselect {\n\t\tcase err := <-errc:\n\t\t\terrChanPool.Put(errc)\n\t\t\treturn err\n\t\tcase <-sc.doneServing:\n\t\t\treturn errClientDisconnected\n\t\tcase <-st.cw:\n\t\t\treturn errStreamClosed\n\t\t}\n\t}\n\treturn nil\n}\n\n// called from handler goroutines.\nfunc (sc *serverConn) write100ContinueHeaders(st *stream) {\n\tsc.writeFrameFromHandler(FrameWriteRequest{\n\t\twrite:  write100ContinueHeadersFrame{st.id},\n\t\tstream: st,\n\t})\n}\n\n// A bodyReadMsg tells the server loop that the http.Handler read n\n// bytes of the DATA from the client on the given stream.\ntype bodyReadMsg struct {\n\tst *stream\n\tn  int\n}\n\n// called from handler goroutines.\n// Notes that the handler for the given stream ID read n bytes of its body\n// and schedules flow control tokens to be sent.\nfunc (sc *serverConn) noteBodyReadFromHandler(st *stream, n int, err error) {\n\tsc.serveG.checkNotOn() // NOT on\n\tif n > 0 {\n\t\tselect {\n\t\tcase sc.bodyReadCh <- bodyReadMsg{st, n}:\n\t\tcase <-sc.doneServing:\n\t\t}\n\t}\n}\n\nfunc (sc *serverConn) noteBodyRead(st *stream, n int) {\n\tsc.serveG.check()\n\tsc.sendWindowUpdate(nil, n) // conn-level\n\tif st.state != stateHalfClosedRemote && st.state != stateClosed {\n\t\t// Don't send this WINDOW_UPDATE if the stream is closed\n\t\t// remotely.\n\t\tsc.sendWindowUpdate(st, n)\n\t}\n}\n\n// st may be nil for conn-level\nfunc (sc *serverConn) sendWindowUpdate32(st *stream, n int32) {\n\tsc.sendWindowUpdate(st, int(n))\n}\n\n// st may be nil for conn-level\nfunc (sc *serverConn) sendWindowUpdate(st *stream, n int) {\n\tsc.serveG.check()\n\tvar streamID uint32\n\tvar send int32\n\tif st == nil {\n\t\tsend = sc.inflow.add(n)\n\t} else {\n\t\tstreamID = st.id\n\t\tsend = st.inflow.add(n)\n\t}\n\tif send == 0 {\n\t\treturn\n\t}\n\tsc.writeFrame(FrameWriteRequest{\n\t\twrite:  writeWindowUpdate{streamID: streamID, n: uint32(send)},\n\t\tstream: st,\n\t})\n}\n\n// requestBody is the Handler's Request.Body type.\n// Read and Close may be called concurrently.\ntype requestBody struct {\n\t_             incomparable\n\tstream        *stream\n\tconn          *serverConn\n\tcloseOnce     sync.Once // for use by Close only\n\tsawEOF        bool      // for use by Read only\n\tpipe          *pipe     // non-nil if we have an HTTP entity message body\n\tneedsContinue bool      // need to send a 100-continue\n}\n\nfunc (b *requestBody) Close() error {\n\tb.closeOnce.Do(func() {\n\t\tif b.pipe != nil {\n\t\t\tb.pipe.BreakWithError(errClosedBody)\n\t\t}\n\t})\n\treturn nil\n}\n\nfunc (b *requestBody) Read(p []byte) (n int, err error) {\n\tif b.needsContinue {\n\t\tb.needsContinue = false\n\t\tb.conn.write100ContinueHeaders(b.stream)\n\t}\n\tif b.pipe == nil || b.sawEOF {\n\t\treturn 0, io.EOF\n\t}\n\tn, err = b.pipe.Read(p)\n\tif err == io.EOF {\n\t\tb.sawEOF = true\n\t}\n\tif b.conn == nil && inTests {\n\t\treturn\n\t}\n\tb.conn.noteBodyReadFromHandler(b.stream, n, err)\n\treturn\n}\n\n// responseWriter is the http.ResponseWriter implementation. It's\n// intentionally small (1 pointer wide) to minimize garbage. The\n// responseWriterState pointer inside is zeroed at the end of a\n// request (in handlerDone) and calls on the responseWriter thereafter\n// simply crash (caller's mistake), but the much larger responseWriterState\n// and buffers are reused between multiple requests.\ntype responseWriter struct {\n\trws *responseWriterState\n}\n\n// Optional http.ResponseWriter interfaces implemented.\nvar (\n\t_ http.CloseNotifier = (*responseWriter)(nil)\n\t_ http.Flusher       = (*responseWriter)(nil)\n\t_ stringWriter       = (*responseWriter)(nil)\n)\n\ntype responseWriterState struct {\n\t// immutable within a request:\n\tstream *stream\n\treq    *http.Request\n\tconn   *serverConn\n\n\t// TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc\n\tbw *bufio.Writer // writing to a chunkWriter{this *responseWriterState}\n\n\t// mutated by http.Handler goroutine:\n\thandlerHeader http.Header // nil until called\n\tsnapHeader    http.Header // snapshot of handlerHeader at WriteHeader time\n\ttrailers      []string    // set in writeChunk\n\tstatus        int         // status code passed to WriteHeader\n\twroteHeader   bool        // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet.\n\tsentHeader    bool        // have we sent the header frame?\n\thandlerDone   bool        // handler has finished\n\n\tsentContentLen int64 // non-zero if handler set a Content-Length header\n\twroteBytes     int64\n\n\tcloseNotifierMu sync.Mutex // guards closeNotifierCh\n\tcloseNotifierCh chan bool  // nil until first used\n}\n\ntype chunkWriter struct{ rws *responseWriterState }\n\nfunc (cw chunkWriter) Write(p []byte) (n int, err error) {\n\tn, err = cw.rws.writeChunk(p)\n\tif err == errStreamClosed {\n\t\t// If writing failed because the stream has been closed,\n\t\t// return the reason it was closed.\n\t\terr = cw.rws.stream.closeErr\n\t}\n\treturn n, err\n}\n\nfunc (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) > 0 }\n\nfunc (rws *responseWriterState) hasNonemptyTrailers() bool {\n\tfor _, trailer := range rws.trailers {\n\t\tif _, ok := rws.handlerHeader[trailer]; ok {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// declareTrailer is called for each Trailer header when the\n// response header is written. It notes that a header will need to be\n// written in the trailers at the end of the response.\nfunc (rws *responseWriterState) declareTrailer(k string) {\n\tk = http.CanonicalHeaderKey(k)\n\tif !httpguts.ValidTrailerHeader(k) {\n\t\t// Forbidden by RFC 7230, section 4.1.2.\n\t\trws.conn.logf(\"ignoring invalid trailer %q\", k)\n\t\treturn\n\t}\n\tif !strSliceContains(rws.trailers, k) {\n\t\trws.trailers = append(rws.trailers, k)\n\t}\n}\n\n// writeChunk writes chunks from the bufio.Writer. But because\n// bufio.Writer may bypass its chunking, sometimes p may be\n// arbitrarily large.\n//\n// writeChunk is also responsible (on the first chunk) for sending the\n// HEADER response.\nfunc (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {\n\tif !rws.wroteHeader {\n\t\trws.writeHeader(200)\n\t}\n\n\tif rws.handlerDone {\n\t\trws.promoteUndeclaredTrailers()\n\t}\n\n\tisHeadResp := rws.req.Method == \"HEAD\"\n\tif !rws.sentHeader {\n\t\trws.sentHeader = true\n\t\tvar ctype, clen string\n\t\tif clen = rws.snapHeader.Get(\"Content-Length\"); clen != \"\" {\n\t\t\trws.snapHeader.Del(\"Content-Length\")\n\t\t\tif cl, err := strconv.ParseUint(clen, 10, 63); err == nil {\n\t\t\t\trws.sentContentLen = int64(cl)\n\t\t\t} else {\n\t\t\t\tclen = \"\"\n\t\t\t}\n\t\t}\n\t\t_, hasContentLength := rws.snapHeader[\"Content-Length\"]\n\t\tif !hasContentLength && clen == \"\" && rws.handlerDone && bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) {\n\t\t\tclen = strconv.Itoa(len(p))\n\t\t}\n\t\t_, hasContentType := rws.snapHeader[\"Content-Type\"]\n\t\t// If the Content-Encoding is non-blank, we shouldn't\n\t\t// sniff the body. See Issue golang.org/issue/31753.\n\t\tce := rws.snapHeader.Get(\"Content-Encoding\")\n\t\thasCE := len(ce) > 0\n\t\tif !hasCE && !hasContentType && bodyAllowedForStatus(rws.status) && len(p) > 0 {\n\t\t\tctype = http.DetectContentType(p)\n\t\t}\n\t\tvar date string\n\t\tif _, ok := rws.snapHeader[\"Date\"]; !ok {\n\t\t\t// TODO(bradfitz): be faster here, like net/http? measure.\n\t\t\tdate = rws.conn.srv.now().UTC().Format(http.TimeFormat)\n\t\t}\n\n\t\tfor _, v := range rws.snapHeader[\"Trailer\"] {\n\t\t\tforeachHeaderElement(v, rws.declareTrailer)\n\t\t}\n\n\t\t// \"Connection\" headers aren't allowed in HTTP/2 (RFC 7540, 8.1.2.2),\n\t\t// but respect \"Connection\" == \"close\" to mean sending a GOAWAY and tearing\n\t\t// down the TCP connection when idle, like we do for HTTP/1.\n\t\t// TODO: remove more Connection-specific header fields here, in addition\n\t\t// to \"Connection\".\n\t\tif _, ok := rws.snapHeader[\"Connection\"]; ok {\n\t\t\tv := rws.snapHeader.Get(\"Connection\")\n\t\t\tdelete(rws.snapHeader, \"Connection\")\n\t\t\tif v == \"close\" {\n\t\t\t\trws.conn.startGracefulShutdown()\n\t\t\t}\n\t\t}\n\n\t\tendStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp\n\t\terr = rws.conn.writeHeaders(rws.stream, &writeResHeaders{\n\t\t\tstreamID:      rws.stream.id,\n\t\t\thttpResCode:   rws.status,\n\t\t\th:             rws.snapHeader,\n\t\t\tendStream:     endStream,\n\t\t\tcontentType:   ctype,\n\t\t\tcontentLength: clen,\n\t\t\tdate:          date,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tif endStream {\n\t\t\treturn 0, nil\n\t\t}\n\t}\n\tif isHeadResp {\n\t\treturn len(p), nil\n\t}\n\tif len(p) == 0 && !rws.handlerDone {\n\t\treturn 0, nil\n\t}\n\n\t// only send trailers if they have actually been defined by the\n\t// server handler.\n\thasNonemptyTrailers := rws.hasNonemptyTrailers()\n\tendStream := rws.handlerDone && !hasNonemptyTrailers\n\tif len(p) > 0 || endStream {\n\t\t// only send a 0 byte DATA frame if we're ending the stream.\n\t\tif err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t}\n\n\tif rws.handlerDone && hasNonemptyTrailers {\n\t\terr = rws.conn.writeHeaders(rws.stream, &writeResHeaders{\n\t\t\tstreamID:  rws.stream.id,\n\t\t\th:         rws.handlerHeader,\n\t\t\ttrailers:  rws.trailers,\n\t\t\tendStream: true,\n\t\t})\n\t\treturn len(p), err\n\t}\n\treturn len(p), nil\n}\n\n// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys\n// that, if present, signals that the map entry is actually for\n// the response trailers, and not the response headers. The prefix\n// is stripped after the ServeHTTP call finishes and the values are\n// sent in the trailers.\n//\n// This mechanism is intended only for trailers that are not known\n// prior to the headers being written. If the set of trailers is fixed\n// or known before the header is written, the normal Go trailers mechanism\n// is preferred:\n//\n//\thttps://golang.org/pkg/net/http/#ResponseWriter\n//\thttps://golang.org/pkg/net/http/#example_ResponseWriter_trailers\nconst TrailerPrefix = \"Trailer:\"\n\n// promoteUndeclaredTrailers permits http.Handlers to set trailers\n// after the header has already been flushed. Because the Go\n// ResponseWriter interface has no way to set Trailers (only the\n// Header), and because we didn't want to expand the ResponseWriter\n// interface, and because nobody used trailers, and because RFC 7230\n// says you SHOULD (but not must) predeclare any trailers in the\n// header, the official ResponseWriter rules said trailers in Go must\n// be predeclared, and then we reuse the same ResponseWriter.Header()\n// map to mean both Headers and Trailers. When it's time to write the\n// Trailers, we pick out the fields of Headers that were declared as\n// trailers. That worked for a while, until we found the first major\n// user of Trailers in the wild: gRPC (using them only over http2),\n// and gRPC libraries permit setting trailers mid-stream without\n// predeclaring them. So: change of plans. We still permit the old\n// way, but we also permit this hack: if a Header() key begins with\n// \"Trailer:\", the suffix of that key is a Trailer. Because ':' is an\n// invalid token byte anyway, there is no ambiguity. (And it's already\n// filtered out) It's mildly hacky, but not terrible.\n//\n// This method runs after the Handler is done and promotes any Header\n// fields to be trailers.\nfunc (rws *responseWriterState) promoteUndeclaredTrailers() {\n\tfor k, vv := range rws.handlerHeader {\n\t\tif !strings.HasPrefix(k, TrailerPrefix) {\n\t\t\tcontinue\n\t\t}\n\t\ttrailerKey := strings.TrimPrefix(k, TrailerPrefix)\n\t\trws.declareTrailer(trailerKey)\n\t\trws.handlerHeader[http.CanonicalHeaderKey(trailerKey)] = vv\n\t}\n\n\tif len(rws.trailers) > 1 {\n\t\tsorter := sorterPool.Get().(*sorter)\n\t\tsorter.SortStrings(rws.trailers)\n\t\tsorterPool.Put(sorter)\n\t}\n}\n\nfunc (w *responseWriter) SetReadDeadline(deadline time.Time) error {\n\tst := w.rws.stream\n\tif !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) {\n\t\t// If we're setting a deadline in the past, reset the stream immediately\n\t\t// so writes after SetWriteDeadline returns will fail.\n\t\tst.onReadTimeout()\n\t\treturn nil\n\t}\n\tw.rws.conn.sendServeMsg(func(sc *serverConn) {\n\t\tif st.readDeadline != nil {\n\t\t\tif !st.readDeadline.Stop() {\n\t\t\t\t// Deadline already exceeded, or stream has been closed.\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tif deadline.IsZero() {\n\t\t\tst.readDeadline = nil\n\t\t} else if st.readDeadline == nil {\n\t\t\tst.readDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onReadTimeout)\n\t\t} else {\n\t\t\tst.readDeadline.Reset(deadline.Sub(sc.srv.now()))\n\t\t}\n\t})\n\treturn nil\n}\n\nfunc (w *responseWriter) SetWriteDeadline(deadline time.Time) error {\n\tst := w.rws.stream\n\tif !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) {\n\t\t// If we're setting a deadline in the past, reset the stream immediately\n\t\t// so writes after SetWriteDeadline returns will fail.\n\t\tst.onWriteTimeout()\n\t\treturn nil\n\t}\n\tw.rws.conn.sendServeMsg(func(sc *serverConn) {\n\t\tif st.writeDeadline != nil {\n\t\t\tif !st.writeDeadline.Stop() {\n\t\t\t\t// Deadline already exceeded, or stream has been closed.\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tif deadline.IsZero() {\n\t\t\tst.writeDeadline = nil\n\t\t} else if st.writeDeadline == nil {\n\t\t\tst.writeDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onWriteTimeout)\n\t\t} else {\n\t\t\tst.writeDeadline.Reset(deadline.Sub(sc.srv.now()))\n\t\t}\n\t})\n\treturn nil\n}\n\nfunc (w *responseWriter) EnableFullDuplex() error {\n\t// We always support full duplex responses, so this is a no-op.\n\treturn nil\n}\n\nfunc (w *responseWriter) Flush() {\n\tw.FlushError()\n}\n\nfunc (w *responseWriter) FlushError() error {\n\trws := w.rws\n\tif rws == nil {\n\t\tpanic(\"Header called after Handler finished\")\n\t}\n\tvar err error\n\tif rws.bw.Buffered() > 0 {\n\t\terr = rws.bw.Flush()\n\t} else {\n\t\t// The bufio.Writer won't call chunkWriter.Write\n\t\t// (writeChunk with zero bytes), so we have to do it\n\t\t// ourselves to force the HTTP response header and/or\n\t\t// final DATA frame (with END_STREAM) to be sent.\n\t\t_, err = chunkWriter{rws}.Write(nil)\n\t\tif err == nil {\n\t\t\tselect {\n\t\t\tcase <-rws.stream.cw:\n\t\t\t\terr = rws.stream.closeErr\n\t\t\tdefault:\n\t\t\t}\n\t\t}\n\t}\n\treturn err\n}\n\nfunc (w *responseWriter) CloseNotify() <-chan bool {\n\trws := w.rws\n\tif rws == nil {\n\t\tpanic(\"CloseNotify called after Handler finished\")\n\t}\n\trws.closeNotifierMu.Lock()\n\tch := rws.closeNotifierCh\n\tif ch == nil {\n\t\tch = make(chan bool, 1)\n\t\trws.closeNotifierCh = ch\n\t\tcw := rws.stream.cw\n\t\tgo func() {\n\t\t\tcw.Wait() // wait for close\n\t\t\tch <- true\n\t\t}()\n\t}\n\trws.closeNotifierMu.Unlock()\n\treturn ch\n}\n\nfunc (w *responseWriter) Header() http.Header {\n\trws := w.rws\n\tif rws == nil {\n\t\tpanic(\"Header called after Handler finished\")\n\t}\n\tif rws.handlerHeader == nil {\n\t\trws.handlerHeader = make(http.Header)\n\t}\n\treturn rws.handlerHeader\n}\n\n// checkWriteHeaderCode is a copy of net/http's checkWriteHeaderCode.\nfunc checkWriteHeaderCode(code int) {\n\t// Issue 22880: require valid WriteHeader status codes.\n\t// For now we only enforce that it's three digits.\n\t// In the future we might block things over 599 (600 and above aren't defined\n\t// at http://httpwg.org/specs/rfc7231.html#status.codes).\n\t// But for now any three digits.\n\t//\n\t// We used to send \"HTTP/1.1 000 0\" on the wire in responses but there's\n\t// no equivalent bogus thing we can realistically send in HTTP/2,\n\t// so we'll consistently panic instead and help people find their bugs\n\t// early. (We can't return an error from WriteHeader even if we wanted to.)\n\tif code < 100 || code > 999 {\n\t\tpanic(fmt.Sprintf(\"invalid WriteHeader code %v\", code))\n\t}\n}\n\nfunc (w *responseWriter) WriteHeader(code int) {\n\trws := w.rws\n\tif rws == nil {\n\t\tpanic(\"WriteHeader called after Handler finished\")\n\t}\n\trws.writeHeader(code)\n}\n\nfunc (rws *responseWriterState) writeHeader(code int) {\n\tif rws.wroteHeader {\n\t\treturn\n\t}\n\n\tcheckWriteHeaderCode(code)\n\n\t// Handle informational headers\n\tif code >= 100 && code <= 199 {\n\t\t// Per RFC 8297 we must not clear the current header map\n\t\th := rws.handlerHeader\n\n\t\t_, cl := h[\"Content-Length\"]\n\t\t_, te := h[\"Transfer-Encoding\"]\n\t\tif cl || te {\n\t\t\th = h.Clone()\n\t\t\th.Del(\"Content-Length\")\n\t\t\th.Del(\"Transfer-Encoding\")\n\t\t}\n\n\t\trws.conn.writeHeaders(rws.stream, &writeResHeaders{\n\t\t\tstreamID:    rws.stream.id,\n\t\t\thttpResCode: code,\n\t\t\th:           h,\n\t\t\tendStream:   rws.handlerDone && !rws.hasTrailers(),\n\t\t})\n\n\t\treturn\n\t}\n\n\trws.wroteHeader = true\n\trws.status = code\n\tif len(rws.handlerHeader) > 0 {\n\t\trws.snapHeader = cloneHeader(rws.handlerHeader)\n\t}\n}\n\nfunc cloneHeader(h http.Header) http.Header {\n\th2 := make(http.Header, len(h))\n\tfor k, vv := range h {\n\t\tvv2 := make([]string, len(vv))\n\t\tcopy(vv2, vv)\n\t\th2[k] = vv2\n\t}\n\treturn h2\n}\n\n// The Life Of A Write is like this:\n//\n// * Handler calls w.Write or w.WriteString ->\n// * -> rws.bw (*bufio.Writer) ->\n// * (Handler might call Flush)\n// * -> chunkWriter{rws}\n// * -> responseWriterState.writeChunk(p []byte)\n// * -> responseWriterState.writeChunk (most of the magic; see comment there)\nfunc (w *responseWriter) Write(p []byte) (n int, err error) {\n\treturn w.write(len(p), p, \"\")\n}\n\nfunc (w *responseWriter) WriteString(s string) (n int, err error) {\n\treturn w.write(len(s), nil, s)\n}\n\n// either dataB or dataS is non-zero.\nfunc (w *responseWriter) write(lenData int, dataB []byte, dataS string) (n int, err error) {\n\trws := w.rws\n\tif rws == nil {\n\t\tpanic(\"Write called after Handler finished\")\n\t}\n\tif !rws.wroteHeader {\n\t\tw.WriteHeader(200)\n\t}\n\tif !bodyAllowedForStatus(rws.status) {\n\t\treturn 0, http.ErrBodyNotAllowed\n\t}\n\trws.wroteBytes += int64(len(dataB)) + int64(len(dataS)) // only one can be set\n\tif rws.sentContentLen != 0 && rws.wroteBytes > rws.sentContentLen {\n\t\t// TODO: send a RST_STREAM\n\t\treturn 0, errors.New(\"http2: handler wrote more than declared Content-Length\")\n\t}\n\n\tif dataB != nil {\n\t\treturn rws.bw.Write(dataB)\n\t} else {\n\t\treturn rws.bw.WriteString(dataS)\n\t}\n}\n\nfunc (w *responseWriter) handlerDone() {\n\trws := w.rws\n\trws.handlerDone = true\n\tw.Flush()\n\tw.rws = nil\n\tresponseWriterStatePool.Put(rws)\n}\n\n// Push errors.\nvar (\n\tErrRecursivePush    = errors.New(\"http2: recursive push not allowed\")\n\tErrPushLimitReached = errors.New(\"http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS\")\n)\n\nvar _ http.Pusher = (*responseWriter)(nil)\n\nfunc (w *responseWriter) Push(target string, opts *http.PushOptions) error {\n\tst := w.rws.stream\n\tsc := st.sc\n\tsc.serveG.checkNotOn()\n\n\t// No recursive pushes: \"PUSH_PROMISE frames MUST only be sent on a peer-initiated stream.\"\n\t// http://tools.ietf.org/html/rfc7540#section-6.6\n\tif st.isPushed() {\n\t\treturn ErrRecursivePush\n\t}\n\n\tif opts == nil {\n\t\topts = new(http.PushOptions)\n\t}\n\n\t// Default options.\n\tif opts.Method == \"\" {\n\t\topts.Method = \"GET\"\n\t}\n\tif opts.Header == nil {\n\t\topts.Header = http.Header{}\n\t}\n\twantScheme := \"http\"\n\tif w.rws.req.TLS != nil {\n\t\twantScheme = \"https\"\n\t}\n\n\t// Validate the request.\n\tu, err := url.Parse(target)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif u.Scheme == \"\" {\n\t\tif !strings.HasPrefix(target, \"/\") {\n\t\t\treturn fmt.Errorf(\"target must be an absolute URL or an absolute path: %q\", target)\n\t\t}\n\t\tu.Scheme = wantScheme\n\t\tu.Host = w.rws.req.Host\n\t} else {\n\t\tif u.Scheme != wantScheme {\n\t\t\treturn fmt.Errorf(\"cannot push URL with scheme %q from request with scheme %q\", u.Scheme, wantScheme)\n\t\t}\n\t\tif u.Host == \"\" {\n\t\t\treturn errors.New(\"URL must have a host\")\n\t\t}\n\t}\n\tfor k := range opts.Header {\n\t\tif strings.HasPrefix(k, \":\") {\n\t\t\treturn fmt.Errorf(\"promised request headers cannot include pseudo header %q\", k)\n\t\t}\n\t\t// These headers are meaningful only if the request has a body,\n\t\t// but PUSH_PROMISE requests cannot have a body.\n\t\t// http://tools.ietf.org/html/rfc7540#section-8.2\n\t\t// Also disallow Host, since the promised URL must be absolute.\n\t\tif asciiEqualFold(k, \"content-length\") ||\n\t\t\tasciiEqualFold(k, \"content-encoding\") ||\n\t\t\tasciiEqualFold(k, \"trailer\") ||\n\t\t\tasciiEqualFold(k, \"te\") ||\n\t\t\tasciiEqualFold(k, \"expect\") ||\n\t\t\tasciiEqualFold(k, \"host\") {\n\t\t\treturn fmt.Errorf(\"promised request headers cannot include %q\", k)\n\t\t}\n\t}\n\tif err := checkValidHTTP2RequestHeaders(opts.Header); err != nil {\n\t\treturn err\n\t}\n\n\t// The RFC effectively limits promised requests to GET and HEAD:\n\t// \"Promised requests MUST be cacheable [GET, HEAD, or POST], and MUST be safe [GET or HEAD]\"\n\t// http://tools.ietf.org/html/rfc7540#section-8.2\n\tif opts.Method != \"GET\" && opts.Method != \"HEAD\" {\n\t\treturn fmt.Errorf(\"method %q must be GET or HEAD\", opts.Method)\n\t}\n\n\tmsg := &startPushRequest{\n\t\tparent: st,\n\t\tmethod: opts.Method,\n\t\turl:    u,\n\t\theader: cloneHeader(opts.Header),\n\t\tdone:   errChanPool.Get().(chan error),\n\t}\n\n\tselect {\n\tcase <-sc.doneServing:\n\t\treturn errClientDisconnected\n\tcase <-st.cw:\n\t\treturn errStreamClosed\n\tcase sc.serveMsgCh <- msg:\n\t}\n\n\tselect {\n\tcase <-sc.doneServing:\n\t\treturn errClientDisconnected\n\tcase <-st.cw:\n\t\treturn errStreamClosed\n\tcase err := <-msg.done:\n\t\terrChanPool.Put(msg.done)\n\t\treturn err\n\t}\n}\n\ntype startPushRequest struct {\n\tparent *stream\n\tmethod string\n\turl    *url.URL\n\theader http.Header\n\tdone   chan error\n}\n\nfunc (sc *serverConn) startPush(msg *startPushRequest) {\n\tsc.serveG.check()\n\n\t// http://tools.ietf.org/html/rfc7540#section-6.6.\n\t// PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that\n\t// is in either the \"open\" or \"half-closed (remote)\" state.\n\tif msg.parent.state != stateOpen && msg.parent.state != stateHalfClosedRemote {\n\t\t// responseWriter.Push checks that the stream is peer-initiated.\n\t\tmsg.done <- errStreamClosed\n\t\treturn\n\t}\n\n\t// http://tools.ietf.org/html/rfc7540#section-6.6.\n\tif !sc.pushEnabled {\n\t\tmsg.done <- http.ErrNotSupported\n\t\treturn\n\t}\n\n\t// PUSH_PROMISE frames must be sent in increasing order by stream ID, so\n\t// we allocate an ID for the promised stream lazily, when the PUSH_PROMISE\n\t// is written. Once the ID is allocated, we start the request handler.\n\tallocatePromisedID := func() (uint32, error) {\n\t\tsc.serveG.check()\n\n\t\t// Check this again, just in case. Technically, we might have received\n\t\t// an updated SETTINGS by the time we got around to writing this frame.\n\t\tif !sc.pushEnabled {\n\t\t\treturn 0, http.ErrNotSupported\n\t\t}\n\t\t// http://tools.ietf.org/html/rfc7540#section-6.5.2.\n\t\tif sc.curPushedStreams+1 > sc.clientMaxStreams {\n\t\t\treturn 0, ErrPushLimitReached\n\t\t}\n\n\t\t// http://tools.ietf.org/html/rfc7540#section-5.1.1.\n\t\t// Streams initiated by the server MUST use even-numbered identifiers.\n\t\t// A server that is unable to establish a new stream identifier can send a GOAWAY\n\t\t// frame so that the client is forced to open a new connection for new streams.\n\t\tif sc.maxPushPromiseID+2 >= 1<<31 {\n\t\t\tsc.startGracefulShutdownInternal()\n\t\t\treturn 0, ErrPushLimitReached\n\t\t}\n\t\tsc.maxPushPromiseID += 2\n\t\tpromisedID := sc.maxPushPromiseID\n\n\t\t// http://tools.ietf.org/html/rfc7540#section-8.2.\n\t\t// Strictly speaking, the new stream should start in \"reserved (local)\", then\n\t\t// transition to \"half closed (remote)\" after sending the initial HEADERS, but\n\t\t// we start in \"half closed (remote)\" for simplicity.\n\t\t// See further comments at the definition of stateHalfClosedRemote.\n\t\tpromised := sc.newStream(promisedID, msg.parent.id, stateHalfClosedRemote)\n\t\trw, req, err := sc.newWriterAndRequestNoBody(promised, httpcommon.ServerRequestParam{\n\t\t\tMethod:    msg.method,\n\t\t\tScheme:    msg.url.Scheme,\n\t\t\tAuthority: msg.url.Host,\n\t\t\tPath:      msg.url.RequestURI(),\n\t\t\tHeader:    cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE\n\t\t})\n\t\tif err != nil {\n\t\t\t// Should not happen, since we've already validated msg.url.\n\t\t\tpanic(fmt.Sprintf(\"newWriterAndRequestNoBody(%+v): %v\", msg.url, err))\n\t\t}\n\n\t\tsc.curHandlers++\n\t\tgo sc.runHandler(rw, req, sc.handler.ServeHTTP)\n\t\treturn promisedID, nil\n\t}\n\n\tsc.writeFrame(FrameWriteRequest{\n\t\twrite: &writePushPromise{\n\t\t\tstreamID:           msg.parent.id,\n\t\t\tmethod:             msg.method,\n\t\t\turl:                msg.url,\n\t\t\th:                  msg.header,\n\t\t\tallocatePromisedID: allocatePromisedID,\n\t\t},\n\t\tstream: msg.parent,\n\t\tdone:   msg.done,\n\t})\n}\n\n// foreachHeaderElement splits v according to the \"#rule\" construction\n// in RFC 7230 section 7 and calls fn for each non-empty element.\nfunc foreachHeaderElement(v string, fn func(string)) {\n\tv = textproto.TrimString(v)\n\tif v == \"\" {\n\t\treturn\n\t}\n\tif !strings.Contains(v, \",\") {\n\t\tfn(v)\n\t\treturn\n\t}\n\tfor _, f := range strings.Split(v, \",\") {\n\t\tif f = textproto.TrimString(f); f != \"\" {\n\t\t\tfn(f)\n\t\t}\n\t}\n}\n\n// From http://httpwg.org/specs/rfc7540.html#rfc.section.8.1.2.2\nvar connHeaders = []string{\n\t\"Connection\",\n\t\"Keep-Alive\",\n\t\"Proxy-Connection\",\n\t\"Transfer-Encoding\",\n\t\"Upgrade\",\n}\n\n// checkValidHTTP2RequestHeaders checks whether h is a valid HTTP/2 request,\n// per RFC 7540 Section 8.1.2.2.\n// The returned error is reported to users.\nfunc checkValidHTTP2RequestHeaders(h http.Header) error {\n\tfor _, k := range connHeaders {\n\t\tif _, ok := h[k]; ok {\n\t\t\treturn fmt.Errorf(\"request header %q is not valid in HTTP/2\", k)\n\t\t}\n\t}\n\tte := h[\"Te\"]\n\tif len(te) > 0 && (len(te) > 1 || (te[0] != \"trailers\" && te[0] != \"\")) {\n\t\treturn errors.New(`request header \"TE\" may only be \"trailers\" in HTTP/2`)\n\t}\n\treturn nil\n}\n\nfunc new400Handler(err error) http.HandlerFunc {\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\thttp.Error(w, err.Error(), http.StatusBadRequest)\n\t}\n}\n\n// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives\n// disabled. See comments on h1ServerShutdownChan above for why\n// the code is written this way.\nfunc h1ServerKeepAlivesDisabled(hs *http.Server) bool {\n\tvar x interface{} = hs\n\ttype I interface {\n\t\tdoKeepAlives() bool\n\t}\n\tif hs, ok := x.(I); ok {\n\t\treturn !hs.doKeepAlives()\n\t}\n\treturn false\n}\n\nfunc (sc *serverConn) countError(name string, err error) error {\n\tif sc == nil || sc.srv == nil {\n\t\treturn err\n\t}\n\tf := sc.countErrorFunc\n\tif f == nil {\n\t\treturn err\n\t}\n\tvar typ string\n\tvar code ErrCode\n\tswitch e := err.(type) {\n\tcase ConnectionError:\n\t\ttyp = \"conn\"\n\t\tcode = ErrCode(e)\n\tcase StreamError:\n\t\ttyp = \"stream\"\n\t\tcode = ErrCode(e.Code)\n\tdefault:\n\t\treturn err\n\t}\n\tcodeStr := errCodeName[code]\n\tif codeStr == \"\" {\n\t\tcodeStr = strconv.Itoa(int(code))\n\t}\n\tf(fmt.Sprintf(\"%s_%s_%s\", typ, codeStr, name))\n\treturn err\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/timer.go",
    "content": "// Copyright 2024 The Go 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.\npackage http2\n\nimport \"time\"\n\n// A timer is a time.Timer, as an interface which can be replaced in tests.\ntype timer = interface {\n\tC() <-chan time.Time\n\tReset(d time.Duration) bool\n\tStop() bool\n}\n\n// timeTimer adapts a time.Timer to the timer interface.\ntype timeTimer struct {\n\t*time.Timer\n}\n\nfunc (t timeTimer) C() <-chan time.Time { return t.Timer.C }\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/transport.go",
    "content": "// Copyright 2015 The Go 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\n// Transport code.\n\npackage http2\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"context\"\n\t\"crypto/rand\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"log\"\n\t\"math\"\n\t\"math/bits\"\n\tmathrand \"math/rand\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptrace\"\n\t\"net/textproto\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"golang.org/x/net/http/httpguts\"\n\t\"golang.org/x/net/http2/hpack\"\n\t\"golang.org/x/net/idna\"\n\t\"golang.org/x/net/internal/httpcommon\"\n)\n\nconst (\n\t// transportDefaultConnFlow is how many connection-level flow control\n\t// tokens we give the server at start-up, past the default 64k.\n\ttransportDefaultConnFlow = 1 << 30\n\n\t// transportDefaultStreamFlow is how many stream-level flow\n\t// control tokens we announce to the peer, and how many bytes\n\t// we buffer per stream.\n\ttransportDefaultStreamFlow = 4 << 20\n\n\tdefaultUserAgent = \"Go-http-client/2.0\"\n\n\t// initialMaxConcurrentStreams is a connections maxConcurrentStreams until\n\t// it's received servers initial SETTINGS frame, which corresponds with the\n\t// spec's minimum recommended value.\n\tinitialMaxConcurrentStreams = 100\n\n\t// defaultMaxConcurrentStreams is a connections default maxConcurrentStreams\n\t// if the server doesn't include one in its initial SETTINGS frame.\n\tdefaultMaxConcurrentStreams = 1000\n)\n\n// Transport is an HTTP/2 Transport.\n//\n// A Transport internally caches connections to servers. It is safe\n// for concurrent use by multiple goroutines.\ntype Transport struct {\n\t// DialTLSContext specifies an optional dial function with context for\n\t// creating TLS connections for requests.\n\t//\n\t// If DialTLSContext and DialTLS is nil, tls.Dial is used.\n\t//\n\t// If the returned net.Conn has a ConnectionState method like tls.Conn,\n\t// it will be used to set http.Response.TLS.\n\tDialTLSContext func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error)\n\n\t// DialTLS specifies an optional dial function for creating\n\t// TLS connections for requests.\n\t//\n\t// If DialTLSContext and DialTLS is nil, tls.Dial is used.\n\t//\n\t// Deprecated: Use DialTLSContext instead, which allows the transport\n\t// to cancel dials as soon as they are no longer needed.\n\t// If both are set, DialTLSContext takes priority.\n\tDialTLS func(network, addr string, cfg *tls.Config) (net.Conn, error)\n\n\t// TLSClientConfig specifies the TLS configuration to use with\n\t// tls.Client. If nil, the default configuration is used.\n\tTLSClientConfig *tls.Config\n\n\t// ConnPool optionally specifies an alternate connection pool to use.\n\t// If nil, the default is used.\n\tConnPool ClientConnPool\n\n\t// DisableCompression, if true, prevents the Transport from\n\t// requesting compression with an \"Accept-Encoding: gzip\"\n\t// request header when the Request contains no existing\n\t// Accept-Encoding value. If the Transport requests gzip on\n\t// its own and gets a gzipped response, it's transparently\n\t// decoded in the Response.Body. However, if the user\n\t// explicitly requested gzip it is not automatically\n\t// uncompressed.\n\tDisableCompression bool\n\n\t// AllowHTTP, if true, permits HTTP/2 requests using the insecure,\n\t// plain-text \"http\" scheme. Note that this does not enable h2c support.\n\tAllowHTTP bool\n\n\t// MaxHeaderListSize is the http2 SETTINGS_MAX_HEADER_LIST_SIZE to\n\t// send in the initial settings frame. It is how many bytes\n\t// of response headers are allowed. Unlike the http2 spec, zero here\n\t// means to use a default limit (currently 10MB). If you actually\n\t// want to advertise an unlimited value to the peer, Transport\n\t// interprets the highest possible value here (0xffffffff or 1<<32-1)\n\t// to mean no limit.\n\tMaxHeaderListSize uint32\n\n\t// MaxReadFrameSize is the http2 SETTINGS_MAX_FRAME_SIZE to send in the\n\t// initial settings frame. It is the size in bytes of the largest frame\n\t// payload that the sender is willing to receive. If 0, no setting is\n\t// sent, and the value is provided by the peer, which should be 16384\n\t// according to the spec:\n\t// https://datatracker.ietf.org/doc/html/rfc7540#section-6.5.2.\n\t// Values are bounded in the range 16k to 16M.\n\tMaxReadFrameSize uint32\n\n\t// MaxDecoderHeaderTableSize optionally specifies the http2\n\t// SETTINGS_HEADER_TABLE_SIZE to send in the initial settings frame. It\n\t// informs the remote endpoint of the maximum size of the header compression\n\t// table used to decode header blocks, in octets. If zero, the default value\n\t// of 4096 is used.\n\tMaxDecoderHeaderTableSize uint32\n\n\t// MaxEncoderHeaderTableSize optionally specifies an upper limit for the\n\t// header compression table used for encoding request headers. Received\n\t// SETTINGS_HEADER_TABLE_SIZE settings are capped at this limit. If zero,\n\t// the default value of 4096 is used.\n\tMaxEncoderHeaderTableSize uint32\n\n\t// StrictMaxConcurrentStreams controls whether the server's\n\t// SETTINGS_MAX_CONCURRENT_STREAMS should be respected\n\t// globally. If false, new TCP connections are created to the\n\t// server as needed to keep each under the per-connection\n\t// SETTINGS_MAX_CONCURRENT_STREAMS limit. If true, the\n\t// server's SETTINGS_MAX_CONCURRENT_STREAMS is interpreted as\n\t// a global limit and callers of RoundTrip block when needed,\n\t// waiting for their turn.\n\tStrictMaxConcurrentStreams bool\n\n\t// IdleConnTimeout is the maximum amount of time an idle\n\t// (keep-alive) connection will remain idle before closing\n\t// itself.\n\t// Zero means no limit.\n\tIdleConnTimeout time.Duration\n\n\t// ReadIdleTimeout is the timeout after which a health check using ping\n\t// frame will be carried out if no frame is received on the connection.\n\t// Note that a ping response will is considered a received frame, so if\n\t// there is no other traffic on the connection, the health check will\n\t// be performed every ReadIdleTimeout interval.\n\t// If zero, no health check is performed.\n\tReadIdleTimeout time.Duration\n\n\t// PingTimeout is the timeout after which the connection will be closed\n\t// if a response to Ping is not received.\n\t// Defaults to 15s.\n\tPingTimeout time.Duration\n\n\t// WriteByteTimeout is the timeout after which the connection will be\n\t// closed no data can be written to it. The timeout begins when data is\n\t// available to write, and is extended whenever any bytes are written.\n\tWriteByteTimeout time.Duration\n\n\t// CountError, if non-nil, is called on HTTP/2 transport errors.\n\t// It's intended to increment a metric for monitoring, such\n\t// as an expvar or Prometheus metric.\n\t// The errType consists of only ASCII word characters.\n\tCountError func(errType string)\n\n\t// t1, if non-nil, is the standard library Transport using\n\t// this transport. Its settings are used (but not its\n\t// RoundTrip method, etc).\n\tt1 *http.Transport\n\n\tconnPoolOnce  sync.Once\n\tconnPoolOrDef ClientConnPool // non-nil version of ConnPool\n\n\t*transportTestHooks\n}\n\n// Hook points used for testing.\n// Outside of tests, t.transportTestHooks is nil and these all have minimal implementations.\n// Inside tests, see the testSyncHooks function docs.\n\ntype transportTestHooks struct {\n\tnewclientconn func(*ClientConn)\n\tgroup         synctestGroupInterface\n}\n\nfunc (t *Transport) markNewGoroutine() {\n\tif t != nil && t.transportTestHooks != nil {\n\t\tt.transportTestHooks.group.Join()\n\t}\n}\n\nfunc (t *Transport) now() time.Time {\n\tif t != nil && t.transportTestHooks != nil {\n\t\treturn t.transportTestHooks.group.Now()\n\t}\n\treturn time.Now()\n}\n\nfunc (t *Transport) timeSince(when time.Time) time.Duration {\n\tif t != nil && t.transportTestHooks != nil {\n\t\treturn t.now().Sub(when)\n\t}\n\treturn time.Since(when)\n}\n\n// newTimer creates a new time.Timer, or a synthetic timer in tests.\nfunc (t *Transport) newTimer(d time.Duration) timer {\n\tif t.transportTestHooks != nil {\n\t\treturn t.transportTestHooks.group.NewTimer(d)\n\t}\n\treturn timeTimer{time.NewTimer(d)}\n}\n\n// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests.\nfunc (t *Transport) afterFunc(d time.Duration, f func()) timer {\n\tif t.transportTestHooks != nil {\n\t\treturn t.transportTestHooks.group.AfterFunc(d, f)\n\t}\n\treturn timeTimer{time.AfterFunc(d, f)}\n}\n\nfunc (t *Transport) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) {\n\tif t.transportTestHooks != nil {\n\t\treturn t.transportTestHooks.group.ContextWithTimeout(ctx, d)\n\t}\n\treturn context.WithTimeout(ctx, d)\n}\n\nfunc (t *Transport) maxHeaderListSize() uint32 {\n\tn := int64(t.MaxHeaderListSize)\n\tif t.t1 != nil && t.t1.MaxResponseHeaderBytes != 0 {\n\t\tn = t.t1.MaxResponseHeaderBytes\n\t\tif n > 0 {\n\t\t\tn = adjustHTTP1MaxHeaderSize(n)\n\t\t}\n\t}\n\tif n <= 0 {\n\t\treturn 10 << 20\n\t}\n\tif n >= 0xffffffff {\n\t\treturn 0\n\t}\n\treturn uint32(n)\n}\n\nfunc (t *Transport) disableCompression() bool {\n\treturn t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)\n}\n\n// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.\n// It returns an error if t1 has already been HTTP/2-enabled.\n//\n// Use ConfigureTransports instead to configure the HTTP/2 Transport.\nfunc ConfigureTransport(t1 *http.Transport) error {\n\t_, err := ConfigureTransports(t1)\n\treturn err\n}\n\n// ConfigureTransports configures a net/http HTTP/1 Transport to use HTTP/2.\n// It returns a new HTTP/2 Transport for further configuration.\n// It returns an error if t1 has already been HTTP/2-enabled.\nfunc ConfigureTransports(t1 *http.Transport) (*Transport, error) {\n\treturn configureTransports(t1)\n}\n\nfunc configureTransports(t1 *http.Transport) (*Transport, error) {\n\tconnPool := new(clientConnPool)\n\tt2 := &Transport{\n\t\tConnPool: noDialClientConnPool{connPool},\n\t\tt1:       t1,\n\t}\n\tconnPool.t = t2\n\tif err := registerHTTPSProtocol(t1, noDialH2RoundTripper{t2}); err != nil {\n\t\treturn nil, err\n\t}\n\tif t1.TLSClientConfig == nil {\n\t\tt1.TLSClientConfig = new(tls.Config)\n\t}\n\tif !strSliceContains(t1.TLSClientConfig.NextProtos, \"h2\") {\n\t\tt1.TLSClientConfig.NextProtos = append([]string{\"h2\"}, t1.TLSClientConfig.NextProtos...)\n\t}\n\tif !strSliceContains(t1.TLSClientConfig.NextProtos, \"http/1.1\") {\n\t\tt1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, \"http/1.1\")\n\t}\n\tupgradeFn := func(scheme, authority string, c net.Conn) http.RoundTripper {\n\t\taddr := authorityAddr(scheme, authority)\n\t\tif used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil {\n\t\t\tgo c.Close()\n\t\t\treturn erringRoundTripper{err}\n\t\t} else if !used {\n\t\t\t// Turns out we don't need this c.\n\t\t\t// For example, two goroutines made requests to the same host\n\t\t\t// at the same time, both kicking off TCP dials. (since protocol\n\t\t\t// was unknown)\n\t\t\tgo c.Close()\n\t\t}\n\t\tif scheme == \"http\" {\n\t\t\treturn (*unencryptedTransport)(t2)\n\t\t}\n\t\treturn t2\n\t}\n\tif t1.TLSNextProto == nil {\n\t\tt1.TLSNextProto = make(map[string]func(string, *tls.Conn) http.RoundTripper)\n\t}\n\tt1.TLSNextProto[NextProtoTLS] = func(authority string, c *tls.Conn) http.RoundTripper {\n\t\treturn upgradeFn(\"https\", authority, c)\n\t}\n\t// The \"unencrypted_http2\" TLSNextProto key is used to pass off non-TLS HTTP/2 conns.\n\tt1.TLSNextProto[nextProtoUnencryptedHTTP2] = func(authority string, c *tls.Conn) http.RoundTripper {\n\t\tnc, err := unencryptedNetConnFromTLSConn(c)\n\t\tif err != nil {\n\t\t\tgo c.Close()\n\t\t\treturn erringRoundTripper{err}\n\t\t}\n\t\treturn upgradeFn(\"http\", authority, nc)\n\t}\n\treturn t2, nil\n}\n\n// unencryptedTransport is a Transport with a RoundTrip method that\n// always permits http:// URLs.\ntype unencryptedTransport Transport\n\nfunc (t *unencryptedTransport) RoundTrip(req *http.Request) (*http.Response, error) {\n\treturn (*Transport)(t).RoundTripOpt(req, RoundTripOpt{allowHTTP: true})\n}\n\nfunc (t *Transport) connPool() ClientConnPool {\n\tt.connPoolOnce.Do(t.initConnPool)\n\treturn t.connPoolOrDef\n}\n\nfunc (t *Transport) initConnPool() {\n\tif t.ConnPool != nil {\n\t\tt.connPoolOrDef = t.ConnPool\n\t} else {\n\t\tt.connPoolOrDef = &clientConnPool{t: t}\n\t}\n}\n\n// ClientConn is the state of a single HTTP/2 client connection to an\n// HTTP/2 server.\ntype ClientConn struct {\n\tt             *Transport\n\ttconn         net.Conn             // usually *tls.Conn, except specialized impls\n\ttlsState      *tls.ConnectionState // nil only for specialized impls\n\tatomicReused  uint32               // whether conn is being reused; atomic\n\tsingleUse     bool                 // whether being used for a single http.Request\n\tgetConnCalled bool                 // used by clientConnPool\n\n\t// readLoop goroutine fields:\n\treaderDone chan struct{} // closed on error\n\treaderErr  error         // set before readerDone is closed\n\n\tidleTimeout time.Duration // or 0 for never\n\tidleTimer   timer\n\n\tmu               sync.Mutex // guards following\n\tcond             *sync.Cond // hold mu; broadcast on flow/closed changes\n\tflow             outflow    // our conn-level flow control quota (cs.outflow is per stream)\n\tinflow           inflow     // peer's conn-level flow control\n\tdoNotReuse       bool       // whether conn is marked to not be reused for any future requests\n\tclosing          bool\n\tclosed           bool\n\tclosedOnIdle     bool                     // true if conn was closed for idleness\n\tseenSettings     bool                     // true if we've seen a settings frame, false otherwise\n\tseenSettingsChan chan struct{}            // closed when seenSettings is true or frame reading fails\n\twantSettingsAck  bool                     // we sent a SETTINGS frame and haven't heard back\n\tgoAway           *GoAwayFrame             // if non-nil, the GoAwayFrame we received\n\tgoAwayDebug      string                   // goAway frame's debug data, retained as a string\n\tstreams          map[uint32]*clientStream // client-initiated\n\tstreamsReserved  int                      // incr by ReserveNewRequest; decr on RoundTrip\n\tnextStreamID     uint32\n\tpendingRequests  int                       // requests blocked and waiting to be sent because len(streams) == maxConcurrentStreams\n\tpings            map[[8]byte]chan struct{} // in flight ping data to notification channel\n\tbr               *bufio.Reader\n\tlastActive       time.Time\n\tlastIdle         time.Time // time last idle\n\t// Settings from peer: (also guarded by wmu)\n\tmaxFrameSize                uint32\n\tmaxConcurrentStreams        uint32\n\tpeerMaxHeaderListSize       uint64\n\tpeerMaxHeaderTableSize      uint32\n\tinitialWindowSize           uint32\n\tinitialStreamRecvWindowSize int32\n\treadIdleTimeout             time.Duration\n\tpingTimeout                 time.Duration\n\textendedConnectAllowed      bool\n\n\t// rstStreamPingsBlocked works around an unfortunate gRPC behavior.\n\t// gRPC strictly limits the number of PING frames that it will receive.\n\t// The default is two pings per two hours, but the limit resets every time\n\t// the gRPC endpoint sends a HEADERS or DATA frame. See golang/go#70575.\n\t//\n\t// rstStreamPingsBlocked is set after receiving a response to a PING frame\n\t// bundled with an RST_STREAM (see pendingResets below), and cleared after\n\t// receiving a HEADERS or DATA frame.\n\trstStreamPingsBlocked bool\n\n\t// pendingResets is the number of RST_STREAM frames we have sent to the peer,\n\t// without confirming that the peer has received them. When we send a RST_STREAM,\n\t// we bundle it with a PING frame, unless a PING is already in flight. We count\n\t// the reset stream against the connection's concurrency limit until we get\n\t// a PING response. This limits the number of requests we'll try to send to a\n\t// completely unresponsive connection.\n\tpendingResets int\n\n\t// reqHeaderMu is a 1-element semaphore channel controlling access to sending new requests.\n\t// Write to reqHeaderMu to lock it, read from it to unlock.\n\t// Lock reqmu BEFORE mu or wmu.\n\treqHeaderMu chan struct{}\n\n\t// wmu is held while writing.\n\t// Acquire BEFORE mu when holding both, to avoid blocking mu on network writes.\n\t// Only acquire both at the same time when changing peer settings.\n\twmu  sync.Mutex\n\tbw   *bufio.Writer\n\tfr   *Framer\n\twerr error        // first write error that has occurred\n\thbuf bytes.Buffer // HPACK encoder writes into this\n\thenc *hpack.Encoder\n}\n\n// clientStream is the state for a single HTTP/2 stream. One of these\n// is created for each Transport.RoundTrip call.\ntype clientStream struct {\n\tcc *ClientConn\n\n\t// Fields of Request that we may access even after the response body is closed.\n\tctx       context.Context\n\treqCancel <-chan struct{}\n\n\ttrace         *httptrace.ClientTrace // or nil\n\tID            uint32\n\tbufPipe       pipe // buffered pipe with the flow-controlled response payload\n\trequestedGzip bool\n\tisHead        bool\n\n\tabortOnce sync.Once\n\tabort     chan struct{} // closed to signal stream should end immediately\n\tabortErr  error         // set if abort is closed\n\n\tpeerClosed chan struct{} // closed when the peer sends an END_STREAM flag\n\tdonec      chan struct{} // closed after the stream is in the closed state\n\ton100      chan struct{} // buffered; written to if a 100 is received\n\n\trespHeaderRecv chan struct{}  // closed when headers are received\n\tres            *http.Response // set if respHeaderRecv is closed\n\n\tflow        outflow // guarded by cc.mu\n\tinflow      inflow  // guarded by cc.mu\n\tbytesRemain int64   // -1 means unknown; owned by transportResponseBody.Read\n\treadErr     error   // sticky read error; owned by transportResponseBody.Read\n\n\treqBody              io.ReadCloser\n\treqBodyContentLength int64         // -1 means unknown\n\treqBodyClosed        chan struct{} // guarded by cc.mu; non-nil on Close, closed when done\n\n\t// owned by writeRequest:\n\tsentEndStream bool // sent an END_STREAM flag to the peer\n\tsentHeaders   bool\n\n\t// owned by clientConnReadLoop:\n\tfirstByte       bool  // got the first response byte\n\tpastHeaders     bool  // got first MetaHeadersFrame (actual headers)\n\tpastTrailers    bool  // got optional second MetaHeadersFrame (trailers)\n\treadClosed      bool  // peer sent an END_STREAM flag\n\treadAborted     bool  // read loop reset the stream\n\ttotalHeaderSize int64 // total size of 1xx headers seen\n\n\ttrailer    http.Header  // accumulated trailers\n\tresTrailer *http.Header // client's Response.Trailer\n}\n\nvar got1xxFuncForTests func(int, textproto.MIMEHeader) error\n\n// get1xxTraceFunc returns the value of request's httptrace.ClientTrace.Got1xxResponse func,\n// if any. It returns nil if not set or if the Go version is too old.\nfunc (cs *clientStream) get1xxTraceFunc() func(int, textproto.MIMEHeader) error {\n\tif fn := got1xxFuncForTests; fn != nil {\n\t\treturn fn\n\t}\n\treturn traceGot1xxResponseFunc(cs.trace)\n}\n\nfunc (cs *clientStream) abortStream(err error) {\n\tcs.cc.mu.Lock()\n\tdefer cs.cc.mu.Unlock()\n\tcs.abortStreamLocked(err)\n}\n\nfunc (cs *clientStream) abortStreamLocked(err error) {\n\tcs.abortOnce.Do(func() {\n\t\tcs.abortErr = err\n\t\tclose(cs.abort)\n\t})\n\tif cs.reqBody != nil {\n\t\tcs.closeReqBodyLocked()\n\t}\n\t// TODO(dneil): Clean up tests where cs.cc.cond is nil.\n\tif cs.cc.cond != nil {\n\t\t// Wake up writeRequestBody if it is waiting on flow control.\n\t\tcs.cc.cond.Broadcast()\n\t}\n}\n\nfunc (cs *clientStream) abortRequestBodyWrite() {\n\tcc := cs.cc\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\tif cs.reqBody != nil && cs.reqBodyClosed == nil {\n\t\tcs.closeReqBodyLocked()\n\t\tcc.cond.Broadcast()\n\t}\n}\n\nfunc (cs *clientStream) closeReqBodyLocked() {\n\tif cs.reqBodyClosed != nil {\n\t\treturn\n\t}\n\tcs.reqBodyClosed = make(chan struct{})\n\treqBodyClosed := cs.reqBodyClosed\n\tgo func() {\n\t\tcs.cc.t.markNewGoroutine()\n\t\tcs.reqBody.Close()\n\t\tclose(reqBodyClosed)\n\t}()\n}\n\ntype stickyErrWriter struct {\n\tgroup   synctestGroupInterface\n\tconn    net.Conn\n\ttimeout time.Duration\n\terr     *error\n}\n\nfunc (sew stickyErrWriter) Write(p []byte) (n int, err error) {\n\tif *sew.err != nil {\n\t\treturn 0, *sew.err\n\t}\n\tn, err = writeWithByteTimeout(sew.group, sew.conn, sew.timeout, p)\n\t*sew.err = err\n\treturn n, err\n}\n\n// noCachedConnError is the concrete type of ErrNoCachedConn, which\n// needs to be detected by net/http regardless of whether it's its\n// bundled version (in h2_bundle.go with a rewritten type name) or\n// from a user's x/net/http2. As such, as it has a unique method name\n// (IsHTTP2NoCachedConnError) that net/http sniffs for via func\n// isNoCachedConnError.\ntype noCachedConnError struct{}\n\nfunc (noCachedConnError) IsHTTP2NoCachedConnError() {}\nfunc (noCachedConnError) Error() string             { return \"http2: no cached connection was available\" }\n\n// isNoCachedConnError reports whether err is of type noCachedConnError\n// or its equivalent renamed type in net/http2's h2_bundle.go. Both types\n// may coexist in the same running program.\nfunc isNoCachedConnError(err error) bool {\n\t_, ok := err.(interface{ IsHTTP2NoCachedConnError() })\n\treturn ok\n}\n\nvar ErrNoCachedConn error = noCachedConnError{}\n\n// RoundTripOpt are options for the Transport.RoundTripOpt method.\ntype RoundTripOpt struct {\n\t// OnlyCachedConn controls whether RoundTripOpt may\n\t// create a new TCP connection. If set true and\n\t// no cached connection is available, RoundTripOpt\n\t// will return ErrNoCachedConn.\n\tOnlyCachedConn bool\n\n\tallowHTTP bool // allow http:// URLs\n}\n\nfunc (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {\n\treturn t.RoundTripOpt(req, RoundTripOpt{})\n}\n\n// authorityAddr returns a given authority (a host/IP, or host:port / ip:port)\n// and returns a host:port. The port 443 is added if needed.\nfunc authorityAddr(scheme string, authority string) (addr string) {\n\thost, port, err := net.SplitHostPort(authority)\n\tif err != nil { // authority didn't have a port\n\t\thost = authority\n\t\tport = \"\"\n\t}\n\tif port == \"\" { // authority's port was empty\n\t\tport = \"443\"\n\t\tif scheme == \"http\" {\n\t\t\tport = \"80\"\n\t\t}\n\t}\n\tif a, err := idna.ToASCII(host); err == nil {\n\t\thost = a\n\t}\n\t// IPv6 address literal, without a port:\n\tif strings.HasPrefix(host, \"[\") && strings.HasSuffix(host, \"]\") {\n\t\treturn host + \":\" + port\n\t}\n\treturn net.JoinHostPort(host, port)\n}\n\n// RoundTripOpt is like RoundTrip, but takes options.\nfunc (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) {\n\tswitch req.URL.Scheme {\n\tcase \"https\":\n\t\t// Always okay.\n\tcase \"http\":\n\t\tif !t.AllowHTTP && !opt.allowHTTP {\n\t\t\treturn nil, errors.New(\"http2: unencrypted HTTP/2 not enabled\")\n\t\t}\n\tdefault:\n\t\treturn nil, errors.New(\"http2: unsupported scheme\")\n\t}\n\n\taddr := authorityAddr(req.URL.Scheme, req.URL.Host)\n\tfor retry := 0; ; retry++ {\n\t\tcc, err := t.connPool().GetClientConn(req, addr)\n\t\tif err != nil {\n\t\t\tt.vlogf(\"http2: Transport failed to get client conn for %s: %v\", addr, err)\n\t\t\treturn nil, err\n\t\t}\n\t\treused := !atomic.CompareAndSwapUint32(&cc.atomicReused, 0, 1)\n\t\ttraceGotConn(req, cc, reused)\n\t\tres, err := cc.RoundTrip(req)\n\t\tif err != nil && retry <= 6 {\n\t\t\troundTripErr := err\n\t\t\tif req, err = shouldRetryRequest(req, err); err == nil {\n\t\t\t\t// After the first retry, do exponential backoff with 10% jitter.\n\t\t\t\tif retry == 0 {\n\t\t\t\t\tt.vlogf(\"RoundTrip retrying after failure: %v\", roundTripErr)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tbackoff := float64(uint(1) << (uint(retry) - 1))\n\t\t\t\tbackoff += backoff * (0.1 * mathrand.Float64())\n\t\t\t\td := time.Second * time.Duration(backoff)\n\t\t\t\ttm := t.newTimer(d)\n\t\t\t\tselect {\n\t\t\t\tcase <-tm.C():\n\t\t\t\t\tt.vlogf(\"RoundTrip retrying after failure: %v\", roundTripErr)\n\t\t\t\t\tcontinue\n\t\t\t\tcase <-req.Context().Done():\n\t\t\t\t\ttm.Stop()\n\t\t\t\t\terr = req.Context().Err()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif err == errClientConnNotEstablished {\n\t\t\t// This ClientConn was created recently,\n\t\t\t// this is the first request to use it,\n\t\t\t// and the connection is closed and not usable.\n\t\t\t//\n\t\t\t// In this state, cc.idleTimer will remove the conn from the pool\n\t\t\t// when it fires. Stop the timer and remove it here so future requests\n\t\t\t// won't try to use this connection.\n\t\t\t//\n\t\t\t// If the timer has already fired and we're racing it, the redundant\n\t\t\t// call to MarkDead is harmless.\n\t\t\tif cc.idleTimer != nil {\n\t\t\t\tcc.idleTimer.Stop()\n\t\t\t}\n\t\t\tt.connPool().MarkDead(cc)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.vlogf(\"RoundTrip failure: %v\", err)\n\t\t\treturn nil, err\n\t\t}\n\t\treturn res, nil\n\t}\n}\n\n// CloseIdleConnections closes any connections which were previously\n// connected from previous requests but are now sitting idle.\n// It does not interrupt any connections currently in use.\nfunc (t *Transport) CloseIdleConnections() {\n\tif cp, ok := t.connPool().(clientConnPoolIdleCloser); ok {\n\t\tcp.closeIdleConnections()\n\t}\n}\n\nvar (\n\terrClientConnClosed         = errors.New(\"http2: client conn is closed\")\n\terrClientConnUnusable       = errors.New(\"http2: client conn not usable\")\n\terrClientConnNotEstablished = errors.New(\"http2: client conn could not be established\")\n\terrClientConnGotGoAway      = errors.New(\"http2: Transport received Server's graceful shutdown GOAWAY\")\n)\n\n// shouldRetryRequest is called by RoundTrip when a request fails to get\n// response headers. It is always called with a non-nil error.\n// It returns either a request to retry (either the same request, or a\n// modified clone), or an error if the request can't be replayed.\nfunc shouldRetryRequest(req *http.Request, err error) (*http.Request, error) {\n\tif !canRetryError(err) {\n\t\treturn nil, err\n\t}\n\t// If the Body is nil (or http.NoBody), it's safe to reuse\n\t// this request and its Body.\n\tif req.Body == nil || req.Body == http.NoBody {\n\t\treturn req, nil\n\t}\n\n\t// If the request body can be reset back to its original\n\t// state via the optional req.GetBody, do that.\n\tif req.GetBody != nil {\n\t\tbody, err := req.GetBody()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tnewReq := *req\n\t\tnewReq.Body = body\n\t\treturn &newReq, nil\n\t}\n\n\t// The Request.Body can't reset back to the beginning, but we\n\t// don't seem to have started to read from it yet, so reuse\n\t// the request directly.\n\tif err == errClientConnUnusable {\n\t\treturn req, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error\", err)\n}\n\nfunc canRetryError(err error) bool {\n\tif err == errClientConnUnusable || err == errClientConnGotGoAway {\n\t\treturn true\n\t}\n\tif se, ok := err.(StreamError); ok {\n\t\tif se.Code == ErrCodeProtocol && se.Cause == errFromPeer {\n\t\t\t// See golang/go#47635, golang/go#42777\n\t\t\treturn true\n\t\t}\n\t\treturn se.Code == ErrCodeRefusedStream\n\t}\n\treturn false\n}\n\nfunc (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*ClientConn, error) {\n\tif t.transportTestHooks != nil {\n\t\treturn t.newClientConn(nil, singleUse)\n\t}\n\thost, _, err := net.SplitHostPort(addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttconn, err := t.dialTLS(ctx, \"tcp\", addr, t.newTLSConfig(host))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn t.newClientConn(tconn, singleUse)\n}\n\nfunc (t *Transport) newTLSConfig(host string) *tls.Config {\n\tcfg := new(tls.Config)\n\tif t.TLSClientConfig != nil {\n\t\t*cfg = *t.TLSClientConfig.Clone()\n\t}\n\tif !strSliceContains(cfg.NextProtos, NextProtoTLS) {\n\t\tcfg.NextProtos = append([]string{NextProtoTLS}, cfg.NextProtos...)\n\t}\n\tif cfg.ServerName == \"\" {\n\t\tcfg.ServerName = host\n\t}\n\treturn cfg\n}\n\nfunc (t *Transport) dialTLS(ctx context.Context, network, addr string, tlsCfg *tls.Config) (net.Conn, error) {\n\tif t.DialTLSContext != nil {\n\t\treturn t.DialTLSContext(ctx, network, addr, tlsCfg)\n\t} else if t.DialTLS != nil {\n\t\treturn t.DialTLS(network, addr, tlsCfg)\n\t}\n\n\ttlsCn, err := t.dialTLSWithContext(ctx, network, addr, tlsCfg)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tstate := tlsCn.ConnectionState()\n\tif p := state.NegotiatedProtocol; p != NextProtoTLS {\n\t\treturn nil, fmt.Errorf(\"http2: unexpected ALPN protocol %q; want %q\", p, NextProtoTLS)\n\t}\n\tif !state.NegotiatedProtocolIsMutual {\n\t\treturn nil, errors.New(\"http2: could not negotiate protocol mutually\")\n\t}\n\treturn tlsCn, nil\n}\n\n// disableKeepAlives reports whether connections should be closed as\n// soon as possible after handling the first request.\nfunc (t *Transport) disableKeepAlives() bool {\n\treturn t.t1 != nil && t.t1.DisableKeepAlives\n}\n\nfunc (t *Transport) expectContinueTimeout() time.Duration {\n\tif t.t1 == nil {\n\t\treturn 0\n\t}\n\treturn t.t1.ExpectContinueTimeout\n}\n\nfunc (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) {\n\treturn t.newClientConn(c, t.disableKeepAlives())\n}\n\nfunc (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) {\n\tconf := configFromTransport(t)\n\tcc := &ClientConn{\n\t\tt:                           t,\n\t\ttconn:                       c,\n\t\treaderDone:                  make(chan struct{}),\n\t\tnextStreamID:                1,\n\t\tmaxFrameSize:                16 << 10, // spec default\n\t\tinitialWindowSize:           65535,    // spec default\n\t\tinitialStreamRecvWindowSize: conf.MaxUploadBufferPerStream,\n\t\tmaxConcurrentStreams:        initialMaxConcurrentStreams, // \"infinite\", per spec. Use a smaller value until we have received server settings.\n\t\tpeerMaxHeaderListSize:       0xffffffffffffffff,          // \"infinite\", per spec. Use 2^64-1 instead.\n\t\tstreams:                     make(map[uint32]*clientStream),\n\t\tsingleUse:                   singleUse,\n\t\tseenSettingsChan:            make(chan struct{}),\n\t\twantSettingsAck:             true,\n\t\treadIdleTimeout:             conf.SendPingTimeout,\n\t\tpingTimeout:                 conf.PingTimeout,\n\t\tpings:                       make(map[[8]byte]chan struct{}),\n\t\treqHeaderMu:                 make(chan struct{}, 1),\n\t\tlastActive:                  t.now(),\n\t}\n\tvar group synctestGroupInterface\n\tif t.transportTestHooks != nil {\n\t\tt.markNewGoroutine()\n\t\tt.transportTestHooks.newclientconn(cc)\n\t\tc = cc.tconn\n\t\tgroup = t.group\n\t}\n\tif VerboseLogs {\n\t\tt.vlogf(\"http2: Transport creating client conn %p to %v\", cc, c.RemoteAddr())\n\t}\n\n\tcc.cond = sync.NewCond(&cc.mu)\n\tcc.flow.add(int32(initialWindowSize))\n\n\t// TODO: adjust this writer size to account for frame size +\n\t// MTU + crypto/tls record padding.\n\tcc.bw = bufio.NewWriter(stickyErrWriter{\n\t\tgroup:   group,\n\t\tconn:    c,\n\t\ttimeout: conf.WriteByteTimeout,\n\t\terr:     &cc.werr,\n\t})\n\tcc.br = bufio.NewReader(c)\n\tcc.fr = NewFramer(cc.bw, cc.br)\n\tcc.fr.SetMaxReadFrameSize(conf.MaxReadFrameSize)\n\tif t.CountError != nil {\n\t\tcc.fr.countError = t.CountError\n\t}\n\tmaxHeaderTableSize := conf.MaxDecoderHeaderTableSize\n\tcc.fr.ReadMetaHeaders = hpack.NewDecoder(maxHeaderTableSize, nil)\n\tcc.fr.MaxHeaderListSize = t.maxHeaderListSize()\n\n\tcc.henc = hpack.NewEncoder(&cc.hbuf)\n\tcc.henc.SetMaxDynamicTableSizeLimit(conf.MaxEncoderHeaderTableSize)\n\tcc.peerMaxHeaderTableSize = initialHeaderTableSize\n\n\tif cs, ok := c.(connectionStater); ok {\n\t\tstate := cs.ConnectionState()\n\t\tcc.tlsState = &state\n\t}\n\n\tinitialSettings := []Setting{\n\t\t{ID: SettingEnablePush, Val: 0},\n\t\t{ID: SettingInitialWindowSize, Val: uint32(cc.initialStreamRecvWindowSize)},\n\t}\n\tinitialSettings = append(initialSettings, Setting{ID: SettingMaxFrameSize, Val: conf.MaxReadFrameSize})\n\tif max := t.maxHeaderListSize(); max != 0 {\n\t\tinitialSettings = append(initialSettings, Setting{ID: SettingMaxHeaderListSize, Val: max})\n\t}\n\tif maxHeaderTableSize != initialHeaderTableSize {\n\t\tinitialSettings = append(initialSettings, Setting{ID: SettingHeaderTableSize, Val: maxHeaderTableSize})\n\t}\n\n\tcc.bw.Write(clientPreface)\n\tcc.fr.WriteSettings(initialSettings...)\n\tcc.fr.WriteWindowUpdate(0, uint32(conf.MaxUploadBufferPerConnection))\n\tcc.inflow.init(conf.MaxUploadBufferPerConnection + initialWindowSize)\n\tcc.bw.Flush()\n\tif cc.werr != nil {\n\t\tcc.Close()\n\t\treturn nil, cc.werr\n\t}\n\n\t// Start the idle timer after the connection is fully initialized.\n\tif d := t.idleConnTimeout(); d != 0 {\n\t\tcc.idleTimeout = d\n\t\tcc.idleTimer = t.afterFunc(d, cc.onIdleTimeout)\n\t}\n\n\tgo cc.readLoop()\n\treturn cc, nil\n}\n\nfunc (cc *ClientConn) healthCheck() {\n\tpingTimeout := cc.pingTimeout\n\t// We don't need to periodically ping in the health check, because the readLoop of ClientConn will\n\t// trigger the healthCheck again if there is no frame received.\n\tctx, cancel := cc.t.contextWithTimeout(context.Background(), pingTimeout)\n\tdefer cancel()\n\tcc.vlogf(\"http2: Transport sending health check\")\n\terr := cc.Ping(ctx)\n\tif err != nil {\n\t\tcc.vlogf(\"http2: Transport health check failure: %v\", err)\n\t\tcc.closeForLostPing()\n\t} else {\n\t\tcc.vlogf(\"http2: Transport health check success\")\n\t}\n}\n\n// SetDoNotReuse marks cc as not reusable for future HTTP requests.\nfunc (cc *ClientConn) SetDoNotReuse() {\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\tcc.doNotReuse = true\n}\n\nfunc (cc *ClientConn) setGoAway(f *GoAwayFrame) {\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\n\told := cc.goAway\n\tcc.goAway = f\n\n\t// Merge the previous and current GoAway error frames.\n\tif cc.goAwayDebug == \"\" {\n\t\tcc.goAwayDebug = string(f.DebugData())\n\t}\n\tif old != nil && old.ErrCode != ErrCodeNo {\n\t\tcc.goAway.ErrCode = old.ErrCode\n\t}\n\tlast := f.LastStreamID\n\tfor streamID, cs := range cc.streams {\n\t\tif streamID <= last {\n\t\t\t// The server's GOAWAY indicates that it received this stream.\n\t\t\t// It will either finish processing it, or close the connection\n\t\t\t// without doing so. Either way, leave the stream alone for now.\n\t\t\tcontinue\n\t\t}\n\t\tif streamID == 1 && cc.goAway.ErrCode != ErrCodeNo {\n\t\t\t// Don't retry the first stream on a connection if we get a non-NO error.\n\t\t\t// If the server is sending an error on a new connection,\n\t\t\t// retrying the request on a new one probably isn't going to work.\n\t\t\tcs.abortStreamLocked(fmt.Errorf(\"http2: Transport received GOAWAY from server ErrCode:%v\", cc.goAway.ErrCode))\n\t\t} else {\n\t\t\t// Aborting the stream with errClentConnGotGoAway indicates that\n\t\t\t// the request should be retried on a new connection.\n\t\t\tcs.abortStreamLocked(errClientConnGotGoAway)\n\t\t}\n\t}\n}\n\n// CanTakeNewRequest reports whether the connection can take a new request,\n// meaning it has not been closed or received or sent a GOAWAY.\n//\n// If the caller is going to immediately make a new request on this\n// connection, use ReserveNewRequest instead.\nfunc (cc *ClientConn) CanTakeNewRequest() bool {\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\treturn cc.canTakeNewRequestLocked()\n}\n\n// ReserveNewRequest is like CanTakeNewRequest but also reserves a\n// concurrent stream in cc. The reservation is decremented on the\n// next call to RoundTrip.\nfunc (cc *ClientConn) ReserveNewRequest() bool {\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\tif st := cc.idleStateLocked(); !st.canTakeNewRequest {\n\t\treturn false\n\t}\n\tcc.streamsReserved++\n\treturn true\n}\n\n// ClientConnState describes the state of a ClientConn.\ntype ClientConnState struct {\n\t// Closed is whether the connection is closed.\n\tClosed bool\n\n\t// Closing is whether the connection is in the process of\n\t// closing. It may be closing due to shutdown, being a\n\t// single-use connection, being marked as DoNotReuse, or\n\t// having received a GOAWAY frame.\n\tClosing bool\n\n\t// StreamsActive is how many streams are active.\n\tStreamsActive int\n\n\t// StreamsReserved is how many streams have been reserved via\n\t// ClientConn.ReserveNewRequest.\n\tStreamsReserved int\n\n\t// StreamsPending is how many requests have been sent in excess\n\t// of the peer's advertised MaxConcurrentStreams setting and\n\t// are waiting for other streams to complete.\n\tStreamsPending int\n\n\t// MaxConcurrentStreams is how many concurrent streams the\n\t// peer advertised as acceptable. Zero means no SETTINGS\n\t// frame has been received yet.\n\tMaxConcurrentStreams uint32\n\n\t// LastIdle, if non-zero, is when the connection last\n\t// transitioned to idle state.\n\tLastIdle time.Time\n}\n\n// State returns a snapshot of cc's state.\nfunc (cc *ClientConn) State() ClientConnState {\n\tcc.wmu.Lock()\n\tmaxConcurrent := cc.maxConcurrentStreams\n\tif !cc.seenSettings {\n\t\tmaxConcurrent = 0\n\t}\n\tcc.wmu.Unlock()\n\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\treturn ClientConnState{\n\t\tClosed:               cc.closed,\n\t\tClosing:              cc.closing || cc.singleUse || cc.doNotReuse || cc.goAway != nil,\n\t\tStreamsActive:        len(cc.streams) + cc.pendingResets,\n\t\tStreamsReserved:      cc.streamsReserved,\n\t\tStreamsPending:       cc.pendingRequests,\n\t\tLastIdle:             cc.lastIdle,\n\t\tMaxConcurrentStreams: maxConcurrent,\n\t}\n}\n\n// clientConnIdleState describes the suitability of a client\n// connection to initiate a new RoundTrip request.\ntype clientConnIdleState struct {\n\tcanTakeNewRequest bool\n}\n\nfunc (cc *ClientConn) idleState() clientConnIdleState {\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\treturn cc.idleStateLocked()\n}\n\nfunc (cc *ClientConn) idleStateLocked() (st clientConnIdleState) {\n\tif cc.singleUse && cc.nextStreamID > 1 {\n\t\treturn\n\t}\n\tvar maxConcurrentOkay bool\n\tif cc.t.StrictMaxConcurrentStreams {\n\t\t// We'll tell the caller we can take a new request to\n\t\t// prevent the caller from dialing a new TCP\n\t\t// connection, but then we'll block later before\n\t\t// writing it.\n\t\tmaxConcurrentOkay = true\n\t} else {\n\t\t// We can take a new request if the total of\n\t\t//   - active streams;\n\t\t//   - reservation slots for new streams; and\n\t\t//   - streams for which we have sent a RST_STREAM and a PING,\n\t\t//     but received no subsequent frame\n\t\t// is less than the concurrency limit.\n\t\tmaxConcurrentOkay = cc.currentRequestCountLocked() < int(cc.maxConcurrentStreams)\n\t}\n\n\tst.canTakeNewRequest = cc.goAway == nil && !cc.closed && !cc.closing && maxConcurrentOkay &&\n\t\t!cc.doNotReuse &&\n\t\tint64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 &&\n\t\t!cc.tooIdleLocked()\n\n\t// If this connection has never been used for a request and is closed,\n\t// then let it take a request (which will fail).\n\t// If the conn was closed for idleness, we're racing the idle timer;\n\t// don't try to use the conn. (Issue #70515.)\n\t//\n\t// This avoids a situation where an error early in a connection's lifetime\n\t// goes unreported.\n\tif cc.nextStreamID == 1 && cc.streamsReserved == 0 && cc.closed && !cc.closedOnIdle {\n\t\tst.canTakeNewRequest = true\n\t}\n\n\treturn\n}\n\n// currentRequestCountLocked reports the number of concurrency slots currently in use,\n// including active streams, reserved slots, and reset streams waiting for acknowledgement.\nfunc (cc *ClientConn) currentRequestCountLocked() int {\n\treturn len(cc.streams) + cc.streamsReserved + cc.pendingResets\n}\n\nfunc (cc *ClientConn) canTakeNewRequestLocked() bool {\n\tst := cc.idleStateLocked()\n\treturn st.canTakeNewRequest\n}\n\n// tooIdleLocked reports whether this connection has been been sitting idle\n// for too much wall time.\nfunc (cc *ClientConn) tooIdleLocked() bool {\n\t// The Round(0) strips the monontonic clock reading so the\n\t// times are compared based on their wall time. We don't want\n\t// to reuse a connection that's been sitting idle during\n\t// VM/laptop suspend if monotonic time was also frozen.\n\treturn cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && cc.t.timeSince(cc.lastIdle.Round(0)) > cc.idleTimeout\n}\n\n// onIdleTimeout is called from a time.AfterFunc goroutine. It will\n// only be called when we're idle, but because we're coming from a new\n// goroutine, there could be a new request coming in at the same time,\n// so this simply calls the synchronized closeIfIdle to shut down this\n// connection. The timer could just call closeIfIdle, but this is more\n// clear.\nfunc (cc *ClientConn) onIdleTimeout() {\n\tcc.closeIfIdle()\n}\n\nfunc (cc *ClientConn) closeConn() {\n\tt := time.AfterFunc(250*time.Millisecond, cc.forceCloseConn)\n\tdefer t.Stop()\n\tcc.tconn.Close()\n}\n\n// A tls.Conn.Close can hang for a long time if the peer is unresponsive.\n// Try to shut it down more aggressively.\nfunc (cc *ClientConn) forceCloseConn() {\n\ttc, ok := cc.tconn.(*tls.Conn)\n\tif !ok {\n\t\treturn\n\t}\n\tif nc := tc.NetConn(); nc != nil {\n\t\tnc.Close()\n\t}\n}\n\nfunc (cc *ClientConn) closeIfIdle() {\n\tcc.mu.Lock()\n\tif len(cc.streams) > 0 || cc.streamsReserved > 0 {\n\t\tcc.mu.Unlock()\n\t\treturn\n\t}\n\tcc.closed = true\n\tcc.closedOnIdle = true\n\tnextID := cc.nextStreamID\n\t// TODO: do clients send GOAWAY too? maybe? Just Close:\n\tcc.mu.Unlock()\n\n\tif VerboseLogs {\n\t\tcc.vlogf(\"http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)\", cc, cc.singleUse, nextID-2)\n\t}\n\tcc.closeConn()\n}\n\nfunc (cc *ClientConn) isDoNotReuseAndIdle() bool {\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\treturn cc.doNotReuse && len(cc.streams) == 0\n}\n\nvar shutdownEnterWaitStateHook = func() {}\n\n// Shutdown gracefully closes the client connection, waiting for running streams to complete.\nfunc (cc *ClientConn) Shutdown(ctx context.Context) error {\n\tif err := cc.sendGoAway(); err != nil {\n\t\treturn err\n\t}\n\t// Wait for all in-flight streams to complete or connection to close\n\tdone := make(chan struct{})\n\tcancelled := false // guarded by cc.mu\n\tgo func() {\n\t\tcc.t.markNewGoroutine()\n\t\tcc.mu.Lock()\n\t\tdefer cc.mu.Unlock()\n\t\tfor {\n\t\t\tif len(cc.streams) == 0 || cc.closed {\n\t\t\t\tcc.closed = true\n\t\t\t\tclose(done)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif cancelled {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcc.cond.Wait()\n\t\t}\n\t}()\n\tshutdownEnterWaitStateHook()\n\tselect {\n\tcase <-done:\n\t\tcc.closeConn()\n\t\treturn nil\n\tcase <-ctx.Done():\n\t\tcc.mu.Lock()\n\t\t// Free the goroutine above\n\t\tcancelled = true\n\t\tcc.cond.Broadcast()\n\t\tcc.mu.Unlock()\n\t\treturn ctx.Err()\n\t}\n}\n\nfunc (cc *ClientConn) sendGoAway() error {\n\tcc.mu.Lock()\n\tclosing := cc.closing\n\tcc.closing = true\n\tmaxStreamID := cc.nextStreamID\n\tcc.mu.Unlock()\n\tif closing {\n\t\t// GOAWAY sent already\n\t\treturn nil\n\t}\n\n\tcc.wmu.Lock()\n\tdefer cc.wmu.Unlock()\n\t// Send a graceful shutdown frame to server\n\tif err := cc.fr.WriteGoAway(maxStreamID, ErrCodeNo, nil); err != nil {\n\t\treturn err\n\t}\n\tif err := cc.bw.Flush(); err != nil {\n\t\treturn err\n\t}\n\t// Prevent new requests\n\treturn nil\n}\n\n// closes the client connection immediately. In-flight requests are interrupted.\n// err is sent to streams.\nfunc (cc *ClientConn) closeForError(err error) {\n\tcc.mu.Lock()\n\tcc.closed = true\n\tfor _, cs := range cc.streams {\n\t\tcs.abortStreamLocked(err)\n\t}\n\tcc.cond.Broadcast()\n\tcc.mu.Unlock()\n\tcc.closeConn()\n}\n\n// Close closes the client connection immediately.\n//\n// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.\nfunc (cc *ClientConn) Close() error {\n\terr := errors.New(\"http2: client connection force closed via ClientConn.Close\")\n\tcc.closeForError(err)\n\treturn nil\n}\n\n// closes the client connection immediately. In-flight requests are interrupted.\nfunc (cc *ClientConn) closeForLostPing() {\n\terr := errors.New(\"http2: client connection lost\")\n\tif f := cc.t.CountError; f != nil {\n\t\tf(\"conn_close_lost_ping\")\n\t}\n\tcc.closeForError(err)\n}\n\n// errRequestCanceled is a copy of net/http's errRequestCanceled because it's not\n// exported. At least they'll be DeepEqual for h1-vs-h2 comparisons tests.\nvar errRequestCanceled = errors.New(\"net/http: request canceled\")\n\nfunc (cc *ClientConn) responseHeaderTimeout() time.Duration {\n\tif cc.t.t1 != nil {\n\t\treturn cc.t.t1.ResponseHeaderTimeout\n\t}\n\t// No way to do this (yet?) with just an http2.Transport. Probably\n\t// no need. Request.Cancel this is the new way. We only need to support\n\t// this for compatibility with the old http.Transport fields when\n\t// we're doing transparent http2.\n\treturn 0\n}\n\n// actualContentLength returns a sanitized version of\n// req.ContentLength, where 0 actually means zero (not unknown) and -1\n// means unknown.\nfunc actualContentLength(req *http.Request) int64 {\n\tif req.Body == nil || req.Body == http.NoBody {\n\t\treturn 0\n\t}\n\tif req.ContentLength != 0 {\n\t\treturn req.ContentLength\n\t}\n\treturn -1\n}\n\nfunc (cc *ClientConn) decrStreamReservations() {\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\tcc.decrStreamReservationsLocked()\n}\n\nfunc (cc *ClientConn) decrStreamReservationsLocked() {\n\tif cc.streamsReserved > 0 {\n\t\tcc.streamsReserved--\n\t}\n}\n\nfunc (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {\n\treturn cc.roundTrip(req, nil)\n}\n\nfunc (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) (*http.Response, error) {\n\tctx := req.Context()\n\tcs := &clientStream{\n\t\tcc:                   cc,\n\t\tctx:                  ctx,\n\t\treqCancel:            req.Cancel,\n\t\tisHead:               req.Method == \"HEAD\",\n\t\treqBody:              req.Body,\n\t\treqBodyContentLength: actualContentLength(req),\n\t\ttrace:                httptrace.ContextClientTrace(ctx),\n\t\tpeerClosed:           make(chan struct{}),\n\t\tabort:                make(chan struct{}),\n\t\trespHeaderRecv:       make(chan struct{}),\n\t\tdonec:                make(chan struct{}),\n\t}\n\n\tcs.requestedGzip = httpcommon.IsRequestGzip(req.Method, req.Header, cc.t.disableCompression())\n\n\tgo cs.doRequest(req, streamf)\n\n\twaitDone := func() error {\n\t\tselect {\n\t\tcase <-cs.donec:\n\t\t\treturn nil\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tcase <-cs.reqCancel:\n\t\t\treturn errRequestCanceled\n\t\t}\n\t}\n\n\thandleResponseHeaders := func() (*http.Response, error) {\n\t\tres := cs.res\n\t\tif res.StatusCode > 299 {\n\t\t\t// On error or status code 3xx, 4xx, 5xx, etc abort any\n\t\t\t// ongoing write, assuming that the server doesn't care\n\t\t\t// about our request body. If the server replied with 1xx or\n\t\t\t// 2xx, however, then assume the server DOES potentially\n\t\t\t// want our body (e.g. full-duplex streaming:\n\t\t\t// golang.org/issue/13444). If it turns out the server\n\t\t\t// doesn't, they'll RST_STREAM us soon enough. This is a\n\t\t\t// heuristic to avoid adding knobs to Transport. Hopefully\n\t\t\t// we can keep it.\n\t\t\tcs.abortRequestBodyWrite()\n\t\t}\n\t\tres.Request = req\n\t\tres.TLS = cc.tlsState\n\t\tif res.Body == noBody && actualContentLength(req) == 0 {\n\t\t\t// If there isn't a request or response body still being\n\t\t\t// written, then wait for the stream to be closed before\n\t\t\t// RoundTrip returns.\n\t\t\tif err := waitDone(); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\treturn res, nil\n\t}\n\n\tcancelRequest := func(cs *clientStream, err error) error {\n\t\tcs.cc.mu.Lock()\n\t\tbodyClosed := cs.reqBodyClosed\n\t\tcs.cc.mu.Unlock()\n\t\t// Wait for the request body to be closed.\n\t\t//\n\t\t// If nothing closed the body before now, abortStreamLocked\n\t\t// will have started a goroutine to close it.\n\t\t//\n\t\t// Closing the body before returning avoids a race condition\n\t\t// with net/http checking its readTrackingBody to see if the\n\t\t// body was read from or closed. See golang/go#60041.\n\t\t//\n\t\t// The body is closed in a separate goroutine without the\n\t\t// connection mutex held, but dropping the mutex before waiting\n\t\t// will keep us from holding it indefinitely if the body\n\t\t// close is slow for some reason.\n\t\tif bodyClosed != nil {\n\t\t\t<-bodyClosed\n\t\t}\n\t\treturn err\n\t}\n\n\tfor {\n\t\tselect {\n\t\tcase <-cs.respHeaderRecv:\n\t\t\treturn handleResponseHeaders()\n\t\tcase <-cs.abort:\n\t\t\tselect {\n\t\t\tcase <-cs.respHeaderRecv:\n\t\t\t\t// If both cs.respHeaderRecv and cs.abort are signaling,\n\t\t\t\t// pick respHeaderRecv. The server probably wrote the\n\t\t\t\t// response and immediately reset the stream.\n\t\t\t\t// golang.org/issue/49645\n\t\t\t\treturn handleResponseHeaders()\n\t\t\tdefault:\n\t\t\t\twaitDone()\n\t\t\t\treturn nil, cs.abortErr\n\t\t\t}\n\t\tcase <-ctx.Done():\n\t\t\terr := ctx.Err()\n\t\t\tcs.abortStream(err)\n\t\t\treturn nil, cancelRequest(cs, err)\n\t\tcase <-cs.reqCancel:\n\t\t\tcs.abortStream(errRequestCanceled)\n\t\t\treturn nil, cancelRequest(cs, errRequestCanceled)\n\t\t}\n\t}\n}\n\n// doRequest runs for the duration of the request lifetime.\n//\n// It sends the request and performs post-request cleanup (closing Request.Body, etc.).\nfunc (cs *clientStream) doRequest(req *http.Request, streamf func(*clientStream)) {\n\tcs.cc.t.markNewGoroutine()\n\terr := cs.writeRequest(req, streamf)\n\tcs.cleanupWriteRequest(err)\n}\n\nvar errExtendedConnectNotSupported = errors.New(\"net/http: extended connect not supported by peer\")\n\n// writeRequest sends a request.\n//\n// It returns nil after the request is written, the response read,\n// and the request stream is half-closed by the peer.\n//\n// It returns non-nil if the request ends otherwise.\n// If the returned error is StreamError, the error Code may be used in resetting the stream.\nfunc (cs *clientStream) writeRequest(req *http.Request, streamf func(*clientStream)) (err error) {\n\tcc := cs.cc\n\tctx := cs.ctx\n\n\t// wait for setting frames to be received, a server can change this value later,\n\t// but we just wait for the first settings frame\n\tvar isExtendedConnect bool\n\tif req.Method == \"CONNECT\" && req.Header.Get(\":protocol\") != \"\" {\n\t\tisExtendedConnect = true\n\t}\n\n\t// Acquire the new-request lock by writing to reqHeaderMu.\n\t// This lock guards the critical section covering allocating a new stream ID\n\t// (requires mu) and creating the stream (requires wmu).\n\tif cc.reqHeaderMu == nil {\n\t\tpanic(\"RoundTrip on uninitialized ClientConn\") // for tests\n\t}\n\tif isExtendedConnect {\n\t\tselect {\n\t\tcase <-cs.reqCancel:\n\t\t\treturn errRequestCanceled\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tcase <-cc.seenSettingsChan:\n\t\t\tif !cc.extendedConnectAllowed {\n\t\t\t\treturn errExtendedConnectNotSupported\n\t\t\t}\n\t\t}\n\t}\n\tselect {\n\tcase cc.reqHeaderMu <- struct{}{}:\n\tcase <-cs.reqCancel:\n\t\treturn errRequestCanceled\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\t}\n\n\tcc.mu.Lock()\n\tif cc.idleTimer != nil {\n\t\tcc.idleTimer.Stop()\n\t}\n\tcc.decrStreamReservationsLocked()\n\tif err := cc.awaitOpenSlotForStreamLocked(cs); err != nil {\n\t\tcc.mu.Unlock()\n\t\t<-cc.reqHeaderMu\n\t\treturn err\n\t}\n\tcc.addStreamLocked(cs) // assigns stream ID\n\tif isConnectionCloseRequest(req) {\n\t\tcc.doNotReuse = true\n\t}\n\tcc.mu.Unlock()\n\n\tif streamf != nil {\n\t\tstreamf(cs)\n\t}\n\n\tcontinueTimeout := cc.t.expectContinueTimeout()\n\tif continueTimeout != 0 {\n\t\tif !httpguts.HeaderValuesContainsToken(req.Header[\"Expect\"], \"100-continue\") {\n\t\t\tcontinueTimeout = 0\n\t\t} else {\n\t\t\tcs.on100 = make(chan struct{}, 1)\n\t\t}\n\t}\n\n\t// Past this point (where we send request headers), it is possible for\n\t// RoundTrip to return successfully. Since the RoundTrip contract permits\n\t// the caller to \"mutate or reuse\" the Request after closing the Response's Body,\n\t// we must take care when referencing the Request from here on.\n\terr = cs.encodeAndWriteHeaders(req)\n\t<-cc.reqHeaderMu\n\tif err != nil {\n\t\treturn err\n\t}\n\n\thasBody := cs.reqBodyContentLength != 0\n\tif !hasBody {\n\t\tcs.sentEndStream = true\n\t} else {\n\t\tif continueTimeout != 0 {\n\t\t\ttraceWait100Continue(cs.trace)\n\t\t\ttimer := time.NewTimer(continueTimeout)\n\t\t\tselect {\n\t\t\tcase <-timer.C:\n\t\t\t\terr = nil\n\t\t\tcase <-cs.on100:\n\t\t\t\terr = nil\n\t\t\tcase <-cs.abort:\n\t\t\t\terr = cs.abortErr\n\t\t\tcase <-ctx.Done():\n\t\t\t\terr = ctx.Err()\n\t\t\tcase <-cs.reqCancel:\n\t\t\t\terr = errRequestCanceled\n\t\t\t}\n\t\t\ttimer.Stop()\n\t\t\tif err != nil {\n\t\t\t\ttraceWroteRequest(cs.trace, err)\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tif err = cs.writeRequestBody(req); err != nil {\n\t\t\tif err != errStopReqBodyWrite {\n\t\t\t\ttraceWroteRequest(cs.trace, err)\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\tcs.sentEndStream = true\n\t\t}\n\t}\n\n\ttraceWroteRequest(cs.trace, err)\n\n\tvar respHeaderTimer <-chan time.Time\n\tvar respHeaderRecv chan struct{}\n\tif d := cc.responseHeaderTimeout(); d != 0 {\n\t\ttimer := cc.t.newTimer(d)\n\t\tdefer timer.Stop()\n\t\trespHeaderTimer = timer.C()\n\t\trespHeaderRecv = cs.respHeaderRecv\n\t}\n\t// Wait until the peer half-closes its end of the stream,\n\t// or until the request is aborted (via context, error, or otherwise),\n\t// whichever comes first.\n\tfor {\n\t\tselect {\n\t\tcase <-cs.peerClosed:\n\t\t\treturn nil\n\t\tcase <-respHeaderTimer:\n\t\t\treturn errTimeout\n\t\tcase <-respHeaderRecv:\n\t\t\trespHeaderRecv = nil\n\t\t\trespHeaderTimer = nil // keep waiting for END_STREAM\n\t\tcase <-cs.abort:\n\t\t\treturn cs.abortErr\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tcase <-cs.reqCancel:\n\t\t\treturn errRequestCanceled\n\t\t}\n\t}\n}\n\nfunc (cs *clientStream) encodeAndWriteHeaders(req *http.Request) error {\n\tcc := cs.cc\n\tctx := cs.ctx\n\n\tcc.wmu.Lock()\n\tdefer cc.wmu.Unlock()\n\n\t// If the request was canceled while waiting for cc.mu, just quit.\n\tselect {\n\tcase <-cs.abort:\n\t\treturn cs.abortErr\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\tcase <-cs.reqCancel:\n\t\treturn errRequestCanceled\n\tdefault:\n\t}\n\n\t// Encode headers.\n\t//\n\t// we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is\n\t// sent by writeRequestBody below, along with any Trailers,\n\t// again in form HEADERS{1}, CONTINUATION{0,})\n\tcc.hbuf.Reset()\n\tres, err := encodeRequestHeaders(req, cs.requestedGzip, cc.peerMaxHeaderListSize, func(name, value string) {\n\t\tcc.writeHeader(name, value)\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"http2: %w\", err)\n\t}\n\thdrs := cc.hbuf.Bytes()\n\n\t// Write the request.\n\tendStream := !res.HasBody && !res.HasTrailers\n\tcs.sentHeaders = true\n\terr = cc.writeHeaders(cs.ID, endStream, int(cc.maxFrameSize), hdrs)\n\ttraceWroteHeaders(cs.trace)\n\treturn err\n}\n\nfunc encodeRequestHeaders(req *http.Request, addGzipHeader bool, peerMaxHeaderListSize uint64, headerf func(name, value string)) (httpcommon.EncodeHeadersResult, error) {\n\treturn httpcommon.EncodeHeaders(req.Context(), httpcommon.EncodeHeadersParam{\n\t\tRequest: httpcommon.Request{\n\t\t\tHeader:              req.Header,\n\t\t\tTrailer:             req.Trailer,\n\t\t\tURL:                 req.URL,\n\t\t\tHost:                req.Host,\n\t\t\tMethod:              req.Method,\n\t\t\tActualContentLength: actualContentLength(req),\n\t\t},\n\t\tAddGzipHeader:         addGzipHeader,\n\t\tPeerMaxHeaderListSize: peerMaxHeaderListSize,\n\t\tDefaultUserAgent:      defaultUserAgent,\n\t}, headerf)\n}\n\n// cleanupWriteRequest performs post-request tasks.\n//\n// If err (the result of writeRequest) is non-nil and the stream is not closed,\n// cleanupWriteRequest will send a reset to the peer.\nfunc (cs *clientStream) cleanupWriteRequest(err error) {\n\tcc := cs.cc\n\n\tif cs.ID == 0 {\n\t\t// We were canceled before creating the stream, so return our reservation.\n\t\tcc.decrStreamReservations()\n\t}\n\n\t// TODO: write h12Compare test showing whether\n\t// Request.Body is closed by the Transport,\n\t// and in multiple cases: server replies <=299 and >299\n\t// while still writing request body\n\tcc.mu.Lock()\n\tmustCloseBody := false\n\tif cs.reqBody != nil && cs.reqBodyClosed == nil {\n\t\tmustCloseBody = true\n\t\tcs.reqBodyClosed = make(chan struct{})\n\t}\n\tbodyClosed := cs.reqBodyClosed\n\tcloseOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil\n\tcc.mu.Unlock()\n\tif mustCloseBody {\n\t\tcs.reqBody.Close()\n\t\tclose(bodyClosed)\n\t}\n\tif bodyClosed != nil {\n\t\t<-bodyClosed\n\t}\n\n\tif err != nil && cs.sentEndStream {\n\t\t// If the connection is closed immediately after the response is read,\n\t\t// we may be aborted before finishing up here. If the stream was closed\n\t\t// cleanly on both sides, there is no error.\n\t\tselect {\n\t\tcase <-cs.peerClosed:\n\t\t\terr = nil\n\t\tdefault:\n\t\t}\n\t}\n\tif err != nil {\n\t\tcs.abortStream(err) // possibly redundant, but harmless\n\t\tif cs.sentHeaders {\n\t\t\tif se, ok := err.(StreamError); ok {\n\t\t\t\tif se.Cause != errFromPeer {\n\t\t\t\t\tcc.writeStreamReset(cs.ID, se.Code, false, err)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We're cancelling an in-flight request.\n\t\t\t\t//\n\t\t\t\t// This could be due to the server becoming unresponsive.\n\t\t\t\t// To avoid sending too many requests on a dead connection,\n\t\t\t\t// we let the request continue to consume a concurrency slot\n\t\t\t\t// until we can confirm the server is still responding.\n\t\t\t\t// We do this by sending a PING frame along with the RST_STREAM\n\t\t\t\t// (unless a ping is already in flight).\n\t\t\t\t//\n\t\t\t\t// For simplicity, we don't bother tracking the PING payload:\n\t\t\t\t// We reset cc.pendingResets any time we receive a PING ACK.\n\t\t\t\t//\n\t\t\t\t// We skip this if the conn is going to be closed on idle,\n\t\t\t\t// because it's short lived and will probably be closed before\n\t\t\t\t// we get the ping response.\n\t\t\t\tping := false\n\t\t\t\tif !closeOnIdle {\n\t\t\t\t\tcc.mu.Lock()\n\t\t\t\t\t// rstStreamPingsBlocked works around a gRPC behavior:\n\t\t\t\t\t// see comment on the field for details.\n\t\t\t\t\tif !cc.rstStreamPingsBlocked {\n\t\t\t\t\t\tif cc.pendingResets == 0 {\n\t\t\t\t\t\t\tping = true\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcc.pendingResets++\n\t\t\t\t\t}\n\t\t\t\t\tcc.mu.Unlock()\n\t\t\t\t}\n\t\t\t\tcc.writeStreamReset(cs.ID, ErrCodeCancel, ping, err)\n\t\t\t}\n\t\t}\n\t\tcs.bufPipe.CloseWithError(err) // no-op if already closed\n\t} else {\n\t\tif cs.sentHeaders && !cs.sentEndStream {\n\t\t\tcc.writeStreamReset(cs.ID, ErrCodeNo, false, nil)\n\t\t}\n\t\tcs.bufPipe.CloseWithError(errRequestCanceled)\n\t}\n\tif cs.ID != 0 {\n\t\tcc.forgetStreamID(cs.ID)\n\t}\n\n\tcc.wmu.Lock()\n\twerr := cc.werr\n\tcc.wmu.Unlock()\n\tif werr != nil {\n\t\tcc.Close()\n\t}\n\n\tclose(cs.donec)\n}\n\n// awaitOpenSlotForStreamLocked waits until len(streams) < maxConcurrentStreams.\n// Must hold cc.mu.\nfunc (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error {\n\tfor {\n\t\tif cc.closed && cc.nextStreamID == 1 && cc.streamsReserved == 0 {\n\t\t\t// This is the very first request sent to this connection.\n\t\t\t// Return a fatal error which aborts the retry loop.\n\t\t\treturn errClientConnNotEstablished\n\t\t}\n\t\tcc.lastActive = cc.t.now()\n\t\tif cc.closed || !cc.canTakeNewRequestLocked() {\n\t\t\treturn errClientConnUnusable\n\t\t}\n\t\tcc.lastIdle = time.Time{}\n\t\tif cc.currentRequestCountLocked() < int(cc.maxConcurrentStreams) {\n\t\t\treturn nil\n\t\t}\n\t\tcc.pendingRequests++\n\t\tcc.cond.Wait()\n\t\tcc.pendingRequests--\n\t\tselect {\n\t\tcase <-cs.abort:\n\t\t\treturn cs.abortErr\n\t\tdefault:\n\t\t}\n\t}\n}\n\n// requires cc.wmu be held\nfunc (cc *ClientConn) writeHeaders(streamID uint32, endStream bool, maxFrameSize int, hdrs []byte) error {\n\tfirst := true // first frame written (HEADERS is first, then CONTINUATION)\n\tfor len(hdrs) > 0 && cc.werr == nil {\n\t\tchunk := hdrs\n\t\tif len(chunk) > maxFrameSize {\n\t\t\tchunk = chunk[:maxFrameSize]\n\t\t}\n\t\thdrs = hdrs[len(chunk):]\n\t\tendHeaders := len(hdrs) == 0\n\t\tif first {\n\t\t\tcc.fr.WriteHeaders(HeadersFrameParam{\n\t\t\t\tStreamID:      streamID,\n\t\t\t\tBlockFragment: chunk,\n\t\t\t\tEndStream:     endStream,\n\t\t\t\tEndHeaders:    endHeaders,\n\t\t\t})\n\t\t\tfirst = false\n\t\t} else {\n\t\t\tcc.fr.WriteContinuation(streamID, endHeaders, chunk)\n\t\t}\n\t}\n\tcc.bw.Flush()\n\treturn cc.werr\n}\n\n// internal error values; they don't escape to callers\nvar (\n\t// abort request body write; don't send cancel\n\terrStopReqBodyWrite = errors.New(\"http2: aborting request body write\")\n\n\t// abort request body write, but send stream reset of cancel.\n\terrStopReqBodyWriteAndCancel = errors.New(\"http2: canceling request\")\n\n\terrReqBodyTooLong = errors.New(\"http2: request body larger than specified content length\")\n)\n\n// frameScratchBufferLen returns the length of a buffer to use for\n// outgoing request bodies to read/write to/from.\n//\n// It returns max(1, min(peer's advertised max frame size,\n// Request.ContentLength+1, 512KB)).\nfunc (cs *clientStream) frameScratchBufferLen(maxFrameSize int) int {\n\tconst max = 512 << 10\n\tn := int64(maxFrameSize)\n\tif n > max {\n\t\tn = max\n\t}\n\tif cl := cs.reqBodyContentLength; cl != -1 && cl+1 < n {\n\t\t// Add an extra byte past the declared content-length to\n\t\t// give the caller's Request.Body io.Reader a chance to\n\t\t// give us more bytes than they declared, so we can catch it\n\t\t// early.\n\t\tn = cl + 1\n\t}\n\tif n < 1 {\n\t\treturn 1\n\t}\n\treturn int(n) // doesn't truncate; max is 512K\n}\n\n// Seven bufPools manage different frame sizes. This helps to avoid scenarios where long-running\n// streaming requests using small frame sizes occupy large buffers initially allocated for prior\n// requests needing big buffers. The size ranges are as follows:\n// {0 KB, 16 KB], {16 KB, 32 KB], {32 KB, 64 KB], {64 KB, 128 KB], {128 KB, 256 KB],\n// {256 KB, 512 KB], {512 KB, infinity}\n// In practice, the maximum scratch buffer size should not exceed 512 KB due to\n// frameScratchBufferLen(maxFrameSize), thus the \"infinity pool\" should never be used.\n// It exists mainly as a safety measure, for potential future increases in max buffer size.\nvar bufPools [7]sync.Pool // of *[]byte\nfunc bufPoolIndex(size int) int {\n\tif size <= 16384 {\n\t\treturn 0\n\t}\n\tsize -= 1\n\tbits := bits.Len(uint(size))\n\tindex := bits - 14\n\tif index >= len(bufPools) {\n\t\treturn len(bufPools) - 1\n\t}\n\treturn index\n}\n\nfunc (cs *clientStream) writeRequestBody(req *http.Request) (err error) {\n\tcc := cs.cc\n\tbody := cs.reqBody\n\tsentEnd := false // whether we sent the final DATA frame w/ END_STREAM\n\n\thasTrailers := req.Trailer != nil\n\tremainLen := cs.reqBodyContentLength\n\thasContentLen := remainLen != -1\n\n\tcc.mu.Lock()\n\tmaxFrameSize := int(cc.maxFrameSize)\n\tcc.mu.Unlock()\n\n\t// Scratch buffer for reading into & writing from.\n\tscratchLen := cs.frameScratchBufferLen(maxFrameSize)\n\tvar buf []byte\n\tindex := bufPoolIndex(scratchLen)\n\tif bp, ok := bufPools[index].Get().(*[]byte); ok && len(*bp) >= scratchLen {\n\t\tdefer bufPools[index].Put(bp)\n\t\tbuf = *bp\n\t} else {\n\t\tbuf = make([]byte, scratchLen)\n\t\tdefer bufPools[index].Put(&buf)\n\t}\n\n\tvar sawEOF bool\n\tfor !sawEOF {\n\t\tn, err := body.Read(buf)\n\t\tif hasContentLen {\n\t\t\tremainLen -= int64(n)\n\t\t\tif remainLen == 0 && err == nil {\n\t\t\t\t// The request body's Content-Length was predeclared and\n\t\t\t\t// we just finished reading it all, but the underlying io.Reader\n\t\t\t\t// returned the final chunk with a nil error (which is one of\n\t\t\t\t// the two valid things a Reader can do at EOF). Because we'd prefer\n\t\t\t\t// to send the END_STREAM bit early, double-check that we're actually\n\t\t\t\t// at EOF. Subsequent reads should return (0, EOF) at this point.\n\t\t\t\t// If either value is different, we return an error in one of two ways below.\n\t\t\t\tvar scratch [1]byte\n\t\t\t\tvar n1 int\n\t\t\t\tn1, err = body.Read(scratch[:])\n\t\t\t\tremainLen -= int64(n1)\n\t\t\t}\n\t\t\tif remainLen < 0 {\n\t\t\t\terr = errReqBodyTooLong\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif err != nil {\n\t\t\tcc.mu.Lock()\n\t\t\tbodyClosed := cs.reqBodyClosed != nil\n\t\t\tcc.mu.Unlock()\n\t\t\tswitch {\n\t\t\tcase bodyClosed:\n\t\t\t\treturn errStopReqBodyWrite\n\t\t\tcase err == io.EOF:\n\t\t\t\tsawEOF = true\n\t\t\t\terr = nil\n\t\t\tdefault:\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tremain := buf[:n]\n\t\tfor len(remain) > 0 && err == nil {\n\t\t\tvar allowed int32\n\t\t\tallowed, err = cs.awaitFlowControl(len(remain))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcc.wmu.Lock()\n\t\t\tdata := remain[:allowed]\n\t\t\tremain = remain[allowed:]\n\t\t\tsentEnd = sawEOF && len(remain) == 0 && !hasTrailers\n\t\t\terr = cc.fr.WriteData(cs.ID, sentEnd, data)\n\t\t\tif err == nil {\n\t\t\t\t// TODO(bradfitz): this flush is for latency, not bandwidth.\n\t\t\t\t// Most requests won't need this. Make this opt-in or\n\t\t\t\t// opt-out?  Use some heuristic on the body type? Nagel-like\n\t\t\t\t// timers?  Based on 'n'? Only last chunk of this for loop,\n\t\t\t\t// unless flow control tokens are low? For now, always.\n\t\t\t\t// If we change this, see comment below.\n\t\t\t\terr = cc.bw.Flush()\n\t\t\t}\n\t\t\tcc.wmu.Unlock()\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif sentEnd {\n\t\t// Already sent END_STREAM (which implies we have no\n\t\t// trailers) and flushed, because currently all\n\t\t// WriteData frames above get a flush. So we're done.\n\t\treturn nil\n\t}\n\n\t// Since the RoundTrip contract permits the caller to \"mutate or reuse\"\n\t// a request after the Response's Body is closed, verify that this hasn't\n\t// happened before accessing the trailers.\n\tcc.mu.Lock()\n\ttrailer := req.Trailer\n\terr = cs.abortErr\n\tcc.mu.Unlock()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcc.wmu.Lock()\n\tdefer cc.wmu.Unlock()\n\tvar trls []byte\n\tif len(trailer) > 0 {\n\t\ttrls, err = cc.encodeTrailers(trailer)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// Two ways to send END_STREAM: either with trailers, or\n\t// with an empty DATA frame.\n\tif len(trls) > 0 {\n\t\terr = cc.writeHeaders(cs.ID, true, maxFrameSize, trls)\n\t} else {\n\t\terr = cc.fr.WriteData(cs.ID, true, nil)\n\t}\n\tif ferr := cc.bw.Flush(); ferr != nil && err == nil {\n\t\terr = ferr\n\t}\n\treturn err\n}\n\n// awaitFlowControl waits for [1, min(maxBytes, cc.cs.maxFrameSize)] flow\n// control tokens from the server.\n// It returns either the non-zero number of tokens taken or an error\n// if the stream is dead.\nfunc (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) {\n\tcc := cs.cc\n\tctx := cs.ctx\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\tfor {\n\t\tif cc.closed {\n\t\t\treturn 0, errClientConnClosed\n\t\t}\n\t\tif cs.reqBodyClosed != nil {\n\t\t\treturn 0, errStopReqBodyWrite\n\t\t}\n\t\tselect {\n\t\tcase <-cs.abort:\n\t\t\treturn 0, cs.abortErr\n\t\tcase <-ctx.Done():\n\t\t\treturn 0, ctx.Err()\n\t\tcase <-cs.reqCancel:\n\t\t\treturn 0, errRequestCanceled\n\t\tdefault:\n\t\t}\n\t\tif a := cs.flow.available(); a > 0 {\n\t\t\ttake := a\n\t\t\tif int(take) > maxBytes {\n\n\t\t\t\ttake = int32(maxBytes) // can't truncate int; take is int32\n\t\t\t}\n\t\t\tif take > int32(cc.maxFrameSize) {\n\t\t\t\ttake = int32(cc.maxFrameSize)\n\t\t\t}\n\t\t\tcs.flow.take(take)\n\t\t\treturn take, nil\n\t\t}\n\t\tcc.cond.Wait()\n\t}\n}\n\n// requires cc.wmu be held.\nfunc (cc *ClientConn) encodeTrailers(trailer http.Header) ([]byte, error) {\n\tcc.hbuf.Reset()\n\n\thlSize := uint64(0)\n\tfor k, vv := range trailer {\n\t\tfor _, v := range vv {\n\t\t\thf := hpack.HeaderField{Name: k, Value: v}\n\t\t\thlSize += uint64(hf.Size())\n\t\t}\n\t}\n\tif hlSize > cc.peerMaxHeaderListSize {\n\t\treturn nil, errRequestHeaderListSize\n\t}\n\n\tfor k, vv := range trailer {\n\t\tlowKey, ascii := httpcommon.LowerHeader(k)\n\t\tif !ascii {\n\t\t\t// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header\n\t\t\t// field names have to be ASCII characters (just as in HTTP/1.x).\n\t\t\tcontinue\n\t\t}\n\t\t// Transfer-Encoding, etc.. have already been filtered at the\n\t\t// start of RoundTrip\n\t\tfor _, v := range vv {\n\t\t\tcc.writeHeader(lowKey, v)\n\t\t}\n\t}\n\treturn cc.hbuf.Bytes(), nil\n}\n\nfunc (cc *ClientConn) writeHeader(name, value string) {\n\tif VerboseLogs {\n\t\tlog.Printf(\"http2: Transport encoding header %q = %q\", name, value)\n\t}\n\tcc.henc.WriteField(hpack.HeaderField{Name: name, Value: value})\n}\n\ntype resAndError struct {\n\t_   incomparable\n\tres *http.Response\n\terr error\n}\n\n// requires cc.mu be held.\nfunc (cc *ClientConn) addStreamLocked(cs *clientStream) {\n\tcs.flow.add(int32(cc.initialWindowSize))\n\tcs.flow.setConnFlow(&cc.flow)\n\tcs.inflow.init(cc.initialStreamRecvWindowSize)\n\tcs.ID = cc.nextStreamID\n\tcc.nextStreamID += 2\n\tcc.streams[cs.ID] = cs\n\tif cs.ID == 0 {\n\t\tpanic(\"assigned stream ID 0\")\n\t}\n}\n\nfunc (cc *ClientConn) forgetStreamID(id uint32) {\n\tcc.mu.Lock()\n\tslen := len(cc.streams)\n\tdelete(cc.streams, id)\n\tif len(cc.streams) != slen-1 {\n\t\tpanic(\"forgetting unknown stream id\")\n\t}\n\tcc.lastActive = cc.t.now()\n\tif len(cc.streams) == 0 && cc.idleTimer != nil {\n\t\tcc.idleTimer.Reset(cc.idleTimeout)\n\t\tcc.lastIdle = cc.t.now()\n\t}\n\t// Wake up writeRequestBody via clientStream.awaitFlowControl and\n\t// wake up RoundTrip if there is a pending request.\n\tcc.cond.Broadcast()\n\n\tcloseOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil\n\tif closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 {\n\t\tif VerboseLogs {\n\t\t\tcc.vlogf(\"http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)\", cc, cc.singleUse, cc.nextStreamID-2)\n\t\t}\n\t\tcc.closed = true\n\t\tdefer cc.closeConn()\n\t}\n\n\tcc.mu.Unlock()\n}\n\n// clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop.\ntype clientConnReadLoop struct {\n\t_  incomparable\n\tcc *ClientConn\n}\n\n// readLoop runs in its own goroutine and reads and dispatches frames.\nfunc (cc *ClientConn) readLoop() {\n\tcc.t.markNewGoroutine()\n\trl := &clientConnReadLoop{cc: cc}\n\tdefer rl.cleanup()\n\tcc.readerErr = rl.run()\n\tif ce, ok := cc.readerErr.(ConnectionError); ok {\n\t\tcc.wmu.Lock()\n\t\tcc.fr.WriteGoAway(0, ErrCode(ce), nil)\n\t\tcc.wmu.Unlock()\n\t}\n}\n\n// GoAwayError is returned by the Transport when the server closes the\n// TCP connection after sending a GOAWAY frame.\ntype GoAwayError struct {\n\tLastStreamID uint32\n\tErrCode      ErrCode\n\tDebugData    string\n}\n\nfunc (e GoAwayError) Error() string {\n\treturn fmt.Sprintf(\"http2: server sent GOAWAY and closed the connection; LastStreamID=%v, ErrCode=%v, debug=%q\",\n\t\te.LastStreamID, e.ErrCode, e.DebugData)\n}\n\nfunc isEOFOrNetReadError(err error) bool {\n\tif err == io.EOF {\n\t\treturn true\n\t}\n\tne, ok := err.(*net.OpError)\n\treturn ok && ne.Op == \"read\"\n}\n\nfunc (rl *clientConnReadLoop) cleanup() {\n\tcc := rl.cc\n\tdefer cc.closeConn()\n\tdefer close(cc.readerDone)\n\n\tif cc.idleTimer != nil {\n\t\tcc.idleTimer.Stop()\n\t}\n\n\t// Close any response bodies if the server closes prematurely.\n\t// TODO: also do this if we've written the headers but not\n\t// gotten a response yet.\n\terr := cc.readerErr\n\tcc.mu.Lock()\n\tif cc.goAway != nil && isEOFOrNetReadError(err) {\n\t\terr = GoAwayError{\n\t\t\tLastStreamID: cc.goAway.LastStreamID,\n\t\t\tErrCode:      cc.goAway.ErrCode,\n\t\t\tDebugData:    cc.goAwayDebug,\n\t\t}\n\t} else if err == io.EOF {\n\t\terr = io.ErrUnexpectedEOF\n\t}\n\tcc.closed = true\n\n\t// If the connection has never been used, and has been open for only a short time,\n\t// leave it in the connection pool for a little while.\n\t//\n\t// This avoids a situation where new connections are constantly created,\n\t// added to the pool, fail, and are removed from the pool, without any error\n\t// being surfaced to the user.\n\tunusedWaitTime := 5 * time.Second\n\tif cc.idleTimeout > 0 && unusedWaitTime > cc.idleTimeout {\n\t\tunusedWaitTime = cc.idleTimeout\n\t}\n\tidleTime := cc.t.now().Sub(cc.lastActive)\n\tif atomic.LoadUint32(&cc.atomicReused) == 0 && idleTime < unusedWaitTime && !cc.closedOnIdle {\n\t\tcc.idleTimer = cc.t.afterFunc(unusedWaitTime-idleTime, func() {\n\t\t\tcc.t.connPool().MarkDead(cc)\n\t\t})\n\t} else {\n\t\tcc.mu.Unlock() // avoid any deadlocks in MarkDead\n\t\tcc.t.connPool().MarkDead(cc)\n\t\tcc.mu.Lock()\n\t}\n\n\tfor _, cs := range cc.streams {\n\t\tselect {\n\t\tcase <-cs.peerClosed:\n\t\t\t// The server closed the stream before closing the conn,\n\t\t\t// so no need to interrupt it.\n\t\tdefault:\n\t\t\tcs.abortStreamLocked(err)\n\t\t}\n\t}\n\tcc.cond.Broadcast()\n\tcc.mu.Unlock()\n\n\tif !cc.seenSettings {\n\t\t// If we have a pending request that wants extended CONNECT,\n\t\t// let it continue and fail with the connection error.\n\t\tcc.extendedConnectAllowed = true\n\t\tclose(cc.seenSettingsChan)\n\t}\n}\n\n// countReadFrameError calls Transport.CountError with a string\n// representing err.\nfunc (cc *ClientConn) countReadFrameError(err error) {\n\tf := cc.t.CountError\n\tif f == nil || err == nil {\n\t\treturn\n\t}\n\tif ce, ok := err.(ConnectionError); ok {\n\t\terrCode := ErrCode(ce)\n\t\tf(fmt.Sprintf(\"read_frame_conn_error_%s\", errCode.stringToken()))\n\t\treturn\n\t}\n\tif errors.Is(err, io.EOF) {\n\t\tf(\"read_frame_eof\")\n\t\treturn\n\t}\n\tif errors.Is(err, io.ErrUnexpectedEOF) {\n\t\tf(\"read_frame_unexpected_eof\")\n\t\treturn\n\t}\n\tif errors.Is(err, ErrFrameTooLarge) {\n\t\tf(\"read_frame_too_large\")\n\t\treturn\n\t}\n\tf(\"read_frame_other\")\n}\n\nfunc (rl *clientConnReadLoop) run() error {\n\tcc := rl.cc\n\tgotSettings := false\n\treadIdleTimeout := cc.readIdleTimeout\n\tvar t timer\n\tif readIdleTimeout != 0 {\n\t\tt = cc.t.afterFunc(readIdleTimeout, cc.healthCheck)\n\t}\n\tfor {\n\t\tf, err := cc.fr.ReadFrame()\n\t\tif t != nil {\n\t\t\tt.Reset(readIdleTimeout)\n\t\t}\n\t\tif err != nil {\n\t\t\tcc.vlogf(\"http2: Transport readFrame error on conn %p: (%T) %v\", cc, err, err)\n\t\t}\n\t\tif se, ok := err.(StreamError); ok {\n\t\t\tif cs := rl.streamByID(se.StreamID, notHeaderOrDataFrame); cs != nil {\n\t\t\t\tif se.Cause == nil {\n\t\t\t\t\tse.Cause = cc.fr.errDetail\n\t\t\t\t}\n\t\t\t\trl.endStreamError(cs, se)\n\t\t\t}\n\t\t\tcontinue\n\t\t} else if err != nil {\n\t\t\tcc.countReadFrameError(err)\n\t\t\treturn err\n\t\t}\n\t\tif VerboseLogs {\n\t\t\tcc.vlogf(\"http2: Transport received %s\", summarizeFrame(f))\n\t\t}\n\t\tif !gotSettings {\n\t\t\tif _, ok := f.(*SettingsFrame); !ok {\n\t\t\t\tcc.logf(\"protocol error: received %T before a SETTINGS frame\", f)\n\t\t\t\treturn ConnectionError(ErrCodeProtocol)\n\t\t\t}\n\t\t\tgotSettings = true\n\t\t}\n\n\t\tswitch f := f.(type) {\n\t\tcase *MetaHeadersFrame:\n\t\t\terr = rl.processHeaders(f)\n\t\tcase *DataFrame:\n\t\t\terr = rl.processData(f)\n\t\tcase *GoAwayFrame:\n\t\t\terr = rl.processGoAway(f)\n\t\tcase *RSTStreamFrame:\n\t\t\terr = rl.processResetStream(f)\n\t\tcase *SettingsFrame:\n\t\t\terr = rl.processSettings(f)\n\t\tcase *PushPromiseFrame:\n\t\t\terr = rl.processPushPromise(f)\n\t\tcase *WindowUpdateFrame:\n\t\t\terr = rl.processWindowUpdate(f)\n\t\tcase *PingFrame:\n\t\t\terr = rl.processPing(f)\n\t\tdefault:\n\t\t\tcc.logf(\"Transport: unhandled response frame type %T\", f)\n\t\t}\n\t\tif err != nil {\n\t\t\tif VerboseLogs {\n\t\t\t\tcc.vlogf(\"http2: Transport conn %p received error from processing frame %v: %v\", cc, summarizeFrame(f), err)\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t}\n}\n\nfunc (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error {\n\tcs := rl.streamByID(f.StreamID, headerOrDataFrame)\n\tif cs == nil {\n\t\t// We'd get here if we canceled a request while the\n\t\t// server had its response still in flight. So if this\n\t\t// was just something we canceled, ignore it.\n\t\treturn nil\n\t}\n\tif cs.readClosed {\n\t\trl.endStreamError(cs, StreamError{\n\t\t\tStreamID: f.StreamID,\n\t\t\tCode:     ErrCodeProtocol,\n\t\t\tCause:    errors.New(\"protocol error: headers after END_STREAM\"),\n\t\t})\n\t\treturn nil\n\t}\n\tif !cs.firstByte {\n\t\tif cs.trace != nil {\n\t\t\t// TODO(bradfitz): move first response byte earlier,\n\t\t\t// when we first read the 9 byte header, not waiting\n\t\t\t// until all the HEADERS+CONTINUATION frames have been\n\t\t\t// merged. This works for now.\n\t\t\ttraceFirstResponseByte(cs.trace)\n\t\t}\n\t\tcs.firstByte = true\n\t}\n\tif !cs.pastHeaders {\n\t\tcs.pastHeaders = true\n\t} else {\n\t\treturn rl.processTrailers(cs, f)\n\t}\n\n\tres, err := rl.handleResponse(cs, f)\n\tif err != nil {\n\t\tif _, ok := err.(ConnectionError); ok {\n\t\t\treturn err\n\t\t}\n\t\t// Any other error type is a stream error.\n\t\trl.endStreamError(cs, StreamError{\n\t\t\tStreamID: f.StreamID,\n\t\t\tCode:     ErrCodeProtocol,\n\t\t\tCause:    err,\n\t\t})\n\t\treturn nil // return nil from process* funcs to keep conn alive\n\t}\n\tif res == nil {\n\t\t// (nil, nil) special case. See handleResponse docs.\n\t\treturn nil\n\t}\n\tcs.resTrailer = &res.Trailer\n\tcs.res = res\n\tclose(cs.respHeaderRecv)\n\tif f.StreamEnded() {\n\t\trl.endStream(cs)\n\t}\n\treturn nil\n}\n\n// may return error types nil, or ConnectionError. Any other error value\n// is a StreamError of type ErrCodeProtocol. The returned error in that case\n// is the detail.\n//\n// As a special case, handleResponse may return (nil, nil) to skip the\n// frame (currently only used for 1xx responses).\nfunc (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFrame) (*http.Response, error) {\n\tif f.Truncated {\n\t\treturn nil, errResponseHeaderListSize\n\t}\n\n\tstatus := f.PseudoValue(\"status\")\n\tif status == \"\" {\n\t\treturn nil, errors.New(\"malformed response from server: missing status pseudo header\")\n\t}\n\tstatusCode, err := strconv.Atoi(status)\n\tif err != nil {\n\t\treturn nil, errors.New(\"malformed response from server: malformed non-numeric status pseudo header\")\n\t}\n\n\tregularFields := f.RegularFields()\n\tstrs := make([]string, len(regularFields))\n\theader := make(http.Header, len(regularFields))\n\tres := &http.Response{\n\t\tProto:      \"HTTP/2.0\",\n\t\tProtoMajor: 2,\n\t\tHeader:     header,\n\t\tStatusCode: statusCode,\n\t\tStatus:     status + \" \" + http.StatusText(statusCode),\n\t}\n\tfor _, hf := range regularFields {\n\t\tkey := httpcommon.CanonicalHeader(hf.Name)\n\t\tif key == \"Trailer\" {\n\t\t\tt := res.Trailer\n\t\t\tif t == nil {\n\t\t\t\tt = make(http.Header)\n\t\t\t\tres.Trailer = t\n\t\t\t}\n\t\t\tforeachHeaderElement(hf.Value, func(v string) {\n\t\t\t\tt[httpcommon.CanonicalHeader(v)] = nil\n\t\t\t})\n\t\t} else {\n\t\t\tvv := header[key]\n\t\t\tif vv == nil && len(strs) > 0 {\n\t\t\t\t// More than likely this will be a single-element key.\n\t\t\t\t// Most headers aren't multi-valued.\n\t\t\t\t// Set the capacity on strs[0] to 1, so any future append\n\t\t\t\t// won't extend the slice into the other strings.\n\t\t\t\tvv, strs = strs[:1:1], strs[1:]\n\t\t\t\tvv[0] = hf.Value\n\t\t\t\theader[key] = vv\n\t\t\t} else {\n\t\t\t\theader[key] = append(vv, hf.Value)\n\t\t\t}\n\t\t}\n\t}\n\n\tif statusCode >= 100 && statusCode <= 199 {\n\t\tif f.StreamEnded() {\n\t\t\treturn nil, errors.New(\"1xx informational response with END_STREAM flag\")\n\t\t}\n\t\tif fn := cs.get1xxTraceFunc(); fn != nil {\n\t\t\t// If the 1xx response is being delivered to the user,\n\t\t\t// then they're responsible for limiting the number\n\t\t\t// of responses.\n\t\t\tif err := fn(statusCode, textproto.MIMEHeader(header)); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t} else {\n\t\t\t// If the user didn't examine the 1xx response, then we\n\t\t\t// limit the size of all 1xx headers.\n\t\t\t//\n\t\t\t// This differs a bit from the HTTP/1 implementation, which\n\t\t\t// limits the size of all 1xx headers plus the final response.\n\t\t\t// Use the larger limit of MaxHeaderListSize and\n\t\t\t// net/http.Transport.MaxResponseHeaderBytes.\n\t\t\tlimit := int64(cs.cc.t.maxHeaderListSize())\n\t\t\tif t1 := cs.cc.t.t1; t1 != nil && t1.MaxResponseHeaderBytes > limit {\n\t\t\t\tlimit = t1.MaxResponseHeaderBytes\n\t\t\t}\n\t\t\tfor _, h := range f.Fields {\n\t\t\t\tcs.totalHeaderSize += int64(h.Size())\n\t\t\t}\n\t\t\tif cs.totalHeaderSize > limit {\n\t\t\t\tif VerboseLogs {\n\t\t\t\t\tlog.Printf(\"http2: 1xx informational responses too large\")\n\t\t\t\t}\n\t\t\t\treturn nil, errors.New(\"header list too large\")\n\t\t\t}\n\t\t}\n\t\tif statusCode == 100 {\n\t\t\ttraceGot100Continue(cs.trace)\n\t\t\tselect {\n\t\t\tcase cs.on100 <- struct{}{}:\n\t\t\tdefault:\n\t\t\t}\n\t\t}\n\t\tcs.pastHeaders = false // do it all again\n\t\treturn nil, nil\n\t}\n\n\tres.ContentLength = -1\n\tif clens := res.Header[\"Content-Length\"]; len(clens) == 1 {\n\t\tif cl, err := strconv.ParseUint(clens[0], 10, 63); err == nil {\n\t\t\tres.ContentLength = int64(cl)\n\t\t} else {\n\t\t\t// TODO: care? unlike http/1, it won't mess up our framing, so it's\n\t\t\t// more safe smuggling-wise to ignore.\n\t\t}\n\t} else if len(clens) > 1 {\n\t\t// TODO: care? unlike http/1, it won't mess up our framing, so it's\n\t\t// more safe smuggling-wise to ignore.\n\t} else if f.StreamEnded() && !cs.isHead {\n\t\tres.ContentLength = 0\n\t}\n\n\tif cs.isHead {\n\t\tres.Body = noBody\n\t\treturn res, nil\n\t}\n\n\tif f.StreamEnded() {\n\t\tif res.ContentLength > 0 {\n\t\t\tres.Body = missingBody{}\n\t\t} else {\n\t\t\tres.Body = noBody\n\t\t}\n\t\treturn res, nil\n\t}\n\n\tcs.bufPipe.setBuffer(&dataBuffer{expected: res.ContentLength})\n\tcs.bytesRemain = res.ContentLength\n\tres.Body = transportResponseBody{cs}\n\n\tif cs.requestedGzip && asciiEqualFold(res.Header.Get(\"Content-Encoding\"), \"gzip\") {\n\t\tres.Header.Del(\"Content-Encoding\")\n\t\tres.Header.Del(\"Content-Length\")\n\t\tres.ContentLength = -1\n\t\tres.Body = &gzipReader{body: res.Body}\n\t\tres.Uncompressed = true\n\t}\n\treturn res, nil\n}\n\nfunc (rl *clientConnReadLoop) processTrailers(cs *clientStream, f *MetaHeadersFrame) error {\n\tif cs.pastTrailers {\n\t\t// Too many HEADERS frames for this stream.\n\t\treturn ConnectionError(ErrCodeProtocol)\n\t}\n\tcs.pastTrailers = true\n\tif !f.StreamEnded() {\n\t\t// We expect that any headers for trailers also\n\t\t// has END_STREAM.\n\t\treturn ConnectionError(ErrCodeProtocol)\n\t}\n\tif len(f.PseudoFields()) > 0 {\n\t\t// No pseudo header fields are defined for trailers.\n\t\t// TODO: ConnectionError might be overly harsh? Check.\n\t\treturn ConnectionError(ErrCodeProtocol)\n\t}\n\n\ttrailer := make(http.Header)\n\tfor _, hf := range f.RegularFields() {\n\t\tkey := httpcommon.CanonicalHeader(hf.Name)\n\t\ttrailer[key] = append(trailer[key], hf.Value)\n\t}\n\tcs.trailer = trailer\n\n\trl.endStream(cs)\n\treturn nil\n}\n\n// transportResponseBody is the concrete type of Transport.RoundTrip's\n// Response.Body. It is an io.ReadCloser.\ntype transportResponseBody struct {\n\tcs *clientStream\n}\n\nfunc (b transportResponseBody) Read(p []byte) (n int, err error) {\n\tcs := b.cs\n\tcc := cs.cc\n\n\tif cs.readErr != nil {\n\t\treturn 0, cs.readErr\n\t}\n\tn, err = b.cs.bufPipe.Read(p)\n\tif cs.bytesRemain != -1 {\n\t\tif int64(n) > cs.bytesRemain {\n\t\t\tn = int(cs.bytesRemain)\n\t\t\tif err == nil {\n\t\t\t\terr = errors.New(\"net/http: server replied with more than declared Content-Length; truncated\")\n\t\t\t\tcs.abortStream(err)\n\t\t\t}\n\t\t\tcs.readErr = err\n\t\t\treturn int(cs.bytesRemain), err\n\t\t}\n\t\tcs.bytesRemain -= int64(n)\n\t\tif err == io.EOF && cs.bytesRemain > 0 {\n\t\t\terr = io.ErrUnexpectedEOF\n\t\t\tcs.readErr = err\n\t\t\treturn n, err\n\t\t}\n\t}\n\tif n == 0 {\n\t\t// No flow control tokens to send back.\n\t\treturn\n\t}\n\n\tcc.mu.Lock()\n\tconnAdd := cc.inflow.add(n)\n\tvar streamAdd int32\n\tif err == nil { // No need to refresh if the stream is over or failed.\n\t\tstreamAdd = cs.inflow.add(n)\n\t}\n\tcc.mu.Unlock()\n\n\tif connAdd != 0 || streamAdd != 0 {\n\t\tcc.wmu.Lock()\n\t\tdefer cc.wmu.Unlock()\n\t\tif connAdd != 0 {\n\t\t\tcc.fr.WriteWindowUpdate(0, mustUint31(connAdd))\n\t\t}\n\t\tif streamAdd != 0 {\n\t\t\tcc.fr.WriteWindowUpdate(cs.ID, mustUint31(streamAdd))\n\t\t}\n\t\tcc.bw.Flush()\n\t}\n\treturn\n}\n\nvar errClosedResponseBody = errors.New(\"http2: response body closed\")\n\nfunc (b transportResponseBody) Close() error {\n\tcs := b.cs\n\tcc := cs.cc\n\n\tcs.bufPipe.BreakWithError(errClosedResponseBody)\n\tcs.abortStream(errClosedResponseBody)\n\n\tunread := cs.bufPipe.Len()\n\tif unread > 0 {\n\t\tcc.mu.Lock()\n\t\t// Return connection-level flow control.\n\t\tconnAdd := cc.inflow.add(unread)\n\t\tcc.mu.Unlock()\n\n\t\t// TODO(dneil): Acquiring this mutex can block indefinitely.\n\t\t// Move flow control return to a goroutine?\n\t\tcc.wmu.Lock()\n\t\t// Return connection-level flow control.\n\t\tif connAdd > 0 {\n\t\t\tcc.fr.WriteWindowUpdate(0, uint32(connAdd))\n\t\t}\n\t\tcc.bw.Flush()\n\t\tcc.wmu.Unlock()\n\t}\n\n\tselect {\n\tcase <-cs.donec:\n\tcase <-cs.ctx.Done():\n\t\t// See golang/go#49366: The net/http package can cancel the\n\t\t// request context after the response body is fully read.\n\t\t// Don't treat this as an error.\n\t\treturn nil\n\tcase <-cs.reqCancel:\n\t\treturn errRequestCanceled\n\t}\n\treturn nil\n}\n\nfunc (rl *clientConnReadLoop) processData(f *DataFrame) error {\n\tcc := rl.cc\n\tcs := rl.streamByID(f.StreamID, headerOrDataFrame)\n\tdata := f.Data()\n\tif cs == nil {\n\t\tcc.mu.Lock()\n\t\tneverSent := cc.nextStreamID\n\t\tcc.mu.Unlock()\n\t\tif f.StreamID >= neverSent {\n\t\t\t// We never asked for this.\n\t\t\tcc.logf(\"http2: Transport received unsolicited DATA frame; closing connection\")\n\t\t\treturn ConnectionError(ErrCodeProtocol)\n\t\t}\n\t\t// We probably did ask for this, but canceled. Just ignore it.\n\t\t// TODO: be stricter here? only silently ignore things which\n\t\t// we canceled, but not things which were closed normally\n\t\t// by the peer? Tough without accumulating too much state.\n\n\t\t// But at least return their flow control:\n\t\tif f.Length > 0 {\n\t\t\tcc.mu.Lock()\n\t\t\tok := cc.inflow.take(f.Length)\n\t\t\tconnAdd := cc.inflow.add(int(f.Length))\n\t\t\tcc.mu.Unlock()\n\t\t\tif !ok {\n\t\t\t\treturn ConnectionError(ErrCodeFlowControl)\n\t\t\t}\n\t\t\tif connAdd > 0 {\n\t\t\t\tcc.wmu.Lock()\n\t\t\t\tcc.fr.WriteWindowUpdate(0, uint32(connAdd))\n\t\t\t\tcc.bw.Flush()\n\t\t\t\tcc.wmu.Unlock()\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tif cs.readClosed {\n\t\tcc.logf(\"protocol error: received DATA after END_STREAM\")\n\t\trl.endStreamError(cs, StreamError{\n\t\t\tStreamID: f.StreamID,\n\t\t\tCode:     ErrCodeProtocol,\n\t\t})\n\t\treturn nil\n\t}\n\tif !cs.pastHeaders {\n\t\tcc.logf(\"protocol error: received DATA before a HEADERS frame\")\n\t\trl.endStreamError(cs, StreamError{\n\t\t\tStreamID: f.StreamID,\n\t\t\tCode:     ErrCodeProtocol,\n\t\t})\n\t\treturn nil\n\t}\n\tif f.Length > 0 {\n\t\tif cs.isHead && len(data) > 0 {\n\t\t\tcc.logf(\"protocol error: received DATA on a HEAD request\")\n\t\t\trl.endStreamError(cs, StreamError{\n\t\t\t\tStreamID: f.StreamID,\n\t\t\t\tCode:     ErrCodeProtocol,\n\t\t\t})\n\t\t\treturn nil\n\t\t}\n\t\t// Check connection-level flow control.\n\t\tcc.mu.Lock()\n\t\tif !takeInflows(&cc.inflow, &cs.inflow, f.Length) {\n\t\t\tcc.mu.Unlock()\n\t\t\treturn ConnectionError(ErrCodeFlowControl)\n\t\t}\n\t\t// Return any padded flow control now, since we won't\n\t\t// refund it later on body reads.\n\t\tvar refund int\n\t\tif pad := int(f.Length) - len(data); pad > 0 {\n\t\t\trefund += pad\n\t\t}\n\n\t\tdidReset := false\n\t\tvar err error\n\t\tif len(data) > 0 {\n\t\t\tif _, err = cs.bufPipe.Write(data); err != nil {\n\t\t\t\t// Return len(data) now if the stream is already closed,\n\t\t\t\t// since data will never be read.\n\t\t\t\tdidReset = true\n\t\t\t\trefund += len(data)\n\t\t\t}\n\t\t}\n\n\t\tsendConn := cc.inflow.add(refund)\n\t\tvar sendStream int32\n\t\tif !didReset {\n\t\t\tsendStream = cs.inflow.add(refund)\n\t\t}\n\t\tcc.mu.Unlock()\n\n\t\tif sendConn > 0 || sendStream > 0 {\n\t\t\tcc.wmu.Lock()\n\t\t\tif sendConn > 0 {\n\t\t\t\tcc.fr.WriteWindowUpdate(0, uint32(sendConn))\n\t\t\t}\n\t\t\tif sendStream > 0 {\n\t\t\t\tcc.fr.WriteWindowUpdate(cs.ID, uint32(sendStream))\n\t\t\t}\n\t\t\tcc.bw.Flush()\n\t\t\tcc.wmu.Unlock()\n\t\t}\n\n\t\tif err != nil {\n\t\t\trl.endStreamError(cs, err)\n\t\t\treturn nil\n\t\t}\n\t}\n\n\tif f.StreamEnded() {\n\t\trl.endStream(cs)\n\t}\n\treturn nil\n}\n\nfunc (rl *clientConnReadLoop) endStream(cs *clientStream) {\n\t// TODO: check that any declared content-length matches, like\n\t// server.go's (*stream).endStream method.\n\tif !cs.readClosed {\n\t\tcs.readClosed = true\n\t\t// Close cs.bufPipe and cs.peerClosed with cc.mu held to avoid a\n\t\t// race condition: The caller can read io.EOF from Response.Body\n\t\t// and close the body before we close cs.peerClosed, causing\n\t\t// cleanupWriteRequest to send a RST_STREAM.\n\t\trl.cc.mu.Lock()\n\t\tdefer rl.cc.mu.Unlock()\n\t\tcs.bufPipe.closeWithErrorAndCode(io.EOF, cs.copyTrailers)\n\t\tclose(cs.peerClosed)\n\t}\n}\n\nfunc (rl *clientConnReadLoop) endStreamError(cs *clientStream, err error) {\n\tcs.readAborted = true\n\tcs.abortStream(err)\n}\n\n// Constants passed to streamByID for documentation purposes.\nconst (\n\theaderOrDataFrame    = true\n\tnotHeaderOrDataFrame = false\n)\n\n// streamByID returns the stream with the given id, or nil if no stream has that id.\n// If headerOrData is true, it clears rst.StreamPingsBlocked.\nfunc (rl *clientConnReadLoop) streamByID(id uint32, headerOrData bool) *clientStream {\n\trl.cc.mu.Lock()\n\tdefer rl.cc.mu.Unlock()\n\tif headerOrData {\n\t\t// Work around an unfortunate gRPC behavior.\n\t\t// See comment on ClientConn.rstStreamPingsBlocked for details.\n\t\trl.cc.rstStreamPingsBlocked = false\n\t}\n\tcs := rl.cc.streams[id]\n\tif cs != nil && !cs.readAborted {\n\t\treturn cs\n\t}\n\treturn nil\n}\n\nfunc (cs *clientStream) copyTrailers() {\n\tfor k, vv := range cs.trailer {\n\t\tt := cs.resTrailer\n\t\tif *t == nil {\n\t\t\t*t = make(http.Header)\n\t\t}\n\t\t(*t)[k] = vv\n\t}\n}\n\nfunc (rl *clientConnReadLoop) processGoAway(f *GoAwayFrame) error {\n\tcc := rl.cc\n\tcc.t.connPool().MarkDead(cc)\n\tif f.ErrCode != 0 {\n\t\t// TODO: deal with GOAWAY more. particularly the error code\n\t\tcc.vlogf(\"transport got GOAWAY with error code = %v\", f.ErrCode)\n\t\tif fn := cc.t.CountError; fn != nil {\n\t\t\tfn(\"recv_goaway_\" + f.ErrCode.stringToken())\n\t\t}\n\t}\n\tcc.setGoAway(f)\n\treturn nil\n}\n\nfunc (rl *clientConnReadLoop) processSettings(f *SettingsFrame) error {\n\tcc := rl.cc\n\t// Locking both mu and wmu here allows frame encoding to read settings with only wmu held.\n\t// Acquiring wmu when f.IsAck() is unnecessary, but convenient and mostly harmless.\n\tcc.wmu.Lock()\n\tdefer cc.wmu.Unlock()\n\n\tif err := rl.processSettingsNoWrite(f); err != nil {\n\t\treturn err\n\t}\n\tif !f.IsAck() {\n\t\tcc.fr.WriteSettingsAck()\n\t\tcc.bw.Flush()\n\t}\n\treturn nil\n}\n\nfunc (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error {\n\tcc := rl.cc\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\n\tif f.IsAck() {\n\t\tif cc.wantSettingsAck {\n\t\t\tcc.wantSettingsAck = false\n\t\t\treturn nil\n\t\t}\n\t\treturn ConnectionError(ErrCodeProtocol)\n\t}\n\n\tvar seenMaxConcurrentStreams bool\n\terr := f.ForeachSetting(func(s Setting) error {\n\t\tswitch s.ID {\n\t\tcase SettingMaxFrameSize:\n\t\t\tcc.maxFrameSize = s.Val\n\t\tcase SettingMaxConcurrentStreams:\n\t\t\tcc.maxConcurrentStreams = s.Val\n\t\t\tseenMaxConcurrentStreams = true\n\t\tcase SettingMaxHeaderListSize:\n\t\t\tcc.peerMaxHeaderListSize = uint64(s.Val)\n\t\tcase SettingInitialWindowSize:\n\t\t\t// Values above the maximum flow-control\n\t\t\t// window size of 2^31-1 MUST be treated as a\n\t\t\t// connection error (Section 5.4.1) of type\n\t\t\t// FLOW_CONTROL_ERROR.\n\t\t\tif s.Val > math.MaxInt32 {\n\t\t\t\treturn ConnectionError(ErrCodeFlowControl)\n\t\t\t}\n\n\t\t\t// Adjust flow control of currently-open\n\t\t\t// frames by the difference of the old initial\n\t\t\t// window size and this one.\n\t\t\tdelta := int32(s.Val) - int32(cc.initialWindowSize)\n\t\t\tfor _, cs := range cc.streams {\n\t\t\t\tcs.flow.add(delta)\n\t\t\t}\n\t\t\tcc.cond.Broadcast()\n\n\t\t\tcc.initialWindowSize = s.Val\n\t\tcase SettingHeaderTableSize:\n\t\t\tcc.henc.SetMaxDynamicTableSize(s.Val)\n\t\t\tcc.peerMaxHeaderTableSize = s.Val\n\t\tcase SettingEnableConnectProtocol:\n\t\t\tif err := s.Valid(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\t// If the peer wants to send us SETTINGS_ENABLE_CONNECT_PROTOCOL,\n\t\t\t// we require that it do so in the first SETTINGS frame.\n\t\t\t//\n\t\t\t// When we attempt to use extended CONNECT, we wait for the first\n\t\t\t// SETTINGS frame to see if the server supports it. If we let the\n\t\t\t// server enable the feature with a later SETTINGS frame, then\n\t\t\t// users will see inconsistent results depending on whether we've\n\t\t\t// seen that frame or not.\n\t\t\tif !cc.seenSettings {\n\t\t\t\tcc.extendedConnectAllowed = s.Val == 1\n\t\t\t}\n\t\tdefault:\n\t\t\tcc.vlogf(\"Unhandled Setting: %v\", s)\n\t\t}\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif !cc.seenSettings {\n\t\tif !seenMaxConcurrentStreams {\n\t\t\t// This was the servers initial SETTINGS frame and it\n\t\t\t// didn't contain a MAX_CONCURRENT_STREAMS field so\n\t\t\t// increase the number of concurrent streams this\n\t\t\t// connection can establish to our default.\n\t\t\tcc.maxConcurrentStreams = defaultMaxConcurrentStreams\n\t\t}\n\t\tclose(cc.seenSettingsChan)\n\t\tcc.seenSettings = true\n\t}\n\n\treturn nil\n}\n\nfunc (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error {\n\tcc := rl.cc\n\tcs := rl.streamByID(f.StreamID, notHeaderOrDataFrame)\n\tif f.StreamID != 0 && cs == nil {\n\t\treturn nil\n\t}\n\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\n\tfl := &cc.flow\n\tif cs != nil {\n\t\tfl = &cs.flow\n\t}\n\tif !fl.add(int32(f.Increment)) {\n\t\t// For stream, the sender sends RST_STREAM with an error code of FLOW_CONTROL_ERROR\n\t\tif cs != nil {\n\t\t\trl.endStreamError(cs, StreamError{\n\t\t\t\tStreamID: f.StreamID,\n\t\t\t\tCode:     ErrCodeFlowControl,\n\t\t\t})\n\t\t\treturn nil\n\t\t}\n\n\t\treturn ConnectionError(ErrCodeFlowControl)\n\t}\n\tcc.cond.Broadcast()\n\treturn nil\n}\n\nfunc (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error {\n\tcs := rl.streamByID(f.StreamID, notHeaderOrDataFrame)\n\tif cs == nil {\n\t\t// TODO: return error if server tries to RST_STREAM an idle stream\n\t\treturn nil\n\t}\n\tserr := streamError(cs.ID, f.ErrCode)\n\tserr.Cause = errFromPeer\n\tif f.ErrCode == ErrCodeProtocol {\n\t\trl.cc.SetDoNotReuse()\n\t}\n\tif fn := cs.cc.t.CountError; fn != nil {\n\t\tfn(\"recv_rststream_\" + f.ErrCode.stringToken())\n\t}\n\tcs.abortStream(serr)\n\n\tcs.bufPipe.CloseWithError(serr)\n\treturn nil\n}\n\n// Ping sends a PING frame to the server and waits for the ack.\nfunc (cc *ClientConn) Ping(ctx context.Context) error {\n\tc := make(chan struct{})\n\t// Generate a random payload\n\tvar p [8]byte\n\tfor {\n\t\tif _, err := rand.Read(p[:]); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcc.mu.Lock()\n\t\t// check for dup before insert\n\t\tif _, found := cc.pings[p]; !found {\n\t\t\tcc.pings[p] = c\n\t\t\tcc.mu.Unlock()\n\t\t\tbreak\n\t\t}\n\t\tcc.mu.Unlock()\n\t}\n\tvar pingError error\n\terrc := make(chan struct{})\n\tgo func() {\n\t\tcc.t.markNewGoroutine()\n\t\tcc.wmu.Lock()\n\t\tdefer cc.wmu.Unlock()\n\t\tif pingError = cc.fr.WritePing(false, p); pingError != nil {\n\t\t\tclose(errc)\n\t\t\treturn\n\t\t}\n\t\tif pingError = cc.bw.Flush(); pingError != nil {\n\t\t\tclose(errc)\n\t\t\treturn\n\t\t}\n\t}()\n\tselect {\n\tcase <-c:\n\t\treturn nil\n\tcase <-errc:\n\t\treturn pingError\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\tcase <-cc.readerDone:\n\t\t// connection closed\n\t\treturn cc.readerErr\n\t}\n}\n\nfunc (rl *clientConnReadLoop) processPing(f *PingFrame) error {\n\tif f.IsAck() {\n\t\tcc := rl.cc\n\t\tcc.mu.Lock()\n\t\tdefer cc.mu.Unlock()\n\t\t// If ack, notify listener if any\n\t\tif c, ok := cc.pings[f.Data]; ok {\n\t\t\tclose(c)\n\t\t\tdelete(cc.pings, f.Data)\n\t\t}\n\t\tif cc.pendingResets > 0 {\n\t\t\t// See clientStream.cleanupWriteRequest.\n\t\t\tcc.pendingResets = 0\n\t\t\tcc.rstStreamPingsBlocked = true\n\t\t\tcc.cond.Broadcast()\n\t\t}\n\t\treturn nil\n\t}\n\tcc := rl.cc\n\tcc.wmu.Lock()\n\tdefer cc.wmu.Unlock()\n\tif err := cc.fr.WritePing(true, f.Data); err != nil {\n\t\treturn err\n\t}\n\treturn cc.bw.Flush()\n}\n\nfunc (rl *clientConnReadLoop) processPushPromise(f *PushPromiseFrame) error {\n\t// We told the peer we don't want them.\n\t// Spec says:\n\t// \"PUSH_PROMISE MUST NOT be sent if the SETTINGS_ENABLE_PUSH\n\t// setting of the peer endpoint is set to 0. An endpoint that\n\t// has set this setting and has received acknowledgement MUST\n\t// treat the receipt of a PUSH_PROMISE frame as a connection\n\t// error (Section 5.4.1) of type PROTOCOL_ERROR.\"\n\treturn ConnectionError(ErrCodeProtocol)\n}\n\n// writeStreamReset sends a RST_STREAM frame.\n// When ping is true, it also sends a PING frame with a random payload.\nfunc (cc *ClientConn) writeStreamReset(streamID uint32, code ErrCode, ping bool, err error) {\n\t// TODO: map err to more interesting error codes, once the\n\t// HTTP community comes up with some. But currently for\n\t// RST_STREAM there's no equivalent to GOAWAY frame's debug\n\t// data, and the error codes are all pretty vague (\"cancel\").\n\tcc.wmu.Lock()\n\tcc.fr.WriteRSTStream(streamID, code)\n\tif ping {\n\t\tvar payload [8]byte\n\t\trand.Read(payload[:])\n\t\tcc.fr.WritePing(false, payload)\n\t}\n\tcc.bw.Flush()\n\tcc.wmu.Unlock()\n}\n\nvar (\n\terrResponseHeaderListSize = errors.New(\"http2: response header list larger than advertised limit\")\n\terrRequestHeaderListSize  = httpcommon.ErrRequestHeaderListSize\n)\n\nfunc (cc *ClientConn) logf(format string, args ...interface{}) {\n\tcc.t.logf(format, args...)\n}\n\nfunc (cc *ClientConn) vlogf(format string, args ...interface{}) {\n\tcc.t.vlogf(format, args...)\n}\n\nfunc (t *Transport) vlogf(format string, args ...interface{}) {\n\tif VerboseLogs {\n\t\tt.logf(format, args...)\n\t}\n}\n\nfunc (t *Transport) logf(format string, args ...interface{}) {\n\tlog.Printf(format, args...)\n}\n\nvar noBody io.ReadCloser = noBodyReader{}\n\ntype noBodyReader struct{}\n\nfunc (noBodyReader) Close() error             { return nil }\nfunc (noBodyReader) Read([]byte) (int, error) { return 0, io.EOF }\n\ntype missingBody struct{}\n\nfunc (missingBody) Close() error             { return nil }\nfunc (missingBody) Read([]byte) (int, error) { return 0, io.ErrUnexpectedEOF }\n\nfunc strSliceContains(ss []string, s string) bool {\n\tfor _, v := range ss {\n\t\tif v == s {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\ntype erringRoundTripper struct{ err error }\n\nfunc (rt erringRoundTripper) RoundTripErr() error                             { return rt.err }\nfunc (rt erringRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { return nil, rt.err }\n\n// gzipReader wraps a response body so it can lazily\n// call gzip.NewReader on the first call to Read\ntype gzipReader struct {\n\t_    incomparable\n\tbody io.ReadCloser // underlying Response.Body\n\tzr   *gzip.Reader  // lazily-initialized gzip reader\n\tzerr error         // sticky error\n}\n\nfunc (gz *gzipReader) Read(p []byte) (n int, err error) {\n\tif gz.zerr != nil {\n\t\treturn 0, gz.zerr\n\t}\n\tif gz.zr == nil {\n\t\tgz.zr, err = gzip.NewReader(gz.body)\n\t\tif err != nil {\n\t\t\tgz.zerr = err\n\t\t\treturn 0, err\n\t\t}\n\t}\n\treturn gz.zr.Read(p)\n}\n\nfunc (gz *gzipReader) Close() error {\n\tif err := gz.body.Close(); err != nil {\n\t\treturn err\n\t}\n\tgz.zerr = fs.ErrClosed\n\treturn nil\n}\n\ntype errorReader struct{ err error }\n\nfunc (r errorReader) Read(p []byte) (int, error) { return 0, r.err }\n\n// isConnectionCloseRequest reports whether req should use its own\n// connection for a single request and then close the connection.\nfunc isConnectionCloseRequest(req *http.Request) bool {\n\treturn req.Close || httpguts.HeaderValuesContainsToken(req.Header[\"Connection\"], \"close\")\n}\n\n// registerHTTPSProtocol calls Transport.RegisterProtocol but\n// converting panics into errors.\nfunc registerHTTPSProtocol(t *http.Transport, rt noDialH2RoundTripper) (err error) {\n\tdefer func() {\n\t\tif e := recover(); e != nil {\n\t\t\terr = fmt.Errorf(\"%v\", e)\n\t\t}\n\t}()\n\tt.RegisterProtocol(\"https\", rt)\n\treturn nil\n}\n\n// noDialH2RoundTripper is a RoundTripper which only tries to complete the request\n// if there's already has a cached connection to the host.\n// (The field is exported so it can be accessed via reflect from net/http; tested\n// by TestNoDialH2RoundTripperType)\ntype noDialH2RoundTripper struct{ *Transport }\n\nfunc (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {\n\tres, err := rt.Transport.RoundTrip(req)\n\tif isNoCachedConnError(err) {\n\t\treturn nil, http.ErrSkipAltProtocol\n\t}\n\treturn res, err\n}\n\nfunc (t *Transport) idleConnTimeout() time.Duration {\n\t// to keep things backwards compatible, we use non-zero values of\n\t// IdleConnTimeout, followed by using the IdleConnTimeout on the underlying\n\t// http1 transport, followed by 0\n\tif t.IdleConnTimeout != 0 {\n\t\treturn t.IdleConnTimeout\n\t}\n\n\tif t.t1 != nil {\n\t\treturn t.t1.IdleConnTimeout\n\t}\n\n\treturn 0\n}\n\nfunc traceGetConn(req *http.Request, hostPort string) {\n\ttrace := httptrace.ContextClientTrace(req.Context())\n\tif trace == nil || trace.GetConn == nil {\n\t\treturn\n\t}\n\ttrace.GetConn(hostPort)\n}\n\nfunc traceGotConn(req *http.Request, cc *ClientConn, reused bool) {\n\ttrace := httptrace.ContextClientTrace(req.Context())\n\tif trace == nil || trace.GotConn == nil {\n\t\treturn\n\t}\n\tci := httptrace.GotConnInfo{Conn: cc.tconn}\n\tci.Reused = reused\n\tcc.mu.Lock()\n\tci.WasIdle = len(cc.streams) == 0 && reused\n\tif ci.WasIdle && !cc.lastActive.IsZero() {\n\t\tci.IdleTime = cc.t.timeSince(cc.lastActive)\n\t}\n\tcc.mu.Unlock()\n\n\ttrace.GotConn(ci)\n}\n\nfunc traceWroteHeaders(trace *httptrace.ClientTrace) {\n\tif trace != nil && trace.WroteHeaders != nil {\n\t\ttrace.WroteHeaders()\n\t}\n}\n\nfunc traceGot100Continue(trace *httptrace.ClientTrace) {\n\tif trace != nil && trace.Got100Continue != nil {\n\t\ttrace.Got100Continue()\n\t}\n}\n\nfunc traceWait100Continue(trace *httptrace.ClientTrace) {\n\tif trace != nil && trace.Wait100Continue != nil {\n\t\ttrace.Wait100Continue()\n\t}\n}\n\nfunc traceWroteRequest(trace *httptrace.ClientTrace, err error) {\n\tif trace != nil && trace.WroteRequest != nil {\n\t\ttrace.WroteRequest(httptrace.WroteRequestInfo{Err: err})\n\t}\n}\n\nfunc traceFirstResponseByte(trace *httptrace.ClientTrace) {\n\tif trace != nil && trace.GotFirstResponseByte != nil {\n\t\ttrace.GotFirstResponseByte()\n\t}\n}\n\nfunc traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error {\n\tif trace != nil {\n\t\treturn trace.Got1xxResponse\n\t}\n\treturn nil\n}\n\n// dialTLSWithContext uses tls.Dialer, added in Go 1.15, to open a TLS\n// connection.\nfunc (t *Transport) dialTLSWithContext(ctx context.Context, network, addr string, cfg *tls.Config) (*tls.Conn, error) {\n\tdialer := &tls.Dialer{\n\t\tConfig: cfg,\n\t}\n\tcn, err := dialer.DialContext(ctx, network, addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttlsCn := cn.(*tls.Conn) // DialContext comment promises this will always succeed\n\treturn tlsCn, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/unencrypted.go",
    "content": "// Copyright 2024 The Go 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 http2\n\nimport (\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"net\"\n)\n\nconst nextProtoUnencryptedHTTP2 = \"unencrypted_http2\"\n\n// unencryptedNetConnFromTLSConn retrieves a net.Conn wrapped in a *tls.Conn.\n//\n// TLSNextProto functions accept a *tls.Conn.\n//\n// When passing an unencrypted HTTP/2 connection to a TLSNextProto function,\n// we pass a *tls.Conn with an underlying net.Conn containing the unencrypted connection.\n// To be extra careful about mistakes (accidentally dropping TLS encryption in a place\n// where we want it), the tls.Conn contains a net.Conn with an UnencryptedNetConn method\n// that returns the actual connection we want to use.\nfunc unencryptedNetConnFromTLSConn(tc *tls.Conn) (net.Conn, error) {\n\tconner, ok := tc.NetConn().(interface {\n\t\tUnencryptedNetConn() net.Conn\n\t})\n\tif !ok {\n\t\treturn nil, errors.New(\"http2: TLS conn unexpectedly found in unencrypted handoff\")\n\t}\n\treturn conner.UnencryptedNetConn(), nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/write.go",
    "content": "// Copyright 2014 The Go 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 http2\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"net/url\"\n\n\t\"golang.org/x/net/http/httpguts\"\n\t\"golang.org/x/net/http2/hpack\"\n\t\"golang.org/x/net/internal/httpcommon\"\n)\n\n// writeFramer is implemented by any type that is used to write frames.\ntype writeFramer interface {\n\twriteFrame(writeContext) error\n\n\t// staysWithinBuffer reports whether this writer promises that\n\t// it will only write less than or equal to size bytes, and it\n\t// won't Flush the write context.\n\tstaysWithinBuffer(size int) bool\n}\n\n// writeContext is the interface needed by the various frame writer\n// types below. All the writeFrame methods below are scheduled via the\n// frame writing scheduler (see writeScheduler in writesched.go).\n//\n// This interface is implemented by *serverConn.\n//\n// TODO: decide whether to a) use this in the client code (which didn't\n// end up using this yet, because it has a simpler design, not\n// currently implementing priorities), or b) delete this and\n// make the server code a bit more concrete.\ntype writeContext interface {\n\tFramer() *Framer\n\tFlush() error\n\tCloseConn() error\n\t// HeaderEncoder returns an HPACK encoder that writes to the\n\t// returned buffer.\n\tHeaderEncoder() (*hpack.Encoder, *bytes.Buffer)\n}\n\n// writeEndsStream reports whether w writes a frame that will transition\n// the stream to a half-closed local state. This returns false for RST_STREAM,\n// which closes the entire stream (not just the local half).\nfunc writeEndsStream(w writeFramer) bool {\n\tswitch v := w.(type) {\n\tcase *writeData:\n\t\treturn v.endStream\n\tcase *writeResHeaders:\n\t\treturn v.endStream\n\tcase nil:\n\t\t// This can only happen if the caller reuses w after it's\n\t\t// been intentionally nil'ed out to prevent use. Keep this\n\t\t// here to catch future refactoring breaking it.\n\t\tpanic(\"writeEndsStream called on nil writeFramer\")\n\t}\n\treturn false\n}\n\ntype flushFrameWriter struct{}\n\nfunc (flushFrameWriter) writeFrame(ctx writeContext) error {\n\treturn ctx.Flush()\n}\n\nfunc (flushFrameWriter) staysWithinBuffer(max int) bool { return false }\n\ntype writeSettings []Setting\n\nfunc (s writeSettings) staysWithinBuffer(max int) bool {\n\tconst settingSize = 6 // uint16 + uint32\n\treturn frameHeaderLen+settingSize*len(s) <= max\n\n}\n\nfunc (s writeSettings) writeFrame(ctx writeContext) error {\n\treturn ctx.Framer().WriteSettings([]Setting(s)...)\n}\n\ntype writeGoAway struct {\n\tmaxStreamID uint32\n\tcode        ErrCode\n}\n\nfunc (p *writeGoAway) writeFrame(ctx writeContext) error {\n\terr := ctx.Framer().WriteGoAway(p.maxStreamID, p.code, nil)\n\tctx.Flush() // ignore error: we're hanging up on them anyway\n\treturn err\n}\n\nfunc (*writeGoAway) staysWithinBuffer(max int) bool { return false } // flushes\n\ntype writeData struct {\n\tstreamID  uint32\n\tp         []byte\n\tendStream bool\n}\n\nfunc (w *writeData) String() string {\n\treturn fmt.Sprintf(\"writeData(stream=%d, p=%d, endStream=%v)\", w.streamID, len(w.p), w.endStream)\n}\n\nfunc (w *writeData) writeFrame(ctx writeContext) error {\n\treturn ctx.Framer().WriteData(w.streamID, w.endStream, w.p)\n}\n\nfunc (w *writeData) staysWithinBuffer(max int) bool {\n\treturn frameHeaderLen+len(w.p) <= max\n}\n\n// handlerPanicRST is the message sent from handler goroutines when\n// the handler panics.\ntype handlerPanicRST struct {\n\tStreamID uint32\n}\n\nfunc (hp handlerPanicRST) writeFrame(ctx writeContext) error {\n\treturn ctx.Framer().WriteRSTStream(hp.StreamID, ErrCodeInternal)\n}\n\nfunc (hp handlerPanicRST) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max }\n\nfunc (se StreamError) writeFrame(ctx writeContext) error {\n\treturn ctx.Framer().WriteRSTStream(se.StreamID, se.Code)\n}\n\nfunc (se StreamError) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max }\n\ntype writePing struct {\n\tdata [8]byte\n}\n\nfunc (w writePing) writeFrame(ctx writeContext) error {\n\treturn ctx.Framer().WritePing(false, w.data)\n}\n\nfunc (w writePing) staysWithinBuffer(max int) bool { return frameHeaderLen+len(w.data) <= max }\n\ntype writePingAck struct{ pf *PingFrame }\n\nfunc (w writePingAck) writeFrame(ctx writeContext) error {\n\treturn ctx.Framer().WritePing(true, w.pf.Data)\n}\n\nfunc (w writePingAck) staysWithinBuffer(max int) bool { return frameHeaderLen+len(w.pf.Data) <= max }\n\ntype writeSettingsAck struct{}\n\nfunc (writeSettingsAck) writeFrame(ctx writeContext) error {\n\treturn ctx.Framer().WriteSettingsAck()\n}\n\nfunc (writeSettingsAck) staysWithinBuffer(max int) bool { return frameHeaderLen <= max }\n\n// splitHeaderBlock splits headerBlock into fragments so that each fragment fits\n// in a single frame, then calls fn for each fragment. firstFrag/lastFrag are true\n// for the first/last fragment, respectively.\nfunc splitHeaderBlock(ctx writeContext, headerBlock []byte, fn func(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error) error {\n\t// For now we're lazy and just pick the minimum MAX_FRAME_SIZE\n\t// that all peers must support (16KB). Later we could care\n\t// more and send larger frames if the peer advertised it, but\n\t// there's little point. Most headers are small anyway (so we\n\t// generally won't have CONTINUATION frames), and extra frames\n\t// only waste 9 bytes anyway.\n\tconst maxFrameSize = 16384\n\n\tfirst := true\n\tfor len(headerBlock) > 0 {\n\t\tfrag := headerBlock\n\t\tif len(frag) > maxFrameSize {\n\t\t\tfrag = frag[:maxFrameSize]\n\t\t}\n\t\theaderBlock = headerBlock[len(frag):]\n\t\tif err := fn(ctx, frag, first, len(headerBlock) == 0); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfirst = false\n\t}\n\treturn nil\n}\n\n// writeResHeaders is a request to write a HEADERS and 0+ CONTINUATION frames\n// for HTTP response headers or trailers from a server handler.\ntype writeResHeaders struct {\n\tstreamID    uint32\n\thttpResCode int         // 0 means no \":status\" line\n\th           http.Header // may be nil\n\ttrailers    []string    // if non-nil, which keys of h to write. nil means all.\n\tendStream   bool\n\n\tdate          string\n\tcontentType   string\n\tcontentLength string\n}\n\nfunc encKV(enc *hpack.Encoder, k, v string) {\n\tif VerboseLogs {\n\t\tlog.Printf(\"http2: server encoding header %q = %q\", k, v)\n\t}\n\tenc.WriteField(hpack.HeaderField{Name: k, Value: v})\n}\n\nfunc (w *writeResHeaders) staysWithinBuffer(max int) bool {\n\t// TODO: this is a common one. It'd be nice to return true\n\t// here and get into the fast path if we could be clever and\n\t// calculate the size fast enough, or at least a conservative\n\t// upper bound that usually fires. (Maybe if w.h and\n\t// w.trailers are nil, so we don't need to enumerate it.)\n\t// Otherwise I'm afraid that just calculating the length to\n\t// answer this question would be slower than the ~2µs benefit.\n\treturn false\n}\n\nfunc (w *writeResHeaders) writeFrame(ctx writeContext) error {\n\tenc, buf := ctx.HeaderEncoder()\n\tbuf.Reset()\n\n\tif w.httpResCode != 0 {\n\t\tencKV(enc, \":status\", httpCodeString(w.httpResCode))\n\t}\n\n\tencodeHeaders(enc, w.h, w.trailers)\n\n\tif w.contentType != \"\" {\n\t\tencKV(enc, \"content-type\", w.contentType)\n\t}\n\tif w.contentLength != \"\" {\n\t\tencKV(enc, \"content-length\", w.contentLength)\n\t}\n\tif w.date != \"\" {\n\t\tencKV(enc, \"date\", w.date)\n\t}\n\n\theaderBlock := buf.Bytes()\n\tif len(headerBlock) == 0 && w.trailers == nil {\n\t\tpanic(\"unexpected empty hpack\")\n\t}\n\n\treturn splitHeaderBlock(ctx, headerBlock, w.writeHeaderBlock)\n}\n\nfunc (w *writeResHeaders) writeHeaderBlock(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error {\n\tif firstFrag {\n\t\treturn ctx.Framer().WriteHeaders(HeadersFrameParam{\n\t\t\tStreamID:      w.streamID,\n\t\t\tBlockFragment: frag,\n\t\t\tEndStream:     w.endStream,\n\t\t\tEndHeaders:    lastFrag,\n\t\t})\n\t} else {\n\t\treturn ctx.Framer().WriteContinuation(w.streamID, lastFrag, frag)\n\t}\n}\n\n// writePushPromise is a request to write a PUSH_PROMISE and 0+ CONTINUATION frames.\ntype writePushPromise struct {\n\tstreamID uint32   // pusher stream\n\tmethod   string   // for :method\n\turl      *url.URL // for :scheme, :authority, :path\n\th        http.Header\n\n\t// Creates an ID for a pushed stream. This runs on serveG just before\n\t// the frame is written. The returned ID is copied to promisedID.\n\tallocatePromisedID func() (uint32, error)\n\tpromisedID         uint32\n}\n\nfunc (w *writePushPromise) staysWithinBuffer(max int) bool {\n\t// TODO: see writeResHeaders.staysWithinBuffer\n\treturn false\n}\n\nfunc (w *writePushPromise) writeFrame(ctx writeContext) error {\n\tenc, buf := ctx.HeaderEncoder()\n\tbuf.Reset()\n\n\tencKV(enc, \":method\", w.method)\n\tencKV(enc, \":scheme\", w.url.Scheme)\n\tencKV(enc, \":authority\", w.url.Host)\n\tencKV(enc, \":path\", w.url.RequestURI())\n\tencodeHeaders(enc, w.h, nil)\n\n\theaderBlock := buf.Bytes()\n\tif len(headerBlock) == 0 {\n\t\tpanic(\"unexpected empty hpack\")\n\t}\n\n\treturn splitHeaderBlock(ctx, headerBlock, w.writeHeaderBlock)\n}\n\nfunc (w *writePushPromise) writeHeaderBlock(ctx writeContext, frag []byte, firstFrag, lastFrag bool) error {\n\tif firstFrag {\n\t\treturn ctx.Framer().WritePushPromise(PushPromiseParam{\n\t\t\tStreamID:      w.streamID,\n\t\t\tPromiseID:     w.promisedID,\n\t\t\tBlockFragment: frag,\n\t\t\tEndHeaders:    lastFrag,\n\t\t})\n\t} else {\n\t\treturn ctx.Framer().WriteContinuation(w.streamID, lastFrag, frag)\n\t}\n}\n\ntype write100ContinueHeadersFrame struct {\n\tstreamID uint32\n}\n\nfunc (w write100ContinueHeadersFrame) writeFrame(ctx writeContext) error {\n\tenc, buf := ctx.HeaderEncoder()\n\tbuf.Reset()\n\tencKV(enc, \":status\", \"100\")\n\treturn ctx.Framer().WriteHeaders(HeadersFrameParam{\n\t\tStreamID:      w.streamID,\n\t\tBlockFragment: buf.Bytes(),\n\t\tEndStream:     false,\n\t\tEndHeaders:    true,\n\t})\n}\n\nfunc (w write100ContinueHeadersFrame) staysWithinBuffer(max int) bool {\n\t// Sloppy but conservative:\n\treturn 9+2*(len(\":status\")+len(\"100\")) <= max\n}\n\ntype writeWindowUpdate struct {\n\tstreamID uint32 // or 0 for conn-level\n\tn        uint32\n}\n\nfunc (wu writeWindowUpdate) staysWithinBuffer(max int) bool { return frameHeaderLen+4 <= max }\n\nfunc (wu writeWindowUpdate) writeFrame(ctx writeContext) error {\n\treturn ctx.Framer().WriteWindowUpdate(wu.streamID, wu.n)\n}\n\n// encodeHeaders encodes an http.Header. If keys is not nil, then (k, h[k])\n// is encoded only if k is in keys.\nfunc encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) {\n\tif keys == nil {\n\t\tsorter := sorterPool.Get().(*sorter)\n\t\t// Using defer here, since the returned keys from the\n\t\t// sorter.Keys method is only valid until the sorter\n\t\t// is returned:\n\t\tdefer sorterPool.Put(sorter)\n\t\tkeys = sorter.Keys(h)\n\t}\n\tfor _, k := range keys {\n\t\tvv := h[k]\n\t\tk, ascii := httpcommon.LowerHeader(k)\n\t\tif !ascii {\n\t\t\t// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header\n\t\t\t// field names have to be ASCII characters (just as in HTTP/1.x).\n\t\t\tcontinue\n\t\t}\n\t\tif !validWireHeaderFieldName(k) {\n\t\t\t// Skip it as backup paranoia. Per\n\t\t\t// golang.org/issue/14048, these should\n\t\t\t// already be rejected at a higher level.\n\t\t\tcontinue\n\t\t}\n\t\tisTE := k == \"transfer-encoding\"\n\t\tfor _, v := range vv {\n\t\t\tif !httpguts.ValidHeaderFieldValue(v) {\n\t\t\t\t// TODO: return an error? golang.org/issue/14048\n\t\t\t\t// For now just omit it.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// TODO: more of \"8.1.2.2 Connection-Specific Header Fields\"\n\t\t\tif isTE && v != \"trailers\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tencKV(enc, k, v)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/writesched.go",
    "content": "// Copyright 2014 The Go 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 http2\n\nimport \"fmt\"\n\n// WriteScheduler is the interface implemented by HTTP/2 write schedulers.\n// Methods are never called concurrently.\ntype WriteScheduler interface {\n\t// OpenStream opens a new stream in the write scheduler.\n\t// It is illegal to call this with streamID=0 or with a streamID that is\n\t// already open -- the call may panic.\n\tOpenStream(streamID uint32, options OpenStreamOptions)\n\n\t// CloseStream closes a stream in the write scheduler. Any frames queued on\n\t// this stream should be discarded. It is illegal to call this on a stream\n\t// that is not open -- the call may panic.\n\tCloseStream(streamID uint32)\n\n\t// AdjustStream adjusts the priority of the given stream. This may be called\n\t// on a stream that has not yet been opened or has been closed. Note that\n\t// RFC 7540 allows PRIORITY frames to be sent on streams in any state. See:\n\t// https://tools.ietf.org/html/rfc7540#section-5.1\n\tAdjustStream(streamID uint32, priority PriorityParam)\n\n\t// Push queues a frame in the scheduler. In most cases, this will not be\n\t// called with wr.StreamID()!=0 unless that stream is currently open. The one\n\t// exception is RST_STREAM frames, which may be sent on idle or closed streams.\n\tPush(wr FrameWriteRequest)\n\n\t// Pop dequeues the next frame to write. Returns false if no frames can\n\t// be written. Frames with a given wr.StreamID() are Pop'd in the same\n\t// order they are Push'd, except RST_STREAM frames. No frames should be\n\t// discarded except by CloseStream.\n\tPop() (wr FrameWriteRequest, ok bool)\n}\n\n// OpenStreamOptions specifies extra options for WriteScheduler.OpenStream.\ntype OpenStreamOptions struct {\n\t// PusherID is zero if the stream was initiated by the client. Otherwise,\n\t// PusherID names the stream that pushed the newly opened stream.\n\tPusherID uint32\n}\n\n// FrameWriteRequest is a request to write a frame.\ntype FrameWriteRequest struct {\n\t// write is the interface value that does the writing, once the\n\t// WriteScheduler has selected this frame to write. The write\n\t// functions are all defined in write.go.\n\twrite writeFramer\n\n\t// stream is the stream on which this frame will be written.\n\t// nil for non-stream frames like PING and SETTINGS.\n\t// nil for RST_STREAM streams, which use the StreamError.StreamID field instead.\n\tstream *stream\n\n\t// done, if non-nil, must be a buffered channel with space for\n\t// 1 message and is sent the return value from write (or an\n\t// earlier error) when the frame has been written.\n\tdone chan error\n}\n\n// StreamID returns the id of the stream this frame will be written to.\n// 0 is used for non-stream frames such as PING and SETTINGS.\nfunc (wr FrameWriteRequest) StreamID() uint32 {\n\tif wr.stream == nil {\n\t\tif se, ok := wr.write.(StreamError); ok {\n\t\t\t// (*serverConn).resetStream doesn't set\n\t\t\t// stream because it doesn't necessarily have\n\t\t\t// one. So special case this type of write\n\t\t\t// message.\n\t\t\treturn se.StreamID\n\t\t}\n\t\treturn 0\n\t}\n\treturn wr.stream.id\n}\n\n// isControl reports whether wr is a control frame for MaxQueuedControlFrames\n// purposes. That includes non-stream frames and RST_STREAM frames.\nfunc (wr FrameWriteRequest) isControl() bool {\n\treturn wr.stream == nil\n}\n\n// DataSize returns the number of flow control bytes that must be consumed\n// to write this entire frame. This is 0 for non-DATA frames.\nfunc (wr FrameWriteRequest) DataSize() int {\n\tif wd, ok := wr.write.(*writeData); ok {\n\t\treturn len(wd.p)\n\t}\n\treturn 0\n}\n\n// Consume consumes min(n, available) bytes from this frame, where available\n// is the number of flow control bytes available on the stream. Consume returns\n// 0, 1, or 2 frames, where the integer return value gives the number of frames\n// returned.\n//\n// If flow control prevents consuming any bytes, this returns (_, _, 0). If\n// the entire frame was consumed, this returns (wr, _, 1). Otherwise, this\n// returns (consumed, rest, 2), where 'consumed' contains the consumed bytes and\n// 'rest' contains the remaining bytes. The consumed bytes are deducted from the\n// underlying stream's flow control budget.\nfunc (wr FrameWriteRequest) Consume(n int32) (FrameWriteRequest, FrameWriteRequest, int) {\n\tvar empty FrameWriteRequest\n\n\t// Non-DATA frames are always consumed whole.\n\twd, ok := wr.write.(*writeData)\n\tif !ok || len(wd.p) == 0 {\n\t\treturn wr, empty, 1\n\t}\n\n\t// Might need to split after applying limits.\n\tallowed := wr.stream.flow.available()\n\tif n < allowed {\n\t\tallowed = n\n\t}\n\tif wr.stream.sc.maxFrameSize < allowed {\n\t\tallowed = wr.stream.sc.maxFrameSize\n\t}\n\tif allowed <= 0 {\n\t\treturn empty, empty, 0\n\t}\n\tif len(wd.p) > int(allowed) {\n\t\twr.stream.flow.take(allowed)\n\t\tconsumed := FrameWriteRequest{\n\t\t\tstream: wr.stream,\n\t\t\twrite: &writeData{\n\t\t\t\tstreamID: wd.streamID,\n\t\t\t\tp:        wd.p[:allowed],\n\t\t\t\t// Even if the original had endStream set, there\n\t\t\t\t// are bytes remaining because len(wd.p) > allowed,\n\t\t\t\t// so we know endStream is false.\n\t\t\t\tendStream: false,\n\t\t\t},\n\t\t\t// Our caller is blocking on the final DATA frame, not\n\t\t\t// this intermediate frame, so no need to wait.\n\t\t\tdone: nil,\n\t\t}\n\t\trest := FrameWriteRequest{\n\t\t\tstream: wr.stream,\n\t\t\twrite: &writeData{\n\t\t\t\tstreamID:  wd.streamID,\n\t\t\t\tp:         wd.p[allowed:],\n\t\t\t\tendStream: wd.endStream,\n\t\t\t},\n\t\t\tdone: wr.done,\n\t\t}\n\t\treturn consumed, rest, 2\n\t}\n\n\t// The frame is consumed whole.\n\t// NB: This cast cannot overflow because allowed is <= math.MaxInt32.\n\twr.stream.flow.take(int32(len(wd.p)))\n\treturn wr, empty, 1\n}\n\n// String is for debugging only.\nfunc (wr FrameWriteRequest) String() string {\n\tvar des string\n\tif s, ok := wr.write.(fmt.Stringer); ok {\n\t\tdes = s.String()\n\t} else {\n\t\tdes = fmt.Sprintf(\"%T\", wr.write)\n\t}\n\treturn fmt.Sprintf(\"[FrameWriteRequest stream=%d, ch=%v, writer=%v]\", wr.StreamID(), wr.done != nil, des)\n}\n\n// replyToWriter sends err to wr.done and panics if the send must block\n// This does nothing if wr.done is nil.\nfunc (wr *FrameWriteRequest) replyToWriter(err error) {\n\tif wr.done == nil {\n\t\treturn\n\t}\n\tselect {\n\tcase wr.done <- err:\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unbuffered done channel passed in for type %T\", wr.write))\n\t}\n\twr.write = nil // prevent use (assume it's tainted after wr.done send)\n}\n\n// writeQueue is used by implementations of WriteScheduler.\ntype writeQueue struct {\n\ts          []FrameWriteRequest\n\tprev, next *writeQueue\n}\n\nfunc (q *writeQueue) empty() bool { return len(q.s) == 0 }\n\nfunc (q *writeQueue) push(wr FrameWriteRequest) {\n\tq.s = append(q.s, wr)\n}\n\nfunc (q *writeQueue) shift() FrameWriteRequest {\n\tif len(q.s) == 0 {\n\t\tpanic(\"invalid use of queue\")\n\t}\n\twr := q.s[0]\n\t// TODO: less copy-happy queue.\n\tcopy(q.s, q.s[1:])\n\tq.s[len(q.s)-1] = FrameWriteRequest{}\n\tq.s = q.s[:len(q.s)-1]\n\treturn wr\n}\n\n// consume consumes up to n bytes from q.s[0]. If the frame is\n// entirely consumed, it is removed from the queue. If the frame\n// is partially consumed, the frame is kept with the consumed\n// bytes removed. Returns true iff any bytes were consumed.\nfunc (q *writeQueue) consume(n int32) (FrameWriteRequest, bool) {\n\tif len(q.s) == 0 {\n\t\treturn FrameWriteRequest{}, false\n\t}\n\tconsumed, rest, numresult := q.s[0].Consume(n)\n\tswitch numresult {\n\tcase 0:\n\t\treturn FrameWriteRequest{}, false\n\tcase 1:\n\t\tq.shift()\n\tcase 2:\n\t\tq.s[0] = rest\n\t}\n\treturn consumed, true\n}\n\ntype writeQueuePool []*writeQueue\n\n// put inserts an unused writeQueue into the pool.\nfunc (p *writeQueuePool) put(q *writeQueue) {\n\tfor i := range q.s {\n\t\tq.s[i] = FrameWriteRequest{}\n\t}\n\tq.s = q.s[:0]\n\t*p = append(*p, q)\n}\n\n// get returns an empty writeQueue.\nfunc (p *writeQueuePool) get() *writeQueue {\n\tln := len(*p)\n\tif ln == 0 {\n\t\treturn new(writeQueue)\n\t}\n\tx := ln - 1\n\tq := (*p)[x]\n\t(*p)[x] = nil\n\t*p = (*p)[:x]\n\treturn q\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/writesched_priority.go",
    "content": "// Copyright 2016 The Go 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 http2\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"sort\"\n)\n\n// RFC 7540, Section 5.3.5: the default weight is 16.\nconst priorityDefaultWeight = 15 // 16 = 15 + 1\n\n// PriorityWriteSchedulerConfig configures a priorityWriteScheduler.\ntype PriorityWriteSchedulerConfig struct {\n\t// MaxClosedNodesInTree controls the maximum number of closed streams to\n\t// retain in the priority tree. Setting this to zero saves a small amount\n\t// of memory at the cost of performance.\n\t//\n\t// See RFC 7540, Section 5.3.4:\n\t//   \"It is possible for a stream to become closed while prioritization\n\t//   information ... is in transit. ... This potentially creates suboptimal\n\t//   prioritization, since the stream could be given a priority that is\n\t//   different from what is intended. To avoid these problems, an endpoint\n\t//   SHOULD retain stream prioritization state for a period after streams\n\t//   become closed. The longer state is retained, the lower the chance that\n\t//   streams are assigned incorrect or default priority values.\"\n\tMaxClosedNodesInTree int\n\n\t// MaxIdleNodesInTree controls the maximum number of idle streams to\n\t// retain in the priority tree. Setting this to zero saves a small amount\n\t// of memory at the cost of performance.\n\t//\n\t// See RFC 7540, Section 5.3.4:\n\t//   Similarly, streams that are in the \"idle\" state can be assigned\n\t//   priority or become a parent of other streams. This allows for the\n\t//   creation of a grouping node in the dependency tree, which enables\n\t//   more flexible expressions of priority. Idle streams begin with a\n\t//   default priority (Section 5.3.5).\n\tMaxIdleNodesInTree int\n\n\t// ThrottleOutOfOrderWrites enables write throttling to help ensure that\n\t// data is delivered in priority order. This works around a race where\n\t// stream B depends on stream A and both streams are about to call Write\n\t// to queue DATA frames. If B wins the race, a naive scheduler would eagerly\n\t// write as much data from B as possible, but this is suboptimal because A\n\t// is a higher-priority stream. With throttling enabled, we write a small\n\t// amount of data from B to minimize the amount of bandwidth that B can\n\t// steal from A.\n\tThrottleOutOfOrderWrites bool\n}\n\n// NewPriorityWriteScheduler constructs a WriteScheduler that schedules\n// frames by following HTTP/2 priorities as described in RFC 7540 Section 5.3.\n// If cfg is nil, default options are used.\nfunc NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler {\n\tif cfg == nil {\n\t\t// For justification of these defaults, see:\n\t\t// https://docs.google.com/document/d/1oLhNg1skaWD4_DtaoCxdSRN5erEXrH-KnLrMwEpOtFY\n\t\tcfg = &PriorityWriteSchedulerConfig{\n\t\t\tMaxClosedNodesInTree:     10,\n\t\t\tMaxIdleNodesInTree:       10,\n\t\t\tThrottleOutOfOrderWrites: false,\n\t\t}\n\t}\n\n\tws := &priorityWriteScheduler{\n\t\tnodes:                make(map[uint32]*priorityNode),\n\t\tmaxClosedNodesInTree: cfg.MaxClosedNodesInTree,\n\t\tmaxIdleNodesInTree:   cfg.MaxIdleNodesInTree,\n\t\tenableWriteThrottle:  cfg.ThrottleOutOfOrderWrites,\n\t}\n\tws.nodes[0] = &ws.root\n\tif cfg.ThrottleOutOfOrderWrites {\n\t\tws.writeThrottleLimit = 1024\n\t} else {\n\t\tws.writeThrottleLimit = math.MaxInt32\n\t}\n\treturn ws\n}\n\ntype priorityNodeState int\n\nconst (\n\tpriorityNodeOpen priorityNodeState = iota\n\tpriorityNodeClosed\n\tpriorityNodeIdle\n)\n\n// priorityNode is a node in an HTTP/2 priority tree.\n// Each node is associated with a single stream ID.\n// See RFC 7540, Section 5.3.\ntype priorityNode struct {\n\tq            writeQueue        // queue of pending frames to write\n\tid           uint32            // id of the stream, or 0 for the root of the tree\n\tweight       uint8             // the actual weight is weight+1, so the value is in [1,256]\n\tstate        priorityNodeState // open | closed | idle\n\tbytes        int64             // number of bytes written by this node, or 0 if closed\n\tsubtreeBytes int64             // sum(node.bytes) of all nodes in this subtree\n\n\t// These links form the priority tree.\n\tparent     *priorityNode\n\tkids       *priorityNode // start of the kids list\n\tprev, next *priorityNode // doubly-linked list of siblings\n}\n\nfunc (n *priorityNode) setParent(parent *priorityNode) {\n\tif n == parent {\n\t\tpanic(\"setParent to self\")\n\t}\n\tif n.parent == parent {\n\t\treturn\n\t}\n\t// Unlink from current parent.\n\tif parent := n.parent; parent != nil {\n\t\tif n.prev == nil {\n\t\t\tparent.kids = n.next\n\t\t} else {\n\t\t\tn.prev.next = n.next\n\t\t}\n\t\tif n.next != nil {\n\t\t\tn.next.prev = n.prev\n\t\t}\n\t}\n\t// Link to new parent.\n\t// If parent=nil, remove n from the tree.\n\t// Always insert at the head of parent.kids (this is assumed by walkReadyInOrder).\n\tn.parent = parent\n\tif parent == nil {\n\t\tn.next = nil\n\t\tn.prev = nil\n\t} else {\n\t\tn.next = parent.kids\n\t\tn.prev = nil\n\t\tif n.next != nil {\n\t\t\tn.next.prev = n\n\t\t}\n\t\tparent.kids = n\n\t}\n}\n\nfunc (n *priorityNode) addBytes(b int64) {\n\tn.bytes += b\n\tfor ; n != nil; n = n.parent {\n\t\tn.subtreeBytes += b\n\t}\n}\n\n// walkReadyInOrder iterates over the tree in priority order, calling f for each node\n// with a non-empty write queue. When f returns true, this function returns true and the\n// walk halts. tmp is used as scratch space for sorting.\n//\n// f(n, openParent) takes two arguments: the node to visit, n, and a bool that is true\n// if any ancestor p of n is still open (ignoring the root node).\nfunc (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f func(*priorityNode, bool) bool) bool {\n\tif !n.q.empty() && f(n, openParent) {\n\t\treturn true\n\t}\n\tif n.kids == nil {\n\t\treturn false\n\t}\n\n\t// Don't consider the root \"open\" when updating openParent since\n\t// we can't send data frames on the root stream (only control frames).\n\tif n.id != 0 {\n\t\topenParent = openParent || (n.state == priorityNodeOpen)\n\t}\n\n\t// Common case: only one kid or all kids have the same weight.\n\t// Some clients don't use weights; other clients (like web browsers)\n\t// use mostly-linear priority trees.\n\tw := n.kids.weight\n\tneedSort := false\n\tfor k := n.kids.next; k != nil; k = k.next {\n\t\tif k.weight != w {\n\t\t\tneedSort = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif !needSort {\n\t\tfor k := n.kids; k != nil; k = k.next {\n\t\t\tif k.walkReadyInOrder(openParent, tmp, f) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\n\t// Uncommon case: sort the child nodes. We remove the kids from the parent,\n\t// then re-insert after sorting so we can reuse tmp for future sort calls.\n\t*tmp = (*tmp)[:0]\n\tfor n.kids != nil {\n\t\t*tmp = append(*tmp, n.kids)\n\t\tn.kids.setParent(nil)\n\t}\n\tsort.Sort(sortPriorityNodeSiblings(*tmp))\n\tfor i := len(*tmp) - 1; i >= 0; i-- {\n\t\t(*tmp)[i].setParent(n) // setParent inserts at the head of n.kids\n\t}\n\tfor k := n.kids; k != nil; k = k.next {\n\t\tif k.walkReadyInOrder(openParent, tmp, f) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\ntype sortPriorityNodeSiblings []*priorityNode\n\nfunc (z sortPriorityNodeSiblings) Len() int      { return len(z) }\nfunc (z sortPriorityNodeSiblings) Swap(i, k int) { z[i], z[k] = z[k], z[i] }\nfunc (z sortPriorityNodeSiblings) Less(i, k int) bool {\n\t// Prefer the subtree that has sent fewer bytes relative to its weight.\n\t// See sections 5.3.2 and 5.3.4.\n\twi, bi := float64(z[i].weight+1), float64(z[i].subtreeBytes)\n\twk, bk := float64(z[k].weight+1), float64(z[k].subtreeBytes)\n\tif bi == 0 && bk == 0 {\n\t\treturn wi >= wk\n\t}\n\tif bk == 0 {\n\t\treturn false\n\t}\n\treturn bi/bk <= wi/wk\n}\n\ntype priorityWriteScheduler struct {\n\t// root is the root of the priority tree, where root.id = 0.\n\t// The root queues control frames that are not associated with any stream.\n\troot priorityNode\n\n\t// nodes maps stream ids to priority tree nodes.\n\tnodes map[uint32]*priorityNode\n\n\t// maxID is the maximum stream id in nodes.\n\tmaxID uint32\n\n\t// lists of nodes that have been closed or are idle, but are kept in\n\t// the tree for improved prioritization. When the lengths exceed either\n\t// maxClosedNodesInTree or maxIdleNodesInTree, old nodes are discarded.\n\tclosedNodes, idleNodes []*priorityNode\n\n\t// From the config.\n\tmaxClosedNodesInTree int\n\tmaxIdleNodesInTree   int\n\twriteThrottleLimit   int32\n\tenableWriteThrottle  bool\n\n\t// tmp is scratch space for priorityNode.walkReadyInOrder to reduce allocations.\n\ttmp []*priorityNode\n\n\t// pool of empty queues for reuse.\n\tqueuePool writeQueuePool\n}\n\nfunc (ws *priorityWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) {\n\t// The stream may be currently idle but cannot be opened or closed.\n\tif curr := ws.nodes[streamID]; curr != nil {\n\t\tif curr.state != priorityNodeIdle {\n\t\t\tpanic(fmt.Sprintf(\"stream %d already opened\", streamID))\n\t\t}\n\t\tcurr.state = priorityNodeOpen\n\t\treturn\n\t}\n\n\t// RFC 7540, Section 5.3.5:\n\t//  \"All streams are initially assigned a non-exclusive dependency on stream 0x0.\n\t//  Pushed streams initially depend on their associated stream. In both cases,\n\t//  streams are assigned a default weight of 16.\"\n\tparent := ws.nodes[options.PusherID]\n\tif parent == nil {\n\t\tparent = &ws.root\n\t}\n\tn := &priorityNode{\n\t\tq:      *ws.queuePool.get(),\n\t\tid:     streamID,\n\t\tweight: priorityDefaultWeight,\n\t\tstate:  priorityNodeOpen,\n\t}\n\tn.setParent(parent)\n\tws.nodes[streamID] = n\n\tif streamID > ws.maxID {\n\t\tws.maxID = streamID\n\t}\n}\n\nfunc (ws *priorityWriteScheduler) CloseStream(streamID uint32) {\n\tif streamID == 0 {\n\t\tpanic(\"violation of WriteScheduler interface: cannot close stream 0\")\n\t}\n\tif ws.nodes[streamID] == nil {\n\t\tpanic(fmt.Sprintf(\"violation of WriteScheduler interface: unknown stream %d\", streamID))\n\t}\n\tif ws.nodes[streamID].state != priorityNodeOpen {\n\t\tpanic(fmt.Sprintf(\"violation of WriteScheduler interface: stream %d already closed\", streamID))\n\t}\n\n\tn := ws.nodes[streamID]\n\tn.state = priorityNodeClosed\n\tn.addBytes(-n.bytes)\n\n\tq := n.q\n\tws.queuePool.put(&q)\n\tn.q.s = nil\n\tif ws.maxClosedNodesInTree > 0 {\n\t\tws.addClosedOrIdleNode(&ws.closedNodes, ws.maxClosedNodesInTree, n)\n\t} else {\n\t\tws.removeNode(n)\n\t}\n}\n\nfunc (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) {\n\tif streamID == 0 {\n\t\tpanic(\"adjustPriority on root\")\n\t}\n\n\t// If streamID does not exist, there are two cases:\n\t// - A closed stream that has been removed (this will have ID <= maxID)\n\t// - An idle stream that is being used for \"grouping\" (this will have ID > maxID)\n\tn := ws.nodes[streamID]\n\tif n == nil {\n\t\tif streamID <= ws.maxID || ws.maxIdleNodesInTree == 0 {\n\t\t\treturn\n\t\t}\n\t\tws.maxID = streamID\n\t\tn = &priorityNode{\n\t\t\tq:      *ws.queuePool.get(),\n\t\t\tid:     streamID,\n\t\t\tweight: priorityDefaultWeight,\n\t\t\tstate:  priorityNodeIdle,\n\t\t}\n\t\tn.setParent(&ws.root)\n\t\tws.nodes[streamID] = n\n\t\tws.addClosedOrIdleNode(&ws.idleNodes, ws.maxIdleNodesInTree, n)\n\t}\n\n\t// Section 5.3.1: A dependency on a stream that is not currently in the tree\n\t// results in that stream being given a default priority (Section 5.3.5).\n\tparent := ws.nodes[priority.StreamDep]\n\tif parent == nil {\n\t\tn.setParent(&ws.root)\n\t\tn.weight = priorityDefaultWeight\n\t\treturn\n\t}\n\n\t// Ignore if the client tries to make a node its own parent.\n\tif n == parent {\n\t\treturn\n\t}\n\n\t// Section 5.3.3:\n\t//   \"If a stream is made dependent on one of its own dependencies, the\n\t//   formerly dependent stream is first moved to be dependent on the\n\t//   reprioritized stream's previous parent. The moved dependency retains\n\t//   its weight.\"\n\t//\n\t// That is: if parent depends on n, move parent to depend on n.parent.\n\tfor x := parent.parent; x != nil; x = x.parent {\n\t\tif x == n {\n\t\t\tparent.setParent(n.parent)\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Section 5.3.3: The exclusive flag causes the stream to become the sole\n\t// dependency of its parent stream, causing other dependencies to become\n\t// dependent on the exclusive stream.\n\tif priority.Exclusive {\n\t\tk := parent.kids\n\t\tfor k != nil {\n\t\t\tnext := k.next\n\t\t\tif k != n {\n\t\t\t\tk.setParent(n)\n\t\t\t}\n\t\t\tk = next\n\t\t}\n\t}\n\n\tn.setParent(parent)\n\tn.weight = priority.Weight\n}\n\nfunc (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) {\n\tvar n *priorityNode\n\tif wr.isControl() {\n\t\tn = &ws.root\n\t} else {\n\t\tid := wr.StreamID()\n\t\tn = ws.nodes[id]\n\t\tif n == nil {\n\t\t\t// id is an idle or closed stream. wr should not be a HEADERS or\n\t\t\t// DATA frame. In other case, we push wr onto the root, rather\n\t\t\t// than creating a new priorityNode.\n\t\t\tif wr.DataSize() > 0 {\n\t\t\t\tpanic(\"add DATA on non-open stream\")\n\t\t\t}\n\t\t\tn = &ws.root\n\t\t}\n\t}\n\tn.q.push(wr)\n}\n\nfunc (ws *priorityWriteScheduler) Pop() (wr FrameWriteRequest, ok bool) {\n\tws.root.walkReadyInOrder(false, &ws.tmp, func(n *priorityNode, openParent bool) bool {\n\t\tlimit := int32(math.MaxInt32)\n\t\tif openParent {\n\t\t\tlimit = ws.writeThrottleLimit\n\t\t}\n\t\twr, ok = n.q.consume(limit)\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\t\tn.addBytes(int64(wr.DataSize()))\n\t\t// If B depends on A and B continuously has data available but A\n\t\t// does not, gradually increase the throttling limit to allow B to\n\t\t// steal more and more bandwidth from A.\n\t\tif openParent {\n\t\t\tws.writeThrottleLimit += 1024\n\t\t\tif ws.writeThrottleLimit < 0 {\n\t\t\t\tws.writeThrottleLimit = math.MaxInt32\n\t\t\t}\n\t\t} else if ws.enableWriteThrottle {\n\t\t\tws.writeThrottleLimit = 1024\n\t\t}\n\t\treturn true\n\t})\n\treturn wr, ok\n}\n\nfunc (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, maxSize int, n *priorityNode) {\n\tif maxSize == 0 {\n\t\treturn\n\t}\n\tif len(*list) == maxSize {\n\t\t// Remove the oldest node, then shift left.\n\t\tws.removeNode((*list)[0])\n\t\tx := (*list)[1:]\n\t\tcopy(*list, x)\n\t\t*list = (*list)[:len(x)]\n\t}\n\t*list = append(*list, n)\n}\n\nfunc (ws *priorityWriteScheduler) removeNode(n *priorityNode) {\n\tfor n.kids != nil {\n\t\tn.kids.setParent(n.parent)\n\t}\n\tn.setParent(nil)\n\tdelete(ws.nodes, n.id)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/writesched_random.go",
    "content": "// Copyright 2014 The Go 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 http2\n\nimport \"math\"\n\n// NewRandomWriteScheduler constructs a WriteScheduler that ignores HTTP/2\n// priorities. Control frames like SETTINGS and PING are written before DATA\n// frames, but if no control frames are queued and multiple streams have queued\n// HEADERS or DATA frames, Pop selects a ready stream arbitrarily.\nfunc NewRandomWriteScheduler() WriteScheduler {\n\treturn &randomWriteScheduler{sq: make(map[uint32]*writeQueue)}\n}\n\ntype randomWriteScheduler struct {\n\t// zero are frames not associated with a specific stream.\n\tzero writeQueue\n\n\t// sq contains the stream-specific queues, keyed by stream ID.\n\t// When a stream is idle, closed, or emptied, it's deleted\n\t// from the map.\n\tsq map[uint32]*writeQueue\n\n\t// pool of empty queues for reuse.\n\tqueuePool writeQueuePool\n}\n\nfunc (ws *randomWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) {\n\t// no-op: idle streams are not tracked\n}\n\nfunc (ws *randomWriteScheduler) CloseStream(streamID uint32) {\n\tq, ok := ws.sq[streamID]\n\tif !ok {\n\t\treturn\n\t}\n\tdelete(ws.sq, streamID)\n\tws.queuePool.put(q)\n}\n\nfunc (ws *randomWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) {\n\t// no-op: priorities are ignored\n}\n\nfunc (ws *randomWriteScheduler) Push(wr FrameWriteRequest) {\n\tif wr.isControl() {\n\t\tws.zero.push(wr)\n\t\treturn\n\t}\n\tid := wr.StreamID()\n\tq, ok := ws.sq[id]\n\tif !ok {\n\t\tq = ws.queuePool.get()\n\t\tws.sq[id] = q\n\t}\n\tq.push(wr)\n}\n\nfunc (ws *randomWriteScheduler) Pop() (FrameWriteRequest, bool) {\n\t// Control and RST_STREAM frames first.\n\tif !ws.zero.empty() {\n\t\treturn ws.zero.shift(), true\n\t}\n\t// Iterate over all non-idle streams until finding one that can be consumed.\n\tfor streamID, q := range ws.sq {\n\t\tif wr, ok := q.consume(math.MaxInt32); ok {\n\t\t\tif q.empty() {\n\t\t\t\tdelete(ws.sq, streamID)\n\t\t\t\tws.queuePool.put(q)\n\t\t\t}\n\t\t\treturn wr, true\n\t\t}\n\t}\n\treturn FrameWriteRequest{}, false\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/writesched_roundrobin.go",
    "content": "// Copyright 2023 The Go 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 http2\n\nimport (\n\t\"fmt\"\n\t\"math\"\n)\n\ntype roundRobinWriteScheduler struct {\n\t// control contains control frames (SETTINGS, PING, etc.).\n\tcontrol writeQueue\n\n\t// streams maps stream ID to a queue.\n\tstreams map[uint32]*writeQueue\n\n\t// stream queues are stored in a circular linked list.\n\t// head is the next stream to write, or nil if there are no streams open.\n\thead *writeQueue\n\n\t// pool of empty queues for reuse.\n\tqueuePool writeQueuePool\n}\n\n// newRoundRobinWriteScheduler constructs a new write scheduler.\n// The round robin scheduler priorizes control frames\n// like SETTINGS and PING over DATA frames.\n// When there are no control frames to send, it performs a round-robin\n// selection from the ready streams.\nfunc newRoundRobinWriteScheduler() WriteScheduler {\n\tws := &roundRobinWriteScheduler{\n\t\tstreams: make(map[uint32]*writeQueue),\n\t}\n\treturn ws\n}\n\nfunc (ws *roundRobinWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) {\n\tif ws.streams[streamID] != nil {\n\t\tpanic(fmt.Errorf(\"stream %d already opened\", streamID))\n\t}\n\tq := ws.queuePool.get()\n\tws.streams[streamID] = q\n\tif ws.head == nil {\n\t\tws.head = q\n\t\tq.next = q\n\t\tq.prev = q\n\t} else {\n\t\t// Queues are stored in a ring.\n\t\t// Insert the new stream before ws.head, putting it at the end of the list.\n\t\tq.prev = ws.head.prev\n\t\tq.next = ws.head\n\t\tq.prev.next = q\n\t\tq.next.prev = q\n\t}\n}\n\nfunc (ws *roundRobinWriteScheduler) CloseStream(streamID uint32) {\n\tq := ws.streams[streamID]\n\tif q == nil {\n\t\treturn\n\t}\n\tif q.next == q {\n\t\t// This was the only open stream.\n\t\tws.head = nil\n\t} else {\n\t\tq.prev.next = q.next\n\t\tq.next.prev = q.prev\n\t\tif ws.head == q {\n\t\t\tws.head = q.next\n\t\t}\n\t}\n\tdelete(ws.streams, streamID)\n\tws.queuePool.put(q)\n}\n\nfunc (ws *roundRobinWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) {}\n\nfunc (ws *roundRobinWriteScheduler) Push(wr FrameWriteRequest) {\n\tif wr.isControl() {\n\t\tws.control.push(wr)\n\t\treturn\n\t}\n\tq := ws.streams[wr.StreamID()]\n\tif q == nil {\n\t\t// This is a closed stream.\n\t\t// wr should not be a HEADERS or DATA frame.\n\t\t// We push the request onto the control queue.\n\t\tif wr.DataSize() > 0 {\n\t\t\tpanic(\"add DATA on non-open stream\")\n\t\t}\n\t\tws.control.push(wr)\n\t\treturn\n\t}\n\tq.push(wr)\n}\n\nfunc (ws *roundRobinWriteScheduler) Pop() (FrameWriteRequest, bool) {\n\t// Control and RST_STREAM frames first.\n\tif !ws.control.empty() {\n\t\treturn ws.control.shift(), true\n\t}\n\tif ws.head == nil {\n\t\treturn FrameWriteRequest{}, false\n\t}\n\tq := ws.head\n\tfor {\n\t\tif wr, ok := q.consume(math.MaxInt32); ok {\n\t\t\tws.head = q.next\n\t\t\treturn wr, true\n\t\t}\n\t\tq = q.next\n\t\tif q == ws.head {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn FrameWriteRequest{}, false\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/dstunreach.go",
    "content": "// Copyright 2014 The Go 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 icmp\n\nimport (\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/ipv4\"\n\t\"golang.org/x/net/ipv6\"\n)\n\n// A DstUnreach represents an ICMP destination unreachable message\n// body.\ntype DstUnreach struct {\n\tData       []byte      // data, known as original datagram field\n\tExtensions []Extension // extensions\n}\n\n// Len implements the Len method of MessageBody interface.\nfunc (p *DstUnreach) Len(proto int) int {\n\tif p == nil {\n\t\treturn 0\n\t}\n\tl, _ := multipartMessageBodyDataLen(proto, true, p.Data, p.Extensions)\n\treturn l\n}\n\n// Marshal implements the Marshal method of MessageBody interface.\nfunc (p *DstUnreach) Marshal(proto int) ([]byte, error) {\n\tvar typ Type\n\tswitch proto {\n\tcase iana.ProtocolICMP:\n\t\ttyp = ipv4.ICMPTypeDestinationUnreachable\n\tcase iana.ProtocolIPv6ICMP:\n\t\ttyp = ipv6.ICMPTypeDestinationUnreachable\n\tdefault:\n\t\treturn nil, errInvalidProtocol\n\t}\n\tif !validExtensions(typ, p.Extensions) {\n\t\treturn nil, errInvalidExtension\n\t}\n\treturn marshalMultipartMessageBody(proto, true, p.Data, p.Extensions)\n}\n\n// parseDstUnreach parses b as an ICMP destination unreachable message\n// body.\nfunc parseDstUnreach(proto int, typ Type, b []byte) (MessageBody, error) {\n\tif len(b) < 4 {\n\t\treturn nil, errMessageTooShort\n\t}\n\tp := &DstUnreach{}\n\tvar err error\n\tp.Data, p.Extensions, err = parseMultipartMessageBody(proto, typ, b)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn p, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/echo.go",
    "content": "// Copyright 2012 The Go 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 icmp\n\nimport (\n\t\"encoding/binary\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/ipv4\"\n\t\"golang.org/x/net/ipv6\"\n)\n\n// An Echo represents an ICMP echo request or reply message body.\ntype Echo struct {\n\tID   int    // identifier\n\tSeq  int    // sequence number\n\tData []byte // data\n}\n\n// Len implements the Len method of MessageBody interface.\nfunc (p *Echo) Len(proto int) int {\n\tif p == nil {\n\t\treturn 0\n\t}\n\treturn 4 + len(p.Data)\n}\n\n// Marshal implements the Marshal method of MessageBody interface.\nfunc (p *Echo) Marshal(proto int) ([]byte, error) {\n\tb := make([]byte, 4+len(p.Data))\n\tbinary.BigEndian.PutUint16(b[:2], uint16(p.ID))\n\tbinary.BigEndian.PutUint16(b[2:4], uint16(p.Seq))\n\tcopy(b[4:], p.Data)\n\treturn b, nil\n}\n\n// parseEcho parses b as an ICMP echo request or reply message body.\nfunc parseEcho(proto int, _ Type, b []byte) (MessageBody, error) {\n\tbodyLen := len(b)\n\tif bodyLen < 4 {\n\t\treturn nil, errMessageTooShort\n\t}\n\tp := &Echo{ID: int(binary.BigEndian.Uint16(b[:2])), Seq: int(binary.BigEndian.Uint16(b[2:4]))}\n\tif bodyLen > 4 {\n\t\tp.Data = make([]byte, bodyLen-4)\n\t\tcopy(p.Data, b[4:])\n\t}\n\treturn p, nil\n}\n\n// An ExtendedEchoRequest represents an ICMP extended echo request\n// message body.\ntype ExtendedEchoRequest struct {\n\tID         int         // identifier\n\tSeq        int         // sequence number\n\tLocal      bool        // must be true when identifying by name or index\n\tExtensions []Extension // extensions\n}\n\n// Len implements the Len method of MessageBody interface.\nfunc (p *ExtendedEchoRequest) Len(proto int) int {\n\tif p == nil {\n\t\treturn 0\n\t}\n\tl, _ := multipartMessageBodyDataLen(proto, false, nil, p.Extensions)\n\treturn l\n}\n\n// Marshal implements the Marshal method of MessageBody interface.\nfunc (p *ExtendedEchoRequest) Marshal(proto int) ([]byte, error) {\n\tvar typ Type\n\tswitch proto {\n\tcase iana.ProtocolICMP:\n\t\ttyp = ipv4.ICMPTypeExtendedEchoRequest\n\tcase iana.ProtocolIPv6ICMP:\n\t\ttyp = ipv6.ICMPTypeExtendedEchoRequest\n\tdefault:\n\t\treturn nil, errInvalidProtocol\n\t}\n\tif !validExtensions(typ, p.Extensions) {\n\t\treturn nil, errInvalidExtension\n\t}\n\tb, err := marshalMultipartMessageBody(proto, false, nil, p.Extensions)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tbinary.BigEndian.PutUint16(b[:2], uint16(p.ID))\n\tb[2] = byte(p.Seq)\n\tif p.Local {\n\t\tb[3] |= 0x01\n\t}\n\treturn b, nil\n}\n\n// parseExtendedEchoRequest parses b as an ICMP extended echo request\n// message body.\nfunc parseExtendedEchoRequest(proto int, typ Type, b []byte) (MessageBody, error) {\n\tif len(b) < 4 {\n\t\treturn nil, errMessageTooShort\n\t}\n\tp := &ExtendedEchoRequest{ID: int(binary.BigEndian.Uint16(b[:2])), Seq: int(b[2])}\n\tif b[3]&0x01 != 0 {\n\t\tp.Local = true\n\t}\n\tvar err error\n\t_, p.Extensions, err = parseMultipartMessageBody(proto, typ, b)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn p, nil\n}\n\n// An ExtendedEchoReply represents an ICMP extended echo reply message\n// body.\ntype ExtendedEchoReply struct {\n\tID     int  // identifier\n\tSeq    int  // sequence number\n\tState  int  // 3-bit state working together with Message.Code\n\tActive bool // probed interface is active\n\tIPv4   bool // probed interface runs IPv4\n\tIPv6   bool // probed interface runs IPv6\n}\n\n// Len implements the Len method of MessageBody interface.\nfunc (p *ExtendedEchoReply) Len(proto int) int {\n\tif p == nil {\n\t\treturn 0\n\t}\n\treturn 4\n}\n\n// Marshal implements the Marshal method of MessageBody interface.\nfunc (p *ExtendedEchoReply) Marshal(proto int) ([]byte, error) {\n\tb := make([]byte, 4)\n\tbinary.BigEndian.PutUint16(b[:2], uint16(p.ID))\n\tb[2] = byte(p.Seq)\n\tb[3] = byte(p.State<<5) & 0xe0\n\tif p.Active {\n\t\tb[3] |= 0x04\n\t}\n\tif p.IPv4 {\n\t\tb[3] |= 0x02\n\t}\n\tif p.IPv6 {\n\t\tb[3] |= 0x01\n\t}\n\treturn b, nil\n}\n\n// parseExtendedEchoReply parses b as an ICMP extended echo reply\n// message body.\nfunc parseExtendedEchoReply(proto int, _ Type, b []byte) (MessageBody, error) {\n\tif len(b) < 4 {\n\t\treturn nil, errMessageTooShort\n\t}\n\tp := &ExtendedEchoReply{\n\t\tID:    int(binary.BigEndian.Uint16(b[:2])),\n\t\tSeq:   int(b[2]),\n\t\tState: int(b[3]) >> 5,\n\t}\n\tif b[3]&0x04 != 0 {\n\t\tp.Active = true\n\t}\n\tif b[3]&0x02 != 0 {\n\t\tp.IPv4 = true\n\t}\n\tif b[3]&0x01 != 0 {\n\t\tp.IPv6 = true\n\t}\n\treturn p, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/endpoint.go",
    "content": "// Copyright 2014 The Go 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 icmp\n\nimport (\n\t\"net\"\n\t\"runtime\"\n\t\"time\"\n\n\t\"golang.org/x/net/ipv4\"\n\t\"golang.org/x/net/ipv6\"\n)\n\nvar _ net.PacketConn = &PacketConn{}\n\n// A PacketConn represents a packet network endpoint that uses either\n// ICMPv4 or ICMPv6.\ntype PacketConn struct {\n\tc  net.PacketConn\n\tp4 *ipv4.PacketConn\n\tp6 *ipv6.PacketConn\n}\n\nfunc (c *PacketConn) ok() bool { return c != nil && c.c != nil }\n\n// IPv4PacketConn returns the ipv4.PacketConn of c.\n// It returns nil when c is not created as the endpoint for ICMPv4.\nfunc (c *PacketConn) IPv4PacketConn() *ipv4.PacketConn {\n\tif !c.ok() {\n\t\treturn nil\n\t}\n\treturn c.p4\n}\n\n// IPv6PacketConn returns the ipv6.PacketConn of c.\n// It returns nil when c is not created as the endpoint for ICMPv6.\nfunc (c *PacketConn) IPv6PacketConn() *ipv6.PacketConn {\n\tif !c.ok() {\n\t\treturn nil\n\t}\n\treturn c.p6\n}\n\n// ReadFrom reads an ICMP message from the connection.\nfunc (c *PacketConn) ReadFrom(b []byte) (int, net.Addr, error) {\n\tif !c.ok() {\n\t\treturn 0, nil, errInvalidConn\n\t}\n\t// Please be informed that ipv4.NewPacketConn enables\n\t// IP_STRIPHDR option by default on Darwin.\n\t// See golang.org/issue/9395 for further information.\n\tif (runtime.GOOS == \"darwin\" || runtime.GOOS == \"ios\") && c.p4 != nil {\n\t\tn, _, peer, err := c.p4.ReadFrom(b)\n\t\treturn n, peer, err\n\t}\n\treturn c.c.ReadFrom(b)\n}\n\n// WriteTo writes the ICMP message b to dst.\n// The provided dst must be net.UDPAddr when c is a non-privileged\n// datagram-oriented ICMP endpoint.\n// Otherwise it must be net.IPAddr.\nfunc (c *PacketConn) WriteTo(b []byte, dst net.Addr) (int, error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\treturn c.c.WriteTo(b, dst)\n}\n\n// Close closes the endpoint.\nfunc (c *PacketConn) Close() error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn c.c.Close()\n}\n\n// LocalAddr returns the local network address.\nfunc (c *PacketConn) LocalAddr() net.Addr {\n\tif !c.ok() {\n\t\treturn nil\n\t}\n\treturn c.c.LocalAddr()\n}\n\n// SetDeadline sets the read and write deadlines associated with the\n// endpoint.\nfunc (c *PacketConn) SetDeadline(t time.Time) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn c.c.SetDeadline(t)\n}\n\n// SetReadDeadline sets the read deadline associated with the\n// endpoint.\nfunc (c *PacketConn) SetReadDeadline(t time.Time) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn c.c.SetReadDeadline(t)\n}\n\n// SetWriteDeadline sets the write deadline associated with the\n// endpoint.\nfunc (c *PacketConn) SetWriteDeadline(t time.Time) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn c.c.SetWriteDeadline(t)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/extension.go",
    "content": "// Copyright 2015 The Go 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 icmp\n\nimport (\n\t\"encoding/binary\"\n\n\t\"golang.org/x/net/ipv4\"\n\t\"golang.org/x/net/ipv6\"\n)\n\n// An Extension represents an ICMP extension.\ntype Extension interface {\n\t// Len returns the length of ICMP extension.\n\t// The provided proto must be either the ICMPv4 or ICMPv6\n\t// protocol number.\n\tLen(proto int) int\n\n\t// Marshal returns the binary encoding of ICMP extension.\n\t// The provided proto must be either the ICMPv4 or ICMPv6\n\t// protocol number.\n\tMarshal(proto int) ([]byte, error)\n}\n\nconst extensionVersion = 2\n\nfunc validExtensionHeader(b []byte) bool {\n\tv := int(b[0]&0xf0) >> 4\n\ts := binary.BigEndian.Uint16(b[2:4])\n\tif s != 0 {\n\t\ts = checksum(b)\n\t}\n\tif v != extensionVersion || s != 0 {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// parseExtensions parses b as a list of ICMP extensions.\n// The length attribute l must be the length attribute field in\n// received icmp messages.\n//\n// It will return a list of ICMP extensions and an adjusted length\n// attribute that represents the length of the padded original\n// datagram field. Otherwise, it returns an error.\nfunc parseExtensions(typ Type, b []byte, l int) ([]Extension, int, error) {\n\t// Still a lot of non-RFC 4884 compliant implementations are\n\t// out there. Set the length attribute l to 128 when it looks\n\t// inappropriate for backwards compatibility.\n\t//\n\t// A minimal extension at least requires 8 octets; 4 octets\n\t// for an extension header, and 4 octets for a single object\n\t// header.\n\t//\n\t// See RFC 4884 for further information.\n\tswitch typ {\n\tcase ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest:\n\t\tif len(b) < 8 || !validExtensionHeader(b) {\n\t\t\treturn nil, -1, errNoExtension\n\t\t}\n\t\tl = 0\n\tdefault:\n\t\tif 128 > l || l+8 > len(b) {\n\t\t\tl = 128\n\t\t}\n\t\tif l+8 > len(b) {\n\t\t\treturn nil, -1, errNoExtension\n\t\t}\n\t\tif !validExtensionHeader(b[l:]) {\n\t\t\tif l == 128 {\n\t\t\t\treturn nil, -1, errNoExtension\n\t\t\t}\n\t\t\tl = 128\n\t\t\tif !validExtensionHeader(b[l:]) {\n\t\t\t\treturn nil, -1, errNoExtension\n\t\t\t}\n\t\t}\n\t}\n\tvar exts []Extension\n\tfor b = b[l+4:]; len(b) >= 4; {\n\t\tol := int(binary.BigEndian.Uint16(b[:2]))\n\t\tif 4 > ol || ol > len(b) {\n\t\t\tbreak\n\t\t}\n\t\tswitch b[2] {\n\t\tcase classMPLSLabelStack:\n\t\t\text, err := parseMPLSLabelStack(b[:ol])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, -1, err\n\t\t\t}\n\t\t\texts = append(exts, ext)\n\t\tcase classInterfaceInfo:\n\t\t\text, err := parseInterfaceInfo(b[:ol])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, -1, err\n\t\t\t}\n\t\t\texts = append(exts, ext)\n\t\tcase classInterfaceIdent:\n\t\t\text, err := parseInterfaceIdent(b[:ol])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, -1, err\n\t\t\t}\n\t\t\texts = append(exts, ext)\n\t\tdefault:\n\t\t\text := &RawExtension{Data: make([]byte, ol)}\n\t\t\tcopy(ext.Data, b[:ol])\n\t\t\texts = append(exts, ext)\n\t\t}\n\t\tb = b[ol:]\n\t}\n\treturn exts, l, nil\n}\n\nfunc validExtensions(typ Type, exts []Extension) bool {\n\tswitch typ {\n\tcase ipv4.ICMPTypeDestinationUnreachable, ipv4.ICMPTypeTimeExceeded, ipv4.ICMPTypeParameterProblem,\n\t\tipv6.ICMPTypeDestinationUnreachable, ipv6.ICMPTypeTimeExceeded:\n\t\tfor i := range exts {\n\t\t\tswitch exts[i].(type) {\n\t\t\tcase *MPLSLabelStack, *InterfaceInfo, *RawExtension:\n\t\t\tdefault:\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\tcase ipv4.ICMPTypeExtendedEchoRequest, ipv6.ICMPTypeExtendedEchoRequest:\n\t\tvar n int\n\t\tfor i := range exts {\n\t\t\tswitch exts[i].(type) {\n\t\t\tcase *InterfaceIdent:\n\t\t\t\tn++\n\t\t\tcase *RawExtension:\n\t\t\tdefault:\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\t// Not a single InterfaceIdent object or a combo of\n\t\t// RawExtension and InterfaceIdent objects is not\n\t\t// allowed.\n\t\tif n == 1 && len(exts) > 1 {\n\t\t\treturn false\n\t\t}\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// A RawExtension represents a raw extension.\n//\n// A raw extension is excluded from message processing and can be used\n// to construct applications such as protocol conformance testing.\ntype RawExtension struct {\n\tData []byte // data\n}\n\n// Len implements the Len method of Extension interface.\nfunc (p *RawExtension) Len(proto int) int {\n\tif p == nil {\n\t\treturn 0\n\t}\n\treturn len(p.Data)\n}\n\n// Marshal implements the Marshal method of Extension interface.\nfunc (p *RawExtension) Marshal(proto int) ([]byte, error) {\n\treturn p.Data, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/helper_posix.go",
    "content": "// Copyright 2014 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows\n\npackage icmp\n\nimport (\n\t\"net\"\n\t\"strconv\"\n\t\"syscall\"\n)\n\nfunc sockaddr(family int, address string) (syscall.Sockaddr, error) {\n\tswitch family {\n\tcase syscall.AF_INET:\n\t\ta, err := net.ResolveIPAddr(\"ip4\", address)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif len(a.IP) == 0 {\n\t\t\ta.IP = net.IPv4zero\n\t\t}\n\t\tif a.IP = a.IP.To4(); a.IP == nil {\n\t\t\treturn nil, net.InvalidAddrError(\"non-ipv4 address\")\n\t\t}\n\t\tsa := &syscall.SockaddrInet4{}\n\t\tcopy(sa.Addr[:], a.IP)\n\t\treturn sa, nil\n\tcase syscall.AF_INET6:\n\t\ta, err := net.ResolveIPAddr(\"ip6\", address)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif len(a.IP) == 0 {\n\t\t\ta.IP = net.IPv6unspecified\n\t\t}\n\t\tif a.IP.Equal(net.IPv4zero) {\n\t\t\ta.IP = net.IPv6unspecified\n\t\t}\n\t\tif a.IP = a.IP.To16(); a.IP == nil || a.IP.To4() != nil {\n\t\t\treturn nil, net.InvalidAddrError(\"non-ipv6 address\")\n\t\t}\n\t\tsa := &syscall.SockaddrInet6{ZoneId: zoneToUint32(a.Zone)}\n\t\tcopy(sa.Addr[:], a.IP)\n\t\treturn sa, nil\n\tdefault:\n\t\treturn nil, net.InvalidAddrError(\"unexpected family\")\n\t}\n}\n\nfunc zoneToUint32(zone string) uint32 {\n\tif zone == \"\" {\n\t\treturn 0\n\t}\n\tif ifi, err := net.InterfaceByName(zone); err == nil {\n\t\treturn uint32(ifi.Index)\n\t}\n\tn, err := strconv.Atoi(zone)\n\tif err != nil {\n\t\treturn 0\n\t}\n\treturn uint32(n)\n}\n\nfunc last(s string, b byte) int {\n\ti := len(s)\n\tfor i--; i >= 0; i-- {\n\t\tif s[i] == b {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn i\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/interface.go",
    "content": "// Copyright 2015 The Go 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 icmp\n\nimport (\n\t\"encoding/binary\"\n\t\"net\"\n\t\"strings\"\n\n\t\"golang.org/x/net/internal/iana\"\n)\n\nconst (\n\tclassInterfaceInfo = 2\n)\n\nconst (\n\tattrMTU = 1 << iota\n\tattrName\n\tattrIPAddr\n\tattrIfIndex\n)\n\n// An InterfaceInfo represents interface and next-hop identification.\ntype InterfaceInfo struct {\n\tClass     int // extension object class number\n\tType      int // extension object sub-type\n\tInterface *net.Interface\n\tAddr      *net.IPAddr\n}\n\nfunc (ifi *InterfaceInfo) nameLen() int {\n\tif len(ifi.Interface.Name) > 63 {\n\t\treturn 64\n\t}\n\tl := 1 + len(ifi.Interface.Name)\n\treturn (l + 3) &^ 3\n}\n\nfunc (ifi *InterfaceInfo) attrsAndLen(proto int) (attrs, l int) {\n\tl = 4\n\tif ifi.Interface != nil && ifi.Interface.Index > 0 {\n\t\tattrs |= attrIfIndex\n\t\tl += 4\n\t\tif len(ifi.Interface.Name) > 0 {\n\t\t\tattrs |= attrName\n\t\t\tl += ifi.nameLen()\n\t\t}\n\t\tif ifi.Interface.MTU > 0 {\n\t\t\tattrs |= attrMTU\n\t\t\tl += 4\n\t\t}\n\t}\n\tif ifi.Addr != nil {\n\t\tswitch proto {\n\t\tcase iana.ProtocolICMP:\n\t\t\tif ifi.Addr.IP.To4() != nil {\n\t\t\t\tattrs |= attrIPAddr\n\t\t\t\tl += 4 + net.IPv4len\n\t\t\t}\n\t\tcase iana.ProtocolIPv6ICMP:\n\t\t\tif ifi.Addr.IP.To16() != nil && ifi.Addr.IP.To4() == nil {\n\t\t\t\tattrs |= attrIPAddr\n\t\t\t\tl += 4 + net.IPv6len\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\n// Len implements the Len method of Extension interface.\nfunc (ifi *InterfaceInfo) Len(proto int) int {\n\t_, l := ifi.attrsAndLen(proto)\n\treturn l\n}\n\n// Marshal implements the Marshal method of Extension interface.\nfunc (ifi *InterfaceInfo) Marshal(proto int) ([]byte, error) {\n\tattrs, l := ifi.attrsAndLen(proto)\n\tb := make([]byte, l)\n\tif err := ifi.marshal(proto, b, attrs, l); err != nil {\n\t\treturn nil, err\n\t}\n\treturn b, nil\n}\n\nfunc (ifi *InterfaceInfo) marshal(proto int, b []byte, attrs, l int) error {\n\tbinary.BigEndian.PutUint16(b[:2], uint16(l))\n\tb[2], b[3] = classInterfaceInfo, byte(ifi.Type)\n\tfor b = b[4:]; len(b) > 0 && attrs != 0; {\n\t\tswitch {\n\t\tcase attrs&attrIfIndex != 0:\n\t\t\tb = ifi.marshalIfIndex(proto, b)\n\t\t\tattrs &^= attrIfIndex\n\t\tcase attrs&attrIPAddr != 0:\n\t\t\tb = ifi.marshalIPAddr(proto, b)\n\t\t\tattrs &^= attrIPAddr\n\t\tcase attrs&attrName != 0:\n\t\t\tb = ifi.marshalName(proto, b)\n\t\t\tattrs &^= attrName\n\t\tcase attrs&attrMTU != 0:\n\t\t\tb = ifi.marshalMTU(proto, b)\n\t\t\tattrs &^= attrMTU\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (ifi *InterfaceInfo) marshalIfIndex(proto int, b []byte) []byte {\n\tbinary.BigEndian.PutUint32(b[:4], uint32(ifi.Interface.Index))\n\treturn b[4:]\n}\n\nfunc (ifi *InterfaceInfo) parseIfIndex(b []byte) ([]byte, error) {\n\tif len(b) < 4 {\n\t\treturn nil, errMessageTooShort\n\t}\n\tifi.Interface.Index = int(binary.BigEndian.Uint32(b[:4]))\n\treturn b[4:], nil\n}\n\nfunc (ifi *InterfaceInfo) marshalIPAddr(proto int, b []byte) []byte {\n\tswitch proto {\n\tcase iana.ProtocolICMP:\n\t\tbinary.BigEndian.PutUint16(b[:2], uint16(iana.AddrFamilyIPv4))\n\t\tcopy(b[4:4+net.IPv4len], ifi.Addr.IP.To4())\n\t\tb = b[4+net.IPv4len:]\n\tcase iana.ProtocolIPv6ICMP:\n\t\tbinary.BigEndian.PutUint16(b[:2], uint16(iana.AddrFamilyIPv6))\n\t\tcopy(b[4:4+net.IPv6len], ifi.Addr.IP.To16())\n\t\tb = b[4+net.IPv6len:]\n\t}\n\treturn b\n}\n\nfunc (ifi *InterfaceInfo) parseIPAddr(b []byte) ([]byte, error) {\n\tif len(b) < 4 {\n\t\treturn nil, errMessageTooShort\n\t}\n\tafi := int(binary.BigEndian.Uint16(b[:2]))\n\tb = b[4:]\n\tswitch afi {\n\tcase iana.AddrFamilyIPv4:\n\t\tif len(b) < net.IPv4len {\n\t\t\treturn nil, errMessageTooShort\n\t\t}\n\t\tifi.Addr.IP = make(net.IP, net.IPv4len)\n\t\tcopy(ifi.Addr.IP, b[:net.IPv4len])\n\t\tb = b[net.IPv4len:]\n\tcase iana.AddrFamilyIPv6:\n\t\tif len(b) < net.IPv6len {\n\t\t\treturn nil, errMessageTooShort\n\t\t}\n\t\tifi.Addr.IP = make(net.IP, net.IPv6len)\n\t\tcopy(ifi.Addr.IP, b[:net.IPv6len])\n\t\tb = b[net.IPv6len:]\n\t}\n\treturn b, nil\n}\n\nfunc (ifi *InterfaceInfo) marshalName(proto int, b []byte) []byte {\n\tl := byte(ifi.nameLen())\n\tb[0] = l\n\tcopy(b[1:], []byte(ifi.Interface.Name))\n\treturn b[l:]\n}\n\nfunc (ifi *InterfaceInfo) parseName(b []byte) ([]byte, error) {\n\tif 4 > len(b) || len(b) < int(b[0]) {\n\t\treturn nil, errMessageTooShort\n\t}\n\tl := int(b[0])\n\tif l%4 != 0 || 4 > l || l > 64 {\n\t\treturn nil, errInvalidExtension\n\t}\n\tvar name [63]byte\n\tcopy(name[:], b[1:l])\n\tifi.Interface.Name = strings.Trim(string(name[:]), \"\\000\")\n\treturn b[l:], nil\n}\n\nfunc (ifi *InterfaceInfo) marshalMTU(proto int, b []byte) []byte {\n\tbinary.BigEndian.PutUint32(b[:4], uint32(ifi.Interface.MTU))\n\treturn b[4:]\n}\n\nfunc (ifi *InterfaceInfo) parseMTU(b []byte) ([]byte, error) {\n\tif len(b) < 4 {\n\t\treturn nil, errMessageTooShort\n\t}\n\tifi.Interface.MTU = int(binary.BigEndian.Uint32(b[:4]))\n\treturn b[4:], nil\n}\n\nfunc parseInterfaceInfo(b []byte) (Extension, error) {\n\tifi := &InterfaceInfo{\n\t\tClass: int(b[2]),\n\t\tType:  int(b[3]),\n\t}\n\tif ifi.Type&(attrIfIndex|attrName|attrMTU) != 0 {\n\t\tifi.Interface = &net.Interface{}\n\t}\n\tif ifi.Type&attrIPAddr != 0 {\n\t\tifi.Addr = &net.IPAddr{}\n\t}\n\tattrs := ifi.Type & (attrIfIndex | attrIPAddr | attrName | attrMTU)\n\tfor b = b[4:]; len(b) > 0 && attrs != 0; {\n\t\tvar err error\n\t\tswitch {\n\t\tcase attrs&attrIfIndex != 0:\n\t\t\tb, err = ifi.parseIfIndex(b)\n\t\t\tattrs &^= attrIfIndex\n\t\tcase attrs&attrIPAddr != 0:\n\t\t\tb, err = ifi.parseIPAddr(b)\n\t\t\tattrs &^= attrIPAddr\n\t\tcase attrs&attrName != 0:\n\t\t\tb, err = ifi.parseName(b)\n\t\t\tattrs &^= attrName\n\t\tcase attrs&attrMTU != 0:\n\t\t\tb, err = ifi.parseMTU(b)\n\t\t\tattrs &^= attrMTU\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif ifi.Interface != nil && ifi.Interface.Name != \"\" && ifi.Addr != nil && ifi.Addr.IP.To16() != nil && ifi.Addr.IP.To4() == nil {\n\t\tifi.Addr.Zone = ifi.Interface.Name\n\t}\n\treturn ifi, nil\n}\n\nconst (\n\tclassInterfaceIdent    = 3\n\ttypeInterfaceByName    = 1\n\ttypeInterfaceByIndex   = 2\n\ttypeInterfaceByAddress = 3\n)\n\n// An InterfaceIdent represents interface identification.\ntype InterfaceIdent struct {\n\tClass int    // extension object class number\n\tType  int    // extension object sub-type\n\tName  string // interface name\n\tIndex int    // interface index\n\tAFI   int    // address family identifier; see address family numbers in IANA registry\n\tAddr  []byte // address\n}\n\n// Len implements the Len method of Extension interface.\nfunc (ifi *InterfaceIdent) Len(_ int) int {\n\tswitch ifi.Type {\n\tcase typeInterfaceByName:\n\t\tl := len(ifi.Name)\n\t\tif l > 255 {\n\t\t\tl = 255\n\t\t}\n\t\treturn 4 + (l+3)&^3\n\tcase typeInterfaceByIndex:\n\t\treturn 4 + 4\n\tcase typeInterfaceByAddress:\n\t\treturn 4 + 4 + (len(ifi.Addr)+3)&^3\n\tdefault:\n\t\treturn 4\n\t}\n}\n\n// Marshal implements the Marshal method of Extension interface.\nfunc (ifi *InterfaceIdent) Marshal(proto int) ([]byte, error) {\n\tb := make([]byte, ifi.Len(proto))\n\tif err := ifi.marshal(proto, b); err != nil {\n\t\treturn nil, err\n\t}\n\treturn b, nil\n}\n\nfunc (ifi *InterfaceIdent) marshal(proto int, b []byte) error {\n\tl := ifi.Len(proto)\n\tbinary.BigEndian.PutUint16(b[:2], uint16(l))\n\tb[2], b[3] = classInterfaceIdent, byte(ifi.Type)\n\tswitch ifi.Type {\n\tcase typeInterfaceByName:\n\t\tcopy(b[4:], ifi.Name)\n\tcase typeInterfaceByIndex:\n\t\tbinary.BigEndian.PutUint32(b[4:4+4], uint32(ifi.Index))\n\tcase typeInterfaceByAddress:\n\t\tbinary.BigEndian.PutUint16(b[4:4+2], uint16(ifi.AFI))\n\t\tb[4+2] = byte(len(ifi.Addr))\n\t\tcopy(b[4+4:], ifi.Addr)\n\t}\n\treturn nil\n}\n\nfunc parseInterfaceIdent(b []byte) (Extension, error) {\n\tifi := &InterfaceIdent{\n\t\tClass: int(b[2]),\n\t\tType:  int(b[3]),\n\t}\n\tswitch ifi.Type {\n\tcase typeInterfaceByName:\n\t\tifi.Name = strings.Trim(string(b[4:]), \"\\x00\")\n\tcase typeInterfaceByIndex:\n\t\tif len(b[4:]) < 4 {\n\t\t\treturn nil, errInvalidExtension\n\t\t}\n\t\tifi.Index = int(binary.BigEndian.Uint32(b[4 : 4+4]))\n\tcase typeInterfaceByAddress:\n\t\tif len(b[4:]) < 4 {\n\t\t\treturn nil, errInvalidExtension\n\t\t}\n\t\tifi.AFI = int(binary.BigEndian.Uint16(b[4 : 4+2]))\n\t\tl := int(b[4+2])\n\t\tif len(b[4+4:]) < l {\n\t\t\treturn nil, errInvalidExtension\n\t\t}\n\t\tifi.Addr = make([]byte, l)\n\t\tcopy(ifi.Addr, b[4+4:])\n\t}\n\treturn ifi, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/ipv4.go",
    "content": "// Copyright 2014 The Go 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 icmp\n\nimport (\n\t\"encoding/binary\"\n\t\"net\"\n\t\"runtime\"\n\n\t\"golang.org/x/net/internal/socket\"\n\t\"golang.org/x/net/ipv4\"\n)\n\n// freebsdVersion is set in sys_freebsd.go.\n// See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.\nvar freebsdVersion uint32\n\n// ParseIPv4Header returns the IPv4 header of the IPv4 packet that\n// triggered an ICMP error message.\n// This is found in the Data field of the ICMP error message body.\n//\n// The provided b must be in the format used by a raw ICMP socket on\n// the local system.\n// This may differ from the wire format, and the format used by a raw\n// IP socket, depending on the system.\n//\n// To parse an IPv6 header, use ipv6.ParseHeader.\nfunc ParseIPv4Header(b []byte) (*ipv4.Header, error) {\n\tif len(b) < ipv4.HeaderLen {\n\t\treturn nil, errHeaderTooShort\n\t}\n\thdrlen := int(b[0]&0x0f) << 2\n\tif hdrlen > len(b) {\n\t\treturn nil, errBufferTooShort\n\t}\n\th := &ipv4.Header{\n\t\tVersion:  int(b[0] >> 4),\n\t\tLen:      hdrlen,\n\t\tTOS:      int(b[1]),\n\t\tID:       int(binary.BigEndian.Uint16(b[4:6])),\n\t\tFragOff:  int(binary.BigEndian.Uint16(b[6:8])),\n\t\tTTL:      int(b[8]),\n\t\tProtocol: int(b[9]),\n\t\tChecksum: int(binary.BigEndian.Uint16(b[10:12])),\n\t\tSrc:      net.IPv4(b[12], b[13], b[14], b[15]),\n\t\tDst:      net.IPv4(b[16], b[17], b[18], b[19]),\n\t}\n\tswitch runtime.GOOS {\n\tcase \"darwin\", \"ios\":\n\t\th.TotalLen = int(socket.NativeEndian.Uint16(b[2:4]))\n\tcase \"freebsd\":\n\t\tif freebsdVersion >= 1000000 {\n\t\t\th.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))\n\t\t} else {\n\t\t\th.TotalLen = int(socket.NativeEndian.Uint16(b[2:4]))\n\t\t}\n\tdefault:\n\t\th.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))\n\t}\n\th.Flags = ipv4.HeaderFlags(h.FragOff&0xe000) >> 13\n\th.FragOff = h.FragOff & 0x1fff\n\tif hdrlen-ipv4.HeaderLen > 0 {\n\t\th.Options = make([]byte, hdrlen-ipv4.HeaderLen)\n\t\tcopy(h.Options, b[ipv4.HeaderLen:])\n\t}\n\treturn h, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/ipv6.go",
    "content": "// Copyright 2013 The Go 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 icmp\n\nimport (\n\t\"net\"\n\n\t\"golang.org/x/net/internal/iana\"\n)\n\nconst ipv6PseudoHeaderLen = 2*net.IPv6len + 8\n\n// IPv6PseudoHeader returns an IPv6 pseudo header for checksum\n// calculation.\nfunc IPv6PseudoHeader(src, dst net.IP) []byte {\n\tb := make([]byte, ipv6PseudoHeaderLen)\n\tcopy(b, src.To16())\n\tcopy(b[net.IPv6len:], dst.To16())\n\tb[len(b)-1] = byte(iana.ProtocolIPv6ICMP)\n\treturn b\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/listen_posix.go",
    "content": "// Copyright 2014 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows\n\npackage icmp\n\nimport (\n\t\"net\"\n\t\"os\"\n\t\"runtime\"\n\t\"syscall\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/ipv4\"\n\t\"golang.org/x/net/ipv6\"\n)\n\nconst sysIP_STRIPHDR = 0x17 // for now only darwin supports this option\n\n// ListenPacket listens for incoming ICMP packets addressed to\n// address. See net.Dial for the syntax of address.\n//\n// For non-privileged datagram-oriented ICMP endpoints, network must\n// be \"udp4\" or \"udp6\". The endpoint allows to read, write a few\n// limited ICMP messages such as echo request and echo reply.\n// Currently only Darwin and Linux support this.\n//\n// Examples:\n//\n//\tListenPacket(\"udp4\", \"192.168.0.1\")\n//\tListenPacket(\"udp4\", \"0.0.0.0\")\n//\tListenPacket(\"udp6\", \"fe80::1%en0\")\n//\tListenPacket(\"udp6\", \"::\")\n//\n// For privileged raw ICMP endpoints, network must be \"ip4\" or \"ip6\"\n// followed by a colon and an ICMP protocol number or name.\n//\n// Examples:\n//\n//\tListenPacket(\"ip4:icmp\", \"192.168.0.1\")\n//\tListenPacket(\"ip4:1\", \"0.0.0.0\")\n//\tListenPacket(\"ip6:ipv6-icmp\", \"fe80::1%en0\")\n//\tListenPacket(\"ip6:58\", \"::\")\nfunc ListenPacket(network, address string) (*PacketConn, error) {\n\tvar family, proto int\n\tswitch network {\n\tcase \"udp4\":\n\t\tfamily, proto = syscall.AF_INET, iana.ProtocolICMP\n\tcase \"udp6\":\n\t\tfamily, proto = syscall.AF_INET6, iana.ProtocolIPv6ICMP\n\tdefault:\n\t\ti := last(network, ':')\n\t\tif i < 0 {\n\t\t\ti = len(network)\n\t\t}\n\t\tswitch network[:i] {\n\t\tcase \"ip4\":\n\t\t\tproto = iana.ProtocolICMP\n\t\tcase \"ip6\":\n\t\t\tproto = iana.ProtocolIPv6ICMP\n\t\t}\n\t}\n\tvar cerr error\n\tvar c net.PacketConn\n\tswitch family {\n\tcase syscall.AF_INET, syscall.AF_INET6:\n\t\ts, err := syscall.Socket(family, syscall.SOCK_DGRAM, proto)\n\t\tif err != nil {\n\t\t\treturn nil, os.NewSyscallError(\"socket\", err)\n\t\t}\n\t\tif (runtime.GOOS == \"darwin\" || runtime.GOOS == \"ios\") && family == syscall.AF_INET {\n\t\t\tif err := syscall.SetsockoptInt(s, iana.ProtocolIP, sysIP_STRIPHDR, 1); err != nil {\n\t\t\t\tsyscall.Close(s)\n\t\t\t\treturn nil, os.NewSyscallError(\"setsockopt\", err)\n\t\t\t}\n\t\t}\n\t\tsa, err := sockaddr(family, address)\n\t\tif err != nil {\n\t\t\tsyscall.Close(s)\n\t\t\treturn nil, err\n\t\t}\n\t\tif err := syscall.Bind(s, sa); err != nil {\n\t\t\tsyscall.Close(s)\n\t\t\treturn nil, os.NewSyscallError(\"bind\", err)\n\t\t}\n\t\tf := os.NewFile(uintptr(s), \"datagram-oriented icmp\")\n\t\tc, cerr = net.FilePacketConn(f)\n\t\tf.Close()\n\tdefault:\n\t\tc, cerr = net.ListenPacket(network, address)\n\t}\n\tif cerr != nil {\n\t\treturn nil, cerr\n\t}\n\tswitch proto {\n\tcase iana.ProtocolICMP:\n\t\treturn &PacketConn{c: c, p4: ipv4.NewPacketConn(c)}, nil\n\tcase iana.ProtocolIPv6ICMP:\n\t\treturn &PacketConn{c: c, p6: ipv6.NewPacketConn(c)}, nil\n\tdefault:\n\t\treturn &PacketConn{c: c}, nil\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/listen_stub.go",
    "content": "// Copyright 2014 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows\n\npackage icmp\n\n// ListenPacket listens for incoming ICMP packets addressed to\n// address. See net.Dial for the syntax of address.\n//\n// For non-privileged datagram-oriented ICMP endpoints, network must\n// be \"udp4\" or \"udp6\". The endpoint allows to read, write a few\n// limited ICMP messages such as echo request and echo reply.\n// Currently only Darwin and Linux support this.\n//\n// Examples:\n//\n//\tListenPacket(\"udp4\", \"192.168.0.1\")\n//\tListenPacket(\"udp4\", \"0.0.0.0\")\n//\tListenPacket(\"udp6\", \"fe80::1%en0\")\n//\tListenPacket(\"udp6\", \"::\")\n//\n// For privileged raw ICMP endpoints, network must be \"ip4\" or \"ip6\"\n// followed by a colon and an ICMP protocol number or name.\n//\n// Examples:\n//\n//\tListenPacket(\"ip4:icmp\", \"192.168.0.1\")\n//\tListenPacket(\"ip4:1\", \"0.0.0.0\")\n//\tListenPacket(\"ip6:ipv6-icmp\", \"fe80::1%en0\")\n//\tListenPacket(\"ip6:58\", \"::\")\nfunc ListenPacket(network, address string) (*PacketConn, error) {\n\treturn nil, errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/message.go",
    "content": "// Copyright 2012 The Go 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\n// Package icmp provides basic functions for the manipulation of\n// messages used in the Internet Control Message Protocols,\n// ICMPv4 and ICMPv6.\n//\n// ICMPv4 and ICMPv6 are defined in RFC 792 and RFC 4443.\n// Multi-part message support for ICMP is defined in RFC 4884.\n// ICMP extensions for MPLS are defined in RFC 4950.\n// ICMP extensions for interface and next-hop identification are\n// defined in RFC 5837.\n// PROBE: A utility for probing interfaces is defined in RFC 8335.\npackage icmp // import \"golang.org/x/net/icmp\"\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"net\"\n\t\"runtime\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/ipv4\"\n\t\"golang.org/x/net/ipv6\"\n)\n\n// BUG(mikio): This package is not implemented on JS, NaCl and Plan 9.\n\nvar (\n\terrInvalidConn      = errors.New(\"invalid connection\")\n\terrInvalidProtocol  = errors.New(\"invalid protocol\")\n\terrMessageTooShort  = errors.New(\"message too short\")\n\terrHeaderTooShort   = errors.New(\"header too short\")\n\terrBufferTooShort   = errors.New(\"buffer too short\")\n\terrInvalidBody      = errors.New(\"invalid body\")\n\terrNoExtension      = errors.New(\"no extension\")\n\terrInvalidExtension = errors.New(\"invalid extension\")\n\terrNotImplemented   = errors.New(\"not implemented on \" + runtime.GOOS + \"/\" + runtime.GOARCH)\n)\n\nfunc checksum(b []byte) uint16 {\n\tcsumcv := len(b) - 1 // checksum coverage\n\ts := uint32(0)\n\tfor i := 0; i < csumcv; i += 2 {\n\t\ts += uint32(b[i+1])<<8 | uint32(b[i])\n\t}\n\tif csumcv&1 == 0 {\n\t\ts += uint32(b[csumcv])\n\t}\n\ts = s>>16 + s&0xffff\n\ts = s + s>>16\n\treturn ^uint16(s)\n}\n\n// A Type represents an ICMP message type.\ntype Type interface {\n\tProtocol() int\n}\n\n// A Message represents an ICMP message.\ntype Message struct {\n\tType     Type        // type, either ipv4.ICMPType or ipv6.ICMPType\n\tCode     int         // code\n\tChecksum int         // checksum\n\tBody     MessageBody // body\n}\n\n// Marshal returns the binary encoding of the ICMP message m.\n//\n// For an ICMPv4 message, the returned message always contains the\n// calculated checksum field.\n//\n// For an ICMPv6 message, the returned message contains the calculated\n// checksum field when psh is not nil, otherwise the kernel will\n// compute the checksum field during the message transmission.\n// When psh is not nil, it must be the pseudo header for IPv6.\nfunc (m *Message) Marshal(psh []byte) ([]byte, error) {\n\tvar mtype byte\n\tswitch typ := m.Type.(type) {\n\tcase ipv4.ICMPType:\n\t\tmtype = byte(typ)\n\tcase ipv6.ICMPType:\n\t\tmtype = byte(typ)\n\tdefault:\n\t\treturn nil, errInvalidProtocol\n\t}\n\tb := []byte{mtype, byte(m.Code), 0, 0}\n\tproto := m.Type.Protocol()\n\tif proto == iana.ProtocolIPv6ICMP && psh != nil {\n\t\tb = append(psh, b...)\n\t}\n\tif m.Body != nil && m.Body.Len(proto) != 0 {\n\t\tmb, err := m.Body.Marshal(proto)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tb = append(b, mb...)\n\t}\n\tif proto == iana.ProtocolIPv6ICMP {\n\t\tif psh == nil { // cannot calculate checksum here\n\t\t\treturn b, nil\n\t\t}\n\t\toff, l := 2*net.IPv6len, len(b)-len(psh)\n\t\tbinary.BigEndian.PutUint32(b[off:off+4], uint32(l))\n\t}\n\ts := checksum(b)\n\t// Place checksum back in header; using ^= avoids the\n\t// assumption the checksum bytes are zero.\n\tb[len(psh)+2] ^= byte(s)\n\tb[len(psh)+3] ^= byte(s >> 8)\n\treturn b[len(psh):], nil\n}\n\nvar parseFns = map[Type]func(int, Type, []byte) (MessageBody, error){\n\tipv4.ICMPTypeDestinationUnreachable: parseDstUnreach,\n\tipv4.ICMPTypeTimeExceeded:           parseTimeExceeded,\n\tipv4.ICMPTypeParameterProblem:       parseParamProb,\n\n\tipv4.ICMPTypeEcho:                parseEcho,\n\tipv4.ICMPTypeEchoReply:           parseEcho,\n\tipv4.ICMPTypeExtendedEchoRequest: parseExtendedEchoRequest,\n\tipv4.ICMPTypeExtendedEchoReply:   parseExtendedEchoReply,\n\n\tipv6.ICMPTypeDestinationUnreachable: parseDstUnreach,\n\tipv6.ICMPTypePacketTooBig:           parsePacketTooBig,\n\tipv6.ICMPTypeTimeExceeded:           parseTimeExceeded,\n\tipv6.ICMPTypeParameterProblem:       parseParamProb,\n\n\tipv6.ICMPTypeEchoRequest:         parseEcho,\n\tipv6.ICMPTypeEchoReply:           parseEcho,\n\tipv6.ICMPTypeExtendedEchoRequest: parseExtendedEchoRequest,\n\tipv6.ICMPTypeExtendedEchoReply:   parseExtendedEchoReply,\n}\n\n// ParseMessage parses b as an ICMP message.\n// The provided proto must be either the ICMPv4 or ICMPv6 protocol\n// number.\nfunc ParseMessage(proto int, b []byte) (*Message, error) {\n\tif len(b) < 4 {\n\t\treturn nil, errMessageTooShort\n\t}\n\tvar err error\n\tm := &Message{Code: int(b[1]), Checksum: int(binary.BigEndian.Uint16(b[2:4]))}\n\tswitch proto {\n\tcase iana.ProtocolICMP:\n\t\tm.Type = ipv4.ICMPType(b[0])\n\tcase iana.ProtocolIPv6ICMP:\n\t\tm.Type = ipv6.ICMPType(b[0])\n\tdefault:\n\t\treturn nil, errInvalidProtocol\n\t}\n\tif fn, ok := parseFns[m.Type]; !ok {\n\t\tm.Body, err = parseRawBody(proto, b[4:])\n\t} else {\n\t\tm.Body, err = fn(proto, m.Type, b[4:])\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn m, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/messagebody.go",
    "content": "// Copyright 2012 The Go 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 icmp\n\n// A MessageBody represents an ICMP message body.\ntype MessageBody interface {\n\t// Len returns the length of ICMP message body.\n\t// The provided proto must be either the ICMPv4 or ICMPv6\n\t// protocol number.\n\tLen(proto int) int\n\n\t// Marshal returns the binary encoding of ICMP message body.\n\t// The provided proto must be either the ICMPv4 or ICMPv6\n\t// protocol number.\n\tMarshal(proto int) ([]byte, error)\n}\n\n// A RawBody represents a raw message body.\n//\n// A raw message body is excluded from message processing and can be\n// used to construct applications such as protocol conformance\n// testing.\ntype RawBody struct {\n\tData []byte // data\n}\n\n// Len implements the Len method of MessageBody interface.\nfunc (p *RawBody) Len(proto int) int {\n\tif p == nil {\n\t\treturn 0\n\t}\n\treturn len(p.Data)\n}\n\n// Marshal implements the Marshal method of MessageBody interface.\nfunc (p *RawBody) Marshal(proto int) ([]byte, error) {\n\treturn p.Data, nil\n}\n\n// parseRawBody parses b as an ICMP message body.\nfunc parseRawBody(proto int, b []byte) (MessageBody, error) {\n\tp := &RawBody{Data: make([]byte, len(b))}\n\tcopy(p.Data, b)\n\treturn p, nil\n}\n\n// A DefaultMessageBody represents the default message body.\n//\n// Deprecated: Use RawBody instead.\ntype DefaultMessageBody = RawBody\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/mpls.go",
    "content": "// Copyright 2015 The Go 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 icmp\n\nimport \"encoding/binary\"\n\n// MPLSLabel represents an MPLS label stack entry.\ntype MPLSLabel struct {\n\tLabel int  // label value\n\tTC    int  // traffic class; formerly experimental use\n\tS     bool // bottom of stack\n\tTTL   int  // time to live\n}\n\nconst (\n\tclassMPLSLabelStack        = 1\n\ttypeIncomingMPLSLabelStack = 1\n)\n\n// MPLSLabelStack represents an MPLS label stack.\ntype MPLSLabelStack struct {\n\tClass  int // extension object class number\n\tType   int // extension object sub-type\n\tLabels []MPLSLabel\n}\n\n// Len implements the Len method of Extension interface.\nfunc (ls *MPLSLabelStack) Len(proto int) int {\n\treturn 4 + (4 * len(ls.Labels))\n}\n\n// Marshal implements the Marshal method of Extension interface.\nfunc (ls *MPLSLabelStack) Marshal(proto int) ([]byte, error) {\n\tb := make([]byte, ls.Len(proto))\n\tif err := ls.marshal(proto, b); err != nil {\n\t\treturn nil, err\n\t}\n\treturn b, nil\n}\n\nfunc (ls *MPLSLabelStack) marshal(proto int, b []byte) error {\n\tl := ls.Len(proto)\n\tbinary.BigEndian.PutUint16(b[:2], uint16(l))\n\tb[2], b[3] = classMPLSLabelStack, typeIncomingMPLSLabelStack\n\toff := 4\n\tfor _, ll := range ls.Labels {\n\t\tb[off], b[off+1], b[off+2] = byte(ll.Label>>12), byte(ll.Label>>4&0xff), byte(ll.Label<<4&0xf0)\n\t\tb[off+2] |= byte(ll.TC << 1 & 0x0e)\n\t\tif ll.S {\n\t\t\tb[off+2] |= 0x1\n\t\t}\n\t\tb[off+3] = byte(ll.TTL)\n\t\toff += 4\n\t}\n\treturn nil\n}\n\nfunc parseMPLSLabelStack(b []byte) (Extension, error) {\n\tls := &MPLSLabelStack{\n\t\tClass: int(b[2]),\n\t\tType:  int(b[3]),\n\t}\n\tfor b = b[4:]; len(b) >= 4; b = b[4:] {\n\t\tll := MPLSLabel{\n\t\t\tLabel: int(b[0])<<12 | int(b[1])<<4 | int(b[2])>>4,\n\t\t\tTC:    int(b[2]&0x0e) >> 1,\n\t\t\tTTL:   int(b[3]),\n\t\t}\n\t\tif b[2]&0x1 != 0 {\n\t\t\tll.S = true\n\t\t}\n\t\tls.Labels = append(ls.Labels, ll)\n\t}\n\treturn ls, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/multipart.go",
    "content": "// Copyright 2015 The Go 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 icmp\n\nimport \"golang.org/x/net/internal/iana\"\n\n// multipartMessageBodyDataLen takes b as an original datagram and\n// exts as extensions, and returns a required length for message body\n// and a required length for a padded original datagram in wire\n// format.\nfunc multipartMessageBodyDataLen(proto int, withOrigDgram bool, b []byte, exts []Extension) (bodyLen, dataLen int) {\n\tbodyLen = 4 // length of leading octets\n\tvar extLen int\n\tvar rawExt bool // raw extension may contain an empty object\n\tfor _, ext := range exts {\n\t\textLen += ext.Len(proto)\n\t\tif _, ok := ext.(*RawExtension); ok {\n\t\t\trawExt = true\n\t\t}\n\t}\n\tif extLen > 0 && withOrigDgram {\n\t\tdataLen = multipartMessageOrigDatagramLen(proto, b)\n\t} else {\n\t\tdataLen = len(b)\n\t}\n\tif extLen > 0 || rawExt {\n\t\tbodyLen += 4 // length of extension header\n\t}\n\tbodyLen += dataLen + extLen\n\treturn bodyLen, dataLen\n}\n\n// multipartMessageOrigDatagramLen takes b as an original datagram,\n// and returns a required length for a padded original datagram in wire\n// format.\nfunc multipartMessageOrigDatagramLen(proto int, b []byte) int {\n\troundup := func(b []byte, align int) int {\n\t\t// According to RFC 4884, the padded original datagram\n\t\t// field must contain at least 128 octets.\n\t\tif len(b) < 128 {\n\t\t\treturn 128\n\t\t}\n\t\tr := len(b)\n\t\treturn (r + align - 1) &^ (align - 1)\n\t}\n\tswitch proto {\n\tcase iana.ProtocolICMP:\n\t\treturn roundup(b, 4)\n\tcase iana.ProtocolIPv6ICMP:\n\t\treturn roundup(b, 8)\n\tdefault:\n\t\treturn len(b)\n\t}\n}\n\n// marshalMultipartMessageBody takes data as an original datagram and\n// exts as extesnsions, and returns a binary encoding of message body.\n// It can be used for non-multipart message bodies when exts is nil.\nfunc marshalMultipartMessageBody(proto int, withOrigDgram bool, data []byte, exts []Extension) ([]byte, error) {\n\tbodyLen, dataLen := multipartMessageBodyDataLen(proto, withOrigDgram, data, exts)\n\tb := make([]byte, bodyLen)\n\tcopy(b[4:], data)\n\tif len(exts) > 0 {\n\t\tb[4+dataLen] = byte(extensionVersion << 4)\n\t\toff := 4 + dataLen + 4 // leading octets, data, extension header\n\t\tfor _, ext := range exts {\n\t\t\tswitch ext := ext.(type) {\n\t\t\tcase *MPLSLabelStack:\n\t\t\t\tif err := ext.marshal(proto, b[off:]); err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\toff += ext.Len(proto)\n\t\t\tcase *InterfaceInfo:\n\t\t\t\tattrs, l := ext.attrsAndLen(proto)\n\t\t\t\tif err := ext.marshal(proto, b[off:], attrs, l); err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\toff += ext.Len(proto)\n\t\t\tcase *InterfaceIdent:\n\t\t\t\tif err := ext.marshal(proto, b[off:]); err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\toff += ext.Len(proto)\n\t\t\tcase *RawExtension:\n\t\t\t\tcopy(b[off:], ext.Data)\n\t\t\t\toff += ext.Len(proto)\n\t\t\t}\n\t\t}\n\t\ts := checksum(b[4+dataLen:])\n\t\tb[4+dataLen+2] ^= byte(s)\n\t\tb[4+dataLen+3] ^= byte(s >> 8)\n\t\tif withOrigDgram {\n\t\t\tswitch proto {\n\t\t\tcase iana.ProtocolICMP:\n\t\t\t\tb[1] = byte(dataLen / 4)\n\t\t\tcase iana.ProtocolIPv6ICMP:\n\t\t\t\tb[0] = byte(dataLen / 8)\n\t\t\t}\n\t\t}\n\t}\n\treturn b, nil\n}\n\n// parseMultipartMessageBody parses b as either a non-multipart\n// message body or a multipart message body.\nfunc parseMultipartMessageBody(proto int, typ Type, b []byte) ([]byte, []Extension, error) {\n\tvar l int\n\tswitch proto {\n\tcase iana.ProtocolICMP:\n\t\tl = 4 * int(b[1])\n\tcase iana.ProtocolIPv6ICMP:\n\t\tl = 8 * int(b[0])\n\t}\n\tif len(b) == 4 {\n\t\treturn nil, nil, nil\n\t}\n\texts, l, err := parseExtensions(typ, b[4:], l)\n\tif err != nil {\n\t\tl = len(b) - 4\n\t}\n\tvar data []byte\n\tif l > 0 {\n\t\tdata = make([]byte, l)\n\t\tcopy(data, b[4:])\n\t}\n\treturn data, exts, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/packettoobig.go",
    "content": "// Copyright 2014 The Go 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 icmp\n\nimport \"encoding/binary\"\n\n// A PacketTooBig represents an ICMP packet too big message body.\ntype PacketTooBig struct {\n\tMTU  int    // maximum transmission unit of the nexthop link\n\tData []byte // data, known as original datagram field\n}\n\n// Len implements the Len method of MessageBody interface.\nfunc (p *PacketTooBig) Len(proto int) int {\n\tif p == nil {\n\t\treturn 0\n\t}\n\treturn 4 + len(p.Data)\n}\n\n// Marshal implements the Marshal method of MessageBody interface.\nfunc (p *PacketTooBig) Marshal(proto int) ([]byte, error) {\n\tb := make([]byte, 4+len(p.Data))\n\tbinary.BigEndian.PutUint32(b[:4], uint32(p.MTU))\n\tcopy(b[4:], p.Data)\n\treturn b, nil\n}\n\n// parsePacketTooBig parses b as an ICMP packet too big message body.\nfunc parsePacketTooBig(proto int, _ Type, b []byte) (MessageBody, error) {\n\tbodyLen := len(b)\n\tif bodyLen < 4 {\n\t\treturn nil, errMessageTooShort\n\t}\n\tp := &PacketTooBig{MTU: int(binary.BigEndian.Uint32(b[:4]))}\n\tif bodyLen > 4 {\n\t\tp.Data = make([]byte, bodyLen-4)\n\t\tcopy(p.Data, b[4:])\n\t}\n\treturn p, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/paramprob.go",
    "content": "// Copyright 2014 The Go 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 icmp\n\nimport (\n\t\"encoding/binary\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/ipv4\"\n)\n\n// A ParamProb represents an ICMP parameter problem message body.\ntype ParamProb struct {\n\tPointer    uintptr     // offset within the data where the error was detected\n\tData       []byte      // data, known as original datagram field\n\tExtensions []Extension // extensions\n}\n\n// Len implements the Len method of MessageBody interface.\nfunc (p *ParamProb) Len(proto int) int {\n\tif p == nil {\n\t\treturn 0\n\t}\n\tl, _ := multipartMessageBodyDataLen(proto, true, p.Data, p.Extensions)\n\treturn l\n}\n\n// Marshal implements the Marshal method of MessageBody interface.\nfunc (p *ParamProb) Marshal(proto int) ([]byte, error) {\n\tswitch proto {\n\tcase iana.ProtocolICMP:\n\t\tif !validExtensions(ipv4.ICMPTypeParameterProblem, p.Extensions) {\n\t\t\treturn nil, errInvalidExtension\n\t\t}\n\t\tb, err := marshalMultipartMessageBody(proto, true, p.Data, p.Extensions)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tb[0] = byte(p.Pointer)\n\t\treturn b, nil\n\tcase iana.ProtocolIPv6ICMP:\n\t\tb := make([]byte, p.Len(proto))\n\t\tbinary.BigEndian.PutUint32(b[:4], uint32(p.Pointer))\n\t\tcopy(b[4:], p.Data)\n\t\treturn b, nil\n\tdefault:\n\t\treturn nil, errInvalidProtocol\n\t}\n}\n\n// parseParamProb parses b as an ICMP parameter problem message body.\nfunc parseParamProb(proto int, typ Type, b []byte) (MessageBody, error) {\n\tif len(b) < 4 {\n\t\treturn nil, errMessageTooShort\n\t}\n\tp := &ParamProb{}\n\tif proto == iana.ProtocolIPv6ICMP {\n\t\tp.Pointer = uintptr(binary.BigEndian.Uint32(b[:4]))\n\t\tp.Data = make([]byte, len(b)-4)\n\t\tcopy(p.Data, b[4:])\n\t\treturn p, nil\n\t}\n\tp.Pointer = uintptr(b[0])\n\tvar err error\n\tp.Data, p.Extensions, err = parseMultipartMessageBody(proto, typ, b)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn p, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/sys_freebsd.go",
    "content": "// Copyright 2014 The Go 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 icmp\n\nimport \"syscall\"\n\nfunc init() {\n\tfreebsdVersion, _ = syscall.SysctlUint32(\"kern.osreldate\")\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/icmp/timeexceeded.go",
    "content": "// Copyright 2014 The Go 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 icmp\n\nimport (\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/ipv4\"\n\t\"golang.org/x/net/ipv6\"\n)\n\n// A TimeExceeded represents an ICMP time exceeded message body.\ntype TimeExceeded struct {\n\tData       []byte      // data, known as original datagram field\n\tExtensions []Extension // extensions\n}\n\n// Len implements the Len method of MessageBody interface.\nfunc (p *TimeExceeded) Len(proto int) int {\n\tif p == nil {\n\t\treturn 0\n\t}\n\tl, _ := multipartMessageBodyDataLen(proto, true, p.Data, p.Extensions)\n\treturn l\n}\n\n// Marshal implements the Marshal method of MessageBody interface.\nfunc (p *TimeExceeded) Marshal(proto int) ([]byte, error) {\n\tvar typ Type\n\tswitch proto {\n\tcase iana.ProtocolICMP:\n\t\ttyp = ipv4.ICMPTypeTimeExceeded\n\tcase iana.ProtocolIPv6ICMP:\n\t\ttyp = ipv6.ICMPTypeTimeExceeded\n\tdefault:\n\t\treturn nil, errInvalidProtocol\n\t}\n\tif !validExtensions(typ, p.Extensions) {\n\t\treturn nil, errInvalidExtension\n\t}\n\treturn marshalMultipartMessageBody(proto, true, p.Data, p.Extensions)\n}\n\n// parseTimeExceeded parses b as an ICMP time exceeded message body.\nfunc parseTimeExceeded(proto int, typ Type, b []byte) (MessageBody, error) {\n\tif len(b) < 4 {\n\t\treturn nil, errMessageTooShort\n\t}\n\tp := &TimeExceeded{}\n\tvar err error\n\tp.Data, p.Extensions, err = parseMultipartMessageBody(proto, typ, b)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn p, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/idna/go118.go",
    "content": "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n// Copyright 2021 The Go 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\n//go:build go1.18\n\npackage idna\n\n// Transitional processing is disabled by default in Go 1.18.\n// https://golang.org/issue/47510\nconst transitionalLookup = false\n"
  },
  {
    "path": "vendor/golang.org/x/net/idna/idna10.0.0.go",
    "content": "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n// Copyright 2016 The Go 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\n//go:build go1.10\n\n// Package idna implements IDNA2008 using the compatibility processing\n// defined by UTS (Unicode Technical Standard) #46, which defines a standard to\n// deal with the transition from IDNA2003.\n//\n// IDNA2008 (Internationalized Domain Names for Applications), is defined in RFC\n// 5890, RFC 5891, RFC 5892, RFC 5893 and RFC 5894.\n// UTS #46 is defined in https://www.unicode.org/reports/tr46.\n// See https://unicode.org/cldr/utility/idna.jsp for a visualization of the\n// differences between these two standards.\npackage idna // import \"golang.org/x/net/idna\"\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"golang.org/x/text/secure/bidirule\"\n\t\"golang.org/x/text/unicode/bidi\"\n\t\"golang.org/x/text/unicode/norm\"\n)\n\n// NOTE: Unlike common practice in Go APIs, the functions will return a\n// sanitized domain name in case of errors. Browsers sometimes use a partially\n// evaluated string as lookup.\n// TODO: the current error handling is, in my opinion, the least opinionated.\n// Other strategies are also viable, though:\n// Option 1) Return an empty string in case of error, but allow the user to\n//    specify explicitly which errors to ignore.\n// Option 2) Return the partially evaluated string if it is itself a valid\n//    string, otherwise return the empty string in case of error.\n// Option 3) Option 1 and 2.\n// Option 4) Always return an empty string for now and implement Option 1 as\n//    needed, and document that the return string may not be empty in case of\n//    error in the future.\n// I think Option 1 is best, but it is quite opinionated.\n\n// ToASCII is a wrapper for Punycode.ToASCII.\nfunc ToASCII(s string) (string, error) {\n\treturn Punycode.process(s, true)\n}\n\n// ToUnicode is a wrapper for Punycode.ToUnicode.\nfunc ToUnicode(s string) (string, error) {\n\treturn Punycode.process(s, false)\n}\n\n// An Option configures a Profile at creation time.\ntype Option func(*options)\n\n// Transitional sets a Profile to use the Transitional mapping as defined in UTS\n// #46. This will cause, for example, \"ß\" to be mapped to \"ss\". Using the\n// transitional mapping provides a compromise between IDNA2003 and IDNA2008\n// compatibility. It is used by some browsers when resolving domain names. This\n// option is only meaningful if combined with MapForLookup.\nfunc Transitional(transitional bool) Option {\n\treturn func(o *options) { o.transitional = transitional }\n}\n\n// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts\n// are longer than allowed by the RFC.\n//\n// This option corresponds to the VerifyDnsLength flag in UTS #46.\nfunc VerifyDNSLength(verify bool) Option {\n\treturn func(o *options) { o.verifyDNSLength = verify }\n}\n\n// RemoveLeadingDots removes leading label separators. Leading runes that map to\n// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well.\nfunc RemoveLeadingDots(remove bool) Option {\n\treturn func(o *options) { o.removeLeadingDots = remove }\n}\n\n// ValidateLabels sets whether to check the mandatory label validation criteria\n// as defined in Section 5.4 of RFC 5891. This includes testing for correct use\n// of hyphens ('-'), normalization, validity of runes, and the context rules.\n// In particular, ValidateLabels also sets the CheckHyphens and CheckJoiners flags\n// in UTS #46.\nfunc ValidateLabels(enable bool) Option {\n\treturn func(o *options) {\n\t\t// Don't override existing mappings, but set one that at least checks\n\t\t// normalization if it is not set.\n\t\tif o.mapping == nil && enable {\n\t\t\to.mapping = normalize\n\t\t}\n\t\to.trie = trie\n\t\to.checkJoiners = enable\n\t\to.checkHyphens = enable\n\t\tif enable {\n\t\t\to.fromPuny = validateFromPunycode\n\t\t} else {\n\t\t\to.fromPuny = nil\n\t\t}\n\t}\n}\n\n// CheckHyphens sets whether to check for correct use of hyphens ('-') in\n// labels. Most web browsers do not have this option set, since labels such as\n// \"r3---sn-apo3qvuoxuxbt-j5pe\" are in common use.\n//\n// This option corresponds to the CheckHyphens flag in UTS #46.\nfunc CheckHyphens(enable bool) Option {\n\treturn func(o *options) { o.checkHyphens = enable }\n}\n\n// CheckJoiners sets whether to check the ContextJ rules as defined in Appendix\n// A of RFC 5892, concerning the use of joiner runes.\n//\n// This option corresponds to the CheckJoiners flag in UTS #46.\nfunc CheckJoiners(enable bool) Option {\n\treturn func(o *options) {\n\t\to.trie = trie\n\t\to.checkJoiners = enable\n\t}\n}\n\n// StrictDomainName limits the set of permissible ASCII characters to those\n// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the\n// hyphen). This is set by default for MapForLookup and ValidateForRegistration,\n// but is only useful if ValidateLabels is set.\n//\n// This option is useful, for instance, for browsers that allow characters\n// outside this range, for example a '_' (U+005F LOW LINE). See\n// http://www.rfc-editor.org/std/std3.txt for more details.\n//\n// This option corresponds to the UseSTD3ASCIIRules flag in UTS #46.\nfunc StrictDomainName(use bool) Option {\n\treturn func(o *options) { o.useSTD3Rules = use }\n}\n\n// NOTE: the following options pull in tables. The tables should not be linked\n// in as long as the options are not used.\n\n// BidiRule enables the Bidi rule as defined in RFC 5893. Any application\n// that relies on proper validation of labels should include this rule.\n//\n// This option corresponds to the CheckBidi flag in UTS #46.\nfunc BidiRule() Option {\n\treturn func(o *options) { o.bidirule = bidirule.ValidString }\n}\n\n// ValidateForRegistration sets validation options to verify that a given IDN is\n// properly formatted for registration as defined by Section 4 of RFC 5891.\nfunc ValidateForRegistration() Option {\n\treturn func(o *options) {\n\t\to.mapping = validateRegistration\n\t\tStrictDomainName(true)(o)\n\t\tValidateLabels(true)(o)\n\t\tVerifyDNSLength(true)(o)\n\t\tBidiRule()(o)\n\t}\n}\n\n// MapForLookup sets validation and mapping options such that a given IDN is\n// transformed for domain name lookup according to the requirements set out in\n// Section 5 of RFC 5891. The mappings follow the recommendations of RFC 5894,\n// RFC 5895 and UTS 46. It does not add the Bidi Rule. Use the BidiRule option\n// to add this check.\n//\n// The mappings include normalization and mapping case, width and other\n// compatibility mappings.\nfunc MapForLookup() Option {\n\treturn func(o *options) {\n\t\to.mapping = validateAndMap\n\t\tStrictDomainName(true)(o)\n\t\tValidateLabels(true)(o)\n\t}\n}\n\ntype options struct {\n\ttransitional      bool\n\tuseSTD3Rules      bool\n\tcheckHyphens      bool\n\tcheckJoiners      bool\n\tverifyDNSLength   bool\n\tremoveLeadingDots bool\n\n\ttrie *idnaTrie\n\n\t// fromPuny calls validation rules when converting A-labels to U-labels.\n\tfromPuny func(p *Profile, s string) error\n\n\t// mapping implements a validation and mapping step as defined in RFC 5895\n\t// or UTS 46, tailored to, for example, domain registration or lookup.\n\tmapping func(p *Profile, s string) (mapped string, isBidi bool, err error)\n\n\t// bidirule, if specified, checks whether s conforms to the Bidi Rule\n\t// defined in RFC 5893.\n\tbidirule func(s string) bool\n}\n\n// A Profile defines the configuration of an IDNA mapper.\ntype Profile struct {\n\toptions\n}\n\nfunc apply(o *options, opts []Option) {\n\tfor _, f := range opts {\n\t\tf(o)\n\t}\n}\n\n// New creates a new Profile.\n//\n// With no options, the returned Profile is the most permissive and equals the\n// Punycode Profile. Options can be passed to further restrict the Profile. The\n// MapForLookup and ValidateForRegistration options set a collection of options,\n// for lookup and registration purposes respectively, which can be tailored by\n// adding more fine-grained options, where later options override earlier\n// options.\nfunc New(o ...Option) *Profile {\n\tp := &Profile{}\n\tapply(&p.options, o)\n\treturn p\n}\n\n// ToASCII converts a domain or domain label to its ASCII form. For example,\n// ToASCII(\"bücher.example.com\") is \"xn--bcher-kva.example.com\", and\n// ToASCII(\"golang\") is \"golang\". If an error is encountered it will return\n// an error and a (partially) processed result.\nfunc (p *Profile) ToASCII(s string) (string, error) {\n\treturn p.process(s, true)\n}\n\n// ToUnicode converts a domain or domain label to its Unicode form. For example,\n// ToUnicode(\"xn--bcher-kva.example.com\") is \"bücher.example.com\", and\n// ToUnicode(\"golang\") is \"golang\". If an error is encountered it will return\n// an error and a (partially) processed result.\nfunc (p *Profile) ToUnicode(s string) (string, error) {\n\tpp := *p\n\tpp.transitional = false\n\treturn pp.process(s, false)\n}\n\n// String reports a string with a description of the profile for debugging\n// purposes. The string format may change with different versions.\nfunc (p *Profile) String() string {\n\ts := \"\"\n\tif p.transitional {\n\t\ts = \"Transitional\"\n\t} else {\n\t\ts = \"NonTransitional\"\n\t}\n\tif p.useSTD3Rules {\n\t\ts += \":UseSTD3Rules\"\n\t}\n\tif p.checkHyphens {\n\t\ts += \":CheckHyphens\"\n\t}\n\tif p.checkJoiners {\n\t\ts += \":CheckJoiners\"\n\t}\n\tif p.verifyDNSLength {\n\t\ts += \":VerifyDNSLength\"\n\t}\n\treturn s\n}\n\nvar (\n\t// Punycode is a Profile that does raw punycode processing with a minimum\n\t// of validation.\n\tPunycode *Profile = punycode\n\n\t// Lookup is the recommended profile for looking up domain names, according\n\t// to Section 5 of RFC 5891. The exact configuration of this profile may\n\t// change over time.\n\tLookup *Profile = lookup\n\n\t// Display is the recommended profile for displaying domain names.\n\t// The configuration of this profile may change over time.\n\tDisplay *Profile = display\n\n\t// Registration is the recommended profile for checking whether a given\n\t// IDN is valid for registration, according to Section 4 of RFC 5891.\n\tRegistration *Profile = registration\n\n\tpunycode = &Profile{}\n\tlookup   = &Profile{options{\n\t\ttransitional: transitionalLookup,\n\t\tuseSTD3Rules: true,\n\t\tcheckHyphens: true,\n\t\tcheckJoiners: true,\n\t\ttrie:         trie,\n\t\tfromPuny:     validateFromPunycode,\n\t\tmapping:      validateAndMap,\n\t\tbidirule:     bidirule.ValidString,\n\t}}\n\tdisplay = &Profile{options{\n\t\tuseSTD3Rules: true,\n\t\tcheckHyphens: true,\n\t\tcheckJoiners: true,\n\t\ttrie:         trie,\n\t\tfromPuny:     validateFromPunycode,\n\t\tmapping:      validateAndMap,\n\t\tbidirule:     bidirule.ValidString,\n\t}}\n\tregistration = &Profile{options{\n\t\tuseSTD3Rules:    true,\n\t\tverifyDNSLength: true,\n\t\tcheckHyphens:    true,\n\t\tcheckJoiners:    true,\n\t\ttrie:            trie,\n\t\tfromPuny:        validateFromPunycode,\n\t\tmapping:         validateRegistration,\n\t\tbidirule:        bidirule.ValidString,\n\t}}\n\n\t// TODO: profiles\n\t// Register: recommended for approving domain names: don't do any mappings\n\t// but rather reject on invalid input. Bundle or block deviation characters.\n)\n\ntype labelError struct{ label, code_ string }\n\nfunc (e labelError) code() string { return e.code_ }\nfunc (e labelError) Error() string {\n\treturn fmt.Sprintf(\"idna: invalid label %q\", e.label)\n}\n\ntype runeError rune\n\nfunc (e runeError) code() string { return \"P1\" }\nfunc (e runeError) Error() string {\n\treturn fmt.Sprintf(\"idna: disallowed rune %U\", e)\n}\n\n// process implements the algorithm described in section 4 of UTS #46,\n// see https://www.unicode.org/reports/tr46.\nfunc (p *Profile) process(s string, toASCII bool) (string, error) {\n\tvar err error\n\tvar isBidi bool\n\tif p.mapping != nil {\n\t\ts, isBidi, err = p.mapping(p, s)\n\t}\n\t// Remove leading empty labels.\n\tif p.removeLeadingDots {\n\t\tfor ; len(s) > 0 && s[0] == '.'; s = s[1:] {\n\t\t}\n\t}\n\t// TODO: allow for a quick check of the tables data.\n\t// It seems like we should only create this error on ToASCII, but the\n\t// UTS 46 conformance tests suggests we should always check this.\n\tif err == nil && p.verifyDNSLength && s == \"\" {\n\t\terr = &labelError{s, \"A4\"}\n\t}\n\tlabels := labelIter{orig: s}\n\tfor ; !labels.done(); labels.next() {\n\t\tlabel := labels.label()\n\t\tif label == \"\" {\n\t\t\t// Empty labels are not okay. The label iterator skips the last\n\t\t\t// label if it is empty.\n\t\t\tif err == nil && p.verifyDNSLength {\n\t\t\t\terr = &labelError{s, \"A4\"}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(label, acePrefix) {\n\t\t\tu, err2 := decode(label[len(acePrefix):])\n\t\t\tif err2 != nil {\n\t\t\t\tif err == nil {\n\t\t\t\t\terr = err2\n\t\t\t\t}\n\t\t\t\t// Spec says keep the old label.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tisBidi = isBidi || bidirule.DirectionString(u) != bidi.LeftToRight\n\t\t\tlabels.set(u)\n\t\t\tif err == nil && p.fromPuny != nil {\n\t\t\t\terr = p.fromPuny(p, u)\n\t\t\t}\n\t\t\tif err == nil {\n\t\t\t\t// This should be called on NonTransitional, according to the\n\t\t\t\t// spec, but that currently does not have any effect. Use the\n\t\t\t\t// original profile to preserve options.\n\t\t\t\terr = p.validateLabel(u)\n\t\t\t}\n\t\t} else if err == nil {\n\t\t\terr = p.validateLabel(label)\n\t\t}\n\t}\n\tif isBidi && p.bidirule != nil && err == nil {\n\t\tfor labels.reset(); !labels.done(); labels.next() {\n\t\t\tif !p.bidirule(labels.label()) {\n\t\t\t\terr = &labelError{s, \"B\"}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tif toASCII {\n\t\tfor labels.reset(); !labels.done(); labels.next() {\n\t\t\tlabel := labels.label()\n\t\t\tif !ascii(label) {\n\t\t\t\ta, err2 := encode(acePrefix, label)\n\t\t\t\tif err == nil {\n\t\t\t\t\terr = err2\n\t\t\t\t}\n\t\t\t\tlabel = a\n\t\t\t\tlabels.set(a)\n\t\t\t}\n\t\t\tn := len(label)\n\t\t\tif p.verifyDNSLength && err == nil && (n == 0 || n > 63) {\n\t\t\t\terr = &labelError{label, \"A4\"}\n\t\t\t}\n\t\t}\n\t}\n\ts = labels.result()\n\tif toASCII && p.verifyDNSLength && err == nil {\n\t\t// Compute the length of the domain name minus the root label and its dot.\n\t\tn := len(s)\n\t\tif n > 0 && s[n-1] == '.' {\n\t\t\tn--\n\t\t}\n\t\tif len(s) < 1 || n > 253 {\n\t\t\terr = &labelError{s, \"A4\"}\n\t\t}\n\t}\n\treturn s, err\n}\n\nfunc normalize(p *Profile, s string) (mapped string, isBidi bool, err error) {\n\t// TODO: consider first doing a quick check to see if any of these checks\n\t// need to be done. This will make it slower in the general case, but\n\t// faster in the common case.\n\tmapped = norm.NFC.String(s)\n\tisBidi = bidirule.DirectionString(mapped) == bidi.RightToLeft\n\treturn mapped, isBidi, nil\n}\n\nfunc validateRegistration(p *Profile, s string) (idem string, bidi bool, err error) {\n\t// TODO: filter need for normalization in loop below.\n\tif !norm.NFC.IsNormalString(s) {\n\t\treturn s, false, &labelError{s, \"V1\"}\n\t}\n\tfor i := 0; i < len(s); {\n\t\tv, sz := trie.lookupString(s[i:])\n\t\tif sz == 0 {\n\t\t\treturn s, bidi, runeError(utf8.RuneError)\n\t\t}\n\t\tbidi = bidi || info(v).isBidi(s[i:])\n\t\t// Copy bytes not copied so far.\n\t\tswitch p.simplify(info(v).category()) {\n\t\t// TODO: handle the NV8 defined in the Unicode idna data set to allow\n\t\t// for strict conformance to IDNA2008.\n\t\tcase valid, deviation:\n\t\tcase disallowed, mapped, unknown, ignored:\n\t\t\tr, _ := utf8.DecodeRuneInString(s[i:])\n\t\t\treturn s, bidi, runeError(r)\n\t\t}\n\t\ti += sz\n\t}\n\treturn s, bidi, nil\n}\n\nfunc (c info) isBidi(s string) bool {\n\tif !c.isMapped() {\n\t\treturn c&attributesMask == rtl\n\t}\n\t// TODO: also store bidi info for mapped data. This is possible, but a bit\n\t// cumbersome and not for the common case.\n\tp, _ := bidi.LookupString(s)\n\tswitch p.Class() {\n\tcase bidi.R, bidi.AL, bidi.AN:\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc validateAndMap(p *Profile, s string) (vm string, bidi bool, err error) {\n\tvar (\n\t\tb []byte\n\t\tk int\n\t)\n\t// combinedInfoBits contains the or-ed bits of all runes. We use this\n\t// to derive the mayNeedNorm bit later. This may trigger normalization\n\t// overeagerly, but it will not do so in the common case. The end result\n\t// is another 10% saving on BenchmarkProfile for the common case.\n\tvar combinedInfoBits info\n\tfor i := 0; i < len(s); {\n\t\tv, sz := trie.lookupString(s[i:])\n\t\tif sz == 0 {\n\t\t\tb = append(b, s[k:i]...)\n\t\t\tb = append(b, \"\\ufffd\"...)\n\t\t\tk = len(s)\n\t\t\tif err == nil {\n\t\t\t\terr = runeError(utf8.RuneError)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tcombinedInfoBits |= info(v)\n\t\tbidi = bidi || info(v).isBidi(s[i:])\n\t\tstart := i\n\t\ti += sz\n\t\t// Copy bytes not copied so far.\n\t\tswitch p.simplify(info(v).category()) {\n\t\tcase valid:\n\t\t\tcontinue\n\t\tcase disallowed:\n\t\t\tif err == nil {\n\t\t\t\tr, _ := utf8.DecodeRuneInString(s[start:])\n\t\t\t\terr = runeError(r)\n\t\t\t}\n\t\t\tcontinue\n\t\tcase mapped, deviation:\n\t\t\tb = append(b, s[k:start]...)\n\t\t\tb = info(v).appendMapping(b, s[start:i])\n\t\tcase ignored:\n\t\t\tb = append(b, s[k:start]...)\n\t\t\t// drop the rune\n\t\tcase unknown:\n\t\t\tb = append(b, s[k:start]...)\n\t\t\tb = append(b, \"\\ufffd\"...)\n\t\t}\n\t\tk = i\n\t}\n\tif k == 0 {\n\t\t// No changes so far.\n\t\tif combinedInfoBits&mayNeedNorm != 0 {\n\t\t\ts = norm.NFC.String(s)\n\t\t}\n\t} else {\n\t\tb = append(b, s[k:]...)\n\t\tif norm.NFC.QuickSpan(b) != len(b) {\n\t\t\tb = norm.NFC.Bytes(b)\n\t\t}\n\t\t// TODO: the punycode converters require strings as input.\n\t\ts = string(b)\n\t}\n\treturn s, bidi, err\n}\n\n// A labelIter allows iterating over domain name labels.\ntype labelIter struct {\n\torig     string\n\tslice    []string\n\tcurStart int\n\tcurEnd   int\n\ti        int\n}\n\nfunc (l *labelIter) reset() {\n\tl.curStart = 0\n\tl.curEnd = 0\n\tl.i = 0\n}\n\nfunc (l *labelIter) done() bool {\n\treturn l.curStart >= len(l.orig)\n}\n\nfunc (l *labelIter) result() string {\n\tif l.slice != nil {\n\t\treturn strings.Join(l.slice, \".\")\n\t}\n\treturn l.orig\n}\n\nfunc (l *labelIter) label() string {\n\tif l.slice != nil {\n\t\treturn l.slice[l.i]\n\t}\n\tp := strings.IndexByte(l.orig[l.curStart:], '.')\n\tl.curEnd = l.curStart + p\n\tif p == -1 {\n\t\tl.curEnd = len(l.orig)\n\t}\n\treturn l.orig[l.curStart:l.curEnd]\n}\n\n// next sets the value to the next label. It skips the last label if it is empty.\nfunc (l *labelIter) next() {\n\tl.i++\n\tif l.slice != nil {\n\t\tif l.i >= len(l.slice) || l.i == len(l.slice)-1 && l.slice[l.i] == \"\" {\n\t\t\tl.curStart = len(l.orig)\n\t\t}\n\t} else {\n\t\tl.curStart = l.curEnd + 1\n\t\tif l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' {\n\t\t\tl.curStart = len(l.orig)\n\t\t}\n\t}\n}\n\nfunc (l *labelIter) set(s string) {\n\tif l.slice == nil {\n\t\tl.slice = strings.Split(l.orig, \".\")\n\t}\n\tl.slice[l.i] = s\n}\n\n// acePrefix is the ASCII Compatible Encoding prefix.\nconst acePrefix = \"xn--\"\n\nfunc (p *Profile) simplify(cat category) category {\n\tswitch cat {\n\tcase disallowedSTD3Mapped:\n\t\tif p.useSTD3Rules {\n\t\t\tcat = disallowed\n\t\t} else {\n\t\t\tcat = mapped\n\t\t}\n\tcase disallowedSTD3Valid:\n\t\tif p.useSTD3Rules {\n\t\t\tcat = disallowed\n\t\t} else {\n\t\t\tcat = valid\n\t\t}\n\tcase deviation:\n\t\tif !p.transitional {\n\t\t\tcat = valid\n\t\t}\n\tcase validNV8, validXV8:\n\t\t// TODO: handle V2008\n\t\tcat = valid\n\t}\n\treturn cat\n}\n\nfunc validateFromPunycode(p *Profile, s string) error {\n\tif !norm.NFC.IsNormalString(s) {\n\t\treturn &labelError{s, \"V1\"}\n\t}\n\t// TODO: detect whether string may have to be normalized in the following\n\t// loop.\n\tfor i := 0; i < len(s); {\n\t\tv, sz := trie.lookupString(s[i:])\n\t\tif sz == 0 {\n\t\t\treturn runeError(utf8.RuneError)\n\t\t}\n\t\tif c := p.simplify(info(v).category()); c != valid && c != deviation {\n\t\t\treturn &labelError{s, \"V6\"}\n\t\t}\n\t\ti += sz\n\t}\n\treturn nil\n}\n\nconst (\n\tzwnj = \"\\u200c\"\n\tzwj  = \"\\u200d\"\n)\n\ntype joinState int8\n\nconst (\n\tstateStart joinState = iota\n\tstateVirama\n\tstateBefore\n\tstateBeforeVirama\n\tstateAfter\n\tstateFAIL\n)\n\nvar joinStates = [][numJoinTypes]joinState{\n\tstateStart: {\n\t\tjoiningL:   stateBefore,\n\t\tjoiningD:   stateBefore,\n\t\tjoinZWNJ:   stateFAIL,\n\t\tjoinZWJ:    stateFAIL,\n\t\tjoinVirama: stateVirama,\n\t},\n\tstateVirama: {\n\t\tjoiningL: stateBefore,\n\t\tjoiningD: stateBefore,\n\t},\n\tstateBefore: {\n\t\tjoiningL:   stateBefore,\n\t\tjoiningD:   stateBefore,\n\t\tjoiningT:   stateBefore,\n\t\tjoinZWNJ:   stateAfter,\n\t\tjoinZWJ:    stateFAIL,\n\t\tjoinVirama: stateBeforeVirama,\n\t},\n\tstateBeforeVirama: {\n\t\tjoiningL: stateBefore,\n\t\tjoiningD: stateBefore,\n\t\tjoiningT: stateBefore,\n\t},\n\tstateAfter: {\n\t\tjoiningL:   stateFAIL,\n\t\tjoiningD:   stateBefore,\n\t\tjoiningT:   stateAfter,\n\t\tjoiningR:   stateStart,\n\t\tjoinZWNJ:   stateFAIL,\n\t\tjoinZWJ:    stateFAIL,\n\t\tjoinVirama: stateAfter, // no-op as we can't accept joiners here\n\t},\n\tstateFAIL: {\n\t\t0:          stateFAIL,\n\t\tjoiningL:   stateFAIL,\n\t\tjoiningD:   stateFAIL,\n\t\tjoiningT:   stateFAIL,\n\t\tjoiningR:   stateFAIL,\n\t\tjoinZWNJ:   stateFAIL,\n\t\tjoinZWJ:    stateFAIL,\n\t\tjoinVirama: stateFAIL,\n\t},\n}\n\n// validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are\n// already implicitly satisfied by the overall implementation.\nfunc (p *Profile) validateLabel(s string) (err error) {\n\tif s == \"\" {\n\t\tif p.verifyDNSLength {\n\t\t\treturn &labelError{s, \"A4\"}\n\t\t}\n\t\treturn nil\n\t}\n\tif p.checkHyphens {\n\t\tif len(s) > 4 && s[2] == '-' && s[3] == '-' {\n\t\t\treturn &labelError{s, \"V2\"}\n\t\t}\n\t\tif s[0] == '-' || s[len(s)-1] == '-' {\n\t\t\treturn &labelError{s, \"V3\"}\n\t\t}\n\t}\n\tif !p.checkJoiners {\n\t\treturn nil\n\t}\n\ttrie := p.trie // p.checkJoiners is only set if trie is set.\n\t// TODO: merge the use of this in the trie.\n\tv, sz := trie.lookupString(s)\n\tx := info(v)\n\tif x.isModifier() {\n\t\treturn &labelError{s, \"V5\"}\n\t}\n\t// Quickly return in the absence of zero-width (non) joiners.\n\tif strings.Index(s, zwj) == -1 && strings.Index(s, zwnj) == -1 {\n\t\treturn nil\n\t}\n\tst := stateStart\n\tfor i := 0; ; {\n\t\tjt := x.joinType()\n\t\tif s[i:i+sz] == zwj {\n\t\t\tjt = joinZWJ\n\t\t} else if s[i:i+sz] == zwnj {\n\t\t\tjt = joinZWNJ\n\t\t}\n\t\tst = joinStates[st][jt]\n\t\tif x.isViramaModifier() {\n\t\t\tst = joinStates[st][joinVirama]\n\t\t}\n\t\tif i += sz; i == len(s) {\n\t\t\tbreak\n\t\t}\n\t\tv, sz = trie.lookupString(s[i:])\n\t\tx = info(v)\n\t}\n\tif st == stateFAIL || st == stateAfter {\n\t\treturn &labelError{s, \"C\"}\n\t}\n\treturn nil\n}\n\nfunc ascii(s string) bool {\n\tfor i := 0; i < len(s); i++ {\n\t\tif s[i] >= utf8.RuneSelf {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/idna/idna9.0.0.go",
    "content": "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n// Copyright 2016 The Go 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\n//go:build !go1.10\n\n// Package idna implements IDNA2008 using the compatibility processing\n// defined by UTS (Unicode Technical Standard) #46, which defines a standard to\n// deal with the transition from IDNA2003.\n//\n// IDNA2008 (Internationalized Domain Names for Applications), is defined in RFC\n// 5890, RFC 5891, RFC 5892, RFC 5893 and RFC 5894.\n// UTS #46 is defined in https://www.unicode.org/reports/tr46.\n// See https://unicode.org/cldr/utility/idna.jsp for a visualization of the\n// differences between these two standards.\npackage idna // import \"golang.org/x/net/idna\"\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"golang.org/x/text/secure/bidirule\"\n\t\"golang.org/x/text/unicode/norm\"\n)\n\n// NOTE: Unlike common practice in Go APIs, the functions will return a\n// sanitized domain name in case of errors. Browsers sometimes use a partially\n// evaluated string as lookup.\n// TODO: the current error handling is, in my opinion, the least opinionated.\n// Other strategies are also viable, though:\n// Option 1) Return an empty string in case of error, but allow the user to\n//    specify explicitly which errors to ignore.\n// Option 2) Return the partially evaluated string if it is itself a valid\n//    string, otherwise return the empty string in case of error.\n// Option 3) Option 1 and 2.\n// Option 4) Always return an empty string for now and implement Option 1 as\n//    needed, and document that the return string may not be empty in case of\n//    error in the future.\n// I think Option 1 is best, but it is quite opinionated.\n\n// ToASCII is a wrapper for Punycode.ToASCII.\nfunc ToASCII(s string) (string, error) {\n\treturn Punycode.process(s, true)\n}\n\n// ToUnicode is a wrapper for Punycode.ToUnicode.\nfunc ToUnicode(s string) (string, error) {\n\treturn Punycode.process(s, false)\n}\n\n// An Option configures a Profile at creation time.\ntype Option func(*options)\n\n// Transitional sets a Profile to use the Transitional mapping as defined in UTS\n// #46. This will cause, for example, \"ß\" to be mapped to \"ss\". Using the\n// transitional mapping provides a compromise between IDNA2003 and IDNA2008\n// compatibility. It is used by some browsers when resolving domain names. This\n// option is only meaningful if combined with MapForLookup.\nfunc Transitional(transitional bool) Option {\n\treturn func(o *options) { o.transitional = transitional }\n}\n\n// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts\n// are longer than allowed by the RFC.\n//\n// This option corresponds to the VerifyDnsLength flag in UTS #46.\nfunc VerifyDNSLength(verify bool) Option {\n\treturn func(o *options) { o.verifyDNSLength = verify }\n}\n\n// RemoveLeadingDots removes leading label separators. Leading runes that map to\n// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well.\nfunc RemoveLeadingDots(remove bool) Option {\n\treturn func(o *options) { o.removeLeadingDots = remove }\n}\n\n// ValidateLabels sets whether to check the mandatory label validation criteria\n// as defined in Section 5.4 of RFC 5891. This includes testing for correct use\n// of hyphens ('-'), normalization, validity of runes, and the context rules.\n// In particular, ValidateLabels also sets the CheckHyphens and CheckJoiners flags\n// in UTS #46.\nfunc ValidateLabels(enable bool) Option {\n\treturn func(o *options) {\n\t\t// Don't override existing mappings, but set one that at least checks\n\t\t// normalization if it is not set.\n\t\tif o.mapping == nil && enable {\n\t\t\to.mapping = normalize\n\t\t}\n\t\to.trie = trie\n\t\to.checkJoiners = enable\n\t\to.checkHyphens = enable\n\t\tif enable {\n\t\t\to.fromPuny = validateFromPunycode\n\t\t} else {\n\t\t\to.fromPuny = nil\n\t\t}\n\t}\n}\n\n// CheckHyphens sets whether to check for correct use of hyphens ('-') in\n// labels. Most web browsers do not have this option set, since labels such as\n// \"r3---sn-apo3qvuoxuxbt-j5pe\" are in common use.\n//\n// This option corresponds to the CheckHyphens flag in UTS #46.\nfunc CheckHyphens(enable bool) Option {\n\treturn func(o *options) { o.checkHyphens = enable }\n}\n\n// CheckJoiners sets whether to check the ContextJ rules as defined in Appendix\n// A of RFC 5892, concerning the use of joiner runes.\n//\n// This option corresponds to the CheckJoiners flag in UTS #46.\nfunc CheckJoiners(enable bool) Option {\n\treturn func(o *options) {\n\t\to.trie = trie\n\t\to.checkJoiners = enable\n\t}\n}\n\n// StrictDomainName limits the set of permissible ASCII characters to those\n// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the\n// hyphen). This is set by default for MapForLookup and ValidateForRegistration,\n// but is only useful if ValidateLabels is set.\n//\n// This option is useful, for instance, for browsers that allow characters\n// outside this range, for example a '_' (U+005F LOW LINE). See\n// http://www.rfc-editor.org/std/std3.txt for more details.\n//\n// This option corresponds to the UseSTD3ASCIIRules flag in UTS #46.\nfunc StrictDomainName(use bool) Option {\n\treturn func(o *options) { o.useSTD3Rules = use }\n}\n\n// NOTE: the following options pull in tables. The tables should not be linked\n// in as long as the options are not used.\n\n// BidiRule enables the Bidi rule as defined in RFC 5893. Any application\n// that relies on proper validation of labels should include this rule.\n//\n// This option corresponds to the CheckBidi flag in UTS #46.\nfunc BidiRule() Option {\n\treturn func(o *options) { o.bidirule = bidirule.ValidString }\n}\n\n// ValidateForRegistration sets validation options to verify that a given IDN is\n// properly formatted for registration as defined by Section 4 of RFC 5891.\nfunc ValidateForRegistration() Option {\n\treturn func(o *options) {\n\t\to.mapping = validateRegistration\n\t\tStrictDomainName(true)(o)\n\t\tValidateLabels(true)(o)\n\t\tVerifyDNSLength(true)(o)\n\t\tBidiRule()(o)\n\t}\n}\n\n// MapForLookup sets validation and mapping options such that a given IDN is\n// transformed for domain name lookup according to the requirements set out in\n// Section 5 of RFC 5891. The mappings follow the recommendations of RFC 5894,\n// RFC 5895 and UTS 46. It does not add the Bidi Rule. Use the BidiRule option\n// to add this check.\n//\n// The mappings include normalization and mapping case, width and other\n// compatibility mappings.\nfunc MapForLookup() Option {\n\treturn func(o *options) {\n\t\to.mapping = validateAndMap\n\t\tStrictDomainName(true)(o)\n\t\tValidateLabels(true)(o)\n\t\tRemoveLeadingDots(true)(o)\n\t}\n}\n\ntype options struct {\n\ttransitional      bool\n\tuseSTD3Rules      bool\n\tcheckHyphens      bool\n\tcheckJoiners      bool\n\tverifyDNSLength   bool\n\tremoveLeadingDots bool\n\n\ttrie *idnaTrie\n\n\t// fromPuny calls validation rules when converting A-labels to U-labels.\n\tfromPuny func(p *Profile, s string) error\n\n\t// mapping implements a validation and mapping step as defined in RFC 5895\n\t// or UTS 46, tailored to, for example, domain registration or lookup.\n\tmapping func(p *Profile, s string) (string, error)\n\n\t// bidirule, if specified, checks whether s conforms to the Bidi Rule\n\t// defined in RFC 5893.\n\tbidirule func(s string) bool\n}\n\n// A Profile defines the configuration of a IDNA mapper.\ntype Profile struct {\n\toptions\n}\n\nfunc apply(o *options, opts []Option) {\n\tfor _, f := range opts {\n\t\tf(o)\n\t}\n}\n\n// New creates a new Profile.\n//\n// With no options, the returned Profile is the most permissive and equals the\n// Punycode Profile. Options can be passed to further restrict the Profile. The\n// MapForLookup and ValidateForRegistration options set a collection of options,\n// for lookup and registration purposes respectively, which can be tailored by\n// adding more fine-grained options, where later options override earlier\n// options.\nfunc New(o ...Option) *Profile {\n\tp := &Profile{}\n\tapply(&p.options, o)\n\treturn p\n}\n\n// ToASCII converts a domain or domain label to its ASCII form. For example,\n// ToASCII(\"bücher.example.com\") is \"xn--bcher-kva.example.com\", and\n// ToASCII(\"golang\") is \"golang\". If an error is encountered it will return\n// an error and a (partially) processed result.\nfunc (p *Profile) ToASCII(s string) (string, error) {\n\treturn p.process(s, true)\n}\n\n// ToUnicode converts a domain or domain label to its Unicode form. For example,\n// ToUnicode(\"xn--bcher-kva.example.com\") is \"bücher.example.com\", and\n// ToUnicode(\"golang\") is \"golang\". If an error is encountered it will return\n// an error and a (partially) processed result.\nfunc (p *Profile) ToUnicode(s string) (string, error) {\n\tpp := *p\n\tpp.transitional = false\n\treturn pp.process(s, false)\n}\n\n// String reports a string with a description of the profile for debugging\n// purposes. The string format may change with different versions.\nfunc (p *Profile) String() string {\n\ts := \"\"\n\tif p.transitional {\n\t\ts = \"Transitional\"\n\t} else {\n\t\ts = \"NonTransitional\"\n\t}\n\tif p.useSTD3Rules {\n\t\ts += \":UseSTD3Rules\"\n\t}\n\tif p.checkHyphens {\n\t\ts += \":CheckHyphens\"\n\t}\n\tif p.checkJoiners {\n\t\ts += \":CheckJoiners\"\n\t}\n\tif p.verifyDNSLength {\n\t\ts += \":VerifyDNSLength\"\n\t}\n\treturn s\n}\n\nvar (\n\t// Punycode is a Profile that does raw punycode processing with a minimum\n\t// of validation.\n\tPunycode *Profile = punycode\n\n\t// Lookup is the recommended profile for looking up domain names, according\n\t// to Section 5 of RFC 5891. The exact configuration of this profile may\n\t// change over time.\n\tLookup *Profile = lookup\n\n\t// Display is the recommended profile for displaying domain names.\n\t// The configuration of this profile may change over time.\n\tDisplay *Profile = display\n\n\t// Registration is the recommended profile for checking whether a given\n\t// IDN is valid for registration, according to Section 4 of RFC 5891.\n\tRegistration *Profile = registration\n\n\tpunycode = &Profile{}\n\tlookup   = &Profile{options{\n\t\ttransitional:      true,\n\t\tremoveLeadingDots: true,\n\t\tuseSTD3Rules:      true,\n\t\tcheckHyphens:      true,\n\t\tcheckJoiners:      true,\n\t\ttrie:              trie,\n\t\tfromPuny:          validateFromPunycode,\n\t\tmapping:           validateAndMap,\n\t\tbidirule:          bidirule.ValidString,\n\t}}\n\tdisplay = &Profile{options{\n\t\tuseSTD3Rules:      true,\n\t\tremoveLeadingDots: true,\n\t\tcheckHyphens:      true,\n\t\tcheckJoiners:      true,\n\t\ttrie:              trie,\n\t\tfromPuny:          validateFromPunycode,\n\t\tmapping:           validateAndMap,\n\t\tbidirule:          bidirule.ValidString,\n\t}}\n\tregistration = &Profile{options{\n\t\tuseSTD3Rules:    true,\n\t\tverifyDNSLength: true,\n\t\tcheckHyphens:    true,\n\t\tcheckJoiners:    true,\n\t\ttrie:            trie,\n\t\tfromPuny:        validateFromPunycode,\n\t\tmapping:         validateRegistration,\n\t\tbidirule:        bidirule.ValidString,\n\t}}\n\n\t// TODO: profiles\n\t// Register: recommended for approving domain names: don't do any mappings\n\t// but rather reject on invalid input. Bundle or block deviation characters.\n)\n\ntype labelError struct{ label, code_ string }\n\nfunc (e labelError) code() string { return e.code_ }\nfunc (e labelError) Error() string {\n\treturn fmt.Sprintf(\"idna: invalid label %q\", e.label)\n}\n\ntype runeError rune\n\nfunc (e runeError) code() string { return \"P1\" }\nfunc (e runeError) Error() string {\n\treturn fmt.Sprintf(\"idna: disallowed rune %U\", e)\n}\n\n// process implements the algorithm described in section 4 of UTS #46,\n// see https://www.unicode.org/reports/tr46.\nfunc (p *Profile) process(s string, toASCII bool) (string, error) {\n\tvar err error\n\tif p.mapping != nil {\n\t\ts, err = p.mapping(p, s)\n\t}\n\t// Remove leading empty labels.\n\tif p.removeLeadingDots {\n\t\tfor ; len(s) > 0 && s[0] == '.'; s = s[1:] {\n\t\t}\n\t}\n\t// It seems like we should only create this error on ToASCII, but the\n\t// UTS 46 conformance tests suggests we should always check this.\n\tif err == nil && p.verifyDNSLength && s == \"\" {\n\t\terr = &labelError{s, \"A4\"}\n\t}\n\tlabels := labelIter{orig: s}\n\tfor ; !labels.done(); labels.next() {\n\t\tlabel := labels.label()\n\t\tif label == \"\" {\n\t\t\t// Empty labels are not okay. The label iterator skips the last\n\t\t\t// label if it is empty.\n\t\t\tif err == nil && p.verifyDNSLength {\n\t\t\t\terr = &labelError{s, \"A4\"}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(label, acePrefix) {\n\t\t\tu, err2 := decode(label[len(acePrefix):])\n\t\t\tif err2 != nil {\n\t\t\t\tif err == nil {\n\t\t\t\t\terr = err2\n\t\t\t\t}\n\t\t\t\t// Spec says keep the old label.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tlabels.set(u)\n\t\t\tif err == nil && p.fromPuny != nil {\n\t\t\t\terr = p.fromPuny(p, u)\n\t\t\t}\n\t\t\tif err == nil {\n\t\t\t\t// This should be called on NonTransitional, according to the\n\t\t\t\t// spec, but that currently does not have any effect. Use the\n\t\t\t\t// original profile to preserve options.\n\t\t\t\terr = p.validateLabel(u)\n\t\t\t}\n\t\t} else if err == nil {\n\t\t\terr = p.validateLabel(label)\n\t\t}\n\t}\n\tif toASCII {\n\t\tfor labels.reset(); !labels.done(); labels.next() {\n\t\t\tlabel := labels.label()\n\t\t\tif !ascii(label) {\n\t\t\t\ta, err2 := encode(acePrefix, label)\n\t\t\t\tif err == nil {\n\t\t\t\t\terr = err2\n\t\t\t\t}\n\t\t\t\tlabel = a\n\t\t\t\tlabels.set(a)\n\t\t\t}\n\t\t\tn := len(label)\n\t\t\tif p.verifyDNSLength && err == nil && (n == 0 || n > 63) {\n\t\t\t\terr = &labelError{label, \"A4\"}\n\t\t\t}\n\t\t}\n\t}\n\ts = labels.result()\n\tif toASCII && p.verifyDNSLength && err == nil {\n\t\t// Compute the length of the domain name minus the root label and its dot.\n\t\tn := len(s)\n\t\tif n > 0 && s[n-1] == '.' {\n\t\t\tn--\n\t\t}\n\t\tif len(s) < 1 || n > 253 {\n\t\t\terr = &labelError{s, \"A4\"}\n\t\t}\n\t}\n\treturn s, err\n}\n\nfunc normalize(p *Profile, s string) (string, error) {\n\treturn norm.NFC.String(s), nil\n}\n\nfunc validateRegistration(p *Profile, s string) (string, error) {\n\tif !norm.NFC.IsNormalString(s) {\n\t\treturn s, &labelError{s, \"V1\"}\n\t}\n\tfor i := 0; i < len(s); {\n\t\tv, sz := trie.lookupString(s[i:])\n\t\t// Copy bytes not copied so far.\n\t\tswitch p.simplify(info(v).category()) {\n\t\t// TODO: handle the NV8 defined in the Unicode idna data set to allow\n\t\t// for strict conformance to IDNA2008.\n\t\tcase valid, deviation:\n\t\tcase disallowed, mapped, unknown, ignored:\n\t\t\tr, _ := utf8.DecodeRuneInString(s[i:])\n\t\t\treturn s, runeError(r)\n\t\t}\n\t\ti += sz\n\t}\n\treturn s, nil\n}\n\nfunc validateAndMap(p *Profile, s string) (string, error) {\n\tvar (\n\t\terr error\n\t\tb   []byte\n\t\tk   int\n\t)\n\tfor i := 0; i < len(s); {\n\t\tv, sz := trie.lookupString(s[i:])\n\t\tstart := i\n\t\ti += sz\n\t\t// Copy bytes not copied so far.\n\t\tswitch p.simplify(info(v).category()) {\n\t\tcase valid:\n\t\t\tcontinue\n\t\tcase disallowed:\n\t\t\tif err == nil {\n\t\t\t\tr, _ := utf8.DecodeRuneInString(s[start:])\n\t\t\t\terr = runeError(r)\n\t\t\t}\n\t\t\tcontinue\n\t\tcase mapped, deviation:\n\t\t\tb = append(b, s[k:start]...)\n\t\t\tb = info(v).appendMapping(b, s[start:i])\n\t\tcase ignored:\n\t\t\tb = append(b, s[k:start]...)\n\t\t\t// drop the rune\n\t\tcase unknown:\n\t\t\tb = append(b, s[k:start]...)\n\t\t\tb = append(b, \"\\ufffd\"...)\n\t\t}\n\t\tk = i\n\t}\n\tif k == 0 {\n\t\t// No changes so far.\n\t\ts = norm.NFC.String(s)\n\t} else {\n\t\tb = append(b, s[k:]...)\n\t\tif norm.NFC.QuickSpan(b) != len(b) {\n\t\t\tb = norm.NFC.Bytes(b)\n\t\t}\n\t\t// TODO: the punycode converters require strings as input.\n\t\ts = string(b)\n\t}\n\treturn s, err\n}\n\n// A labelIter allows iterating over domain name labels.\ntype labelIter struct {\n\torig     string\n\tslice    []string\n\tcurStart int\n\tcurEnd   int\n\ti        int\n}\n\nfunc (l *labelIter) reset() {\n\tl.curStart = 0\n\tl.curEnd = 0\n\tl.i = 0\n}\n\nfunc (l *labelIter) done() bool {\n\treturn l.curStart >= len(l.orig)\n}\n\nfunc (l *labelIter) result() string {\n\tif l.slice != nil {\n\t\treturn strings.Join(l.slice, \".\")\n\t}\n\treturn l.orig\n}\n\nfunc (l *labelIter) label() string {\n\tif l.slice != nil {\n\t\treturn l.slice[l.i]\n\t}\n\tp := strings.IndexByte(l.orig[l.curStart:], '.')\n\tl.curEnd = l.curStart + p\n\tif p == -1 {\n\t\tl.curEnd = len(l.orig)\n\t}\n\treturn l.orig[l.curStart:l.curEnd]\n}\n\n// next sets the value to the next label. It skips the last label if it is empty.\nfunc (l *labelIter) next() {\n\tl.i++\n\tif l.slice != nil {\n\t\tif l.i >= len(l.slice) || l.i == len(l.slice)-1 && l.slice[l.i] == \"\" {\n\t\t\tl.curStart = len(l.orig)\n\t\t}\n\t} else {\n\t\tl.curStart = l.curEnd + 1\n\t\tif l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' {\n\t\t\tl.curStart = len(l.orig)\n\t\t}\n\t}\n}\n\nfunc (l *labelIter) set(s string) {\n\tif l.slice == nil {\n\t\tl.slice = strings.Split(l.orig, \".\")\n\t}\n\tl.slice[l.i] = s\n}\n\n// acePrefix is the ASCII Compatible Encoding prefix.\nconst acePrefix = \"xn--\"\n\nfunc (p *Profile) simplify(cat category) category {\n\tswitch cat {\n\tcase disallowedSTD3Mapped:\n\t\tif p.useSTD3Rules {\n\t\t\tcat = disallowed\n\t\t} else {\n\t\t\tcat = mapped\n\t\t}\n\tcase disallowedSTD3Valid:\n\t\tif p.useSTD3Rules {\n\t\t\tcat = disallowed\n\t\t} else {\n\t\t\tcat = valid\n\t\t}\n\tcase deviation:\n\t\tif !p.transitional {\n\t\t\tcat = valid\n\t\t}\n\tcase validNV8, validXV8:\n\t\t// TODO: handle V2008\n\t\tcat = valid\n\t}\n\treturn cat\n}\n\nfunc validateFromPunycode(p *Profile, s string) error {\n\tif !norm.NFC.IsNormalString(s) {\n\t\treturn &labelError{s, \"V1\"}\n\t}\n\tfor i := 0; i < len(s); {\n\t\tv, sz := trie.lookupString(s[i:])\n\t\tif c := p.simplify(info(v).category()); c != valid && c != deviation {\n\t\t\treturn &labelError{s, \"V6\"}\n\t\t}\n\t\ti += sz\n\t}\n\treturn nil\n}\n\nconst (\n\tzwnj = \"\\u200c\"\n\tzwj  = \"\\u200d\"\n)\n\ntype joinState int8\n\nconst (\n\tstateStart joinState = iota\n\tstateVirama\n\tstateBefore\n\tstateBeforeVirama\n\tstateAfter\n\tstateFAIL\n)\n\nvar joinStates = [][numJoinTypes]joinState{\n\tstateStart: {\n\t\tjoiningL:   stateBefore,\n\t\tjoiningD:   stateBefore,\n\t\tjoinZWNJ:   stateFAIL,\n\t\tjoinZWJ:    stateFAIL,\n\t\tjoinVirama: stateVirama,\n\t},\n\tstateVirama: {\n\t\tjoiningL: stateBefore,\n\t\tjoiningD: stateBefore,\n\t},\n\tstateBefore: {\n\t\tjoiningL:   stateBefore,\n\t\tjoiningD:   stateBefore,\n\t\tjoiningT:   stateBefore,\n\t\tjoinZWNJ:   stateAfter,\n\t\tjoinZWJ:    stateFAIL,\n\t\tjoinVirama: stateBeforeVirama,\n\t},\n\tstateBeforeVirama: {\n\t\tjoiningL: stateBefore,\n\t\tjoiningD: stateBefore,\n\t\tjoiningT: stateBefore,\n\t},\n\tstateAfter: {\n\t\tjoiningL:   stateFAIL,\n\t\tjoiningD:   stateBefore,\n\t\tjoiningT:   stateAfter,\n\t\tjoiningR:   stateStart,\n\t\tjoinZWNJ:   stateFAIL,\n\t\tjoinZWJ:    stateFAIL,\n\t\tjoinVirama: stateAfter, // no-op as we can't accept joiners here\n\t},\n\tstateFAIL: {\n\t\t0:          stateFAIL,\n\t\tjoiningL:   stateFAIL,\n\t\tjoiningD:   stateFAIL,\n\t\tjoiningT:   stateFAIL,\n\t\tjoiningR:   stateFAIL,\n\t\tjoinZWNJ:   stateFAIL,\n\t\tjoinZWJ:    stateFAIL,\n\t\tjoinVirama: stateFAIL,\n\t},\n}\n\n// validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are\n// already implicitly satisfied by the overall implementation.\nfunc (p *Profile) validateLabel(s string) error {\n\tif s == \"\" {\n\t\tif p.verifyDNSLength {\n\t\t\treturn &labelError{s, \"A4\"}\n\t\t}\n\t\treturn nil\n\t}\n\tif p.bidirule != nil && !p.bidirule(s) {\n\t\treturn &labelError{s, \"B\"}\n\t}\n\tif p.checkHyphens {\n\t\tif len(s) > 4 && s[2] == '-' && s[3] == '-' {\n\t\t\treturn &labelError{s, \"V2\"}\n\t\t}\n\t\tif s[0] == '-' || s[len(s)-1] == '-' {\n\t\t\treturn &labelError{s, \"V3\"}\n\t\t}\n\t}\n\tif !p.checkJoiners {\n\t\treturn nil\n\t}\n\ttrie := p.trie // p.checkJoiners is only set if trie is set.\n\t// TODO: merge the use of this in the trie.\n\tv, sz := trie.lookupString(s)\n\tx := info(v)\n\tif x.isModifier() {\n\t\treturn &labelError{s, \"V5\"}\n\t}\n\t// Quickly return in the absence of zero-width (non) joiners.\n\tif strings.Index(s, zwj) == -1 && strings.Index(s, zwnj) == -1 {\n\t\treturn nil\n\t}\n\tst := stateStart\n\tfor i := 0; ; {\n\t\tjt := x.joinType()\n\t\tif s[i:i+sz] == zwj {\n\t\t\tjt = joinZWJ\n\t\t} else if s[i:i+sz] == zwnj {\n\t\t\tjt = joinZWNJ\n\t\t}\n\t\tst = joinStates[st][jt]\n\t\tif x.isViramaModifier() {\n\t\t\tst = joinStates[st][joinVirama]\n\t\t}\n\t\tif i += sz; i == len(s) {\n\t\t\tbreak\n\t\t}\n\t\tv, sz = trie.lookupString(s[i:])\n\t\tx = info(v)\n\t}\n\tif st == stateFAIL || st == stateAfter {\n\t\treturn &labelError{s, \"C\"}\n\t}\n\treturn nil\n}\n\nfunc ascii(s string) bool {\n\tfor i := 0; i < len(s); i++ {\n\t\tif s[i] >= utf8.RuneSelf {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/idna/pre_go118.go",
    "content": "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n// Copyright 2021 The Go 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\n//go:build !go1.18\n\npackage idna\n\nconst transitionalLookup = true\n"
  },
  {
    "path": "vendor/golang.org/x/net/idna/punycode.go",
    "content": "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n// Copyright 2016 The Go 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 idna\n\n// This file implements the Punycode algorithm from RFC 3492.\n\nimport (\n\t\"math\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\n// These parameter values are specified in section 5.\n//\n// All computation is done with int32s, so that overflow behavior is identical\n// regardless of whether int is 32-bit or 64-bit.\nconst (\n\tbase        int32 = 36\n\tdamp        int32 = 700\n\tinitialBias int32 = 72\n\tinitialN    int32 = 128\n\tskew        int32 = 38\n\ttmax        int32 = 26\n\ttmin        int32 = 1\n)\n\nfunc punyError(s string) error { return &labelError{s, \"A3\"} }\n\n// decode decodes a string as specified in section 6.2.\nfunc decode(encoded string) (string, error) {\n\tif encoded == \"\" {\n\t\treturn \"\", nil\n\t}\n\tpos := 1 + strings.LastIndex(encoded, \"-\")\n\tif pos == 1 {\n\t\treturn \"\", punyError(encoded)\n\t}\n\tif pos == len(encoded) {\n\t\treturn encoded[:len(encoded)-1], nil\n\t}\n\toutput := make([]rune, 0, len(encoded))\n\tif pos != 0 {\n\t\tfor _, r := range encoded[:pos-1] {\n\t\t\toutput = append(output, r)\n\t\t}\n\t}\n\ti, n, bias := int32(0), initialN, initialBias\n\toverflow := false\n\tfor pos < len(encoded) {\n\t\toldI, w := i, int32(1)\n\t\tfor k := base; ; k += base {\n\t\t\tif pos == len(encoded) {\n\t\t\t\treturn \"\", punyError(encoded)\n\t\t\t}\n\t\t\tdigit, ok := decodeDigit(encoded[pos])\n\t\t\tif !ok {\n\t\t\t\treturn \"\", punyError(encoded)\n\t\t\t}\n\t\t\tpos++\n\t\t\ti, overflow = madd(i, digit, w)\n\t\t\tif overflow {\n\t\t\t\treturn \"\", punyError(encoded)\n\t\t\t}\n\t\t\tt := k - bias\n\t\t\tif k <= bias {\n\t\t\t\tt = tmin\n\t\t\t} else if k >= bias+tmax {\n\t\t\t\tt = tmax\n\t\t\t}\n\t\t\tif digit < t {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tw, overflow = madd(0, w, base-t)\n\t\t\tif overflow {\n\t\t\t\treturn \"\", punyError(encoded)\n\t\t\t}\n\t\t}\n\t\tif len(output) >= 1024 {\n\t\t\treturn \"\", punyError(encoded)\n\t\t}\n\t\tx := int32(len(output) + 1)\n\t\tbias = adapt(i-oldI, x, oldI == 0)\n\t\tn += i / x\n\t\ti %= x\n\t\tif n < 0 || n > utf8.MaxRune {\n\t\t\treturn \"\", punyError(encoded)\n\t\t}\n\t\toutput = append(output, 0)\n\t\tcopy(output[i+1:], output[i:])\n\t\toutput[i] = n\n\t\ti++\n\t}\n\treturn string(output), nil\n}\n\n// encode encodes a string as specified in section 6.3 and prepends prefix to\n// the result.\n//\n// The \"while h < length(input)\" line in the specification becomes \"for\n// remaining != 0\" in the Go code, because len(s) in Go is in bytes, not runes.\nfunc encode(prefix, s string) (string, error) {\n\toutput := make([]byte, len(prefix), len(prefix)+1+2*len(s))\n\tcopy(output, prefix)\n\tdelta, n, bias := int32(0), initialN, initialBias\n\tb, remaining := int32(0), int32(0)\n\tfor _, r := range s {\n\t\tif r < 0x80 {\n\t\t\tb++\n\t\t\toutput = append(output, byte(r))\n\t\t} else {\n\t\t\tremaining++\n\t\t}\n\t}\n\th := b\n\tif b > 0 {\n\t\toutput = append(output, '-')\n\t}\n\toverflow := false\n\tfor remaining != 0 {\n\t\tm := int32(0x7fffffff)\n\t\tfor _, r := range s {\n\t\t\tif m > r && r >= n {\n\t\t\t\tm = r\n\t\t\t}\n\t\t}\n\t\tdelta, overflow = madd(delta, m-n, h+1)\n\t\tif overflow {\n\t\t\treturn \"\", punyError(s)\n\t\t}\n\t\tn = m\n\t\tfor _, r := range s {\n\t\t\tif r < n {\n\t\t\t\tdelta++\n\t\t\t\tif delta < 0 {\n\t\t\t\t\treturn \"\", punyError(s)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif r > n {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tq := delta\n\t\t\tfor k := base; ; k += base {\n\t\t\t\tt := k - bias\n\t\t\t\tif k <= bias {\n\t\t\t\t\tt = tmin\n\t\t\t\t} else if k >= bias+tmax {\n\t\t\t\t\tt = tmax\n\t\t\t\t}\n\t\t\t\tif q < t {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\toutput = append(output, encodeDigit(t+(q-t)%(base-t)))\n\t\t\t\tq = (q - t) / (base - t)\n\t\t\t}\n\t\t\toutput = append(output, encodeDigit(q))\n\t\t\tbias = adapt(delta, h+1, h == b)\n\t\t\tdelta = 0\n\t\t\th++\n\t\t\tremaining--\n\t\t}\n\t\tdelta++\n\t\tn++\n\t}\n\treturn string(output), nil\n}\n\n// madd computes a + (b * c), detecting overflow.\nfunc madd(a, b, c int32) (next int32, overflow bool) {\n\tp := int64(b) * int64(c)\n\tif p > math.MaxInt32-int64(a) {\n\t\treturn 0, true\n\t}\n\treturn a + int32(p), false\n}\n\nfunc decodeDigit(x byte) (digit int32, ok bool) {\n\tswitch {\n\tcase '0' <= x && x <= '9':\n\t\treturn int32(x - ('0' - 26)), true\n\tcase 'A' <= x && x <= 'Z':\n\t\treturn int32(x - 'A'), true\n\tcase 'a' <= x && x <= 'z':\n\t\treturn int32(x - 'a'), true\n\t}\n\treturn 0, false\n}\n\nfunc encodeDigit(digit int32) byte {\n\tswitch {\n\tcase 0 <= digit && digit < 26:\n\t\treturn byte(digit + 'a')\n\tcase 26 <= digit && digit < 36:\n\t\treturn byte(digit + ('0' - 26))\n\t}\n\tpanic(\"idna: internal error in punycode encoding\")\n}\n\n// adapt is the bias adaptation function specified in section 6.1.\nfunc adapt(delta, numPoints int32, firstTime bool) int32 {\n\tif firstTime {\n\t\tdelta /= damp\n\t} else {\n\t\tdelta /= 2\n\t}\n\tdelta += delta / numPoints\n\tk := int32(0)\n\tfor delta > ((base-tmin)*tmax)/2 {\n\t\tdelta /= base - tmin\n\t\tk += base\n\t}\n\treturn k + (base-tmin+1)*delta/(delta+skew)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/idna/tables10.0.0.go",
    "content": "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n//go:build go1.10 && !go1.13\n\npackage idna\n\n// UnicodeVersion is the Unicode version from which the tables in this package are derived.\nconst UnicodeVersion = \"10.0.0\"\n\nvar mappings string = \"\" + // Size: 8175 bytes\n\t\"\\x00\\x01 \\x03 ̈\\x01a\\x03 ̄\\x012\\x013\\x03 ́\\x03 ̧\\x011\\x01o\\x051⁄4\\x051⁄2\" +\n\t\"\\x053⁄4\\x03i̇\\x03l·\\x03ʼn\\x01s\\x03dž\\x03ⱥ\\x03ⱦ\\x01h\\x01j\\x01r\\x01w\\x01y\" +\n\t\"\\x03 ̆\\x03 ̇\\x03 ̊\\x03 ̨\\x03 ̃\\x03 ̋\\x01l\\x01x\\x04̈́\\x03 ι\\x01;\\x05 ̈́\" +\n\t\"\\x04եւ\\x04اٴ\\x04وٴ\\x04ۇٴ\\x04يٴ\\x06क़\\x06ख़\\x06ग़\\x06ज़\\x06ड़\\x06ढ़\\x06फ़\" +\n\t\"\\x06य़\\x06ড়\\x06ঢ়\\x06য়\\x06ਲ਼\\x06ਸ਼\\x06ਖ਼\\x06ਗ਼\\x06ਜ਼\\x06ਫ਼\\x06ଡ଼\\x06ଢ଼\" +\n\t\"\\x06ํา\\x06ໍາ\\x06ຫນ\\x06ຫມ\\x06གྷ\\x06ཌྷ\\x06དྷ\\x06བྷ\\x06ཛྷ\\x06ཀྵ\\x06ཱི\\x06ཱུ\" +\n\t\"\\x06ྲྀ\\x09ྲཱྀ\\x06ླྀ\\x09ླཱྀ\\x06ཱྀ\\x06ྒྷ\\x06ྜྷ\\x06ྡྷ\\x06ྦྷ\\x06ྫྷ\\x06ྐྵ\\x02\" +\n\t\"в\\x02д\\x02о\\x02с\\x02т\\x02ъ\\x02ѣ\\x02æ\\x01b\\x01d\\x01e\\x02ǝ\\x01g\\x01i\\x01k\" +\n\t\"\\x01m\\x01n\\x02ȣ\\x01p\\x01t\\x01u\\x02ɐ\\x02ɑ\\x02ə\\x02ɛ\\x02ɜ\\x02ŋ\\x02ɔ\\x02ɯ\" +\n\t\"\\x01v\\x02β\\x02γ\\x02δ\\x02φ\\x02χ\\x02ρ\\x02н\\x02ɒ\\x01c\\x02ɕ\\x02ð\\x01f\\x02ɟ\" +\n\t\"\\x02ɡ\\x02ɥ\\x02ɨ\\x02ɩ\\x02ɪ\\x02ʝ\\x02ɭ\\x02ʟ\\x02ɱ\\x02ɰ\\x02ɲ\\x02ɳ\\x02ɴ\\x02ɵ\" +\n\t\"\\x02ɸ\\x02ʂ\\x02ʃ\\x02ƫ\\x02ʉ\\x02ʊ\\x02ʋ\\x02ʌ\\x01z\\x02ʐ\\x02ʑ\\x02ʒ\\x02θ\\x02ss\" +\n\t\"\\x02ά\\x02έ\\x02ή\\x02ί\\x02ό\\x02ύ\\x02ώ\\x05ἀι\\x05ἁι\\x05ἂι\\x05ἃι\\x05ἄι\\x05ἅι\" +\n\t\"\\x05ἆι\\x05ἇι\\x05ἠι\\x05ἡι\\x05ἢι\\x05ἣι\\x05ἤι\\x05ἥι\\x05ἦι\\x05ἧι\\x05ὠι\\x05ὡι\" +\n\t\"\\x05ὢι\\x05ὣι\\x05ὤι\\x05ὥι\\x05ὦι\\x05ὧι\\x05ὰι\\x04αι\\x04άι\\x05ᾶι\\x02ι\\x05 ̈͂\" +\n\t\"\\x05ὴι\\x04ηι\\x04ήι\\x05ῆι\\x05 ̓̀\\x05 ̓́\\x05 ̓͂\\x02ΐ\\x05 ̔̀\\x05 ̔́\\x05 ̔͂\" +\n\t\"\\x02ΰ\\x05 ̈̀\\x01`\\x05ὼι\\x04ωι\\x04ώι\\x05ῶι\\x06′′\\x09′′′\\x06‵‵\\x09‵‵‵\\x02!\" +\n\t\"!\\x02??\\x02?!\\x02!?\\x0c′′′′\\x010\\x014\\x015\\x016\\x017\\x018\\x019\\x01+\\x01=\" +\n\t\"\\x01(\\x01)\\x02rs\\x02ħ\\x02no\\x01q\\x02sm\\x02tm\\x02ω\\x02å\\x02א\\x02ב\\x02ג\" +\n\t\"\\x02ד\\x02π\\x051⁄7\\x051⁄9\\x061⁄10\\x051⁄3\\x052⁄3\\x051⁄5\\x052⁄5\\x053⁄5\\x054\" +\n\t\"⁄5\\x051⁄6\\x055⁄6\\x051⁄8\\x053⁄8\\x055⁄8\\x057⁄8\\x041⁄\\x02ii\\x02iv\\x02vi\" +\n\t\"\\x04viii\\x02ix\\x02xi\\x050⁄3\\x06∫∫\\x09∫∫∫\\x06∮∮\\x09∮∮∮\\x0210\\x0211\\x0212\" +\n\t\"\\x0213\\x0214\\x0215\\x0216\\x0217\\x0218\\x0219\\x0220\\x04(10)\\x04(11)\\x04(12)\" +\n\t\"\\x04(13)\\x04(14)\\x04(15)\\x04(16)\\x04(17)\\x04(18)\\x04(19)\\x04(20)\\x0c∫∫∫∫\" +\n\t\"\\x02==\\x05⫝̸\\x02ɫ\\x02ɽ\\x02ȿ\\x02ɀ\\x01.\\x04 ゙\\x04 ゚\\x06より\\x06コト\\x05(ᄀ)\\x05\" +\n\t\"(ᄂ)\\x05(ᄃ)\\x05(ᄅ)\\x05(ᄆ)\\x05(ᄇ)\\x05(ᄉ)\\x05(ᄋ)\\x05(ᄌ)\\x05(ᄎ)\\x05(ᄏ)\\x05(ᄐ\" +\n\t\")\\x05(ᄑ)\\x05(ᄒ)\\x05(가)\\x05(나)\\x05(다)\\x05(라)\\x05(마)\\x05(바)\\x05(사)\\x05(아)\" +\n\t\"\\x05(자)\\x05(차)\\x05(카)\\x05(타)\\x05(파)\\x05(하)\\x05(주)\\x08(오전)\\x08(오후)\\x05(一)\" +\n\t\"\\x05(二)\\x05(三)\\x05(四)\\x05(五)\\x05(六)\\x05(七)\\x05(八)\\x05(九)\\x05(十)\\x05(月)\" +\n\t\"\\x05(火)\\x05(水)\\x05(木)\\x05(金)\\x05(土)\\x05(日)\\x05(株)\\x05(有)\\x05(社)\\x05(名)\" +\n\t\"\\x05(特)\\x05(財)\\x05(祝)\\x05(労)\\x05(代)\\x05(呼)\\x05(学)\\x05(監)\\x05(企)\\x05(資)\" +\n\t\"\\x05(協)\\x05(祭)\\x05(休)\\x05(自)\\x05(至)\\x0221\\x0222\\x0223\\x0224\\x0225\\x0226\" +\n\t\"\\x0227\\x0228\\x0229\\x0230\\x0231\\x0232\\x0233\\x0234\\x0235\\x06참고\\x06주의\\x0236\" +\n\t\"\\x0237\\x0238\\x0239\\x0240\\x0241\\x0242\\x0243\\x0244\\x0245\\x0246\\x0247\\x0248\" +\n\t\"\\x0249\\x0250\\x041月\\x042月\\x043月\\x044月\\x045月\\x046月\\x047月\\x048月\\x049月\\x0510\" +\n\t\"月\\x0511月\\x0512月\\x02hg\\x02ev\\x0cアパート\\x0cアルファ\\x0cアンペア\\x09アール\\x0cイニング\\x09\" +\n\t\"インチ\\x09ウォン\\x0fエスクード\\x0cエーカー\\x09オンス\\x09オーム\\x09カイリ\\x0cカラット\\x0cカロリー\\x09ガロ\" +\n\t\"ン\\x09ガンマ\\x06ギガ\\x09ギニー\\x0cキュリー\\x0cギルダー\\x06キロ\\x0fキログラム\\x12キロメートル\\x0fキロワッ\" +\n\t\"ト\\x09グラム\\x0fグラムトン\\x0fクルゼイロ\\x0cクローネ\\x09ケース\\x09コルナ\\x09コーポ\\x0cサイクル\\x0fサンチ\" +\n\t\"ーム\\x0cシリング\\x09センチ\\x09セント\\x09ダース\\x06デシ\\x06ドル\\x06トン\\x06ナノ\\x09ノット\\x09ハイツ\" +\n\t\"\\x0fパーセント\\x09パーツ\\x0cバーレル\\x0fピアストル\\x09ピクル\\x06ピコ\\x06ビル\\x0fファラッド\\x0cフィート\" +\n\t\"\\x0fブッシェル\\x09フラン\\x0fヘクタール\\x06ペソ\\x09ペニヒ\\x09ヘルツ\\x09ペンス\\x09ページ\\x09ベータ\\x0cポイ\" +\n\t\"ント\\x09ボルト\\x06ホン\\x09ポンド\\x09ホール\\x09ホーン\\x0cマイクロ\\x09マイル\\x09マッハ\\x09マルク\\x0fマ\" +\n\t\"ンション\\x0cミクロン\\x06ミリ\\x0fミリバール\\x06メガ\\x0cメガトン\\x0cメートル\\x09ヤード\\x09ヤール\\x09ユアン\" +\n\t\"\\x0cリットル\\x06リラ\\x09ルピー\\x0cルーブル\\x06レム\\x0fレントゲン\\x09ワット\\x040点\\x041点\\x042点\" +\n\t\"\\x043点\\x044点\\x045点\\x046点\\x047点\\x048点\\x049点\\x0510点\\x0511点\\x0512点\\x0513点\" +\n\t\"\\x0514点\\x0515点\\x0516点\\x0517点\\x0518点\\x0519点\\x0520点\\x0521点\\x0522点\\x0523点\" +\n\t\"\\x0524点\\x02da\\x02au\\x02ov\\x02pc\\x02dm\\x02iu\\x06平成\\x06昭和\\x06大正\\x06明治\\x0c株\" +\n\t\"式会社\\x02pa\\x02na\\x02ma\\x02ka\\x02kb\\x02mb\\x02gb\\x04kcal\\x02pf\\x02nf\\x02m\" +\n\t\"g\\x02kg\\x02hz\\x02ml\\x02dl\\x02kl\\x02fm\\x02nm\\x02mm\\x02cm\\x02km\\x02m2\\x02m\" +\n\t\"3\\x05m∕s\\x06m∕s2\\x07rad∕s\\x08rad∕s2\\x02ps\\x02ns\\x02ms\\x02pv\\x02nv\\x02mv\" +\n\t\"\\x02kv\\x02pw\\x02nw\\x02mw\\x02kw\\x02bq\\x02cc\\x02cd\\x06c∕kg\\x02db\\x02gy\\x02\" +\n\t\"ha\\x02hp\\x02in\\x02kk\\x02kt\\x02lm\\x02ln\\x02lx\\x02ph\\x02pr\\x02sr\\x02sv\\x02\" +\n\t\"wb\\x05v∕m\\x05a∕m\\x041日\\x042日\\x043日\\x044日\\x045日\\x046日\\x047日\\x048日\\x049日\" +\n\t\"\\x0510日\\x0511日\\x0512日\\x0513日\\x0514日\\x0515日\\x0516日\\x0517日\\x0518日\\x0519日\" +\n\t\"\\x0520日\\x0521日\\x0522日\\x0523日\\x0524日\\x0525日\\x0526日\\x0527日\\x0528日\\x0529日\" +\n\t\"\\x0530日\\x0531日\\x02ь\\x02ɦ\\x02ɬ\\x02ʞ\\x02ʇ\\x02œ\\x04𤋮\\x04𢡊\\x04𢡄\\x04𣏕\\x04𥉉\" +\n\t\"\\x04𥳐\\x04𧻓\\x02ff\\x02fi\\x02fl\\x02st\\x04մն\\x04մե\\x04մի\\x04վն\\x04մխ\\x04יִ\" +\n\t\"\\x04ײַ\\x02ע\\x02ה\\x02כ\\x02ל\\x02ם\\x02ר\\x02ת\\x04שׁ\\x04שׂ\\x06שּׁ\\x06שּׂ\\x04א\" +\n\t\"ַ\\x04אָ\\x04אּ\\x04בּ\\x04גּ\\x04דּ\\x04הּ\\x04וּ\\x04זּ\\x04טּ\\x04יּ\\x04ךּ\\x04\" +\n\t\"כּ\\x04לּ\\x04מּ\\x04נּ\\x04סּ\\x04ףּ\\x04פּ\\x04צּ\\x04קּ\\x04רּ\\x04שּ\\x04תּ\" +\n\t\"\\x04וֹ\\x04בֿ\\x04כֿ\\x04פֿ\\x04אל\\x02ٱ\\x02ٻ\\x02پ\\x02ڀ\\x02ٺ\\x02ٿ\\x02ٹ\\x02ڤ\" +\n\t\"\\x02ڦ\\x02ڄ\\x02ڃ\\x02چ\\x02ڇ\\x02ڍ\\x02ڌ\\x02ڎ\\x02ڈ\\x02ژ\\x02ڑ\\x02ک\\x02گ\\x02ڳ\" +\n\t\"\\x02ڱ\\x02ں\\x02ڻ\\x02ۀ\\x02ہ\\x02ھ\\x02ے\\x02ۓ\\x02ڭ\\x02ۇ\\x02ۆ\\x02ۈ\\x02ۋ\\x02ۅ\" +\n\t\"\\x02ۉ\\x02ې\\x02ى\\x04ئا\\x04ئە\\x04ئو\\x04ئۇ\\x04ئۆ\\x04ئۈ\\x04ئې\\x04ئى\\x02ی\\x04\" +\n\t\"ئج\\x04ئح\\x04ئم\\x04ئي\\x04بج\\x04بح\\x04بخ\\x04بم\\x04بى\\x04بي\\x04تج\\x04تح\" +\n\t\"\\x04تخ\\x04تم\\x04تى\\x04تي\\x04ثج\\x04ثم\\x04ثى\\x04ثي\\x04جح\\x04جم\\x04حج\\x04حم\" +\n\t\"\\x04خج\\x04خح\\x04خم\\x04سج\\x04سح\\x04سخ\\x04سم\\x04صح\\x04صم\\x04ضج\\x04ضح\\x04ضخ\" +\n\t\"\\x04ضم\\x04طح\\x04طم\\x04ظم\\x04عج\\x04عم\\x04غج\\x04غم\\x04فج\\x04فح\\x04فخ\\x04فم\" +\n\t\"\\x04فى\\x04في\\x04قح\\x04قم\\x04قى\\x04قي\\x04كا\\x04كج\\x04كح\\x04كخ\\x04كل\\x04كم\" +\n\t\"\\x04كى\\x04كي\\x04لج\\x04لح\\x04لخ\\x04لم\\x04لى\\x04لي\\x04مج\\x04مح\\x04مخ\\x04مم\" +\n\t\"\\x04مى\\x04مي\\x04نج\\x04نح\\x04نخ\\x04نم\\x04نى\\x04ني\\x04هج\\x04هم\\x04هى\\x04هي\" +\n\t\"\\x04يج\\x04يح\\x04يخ\\x04يم\\x04يى\\x04يي\\x04ذٰ\\x04رٰ\\x04ىٰ\\x05 ٌّ\\x05 ٍّ\\x05\" +\n\t\" َّ\\x05 ُّ\\x05 ِّ\\x05 ّٰ\\x04ئر\\x04ئز\\x04ئن\\x04بر\\x04بز\\x04بن\\x04تر\\x04تز\" +\n\t\"\\x04تن\\x04ثر\\x04ثز\\x04ثن\\x04ما\\x04نر\\x04نز\\x04نن\\x04ير\\x04يز\\x04ين\\x04ئخ\" +\n\t\"\\x04ئه\\x04به\\x04ته\\x04صخ\\x04له\\x04نه\\x04هٰ\\x04يه\\x04ثه\\x04سه\\x04شم\\x04شه\" +\n\t\"\\x06ـَّ\\x06ـُّ\\x06ـِّ\\x04طى\\x04طي\\x04عى\\x04عي\\x04غى\\x04غي\\x04سى\\x04سي\" +\n\t\"\\x04شى\\x04شي\\x04حى\\x04حي\\x04جى\\x04جي\\x04خى\\x04خي\\x04صى\\x04صي\\x04ضى\\x04ضي\" +\n\t\"\\x04شج\\x04شح\\x04شخ\\x04شر\\x04سر\\x04صر\\x04ضر\\x04اً\\x06تجم\\x06تحج\\x06تحم\" +\n\t\"\\x06تخم\\x06تمج\\x06تمح\\x06تمخ\\x06جمح\\x06حمي\\x06حمى\\x06سحج\\x06سجح\\x06سجى\" +\n\t\"\\x06سمح\\x06سمج\\x06سمم\\x06صحح\\x06صمم\\x06شحم\\x06شجي\\x06شمخ\\x06شمم\\x06ضحى\" +\n\t\"\\x06ضخم\\x06طمح\\x06طمم\\x06طمي\\x06عجم\\x06عمم\\x06عمى\\x06غمم\\x06غمي\\x06غمى\" +\n\t\"\\x06فخم\\x06قمح\\x06قمم\\x06لحم\\x06لحي\\x06لحى\\x06لجج\\x06لخم\\x06لمح\\x06محج\" +\n\t\"\\x06محم\\x06محي\\x06مجح\\x06مجم\\x06مخج\\x06مخم\\x06مجخ\\x06همج\\x06همم\\x06نحم\" +\n\t\"\\x06نحى\\x06نجم\\x06نجى\\x06نمي\\x06نمى\\x06يمم\\x06بخي\\x06تجي\\x06تجى\\x06تخي\" +\n\t\"\\x06تخى\\x06تمي\\x06تمى\\x06جمي\\x06جحى\\x06جمى\\x06سخى\\x06صحي\\x06شحي\\x06ضحي\" +\n\t\"\\x06لجي\\x06لمي\\x06يحي\\x06يجي\\x06يمي\\x06ممي\\x06قمي\\x06نحي\\x06عمي\\x06كمي\" +\n\t\"\\x06نجح\\x06مخي\\x06لجم\\x06كمم\\x06جحي\\x06حجي\\x06مجي\\x06فمي\\x06بحي\\x06سخي\" +\n\t\"\\x06نجي\\x06صلے\\x06قلے\\x08الله\\x08اكبر\\x08محمد\\x08صلعم\\x08رسول\\x08عليه\" +\n\t\"\\x08وسلم\\x06صلى!صلى الله عليه وسلم\\x0fجل جلاله\\x08ریال\\x01,\\x01:\\x01!\" +\n\t\"\\x01?\\x01_\\x01{\\x01}\\x01[\\x01]\\x01#\\x01&\\x01*\\x01-\\x01<\\x01>\\x01\\\\\\x01$\" +\n\t\"\\x01%\\x01@\\x04ـً\\x04ـَ\\x04ـُ\\x04ـِ\\x04ـّ\\x04ـْ\\x02ء\\x02آ\\x02أ\\x02ؤ\\x02إ\" +\n\t\"\\x02ئ\\x02ا\\x02ب\\x02ة\\x02ت\\x02ث\\x02ج\\x02ح\\x02خ\\x02د\\x02ذ\\x02ر\\x02ز\\x02س\" +\n\t\"\\x02ش\\x02ص\\x02ض\\x02ط\\x02ظ\\x02ع\\x02غ\\x02ف\\x02ق\\x02ك\\x02ل\\x02م\\x02ن\\x02ه\" +\n\t\"\\x02و\\x02ي\\x04لآ\\x04لأ\\x04لإ\\x04لا\\x01\\x22\\x01'\\x01/\\x01^\\x01|\\x01~\\x02¢\" +\n\t\"\\x02£\\x02¬\\x02¦\\x02¥\\x08𝅗𝅥\\x08𝅘𝅥\\x0c𝅘𝅥𝅮\\x0c𝅘𝅥𝅯\\x0c𝅘𝅥𝅰\\x0c𝅘𝅥𝅱\\x0c𝅘𝅥𝅲\\x08𝆹\" +\n\t\"𝅥\\x08𝆺𝅥\\x0c𝆹𝅥𝅮\\x0c𝆺𝅥𝅮\\x0c𝆹𝅥𝅯\\x0c𝆺𝅥𝅯\\x02ı\\x02ȷ\\x02α\\x02ε\\x02ζ\\x02η\\x02\" +\n\t\"κ\\x02λ\\x02μ\\x02ν\\x02ξ\\x02ο\\x02σ\\x02τ\\x02υ\\x02ψ\\x03∇\\x03∂\\x02ϝ\\x02ٮ\\x02ڡ\" +\n\t\"\\x02ٯ\\x020,\\x021,\\x022,\\x023,\\x024,\\x025,\\x026,\\x027,\\x028,\\x029,\\x03(a)\" +\n\t\"\\x03(b)\\x03(c)\\x03(d)\\x03(e)\\x03(f)\\x03(g)\\x03(h)\\x03(i)\\x03(j)\\x03(k)\" +\n\t\"\\x03(l)\\x03(m)\\x03(n)\\x03(o)\\x03(p)\\x03(q)\\x03(r)\\x03(s)\\x03(t)\\x03(u)\" +\n\t\"\\x03(v)\\x03(w)\\x03(x)\\x03(y)\\x03(z)\\x07〔s〕\\x02wz\\x02hv\\x02sd\\x03ppv\\x02w\" +\n\t\"c\\x02mc\\x02md\\x02dj\\x06ほか\\x06ココ\\x03サ\\x03手\\x03字\\x03双\\x03デ\\x03二\\x03多\\x03解\" +\n\t\"\\x03天\\x03交\\x03映\\x03無\\x03料\\x03前\\x03後\\x03再\\x03新\\x03初\\x03終\\x03生\\x03販\\x03声\" +\n\t\"\\x03吹\\x03演\\x03投\\x03捕\\x03一\\x03三\\x03遊\\x03左\\x03中\\x03右\\x03指\\x03走\\x03打\\x03禁\" +\n\t\"\\x03空\\x03合\\x03満\\x03有\\x03月\\x03申\\x03割\\x03営\\x03配\\x09〔本〕\\x09〔三〕\\x09〔二〕\\x09〔安\" +\n\t\"〕\\x09〔点〕\\x09〔打〕\\x09〔盗〕\\x09〔勝〕\\x09〔敗〕\\x03得\\x03可\\x03丽\\x03丸\\x03乁\\x03你\\x03\" +\n\t\"侮\\x03侻\\x03倂\\x03偺\\x03備\\x03僧\\x03像\\x03㒞\\x03免\\x03兔\\x03兤\\x03具\\x03㒹\\x03內\\x03\" +\n\t\"冗\\x03冤\\x03仌\\x03冬\\x03况\\x03凵\\x03刃\\x03㓟\\x03刻\\x03剆\\x03剷\\x03㔕\\x03勇\\x03勉\\x03\" +\n\t\"勤\\x03勺\\x03包\\x03匆\\x03北\\x03卉\\x03卑\\x03博\\x03即\\x03卽\\x03卿\\x03灰\\x03及\\x03叟\\x03\" +\n\t\"叫\\x03叱\\x03吆\\x03咞\\x03吸\\x03呈\\x03周\\x03咢\\x03哶\\x03唐\\x03啓\\x03啣\\x03善\\x03喙\\x03\" +\n\t\"喫\\x03喳\\x03嗂\\x03圖\\x03嘆\\x03圗\\x03噑\\x03噴\\x03切\\x03壮\\x03城\\x03埴\\x03堍\\x03型\\x03\" +\n\t\"堲\\x03報\\x03墬\\x03売\\x03壷\\x03夆\\x03夢\\x03奢\\x03姬\\x03娛\\x03娧\\x03姘\\x03婦\\x03㛮\\x03\" +\n\t\"嬈\\x03嬾\\x03寃\\x03寘\\x03寧\\x03寳\\x03寿\\x03将\\x03尢\\x03㞁\\x03屠\\x03屮\\x03峀\\x03岍\\x03\" +\n\t\"嵃\\x03嵮\\x03嵫\\x03嵼\\x03巡\\x03巢\\x03㠯\\x03巽\\x03帨\\x03帽\\x03幩\\x03㡢\\x03㡼\\x03庰\\x03\" +\n\t\"庳\\x03庶\\x03廊\\x03廾\\x03舁\\x03弢\\x03㣇\\x03形\\x03彫\\x03㣣\\x03徚\\x03忍\\x03志\\x03忹\\x03\" +\n\t\"悁\\x03㤺\\x03㤜\\x03悔\\x03惇\\x03慈\\x03慌\\x03慎\\x03慺\\x03憎\\x03憲\\x03憤\\x03憯\\x03懞\\x03\" +\n\t\"懲\\x03懶\\x03成\\x03戛\\x03扝\\x03抱\\x03拔\\x03捐\\x03挽\\x03拼\\x03捨\\x03掃\\x03揤\\x03搢\\x03\" +\n\t\"揅\\x03掩\\x03㨮\\x03摩\\x03摾\\x03撝\\x03摷\\x03㩬\\x03敏\\x03敬\\x03旣\\x03書\\x03晉\\x03㬙\\x03\" +\n\t\"暑\\x03㬈\\x03㫤\\x03冒\\x03冕\\x03最\\x03暜\\x03肭\\x03䏙\\x03朗\\x03望\\x03朡\\x03杞\\x03杓\\x03\" +\n\t\"㭉\\x03柺\\x03枅\\x03桒\\x03梅\\x03梎\\x03栟\\x03椔\\x03㮝\\x03楂\\x03榣\\x03槪\\x03檨\\x03櫛\\x03\" +\n\t\"㰘\\x03次\\x03歔\\x03㱎\\x03歲\\x03殟\\x03殺\\x03殻\\x03汎\\x03沿\\x03泍\\x03汧\\x03洖\\x03派\\x03\" +\n\t\"海\\x03流\\x03浩\\x03浸\\x03涅\\x03洴\\x03港\\x03湮\\x03㴳\\x03滋\\x03滇\\x03淹\\x03潮\\x03濆\\x03\" +\n\t\"瀹\\x03瀞\\x03瀛\\x03㶖\\x03灊\\x03災\\x03灷\\x03炭\\x03煅\\x03熜\\x03爨\\x03爵\\x03牐\\x03犀\\x03\" +\n\t\"犕\\x03獺\\x03王\\x03㺬\\x03玥\\x03㺸\\x03瑇\\x03瑜\\x03瑱\\x03璅\\x03瓊\\x03㼛\\x03甤\\x03甾\\x03\" +\n\t\"異\\x03瘐\\x03㿼\\x03䀈\\x03直\\x03眞\\x03真\\x03睊\\x03䀹\\x03瞋\\x03䁆\\x03䂖\\x03硎\\x03碌\\x03\" +\n\t\"磌\\x03䃣\\x03祖\\x03福\\x03秫\\x03䄯\\x03穀\\x03穊\\x03穏\\x03䈂\\x03篆\\x03築\\x03䈧\\x03糒\\x03\" +\n\t\"䊠\\x03糨\\x03糣\\x03紀\\x03絣\\x03䌁\\x03緇\\x03縂\\x03繅\\x03䌴\\x03䍙\\x03罺\\x03羕\\x03翺\\x03\" +\n\t\"者\\x03聠\\x03聰\\x03䏕\\x03育\\x03脃\\x03䐋\\x03脾\\x03媵\\x03舄\\x03辞\\x03䑫\\x03芑\\x03芋\\x03\" +\n\t\"芝\\x03劳\\x03花\\x03芳\\x03芽\\x03苦\\x03若\\x03茝\\x03荣\\x03莭\\x03茣\\x03莽\\x03菧\\x03著\\x03\" +\n\t\"荓\\x03菊\\x03菌\\x03菜\\x03䔫\\x03蓱\\x03蓳\\x03蔖\\x03蕤\\x03䕝\\x03䕡\\x03䕫\\x03虐\\x03虜\\x03\" +\n\t\"虧\\x03虩\\x03蚩\\x03蚈\\x03蜎\\x03蛢\\x03蝹\\x03蜨\\x03蝫\\x03螆\\x03蟡\\x03蠁\\x03䗹\\x03衠\\x03\" +\n\t\"衣\\x03裗\\x03裞\\x03䘵\\x03裺\\x03㒻\\x03䚾\\x03䛇\\x03誠\\x03諭\\x03變\\x03豕\\x03貫\\x03賁\\x03\" +\n\t\"贛\\x03起\\x03跋\\x03趼\\x03跰\\x03軔\\x03輸\\x03邔\\x03郱\\x03鄑\\x03鄛\\x03鈸\\x03鋗\\x03鋘\\x03\" +\n\t\"鉼\\x03鏹\\x03鐕\\x03開\\x03䦕\\x03閷\\x03䧦\\x03雃\\x03嶲\\x03霣\\x03䩮\\x03䩶\\x03韠\\x03䪲\\x03\" +\n\t\"頋\\x03頩\\x03飢\\x03䬳\\x03餩\\x03馧\\x03駂\\x03駾\\x03䯎\\x03鬒\\x03鱀\\x03鳽\\x03䳎\\x03䳭\\x03\" +\n\t\"鵧\\x03䳸\\x03麻\\x03䵖\\x03黹\\x03黾\\x03鼅\\x03鼏\\x03鼖\\x03鼻\"\n\nvar xorData string = \"\" + // Size: 4855 bytes\n\t\"\\x02\\x0c\\x09\\x02\\xb0\\xec\\x02\\xad\\xd8\\x02\\xad\\xd9\\x02\\x06\\x07\\x02\\x0f\\x12\" +\n\t\"\\x02\\x0f\\x1f\\x02\\x0f\\x1d\\x02\\x01\\x13\\x02\\x0f\\x16\\x02\\x0f\\x0b\\x02\\x0f3\" +\n\t\"\\x02\\x0f7\\x02\\x0f?\\x02\\x0f/\\x02\\x0f*\\x02\\x0c&\\x02\\x0c*\\x02\\x0c;\\x02\\x0c9\" +\n\t\"\\x02\\x0c%\\x02\\xab\\xed\\x02\\xab\\xe2\\x02\\xab\\xe3\\x02\\xa9\\xe0\\x02\\xa9\\xe1\" +\n\t\"\\x02\\xa9\\xe6\\x02\\xa3\\xcb\\x02\\xa3\\xc8\\x02\\xa3\\xc9\\x02\\x01#\\x02\\x01\\x08\" +\n\t\"\\x02\\x0e>\\x02\\x0e'\\x02\\x0f\\x03\\x02\\x03\\x0d\\x02\\x03\\x09\\x02\\x03\\x17\\x02\" +\n\t\"\\x03\\x0e\\x02\\x02\\x03\\x02\\x011\\x02\\x01\\x00\\x02\\x01\\x10\\x02\\x03<\\x02\\x07\" +\n\t\"\\x0d\\x02\\x02\\x0c\\x02\\x0c0\\x02\\x01\\x03\\x02\\x01\\x01\\x02\\x01 \\x02\\x01\\x22\" +\n\t\"\\x02\\x01)\\x02\\x01\\x0a\\x02\\x01\\x0c\\x02\\x02\\x06\\x02\\x02\\x02\\x02\\x03\\x10\" +\n\t\"\\x03\\x037 \\x03\\x0b+\\x03\\x02\\x01\\x04\\x02\\x01\\x02\\x02\\x019\\x02\\x03\\x1c\\x02\" +\n\t\"\\x02$\\x03\\x80p$\\x02\\x03:\\x02\\x03\\x0a\\x03\\xc1r.\\x03\\xc1r,\\x03\\xc1r\\x02\" +\n\t\"\\x02\\x02:\\x02\\x02>\\x02\\x02,\\x02\\x02\\x10\\x02\\x02\\x00\\x03\\xc1s<\\x03\\xc1s*\" +\n\t\"\\x03\\xc2L$\\x03\\xc2L;\\x02\\x09)\\x02\\x0a\\x19\\x03\\x83\\xab\\xe3\\x03\\x83\\xab\" +\n\t\"\\xf2\\x03 4\\xe0\\x03\\x81\\xab\\xea\\x03\\x81\\xab\\xf3\\x03 4\\xef\\x03\\x96\\xe1\\xcd\" +\n\t\"\\x03\\x84\\xe5\\xc3\\x02\\x0d\\x11\\x03\\x8b\\xec\\xcb\\x03\\x94\\xec\\xcf\\x03\\x9a\\xec\" +\n\t\"\\xc2\\x03\\x8b\\xec\\xdb\\x03\\x94\\xec\\xdf\\x03\\x9a\\xec\\xd2\\x03\\x01\\x0c!\\x03\" +\n\t\"\\x01\\x0c#\\x03ʠ\\x9d\\x03ʣ\\x9c\\x03ʢ\\x9f\\x03ʥ\\x9e\\x03ʤ\\x91\\x03ʧ\\x90\\x03ʦ\\x93\" +\n\t\"\\x03ʩ\\x92\\x03ʨ\\x95\\x03\\xca\\xf3\\xb5\\x03\\xca\\xf0\\xb4\\x03\\xca\\xf1\\xb7\\x03\" +\n\t\"\\xca\\xf6\\xb6\\x03\\xca\\xf7\\x89\\x03\\xca\\xf4\\x88\\x03\\xca\\xf5\\x8b\\x03\\xca\\xfa\" +\n\t\"\\x8a\\x03\\xca\\xfb\\x8d\\x03\\xca\\xf8\\x8c\\x03\\xca\\xf9\\x8f\\x03\\xca\\xfe\\x8e\\x03\" +\n\t\"\\xca\\xff\\x81\\x03\\xca\\xfc\\x80\\x03\\xca\\xfd\\x83\\x03\\xca\\xe2\\x82\\x03\\xca\\xe3\" +\n\t\"\\x85\\x03\\xca\\xe0\\x84\\x03\\xca\\xe1\\x87\\x03\\xca\\xe6\\x86\\x03\\xca\\xe7\\x99\\x03\" +\n\t\"\\xca\\xe4\\x98\\x03\\xca\\xe5\\x9b\\x03\\xca\\xea\\x9a\\x03\\xca\\xeb\\x9d\\x03\\xca\\xe8\" +\n\t\"\\x9c\\x03ؓ\\x89\\x03ߔ\\x8b\\x02\\x010\\x03\\x03\\x04\\x1e\\x03\\x04\\x15\\x12\\x03\\x0b\" +\n\t\"\\x05,\\x03\\x06\\x04\\x00\\x03\\x06\\x04)\\x03\\x06\\x044\\x03\\x06\\x04<\\x03\\x06\\x05\" +\n\t\"\\x1d\\x03\\x06\\x06\\x00\\x03\\x06\\x06\\x0a\\x03\\x06\\x06'\\x03\\x06\\x062\\x03\\x0786\" +\n\t\"\\x03\\x079/\\x03\\x079 \\x03\\x07:\\x0e\\x03\\x07:\\x1b\\x03\\x07:%\\x03\\x07;/\\x03\" +\n\t\"\\x07;%\\x03\\x074\\x11\\x03\\x076\\x09\\x03\\x077*\\x03\\x070\\x01\\x03\\x070\\x0f\\x03\" +\n\t\"\\x070.\\x03\\x071\\x16\\x03\\x071\\x04\\x03\\x0710\\x03\\x072\\x18\\x03\\x072-\\x03\" +\n\t\"\\x073\\x14\\x03\\x073>\\x03\\x07'\\x09\\x03\\x07 \\x00\\x03\\x07\\x1f\\x0b\\x03\\x07\" +\n\t\"\\x18#\\x03\\x07\\x18(\\x03\\x07\\x186\\x03\\x07\\x18\\x03\\x03\\x07\\x19\\x16\\x03\\x07\" +\n\t\"\\x116\\x03\\x07\\x12'\\x03\\x07\\x13\\x10\\x03\\x07\\x0c&\\x03\\x07\\x0c\\x08\\x03\\x07\" +\n\t\"\\x0c\\x13\\x03\\x07\\x0d\\x02\\x03\\x07\\x0d\\x1c\\x03\\x07\\x0b5\\x03\\x07\\x0b\\x0a\" +\n\t\"\\x03\\x07\\x0b\\x01\\x03\\x07\\x0b\\x0f\\x03\\x07\\x05\\x00\\x03\\x07\\x05\\x09\\x03\\x07\" +\n\t\"\\x05\\x0b\\x03\\x07\\x07\\x01\\x03\\x07\\x07\\x08\\x03\\x07\\x00<\\x03\\x07\\x00+\\x03\" +\n\t\"\\x07\\x01)\\x03\\x07\\x01\\x1b\\x03\\x07\\x01\\x08\\x03\\x07\\x03?\\x03\\x0445\\x03\\x04\" +\n\t\"4\\x08\\x03\\x0454\\x03\\x04)/\\x03\\x04)5\\x03\\x04+\\x05\\x03\\x04+\\x14\\x03\\x04+ \" +\n\t\"\\x03\\x04+<\\x03\\x04*&\\x03\\x04*\\x22\\x03\\x04&8\\x03\\x04!\\x01\\x03\\x04!\\x22\" +\n\t\"\\x03\\x04\\x11+\\x03\\x04\\x10.\\x03\\x04\\x104\\x03\\x04\\x13=\\x03\\x04\\x12\\x04\\x03\" +\n\t\"\\x04\\x12\\x0a\\x03\\x04\\x0d\\x1d\\x03\\x04\\x0d\\x07\\x03\\x04\\x0d \\x03\\x05<>\\x03\" +\n\t\"\\x055<\\x03\\x055!\\x03\\x055#\\x03\\x055&\\x03\\x054\\x1d\\x03\\x054\\x02\\x03\\x054\" +\n\t\"\\x07\\x03\\x0571\\x03\\x053\\x1a\\x03\\x053\\x16\\x03\\x05.<\\x03\\x05.\\x07\\x03\\x05)\" +\n\t\":\\x03\\x05)<\\x03\\x05)\\x0c\\x03\\x05)\\x15\\x03\\x05+-\\x03\\x05+5\\x03\\x05$\\x1e\" +\n\t\"\\x03\\x05$\\x14\\x03\\x05'\\x04\\x03\\x05'\\x14\\x03\\x05&\\x02\\x03\\x05\\x226\\x03\" +\n\t\"\\x05\\x22\\x0c\\x03\\x05\\x22\\x1c\\x03\\x05\\x19\\x0a\\x03\\x05\\x1b\\x09\\x03\\x05\\x1b\" +\n\t\"\\x0c\\x03\\x05\\x14\\x07\\x03\\x05\\x16?\\x03\\x05\\x16\\x0c\\x03\\x05\\x0c\\x05\\x03\" +\n\t\"\\x05\\x0e\\x0f\\x03\\x05\\x01\\x0e\\x03\\x05\\x00(\\x03\\x05\\x030\\x03\\x05\\x03\\x06\" +\n\t\"\\x03\\x0a==\\x03\\x0a=1\\x03\\x0a=,\\x03\\x0a=\\x0c\\x03\\x0a??\\x03\\x0a<\\x08\\x03\" +\n\t\"\\x0a9!\\x03\\x0a9)\\x03\\x0a97\\x03\\x0a99\\x03\\x0a6\\x0a\\x03\\x0a6\\x1c\\x03\\x0a6\" +\n\t\"\\x17\\x03\\x0a7'\\x03\\x0a78\\x03\\x0a73\\x03\\x0a'\\x01\\x03\\x0a'&\\x03\\x0a\\x1f\" +\n\t\"\\x0e\\x03\\x0a\\x1f\\x03\\x03\\x0a\\x1f3\\x03\\x0a\\x1b/\\x03\\x0a\\x18\\x19\\x03\\x0a\" +\n\t\"\\x19\\x01\\x03\\x0a\\x16\\x14\\x03\\x0a\\x0e\\x22\\x03\\x0a\\x0f\\x10\\x03\\x0a\\x0f\\x02\" +\n\t\"\\x03\\x0a\\x0f \\x03\\x0a\\x0c\\x04\\x03\\x0a\\x0b>\\x03\\x0a\\x0b+\\x03\\x0a\\x08/\\x03\" +\n\t\"\\x0a\\x046\\x03\\x0a\\x05\\x14\\x03\\x0a\\x00\\x04\\x03\\x0a\\x00\\x10\\x03\\x0a\\x00\" +\n\t\"\\x14\\x03\\x0b<3\\x03\\x0b;*\\x03\\x0b9\\x22\\x03\\x0b9)\\x03\\x0b97\\x03\\x0b+\\x10\" +\n\t\"\\x03\\x0b((\\x03\\x0b&5\\x03\\x0b$\\x1c\\x03\\x0b$\\x12\\x03\\x0b%\\x04\\x03\\x0b#<\" +\n\t\"\\x03\\x0b#0\\x03\\x0b#\\x0d\\x03\\x0b#\\x19\\x03\\x0b!:\\x03\\x0b!\\x1f\\x03\\x0b!\\x00\" +\n\t\"\\x03\\x0b\\x1e5\\x03\\x0b\\x1c\\x1d\\x03\\x0b\\x1d-\\x03\\x0b\\x1d(\\x03\\x0b\\x18.\\x03\" +\n\t\"\\x0b\\x18 \\x03\\x0b\\x18\\x16\\x03\\x0b\\x14\\x13\\x03\\x0b\\x15$\\x03\\x0b\\x15\\x22\" +\n\t\"\\x03\\x0b\\x12\\x1b\\x03\\x0b\\x12\\x10\\x03\\x0b\\x132\\x03\\x0b\\x13=\\x03\\x0b\\x12\" +\n\t\"\\x18\\x03\\x0b\\x0c&\\x03\\x0b\\x061\\x03\\x0b\\x06:\\x03\\x0b\\x05#\\x03\\x0b\\x05<\" +\n\t\"\\x03\\x0b\\x04\\x0b\\x03\\x0b\\x04\\x04\\x03\\x0b\\x04\\x1b\\x03\\x0b\\x042\\x03\\x0b\" +\n\t\"\\x041\\x03\\x0b\\x03\\x03\\x03\\x0b\\x03\\x1d\\x03\\x0b\\x03/\\x03\\x0b\\x03+\\x03\\x0b\" +\n\t\"\\x02\\x1b\\x03\\x0b\\x02\\x00\\x03\\x0b\\x01\\x1e\\x03\\x0b\\x01\\x08\\x03\\x0b\\x015\" +\n\t\"\\x03\\x06\\x0d9\\x03\\x06\\x0d=\\x03\\x06\\x0d?\\x03\\x02\\x001\\x03\\x02\\x003\\x03\" +\n\t\"\\x02\\x02\\x19\\x03\\x02\\x006\\x03\\x02\\x02\\x1b\\x03\\x02\\x004\\x03\\x02\\x00<\\x03\" +\n\t\"\\x02\\x02\\x0a\\x03\\x02\\x02\\x0e\\x03\\x02\\x01\\x1a\\x03\\x02\\x01\\x07\\x03\\x02\\x01\" +\n\t\"\\x05\\x03\\x02\\x01\\x0b\\x03\\x02\\x01%\\x03\\x02\\x01\\x0c\\x03\\x02\\x01\\x04\\x03\" +\n\t\"\\x02\\x01\\x1c\\x03\\x02\\x00.\\x03\\x02\\x002\\x03\\x02\\x00>\\x03\\x02\\x00\\x12\\x03\" +\n\t\"\\x02\\x00\\x16\\x03\\x02\\x011\\x03\\x02\\x013\\x03\\x02\\x02 \\x03\\x02\\x02%\\x03\\x02\" +\n\t\"\\x02$\\x03\\x02\\x028\\x03\\x02\\x02;\\x03\\x02\\x024\\x03\\x02\\x012\\x03\\x02\\x022\" +\n\t\"\\x03\\x02\\x02/\\x03\\x02\\x01,\\x03\\x02\\x01\\x13\\x03\\x02\\x01\\x16\\x03\\x02\\x01\" +\n\t\"\\x11\\x03\\x02\\x01\\x1e\\x03\\x02\\x01\\x15\\x03\\x02\\x01\\x17\\x03\\x02\\x01\\x0f\\x03\" +\n\t\"\\x02\\x01\\x08\\x03\\x02\\x00?\\x03\\x02\\x03\\x07\\x03\\x02\\x03\\x0d\\x03\\x02\\x03\" +\n\t\"\\x13\\x03\\x02\\x03\\x1d\\x03\\x02\\x03\\x1f\\x03\\x02\\x00\\x03\\x03\\x02\\x00\\x0d\\x03\" +\n\t\"\\x02\\x00\\x01\\x03\\x02\\x00\\x1b\\x03\\x02\\x00\\x19\\x03\\x02\\x00\\x18\\x03\\x02\\x00\" +\n\t\"\\x13\\x03\\x02\\x00/\\x03\\x07>\\x12\\x03\\x07<\\x1f\\x03\\x07>\\x1d\\x03\\x06\\x1d\\x0e\" +\n\t\"\\x03\\x07>\\x1c\\x03\\x07>:\\x03\\x07>\\x13\\x03\\x04\\x12+\\x03\\x07?\\x03\\x03\\x07>\" +\n\t\"\\x02\\x03\\x06\\x224\\x03\\x06\\x1a.\\x03\\x07<%\\x03\\x06\\x1c\\x0b\\x03\\x0609\\x03\" +\n\t\"\\x05\\x1f\\x01\\x03\\x04'\\x08\\x03\\x93\\xfd\\xf5\\x03\\x02\\x0d \\x03\\x02\\x0d#\\x03\" +\n\t\"\\x02\\x0d!\\x03\\x02\\x0d&\\x03\\x02\\x0d\\x22\\x03\\x02\\x0d/\\x03\\x02\\x0d,\\x03\\x02\" +\n\t\"\\x0d$\\x03\\x02\\x0d'\\x03\\x02\\x0d%\\x03\\x02\\x0d;\\x03\\x02\\x0d=\\x03\\x02\\x0d?\" +\n\t\"\\x03\\x099.\\x03\\x08\\x0b7\\x03\\x08\\x02\\x14\\x03\\x08\\x14\\x0d\\x03\\x08.:\\x03\" +\n\t\"\\x089'\\x03\\x0f\\x0b\\x18\\x03\\x0f\\x1c1\\x03\\x0f\\x17&\\x03\\x0f9\\x1f\\x03\\x0f0\" +\n\t\"\\x0c\\x03\\x0e\\x0a9\\x03\\x0e\\x056\\x03\\x0e\\x1c#\\x03\\x0f\\x13\\x0e\\x03\\x072\\x00\" +\n\t\"\\x03\\x070\\x0d\\x03\\x072\\x0b\\x03\\x06\\x11\\x18\\x03\\x070\\x10\\x03\\x06\\x0f(\\x03\" +\n\t\"\\x072\\x05\\x03\\x06\\x0f,\\x03\\x073\\x15\\x03\\x06\\x07\\x08\\x03\\x05\\x16\\x02\\x03\" +\n\t\"\\x04\\x0b \\x03\\x05:8\\x03\\x05\\x16%\\x03\\x0a\\x0d\\x1f\\x03\\x06\\x16\\x10\\x03\\x05\" +\n\t\"\\x1d5\\x03\\x05*;\\x03\\x05\\x16\\x1b\\x03\\x04.-\\x03\\x06\\x1a\\x19\\x03\\x04\\x03,\" +\n\t\"\\x03\\x0b87\\x03\\x04/\\x0a\\x03\\x06\\x00,\\x03\\x04-\\x01\\x03\\x04\\x1e-\\x03\\x06/(\" +\n\t\"\\x03\\x0a\\x0b5\\x03\\x06\\x0e7\\x03\\x06\\x07.\\x03\\x0597\\x03\\x0a*%\\x03\\x0760\" +\n\t\"\\x03\\x06\\x0c;\\x03\\x05'\\x00\\x03\\x072.\\x03\\x072\\x08\\x03\\x06=\\x01\\x03\\x06\" +\n\t\"\\x05\\x1b\\x03\\x06\\x06\\x12\\x03\\x06$=\\x03\\x06'\\x0d\\x03\\x04\\x11\\x0f\\x03\\x076\" +\n\t\",\\x03\\x06\\x07;\\x03\\x06.,\\x03\\x86\\xf9\\xea\\x03\\x8f\\xff\\xeb\\x02\\x092\\x02\" +\n\t\"\\x095\\x02\\x094\\x02\\x09;\\x02\\x09>\\x02\\x098\\x02\\x09*\\x02\\x09/\\x02\\x09,\\x02\" +\n\t\"\\x09%\\x02\\x09&\\x02\\x09#\\x02\\x09 \\x02\\x08!\\x02\\x08%\\x02\\x08$\\x02\\x08+\\x02\" +\n\t\"\\x08.\\x02\\x08*\\x02\\x08&\\x02\\x088\\x02\\x08>\\x02\\x084\\x02\\x086\\x02\\x080\\x02\" +\n\t\"\\x08\\x10\\x02\\x08\\x17\\x02\\x08\\x12\\x02\\x08\\x1d\\x02\\x08\\x1f\\x02\\x08\\x13\\x02\" +\n\t\"\\x08\\x15\\x02\\x08\\x14\\x02\\x08\\x0c\\x03\\x8b\\xfd\\xd0\\x03\\x81\\xec\\xc6\\x03\\x87\" +\n\t\"\\xe0\\x8a\\x03-2\\xe3\\x03\\x80\\xef\\xe4\\x03-2\\xea\\x03\\x88\\xe6\\xeb\\x03\\x8e\\xe6\" +\n\t\"\\xe8\\x03\\x84\\xe6\\xe9\\x03\\x97\\xe6\\xee\\x03-2\\xf9\\x03-2\\xf6\\x03\\x8e\\xe3\\xad\" +\n\t\"\\x03\\x80\\xe3\\x92\\x03\\x88\\xe3\\x90\\x03\\x8e\\xe3\\x90\\x03\\x80\\xe3\\x97\\x03\\x88\" +\n\t\"\\xe3\\x95\\x03\\x88\\xfe\\xcb\\x03\\x8e\\xfe\\xca\\x03\\x84\\xfe\\xcd\\x03\\x91\\xef\\xc9\" +\n\t\"\\x03-2\\xc1\\x03-2\\xc0\\x03-2\\xcb\\x03\\x88@\\x09\\x03\\x8e@\\x08\\x03\\x8f\\xe0\\xf5\" +\n\t\"\\x03\\x8e\\xe6\\xf9\\x03\\x8e\\xe0\\xfa\\x03\\x93\\xff\\xf4\\x03\\x84\\xee\\xd3\\x03\\x0b\" +\n\t\"(\\x04\\x023 \\x021;\\x02\\x01*\\x03\\x0b#\\x10\\x03\\x0b 0\\x03\\x0b!\\x10\\x03\\x0b!0\" +\n\t\"\\x03\\x07\\x15\\x08\\x03\\x09?5\\x03\\x07\\x1f\\x08\\x03\\x07\\x17\\x0b\\x03\\x09\\x1f\" +\n\t\"\\x15\\x03\\x0b\\x1c7\\x03\\x0a+#\\x03\\x06\\x1a\\x1b\\x03\\x06\\x1a\\x14\\x03\\x0a\\x01\" +\n\t\"\\x18\\x03\\x06#\\x1b\\x03\\x0a2\\x0c\\x03\\x0a\\x01\\x04\\x03\\x09#;\\x03\\x08='\\x03\" +\n\t\"\\x08\\x1a\\x0a\\x03\\x07</\\x03\\x07:+\\x03\\x07\\x07*\\x03\\x06&\\x1c\\x03\\x09\\x0c\" +\n\t\"\\x16\\x03\\x09\\x10\\x0e\\x03\\x08'\\x0f\\x03\\x08+\\x09\\x03\\x074%\\x03\\x06!3\\x03\" +\n\t\"\\x06\\x03+\\x03\\x0b\\x1e\\x19\\x03\\x0a))\\x03\\x09\\x08\\x19\\x03\\x08,\\x05\\x03\\x07\" +\n\t\"<2\\x03\\x06\\x1c>\\x03\\x0a\\x111\\x03\\x09\\x1b\\x09\\x03\\x073.\\x03\\x07\\x01\\x00\" +\n\t\"\\x03\\x09/,\\x03\\x07#>\\x03\\x07\\x048\\x03\\x0a\\x1f\\x22\\x03\\x098>\\x03\\x09\\x11\" +\n\t\"\\x00\\x03\\x08/\\x17\\x03\\x06'\\x22\\x03\\x0b\\x1a+\\x03\\x0a\\x22\\x19\\x03\\x0a/1\" +\n\t\"\\x03\\x0974\\x03\\x09\\x0f\\x22\\x03\\x08,\\x22\\x03\\x08?\\x14\\x03\\x07$5\\x03\\x07<3\" +\n\t\"\\x03\\x07=*\\x03\\x07\\x13\\x18\\x03\\x068\\x0a\\x03\\x06\\x09\\x16\\x03\\x06\\x13\\x00\" +\n\t\"\\x03\\x08\\x067\\x03\\x08\\x01\\x03\\x03\\x08\\x12\\x1d\\x03\\x07+7\\x03\\x06(;\\x03\" +\n\t\"\\x06\\x1c?\\x03\\x07\\x0e\\x17\\x03\\x0a\\x06\\x1d\\x03\\x0a\\x19\\x07\\x03\\x08\\x14$\" +\n\t\"\\x03\\x07$;\\x03\\x08,$\\x03\\x08\\x06\\x0d\\x03\\x07\\x16\\x0a\\x03\\x06>>\\x03\\x0a\" +\n\t\"\\x06\\x12\\x03\\x0a\\x14)\\x03\\x09\\x0d\\x1f\\x03\\x09\\x12\\x17\\x03\\x09\\x19\\x01\" +\n\t\"\\x03\\x08\\x11 \\x03\\x08\\x1d'\\x03\\x06<\\x1a\\x03\\x0a.\\x00\\x03\\x07'\\x18\\x03\" +\n\t\"\\x0a\\x22\\x08\\x03\\x08\\x0d\\x0a\\x03\\x08\\x13)\\x03\\x07*)\\x03\\x06<,\\x03\\x07\" +\n\t\"\\x0b\\x1a\\x03\\x09.\\x14\\x03\\x09\\x0d\\x1e\\x03\\x07\\x0e#\\x03\\x0b\\x1d'\\x03\\x0a\" +\n\t\"\\x0a8\\x03\\x09%2\\x03\\x08+&\\x03\\x080\\x12\\x03\\x0a)4\\x03\\x08\\x06\\x1f\\x03\\x0b\" +\n\t\"\\x1b\\x1a\\x03\\x0a\\x1b\\x0f\\x03\\x0b\\x1d*\\x03\\x09\\x16$\\x03\\x090\\x11\\x03\\x08\" +\n\t\"\\x11\\x08\\x03\\x0a*(\\x03\\x0a\\x042\\x03\\x089,\\x03\\x074'\\x03\\x07\\x0f\\x05\\x03\" +\n\t\"\\x09\\x0b\\x0a\\x03\\x07\\x1b\\x01\\x03\\x09\\x17:\\x03\\x09.\\x0d\\x03\\x07.\\x11\\x03\" +\n\t\"\\x09+\\x15\\x03\\x080\\x13\\x03\\x0b\\x1f\\x19\\x03\\x0a \\x11\\x03\\x0a\\x220\\x03\\x09\" +\n\t\"\\x07;\\x03\\x08\\x16\\x1c\\x03\\x07,\\x13\\x03\\x07\\x0e/\\x03\\x06\\x221\\x03\\x0a.\" +\n\t\"\\x0a\\x03\\x0a7\\x02\\x03\\x0a\\x032\\x03\\x0a\\x1d.\\x03\\x091\\x06\\x03\\x09\\x19:\" +\n\t\"\\x03\\x08\\x02/\\x03\\x060+\\x03\\x06\\x0f-\\x03\\x06\\x1c\\x1f\\x03\\x06\\x1d\\x07\\x03\" +\n\t\"\\x0a,\\x11\\x03\\x09=\\x0d\\x03\\x09\\x0b;\\x03\\x07\\x1b/\\x03\\x0a\\x1f:\\x03\\x09 \" +\n\t\"\\x1f\\x03\\x09.\\x10\\x03\\x094\\x0b\\x03\\x09\\x1a1\\x03\\x08#\\x1a\\x03\\x084\\x1d\" +\n\t\"\\x03\\x08\\x01\\x1f\\x03\\x08\\x11\\x22\\x03\\x07'8\\x03\\x07\\x1a>\\x03\\x0757\\x03\" +\n\t\"\\x06&9\\x03\\x06+\\x11\\x03\\x0a.\\x0b\\x03\\x0a,>\\x03\\x0a4#\\x03\\x08%\\x17\\x03\" +\n\t\"\\x07\\x05\\x22\\x03\\x07\\x0c\\x0b\\x03\\x0a\\x1d+\\x03\\x0a\\x19\\x16\\x03\\x09+\\x1f\" +\n\t\"\\x03\\x09\\x08\\x0b\\x03\\x08\\x16\\x18\\x03\\x08+\\x12\\x03\\x0b\\x1d\\x0c\\x03\\x0a=\" +\n\t\"\\x10\\x03\\x0a\\x09\\x0d\\x03\\x0a\\x10\\x11\\x03\\x09&0\\x03\\x08(\\x1f\\x03\\x087\\x07\" +\n\t\"\\x03\\x08\\x185\\x03\\x07'6\\x03\\x06.\\x05\\x03\\x06=\\x04\\x03\\x06;;\\x03\\x06\\x06,\" +\n\t\"\\x03\\x0b\\x18>\\x03\\x08\\x00\\x18\\x03\\x06 \\x03\\x03\\x06<\\x00\\x03\\x09%\\x18\\x03\" +\n\t\"\\x0b\\x1c<\\x03\\x0a%!\\x03\\x0a\\x09\\x12\\x03\\x0a\\x16\\x02\\x03\\x090'\\x03\\x09\" +\n\t\"\\x0e=\\x03\\x08 \\x0e\\x03\\x08>\\x03\\x03\\x074>\\x03\\x06&?\\x03\\x06\\x19\\x09\\x03\" +\n\t\"\\x06?(\\x03\\x0a-\\x0e\\x03\\x09:3\\x03\\x098:\\x03\\x09\\x12\\x0b\\x03\\x09\\x1d\\x17\" +\n\t\"\\x03\\x087\\x05\\x03\\x082\\x14\\x03\\x08\\x06%\\x03\\x08\\x13\\x1f\\x03\\x06\\x06\\x0e\" +\n\t\"\\x03\\x0a\\x22<\\x03\\x09/<\\x03\\x06>+\\x03\\x0a'?\\x03\\x0a\\x13\\x0c\\x03\\x09\\x10<\" +\n\t\"\\x03\\x07\\x1b=\\x03\\x0a\\x19\\x13\\x03\\x09\\x22\\x1d\\x03\\x09\\x07\\x0d\\x03\\x08)\" +\n\t\"\\x1c\\x03\\x06=\\x1a\\x03\\x0a/4\\x03\\x0a7\\x11\\x03\\x0a\\x16:\\x03\\x09?3\\x03\\x09:\" +\n\t\"/\\x03\\x09\\x05\\x0a\\x03\\x09\\x14\\x06\\x03\\x087\\x22\\x03\\x080\\x07\\x03\\x08\\x1a\" +\n\t\"\\x1f\\x03\\x07\\x04(\\x03\\x07\\x04\\x09\\x03\\x06 %\\x03\\x06<\\x08\\x03\\x0a+\\x14\" +\n\t\"\\x03\\x09\\x1d\\x16\\x03\\x0a70\\x03\\x08 >\\x03\\x0857\\x03\\x070\\x0a\\x03\\x06=\\x12\" +\n\t\"\\x03\\x06\\x16%\\x03\\x06\\x1d,\\x03\\x099#\\x03\\x09\\x10>\\x03\\x07 \\x1e\\x03\\x08\" +\n\t\"\\x0c<\\x03\\x08\\x0b\\x18\\x03\\x08\\x15+\\x03\\x08,:\\x03\\x08%\\x22\\x03\\x07\\x0a$\" +\n\t\"\\x03\\x0b\\x1c=\\x03\\x07+\\x08\\x03\\x0a/\\x05\\x03\\x0a \\x07\\x03\\x0a\\x12'\\x03\" +\n\t\"\\x09#\\x11\\x03\\x08\\x1b\\x15\\x03\\x0a\\x06\\x01\\x03\\x09\\x1c\\x1b\\x03\\x0922\\x03\" +\n\t\"\\x07\\x14<\\x03\\x07\\x09\\x04\\x03\\x061\\x04\\x03\\x07\\x0e\\x01\\x03\\x0a\\x13\\x18\" +\n\t\"\\x03\\x0a-\\x0c\\x03\\x0a?\\x0d\\x03\\x0a\\x09\\x0a\\x03\\x091&\\x03\\x0a/\\x0b\\x03\" +\n\t\"\\x08$<\\x03\\x083\\x1d\\x03\\x08\\x0c$\\x03\\x08\\x0d\\x07\\x03\\x08\\x0d?\\x03\\x08\" +\n\t\"\\x0e\\x14\\x03\\x065\\x0a\\x03\\x08\\x1a#\\x03\\x08\\x16#\\x03\\x0702\\x03\\x07\\x03\" +\n\t\"\\x1a\\x03\\x06(\\x1d\\x03\\x06+\\x1b\\x03\\x06\\x0b\\x05\\x03\\x06\\x0b\\x17\\x03\\x06\" +\n\t\"\\x0c\\x04\\x03\\x06\\x1e\\x19\\x03\\x06+0\\x03\\x062\\x18\\x03\\x0b\\x16\\x1e\\x03\\x0a+\" +\n\t\"\\x16\\x03\\x0a-?\\x03\\x0a#:\\x03\\x0a#\\x10\\x03\\x0a%$\\x03\\x0a>+\\x03\\x0a01\\x03\" +\n\t\"\\x0a1\\x10\\x03\\x0a\\x099\\x03\\x0a\\x0a\\x12\\x03\\x0a\\x19\\x1f\\x03\\x0a\\x19\\x12\" +\n\t\"\\x03\\x09*)\\x03\\x09-\\x16\\x03\\x09.1\\x03\\x09.2\\x03\\x09<\\x0e\\x03\\x09> \\x03\" +\n\t\"\\x093\\x12\\x03\\x09\\x0b\\x01\\x03\\x09\\x1c2\\x03\\x09\\x11\\x1c\\x03\\x09\\x15%\\x03\" +\n\t\"\\x08,&\\x03\\x08!\\x22\\x03\\x089(\\x03\\x08\\x0b\\x1a\\x03\\x08\\x0d2\\x03\\x08\\x0c\" +\n\t\"\\x04\\x03\\x08\\x0c\\x06\\x03\\x08\\x0c\\x1f\\x03\\x08\\x0c\\x0c\\x03\\x08\\x0f\\x1f\\x03\" +\n\t\"\\x08\\x0f\\x1d\\x03\\x08\\x00\\x14\\x03\\x08\\x03\\x14\\x03\\x08\\x06\\x16\\x03\\x08\\x1e\" +\n\t\"#\\x03\\x08\\x11\\x11\\x03\\x08\\x10\\x18\\x03\\x08\\x14(\\x03\\x07)\\x1e\\x03\\x07.1\" +\n\t\"\\x03\\x07 $\\x03\\x07 '\\x03\\x078\\x08\\x03\\x07\\x0d0\\x03\\x07\\x0f7\\x03\\x07\\x05#\" +\n\t\"\\x03\\x07\\x05\\x1a\\x03\\x07\\x1a7\\x03\\x07\\x1d-\\x03\\x07\\x17\\x10\\x03\\x06)\\x1f\" +\n\t\"\\x03\\x062\\x0b\\x03\\x066\\x16\\x03\\x06\\x09\\x11\\x03\\x09(\\x1e\\x03\\x07!5\\x03\" +\n\t\"\\x0b\\x11\\x16\\x03\\x0a/\\x04\\x03\\x0a,\\x1a\\x03\\x0b\\x173\\x03\\x0a,1\\x03\\x0a/5\" +\n\t\"\\x03\\x0a\\x221\\x03\\x0a\\x22\\x0d\\x03\\x0a?%\\x03\\x0a<,\\x03\\x0a?#\\x03\\x0a>\\x19\" +\n\t\"\\x03\\x0a\\x08&\\x03\\x0a\\x0b\\x0e\\x03\\x0a\\x0c:\\x03\\x0a\\x0c+\\x03\\x0a\\x03\\x22\" +\n\t\"\\x03\\x0a\\x06)\\x03\\x0a\\x11\\x10\\x03\\x0a\\x11\\x1a\\x03\\x0a\\x17-\\x03\\x0a\\x14(\" +\n\t\"\\x03\\x09)\\x1e\\x03\\x09/\\x09\\x03\\x09.\\x00\\x03\\x09,\\x07\\x03\\x09/*\\x03\\x09-9\" +\n\t\"\\x03\\x09\\x228\\x03\\x09%\\x09\\x03\\x09:\\x12\\x03\\x09;\\x1d\\x03\\x09?\\x06\\x03\" +\n\t\"\\x093%\\x03\\x096\\x05\\x03\\x096\\x08\\x03\\x097\\x02\\x03\\x09\\x07,\\x03\\x09\\x04,\" +\n\t\"\\x03\\x09\\x1f\\x16\\x03\\x09\\x11\\x03\\x03\\x09\\x11\\x12\\x03\\x09\\x168\\x03\\x08*\" +\n\t\"\\x05\\x03\\x08/2\\x03\\x084:\\x03\\x08\\x22+\\x03\\x08 0\\x03\\x08&\\x0a\\x03\\x08;\" +\n\t\"\\x10\\x03\\x08>$\\x03\\x08>\\x18\\x03\\x0829\\x03\\x082:\\x03\\x081,\\x03\\x081<\\x03\" +\n\t\"\\x081\\x1c\\x03\\x087#\\x03\\x087*\\x03\\x08\\x09'\\x03\\x08\\x00\\x1d\\x03\\x08\\x05-\" +\n\t\"\\x03\\x08\\x1f4\\x03\\x08\\x1d\\x04\\x03\\x08\\x16\\x0f\\x03\\x07*7\\x03\\x07'!\\x03\" +\n\t\"\\x07%\\x1b\\x03\\x077\\x0c\\x03\\x07\\x0c1\\x03\\x07\\x0c.\\x03\\x07\\x00\\x06\\x03\\x07\" +\n\t\"\\x01\\x02\\x03\\x07\\x010\\x03\\x07\\x06=\\x03\\x07\\x01\\x03\\x03\\x07\\x01\\x13\\x03\" +\n\t\"\\x07\\x06\\x06\\x03\\x07\\x05\\x0a\\x03\\x07\\x1f\\x09\\x03\\x07\\x17:\\x03\\x06*1\\x03\" +\n\t\"\\x06-\\x1d\\x03\\x06\\x223\\x03\\x062:\\x03\\x060$\\x03\\x066\\x1e\\x03\\x064\\x12\\x03\" +\n\t\"\\x0645\\x03\\x06\\x0b\\x00\\x03\\x06\\x0b7\\x03\\x06\\x07\\x1f\\x03\\x06\\x15\\x12\\x03\" +\n\t\"\\x0c\\x05\\x0f\\x03\\x0b+\\x0b\\x03\\x0b+-\\x03\\x06\\x16\\x1b\\x03\\x06\\x15\\x17\\x03\" +\n\t\"\\x89\\xca\\xea\\x03\\x89\\xca\\xe8\\x03\\x0c8\\x10\\x03\\x0c8\\x01\\x03\\x0c8\\x0f\\x03\" +\n\t\"\\x0d8%\\x03\\x0d8!\\x03\\x0c8-\\x03\\x0c8/\\x03\\x0c8+\\x03\\x0c87\\x03\\x0c85\\x03\" +\n\t\"\\x0c9\\x09\\x03\\x0c9\\x0d\\x03\\x0c9\\x0f\\x03\\x0c9\\x0b\\x03\\xcfu\\x0c\\x03\\xcfu\" +\n\t\"\\x0f\\x03\\xcfu\\x0e\\x03\\xcfu\\x09\\x03\\x0c9\\x10\\x03\\x0d9\\x0c\\x03\\xcf`;\\x03\" +\n\t\"\\xcf`>\\x03\\xcf`9\\x03\\xcf`8\\x03\\xcf`7\\x03\\xcf`*\\x03\\xcf`-\\x03\\xcf`,\\x03\" +\n\t\"\\x0d\\x1b\\x1a\\x03\\x0d\\x1b&\\x03\\x0c=.\\x03\\x0c=%\\x03\\x0c>\\x1e\\x03\\x0c>\\x14\" +\n\t\"\\x03\\x0c?\\x06\\x03\\x0c?\\x0b\\x03\\x0c?\\x0c\\x03\\x0c?\\x0d\\x03\\x0c?\\x02\\x03\" +\n\t\"\\x0c>\\x0f\\x03\\x0c>\\x08\\x03\\x0c>\\x09\\x03\\x0c>,\\x03\\x0c>\\x0c\\x03\\x0c?\\x13\" +\n\t\"\\x03\\x0c?\\x16\\x03\\x0c?\\x15\\x03\\x0c?\\x1c\\x03\\x0c?\\x1f\\x03\\x0c?\\x1d\\x03\" +\n\t\"\\x0c?\\x1a\\x03\\x0c?\\x17\\x03\\x0c?\\x08\\x03\\x0c?\\x09\\x03\\x0c?\\x0e\\x03\\x0c?\" +\n\t\"\\x04\\x03\\x0c?\\x05\\x03\\x0c<?\\x03\\x0c=\\x00\\x03\\x0c=\\x06\\x03\\x0c=\\x05\\x03\" +\n\t\"\\x0c=\\x0c\\x03\\x0c=\\x0f\\x03\\x0c=\\x0d\\x03\\x0c=\\x0b\\x03\\x0c=\\x07\\x03\\x0c=\" +\n\t\"\\x19\\x03\\x0c=\\x15\\x03\\x0c=\\x11\\x03\\x0c=1\\x03\\x0c=3\\x03\\x0c=0\\x03\\x0c=>\" +\n\t\"\\x03\\x0c=2\\x03\\x0c=6\\x03\\x0c<\\x07\\x03\\x0c<\\x05\\x03\\x0e:!\\x03\\x0e:#\\x03\" +\n\t\"\\x0e8\\x09\\x03\\x0e:&\\x03\\x0e8\\x0b\\x03\\x0e:$\\x03\\x0e:,\\x03\\x0e8\\x1a\\x03\" +\n\t\"\\x0e8\\x1e\\x03\\x0e:*\\x03\\x0e:7\\x03\\x0e:5\\x03\\x0e:;\\x03\\x0e:\\x15\\x03\\x0e:<\" +\n\t\"\\x03\\x0e:4\\x03\\x0e:'\\x03\\x0e:-\\x03\\x0e:%\\x03\\x0e:?\\x03\\x0e:=\\x03\\x0e:)\" +\n\t\"\\x03\\x0e:/\\x03\\xcfs'\\x03\\x0d=\\x0f\\x03\\x0d+*\\x03\\x0d99\\x03\\x0d9;\\x03\\x0d9\" +\n\t\"?\\x03\\x0d)\\x0d\\x03\\x0d(%\\x02\\x01\\x18\\x02\\x01(\\x02\\x01\\x1e\\x03\\x0f$!\\x03\" +\n\t\"\\x0f87\\x03\\x0f4\\x0e\\x03\\x0f5\\x1d\\x03\\x06'\\x03\\x03\\x0f\\x08\\x18\\x03\\x0f\" +\n\t\"\\x0d\\x1b\\x03\\x0e2=\\x03\\x0e;\\x08\\x03\\x0e:\\x0b\\x03\\x0e\\x06$\\x03\\x0e\\x0d)\" +\n\t\"\\x03\\x0e\\x16\\x1f\\x03\\x0e\\x16\\x1b\\x03\\x0d$\\x0a\\x03\\x05,\\x1d\\x03\\x0d. \\x03\" +\n\t\"\\x0d.#\\x03\\x0c(/\\x03\\x09%\\x02\\x03\\x0d90\\x03\\x0d\\x0e4\\x03\\x0d\\x0d\\x0f\\x03\" +\n\t\"\\x0c#\\x00\\x03\\x0c,\\x1e\\x03\\x0c2\\x0e\\x03\\x0c\\x01\\x17\\x03\\x0c\\x09:\\x03\\x0e\" +\n\t\"\\x173\\x03\\x0c\\x08\\x03\\x03\\x0c\\x11\\x07\\x03\\x0c\\x10\\x18\\x03\\x0c\\x1f\\x1c\" +\n\t\"\\x03\\x0c\\x19\\x0e\\x03\\x0c\\x1a\\x1f\\x03\\x0f0>\\x03\\x0b->\\x03\\x0b<+\\x03\\x0b8\" +\n\t\"\\x13\\x03\\x0b\\x043\\x03\\x0b\\x14\\x03\\x03\\x0b\\x16%\\x03\\x0d\\x22&\\x03\\x0b\\x1a\" +\n\t\"\\x1a\\x03\\x0b\\x1a\\x04\\x03\\x0a%9\\x03\\x0a&2\\x03\\x0a&0\\x03\\x0a!\\x1a\\x03\\x0a!\" +\n\t\"7\\x03\\x0a5\\x10\\x03\\x0a=4\\x03\\x0a?\\x0e\\x03\\x0a>\\x10\\x03\\x0a\\x00 \\x03\\x0a\" +\n\t\"\\x0f:\\x03\\x0a\\x0f9\\x03\\x0a\\x0b\\x0a\\x03\\x0a\\x17%\\x03\\x0a\\x1b-\\x03\\x09-\" +\n\t\"\\x1a\\x03\\x09,4\\x03\\x09.,\\x03\\x09)\\x09\\x03\\x096!\\x03\\x091\\x1f\\x03\\x093\" +\n\t\"\\x16\\x03\\x0c+\\x1f\\x03\\x098 \\x03\\x098=\\x03\\x0c(\\x1a\\x03\\x0c(\\x16\\x03\\x09\" +\n\t\"\\x0a+\\x03\\x09\\x16\\x12\\x03\\x09\\x13\\x0e\\x03\\x09\\x153\\x03\\x08)!\\x03\\x09\\x1a\" +\n\t\"\\x01\\x03\\x09\\x18\\x01\\x03\\x08%#\\x03\\x08>\\x22\\x03\\x08\\x05%\\x03\\x08\\x02*\" +\n\t\"\\x03\\x08\\x15;\\x03\\x08\\x1b7\\x03\\x0f\\x07\\x1d\\x03\\x0f\\x04\\x03\\x03\\x070\\x0c\" +\n\t\"\\x03\\x07;\\x0b\\x03\\x07\\x08\\x17\\x03\\x07\\x12\\x06\\x03\\x06/-\\x03\\x0671\\x03\" +\n\t\"\\x065+\\x03\\x06>7\\x03\\x06\\x049\\x03\\x05+\\x1e\\x03\\x05,\\x17\\x03\\x05 \\x1d\\x03\" +\n\t\"\\x05\\x22\\x05\\x03\\x050\\x1d\"\n\n// lookup returns the trie value for the first UTF-8 encoding in s and\n// the width in bytes of this encoding. The size will be 0 if s does not\n// hold enough bytes to complete the encoding. len(s) must be greater than 0.\nfunc (t *idnaTrie) lookup(s []byte) (v uint16, sz int) {\n\tc0 := s[0]\n\tswitch {\n\tcase c0 < 0x80: // is ASCII\n\t\treturn idnaValues[c0], 1\n\tcase c0 < 0xC2:\n\t\treturn 0, 1 // Illegal UTF-8: not a starter, not ASCII.\n\tcase c0 < 0xE0: // 2-byte UTF-8\n\t\tif len(s) < 2 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c1), 2\n\tcase c0 < 0xF0: // 3-byte UTF-8\n\t\tif len(s) < 3 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c2), 3\n\tcase c0 < 0xF8: // 4-byte UTF-8\n\t\tif len(s) < 4 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to = uint32(i)<<6 + uint32(c2)\n\t\ti = idnaIndex[o]\n\t\tc3 := s[3]\n\t\tif c3 < 0x80 || 0xC0 <= c3 {\n\t\t\treturn 0, 3 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c3), 4\n\t}\n\t// Illegal rune\n\treturn 0, 1\n}\n\n// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.\n// s must start with a full and valid UTF-8 encoded rune.\nfunc (t *idnaTrie) lookupUnsafe(s []byte) uint16 {\n\tc0 := s[0]\n\tif c0 < 0x80 { // is ASCII\n\t\treturn idnaValues[c0]\n\t}\n\ti := idnaIndex[c0]\n\tif c0 < 0xE0 { // 2-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[1])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[1])]\n\tif c0 < 0xF0 { // 3-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[2])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[2])]\n\tif c0 < 0xF8 { // 4-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[3])\n\t}\n\treturn 0\n}\n\n// lookupString returns the trie value for the first UTF-8 encoding in s and\n// the width in bytes of this encoding. The size will be 0 if s does not\n// hold enough bytes to complete the encoding. len(s) must be greater than 0.\nfunc (t *idnaTrie) lookupString(s string) (v uint16, sz int) {\n\tc0 := s[0]\n\tswitch {\n\tcase c0 < 0x80: // is ASCII\n\t\treturn idnaValues[c0], 1\n\tcase c0 < 0xC2:\n\t\treturn 0, 1 // Illegal UTF-8: not a starter, not ASCII.\n\tcase c0 < 0xE0: // 2-byte UTF-8\n\t\tif len(s) < 2 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c1), 2\n\tcase c0 < 0xF0: // 3-byte UTF-8\n\t\tif len(s) < 3 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c2), 3\n\tcase c0 < 0xF8: // 4-byte UTF-8\n\t\tif len(s) < 4 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to = uint32(i)<<6 + uint32(c2)\n\t\ti = idnaIndex[o]\n\t\tc3 := s[3]\n\t\tif c3 < 0x80 || 0xC0 <= c3 {\n\t\t\treturn 0, 3 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c3), 4\n\t}\n\t// Illegal rune\n\treturn 0, 1\n}\n\n// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.\n// s must start with a full and valid UTF-8 encoded rune.\nfunc (t *idnaTrie) lookupStringUnsafe(s string) uint16 {\n\tc0 := s[0]\n\tif c0 < 0x80 { // is ASCII\n\t\treturn idnaValues[c0]\n\t}\n\ti := idnaIndex[c0]\n\tif c0 < 0xE0 { // 2-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[1])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[1])]\n\tif c0 < 0xF0 { // 3-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[2])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[2])]\n\tif c0 < 0xF8 { // 4-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[3])\n\t}\n\treturn 0\n}\n\n// idnaTrie. Total size: 29052 bytes (28.37 KiB). Checksum: ef06e7ecc26f36dd.\ntype idnaTrie struct{}\n\nfunc newIdnaTrie(i int) *idnaTrie {\n\treturn &idnaTrie{}\n}\n\n// lookupValue determines the type of block n and looks up the value for b.\nfunc (t *idnaTrie) lookupValue(n uint32, b byte) uint16 {\n\tswitch {\n\tcase n < 125:\n\t\treturn uint16(idnaValues[n<<6+uint32(b)])\n\tdefault:\n\t\tn -= 125\n\t\treturn uint16(idnaSparse.lookup(n, b))\n\t}\n}\n\n// idnaValues: 127 blocks, 8128 entries, 16256 bytes\n// The third block is the zero block.\nvar idnaValues = [8128]uint16{\n\t// Block 0x0, offset 0x0\n\t0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080,\n\t0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080,\n\t0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080,\n\t0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080,\n\t0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080,\n\t0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080,\n\t0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080,\n\t0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080,\n\t0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008,\n\t0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080,\n\t0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080,\n\t// Block 0x1, offset 0x40\n\t0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105,\n\t0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105,\n\t0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105,\n\t0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105,\n\t0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080,\n\t0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008,\n\t0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008,\n\t0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008,\n\t0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008,\n\t0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080,\n\t0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080,\n\t// Block 0x2, offset 0x80\n\t// Block 0x3, offset 0xc0\n\t0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040,\n\t0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040,\n\t0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040,\n\t0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040,\n\t0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040,\n\t0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018,\n\t0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x001a, 0xe9: 0x0018,\n\t0xea: 0x0039, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x004a,\n\t0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0069, 0xf3: 0x0079, 0xf4: 0x008a, 0xf5: 0x0005,\n\t0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x00aa, 0xf9: 0x00c9, 0xfa: 0x00d9, 0xfb: 0x0018,\n\t0xfc: 0x00e9, 0xfd: 0x0119, 0xfe: 0x0149, 0xff: 0x0018,\n\t// Block 0x4, offset 0x100\n\t0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008,\n\t0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008,\n\t0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008,\n\t0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008,\n\t0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008,\n\t0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008,\n\t0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008,\n\t0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008,\n\t0x130: 0x0179, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008,\n\t0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d,\n\t0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0199,\n\t// Block 0x5, offset 0x140\n\t0x140: 0x0199, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d,\n\t0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x01b9, 0x14a: 0xe00d, 0x14b: 0x0008,\n\t0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008,\n\t0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008,\n\t0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008,\n\t0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008,\n\t0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008,\n\t0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008,\n\t0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008,\n\t0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d,\n\t0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x01d9,\n\t// Block 0x6, offset 0x180\n\t0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008,\n\t0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d,\n\t0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d,\n\t0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d,\n\t0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155,\n\t0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008,\n\t0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d,\n\t0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd,\n\t0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d,\n\t0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008,\n\t0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008,\n\t// Block 0x7, offset 0x1c0\n\t0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x01e9, 0x1c5: 0x01e9,\n\t0x1c6: 0x01e9, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d,\n\t0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d,\n\t0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d,\n\t0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008,\n\t0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008,\n\t0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008,\n\t0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008,\n\t0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008,\n\t0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008,\n\t0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008,\n\t// Block 0x8, offset 0x200\n\t0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008,\n\t0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008,\n\t0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008,\n\t0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008,\n\t0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008,\n\t0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008,\n\t0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008,\n\t0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008,\n\t0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008,\n\t0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0209, 0x23b: 0xe03d,\n\t0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x0229, 0x23f: 0x0008,\n\t// Block 0x9, offset 0x240\n\t0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018,\n\t0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008,\n\t0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008,\n\t0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018,\n\t0x258: 0x029a, 0x259: 0x02ba, 0x25a: 0x02da, 0x25b: 0x02fa, 0x25c: 0x031a, 0x25d: 0x033a,\n\t0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0359, 0x262: 0x01d9, 0x263: 0x0369,\n\t0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018,\n\t0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018,\n\t0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018,\n\t0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018,\n\t0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018,\n\t// Block 0xa, offset 0x280\n\t0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d,\n\t0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308,\n\t0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308,\n\t0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308,\n\t0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308,\n\t0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308,\n\t0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308,\n\t0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308,\n\t0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008,\n\t0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008,\n\t0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d,\n\t// Block 0xb, offset 0x2c0\n\t0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x008a, 0x2c5: 0x03d2,\n\t0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040,\n\t0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105,\n\t0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105,\n\t0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105,\n\t0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d,\n\t0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d,\n\t0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008,\n\t0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008,\n\t0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008,\n\t0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008,\n\t// Block 0xc, offset 0x300\n\t0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008,\n\t0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008,\n\t0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd,\n\t0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008,\n\t0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008,\n\t0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008,\n\t0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008,\n\t0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008,\n\t0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd,\n\t0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008,\n\t0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d,\n\t// Block 0xd, offset 0x340\n\t0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008,\n\t0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008,\n\t0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008,\n\t0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008,\n\t0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008,\n\t0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008,\n\t0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008,\n\t0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008,\n\t0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008,\n\t0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008,\n\t0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008,\n\t// Block 0xe, offset 0x380\n\t0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308,\n\t0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008,\n\t0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008,\n\t0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008,\n\t0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008,\n\t0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008,\n\t0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008,\n\t0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008,\n\t0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008,\n\t0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008,\n\t0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008,\n\t// Block 0xf, offset 0x3c0\n\t0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d,\n\t0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d,\n\t0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008,\n\t0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008,\n\t0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008,\n\t0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008,\n\t0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008,\n\t0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008,\n\t0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008,\n\t0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008,\n\t0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008,\n\t// Block 0x10, offset 0x400\n\t0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008,\n\t0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008,\n\t0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008,\n\t0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008,\n\t0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008,\n\t0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008,\n\t0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008,\n\t0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008,\n\t0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5,\n\t0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5,\n\t0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5,\n\t// Block 0x11, offset 0x440\n\t0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840,\n\t0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818,\n\t0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308,\n\t0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308,\n\t0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040,\n\t0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08,\n\t0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08,\n\t0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08,\n\t0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08,\n\t0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08,\n\t0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08,\n\t// Block 0x12, offset 0x480\n\t0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08,\n\t0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308,\n\t0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308,\n\t0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308,\n\t0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308,\n\t0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808,\n\t0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808,\n\t0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08,\n\t0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0429,\n\t0x4b6: 0x0451, 0x4b7: 0x0479, 0x4b8: 0x04a1, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08,\n\t0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08,\n\t// Block 0x13, offset 0x4c0\n\t0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08,\n\t0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08,\n\t0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08,\n\t0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308,\n\t0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840,\n\t0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308,\n\t0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018,\n\t0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08,\n\t0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008,\n\t0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08,\n\t0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08,\n\t// Block 0x14, offset 0x500\n\t0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818,\n\t0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818,\n\t0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308,\n\t0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08,\n\t0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08,\n\t0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08,\n\t0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08,\n\t0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08,\n\t0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308,\n\t0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308,\n\t0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308,\n\t// Block 0x15, offset 0x540\n\t0x540: 0x0c08, 0x541: 0x0a08, 0x542: 0x0a08, 0x543: 0x0a08, 0x544: 0x0a08, 0x545: 0x0a08,\n\t0x546: 0x0c08, 0x547: 0x0c08, 0x548: 0x0a08, 0x549: 0x0c08, 0x54a: 0x0a08, 0x54b: 0x0a08,\n\t0x54c: 0x0a08, 0x54d: 0x0a08, 0x54e: 0x0a08, 0x54f: 0x0a08, 0x550: 0x0a08, 0x551: 0x0a08,\n\t0x552: 0x0a08, 0x553: 0x0a08, 0x554: 0x0c08, 0x555: 0x0a08, 0x556: 0x0808, 0x557: 0x0808,\n\t0x558: 0x0808, 0x559: 0x3308, 0x55a: 0x3308, 0x55b: 0x3308, 0x55c: 0x0040, 0x55d: 0x0040,\n\t0x55e: 0x0818, 0x55f: 0x0040, 0x560: 0x0a08, 0x561: 0x0808, 0x562: 0x0a08, 0x563: 0x0a08,\n\t0x564: 0x0a08, 0x565: 0x0a08, 0x566: 0x0808, 0x567: 0x0c08, 0x568: 0x0a08, 0x569: 0x0c08,\n\t0x56a: 0x0c08, 0x56b: 0x0040, 0x56c: 0x0040, 0x56d: 0x0040, 0x56e: 0x0040, 0x56f: 0x0040,\n\t0x570: 0x0040, 0x571: 0x0040, 0x572: 0x0040, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040,\n\t0x576: 0x0040, 0x577: 0x0040, 0x578: 0x0040, 0x579: 0x0040, 0x57a: 0x0040, 0x57b: 0x0040,\n\t0x57c: 0x0040, 0x57d: 0x0040, 0x57e: 0x0040, 0x57f: 0x0040,\n\t// Block 0x16, offset 0x580\n\t0x580: 0x3008, 0x581: 0x3308, 0x582: 0x3308, 0x583: 0x3308, 0x584: 0x3308, 0x585: 0x3308,\n\t0x586: 0x3308, 0x587: 0x3308, 0x588: 0x3308, 0x589: 0x3008, 0x58a: 0x3008, 0x58b: 0x3008,\n\t0x58c: 0x3008, 0x58d: 0x3b08, 0x58e: 0x3008, 0x58f: 0x3008, 0x590: 0x0008, 0x591: 0x3308,\n\t0x592: 0x3308, 0x593: 0x3308, 0x594: 0x3308, 0x595: 0x3308, 0x596: 0x3308, 0x597: 0x3308,\n\t0x598: 0x04c9, 0x599: 0x0501, 0x59a: 0x0539, 0x59b: 0x0571, 0x59c: 0x05a9, 0x59d: 0x05e1,\n\t0x59e: 0x0619, 0x59f: 0x0651, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x3308, 0x5a3: 0x3308,\n\t0x5a4: 0x0018, 0x5a5: 0x0018, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008,\n\t0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008,\n\t0x5b0: 0x0018, 0x5b1: 0x0008, 0x5b2: 0x0008, 0x5b3: 0x0008, 0x5b4: 0x0008, 0x5b5: 0x0008,\n\t0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0008, 0x5bb: 0x0008,\n\t0x5bc: 0x0008, 0x5bd: 0x0008, 0x5be: 0x0008, 0x5bf: 0x0008,\n\t// Block 0x17, offset 0x5c0\n\t0x5c0: 0x0008, 0x5c1: 0x3308, 0x5c2: 0x3008, 0x5c3: 0x3008, 0x5c4: 0x0040, 0x5c5: 0x0008,\n\t0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0008,\n\t0x5cc: 0x0008, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040,\n\t0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008,\n\t0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008,\n\t0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008,\n\t0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040,\n\t0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008,\n\t0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0040, 0x5f4: 0x0040, 0x5f5: 0x0040,\n\t0x5f6: 0x0008, 0x5f7: 0x0008, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040,\n\t0x5fc: 0x3308, 0x5fd: 0x0008, 0x5fe: 0x3008, 0x5ff: 0x3008,\n\t// Block 0x18, offset 0x600\n\t0x600: 0x3008, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3308, 0x604: 0x3308, 0x605: 0x0040,\n\t0x606: 0x0040, 0x607: 0x3008, 0x608: 0x3008, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x3008,\n\t0x60c: 0x3008, 0x60d: 0x3b08, 0x60e: 0x0008, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x0040,\n\t0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x3008,\n\t0x618: 0x0040, 0x619: 0x0040, 0x61a: 0x0040, 0x61b: 0x0040, 0x61c: 0x0689, 0x61d: 0x06c1,\n\t0x61e: 0x0040, 0x61f: 0x06f9, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x3308, 0x623: 0x3308,\n\t0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008,\n\t0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008,\n\t0x630: 0x0008, 0x631: 0x0008, 0x632: 0x0018, 0x633: 0x0018, 0x634: 0x0018, 0x635: 0x0018,\n\t0x636: 0x0018, 0x637: 0x0018, 0x638: 0x0018, 0x639: 0x0018, 0x63a: 0x0018, 0x63b: 0x0018,\n\t0x63c: 0x0008, 0x63d: 0x0018, 0x63e: 0x0040, 0x63f: 0x0040,\n\t// Block 0x19, offset 0x640\n\t0x640: 0x0040, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x3008, 0x644: 0x0040, 0x645: 0x0008,\n\t0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0040,\n\t0x64c: 0x0040, 0x64d: 0x0040, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0040,\n\t0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008,\n\t0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008,\n\t0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008,\n\t0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040,\n\t0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008,\n\t0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0731, 0x674: 0x0040, 0x675: 0x0008,\n\t0x676: 0x0769, 0x677: 0x0040, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040,\n\t0x67c: 0x3308, 0x67d: 0x0040, 0x67e: 0x3008, 0x67f: 0x3008,\n\t// Block 0x1a, offset 0x680\n\t0x680: 0x3008, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x0040, 0x684: 0x0040, 0x685: 0x0040,\n\t0x686: 0x0040, 0x687: 0x3308, 0x688: 0x3308, 0x689: 0x0040, 0x68a: 0x0040, 0x68b: 0x3308,\n\t0x68c: 0x3308, 0x68d: 0x3b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0040, 0x691: 0x3308,\n\t0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040,\n\t0x698: 0x0040, 0x699: 0x07a1, 0x69a: 0x07d9, 0x69b: 0x0811, 0x69c: 0x0008, 0x69d: 0x0040,\n\t0x69e: 0x0849, 0x69f: 0x0040, 0x6a0: 0x0040, 0x6a1: 0x0040, 0x6a2: 0x0040, 0x6a3: 0x0040,\n\t0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008,\n\t0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008,\n\t0x6b0: 0x3308, 0x6b1: 0x3308, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0008, 0x6b5: 0x3308,\n\t0x6b6: 0x0040, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0040, 0x6ba: 0x0040, 0x6bb: 0x0040,\n\t0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040,\n\t// Block 0x1b, offset 0x6c0\n\t0x6c0: 0x0040, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3008, 0x6c4: 0x0040, 0x6c5: 0x0008,\n\t0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008,\n\t0x6cc: 0x0008, 0x6cd: 0x0008, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0008,\n\t0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008,\n\t0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008,\n\t0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008,\n\t0x6e4: 0x0008, 0x6e5: 0x0008, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0040,\n\t0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008,\n\t0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008,\n\t0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040,\n\t0x6fc: 0x3308, 0x6fd: 0x0008, 0x6fe: 0x3008, 0x6ff: 0x3008,\n\t// Block 0x1c, offset 0x700\n\t0x700: 0x3008, 0x701: 0x3308, 0x702: 0x3308, 0x703: 0x3308, 0x704: 0x3308, 0x705: 0x3308,\n\t0x706: 0x0040, 0x707: 0x3308, 0x708: 0x3308, 0x709: 0x3008, 0x70a: 0x0040, 0x70b: 0x3008,\n\t0x70c: 0x3008, 0x70d: 0x3b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0008, 0x711: 0x0040,\n\t0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x0040, 0x717: 0x0040,\n\t0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0040, 0x71d: 0x0040,\n\t0x71e: 0x0040, 0x71f: 0x0040, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x3308, 0x723: 0x3308,\n\t0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008,\n\t0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008,\n\t0x730: 0x0018, 0x731: 0x0018, 0x732: 0x0040, 0x733: 0x0040, 0x734: 0x0040, 0x735: 0x0040,\n\t0x736: 0x0040, 0x737: 0x0040, 0x738: 0x0040, 0x739: 0x0008, 0x73a: 0x3308, 0x73b: 0x3308,\n\t0x73c: 0x3308, 0x73d: 0x3308, 0x73e: 0x3308, 0x73f: 0x3308,\n\t// Block 0x1d, offset 0x740\n\t0x740: 0x0040, 0x741: 0x3308, 0x742: 0x3008, 0x743: 0x3008, 0x744: 0x0040, 0x745: 0x0008,\n\t0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0008,\n\t0x74c: 0x0008, 0x74d: 0x0040, 0x74e: 0x0040, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040,\n\t0x752: 0x0040, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0008, 0x757: 0x0008,\n\t0x758: 0x0008, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0008, 0x75c: 0x0008, 0x75d: 0x0008,\n\t0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x0008, 0x763: 0x0008,\n\t0x764: 0x0008, 0x765: 0x0008, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0040,\n\t0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008,\n\t0x770: 0x0008, 0x771: 0x0040, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0040, 0x775: 0x0008,\n\t0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040,\n\t0x77c: 0x3308, 0x77d: 0x0008, 0x77e: 0x3008, 0x77f: 0x3308,\n\t// Block 0x1e, offset 0x780\n\t0x780: 0x3008, 0x781: 0x3308, 0x782: 0x3308, 0x783: 0x3308, 0x784: 0x3308, 0x785: 0x0040,\n\t0x786: 0x0040, 0x787: 0x3008, 0x788: 0x3008, 0x789: 0x0040, 0x78a: 0x0040, 0x78b: 0x3008,\n\t0x78c: 0x3008, 0x78d: 0x3b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040,\n\t0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x0040, 0x796: 0x3308, 0x797: 0x3008,\n\t0x798: 0x0040, 0x799: 0x0040, 0x79a: 0x0040, 0x79b: 0x0040, 0x79c: 0x0881, 0x79d: 0x08b9,\n\t0x79e: 0x0040, 0x79f: 0x0008, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x3308, 0x7a3: 0x3308,\n\t0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008,\n\t0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008,\n\t0x7b0: 0x0018, 0x7b1: 0x0008, 0x7b2: 0x0018, 0x7b3: 0x0018, 0x7b4: 0x0018, 0x7b5: 0x0018,\n\t0x7b6: 0x0018, 0x7b7: 0x0018, 0x7b8: 0x0040, 0x7b9: 0x0040, 0x7ba: 0x0040, 0x7bb: 0x0040,\n\t0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x0040, 0x7bf: 0x0040,\n\t// Block 0x1f, offset 0x7c0\n\t0x7c0: 0x0040, 0x7c1: 0x0040, 0x7c2: 0x3308, 0x7c3: 0x0008, 0x7c4: 0x0040, 0x7c5: 0x0008,\n\t0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0040,\n\t0x7cc: 0x0040, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040,\n\t0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0040, 0x7d7: 0x0040,\n\t0x7d8: 0x0040, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0008, 0x7dd: 0x0040,\n\t0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0040, 0x7e1: 0x0040, 0x7e2: 0x0040, 0x7e3: 0x0008,\n\t0x7e4: 0x0008, 0x7e5: 0x0040, 0x7e6: 0x0040, 0x7e7: 0x0040, 0x7e8: 0x0008, 0x7e9: 0x0008,\n\t0x7ea: 0x0008, 0x7eb: 0x0040, 0x7ec: 0x0040, 0x7ed: 0x0040, 0x7ee: 0x0008, 0x7ef: 0x0008,\n\t0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0008, 0x7f5: 0x0008,\n\t0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040,\n\t0x7fc: 0x0040, 0x7fd: 0x0040, 0x7fe: 0x3008, 0x7ff: 0x3008,\n\t// Block 0x20, offset 0x800\n\t0x800: 0x3308, 0x801: 0x3008, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x3008, 0x805: 0x0040,\n\t0x806: 0x3308, 0x807: 0x3308, 0x808: 0x3308, 0x809: 0x0040, 0x80a: 0x3308, 0x80b: 0x3308,\n\t0x80c: 0x3308, 0x80d: 0x3b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040,\n\t0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x3308, 0x816: 0x3308, 0x817: 0x0040,\n\t0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040,\n\t0x81e: 0x0040, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x3308, 0x823: 0x3308,\n\t0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008,\n\t0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008,\n\t0x830: 0x0040, 0x831: 0x0040, 0x832: 0x0040, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040,\n\t0x836: 0x0040, 0x837: 0x0040, 0x838: 0x0018, 0x839: 0x0018, 0x83a: 0x0018, 0x83b: 0x0018,\n\t0x83c: 0x0018, 0x83d: 0x0018, 0x83e: 0x0018, 0x83f: 0x0018,\n\t// Block 0x21, offset 0x840\n\t0x840: 0x0008, 0x841: 0x3308, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x0040, 0x845: 0x0008,\n\t0x846: 0x0008, 0x847: 0x0008, 0x848: 0x0008, 0x849: 0x0008, 0x84a: 0x0008, 0x84b: 0x0008,\n\t0x84c: 0x0008, 0x84d: 0x0040, 0x84e: 0x0008, 0x84f: 0x0008, 0x850: 0x0008, 0x851: 0x0040,\n\t0x852: 0x0008, 0x853: 0x0008, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x0008,\n\t0x858: 0x0008, 0x859: 0x0008, 0x85a: 0x0008, 0x85b: 0x0008, 0x85c: 0x0008, 0x85d: 0x0008,\n\t0x85e: 0x0008, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x0008, 0x863: 0x0008,\n\t0x864: 0x0008, 0x865: 0x0008, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0040,\n\t0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008,\n\t0x870: 0x0008, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0008, 0x874: 0x0040, 0x875: 0x0008,\n\t0x876: 0x0008, 0x877: 0x0008, 0x878: 0x0008, 0x879: 0x0008, 0x87a: 0x0040, 0x87b: 0x0040,\n\t0x87c: 0x3308, 0x87d: 0x0008, 0x87e: 0x3008, 0x87f: 0x3308,\n\t// Block 0x22, offset 0x880\n\t0x880: 0x3008, 0x881: 0x3008, 0x882: 0x3008, 0x883: 0x3008, 0x884: 0x3008, 0x885: 0x0040,\n\t0x886: 0x3308, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008,\n\t0x88c: 0x3308, 0x88d: 0x3b08, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040,\n\t0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0040, 0x895: 0x3008, 0x896: 0x3008, 0x897: 0x0040,\n\t0x898: 0x0040, 0x899: 0x0040, 0x89a: 0x0040, 0x89b: 0x0040, 0x89c: 0x0040, 0x89d: 0x0040,\n\t0x89e: 0x0008, 0x89f: 0x0040, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308,\n\t0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008,\n\t0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008,\n\t0x8b0: 0x0040, 0x8b1: 0x0008, 0x8b2: 0x0008, 0x8b3: 0x0040, 0x8b4: 0x0040, 0x8b5: 0x0040,\n\t0x8b6: 0x0040, 0x8b7: 0x0040, 0x8b8: 0x0040, 0x8b9: 0x0040, 0x8ba: 0x0040, 0x8bb: 0x0040,\n\t0x8bc: 0x0040, 0x8bd: 0x0040, 0x8be: 0x0040, 0x8bf: 0x0040,\n\t// Block 0x23, offset 0x8c0\n\t0x8c0: 0x3008, 0x8c1: 0x3308, 0x8c2: 0x3308, 0x8c3: 0x3308, 0x8c4: 0x3308, 0x8c5: 0x0040,\n\t0x8c6: 0x3008, 0x8c7: 0x3008, 0x8c8: 0x3008, 0x8c9: 0x0040, 0x8ca: 0x3008, 0x8cb: 0x3008,\n\t0x8cc: 0x3008, 0x8cd: 0x3b08, 0x8ce: 0x0008, 0x8cf: 0x0018, 0x8d0: 0x0040, 0x8d1: 0x0040,\n\t0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x3008,\n\t0x8d8: 0x0018, 0x8d9: 0x0018, 0x8da: 0x0018, 0x8db: 0x0018, 0x8dc: 0x0018, 0x8dd: 0x0018,\n\t0x8de: 0x0018, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x3308, 0x8e3: 0x3308,\n\t0x8e4: 0x0040, 0x8e5: 0x0040, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0008,\n\t0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008,\n\t0x8f0: 0x0018, 0x8f1: 0x0018, 0x8f2: 0x0018, 0x8f3: 0x0018, 0x8f4: 0x0018, 0x8f5: 0x0018,\n\t0x8f6: 0x0018, 0x8f7: 0x0018, 0x8f8: 0x0018, 0x8f9: 0x0018, 0x8fa: 0x0008, 0x8fb: 0x0008,\n\t0x8fc: 0x0008, 0x8fd: 0x0008, 0x8fe: 0x0008, 0x8ff: 0x0008,\n\t// Block 0x24, offset 0x900\n\t0x900: 0x0040, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x0040, 0x904: 0x0008, 0x905: 0x0040,\n\t0x906: 0x0040, 0x907: 0x0008, 0x908: 0x0008, 0x909: 0x0040, 0x90a: 0x0008, 0x90b: 0x0040,\n\t0x90c: 0x0040, 0x90d: 0x0008, 0x90e: 0x0040, 0x90f: 0x0040, 0x910: 0x0040, 0x911: 0x0040,\n\t0x912: 0x0040, 0x913: 0x0040, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0008,\n\t0x918: 0x0040, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0008, 0x91d: 0x0008,\n\t0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0040, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008,\n\t0x924: 0x0040, 0x925: 0x0008, 0x926: 0x0040, 0x927: 0x0008, 0x928: 0x0040, 0x929: 0x0040,\n\t0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0040, 0x92d: 0x0008, 0x92e: 0x0008, 0x92f: 0x0008,\n\t0x930: 0x0008, 0x931: 0x3308, 0x932: 0x0008, 0x933: 0x0929, 0x934: 0x3308, 0x935: 0x3308,\n\t0x936: 0x3308, 0x937: 0x3308, 0x938: 0x3308, 0x939: 0x3308, 0x93a: 0x0040, 0x93b: 0x3308,\n\t0x93c: 0x3308, 0x93d: 0x0008, 0x93e: 0x0040, 0x93f: 0x0040,\n\t// Block 0x25, offset 0x940\n\t0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x09d1, 0x944: 0x0008, 0x945: 0x0008,\n\t0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0040, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008,\n\t0x94c: 0x0008, 0x94d: 0x0a09, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008,\n\t0x952: 0x0a41, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0a79,\n\t0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0ab1, 0x95d: 0x0008,\n\t0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008,\n\t0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0ae9,\n\t0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0008, 0x96d: 0x0040, 0x96e: 0x0040, 0x96f: 0x0040,\n\t0x970: 0x0040, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x0b21, 0x974: 0x3308, 0x975: 0x0b59,\n\t0x976: 0x0b91, 0x977: 0x0bc9, 0x978: 0x0c19, 0x979: 0x0c51, 0x97a: 0x3308, 0x97b: 0x3308,\n\t0x97c: 0x3308, 0x97d: 0x3308, 0x97e: 0x3308, 0x97f: 0x3008,\n\t// Block 0x26, offset 0x980\n\t0x980: 0x3308, 0x981: 0x0ca1, 0x982: 0x3308, 0x983: 0x3308, 0x984: 0x3b08, 0x985: 0x0018,\n\t0x986: 0x3308, 0x987: 0x3308, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008,\n\t0x98c: 0x0008, 0x98d: 0x3308, 0x98e: 0x3308, 0x98f: 0x3308, 0x990: 0x3308, 0x991: 0x3308,\n\t0x992: 0x3308, 0x993: 0x0cd9, 0x994: 0x3308, 0x995: 0x3308, 0x996: 0x3308, 0x997: 0x3308,\n\t0x998: 0x0040, 0x999: 0x3308, 0x99a: 0x3308, 0x99b: 0x3308, 0x99c: 0x3308, 0x99d: 0x0d11,\n\t0x99e: 0x3308, 0x99f: 0x3308, 0x9a0: 0x3308, 0x9a1: 0x3308, 0x9a2: 0x0d49, 0x9a3: 0x3308,\n\t0x9a4: 0x3308, 0x9a5: 0x3308, 0x9a6: 0x3308, 0x9a7: 0x0d81, 0x9a8: 0x3308, 0x9a9: 0x3308,\n\t0x9aa: 0x3308, 0x9ab: 0x3308, 0x9ac: 0x0db9, 0x9ad: 0x3308, 0x9ae: 0x3308, 0x9af: 0x3308,\n\t0x9b0: 0x3308, 0x9b1: 0x3308, 0x9b2: 0x3308, 0x9b3: 0x3308, 0x9b4: 0x3308, 0x9b5: 0x3308,\n\t0x9b6: 0x3308, 0x9b7: 0x3308, 0x9b8: 0x3308, 0x9b9: 0x0df1, 0x9ba: 0x3308, 0x9bb: 0x3308,\n\t0x9bc: 0x3308, 0x9bd: 0x0040, 0x9be: 0x0018, 0x9bf: 0x0018,\n\t// Block 0x27, offset 0x9c0\n\t0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008,\n\t0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008,\n\t0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008,\n\t0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008,\n\t0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x0008, 0x9dc: 0x0008, 0x9dd: 0x0008,\n\t0x9de: 0x0008, 0x9df: 0x0008, 0x9e0: 0x0008, 0x9e1: 0x0008, 0x9e2: 0x0008, 0x9e3: 0x0008,\n\t0x9e4: 0x0008, 0x9e5: 0x0008, 0x9e6: 0x0008, 0x9e7: 0x0008, 0x9e8: 0x0008, 0x9e9: 0x0008,\n\t0x9ea: 0x0008, 0x9eb: 0x0008, 0x9ec: 0x0039, 0x9ed: 0x0ed1, 0x9ee: 0x0ee9, 0x9ef: 0x0008,\n\t0x9f0: 0x0ef9, 0x9f1: 0x0f09, 0x9f2: 0x0f19, 0x9f3: 0x0f31, 0x9f4: 0x0249, 0x9f5: 0x0f41,\n\t0x9f6: 0x0259, 0x9f7: 0x0f51, 0x9f8: 0x0359, 0x9f9: 0x0f61, 0x9fa: 0x0f71, 0x9fb: 0x0008,\n\t0x9fc: 0x00d9, 0x9fd: 0x0f81, 0x9fe: 0x0f99, 0x9ff: 0x0269,\n\t// Block 0x28, offset 0xa00\n\t0xa00: 0x0fa9, 0xa01: 0x0fb9, 0xa02: 0x0279, 0xa03: 0x0039, 0xa04: 0x0fc9, 0xa05: 0x0fe1,\n\t0xa06: 0x059d, 0xa07: 0x0ee9, 0xa08: 0x0ef9, 0xa09: 0x0f09, 0xa0a: 0x0ff9, 0xa0b: 0x1011,\n\t0xa0c: 0x1029, 0xa0d: 0x0f31, 0xa0e: 0x0008, 0xa0f: 0x0f51, 0xa10: 0x0f61, 0xa11: 0x1041,\n\t0xa12: 0x00d9, 0xa13: 0x1059, 0xa14: 0x05b5, 0xa15: 0x05b5, 0xa16: 0x0f99, 0xa17: 0x0fa9,\n\t0xa18: 0x0fb9, 0xa19: 0x059d, 0xa1a: 0x1071, 0xa1b: 0x1089, 0xa1c: 0x05cd, 0xa1d: 0x1099,\n\t0xa1e: 0x10b1, 0xa1f: 0x10c9, 0xa20: 0x10e1, 0xa21: 0x10f9, 0xa22: 0x0f41, 0xa23: 0x0269,\n\t0xa24: 0x0fb9, 0xa25: 0x1089, 0xa26: 0x1099, 0xa27: 0x10b1, 0xa28: 0x1111, 0xa29: 0x10e1,\n\t0xa2a: 0x10f9, 0xa2b: 0x0008, 0xa2c: 0x0008, 0xa2d: 0x0008, 0xa2e: 0x0008, 0xa2f: 0x0008,\n\t0xa30: 0x0008, 0xa31: 0x0008, 0xa32: 0x0008, 0xa33: 0x0008, 0xa34: 0x0008, 0xa35: 0x0008,\n\t0xa36: 0x0008, 0xa37: 0x0008, 0xa38: 0x1129, 0xa39: 0x0008, 0xa3a: 0x0008, 0xa3b: 0x0008,\n\t0xa3c: 0x0008, 0xa3d: 0x0008, 0xa3e: 0x0008, 0xa3f: 0x0008,\n\t// Block 0x29, offset 0xa40\n\t0xa40: 0x0008, 0xa41: 0x0008, 0xa42: 0x0008, 0xa43: 0x0008, 0xa44: 0x0008, 0xa45: 0x0008,\n\t0xa46: 0x0008, 0xa47: 0x0008, 0xa48: 0x0008, 0xa49: 0x0008, 0xa4a: 0x0008, 0xa4b: 0x0008,\n\t0xa4c: 0x0008, 0xa4d: 0x0008, 0xa4e: 0x0008, 0xa4f: 0x0008, 0xa50: 0x0008, 0xa51: 0x0008,\n\t0xa52: 0x0008, 0xa53: 0x0008, 0xa54: 0x0008, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008,\n\t0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0008, 0xa5b: 0x1141, 0xa5c: 0x1159, 0xa5d: 0x1169,\n\t0xa5e: 0x1181, 0xa5f: 0x1029, 0xa60: 0x1199, 0xa61: 0x11a9, 0xa62: 0x11c1, 0xa63: 0x11d9,\n\t0xa64: 0x11f1, 0xa65: 0x1209, 0xa66: 0x1221, 0xa67: 0x05e5, 0xa68: 0x1239, 0xa69: 0x1251,\n\t0xa6a: 0xe17d, 0xa6b: 0x1269, 0xa6c: 0x1281, 0xa6d: 0x1299, 0xa6e: 0x12b1, 0xa6f: 0x12c9,\n\t0xa70: 0x12e1, 0xa71: 0x12f9, 0xa72: 0x1311, 0xa73: 0x1329, 0xa74: 0x1341, 0xa75: 0x1359,\n\t0xa76: 0x1371, 0xa77: 0x1389, 0xa78: 0x05fd, 0xa79: 0x13a1, 0xa7a: 0x13b9, 0xa7b: 0x13d1,\n\t0xa7c: 0x13e1, 0xa7d: 0x13f9, 0xa7e: 0x1411, 0xa7f: 0x1429,\n\t// Block 0x2a, offset 0xa80\n\t0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008,\n\t0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008,\n\t0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008,\n\t0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0xe00d, 0xa97: 0x0008,\n\t0xa98: 0xe00d, 0xa99: 0x0008, 0xa9a: 0xe00d, 0xa9b: 0x0008, 0xa9c: 0xe00d, 0xa9d: 0x0008,\n\t0xa9e: 0xe00d, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008,\n\t0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008,\n\t0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008,\n\t0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008,\n\t0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008,\n\t0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008,\n\t// Block 0x2b, offset 0xac0\n\t0xac0: 0xe00d, 0xac1: 0x0008, 0xac2: 0xe00d, 0xac3: 0x0008, 0xac4: 0xe00d, 0xac5: 0x0008,\n\t0xac6: 0xe00d, 0xac7: 0x0008, 0xac8: 0xe00d, 0xac9: 0x0008, 0xaca: 0xe00d, 0xacb: 0x0008,\n\t0xacc: 0xe00d, 0xacd: 0x0008, 0xace: 0xe00d, 0xacf: 0x0008, 0xad0: 0xe00d, 0xad1: 0x0008,\n\t0xad2: 0xe00d, 0xad3: 0x0008, 0xad4: 0xe00d, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008,\n\t0xad8: 0x0008, 0xad9: 0x0008, 0xada: 0x0615, 0xadb: 0x0635, 0xadc: 0x0008, 0xadd: 0x0008,\n\t0xade: 0x1441, 0xadf: 0x0008, 0xae0: 0xe00d, 0xae1: 0x0008, 0xae2: 0xe00d, 0xae3: 0x0008,\n\t0xae4: 0xe00d, 0xae5: 0x0008, 0xae6: 0xe00d, 0xae7: 0x0008, 0xae8: 0xe00d, 0xae9: 0x0008,\n\t0xaea: 0xe00d, 0xaeb: 0x0008, 0xaec: 0xe00d, 0xaed: 0x0008, 0xaee: 0xe00d, 0xaef: 0x0008,\n\t0xaf0: 0xe00d, 0xaf1: 0x0008, 0xaf2: 0xe00d, 0xaf3: 0x0008, 0xaf4: 0xe00d, 0xaf5: 0x0008,\n\t0xaf6: 0xe00d, 0xaf7: 0x0008, 0xaf8: 0xe00d, 0xaf9: 0x0008, 0xafa: 0xe00d, 0xafb: 0x0008,\n\t0xafc: 0xe00d, 0xafd: 0x0008, 0xafe: 0xe00d, 0xaff: 0x0008,\n\t// Block 0x2c, offset 0xb00\n\t0xb00: 0x0008, 0xb01: 0x0008, 0xb02: 0x0008, 0xb03: 0x0008, 0xb04: 0x0008, 0xb05: 0x0008,\n\t0xb06: 0x0040, 0xb07: 0x0040, 0xb08: 0xe045, 0xb09: 0xe045, 0xb0a: 0xe045, 0xb0b: 0xe045,\n\t0xb0c: 0xe045, 0xb0d: 0xe045, 0xb0e: 0x0040, 0xb0f: 0x0040, 0xb10: 0x0008, 0xb11: 0x0008,\n\t0xb12: 0x0008, 0xb13: 0x0008, 0xb14: 0x0008, 0xb15: 0x0008, 0xb16: 0x0008, 0xb17: 0x0008,\n\t0xb18: 0x0040, 0xb19: 0xe045, 0xb1a: 0x0040, 0xb1b: 0xe045, 0xb1c: 0x0040, 0xb1d: 0xe045,\n\t0xb1e: 0x0040, 0xb1f: 0xe045, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x0008,\n\t0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045,\n\t0xb2a: 0xe045, 0xb2b: 0xe045, 0xb2c: 0xe045, 0xb2d: 0xe045, 0xb2e: 0xe045, 0xb2f: 0xe045,\n\t0xb30: 0x0008, 0xb31: 0x1459, 0xb32: 0x0008, 0xb33: 0x1471, 0xb34: 0x0008, 0xb35: 0x1489,\n\t0xb36: 0x0008, 0xb37: 0x14a1, 0xb38: 0x0008, 0xb39: 0x14b9, 0xb3a: 0x0008, 0xb3b: 0x14d1,\n\t0xb3c: 0x0008, 0xb3d: 0x14e9, 0xb3e: 0x0040, 0xb3f: 0x0040,\n\t// Block 0x2d, offset 0xb40\n\t0xb40: 0x1501, 0xb41: 0x1531, 0xb42: 0x1561, 0xb43: 0x1591, 0xb44: 0x15c1, 0xb45: 0x15f1,\n\t0xb46: 0x1621, 0xb47: 0x1651, 0xb48: 0x1501, 0xb49: 0x1531, 0xb4a: 0x1561, 0xb4b: 0x1591,\n\t0xb4c: 0x15c1, 0xb4d: 0x15f1, 0xb4e: 0x1621, 0xb4f: 0x1651, 0xb50: 0x1681, 0xb51: 0x16b1,\n\t0xb52: 0x16e1, 0xb53: 0x1711, 0xb54: 0x1741, 0xb55: 0x1771, 0xb56: 0x17a1, 0xb57: 0x17d1,\n\t0xb58: 0x1681, 0xb59: 0x16b1, 0xb5a: 0x16e1, 0xb5b: 0x1711, 0xb5c: 0x1741, 0xb5d: 0x1771,\n\t0xb5e: 0x17a1, 0xb5f: 0x17d1, 0xb60: 0x1801, 0xb61: 0x1831, 0xb62: 0x1861, 0xb63: 0x1891,\n\t0xb64: 0x18c1, 0xb65: 0x18f1, 0xb66: 0x1921, 0xb67: 0x1951, 0xb68: 0x1801, 0xb69: 0x1831,\n\t0xb6a: 0x1861, 0xb6b: 0x1891, 0xb6c: 0x18c1, 0xb6d: 0x18f1, 0xb6e: 0x1921, 0xb6f: 0x1951,\n\t0xb70: 0x0008, 0xb71: 0x0008, 0xb72: 0x1981, 0xb73: 0x19b1, 0xb74: 0x19d9, 0xb75: 0x0040,\n\t0xb76: 0x0008, 0xb77: 0x1a01, 0xb78: 0xe045, 0xb79: 0xe045, 0xb7a: 0x064d, 0xb7b: 0x1459,\n\t0xb7c: 0x19b1, 0xb7d: 0x0666, 0xb7e: 0x1a31, 0xb7f: 0x0686,\n\t// Block 0x2e, offset 0xb80\n\t0xb80: 0x06a6, 0xb81: 0x1a4a, 0xb82: 0x1a79, 0xb83: 0x1aa9, 0xb84: 0x1ad1, 0xb85: 0x0040,\n\t0xb86: 0x0008, 0xb87: 0x1af9, 0xb88: 0x06c5, 0xb89: 0x1471, 0xb8a: 0x06dd, 0xb8b: 0x1489,\n\t0xb8c: 0x1aa9, 0xb8d: 0x1b2a, 0xb8e: 0x1b5a, 0xb8f: 0x1b8a, 0xb90: 0x0008, 0xb91: 0x0008,\n\t0xb92: 0x0008, 0xb93: 0x1bb9, 0xb94: 0x0040, 0xb95: 0x0040, 0xb96: 0x0008, 0xb97: 0x0008,\n\t0xb98: 0xe045, 0xb99: 0xe045, 0xb9a: 0x06f5, 0xb9b: 0x14a1, 0xb9c: 0x0040, 0xb9d: 0x1bd2,\n\t0xb9e: 0x1c02, 0xb9f: 0x1c32, 0xba0: 0x0008, 0xba1: 0x0008, 0xba2: 0x0008, 0xba3: 0x1c61,\n\t0xba4: 0x0008, 0xba5: 0x0008, 0xba6: 0x0008, 0xba7: 0x0008, 0xba8: 0xe045, 0xba9: 0xe045,\n\t0xbaa: 0x070d, 0xbab: 0x14d1, 0xbac: 0xe04d, 0xbad: 0x1c7a, 0xbae: 0x03d2, 0xbaf: 0x1caa,\n\t0xbb0: 0x0040, 0xbb1: 0x0040, 0xbb2: 0x1cb9, 0xbb3: 0x1ce9, 0xbb4: 0x1d11, 0xbb5: 0x0040,\n\t0xbb6: 0x0008, 0xbb7: 0x1d39, 0xbb8: 0x0725, 0xbb9: 0x14b9, 0xbba: 0x0515, 0xbbb: 0x14e9,\n\t0xbbc: 0x1ce9, 0xbbd: 0x073e, 0xbbe: 0x075e, 0xbbf: 0x0040,\n\t// Block 0x2f, offset 0xbc0\n\t0xbc0: 0x000a, 0xbc1: 0x000a, 0xbc2: 0x000a, 0xbc3: 0x000a, 0xbc4: 0x000a, 0xbc5: 0x000a,\n\t0xbc6: 0x000a, 0xbc7: 0x000a, 0xbc8: 0x000a, 0xbc9: 0x000a, 0xbca: 0x000a, 0xbcb: 0x03c0,\n\t0xbcc: 0x0003, 0xbcd: 0x0003, 0xbce: 0x0340, 0xbcf: 0x0b40, 0xbd0: 0x0018, 0xbd1: 0xe00d,\n\t0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x077e,\n\t0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018,\n\t0xbde: 0x0018, 0xbdf: 0x0018, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018,\n\t0xbe4: 0x0040, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0018, 0xbe8: 0x0040, 0xbe9: 0x0040,\n\t0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x000a,\n\t0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x1d69, 0xbf4: 0x1da1, 0xbf5: 0x0018,\n\t0xbf6: 0x1df1, 0xbf7: 0x1e29, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018,\n\t0xbfc: 0x1e7a, 0xbfd: 0x0018, 0xbfe: 0x079e, 0xbff: 0x0018,\n\t// Block 0x30, offset 0xc00\n\t0xc00: 0x0018, 0xc01: 0x0018, 0xc02: 0x0018, 0xc03: 0x0018, 0xc04: 0x0018, 0xc05: 0x0018,\n\t0xc06: 0x0018, 0xc07: 0x1e92, 0xc08: 0x1eaa, 0xc09: 0x1ec2, 0xc0a: 0x0018, 0xc0b: 0x0018,\n\t0xc0c: 0x0018, 0xc0d: 0x0018, 0xc0e: 0x0018, 0xc0f: 0x0018, 0xc10: 0x0018, 0xc11: 0x0018,\n\t0xc12: 0x0018, 0xc13: 0x0018, 0xc14: 0x0018, 0xc15: 0x0018, 0xc16: 0x0018, 0xc17: 0x1ed9,\n\t0xc18: 0x0018, 0xc19: 0x0018, 0xc1a: 0x0018, 0xc1b: 0x0018, 0xc1c: 0x0018, 0xc1d: 0x0018,\n\t0xc1e: 0x0018, 0xc1f: 0x000a, 0xc20: 0x03c0, 0xc21: 0x0340, 0xc22: 0x0340, 0xc23: 0x0340,\n\t0xc24: 0x03c0, 0xc25: 0x0040, 0xc26: 0x0040, 0xc27: 0x0040, 0xc28: 0x0040, 0xc29: 0x0040,\n\t0xc2a: 0x0340, 0xc2b: 0x0340, 0xc2c: 0x0340, 0xc2d: 0x0340, 0xc2e: 0x0340, 0xc2f: 0x0340,\n\t0xc30: 0x1f41, 0xc31: 0x0f41, 0xc32: 0x0040, 0xc33: 0x0040, 0xc34: 0x1f51, 0xc35: 0x1f61,\n\t0xc36: 0x1f71, 0xc37: 0x1f81, 0xc38: 0x1f91, 0xc39: 0x1fa1, 0xc3a: 0x1fb2, 0xc3b: 0x07bd,\n\t0xc3c: 0x1fc2, 0xc3d: 0x1fd2, 0xc3e: 0x1fe2, 0xc3f: 0x0f71,\n\t// Block 0x31, offset 0xc40\n\t0xc40: 0x1f41, 0xc41: 0x00c9, 0xc42: 0x0069, 0xc43: 0x0079, 0xc44: 0x1f51, 0xc45: 0x1f61,\n\t0xc46: 0x1f71, 0xc47: 0x1f81, 0xc48: 0x1f91, 0xc49: 0x1fa1, 0xc4a: 0x1fb2, 0xc4b: 0x07d5,\n\t0xc4c: 0x1fc2, 0xc4d: 0x1fd2, 0xc4e: 0x1fe2, 0xc4f: 0x0040, 0xc50: 0x0039, 0xc51: 0x0f09,\n\t0xc52: 0x00d9, 0xc53: 0x0369, 0xc54: 0x0ff9, 0xc55: 0x0249, 0xc56: 0x0f51, 0xc57: 0x0359,\n\t0xc58: 0x0f61, 0xc59: 0x0f71, 0xc5a: 0x0f99, 0xc5b: 0x01d9, 0xc5c: 0x0fa9, 0xc5d: 0x0040,\n\t0xc5e: 0x0040, 0xc5f: 0x0040, 0xc60: 0x0018, 0xc61: 0x0018, 0xc62: 0x0018, 0xc63: 0x0018,\n\t0xc64: 0x0018, 0xc65: 0x0018, 0xc66: 0x0018, 0xc67: 0x0018, 0xc68: 0x1ff1, 0xc69: 0x0018,\n\t0xc6a: 0x0018, 0xc6b: 0x0018, 0xc6c: 0x0018, 0xc6d: 0x0018, 0xc6e: 0x0018, 0xc6f: 0x0018,\n\t0xc70: 0x0018, 0xc71: 0x0018, 0xc72: 0x0018, 0xc73: 0x0018, 0xc74: 0x0018, 0xc75: 0x0018,\n\t0xc76: 0x0018, 0xc77: 0x0018, 0xc78: 0x0018, 0xc79: 0x0018, 0xc7a: 0x0018, 0xc7b: 0x0018,\n\t0xc7c: 0x0018, 0xc7d: 0x0018, 0xc7e: 0x0018, 0xc7f: 0x0018,\n\t// Block 0x32, offset 0xc80\n\t0xc80: 0x07ee, 0xc81: 0x080e, 0xc82: 0x1159, 0xc83: 0x082d, 0xc84: 0x0018, 0xc85: 0x084e,\n\t0xc86: 0x086e, 0xc87: 0x1011, 0xc88: 0x0018, 0xc89: 0x088d, 0xc8a: 0x0f31, 0xc8b: 0x0249,\n\t0xc8c: 0x0249, 0xc8d: 0x0249, 0xc8e: 0x0249, 0xc8f: 0x2009, 0xc90: 0x0f41, 0xc91: 0x0f41,\n\t0xc92: 0x0359, 0xc93: 0x0359, 0xc94: 0x0018, 0xc95: 0x0f71, 0xc96: 0x2021, 0xc97: 0x0018,\n\t0xc98: 0x0018, 0xc99: 0x0f99, 0xc9a: 0x2039, 0xc9b: 0x0269, 0xc9c: 0x0269, 0xc9d: 0x0269,\n\t0xc9e: 0x0018, 0xc9f: 0x0018, 0xca0: 0x2049, 0xca1: 0x08ad, 0xca2: 0x2061, 0xca3: 0x0018,\n\t0xca4: 0x13d1, 0xca5: 0x0018, 0xca6: 0x2079, 0xca7: 0x0018, 0xca8: 0x13d1, 0xca9: 0x0018,\n\t0xcaa: 0x0f51, 0xcab: 0x2091, 0xcac: 0x0ee9, 0xcad: 0x1159, 0xcae: 0x0018, 0xcaf: 0x0f09,\n\t0xcb0: 0x0f09, 0xcb1: 0x1199, 0xcb2: 0x0040, 0xcb3: 0x0f61, 0xcb4: 0x00d9, 0xcb5: 0x20a9,\n\t0xcb6: 0x20c1, 0xcb7: 0x20d9, 0xcb8: 0x20f1, 0xcb9: 0x0f41, 0xcba: 0x0018, 0xcbb: 0x08cd,\n\t0xcbc: 0x2109, 0xcbd: 0x10b1, 0xcbe: 0x10b1, 0xcbf: 0x2109,\n\t// Block 0x33, offset 0xcc0\n\t0xcc0: 0x08ed, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x0ef9,\n\t0xcc6: 0x0ef9, 0xcc7: 0x0f09, 0xcc8: 0x0f41, 0xcc9: 0x0259, 0xcca: 0x0018, 0xccb: 0x0018,\n\t0xccc: 0x0018, 0xccd: 0x0018, 0xcce: 0x0008, 0xccf: 0x0018, 0xcd0: 0x2121, 0xcd1: 0x2151,\n\t0xcd2: 0x2181, 0xcd3: 0x21b9, 0xcd4: 0x21e9, 0xcd5: 0x2219, 0xcd6: 0x2249, 0xcd7: 0x2279,\n\t0xcd8: 0x22a9, 0xcd9: 0x22d9, 0xcda: 0x2309, 0xcdb: 0x2339, 0xcdc: 0x2369, 0xcdd: 0x2399,\n\t0xcde: 0x23c9, 0xcdf: 0x23f9, 0xce0: 0x0f41, 0xce1: 0x2421, 0xce2: 0x0905, 0xce3: 0x2439,\n\t0xce4: 0x1089, 0xce5: 0x2451, 0xce6: 0x0925, 0xce7: 0x2469, 0xce8: 0x2491, 0xce9: 0x0369,\n\t0xcea: 0x24a9, 0xceb: 0x0945, 0xcec: 0x0359, 0xced: 0x1159, 0xcee: 0x0ef9, 0xcef: 0x0f61,\n\t0xcf0: 0x0f41, 0xcf1: 0x2421, 0xcf2: 0x0965, 0xcf3: 0x2439, 0xcf4: 0x1089, 0xcf5: 0x2451,\n\t0xcf6: 0x0985, 0xcf7: 0x2469, 0xcf8: 0x2491, 0xcf9: 0x0369, 0xcfa: 0x24a9, 0xcfb: 0x09a5,\n\t0xcfc: 0x0359, 0xcfd: 0x1159, 0xcfe: 0x0ef9, 0xcff: 0x0f61,\n\t// Block 0x34, offset 0xd00\n\t0xd00: 0x0018, 0xd01: 0x0018, 0xd02: 0x0018, 0xd03: 0x0018, 0xd04: 0x0018, 0xd05: 0x0018,\n\t0xd06: 0x0018, 0xd07: 0x0018, 0xd08: 0x0018, 0xd09: 0x0018, 0xd0a: 0x0018, 0xd0b: 0x0040,\n\t0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040,\n\t0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040,\n\t0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0040, 0xd1d: 0x0040,\n\t0xd1e: 0x0040, 0xd1f: 0x0040, 0xd20: 0x00c9, 0xd21: 0x0069, 0xd22: 0x0079, 0xd23: 0x1f51,\n\t0xd24: 0x1f61, 0xd25: 0x1f71, 0xd26: 0x1f81, 0xd27: 0x1f91, 0xd28: 0x1fa1, 0xd29: 0x2601,\n\t0xd2a: 0x2619, 0xd2b: 0x2631, 0xd2c: 0x2649, 0xd2d: 0x2661, 0xd2e: 0x2679, 0xd2f: 0x2691,\n\t0xd30: 0x26a9, 0xd31: 0x26c1, 0xd32: 0x26d9, 0xd33: 0x26f1, 0xd34: 0x0a06, 0xd35: 0x0a26,\n\t0xd36: 0x0a46, 0xd37: 0x0a66, 0xd38: 0x0a86, 0xd39: 0x0aa6, 0xd3a: 0x0ac6, 0xd3b: 0x0ae6,\n\t0xd3c: 0x0b06, 0xd3d: 0x270a, 0xd3e: 0x2732, 0xd3f: 0x275a,\n\t// Block 0x35, offset 0xd40\n\t0xd40: 0x2782, 0xd41: 0x27aa, 0xd42: 0x27d2, 0xd43: 0x27fa, 0xd44: 0x2822, 0xd45: 0x284a,\n\t0xd46: 0x2872, 0xd47: 0x289a, 0xd48: 0x0040, 0xd49: 0x0040, 0xd4a: 0x0040, 0xd4b: 0x0040,\n\t0xd4c: 0x0040, 0xd4d: 0x0040, 0xd4e: 0x0040, 0xd4f: 0x0040, 0xd50: 0x0040, 0xd51: 0x0040,\n\t0xd52: 0x0040, 0xd53: 0x0040, 0xd54: 0x0040, 0xd55: 0x0040, 0xd56: 0x0040, 0xd57: 0x0040,\n\t0xd58: 0x0040, 0xd59: 0x0040, 0xd5a: 0x0040, 0xd5b: 0x0040, 0xd5c: 0x0b26, 0xd5d: 0x0b46,\n\t0xd5e: 0x0b66, 0xd5f: 0x0b86, 0xd60: 0x0ba6, 0xd61: 0x0bc6, 0xd62: 0x0be6, 0xd63: 0x0c06,\n\t0xd64: 0x0c26, 0xd65: 0x0c46, 0xd66: 0x0c66, 0xd67: 0x0c86, 0xd68: 0x0ca6, 0xd69: 0x0cc6,\n\t0xd6a: 0x0ce6, 0xd6b: 0x0d06, 0xd6c: 0x0d26, 0xd6d: 0x0d46, 0xd6e: 0x0d66, 0xd6f: 0x0d86,\n\t0xd70: 0x0da6, 0xd71: 0x0dc6, 0xd72: 0x0de6, 0xd73: 0x0e06, 0xd74: 0x0e26, 0xd75: 0x0e46,\n\t0xd76: 0x0039, 0xd77: 0x0ee9, 0xd78: 0x1159, 0xd79: 0x0ef9, 0xd7a: 0x0f09, 0xd7b: 0x1199,\n\t0xd7c: 0x0f31, 0xd7d: 0x0249, 0xd7e: 0x0f41, 0xd7f: 0x0259,\n\t// Block 0x36, offset 0xd80\n\t0xd80: 0x0f51, 0xd81: 0x0359, 0xd82: 0x0f61, 0xd83: 0x0f71, 0xd84: 0x00d9, 0xd85: 0x0f99,\n\t0xd86: 0x2039, 0xd87: 0x0269, 0xd88: 0x01d9, 0xd89: 0x0fa9, 0xd8a: 0x0fb9, 0xd8b: 0x1089,\n\t0xd8c: 0x0279, 0xd8d: 0x0369, 0xd8e: 0x0289, 0xd8f: 0x13d1, 0xd90: 0x0039, 0xd91: 0x0ee9,\n\t0xd92: 0x1159, 0xd93: 0x0ef9, 0xd94: 0x0f09, 0xd95: 0x1199, 0xd96: 0x0f31, 0xd97: 0x0249,\n\t0xd98: 0x0f41, 0xd99: 0x0259, 0xd9a: 0x0f51, 0xd9b: 0x0359, 0xd9c: 0x0f61, 0xd9d: 0x0f71,\n\t0xd9e: 0x00d9, 0xd9f: 0x0f99, 0xda0: 0x2039, 0xda1: 0x0269, 0xda2: 0x01d9, 0xda3: 0x0fa9,\n\t0xda4: 0x0fb9, 0xda5: 0x1089, 0xda6: 0x0279, 0xda7: 0x0369, 0xda8: 0x0289, 0xda9: 0x13d1,\n\t0xdaa: 0x1f41, 0xdab: 0x0018, 0xdac: 0x0018, 0xdad: 0x0018, 0xdae: 0x0018, 0xdaf: 0x0018,\n\t0xdb0: 0x0018, 0xdb1: 0x0018, 0xdb2: 0x0018, 0xdb3: 0x0018, 0xdb4: 0x0018, 0xdb5: 0x0018,\n\t0xdb6: 0x0018, 0xdb7: 0x0018, 0xdb8: 0x0018, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018,\n\t0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018,\n\t// Block 0x37, offset 0xdc0\n\t0xdc0: 0x0008, 0xdc1: 0x0008, 0xdc2: 0x0008, 0xdc3: 0x0008, 0xdc4: 0x0008, 0xdc5: 0x0008,\n\t0xdc6: 0x0008, 0xdc7: 0x0008, 0xdc8: 0x0008, 0xdc9: 0x0008, 0xdca: 0x0008, 0xdcb: 0x0008,\n\t0xdcc: 0x0008, 0xdcd: 0x0008, 0xdce: 0x0008, 0xdcf: 0x0008, 0xdd0: 0x0008, 0xdd1: 0x0008,\n\t0xdd2: 0x0008, 0xdd3: 0x0008, 0xdd4: 0x0008, 0xdd5: 0x0008, 0xdd6: 0x0008, 0xdd7: 0x0008,\n\t0xdd8: 0x0008, 0xdd9: 0x0008, 0xdda: 0x0008, 0xddb: 0x0008, 0xddc: 0x0008, 0xddd: 0x0008,\n\t0xdde: 0x0008, 0xddf: 0x0040, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0x2971, 0xde3: 0x0ebd,\n\t0xde4: 0x2989, 0xde5: 0x0008, 0xde6: 0x0008, 0xde7: 0xe07d, 0xde8: 0x0008, 0xde9: 0xe01d,\n\t0xdea: 0x0008, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0x0fe1, 0xdee: 0x1281, 0xdef: 0x0fc9,\n\t0xdf0: 0x1141, 0xdf1: 0x0008, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0008, 0xdf5: 0xe01d,\n\t0xdf6: 0x0008, 0xdf7: 0x0008, 0xdf8: 0x0008, 0xdf9: 0x0008, 0xdfa: 0x0008, 0xdfb: 0x0008,\n\t0xdfc: 0x0259, 0xdfd: 0x1089, 0xdfe: 0x29a1, 0xdff: 0x29b9,\n\t// Block 0x38, offset 0xe00\n\t0xe00: 0xe00d, 0xe01: 0x0008, 0xe02: 0xe00d, 0xe03: 0x0008, 0xe04: 0xe00d, 0xe05: 0x0008,\n\t0xe06: 0xe00d, 0xe07: 0x0008, 0xe08: 0xe00d, 0xe09: 0x0008, 0xe0a: 0xe00d, 0xe0b: 0x0008,\n\t0xe0c: 0xe00d, 0xe0d: 0x0008, 0xe0e: 0xe00d, 0xe0f: 0x0008, 0xe10: 0xe00d, 0xe11: 0x0008,\n\t0xe12: 0xe00d, 0xe13: 0x0008, 0xe14: 0xe00d, 0xe15: 0x0008, 0xe16: 0xe00d, 0xe17: 0x0008,\n\t0xe18: 0xe00d, 0xe19: 0x0008, 0xe1a: 0xe00d, 0xe1b: 0x0008, 0xe1c: 0xe00d, 0xe1d: 0x0008,\n\t0xe1e: 0xe00d, 0xe1f: 0x0008, 0xe20: 0xe00d, 0xe21: 0x0008, 0xe22: 0xe00d, 0xe23: 0x0008,\n\t0xe24: 0x0008, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018,\n\t0xe2a: 0x0018, 0xe2b: 0xe03d, 0xe2c: 0x0008, 0xe2d: 0xe01d, 0xe2e: 0x0008, 0xe2f: 0x3308,\n\t0xe30: 0x3308, 0xe31: 0x3308, 0xe32: 0xe00d, 0xe33: 0x0008, 0xe34: 0x0040, 0xe35: 0x0040,\n\t0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0018, 0xe3a: 0x0018, 0xe3b: 0x0018,\n\t0xe3c: 0x0018, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018,\n\t// Block 0x39, offset 0xe40\n\t0xe40: 0x26fd, 0xe41: 0x271d, 0xe42: 0x273d, 0xe43: 0x275d, 0xe44: 0x277d, 0xe45: 0x279d,\n\t0xe46: 0x27bd, 0xe47: 0x27dd, 0xe48: 0x27fd, 0xe49: 0x281d, 0xe4a: 0x283d, 0xe4b: 0x285d,\n\t0xe4c: 0x287d, 0xe4d: 0x289d, 0xe4e: 0x28bd, 0xe4f: 0x28dd, 0xe50: 0x28fd, 0xe51: 0x291d,\n\t0xe52: 0x293d, 0xe53: 0x295d, 0xe54: 0x297d, 0xe55: 0x299d, 0xe56: 0x0040, 0xe57: 0x0040,\n\t0xe58: 0x0040, 0xe59: 0x0040, 0xe5a: 0x0040, 0xe5b: 0x0040, 0xe5c: 0x0040, 0xe5d: 0x0040,\n\t0xe5e: 0x0040, 0xe5f: 0x0040, 0xe60: 0x0040, 0xe61: 0x0040, 0xe62: 0x0040, 0xe63: 0x0040,\n\t0xe64: 0x0040, 0xe65: 0x0040, 0xe66: 0x0040, 0xe67: 0x0040, 0xe68: 0x0040, 0xe69: 0x0040,\n\t0xe6a: 0x0040, 0xe6b: 0x0040, 0xe6c: 0x0040, 0xe6d: 0x0040, 0xe6e: 0x0040, 0xe6f: 0x0040,\n\t0xe70: 0x0040, 0xe71: 0x0040, 0xe72: 0x0040, 0xe73: 0x0040, 0xe74: 0x0040, 0xe75: 0x0040,\n\t0xe76: 0x0040, 0xe77: 0x0040, 0xe78: 0x0040, 0xe79: 0x0040, 0xe7a: 0x0040, 0xe7b: 0x0040,\n\t0xe7c: 0x0040, 0xe7d: 0x0040, 0xe7e: 0x0040, 0xe7f: 0x0040,\n\t// Block 0x3a, offset 0xe80\n\t0xe80: 0x000a, 0xe81: 0x0018, 0xe82: 0x29d1, 0xe83: 0x0018, 0xe84: 0x0018, 0xe85: 0x0008,\n\t0xe86: 0x0008, 0xe87: 0x0008, 0xe88: 0x0018, 0xe89: 0x0018, 0xe8a: 0x0018, 0xe8b: 0x0018,\n\t0xe8c: 0x0018, 0xe8d: 0x0018, 0xe8e: 0x0018, 0xe8f: 0x0018, 0xe90: 0x0018, 0xe91: 0x0018,\n\t0xe92: 0x0018, 0xe93: 0x0018, 0xe94: 0x0018, 0xe95: 0x0018, 0xe96: 0x0018, 0xe97: 0x0018,\n\t0xe98: 0x0018, 0xe99: 0x0018, 0xe9a: 0x0018, 0xe9b: 0x0018, 0xe9c: 0x0018, 0xe9d: 0x0018,\n\t0xe9e: 0x0018, 0xe9f: 0x0018, 0xea0: 0x0018, 0xea1: 0x0018, 0xea2: 0x0018, 0xea3: 0x0018,\n\t0xea4: 0x0018, 0xea5: 0x0018, 0xea6: 0x0018, 0xea7: 0x0018, 0xea8: 0x0018, 0xea9: 0x0018,\n\t0xeaa: 0x3308, 0xeab: 0x3308, 0xeac: 0x3308, 0xead: 0x3308, 0xeae: 0x3018, 0xeaf: 0x3018,\n\t0xeb0: 0x0018, 0xeb1: 0x0018, 0xeb2: 0x0018, 0xeb3: 0x0018, 0xeb4: 0x0018, 0xeb5: 0x0018,\n\t0xeb6: 0xe125, 0xeb7: 0x0018, 0xeb8: 0x29bd, 0xeb9: 0x29dd, 0xeba: 0x29fd, 0xebb: 0x0018,\n\t0xebc: 0x0008, 0xebd: 0x0018, 0xebe: 0x0018, 0xebf: 0x0018,\n\t// Block 0x3b, offset 0xec0\n\t0xec0: 0x2b3d, 0xec1: 0x2b5d, 0xec2: 0x2b7d, 0xec3: 0x2b9d, 0xec4: 0x2bbd, 0xec5: 0x2bdd,\n\t0xec6: 0x2bdd, 0xec7: 0x2bdd, 0xec8: 0x2bfd, 0xec9: 0x2bfd, 0xeca: 0x2bfd, 0xecb: 0x2bfd,\n\t0xecc: 0x2c1d, 0xecd: 0x2c1d, 0xece: 0x2c1d, 0xecf: 0x2c3d, 0xed0: 0x2c5d, 0xed1: 0x2c5d,\n\t0xed2: 0x2a7d, 0xed3: 0x2a7d, 0xed4: 0x2c5d, 0xed5: 0x2c5d, 0xed6: 0x2c7d, 0xed7: 0x2c7d,\n\t0xed8: 0x2c5d, 0xed9: 0x2c5d, 0xeda: 0x2a7d, 0xedb: 0x2a7d, 0xedc: 0x2c5d, 0xedd: 0x2c5d,\n\t0xede: 0x2c3d, 0xedf: 0x2c3d, 0xee0: 0x2c9d, 0xee1: 0x2c9d, 0xee2: 0x2cbd, 0xee3: 0x2cbd,\n\t0xee4: 0x0040, 0xee5: 0x2cdd, 0xee6: 0x2cfd, 0xee7: 0x2d1d, 0xee8: 0x2d1d, 0xee9: 0x2d3d,\n\t0xeea: 0x2d5d, 0xeeb: 0x2d7d, 0xeec: 0x2d9d, 0xeed: 0x2dbd, 0xeee: 0x2ddd, 0xeef: 0x2dfd,\n\t0xef0: 0x2e1d, 0xef1: 0x2e3d, 0xef2: 0x2e3d, 0xef3: 0x2e5d, 0xef4: 0x2e7d, 0xef5: 0x2e7d,\n\t0xef6: 0x2e9d, 0xef7: 0x2ebd, 0xef8: 0x2e5d, 0xef9: 0x2edd, 0xefa: 0x2efd, 0xefb: 0x2edd,\n\t0xefc: 0x2e5d, 0xefd: 0x2f1d, 0xefe: 0x2f3d, 0xeff: 0x2f5d,\n\t// Block 0x3c, offset 0xf00\n\t0xf00: 0x2f7d, 0xf01: 0x2f9d, 0xf02: 0x2cfd, 0xf03: 0x2cdd, 0xf04: 0x2fbd, 0xf05: 0x2fdd,\n\t0xf06: 0x2ffd, 0xf07: 0x301d, 0xf08: 0x303d, 0xf09: 0x305d, 0xf0a: 0x307d, 0xf0b: 0x309d,\n\t0xf0c: 0x30bd, 0xf0d: 0x30dd, 0xf0e: 0x30fd, 0xf0f: 0x0040, 0xf10: 0x0018, 0xf11: 0x0018,\n\t0xf12: 0x311d, 0xf13: 0x313d, 0xf14: 0x315d, 0xf15: 0x317d, 0xf16: 0x319d, 0xf17: 0x31bd,\n\t0xf18: 0x31dd, 0xf19: 0x31fd, 0xf1a: 0x321d, 0xf1b: 0x323d, 0xf1c: 0x315d, 0xf1d: 0x325d,\n\t0xf1e: 0x327d, 0xf1f: 0x329d, 0xf20: 0x0008, 0xf21: 0x0008, 0xf22: 0x0008, 0xf23: 0x0008,\n\t0xf24: 0x0008, 0xf25: 0x0008, 0xf26: 0x0008, 0xf27: 0x0008, 0xf28: 0x0008, 0xf29: 0x0008,\n\t0xf2a: 0x0008, 0xf2b: 0x0008, 0xf2c: 0x0008, 0xf2d: 0x0008, 0xf2e: 0x0008, 0xf2f: 0x0008,\n\t0xf30: 0x0008, 0xf31: 0x0008, 0xf32: 0x0008, 0xf33: 0x0008, 0xf34: 0x0008, 0xf35: 0x0008,\n\t0xf36: 0x0008, 0xf37: 0x0008, 0xf38: 0x0008, 0xf39: 0x0008, 0xf3a: 0x0008, 0xf3b: 0x0040,\n\t0xf3c: 0x0040, 0xf3d: 0x0040, 0xf3e: 0x0040, 0xf3f: 0x0040,\n\t// Block 0x3d, offset 0xf40\n\t0xf40: 0x36a2, 0xf41: 0x36d2, 0xf42: 0x3702, 0xf43: 0x3732, 0xf44: 0x32bd, 0xf45: 0x32dd,\n\t0xf46: 0x32fd, 0xf47: 0x331d, 0xf48: 0x0018, 0xf49: 0x0018, 0xf4a: 0x0018, 0xf4b: 0x0018,\n\t0xf4c: 0x0018, 0xf4d: 0x0018, 0xf4e: 0x0018, 0xf4f: 0x0018, 0xf50: 0x333d, 0xf51: 0x3761,\n\t0xf52: 0x3779, 0xf53: 0x3791, 0xf54: 0x37a9, 0xf55: 0x37c1, 0xf56: 0x37d9, 0xf57: 0x37f1,\n\t0xf58: 0x3809, 0xf59: 0x3821, 0xf5a: 0x3839, 0xf5b: 0x3851, 0xf5c: 0x3869, 0xf5d: 0x3881,\n\t0xf5e: 0x3899, 0xf5f: 0x38b1, 0xf60: 0x335d, 0xf61: 0x337d, 0xf62: 0x339d, 0xf63: 0x33bd,\n\t0xf64: 0x33dd, 0xf65: 0x33dd, 0xf66: 0x33fd, 0xf67: 0x341d, 0xf68: 0x343d, 0xf69: 0x345d,\n\t0xf6a: 0x347d, 0xf6b: 0x349d, 0xf6c: 0x34bd, 0xf6d: 0x34dd, 0xf6e: 0x34fd, 0xf6f: 0x351d,\n\t0xf70: 0x353d, 0xf71: 0x355d, 0xf72: 0x357d, 0xf73: 0x359d, 0xf74: 0x35bd, 0xf75: 0x35dd,\n\t0xf76: 0x35fd, 0xf77: 0x361d, 0xf78: 0x363d, 0xf79: 0x365d, 0xf7a: 0x367d, 0xf7b: 0x369d,\n\t0xf7c: 0x38c9, 0xf7d: 0x3901, 0xf7e: 0x36bd, 0xf7f: 0x0018,\n\t// Block 0x3e, offset 0xf80\n\t0xf80: 0x36dd, 0xf81: 0x36fd, 0xf82: 0x371d, 0xf83: 0x373d, 0xf84: 0x375d, 0xf85: 0x377d,\n\t0xf86: 0x379d, 0xf87: 0x37bd, 0xf88: 0x37dd, 0xf89: 0x37fd, 0xf8a: 0x381d, 0xf8b: 0x383d,\n\t0xf8c: 0x385d, 0xf8d: 0x387d, 0xf8e: 0x389d, 0xf8f: 0x38bd, 0xf90: 0x38dd, 0xf91: 0x38fd,\n\t0xf92: 0x391d, 0xf93: 0x393d, 0xf94: 0x395d, 0xf95: 0x397d, 0xf96: 0x399d, 0xf97: 0x39bd,\n\t0xf98: 0x39dd, 0xf99: 0x39fd, 0xf9a: 0x3a1d, 0xf9b: 0x3a3d, 0xf9c: 0x3a5d, 0xf9d: 0x3a7d,\n\t0xf9e: 0x3a9d, 0xf9f: 0x3abd, 0xfa0: 0x3add, 0xfa1: 0x3afd, 0xfa2: 0x3b1d, 0xfa3: 0x3b3d,\n\t0xfa4: 0x3b5d, 0xfa5: 0x3b7d, 0xfa6: 0x127d, 0xfa7: 0x3b9d, 0xfa8: 0x3bbd, 0xfa9: 0x3bdd,\n\t0xfaa: 0x3bfd, 0xfab: 0x3c1d, 0xfac: 0x3c3d, 0xfad: 0x3c5d, 0xfae: 0x239d, 0xfaf: 0x3c7d,\n\t0xfb0: 0x3c9d, 0xfb1: 0x3939, 0xfb2: 0x3951, 0xfb3: 0x3969, 0xfb4: 0x3981, 0xfb5: 0x3999,\n\t0xfb6: 0x39b1, 0xfb7: 0x39c9, 0xfb8: 0x39e1, 0xfb9: 0x39f9, 0xfba: 0x3a11, 0xfbb: 0x3a29,\n\t0xfbc: 0x3a41, 0xfbd: 0x3a59, 0xfbe: 0x3a71, 0xfbf: 0x3a89,\n\t// Block 0x3f, offset 0xfc0\n\t0xfc0: 0x3aa1, 0xfc1: 0x3ac9, 0xfc2: 0x3af1, 0xfc3: 0x3b19, 0xfc4: 0x3b41, 0xfc5: 0x3b69,\n\t0xfc6: 0x3b91, 0xfc7: 0x3bb9, 0xfc8: 0x3be1, 0xfc9: 0x3c09, 0xfca: 0x3c39, 0xfcb: 0x3c69,\n\t0xfcc: 0x3c99, 0xfcd: 0x3cbd, 0xfce: 0x3cb1, 0xfcf: 0x3cdd, 0xfd0: 0x3cfd, 0xfd1: 0x3d15,\n\t0xfd2: 0x3d2d, 0xfd3: 0x3d45, 0xfd4: 0x3d5d, 0xfd5: 0x3d5d, 0xfd6: 0x3d45, 0xfd7: 0x3d75,\n\t0xfd8: 0x07bd, 0xfd9: 0x3d8d, 0xfda: 0x3da5, 0xfdb: 0x3dbd, 0xfdc: 0x3dd5, 0xfdd: 0x3ded,\n\t0xfde: 0x3e05, 0xfdf: 0x3e1d, 0xfe0: 0x3e35, 0xfe1: 0x3e4d, 0xfe2: 0x3e65, 0xfe3: 0x3e7d,\n\t0xfe4: 0x3e95, 0xfe5: 0x3e95, 0xfe6: 0x3ead, 0xfe7: 0x3ead, 0xfe8: 0x3ec5, 0xfe9: 0x3ec5,\n\t0xfea: 0x3edd, 0xfeb: 0x3ef5, 0xfec: 0x3f0d, 0xfed: 0x3f25, 0xfee: 0x3f3d, 0xfef: 0x3f3d,\n\t0xff0: 0x3f55, 0xff1: 0x3f55, 0xff2: 0x3f55, 0xff3: 0x3f6d, 0xff4: 0x3f85, 0xff5: 0x3f9d,\n\t0xff6: 0x3fb5, 0xff7: 0x3f9d, 0xff8: 0x3fcd, 0xff9: 0x3fe5, 0xffa: 0x3f6d, 0xffb: 0x3ffd,\n\t0xffc: 0x4015, 0xffd: 0x4015, 0xffe: 0x4015, 0xfff: 0x0040,\n\t// Block 0x40, offset 0x1000\n\t0x1000: 0x3cc9, 0x1001: 0x3d31, 0x1002: 0x3d99, 0x1003: 0x3e01, 0x1004: 0x3e51, 0x1005: 0x3eb9,\n\t0x1006: 0x3f09, 0x1007: 0x3f59, 0x1008: 0x3fd9, 0x1009: 0x4041, 0x100a: 0x4091, 0x100b: 0x40e1,\n\t0x100c: 0x4131, 0x100d: 0x4199, 0x100e: 0x4201, 0x100f: 0x4251, 0x1010: 0x42a1, 0x1011: 0x42d9,\n\t0x1012: 0x4329, 0x1013: 0x4391, 0x1014: 0x43f9, 0x1015: 0x4431, 0x1016: 0x44b1, 0x1017: 0x4549,\n\t0x1018: 0x45c9, 0x1019: 0x4619, 0x101a: 0x4699, 0x101b: 0x4719, 0x101c: 0x4781, 0x101d: 0x47d1,\n\t0x101e: 0x4821, 0x101f: 0x4871, 0x1020: 0x48d9, 0x1021: 0x4959, 0x1022: 0x49c1, 0x1023: 0x4a11,\n\t0x1024: 0x4a61, 0x1025: 0x4ab1, 0x1026: 0x4ae9, 0x1027: 0x4b21, 0x1028: 0x4b59, 0x1029: 0x4b91,\n\t0x102a: 0x4be1, 0x102b: 0x4c31, 0x102c: 0x4cb1, 0x102d: 0x4d01, 0x102e: 0x4d69, 0x102f: 0x4de9,\n\t0x1030: 0x4e39, 0x1031: 0x4e71, 0x1032: 0x4ea9, 0x1033: 0x4f29, 0x1034: 0x4f91, 0x1035: 0x5011,\n\t0x1036: 0x5061, 0x1037: 0x50e1, 0x1038: 0x5119, 0x1039: 0x5169, 0x103a: 0x51b9, 0x103b: 0x5209,\n\t0x103c: 0x5259, 0x103d: 0x52a9, 0x103e: 0x5311, 0x103f: 0x5361,\n\t// Block 0x41, offset 0x1040\n\t0x1040: 0x5399, 0x1041: 0x53e9, 0x1042: 0x5439, 0x1043: 0x5489, 0x1044: 0x54f1, 0x1045: 0x5541,\n\t0x1046: 0x5591, 0x1047: 0x55e1, 0x1048: 0x5661, 0x1049: 0x56c9, 0x104a: 0x5701, 0x104b: 0x5781,\n\t0x104c: 0x57b9, 0x104d: 0x5821, 0x104e: 0x5889, 0x104f: 0x58d9, 0x1050: 0x5929, 0x1051: 0x5979,\n\t0x1052: 0x59e1, 0x1053: 0x5a19, 0x1054: 0x5a69, 0x1055: 0x5ad1, 0x1056: 0x5b09, 0x1057: 0x5b89,\n\t0x1058: 0x5bd9, 0x1059: 0x5c01, 0x105a: 0x5c29, 0x105b: 0x5c51, 0x105c: 0x5c79, 0x105d: 0x5ca1,\n\t0x105e: 0x5cc9, 0x105f: 0x5cf1, 0x1060: 0x5d19, 0x1061: 0x5d41, 0x1062: 0x5d69, 0x1063: 0x5d99,\n\t0x1064: 0x5dc9, 0x1065: 0x5df9, 0x1066: 0x5e29, 0x1067: 0x5e59, 0x1068: 0x5e89, 0x1069: 0x5eb9,\n\t0x106a: 0x5ee9, 0x106b: 0x5f19, 0x106c: 0x5f49, 0x106d: 0x5f79, 0x106e: 0x5fa9, 0x106f: 0x5fd9,\n\t0x1070: 0x6009, 0x1071: 0x402d, 0x1072: 0x6039, 0x1073: 0x6051, 0x1074: 0x404d, 0x1075: 0x6069,\n\t0x1076: 0x6081, 0x1077: 0x6099, 0x1078: 0x406d, 0x1079: 0x406d, 0x107a: 0x60b1, 0x107b: 0x60c9,\n\t0x107c: 0x6101, 0x107d: 0x6139, 0x107e: 0x6171, 0x107f: 0x61a9,\n\t// Block 0x42, offset 0x1080\n\t0x1080: 0x6211, 0x1081: 0x6229, 0x1082: 0x408d, 0x1083: 0x6241, 0x1084: 0x6259, 0x1085: 0x6271,\n\t0x1086: 0x6289, 0x1087: 0x62a1, 0x1088: 0x40ad, 0x1089: 0x62b9, 0x108a: 0x62e1, 0x108b: 0x62f9,\n\t0x108c: 0x40cd, 0x108d: 0x40cd, 0x108e: 0x6311, 0x108f: 0x6329, 0x1090: 0x6341, 0x1091: 0x40ed,\n\t0x1092: 0x410d, 0x1093: 0x412d, 0x1094: 0x414d, 0x1095: 0x416d, 0x1096: 0x6359, 0x1097: 0x6371,\n\t0x1098: 0x6389, 0x1099: 0x63a1, 0x109a: 0x63b9, 0x109b: 0x418d, 0x109c: 0x63d1, 0x109d: 0x63e9,\n\t0x109e: 0x6401, 0x109f: 0x41ad, 0x10a0: 0x41cd, 0x10a1: 0x6419, 0x10a2: 0x41ed, 0x10a3: 0x420d,\n\t0x10a4: 0x422d, 0x10a5: 0x6431, 0x10a6: 0x424d, 0x10a7: 0x6449, 0x10a8: 0x6479, 0x10a9: 0x6211,\n\t0x10aa: 0x426d, 0x10ab: 0x428d, 0x10ac: 0x42ad, 0x10ad: 0x42cd, 0x10ae: 0x64b1, 0x10af: 0x64f1,\n\t0x10b0: 0x6539, 0x10b1: 0x6551, 0x10b2: 0x42ed, 0x10b3: 0x6569, 0x10b4: 0x6581, 0x10b5: 0x6599,\n\t0x10b6: 0x430d, 0x10b7: 0x65b1, 0x10b8: 0x65c9, 0x10b9: 0x65b1, 0x10ba: 0x65e1, 0x10bb: 0x65f9,\n\t0x10bc: 0x432d, 0x10bd: 0x6611, 0x10be: 0x6629, 0x10bf: 0x6611,\n\t// Block 0x43, offset 0x10c0\n\t0x10c0: 0x434d, 0x10c1: 0x436d, 0x10c2: 0x0040, 0x10c3: 0x6641, 0x10c4: 0x6659, 0x10c5: 0x6671,\n\t0x10c6: 0x6689, 0x10c7: 0x0040, 0x10c8: 0x66c1, 0x10c9: 0x66d9, 0x10ca: 0x66f1, 0x10cb: 0x6709,\n\t0x10cc: 0x6721, 0x10cd: 0x6739, 0x10ce: 0x6401, 0x10cf: 0x6751, 0x10d0: 0x6769, 0x10d1: 0x6781,\n\t0x10d2: 0x438d, 0x10d3: 0x6799, 0x10d4: 0x6289, 0x10d5: 0x43ad, 0x10d6: 0x43cd, 0x10d7: 0x67b1,\n\t0x10d8: 0x0040, 0x10d9: 0x43ed, 0x10da: 0x67c9, 0x10db: 0x67e1, 0x10dc: 0x67f9, 0x10dd: 0x6811,\n\t0x10de: 0x6829, 0x10df: 0x6859, 0x10e0: 0x6889, 0x10e1: 0x68b1, 0x10e2: 0x68d9, 0x10e3: 0x6901,\n\t0x10e4: 0x6929, 0x10e5: 0x6951, 0x10e6: 0x6979, 0x10e7: 0x69a1, 0x10e8: 0x69c9, 0x10e9: 0x69f1,\n\t0x10ea: 0x6a21, 0x10eb: 0x6a51, 0x10ec: 0x6a81, 0x10ed: 0x6ab1, 0x10ee: 0x6ae1, 0x10ef: 0x6b11,\n\t0x10f0: 0x6b41, 0x10f1: 0x6b71, 0x10f2: 0x6ba1, 0x10f3: 0x6bd1, 0x10f4: 0x6c01, 0x10f5: 0x6c31,\n\t0x10f6: 0x6c61, 0x10f7: 0x6c91, 0x10f8: 0x6cc1, 0x10f9: 0x6cf1, 0x10fa: 0x6d21, 0x10fb: 0x6d51,\n\t0x10fc: 0x6d81, 0x10fd: 0x6db1, 0x10fe: 0x6de1, 0x10ff: 0x440d,\n\t// Block 0x44, offset 0x1100\n\t0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008,\n\t0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008,\n\t0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008,\n\t0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008,\n\t0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0xe00d, 0x111d: 0x0008,\n\t0x111e: 0xe00d, 0x111f: 0x0008, 0x1120: 0xe00d, 0x1121: 0x0008, 0x1122: 0xe00d, 0x1123: 0x0008,\n\t0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008,\n\t0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x3308,\n\t0x1130: 0x3318, 0x1131: 0x3318, 0x1132: 0x3318, 0x1133: 0x0018, 0x1134: 0x3308, 0x1135: 0x3308,\n\t0x1136: 0x3308, 0x1137: 0x3308, 0x1138: 0x3308, 0x1139: 0x3308, 0x113a: 0x3308, 0x113b: 0x3308,\n\t0x113c: 0x3308, 0x113d: 0x3308, 0x113e: 0x0018, 0x113f: 0x0008,\n\t// Block 0x45, offset 0x1140\n\t0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008,\n\t0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008,\n\t0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008,\n\t0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008,\n\t0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0x0ea1, 0x115d: 0x6e11,\n\t0x115e: 0x3308, 0x115f: 0x3308, 0x1160: 0x0008, 0x1161: 0x0008, 0x1162: 0x0008, 0x1163: 0x0008,\n\t0x1164: 0x0008, 0x1165: 0x0008, 0x1166: 0x0008, 0x1167: 0x0008, 0x1168: 0x0008, 0x1169: 0x0008,\n\t0x116a: 0x0008, 0x116b: 0x0008, 0x116c: 0x0008, 0x116d: 0x0008, 0x116e: 0x0008, 0x116f: 0x0008,\n\t0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008,\n\t0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0x0008, 0x117a: 0x0008, 0x117b: 0x0008,\n\t0x117c: 0x0008, 0x117d: 0x0008, 0x117e: 0x0008, 0x117f: 0x0008,\n\t// Block 0x46, offset 0x1180\n\t0x1180: 0x0018, 0x1181: 0x0018, 0x1182: 0x0018, 0x1183: 0x0018, 0x1184: 0x0018, 0x1185: 0x0018,\n\t0x1186: 0x0018, 0x1187: 0x0018, 0x1188: 0x0018, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0x0018,\n\t0x118c: 0x0018, 0x118d: 0x0018, 0x118e: 0x0018, 0x118f: 0x0018, 0x1190: 0x0018, 0x1191: 0x0018,\n\t0x1192: 0x0018, 0x1193: 0x0018, 0x1194: 0x0018, 0x1195: 0x0018, 0x1196: 0x0018, 0x1197: 0x0008,\n\t0x1198: 0x0008, 0x1199: 0x0008, 0x119a: 0x0008, 0x119b: 0x0008, 0x119c: 0x0008, 0x119d: 0x0008,\n\t0x119e: 0x0008, 0x119f: 0x0008, 0x11a0: 0x0018, 0x11a1: 0x0018, 0x11a2: 0xe00d, 0x11a3: 0x0008,\n\t0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008,\n\t0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008,\n\t0x11b0: 0x0008, 0x11b1: 0x0008, 0x11b2: 0xe00d, 0x11b3: 0x0008, 0x11b4: 0xe00d, 0x11b5: 0x0008,\n\t0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0xe00d, 0x11b9: 0x0008, 0x11ba: 0xe00d, 0x11bb: 0x0008,\n\t0x11bc: 0xe00d, 0x11bd: 0x0008, 0x11be: 0xe00d, 0x11bf: 0x0008,\n\t// Block 0x47, offset 0x11c0\n\t0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008,\n\t0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0xe00d, 0x11c9: 0x0008, 0x11ca: 0xe00d, 0x11cb: 0x0008,\n\t0x11cc: 0xe00d, 0x11cd: 0x0008, 0x11ce: 0xe00d, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008,\n\t0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0xe00d, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008,\n\t0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008,\n\t0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008,\n\t0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008,\n\t0x11ea: 0xe00d, 0x11eb: 0x0008, 0x11ec: 0xe00d, 0x11ed: 0x0008, 0x11ee: 0xe00d, 0x11ef: 0x0008,\n\t0x11f0: 0xe0fd, 0x11f1: 0x0008, 0x11f2: 0x0008, 0x11f3: 0x0008, 0x11f4: 0x0008, 0x11f5: 0x0008,\n\t0x11f6: 0x0008, 0x11f7: 0x0008, 0x11f8: 0x0008, 0x11f9: 0xe01d, 0x11fa: 0x0008, 0x11fb: 0xe03d,\n\t0x11fc: 0x0008, 0x11fd: 0x442d, 0x11fe: 0xe00d, 0x11ff: 0x0008,\n\t// Block 0x48, offset 0x1200\n\t0x1200: 0xe00d, 0x1201: 0x0008, 0x1202: 0xe00d, 0x1203: 0x0008, 0x1204: 0xe00d, 0x1205: 0x0008,\n\t0x1206: 0xe00d, 0x1207: 0x0008, 0x1208: 0x0008, 0x1209: 0x0018, 0x120a: 0x0018, 0x120b: 0xe03d,\n\t0x120c: 0x0008, 0x120d: 0x11d9, 0x120e: 0x0008, 0x120f: 0x0008, 0x1210: 0xe00d, 0x1211: 0x0008,\n\t0x1212: 0xe00d, 0x1213: 0x0008, 0x1214: 0x0008, 0x1215: 0x0008, 0x1216: 0xe00d, 0x1217: 0x0008,\n\t0x1218: 0xe00d, 0x1219: 0x0008, 0x121a: 0xe00d, 0x121b: 0x0008, 0x121c: 0xe00d, 0x121d: 0x0008,\n\t0x121e: 0xe00d, 0x121f: 0x0008, 0x1220: 0xe00d, 0x1221: 0x0008, 0x1222: 0xe00d, 0x1223: 0x0008,\n\t0x1224: 0xe00d, 0x1225: 0x0008, 0x1226: 0xe00d, 0x1227: 0x0008, 0x1228: 0xe00d, 0x1229: 0x0008,\n\t0x122a: 0x6e29, 0x122b: 0x1029, 0x122c: 0x11c1, 0x122d: 0x6e41, 0x122e: 0x1221, 0x122f: 0x0040,\n\t0x1230: 0x6e59, 0x1231: 0x6e71, 0x1232: 0x1239, 0x1233: 0x444d, 0x1234: 0xe00d, 0x1235: 0x0008,\n\t0x1236: 0xe00d, 0x1237: 0x0008, 0x1238: 0x0040, 0x1239: 0x0040, 0x123a: 0x0040, 0x123b: 0x0040,\n\t0x123c: 0x0040, 0x123d: 0x0040, 0x123e: 0x0040, 0x123f: 0x0040,\n\t// Block 0x49, offset 0x1240\n\t0x1240: 0x64d5, 0x1241: 0x64f5, 0x1242: 0x6515, 0x1243: 0x6535, 0x1244: 0x6555, 0x1245: 0x6575,\n\t0x1246: 0x6595, 0x1247: 0x65b5, 0x1248: 0x65d5, 0x1249: 0x65f5, 0x124a: 0x6615, 0x124b: 0x6635,\n\t0x124c: 0x6655, 0x124d: 0x6675, 0x124e: 0x0008, 0x124f: 0x0008, 0x1250: 0x6695, 0x1251: 0x0008,\n\t0x1252: 0x66b5, 0x1253: 0x0008, 0x1254: 0x0008, 0x1255: 0x66d5, 0x1256: 0x66f5, 0x1257: 0x6715,\n\t0x1258: 0x6735, 0x1259: 0x6755, 0x125a: 0x6775, 0x125b: 0x6795, 0x125c: 0x67b5, 0x125d: 0x67d5,\n\t0x125e: 0x67f5, 0x125f: 0x0008, 0x1260: 0x6815, 0x1261: 0x0008, 0x1262: 0x6835, 0x1263: 0x0008,\n\t0x1264: 0x0008, 0x1265: 0x6855, 0x1266: 0x6875, 0x1267: 0x0008, 0x1268: 0x0008, 0x1269: 0x0008,\n\t0x126a: 0x6895, 0x126b: 0x68b5, 0x126c: 0x68d5, 0x126d: 0x68f5, 0x126e: 0x6915, 0x126f: 0x6935,\n\t0x1270: 0x6955, 0x1271: 0x6975, 0x1272: 0x6995, 0x1273: 0x69b5, 0x1274: 0x69d5, 0x1275: 0x69f5,\n\t0x1276: 0x6a15, 0x1277: 0x6a35, 0x1278: 0x6a55, 0x1279: 0x6a75, 0x127a: 0x6a95, 0x127b: 0x6ab5,\n\t0x127c: 0x6ad5, 0x127d: 0x6af5, 0x127e: 0x6b15, 0x127f: 0x6b35,\n\t// Block 0x4a, offset 0x1280\n\t0x1280: 0x7a95, 0x1281: 0x7ab5, 0x1282: 0x7ad5, 0x1283: 0x7af5, 0x1284: 0x7b15, 0x1285: 0x7b35,\n\t0x1286: 0x7b55, 0x1287: 0x7b75, 0x1288: 0x7b95, 0x1289: 0x7bb5, 0x128a: 0x7bd5, 0x128b: 0x7bf5,\n\t0x128c: 0x7c15, 0x128d: 0x7c35, 0x128e: 0x7c55, 0x128f: 0x6ec9, 0x1290: 0x6ef1, 0x1291: 0x6f19,\n\t0x1292: 0x7c75, 0x1293: 0x7c95, 0x1294: 0x7cb5, 0x1295: 0x6f41, 0x1296: 0x6f69, 0x1297: 0x6f91,\n\t0x1298: 0x7cd5, 0x1299: 0x7cf5, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x0040,\n\t0x129e: 0x0040, 0x129f: 0x0040, 0x12a0: 0x0040, 0x12a1: 0x0040, 0x12a2: 0x0040, 0x12a3: 0x0040,\n\t0x12a4: 0x0040, 0x12a5: 0x0040, 0x12a6: 0x0040, 0x12a7: 0x0040, 0x12a8: 0x0040, 0x12a9: 0x0040,\n\t0x12aa: 0x0040, 0x12ab: 0x0040, 0x12ac: 0x0040, 0x12ad: 0x0040, 0x12ae: 0x0040, 0x12af: 0x0040,\n\t0x12b0: 0x0040, 0x12b1: 0x0040, 0x12b2: 0x0040, 0x12b3: 0x0040, 0x12b4: 0x0040, 0x12b5: 0x0040,\n\t0x12b6: 0x0040, 0x12b7: 0x0040, 0x12b8: 0x0040, 0x12b9: 0x0040, 0x12ba: 0x0040, 0x12bb: 0x0040,\n\t0x12bc: 0x0040, 0x12bd: 0x0040, 0x12be: 0x0040, 0x12bf: 0x0040,\n\t// Block 0x4b, offset 0x12c0\n\t0x12c0: 0x6fb9, 0x12c1: 0x6fd1, 0x12c2: 0x6fe9, 0x12c3: 0x7d15, 0x12c4: 0x7d35, 0x12c5: 0x7001,\n\t0x12c6: 0x7001, 0x12c7: 0x0040, 0x12c8: 0x0040, 0x12c9: 0x0040, 0x12ca: 0x0040, 0x12cb: 0x0040,\n\t0x12cc: 0x0040, 0x12cd: 0x0040, 0x12ce: 0x0040, 0x12cf: 0x0040, 0x12d0: 0x0040, 0x12d1: 0x0040,\n\t0x12d2: 0x0040, 0x12d3: 0x7019, 0x12d4: 0x7041, 0x12d5: 0x7069, 0x12d6: 0x7091, 0x12d7: 0x70b9,\n\t0x12d8: 0x0040, 0x12d9: 0x0040, 0x12da: 0x0040, 0x12db: 0x0040, 0x12dc: 0x0040, 0x12dd: 0x70e1,\n\t0x12de: 0x3308, 0x12df: 0x7109, 0x12e0: 0x7131, 0x12e1: 0x20a9, 0x12e2: 0x20f1, 0x12e3: 0x7149,\n\t0x12e4: 0x7161, 0x12e5: 0x7179, 0x12e6: 0x7191, 0x12e7: 0x71a9, 0x12e8: 0x71c1, 0x12e9: 0x1fb2,\n\t0x12ea: 0x71d9, 0x12eb: 0x7201, 0x12ec: 0x7229, 0x12ed: 0x7261, 0x12ee: 0x7299, 0x12ef: 0x72c1,\n\t0x12f0: 0x72e9, 0x12f1: 0x7311, 0x12f2: 0x7339, 0x12f3: 0x7361, 0x12f4: 0x7389, 0x12f5: 0x73b1,\n\t0x12f6: 0x73d9, 0x12f7: 0x0040, 0x12f8: 0x7401, 0x12f9: 0x7429, 0x12fa: 0x7451, 0x12fb: 0x7479,\n\t0x12fc: 0x74a1, 0x12fd: 0x0040, 0x12fe: 0x74c9, 0x12ff: 0x0040,\n\t// Block 0x4c, offset 0x1300\n\t0x1300: 0x74f1, 0x1301: 0x7519, 0x1302: 0x0040, 0x1303: 0x7541, 0x1304: 0x7569, 0x1305: 0x0040,\n\t0x1306: 0x7591, 0x1307: 0x75b9, 0x1308: 0x75e1, 0x1309: 0x7609, 0x130a: 0x7631, 0x130b: 0x7659,\n\t0x130c: 0x7681, 0x130d: 0x76a9, 0x130e: 0x76d1, 0x130f: 0x76f9, 0x1310: 0x7721, 0x1311: 0x7721,\n\t0x1312: 0x7739, 0x1313: 0x7739, 0x1314: 0x7739, 0x1315: 0x7739, 0x1316: 0x7751, 0x1317: 0x7751,\n\t0x1318: 0x7751, 0x1319: 0x7751, 0x131a: 0x7769, 0x131b: 0x7769, 0x131c: 0x7769, 0x131d: 0x7769,\n\t0x131e: 0x7781, 0x131f: 0x7781, 0x1320: 0x7781, 0x1321: 0x7781, 0x1322: 0x7799, 0x1323: 0x7799,\n\t0x1324: 0x7799, 0x1325: 0x7799, 0x1326: 0x77b1, 0x1327: 0x77b1, 0x1328: 0x77b1, 0x1329: 0x77b1,\n\t0x132a: 0x77c9, 0x132b: 0x77c9, 0x132c: 0x77c9, 0x132d: 0x77c9, 0x132e: 0x77e1, 0x132f: 0x77e1,\n\t0x1330: 0x77e1, 0x1331: 0x77e1, 0x1332: 0x77f9, 0x1333: 0x77f9, 0x1334: 0x77f9, 0x1335: 0x77f9,\n\t0x1336: 0x7811, 0x1337: 0x7811, 0x1338: 0x7811, 0x1339: 0x7811, 0x133a: 0x7829, 0x133b: 0x7829,\n\t0x133c: 0x7829, 0x133d: 0x7829, 0x133e: 0x7841, 0x133f: 0x7841,\n\t// Block 0x4d, offset 0x1340\n\t0x1340: 0x7841, 0x1341: 0x7841, 0x1342: 0x7859, 0x1343: 0x7859, 0x1344: 0x7871, 0x1345: 0x7871,\n\t0x1346: 0x7889, 0x1347: 0x7889, 0x1348: 0x78a1, 0x1349: 0x78a1, 0x134a: 0x78b9, 0x134b: 0x78b9,\n\t0x134c: 0x78d1, 0x134d: 0x78d1, 0x134e: 0x78e9, 0x134f: 0x78e9, 0x1350: 0x78e9, 0x1351: 0x78e9,\n\t0x1352: 0x7901, 0x1353: 0x7901, 0x1354: 0x7901, 0x1355: 0x7901, 0x1356: 0x7919, 0x1357: 0x7919,\n\t0x1358: 0x7919, 0x1359: 0x7919, 0x135a: 0x7931, 0x135b: 0x7931, 0x135c: 0x7931, 0x135d: 0x7931,\n\t0x135e: 0x7949, 0x135f: 0x7949, 0x1360: 0x7961, 0x1361: 0x7961, 0x1362: 0x7961, 0x1363: 0x7961,\n\t0x1364: 0x7979, 0x1365: 0x7979, 0x1366: 0x7991, 0x1367: 0x7991, 0x1368: 0x7991, 0x1369: 0x7991,\n\t0x136a: 0x79a9, 0x136b: 0x79a9, 0x136c: 0x79a9, 0x136d: 0x79a9, 0x136e: 0x79c1, 0x136f: 0x79c1,\n\t0x1370: 0x79d9, 0x1371: 0x79d9, 0x1372: 0x0818, 0x1373: 0x0818, 0x1374: 0x0818, 0x1375: 0x0818,\n\t0x1376: 0x0818, 0x1377: 0x0818, 0x1378: 0x0818, 0x1379: 0x0818, 0x137a: 0x0818, 0x137b: 0x0818,\n\t0x137c: 0x0818, 0x137d: 0x0818, 0x137e: 0x0818, 0x137f: 0x0818,\n\t// Block 0x4e, offset 0x1380\n\t0x1380: 0x0818, 0x1381: 0x0818, 0x1382: 0x0040, 0x1383: 0x0040, 0x1384: 0x0040, 0x1385: 0x0040,\n\t0x1386: 0x0040, 0x1387: 0x0040, 0x1388: 0x0040, 0x1389: 0x0040, 0x138a: 0x0040, 0x138b: 0x0040,\n\t0x138c: 0x0040, 0x138d: 0x0040, 0x138e: 0x0040, 0x138f: 0x0040, 0x1390: 0x0040, 0x1391: 0x0040,\n\t0x1392: 0x0040, 0x1393: 0x79f1, 0x1394: 0x79f1, 0x1395: 0x79f1, 0x1396: 0x79f1, 0x1397: 0x7a09,\n\t0x1398: 0x7a09, 0x1399: 0x7a21, 0x139a: 0x7a21, 0x139b: 0x7a39, 0x139c: 0x7a39, 0x139d: 0x0479,\n\t0x139e: 0x7a51, 0x139f: 0x7a51, 0x13a0: 0x7a69, 0x13a1: 0x7a69, 0x13a2: 0x7a81, 0x13a3: 0x7a81,\n\t0x13a4: 0x7a99, 0x13a5: 0x7a99, 0x13a6: 0x7a99, 0x13a7: 0x7a99, 0x13a8: 0x7ab1, 0x13a9: 0x7ab1,\n\t0x13aa: 0x7ac9, 0x13ab: 0x7ac9, 0x13ac: 0x7af1, 0x13ad: 0x7af1, 0x13ae: 0x7b19, 0x13af: 0x7b19,\n\t0x13b0: 0x7b41, 0x13b1: 0x7b41, 0x13b2: 0x7b69, 0x13b3: 0x7b69, 0x13b4: 0x7b91, 0x13b5: 0x7b91,\n\t0x13b6: 0x7bb9, 0x13b7: 0x7bb9, 0x13b8: 0x7bb9, 0x13b9: 0x7be1, 0x13ba: 0x7be1, 0x13bb: 0x7be1,\n\t0x13bc: 0x7c09, 0x13bd: 0x7c09, 0x13be: 0x7c09, 0x13bf: 0x7c09,\n\t// Block 0x4f, offset 0x13c0\n\t0x13c0: 0x85f9, 0x13c1: 0x8621, 0x13c2: 0x8649, 0x13c3: 0x8671, 0x13c4: 0x8699, 0x13c5: 0x86c1,\n\t0x13c6: 0x86e9, 0x13c7: 0x8711, 0x13c8: 0x8739, 0x13c9: 0x8761, 0x13ca: 0x8789, 0x13cb: 0x87b1,\n\t0x13cc: 0x87d9, 0x13cd: 0x8801, 0x13ce: 0x8829, 0x13cf: 0x8851, 0x13d0: 0x8879, 0x13d1: 0x88a1,\n\t0x13d2: 0x88c9, 0x13d3: 0x88f1, 0x13d4: 0x8919, 0x13d5: 0x8941, 0x13d6: 0x8969, 0x13d7: 0x8991,\n\t0x13d8: 0x89b9, 0x13d9: 0x89e1, 0x13da: 0x8a09, 0x13db: 0x8a31, 0x13dc: 0x8a59, 0x13dd: 0x8a81,\n\t0x13de: 0x8aaa, 0x13df: 0x8ada, 0x13e0: 0x8b0a, 0x13e1: 0x8b3a, 0x13e2: 0x8b6a, 0x13e3: 0x8b9a,\n\t0x13e4: 0x8bc9, 0x13e5: 0x8bf1, 0x13e6: 0x7c71, 0x13e7: 0x8c19, 0x13e8: 0x7be1, 0x13e9: 0x7c99,\n\t0x13ea: 0x8c41, 0x13eb: 0x8c69, 0x13ec: 0x7d39, 0x13ed: 0x8c91, 0x13ee: 0x7d61, 0x13ef: 0x7d89,\n\t0x13f0: 0x8cb9, 0x13f1: 0x8ce1, 0x13f2: 0x7e29, 0x13f3: 0x8d09, 0x13f4: 0x7e51, 0x13f5: 0x7e79,\n\t0x13f6: 0x8d31, 0x13f7: 0x8d59, 0x13f8: 0x7ec9, 0x13f9: 0x8d81, 0x13fa: 0x7ef1, 0x13fb: 0x7f19,\n\t0x13fc: 0x83a1, 0x13fd: 0x83c9, 0x13fe: 0x8441, 0x13ff: 0x8469,\n\t// Block 0x50, offset 0x1400\n\t0x1400: 0x8491, 0x1401: 0x8531, 0x1402: 0x8559, 0x1403: 0x8581, 0x1404: 0x85a9, 0x1405: 0x8649,\n\t0x1406: 0x8671, 0x1407: 0x8699, 0x1408: 0x8da9, 0x1409: 0x8739, 0x140a: 0x8dd1, 0x140b: 0x8df9,\n\t0x140c: 0x8829, 0x140d: 0x8e21, 0x140e: 0x8851, 0x140f: 0x8879, 0x1410: 0x8a81, 0x1411: 0x8e49,\n\t0x1412: 0x8e71, 0x1413: 0x89b9, 0x1414: 0x8e99, 0x1415: 0x89e1, 0x1416: 0x8a09, 0x1417: 0x7c21,\n\t0x1418: 0x7c49, 0x1419: 0x8ec1, 0x141a: 0x7c71, 0x141b: 0x8ee9, 0x141c: 0x7cc1, 0x141d: 0x7ce9,\n\t0x141e: 0x7d11, 0x141f: 0x7d39, 0x1420: 0x8f11, 0x1421: 0x7db1, 0x1422: 0x7dd9, 0x1423: 0x7e01,\n\t0x1424: 0x7e29, 0x1425: 0x8f39, 0x1426: 0x7ec9, 0x1427: 0x7f41, 0x1428: 0x7f69, 0x1429: 0x7f91,\n\t0x142a: 0x7fb9, 0x142b: 0x7fe1, 0x142c: 0x8031, 0x142d: 0x8059, 0x142e: 0x8081, 0x142f: 0x80a9,\n\t0x1430: 0x80d1, 0x1431: 0x80f9, 0x1432: 0x8f61, 0x1433: 0x8121, 0x1434: 0x8149, 0x1435: 0x8171,\n\t0x1436: 0x8199, 0x1437: 0x81c1, 0x1438: 0x81e9, 0x1439: 0x8239, 0x143a: 0x8261, 0x143b: 0x8289,\n\t0x143c: 0x82b1, 0x143d: 0x82d9, 0x143e: 0x8301, 0x143f: 0x8329,\n\t// Block 0x51, offset 0x1440\n\t0x1440: 0x8351, 0x1441: 0x8379, 0x1442: 0x83f1, 0x1443: 0x8419, 0x1444: 0x84b9, 0x1445: 0x84e1,\n\t0x1446: 0x8509, 0x1447: 0x8531, 0x1448: 0x8559, 0x1449: 0x85d1, 0x144a: 0x85f9, 0x144b: 0x8621,\n\t0x144c: 0x8649, 0x144d: 0x8f89, 0x144e: 0x86c1, 0x144f: 0x86e9, 0x1450: 0x8711, 0x1451: 0x8739,\n\t0x1452: 0x87b1, 0x1453: 0x87d9, 0x1454: 0x8801, 0x1455: 0x8829, 0x1456: 0x8fb1, 0x1457: 0x88a1,\n\t0x1458: 0x88c9, 0x1459: 0x8fd9, 0x145a: 0x8941, 0x145b: 0x8969, 0x145c: 0x8991, 0x145d: 0x89b9,\n\t0x145e: 0x9001, 0x145f: 0x7c71, 0x1460: 0x8ee9, 0x1461: 0x7d39, 0x1462: 0x8f11, 0x1463: 0x7e29,\n\t0x1464: 0x8f39, 0x1465: 0x7ec9, 0x1466: 0x9029, 0x1467: 0x80d1, 0x1468: 0x9051, 0x1469: 0x9079,\n\t0x146a: 0x90a1, 0x146b: 0x8531, 0x146c: 0x8559, 0x146d: 0x8649, 0x146e: 0x8829, 0x146f: 0x8fb1,\n\t0x1470: 0x89b9, 0x1471: 0x9001, 0x1472: 0x90c9, 0x1473: 0x9101, 0x1474: 0x9139, 0x1475: 0x9171,\n\t0x1476: 0x9199, 0x1477: 0x91c1, 0x1478: 0x91e9, 0x1479: 0x9211, 0x147a: 0x9239, 0x147b: 0x9261,\n\t0x147c: 0x9289, 0x147d: 0x92b1, 0x147e: 0x92d9, 0x147f: 0x9301,\n\t// Block 0x52, offset 0x1480\n\t0x1480: 0x9329, 0x1481: 0x9351, 0x1482: 0x9379, 0x1483: 0x93a1, 0x1484: 0x93c9, 0x1485: 0x93f1,\n\t0x1486: 0x9419, 0x1487: 0x9441, 0x1488: 0x9469, 0x1489: 0x9491, 0x148a: 0x94b9, 0x148b: 0x94e1,\n\t0x148c: 0x9079, 0x148d: 0x9509, 0x148e: 0x9531, 0x148f: 0x9559, 0x1490: 0x9581, 0x1491: 0x9171,\n\t0x1492: 0x9199, 0x1493: 0x91c1, 0x1494: 0x91e9, 0x1495: 0x9211, 0x1496: 0x9239, 0x1497: 0x9261,\n\t0x1498: 0x9289, 0x1499: 0x92b1, 0x149a: 0x92d9, 0x149b: 0x9301, 0x149c: 0x9329, 0x149d: 0x9351,\n\t0x149e: 0x9379, 0x149f: 0x93a1, 0x14a0: 0x93c9, 0x14a1: 0x93f1, 0x14a2: 0x9419, 0x14a3: 0x9441,\n\t0x14a4: 0x9469, 0x14a5: 0x9491, 0x14a6: 0x94b9, 0x14a7: 0x94e1, 0x14a8: 0x9079, 0x14a9: 0x9509,\n\t0x14aa: 0x9531, 0x14ab: 0x9559, 0x14ac: 0x9581, 0x14ad: 0x9491, 0x14ae: 0x94b9, 0x14af: 0x94e1,\n\t0x14b0: 0x9079, 0x14b1: 0x9051, 0x14b2: 0x90a1, 0x14b3: 0x8211, 0x14b4: 0x8059, 0x14b5: 0x8081,\n\t0x14b6: 0x80a9, 0x14b7: 0x9491, 0x14b8: 0x94b9, 0x14b9: 0x94e1, 0x14ba: 0x8211, 0x14bb: 0x8239,\n\t0x14bc: 0x95a9, 0x14bd: 0x95a9, 0x14be: 0x0018, 0x14bf: 0x0018,\n\t// Block 0x53, offset 0x14c0\n\t0x14c0: 0x0040, 0x14c1: 0x0040, 0x14c2: 0x0040, 0x14c3: 0x0040, 0x14c4: 0x0040, 0x14c5: 0x0040,\n\t0x14c6: 0x0040, 0x14c7: 0x0040, 0x14c8: 0x0040, 0x14c9: 0x0040, 0x14ca: 0x0040, 0x14cb: 0x0040,\n\t0x14cc: 0x0040, 0x14cd: 0x0040, 0x14ce: 0x0040, 0x14cf: 0x0040, 0x14d0: 0x95d1, 0x14d1: 0x9609,\n\t0x14d2: 0x9609, 0x14d3: 0x9641, 0x14d4: 0x9679, 0x14d5: 0x96b1, 0x14d6: 0x96e9, 0x14d7: 0x9721,\n\t0x14d8: 0x9759, 0x14d9: 0x9759, 0x14da: 0x9791, 0x14db: 0x97c9, 0x14dc: 0x9801, 0x14dd: 0x9839,\n\t0x14de: 0x9871, 0x14df: 0x98a9, 0x14e0: 0x98a9, 0x14e1: 0x98e1, 0x14e2: 0x9919, 0x14e3: 0x9919,\n\t0x14e4: 0x9951, 0x14e5: 0x9951, 0x14e6: 0x9989, 0x14e7: 0x99c1, 0x14e8: 0x99c1, 0x14e9: 0x99f9,\n\t0x14ea: 0x9a31, 0x14eb: 0x9a31, 0x14ec: 0x9a69, 0x14ed: 0x9a69, 0x14ee: 0x9aa1, 0x14ef: 0x9ad9,\n\t0x14f0: 0x9ad9, 0x14f1: 0x9b11, 0x14f2: 0x9b11, 0x14f3: 0x9b49, 0x14f4: 0x9b81, 0x14f5: 0x9bb9,\n\t0x14f6: 0x9bf1, 0x14f7: 0x9bf1, 0x14f8: 0x9c29, 0x14f9: 0x9c61, 0x14fa: 0x9c99, 0x14fb: 0x9cd1,\n\t0x14fc: 0x9d09, 0x14fd: 0x9d09, 0x14fe: 0x9d41, 0x14ff: 0x9d79,\n\t// Block 0x54, offset 0x1500\n\t0x1500: 0xa949, 0x1501: 0xa981, 0x1502: 0xa9b9, 0x1503: 0xa8a1, 0x1504: 0x9bb9, 0x1505: 0x9989,\n\t0x1506: 0xa9f1, 0x1507: 0xaa29, 0x1508: 0x0040, 0x1509: 0x0040, 0x150a: 0x0040, 0x150b: 0x0040,\n\t0x150c: 0x0040, 0x150d: 0x0040, 0x150e: 0x0040, 0x150f: 0x0040, 0x1510: 0x0040, 0x1511: 0x0040,\n\t0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x0040, 0x1515: 0x0040, 0x1516: 0x0040, 0x1517: 0x0040,\n\t0x1518: 0x0040, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040,\n\t0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x0040, 0x1521: 0x0040, 0x1522: 0x0040, 0x1523: 0x0040,\n\t0x1524: 0x0040, 0x1525: 0x0040, 0x1526: 0x0040, 0x1527: 0x0040, 0x1528: 0x0040, 0x1529: 0x0040,\n\t0x152a: 0x0040, 0x152b: 0x0040, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040,\n\t0x1530: 0xaa61, 0x1531: 0xaa99, 0x1532: 0xaad1, 0x1533: 0xab19, 0x1534: 0xab61, 0x1535: 0xaba9,\n\t0x1536: 0xabf1, 0x1537: 0xac39, 0x1538: 0xac81, 0x1539: 0xacc9, 0x153a: 0xad02, 0x153b: 0xae12,\n\t0x153c: 0xae91, 0x153d: 0x0018, 0x153e: 0x0040, 0x153f: 0x0040,\n\t// Block 0x55, offset 0x1540\n\t0x1540: 0x33c0, 0x1541: 0x33c0, 0x1542: 0x33c0, 0x1543: 0x33c0, 0x1544: 0x33c0, 0x1545: 0x33c0,\n\t0x1546: 0x33c0, 0x1547: 0x33c0, 0x1548: 0x33c0, 0x1549: 0x33c0, 0x154a: 0x33c0, 0x154b: 0x33c0,\n\t0x154c: 0x33c0, 0x154d: 0x33c0, 0x154e: 0x33c0, 0x154f: 0x33c0, 0x1550: 0xaeda, 0x1551: 0x7d55,\n\t0x1552: 0x0040, 0x1553: 0xaeea, 0x1554: 0x03c2, 0x1555: 0xaefa, 0x1556: 0xaf0a, 0x1557: 0x7d75,\n\t0x1558: 0x7d95, 0x1559: 0x0040, 0x155a: 0x0040, 0x155b: 0x0040, 0x155c: 0x0040, 0x155d: 0x0040,\n\t0x155e: 0x0040, 0x155f: 0x0040, 0x1560: 0x3308, 0x1561: 0x3308, 0x1562: 0x3308, 0x1563: 0x3308,\n\t0x1564: 0x3308, 0x1565: 0x3308, 0x1566: 0x3308, 0x1567: 0x3308, 0x1568: 0x3308, 0x1569: 0x3308,\n\t0x156a: 0x3308, 0x156b: 0x3308, 0x156c: 0x3308, 0x156d: 0x3308, 0x156e: 0x3308, 0x156f: 0x3308,\n\t0x1570: 0x0040, 0x1571: 0x7db5, 0x1572: 0x7dd5, 0x1573: 0xaf1a, 0x1574: 0xaf1a, 0x1575: 0x1fd2,\n\t0x1576: 0x1fe2, 0x1577: 0xaf2a, 0x1578: 0xaf3a, 0x1579: 0x7df5, 0x157a: 0x7e15, 0x157b: 0x7e35,\n\t0x157c: 0x7df5, 0x157d: 0x7e55, 0x157e: 0x7e75, 0x157f: 0x7e55,\n\t// Block 0x56, offset 0x1580\n\t0x1580: 0x7e95, 0x1581: 0x7eb5, 0x1582: 0x7ed5, 0x1583: 0x7eb5, 0x1584: 0x7ef5, 0x1585: 0x0018,\n\t0x1586: 0x0018, 0x1587: 0xaf4a, 0x1588: 0xaf5a, 0x1589: 0x7f16, 0x158a: 0x7f36, 0x158b: 0x7f56,\n\t0x158c: 0x7f76, 0x158d: 0xaf1a, 0x158e: 0xaf1a, 0x158f: 0xaf1a, 0x1590: 0xaeda, 0x1591: 0x7f95,\n\t0x1592: 0x0040, 0x1593: 0x0040, 0x1594: 0x03c2, 0x1595: 0xaeea, 0x1596: 0xaf0a, 0x1597: 0xaefa,\n\t0x1598: 0x7fb5, 0x1599: 0x1fd2, 0x159a: 0x1fe2, 0x159b: 0xaf2a, 0x159c: 0xaf3a, 0x159d: 0x7e95,\n\t0x159e: 0x7ef5, 0x159f: 0xaf6a, 0x15a0: 0xaf7a, 0x15a1: 0xaf8a, 0x15a2: 0x1fb2, 0x15a3: 0xaf99,\n\t0x15a4: 0xafaa, 0x15a5: 0xafba, 0x15a6: 0x1fc2, 0x15a7: 0x0040, 0x15a8: 0xafca, 0x15a9: 0xafda,\n\t0x15aa: 0xafea, 0x15ab: 0xaffa, 0x15ac: 0x0040, 0x15ad: 0x0040, 0x15ae: 0x0040, 0x15af: 0x0040,\n\t0x15b0: 0x7fd6, 0x15b1: 0xb009, 0x15b2: 0x7ff6, 0x15b3: 0x0808, 0x15b4: 0x8016, 0x15b5: 0x0040,\n\t0x15b6: 0x8036, 0x15b7: 0xb031, 0x15b8: 0x8056, 0x15b9: 0xb059, 0x15ba: 0x8076, 0x15bb: 0xb081,\n\t0x15bc: 0x8096, 0x15bd: 0xb0a9, 0x15be: 0x80b6, 0x15bf: 0xb0d1,\n\t// Block 0x57, offset 0x15c0\n\t0x15c0: 0xb0f9, 0x15c1: 0xb111, 0x15c2: 0xb111, 0x15c3: 0xb129, 0x15c4: 0xb129, 0x15c5: 0xb141,\n\t0x15c6: 0xb141, 0x15c7: 0xb159, 0x15c8: 0xb159, 0x15c9: 0xb171, 0x15ca: 0xb171, 0x15cb: 0xb171,\n\t0x15cc: 0xb171, 0x15cd: 0xb189, 0x15ce: 0xb189, 0x15cf: 0xb1a1, 0x15d0: 0xb1a1, 0x15d1: 0xb1a1,\n\t0x15d2: 0xb1a1, 0x15d3: 0xb1b9, 0x15d4: 0xb1b9, 0x15d5: 0xb1d1, 0x15d6: 0xb1d1, 0x15d7: 0xb1d1,\n\t0x15d8: 0xb1d1, 0x15d9: 0xb1e9, 0x15da: 0xb1e9, 0x15db: 0xb1e9, 0x15dc: 0xb1e9, 0x15dd: 0xb201,\n\t0x15de: 0xb201, 0x15df: 0xb201, 0x15e0: 0xb201, 0x15e1: 0xb219, 0x15e2: 0xb219, 0x15e3: 0xb219,\n\t0x15e4: 0xb219, 0x15e5: 0xb231, 0x15e6: 0xb231, 0x15e7: 0xb231, 0x15e8: 0xb231, 0x15e9: 0xb249,\n\t0x15ea: 0xb249, 0x15eb: 0xb261, 0x15ec: 0xb261, 0x15ed: 0xb279, 0x15ee: 0xb279, 0x15ef: 0xb291,\n\t0x15f0: 0xb291, 0x15f1: 0xb2a9, 0x15f2: 0xb2a9, 0x15f3: 0xb2a9, 0x15f4: 0xb2a9, 0x15f5: 0xb2c1,\n\t0x15f6: 0xb2c1, 0x15f7: 0xb2c1, 0x15f8: 0xb2c1, 0x15f9: 0xb2d9, 0x15fa: 0xb2d9, 0x15fb: 0xb2d9,\n\t0x15fc: 0xb2d9, 0x15fd: 0xb2f1, 0x15fe: 0xb2f1, 0x15ff: 0xb2f1,\n\t// Block 0x58, offset 0x1600\n\t0x1600: 0xb2f1, 0x1601: 0xb309, 0x1602: 0xb309, 0x1603: 0xb309, 0x1604: 0xb309, 0x1605: 0xb321,\n\t0x1606: 0xb321, 0x1607: 0xb321, 0x1608: 0xb321, 0x1609: 0xb339, 0x160a: 0xb339, 0x160b: 0xb339,\n\t0x160c: 0xb339, 0x160d: 0xb351, 0x160e: 0xb351, 0x160f: 0xb351, 0x1610: 0xb351, 0x1611: 0xb369,\n\t0x1612: 0xb369, 0x1613: 0xb369, 0x1614: 0xb369, 0x1615: 0xb381, 0x1616: 0xb381, 0x1617: 0xb381,\n\t0x1618: 0xb381, 0x1619: 0xb399, 0x161a: 0xb399, 0x161b: 0xb399, 0x161c: 0xb399, 0x161d: 0xb3b1,\n\t0x161e: 0xb3b1, 0x161f: 0xb3b1, 0x1620: 0xb3b1, 0x1621: 0xb3c9, 0x1622: 0xb3c9, 0x1623: 0xb3c9,\n\t0x1624: 0xb3c9, 0x1625: 0xb3e1, 0x1626: 0xb3e1, 0x1627: 0xb3e1, 0x1628: 0xb3e1, 0x1629: 0xb3f9,\n\t0x162a: 0xb3f9, 0x162b: 0xb3f9, 0x162c: 0xb3f9, 0x162d: 0xb411, 0x162e: 0xb411, 0x162f: 0x7ab1,\n\t0x1630: 0x7ab1, 0x1631: 0xb429, 0x1632: 0xb429, 0x1633: 0xb429, 0x1634: 0xb429, 0x1635: 0xb441,\n\t0x1636: 0xb441, 0x1637: 0xb469, 0x1638: 0xb469, 0x1639: 0xb491, 0x163a: 0xb491, 0x163b: 0xb4b9,\n\t0x163c: 0xb4b9, 0x163d: 0x0040, 0x163e: 0x0040, 0x163f: 0x03c0,\n\t// Block 0x59, offset 0x1640\n\t0x1640: 0x0040, 0x1641: 0xaefa, 0x1642: 0xb4e2, 0x1643: 0xaf6a, 0x1644: 0xafda, 0x1645: 0xafea,\n\t0x1646: 0xaf7a, 0x1647: 0xb4f2, 0x1648: 0x1fd2, 0x1649: 0x1fe2, 0x164a: 0xaf8a, 0x164b: 0x1fb2,\n\t0x164c: 0xaeda, 0x164d: 0xaf99, 0x164e: 0x29d1, 0x164f: 0xb502, 0x1650: 0x1f41, 0x1651: 0x00c9,\n\t0x1652: 0x0069, 0x1653: 0x0079, 0x1654: 0x1f51, 0x1655: 0x1f61, 0x1656: 0x1f71, 0x1657: 0x1f81,\n\t0x1658: 0x1f91, 0x1659: 0x1fa1, 0x165a: 0xaeea, 0x165b: 0x03c2, 0x165c: 0xafaa, 0x165d: 0x1fc2,\n\t0x165e: 0xafba, 0x165f: 0xaf0a, 0x1660: 0xaffa, 0x1661: 0x0039, 0x1662: 0x0ee9, 0x1663: 0x1159,\n\t0x1664: 0x0ef9, 0x1665: 0x0f09, 0x1666: 0x1199, 0x1667: 0x0f31, 0x1668: 0x0249, 0x1669: 0x0f41,\n\t0x166a: 0x0259, 0x166b: 0x0f51, 0x166c: 0x0359, 0x166d: 0x0f61, 0x166e: 0x0f71, 0x166f: 0x00d9,\n\t0x1670: 0x0f99, 0x1671: 0x2039, 0x1672: 0x0269, 0x1673: 0x01d9, 0x1674: 0x0fa9, 0x1675: 0x0fb9,\n\t0x1676: 0x1089, 0x1677: 0x0279, 0x1678: 0x0369, 0x1679: 0x0289, 0x167a: 0x13d1, 0x167b: 0xaf4a,\n\t0x167c: 0xafca, 0x167d: 0xaf5a, 0x167e: 0xb512, 0x167f: 0xaf1a,\n\t// Block 0x5a, offset 0x1680\n\t0x1680: 0x1caa, 0x1681: 0x0039, 0x1682: 0x0ee9, 0x1683: 0x1159, 0x1684: 0x0ef9, 0x1685: 0x0f09,\n\t0x1686: 0x1199, 0x1687: 0x0f31, 0x1688: 0x0249, 0x1689: 0x0f41, 0x168a: 0x0259, 0x168b: 0x0f51,\n\t0x168c: 0x0359, 0x168d: 0x0f61, 0x168e: 0x0f71, 0x168f: 0x00d9, 0x1690: 0x0f99, 0x1691: 0x2039,\n\t0x1692: 0x0269, 0x1693: 0x01d9, 0x1694: 0x0fa9, 0x1695: 0x0fb9, 0x1696: 0x1089, 0x1697: 0x0279,\n\t0x1698: 0x0369, 0x1699: 0x0289, 0x169a: 0x13d1, 0x169b: 0xaf2a, 0x169c: 0xb522, 0x169d: 0xaf3a,\n\t0x169e: 0xb532, 0x169f: 0x80d5, 0x16a0: 0x80f5, 0x16a1: 0x29d1, 0x16a2: 0x8115, 0x16a3: 0x8115,\n\t0x16a4: 0x8135, 0x16a5: 0x8155, 0x16a6: 0x8175, 0x16a7: 0x8195, 0x16a8: 0x81b5, 0x16a9: 0x81d5,\n\t0x16aa: 0x81f5, 0x16ab: 0x8215, 0x16ac: 0x8235, 0x16ad: 0x8255, 0x16ae: 0x8275, 0x16af: 0x8295,\n\t0x16b0: 0x82b5, 0x16b1: 0x82d5, 0x16b2: 0x82f5, 0x16b3: 0x8315, 0x16b4: 0x8335, 0x16b5: 0x8355,\n\t0x16b6: 0x8375, 0x16b7: 0x8395, 0x16b8: 0x83b5, 0x16b9: 0x83d5, 0x16ba: 0x83f5, 0x16bb: 0x8415,\n\t0x16bc: 0x81b5, 0x16bd: 0x8435, 0x16be: 0x8455, 0x16bf: 0x8215,\n\t// Block 0x5b, offset 0x16c0\n\t0x16c0: 0x8475, 0x16c1: 0x8495, 0x16c2: 0x84b5, 0x16c3: 0x84d5, 0x16c4: 0x84f5, 0x16c5: 0x8515,\n\t0x16c6: 0x8535, 0x16c7: 0x8555, 0x16c8: 0x84d5, 0x16c9: 0x8575, 0x16ca: 0x84d5, 0x16cb: 0x8595,\n\t0x16cc: 0x8595, 0x16cd: 0x85b5, 0x16ce: 0x85b5, 0x16cf: 0x85d5, 0x16d0: 0x8515, 0x16d1: 0x85f5,\n\t0x16d2: 0x8615, 0x16d3: 0x85f5, 0x16d4: 0x8635, 0x16d5: 0x8615, 0x16d6: 0x8655, 0x16d7: 0x8655,\n\t0x16d8: 0x8675, 0x16d9: 0x8675, 0x16da: 0x8695, 0x16db: 0x8695, 0x16dc: 0x8615, 0x16dd: 0x8115,\n\t0x16de: 0x86b5, 0x16df: 0x86d5, 0x16e0: 0x0040, 0x16e1: 0x86f5, 0x16e2: 0x8715, 0x16e3: 0x8735,\n\t0x16e4: 0x8755, 0x16e5: 0x8735, 0x16e6: 0x8775, 0x16e7: 0x8795, 0x16e8: 0x87b5, 0x16e9: 0x87b5,\n\t0x16ea: 0x87d5, 0x16eb: 0x87d5, 0x16ec: 0x87f5, 0x16ed: 0x87f5, 0x16ee: 0x87d5, 0x16ef: 0x87d5,\n\t0x16f0: 0x8815, 0x16f1: 0x8835, 0x16f2: 0x8855, 0x16f3: 0x8875, 0x16f4: 0x8895, 0x16f5: 0x88b5,\n\t0x16f6: 0x88b5, 0x16f7: 0x88b5, 0x16f8: 0x88d5, 0x16f9: 0x88d5, 0x16fa: 0x88d5, 0x16fb: 0x88d5,\n\t0x16fc: 0x87b5, 0x16fd: 0x87b5, 0x16fe: 0x87b5, 0x16ff: 0x0040,\n\t// Block 0x5c, offset 0x1700\n\t0x1700: 0x0040, 0x1701: 0x0040, 0x1702: 0x8715, 0x1703: 0x86f5, 0x1704: 0x88f5, 0x1705: 0x86f5,\n\t0x1706: 0x8715, 0x1707: 0x86f5, 0x1708: 0x0040, 0x1709: 0x0040, 0x170a: 0x8915, 0x170b: 0x8715,\n\t0x170c: 0x8935, 0x170d: 0x88f5, 0x170e: 0x8935, 0x170f: 0x8715, 0x1710: 0x0040, 0x1711: 0x0040,\n\t0x1712: 0x8955, 0x1713: 0x8975, 0x1714: 0x8875, 0x1715: 0x8935, 0x1716: 0x88f5, 0x1717: 0x8935,\n\t0x1718: 0x0040, 0x1719: 0x0040, 0x171a: 0x8995, 0x171b: 0x89b5, 0x171c: 0x8995, 0x171d: 0x0040,\n\t0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0xb541, 0x1721: 0xb559, 0x1722: 0xb571, 0x1723: 0x89d6,\n\t0x1724: 0xb589, 0x1725: 0xb5a1, 0x1726: 0x89f5, 0x1727: 0x0040, 0x1728: 0x8a15, 0x1729: 0x8a35,\n\t0x172a: 0x8a55, 0x172b: 0x8a35, 0x172c: 0x8a75, 0x172d: 0x8a95, 0x172e: 0x8ab5, 0x172f: 0x0040,\n\t0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040,\n\t0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0340, 0x173a: 0x0340, 0x173b: 0x0340,\n\t0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040,\n\t// Block 0x5d, offset 0x1740\n\t0x1740: 0x0a08, 0x1741: 0x0a08, 0x1742: 0x0a08, 0x1743: 0x0a08, 0x1744: 0x0a08, 0x1745: 0x0c08,\n\t0x1746: 0x0808, 0x1747: 0x0c08, 0x1748: 0x0818, 0x1749: 0x0c08, 0x174a: 0x0c08, 0x174b: 0x0808,\n\t0x174c: 0x0808, 0x174d: 0x0908, 0x174e: 0x0c08, 0x174f: 0x0c08, 0x1750: 0x0c08, 0x1751: 0x0c08,\n\t0x1752: 0x0c08, 0x1753: 0x0a08, 0x1754: 0x0a08, 0x1755: 0x0a08, 0x1756: 0x0a08, 0x1757: 0x0908,\n\t0x1758: 0x0a08, 0x1759: 0x0a08, 0x175a: 0x0a08, 0x175b: 0x0a08, 0x175c: 0x0a08, 0x175d: 0x0c08,\n\t0x175e: 0x0a08, 0x175f: 0x0a08, 0x1760: 0x0a08, 0x1761: 0x0c08, 0x1762: 0x0808, 0x1763: 0x0808,\n\t0x1764: 0x0c08, 0x1765: 0x3308, 0x1766: 0x3308, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0040,\n\t0x176a: 0x0040, 0x176b: 0x0a18, 0x176c: 0x0a18, 0x176d: 0x0a18, 0x176e: 0x0a18, 0x176f: 0x0c18,\n\t0x1770: 0x0818, 0x1771: 0x0818, 0x1772: 0x0818, 0x1773: 0x0818, 0x1774: 0x0818, 0x1775: 0x0818,\n\t0x1776: 0x0818, 0x1777: 0x0040, 0x1778: 0x0040, 0x1779: 0x0040, 0x177a: 0x0040, 0x177b: 0x0040,\n\t0x177c: 0x0040, 0x177d: 0x0040, 0x177e: 0x0040, 0x177f: 0x0040,\n\t// Block 0x5e, offset 0x1780\n\t0x1780: 0x0a08, 0x1781: 0x0c08, 0x1782: 0x0a08, 0x1783: 0x0c08, 0x1784: 0x0c08, 0x1785: 0x0c08,\n\t0x1786: 0x0a08, 0x1787: 0x0a08, 0x1788: 0x0a08, 0x1789: 0x0c08, 0x178a: 0x0a08, 0x178b: 0x0a08,\n\t0x178c: 0x0c08, 0x178d: 0x0a08, 0x178e: 0x0c08, 0x178f: 0x0c08, 0x1790: 0x0a08, 0x1791: 0x0c08,\n\t0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x0040,\n\t0x1798: 0x0040, 0x1799: 0x0818, 0x179a: 0x0818, 0x179b: 0x0818, 0x179c: 0x0818, 0x179d: 0x0040,\n\t0x179e: 0x0040, 0x179f: 0x0040, 0x17a0: 0x0040, 0x17a1: 0x0040, 0x17a2: 0x0040, 0x17a3: 0x0040,\n\t0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x0040, 0x17a7: 0x0040, 0x17a8: 0x0040, 0x17a9: 0x0c18,\n\t0x17aa: 0x0c18, 0x17ab: 0x0c18, 0x17ac: 0x0c18, 0x17ad: 0x0a18, 0x17ae: 0x0a18, 0x17af: 0x0818,\n\t0x17b0: 0x0040, 0x17b1: 0x0040, 0x17b2: 0x0040, 0x17b3: 0x0040, 0x17b4: 0x0040, 0x17b5: 0x0040,\n\t0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040,\n\t0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040,\n\t// Block 0x5f, offset 0x17c0\n\t0x17c0: 0x3308, 0x17c1: 0x3308, 0x17c2: 0x3008, 0x17c3: 0x3008, 0x17c4: 0x0040, 0x17c5: 0x0008,\n\t0x17c6: 0x0008, 0x17c7: 0x0008, 0x17c8: 0x0008, 0x17c9: 0x0008, 0x17ca: 0x0008, 0x17cb: 0x0008,\n\t0x17cc: 0x0008, 0x17cd: 0x0040, 0x17ce: 0x0040, 0x17cf: 0x0008, 0x17d0: 0x0008, 0x17d1: 0x0040,\n\t0x17d2: 0x0040, 0x17d3: 0x0008, 0x17d4: 0x0008, 0x17d5: 0x0008, 0x17d6: 0x0008, 0x17d7: 0x0008,\n\t0x17d8: 0x0008, 0x17d9: 0x0008, 0x17da: 0x0008, 0x17db: 0x0008, 0x17dc: 0x0008, 0x17dd: 0x0008,\n\t0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x0008, 0x17e3: 0x0008,\n\t0x17e4: 0x0008, 0x17e5: 0x0008, 0x17e6: 0x0008, 0x17e7: 0x0008, 0x17e8: 0x0008, 0x17e9: 0x0040,\n\t0x17ea: 0x0008, 0x17eb: 0x0008, 0x17ec: 0x0008, 0x17ed: 0x0008, 0x17ee: 0x0008, 0x17ef: 0x0008,\n\t0x17f0: 0x0008, 0x17f1: 0x0040, 0x17f2: 0x0008, 0x17f3: 0x0008, 0x17f4: 0x0040, 0x17f5: 0x0008,\n\t0x17f6: 0x0008, 0x17f7: 0x0008, 0x17f8: 0x0008, 0x17f9: 0x0008, 0x17fa: 0x0040, 0x17fb: 0x0040,\n\t0x17fc: 0x3308, 0x17fd: 0x0008, 0x17fe: 0x3008, 0x17ff: 0x3008,\n\t// Block 0x60, offset 0x1800\n\t0x1800: 0x3308, 0x1801: 0x3008, 0x1802: 0x3008, 0x1803: 0x3008, 0x1804: 0x3008, 0x1805: 0x0040,\n\t0x1806: 0x0040, 0x1807: 0x3008, 0x1808: 0x3008, 0x1809: 0x0040, 0x180a: 0x0040, 0x180b: 0x3008,\n\t0x180c: 0x3008, 0x180d: 0x3808, 0x180e: 0x0040, 0x180f: 0x0040, 0x1810: 0x0008, 0x1811: 0x0040,\n\t0x1812: 0x0040, 0x1813: 0x0040, 0x1814: 0x0040, 0x1815: 0x0040, 0x1816: 0x0040, 0x1817: 0x3008,\n\t0x1818: 0x0040, 0x1819: 0x0040, 0x181a: 0x0040, 0x181b: 0x0040, 0x181c: 0x0040, 0x181d: 0x0008,\n\t0x181e: 0x0008, 0x181f: 0x0008, 0x1820: 0x0008, 0x1821: 0x0008, 0x1822: 0x3008, 0x1823: 0x3008,\n\t0x1824: 0x0040, 0x1825: 0x0040, 0x1826: 0x3308, 0x1827: 0x3308, 0x1828: 0x3308, 0x1829: 0x3308,\n\t0x182a: 0x3308, 0x182b: 0x3308, 0x182c: 0x3308, 0x182d: 0x0040, 0x182e: 0x0040, 0x182f: 0x0040,\n\t0x1830: 0x3308, 0x1831: 0x3308, 0x1832: 0x3308, 0x1833: 0x3308, 0x1834: 0x3308, 0x1835: 0x0040,\n\t0x1836: 0x0040, 0x1837: 0x0040, 0x1838: 0x0040, 0x1839: 0x0040, 0x183a: 0x0040, 0x183b: 0x0040,\n\t0x183c: 0x0040, 0x183d: 0x0040, 0x183e: 0x0040, 0x183f: 0x0040,\n\t// Block 0x61, offset 0x1840\n\t0x1840: 0x0039, 0x1841: 0x0ee9, 0x1842: 0x1159, 0x1843: 0x0ef9, 0x1844: 0x0f09, 0x1845: 0x1199,\n\t0x1846: 0x0f31, 0x1847: 0x0249, 0x1848: 0x0f41, 0x1849: 0x0259, 0x184a: 0x0f51, 0x184b: 0x0359,\n\t0x184c: 0x0f61, 0x184d: 0x0f71, 0x184e: 0x00d9, 0x184f: 0x0f99, 0x1850: 0x2039, 0x1851: 0x0269,\n\t0x1852: 0x01d9, 0x1853: 0x0fa9, 0x1854: 0x0fb9, 0x1855: 0x1089, 0x1856: 0x0279, 0x1857: 0x0369,\n\t0x1858: 0x0289, 0x1859: 0x13d1, 0x185a: 0x0039, 0x185b: 0x0ee9, 0x185c: 0x1159, 0x185d: 0x0ef9,\n\t0x185e: 0x0f09, 0x185f: 0x1199, 0x1860: 0x0f31, 0x1861: 0x0249, 0x1862: 0x0f41, 0x1863: 0x0259,\n\t0x1864: 0x0f51, 0x1865: 0x0359, 0x1866: 0x0f61, 0x1867: 0x0f71, 0x1868: 0x00d9, 0x1869: 0x0f99,\n\t0x186a: 0x2039, 0x186b: 0x0269, 0x186c: 0x01d9, 0x186d: 0x0fa9, 0x186e: 0x0fb9, 0x186f: 0x1089,\n\t0x1870: 0x0279, 0x1871: 0x0369, 0x1872: 0x0289, 0x1873: 0x13d1, 0x1874: 0x0039, 0x1875: 0x0ee9,\n\t0x1876: 0x1159, 0x1877: 0x0ef9, 0x1878: 0x0f09, 0x1879: 0x1199, 0x187a: 0x0f31, 0x187b: 0x0249,\n\t0x187c: 0x0f41, 0x187d: 0x0259, 0x187e: 0x0f51, 0x187f: 0x0359,\n\t// Block 0x62, offset 0x1880\n\t0x1880: 0x0f61, 0x1881: 0x0f71, 0x1882: 0x00d9, 0x1883: 0x0f99, 0x1884: 0x2039, 0x1885: 0x0269,\n\t0x1886: 0x01d9, 0x1887: 0x0fa9, 0x1888: 0x0fb9, 0x1889: 0x1089, 0x188a: 0x0279, 0x188b: 0x0369,\n\t0x188c: 0x0289, 0x188d: 0x13d1, 0x188e: 0x0039, 0x188f: 0x0ee9, 0x1890: 0x1159, 0x1891: 0x0ef9,\n\t0x1892: 0x0f09, 0x1893: 0x1199, 0x1894: 0x0f31, 0x1895: 0x0040, 0x1896: 0x0f41, 0x1897: 0x0259,\n\t0x1898: 0x0f51, 0x1899: 0x0359, 0x189a: 0x0f61, 0x189b: 0x0f71, 0x189c: 0x00d9, 0x189d: 0x0f99,\n\t0x189e: 0x2039, 0x189f: 0x0269, 0x18a0: 0x01d9, 0x18a1: 0x0fa9, 0x18a2: 0x0fb9, 0x18a3: 0x1089,\n\t0x18a4: 0x0279, 0x18a5: 0x0369, 0x18a6: 0x0289, 0x18a7: 0x13d1, 0x18a8: 0x0039, 0x18a9: 0x0ee9,\n\t0x18aa: 0x1159, 0x18ab: 0x0ef9, 0x18ac: 0x0f09, 0x18ad: 0x1199, 0x18ae: 0x0f31, 0x18af: 0x0249,\n\t0x18b0: 0x0f41, 0x18b1: 0x0259, 0x18b2: 0x0f51, 0x18b3: 0x0359, 0x18b4: 0x0f61, 0x18b5: 0x0f71,\n\t0x18b6: 0x00d9, 0x18b7: 0x0f99, 0x18b8: 0x2039, 0x18b9: 0x0269, 0x18ba: 0x01d9, 0x18bb: 0x0fa9,\n\t0x18bc: 0x0fb9, 0x18bd: 0x1089, 0x18be: 0x0279, 0x18bf: 0x0369,\n\t// Block 0x63, offset 0x18c0\n\t0x18c0: 0x0289, 0x18c1: 0x13d1, 0x18c2: 0x0039, 0x18c3: 0x0ee9, 0x18c4: 0x1159, 0x18c5: 0x0ef9,\n\t0x18c6: 0x0f09, 0x18c7: 0x1199, 0x18c8: 0x0f31, 0x18c9: 0x0249, 0x18ca: 0x0f41, 0x18cb: 0x0259,\n\t0x18cc: 0x0f51, 0x18cd: 0x0359, 0x18ce: 0x0f61, 0x18cf: 0x0f71, 0x18d0: 0x00d9, 0x18d1: 0x0f99,\n\t0x18d2: 0x2039, 0x18d3: 0x0269, 0x18d4: 0x01d9, 0x18d5: 0x0fa9, 0x18d6: 0x0fb9, 0x18d7: 0x1089,\n\t0x18d8: 0x0279, 0x18d9: 0x0369, 0x18da: 0x0289, 0x18db: 0x13d1, 0x18dc: 0x0039, 0x18dd: 0x0040,\n\t0x18de: 0x1159, 0x18df: 0x0ef9, 0x18e0: 0x0040, 0x18e1: 0x0040, 0x18e2: 0x0f31, 0x18e3: 0x0040,\n\t0x18e4: 0x0040, 0x18e5: 0x0259, 0x18e6: 0x0f51, 0x18e7: 0x0040, 0x18e8: 0x0040, 0x18e9: 0x0f71,\n\t0x18ea: 0x00d9, 0x18eb: 0x0f99, 0x18ec: 0x2039, 0x18ed: 0x0040, 0x18ee: 0x01d9, 0x18ef: 0x0fa9,\n\t0x18f0: 0x0fb9, 0x18f1: 0x1089, 0x18f2: 0x0279, 0x18f3: 0x0369, 0x18f4: 0x0289, 0x18f5: 0x13d1,\n\t0x18f6: 0x0039, 0x18f7: 0x0ee9, 0x18f8: 0x1159, 0x18f9: 0x0ef9, 0x18fa: 0x0040, 0x18fb: 0x1199,\n\t0x18fc: 0x0040, 0x18fd: 0x0249, 0x18fe: 0x0f41, 0x18ff: 0x0259,\n\t// Block 0x64, offset 0x1900\n\t0x1900: 0x0f51, 0x1901: 0x0359, 0x1902: 0x0f61, 0x1903: 0x0f71, 0x1904: 0x0040, 0x1905: 0x0f99,\n\t0x1906: 0x2039, 0x1907: 0x0269, 0x1908: 0x01d9, 0x1909: 0x0fa9, 0x190a: 0x0fb9, 0x190b: 0x1089,\n\t0x190c: 0x0279, 0x190d: 0x0369, 0x190e: 0x0289, 0x190f: 0x13d1, 0x1910: 0x0039, 0x1911: 0x0ee9,\n\t0x1912: 0x1159, 0x1913: 0x0ef9, 0x1914: 0x0f09, 0x1915: 0x1199, 0x1916: 0x0f31, 0x1917: 0x0249,\n\t0x1918: 0x0f41, 0x1919: 0x0259, 0x191a: 0x0f51, 0x191b: 0x0359, 0x191c: 0x0f61, 0x191d: 0x0f71,\n\t0x191e: 0x00d9, 0x191f: 0x0f99, 0x1920: 0x2039, 0x1921: 0x0269, 0x1922: 0x01d9, 0x1923: 0x0fa9,\n\t0x1924: 0x0fb9, 0x1925: 0x1089, 0x1926: 0x0279, 0x1927: 0x0369, 0x1928: 0x0289, 0x1929: 0x13d1,\n\t0x192a: 0x0039, 0x192b: 0x0ee9, 0x192c: 0x1159, 0x192d: 0x0ef9, 0x192e: 0x0f09, 0x192f: 0x1199,\n\t0x1930: 0x0f31, 0x1931: 0x0249, 0x1932: 0x0f41, 0x1933: 0x0259, 0x1934: 0x0f51, 0x1935: 0x0359,\n\t0x1936: 0x0f61, 0x1937: 0x0f71, 0x1938: 0x00d9, 0x1939: 0x0f99, 0x193a: 0x2039, 0x193b: 0x0269,\n\t0x193c: 0x01d9, 0x193d: 0x0fa9, 0x193e: 0x0fb9, 0x193f: 0x1089,\n\t// Block 0x65, offset 0x1940\n\t0x1940: 0x0279, 0x1941: 0x0369, 0x1942: 0x0289, 0x1943: 0x13d1, 0x1944: 0x0039, 0x1945: 0x0ee9,\n\t0x1946: 0x0040, 0x1947: 0x0ef9, 0x1948: 0x0f09, 0x1949: 0x1199, 0x194a: 0x0f31, 0x194b: 0x0040,\n\t0x194c: 0x0040, 0x194d: 0x0259, 0x194e: 0x0f51, 0x194f: 0x0359, 0x1950: 0x0f61, 0x1951: 0x0f71,\n\t0x1952: 0x00d9, 0x1953: 0x0f99, 0x1954: 0x2039, 0x1955: 0x0040, 0x1956: 0x01d9, 0x1957: 0x0fa9,\n\t0x1958: 0x0fb9, 0x1959: 0x1089, 0x195a: 0x0279, 0x195b: 0x0369, 0x195c: 0x0289, 0x195d: 0x0040,\n\t0x195e: 0x0039, 0x195f: 0x0ee9, 0x1960: 0x1159, 0x1961: 0x0ef9, 0x1962: 0x0f09, 0x1963: 0x1199,\n\t0x1964: 0x0f31, 0x1965: 0x0249, 0x1966: 0x0f41, 0x1967: 0x0259, 0x1968: 0x0f51, 0x1969: 0x0359,\n\t0x196a: 0x0f61, 0x196b: 0x0f71, 0x196c: 0x00d9, 0x196d: 0x0f99, 0x196e: 0x2039, 0x196f: 0x0269,\n\t0x1970: 0x01d9, 0x1971: 0x0fa9, 0x1972: 0x0fb9, 0x1973: 0x1089, 0x1974: 0x0279, 0x1975: 0x0369,\n\t0x1976: 0x0289, 0x1977: 0x13d1, 0x1978: 0x0039, 0x1979: 0x0ee9, 0x197a: 0x0040, 0x197b: 0x0ef9,\n\t0x197c: 0x0f09, 0x197d: 0x1199, 0x197e: 0x0f31, 0x197f: 0x0040,\n\t// Block 0x66, offset 0x1980\n\t0x1980: 0x0f41, 0x1981: 0x0259, 0x1982: 0x0f51, 0x1983: 0x0359, 0x1984: 0x0f61, 0x1985: 0x0040,\n\t0x1986: 0x00d9, 0x1987: 0x0040, 0x1988: 0x0040, 0x1989: 0x0040, 0x198a: 0x01d9, 0x198b: 0x0fa9,\n\t0x198c: 0x0fb9, 0x198d: 0x1089, 0x198e: 0x0279, 0x198f: 0x0369, 0x1990: 0x0289, 0x1991: 0x0040,\n\t0x1992: 0x0039, 0x1993: 0x0ee9, 0x1994: 0x1159, 0x1995: 0x0ef9, 0x1996: 0x0f09, 0x1997: 0x1199,\n\t0x1998: 0x0f31, 0x1999: 0x0249, 0x199a: 0x0f41, 0x199b: 0x0259, 0x199c: 0x0f51, 0x199d: 0x0359,\n\t0x199e: 0x0f61, 0x199f: 0x0f71, 0x19a0: 0x00d9, 0x19a1: 0x0f99, 0x19a2: 0x2039, 0x19a3: 0x0269,\n\t0x19a4: 0x01d9, 0x19a5: 0x0fa9, 0x19a6: 0x0fb9, 0x19a7: 0x1089, 0x19a8: 0x0279, 0x19a9: 0x0369,\n\t0x19aa: 0x0289, 0x19ab: 0x13d1, 0x19ac: 0x0039, 0x19ad: 0x0ee9, 0x19ae: 0x1159, 0x19af: 0x0ef9,\n\t0x19b0: 0x0f09, 0x19b1: 0x1199, 0x19b2: 0x0f31, 0x19b3: 0x0249, 0x19b4: 0x0f41, 0x19b5: 0x0259,\n\t0x19b6: 0x0f51, 0x19b7: 0x0359, 0x19b8: 0x0f61, 0x19b9: 0x0f71, 0x19ba: 0x00d9, 0x19bb: 0x0f99,\n\t0x19bc: 0x2039, 0x19bd: 0x0269, 0x19be: 0x01d9, 0x19bf: 0x0fa9,\n\t// Block 0x67, offset 0x19c0\n\t0x19c0: 0x0fb9, 0x19c1: 0x1089, 0x19c2: 0x0279, 0x19c3: 0x0369, 0x19c4: 0x0289, 0x19c5: 0x13d1,\n\t0x19c6: 0x0039, 0x19c7: 0x0ee9, 0x19c8: 0x1159, 0x19c9: 0x0ef9, 0x19ca: 0x0f09, 0x19cb: 0x1199,\n\t0x19cc: 0x0f31, 0x19cd: 0x0249, 0x19ce: 0x0f41, 0x19cf: 0x0259, 0x19d0: 0x0f51, 0x19d1: 0x0359,\n\t0x19d2: 0x0f61, 0x19d3: 0x0f71, 0x19d4: 0x00d9, 0x19d5: 0x0f99, 0x19d6: 0x2039, 0x19d7: 0x0269,\n\t0x19d8: 0x01d9, 0x19d9: 0x0fa9, 0x19da: 0x0fb9, 0x19db: 0x1089, 0x19dc: 0x0279, 0x19dd: 0x0369,\n\t0x19de: 0x0289, 0x19df: 0x13d1, 0x19e0: 0x0039, 0x19e1: 0x0ee9, 0x19e2: 0x1159, 0x19e3: 0x0ef9,\n\t0x19e4: 0x0f09, 0x19e5: 0x1199, 0x19e6: 0x0f31, 0x19e7: 0x0249, 0x19e8: 0x0f41, 0x19e9: 0x0259,\n\t0x19ea: 0x0f51, 0x19eb: 0x0359, 0x19ec: 0x0f61, 0x19ed: 0x0f71, 0x19ee: 0x00d9, 0x19ef: 0x0f99,\n\t0x19f0: 0x2039, 0x19f1: 0x0269, 0x19f2: 0x01d9, 0x19f3: 0x0fa9, 0x19f4: 0x0fb9, 0x19f5: 0x1089,\n\t0x19f6: 0x0279, 0x19f7: 0x0369, 0x19f8: 0x0289, 0x19f9: 0x13d1, 0x19fa: 0x0039, 0x19fb: 0x0ee9,\n\t0x19fc: 0x1159, 0x19fd: 0x0ef9, 0x19fe: 0x0f09, 0x19ff: 0x1199,\n\t// Block 0x68, offset 0x1a00\n\t0x1a00: 0x0f31, 0x1a01: 0x0249, 0x1a02: 0x0f41, 0x1a03: 0x0259, 0x1a04: 0x0f51, 0x1a05: 0x0359,\n\t0x1a06: 0x0f61, 0x1a07: 0x0f71, 0x1a08: 0x00d9, 0x1a09: 0x0f99, 0x1a0a: 0x2039, 0x1a0b: 0x0269,\n\t0x1a0c: 0x01d9, 0x1a0d: 0x0fa9, 0x1a0e: 0x0fb9, 0x1a0f: 0x1089, 0x1a10: 0x0279, 0x1a11: 0x0369,\n\t0x1a12: 0x0289, 0x1a13: 0x13d1, 0x1a14: 0x0039, 0x1a15: 0x0ee9, 0x1a16: 0x1159, 0x1a17: 0x0ef9,\n\t0x1a18: 0x0f09, 0x1a19: 0x1199, 0x1a1a: 0x0f31, 0x1a1b: 0x0249, 0x1a1c: 0x0f41, 0x1a1d: 0x0259,\n\t0x1a1e: 0x0f51, 0x1a1f: 0x0359, 0x1a20: 0x0f61, 0x1a21: 0x0f71, 0x1a22: 0x00d9, 0x1a23: 0x0f99,\n\t0x1a24: 0x2039, 0x1a25: 0x0269, 0x1a26: 0x01d9, 0x1a27: 0x0fa9, 0x1a28: 0x0fb9, 0x1a29: 0x1089,\n\t0x1a2a: 0x0279, 0x1a2b: 0x0369, 0x1a2c: 0x0289, 0x1a2d: 0x13d1, 0x1a2e: 0x0039, 0x1a2f: 0x0ee9,\n\t0x1a30: 0x1159, 0x1a31: 0x0ef9, 0x1a32: 0x0f09, 0x1a33: 0x1199, 0x1a34: 0x0f31, 0x1a35: 0x0249,\n\t0x1a36: 0x0f41, 0x1a37: 0x0259, 0x1a38: 0x0f51, 0x1a39: 0x0359, 0x1a3a: 0x0f61, 0x1a3b: 0x0f71,\n\t0x1a3c: 0x00d9, 0x1a3d: 0x0f99, 0x1a3e: 0x2039, 0x1a3f: 0x0269,\n\t// Block 0x69, offset 0x1a40\n\t0x1a40: 0x01d9, 0x1a41: 0x0fa9, 0x1a42: 0x0fb9, 0x1a43: 0x1089, 0x1a44: 0x0279, 0x1a45: 0x0369,\n\t0x1a46: 0x0289, 0x1a47: 0x13d1, 0x1a48: 0x0039, 0x1a49: 0x0ee9, 0x1a4a: 0x1159, 0x1a4b: 0x0ef9,\n\t0x1a4c: 0x0f09, 0x1a4d: 0x1199, 0x1a4e: 0x0f31, 0x1a4f: 0x0249, 0x1a50: 0x0f41, 0x1a51: 0x0259,\n\t0x1a52: 0x0f51, 0x1a53: 0x0359, 0x1a54: 0x0f61, 0x1a55: 0x0f71, 0x1a56: 0x00d9, 0x1a57: 0x0f99,\n\t0x1a58: 0x2039, 0x1a59: 0x0269, 0x1a5a: 0x01d9, 0x1a5b: 0x0fa9, 0x1a5c: 0x0fb9, 0x1a5d: 0x1089,\n\t0x1a5e: 0x0279, 0x1a5f: 0x0369, 0x1a60: 0x0289, 0x1a61: 0x13d1, 0x1a62: 0x0039, 0x1a63: 0x0ee9,\n\t0x1a64: 0x1159, 0x1a65: 0x0ef9, 0x1a66: 0x0f09, 0x1a67: 0x1199, 0x1a68: 0x0f31, 0x1a69: 0x0249,\n\t0x1a6a: 0x0f41, 0x1a6b: 0x0259, 0x1a6c: 0x0f51, 0x1a6d: 0x0359, 0x1a6e: 0x0f61, 0x1a6f: 0x0f71,\n\t0x1a70: 0x00d9, 0x1a71: 0x0f99, 0x1a72: 0x2039, 0x1a73: 0x0269, 0x1a74: 0x01d9, 0x1a75: 0x0fa9,\n\t0x1a76: 0x0fb9, 0x1a77: 0x1089, 0x1a78: 0x0279, 0x1a79: 0x0369, 0x1a7a: 0x0289, 0x1a7b: 0x13d1,\n\t0x1a7c: 0x0039, 0x1a7d: 0x0ee9, 0x1a7e: 0x1159, 0x1a7f: 0x0ef9,\n\t// Block 0x6a, offset 0x1a80\n\t0x1a80: 0x0f09, 0x1a81: 0x1199, 0x1a82: 0x0f31, 0x1a83: 0x0249, 0x1a84: 0x0f41, 0x1a85: 0x0259,\n\t0x1a86: 0x0f51, 0x1a87: 0x0359, 0x1a88: 0x0f61, 0x1a89: 0x0f71, 0x1a8a: 0x00d9, 0x1a8b: 0x0f99,\n\t0x1a8c: 0x2039, 0x1a8d: 0x0269, 0x1a8e: 0x01d9, 0x1a8f: 0x0fa9, 0x1a90: 0x0fb9, 0x1a91: 0x1089,\n\t0x1a92: 0x0279, 0x1a93: 0x0369, 0x1a94: 0x0289, 0x1a95: 0x13d1, 0x1a96: 0x0039, 0x1a97: 0x0ee9,\n\t0x1a98: 0x1159, 0x1a99: 0x0ef9, 0x1a9a: 0x0f09, 0x1a9b: 0x1199, 0x1a9c: 0x0f31, 0x1a9d: 0x0249,\n\t0x1a9e: 0x0f41, 0x1a9f: 0x0259, 0x1aa0: 0x0f51, 0x1aa1: 0x0359, 0x1aa2: 0x0f61, 0x1aa3: 0x0f71,\n\t0x1aa4: 0x00d9, 0x1aa5: 0x0f99, 0x1aa6: 0x2039, 0x1aa7: 0x0269, 0x1aa8: 0x01d9, 0x1aa9: 0x0fa9,\n\t0x1aaa: 0x0fb9, 0x1aab: 0x1089, 0x1aac: 0x0279, 0x1aad: 0x0369, 0x1aae: 0x0289, 0x1aaf: 0x13d1,\n\t0x1ab0: 0x0039, 0x1ab1: 0x0ee9, 0x1ab2: 0x1159, 0x1ab3: 0x0ef9, 0x1ab4: 0x0f09, 0x1ab5: 0x1199,\n\t0x1ab6: 0x0f31, 0x1ab7: 0x0249, 0x1ab8: 0x0f41, 0x1ab9: 0x0259, 0x1aba: 0x0f51, 0x1abb: 0x0359,\n\t0x1abc: 0x0f61, 0x1abd: 0x0f71, 0x1abe: 0x00d9, 0x1abf: 0x0f99,\n\t// Block 0x6b, offset 0x1ac0\n\t0x1ac0: 0x2039, 0x1ac1: 0x0269, 0x1ac2: 0x01d9, 0x1ac3: 0x0fa9, 0x1ac4: 0x0fb9, 0x1ac5: 0x1089,\n\t0x1ac6: 0x0279, 0x1ac7: 0x0369, 0x1ac8: 0x0289, 0x1ac9: 0x13d1, 0x1aca: 0x0039, 0x1acb: 0x0ee9,\n\t0x1acc: 0x1159, 0x1acd: 0x0ef9, 0x1ace: 0x0f09, 0x1acf: 0x1199, 0x1ad0: 0x0f31, 0x1ad1: 0x0249,\n\t0x1ad2: 0x0f41, 0x1ad3: 0x0259, 0x1ad4: 0x0f51, 0x1ad5: 0x0359, 0x1ad6: 0x0f61, 0x1ad7: 0x0f71,\n\t0x1ad8: 0x00d9, 0x1ad9: 0x0f99, 0x1ada: 0x2039, 0x1adb: 0x0269, 0x1adc: 0x01d9, 0x1add: 0x0fa9,\n\t0x1ade: 0x0fb9, 0x1adf: 0x1089, 0x1ae0: 0x0279, 0x1ae1: 0x0369, 0x1ae2: 0x0289, 0x1ae3: 0x13d1,\n\t0x1ae4: 0xba81, 0x1ae5: 0xba99, 0x1ae6: 0x0040, 0x1ae7: 0x0040, 0x1ae8: 0xbab1, 0x1ae9: 0x1099,\n\t0x1aea: 0x10b1, 0x1aeb: 0x10c9, 0x1aec: 0xbac9, 0x1aed: 0xbae1, 0x1aee: 0xbaf9, 0x1aef: 0x1429,\n\t0x1af0: 0x1a31, 0x1af1: 0xbb11, 0x1af2: 0xbb29, 0x1af3: 0xbb41, 0x1af4: 0xbb59, 0x1af5: 0xbb71,\n\t0x1af6: 0xbb89, 0x1af7: 0x2109, 0x1af8: 0x1111, 0x1af9: 0x1429, 0x1afa: 0xbba1, 0x1afb: 0xbbb9,\n\t0x1afc: 0xbbd1, 0x1afd: 0x10e1, 0x1afe: 0x10f9, 0x1aff: 0xbbe9,\n\t// Block 0x6c, offset 0x1b00\n\t0x1b00: 0x2079, 0x1b01: 0xbc01, 0x1b02: 0xbab1, 0x1b03: 0x1099, 0x1b04: 0x10b1, 0x1b05: 0x10c9,\n\t0x1b06: 0xbac9, 0x1b07: 0xbae1, 0x1b08: 0xbaf9, 0x1b09: 0x1429, 0x1b0a: 0x1a31, 0x1b0b: 0xbb11,\n\t0x1b0c: 0xbb29, 0x1b0d: 0xbb41, 0x1b0e: 0xbb59, 0x1b0f: 0xbb71, 0x1b10: 0xbb89, 0x1b11: 0x2109,\n\t0x1b12: 0x1111, 0x1b13: 0xbba1, 0x1b14: 0xbba1, 0x1b15: 0xbbb9, 0x1b16: 0xbbd1, 0x1b17: 0x10e1,\n\t0x1b18: 0x10f9, 0x1b19: 0xbbe9, 0x1b1a: 0x2079, 0x1b1b: 0xbc21, 0x1b1c: 0xbac9, 0x1b1d: 0x1429,\n\t0x1b1e: 0xbb11, 0x1b1f: 0x10e1, 0x1b20: 0x1111, 0x1b21: 0x2109, 0x1b22: 0xbab1, 0x1b23: 0x1099,\n\t0x1b24: 0x10b1, 0x1b25: 0x10c9, 0x1b26: 0xbac9, 0x1b27: 0xbae1, 0x1b28: 0xbaf9, 0x1b29: 0x1429,\n\t0x1b2a: 0x1a31, 0x1b2b: 0xbb11, 0x1b2c: 0xbb29, 0x1b2d: 0xbb41, 0x1b2e: 0xbb59, 0x1b2f: 0xbb71,\n\t0x1b30: 0xbb89, 0x1b31: 0x2109, 0x1b32: 0x1111, 0x1b33: 0x1429, 0x1b34: 0xbba1, 0x1b35: 0xbbb9,\n\t0x1b36: 0xbbd1, 0x1b37: 0x10e1, 0x1b38: 0x10f9, 0x1b39: 0xbbe9, 0x1b3a: 0x2079, 0x1b3b: 0xbc01,\n\t0x1b3c: 0xbab1, 0x1b3d: 0x1099, 0x1b3e: 0x10b1, 0x1b3f: 0x10c9,\n\t// Block 0x6d, offset 0x1b40\n\t0x1b40: 0xbac9, 0x1b41: 0xbae1, 0x1b42: 0xbaf9, 0x1b43: 0x1429, 0x1b44: 0x1a31, 0x1b45: 0xbb11,\n\t0x1b46: 0xbb29, 0x1b47: 0xbb41, 0x1b48: 0xbb59, 0x1b49: 0xbb71, 0x1b4a: 0xbb89, 0x1b4b: 0x2109,\n\t0x1b4c: 0x1111, 0x1b4d: 0xbba1, 0x1b4e: 0xbba1, 0x1b4f: 0xbbb9, 0x1b50: 0xbbd1, 0x1b51: 0x10e1,\n\t0x1b52: 0x10f9, 0x1b53: 0xbbe9, 0x1b54: 0x2079, 0x1b55: 0xbc21, 0x1b56: 0xbac9, 0x1b57: 0x1429,\n\t0x1b58: 0xbb11, 0x1b59: 0x10e1, 0x1b5a: 0x1111, 0x1b5b: 0x2109, 0x1b5c: 0xbab1, 0x1b5d: 0x1099,\n\t0x1b5e: 0x10b1, 0x1b5f: 0x10c9, 0x1b60: 0xbac9, 0x1b61: 0xbae1, 0x1b62: 0xbaf9, 0x1b63: 0x1429,\n\t0x1b64: 0x1a31, 0x1b65: 0xbb11, 0x1b66: 0xbb29, 0x1b67: 0xbb41, 0x1b68: 0xbb59, 0x1b69: 0xbb71,\n\t0x1b6a: 0xbb89, 0x1b6b: 0x2109, 0x1b6c: 0x1111, 0x1b6d: 0x1429, 0x1b6e: 0xbba1, 0x1b6f: 0xbbb9,\n\t0x1b70: 0xbbd1, 0x1b71: 0x10e1, 0x1b72: 0x10f9, 0x1b73: 0xbbe9, 0x1b74: 0x2079, 0x1b75: 0xbc01,\n\t0x1b76: 0xbab1, 0x1b77: 0x1099, 0x1b78: 0x10b1, 0x1b79: 0x10c9, 0x1b7a: 0xbac9, 0x1b7b: 0xbae1,\n\t0x1b7c: 0xbaf9, 0x1b7d: 0x1429, 0x1b7e: 0x1a31, 0x1b7f: 0xbb11,\n\t// Block 0x6e, offset 0x1b80\n\t0x1b80: 0xbb29, 0x1b81: 0xbb41, 0x1b82: 0xbb59, 0x1b83: 0xbb71, 0x1b84: 0xbb89, 0x1b85: 0x2109,\n\t0x1b86: 0x1111, 0x1b87: 0xbba1, 0x1b88: 0xbba1, 0x1b89: 0xbbb9, 0x1b8a: 0xbbd1, 0x1b8b: 0x10e1,\n\t0x1b8c: 0x10f9, 0x1b8d: 0xbbe9, 0x1b8e: 0x2079, 0x1b8f: 0xbc21, 0x1b90: 0xbac9, 0x1b91: 0x1429,\n\t0x1b92: 0xbb11, 0x1b93: 0x10e1, 0x1b94: 0x1111, 0x1b95: 0x2109, 0x1b96: 0xbab1, 0x1b97: 0x1099,\n\t0x1b98: 0x10b1, 0x1b99: 0x10c9, 0x1b9a: 0xbac9, 0x1b9b: 0xbae1, 0x1b9c: 0xbaf9, 0x1b9d: 0x1429,\n\t0x1b9e: 0x1a31, 0x1b9f: 0xbb11, 0x1ba0: 0xbb29, 0x1ba1: 0xbb41, 0x1ba2: 0xbb59, 0x1ba3: 0xbb71,\n\t0x1ba4: 0xbb89, 0x1ba5: 0x2109, 0x1ba6: 0x1111, 0x1ba7: 0x1429, 0x1ba8: 0xbba1, 0x1ba9: 0xbbb9,\n\t0x1baa: 0xbbd1, 0x1bab: 0x10e1, 0x1bac: 0x10f9, 0x1bad: 0xbbe9, 0x1bae: 0x2079, 0x1baf: 0xbc01,\n\t0x1bb0: 0xbab1, 0x1bb1: 0x1099, 0x1bb2: 0x10b1, 0x1bb3: 0x10c9, 0x1bb4: 0xbac9, 0x1bb5: 0xbae1,\n\t0x1bb6: 0xbaf9, 0x1bb7: 0x1429, 0x1bb8: 0x1a31, 0x1bb9: 0xbb11, 0x1bba: 0xbb29, 0x1bbb: 0xbb41,\n\t0x1bbc: 0xbb59, 0x1bbd: 0xbb71, 0x1bbe: 0xbb89, 0x1bbf: 0x2109,\n\t// Block 0x6f, offset 0x1bc0\n\t0x1bc0: 0x1111, 0x1bc1: 0xbba1, 0x1bc2: 0xbba1, 0x1bc3: 0xbbb9, 0x1bc4: 0xbbd1, 0x1bc5: 0x10e1,\n\t0x1bc6: 0x10f9, 0x1bc7: 0xbbe9, 0x1bc8: 0x2079, 0x1bc9: 0xbc21, 0x1bca: 0xbac9, 0x1bcb: 0x1429,\n\t0x1bcc: 0xbb11, 0x1bcd: 0x10e1, 0x1bce: 0x1111, 0x1bcf: 0x2109, 0x1bd0: 0xbab1, 0x1bd1: 0x1099,\n\t0x1bd2: 0x10b1, 0x1bd3: 0x10c9, 0x1bd4: 0xbac9, 0x1bd5: 0xbae1, 0x1bd6: 0xbaf9, 0x1bd7: 0x1429,\n\t0x1bd8: 0x1a31, 0x1bd9: 0xbb11, 0x1bda: 0xbb29, 0x1bdb: 0xbb41, 0x1bdc: 0xbb59, 0x1bdd: 0xbb71,\n\t0x1bde: 0xbb89, 0x1bdf: 0x2109, 0x1be0: 0x1111, 0x1be1: 0x1429, 0x1be2: 0xbba1, 0x1be3: 0xbbb9,\n\t0x1be4: 0xbbd1, 0x1be5: 0x10e1, 0x1be6: 0x10f9, 0x1be7: 0xbbe9, 0x1be8: 0x2079, 0x1be9: 0xbc01,\n\t0x1bea: 0xbab1, 0x1beb: 0x1099, 0x1bec: 0x10b1, 0x1bed: 0x10c9, 0x1bee: 0xbac9, 0x1bef: 0xbae1,\n\t0x1bf0: 0xbaf9, 0x1bf1: 0x1429, 0x1bf2: 0x1a31, 0x1bf3: 0xbb11, 0x1bf4: 0xbb29, 0x1bf5: 0xbb41,\n\t0x1bf6: 0xbb59, 0x1bf7: 0xbb71, 0x1bf8: 0xbb89, 0x1bf9: 0x2109, 0x1bfa: 0x1111, 0x1bfb: 0xbba1,\n\t0x1bfc: 0xbba1, 0x1bfd: 0xbbb9, 0x1bfe: 0xbbd1, 0x1bff: 0x10e1,\n\t// Block 0x70, offset 0x1c00\n\t0x1c00: 0x10f9, 0x1c01: 0xbbe9, 0x1c02: 0x2079, 0x1c03: 0xbc21, 0x1c04: 0xbac9, 0x1c05: 0x1429,\n\t0x1c06: 0xbb11, 0x1c07: 0x10e1, 0x1c08: 0x1111, 0x1c09: 0x2109, 0x1c0a: 0xbc41, 0x1c0b: 0xbc41,\n\t0x1c0c: 0x0040, 0x1c0d: 0x0040, 0x1c0e: 0x1f41, 0x1c0f: 0x00c9, 0x1c10: 0x0069, 0x1c11: 0x0079,\n\t0x1c12: 0x1f51, 0x1c13: 0x1f61, 0x1c14: 0x1f71, 0x1c15: 0x1f81, 0x1c16: 0x1f91, 0x1c17: 0x1fa1,\n\t0x1c18: 0x1f41, 0x1c19: 0x00c9, 0x1c1a: 0x0069, 0x1c1b: 0x0079, 0x1c1c: 0x1f51, 0x1c1d: 0x1f61,\n\t0x1c1e: 0x1f71, 0x1c1f: 0x1f81, 0x1c20: 0x1f91, 0x1c21: 0x1fa1, 0x1c22: 0x1f41, 0x1c23: 0x00c9,\n\t0x1c24: 0x0069, 0x1c25: 0x0079, 0x1c26: 0x1f51, 0x1c27: 0x1f61, 0x1c28: 0x1f71, 0x1c29: 0x1f81,\n\t0x1c2a: 0x1f91, 0x1c2b: 0x1fa1, 0x1c2c: 0x1f41, 0x1c2d: 0x00c9, 0x1c2e: 0x0069, 0x1c2f: 0x0079,\n\t0x1c30: 0x1f51, 0x1c31: 0x1f61, 0x1c32: 0x1f71, 0x1c33: 0x1f81, 0x1c34: 0x1f91, 0x1c35: 0x1fa1,\n\t0x1c36: 0x1f41, 0x1c37: 0x00c9, 0x1c38: 0x0069, 0x1c39: 0x0079, 0x1c3a: 0x1f51, 0x1c3b: 0x1f61,\n\t0x1c3c: 0x1f71, 0x1c3d: 0x1f81, 0x1c3e: 0x1f91, 0x1c3f: 0x1fa1,\n\t// Block 0x71, offset 0x1c40\n\t0x1c40: 0xe115, 0x1c41: 0xe115, 0x1c42: 0xe135, 0x1c43: 0xe135, 0x1c44: 0xe115, 0x1c45: 0xe115,\n\t0x1c46: 0xe175, 0x1c47: 0xe175, 0x1c48: 0xe115, 0x1c49: 0xe115, 0x1c4a: 0xe135, 0x1c4b: 0xe135,\n\t0x1c4c: 0xe115, 0x1c4d: 0xe115, 0x1c4e: 0xe1f5, 0x1c4f: 0xe1f5, 0x1c50: 0xe115, 0x1c51: 0xe115,\n\t0x1c52: 0xe135, 0x1c53: 0xe135, 0x1c54: 0xe115, 0x1c55: 0xe115, 0x1c56: 0xe175, 0x1c57: 0xe175,\n\t0x1c58: 0xe115, 0x1c59: 0xe115, 0x1c5a: 0xe135, 0x1c5b: 0xe135, 0x1c5c: 0xe115, 0x1c5d: 0xe115,\n\t0x1c5e: 0x8b05, 0x1c5f: 0x8b05, 0x1c60: 0x04b5, 0x1c61: 0x04b5, 0x1c62: 0x0a08, 0x1c63: 0x0a08,\n\t0x1c64: 0x0a08, 0x1c65: 0x0a08, 0x1c66: 0x0a08, 0x1c67: 0x0a08, 0x1c68: 0x0a08, 0x1c69: 0x0a08,\n\t0x1c6a: 0x0a08, 0x1c6b: 0x0a08, 0x1c6c: 0x0a08, 0x1c6d: 0x0a08, 0x1c6e: 0x0a08, 0x1c6f: 0x0a08,\n\t0x1c70: 0x0a08, 0x1c71: 0x0a08, 0x1c72: 0x0a08, 0x1c73: 0x0a08, 0x1c74: 0x0a08, 0x1c75: 0x0a08,\n\t0x1c76: 0x0a08, 0x1c77: 0x0a08, 0x1c78: 0x0a08, 0x1c79: 0x0a08, 0x1c7a: 0x0a08, 0x1c7b: 0x0a08,\n\t0x1c7c: 0x0a08, 0x1c7d: 0x0a08, 0x1c7e: 0x0a08, 0x1c7f: 0x0a08,\n\t// Block 0x72, offset 0x1c80\n\t0x1c80: 0xb189, 0x1c81: 0xb1a1, 0x1c82: 0xb201, 0x1c83: 0xb249, 0x1c84: 0x0040, 0x1c85: 0xb411,\n\t0x1c86: 0xb291, 0x1c87: 0xb219, 0x1c88: 0xb309, 0x1c89: 0xb429, 0x1c8a: 0xb399, 0x1c8b: 0xb3b1,\n\t0x1c8c: 0xb3c9, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0xb369, 0x1c91: 0xb2d9,\n\t0x1c92: 0xb381, 0x1c93: 0xb279, 0x1c94: 0xb2c1, 0x1c95: 0xb1d1, 0x1c96: 0xb1e9, 0x1c97: 0xb231,\n\t0x1c98: 0xb261, 0x1c99: 0xb2f1, 0x1c9a: 0xb321, 0x1c9b: 0xb351, 0x1c9c: 0xbc59, 0x1c9d: 0x7949,\n\t0x1c9e: 0xbc71, 0x1c9f: 0xbc89, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0x0040,\n\t0x1ca4: 0xb3f9, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0xb219, 0x1ca8: 0x0040, 0x1ca9: 0xb429,\n\t0x1caa: 0xb399, 0x1cab: 0xb3b1, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339,\n\t0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0x0040, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1,\n\t0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0x0040, 0x1cb9: 0xb2f1, 0x1cba: 0x0040, 0x1cbb: 0xb351,\n\t0x1cbc: 0x0040, 0x1cbd: 0x0040, 0x1cbe: 0x0040, 0x1cbf: 0x0040,\n\t// Block 0x73, offset 0x1cc0\n\t0x1cc0: 0x0040, 0x1cc1: 0x0040, 0x1cc2: 0xb201, 0x1cc3: 0x0040, 0x1cc4: 0x0040, 0x1cc5: 0x0040,\n\t0x1cc6: 0x0040, 0x1cc7: 0xb219, 0x1cc8: 0x0040, 0x1cc9: 0xb429, 0x1cca: 0x0040, 0x1ccb: 0xb3b1,\n\t0x1ccc: 0x0040, 0x1ccd: 0xb3e1, 0x1cce: 0xb2a9, 0x1ccf: 0xb339, 0x1cd0: 0x0040, 0x1cd1: 0xb2d9,\n\t0x1cd2: 0xb381, 0x1cd3: 0x0040, 0x1cd4: 0xb2c1, 0x1cd5: 0x0040, 0x1cd6: 0x0040, 0x1cd7: 0xb231,\n\t0x1cd8: 0x0040, 0x1cd9: 0xb2f1, 0x1cda: 0x0040, 0x1cdb: 0xb351, 0x1cdc: 0x0040, 0x1cdd: 0x7949,\n\t0x1cde: 0x0040, 0x1cdf: 0xbc89, 0x1ce0: 0x0040, 0x1ce1: 0xb1a1, 0x1ce2: 0xb201, 0x1ce3: 0x0040,\n\t0x1ce4: 0xb3f9, 0x1ce5: 0x0040, 0x1ce6: 0x0040, 0x1ce7: 0xb219, 0x1ce8: 0xb309, 0x1ce9: 0xb429,\n\t0x1cea: 0xb399, 0x1ceb: 0x0040, 0x1cec: 0xb3c9, 0x1ced: 0xb3e1, 0x1cee: 0xb2a9, 0x1cef: 0xb339,\n\t0x1cf0: 0xb369, 0x1cf1: 0xb2d9, 0x1cf2: 0xb381, 0x1cf3: 0x0040, 0x1cf4: 0xb2c1, 0x1cf5: 0xb1d1,\n\t0x1cf6: 0xb1e9, 0x1cf7: 0xb231, 0x1cf8: 0x0040, 0x1cf9: 0xb2f1, 0x1cfa: 0xb321, 0x1cfb: 0xb351,\n\t0x1cfc: 0xbc59, 0x1cfd: 0x0040, 0x1cfe: 0xbc71, 0x1cff: 0x0040,\n\t// Block 0x74, offset 0x1d00\n\t0x1d00: 0xb189, 0x1d01: 0xb1a1, 0x1d02: 0xb201, 0x1d03: 0xb249, 0x1d04: 0xb3f9, 0x1d05: 0xb411,\n\t0x1d06: 0xb291, 0x1d07: 0xb219, 0x1d08: 0xb309, 0x1d09: 0xb429, 0x1d0a: 0x0040, 0x1d0b: 0xb3b1,\n\t0x1d0c: 0xb3c9, 0x1d0d: 0xb3e1, 0x1d0e: 0xb2a9, 0x1d0f: 0xb339, 0x1d10: 0xb369, 0x1d11: 0xb2d9,\n\t0x1d12: 0xb381, 0x1d13: 0xb279, 0x1d14: 0xb2c1, 0x1d15: 0xb1d1, 0x1d16: 0xb1e9, 0x1d17: 0xb231,\n\t0x1d18: 0xb261, 0x1d19: 0xb2f1, 0x1d1a: 0xb321, 0x1d1b: 0xb351, 0x1d1c: 0x0040, 0x1d1d: 0x0040,\n\t0x1d1e: 0x0040, 0x1d1f: 0x0040, 0x1d20: 0x0040, 0x1d21: 0xb1a1, 0x1d22: 0xb201, 0x1d23: 0xb249,\n\t0x1d24: 0x0040, 0x1d25: 0xb411, 0x1d26: 0xb291, 0x1d27: 0xb219, 0x1d28: 0xb309, 0x1d29: 0xb429,\n\t0x1d2a: 0x0040, 0x1d2b: 0xb3b1, 0x1d2c: 0xb3c9, 0x1d2d: 0xb3e1, 0x1d2e: 0xb2a9, 0x1d2f: 0xb339,\n\t0x1d30: 0xb369, 0x1d31: 0xb2d9, 0x1d32: 0xb381, 0x1d33: 0xb279, 0x1d34: 0xb2c1, 0x1d35: 0xb1d1,\n\t0x1d36: 0xb1e9, 0x1d37: 0xb231, 0x1d38: 0xb261, 0x1d39: 0xb2f1, 0x1d3a: 0xb321, 0x1d3b: 0xb351,\n\t0x1d3c: 0x0040, 0x1d3d: 0x0040, 0x1d3e: 0x0040, 0x1d3f: 0x0040,\n\t// Block 0x75, offset 0x1d40\n\t0x1d40: 0x0040, 0x1d41: 0xbca2, 0x1d42: 0xbcba, 0x1d43: 0xbcd2, 0x1d44: 0xbcea, 0x1d45: 0xbd02,\n\t0x1d46: 0xbd1a, 0x1d47: 0xbd32, 0x1d48: 0xbd4a, 0x1d49: 0xbd62, 0x1d4a: 0xbd7a, 0x1d4b: 0x0018,\n\t0x1d4c: 0x0018, 0x1d4d: 0x0040, 0x1d4e: 0x0040, 0x1d4f: 0x0040, 0x1d50: 0xbd92, 0x1d51: 0xbdb2,\n\t0x1d52: 0xbdd2, 0x1d53: 0xbdf2, 0x1d54: 0xbe12, 0x1d55: 0xbe32, 0x1d56: 0xbe52, 0x1d57: 0xbe72,\n\t0x1d58: 0xbe92, 0x1d59: 0xbeb2, 0x1d5a: 0xbed2, 0x1d5b: 0xbef2, 0x1d5c: 0xbf12, 0x1d5d: 0xbf32,\n\t0x1d5e: 0xbf52, 0x1d5f: 0xbf72, 0x1d60: 0xbf92, 0x1d61: 0xbfb2, 0x1d62: 0xbfd2, 0x1d63: 0xbff2,\n\t0x1d64: 0xc012, 0x1d65: 0xc032, 0x1d66: 0xc052, 0x1d67: 0xc072, 0x1d68: 0xc092, 0x1d69: 0xc0b2,\n\t0x1d6a: 0xc0d1, 0x1d6b: 0x1159, 0x1d6c: 0x0269, 0x1d6d: 0x6671, 0x1d6e: 0xc111, 0x1d6f: 0x0040,\n\t0x1d70: 0x0039, 0x1d71: 0x0ee9, 0x1d72: 0x1159, 0x1d73: 0x0ef9, 0x1d74: 0x0f09, 0x1d75: 0x1199,\n\t0x1d76: 0x0f31, 0x1d77: 0x0249, 0x1d78: 0x0f41, 0x1d79: 0x0259, 0x1d7a: 0x0f51, 0x1d7b: 0x0359,\n\t0x1d7c: 0x0f61, 0x1d7d: 0x0f71, 0x1d7e: 0x00d9, 0x1d7f: 0x0f99,\n\t// Block 0x76, offset 0x1d80\n\t0x1d80: 0x2039, 0x1d81: 0x0269, 0x1d82: 0x01d9, 0x1d83: 0x0fa9, 0x1d84: 0x0fb9, 0x1d85: 0x1089,\n\t0x1d86: 0x0279, 0x1d87: 0x0369, 0x1d88: 0x0289, 0x1d89: 0x13d1, 0x1d8a: 0xc129, 0x1d8b: 0x65b1,\n\t0x1d8c: 0xc141, 0x1d8d: 0x1441, 0x1d8e: 0xc159, 0x1d8f: 0xc179, 0x1d90: 0x0018, 0x1d91: 0x0018,\n\t0x1d92: 0x0018, 0x1d93: 0x0018, 0x1d94: 0x0018, 0x1d95: 0x0018, 0x1d96: 0x0018, 0x1d97: 0x0018,\n\t0x1d98: 0x0018, 0x1d99: 0x0018, 0x1d9a: 0x0018, 0x1d9b: 0x0018, 0x1d9c: 0x0018, 0x1d9d: 0x0018,\n\t0x1d9e: 0x0018, 0x1d9f: 0x0018, 0x1da0: 0x0018, 0x1da1: 0x0018, 0x1da2: 0x0018, 0x1da3: 0x0018,\n\t0x1da4: 0x0018, 0x1da5: 0x0018, 0x1da6: 0x0018, 0x1da7: 0x0018, 0x1da8: 0x0018, 0x1da9: 0x0018,\n\t0x1daa: 0xc191, 0x1dab: 0xc1a9, 0x1dac: 0x0040, 0x1dad: 0x0040, 0x1dae: 0x0040, 0x1daf: 0x0040,\n\t0x1db0: 0x0018, 0x1db1: 0x0018, 0x1db2: 0x0018, 0x1db3: 0x0018, 0x1db4: 0x0018, 0x1db5: 0x0018,\n\t0x1db6: 0x0018, 0x1db7: 0x0018, 0x1db8: 0x0018, 0x1db9: 0x0018, 0x1dba: 0x0018, 0x1dbb: 0x0018,\n\t0x1dbc: 0x0018, 0x1dbd: 0x0018, 0x1dbe: 0x0018, 0x1dbf: 0x0018,\n\t// Block 0x77, offset 0x1dc0\n\t0x1dc0: 0xc1d9, 0x1dc1: 0xc211, 0x1dc2: 0xc249, 0x1dc3: 0x0040, 0x1dc4: 0x0040, 0x1dc5: 0x0040,\n\t0x1dc6: 0x0040, 0x1dc7: 0x0040, 0x1dc8: 0x0040, 0x1dc9: 0x0040, 0x1dca: 0x0040, 0x1dcb: 0x0040,\n\t0x1dcc: 0x0040, 0x1dcd: 0x0040, 0x1dce: 0x0040, 0x1dcf: 0x0040, 0x1dd0: 0xc269, 0x1dd1: 0xc289,\n\t0x1dd2: 0xc2a9, 0x1dd3: 0xc2c9, 0x1dd4: 0xc2e9, 0x1dd5: 0xc309, 0x1dd6: 0xc329, 0x1dd7: 0xc349,\n\t0x1dd8: 0xc369, 0x1dd9: 0xc389, 0x1dda: 0xc3a9, 0x1ddb: 0xc3c9, 0x1ddc: 0xc3e9, 0x1ddd: 0xc409,\n\t0x1dde: 0xc429, 0x1ddf: 0xc449, 0x1de0: 0xc469, 0x1de1: 0xc489, 0x1de2: 0xc4a9, 0x1de3: 0xc4c9,\n\t0x1de4: 0xc4e9, 0x1de5: 0xc509, 0x1de6: 0xc529, 0x1de7: 0xc549, 0x1de8: 0xc569, 0x1de9: 0xc589,\n\t0x1dea: 0xc5a9, 0x1deb: 0xc5c9, 0x1dec: 0xc5e9, 0x1ded: 0xc609, 0x1dee: 0xc629, 0x1def: 0xc649,\n\t0x1df0: 0xc669, 0x1df1: 0xc689, 0x1df2: 0xc6a9, 0x1df3: 0xc6c9, 0x1df4: 0xc6e9, 0x1df5: 0xc709,\n\t0x1df6: 0xc729, 0x1df7: 0xc749, 0x1df8: 0xc769, 0x1df9: 0xc789, 0x1dfa: 0xc7a9, 0x1dfb: 0xc7c9,\n\t0x1dfc: 0x0040, 0x1dfd: 0x0040, 0x1dfe: 0x0040, 0x1dff: 0x0040,\n\t// Block 0x78, offset 0x1e00\n\t0x1e00: 0xcaf9, 0x1e01: 0xcb19, 0x1e02: 0xcb39, 0x1e03: 0x8b1d, 0x1e04: 0xcb59, 0x1e05: 0xcb79,\n\t0x1e06: 0xcb99, 0x1e07: 0xcbb9, 0x1e08: 0xcbd9, 0x1e09: 0xcbf9, 0x1e0a: 0xcc19, 0x1e0b: 0xcc39,\n\t0x1e0c: 0xcc59, 0x1e0d: 0x8b3d, 0x1e0e: 0xcc79, 0x1e0f: 0xcc99, 0x1e10: 0xccb9, 0x1e11: 0xccd9,\n\t0x1e12: 0x8b5d, 0x1e13: 0xccf9, 0x1e14: 0xcd19, 0x1e15: 0xc429, 0x1e16: 0x8b7d, 0x1e17: 0xcd39,\n\t0x1e18: 0xcd59, 0x1e19: 0xcd79, 0x1e1a: 0xcd99, 0x1e1b: 0xcdb9, 0x1e1c: 0x8b9d, 0x1e1d: 0xcdd9,\n\t0x1e1e: 0xcdf9, 0x1e1f: 0xce19, 0x1e20: 0xce39, 0x1e21: 0xce59, 0x1e22: 0xc789, 0x1e23: 0xce79,\n\t0x1e24: 0xce99, 0x1e25: 0xceb9, 0x1e26: 0xced9, 0x1e27: 0xcef9, 0x1e28: 0xcf19, 0x1e29: 0xcf39,\n\t0x1e2a: 0xcf59, 0x1e2b: 0xcf79, 0x1e2c: 0xcf99, 0x1e2d: 0xcfb9, 0x1e2e: 0xcfd9, 0x1e2f: 0xcff9,\n\t0x1e30: 0xd019, 0x1e31: 0xd039, 0x1e32: 0xd039, 0x1e33: 0xd039, 0x1e34: 0x8bbd, 0x1e35: 0xd059,\n\t0x1e36: 0xd079, 0x1e37: 0xd099, 0x1e38: 0x8bdd, 0x1e39: 0xd0b9, 0x1e3a: 0xd0d9, 0x1e3b: 0xd0f9,\n\t0x1e3c: 0xd119, 0x1e3d: 0xd139, 0x1e3e: 0xd159, 0x1e3f: 0xd179,\n\t// Block 0x79, offset 0x1e40\n\t0x1e40: 0xd199, 0x1e41: 0xd1b9, 0x1e42: 0xd1d9, 0x1e43: 0xd1f9, 0x1e44: 0xd219, 0x1e45: 0xd239,\n\t0x1e46: 0xd239, 0x1e47: 0xd259, 0x1e48: 0xd279, 0x1e49: 0xd299, 0x1e4a: 0xd2b9, 0x1e4b: 0xd2d9,\n\t0x1e4c: 0xd2f9, 0x1e4d: 0xd319, 0x1e4e: 0xd339, 0x1e4f: 0xd359, 0x1e50: 0xd379, 0x1e51: 0xd399,\n\t0x1e52: 0xd3b9, 0x1e53: 0xd3d9, 0x1e54: 0xd3f9, 0x1e55: 0xd419, 0x1e56: 0xd439, 0x1e57: 0xd459,\n\t0x1e58: 0xd479, 0x1e59: 0x8bfd, 0x1e5a: 0xd499, 0x1e5b: 0xd4b9, 0x1e5c: 0xd4d9, 0x1e5d: 0xc309,\n\t0x1e5e: 0xd4f9, 0x1e5f: 0xd519, 0x1e60: 0x8c1d, 0x1e61: 0x8c3d, 0x1e62: 0xd539, 0x1e63: 0xd559,\n\t0x1e64: 0xd579, 0x1e65: 0xd599, 0x1e66: 0xd5b9, 0x1e67: 0xd5d9, 0x1e68: 0x2040, 0x1e69: 0xd5f9,\n\t0x1e6a: 0xd619, 0x1e6b: 0xd619, 0x1e6c: 0x8c5d, 0x1e6d: 0xd639, 0x1e6e: 0xd659, 0x1e6f: 0xd679,\n\t0x1e70: 0xd699, 0x1e71: 0x8c7d, 0x1e72: 0xd6b9, 0x1e73: 0xd6d9, 0x1e74: 0x2040, 0x1e75: 0xd6f9,\n\t0x1e76: 0xd719, 0x1e77: 0xd739, 0x1e78: 0xd759, 0x1e79: 0xd779, 0x1e7a: 0xd799, 0x1e7b: 0x8c9d,\n\t0x1e7c: 0xd7b9, 0x1e7d: 0x8cbd, 0x1e7e: 0xd7d9, 0x1e7f: 0xd7f9,\n\t// Block 0x7a, offset 0x1e80\n\t0x1e80: 0xd819, 0x1e81: 0xd839, 0x1e82: 0xd859, 0x1e83: 0xd879, 0x1e84: 0xd899, 0x1e85: 0xd8b9,\n\t0x1e86: 0xd8d9, 0x1e87: 0xd8f9, 0x1e88: 0xd919, 0x1e89: 0x8cdd, 0x1e8a: 0xd939, 0x1e8b: 0xd959,\n\t0x1e8c: 0xd979, 0x1e8d: 0xd999, 0x1e8e: 0xd9b9, 0x1e8f: 0x8cfd, 0x1e90: 0xd9d9, 0x1e91: 0x8d1d,\n\t0x1e92: 0x8d3d, 0x1e93: 0xd9f9, 0x1e94: 0xda19, 0x1e95: 0xda19, 0x1e96: 0xda39, 0x1e97: 0x8d5d,\n\t0x1e98: 0x8d7d, 0x1e99: 0xda59, 0x1e9a: 0xda79, 0x1e9b: 0xda99, 0x1e9c: 0xdab9, 0x1e9d: 0xdad9,\n\t0x1e9e: 0xdaf9, 0x1e9f: 0xdb19, 0x1ea0: 0xdb39, 0x1ea1: 0xdb59, 0x1ea2: 0xdb79, 0x1ea3: 0xdb99,\n\t0x1ea4: 0x8d9d, 0x1ea5: 0xdbb9, 0x1ea6: 0xdbd9, 0x1ea7: 0xdbf9, 0x1ea8: 0xdc19, 0x1ea9: 0xdbf9,\n\t0x1eaa: 0xdc39, 0x1eab: 0xdc59, 0x1eac: 0xdc79, 0x1ead: 0xdc99, 0x1eae: 0xdcb9, 0x1eaf: 0xdcd9,\n\t0x1eb0: 0xdcf9, 0x1eb1: 0xdd19, 0x1eb2: 0xdd39, 0x1eb3: 0xdd59, 0x1eb4: 0xdd79, 0x1eb5: 0xdd99,\n\t0x1eb6: 0xddb9, 0x1eb7: 0xddd9, 0x1eb8: 0x8dbd, 0x1eb9: 0xddf9, 0x1eba: 0xde19, 0x1ebb: 0xde39,\n\t0x1ebc: 0xde59, 0x1ebd: 0xde79, 0x1ebe: 0x8ddd, 0x1ebf: 0xde99,\n\t// Block 0x7b, offset 0x1ec0\n\t0x1ec0: 0xe599, 0x1ec1: 0xe5b9, 0x1ec2: 0xe5d9, 0x1ec3: 0xe5f9, 0x1ec4: 0xe619, 0x1ec5: 0xe639,\n\t0x1ec6: 0x8efd, 0x1ec7: 0xe659, 0x1ec8: 0xe679, 0x1ec9: 0xe699, 0x1eca: 0xe6b9, 0x1ecb: 0xe6d9,\n\t0x1ecc: 0xe6f9, 0x1ecd: 0x8f1d, 0x1ece: 0xe719, 0x1ecf: 0xe739, 0x1ed0: 0x8f3d, 0x1ed1: 0x8f5d,\n\t0x1ed2: 0xe759, 0x1ed3: 0xe779, 0x1ed4: 0xe799, 0x1ed5: 0xe7b9, 0x1ed6: 0xe7d9, 0x1ed7: 0xe7f9,\n\t0x1ed8: 0xe819, 0x1ed9: 0xe839, 0x1eda: 0xe859, 0x1edb: 0x8f7d, 0x1edc: 0xe879, 0x1edd: 0x8f9d,\n\t0x1ede: 0xe899, 0x1edf: 0x2040, 0x1ee0: 0xe8b9, 0x1ee1: 0xe8d9, 0x1ee2: 0xe8f9, 0x1ee3: 0x8fbd,\n\t0x1ee4: 0xe919, 0x1ee5: 0xe939, 0x1ee6: 0x8fdd, 0x1ee7: 0x8ffd, 0x1ee8: 0xe959, 0x1ee9: 0xe979,\n\t0x1eea: 0xe999, 0x1eeb: 0xe9b9, 0x1eec: 0xe9d9, 0x1eed: 0xe9d9, 0x1eee: 0xe9f9, 0x1eef: 0xea19,\n\t0x1ef0: 0xea39, 0x1ef1: 0xea59, 0x1ef2: 0xea79, 0x1ef3: 0xea99, 0x1ef4: 0xeab9, 0x1ef5: 0x901d,\n\t0x1ef6: 0xead9, 0x1ef7: 0x903d, 0x1ef8: 0xeaf9, 0x1ef9: 0x905d, 0x1efa: 0xeb19, 0x1efb: 0x907d,\n\t0x1efc: 0x909d, 0x1efd: 0x90bd, 0x1efe: 0xeb39, 0x1eff: 0xeb59,\n\t// Block 0x7c, offset 0x1f00\n\t0x1f00: 0xeb79, 0x1f01: 0x90dd, 0x1f02: 0x90fd, 0x1f03: 0x911d, 0x1f04: 0x913d, 0x1f05: 0xeb99,\n\t0x1f06: 0xebb9, 0x1f07: 0xebb9, 0x1f08: 0xebd9, 0x1f09: 0xebf9, 0x1f0a: 0xec19, 0x1f0b: 0xec39,\n\t0x1f0c: 0xec59, 0x1f0d: 0x915d, 0x1f0e: 0xec79, 0x1f0f: 0xec99, 0x1f10: 0xecb9, 0x1f11: 0xecd9,\n\t0x1f12: 0x917d, 0x1f13: 0xecf9, 0x1f14: 0x919d, 0x1f15: 0x91bd, 0x1f16: 0xed19, 0x1f17: 0xed39,\n\t0x1f18: 0xed59, 0x1f19: 0xed79, 0x1f1a: 0xed99, 0x1f1b: 0xedb9, 0x1f1c: 0x91dd, 0x1f1d: 0x91fd,\n\t0x1f1e: 0x921d, 0x1f1f: 0x2040, 0x1f20: 0xedd9, 0x1f21: 0x923d, 0x1f22: 0xedf9, 0x1f23: 0xee19,\n\t0x1f24: 0xee39, 0x1f25: 0x925d, 0x1f26: 0xee59, 0x1f27: 0xee79, 0x1f28: 0xee99, 0x1f29: 0xeeb9,\n\t0x1f2a: 0xeed9, 0x1f2b: 0x927d, 0x1f2c: 0xeef9, 0x1f2d: 0xef19, 0x1f2e: 0xef39, 0x1f2f: 0xef59,\n\t0x1f30: 0xef79, 0x1f31: 0xef99, 0x1f32: 0x929d, 0x1f33: 0x92bd, 0x1f34: 0xefb9, 0x1f35: 0x92dd,\n\t0x1f36: 0xefd9, 0x1f37: 0x92fd, 0x1f38: 0xeff9, 0x1f39: 0xf019, 0x1f3a: 0xf039, 0x1f3b: 0x931d,\n\t0x1f3c: 0x933d, 0x1f3d: 0xf059, 0x1f3e: 0x935d, 0x1f3f: 0xf079,\n\t// Block 0x7d, offset 0x1f40\n\t0x1f40: 0xf6b9, 0x1f41: 0xf6d9, 0x1f42: 0xf6f9, 0x1f43: 0xf719, 0x1f44: 0xf739, 0x1f45: 0x951d,\n\t0x1f46: 0xf759, 0x1f47: 0xf779, 0x1f48: 0xf799, 0x1f49: 0xf7b9, 0x1f4a: 0xf7d9, 0x1f4b: 0x953d,\n\t0x1f4c: 0x955d, 0x1f4d: 0xf7f9, 0x1f4e: 0xf819, 0x1f4f: 0xf839, 0x1f50: 0xf859, 0x1f51: 0xf879,\n\t0x1f52: 0xf899, 0x1f53: 0x957d, 0x1f54: 0xf8b9, 0x1f55: 0xf8d9, 0x1f56: 0xf8f9, 0x1f57: 0xf919,\n\t0x1f58: 0x959d, 0x1f59: 0x95bd, 0x1f5a: 0xf939, 0x1f5b: 0xf959, 0x1f5c: 0xf979, 0x1f5d: 0x95dd,\n\t0x1f5e: 0xf999, 0x1f5f: 0xf9b9, 0x1f60: 0x6815, 0x1f61: 0x95fd, 0x1f62: 0xf9d9, 0x1f63: 0xf9f9,\n\t0x1f64: 0xfa19, 0x1f65: 0x961d, 0x1f66: 0xfa39, 0x1f67: 0xfa59, 0x1f68: 0xfa79, 0x1f69: 0xfa99,\n\t0x1f6a: 0xfab9, 0x1f6b: 0xfad9, 0x1f6c: 0xfaf9, 0x1f6d: 0x963d, 0x1f6e: 0xfb19, 0x1f6f: 0xfb39,\n\t0x1f70: 0xfb59, 0x1f71: 0x965d, 0x1f72: 0xfb79, 0x1f73: 0xfb99, 0x1f74: 0xfbb9, 0x1f75: 0xfbd9,\n\t0x1f76: 0x7b35, 0x1f77: 0x967d, 0x1f78: 0xfbf9, 0x1f79: 0xfc19, 0x1f7a: 0xfc39, 0x1f7b: 0x969d,\n\t0x1f7c: 0xfc59, 0x1f7d: 0x96bd, 0x1f7e: 0xfc79, 0x1f7f: 0xfc79,\n\t// Block 0x7e, offset 0x1f80\n\t0x1f80: 0xfc99, 0x1f81: 0x96dd, 0x1f82: 0xfcb9, 0x1f83: 0xfcd9, 0x1f84: 0xfcf9, 0x1f85: 0xfd19,\n\t0x1f86: 0xfd39, 0x1f87: 0xfd59, 0x1f88: 0xfd79, 0x1f89: 0x96fd, 0x1f8a: 0xfd99, 0x1f8b: 0xfdb9,\n\t0x1f8c: 0xfdd9, 0x1f8d: 0xfdf9, 0x1f8e: 0xfe19, 0x1f8f: 0xfe39, 0x1f90: 0x971d, 0x1f91: 0xfe59,\n\t0x1f92: 0x973d, 0x1f93: 0x975d, 0x1f94: 0x977d, 0x1f95: 0xfe79, 0x1f96: 0xfe99, 0x1f97: 0xfeb9,\n\t0x1f98: 0xfed9, 0x1f99: 0xfef9, 0x1f9a: 0xff19, 0x1f9b: 0xff39, 0x1f9c: 0xff59, 0x1f9d: 0x979d,\n\t0x1f9e: 0x0040, 0x1f9f: 0x0040, 0x1fa0: 0x0040, 0x1fa1: 0x0040, 0x1fa2: 0x0040, 0x1fa3: 0x0040,\n\t0x1fa4: 0x0040, 0x1fa5: 0x0040, 0x1fa6: 0x0040, 0x1fa7: 0x0040, 0x1fa8: 0x0040, 0x1fa9: 0x0040,\n\t0x1faa: 0x0040, 0x1fab: 0x0040, 0x1fac: 0x0040, 0x1fad: 0x0040, 0x1fae: 0x0040, 0x1faf: 0x0040,\n\t0x1fb0: 0x0040, 0x1fb1: 0x0040, 0x1fb2: 0x0040, 0x1fb3: 0x0040, 0x1fb4: 0x0040, 0x1fb5: 0x0040,\n\t0x1fb6: 0x0040, 0x1fb7: 0x0040, 0x1fb8: 0x0040, 0x1fb9: 0x0040, 0x1fba: 0x0040, 0x1fbb: 0x0040,\n\t0x1fbc: 0x0040, 0x1fbd: 0x0040, 0x1fbe: 0x0040, 0x1fbf: 0x0040,\n}\n\n// idnaIndex: 36 blocks, 2304 entries, 4608 bytes\n// Block 0 is the zero block.\nvar idnaIndex = [2304]uint16{\n\t// Block 0x0, offset 0x0\n\t// Block 0x1, offset 0x40\n\t// Block 0x2, offset 0x80\n\t// Block 0x3, offset 0xc0\n\t0xc2: 0x01, 0xc3: 0x7d, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05,\n\t0xc8: 0x06, 0xc9: 0x7e, 0xca: 0x7f, 0xcb: 0x07, 0xcc: 0x80, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a,\n\t0xd0: 0x81, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x82, 0xd6: 0x83, 0xd7: 0x84,\n\t0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x85, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x86, 0xde: 0x87, 0xdf: 0x88,\n\t0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07,\n\t0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c,\n\t0xf0: 0x1d, 0xf1: 0x1e, 0xf2: 0x1e, 0xf3: 0x20, 0xf4: 0x21,\n\t// Block 0x4, offset 0x100\n\t0x120: 0x89, 0x121: 0x13, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x14, 0x126: 0x15, 0x127: 0x16,\n\t0x128: 0x17, 0x129: 0x18, 0x12a: 0x19, 0x12b: 0x1a, 0x12c: 0x1b, 0x12d: 0x1c, 0x12e: 0x1d, 0x12f: 0x8d,\n\t0x130: 0x8e, 0x131: 0x1e, 0x132: 0x1f, 0x133: 0x20, 0x134: 0x8f, 0x135: 0x21, 0x136: 0x90, 0x137: 0x91,\n\t0x138: 0x92, 0x139: 0x93, 0x13a: 0x22, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x23, 0x13e: 0x24, 0x13f: 0x96,\n\t// Block 0x5, offset 0x140\n\t0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9d, 0x147: 0x9e,\n\t0x148: 0x9f, 0x149: 0xa0, 0x14a: 0xa1, 0x14b: 0xa2, 0x14c: 0xa3, 0x14d: 0xa4, 0x14e: 0xa5, 0x14f: 0xa6,\n\t0x150: 0xa7, 0x151: 0x9f, 0x152: 0x9f, 0x153: 0x9f, 0x154: 0x9f, 0x155: 0x9f, 0x156: 0x9f, 0x157: 0x9f,\n\t0x158: 0x9f, 0x159: 0xa8, 0x15a: 0xa9, 0x15b: 0xaa, 0x15c: 0xab, 0x15d: 0xac, 0x15e: 0xad, 0x15f: 0xae,\n\t0x160: 0xaf, 0x161: 0xb0, 0x162: 0xb1, 0x163: 0xb2, 0x164: 0xb3, 0x165: 0xb4, 0x166: 0xb5, 0x167: 0xb6,\n\t0x168: 0xb7, 0x169: 0xb8, 0x16a: 0xb9, 0x16b: 0xba, 0x16c: 0xbb, 0x16d: 0xbc, 0x16e: 0xbd, 0x16f: 0xbe,\n\t0x170: 0xbf, 0x171: 0xc0, 0x172: 0xc1, 0x173: 0xc2, 0x174: 0x25, 0x175: 0x26, 0x176: 0x27, 0x177: 0xc3,\n\t0x178: 0x28, 0x179: 0x28, 0x17a: 0x29, 0x17b: 0x28, 0x17c: 0xc4, 0x17d: 0x2a, 0x17e: 0x2b, 0x17f: 0x2c,\n\t// Block 0x6, offset 0x180\n\t0x180: 0x2d, 0x181: 0x2e, 0x182: 0x2f, 0x183: 0xc5, 0x184: 0x30, 0x185: 0x31, 0x186: 0xc6, 0x187: 0x9b,\n\t0x188: 0xc7, 0x189: 0xc8, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc9, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0x9b,\n\t0x190: 0xca, 0x191: 0x32, 0x192: 0x33, 0x193: 0x34, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b,\n\t0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b,\n\t0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b,\n\t0x1a8: 0xcb, 0x1a9: 0xcc, 0x1aa: 0x9b, 0x1ab: 0xcd, 0x1ac: 0x9b, 0x1ad: 0xce, 0x1ae: 0xcf, 0x1af: 0xd0,\n\t0x1b0: 0xd1, 0x1b1: 0x35, 0x1b2: 0x28, 0x1b3: 0x36, 0x1b4: 0xd2, 0x1b5: 0xd3, 0x1b6: 0xd4, 0x1b7: 0xd5,\n\t0x1b8: 0xd6, 0x1b9: 0xd7, 0x1ba: 0xd8, 0x1bb: 0xd9, 0x1bc: 0xda, 0x1bd: 0xdb, 0x1be: 0xdc, 0x1bf: 0x37,\n\t// Block 0x7, offset 0x1c0\n\t0x1c0: 0x38, 0x1c1: 0xdd, 0x1c2: 0xde, 0x1c3: 0xdf, 0x1c4: 0xe0, 0x1c5: 0x39, 0x1c6: 0x3a, 0x1c7: 0xe1,\n\t0x1c8: 0xe2, 0x1c9: 0x3b, 0x1ca: 0x3c, 0x1cb: 0x3d, 0x1cc: 0x3e, 0x1cd: 0x3f, 0x1ce: 0x40, 0x1cf: 0x41,\n\t0x1d0: 0x9f, 0x1d1: 0x9f, 0x1d2: 0x9f, 0x1d3: 0x9f, 0x1d4: 0x9f, 0x1d5: 0x9f, 0x1d6: 0x9f, 0x1d7: 0x9f,\n\t0x1d8: 0x9f, 0x1d9: 0x9f, 0x1da: 0x9f, 0x1db: 0x9f, 0x1dc: 0x9f, 0x1dd: 0x9f, 0x1de: 0x9f, 0x1df: 0x9f,\n\t0x1e0: 0x9f, 0x1e1: 0x9f, 0x1e2: 0x9f, 0x1e3: 0x9f, 0x1e4: 0x9f, 0x1e5: 0x9f, 0x1e6: 0x9f, 0x1e7: 0x9f,\n\t0x1e8: 0x9f, 0x1e9: 0x9f, 0x1ea: 0x9f, 0x1eb: 0x9f, 0x1ec: 0x9f, 0x1ed: 0x9f, 0x1ee: 0x9f, 0x1ef: 0x9f,\n\t0x1f0: 0x9f, 0x1f1: 0x9f, 0x1f2: 0x9f, 0x1f3: 0x9f, 0x1f4: 0x9f, 0x1f5: 0x9f, 0x1f6: 0x9f, 0x1f7: 0x9f,\n\t0x1f8: 0x9f, 0x1f9: 0x9f, 0x1fa: 0x9f, 0x1fb: 0x9f, 0x1fc: 0x9f, 0x1fd: 0x9f, 0x1fe: 0x9f, 0x1ff: 0x9f,\n\t// Block 0x8, offset 0x200\n\t0x200: 0x9f, 0x201: 0x9f, 0x202: 0x9f, 0x203: 0x9f, 0x204: 0x9f, 0x205: 0x9f, 0x206: 0x9f, 0x207: 0x9f,\n\t0x208: 0x9f, 0x209: 0x9f, 0x20a: 0x9f, 0x20b: 0x9f, 0x20c: 0x9f, 0x20d: 0x9f, 0x20e: 0x9f, 0x20f: 0x9f,\n\t0x210: 0x9f, 0x211: 0x9f, 0x212: 0x9f, 0x213: 0x9f, 0x214: 0x9f, 0x215: 0x9f, 0x216: 0x9f, 0x217: 0x9f,\n\t0x218: 0x9f, 0x219: 0x9f, 0x21a: 0x9f, 0x21b: 0x9f, 0x21c: 0x9f, 0x21d: 0x9f, 0x21e: 0x9f, 0x21f: 0x9f,\n\t0x220: 0x9f, 0x221: 0x9f, 0x222: 0x9f, 0x223: 0x9f, 0x224: 0x9f, 0x225: 0x9f, 0x226: 0x9f, 0x227: 0x9f,\n\t0x228: 0x9f, 0x229: 0x9f, 0x22a: 0x9f, 0x22b: 0x9f, 0x22c: 0x9f, 0x22d: 0x9f, 0x22e: 0x9f, 0x22f: 0x9f,\n\t0x230: 0x9f, 0x231: 0x9f, 0x232: 0x9f, 0x233: 0x9f, 0x234: 0x9f, 0x235: 0x9f, 0x236: 0xb2, 0x237: 0x9b,\n\t0x238: 0x9f, 0x239: 0x9f, 0x23a: 0x9f, 0x23b: 0x9f, 0x23c: 0x9f, 0x23d: 0x9f, 0x23e: 0x9f, 0x23f: 0x9f,\n\t// Block 0x9, offset 0x240\n\t0x240: 0x9f, 0x241: 0x9f, 0x242: 0x9f, 0x243: 0x9f, 0x244: 0x9f, 0x245: 0x9f, 0x246: 0x9f, 0x247: 0x9f,\n\t0x248: 0x9f, 0x249: 0x9f, 0x24a: 0x9f, 0x24b: 0x9f, 0x24c: 0x9f, 0x24d: 0x9f, 0x24e: 0x9f, 0x24f: 0x9f,\n\t0x250: 0x9f, 0x251: 0x9f, 0x252: 0x9f, 0x253: 0x9f, 0x254: 0x9f, 0x255: 0x9f, 0x256: 0x9f, 0x257: 0x9f,\n\t0x258: 0x9f, 0x259: 0x9f, 0x25a: 0x9f, 0x25b: 0x9f, 0x25c: 0x9f, 0x25d: 0x9f, 0x25e: 0x9f, 0x25f: 0x9f,\n\t0x260: 0x9f, 0x261: 0x9f, 0x262: 0x9f, 0x263: 0x9f, 0x264: 0x9f, 0x265: 0x9f, 0x266: 0x9f, 0x267: 0x9f,\n\t0x268: 0x9f, 0x269: 0x9f, 0x26a: 0x9f, 0x26b: 0x9f, 0x26c: 0x9f, 0x26d: 0x9f, 0x26e: 0x9f, 0x26f: 0x9f,\n\t0x270: 0x9f, 0x271: 0x9f, 0x272: 0x9f, 0x273: 0x9f, 0x274: 0x9f, 0x275: 0x9f, 0x276: 0x9f, 0x277: 0x9f,\n\t0x278: 0x9f, 0x279: 0x9f, 0x27a: 0x9f, 0x27b: 0x9f, 0x27c: 0x9f, 0x27d: 0x9f, 0x27e: 0x9f, 0x27f: 0x9f,\n\t// Block 0xa, offset 0x280\n\t0x280: 0x9f, 0x281: 0x9f, 0x282: 0x9f, 0x283: 0x9f, 0x284: 0x9f, 0x285: 0x9f, 0x286: 0x9f, 0x287: 0x9f,\n\t0x288: 0x9f, 0x289: 0x9f, 0x28a: 0x9f, 0x28b: 0x9f, 0x28c: 0x9f, 0x28d: 0x9f, 0x28e: 0x9f, 0x28f: 0x9f,\n\t0x290: 0x9f, 0x291: 0x9f, 0x292: 0x9f, 0x293: 0x9f, 0x294: 0x9f, 0x295: 0x9f, 0x296: 0x9f, 0x297: 0x9f,\n\t0x298: 0x9f, 0x299: 0x9f, 0x29a: 0x9f, 0x29b: 0x9f, 0x29c: 0x9f, 0x29d: 0x9f, 0x29e: 0x9f, 0x29f: 0x9f,\n\t0x2a0: 0x9f, 0x2a1: 0x9f, 0x2a2: 0x9f, 0x2a3: 0x9f, 0x2a4: 0x9f, 0x2a5: 0x9f, 0x2a6: 0x9f, 0x2a7: 0x9f,\n\t0x2a8: 0x9f, 0x2a9: 0x9f, 0x2aa: 0x9f, 0x2ab: 0x9f, 0x2ac: 0x9f, 0x2ad: 0x9f, 0x2ae: 0x9f, 0x2af: 0x9f,\n\t0x2b0: 0x9f, 0x2b1: 0x9f, 0x2b2: 0x9f, 0x2b3: 0x9f, 0x2b4: 0x9f, 0x2b5: 0x9f, 0x2b6: 0x9f, 0x2b7: 0x9f,\n\t0x2b8: 0x9f, 0x2b9: 0x9f, 0x2ba: 0x9f, 0x2bb: 0x9f, 0x2bc: 0x9f, 0x2bd: 0x9f, 0x2be: 0x9f, 0x2bf: 0xe3,\n\t// Block 0xb, offset 0x2c0\n\t0x2c0: 0x9f, 0x2c1: 0x9f, 0x2c2: 0x9f, 0x2c3: 0x9f, 0x2c4: 0x9f, 0x2c5: 0x9f, 0x2c6: 0x9f, 0x2c7: 0x9f,\n\t0x2c8: 0x9f, 0x2c9: 0x9f, 0x2ca: 0x9f, 0x2cb: 0x9f, 0x2cc: 0x9f, 0x2cd: 0x9f, 0x2ce: 0x9f, 0x2cf: 0x9f,\n\t0x2d0: 0x9f, 0x2d1: 0x9f, 0x2d2: 0xe4, 0x2d3: 0xe5, 0x2d4: 0x9f, 0x2d5: 0x9f, 0x2d6: 0x9f, 0x2d7: 0x9f,\n\t0x2d8: 0xe6, 0x2d9: 0x42, 0x2da: 0x43, 0x2db: 0xe7, 0x2dc: 0x44, 0x2dd: 0x45, 0x2de: 0x46, 0x2df: 0xe8,\n\t0x2e0: 0xe9, 0x2e1: 0xea, 0x2e2: 0xeb, 0x2e3: 0xec, 0x2e4: 0xed, 0x2e5: 0xee, 0x2e6: 0xef, 0x2e7: 0xf0,\n\t0x2e8: 0xf1, 0x2e9: 0xf2, 0x2ea: 0xf3, 0x2eb: 0xf4, 0x2ec: 0xf5, 0x2ed: 0xf6, 0x2ee: 0xf7, 0x2ef: 0xf8,\n\t0x2f0: 0x9f, 0x2f1: 0x9f, 0x2f2: 0x9f, 0x2f3: 0x9f, 0x2f4: 0x9f, 0x2f5: 0x9f, 0x2f6: 0x9f, 0x2f7: 0x9f,\n\t0x2f8: 0x9f, 0x2f9: 0x9f, 0x2fa: 0x9f, 0x2fb: 0x9f, 0x2fc: 0x9f, 0x2fd: 0x9f, 0x2fe: 0x9f, 0x2ff: 0x9f,\n\t// Block 0xc, offset 0x300\n\t0x300: 0x9f, 0x301: 0x9f, 0x302: 0x9f, 0x303: 0x9f, 0x304: 0x9f, 0x305: 0x9f, 0x306: 0x9f, 0x307: 0x9f,\n\t0x308: 0x9f, 0x309: 0x9f, 0x30a: 0x9f, 0x30b: 0x9f, 0x30c: 0x9f, 0x30d: 0x9f, 0x30e: 0x9f, 0x30f: 0x9f,\n\t0x310: 0x9f, 0x311: 0x9f, 0x312: 0x9f, 0x313: 0x9f, 0x314: 0x9f, 0x315: 0x9f, 0x316: 0x9f, 0x317: 0x9f,\n\t0x318: 0x9f, 0x319: 0x9f, 0x31a: 0x9f, 0x31b: 0x9f, 0x31c: 0x9f, 0x31d: 0x9f, 0x31e: 0xf9, 0x31f: 0xfa,\n\t// Block 0xd, offset 0x340\n\t0x340: 0xba, 0x341: 0xba, 0x342: 0xba, 0x343: 0xba, 0x344: 0xba, 0x345: 0xba, 0x346: 0xba, 0x347: 0xba,\n\t0x348: 0xba, 0x349: 0xba, 0x34a: 0xba, 0x34b: 0xba, 0x34c: 0xba, 0x34d: 0xba, 0x34e: 0xba, 0x34f: 0xba,\n\t0x350: 0xba, 0x351: 0xba, 0x352: 0xba, 0x353: 0xba, 0x354: 0xba, 0x355: 0xba, 0x356: 0xba, 0x357: 0xba,\n\t0x358: 0xba, 0x359: 0xba, 0x35a: 0xba, 0x35b: 0xba, 0x35c: 0xba, 0x35d: 0xba, 0x35e: 0xba, 0x35f: 0xba,\n\t0x360: 0xba, 0x361: 0xba, 0x362: 0xba, 0x363: 0xba, 0x364: 0xba, 0x365: 0xba, 0x366: 0xba, 0x367: 0xba,\n\t0x368: 0xba, 0x369: 0xba, 0x36a: 0xba, 0x36b: 0xba, 0x36c: 0xba, 0x36d: 0xba, 0x36e: 0xba, 0x36f: 0xba,\n\t0x370: 0xba, 0x371: 0xba, 0x372: 0xba, 0x373: 0xba, 0x374: 0xba, 0x375: 0xba, 0x376: 0xba, 0x377: 0xba,\n\t0x378: 0xba, 0x379: 0xba, 0x37a: 0xba, 0x37b: 0xba, 0x37c: 0xba, 0x37d: 0xba, 0x37e: 0xba, 0x37f: 0xba,\n\t// Block 0xe, offset 0x380\n\t0x380: 0xba, 0x381: 0xba, 0x382: 0xba, 0x383: 0xba, 0x384: 0xba, 0x385: 0xba, 0x386: 0xba, 0x387: 0xba,\n\t0x388: 0xba, 0x389: 0xba, 0x38a: 0xba, 0x38b: 0xba, 0x38c: 0xba, 0x38d: 0xba, 0x38e: 0xba, 0x38f: 0xba,\n\t0x390: 0xba, 0x391: 0xba, 0x392: 0xba, 0x393: 0xba, 0x394: 0xba, 0x395: 0xba, 0x396: 0xba, 0x397: 0xba,\n\t0x398: 0xba, 0x399: 0xba, 0x39a: 0xba, 0x39b: 0xba, 0x39c: 0xba, 0x39d: 0xba, 0x39e: 0xba, 0x39f: 0xba,\n\t0x3a0: 0xba, 0x3a1: 0xba, 0x3a2: 0xba, 0x3a3: 0xba, 0x3a4: 0xfb, 0x3a5: 0xfc, 0x3a6: 0xfd, 0x3a7: 0xfe,\n\t0x3a8: 0x47, 0x3a9: 0xff, 0x3aa: 0x100, 0x3ab: 0x48, 0x3ac: 0x49, 0x3ad: 0x4a, 0x3ae: 0x4b, 0x3af: 0x4c,\n\t0x3b0: 0x101, 0x3b1: 0x4d, 0x3b2: 0x4e, 0x3b3: 0x4f, 0x3b4: 0x50, 0x3b5: 0x51, 0x3b6: 0x102, 0x3b7: 0x52,\n\t0x3b8: 0x53, 0x3b9: 0x54, 0x3ba: 0x55, 0x3bb: 0x56, 0x3bc: 0x57, 0x3bd: 0x58, 0x3be: 0x59, 0x3bf: 0x5a,\n\t// Block 0xf, offset 0x3c0\n\t0x3c0: 0x103, 0x3c1: 0x104, 0x3c2: 0x9f, 0x3c3: 0x105, 0x3c4: 0x106, 0x3c5: 0x9b, 0x3c6: 0x107, 0x3c7: 0x108,\n\t0x3c8: 0xba, 0x3c9: 0xba, 0x3ca: 0x109, 0x3cb: 0x10a, 0x3cc: 0x10b, 0x3cd: 0x10c, 0x3ce: 0x10d, 0x3cf: 0x10e,\n\t0x3d0: 0x10f, 0x3d1: 0x9f, 0x3d2: 0x110, 0x3d3: 0x111, 0x3d4: 0x112, 0x3d5: 0x113, 0x3d6: 0xba, 0x3d7: 0xba,\n\t0x3d8: 0x9f, 0x3d9: 0x9f, 0x3da: 0x9f, 0x3db: 0x9f, 0x3dc: 0x114, 0x3dd: 0x115, 0x3de: 0xba, 0x3df: 0xba,\n\t0x3e0: 0x116, 0x3e1: 0x117, 0x3e2: 0x118, 0x3e3: 0x119, 0x3e4: 0x11a, 0x3e5: 0xba, 0x3e6: 0x11b, 0x3e7: 0x11c,\n\t0x3e8: 0x11d, 0x3e9: 0x11e, 0x3ea: 0x11f, 0x3eb: 0x5b, 0x3ec: 0x120, 0x3ed: 0x121, 0x3ee: 0x5c, 0x3ef: 0xba,\n\t0x3f0: 0x122, 0x3f1: 0x123, 0x3f2: 0x124, 0x3f3: 0x125, 0x3f4: 0xba, 0x3f5: 0xba, 0x3f6: 0xba, 0x3f7: 0xba,\n\t0x3f8: 0xba, 0x3f9: 0x126, 0x3fa: 0xba, 0x3fb: 0xba, 0x3fc: 0xba, 0x3fd: 0xba, 0x3fe: 0xba, 0x3ff: 0xba,\n\t// Block 0x10, offset 0x400\n\t0x400: 0x127, 0x401: 0x128, 0x402: 0x129, 0x403: 0x12a, 0x404: 0x12b, 0x405: 0x12c, 0x406: 0x12d, 0x407: 0x12e,\n\t0x408: 0x12f, 0x409: 0xba, 0x40a: 0x130, 0x40b: 0x131, 0x40c: 0x5d, 0x40d: 0x5e, 0x40e: 0xba, 0x40f: 0xba,\n\t0x410: 0x132, 0x411: 0x133, 0x412: 0x134, 0x413: 0x135, 0x414: 0xba, 0x415: 0xba, 0x416: 0x136, 0x417: 0x137,\n\t0x418: 0x138, 0x419: 0x139, 0x41a: 0x13a, 0x41b: 0x13b, 0x41c: 0x13c, 0x41d: 0xba, 0x41e: 0xba, 0x41f: 0xba,\n\t0x420: 0xba, 0x421: 0xba, 0x422: 0x13d, 0x423: 0x13e, 0x424: 0xba, 0x425: 0xba, 0x426: 0xba, 0x427: 0xba,\n\t0x428: 0x13f, 0x429: 0x140, 0x42a: 0x141, 0x42b: 0x142, 0x42c: 0xba, 0x42d: 0xba, 0x42e: 0xba, 0x42f: 0xba,\n\t0x430: 0x143, 0x431: 0x144, 0x432: 0x145, 0x433: 0xba, 0x434: 0x146, 0x435: 0x147, 0x436: 0xba, 0x437: 0xba,\n\t0x438: 0xba, 0x439: 0xba, 0x43a: 0xba, 0x43b: 0xba, 0x43c: 0xba, 0x43d: 0xba, 0x43e: 0xba, 0x43f: 0xba,\n\t// Block 0x11, offset 0x440\n\t0x440: 0x9f, 0x441: 0x9f, 0x442: 0x9f, 0x443: 0x9f, 0x444: 0x9f, 0x445: 0x9f, 0x446: 0x9f, 0x447: 0x9f,\n\t0x448: 0x9f, 0x449: 0x9f, 0x44a: 0x9f, 0x44b: 0x9f, 0x44c: 0x9f, 0x44d: 0x9f, 0x44e: 0x148, 0x44f: 0xba,\n\t0x450: 0x9b, 0x451: 0x149, 0x452: 0x9f, 0x453: 0x9f, 0x454: 0x9f, 0x455: 0x14a, 0x456: 0xba, 0x457: 0xba,\n\t0x458: 0xba, 0x459: 0xba, 0x45a: 0xba, 0x45b: 0xba, 0x45c: 0xba, 0x45d: 0xba, 0x45e: 0xba, 0x45f: 0xba,\n\t0x460: 0xba, 0x461: 0xba, 0x462: 0xba, 0x463: 0xba, 0x464: 0xba, 0x465: 0xba, 0x466: 0xba, 0x467: 0xba,\n\t0x468: 0xba, 0x469: 0xba, 0x46a: 0xba, 0x46b: 0xba, 0x46c: 0xba, 0x46d: 0xba, 0x46e: 0xba, 0x46f: 0xba,\n\t0x470: 0xba, 0x471: 0xba, 0x472: 0xba, 0x473: 0xba, 0x474: 0xba, 0x475: 0xba, 0x476: 0xba, 0x477: 0xba,\n\t0x478: 0xba, 0x479: 0xba, 0x47a: 0xba, 0x47b: 0xba, 0x47c: 0xba, 0x47d: 0xba, 0x47e: 0xba, 0x47f: 0xba,\n\t// Block 0x12, offset 0x480\n\t0x480: 0x9f, 0x481: 0x9f, 0x482: 0x9f, 0x483: 0x9f, 0x484: 0x9f, 0x485: 0x9f, 0x486: 0x9f, 0x487: 0x9f,\n\t0x488: 0x9f, 0x489: 0x9f, 0x48a: 0x9f, 0x48b: 0x9f, 0x48c: 0x9f, 0x48d: 0x9f, 0x48e: 0x9f, 0x48f: 0x9f,\n\t0x490: 0x14b, 0x491: 0xba, 0x492: 0xba, 0x493: 0xba, 0x494: 0xba, 0x495: 0xba, 0x496: 0xba, 0x497: 0xba,\n\t0x498: 0xba, 0x499: 0xba, 0x49a: 0xba, 0x49b: 0xba, 0x49c: 0xba, 0x49d: 0xba, 0x49e: 0xba, 0x49f: 0xba,\n\t0x4a0: 0xba, 0x4a1: 0xba, 0x4a2: 0xba, 0x4a3: 0xba, 0x4a4: 0xba, 0x4a5: 0xba, 0x4a6: 0xba, 0x4a7: 0xba,\n\t0x4a8: 0xba, 0x4a9: 0xba, 0x4aa: 0xba, 0x4ab: 0xba, 0x4ac: 0xba, 0x4ad: 0xba, 0x4ae: 0xba, 0x4af: 0xba,\n\t0x4b0: 0xba, 0x4b1: 0xba, 0x4b2: 0xba, 0x4b3: 0xba, 0x4b4: 0xba, 0x4b5: 0xba, 0x4b6: 0xba, 0x4b7: 0xba,\n\t0x4b8: 0xba, 0x4b9: 0xba, 0x4ba: 0xba, 0x4bb: 0xba, 0x4bc: 0xba, 0x4bd: 0xba, 0x4be: 0xba, 0x4bf: 0xba,\n\t// Block 0x13, offset 0x4c0\n\t0x4c0: 0xba, 0x4c1: 0xba, 0x4c2: 0xba, 0x4c3: 0xba, 0x4c4: 0xba, 0x4c5: 0xba, 0x4c6: 0xba, 0x4c7: 0xba,\n\t0x4c8: 0xba, 0x4c9: 0xba, 0x4ca: 0xba, 0x4cb: 0xba, 0x4cc: 0xba, 0x4cd: 0xba, 0x4ce: 0xba, 0x4cf: 0xba,\n\t0x4d0: 0x9f, 0x4d1: 0x9f, 0x4d2: 0x9f, 0x4d3: 0x9f, 0x4d4: 0x9f, 0x4d5: 0x9f, 0x4d6: 0x9f, 0x4d7: 0x9f,\n\t0x4d8: 0x9f, 0x4d9: 0x14c, 0x4da: 0xba, 0x4db: 0xba, 0x4dc: 0xba, 0x4dd: 0xba, 0x4de: 0xba, 0x4df: 0xba,\n\t0x4e0: 0xba, 0x4e1: 0xba, 0x4e2: 0xba, 0x4e3: 0xba, 0x4e4: 0xba, 0x4e5: 0xba, 0x4e6: 0xba, 0x4e7: 0xba,\n\t0x4e8: 0xba, 0x4e9: 0xba, 0x4ea: 0xba, 0x4eb: 0xba, 0x4ec: 0xba, 0x4ed: 0xba, 0x4ee: 0xba, 0x4ef: 0xba,\n\t0x4f0: 0xba, 0x4f1: 0xba, 0x4f2: 0xba, 0x4f3: 0xba, 0x4f4: 0xba, 0x4f5: 0xba, 0x4f6: 0xba, 0x4f7: 0xba,\n\t0x4f8: 0xba, 0x4f9: 0xba, 0x4fa: 0xba, 0x4fb: 0xba, 0x4fc: 0xba, 0x4fd: 0xba, 0x4fe: 0xba, 0x4ff: 0xba,\n\t// Block 0x14, offset 0x500\n\t0x500: 0xba, 0x501: 0xba, 0x502: 0xba, 0x503: 0xba, 0x504: 0xba, 0x505: 0xba, 0x506: 0xba, 0x507: 0xba,\n\t0x508: 0xba, 0x509: 0xba, 0x50a: 0xba, 0x50b: 0xba, 0x50c: 0xba, 0x50d: 0xba, 0x50e: 0xba, 0x50f: 0xba,\n\t0x510: 0xba, 0x511: 0xba, 0x512: 0xba, 0x513: 0xba, 0x514: 0xba, 0x515: 0xba, 0x516: 0xba, 0x517: 0xba,\n\t0x518: 0xba, 0x519: 0xba, 0x51a: 0xba, 0x51b: 0xba, 0x51c: 0xba, 0x51d: 0xba, 0x51e: 0xba, 0x51f: 0xba,\n\t0x520: 0x9f, 0x521: 0x9f, 0x522: 0x9f, 0x523: 0x9f, 0x524: 0x9f, 0x525: 0x9f, 0x526: 0x9f, 0x527: 0x9f,\n\t0x528: 0x142, 0x529: 0x14d, 0x52a: 0xba, 0x52b: 0x14e, 0x52c: 0x14f, 0x52d: 0x150, 0x52e: 0x151, 0x52f: 0xba,\n\t0x530: 0xba, 0x531: 0xba, 0x532: 0xba, 0x533: 0xba, 0x534: 0xba, 0x535: 0xba, 0x536: 0xba, 0x537: 0xba,\n\t0x538: 0xba, 0x539: 0xba, 0x53a: 0xba, 0x53b: 0xba, 0x53c: 0x9f, 0x53d: 0x152, 0x53e: 0x153, 0x53f: 0x154,\n\t// Block 0x15, offset 0x540\n\t0x540: 0x9f, 0x541: 0x9f, 0x542: 0x9f, 0x543: 0x9f, 0x544: 0x9f, 0x545: 0x9f, 0x546: 0x9f, 0x547: 0x9f,\n\t0x548: 0x9f, 0x549: 0x9f, 0x54a: 0x9f, 0x54b: 0x9f, 0x54c: 0x9f, 0x54d: 0x9f, 0x54e: 0x9f, 0x54f: 0x9f,\n\t0x550: 0x9f, 0x551: 0x9f, 0x552: 0x9f, 0x553: 0x9f, 0x554: 0x9f, 0x555: 0x9f, 0x556: 0x9f, 0x557: 0x9f,\n\t0x558: 0x9f, 0x559: 0x9f, 0x55a: 0x9f, 0x55b: 0x9f, 0x55c: 0x9f, 0x55d: 0x9f, 0x55e: 0x9f, 0x55f: 0x155,\n\t0x560: 0x9f, 0x561: 0x9f, 0x562: 0x9f, 0x563: 0x9f, 0x564: 0x9f, 0x565: 0x9f, 0x566: 0x9f, 0x567: 0x9f,\n\t0x568: 0x9f, 0x569: 0x9f, 0x56a: 0x9f, 0x56b: 0x156, 0x56c: 0xba, 0x56d: 0xba, 0x56e: 0xba, 0x56f: 0xba,\n\t0x570: 0xba, 0x571: 0xba, 0x572: 0xba, 0x573: 0xba, 0x574: 0xba, 0x575: 0xba, 0x576: 0xba, 0x577: 0xba,\n\t0x578: 0xba, 0x579: 0xba, 0x57a: 0xba, 0x57b: 0xba, 0x57c: 0xba, 0x57d: 0xba, 0x57e: 0xba, 0x57f: 0xba,\n\t// Block 0x16, offset 0x580\n\t0x580: 0x9f, 0x581: 0x9f, 0x582: 0x9f, 0x583: 0x9f, 0x584: 0x157, 0x585: 0x158, 0x586: 0x9f, 0x587: 0x9f,\n\t0x588: 0x9f, 0x589: 0x9f, 0x58a: 0x9f, 0x58b: 0x159, 0x58c: 0xba, 0x58d: 0xba, 0x58e: 0xba, 0x58f: 0xba,\n\t0x590: 0xba, 0x591: 0xba, 0x592: 0xba, 0x593: 0xba, 0x594: 0xba, 0x595: 0xba, 0x596: 0xba, 0x597: 0xba,\n\t0x598: 0xba, 0x599: 0xba, 0x59a: 0xba, 0x59b: 0xba, 0x59c: 0xba, 0x59d: 0xba, 0x59e: 0xba, 0x59f: 0xba,\n\t0x5a0: 0xba, 0x5a1: 0xba, 0x5a2: 0xba, 0x5a3: 0xba, 0x5a4: 0xba, 0x5a5: 0xba, 0x5a6: 0xba, 0x5a7: 0xba,\n\t0x5a8: 0xba, 0x5a9: 0xba, 0x5aa: 0xba, 0x5ab: 0xba, 0x5ac: 0xba, 0x5ad: 0xba, 0x5ae: 0xba, 0x5af: 0xba,\n\t0x5b0: 0x9f, 0x5b1: 0x15a, 0x5b2: 0x15b, 0x5b3: 0xba, 0x5b4: 0xba, 0x5b5: 0xba, 0x5b6: 0xba, 0x5b7: 0xba,\n\t0x5b8: 0xba, 0x5b9: 0xba, 0x5ba: 0xba, 0x5bb: 0xba, 0x5bc: 0xba, 0x5bd: 0xba, 0x5be: 0xba, 0x5bf: 0xba,\n\t// Block 0x17, offset 0x5c0\n\t0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x15c, 0x5c4: 0x15d, 0x5c5: 0x15e, 0x5c6: 0x15f, 0x5c7: 0x160,\n\t0x5c8: 0x9b, 0x5c9: 0x161, 0x5ca: 0xba, 0x5cb: 0xba, 0x5cc: 0x9b, 0x5cd: 0x162, 0x5ce: 0xba, 0x5cf: 0xba,\n\t0x5d0: 0x5f, 0x5d1: 0x60, 0x5d2: 0x61, 0x5d3: 0x62, 0x5d4: 0x63, 0x5d5: 0x64, 0x5d6: 0x65, 0x5d7: 0x66,\n\t0x5d8: 0x67, 0x5d9: 0x68, 0x5da: 0x69, 0x5db: 0x6a, 0x5dc: 0x6b, 0x5dd: 0x6c, 0x5de: 0x6d, 0x5df: 0x6e,\n\t0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b,\n\t0x5e8: 0x163, 0x5e9: 0x164, 0x5ea: 0x165, 0x5eb: 0xba, 0x5ec: 0xba, 0x5ed: 0xba, 0x5ee: 0xba, 0x5ef: 0xba,\n\t0x5f0: 0xba, 0x5f1: 0xba, 0x5f2: 0xba, 0x5f3: 0xba, 0x5f4: 0xba, 0x5f5: 0xba, 0x5f6: 0xba, 0x5f7: 0xba,\n\t0x5f8: 0xba, 0x5f9: 0xba, 0x5fa: 0xba, 0x5fb: 0xba, 0x5fc: 0xba, 0x5fd: 0xba, 0x5fe: 0xba, 0x5ff: 0xba,\n\t// Block 0x18, offset 0x600\n\t0x600: 0x166, 0x601: 0xba, 0x602: 0xba, 0x603: 0xba, 0x604: 0xba, 0x605: 0xba, 0x606: 0xba, 0x607: 0xba,\n\t0x608: 0xba, 0x609: 0xba, 0x60a: 0xba, 0x60b: 0xba, 0x60c: 0xba, 0x60d: 0xba, 0x60e: 0xba, 0x60f: 0xba,\n\t0x610: 0xba, 0x611: 0xba, 0x612: 0xba, 0x613: 0xba, 0x614: 0xba, 0x615: 0xba, 0x616: 0xba, 0x617: 0xba,\n\t0x618: 0xba, 0x619: 0xba, 0x61a: 0xba, 0x61b: 0xba, 0x61c: 0xba, 0x61d: 0xba, 0x61e: 0xba, 0x61f: 0xba,\n\t0x620: 0x122, 0x621: 0x122, 0x622: 0x122, 0x623: 0x167, 0x624: 0x6f, 0x625: 0x168, 0x626: 0xba, 0x627: 0xba,\n\t0x628: 0xba, 0x629: 0xba, 0x62a: 0xba, 0x62b: 0xba, 0x62c: 0xba, 0x62d: 0xba, 0x62e: 0xba, 0x62f: 0xba,\n\t0x630: 0xba, 0x631: 0xba, 0x632: 0xba, 0x633: 0xba, 0x634: 0xba, 0x635: 0xba, 0x636: 0xba, 0x637: 0xba,\n\t0x638: 0x70, 0x639: 0x71, 0x63a: 0x72, 0x63b: 0x169, 0x63c: 0xba, 0x63d: 0xba, 0x63e: 0xba, 0x63f: 0xba,\n\t// Block 0x19, offset 0x640\n\t0x640: 0x16a, 0x641: 0x9b, 0x642: 0x16b, 0x643: 0x16c, 0x644: 0x73, 0x645: 0x74, 0x646: 0x16d, 0x647: 0x16e,\n\t0x648: 0x75, 0x649: 0x16f, 0x64a: 0xba, 0x64b: 0xba, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b,\n\t0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b,\n\t0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x170, 0x65c: 0x9b, 0x65d: 0x171, 0x65e: 0x9b, 0x65f: 0x172,\n\t0x660: 0x173, 0x661: 0x174, 0x662: 0x175, 0x663: 0xba, 0x664: 0x176, 0x665: 0x177, 0x666: 0x178, 0x667: 0x179,\n\t0x668: 0xba, 0x669: 0xba, 0x66a: 0xba, 0x66b: 0xba, 0x66c: 0xba, 0x66d: 0xba, 0x66e: 0xba, 0x66f: 0xba,\n\t0x670: 0xba, 0x671: 0xba, 0x672: 0xba, 0x673: 0xba, 0x674: 0xba, 0x675: 0xba, 0x676: 0xba, 0x677: 0xba,\n\t0x678: 0xba, 0x679: 0xba, 0x67a: 0xba, 0x67b: 0xba, 0x67c: 0xba, 0x67d: 0xba, 0x67e: 0xba, 0x67f: 0xba,\n\t// Block 0x1a, offset 0x680\n\t0x680: 0x9f, 0x681: 0x9f, 0x682: 0x9f, 0x683: 0x9f, 0x684: 0x9f, 0x685: 0x9f, 0x686: 0x9f, 0x687: 0x9f,\n\t0x688: 0x9f, 0x689: 0x9f, 0x68a: 0x9f, 0x68b: 0x9f, 0x68c: 0x9f, 0x68d: 0x9f, 0x68e: 0x9f, 0x68f: 0x9f,\n\t0x690: 0x9f, 0x691: 0x9f, 0x692: 0x9f, 0x693: 0x9f, 0x694: 0x9f, 0x695: 0x9f, 0x696: 0x9f, 0x697: 0x9f,\n\t0x698: 0x9f, 0x699: 0x9f, 0x69a: 0x9f, 0x69b: 0x17a, 0x69c: 0x9f, 0x69d: 0x9f, 0x69e: 0x9f, 0x69f: 0x9f,\n\t0x6a0: 0x9f, 0x6a1: 0x9f, 0x6a2: 0x9f, 0x6a3: 0x9f, 0x6a4: 0x9f, 0x6a5: 0x9f, 0x6a6: 0x9f, 0x6a7: 0x9f,\n\t0x6a8: 0x9f, 0x6a9: 0x9f, 0x6aa: 0x9f, 0x6ab: 0x9f, 0x6ac: 0x9f, 0x6ad: 0x9f, 0x6ae: 0x9f, 0x6af: 0x9f,\n\t0x6b0: 0x9f, 0x6b1: 0x9f, 0x6b2: 0x9f, 0x6b3: 0x9f, 0x6b4: 0x9f, 0x6b5: 0x9f, 0x6b6: 0x9f, 0x6b7: 0x9f,\n\t0x6b8: 0x9f, 0x6b9: 0x9f, 0x6ba: 0x9f, 0x6bb: 0x9f, 0x6bc: 0x9f, 0x6bd: 0x9f, 0x6be: 0x9f, 0x6bf: 0x9f,\n\t// Block 0x1b, offset 0x6c0\n\t0x6c0: 0x9f, 0x6c1: 0x9f, 0x6c2: 0x9f, 0x6c3: 0x9f, 0x6c4: 0x9f, 0x6c5: 0x9f, 0x6c6: 0x9f, 0x6c7: 0x9f,\n\t0x6c8: 0x9f, 0x6c9: 0x9f, 0x6ca: 0x9f, 0x6cb: 0x9f, 0x6cc: 0x9f, 0x6cd: 0x9f, 0x6ce: 0x9f, 0x6cf: 0x9f,\n\t0x6d0: 0x9f, 0x6d1: 0x9f, 0x6d2: 0x9f, 0x6d3: 0x9f, 0x6d4: 0x9f, 0x6d5: 0x9f, 0x6d6: 0x9f, 0x6d7: 0x9f,\n\t0x6d8: 0x9f, 0x6d9: 0x9f, 0x6da: 0x9f, 0x6db: 0x9f, 0x6dc: 0x17b, 0x6dd: 0x9f, 0x6de: 0x9f, 0x6df: 0x9f,\n\t0x6e0: 0x17c, 0x6e1: 0x9f, 0x6e2: 0x9f, 0x6e3: 0x9f, 0x6e4: 0x9f, 0x6e5: 0x9f, 0x6e6: 0x9f, 0x6e7: 0x9f,\n\t0x6e8: 0x9f, 0x6e9: 0x9f, 0x6ea: 0x9f, 0x6eb: 0x9f, 0x6ec: 0x9f, 0x6ed: 0x9f, 0x6ee: 0x9f, 0x6ef: 0x9f,\n\t0x6f0: 0x9f, 0x6f1: 0x9f, 0x6f2: 0x9f, 0x6f3: 0x9f, 0x6f4: 0x9f, 0x6f5: 0x9f, 0x6f6: 0x9f, 0x6f7: 0x9f,\n\t0x6f8: 0x9f, 0x6f9: 0x9f, 0x6fa: 0x9f, 0x6fb: 0x9f, 0x6fc: 0x9f, 0x6fd: 0x9f, 0x6fe: 0x9f, 0x6ff: 0x9f,\n\t// Block 0x1c, offset 0x700\n\t0x700: 0x9f, 0x701: 0x9f, 0x702: 0x9f, 0x703: 0x9f, 0x704: 0x9f, 0x705: 0x9f, 0x706: 0x9f, 0x707: 0x9f,\n\t0x708: 0x9f, 0x709: 0x9f, 0x70a: 0x9f, 0x70b: 0x9f, 0x70c: 0x9f, 0x70d: 0x9f, 0x70e: 0x9f, 0x70f: 0x9f,\n\t0x710: 0x9f, 0x711: 0x9f, 0x712: 0x9f, 0x713: 0x9f, 0x714: 0x9f, 0x715: 0x9f, 0x716: 0x9f, 0x717: 0x9f,\n\t0x718: 0x9f, 0x719: 0x9f, 0x71a: 0x9f, 0x71b: 0x9f, 0x71c: 0x9f, 0x71d: 0x9f, 0x71e: 0x9f, 0x71f: 0x9f,\n\t0x720: 0x9f, 0x721: 0x9f, 0x722: 0x9f, 0x723: 0x9f, 0x724: 0x9f, 0x725: 0x9f, 0x726: 0x9f, 0x727: 0x9f,\n\t0x728: 0x9f, 0x729: 0x9f, 0x72a: 0x9f, 0x72b: 0x9f, 0x72c: 0x9f, 0x72d: 0x9f, 0x72e: 0x9f, 0x72f: 0x9f,\n\t0x730: 0x9f, 0x731: 0x9f, 0x732: 0x9f, 0x733: 0x9f, 0x734: 0x9f, 0x735: 0x9f, 0x736: 0x9f, 0x737: 0x9f,\n\t0x738: 0x9f, 0x739: 0x9f, 0x73a: 0x17d, 0x73b: 0x9f, 0x73c: 0x9f, 0x73d: 0x9f, 0x73e: 0x9f, 0x73f: 0x9f,\n\t// Block 0x1d, offset 0x740\n\t0x740: 0x9f, 0x741: 0x9f, 0x742: 0x9f, 0x743: 0x9f, 0x744: 0x9f, 0x745: 0x9f, 0x746: 0x9f, 0x747: 0x9f,\n\t0x748: 0x9f, 0x749: 0x9f, 0x74a: 0x9f, 0x74b: 0x9f, 0x74c: 0x9f, 0x74d: 0x9f, 0x74e: 0x9f, 0x74f: 0x9f,\n\t0x750: 0x9f, 0x751: 0x9f, 0x752: 0x9f, 0x753: 0x9f, 0x754: 0x9f, 0x755: 0x9f, 0x756: 0x9f, 0x757: 0x9f,\n\t0x758: 0x9f, 0x759: 0x9f, 0x75a: 0x9f, 0x75b: 0x9f, 0x75c: 0x9f, 0x75d: 0x9f, 0x75e: 0x9f, 0x75f: 0x9f,\n\t0x760: 0x9f, 0x761: 0x9f, 0x762: 0x9f, 0x763: 0x9f, 0x764: 0x9f, 0x765: 0x9f, 0x766: 0x9f, 0x767: 0x9f,\n\t0x768: 0x9f, 0x769: 0x9f, 0x76a: 0x9f, 0x76b: 0x9f, 0x76c: 0x9f, 0x76d: 0x9f, 0x76e: 0x9f, 0x76f: 0x17e,\n\t0x770: 0xba, 0x771: 0xba, 0x772: 0xba, 0x773: 0xba, 0x774: 0xba, 0x775: 0xba, 0x776: 0xba, 0x777: 0xba,\n\t0x778: 0xba, 0x779: 0xba, 0x77a: 0xba, 0x77b: 0xba, 0x77c: 0xba, 0x77d: 0xba, 0x77e: 0xba, 0x77f: 0xba,\n\t// Block 0x1e, offset 0x780\n\t0x780: 0xba, 0x781: 0xba, 0x782: 0xba, 0x783: 0xba, 0x784: 0xba, 0x785: 0xba, 0x786: 0xba, 0x787: 0xba,\n\t0x788: 0xba, 0x789: 0xba, 0x78a: 0xba, 0x78b: 0xba, 0x78c: 0xba, 0x78d: 0xba, 0x78e: 0xba, 0x78f: 0xba,\n\t0x790: 0xba, 0x791: 0xba, 0x792: 0xba, 0x793: 0xba, 0x794: 0xba, 0x795: 0xba, 0x796: 0xba, 0x797: 0xba,\n\t0x798: 0xba, 0x799: 0xba, 0x79a: 0xba, 0x79b: 0xba, 0x79c: 0xba, 0x79d: 0xba, 0x79e: 0xba, 0x79f: 0xba,\n\t0x7a0: 0x76, 0x7a1: 0x77, 0x7a2: 0x78, 0x7a3: 0x17f, 0x7a4: 0x79, 0x7a5: 0x7a, 0x7a6: 0x180, 0x7a7: 0x7b,\n\t0x7a8: 0x7c, 0x7a9: 0xba, 0x7aa: 0xba, 0x7ab: 0xba, 0x7ac: 0xba, 0x7ad: 0xba, 0x7ae: 0xba, 0x7af: 0xba,\n\t0x7b0: 0xba, 0x7b1: 0xba, 0x7b2: 0xba, 0x7b3: 0xba, 0x7b4: 0xba, 0x7b5: 0xba, 0x7b6: 0xba, 0x7b7: 0xba,\n\t0x7b8: 0xba, 0x7b9: 0xba, 0x7ba: 0xba, 0x7bb: 0xba, 0x7bc: 0xba, 0x7bd: 0xba, 0x7be: 0xba, 0x7bf: 0xba,\n\t// Block 0x1f, offset 0x7c0\n\t0x7d0: 0x0d, 0x7d1: 0x0e, 0x7d2: 0x0f, 0x7d3: 0x10, 0x7d4: 0x11, 0x7d5: 0x0b, 0x7d6: 0x12, 0x7d7: 0x07,\n\t0x7d8: 0x13, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x14, 0x7dc: 0x0b, 0x7dd: 0x15, 0x7de: 0x16, 0x7df: 0x17,\n\t0x7e0: 0x07, 0x7e1: 0x07, 0x7e2: 0x07, 0x7e3: 0x07, 0x7e4: 0x07, 0x7e5: 0x07, 0x7e6: 0x07, 0x7e7: 0x07,\n\t0x7e8: 0x07, 0x7e9: 0x07, 0x7ea: 0x18, 0x7eb: 0x19, 0x7ec: 0x1a, 0x7ed: 0x07, 0x7ee: 0x1b, 0x7ef: 0x1c,\n\t0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b,\n\t0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b,\n\t// Block 0x20, offset 0x800\n\t0x800: 0x0b, 0x801: 0x0b, 0x802: 0x0b, 0x803: 0x0b, 0x804: 0x0b, 0x805: 0x0b, 0x806: 0x0b, 0x807: 0x0b,\n\t0x808: 0x0b, 0x809: 0x0b, 0x80a: 0x0b, 0x80b: 0x0b, 0x80c: 0x0b, 0x80d: 0x0b, 0x80e: 0x0b, 0x80f: 0x0b,\n\t0x810: 0x0b, 0x811: 0x0b, 0x812: 0x0b, 0x813: 0x0b, 0x814: 0x0b, 0x815: 0x0b, 0x816: 0x0b, 0x817: 0x0b,\n\t0x818: 0x0b, 0x819: 0x0b, 0x81a: 0x0b, 0x81b: 0x0b, 0x81c: 0x0b, 0x81d: 0x0b, 0x81e: 0x0b, 0x81f: 0x0b,\n\t0x820: 0x0b, 0x821: 0x0b, 0x822: 0x0b, 0x823: 0x0b, 0x824: 0x0b, 0x825: 0x0b, 0x826: 0x0b, 0x827: 0x0b,\n\t0x828: 0x0b, 0x829: 0x0b, 0x82a: 0x0b, 0x82b: 0x0b, 0x82c: 0x0b, 0x82d: 0x0b, 0x82e: 0x0b, 0x82f: 0x0b,\n\t0x830: 0x0b, 0x831: 0x0b, 0x832: 0x0b, 0x833: 0x0b, 0x834: 0x0b, 0x835: 0x0b, 0x836: 0x0b, 0x837: 0x0b,\n\t0x838: 0x0b, 0x839: 0x0b, 0x83a: 0x0b, 0x83b: 0x0b, 0x83c: 0x0b, 0x83d: 0x0b, 0x83e: 0x0b, 0x83f: 0x0b,\n\t// Block 0x21, offset 0x840\n\t0x840: 0x181, 0x841: 0x182, 0x842: 0xba, 0x843: 0xba, 0x844: 0x183, 0x845: 0x183, 0x846: 0x183, 0x847: 0x184,\n\t0x848: 0xba, 0x849: 0xba, 0x84a: 0xba, 0x84b: 0xba, 0x84c: 0xba, 0x84d: 0xba, 0x84e: 0xba, 0x84f: 0xba,\n\t0x850: 0xba, 0x851: 0xba, 0x852: 0xba, 0x853: 0xba, 0x854: 0xba, 0x855: 0xba, 0x856: 0xba, 0x857: 0xba,\n\t0x858: 0xba, 0x859: 0xba, 0x85a: 0xba, 0x85b: 0xba, 0x85c: 0xba, 0x85d: 0xba, 0x85e: 0xba, 0x85f: 0xba,\n\t0x860: 0xba, 0x861: 0xba, 0x862: 0xba, 0x863: 0xba, 0x864: 0xba, 0x865: 0xba, 0x866: 0xba, 0x867: 0xba,\n\t0x868: 0xba, 0x869: 0xba, 0x86a: 0xba, 0x86b: 0xba, 0x86c: 0xba, 0x86d: 0xba, 0x86e: 0xba, 0x86f: 0xba,\n\t0x870: 0xba, 0x871: 0xba, 0x872: 0xba, 0x873: 0xba, 0x874: 0xba, 0x875: 0xba, 0x876: 0xba, 0x877: 0xba,\n\t0x878: 0xba, 0x879: 0xba, 0x87a: 0xba, 0x87b: 0xba, 0x87c: 0xba, 0x87d: 0xba, 0x87e: 0xba, 0x87f: 0xba,\n\t// Block 0x22, offset 0x880\n\t0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b,\n\t0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b,\n\t0x890: 0x0b, 0x891: 0x0b, 0x892: 0x0b, 0x893: 0x0b, 0x894: 0x0b, 0x895: 0x0b, 0x896: 0x0b, 0x897: 0x0b,\n\t0x898: 0x0b, 0x899: 0x0b, 0x89a: 0x0b, 0x89b: 0x0b, 0x89c: 0x0b, 0x89d: 0x0b, 0x89e: 0x0b, 0x89f: 0x0b,\n\t0x8a0: 0x1f, 0x8a1: 0x0b, 0x8a2: 0x0b, 0x8a3: 0x0b, 0x8a4: 0x0b, 0x8a5: 0x0b, 0x8a6: 0x0b, 0x8a7: 0x0b,\n\t0x8a8: 0x0b, 0x8a9: 0x0b, 0x8aa: 0x0b, 0x8ab: 0x0b, 0x8ac: 0x0b, 0x8ad: 0x0b, 0x8ae: 0x0b, 0x8af: 0x0b,\n\t0x8b0: 0x0b, 0x8b1: 0x0b, 0x8b2: 0x0b, 0x8b3: 0x0b, 0x8b4: 0x0b, 0x8b5: 0x0b, 0x8b6: 0x0b, 0x8b7: 0x0b,\n\t0x8b8: 0x0b, 0x8b9: 0x0b, 0x8ba: 0x0b, 0x8bb: 0x0b, 0x8bc: 0x0b, 0x8bd: 0x0b, 0x8be: 0x0b, 0x8bf: 0x0b,\n\t// Block 0x23, offset 0x8c0\n\t0x8c0: 0x0b, 0x8c1: 0x0b, 0x8c2: 0x0b, 0x8c3: 0x0b, 0x8c4: 0x0b, 0x8c5: 0x0b, 0x8c6: 0x0b, 0x8c7: 0x0b,\n\t0x8c8: 0x0b, 0x8c9: 0x0b, 0x8ca: 0x0b, 0x8cb: 0x0b, 0x8cc: 0x0b, 0x8cd: 0x0b, 0x8ce: 0x0b, 0x8cf: 0x0b,\n}\n\n// idnaSparseOffset: 264 entries, 528 bytes\nvar idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x34, 0x3f, 0x4b, 0x4f, 0x5e, 0x63, 0x6b, 0x77, 0x85, 0x8a, 0x93, 0xa3, 0xb1, 0xbd, 0xc9, 0xda, 0xe4, 0xeb, 0xf8, 0x109, 0x110, 0x11b, 0x12a, 0x138, 0x142, 0x144, 0x149, 0x14c, 0x14f, 0x151, 0x15d, 0x168, 0x170, 0x176, 0x17c, 0x181, 0x186, 0x189, 0x18d, 0x193, 0x198, 0x1a4, 0x1ae, 0x1b4, 0x1c5, 0x1cf, 0x1d2, 0x1da, 0x1dd, 0x1ea, 0x1f2, 0x1f6, 0x1fd, 0x205, 0x215, 0x221, 0x223, 0x22d, 0x239, 0x245, 0x251, 0x259, 0x25e, 0x268, 0x279, 0x27d, 0x288, 0x28c, 0x295, 0x29d, 0x2a3, 0x2a8, 0x2ab, 0x2af, 0x2b5, 0x2b9, 0x2bd, 0x2c3, 0x2ca, 0x2d0, 0x2d8, 0x2df, 0x2ea, 0x2f4, 0x2f8, 0x2fb, 0x301, 0x305, 0x307, 0x30a, 0x30c, 0x30f, 0x319, 0x31c, 0x32b, 0x32f, 0x334, 0x337, 0x33b, 0x340, 0x345, 0x34b, 0x351, 0x360, 0x366, 0x36a, 0x379, 0x37e, 0x386, 0x390, 0x39b, 0x3a3, 0x3b4, 0x3bd, 0x3cd, 0x3da, 0x3e4, 0x3e9, 0x3f6, 0x3fa, 0x3ff, 0x401, 0x405, 0x407, 0x40b, 0x414, 0x41a, 0x41e, 0x42e, 0x438, 0x43d, 0x440, 0x446, 0x44d, 0x452, 0x456, 0x45c, 0x461, 0x46a, 0x46f, 0x475, 0x47c, 0x483, 0x48a, 0x48e, 0x493, 0x496, 0x49b, 0x4a7, 0x4ad, 0x4b2, 0x4b9, 0x4c1, 0x4c6, 0x4ca, 0x4da, 0x4e1, 0x4e5, 0x4e9, 0x4f0, 0x4f2, 0x4f5, 0x4f8, 0x4fc, 0x500, 0x506, 0x50f, 0x51b, 0x522, 0x52b, 0x533, 0x53a, 0x548, 0x555, 0x562, 0x56b, 0x56f, 0x57d, 0x585, 0x590, 0x599, 0x59f, 0x5a7, 0x5b0, 0x5ba, 0x5bd, 0x5c9, 0x5cc, 0x5d1, 0x5de, 0x5e7, 0x5f3, 0x5f6, 0x600, 0x609, 0x615, 0x622, 0x62a, 0x62d, 0x632, 0x635, 0x638, 0x63b, 0x642, 0x649, 0x64d, 0x658, 0x65b, 0x661, 0x666, 0x66a, 0x66d, 0x670, 0x673, 0x676, 0x679, 0x67e, 0x688, 0x68b, 0x68f, 0x69e, 0x6aa, 0x6ae, 0x6b3, 0x6b8, 0x6bc, 0x6c1, 0x6ca, 0x6d5, 0x6db, 0x6e3, 0x6e7, 0x6eb, 0x6f1, 0x6f7, 0x6fc, 0x6ff, 0x70f, 0x716, 0x719, 0x71c, 0x720, 0x726, 0x72b, 0x730, 0x735, 0x738, 0x73d, 0x740, 0x743, 0x747, 0x74b, 0x74e, 0x75e, 0x76f, 0x774, 0x776, 0x778}\n\n// idnaSparseValues: 1915 entries, 7660 bytes\nvar idnaSparseValues = [1915]valueRange{\n\t// Block 0x0, offset 0x0\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0xe105, lo: 0x80, hi: 0x96},\n\t{value: 0x0018, lo: 0x97, hi: 0x97},\n\t{value: 0xe105, lo: 0x98, hi: 0x9e},\n\t{value: 0x001f, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbf},\n\t// Block 0x1, offset 0x8\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0xe01d, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x82},\n\t{value: 0x0335, lo: 0x83, hi: 0x83},\n\t{value: 0x034d, lo: 0x84, hi: 0x84},\n\t{value: 0x0365, lo: 0x85, hi: 0x85},\n\t{value: 0xe00d, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0xe00d, lo: 0x88, hi: 0x88},\n\t{value: 0x0008, lo: 0x89, hi: 0x89},\n\t{value: 0xe00d, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0x8b},\n\t{value: 0xe00d, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0x8d},\n\t{value: 0xe00d, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0xbf},\n\t// Block 0x2, offset 0x19\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x0249, lo: 0xb0, hi: 0xb0},\n\t{value: 0x037d, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0259, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0269, lo: 0xb3, hi: 0xb3},\n\t{value: 0x034d, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0395, lo: 0xb5, hi: 0xb5},\n\t{value: 0xe1bd, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0279, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0289, lo: 0xb8, hi: 0xb8},\n\t{value: 0x0008, lo: 0xb9, hi: 0xbf},\n\t// Block 0x3, offset 0x25\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x3308, lo: 0x80, hi: 0xbf},\n\t// Block 0x4, offset 0x27\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x03f5, lo: 0x80, hi: 0x8f},\n\t{value: 0xe105, lo: 0x90, hi: 0x9f},\n\t{value: 0x049d, lo: 0xa0, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x5, offset 0x2c\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0xe185, lo: 0x80, hi: 0x8f},\n\t{value: 0x0545, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x98},\n\t{value: 0x0008, lo: 0x99, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xbf},\n\t// Block 0x6, offset 0x34\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0401, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x88},\n\t{value: 0x0018, lo: 0x89, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x3308, lo: 0x91, hi: 0xbd},\n\t{value: 0x0818, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x7, offset 0x3f\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0818, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x82},\n\t{value: 0x0818, lo: 0x83, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x85},\n\t{value: 0x0818, lo: 0x86, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0808, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x8, offset 0x4b\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0a08, lo: 0x80, hi: 0x87},\n\t{value: 0x0c08, lo: 0x88, hi: 0x99},\n\t{value: 0x0a08, lo: 0x9a, hi: 0xbf},\n\t// Block 0x9, offset 0x4f\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3308, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0c08, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0a08, lo: 0x8e, hi: 0x98},\n\t{value: 0x0c08, lo: 0x99, hi: 0x9b},\n\t{value: 0x0a08, lo: 0x9c, hi: 0xaa},\n\t{value: 0x0c08, lo: 0xab, hi: 0xac},\n\t{value: 0x0a08, lo: 0xad, hi: 0xb0},\n\t{value: 0x0c08, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0a08, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0c08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0a08, lo: 0xb5, hi: 0xb7},\n\t{value: 0x0c08, lo: 0xb8, hi: 0xb9},\n\t{value: 0x0a08, lo: 0xba, hi: 0xbf},\n\t// Block 0xa, offset 0x5e\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xb0},\n\t{value: 0x0808, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xb, offset 0x63\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0x89},\n\t{value: 0x0a08, lo: 0x8a, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xb3},\n\t{value: 0x0808, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xb9},\n\t{value: 0x0818, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0xc, offset 0x6b\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x99},\n\t{value: 0x0808, lo: 0x9a, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0xa3},\n\t{value: 0x0808, lo: 0xa4, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa7},\n\t{value: 0x0808, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0818, lo: 0xb0, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd, offset 0x77\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0a08, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0c08, lo: 0xaa, hi: 0xac},\n\t{value: 0x0808, lo: 0xad, hi: 0xad},\n\t{value: 0x0c08, lo: 0xae, hi: 0xae},\n\t{value: 0x0a08, lo: 0xaf, hi: 0xb0},\n\t{value: 0x0c08, lo: 0xb1, hi: 0xb2},\n\t{value: 0x0a08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0a08, lo: 0xb6, hi: 0xb8},\n\t{value: 0x0c08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0a08, lo: 0xba, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0xe, offset 0x85\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x93},\n\t{value: 0x3308, lo: 0x94, hi: 0xa1},\n\t{value: 0x0840, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xbf},\n\t// Block 0xf, offset 0x8a\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x10, offset 0x93\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x85},\n\t{value: 0x3008, lo: 0x86, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x3008, lo: 0x8a, hi: 0x8c},\n\t{value: 0x3b08, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x11, offset 0xa3\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbf},\n\t// Block 0x12, offset 0xb1\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0xba},\n\t{value: 0x3b08, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x13, offset 0xbd\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0040, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0008, lo: 0xb3, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x14, offset 0xc9\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x89},\n\t{value: 0x3b08, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8e},\n\t{value: 0x3008, lo: 0x8f, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x3008, lo: 0x98, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x15, offset 0xda\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb2},\n\t{value: 0x08f1, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb9},\n\t{value: 0x3b08, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0x16, offset 0xe4\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x8e},\n\t{value: 0x0018, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0xbf},\n\t// Block 0x17, offset 0xeb\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x3308, lo: 0x88, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0961, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0999, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0008, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x18, offset 0xf8\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0x8b},\n\t{value: 0xe03d, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3308, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x19, offset 0x109\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0018, lo: 0x8e, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0xbf},\n\t// Block 0x1a, offset 0x110\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x3008, lo: 0xab, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xb0},\n\t{value: 0x3008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0x1b, offset 0x11b\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x95},\n\t{value: 0x3008, lo: 0x96, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0x9d},\n\t{value: 0x3308, lo: 0x9e, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3008, lo: 0xa2, hi: 0xa4},\n\t{value: 0x0008, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xbf},\n\t// Block 0x1c, offset 0x12a\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x3008, lo: 0x87, hi: 0x8c},\n\t{value: 0x3308, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x8e},\n\t{value: 0x3008, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x3008, lo: 0x9a, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x1d, offset 0x138\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x86},\n\t{value: 0x055d, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8c},\n\t{value: 0x055d, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbb},\n\t{value: 0xe105, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x1e, offset 0x142\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0018, lo: 0x80, hi: 0xbf},\n\t// Block 0x1f, offset 0x144\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xa0},\n\t{value: 0x2018, lo: 0xa1, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0x20, offset 0x149\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xa7},\n\t{value: 0x2018, lo: 0xa8, hi: 0xbf},\n\t// Block 0x21, offset 0x14c\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x2018, lo: 0x80, hi: 0x82},\n\t{value: 0x0018, lo: 0x83, hi: 0xbf},\n\t// Block 0x22, offset 0x14f\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0008, lo: 0x80, hi: 0xbf},\n\t// Block 0x23, offset 0x151\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x24, offset 0x15d\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x25, offset 0x168\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbf},\n\t// Block 0x26, offset 0x170\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbf},\n\t// Block 0x27, offset 0x176\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x28, offset 0x17c\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x29, offset 0x181\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0xe045, lo: 0xb8, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x2a, offset 0x186\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xbf},\n\t// Block 0x2b, offset 0x189\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xac},\n\t{value: 0x0018, lo: 0xad, hi: 0xae},\n\t{value: 0x0008, lo: 0xaf, hi: 0xbf},\n\t// Block 0x2c, offset 0x18d\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x2d, offset 0x193\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xb0},\n\t{value: 0x0008, lo: 0xb1, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0x2e, offset 0x198\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x93},\n\t{value: 0x3b08, lo: 0x94, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3b08, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0018, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x2f, offset 0x1a4\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x30, offset 0x1ae\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xb3},\n\t{value: 0x3340, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3008, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x31, offset 0x1b4\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x3008, lo: 0x80, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x3008, lo: 0x87, hi: 0x88},\n\t{value: 0x3308, lo: 0x89, hi: 0x91},\n\t{value: 0x3b08, lo: 0x92, hi: 0x92},\n\t{value: 0x3308, lo: 0x93, hi: 0x93},\n\t{value: 0x0018, lo: 0x94, hi: 0x96},\n\t{value: 0x0008, lo: 0x97, hi: 0x97},\n\t{value: 0x0018, lo: 0x98, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x32, offset 0x1c5\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0018, lo: 0x80, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x86},\n\t{value: 0x0218, lo: 0x87, hi: 0x87},\n\t{value: 0x0018, lo: 0x88, hi: 0x8a},\n\t{value: 0x33c0, lo: 0x8b, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0208, lo: 0xa0, hi: 0xbf},\n\t// Block 0x33, offset 0x1cf\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0208, lo: 0x80, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x34, offset 0x1d2\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x0208, lo: 0x87, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0208, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x35, offset 0x1da\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0x36, offset 0x1dd\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb8},\n\t{value: 0x3308, lo: 0xb9, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x37, offset 0x1ea\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x38, offset 0x1f2\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x39, offset 0x1f6\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0028, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0xbf},\n\t// Block 0x3a, offset 0x1fd\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x3308, lo: 0x97, hi: 0x98},\n\t{value: 0x3008, lo: 0x99, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x3b, offset 0x205\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x94},\n\t{value: 0x3008, lo: 0x95, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3b08, lo: 0xa0, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xac},\n\t{value: 0x3008, lo: 0xad, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x3c, offset 0x215\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0018, lo: 0xa8, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xbd},\n\t{value: 0x3318, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x3d, offset 0x221\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0040, lo: 0x80, hi: 0xbf},\n\t// Block 0x3e, offset 0x223\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x3308, lo: 0x80, hi: 0x83},\n\t{value: 0x3008, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x3f, offset 0x22d\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x3808, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x40, offset 0x239\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa9},\n\t{value: 0x3808, lo: 0xaa, hi: 0xaa},\n\t{value: 0x3b08, lo: 0xab, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xbf},\n\t// Block 0x41, offset 0x245\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa9},\n\t{value: 0x3008, lo: 0xaa, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3808, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbf},\n\t// Block 0x42, offset 0x251\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x3008, lo: 0xa4, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbf},\n\t// Block 0x43, offset 0x259\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0x44, offset 0x25e\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0e29, lo: 0x80, hi: 0x80},\n\t{value: 0x0e41, lo: 0x81, hi: 0x81},\n\t{value: 0x0e59, lo: 0x82, hi: 0x82},\n\t{value: 0x0e71, lo: 0x83, hi: 0x83},\n\t{value: 0x0e89, lo: 0x84, hi: 0x85},\n\t{value: 0x0ea1, lo: 0x86, hi: 0x86},\n\t{value: 0x0eb9, lo: 0x87, hi: 0x87},\n\t{value: 0x057d, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0xbf},\n\t// Block 0x45, offset 0x268\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x92},\n\t{value: 0x0018, lo: 0x93, hi: 0x93},\n\t{value: 0x3308, lo: 0x94, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa8},\n\t{value: 0x0008, lo: 0xa9, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x3008, lo: 0xb7, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x46, offset 0x279\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3308, lo: 0x80, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbf},\n\t// Block 0x47, offset 0x27d\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x87},\n\t{value: 0xe045, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0xe045, lo: 0x98, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0xe045, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb7},\n\t{value: 0xe045, lo: 0xb8, hi: 0xbf},\n\t// Block 0x48, offset 0x288\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x3318, lo: 0x90, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbf},\n\t// Block 0x49, offset 0x28c\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x88},\n\t{value: 0x24c1, lo: 0x89, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x4a, offset 0x295\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0xab},\n\t{value: 0x24f1, lo: 0xac, hi: 0xac},\n\t{value: 0x2529, lo: 0xad, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xae},\n\t{value: 0x2579, lo: 0xaf, hi: 0xaf},\n\t{value: 0x25b1, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0018, lo: 0xb1, hi: 0xbf},\n\t// Block 0x4b, offset 0x29d\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x9f},\n\t{value: 0x0080, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xad},\n\t{value: 0x0080, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x4c, offset 0x2a3\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xa8},\n\t{value: 0x09c5, lo: 0xa9, hi: 0xa9},\n\t{value: 0x09e5, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xbf},\n\t// Block 0x4d, offset 0x2a8\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xbf},\n\t// Block 0x4e, offset 0x2ab\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x28c1, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0xbf},\n\t// Block 0x4f, offset 0x2af\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0e66, lo: 0xb4, hi: 0xb4},\n\t{value: 0x292a, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0e86, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0x50, offset 0x2b5\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x9b},\n\t{value: 0x2941, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0xbf},\n\t// Block 0x51, offset 0x2b9\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0x52, offset 0x2bd\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0018, lo: 0x98, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbc},\n\t{value: 0x0018, lo: 0xbd, hi: 0xbf},\n\t// Block 0x53, offset 0x2c3\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x92},\n\t{value: 0x0040, lo: 0x93, hi: 0xab},\n\t{value: 0x0018, lo: 0xac, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x54, offset 0x2ca\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0xe185, lo: 0x80, hi: 0x8f},\n\t{value: 0x03f5, lo: 0x90, hi: 0x9f},\n\t{value: 0x0ea5, lo: 0xa0, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x55, offset 0x2d0\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xac},\n\t{value: 0x0008, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x56, offset 0x2d8\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xae},\n\t{value: 0xe075, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0x57, offset 0x2df\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x58, offset 0x2ea\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xbf},\n\t// Block 0x59, offset 0x2f4\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xae},\n\t{value: 0x0008, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x5a, offset 0x2f8\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0xbf},\n\t// Block 0x5b, offset 0x2fb\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9e},\n\t{value: 0x0edd, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbf},\n\t// Block 0x5c, offset 0x301\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb2},\n\t{value: 0x0efd, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x5d, offset 0x305\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x0f1d, lo: 0x80, hi: 0xbf},\n\t// Block 0x5e, offset 0x307\n\t{value: 0x0020, lo: 0x02},\n\t{value: 0x171d, lo: 0x80, hi: 0x8f},\n\t{value: 0x18fd, lo: 0x90, hi: 0xbf},\n\t// Block 0x5f, offset 0x30a\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x1efd, lo: 0x80, hi: 0xbf},\n\t// Block 0x60, offset 0x30c\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xbf},\n\t// Block 0x61, offset 0x30f\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x98},\n\t{value: 0x3308, lo: 0x99, hi: 0x9a},\n\t{value: 0x29e2, lo: 0x9b, hi: 0x9b},\n\t{value: 0x2a0a, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0008, lo: 0x9d, hi: 0x9e},\n\t{value: 0x2a31, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xbf},\n\t// Block 0x62, offset 0x319\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xbe},\n\t{value: 0x2a69, lo: 0xbf, hi: 0xbf},\n\t// Block 0x63, offset 0x31c\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0040, lo: 0x80, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xb0},\n\t{value: 0x2a1d, lo: 0xb1, hi: 0xb1},\n\t{value: 0x2a3d, lo: 0xb2, hi: 0xb2},\n\t{value: 0x2a5d, lo: 0xb3, hi: 0xb3},\n\t{value: 0x2a7d, lo: 0xb4, hi: 0xb4},\n\t{value: 0x2a5d, lo: 0xb5, hi: 0xb5},\n\t{value: 0x2a9d, lo: 0xb6, hi: 0xb6},\n\t{value: 0x2abd, lo: 0xb7, hi: 0xb7},\n\t{value: 0x2add, lo: 0xb8, hi: 0xb9},\n\t{value: 0x2afd, lo: 0xba, hi: 0xbb},\n\t{value: 0x2b1d, lo: 0xbc, hi: 0xbd},\n\t{value: 0x2afd, lo: 0xbe, hi: 0xbf},\n\t// Block 0x64, offset 0x32b\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x65, offset 0x32f\n\t{value: 0x0030, lo: 0x04},\n\t{value: 0x2aa2, lo: 0x80, hi: 0x9d},\n\t{value: 0x305a, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x30a2, lo: 0xa0, hi: 0xbf},\n\t// Block 0x66, offset 0x334\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xbf},\n\t// Block 0x67, offset 0x337\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x68, offset 0x33b\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0x69, offset 0x340\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xbf},\n\t// Block 0x6a, offset 0x345\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x0018, lo: 0xa6, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0018, lo: 0xb2, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x6b, offset 0x34b\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0xb6},\n\t{value: 0x0008, lo: 0xb7, hi: 0xb7},\n\t{value: 0x2009, lo: 0xb8, hi: 0xb8},\n\t{value: 0x6e89, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xbf},\n\t// Block 0x6c, offset 0x351\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0x85},\n\t{value: 0x3b08, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x8a},\n\t{value: 0x3308, lo: 0x8b, hi: 0x8b},\n\t{value: 0x0008, lo: 0x8c, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0018, lo: 0xa8, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x6d, offset 0x360\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0208, lo: 0x80, hi: 0xb1},\n\t{value: 0x0108, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0008, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x6e, offset 0x366\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xbf},\n\t// Block 0x6f, offset 0x36a\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3008, lo: 0x80, hi: 0x83},\n\t{value: 0x3b08, lo: 0x84, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8d},\n\t{value: 0x0018, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xba},\n\t{value: 0x0008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x70, offset 0x379\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x71, offset 0x37e\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x91},\n\t{value: 0x3008, lo: 0x92, hi: 0x92},\n\t{value: 0x3808, lo: 0x93, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x72, offset 0x386\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb9},\n\t{value: 0x3008, lo: 0xba, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x73, offset 0x390\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3808, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x74, offset 0x39b\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x75, offset 0x3a3\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x8b},\n\t{value: 0x3308, lo: 0x8c, hi: 0x8c},\n\t{value: 0x3008, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0018, lo: 0x9c, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x76, offset 0x3b4\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0008, lo: 0xb9, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbf},\n\t// Block 0x77, offset 0x3bd\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x9a},\n\t{value: 0x0008, lo: 0x9b, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xaa},\n\t{value: 0x3008, lo: 0xab, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3b08, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x78, offset 0x3cd\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x88},\n\t{value: 0x0008, lo: 0x89, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x90},\n\t{value: 0x0008, lo: 0x91, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x79, offset 0x3da\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x4465, lo: 0x9c, hi: 0x9c},\n\t{value: 0x447d, lo: 0x9d, hi: 0x9d},\n\t{value: 0x2971, lo: 0x9e, hi: 0x9e},\n\t{value: 0xe06d, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xaf},\n\t{value: 0x4495, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7a, offset 0x3e4\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x44b5, lo: 0x80, hi: 0x8f},\n\t{value: 0x44d5, lo: 0x90, hi: 0x9f},\n\t{value: 0x44f5, lo: 0xa0, hi: 0xaf},\n\t{value: 0x44d5, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7b, offset 0x3e9\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3b08, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x7c, offset 0x3f6\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7d, offset 0x3fa\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8a},\n\t{value: 0x0018, lo: 0x8b, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x7e, offset 0x3ff\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x4515, lo: 0x80, hi: 0xbf},\n\t// Block 0x7f, offset 0x401\n\t{value: 0x0020, lo: 0x03},\n\t{value: 0x4d15, lo: 0x80, hi: 0x94},\n\t{value: 0x4ad5, lo: 0x95, hi: 0x95},\n\t{value: 0x4fb5, lo: 0x96, hi: 0xbf},\n\t// Block 0x80, offset 0x405\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x54f5, lo: 0x80, hi: 0xbf},\n\t// Block 0x81, offset 0x407\n\t{value: 0x0020, lo: 0x03},\n\t{value: 0x5cf5, lo: 0x80, hi: 0x84},\n\t{value: 0x5655, lo: 0x85, hi: 0x85},\n\t{value: 0x5d95, lo: 0x86, hi: 0xbf},\n\t// Block 0x82, offset 0x40b\n\t{value: 0x0020, lo: 0x08},\n\t{value: 0x6b55, lo: 0x80, hi: 0x8f},\n\t{value: 0x6d15, lo: 0x90, hi: 0x90},\n\t{value: 0x6d55, lo: 0x91, hi: 0xab},\n\t{value: 0x6ea1, lo: 0xac, hi: 0xac},\n\t{value: 0x70b5, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x70d5, lo: 0xb0, hi: 0xbf},\n\t// Block 0x83, offset 0x414\n\t{value: 0x0020, lo: 0x05},\n\t{value: 0x72d5, lo: 0x80, hi: 0xad},\n\t{value: 0x6535, lo: 0xae, hi: 0xae},\n\t{value: 0x7895, lo: 0xaf, hi: 0xb5},\n\t{value: 0x6f55, lo: 0xb6, hi: 0xb6},\n\t{value: 0x7975, lo: 0xb7, hi: 0xbf},\n\t// Block 0x84, offset 0x41a\n\t{value: 0x0028, lo: 0x03},\n\t{value: 0x7c21, lo: 0x80, hi: 0x82},\n\t{value: 0x7be1, lo: 0x83, hi: 0x83},\n\t{value: 0x7c99, lo: 0x84, hi: 0xbf},\n\t// Block 0x85, offset 0x41e\n\t{value: 0x0038, lo: 0x0f},\n\t{value: 0x9db1, lo: 0x80, hi: 0x83},\n\t{value: 0x9e59, lo: 0x84, hi: 0x85},\n\t{value: 0x9e91, lo: 0x86, hi: 0x87},\n\t{value: 0x9ec9, lo: 0x88, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0xa089, lo: 0x92, hi: 0x97},\n\t{value: 0xa1a1, lo: 0x98, hi: 0x9c},\n\t{value: 0xa281, lo: 0x9d, hi: 0xb3},\n\t{value: 0x9d41, lo: 0xb4, hi: 0xb4},\n\t{value: 0x9db1, lo: 0xb5, hi: 0xb5},\n\t{value: 0xa789, lo: 0xb6, hi: 0xbb},\n\t{value: 0xa869, lo: 0xbc, hi: 0xbc},\n\t{value: 0xa7f9, lo: 0xbd, hi: 0xbd},\n\t{value: 0xa8d9, lo: 0xbe, hi: 0xbf},\n\t// Block 0x86, offset 0x42e\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0008, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0x87, offset 0x438\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0x88, offset 0x43d\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x89, offset 0x440\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0x8a, offset 0x446\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0040, lo: 0xa1, hi: 0xbf},\n\t// Block 0x8b, offset 0x44d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x8c, offset 0x452\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x8d, offset 0x456\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x8e, offset 0x45c\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xac},\n\t{value: 0x0008, lo: 0xad, hi: 0xbf},\n\t// Block 0x8f, offset 0x461\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x90, offset 0x46a\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x91, offset 0x46f\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0xbf},\n\t// Block 0x92, offset 0x475\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe145, lo: 0x80, hi: 0x87},\n\t{value: 0xe1c5, lo: 0x88, hi: 0x8f},\n\t{value: 0xe145, lo: 0x90, hi: 0x97},\n\t{value: 0x8ad5, lo: 0x98, hi: 0x9f},\n\t{value: 0x8aed, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xbf},\n\t// Block 0x93, offset 0x47c\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x8aed, lo: 0xb0, hi: 0xb7},\n\t{value: 0x8ad5, lo: 0xb8, hi: 0xbf},\n\t// Block 0x94, offset 0x483\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe145, lo: 0x80, hi: 0x87},\n\t{value: 0xe1c5, lo: 0x88, hi: 0x8f},\n\t{value: 0xe145, lo: 0x90, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x95, offset 0x48a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x96, offset 0x48e\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xae},\n\t{value: 0x0018, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x97, offset 0x493\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x98, offset 0x496\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xbf},\n\t// Block 0x99, offset 0x49b\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x87},\n\t{value: 0x0808, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0808, lo: 0x8a, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0808, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbb},\n\t{value: 0x0808, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbe},\n\t{value: 0x0808, lo: 0xbf, hi: 0xbf},\n\t// Block 0x9a, offset 0x4a7\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x96},\n\t{value: 0x0818, lo: 0x97, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0818, lo: 0xb7, hi: 0xbf},\n\t// Block 0x9b, offset 0x4ad\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xa6},\n\t{value: 0x0818, lo: 0xa7, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x9c, offset 0x4b2\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0808, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xba},\n\t{value: 0x0818, lo: 0xbb, hi: 0xbf},\n\t// Block 0x9d, offset 0x4b9\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0818, lo: 0x96, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbe},\n\t{value: 0x0818, lo: 0xbf, hi: 0xbf},\n\t// Block 0x9e, offset 0x4c1\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbb},\n\t{value: 0x0818, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0808, lo: 0xbe, hi: 0xbf},\n\t// Block 0x9f, offset 0x4c6\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0818, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x91},\n\t{value: 0x0818, lo: 0x92, hi: 0xbf},\n\t// Block 0xa0, offset 0x4ca\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0808, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8b},\n\t{value: 0x3308, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x94},\n\t{value: 0x0808, lo: 0x95, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0x98},\n\t{value: 0x0808, lo: 0x99, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xa1, offset 0x4da\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0818, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0818, lo: 0x90, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xbc},\n\t{value: 0x0818, lo: 0xbd, hi: 0xbf},\n\t// Block 0xa2, offset 0x4e1\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0x9c},\n\t{value: 0x0818, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xa3, offset 0x4e5\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb8},\n\t{value: 0x0018, lo: 0xb9, hi: 0xbf},\n\t// Block 0xa4, offset 0x4e9\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0818, lo: 0x98, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb7},\n\t{value: 0x0818, lo: 0xb8, hi: 0xbf},\n\t// Block 0xa5, offset 0x4f0\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0808, lo: 0x80, hi: 0xbf},\n\t// Block 0xa6, offset 0x4f2\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0808, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0xbf},\n\t// Block 0xa7, offset 0x4f5\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x03dd, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbf},\n\t// Block 0xa8, offset 0x4f8\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb9},\n\t{value: 0x0818, lo: 0xba, hi: 0xbf},\n\t// Block 0xa9, offset 0x4fc\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0818, lo: 0xa0, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xaa, offset 0x500\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbf},\n\t// Block 0xab, offset 0x506\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x85},\n\t{value: 0x3b08, lo: 0x86, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x91},\n\t{value: 0x0018, lo: 0x92, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xac, offset 0x50f\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb6},\n\t{value: 0x3008, lo: 0xb7, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0340, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0xad, offset 0x51b\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x81},\n\t{value: 0x0040, lo: 0x82, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xae, offset 0x522\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xb2},\n\t{value: 0x3b08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0008, lo: 0xb6, hi: 0xbf},\n\t// Block 0xaf, offset 0x52b\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0008, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xb0, offset 0x533\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xbe},\n\t{value: 0x3008, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb1, offset 0x53a\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x3808, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x89},\n\t{value: 0x3308, lo: 0x8a, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xb2, offset 0x548\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x92},\n\t{value: 0x0008, lo: 0x93, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3808, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb3, offset 0x555\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0008, lo: 0x9f, hi: 0xa8},\n\t{value: 0x0018, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0xb4, offset 0x562\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x3308, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3008, lo: 0xa0, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xa9},\n\t{value: 0x3b08, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xb5, offset 0x56b\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbf},\n\t// Block 0xb6, offset 0x56f\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x3b08, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x84},\n\t{value: 0x3008, lo: 0x85, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x8a},\n\t{value: 0x0018, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0xb7, offset 0x57d\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb8},\n\t{value: 0x3008, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb8, offset 0x585\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x81},\n\t{value: 0x3b08, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x85},\n\t{value: 0x0018, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xb9, offset 0x590\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xba, offset 0x599\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x9b},\n\t{value: 0x3308, lo: 0x9c, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0xbb, offset 0x59f\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbc, offset 0x5a7\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xbf},\n\t// Block 0xbd, offset 0x5b0\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb5},\n\t{value: 0x3808, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0xbe, offset 0x5ba\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0xbf},\n\t// Block 0xbf, offset 0x5bd\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9f},\n\t{value: 0x3008, lo: 0xa0, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xaa},\n\t{value: 0x3b08, lo: 0xab, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbf},\n\t// Block 0xc0, offset 0x5c9\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x049d, lo: 0xa0, hi: 0xbf},\n\t// Block 0xc1, offset 0x5cc\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc2, offset 0x5d1\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x86},\n\t{value: 0x3008, lo: 0x87, hi: 0x88},\n\t{value: 0x3308, lo: 0x89, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3b08, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb8},\n\t{value: 0x3008, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc3, offset 0x5de\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x3b08, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x3308, lo: 0x91, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x98},\n\t{value: 0x3308, lo: 0x99, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0xbf},\n\t// Block 0xc4, offset 0x5e7\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x89},\n\t{value: 0x3308, lo: 0x8a, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x98},\n\t{value: 0x3b08, lo: 0x99, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0xa2},\n\t{value: 0x0040, lo: 0xa3, hi: 0xbf},\n\t// Block 0xc5, offset 0x5f3\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xc6, offset 0x5f6\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc7, offset 0x600\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xbf},\n\t// Block 0xc8, offset 0x609\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xa9},\n\t{value: 0x3308, lo: 0xaa, hi: 0xb0},\n\t{value: 0x3008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xc9, offset 0x615\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0xca, offset 0x622\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x3308, lo: 0x80, hi: 0x83},\n\t{value: 0x3b08, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xcb, offset 0x62a\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xcc, offset 0x62d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xcd, offset 0x632\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0xbf},\n\t// Block 0xce, offset 0x635\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xbf},\n\t// Block 0xcf, offset 0x638\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0xbf},\n\t// Block 0xd0, offset 0x63b\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0xd1, offset 0x642\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0018, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xd2, offset 0x649\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0xd3, offset 0x64d\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0008, lo: 0xa3, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbf},\n\t// Block 0xd4, offset 0x658\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0xbf},\n\t// Block 0xd5, offset 0x65b\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x3008, lo: 0x91, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd6, offset 0x661\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x8e},\n\t{value: 0x3308, lo: 0x8f, hi: 0x92},\n\t{value: 0x0008, lo: 0x93, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xd7, offset 0x666\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xbf},\n\t// Block 0xd8, offset 0x66a\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xbf},\n\t// Block 0xd9, offset 0x66d\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbf},\n\t// Block 0xda, offset 0x670\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xbf},\n\t// Block 0xdb, offset 0x673\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0xdc, offset 0x676\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0xdd, offset 0x679\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0xde, offset 0x67e\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0018, lo: 0x9c, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x03c0, lo: 0xa0, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xbf},\n\t// Block 0xdf, offset 0x688\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xe0, offset 0x68b\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa8},\n\t{value: 0x0018, lo: 0xa9, hi: 0xbf},\n\t// Block 0xe1, offset 0x68f\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0018, lo: 0x80, hi: 0x9d},\n\t{value: 0xb5b9, lo: 0x9e, hi: 0x9e},\n\t{value: 0xb601, lo: 0x9f, hi: 0x9f},\n\t{value: 0xb649, lo: 0xa0, hi: 0xa0},\n\t{value: 0xb6b1, lo: 0xa1, hi: 0xa1},\n\t{value: 0xb719, lo: 0xa2, hi: 0xa2},\n\t{value: 0xb781, lo: 0xa3, hi: 0xa3},\n\t{value: 0xb7e9, lo: 0xa4, hi: 0xa4},\n\t{value: 0x3018, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3318, lo: 0xa7, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xac},\n\t{value: 0x3018, lo: 0xad, hi: 0xb2},\n\t{value: 0x0340, lo: 0xb3, hi: 0xba},\n\t{value: 0x3318, lo: 0xbb, hi: 0xbf},\n\t// Block 0xe2, offset 0x69e\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3318, lo: 0x80, hi: 0x82},\n\t{value: 0x0018, lo: 0x83, hi: 0x84},\n\t{value: 0x3318, lo: 0x85, hi: 0x8b},\n\t{value: 0x0018, lo: 0x8c, hi: 0xa9},\n\t{value: 0x3318, lo: 0xaa, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xba},\n\t{value: 0xb851, lo: 0xbb, hi: 0xbb},\n\t{value: 0xb899, lo: 0xbc, hi: 0xbc},\n\t{value: 0xb8e1, lo: 0xbd, hi: 0xbd},\n\t{value: 0xb949, lo: 0xbe, hi: 0xbe},\n\t{value: 0xb9b1, lo: 0xbf, hi: 0xbf},\n\t// Block 0xe3, offset 0x6aa\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0xba19, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xbf},\n\t// Block 0xe4, offset 0x6ae\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x81},\n\t{value: 0x3318, lo: 0x82, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0xbf},\n\t// Block 0xe5, offset 0x6b3\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xe6, offset 0x6b8\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3308, lo: 0x80, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbf},\n\t// Block 0xe7, offset 0x6bc\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x3308, lo: 0x80, hi: 0xac},\n\t{value: 0x0018, lo: 0xad, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0xe8, offset 0x6c1\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x3308, lo: 0xa1, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0xe9, offset 0x6ca\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x3308, lo: 0x88, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xa4},\n\t{value: 0x0040, lo: 0xa5, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xbf},\n\t// Block 0xea, offset 0x6d5\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0808, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x86},\n\t{value: 0x0818, lo: 0x87, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0xbf},\n\t// Block 0xeb, offset 0x6db\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0a08, lo: 0x80, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0818, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xec, offset 0x6e3\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xed, offset 0x6e7\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0xee, offset 0x6eb\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xb0},\n\t{value: 0x0018, lo: 0xb1, hi: 0xbf},\n\t// Block 0xef, offset 0x6f1\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x0018, lo: 0x91, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xf0, offset 0x6f7\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x8f},\n\t{value: 0xc1c1, lo: 0x90, hi: 0x90},\n\t{value: 0x0018, lo: 0x91, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xbf},\n\t// Block 0xf1, offset 0x6fc\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xa5},\n\t{value: 0x0018, lo: 0xa6, hi: 0xbf},\n\t// Block 0xf2, offset 0x6ff\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0xc7e9, lo: 0x80, hi: 0x80},\n\t{value: 0xc839, lo: 0x81, hi: 0x81},\n\t{value: 0xc889, lo: 0x82, hi: 0x82},\n\t{value: 0xc8d9, lo: 0x83, hi: 0x83},\n\t{value: 0xc929, lo: 0x84, hi: 0x84},\n\t{value: 0xc979, lo: 0x85, hi: 0x85},\n\t{value: 0xc9c9, lo: 0x86, hi: 0x86},\n\t{value: 0xca19, lo: 0x87, hi: 0x87},\n\t{value: 0xca69, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0xcab9, lo: 0x90, hi: 0x90},\n\t{value: 0xcad9, lo: 0x91, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xbf},\n\t// Block 0xf3, offset 0x70f\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xf4, offset 0x716\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0xf5, offset 0x719\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0xbf},\n\t// Block 0xf6, offset 0x71c\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0xf7, offset 0x720\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbf},\n\t// Block 0xf8, offset 0x726\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xbf},\n\t// Block 0xf9, offset 0x72b\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xfa, offset 0x730\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xbf},\n\t// Block 0xfb, offset 0x735\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0xbf},\n\t// Block 0xfc, offset 0x738\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xbf},\n\t// Block 0xfd, offset 0x73d\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0xbf},\n\t// Block 0xfe, offset 0x740\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xff, offset 0x743\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x100, offset 0x747\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x101, offset 0x74b\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xa0},\n\t{value: 0x0040, lo: 0xa1, hi: 0xbf},\n\t// Block 0x102, offset 0x74e\n\t{value: 0x0020, lo: 0x0f},\n\t{value: 0xdeb9, lo: 0x80, hi: 0x89},\n\t{value: 0x8dfd, lo: 0x8a, hi: 0x8a},\n\t{value: 0xdff9, lo: 0x8b, hi: 0x9c},\n\t{value: 0x8e1d, lo: 0x9d, hi: 0x9d},\n\t{value: 0xe239, lo: 0x9e, hi: 0xa2},\n\t{value: 0x8e3d, lo: 0xa3, hi: 0xa3},\n\t{value: 0xe2d9, lo: 0xa4, hi: 0xab},\n\t{value: 0x7ed5, lo: 0xac, hi: 0xac},\n\t{value: 0xe3d9, lo: 0xad, hi: 0xaf},\n\t{value: 0x8e5d, lo: 0xb0, hi: 0xb0},\n\t{value: 0xe439, lo: 0xb1, hi: 0xb6},\n\t{value: 0x8e7d, lo: 0xb7, hi: 0xb9},\n\t{value: 0xe4f9, lo: 0xba, hi: 0xba},\n\t{value: 0x8edd, lo: 0xbb, hi: 0xbb},\n\t{value: 0xe519, lo: 0xbc, hi: 0xbf},\n\t// Block 0x103, offset 0x75e\n\t{value: 0x0020, lo: 0x10},\n\t{value: 0x937d, lo: 0x80, hi: 0x80},\n\t{value: 0xf099, lo: 0x81, hi: 0x86},\n\t{value: 0x939d, lo: 0x87, hi: 0x8a},\n\t{value: 0xd9f9, lo: 0x8b, hi: 0x8b},\n\t{value: 0xf159, lo: 0x8c, hi: 0x96},\n\t{value: 0x941d, lo: 0x97, hi: 0x97},\n\t{value: 0xf2b9, lo: 0x98, hi: 0xa3},\n\t{value: 0x943d, lo: 0xa4, hi: 0xa6},\n\t{value: 0xf439, lo: 0xa7, hi: 0xaa},\n\t{value: 0x949d, lo: 0xab, hi: 0xab},\n\t{value: 0xf4b9, lo: 0xac, hi: 0xac},\n\t{value: 0x94bd, lo: 0xad, hi: 0xad},\n\t{value: 0xf4d9, lo: 0xae, hi: 0xaf},\n\t{value: 0x94dd, lo: 0xb0, hi: 0xb1},\n\t{value: 0xf519, lo: 0xb2, hi: 0xbe},\n\t{value: 0x2040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x104, offset 0x76f\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0340, lo: 0x81, hi: 0x81},\n\t{value: 0x0040, lo: 0x82, hi: 0x9f},\n\t{value: 0x0340, lo: 0xa0, hi: 0xbf},\n\t// Block 0x105, offset 0x774\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0340, lo: 0x80, hi: 0xbf},\n\t// Block 0x106, offset 0x776\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x33c0, lo: 0x80, hi: 0xbf},\n\t// Block 0x107, offset 0x778\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x33c0, lo: 0x80, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n}\n\n// Total table size 42114 bytes (41KiB); checksum: 355A58A4\n"
  },
  {
    "path": "vendor/golang.org/x/net/idna/tables11.0.0.go",
    "content": "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n//go:build go1.13 && !go1.14\n\npackage idna\n\n// UnicodeVersion is the Unicode version from which the tables in this package are derived.\nconst UnicodeVersion = \"11.0.0\"\n\nvar mappings string = \"\" + // Size: 8175 bytes\n\t\"\\x00\\x01 \\x03 ̈\\x01a\\x03 ̄\\x012\\x013\\x03 ́\\x03 ̧\\x011\\x01o\\x051⁄4\\x051⁄2\" +\n\t\"\\x053⁄4\\x03i̇\\x03l·\\x03ʼn\\x01s\\x03dž\\x03ⱥ\\x03ⱦ\\x01h\\x01j\\x01r\\x01w\\x01y\" +\n\t\"\\x03 ̆\\x03 ̇\\x03 ̊\\x03 ̨\\x03 ̃\\x03 ̋\\x01l\\x01x\\x04̈́\\x03 ι\\x01;\\x05 ̈́\" +\n\t\"\\x04եւ\\x04اٴ\\x04وٴ\\x04ۇٴ\\x04يٴ\\x06क़\\x06ख़\\x06ग़\\x06ज़\\x06ड़\\x06ढ़\\x06फ़\" +\n\t\"\\x06य़\\x06ড়\\x06ঢ়\\x06য়\\x06ਲ਼\\x06ਸ਼\\x06ਖ਼\\x06ਗ਼\\x06ਜ਼\\x06ਫ਼\\x06ଡ଼\\x06ଢ଼\" +\n\t\"\\x06ํา\\x06ໍາ\\x06ຫນ\\x06ຫມ\\x06གྷ\\x06ཌྷ\\x06དྷ\\x06བྷ\\x06ཛྷ\\x06ཀྵ\\x06ཱི\\x06ཱུ\" +\n\t\"\\x06ྲྀ\\x09ྲཱྀ\\x06ླྀ\\x09ླཱྀ\\x06ཱྀ\\x06ྒྷ\\x06ྜྷ\\x06ྡྷ\\x06ྦྷ\\x06ྫྷ\\x06ྐྵ\\x02\" +\n\t\"в\\x02д\\x02о\\x02с\\x02т\\x02ъ\\x02ѣ\\x02æ\\x01b\\x01d\\x01e\\x02ǝ\\x01g\\x01i\\x01k\" +\n\t\"\\x01m\\x01n\\x02ȣ\\x01p\\x01t\\x01u\\x02ɐ\\x02ɑ\\x02ə\\x02ɛ\\x02ɜ\\x02ŋ\\x02ɔ\\x02ɯ\" +\n\t\"\\x01v\\x02β\\x02γ\\x02δ\\x02φ\\x02χ\\x02ρ\\x02н\\x02ɒ\\x01c\\x02ɕ\\x02ð\\x01f\\x02ɟ\" +\n\t\"\\x02ɡ\\x02ɥ\\x02ɨ\\x02ɩ\\x02ɪ\\x02ʝ\\x02ɭ\\x02ʟ\\x02ɱ\\x02ɰ\\x02ɲ\\x02ɳ\\x02ɴ\\x02ɵ\" +\n\t\"\\x02ɸ\\x02ʂ\\x02ʃ\\x02ƫ\\x02ʉ\\x02ʊ\\x02ʋ\\x02ʌ\\x01z\\x02ʐ\\x02ʑ\\x02ʒ\\x02θ\\x02ss\" +\n\t\"\\x02ά\\x02έ\\x02ή\\x02ί\\x02ό\\x02ύ\\x02ώ\\x05ἀι\\x05ἁι\\x05ἂι\\x05ἃι\\x05ἄι\\x05ἅι\" +\n\t\"\\x05ἆι\\x05ἇι\\x05ἠι\\x05ἡι\\x05ἢι\\x05ἣι\\x05ἤι\\x05ἥι\\x05ἦι\\x05ἧι\\x05ὠι\\x05ὡι\" +\n\t\"\\x05ὢι\\x05ὣι\\x05ὤι\\x05ὥι\\x05ὦι\\x05ὧι\\x05ὰι\\x04αι\\x04άι\\x05ᾶι\\x02ι\\x05 ̈͂\" +\n\t\"\\x05ὴι\\x04ηι\\x04ήι\\x05ῆι\\x05 ̓̀\\x05 ̓́\\x05 ̓͂\\x02ΐ\\x05 ̔̀\\x05 ̔́\\x05 ̔͂\" +\n\t\"\\x02ΰ\\x05 ̈̀\\x01`\\x05ὼι\\x04ωι\\x04ώι\\x05ῶι\\x06′′\\x09′′′\\x06‵‵\\x09‵‵‵\\x02!\" +\n\t\"!\\x02??\\x02?!\\x02!?\\x0c′′′′\\x010\\x014\\x015\\x016\\x017\\x018\\x019\\x01+\\x01=\" +\n\t\"\\x01(\\x01)\\x02rs\\x02ħ\\x02no\\x01q\\x02sm\\x02tm\\x02ω\\x02å\\x02א\\x02ב\\x02ג\" +\n\t\"\\x02ד\\x02π\\x051⁄7\\x051⁄9\\x061⁄10\\x051⁄3\\x052⁄3\\x051⁄5\\x052⁄5\\x053⁄5\\x054\" +\n\t\"⁄5\\x051⁄6\\x055⁄6\\x051⁄8\\x053⁄8\\x055⁄8\\x057⁄8\\x041⁄\\x02ii\\x02iv\\x02vi\" +\n\t\"\\x04viii\\x02ix\\x02xi\\x050⁄3\\x06∫∫\\x09∫∫∫\\x06∮∮\\x09∮∮∮\\x0210\\x0211\\x0212\" +\n\t\"\\x0213\\x0214\\x0215\\x0216\\x0217\\x0218\\x0219\\x0220\\x04(10)\\x04(11)\\x04(12)\" +\n\t\"\\x04(13)\\x04(14)\\x04(15)\\x04(16)\\x04(17)\\x04(18)\\x04(19)\\x04(20)\\x0c∫∫∫∫\" +\n\t\"\\x02==\\x05⫝̸\\x02ɫ\\x02ɽ\\x02ȿ\\x02ɀ\\x01.\\x04 ゙\\x04 ゚\\x06より\\x06コト\\x05(ᄀ)\\x05\" +\n\t\"(ᄂ)\\x05(ᄃ)\\x05(ᄅ)\\x05(ᄆ)\\x05(ᄇ)\\x05(ᄉ)\\x05(ᄋ)\\x05(ᄌ)\\x05(ᄎ)\\x05(ᄏ)\\x05(ᄐ\" +\n\t\")\\x05(ᄑ)\\x05(ᄒ)\\x05(가)\\x05(나)\\x05(다)\\x05(라)\\x05(마)\\x05(바)\\x05(사)\\x05(아)\" +\n\t\"\\x05(자)\\x05(차)\\x05(카)\\x05(타)\\x05(파)\\x05(하)\\x05(주)\\x08(오전)\\x08(오후)\\x05(一)\" +\n\t\"\\x05(二)\\x05(三)\\x05(四)\\x05(五)\\x05(六)\\x05(七)\\x05(八)\\x05(九)\\x05(十)\\x05(月)\" +\n\t\"\\x05(火)\\x05(水)\\x05(木)\\x05(金)\\x05(土)\\x05(日)\\x05(株)\\x05(有)\\x05(社)\\x05(名)\" +\n\t\"\\x05(特)\\x05(財)\\x05(祝)\\x05(労)\\x05(代)\\x05(呼)\\x05(学)\\x05(監)\\x05(企)\\x05(資)\" +\n\t\"\\x05(協)\\x05(祭)\\x05(休)\\x05(自)\\x05(至)\\x0221\\x0222\\x0223\\x0224\\x0225\\x0226\" +\n\t\"\\x0227\\x0228\\x0229\\x0230\\x0231\\x0232\\x0233\\x0234\\x0235\\x06참고\\x06주의\\x0236\" +\n\t\"\\x0237\\x0238\\x0239\\x0240\\x0241\\x0242\\x0243\\x0244\\x0245\\x0246\\x0247\\x0248\" +\n\t\"\\x0249\\x0250\\x041月\\x042月\\x043月\\x044月\\x045月\\x046月\\x047月\\x048月\\x049月\\x0510\" +\n\t\"月\\x0511月\\x0512月\\x02hg\\x02ev\\x0cアパート\\x0cアルファ\\x0cアンペア\\x09アール\\x0cイニング\\x09\" +\n\t\"インチ\\x09ウォン\\x0fエスクード\\x0cエーカー\\x09オンス\\x09オーム\\x09カイリ\\x0cカラット\\x0cカロリー\\x09ガロ\" +\n\t\"ン\\x09ガンマ\\x06ギガ\\x09ギニー\\x0cキュリー\\x0cギルダー\\x06キロ\\x0fキログラム\\x12キロメートル\\x0fキロワッ\" +\n\t\"ト\\x09グラム\\x0fグラムトン\\x0fクルゼイロ\\x0cクローネ\\x09ケース\\x09コルナ\\x09コーポ\\x0cサイクル\\x0fサンチ\" +\n\t\"ーム\\x0cシリング\\x09センチ\\x09セント\\x09ダース\\x06デシ\\x06ドル\\x06トン\\x06ナノ\\x09ノット\\x09ハイツ\" +\n\t\"\\x0fパーセント\\x09パーツ\\x0cバーレル\\x0fピアストル\\x09ピクル\\x06ピコ\\x06ビル\\x0fファラッド\\x0cフィート\" +\n\t\"\\x0fブッシェル\\x09フラン\\x0fヘクタール\\x06ペソ\\x09ペニヒ\\x09ヘルツ\\x09ペンス\\x09ページ\\x09ベータ\\x0cポイ\" +\n\t\"ント\\x09ボルト\\x06ホン\\x09ポンド\\x09ホール\\x09ホーン\\x0cマイクロ\\x09マイル\\x09マッハ\\x09マルク\\x0fマ\" +\n\t\"ンション\\x0cミクロン\\x06ミリ\\x0fミリバール\\x06メガ\\x0cメガトン\\x0cメートル\\x09ヤード\\x09ヤール\\x09ユアン\" +\n\t\"\\x0cリットル\\x06リラ\\x09ルピー\\x0cルーブル\\x06レム\\x0fレントゲン\\x09ワット\\x040点\\x041点\\x042点\" +\n\t\"\\x043点\\x044点\\x045点\\x046点\\x047点\\x048点\\x049点\\x0510点\\x0511点\\x0512点\\x0513点\" +\n\t\"\\x0514点\\x0515点\\x0516点\\x0517点\\x0518点\\x0519点\\x0520点\\x0521点\\x0522点\\x0523点\" +\n\t\"\\x0524点\\x02da\\x02au\\x02ov\\x02pc\\x02dm\\x02iu\\x06平成\\x06昭和\\x06大正\\x06明治\\x0c株\" +\n\t\"式会社\\x02pa\\x02na\\x02ma\\x02ka\\x02kb\\x02mb\\x02gb\\x04kcal\\x02pf\\x02nf\\x02m\" +\n\t\"g\\x02kg\\x02hz\\x02ml\\x02dl\\x02kl\\x02fm\\x02nm\\x02mm\\x02cm\\x02km\\x02m2\\x02m\" +\n\t\"3\\x05m∕s\\x06m∕s2\\x07rad∕s\\x08rad∕s2\\x02ps\\x02ns\\x02ms\\x02pv\\x02nv\\x02mv\" +\n\t\"\\x02kv\\x02pw\\x02nw\\x02mw\\x02kw\\x02bq\\x02cc\\x02cd\\x06c∕kg\\x02db\\x02gy\\x02\" +\n\t\"ha\\x02hp\\x02in\\x02kk\\x02kt\\x02lm\\x02ln\\x02lx\\x02ph\\x02pr\\x02sr\\x02sv\\x02\" +\n\t\"wb\\x05v∕m\\x05a∕m\\x041日\\x042日\\x043日\\x044日\\x045日\\x046日\\x047日\\x048日\\x049日\" +\n\t\"\\x0510日\\x0511日\\x0512日\\x0513日\\x0514日\\x0515日\\x0516日\\x0517日\\x0518日\\x0519日\" +\n\t\"\\x0520日\\x0521日\\x0522日\\x0523日\\x0524日\\x0525日\\x0526日\\x0527日\\x0528日\\x0529日\" +\n\t\"\\x0530日\\x0531日\\x02ь\\x02ɦ\\x02ɬ\\x02ʞ\\x02ʇ\\x02œ\\x04𤋮\\x04𢡊\\x04𢡄\\x04𣏕\\x04𥉉\" +\n\t\"\\x04𥳐\\x04𧻓\\x02ff\\x02fi\\x02fl\\x02st\\x04մն\\x04մե\\x04մի\\x04վն\\x04մխ\\x04יִ\" +\n\t\"\\x04ײַ\\x02ע\\x02ה\\x02כ\\x02ל\\x02ם\\x02ר\\x02ת\\x04שׁ\\x04שׂ\\x06שּׁ\\x06שּׂ\\x04א\" +\n\t\"ַ\\x04אָ\\x04אּ\\x04בּ\\x04גּ\\x04דּ\\x04הּ\\x04וּ\\x04זּ\\x04טּ\\x04יּ\\x04ךּ\\x04\" +\n\t\"כּ\\x04לּ\\x04מּ\\x04נּ\\x04סּ\\x04ףּ\\x04פּ\\x04צּ\\x04קּ\\x04רּ\\x04שּ\\x04תּ\" +\n\t\"\\x04וֹ\\x04בֿ\\x04כֿ\\x04פֿ\\x04אל\\x02ٱ\\x02ٻ\\x02پ\\x02ڀ\\x02ٺ\\x02ٿ\\x02ٹ\\x02ڤ\" +\n\t\"\\x02ڦ\\x02ڄ\\x02ڃ\\x02چ\\x02ڇ\\x02ڍ\\x02ڌ\\x02ڎ\\x02ڈ\\x02ژ\\x02ڑ\\x02ک\\x02گ\\x02ڳ\" +\n\t\"\\x02ڱ\\x02ں\\x02ڻ\\x02ۀ\\x02ہ\\x02ھ\\x02ے\\x02ۓ\\x02ڭ\\x02ۇ\\x02ۆ\\x02ۈ\\x02ۋ\\x02ۅ\" +\n\t\"\\x02ۉ\\x02ې\\x02ى\\x04ئا\\x04ئە\\x04ئو\\x04ئۇ\\x04ئۆ\\x04ئۈ\\x04ئې\\x04ئى\\x02ی\\x04\" +\n\t\"ئج\\x04ئح\\x04ئم\\x04ئي\\x04بج\\x04بح\\x04بخ\\x04بم\\x04بى\\x04بي\\x04تج\\x04تح\" +\n\t\"\\x04تخ\\x04تم\\x04تى\\x04تي\\x04ثج\\x04ثم\\x04ثى\\x04ثي\\x04جح\\x04جم\\x04حج\\x04حم\" +\n\t\"\\x04خج\\x04خح\\x04خم\\x04سج\\x04سح\\x04سخ\\x04سم\\x04صح\\x04صم\\x04ضج\\x04ضح\\x04ضخ\" +\n\t\"\\x04ضم\\x04طح\\x04طم\\x04ظم\\x04عج\\x04عم\\x04غج\\x04غم\\x04فج\\x04فح\\x04فخ\\x04فم\" +\n\t\"\\x04فى\\x04في\\x04قح\\x04قم\\x04قى\\x04قي\\x04كا\\x04كج\\x04كح\\x04كخ\\x04كل\\x04كم\" +\n\t\"\\x04كى\\x04كي\\x04لج\\x04لح\\x04لخ\\x04لم\\x04لى\\x04لي\\x04مج\\x04مح\\x04مخ\\x04مم\" +\n\t\"\\x04مى\\x04مي\\x04نج\\x04نح\\x04نخ\\x04نم\\x04نى\\x04ني\\x04هج\\x04هم\\x04هى\\x04هي\" +\n\t\"\\x04يج\\x04يح\\x04يخ\\x04يم\\x04يى\\x04يي\\x04ذٰ\\x04رٰ\\x04ىٰ\\x05 ٌّ\\x05 ٍّ\\x05\" +\n\t\" َّ\\x05 ُّ\\x05 ِّ\\x05 ّٰ\\x04ئر\\x04ئز\\x04ئن\\x04بر\\x04بز\\x04بن\\x04تر\\x04تز\" +\n\t\"\\x04تن\\x04ثر\\x04ثز\\x04ثن\\x04ما\\x04نر\\x04نز\\x04نن\\x04ير\\x04يز\\x04ين\\x04ئخ\" +\n\t\"\\x04ئه\\x04به\\x04ته\\x04صخ\\x04له\\x04نه\\x04هٰ\\x04يه\\x04ثه\\x04سه\\x04شم\\x04شه\" +\n\t\"\\x06ـَّ\\x06ـُّ\\x06ـِّ\\x04طى\\x04طي\\x04عى\\x04عي\\x04غى\\x04غي\\x04سى\\x04سي\" +\n\t\"\\x04شى\\x04شي\\x04حى\\x04حي\\x04جى\\x04جي\\x04خى\\x04خي\\x04صى\\x04صي\\x04ضى\\x04ضي\" +\n\t\"\\x04شج\\x04شح\\x04شخ\\x04شر\\x04سر\\x04صر\\x04ضر\\x04اً\\x06تجم\\x06تحج\\x06تحم\" +\n\t\"\\x06تخم\\x06تمج\\x06تمح\\x06تمخ\\x06جمح\\x06حمي\\x06حمى\\x06سحج\\x06سجح\\x06سجى\" +\n\t\"\\x06سمح\\x06سمج\\x06سمم\\x06صحح\\x06صمم\\x06شحم\\x06شجي\\x06شمخ\\x06شمم\\x06ضحى\" +\n\t\"\\x06ضخم\\x06طمح\\x06طمم\\x06طمي\\x06عجم\\x06عمم\\x06عمى\\x06غمم\\x06غمي\\x06غمى\" +\n\t\"\\x06فخم\\x06قمح\\x06قمم\\x06لحم\\x06لحي\\x06لحى\\x06لجج\\x06لخم\\x06لمح\\x06محج\" +\n\t\"\\x06محم\\x06محي\\x06مجح\\x06مجم\\x06مخج\\x06مخم\\x06مجخ\\x06همج\\x06همم\\x06نحم\" +\n\t\"\\x06نحى\\x06نجم\\x06نجى\\x06نمي\\x06نمى\\x06يمم\\x06بخي\\x06تجي\\x06تجى\\x06تخي\" +\n\t\"\\x06تخى\\x06تمي\\x06تمى\\x06جمي\\x06جحى\\x06جمى\\x06سخى\\x06صحي\\x06شحي\\x06ضحي\" +\n\t\"\\x06لجي\\x06لمي\\x06يحي\\x06يجي\\x06يمي\\x06ممي\\x06قمي\\x06نحي\\x06عمي\\x06كمي\" +\n\t\"\\x06نجح\\x06مخي\\x06لجم\\x06كمم\\x06جحي\\x06حجي\\x06مجي\\x06فمي\\x06بحي\\x06سخي\" +\n\t\"\\x06نجي\\x06صلے\\x06قلے\\x08الله\\x08اكبر\\x08محمد\\x08صلعم\\x08رسول\\x08عليه\" +\n\t\"\\x08وسلم\\x06صلى!صلى الله عليه وسلم\\x0fجل جلاله\\x08ریال\\x01,\\x01:\\x01!\" +\n\t\"\\x01?\\x01_\\x01{\\x01}\\x01[\\x01]\\x01#\\x01&\\x01*\\x01-\\x01<\\x01>\\x01\\\\\\x01$\" +\n\t\"\\x01%\\x01@\\x04ـً\\x04ـَ\\x04ـُ\\x04ـِ\\x04ـّ\\x04ـْ\\x02ء\\x02آ\\x02أ\\x02ؤ\\x02إ\" +\n\t\"\\x02ئ\\x02ا\\x02ب\\x02ة\\x02ت\\x02ث\\x02ج\\x02ح\\x02خ\\x02د\\x02ذ\\x02ر\\x02ز\\x02س\" +\n\t\"\\x02ش\\x02ص\\x02ض\\x02ط\\x02ظ\\x02ع\\x02غ\\x02ف\\x02ق\\x02ك\\x02ل\\x02م\\x02ن\\x02ه\" +\n\t\"\\x02و\\x02ي\\x04لآ\\x04لأ\\x04لإ\\x04لا\\x01\\x22\\x01'\\x01/\\x01^\\x01|\\x01~\\x02¢\" +\n\t\"\\x02£\\x02¬\\x02¦\\x02¥\\x08𝅗𝅥\\x08𝅘𝅥\\x0c𝅘𝅥𝅮\\x0c𝅘𝅥𝅯\\x0c𝅘𝅥𝅰\\x0c𝅘𝅥𝅱\\x0c𝅘𝅥𝅲\\x08𝆹\" +\n\t\"𝅥\\x08𝆺𝅥\\x0c𝆹𝅥𝅮\\x0c𝆺𝅥𝅮\\x0c𝆹𝅥𝅯\\x0c𝆺𝅥𝅯\\x02ı\\x02ȷ\\x02α\\x02ε\\x02ζ\\x02η\\x02\" +\n\t\"κ\\x02λ\\x02μ\\x02ν\\x02ξ\\x02ο\\x02σ\\x02τ\\x02υ\\x02ψ\\x03∇\\x03∂\\x02ϝ\\x02ٮ\\x02ڡ\" +\n\t\"\\x02ٯ\\x020,\\x021,\\x022,\\x023,\\x024,\\x025,\\x026,\\x027,\\x028,\\x029,\\x03(a)\" +\n\t\"\\x03(b)\\x03(c)\\x03(d)\\x03(e)\\x03(f)\\x03(g)\\x03(h)\\x03(i)\\x03(j)\\x03(k)\" +\n\t\"\\x03(l)\\x03(m)\\x03(n)\\x03(o)\\x03(p)\\x03(q)\\x03(r)\\x03(s)\\x03(t)\\x03(u)\" +\n\t\"\\x03(v)\\x03(w)\\x03(x)\\x03(y)\\x03(z)\\x07〔s〕\\x02wz\\x02hv\\x02sd\\x03ppv\\x02w\" +\n\t\"c\\x02mc\\x02md\\x02dj\\x06ほか\\x06ココ\\x03サ\\x03手\\x03字\\x03双\\x03デ\\x03二\\x03多\\x03解\" +\n\t\"\\x03天\\x03交\\x03映\\x03無\\x03料\\x03前\\x03後\\x03再\\x03新\\x03初\\x03終\\x03生\\x03販\\x03声\" +\n\t\"\\x03吹\\x03演\\x03投\\x03捕\\x03一\\x03三\\x03遊\\x03左\\x03中\\x03右\\x03指\\x03走\\x03打\\x03禁\" +\n\t\"\\x03空\\x03合\\x03満\\x03有\\x03月\\x03申\\x03割\\x03営\\x03配\\x09〔本〕\\x09〔三〕\\x09〔二〕\\x09〔安\" +\n\t\"〕\\x09〔点〕\\x09〔打〕\\x09〔盗〕\\x09〔勝〕\\x09〔敗〕\\x03得\\x03可\\x03丽\\x03丸\\x03乁\\x03你\\x03\" +\n\t\"侮\\x03侻\\x03倂\\x03偺\\x03備\\x03僧\\x03像\\x03㒞\\x03免\\x03兔\\x03兤\\x03具\\x03㒹\\x03內\\x03\" +\n\t\"冗\\x03冤\\x03仌\\x03冬\\x03况\\x03凵\\x03刃\\x03㓟\\x03刻\\x03剆\\x03剷\\x03㔕\\x03勇\\x03勉\\x03\" +\n\t\"勤\\x03勺\\x03包\\x03匆\\x03北\\x03卉\\x03卑\\x03博\\x03即\\x03卽\\x03卿\\x03灰\\x03及\\x03叟\\x03\" +\n\t\"叫\\x03叱\\x03吆\\x03咞\\x03吸\\x03呈\\x03周\\x03咢\\x03哶\\x03唐\\x03啓\\x03啣\\x03善\\x03喙\\x03\" +\n\t\"喫\\x03喳\\x03嗂\\x03圖\\x03嘆\\x03圗\\x03噑\\x03噴\\x03切\\x03壮\\x03城\\x03埴\\x03堍\\x03型\\x03\" +\n\t\"堲\\x03報\\x03墬\\x03売\\x03壷\\x03夆\\x03夢\\x03奢\\x03姬\\x03娛\\x03娧\\x03姘\\x03婦\\x03㛮\\x03\" +\n\t\"嬈\\x03嬾\\x03寃\\x03寘\\x03寧\\x03寳\\x03寿\\x03将\\x03尢\\x03㞁\\x03屠\\x03屮\\x03峀\\x03岍\\x03\" +\n\t\"嵃\\x03嵮\\x03嵫\\x03嵼\\x03巡\\x03巢\\x03㠯\\x03巽\\x03帨\\x03帽\\x03幩\\x03㡢\\x03㡼\\x03庰\\x03\" +\n\t\"庳\\x03庶\\x03廊\\x03廾\\x03舁\\x03弢\\x03㣇\\x03形\\x03彫\\x03㣣\\x03徚\\x03忍\\x03志\\x03忹\\x03\" +\n\t\"悁\\x03㤺\\x03㤜\\x03悔\\x03惇\\x03慈\\x03慌\\x03慎\\x03慺\\x03憎\\x03憲\\x03憤\\x03憯\\x03懞\\x03\" +\n\t\"懲\\x03懶\\x03成\\x03戛\\x03扝\\x03抱\\x03拔\\x03捐\\x03挽\\x03拼\\x03捨\\x03掃\\x03揤\\x03搢\\x03\" +\n\t\"揅\\x03掩\\x03㨮\\x03摩\\x03摾\\x03撝\\x03摷\\x03㩬\\x03敏\\x03敬\\x03旣\\x03書\\x03晉\\x03㬙\\x03\" +\n\t\"暑\\x03㬈\\x03㫤\\x03冒\\x03冕\\x03最\\x03暜\\x03肭\\x03䏙\\x03朗\\x03望\\x03朡\\x03杞\\x03杓\\x03\" +\n\t\"㭉\\x03柺\\x03枅\\x03桒\\x03梅\\x03梎\\x03栟\\x03椔\\x03㮝\\x03楂\\x03榣\\x03槪\\x03檨\\x03櫛\\x03\" +\n\t\"㰘\\x03次\\x03歔\\x03㱎\\x03歲\\x03殟\\x03殺\\x03殻\\x03汎\\x03沿\\x03泍\\x03汧\\x03洖\\x03派\\x03\" +\n\t\"海\\x03流\\x03浩\\x03浸\\x03涅\\x03洴\\x03港\\x03湮\\x03㴳\\x03滋\\x03滇\\x03淹\\x03潮\\x03濆\\x03\" +\n\t\"瀹\\x03瀞\\x03瀛\\x03㶖\\x03灊\\x03災\\x03灷\\x03炭\\x03煅\\x03熜\\x03爨\\x03爵\\x03牐\\x03犀\\x03\" +\n\t\"犕\\x03獺\\x03王\\x03㺬\\x03玥\\x03㺸\\x03瑇\\x03瑜\\x03瑱\\x03璅\\x03瓊\\x03㼛\\x03甤\\x03甾\\x03\" +\n\t\"異\\x03瘐\\x03㿼\\x03䀈\\x03直\\x03眞\\x03真\\x03睊\\x03䀹\\x03瞋\\x03䁆\\x03䂖\\x03硎\\x03碌\\x03\" +\n\t\"磌\\x03䃣\\x03祖\\x03福\\x03秫\\x03䄯\\x03穀\\x03穊\\x03穏\\x03䈂\\x03篆\\x03築\\x03䈧\\x03糒\\x03\" +\n\t\"䊠\\x03糨\\x03糣\\x03紀\\x03絣\\x03䌁\\x03緇\\x03縂\\x03繅\\x03䌴\\x03䍙\\x03罺\\x03羕\\x03翺\\x03\" +\n\t\"者\\x03聠\\x03聰\\x03䏕\\x03育\\x03脃\\x03䐋\\x03脾\\x03媵\\x03舄\\x03辞\\x03䑫\\x03芑\\x03芋\\x03\" +\n\t\"芝\\x03劳\\x03花\\x03芳\\x03芽\\x03苦\\x03若\\x03茝\\x03荣\\x03莭\\x03茣\\x03莽\\x03菧\\x03著\\x03\" +\n\t\"荓\\x03菊\\x03菌\\x03菜\\x03䔫\\x03蓱\\x03蓳\\x03蔖\\x03蕤\\x03䕝\\x03䕡\\x03䕫\\x03虐\\x03虜\\x03\" +\n\t\"虧\\x03虩\\x03蚩\\x03蚈\\x03蜎\\x03蛢\\x03蝹\\x03蜨\\x03蝫\\x03螆\\x03蟡\\x03蠁\\x03䗹\\x03衠\\x03\" +\n\t\"衣\\x03裗\\x03裞\\x03䘵\\x03裺\\x03㒻\\x03䚾\\x03䛇\\x03誠\\x03諭\\x03變\\x03豕\\x03貫\\x03賁\\x03\" +\n\t\"贛\\x03起\\x03跋\\x03趼\\x03跰\\x03軔\\x03輸\\x03邔\\x03郱\\x03鄑\\x03鄛\\x03鈸\\x03鋗\\x03鋘\\x03\" +\n\t\"鉼\\x03鏹\\x03鐕\\x03開\\x03䦕\\x03閷\\x03䧦\\x03雃\\x03嶲\\x03霣\\x03䩮\\x03䩶\\x03韠\\x03䪲\\x03\" +\n\t\"頋\\x03頩\\x03飢\\x03䬳\\x03餩\\x03馧\\x03駂\\x03駾\\x03䯎\\x03鬒\\x03鱀\\x03鳽\\x03䳎\\x03䳭\\x03\" +\n\t\"鵧\\x03䳸\\x03麻\\x03䵖\\x03黹\\x03黾\\x03鼅\\x03鼏\\x03鼖\\x03鼻\"\n\nvar xorData string = \"\" + // Size: 4855 bytes\n\t\"\\x02\\x0c\\x09\\x02\\xb0\\xec\\x02\\xad\\xd8\\x02\\xad\\xd9\\x02\\x06\\x07\\x02\\x0f\\x12\" +\n\t\"\\x02\\x0f\\x1f\\x02\\x0f\\x1d\\x02\\x01\\x13\\x02\\x0f\\x16\\x02\\x0f\\x0b\\x02\\x0f3\" +\n\t\"\\x02\\x0f7\\x02\\x0f?\\x02\\x0f/\\x02\\x0f*\\x02\\x0c&\\x02\\x0c*\\x02\\x0c;\\x02\\x0c9\" +\n\t\"\\x02\\x0c%\\x02\\xab\\xed\\x02\\xab\\xe2\\x02\\xab\\xe3\\x02\\xa9\\xe0\\x02\\xa9\\xe1\" +\n\t\"\\x02\\xa9\\xe6\\x02\\xa3\\xcb\\x02\\xa3\\xc8\\x02\\xa3\\xc9\\x02\\x01#\\x02\\x01\\x08\" +\n\t\"\\x02\\x0e>\\x02\\x0e'\\x02\\x0f\\x03\\x02\\x03\\x0d\\x02\\x03\\x09\\x02\\x03\\x17\\x02\" +\n\t\"\\x03\\x0e\\x02\\x02\\x03\\x02\\x011\\x02\\x01\\x00\\x02\\x01\\x10\\x02\\x03<\\x02\\x07\" +\n\t\"\\x0d\\x02\\x02\\x0c\\x02\\x0c0\\x02\\x01\\x03\\x02\\x01\\x01\\x02\\x01 \\x02\\x01\\x22\" +\n\t\"\\x02\\x01)\\x02\\x01\\x0a\\x02\\x01\\x0c\\x02\\x02\\x06\\x02\\x02\\x02\\x02\\x03\\x10\" +\n\t\"\\x03\\x037 \\x03\\x0b+\\x03\\x02\\x01\\x04\\x02\\x01\\x02\\x02\\x019\\x02\\x03\\x1c\\x02\" +\n\t\"\\x02$\\x03\\x80p$\\x02\\x03:\\x02\\x03\\x0a\\x03\\xc1r.\\x03\\xc1r,\\x03\\xc1r\\x02\" +\n\t\"\\x02\\x02:\\x02\\x02>\\x02\\x02,\\x02\\x02\\x10\\x02\\x02\\x00\\x03\\xc1s<\\x03\\xc1s*\" +\n\t\"\\x03\\xc2L$\\x03\\xc2L;\\x02\\x09)\\x02\\x0a\\x19\\x03\\x83\\xab\\xe3\\x03\\x83\\xab\" +\n\t\"\\xf2\\x03 4\\xe0\\x03\\x81\\xab\\xea\\x03\\x81\\xab\\xf3\\x03 4\\xef\\x03\\x96\\xe1\\xcd\" +\n\t\"\\x03\\x84\\xe5\\xc3\\x02\\x0d\\x11\\x03\\x8b\\xec\\xcb\\x03\\x94\\xec\\xcf\\x03\\x9a\\xec\" +\n\t\"\\xc2\\x03\\x8b\\xec\\xdb\\x03\\x94\\xec\\xdf\\x03\\x9a\\xec\\xd2\\x03\\x01\\x0c!\\x03\" +\n\t\"\\x01\\x0c#\\x03ʠ\\x9d\\x03ʣ\\x9c\\x03ʢ\\x9f\\x03ʥ\\x9e\\x03ʤ\\x91\\x03ʧ\\x90\\x03ʦ\\x93\" +\n\t\"\\x03ʩ\\x92\\x03ʨ\\x95\\x03\\xca\\xf3\\xb5\\x03\\xca\\xf0\\xb4\\x03\\xca\\xf1\\xb7\\x03\" +\n\t\"\\xca\\xf6\\xb6\\x03\\xca\\xf7\\x89\\x03\\xca\\xf4\\x88\\x03\\xca\\xf5\\x8b\\x03\\xca\\xfa\" +\n\t\"\\x8a\\x03\\xca\\xfb\\x8d\\x03\\xca\\xf8\\x8c\\x03\\xca\\xf9\\x8f\\x03\\xca\\xfe\\x8e\\x03\" +\n\t\"\\xca\\xff\\x81\\x03\\xca\\xfc\\x80\\x03\\xca\\xfd\\x83\\x03\\xca\\xe2\\x82\\x03\\xca\\xe3\" +\n\t\"\\x85\\x03\\xca\\xe0\\x84\\x03\\xca\\xe1\\x87\\x03\\xca\\xe6\\x86\\x03\\xca\\xe7\\x99\\x03\" +\n\t\"\\xca\\xe4\\x98\\x03\\xca\\xe5\\x9b\\x03\\xca\\xea\\x9a\\x03\\xca\\xeb\\x9d\\x03\\xca\\xe8\" +\n\t\"\\x9c\\x03ؓ\\x89\\x03ߔ\\x8b\\x02\\x010\\x03\\x03\\x04\\x1e\\x03\\x04\\x15\\x12\\x03\\x0b\" +\n\t\"\\x05,\\x03\\x06\\x04\\x00\\x03\\x06\\x04)\\x03\\x06\\x044\\x03\\x06\\x04<\\x03\\x06\\x05\" +\n\t\"\\x1d\\x03\\x06\\x06\\x00\\x03\\x06\\x06\\x0a\\x03\\x06\\x06'\\x03\\x06\\x062\\x03\\x0786\" +\n\t\"\\x03\\x079/\\x03\\x079 \\x03\\x07:\\x0e\\x03\\x07:\\x1b\\x03\\x07:%\\x03\\x07;/\\x03\" +\n\t\"\\x07;%\\x03\\x074\\x11\\x03\\x076\\x09\\x03\\x077*\\x03\\x070\\x01\\x03\\x070\\x0f\\x03\" +\n\t\"\\x070.\\x03\\x071\\x16\\x03\\x071\\x04\\x03\\x0710\\x03\\x072\\x18\\x03\\x072-\\x03\" +\n\t\"\\x073\\x14\\x03\\x073>\\x03\\x07'\\x09\\x03\\x07 \\x00\\x03\\x07\\x1f\\x0b\\x03\\x07\" +\n\t\"\\x18#\\x03\\x07\\x18(\\x03\\x07\\x186\\x03\\x07\\x18\\x03\\x03\\x07\\x19\\x16\\x03\\x07\" +\n\t\"\\x116\\x03\\x07\\x12'\\x03\\x07\\x13\\x10\\x03\\x07\\x0c&\\x03\\x07\\x0c\\x08\\x03\\x07\" +\n\t\"\\x0c\\x13\\x03\\x07\\x0d\\x02\\x03\\x07\\x0d\\x1c\\x03\\x07\\x0b5\\x03\\x07\\x0b\\x0a\" +\n\t\"\\x03\\x07\\x0b\\x01\\x03\\x07\\x0b\\x0f\\x03\\x07\\x05\\x00\\x03\\x07\\x05\\x09\\x03\\x07\" +\n\t\"\\x05\\x0b\\x03\\x07\\x07\\x01\\x03\\x07\\x07\\x08\\x03\\x07\\x00<\\x03\\x07\\x00+\\x03\" +\n\t\"\\x07\\x01)\\x03\\x07\\x01\\x1b\\x03\\x07\\x01\\x08\\x03\\x07\\x03?\\x03\\x0445\\x03\\x04\" +\n\t\"4\\x08\\x03\\x0454\\x03\\x04)/\\x03\\x04)5\\x03\\x04+\\x05\\x03\\x04+\\x14\\x03\\x04+ \" +\n\t\"\\x03\\x04+<\\x03\\x04*&\\x03\\x04*\\x22\\x03\\x04&8\\x03\\x04!\\x01\\x03\\x04!\\x22\" +\n\t\"\\x03\\x04\\x11+\\x03\\x04\\x10.\\x03\\x04\\x104\\x03\\x04\\x13=\\x03\\x04\\x12\\x04\\x03\" +\n\t\"\\x04\\x12\\x0a\\x03\\x04\\x0d\\x1d\\x03\\x04\\x0d\\x07\\x03\\x04\\x0d \\x03\\x05<>\\x03\" +\n\t\"\\x055<\\x03\\x055!\\x03\\x055#\\x03\\x055&\\x03\\x054\\x1d\\x03\\x054\\x02\\x03\\x054\" +\n\t\"\\x07\\x03\\x0571\\x03\\x053\\x1a\\x03\\x053\\x16\\x03\\x05.<\\x03\\x05.\\x07\\x03\\x05)\" +\n\t\":\\x03\\x05)<\\x03\\x05)\\x0c\\x03\\x05)\\x15\\x03\\x05+-\\x03\\x05+5\\x03\\x05$\\x1e\" +\n\t\"\\x03\\x05$\\x14\\x03\\x05'\\x04\\x03\\x05'\\x14\\x03\\x05&\\x02\\x03\\x05\\x226\\x03\" +\n\t\"\\x05\\x22\\x0c\\x03\\x05\\x22\\x1c\\x03\\x05\\x19\\x0a\\x03\\x05\\x1b\\x09\\x03\\x05\\x1b\" +\n\t\"\\x0c\\x03\\x05\\x14\\x07\\x03\\x05\\x16?\\x03\\x05\\x16\\x0c\\x03\\x05\\x0c\\x05\\x03\" +\n\t\"\\x05\\x0e\\x0f\\x03\\x05\\x01\\x0e\\x03\\x05\\x00(\\x03\\x05\\x030\\x03\\x05\\x03\\x06\" +\n\t\"\\x03\\x0a==\\x03\\x0a=1\\x03\\x0a=,\\x03\\x0a=\\x0c\\x03\\x0a??\\x03\\x0a<\\x08\\x03\" +\n\t\"\\x0a9!\\x03\\x0a9)\\x03\\x0a97\\x03\\x0a99\\x03\\x0a6\\x0a\\x03\\x0a6\\x1c\\x03\\x0a6\" +\n\t\"\\x17\\x03\\x0a7'\\x03\\x0a78\\x03\\x0a73\\x03\\x0a'\\x01\\x03\\x0a'&\\x03\\x0a\\x1f\" +\n\t\"\\x0e\\x03\\x0a\\x1f\\x03\\x03\\x0a\\x1f3\\x03\\x0a\\x1b/\\x03\\x0a\\x18\\x19\\x03\\x0a\" +\n\t\"\\x19\\x01\\x03\\x0a\\x16\\x14\\x03\\x0a\\x0e\\x22\\x03\\x0a\\x0f\\x10\\x03\\x0a\\x0f\\x02\" +\n\t\"\\x03\\x0a\\x0f \\x03\\x0a\\x0c\\x04\\x03\\x0a\\x0b>\\x03\\x0a\\x0b+\\x03\\x0a\\x08/\\x03\" +\n\t\"\\x0a\\x046\\x03\\x0a\\x05\\x14\\x03\\x0a\\x00\\x04\\x03\\x0a\\x00\\x10\\x03\\x0a\\x00\" +\n\t\"\\x14\\x03\\x0b<3\\x03\\x0b;*\\x03\\x0b9\\x22\\x03\\x0b9)\\x03\\x0b97\\x03\\x0b+\\x10\" +\n\t\"\\x03\\x0b((\\x03\\x0b&5\\x03\\x0b$\\x1c\\x03\\x0b$\\x12\\x03\\x0b%\\x04\\x03\\x0b#<\" +\n\t\"\\x03\\x0b#0\\x03\\x0b#\\x0d\\x03\\x0b#\\x19\\x03\\x0b!:\\x03\\x0b!\\x1f\\x03\\x0b!\\x00\" +\n\t\"\\x03\\x0b\\x1e5\\x03\\x0b\\x1c\\x1d\\x03\\x0b\\x1d-\\x03\\x0b\\x1d(\\x03\\x0b\\x18.\\x03\" +\n\t\"\\x0b\\x18 \\x03\\x0b\\x18\\x16\\x03\\x0b\\x14\\x13\\x03\\x0b\\x15$\\x03\\x0b\\x15\\x22\" +\n\t\"\\x03\\x0b\\x12\\x1b\\x03\\x0b\\x12\\x10\\x03\\x0b\\x132\\x03\\x0b\\x13=\\x03\\x0b\\x12\" +\n\t\"\\x18\\x03\\x0b\\x0c&\\x03\\x0b\\x061\\x03\\x0b\\x06:\\x03\\x0b\\x05#\\x03\\x0b\\x05<\" +\n\t\"\\x03\\x0b\\x04\\x0b\\x03\\x0b\\x04\\x04\\x03\\x0b\\x04\\x1b\\x03\\x0b\\x042\\x03\\x0b\" +\n\t\"\\x041\\x03\\x0b\\x03\\x03\\x03\\x0b\\x03\\x1d\\x03\\x0b\\x03/\\x03\\x0b\\x03+\\x03\\x0b\" +\n\t\"\\x02\\x1b\\x03\\x0b\\x02\\x00\\x03\\x0b\\x01\\x1e\\x03\\x0b\\x01\\x08\\x03\\x0b\\x015\" +\n\t\"\\x03\\x06\\x0d9\\x03\\x06\\x0d=\\x03\\x06\\x0d?\\x03\\x02\\x001\\x03\\x02\\x003\\x03\" +\n\t\"\\x02\\x02\\x19\\x03\\x02\\x006\\x03\\x02\\x02\\x1b\\x03\\x02\\x004\\x03\\x02\\x00<\\x03\" +\n\t\"\\x02\\x02\\x0a\\x03\\x02\\x02\\x0e\\x03\\x02\\x01\\x1a\\x03\\x02\\x01\\x07\\x03\\x02\\x01\" +\n\t\"\\x05\\x03\\x02\\x01\\x0b\\x03\\x02\\x01%\\x03\\x02\\x01\\x0c\\x03\\x02\\x01\\x04\\x03\" +\n\t\"\\x02\\x01\\x1c\\x03\\x02\\x00.\\x03\\x02\\x002\\x03\\x02\\x00>\\x03\\x02\\x00\\x12\\x03\" +\n\t\"\\x02\\x00\\x16\\x03\\x02\\x011\\x03\\x02\\x013\\x03\\x02\\x02 \\x03\\x02\\x02%\\x03\\x02\" +\n\t\"\\x02$\\x03\\x02\\x028\\x03\\x02\\x02;\\x03\\x02\\x024\\x03\\x02\\x012\\x03\\x02\\x022\" +\n\t\"\\x03\\x02\\x02/\\x03\\x02\\x01,\\x03\\x02\\x01\\x13\\x03\\x02\\x01\\x16\\x03\\x02\\x01\" +\n\t\"\\x11\\x03\\x02\\x01\\x1e\\x03\\x02\\x01\\x15\\x03\\x02\\x01\\x17\\x03\\x02\\x01\\x0f\\x03\" +\n\t\"\\x02\\x01\\x08\\x03\\x02\\x00?\\x03\\x02\\x03\\x07\\x03\\x02\\x03\\x0d\\x03\\x02\\x03\" +\n\t\"\\x13\\x03\\x02\\x03\\x1d\\x03\\x02\\x03\\x1f\\x03\\x02\\x00\\x03\\x03\\x02\\x00\\x0d\\x03\" +\n\t\"\\x02\\x00\\x01\\x03\\x02\\x00\\x1b\\x03\\x02\\x00\\x19\\x03\\x02\\x00\\x18\\x03\\x02\\x00\" +\n\t\"\\x13\\x03\\x02\\x00/\\x03\\x07>\\x12\\x03\\x07<\\x1f\\x03\\x07>\\x1d\\x03\\x06\\x1d\\x0e\" +\n\t\"\\x03\\x07>\\x1c\\x03\\x07>:\\x03\\x07>\\x13\\x03\\x04\\x12+\\x03\\x07?\\x03\\x03\\x07>\" +\n\t\"\\x02\\x03\\x06\\x224\\x03\\x06\\x1a.\\x03\\x07<%\\x03\\x06\\x1c\\x0b\\x03\\x0609\\x03\" +\n\t\"\\x05\\x1f\\x01\\x03\\x04'\\x08\\x03\\x93\\xfd\\xf5\\x03\\x02\\x0d \\x03\\x02\\x0d#\\x03\" +\n\t\"\\x02\\x0d!\\x03\\x02\\x0d&\\x03\\x02\\x0d\\x22\\x03\\x02\\x0d/\\x03\\x02\\x0d,\\x03\\x02\" +\n\t\"\\x0d$\\x03\\x02\\x0d'\\x03\\x02\\x0d%\\x03\\x02\\x0d;\\x03\\x02\\x0d=\\x03\\x02\\x0d?\" +\n\t\"\\x03\\x099.\\x03\\x08\\x0b7\\x03\\x08\\x02\\x14\\x03\\x08\\x14\\x0d\\x03\\x08.:\\x03\" +\n\t\"\\x089'\\x03\\x0f\\x0b\\x18\\x03\\x0f\\x1c1\\x03\\x0f\\x17&\\x03\\x0f9\\x1f\\x03\\x0f0\" +\n\t\"\\x0c\\x03\\x0e\\x0a9\\x03\\x0e\\x056\\x03\\x0e\\x1c#\\x03\\x0f\\x13\\x0e\\x03\\x072\\x00\" +\n\t\"\\x03\\x070\\x0d\\x03\\x072\\x0b\\x03\\x06\\x11\\x18\\x03\\x070\\x10\\x03\\x06\\x0f(\\x03\" +\n\t\"\\x072\\x05\\x03\\x06\\x0f,\\x03\\x073\\x15\\x03\\x06\\x07\\x08\\x03\\x05\\x16\\x02\\x03\" +\n\t\"\\x04\\x0b \\x03\\x05:8\\x03\\x05\\x16%\\x03\\x0a\\x0d\\x1f\\x03\\x06\\x16\\x10\\x03\\x05\" +\n\t\"\\x1d5\\x03\\x05*;\\x03\\x05\\x16\\x1b\\x03\\x04.-\\x03\\x06\\x1a\\x19\\x03\\x04\\x03,\" +\n\t\"\\x03\\x0b87\\x03\\x04/\\x0a\\x03\\x06\\x00,\\x03\\x04-\\x01\\x03\\x04\\x1e-\\x03\\x06/(\" +\n\t\"\\x03\\x0a\\x0b5\\x03\\x06\\x0e7\\x03\\x06\\x07.\\x03\\x0597\\x03\\x0a*%\\x03\\x0760\" +\n\t\"\\x03\\x06\\x0c;\\x03\\x05'\\x00\\x03\\x072.\\x03\\x072\\x08\\x03\\x06=\\x01\\x03\\x06\" +\n\t\"\\x05\\x1b\\x03\\x06\\x06\\x12\\x03\\x06$=\\x03\\x06'\\x0d\\x03\\x04\\x11\\x0f\\x03\\x076\" +\n\t\",\\x03\\x06\\x07;\\x03\\x06.,\\x03\\x86\\xf9\\xea\\x03\\x8f\\xff\\xeb\\x02\\x092\\x02\" +\n\t\"\\x095\\x02\\x094\\x02\\x09;\\x02\\x09>\\x02\\x098\\x02\\x09*\\x02\\x09/\\x02\\x09,\\x02\" +\n\t\"\\x09%\\x02\\x09&\\x02\\x09#\\x02\\x09 \\x02\\x08!\\x02\\x08%\\x02\\x08$\\x02\\x08+\\x02\" +\n\t\"\\x08.\\x02\\x08*\\x02\\x08&\\x02\\x088\\x02\\x08>\\x02\\x084\\x02\\x086\\x02\\x080\\x02\" +\n\t\"\\x08\\x10\\x02\\x08\\x17\\x02\\x08\\x12\\x02\\x08\\x1d\\x02\\x08\\x1f\\x02\\x08\\x13\\x02\" +\n\t\"\\x08\\x15\\x02\\x08\\x14\\x02\\x08\\x0c\\x03\\x8b\\xfd\\xd0\\x03\\x81\\xec\\xc6\\x03\\x87\" +\n\t\"\\xe0\\x8a\\x03-2\\xe3\\x03\\x80\\xef\\xe4\\x03-2\\xea\\x03\\x88\\xe6\\xeb\\x03\\x8e\\xe6\" +\n\t\"\\xe8\\x03\\x84\\xe6\\xe9\\x03\\x97\\xe6\\xee\\x03-2\\xf9\\x03-2\\xf6\\x03\\x8e\\xe3\\xad\" +\n\t\"\\x03\\x80\\xe3\\x92\\x03\\x88\\xe3\\x90\\x03\\x8e\\xe3\\x90\\x03\\x80\\xe3\\x97\\x03\\x88\" +\n\t\"\\xe3\\x95\\x03\\x88\\xfe\\xcb\\x03\\x8e\\xfe\\xca\\x03\\x84\\xfe\\xcd\\x03\\x91\\xef\\xc9\" +\n\t\"\\x03-2\\xc1\\x03-2\\xc0\\x03-2\\xcb\\x03\\x88@\\x09\\x03\\x8e@\\x08\\x03\\x8f\\xe0\\xf5\" +\n\t\"\\x03\\x8e\\xe6\\xf9\\x03\\x8e\\xe0\\xfa\\x03\\x93\\xff\\xf4\\x03\\x84\\xee\\xd3\\x03\\x0b\" +\n\t\"(\\x04\\x023 \\x021;\\x02\\x01*\\x03\\x0b#\\x10\\x03\\x0b 0\\x03\\x0b!\\x10\\x03\\x0b!0\" +\n\t\"\\x03\\x07\\x15\\x08\\x03\\x09?5\\x03\\x07\\x1f\\x08\\x03\\x07\\x17\\x0b\\x03\\x09\\x1f\" +\n\t\"\\x15\\x03\\x0b\\x1c7\\x03\\x0a+#\\x03\\x06\\x1a\\x1b\\x03\\x06\\x1a\\x14\\x03\\x0a\\x01\" +\n\t\"\\x18\\x03\\x06#\\x1b\\x03\\x0a2\\x0c\\x03\\x0a\\x01\\x04\\x03\\x09#;\\x03\\x08='\\x03\" +\n\t\"\\x08\\x1a\\x0a\\x03\\x07</\\x03\\x07:+\\x03\\x07\\x07*\\x03\\x06&\\x1c\\x03\\x09\\x0c\" +\n\t\"\\x16\\x03\\x09\\x10\\x0e\\x03\\x08'\\x0f\\x03\\x08+\\x09\\x03\\x074%\\x03\\x06!3\\x03\" +\n\t\"\\x06\\x03+\\x03\\x0b\\x1e\\x19\\x03\\x0a))\\x03\\x09\\x08\\x19\\x03\\x08,\\x05\\x03\\x07\" +\n\t\"<2\\x03\\x06\\x1c>\\x03\\x0a\\x111\\x03\\x09\\x1b\\x09\\x03\\x073.\\x03\\x07\\x01\\x00\" +\n\t\"\\x03\\x09/,\\x03\\x07#>\\x03\\x07\\x048\\x03\\x0a\\x1f\\x22\\x03\\x098>\\x03\\x09\\x11\" +\n\t\"\\x00\\x03\\x08/\\x17\\x03\\x06'\\x22\\x03\\x0b\\x1a+\\x03\\x0a\\x22\\x19\\x03\\x0a/1\" +\n\t\"\\x03\\x0974\\x03\\x09\\x0f\\x22\\x03\\x08,\\x22\\x03\\x08?\\x14\\x03\\x07$5\\x03\\x07<3\" +\n\t\"\\x03\\x07=*\\x03\\x07\\x13\\x18\\x03\\x068\\x0a\\x03\\x06\\x09\\x16\\x03\\x06\\x13\\x00\" +\n\t\"\\x03\\x08\\x067\\x03\\x08\\x01\\x03\\x03\\x08\\x12\\x1d\\x03\\x07+7\\x03\\x06(;\\x03\" +\n\t\"\\x06\\x1c?\\x03\\x07\\x0e\\x17\\x03\\x0a\\x06\\x1d\\x03\\x0a\\x19\\x07\\x03\\x08\\x14$\" +\n\t\"\\x03\\x07$;\\x03\\x08,$\\x03\\x08\\x06\\x0d\\x03\\x07\\x16\\x0a\\x03\\x06>>\\x03\\x0a\" +\n\t\"\\x06\\x12\\x03\\x0a\\x14)\\x03\\x09\\x0d\\x1f\\x03\\x09\\x12\\x17\\x03\\x09\\x19\\x01\" +\n\t\"\\x03\\x08\\x11 \\x03\\x08\\x1d'\\x03\\x06<\\x1a\\x03\\x0a.\\x00\\x03\\x07'\\x18\\x03\" +\n\t\"\\x0a\\x22\\x08\\x03\\x08\\x0d\\x0a\\x03\\x08\\x13)\\x03\\x07*)\\x03\\x06<,\\x03\\x07\" +\n\t\"\\x0b\\x1a\\x03\\x09.\\x14\\x03\\x09\\x0d\\x1e\\x03\\x07\\x0e#\\x03\\x0b\\x1d'\\x03\\x0a\" +\n\t\"\\x0a8\\x03\\x09%2\\x03\\x08+&\\x03\\x080\\x12\\x03\\x0a)4\\x03\\x08\\x06\\x1f\\x03\\x0b\" +\n\t\"\\x1b\\x1a\\x03\\x0a\\x1b\\x0f\\x03\\x0b\\x1d*\\x03\\x09\\x16$\\x03\\x090\\x11\\x03\\x08\" +\n\t\"\\x11\\x08\\x03\\x0a*(\\x03\\x0a\\x042\\x03\\x089,\\x03\\x074'\\x03\\x07\\x0f\\x05\\x03\" +\n\t\"\\x09\\x0b\\x0a\\x03\\x07\\x1b\\x01\\x03\\x09\\x17:\\x03\\x09.\\x0d\\x03\\x07.\\x11\\x03\" +\n\t\"\\x09+\\x15\\x03\\x080\\x13\\x03\\x0b\\x1f\\x19\\x03\\x0a \\x11\\x03\\x0a\\x220\\x03\\x09\" +\n\t\"\\x07;\\x03\\x08\\x16\\x1c\\x03\\x07,\\x13\\x03\\x07\\x0e/\\x03\\x06\\x221\\x03\\x0a.\" +\n\t\"\\x0a\\x03\\x0a7\\x02\\x03\\x0a\\x032\\x03\\x0a\\x1d.\\x03\\x091\\x06\\x03\\x09\\x19:\" +\n\t\"\\x03\\x08\\x02/\\x03\\x060+\\x03\\x06\\x0f-\\x03\\x06\\x1c\\x1f\\x03\\x06\\x1d\\x07\\x03\" +\n\t\"\\x0a,\\x11\\x03\\x09=\\x0d\\x03\\x09\\x0b;\\x03\\x07\\x1b/\\x03\\x0a\\x1f:\\x03\\x09 \" +\n\t\"\\x1f\\x03\\x09.\\x10\\x03\\x094\\x0b\\x03\\x09\\x1a1\\x03\\x08#\\x1a\\x03\\x084\\x1d\" +\n\t\"\\x03\\x08\\x01\\x1f\\x03\\x08\\x11\\x22\\x03\\x07'8\\x03\\x07\\x1a>\\x03\\x0757\\x03\" +\n\t\"\\x06&9\\x03\\x06+\\x11\\x03\\x0a.\\x0b\\x03\\x0a,>\\x03\\x0a4#\\x03\\x08%\\x17\\x03\" +\n\t\"\\x07\\x05\\x22\\x03\\x07\\x0c\\x0b\\x03\\x0a\\x1d+\\x03\\x0a\\x19\\x16\\x03\\x09+\\x1f\" +\n\t\"\\x03\\x09\\x08\\x0b\\x03\\x08\\x16\\x18\\x03\\x08+\\x12\\x03\\x0b\\x1d\\x0c\\x03\\x0a=\" +\n\t\"\\x10\\x03\\x0a\\x09\\x0d\\x03\\x0a\\x10\\x11\\x03\\x09&0\\x03\\x08(\\x1f\\x03\\x087\\x07\" +\n\t\"\\x03\\x08\\x185\\x03\\x07'6\\x03\\x06.\\x05\\x03\\x06=\\x04\\x03\\x06;;\\x03\\x06\\x06,\" +\n\t\"\\x03\\x0b\\x18>\\x03\\x08\\x00\\x18\\x03\\x06 \\x03\\x03\\x06<\\x00\\x03\\x09%\\x18\\x03\" +\n\t\"\\x0b\\x1c<\\x03\\x0a%!\\x03\\x0a\\x09\\x12\\x03\\x0a\\x16\\x02\\x03\\x090'\\x03\\x09\" +\n\t\"\\x0e=\\x03\\x08 \\x0e\\x03\\x08>\\x03\\x03\\x074>\\x03\\x06&?\\x03\\x06\\x19\\x09\\x03\" +\n\t\"\\x06?(\\x03\\x0a-\\x0e\\x03\\x09:3\\x03\\x098:\\x03\\x09\\x12\\x0b\\x03\\x09\\x1d\\x17\" +\n\t\"\\x03\\x087\\x05\\x03\\x082\\x14\\x03\\x08\\x06%\\x03\\x08\\x13\\x1f\\x03\\x06\\x06\\x0e\" +\n\t\"\\x03\\x0a\\x22<\\x03\\x09/<\\x03\\x06>+\\x03\\x0a'?\\x03\\x0a\\x13\\x0c\\x03\\x09\\x10<\" +\n\t\"\\x03\\x07\\x1b=\\x03\\x0a\\x19\\x13\\x03\\x09\\x22\\x1d\\x03\\x09\\x07\\x0d\\x03\\x08)\" +\n\t\"\\x1c\\x03\\x06=\\x1a\\x03\\x0a/4\\x03\\x0a7\\x11\\x03\\x0a\\x16:\\x03\\x09?3\\x03\\x09:\" +\n\t\"/\\x03\\x09\\x05\\x0a\\x03\\x09\\x14\\x06\\x03\\x087\\x22\\x03\\x080\\x07\\x03\\x08\\x1a\" +\n\t\"\\x1f\\x03\\x07\\x04(\\x03\\x07\\x04\\x09\\x03\\x06 %\\x03\\x06<\\x08\\x03\\x0a+\\x14\" +\n\t\"\\x03\\x09\\x1d\\x16\\x03\\x0a70\\x03\\x08 >\\x03\\x0857\\x03\\x070\\x0a\\x03\\x06=\\x12\" +\n\t\"\\x03\\x06\\x16%\\x03\\x06\\x1d,\\x03\\x099#\\x03\\x09\\x10>\\x03\\x07 \\x1e\\x03\\x08\" +\n\t\"\\x0c<\\x03\\x08\\x0b\\x18\\x03\\x08\\x15+\\x03\\x08,:\\x03\\x08%\\x22\\x03\\x07\\x0a$\" +\n\t\"\\x03\\x0b\\x1c=\\x03\\x07+\\x08\\x03\\x0a/\\x05\\x03\\x0a \\x07\\x03\\x0a\\x12'\\x03\" +\n\t\"\\x09#\\x11\\x03\\x08\\x1b\\x15\\x03\\x0a\\x06\\x01\\x03\\x09\\x1c\\x1b\\x03\\x0922\\x03\" +\n\t\"\\x07\\x14<\\x03\\x07\\x09\\x04\\x03\\x061\\x04\\x03\\x07\\x0e\\x01\\x03\\x0a\\x13\\x18\" +\n\t\"\\x03\\x0a-\\x0c\\x03\\x0a?\\x0d\\x03\\x0a\\x09\\x0a\\x03\\x091&\\x03\\x0a/\\x0b\\x03\" +\n\t\"\\x08$<\\x03\\x083\\x1d\\x03\\x08\\x0c$\\x03\\x08\\x0d\\x07\\x03\\x08\\x0d?\\x03\\x08\" +\n\t\"\\x0e\\x14\\x03\\x065\\x0a\\x03\\x08\\x1a#\\x03\\x08\\x16#\\x03\\x0702\\x03\\x07\\x03\" +\n\t\"\\x1a\\x03\\x06(\\x1d\\x03\\x06+\\x1b\\x03\\x06\\x0b\\x05\\x03\\x06\\x0b\\x17\\x03\\x06\" +\n\t\"\\x0c\\x04\\x03\\x06\\x1e\\x19\\x03\\x06+0\\x03\\x062\\x18\\x03\\x0b\\x16\\x1e\\x03\\x0a+\" +\n\t\"\\x16\\x03\\x0a-?\\x03\\x0a#:\\x03\\x0a#\\x10\\x03\\x0a%$\\x03\\x0a>+\\x03\\x0a01\\x03\" +\n\t\"\\x0a1\\x10\\x03\\x0a\\x099\\x03\\x0a\\x0a\\x12\\x03\\x0a\\x19\\x1f\\x03\\x0a\\x19\\x12\" +\n\t\"\\x03\\x09*)\\x03\\x09-\\x16\\x03\\x09.1\\x03\\x09.2\\x03\\x09<\\x0e\\x03\\x09> \\x03\" +\n\t\"\\x093\\x12\\x03\\x09\\x0b\\x01\\x03\\x09\\x1c2\\x03\\x09\\x11\\x1c\\x03\\x09\\x15%\\x03\" +\n\t\"\\x08,&\\x03\\x08!\\x22\\x03\\x089(\\x03\\x08\\x0b\\x1a\\x03\\x08\\x0d2\\x03\\x08\\x0c\" +\n\t\"\\x04\\x03\\x08\\x0c\\x06\\x03\\x08\\x0c\\x1f\\x03\\x08\\x0c\\x0c\\x03\\x08\\x0f\\x1f\\x03\" +\n\t\"\\x08\\x0f\\x1d\\x03\\x08\\x00\\x14\\x03\\x08\\x03\\x14\\x03\\x08\\x06\\x16\\x03\\x08\\x1e\" +\n\t\"#\\x03\\x08\\x11\\x11\\x03\\x08\\x10\\x18\\x03\\x08\\x14(\\x03\\x07)\\x1e\\x03\\x07.1\" +\n\t\"\\x03\\x07 $\\x03\\x07 '\\x03\\x078\\x08\\x03\\x07\\x0d0\\x03\\x07\\x0f7\\x03\\x07\\x05#\" +\n\t\"\\x03\\x07\\x05\\x1a\\x03\\x07\\x1a7\\x03\\x07\\x1d-\\x03\\x07\\x17\\x10\\x03\\x06)\\x1f\" +\n\t\"\\x03\\x062\\x0b\\x03\\x066\\x16\\x03\\x06\\x09\\x11\\x03\\x09(\\x1e\\x03\\x07!5\\x03\" +\n\t\"\\x0b\\x11\\x16\\x03\\x0a/\\x04\\x03\\x0a,\\x1a\\x03\\x0b\\x173\\x03\\x0a,1\\x03\\x0a/5\" +\n\t\"\\x03\\x0a\\x221\\x03\\x0a\\x22\\x0d\\x03\\x0a?%\\x03\\x0a<,\\x03\\x0a?#\\x03\\x0a>\\x19\" +\n\t\"\\x03\\x0a\\x08&\\x03\\x0a\\x0b\\x0e\\x03\\x0a\\x0c:\\x03\\x0a\\x0c+\\x03\\x0a\\x03\\x22\" +\n\t\"\\x03\\x0a\\x06)\\x03\\x0a\\x11\\x10\\x03\\x0a\\x11\\x1a\\x03\\x0a\\x17-\\x03\\x0a\\x14(\" +\n\t\"\\x03\\x09)\\x1e\\x03\\x09/\\x09\\x03\\x09.\\x00\\x03\\x09,\\x07\\x03\\x09/*\\x03\\x09-9\" +\n\t\"\\x03\\x09\\x228\\x03\\x09%\\x09\\x03\\x09:\\x12\\x03\\x09;\\x1d\\x03\\x09?\\x06\\x03\" +\n\t\"\\x093%\\x03\\x096\\x05\\x03\\x096\\x08\\x03\\x097\\x02\\x03\\x09\\x07,\\x03\\x09\\x04,\" +\n\t\"\\x03\\x09\\x1f\\x16\\x03\\x09\\x11\\x03\\x03\\x09\\x11\\x12\\x03\\x09\\x168\\x03\\x08*\" +\n\t\"\\x05\\x03\\x08/2\\x03\\x084:\\x03\\x08\\x22+\\x03\\x08 0\\x03\\x08&\\x0a\\x03\\x08;\" +\n\t\"\\x10\\x03\\x08>$\\x03\\x08>\\x18\\x03\\x0829\\x03\\x082:\\x03\\x081,\\x03\\x081<\\x03\" +\n\t\"\\x081\\x1c\\x03\\x087#\\x03\\x087*\\x03\\x08\\x09'\\x03\\x08\\x00\\x1d\\x03\\x08\\x05-\" +\n\t\"\\x03\\x08\\x1f4\\x03\\x08\\x1d\\x04\\x03\\x08\\x16\\x0f\\x03\\x07*7\\x03\\x07'!\\x03\" +\n\t\"\\x07%\\x1b\\x03\\x077\\x0c\\x03\\x07\\x0c1\\x03\\x07\\x0c.\\x03\\x07\\x00\\x06\\x03\\x07\" +\n\t\"\\x01\\x02\\x03\\x07\\x010\\x03\\x07\\x06=\\x03\\x07\\x01\\x03\\x03\\x07\\x01\\x13\\x03\" +\n\t\"\\x07\\x06\\x06\\x03\\x07\\x05\\x0a\\x03\\x07\\x1f\\x09\\x03\\x07\\x17:\\x03\\x06*1\\x03\" +\n\t\"\\x06-\\x1d\\x03\\x06\\x223\\x03\\x062:\\x03\\x060$\\x03\\x066\\x1e\\x03\\x064\\x12\\x03\" +\n\t\"\\x0645\\x03\\x06\\x0b\\x00\\x03\\x06\\x0b7\\x03\\x06\\x07\\x1f\\x03\\x06\\x15\\x12\\x03\" +\n\t\"\\x0c\\x05\\x0f\\x03\\x0b+\\x0b\\x03\\x0b+-\\x03\\x06\\x16\\x1b\\x03\\x06\\x15\\x17\\x03\" +\n\t\"\\x89\\xca\\xea\\x03\\x89\\xca\\xe8\\x03\\x0c8\\x10\\x03\\x0c8\\x01\\x03\\x0c8\\x0f\\x03\" +\n\t\"\\x0d8%\\x03\\x0d8!\\x03\\x0c8-\\x03\\x0c8/\\x03\\x0c8+\\x03\\x0c87\\x03\\x0c85\\x03\" +\n\t\"\\x0c9\\x09\\x03\\x0c9\\x0d\\x03\\x0c9\\x0f\\x03\\x0c9\\x0b\\x03\\xcfu\\x0c\\x03\\xcfu\" +\n\t\"\\x0f\\x03\\xcfu\\x0e\\x03\\xcfu\\x09\\x03\\x0c9\\x10\\x03\\x0d9\\x0c\\x03\\xcf`;\\x03\" +\n\t\"\\xcf`>\\x03\\xcf`9\\x03\\xcf`8\\x03\\xcf`7\\x03\\xcf`*\\x03\\xcf`-\\x03\\xcf`,\\x03\" +\n\t\"\\x0d\\x1b\\x1a\\x03\\x0d\\x1b&\\x03\\x0c=.\\x03\\x0c=%\\x03\\x0c>\\x1e\\x03\\x0c>\\x14\" +\n\t\"\\x03\\x0c?\\x06\\x03\\x0c?\\x0b\\x03\\x0c?\\x0c\\x03\\x0c?\\x0d\\x03\\x0c?\\x02\\x03\" +\n\t\"\\x0c>\\x0f\\x03\\x0c>\\x08\\x03\\x0c>\\x09\\x03\\x0c>,\\x03\\x0c>\\x0c\\x03\\x0c?\\x13\" +\n\t\"\\x03\\x0c?\\x16\\x03\\x0c?\\x15\\x03\\x0c?\\x1c\\x03\\x0c?\\x1f\\x03\\x0c?\\x1d\\x03\" +\n\t\"\\x0c?\\x1a\\x03\\x0c?\\x17\\x03\\x0c?\\x08\\x03\\x0c?\\x09\\x03\\x0c?\\x0e\\x03\\x0c?\" +\n\t\"\\x04\\x03\\x0c?\\x05\\x03\\x0c<?\\x03\\x0c=\\x00\\x03\\x0c=\\x06\\x03\\x0c=\\x05\\x03\" +\n\t\"\\x0c=\\x0c\\x03\\x0c=\\x0f\\x03\\x0c=\\x0d\\x03\\x0c=\\x0b\\x03\\x0c=\\x07\\x03\\x0c=\" +\n\t\"\\x19\\x03\\x0c=\\x15\\x03\\x0c=\\x11\\x03\\x0c=1\\x03\\x0c=3\\x03\\x0c=0\\x03\\x0c=>\" +\n\t\"\\x03\\x0c=2\\x03\\x0c=6\\x03\\x0c<\\x07\\x03\\x0c<\\x05\\x03\\x0e:!\\x03\\x0e:#\\x03\" +\n\t\"\\x0e8\\x09\\x03\\x0e:&\\x03\\x0e8\\x0b\\x03\\x0e:$\\x03\\x0e:,\\x03\\x0e8\\x1a\\x03\" +\n\t\"\\x0e8\\x1e\\x03\\x0e:*\\x03\\x0e:7\\x03\\x0e:5\\x03\\x0e:;\\x03\\x0e:\\x15\\x03\\x0e:<\" +\n\t\"\\x03\\x0e:4\\x03\\x0e:'\\x03\\x0e:-\\x03\\x0e:%\\x03\\x0e:?\\x03\\x0e:=\\x03\\x0e:)\" +\n\t\"\\x03\\x0e:/\\x03\\xcfs'\\x03\\x0d=\\x0f\\x03\\x0d+*\\x03\\x0d99\\x03\\x0d9;\\x03\\x0d9\" +\n\t\"?\\x03\\x0d)\\x0d\\x03\\x0d(%\\x02\\x01\\x18\\x02\\x01(\\x02\\x01\\x1e\\x03\\x0f$!\\x03\" +\n\t\"\\x0f87\\x03\\x0f4\\x0e\\x03\\x0f5\\x1d\\x03\\x06'\\x03\\x03\\x0f\\x08\\x18\\x03\\x0f\" +\n\t\"\\x0d\\x1b\\x03\\x0e2=\\x03\\x0e;\\x08\\x03\\x0e:\\x0b\\x03\\x0e\\x06$\\x03\\x0e\\x0d)\" +\n\t\"\\x03\\x0e\\x16\\x1f\\x03\\x0e\\x16\\x1b\\x03\\x0d$\\x0a\\x03\\x05,\\x1d\\x03\\x0d. \\x03\" +\n\t\"\\x0d.#\\x03\\x0c(/\\x03\\x09%\\x02\\x03\\x0d90\\x03\\x0d\\x0e4\\x03\\x0d\\x0d\\x0f\\x03\" +\n\t\"\\x0c#\\x00\\x03\\x0c,\\x1e\\x03\\x0c2\\x0e\\x03\\x0c\\x01\\x17\\x03\\x0c\\x09:\\x03\\x0e\" +\n\t\"\\x173\\x03\\x0c\\x08\\x03\\x03\\x0c\\x11\\x07\\x03\\x0c\\x10\\x18\\x03\\x0c\\x1f\\x1c\" +\n\t\"\\x03\\x0c\\x19\\x0e\\x03\\x0c\\x1a\\x1f\\x03\\x0f0>\\x03\\x0b->\\x03\\x0b<+\\x03\\x0b8\" +\n\t\"\\x13\\x03\\x0b\\x043\\x03\\x0b\\x14\\x03\\x03\\x0b\\x16%\\x03\\x0d\\x22&\\x03\\x0b\\x1a\" +\n\t\"\\x1a\\x03\\x0b\\x1a\\x04\\x03\\x0a%9\\x03\\x0a&2\\x03\\x0a&0\\x03\\x0a!\\x1a\\x03\\x0a!\" +\n\t\"7\\x03\\x0a5\\x10\\x03\\x0a=4\\x03\\x0a?\\x0e\\x03\\x0a>\\x10\\x03\\x0a\\x00 \\x03\\x0a\" +\n\t\"\\x0f:\\x03\\x0a\\x0f9\\x03\\x0a\\x0b\\x0a\\x03\\x0a\\x17%\\x03\\x0a\\x1b-\\x03\\x09-\" +\n\t\"\\x1a\\x03\\x09,4\\x03\\x09.,\\x03\\x09)\\x09\\x03\\x096!\\x03\\x091\\x1f\\x03\\x093\" +\n\t\"\\x16\\x03\\x0c+\\x1f\\x03\\x098 \\x03\\x098=\\x03\\x0c(\\x1a\\x03\\x0c(\\x16\\x03\\x09\" +\n\t\"\\x0a+\\x03\\x09\\x16\\x12\\x03\\x09\\x13\\x0e\\x03\\x09\\x153\\x03\\x08)!\\x03\\x09\\x1a\" +\n\t\"\\x01\\x03\\x09\\x18\\x01\\x03\\x08%#\\x03\\x08>\\x22\\x03\\x08\\x05%\\x03\\x08\\x02*\" +\n\t\"\\x03\\x08\\x15;\\x03\\x08\\x1b7\\x03\\x0f\\x07\\x1d\\x03\\x0f\\x04\\x03\\x03\\x070\\x0c\" +\n\t\"\\x03\\x07;\\x0b\\x03\\x07\\x08\\x17\\x03\\x07\\x12\\x06\\x03\\x06/-\\x03\\x0671\\x03\" +\n\t\"\\x065+\\x03\\x06>7\\x03\\x06\\x049\\x03\\x05+\\x1e\\x03\\x05,\\x17\\x03\\x05 \\x1d\\x03\" +\n\t\"\\x05\\x22\\x05\\x03\\x050\\x1d\"\n\n// lookup returns the trie value for the first UTF-8 encoding in s and\n// the width in bytes of this encoding. The size will be 0 if s does not\n// hold enough bytes to complete the encoding. len(s) must be greater than 0.\nfunc (t *idnaTrie) lookup(s []byte) (v uint16, sz int) {\n\tc0 := s[0]\n\tswitch {\n\tcase c0 < 0x80: // is ASCII\n\t\treturn idnaValues[c0], 1\n\tcase c0 < 0xC2:\n\t\treturn 0, 1 // Illegal UTF-8: not a starter, not ASCII.\n\tcase c0 < 0xE0: // 2-byte UTF-8\n\t\tif len(s) < 2 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c1), 2\n\tcase c0 < 0xF0: // 3-byte UTF-8\n\t\tif len(s) < 3 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c2), 3\n\tcase c0 < 0xF8: // 4-byte UTF-8\n\t\tif len(s) < 4 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to = uint32(i)<<6 + uint32(c2)\n\t\ti = idnaIndex[o]\n\t\tc3 := s[3]\n\t\tif c3 < 0x80 || 0xC0 <= c3 {\n\t\t\treturn 0, 3 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c3), 4\n\t}\n\t// Illegal rune\n\treturn 0, 1\n}\n\n// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.\n// s must start with a full and valid UTF-8 encoded rune.\nfunc (t *idnaTrie) lookupUnsafe(s []byte) uint16 {\n\tc0 := s[0]\n\tif c0 < 0x80 { // is ASCII\n\t\treturn idnaValues[c0]\n\t}\n\ti := idnaIndex[c0]\n\tif c0 < 0xE0 { // 2-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[1])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[1])]\n\tif c0 < 0xF0 { // 3-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[2])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[2])]\n\tif c0 < 0xF8 { // 4-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[3])\n\t}\n\treturn 0\n}\n\n// lookupString returns the trie value for the first UTF-8 encoding in s and\n// the width in bytes of this encoding. The size will be 0 if s does not\n// hold enough bytes to complete the encoding. len(s) must be greater than 0.\nfunc (t *idnaTrie) lookupString(s string) (v uint16, sz int) {\n\tc0 := s[0]\n\tswitch {\n\tcase c0 < 0x80: // is ASCII\n\t\treturn idnaValues[c0], 1\n\tcase c0 < 0xC2:\n\t\treturn 0, 1 // Illegal UTF-8: not a starter, not ASCII.\n\tcase c0 < 0xE0: // 2-byte UTF-8\n\t\tif len(s) < 2 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c1), 2\n\tcase c0 < 0xF0: // 3-byte UTF-8\n\t\tif len(s) < 3 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c2), 3\n\tcase c0 < 0xF8: // 4-byte UTF-8\n\t\tif len(s) < 4 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to = uint32(i)<<6 + uint32(c2)\n\t\ti = idnaIndex[o]\n\t\tc3 := s[3]\n\t\tif c3 < 0x80 || 0xC0 <= c3 {\n\t\t\treturn 0, 3 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c3), 4\n\t}\n\t// Illegal rune\n\treturn 0, 1\n}\n\n// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.\n// s must start with a full and valid UTF-8 encoded rune.\nfunc (t *idnaTrie) lookupStringUnsafe(s string) uint16 {\n\tc0 := s[0]\n\tif c0 < 0x80 { // is ASCII\n\t\treturn idnaValues[c0]\n\t}\n\ti := idnaIndex[c0]\n\tif c0 < 0xE0 { // 2-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[1])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[1])]\n\tif c0 < 0xF0 { // 3-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[2])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[2])]\n\tif c0 < 0xF8 { // 4-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[3])\n\t}\n\treturn 0\n}\n\n// idnaTrie. Total size: 29404 bytes (28.71 KiB). Checksum: 848c45acb5f7991c.\ntype idnaTrie struct{}\n\nfunc newIdnaTrie(i int) *idnaTrie {\n\treturn &idnaTrie{}\n}\n\n// lookupValue determines the type of block n and looks up the value for b.\nfunc (t *idnaTrie) lookupValue(n uint32, b byte) uint16 {\n\tswitch {\n\tcase n < 125:\n\t\treturn uint16(idnaValues[n<<6+uint32(b)])\n\tdefault:\n\t\tn -= 125\n\t\treturn uint16(idnaSparse.lookup(n, b))\n\t}\n}\n\n// idnaValues: 127 blocks, 8128 entries, 16256 bytes\n// The third block is the zero block.\nvar idnaValues = [8128]uint16{\n\t// Block 0x0, offset 0x0\n\t0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080,\n\t0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080,\n\t0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080,\n\t0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080,\n\t0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080,\n\t0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080,\n\t0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080,\n\t0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080,\n\t0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008,\n\t0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080,\n\t0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080,\n\t// Block 0x1, offset 0x40\n\t0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105,\n\t0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105,\n\t0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105,\n\t0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105,\n\t0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080,\n\t0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008,\n\t0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008,\n\t0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008,\n\t0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008,\n\t0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080,\n\t0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080,\n\t// Block 0x2, offset 0x80\n\t// Block 0x3, offset 0xc0\n\t0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040,\n\t0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040,\n\t0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040,\n\t0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040,\n\t0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040,\n\t0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018,\n\t0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x001a, 0xe9: 0x0018,\n\t0xea: 0x0039, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x004a,\n\t0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0069, 0xf3: 0x0079, 0xf4: 0x008a, 0xf5: 0x0005,\n\t0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x00aa, 0xf9: 0x00c9, 0xfa: 0x00d9, 0xfb: 0x0018,\n\t0xfc: 0x00e9, 0xfd: 0x0119, 0xfe: 0x0149, 0xff: 0x0018,\n\t// Block 0x4, offset 0x100\n\t0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008,\n\t0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008,\n\t0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008,\n\t0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008,\n\t0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008,\n\t0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008,\n\t0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008,\n\t0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008,\n\t0x130: 0x0179, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008,\n\t0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d,\n\t0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0199,\n\t// Block 0x5, offset 0x140\n\t0x140: 0x0199, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d,\n\t0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x01b9, 0x14a: 0xe00d, 0x14b: 0x0008,\n\t0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008,\n\t0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008,\n\t0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008,\n\t0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008,\n\t0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008,\n\t0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008,\n\t0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008,\n\t0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d,\n\t0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x01d9,\n\t// Block 0x6, offset 0x180\n\t0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008,\n\t0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d,\n\t0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d,\n\t0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d,\n\t0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155,\n\t0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008,\n\t0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d,\n\t0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd,\n\t0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d,\n\t0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008,\n\t0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008,\n\t// Block 0x7, offset 0x1c0\n\t0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x01e9, 0x1c5: 0x01e9,\n\t0x1c6: 0x01e9, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d,\n\t0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d,\n\t0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d,\n\t0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008,\n\t0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008,\n\t0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008,\n\t0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008,\n\t0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008,\n\t0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008,\n\t0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008,\n\t// Block 0x8, offset 0x200\n\t0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008,\n\t0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008,\n\t0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008,\n\t0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008,\n\t0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008,\n\t0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008,\n\t0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008,\n\t0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008,\n\t0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008,\n\t0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0209, 0x23b: 0xe03d,\n\t0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x0229, 0x23f: 0x0008,\n\t// Block 0x9, offset 0x240\n\t0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018,\n\t0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008,\n\t0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008,\n\t0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018,\n\t0x258: 0x029a, 0x259: 0x02ba, 0x25a: 0x02da, 0x25b: 0x02fa, 0x25c: 0x031a, 0x25d: 0x033a,\n\t0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0359, 0x262: 0x01d9, 0x263: 0x0369,\n\t0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018,\n\t0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018,\n\t0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018,\n\t0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018,\n\t0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018,\n\t// Block 0xa, offset 0x280\n\t0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d,\n\t0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308,\n\t0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308,\n\t0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308,\n\t0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308,\n\t0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308,\n\t0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308,\n\t0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308,\n\t0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008,\n\t0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008,\n\t0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d,\n\t// Block 0xb, offset 0x2c0\n\t0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x008a, 0x2c5: 0x03d2,\n\t0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040,\n\t0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105,\n\t0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105,\n\t0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105,\n\t0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d,\n\t0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d,\n\t0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008,\n\t0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008,\n\t0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008,\n\t0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008,\n\t// Block 0xc, offset 0x300\n\t0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008,\n\t0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008,\n\t0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd,\n\t0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008,\n\t0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008,\n\t0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008,\n\t0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008,\n\t0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008,\n\t0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd,\n\t0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008,\n\t0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d,\n\t// Block 0xd, offset 0x340\n\t0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008,\n\t0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008,\n\t0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008,\n\t0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008,\n\t0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008,\n\t0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008,\n\t0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008,\n\t0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008,\n\t0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008,\n\t0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008,\n\t0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008,\n\t// Block 0xe, offset 0x380\n\t0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308,\n\t0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008,\n\t0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008,\n\t0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008,\n\t0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008,\n\t0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008,\n\t0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008,\n\t0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008,\n\t0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008,\n\t0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008,\n\t0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008,\n\t// Block 0xf, offset 0x3c0\n\t0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d,\n\t0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d,\n\t0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008,\n\t0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008,\n\t0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008,\n\t0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008,\n\t0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008,\n\t0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008,\n\t0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008,\n\t0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008,\n\t0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008,\n\t// Block 0x10, offset 0x400\n\t0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008,\n\t0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008,\n\t0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008,\n\t0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008,\n\t0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008,\n\t0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008,\n\t0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008,\n\t0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008,\n\t0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5,\n\t0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5,\n\t0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5,\n\t// Block 0x11, offset 0x440\n\t0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840,\n\t0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818,\n\t0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308,\n\t0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308,\n\t0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040,\n\t0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08,\n\t0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08,\n\t0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08,\n\t0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08,\n\t0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08,\n\t0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08,\n\t// Block 0x12, offset 0x480\n\t0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08,\n\t0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308,\n\t0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308,\n\t0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308,\n\t0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308,\n\t0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808,\n\t0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808,\n\t0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08,\n\t0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0429,\n\t0x4b6: 0x0451, 0x4b7: 0x0479, 0x4b8: 0x04a1, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08,\n\t0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08,\n\t// Block 0x13, offset 0x4c0\n\t0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08,\n\t0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08,\n\t0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08,\n\t0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308,\n\t0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840,\n\t0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308,\n\t0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018,\n\t0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08,\n\t0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008,\n\t0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08,\n\t0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08,\n\t// Block 0x14, offset 0x500\n\t0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818,\n\t0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818,\n\t0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308,\n\t0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08,\n\t0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08,\n\t0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08,\n\t0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08,\n\t0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08,\n\t0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308,\n\t0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308,\n\t0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308,\n\t// Block 0x15, offset 0x540\n\t0x540: 0x0c08, 0x541: 0x0a08, 0x542: 0x0a08, 0x543: 0x0a08, 0x544: 0x0a08, 0x545: 0x0a08,\n\t0x546: 0x0c08, 0x547: 0x0c08, 0x548: 0x0a08, 0x549: 0x0c08, 0x54a: 0x0a08, 0x54b: 0x0a08,\n\t0x54c: 0x0a08, 0x54d: 0x0a08, 0x54e: 0x0a08, 0x54f: 0x0a08, 0x550: 0x0a08, 0x551: 0x0a08,\n\t0x552: 0x0a08, 0x553: 0x0a08, 0x554: 0x0c08, 0x555: 0x0a08, 0x556: 0x0808, 0x557: 0x0808,\n\t0x558: 0x0808, 0x559: 0x3308, 0x55a: 0x3308, 0x55b: 0x3308, 0x55c: 0x0040, 0x55d: 0x0040,\n\t0x55e: 0x0818, 0x55f: 0x0040, 0x560: 0x0a08, 0x561: 0x0808, 0x562: 0x0a08, 0x563: 0x0a08,\n\t0x564: 0x0a08, 0x565: 0x0a08, 0x566: 0x0808, 0x567: 0x0c08, 0x568: 0x0a08, 0x569: 0x0c08,\n\t0x56a: 0x0c08, 0x56b: 0x0040, 0x56c: 0x0040, 0x56d: 0x0040, 0x56e: 0x0040, 0x56f: 0x0040,\n\t0x570: 0x0040, 0x571: 0x0040, 0x572: 0x0040, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040,\n\t0x576: 0x0040, 0x577: 0x0040, 0x578: 0x0040, 0x579: 0x0040, 0x57a: 0x0040, 0x57b: 0x0040,\n\t0x57c: 0x0040, 0x57d: 0x0040, 0x57e: 0x0040, 0x57f: 0x0040,\n\t// Block 0x16, offset 0x580\n\t0x580: 0x3008, 0x581: 0x3308, 0x582: 0x3308, 0x583: 0x3308, 0x584: 0x3308, 0x585: 0x3308,\n\t0x586: 0x3308, 0x587: 0x3308, 0x588: 0x3308, 0x589: 0x3008, 0x58a: 0x3008, 0x58b: 0x3008,\n\t0x58c: 0x3008, 0x58d: 0x3b08, 0x58e: 0x3008, 0x58f: 0x3008, 0x590: 0x0008, 0x591: 0x3308,\n\t0x592: 0x3308, 0x593: 0x3308, 0x594: 0x3308, 0x595: 0x3308, 0x596: 0x3308, 0x597: 0x3308,\n\t0x598: 0x04c9, 0x599: 0x0501, 0x59a: 0x0539, 0x59b: 0x0571, 0x59c: 0x05a9, 0x59d: 0x05e1,\n\t0x59e: 0x0619, 0x59f: 0x0651, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x3308, 0x5a3: 0x3308,\n\t0x5a4: 0x0018, 0x5a5: 0x0018, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008,\n\t0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008,\n\t0x5b0: 0x0018, 0x5b1: 0x0008, 0x5b2: 0x0008, 0x5b3: 0x0008, 0x5b4: 0x0008, 0x5b5: 0x0008,\n\t0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0008, 0x5bb: 0x0008,\n\t0x5bc: 0x0008, 0x5bd: 0x0008, 0x5be: 0x0008, 0x5bf: 0x0008,\n\t// Block 0x17, offset 0x5c0\n\t0x5c0: 0x0008, 0x5c1: 0x3308, 0x5c2: 0x3008, 0x5c3: 0x3008, 0x5c4: 0x0040, 0x5c5: 0x0008,\n\t0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0008,\n\t0x5cc: 0x0008, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040,\n\t0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008,\n\t0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008,\n\t0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008,\n\t0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040,\n\t0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008,\n\t0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0040, 0x5f4: 0x0040, 0x5f5: 0x0040,\n\t0x5f6: 0x0008, 0x5f7: 0x0008, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040,\n\t0x5fc: 0x3308, 0x5fd: 0x0008, 0x5fe: 0x3008, 0x5ff: 0x3008,\n\t// Block 0x18, offset 0x600\n\t0x600: 0x3008, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3308, 0x604: 0x3308, 0x605: 0x0040,\n\t0x606: 0x0040, 0x607: 0x3008, 0x608: 0x3008, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x3008,\n\t0x60c: 0x3008, 0x60d: 0x3b08, 0x60e: 0x0008, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x0040,\n\t0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x3008,\n\t0x618: 0x0040, 0x619: 0x0040, 0x61a: 0x0040, 0x61b: 0x0040, 0x61c: 0x0689, 0x61d: 0x06c1,\n\t0x61e: 0x0040, 0x61f: 0x06f9, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x3308, 0x623: 0x3308,\n\t0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008,\n\t0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008,\n\t0x630: 0x0008, 0x631: 0x0008, 0x632: 0x0018, 0x633: 0x0018, 0x634: 0x0018, 0x635: 0x0018,\n\t0x636: 0x0018, 0x637: 0x0018, 0x638: 0x0018, 0x639: 0x0018, 0x63a: 0x0018, 0x63b: 0x0018,\n\t0x63c: 0x0008, 0x63d: 0x0018, 0x63e: 0x3308, 0x63f: 0x0040,\n\t// Block 0x19, offset 0x640\n\t0x640: 0x0040, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x3008, 0x644: 0x0040, 0x645: 0x0008,\n\t0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0040,\n\t0x64c: 0x0040, 0x64d: 0x0040, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0040,\n\t0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008,\n\t0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008,\n\t0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008,\n\t0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040,\n\t0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008,\n\t0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0731, 0x674: 0x0040, 0x675: 0x0008,\n\t0x676: 0x0769, 0x677: 0x0040, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040,\n\t0x67c: 0x3308, 0x67d: 0x0040, 0x67e: 0x3008, 0x67f: 0x3008,\n\t// Block 0x1a, offset 0x680\n\t0x680: 0x3008, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x0040, 0x684: 0x0040, 0x685: 0x0040,\n\t0x686: 0x0040, 0x687: 0x3308, 0x688: 0x3308, 0x689: 0x0040, 0x68a: 0x0040, 0x68b: 0x3308,\n\t0x68c: 0x3308, 0x68d: 0x3b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0040, 0x691: 0x3308,\n\t0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040,\n\t0x698: 0x0040, 0x699: 0x07a1, 0x69a: 0x07d9, 0x69b: 0x0811, 0x69c: 0x0008, 0x69d: 0x0040,\n\t0x69e: 0x0849, 0x69f: 0x0040, 0x6a0: 0x0040, 0x6a1: 0x0040, 0x6a2: 0x0040, 0x6a3: 0x0040,\n\t0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008,\n\t0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008,\n\t0x6b0: 0x3308, 0x6b1: 0x3308, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0008, 0x6b5: 0x3308,\n\t0x6b6: 0x0018, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0040, 0x6ba: 0x0040, 0x6bb: 0x0040,\n\t0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040,\n\t// Block 0x1b, offset 0x6c0\n\t0x6c0: 0x0040, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3008, 0x6c4: 0x0040, 0x6c5: 0x0008,\n\t0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008,\n\t0x6cc: 0x0008, 0x6cd: 0x0008, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0008,\n\t0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008,\n\t0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008,\n\t0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008,\n\t0x6e4: 0x0008, 0x6e5: 0x0008, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0040,\n\t0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008,\n\t0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008,\n\t0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040,\n\t0x6fc: 0x3308, 0x6fd: 0x0008, 0x6fe: 0x3008, 0x6ff: 0x3008,\n\t// Block 0x1c, offset 0x700\n\t0x700: 0x3008, 0x701: 0x3308, 0x702: 0x3308, 0x703: 0x3308, 0x704: 0x3308, 0x705: 0x3308,\n\t0x706: 0x0040, 0x707: 0x3308, 0x708: 0x3308, 0x709: 0x3008, 0x70a: 0x0040, 0x70b: 0x3008,\n\t0x70c: 0x3008, 0x70d: 0x3b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0008, 0x711: 0x0040,\n\t0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x0040, 0x717: 0x0040,\n\t0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0040, 0x71d: 0x0040,\n\t0x71e: 0x0040, 0x71f: 0x0040, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x3308, 0x723: 0x3308,\n\t0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008,\n\t0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008,\n\t0x730: 0x0018, 0x731: 0x0018, 0x732: 0x0040, 0x733: 0x0040, 0x734: 0x0040, 0x735: 0x0040,\n\t0x736: 0x0040, 0x737: 0x0040, 0x738: 0x0040, 0x739: 0x0008, 0x73a: 0x3308, 0x73b: 0x3308,\n\t0x73c: 0x3308, 0x73d: 0x3308, 0x73e: 0x3308, 0x73f: 0x3308,\n\t// Block 0x1d, offset 0x740\n\t0x740: 0x0040, 0x741: 0x3308, 0x742: 0x3008, 0x743: 0x3008, 0x744: 0x0040, 0x745: 0x0008,\n\t0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0008,\n\t0x74c: 0x0008, 0x74d: 0x0040, 0x74e: 0x0040, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040,\n\t0x752: 0x0040, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0008, 0x757: 0x0008,\n\t0x758: 0x0008, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0008, 0x75c: 0x0008, 0x75d: 0x0008,\n\t0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x0008, 0x763: 0x0008,\n\t0x764: 0x0008, 0x765: 0x0008, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0040,\n\t0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008,\n\t0x770: 0x0008, 0x771: 0x0040, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0040, 0x775: 0x0008,\n\t0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040,\n\t0x77c: 0x3308, 0x77d: 0x0008, 0x77e: 0x3008, 0x77f: 0x3308,\n\t// Block 0x1e, offset 0x780\n\t0x780: 0x3008, 0x781: 0x3308, 0x782: 0x3308, 0x783: 0x3308, 0x784: 0x3308, 0x785: 0x0040,\n\t0x786: 0x0040, 0x787: 0x3008, 0x788: 0x3008, 0x789: 0x0040, 0x78a: 0x0040, 0x78b: 0x3008,\n\t0x78c: 0x3008, 0x78d: 0x3b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040,\n\t0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x0040, 0x796: 0x3308, 0x797: 0x3008,\n\t0x798: 0x0040, 0x799: 0x0040, 0x79a: 0x0040, 0x79b: 0x0040, 0x79c: 0x0881, 0x79d: 0x08b9,\n\t0x79e: 0x0040, 0x79f: 0x0008, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x3308, 0x7a3: 0x3308,\n\t0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008,\n\t0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008,\n\t0x7b0: 0x0018, 0x7b1: 0x0008, 0x7b2: 0x0018, 0x7b3: 0x0018, 0x7b4: 0x0018, 0x7b5: 0x0018,\n\t0x7b6: 0x0018, 0x7b7: 0x0018, 0x7b8: 0x0040, 0x7b9: 0x0040, 0x7ba: 0x0040, 0x7bb: 0x0040,\n\t0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x0040, 0x7bf: 0x0040,\n\t// Block 0x1f, offset 0x7c0\n\t0x7c0: 0x0040, 0x7c1: 0x0040, 0x7c2: 0x3308, 0x7c3: 0x0008, 0x7c4: 0x0040, 0x7c5: 0x0008,\n\t0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0040,\n\t0x7cc: 0x0040, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040,\n\t0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0040, 0x7d7: 0x0040,\n\t0x7d8: 0x0040, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0008, 0x7dd: 0x0040,\n\t0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0040, 0x7e1: 0x0040, 0x7e2: 0x0040, 0x7e3: 0x0008,\n\t0x7e4: 0x0008, 0x7e5: 0x0040, 0x7e6: 0x0040, 0x7e7: 0x0040, 0x7e8: 0x0008, 0x7e9: 0x0008,\n\t0x7ea: 0x0008, 0x7eb: 0x0040, 0x7ec: 0x0040, 0x7ed: 0x0040, 0x7ee: 0x0008, 0x7ef: 0x0008,\n\t0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0008, 0x7f5: 0x0008,\n\t0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040,\n\t0x7fc: 0x0040, 0x7fd: 0x0040, 0x7fe: 0x3008, 0x7ff: 0x3008,\n\t// Block 0x20, offset 0x800\n\t0x800: 0x3308, 0x801: 0x3008, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x3008, 0x805: 0x0040,\n\t0x806: 0x3308, 0x807: 0x3308, 0x808: 0x3308, 0x809: 0x0040, 0x80a: 0x3308, 0x80b: 0x3308,\n\t0x80c: 0x3308, 0x80d: 0x3b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040,\n\t0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x3308, 0x816: 0x3308, 0x817: 0x0040,\n\t0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040,\n\t0x81e: 0x0040, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x3308, 0x823: 0x3308,\n\t0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008,\n\t0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008,\n\t0x830: 0x0040, 0x831: 0x0040, 0x832: 0x0040, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040,\n\t0x836: 0x0040, 0x837: 0x0040, 0x838: 0x0018, 0x839: 0x0018, 0x83a: 0x0018, 0x83b: 0x0018,\n\t0x83c: 0x0018, 0x83d: 0x0018, 0x83e: 0x0018, 0x83f: 0x0018,\n\t// Block 0x21, offset 0x840\n\t0x840: 0x0008, 0x841: 0x3308, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x0018, 0x845: 0x0008,\n\t0x846: 0x0008, 0x847: 0x0008, 0x848: 0x0008, 0x849: 0x0008, 0x84a: 0x0008, 0x84b: 0x0008,\n\t0x84c: 0x0008, 0x84d: 0x0040, 0x84e: 0x0008, 0x84f: 0x0008, 0x850: 0x0008, 0x851: 0x0040,\n\t0x852: 0x0008, 0x853: 0x0008, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x0008,\n\t0x858: 0x0008, 0x859: 0x0008, 0x85a: 0x0008, 0x85b: 0x0008, 0x85c: 0x0008, 0x85d: 0x0008,\n\t0x85e: 0x0008, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x0008, 0x863: 0x0008,\n\t0x864: 0x0008, 0x865: 0x0008, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0040,\n\t0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008,\n\t0x870: 0x0008, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0008, 0x874: 0x0040, 0x875: 0x0008,\n\t0x876: 0x0008, 0x877: 0x0008, 0x878: 0x0008, 0x879: 0x0008, 0x87a: 0x0040, 0x87b: 0x0040,\n\t0x87c: 0x3308, 0x87d: 0x0008, 0x87e: 0x3008, 0x87f: 0x3308,\n\t// Block 0x22, offset 0x880\n\t0x880: 0x3008, 0x881: 0x3008, 0x882: 0x3008, 0x883: 0x3008, 0x884: 0x3008, 0x885: 0x0040,\n\t0x886: 0x3308, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008,\n\t0x88c: 0x3308, 0x88d: 0x3b08, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040,\n\t0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0040, 0x895: 0x3008, 0x896: 0x3008, 0x897: 0x0040,\n\t0x898: 0x0040, 0x899: 0x0040, 0x89a: 0x0040, 0x89b: 0x0040, 0x89c: 0x0040, 0x89d: 0x0040,\n\t0x89e: 0x0008, 0x89f: 0x0040, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308,\n\t0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008,\n\t0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008,\n\t0x8b0: 0x0040, 0x8b1: 0x0008, 0x8b2: 0x0008, 0x8b3: 0x0040, 0x8b4: 0x0040, 0x8b5: 0x0040,\n\t0x8b6: 0x0040, 0x8b7: 0x0040, 0x8b8: 0x0040, 0x8b9: 0x0040, 0x8ba: 0x0040, 0x8bb: 0x0040,\n\t0x8bc: 0x0040, 0x8bd: 0x0040, 0x8be: 0x0040, 0x8bf: 0x0040,\n\t// Block 0x23, offset 0x8c0\n\t0x8c0: 0x3008, 0x8c1: 0x3308, 0x8c2: 0x3308, 0x8c3: 0x3308, 0x8c4: 0x3308, 0x8c5: 0x0040,\n\t0x8c6: 0x3008, 0x8c7: 0x3008, 0x8c8: 0x3008, 0x8c9: 0x0040, 0x8ca: 0x3008, 0x8cb: 0x3008,\n\t0x8cc: 0x3008, 0x8cd: 0x3b08, 0x8ce: 0x0008, 0x8cf: 0x0018, 0x8d0: 0x0040, 0x8d1: 0x0040,\n\t0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x3008,\n\t0x8d8: 0x0018, 0x8d9: 0x0018, 0x8da: 0x0018, 0x8db: 0x0018, 0x8dc: 0x0018, 0x8dd: 0x0018,\n\t0x8de: 0x0018, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x3308, 0x8e3: 0x3308,\n\t0x8e4: 0x0040, 0x8e5: 0x0040, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0008,\n\t0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008,\n\t0x8f0: 0x0018, 0x8f1: 0x0018, 0x8f2: 0x0018, 0x8f3: 0x0018, 0x8f4: 0x0018, 0x8f5: 0x0018,\n\t0x8f6: 0x0018, 0x8f7: 0x0018, 0x8f8: 0x0018, 0x8f9: 0x0018, 0x8fa: 0x0008, 0x8fb: 0x0008,\n\t0x8fc: 0x0008, 0x8fd: 0x0008, 0x8fe: 0x0008, 0x8ff: 0x0008,\n\t// Block 0x24, offset 0x900\n\t0x900: 0x0040, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x0040, 0x904: 0x0008, 0x905: 0x0040,\n\t0x906: 0x0040, 0x907: 0x0008, 0x908: 0x0008, 0x909: 0x0040, 0x90a: 0x0008, 0x90b: 0x0040,\n\t0x90c: 0x0040, 0x90d: 0x0008, 0x90e: 0x0040, 0x90f: 0x0040, 0x910: 0x0040, 0x911: 0x0040,\n\t0x912: 0x0040, 0x913: 0x0040, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0008,\n\t0x918: 0x0040, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0008, 0x91d: 0x0008,\n\t0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0040, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008,\n\t0x924: 0x0040, 0x925: 0x0008, 0x926: 0x0040, 0x927: 0x0008, 0x928: 0x0040, 0x929: 0x0040,\n\t0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0040, 0x92d: 0x0008, 0x92e: 0x0008, 0x92f: 0x0008,\n\t0x930: 0x0008, 0x931: 0x3308, 0x932: 0x0008, 0x933: 0x0929, 0x934: 0x3308, 0x935: 0x3308,\n\t0x936: 0x3308, 0x937: 0x3308, 0x938: 0x3308, 0x939: 0x3308, 0x93a: 0x0040, 0x93b: 0x3308,\n\t0x93c: 0x3308, 0x93d: 0x0008, 0x93e: 0x0040, 0x93f: 0x0040,\n\t// Block 0x25, offset 0x940\n\t0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x09d1, 0x944: 0x0008, 0x945: 0x0008,\n\t0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0040, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008,\n\t0x94c: 0x0008, 0x94d: 0x0a09, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008,\n\t0x952: 0x0a41, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0a79,\n\t0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0ab1, 0x95d: 0x0008,\n\t0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008,\n\t0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0ae9,\n\t0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0008, 0x96d: 0x0040, 0x96e: 0x0040, 0x96f: 0x0040,\n\t0x970: 0x0040, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x0b21, 0x974: 0x3308, 0x975: 0x0b59,\n\t0x976: 0x0b91, 0x977: 0x0bc9, 0x978: 0x0c19, 0x979: 0x0c51, 0x97a: 0x3308, 0x97b: 0x3308,\n\t0x97c: 0x3308, 0x97d: 0x3308, 0x97e: 0x3308, 0x97f: 0x3008,\n\t// Block 0x26, offset 0x980\n\t0x980: 0x3308, 0x981: 0x0ca1, 0x982: 0x3308, 0x983: 0x3308, 0x984: 0x3b08, 0x985: 0x0018,\n\t0x986: 0x3308, 0x987: 0x3308, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008,\n\t0x98c: 0x0008, 0x98d: 0x3308, 0x98e: 0x3308, 0x98f: 0x3308, 0x990: 0x3308, 0x991: 0x3308,\n\t0x992: 0x3308, 0x993: 0x0cd9, 0x994: 0x3308, 0x995: 0x3308, 0x996: 0x3308, 0x997: 0x3308,\n\t0x998: 0x0040, 0x999: 0x3308, 0x99a: 0x3308, 0x99b: 0x3308, 0x99c: 0x3308, 0x99d: 0x0d11,\n\t0x99e: 0x3308, 0x99f: 0x3308, 0x9a0: 0x3308, 0x9a1: 0x3308, 0x9a2: 0x0d49, 0x9a3: 0x3308,\n\t0x9a4: 0x3308, 0x9a5: 0x3308, 0x9a6: 0x3308, 0x9a7: 0x0d81, 0x9a8: 0x3308, 0x9a9: 0x3308,\n\t0x9aa: 0x3308, 0x9ab: 0x3308, 0x9ac: 0x0db9, 0x9ad: 0x3308, 0x9ae: 0x3308, 0x9af: 0x3308,\n\t0x9b0: 0x3308, 0x9b1: 0x3308, 0x9b2: 0x3308, 0x9b3: 0x3308, 0x9b4: 0x3308, 0x9b5: 0x3308,\n\t0x9b6: 0x3308, 0x9b7: 0x3308, 0x9b8: 0x3308, 0x9b9: 0x0df1, 0x9ba: 0x3308, 0x9bb: 0x3308,\n\t0x9bc: 0x3308, 0x9bd: 0x0040, 0x9be: 0x0018, 0x9bf: 0x0018,\n\t// Block 0x27, offset 0x9c0\n\t0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008,\n\t0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008,\n\t0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008,\n\t0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008,\n\t0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x0008, 0x9dc: 0x0008, 0x9dd: 0x0008,\n\t0x9de: 0x0008, 0x9df: 0x0008, 0x9e0: 0x0008, 0x9e1: 0x0008, 0x9e2: 0x0008, 0x9e3: 0x0008,\n\t0x9e4: 0x0008, 0x9e5: 0x0008, 0x9e6: 0x0008, 0x9e7: 0x0008, 0x9e8: 0x0008, 0x9e9: 0x0008,\n\t0x9ea: 0x0008, 0x9eb: 0x0008, 0x9ec: 0x0039, 0x9ed: 0x0ed1, 0x9ee: 0x0ee9, 0x9ef: 0x0008,\n\t0x9f0: 0x0ef9, 0x9f1: 0x0f09, 0x9f2: 0x0f19, 0x9f3: 0x0f31, 0x9f4: 0x0249, 0x9f5: 0x0f41,\n\t0x9f6: 0x0259, 0x9f7: 0x0f51, 0x9f8: 0x0359, 0x9f9: 0x0f61, 0x9fa: 0x0f71, 0x9fb: 0x0008,\n\t0x9fc: 0x00d9, 0x9fd: 0x0f81, 0x9fe: 0x0f99, 0x9ff: 0x0269,\n\t// Block 0x28, offset 0xa00\n\t0xa00: 0x0fa9, 0xa01: 0x0fb9, 0xa02: 0x0279, 0xa03: 0x0039, 0xa04: 0x0fc9, 0xa05: 0x0fe1,\n\t0xa06: 0x059d, 0xa07: 0x0ee9, 0xa08: 0x0ef9, 0xa09: 0x0f09, 0xa0a: 0x0ff9, 0xa0b: 0x1011,\n\t0xa0c: 0x1029, 0xa0d: 0x0f31, 0xa0e: 0x0008, 0xa0f: 0x0f51, 0xa10: 0x0f61, 0xa11: 0x1041,\n\t0xa12: 0x00d9, 0xa13: 0x1059, 0xa14: 0x05b5, 0xa15: 0x05b5, 0xa16: 0x0f99, 0xa17: 0x0fa9,\n\t0xa18: 0x0fb9, 0xa19: 0x059d, 0xa1a: 0x1071, 0xa1b: 0x1089, 0xa1c: 0x05cd, 0xa1d: 0x1099,\n\t0xa1e: 0x10b1, 0xa1f: 0x10c9, 0xa20: 0x10e1, 0xa21: 0x10f9, 0xa22: 0x0f41, 0xa23: 0x0269,\n\t0xa24: 0x0fb9, 0xa25: 0x1089, 0xa26: 0x1099, 0xa27: 0x10b1, 0xa28: 0x1111, 0xa29: 0x10e1,\n\t0xa2a: 0x10f9, 0xa2b: 0x0008, 0xa2c: 0x0008, 0xa2d: 0x0008, 0xa2e: 0x0008, 0xa2f: 0x0008,\n\t0xa30: 0x0008, 0xa31: 0x0008, 0xa32: 0x0008, 0xa33: 0x0008, 0xa34: 0x0008, 0xa35: 0x0008,\n\t0xa36: 0x0008, 0xa37: 0x0008, 0xa38: 0x1129, 0xa39: 0x0008, 0xa3a: 0x0008, 0xa3b: 0x0008,\n\t0xa3c: 0x0008, 0xa3d: 0x0008, 0xa3e: 0x0008, 0xa3f: 0x0008,\n\t// Block 0x29, offset 0xa40\n\t0xa40: 0x0008, 0xa41: 0x0008, 0xa42: 0x0008, 0xa43: 0x0008, 0xa44: 0x0008, 0xa45: 0x0008,\n\t0xa46: 0x0008, 0xa47: 0x0008, 0xa48: 0x0008, 0xa49: 0x0008, 0xa4a: 0x0008, 0xa4b: 0x0008,\n\t0xa4c: 0x0008, 0xa4d: 0x0008, 0xa4e: 0x0008, 0xa4f: 0x0008, 0xa50: 0x0008, 0xa51: 0x0008,\n\t0xa52: 0x0008, 0xa53: 0x0008, 0xa54: 0x0008, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008,\n\t0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0008, 0xa5b: 0x1141, 0xa5c: 0x1159, 0xa5d: 0x1169,\n\t0xa5e: 0x1181, 0xa5f: 0x1029, 0xa60: 0x1199, 0xa61: 0x11a9, 0xa62: 0x11c1, 0xa63: 0x11d9,\n\t0xa64: 0x11f1, 0xa65: 0x1209, 0xa66: 0x1221, 0xa67: 0x05e5, 0xa68: 0x1239, 0xa69: 0x1251,\n\t0xa6a: 0xe17d, 0xa6b: 0x1269, 0xa6c: 0x1281, 0xa6d: 0x1299, 0xa6e: 0x12b1, 0xa6f: 0x12c9,\n\t0xa70: 0x12e1, 0xa71: 0x12f9, 0xa72: 0x1311, 0xa73: 0x1329, 0xa74: 0x1341, 0xa75: 0x1359,\n\t0xa76: 0x1371, 0xa77: 0x1389, 0xa78: 0x05fd, 0xa79: 0x13a1, 0xa7a: 0x13b9, 0xa7b: 0x13d1,\n\t0xa7c: 0x13e1, 0xa7d: 0x13f9, 0xa7e: 0x1411, 0xa7f: 0x1429,\n\t// Block 0x2a, offset 0xa80\n\t0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008,\n\t0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008,\n\t0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008,\n\t0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0xe00d, 0xa97: 0x0008,\n\t0xa98: 0xe00d, 0xa99: 0x0008, 0xa9a: 0xe00d, 0xa9b: 0x0008, 0xa9c: 0xe00d, 0xa9d: 0x0008,\n\t0xa9e: 0xe00d, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008,\n\t0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008,\n\t0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008,\n\t0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008,\n\t0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008,\n\t0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008,\n\t// Block 0x2b, offset 0xac0\n\t0xac0: 0xe00d, 0xac1: 0x0008, 0xac2: 0xe00d, 0xac3: 0x0008, 0xac4: 0xe00d, 0xac5: 0x0008,\n\t0xac6: 0xe00d, 0xac7: 0x0008, 0xac8: 0xe00d, 0xac9: 0x0008, 0xaca: 0xe00d, 0xacb: 0x0008,\n\t0xacc: 0xe00d, 0xacd: 0x0008, 0xace: 0xe00d, 0xacf: 0x0008, 0xad0: 0xe00d, 0xad1: 0x0008,\n\t0xad2: 0xe00d, 0xad3: 0x0008, 0xad4: 0xe00d, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008,\n\t0xad8: 0x0008, 0xad9: 0x0008, 0xada: 0x0615, 0xadb: 0x0635, 0xadc: 0x0008, 0xadd: 0x0008,\n\t0xade: 0x1441, 0xadf: 0x0008, 0xae0: 0xe00d, 0xae1: 0x0008, 0xae2: 0xe00d, 0xae3: 0x0008,\n\t0xae4: 0xe00d, 0xae5: 0x0008, 0xae6: 0xe00d, 0xae7: 0x0008, 0xae8: 0xe00d, 0xae9: 0x0008,\n\t0xaea: 0xe00d, 0xaeb: 0x0008, 0xaec: 0xe00d, 0xaed: 0x0008, 0xaee: 0xe00d, 0xaef: 0x0008,\n\t0xaf0: 0xe00d, 0xaf1: 0x0008, 0xaf2: 0xe00d, 0xaf3: 0x0008, 0xaf4: 0xe00d, 0xaf5: 0x0008,\n\t0xaf6: 0xe00d, 0xaf7: 0x0008, 0xaf8: 0xe00d, 0xaf9: 0x0008, 0xafa: 0xe00d, 0xafb: 0x0008,\n\t0xafc: 0xe00d, 0xafd: 0x0008, 0xafe: 0xe00d, 0xaff: 0x0008,\n\t// Block 0x2c, offset 0xb00\n\t0xb00: 0x0008, 0xb01: 0x0008, 0xb02: 0x0008, 0xb03: 0x0008, 0xb04: 0x0008, 0xb05: 0x0008,\n\t0xb06: 0x0040, 0xb07: 0x0040, 0xb08: 0xe045, 0xb09: 0xe045, 0xb0a: 0xe045, 0xb0b: 0xe045,\n\t0xb0c: 0xe045, 0xb0d: 0xe045, 0xb0e: 0x0040, 0xb0f: 0x0040, 0xb10: 0x0008, 0xb11: 0x0008,\n\t0xb12: 0x0008, 0xb13: 0x0008, 0xb14: 0x0008, 0xb15: 0x0008, 0xb16: 0x0008, 0xb17: 0x0008,\n\t0xb18: 0x0040, 0xb19: 0xe045, 0xb1a: 0x0040, 0xb1b: 0xe045, 0xb1c: 0x0040, 0xb1d: 0xe045,\n\t0xb1e: 0x0040, 0xb1f: 0xe045, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x0008,\n\t0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045,\n\t0xb2a: 0xe045, 0xb2b: 0xe045, 0xb2c: 0xe045, 0xb2d: 0xe045, 0xb2e: 0xe045, 0xb2f: 0xe045,\n\t0xb30: 0x0008, 0xb31: 0x1459, 0xb32: 0x0008, 0xb33: 0x1471, 0xb34: 0x0008, 0xb35: 0x1489,\n\t0xb36: 0x0008, 0xb37: 0x14a1, 0xb38: 0x0008, 0xb39: 0x14b9, 0xb3a: 0x0008, 0xb3b: 0x14d1,\n\t0xb3c: 0x0008, 0xb3d: 0x14e9, 0xb3e: 0x0040, 0xb3f: 0x0040,\n\t// Block 0x2d, offset 0xb40\n\t0xb40: 0x1501, 0xb41: 0x1531, 0xb42: 0x1561, 0xb43: 0x1591, 0xb44: 0x15c1, 0xb45: 0x15f1,\n\t0xb46: 0x1621, 0xb47: 0x1651, 0xb48: 0x1501, 0xb49: 0x1531, 0xb4a: 0x1561, 0xb4b: 0x1591,\n\t0xb4c: 0x15c1, 0xb4d: 0x15f1, 0xb4e: 0x1621, 0xb4f: 0x1651, 0xb50: 0x1681, 0xb51: 0x16b1,\n\t0xb52: 0x16e1, 0xb53: 0x1711, 0xb54: 0x1741, 0xb55: 0x1771, 0xb56: 0x17a1, 0xb57: 0x17d1,\n\t0xb58: 0x1681, 0xb59: 0x16b1, 0xb5a: 0x16e1, 0xb5b: 0x1711, 0xb5c: 0x1741, 0xb5d: 0x1771,\n\t0xb5e: 0x17a1, 0xb5f: 0x17d1, 0xb60: 0x1801, 0xb61: 0x1831, 0xb62: 0x1861, 0xb63: 0x1891,\n\t0xb64: 0x18c1, 0xb65: 0x18f1, 0xb66: 0x1921, 0xb67: 0x1951, 0xb68: 0x1801, 0xb69: 0x1831,\n\t0xb6a: 0x1861, 0xb6b: 0x1891, 0xb6c: 0x18c1, 0xb6d: 0x18f1, 0xb6e: 0x1921, 0xb6f: 0x1951,\n\t0xb70: 0x0008, 0xb71: 0x0008, 0xb72: 0x1981, 0xb73: 0x19b1, 0xb74: 0x19d9, 0xb75: 0x0040,\n\t0xb76: 0x0008, 0xb77: 0x1a01, 0xb78: 0xe045, 0xb79: 0xe045, 0xb7a: 0x064d, 0xb7b: 0x1459,\n\t0xb7c: 0x19b1, 0xb7d: 0x0666, 0xb7e: 0x1a31, 0xb7f: 0x0686,\n\t// Block 0x2e, offset 0xb80\n\t0xb80: 0x06a6, 0xb81: 0x1a4a, 0xb82: 0x1a79, 0xb83: 0x1aa9, 0xb84: 0x1ad1, 0xb85: 0x0040,\n\t0xb86: 0x0008, 0xb87: 0x1af9, 0xb88: 0x06c5, 0xb89: 0x1471, 0xb8a: 0x06dd, 0xb8b: 0x1489,\n\t0xb8c: 0x1aa9, 0xb8d: 0x1b2a, 0xb8e: 0x1b5a, 0xb8f: 0x1b8a, 0xb90: 0x0008, 0xb91: 0x0008,\n\t0xb92: 0x0008, 0xb93: 0x1bb9, 0xb94: 0x0040, 0xb95: 0x0040, 0xb96: 0x0008, 0xb97: 0x0008,\n\t0xb98: 0xe045, 0xb99: 0xe045, 0xb9a: 0x06f5, 0xb9b: 0x14a1, 0xb9c: 0x0040, 0xb9d: 0x1bd2,\n\t0xb9e: 0x1c02, 0xb9f: 0x1c32, 0xba0: 0x0008, 0xba1: 0x0008, 0xba2: 0x0008, 0xba3: 0x1c61,\n\t0xba4: 0x0008, 0xba5: 0x0008, 0xba6: 0x0008, 0xba7: 0x0008, 0xba8: 0xe045, 0xba9: 0xe045,\n\t0xbaa: 0x070d, 0xbab: 0x14d1, 0xbac: 0xe04d, 0xbad: 0x1c7a, 0xbae: 0x03d2, 0xbaf: 0x1caa,\n\t0xbb0: 0x0040, 0xbb1: 0x0040, 0xbb2: 0x1cb9, 0xbb3: 0x1ce9, 0xbb4: 0x1d11, 0xbb5: 0x0040,\n\t0xbb6: 0x0008, 0xbb7: 0x1d39, 0xbb8: 0x0725, 0xbb9: 0x14b9, 0xbba: 0x0515, 0xbbb: 0x14e9,\n\t0xbbc: 0x1ce9, 0xbbd: 0x073e, 0xbbe: 0x075e, 0xbbf: 0x0040,\n\t// Block 0x2f, offset 0xbc0\n\t0xbc0: 0x000a, 0xbc1: 0x000a, 0xbc2: 0x000a, 0xbc3: 0x000a, 0xbc4: 0x000a, 0xbc5: 0x000a,\n\t0xbc6: 0x000a, 0xbc7: 0x000a, 0xbc8: 0x000a, 0xbc9: 0x000a, 0xbca: 0x000a, 0xbcb: 0x03c0,\n\t0xbcc: 0x0003, 0xbcd: 0x0003, 0xbce: 0x0340, 0xbcf: 0x0b40, 0xbd0: 0x0018, 0xbd1: 0xe00d,\n\t0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x077e,\n\t0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018,\n\t0xbde: 0x0018, 0xbdf: 0x0018, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018,\n\t0xbe4: 0x0040, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0018, 0xbe8: 0x0040, 0xbe9: 0x0040,\n\t0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x000a,\n\t0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x1d69, 0xbf4: 0x1da1, 0xbf5: 0x0018,\n\t0xbf6: 0x1df1, 0xbf7: 0x1e29, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018,\n\t0xbfc: 0x1e7a, 0xbfd: 0x0018, 0xbfe: 0x079e, 0xbff: 0x0018,\n\t// Block 0x30, offset 0xc00\n\t0xc00: 0x0018, 0xc01: 0x0018, 0xc02: 0x0018, 0xc03: 0x0018, 0xc04: 0x0018, 0xc05: 0x0018,\n\t0xc06: 0x0018, 0xc07: 0x1e92, 0xc08: 0x1eaa, 0xc09: 0x1ec2, 0xc0a: 0x0018, 0xc0b: 0x0018,\n\t0xc0c: 0x0018, 0xc0d: 0x0018, 0xc0e: 0x0018, 0xc0f: 0x0018, 0xc10: 0x0018, 0xc11: 0x0018,\n\t0xc12: 0x0018, 0xc13: 0x0018, 0xc14: 0x0018, 0xc15: 0x0018, 0xc16: 0x0018, 0xc17: 0x1ed9,\n\t0xc18: 0x0018, 0xc19: 0x0018, 0xc1a: 0x0018, 0xc1b: 0x0018, 0xc1c: 0x0018, 0xc1d: 0x0018,\n\t0xc1e: 0x0018, 0xc1f: 0x000a, 0xc20: 0x03c0, 0xc21: 0x0340, 0xc22: 0x0340, 0xc23: 0x0340,\n\t0xc24: 0x03c0, 0xc25: 0x0040, 0xc26: 0x0040, 0xc27: 0x0040, 0xc28: 0x0040, 0xc29: 0x0040,\n\t0xc2a: 0x0340, 0xc2b: 0x0340, 0xc2c: 0x0340, 0xc2d: 0x0340, 0xc2e: 0x0340, 0xc2f: 0x0340,\n\t0xc30: 0x1f41, 0xc31: 0x0f41, 0xc32: 0x0040, 0xc33: 0x0040, 0xc34: 0x1f51, 0xc35: 0x1f61,\n\t0xc36: 0x1f71, 0xc37: 0x1f81, 0xc38: 0x1f91, 0xc39: 0x1fa1, 0xc3a: 0x1fb2, 0xc3b: 0x07bd,\n\t0xc3c: 0x1fc2, 0xc3d: 0x1fd2, 0xc3e: 0x1fe2, 0xc3f: 0x0f71,\n\t// Block 0x31, offset 0xc40\n\t0xc40: 0x1f41, 0xc41: 0x00c9, 0xc42: 0x0069, 0xc43: 0x0079, 0xc44: 0x1f51, 0xc45: 0x1f61,\n\t0xc46: 0x1f71, 0xc47: 0x1f81, 0xc48: 0x1f91, 0xc49: 0x1fa1, 0xc4a: 0x1fb2, 0xc4b: 0x07d5,\n\t0xc4c: 0x1fc2, 0xc4d: 0x1fd2, 0xc4e: 0x1fe2, 0xc4f: 0x0040, 0xc50: 0x0039, 0xc51: 0x0f09,\n\t0xc52: 0x00d9, 0xc53: 0x0369, 0xc54: 0x0ff9, 0xc55: 0x0249, 0xc56: 0x0f51, 0xc57: 0x0359,\n\t0xc58: 0x0f61, 0xc59: 0x0f71, 0xc5a: 0x0f99, 0xc5b: 0x01d9, 0xc5c: 0x0fa9, 0xc5d: 0x0040,\n\t0xc5e: 0x0040, 0xc5f: 0x0040, 0xc60: 0x0018, 0xc61: 0x0018, 0xc62: 0x0018, 0xc63: 0x0018,\n\t0xc64: 0x0018, 0xc65: 0x0018, 0xc66: 0x0018, 0xc67: 0x0018, 0xc68: 0x1ff1, 0xc69: 0x0018,\n\t0xc6a: 0x0018, 0xc6b: 0x0018, 0xc6c: 0x0018, 0xc6d: 0x0018, 0xc6e: 0x0018, 0xc6f: 0x0018,\n\t0xc70: 0x0018, 0xc71: 0x0018, 0xc72: 0x0018, 0xc73: 0x0018, 0xc74: 0x0018, 0xc75: 0x0018,\n\t0xc76: 0x0018, 0xc77: 0x0018, 0xc78: 0x0018, 0xc79: 0x0018, 0xc7a: 0x0018, 0xc7b: 0x0018,\n\t0xc7c: 0x0018, 0xc7d: 0x0018, 0xc7e: 0x0018, 0xc7f: 0x0018,\n\t// Block 0x32, offset 0xc80\n\t0xc80: 0x07ee, 0xc81: 0x080e, 0xc82: 0x1159, 0xc83: 0x082d, 0xc84: 0x0018, 0xc85: 0x084e,\n\t0xc86: 0x086e, 0xc87: 0x1011, 0xc88: 0x0018, 0xc89: 0x088d, 0xc8a: 0x0f31, 0xc8b: 0x0249,\n\t0xc8c: 0x0249, 0xc8d: 0x0249, 0xc8e: 0x0249, 0xc8f: 0x2009, 0xc90: 0x0f41, 0xc91: 0x0f41,\n\t0xc92: 0x0359, 0xc93: 0x0359, 0xc94: 0x0018, 0xc95: 0x0f71, 0xc96: 0x2021, 0xc97: 0x0018,\n\t0xc98: 0x0018, 0xc99: 0x0f99, 0xc9a: 0x2039, 0xc9b: 0x0269, 0xc9c: 0x0269, 0xc9d: 0x0269,\n\t0xc9e: 0x0018, 0xc9f: 0x0018, 0xca0: 0x2049, 0xca1: 0x08ad, 0xca2: 0x2061, 0xca3: 0x0018,\n\t0xca4: 0x13d1, 0xca5: 0x0018, 0xca6: 0x2079, 0xca7: 0x0018, 0xca8: 0x13d1, 0xca9: 0x0018,\n\t0xcaa: 0x0f51, 0xcab: 0x2091, 0xcac: 0x0ee9, 0xcad: 0x1159, 0xcae: 0x0018, 0xcaf: 0x0f09,\n\t0xcb0: 0x0f09, 0xcb1: 0x1199, 0xcb2: 0x0040, 0xcb3: 0x0f61, 0xcb4: 0x00d9, 0xcb5: 0x20a9,\n\t0xcb6: 0x20c1, 0xcb7: 0x20d9, 0xcb8: 0x20f1, 0xcb9: 0x0f41, 0xcba: 0x0018, 0xcbb: 0x08cd,\n\t0xcbc: 0x2109, 0xcbd: 0x10b1, 0xcbe: 0x10b1, 0xcbf: 0x2109,\n\t// Block 0x33, offset 0xcc0\n\t0xcc0: 0x08ed, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x0ef9,\n\t0xcc6: 0x0ef9, 0xcc7: 0x0f09, 0xcc8: 0x0f41, 0xcc9: 0x0259, 0xcca: 0x0018, 0xccb: 0x0018,\n\t0xccc: 0x0018, 0xccd: 0x0018, 0xcce: 0x0008, 0xccf: 0x0018, 0xcd0: 0x2121, 0xcd1: 0x2151,\n\t0xcd2: 0x2181, 0xcd3: 0x21b9, 0xcd4: 0x21e9, 0xcd5: 0x2219, 0xcd6: 0x2249, 0xcd7: 0x2279,\n\t0xcd8: 0x22a9, 0xcd9: 0x22d9, 0xcda: 0x2309, 0xcdb: 0x2339, 0xcdc: 0x2369, 0xcdd: 0x2399,\n\t0xcde: 0x23c9, 0xcdf: 0x23f9, 0xce0: 0x0f41, 0xce1: 0x2421, 0xce2: 0x0905, 0xce3: 0x2439,\n\t0xce4: 0x1089, 0xce5: 0x2451, 0xce6: 0x0925, 0xce7: 0x2469, 0xce8: 0x2491, 0xce9: 0x0369,\n\t0xcea: 0x24a9, 0xceb: 0x0945, 0xcec: 0x0359, 0xced: 0x1159, 0xcee: 0x0ef9, 0xcef: 0x0f61,\n\t0xcf0: 0x0f41, 0xcf1: 0x2421, 0xcf2: 0x0965, 0xcf3: 0x2439, 0xcf4: 0x1089, 0xcf5: 0x2451,\n\t0xcf6: 0x0985, 0xcf7: 0x2469, 0xcf8: 0x2491, 0xcf9: 0x0369, 0xcfa: 0x24a9, 0xcfb: 0x09a5,\n\t0xcfc: 0x0359, 0xcfd: 0x1159, 0xcfe: 0x0ef9, 0xcff: 0x0f61,\n\t// Block 0x34, offset 0xd00\n\t0xd00: 0x0018, 0xd01: 0x0018, 0xd02: 0x0018, 0xd03: 0x0018, 0xd04: 0x0018, 0xd05: 0x0018,\n\t0xd06: 0x0018, 0xd07: 0x0018, 0xd08: 0x0018, 0xd09: 0x0018, 0xd0a: 0x0018, 0xd0b: 0x0040,\n\t0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040,\n\t0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040,\n\t0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0040, 0xd1d: 0x0040,\n\t0xd1e: 0x0040, 0xd1f: 0x0040, 0xd20: 0x00c9, 0xd21: 0x0069, 0xd22: 0x0079, 0xd23: 0x1f51,\n\t0xd24: 0x1f61, 0xd25: 0x1f71, 0xd26: 0x1f81, 0xd27: 0x1f91, 0xd28: 0x1fa1, 0xd29: 0x2601,\n\t0xd2a: 0x2619, 0xd2b: 0x2631, 0xd2c: 0x2649, 0xd2d: 0x2661, 0xd2e: 0x2679, 0xd2f: 0x2691,\n\t0xd30: 0x26a9, 0xd31: 0x26c1, 0xd32: 0x26d9, 0xd33: 0x26f1, 0xd34: 0x0a06, 0xd35: 0x0a26,\n\t0xd36: 0x0a46, 0xd37: 0x0a66, 0xd38: 0x0a86, 0xd39: 0x0aa6, 0xd3a: 0x0ac6, 0xd3b: 0x0ae6,\n\t0xd3c: 0x0b06, 0xd3d: 0x270a, 0xd3e: 0x2732, 0xd3f: 0x275a,\n\t// Block 0x35, offset 0xd40\n\t0xd40: 0x2782, 0xd41: 0x27aa, 0xd42: 0x27d2, 0xd43: 0x27fa, 0xd44: 0x2822, 0xd45: 0x284a,\n\t0xd46: 0x2872, 0xd47: 0x289a, 0xd48: 0x0040, 0xd49: 0x0040, 0xd4a: 0x0040, 0xd4b: 0x0040,\n\t0xd4c: 0x0040, 0xd4d: 0x0040, 0xd4e: 0x0040, 0xd4f: 0x0040, 0xd50: 0x0040, 0xd51: 0x0040,\n\t0xd52: 0x0040, 0xd53: 0x0040, 0xd54: 0x0040, 0xd55: 0x0040, 0xd56: 0x0040, 0xd57: 0x0040,\n\t0xd58: 0x0040, 0xd59: 0x0040, 0xd5a: 0x0040, 0xd5b: 0x0040, 0xd5c: 0x0b26, 0xd5d: 0x0b46,\n\t0xd5e: 0x0b66, 0xd5f: 0x0b86, 0xd60: 0x0ba6, 0xd61: 0x0bc6, 0xd62: 0x0be6, 0xd63: 0x0c06,\n\t0xd64: 0x0c26, 0xd65: 0x0c46, 0xd66: 0x0c66, 0xd67: 0x0c86, 0xd68: 0x0ca6, 0xd69: 0x0cc6,\n\t0xd6a: 0x0ce6, 0xd6b: 0x0d06, 0xd6c: 0x0d26, 0xd6d: 0x0d46, 0xd6e: 0x0d66, 0xd6f: 0x0d86,\n\t0xd70: 0x0da6, 0xd71: 0x0dc6, 0xd72: 0x0de6, 0xd73: 0x0e06, 0xd74: 0x0e26, 0xd75: 0x0e46,\n\t0xd76: 0x0039, 0xd77: 0x0ee9, 0xd78: 0x1159, 0xd79: 0x0ef9, 0xd7a: 0x0f09, 0xd7b: 0x1199,\n\t0xd7c: 0x0f31, 0xd7d: 0x0249, 0xd7e: 0x0f41, 0xd7f: 0x0259,\n\t// Block 0x36, offset 0xd80\n\t0xd80: 0x0f51, 0xd81: 0x0359, 0xd82: 0x0f61, 0xd83: 0x0f71, 0xd84: 0x00d9, 0xd85: 0x0f99,\n\t0xd86: 0x2039, 0xd87: 0x0269, 0xd88: 0x01d9, 0xd89: 0x0fa9, 0xd8a: 0x0fb9, 0xd8b: 0x1089,\n\t0xd8c: 0x0279, 0xd8d: 0x0369, 0xd8e: 0x0289, 0xd8f: 0x13d1, 0xd90: 0x0039, 0xd91: 0x0ee9,\n\t0xd92: 0x1159, 0xd93: 0x0ef9, 0xd94: 0x0f09, 0xd95: 0x1199, 0xd96: 0x0f31, 0xd97: 0x0249,\n\t0xd98: 0x0f41, 0xd99: 0x0259, 0xd9a: 0x0f51, 0xd9b: 0x0359, 0xd9c: 0x0f61, 0xd9d: 0x0f71,\n\t0xd9e: 0x00d9, 0xd9f: 0x0f99, 0xda0: 0x2039, 0xda1: 0x0269, 0xda2: 0x01d9, 0xda3: 0x0fa9,\n\t0xda4: 0x0fb9, 0xda5: 0x1089, 0xda6: 0x0279, 0xda7: 0x0369, 0xda8: 0x0289, 0xda9: 0x13d1,\n\t0xdaa: 0x1f41, 0xdab: 0x0018, 0xdac: 0x0018, 0xdad: 0x0018, 0xdae: 0x0018, 0xdaf: 0x0018,\n\t0xdb0: 0x0018, 0xdb1: 0x0018, 0xdb2: 0x0018, 0xdb3: 0x0018, 0xdb4: 0x0018, 0xdb5: 0x0018,\n\t0xdb6: 0x0018, 0xdb7: 0x0018, 0xdb8: 0x0018, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018,\n\t0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018,\n\t// Block 0x37, offset 0xdc0\n\t0xdc0: 0x0008, 0xdc1: 0x0008, 0xdc2: 0x0008, 0xdc3: 0x0008, 0xdc4: 0x0008, 0xdc5: 0x0008,\n\t0xdc6: 0x0008, 0xdc7: 0x0008, 0xdc8: 0x0008, 0xdc9: 0x0008, 0xdca: 0x0008, 0xdcb: 0x0008,\n\t0xdcc: 0x0008, 0xdcd: 0x0008, 0xdce: 0x0008, 0xdcf: 0x0008, 0xdd0: 0x0008, 0xdd1: 0x0008,\n\t0xdd2: 0x0008, 0xdd3: 0x0008, 0xdd4: 0x0008, 0xdd5: 0x0008, 0xdd6: 0x0008, 0xdd7: 0x0008,\n\t0xdd8: 0x0008, 0xdd9: 0x0008, 0xdda: 0x0008, 0xddb: 0x0008, 0xddc: 0x0008, 0xddd: 0x0008,\n\t0xdde: 0x0008, 0xddf: 0x0040, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0x2971, 0xde3: 0x0ebd,\n\t0xde4: 0x2989, 0xde5: 0x0008, 0xde6: 0x0008, 0xde7: 0xe07d, 0xde8: 0x0008, 0xde9: 0xe01d,\n\t0xdea: 0x0008, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0x0fe1, 0xdee: 0x1281, 0xdef: 0x0fc9,\n\t0xdf0: 0x1141, 0xdf1: 0x0008, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0008, 0xdf5: 0xe01d,\n\t0xdf6: 0x0008, 0xdf7: 0x0008, 0xdf8: 0x0008, 0xdf9: 0x0008, 0xdfa: 0x0008, 0xdfb: 0x0008,\n\t0xdfc: 0x0259, 0xdfd: 0x1089, 0xdfe: 0x29a1, 0xdff: 0x29b9,\n\t// Block 0x38, offset 0xe00\n\t0xe00: 0xe00d, 0xe01: 0x0008, 0xe02: 0xe00d, 0xe03: 0x0008, 0xe04: 0xe00d, 0xe05: 0x0008,\n\t0xe06: 0xe00d, 0xe07: 0x0008, 0xe08: 0xe00d, 0xe09: 0x0008, 0xe0a: 0xe00d, 0xe0b: 0x0008,\n\t0xe0c: 0xe00d, 0xe0d: 0x0008, 0xe0e: 0xe00d, 0xe0f: 0x0008, 0xe10: 0xe00d, 0xe11: 0x0008,\n\t0xe12: 0xe00d, 0xe13: 0x0008, 0xe14: 0xe00d, 0xe15: 0x0008, 0xe16: 0xe00d, 0xe17: 0x0008,\n\t0xe18: 0xe00d, 0xe19: 0x0008, 0xe1a: 0xe00d, 0xe1b: 0x0008, 0xe1c: 0xe00d, 0xe1d: 0x0008,\n\t0xe1e: 0xe00d, 0xe1f: 0x0008, 0xe20: 0xe00d, 0xe21: 0x0008, 0xe22: 0xe00d, 0xe23: 0x0008,\n\t0xe24: 0x0008, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018,\n\t0xe2a: 0x0018, 0xe2b: 0xe03d, 0xe2c: 0x0008, 0xe2d: 0xe01d, 0xe2e: 0x0008, 0xe2f: 0x3308,\n\t0xe30: 0x3308, 0xe31: 0x3308, 0xe32: 0xe00d, 0xe33: 0x0008, 0xe34: 0x0040, 0xe35: 0x0040,\n\t0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0018, 0xe3a: 0x0018, 0xe3b: 0x0018,\n\t0xe3c: 0x0018, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018,\n\t// Block 0x39, offset 0xe40\n\t0xe40: 0x26fd, 0xe41: 0x271d, 0xe42: 0x273d, 0xe43: 0x275d, 0xe44: 0x277d, 0xe45: 0x279d,\n\t0xe46: 0x27bd, 0xe47: 0x27dd, 0xe48: 0x27fd, 0xe49: 0x281d, 0xe4a: 0x283d, 0xe4b: 0x285d,\n\t0xe4c: 0x287d, 0xe4d: 0x289d, 0xe4e: 0x28bd, 0xe4f: 0x28dd, 0xe50: 0x28fd, 0xe51: 0x291d,\n\t0xe52: 0x293d, 0xe53: 0x295d, 0xe54: 0x297d, 0xe55: 0x299d, 0xe56: 0x0040, 0xe57: 0x0040,\n\t0xe58: 0x0040, 0xe59: 0x0040, 0xe5a: 0x0040, 0xe5b: 0x0040, 0xe5c: 0x0040, 0xe5d: 0x0040,\n\t0xe5e: 0x0040, 0xe5f: 0x0040, 0xe60: 0x0040, 0xe61: 0x0040, 0xe62: 0x0040, 0xe63: 0x0040,\n\t0xe64: 0x0040, 0xe65: 0x0040, 0xe66: 0x0040, 0xe67: 0x0040, 0xe68: 0x0040, 0xe69: 0x0040,\n\t0xe6a: 0x0040, 0xe6b: 0x0040, 0xe6c: 0x0040, 0xe6d: 0x0040, 0xe6e: 0x0040, 0xe6f: 0x0040,\n\t0xe70: 0x0040, 0xe71: 0x0040, 0xe72: 0x0040, 0xe73: 0x0040, 0xe74: 0x0040, 0xe75: 0x0040,\n\t0xe76: 0x0040, 0xe77: 0x0040, 0xe78: 0x0040, 0xe79: 0x0040, 0xe7a: 0x0040, 0xe7b: 0x0040,\n\t0xe7c: 0x0040, 0xe7d: 0x0040, 0xe7e: 0x0040, 0xe7f: 0x0040,\n\t// Block 0x3a, offset 0xe80\n\t0xe80: 0x000a, 0xe81: 0x0018, 0xe82: 0x29d1, 0xe83: 0x0018, 0xe84: 0x0018, 0xe85: 0x0008,\n\t0xe86: 0x0008, 0xe87: 0x0008, 0xe88: 0x0018, 0xe89: 0x0018, 0xe8a: 0x0018, 0xe8b: 0x0018,\n\t0xe8c: 0x0018, 0xe8d: 0x0018, 0xe8e: 0x0018, 0xe8f: 0x0018, 0xe90: 0x0018, 0xe91: 0x0018,\n\t0xe92: 0x0018, 0xe93: 0x0018, 0xe94: 0x0018, 0xe95: 0x0018, 0xe96: 0x0018, 0xe97: 0x0018,\n\t0xe98: 0x0018, 0xe99: 0x0018, 0xe9a: 0x0018, 0xe9b: 0x0018, 0xe9c: 0x0018, 0xe9d: 0x0018,\n\t0xe9e: 0x0018, 0xe9f: 0x0018, 0xea0: 0x0018, 0xea1: 0x0018, 0xea2: 0x0018, 0xea3: 0x0018,\n\t0xea4: 0x0018, 0xea5: 0x0018, 0xea6: 0x0018, 0xea7: 0x0018, 0xea8: 0x0018, 0xea9: 0x0018,\n\t0xeaa: 0x3308, 0xeab: 0x3308, 0xeac: 0x3308, 0xead: 0x3308, 0xeae: 0x3018, 0xeaf: 0x3018,\n\t0xeb0: 0x0018, 0xeb1: 0x0018, 0xeb2: 0x0018, 0xeb3: 0x0018, 0xeb4: 0x0018, 0xeb5: 0x0018,\n\t0xeb6: 0xe125, 0xeb7: 0x0018, 0xeb8: 0x29bd, 0xeb9: 0x29dd, 0xeba: 0x29fd, 0xebb: 0x0018,\n\t0xebc: 0x0008, 0xebd: 0x0018, 0xebe: 0x0018, 0xebf: 0x0018,\n\t// Block 0x3b, offset 0xec0\n\t0xec0: 0x2b3d, 0xec1: 0x2b5d, 0xec2: 0x2b7d, 0xec3: 0x2b9d, 0xec4: 0x2bbd, 0xec5: 0x2bdd,\n\t0xec6: 0x2bdd, 0xec7: 0x2bdd, 0xec8: 0x2bfd, 0xec9: 0x2bfd, 0xeca: 0x2bfd, 0xecb: 0x2bfd,\n\t0xecc: 0x2c1d, 0xecd: 0x2c1d, 0xece: 0x2c1d, 0xecf: 0x2c3d, 0xed0: 0x2c5d, 0xed1: 0x2c5d,\n\t0xed2: 0x2a7d, 0xed3: 0x2a7d, 0xed4: 0x2c5d, 0xed5: 0x2c5d, 0xed6: 0x2c7d, 0xed7: 0x2c7d,\n\t0xed8: 0x2c5d, 0xed9: 0x2c5d, 0xeda: 0x2a7d, 0xedb: 0x2a7d, 0xedc: 0x2c5d, 0xedd: 0x2c5d,\n\t0xede: 0x2c3d, 0xedf: 0x2c3d, 0xee0: 0x2c9d, 0xee1: 0x2c9d, 0xee2: 0x2cbd, 0xee3: 0x2cbd,\n\t0xee4: 0x0040, 0xee5: 0x2cdd, 0xee6: 0x2cfd, 0xee7: 0x2d1d, 0xee8: 0x2d1d, 0xee9: 0x2d3d,\n\t0xeea: 0x2d5d, 0xeeb: 0x2d7d, 0xeec: 0x2d9d, 0xeed: 0x2dbd, 0xeee: 0x2ddd, 0xeef: 0x2dfd,\n\t0xef0: 0x2e1d, 0xef1: 0x2e3d, 0xef2: 0x2e3d, 0xef3: 0x2e5d, 0xef4: 0x2e7d, 0xef5: 0x2e7d,\n\t0xef6: 0x2e9d, 0xef7: 0x2ebd, 0xef8: 0x2e5d, 0xef9: 0x2edd, 0xefa: 0x2efd, 0xefb: 0x2edd,\n\t0xefc: 0x2e5d, 0xefd: 0x2f1d, 0xefe: 0x2f3d, 0xeff: 0x2f5d,\n\t// Block 0x3c, offset 0xf00\n\t0xf00: 0x2f7d, 0xf01: 0x2f9d, 0xf02: 0x2cfd, 0xf03: 0x2cdd, 0xf04: 0x2fbd, 0xf05: 0x2fdd,\n\t0xf06: 0x2ffd, 0xf07: 0x301d, 0xf08: 0x303d, 0xf09: 0x305d, 0xf0a: 0x307d, 0xf0b: 0x309d,\n\t0xf0c: 0x30bd, 0xf0d: 0x30dd, 0xf0e: 0x30fd, 0xf0f: 0x0040, 0xf10: 0x0018, 0xf11: 0x0018,\n\t0xf12: 0x311d, 0xf13: 0x313d, 0xf14: 0x315d, 0xf15: 0x317d, 0xf16: 0x319d, 0xf17: 0x31bd,\n\t0xf18: 0x31dd, 0xf19: 0x31fd, 0xf1a: 0x321d, 0xf1b: 0x323d, 0xf1c: 0x315d, 0xf1d: 0x325d,\n\t0xf1e: 0x327d, 0xf1f: 0x329d, 0xf20: 0x0008, 0xf21: 0x0008, 0xf22: 0x0008, 0xf23: 0x0008,\n\t0xf24: 0x0008, 0xf25: 0x0008, 0xf26: 0x0008, 0xf27: 0x0008, 0xf28: 0x0008, 0xf29: 0x0008,\n\t0xf2a: 0x0008, 0xf2b: 0x0008, 0xf2c: 0x0008, 0xf2d: 0x0008, 0xf2e: 0x0008, 0xf2f: 0x0008,\n\t0xf30: 0x0008, 0xf31: 0x0008, 0xf32: 0x0008, 0xf33: 0x0008, 0xf34: 0x0008, 0xf35: 0x0008,\n\t0xf36: 0x0008, 0xf37: 0x0008, 0xf38: 0x0008, 0xf39: 0x0008, 0xf3a: 0x0008, 0xf3b: 0x0040,\n\t0xf3c: 0x0040, 0xf3d: 0x0040, 0xf3e: 0x0040, 0xf3f: 0x0040,\n\t// Block 0x3d, offset 0xf40\n\t0xf40: 0x36a2, 0xf41: 0x36d2, 0xf42: 0x3702, 0xf43: 0x3732, 0xf44: 0x32bd, 0xf45: 0x32dd,\n\t0xf46: 0x32fd, 0xf47: 0x331d, 0xf48: 0x0018, 0xf49: 0x0018, 0xf4a: 0x0018, 0xf4b: 0x0018,\n\t0xf4c: 0x0018, 0xf4d: 0x0018, 0xf4e: 0x0018, 0xf4f: 0x0018, 0xf50: 0x333d, 0xf51: 0x3761,\n\t0xf52: 0x3779, 0xf53: 0x3791, 0xf54: 0x37a9, 0xf55: 0x37c1, 0xf56: 0x37d9, 0xf57: 0x37f1,\n\t0xf58: 0x3809, 0xf59: 0x3821, 0xf5a: 0x3839, 0xf5b: 0x3851, 0xf5c: 0x3869, 0xf5d: 0x3881,\n\t0xf5e: 0x3899, 0xf5f: 0x38b1, 0xf60: 0x335d, 0xf61: 0x337d, 0xf62: 0x339d, 0xf63: 0x33bd,\n\t0xf64: 0x33dd, 0xf65: 0x33dd, 0xf66: 0x33fd, 0xf67: 0x341d, 0xf68: 0x343d, 0xf69: 0x345d,\n\t0xf6a: 0x347d, 0xf6b: 0x349d, 0xf6c: 0x34bd, 0xf6d: 0x34dd, 0xf6e: 0x34fd, 0xf6f: 0x351d,\n\t0xf70: 0x353d, 0xf71: 0x355d, 0xf72: 0x357d, 0xf73: 0x359d, 0xf74: 0x35bd, 0xf75: 0x35dd,\n\t0xf76: 0x35fd, 0xf77: 0x361d, 0xf78: 0x363d, 0xf79: 0x365d, 0xf7a: 0x367d, 0xf7b: 0x369d,\n\t0xf7c: 0x38c9, 0xf7d: 0x3901, 0xf7e: 0x36bd, 0xf7f: 0x0018,\n\t// Block 0x3e, offset 0xf80\n\t0xf80: 0x36dd, 0xf81: 0x36fd, 0xf82: 0x371d, 0xf83: 0x373d, 0xf84: 0x375d, 0xf85: 0x377d,\n\t0xf86: 0x379d, 0xf87: 0x37bd, 0xf88: 0x37dd, 0xf89: 0x37fd, 0xf8a: 0x381d, 0xf8b: 0x383d,\n\t0xf8c: 0x385d, 0xf8d: 0x387d, 0xf8e: 0x389d, 0xf8f: 0x38bd, 0xf90: 0x38dd, 0xf91: 0x38fd,\n\t0xf92: 0x391d, 0xf93: 0x393d, 0xf94: 0x395d, 0xf95: 0x397d, 0xf96: 0x399d, 0xf97: 0x39bd,\n\t0xf98: 0x39dd, 0xf99: 0x39fd, 0xf9a: 0x3a1d, 0xf9b: 0x3a3d, 0xf9c: 0x3a5d, 0xf9d: 0x3a7d,\n\t0xf9e: 0x3a9d, 0xf9f: 0x3abd, 0xfa0: 0x3add, 0xfa1: 0x3afd, 0xfa2: 0x3b1d, 0xfa3: 0x3b3d,\n\t0xfa4: 0x3b5d, 0xfa5: 0x3b7d, 0xfa6: 0x127d, 0xfa7: 0x3b9d, 0xfa8: 0x3bbd, 0xfa9: 0x3bdd,\n\t0xfaa: 0x3bfd, 0xfab: 0x3c1d, 0xfac: 0x3c3d, 0xfad: 0x3c5d, 0xfae: 0x239d, 0xfaf: 0x3c7d,\n\t0xfb0: 0x3c9d, 0xfb1: 0x3939, 0xfb2: 0x3951, 0xfb3: 0x3969, 0xfb4: 0x3981, 0xfb5: 0x3999,\n\t0xfb6: 0x39b1, 0xfb7: 0x39c9, 0xfb8: 0x39e1, 0xfb9: 0x39f9, 0xfba: 0x3a11, 0xfbb: 0x3a29,\n\t0xfbc: 0x3a41, 0xfbd: 0x3a59, 0xfbe: 0x3a71, 0xfbf: 0x3a89,\n\t// Block 0x3f, offset 0xfc0\n\t0xfc0: 0x3aa1, 0xfc1: 0x3ac9, 0xfc2: 0x3af1, 0xfc3: 0x3b19, 0xfc4: 0x3b41, 0xfc5: 0x3b69,\n\t0xfc6: 0x3b91, 0xfc7: 0x3bb9, 0xfc8: 0x3be1, 0xfc9: 0x3c09, 0xfca: 0x3c39, 0xfcb: 0x3c69,\n\t0xfcc: 0x3c99, 0xfcd: 0x3cbd, 0xfce: 0x3cb1, 0xfcf: 0x3cdd, 0xfd0: 0x3cfd, 0xfd1: 0x3d15,\n\t0xfd2: 0x3d2d, 0xfd3: 0x3d45, 0xfd4: 0x3d5d, 0xfd5: 0x3d5d, 0xfd6: 0x3d45, 0xfd7: 0x3d75,\n\t0xfd8: 0x07bd, 0xfd9: 0x3d8d, 0xfda: 0x3da5, 0xfdb: 0x3dbd, 0xfdc: 0x3dd5, 0xfdd: 0x3ded,\n\t0xfde: 0x3e05, 0xfdf: 0x3e1d, 0xfe0: 0x3e35, 0xfe1: 0x3e4d, 0xfe2: 0x3e65, 0xfe3: 0x3e7d,\n\t0xfe4: 0x3e95, 0xfe5: 0x3e95, 0xfe6: 0x3ead, 0xfe7: 0x3ead, 0xfe8: 0x3ec5, 0xfe9: 0x3ec5,\n\t0xfea: 0x3edd, 0xfeb: 0x3ef5, 0xfec: 0x3f0d, 0xfed: 0x3f25, 0xfee: 0x3f3d, 0xfef: 0x3f3d,\n\t0xff0: 0x3f55, 0xff1: 0x3f55, 0xff2: 0x3f55, 0xff3: 0x3f6d, 0xff4: 0x3f85, 0xff5: 0x3f9d,\n\t0xff6: 0x3fb5, 0xff7: 0x3f9d, 0xff8: 0x3fcd, 0xff9: 0x3fe5, 0xffa: 0x3f6d, 0xffb: 0x3ffd,\n\t0xffc: 0x4015, 0xffd: 0x4015, 0xffe: 0x4015, 0xfff: 0x0040,\n\t// Block 0x40, offset 0x1000\n\t0x1000: 0x3cc9, 0x1001: 0x3d31, 0x1002: 0x3d99, 0x1003: 0x3e01, 0x1004: 0x3e51, 0x1005: 0x3eb9,\n\t0x1006: 0x3f09, 0x1007: 0x3f59, 0x1008: 0x3fd9, 0x1009: 0x4041, 0x100a: 0x4091, 0x100b: 0x40e1,\n\t0x100c: 0x4131, 0x100d: 0x4199, 0x100e: 0x4201, 0x100f: 0x4251, 0x1010: 0x42a1, 0x1011: 0x42d9,\n\t0x1012: 0x4329, 0x1013: 0x4391, 0x1014: 0x43f9, 0x1015: 0x4431, 0x1016: 0x44b1, 0x1017: 0x4549,\n\t0x1018: 0x45c9, 0x1019: 0x4619, 0x101a: 0x4699, 0x101b: 0x4719, 0x101c: 0x4781, 0x101d: 0x47d1,\n\t0x101e: 0x4821, 0x101f: 0x4871, 0x1020: 0x48d9, 0x1021: 0x4959, 0x1022: 0x49c1, 0x1023: 0x4a11,\n\t0x1024: 0x4a61, 0x1025: 0x4ab1, 0x1026: 0x4ae9, 0x1027: 0x4b21, 0x1028: 0x4b59, 0x1029: 0x4b91,\n\t0x102a: 0x4be1, 0x102b: 0x4c31, 0x102c: 0x4cb1, 0x102d: 0x4d01, 0x102e: 0x4d69, 0x102f: 0x4de9,\n\t0x1030: 0x4e39, 0x1031: 0x4e71, 0x1032: 0x4ea9, 0x1033: 0x4f29, 0x1034: 0x4f91, 0x1035: 0x5011,\n\t0x1036: 0x5061, 0x1037: 0x50e1, 0x1038: 0x5119, 0x1039: 0x5169, 0x103a: 0x51b9, 0x103b: 0x5209,\n\t0x103c: 0x5259, 0x103d: 0x52a9, 0x103e: 0x5311, 0x103f: 0x5361,\n\t// Block 0x41, offset 0x1040\n\t0x1040: 0x5399, 0x1041: 0x53e9, 0x1042: 0x5439, 0x1043: 0x5489, 0x1044: 0x54f1, 0x1045: 0x5541,\n\t0x1046: 0x5591, 0x1047: 0x55e1, 0x1048: 0x5661, 0x1049: 0x56c9, 0x104a: 0x5701, 0x104b: 0x5781,\n\t0x104c: 0x57b9, 0x104d: 0x5821, 0x104e: 0x5889, 0x104f: 0x58d9, 0x1050: 0x5929, 0x1051: 0x5979,\n\t0x1052: 0x59e1, 0x1053: 0x5a19, 0x1054: 0x5a69, 0x1055: 0x5ad1, 0x1056: 0x5b09, 0x1057: 0x5b89,\n\t0x1058: 0x5bd9, 0x1059: 0x5c01, 0x105a: 0x5c29, 0x105b: 0x5c51, 0x105c: 0x5c79, 0x105d: 0x5ca1,\n\t0x105e: 0x5cc9, 0x105f: 0x5cf1, 0x1060: 0x5d19, 0x1061: 0x5d41, 0x1062: 0x5d69, 0x1063: 0x5d99,\n\t0x1064: 0x5dc9, 0x1065: 0x5df9, 0x1066: 0x5e29, 0x1067: 0x5e59, 0x1068: 0x5e89, 0x1069: 0x5eb9,\n\t0x106a: 0x5ee9, 0x106b: 0x5f19, 0x106c: 0x5f49, 0x106d: 0x5f79, 0x106e: 0x5fa9, 0x106f: 0x5fd9,\n\t0x1070: 0x6009, 0x1071: 0x402d, 0x1072: 0x6039, 0x1073: 0x6051, 0x1074: 0x404d, 0x1075: 0x6069,\n\t0x1076: 0x6081, 0x1077: 0x6099, 0x1078: 0x406d, 0x1079: 0x406d, 0x107a: 0x60b1, 0x107b: 0x60c9,\n\t0x107c: 0x6101, 0x107d: 0x6139, 0x107e: 0x6171, 0x107f: 0x61a9,\n\t// Block 0x42, offset 0x1080\n\t0x1080: 0x6211, 0x1081: 0x6229, 0x1082: 0x408d, 0x1083: 0x6241, 0x1084: 0x6259, 0x1085: 0x6271,\n\t0x1086: 0x6289, 0x1087: 0x62a1, 0x1088: 0x40ad, 0x1089: 0x62b9, 0x108a: 0x62e1, 0x108b: 0x62f9,\n\t0x108c: 0x40cd, 0x108d: 0x40cd, 0x108e: 0x6311, 0x108f: 0x6329, 0x1090: 0x6341, 0x1091: 0x40ed,\n\t0x1092: 0x410d, 0x1093: 0x412d, 0x1094: 0x414d, 0x1095: 0x416d, 0x1096: 0x6359, 0x1097: 0x6371,\n\t0x1098: 0x6389, 0x1099: 0x63a1, 0x109a: 0x63b9, 0x109b: 0x418d, 0x109c: 0x63d1, 0x109d: 0x63e9,\n\t0x109e: 0x6401, 0x109f: 0x41ad, 0x10a0: 0x41cd, 0x10a1: 0x6419, 0x10a2: 0x41ed, 0x10a3: 0x420d,\n\t0x10a4: 0x422d, 0x10a5: 0x6431, 0x10a6: 0x424d, 0x10a7: 0x6449, 0x10a8: 0x6479, 0x10a9: 0x6211,\n\t0x10aa: 0x426d, 0x10ab: 0x428d, 0x10ac: 0x42ad, 0x10ad: 0x42cd, 0x10ae: 0x64b1, 0x10af: 0x64f1,\n\t0x10b0: 0x6539, 0x10b1: 0x6551, 0x10b2: 0x42ed, 0x10b3: 0x6569, 0x10b4: 0x6581, 0x10b5: 0x6599,\n\t0x10b6: 0x430d, 0x10b7: 0x65b1, 0x10b8: 0x65c9, 0x10b9: 0x65b1, 0x10ba: 0x65e1, 0x10bb: 0x65f9,\n\t0x10bc: 0x432d, 0x10bd: 0x6611, 0x10be: 0x6629, 0x10bf: 0x6611,\n\t// Block 0x43, offset 0x10c0\n\t0x10c0: 0x434d, 0x10c1: 0x436d, 0x10c2: 0x0040, 0x10c3: 0x6641, 0x10c4: 0x6659, 0x10c5: 0x6671,\n\t0x10c6: 0x6689, 0x10c7: 0x0040, 0x10c8: 0x66c1, 0x10c9: 0x66d9, 0x10ca: 0x66f1, 0x10cb: 0x6709,\n\t0x10cc: 0x6721, 0x10cd: 0x6739, 0x10ce: 0x6401, 0x10cf: 0x6751, 0x10d0: 0x6769, 0x10d1: 0x6781,\n\t0x10d2: 0x438d, 0x10d3: 0x6799, 0x10d4: 0x6289, 0x10d5: 0x43ad, 0x10d6: 0x43cd, 0x10d7: 0x67b1,\n\t0x10d8: 0x0040, 0x10d9: 0x43ed, 0x10da: 0x67c9, 0x10db: 0x67e1, 0x10dc: 0x67f9, 0x10dd: 0x6811,\n\t0x10de: 0x6829, 0x10df: 0x6859, 0x10e0: 0x6889, 0x10e1: 0x68b1, 0x10e2: 0x68d9, 0x10e3: 0x6901,\n\t0x10e4: 0x6929, 0x10e5: 0x6951, 0x10e6: 0x6979, 0x10e7: 0x69a1, 0x10e8: 0x69c9, 0x10e9: 0x69f1,\n\t0x10ea: 0x6a21, 0x10eb: 0x6a51, 0x10ec: 0x6a81, 0x10ed: 0x6ab1, 0x10ee: 0x6ae1, 0x10ef: 0x6b11,\n\t0x10f0: 0x6b41, 0x10f1: 0x6b71, 0x10f2: 0x6ba1, 0x10f3: 0x6bd1, 0x10f4: 0x6c01, 0x10f5: 0x6c31,\n\t0x10f6: 0x6c61, 0x10f7: 0x6c91, 0x10f8: 0x6cc1, 0x10f9: 0x6cf1, 0x10fa: 0x6d21, 0x10fb: 0x6d51,\n\t0x10fc: 0x6d81, 0x10fd: 0x6db1, 0x10fe: 0x6de1, 0x10ff: 0x440d,\n\t// Block 0x44, offset 0x1100\n\t0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008,\n\t0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008,\n\t0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008,\n\t0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008,\n\t0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0xe00d, 0x111d: 0x0008,\n\t0x111e: 0xe00d, 0x111f: 0x0008, 0x1120: 0xe00d, 0x1121: 0x0008, 0x1122: 0xe00d, 0x1123: 0x0008,\n\t0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008,\n\t0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x3308,\n\t0x1130: 0x3318, 0x1131: 0x3318, 0x1132: 0x3318, 0x1133: 0x0018, 0x1134: 0x3308, 0x1135: 0x3308,\n\t0x1136: 0x3308, 0x1137: 0x3308, 0x1138: 0x3308, 0x1139: 0x3308, 0x113a: 0x3308, 0x113b: 0x3308,\n\t0x113c: 0x3308, 0x113d: 0x3308, 0x113e: 0x0018, 0x113f: 0x0008,\n\t// Block 0x45, offset 0x1140\n\t0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008,\n\t0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008,\n\t0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008,\n\t0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008,\n\t0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0x0ea1, 0x115d: 0x6e11,\n\t0x115e: 0x3308, 0x115f: 0x3308, 0x1160: 0x0008, 0x1161: 0x0008, 0x1162: 0x0008, 0x1163: 0x0008,\n\t0x1164: 0x0008, 0x1165: 0x0008, 0x1166: 0x0008, 0x1167: 0x0008, 0x1168: 0x0008, 0x1169: 0x0008,\n\t0x116a: 0x0008, 0x116b: 0x0008, 0x116c: 0x0008, 0x116d: 0x0008, 0x116e: 0x0008, 0x116f: 0x0008,\n\t0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008,\n\t0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0x0008, 0x117a: 0x0008, 0x117b: 0x0008,\n\t0x117c: 0x0008, 0x117d: 0x0008, 0x117e: 0x0008, 0x117f: 0x0008,\n\t// Block 0x46, offset 0x1180\n\t0x1180: 0x0018, 0x1181: 0x0018, 0x1182: 0x0018, 0x1183: 0x0018, 0x1184: 0x0018, 0x1185: 0x0018,\n\t0x1186: 0x0018, 0x1187: 0x0018, 0x1188: 0x0018, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0x0018,\n\t0x118c: 0x0018, 0x118d: 0x0018, 0x118e: 0x0018, 0x118f: 0x0018, 0x1190: 0x0018, 0x1191: 0x0018,\n\t0x1192: 0x0018, 0x1193: 0x0018, 0x1194: 0x0018, 0x1195: 0x0018, 0x1196: 0x0018, 0x1197: 0x0008,\n\t0x1198: 0x0008, 0x1199: 0x0008, 0x119a: 0x0008, 0x119b: 0x0008, 0x119c: 0x0008, 0x119d: 0x0008,\n\t0x119e: 0x0008, 0x119f: 0x0008, 0x11a0: 0x0018, 0x11a1: 0x0018, 0x11a2: 0xe00d, 0x11a3: 0x0008,\n\t0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008,\n\t0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008,\n\t0x11b0: 0x0008, 0x11b1: 0x0008, 0x11b2: 0xe00d, 0x11b3: 0x0008, 0x11b4: 0xe00d, 0x11b5: 0x0008,\n\t0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0xe00d, 0x11b9: 0x0008, 0x11ba: 0xe00d, 0x11bb: 0x0008,\n\t0x11bc: 0xe00d, 0x11bd: 0x0008, 0x11be: 0xe00d, 0x11bf: 0x0008,\n\t// Block 0x47, offset 0x11c0\n\t0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008,\n\t0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0xe00d, 0x11c9: 0x0008, 0x11ca: 0xe00d, 0x11cb: 0x0008,\n\t0x11cc: 0xe00d, 0x11cd: 0x0008, 0x11ce: 0xe00d, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008,\n\t0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0xe00d, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008,\n\t0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008,\n\t0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008,\n\t0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008,\n\t0x11ea: 0xe00d, 0x11eb: 0x0008, 0x11ec: 0xe00d, 0x11ed: 0x0008, 0x11ee: 0xe00d, 0x11ef: 0x0008,\n\t0x11f0: 0xe0fd, 0x11f1: 0x0008, 0x11f2: 0x0008, 0x11f3: 0x0008, 0x11f4: 0x0008, 0x11f5: 0x0008,\n\t0x11f6: 0x0008, 0x11f7: 0x0008, 0x11f8: 0x0008, 0x11f9: 0xe01d, 0x11fa: 0x0008, 0x11fb: 0xe03d,\n\t0x11fc: 0x0008, 0x11fd: 0x442d, 0x11fe: 0xe00d, 0x11ff: 0x0008,\n\t// Block 0x48, offset 0x1200\n\t0x1200: 0xe00d, 0x1201: 0x0008, 0x1202: 0xe00d, 0x1203: 0x0008, 0x1204: 0xe00d, 0x1205: 0x0008,\n\t0x1206: 0xe00d, 0x1207: 0x0008, 0x1208: 0x0008, 0x1209: 0x0018, 0x120a: 0x0018, 0x120b: 0xe03d,\n\t0x120c: 0x0008, 0x120d: 0x11d9, 0x120e: 0x0008, 0x120f: 0x0008, 0x1210: 0xe00d, 0x1211: 0x0008,\n\t0x1212: 0xe00d, 0x1213: 0x0008, 0x1214: 0x0008, 0x1215: 0x0008, 0x1216: 0xe00d, 0x1217: 0x0008,\n\t0x1218: 0xe00d, 0x1219: 0x0008, 0x121a: 0xe00d, 0x121b: 0x0008, 0x121c: 0xe00d, 0x121d: 0x0008,\n\t0x121e: 0xe00d, 0x121f: 0x0008, 0x1220: 0xe00d, 0x1221: 0x0008, 0x1222: 0xe00d, 0x1223: 0x0008,\n\t0x1224: 0xe00d, 0x1225: 0x0008, 0x1226: 0xe00d, 0x1227: 0x0008, 0x1228: 0xe00d, 0x1229: 0x0008,\n\t0x122a: 0x6e29, 0x122b: 0x1029, 0x122c: 0x11c1, 0x122d: 0x6e41, 0x122e: 0x1221, 0x122f: 0x0008,\n\t0x1230: 0x6e59, 0x1231: 0x6e71, 0x1232: 0x1239, 0x1233: 0x444d, 0x1234: 0xe00d, 0x1235: 0x0008,\n\t0x1236: 0xe00d, 0x1237: 0x0008, 0x1238: 0x0040, 0x1239: 0x0008, 0x123a: 0x0040, 0x123b: 0x0040,\n\t0x123c: 0x0040, 0x123d: 0x0040, 0x123e: 0x0040, 0x123f: 0x0040,\n\t// Block 0x49, offset 0x1240\n\t0x1240: 0x64d5, 0x1241: 0x64f5, 0x1242: 0x6515, 0x1243: 0x6535, 0x1244: 0x6555, 0x1245: 0x6575,\n\t0x1246: 0x6595, 0x1247: 0x65b5, 0x1248: 0x65d5, 0x1249: 0x65f5, 0x124a: 0x6615, 0x124b: 0x6635,\n\t0x124c: 0x6655, 0x124d: 0x6675, 0x124e: 0x0008, 0x124f: 0x0008, 0x1250: 0x6695, 0x1251: 0x0008,\n\t0x1252: 0x66b5, 0x1253: 0x0008, 0x1254: 0x0008, 0x1255: 0x66d5, 0x1256: 0x66f5, 0x1257: 0x6715,\n\t0x1258: 0x6735, 0x1259: 0x6755, 0x125a: 0x6775, 0x125b: 0x6795, 0x125c: 0x67b5, 0x125d: 0x67d5,\n\t0x125e: 0x67f5, 0x125f: 0x0008, 0x1260: 0x6815, 0x1261: 0x0008, 0x1262: 0x6835, 0x1263: 0x0008,\n\t0x1264: 0x0008, 0x1265: 0x6855, 0x1266: 0x6875, 0x1267: 0x0008, 0x1268: 0x0008, 0x1269: 0x0008,\n\t0x126a: 0x6895, 0x126b: 0x68b5, 0x126c: 0x68d5, 0x126d: 0x68f5, 0x126e: 0x6915, 0x126f: 0x6935,\n\t0x1270: 0x6955, 0x1271: 0x6975, 0x1272: 0x6995, 0x1273: 0x69b5, 0x1274: 0x69d5, 0x1275: 0x69f5,\n\t0x1276: 0x6a15, 0x1277: 0x6a35, 0x1278: 0x6a55, 0x1279: 0x6a75, 0x127a: 0x6a95, 0x127b: 0x6ab5,\n\t0x127c: 0x6ad5, 0x127d: 0x6af5, 0x127e: 0x6b15, 0x127f: 0x6b35,\n\t// Block 0x4a, offset 0x1280\n\t0x1280: 0x7a95, 0x1281: 0x7ab5, 0x1282: 0x7ad5, 0x1283: 0x7af5, 0x1284: 0x7b15, 0x1285: 0x7b35,\n\t0x1286: 0x7b55, 0x1287: 0x7b75, 0x1288: 0x7b95, 0x1289: 0x7bb5, 0x128a: 0x7bd5, 0x128b: 0x7bf5,\n\t0x128c: 0x7c15, 0x128d: 0x7c35, 0x128e: 0x7c55, 0x128f: 0x6ec9, 0x1290: 0x6ef1, 0x1291: 0x6f19,\n\t0x1292: 0x7c75, 0x1293: 0x7c95, 0x1294: 0x7cb5, 0x1295: 0x6f41, 0x1296: 0x6f69, 0x1297: 0x6f91,\n\t0x1298: 0x7cd5, 0x1299: 0x7cf5, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x0040,\n\t0x129e: 0x0040, 0x129f: 0x0040, 0x12a0: 0x0040, 0x12a1: 0x0040, 0x12a2: 0x0040, 0x12a3: 0x0040,\n\t0x12a4: 0x0040, 0x12a5: 0x0040, 0x12a6: 0x0040, 0x12a7: 0x0040, 0x12a8: 0x0040, 0x12a9: 0x0040,\n\t0x12aa: 0x0040, 0x12ab: 0x0040, 0x12ac: 0x0040, 0x12ad: 0x0040, 0x12ae: 0x0040, 0x12af: 0x0040,\n\t0x12b0: 0x0040, 0x12b1: 0x0040, 0x12b2: 0x0040, 0x12b3: 0x0040, 0x12b4: 0x0040, 0x12b5: 0x0040,\n\t0x12b6: 0x0040, 0x12b7: 0x0040, 0x12b8: 0x0040, 0x12b9: 0x0040, 0x12ba: 0x0040, 0x12bb: 0x0040,\n\t0x12bc: 0x0040, 0x12bd: 0x0040, 0x12be: 0x0040, 0x12bf: 0x0040,\n\t// Block 0x4b, offset 0x12c0\n\t0x12c0: 0x6fb9, 0x12c1: 0x6fd1, 0x12c2: 0x6fe9, 0x12c3: 0x7d15, 0x12c4: 0x7d35, 0x12c5: 0x7001,\n\t0x12c6: 0x7001, 0x12c7: 0x0040, 0x12c8: 0x0040, 0x12c9: 0x0040, 0x12ca: 0x0040, 0x12cb: 0x0040,\n\t0x12cc: 0x0040, 0x12cd: 0x0040, 0x12ce: 0x0040, 0x12cf: 0x0040, 0x12d0: 0x0040, 0x12d1: 0x0040,\n\t0x12d2: 0x0040, 0x12d3: 0x7019, 0x12d4: 0x7041, 0x12d5: 0x7069, 0x12d6: 0x7091, 0x12d7: 0x70b9,\n\t0x12d8: 0x0040, 0x12d9: 0x0040, 0x12da: 0x0040, 0x12db: 0x0040, 0x12dc: 0x0040, 0x12dd: 0x70e1,\n\t0x12de: 0x3308, 0x12df: 0x7109, 0x12e0: 0x7131, 0x12e1: 0x20a9, 0x12e2: 0x20f1, 0x12e3: 0x7149,\n\t0x12e4: 0x7161, 0x12e5: 0x7179, 0x12e6: 0x7191, 0x12e7: 0x71a9, 0x12e8: 0x71c1, 0x12e9: 0x1fb2,\n\t0x12ea: 0x71d9, 0x12eb: 0x7201, 0x12ec: 0x7229, 0x12ed: 0x7261, 0x12ee: 0x7299, 0x12ef: 0x72c1,\n\t0x12f0: 0x72e9, 0x12f1: 0x7311, 0x12f2: 0x7339, 0x12f3: 0x7361, 0x12f4: 0x7389, 0x12f5: 0x73b1,\n\t0x12f6: 0x73d9, 0x12f7: 0x0040, 0x12f8: 0x7401, 0x12f9: 0x7429, 0x12fa: 0x7451, 0x12fb: 0x7479,\n\t0x12fc: 0x74a1, 0x12fd: 0x0040, 0x12fe: 0x74c9, 0x12ff: 0x0040,\n\t// Block 0x4c, offset 0x1300\n\t0x1300: 0x74f1, 0x1301: 0x7519, 0x1302: 0x0040, 0x1303: 0x7541, 0x1304: 0x7569, 0x1305: 0x0040,\n\t0x1306: 0x7591, 0x1307: 0x75b9, 0x1308: 0x75e1, 0x1309: 0x7609, 0x130a: 0x7631, 0x130b: 0x7659,\n\t0x130c: 0x7681, 0x130d: 0x76a9, 0x130e: 0x76d1, 0x130f: 0x76f9, 0x1310: 0x7721, 0x1311: 0x7721,\n\t0x1312: 0x7739, 0x1313: 0x7739, 0x1314: 0x7739, 0x1315: 0x7739, 0x1316: 0x7751, 0x1317: 0x7751,\n\t0x1318: 0x7751, 0x1319: 0x7751, 0x131a: 0x7769, 0x131b: 0x7769, 0x131c: 0x7769, 0x131d: 0x7769,\n\t0x131e: 0x7781, 0x131f: 0x7781, 0x1320: 0x7781, 0x1321: 0x7781, 0x1322: 0x7799, 0x1323: 0x7799,\n\t0x1324: 0x7799, 0x1325: 0x7799, 0x1326: 0x77b1, 0x1327: 0x77b1, 0x1328: 0x77b1, 0x1329: 0x77b1,\n\t0x132a: 0x77c9, 0x132b: 0x77c9, 0x132c: 0x77c9, 0x132d: 0x77c9, 0x132e: 0x77e1, 0x132f: 0x77e1,\n\t0x1330: 0x77e1, 0x1331: 0x77e1, 0x1332: 0x77f9, 0x1333: 0x77f9, 0x1334: 0x77f9, 0x1335: 0x77f9,\n\t0x1336: 0x7811, 0x1337: 0x7811, 0x1338: 0x7811, 0x1339: 0x7811, 0x133a: 0x7829, 0x133b: 0x7829,\n\t0x133c: 0x7829, 0x133d: 0x7829, 0x133e: 0x7841, 0x133f: 0x7841,\n\t// Block 0x4d, offset 0x1340\n\t0x1340: 0x7841, 0x1341: 0x7841, 0x1342: 0x7859, 0x1343: 0x7859, 0x1344: 0x7871, 0x1345: 0x7871,\n\t0x1346: 0x7889, 0x1347: 0x7889, 0x1348: 0x78a1, 0x1349: 0x78a1, 0x134a: 0x78b9, 0x134b: 0x78b9,\n\t0x134c: 0x78d1, 0x134d: 0x78d1, 0x134e: 0x78e9, 0x134f: 0x78e9, 0x1350: 0x78e9, 0x1351: 0x78e9,\n\t0x1352: 0x7901, 0x1353: 0x7901, 0x1354: 0x7901, 0x1355: 0x7901, 0x1356: 0x7919, 0x1357: 0x7919,\n\t0x1358: 0x7919, 0x1359: 0x7919, 0x135a: 0x7931, 0x135b: 0x7931, 0x135c: 0x7931, 0x135d: 0x7931,\n\t0x135e: 0x7949, 0x135f: 0x7949, 0x1360: 0x7961, 0x1361: 0x7961, 0x1362: 0x7961, 0x1363: 0x7961,\n\t0x1364: 0x7979, 0x1365: 0x7979, 0x1366: 0x7991, 0x1367: 0x7991, 0x1368: 0x7991, 0x1369: 0x7991,\n\t0x136a: 0x79a9, 0x136b: 0x79a9, 0x136c: 0x79a9, 0x136d: 0x79a9, 0x136e: 0x79c1, 0x136f: 0x79c1,\n\t0x1370: 0x79d9, 0x1371: 0x79d9, 0x1372: 0x0818, 0x1373: 0x0818, 0x1374: 0x0818, 0x1375: 0x0818,\n\t0x1376: 0x0818, 0x1377: 0x0818, 0x1378: 0x0818, 0x1379: 0x0818, 0x137a: 0x0818, 0x137b: 0x0818,\n\t0x137c: 0x0818, 0x137d: 0x0818, 0x137e: 0x0818, 0x137f: 0x0818,\n\t// Block 0x4e, offset 0x1380\n\t0x1380: 0x0818, 0x1381: 0x0818, 0x1382: 0x0040, 0x1383: 0x0040, 0x1384: 0x0040, 0x1385: 0x0040,\n\t0x1386: 0x0040, 0x1387: 0x0040, 0x1388: 0x0040, 0x1389: 0x0040, 0x138a: 0x0040, 0x138b: 0x0040,\n\t0x138c: 0x0040, 0x138d: 0x0040, 0x138e: 0x0040, 0x138f: 0x0040, 0x1390: 0x0040, 0x1391: 0x0040,\n\t0x1392: 0x0040, 0x1393: 0x79f1, 0x1394: 0x79f1, 0x1395: 0x79f1, 0x1396: 0x79f1, 0x1397: 0x7a09,\n\t0x1398: 0x7a09, 0x1399: 0x7a21, 0x139a: 0x7a21, 0x139b: 0x7a39, 0x139c: 0x7a39, 0x139d: 0x0479,\n\t0x139e: 0x7a51, 0x139f: 0x7a51, 0x13a0: 0x7a69, 0x13a1: 0x7a69, 0x13a2: 0x7a81, 0x13a3: 0x7a81,\n\t0x13a4: 0x7a99, 0x13a5: 0x7a99, 0x13a6: 0x7a99, 0x13a7: 0x7a99, 0x13a8: 0x7ab1, 0x13a9: 0x7ab1,\n\t0x13aa: 0x7ac9, 0x13ab: 0x7ac9, 0x13ac: 0x7af1, 0x13ad: 0x7af1, 0x13ae: 0x7b19, 0x13af: 0x7b19,\n\t0x13b0: 0x7b41, 0x13b1: 0x7b41, 0x13b2: 0x7b69, 0x13b3: 0x7b69, 0x13b4: 0x7b91, 0x13b5: 0x7b91,\n\t0x13b6: 0x7bb9, 0x13b7: 0x7bb9, 0x13b8: 0x7bb9, 0x13b9: 0x7be1, 0x13ba: 0x7be1, 0x13bb: 0x7be1,\n\t0x13bc: 0x7c09, 0x13bd: 0x7c09, 0x13be: 0x7c09, 0x13bf: 0x7c09,\n\t// Block 0x4f, offset 0x13c0\n\t0x13c0: 0x85f9, 0x13c1: 0x8621, 0x13c2: 0x8649, 0x13c3: 0x8671, 0x13c4: 0x8699, 0x13c5: 0x86c1,\n\t0x13c6: 0x86e9, 0x13c7: 0x8711, 0x13c8: 0x8739, 0x13c9: 0x8761, 0x13ca: 0x8789, 0x13cb: 0x87b1,\n\t0x13cc: 0x87d9, 0x13cd: 0x8801, 0x13ce: 0x8829, 0x13cf: 0x8851, 0x13d0: 0x8879, 0x13d1: 0x88a1,\n\t0x13d2: 0x88c9, 0x13d3: 0x88f1, 0x13d4: 0x8919, 0x13d5: 0x8941, 0x13d6: 0x8969, 0x13d7: 0x8991,\n\t0x13d8: 0x89b9, 0x13d9: 0x89e1, 0x13da: 0x8a09, 0x13db: 0x8a31, 0x13dc: 0x8a59, 0x13dd: 0x8a81,\n\t0x13de: 0x8aaa, 0x13df: 0x8ada, 0x13e0: 0x8b0a, 0x13e1: 0x8b3a, 0x13e2: 0x8b6a, 0x13e3: 0x8b9a,\n\t0x13e4: 0x8bc9, 0x13e5: 0x8bf1, 0x13e6: 0x7c71, 0x13e7: 0x8c19, 0x13e8: 0x7be1, 0x13e9: 0x7c99,\n\t0x13ea: 0x8c41, 0x13eb: 0x8c69, 0x13ec: 0x7d39, 0x13ed: 0x8c91, 0x13ee: 0x7d61, 0x13ef: 0x7d89,\n\t0x13f0: 0x8cb9, 0x13f1: 0x8ce1, 0x13f2: 0x7e29, 0x13f3: 0x8d09, 0x13f4: 0x7e51, 0x13f5: 0x7e79,\n\t0x13f6: 0x8d31, 0x13f7: 0x8d59, 0x13f8: 0x7ec9, 0x13f9: 0x8d81, 0x13fa: 0x7ef1, 0x13fb: 0x7f19,\n\t0x13fc: 0x83a1, 0x13fd: 0x83c9, 0x13fe: 0x8441, 0x13ff: 0x8469,\n\t// Block 0x50, offset 0x1400\n\t0x1400: 0x8491, 0x1401: 0x8531, 0x1402: 0x8559, 0x1403: 0x8581, 0x1404: 0x85a9, 0x1405: 0x8649,\n\t0x1406: 0x8671, 0x1407: 0x8699, 0x1408: 0x8da9, 0x1409: 0x8739, 0x140a: 0x8dd1, 0x140b: 0x8df9,\n\t0x140c: 0x8829, 0x140d: 0x8e21, 0x140e: 0x8851, 0x140f: 0x8879, 0x1410: 0x8a81, 0x1411: 0x8e49,\n\t0x1412: 0x8e71, 0x1413: 0x89b9, 0x1414: 0x8e99, 0x1415: 0x89e1, 0x1416: 0x8a09, 0x1417: 0x7c21,\n\t0x1418: 0x7c49, 0x1419: 0x8ec1, 0x141a: 0x7c71, 0x141b: 0x8ee9, 0x141c: 0x7cc1, 0x141d: 0x7ce9,\n\t0x141e: 0x7d11, 0x141f: 0x7d39, 0x1420: 0x8f11, 0x1421: 0x7db1, 0x1422: 0x7dd9, 0x1423: 0x7e01,\n\t0x1424: 0x7e29, 0x1425: 0x8f39, 0x1426: 0x7ec9, 0x1427: 0x7f41, 0x1428: 0x7f69, 0x1429: 0x7f91,\n\t0x142a: 0x7fb9, 0x142b: 0x7fe1, 0x142c: 0x8031, 0x142d: 0x8059, 0x142e: 0x8081, 0x142f: 0x80a9,\n\t0x1430: 0x80d1, 0x1431: 0x80f9, 0x1432: 0x8f61, 0x1433: 0x8121, 0x1434: 0x8149, 0x1435: 0x8171,\n\t0x1436: 0x8199, 0x1437: 0x81c1, 0x1438: 0x81e9, 0x1439: 0x8239, 0x143a: 0x8261, 0x143b: 0x8289,\n\t0x143c: 0x82b1, 0x143d: 0x82d9, 0x143e: 0x8301, 0x143f: 0x8329,\n\t// Block 0x51, offset 0x1440\n\t0x1440: 0x8351, 0x1441: 0x8379, 0x1442: 0x83f1, 0x1443: 0x8419, 0x1444: 0x84b9, 0x1445: 0x84e1,\n\t0x1446: 0x8509, 0x1447: 0x8531, 0x1448: 0x8559, 0x1449: 0x85d1, 0x144a: 0x85f9, 0x144b: 0x8621,\n\t0x144c: 0x8649, 0x144d: 0x8f89, 0x144e: 0x86c1, 0x144f: 0x86e9, 0x1450: 0x8711, 0x1451: 0x8739,\n\t0x1452: 0x87b1, 0x1453: 0x87d9, 0x1454: 0x8801, 0x1455: 0x8829, 0x1456: 0x8fb1, 0x1457: 0x88a1,\n\t0x1458: 0x88c9, 0x1459: 0x8fd9, 0x145a: 0x8941, 0x145b: 0x8969, 0x145c: 0x8991, 0x145d: 0x89b9,\n\t0x145e: 0x9001, 0x145f: 0x7c71, 0x1460: 0x8ee9, 0x1461: 0x7d39, 0x1462: 0x8f11, 0x1463: 0x7e29,\n\t0x1464: 0x8f39, 0x1465: 0x7ec9, 0x1466: 0x9029, 0x1467: 0x80d1, 0x1468: 0x9051, 0x1469: 0x9079,\n\t0x146a: 0x90a1, 0x146b: 0x8531, 0x146c: 0x8559, 0x146d: 0x8649, 0x146e: 0x8829, 0x146f: 0x8fb1,\n\t0x1470: 0x89b9, 0x1471: 0x9001, 0x1472: 0x90c9, 0x1473: 0x9101, 0x1474: 0x9139, 0x1475: 0x9171,\n\t0x1476: 0x9199, 0x1477: 0x91c1, 0x1478: 0x91e9, 0x1479: 0x9211, 0x147a: 0x9239, 0x147b: 0x9261,\n\t0x147c: 0x9289, 0x147d: 0x92b1, 0x147e: 0x92d9, 0x147f: 0x9301,\n\t// Block 0x52, offset 0x1480\n\t0x1480: 0x9329, 0x1481: 0x9351, 0x1482: 0x9379, 0x1483: 0x93a1, 0x1484: 0x93c9, 0x1485: 0x93f1,\n\t0x1486: 0x9419, 0x1487: 0x9441, 0x1488: 0x9469, 0x1489: 0x9491, 0x148a: 0x94b9, 0x148b: 0x94e1,\n\t0x148c: 0x9079, 0x148d: 0x9509, 0x148e: 0x9531, 0x148f: 0x9559, 0x1490: 0x9581, 0x1491: 0x9171,\n\t0x1492: 0x9199, 0x1493: 0x91c1, 0x1494: 0x91e9, 0x1495: 0x9211, 0x1496: 0x9239, 0x1497: 0x9261,\n\t0x1498: 0x9289, 0x1499: 0x92b1, 0x149a: 0x92d9, 0x149b: 0x9301, 0x149c: 0x9329, 0x149d: 0x9351,\n\t0x149e: 0x9379, 0x149f: 0x93a1, 0x14a0: 0x93c9, 0x14a1: 0x93f1, 0x14a2: 0x9419, 0x14a3: 0x9441,\n\t0x14a4: 0x9469, 0x14a5: 0x9491, 0x14a6: 0x94b9, 0x14a7: 0x94e1, 0x14a8: 0x9079, 0x14a9: 0x9509,\n\t0x14aa: 0x9531, 0x14ab: 0x9559, 0x14ac: 0x9581, 0x14ad: 0x9491, 0x14ae: 0x94b9, 0x14af: 0x94e1,\n\t0x14b0: 0x9079, 0x14b1: 0x9051, 0x14b2: 0x90a1, 0x14b3: 0x8211, 0x14b4: 0x8059, 0x14b5: 0x8081,\n\t0x14b6: 0x80a9, 0x14b7: 0x9491, 0x14b8: 0x94b9, 0x14b9: 0x94e1, 0x14ba: 0x8211, 0x14bb: 0x8239,\n\t0x14bc: 0x95a9, 0x14bd: 0x95a9, 0x14be: 0x0018, 0x14bf: 0x0018,\n\t// Block 0x53, offset 0x14c0\n\t0x14c0: 0x0040, 0x14c1: 0x0040, 0x14c2: 0x0040, 0x14c3: 0x0040, 0x14c4: 0x0040, 0x14c5: 0x0040,\n\t0x14c6: 0x0040, 0x14c7: 0x0040, 0x14c8: 0x0040, 0x14c9: 0x0040, 0x14ca: 0x0040, 0x14cb: 0x0040,\n\t0x14cc: 0x0040, 0x14cd: 0x0040, 0x14ce: 0x0040, 0x14cf: 0x0040, 0x14d0: 0x95d1, 0x14d1: 0x9609,\n\t0x14d2: 0x9609, 0x14d3: 0x9641, 0x14d4: 0x9679, 0x14d5: 0x96b1, 0x14d6: 0x96e9, 0x14d7: 0x9721,\n\t0x14d8: 0x9759, 0x14d9: 0x9759, 0x14da: 0x9791, 0x14db: 0x97c9, 0x14dc: 0x9801, 0x14dd: 0x9839,\n\t0x14de: 0x9871, 0x14df: 0x98a9, 0x14e0: 0x98a9, 0x14e1: 0x98e1, 0x14e2: 0x9919, 0x14e3: 0x9919,\n\t0x14e4: 0x9951, 0x14e5: 0x9951, 0x14e6: 0x9989, 0x14e7: 0x99c1, 0x14e8: 0x99c1, 0x14e9: 0x99f9,\n\t0x14ea: 0x9a31, 0x14eb: 0x9a31, 0x14ec: 0x9a69, 0x14ed: 0x9a69, 0x14ee: 0x9aa1, 0x14ef: 0x9ad9,\n\t0x14f0: 0x9ad9, 0x14f1: 0x9b11, 0x14f2: 0x9b11, 0x14f3: 0x9b49, 0x14f4: 0x9b81, 0x14f5: 0x9bb9,\n\t0x14f6: 0x9bf1, 0x14f7: 0x9bf1, 0x14f8: 0x9c29, 0x14f9: 0x9c61, 0x14fa: 0x9c99, 0x14fb: 0x9cd1,\n\t0x14fc: 0x9d09, 0x14fd: 0x9d09, 0x14fe: 0x9d41, 0x14ff: 0x9d79,\n\t// Block 0x54, offset 0x1500\n\t0x1500: 0xa949, 0x1501: 0xa981, 0x1502: 0xa9b9, 0x1503: 0xa8a1, 0x1504: 0x9bb9, 0x1505: 0x9989,\n\t0x1506: 0xa9f1, 0x1507: 0xaa29, 0x1508: 0x0040, 0x1509: 0x0040, 0x150a: 0x0040, 0x150b: 0x0040,\n\t0x150c: 0x0040, 0x150d: 0x0040, 0x150e: 0x0040, 0x150f: 0x0040, 0x1510: 0x0040, 0x1511: 0x0040,\n\t0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x0040, 0x1515: 0x0040, 0x1516: 0x0040, 0x1517: 0x0040,\n\t0x1518: 0x0040, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040,\n\t0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x0040, 0x1521: 0x0040, 0x1522: 0x0040, 0x1523: 0x0040,\n\t0x1524: 0x0040, 0x1525: 0x0040, 0x1526: 0x0040, 0x1527: 0x0040, 0x1528: 0x0040, 0x1529: 0x0040,\n\t0x152a: 0x0040, 0x152b: 0x0040, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040,\n\t0x1530: 0xaa61, 0x1531: 0xaa99, 0x1532: 0xaad1, 0x1533: 0xab19, 0x1534: 0xab61, 0x1535: 0xaba9,\n\t0x1536: 0xabf1, 0x1537: 0xac39, 0x1538: 0xac81, 0x1539: 0xacc9, 0x153a: 0xad02, 0x153b: 0xae12,\n\t0x153c: 0xae91, 0x153d: 0x0018, 0x153e: 0x0040, 0x153f: 0x0040,\n\t// Block 0x55, offset 0x1540\n\t0x1540: 0x33c0, 0x1541: 0x33c0, 0x1542: 0x33c0, 0x1543: 0x33c0, 0x1544: 0x33c0, 0x1545: 0x33c0,\n\t0x1546: 0x33c0, 0x1547: 0x33c0, 0x1548: 0x33c0, 0x1549: 0x33c0, 0x154a: 0x33c0, 0x154b: 0x33c0,\n\t0x154c: 0x33c0, 0x154d: 0x33c0, 0x154e: 0x33c0, 0x154f: 0x33c0, 0x1550: 0xaeda, 0x1551: 0x7d55,\n\t0x1552: 0x0040, 0x1553: 0xaeea, 0x1554: 0x03c2, 0x1555: 0xaefa, 0x1556: 0xaf0a, 0x1557: 0x7d75,\n\t0x1558: 0x7d95, 0x1559: 0x0040, 0x155a: 0x0040, 0x155b: 0x0040, 0x155c: 0x0040, 0x155d: 0x0040,\n\t0x155e: 0x0040, 0x155f: 0x0040, 0x1560: 0x3308, 0x1561: 0x3308, 0x1562: 0x3308, 0x1563: 0x3308,\n\t0x1564: 0x3308, 0x1565: 0x3308, 0x1566: 0x3308, 0x1567: 0x3308, 0x1568: 0x3308, 0x1569: 0x3308,\n\t0x156a: 0x3308, 0x156b: 0x3308, 0x156c: 0x3308, 0x156d: 0x3308, 0x156e: 0x3308, 0x156f: 0x3308,\n\t0x1570: 0x0040, 0x1571: 0x7db5, 0x1572: 0x7dd5, 0x1573: 0xaf1a, 0x1574: 0xaf1a, 0x1575: 0x1fd2,\n\t0x1576: 0x1fe2, 0x1577: 0xaf2a, 0x1578: 0xaf3a, 0x1579: 0x7df5, 0x157a: 0x7e15, 0x157b: 0x7e35,\n\t0x157c: 0x7df5, 0x157d: 0x7e55, 0x157e: 0x7e75, 0x157f: 0x7e55,\n\t// Block 0x56, offset 0x1580\n\t0x1580: 0x7e95, 0x1581: 0x7eb5, 0x1582: 0x7ed5, 0x1583: 0x7eb5, 0x1584: 0x7ef5, 0x1585: 0x0018,\n\t0x1586: 0x0018, 0x1587: 0xaf4a, 0x1588: 0xaf5a, 0x1589: 0x7f16, 0x158a: 0x7f36, 0x158b: 0x7f56,\n\t0x158c: 0x7f76, 0x158d: 0xaf1a, 0x158e: 0xaf1a, 0x158f: 0xaf1a, 0x1590: 0xaeda, 0x1591: 0x7f95,\n\t0x1592: 0x0040, 0x1593: 0x0040, 0x1594: 0x03c2, 0x1595: 0xaeea, 0x1596: 0xaf0a, 0x1597: 0xaefa,\n\t0x1598: 0x7fb5, 0x1599: 0x1fd2, 0x159a: 0x1fe2, 0x159b: 0xaf2a, 0x159c: 0xaf3a, 0x159d: 0x7e95,\n\t0x159e: 0x7ef5, 0x159f: 0xaf6a, 0x15a0: 0xaf7a, 0x15a1: 0xaf8a, 0x15a2: 0x1fb2, 0x15a3: 0xaf99,\n\t0x15a4: 0xafaa, 0x15a5: 0xafba, 0x15a6: 0x1fc2, 0x15a7: 0x0040, 0x15a8: 0xafca, 0x15a9: 0xafda,\n\t0x15aa: 0xafea, 0x15ab: 0xaffa, 0x15ac: 0x0040, 0x15ad: 0x0040, 0x15ae: 0x0040, 0x15af: 0x0040,\n\t0x15b0: 0x7fd6, 0x15b1: 0xb009, 0x15b2: 0x7ff6, 0x15b3: 0x0808, 0x15b4: 0x8016, 0x15b5: 0x0040,\n\t0x15b6: 0x8036, 0x15b7: 0xb031, 0x15b8: 0x8056, 0x15b9: 0xb059, 0x15ba: 0x8076, 0x15bb: 0xb081,\n\t0x15bc: 0x8096, 0x15bd: 0xb0a9, 0x15be: 0x80b6, 0x15bf: 0xb0d1,\n\t// Block 0x57, offset 0x15c0\n\t0x15c0: 0xb0f9, 0x15c1: 0xb111, 0x15c2: 0xb111, 0x15c3: 0xb129, 0x15c4: 0xb129, 0x15c5: 0xb141,\n\t0x15c6: 0xb141, 0x15c7: 0xb159, 0x15c8: 0xb159, 0x15c9: 0xb171, 0x15ca: 0xb171, 0x15cb: 0xb171,\n\t0x15cc: 0xb171, 0x15cd: 0xb189, 0x15ce: 0xb189, 0x15cf: 0xb1a1, 0x15d0: 0xb1a1, 0x15d1: 0xb1a1,\n\t0x15d2: 0xb1a1, 0x15d3: 0xb1b9, 0x15d4: 0xb1b9, 0x15d5: 0xb1d1, 0x15d6: 0xb1d1, 0x15d7: 0xb1d1,\n\t0x15d8: 0xb1d1, 0x15d9: 0xb1e9, 0x15da: 0xb1e9, 0x15db: 0xb1e9, 0x15dc: 0xb1e9, 0x15dd: 0xb201,\n\t0x15de: 0xb201, 0x15df: 0xb201, 0x15e0: 0xb201, 0x15e1: 0xb219, 0x15e2: 0xb219, 0x15e3: 0xb219,\n\t0x15e4: 0xb219, 0x15e5: 0xb231, 0x15e6: 0xb231, 0x15e7: 0xb231, 0x15e8: 0xb231, 0x15e9: 0xb249,\n\t0x15ea: 0xb249, 0x15eb: 0xb261, 0x15ec: 0xb261, 0x15ed: 0xb279, 0x15ee: 0xb279, 0x15ef: 0xb291,\n\t0x15f0: 0xb291, 0x15f1: 0xb2a9, 0x15f2: 0xb2a9, 0x15f3: 0xb2a9, 0x15f4: 0xb2a9, 0x15f5: 0xb2c1,\n\t0x15f6: 0xb2c1, 0x15f7: 0xb2c1, 0x15f8: 0xb2c1, 0x15f9: 0xb2d9, 0x15fa: 0xb2d9, 0x15fb: 0xb2d9,\n\t0x15fc: 0xb2d9, 0x15fd: 0xb2f1, 0x15fe: 0xb2f1, 0x15ff: 0xb2f1,\n\t// Block 0x58, offset 0x1600\n\t0x1600: 0xb2f1, 0x1601: 0xb309, 0x1602: 0xb309, 0x1603: 0xb309, 0x1604: 0xb309, 0x1605: 0xb321,\n\t0x1606: 0xb321, 0x1607: 0xb321, 0x1608: 0xb321, 0x1609: 0xb339, 0x160a: 0xb339, 0x160b: 0xb339,\n\t0x160c: 0xb339, 0x160d: 0xb351, 0x160e: 0xb351, 0x160f: 0xb351, 0x1610: 0xb351, 0x1611: 0xb369,\n\t0x1612: 0xb369, 0x1613: 0xb369, 0x1614: 0xb369, 0x1615: 0xb381, 0x1616: 0xb381, 0x1617: 0xb381,\n\t0x1618: 0xb381, 0x1619: 0xb399, 0x161a: 0xb399, 0x161b: 0xb399, 0x161c: 0xb399, 0x161d: 0xb3b1,\n\t0x161e: 0xb3b1, 0x161f: 0xb3b1, 0x1620: 0xb3b1, 0x1621: 0xb3c9, 0x1622: 0xb3c9, 0x1623: 0xb3c9,\n\t0x1624: 0xb3c9, 0x1625: 0xb3e1, 0x1626: 0xb3e1, 0x1627: 0xb3e1, 0x1628: 0xb3e1, 0x1629: 0xb3f9,\n\t0x162a: 0xb3f9, 0x162b: 0xb3f9, 0x162c: 0xb3f9, 0x162d: 0xb411, 0x162e: 0xb411, 0x162f: 0x7ab1,\n\t0x1630: 0x7ab1, 0x1631: 0xb429, 0x1632: 0xb429, 0x1633: 0xb429, 0x1634: 0xb429, 0x1635: 0xb441,\n\t0x1636: 0xb441, 0x1637: 0xb469, 0x1638: 0xb469, 0x1639: 0xb491, 0x163a: 0xb491, 0x163b: 0xb4b9,\n\t0x163c: 0xb4b9, 0x163d: 0x0040, 0x163e: 0x0040, 0x163f: 0x03c0,\n\t// Block 0x59, offset 0x1640\n\t0x1640: 0x0040, 0x1641: 0xaefa, 0x1642: 0xb4e2, 0x1643: 0xaf6a, 0x1644: 0xafda, 0x1645: 0xafea,\n\t0x1646: 0xaf7a, 0x1647: 0xb4f2, 0x1648: 0x1fd2, 0x1649: 0x1fe2, 0x164a: 0xaf8a, 0x164b: 0x1fb2,\n\t0x164c: 0xaeda, 0x164d: 0xaf99, 0x164e: 0x29d1, 0x164f: 0xb502, 0x1650: 0x1f41, 0x1651: 0x00c9,\n\t0x1652: 0x0069, 0x1653: 0x0079, 0x1654: 0x1f51, 0x1655: 0x1f61, 0x1656: 0x1f71, 0x1657: 0x1f81,\n\t0x1658: 0x1f91, 0x1659: 0x1fa1, 0x165a: 0xaeea, 0x165b: 0x03c2, 0x165c: 0xafaa, 0x165d: 0x1fc2,\n\t0x165e: 0xafba, 0x165f: 0xaf0a, 0x1660: 0xaffa, 0x1661: 0x0039, 0x1662: 0x0ee9, 0x1663: 0x1159,\n\t0x1664: 0x0ef9, 0x1665: 0x0f09, 0x1666: 0x1199, 0x1667: 0x0f31, 0x1668: 0x0249, 0x1669: 0x0f41,\n\t0x166a: 0x0259, 0x166b: 0x0f51, 0x166c: 0x0359, 0x166d: 0x0f61, 0x166e: 0x0f71, 0x166f: 0x00d9,\n\t0x1670: 0x0f99, 0x1671: 0x2039, 0x1672: 0x0269, 0x1673: 0x01d9, 0x1674: 0x0fa9, 0x1675: 0x0fb9,\n\t0x1676: 0x1089, 0x1677: 0x0279, 0x1678: 0x0369, 0x1679: 0x0289, 0x167a: 0x13d1, 0x167b: 0xaf4a,\n\t0x167c: 0xafca, 0x167d: 0xaf5a, 0x167e: 0xb512, 0x167f: 0xaf1a,\n\t// Block 0x5a, offset 0x1680\n\t0x1680: 0x1caa, 0x1681: 0x0039, 0x1682: 0x0ee9, 0x1683: 0x1159, 0x1684: 0x0ef9, 0x1685: 0x0f09,\n\t0x1686: 0x1199, 0x1687: 0x0f31, 0x1688: 0x0249, 0x1689: 0x0f41, 0x168a: 0x0259, 0x168b: 0x0f51,\n\t0x168c: 0x0359, 0x168d: 0x0f61, 0x168e: 0x0f71, 0x168f: 0x00d9, 0x1690: 0x0f99, 0x1691: 0x2039,\n\t0x1692: 0x0269, 0x1693: 0x01d9, 0x1694: 0x0fa9, 0x1695: 0x0fb9, 0x1696: 0x1089, 0x1697: 0x0279,\n\t0x1698: 0x0369, 0x1699: 0x0289, 0x169a: 0x13d1, 0x169b: 0xaf2a, 0x169c: 0xb522, 0x169d: 0xaf3a,\n\t0x169e: 0xb532, 0x169f: 0x80d5, 0x16a0: 0x80f5, 0x16a1: 0x29d1, 0x16a2: 0x8115, 0x16a3: 0x8115,\n\t0x16a4: 0x8135, 0x16a5: 0x8155, 0x16a6: 0x8175, 0x16a7: 0x8195, 0x16a8: 0x81b5, 0x16a9: 0x81d5,\n\t0x16aa: 0x81f5, 0x16ab: 0x8215, 0x16ac: 0x8235, 0x16ad: 0x8255, 0x16ae: 0x8275, 0x16af: 0x8295,\n\t0x16b0: 0x82b5, 0x16b1: 0x82d5, 0x16b2: 0x82f5, 0x16b3: 0x8315, 0x16b4: 0x8335, 0x16b5: 0x8355,\n\t0x16b6: 0x8375, 0x16b7: 0x8395, 0x16b8: 0x83b5, 0x16b9: 0x83d5, 0x16ba: 0x83f5, 0x16bb: 0x8415,\n\t0x16bc: 0x81b5, 0x16bd: 0x8435, 0x16be: 0x8455, 0x16bf: 0x8215,\n\t// Block 0x5b, offset 0x16c0\n\t0x16c0: 0x8475, 0x16c1: 0x8495, 0x16c2: 0x84b5, 0x16c3: 0x84d5, 0x16c4: 0x84f5, 0x16c5: 0x8515,\n\t0x16c6: 0x8535, 0x16c7: 0x8555, 0x16c8: 0x84d5, 0x16c9: 0x8575, 0x16ca: 0x84d5, 0x16cb: 0x8595,\n\t0x16cc: 0x8595, 0x16cd: 0x85b5, 0x16ce: 0x85b5, 0x16cf: 0x85d5, 0x16d0: 0x8515, 0x16d1: 0x85f5,\n\t0x16d2: 0x8615, 0x16d3: 0x85f5, 0x16d4: 0x8635, 0x16d5: 0x8615, 0x16d6: 0x8655, 0x16d7: 0x8655,\n\t0x16d8: 0x8675, 0x16d9: 0x8675, 0x16da: 0x8695, 0x16db: 0x8695, 0x16dc: 0x8615, 0x16dd: 0x8115,\n\t0x16de: 0x86b5, 0x16df: 0x86d5, 0x16e0: 0x0040, 0x16e1: 0x86f5, 0x16e2: 0x8715, 0x16e3: 0x8735,\n\t0x16e4: 0x8755, 0x16e5: 0x8735, 0x16e6: 0x8775, 0x16e7: 0x8795, 0x16e8: 0x87b5, 0x16e9: 0x87b5,\n\t0x16ea: 0x87d5, 0x16eb: 0x87d5, 0x16ec: 0x87f5, 0x16ed: 0x87f5, 0x16ee: 0x87d5, 0x16ef: 0x87d5,\n\t0x16f0: 0x8815, 0x16f1: 0x8835, 0x16f2: 0x8855, 0x16f3: 0x8875, 0x16f4: 0x8895, 0x16f5: 0x88b5,\n\t0x16f6: 0x88b5, 0x16f7: 0x88b5, 0x16f8: 0x88d5, 0x16f9: 0x88d5, 0x16fa: 0x88d5, 0x16fb: 0x88d5,\n\t0x16fc: 0x87b5, 0x16fd: 0x87b5, 0x16fe: 0x87b5, 0x16ff: 0x0040,\n\t// Block 0x5c, offset 0x1700\n\t0x1700: 0x0040, 0x1701: 0x0040, 0x1702: 0x8715, 0x1703: 0x86f5, 0x1704: 0x88f5, 0x1705: 0x86f5,\n\t0x1706: 0x8715, 0x1707: 0x86f5, 0x1708: 0x0040, 0x1709: 0x0040, 0x170a: 0x8915, 0x170b: 0x8715,\n\t0x170c: 0x8935, 0x170d: 0x88f5, 0x170e: 0x8935, 0x170f: 0x8715, 0x1710: 0x0040, 0x1711: 0x0040,\n\t0x1712: 0x8955, 0x1713: 0x8975, 0x1714: 0x8875, 0x1715: 0x8935, 0x1716: 0x88f5, 0x1717: 0x8935,\n\t0x1718: 0x0040, 0x1719: 0x0040, 0x171a: 0x8995, 0x171b: 0x89b5, 0x171c: 0x8995, 0x171d: 0x0040,\n\t0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0xb541, 0x1721: 0xb559, 0x1722: 0xb571, 0x1723: 0x89d6,\n\t0x1724: 0xb589, 0x1725: 0xb5a1, 0x1726: 0x89f5, 0x1727: 0x0040, 0x1728: 0x8a15, 0x1729: 0x8a35,\n\t0x172a: 0x8a55, 0x172b: 0x8a35, 0x172c: 0x8a75, 0x172d: 0x8a95, 0x172e: 0x8ab5, 0x172f: 0x0040,\n\t0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040,\n\t0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0340, 0x173a: 0x0340, 0x173b: 0x0340,\n\t0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040,\n\t// Block 0x5d, offset 0x1740\n\t0x1740: 0x0a08, 0x1741: 0x0a08, 0x1742: 0x0a08, 0x1743: 0x0a08, 0x1744: 0x0a08, 0x1745: 0x0c08,\n\t0x1746: 0x0808, 0x1747: 0x0c08, 0x1748: 0x0818, 0x1749: 0x0c08, 0x174a: 0x0c08, 0x174b: 0x0808,\n\t0x174c: 0x0808, 0x174d: 0x0908, 0x174e: 0x0c08, 0x174f: 0x0c08, 0x1750: 0x0c08, 0x1751: 0x0c08,\n\t0x1752: 0x0c08, 0x1753: 0x0a08, 0x1754: 0x0a08, 0x1755: 0x0a08, 0x1756: 0x0a08, 0x1757: 0x0908,\n\t0x1758: 0x0a08, 0x1759: 0x0a08, 0x175a: 0x0a08, 0x175b: 0x0a08, 0x175c: 0x0a08, 0x175d: 0x0c08,\n\t0x175e: 0x0a08, 0x175f: 0x0a08, 0x1760: 0x0a08, 0x1761: 0x0c08, 0x1762: 0x0808, 0x1763: 0x0808,\n\t0x1764: 0x0c08, 0x1765: 0x3308, 0x1766: 0x3308, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0040,\n\t0x176a: 0x0040, 0x176b: 0x0a18, 0x176c: 0x0a18, 0x176d: 0x0a18, 0x176e: 0x0a18, 0x176f: 0x0c18,\n\t0x1770: 0x0818, 0x1771: 0x0818, 0x1772: 0x0818, 0x1773: 0x0818, 0x1774: 0x0818, 0x1775: 0x0818,\n\t0x1776: 0x0818, 0x1777: 0x0040, 0x1778: 0x0040, 0x1779: 0x0040, 0x177a: 0x0040, 0x177b: 0x0040,\n\t0x177c: 0x0040, 0x177d: 0x0040, 0x177e: 0x0040, 0x177f: 0x0040,\n\t// Block 0x5e, offset 0x1780\n\t0x1780: 0x0a08, 0x1781: 0x0c08, 0x1782: 0x0a08, 0x1783: 0x0c08, 0x1784: 0x0c08, 0x1785: 0x0c08,\n\t0x1786: 0x0a08, 0x1787: 0x0a08, 0x1788: 0x0a08, 0x1789: 0x0c08, 0x178a: 0x0a08, 0x178b: 0x0a08,\n\t0x178c: 0x0c08, 0x178d: 0x0a08, 0x178e: 0x0c08, 0x178f: 0x0c08, 0x1790: 0x0a08, 0x1791: 0x0c08,\n\t0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x0040,\n\t0x1798: 0x0040, 0x1799: 0x0818, 0x179a: 0x0818, 0x179b: 0x0818, 0x179c: 0x0818, 0x179d: 0x0040,\n\t0x179e: 0x0040, 0x179f: 0x0040, 0x17a0: 0x0040, 0x17a1: 0x0040, 0x17a2: 0x0040, 0x17a3: 0x0040,\n\t0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x0040, 0x17a7: 0x0040, 0x17a8: 0x0040, 0x17a9: 0x0c18,\n\t0x17aa: 0x0c18, 0x17ab: 0x0c18, 0x17ac: 0x0c18, 0x17ad: 0x0a18, 0x17ae: 0x0a18, 0x17af: 0x0818,\n\t0x17b0: 0x0040, 0x17b1: 0x0040, 0x17b2: 0x0040, 0x17b3: 0x0040, 0x17b4: 0x0040, 0x17b5: 0x0040,\n\t0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040,\n\t0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040,\n\t// Block 0x5f, offset 0x17c0\n\t0x17c0: 0x3308, 0x17c1: 0x3308, 0x17c2: 0x3008, 0x17c3: 0x3008, 0x17c4: 0x0040, 0x17c5: 0x0008,\n\t0x17c6: 0x0008, 0x17c7: 0x0008, 0x17c8: 0x0008, 0x17c9: 0x0008, 0x17ca: 0x0008, 0x17cb: 0x0008,\n\t0x17cc: 0x0008, 0x17cd: 0x0040, 0x17ce: 0x0040, 0x17cf: 0x0008, 0x17d0: 0x0008, 0x17d1: 0x0040,\n\t0x17d2: 0x0040, 0x17d3: 0x0008, 0x17d4: 0x0008, 0x17d5: 0x0008, 0x17d6: 0x0008, 0x17d7: 0x0008,\n\t0x17d8: 0x0008, 0x17d9: 0x0008, 0x17da: 0x0008, 0x17db: 0x0008, 0x17dc: 0x0008, 0x17dd: 0x0008,\n\t0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x0008, 0x17e3: 0x0008,\n\t0x17e4: 0x0008, 0x17e5: 0x0008, 0x17e6: 0x0008, 0x17e7: 0x0008, 0x17e8: 0x0008, 0x17e9: 0x0040,\n\t0x17ea: 0x0008, 0x17eb: 0x0008, 0x17ec: 0x0008, 0x17ed: 0x0008, 0x17ee: 0x0008, 0x17ef: 0x0008,\n\t0x17f0: 0x0008, 0x17f1: 0x0040, 0x17f2: 0x0008, 0x17f3: 0x0008, 0x17f4: 0x0040, 0x17f5: 0x0008,\n\t0x17f6: 0x0008, 0x17f7: 0x0008, 0x17f8: 0x0008, 0x17f9: 0x0008, 0x17fa: 0x0040, 0x17fb: 0x3308,\n\t0x17fc: 0x3308, 0x17fd: 0x0008, 0x17fe: 0x3008, 0x17ff: 0x3008,\n\t// Block 0x60, offset 0x1800\n\t0x1800: 0x3308, 0x1801: 0x3008, 0x1802: 0x3008, 0x1803: 0x3008, 0x1804: 0x3008, 0x1805: 0x0040,\n\t0x1806: 0x0040, 0x1807: 0x3008, 0x1808: 0x3008, 0x1809: 0x0040, 0x180a: 0x0040, 0x180b: 0x3008,\n\t0x180c: 0x3008, 0x180d: 0x3808, 0x180e: 0x0040, 0x180f: 0x0040, 0x1810: 0x0008, 0x1811: 0x0040,\n\t0x1812: 0x0040, 0x1813: 0x0040, 0x1814: 0x0040, 0x1815: 0x0040, 0x1816: 0x0040, 0x1817: 0x3008,\n\t0x1818: 0x0040, 0x1819: 0x0040, 0x181a: 0x0040, 0x181b: 0x0040, 0x181c: 0x0040, 0x181d: 0x0008,\n\t0x181e: 0x0008, 0x181f: 0x0008, 0x1820: 0x0008, 0x1821: 0x0008, 0x1822: 0x3008, 0x1823: 0x3008,\n\t0x1824: 0x0040, 0x1825: 0x0040, 0x1826: 0x3308, 0x1827: 0x3308, 0x1828: 0x3308, 0x1829: 0x3308,\n\t0x182a: 0x3308, 0x182b: 0x3308, 0x182c: 0x3308, 0x182d: 0x0040, 0x182e: 0x0040, 0x182f: 0x0040,\n\t0x1830: 0x3308, 0x1831: 0x3308, 0x1832: 0x3308, 0x1833: 0x3308, 0x1834: 0x3308, 0x1835: 0x0040,\n\t0x1836: 0x0040, 0x1837: 0x0040, 0x1838: 0x0040, 0x1839: 0x0040, 0x183a: 0x0040, 0x183b: 0x0040,\n\t0x183c: 0x0040, 0x183d: 0x0040, 0x183e: 0x0040, 0x183f: 0x0040,\n\t// Block 0x61, offset 0x1840\n\t0x1840: 0x0039, 0x1841: 0x0ee9, 0x1842: 0x1159, 0x1843: 0x0ef9, 0x1844: 0x0f09, 0x1845: 0x1199,\n\t0x1846: 0x0f31, 0x1847: 0x0249, 0x1848: 0x0f41, 0x1849: 0x0259, 0x184a: 0x0f51, 0x184b: 0x0359,\n\t0x184c: 0x0f61, 0x184d: 0x0f71, 0x184e: 0x00d9, 0x184f: 0x0f99, 0x1850: 0x2039, 0x1851: 0x0269,\n\t0x1852: 0x01d9, 0x1853: 0x0fa9, 0x1854: 0x0fb9, 0x1855: 0x1089, 0x1856: 0x0279, 0x1857: 0x0369,\n\t0x1858: 0x0289, 0x1859: 0x13d1, 0x185a: 0x0039, 0x185b: 0x0ee9, 0x185c: 0x1159, 0x185d: 0x0ef9,\n\t0x185e: 0x0f09, 0x185f: 0x1199, 0x1860: 0x0f31, 0x1861: 0x0249, 0x1862: 0x0f41, 0x1863: 0x0259,\n\t0x1864: 0x0f51, 0x1865: 0x0359, 0x1866: 0x0f61, 0x1867: 0x0f71, 0x1868: 0x00d9, 0x1869: 0x0f99,\n\t0x186a: 0x2039, 0x186b: 0x0269, 0x186c: 0x01d9, 0x186d: 0x0fa9, 0x186e: 0x0fb9, 0x186f: 0x1089,\n\t0x1870: 0x0279, 0x1871: 0x0369, 0x1872: 0x0289, 0x1873: 0x13d1, 0x1874: 0x0039, 0x1875: 0x0ee9,\n\t0x1876: 0x1159, 0x1877: 0x0ef9, 0x1878: 0x0f09, 0x1879: 0x1199, 0x187a: 0x0f31, 0x187b: 0x0249,\n\t0x187c: 0x0f41, 0x187d: 0x0259, 0x187e: 0x0f51, 0x187f: 0x0359,\n\t// Block 0x62, offset 0x1880\n\t0x1880: 0x0f61, 0x1881: 0x0f71, 0x1882: 0x00d9, 0x1883: 0x0f99, 0x1884: 0x2039, 0x1885: 0x0269,\n\t0x1886: 0x01d9, 0x1887: 0x0fa9, 0x1888: 0x0fb9, 0x1889: 0x1089, 0x188a: 0x0279, 0x188b: 0x0369,\n\t0x188c: 0x0289, 0x188d: 0x13d1, 0x188e: 0x0039, 0x188f: 0x0ee9, 0x1890: 0x1159, 0x1891: 0x0ef9,\n\t0x1892: 0x0f09, 0x1893: 0x1199, 0x1894: 0x0f31, 0x1895: 0x0040, 0x1896: 0x0f41, 0x1897: 0x0259,\n\t0x1898: 0x0f51, 0x1899: 0x0359, 0x189a: 0x0f61, 0x189b: 0x0f71, 0x189c: 0x00d9, 0x189d: 0x0f99,\n\t0x189e: 0x2039, 0x189f: 0x0269, 0x18a0: 0x01d9, 0x18a1: 0x0fa9, 0x18a2: 0x0fb9, 0x18a3: 0x1089,\n\t0x18a4: 0x0279, 0x18a5: 0x0369, 0x18a6: 0x0289, 0x18a7: 0x13d1, 0x18a8: 0x0039, 0x18a9: 0x0ee9,\n\t0x18aa: 0x1159, 0x18ab: 0x0ef9, 0x18ac: 0x0f09, 0x18ad: 0x1199, 0x18ae: 0x0f31, 0x18af: 0x0249,\n\t0x18b0: 0x0f41, 0x18b1: 0x0259, 0x18b2: 0x0f51, 0x18b3: 0x0359, 0x18b4: 0x0f61, 0x18b5: 0x0f71,\n\t0x18b6: 0x00d9, 0x18b7: 0x0f99, 0x18b8: 0x2039, 0x18b9: 0x0269, 0x18ba: 0x01d9, 0x18bb: 0x0fa9,\n\t0x18bc: 0x0fb9, 0x18bd: 0x1089, 0x18be: 0x0279, 0x18bf: 0x0369,\n\t// Block 0x63, offset 0x18c0\n\t0x18c0: 0x0289, 0x18c1: 0x13d1, 0x18c2: 0x0039, 0x18c3: 0x0ee9, 0x18c4: 0x1159, 0x18c5: 0x0ef9,\n\t0x18c6: 0x0f09, 0x18c7: 0x1199, 0x18c8: 0x0f31, 0x18c9: 0x0249, 0x18ca: 0x0f41, 0x18cb: 0x0259,\n\t0x18cc: 0x0f51, 0x18cd: 0x0359, 0x18ce: 0x0f61, 0x18cf: 0x0f71, 0x18d0: 0x00d9, 0x18d1: 0x0f99,\n\t0x18d2: 0x2039, 0x18d3: 0x0269, 0x18d4: 0x01d9, 0x18d5: 0x0fa9, 0x18d6: 0x0fb9, 0x18d7: 0x1089,\n\t0x18d8: 0x0279, 0x18d9: 0x0369, 0x18da: 0x0289, 0x18db: 0x13d1, 0x18dc: 0x0039, 0x18dd: 0x0040,\n\t0x18de: 0x1159, 0x18df: 0x0ef9, 0x18e0: 0x0040, 0x18e1: 0x0040, 0x18e2: 0x0f31, 0x18e3: 0x0040,\n\t0x18e4: 0x0040, 0x18e5: 0x0259, 0x18e6: 0x0f51, 0x18e7: 0x0040, 0x18e8: 0x0040, 0x18e9: 0x0f71,\n\t0x18ea: 0x00d9, 0x18eb: 0x0f99, 0x18ec: 0x2039, 0x18ed: 0x0040, 0x18ee: 0x01d9, 0x18ef: 0x0fa9,\n\t0x18f0: 0x0fb9, 0x18f1: 0x1089, 0x18f2: 0x0279, 0x18f3: 0x0369, 0x18f4: 0x0289, 0x18f5: 0x13d1,\n\t0x18f6: 0x0039, 0x18f7: 0x0ee9, 0x18f8: 0x1159, 0x18f9: 0x0ef9, 0x18fa: 0x0040, 0x18fb: 0x1199,\n\t0x18fc: 0x0040, 0x18fd: 0x0249, 0x18fe: 0x0f41, 0x18ff: 0x0259,\n\t// Block 0x64, offset 0x1900\n\t0x1900: 0x0f51, 0x1901: 0x0359, 0x1902: 0x0f61, 0x1903: 0x0f71, 0x1904: 0x0040, 0x1905: 0x0f99,\n\t0x1906: 0x2039, 0x1907: 0x0269, 0x1908: 0x01d9, 0x1909: 0x0fa9, 0x190a: 0x0fb9, 0x190b: 0x1089,\n\t0x190c: 0x0279, 0x190d: 0x0369, 0x190e: 0x0289, 0x190f: 0x13d1, 0x1910: 0x0039, 0x1911: 0x0ee9,\n\t0x1912: 0x1159, 0x1913: 0x0ef9, 0x1914: 0x0f09, 0x1915: 0x1199, 0x1916: 0x0f31, 0x1917: 0x0249,\n\t0x1918: 0x0f41, 0x1919: 0x0259, 0x191a: 0x0f51, 0x191b: 0x0359, 0x191c: 0x0f61, 0x191d: 0x0f71,\n\t0x191e: 0x00d9, 0x191f: 0x0f99, 0x1920: 0x2039, 0x1921: 0x0269, 0x1922: 0x01d9, 0x1923: 0x0fa9,\n\t0x1924: 0x0fb9, 0x1925: 0x1089, 0x1926: 0x0279, 0x1927: 0x0369, 0x1928: 0x0289, 0x1929: 0x13d1,\n\t0x192a: 0x0039, 0x192b: 0x0ee9, 0x192c: 0x1159, 0x192d: 0x0ef9, 0x192e: 0x0f09, 0x192f: 0x1199,\n\t0x1930: 0x0f31, 0x1931: 0x0249, 0x1932: 0x0f41, 0x1933: 0x0259, 0x1934: 0x0f51, 0x1935: 0x0359,\n\t0x1936: 0x0f61, 0x1937: 0x0f71, 0x1938: 0x00d9, 0x1939: 0x0f99, 0x193a: 0x2039, 0x193b: 0x0269,\n\t0x193c: 0x01d9, 0x193d: 0x0fa9, 0x193e: 0x0fb9, 0x193f: 0x1089,\n\t// Block 0x65, offset 0x1940\n\t0x1940: 0x0279, 0x1941: 0x0369, 0x1942: 0x0289, 0x1943: 0x13d1, 0x1944: 0x0039, 0x1945: 0x0ee9,\n\t0x1946: 0x0040, 0x1947: 0x0ef9, 0x1948: 0x0f09, 0x1949: 0x1199, 0x194a: 0x0f31, 0x194b: 0x0040,\n\t0x194c: 0x0040, 0x194d: 0x0259, 0x194e: 0x0f51, 0x194f: 0x0359, 0x1950: 0x0f61, 0x1951: 0x0f71,\n\t0x1952: 0x00d9, 0x1953: 0x0f99, 0x1954: 0x2039, 0x1955: 0x0040, 0x1956: 0x01d9, 0x1957: 0x0fa9,\n\t0x1958: 0x0fb9, 0x1959: 0x1089, 0x195a: 0x0279, 0x195b: 0x0369, 0x195c: 0x0289, 0x195d: 0x0040,\n\t0x195e: 0x0039, 0x195f: 0x0ee9, 0x1960: 0x1159, 0x1961: 0x0ef9, 0x1962: 0x0f09, 0x1963: 0x1199,\n\t0x1964: 0x0f31, 0x1965: 0x0249, 0x1966: 0x0f41, 0x1967: 0x0259, 0x1968: 0x0f51, 0x1969: 0x0359,\n\t0x196a: 0x0f61, 0x196b: 0x0f71, 0x196c: 0x00d9, 0x196d: 0x0f99, 0x196e: 0x2039, 0x196f: 0x0269,\n\t0x1970: 0x01d9, 0x1971: 0x0fa9, 0x1972: 0x0fb9, 0x1973: 0x1089, 0x1974: 0x0279, 0x1975: 0x0369,\n\t0x1976: 0x0289, 0x1977: 0x13d1, 0x1978: 0x0039, 0x1979: 0x0ee9, 0x197a: 0x0040, 0x197b: 0x0ef9,\n\t0x197c: 0x0f09, 0x197d: 0x1199, 0x197e: 0x0f31, 0x197f: 0x0040,\n\t// Block 0x66, offset 0x1980\n\t0x1980: 0x0f41, 0x1981: 0x0259, 0x1982: 0x0f51, 0x1983: 0x0359, 0x1984: 0x0f61, 0x1985: 0x0040,\n\t0x1986: 0x00d9, 0x1987: 0x0040, 0x1988: 0x0040, 0x1989: 0x0040, 0x198a: 0x01d9, 0x198b: 0x0fa9,\n\t0x198c: 0x0fb9, 0x198d: 0x1089, 0x198e: 0x0279, 0x198f: 0x0369, 0x1990: 0x0289, 0x1991: 0x0040,\n\t0x1992: 0x0039, 0x1993: 0x0ee9, 0x1994: 0x1159, 0x1995: 0x0ef9, 0x1996: 0x0f09, 0x1997: 0x1199,\n\t0x1998: 0x0f31, 0x1999: 0x0249, 0x199a: 0x0f41, 0x199b: 0x0259, 0x199c: 0x0f51, 0x199d: 0x0359,\n\t0x199e: 0x0f61, 0x199f: 0x0f71, 0x19a0: 0x00d9, 0x19a1: 0x0f99, 0x19a2: 0x2039, 0x19a3: 0x0269,\n\t0x19a4: 0x01d9, 0x19a5: 0x0fa9, 0x19a6: 0x0fb9, 0x19a7: 0x1089, 0x19a8: 0x0279, 0x19a9: 0x0369,\n\t0x19aa: 0x0289, 0x19ab: 0x13d1, 0x19ac: 0x0039, 0x19ad: 0x0ee9, 0x19ae: 0x1159, 0x19af: 0x0ef9,\n\t0x19b0: 0x0f09, 0x19b1: 0x1199, 0x19b2: 0x0f31, 0x19b3: 0x0249, 0x19b4: 0x0f41, 0x19b5: 0x0259,\n\t0x19b6: 0x0f51, 0x19b7: 0x0359, 0x19b8: 0x0f61, 0x19b9: 0x0f71, 0x19ba: 0x00d9, 0x19bb: 0x0f99,\n\t0x19bc: 0x2039, 0x19bd: 0x0269, 0x19be: 0x01d9, 0x19bf: 0x0fa9,\n\t// Block 0x67, offset 0x19c0\n\t0x19c0: 0x0fb9, 0x19c1: 0x1089, 0x19c2: 0x0279, 0x19c3: 0x0369, 0x19c4: 0x0289, 0x19c5: 0x13d1,\n\t0x19c6: 0x0039, 0x19c7: 0x0ee9, 0x19c8: 0x1159, 0x19c9: 0x0ef9, 0x19ca: 0x0f09, 0x19cb: 0x1199,\n\t0x19cc: 0x0f31, 0x19cd: 0x0249, 0x19ce: 0x0f41, 0x19cf: 0x0259, 0x19d0: 0x0f51, 0x19d1: 0x0359,\n\t0x19d2: 0x0f61, 0x19d3: 0x0f71, 0x19d4: 0x00d9, 0x19d5: 0x0f99, 0x19d6: 0x2039, 0x19d7: 0x0269,\n\t0x19d8: 0x01d9, 0x19d9: 0x0fa9, 0x19da: 0x0fb9, 0x19db: 0x1089, 0x19dc: 0x0279, 0x19dd: 0x0369,\n\t0x19de: 0x0289, 0x19df: 0x13d1, 0x19e0: 0x0039, 0x19e1: 0x0ee9, 0x19e2: 0x1159, 0x19e3: 0x0ef9,\n\t0x19e4: 0x0f09, 0x19e5: 0x1199, 0x19e6: 0x0f31, 0x19e7: 0x0249, 0x19e8: 0x0f41, 0x19e9: 0x0259,\n\t0x19ea: 0x0f51, 0x19eb: 0x0359, 0x19ec: 0x0f61, 0x19ed: 0x0f71, 0x19ee: 0x00d9, 0x19ef: 0x0f99,\n\t0x19f0: 0x2039, 0x19f1: 0x0269, 0x19f2: 0x01d9, 0x19f3: 0x0fa9, 0x19f4: 0x0fb9, 0x19f5: 0x1089,\n\t0x19f6: 0x0279, 0x19f7: 0x0369, 0x19f8: 0x0289, 0x19f9: 0x13d1, 0x19fa: 0x0039, 0x19fb: 0x0ee9,\n\t0x19fc: 0x1159, 0x19fd: 0x0ef9, 0x19fe: 0x0f09, 0x19ff: 0x1199,\n\t// Block 0x68, offset 0x1a00\n\t0x1a00: 0x0f31, 0x1a01: 0x0249, 0x1a02: 0x0f41, 0x1a03: 0x0259, 0x1a04: 0x0f51, 0x1a05: 0x0359,\n\t0x1a06: 0x0f61, 0x1a07: 0x0f71, 0x1a08: 0x00d9, 0x1a09: 0x0f99, 0x1a0a: 0x2039, 0x1a0b: 0x0269,\n\t0x1a0c: 0x01d9, 0x1a0d: 0x0fa9, 0x1a0e: 0x0fb9, 0x1a0f: 0x1089, 0x1a10: 0x0279, 0x1a11: 0x0369,\n\t0x1a12: 0x0289, 0x1a13: 0x13d1, 0x1a14: 0x0039, 0x1a15: 0x0ee9, 0x1a16: 0x1159, 0x1a17: 0x0ef9,\n\t0x1a18: 0x0f09, 0x1a19: 0x1199, 0x1a1a: 0x0f31, 0x1a1b: 0x0249, 0x1a1c: 0x0f41, 0x1a1d: 0x0259,\n\t0x1a1e: 0x0f51, 0x1a1f: 0x0359, 0x1a20: 0x0f61, 0x1a21: 0x0f71, 0x1a22: 0x00d9, 0x1a23: 0x0f99,\n\t0x1a24: 0x2039, 0x1a25: 0x0269, 0x1a26: 0x01d9, 0x1a27: 0x0fa9, 0x1a28: 0x0fb9, 0x1a29: 0x1089,\n\t0x1a2a: 0x0279, 0x1a2b: 0x0369, 0x1a2c: 0x0289, 0x1a2d: 0x13d1, 0x1a2e: 0x0039, 0x1a2f: 0x0ee9,\n\t0x1a30: 0x1159, 0x1a31: 0x0ef9, 0x1a32: 0x0f09, 0x1a33: 0x1199, 0x1a34: 0x0f31, 0x1a35: 0x0249,\n\t0x1a36: 0x0f41, 0x1a37: 0x0259, 0x1a38: 0x0f51, 0x1a39: 0x0359, 0x1a3a: 0x0f61, 0x1a3b: 0x0f71,\n\t0x1a3c: 0x00d9, 0x1a3d: 0x0f99, 0x1a3e: 0x2039, 0x1a3f: 0x0269,\n\t// Block 0x69, offset 0x1a40\n\t0x1a40: 0x01d9, 0x1a41: 0x0fa9, 0x1a42: 0x0fb9, 0x1a43: 0x1089, 0x1a44: 0x0279, 0x1a45: 0x0369,\n\t0x1a46: 0x0289, 0x1a47: 0x13d1, 0x1a48: 0x0039, 0x1a49: 0x0ee9, 0x1a4a: 0x1159, 0x1a4b: 0x0ef9,\n\t0x1a4c: 0x0f09, 0x1a4d: 0x1199, 0x1a4e: 0x0f31, 0x1a4f: 0x0249, 0x1a50: 0x0f41, 0x1a51: 0x0259,\n\t0x1a52: 0x0f51, 0x1a53: 0x0359, 0x1a54: 0x0f61, 0x1a55: 0x0f71, 0x1a56: 0x00d9, 0x1a57: 0x0f99,\n\t0x1a58: 0x2039, 0x1a59: 0x0269, 0x1a5a: 0x01d9, 0x1a5b: 0x0fa9, 0x1a5c: 0x0fb9, 0x1a5d: 0x1089,\n\t0x1a5e: 0x0279, 0x1a5f: 0x0369, 0x1a60: 0x0289, 0x1a61: 0x13d1, 0x1a62: 0x0039, 0x1a63: 0x0ee9,\n\t0x1a64: 0x1159, 0x1a65: 0x0ef9, 0x1a66: 0x0f09, 0x1a67: 0x1199, 0x1a68: 0x0f31, 0x1a69: 0x0249,\n\t0x1a6a: 0x0f41, 0x1a6b: 0x0259, 0x1a6c: 0x0f51, 0x1a6d: 0x0359, 0x1a6e: 0x0f61, 0x1a6f: 0x0f71,\n\t0x1a70: 0x00d9, 0x1a71: 0x0f99, 0x1a72: 0x2039, 0x1a73: 0x0269, 0x1a74: 0x01d9, 0x1a75: 0x0fa9,\n\t0x1a76: 0x0fb9, 0x1a77: 0x1089, 0x1a78: 0x0279, 0x1a79: 0x0369, 0x1a7a: 0x0289, 0x1a7b: 0x13d1,\n\t0x1a7c: 0x0039, 0x1a7d: 0x0ee9, 0x1a7e: 0x1159, 0x1a7f: 0x0ef9,\n\t// Block 0x6a, offset 0x1a80\n\t0x1a80: 0x0f09, 0x1a81: 0x1199, 0x1a82: 0x0f31, 0x1a83: 0x0249, 0x1a84: 0x0f41, 0x1a85: 0x0259,\n\t0x1a86: 0x0f51, 0x1a87: 0x0359, 0x1a88: 0x0f61, 0x1a89: 0x0f71, 0x1a8a: 0x00d9, 0x1a8b: 0x0f99,\n\t0x1a8c: 0x2039, 0x1a8d: 0x0269, 0x1a8e: 0x01d9, 0x1a8f: 0x0fa9, 0x1a90: 0x0fb9, 0x1a91: 0x1089,\n\t0x1a92: 0x0279, 0x1a93: 0x0369, 0x1a94: 0x0289, 0x1a95: 0x13d1, 0x1a96: 0x0039, 0x1a97: 0x0ee9,\n\t0x1a98: 0x1159, 0x1a99: 0x0ef9, 0x1a9a: 0x0f09, 0x1a9b: 0x1199, 0x1a9c: 0x0f31, 0x1a9d: 0x0249,\n\t0x1a9e: 0x0f41, 0x1a9f: 0x0259, 0x1aa0: 0x0f51, 0x1aa1: 0x0359, 0x1aa2: 0x0f61, 0x1aa3: 0x0f71,\n\t0x1aa4: 0x00d9, 0x1aa5: 0x0f99, 0x1aa6: 0x2039, 0x1aa7: 0x0269, 0x1aa8: 0x01d9, 0x1aa9: 0x0fa9,\n\t0x1aaa: 0x0fb9, 0x1aab: 0x1089, 0x1aac: 0x0279, 0x1aad: 0x0369, 0x1aae: 0x0289, 0x1aaf: 0x13d1,\n\t0x1ab0: 0x0039, 0x1ab1: 0x0ee9, 0x1ab2: 0x1159, 0x1ab3: 0x0ef9, 0x1ab4: 0x0f09, 0x1ab5: 0x1199,\n\t0x1ab6: 0x0f31, 0x1ab7: 0x0249, 0x1ab8: 0x0f41, 0x1ab9: 0x0259, 0x1aba: 0x0f51, 0x1abb: 0x0359,\n\t0x1abc: 0x0f61, 0x1abd: 0x0f71, 0x1abe: 0x00d9, 0x1abf: 0x0f99,\n\t// Block 0x6b, offset 0x1ac0\n\t0x1ac0: 0x2039, 0x1ac1: 0x0269, 0x1ac2: 0x01d9, 0x1ac3: 0x0fa9, 0x1ac4: 0x0fb9, 0x1ac5: 0x1089,\n\t0x1ac6: 0x0279, 0x1ac7: 0x0369, 0x1ac8: 0x0289, 0x1ac9: 0x13d1, 0x1aca: 0x0039, 0x1acb: 0x0ee9,\n\t0x1acc: 0x1159, 0x1acd: 0x0ef9, 0x1ace: 0x0f09, 0x1acf: 0x1199, 0x1ad0: 0x0f31, 0x1ad1: 0x0249,\n\t0x1ad2: 0x0f41, 0x1ad3: 0x0259, 0x1ad4: 0x0f51, 0x1ad5: 0x0359, 0x1ad6: 0x0f61, 0x1ad7: 0x0f71,\n\t0x1ad8: 0x00d9, 0x1ad9: 0x0f99, 0x1ada: 0x2039, 0x1adb: 0x0269, 0x1adc: 0x01d9, 0x1add: 0x0fa9,\n\t0x1ade: 0x0fb9, 0x1adf: 0x1089, 0x1ae0: 0x0279, 0x1ae1: 0x0369, 0x1ae2: 0x0289, 0x1ae3: 0x13d1,\n\t0x1ae4: 0xba81, 0x1ae5: 0xba99, 0x1ae6: 0x0040, 0x1ae7: 0x0040, 0x1ae8: 0xbab1, 0x1ae9: 0x1099,\n\t0x1aea: 0x10b1, 0x1aeb: 0x10c9, 0x1aec: 0xbac9, 0x1aed: 0xbae1, 0x1aee: 0xbaf9, 0x1aef: 0x1429,\n\t0x1af0: 0x1a31, 0x1af1: 0xbb11, 0x1af2: 0xbb29, 0x1af3: 0xbb41, 0x1af4: 0xbb59, 0x1af5: 0xbb71,\n\t0x1af6: 0xbb89, 0x1af7: 0x2109, 0x1af8: 0x1111, 0x1af9: 0x1429, 0x1afa: 0xbba1, 0x1afb: 0xbbb9,\n\t0x1afc: 0xbbd1, 0x1afd: 0x10e1, 0x1afe: 0x10f9, 0x1aff: 0xbbe9,\n\t// Block 0x6c, offset 0x1b00\n\t0x1b00: 0x2079, 0x1b01: 0xbc01, 0x1b02: 0xbab1, 0x1b03: 0x1099, 0x1b04: 0x10b1, 0x1b05: 0x10c9,\n\t0x1b06: 0xbac9, 0x1b07: 0xbae1, 0x1b08: 0xbaf9, 0x1b09: 0x1429, 0x1b0a: 0x1a31, 0x1b0b: 0xbb11,\n\t0x1b0c: 0xbb29, 0x1b0d: 0xbb41, 0x1b0e: 0xbb59, 0x1b0f: 0xbb71, 0x1b10: 0xbb89, 0x1b11: 0x2109,\n\t0x1b12: 0x1111, 0x1b13: 0xbba1, 0x1b14: 0xbba1, 0x1b15: 0xbbb9, 0x1b16: 0xbbd1, 0x1b17: 0x10e1,\n\t0x1b18: 0x10f9, 0x1b19: 0xbbe9, 0x1b1a: 0x2079, 0x1b1b: 0xbc21, 0x1b1c: 0xbac9, 0x1b1d: 0x1429,\n\t0x1b1e: 0xbb11, 0x1b1f: 0x10e1, 0x1b20: 0x1111, 0x1b21: 0x2109, 0x1b22: 0xbab1, 0x1b23: 0x1099,\n\t0x1b24: 0x10b1, 0x1b25: 0x10c9, 0x1b26: 0xbac9, 0x1b27: 0xbae1, 0x1b28: 0xbaf9, 0x1b29: 0x1429,\n\t0x1b2a: 0x1a31, 0x1b2b: 0xbb11, 0x1b2c: 0xbb29, 0x1b2d: 0xbb41, 0x1b2e: 0xbb59, 0x1b2f: 0xbb71,\n\t0x1b30: 0xbb89, 0x1b31: 0x2109, 0x1b32: 0x1111, 0x1b33: 0x1429, 0x1b34: 0xbba1, 0x1b35: 0xbbb9,\n\t0x1b36: 0xbbd1, 0x1b37: 0x10e1, 0x1b38: 0x10f9, 0x1b39: 0xbbe9, 0x1b3a: 0x2079, 0x1b3b: 0xbc01,\n\t0x1b3c: 0xbab1, 0x1b3d: 0x1099, 0x1b3e: 0x10b1, 0x1b3f: 0x10c9,\n\t// Block 0x6d, offset 0x1b40\n\t0x1b40: 0xbac9, 0x1b41: 0xbae1, 0x1b42: 0xbaf9, 0x1b43: 0x1429, 0x1b44: 0x1a31, 0x1b45: 0xbb11,\n\t0x1b46: 0xbb29, 0x1b47: 0xbb41, 0x1b48: 0xbb59, 0x1b49: 0xbb71, 0x1b4a: 0xbb89, 0x1b4b: 0x2109,\n\t0x1b4c: 0x1111, 0x1b4d: 0xbba1, 0x1b4e: 0xbba1, 0x1b4f: 0xbbb9, 0x1b50: 0xbbd1, 0x1b51: 0x10e1,\n\t0x1b52: 0x10f9, 0x1b53: 0xbbe9, 0x1b54: 0x2079, 0x1b55: 0xbc21, 0x1b56: 0xbac9, 0x1b57: 0x1429,\n\t0x1b58: 0xbb11, 0x1b59: 0x10e1, 0x1b5a: 0x1111, 0x1b5b: 0x2109, 0x1b5c: 0xbab1, 0x1b5d: 0x1099,\n\t0x1b5e: 0x10b1, 0x1b5f: 0x10c9, 0x1b60: 0xbac9, 0x1b61: 0xbae1, 0x1b62: 0xbaf9, 0x1b63: 0x1429,\n\t0x1b64: 0x1a31, 0x1b65: 0xbb11, 0x1b66: 0xbb29, 0x1b67: 0xbb41, 0x1b68: 0xbb59, 0x1b69: 0xbb71,\n\t0x1b6a: 0xbb89, 0x1b6b: 0x2109, 0x1b6c: 0x1111, 0x1b6d: 0x1429, 0x1b6e: 0xbba1, 0x1b6f: 0xbbb9,\n\t0x1b70: 0xbbd1, 0x1b71: 0x10e1, 0x1b72: 0x10f9, 0x1b73: 0xbbe9, 0x1b74: 0x2079, 0x1b75: 0xbc01,\n\t0x1b76: 0xbab1, 0x1b77: 0x1099, 0x1b78: 0x10b1, 0x1b79: 0x10c9, 0x1b7a: 0xbac9, 0x1b7b: 0xbae1,\n\t0x1b7c: 0xbaf9, 0x1b7d: 0x1429, 0x1b7e: 0x1a31, 0x1b7f: 0xbb11,\n\t// Block 0x6e, offset 0x1b80\n\t0x1b80: 0xbb29, 0x1b81: 0xbb41, 0x1b82: 0xbb59, 0x1b83: 0xbb71, 0x1b84: 0xbb89, 0x1b85: 0x2109,\n\t0x1b86: 0x1111, 0x1b87: 0xbba1, 0x1b88: 0xbba1, 0x1b89: 0xbbb9, 0x1b8a: 0xbbd1, 0x1b8b: 0x10e1,\n\t0x1b8c: 0x10f9, 0x1b8d: 0xbbe9, 0x1b8e: 0x2079, 0x1b8f: 0xbc21, 0x1b90: 0xbac9, 0x1b91: 0x1429,\n\t0x1b92: 0xbb11, 0x1b93: 0x10e1, 0x1b94: 0x1111, 0x1b95: 0x2109, 0x1b96: 0xbab1, 0x1b97: 0x1099,\n\t0x1b98: 0x10b1, 0x1b99: 0x10c9, 0x1b9a: 0xbac9, 0x1b9b: 0xbae1, 0x1b9c: 0xbaf9, 0x1b9d: 0x1429,\n\t0x1b9e: 0x1a31, 0x1b9f: 0xbb11, 0x1ba0: 0xbb29, 0x1ba1: 0xbb41, 0x1ba2: 0xbb59, 0x1ba3: 0xbb71,\n\t0x1ba4: 0xbb89, 0x1ba5: 0x2109, 0x1ba6: 0x1111, 0x1ba7: 0x1429, 0x1ba8: 0xbba1, 0x1ba9: 0xbbb9,\n\t0x1baa: 0xbbd1, 0x1bab: 0x10e1, 0x1bac: 0x10f9, 0x1bad: 0xbbe9, 0x1bae: 0x2079, 0x1baf: 0xbc01,\n\t0x1bb0: 0xbab1, 0x1bb1: 0x1099, 0x1bb2: 0x10b1, 0x1bb3: 0x10c9, 0x1bb4: 0xbac9, 0x1bb5: 0xbae1,\n\t0x1bb6: 0xbaf9, 0x1bb7: 0x1429, 0x1bb8: 0x1a31, 0x1bb9: 0xbb11, 0x1bba: 0xbb29, 0x1bbb: 0xbb41,\n\t0x1bbc: 0xbb59, 0x1bbd: 0xbb71, 0x1bbe: 0xbb89, 0x1bbf: 0x2109,\n\t// Block 0x6f, offset 0x1bc0\n\t0x1bc0: 0x1111, 0x1bc1: 0xbba1, 0x1bc2: 0xbba1, 0x1bc3: 0xbbb9, 0x1bc4: 0xbbd1, 0x1bc5: 0x10e1,\n\t0x1bc6: 0x10f9, 0x1bc7: 0xbbe9, 0x1bc8: 0x2079, 0x1bc9: 0xbc21, 0x1bca: 0xbac9, 0x1bcb: 0x1429,\n\t0x1bcc: 0xbb11, 0x1bcd: 0x10e1, 0x1bce: 0x1111, 0x1bcf: 0x2109, 0x1bd0: 0xbab1, 0x1bd1: 0x1099,\n\t0x1bd2: 0x10b1, 0x1bd3: 0x10c9, 0x1bd4: 0xbac9, 0x1bd5: 0xbae1, 0x1bd6: 0xbaf9, 0x1bd7: 0x1429,\n\t0x1bd8: 0x1a31, 0x1bd9: 0xbb11, 0x1bda: 0xbb29, 0x1bdb: 0xbb41, 0x1bdc: 0xbb59, 0x1bdd: 0xbb71,\n\t0x1bde: 0xbb89, 0x1bdf: 0x2109, 0x1be0: 0x1111, 0x1be1: 0x1429, 0x1be2: 0xbba1, 0x1be3: 0xbbb9,\n\t0x1be4: 0xbbd1, 0x1be5: 0x10e1, 0x1be6: 0x10f9, 0x1be7: 0xbbe9, 0x1be8: 0x2079, 0x1be9: 0xbc01,\n\t0x1bea: 0xbab1, 0x1beb: 0x1099, 0x1bec: 0x10b1, 0x1bed: 0x10c9, 0x1bee: 0xbac9, 0x1bef: 0xbae1,\n\t0x1bf0: 0xbaf9, 0x1bf1: 0x1429, 0x1bf2: 0x1a31, 0x1bf3: 0xbb11, 0x1bf4: 0xbb29, 0x1bf5: 0xbb41,\n\t0x1bf6: 0xbb59, 0x1bf7: 0xbb71, 0x1bf8: 0xbb89, 0x1bf9: 0x2109, 0x1bfa: 0x1111, 0x1bfb: 0xbba1,\n\t0x1bfc: 0xbba1, 0x1bfd: 0xbbb9, 0x1bfe: 0xbbd1, 0x1bff: 0x10e1,\n\t// Block 0x70, offset 0x1c00\n\t0x1c00: 0x10f9, 0x1c01: 0xbbe9, 0x1c02: 0x2079, 0x1c03: 0xbc21, 0x1c04: 0xbac9, 0x1c05: 0x1429,\n\t0x1c06: 0xbb11, 0x1c07: 0x10e1, 0x1c08: 0x1111, 0x1c09: 0x2109, 0x1c0a: 0xbc41, 0x1c0b: 0xbc41,\n\t0x1c0c: 0x0040, 0x1c0d: 0x0040, 0x1c0e: 0x1f41, 0x1c0f: 0x00c9, 0x1c10: 0x0069, 0x1c11: 0x0079,\n\t0x1c12: 0x1f51, 0x1c13: 0x1f61, 0x1c14: 0x1f71, 0x1c15: 0x1f81, 0x1c16: 0x1f91, 0x1c17: 0x1fa1,\n\t0x1c18: 0x1f41, 0x1c19: 0x00c9, 0x1c1a: 0x0069, 0x1c1b: 0x0079, 0x1c1c: 0x1f51, 0x1c1d: 0x1f61,\n\t0x1c1e: 0x1f71, 0x1c1f: 0x1f81, 0x1c20: 0x1f91, 0x1c21: 0x1fa1, 0x1c22: 0x1f41, 0x1c23: 0x00c9,\n\t0x1c24: 0x0069, 0x1c25: 0x0079, 0x1c26: 0x1f51, 0x1c27: 0x1f61, 0x1c28: 0x1f71, 0x1c29: 0x1f81,\n\t0x1c2a: 0x1f91, 0x1c2b: 0x1fa1, 0x1c2c: 0x1f41, 0x1c2d: 0x00c9, 0x1c2e: 0x0069, 0x1c2f: 0x0079,\n\t0x1c30: 0x1f51, 0x1c31: 0x1f61, 0x1c32: 0x1f71, 0x1c33: 0x1f81, 0x1c34: 0x1f91, 0x1c35: 0x1fa1,\n\t0x1c36: 0x1f41, 0x1c37: 0x00c9, 0x1c38: 0x0069, 0x1c39: 0x0079, 0x1c3a: 0x1f51, 0x1c3b: 0x1f61,\n\t0x1c3c: 0x1f71, 0x1c3d: 0x1f81, 0x1c3e: 0x1f91, 0x1c3f: 0x1fa1,\n\t// Block 0x71, offset 0x1c40\n\t0x1c40: 0xe115, 0x1c41: 0xe115, 0x1c42: 0xe135, 0x1c43: 0xe135, 0x1c44: 0xe115, 0x1c45: 0xe115,\n\t0x1c46: 0xe175, 0x1c47: 0xe175, 0x1c48: 0xe115, 0x1c49: 0xe115, 0x1c4a: 0xe135, 0x1c4b: 0xe135,\n\t0x1c4c: 0xe115, 0x1c4d: 0xe115, 0x1c4e: 0xe1f5, 0x1c4f: 0xe1f5, 0x1c50: 0xe115, 0x1c51: 0xe115,\n\t0x1c52: 0xe135, 0x1c53: 0xe135, 0x1c54: 0xe115, 0x1c55: 0xe115, 0x1c56: 0xe175, 0x1c57: 0xe175,\n\t0x1c58: 0xe115, 0x1c59: 0xe115, 0x1c5a: 0xe135, 0x1c5b: 0xe135, 0x1c5c: 0xe115, 0x1c5d: 0xe115,\n\t0x1c5e: 0x8b05, 0x1c5f: 0x8b05, 0x1c60: 0x04b5, 0x1c61: 0x04b5, 0x1c62: 0x0a08, 0x1c63: 0x0a08,\n\t0x1c64: 0x0a08, 0x1c65: 0x0a08, 0x1c66: 0x0a08, 0x1c67: 0x0a08, 0x1c68: 0x0a08, 0x1c69: 0x0a08,\n\t0x1c6a: 0x0a08, 0x1c6b: 0x0a08, 0x1c6c: 0x0a08, 0x1c6d: 0x0a08, 0x1c6e: 0x0a08, 0x1c6f: 0x0a08,\n\t0x1c70: 0x0a08, 0x1c71: 0x0a08, 0x1c72: 0x0a08, 0x1c73: 0x0a08, 0x1c74: 0x0a08, 0x1c75: 0x0a08,\n\t0x1c76: 0x0a08, 0x1c77: 0x0a08, 0x1c78: 0x0a08, 0x1c79: 0x0a08, 0x1c7a: 0x0a08, 0x1c7b: 0x0a08,\n\t0x1c7c: 0x0a08, 0x1c7d: 0x0a08, 0x1c7e: 0x0a08, 0x1c7f: 0x0a08,\n\t// Block 0x72, offset 0x1c80\n\t0x1c80: 0xb189, 0x1c81: 0xb1a1, 0x1c82: 0xb201, 0x1c83: 0xb249, 0x1c84: 0x0040, 0x1c85: 0xb411,\n\t0x1c86: 0xb291, 0x1c87: 0xb219, 0x1c88: 0xb309, 0x1c89: 0xb429, 0x1c8a: 0xb399, 0x1c8b: 0xb3b1,\n\t0x1c8c: 0xb3c9, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0xb369, 0x1c91: 0xb2d9,\n\t0x1c92: 0xb381, 0x1c93: 0xb279, 0x1c94: 0xb2c1, 0x1c95: 0xb1d1, 0x1c96: 0xb1e9, 0x1c97: 0xb231,\n\t0x1c98: 0xb261, 0x1c99: 0xb2f1, 0x1c9a: 0xb321, 0x1c9b: 0xb351, 0x1c9c: 0xbc59, 0x1c9d: 0x7949,\n\t0x1c9e: 0xbc71, 0x1c9f: 0xbc89, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0x0040,\n\t0x1ca4: 0xb3f9, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0xb219, 0x1ca8: 0x0040, 0x1ca9: 0xb429,\n\t0x1caa: 0xb399, 0x1cab: 0xb3b1, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339,\n\t0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0x0040, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1,\n\t0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0x0040, 0x1cb9: 0xb2f1, 0x1cba: 0x0040, 0x1cbb: 0xb351,\n\t0x1cbc: 0x0040, 0x1cbd: 0x0040, 0x1cbe: 0x0040, 0x1cbf: 0x0040,\n\t// Block 0x73, offset 0x1cc0\n\t0x1cc0: 0x0040, 0x1cc1: 0x0040, 0x1cc2: 0xb201, 0x1cc3: 0x0040, 0x1cc4: 0x0040, 0x1cc5: 0x0040,\n\t0x1cc6: 0x0040, 0x1cc7: 0xb219, 0x1cc8: 0x0040, 0x1cc9: 0xb429, 0x1cca: 0x0040, 0x1ccb: 0xb3b1,\n\t0x1ccc: 0x0040, 0x1ccd: 0xb3e1, 0x1cce: 0xb2a9, 0x1ccf: 0xb339, 0x1cd0: 0x0040, 0x1cd1: 0xb2d9,\n\t0x1cd2: 0xb381, 0x1cd3: 0x0040, 0x1cd4: 0xb2c1, 0x1cd5: 0x0040, 0x1cd6: 0x0040, 0x1cd7: 0xb231,\n\t0x1cd8: 0x0040, 0x1cd9: 0xb2f1, 0x1cda: 0x0040, 0x1cdb: 0xb351, 0x1cdc: 0x0040, 0x1cdd: 0x7949,\n\t0x1cde: 0x0040, 0x1cdf: 0xbc89, 0x1ce0: 0x0040, 0x1ce1: 0xb1a1, 0x1ce2: 0xb201, 0x1ce3: 0x0040,\n\t0x1ce4: 0xb3f9, 0x1ce5: 0x0040, 0x1ce6: 0x0040, 0x1ce7: 0xb219, 0x1ce8: 0xb309, 0x1ce9: 0xb429,\n\t0x1cea: 0xb399, 0x1ceb: 0x0040, 0x1cec: 0xb3c9, 0x1ced: 0xb3e1, 0x1cee: 0xb2a9, 0x1cef: 0xb339,\n\t0x1cf0: 0xb369, 0x1cf1: 0xb2d9, 0x1cf2: 0xb381, 0x1cf3: 0x0040, 0x1cf4: 0xb2c1, 0x1cf5: 0xb1d1,\n\t0x1cf6: 0xb1e9, 0x1cf7: 0xb231, 0x1cf8: 0x0040, 0x1cf9: 0xb2f1, 0x1cfa: 0xb321, 0x1cfb: 0xb351,\n\t0x1cfc: 0xbc59, 0x1cfd: 0x0040, 0x1cfe: 0xbc71, 0x1cff: 0x0040,\n\t// Block 0x74, offset 0x1d00\n\t0x1d00: 0xb189, 0x1d01: 0xb1a1, 0x1d02: 0xb201, 0x1d03: 0xb249, 0x1d04: 0xb3f9, 0x1d05: 0xb411,\n\t0x1d06: 0xb291, 0x1d07: 0xb219, 0x1d08: 0xb309, 0x1d09: 0xb429, 0x1d0a: 0x0040, 0x1d0b: 0xb3b1,\n\t0x1d0c: 0xb3c9, 0x1d0d: 0xb3e1, 0x1d0e: 0xb2a9, 0x1d0f: 0xb339, 0x1d10: 0xb369, 0x1d11: 0xb2d9,\n\t0x1d12: 0xb381, 0x1d13: 0xb279, 0x1d14: 0xb2c1, 0x1d15: 0xb1d1, 0x1d16: 0xb1e9, 0x1d17: 0xb231,\n\t0x1d18: 0xb261, 0x1d19: 0xb2f1, 0x1d1a: 0xb321, 0x1d1b: 0xb351, 0x1d1c: 0x0040, 0x1d1d: 0x0040,\n\t0x1d1e: 0x0040, 0x1d1f: 0x0040, 0x1d20: 0x0040, 0x1d21: 0xb1a1, 0x1d22: 0xb201, 0x1d23: 0xb249,\n\t0x1d24: 0x0040, 0x1d25: 0xb411, 0x1d26: 0xb291, 0x1d27: 0xb219, 0x1d28: 0xb309, 0x1d29: 0xb429,\n\t0x1d2a: 0x0040, 0x1d2b: 0xb3b1, 0x1d2c: 0xb3c9, 0x1d2d: 0xb3e1, 0x1d2e: 0xb2a9, 0x1d2f: 0xb339,\n\t0x1d30: 0xb369, 0x1d31: 0xb2d9, 0x1d32: 0xb381, 0x1d33: 0xb279, 0x1d34: 0xb2c1, 0x1d35: 0xb1d1,\n\t0x1d36: 0xb1e9, 0x1d37: 0xb231, 0x1d38: 0xb261, 0x1d39: 0xb2f1, 0x1d3a: 0xb321, 0x1d3b: 0xb351,\n\t0x1d3c: 0x0040, 0x1d3d: 0x0040, 0x1d3e: 0x0040, 0x1d3f: 0x0040,\n\t// Block 0x75, offset 0x1d40\n\t0x1d40: 0x0040, 0x1d41: 0xbca2, 0x1d42: 0xbcba, 0x1d43: 0xbcd2, 0x1d44: 0xbcea, 0x1d45: 0xbd02,\n\t0x1d46: 0xbd1a, 0x1d47: 0xbd32, 0x1d48: 0xbd4a, 0x1d49: 0xbd62, 0x1d4a: 0xbd7a, 0x1d4b: 0x0018,\n\t0x1d4c: 0x0018, 0x1d4d: 0x0040, 0x1d4e: 0x0040, 0x1d4f: 0x0040, 0x1d50: 0xbd92, 0x1d51: 0xbdb2,\n\t0x1d52: 0xbdd2, 0x1d53: 0xbdf2, 0x1d54: 0xbe12, 0x1d55: 0xbe32, 0x1d56: 0xbe52, 0x1d57: 0xbe72,\n\t0x1d58: 0xbe92, 0x1d59: 0xbeb2, 0x1d5a: 0xbed2, 0x1d5b: 0xbef2, 0x1d5c: 0xbf12, 0x1d5d: 0xbf32,\n\t0x1d5e: 0xbf52, 0x1d5f: 0xbf72, 0x1d60: 0xbf92, 0x1d61: 0xbfb2, 0x1d62: 0xbfd2, 0x1d63: 0xbff2,\n\t0x1d64: 0xc012, 0x1d65: 0xc032, 0x1d66: 0xc052, 0x1d67: 0xc072, 0x1d68: 0xc092, 0x1d69: 0xc0b2,\n\t0x1d6a: 0xc0d1, 0x1d6b: 0x1159, 0x1d6c: 0x0269, 0x1d6d: 0x6671, 0x1d6e: 0xc111, 0x1d6f: 0x0018,\n\t0x1d70: 0x0039, 0x1d71: 0x0ee9, 0x1d72: 0x1159, 0x1d73: 0x0ef9, 0x1d74: 0x0f09, 0x1d75: 0x1199,\n\t0x1d76: 0x0f31, 0x1d77: 0x0249, 0x1d78: 0x0f41, 0x1d79: 0x0259, 0x1d7a: 0x0f51, 0x1d7b: 0x0359,\n\t0x1d7c: 0x0f61, 0x1d7d: 0x0f71, 0x1d7e: 0x00d9, 0x1d7f: 0x0f99,\n\t// Block 0x76, offset 0x1d80\n\t0x1d80: 0x2039, 0x1d81: 0x0269, 0x1d82: 0x01d9, 0x1d83: 0x0fa9, 0x1d84: 0x0fb9, 0x1d85: 0x1089,\n\t0x1d86: 0x0279, 0x1d87: 0x0369, 0x1d88: 0x0289, 0x1d89: 0x13d1, 0x1d8a: 0xc129, 0x1d8b: 0x65b1,\n\t0x1d8c: 0xc141, 0x1d8d: 0x1441, 0x1d8e: 0xc159, 0x1d8f: 0xc179, 0x1d90: 0x0018, 0x1d91: 0x0018,\n\t0x1d92: 0x0018, 0x1d93: 0x0018, 0x1d94: 0x0018, 0x1d95: 0x0018, 0x1d96: 0x0018, 0x1d97: 0x0018,\n\t0x1d98: 0x0018, 0x1d99: 0x0018, 0x1d9a: 0x0018, 0x1d9b: 0x0018, 0x1d9c: 0x0018, 0x1d9d: 0x0018,\n\t0x1d9e: 0x0018, 0x1d9f: 0x0018, 0x1da0: 0x0018, 0x1da1: 0x0018, 0x1da2: 0x0018, 0x1da3: 0x0018,\n\t0x1da4: 0x0018, 0x1da5: 0x0018, 0x1da6: 0x0018, 0x1da7: 0x0018, 0x1da8: 0x0018, 0x1da9: 0x0018,\n\t0x1daa: 0xc191, 0x1dab: 0xc1a9, 0x1dac: 0x0040, 0x1dad: 0x0040, 0x1dae: 0x0040, 0x1daf: 0x0040,\n\t0x1db0: 0x0018, 0x1db1: 0x0018, 0x1db2: 0x0018, 0x1db3: 0x0018, 0x1db4: 0x0018, 0x1db5: 0x0018,\n\t0x1db6: 0x0018, 0x1db7: 0x0018, 0x1db8: 0x0018, 0x1db9: 0x0018, 0x1dba: 0x0018, 0x1dbb: 0x0018,\n\t0x1dbc: 0x0018, 0x1dbd: 0x0018, 0x1dbe: 0x0018, 0x1dbf: 0x0018,\n\t// Block 0x77, offset 0x1dc0\n\t0x1dc0: 0xc1d9, 0x1dc1: 0xc211, 0x1dc2: 0xc249, 0x1dc3: 0x0040, 0x1dc4: 0x0040, 0x1dc5: 0x0040,\n\t0x1dc6: 0x0040, 0x1dc7: 0x0040, 0x1dc8: 0x0040, 0x1dc9: 0x0040, 0x1dca: 0x0040, 0x1dcb: 0x0040,\n\t0x1dcc: 0x0040, 0x1dcd: 0x0040, 0x1dce: 0x0040, 0x1dcf: 0x0040, 0x1dd0: 0xc269, 0x1dd1: 0xc289,\n\t0x1dd2: 0xc2a9, 0x1dd3: 0xc2c9, 0x1dd4: 0xc2e9, 0x1dd5: 0xc309, 0x1dd6: 0xc329, 0x1dd7: 0xc349,\n\t0x1dd8: 0xc369, 0x1dd9: 0xc389, 0x1dda: 0xc3a9, 0x1ddb: 0xc3c9, 0x1ddc: 0xc3e9, 0x1ddd: 0xc409,\n\t0x1dde: 0xc429, 0x1ddf: 0xc449, 0x1de0: 0xc469, 0x1de1: 0xc489, 0x1de2: 0xc4a9, 0x1de3: 0xc4c9,\n\t0x1de4: 0xc4e9, 0x1de5: 0xc509, 0x1de6: 0xc529, 0x1de7: 0xc549, 0x1de8: 0xc569, 0x1de9: 0xc589,\n\t0x1dea: 0xc5a9, 0x1deb: 0xc5c9, 0x1dec: 0xc5e9, 0x1ded: 0xc609, 0x1dee: 0xc629, 0x1def: 0xc649,\n\t0x1df0: 0xc669, 0x1df1: 0xc689, 0x1df2: 0xc6a9, 0x1df3: 0xc6c9, 0x1df4: 0xc6e9, 0x1df5: 0xc709,\n\t0x1df6: 0xc729, 0x1df7: 0xc749, 0x1df8: 0xc769, 0x1df9: 0xc789, 0x1dfa: 0xc7a9, 0x1dfb: 0xc7c9,\n\t0x1dfc: 0x0040, 0x1dfd: 0x0040, 0x1dfe: 0x0040, 0x1dff: 0x0040,\n\t// Block 0x78, offset 0x1e00\n\t0x1e00: 0xcaf9, 0x1e01: 0xcb19, 0x1e02: 0xcb39, 0x1e03: 0x8b1d, 0x1e04: 0xcb59, 0x1e05: 0xcb79,\n\t0x1e06: 0xcb99, 0x1e07: 0xcbb9, 0x1e08: 0xcbd9, 0x1e09: 0xcbf9, 0x1e0a: 0xcc19, 0x1e0b: 0xcc39,\n\t0x1e0c: 0xcc59, 0x1e0d: 0x8b3d, 0x1e0e: 0xcc79, 0x1e0f: 0xcc99, 0x1e10: 0xccb9, 0x1e11: 0xccd9,\n\t0x1e12: 0x8b5d, 0x1e13: 0xccf9, 0x1e14: 0xcd19, 0x1e15: 0xc429, 0x1e16: 0x8b7d, 0x1e17: 0xcd39,\n\t0x1e18: 0xcd59, 0x1e19: 0xcd79, 0x1e1a: 0xcd99, 0x1e1b: 0xcdb9, 0x1e1c: 0x8b9d, 0x1e1d: 0xcdd9,\n\t0x1e1e: 0xcdf9, 0x1e1f: 0xce19, 0x1e20: 0xce39, 0x1e21: 0xce59, 0x1e22: 0xc789, 0x1e23: 0xce79,\n\t0x1e24: 0xce99, 0x1e25: 0xceb9, 0x1e26: 0xced9, 0x1e27: 0xcef9, 0x1e28: 0xcf19, 0x1e29: 0xcf39,\n\t0x1e2a: 0xcf59, 0x1e2b: 0xcf79, 0x1e2c: 0xcf99, 0x1e2d: 0xcfb9, 0x1e2e: 0xcfd9, 0x1e2f: 0xcff9,\n\t0x1e30: 0xd019, 0x1e31: 0xd039, 0x1e32: 0xd039, 0x1e33: 0xd039, 0x1e34: 0x8bbd, 0x1e35: 0xd059,\n\t0x1e36: 0xd079, 0x1e37: 0xd099, 0x1e38: 0x8bdd, 0x1e39: 0xd0b9, 0x1e3a: 0xd0d9, 0x1e3b: 0xd0f9,\n\t0x1e3c: 0xd119, 0x1e3d: 0xd139, 0x1e3e: 0xd159, 0x1e3f: 0xd179,\n\t// Block 0x79, offset 0x1e40\n\t0x1e40: 0xd199, 0x1e41: 0xd1b9, 0x1e42: 0xd1d9, 0x1e43: 0xd1f9, 0x1e44: 0xd219, 0x1e45: 0xd239,\n\t0x1e46: 0xd239, 0x1e47: 0xd259, 0x1e48: 0xd279, 0x1e49: 0xd299, 0x1e4a: 0xd2b9, 0x1e4b: 0xd2d9,\n\t0x1e4c: 0xd2f9, 0x1e4d: 0xd319, 0x1e4e: 0xd339, 0x1e4f: 0xd359, 0x1e50: 0xd379, 0x1e51: 0xd399,\n\t0x1e52: 0xd3b9, 0x1e53: 0xd3d9, 0x1e54: 0xd3f9, 0x1e55: 0xd419, 0x1e56: 0xd439, 0x1e57: 0xd459,\n\t0x1e58: 0xd479, 0x1e59: 0x8bfd, 0x1e5a: 0xd499, 0x1e5b: 0xd4b9, 0x1e5c: 0xd4d9, 0x1e5d: 0xc309,\n\t0x1e5e: 0xd4f9, 0x1e5f: 0xd519, 0x1e60: 0x8c1d, 0x1e61: 0x8c3d, 0x1e62: 0xd539, 0x1e63: 0xd559,\n\t0x1e64: 0xd579, 0x1e65: 0xd599, 0x1e66: 0xd5b9, 0x1e67: 0xd5d9, 0x1e68: 0x2040, 0x1e69: 0xd5f9,\n\t0x1e6a: 0xd619, 0x1e6b: 0xd619, 0x1e6c: 0x8c5d, 0x1e6d: 0xd639, 0x1e6e: 0xd659, 0x1e6f: 0xd679,\n\t0x1e70: 0xd699, 0x1e71: 0x8c7d, 0x1e72: 0xd6b9, 0x1e73: 0xd6d9, 0x1e74: 0x2040, 0x1e75: 0xd6f9,\n\t0x1e76: 0xd719, 0x1e77: 0xd739, 0x1e78: 0xd759, 0x1e79: 0xd779, 0x1e7a: 0xd799, 0x1e7b: 0x8c9d,\n\t0x1e7c: 0xd7b9, 0x1e7d: 0x8cbd, 0x1e7e: 0xd7d9, 0x1e7f: 0xd7f9,\n\t// Block 0x7a, offset 0x1e80\n\t0x1e80: 0xd819, 0x1e81: 0xd839, 0x1e82: 0xd859, 0x1e83: 0xd879, 0x1e84: 0xd899, 0x1e85: 0xd8b9,\n\t0x1e86: 0xd8d9, 0x1e87: 0xd8f9, 0x1e88: 0xd919, 0x1e89: 0x8cdd, 0x1e8a: 0xd939, 0x1e8b: 0xd959,\n\t0x1e8c: 0xd979, 0x1e8d: 0xd999, 0x1e8e: 0xd9b9, 0x1e8f: 0x8cfd, 0x1e90: 0xd9d9, 0x1e91: 0x8d1d,\n\t0x1e92: 0x8d3d, 0x1e93: 0xd9f9, 0x1e94: 0xda19, 0x1e95: 0xda19, 0x1e96: 0xda39, 0x1e97: 0x8d5d,\n\t0x1e98: 0x8d7d, 0x1e99: 0xda59, 0x1e9a: 0xda79, 0x1e9b: 0xda99, 0x1e9c: 0xdab9, 0x1e9d: 0xdad9,\n\t0x1e9e: 0xdaf9, 0x1e9f: 0xdb19, 0x1ea0: 0xdb39, 0x1ea1: 0xdb59, 0x1ea2: 0xdb79, 0x1ea3: 0xdb99,\n\t0x1ea4: 0x8d9d, 0x1ea5: 0xdbb9, 0x1ea6: 0xdbd9, 0x1ea7: 0xdbf9, 0x1ea8: 0xdc19, 0x1ea9: 0xdbf9,\n\t0x1eaa: 0xdc39, 0x1eab: 0xdc59, 0x1eac: 0xdc79, 0x1ead: 0xdc99, 0x1eae: 0xdcb9, 0x1eaf: 0xdcd9,\n\t0x1eb0: 0xdcf9, 0x1eb1: 0xdd19, 0x1eb2: 0xdd39, 0x1eb3: 0xdd59, 0x1eb4: 0xdd79, 0x1eb5: 0xdd99,\n\t0x1eb6: 0xddb9, 0x1eb7: 0xddd9, 0x1eb8: 0x8dbd, 0x1eb9: 0xddf9, 0x1eba: 0xde19, 0x1ebb: 0xde39,\n\t0x1ebc: 0xde59, 0x1ebd: 0xde79, 0x1ebe: 0x8ddd, 0x1ebf: 0xde99,\n\t// Block 0x7b, offset 0x1ec0\n\t0x1ec0: 0xe599, 0x1ec1: 0xe5b9, 0x1ec2: 0xe5d9, 0x1ec3: 0xe5f9, 0x1ec4: 0xe619, 0x1ec5: 0xe639,\n\t0x1ec6: 0x8efd, 0x1ec7: 0xe659, 0x1ec8: 0xe679, 0x1ec9: 0xe699, 0x1eca: 0xe6b9, 0x1ecb: 0xe6d9,\n\t0x1ecc: 0xe6f9, 0x1ecd: 0x8f1d, 0x1ece: 0xe719, 0x1ecf: 0xe739, 0x1ed0: 0x8f3d, 0x1ed1: 0x8f5d,\n\t0x1ed2: 0xe759, 0x1ed3: 0xe779, 0x1ed4: 0xe799, 0x1ed5: 0xe7b9, 0x1ed6: 0xe7d9, 0x1ed7: 0xe7f9,\n\t0x1ed8: 0xe819, 0x1ed9: 0xe839, 0x1eda: 0xe859, 0x1edb: 0x8f7d, 0x1edc: 0xe879, 0x1edd: 0x8f9d,\n\t0x1ede: 0xe899, 0x1edf: 0x2040, 0x1ee0: 0xe8b9, 0x1ee1: 0xe8d9, 0x1ee2: 0xe8f9, 0x1ee3: 0x8fbd,\n\t0x1ee4: 0xe919, 0x1ee5: 0xe939, 0x1ee6: 0x8fdd, 0x1ee7: 0x8ffd, 0x1ee8: 0xe959, 0x1ee9: 0xe979,\n\t0x1eea: 0xe999, 0x1eeb: 0xe9b9, 0x1eec: 0xe9d9, 0x1eed: 0xe9d9, 0x1eee: 0xe9f9, 0x1eef: 0xea19,\n\t0x1ef0: 0xea39, 0x1ef1: 0xea59, 0x1ef2: 0xea79, 0x1ef3: 0xea99, 0x1ef4: 0xeab9, 0x1ef5: 0x901d,\n\t0x1ef6: 0xead9, 0x1ef7: 0x903d, 0x1ef8: 0xeaf9, 0x1ef9: 0x905d, 0x1efa: 0xeb19, 0x1efb: 0x907d,\n\t0x1efc: 0x909d, 0x1efd: 0x90bd, 0x1efe: 0xeb39, 0x1eff: 0xeb59,\n\t// Block 0x7c, offset 0x1f00\n\t0x1f00: 0xeb79, 0x1f01: 0x90dd, 0x1f02: 0x90fd, 0x1f03: 0x911d, 0x1f04: 0x913d, 0x1f05: 0xeb99,\n\t0x1f06: 0xebb9, 0x1f07: 0xebb9, 0x1f08: 0xebd9, 0x1f09: 0xebf9, 0x1f0a: 0xec19, 0x1f0b: 0xec39,\n\t0x1f0c: 0xec59, 0x1f0d: 0x915d, 0x1f0e: 0xec79, 0x1f0f: 0xec99, 0x1f10: 0xecb9, 0x1f11: 0xecd9,\n\t0x1f12: 0x917d, 0x1f13: 0xecf9, 0x1f14: 0x919d, 0x1f15: 0x91bd, 0x1f16: 0xed19, 0x1f17: 0xed39,\n\t0x1f18: 0xed59, 0x1f19: 0xed79, 0x1f1a: 0xed99, 0x1f1b: 0xedb9, 0x1f1c: 0x91dd, 0x1f1d: 0x91fd,\n\t0x1f1e: 0x921d, 0x1f1f: 0x2040, 0x1f20: 0xedd9, 0x1f21: 0x923d, 0x1f22: 0xedf9, 0x1f23: 0xee19,\n\t0x1f24: 0xee39, 0x1f25: 0x925d, 0x1f26: 0xee59, 0x1f27: 0xee79, 0x1f28: 0xee99, 0x1f29: 0xeeb9,\n\t0x1f2a: 0xeed9, 0x1f2b: 0x927d, 0x1f2c: 0xeef9, 0x1f2d: 0xef19, 0x1f2e: 0xef39, 0x1f2f: 0xef59,\n\t0x1f30: 0xef79, 0x1f31: 0xef99, 0x1f32: 0x929d, 0x1f33: 0x92bd, 0x1f34: 0xefb9, 0x1f35: 0x92dd,\n\t0x1f36: 0xefd9, 0x1f37: 0x92fd, 0x1f38: 0xeff9, 0x1f39: 0xf019, 0x1f3a: 0xf039, 0x1f3b: 0x931d,\n\t0x1f3c: 0x933d, 0x1f3d: 0xf059, 0x1f3e: 0x935d, 0x1f3f: 0xf079,\n\t// Block 0x7d, offset 0x1f40\n\t0x1f40: 0xf6b9, 0x1f41: 0xf6d9, 0x1f42: 0xf6f9, 0x1f43: 0xf719, 0x1f44: 0xf739, 0x1f45: 0x951d,\n\t0x1f46: 0xf759, 0x1f47: 0xf779, 0x1f48: 0xf799, 0x1f49: 0xf7b9, 0x1f4a: 0xf7d9, 0x1f4b: 0x953d,\n\t0x1f4c: 0x955d, 0x1f4d: 0xf7f9, 0x1f4e: 0xf819, 0x1f4f: 0xf839, 0x1f50: 0xf859, 0x1f51: 0xf879,\n\t0x1f52: 0xf899, 0x1f53: 0x957d, 0x1f54: 0xf8b9, 0x1f55: 0xf8d9, 0x1f56: 0xf8f9, 0x1f57: 0xf919,\n\t0x1f58: 0x959d, 0x1f59: 0x95bd, 0x1f5a: 0xf939, 0x1f5b: 0xf959, 0x1f5c: 0xf979, 0x1f5d: 0x95dd,\n\t0x1f5e: 0xf999, 0x1f5f: 0xf9b9, 0x1f60: 0x6815, 0x1f61: 0x95fd, 0x1f62: 0xf9d9, 0x1f63: 0xf9f9,\n\t0x1f64: 0xfa19, 0x1f65: 0x961d, 0x1f66: 0xfa39, 0x1f67: 0xfa59, 0x1f68: 0xfa79, 0x1f69: 0xfa99,\n\t0x1f6a: 0xfab9, 0x1f6b: 0xfad9, 0x1f6c: 0xfaf9, 0x1f6d: 0x963d, 0x1f6e: 0xfb19, 0x1f6f: 0xfb39,\n\t0x1f70: 0xfb59, 0x1f71: 0x965d, 0x1f72: 0xfb79, 0x1f73: 0xfb99, 0x1f74: 0xfbb9, 0x1f75: 0xfbd9,\n\t0x1f76: 0x7b35, 0x1f77: 0x967d, 0x1f78: 0xfbf9, 0x1f79: 0xfc19, 0x1f7a: 0xfc39, 0x1f7b: 0x969d,\n\t0x1f7c: 0xfc59, 0x1f7d: 0x96bd, 0x1f7e: 0xfc79, 0x1f7f: 0xfc79,\n\t// Block 0x7e, offset 0x1f80\n\t0x1f80: 0xfc99, 0x1f81: 0x96dd, 0x1f82: 0xfcb9, 0x1f83: 0xfcd9, 0x1f84: 0xfcf9, 0x1f85: 0xfd19,\n\t0x1f86: 0xfd39, 0x1f87: 0xfd59, 0x1f88: 0xfd79, 0x1f89: 0x96fd, 0x1f8a: 0xfd99, 0x1f8b: 0xfdb9,\n\t0x1f8c: 0xfdd9, 0x1f8d: 0xfdf9, 0x1f8e: 0xfe19, 0x1f8f: 0xfe39, 0x1f90: 0x971d, 0x1f91: 0xfe59,\n\t0x1f92: 0x973d, 0x1f93: 0x975d, 0x1f94: 0x977d, 0x1f95: 0xfe79, 0x1f96: 0xfe99, 0x1f97: 0xfeb9,\n\t0x1f98: 0xfed9, 0x1f99: 0xfef9, 0x1f9a: 0xff19, 0x1f9b: 0xff39, 0x1f9c: 0xff59, 0x1f9d: 0x979d,\n\t0x1f9e: 0x0040, 0x1f9f: 0x0040, 0x1fa0: 0x0040, 0x1fa1: 0x0040, 0x1fa2: 0x0040, 0x1fa3: 0x0040,\n\t0x1fa4: 0x0040, 0x1fa5: 0x0040, 0x1fa6: 0x0040, 0x1fa7: 0x0040, 0x1fa8: 0x0040, 0x1fa9: 0x0040,\n\t0x1faa: 0x0040, 0x1fab: 0x0040, 0x1fac: 0x0040, 0x1fad: 0x0040, 0x1fae: 0x0040, 0x1faf: 0x0040,\n\t0x1fb0: 0x0040, 0x1fb1: 0x0040, 0x1fb2: 0x0040, 0x1fb3: 0x0040, 0x1fb4: 0x0040, 0x1fb5: 0x0040,\n\t0x1fb6: 0x0040, 0x1fb7: 0x0040, 0x1fb8: 0x0040, 0x1fb9: 0x0040, 0x1fba: 0x0040, 0x1fbb: 0x0040,\n\t0x1fbc: 0x0040, 0x1fbd: 0x0040, 0x1fbe: 0x0040, 0x1fbf: 0x0040,\n}\n\n// idnaIndex: 36 blocks, 2304 entries, 4608 bytes\n// Block 0 is the zero block.\nvar idnaIndex = [2304]uint16{\n\t// Block 0x0, offset 0x0\n\t// Block 0x1, offset 0x40\n\t// Block 0x2, offset 0x80\n\t// Block 0x3, offset 0xc0\n\t0xc2: 0x01, 0xc3: 0x7d, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05,\n\t0xc8: 0x06, 0xc9: 0x7e, 0xca: 0x7f, 0xcb: 0x07, 0xcc: 0x80, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a,\n\t0xd0: 0x81, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x82, 0xd6: 0x83, 0xd7: 0x84,\n\t0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x85, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x86, 0xde: 0x87, 0xdf: 0x88,\n\t0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07,\n\t0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c,\n\t0xf0: 0x1d, 0xf1: 0x1e, 0xf2: 0x1e, 0xf3: 0x20, 0xf4: 0x21,\n\t// Block 0x4, offset 0x100\n\t0x120: 0x89, 0x121: 0x13, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x14, 0x126: 0x15, 0x127: 0x16,\n\t0x128: 0x17, 0x129: 0x18, 0x12a: 0x19, 0x12b: 0x1a, 0x12c: 0x1b, 0x12d: 0x1c, 0x12e: 0x1d, 0x12f: 0x8d,\n\t0x130: 0x8e, 0x131: 0x1e, 0x132: 0x1f, 0x133: 0x20, 0x134: 0x8f, 0x135: 0x21, 0x136: 0x90, 0x137: 0x91,\n\t0x138: 0x92, 0x139: 0x93, 0x13a: 0x22, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x23, 0x13e: 0x24, 0x13f: 0x96,\n\t// Block 0x5, offset 0x140\n\t0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9d, 0x147: 0x9e,\n\t0x148: 0x9f, 0x149: 0xa0, 0x14a: 0xa1, 0x14b: 0xa2, 0x14c: 0xa3, 0x14d: 0xa4, 0x14e: 0xa5, 0x14f: 0xa6,\n\t0x150: 0xa7, 0x151: 0x9f, 0x152: 0x9f, 0x153: 0x9f, 0x154: 0x9f, 0x155: 0x9f, 0x156: 0x9f, 0x157: 0x9f,\n\t0x158: 0x9f, 0x159: 0xa8, 0x15a: 0xa9, 0x15b: 0xaa, 0x15c: 0xab, 0x15d: 0xac, 0x15e: 0xad, 0x15f: 0xae,\n\t0x160: 0xaf, 0x161: 0xb0, 0x162: 0xb1, 0x163: 0xb2, 0x164: 0xb3, 0x165: 0xb4, 0x166: 0xb5, 0x167: 0xb6,\n\t0x168: 0xb7, 0x169: 0xb8, 0x16a: 0xb9, 0x16b: 0xba, 0x16c: 0xbb, 0x16d: 0xbc, 0x16e: 0xbd, 0x16f: 0xbe,\n\t0x170: 0xbf, 0x171: 0xc0, 0x172: 0xc1, 0x173: 0xc2, 0x174: 0x25, 0x175: 0x26, 0x176: 0x27, 0x177: 0xc3,\n\t0x178: 0x28, 0x179: 0x28, 0x17a: 0x29, 0x17b: 0x28, 0x17c: 0xc4, 0x17d: 0x2a, 0x17e: 0x2b, 0x17f: 0x2c,\n\t// Block 0x6, offset 0x180\n\t0x180: 0x2d, 0x181: 0x2e, 0x182: 0x2f, 0x183: 0xc5, 0x184: 0x30, 0x185: 0x31, 0x186: 0xc6, 0x187: 0x9b,\n\t0x188: 0xc7, 0x189: 0xc8, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc9, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0x9b,\n\t0x190: 0xca, 0x191: 0x32, 0x192: 0x33, 0x193: 0x34, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b,\n\t0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b,\n\t0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b,\n\t0x1a8: 0xcb, 0x1a9: 0xcc, 0x1aa: 0x9b, 0x1ab: 0xcd, 0x1ac: 0x9b, 0x1ad: 0xce, 0x1ae: 0xcf, 0x1af: 0xd0,\n\t0x1b0: 0xd1, 0x1b1: 0x35, 0x1b2: 0x28, 0x1b3: 0x36, 0x1b4: 0xd2, 0x1b5: 0xd3, 0x1b6: 0xd4, 0x1b7: 0xd5,\n\t0x1b8: 0xd6, 0x1b9: 0xd7, 0x1ba: 0xd8, 0x1bb: 0xd9, 0x1bc: 0xda, 0x1bd: 0xdb, 0x1be: 0xdc, 0x1bf: 0x37,\n\t// Block 0x7, offset 0x1c0\n\t0x1c0: 0x38, 0x1c1: 0xdd, 0x1c2: 0xde, 0x1c3: 0xdf, 0x1c4: 0xe0, 0x1c5: 0x39, 0x1c6: 0x3a, 0x1c7: 0xe1,\n\t0x1c8: 0xe2, 0x1c9: 0x3b, 0x1ca: 0x3c, 0x1cb: 0x3d, 0x1cc: 0x3e, 0x1cd: 0x3f, 0x1ce: 0x40, 0x1cf: 0x41,\n\t0x1d0: 0x9f, 0x1d1: 0x9f, 0x1d2: 0x9f, 0x1d3: 0x9f, 0x1d4: 0x9f, 0x1d5: 0x9f, 0x1d6: 0x9f, 0x1d7: 0x9f,\n\t0x1d8: 0x9f, 0x1d9: 0x9f, 0x1da: 0x9f, 0x1db: 0x9f, 0x1dc: 0x9f, 0x1dd: 0x9f, 0x1de: 0x9f, 0x1df: 0x9f,\n\t0x1e0: 0x9f, 0x1e1: 0x9f, 0x1e2: 0x9f, 0x1e3: 0x9f, 0x1e4: 0x9f, 0x1e5: 0x9f, 0x1e6: 0x9f, 0x1e7: 0x9f,\n\t0x1e8: 0x9f, 0x1e9: 0x9f, 0x1ea: 0x9f, 0x1eb: 0x9f, 0x1ec: 0x9f, 0x1ed: 0x9f, 0x1ee: 0x9f, 0x1ef: 0x9f,\n\t0x1f0: 0x9f, 0x1f1: 0x9f, 0x1f2: 0x9f, 0x1f3: 0x9f, 0x1f4: 0x9f, 0x1f5: 0x9f, 0x1f6: 0x9f, 0x1f7: 0x9f,\n\t0x1f8: 0x9f, 0x1f9: 0x9f, 0x1fa: 0x9f, 0x1fb: 0x9f, 0x1fc: 0x9f, 0x1fd: 0x9f, 0x1fe: 0x9f, 0x1ff: 0x9f,\n\t// Block 0x8, offset 0x200\n\t0x200: 0x9f, 0x201: 0x9f, 0x202: 0x9f, 0x203: 0x9f, 0x204: 0x9f, 0x205: 0x9f, 0x206: 0x9f, 0x207: 0x9f,\n\t0x208: 0x9f, 0x209: 0x9f, 0x20a: 0x9f, 0x20b: 0x9f, 0x20c: 0x9f, 0x20d: 0x9f, 0x20e: 0x9f, 0x20f: 0x9f,\n\t0x210: 0x9f, 0x211: 0x9f, 0x212: 0x9f, 0x213: 0x9f, 0x214: 0x9f, 0x215: 0x9f, 0x216: 0x9f, 0x217: 0x9f,\n\t0x218: 0x9f, 0x219: 0x9f, 0x21a: 0x9f, 0x21b: 0x9f, 0x21c: 0x9f, 0x21d: 0x9f, 0x21e: 0x9f, 0x21f: 0x9f,\n\t0x220: 0x9f, 0x221: 0x9f, 0x222: 0x9f, 0x223: 0x9f, 0x224: 0x9f, 0x225: 0x9f, 0x226: 0x9f, 0x227: 0x9f,\n\t0x228: 0x9f, 0x229: 0x9f, 0x22a: 0x9f, 0x22b: 0x9f, 0x22c: 0x9f, 0x22d: 0x9f, 0x22e: 0x9f, 0x22f: 0x9f,\n\t0x230: 0x9f, 0x231: 0x9f, 0x232: 0x9f, 0x233: 0x9f, 0x234: 0x9f, 0x235: 0x9f, 0x236: 0xb2, 0x237: 0x9b,\n\t0x238: 0x9f, 0x239: 0x9f, 0x23a: 0x9f, 0x23b: 0x9f, 0x23c: 0x9f, 0x23d: 0x9f, 0x23e: 0x9f, 0x23f: 0x9f,\n\t// Block 0x9, offset 0x240\n\t0x240: 0x9f, 0x241: 0x9f, 0x242: 0x9f, 0x243: 0x9f, 0x244: 0x9f, 0x245: 0x9f, 0x246: 0x9f, 0x247: 0x9f,\n\t0x248: 0x9f, 0x249: 0x9f, 0x24a: 0x9f, 0x24b: 0x9f, 0x24c: 0x9f, 0x24d: 0x9f, 0x24e: 0x9f, 0x24f: 0x9f,\n\t0x250: 0x9f, 0x251: 0x9f, 0x252: 0x9f, 0x253: 0x9f, 0x254: 0x9f, 0x255: 0x9f, 0x256: 0x9f, 0x257: 0x9f,\n\t0x258: 0x9f, 0x259: 0x9f, 0x25a: 0x9f, 0x25b: 0x9f, 0x25c: 0x9f, 0x25d: 0x9f, 0x25e: 0x9f, 0x25f: 0x9f,\n\t0x260: 0x9f, 0x261: 0x9f, 0x262: 0x9f, 0x263: 0x9f, 0x264: 0x9f, 0x265: 0x9f, 0x266: 0x9f, 0x267: 0x9f,\n\t0x268: 0x9f, 0x269: 0x9f, 0x26a: 0x9f, 0x26b: 0x9f, 0x26c: 0x9f, 0x26d: 0x9f, 0x26e: 0x9f, 0x26f: 0x9f,\n\t0x270: 0x9f, 0x271: 0x9f, 0x272: 0x9f, 0x273: 0x9f, 0x274: 0x9f, 0x275: 0x9f, 0x276: 0x9f, 0x277: 0x9f,\n\t0x278: 0x9f, 0x279: 0x9f, 0x27a: 0x9f, 0x27b: 0x9f, 0x27c: 0x9f, 0x27d: 0x9f, 0x27e: 0x9f, 0x27f: 0x9f,\n\t// Block 0xa, offset 0x280\n\t0x280: 0x9f, 0x281: 0x9f, 0x282: 0x9f, 0x283: 0x9f, 0x284: 0x9f, 0x285: 0x9f, 0x286: 0x9f, 0x287: 0x9f,\n\t0x288: 0x9f, 0x289: 0x9f, 0x28a: 0x9f, 0x28b: 0x9f, 0x28c: 0x9f, 0x28d: 0x9f, 0x28e: 0x9f, 0x28f: 0x9f,\n\t0x290: 0x9f, 0x291: 0x9f, 0x292: 0x9f, 0x293: 0x9f, 0x294: 0x9f, 0x295: 0x9f, 0x296: 0x9f, 0x297: 0x9f,\n\t0x298: 0x9f, 0x299: 0x9f, 0x29a: 0x9f, 0x29b: 0x9f, 0x29c: 0x9f, 0x29d: 0x9f, 0x29e: 0x9f, 0x29f: 0x9f,\n\t0x2a0: 0x9f, 0x2a1: 0x9f, 0x2a2: 0x9f, 0x2a3: 0x9f, 0x2a4: 0x9f, 0x2a5: 0x9f, 0x2a6: 0x9f, 0x2a7: 0x9f,\n\t0x2a8: 0x9f, 0x2a9: 0x9f, 0x2aa: 0x9f, 0x2ab: 0x9f, 0x2ac: 0x9f, 0x2ad: 0x9f, 0x2ae: 0x9f, 0x2af: 0x9f,\n\t0x2b0: 0x9f, 0x2b1: 0x9f, 0x2b2: 0x9f, 0x2b3: 0x9f, 0x2b4: 0x9f, 0x2b5: 0x9f, 0x2b6: 0x9f, 0x2b7: 0x9f,\n\t0x2b8: 0x9f, 0x2b9: 0x9f, 0x2ba: 0x9f, 0x2bb: 0x9f, 0x2bc: 0x9f, 0x2bd: 0x9f, 0x2be: 0x9f, 0x2bf: 0xe3,\n\t// Block 0xb, offset 0x2c0\n\t0x2c0: 0x9f, 0x2c1: 0x9f, 0x2c2: 0x9f, 0x2c3: 0x9f, 0x2c4: 0x9f, 0x2c5: 0x9f, 0x2c6: 0x9f, 0x2c7: 0x9f,\n\t0x2c8: 0x9f, 0x2c9: 0x9f, 0x2ca: 0x9f, 0x2cb: 0x9f, 0x2cc: 0x9f, 0x2cd: 0x9f, 0x2ce: 0x9f, 0x2cf: 0x9f,\n\t0x2d0: 0x9f, 0x2d1: 0x9f, 0x2d2: 0xe4, 0x2d3: 0xe5, 0x2d4: 0x9f, 0x2d5: 0x9f, 0x2d6: 0x9f, 0x2d7: 0x9f,\n\t0x2d8: 0xe6, 0x2d9: 0x42, 0x2da: 0x43, 0x2db: 0xe7, 0x2dc: 0x44, 0x2dd: 0x45, 0x2de: 0x46, 0x2df: 0xe8,\n\t0x2e0: 0xe9, 0x2e1: 0xea, 0x2e2: 0xeb, 0x2e3: 0xec, 0x2e4: 0xed, 0x2e5: 0xee, 0x2e6: 0xef, 0x2e7: 0xf0,\n\t0x2e8: 0xf1, 0x2e9: 0xf2, 0x2ea: 0xf3, 0x2eb: 0xf4, 0x2ec: 0xf5, 0x2ed: 0xf6, 0x2ee: 0xf7, 0x2ef: 0xf8,\n\t0x2f0: 0x9f, 0x2f1: 0x9f, 0x2f2: 0x9f, 0x2f3: 0x9f, 0x2f4: 0x9f, 0x2f5: 0x9f, 0x2f6: 0x9f, 0x2f7: 0x9f,\n\t0x2f8: 0x9f, 0x2f9: 0x9f, 0x2fa: 0x9f, 0x2fb: 0x9f, 0x2fc: 0x9f, 0x2fd: 0x9f, 0x2fe: 0x9f, 0x2ff: 0x9f,\n\t// Block 0xc, offset 0x300\n\t0x300: 0x9f, 0x301: 0x9f, 0x302: 0x9f, 0x303: 0x9f, 0x304: 0x9f, 0x305: 0x9f, 0x306: 0x9f, 0x307: 0x9f,\n\t0x308: 0x9f, 0x309: 0x9f, 0x30a: 0x9f, 0x30b: 0x9f, 0x30c: 0x9f, 0x30d: 0x9f, 0x30e: 0x9f, 0x30f: 0x9f,\n\t0x310: 0x9f, 0x311: 0x9f, 0x312: 0x9f, 0x313: 0x9f, 0x314: 0x9f, 0x315: 0x9f, 0x316: 0x9f, 0x317: 0x9f,\n\t0x318: 0x9f, 0x319: 0x9f, 0x31a: 0x9f, 0x31b: 0x9f, 0x31c: 0x9f, 0x31d: 0x9f, 0x31e: 0xf9, 0x31f: 0xfa,\n\t// Block 0xd, offset 0x340\n\t0x340: 0xba, 0x341: 0xba, 0x342: 0xba, 0x343: 0xba, 0x344: 0xba, 0x345: 0xba, 0x346: 0xba, 0x347: 0xba,\n\t0x348: 0xba, 0x349: 0xba, 0x34a: 0xba, 0x34b: 0xba, 0x34c: 0xba, 0x34d: 0xba, 0x34e: 0xba, 0x34f: 0xba,\n\t0x350: 0xba, 0x351: 0xba, 0x352: 0xba, 0x353: 0xba, 0x354: 0xba, 0x355: 0xba, 0x356: 0xba, 0x357: 0xba,\n\t0x358: 0xba, 0x359: 0xba, 0x35a: 0xba, 0x35b: 0xba, 0x35c: 0xba, 0x35d: 0xba, 0x35e: 0xba, 0x35f: 0xba,\n\t0x360: 0xba, 0x361: 0xba, 0x362: 0xba, 0x363: 0xba, 0x364: 0xba, 0x365: 0xba, 0x366: 0xba, 0x367: 0xba,\n\t0x368: 0xba, 0x369: 0xba, 0x36a: 0xba, 0x36b: 0xba, 0x36c: 0xba, 0x36d: 0xba, 0x36e: 0xba, 0x36f: 0xba,\n\t0x370: 0xba, 0x371: 0xba, 0x372: 0xba, 0x373: 0xba, 0x374: 0xba, 0x375: 0xba, 0x376: 0xba, 0x377: 0xba,\n\t0x378: 0xba, 0x379: 0xba, 0x37a: 0xba, 0x37b: 0xba, 0x37c: 0xba, 0x37d: 0xba, 0x37e: 0xba, 0x37f: 0xba,\n\t// Block 0xe, offset 0x380\n\t0x380: 0xba, 0x381: 0xba, 0x382: 0xba, 0x383: 0xba, 0x384: 0xba, 0x385: 0xba, 0x386: 0xba, 0x387: 0xba,\n\t0x388: 0xba, 0x389: 0xba, 0x38a: 0xba, 0x38b: 0xba, 0x38c: 0xba, 0x38d: 0xba, 0x38e: 0xba, 0x38f: 0xba,\n\t0x390: 0xba, 0x391: 0xba, 0x392: 0xba, 0x393: 0xba, 0x394: 0xba, 0x395: 0xba, 0x396: 0xba, 0x397: 0xba,\n\t0x398: 0xba, 0x399: 0xba, 0x39a: 0xba, 0x39b: 0xba, 0x39c: 0xba, 0x39d: 0xba, 0x39e: 0xba, 0x39f: 0xba,\n\t0x3a0: 0xba, 0x3a1: 0xba, 0x3a2: 0xba, 0x3a3: 0xba, 0x3a4: 0xfb, 0x3a5: 0xfc, 0x3a6: 0xfd, 0x3a7: 0xfe,\n\t0x3a8: 0x47, 0x3a9: 0xff, 0x3aa: 0x100, 0x3ab: 0x48, 0x3ac: 0x49, 0x3ad: 0x4a, 0x3ae: 0x4b, 0x3af: 0x4c,\n\t0x3b0: 0x101, 0x3b1: 0x4d, 0x3b2: 0x4e, 0x3b3: 0x4f, 0x3b4: 0x50, 0x3b5: 0x51, 0x3b6: 0x102, 0x3b7: 0x52,\n\t0x3b8: 0x53, 0x3b9: 0x54, 0x3ba: 0x55, 0x3bb: 0x56, 0x3bc: 0x57, 0x3bd: 0x58, 0x3be: 0x59, 0x3bf: 0x5a,\n\t// Block 0xf, offset 0x3c0\n\t0x3c0: 0x103, 0x3c1: 0x104, 0x3c2: 0x9f, 0x3c3: 0x105, 0x3c4: 0x106, 0x3c5: 0x9b, 0x3c6: 0x107, 0x3c7: 0x108,\n\t0x3c8: 0xba, 0x3c9: 0xba, 0x3ca: 0x109, 0x3cb: 0x10a, 0x3cc: 0x10b, 0x3cd: 0x10c, 0x3ce: 0x10d, 0x3cf: 0x10e,\n\t0x3d0: 0x10f, 0x3d1: 0x9f, 0x3d2: 0x110, 0x3d3: 0x111, 0x3d4: 0x112, 0x3d5: 0x113, 0x3d6: 0xba, 0x3d7: 0xba,\n\t0x3d8: 0x9f, 0x3d9: 0x9f, 0x3da: 0x9f, 0x3db: 0x9f, 0x3dc: 0x114, 0x3dd: 0x115, 0x3de: 0xba, 0x3df: 0xba,\n\t0x3e0: 0x116, 0x3e1: 0x117, 0x3e2: 0x118, 0x3e3: 0x119, 0x3e4: 0x11a, 0x3e5: 0xba, 0x3e6: 0x11b, 0x3e7: 0x11c,\n\t0x3e8: 0x11d, 0x3e9: 0x11e, 0x3ea: 0x11f, 0x3eb: 0x5b, 0x3ec: 0x120, 0x3ed: 0x121, 0x3ee: 0x5c, 0x3ef: 0xba,\n\t0x3f0: 0x122, 0x3f1: 0x123, 0x3f2: 0x124, 0x3f3: 0x125, 0x3f4: 0x126, 0x3f5: 0xba, 0x3f6: 0xba, 0x3f7: 0xba,\n\t0x3f8: 0xba, 0x3f9: 0x127, 0x3fa: 0xba, 0x3fb: 0xba, 0x3fc: 0x128, 0x3fd: 0x129, 0x3fe: 0xba, 0x3ff: 0xba,\n\t// Block 0x10, offset 0x400\n\t0x400: 0x12a, 0x401: 0x12b, 0x402: 0x12c, 0x403: 0x12d, 0x404: 0x12e, 0x405: 0x12f, 0x406: 0x130, 0x407: 0x131,\n\t0x408: 0x132, 0x409: 0xba, 0x40a: 0x133, 0x40b: 0x134, 0x40c: 0x5d, 0x40d: 0x5e, 0x40e: 0xba, 0x40f: 0xba,\n\t0x410: 0x135, 0x411: 0x136, 0x412: 0x137, 0x413: 0x138, 0x414: 0xba, 0x415: 0xba, 0x416: 0x139, 0x417: 0x13a,\n\t0x418: 0x13b, 0x419: 0x13c, 0x41a: 0x13d, 0x41b: 0x13e, 0x41c: 0x13f, 0x41d: 0xba, 0x41e: 0xba, 0x41f: 0xba,\n\t0x420: 0x140, 0x421: 0xba, 0x422: 0x141, 0x423: 0x142, 0x424: 0xba, 0x425: 0xba, 0x426: 0xba, 0x427: 0xba,\n\t0x428: 0x143, 0x429: 0x144, 0x42a: 0x145, 0x42b: 0x146, 0x42c: 0xba, 0x42d: 0xba, 0x42e: 0xba, 0x42f: 0xba,\n\t0x430: 0x147, 0x431: 0x148, 0x432: 0x149, 0x433: 0xba, 0x434: 0x14a, 0x435: 0x14b, 0x436: 0x14c, 0x437: 0xba,\n\t0x438: 0xba, 0x439: 0xba, 0x43a: 0xba, 0x43b: 0x14d, 0x43c: 0xba, 0x43d: 0xba, 0x43e: 0xba, 0x43f: 0xba,\n\t// Block 0x11, offset 0x440\n\t0x440: 0x9f, 0x441: 0x9f, 0x442: 0x9f, 0x443: 0x9f, 0x444: 0x9f, 0x445: 0x9f, 0x446: 0x9f, 0x447: 0x9f,\n\t0x448: 0x9f, 0x449: 0x9f, 0x44a: 0x9f, 0x44b: 0x9f, 0x44c: 0x9f, 0x44d: 0x9f, 0x44e: 0x14e, 0x44f: 0xba,\n\t0x450: 0x9b, 0x451: 0x14f, 0x452: 0x9f, 0x453: 0x9f, 0x454: 0x9f, 0x455: 0x150, 0x456: 0xba, 0x457: 0xba,\n\t0x458: 0xba, 0x459: 0xba, 0x45a: 0xba, 0x45b: 0xba, 0x45c: 0xba, 0x45d: 0xba, 0x45e: 0xba, 0x45f: 0xba,\n\t0x460: 0xba, 0x461: 0xba, 0x462: 0xba, 0x463: 0xba, 0x464: 0xba, 0x465: 0xba, 0x466: 0xba, 0x467: 0xba,\n\t0x468: 0xba, 0x469: 0xba, 0x46a: 0xba, 0x46b: 0xba, 0x46c: 0xba, 0x46d: 0xba, 0x46e: 0xba, 0x46f: 0xba,\n\t0x470: 0xba, 0x471: 0xba, 0x472: 0xba, 0x473: 0xba, 0x474: 0xba, 0x475: 0xba, 0x476: 0xba, 0x477: 0xba,\n\t0x478: 0xba, 0x479: 0xba, 0x47a: 0xba, 0x47b: 0xba, 0x47c: 0xba, 0x47d: 0xba, 0x47e: 0xba, 0x47f: 0xba,\n\t// Block 0x12, offset 0x480\n\t0x480: 0x9f, 0x481: 0x9f, 0x482: 0x9f, 0x483: 0x9f, 0x484: 0x9f, 0x485: 0x9f, 0x486: 0x9f, 0x487: 0x9f,\n\t0x488: 0x9f, 0x489: 0x9f, 0x48a: 0x9f, 0x48b: 0x9f, 0x48c: 0x9f, 0x48d: 0x9f, 0x48e: 0x9f, 0x48f: 0x9f,\n\t0x490: 0x151, 0x491: 0xba, 0x492: 0xba, 0x493: 0xba, 0x494: 0xba, 0x495: 0xba, 0x496: 0xba, 0x497: 0xba,\n\t0x498: 0xba, 0x499: 0xba, 0x49a: 0xba, 0x49b: 0xba, 0x49c: 0xba, 0x49d: 0xba, 0x49e: 0xba, 0x49f: 0xba,\n\t0x4a0: 0xba, 0x4a1: 0xba, 0x4a2: 0xba, 0x4a3: 0xba, 0x4a4: 0xba, 0x4a5: 0xba, 0x4a6: 0xba, 0x4a7: 0xba,\n\t0x4a8: 0xba, 0x4a9: 0xba, 0x4aa: 0xba, 0x4ab: 0xba, 0x4ac: 0xba, 0x4ad: 0xba, 0x4ae: 0xba, 0x4af: 0xba,\n\t0x4b0: 0xba, 0x4b1: 0xba, 0x4b2: 0xba, 0x4b3: 0xba, 0x4b4: 0xba, 0x4b5: 0xba, 0x4b6: 0xba, 0x4b7: 0xba,\n\t0x4b8: 0xba, 0x4b9: 0xba, 0x4ba: 0xba, 0x4bb: 0xba, 0x4bc: 0xba, 0x4bd: 0xba, 0x4be: 0xba, 0x4bf: 0xba,\n\t// Block 0x13, offset 0x4c0\n\t0x4c0: 0xba, 0x4c1: 0xba, 0x4c2: 0xba, 0x4c3: 0xba, 0x4c4: 0xba, 0x4c5: 0xba, 0x4c6: 0xba, 0x4c7: 0xba,\n\t0x4c8: 0xba, 0x4c9: 0xba, 0x4ca: 0xba, 0x4cb: 0xba, 0x4cc: 0xba, 0x4cd: 0xba, 0x4ce: 0xba, 0x4cf: 0xba,\n\t0x4d0: 0x9f, 0x4d1: 0x9f, 0x4d2: 0x9f, 0x4d3: 0x9f, 0x4d4: 0x9f, 0x4d5: 0x9f, 0x4d6: 0x9f, 0x4d7: 0x9f,\n\t0x4d8: 0x9f, 0x4d9: 0x152, 0x4da: 0xba, 0x4db: 0xba, 0x4dc: 0xba, 0x4dd: 0xba, 0x4de: 0xba, 0x4df: 0xba,\n\t0x4e0: 0xba, 0x4e1: 0xba, 0x4e2: 0xba, 0x4e3: 0xba, 0x4e4: 0xba, 0x4e5: 0xba, 0x4e6: 0xba, 0x4e7: 0xba,\n\t0x4e8: 0xba, 0x4e9: 0xba, 0x4ea: 0xba, 0x4eb: 0xba, 0x4ec: 0xba, 0x4ed: 0xba, 0x4ee: 0xba, 0x4ef: 0xba,\n\t0x4f0: 0xba, 0x4f1: 0xba, 0x4f2: 0xba, 0x4f3: 0xba, 0x4f4: 0xba, 0x4f5: 0xba, 0x4f6: 0xba, 0x4f7: 0xba,\n\t0x4f8: 0xba, 0x4f9: 0xba, 0x4fa: 0xba, 0x4fb: 0xba, 0x4fc: 0xba, 0x4fd: 0xba, 0x4fe: 0xba, 0x4ff: 0xba,\n\t// Block 0x14, offset 0x500\n\t0x500: 0xba, 0x501: 0xba, 0x502: 0xba, 0x503: 0xba, 0x504: 0xba, 0x505: 0xba, 0x506: 0xba, 0x507: 0xba,\n\t0x508: 0xba, 0x509: 0xba, 0x50a: 0xba, 0x50b: 0xba, 0x50c: 0xba, 0x50d: 0xba, 0x50e: 0xba, 0x50f: 0xba,\n\t0x510: 0xba, 0x511: 0xba, 0x512: 0xba, 0x513: 0xba, 0x514: 0xba, 0x515: 0xba, 0x516: 0xba, 0x517: 0xba,\n\t0x518: 0xba, 0x519: 0xba, 0x51a: 0xba, 0x51b: 0xba, 0x51c: 0xba, 0x51d: 0xba, 0x51e: 0xba, 0x51f: 0xba,\n\t0x520: 0x9f, 0x521: 0x9f, 0x522: 0x9f, 0x523: 0x9f, 0x524: 0x9f, 0x525: 0x9f, 0x526: 0x9f, 0x527: 0x9f,\n\t0x528: 0x146, 0x529: 0x153, 0x52a: 0xba, 0x52b: 0x154, 0x52c: 0x155, 0x52d: 0x156, 0x52e: 0x157, 0x52f: 0xba,\n\t0x530: 0xba, 0x531: 0xba, 0x532: 0xba, 0x533: 0xba, 0x534: 0xba, 0x535: 0xba, 0x536: 0xba, 0x537: 0xba,\n\t0x538: 0xba, 0x539: 0x158, 0x53a: 0x159, 0x53b: 0xba, 0x53c: 0x9f, 0x53d: 0x15a, 0x53e: 0x15b, 0x53f: 0x15c,\n\t// Block 0x15, offset 0x540\n\t0x540: 0x9f, 0x541: 0x9f, 0x542: 0x9f, 0x543: 0x9f, 0x544: 0x9f, 0x545: 0x9f, 0x546: 0x9f, 0x547: 0x9f,\n\t0x548: 0x9f, 0x549: 0x9f, 0x54a: 0x9f, 0x54b: 0x9f, 0x54c: 0x9f, 0x54d: 0x9f, 0x54e: 0x9f, 0x54f: 0x9f,\n\t0x550: 0x9f, 0x551: 0x9f, 0x552: 0x9f, 0x553: 0x9f, 0x554: 0x9f, 0x555: 0x9f, 0x556: 0x9f, 0x557: 0x9f,\n\t0x558: 0x9f, 0x559: 0x9f, 0x55a: 0x9f, 0x55b: 0x9f, 0x55c: 0x9f, 0x55d: 0x9f, 0x55e: 0x9f, 0x55f: 0x15d,\n\t0x560: 0x9f, 0x561: 0x9f, 0x562: 0x9f, 0x563: 0x9f, 0x564: 0x9f, 0x565: 0x9f, 0x566: 0x9f, 0x567: 0x9f,\n\t0x568: 0x9f, 0x569: 0x9f, 0x56a: 0x9f, 0x56b: 0x15e, 0x56c: 0xba, 0x56d: 0xba, 0x56e: 0xba, 0x56f: 0xba,\n\t0x570: 0xba, 0x571: 0xba, 0x572: 0xba, 0x573: 0xba, 0x574: 0xba, 0x575: 0xba, 0x576: 0xba, 0x577: 0xba,\n\t0x578: 0xba, 0x579: 0xba, 0x57a: 0xba, 0x57b: 0xba, 0x57c: 0xba, 0x57d: 0xba, 0x57e: 0xba, 0x57f: 0xba,\n\t// Block 0x16, offset 0x580\n\t0x580: 0x9f, 0x581: 0x9f, 0x582: 0x9f, 0x583: 0x9f, 0x584: 0x15f, 0x585: 0x160, 0x586: 0x9f, 0x587: 0x9f,\n\t0x588: 0x9f, 0x589: 0x9f, 0x58a: 0x9f, 0x58b: 0x161, 0x58c: 0xba, 0x58d: 0xba, 0x58e: 0xba, 0x58f: 0xba,\n\t0x590: 0xba, 0x591: 0xba, 0x592: 0xba, 0x593: 0xba, 0x594: 0xba, 0x595: 0xba, 0x596: 0xba, 0x597: 0xba,\n\t0x598: 0xba, 0x599: 0xba, 0x59a: 0xba, 0x59b: 0xba, 0x59c: 0xba, 0x59d: 0xba, 0x59e: 0xba, 0x59f: 0xba,\n\t0x5a0: 0xba, 0x5a1: 0xba, 0x5a2: 0xba, 0x5a3: 0xba, 0x5a4: 0xba, 0x5a5: 0xba, 0x5a6: 0xba, 0x5a7: 0xba,\n\t0x5a8: 0xba, 0x5a9: 0xba, 0x5aa: 0xba, 0x5ab: 0xba, 0x5ac: 0xba, 0x5ad: 0xba, 0x5ae: 0xba, 0x5af: 0xba,\n\t0x5b0: 0x9f, 0x5b1: 0x162, 0x5b2: 0x163, 0x5b3: 0xba, 0x5b4: 0xba, 0x5b5: 0xba, 0x5b6: 0xba, 0x5b7: 0xba,\n\t0x5b8: 0xba, 0x5b9: 0xba, 0x5ba: 0xba, 0x5bb: 0xba, 0x5bc: 0xba, 0x5bd: 0xba, 0x5be: 0xba, 0x5bf: 0xba,\n\t// Block 0x17, offset 0x5c0\n\t0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x164, 0x5c4: 0x165, 0x5c5: 0x166, 0x5c6: 0x167, 0x5c7: 0x168,\n\t0x5c8: 0x9b, 0x5c9: 0x169, 0x5ca: 0xba, 0x5cb: 0x16a, 0x5cc: 0x9b, 0x5cd: 0x16b, 0x5ce: 0xba, 0x5cf: 0xba,\n\t0x5d0: 0x5f, 0x5d1: 0x60, 0x5d2: 0x61, 0x5d3: 0x62, 0x5d4: 0x63, 0x5d5: 0x64, 0x5d6: 0x65, 0x5d7: 0x66,\n\t0x5d8: 0x67, 0x5d9: 0x68, 0x5da: 0x69, 0x5db: 0x6a, 0x5dc: 0x6b, 0x5dd: 0x6c, 0x5de: 0x6d, 0x5df: 0x6e,\n\t0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b,\n\t0x5e8: 0x16c, 0x5e9: 0x16d, 0x5ea: 0x16e, 0x5eb: 0xba, 0x5ec: 0xba, 0x5ed: 0xba, 0x5ee: 0xba, 0x5ef: 0xba,\n\t0x5f0: 0xba, 0x5f1: 0xba, 0x5f2: 0xba, 0x5f3: 0xba, 0x5f4: 0xba, 0x5f5: 0xba, 0x5f6: 0xba, 0x5f7: 0xba,\n\t0x5f8: 0xba, 0x5f9: 0xba, 0x5fa: 0xba, 0x5fb: 0xba, 0x5fc: 0xba, 0x5fd: 0xba, 0x5fe: 0xba, 0x5ff: 0xba,\n\t// Block 0x18, offset 0x600\n\t0x600: 0x16f, 0x601: 0xba, 0x602: 0xba, 0x603: 0xba, 0x604: 0xba, 0x605: 0xba, 0x606: 0xba, 0x607: 0xba,\n\t0x608: 0xba, 0x609: 0xba, 0x60a: 0xba, 0x60b: 0xba, 0x60c: 0xba, 0x60d: 0xba, 0x60e: 0xba, 0x60f: 0xba,\n\t0x610: 0xba, 0x611: 0xba, 0x612: 0xba, 0x613: 0xba, 0x614: 0xba, 0x615: 0xba, 0x616: 0xba, 0x617: 0xba,\n\t0x618: 0xba, 0x619: 0xba, 0x61a: 0xba, 0x61b: 0xba, 0x61c: 0xba, 0x61d: 0xba, 0x61e: 0xba, 0x61f: 0xba,\n\t0x620: 0x122, 0x621: 0x122, 0x622: 0x122, 0x623: 0x170, 0x624: 0x6f, 0x625: 0x171, 0x626: 0xba, 0x627: 0xba,\n\t0x628: 0xba, 0x629: 0xba, 0x62a: 0xba, 0x62b: 0xba, 0x62c: 0xba, 0x62d: 0xba, 0x62e: 0xba, 0x62f: 0xba,\n\t0x630: 0xba, 0x631: 0x172, 0x632: 0x173, 0x633: 0xba, 0x634: 0xba, 0x635: 0xba, 0x636: 0xba, 0x637: 0xba,\n\t0x638: 0x70, 0x639: 0x71, 0x63a: 0x72, 0x63b: 0x174, 0x63c: 0xba, 0x63d: 0xba, 0x63e: 0xba, 0x63f: 0xba,\n\t// Block 0x19, offset 0x640\n\t0x640: 0x175, 0x641: 0x9b, 0x642: 0x176, 0x643: 0x177, 0x644: 0x73, 0x645: 0x74, 0x646: 0x178, 0x647: 0x179,\n\t0x648: 0x75, 0x649: 0x17a, 0x64a: 0xba, 0x64b: 0xba, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b,\n\t0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b,\n\t0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x17b, 0x65c: 0x9b, 0x65d: 0x17c, 0x65e: 0x9b, 0x65f: 0x17d,\n\t0x660: 0x17e, 0x661: 0x17f, 0x662: 0x180, 0x663: 0xba, 0x664: 0x181, 0x665: 0x182, 0x666: 0x183, 0x667: 0x184,\n\t0x668: 0xba, 0x669: 0x185, 0x66a: 0xba, 0x66b: 0xba, 0x66c: 0xba, 0x66d: 0xba, 0x66e: 0xba, 0x66f: 0xba,\n\t0x670: 0xba, 0x671: 0xba, 0x672: 0xba, 0x673: 0xba, 0x674: 0xba, 0x675: 0xba, 0x676: 0xba, 0x677: 0xba,\n\t0x678: 0xba, 0x679: 0xba, 0x67a: 0xba, 0x67b: 0xba, 0x67c: 0xba, 0x67d: 0xba, 0x67e: 0xba, 0x67f: 0xba,\n\t// Block 0x1a, offset 0x680\n\t0x680: 0x9f, 0x681: 0x9f, 0x682: 0x9f, 0x683: 0x9f, 0x684: 0x9f, 0x685: 0x9f, 0x686: 0x9f, 0x687: 0x9f,\n\t0x688: 0x9f, 0x689: 0x9f, 0x68a: 0x9f, 0x68b: 0x9f, 0x68c: 0x9f, 0x68d: 0x9f, 0x68e: 0x9f, 0x68f: 0x9f,\n\t0x690: 0x9f, 0x691: 0x9f, 0x692: 0x9f, 0x693: 0x9f, 0x694: 0x9f, 0x695: 0x9f, 0x696: 0x9f, 0x697: 0x9f,\n\t0x698: 0x9f, 0x699: 0x9f, 0x69a: 0x9f, 0x69b: 0x186, 0x69c: 0x9f, 0x69d: 0x9f, 0x69e: 0x9f, 0x69f: 0x9f,\n\t0x6a0: 0x9f, 0x6a1: 0x9f, 0x6a2: 0x9f, 0x6a3: 0x9f, 0x6a4: 0x9f, 0x6a5: 0x9f, 0x6a6: 0x9f, 0x6a7: 0x9f,\n\t0x6a8: 0x9f, 0x6a9: 0x9f, 0x6aa: 0x9f, 0x6ab: 0x9f, 0x6ac: 0x9f, 0x6ad: 0x9f, 0x6ae: 0x9f, 0x6af: 0x9f,\n\t0x6b0: 0x9f, 0x6b1: 0x9f, 0x6b2: 0x9f, 0x6b3: 0x9f, 0x6b4: 0x9f, 0x6b5: 0x9f, 0x6b6: 0x9f, 0x6b7: 0x9f,\n\t0x6b8: 0x9f, 0x6b9: 0x9f, 0x6ba: 0x9f, 0x6bb: 0x9f, 0x6bc: 0x9f, 0x6bd: 0x9f, 0x6be: 0x9f, 0x6bf: 0x9f,\n\t// Block 0x1b, offset 0x6c0\n\t0x6c0: 0x9f, 0x6c1: 0x9f, 0x6c2: 0x9f, 0x6c3: 0x9f, 0x6c4: 0x9f, 0x6c5: 0x9f, 0x6c6: 0x9f, 0x6c7: 0x9f,\n\t0x6c8: 0x9f, 0x6c9: 0x9f, 0x6ca: 0x9f, 0x6cb: 0x9f, 0x6cc: 0x9f, 0x6cd: 0x9f, 0x6ce: 0x9f, 0x6cf: 0x9f,\n\t0x6d0: 0x9f, 0x6d1: 0x9f, 0x6d2: 0x9f, 0x6d3: 0x9f, 0x6d4: 0x9f, 0x6d5: 0x9f, 0x6d6: 0x9f, 0x6d7: 0x9f,\n\t0x6d8: 0x9f, 0x6d9: 0x9f, 0x6da: 0x9f, 0x6db: 0x9f, 0x6dc: 0x187, 0x6dd: 0x9f, 0x6de: 0x9f, 0x6df: 0x9f,\n\t0x6e0: 0x188, 0x6e1: 0x9f, 0x6e2: 0x9f, 0x6e3: 0x9f, 0x6e4: 0x9f, 0x6e5: 0x9f, 0x6e6: 0x9f, 0x6e7: 0x9f,\n\t0x6e8: 0x9f, 0x6e9: 0x9f, 0x6ea: 0x9f, 0x6eb: 0x9f, 0x6ec: 0x9f, 0x6ed: 0x9f, 0x6ee: 0x9f, 0x6ef: 0x9f,\n\t0x6f0: 0x9f, 0x6f1: 0x9f, 0x6f2: 0x9f, 0x6f3: 0x9f, 0x6f4: 0x9f, 0x6f5: 0x9f, 0x6f6: 0x9f, 0x6f7: 0x9f,\n\t0x6f8: 0x9f, 0x6f9: 0x9f, 0x6fa: 0x9f, 0x6fb: 0x9f, 0x6fc: 0x9f, 0x6fd: 0x9f, 0x6fe: 0x9f, 0x6ff: 0x9f,\n\t// Block 0x1c, offset 0x700\n\t0x700: 0x9f, 0x701: 0x9f, 0x702: 0x9f, 0x703: 0x9f, 0x704: 0x9f, 0x705: 0x9f, 0x706: 0x9f, 0x707: 0x9f,\n\t0x708: 0x9f, 0x709: 0x9f, 0x70a: 0x9f, 0x70b: 0x9f, 0x70c: 0x9f, 0x70d: 0x9f, 0x70e: 0x9f, 0x70f: 0x9f,\n\t0x710: 0x9f, 0x711: 0x9f, 0x712: 0x9f, 0x713: 0x9f, 0x714: 0x9f, 0x715: 0x9f, 0x716: 0x9f, 0x717: 0x9f,\n\t0x718: 0x9f, 0x719: 0x9f, 0x71a: 0x9f, 0x71b: 0x9f, 0x71c: 0x9f, 0x71d: 0x9f, 0x71e: 0x9f, 0x71f: 0x9f,\n\t0x720: 0x9f, 0x721: 0x9f, 0x722: 0x9f, 0x723: 0x9f, 0x724: 0x9f, 0x725: 0x9f, 0x726: 0x9f, 0x727: 0x9f,\n\t0x728: 0x9f, 0x729: 0x9f, 0x72a: 0x9f, 0x72b: 0x9f, 0x72c: 0x9f, 0x72d: 0x9f, 0x72e: 0x9f, 0x72f: 0x9f,\n\t0x730: 0x9f, 0x731: 0x9f, 0x732: 0x9f, 0x733: 0x9f, 0x734: 0x9f, 0x735: 0x9f, 0x736: 0x9f, 0x737: 0x9f,\n\t0x738: 0x9f, 0x739: 0x9f, 0x73a: 0x189, 0x73b: 0x9f, 0x73c: 0x9f, 0x73d: 0x9f, 0x73e: 0x9f, 0x73f: 0x9f,\n\t// Block 0x1d, offset 0x740\n\t0x740: 0x9f, 0x741: 0x9f, 0x742: 0x9f, 0x743: 0x9f, 0x744: 0x9f, 0x745: 0x9f, 0x746: 0x9f, 0x747: 0x9f,\n\t0x748: 0x9f, 0x749: 0x9f, 0x74a: 0x9f, 0x74b: 0x9f, 0x74c: 0x9f, 0x74d: 0x9f, 0x74e: 0x9f, 0x74f: 0x9f,\n\t0x750: 0x9f, 0x751: 0x9f, 0x752: 0x9f, 0x753: 0x9f, 0x754: 0x9f, 0x755: 0x9f, 0x756: 0x9f, 0x757: 0x9f,\n\t0x758: 0x9f, 0x759: 0x9f, 0x75a: 0x9f, 0x75b: 0x9f, 0x75c: 0x9f, 0x75d: 0x9f, 0x75e: 0x9f, 0x75f: 0x9f,\n\t0x760: 0x9f, 0x761: 0x9f, 0x762: 0x9f, 0x763: 0x9f, 0x764: 0x9f, 0x765: 0x9f, 0x766: 0x9f, 0x767: 0x9f,\n\t0x768: 0x9f, 0x769: 0x9f, 0x76a: 0x9f, 0x76b: 0x9f, 0x76c: 0x9f, 0x76d: 0x9f, 0x76e: 0x9f, 0x76f: 0x18a,\n\t0x770: 0xba, 0x771: 0xba, 0x772: 0xba, 0x773: 0xba, 0x774: 0xba, 0x775: 0xba, 0x776: 0xba, 0x777: 0xba,\n\t0x778: 0xba, 0x779: 0xba, 0x77a: 0xba, 0x77b: 0xba, 0x77c: 0xba, 0x77d: 0xba, 0x77e: 0xba, 0x77f: 0xba,\n\t// Block 0x1e, offset 0x780\n\t0x780: 0xba, 0x781: 0xba, 0x782: 0xba, 0x783: 0xba, 0x784: 0xba, 0x785: 0xba, 0x786: 0xba, 0x787: 0xba,\n\t0x788: 0xba, 0x789: 0xba, 0x78a: 0xba, 0x78b: 0xba, 0x78c: 0xba, 0x78d: 0xba, 0x78e: 0xba, 0x78f: 0xba,\n\t0x790: 0xba, 0x791: 0xba, 0x792: 0xba, 0x793: 0xba, 0x794: 0xba, 0x795: 0xba, 0x796: 0xba, 0x797: 0xba,\n\t0x798: 0xba, 0x799: 0xba, 0x79a: 0xba, 0x79b: 0xba, 0x79c: 0xba, 0x79d: 0xba, 0x79e: 0xba, 0x79f: 0xba,\n\t0x7a0: 0x76, 0x7a1: 0x77, 0x7a2: 0x78, 0x7a3: 0x18b, 0x7a4: 0x79, 0x7a5: 0x7a, 0x7a6: 0x18c, 0x7a7: 0x7b,\n\t0x7a8: 0x7c, 0x7a9: 0xba, 0x7aa: 0xba, 0x7ab: 0xba, 0x7ac: 0xba, 0x7ad: 0xba, 0x7ae: 0xba, 0x7af: 0xba,\n\t0x7b0: 0xba, 0x7b1: 0xba, 0x7b2: 0xba, 0x7b3: 0xba, 0x7b4: 0xba, 0x7b5: 0xba, 0x7b6: 0xba, 0x7b7: 0xba,\n\t0x7b8: 0xba, 0x7b9: 0xba, 0x7ba: 0xba, 0x7bb: 0xba, 0x7bc: 0xba, 0x7bd: 0xba, 0x7be: 0xba, 0x7bf: 0xba,\n\t// Block 0x1f, offset 0x7c0\n\t0x7d0: 0x0d, 0x7d1: 0x0e, 0x7d2: 0x0f, 0x7d3: 0x10, 0x7d4: 0x11, 0x7d5: 0x0b, 0x7d6: 0x12, 0x7d7: 0x07,\n\t0x7d8: 0x13, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x14, 0x7dc: 0x0b, 0x7dd: 0x15, 0x7de: 0x16, 0x7df: 0x17,\n\t0x7e0: 0x07, 0x7e1: 0x07, 0x7e2: 0x07, 0x7e3: 0x07, 0x7e4: 0x07, 0x7e5: 0x07, 0x7e6: 0x07, 0x7e7: 0x07,\n\t0x7e8: 0x07, 0x7e9: 0x07, 0x7ea: 0x18, 0x7eb: 0x19, 0x7ec: 0x1a, 0x7ed: 0x07, 0x7ee: 0x1b, 0x7ef: 0x1c,\n\t0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b,\n\t0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b,\n\t// Block 0x20, offset 0x800\n\t0x800: 0x0b, 0x801: 0x0b, 0x802: 0x0b, 0x803: 0x0b, 0x804: 0x0b, 0x805: 0x0b, 0x806: 0x0b, 0x807: 0x0b,\n\t0x808: 0x0b, 0x809: 0x0b, 0x80a: 0x0b, 0x80b: 0x0b, 0x80c: 0x0b, 0x80d: 0x0b, 0x80e: 0x0b, 0x80f: 0x0b,\n\t0x810: 0x0b, 0x811: 0x0b, 0x812: 0x0b, 0x813: 0x0b, 0x814: 0x0b, 0x815: 0x0b, 0x816: 0x0b, 0x817: 0x0b,\n\t0x818: 0x0b, 0x819: 0x0b, 0x81a: 0x0b, 0x81b: 0x0b, 0x81c: 0x0b, 0x81d: 0x0b, 0x81e: 0x0b, 0x81f: 0x0b,\n\t0x820: 0x0b, 0x821: 0x0b, 0x822: 0x0b, 0x823: 0x0b, 0x824: 0x0b, 0x825: 0x0b, 0x826: 0x0b, 0x827: 0x0b,\n\t0x828: 0x0b, 0x829: 0x0b, 0x82a: 0x0b, 0x82b: 0x0b, 0x82c: 0x0b, 0x82d: 0x0b, 0x82e: 0x0b, 0x82f: 0x0b,\n\t0x830: 0x0b, 0x831: 0x0b, 0x832: 0x0b, 0x833: 0x0b, 0x834: 0x0b, 0x835: 0x0b, 0x836: 0x0b, 0x837: 0x0b,\n\t0x838: 0x0b, 0x839: 0x0b, 0x83a: 0x0b, 0x83b: 0x0b, 0x83c: 0x0b, 0x83d: 0x0b, 0x83e: 0x0b, 0x83f: 0x0b,\n\t// Block 0x21, offset 0x840\n\t0x840: 0x18d, 0x841: 0x18e, 0x842: 0xba, 0x843: 0xba, 0x844: 0x18f, 0x845: 0x18f, 0x846: 0x18f, 0x847: 0x190,\n\t0x848: 0xba, 0x849: 0xba, 0x84a: 0xba, 0x84b: 0xba, 0x84c: 0xba, 0x84d: 0xba, 0x84e: 0xba, 0x84f: 0xba,\n\t0x850: 0xba, 0x851: 0xba, 0x852: 0xba, 0x853: 0xba, 0x854: 0xba, 0x855: 0xba, 0x856: 0xba, 0x857: 0xba,\n\t0x858: 0xba, 0x859: 0xba, 0x85a: 0xba, 0x85b: 0xba, 0x85c: 0xba, 0x85d: 0xba, 0x85e: 0xba, 0x85f: 0xba,\n\t0x860: 0xba, 0x861: 0xba, 0x862: 0xba, 0x863: 0xba, 0x864: 0xba, 0x865: 0xba, 0x866: 0xba, 0x867: 0xba,\n\t0x868: 0xba, 0x869: 0xba, 0x86a: 0xba, 0x86b: 0xba, 0x86c: 0xba, 0x86d: 0xba, 0x86e: 0xba, 0x86f: 0xba,\n\t0x870: 0xba, 0x871: 0xba, 0x872: 0xba, 0x873: 0xba, 0x874: 0xba, 0x875: 0xba, 0x876: 0xba, 0x877: 0xba,\n\t0x878: 0xba, 0x879: 0xba, 0x87a: 0xba, 0x87b: 0xba, 0x87c: 0xba, 0x87d: 0xba, 0x87e: 0xba, 0x87f: 0xba,\n\t// Block 0x22, offset 0x880\n\t0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b,\n\t0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b,\n\t0x890: 0x0b, 0x891: 0x0b, 0x892: 0x0b, 0x893: 0x0b, 0x894: 0x0b, 0x895: 0x0b, 0x896: 0x0b, 0x897: 0x0b,\n\t0x898: 0x0b, 0x899: 0x0b, 0x89a: 0x0b, 0x89b: 0x0b, 0x89c: 0x0b, 0x89d: 0x0b, 0x89e: 0x0b, 0x89f: 0x0b,\n\t0x8a0: 0x1f, 0x8a1: 0x0b, 0x8a2: 0x0b, 0x8a3: 0x0b, 0x8a4: 0x0b, 0x8a5: 0x0b, 0x8a6: 0x0b, 0x8a7: 0x0b,\n\t0x8a8: 0x0b, 0x8a9: 0x0b, 0x8aa: 0x0b, 0x8ab: 0x0b, 0x8ac: 0x0b, 0x8ad: 0x0b, 0x8ae: 0x0b, 0x8af: 0x0b,\n\t0x8b0: 0x0b, 0x8b1: 0x0b, 0x8b2: 0x0b, 0x8b3: 0x0b, 0x8b4: 0x0b, 0x8b5: 0x0b, 0x8b6: 0x0b, 0x8b7: 0x0b,\n\t0x8b8: 0x0b, 0x8b9: 0x0b, 0x8ba: 0x0b, 0x8bb: 0x0b, 0x8bc: 0x0b, 0x8bd: 0x0b, 0x8be: 0x0b, 0x8bf: 0x0b,\n\t// Block 0x23, offset 0x8c0\n\t0x8c0: 0x0b, 0x8c1: 0x0b, 0x8c2: 0x0b, 0x8c3: 0x0b, 0x8c4: 0x0b, 0x8c5: 0x0b, 0x8c6: 0x0b, 0x8c7: 0x0b,\n\t0x8c8: 0x0b, 0x8c9: 0x0b, 0x8ca: 0x0b, 0x8cb: 0x0b, 0x8cc: 0x0b, 0x8cd: 0x0b, 0x8ce: 0x0b, 0x8cf: 0x0b,\n}\n\n// idnaSparseOffset: 276 entries, 552 bytes\nvar idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x33, 0x3e, 0x4a, 0x4e, 0x5d, 0x62, 0x6c, 0x78, 0x86, 0x8b, 0x94, 0xa4, 0xb2, 0xbe, 0xca, 0xdb, 0xe5, 0xec, 0xf9, 0x10a, 0x111, 0x11c, 0x12b, 0x139, 0x143, 0x145, 0x14a, 0x14d, 0x150, 0x152, 0x15e, 0x169, 0x171, 0x177, 0x17d, 0x182, 0x187, 0x18a, 0x18e, 0x194, 0x199, 0x1a5, 0x1af, 0x1b5, 0x1c6, 0x1d0, 0x1d3, 0x1db, 0x1de, 0x1eb, 0x1f3, 0x1f7, 0x1fe, 0x206, 0x216, 0x222, 0x224, 0x22e, 0x23a, 0x246, 0x252, 0x25a, 0x25f, 0x269, 0x27a, 0x27e, 0x289, 0x28d, 0x296, 0x29e, 0x2a4, 0x2a9, 0x2ac, 0x2b0, 0x2b6, 0x2ba, 0x2be, 0x2c2, 0x2c7, 0x2cd, 0x2d5, 0x2dc, 0x2e7, 0x2f1, 0x2f5, 0x2f8, 0x2fe, 0x302, 0x304, 0x307, 0x309, 0x30c, 0x316, 0x319, 0x328, 0x32c, 0x331, 0x334, 0x338, 0x33d, 0x342, 0x348, 0x34e, 0x35d, 0x363, 0x367, 0x376, 0x37b, 0x383, 0x38d, 0x398, 0x3a0, 0x3b1, 0x3ba, 0x3ca, 0x3d7, 0x3e1, 0x3e6, 0x3f3, 0x3f7, 0x3fc, 0x3fe, 0x402, 0x404, 0x408, 0x411, 0x417, 0x41b, 0x42b, 0x435, 0x43a, 0x43d, 0x443, 0x44a, 0x44f, 0x453, 0x459, 0x45e, 0x467, 0x46c, 0x472, 0x479, 0x480, 0x487, 0x48b, 0x490, 0x493, 0x498, 0x4a4, 0x4aa, 0x4af, 0x4b6, 0x4be, 0x4c3, 0x4c7, 0x4d7, 0x4de, 0x4e2, 0x4e6, 0x4ed, 0x4ef, 0x4f2, 0x4f5, 0x4f9, 0x502, 0x506, 0x50e, 0x516, 0x51c, 0x525, 0x531, 0x538, 0x541, 0x54b, 0x552, 0x560, 0x56d, 0x57a, 0x583, 0x587, 0x596, 0x59e, 0x5a9, 0x5b2, 0x5b8, 0x5c0, 0x5c9, 0x5d3, 0x5d6, 0x5e2, 0x5eb, 0x5ee, 0x5f3, 0x5fe, 0x607, 0x613, 0x616, 0x620, 0x629, 0x635, 0x642, 0x64f, 0x65d, 0x664, 0x667, 0x66c, 0x66f, 0x672, 0x675, 0x67c, 0x683, 0x687, 0x692, 0x695, 0x698, 0x69b, 0x6a1, 0x6a6, 0x6aa, 0x6ad, 0x6b0, 0x6b3, 0x6b6, 0x6b9, 0x6be, 0x6c8, 0x6cb, 0x6cf, 0x6de, 0x6ea, 0x6ee, 0x6f3, 0x6f7, 0x6fc, 0x700, 0x705, 0x70e, 0x719, 0x71f, 0x727, 0x72a, 0x72d, 0x731, 0x735, 0x73b, 0x741, 0x746, 0x749, 0x759, 0x760, 0x763, 0x766, 0x76a, 0x770, 0x775, 0x77a, 0x782, 0x787, 0x78b, 0x78f, 0x792, 0x795, 0x799, 0x79d, 0x7a0, 0x7b0, 0x7c1, 0x7c6, 0x7c8, 0x7ca}\n\n// idnaSparseValues: 1997 entries, 7988 bytes\nvar idnaSparseValues = [1997]valueRange{\n\t// Block 0x0, offset 0x0\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0xe105, lo: 0x80, hi: 0x96},\n\t{value: 0x0018, lo: 0x97, hi: 0x97},\n\t{value: 0xe105, lo: 0x98, hi: 0x9e},\n\t{value: 0x001f, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbf},\n\t// Block 0x1, offset 0x8\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0xe01d, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x82},\n\t{value: 0x0335, lo: 0x83, hi: 0x83},\n\t{value: 0x034d, lo: 0x84, hi: 0x84},\n\t{value: 0x0365, lo: 0x85, hi: 0x85},\n\t{value: 0xe00d, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0xe00d, lo: 0x88, hi: 0x88},\n\t{value: 0x0008, lo: 0x89, hi: 0x89},\n\t{value: 0xe00d, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0x8b},\n\t{value: 0xe00d, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0x8d},\n\t{value: 0xe00d, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0xbf},\n\t// Block 0x2, offset 0x19\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x0249, lo: 0xb0, hi: 0xb0},\n\t{value: 0x037d, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0259, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0269, lo: 0xb3, hi: 0xb3},\n\t{value: 0x034d, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0395, lo: 0xb5, hi: 0xb5},\n\t{value: 0xe1bd, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0279, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0289, lo: 0xb8, hi: 0xb8},\n\t{value: 0x0008, lo: 0xb9, hi: 0xbf},\n\t// Block 0x3, offset 0x25\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x3308, lo: 0x80, hi: 0xbf},\n\t// Block 0x4, offset 0x27\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x03f5, lo: 0x80, hi: 0x8f},\n\t{value: 0xe105, lo: 0x90, hi: 0x9f},\n\t{value: 0x049d, lo: 0xa0, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x5, offset 0x2c\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe185, lo: 0x80, hi: 0x8f},\n\t{value: 0x0545, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x98},\n\t{value: 0x0008, lo: 0x99, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x6, offset 0x33\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0401, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x88},\n\t{value: 0x0018, lo: 0x89, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x3308, lo: 0x91, hi: 0xbd},\n\t{value: 0x0818, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x7, offset 0x3e\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0818, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x82},\n\t{value: 0x0818, lo: 0x83, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x85},\n\t{value: 0x0818, lo: 0x86, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xae},\n\t{value: 0x0808, lo: 0xaf, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x8, offset 0x4a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0a08, lo: 0x80, hi: 0x87},\n\t{value: 0x0c08, lo: 0x88, hi: 0x99},\n\t{value: 0x0a08, lo: 0x9a, hi: 0xbf},\n\t// Block 0x9, offset 0x4e\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3308, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0c08, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0a08, lo: 0x8e, hi: 0x98},\n\t{value: 0x0c08, lo: 0x99, hi: 0x9b},\n\t{value: 0x0a08, lo: 0x9c, hi: 0xaa},\n\t{value: 0x0c08, lo: 0xab, hi: 0xac},\n\t{value: 0x0a08, lo: 0xad, hi: 0xb0},\n\t{value: 0x0c08, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0a08, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0c08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0a08, lo: 0xb5, hi: 0xb7},\n\t{value: 0x0c08, lo: 0xb8, hi: 0xb9},\n\t{value: 0x0a08, lo: 0xba, hi: 0xbf},\n\t// Block 0xa, offset 0x5d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xb0},\n\t{value: 0x0808, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xb, offset 0x62\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0808, lo: 0x80, hi: 0x89},\n\t{value: 0x0a08, lo: 0x8a, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xb3},\n\t{value: 0x0808, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xb9},\n\t{value: 0x0818, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0818, lo: 0xbe, hi: 0xbf},\n\t// Block 0xc, offset 0x6c\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x99},\n\t{value: 0x0808, lo: 0x9a, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0xa3},\n\t{value: 0x0808, lo: 0xa4, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa7},\n\t{value: 0x0808, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0818, lo: 0xb0, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd, offset 0x78\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0a08, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0c08, lo: 0xaa, hi: 0xac},\n\t{value: 0x0808, lo: 0xad, hi: 0xad},\n\t{value: 0x0c08, lo: 0xae, hi: 0xae},\n\t{value: 0x0a08, lo: 0xaf, hi: 0xb0},\n\t{value: 0x0c08, lo: 0xb1, hi: 0xb2},\n\t{value: 0x0a08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0a08, lo: 0xb6, hi: 0xb8},\n\t{value: 0x0c08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0a08, lo: 0xba, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0xe, offset 0x86\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x92},\n\t{value: 0x3308, lo: 0x93, hi: 0xa1},\n\t{value: 0x0840, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xbf},\n\t// Block 0xf, offset 0x8b\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x10, offset 0x94\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x85},\n\t{value: 0x3008, lo: 0x86, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x3008, lo: 0x8a, hi: 0x8c},\n\t{value: 0x3b08, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x11, offset 0xa4\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbf},\n\t// Block 0x12, offset 0xb2\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0xba},\n\t{value: 0x3b08, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x13, offset 0xbe\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0040, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0008, lo: 0xb3, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x14, offset 0xca\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x89},\n\t{value: 0x3b08, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8e},\n\t{value: 0x3008, lo: 0x8f, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x3008, lo: 0x98, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x15, offset 0xdb\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb2},\n\t{value: 0x08f1, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb9},\n\t{value: 0x3b08, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0x16, offset 0xe5\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x8e},\n\t{value: 0x0018, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0xbf},\n\t// Block 0x17, offset 0xec\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x3308, lo: 0x88, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0961, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0999, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0008, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x18, offset 0xf9\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0x8b},\n\t{value: 0xe03d, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3308, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x19, offset 0x10a\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0018, lo: 0x8e, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0xbf},\n\t// Block 0x1a, offset 0x111\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x3008, lo: 0xab, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xb0},\n\t{value: 0x3008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0x1b, offset 0x11c\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x95},\n\t{value: 0x3008, lo: 0x96, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0x9d},\n\t{value: 0x3308, lo: 0x9e, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3008, lo: 0xa2, hi: 0xa4},\n\t{value: 0x0008, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xbf},\n\t// Block 0x1c, offset 0x12b\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x3008, lo: 0x87, hi: 0x8c},\n\t{value: 0x3308, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x8e},\n\t{value: 0x3008, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x3008, lo: 0x9a, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x1d, offset 0x139\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x86},\n\t{value: 0x055d, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8c},\n\t{value: 0x055d, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbb},\n\t{value: 0xe105, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x1e, offset 0x143\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0018, lo: 0x80, hi: 0xbf},\n\t// Block 0x1f, offset 0x145\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xa0},\n\t{value: 0x2018, lo: 0xa1, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0x20, offset 0x14a\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xa7},\n\t{value: 0x2018, lo: 0xa8, hi: 0xbf},\n\t// Block 0x21, offset 0x14d\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x2018, lo: 0x80, hi: 0x82},\n\t{value: 0x0018, lo: 0x83, hi: 0xbf},\n\t// Block 0x22, offset 0x150\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0008, lo: 0x80, hi: 0xbf},\n\t// Block 0x23, offset 0x152\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x24, offset 0x15e\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x25, offset 0x169\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbf},\n\t// Block 0x26, offset 0x171\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbf},\n\t// Block 0x27, offset 0x177\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x28, offset 0x17d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x29, offset 0x182\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0xe045, lo: 0xb8, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x2a, offset 0x187\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xbf},\n\t// Block 0x2b, offset 0x18a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xac},\n\t{value: 0x0018, lo: 0xad, hi: 0xae},\n\t{value: 0x0008, lo: 0xaf, hi: 0xbf},\n\t// Block 0x2c, offset 0x18e\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x2d, offset 0x194\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xb0},\n\t{value: 0x0008, lo: 0xb1, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0x2e, offset 0x199\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x93},\n\t{value: 0x3b08, lo: 0x94, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3b08, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0018, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x2f, offset 0x1a5\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x30, offset 0x1af\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xb3},\n\t{value: 0x3340, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3008, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x31, offset 0x1b5\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x3008, lo: 0x80, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x3008, lo: 0x87, hi: 0x88},\n\t{value: 0x3308, lo: 0x89, hi: 0x91},\n\t{value: 0x3b08, lo: 0x92, hi: 0x92},\n\t{value: 0x3308, lo: 0x93, hi: 0x93},\n\t{value: 0x0018, lo: 0x94, hi: 0x96},\n\t{value: 0x0008, lo: 0x97, hi: 0x97},\n\t{value: 0x0018, lo: 0x98, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x32, offset 0x1c6\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0018, lo: 0x80, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x86},\n\t{value: 0x0218, lo: 0x87, hi: 0x87},\n\t{value: 0x0018, lo: 0x88, hi: 0x8a},\n\t{value: 0x33c0, lo: 0x8b, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0208, lo: 0xa0, hi: 0xbf},\n\t// Block 0x33, offset 0x1d0\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0208, lo: 0x80, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0x34, offset 0x1d3\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x0208, lo: 0x87, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0208, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x35, offset 0x1db\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0x36, offset 0x1de\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb8},\n\t{value: 0x3308, lo: 0xb9, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x37, offset 0x1eb\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x38, offset 0x1f3\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x39, offset 0x1f7\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0028, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0xbf},\n\t// Block 0x3a, offset 0x1fe\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x3308, lo: 0x97, hi: 0x98},\n\t{value: 0x3008, lo: 0x99, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x3b, offset 0x206\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x94},\n\t{value: 0x3008, lo: 0x95, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3b08, lo: 0xa0, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xac},\n\t{value: 0x3008, lo: 0xad, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x3c, offset 0x216\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0018, lo: 0xa8, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xbd},\n\t{value: 0x3318, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x3d, offset 0x222\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0040, lo: 0x80, hi: 0xbf},\n\t// Block 0x3e, offset 0x224\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x3308, lo: 0x80, hi: 0x83},\n\t{value: 0x3008, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x3f, offset 0x22e\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x3808, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x40, offset 0x23a\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa9},\n\t{value: 0x3808, lo: 0xaa, hi: 0xaa},\n\t{value: 0x3b08, lo: 0xab, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xbf},\n\t// Block 0x41, offset 0x246\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa9},\n\t{value: 0x3008, lo: 0xaa, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3808, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbf},\n\t// Block 0x42, offset 0x252\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x3008, lo: 0xa4, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbf},\n\t// Block 0x43, offset 0x25a\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0x44, offset 0x25f\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0e29, lo: 0x80, hi: 0x80},\n\t{value: 0x0e41, lo: 0x81, hi: 0x81},\n\t{value: 0x0e59, lo: 0x82, hi: 0x82},\n\t{value: 0x0e71, lo: 0x83, hi: 0x83},\n\t{value: 0x0e89, lo: 0x84, hi: 0x85},\n\t{value: 0x0ea1, lo: 0x86, hi: 0x86},\n\t{value: 0x0eb9, lo: 0x87, hi: 0x87},\n\t{value: 0x057d, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0xbf},\n\t// Block 0x45, offset 0x269\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x92},\n\t{value: 0x0018, lo: 0x93, hi: 0x93},\n\t{value: 0x3308, lo: 0x94, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa8},\n\t{value: 0x0008, lo: 0xa9, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x3008, lo: 0xb7, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x46, offset 0x27a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3308, lo: 0x80, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbf},\n\t// Block 0x47, offset 0x27e\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x87},\n\t{value: 0xe045, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0xe045, lo: 0x98, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0xe045, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb7},\n\t{value: 0xe045, lo: 0xb8, hi: 0xbf},\n\t// Block 0x48, offset 0x289\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x3318, lo: 0x90, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbf},\n\t// Block 0x49, offset 0x28d\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x88},\n\t{value: 0x24c1, lo: 0x89, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x4a, offset 0x296\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0xab},\n\t{value: 0x24f1, lo: 0xac, hi: 0xac},\n\t{value: 0x2529, lo: 0xad, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xae},\n\t{value: 0x2579, lo: 0xaf, hi: 0xaf},\n\t{value: 0x25b1, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0018, lo: 0xb1, hi: 0xbf},\n\t// Block 0x4b, offset 0x29e\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x9f},\n\t{value: 0x0080, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xad},\n\t{value: 0x0080, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x4c, offset 0x2a4\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xa8},\n\t{value: 0x09c5, lo: 0xa9, hi: 0xa9},\n\t{value: 0x09e5, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xbf},\n\t// Block 0x4d, offset 0x2a9\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xbf},\n\t// Block 0x4e, offset 0x2ac\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x28c1, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0xbf},\n\t// Block 0x4f, offset 0x2b0\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0e66, lo: 0xb4, hi: 0xb4},\n\t{value: 0x292a, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0e86, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0x50, offset 0x2b6\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x9b},\n\t{value: 0x2941, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0xbf},\n\t// Block 0x51, offset 0x2ba\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0x52, offset 0x2be\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0018, lo: 0x98, hi: 0xbf},\n\t// Block 0x53, offset 0x2c2\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x54, offset 0x2c7\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0xe185, lo: 0x80, hi: 0x8f},\n\t{value: 0x03f5, lo: 0x90, hi: 0x9f},\n\t{value: 0x0ea5, lo: 0xa0, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x55, offset 0x2cd\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xac},\n\t{value: 0x0008, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x56, offset 0x2d5\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xae},\n\t{value: 0xe075, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0x57, offset 0x2dc\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x58, offset 0x2e7\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xbf},\n\t// Block 0x59, offset 0x2f1\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xae},\n\t{value: 0x0008, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x5a, offset 0x2f5\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0xbf},\n\t// Block 0x5b, offset 0x2f8\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9e},\n\t{value: 0x0edd, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbf},\n\t// Block 0x5c, offset 0x2fe\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb2},\n\t{value: 0x0efd, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x5d, offset 0x302\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x0f1d, lo: 0x80, hi: 0xbf},\n\t// Block 0x5e, offset 0x304\n\t{value: 0x0020, lo: 0x02},\n\t{value: 0x171d, lo: 0x80, hi: 0x8f},\n\t{value: 0x18fd, lo: 0x90, hi: 0xbf},\n\t// Block 0x5f, offset 0x307\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x1efd, lo: 0x80, hi: 0xbf},\n\t// Block 0x60, offset 0x309\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xbf},\n\t// Block 0x61, offset 0x30c\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x98},\n\t{value: 0x3308, lo: 0x99, hi: 0x9a},\n\t{value: 0x29e2, lo: 0x9b, hi: 0x9b},\n\t{value: 0x2a0a, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0008, lo: 0x9d, hi: 0x9e},\n\t{value: 0x2a31, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xbf},\n\t// Block 0x62, offset 0x316\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xbe},\n\t{value: 0x2a69, lo: 0xbf, hi: 0xbf},\n\t// Block 0x63, offset 0x319\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0040, lo: 0x80, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xb0},\n\t{value: 0x2a1d, lo: 0xb1, hi: 0xb1},\n\t{value: 0x2a3d, lo: 0xb2, hi: 0xb2},\n\t{value: 0x2a5d, lo: 0xb3, hi: 0xb3},\n\t{value: 0x2a7d, lo: 0xb4, hi: 0xb4},\n\t{value: 0x2a5d, lo: 0xb5, hi: 0xb5},\n\t{value: 0x2a9d, lo: 0xb6, hi: 0xb6},\n\t{value: 0x2abd, lo: 0xb7, hi: 0xb7},\n\t{value: 0x2add, lo: 0xb8, hi: 0xb9},\n\t{value: 0x2afd, lo: 0xba, hi: 0xbb},\n\t{value: 0x2b1d, lo: 0xbc, hi: 0xbd},\n\t{value: 0x2afd, lo: 0xbe, hi: 0xbf},\n\t// Block 0x64, offset 0x328\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x65, offset 0x32c\n\t{value: 0x0030, lo: 0x04},\n\t{value: 0x2aa2, lo: 0x80, hi: 0x9d},\n\t{value: 0x305a, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x30a2, lo: 0xa0, hi: 0xbf},\n\t// Block 0x66, offset 0x331\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x67, offset 0x334\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x68, offset 0x338\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0x69, offset 0x33d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xbf},\n\t// Block 0x6a, offset 0x342\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x0018, lo: 0xa6, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0018, lo: 0xb2, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x6b, offset 0x348\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0xb6},\n\t{value: 0x0008, lo: 0xb7, hi: 0xb7},\n\t{value: 0x2009, lo: 0xb8, hi: 0xb8},\n\t{value: 0x6e89, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xbf},\n\t// Block 0x6c, offset 0x34e\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0x85},\n\t{value: 0x3b08, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x8a},\n\t{value: 0x3308, lo: 0x8b, hi: 0x8b},\n\t{value: 0x0008, lo: 0x8c, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0018, lo: 0xa8, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x6d, offset 0x35d\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0208, lo: 0x80, hi: 0xb1},\n\t{value: 0x0108, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0008, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x6e, offset 0x363\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xbf},\n\t// Block 0x6f, offset 0x367\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3008, lo: 0x80, hi: 0x83},\n\t{value: 0x3b08, lo: 0x84, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8d},\n\t{value: 0x0018, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xba},\n\t{value: 0x0008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x70, offset 0x376\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x71, offset 0x37b\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x91},\n\t{value: 0x3008, lo: 0x92, hi: 0x92},\n\t{value: 0x3808, lo: 0x93, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x72, offset 0x383\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb9},\n\t{value: 0x3008, lo: 0xba, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x73, offset 0x38d\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3808, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x74, offset 0x398\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x75, offset 0x3a0\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x8b},\n\t{value: 0x3308, lo: 0x8c, hi: 0x8c},\n\t{value: 0x3008, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0018, lo: 0x9c, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x76, offset 0x3b1\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0008, lo: 0xb9, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbf},\n\t// Block 0x77, offset 0x3ba\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x9a},\n\t{value: 0x0008, lo: 0x9b, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xaa},\n\t{value: 0x3008, lo: 0xab, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3b08, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x78, offset 0x3ca\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x88},\n\t{value: 0x0008, lo: 0x89, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x90},\n\t{value: 0x0008, lo: 0x91, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x79, offset 0x3d7\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x4465, lo: 0x9c, hi: 0x9c},\n\t{value: 0x447d, lo: 0x9d, hi: 0x9d},\n\t{value: 0x2971, lo: 0x9e, hi: 0x9e},\n\t{value: 0xe06d, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xaf},\n\t{value: 0x4495, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7a, offset 0x3e1\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x44b5, lo: 0x80, hi: 0x8f},\n\t{value: 0x44d5, lo: 0x90, hi: 0x9f},\n\t{value: 0x44f5, lo: 0xa0, hi: 0xaf},\n\t{value: 0x44d5, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7b, offset 0x3e6\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3b08, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x7c, offset 0x3f3\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7d, offset 0x3f7\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8a},\n\t{value: 0x0018, lo: 0x8b, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x7e, offset 0x3fc\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x4515, lo: 0x80, hi: 0xbf},\n\t// Block 0x7f, offset 0x3fe\n\t{value: 0x0020, lo: 0x03},\n\t{value: 0x4d15, lo: 0x80, hi: 0x94},\n\t{value: 0x4ad5, lo: 0x95, hi: 0x95},\n\t{value: 0x4fb5, lo: 0x96, hi: 0xbf},\n\t// Block 0x80, offset 0x402\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x54f5, lo: 0x80, hi: 0xbf},\n\t// Block 0x81, offset 0x404\n\t{value: 0x0020, lo: 0x03},\n\t{value: 0x5cf5, lo: 0x80, hi: 0x84},\n\t{value: 0x5655, lo: 0x85, hi: 0x85},\n\t{value: 0x5d95, lo: 0x86, hi: 0xbf},\n\t// Block 0x82, offset 0x408\n\t{value: 0x0020, lo: 0x08},\n\t{value: 0x6b55, lo: 0x80, hi: 0x8f},\n\t{value: 0x6d15, lo: 0x90, hi: 0x90},\n\t{value: 0x6d55, lo: 0x91, hi: 0xab},\n\t{value: 0x6ea1, lo: 0xac, hi: 0xac},\n\t{value: 0x70b5, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x70d5, lo: 0xb0, hi: 0xbf},\n\t// Block 0x83, offset 0x411\n\t{value: 0x0020, lo: 0x05},\n\t{value: 0x72d5, lo: 0x80, hi: 0xad},\n\t{value: 0x6535, lo: 0xae, hi: 0xae},\n\t{value: 0x7895, lo: 0xaf, hi: 0xb5},\n\t{value: 0x6f55, lo: 0xb6, hi: 0xb6},\n\t{value: 0x7975, lo: 0xb7, hi: 0xbf},\n\t// Block 0x84, offset 0x417\n\t{value: 0x0028, lo: 0x03},\n\t{value: 0x7c21, lo: 0x80, hi: 0x82},\n\t{value: 0x7be1, lo: 0x83, hi: 0x83},\n\t{value: 0x7c99, lo: 0x84, hi: 0xbf},\n\t// Block 0x85, offset 0x41b\n\t{value: 0x0038, lo: 0x0f},\n\t{value: 0x9db1, lo: 0x80, hi: 0x83},\n\t{value: 0x9e59, lo: 0x84, hi: 0x85},\n\t{value: 0x9e91, lo: 0x86, hi: 0x87},\n\t{value: 0x9ec9, lo: 0x88, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0xa089, lo: 0x92, hi: 0x97},\n\t{value: 0xa1a1, lo: 0x98, hi: 0x9c},\n\t{value: 0xa281, lo: 0x9d, hi: 0xb3},\n\t{value: 0x9d41, lo: 0xb4, hi: 0xb4},\n\t{value: 0x9db1, lo: 0xb5, hi: 0xb5},\n\t{value: 0xa789, lo: 0xb6, hi: 0xbb},\n\t{value: 0xa869, lo: 0xbc, hi: 0xbc},\n\t{value: 0xa7f9, lo: 0xbd, hi: 0xbd},\n\t{value: 0xa8d9, lo: 0xbe, hi: 0xbf},\n\t// Block 0x86, offset 0x42b\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0008, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0x87, offset 0x435\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0x88, offset 0x43a\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x89, offset 0x43d\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0x8a, offset 0x443\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0040, lo: 0xa1, hi: 0xbf},\n\t// Block 0x8b, offset 0x44a\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x8c, offset 0x44f\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x8d, offset 0x453\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x8e, offset 0x459\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xac},\n\t{value: 0x0008, lo: 0xad, hi: 0xbf},\n\t// Block 0x8f, offset 0x45e\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x90, offset 0x467\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x91, offset 0x46c\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0xbf},\n\t// Block 0x92, offset 0x472\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe145, lo: 0x80, hi: 0x87},\n\t{value: 0xe1c5, lo: 0x88, hi: 0x8f},\n\t{value: 0xe145, lo: 0x90, hi: 0x97},\n\t{value: 0x8ad5, lo: 0x98, hi: 0x9f},\n\t{value: 0x8aed, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xbf},\n\t// Block 0x93, offset 0x479\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x8aed, lo: 0xb0, hi: 0xb7},\n\t{value: 0x8ad5, lo: 0xb8, hi: 0xbf},\n\t// Block 0x94, offset 0x480\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe145, lo: 0x80, hi: 0x87},\n\t{value: 0xe1c5, lo: 0x88, hi: 0x8f},\n\t{value: 0xe145, lo: 0x90, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x95, offset 0x487\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x96, offset 0x48b\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xae},\n\t{value: 0x0018, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x97, offset 0x490\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x98, offset 0x493\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xbf},\n\t// Block 0x99, offset 0x498\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x87},\n\t{value: 0x0808, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0808, lo: 0x8a, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0808, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbb},\n\t{value: 0x0808, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbe},\n\t{value: 0x0808, lo: 0xbf, hi: 0xbf},\n\t// Block 0x9a, offset 0x4a4\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x96},\n\t{value: 0x0818, lo: 0x97, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0818, lo: 0xb7, hi: 0xbf},\n\t// Block 0x9b, offset 0x4aa\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xa6},\n\t{value: 0x0818, lo: 0xa7, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x9c, offset 0x4af\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0808, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xba},\n\t{value: 0x0818, lo: 0xbb, hi: 0xbf},\n\t// Block 0x9d, offset 0x4b6\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0818, lo: 0x96, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbe},\n\t{value: 0x0818, lo: 0xbf, hi: 0xbf},\n\t// Block 0x9e, offset 0x4be\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbb},\n\t{value: 0x0818, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0808, lo: 0xbe, hi: 0xbf},\n\t// Block 0x9f, offset 0x4c3\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0818, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x91},\n\t{value: 0x0818, lo: 0x92, hi: 0xbf},\n\t// Block 0xa0, offset 0x4c7\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0808, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8b},\n\t{value: 0x3308, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x94},\n\t{value: 0x0808, lo: 0x95, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0x98},\n\t{value: 0x0808, lo: 0x99, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xa1, offset 0x4d7\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0818, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x0818, lo: 0x90, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xbc},\n\t{value: 0x0818, lo: 0xbd, hi: 0xbf},\n\t// Block 0xa2, offset 0x4de\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0x9c},\n\t{value: 0x0818, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xa3, offset 0x4e2\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb8},\n\t{value: 0x0018, lo: 0xb9, hi: 0xbf},\n\t// Block 0xa4, offset 0x4e6\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0818, lo: 0x98, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb7},\n\t{value: 0x0818, lo: 0xb8, hi: 0xbf},\n\t// Block 0xa5, offset 0x4ed\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0808, lo: 0x80, hi: 0xbf},\n\t// Block 0xa6, offset 0x4ef\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0808, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0xbf},\n\t// Block 0xa7, offset 0x4f2\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x03dd, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbf},\n\t// Block 0xa8, offset 0x4f5\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb9},\n\t{value: 0x0818, lo: 0xba, hi: 0xbf},\n\t// Block 0xa9, offset 0x4f9\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0908, lo: 0x80, hi: 0x80},\n\t{value: 0x0a08, lo: 0x81, hi: 0xa1},\n\t{value: 0x0c08, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0a08, lo: 0xa3, hi: 0xa3},\n\t{value: 0x3308, lo: 0xa4, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0808, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xaa, offset 0x502\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0818, lo: 0xa0, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xab, offset 0x506\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0x9c},\n\t{value: 0x0818, lo: 0x9d, hi: 0xa6},\n\t{value: 0x0808, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0a08, lo: 0xb0, hi: 0xb2},\n\t{value: 0x0c08, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0a08, lo: 0xb4, hi: 0xbf},\n\t// Block 0xac, offset 0x50e\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0a08, lo: 0x80, hi: 0x84},\n\t{value: 0x0808, lo: 0x85, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x90},\n\t{value: 0x0a18, lo: 0x91, hi: 0x93},\n\t{value: 0x0c18, lo: 0x94, hi: 0x94},\n\t{value: 0x0818, lo: 0x95, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xad, offset 0x516\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbf},\n\t// Block 0xae, offset 0x51c\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x85},\n\t{value: 0x3b08, lo: 0x86, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x91},\n\t{value: 0x0018, lo: 0x92, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xaf, offset 0x525\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb6},\n\t{value: 0x3008, lo: 0xb7, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0xb0, offset 0x531\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x81},\n\t{value: 0x0040, lo: 0x82, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xb1, offset 0x538\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xb2},\n\t{value: 0x3b08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0008, lo: 0xb6, hi: 0xbf},\n\t// Block 0xb2, offset 0x541\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0018, lo: 0x80, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x3008, lo: 0x85, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0008, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xb3, offset 0x54b\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xbe},\n\t{value: 0x3008, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb4, offset 0x552\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x3808, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x88},\n\t{value: 0x3308, lo: 0x89, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xb5, offset 0x560\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x92},\n\t{value: 0x0008, lo: 0x93, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3808, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb6, offset 0x56d\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0008, lo: 0x9f, hi: 0xa8},\n\t{value: 0x0018, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0xb7, offset 0x57a\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x3308, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3008, lo: 0xa0, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xa9},\n\t{value: 0x3b08, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xb8, offset 0x583\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbf},\n\t// Block 0xb9, offset 0x587\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x3b08, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x84},\n\t{value: 0x3008, lo: 0x85, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x8a},\n\t{value: 0x0018, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0x9d},\n\t{value: 0x3308, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xbf},\n\t// Block 0xba, offset 0x596\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb8},\n\t{value: 0x3008, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbb, offset 0x59e\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x81},\n\t{value: 0x3b08, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x85},\n\t{value: 0x0018, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xbc, offset 0x5a9\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbd, offset 0x5b2\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x9b},\n\t{value: 0x3308, lo: 0x9c, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0xbe, offset 0x5b8\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbf, offset 0x5c0\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xbf},\n\t// Block 0xc0, offset 0x5c9\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb5},\n\t{value: 0x3808, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0xc1, offset 0x5d3\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0xbf},\n\t// Block 0xc2, offset 0x5d6\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9f},\n\t{value: 0x3008, lo: 0xa0, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xaa},\n\t{value: 0x3b08, lo: 0xab, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbf},\n\t// Block 0xc3, offset 0x5e2\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0xc4, offset 0x5eb\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x049d, lo: 0xa0, hi: 0xbf},\n\t// Block 0xc5, offset 0x5ee\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc6, offset 0x5f3\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3b08, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb8},\n\t{value: 0x3008, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc7, offset 0x5fe\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x3b08, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x3308, lo: 0x91, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x98},\n\t{value: 0x3308, lo: 0x99, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0xbf},\n\t// Block 0xc8, offset 0x607\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x89},\n\t{value: 0x3308, lo: 0x8a, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x98},\n\t{value: 0x3b08, lo: 0x99, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9c},\n\t{value: 0x0008, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0xa2},\n\t{value: 0x0040, lo: 0xa3, hi: 0xbf},\n\t// Block 0xc9, offset 0x613\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xca, offset 0x616\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xcb, offset 0x620\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xbf},\n\t// Block 0xcc, offset 0x629\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xa9},\n\t{value: 0x3308, lo: 0xaa, hi: 0xb0},\n\t{value: 0x3008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xcd, offset 0x635\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0xce, offset 0x642\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x3308, lo: 0x80, hi: 0x83},\n\t{value: 0x3b08, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xbf},\n\t// Block 0xcf, offset 0x64f\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x3008, lo: 0x8a, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x92},\n\t{value: 0x3008, lo: 0x93, hi: 0x94},\n\t{value: 0x3308, lo: 0x95, hi: 0x95},\n\t{value: 0x3008, lo: 0x96, hi: 0x96},\n\t{value: 0x3b08, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xbf},\n\t// Block 0xd0, offset 0x65d\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xd1, offset 0x664\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xd2, offset 0x667\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xd3, offset 0x66c\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0xbf},\n\t// Block 0xd4, offset 0x66f\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xbf},\n\t// Block 0xd5, offset 0x672\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0xbf},\n\t// Block 0xd6, offset 0x675\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0xd7, offset 0x67c\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0018, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xd8, offset 0x683\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0xd9, offset 0x687\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0008, lo: 0xa3, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbf},\n\t// Block 0xda, offset 0x692\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0xbf},\n\t// Block 0xdb, offset 0x695\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0xdc, offset 0x698\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0xbf},\n\t// Block 0xdd, offset 0x69b\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x3008, lo: 0x91, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xde, offset 0x6a1\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x8e},\n\t{value: 0x3308, lo: 0x8f, hi: 0x92},\n\t{value: 0x0008, lo: 0x93, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xdf, offset 0x6a6\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xbf},\n\t// Block 0xe0, offset 0x6aa\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xe1, offset 0x6ad\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbf},\n\t// Block 0xe2, offset 0x6b0\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xbf},\n\t// Block 0xe3, offset 0x6b3\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0xe4, offset 0x6b6\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0xe5, offset 0x6b9\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0xe6, offset 0x6be\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0018, lo: 0x9c, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x03c0, lo: 0xa0, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xbf},\n\t// Block 0xe7, offset 0x6c8\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xe8, offset 0x6cb\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa8},\n\t{value: 0x0018, lo: 0xa9, hi: 0xbf},\n\t// Block 0xe9, offset 0x6cf\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0018, lo: 0x80, hi: 0x9d},\n\t{value: 0xb5b9, lo: 0x9e, hi: 0x9e},\n\t{value: 0xb601, lo: 0x9f, hi: 0x9f},\n\t{value: 0xb649, lo: 0xa0, hi: 0xa0},\n\t{value: 0xb6b1, lo: 0xa1, hi: 0xa1},\n\t{value: 0xb719, lo: 0xa2, hi: 0xa2},\n\t{value: 0xb781, lo: 0xa3, hi: 0xa3},\n\t{value: 0xb7e9, lo: 0xa4, hi: 0xa4},\n\t{value: 0x3018, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3318, lo: 0xa7, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xac},\n\t{value: 0x3018, lo: 0xad, hi: 0xb2},\n\t{value: 0x0340, lo: 0xb3, hi: 0xba},\n\t{value: 0x3318, lo: 0xbb, hi: 0xbf},\n\t// Block 0xea, offset 0x6de\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3318, lo: 0x80, hi: 0x82},\n\t{value: 0x0018, lo: 0x83, hi: 0x84},\n\t{value: 0x3318, lo: 0x85, hi: 0x8b},\n\t{value: 0x0018, lo: 0x8c, hi: 0xa9},\n\t{value: 0x3318, lo: 0xaa, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xba},\n\t{value: 0xb851, lo: 0xbb, hi: 0xbb},\n\t{value: 0xb899, lo: 0xbc, hi: 0xbc},\n\t{value: 0xb8e1, lo: 0xbd, hi: 0xbd},\n\t{value: 0xb949, lo: 0xbe, hi: 0xbe},\n\t{value: 0xb9b1, lo: 0xbf, hi: 0xbf},\n\t// Block 0xeb, offset 0x6ea\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0xba19, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xbf},\n\t// Block 0xec, offset 0x6ee\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x81},\n\t{value: 0x3318, lo: 0x82, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0xbf},\n\t// Block 0xed, offset 0x6f3\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0xee, offset 0x6f7\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xef, offset 0x6fc\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3308, lo: 0x80, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbf},\n\t// Block 0xf0, offset 0x700\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x3308, lo: 0x80, hi: 0xac},\n\t{value: 0x0018, lo: 0xad, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0xf1, offset 0x705\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x3308, lo: 0xa1, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0xf2, offset 0x70e\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x3308, lo: 0x88, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xa4},\n\t{value: 0x0040, lo: 0xa5, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xbf},\n\t// Block 0xf3, offset 0x719\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0808, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x86},\n\t{value: 0x0818, lo: 0x87, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0xbf},\n\t// Block 0xf4, offset 0x71f\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0a08, lo: 0x80, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0818, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xf5, offset 0x727\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xb0},\n\t{value: 0x0818, lo: 0xb1, hi: 0xbf},\n\t// Block 0xf6, offset 0x72a\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0818, lo: 0x80, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xf7, offset 0x72d\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xf8, offset 0x731\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0xf9, offset 0x735\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xb0},\n\t{value: 0x0018, lo: 0xb1, hi: 0xbf},\n\t// Block 0xfa, offset 0x73b\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x0018, lo: 0x91, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xfb, offset 0x741\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x8f},\n\t{value: 0xc1c1, lo: 0x90, hi: 0x90},\n\t{value: 0x0018, lo: 0x91, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xbf},\n\t// Block 0xfc, offset 0x746\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xa5},\n\t{value: 0x0018, lo: 0xa6, hi: 0xbf},\n\t// Block 0xfd, offset 0x749\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0xc7e9, lo: 0x80, hi: 0x80},\n\t{value: 0xc839, lo: 0x81, hi: 0x81},\n\t{value: 0xc889, lo: 0x82, hi: 0x82},\n\t{value: 0xc8d9, lo: 0x83, hi: 0x83},\n\t{value: 0xc929, lo: 0x84, hi: 0x84},\n\t{value: 0xc979, lo: 0x85, hi: 0x85},\n\t{value: 0xc9c9, lo: 0x86, hi: 0x86},\n\t{value: 0xca19, lo: 0x87, hi: 0x87},\n\t{value: 0xca69, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0xcab9, lo: 0x90, hi: 0x90},\n\t{value: 0xcad9, lo: 0x91, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xbf},\n\t// Block 0xfe, offset 0x759\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xff, offset 0x760\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x100, offset 0x763\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0xbf},\n\t// Block 0x101, offset 0x766\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x102, offset 0x76a\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbf},\n\t// Block 0x103, offset 0x770\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xbf},\n\t// Block 0x104, offset 0x775\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x105, offset 0x77a\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb2},\n\t{value: 0x0018, lo: 0xb3, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbf},\n\t// Block 0x106, offset 0x782\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xa2},\n\t{value: 0x0040, lo: 0xa3, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x107, offset 0x787\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x108, offset 0x78b\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xbf},\n\t// Block 0x109, offset 0x78f\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0xbf},\n\t// Block 0x10a, offset 0x792\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x10b, offset 0x795\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x10c, offset 0x799\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x10d, offset 0x79d\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xa0},\n\t{value: 0x0040, lo: 0xa1, hi: 0xbf},\n\t// Block 0x10e, offset 0x7a0\n\t{value: 0x0020, lo: 0x0f},\n\t{value: 0xdeb9, lo: 0x80, hi: 0x89},\n\t{value: 0x8dfd, lo: 0x8a, hi: 0x8a},\n\t{value: 0xdff9, lo: 0x8b, hi: 0x9c},\n\t{value: 0x8e1d, lo: 0x9d, hi: 0x9d},\n\t{value: 0xe239, lo: 0x9e, hi: 0xa2},\n\t{value: 0x8e3d, lo: 0xa3, hi: 0xa3},\n\t{value: 0xe2d9, lo: 0xa4, hi: 0xab},\n\t{value: 0x7ed5, lo: 0xac, hi: 0xac},\n\t{value: 0xe3d9, lo: 0xad, hi: 0xaf},\n\t{value: 0x8e5d, lo: 0xb0, hi: 0xb0},\n\t{value: 0xe439, lo: 0xb1, hi: 0xb6},\n\t{value: 0x8e7d, lo: 0xb7, hi: 0xb9},\n\t{value: 0xe4f9, lo: 0xba, hi: 0xba},\n\t{value: 0x8edd, lo: 0xbb, hi: 0xbb},\n\t{value: 0xe519, lo: 0xbc, hi: 0xbf},\n\t// Block 0x10f, offset 0x7b0\n\t{value: 0x0020, lo: 0x10},\n\t{value: 0x937d, lo: 0x80, hi: 0x80},\n\t{value: 0xf099, lo: 0x81, hi: 0x86},\n\t{value: 0x939d, lo: 0x87, hi: 0x8a},\n\t{value: 0xd9f9, lo: 0x8b, hi: 0x8b},\n\t{value: 0xf159, lo: 0x8c, hi: 0x96},\n\t{value: 0x941d, lo: 0x97, hi: 0x97},\n\t{value: 0xf2b9, lo: 0x98, hi: 0xa3},\n\t{value: 0x943d, lo: 0xa4, hi: 0xa6},\n\t{value: 0xf439, lo: 0xa7, hi: 0xaa},\n\t{value: 0x949d, lo: 0xab, hi: 0xab},\n\t{value: 0xf4b9, lo: 0xac, hi: 0xac},\n\t{value: 0x94bd, lo: 0xad, hi: 0xad},\n\t{value: 0xf4d9, lo: 0xae, hi: 0xaf},\n\t{value: 0x94dd, lo: 0xb0, hi: 0xb1},\n\t{value: 0xf519, lo: 0xb2, hi: 0xbe},\n\t{value: 0x2040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x110, offset 0x7c1\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0340, lo: 0x81, hi: 0x81},\n\t{value: 0x0040, lo: 0x82, hi: 0x9f},\n\t{value: 0x0340, lo: 0xa0, hi: 0xbf},\n\t// Block 0x111, offset 0x7c6\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0340, lo: 0x80, hi: 0xbf},\n\t// Block 0x112, offset 0x7c8\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x33c0, lo: 0x80, hi: 0xbf},\n\t// Block 0x113, offset 0x7ca\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x33c0, lo: 0x80, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n}\n\n// Total table size 42466 bytes (41KiB); checksum: 355A58A4\n"
  },
  {
    "path": "vendor/golang.org/x/net/idna/tables12.0.0.go",
    "content": "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n//go:build go1.14 && !go1.16\n\npackage idna\n\n// UnicodeVersion is the Unicode version from which the tables in this package are derived.\nconst UnicodeVersion = \"12.0.0\"\n\nvar mappings string = \"\" + // Size: 8178 bytes\n\t\"\\x00\\x01 \\x03 ̈\\x01a\\x03 ̄\\x012\\x013\\x03 ́\\x03 ̧\\x011\\x01o\\x051⁄4\\x051⁄2\" +\n\t\"\\x053⁄4\\x03i̇\\x03l·\\x03ʼn\\x01s\\x03dž\\x03ⱥ\\x03ⱦ\\x01h\\x01j\\x01r\\x01w\\x01y\" +\n\t\"\\x03 ̆\\x03 ̇\\x03 ̊\\x03 ̨\\x03 ̃\\x03 ̋\\x01l\\x01x\\x04̈́\\x03 ι\\x01;\\x05 ̈́\" +\n\t\"\\x04եւ\\x04اٴ\\x04وٴ\\x04ۇٴ\\x04يٴ\\x06क़\\x06ख़\\x06ग़\\x06ज़\\x06ड़\\x06ढ़\\x06फ़\" +\n\t\"\\x06य़\\x06ড়\\x06ঢ়\\x06য়\\x06ਲ਼\\x06ਸ਼\\x06ਖ਼\\x06ਗ਼\\x06ਜ਼\\x06ਫ਼\\x06ଡ଼\\x06ଢ଼\" +\n\t\"\\x06ํา\\x06ໍາ\\x06ຫນ\\x06ຫມ\\x06གྷ\\x06ཌྷ\\x06དྷ\\x06བྷ\\x06ཛྷ\\x06ཀྵ\\x06ཱི\\x06ཱུ\" +\n\t\"\\x06ྲྀ\\x09ྲཱྀ\\x06ླྀ\\x09ླཱྀ\\x06ཱྀ\\x06ྒྷ\\x06ྜྷ\\x06ྡྷ\\x06ྦྷ\\x06ྫྷ\\x06ྐྵ\\x02\" +\n\t\"в\\x02д\\x02о\\x02с\\x02т\\x02ъ\\x02ѣ\\x02æ\\x01b\\x01d\\x01e\\x02ǝ\\x01g\\x01i\\x01k\" +\n\t\"\\x01m\\x01n\\x02ȣ\\x01p\\x01t\\x01u\\x02ɐ\\x02ɑ\\x02ə\\x02ɛ\\x02ɜ\\x02ŋ\\x02ɔ\\x02ɯ\" +\n\t\"\\x01v\\x02β\\x02γ\\x02δ\\x02φ\\x02χ\\x02ρ\\x02н\\x02ɒ\\x01c\\x02ɕ\\x02ð\\x01f\\x02ɟ\" +\n\t\"\\x02ɡ\\x02ɥ\\x02ɨ\\x02ɩ\\x02ɪ\\x02ʝ\\x02ɭ\\x02ʟ\\x02ɱ\\x02ɰ\\x02ɲ\\x02ɳ\\x02ɴ\\x02ɵ\" +\n\t\"\\x02ɸ\\x02ʂ\\x02ʃ\\x02ƫ\\x02ʉ\\x02ʊ\\x02ʋ\\x02ʌ\\x01z\\x02ʐ\\x02ʑ\\x02ʒ\\x02θ\\x02ss\" +\n\t\"\\x02ά\\x02έ\\x02ή\\x02ί\\x02ό\\x02ύ\\x02ώ\\x05ἀι\\x05ἁι\\x05ἂι\\x05ἃι\\x05ἄι\\x05ἅι\" +\n\t\"\\x05ἆι\\x05ἇι\\x05ἠι\\x05ἡι\\x05ἢι\\x05ἣι\\x05ἤι\\x05ἥι\\x05ἦι\\x05ἧι\\x05ὠι\\x05ὡι\" +\n\t\"\\x05ὢι\\x05ὣι\\x05ὤι\\x05ὥι\\x05ὦι\\x05ὧι\\x05ὰι\\x04αι\\x04άι\\x05ᾶι\\x02ι\\x05 ̈͂\" +\n\t\"\\x05ὴι\\x04ηι\\x04ήι\\x05ῆι\\x05 ̓̀\\x05 ̓́\\x05 ̓͂\\x02ΐ\\x05 ̔̀\\x05 ̔́\\x05 ̔͂\" +\n\t\"\\x02ΰ\\x05 ̈̀\\x01`\\x05ὼι\\x04ωι\\x04ώι\\x05ῶι\\x06′′\\x09′′′\\x06‵‵\\x09‵‵‵\\x02!\" +\n\t\"!\\x02??\\x02?!\\x02!?\\x0c′′′′\\x010\\x014\\x015\\x016\\x017\\x018\\x019\\x01+\\x01=\" +\n\t\"\\x01(\\x01)\\x02rs\\x02ħ\\x02no\\x01q\\x02sm\\x02tm\\x02ω\\x02å\\x02א\\x02ב\\x02ג\" +\n\t\"\\x02ד\\x02π\\x051⁄7\\x051⁄9\\x061⁄10\\x051⁄3\\x052⁄3\\x051⁄5\\x052⁄5\\x053⁄5\\x054\" +\n\t\"⁄5\\x051⁄6\\x055⁄6\\x051⁄8\\x053⁄8\\x055⁄8\\x057⁄8\\x041⁄\\x02ii\\x02iv\\x02vi\" +\n\t\"\\x04viii\\x02ix\\x02xi\\x050⁄3\\x06∫∫\\x09∫∫∫\\x06∮∮\\x09∮∮∮\\x0210\\x0211\\x0212\" +\n\t\"\\x0213\\x0214\\x0215\\x0216\\x0217\\x0218\\x0219\\x0220\\x04(10)\\x04(11)\\x04(12)\" +\n\t\"\\x04(13)\\x04(14)\\x04(15)\\x04(16)\\x04(17)\\x04(18)\\x04(19)\\x04(20)\\x0c∫∫∫∫\" +\n\t\"\\x02==\\x05⫝̸\\x02ɫ\\x02ɽ\\x02ȿ\\x02ɀ\\x01.\\x04 ゙\\x04 ゚\\x06より\\x06コト\\x05(ᄀ)\\x05\" +\n\t\"(ᄂ)\\x05(ᄃ)\\x05(ᄅ)\\x05(ᄆ)\\x05(ᄇ)\\x05(ᄉ)\\x05(ᄋ)\\x05(ᄌ)\\x05(ᄎ)\\x05(ᄏ)\\x05(ᄐ\" +\n\t\")\\x05(ᄑ)\\x05(ᄒ)\\x05(가)\\x05(나)\\x05(다)\\x05(라)\\x05(마)\\x05(바)\\x05(사)\\x05(아)\" +\n\t\"\\x05(자)\\x05(차)\\x05(카)\\x05(타)\\x05(파)\\x05(하)\\x05(주)\\x08(오전)\\x08(오후)\\x05(一)\" +\n\t\"\\x05(二)\\x05(三)\\x05(四)\\x05(五)\\x05(六)\\x05(七)\\x05(八)\\x05(九)\\x05(十)\\x05(月)\" +\n\t\"\\x05(火)\\x05(水)\\x05(木)\\x05(金)\\x05(土)\\x05(日)\\x05(株)\\x05(有)\\x05(社)\\x05(名)\" +\n\t\"\\x05(特)\\x05(財)\\x05(祝)\\x05(労)\\x05(代)\\x05(呼)\\x05(学)\\x05(監)\\x05(企)\\x05(資)\" +\n\t\"\\x05(協)\\x05(祭)\\x05(休)\\x05(自)\\x05(至)\\x0221\\x0222\\x0223\\x0224\\x0225\\x0226\" +\n\t\"\\x0227\\x0228\\x0229\\x0230\\x0231\\x0232\\x0233\\x0234\\x0235\\x06참고\\x06주의\\x0236\" +\n\t\"\\x0237\\x0238\\x0239\\x0240\\x0241\\x0242\\x0243\\x0244\\x0245\\x0246\\x0247\\x0248\" +\n\t\"\\x0249\\x0250\\x041月\\x042月\\x043月\\x044月\\x045月\\x046月\\x047月\\x048月\\x049月\\x0510\" +\n\t\"月\\x0511月\\x0512月\\x02hg\\x02ev\\x0cアパート\\x0cアルファ\\x0cアンペア\\x09アール\\x0cイニング\\x09\" +\n\t\"インチ\\x09ウォン\\x0fエスクード\\x0cエーカー\\x09オンス\\x09オーム\\x09カイリ\\x0cカラット\\x0cカロリー\\x09ガロ\" +\n\t\"ン\\x09ガンマ\\x06ギガ\\x09ギニー\\x0cキュリー\\x0cギルダー\\x06キロ\\x0fキログラム\\x12キロメートル\\x0fキロワッ\" +\n\t\"ト\\x09グラム\\x0fグラムトン\\x0fクルゼイロ\\x0cクローネ\\x09ケース\\x09コルナ\\x09コーポ\\x0cサイクル\\x0fサンチ\" +\n\t\"ーム\\x0cシリング\\x09センチ\\x09セント\\x09ダース\\x06デシ\\x06ドル\\x06トン\\x06ナノ\\x09ノット\\x09ハイツ\" +\n\t\"\\x0fパーセント\\x09パーツ\\x0cバーレル\\x0fピアストル\\x09ピクル\\x06ピコ\\x06ビル\\x0fファラッド\\x0cフィート\" +\n\t\"\\x0fブッシェル\\x09フラン\\x0fヘクタール\\x06ペソ\\x09ペニヒ\\x09ヘルツ\\x09ペンス\\x09ページ\\x09ベータ\\x0cポイ\" +\n\t\"ント\\x09ボルト\\x06ホン\\x09ポンド\\x09ホール\\x09ホーン\\x0cマイクロ\\x09マイル\\x09マッハ\\x09マルク\\x0fマ\" +\n\t\"ンション\\x0cミクロン\\x06ミリ\\x0fミリバール\\x06メガ\\x0cメガトン\\x0cメートル\\x09ヤード\\x09ヤール\\x09ユアン\" +\n\t\"\\x0cリットル\\x06リラ\\x09ルピー\\x0cルーブル\\x06レム\\x0fレントゲン\\x09ワット\\x040点\\x041点\\x042点\" +\n\t\"\\x043点\\x044点\\x045点\\x046点\\x047点\\x048点\\x049点\\x0510点\\x0511点\\x0512点\\x0513点\" +\n\t\"\\x0514点\\x0515点\\x0516点\\x0517点\\x0518点\\x0519点\\x0520点\\x0521点\\x0522点\\x0523点\" +\n\t\"\\x0524点\\x02da\\x02au\\x02ov\\x02pc\\x02dm\\x02iu\\x06平成\\x06昭和\\x06大正\\x06明治\\x0c株\" +\n\t\"式会社\\x02pa\\x02na\\x02ma\\x02ka\\x02kb\\x02mb\\x02gb\\x04kcal\\x02pf\\x02nf\\x02m\" +\n\t\"g\\x02kg\\x02hz\\x02ml\\x02dl\\x02kl\\x02fm\\x02nm\\x02mm\\x02cm\\x02km\\x02m2\\x02m\" +\n\t\"3\\x05m∕s\\x06m∕s2\\x07rad∕s\\x08rad∕s2\\x02ps\\x02ns\\x02ms\\x02pv\\x02nv\\x02mv\" +\n\t\"\\x02kv\\x02pw\\x02nw\\x02mw\\x02kw\\x02bq\\x02cc\\x02cd\\x06c∕kg\\x02db\\x02gy\\x02\" +\n\t\"ha\\x02hp\\x02in\\x02kk\\x02kt\\x02lm\\x02ln\\x02lx\\x02ph\\x02pr\\x02sr\\x02sv\\x02\" +\n\t\"wb\\x05v∕m\\x05a∕m\\x041日\\x042日\\x043日\\x044日\\x045日\\x046日\\x047日\\x048日\\x049日\" +\n\t\"\\x0510日\\x0511日\\x0512日\\x0513日\\x0514日\\x0515日\\x0516日\\x0517日\\x0518日\\x0519日\" +\n\t\"\\x0520日\\x0521日\\x0522日\\x0523日\\x0524日\\x0525日\\x0526日\\x0527日\\x0528日\\x0529日\" +\n\t\"\\x0530日\\x0531日\\x02ь\\x02ɦ\\x02ɬ\\x02ʞ\\x02ʇ\\x02œ\\x04𤋮\\x04𢡊\\x04𢡄\\x04𣏕\\x04𥉉\" +\n\t\"\\x04𥳐\\x04𧻓\\x02ff\\x02fi\\x02fl\\x02st\\x04մն\\x04մե\\x04մի\\x04վն\\x04մխ\\x04יִ\" +\n\t\"\\x04ײַ\\x02ע\\x02ה\\x02כ\\x02ל\\x02ם\\x02ר\\x02ת\\x04שׁ\\x04שׂ\\x06שּׁ\\x06שּׂ\\x04א\" +\n\t\"ַ\\x04אָ\\x04אּ\\x04בּ\\x04גּ\\x04דּ\\x04הּ\\x04וּ\\x04זּ\\x04טּ\\x04יּ\\x04ךּ\\x04\" +\n\t\"כּ\\x04לּ\\x04מּ\\x04נּ\\x04סּ\\x04ףּ\\x04פּ\\x04צּ\\x04קּ\\x04רּ\\x04שּ\\x04תּ\" +\n\t\"\\x04וֹ\\x04בֿ\\x04כֿ\\x04פֿ\\x04אל\\x02ٱ\\x02ٻ\\x02پ\\x02ڀ\\x02ٺ\\x02ٿ\\x02ٹ\\x02ڤ\" +\n\t\"\\x02ڦ\\x02ڄ\\x02ڃ\\x02چ\\x02ڇ\\x02ڍ\\x02ڌ\\x02ڎ\\x02ڈ\\x02ژ\\x02ڑ\\x02ک\\x02گ\\x02ڳ\" +\n\t\"\\x02ڱ\\x02ں\\x02ڻ\\x02ۀ\\x02ہ\\x02ھ\\x02ے\\x02ۓ\\x02ڭ\\x02ۇ\\x02ۆ\\x02ۈ\\x02ۋ\\x02ۅ\" +\n\t\"\\x02ۉ\\x02ې\\x02ى\\x04ئا\\x04ئە\\x04ئو\\x04ئۇ\\x04ئۆ\\x04ئۈ\\x04ئې\\x04ئى\\x02ی\\x04\" +\n\t\"ئج\\x04ئح\\x04ئم\\x04ئي\\x04بج\\x04بح\\x04بخ\\x04بم\\x04بى\\x04بي\\x04تج\\x04تح\" +\n\t\"\\x04تخ\\x04تم\\x04تى\\x04تي\\x04ثج\\x04ثم\\x04ثى\\x04ثي\\x04جح\\x04جم\\x04حج\\x04حم\" +\n\t\"\\x04خج\\x04خح\\x04خم\\x04سج\\x04سح\\x04سخ\\x04سم\\x04صح\\x04صم\\x04ضج\\x04ضح\\x04ضخ\" +\n\t\"\\x04ضم\\x04طح\\x04طم\\x04ظم\\x04عج\\x04عم\\x04غج\\x04غم\\x04فج\\x04فح\\x04فخ\\x04فم\" +\n\t\"\\x04فى\\x04في\\x04قح\\x04قم\\x04قى\\x04قي\\x04كا\\x04كج\\x04كح\\x04كخ\\x04كل\\x04كم\" +\n\t\"\\x04كى\\x04كي\\x04لج\\x04لح\\x04لخ\\x04لم\\x04لى\\x04لي\\x04مج\\x04مح\\x04مخ\\x04مم\" +\n\t\"\\x04مى\\x04مي\\x04نج\\x04نح\\x04نخ\\x04نم\\x04نى\\x04ني\\x04هج\\x04هم\\x04هى\\x04هي\" +\n\t\"\\x04يج\\x04يح\\x04يخ\\x04يم\\x04يى\\x04يي\\x04ذٰ\\x04رٰ\\x04ىٰ\\x05 ٌّ\\x05 ٍّ\\x05\" +\n\t\" َّ\\x05 ُّ\\x05 ِّ\\x05 ّٰ\\x04ئر\\x04ئز\\x04ئن\\x04بر\\x04بز\\x04بن\\x04تر\\x04تز\" +\n\t\"\\x04تن\\x04ثر\\x04ثز\\x04ثن\\x04ما\\x04نر\\x04نز\\x04نن\\x04ير\\x04يز\\x04ين\\x04ئخ\" +\n\t\"\\x04ئه\\x04به\\x04ته\\x04صخ\\x04له\\x04نه\\x04هٰ\\x04يه\\x04ثه\\x04سه\\x04شم\\x04شه\" +\n\t\"\\x06ـَّ\\x06ـُّ\\x06ـِّ\\x04طى\\x04طي\\x04عى\\x04عي\\x04غى\\x04غي\\x04سى\\x04سي\" +\n\t\"\\x04شى\\x04شي\\x04حى\\x04حي\\x04جى\\x04جي\\x04خى\\x04خي\\x04صى\\x04صي\\x04ضى\\x04ضي\" +\n\t\"\\x04شج\\x04شح\\x04شخ\\x04شر\\x04سر\\x04صر\\x04ضر\\x04اً\\x06تجم\\x06تحج\\x06تحم\" +\n\t\"\\x06تخم\\x06تمج\\x06تمح\\x06تمخ\\x06جمح\\x06حمي\\x06حمى\\x06سحج\\x06سجح\\x06سجى\" +\n\t\"\\x06سمح\\x06سمج\\x06سمم\\x06صحح\\x06صمم\\x06شحم\\x06شجي\\x06شمخ\\x06شمم\\x06ضحى\" +\n\t\"\\x06ضخم\\x06طمح\\x06طمم\\x06طمي\\x06عجم\\x06عمم\\x06عمى\\x06غمم\\x06غمي\\x06غمى\" +\n\t\"\\x06فخم\\x06قمح\\x06قمم\\x06لحم\\x06لحي\\x06لحى\\x06لجج\\x06لخم\\x06لمح\\x06محج\" +\n\t\"\\x06محم\\x06محي\\x06مجح\\x06مجم\\x06مخج\\x06مخم\\x06مجخ\\x06همج\\x06همم\\x06نحم\" +\n\t\"\\x06نحى\\x06نجم\\x06نجى\\x06نمي\\x06نمى\\x06يمم\\x06بخي\\x06تجي\\x06تجى\\x06تخي\" +\n\t\"\\x06تخى\\x06تمي\\x06تمى\\x06جمي\\x06جحى\\x06جمى\\x06سخى\\x06صحي\\x06شحي\\x06ضحي\" +\n\t\"\\x06لجي\\x06لمي\\x06يحي\\x06يجي\\x06يمي\\x06ممي\\x06قمي\\x06نحي\\x06عمي\\x06كمي\" +\n\t\"\\x06نجح\\x06مخي\\x06لجم\\x06كمم\\x06جحي\\x06حجي\\x06مجي\\x06فمي\\x06بحي\\x06سخي\" +\n\t\"\\x06نجي\\x06صلے\\x06قلے\\x08الله\\x08اكبر\\x08محمد\\x08صلعم\\x08رسول\\x08عليه\" +\n\t\"\\x08وسلم\\x06صلى!صلى الله عليه وسلم\\x0fجل جلاله\\x08ریال\\x01,\\x01:\\x01!\" +\n\t\"\\x01?\\x01_\\x01{\\x01}\\x01[\\x01]\\x01#\\x01&\\x01*\\x01-\\x01<\\x01>\\x01\\\\\\x01$\" +\n\t\"\\x01%\\x01@\\x04ـً\\x04ـَ\\x04ـُ\\x04ـِ\\x04ـّ\\x04ـْ\\x02ء\\x02آ\\x02أ\\x02ؤ\\x02إ\" +\n\t\"\\x02ئ\\x02ا\\x02ب\\x02ة\\x02ت\\x02ث\\x02ج\\x02ح\\x02خ\\x02د\\x02ذ\\x02ر\\x02ز\\x02س\" +\n\t\"\\x02ش\\x02ص\\x02ض\\x02ط\\x02ظ\\x02ع\\x02غ\\x02ف\\x02ق\\x02ك\\x02ل\\x02م\\x02ن\\x02ه\" +\n\t\"\\x02و\\x02ي\\x04لآ\\x04لأ\\x04لإ\\x04لا\\x01\\x22\\x01'\\x01/\\x01^\\x01|\\x01~\\x02¢\" +\n\t\"\\x02£\\x02¬\\x02¦\\x02¥\\x08𝅗𝅥\\x08𝅘𝅥\\x0c𝅘𝅥𝅮\\x0c𝅘𝅥𝅯\\x0c𝅘𝅥𝅰\\x0c𝅘𝅥𝅱\\x0c𝅘𝅥𝅲\\x08𝆹\" +\n\t\"𝅥\\x08𝆺𝅥\\x0c𝆹𝅥𝅮\\x0c𝆺𝅥𝅮\\x0c𝆹𝅥𝅯\\x0c𝆺𝅥𝅯\\x02ı\\x02ȷ\\x02α\\x02ε\\x02ζ\\x02η\\x02\" +\n\t\"κ\\x02λ\\x02μ\\x02ν\\x02ξ\\x02ο\\x02σ\\x02τ\\x02υ\\x02ψ\\x03∇\\x03∂\\x02ϝ\\x02ٮ\\x02ڡ\" +\n\t\"\\x02ٯ\\x020,\\x021,\\x022,\\x023,\\x024,\\x025,\\x026,\\x027,\\x028,\\x029,\\x03(a)\" +\n\t\"\\x03(b)\\x03(c)\\x03(d)\\x03(e)\\x03(f)\\x03(g)\\x03(h)\\x03(i)\\x03(j)\\x03(k)\" +\n\t\"\\x03(l)\\x03(m)\\x03(n)\\x03(o)\\x03(p)\\x03(q)\\x03(r)\\x03(s)\\x03(t)\\x03(u)\" +\n\t\"\\x03(v)\\x03(w)\\x03(x)\\x03(y)\\x03(z)\\x07〔s〕\\x02wz\\x02hv\\x02sd\\x03ppv\\x02w\" +\n\t\"c\\x02mc\\x02md\\x02mr\\x02dj\\x06ほか\\x06ココ\\x03サ\\x03手\\x03字\\x03双\\x03デ\\x03二\\x03多\" +\n\t\"\\x03解\\x03天\\x03交\\x03映\\x03無\\x03料\\x03前\\x03後\\x03再\\x03新\\x03初\\x03終\\x03生\\x03販\" +\n\t\"\\x03声\\x03吹\\x03演\\x03投\\x03捕\\x03一\\x03三\\x03遊\\x03左\\x03中\\x03右\\x03指\\x03走\\x03打\" +\n\t\"\\x03禁\\x03空\\x03合\\x03満\\x03有\\x03月\\x03申\\x03割\\x03営\\x03配\\x09〔本〕\\x09〔三〕\\x09〔二〕\" +\n\t\"\\x09〔安〕\\x09〔点〕\\x09〔打〕\\x09〔盗〕\\x09〔勝〕\\x09〔敗〕\\x03得\\x03可\\x03丽\\x03丸\\x03乁\\x03你\" +\n\t\"\\x03侮\\x03侻\\x03倂\\x03偺\\x03備\\x03僧\\x03像\\x03㒞\\x03免\\x03兔\\x03兤\\x03具\\x03㒹\\x03內\" +\n\t\"\\x03冗\\x03冤\\x03仌\\x03冬\\x03况\\x03凵\\x03刃\\x03㓟\\x03刻\\x03剆\\x03剷\\x03㔕\\x03勇\\x03勉\" +\n\t\"\\x03勤\\x03勺\\x03包\\x03匆\\x03北\\x03卉\\x03卑\\x03博\\x03即\\x03卽\\x03卿\\x03灰\\x03及\\x03叟\" +\n\t\"\\x03叫\\x03叱\\x03吆\\x03咞\\x03吸\\x03呈\\x03周\\x03咢\\x03哶\\x03唐\\x03啓\\x03啣\\x03善\\x03喙\" +\n\t\"\\x03喫\\x03喳\\x03嗂\\x03圖\\x03嘆\\x03圗\\x03噑\\x03噴\\x03切\\x03壮\\x03城\\x03埴\\x03堍\\x03型\" +\n\t\"\\x03堲\\x03報\\x03墬\\x03売\\x03壷\\x03夆\\x03夢\\x03奢\\x03姬\\x03娛\\x03娧\\x03姘\\x03婦\\x03㛮\" +\n\t\"\\x03嬈\\x03嬾\\x03寃\\x03寘\\x03寧\\x03寳\\x03寿\\x03将\\x03尢\\x03㞁\\x03屠\\x03屮\\x03峀\\x03岍\" +\n\t\"\\x03嵃\\x03嵮\\x03嵫\\x03嵼\\x03巡\\x03巢\\x03㠯\\x03巽\\x03帨\\x03帽\\x03幩\\x03㡢\\x03㡼\\x03庰\" +\n\t\"\\x03庳\\x03庶\\x03廊\\x03廾\\x03舁\\x03弢\\x03㣇\\x03形\\x03彫\\x03㣣\\x03徚\\x03忍\\x03志\\x03忹\" +\n\t\"\\x03悁\\x03㤺\\x03㤜\\x03悔\\x03惇\\x03慈\\x03慌\\x03慎\\x03慺\\x03憎\\x03憲\\x03憤\\x03憯\\x03懞\" +\n\t\"\\x03懲\\x03懶\\x03成\\x03戛\\x03扝\\x03抱\\x03拔\\x03捐\\x03挽\\x03拼\\x03捨\\x03掃\\x03揤\\x03搢\" +\n\t\"\\x03揅\\x03掩\\x03㨮\\x03摩\\x03摾\\x03撝\\x03摷\\x03㩬\\x03敏\\x03敬\\x03旣\\x03書\\x03晉\\x03㬙\" +\n\t\"\\x03暑\\x03㬈\\x03㫤\\x03冒\\x03冕\\x03最\\x03暜\\x03肭\\x03䏙\\x03朗\\x03望\\x03朡\\x03杞\\x03杓\" +\n\t\"\\x03㭉\\x03柺\\x03枅\\x03桒\\x03梅\\x03梎\\x03栟\\x03椔\\x03㮝\\x03楂\\x03榣\\x03槪\\x03檨\\x03櫛\" +\n\t\"\\x03㰘\\x03次\\x03歔\\x03㱎\\x03歲\\x03殟\\x03殺\\x03殻\\x03汎\\x03沿\\x03泍\\x03汧\\x03洖\\x03派\" +\n\t\"\\x03海\\x03流\\x03浩\\x03浸\\x03涅\\x03洴\\x03港\\x03湮\\x03㴳\\x03滋\\x03滇\\x03淹\\x03潮\\x03濆\" +\n\t\"\\x03瀹\\x03瀞\\x03瀛\\x03㶖\\x03灊\\x03災\\x03灷\\x03炭\\x03煅\\x03熜\\x03爨\\x03爵\\x03牐\\x03犀\" +\n\t\"\\x03犕\\x03獺\\x03王\\x03㺬\\x03玥\\x03㺸\\x03瑇\\x03瑜\\x03瑱\\x03璅\\x03瓊\\x03㼛\\x03甤\\x03甾\" +\n\t\"\\x03異\\x03瘐\\x03㿼\\x03䀈\\x03直\\x03眞\\x03真\\x03睊\\x03䀹\\x03瞋\\x03䁆\\x03䂖\\x03硎\\x03碌\" +\n\t\"\\x03磌\\x03䃣\\x03祖\\x03福\\x03秫\\x03䄯\\x03穀\\x03穊\\x03穏\\x03䈂\\x03篆\\x03築\\x03䈧\\x03糒\" +\n\t\"\\x03䊠\\x03糨\\x03糣\\x03紀\\x03絣\\x03䌁\\x03緇\\x03縂\\x03繅\\x03䌴\\x03䍙\\x03罺\\x03羕\\x03翺\" +\n\t\"\\x03者\\x03聠\\x03聰\\x03䏕\\x03育\\x03脃\\x03䐋\\x03脾\\x03媵\\x03舄\\x03辞\\x03䑫\\x03芑\\x03芋\" +\n\t\"\\x03芝\\x03劳\\x03花\\x03芳\\x03芽\\x03苦\\x03若\\x03茝\\x03荣\\x03莭\\x03茣\\x03莽\\x03菧\\x03著\" +\n\t\"\\x03荓\\x03菊\\x03菌\\x03菜\\x03䔫\\x03蓱\\x03蓳\\x03蔖\\x03蕤\\x03䕝\\x03䕡\\x03䕫\\x03虐\\x03虜\" +\n\t\"\\x03虧\\x03虩\\x03蚩\\x03蚈\\x03蜎\\x03蛢\\x03蝹\\x03蜨\\x03蝫\\x03螆\\x03蟡\\x03蠁\\x03䗹\\x03衠\" +\n\t\"\\x03衣\\x03裗\\x03裞\\x03䘵\\x03裺\\x03㒻\\x03䚾\\x03䛇\\x03誠\\x03諭\\x03變\\x03豕\\x03貫\\x03賁\" +\n\t\"\\x03贛\\x03起\\x03跋\\x03趼\\x03跰\\x03軔\\x03輸\\x03邔\\x03郱\\x03鄑\\x03鄛\\x03鈸\\x03鋗\\x03鋘\" +\n\t\"\\x03鉼\\x03鏹\\x03鐕\\x03開\\x03䦕\\x03閷\\x03䧦\\x03雃\\x03嶲\\x03霣\\x03䩮\\x03䩶\\x03韠\\x03䪲\" +\n\t\"\\x03頋\\x03頩\\x03飢\\x03䬳\\x03餩\\x03馧\\x03駂\\x03駾\\x03䯎\\x03鬒\\x03鱀\\x03鳽\\x03䳎\\x03䳭\" +\n\t\"\\x03鵧\\x03䳸\\x03麻\\x03䵖\\x03黹\\x03黾\\x03鼅\\x03鼏\\x03鼖\\x03鼻\"\n\nvar xorData string = \"\" + // Size: 4862 bytes\n\t\"\\x02\\x0c\\x09\\x02\\xb0\\xec\\x02\\xad\\xd8\\x02\\xad\\xd9\\x02\\x06\\x07\\x02\\x0f\\x12\" +\n\t\"\\x02\\x0f\\x1f\\x02\\x0f\\x1d\\x02\\x01\\x13\\x02\\x0f\\x16\\x02\\x0f\\x0b\\x02\\x0f3\" +\n\t\"\\x02\\x0f7\\x02\\x0f?\\x02\\x0f/\\x02\\x0f*\\x02\\x0c&\\x02\\x0c*\\x02\\x0c;\\x02\\x0c9\" +\n\t\"\\x02\\x0c%\\x02\\xab\\xed\\x02\\xab\\xe2\\x02\\xab\\xe3\\x02\\xa9\\xe0\\x02\\xa9\\xe1\" +\n\t\"\\x02\\xa9\\xe6\\x02\\xa3\\xcb\\x02\\xa3\\xc8\\x02\\xa3\\xc9\\x02\\x01#\\x02\\x01\\x08\" +\n\t\"\\x02\\x0e>\\x02\\x0e'\\x02\\x0f\\x03\\x02\\x03\\x0d\\x02\\x03\\x09\\x02\\x03\\x17\\x02\" +\n\t\"\\x03\\x0e\\x02\\x02\\x03\\x02\\x011\\x02\\x01\\x00\\x02\\x01\\x10\\x02\\x03<\\x02\\x07\" +\n\t\"\\x0d\\x02\\x02\\x0c\\x02\\x0c0\\x02\\x01\\x03\\x02\\x01\\x01\\x02\\x01 \\x02\\x01\\x22\" +\n\t\"\\x02\\x01)\\x02\\x01\\x0a\\x02\\x01\\x0c\\x02\\x02\\x06\\x02\\x02\\x02\\x02\\x03\\x10\" +\n\t\"\\x03\\x037 \\x03\\x0b+\\x03\\x021\\x00\\x02\\x01\\x04\\x02\\x01\\x02\\x02\\x019\\x02\" +\n\t\"\\x03\\x1c\\x02\\x02$\\x03\\x80p$\\x02\\x03:\\x02\\x03\\x0a\\x03\\xc1r.\\x03\\xc1r,\\x03\" +\n\t\"\\xc1r\\x02\\x02\\x02:\\x02\\x02>\\x02\\x02,\\x02\\x02\\x10\\x02\\x02\\x00\\x03\\xc1s<\" +\n\t\"\\x03\\xc1s*\\x03\\xc2L$\\x03\\xc2L;\\x02\\x09)\\x02\\x0a\\x19\\x03\\x83\\xab\\xe3\\x03\" +\n\t\"\\x83\\xab\\xf2\\x03 4\\xe0\\x03\\x81\\xab\\xea\\x03\\x81\\xab\\xf3\\x03 4\\xef\\x03\\x96\" +\n\t\"\\xe1\\xcd\\x03\\x84\\xe5\\xc3\\x02\\x0d\\x11\\x03\\x8b\\xec\\xcb\\x03\\x94\\xec\\xcf\\x03\" +\n\t\"\\x9a\\xec\\xc2\\x03\\x8b\\xec\\xdb\\x03\\x94\\xec\\xdf\\x03\\x9a\\xec\\xd2\\x03\\x01\\x0c\" +\n\t\"!\\x03\\x01\\x0c#\\x03ʠ\\x9d\\x03ʣ\\x9c\\x03ʢ\\x9f\\x03ʥ\\x9e\\x03ʤ\\x91\\x03ʧ\\x90\\x03\" +\n\t\"ʦ\\x93\\x03ʩ\\x92\\x03ʨ\\x95\\x03\\xca\\xf3\\xb5\\x03\\xca\\xf0\\xb4\\x03\\xca\\xf1\\xb7\" +\n\t\"\\x03\\xca\\xf6\\xb6\\x03\\xca\\xf7\\x89\\x03\\xca\\xf4\\x88\\x03\\xca\\xf5\\x8b\\x03\\xca\" +\n\t\"\\xfa\\x8a\\x03\\xca\\xfb\\x8d\\x03\\xca\\xf8\\x8c\\x03\\xca\\xf9\\x8f\\x03\\xca\\xfe\\x8e\" +\n\t\"\\x03\\xca\\xff\\x81\\x03\\xca\\xfc\\x80\\x03\\xca\\xfd\\x83\\x03\\xca\\xe2\\x82\\x03\\xca\" +\n\t\"\\xe3\\x85\\x03\\xca\\xe0\\x84\\x03\\xca\\xe1\\x87\\x03\\xca\\xe6\\x86\\x03\\xca\\xe7\\x99\" +\n\t\"\\x03\\xca\\xe4\\x98\\x03\\xca\\xe5\\x9b\\x03\\xca\\xea\\x9a\\x03\\xca\\xeb\\x9d\\x03\\xca\" +\n\t\"\\xe8\\x9c\\x03ؓ\\x89\\x03ߔ\\x8b\\x02\\x010\\x03\\x03\\x04\\x1e\\x03\\x04\\x15\\x12\\x03\" +\n\t\"\\x0b\\x05,\\x03\\x06\\x04\\x00\\x03\\x06\\x04)\\x03\\x06\\x044\\x03\\x06\\x04<\\x03\\x06\" +\n\t\"\\x05\\x1d\\x03\\x06\\x06\\x00\\x03\\x06\\x06\\x0a\\x03\\x06\\x06'\\x03\\x06\\x062\\x03\" +\n\t\"\\x0786\\x03\\x079/\\x03\\x079 \\x03\\x07:\\x0e\\x03\\x07:\\x1b\\x03\\x07:%\\x03\\x07;/\" +\n\t\"\\x03\\x07;%\\x03\\x074\\x11\\x03\\x076\\x09\\x03\\x077*\\x03\\x070\\x01\\x03\\x070\\x0f\" +\n\t\"\\x03\\x070.\\x03\\x071\\x16\\x03\\x071\\x04\\x03\\x0710\\x03\\x072\\x18\\x03\\x072-\" +\n\t\"\\x03\\x073\\x14\\x03\\x073>\\x03\\x07'\\x09\\x03\\x07 \\x00\\x03\\x07\\x1f\\x0b\\x03\" +\n\t\"\\x07\\x18#\\x03\\x07\\x18(\\x03\\x07\\x186\\x03\\x07\\x18\\x03\\x03\\x07\\x19\\x16\\x03\" +\n\t\"\\x07\\x116\\x03\\x07\\x12'\\x03\\x07\\x13\\x10\\x03\\x07\\x0c&\\x03\\x07\\x0c\\x08\\x03\" +\n\t\"\\x07\\x0c\\x13\\x03\\x07\\x0d\\x02\\x03\\x07\\x0d\\x1c\\x03\\x07\\x0b5\\x03\\x07\\x0b\" +\n\t\"\\x0a\\x03\\x07\\x0b\\x01\\x03\\x07\\x0b\\x0f\\x03\\x07\\x05\\x00\\x03\\x07\\x05\\x09\\x03\" +\n\t\"\\x07\\x05\\x0b\\x03\\x07\\x07\\x01\\x03\\x07\\x07\\x08\\x03\\x07\\x00<\\x03\\x07\\x00+\" +\n\t\"\\x03\\x07\\x01)\\x03\\x07\\x01\\x1b\\x03\\x07\\x01\\x08\\x03\\x07\\x03?\\x03\\x0445\\x03\" +\n\t\"\\x044\\x08\\x03\\x0454\\x03\\x04)/\\x03\\x04)5\\x03\\x04+\\x05\\x03\\x04+\\x14\\x03\" +\n\t\"\\x04+ \\x03\\x04+<\\x03\\x04*&\\x03\\x04*\\x22\\x03\\x04&8\\x03\\x04!\\x01\\x03\\x04!\" +\n\t\"\\x22\\x03\\x04\\x11+\\x03\\x04\\x10.\\x03\\x04\\x104\\x03\\x04\\x13=\\x03\\x04\\x12\\x04\" +\n\t\"\\x03\\x04\\x12\\x0a\\x03\\x04\\x0d\\x1d\\x03\\x04\\x0d\\x07\\x03\\x04\\x0d \\x03\\x05<>\" +\n\t\"\\x03\\x055<\\x03\\x055!\\x03\\x055#\\x03\\x055&\\x03\\x054\\x1d\\x03\\x054\\x02\\x03\" +\n\t\"\\x054\\x07\\x03\\x0571\\x03\\x053\\x1a\\x03\\x053\\x16\\x03\\x05.<\\x03\\x05.\\x07\\x03\" +\n\t\"\\x05):\\x03\\x05)<\\x03\\x05)\\x0c\\x03\\x05)\\x15\\x03\\x05+-\\x03\\x05+5\\x03\\x05$\" +\n\t\"\\x1e\\x03\\x05$\\x14\\x03\\x05'\\x04\\x03\\x05'\\x14\\x03\\x05&\\x02\\x03\\x05\\x226\" +\n\t\"\\x03\\x05\\x22\\x0c\\x03\\x05\\x22\\x1c\\x03\\x05\\x19\\x0a\\x03\\x05\\x1b\\x09\\x03\\x05\" +\n\t\"\\x1b\\x0c\\x03\\x05\\x14\\x07\\x03\\x05\\x16?\\x03\\x05\\x16\\x0c\\x03\\x05\\x0c\\x05\" +\n\t\"\\x03\\x05\\x0e\\x0f\\x03\\x05\\x01\\x0e\\x03\\x05\\x00(\\x03\\x05\\x030\\x03\\x05\\x03\" +\n\t\"\\x06\\x03\\x0a==\\x03\\x0a=1\\x03\\x0a=,\\x03\\x0a=\\x0c\\x03\\x0a??\\x03\\x0a<\\x08\" +\n\t\"\\x03\\x0a9!\\x03\\x0a9)\\x03\\x0a97\\x03\\x0a99\\x03\\x0a6\\x0a\\x03\\x0a6\\x1c\\x03\" +\n\t\"\\x0a6\\x17\\x03\\x0a7'\\x03\\x0a78\\x03\\x0a73\\x03\\x0a'\\x01\\x03\\x0a'&\\x03\\x0a\" +\n\t\"\\x1f\\x0e\\x03\\x0a\\x1f\\x03\\x03\\x0a\\x1f3\\x03\\x0a\\x1b/\\x03\\x0a\\x18\\x19\\x03\" +\n\t\"\\x0a\\x19\\x01\\x03\\x0a\\x16\\x14\\x03\\x0a\\x0e\\x22\\x03\\x0a\\x0f\\x10\\x03\\x0a\\x0f\" +\n\t\"\\x02\\x03\\x0a\\x0f \\x03\\x0a\\x0c\\x04\\x03\\x0a\\x0b>\\x03\\x0a\\x0b+\\x03\\x0a\\x08/\" +\n\t\"\\x03\\x0a\\x046\\x03\\x0a\\x05\\x14\\x03\\x0a\\x00\\x04\\x03\\x0a\\x00\\x10\\x03\\x0a\" +\n\t\"\\x00\\x14\\x03\\x0b<3\\x03\\x0b;*\\x03\\x0b9\\x22\\x03\\x0b9)\\x03\\x0b97\\x03\\x0b+\" +\n\t\"\\x10\\x03\\x0b((\\x03\\x0b&5\\x03\\x0b$\\x1c\\x03\\x0b$\\x12\\x03\\x0b%\\x04\\x03\\x0b#\" +\n\t\"<\\x03\\x0b#0\\x03\\x0b#\\x0d\\x03\\x0b#\\x19\\x03\\x0b!:\\x03\\x0b!\\x1f\\x03\\x0b!\" +\n\t\"\\x00\\x03\\x0b\\x1e5\\x03\\x0b\\x1c\\x1d\\x03\\x0b\\x1d-\\x03\\x0b\\x1d(\\x03\\x0b\\x18.\" +\n\t\"\\x03\\x0b\\x18 \\x03\\x0b\\x18\\x16\\x03\\x0b\\x14\\x13\\x03\\x0b\\x15$\\x03\\x0b\\x15\" +\n\t\"\\x22\\x03\\x0b\\x12\\x1b\\x03\\x0b\\x12\\x10\\x03\\x0b\\x132\\x03\\x0b\\x13=\\x03\\x0b\" +\n\t\"\\x12\\x18\\x03\\x0b\\x0c&\\x03\\x0b\\x061\\x03\\x0b\\x06:\\x03\\x0b\\x05#\\x03\\x0b\\x05\" +\n\t\"<\\x03\\x0b\\x04\\x0b\\x03\\x0b\\x04\\x04\\x03\\x0b\\x04\\x1b\\x03\\x0b\\x042\\x03\\x0b\" +\n\t\"\\x041\\x03\\x0b\\x03\\x03\\x03\\x0b\\x03\\x1d\\x03\\x0b\\x03/\\x03\\x0b\\x03+\\x03\\x0b\" +\n\t\"\\x02\\x1b\\x03\\x0b\\x02\\x00\\x03\\x0b\\x01\\x1e\\x03\\x0b\\x01\\x08\\x03\\x0b\\x015\" +\n\t\"\\x03\\x06\\x0d9\\x03\\x06\\x0d=\\x03\\x06\\x0d?\\x03\\x02\\x001\\x03\\x02\\x003\\x03\" +\n\t\"\\x02\\x02\\x19\\x03\\x02\\x006\\x03\\x02\\x02\\x1b\\x03\\x02\\x004\\x03\\x02\\x00<\\x03\" +\n\t\"\\x02\\x02\\x0a\\x03\\x02\\x02\\x0e\\x03\\x02\\x01\\x1a\\x03\\x02\\x01\\x07\\x03\\x02\\x01\" +\n\t\"\\x05\\x03\\x02\\x01\\x0b\\x03\\x02\\x01%\\x03\\x02\\x01\\x0c\\x03\\x02\\x01\\x04\\x03\" +\n\t\"\\x02\\x01\\x1c\\x03\\x02\\x00.\\x03\\x02\\x002\\x03\\x02\\x00>\\x03\\x02\\x00\\x12\\x03\" +\n\t\"\\x02\\x00\\x16\\x03\\x02\\x011\\x03\\x02\\x013\\x03\\x02\\x02 \\x03\\x02\\x02%\\x03\\x02\" +\n\t\"\\x02$\\x03\\x02\\x028\\x03\\x02\\x02;\\x03\\x02\\x024\\x03\\x02\\x012\\x03\\x02\\x022\" +\n\t\"\\x03\\x02\\x02/\\x03\\x02\\x01,\\x03\\x02\\x01\\x13\\x03\\x02\\x01\\x16\\x03\\x02\\x01\" +\n\t\"\\x11\\x03\\x02\\x01\\x1e\\x03\\x02\\x01\\x15\\x03\\x02\\x01\\x17\\x03\\x02\\x01\\x0f\\x03\" +\n\t\"\\x02\\x01\\x08\\x03\\x02\\x00?\\x03\\x02\\x03\\x07\\x03\\x02\\x03\\x0d\\x03\\x02\\x03\" +\n\t\"\\x13\\x03\\x02\\x03\\x1d\\x03\\x02\\x03\\x1f\\x03\\x02\\x00\\x03\\x03\\x02\\x00\\x0d\\x03\" +\n\t\"\\x02\\x00\\x01\\x03\\x02\\x00\\x1b\\x03\\x02\\x00\\x19\\x03\\x02\\x00\\x18\\x03\\x02\\x00\" +\n\t\"\\x13\\x03\\x02\\x00/\\x03\\x07>\\x12\\x03\\x07<\\x1f\\x03\\x07>\\x1d\\x03\\x06\\x1d\\x0e\" +\n\t\"\\x03\\x07>\\x1c\\x03\\x07>:\\x03\\x07>\\x13\\x03\\x04\\x12+\\x03\\x07?\\x03\\x03\\x07>\" +\n\t\"\\x02\\x03\\x06\\x224\\x03\\x06\\x1a.\\x03\\x07<%\\x03\\x06\\x1c\\x0b\\x03\\x0609\\x03\" +\n\t\"\\x05\\x1f\\x01\\x03\\x04'\\x08\\x03\\x93\\xfd\\xf5\\x03\\x02\\x0d \\x03\\x02\\x0d#\\x03\" +\n\t\"\\x02\\x0d!\\x03\\x02\\x0d&\\x03\\x02\\x0d\\x22\\x03\\x02\\x0d/\\x03\\x02\\x0d,\\x03\\x02\" +\n\t\"\\x0d$\\x03\\x02\\x0d'\\x03\\x02\\x0d%\\x03\\x02\\x0d;\\x03\\x02\\x0d=\\x03\\x02\\x0d?\" +\n\t\"\\x03\\x099.\\x03\\x08\\x0b7\\x03\\x08\\x02\\x14\\x03\\x08\\x14\\x0d\\x03\\x08.:\\x03\" +\n\t\"\\x089'\\x03\\x0f\\x0b\\x18\\x03\\x0f\\x1c1\\x03\\x0f\\x17&\\x03\\x0f9\\x1f\\x03\\x0f0\" +\n\t\"\\x0c\\x03\\x0e\\x0a9\\x03\\x0e\\x056\\x03\\x0e\\x1c#\\x03\\x0f\\x13\\x0e\\x03\\x072\\x00\" +\n\t\"\\x03\\x070\\x0d\\x03\\x072\\x0b\\x03\\x06\\x11\\x18\\x03\\x070\\x10\\x03\\x06\\x0f(\\x03\" +\n\t\"\\x072\\x05\\x03\\x06\\x0f,\\x03\\x073\\x15\\x03\\x06\\x07\\x08\\x03\\x05\\x16\\x02\\x03\" +\n\t\"\\x04\\x0b \\x03\\x05:8\\x03\\x05\\x16%\\x03\\x0a\\x0d\\x1f\\x03\\x06\\x16\\x10\\x03\\x05\" +\n\t\"\\x1d5\\x03\\x05*;\\x03\\x05\\x16\\x1b\\x03\\x04.-\\x03\\x06\\x1a\\x19\\x03\\x04\\x03,\" +\n\t\"\\x03\\x0b87\\x03\\x04/\\x0a\\x03\\x06\\x00,\\x03\\x04-\\x01\\x03\\x04\\x1e-\\x03\\x06/(\" +\n\t\"\\x03\\x0a\\x0b5\\x03\\x06\\x0e7\\x03\\x06\\x07.\\x03\\x0597\\x03\\x0a*%\\x03\\x0760\" +\n\t\"\\x03\\x06\\x0c;\\x03\\x05'\\x00\\x03\\x072.\\x03\\x072\\x08\\x03\\x06=\\x01\\x03\\x06\" +\n\t\"\\x05\\x1b\\x03\\x06\\x06\\x12\\x03\\x06$=\\x03\\x06'\\x0d\\x03\\x04\\x11\\x0f\\x03\\x076\" +\n\t\",\\x03\\x06\\x07;\\x03\\x06.,\\x03\\x86\\xf9\\xea\\x03\\x8f\\xff\\xeb\\x02\\x092\\x02\" +\n\t\"\\x095\\x02\\x094\\x02\\x09;\\x02\\x09>\\x02\\x098\\x02\\x09*\\x02\\x09/\\x02\\x09,\\x02\" +\n\t\"\\x09%\\x02\\x09&\\x02\\x09#\\x02\\x09 \\x02\\x08!\\x02\\x08%\\x02\\x08$\\x02\\x08+\\x02\" +\n\t\"\\x08.\\x02\\x08*\\x02\\x08&\\x02\\x088\\x02\\x08>\\x02\\x084\\x02\\x086\\x02\\x080\\x02\" +\n\t\"\\x08\\x10\\x02\\x08\\x17\\x02\\x08\\x12\\x02\\x08\\x1d\\x02\\x08\\x1f\\x02\\x08\\x13\\x02\" +\n\t\"\\x08\\x15\\x02\\x08\\x14\\x02\\x08\\x0c\\x03\\x8b\\xfd\\xd0\\x03\\x81\\xec\\xc6\\x03\\x87\" +\n\t\"\\xe0\\x8a\\x03-2\\xe3\\x03\\x80\\xef\\xe4\\x03-2\\xea\\x03\\x88\\xe6\\xeb\\x03\\x8e\\xe6\" +\n\t\"\\xe8\\x03\\x84\\xe6\\xe9\\x03\\x97\\xe6\\xee\\x03-2\\xf9\\x03-2\\xf6\\x03\\x8e\\xe3\\xad\" +\n\t\"\\x03\\x80\\xe3\\x92\\x03\\x88\\xe3\\x90\\x03\\x8e\\xe3\\x90\\x03\\x80\\xe3\\x97\\x03\\x88\" +\n\t\"\\xe3\\x95\\x03\\x88\\xfe\\xcb\\x03\\x8e\\xfe\\xca\\x03\\x84\\xfe\\xcd\\x03\\x91\\xef\\xc9\" +\n\t\"\\x03-2\\xc1\\x03-2\\xc0\\x03-2\\xcb\\x03\\x88@\\x09\\x03\\x8e@\\x08\\x03\\x8f\\xe0\\xf5\" +\n\t\"\\x03\\x8e\\xe6\\xf9\\x03\\x8e\\xe0\\xfa\\x03\\x93\\xff\\xf4\\x03\\x84\\xee\\xd3\\x03\\x0b\" +\n\t\"(\\x04\\x023 \\x03\\x0b)\\x08\\x021;\\x02\\x01*\\x03\\x0b#\\x10\\x03\\x0b 0\\x03\\x0b!\" +\n\t\"\\x10\\x03\\x0b!0\\x03\\x07\\x15\\x08\\x03\\x09?5\\x03\\x07\\x1f\\x08\\x03\\x07\\x17\\x0b\" +\n\t\"\\x03\\x09\\x1f\\x15\\x03\\x0b\\x1c7\\x03\\x0a+#\\x03\\x06\\x1a\\x1b\\x03\\x06\\x1a\\x14\" +\n\t\"\\x03\\x0a\\x01\\x18\\x03\\x06#\\x1b\\x03\\x0a2\\x0c\\x03\\x0a\\x01\\x04\\x03\\x09#;\\x03\" +\n\t\"\\x08='\\x03\\x08\\x1a\\x0a\\x03\\x07</\\x03\\x07:+\\x03\\x07\\x07*\\x03\\x06&\\x1c\\x03\" +\n\t\"\\x09\\x0c\\x16\\x03\\x09\\x10\\x0e\\x03\\x08'\\x0f\\x03\\x08+\\x09\\x03\\x074%\\x03\\x06\" +\n\t\"!3\\x03\\x06\\x03+\\x03\\x0b\\x1e\\x19\\x03\\x0a))\\x03\\x09\\x08\\x19\\x03\\x08,\\x05\" +\n\t\"\\x03\\x07<2\\x03\\x06\\x1c>\\x03\\x0a\\x111\\x03\\x09\\x1b\\x09\\x03\\x073.\\x03\\x07\" +\n\t\"\\x01\\x00\\x03\\x09/,\\x03\\x07#>\\x03\\x07\\x048\\x03\\x0a\\x1f\\x22\\x03\\x098>\\x03\" +\n\t\"\\x09\\x11\\x00\\x03\\x08/\\x17\\x03\\x06'\\x22\\x03\\x0b\\x1a+\\x03\\x0a\\x22\\x19\\x03\" +\n\t\"\\x0a/1\\x03\\x0974\\x03\\x09\\x0f\\x22\\x03\\x08,\\x22\\x03\\x08?\\x14\\x03\\x07$5\\x03\" +\n\t\"\\x07<3\\x03\\x07=*\\x03\\x07\\x13\\x18\\x03\\x068\\x0a\\x03\\x06\\x09\\x16\\x03\\x06\" +\n\t\"\\x13\\x00\\x03\\x08\\x067\\x03\\x08\\x01\\x03\\x03\\x08\\x12\\x1d\\x03\\x07+7\\x03\\x06(\" +\n\t\";\\x03\\x06\\x1c?\\x03\\x07\\x0e\\x17\\x03\\x0a\\x06\\x1d\\x03\\x0a\\x19\\x07\\x03\\x08\" +\n\t\"\\x14$\\x03\\x07$;\\x03\\x08,$\\x03\\x08\\x06\\x0d\\x03\\x07\\x16\\x0a\\x03\\x06>>\\x03\" +\n\t\"\\x0a\\x06\\x12\\x03\\x0a\\x14)\\x03\\x09\\x0d\\x1f\\x03\\x09\\x12\\x17\\x03\\x09\\x19\" +\n\t\"\\x01\\x03\\x08\\x11 \\x03\\x08\\x1d'\\x03\\x06<\\x1a\\x03\\x0a.\\x00\\x03\\x07'\\x18\" +\n\t\"\\x03\\x0a\\x22\\x08\\x03\\x08\\x0d\\x0a\\x03\\x08\\x13)\\x03\\x07*)\\x03\\x06<,\\x03\" +\n\t\"\\x07\\x0b\\x1a\\x03\\x09.\\x14\\x03\\x09\\x0d\\x1e\\x03\\x07\\x0e#\\x03\\x0b\\x1d'\\x03\" +\n\t\"\\x0a\\x0a8\\x03\\x09%2\\x03\\x08+&\\x03\\x080\\x12\\x03\\x0a)4\\x03\\x08\\x06\\x1f\\x03\" +\n\t\"\\x0b\\x1b\\x1a\\x03\\x0a\\x1b\\x0f\\x03\\x0b\\x1d*\\x03\\x09\\x16$\\x03\\x090\\x11\\x03\" +\n\t\"\\x08\\x11\\x08\\x03\\x0a*(\\x03\\x0a\\x042\\x03\\x089,\\x03\\x074'\\x03\\x07\\x0f\\x05\" +\n\t\"\\x03\\x09\\x0b\\x0a\\x03\\x07\\x1b\\x01\\x03\\x09\\x17:\\x03\\x09.\\x0d\\x03\\x07.\\x11\" +\n\t\"\\x03\\x09+\\x15\\x03\\x080\\x13\\x03\\x0b\\x1f\\x19\\x03\\x0a \\x11\\x03\\x0a\\x220\\x03\" +\n\t\"\\x09\\x07;\\x03\\x08\\x16\\x1c\\x03\\x07,\\x13\\x03\\x07\\x0e/\\x03\\x06\\x221\\x03\\x0a\" +\n\t\".\\x0a\\x03\\x0a7\\x02\\x03\\x0a\\x032\\x03\\x0a\\x1d.\\x03\\x091\\x06\\x03\\x09\\x19:\" +\n\t\"\\x03\\x08\\x02/\\x03\\x060+\\x03\\x06\\x0f-\\x03\\x06\\x1c\\x1f\\x03\\x06\\x1d\\x07\\x03\" +\n\t\"\\x0a,\\x11\\x03\\x09=\\x0d\\x03\\x09\\x0b;\\x03\\x07\\x1b/\\x03\\x0a\\x1f:\\x03\\x09 \" +\n\t\"\\x1f\\x03\\x09.\\x10\\x03\\x094\\x0b\\x03\\x09\\x1a1\\x03\\x08#\\x1a\\x03\\x084\\x1d\" +\n\t\"\\x03\\x08\\x01\\x1f\\x03\\x08\\x11\\x22\\x03\\x07'8\\x03\\x07\\x1a>\\x03\\x0757\\x03\" +\n\t\"\\x06&9\\x03\\x06+\\x11\\x03\\x0a.\\x0b\\x03\\x0a,>\\x03\\x0a4#\\x03\\x08%\\x17\\x03\" +\n\t\"\\x07\\x05\\x22\\x03\\x07\\x0c\\x0b\\x03\\x0a\\x1d+\\x03\\x0a\\x19\\x16\\x03\\x09+\\x1f\" +\n\t\"\\x03\\x09\\x08\\x0b\\x03\\x08\\x16\\x18\\x03\\x08+\\x12\\x03\\x0b\\x1d\\x0c\\x03\\x0a=\" +\n\t\"\\x10\\x03\\x0a\\x09\\x0d\\x03\\x0a\\x10\\x11\\x03\\x09&0\\x03\\x08(\\x1f\\x03\\x087\\x07\" +\n\t\"\\x03\\x08\\x185\\x03\\x07'6\\x03\\x06.\\x05\\x03\\x06=\\x04\\x03\\x06;;\\x03\\x06\\x06,\" +\n\t\"\\x03\\x0b\\x18>\\x03\\x08\\x00\\x18\\x03\\x06 \\x03\\x03\\x06<\\x00\\x03\\x09%\\x18\\x03\" +\n\t\"\\x0b\\x1c<\\x03\\x0a%!\\x03\\x0a\\x09\\x12\\x03\\x0a\\x16\\x02\\x03\\x090'\\x03\\x09\" +\n\t\"\\x0e=\\x03\\x08 \\x0e\\x03\\x08>\\x03\\x03\\x074>\\x03\\x06&?\\x03\\x06\\x19\\x09\\x03\" +\n\t\"\\x06?(\\x03\\x0a-\\x0e\\x03\\x09:3\\x03\\x098:\\x03\\x09\\x12\\x0b\\x03\\x09\\x1d\\x17\" +\n\t\"\\x03\\x087\\x05\\x03\\x082\\x14\\x03\\x08\\x06%\\x03\\x08\\x13\\x1f\\x03\\x06\\x06\\x0e\" +\n\t\"\\x03\\x0a\\x22<\\x03\\x09/<\\x03\\x06>+\\x03\\x0a'?\\x03\\x0a\\x13\\x0c\\x03\\x09\\x10<\" +\n\t\"\\x03\\x07\\x1b=\\x03\\x0a\\x19\\x13\\x03\\x09\\x22\\x1d\\x03\\x09\\x07\\x0d\\x03\\x08)\" +\n\t\"\\x1c\\x03\\x06=\\x1a\\x03\\x0a/4\\x03\\x0a7\\x11\\x03\\x0a\\x16:\\x03\\x09?3\\x03\\x09:\" +\n\t\"/\\x03\\x09\\x05\\x0a\\x03\\x09\\x14\\x06\\x03\\x087\\x22\\x03\\x080\\x07\\x03\\x08\\x1a\" +\n\t\"\\x1f\\x03\\x07\\x04(\\x03\\x07\\x04\\x09\\x03\\x06 %\\x03\\x06<\\x08\\x03\\x0a+\\x14\" +\n\t\"\\x03\\x09\\x1d\\x16\\x03\\x0a70\\x03\\x08 >\\x03\\x0857\\x03\\x070\\x0a\\x03\\x06=\\x12\" +\n\t\"\\x03\\x06\\x16%\\x03\\x06\\x1d,\\x03\\x099#\\x03\\x09\\x10>\\x03\\x07 \\x1e\\x03\\x08\" +\n\t\"\\x0c<\\x03\\x08\\x0b\\x18\\x03\\x08\\x15+\\x03\\x08,:\\x03\\x08%\\x22\\x03\\x07\\x0a$\" +\n\t\"\\x03\\x0b\\x1c=\\x03\\x07+\\x08\\x03\\x0a/\\x05\\x03\\x0a \\x07\\x03\\x0a\\x12'\\x03\" +\n\t\"\\x09#\\x11\\x03\\x08\\x1b\\x15\\x03\\x0a\\x06\\x01\\x03\\x09\\x1c\\x1b\\x03\\x0922\\x03\" +\n\t\"\\x07\\x14<\\x03\\x07\\x09\\x04\\x03\\x061\\x04\\x03\\x07\\x0e\\x01\\x03\\x0a\\x13\\x18\" +\n\t\"\\x03\\x0a-\\x0c\\x03\\x0a?\\x0d\\x03\\x0a\\x09\\x0a\\x03\\x091&\\x03\\x0a/\\x0b\\x03\" +\n\t\"\\x08$<\\x03\\x083\\x1d\\x03\\x08\\x0c$\\x03\\x08\\x0d\\x07\\x03\\x08\\x0d?\\x03\\x08\" +\n\t\"\\x0e\\x14\\x03\\x065\\x0a\\x03\\x08\\x1a#\\x03\\x08\\x16#\\x03\\x0702\\x03\\x07\\x03\" +\n\t\"\\x1a\\x03\\x06(\\x1d\\x03\\x06+\\x1b\\x03\\x06\\x0b\\x05\\x03\\x06\\x0b\\x17\\x03\\x06\" +\n\t\"\\x0c\\x04\\x03\\x06\\x1e\\x19\\x03\\x06+0\\x03\\x062\\x18\\x03\\x0b\\x16\\x1e\\x03\\x0a+\" +\n\t\"\\x16\\x03\\x0a-?\\x03\\x0a#:\\x03\\x0a#\\x10\\x03\\x0a%$\\x03\\x0a>+\\x03\\x0a01\\x03\" +\n\t\"\\x0a1\\x10\\x03\\x0a\\x099\\x03\\x0a\\x0a\\x12\\x03\\x0a\\x19\\x1f\\x03\\x0a\\x19\\x12\" +\n\t\"\\x03\\x09*)\\x03\\x09-\\x16\\x03\\x09.1\\x03\\x09.2\\x03\\x09<\\x0e\\x03\\x09> \\x03\" +\n\t\"\\x093\\x12\\x03\\x09\\x0b\\x01\\x03\\x09\\x1c2\\x03\\x09\\x11\\x1c\\x03\\x09\\x15%\\x03\" +\n\t\"\\x08,&\\x03\\x08!\\x22\\x03\\x089(\\x03\\x08\\x0b\\x1a\\x03\\x08\\x0d2\\x03\\x08\\x0c\" +\n\t\"\\x04\\x03\\x08\\x0c\\x06\\x03\\x08\\x0c\\x1f\\x03\\x08\\x0c\\x0c\\x03\\x08\\x0f\\x1f\\x03\" +\n\t\"\\x08\\x0f\\x1d\\x03\\x08\\x00\\x14\\x03\\x08\\x03\\x14\\x03\\x08\\x06\\x16\\x03\\x08\\x1e\" +\n\t\"#\\x03\\x08\\x11\\x11\\x03\\x08\\x10\\x18\\x03\\x08\\x14(\\x03\\x07)\\x1e\\x03\\x07.1\" +\n\t\"\\x03\\x07 $\\x03\\x07 '\\x03\\x078\\x08\\x03\\x07\\x0d0\\x03\\x07\\x0f7\\x03\\x07\\x05#\" +\n\t\"\\x03\\x07\\x05\\x1a\\x03\\x07\\x1a7\\x03\\x07\\x1d-\\x03\\x07\\x17\\x10\\x03\\x06)\\x1f\" +\n\t\"\\x03\\x062\\x0b\\x03\\x066\\x16\\x03\\x06\\x09\\x11\\x03\\x09(\\x1e\\x03\\x07!5\\x03\" +\n\t\"\\x0b\\x11\\x16\\x03\\x0a/\\x04\\x03\\x0a,\\x1a\\x03\\x0b\\x173\\x03\\x0a,1\\x03\\x0a/5\" +\n\t\"\\x03\\x0a\\x221\\x03\\x0a\\x22\\x0d\\x03\\x0a?%\\x03\\x0a<,\\x03\\x0a?#\\x03\\x0a>\\x19\" +\n\t\"\\x03\\x0a\\x08&\\x03\\x0a\\x0b\\x0e\\x03\\x0a\\x0c:\\x03\\x0a\\x0c+\\x03\\x0a\\x03\\x22\" +\n\t\"\\x03\\x0a\\x06)\\x03\\x0a\\x11\\x10\\x03\\x0a\\x11\\x1a\\x03\\x0a\\x17-\\x03\\x0a\\x14(\" +\n\t\"\\x03\\x09)\\x1e\\x03\\x09/\\x09\\x03\\x09.\\x00\\x03\\x09,\\x07\\x03\\x09/*\\x03\\x09-9\" +\n\t\"\\x03\\x09\\x228\\x03\\x09%\\x09\\x03\\x09:\\x12\\x03\\x09;\\x1d\\x03\\x09?\\x06\\x03\" +\n\t\"\\x093%\\x03\\x096\\x05\\x03\\x096\\x08\\x03\\x097\\x02\\x03\\x09\\x07,\\x03\\x09\\x04,\" +\n\t\"\\x03\\x09\\x1f\\x16\\x03\\x09\\x11\\x03\\x03\\x09\\x11\\x12\\x03\\x09\\x168\\x03\\x08*\" +\n\t\"\\x05\\x03\\x08/2\\x03\\x084:\\x03\\x08\\x22+\\x03\\x08 0\\x03\\x08&\\x0a\\x03\\x08;\" +\n\t\"\\x10\\x03\\x08>$\\x03\\x08>\\x18\\x03\\x0829\\x03\\x082:\\x03\\x081,\\x03\\x081<\\x03\" +\n\t\"\\x081\\x1c\\x03\\x087#\\x03\\x087*\\x03\\x08\\x09'\\x03\\x08\\x00\\x1d\\x03\\x08\\x05-\" +\n\t\"\\x03\\x08\\x1f4\\x03\\x08\\x1d\\x04\\x03\\x08\\x16\\x0f\\x03\\x07*7\\x03\\x07'!\\x03\" +\n\t\"\\x07%\\x1b\\x03\\x077\\x0c\\x03\\x07\\x0c1\\x03\\x07\\x0c.\\x03\\x07\\x00\\x06\\x03\\x07\" +\n\t\"\\x01\\x02\\x03\\x07\\x010\\x03\\x07\\x06=\\x03\\x07\\x01\\x03\\x03\\x07\\x01\\x13\\x03\" +\n\t\"\\x07\\x06\\x06\\x03\\x07\\x05\\x0a\\x03\\x07\\x1f\\x09\\x03\\x07\\x17:\\x03\\x06*1\\x03\" +\n\t\"\\x06-\\x1d\\x03\\x06\\x223\\x03\\x062:\\x03\\x060$\\x03\\x066\\x1e\\x03\\x064\\x12\\x03\" +\n\t\"\\x0645\\x03\\x06\\x0b\\x00\\x03\\x06\\x0b7\\x03\\x06\\x07\\x1f\\x03\\x06\\x15\\x12\\x03\" +\n\t\"\\x0c\\x05\\x0f\\x03\\x0b+\\x0b\\x03\\x0b+-\\x03\\x06\\x16\\x1b\\x03\\x06\\x15\\x17\\x03\" +\n\t\"\\x89\\xca\\xea\\x03\\x89\\xca\\xe8\\x03\\x0c8\\x10\\x03\\x0c8\\x01\\x03\\x0c8\\x0f\\x03\" +\n\t\"\\x0d8%\\x03\\x0d8!\\x03\\x0c8-\\x03\\x0c8/\\x03\\x0c8+\\x03\\x0c87\\x03\\x0c85\\x03\" +\n\t\"\\x0c9\\x09\\x03\\x0c9\\x0d\\x03\\x0c9\\x0f\\x03\\x0c9\\x0b\\x03\\xcfu\\x0c\\x03\\xcfu\" +\n\t\"\\x0f\\x03\\xcfu\\x0e\\x03\\xcfu\\x09\\x03\\x0c9\\x10\\x03\\x0d9\\x0c\\x03\\xcf`;\\x03\" +\n\t\"\\xcf`>\\x03\\xcf`9\\x03\\xcf`8\\x03\\xcf`7\\x03\\xcf`*\\x03\\xcf`-\\x03\\xcf`,\\x03\" +\n\t\"\\x0d\\x1b\\x1a\\x03\\x0d\\x1b&\\x03\\x0c=.\\x03\\x0c=%\\x03\\x0c>\\x1e\\x03\\x0c>\\x14\" +\n\t\"\\x03\\x0c?\\x06\\x03\\x0c?\\x0b\\x03\\x0c?\\x0c\\x03\\x0c?\\x0d\\x03\\x0c?\\x02\\x03\" +\n\t\"\\x0c>\\x0f\\x03\\x0c>\\x08\\x03\\x0c>\\x09\\x03\\x0c>,\\x03\\x0c>\\x0c\\x03\\x0c?\\x13\" +\n\t\"\\x03\\x0c?\\x16\\x03\\x0c?\\x15\\x03\\x0c?\\x1c\\x03\\x0c?\\x1f\\x03\\x0c?\\x1d\\x03\" +\n\t\"\\x0c?\\x1a\\x03\\x0c?\\x17\\x03\\x0c?\\x08\\x03\\x0c?\\x09\\x03\\x0c?\\x0e\\x03\\x0c?\" +\n\t\"\\x04\\x03\\x0c?\\x05\\x03\\x0c<?\\x03\\x0c=\\x00\\x03\\x0c=\\x06\\x03\\x0c=\\x05\\x03\" +\n\t\"\\x0c=\\x0c\\x03\\x0c=\\x0f\\x03\\x0c=\\x0d\\x03\\x0c=\\x0b\\x03\\x0c=\\x07\\x03\\x0c=\" +\n\t\"\\x19\\x03\\x0c=\\x15\\x03\\x0c=\\x11\\x03\\x0c=1\\x03\\x0c=3\\x03\\x0c=0\\x03\\x0c=>\" +\n\t\"\\x03\\x0c=2\\x03\\x0c=6\\x03\\x0c<\\x07\\x03\\x0c<\\x05\\x03\\x0e:!\\x03\\x0e:#\\x03\" +\n\t\"\\x0e8\\x09\\x03\\x0e:&\\x03\\x0e8\\x0b\\x03\\x0e:$\\x03\\x0e:,\\x03\\x0e8\\x1a\\x03\" +\n\t\"\\x0e8\\x1e\\x03\\x0e:*\\x03\\x0e:7\\x03\\x0e:5\\x03\\x0e:;\\x03\\x0e:\\x15\\x03\\x0e:<\" +\n\t\"\\x03\\x0e:4\\x03\\x0e:'\\x03\\x0e:-\\x03\\x0e:%\\x03\\x0e:?\\x03\\x0e:=\\x03\\x0e:)\" +\n\t\"\\x03\\x0e:/\\x03\\xcfs'\\x03\\x0d=\\x0f\\x03\\x0d+*\\x03\\x0d99\\x03\\x0d9;\\x03\\x0d9\" +\n\t\"?\\x03\\x0d)\\x0d\\x03\\x0d(%\\x02\\x01\\x18\\x02\\x01(\\x02\\x01\\x1e\\x03\\x0f$!\\x03\" +\n\t\"\\x0f87\\x03\\x0f4\\x0e\\x03\\x0f5\\x1d\\x03\\x06'\\x03\\x03\\x0f\\x08\\x18\\x03\\x0f\" +\n\t\"\\x0d\\x1b\\x03\\x0e2=\\x03\\x0e;\\x08\\x03\\x0e:\\x0b\\x03\\x0e\\x06$\\x03\\x0e\\x0d)\" +\n\t\"\\x03\\x0e\\x16\\x1f\\x03\\x0e\\x16\\x1b\\x03\\x0d$\\x0a\\x03\\x05,\\x1d\\x03\\x0d. \\x03\" +\n\t\"\\x0d.#\\x03\\x0c(/\\x03\\x09%\\x02\\x03\\x0d90\\x03\\x0d\\x0e4\\x03\\x0d\\x0d\\x0f\\x03\" +\n\t\"\\x0c#\\x00\\x03\\x0c,\\x1e\\x03\\x0c2\\x0e\\x03\\x0c\\x01\\x17\\x03\\x0c\\x09:\\x03\\x0e\" +\n\t\"\\x173\\x03\\x0c\\x08\\x03\\x03\\x0c\\x11\\x07\\x03\\x0c\\x10\\x18\\x03\\x0c\\x1f\\x1c\" +\n\t\"\\x03\\x0c\\x19\\x0e\\x03\\x0c\\x1a\\x1f\\x03\\x0f0>\\x03\\x0b->\\x03\\x0b<+\\x03\\x0b8\" +\n\t\"\\x13\\x03\\x0b\\x043\\x03\\x0b\\x14\\x03\\x03\\x0b\\x16%\\x03\\x0d\\x22&\\x03\\x0b\\x1a\" +\n\t\"\\x1a\\x03\\x0b\\x1a\\x04\\x03\\x0a%9\\x03\\x0a&2\\x03\\x0a&0\\x03\\x0a!\\x1a\\x03\\x0a!\" +\n\t\"7\\x03\\x0a5\\x10\\x03\\x0a=4\\x03\\x0a?\\x0e\\x03\\x0a>\\x10\\x03\\x0a\\x00 \\x03\\x0a\" +\n\t\"\\x0f:\\x03\\x0a\\x0f9\\x03\\x0a\\x0b\\x0a\\x03\\x0a\\x17%\\x03\\x0a\\x1b-\\x03\\x09-\" +\n\t\"\\x1a\\x03\\x09,4\\x03\\x09.,\\x03\\x09)\\x09\\x03\\x096!\\x03\\x091\\x1f\\x03\\x093\" +\n\t\"\\x16\\x03\\x0c+\\x1f\\x03\\x098 \\x03\\x098=\\x03\\x0c(\\x1a\\x03\\x0c(\\x16\\x03\\x09\" +\n\t\"\\x0a+\\x03\\x09\\x16\\x12\\x03\\x09\\x13\\x0e\\x03\\x09\\x153\\x03\\x08)!\\x03\\x09\\x1a\" +\n\t\"\\x01\\x03\\x09\\x18\\x01\\x03\\x08%#\\x03\\x08>\\x22\\x03\\x08\\x05%\\x03\\x08\\x02*\" +\n\t\"\\x03\\x08\\x15;\\x03\\x08\\x1b7\\x03\\x0f\\x07\\x1d\\x03\\x0f\\x04\\x03\\x03\\x070\\x0c\" +\n\t\"\\x03\\x07;\\x0b\\x03\\x07\\x08\\x17\\x03\\x07\\x12\\x06\\x03\\x06/-\\x03\\x0671\\x03\" +\n\t\"\\x065+\\x03\\x06>7\\x03\\x06\\x049\\x03\\x05+\\x1e\\x03\\x05,\\x17\\x03\\x05 \\x1d\\x03\" +\n\t\"\\x05\\x22\\x05\\x03\\x050\\x1d\"\n\n// lookup returns the trie value for the first UTF-8 encoding in s and\n// the width in bytes of this encoding. The size will be 0 if s does not\n// hold enough bytes to complete the encoding. len(s) must be greater than 0.\nfunc (t *idnaTrie) lookup(s []byte) (v uint16, sz int) {\n\tc0 := s[0]\n\tswitch {\n\tcase c0 < 0x80: // is ASCII\n\t\treturn idnaValues[c0], 1\n\tcase c0 < 0xC2:\n\t\treturn 0, 1 // Illegal UTF-8: not a starter, not ASCII.\n\tcase c0 < 0xE0: // 2-byte UTF-8\n\t\tif len(s) < 2 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c1), 2\n\tcase c0 < 0xF0: // 3-byte UTF-8\n\t\tif len(s) < 3 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c2), 3\n\tcase c0 < 0xF8: // 4-byte UTF-8\n\t\tif len(s) < 4 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to = uint32(i)<<6 + uint32(c2)\n\t\ti = idnaIndex[o]\n\t\tc3 := s[3]\n\t\tif c3 < 0x80 || 0xC0 <= c3 {\n\t\t\treturn 0, 3 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c3), 4\n\t}\n\t// Illegal rune\n\treturn 0, 1\n}\n\n// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.\n// s must start with a full and valid UTF-8 encoded rune.\nfunc (t *idnaTrie) lookupUnsafe(s []byte) uint16 {\n\tc0 := s[0]\n\tif c0 < 0x80 { // is ASCII\n\t\treturn idnaValues[c0]\n\t}\n\ti := idnaIndex[c0]\n\tif c0 < 0xE0 { // 2-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[1])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[1])]\n\tif c0 < 0xF0 { // 3-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[2])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[2])]\n\tif c0 < 0xF8 { // 4-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[3])\n\t}\n\treturn 0\n}\n\n// lookupString returns the trie value for the first UTF-8 encoding in s and\n// the width in bytes of this encoding. The size will be 0 if s does not\n// hold enough bytes to complete the encoding. len(s) must be greater than 0.\nfunc (t *idnaTrie) lookupString(s string) (v uint16, sz int) {\n\tc0 := s[0]\n\tswitch {\n\tcase c0 < 0x80: // is ASCII\n\t\treturn idnaValues[c0], 1\n\tcase c0 < 0xC2:\n\t\treturn 0, 1 // Illegal UTF-8: not a starter, not ASCII.\n\tcase c0 < 0xE0: // 2-byte UTF-8\n\t\tif len(s) < 2 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c1), 2\n\tcase c0 < 0xF0: // 3-byte UTF-8\n\t\tif len(s) < 3 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c2), 3\n\tcase c0 < 0xF8: // 4-byte UTF-8\n\t\tif len(s) < 4 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to = uint32(i)<<6 + uint32(c2)\n\t\ti = idnaIndex[o]\n\t\tc3 := s[3]\n\t\tif c3 < 0x80 || 0xC0 <= c3 {\n\t\t\treturn 0, 3 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c3), 4\n\t}\n\t// Illegal rune\n\treturn 0, 1\n}\n\n// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.\n// s must start with a full and valid UTF-8 encoded rune.\nfunc (t *idnaTrie) lookupStringUnsafe(s string) uint16 {\n\tc0 := s[0]\n\tif c0 < 0x80 { // is ASCII\n\t\treturn idnaValues[c0]\n\t}\n\ti := idnaIndex[c0]\n\tif c0 < 0xE0 { // 2-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[1])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[1])]\n\tif c0 < 0xF0 { // 3-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[2])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[2])]\n\tif c0 < 0xF8 { // 4-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[3])\n\t}\n\treturn 0\n}\n\n// idnaTrie. Total size: 29708 bytes (29.01 KiB). Checksum: c3ecc76d8fffa6e6.\ntype idnaTrie struct{}\n\nfunc newIdnaTrie(i int) *idnaTrie {\n\treturn &idnaTrie{}\n}\n\n// lookupValue determines the type of block n and looks up the value for b.\nfunc (t *idnaTrie) lookupValue(n uint32, b byte) uint16 {\n\tswitch {\n\tcase n < 125:\n\t\treturn uint16(idnaValues[n<<6+uint32(b)])\n\tdefault:\n\t\tn -= 125\n\t\treturn uint16(idnaSparse.lookup(n, b))\n\t}\n}\n\n// idnaValues: 127 blocks, 8128 entries, 16256 bytes\n// The third block is the zero block.\nvar idnaValues = [8128]uint16{\n\t// Block 0x0, offset 0x0\n\t0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080,\n\t0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080,\n\t0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080,\n\t0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080,\n\t0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080,\n\t0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080,\n\t0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080,\n\t0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080,\n\t0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008,\n\t0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080,\n\t0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080,\n\t// Block 0x1, offset 0x40\n\t0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105,\n\t0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105,\n\t0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105,\n\t0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105,\n\t0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080,\n\t0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008,\n\t0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008,\n\t0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008,\n\t0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008,\n\t0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080,\n\t0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080,\n\t// Block 0x2, offset 0x80\n\t// Block 0x3, offset 0xc0\n\t0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040,\n\t0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040,\n\t0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040,\n\t0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040,\n\t0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040,\n\t0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018,\n\t0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x001a, 0xe9: 0x0018,\n\t0xea: 0x0039, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x004a,\n\t0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0069, 0xf3: 0x0079, 0xf4: 0x008a, 0xf5: 0x0005,\n\t0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x00aa, 0xf9: 0x00c9, 0xfa: 0x00d9, 0xfb: 0x0018,\n\t0xfc: 0x00e9, 0xfd: 0x0119, 0xfe: 0x0149, 0xff: 0x0018,\n\t// Block 0x4, offset 0x100\n\t0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008,\n\t0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008,\n\t0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008,\n\t0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008,\n\t0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008,\n\t0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008,\n\t0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008,\n\t0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008,\n\t0x130: 0x0179, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008,\n\t0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d,\n\t0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0199,\n\t// Block 0x5, offset 0x140\n\t0x140: 0x0199, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d,\n\t0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x01b9, 0x14a: 0xe00d, 0x14b: 0x0008,\n\t0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008,\n\t0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008,\n\t0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008,\n\t0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008,\n\t0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008,\n\t0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008,\n\t0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008,\n\t0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d,\n\t0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x01d9,\n\t// Block 0x6, offset 0x180\n\t0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008,\n\t0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d,\n\t0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d,\n\t0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d,\n\t0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155,\n\t0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008,\n\t0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d,\n\t0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd,\n\t0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d,\n\t0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008,\n\t0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008,\n\t// Block 0x7, offset 0x1c0\n\t0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x01e9, 0x1c5: 0x01e9,\n\t0x1c6: 0x01e9, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d,\n\t0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d,\n\t0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d,\n\t0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008,\n\t0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008,\n\t0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008,\n\t0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008,\n\t0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008,\n\t0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008,\n\t0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008,\n\t// Block 0x8, offset 0x200\n\t0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008,\n\t0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008,\n\t0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008,\n\t0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008,\n\t0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008,\n\t0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008,\n\t0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008,\n\t0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008,\n\t0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008,\n\t0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0209, 0x23b: 0xe03d,\n\t0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x0229, 0x23f: 0x0008,\n\t// Block 0x9, offset 0x240\n\t0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018,\n\t0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008,\n\t0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008,\n\t0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018,\n\t0x258: 0x029a, 0x259: 0x02ba, 0x25a: 0x02da, 0x25b: 0x02fa, 0x25c: 0x031a, 0x25d: 0x033a,\n\t0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0359, 0x262: 0x01d9, 0x263: 0x0369,\n\t0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018,\n\t0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018,\n\t0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018,\n\t0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018,\n\t0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018,\n\t// Block 0xa, offset 0x280\n\t0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d,\n\t0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308,\n\t0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308,\n\t0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308,\n\t0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308,\n\t0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308,\n\t0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308,\n\t0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308,\n\t0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008,\n\t0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008,\n\t0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d,\n\t// Block 0xb, offset 0x2c0\n\t0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x008a, 0x2c5: 0x03d2,\n\t0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040,\n\t0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105,\n\t0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105,\n\t0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105,\n\t0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d,\n\t0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d,\n\t0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008,\n\t0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008,\n\t0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008,\n\t0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008,\n\t// Block 0xc, offset 0x300\n\t0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008,\n\t0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008,\n\t0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd,\n\t0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008,\n\t0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008,\n\t0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008,\n\t0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008,\n\t0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008,\n\t0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd,\n\t0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008,\n\t0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d,\n\t// Block 0xd, offset 0x340\n\t0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008,\n\t0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008,\n\t0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008,\n\t0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008,\n\t0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008,\n\t0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008,\n\t0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008,\n\t0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008,\n\t0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008,\n\t0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008,\n\t0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008,\n\t// Block 0xe, offset 0x380\n\t0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308,\n\t0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008,\n\t0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008,\n\t0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008,\n\t0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008,\n\t0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008,\n\t0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008,\n\t0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008,\n\t0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008,\n\t0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008,\n\t0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008,\n\t// Block 0xf, offset 0x3c0\n\t0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d,\n\t0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d,\n\t0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008,\n\t0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008,\n\t0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008,\n\t0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008,\n\t0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008,\n\t0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008,\n\t0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008,\n\t0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008,\n\t0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008,\n\t// Block 0x10, offset 0x400\n\t0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008,\n\t0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008,\n\t0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008,\n\t0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008,\n\t0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008,\n\t0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008,\n\t0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008,\n\t0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008,\n\t0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5,\n\t0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5,\n\t0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5,\n\t// Block 0x11, offset 0x440\n\t0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840,\n\t0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818,\n\t0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308,\n\t0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308,\n\t0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040,\n\t0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08,\n\t0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08,\n\t0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08,\n\t0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08,\n\t0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08,\n\t0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08,\n\t// Block 0x12, offset 0x480\n\t0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08,\n\t0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308,\n\t0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308,\n\t0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308,\n\t0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308,\n\t0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808,\n\t0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808,\n\t0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08,\n\t0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0429,\n\t0x4b6: 0x0451, 0x4b7: 0x0479, 0x4b8: 0x04a1, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08,\n\t0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08,\n\t// Block 0x13, offset 0x4c0\n\t0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08,\n\t0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08,\n\t0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08,\n\t0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308,\n\t0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840,\n\t0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308,\n\t0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018,\n\t0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08,\n\t0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008,\n\t0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08,\n\t0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08,\n\t// Block 0x14, offset 0x500\n\t0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818,\n\t0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818,\n\t0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308,\n\t0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08,\n\t0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08,\n\t0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08,\n\t0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08,\n\t0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08,\n\t0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308,\n\t0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308,\n\t0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308,\n\t// Block 0x15, offset 0x540\n\t0x540: 0x0c08, 0x541: 0x0a08, 0x542: 0x0a08, 0x543: 0x0a08, 0x544: 0x0a08, 0x545: 0x0a08,\n\t0x546: 0x0c08, 0x547: 0x0c08, 0x548: 0x0a08, 0x549: 0x0c08, 0x54a: 0x0a08, 0x54b: 0x0a08,\n\t0x54c: 0x0a08, 0x54d: 0x0a08, 0x54e: 0x0a08, 0x54f: 0x0a08, 0x550: 0x0a08, 0x551: 0x0a08,\n\t0x552: 0x0a08, 0x553: 0x0a08, 0x554: 0x0c08, 0x555: 0x0a08, 0x556: 0x0808, 0x557: 0x0808,\n\t0x558: 0x0808, 0x559: 0x3308, 0x55a: 0x3308, 0x55b: 0x3308, 0x55c: 0x0040, 0x55d: 0x0040,\n\t0x55e: 0x0818, 0x55f: 0x0040, 0x560: 0x0a08, 0x561: 0x0808, 0x562: 0x0a08, 0x563: 0x0a08,\n\t0x564: 0x0a08, 0x565: 0x0a08, 0x566: 0x0808, 0x567: 0x0c08, 0x568: 0x0a08, 0x569: 0x0c08,\n\t0x56a: 0x0c08, 0x56b: 0x0040, 0x56c: 0x0040, 0x56d: 0x0040, 0x56e: 0x0040, 0x56f: 0x0040,\n\t0x570: 0x0040, 0x571: 0x0040, 0x572: 0x0040, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040,\n\t0x576: 0x0040, 0x577: 0x0040, 0x578: 0x0040, 0x579: 0x0040, 0x57a: 0x0040, 0x57b: 0x0040,\n\t0x57c: 0x0040, 0x57d: 0x0040, 0x57e: 0x0040, 0x57f: 0x0040,\n\t// Block 0x16, offset 0x580\n\t0x580: 0x3008, 0x581: 0x3308, 0x582: 0x3308, 0x583: 0x3308, 0x584: 0x3308, 0x585: 0x3308,\n\t0x586: 0x3308, 0x587: 0x3308, 0x588: 0x3308, 0x589: 0x3008, 0x58a: 0x3008, 0x58b: 0x3008,\n\t0x58c: 0x3008, 0x58d: 0x3b08, 0x58e: 0x3008, 0x58f: 0x3008, 0x590: 0x0008, 0x591: 0x3308,\n\t0x592: 0x3308, 0x593: 0x3308, 0x594: 0x3308, 0x595: 0x3308, 0x596: 0x3308, 0x597: 0x3308,\n\t0x598: 0x04c9, 0x599: 0x0501, 0x59a: 0x0539, 0x59b: 0x0571, 0x59c: 0x05a9, 0x59d: 0x05e1,\n\t0x59e: 0x0619, 0x59f: 0x0651, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x3308, 0x5a3: 0x3308,\n\t0x5a4: 0x0018, 0x5a5: 0x0018, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008,\n\t0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008,\n\t0x5b0: 0x0018, 0x5b1: 0x0008, 0x5b2: 0x0008, 0x5b3: 0x0008, 0x5b4: 0x0008, 0x5b5: 0x0008,\n\t0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0008, 0x5bb: 0x0008,\n\t0x5bc: 0x0008, 0x5bd: 0x0008, 0x5be: 0x0008, 0x5bf: 0x0008,\n\t// Block 0x17, offset 0x5c0\n\t0x5c0: 0x0008, 0x5c1: 0x3308, 0x5c2: 0x3008, 0x5c3: 0x3008, 0x5c4: 0x0040, 0x5c5: 0x0008,\n\t0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0008,\n\t0x5cc: 0x0008, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040,\n\t0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008,\n\t0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008,\n\t0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008,\n\t0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040,\n\t0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008,\n\t0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0040, 0x5f4: 0x0040, 0x5f5: 0x0040,\n\t0x5f6: 0x0008, 0x5f7: 0x0008, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040,\n\t0x5fc: 0x3308, 0x5fd: 0x0008, 0x5fe: 0x3008, 0x5ff: 0x3008,\n\t// Block 0x18, offset 0x600\n\t0x600: 0x3008, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3308, 0x604: 0x3308, 0x605: 0x0040,\n\t0x606: 0x0040, 0x607: 0x3008, 0x608: 0x3008, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x3008,\n\t0x60c: 0x3008, 0x60d: 0x3b08, 0x60e: 0x0008, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x0040,\n\t0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x3008,\n\t0x618: 0x0040, 0x619: 0x0040, 0x61a: 0x0040, 0x61b: 0x0040, 0x61c: 0x0689, 0x61d: 0x06c1,\n\t0x61e: 0x0040, 0x61f: 0x06f9, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x3308, 0x623: 0x3308,\n\t0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008,\n\t0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008,\n\t0x630: 0x0008, 0x631: 0x0008, 0x632: 0x0018, 0x633: 0x0018, 0x634: 0x0018, 0x635: 0x0018,\n\t0x636: 0x0018, 0x637: 0x0018, 0x638: 0x0018, 0x639: 0x0018, 0x63a: 0x0018, 0x63b: 0x0018,\n\t0x63c: 0x0008, 0x63d: 0x0018, 0x63e: 0x3308, 0x63f: 0x0040,\n\t// Block 0x19, offset 0x640\n\t0x640: 0x0040, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x3008, 0x644: 0x0040, 0x645: 0x0008,\n\t0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0040,\n\t0x64c: 0x0040, 0x64d: 0x0040, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0040,\n\t0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008,\n\t0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008,\n\t0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008,\n\t0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040,\n\t0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008,\n\t0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0731, 0x674: 0x0040, 0x675: 0x0008,\n\t0x676: 0x0769, 0x677: 0x0040, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040,\n\t0x67c: 0x3308, 0x67d: 0x0040, 0x67e: 0x3008, 0x67f: 0x3008,\n\t// Block 0x1a, offset 0x680\n\t0x680: 0x3008, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x0040, 0x684: 0x0040, 0x685: 0x0040,\n\t0x686: 0x0040, 0x687: 0x3308, 0x688: 0x3308, 0x689: 0x0040, 0x68a: 0x0040, 0x68b: 0x3308,\n\t0x68c: 0x3308, 0x68d: 0x3b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0040, 0x691: 0x3308,\n\t0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040,\n\t0x698: 0x0040, 0x699: 0x07a1, 0x69a: 0x07d9, 0x69b: 0x0811, 0x69c: 0x0008, 0x69d: 0x0040,\n\t0x69e: 0x0849, 0x69f: 0x0040, 0x6a0: 0x0040, 0x6a1: 0x0040, 0x6a2: 0x0040, 0x6a3: 0x0040,\n\t0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008,\n\t0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008,\n\t0x6b0: 0x3308, 0x6b1: 0x3308, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0008, 0x6b5: 0x3308,\n\t0x6b6: 0x0018, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0040, 0x6ba: 0x0040, 0x6bb: 0x0040,\n\t0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040,\n\t// Block 0x1b, offset 0x6c0\n\t0x6c0: 0x0040, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3008, 0x6c4: 0x0040, 0x6c5: 0x0008,\n\t0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008,\n\t0x6cc: 0x0008, 0x6cd: 0x0008, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0008,\n\t0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008,\n\t0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008,\n\t0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008,\n\t0x6e4: 0x0008, 0x6e5: 0x0008, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0040,\n\t0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008,\n\t0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008,\n\t0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040,\n\t0x6fc: 0x3308, 0x6fd: 0x0008, 0x6fe: 0x3008, 0x6ff: 0x3008,\n\t// Block 0x1c, offset 0x700\n\t0x700: 0x3008, 0x701: 0x3308, 0x702: 0x3308, 0x703: 0x3308, 0x704: 0x3308, 0x705: 0x3308,\n\t0x706: 0x0040, 0x707: 0x3308, 0x708: 0x3308, 0x709: 0x3008, 0x70a: 0x0040, 0x70b: 0x3008,\n\t0x70c: 0x3008, 0x70d: 0x3b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0008, 0x711: 0x0040,\n\t0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x0040, 0x717: 0x0040,\n\t0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0040, 0x71d: 0x0040,\n\t0x71e: 0x0040, 0x71f: 0x0040, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x3308, 0x723: 0x3308,\n\t0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008,\n\t0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008,\n\t0x730: 0x0018, 0x731: 0x0018, 0x732: 0x0040, 0x733: 0x0040, 0x734: 0x0040, 0x735: 0x0040,\n\t0x736: 0x0040, 0x737: 0x0040, 0x738: 0x0040, 0x739: 0x0008, 0x73a: 0x3308, 0x73b: 0x3308,\n\t0x73c: 0x3308, 0x73d: 0x3308, 0x73e: 0x3308, 0x73f: 0x3308,\n\t// Block 0x1d, offset 0x740\n\t0x740: 0x0040, 0x741: 0x3308, 0x742: 0x3008, 0x743: 0x3008, 0x744: 0x0040, 0x745: 0x0008,\n\t0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0008,\n\t0x74c: 0x0008, 0x74d: 0x0040, 0x74e: 0x0040, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040,\n\t0x752: 0x0040, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0008, 0x757: 0x0008,\n\t0x758: 0x0008, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0008, 0x75c: 0x0008, 0x75d: 0x0008,\n\t0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x0008, 0x763: 0x0008,\n\t0x764: 0x0008, 0x765: 0x0008, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0040,\n\t0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008,\n\t0x770: 0x0008, 0x771: 0x0040, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0040, 0x775: 0x0008,\n\t0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040,\n\t0x77c: 0x3308, 0x77d: 0x0008, 0x77e: 0x3008, 0x77f: 0x3308,\n\t// Block 0x1e, offset 0x780\n\t0x780: 0x3008, 0x781: 0x3308, 0x782: 0x3308, 0x783: 0x3308, 0x784: 0x3308, 0x785: 0x0040,\n\t0x786: 0x0040, 0x787: 0x3008, 0x788: 0x3008, 0x789: 0x0040, 0x78a: 0x0040, 0x78b: 0x3008,\n\t0x78c: 0x3008, 0x78d: 0x3b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040,\n\t0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x0040, 0x796: 0x3308, 0x797: 0x3008,\n\t0x798: 0x0040, 0x799: 0x0040, 0x79a: 0x0040, 0x79b: 0x0040, 0x79c: 0x0881, 0x79d: 0x08b9,\n\t0x79e: 0x0040, 0x79f: 0x0008, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x3308, 0x7a3: 0x3308,\n\t0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008,\n\t0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008,\n\t0x7b0: 0x0018, 0x7b1: 0x0008, 0x7b2: 0x0018, 0x7b3: 0x0018, 0x7b4: 0x0018, 0x7b5: 0x0018,\n\t0x7b6: 0x0018, 0x7b7: 0x0018, 0x7b8: 0x0040, 0x7b9: 0x0040, 0x7ba: 0x0040, 0x7bb: 0x0040,\n\t0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x0040, 0x7bf: 0x0040,\n\t// Block 0x1f, offset 0x7c0\n\t0x7c0: 0x0040, 0x7c1: 0x0040, 0x7c2: 0x3308, 0x7c3: 0x0008, 0x7c4: 0x0040, 0x7c5: 0x0008,\n\t0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0040,\n\t0x7cc: 0x0040, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040,\n\t0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0040, 0x7d7: 0x0040,\n\t0x7d8: 0x0040, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0008, 0x7dd: 0x0040,\n\t0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0040, 0x7e1: 0x0040, 0x7e2: 0x0040, 0x7e3: 0x0008,\n\t0x7e4: 0x0008, 0x7e5: 0x0040, 0x7e6: 0x0040, 0x7e7: 0x0040, 0x7e8: 0x0008, 0x7e9: 0x0008,\n\t0x7ea: 0x0008, 0x7eb: 0x0040, 0x7ec: 0x0040, 0x7ed: 0x0040, 0x7ee: 0x0008, 0x7ef: 0x0008,\n\t0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0008, 0x7f5: 0x0008,\n\t0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040,\n\t0x7fc: 0x0040, 0x7fd: 0x0040, 0x7fe: 0x3008, 0x7ff: 0x3008,\n\t// Block 0x20, offset 0x800\n\t0x800: 0x3308, 0x801: 0x3008, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x3008, 0x805: 0x0040,\n\t0x806: 0x3308, 0x807: 0x3308, 0x808: 0x3308, 0x809: 0x0040, 0x80a: 0x3308, 0x80b: 0x3308,\n\t0x80c: 0x3308, 0x80d: 0x3b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040,\n\t0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x3308, 0x816: 0x3308, 0x817: 0x0040,\n\t0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040,\n\t0x81e: 0x0040, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x3308, 0x823: 0x3308,\n\t0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008,\n\t0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008,\n\t0x830: 0x0040, 0x831: 0x0040, 0x832: 0x0040, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040,\n\t0x836: 0x0040, 0x837: 0x0018, 0x838: 0x0018, 0x839: 0x0018, 0x83a: 0x0018, 0x83b: 0x0018,\n\t0x83c: 0x0018, 0x83d: 0x0018, 0x83e: 0x0018, 0x83f: 0x0018,\n\t// Block 0x21, offset 0x840\n\t0x840: 0x0008, 0x841: 0x3308, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x0018, 0x845: 0x0008,\n\t0x846: 0x0008, 0x847: 0x0008, 0x848: 0x0008, 0x849: 0x0008, 0x84a: 0x0008, 0x84b: 0x0008,\n\t0x84c: 0x0008, 0x84d: 0x0040, 0x84e: 0x0008, 0x84f: 0x0008, 0x850: 0x0008, 0x851: 0x0040,\n\t0x852: 0x0008, 0x853: 0x0008, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x0008,\n\t0x858: 0x0008, 0x859: 0x0008, 0x85a: 0x0008, 0x85b: 0x0008, 0x85c: 0x0008, 0x85d: 0x0008,\n\t0x85e: 0x0008, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x0008, 0x863: 0x0008,\n\t0x864: 0x0008, 0x865: 0x0008, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0040,\n\t0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008,\n\t0x870: 0x0008, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0008, 0x874: 0x0040, 0x875: 0x0008,\n\t0x876: 0x0008, 0x877: 0x0008, 0x878: 0x0008, 0x879: 0x0008, 0x87a: 0x0040, 0x87b: 0x0040,\n\t0x87c: 0x3308, 0x87d: 0x0008, 0x87e: 0x3008, 0x87f: 0x3308,\n\t// Block 0x22, offset 0x880\n\t0x880: 0x3008, 0x881: 0x3008, 0x882: 0x3008, 0x883: 0x3008, 0x884: 0x3008, 0x885: 0x0040,\n\t0x886: 0x3308, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008,\n\t0x88c: 0x3308, 0x88d: 0x3b08, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040,\n\t0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0040, 0x895: 0x3008, 0x896: 0x3008, 0x897: 0x0040,\n\t0x898: 0x0040, 0x899: 0x0040, 0x89a: 0x0040, 0x89b: 0x0040, 0x89c: 0x0040, 0x89d: 0x0040,\n\t0x89e: 0x0008, 0x89f: 0x0040, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308,\n\t0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008,\n\t0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008,\n\t0x8b0: 0x0040, 0x8b1: 0x0008, 0x8b2: 0x0008, 0x8b3: 0x0040, 0x8b4: 0x0040, 0x8b5: 0x0040,\n\t0x8b6: 0x0040, 0x8b7: 0x0040, 0x8b8: 0x0040, 0x8b9: 0x0040, 0x8ba: 0x0040, 0x8bb: 0x0040,\n\t0x8bc: 0x0040, 0x8bd: 0x0040, 0x8be: 0x0040, 0x8bf: 0x0040,\n\t// Block 0x23, offset 0x8c0\n\t0x8c0: 0x3008, 0x8c1: 0x3308, 0x8c2: 0x3308, 0x8c3: 0x3308, 0x8c4: 0x3308, 0x8c5: 0x0040,\n\t0x8c6: 0x3008, 0x8c7: 0x3008, 0x8c8: 0x3008, 0x8c9: 0x0040, 0x8ca: 0x3008, 0x8cb: 0x3008,\n\t0x8cc: 0x3008, 0x8cd: 0x3b08, 0x8ce: 0x0008, 0x8cf: 0x0018, 0x8d0: 0x0040, 0x8d1: 0x0040,\n\t0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x3008,\n\t0x8d8: 0x0018, 0x8d9: 0x0018, 0x8da: 0x0018, 0x8db: 0x0018, 0x8dc: 0x0018, 0x8dd: 0x0018,\n\t0x8de: 0x0018, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x3308, 0x8e3: 0x3308,\n\t0x8e4: 0x0040, 0x8e5: 0x0040, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0008,\n\t0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008,\n\t0x8f0: 0x0018, 0x8f1: 0x0018, 0x8f2: 0x0018, 0x8f3: 0x0018, 0x8f4: 0x0018, 0x8f5: 0x0018,\n\t0x8f6: 0x0018, 0x8f7: 0x0018, 0x8f8: 0x0018, 0x8f9: 0x0018, 0x8fa: 0x0008, 0x8fb: 0x0008,\n\t0x8fc: 0x0008, 0x8fd: 0x0008, 0x8fe: 0x0008, 0x8ff: 0x0008,\n\t// Block 0x24, offset 0x900\n\t0x900: 0x0040, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x0040, 0x904: 0x0008, 0x905: 0x0040,\n\t0x906: 0x0008, 0x907: 0x0008, 0x908: 0x0008, 0x909: 0x0008, 0x90a: 0x0008, 0x90b: 0x0040,\n\t0x90c: 0x0008, 0x90d: 0x0008, 0x90e: 0x0008, 0x90f: 0x0008, 0x910: 0x0008, 0x911: 0x0008,\n\t0x912: 0x0008, 0x913: 0x0008, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0008,\n\t0x918: 0x0008, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0008, 0x91d: 0x0008,\n\t0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0008, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008,\n\t0x924: 0x0040, 0x925: 0x0008, 0x926: 0x0040, 0x927: 0x0008, 0x928: 0x0008, 0x929: 0x0008,\n\t0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0008, 0x92d: 0x0008, 0x92e: 0x0008, 0x92f: 0x0008,\n\t0x930: 0x0008, 0x931: 0x3308, 0x932: 0x0008, 0x933: 0x0929, 0x934: 0x3308, 0x935: 0x3308,\n\t0x936: 0x3308, 0x937: 0x3308, 0x938: 0x3308, 0x939: 0x3308, 0x93a: 0x3b08, 0x93b: 0x3308,\n\t0x93c: 0x3308, 0x93d: 0x0008, 0x93e: 0x0040, 0x93f: 0x0040,\n\t// Block 0x25, offset 0x940\n\t0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x09d1, 0x944: 0x0008, 0x945: 0x0008,\n\t0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0040, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008,\n\t0x94c: 0x0008, 0x94d: 0x0a09, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008,\n\t0x952: 0x0a41, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0a79,\n\t0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0ab1, 0x95d: 0x0008,\n\t0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008,\n\t0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0ae9,\n\t0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0008, 0x96d: 0x0040, 0x96e: 0x0040, 0x96f: 0x0040,\n\t0x970: 0x0040, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x0b21, 0x974: 0x3308, 0x975: 0x0b59,\n\t0x976: 0x0b91, 0x977: 0x0bc9, 0x978: 0x0c19, 0x979: 0x0c51, 0x97a: 0x3308, 0x97b: 0x3308,\n\t0x97c: 0x3308, 0x97d: 0x3308, 0x97e: 0x3308, 0x97f: 0x3008,\n\t// Block 0x26, offset 0x980\n\t0x980: 0x3308, 0x981: 0x0ca1, 0x982: 0x3308, 0x983: 0x3308, 0x984: 0x3b08, 0x985: 0x0018,\n\t0x986: 0x3308, 0x987: 0x3308, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008,\n\t0x98c: 0x0008, 0x98d: 0x3308, 0x98e: 0x3308, 0x98f: 0x3308, 0x990: 0x3308, 0x991: 0x3308,\n\t0x992: 0x3308, 0x993: 0x0cd9, 0x994: 0x3308, 0x995: 0x3308, 0x996: 0x3308, 0x997: 0x3308,\n\t0x998: 0x0040, 0x999: 0x3308, 0x99a: 0x3308, 0x99b: 0x3308, 0x99c: 0x3308, 0x99d: 0x0d11,\n\t0x99e: 0x3308, 0x99f: 0x3308, 0x9a0: 0x3308, 0x9a1: 0x3308, 0x9a2: 0x0d49, 0x9a3: 0x3308,\n\t0x9a4: 0x3308, 0x9a5: 0x3308, 0x9a6: 0x3308, 0x9a7: 0x0d81, 0x9a8: 0x3308, 0x9a9: 0x3308,\n\t0x9aa: 0x3308, 0x9ab: 0x3308, 0x9ac: 0x0db9, 0x9ad: 0x3308, 0x9ae: 0x3308, 0x9af: 0x3308,\n\t0x9b0: 0x3308, 0x9b1: 0x3308, 0x9b2: 0x3308, 0x9b3: 0x3308, 0x9b4: 0x3308, 0x9b5: 0x3308,\n\t0x9b6: 0x3308, 0x9b7: 0x3308, 0x9b8: 0x3308, 0x9b9: 0x0df1, 0x9ba: 0x3308, 0x9bb: 0x3308,\n\t0x9bc: 0x3308, 0x9bd: 0x0040, 0x9be: 0x0018, 0x9bf: 0x0018,\n\t// Block 0x27, offset 0x9c0\n\t0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008,\n\t0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008,\n\t0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008,\n\t0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008,\n\t0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x0008, 0x9dc: 0x0008, 0x9dd: 0x0008,\n\t0x9de: 0x0008, 0x9df: 0x0008, 0x9e0: 0x0008, 0x9e1: 0x0008, 0x9e2: 0x0008, 0x9e3: 0x0008,\n\t0x9e4: 0x0008, 0x9e5: 0x0008, 0x9e6: 0x0008, 0x9e7: 0x0008, 0x9e8: 0x0008, 0x9e9: 0x0008,\n\t0x9ea: 0x0008, 0x9eb: 0x0008, 0x9ec: 0x0039, 0x9ed: 0x0ed1, 0x9ee: 0x0ee9, 0x9ef: 0x0008,\n\t0x9f0: 0x0ef9, 0x9f1: 0x0f09, 0x9f2: 0x0f19, 0x9f3: 0x0f31, 0x9f4: 0x0249, 0x9f5: 0x0f41,\n\t0x9f6: 0x0259, 0x9f7: 0x0f51, 0x9f8: 0x0359, 0x9f9: 0x0f61, 0x9fa: 0x0f71, 0x9fb: 0x0008,\n\t0x9fc: 0x00d9, 0x9fd: 0x0f81, 0x9fe: 0x0f99, 0x9ff: 0x0269,\n\t// Block 0x28, offset 0xa00\n\t0xa00: 0x0fa9, 0xa01: 0x0fb9, 0xa02: 0x0279, 0xa03: 0x0039, 0xa04: 0x0fc9, 0xa05: 0x0fe1,\n\t0xa06: 0x05b5, 0xa07: 0x0ee9, 0xa08: 0x0ef9, 0xa09: 0x0f09, 0xa0a: 0x0ff9, 0xa0b: 0x1011,\n\t0xa0c: 0x1029, 0xa0d: 0x0f31, 0xa0e: 0x0008, 0xa0f: 0x0f51, 0xa10: 0x0f61, 0xa11: 0x1041,\n\t0xa12: 0x00d9, 0xa13: 0x1059, 0xa14: 0x05cd, 0xa15: 0x05cd, 0xa16: 0x0f99, 0xa17: 0x0fa9,\n\t0xa18: 0x0fb9, 0xa19: 0x05b5, 0xa1a: 0x1071, 0xa1b: 0x1089, 0xa1c: 0x05e5, 0xa1d: 0x1099,\n\t0xa1e: 0x10b1, 0xa1f: 0x10c9, 0xa20: 0x10e1, 0xa21: 0x10f9, 0xa22: 0x0f41, 0xa23: 0x0269,\n\t0xa24: 0x0fb9, 0xa25: 0x1089, 0xa26: 0x1099, 0xa27: 0x10b1, 0xa28: 0x1111, 0xa29: 0x10e1,\n\t0xa2a: 0x10f9, 0xa2b: 0x0008, 0xa2c: 0x0008, 0xa2d: 0x0008, 0xa2e: 0x0008, 0xa2f: 0x0008,\n\t0xa30: 0x0008, 0xa31: 0x0008, 0xa32: 0x0008, 0xa33: 0x0008, 0xa34: 0x0008, 0xa35: 0x0008,\n\t0xa36: 0x0008, 0xa37: 0x0008, 0xa38: 0x1129, 0xa39: 0x0008, 0xa3a: 0x0008, 0xa3b: 0x0008,\n\t0xa3c: 0x0008, 0xa3d: 0x0008, 0xa3e: 0x0008, 0xa3f: 0x0008,\n\t// Block 0x29, offset 0xa40\n\t0xa40: 0x0008, 0xa41: 0x0008, 0xa42: 0x0008, 0xa43: 0x0008, 0xa44: 0x0008, 0xa45: 0x0008,\n\t0xa46: 0x0008, 0xa47: 0x0008, 0xa48: 0x0008, 0xa49: 0x0008, 0xa4a: 0x0008, 0xa4b: 0x0008,\n\t0xa4c: 0x0008, 0xa4d: 0x0008, 0xa4e: 0x0008, 0xa4f: 0x0008, 0xa50: 0x0008, 0xa51: 0x0008,\n\t0xa52: 0x0008, 0xa53: 0x0008, 0xa54: 0x0008, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008,\n\t0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0008, 0xa5b: 0x1141, 0xa5c: 0x1159, 0xa5d: 0x1169,\n\t0xa5e: 0x1181, 0xa5f: 0x1029, 0xa60: 0x1199, 0xa61: 0x11a9, 0xa62: 0x11c1, 0xa63: 0x11d9,\n\t0xa64: 0x11f1, 0xa65: 0x1209, 0xa66: 0x1221, 0xa67: 0x05fd, 0xa68: 0x1239, 0xa69: 0x1251,\n\t0xa6a: 0xe17d, 0xa6b: 0x1269, 0xa6c: 0x1281, 0xa6d: 0x1299, 0xa6e: 0x12b1, 0xa6f: 0x12c9,\n\t0xa70: 0x12e1, 0xa71: 0x12f9, 0xa72: 0x1311, 0xa73: 0x1329, 0xa74: 0x1341, 0xa75: 0x1359,\n\t0xa76: 0x1371, 0xa77: 0x1389, 0xa78: 0x0615, 0xa79: 0x13a1, 0xa7a: 0x13b9, 0xa7b: 0x13d1,\n\t0xa7c: 0x13e1, 0xa7d: 0x13f9, 0xa7e: 0x1411, 0xa7f: 0x1429,\n\t// Block 0x2a, offset 0xa80\n\t0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008,\n\t0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008,\n\t0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008,\n\t0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0xe00d, 0xa97: 0x0008,\n\t0xa98: 0xe00d, 0xa99: 0x0008, 0xa9a: 0xe00d, 0xa9b: 0x0008, 0xa9c: 0xe00d, 0xa9d: 0x0008,\n\t0xa9e: 0xe00d, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008,\n\t0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008,\n\t0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008,\n\t0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008,\n\t0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008,\n\t0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008,\n\t// Block 0x2b, offset 0xac0\n\t0xac0: 0xe00d, 0xac1: 0x0008, 0xac2: 0xe00d, 0xac3: 0x0008, 0xac4: 0xe00d, 0xac5: 0x0008,\n\t0xac6: 0xe00d, 0xac7: 0x0008, 0xac8: 0xe00d, 0xac9: 0x0008, 0xaca: 0xe00d, 0xacb: 0x0008,\n\t0xacc: 0xe00d, 0xacd: 0x0008, 0xace: 0xe00d, 0xacf: 0x0008, 0xad0: 0xe00d, 0xad1: 0x0008,\n\t0xad2: 0xe00d, 0xad3: 0x0008, 0xad4: 0xe00d, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008,\n\t0xad8: 0x0008, 0xad9: 0x0008, 0xada: 0x062d, 0xadb: 0x064d, 0xadc: 0x0008, 0xadd: 0x0008,\n\t0xade: 0x1441, 0xadf: 0x0008, 0xae0: 0xe00d, 0xae1: 0x0008, 0xae2: 0xe00d, 0xae3: 0x0008,\n\t0xae4: 0xe00d, 0xae5: 0x0008, 0xae6: 0xe00d, 0xae7: 0x0008, 0xae8: 0xe00d, 0xae9: 0x0008,\n\t0xaea: 0xe00d, 0xaeb: 0x0008, 0xaec: 0xe00d, 0xaed: 0x0008, 0xaee: 0xe00d, 0xaef: 0x0008,\n\t0xaf0: 0xe00d, 0xaf1: 0x0008, 0xaf2: 0xe00d, 0xaf3: 0x0008, 0xaf4: 0xe00d, 0xaf5: 0x0008,\n\t0xaf6: 0xe00d, 0xaf7: 0x0008, 0xaf8: 0xe00d, 0xaf9: 0x0008, 0xafa: 0xe00d, 0xafb: 0x0008,\n\t0xafc: 0xe00d, 0xafd: 0x0008, 0xafe: 0xe00d, 0xaff: 0x0008,\n\t// Block 0x2c, offset 0xb00\n\t0xb00: 0x0008, 0xb01: 0x0008, 0xb02: 0x0008, 0xb03: 0x0008, 0xb04: 0x0008, 0xb05: 0x0008,\n\t0xb06: 0x0040, 0xb07: 0x0040, 0xb08: 0xe045, 0xb09: 0xe045, 0xb0a: 0xe045, 0xb0b: 0xe045,\n\t0xb0c: 0xe045, 0xb0d: 0xe045, 0xb0e: 0x0040, 0xb0f: 0x0040, 0xb10: 0x0008, 0xb11: 0x0008,\n\t0xb12: 0x0008, 0xb13: 0x0008, 0xb14: 0x0008, 0xb15: 0x0008, 0xb16: 0x0008, 0xb17: 0x0008,\n\t0xb18: 0x0040, 0xb19: 0xe045, 0xb1a: 0x0040, 0xb1b: 0xe045, 0xb1c: 0x0040, 0xb1d: 0xe045,\n\t0xb1e: 0x0040, 0xb1f: 0xe045, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x0008,\n\t0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045,\n\t0xb2a: 0xe045, 0xb2b: 0xe045, 0xb2c: 0xe045, 0xb2d: 0xe045, 0xb2e: 0xe045, 0xb2f: 0xe045,\n\t0xb30: 0x0008, 0xb31: 0x1459, 0xb32: 0x0008, 0xb33: 0x1471, 0xb34: 0x0008, 0xb35: 0x1489,\n\t0xb36: 0x0008, 0xb37: 0x14a1, 0xb38: 0x0008, 0xb39: 0x14b9, 0xb3a: 0x0008, 0xb3b: 0x14d1,\n\t0xb3c: 0x0008, 0xb3d: 0x14e9, 0xb3e: 0x0040, 0xb3f: 0x0040,\n\t// Block 0x2d, offset 0xb40\n\t0xb40: 0x1501, 0xb41: 0x1531, 0xb42: 0x1561, 0xb43: 0x1591, 0xb44: 0x15c1, 0xb45: 0x15f1,\n\t0xb46: 0x1621, 0xb47: 0x1651, 0xb48: 0x1501, 0xb49: 0x1531, 0xb4a: 0x1561, 0xb4b: 0x1591,\n\t0xb4c: 0x15c1, 0xb4d: 0x15f1, 0xb4e: 0x1621, 0xb4f: 0x1651, 0xb50: 0x1681, 0xb51: 0x16b1,\n\t0xb52: 0x16e1, 0xb53: 0x1711, 0xb54: 0x1741, 0xb55: 0x1771, 0xb56: 0x17a1, 0xb57: 0x17d1,\n\t0xb58: 0x1681, 0xb59: 0x16b1, 0xb5a: 0x16e1, 0xb5b: 0x1711, 0xb5c: 0x1741, 0xb5d: 0x1771,\n\t0xb5e: 0x17a1, 0xb5f: 0x17d1, 0xb60: 0x1801, 0xb61: 0x1831, 0xb62: 0x1861, 0xb63: 0x1891,\n\t0xb64: 0x18c1, 0xb65: 0x18f1, 0xb66: 0x1921, 0xb67: 0x1951, 0xb68: 0x1801, 0xb69: 0x1831,\n\t0xb6a: 0x1861, 0xb6b: 0x1891, 0xb6c: 0x18c1, 0xb6d: 0x18f1, 0xb6e: 0x1921, 0xb6f: 0x1951,\n\t0xb70: 0x0008, 0xb71: 0x0008, 0xb72: 0x1981, 0xb73: 0x19b1, 0xb74: 0x19d9, 0xb75: 0x0040,\n\t0xb76: 0x0008, 0xb77: 0x1a01, 0xb78: 0xe045, 0xb79: 0xe045, 0xb7a: 0x0665, 0xb7b: 0x1459,\n\t0xb7c: 0x19b1, 0xb7d: 0x067e, 0xb7e: 0x1a31, 0xb7f: 0x069e,\n\t// Block 0x2e, offset 0xb80\n\t0xb80: 0x06be, 0xb81: 0x1a4a, 0xb82: 0x1a79, 0xb83: 0x1aa9, 0xb84: 0x1ad1, 0xb85: 0x0040,\n\t0xb86: 0x0008, 0xb87: 0x1af9, 0xb88: 0x06dd, 0xb89: 0x1471, 0xb8a: 0x06f5, 0xb8b: 0x1489,\n\t0xb8c: 0x1aa9, 0xb8d: 0x1b2a, 0xb8e: 0x1b5a, 0xb8f: 0x1b8a, 0xb90: 0x0008, 0xb91: 0x0008,\n\t0xb92: 0x0008, 0xb93: 0x1bb9, 0xb94: 0x0040, 0xb95: 0x0040, 0xb96: 0x0008, 0xb97: 0x0008,\n\t0xb98: 0xe045, 0xb99: 0xe045, 0xb9a: 0x070d, 0xb9b: 0x14a1, 0xb9c: 0x0040, 0xb9d: 0x1bd2,\n\t0xb9e: 0x1c02, 0xb9f: 0x1c32, 0xba0: 0x0008, 0xba1: 0x0008, 0xba2: 0x0008, 0xba3: 0x1c61,\n\t0xba4: 0x0008, 0xba5: 0x0008, 0xba6: 0x0008, 0xba7: 0x0008, 0xba8: 0xe045, 0xba9: 0xe045,\n\t0xbaa: 0x0725, 0xbab: 0x14d1, 0xbac: 0xe04d, 0xbad: 0x1c7a, 0xbae: 0x03d2, 0xbaf: 0x1caa,\n\t0xbb0: 0x0040, 0xbb1: 0x0040, 0xbb2: 0x1cb9, 0xbb3: 0x1ce9, 0xbb4: 0x1d11, 0xbb5: 0x0040,\n\t0xbb6: 0x0008, 0xbb7: 0x1d39, 0xbb8: 0x073d, 0xbb9: 0x14b9, 0xbba: 0x0515, 0xbbb: 0x14e9,\n\t0xbbc: 0x1ce9, 0xbbd: 0x0756, 0xbbe: 0x0776, 0xbbf: 0x0040,\n\t// Block 0x2f, offset 0xbc0\n\t0xbc0: 0x000a, 0xbc1: 0x000a, 0xbc2: 0x000a, 0xbc3: 0x000a, 0xbc4: 0x000a, 0xbc5: 0x000a,\n\t0xbc6: 0x000a, 0xbc7: 0x000a, 0xbc8: 0x000a, 0xbc9: 0x000a, 0xbca: 0x000a, 0xbcb: 0x03c0,\n\t0xbcc: 0x0003, 0xbcd: 0x0003, 0xbce: 0x0340, 0xbcf: 0x0b40, 0xbd0: 0x0018, 0xbd1: 0xe00d,\n\t0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x0796,\n\t0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018,\n\t0xbde: 0x0018, 0xbdf: 0x0018, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018,\n\t0xbe4: 0x0040, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0018, 0xbe8: 0x0040, 0xbe9: 0x0040,\n\t0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x000a,\n\t0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x1d69, 0xbf4: 0x1da1, 0xbf5: 0x0018,\n\t0xbf6: 0x1df1, 0xbf7: 0x1e29, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018,\n\t0xbfc: 0x1e7a, 0xbfd: 0x0018, 0xbfe: 0x07b6, 0xbff: 0x0018,\n\t// Block 0x30, offset 0xc00\n\t0xc00: 0x0018, 0xc01: 0x0018, 0xc02: 0x0018, 0xc03: 0x0018, 0xc04: 0x0018, 0xc05: 0x0018,\n\t0xc06: 0x0018, 0xc07: 0x1e92, 0xc08: 0x1eaa, 0xc09: 0x1ec2, 0xc0a: 0x0018, 0xc0b: 0x0018,\n\t0xc0c: 0x0018, 0xc0d: 0x0018, 0xc0e: 0x0018, 0xc0f: 0x0018, 0xc10: 0x0018, 0xc11: 0x0018,\n\t0xc12: 0x0018, 0xc13: 0x0018, 0xc14: 0x0018, 0xc15: 0x0018, 0xc16: 0x0018, 0xc17: 0x1ed9,\n\t0xc18: 0x0018, 0xc19: 0x0018, 0xc1a: 0x0018, 0xc1b: 0x0018, 0xc1c: 0x0018, 0xc1d: 0x0018,\n\t0xc1e: 0x0018, 0xc1f: 0x000a, 0xc20: 0x03c0, 0xc21: 0x0340, 0xc22: 0x0340, 0xc23: 0x0340,\n\t0xc24: 0x03c0, 0xc25: 0x0040, 0xc26: 0x0040, 0xc27: 0x0040, 0xc28: 0x0040, 0xc29: 0x0040,\n\t0xc2a: 0x0340, 0xc2b: 0x0340, 0xc2c: 0x0340, 0xc2d: 0x0340, 0xc2e: 0x0340, 0xc2f: 0x0340,\n\t0xc30: 0x1f41, 0xc31: 0x0f41, 0xc32: 0x0040, 0xc33: 0x0040, 0xc34: 0x1f51, 0xc35: 0x1f61,\n\t0xc36: 0x1f71, 0xc37: 0x1f81, 0xc38: 0x1f91, 0xc39: 0x1fa1, 0xc3a: 0x1fb2, 0xc3b: 0x07d5,\n\t0xc3c: 0x1fc2, 0xc3d: 0x1fd2, 0xc3e: 0x1fe2, 0xc3f: 0x0f71,\n\t// Block 0x31, offset 0xc40\n\t0xc40: 0x1f41, 0xc41: 0x00c9, 0xc42: 0x0069, 0xc43: 0x0079, 0xc44: 0x1f51, 0xc45: 0x1f61,\n\t0xc46: 0x1f71, 0xc47: 0x1f81, 0xc48: 0x1f91, 0xc49: 0x1fa1, 0xc4a: 0x1fb2, 0xc4b: 0x07ed,\n\t0xc4c: 0x1fc2, 0xc4d: 0x1fd2, 0xc4e: 0x1fe2, 0xc4f: 0x0040, 0xc50: 0x0039, 0xc51: 0x0f09,\n\t0xc52: 0x00d9, 0xc53: 0x0369, 0xc54: 0x0ff9, 0xc55: 0x0249, 0xc56: 0x0f51, 0xc57: 0x0359,\n\t0xc58: 0x0f61, 0xc59: 0x0f71, 0xc5a: 0x0f99, 0xc5b: 0x01d9, 0xc5c: 0x0fa9, 0xc5d: 0x0040,\n\t0xc5e: 0x0040, 0xc5f: 0x0040, 0xc60: 0x0018, 0xc61: 0x0018, 0xc62: 0x0018, 0xc63: 0x0018,\n\t0xc64: 0x0018, 0xc65: 0x0018, 0xc66: 0x0018, 0xc67: 0x0018, 0xc68: 0x1ff1, 0xc69: 0x0018,\n\t0xc6a: 0x0018, 0xc6b: 0x0018, 0xc6c: 0x0018, 0xc6d: 0x0018, 0xc6e: 0x0018, 0xc6f: 0x0018,\n\t0xc70: 0x0018, 0xc71: 0x0018, 0xc72: 0x0018, 0xc73: 0x0018, 0xc74: 0x0018, 0xc75: 0x0018,\n\t0xc76: 0x0018, 0xc77: 0x0018, 0xc78: 0x0018, 0xc79: 0x0018, 0xc7a: 0x0018, 0xc7b: 0x0018,\n\t0xc7c: 0x0018, 0xc7d: 0x0018, 0xc7e: 0x0018, 0xc7f: 0x0018,\n\t// Block 0x32, offset 0xc80\n\t0xc80: 0x0806, 0xc81: 0x0826, 0xc82: 0x1159, 0xc83: 0x0845, 0xc84: 0x0018, 0xc85: 0x0866,\n\t0xc86: 0x0886, 0xc87: 0x1011, 0xc88: 0x0018, 0xc89: 0x08a5, 0xc8a: 0x0f31, 0xc8b: 0x0249,\n\t0xc8c: 0x0249, 0xc8d: 0x0249, 0xc8e: 0x0249, 0xc8f: 0x2009, 0xc90: 0x0f41, 0xc91: 0x0f41,\n\t0xc92: 0x0359, 0xc93: 0x0359, 0xc94: 0x0018, 0xc95: 0x0f71, 0xc96: 0x2021, 0xc97: 0x0018,\n\t0xc98: 0x0018, 0xc99: 0x0f99, 0xc9a: 0x2039, 0xc9b: 0x0269, 0xc9c: 0x0269, 0xc9d: 0x0269,\n\t0xc9e: 0x0018, 0xc9f: 0x0018, 0xca0: 0x2049, 0xca1: 0x08c5, 0xca2: 0x2061, 0xca3: 0x0018,\n\t0xca4: 0x13d1, 0xca5: 0x0018, 0xca6: 0x2079, 0xca7: 0x0018, 0xca8: 0x13d1, 0xca9: 0x0018,\n\t0xcaa: 0x0f51, 0xcab: 0x2091, 0xcac: 0x0ee9, 0xcad: 0x1159, 0xcae: 0x0018, 0xcaf: 0x0f09,\n\t0xcb0: 0x0f09, 0xcb1: 0x1199, 0xcb2: 0x0040, 0xcb3: 0x0f61, 0xcb4: 0x00d9, 0xcb5: 0x20a9,\n\t0xcb6: 0x20c1, 0xcb7: 0x20d9, 0xcb8: 0x20f1, 0xcb9: 0x0f41, 0xcba: 0x0018, 0xcbb: 0x08e5,\n\t0xcbc: 0x2109, 0xcbd: 0x10b1, 0xcbe: 0x10b1, 0xcbf: 0x2109,\n\t// Block 0x33, offset 0xcc0\n\t0xcc0: 0x0905, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x0ef9,\n\t0xcc6: 0x0ef9, 0xcc7: 0x0f09, 0xcc8: 0x0f41, 0xcc9: 0x0259, 0xcca: 0x0018, 0xccb: 0x0018,\n\t0xccc: 0x0018, 0xccd: 0x0018, 0xcce: 0x0008, 0xccf: 0x0018, 0xcd0: 0x2121, 0xcd1: 0x2151,\n\t0xcd2: 0x2181, 0xcd3: 0x21b9, 0xcd4: 0x21e9, 0xcd5: 0x2219, 0xcd6: 0x2249, 0xcd7: 0x2279,\n\t0xcd8: 0x22a9, 0xcd9: 0x22d9, 0xcda: 0x2309, 0xcdb: 0x2339, 0xcdc: 0x2369, 0xcdd: 0x2399,\n\t0xcde: 0x23c9, 0xcdf: 0x23f9, 0xce0: 0x0f41, 0xce1: 0x2421, 0xce2: 0x091d, 0xce3: 0x2439,\n\t0xce4: 0x1089, 0xce5: 0x2451, 0xce6: 0x093d, 0xce7: 0x2469, 0xce8: 0x2491, 0xce9: 0x0369,\n\t0xcea: 0x24a9, 0xceb: 0x095d, 0xcec: 0x0359, 0xced: 0x1159, 0xcee: 0x0ef9, 0xcef: 0x0f61,\n\t0xcf0: 0x0f41, 0xcf1: 0x2421, 0xcf2: 0x097d, 0xcf3: 0x2439, 0xcf4: 0x1089, 0xcf5: 0x2451,\n\t0xcf6: 0x099d, 0xcf7: 0x2469, 0xcf8: 0x2491, 0xcf9: 0x0369, 0xcfa: 0x24a9, 0xcfb: 0x09bd,\n\t0xcfc: 0x0359, 0xcfd: 0x1159, 0xcfe: 0x0ef9, 0xcff: 0x0f61,\n\t// Block 0x34, offset 0xd00\n\t0xd00: 0x0018, 0xd01: 0x0018, 0xd02: 0x0018, 0xd03: 0x0018, 0xd04: 0x0018, 0xd05: 0x0018,\n\t0xd06: 0x0018, 0xd07: 0x0018, 0xd08: 0x0018, 0xd09: 0x0018, 0xd0a: 0x0018, 0xd0b: 0x0040,\n\t0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040,\n\t0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040,\n\t0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0040, 0xd1d: 0x0040,\n\t0xd1e: 0x0040, 0xd1f: 0x0040, 0xd20: 0x00c9, 0xd21: 0x0069, 0xd22: 0x0079, 0xd23: 0x1f51,\n\t0xd24: 0x1f61, 0xd25: 0x1f71, 0xd26: 0x1f81, 0xd27: 0x1f91, 0xd28: 0x1fa1, 0xd29: 0x2601,\n\t0xd2a: 0x2619, 0xd2b: 0x2631, 0xd2c: 0x2649, 0xd2d: 0x2661, 0xd2e: 0x2679, 0xd2f: 0x2691,\n\t0xd30: 0x26a9, 0xd31: 0x26c1, 0xd32: 0x26d9, 0xd33: 0x26f1, 0xd34: 0x0a1e, 0xd35: 0x0a3e,\n\t0xd36: 0x0a5e, 0xd37: 0x0a7e, 0xd38: 0x0a9e, 0xd39: 0x0abe, 0xd3a: 0x0ade, 0xd3b: 0x0afe,\n\t0xd3c: 0x0b1e, 0xd3d: 0x270a, 0xd3e: 0x2732, 0xd3f: 0x275a,\n\t// Block 0x35, offset 0xd40\n\t0xd40: 0x2782, 0xd41: 0x27aa, 0xd42: 0x27d2, 0xd43: 0x27fa, 0xd44: 0x2822, 0xd45: 0x284a,\n\t0xd46: 0x2872, 0xd47: 0x289a, 0xd48: 0x0040, 0xd49: 0x0040, 0xd4a: 0x0040, 0xd4b: 0x0040,\n\t0xd4c: 0x0040, 0xd4d: 0x0040, 0xd4e: 0x0040, 0xd4f: 0x0040, 0xd50: 0x0040, 0xd51: 0x0040,\n\t0xd52: 0x0040, 0xd53: 0x0040, 0xd54: 0x0040, 0xd55: 0x0040, 0xd56: 0x0040, 0xd57: 0x0040,\n\t0xd58: 0x0040, 0xd59: 0x0040, 0xd5a: 0x0040, 0xd5b: 0x0040, 0xd5c: 0x0b3e, 0xd5d: 0x0b5e,\n\t0xd5e: 0x0b7e, 0xd5f: 0x0b9e, 0xd60: 0x0bbe, 0xd61: 0x0bde, 0xd62: 0x0bfe, 0xd63: 0x0c1e,\n\t0xd64: 0x0c3e, 0xd65: 0x0c5e, 0xd66: 0x0c7e, 0xd67: 0x0c9e, 0xd68: 0x0cbe, 0xd69: 0x0cde,\n\t0xd6a: 0x0cfe, 0xd6b: 0x0d1e, 0xd6c: 0x0d3e, 0xd6d: 0x0d5e, 0xd6e: 0x0d7e, 0xd6f: 0x0d9e,\n\t0xd70: 0x0dbe, 0xd71: 0x0dde, 0xd72: 0x0dfe, 0xd73: 0x0e1e, 0xd74: 0x0e3e, 0xd75: 0x0e5e,\n\t0xd76: 0x0039, 0xd77: 0x0ee9, 0xd78: 0x1159, 0xd79: 0x0ef9, 0xd7a: 0x0f09, 0xd7b: 0x1199,\n\t0xd7c: 0x0f31, 0xd7d: 0x0249, 0xd7e: 0x0f41, 0xd7f: 0x0259,\n\t// Block 0x36, offset 0xd80\n\t0xd80: 0x0f51, 0xd81: 0x0359, 0xd82: 0x0f61, 0xd83: 0x0f71, 0xd84: 0x00d9, 0xd85: 0x0f99,\n\t0xd86: 0x2039, 0xd87: 0x0269, 0xd88: 0x01d9, 0xd89: 0x0fa9, 0xd8a: 0x0fb9, 0xd8b: 0x1089,\n\t0xd8c: 0x0279, 0xd8d: 0x0369, 0xd8e: 0x0289, 0xd8f: 0x13d1, 0xd90: 0x0039, 0xd91: 0x0ee9,\n\t0xd92: 0x1159, 0xd93: 0x0ef9, 0xd94: 0x0f09, 0xd95: 0x1199, 0xd96: 0x0f31, 0xd97: 0x0249,\n\t0xd98: 0x0f41, 0xd99: 0x0259, 0xd9a: 0x0f51, 0xd9b: 0x0359, 0xd9c: 0x0f61, 0xd9d: 0x0f71,\n\t0xd9e: 0x00d9, 0xd9f: 0x0f99, 0xda0: 0x2039, 0xda1: 0x0269, 0xda2: 0x01d9, 0xda3: 0x0fa9,\n\t0xda4: 0x0fb9, 0xda5: 0x1089, 0xda6: 0x0279, 0xda7: 0x0369, 0xda8: 0x0289, 0xda9: 0x13d1,\n\t0xdaa: 0x1f41, 0xdab: 0x0018, 0xdac: 0x0018, 0xdad: 0x0018, 0xdae: 0x0018, 0xdaf: 0x0018,\n\t0xdb0: 0x0018, 0xdb1: 0x0018, 0xdb2: 0x0018, 0xdb3: 0x0018, 0xdb4: 0x0018, 0xdb5: 0x0018,\n\t0xdb6: 0x0018, 0xdb7: 0x0018, 0xdb8: 0x0018, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018,\n\t0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018,\n\t// Block 0x37, offset 0xdc0\n\t0xdc0: 0x0008, 0xdc1: 0x0008, 0xdc2: 0x0008, 0xdc3: 0x0008, 0xdc4: 0x0008, 0xdc5: 0x0008,\n\t0xdc6: 0x0008, 0xdc7: 0x0008, 0xdc8: 0x0008, 0xdc9: 0x0008, 0xdca: 0x0008, 0xdcb: 0x0008,\n\t0xdcc: 0x0008, 0xdcd: 0x0008, 0xdce: 0x0008, 0xdcf: 0x0008, 0xdd0: 0x0008, 0xdd1: 0x0008,\n\t0xdd2: 0x0008, 0xdd3: 0x0008, 0xdd4: 0x0008, 0xdd5: 0x0008, 0xdd6: 0x0008, 0xdd7: 0x0008,\n\t0xdd8: 0x0008, 0xdd9: 0x0008, 0xdda: 0x0008, 0xddb: 0x0008, 0xddc: 0x0008, 0xddd: 0x0008,\n\t0xdde: 0x0008, 0xddf: 0x0040, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0x2971, 0xde3: 0x0ed5,\n\t0xde4: 0x2989, 0xde5: 0x0008, 0xde6: 0x0008, 0xde7: 0xe07d, 0xde8: 0x0008, 0xde9: 0xe01d,\n\t0xdea: 0x0008, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0x0fe1, 0xdee: 0x1281, 0xdef: 0x0fc9,\n\t0xdf0: 0x1141, 0xdf1: 0x0008, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0008, 0xdf5: 0xe01d,\n\t0xdf6: 0x0008, 0xdf7: 0x0008, 0xdf8: 0x0008, 0xdf9: 0x0008, 0xdfa: 0x0008, 0xdfb: 0x0008,\n\t0xdfc: 0x0259, 0xdfd: 0x1089, 0xdfe: 0x29a1, 0xdff: 0x29b9,\n\t// Block 0x38, offset 0xe00\n\t0xe00: 0xe00d, 0xe01: 0x0008, 0xe02: 0xe00d, 0xe03: 0x0008, 0xe04: 0xe00d, 0xe05: 0x0008,\n\t0xe06: 0xe00d, 0xe07: 0x0008, 0xe08: 0xe00d, 0xe09: 0x0008, 0xe0a: 0xe00d, 0xe0b: 0x0008,\n\t0xe0c: 0xe00d, 0xe0d: 0x0008, 0xe0e: 0xe00d, 0xe0f: 0x0008, 0xe10: 0xe00d, 0xe11: 0x0008,\n\t0xe12: 0xe00d, 0xe13: 0x0008, 0xe14: 0xe00d, 0xe15: 0x0008, 0xe16: 0xe00d, 0xe17: 0x0008,\n\t0xe18: 0xe00d, 0xe19: 0x0008, 0xe1a: 0xe00d, 0xe1b: 0x0008, 0xe1c: 0xe00d, 0xe1d: 0x0008,\n\t0xe1e: 0xe00d, 0xe1f: 0x0008, 0xe20: 0xe00d, 0xe21: 0x0008, 0xe22: 0xe00d, 0xe23: 0x0008,\n\t0xe24: 0x0008, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018,\n\t0xe2a: 0x0018, 0xe2b: 0xe03d, 0xe2c: 0x0008, 0xe2d: 0xe01d, 0xe2e: 0x0008, 0xe2f: 0x3308,\n\t0xe30: 0x3308, 0xe31: 0x3308, 0xe32: 0xe00d, 0xe33: 0x0008, 0xe34: 0x0040, 0xe35: 0x0040,\n\t0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0018, 0xe3a: 0x0018, 0xe3b: 0x0018,\n\t0xe3c: 0x0018, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018,\n\t// Block 0x39, offset 0xe40\n\t0xe40: 0x2715, 0xe41: 0x2735, 0xe42: 0x2755, 0xe43: 0x2775, 0xe44: 0x2795, 0xe45: 0x27b5,\n\t0xe46: 0x27d5, 0xe47: 0x27f5, 0xe48: 0x2815, 0xe49: 0x2835, 0xe4a: 0x2855, 0xe4b: 0x2875,\n\t0xe4c: 0x2895, 0xe4d: 0x28b5, 0xe4e: 0x28d5, 0xe4f: 0x28f5, 0xe50: 0x2915, 0xe51: 0x2935,\n\t0xe52: 0x2955, 0xe53: 0x2975, 0xe54: 0x2995, 0xe55: 0x29b5, 0xe56: 0x0040, 0xe57: 0x0040,\n\t0xe58: 0x0040, 0xe59: 0x0040, 0xe5a: 0x0040, 0xe5b: 0x0040, 0xe5c: 0x0040, 0xe5d: 0x0040,\n\t0xe5e: 0x0040, 0xe5f: 0x0040, 0xe60: 0x0040, 0xe61: 0x0040, 0xe62: 0x0040, 0xe63: 0x0040,\n\t0xe64: 0x0040, 0xe65: 0x0040, 0xe66: 0x0040, 0xe67: 0x0040, 0xe68: 0x0040, 0xe69: 0x0040,\n\t0xe6a: 0x0040, 0xe6b: 0x0040, 0xe6c: 0x0040, 0xe6d: 0x0040, 0xe6e: 0x0040, 0xe6f: 0x0040,\n\t0xe70: 0x0040, 0xe71: 0x0040, 0xe72: 0x0040, 0xe73: 0x0040, 0xe74: 0x0040, 0xe75: 0x0040,\n\t0xe76: 0x0040, 0xe77: 0x0040, 0xe78: 0x0040, 0xe79: 0x0040, 0xe7a: 0x0040, 0xe7b: 0x0040,\n\t0xe7c: 0x0040, 0xe7d: 0x0040, 0xe7e: 0x0040, 0xe7f: 0x0040,\n\t// Block 0x3a, offset 0xe80\n\t0xe80: 0x000a, 0xe81: 0x0018, 0xe82: 0x29d1, 0xe83: 0x0018, 0xe84: 0x0018, 0xe85: 0x0008,\n\t0xe86: 0x0008, 0xe87: 0x0008, 0xe88: 0x0018, 0xe89: 0x0018, 0xe8a: 0x0018, 0xe8b: 0x0018,\n\t0xe8c: 0x0018, 0xe8d: 0x0018, 0xe8e: 0x0018, 0xe8f: 0x0018, 0xe90: 0x0018, 0xe91: 0x0018,\n\t0xe92: 0x0018, 0xe93: 0x0018, 0xe94: 0x0018, 0xe95: 0x0018, 0xe96: 0x0018, 0xe97: 0x0018,\n\t0xe98: 0x0018, 0xe99: 0x0018, 0xe9a: 0x0018, 0xe9b: 0x0018, 0xe9c: 0x0018, 0xe9d: 0x0018,\n\t0xe9e: 0x0018, 0xe9f: 0x0018, 0xea0: 0x0018, 0xea1: 0x0018, 0xea2: 0x0018, 0xea3: 0x0018,\n\t0xea4: 0x0018, 0xea5: 0x0018, 0xea6: 0x0018, 0xea7: 0x0018, 0xea8: 0x0018, 0xea9: 0x0018,\n\t0xeaa: 0x3308, 0xeab: 0x3308, 0xeac: 0x3308, 0xead: 0x3308, 0xeae: 0x3018, 0xeaf: 0x3018,\n\t0xeb0: 0x0018, 0xeb1: 0x0018, 0xeb2: 0x0018, 0xeb3: 0x0018, 0xeb4: 0x0018, 0xeb5: 0x0018,\n\t0xeb6: 0xe125, 0xeb7: 0x0018, 0xeb8: 0x29d5, 0xeb9: 0x29f5, 0xeba: 0x2a15, 0xebb: 0x0018,\n\t0xebc: 0x0008, 0xebd: 0x0018, 0xebe: 0x0018, 0xebf: 0x0018,\n\t// Block 0x3b, offset 0xec0\n\t0xec0: 0x2b55, 0xec1: 0x2b75, 0xec2: 0x2b95, 0xec3: 0x2bb5, 0xec4: 0x2bd5, 0xec5: 0x2bf5,\n\t0xec6: 0x2bf5, 0xec7: 0x2bf5, 0xec8: 0x2c15, 0xec9: 0x2c15, 0xeca: 0x2c15, 0xecb: 0x2c15,\n\t0xecc: 0x2c35, 0xecd: 0x2c35, 0xece: 0x2c35, 0xecf: 0x2c55, 0xed0: 0x2c75, 0xed1: 0x2c75,\n\t0xed2: 0x2a95, 0xed3: 0x2a95, 0xed4: 0x2c75, 0xed5: 0x2c75, 0xed6: 0x2c95, 0xed7: 0x2c95,\n\t0xed8: 0x2c75, 0xed9: 0x2c75, 0xeda: 0x2a95, 0xedb: 0x2a95, 0xedc: 0x2c75, 0xedd: 0x2c75,\n\t0xede: 0x2c55, 0xedf: 0x2c55, 0xee0: 0x2cb5, 0xee1: 0x2cb5, 0xee2: 0x2cd5, 0xee3: 0x2cd5,\n\t0xee4: 0x0040, 0xee5: 0x2cf5, 0xee6: 0x2d15, 0xee7: 0x2d35, 0xee8: 0x2d35, 0xee9: 0x2d55,\n\t0xeea: 0x2d75, 0xeeb: 0x2d95, 0xeec: 0x2db5, 0xeed: 0x2dd5, 0xeee: 0x2df5, 0xeef: 0x2e15,\n\t0xef0: 0x2e35, 0xef1: 0x2e55, 0xef2: 0x2e55, 0xef3: 0x2e75, 0xef4: 0x2e95, 0xef5: 0x2e95,\n\t0xef6: 0x2eb5, 0xef7: 0x2ed5, 0xef8: 0x2e75, 0xef9: 0x2ef5, 0xefa: 0x2f15, 0xefb: 0x2ef5,\n\t0xefc: 0x2e75, 0xefd: 0x2f35, 0xefe: 0x2f55, 0xeff: 0x2f75,\n\t// Block 0x3c, offset 0xf00\n\t0xf00: 0x2f95, 0xf01: 0x2fb5, 0xf02: 0x2d15, 0xf03: 0x2cf5, 0xf04: 0x2fd5, 0xf05: 0x2ff5,\n\t0xf06: 0x3015, 0xf07: 0x3035, 0xf08: 0x3055, 0xf09: 0x3075, 0xf0a: 0x3095, 0xf0b: 0x30b5,\n\t0xf0c: 0x30d5, 0xf0d: 0x30f5, 0xf0e: 0x3115, 0xf0f: 0x0040, 0xf10: 0x0018, 0xf11: 0x0018,\n\t0xf12: 0x3135, 0xf13: 0x3155, 0xf14: 0x3175, 0xf15: 0x3195, 0xf16: 0x31b5, 0xf17: 0x31d5,\n\t0xf18: 0x31f5, 0xf19: 0x3215, 0xf1a: 0x3235, 0xf1b: 0x3255, 0xf1c: 0x3175, 0xf1d: 0x3275,\n\t0xf1e: 0x3295, 0xf1f: 0x32b5, 0xf20: 0x0008, 0xf21: 0x0008, 0xf22: 0x0008, 0xf23: 0x0008,\n\t0xf24: 0x0008, 0xf25: 0x0008, 0xf26: 0x0008, 0xf27: 0x0008, 0xf28: 0x0008, 0xf29: 0x0008,\n\t0xf2a: 0x0008, 0xf2b: 0x0008, 0xf2c: 0x0008, 0xf2d: 0x0008, 0xf2e: 0x0008, 0xf2f: 0x0008,\n\t0xf30: 0x0008, 0xf31: 0x0008, 0xf32: 0x0008, 0xf33: 0x0008, 0xf34: 0x0008, 0xf35: 0x0008,\n\t0xf36: 0x0008, 0xf37: 0x0008, 0xf38: 0x0008, 0xf39: 0x0008, 0xf3a: 0x0008, 0xf3b: 0x0040,\n\t0xf3c: 0x0040, 0xf3d: 0x0040, 0xf3e: 0x0040, 0xf3f: 0x0040,\n\t// Block 0x3d, offset 0xf40\n\t0xf40: 0x36a2, 0xf41: 0x36d2, 0xf42: 0x3702, 0xf43: 0x3732, 0xf44: 0x32d5, 0xf45: 0x32f5,\n\t0xf46: 0x3315, 0xf47: 0x3335, 0xf48: 0x0018, 0xf49: 0x0018, 0xf4a: 0x0018, 0xf4b: 0x0018,\n\t0xf4c: 0x0018, 0xf4d: 0x0018, 0xf4e: 0x0018, 0xf4f: 0x0018, 0xf50: 0x3355, 0xf51: 0x3761,\n\t0xf52: 0x3779, 0xf53: 0x3791, 0xf54: 0x37a9, 0xf55: 0x37c1, 0xf56: 0x37d9, 0xf57: 0x37f1,\n\t0xf58: 0x3809, 0xf59: 0x3821, 0xf5a: 0x3839, 0xf5b: 0x3851, 0xf5c: 0x3869, 0xf5d: 0x3881,\n\t0xf5e: 0x3899, 0xf5f: 0x38b1, 0xf60: 0x3375, 0xf61: 0x3395, 0xf62: 0x33b5, 0xf63: 0x33d5,\n\t0xf64: 0x33f5, 0xf65: 0x33f5, 0xf66: 0x3415, 0xf67: 0x3435, 0xf68: 0x3455, 0xf69: 0x3475,\n\t0xf6a: 0x3495, 0xf6b: 0x34b5, 0xf6c: 0x34d5, 0xf6d: 0x34f5, 0xf6e: 0x3515, 0xf6f: 0x3535,\n\t0xf70: 0x3555, 0xf71: 0x3575, 0xf72: 0x3595, 0xf73: 0x35b5, 0xf74: 0x35d5, 0xf75: 0x35f5,\n\t0xf76: 0x3615, 0xf77: 0x3635, 0xf78: 0x3655, 0xf79: 0x3675, 0xf7a: 0x3695, 0xf7b: 0x36b5,\n\t0xf7c: 0x38c9, 0xf7d: 0x3901, 0xf7e: 0x36d5, 0xf7f: 0x0018,\n\t// Block 0x3e, offset 0xf80\n\t0xf80: 0x36f5, 0xf81: 0x3715, 0xf82: 0x3735, 0xf83: 0x3755, 0xf84: 0x3775, 0xf85: 0x3795,\n\t0xf86: 0x37b5, 0xf87: 0x37d5, 0xf88: 0x37f5, 0xf89: 0x3815, 0xf8a: 0x3835, 0xf8b: 0x3855,\n\t0xf8c: 0x3875, 0xf8d: 0x3895, 0xf8e: 0x38b5, 0xf8f: 0x38d5, 0xf90: 0x38f5, 0xf91: 0x3915,\n\t0xf92: 0x3935, 0xf93: 0x3955, 0xf94: 0x3975, 0xf95: 0x3995, 0xf96: 0x39b5, 0xf97: 0x39d5,\n\t0xf98: 0x39f5, 0xf99: 0x3a15, 0xf9a: 0x3a35, 0xf9b: 0x3a55, 0xf9c: 0x3a75, 0xf9d: 0x3a95,\n\t0xf9e: 0x3ab5, 0xf9f: 0x3ad5, 0xfa0: 0x3af5, 0xfa1: 0x3b15, 0xfa2: 0x3b35, 0xfa3: 0x3b55,\n\t0xfa4: 0x3b75, 0xfa5: 0x3b95, 0xfa6: 0x1295, 0xfa7: 0x3bb5, 0xfa8: 0x3bd5, 0xfa9: 0x3bf5,\n\t0xfaa: 0x3c15, 0xfab: 0x3c35, 0xfac: 0x3c55, 0xfad: 0x3c75, 0xfae: 0x23b5, 0xfaf: 0x3c95,\n\t0xfb0: 0x3cb5, 0xfb1: 0x3939, 0xfb2: 0x3951, 0xfb3: 0x3969, 0xfb4: 0x3981, 0xfb5: 0x3999,\n\t0xfb6: 0x39b1, 0xfb7: 0x39c9, 0xfb8: 0x39e1, 0xfb9: 0x39f9, 0xfba: 0x3a11, 0xfbb: 0x3a29,\n\t0xfbc: 0x3a41, 0xfbd: 0x3a59, 0xfbe: 0x3a71, 0xfbf: 0x3a89,\n\t// Block 0x3f, offset 0xfc0\n\t0xfc0: 0x3aa1, 0xfc1: 0x3ac9, 0xfc2: 0x3af1, 0xfc3: 0x3b19, 0xfc4: 0x3b41, 0xfc5: 0x3b69,\n\t0xfc6: 0x3b91, 0xfc7: 0x3bb9, 0xfc8: 0x3be1, 0xfc9: 0x3c09, 0xfca: 0x3c39, 0xfcb: 0x3c69,\n\t0xfcc: 0x3c99, 0xfcd: 0x3cd5, 0xfce: 0x3cb1, 0xfcf: 0x3cf5, 0xfd0: 0x3d15, 0xfd1: 0x3d2d,\n\t0xfd2: 0x3d45, 0xfd3: 0x3d5d, 0xfd4: 0x3d75, 0xfd5: 0x3d75, 0xfd6: 0x3d5d, 0xfd7: 0x3d8d,\n\t0xfd8: 0x07d5, 0xfd9: 0x3da5, 0xfda: 0x3dbd, 0xfdb: 0x3dd5, 0xfdc: 0x3ded, 0xfdd: 0x3e05,\n\t0xfde: 0x3e1d, 0xfdf: 0x3e35, 0xfe0: 0x3e4d, 0xfe1: 0x3e65, 0xfe2: 0x3e7d, 0xfe3: 0x3e95,\n\t0xfe4: 0x3ead, 0xfe5: 0x3ead, 0xfe6: 0x3ec5, 0xfe7: 0x3ec5, 0xfe8: 0x3edd, 0xfe9: 0x3edd,\n\t0xfea: 0x3ef5, 0xfeb: 0x3f0d, 0xfec: 0x3f25, 0xfed: 0x3f3d, 0xfee: 0x3f55, 0xfef: 0x3f55,\n\t0xff0: 0x3f6d, 0xff1: 0x3f6d, 0xff2: 0x3f6d, 0xff3: 0x3f85, 0xff4: 0x3f9d, 0xff5: 0x3fb5,\n\t0xff6: 0x3fcd, 0xff7: 0x3fb5, 0xff8: 0x3fe5, 0xff9: 0x3ffd, 0xffa: 0x3f85, 0xffb: 0x4015,\n\t0xffc: 0x402d, 0xffd: 0x402d, 0xffe: 0x402d, 0xfff: 0x0040,\n\t// Block 0x40, offset 0x1000\n\t0x1000: 0x3cc9, 0x1001: 0x3d31, 0x1002: 0x3d99, 0x1003: 0x3e01, 0x1004: 0x3e51, 0x1005: 0x3eb9,\n\t0x1006: 0x3f09, 0x1007: 0x3f59, 0x1008: 0x3fd9, 0x1009: 0x4041, 0x100a: 0x4091, 0x100b: 0x40e1,\n\t0x100c: 0x4131, 0x100d: 0x4199, 0x100e: 0x4201, 0x100f: 0x4251, 0x1010: 0x42a1, 0x1011: 0x42d9,\n\t0x1012: 0x4329, 0x1013: 0x4391, 0x1014: 0x43f9, 0x1015: 0x4431, 0x1016: 0x44b1, 0x1017: 0x4549,\n\t0x1018: 0x45c9, 0x1019: 0x4619, 0x101a: 0x4699, 0x101b: 0x4719, 0x101c: 0x4781, 0x101d: 0x47d1,\n\t0x101e: 0x4821, 0x101f: 0x4871, 0x1020: 0x48d9, 0x1021: 0x4959, 0x1022: 0x49c1, 0x1023: 0x4a11,\n\t0x1024: 0x4a61, 0x1025: 0x4ab1, 0x1026: 0x4ae9, 0x1027: 0x4b21, 0x1028: 0x4b59, 0x1029: 0x4b91,\n\t0x102a: 0x4be1, 0x102b: 0x4c31, 0x102c: 0x4cb1, 0x102d: 0x4d01, 0x102e: 0x4d69, 0x102f: 0x4de9,\n\t0x1030: 0x4e39, 0x1031: 0x4e71, 0x1032: 0x4ea9, 0x1033: 0x4f29, 0x1034: 0x4f91, 0x1035: 0x5011,\n\t0x1036: 0x5061, 0x1037: 0x50e1, 0x1038: 0x5119, 0x1039: 0x5169, 0x103a: 0x51b9, 0x103b: 0x5209,\n\t0x103c: 0x5259, 0x103d: 0x52a9, 0x103e: 0x5311, 0x103f: 0x5361,\n\t// Block 0x41, offset 0x1040\n\t0x1040: 0x5399, 0x1041: 0x53e9, 0x1042: 0x5439, 0x1043: 0x5489, 0x1044: 0x54f1, 0x1045: 0x5541,\n\t0x1046: 0x5591, 0x1047: 0x55e1, 0x1048: 0x5661, 0x1049: 0x56c9, 0x104a: 0x5701, 0x104b: 0x5781,\n\t0x104c: 0x57b9, 0x104d: 0x5821, 0x104e: 0x5889, 0x104f: 0x58d9, 0x1050: 0x5929, 0x1051: 0x5979,\n\t0x1052: 0x59e1, 0x1053: 0x5a19, 0x1054: 0x5a69, 0x1055: 0x5ad1, 0x1056: 0x5b09, 0x1057: 0x5b89,\n\t0x1058: 0x5bd9, 0x1059: 0x5c01, 0x105a: 0x5c29, 0x105b: 0x5c51, 0x105c: 0x5c79, 0x105d: 0x5ca1,\n\t0x105e: 0x5cc9, 0x105f: 0x5cf1, 0x1060: 0x5d19, 0x1061: 0x5d41, 0x1062: 0x5d69, 0x1063: 0x5d99,\n\t0x1064: 0x5dc9, 0x1065: 0x5df9, 0x1066: 0x5e29, 0x1067: 0x5e59, 0x1068: 0x5e89, 0x1069: 0x5eb9,\n\t0x106a: 0x5ee9, 0x106b: 0x5f19, 0x106c: 0x5f49, 0x106d: 0x5f79, 0x106e: 0x5fa9, 0x106f: 0x5fd9,\n\t0x1070: 0x6009, 0x1071: 0x4045, 0x1072: 0x6039, 0x1073: 0x6051, 0x1074: 0x4065, 0x1075: 0x6069,\n\t0x1076: 0x6081, 0x1077: 0x6099, 0x1078: 0x4085, 0x1079: 0x4085, 0x107a: 0x60b1, 0x107b: 0x60c9,\n\t0x107c: 0x6101, 0x107d: 0x6139, 0x107e: 0x6171, 0x107f: 0x61a9,\n\t// Block 0x42, offset 0x1080\n\t0x1080: 0x6211, 0x1081: 0x6229, 0x1082: 0x40a5, 0x1083: 0x6241, 0x1084: 0x6259, 0x1085: 0x6271,\n\t0x1086: 0x6289, 0x1087: 0x62a1, 0x1088: 0x40c5, 0x1089: 0x62b9, 0x108a: 0x62e1, 0x108b: 0x62f9,\n\t0x108c: 0x40e5, 0x108d: 0x40e5, 0x108e: 0x6311, 0x108f: 0x6329, 0x1090: 0x6341, 0x1091: 0x4105,\n\t0x1092: 0x4125, 0x1093: 0x4145, 0x1094: 0x4165, 0x1095: 0x4185, 0x1096: 0x6359, 0x1097: 0x6371,\n\t0x1098: 0x6389, 0x1099: 0x63a1, 0x109a: 0x63b9, 0x109b: 0x41a5, 0x109c: 0x63d1, 0x109d: 0x63e9,\n\t0x109e: 0x6401, 0x109f: 0x41c5, 0x10a0: 0x41e5, 0x10a1: 0x6419, 0x10a2: 0x4205, 0x10a3: 0x4225,\n\t0x10a4: 0x4245, 0x10a5: 0x6431, 0x10a6: 0x4265, 0x10a7: 0x6449, 0x10a8: 0x6479, 0x10a9: 0x6211,\n\t0x10aa: 0x4285, 0x10ab: 0x42a5, 0x10ac: 0x42c5, 0x10ad: 0x42e5, 0x10ae: 0x64b1, 0x10af: 0x64f1,\n\t0x10b0: 0x6539, 0x10b1: 0x6551, 0x10b2: 0x4305, 0x10b3: 0x6569, 0x10b4: 0x6581, 0x10b5: 0x6599,\n\t0x10b6: 0x4325, 0x10b7: 0x65b1, 0x10b8: 0x65c9, 0x10b9: 0x65b1, 0x10ba: 0x65e1, 0x10bb: 0x65f9,\n\t0x10bc: 0x4345, 0x10bd: 0x6611, 0x10be: 0x6629, 0x10bf: 0x6611,\n\t// Block 0x43, offset 0x10c0\n\t0x10c0: 0x4365, 0x10c1: 0x4385, 0x10c2: 0x0040, 0x10c3: 0x6641, 0x10c4: 0x6659, 0x10c5: 0x6671,\n\t0x10c6: 0x6689, 0x10c7: 0x0040, 0x10c8: 0x66c1, 0x10c9: 0x66d9, 0x10ca: 0x66f1, 0x10cb: 0x6709,\n\t0x10cc: 0x6721, 0x10cd: 0x6739, 0x10ce: 0x6401, 0x10cf: 0x6751, 0x10d0: 0x6769, 0x10d1: 0x6781,\n\t0x10d2: 0x43a5, 0x10d3: 0x6799, 0x10d4: 0x6289, 0x10d5: 0x43c5, 0x10d6: 0x43e5, 0x10d7: 0x67b1,\n\t0x10d8: 0x0040, 0x10d9: 0x4405, 0x10da: 0x67c9, 0x10db: 0x67e1, 0x10dc: 0x67f9, 0x10dd: 0x6811,\n\t0x10de: 0x6829, 0x10df: 0x6859, 0x10e0: 0x6889, 0x10e1: 0x68b1, 0x10e2: 0x68d9, 0x10e3: 0x6901,\n\t0x10e4: 0x6929, 0x10e5: 0x6951, 0x10e6: 0x6979, 0x10e7: 0x69a1, 0x10e8: 0x69c9, 0x10e9: 0x69f1,\n\t0x10ea: 0x6a21, 0x10eb: 0x6a51, 0x10ec: 0x6a81, 0x10ed: 0x6ab1, 0x10ee: 0x6ae1, 0x10ef: 0x6b11,\n\t0x10f0: 0x6b41, 0x10f1: 0x6b71, 0x10f2: 0x6ba1, 0x10f3: 0x6bd1, 0x10f4: 0x6c01, 0x10f5: 0x6c31,\n\t0x10f6: 0x6c61, 0x10f7: 0x6c91, 0x10f8: 0x6cc1, 0x10f9: 0x6cf1, 0x10fa: 0x6d21, 0x10fb: 0x6d51,\n\t0x10fc: 0x6d81, 0x10fd: 0x6db1, 0x10fe: 0x6de1, 0x10ff: 0x4425,\n\t// Block 0x44, offset 0x1100\n\t0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008,\n\t0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008,\n\t0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008,\n\t0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008,\n\t0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0xe00d, 0x111d: 0x0008,\n\t0x111e: 0xe00d, 0x111f: 0x0008, 0x1120: 0xe00d, 0x1121: 0x0008, 0x1122: 0xe00d, 0x1123: 0x0008,\n\t0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008,\n\t0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x3308,\n\t0x1130: 0x3318, 0x1131: 0x3318, 0x1132: 0x3318, 0x1133: 0x0018, 0x1134: 0x3308, 0x1135: 0x3308,\n\t0x1136: 0x3308, 0x1137: 0x3308, 0x1138: 0x3308, 0x1139: 0x3308, 0x113a: 0x3308, 0x113b: 0x3308,\n\t0x113c: 0x3308, 0x113d: 0x3308, 0x113e: 0x0018, 0x113f: 0x0008,\n\t// Block 0x45, offset 0x1140\n\t0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008,\n\t0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008,\n\t0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008,\n\t0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008,\n\t0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0x0ea1, 0x115d: 0x6e11,\n\t0x115e: 0x3308, 0x115f: 0x3308, 0x1160: 0x0008, 0x1161: 0x0008, 0x1162: 0x0008, 0x1163: 0x0008,\n\t0x1164: 0x0008, 0x1165: 0x0008, 0x1166: 0x0008, 0x1167: 0x0008, 0x1168: 0x0008, 0x1169: 0x0008,\n\t0x116a: 0x0008, 0x116b: 0x0008, 0x116c: 0x0008, 0x116d: 0x0008, 0x116e: 0x0008, 0x116f: 0x0008,\n\t0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008,\n\t0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0x0008, 0x117a: 0x0008, 0x117b: 0x0008,\n\t0x117c: 0x0008, 0x117d: 0x0008, 0x117e: 0x0008, 0x117f: 0x0008,\n\t// Block 0x46, offset 0x1180\n\t0x1180: 0x0018, 0x1181: 0x0018, 0x1182: 0x0018, 0x1183: 0x0018, 0x1184: 0x0018, 0x1185: 0x0018,\n\t0x1186: 0x0018, 0x1187: 0x0018, 0x1188: 0x0018, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0x0018,\n\t0x118c: 0x0018, 0x118d: 0x0018, 0x118e: 0x0018, 0x118f: 0x0018, 0x1190: 0x0018, 0x1191: 0x0018,\n\t0x1192: 0x0018, 0x1193: 0x0018, 0x1194: 0x0018, 0x1195: 0x0018, 0x1196: 0x0018, 0x1197: 0x0008,\n\t0x1198: 0x0008, 0x1199: 0x0008, 0x119a: 0x0008, 0x119b: 0x0008, 0x119c: 0x0008, 0x119d: 0x0008,\n\t0x119e: 0x0008, 0x119f: 0x0008, 0x11a0: 0x0018, 0x11a1: 0x0018, 0x11a2: 0xe00d, 0x11a3: 0x0008,\n\t0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008,\n\t0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008,\n\t0x11b0: 0x0008, 0x11b1: 0x0008, 0x11b2: 0xe00d, 0x11b3: 0x0008, 0x11b4: 0xe00d, 0x11b5: 0x0008,\n\t0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0xe00d, 0x11b9: 0x0008, 0x11ba: 0xe00d, 0x11bb: 0x0008,\n\t0x11bc: 0xe00d, 0x11bd: 0x0008, 0x11be: 0xe00d, 0x11bf: 0x0008,\n\t// Block 0x47, offset 0x11c0\n\t0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008,\n\t0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0xe00d, 0x11c9: 0x0008, 0x11ca: 0xe00d, 0x11cb: 0x0008,\n\t0x11cc: 0xe00d, 0x11cd: 0x0008, 0x11ce: 0xe00d, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008,\n\t0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0xe00d, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008,\n\t0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008,\n\t0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008,\n\t0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008,\n\t0x11ea: 0xe00d, 0x11eb: 0x0008, 0x11ec: 0xe00d, 0x11ed: 0x0008, 0x11ee: 0xe00d, 0x11ef: 0x0008,\n\t0x11f0: 0xe0fd, 0x11f1: 0x0008, 0x11f2: 0x0008, 0x11f3: 0x0008, 0x11f4: 0x0008, 0x11f5: 0x0008,\n\t0x11f6: 0x0008, 0x11f7: 0x0008, 0x11f8: 0x0008, 0x11f9: 0xe01d, 0x11fa: 0x0008, 0x11fb: 0xe03d,\n\t0x11fc: 0x0008, 0x11fd: 0x4445, 0x11fe: 0xe00d, 0x11ff: 0x0008,\n\t// Block 0x48, offset 0x1200\n\t0x1200: 0xe00d, 0x1201: 0x0008, 0x1202: 0xe00d, 0x1203: 0x0008, 0x1204: 0xe00d, 0x1205: 0x0008,\n\t0x1206: 0xe00d, 0x1207: 0x0008, 0x1208: 0x0008, 0x1209: 0x0018, 0x120a: 0x0018, 0x120b: 0xe03d,\n\t0x120c: 0x0008, 0x120d: 0x11d9, 0x120e: 0x0008, 0x120f: 0x0008, 0x1210: 0xe00d, 0x1211: 0x0008,\n\t0x1212: 0xe00d, 0x1213: 0x0008, 0x1214: 0x0008, 0x1215: 0x0008, 0x1216: 0xe00d, 0x1217: 0x0008,\n\t0x1218: 0xe00d, 0x1219: 0x0008, 0x121a: 0xe00d, 0x121b: 0x0008, 0x121c: 0xe00d, 0x121d: 0x0008,\n\t0x121e: 0xe00d, 0x121f: 0x0008, 0x1220: 0xe00d, 0x1221: 0x0008, 0x1222: 0xe00d, 0x1223: 0x0008,\n\t0x1224: 0xe00d, 0x1225: 0x0008, 0x1226: 0xe00d, 0x1227: 0x0008, 0x1228: 0xe00d, 0x1229: 0x0008,\n\t0x122a: 0x6e29, 0x122b: 0x1029, 0x122c: 0x11c1, 0x122d: 0x6e41, 0x122e: 0x1221, 0x122f: 0x0008,\n\t0x1230: 0x6e59, 0x1231: 0x6e71, 0x1232: 0x1239, 0x1233: 0x4465, 0x1234: 0xe00d, 0x1235: 0x0008,\n\t0x1236: 0xe00d, 0x1237: 0x0008, 0x1238: 0xe00d, 0x1239: 0x0008, 0x123a: 0xe00d, 0x123b: 0x0008,\n\t0x123c: 0xe00d, 0x123d: 0x0008, 0x123e: 0xe00d, 0x123f: 0x0008,\n\t// Block 0x49, offset 0x1240\n\t0x1240: 0x650d, 0x1241: 0x652d, 0x1242: 0x654d, 0x1243: 0x656d, 0x1244: 0x658d, 0x1245: 0x65ad,\n\t0x1246: 0x65cd, 0x1247: 0x65ed, 0x1248: 0x660d, 0x1249: 0x662d, 0x124a: 0x664d, 0x124b: 0x666d,\n\t0x124c: 0x668d, 0x124d: 0x66ad, 0x124e: 0x0008, 0x124f: 0x0008, 0x1250: 0x66cd, 0x1251: 0x0008,\n\t0x1252: 0x66ed, 0x1253: 0x0008, 0x1254: 0x0008, 0x1255: 0x670d, 0x1256: 0x672d, 0x1257: 0x674d,\n\t0x1258: 0x676d, 0x1259: 0x678d, 0x125a: 0x67ad, 0x125b: 0x67cd, 0x125c: 0x67ed, 0x125d: 0x680d,\n\t0x125e: 0x682d, 0x125f: 0x0008, 0x1260: 0x684d, 0x1261: 0x0008, 0x1262: 0x686d, 0x1263: 0x0008,\n\t0x1264: 0x0008, 0x1265: 0x688d, 0x1266: 0x68ad, 0x1267: 0x0008, 0x1268: 0x0008, 0x1269: 0x0008,\n\t0x126a: 0x68cd, 0x126b: 0x68ed, 0x126c: 0x690d, 0x126d: 0x692d, 0x126e: 0x694d, 0x126f: 0x696d,\n\t0x1270: 0x698d, 0x1271: 0x69ad, 0x1272: 0x69cd, 0x1273: 0x69ed, 0x1274: 0x6a0d, 0x1275: 0x6a2d,\n\t0x1276: 0x6a4d, 0x1277: 0x6a6d, 0x1278: 0x6a8d, 0x1279: 0x6aad, 0x127a: 0x6acd, 0x127b: 0x6aed,\n\t0x127c: 0x6b0d, 0x127d: 0x6b2d, 0x127e: 0x6b4d, 0x127f: 0x6b6d,\n\t// Block 0x4a, offset 0x1280\n\t0x1280: 0x7acd, 0x1281: 0x7aed, 0x1282: 0x7b0d, 0x1283: 0x7b2d, 0x1284: 0x7b4d, 0x1285: 0x7b6d,\n\t0x1286: 0x7b8d, 0x1287: 0x7bad, 0x1288: 0x7bcd, 0x1289: 0x7bed, 0x128a: 0x7c0d, 0x128b: 0x7c2d,\n\t0x128c: 0x7c4d, 0x128d: 0x7c6d, 0x128e: 0x7c8d, 0x128f: 0x6ec9, 0x1290: 0x6ef1, 0x1291: 0x6f19,\n\t0x1292: 0x7cad, 0x1293: 0x7ccd, 0x1294: 0x7ced, 0x1295: 0x6f41, 0x1296: 0x6f69, 0x1297: 0x6f91,\n\t0x1298: 0x7d0d, 0x1299: 0x7d2d, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x0040,\n\t0x129e: 0x0040, 0x129f: 0x0040, 0x12a0: 0x0040, 0x12a1: 0x0040, 0x12a2: 0x0040, 0x12a3: 0x0040,\n\t0x12a4: 0x0040, 0x12a5: 0x0040, 0x12a6: 0x0040, 0x12a7: 0x0040, 0x12a8: 0x0040, 0x12a9: 0x0040,\n\t0x12aa: 0x0040, 0x12ab: 0x0040, 0x12ac: 0x0040, 0x12ad: 0x0040, 0x12ae: 0x0040, 0x12af: 0x0040,\n\t0x12b0: 0x0040, 0x12b1: 0x0040, 0x12b2: 0x0040, 0x12b3: 0x0040, 0x12b4: 0x0040, 0x12b5: 0x0040,\n\t0x12b6: 0x0040, 0x12b7: 0x0040, 0x12b8: 0x0040, 0x12b9: 0x0040, 0x12ba: 0x0040, 0x12bb: 0x0040,\n\t0x12bc: 0x0040, 0x12bd: 0x0040, 0x12be: 0x0040, 0x12bf: 0x0040,\n\t// Block 0x4b, offset 0x12c0\n\t0x12c0: 0x6fb9, 0x12c1: 0x6fd1, 0x12c2: 0x6fe9, 0x12c3: 0x7d4d, 0x12c4: 0x7d6d, 0x12c5: 0x7001,\n\t0x12c6: 0x7001, 0x12c7: 0x0040, 0x12c8: 0x0040, 0x12c9: 0x0040, 0x12ca: 0x0040, 0x12cb: 0x0040,\n\t0x12cc: 0x0040, 0x12cd: 0x0040, 0x12ce: 0x0040, 0x12cf: 0x0040, 0x12d0: 0x0040, 0x12d1: 0x0040,\n\t0x12d2: 0x0040, 0x12d3: 0x7019, 0x12d4: 0x7041, 0x12d5: 0x7069, 0x12d6: 0x7091, 0x12d7: 0x70b9,\n\t0x12d8: 0x0040, 0x12d9: 0x0040, 0x12da: 0x0040, 0x12db: 0x0040, 0x12dc: 0x0040, 0x12dd: 0x70e1,\n\t0x12de: 0x3308, 0x12df: 0x7109, 0x12e0: 0x7131, 0x12e1: 0x20a9, 0x12e2: 0x20f1, 0x12e3: 0x7149,\n\t0x12e4: 0x7161, 0x12e5: 0x7179, 0x12e6: 0x7191, 0x12e7: 0x71a9, 0x12e8: 0x71c1, 0x12e9: 0x1fb2,\n\t0x12ea: 0x71d9, 0x12eb: 0x7201, 0x12ec: 0x7229, 0x12ed: 0x7261, 0x12ee: 0x7299, 0x12ef: 0x72c1,\n\t0x12f0: 0x72e9, 0x12f1: 0x7311, 0x12f2: 0x7339, 0x12f3: 0x7361, 0x12f4: 0x7389, 0x12f5: 0x73b1,\n\t0x12f6: 0x73d9, 0x12f7: 0x0040, 0x12f8: 0x7401, 0x12f9: 0x7429, 0x12fa: 0x7451, 0x12fb: 0x7479,\n\t0x12fc: 0x74a1, 0x12fd: 0x0040, 0x12fe: 0x74c9, 0x12ff: 0x0040,\n\t// Block 0x4c, offset 0x1300\n\t0x1300: 0x74f1, 0x1301: 0x7519, 0x1302: 0x0040, 0x1303: 0x7541, 0x1304: 0x7569, 0x1305: 0x0040,\n\t0x1306: 0x7591, 0x1307: 0x75b9, 0x1308: 0x75e1, 0x1309: 0x7609, 0x130a: 0x7631, 0x130b: 0x7659,\n\t0x130c: 0x7681, 0x130d: 0x76a9, 0x130e: 0x76d1, 0x130f: 0x76f9, 0x1310: 0x7721, 0x1311: 0x7721,\n\t0x1312: 0x7739, 0x1313: 0x7739, 0x1314: 0x7739, 0x1315: 0x7739, 0x1316: 0x7751, 0x1317: 0x7751,\n\t0x1318: 0x7751, 0x1319: 0x7751, 0x131a: 0x7769, 0x131b: 0x7769, 0x131c: 0x7769, 0x131d: 0x7769,\n\t0x131e: 0x7781, 0x131f: 0x7781, 0x1320: 0x7781, 0x1321: 0x7781, 0x1322: 0x7799, 0x1323: 0x7799,\n\t0x1324: 0x7799, 0x1325: 0x7799, 0x1326: 0x77b1, 0x1327: 0x77b1, 0x1328: 0x77b1, 0x1329: 0x77b1,\n\t0x132a: 0x77c9, 0x132b: 0x77c9, 0x132c: 0x77c9, 0x132d: 0x77c9, 0x132e: 0x77e1, 0x132f: 0x77e1,\n\t0x1330: 0x77e1, 0x1331: 0x77e1, 0x1332: 0x77f9, 0x1333: 0x77f9, 0x1334: 0x77f9, 0x1335: 0x77f9,\n\t0x1336: 0x7811, 0x1337: 0x7811, 0x1338: 0x7811, 0x1339: 0x7811, 0x133a: 0x7829, 0x133b: 0x7829,\n\t0x133c: 0x7829, 0x133d: 0x7829, 0x133e: 0x7841, 0x133f: 0x7841,\n\t// Block 0x4d, offset 0x1340\n\t0x1340: 0x7841, 0x1341: 0x7841, 0x1342: 0x7859, 0x1343: 0x7859, 0x1344: 0x7871, 0x1345: 0x7871,\n\t0x1346: 0x7889, 0x1347: 0x7889, 0x1348: 0x78a1, 0x1349: 0x78a1, 0x134a: 0x78b9, 0x134b: 0x78b9,\n\t0x134c: 0x78d1, 0x134d: 0x78d1, 0x134e: 0x78e9, 0x134f: 0x78e9, 0x1350: 0x78e9, 0x1351: 0x78e9,\n\t0x1352: 0x7901, 0x1353: 0x7901, 0x1354: 0x7901, 0x1355: 0x7901, 0x1356: 0x7919, 0x1357: 0x7919,\n\t0x1358: 0x7919, 0x1359: 0x7919, 0x135a: 0x7931, 0x135b: 0x7931, 0x135c: 0x7931, 0x135d: 0x7931,\n\t0x135e: 0x7949, 0x135f: 0x7949, 0x1360: 0x7961, 0x1361: 0x7961, 0x1362: 0x7961, 0x1363: 0x7961,\n\t0x1364: 0x7979, 0x1365: 0x7979, 0x1366: 0x7991, 0x1367: 0x7991, 0x1368: 0x7991, 0x1369: 0x7991,\n\t0x136a: 0x79a9, 0x136b: 0x79a9, 0x136c: 0x79a9, 0x136d: 0x79a9, 0x136e: 0x79c1, 0x136f: 0x79c1,\n\t0x1370: 0x79d9, 0x1371: 0x79d9, 0x1372: 0x0818, 0x1373: 0x0818, 0x1374: 0x0818, 0x1375: 0x0818,\n\t0x1376: 0x0818, 0x1377: 0x0818, 0x1378: 0x0818, 0x1379: 0x0818, 0x137a: 0x0818, 0x137b: 0x0818,\n\t0x137c: 0x0818, 0x137d: 0x0818, 0x137e: 0x0818, 0x137f: 0x0818,\n\t// Block 0x4e, offset 0x1380\n\t0x1380: 0x0818, 0x1381: 0x0818, 0x1382: 0x0040, 0x1383: 0x0040, 0x1384: 0x0040, 0x1385: 0x0040,\n\t0x1386: 0x0040, 0x1387: 0x0040, 0x1388: 0x0040, 0x1389: 0x0040, 0x138a: 0x0040, 0x138b: 0x0040,\n\t0x138c: 0x0040, 0x138d: 0x0040, 0x138e: 0x0040, 0x138f: 0x0040, 0x1390: 0x0040, 0x1391: 0x0040,\n\t0x1392: 0x0040, 0x1393: 0x79f1, 0x1394: 0x79f1, 0x1395: 0x79f1, 0x1396: 0x79f1, 0x1397: 0x7a09,\n\t0x1398: 0x7a09, 0x1399: 0x7a21, 0x139a: 0x7a21, 0x139b: 0x7a39, 0x139c: 0x7a39, 0x139d: 0x0479,\n\t0x139e: 0x7a51, 0x139f: 0x7a51, 0x13a0: 0x7a69, 0x13a1: 0x7a69, 0x13a2: 0x7a81, 0x13a3: 0x7a81,\n\t0x13a4: 0x7a99, 0x13a5: 0x7a99, 0x13a6: 0x7a99, 0x13a7: 0x7a99, 0x13a8: 0x7ab1, 0x13a9: 0x7ab1,\n\t0x13aa: 0x7ac9, 0x13ab: 0x7ac9, 0x13ac: 0x7af1, 0x13ad: 0x7af1, 0x13ae: 0x7b19, 0x13af: 0x7b19,\n\t0x13b0: 0x7b41, 0x13b1: 0x7b41, 0x13b2: 0x7b69, 0x13b3: 0x7b69, 0x13b4: 0x7b91, 0x13b5: 0x7b91,\n\t0x13b6: 0x7bb9, 0x13b7: 0x7bb9, 0x13b8: 0x7bb9, 0x13b9: 0x7be1, 0x13ba: 0x7be1, 0x13bb: 0x7be1,\n\t0x13bc: 0x7c09, 0x13bd: 0x7c09, 0x13be: 0x7c09, 0x13bf: 0x7c09,\n\t// Block 0x4f, offset 0x13c0\n\t0x13c0: 0x85f9, 0x13c1: 0x8621, 0x13c2: 0x8649, 0x13c3: 0x8671, 0x13c4: 0x8699, 0x13c5: 0x86c1,\n\t0x13c6: 0x86e9, 0x13c7: 0x8711, 0x13c8: 0x8739, 0x13c9: 0x8761, 0x13ca: 0x8789, 0x13cb: 0x87b1,\n\t0x13cc: 0x87d9, 0x13cd: 0x8801, 0x13ce: 0x8829, 0x13cf: 0x8851, 0x13d0: 0x8879, 0x13d1: 0x88a1,\n\t0x13d2: 0x88c9, 0x13d3: 0x88f1, 0x13d4: 0x8919, 0x13d5: 0x8941, 0x13d6: 0x8969, 0x13d7: 0x8991,\n\t0x13d8: 0x89b9, 0x13d9: 0x89e1, 0x13da: 0x8a09, 0x13db: 0x8a31, 0x13dc: 0x8a59, 0x13dd: 0x8a81,\n\t0x13de: 0x8aaa, 0x13df: 0x8ada, 0x13e0: 0x8b0a, 0x13e1: 0x8b3a, 0x13e2: 0x8b6a, 0x13e3: 0x8b9a,\n\t0x13e4: 0x8bc9, 0x13e5: 0x8bf1, 0x13e6: 0x7c71, 0x13e7: 0x8c19, 0x13e8: 0x7be1, 0x13e9: 0x7c99,\n\t0x13ea: 0x8c41, 0x13eb: 0x8c69, 0x13ec: 0x7d39, 0x13ed: 0x8c91, 0x13ee: 0x7d61, 0x13ef: 0x7d89,\n\t0x13f0: 0x8cb9, 0x13f1: 0x8ce1, 0x13f2: 0x7e29, 0x13f3: 0x8d09, 0x13f4: 0x7e51, 0x13f5: 0x7e79,\n\t0x13f6: 0x8d31, 0x13f7: 0x8d59, 0x13f8: 0x7ec9, 0x13f9: 0x8d81, 0x13fa: 0x7ef1, 0x13fb: 0x7f19,\n\t0x13fc: 0x83a1, 0x13fd: 0x83c9, 0x13fe: 0x8441, 0x13ff: 0x8469,\n\t// Block 0x50, offset 0x1400\n\t0x1400: 0x8491, 0x1401: 0x8531, 0x1402: 0x8559, 0x1403: 0x8581, 0x1404: 0x85a9, 0x1405: 0x8649,\n\t0x1406: 0x8671, 0x1407: 0x8699, 0x1408: 0x8da9, 0x1409: 0x8739, 0x140a: 0x8dd1, 0x140b: 0x8df9,\n\t0x140c: 0x8829, 0x140d: 0x8e21, 0x140e: 0x8851, 0x140f: 0x8879, 0x1410: 0x8a81, 0x1411: 0x8e49,\n\t0x1412: 0x8e71, 0x1413: 0x89b9, 0x1414: 0x8e99, 0x1415: 0x89e1, 0x1416: 0x8a09, 0x1417: 0x7c21,\n\t0x1418: 0x7c49, 0x1419: 0x8ec1, 0x141a: 0x7c71, 0x141b: 0x8ee9, 0x141c: 0x7cc1, 0x141d: 0x7ce9,\n\t0x141e: 0x7d11, 0x141f: 0x7d39, 0x1420: 0x8f11, 0x1421: 0x7db1, 0x1422: 0x7dd9, 0x1423: 0x7e01,\n\t0x1424: 0x7e29, 0x1425: 0x8f39, 0x1426: 0x7ec9, 0x1427: 0x7f41, 0x1428: 0x7f69, 0x1429: 0x7f91,\n\t0x142a: 0x7fb9, 0x142b: 0x7fe1, 0x142c: 0x8031, 0x142d: 0x8059, 0x142e: 0x8081, 0x142f: 0x80a9,\n\t0x1430: 0x80d1, 0x1431: 0x80f9, 0x1432: 0x8f61, 0x1433: 0x8121, 0x1434: 0x8149, 0x1435: 0x8171,\n\t0x1436: 0x8199, 0x1437: 0x81c1, 0x1438: 0x81e9, 0x1439: 0x8239, 0x143a: 0x8261, 0x143b: 0x8289,\n\t0x143c: 0x82b1, 0x143d: 0x82d9, 0x143e: 0x8301, 0x143f: 0x8329,\n\t// Block 0x51, offset 0x1440\n\t0x1440: 0x8351, 0x1441: 0x8379, 0x1442: 0x83f1, 0x1443: 0x8419, 0x1444: 0x84b9, 0x1445: 0x84e1,\n\t0x1446: 0x8509, 0x1447: 0x8531, 0x1448: 0x8559, 0x1449: 0x85d1, 0x144a: 0x85f9, 0x144b: 0x8621,\n\t0x144c: 0x8649, 0x144d: 0x8f89, 0x144e: 0x86c1, 0x144f: 0x86e9, 0x1450: 0x8711, 0x1451: 0x8739,\n\t0x1452: 0x87b1, 0x1453: 0x87d9, 0x1454: 0x8801, 0x1455: 0x8829, 0x1456: 0x8fb1, 0x1457: 0x88a1,\n\t0x1458: 0x88c9, 0x1459: 0x8fd9, 0x145a: 0x8941, 0x145b: 0x8969, 0x145c: 0x8991, 0x145d: 0x89b9,\n\t0x145e: 0x9001, 0x145f: 0x7c71, 0x1460: 0x8ee9, 0x1461: 0x7d39, 0x1462: 0x8f11, 0x1463: 0x7e29,\n\t0x1464: 0x8f39, 0x1465: 0x7ec9, 0x1466: 0x9029, 0x1467: 0x80d1, 0x1468: 0x9051, 0x1469: 0x9079,\n\t0x146a: 0x90a1, 0x146b: 0x8531, 0x146c: 0x8559, 0x146d: 0x8649, 0x146e: 0x8829, 0x146f: 0x8fb1,\n\t0x1470: 0x89b9, 0x1471: 0x9001, 0x1472: 0x90c9, 0x1473: 0x9101, 0x1474: 0x9139, 0x1475: 0x9171,\n\t0x1476: 0x9199, 0x1477: 0x91c1, 0x1478: 0x91e9, 0x1479: 0x9211, 0x147a: 0x9239, 0x147b: 0x9261,\n\t0x147c: 0x9289, 0x147d: 0x92b1, 0x147e: 0x92d9, 0x147f: 0x9301,\n\t// Block 0x52, offset 0x1480\n\t0x1480: 0x9329, 0x1481: 0x9351, 0x1482: 0x9379, 0x1483: 0x93a1, 0x1484: 0x93c9, 0x1485: 0x93f1,\n\t0x1486: 0x9419, 0x1487: 0x9441, 0x1488: 0x9469, 0x1489: 0x9491, 0x148a: 0x94b9, 0x148b: 0x94e1,\n\t0x148c: 0x9079, 0x148d: 0x9509, 0x148e: 0x9531, 0x148f: 0x9559, 0x1490: 0x9581, 0x1491: 0x9171,\n\t0x1492: 0x9199, 0x1493: 0x91c1, 0x1494: 0x91e9, 0x1495: 0x9211, 0x1496: 0x9239, 0x1497: 0x9261,\n\t0x1498: 0x9289, 0x1499: 0x92b1, 0x149a: 0x92d9, 0x149b: 0x9301, 0x149c: 0x9329, 0x149d: 0x9351,\n\t0x149e: 0x9379, 0x149f: 0x93a1, 0x14a0: 0x93c9, 0x14a1: 0x93f1, 0x14a2: 0x9419, 0x14a3: 0x9441,\n\t0x14a4: 0x9469, 0x14a5: 0x9491, 0x14a6: 0x94b9, 0x14a7: 0x94e1, 0x14a8: 0x9079, 0x14a9: 0x9509,\n\t0x14aa: 0x9531, 0x14ab: 0x9559, 0x14ac: 0x9581, 0x14ad: 0x9491, 0x14ae: 0x94b9, 0x14af: 0x94e1,\n\t0x14b0: 0x9079, 0x14b1: 0x9051, 0x14b2: 0x90a1, 0x14b3: 0x8211, 0x14b4: 0x8059, 0x14b5: 0x8081,\n\t0x14b6: 0x80a9, 0x14b7: 0x9491, 0x14b8: 0x94b9, 0x14b9: 0x94e1, 0x14ba: 0x8211, 0x14bb: 0x8239,\n\t0x14bc: 0x95a9, 0x14bd: 0x95a9, 0x14be: 0x0018, 0x14bf: 0x0018,\n\t// Block 0x53, offset 0x14c0\n\t0x14c0: 0x0040, 0x14c1: 0x0040, 0x14c2: 0x0040, 0x14c3: 0x0040, 0x14c4: 0x0040, 0x14c5: 0x0040,\n\t0x14c6: 0x0040, 0x14c7: 0x0040, 0x14c8: 0x0040, 0x14c9: 0x0040, 0x14ca: 0x0040, 0x14cb: 0x0040,\n\t0x14cc: 0x0040, 0x14cd: 0x0040, 0x14ce: 0x0040, 0x14cf: 0x0040, 0x14d0: 0x95d1, 0x14d1: 0x9609,\n\t0x14d2: 0x9609, 0x14d3: 0x9641, 0x14d4: 0x9679, 0x14d5: 0x96b1, 0x14d6: 0x96e9, 0x14d7: 0x9721,\n\t0x14d8: 0x9759, 0x14d9: 0x9759, 0x14da: 0x9791, 0x14db: 0x97c9, 0x14dc: 0x9801, 0x14dd: 0x9839,\n\t0x14de: 0x9871, 0x14df: 0x98a9, 0x14e0: 0x98a9, 0x14e1: 0x98e1, 0x14e2: 0x9919, 0x14e3: 0x9919,\n\t0x14e4: 0x9951, 0x14e5: 0x9951, 0x14e6: 0x9989, 0x14e7: 0x99c1, 0x14e8: 0x99c1, 0x14e9: 0x99f9,\n\t0x14ea: 0x9a31, 0x14eb: 0x9a31, 0x14ec: 0x9a69, 0x14ed: 0x9a69, 0x14ee: 0x9aa1, 0x14ef: 0x9ad9,\n\t0x14f0: 0x9ad9, 0x14f1: 0x9b11, 0x14f2: 0x9b11, 0x14f3: 0x9b49, 0x14f4: 0x9b81, 0x14f5: 0x9bb9,\n\t0x14f6: 0x9bf1, 0x14f7: 0x9bf1, 0x14f8: 0x9c29, 0x14f9: 0x9c61, 0x14fa: 0x9c99, 0x14fb: 0x9cd1,\n\t0x14fc: 0x9d09, 0x14fd: 0x9d09, 0x14fe: 0x9d41, 0x14ff: 0x9d79,\n\t// Block 0x54, offset 0x1500\n\t0x1500: 0xa949, 0x1501: 0xa981, 0x1502: 0xa9b9, 0x1503: 0xa8a1, 0x1504: 0x9bb9, 0x1505: 0x9989,\n\t0x1506: 0xa9f1, 0x1507: 0xaa29, 0x1508: 0x0040, 0x1509: 0x0040, 0x150a: 0x0040, 0x150b: 0x0040,\n\t0x150c: 0x0040, 0x150d: 0x0040, 0x150e: 0x0040, 0x150f: 0x0040, 0x1510: 0x0040, 0x1511: 0x0040,\n\t0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x0040, 0x1515: 0x0040, 0x1516: 0x0040, 0x1517: 0x0040,\n\t0x1518: 0x0040, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040,\n\t0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x0040, 0x1521: 0x0040, 0x1522: 0x0040, 0x1523: 0x0040,\n\t0x1524: 0x0040, 0x1525: 0x0040, 0x1526: 0x0040, 0x1527: 0x0040, 0x1528: 0x0040, 0x1529: 0x0040,\n\t0x152a: 0x0040, 0x152b: 0x0040, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040,\n\t0x1530: 0xaa61, 0x1531: 0xaa99, 0x1532: 0xaad1, 0x1533: 0xab19, 0x1534: 0xab61, 0x1535: 0xaba9,\n\t0x1536: 0xabf1, 0x1537: 0xac39, 0x1538: 0xac81, 0x1539: 0xacc9, 0x153a: 0xad02, 0x153b: 0xae12,\n\t0x153c: 0xae91, 0x153d: 0x0018, 0x153e: 0x0040, 0x153f: 0x0040,\n\t// Block 0x55, offset 0x1540\n\t0x1540: 0x33c0, 0x1541: 0x33c0, 0x1542: 0x33c0, 0x1543: 0x33c0, 0x1544: 0x33c0, 0x1545: 0x33c0,\n\t0x1546: 0x33c0, 0x1547: 0x33c0, 0x1548: 0x33c0, 0x1549: 0x33c0, 0x154a: 0x33c0, 0x154b: 0x33c0,\n\t0x154c: 0x33c0, 0x154d: 0x33c0, 0x154e: 0x33c0, 0x154f: 0x33c0, 0x1550: 0xaeda, 0x1551: 0x7d8d,\n\t0x1552: 0x0040, 0x1553: 0xaeea, 0x1554: 0x03c2, 0x1555: 0xaefa, 0x1556: 0xaf0a, 0x1557: 0x7dad,\n\t0x1558: 0x7dcd, 0x1559: 0x0040, 0x155a: 0x0040, 0x155b: 0x0040, 0x155c: 0x0040, 0x155d: 0x0040,\n\t0x155e: 0x0040, 0x155f: 0x0040, 0x1560: 0x3308, 0x1561: 0x3308, 0x1562: 0x3308, 0x1563: 0x3308,\n\t0x1564: 0x3308, 0x1565: 0x3308, 0x1566: 0x3308, 0x1567: 0x3308, 0x1568: 0x3308, 0x1569: 0x3308,\n\t0x156a: 0x3308, 0x156b: 0x3308, 0x156c: 0x3308, 0x156d: 0x3308, 0x156e: 0x3308, 0x156f: 0x3308,\n\t0x1570: 0x0040, 0x1571: 0x7ded, 0x1572: 0x7e0d, 0x1573: 0xaf1a, 0x1574: 0xaf1a, 0x1575: 0x1fd2,\n\t0x1576: 0x1fe2, 0x1577: 0xaf2a, 0x1578: 0xaf3a, 0x1579: 0x7e2d, 0x157a: 0x7e4d, 0x157b: 0x7e6d,\n\t0x157c: 0x7e2d, 0x157d: 0x7e8d, 0x157e: 0x7ead, 0x157f: 0x7e8d,\n\t// Block 0x56, offset 0x1580\n\t0x1580: 0x7ecd, 0x1581: 0x7eed, 0x1582: 0x7f0d, 0x1583: 0x7eed, 0x1584: 0x7f2d, 0x1585: 0x0018,\n\t0x1586: 0x0018, 0x1587: 0xaf4a, 0x1588: 0xaf5a, 0x1589: 0x7f4e, 0x158a: 0x7f6e, 0x158b: 0x7f8e,\n\t0x158c: 0x7fae, 0x158d: 0xaf1a, 0x158e: 0xaf1a, 0x158f: 0xaf1a, 0x1590: 0xaeda, 0x1591: 0x7fcd,\n\t0x1592: 0x0040, 0x1593: 0x0040, 0x1594: 0x03c2, 0x1595: 0xaeea, 0x1596: 0xaf0a, 0x1597: 0xaefa,\n\t0x1598: 0x7fed, 0x1599: 0x1fd2, 0x159a: 0x1fe2, 0x159b: 0xaf2a, 0x159c: 0xaf3a, 0x159d: 0x7ecd,\n\t0x159e: 0x7f2d, 0x159f: 0xaf6a, 0x15a0: 0xaf7a, 0x15a1: 0xaf8a, 0x15a2: 0x1fb2, 0x15a3: 0xaf99,\n\t0x15a4: 0xafaa, 0x15a5: 0xafba, 0x15a6: 0x1fc2, 0x15a7: 0x0040, 0x15a8: 0xafca, 0x15a9: 0xafda,\n\t0x15aa: 0xafea, 0x15ab: 0xaffa, 0x15ac: 0x0040, 0x15ad: 0x0040, 0x15ae: 0x0040, 0x15af: 0x0040,\n\t0x15b0: 0x800e, 0x15b1: 0xb009, 0x15b2: 0x802e, 0x15b3: 0x0808, 0x15b4: 0x804e, 0x15b5: 0x0040,\n\t0x15b6: 0x806e, 0x15b7: 0xb031, 0x15b8: 0x808e, 0x15b9: 0xb059, 0x15ba: 0x80ae, 0x15bb: 0xb081,\n\t0x15bc: 0x80ce, 0x15bd: 0xb0a9, 0x15be: 0x80ee, 0x15bf: 0xb0d1,\n\t// Block 0x57, offset 0x15c0\n\t0x15c0: 0xb0f9, 0x15c1: 0xb111, 0x15c2: 0xb111, 0x15c3: 0xb129, 0x15c4: 0xb129, 0x15c5: 0xb141,\n\t0x15c6: 0xb141, 0x15c7: 0xb159, 0x15c8: 0xb159, 0x15c9: 0xb171, 0x15ca: 0xb171, 0x15cb: 0xb171,\n\t0x15cc: 0xb171, 0x15cd: 0xb189, 0x15ce: 0xb189, 0x15cf: 0xb1a1, 0x15d0: 0xb1a1, 0x15d1: 0xb1a1,\n\t0x15d2: 0xb1a1, 0x15d3: 0xb1b9, 0x15d4: 0xb1b9, 0x15d5: 0xb1d1, 0x15d6: 0xb1d1, 0x15d7: 0xb1d1,\n\t0x15d8: 0xb1d1, 0x15d9: 0xb1e9, 0x15da: 0xb1e9, 0x15db: 0xb1e9, 0x15dc: 0xb1e9, 0x15dd: 0xb201,\n\t0x15de: 0xb201, 0x15df: 0xb201, 0x15e0: 0xb201, 0x15e1: 0xb219, 0x15e2: 0xb219, 0x15e3: 0xb219,\n\t0x15e4: 0xb219, 0x15e5: 0xb231, 0x15e6: 0xb231, 0x15e7: 0xb231, 0x15e8: 0xb231, 0x15e9: 0xb249,\n\t0x15ea: 0xb249, 0x15eb: 0xb261, 0x15ec: 0xb261, 0x15ed: 0xb279, 0x15ee: 0xb279, 0x15ef: 0xb291,\n\t0x15f0: 0xb291, 0x15f1: 0xb2a9, 0x15f2: 0xb2a9, 0x15f3: 0xb2a9, 0x15f4: 0xb2a9, 0x15f5: 0xb2c1,\n\t0x15f6: 0xb2c1, 0x15f7: 0xb2c1, 0x15f8: 0xb2c1, 0x15f9: 0xb2d9, 0x15fa: 0xb2d9, 0x15fb: 0xb2d9,\n\t0x15fc: 0xb2d9, 0x15fd: 0xb2f1, 0x15fe: 0xb2f1, 0x15ff: 0xb2f1,\n\t// Block 0x58, offset 0x1600\n\t0x1600: 0xb2f1, 0x1601: 0xb309, 0x1602: 0xb309, 0x1603: 0xb309, 0x1604: 0xb309, 0x1605: 0xb321,\n\t0x1606: 0xb321, 0x1607: 0xb321, 0x1608: 0xb321, 0x1609: 0xb339, 0x160a: 0xb339, 0x160b: 0xb339,\n\t0x160c: 0xb339, 0x160d: 0xb351, 0x160e: 0xb351, 0x160f: 0xb351, 0x1610: 0xb351, 0x1611: 0xb369,\n\t0x1612: 0xb369, 0x1613: 0xb369, 0x1614: 0xb369, 0x1615: 0xb381, 0x1616: 0xb381, 0x1617: 0xb381,\n\t0x1618: 0xb381, 0x1619: 0xb399, 0x161a: 0xb399, 0x161b: 0xb399, 0x161c: 0xb399, 0x161d: 0xb3b1,\n\t0x161e: 0xb3b1, 0x161f: 0xb3b1, 0x1620: 0xb3b1, 0x1621: 0xb3c9, 0x1622: 0xb3c9, 0x1623: 0xb3c9,\n\t0x1624: 0xb3c9, 0x1625: 0xb3e1, 0x1626: 0xb3e1, 0x1627: 0xb3e1, 0x1628: 0xb3e1, 0x1629: 0xb3f9,\n\t0x162a: 0xb3f9, 0x162b: 0xb3f9, 0x162c: 0xb3f9, 0x162d: 0xb411, 0x162e: 0xb411, 0x162f: 0x7ab1,\n\t0x1630: 0x7ab1, 0x1631: 0xb429, 0x1632: 0xb429, 0x1633: 0xb429, 0x1634: 0xb429, 0x1635: 0xb441,\n\t0x1636: 0xb441, 0x1637: 0xb469, 0x1638: 0xb469, 0x1639: 0xb491, 0x163a: 0xb491, 0x163b: 0xb4b9,\n\t0x163c: 0xb4b9, 0x163d: 0x0040, 0x163e: 0x0040, 0x163f: 0x03c0,\n\t// Block 0x59, offset 0x1640\n\t0x1640: 0x0040, 0x1641: 0xaefa, 0x1642: 0xb4e2, 0x1643: 0xaf6a, 0x1644: 0xafda, 0x1645: 0xafea,\n\t0x1646: 0xaf7a, 0x1647: 0xb4f2, 0x1648: 0x1fd2, 0x1649: 0x1fe2, 0x164a: 0xaf8a, 0x164b: 0x1fb2,\n\t0x164c: 0xaeda, 0x164d: 0xaf99, 0x164e: 0x29d1, 0x164f: 0xb502, 0x1650: 0x1f41, 0x1651: 0x00c9,\n\t0x1652: 0x0069, 0x1653: 0x0079, 0x1654: 0x1f51, 0x1655: 0x1f61, 0x1656: 0x1f71, 0x1657: 0x1f81,\n\t0x1658: 0x1f91, 0x1659: 0x1fa1, 0x165a: 0xaeea, 0x165b: 0x03c2, 0x165c: 0xafaa, 0x165d: 0x1fc2,\n\t0x165e: 0xafba, 0x165f: 0xaf0a, 0x1660: 0xaffa, 0x1661: 0x0039, 0x1662: 0x0ee9, 0x1663: 0x1159,\n\t0x1664: 0x0ef9, 0x1665: 0x0f09, 0x1666: 0x1199, 0x1667: 0x0f31, 0x1668: 0x0249, 0x1669: 0x0f41,\n\t0x166a: 0x0259, 0x166b: 0x0f51, 0x166c: 0x0359, 0x166d: 0x0f61, 0x166e: 0x0f71, 0x166f: 0x00d9,\n\t0x1670: 0x0f99, 0x1671: 0x2039, 0x1672: 0x0269, 0x1673: 0x01d9, 0x1674: 0x0fa9, 0x1675: 0x0fb9,\n\t0x1676: 0x1089, 0x1677: 0x0279, 0x1678: 0x0369, 0x1679: 0x0289, 0x167a: 0x13d1, 0x167b: 0xaf4a,\n\t0x167c: 0xafca, 0x167d: 0xaf5a, 0x167e: 0xb512, 0x167f: 0xaf1a,\n\t// Block 0x5a, offset 0x1680\n\t0x1680: 0x1caa, 0x1681: 0x0039, 0x1682: 0x0ee9, 0x1683: 0x1159, 0x1684: 0x0ef9, 0x1685: 0x0f09,\n\t0x1686: 0x1199, 0x1687: 0x0f31, 0x1688: 0x0249, 0x1689: 0x0f41, 0x168a: 0x0259, 0x168b: 0x0f51,\n\t0x168c: 0x0359, 0x168d: 0x0f61, 0x168e: 0x0f71, 0x168f: 0x00d9, 0x1690: 0x0f99, 0x1691: 0x2039,\n\t0x1692: 0x0269, 0x1693: 0x01d9, 0x1694: 0x0fa9, 0x1695: 0x0fb9, 0x1696: 0x1089, 0x1697: 0x0279,\n\t0x1698: 0x0369, 0x1699: 0x0289, 0x169a: 0x13d1, 0x169b: 0xaf2a, 0x169c: 0xb522, 0x169d: 0xaf3a,\n\t0x169e: 0xb532, 0x169f: 0x810d, 0x16a0: 0x812d, 0x16a1: 0x29d1, 0x16a2: 0x814d, 0x16a3: 0x814d,\n\t0x16a4: 0x816d, 0x16a5: 0x818d, 0x16a6: 0x81ad, 0x16a7: 0x81cd, 0x16a8: 0x81ed, 0x16a9: 0x820d,\n\t0x16aa: 0x822d, 0x16ab: 0x824d, 0x16ac: 0x826d, 0x16ad: 0x828d, 0x16ae: 0x82ad, 0x16af: 0x82cd,\n\t0x16b0: 0x82ed, 0x16b1: 0x830d, 0x16b2: 0x832d, 0x16b3: 0x834d, 0x16b4: 0x836d, 0x16b5: 0x838d,\n\t0x16b6: 0x83ad, 0x16b7: 0x83cd, 0x16b8: 0x83ed, 0x16b9: 0x840d, 0x16ba: 0x842d, 0x16bb: 0x844d,\n\t0x16bc: 0x81ed, 0x16bd: 0x846d, 0x16be: 0x848d, 0x16bf: 0x824d,\n\t// Block 0x5b, offset 0x16c0\n\t0x16c0: 0x84ad, 0x16c1: 0x84cd, 0x16c2: 0x84ed, 0x16c3: 0x850d, 0x16c4: 0x852d, 0x16c5: 0x854d,\n\t0x16c6: 0x856d, 0x16c7: 0x858d, 0x16c8: 0x850d, 0x16c9: 0x85ad, 0x16ca: 0x850d, 0x16cb: 0x85cd,\n\t0x16cc: 0x85cd, 0x16cd: 0x85ed, 0x16ce: 0x85ed, 0x16cf: 0x860d, 0x16d0: 0x854d, 0x16d1: 0x862d,\n\t0x16d2: 0x864d, 0x16d3: 0x862d, 0x16d4: 0x866d, 0x16d5: 0x864d, 0x16d6: 0x868d, 0x16d7: 0x868d,\n\t0x16d8: 0x86ad, 0x16d9: 0x86ad, 0x16da: 0x86cd, 0x16db: 0x86cd, 0x16dc: 0x864d, 0x16dd: 0x814d,\n\t0x16de: 0x86ed, 0x16df: 0x870d, 0x16e0: 0x0040, 0x16e1: 0x872d, 0x16e2: 0x874d, 0x16e3: 0x876d,\n\t0x16e4: 0x878d, 0x16e5: 0x876d, 0x16e6: 0x87ad, 0x16e7: 0x87cd, 0x16e8: 0x87ed, 0x16e9: 0x87ed,\n\t0x16ea: 0x880d, 0x16eb: 0x880d, 0x16ec: 0x882d, 0x16ed: 0x882d, 0x16ee: 0x880d, 0x16ef: 0x880d,\n\t0x16f0: 0x884d, 0x16f1: 0x886d, 0x16f2: 0x888d, 0x16f3: 0x88ad, 0x16f4: 0x88cd, 0x16f5: 0x88ed,\n\t0x16f6: 0x88ed, 0x16f7: 0x88ed, 0x16f8: 0x890d, 0x16f9: 0x890d, 0x16fa: 0x890d, 0x16fb: 0x890d,\n\t0x16fc: 0x87ed, 0x16fd: 0x87ed, 0x16fe: 0x87ed, 0x16ff: 0x0040,\n\t// Block 0x5c, offset 0x1700\n\t0x1700: 0x0040, 0x1701: 0x0040, 0x1702: 0x874d, 0x1703: 0x872d, 0x1704: 0x892d, 0x1705: 0x872d,\n\t0x1706: 0x874d, 0x1707: 0x872d, 0x1708: 0x0040, 0x1709: 0x0040, 0x170a: 0x894d, 0x170b: 0x874d,\n\t0x170c: 0x896d, 0x170d: 0x892d, 0x170e: 0x896d, 0x170f: 0x874d, 0x1710: 0x0040, 0x1711: 0x0040,\n\t0x1712: 0x898d, 0x1713: 0x89ad, 0x1714: 0x88ad, 0x1715: 0x896d, 0x1716: 0x892d, 0x1717: 0x896d,\n\t0x1718: 0x0040, 0x1719: 0x0040, 0x171a: 0x89cd, 0x171b: 0x89ed, 0x171c: 0x89cd, 0x171d: 0x0040,\n\t0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0xb541, 0x1721: 0xb559, 0x1722: 0xb571, 0x1723: 0x8a0e,\n\t0x1724: 0xb589, 0x1725: 0xb5a1, 0x1726: 0x8a2d, 0x1727: 0x0040, 0x1728: 0x8a4d, 0x1729: 0x8a6d,\n\t0x172a: 0x8a8d, 0x172b: 0x8a6d, 0x172c: 0x8aad, 0x172d: 0x8acd, 0x172e: 0x8aed, 0x172f: 0x0040,\n\t0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040,\n\t0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0340, 0x173a: 0x0340, 0x173b: 0x0340,\n\t0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040,\n\t// Block 0x5d, offset 0x1740\n\t0x1740: 0x0a08, 0x1741: 0x0a08, 0x1742: 0x0a08, 0x1743: 0x0a08, 0x1744: 0x0a08, 0x1745: 0x0c08,\n\t0x1746: 0x0808, 0x1747: 0x0c08, 0x1748: 0x0818, 0x1749: 0x0c08, 0x174a: 0x0c08, 0x174b: 0x0808,\n\t0x174c: 0x0808, 0x174d: 0x0908, 0x174e: 0x0c08, 0x174f: 0x0c08, 0x1750: 0x0c08, 0x1751: 0x0c08,\n\t0x1752: 0x0c08, 0x1753: 0x0a08, 0x1754: 0x0a08, 0x1755: 0x0a08, 0x1756: 0x0a08, 0x1757: 0x0908,\n\t0x1758: 0x0a08, 0x1759: 0x0a08, 0x175a: 0x0a08, 0x175b: 0x0a08, 0x175c: 0x0a08, 0x175d: 0x0c08,\n\t0x175e: 0x0a08, 0x175f: 0x0a08, 0x1760: 0x0a08, 0x1761: 0x0c08, 0x1762: 0x0808, 0x1763: 0x0808,\n\t0x1764: 0x0c08, 0x1765: 0x3308, 0x1766: 0x3308, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0040,\n\t0x176a: 0x0040, 0x176b: 0x0a18, 0x176c: 0x0a18, 0x176d: 0x0a18, 0x176e: 0x0a18, 0x176f: 0x0c18,\n\t0x1770: 0x0818, 0x1771: 0x0818, 0x1772: 0x0818, 0x1773: 0x0818, 0x1774: 0x0818, 0x1775: 0x0818,\n\t0x1776: 0x0818, 0x1777: 0x0040, 0x1778: 0x0040, 0x1779: 0x0040, 0x177a: 0x0040, 0x177b: 0x0040,\n\t0x177c: 0x0040, 0x177d: 0x0040, 0x177e: 0x0040, 0x177f: 0x0040,\n\t// Block 0x5e, offset 0x1780\n\t0x1780: 0x0a08, 0x1781: 0x0c08, 0x1782: 0x0a08, 0x1783: 0x0c08, 0x1784: 0x0c08, 0x1785: 0x0c08,\n\t0x1786: 0x0a08, 0x1787: 0x0a08, 0x1788: 0x0a08, 0x1789: 0x0c08, 0x178a: 0x0a08, 0x178b: 0x0a08,\n\t0x178c: 0x0c08, 0x178d: 0x0a08, 0x178e: 0x0c08, 0x178f: 0x0c08, 0x1790: 0x0a08, 0x1791: 0x0c08,\n\t0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x0040,\n\t0x1798: 0x0040, 0x1799: 0x0818, 0x179a: 0x0818, 0x179b: 0x0818, 0x179c: 0x0818, 0x179d: 0x0040,\n\t0x179e: 0x0040, 0x179f: 0x0040, 0x17a0: 0x0040, 0x17a1: 0x0040, 0x17a2: 0x0040, 0x17a3: 0x0040,\n\t0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x0040, 0x17a7: 0x0040, 0x17a8: 0x0040, 0x17a9: 0x0c18,\n\t0x17aa: 0x0c18, 0x17ab: 0x0c18, 0x17ac: 0x0c18, 0x17ad: 0x0a18, 0x17ae: 0x0a18, 0x17af: 0x0818,\n\t0x17b0: 0x0040, 0x17b1: 0x0040, 0x17b2: 0x0040, 0x17b3: 0x0040, 0x17b4: 0x0040, 0x17b5: 0x0040,\n\t0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040,\n\t0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040,\n\t// Block 0x5f, offset 0x17c0\n\t0x17c0: 0x3308, 0x17c1: 0x3308, 0x17c2: 0x3008, 0x17c3: 0x3008, 0x17c4: 0x0040, 0x17c5: 0x0008,\n\t0x17c6: 0x0008, 0x17c7: 0x0008, 0x17c8: 0x0008, 0x17c9: 0x0008, 0x17ca: 0x0008, 0x17cb: 0x0008,\n\t0x17cc: 0x0008, 0x17cd: 0x0040, 0x17ce: 0x0040, 0x17cf: 0x0008, 0x17d0: 0x0008, 0x17d1: 0x0040,\n\t0x17d2: 0x0040, 0x17d3: 0x0008, 0x17d4: 0x0008, 0x17d5: 0x0008, 0x17d6: 0x0008, 0x17d7: 0x0008,\n\t0x17d8: 0x0008, 0x17d9: 0x0008, 0x17da: 0x0008, 0x17db: 0x0008, 0x17dc: 0x0008, 0x17dd: 0x0008,\n\t0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x0008, 0x17e3: 0x0008,\n\t0x17e4: 0x0008, 0x17e5: 0x0008, 0x17e6: 0x0008, 0x17e7: 0x0008, 0x17e8: 0x0008, 0x17e9: 0x0040,\n\t0x17ea: 0x0008, 0x17eb: 0x0008, 0x17ec: 0x0008, 0x17ed: 0x0008, 0x17ee: 0x0008, 0x17ef: 0x0008,\n\t0x17f0: 0x0008, 0x17f1: 0x0040, 0x17f2: 0x0008, 0x17f3: 0x0008, 0x17f4: 0x0040, 0x17f5: 0x0008,\n\t0x17f6: 0x0008, 0x17f7: 0x0008, 0x17f8: 0x0008, 0x17f9: 0x0008, 0x17fa: 0x0040, 0x17fb: 0x3308,\n\t0x17fc: 0x3308, 0x17fd: 0x0008, 0x17fe: 0x3008, 0x17ff: 0x3008,\n\t// Block 0x60, offset 0x1800\n\t0x1800: 0x3308, 0x1801: 0x3008, 0x1802: 0x3008, 0x1803: 0x3008, 0x1804: 0x3008, 0x1805: 0x0040,\n\t0x1806: 0x0040, 0x1807: 0x3008, 0x1808: 0x3008, 0x1809: 0x0040, 0x180a: 0x0040, 0x180b: 0x3008,\n\t0x180c: 0x3008, 0x180d: 0x3808, 0x180e: 0x0040, 0x180f: 0x0040, 0x1810: 0x0008, 0x1811: 0x0040,\n\t0x1812: 0x0040, 0x1813: 0x0040, 0x1814: 0x0040, 0x1815: 0x0040, 0x1816: 0x0040, 0x1817: 0x3008,\n\t0x1818: 0x0040, 0x1819: 0x0040, 0x181a: 0x0040, 0x181b: 0x0040, 0x181c: 0x0040, 0x181d: 0x0008,\n\t0x181e: 0x0008, 0x181f: 0x0008, 0x1820: 0x0008, 0x1821: 0x0008, 0x1822: 0x3008, 0x1823: 0x3008,\n\t0x1824: 0x0040, 0x1825: 0x0040, 0x1826: 0x3308, 0x1827: 0x3308, 0x1828: 0x3308, 0x1829: 0x3308,\n\t0x182a: 0x3308, 0x182b: 0x3308, 0x182c: 0x3308, 0x182d: 0x0040, 0x182e: 0x0040, 0x182f: 0x0040,\n\t0x1830: 0x3308, 0x1831: 0x3308, 0x1832: 0x3308, 0x1833: 0x3308, 0x1834: 0x3308, 0x1835: 0x0040,\n\t0x1836: 0x0040, 0x1837: 0x0040, 0x1838: 0x0040, 0x1839: 0x0040, 0x183a: 0x0040, 0x183b: 0x0040,\n\t0x183c: 0x0040, 0x183d: 0x0040, 0x183e: 0x0040, 0x183f: 0x0040,\n\t// Block 0x61, offset 0x1840\n\t0x1840: 0x0039, 0x1841: 0x0ee9, 0x1842: 0x1159, 0x1843: 0x0ef9, 0x1844: 0x0f09, 0x1845: 0x1199,\n\t0x1846: 0x0f31, 0x1847: 0x0249, 0x1848: 0x0f41, 0x1849: 0x0259, 0x184a: 0x0f51, 0x184b: 0x0359,\n\t0x184c: 0x0f61, 0x184d: 0x0f71, 0x184e: 0x00d9, 0x184f: 0x0f99, 0x1850: 0x2039, 0x1851: 0x0269,\n\t0x1852: 0x01d9, 0x1853: 0x0fa9, 0x1854: 0x0fb9, 0x1855: 0x1089, 0x1856: 0x0279, 0x1857: 0x0369,\n\t0x1858: 0x0289, 0x1859: 0x13d1, 0x185a: 0x0039, 0x185b: 0x0ee9, 0x185c: 0x1159, 0x185d: 0x0ef9,\n\t0x185e: 0x0f09, 0x185f: 0x1199, 0x1860: 0x0f31, 0x1861: 0x0249, 0x1862: 0x0f41, 0x1863: 0x0259,\n\t0x1864: 0x0f51, 0x1865: 0x0359, 0x1866: 0x0f61, 0x1867: 0x0f71, 0x1868: 0x00d9, 0x1869: 0x0f99,\n\t0x186a: 0x2039, 0x186b: 0x0269, 0x186c: 0x01d9, 0x186d: 0x0fa9, 0x186e: 0x0fb9, 0x186f: 0x1089,\n\t0x1870: 0x0279, 0x1871: 0x0369, 0x1872: 0x0289, 0x1873: 0x13d1, 0x1874: 0x0039, 0x1875: 0x0ee9,\n\t0x1876: 0x1159, 0x1877: 0x0ef9, 0x1878: 0x0f09, 0x1879: 0x1199, 0x187a: 0x0f31, 0x187b: 0x0249,\n\t0x187c: 0x0f41, 0x187d: 0x0259, 0x187e: 0x0f51, 0x187f: 0x0359,\n\t// Block 0x62, offset 0x1880\n\t0x1880: 0x0f61, 0x1881: 0x0f71, 0x1882: 0x00d9, 0x1883: 0x0f99, 0x1884: 0x2039, 0x1885: 0x0269,\n\t0x1886: 0x01d9, 0x1887: 0x0fa9, 0x1888: 0x0fb9, 0x1889: 0x1089, 0x188a: 0x0279, 0x188b: 0x0369,\n\t0x188c: 0x0289, 0x188d: 0x13d1, 0x188e: 0x0039, 0x188f: 0x0ee9, 0x1890: 0x1159, 0x1891: 0x0ef9,\n\t0x1892: 0x0f09, 0x1893: 0x1199, 0x1894: 0x0f31, 0x1895: 0x0040, 0x1896: 0x0f41, 0x1897: 0x0259,\n\t0x1898: 0x0f51, 0x1899: 0x0359, 0x189a: 0x0f61, 0x189b: 0x0f71, 0x189c: 0x00d9, 0x189d: 0x0f99,\n\t0x189e: 0x2039, 0x189f: 0x0269, 0x18a0: 0x01d9, 0x18a1: 0x0fa9, 0x18a2: 0x0fb9, 0x18a3: 0x1089,\n\t0x18a4: 0x0279, 0x18a5: 0x0369, 0x18a6: 0x0289, 0x18a7: 0x13d1, 0x18a8: 0x0039, 0x18a9: 0x0ee9,\n\t0x18aa: 0x1159, 0x18ab: 0x0ef9, 0x18ac: 0x0f09, 0x18ad: 0x1199, 0x18ae: 0x0f31, 0x18af: 0x0249,\n\t0x18b0: 0x0f41, 0x18b1: 0x0259, 0x18b2: 0x0f51, 0x18b3: 0x0359, 0x18b4: 0x0f61, 0x18b5: 0x0f71,\n\t0x18b6: 0x00d9, 0x18b7: 0x0f99, 0x18b8: 0x2039, 0x18b9: 0x0269, 0x18ba: 0x01d9, 0x18bb: 0x0fa9,\n\t0x18bc: 0x0fb9, 0x18bd: 0x1089, 0x18be: 0x0279, 0x18bf: 0x0369,\n\t// Block 0x63, offset 0x18c0\n\t0x18c0: 0x0289, 0x18c1: 0x13d1, 0x18c2: 0x0039, 0x18c3: 0x0ee9, 0x18c4: 0x1159, 0x18c5: 0x0ef9,\n\t0x18c6: 0x0f09, 0x18c7: 0x1199, 0x18c8: 0x0f31, 0x18c9: 0x0249, 0x18ca: 0x0f41, 0x18cb: 0x0259,\n\t0x18cc: 0x0f51, 0x18cd: 0x0359, 0x18ce: 0x0f61, 0x18cf: 0x0f71, 0x18d0: 0x00d9, 0x18d1: 0x0f99,\n\t0x18d2: 0x2039, 0x18d3: 0x0269, 0x18d4: 0x01d9, 0x18d5: 0x0fa9, 0x18d6: 0x0fb9, 0x18d7: 0x1089,\n\t0x18d8: 0x0279, 0x18d9: 0x0369, 0x18da: 0x0289, 0x18db: 0x13d1, 0x18dc: 0x0039, 0x18dd: 0x0040,\n\t0x18de: 0x1159, 0x18df: 0x0ef9, 0x18e0: 0x0040, 0x18e1: 0x0040, 0x18e2: 0x0f31, 0x18e3: 0x0040,\n\t0x18e4: 0x0040, 0x18e5: 0x0259, 0x18e6: 0x0f51, 0x18e7: 0x0040, 0x18e8: 0x0040, 0x18e9: 0x0f71,\n\t0x18ea: 0x00d9, 0x18eb: 0x0f99, 0x18ec: 0x2039, 0x18ed: 0x0040, 0x18ee: 0x01d9, 0x18ef: 0x0fa9,\n\t0x18f0: 0x0fb9, 0x18f1: 0x1089, 0x18f2: 0x0279, 0x18f3: 0x0369, 0x18f4: 0x0289, 0x18f5: 0x13d1,\n\t0x18f6: 0x0039, 0x18f7: 0x0ee9, 0x18f8: 0x1159, 0x18f9: 0x0ef9, 0x18fa: 0x0040, 0x18fb: 0x1199,\n\t0x18fc: 0x0040, 0x18fd: 0x0249, 0x18fe: 0x0f41, 0x18ff: 0x0259,\n\t// Block 0x64, offset 0x1900\n\t0x1900: 0x0f51, 0x1901: 0x0359, 0x1902: 0x0f61, 0x1903: 0x0f71, 0x1904: 0x0040, 0x1905: 0x0f99,\n\t0x1906: 0x2039, 0x1907: 0x0269, 0x1908: 0x01d9, 0x1909: 0x0fa9, 0x190a: 0x0fb9, 0x190b: 0x1089,\n\t0x190c: 0x0279, 0x190d: 0x0369, 0x190e: 0x0289, 0x190f: 0x13d1, 0x1910: 0x0039, 0x1911: 0x0ee9,\n\t0x1912: 0x1159, 0x1913: 0x0ef9, 0x1914: 0x0f09, 0x1915: 0x1199, 0x1916: 0x0f31, 0x1917: 0x0249,\n\t0x1918: 0x0f41, 0x1919: 0x0259, 0x191a: 0x0f51, 0x191b: 0x0359, 0x191c: 0x0f61, 0x191d: 0x0f71,\n\t0x191e: 0x00d9, 0x191f: 0x0f99, 0x1920: 0x2039, 0x1921: 0x0269, 0x1922: 0x01d9, 0x1923: 0x0fa9,\n\t0x1924: 0x0fb9, 0x1925: 0x1089, 0x1926: 0x0279, 0x1927: 0x0369, 0x1928: 0x0289, 0x1929: 0x13d1,\n\t0x192a: 0x0039, 0x192b: 0x0ee9, 0x192c: 0x1159, 0x192d: 0x0ef9, 0x192e: 0x0f09, 0x192f: 0x1199,\n\t0x1930: 0x0f31, 0x1931: 0x0249, 0x1932: 0x0f41, 0x1933: 0x0259, 0x1934: 0x0f51, 0x1935: 0x0359,\n\t0x1936: 0x0f61, 0x1937: 0x0f71, 0x1938: 0x00d9, 0x1939: 0x0f99, 0x193a: 0x2039, 0x193b: 0x0269,\n\t0x193c: 0x01d9, 0x193d: 0x0fa9, 0x193e: 0x0fb9, 0x193f: 0x1089,\n\t// Block 0x65, offset 0x1940\n\t0x1940: 0x0279, 0x1941: 0x0369, 0x1942: 0x0289, 0x1943: 0x13d1, 0x1944: 0x0039, 0x1945: 0x0ee9,\n\t0x1946: 0x0040, 0x1947: 0x0ef9, 0x1948: 0x0f09, 0x1949: 0x1199, 0x194a: 0x0f31, 0x194b: 0x0040,\n\t0x194c: 0x0040, 0x194d: 0x0259, 0x194e: 0x0f51, 0x194f: 0x0359, 0x1950: 0x0f61, 0x1951: 0x0f71,\n\t0x1952: 0x00d9, 0x1953: 0x0f99, 0x1954: 0x2039, 0x1955: 0x0040, 0x1956: 0x01d9, 0x1957: 0x0fa9,\n\t0x1958: 0x0fb9, 0x1959: 0x1089, 0x195a: 0x0279, 0x195b: 0x0369, 0x195c: 0x0289, 0x195d: 0x0040,\n\t0x195e: 0x0039, 0x195f: 0x0ee9, 0x1960: 0x1159, 0x1961: 0x0ef9, 0x1962: 0x0f09, 0x1963: 0x1199,\n\t0x1964: 0x0f31, 0x1965: 0x0249, 0x1966: 0x0f41, 0x1967: 0x0259, 0x1968: 0x0f51, 0x1969: 0x0359,\n\t0x196a: 0x0f61, 0x196b: 0x0f71, 0x196c: 0x00d9, 0x196d: 0x0f99, 0x196e: 0x2039, 0x196f: 0x0269,\n\t0x1970: 0x01d9, 0x1971: 0x0fa9, 0x1972: 0x0fb9, 0x1973: 0x1089, 0x1974: 0x0279, 0x1975: 0x0369,\n\t0x1976: 0x0289, 0x1977: 0x13d1, 0x1978: 0x0039, 0x1979: 0x0ee9, 0x197a: 0x0040, 0x197b: 0x0ef9,\n\t0x197c: 0x0f09, 0x197d: 0x1199, 0x197e: 0x0f31, 0x197f: 0x0040,\n\t// Block 0x66, offset 0x1980\n\t0x1980: 0x0f41, 0x1981: 0x0259, 0x1982: 0x0f51, 0x1983: 0x0359, 0x1984: 0x0f61, 0x1985: 0x0040,\n\t0x1986: 0x00d9, 0x1987: 0x0040, 0x1988: 0x0040, 0x1989: 0x0040, 0x198a: 0x01d9, 0x198b: 0x0fa9,\n\t0x198c: 0x0fb9, 0x198d: 0x1089, 0x198e: 0x0279, 0x198f: 0x0369, 0x1990: 0x0289, 0x1991: 0x0040,\n\t0x1992: 0x0039, 0x1993: 0x0ee9, 0x1994: 0x1159, 0x1995: 0x0ef9, 0x1996: 0x0f09, 0x1997: 0x1199,\n\t0x1998: 0x0f31, 0x1999: 0x0249, 0x199a: 0x0f41, 0x199b: 0x0259, 0x199c: 0x0f51, 0x199d: 0x0359,\n\t0x199e: 0x0f61, 0x199f: 0x0f71, 0x19a0: 0x00d9, 0x19a1: 0x0f99, 0x19a2: 0x2039, 0x19a3: 0x0269,\n\t0x19a4: 0x01d9, 0x19a5: 0x0fa9, 0x19a6: 0x0fb9, 0x19a7: 0x1089, 0x19a8: 0x0279, 0x19a9: 0x0369,\n\t0x19aa: 0x0289, 0x19ab: 0x13d1, 0x19ac: 0x0039, 0x19ad: 0x0ee9, 0x19ae: 0x1159, 0x19af: 0x0ef9,\n\t0x19b0: 0x0f09, 0x19b1: 0x1199, 0x19b2: 0x0f31, 0x19b3: 0x0249, 0x19b4: 0x0f41, 0x19b5: 0x0259,\n\t0x19b6: 0x0f51, 0x19b7: 0x0359, 0x19b8: 0x0f61, 0x19b9: 0x0f71, 0x19ba: 0x00d9, 0x19bb: 0x0f99,\n\t0x19bc: 0x2039, 0x19bd: 0x0269, 0x19be: 0x01d9, 0x19bf: 0x0fa9,\n\t// Block 0x67, offset 0x19c0\n\t0x19c0: 0x0fb9, 0x19c1: 0x1089, 0x19c2: 0x0279, 0x19c3: 0x0369, 0x19c4: 0x0289, 0x19c5: 0x13d1,\n\t0x19c6: 0x0039, 0x19c7: 0x0ee9, 0x19c8: 0x1159, 0x19c9: 0x0ef9, 0x19ca: 0x0f09, 0x19cb: 0x1199,\n\t0x19cc: 0x0f31, 0x19cd: 0x0249, 0x19ce: 0x0f41, 0x19cf: 0x0259, 0x19d0: 0x0f51, 0x19d1: 0x0359,\n\t0x19d2: 0x0f61, 0x19d3: 0x0f71, 0x19d4: 0x00d9, 0x19d5: 0x0f99, 0x19d6: 0x2039, 0x19d7: 0x0269,\n\t0x19d8: 0x01d9, 0x19d9: 0x0fa9, 0x19da: 0x0fb9, 0x19db: 0x1089, 0x19dc: 0x0279, 0x19dd: 0x0369,\n\t0x19de: 0x0289, 0x19df: 0x13d1, 0x19e0: 0x0039, 0x19e1: 0x0ee9, 0x19e2: 0x1159, 0x19e3: 0x0ef9,\n\t0x19e4: 0x0f09, 0x19e5: 0x1199, 0x19e6: 0x0f31, 0x19e7: 0x0249, 0x19e8: 0x0f41, 0x19e9: 0x0259,\n\t0x19ea: 0x0f51, 0x19eb: 0x0359, 0x19ec: 0x0f61, 0x19ed: 0x0f71, 0x19ee: 0x00d9, 0x19ef: 0x0f99,\n\t0x19f0: 0x2039, 0x19f1: 0x0269, 0x19f2: 0x01d9, 0x19f3: 0x0fa9, 0x19f4: 0x0fb9, 0x19f5: 0x1089,\n\t0x19f6: 0x0279, 0x19f7: 0x0369, 0x19f8: 0x0289, 0x19f9: 0x13d1, 0x19fa: 0x0039, 0x19fb: 0x0ee9,\n\t0x19fc: 0x1159, 0x19fd: 0x0ef9, 0x19fe: 0x0f09, 0x19ff: 0x1199,\n\t// Block 0x68, offset 0x1a00\n\t0x1a00: 0x0f31, 0x1a01: 0x0249, 0x1a02: 0x0f41, 0x1a03: 0x0259, 0x1a04: 0x0f51, 0x1a05: 0x0359,\n\t0x1a06: 0x0f61, 0x1a07: 0x0f71, 0x1a08: 0x00d9, 0x1a09: 0x0f99, 0x1a0a: 0x2039, 0x1a0b: 0x0269,\n\t0x1a0c: 0x01d9, 0x1a0d: 0x0fa9, 0x1a0e: 0x0fb9, 0x1a0f: 0x1089, 0x1a10: 0x0279, 0x1a11: 0x0369,\n\t0x1a12: 0x0289, 0x1a13: 0x13d1, 0x1a14: 0x0039, 0x1a15: 0x0ee9, 0x1a16: 0x1159, 0x1a17: 0x0ef9,\n\t0x1a18: 0x0f09, 0x1a19: 0x1199, 0x1a1a: 0x0f31, 0x1a1b: 0x0249, 0x1a1c: 0x0f41, 0x1a1d: 0x0259,\n\t0x1a1e: 0x0f51, 0x1a1f: 0x0359, 0x1a20: 0x0f61, 0x1a21: 0x0f71, 0x1a22: 0x00d9, 0x1a23: 0x0f99,\n\t0x1a24: 0x2039, 0x1a25: 0x0269, 0x1a26: 0x01d9, 0x1a27: 0x0fa9, 0x1a28: 0x0fb9, 0x1a29: 0x1089,\n\t0x1a2a: 0x0279, 0x1a2b: 0x0369, 0x1a2c: 0x0289, 0x1a2d: 0x13d1, 0x1a2e: 0x0039, 0x1a2f: 0x0ee9,\n\t0x1a30: 0x1159, 0x1a31: 0x0ef9, 0x1a32: 0x0f09, 0x1a33: 0x1199, 0x1a34: 0x0f31, 0x1a35: 0x0249,\n\t0x1a36: 0x0f41, 0x1a37: 0x0259, 0x1a38: 0x0f51, 0x1a39: 0x0359, 0x1a3a: 0x0f61, 0x1a3b: 0x0f71,\n\t0x1a3c: 0x00d9, 0x1a3d: 0x0f99, 0x1a3e: 0x2039, 0x1a3f: 0x0269,\n\t// Block 0x69, offset 0x1a40\n\t0x1a40: 0x01d9, 0x1a41: 0x0fa9, 0x1a42: 0x0fb9, 0x1a43: 0x1089, 0x1a44: 0x0279, 0x1a45: 0x0369,\n\t0x1a46: 0x0289, 0x1a47: 0x13d1, 0x1a48: 0x0039, 0x1a49: 0x0ee9, 0x1a4a: 0x1159, 0x1a4b: 0x0ef9,\n\t0x1a4c: 0x0f09, 0x1a4d: 0x1199, 0x1a4e: 0x0f31, 0x1a4f: 0x0249, 0x1a50: 0x0f41, 0x1a51: 0x0259,\n\t0x1a52: 0x0f51, 0x1a53: 0x0359, 0x1a54: 0x0f61, 0x1a55: 0x0f71, 0x1a56: 0x00d9, 0x1a57: 0x0f99,\n\t0x1a58: 0x2039, 0x1a59: 0x0269, 0x1a5a: 0x01d9, 0x1a5b: 0x0fa9, 0x1a5c: 0x0fb9, 0x1a5d: 0x1089,\n\t0x1a5e: 0x0279, 0x1a5f: 0x0369, 0x1a60: 0x0289, 0x1a61: 0x13d1, 0x1a62: 0x0039, 0x1a63: 0x0ee9,\n\t0x1a64: 0x1159, 0x1a65: 0x0ef9, 0x1a66: 0x0f09, 0x1a67: 0x1199, 0x1a68: 0x0f31, 0x1a69: 0x0249,\n\t0x1a6a: 0x0f41, 0x1a6b: 0x0259, 0x1a6c: 0x0f51, 0x1a6d: 0x0359, 0x1a6e: 0x0f61, 0x1a6f: 0x0f71,\n\t0x1a70: 0x00d9, 0x1a71: 0x0f99, 0x1a72: 0x2039, 0x1a73: 0x0269, 0x1a74: 0x01d9, 0x1a75: 0x0fa9,\n\t0x1a76: 0x0fb9, 0x1a77: 0x1089, 0x1a78: 0x0279, 0x1a79: 0x0369, 0x1a7a: 0x0289, 0x1a7b: 0x13d1,\n\t0x1a7c: 0x0039, 0x1a7d: 0x0ee9, 0x1a7e: 0x1159, 0x1a7f: 0x0ef9,\n\t// Block 0x6a, offset 0x1a80\n\t0x1a80: 0x0f09, 0x1a81: 0x1199, 0x1a82: 0x0f31, 0x1a83: 0x0249, 0x1a84: 0x0f41, 0x1a85: 0x0259,\n\t0x1a86: 0x0f51, 0x1a87: 0x0359, 0x1a88: 0x0f61, 0x1a89: 0x0f71, 0x1a8a: 0x00d9, 0x1a8b: 0x0f99,\n\t0x1a8c: 0x2039, 0x1a8d: 0x0269, 0x1a8e: 0x01d9, 0x1a8f: 0x0fa9, 0x1a90: 0x0fb9, 0x1a91: 0x1089,\n\t0x1a92: 0x0279, 0x1a93: 0x0369, 0x1a94: 0x0289, 0x1a95: 0x13d1, 0x1a96: 0x0039, 0x1a97: 0x0ee9,\n\t0x1a98: 0x1159, 0x1a99: 0x0ef9, 0x1a9a: 0x0f09, 0x1a9b: 0x1199, 0x1a9c: 0x0f31, 0x1a9d: 0x0249,\n\t0x1a9e: 0x0f41, 0x1a9f: 0x0259, 0x1aa0: 0x0f51, 0x1aa1: 0x0359, 0x1aa2: 0x0f61, 0x1aa3: 0x0f71,\n\t0x1aa4: 0x00d9, 0x1aa5: 0x0f99, 0x1aa6: 0x2039, 0x1aa7: 0x0269, 0x1aa8: 0x01d9, 0x1aa9: 0x0fa9,\n\t0x1aaa: 0x0fb9, 0x1aab: 0x1089, 0x1aac: 0x0279, 0x1aad: 0x0369, 0x1aae: 0x0289, 0x1aaf: 0x13d1,\n\t0x1ab0: 0x0039, 0x1ab1: 0x0ee9, 0x1ab2: 0x1159, 0x1ab3: 0x0ef9, 0x1ab4: 0x0f09, 0x1ab5: 0x1199,\n\t0x1ab6: 0x0f31, 0x1ab7: 0x0249, 0x1ab8: 0x0f41, 0x1ab9: 0x0259, 0x1aba: 0x0f51, 0x1abb: 0x0359,\n\t0x1abc: 0x0f61, 0x1abd: 0x0f71, 0x1abe: 0x00d9, 0x1abf: 0x0f99,\n\t// Block 0x6b, offset 0x1ac0\n\t0x1ac0: 0x2039, 0x1ac1: 0x0269, 0x1ac2: 0x01d9, 0x1ac3: 0x0fa9, 0x1ac4: 0x0fb9, 0x1ac5: 0x1089,\n\t0x1ac6: 0x0279, 0x1ac7: 0x0369, 0x1ac8: 0x0289, 0x1ac9: 0x13d1, 0x1aca: 0x0039, 0x1acb: 0x0ee9,\n\t0x1acc: 0x1159, 0x1acd: 0x0ef9, 0x1ace: 0x0f09, 0x1acf: 0x1199, 0x1ad0: 0x0f31, 0x1ad1: 0x0249,\n\t0x1ad2: 0x0f41, 0x1ad3: 0x0259, 0x1ad4: 0x0f51, 0x1ad5: 0x0359, 0x1ad6: 0x0f61, 0x1ad7: 0x0f71,\n\t0x1ad8: 0x00d9, 0x1ad9: 0x0f99, 0x1ada: 0x2039, 0x1adb: 0x0269, 0x1adc: 0x01d9, 0x1add: 0x0fa9,\n\t0x1ade: 0x0fb9, 0x1adf: 0x1089, 0x1ae0: 0x0279, 0x1ae1: 0x0369, 0x1ae2: 0x0289, 0x1ae3: 0x13d1,\n\t0x1ae4: 0xba81, 0x1ae5: 0xba99, 0x1ae6: 0x0040, 0x1ae7: 0x0040, 0x1ae8: 0xbab1, 0x1ae9: 0x1099,\n\t0x1aea: 0x10b1, 0x1aeb: 0x10c9, 0x1aec: 0xbac9, 0x1aed: 0xbae1, 0x1aee: 0xbaf9, 0x1aef: 0x1429,\n\t0x1af0: 0x1a31, 0x1af1: 0xbb11, 0x1af2: 0xbb29, 0x1af3: 0xbb41, 0x1af4: 0xbb59, 0x1af5: 0xbb71,\n\t0x1af6: 0xbb89, 0x1af7: 0x2109, 0x1af8: 0x1111, 0x1af9: 0x1429, 0x1afa: 0xbba1, 0x1afb: 0xbbb9,\n\t0x1afc: 0xbbd1, 0x1afd: 0x10e1, 0x1afe: 0x10f9, 0x1aff: 0xbbe9,\n\t// Block 0x6c, offset 0x1b00\n\t0x1b00: 0x2079, 0x1b01: 0xbc01, 0x1b02: 0xbab1, 0x1b03: 0x1099, 0x1b04: 0x10b1, 0x1b05: 0x10c9,\n\t0x1b06: 0xbac9, 0x1b07: 0xbae1, 0x1b08: 0xbaf9, 0x1b09: 0x1429, 0x1b0a: 0x1a31, 0x1b0b: 0xbb11,\n\t0x1b0c: 0xbb29, 0x1b0d: 0xbb41, 0x1b0e: 0xbb59, 0x1b0f: 0xbb71, 0x1b10: 0xbb89, 0x1b11: 0x2109,\n\t0x1b12: 0x1111, 0x1b13: 0xbba1, 0x1b14: 0xbba1, 0x1b15: 0xbbb9, 0x1b16: 0xbbd1, 0x1b17: 0x10e1,\n\t0x1b18: 0x10f9, 0x1b19: 0xbbe9, 0x1b1a: 0x2079, 0x1b1b: 0xbc21, 0x1b1c: 0xbac9, 0x1b1d: 0x1429,\n\t0x1b1e: 0xbb11, 0x1b1f: 0x10e1, 0x1b20: 0x1111, 0x1b21: 0x2109, 0x1b22: 0xbab1, 0x1b23: 0x1099,\n\t0x1b24: 0x10b1, 0x1b25: 0x10c9, 0x1b26: 0xbac9, 0x1b27: 0xbae1, 0x1b28: 0xbaf9, 0x1b29: 0x1429,\n\t0x1b2a: 0x1a31, 0x1b2b: 0xbb11, 0x1b2c: 0xbb29, 0x1b2d: 0xbb41, 0x1b2e: 0xbb59, 0x1b2f: 0xbb71,\n\t0x1b30: 0xbb89, 0x1b31: 0x2109, 0x1b32: 0x1111, 0x1b33: 0x1429, 0x1b34: 0xbba1, 0x1b35: 0xbbb9,\n\t0x1b36: 0xbbd1, 0x1b37: 0x10e1, 0x1b38: 0x10f9, 0x1b39: 0xbbe9, 0x1b3a: 0x2079, 0x1b3b: 0xbc01,\n\t0x1b3c: 0xbab1, 0x1b3d: 0x1099, 0x1b3e: 0x10b1, 0x1b3f: 0x10c9,\n\t// Block 0x6d, offset 0x1b40\n\t0x1b40: 0xbac9, 0x1b41: 0xbae1, 0x1b42: 0xbaf9, 0x1b43: 0x1429, 0x1b44: 0x1a31, 0x1b45: 0xbb11,\n\t0x1b46: 0xbb29, 0x1b47: 0xbb41, 0x1b48: 0xbb59, 0x1b49: 0xbb71, 0x1b4a: 0xbb89, 0x1b4b: 0x2109,\n\t0x1b4c: 0x1111, 0x1b4d: 0xbba1, 0x1b4e: 0xbba1, 0x1b4f: 0xbbb9, 0x1b50: 0xbbd1, 0x1b51: 0x10e1,\n\t0x1b52: 0x10f9, 0x1b53: 0xbbe9, 0x1b54: 0x2079, 0x1b55: 0xbc21, 0x1b56: 0xbac9, 0x1b57: 0x1429,\n\t0x1b58: 0xbb11, 0x1b59: 0x10e1, 0x1b5a: 0x1111, 0x1b5b: 0x2109, 0x1b5c: 0xbab1, 0x1b5d: 0x1099,\n\t0x1b5e: 0x10b1, 0x1b5f: 0x10c9, 0x1b60: 0xbac9, 0x1b61: 0xbae1, 0x1b62: 0xbaf9, 0x1b63: 0x1429,\n\t0x1b64: 0x1a31, 0x1b65: 0xbb11, 0x1b66: 0xbb29, 0x1b67: 0xbb41, 0x1b68: 0xbb59, 0x1b69: 0xbb71,\n\t0x1b6a: 0xbb89, 0x1b6b: 0x2109, 0x1b6c: 0x1111, 0x1b6d: 0x1429, 0x1b6e: 0xbba1, 0x1b6f: 0xbbb9,\n\t0x1b70: 0xbbd1, 0x1b71: 0x10e1, 0x1b72: 0x10f9, 0x1b73: 0xbbe9, 0x1b74: 0x2079, 0x1b75: 0xbc01,\n\t0x1b76: 0xbab1, 0x1b77: 0x1099, 0x1b78: 0x10b1, 0x1b79: 0x10c9, 0x1b7a: 0xbac9, 0x1b7b: 0xbae1,\n\t0x1b7c: 0xbaf9, 0x1b7d: 0x1429, 0x1b7e: 0x1a31, 0x1b7f: 0xbb11,\n\t// Block 0x6e, offset 0x1b80\n\t0x1b80: 0xbb29, 0x1b81: 0xbb41, 0x1b82: 0xbb59, 0x1b83: 0xbb71, 0x1b84: 0xbb89, 0x1b85: 0x2109,\n\t0x1b86: 0x1111, 0x1b87: 0xbba1, 0x1b88: 0xbba1, 0x1b89: 0xbbb9, 0x1b8a: 0xbbd1, 0x1b8b: 0x10e1,\n\t0x1b8c: 0x10f9, 0x1b8d: 0xbbe9, 0x1b8e: 0x2079, 0x1b8f: 0xbc21, 0x1b90: 0xbac9, 0x1b91: 0x1429,\n\t0x1b92: 0xbb11, 0x1b93: 0x10e1, 0x1b94: 0x1111, 0x1b95: 0x2109, 0x1b96: 0xbab1, 0x1b97: 0x1099,\n\t0x1b98: 0x10b1, 0x1b99: 0x10c9, 0x1b9a: 0xbac9, 0x1b9b: 0xbae1, 0x1b9c: 0xbaf9, 0x1b9d: 0x1429,\n\t0x1b9e: 0x1a31, 0x1b9f: 0xbb11, 0x1ba0: 0xbb29, 0x1ba1: 0xbb41, 0x1ba2: 0xbb59, 0x1ba3: 0xbb71,\n\t0x1ba4: 0xbb89, 0x1ba5: 0x2109, 0x1ba6: 0x1111, 0x1ba7: 0x1429, 0x1ba8: 0xbba1, 0x1ba9: 0xbbb9,\n\t0x1baa: 0xbbd1, 0x1bab: 0x10e1, 0x1bac: 0x10f9, 0x1bad: 0xbbe9, 0x1bae: 0x2079, 0x1baf: 0xbc01,\n\t0x1bb0: 0xbab1, 0x1bb1: 0x1099, 0x1bb2: 0x10b1, 0x1bb3: 0x10c9, 0x1bb4: 0xbac9, 0x1bb5: 0xbae1,\n\t0x1bb6: 0xbaf9, 0x1bb7: 0x1429, 0x1bb8: 0x1a31, 0x1bb9: 0xbb11, 0x1bba: 0xbb29, 0x1bbb: 0xbb41,\n\t0x1bbc: 0xbb59, 0x1bbd: 0xbb71, 0x1bbe: 0xbb89, 0x1bbf: 0x2109,\n\t// Block 0x6f, offset 0x1bc0\n\t0x1bc0: 0x1111, 0x1bc1: 0xbba1, 0x1bc2: 0xbba1, 0x1bc3: 0xbbb9, 0x1bc4: 0xbbd1, 0x1bc5: 0x10e1,\n\t0x1bc6: 0x10f9, 0x1bc7: 0xbbe9, 0x1bc8: 0x2079, 0x1bc9: 0xbc21, 0x1bca: 0xbac9, 0x1bcb: 0x1429,\n\t0x1bcc: 0xbb11, 0x1bcd: 0x10e1, 0x1bce: 0x1111, 0x1bcf: 0x2109, 0x1bd0: 0xbab1, 0x1bd1: 0x1099,\n\t0x1bd2: 0x10b1, 0x1bd3: 0x10c9, 0x1bd4: 0xbac9, 0x1bd5: 0xbae1, 0x1bd6: 0xbaf9, 0x1bd7: 0x1429,\n\t0x1bd8: 0x1a31, 0x1bd9: 0xbb11, 0x1bda: 0xbb29, 0x1bdb: 0xbb41, 0x1bdc: 0xbb59, 0x1bdd: 0xbb71,\n\t0x1bde: 0xbb89, 0x1bdf: 0x2109, 0x1be0: 0x1111, 0x1be1: 0x1429, 0x1be2: 0xbba1, 0x1be3: 0xbbb9,\n\t0x1be4: 0xbbd1, 0x1be5: 0x10e1, 0x1be6: 0x10f9, 0x1be7: 0xbbe9, 0x1be8: 0x2079, 0x1be9: 0xbc01,\n\t0x1bea: 0xbab1, 0x1beb: 0x1099, 0x1bec: 0x10b1, 0x1bed: 0x10c9, 0x1bee: 0xbac9, 0x1bef: 0xbae1,\n\t0x1bf0: 0xbaf9, 0x1bf1: 0x1429, 0x1bf2: 0x1a31, 0x1bf3: 0xbb11, 0x1bf4: 0xbb29, 0x1bf5: 0xbb41,\n\t0x1bf6: 0xbb59, 0x1bf7: 0xbb71, 0x1bf8: 0xbb89, 0x1bf9: 0x2109, 0x1bfa: 0x1111, 0x1bfb: 0xbba1,\n\t0x1bfc: 0xbba1, 0x1bfd: 0xbbb9, 0x1bfe: 0xbbd1, 0x1bff: 0x10e1,\n\t// Block 0x70, offset 0x1c00\n\t0x1c00: 0x10f9, 0x1c01: 0xbbe9, 0x1c02: 0x2079, 0x1c03: 0xbc21, 0x1c04: 0xbac9, 0x1c05: 0x1429,\n\t0x1c06: 0xbb11, 0x1c07: 0x10e1, 0x1c08: 0x1111, 0x1c09: 0x2109, 0x1c0a: 0xbc41, 0x1c0b: 0xbc41,\n\t0x1c0c: 0x0040, 0x1c0d: 0x0040, 0x1c0e: 0x1f41, 0x1c0f: 0x00c9, 0x1c10: 0x0069, 0x1c11: 0x0079,\n\t0x1c12: 0x1f51, 0x1c13: 0x1f61, 0x1c14: 0x1f71, 0x1c15: 0x1f81, 0x1c16: 0x1f91, 0x1c17: 0x1fa1,\n\t0x1c18: 0x1f41, 0x1c19: 0x00c9, 0x1c1a: 0x0069, 0x1c1b: 0x0079, 0x1c1c: 0x1f51, 0x1c1d: 0x1f61,\n\t0x1c1e: 0x1f71, 0x1c1f: 0x1f81, 0x1c20: 0x1f91, 0x1c21: 0x1fa1, 0x1c22: 0x1f41, 0x1c23: 0x00c9,\n\t0x1c24: 0x0069, 0x1c25: 0x0079, 0x1c26: 0x1f51, 0x1c27: 0x1f61, 0x1c28: 0x1f71, 0x1c29: 0x1f81,\n\t0x1c2a: 0x1f91, 0x1c2b: 0x1fa1, 0x1c2c: 0x1f41, 0x1c2d: 0x00c9, 0x1c2e: 0x0069, 0x1c2f: 0x0079,\n\t0x1c30: 0x1f51, 0x1c31: 0x1f61, 0x1c32: 0x1f71, 0x1c33: 0x1f81, 0x1c34: 0x1f91, 0x1c35: 0x1fa1,\n\t0x1c36: 0x1f41, 0x1c37: 0x00c9, 0x1c38: 0x0069, 0x1c39: 0x0079, 0x1c3a: 0x1f51, 0x1c3b: 0x1f61,\n\t0x1c3c: 0x1f71, 0x1c3d: 0x1f81, 0x1c3e: 0x1f91, 0x1c3f: 0x1fa1,\n\t// Block 0x71, offset 0x1c40\n\t0x1c40: 0xe115, 0x1c41: 0xe115, 0x1c42: 0xe135, 0x1c43: 0xe135, 0x1c44: 0xe115, 0x1c45: 0xe115,\n\t0x1c46: 0xe175, 0x1c47: 0xe175, 0x1c48: 0xe115, 0x1c49: 0xe115, 0x1c4a: 0xe135, 0x1c4b: 0xe135,\n\t0x1c4c: 0xe115, 0x1c4d: 0xe115, 0x1c4e: 0xe1f5, 0x1c4f: 0xe1f5, 0x1c50: 0xe115, 0x1c51: 0xe115,\n\t0x1c52: 0xe135, 0x1c53: 0xe135, 0x1c54: 0xe115, 0x1c55: 0xe115, 0x1c56: 0xe175, 0x1c57: 0xe175,\n\t0x1c58: 0xe115, 0x1c59: 0xe115, 0x1c5a: 0xe135, 0x1c5b: 0xe135, 0x1c5c: 0xe115, 0x1c5d: 0xe115,\n\t0x1c5e: 0x8b3d, 0x1c5f: 0x8b3d, 0x1c60: 0x04b5, 0x1c61: 0x04b5, 0x1c62: 0x0a08, 0x1c63: 0x0a08,\n\t0x1c64: 0x0a08, 0x1c65: 0x0a08, 0x1c66: 0x0a08, 0x1c67: 0x0a08, 0x1c68: 0x0a08, 0x1c69: 0x0a08,\n\t0x1c6a: 0x0a08, 0x1c6b: 0x0a08, 0x1c6c: 0x0a08, 0x1c6d: 0x0a08, 0x1c6e: 0x0a08, 0x1c6f: 0x0a08,\n\t0x1c70: 0x0a08, 0x1c71: 0x0a08, 0x1c72: 0x0a08, 0x1c73: 0x0a08, 0x1c74: 0x0a08, 0x1c75: 0x0a08,\n\t0x1c76: 0x0a08, 0x1c77: 0x0a08, 0x1c78: 0x0a08, 0x1c79: 0x0a08, 0x1c7a: 0x0a08, 0x1c7b: 0x0a08,\n\t0x1c7c: 0x0a08, 0x1c7d: 0x0a08, 0x1c7e: 0x0a08, 0x1c7f: 0x0a08,\n\t// Block 0x72, offset 0x1c80\n\t0x1c80: 0xb189, 0x1c81: 0xb1a1, 0x1c82: 0xb201, 0x1c83: 0xb249, 0x1c84: 0x0040, 0x1c85: 0xb411,\n\t0x1c86: 0xb291, 0x1c87: 0xb219, 0x1c88: 0xb309, 0x1c89: 0xb429, 0x1c8a: 0xb399, 0x1c8b: 0xb3b1,\n\t0x1c8c: 0xb3c9, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0xb369, 0x1c91: 0xb2d9,\n\t0x1c92: 0xb381, 0x1c93: 0xb279, 0x1c94: 0xb2c1, 0x1c95: 0xb1d1, 0x1c96: 0xb1e9, 0x1c97: 0xb231,\n\t0x1c98: 0xb261, 0x1c99: 0xb2f1, 0x1c9a: 0xb321, 0x1c9b: 0xb351, 0x1c9c: 0xbc59, 0x1c9d: 0x7949,\n\t0x1c9e: 0xbc71, 0x1c9f: 0xbc89, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0x0040,\n\t0x1ca4: 0xb3f9, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0xb219, 0x1ca8: 0x0040, 0x1ca9: 0xb429,\n\t0x1caa: 0xb399, 0x1cab: 0xb3b1, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339,\n\t0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0x0040, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1,\n\t0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0x0040, 0x1cb9: 0xb2f1, 0x1cba: 0x0040, 0x1cbb: 0xb351,\n\t0x1cbc: 0x0040, 0x1cbd: 0x0040, 0x1cbe: 0x0040, 0x1cbf: 0x0040,\n\t// Block 0x73, offset 0x1cc0\n\t0x1cc0: 0x0040, 0x1cc1: 0x0040, 0x1cc2: 0xb201, 0x1cc3: 0x0040, 0x1cc4: 0x0040, 0x1cc5: 0x0040,\n\t0x1cc6: 0x0040, 0x1cc7: 0xb219, 0x1cc8: 0x0040, 0x1cc9: 0xb429, 0x1cca: 0x0040, 0x1ccb: 0xb3b1,\n\t0x1ccc: 0x0040, 0x1ccd: 0xb3e1, 0x1cce: 0xb2a9, 0x1ccf: 0xb339, 0x1cd0: 0x0040, 0x1cd1: 0xb2d9,\n\t0x1cd2: 0xb381, 0x1cd3: 0x0040, 0x1cd4: 0xb2c1, 0x1cd5: 0x0040, 0x1cd6: 0x0040, 0x1cd7: 0xb231,\n\t0x1cd8: 0x0040, 0x1cd9: 0xb2f1, 0x1cda: 0x0040, 0x1cdb: 0xb351, 0x1cdc: 0x0040, 0x1cdd: 0x7949,\n\t0x1cde: 0x0040, 0x1cdf: 0xbc89, 0x1ce0: 0x0040, 0x1ce1: 0xb1a1, 0x1ce2: 0xb201, 0x1ce3: 0x0040,\n\t0x1ce4: 0xb3f9, 0x1ce5: 0x0040, 0x1ce6: 0x0040, 0x1ce7: 0xb219, 0x1ce8: 0xb309, 0x1ce9: 0xb429,\n\t0x1cea: 0xb399, 0x1ceb: 0x0040, 0x1cec: 0xb3c9, 0x1ced: 0xb3e1, 0x1cee: 0xb2a9, 0x1cef: 0xb339,\n\t0x1cf0: 0xb369, 0x1cf1: 0xb2d9, 0x1cf2: 0xb381, 0x1cf3: 0x0040, 0x1cf4: 0xb2c1, 0x1cf5: 0xb1d1,\n\t0x1cf6: 0xb1e9, 0x1cf7: 0xb231, 0x1cf8: 0x0040, 0x1cf9: 0xb2f1, 0x1cfa: 0xb321, 0x1cfb: 0xb351,\n\t0x1cfc: 0xbc59, 0x1cfd: 0x0040, 0x1cfe: 0xbc71, 0x1cff: 0x0040,\n\t// Block 0x74, offset 0x1d00\n\t0x1d00: 0xb189, 0x1d01: 0xb1a1, 0x1d02: 0xb201, 0x1d03: 0xb249, 0x1d04: 0xb3f9, 0x1d05: 0xb411,\n\t0x1d06: 0xb291, 0x1d07: 0xb219, 0x1d08: 0xb309, 0x1d09: 0xb429, 0x1d0a: 0x0040, 0x1d0b: 0xb3b1,\n\t0x1d0c: 0xb3c9, 0x1d0d: 0xb3e1, 0x1d0e: 0xb2a9, 0x1d0f: 0xb339, 0x1d10: 0xb369, 0x1d11: 0xb2d9,\n\t0x1d12: 0xb381, 0x1d13: 0xb279, 0x1d14: 0xb2c1, 0x1d15: 0xb1d1, 0x1d16: 0xb1e9, 0x1d17: 0xb231,\n\t0x1d18: 0xb261, 0x1d19: 0xb2f1, 0x1d1a: 0xb321, 0x1d1b: 0xb351, 0x1d1c: 0x0040, 0x1d1d: 0x0040,\n\t0x1d1e: 0x0040, 0x1d1f: 0x0040, 0x1d20: 0x0040, 0x1d21: 0xb1a1, 0x1d22: 0xb201, 0x1d23: 0xb249,\n\t0x1d24: 0x0040, 0x1d25: 0xb411, 0x1d26: 0xb291, 0x1d27: 0xb219, 0x1d28: 0xb309, 0x1d29: 0xb429,\n\t0x1d2a: 0x0040, 0x1d2b: 0xb3b1, 0x1d2c: 0xb3c9, 0x1d2d: 0xb3e1, 0x1d2e: 0xb2a9, 0x1d2f: 0xb339,\n\t0x1d30: 0xb369, 0x1d31: 0xb2d9, 0x1d32: 0xb381, 0x1d33: 0xb279, 0x1d34: 0xb2c1, 0x1d35: 0xb1d1,\n\t0x1d36: 0xb1e9, 0x1d37: 0xb231, 0x1d38: 0xb261, 0x1d39: 0xb2f1, 0x1d3a: 0xb321, 0x1d3b: 0xb351,\n\t0x1d3c: 0x0040, 0x1d3d: 0x0040, 0x1d3e: 0x0040, 0x1d3f: 0x0040,\n\t// Block 0x75, offset 0x1d40\n\t0x1d40: 0x0040, 0x1d41: 0xbca2, 0x1d42: 0xbcba, 0x1d43: 0xbcd2, 0x1d44: 0xbcea, 0x1d45: 0xbd02,\n\t0x1d46: 0xbd1a, 0x1d47: 0xbd32, 0x1d48: 0xbd4a, 0x1d49: 0xbd62, 0x1d4a: 0xbd7a, 0x1d4b: 0x0018,\n\t0x1d4c: 0x0018, 0x1d4d: 0x0040, 0x1d4e: 0x0040, 0x1d4f: 0x0040, 0x1d50: 0xbd92, 0x1d51: 0xbdb2,\n\t0x1d52: 0xbdd2, 0x1d53: 0xbdf2, 0x1d54: 0xbe12, 0x1d55: 0xbe32, 0x1d56: 0xbe52, 0x1d57: 0xbe72,\n\t0x1d58: 0xbe92, 0x1d59: 0xbeb2, 0x1d5a: 0xbed2, 0x1d5b: 0xbef2, 0x1d5c: 0xbf12, 0x1d5d: 0xbf32,\n\t0x1d5e: 0xbf52, 0x1d5f: 0xbf72, 0x1d60: 0xbf92, 0x1d61: 0xbfb2, 0x1d62: 0xbfd2, 0x1d63: 0xbff2,\n\t0x1d64: 0xc012, 0x1d65: 0xc032, 0x1d66: 0xc052, 0x1d67: 0xc072, 0x1d68: 0xc092, 0x1d69: 0xc0b2,\n\t0x1d6a: 0xc0d1, 0x1d6b: 0x1159, 0x1d6c: 0x0269, 0x1d6d: 0x6671, 0x1d6e: 0xc111, 0x1d6f: 0x0018,\n\t0x1d70: 0x0039, 0x1d71: 0x0ee9, 0x1d72: 0x1159, 0x1d73: 0x0ef9, 0x1d74: 0x0f09, 0x1d75: 0x1199,\n\t0x1d76: 0x0f31, 0x1d77: 0x0249, 0x1d78: 0x0f41, 0x1d79: 0x0259, 0x1d7a: 0x0f51, 0x1d7b: 0x0359,\n\t0x1d7c: 0x0f61, 0x1d7d: 0x0f71, 0x1d7e: 0x00d9, 0x1d7f: 0x0f99,\n\t// Block 0x76, offset 0x1d80\n\t0x1d80: 0x2039, 0x1d81: 0x0269, 0x1d82: 0x01d9, 0x1d83: 0x0fa9, 0x1d84: 0x0fb9, 0x1d85: 0x1089,\n\t0x1d86: 0x0279, 0x1d87: 0x0369, 0x1d88: 0x0289, 0x1d89: 0x13d1, 0x1d8a: 0xc129, 0x1d8b: 0x65b1,\n\t0x1d8c: 0xc141, 0x1d8d: 0x1441, 0x1d8e: 0xc159, 0x1d8f: 0xc179, 0x1d90: 0x0018, 0x1d91: 0x0018,\n\t0x1d92: 0x0018, 0x1d93: 0x0018, 0x1d94: 0x0018, 0x1d95: 0x0018, 0x1d96: 0x0018, 0x1d97: 0x0018,\n\t0x1d98: 0x0018, 0x1d99: 0x0018, 0x1d9a: 0x0018, 0x1d9b: 0x0018, 0x1d9c: 0x0018, 0x1d9d: 0x0018,\n\t0x1d9e: 0x0018, 0x1d9f: 0x0018, 0x1da0: 0x0018, 0x1da1: 0x0018, 0x1da2: 0x0018, 0x1da3: 0x0018,\n\t0x1da4: 0x0018, 0x1da5: 0x0018, 0x1da6: 0x0018, 0x1da7: 0x0018, 0x1da8: 0x0018, 0x1da9: 0x0018,\n\t0x1daa: 0xc191, 0x1dab: 0xc1a9, 0x1dac: 0xc1c1, 0x1dad: 0x0040, 0x1dae: 0x0040, 0x1daf: 0x0040,\n\t0x1db0: 0x0018, 0x1db1: 0x0018, 0x1db2: 0x0018, 0x1db3: 0x0018, 0x1db4: 0x0018, 0x1db5: 0x0018,\n\t0x1db6: 0x0018, 0x1db7: 0x0018, 0x1db8: 0x0018, 0x1db9: 0x0018, 0x1dba: 0x0018, 0x1dbb: 0x0018,\n\t0x1dbc: 0x0018, 0x1dbd: 0x0018, 0x1dbe: 0x0018, 0x1dbf: 0x0018,\n\t// Block 0x77, offset 0x1dc0\n\t0x1dc0: 0xc1f1, 0x1dc1: 0xc229, 0x1dc2: 0xc261, 0x1dc3: 0x0040, 0x1dc4: 0x0040, 0x1dc5: 0x0040,\n\t0x1dc6: 0x0040, 0x1dc7: 0x0040, 0x1dc8: 0x0040, 0x1dc9: 0x0040, 0x1dca: 0x0040, 0x1dcb: 0x0040,\n\t0x1dcc: 0x0040, 0x1dcd: 0x0040, 0x1dce: 0x0040, 0x1dcf: 0x0040, 0x1dd0: 0xc281, 0x1dd1: 0xc2a1,\n\t0x1dd2: 0xc2c1, 0x1dd3: 0xc2e1, 0x1dd4: 0xc301, 0x1dd5: 0xc321, 0x1dd6: 0xc341, 0x1dd7: 0xc361,\n\t0x1dd8: 0xc381, 0x1dd9: 0xc3a1, 0x1dda: 0xc3c1, 0x1ddb: 0xc3e1, 0x1ddc: 0xc401, 0x1ddd: 0xc421,\n\t0x1dde: 0xc441, 0x1ddf: 0xc461, 0x1de0: 0xc481, 0x1de1: 0xc4a1, 0x1de2: 0xc4c1, 0x1de3: 0xc4e1,\n\t0x1de4: 0xc501, 0x1de5: 0xc521, 0x1de6: 0xc541, 0x1de7: 0xc561, 0x1de8: 0xc581, 0x1de9: 0xc5a1,\n\t0x1dea: 0xc5c1, 0x1deb: 0xc5e1, 0x1dec: 0xc601, 0x1ded: 0xc621, 0x1dee: 0xc641, 0x1def: 0xc661,\n\t0x1df0: 0xc681, 0x1df1: 0xc6a1, 0x1df2: 0xc6c1, 0x1df3: 0xc6e1, 0x1df4: 0xc701, 0x1df5: 0xc721,\n\t0x1df6: 0xc741, 0x1df7: 0xc761, 0x1df8: 0xc781, 0x1df9: 0xc7a1, 0x1dfa: 0xc7c1, 0x1dfb: 0xc7e1,\n\t0x1dfc: 0x0040, 0x1dfd: 0x0040, 0x1dfe: 0x0040, 0x1dff: 0x0040,\n\t// Block 0x78, offset 0x1e00\n\t0x1e00: 0xcb11, 0x1e01: 0xcb31, 0x1e02: 0xcb51, 0x1e03: 0x8b55, 0x1e04: 0xcb71, 0x1e05: 0xcb91,\n\t0x1e06: 0xcbb1, 0x1e07: 0xcbd1, 0x1e08: 0xcbf1, 0x1e09: 0xcc11, 0x1e0a: 0xcc31, 0x1e0b: 0xcc51,\n\t0x1e0c: 0xcc71, 0x1e0d: 0x8b75, 0x1e0e: 0xcc91, 0x1e0f: 0xccb1, 0x1e10: 0xccd1, 0x1e11: 0xccf1,\n\t0x1e12: 0x8b95, 0x1e13: 0xcd11, 0x1e14: 0xcd31, 0x1e15: 0xc441, 0x1e16: 0x8bb5, 0x1e17: 0xcd51,\n\t0x1e18: 0xcd71, 0x1e19: 0xcd91, 0x1e1a: 0xcdb1, 0x1e1b: 0xcdd1, 0x1e1c: 0x8bd5, 0x1e1d: 0xcdf1,\n\t0x1e1e: 0xce11, 0x1e1f: 0xce31, 0x1e20: 0xce51, 0x1e21: 0xce71, 0x1e22: 0xc7a1, 0x1e23: 0xce91,\n\t0x1e24: 0xceb1, 0x1e25: 0xced1, 0x1e26: 0xcef1, 0x1e27: 0xcf11, 0x1e28: 0xcf31, 0x1e29: 0xcf51,\n\t0x1e2a: 0xcf71, 0x1e2b: 0xcf91, 0x1e2c: 0xcfb1, 0x1e2d: 0xcfd1, 0x1e2e: 0xcff1, 0x1e2f: 0xd011,\n\t0x1e30: 0xd031, 0x1e31: 0xd051, 0x1e32: 0xd051, 0x1e33: 0xd051, 0x1e34: 0x8bf5, 0x1e35: 0xd071,\n\t0x1e36: 0xd091, 0x1e37: 0xd0b1, 0x1e38: 0x8c15, 0x1e39: 0xd0d1, 0x1e3a: 0xd0f1, 0x1e3b: 0xd111,\n\t0x1e3c: 0xd131, 0x1e3d: 0xd151, 0x1e3e: 0xd171, 0x1e3f: 0xd191,\n\t// Block 0x79, offset 0x1e40\n\t0x1e40: 0xd1b1, 0x1e41: 0xd1d1, 0x1e42: 0xd1f1, 0x1e43: 0xd211, 0x1e44: 0xd231, 0x1e45: 0xd251,\n\t0x1e46: 0xd251, 0x1e47: 0xd271, 0x1e48: 0xd291, 0x1e49: 0xd2b1, 0x1e4a: 0xd2d1, 0x1e4b: 0xd2f1,\n\t0x1e4c: 0xd311, 0x1e4d: 0xd331, 0x1e4e: 0xd351, 0x1e4f: 0xd371, 0x1e50: 0xd391, 0x1e51: 0xd3b1,\n\t0x1e52: 0xd3d1, 0x1e53: 0xd3f1, 0x1e54: 0xd411, 0x1e55: 0xd431, 0x1e56: 0xd451, 0x1e57: 0xd471,\n\t0x1e58: 0xd491, 0x1e59: 0x8c35, 0x1e5a: 0xd4b1, 0x1e5b: 0xd4d1, 0x1e5c: 0xd4f1, 0x1e5d: 0xc321,\n\t0x1e5e: 0xd511, 0x1e5f: 0xd531, 0x1e60: 0x8c55, 0x1e61: 0x8c75, 0x1e62: 0xd551, 0x1e63: 0xd571,\n\t0x1e64: 0xd591, 0x1e65: 0xd5b1, 0x1e66: 0xd5d1, 0x1e67: 0xd5f1, 0x1e68: 0x2040, 0x1e69: 0xd611,\n\t0x1e6a: 0xd631, 0x1e6b: 0xd631, 0x1e6c: 0x8c95, 0x1e6d: 0xd651, 0x1e6e: 0xd671, 0x1e6f: 0xd691,\n\t0x1e70: 0xd6b1, 0x1e71: 0x8cb5, 0x1e72: 0xd6d1, 0x1e73: 0xd6f1, 0x1e74: 0x2040, 0x1e75: 0xd711,\n\t0x1e76: 0xd731, 0x1e77: 0xd751, 0x1e78: 0xd771, 0x1e79: 0xd791, 0x1e7a: 0xd7b1, 0x1e7b: 0x8cd5,\n\t0x1e7c: 0xd7d1, 0x1e7d: 0x8cf5, 0x1e7e: 0xd7f1, 0x1e7f: 0xd811,\n\t// Block 0x7a, offset 0x1e80\n\t0x1e80: 0xd831, 0x1e81: 0xd851, 0x1e82: 0xd871, 0x1e83: 0xd891, 0x1e84: 0xd8b1, 0x1e85: 0xd8d1,\n\t0x1e86: 0xd8f1, 0x1e87: 0xd911, 0x1e88: 0xd931, 0x1e89: 0x8d15, 0x1e8a: 0xd951, 0x1e8b: 0xd971,\n\t0x1e8c: 0xd991, 0x1e8d: 0xd9b1, 0x1e8e: 0xd9d1, 0x1e8f: 0x8d35, 0x1e90: 0xd9f1, 0x1e91: 0x8d55,\n\t0x1e92: 0x8d75, 0x1e93: 0xda11, 0x1e94: 0xda31, 0x1e95: 0xda31, 0x1e96: 0xda51, 0x1e97: 0x8d95,\n\t0x1e98: 0x8db5, 0x1e99: 0xda71, 0x1e9a: 0xda91, 0x1e9b: 0xdab1, 0x1e9c: 0xdad1, 0x1e9d: 0xdaf1,\n\t0x1e9e: 0xdb11, 0x1e9f: 0xdb31, 0x1ea0: 0xdb51, 0x1ea1: 0xdb71, 0x1ea2: 0xdb91, 0x1ea3: 0xdbb1,\n\t0x1ea4: 0x8dd5, 0x1ea5: 0xdbd1, 0x1ea6: 0xdbf1, 0x1ea7: 0xdc11, 0x1ea8: 0xdc31, 0x1ea9: 0xdc11,\n\t0x1eaa: 0xdc51, 0x1eab: 0xdc71, 0x1eac: 0xdc91, 0x1ead: 0xdcb1, 0x1eae: 0xdcd1, 0x1eaf: 0xdcf1,\n\t0x1eb0: 0xdd11, 0x1eb1: 0xdd31, 0x1eb2: 0xdd51, 0x1eb3: 0xdd71, 0x1eb4: 0xdd91, 0x1eb5: 0xddb1,\n\t0x1eb6: 0xddd1, 0x1eb7: 0xddf1, 0x1eb8: 0x8df5, 0x1eb9: 0xde11, 0x1eba: 0xde31, 0x1ebb: 0xde51,\n\t0x1ebc: 0xde71, 0x1ebd: 0xde91, 0x1ebe: 0x8e15, 0x1ebf: 0xdeb1,\n\t// Block 0x7b, offset 0x1ec0\n\t0x1ec0: 0xe5b1, 0x1ec1: 0xe5d1, 0x1ec2: 0xe5f1, 0x1ec3: 0xe611, 0x1ec4: 0xe631, 0x1ec5: 0xe651,\n\t0x1ec6: 0x8f35, 0x1ec7: 0xe671, 0x1ec8: 0xe691, 0x1ec9: 0xe6b1, 0x1eca: 0xe6d1, 0x1ecb: 0xe6f1,\n\t0x1ecc: 0xe711, 0x1ecd: 0x8f55, 0x1ece: 0xe731, 0x1ecf: 0xe751, 0x1ed0: 0x8f75, 0x1ed1: 0x8f95,\n\t0x1ed2: 0xe771, 0x1ed3: 0xe791, 0x1ed4: 0xe7b1, 0x1ed5: 0xe7d1, 0x1ed6: 0xe7f1, 0x1ed7: 0xe811,\n\t0x1ed8: 0xe831, 0x1ed9: 0xe851, 0x1eda: 0xe871, 0x1edb: 0x8fb5, 0x1edc: 0xe891, 0x1edd: 0x8fd5,\n\t0x1ede: 0xe8b1, 0x1edf: 0x2040, 0x1ee0: 0xe8d1, 0x1ee1: 0xe8f1, 0x1ee2: 0xe911, 0x1ee3: 0x8ff5,\n\t0x1ee4: 0xe931, 0x1ee5: 0xe951, 0x1ee6: 0x9015, 0x1ee7: 0x9035, 0x1ee8: 0xe971, 0x1ee9: 0xe991,\n\t0x1eea: 0xe9b1, 0x1eeb: 0xe9d1, 0x1eec: 0xe9f1, 0x1eed: 0xe9f1, 0x1eee: 0xea11, 0x1eef: 0xea31,\n\t0x1ef0: 0xea51, 0x1ef1: 0xea71, 0x1ef2: 0xea91, 0x1ef3: 0xeab1, 0x1ef4: 0xead1, 0x1ef5: 0x9055,\n\t0x1ef6: 0xeaf1, 0x1ef7: 0x9075, 0x1ef8: 0xeb11, 0x1ef9: 0x9095, 0x1efa: 0xeb31, 0x1efb: 0x90b5,\n\t0x1efc: 0x90d5, 0x1efd: 0x90f5, 0x1efe: 0xeb51, 0x1eff: 0xeb71,\n\t// Block 0x7c, offset 0x1f00\n\t0x1f00: 0xeb91, 0x1f01: 0x9115, 0x1f02: 0x9135, 0x1f03: 0x9155, 0x1f04: 0x9175, 0x1f05: 0xebb1,\n\t0x1f06: 0xebd1, 0x1f07: 0xebd1, 0x1f08: 0xebf1, 0x1f09: 0xec11, 0x1f0a: 0xec31, 0x1f0b: 0xec51,\n\t0x1f0c: 0xec71, 0x1f0d: 0x9195, 0x1f0e: 0xec91, 0x1f0f: 0xecb1, 0x1f10: 0xecd1, 0x1f11: 0xecf1,\n\t0x1f12: 0x91b5, 0x1f13: 0xed11, 0x1f14: 0x91d5, 0x1f15: 0x91f5, 0x1f16: 0xed31, 0x1f17: 0xed51,\n\t0x1f18: 0xed71, 0x1f19: 0xed91, 0x1f1a: 0xedb1, 0x1f1b: 0xedd1, 0x1f1c: 0x9215, 0x1f1d: 0x9235,\n\t0x1f1e: 0x9255, 0x1f1f: 0x2040, 0x1f20: 0xedf1, 0x1f21: 0x9275, 0x1f22: 0xee11, 0x1f23: 0xee31,\n\t0x1f24: 0xee51, 0x1f25: 0x9295, 0x1f26: 0xee71, 0x1f27: 0xee91, 0x1f28: 0xeeb1, 0x1f29: 0xeed1,\n\t0x1f2a: 0xeef1, 0x1f2b: 0x92b5, 0x1f2c: 0xef11, 0x1f2d: 0xef31, 0x1f2e: 0xef51, 0x1f2f: 0xef71,\n\t0x1f30: 0xef91, 0x1f31: 0xefb1, 0x1f32: 0x92d5, 0x1f33: 0x92f5, 0x1f34: 0xefd1, 0x1f35: 0x9315,\n\t0x1f36: 0xeff1, 0x1f37: 0x9335, 0x1f38: 0xf011, 0x1f39: 0xf031, 0x1f3a: 0xf051, 0x1f3b: 0x9355,\n\t0x1f3c: 0x9375, 0x1f3d: 0xf071, 0x1f3e: 0x9395, 0x1f3f: 0xf091,\n\t// Block 0x7d, offset 0x1f40\n\t0x1f40: 0xf6d1, 0x1f41: 0xf6f1, 0x1f42: 0xf711, 0x1f43: 0xf731, 0x1f44: 0xf751, 0x1f45: 0x9555,\n\t0x1f46: 0xf771, 0x1f47: 0xf791, 0x1f48: 0xf7b1, 0x1f49: 0xf7d1, 0x1f4a: 0xf7f1, 0x1f4b: 0x9575,\n\t0x1f4c: 0x9595, 0x1f4d: 0xf811, 0x1f4e: 0xf831, 0x1f4f: 0xf851, 0x1f50: 0xf871, 0x1f51: 0xf891,\n\t0x1f52: 0xf8b1, 0x1f53: 0x95b5, 0x1f54: 0xf8d1, 0x1f55: 0xf8f1, 0x1f56: 0xf911, 0x1f57: 0xf931,\n\t0x1f58: 0x95d5, 0x1f59: 0x95f5, 0x1f5a: 0xf951, 0x1f5b: 0xf971, 0x1f5c: 0xf991, 0x1f5d: 0x9615,\n\t0x1f5e: 0xf9b1, 0x1f5f: 0xf9d1, 0x1f60: 0x684d, 0x1f61: 0x9635, 0x1f62: 0xf9f1, 0x1f63: 0xfa11,\n\t0x1f64: 0xfa31, 0x1f65: 0x9655, 0x1f66: 0xfa51, 0x1f67: 0xfa71, 0x1f68: 0xfa91, 0x1f69: 0xfab1,\n\t0x1f6a: 0xfad1, 0x1f6b: 0xfaf1, 0x1f6c: 0xfb11, 0x1f6d: 0x9675, 0x1f6e: 0xfb31, 0x1f6f: 0xfb51,\n\t0x1f70: 0xfb71, 0x1f71: 0x9695, 0x1f72: 0xfb91, 0x1f73: 0xfbb1, 0x1f74: 0xfbd1, 0x1f75: 0xfbf1,\n\t0x1f76: 0x7b6d, 0x1f77: 0x96b5, 0x1f78: 0xfc11, 0x1f79: 0xfc31, 0x1f7a: 0xfc51, 0x1f7b: 0x96d5,\n\t0x1f7c: 0xfc71, 0x1f7d: 0x96f5, 0x1f7e: 0xfc91, 0x1f7f: 0xfc91,\n\t// Block 0x7e, offset 0x1f80\n\t0x1f80: 0xfcb1, 0x1f81: 0x9715, 0x1f82: 0xfcd1, 0x1f83: 0xfcf1, 0x1f84: 0xfd11, 0x1f85: 0xfd31,\n\t0x1f86: 0xfd51, 0x1f87: 0xfd71, 0x1f88: 0xfd91, 0x1f89: 0x9735, 0x1f8a: 0xfdb1, 0x1f8b: 0xfdd1,\n\t0x1f8c: 0xfdf1, 0x1f8d: 0xfe11, 0x1f8e: 0xfe31, 0x1f8f: 0xfe51, 0x1f90: 0x9755, 0x1f91: 0xfe71,\n\t0x1f92: 0x9775, 0x1f93: 0x9795, 0x1f94: 0x97b5, 0x1f95: 0xfe91, 0x1f96: 0xfeb1, 0x1f97: 0xfed1,\n\t0x1f98: 0xfef1, 0x1f99: 0xff11, 0x1f9a: 0xff31, 0x1f9b: 0xff51, 0x1f9c: 0xff71, 0x1f9d: 0x97d5,\n\t0x1f9e: 0x0040, 0x1f9f: 0x0040, 0x1fa0: 0x0040, 0x1fa1: 0x0040, 0x1fa2: 0x0040, 0x1fa3: 0x0040,\n\t0x1fa4: 0x0040, 0x1fa5: 0x0040, 0x1fa6: 0x0040, 0x1fa7: 0x0040, 0x1fa8: 0x0040, 0x1fa9: 0x0040,\n\t0x1faa: 0x0040, 0x1fab: 0x0040, 0x1fac: 0x0040, 0x1fad: 0x0040, 0x1fae: 0x0040, 0x1faf: 0x0040,\n\t0x1fb0: 0x0040, 0x1fb1: 0x0040, 0x1fb2: 0x0040, 0x1fb3: 0x0040, 0x1fb4: 0x0040, 0x1fb5: 0x0040,\n\t0x1fb6: 0x0040, 0x1fb7: 0x0040, 0x1fb8: 0x0040, 0x1fb9: 0x0040, 0x1fba: 0x0040, 0x1fbb: 0x0040,\n\t0x1fbc: 0x0040, 0x1fbd: 0x0040, 0x1fbe: 0x0040, 0x1fbf: 0x0040,\n}\n\n// idnaIndex: 36 blocks, 2304 entries, 4608 bytes\n// Block 0 is the zero block.\nvar idnaIndex = [2304]uint16{\n\t// Block 0x0, offset 0x0\n\t// Block 0x1, offset 0x40\n\t// Block 0x2, offset 0x80\n\t// Block 0x3, offset 0xc0\n\t0xc2: 0x01, 0xc3: 0x7d, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05,\n\t0xc8: 0x06, 0xc9: 0x7e, 0xca: 0x7f, 0xcb: 0x07, 0xcc: 0x80, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a,\n\t0xd0: 0x81, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x82, 0xd6: 0x83, 0xd7: 0x84,\n\t0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x85, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x86, 0xde: 0x87, 0xdf: 0x88,\n\t0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07,\n\t0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c,\n\t0xf0: 0x1d, 0xf1: 0x1e, 0xf2: 0x1e, 0xf3: 0x20, 0xf4: 0x21,\n\t// Block 0x4, offset 0x100\n\t0x120: 0x89, 0x121: 0x13, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x14, 0x126: 0x15, 0x127: 0x16,\n\t0x128: 0x17, 0x129: 0x18, 0x12a: 0x19, 0x12b: 0x1a, 0x12c: 0x1b, 0x12d: 0x1c, 0x12e: 0x1d, 0x12f: 0x8d,\n\t0x130: 0x8e, 0x131: 0x1e, 0x132: 0x1f, 0x133: 0x20, 0x134: 0x8f, 0x135: 0x21, 0x136: 0x90, 0x137: 0x91,\n\t0x138: 0x92, 0x139: 0x93, 0x13a: 0x22, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x23, 0x13e: 0x24, 0x13f: 0x96,\n\t// Block 0x5, offset 0x140\n\t0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9d, 0x147: 0x9e,\n\t0x148: 0x9f, 0x149: 0xa0, 0x14a: 0xa1, 0x14b: 0xa2, 0x14c: 0xa3, 0x14d: 0xa4, 0x14e: 0xa5, 0x14f: 0xa6,\n\t0x150: 0xa7, 0x151: 0x9f, 0x152: 0x9f, 0x153: 0x9f, 0x154: 0x9f, 0x155: 0x9f, 0x156: 0x9f, 0x157: 0x9f,\n\t0x158: 0x9f, 0x159: 0xa8, 0x15a: 0xa9, 0x15b: 0xaa, 0x15c: 0xab, 0x15d: 0xac, 0x15e: 0xad, 0x15f: 0xae,\n\t0x160: 0xaf, 0x161: 0xb0, 0x162: 0xb1, 0x163: 0xb2, 0x164: 0xb3, 0x165: 0xb4, 0x166: 0xb5, 0x167: 0xb6,\n\t0x168: 0xb7, 0x169: 0xb8, 0x16a: 0xb9, 0x16b: 0xba, 0x16c: 0xbb, 0x16d: 0xbc, 0x16e: 0xbd, 0x16f: 0xbe,\n\t0x170: 0xbf, 0x171: 0xc0, 0x172: 0xc1, 0x173: 0xc2, 0x174: 0x25, 0x175: 0x26, 0x176: 0x27, 0x177: 0xc3,\n\t0x178: 0x28, 0x179: 0x28, 0x17a: 0x29, 0x17b: 0x28, 0x17c: 0xc4, 0x17d: 0x2a, 0x17e: 0x2b, 0x17f: 0x2c,\n\t// Block 0x6, offset 0x180\n\t0x180: 0x2d, 0x181: 0x2e, 0x182: 0x2f, 0x183: 0xc5, 0x184: 0x30, 0x185: 0x31, 0x186: 0xc6, 0x187: 0x9b,\n\t0x188: 0xc7, 0x189: 0xc8, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc9, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0x9b,\n\t0x190: 0xca, 0x191: 0x32, 0x192: 0x33, 0x193: 0x34, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b,\n\t0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b,\n\t0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b,\n\t0x1a8: 0xcb, 0x1a9: 0xcc, 0x1aa: 0x9b, 0x1ab: 0xcd, 0x1ac: 0x9b, 0x1ad: 0xce, 0x1ae: 0xcf, 0x1af: 0x9b,\n\t0x1b0: 0xd0, 0x1b1: 0x35, 0x1b2: 0x28, 0x1b3: 0x36, 0x1b4: 0xd1, 0x1b5: 0xd2, 0x1b6: 0xd3, 0x1b7: 0xd4,\n\t0x1b8: 0xd5, 0x1b9: 0xd6, 0x1ba: 0xd7, 0x1bb: 0xd8, 0x1bc: 0xd9, 0x1bd: 0xda, 0x1be: 0xdb, 0x1bf: 0x37,\n\t// Block 0x7, offset 0x1c0\n\t0x1c0: 0x38, 0x1c1: 0xdc, 0x1c2: 0xdd, 0x1c3: 0xde, 0x1c4: 0xdf, 0x1c5: 0x39, 0x1c6: 0x3a, 0x1c7: 0xe0,\n\t0x1c8: 0xe1, 0x1c9: 0x3b, 0x1ca: 0x3c, 0x1cb: 0x3d, 0x1cc: 0x3e, 0x1cd: 0x3f, 0x1ce: 0x40, 0x1cf: 0x41,\n\t0x1d0: 0x9f, 0x1d1: 0x9f, 0x1d2: 0x9f, 0x1d3: 0x9f, 0x1d4: 0x9f, 0x1d5: 0x9f, 0x1d6: 0x9f, 0x1d7: 0x9f,\n\t0x1d8: 0x9f, 0x1d9: 0x9f, 0x1da: 0x9f, 0x1db: 0x9f, 0x1dc: 0x9f, 0x1dd: 0x9f, 0x1de: 0x9f, 0x1df: 0x9f,\n\t0x1e0: 0x9f, 0x1e1: 0x9f, 0x1e2: 0x9f, 0x1e3: 0x9f, 0x1e4: 0x9f, 0x1e5: 0x9f, 0x1e6: 0x9f, 0x1e7: 0x9f,\n\t0x1e8: 0x9f, 0x1e9: 0x9f, 0x1ea: 0x9f, 0x1eb: 0x9f, 0x1ec: 0x9f, 0x1ed: 0x9f, 0x1ee: 0x9f, 0x1ef: 0x9f,\n\t0x1f0: 0x9f, 0x1f1: 0x9f, 0x1f2: 0x9f, 0x1f3: 0x9f, 0x1f4: 0x9f, 0x1f5: 0x9f, 0x1f6: 0x9f, 0x1f7: 0x9f,\n\t0x1f8: 0x9f, 0x1f9: 0x9f, 0x1fa: 0x9f, 0x1fb: 0x9f, 0x1fc: 0x9f, 0x1fd: 0x9f, 0x1fe: 0x9f, 0x1ff: 0x9f,\n\t// Block 0x8, offset 0x200\n\t0x200: 0x9f, 0x201: 0x9f, 0x202: 0x9f, 0x203: 0x9f, 0x204: 0x9f, 0x205: 0x9f, 0x206: 0x9f, 0x207: 0x9f,\n\t0x208: 0x9f, 0x209: 0x9f, 0x20a: 0x9f, 0x20b: 0x9f, 0x20c: 0x9f, 0x20d: 0x9f, 0x20e: 0x9f, 0x20f: 0x9f,\n\t0x210: 0x9f, 0x211: 0x9f, 0x212: 0x9f, 0x213: 0x9f, 0x214: 0x9f, 0x215: 0x9f, 0x216: 0x9f, 0x217: 0x9f,\n\t0x218: 0x9f, 0x219: 0x9f, 0x21a: 0x9f, 0x21b: 0x9f, 0x21c: 0x9f, 0x21d: 0x9f, 0x21e: 0x9f, 0x21f: 0x9f,\n\t0x220: 0x9f, 0x221: 0x9f, 0x222: 0x9f, 0x223: 0x9f, 0x224: 0x9f, 0x225: 0x9f, 0x226: 0x9f, 0x227: 0x9f,\n\t0x228: 0x9f, 0x229: 0x9f, 0x22a: 0x9f, 0x22b: 0x9f, 0x22c: 0x9f, 0x22d: 0x9f, 0x22e: 0x9f, 0x22f: 0x9f,\n\t0x230: 0x9f, 0x231: 0x9f, 0x232: 0x9f, 0x233: 0x9f, 0x234: 0x9f, 0x235: 0x9f, 0x236: 0xb2, 0x237: 0x9b,\n\t0x238: 0x9f, 0x239: 0x9f, 0x23a: 0x9f, 0x23b: 0x9f, 0x23c: 0x9f, 0x23d: 0x9f, 0x23e: 0x9f, 0x23f: 0x9f,\n\t// Block 0x9, offset 0x240\n\t0x240: 0x9f, 0x241: 0x9f, 0x242: 0x9f, 0x243: 0x9f, 0x244: 0x9f, 0x245: 0x9f, 0x246: 0x9f, 0x247: 0x9f,\n\t0x248: 0x9f, 0x249: 0x9f, 0x24a: 0x9f, 0x24b: 0x9f, 0x24c: 0x9f, 0x24d: 0x9f, 0x24e: 0x9f, 0x24f: 0x9f,\n\t0x250: 0x9f, 0x251: 0x9f, 0x252: 0x9f, 0x253: 0x9f, 0x254: 0x9f, 0x255: 0x9f, 0x256: 0x9f, 0x257: 0x9f,\n\t0x258: 0x9f, 0x259: 0x9f, 0x25a: 0x9f, 0x25b: 0x9f, 0x25c: 0x9f, 0x25d: 0x9f, 0x25e: 0x9f, 0x25f: 0x9f,\n\t0x260: 0x9f, 0x261: 0x9f, 0x262: 0x9f, 0x263: 0x9f, 0x264: 0x9f, 0x265: 0x9f, 0x266: 0x9f, 0x267: 0x9f,\n\t0x268: 0x9f, 0x269: 0x9f, 0x26a: 0x9f, 0x26b: 0x9f, 0x26c: 0x9f, 0x26d: 0x9f, 0x26e: 0x9f, 0x26f: 0x9f,\n\t0x270: 0x9f, 0x271: 0x9f, 0x272: 0x9f, 0x273: 0x9f, 0x274: 0x9f, 0x275: 0x9f, 0x276: 0x9f, 0x277: 0x9f,\n\t0x278: 0x9f, 0x279: 0x9f, 0x27a: 0x9f, 0x27b: 0x9f, 0x27c: 0x9f, 0x27d: 0x9f, 0x27e: 0x9f, 0x27f: 0x9f,\n\t// Block 0xa, offset 0x280\n\t0x280: 0x9f, 0x281: 0x9f, 0x282: 0x9f, 0x283: 0x9f, 0x284: 0x9f, 0x285: 0x9f, 0x286: 0x9f, 0x287: 0x9f,\n\t0x288: 0x9f, 0x289: 0x9f, 0x28a: 0x9f, 0x28b: 0x9f, 0x28c: 0x9f, 0x28d: 0x9f, 0x28e: 0x9f, 0x28f: 0x9f,\n\t0x290: 0x9f, 0x291: 0x9f, 0x292: 0x9f, 0x293: 0x9f, 0x294: 0x9f, 0x295: 0x9f, 0x296: 0x9f, 0x297: 0x9f,\n\t0x298: 0x9f, 0x299: 0x9f, 0x29a: 0x9f, 0x29b: 0x9f, 0x29c: 0x9f, 0x29d: 0x9f, 0x29e: 0x9f, 0x29f: 0x9f,\n\t0x2a0: 0x9f, 0x2a1: 0x9f, 0x2a2: 0x9f, 0x2a3: 0x9f, 0x2a4: 0x9f, 0x2a5: 0x9f, 0x2a6: 0x9f, 0x2a7: 0x9f,\n\t0x2a8: 0x9f, 0x2a9: 0x9f, 0x2aa: 0x9f, 0x2ab: 0x9f, 0x2ac: 0x9f, 0x2ad: 0x9f, 0x2ae: 0x9f, 0x2af: 0x9f,\n\t0x2b0: 0x9f, 0x2b1: 0x9f, 0x2b2: 0x9f, 0x2b3: 0x9f, 0x2b4: 0x9f, 0x2b5: 0x9f, 0x2b6: 0x9f, 0x2b7: 0x9f,\n\t0x2b8: 0x9f, 0x2b9: 0x9f, 0x2ba: 0x9f, 0x2bb: 0x9f, 0x2bc: 0x9f, 0x2bd: 0x9f, 0x2be: 0x9f, 0x2bf: 0xe2,\n\t// Block 0xb, offset 0x2c0\n\t0x2c0: 0x9f, 0x2c1: 0x9f, 0x2c2: 0x9f, 0x2c3: 0x9f, 0x2c4: 0x9f, 0x2c5: 0x9f, 0x2c6: 0x9f, 0x2c7: 0x9f,\n\t0x2c8: 0x9f, 0x2c9: 0x9f, 0x2ca: 0x9f, 0x2cb: 0x9f, 0x2cc: 0x9f, 0x2cd: 0x9f, 0x2ce: 0x9f, 0x2cf: 0x9f,\n\t0x2d0: 0x9f, 0x2d1: 0x9f, 0x2d2: 0xe3, 0x2d3: 0xe4, 0x2d4: 0x9f, 0x2d5: 0x9f, 0x2d6: 0x9f, 0x2d7: 0x9f,\n\t0x2d8: 0xe5, 0x2d9: 0x42, 0x2da: 0x43, 0x2db: 0xe6, 0x2dc: 0x44, 0x2dd: 0x45, 0x2de: 0x46, 0x2df: 0xe7,\n\t0x2e0: 0xe8, 0x2e1: 0xe9, 0x2e2: 0xea, 0x2e3: 0xeb, 0x2e4: 0xec, 0x2e5: 0xed, 0x2e6: 0xee, 0x2e7: 0xef,\n\t0x2e8: 0xf0, 0x2e9: 0xf1, 0x2ea: 0xf2, 0x2eb: 0xf3, 0x2ec: 0xf4, 0x2ed: 0xf5, 0x2ee: 0xf6, 0x2ef: 0xf7,\n\t0x2f0: 0x9f, 0x2f1: 0x9f, 0x2f2: 0x9f, 0x2f3: 0x9f, 0x2f4: 0x9f, 0x2f5: 0x9f, 0x2f6: 0x9f, 0x2f7: 0x9f,\n\t0x2f8: 0x9f, 0x2f9: 0x9f, 0x2fa: 0x9f, 0x2fb: 0x9f, 0x2fc: 0x9f, 0x2fd: 0x9f, 0x2fe: 0x9f, 0x2ff: 0x9f,\n\t// Block 0xc, offset 0x300\n\t0x300: 0x9f, 0x301: 0x9f, 0x302: 0x9f, 0x303: 0x9f, 0x304: 0x9f, 0x305: 0x9f, 0x306: 0x9f, 0x307: 0x9f,\n\t0x308: 0x9f, 0x309: 0x9f, 0x30a: 0x9f, 0x30b: 0x9f, 0x30c: 0x9f, 0x30d: 0x9f, 0x30e: 0x9f, 0x30f: 0x9f,\n\t0x310: 0x9f, 0x311: 0x9f, 0x312: 0x9f, 0x313: 0x9f, 0x314: 0x9f, 0x315: 0x9f, 0x316: 0x9f, 0x317: 0x9f,\n\t0x318: 0x9f, 0x319: 0x9f, 0x31a: 0x9f, 0x31b: 0x9f, 0x31c: 0x9f, 0x31d: 0x9f, 0x31e: 0xf8, 0x31f: 0xf9,\n\t// Block 0xd, offset 0x340\n\t0x340: 0xba, 0x341: 0xba, 0x342: 0xba, 0x343: 0xba, 0x344: 0xba, 0x345: 0xba, 0x346: 0xba, 0x347: 0xba,\n\t0x348: 0xba, 0x349: 0xba, 0x34a: 0xba, 0x34b: 0xba, 0x34c: 0xba, 0x34d: 0xba, 0x34e: 0xba, 0x34f: 0xba,\n\t0x350: 0xba, 0x351: 0xba, 0x352: 0xba, 0x353: 0xba, 0x354: 0xba, 0x355: 0xba, 0x356: 0xba, 0x357: 0xba,\n\t0x358: 0xba, 0x359: 0xba, 0x35a: 0xba, 0x35b: 0xba, 0x35c: 0xba, 0x35d: 0xba, 0x35e: 0xba, 0x35f: 0xba,\n\t0x360: 0xba, 0x361: 0xba, 0x362: 0xba, 0x363: 0xba, 0x364: 0xba, 0x365: 0xba, 0x366: 0xba, 0x367: 0xba,\n\t0x368: 0xba, 0x369: 0xba, 0x36a: 0xba, 0x36b: 0xba, 0x36c: 0xba, 0x36d: 0xba, 0x36e: 0xba, 0x36f: 0xba,\n\t0x370: 0xba, 0x371: 0xba, 0x372: 0xba, 0x373: 0xba, 0x374: 0xba, 0x375: 0xba, 0x376: 0xba, 0x377: 0xba,\n\t0x378: 0xba, 0x379: 0xba, 0x37a: 0xba, 0x37b: 0xba, 0x37c: 0xba, 0x37d: 0xba, 0x37e: 0xba, 0x37f: 0xba,\n\t// Block 0xe, offset 0x380\n\t0x380: 0xba, 0x381: 0xba, 0x382: 0xba, 0x383: 0xba, 0x384: 0xba, 0x385: 0xba, 0x386: 0xba, 0x387: 0xba,\n\t0x388: 0xba, 0x389: 0xba, 0x38a: 0xba, 0x38b: 0xba, 0x38c: 0xba, 0x38d: 0xba, 0x38e: 0xba, 0x38f: 0xba,\n\t0x390: 0xba, 0x391: 0xba, 0x392: 0xba, 0x393: 0xba, 0x394: 0xba, 0x395: 0xba, 0x396: 0xba, 0x397: 0xba,\n\t0x398: 0xba, 0x399: 0xba, 0x39a: 0xba, 0x39b: 0xba, 0x39c: 0xba, 0x39d: 0xba, 0x39e: 0xba, 0x39f: 0xba,\n\t0x3a0: 0xba, 0x3a1: 0xba, 0x3a2: 0xba, 0x3a3: 0xba, 0x3a4: 0xfa, 0x3a5: 0xfb, 0x3a6: 0xfc, 0x3a7: 0xfd,\n\t0x3a8: 0x47, 0x3a9: 0xfe, 0x3aa: 0xff, 0x3ab: 0x48, 0x3ac: 0x49, 0x3ad: 0x4a, 0x3ae: 0x4b, 0x3af: 0x4c,\n\t0x3b0: 0x100, 0x3b1: 0x4d, 0x3b2: 0x4e, 0x3b3: 0x4f, 0x3b4: 0x50, 0x3b5: 0x51, 0x3b6: 0x101, 0x3b7: 0x52,\n\t0x3b8: 0x53, 0x3b9: 0x54, 0x3ba: 0x55, 0x3bb: 0x56, 0x3bc: 0x57, 0x3bd: 0x58, 0x3be: 0x59, 0x3bf: 0x5a,\n\t// Block 0xf, offset 0x3c0\n\t0x3c0: 0x102, 0x3c1: 0x103, 0x3c2: 0x9f, 0x3c3: 0x104, 0x3c4: 0x105, 0x3c5: 0x9b, 0x3c6: 0x106, 0x3c7: 0x107,\n\t0x3c8: 0xba, 0x3c9: 0xba, 0x3ca: 0x108, 0x3cb: 0x109, 0x3cc: 0x10a, 0x3cd: 0x10b, 0x3ce: 0x10c, 0x3cf: 0x10d,\n\t0x3d0: 0x10e, 0x3d1: 0x9f, 0x3d2: 0x10f, 0x3d3: 0x110, 0x3d4: 0x111, 0x3d5: 0x112, 0x3d6: 0xba, 0x3d7: 0xba,\n\t0x3d8: 0x9f, 0x3d9: 0x9f, 0x3da: 0x9f, 0x3db: 0x9f, 0x3dc: 0x113, 0x3dd: 0x114, 0x3de: 0xba, 0x3df: 0xba,\n\t0x3e0: 0x115, 0x3e1: 0x116, 0x3e2: 0x117, 0x3e3: 0x118, 0x3e4: 0x119, 0x3e5: 0xba, 0x3e6: 0x11a, 0x3e7: 0x11b,\n\t0x3e8: 0x11c, 0x3e9: 0x11d, 0x3ea: 0x11e, 0x3eb: 0x5b, 0x3ec: 0x11f, 0x3ed: 0x120, 0x3ee: 0x5c, 0x3ef: 0xba,\n\t0x3f0: 0x121, 0x3f1: 0x122, 0x3f2: 0x123, 0x3f3: 0x124, 0x3f4: 0x125, 0x3f5: 0xba, 0x3f6: 0xba, 0x3f7: 0xba,\n\t0x3f8: 0xba, 0x3f9: 0x126, 0x3fa: 0xba, 0x3fb: 0xba, 0x3fc: 0x127, 0x3fd: 0x128, 0x3fe: 0xba, 0x3ff: 0x129,\n\t// Block 0x10, offset 0x400\n\t0x400: 0x12a, 0x401: 0x12b, 0x402: 0x12c, 0x403: 0x12d, 0x404: 0x12e, 0x405: 0x12f, 0x406: 0x130, 0x407: 0x131,\n\t0x408: 0x132, 0x409: 0xba, 0x40a: 0x133, 0x40b: 0x134, 0x40c: 0x5d, 0x40d: 0x5e, 0x40e: 0xba, 0x40f: 0xba,\n\t0x410: 0x135, 0x411: 0x136, 0x412: 0x137, 0x413: 0x138, 0x414: 0xba, 0x415: 0xba, 0x416: 0x139, 0x417: 0x13a,\n\t0x418: 0x13b, 0x419: 0x13c, 0x41a: 0x13d, 0x41b: 0x13e, 0x41c: 0x13f, 0x41d: 0xba, 0x41e: 0xba, 0x41f: 0xba,\n\t0x420: 0x140, 0x421: 0xba, 0x422: 0x141, 0x423: 0x142, 0x424: 0xba, 0x425: 0xba, 0x426: 0x143, 0x427: 0x144,\n\t0x428: 0x145, 0x429: 0x146, 0x42a: 0x147, 0x42b: 0x148, 0x42c: 0xba, 0x42d: 0xba, 0x42e: 0xba, 0x42f: 0xba,\n\t0x430: 0x149, 0x431: 0x14a, 0x432: 0x14b, 0x433: 0xba, 0x434: 0x14c, 0x435: 0x14d, 0x436: 0x14e, 0x437: 0xba,\n\t0x438: 0xba, 0x439: 0xba, 0x43a: 0xba, 0x43b: 0x14f, 0x43c: 0xba, 0x43d: 0xba, 0x43e: 0xba, 0x43f: 0x150,\n\t// Block 0x11, offset 0x440\n\t0x440: 0x9f, 0x441: 0x9f, 0x442: 0x9f, 0x443: 0x9f, 0x444: 0x9f, 0x445: 0x9f, 0x446: 0x9f, 0x447: 0x9f,\n\t0x448: 0x9f, 0x449: 0x9f, 0x44a: 0x9f, 0x44b: 0x9f, 0x44c: 0x9f, 0x44d: 0x9f, 0x44e: 0x151, 0x44f: 0xba,\n\t0x450: 0x9b, 0x451: 0x152, 0x452: 0x9f, 0x453: 0x9f, 0x454: 0x9f, 0x455: 0x153, 0x456: 0xba, 0x457: 0xba,\n\t0x458: 0xba, 0x459: 0xba, 0x45a: 0xba, 0x45b: 0xba, 0x45c: 0xba, 0x45d: 0xba, 0x45e: 0xba, 0x45f: 0xba,\n\t0x460: 0xba, 0x461: 0xba, 0x462: 0xba, 0x463: 0xba, 0x464: 0xba, 0x465: 0xba, 0x466: 0xba, 0x467: 0xba,\n\t0x468: 0xba, 0x469: 0xba, 0x46a: 0xba, 0x46b: 0xba, 0x46c: 0xba, 0x46d: 0xba, 0x46e: 0xba, 0x46f: 0xba,\n\t0x470: 0xba, 0x471: 0xba, 0x472: 0xba, 0x473: 0xba, 0x474: 0xba, 0x475: 0xba, 0x476: 0xba, 0x477: 0xba,\n\t0x478: 0xba, 0x479: 0xba, 0x47a: 0xba, 0x47b: 0xba, 0x47c: 0xba, 0x47d: 0xba, 0x47e: 0xba, 0x47f: 0xba,\n\t// Block 0x12, offset 0x480\n\t0x480: 0x9f, 0x481: 0x9f, 0x482: 0x9f, 0x483: 0x9f, 0x484: 0x9f, 0x485: 0x9f, 0x486: 0x9f, 0x487: 0x9f,\n\t0x488: 0x9f, 0x489: 0x9f, 0x48a: 0x9f, 0x48b: 0x9f, 0x48c: 0x9f, 0x48d: 0x9f, 0x48e: 0x9f, 0x48f: 0x9f,\n\t0x490: 0x154, 0x491: 0xba, 0x492: 0xba, 0x493: 0xba, 0x494: 0xba, 0x495: 0xba, 0x496: 0xba, 0x497: 0xba,\n\t0x498: 0xba, 0x499: 0xba, 0x49a: 0xba, 0x49b: 0xba, 0x49c: 0xba, 0x49d: 0xba, 0x49e: 0xba, 0x49f: 0xba,\n\t0x4a0: 0xba, 0x4a1: 0xba, 0x4a2: 0xba, 0x4a3: 0xba, 0x4a4: 0xba, 0x4a5: 0xba, 0x4a6: 0xba, 0x4a7: 0xba,\n\t0x4a8: 0xba, 0x4a9: 0xba, 0x4aa: 0xba, 0x4ab: 0xba, 0x4ac: 0xba, 0x4ad: 0xba, 0x4ae: 0xba, 0x4af: 0xba,\n\t0x4b0: 0xba, 0x4b1: 0xba, 0x4b2: 0xba, 0x4b3: 0xba, 0x4b4: 0xba, 0x4b5: 0xba, 0x4b6: 0xba, 0x4b7: 0xba,\n\t0x4b8: 0xba, 0x4b9: 0xba, 0x4ba: 0xba, 0x4bb: 0xba, 0x4bc: 0xba, 0x4bd: 0xba, 0x4be: 0xba, 0x4bf: 0xba,\n\t// Block 0x13, offset 0x4c0\n\t0x4c0: 0xba, 0x4c1: 0xba, 0x4c2: 0xba, 0x4c3: 0xba, 0x4c4: 0xba, 0x4c5: 0xba, 0x4c6: 0xba, 0x4c7: 0xba,\n\t0x4c8: 0xba, 0x4c9: 0xba, 0x4ca: 0xba, 0x4cb: 0xba, 0x4cc: 0xba, 0x4cd: 0xba, 0x4ce: 0xba, 0x4cf: 0xba,\n\t0x4d0: 0x9f, 0x4d1: 0x9f, 0x4d2: 0x9f, 0x4d3: 0x9f, 0x4d4: 0x9f, 0x4d5: 0x9f, 0x4d6: 0x9f, 0x4d7: 0x9f,\n\t0x4d8: 0x9f, 0x4d9: 0x155, 0x4da: 0xba, 0x4db: 0xba, 0x4dc: 0xba, 0x4dd: 0xba, 0x4de: 0xba, 0x4df: 0xba,\n\t0x4e0: 0xba, 0x4e1: 0xba, 0x4e2: 0xba, 0x4e3: 0xba, 0x4e4: 0xba, 0x4e5: 0xba, 0x4e6: 0xba, 0x4e7: 0xba,\n\t0x4e8: 0xba, 0x4e9: 0xba, 0x4ea: 0xba, 0x4eb: 0xba, 0x4ec: 0xba, 0x4ed: 0xba, 0x4ee: 0xba, 0x4ef: 0xba,\n\t0x4f0: 0xba, 0x4f1: 0xba, 0x4f2: 0xba, 0x4f3: 0xba, 0x4f4: 0xba, 0x4f5: 0xba, 0x4f6: 0xba, 0x4f7: 0xba,\n\t0x4f8: 0xba, 0x4f9: 0xba, 0x4fa: 0xba, 0x4fb: 0xba, 0x4fc: 0xba, 0x4fd: 0xba, 0x4fe: 0xba, 0x4ff: 0xba,\n\t// Block 0x14, offset 0x500\n\t0x500: 0xba, 0x501: 0xba, 0x502: 0xba, 0x503: 0xba, 0x504: 0xba, 0x505: 0xba, 0x506: 0xba, 0x507: 0xba,\n\t0x508: 0xba, 0x509: 0xba, 0x50a: 0xba, 0x50b: 0xba, 0x50c: 0xba, 0x50d: 0xba, 0x50e: 0xba, 0x50f: 0xba,\n\t0x510: 0xba, 0x511: 0xba, 0x512: 0xba, 0x513: 0xba, 0x514: 0xba, 0x515: 0xba, 0x516: 0xba, 0x517: 0xba,\n\t0x518: 0xba, 0x519: 0xba, 0x51a: 0xba, 0x51b: 0xba, 0x51c: 0xba, 0x51d: 0xba, 0x51e: 0xba, 0x51f: 0xba,\n\t0x520: 0x9f, 0x521: 0x9f, 0x522: 0x9f, 0x523: 0x9f, 0x524: 0x9f, 0x525: 0x9f, 0x526: 0x9f, 0x527: 0x9f,\n\t0x528: 0x148, 0x529: 0x156, 0x52a: 0xba, 0x52b: 0x157, 0x52c: 0x158, 0x52d: 0x159, 0x52e: 0x15a, 0x52f: 0xba,\n\t0x530: 0xba, 0x531: 0xba, 0x532: 0xba, 0x533: 0xba, 0x534: 0xba, 0x535: 0xba, 0x536: 0xba, 0x537: 0xba,\n\t0x538: 0xba, 0x539: 0x15b, 0x53a: 0x15c, 0x53b: 0xba, 0x53c: 0x9f, 0x53d: 0x15d, 0x53e: 0x15e, 0x53f: 0x15f,\n\t// Block 0x15, offset 0x540\n\t0x540: 0x9f, 0x541: 0x9f, 0x542: 0x9f, 0x543: 0x9f, 0x544: 0x9f, 0x545: 0x9f, 0x546: 0x9f, 0x547: 0x9f,\n\t0x548: 0x9f, 0x549: 0x9f, 0x54a: 0x9f, 0x54b: 0x9f, 0x54c: 0x9f, 0x54d: 0x9f, 0x54e: 0x9f, 0x54f: 0x9f,\n\t0x550: 0x9f, 0x551: 0x9f, 0x552: 0x9f, 0x553: 0x9f, 0x554: 0x9f, 0x555: 0x9f, 0x556: 0x9f, 0x557: 0x9f,\n\t0x558: 0x9f, 0x559: 0x9f, 0x55a: 0x9f, 0x55b: 0x9f, 0x55c: 0x9f, 0x55d: 0x9f, 0x55e: 0x9f, 0x55f: 0x160,\n\t0x560: 0x9f, 0x561: 0x9f, 0x562: 0x9f, 0x563: 0x9f, 0x564: 0x9f, 0x565: 0x9f, 0x566: 0x9f, 0x567: 0x9f,\n\t0x568: 0x9f, 0x569: 0x9f, 0x56a: 0x9f, 0x56b: 0x161, 0x56c: 0xba, 0x56d: 0xba, 0x56e: 0xba, 0x56f: 0xba,\n\t0x570: 0xba, 0x571: 0xba, 0x572: 0xba, 0x573: 0xba, 0x574: 0xba, 0x575: 0xba, 0x576: 0xba, 0x577: 0xba,\n\t0x578: 0xba, 0x579: 0xba, 0x57a: 0xba, 0x57b: 0xba, 0x57c: 0xba, 0x57d: 0xba, 0x57e: 0xba, 0x57f: 0xba,\n\t// Block 0x16, offset 0x580\n\t0x580: 0x9f, 0x581: 0x9f, 0x582: 0x9f, 0x583: 0x9f, 0x584: 0x162, 0x585: 0x163, 0x586: 0x9f, 0x587: 0x9f,\n\t0x588: 0x9f, 0x589: 0x9f, 0x58a: 0x9f, 0x58b: 0x164, 0x58c: 0xba, 0x58d: 0xba, 0x58e: 0xba, 0x58f: 0xba,\n\t0x590: 0xba, 0x591: 0xba, 0x592: 0xba, 0x593: 0xba, 0x594: 0xba, 0x595: 0xba, 0x596: 0xba, 0x597: 0xba,\n\t0x598: 0xba, 0x599: 0xba, 0x59a: 0xba, 0x59b: 0xba, 0x59c: 0xba, 0x59d: 0xba, 0x59e: 0xba, 0x59f: 0xba,\n\t0x5a0: 0xba, 0x5a1: 0xba, 0x5a2: 0xba, 0x5a3: 0xba, 0x5a4: 0xba, 0x5a5: 0xba, 0x5a6: 0xba, 0x5a7: 0xba,\n\t0x5a8: 0xba, 0x5a9: 0xba, 0x5aa: 0xba, 0x5ab: 0xba, 0x5ac: 0xba, 0x5ad: 0xba, 0x5ae: 0xba, 0x5af: 0xba,\n\t0x5b0: 0x9f, 0x5b1: 0x165, 0x5b2: 0x166, 0x5b3: 0xba, 0x5b4: 0xba, 0x5b5: 0xba, 0x5b6: 0xba, 0x5b7: 0xba,\n\t0x5b8: 0xba, 0x5b9: 0xba, 0x5ba: 0xba, 0x5bb: 0xba, 0x5bc: 0xba, 0x5bd: 0xba, 0x5be: 0xba, 0x5bf: 0xba,\n\t// Block 0x17, offset 0x5c0\n\t0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x167, 0x5c4: 0x168, 0x5c5: 0x169, 0x5c6: 0x16a, 0x5c7: 0x16b,\n\t0x5c8: 0x9b, 0x5c9: 0x16c, 0x5ca: 0xba, 0x5cb: 0x16d, 0x5cc: 0x9b, 0x5cd: 0x16e, 0x5ce: 0xba, 0x5cf: 0xba,\n\t0x5d0: 0x5f, 0x5d1: 0x60, 0x5d2: 0x61, 0x5d3: 0x62, 0x5d4: 0x63, 0x5d5: 0x64, 0x5d6: 0x65, 0x5d7: 0x66,\n\t0x5d8: 0x67, 0x5d9: 0x68, 0x5da: 0x69, 0x5db: 0x6a, 0x5dc: 0x6b, 0x5dd: 0x6c, 0x5de: 0x6d, 0x5df: 0x6e,\n\t0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b,\n\t0x5e8: 0x16f, 0x5e9: 0x170, 0x5ea: 0x171, 0x5eb: 0xba, 0x5ec: 0xba, 0x5ed: 0xba, 0x5ee: 0xba, 0x5ef: 0xba,\n\t0x5f0: 0xba, 0x5f1: 0xba, 0x5f2: 0xba, 0x5f3: 0xba, 0x5f4: 0xba, 0x5f5: 0xba, 0x5f6: 0xba, 0x5f7: 0xba,\n\t0x5f8: 0xba, 0x5f9: 0xba, 0x5fa: 0xba, 0x5fb: 0xba, 0x5fc: 0xba, 0x5fd: 0xba, 0x5fe: 0xba, 0x5ff: 0xba,\n\t// Block 0x18, offset 0x600\n\t0x600: 0x172, 0x601: 0xba, 0x602: 0xba, 0x603: 0xba, 0x604: 0x173, 0x605: 0x174, 0x606: 0xba, 0x607: 0xba,\n\t0x608: 0xba, 0x609: 0xba, 0x60a: 0xba, 0x60b: 0x175, 0x60c: 0xba, 0x60d: 0xba, 0x60e: 0xba, 0x60f: 0xba,\n\t0x610: 0xba, 0x611: 0xba, 0x612: 0xba, 0x613: 0xba, 0x614: 0xba, 0x615: 0xba, 0x616: 0xba, 0x617: 0xba,\n\t0x618: 0xba, 0x619: 0xba, 0x61a: 0xba, 0x61b: 0xba, 0x61c: 0xba, 0x61d: 0xba, 0x61e: 0xba, 0x61f: 0xba,\n\t0x620: 0x121, 0x621: 0x121, 0x622: 0x121, 0x623: 0x176, 0x624: 0x6f, 0x625: 0x177, 0x626: 0xba, 0x627: 0xba,\n\t0x628: 0xba, 0x629: 0xba, 0x62a: 0xba, 0x62b: 0xba, 0x62c: 0xba, 0x62d: 0xba, 0x62e: 0xba, 0x62f: 0xba,\n\t0x630: 0xba, 0x631: 0x178, 0x632: 0x179, 0x633: 0xba, 0x634: 0x17a, 0x635: 0xba, 0x636: 0xba, 0x637: 0xba,\n\t0x638: 0x70, 0x639: 0x71, 0x63a: 0x72, 0x63b: 0x17b, 0x63c: 0xba, 0x63d: 0xba, 0x63e: 0xba, 0x63f: 0xba,\n\t// Block 0x19, offset 0x640\n\t0x640: 0x17c, 0x641: 0x9b, 0x642: 0x17d, 0x643: 0x17e, 0x644: 0x73, 0x645: 0x74, 0x646: 0x17f, 0x647: 0x180,\n\t0x648: 0x75, 0x649: 0x181, 0x64a: 0xba, 0x64b: 0xba, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b,\n\t0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b,\n\t0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x182, 0x65c: 0x9b, 0x65d: 0x183, 0x65e: 0x9b, 0x65f: 0x184,\n\t0x660: 0x185, 0x661: 0x186, 0x662: 0x187, 0x663: 0xba, 0x664: 0x188, 0x665: 0x189, 0x666: 0x18a, 0x667: 0x18b,\n\t0x668: 0x9b, 0x669: 0x18c, 0x66a: 0x18d, 0x66b: 0xba, 0x66c: 0xba, 0x66d: 0xba, 0x66e: 0xba, 0x66f: 0xba,\n\t0x670: 0xba, 0x671: 0xba, 0x672: 0xba, 0x673: 0xba, 0x674: 0xba, 0x675: 0xba, 0x676: 0xba, 0x677: 0xba,\n\t0x678: 0xba, 0x679: 0xba, 0x67a: 0xba, 0x67b: 0xba, 0x67c: 0xba, 0x67d: 0xba, 0x67e: 0xba, 0x67f: 0xba,\n\t// Block 0x1a, offset 0x680\n\t0x680: 0x9f, 0x681: 0x9f, 0x682: 0x9f, 0x683: 0x9f, 0x684: 0x9f, 0x685: 0x9f, 0x686: 0x9f, 0x687: 0x9f,\n\t0x688: 0x9f, 0x689: 0x9f, 0x68a: 0x9f, 0x68b: 0x9f, 0x68c: 0x9f, 0x68d: 0x9f, 0x68e: 0x9f, 0x68f: 0x9f,\n\t0x690: 0x9f, 0x691: 0x9f, 0x692: 0x9f, 0x693: 0x9f, 0x694: 0x9f, 0x695: 0x9f, 0x696: 0x9f, 0x697: 0x9f,\n\t0x698: 0x9f, 0x699: 0x9f, 0x69a: 0x9f, 0x69b: 0x18e, 0x69c: 0x9f, 0x69d: 0x9f, 0x69e: 0x9f, 0x69f: 0x9f,\n\t0x6a0: 0x9f, 0x6a1: 0x9f, 0x6a2: 0x9f, 0x6a3: 0x9f, 0x6a4: 0x9f, 0x6a5: 0x9f, 0x6a6: 0x9f, 0x6a7: 0x9f,\n\t0x6a8: 0x9f, 0x6a9: 0x9f, 0x6aa: 0x9f, 0x6ab: 0x9f, 0x6ac: 0x9f, 0x6ad: 0x9f, 0x6ae: 0x9f, 0x6af: 0x9f,\n\t0x6b0: 0x9f, 0x6b1: 0x9f, 0x6b2: 0x9f, 0x6b3: 0x9f, 0x6b4: 0x9f, 0x6b5: 0x9f, 0x6b6: 0x9f, 0x6b7: 0x9f,\n\t0x6b8: 0x9f, 0x6b9: 0x9f, 0x6ba: 0x9f, 0x6bb: 0x9f, 0x6bc: 0x9f, 0x6bd: 0x9f, 0x6be: 0x9f, 0x6bf: 0x9f,\n\t// Block 0x1b, offset 0x6c0\n\t0x6c0: 0x9f, 0x6c1: 0x9f, 0x6c2: 0x9f, 0x6c3: 0x9f, 0x6c4: 0x9f, 0x6c5: 0x9f, 0x6c6: 0x9f, 0x6c7: 0x9f,\n\t0x6c8: 0x9f, 0x6c9: 0x9f, 0x6ca: 0x9f, 0x6cb: 0x9f, 0x6cc: 0x9f, 0x6cd: 0x9f, 0x6ce: 0x9f, 0x6cf: 0x9f,\n\t0x6d0: 0x9f, 0x6d1: 0x9f, 0x6d2: 0x9f, 0x6d3: 0x9f, 0x6d4: 0x9f, 0x6d5: 0x9f, 0x6d6: 0x9f, 0x6d7: 0x9f,\n\t0x6d8: 0x9f, 0x6d9: 0x9f, 0x6da: 0x9f, 0x6db: 0x9f, 0x6dc: 0x18f, 0x6dd: 0x9f, 0x6de: 0x9f, 0x6df: 0x9f,\n\t0x6e0: 0x190, 0x6e1: 0x9f, 0x6e2: 0x9f, 0x6e3: 0x9f, 0x6e4: 0x9f, 0x6e5: 0x9f, 0x6e6: 0x9f, 0x6e7: 0x9f,\n\t0x6e8: 0x9f, 0x6e9: 0x9f, 0x6ea: 0x9f, 0x6eb: 0x9f, 0x6ec: 0x9f, 0x6ed: 0x9f, 0x6ee: 0x9f, 0x6ef: 0x9f,\n\t0x6f0: 0x9f, 0x6f1: 0x9f, 0x6f2: 0x9f, 0x6f3: 0x9f, 0x6f4: 0x9f, 0x6f5: 0x9f, 0x6f6: 0x9f, 0x6f7: 0x9f,\n\t0x6f8: 0x9f, 0x6f9: 0x9f, 0x6fa: 0x9f, 0x6fb: 0x9f, 0x6fc: 0x9f, 0x6fd: 0x9f, 0x6fe: 0x9f, 0x6ff: 0x9f,\n\t// Block 0x1c, offset 0x700\n\t0x700: 0x9f, 0x701: 0x9f, 0x702: 0x9f, 0x703: 0x9f, 0x704: 0x9f, 0x705: 0x9f, 0x706: 0x9f, 0x707: 0x9f,\n\t0x708: 0x9f, 0x709: 0x9f, 0x70a: 0x9f, 0x70b: 0x9f, 0x70c: 0x9f, 0x70d: 0x9f, 0x70e: 0x9f, 0x70f: 0x9f,\n\t0x710: 0x9f, 0x711: 0x9f, 0x712: 0x9f, 0x713: 0x9f, 0x714: 0x9f, 0x715: 0x9f, 0x716: 0x9f, 0x717: 0x9f,\n\t0x718: 0x9f, 0x719: 0x9f, 0x71a: 0x9f, 0x71b: 0x9f, 0x71c: 0x9f, 0x71d: 0x9f, 0x71e: 0x9f, 0x71f: 0x9f,\n\t0x720: 0x9f, 0x721: 0x9f, 0x722: 0x9f, 0x723: 0x9f, 0x724: 0x9f, 0x725: 0x9f, 0x726: 0x9f, 0x727: 0x9f,\n\t0x728: 0x9f, 0x729: 0x9f, 0x72a: 0x9f, 0x72b: 0x9f, 0x72c: 0x9f, 0x72d: 0x9f, 0x72e: 0x9f, 0x72f: 0x9f,\n\t0x730: 0x9f, 0x731: 0x9f, 0x732: 0x9f, 0x733: 0x9f, 0x734: 0x9f, 0x735: 0x9f, 0x736: 0x9f, 0x737: 0x9f,\n\t0x738: 0x9f, 0x739: 0x9f, 0x73a: 0x191, 0x73b: 0x9f, 0x73c: 0x9f, 0x73d: 0x9f, 0x73e: 0x9f, 0x73f: 0x9f,\n\t// Block 0x1d, offset 0x740\n\t0x740: 0x9f, 0x741: 0x9f, 0x742: 0x9f, 0x743: 0x9f, 0x744: 0x9f, 0x745: 0x9f, 0x746: 0x9f, 0x747: 0x9f,\n\t0x748: 0x9f, 0x749: 0x9f, 0x74a: 0x9f, 0x74b: 0x9f, 0x74c: 0x9f, 0x74d: 0x9f, 0x74e: 0x9f, 0x74f: 0x9f,\n\t0x750: 0x9f, 0x751: 0x9f, 0x752: 0x9f, 0x753: 0x9f, 0x754: 0x9f, 0x755: 0x9f, 0x756: 0x9f, 0x757: 0x9f,\n\t0x758: 0x9f, 0x759: 0x9f, 0x75a: 0x9f, 0x75b: 0x9f, 0x75c: 0x9f, 0x75d: 0x9f, 0x75e: 0x9f, 0x75f: 0x9f,\n\t0x760: 0x9f, 0x761: 0x9f, 0x762: 0x9f, 0x763: 0x9f, 0x764: 0x9f, 0x765: 0x9f, 0x766: 0x9f, 0x767: 0x9f,\n\t0x768: 0x9f, 0x769: 0x9f, 0x76a: 0x9f, 0x76b: 0x9f, 0x76c: 0x9f, 0x76d: 0x9f, 0x76e: 0x9f, 0x76f: 0x192,\n\t0x770: 0xba, 0x771: 0xba, 0x772: 0xba, 0x773: 0xba, 0x774: 0xba, 0x775: 0xba, 0x776: 0xba, 0x777: 0xba,\n\t0x778: 0xba, 0x779: 0xba, 0x77a: 0xba, 0x77b: 0xba, 0x77c: 0xba, 0x77d: 0xba, 0x77e: 0xba, 0x77f: 0xba,\n\t// Block 0x1e, offset 0x780\n\t0x780: 0xba, 0x781: 0xba, 0x782: 0xba, 0x783: 0xba, 0x784: 0xba, 0x785: 0xba, 0x786: 0xba, 0x787: 0xba,\n\t0x788: 0xba, 0x789: 0xba, 0x78a: 0xba, 0x78b: 0xba, 0x78c: 0xba, 0x78d: 0xba, 0x78e: 0xba, 0x78f: 0xba,\n\t0x790: 0xba, 0x791: 0xba, 0x792: 0xba, 0x793: 0xba, 0x794: 0xba, 0x795: 0xba, 0x796: 0xba, 0x797: 0xba,\n\t0x798: 0xba, 0x799: 0xba, 0x79a: 0xba, 0x79b: 0xba, 0x79c: 0xba, 0x79d: 0xba, 0x79e: 0xba, 0x79f: 0xba,\n\t0x7a0: 0x76, 0x7a1: 0x77, 0x7a2: 0x78, 0x7a3: 0x193, 0x7a4: 0x79, 0x7a5: 0x7a, 0x7a6: 0x194, 0x7a7: 0x7b,\n\t0x7a8: 0x7c, 0x7a9: 0xba, 0x7aa: 0xba, 0x7ab: 0xba, 0x7ac: 0xba, 0x7ad: 0xba, 0x7ae: 0xba, 0x7af: 0xba,\n\t0x7b0: 0xba, 0x7b1: 0xba, 0x7b2: 0xba, 0x7b3: 0xba, 0x7b4: 0xba, 0x7b5: 0xba, 0x7b6: 0xba, 0x7b7: 0xba,\n\t0x7b8: 0xba, 0x7b9: 0xba, 0x7ba: 0xba, 0x7bb: 0xba, 0x7bc: 0xba, 0x7bd: 0xba, 0x7be: 0xba, 0x7bf: 0xba,\n\t// Block 0x1f, offset 0x7c0\n\t0x7d0: 0x0d, 0x7d1: 0x0e, 0x7d2: 0x0f, 0x7d3: 0x10, 0x7d4: 0x11, 0x7d5: 0x0b, 0x7d6: 0x12, 0x7d7: 0x07,\n\t0x7d8: 0x13, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x14, 0x7dc: 0x0b, 0x7dd: 0x15, 0x7de: 0x16, 0x7df: 0x17,\n\t0x7e0: 0x07, 0x7e1: 0x07, 0x7e2: 0x07, 0x7e3: 0x07, 0x7e4: 0x07, 0x7e5: 0x07, 0x7e6: 0x07, 0x7e7: 0x07,\n\t0x7e8: 0x07, 0x7e9: 0x07, 0x7ea: 0x18, 0x7eb: 0x19, 0x7ec: 0x1a, 0x7ed: 0x07, 0x7ee: 0x1b, 0x7ef: 0x1c,\n\t0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b,\n\t0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b,\n\t// Block 0x20, offset 0x800\n\t0x800: 0x0b, 0x801: 0x0b, 0x802: 0x0b, 0x803: 0x0b, 0x804: 0x0b, 0x805: 0x0b, 0x806: 0x0b, 0x807: 0x0b,\n\t0x808: 0x0b, 0x809: 0x0b, 0x80a: 0x0b, 0x80b: 0x0b, 0x80c: 0x0b, 0x80d: 0x0b, 0x80e: 0x0b, 0x80f: 0x0b,\n\t0x810: 0x0b, 0x811: 0x0b, 0x812: 0x0b, 0x813: 0x0b, 0x814: 0x0b, 0x815: 0x0b, 0x816: 0x0b, 0x817: 0x0b,\n\t0x818: 0x0b, 0x819: 0x0b, 0x81a: 0x0b, 0x81b: 0x0b, 0x81c: 0x0b, 0x81d: 0x0b, 0x81e: 0x0b, 0x81f: 0x0b,\n\t0x820: 0x0b, 0x821: 0x0b, 0x822: 0x0b, 0x823: 0x0b, 0x824: 0x0b, 0x825: 0x0b, 0x826: 0x0b, 0x827: 0x0b,\n\t0x828: 0x0b, 0x829: 0x0b, 0x82a: 0x0b, 0x82b: 0x0b, 0x82c: 0x0b, 0x82d: 0x0b, 0x82e: 0x0b, 0x82f: 0x0b,\n\t0x830: 0x0b, 0x831: 0x0b, 0x832: 0x0b, 0x833: 0x0b, 0x834: 0x0b, 0x835: 0x0b, 0x836: 0x0b, 0x837: 0x0b,\n\t0x838: 0x0b, 0x839: 0x0b, 0x83a: 0x0b, 0x83b: 0x0b, 0x83c: 0x0b, 0x83d: 0x0b, 0x83e: 0x0b, 0x83f: 0x0b,\n\t// Block 0x21, offset 0x840\n\t0x840: 0x195, 0x841: 0x196, 0x842: 0xba, 0x843: 0xba, 0x844: 0x197, 0x845: 0x197, 0x846: 0x197, 0x847: 0x198,\n\t0x848: 0xba, 0x849: 0xba, 0x84a: 0xba, 0x84b: 0xba, 0x84c: 0xba, 0x84d: 0xba, 0x84e: 0xba, 0x84f: 0xba,\n\t0x850: 0xba, 0x851: 0xba, 0x852: 0xba, 0x853: 0xba, 0x854: 0xba, 0x855: 0xba, 0x856: 0xba, 0x857: 0xba,\n\t0x858: 0xba, 0x859: 0xba, 0x85a: 0xba, 0x85b: 0xba, 0x85c: 0xba, 0x85d: 0xba, 0x85e: 0xba, 0x85f: 0xba,\n\t0x860: 0xba, 0x861: 0xba, 0x862: 0xba, 0x863: 0xba, 0x864: 0xba, 0x865: 0xba, 0x866: 0xba, 0x867: 0xba,\n\t0x868: 0xba, 0x869: 0xba, 0x86a: 0xba, 0x86b: 0xba, 0x86c: 0xba, 0x86d: 0xba, 0x86e: 0xba, 0x86f: 0xba,\n\t0x870: 0xba, 0x871: 0xba, 0x872: 0xba, 0x873: 0xba, 0x874: 0xba, 0x875: 0xba, 0x876: 0xba, 0x877: 0xba,\n\t0x878: 0xba, 0x879: 0xba, 0x87a: 0xba, 0x87b: 0xba, 0x87c: 0xba, 0x87d: 0xba, 0x87e: 0xba, 0x87f: 0xba,\n\t// Block 0x22, offset 0x880\n\t0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b,\n\t0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b,\n\t0x890: 0x0b, 0x891: 0x0b, 0x892: 0x0b, 0x893: 0x0b, 0x894: 0x0b, 0x895: 0x0b, 0x896: 0x0b, 0x897: 0x0b,\n\t0x898: 0x0b, 0x899: 0x0b, 0x89a: 0x0b, 0x89b: 0x0b, 0x89c: 0x0b, 0x89d: 0x0b, 0x89e: 0x0b, 0x89f: 0x0b,\n\t0x8a0: 0x1f, 0x8a1: 0x0b, 0x8a2: 0x0b, 0x8a3: 0x0b, 0x8a4: 0x0b, 0x8a5: 0x0b, 0x8a6: 0x0b, 0x8a7: 0x0b,\n\t0x8a8: 0x0b, 0x8a9: 0x0b, 0x8aa: 0x0b, 0x8ab: 0x0b, 0x8ac: 0x0b, 0x8ad: 0x0b, 0x8ae: 0x0b, 0x8af: 0x0b,\n\t0x8b0: 0x0b, 0x8b1: 0x0b, 0x8b2: 0x0b, 0x8b3: 0x0b, 0x8b4: 0x0b, 0x8b5: 0x0b, 0x8b6: 0x0b, 0x8b7: 0x0b,\n\t0x8b8: 0x0b, 0x8b9: 0x0b, 0x8ba: 0x0b, 0x8bb: 0x0b, 0x8bc: 0x0b, 0x8bd: 0x0b, 0x8be: 0x0b, 0x8bf: 0x0b,\n\t// Block 0x23, offset 0x8c0\n\t0x8c0: 0x0b, 0x8c1: 0x0b, 0x8c2: 0x0b, 0x8c3: 0x0b, 0x8c4: 0x0b, 0x8c5: 0x0b, 0x8c6: 0x0b, 0x8c7: 0x0b,\n\t0x8c8: 0x0b, 0x8c9: 0x0b, 0x8ca: 0x0b, 0x8cb: 0x0b, 0x8cc: 0x0b, 0x8cd: 0x0b, 0x8ce: 0x0b, 0x8cf: 0x0b,\n}\n\n// idnaSparseOffset: 284 entries, 568 bytes\nvar idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x33, 0x3e, 0x4a, 0x4e, 0x5d, 0x62, 0x6c, 0x78, 0x86, 0x8b, 0x94, 0xa4, 0xb2, 0xbe, 0xca, 0xdb, 0xe5, 0xec, 0xf9, 0x10a, 0x111, 0x11c, 0x12b, 0x139, 0x143, 0x145, 0x14a, 0x14d, 0x150, 0x152, 0x15e, 0x169, 0x171, 0x177, 0x17d, 0x182, 0x187, 0x18a, 0x18e, 0x194, 0x199, 0x1a5, 0x1af, 0x1b5, 0x1c6, 0x1d0, 0x1d3, 0x1db, 0x1de, 0x1eb, 0x1f3, 0x1f7, 0x1fe, 0x206, 0x216, 0x222, 0x224, 0x22e, 0x23a, 0x246, 0x252, 0x25a, 0x25f, 0x26c, 0x27d, 0x281, 0x28c, 0x290, 0x299, 0x2a1, 0x2a7, 0x2ac, 0x2af, 0x2b3, 0x2b9, 0x2bd, 0x2c1, 0x2c5, 0x2cb, 0x2d3, 0x2da, 0x2e5, 0x2ef, 0x2f3, 0x2f6, 0x2fc, 0x300, 0x302, 0x305, 0x307, 0x30a, 0x314, 0x317, 0x326, 0x32a, 0x32f, 0x332, 0x336, 0x33b, 0x340, 0x346, 0x352, 0x361, 0x367, 0x36b, 0x37a, 0x37f, 0x387, 0x391, 0x39c, 0x3a4, 0x3b5, 0x3be, 0x3ce, 0x3db, 0x3e5, 0x3ea, 0x3f7, 0x3fb, 0x400, 0x402, 0x406, 0x408, 0x40c, 0x415, 0x41b, 0x41f, 0x42f, 0x439, 0x43e, 0x441, 0x447, 0x44e, 0x453, 0x457, 0x45d, 0x462, 0x46b, 0x470, 0x476, 0x47d, 0x484, 0x48b, 0x48f, 0x494, 0x497, 0x49c, 0x4a8, 0x4ae, 0x4b3, 0x4ba, 0x4c2, 0x4c7, 0x4cb, 0x4db, 0x4e2, 0x4e6, 0x4ea, 0x4f1, 0x4f3, 0x4f6, 0x4f9, 0x4fd, 0x506, 0x50a, 0x512, 0x51a, 0x51e, 0x524, 0x52d, 0x539, 0x540, 0x549, 0x553, 0x55a, 0x568, 0x575, 0x582, 0x58b, 0x58f, 0x59f, 0x5a7, 0x5b2, 0x5bb, 0x5c1, 0x5c9, 0x5d2, 0x5dd, 0x5e0, 0x5ec, 0x5f5, 0x5f8, 0x5fd, 0x602, 0x60f, 0x61a, 0x623, 0x62d, 0x630, 0x63a, 0x643, 0x64f, 0x65c, 0x669, 0x677, 0x67e, 0x682, 0x685, 0x68a, 0x68d, 0x692, 0x695, 0x69c, 0x6a3, 0x6a7, 0x6b2, 0x6b5, 0x6b8, 0x6bb, 0x6c1, 0x6c7, 0x6cd, 0x6d0, 0x6d3, 0x6d6, 0x6dd, 0x6e0, 0x6e5, 0x6ef, 0x6f2, 0x6f6, 0x705, 0x711, 0x715, 0x71a, 0x71e, 0x723, 0x727, 0x72c, 0x735, 0x740, 0x746, 0x74c, 0x752, 0x758, 0x761, 0x764, 0x767, 0x76b, 0x76f, 0x773, 0x779, 0x77f, 0x784, 0x787, 0x797, 0x79e, 0x7a1, 0x7a6, 0x7aa, 0x7b0, 0x7b5, 0x7b9, 0x7bf, 0x7c5, 0x7c9, 0x7d2, 0x7d7, 0x7da, 0x7dd, 0x7e1, 0x7e5, 0x7e8, 0x7f8, 0x809, 0x80e, 0x810, 0x812}\n\n// idnaSparseValues: 2069 entries, 8276 bytes\nvar idnaSparseValues = [2069]valueRange{\n\t// Block 0x0, offset 0x0\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0xe105, lo: 0x80, hi: 0x96},\n\t{value: 0x0018, lo: 0x97, hi: 0x97},\n\t{value: 0xe105, lo: 0x98, hi: 0x9e},\n\t{value: 0x001f, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbf},\n\t// Block 0x1, offset 0x8\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0xe01d, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x82},\n\t{value: 0x0335, lo: 0x83, hi: 0x83},\n\t{value: 0x034d, lo: 0x84, hi: 0x84},\n\t{value: 0x0365, lo: 0x85, hi: 0x85},\n\t{value: 0xe00d, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0xe00d, lo: 0x88, hi: 0x88},\n\t{value: 0x0008, lo: 0x89, hi: 0x89},\n\t{value: 0xe00d, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0x8b},\n\t{value: 0xe00d, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0x8d},\n\t{value: 0xe00d, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0xbf},\n\t// Block 0x2, offset 0x19\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x0249, lo: 0xb0, hi: 0xb0},\n\t{value: 0x037d, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0259, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0269, lo: 0xb3, hi: 0xb3},\n\t{value: 0x034d, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0395, lo: 0xb5, hi: 0xb5},\n\t{value: 0xe1bd, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0279, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0289, lo: 0xb8, hi: 0xb8},\n\t{value: 0x0008, lo: 0xb9, hi: 0xbf},\n\t// Block 0x3, offset 0x25\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x3308, lo: 0x80, hi: 0xbf},\n\t// Block 0x4, offset 0x27\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x03f5, lo: 0x80, hi: 0x8f},\n\t{value: 0xe105, lo: 0x90, hi: 0x9f},\n\t{value: 0x049d, lo: 0xa0, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x5, offset 0x2c\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe185, lo: 0x80, hi: 0x8f},\n\t{value: 0x0545, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x98},\n\t{value: 0x0008, lo: 0x99, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x6, offset 0x33\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0401, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x88},\n\t{value: 0x0018, lo: 0x89, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x3308, lo: 0x91, hi: 0xbd},\n\t{value: 0x0818, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x7, offset 0x3e\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0818, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x82},\n\t{value: 0x0818, lo: 0x83, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x85},\n\t{value: 0x0818, lo: 0x86, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xae},\n\t{value: 0x0808, lo: 0xaf, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x8, offset 0x4a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0a08, lo: 0x80, hi: 0x87},\n\t{value: 0x0c08, lo: 0x88, hi: 0x99},\n\t{value: 0x0a08, lo: 0x9a, hi: 0xbf},\n\t// Block 0x9, offset 0x4e\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3308, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0c08, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0a08, lo: 0x8e, hi: 0x98},\n\t{value: 0x0c08, lo: 0x99, hi: 0x9b},\n\t{value: 0x0a08, lo: 0x9c, hi: 0xaa},\n\t{value: 0x0c08, lo: 0xab, hi: 0xac},\n\t{value: 0x0a08, lo: 0xad, hi: 0xb0},\n\t{value: 0x0c08, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0a08, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0c08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0a08, lo: 0xb5, hi: 0xb7},\n\t{value: 0x0c08, lo: 0xb8, hi: 0xb9},\n\t{value: 0x0a08, lo: 0xba, hi: 0xbf},\n\t// Block 0xa, offset 0x5d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xb0},\n\t{value: 0x0808, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xb, offset 0x62\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0808, lo: 0x80, hi: 0x89},\n\t{value: 0x0a08, lo: 0x8a, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xb3},\n\t{value: 0x0808, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xb9},\n\t{value: 0x0818, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0818, lo: 0xbe, hi: 0xbf},\n\t// Block 0xc, offset 0x6c\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x99},\n\t{value: 0x0808, lo: 0x9a, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0xa3},\n\t{value: 0x0808, lo: 0xa4, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa7},\n\t{value: 0x0808, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0818, lo: 0xb0, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd, offset 0x78\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0a08, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0c08, lo: 0xaa, hi: 0xac},\n\t{value: 0x0808, lo: 0xad, hi: 0xad},\n\t{value: 0x0c08, lo: 0xae, hi: 0xae},\n\t{value: 0x0a08, lo: 0xaf, hi: 0xb0},\n\t{value: 0x0c08, lo: 0xb1, hi: 0xb2},\n\t{value: 0x0a08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0a08, lo: 0xb6, hi: 0xb8},\n\t{value: 0x0c08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0a08, lo: 0xba, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0xe, offset 0x86\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x92},\n\t{value: 0x3308, lo: 0x93, hi: 0xa1},\n\t{value: 0x0840, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xbf},\n\t// Block 0xf, offset 0x8b\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x10, offset 0x94\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x85},\n\t{value: 0x3008, lo: 0x86, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x3008, lo: 0x8a, hi: 0x8c},\n\t{value: 0x3b08, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x11, offset 0xa4\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbf},\n\t// Block 0x12, offset 0xb2\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0xba},\n\t{value: 0x3b08, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x13, offset 0xbe\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0040, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0008, lo: 0xb3, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x14, offset 0xca\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x89},\n\t{value: 0x3b08, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8e},\n\t{value: 0x3008, lo: 0x8f, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x3008, lo: 0x98, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x15, offset 0xdb\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb2},\n\t{value: 0x08f1, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb9},\n\t{value: 0x3b08, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0x16, offset 0xe5\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x8e},\n\t{value: 0x0018, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0xbf},\n\t// Block 0x17, offset 0xec\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x3308, lo: 0x88, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0961, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0999, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0008, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x18, offset 0xf9\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0x8b},\n\t{value: 0xe03d, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3308, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x19, offset 0x10a\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0018, lo: 0x8e, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0xbf},\n\t// Block 0x1a, offset 0x111\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x3008, lo: 0xab, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xb0},\n\t{value: 0x3008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0x1b, offset 0x11c\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x95},\n\t{value: 0x3008, lo: 0x96, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0x9d},\n\t{value: 0x3308, lo: 0x9e, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3008, lo: 0xa2, hi: 0xa4},\n\t{value: 0x0008, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xbf},\n\t// Block 0x1c, offset 0x12b\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x3008, lo: 0x87, hi: 0x8c},\n\t{value: 0x3308, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x8e},\n\t{value: 0x3008, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x3008, lo: 0x9a, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x1d, offset 0x139\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x86},\n\t{value: 0x055d, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8c},\n\t{value: 0x055d, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbb},\n\t{value: 0xe105, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x1e, offset 0x143\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0018, lo: 0x80, hi: 0xbf},\n\t// Block 0x1f, offset 0x145\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xa0},\n\t{value: 0x2018, lo: 0xa1, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0x20, offset 0x14a\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xa7},\n\t{value: 0x2018, lo: 0xa8, hi: 0xbf},\n\t// Block 0x21, offset 0x14d\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x2018, lo: 0x80, hi: 0x82},\n\t{value: 0x0018, lo: 0x83, hi: 0xbf},\n\t// Block 0x22, offset 0x150\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0008, lo: 0x80, hi: 0xbf},\n\t// Block 0x23, offset 0x152\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x24, offset 0x15e\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x25, offset 0x169\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbf},\n\t// Block 0x26, offset 0x171\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbf},\n\t// Block 0x27, offset 0x177\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x28, offset 0x17d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x29, offset 0x182\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0xe045, lo: 0xb8, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x2a, offset 0x187\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xbf},\n\t// Block 0x2b, offset 0x18a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xac},\n\t{value: 0x0018, lo: 0xad, hi: 0xae},\n\t{value: 0x0008, lo: 0xaf, hi: 0xbf},\n\t// Block 0x2c, offset 0x18e\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x2d, offset 0x194\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xb0},\n\t{value: 0x0008, lo: 0xb1, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0x2e, offset 0x199\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x93},\n\t{value: 0x3b08, lo: 0x94, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3b08, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0018, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x2f, offset 0x1a5\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x30, offset 0x1af\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xb3},\n\t{value: 0x3340, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3008, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x31, offset 0x1b5\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x3008, lo: 0x80, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x3008, lo: 0x87, hi: 0x88},\n\t{value: 0x3308, lo: 0x89, hi: 0x91},\n\t{value: 0x3b08, lo: 0x92, hi: 0x92},\n\t{value: 0x3308, lo: 0x93, hi: 0x93},\n\t{value: 0x0018, lo: 0x94, hi: 0x96},\n\t{value: 0x0008, lo: 0x97, hi: 0x97},\n\t{value: 0x0018, lo: 0x98, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x32, offset 0x1c6\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0018, lo: 0x80, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x86},\n\t{value: 0x0218, lo: 0x87, hi: 0x87},\n\t{value: 0x0018, lo: 0x88, hi: 0x8a},\n\t{value: 0x33c0, lo: 0x8b, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0208, lo: 0xa0, hi: 0xbf},\n\t// Block 0x33, offset 0x1d0\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0208, lo: 0x80, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0x34, offset 0x1d3\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x0208, lo: 0x87, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0208, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x35, offset 0x1db\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0x36, offset 0x1de\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb8},\n\t{value: 0x3308, lo: 0xb9, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x37, offset 0x1eb\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x38, offset 0x1f3\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x39, offset 0x1f7\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0028, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0xbf},\n\t// Block 0x3a, offset 0x1fe\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x3308, lo: 0x97, hi: 0x98},\n\t{value: 0x3008, lo: 0x99, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x3b, offset 0x206\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x94},\n\t{value: 0x3008, lo: 0x95, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3b08, lo: 0xa0, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xac},\n\t{value: 0x3008, lo: 0xad, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x3c, offset 0x216\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0018, lo: 0xa8, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xbd},\n\t{value: 0x3318, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x3d, offset 0x222\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0040, lo: 0x80, hi: 0xbf},\n\t// Block 0x3e, offset 0x224\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x3308, lo: 0x80, hi: 0x83},\n\t{value: 0x3008, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x3f, offset 0x22e\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x3808, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x40, offset 0x23a\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa9},\n\t{value: 0x3808, lo: 0xaa, hi: 0xaa},\n\t{value: 0x3b08, lo: 0xab, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xbf},\n\t// Block 0x41, offset 0x246\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa9},\n\t{value: 0x3008, lo: 0xaa, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3808, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbf},\n\t// Block 0x42, offset 0x252\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x3008, lo: 0xa4, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbf},\n\t// Block 0x43, offset 0x25a\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0x44, offset 0x25f\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0e29, lo: 0x80, hi: 0x80},\n\t{value: 0x0e41, lo: 0x81, hi: 0x81},\n\t{value: 0x0e59, lo: 0x82, hi: 0x82},\n\t{value: 0x0e71, lo: 0x83, hi: 0x83},\n\t{value: 0x0e89, lo: 0x84, hi: 0x85},\n\t{value: 0x0ea1, lo: 0x86, hi: 0x86},\n\t{value: 0x0eb9, lo: 0x87, hi: 0x87},\n\t{value: 0x057d, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x059d, lo: 0x90, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbc},\n\t{value: 0x059d, lo: 0xbd, hi: 0xbf},\n\t// Block 0x45, offset 0x26c\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x92},\n\t{value: 0x0018, lo: 0x93, hi: 0x93},\n\t{value: 0x3308, lo: 0x94, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa8},\n\t{value: 0x0008, lo: 0xa9, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x3008, lo: 0xb7, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x46, offset 0x27d\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3308, lo: 0x80, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbf},\n\t// Block 0x47, offset 0x281\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x87},\n\t{value: 0xe045, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0xe045, lo: 0x98, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0xe045, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb7},\n\t{value: 0xe045, lo: 0xb8, hi: 0xbf},\n\t// Block 0x48, offset 0x28c\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x3318, lo: 0x90, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbf},\n\t// Block 0x49, offset 0x290\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x88},\n\t{value: 0x24c1, lo: 0x89, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x4a, offset 0x299\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0xab},\n\t{value: 0x24f1, lo: 0xac, hi: 0xac},\n\t{value: 0x2529, lo: 0xad, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xae},\n\t{value: 0x2579, lo: 0xaf, hi: 0xaf},\n\t{value: 0x25b1, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0018, lo: 0xb1, hi: 0xbf},\n\t// Block 0x4b, offset 0x2a1\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x9f},\n\t{value: 0x0080, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xad},\n\t{value: 0x0080, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x4c, offset 0x2a7\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xa8},\n\t{value: 0x09dd, lo: 0xa9, hi: 0xa9},\n\t{value: 0x09fd, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xbf},\n\t// Block 0x4d, offset 0x2ac\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xbf},\n\t// Block 0x4e, offset 0x2af\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x28c1, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0xbf},\n\t// Block 0x4f, offset 0x2b3\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0e7e, lo: 0xb4, hi: 0xb4},\n\t{value: 0x292a, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0e9e, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0x50, offset 0x2b9\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x9b},\n\t{value: 0x2941, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0xbf},\n\t// Block 0x51, offset 0x2bd\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0x52, offset 0x2c1\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0018, lo: 0x98, hi: 0xbf},\n\t// Block 0x53, offset 0x2c5\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0xe185, lo: 0x80, hi: 0x8f},\n\t{value: 0x03f5, lo: 0x90, hi: 0x9f},\n\t{value: 0x0ebd, lo: 0xa0, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x54, offset 0x2cb\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xac},\n\t{value: 0x0008, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x55, offset 0x2d3\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xae},\n\t{value: 0xe075, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0x56, offset 0x2da\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x57, offset 0x2e5\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xbf},\n\t// Block 0x58, offset 0x2ef\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xae},\n\t{value: 0x0008, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x59, offset 0x2f3\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0xbf},\n\t// Block 0x5a, offset 0x2f6\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9e},\n\t{value: 0x0ef5, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbf},\n\t// Block 0x5b, offset 0x2fc\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb2},\n\t{value: 0x0f15, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x5c, offset 0x300\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x0f35, lo: 0x80, hi: 0xbf},\n\t// Block 0x5d, offset 0x302\n\t{value: 0x0020, lo: 0x02},\n\t{value: 0x1735, lo: 0x80, hi: 0x8f},\n\t{value: 0x1915, lo: 0x90, hi: 0xbf},\n\t// Block 0x5e, offset 0x305\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x1f15, lo: 0x80, hi: 0xbf},\n\t// Block 0x5f, offset 0x307\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xbf},\n\t// Block 0x60, offset 0x30a\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x98},\n\t{value: 0x3308, lo: 0x99, hi: 0x9a},\n\t{value: 0x29e2, lo: 0x9b, hi: 0x9b},\n\t{value: 0x2a0a, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0008, lo: 0x9d, hi: 0x9e},\n\t{value: 0x2a31, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xbf},\n\t// Block 0x61, offset 0x314\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xbe},\n\t{value: 0x2a69, lo: 0xbf, hi: 0xbf},\n\t// Block 0x62, offset 0x317\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0040, lo: 0x80, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xb0},\n\t{value: 0x2a35, lo: 0xb1, hi: 0xb1},\n\t{value: 0x2a55, lo: 0xb2, hi: 0xb2},\n\t{value: 0x2a75, lo: 0xb3, hi: 0xb3},\n\t{value: 0x2a95, lo: 0xb4, hi: 0xb4},\n\t{value: 0x2a75, lo: 0xb5, hi: 0xb5},\n\t{value: 0x2ab5, lo: 0xb6, hi: 0xb6},\n\t{value: 0x2ad5, lo: 0xb7, hi: 0xb7},\n\t{value: 0x2af5, lo: 0xb8, hi: 0xb9},\n\t{value: 0x2b15, lo: 0xba, hi: 0xbb},\n\t{value: 0x2b35, lo: 0xbc, hi: 0xbd},\n\t{value: 0x2b15, lo: 0xbe, hi: 0xbf},\n\t// Block 0x63, offset 0x326\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x64, offset 0x32a\n\t{value: 0x0030, lo: 0x04},\n\t{value: 0x2aa2, lo: 0x80, hi: 0x9d},\n\t{value: 0x305a, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x30a2, lo: 0xa0, hi: 0xbf},\n\t// Block 0x65, offset 0x32f\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x66, offset 0x332\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x67, offset 0x336\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0x68, offset 0x33b\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xbf},\n\t// Block 0x69, offset 0x340\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x0018, lo: 0xa6, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0018, lo: 0xb2, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x6a, offset 0x346\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0040, lo: 0x80, hi: 0x81},\n\t{value: 0xe00d, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0x83},\n\t{value: 0x03f5, lo: 0x84, hi: 0x84},\n\t{value: 0x1329, lo: 0x85, hi: 0x85},\n\t{value: 0x447d, lo: 0x86, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0xb6},\n\t{value: 0x0008, lo: 0xb7, hi: 0xb7},\n\t{value: 0x2009, lo: 0xb8, hi: 0xb8},\n\t{value: 0x6e89, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xbf},\n\t// Block 0x6b, offset 0x352\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0x85},\n\t{value: 0x3b08, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x8a},\n\t{value: 0x3308, lo: 0x8b, hi: 0x8b},\n\t{value: 0x0008, lo: 0x8c, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0018, lo: 0xa8, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x6c, offset 0x361\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0208, lo: 0x80, hi: 0xb1},\n\t{value: 0x0108, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0008, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x6d, offset 0x367\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xbf},\n\t// Block 0x6e, offset 0x36b\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3008, lo: 0x80, hi: 0x83},\n\t{value: 0x3b08, lo: 0x84, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8d},\n\t{value: 0x0018, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xba},\n\t{value: 0x0008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x6f, offset 0x37a\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x70, offset 0x37f\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x91},\n\t{value: 0x3008, lo: 0x92, hi: 0x92},\n\t{value: 0x3808, lo: 0x93, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x71, offset 0x387\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb9},\n\t{value: 0x3008, lo: 0xba, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x72, offset 0x391\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3808, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x73, offset 0x39c\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x74, offset 0x3a4\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x8b},\n\t{value: 0x3308, lo: 0x8c, hi: 0x8c},\n\t{value: 0x3008, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0018, lo: 0x9c, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x75, offset 0x3b5\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0008, lo: 0xb9, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbf},\n\t// Block 0x76, offset 0x3be\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x9a},\n\t{value: 0x0008, lo: 0x9b, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xaa},\n\t{value: 0x3008, lo: 0xab, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3b08, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x77, offset 0x3ce\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x88},\n\t{value: 0x0008, lo: 0x89, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x90},\n\t{value: 0x0008, lo: 0x91, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x78, offset 0x3db\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x449d, lo: 0x9c, hi: 0x9c},\n\t{value: 0x44b5, lo: 0x9d, hi: 0x9d},\n\t{value: 0x2971, lo: 0x9e, hi: 0x9e},\n\t{value: 0xe06d, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x44cd, lo: 0xb0, hi: 0xbf},\n\t// Block 0x79, offset 0x3e5\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x44ed, lo: 0x80, hi: 0x8f},\n\t{value: 0x450d, lo: 0x90, hi: 0x9f},\n\t{value: 0x452d, lo: 0xa0, hi: 0xaf},\n\t{value: 0x450d, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7a, offset 0x3ea\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3b08, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x7b, offset 0x3f7\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7c, offset 0x3fb\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8a},\n\t{value: 0x0018, lo: 0x8b, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x7d, offset 0x400\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x454d, lo: 0x80, hi: 0xbf},\n\t// Block 0x7e, offset 0x402\n\t{value: 0x0020, lo: 0x03},\n\t{value: 0x4d4d, lo: 0x80, hi: 0x94},\n\t{value: 0x4b0d, lo: 0x95, hi: 0x95},\n\t{value: 0x4fed, lo: 0x96, hi: 0xbf},\n\t// Block 0x7f, offset 0x406\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x552d, lo: 0x80, hi: 0xbf},\n\t// Block 0x80, offset 0x408\n\t{value: 0x0020, lo: 0x03},\n\t{value: 0x5d2d, lo: 0x80, hi: 0x84},\n\t{value: 0x568d, lo: 0x85, hi: 0x85},\n\t{value: 0x5dcd, lo: 0x86, hi: 0xbf},\n\t// Block 0x81, offset 0x40c\n\t{value: 0x0020, lo: 0x08},\n\t{value: 0x6b8d, lo: 0x80, hi: 0x8f},\n\t{value: 0x6d4d, lo: 0x90, hi: 0x90},\n\t{value: 0x6d8d, lo: 0x91, hi: 0xab},\n\t{value: 0x6ea1, lo: 0xac, hi: 0xac},\n\t{value: 0x70ed, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x710d, lo: 0xb0, hi: 0xbf},\n\t// Block 0x82, offset 0x415\n\t{value: 0x0020, lo: 0x05},\n\t{value: 0x730d, lo: 0x80, hi: 0xad},\n\t{value: 0x656d, lo: 0xae, hi: 0xae},\n\t{value: 0x78cd, lo: 0xaf, hi: 0xb5},\n\t{value: 0x6f8d, lo: 0xb6, hi: 0xb6},\n\t{value: 0x79ad, lo: 0xb7, hi: 0xbf},\n\t// Block 0x83, offset 0x41b\n\t{value: 0x0028, lo: 0x03},\n\t{value: 0x7c21, lo: 0x80, hi: 0x82},\n\t{value: 0x7be1, lo: 0x83, hi: 0x83},\n\t{value: 0x7c99, lo: 0x84, hi: 0xbf},\n\t// Block 0x84, offset 0x41f\n\t{value: 0x0038, lo: 0x0f},\n\t{value: 0x9db1, lo: 0x80, hi: 0x83},\n\t{value: 0x9e59, lo: 0x84, hi: 0x85},\n\t{value: 0x9e91, lo: 0x86, hi: 0x87},\n\t{value: 0x9ec9, lo: 0x88, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0xa089, lo: 0x92, hi: 0x97},\n\t{value: 0xa1a1, lo: 0x98, hi: 0x9c},\n\t{value: 0xa281, lo: 0x9d, hi: 0xb3},\n\t{value: 0x9d41, lo: 0xb4, hi: 0xb4},\n\t{value: 0x9db1, lo: 0xb5, hi: 0xb5},\n\t{value: 0xa789, lo: 0xb6, hi: 0xbb},\n\t{value: 0xa869, lo: 0xbc, hi: 0xbc},\n\t{value: 0xa7f9, lo: 0xbd, hi: 0xbd},\n\t{value: 0xa8d9, lo: 0xbe, hi: 0xbf},\n\t// Block 0x85, offset 0x42f\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0008, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0x86, offset 0x439\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0x87, offset 0x43e\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x88, offset 0x441\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0x89, offset 0x447\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0040, lo: 0xa1, hi: 0xbf},\n\t// Block 0x8a, offset 0x44e\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x8b, offset 0x453\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x8c, offset 0x457\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x8d, offset 0x45d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xac},\n\t{value: 0x0008, lo: 0xad, hi: 0xbf},\n\t// Block 0x8e, offset 0x462\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x8f, offset 0x46b\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x90, offset 0x470\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0xbf},\n\t// Block 0x91, offset 0x476\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe145, lo: 0x80, hi: 0x87},\n\t{value: 0xe1c5, lo: 0x88, hi: 0x8f},\n\t{value: 0xe145, lo: 0x90, hi: 0x97},\n\t{value: 0x8b0d, lo: 0x98, hi: 0x9f},\n\t{value: 0x8b25, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xbf},\n\t// Block 0x92, offset 0x47d\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x8b25, lo: 0xb0, hi: 0xb7},\n\t{value: 0x8b0d, lo: 0xb8, hi: 0xbf},\n\t// Block 0x93, offset 0x484\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe145, lo: 0x80, hi: 0x87},\n\t{value: 0xe1c5, lo: 0x88, hi: 0x8f},\n\t{value: 0xe145, lo: 0x90, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x94, offset 0x48b\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x95, offset 0x48f\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xae},\n\t{value: 0x0018, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x96, offset 0x494\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x97, offset 0x497\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xbf},\n\t// Block 0x98, offset 0x49c\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x87},\n\t{value: 0x0808, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0808, lo: 0x8a, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0808, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbb},\n\t{value: 0x0808, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbe},\n\t{value: 0x0808, lo: 0xbf, hi: 0xbf},\n\t// Block 0x99, offset 0x4a8\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x96},\n\t{value: 0x0818, lo: 0x97, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0818, lo: 0xb7, hi: 0xbf},\n\t// Block 0x9a, offset 0x4ae\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xa6},\n\t{value: 0x0818, lo: 0xa7, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x9b, offset 0x4b3\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0808, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xba},\n\t{value: 0x0818, lo: 0xbb, hi: 0xbf},\n\t// Block 0x9c, offset 0x4ba\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0818, lo: 0x96, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbe},\n\t{value: 0x0818, lo: 0xbf, hi: 0xbf},\n\t// Block 0x9d, offset 0x4c2\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbb},\n\t{value: 0x0818, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0808, lo: 0xbe, hi: 0xbf},\n\t// Block 0x9e, offset 0x4c7\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0818, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x91},\n\t{value: 0x0818, lo: 0x92, hi: 0xbf},\n\t// Block 0x9f, offset 0x4cb\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0808, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8b},\n\t{value: 0x3308, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x94},\n\t{value: 0x0808, lo: 0x95, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0x98},\n\t{value: 0x0808, lo: 0x99, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xa0, offset 0x4db\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0818, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x0818, lo: 0x90, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xbc},\n\t{value: 0x0818, lo: 0xbd, hi: 0xbf},\n\t// Block 0xa1, offset 0x4e2\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0x9c},\n\t{value: 0x0818, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xa2, offset 0x4e6\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb8},\n\t{value: 0x0018, lo: 0xb9, hi: 0xbf},\n\t// Block 0xa3, offset 0x4ea\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0818, lo: 0x98, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb7},\n\t{value: 0x0818, lo: 0xb8, hi: 0xbf},\n\t// Block 0xa4, offset 0x4f1\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0808, lo: 0x80, hi: 0xbf},\n\t// Block 0xa5, offset 0x4f3\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0808, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0xbf},\n\t// Block 0xa6, offset 0x4f6\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x03dd, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbf},\n\t// Block 0xa7, offset 0x4f9\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb9},\n\t{value: 0x0818, lo: 0xba, hi: 0xbf},\n\t// Block 0xa8, offset 0x4fd\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0908, lo: 0x80, hi: 0x80},\n\t{value: 0x0a08, lo: 0x81, hi: 0xa1},\n\t{value: 0x0c08, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0a08, lo: 0xa3, hi: 0xa3},\n\t{value: 0x3308, lo: 0xa4, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0808, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xa9, offset 0x506\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0818, lo: 0xa0, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xaa, offset 0x50a\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0x9c},\n\t{value: 0x0818, lo: 0x9d, hi: 0xa6},\n\t{value: 0x0808, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0a08, lo: 0xb0, hi: 0xb2},\n\t{value: 0x0c08, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0a08, lo: 0xb4, hi: 0xbf},\n\t// Block 0xab, offset 0x512\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0a08, lo: 0x80, hi: 0x84},\n\t{value: 0x0808, lo: 0x85, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x90},\n\t{value: 0x0a18, lo: 0x91, hi: 0x93},\n\t{value: 0x0c18, lo: 0x94, hi: 0x94},\n\t{value: 0x0818, lo: 0x95, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xac, offset 0x51a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xad, offset 0x51e\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbf},\n\t// Block 0xae, offset 0x524\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x85},\n\t{value: 0x3b08, lo: 0x86, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x91},\n\t{value: 0x0018, lo: 0x92, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xaf, offset 0x52d\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb6},\n\t{value: 0x3008, lo: 0xb7, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0xb0, offset 0x539\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x81},\n\t{value: 0x0040, lo: 0x82, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xb1, offset 0x540\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xb2},\n\t{value: 0x3b08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0008, lo: 0xb6, hi: 0xbf},\n\t// Block 0xb2, offset 0x549\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0018, lo: 0x80, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x3008, lo: 0x85, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0008, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xb3, offset 0x553\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xbe},\n\t{value: 0x3008, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb4, offset 0x55a\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x3808, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x88},\n\t{value: 0x3308, lo: 0x89, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xb5, offset 0x568\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x92},\n\t{value: 0x0008, lo: 0x93, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3808, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb6, offset 0x575\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0008, lo: 0x9f, hi: 0xa8},\n\t{value: 0x0018, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0xb7, offset 0x582\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x3308, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3008, lo: 0xa0, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xa9},\n\t{value: 0x3b08, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xb8, offset 0x58b\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbf},\n\t// Block 0xb9, offset 0x58f\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x3b08, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x84},\n\t{value: 0x3008, lo: 0x85, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x8a},\n\t{value: 0x0018, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0x9d},\n\t{value: 0x3308, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0008, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xba, offset 0x59f\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb8},\n\t{value: 0x3008, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbb, offset 0x5a7\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x81},\n\t{value: 0x3b08, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x85},\n\t{value: 0x0018, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xbc, offset 0x5b2\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbd, offset 0x5bb\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x9b},\n\t{value: 0x3308, lo: 0x9c, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0xbe, offset 0x5c1\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbf, offset 0x5c9\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xbf},\n\t// Block 0xc0, offset 0x5d2\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb5},\n\t{value: 0x3808, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xc1, offset 0x5dd\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0xbf},\n\t// Block 0xc2, offset 0x5e0\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9f},\n\t{value: 0x3008, lo: 0xa0, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xaa},\n\t{value: 0x3b08, lo: 0xab, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbf},\n\t// Block 0xc3, offset 0x5ec\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0xc4, offset 0x5f5\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x049d, lo: 0xa0, hi: 0xbf},\n\t// Block 0xc5, offset 0x5f8\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc6, offset 0x5fd\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xbf},\n\t// Block 0xc7, offset 0x602\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x3008, lo: 0x91, hi: 0x93},\n\t{value: 0x3308, lo: 0x94, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0x99},\n\t{value: 0x3308, lo: 0x9a, hi: 0x9b},\n\t{value: 0x3008, lo: 0x9c, hi: 0x9f},\n\t{value: 0x3b08, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x0018, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0008, lo: 0xa3, hi: 0xa3},\n\t{value: 0x3008, lo: 0xa4, hi: 0xa4},\n\t{value: 0x0040, lo: 0xa5, hi: 0xbf},\n\t// Block 0xc8, offset 0x60f\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3b08, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb8},\n\t{value: 0x3008, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc9, offset 0x61a\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x3b08, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x3308, lo: 0x91, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x98},\n\t{value: 0x3308, lo: 0x99, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0xbf},\n\t// Block 0xca, offset 0x623\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x3308, lo: 0x8a, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x98},\n\t{value: 0x3b08, lo: 0x99, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9c},\n\t{value: 0x0008, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0xa2},\n\t{value: 0x0040, lo: 0xa3, hi: 0xbf},\n\t// Block 0xcb, offset 0x62d\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xcc, offset 0x630\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xcd, offset 0x63a\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xbf},\n\t// Block 0xce, offset 0x643\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xa9},\n\t{value: 0x3308, lo: 0xaa, hi: 0xb0},\n\t{value: 0x3008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xcf, offset 0x64f\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd0, offset 0x65c\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x3308, lo: 0x80, hi: 0x83},\n\t{value: 0x3b08, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xbf},\n\t// Block 0xd1, offset 0x669\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x3008, lo: 0x8a, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x92},\n\t{value: 0x3008, lo: 0x93, hi: 0x94},\n\t{value: 0x3308, lo: 0x95, hi: 0x95},\n\t{value: 0x3008, lo: 0x96, hi: 0x96},\n\t{value: 0x3b08, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xbf},\n\t// Block 0xd2, offset 0x677\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xd3, offset 0x67e\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd4, offset 0x682\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xd5, offset 0x685\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xd6, offset 0x68a\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0xbf},\n\t// Block 0xd7, offset 0x68d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0340, lo: 0xb0, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xd8, offset 0x692\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0xbf},\n\t// Block 0xd9, offset 0x695\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0xda, offset 0x69c\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0018, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xdb, offset 0x6a3\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0xdc, offset 0x6a7\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0008, lo: 0xa3, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbf},\n\t// Block 0xdd, offset 0x6b2\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0xbf},\n\t// Block 0xde, offset 0x6b5\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0xe105, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0xdf, offset 0x6b8\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0xbf},\n\t// Block 0xe0, offset 0x6bb\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8e},\n\t{value: 0x3308, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x3008, lo: 0x91, hi: 0xbf},\n\t// Block 0xe1, offset 0x6c1\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3008, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8e},\n\t{value: 0x3308, lo: 0x8f, hi: 0x92},\n\t{value: 0x0008, lo: 0x93, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xe2, offset 0x6c7\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa1},\n\t{value: 0x0018, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0008, lo: 0xa3, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xbf},\n\t// Block 0xe3, offset 0x6cd\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0xe4, offset 0x6d0\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbf},\n\t// Block 0xe5, offset 0x6d3\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xbf},\n\t// Block 0xe6, offset 0x6d6\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x92},\n\t{value: 0x0040, lo: 0x93, hi: 0xa3},\n\t{value: 0x0008, lo: 0xa4, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0xe7, offset 0x6dd\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0xe8, offset 0x6e0\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0xe9, offset 0x6e5\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0018, lo: 0x9c, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x03c0, lo: 0xa0, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xbf},\n\t// Block 0xea, offset 0x6ef\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xeb, offset 0x6f2\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa8},\n\t{value: 0x0018, lo: 0xa9, hi: 0xbf},\n\t// Block 0xec, offset 0x6f6\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0018, lo: 0x80, hi: 0x9d},\n\t{value: 0xb5b9, lo: 0x9e, hi: 0x9e},\n\t{value: 0xb601, lo: 0x9f, hi: 0x9f},\n\t{value: 0xb649, lo: 0xa0, hi: 0xa0},\n\t{value: 0xb6b1, lo: 0xa1, hi: 0xa1},\n\t{value: 0xb719, lo: 0xa2, hi: 0xa2},\n\t{value: 0xb781, lo: 0xa3, hi: 0xa3},\n\t{value: 0xb7e9, lo: 0xa4, hi: 0xa4},\n\t{value: 0x3018, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3318, lo: 0xa7, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xac},\n\t{value: 0x3018, lo: 0xad, hi: 0xb2},\n\t{value: 0x0340, lo: 0xb3, hi: 0xba},\n\t{value: 0x3318, lo: 0xbb, hi: 0xbf},\n\t// Block 0xed, offset 0x705\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3318, lo: 0x80, hi: 0x82},\n\t{value: 0x0018, lo: 0x83, hi: 0x84},\n\t{value: 0x3318, lo: 0x85, hi: 0x8b},\n\t{value: 0x0018, lo: 0x8c, hi: 0xa9},\n\t{value: 0x3318, lo: 0xaa, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xba},\n\t{value: 0xb851, lo: 0xbb, hi: 0xbb},\n\t{value: 0xb899, lo: 0xbc, hi: 0xbc},\n\t{value: 0xb8e1, lo: 0xbd, hi: 0xbd},\n\t{value: 0xb949, lo: 0xbe, hi: 0xbe},\n\t{value: 0xb9b1, lo: 0xbf, hi: 0xbf},\n\t// Block 0xee, offset 0x711\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0xba19, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xbf},\n\t// Block 0xef, offset 0x715\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x81},\n\t{value: 0x3318, lo: 0x82, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0xbf},\n\t// Block 0xf0, offset 0x71a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0xf1, offset 0x71e\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xf2, offset 0x723\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3308, lo: 0x80, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbf},\n\t// Block 0xf3, offset 0x727\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x3308, lo: 0x80, hi: 0xac},\n\t{value: 0x0018, lo: 0xad, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0xf4, offset 0x72c\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x3308, lo: 0xa1, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0xf5, offset 0x735\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x3308, lo: 0x88, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xa4},\n\t{value: 0x0040, lo: 0xa5, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xbf},\n\t// Block 0xf6, offset 0x740\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0008, lo: 0xb7, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0xf7, offset 0x746\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0018, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0xbf},\n\t// Block 0xf8, offset 0x74c\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0xf9, offset 0x752\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0808, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x86},\n\t{value: 0x0818, lo: 0x87, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0xbf},\n\t// Block 0xfa, offset 0x758\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0a08, lo: 0x80, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x8a},\n\t{value: 0x0b08, lo: 0x8b, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0818, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xfb, offset 0x761\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xb0},\n\t{value: 0x0818, lo: 0xb1, hi: 0xbf},\n\t// Block 0xfc, offset 0x764\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0818, lo: 0x80, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xfd, offset 0x767\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0818, lo: 0x81, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0xfe, offset 0x76b\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xff, offset 0x76f\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x100, offset 0x773\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xb0},\n\t{value: 0x0018, lo: 0xb1, hi: 0xbf},\n\t// Block 0x101, offset 0x779\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x0018, lo: 0x91, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0x102, offset 0x77f\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x8f},\n\t{value: 0xc1d9, lo: 0x90, hi: 0x90},\n\t{value: 0x0018, lo: 0x91, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xbf},\n\t// Block 0x103, offset 0x784\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xa5},\n\t{value: 0x0018, lo: 0xa6, hi: 0xbf},\n\t// Block 0x104, offset 0x787\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0xc801, lo: 0x80, hi: 0x80},\n\t{value: 0xc851, lo: 0x81, hi: 0x81},\n\t{value: 0xc8a1, lo: 0x82, hi: 0x82},\n\t{value: 0xc8f1, lo: 0x83, hi: 0x83},\n\t{value: 0xc941, lo: 0x84, hi: 0x84},\n\t{value: 0xc991, lo: 0x85, hi: 0x85},\n\t{value: 0xc9e1, lo: 0x86, hi: 0x86},\n\t{value: 0xca31, lo: 0x87, hi: 0x87},\n\t{value: 0xca81, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0xcad1, lo: 0x90, hi: 0x90},\n\t{value: 0xcaf1, lo: 0x91, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xbf},\n\t// Block 0x105, offset 0x797\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x106, offset 0x79e\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x107, offset 0x7a1\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xbf},\n\t// Block 0x108, offset 0x7a6\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x109, offset 0x7aa\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbf},\n\t// Block 0x10a, offset 0x7b0\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xbf},\n\t// Block 0x10b, offset 0x7b5\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0xbf},\n\t// Block 0x10c, offset 0x7b9\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0018, lo: 0xb3, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbf},\n\t// Block 0x10d, offset 0x7bf\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0xa2},\n\t{value: 0x0040, lo: 0xa3, hi: 0xa4},\n\t{value: 0x0018, lo: 0xa5, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xbf},\n\t// Block 0x10e, offset 0x7c5\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0xbf},\n\t// Block 0x10f, offset 0x7c9\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x110, offset 0x7d2\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0xbf},\n\t// Block 0x111, offset 0x7d7\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0xbf},\n\t// Block 0x112, offset 0x7da\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x113, offset 0x7dd\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x114, offset 0x7e1\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x115, offset 0x7e5\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xa0},\n\t{value: 0x0040, lo: 0xa1, hi: 0xbf},\n\t// Block 0x116, offset 0x7e8\n\t{value: 0x0020, lo: 0x0f},\n\t{value: 0xded1, lo: 0x80, hi: 0x89},\n\t{value: 0x8e35, lo: 0x8a, hi: 0x8a},\n\t{value: 0xe011, lo: 0x8b, hi: 0x9c},\n\t{value: 0x8e55, lo: 0x9d, hi: 0x9d},\n\t{value: 0xe251, lo: 0x9e, hi: 0xa2},\n\t{value: 0x8e75, lo: 0xa3, hi: 0xa3},\n\t{value: 0xe2f1, lo: 0xa4, hi: 0xab},\n\t{value: 0x7f0d, lo: 0xac, hi: 0xac},\n\t{value: 0xe3f1, lo: 0xad, hi: 0xaf},\n\t{value: 0x8e95, lo: 0xb0, hi: 0xb0},\n\t{value: 0xe451, lo: 0xb1, hi: 0xb6},\n\t{value: 0x8eb5, lo: 0xb7, hi: 0xb9},\n\t{value: 0xe511, lo: 0xba, hi: 0xba},\n\t{value: 0x8f15, lo: 0xbb, hi: 0xbb},\n\t{value: 0xe531, lo: 0xbc, hi: 0xbf},\n\t// Block 0x117, offset 0x7f8\n\t{value: 0x0020, lo: 0x10},\n\t{value: 0x93b5, lo: 0x80, hi: 0x80},\n\t{value: 0xf0b1, lo: 0x81, hi: 0x86},\n\t{value: 0x93d5, lo: 0x87, hi: 0x8a},\n\t{value: 0xda11, lo: 0x8b, hi: 0x8b},\n\t{value: 0xf171, lo: 0x8c, hi: 0x96},\n\t{value: 0x9455, lo: 0x97, hi: 0x97},\n\t{value: 0xf2d1, lo: 0x98, hi: 0xa3},\n\t{value: 0x9475, lo: 0xa4, hi: 0xa6},\n\t{value: 0xf451, lo: 0xa7, hi: 0xaa},\n\t{value: 0x94d5, lo: 0xab, hi: 0xab},\n\t{value: 0xf4d1, lo: 0xac, hi: 0xac},\n\t{value: 0x94f5, lo: 0xad, hi: 0xad},\n\t{value: 0xf4f1, lo: 0xae, hi: 0xaf},\n\t{value: 0x9515, lo: 0xb0, hi: 0xb1},\n\t{value: 0xf531, lo: 0xb2, hi: 0xbe},\n\t{value: 0x2040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x118, offset 0x809\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0340, lo: 0x81, hi: 0x81},\n\t{value: 0x0040, lo: 0x82, hi: 0x9f},\n\t{value: 0x0340, lo: 0xa0, hi: 0xbf},\n\t// Block 0x119, offset 0x80e\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0340, lo: 0x80, hi: 0xbf},\n\t// Block 0x11a, offset 0x810\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x33c0, lo: 0x80, hi: 0xbf},\n\t// Block 0x11b, offset 0x812\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x33c0, lo: 0x80, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n}\n\n// Total table size 42780 bytes (41KiB); checksum: 29936AB9\n"
  },
  {
    "path": "vendor/golang.org/x/net/idna/tables13.0.0.go",
    "content": "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n//go:build go1.16 && !go1.21\n\npackage idna\n\n// UnicodeVersion is the Unicode version from which the tables in this package are derived.\nconst UnicodeVersion = \"13.0.0\"\n\nvar mappings string = \"\" + // Size: 6539 bytes\n\t\"  ̈a ̄23 ́ ̧1o1⁄41⁄23⁄4i̇l·ʼnsdžⱥⱦhjrwy ̆ ̇ ̊ ̨ ̃ ̋lẍ́ ι; ̈́եւاٴوٴۇٴيٴक\" +\n\t\"़ख़ग़ज़ड़ढ़फ़य़ড়ঢ়য়ਲ਼ਸ਼ਖ਼ਗ਼ਜ਼ਫ਼ଡ଼ଢ଼ําໍາຫນຫມགྷཌྷདྷབྷཛྷཀྵཱཱིུྲྀྲཱྀླྀླཱ\" +\n\t\"ཱྀྀྒྷྜྷྡྷྦྷྫྷྐྵвдостъѣæbdeǝgikmnȣptuɐɑəɛɜŋɔɯvβγδφχρнɒcɕðfɟɡɥɨɩɪʝɭʟɱɰɲɳ\" +\n\t\"ɴɵɸʂʃƫʉʊʋʌzʐʑʒθssάέήίόύώἀιἁιἂιἃιἄιἅιἆιἇιἠιἡιἢιἣιἤιἥιἦιἧιὠιὡιὢιὣιὤιὥιὦιὧ\" +\n\t\"ιὰιαιάιᾶιι ̈͂ὴιηιήιῆι ̓̀ ̓́ ̓͂ΐ ̔̀ ̔́ ̔͂ΰ ̈̀`ὼιωιώιῶι′′′′′‵‵‵‵‵!!???!!?\" +\n\t\"′′′′0456789+=()rsħnoqsmtmωåאבגדπ1⁄71⁄91⁄101⁄32⁄31⁄52⁄53⁄54⁄51⁄65⁄61⁄83\" +\n\t\"⁄85⁄87⁄81⁄iiivviviiiixxi0⁄3∫∫∫∫∫∮∮∮∮∮1011121314151617181920(10)(11)(12\" +\n\t\")(13)(14)(15)(16)(17)(18)(19)(20)∫∫∫∫==⫝̸ɫɽȿɀ. ゙ ゚よりコト(ᄀ)(ᄂ)(ᄃ)(ᄅ)(ᄆ)(ᄇ)\" +\n\t\"(ᄉ)(ᄋ)(ᄌ)(ᄎ)(ᄏ)(ᄐ)(ᄑ)(ᄒ)(가)(나)(다)(라)(마)(바)(사)(아)(자)(차)(카)(타)(파)(하)(주)(오전\" +\n\t\")(오후)(一)(二)(三)(四)(五)(六)(七)(八)(九)(十)(月)(火)(水)(木)(金)(土)(日)(株)(有)(社)(名)(特)(\" +\n\t\"財)(祝)(労)(代)(呼)(学)(監)(企)(資)(協)(祭)(休)(自)(至)21222324252627282930313233343\" +\n\t\"5참고주의3637383940414243444546474849501月2月3月4月5月6月7月8月9月10月11月12月hgev令和アパート\" +\n\t\"アルファアンペアアールイニングインチウォンエスクードエーカーオンスオームカイリカラットカロリーガロンガンマギガギニーキュリーギルダーキロキロ\" +\n\t\"グラムキロメートルキロワットグラムグラムトンクルゼイロクローネケースコルナコーポサイクルサンチームシリングセンチセントダースデシドルトンナノ\" +\n\t\"ノットハイツパーセントパーツバーレルピアストルピクルピコビルファラッドフィートブッシェルフランヘクタールペソペニヒヘルツペンスページベータポ\" +\n\t\"イントボルトホンポンドホールホーンマイクロマイルマッハマルクマンションミクロンミリミリバールメガメガトンメートルヤードヤールユアンリットルリ\" +\n\t\"ラルピールーブルレムレントゲンワット0点1点2点3点4点5点6点7点8点9点10点11点12点13点14点15点16点17点18点19点20\" +\n\t\"点21点22点23点24点daauovpcdmiu平成昭和大正明治株式会社panamakakbmbgbkcalpfnfmgkghzmldlk\" +\n\t\"lfmnmmmcmkmm2m3m∕sm∕s2rad∕srad∕s2psnsmspvnvmvkvpwnwmwkwbqcccdc∕kgdbgyhah\" +\n\t\"pinkkktlmlnlxphprsrsvwbv∕ma∕m1日2日3日4日5日6日7日8日9日10日11日12日13日14日15日16日17日1\" +\n\t\"8日19日20日21日22日23日24日25日26日27日28日29日30日31日ьɦɬʞʇœʍ𤋮𢡊𢡄𣏕𥉉𥳐𧻓fffiflstմնմեմիվնմ\" +\n\t\"խיִײַעהכלםרתשׁשׂשּׁשּׂאַאָאּבּגּדּהּוּזּטּיּךּכּלּמּנּסּףּפּצּקּרּשּתּו\" +\n\t\"ֹבֿכֿפֿאלٱٻپڀٺٿٹڤڦڄڃچڇڍڌڎڈژڑکگڳڱںڻۀہھےۓڭۇۆۈۋۅۉېىئائەئوئۇئۆئۈئېئىیئجئحئم\" +\n\t\"ئيبجبحبخبمبىبيتجتحتختمتىتيثجثمثىثيجحجمحجحمخجخحخمسجسحسخسمصحصمضجضحضخضمطحط\" +\n\t\"مظمعجعمغجغمفجفحفخفمفىفيقحقمقىقيكاكجكحكخكلكمكىكيلجلحلخلملىليمجمحمخمممىمي\" +\n\t\"نجنحنخنمنىنيهجهمهىهييجيحيخيميىييذٰرٰىٰ ٌّ ٍّ َّ ُّ ِّ ّٰئرئزئنبربزبنترت\" +\n\t\"زتنثرثزثنمانرنزننيريزينئخئهبهتهصخلهنههٰيهثهسهشمشهـَّـُّـِّطىطيعىعيغىغيس\" +\n\t\"ىسيشىشيحىحيجىجيخىخيصىصيضىضيشجشحشخشرسرصرضراًتجمتحجتحمتخمتمجتمحتمخجمححميح\" +\n\t\"مىسحجسجحسجىسمحسمجسممصححصممشحمشجيشمخشممضحىضخمطمحطممطميعجمعممعمىغممغميغمى\" +\n\t\"فخمقمحقمملحملحيلحىلججلخملمحمحجمحممحيمجحمجممخجمخممجخهمجهممنحمنحىنجمنجىنم\" +\n\t\"ينمىيممبخيتجيتجىتخيتخىتميتمىجميجحىجمىسخىصحيشحيضحيلجيلمييحييجييميمميقمين\" +\n\t\"حيعميكمينجحمخيلجمكممجحيحجيمجيفميبحيسخينجيصلےقلےاللهاكبرمحمدصلعمرسولعليه\" +\n\t\"وسلمصلىصلى الله عليه وسلمجل جلالهریال,:!?_{}[]#&*-<>\\\\$%@ـًـَـُـِـّـْءآ\" +\n\t\"أؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهويلآلألإلا\\x22'/^|~¢£¬¦¥𝅗𝅥𝅘𝅥𝅘𝅥𝅮𝅘𝅥𝅯𝅘𝅥𝅰𝅘𝅥𝅱\" +\n\t\"𝅘𝅥𝅲𝆹𝅥𝆺𝅥𝆹𝅥𝅮𝆺𝅥𝅮𝆹𝅥𝅯𝆺𝅥𝅯ıȷαεζηκλμνξοστυψ∇∂ϝٮڡٯ0,1,2,3,4,5,6,7,8,9,(a)(b)(c\" +\n\t\")(d)(e)(f)(g)(h)(i)(j)(k)(l)(m)(n)(o)(p)(q)(r)(s)(t)(u)(v)(w)(x)(y)(z)〔s\" +\n\t\"〕wzhvsdppvwcmcmdmrdjほかココサ手字双デ二多解天交映無料前後再新初終生販声吹演投捕一三遊左中右指走打禁空合満有月申割営配〔\" +\n\t\"本〕〔三〕〔二〕〔安〕〔点〕〔打〕〔盗〕〔勝〕〔敗〕得可丽丸乁你侮侻倂偺備僧像㒞免兔兤具㒹內冗冤仌冬况凵刃㓟刻剆剷㔕勇勉勤勺包匆北卉卑博即卽\" +\n\t\"卿灰及叟叫叱吆咞吸呈周咢哶唐啓啣善喙喫喳嗂圖嘆圗噑噴切壮城埴堍型堲報墬売壷夆夢奢姬娛娧姘婦㛮嬈嬾寃寘寧寳寿将尢㞁屠屮峀岍嵃嵮嵫嵼巡巢㠯巽帨帽\" +\n\t\"幩㡢㡼庰庳庶廊廾舁弢㣇形彫㣣徚忍志忹悁㤺㤜悔惇慈慌慎慺憎憲憤憯懞懲懶成戛扝抱拔捐挽拼捨掃揤搢揅掩㨮摩摾撝摷㩬敏敬旣書晉㬙暑㬈㫤冒冕最暜肭䏙朗\" +\n\t\"望朡杞杓㭉柺枅桒梅梎栟椔㮝楂榣槪檨櫛㰘次歔㱎歲殟殺殻汎沿泍汧洖派海流浩浸涅洴港湮㴳滋滇淹潮濆瀹瀞瀛㶖灊災灷炭煅熜爨爵牐犀犕獺王㺬玥㺸瑇瑜瑱璅\" +\n\t\"瓊㼛甤甾異瘐㿼䀈直眞真睊䀹瞋䁆䂖硎碌磌䃣祖福秫䄯穀穊穏䈂篆築䈧糒䊠糨糣紀絣䌁緇縂繅䌴䍙罺羕翺者聠聰䏕育脃䐋脾媵舄辞䑫芑芋芝劳花芳芽苦若茝荣莭\" +\n\t\"茣莽菧著荓菊菌菜䔫蓱蓳蔖蕤䕝䕡䕫虐虜虧虩蚩蚈蜎蛢蝹蜨蝫螆蟡蠁䗹衠衣裗裞䘵裺㒻䚾䛇誠諭變豕貫賁贛起跋趼跰軔輸邔郱鄑鄛鈸鋗鋘鉼鏹鐕開䦕閷䧦雃嶲霣\" +\n\t\"䩮䩶韠䪲頋頩飢䬳餩馧駂駾䯎鬒鱀鳽䳎䳭鵧䳸麻䵖黹黾鼅鼏鼖鼻\"\n\nvar mappingIndex = []uint16{ // 1650 elements\n\t// Entry 0 - 3F\n\t0x0000, 0x0000, 0x0001, 0x0004, 0x0005, 0x0008, 0x0009, 0x000a,\n\t0x000d, 0x0010, 0x0011, 0x0012, 0x0017, 0x001c, 0x0021, 0x0024,\n\t0x0027, 0x002a, 0x002b, 0x002e, 0x0031, 0x0034, 0x0035, 0x0036,\n\t0x0037, 0x0038, 0x0039, 0x003c, 0x003f, 0x0042, 0x0045, 0x0048,\n\t0x004b, 0x004c, 0x004d, 0x0051, 0x0054, 0x0055, 0x005a, 0x005e,\n\t0x0062, 0x0066, 0x006a, 0x006e, 0x0074, 0x007a, 0x0080, 0x0086,\n\t0x008c, 0x0092, 0x0098, 0x009e, 0x00a4, 0x00aa, 0x00b0, 0x00b6,\n\t0x00bc, 0x00c2, 0x00c8, 0x00ce, 0x00d4, 0x00da, 0x00e0, 0x00e6,\n\t// Entry 40 - 7F\n\t0x00ec, 0x00f2, 0x00f8, 0x00fe, 0x0104, 0x010a, 0x0110, 0x0116,\n\t0x011c, 0x0122, 0x0128, 0x012e, 0x0137, 0x013d, 0x0146, 0x014c,\n\t0x0152, 0x0158, 0x015e, 0x0164, 0x016a, 0x0170, 0x0172, 0x0174,\n\t0x0176, 0x0178, 0x017a, 0x017c, 0x017e, 0x0180, 0x0181, 0x0182,\n\t0x0183, 0x0185, 0x0186, 0x0187, 0x0188, 0x0189, 0x018a, 0x018c,\n\t0x018d, 0x018e, 0x018f, 0x0191, 0x0193, 0x0195, 0x0197, 0x0199,\n\t0x019b, 0x019d, 0x019f, 0x01a0, 0x01a2, 0x01a4, 0x01a6, 0x01a8,\n\t0x01aa, 0x01ac, 0x01ae, 0x01b0, 0x01b1, 0x01b3, 0x01b5, 0x01b6,\n\t// Entry 80 - BF\n\t0x01b8, 0x01ba, 0x01bc, 0x01be, 0x01c0, 0x01c2, 0x01c4, 0x01c6,\n\t0x01c8, 0x01ca, 0x01cc, 0x01ce, 0x01d0, 0x01d2, 0x01d4, 0x01d6,\n\t0x01d8, 0x01da, 0x01dc, 0x01de, 0x01e0, 0x01e2, 0x01e4, 0x01e5,\n\t0x01e7, 0x01e9, 0x01eb, 0x01ed, 0x01ef, 0x01f1, 0x01f3, 0x01f5,\n\t0x01f7, 0x01f9, 0x01fb, 0x01fd, 0x0202, 0x0207, 0x020c, 0x0211,\n\t0x0216, 0x021b, 0x0220, 0x0225, 0x022a, 0x022f, 0x0234, 0x0239,\n\t0x023e, 0x0243, 0x0248, 0x024d, 0x0252, 0x0257, 0x025c, 0x0261,\n\t0x0266, 0x026b, 0x0270, 0x0275, 0x027a, 0x027e, 0x0282, 0x0287,\n\t// Entry C0 - FF\n\t0x0289, 0x028e, 0x0293, 0x0297, 0x029b, 0x02a0, 0x02a5, 0x02aa,\n\t0x02af, 0x02b1, 0x02b6, 0x02bb, 0x02c0, 0x02c2, 0x02c7, 0x02c8,\n\t0x02cd, 0x02d1, 0x02d5, 0x02da, 0x02e0, 0x02e9, 0x02ef, 0x02f8,\n\t0x02fa, 0x02fc, 0x02fe, 0x0300, 0x030c, 0x030d, 0x030e, 0x030f,\n\t0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317,\n\t0x0319, 0x031b, 0x031d, 0x031e, 0x0320, 0x0322, 0x0324, 0x0326,\n\t0x0328, 0x032a, 0x032c, 0x032e, 0x0330, 0x0335, 0x033a, 0x0340,\n\t0x0345, 0x034a, 0x034f, 0x0354, 0x0359, 0x035e, 0x0363, 0x0368,\n\t// Entry 100 - 13F\n\t0x036d, 0x0372, 0x0377, 0x037c, 0x0380, 0x0382, 0x0384, 0x0386,\n\t0x038a, 0x038c, 0x038e, 0x0393, 0x0399, 0x03a2, 0x03a8, 0x03b1,\n\t0x03b3, 0x03b5, 0x03b7, 0x03b9, 0x03bb, 0x03bd, 0x03bf, 0x03c1,\n\t0x03c3, 0x03c5, 0x03c7, 0x03cb, 0x03cf, 0x03d3, 0x03d7, 0x03db,\n\t0x03df, 0x03e3, 0x03e7, 0x03eb, 0x03ef, 0x03f3, 0x03ff, 0x0401,\n\t0x0406, 0x0408, 0x040a, 0x040c, 0x040e, 0x040f, 0x0413, 0x0417,\n\t0x041d, 0x0423, 0x0428, 0x042d, 0x0432, 0x0437, 0x043c, 0x0441,\n\t0x0446, 0x044b, 0x0450, 0x0455, 0x045a, 0x045f, 0x0464, 0x0469,\n\t// Entry 140 - 17F\n\t0x046e, 0x0473, 0x0478, 0x047d, 0x0482, 0x0487, 0x048c, 0x0491,\n\t0x0496, 0x049b, 0x04a0, 0x04a5, 0x04aa, 0x04af, 0x04b4, 0x04bc,\n\t0x04c4, 0x04c9, 0x04ce, 0x04d3, 0x04d8, 0x04dd, 0x04e2, 0x04e7,\n\t0x04ec, 0x04f1, 0x04f6, 0x04fb, 0x0500, 0x0505, 0x050a, 0x050f,\n\t0x0514, 0x0519, 0x051e, 0x0523, 0x0528, 0x052d, 0x0532, 0x0537,\n\t0x053c, 0x0541, 0x0546, 0x054b, 0x0550, 0x0555, 0x055a, 0x055f,\n\t0x0564, 0x0569, 0x056e, 0x0573, 0x0578, 0x057a, 0x057c, 0x057e,\n\t0x0580, 0x0582, 0x0584, 0x0586, 0x0588, 0x058a, 0x058c, 0x058e,\n\t// Entry 180 - 1BF\n\t0x0590, 0x0592, 0x0594, 0x0596, 0x059c, 0x05a2, 0x05a4, 0x05a6,\n\t0x05a8, 0x05aa, 0x05ac, 0x05ae, 0x05b0, 0x05b2, 0x05b4, 0x05b6,\n\t0x05b8, 0x05ba, 0x05bc, 0x05be, 0x05c0, 0x05c4, 0x05c8, 0x05cc,\n\t0x05d0, 0x05d4, 0x05d8, 0x05dc, 0x05e0, 0x05e4, 0x05e9, 0x05ee,\n\t0x05f3, 0x05f5, 0x05f7, 0x05fd, 0x0609, 0x0615, 0x0621, 0x062a,\n\t0x0636, 0x063f, 0x0648, 0x0657, 0x0663, 0x066c, 0x0675, 0x067e,\n\t0x068a, 0x0696, 0x069f, 0x06a8, 0x06ae, 0x06b7, 0x06c3, 0x06cf,\n\t0x06d5, 0x06e4, 0x06f6, 0x0705, 0x070e, 0x071d, 0x072c, 0x0738,\n\t// Entry 1C0 - 1FF\n\t0x0741, 0x074a, 0x0753, 0x075f, 0x076e, 0x077a, 0x0783, 0x078c,\n\t0x0795, 0x079b, 0x07a1, 0x07a7, 0x07ad, 0x07b6, 0x07bf, 0x07ce,\n\t0x07d7, 0x07e3, 0x07f2, 0x07fb, 0x0801, 0x0807, 0x0816, 0x0822,\n\t0x0831, 0x083a, 0x0849, 0x084f, 0x0858, 0x0861, 0x086a, 0x0873,\n\t0x087c, 0x0888, 0x0891, 0x0897, 0x08a0, 0x08a9, 0x08b2, 0x08be,\n\t0x08c7, 0x08d0, 0x08d9, 0x08e8, 0x08f4, 0x08fa, 0x0909, 0x090f,\n\t0x091b, 0x0927, 0x0930, 0x0939, 0x0942, 0x094e, 0x0954, 0x095d,\n\t0x0969, 0x096f, 0x097e, 0x0987, 0x098b, 0x098f, 0x0993, 0x0997,\n\t// Entry 200 - 23F\n\t0x099b, 0x099f, 0x09a3, 0x09a7, 0x09ab, 0x09af, 0x09b4, 0x09b9,\n\t0x09be, 0x09c3, 0x09c8, 0x09cd, 0x09d2, 0x09d7, 0x09dc, 0x09e1,\n\t0x09e6, 0x09eb, 0x09f0, 0x09f5, 0x09fa, 0x09fc, 0x09fe, 0x0a00,\n\t0x0a02, 0x0a04, 0x0a06, 0x0a0c, 0x0a12, 0x0a18, 0x0a1e, 0x0a2a,\n\t0x0a2c, 0x0a2e, 0x0a30, 0x0a32, 0x0a34, 0x0a36, 0x0a38, 0x0a3c,\n\t0x0a3e, 0x0a40, 0x0a42, 0x0a44, 0x0a46, 0x0a48, 0x0a4a, 0x0a4c,\n\t0x0a4e, 0x0a50, 0x0a52, 0x0a54, 0x0a56, 0x0a58, 0x0a5a, 0x0a5f,\n\t0x0a65, 0x0a6c, 0x0a74, 0x0a76, 0x0a78, 0x0a7a, 0x0a7c, 0x0a7e,\n\t// Entry 240 - 27F\n\t0x0a80, 0x0a82, 0x0a84, 0x0a86, 0x0a88, 0x0a8a, 0x0a8c, 0x0a8e,\n\t0x0a90, 0x0a96, 0x0a98, 0x0a9a, 0x0a9c, 0x0a9e, 0x0aa0, 0x0aa2,\n\t0x0aa4, 0x0aa6, 0x0aa8, 0x0aaa, 0x0aac, 0x0aae, 0x0ab0, 0x0ab2,\n\t0x0ab4, 0x0ab9, 0x0abe, 0x0ac2, 0x0ac6, 0x0aca, 0x0ace, 0x0ad2,\n\t0x0ad6, 0x0ada, 0x0ade, 0x0ae2, 0x0ae7, 0x0aec, 0x0af1, 0x0af6,\n\t0x0afb, 0x0b00, 0x0b05, 0x0b0a, 0x0b0f, 0x0b14, 0x0b19, 0x0b1e,\n\t0x0b23, 0x0b28, 0x0b2d, 0x0b32, 0x0b37, 0x0b3c, 0x0b41, 0x0b46,\n\t0x0b4b, 0x0b50, 0x0b52, 0x0b54, 0x0b56, 0x0b58, 0x0b5a, 0x0b5c,\n\t// Entry 280 - 2BF\n\t0x0b5e, 0x0b62, 0x0b66, 0x0b6a, 0x0b6e, 0x0b72, 0x0b76, 0x0b7a,\n\t0x0b7c, 0x0b7e, 0x0b80, 0x0b82, 0x0b86, 0x0b8a, 0x0b8e, 0x0b92,\n\t0x0b96, 0x0b9a, 0x0b9e, 0x0ba0, 0x0ba2, 0x0ba4, 0x0ba6, 0x0ba8,\n\t0x0baa, 0x0bac, 0x0bb0, 0x0bb4, 0x0bba, 0x0bc0, 0x0bc4, 0x0bc8,\n\t0x0bcc, 0x0bd0, 0x0bd4, 0x0bd8, 0x0bdc, 0x0be0, 0x0be4, 0x0be8,\n\t0x0bec, 0x0bf0, 0x0bf4, 0x0bf8, 0x0bfc, 0x0c00, 0x0c04, 0x0c08,\n\t0x0c0c, 0x0c10, 0x0c14, 0x0c18, 0x0c1c, 0x0c20, 0x0c24, 0x0c28,\n\t0x0c2c, 0x0c30, 0x0c34, 0x0c36, 0x0c38, 0x0c3a, 0x0c3c, 0x0c3e,\n\t// Entry 2C0 - 2FF\n\t0x0c40, 0x0c42, 0x0c44, 0x0c46, 0x0c48, 0x0c4a, 0x0c4c, 0x0c4e,\n\t0x0c50, 0x0c52, 0x0c54, 0x0c56, 0x0c58, 0x0c5a, 0x0c5c, 0x0c5e,\n\t0x0c60, 0x0c62, 0x0c64, 0x0c66, 0x0c68, 0x0c6a, 0x0c6c, 0x0c6e,\n\t0x0c70, 0x0c72, 0x0c74, 0x0c76, 0x0c78, 0x0c7a, 0x0c7c, 0x0c7e,\n\t0x0c80, 0x0c82, 0x0c86, 0x0c8a, 0x0c8e, 0x0c92, 0x0c96, 0x0c9a,\n\t0x0c9e, 0x0ca2, 0x0ca4, 0x0ca8, 0x0cac, 0x0cb0, 0x0cb4, 0x0cb8,\n\t0x0cbc, 0x0cc0, 0x0cc4, 0x0cc8, 0x0ccc, 0x0cd0, 0x0cd4, 0x0cd8,\n\t0x0cdc, 0x0ce0, 0x0ce4, 0x0ce8, 0x0cec, 0x0cf0, 0x0cf4, 0x0cf8,\n\t// Entry 300 - 33F\n\t0x0cfc, 0x0d00, 0x0d04, 0x0d08, 0x0d0c, 0x0d10, 0x0d14, 0x0d18,\n\t0x0d1c, 0x0d20, 0x0d24, 0x0d28, 0x0d2c, 0x0d30, 0x0d34, 0x0d38,\n\t0x0d3c, 0x0d40, 0x0d44, 0x0d48, 0x0d4c, 0x0d50, 0x0d54, 0x0d58,\n\t0x0d5c, 0x0d60, 0x0d64, 0x0d68, 0x0d6c, 0x0d70, 0x0d74, 0x0d78,\n\t0x0d7c, 0x0d80, 0x0d84, 0x0d88, 0x0d8c, 0x0d90, 0x0d94, 0x0d98,\n\t0x0d9c, 0x0da0, 0x0da4, 0x0da8, 0x0dac, 0x0db0, 0x0db4, 0x0db8,\n\t0x0dbc, 0x0dc0, 0x0dc4, 0x0dc8, 0x0dcc, 0x0dd0, 0x0dd4, 0x0dd8,\n\t0x0ddc, 0x0de0, 0x0de4, 0x0de8, 0x0dec, 0x0df0, 0x0df4, 0x0df8,\n\t// Entry 340 - 37F\n\t0x0dfc, 0x0e00, 0x0e04, 0x0e08, 0x0e0c, 0x0e10, 0x0e14, 0x0e18,\n\t0x0e1d, 0x0e22, 0x0e27, 0x0e2c, 0x0e31, 0x0e36, 0x0e3a, 0x0e3e,\n\t0x0e42, 0x0e46, 0x0e4a, 0x0e4e, 0x0e52, 0x0e56, 0x0e5a, 0x0e5e,\n\t0x0e62, 0x0e66, 0x0e6a, 0x0e6e, 0x0e72, 0x0e76, 0x0e7a, 0x0e7e,\n\t0x0e82, 0x0e86, 0x0e8a, 0x0e8e, 0x0e92, 0x0e96, 0x0e9a, 0x0e9e,\n\t0x0ea2, 0x0ea6, 0x0eaa, 0x0eae, 0x0eb2, 0x0eb6, 0x0ebc, 0x0ec2,\n\t0x0ec8, 0x0ecc, 0x0ed0, 0x0ed4, 0x0ed8, 0x0edc, 0x0ee0, 0x0ee4,\n\t0x0ee8, 0x0eec, 0x0ef0, 0x0ef4, 0x0ef8, 0x0efc, 0x0f00, 0x0f04,\n\t// Entry 380 - 3BF\n\t0x0f08, 0x0f0c, 0x0f10, 0x0f14, 0x0f18, 0x0f1c, 0x0f20, 0x0f24,\n\t0x0f28, 0x0f2c, 0x0f30, 0x0f34, 0x0f38, 0x0f3e, 0x0f44, 0x0f4a,\n\t0x0f50, 0x0f56, 0x0f5c, 0x0f62, 0x0f68, 0x0f6e, 0x0f74, 0x0f7a,\n\t0x0f80, 0x0f86, 0x0f8c, 0x0f92, 0x0f98, 0x0f9e, 0x0fa4, 0x0faa,\n\t0x0fb0, 0x0fb6, 0x0fbc, 0x0fc2, 0x0fc8, 0x0fce, 0x0fd4, 0x0fda,\n\t0x0fe0, 0x0fe6, 0x0fec, 0x0ff2, 0x0ff8, 0x0ffe, 0x1004, 0x100a,\n\t0x1010, 0x1016, 0x101c, 0x1022, 0x1028, 0x102e, 0x1034, 0x103a,\n\t0x1040, 0x1046, 0x104c, 0x1052, 0x1058, 0x105e, 0x1064, 0x106a,\n\t// Entry 3C0 - 3FF\n\t0x1070, 0x1076, 0x107c, 0x1082, 0x1088, 0x108e, 0x1094, 0x109a,\n\t0x10a0, 0x10a6, 0x10ac, 0x10b2, 0x10b8, 0x10be, 0x10c4, 0x10ca,\n\t0x10d0, 0x10d6, 0x10dc, 0x10e2, 0x10e8, 0x10ee, 0x10f4, 0x10fa,\n\t0x1100, 0x1106, 0x110c, 0x1112, 0x1118, 0x111e, 0x1124, 0x112a,\n\t0x1130, 0x1136, 0x113c, 0x1142, 0x1148, 0x114e, 0x1154, 0x115a,\n\t0x1160, 0x1166, 0x116c, 0x1172, 0x1178, 0x1180, 0x1188, 0x1190,\n\t0x1198, 0x11a0, 0x11a8, 0x11b0, 0x11b6, 0x11d7, 0x11e6, 0x11ee,\n\t0x11ef, 0x11f0, 0x11f1, 0x11f2, 0x11f3, 0x11f4, 0x11f5, 0x11f6,\n\t// Entry 400 - 43F\n\t0x11f7, 0x11f8, 0x11f9, 0x11fa, 0x11fb, 0x11fc, 0x11fd, 0x11fe,\n\t0x11ff, 0x1200, 0x1201, 0x1205, 0x1209, 0x120d, 0x1211, 0x1215,\n\t0x1219, 0x121b, 0x121d, 0x121f, 0x1221, 0x1223, 0x1225, 0x1227,\n\t0x1229, 0x122b, 0x122d, 0x122f, 0x1231, 0x1233, 0x1235, 0x1237,\n\t0x1239, 0x123b, 0x123d, 0x123f, 0x1241, 0x1243, 0x1245, 0x1247,\n\t0x1249, 0x124b, 0x124d, 0x124f, 0x1251, 0x1253, 0x1255, 0x1257,\n\t0x1259, 0x125b, 0x125d, 0x125f, 0x1263, 0x1267, 0x126b, 0x126f,\n\t0x1270, 0x1271, 0x1272, 0x1273, 0x1274, 0x1275, 0x1277, 0x1279,\n\t// Entry 440 - 47F\n\t0x127b, 0x127d, 0x127f, 0x1287, 0x128f, 0x129b, 0x12a7, 0x12b3,\n\t0x12bf, 0x12cb, 0x12d3, 0x12db, 0x12e7, 0x12f3, 0x12ff, 0x130b,\n\t0x130d, 0x130f, 0x1311, 0x1313, 0x1315, 0x1317, 0x1319, 0x131b,\n\t0x131d, 0x131f, 0x1321, 0x1323, 0x1325, 0x1327, 0x1329, 0x132b,\n\t0x132e, 0x1331, 0x1333, 0x1335, 0x1337, 0x1339, 0x133b, 0x133d,\n\t0x133f, 0x1341, 0x1343, 0x1345, 0x1347, 0x1349, 0x134b, 0x134d,\n\t0x1350, 0x1353, 0x1356, 0x1359, 0x135c, 0x135f, 0x1362, 0x1365,\n\t0x1368, 0x136b, 0x136e, 0x1371, 0x1374, 0x1377, 0x137a, 0x137d,\n\t// Entry 480 - 4BF\n\t0x1380, 0x1383, 0x1386, 0x1389, 0x138c, 0x138f, 0x1392, 0x1395,\n\t0x1398, 0x139b, 0x13a2, 0x13a4, 0x13a6, 0x13a8, 0x13ab, 0x13ad,\n\t0x13af, 0x13b1, 0x13b3, 0x13b5, 0x13bb, 0x13c1, 0x13c4, 0x13c7,\n\t0x13ca, 0x13cd, 0x13d0, 0x13d3, 0x13d6, 0x13d9, 0x13dc, 0x13df,\n\t0x13e2, 0x13e5, 0x13e8, 0x13eb, 0x13ee, 0x13f1, 0x13f4, 0x13f7,\n\t0x13fa, 0x13fd, 0x1400, 0x1403, 0x1406, 0x1409, 0x140c, 0x140f,\n\t0x1412, 0x1415, 0x1418, 0x141b, 0x141e, 0x1421, 0x1424, 0x1427,\n\t0x142a, 0x142d, 0x1430, 0x1433, 0x1436, 0x1439, 0x143c, 0x143f,\n\t// Entry 4C0 - 4FF\n\t0x1442, 0x1445, 0x1448, 0x1451, 0x145a, 0x1463, 0x146c, 0x1475,\n\t0x147e, 0x1487, 0x1490, 0x1499, 0x149c, 0x149f, 0x14a2, 0x14a5,\n\t0x14a8, 0x14ab, 0x14ae, 0x14b1, 0x14b4, 0x14b7, 0x14ba, 0x14bd,\n\t0x14c0, 0x14c3, 0x14c6, 0x14c9, 0x14cc, 0x14cf, 0x14d2, 0x14d5,\n\t0x14d8, 0x14db, 0x14de, 0x14e1, 0x14e4, 0x14e7, 0x14ea, 0x14ed,\n\t0x14f0, 0x14f3, 0x14f6, 0x14f9, 0x14fc, 0x14ff, 0x1502, 0x1505,\n\t0x1508, 0x150b, 0x150e, 0x1511, 0x1514, 0x1517, 0x151a, 0x151d,\n\t0x1520, 0x1523, 0x1526, 0x1529, 0x152c, 0x152f, 0x1532, 0x1535,\n\t// Entry 500 - 53F\n\t0x1538, 0x153b, 0x153e, 0x1541, 0x1544, 0x1547, 0x154a, 0x154d,\n\t0x1550, 0x1553, 0x1556, 0x1559, 0x155c, 0x155f, 0x1562, 0x1565,\n\t0x1568, 0x156b, 0x156e, 0x1571, 0x1574, 0x1577, 0x157a, 0x157d,\n\t0x1580, 0x1583, 0x1586, 0x1589, 0x158c, 0x158f, 0x1592, 0x1595,\n\t0x1598, 0x159b, 0x159e, 0x15a1, 0x15a4, 0x15a7, 0x15aa, 0x15ad,\n\t0x15b0, 0x15b3, 0x15b6, 0x15b9, 0x15bc, 0x15bf, 0x15c2, 0x15c5,\n\t0x15c8, 0x15cb, 0x15ce, 0x15d1, 0x15d4, 0x15d7, 0x15da, 0x15dd,\n\t0x15e0, 0x15e3, 0x15e6, 0x15e9, 0x15ec, 0x15ef, 0x15f2, 0x15f5,\n\t// Entry 540 - 57F\n\t0x15f8, 0x15fb, 0x15fe, 0x1601, 0x1604, 0x1607, 0x160a, 0x160d,\n\t0x1610, 0x1613, 0x1616, 0x1619, 0x161c, 0x161f, 0x1622, 0x1625,\n\t0x1628, 0x162b, 0x162e, 0x1631, 0x1634, 0x1637, 0x163a, 0x163d,\n\t0x1640, 0x1643, 0x1646, 0x1649, 0x164c, 0x164f, 0x1652, 0x1655,\n\t0x1658, 0x165b, 0x165e, 0x1661, 0x1664, 0x1667, 0x166a, 0x166d,\n\t0x1670, 0x1673, 0x1676, 0x1679, 0x167c, 0x167f, 0x1682, 0x1685,\n\t0x1688, 0x168b, 0x168e, 0x1691, 0x1694, 0x1697, 0x169a, 0x169d,\n\t0x16a0, 0x16a3, 0x16a6, 0x16a9, 0x16ac, 0x16af, 0x16b2, 0x16b5,\n\t// Entry 580 - 5BF\n\t0x16b8, 0x16bb, 0x16be, 0x16c1, 0x16c4, 0x16c7, 0x16ca, 0x16cd,\n\t0x16d0, 0x16d3, 0x16d6, 0x16d9, 0x16dc, 0x16df, 0x16e2, 0x16e5,\n\t0x16e8, 0x16eb, 0x16ee, 0x16f1, 0x16f4, 0x16f7, 0x16fa, 0x16fd,\n\t0x1700, 0x1703, 0x1706, 0x1709, 0x170c, 0x170f, 0x1712, 0x1715,\n\t0x1718, 0x171b, 0x171e, 0x1721, 0x1724, 0x1727, 0x172a, 0x172d,\n\t0x1730, 0x1733, 0x1736, 0x1739, 0x173c, 0x173f, 0x1742, 0x1745,\n\t0x1748, 0x174b, 0x174e, 0x1751, 0x1754, 0x1757, 0x175a, 0x175d,\n\t0x1760, 0x1763, 0x1766, 0x1769, 0x176c, 0x176f, 0x1772, 0x1775,\n\t// Entry 5C0 - 5FF\n\t0x1778, 0x177b, 0x177e, 0x1781, 0x1784, 0x1787, 0x178a, 0x178d,\n\t0x1790, 0x1793, 0x1796, 0x1799, 0x179c, 0x179f, 0x17a2, 0x17a5,\n\t0x17a8, 0x17ab, 0x17ae, 0x17b1, 0x17b4, 0x17b7, 0x17ba, 0x17bd,\n\t0x17c0, 0x17c3, 0x17c6, 0x17c9, 0x17cc, 0x17cf, 0x17d2, 0x17d5,\n\t0x17d8, 0x17db, 0x17de, 0x17e1, 0x17e4, 0x17e7, 0x17ea, 0x17ed,\n\t0x17f0, 0x17f3, 0x17f6, 0x17f9, 0x17fc, 0x17ff, 0x1802, 0x1805,\n\t0x1808, 0x180b, 0x180e, 0x1811, 0x1814, 0x1817, 0x181a, 0x181d,\n\t0x1820, 0x1823, 0x1826, 0x1829, 0x182c, 0x182f, 0x1832, 0x1835,\n\t// Entry 600 - 63F\n\t0x1838, 0x183b, 0x183e, 0x1841, 0x1844, 0x1847, 0x184a, 0x184d,\n\t0x1850, 0x1853, 0x1856, 0x1859, 0x185c, 0x185f, 0x1862, 0x1865,\n\t0x1868, 0x186b, 0x186e, 0x1871, 0x1874, 0x1877, 0x187a, 0x187d,\n\t0x1880, 0x1883, 0x1886, 0x1889, 0x188c, 0x188f, 0x1892, 0x1895,\n\t0x1898, 0x189b, 0x189e, 0x18a1, 0x18a4, 0x18a7, 0x18aa, 0x18ad,\n\t0x18b0, 0x18b3, 0x18b6, 0x18b9, 0x18bc, 0x18bf, 0x18c2, 0x18c5,\n\t0x18c8, 0x18cb, 0x18ce, 0x18d1, 0x18d4, 0x18d7, 0x18da, 0x18dd,\n\t0x18e0, 0x18e3, 0x18e6, 0x18e9, 0x18ec, 0x18ef, 0x18f2, 0x18f5,\n\t// Entry 640 - 67F\n\t0x18f8, 0x18fb, 0x18fe, 0x1901, 0x1904, 0x1907, 0x190a, 0x190d,\n\t0x1910, 0x1913, 0x1916, 0x1919, 0x191c, 0x191f, 0x1922, 0x1925,\n\t0x1928, 0x192b, 0x192e, 0x1931, 0x1934, 0x1937, 0x193a, 0x193d,\n\t0x1940, 0x1943, 0x1946, 0x1949, 0x194c, 0x194f, 0x1952, 0x1955,\n\t0x1958, 0x195b, 0x195e, 0x1961, 0x1964, 0x1967, 0x196a, 0x196d,\n\t0x1970, 0x1973, 0x1976, 0x1979, 0x197c, 0x197f, 0x1982, 0x1985,\n\t0x1988, 0x198b,\n} // Size: 3324 bytes\n\nvar xorData string = \"\" + // Size: 4862 bytes\n\t\"\\x02\\x0c\\x09\\x02\\xb0\\xec\\x02\\xad\\xd8\\x02\\xad\\xd9\\x02\\x06\\x07\\x02\\x0f\\x12\" +\n\t\"\\x02\\x0f\\x1f\\x02\\x0f\\x1d\\x02\\x01\\x13\\x02\\x0f\\x16\\x02\\x0f\\x0b\\x02\\x0f3\" +\n\t\"\\x02\\x0f7\\x02\\x0f?\\x02\\x0f/\\x02\\x0f*\\x02\\x0c&\\x02\\x0c*\\x02\\x0c;\\x02\\x0c9\" +\n\t\"\\x02\\x0c%\\x02\\xab\\xed\\x02\\xab\\xe2\\x02\\xab\\xe3\\x02\\xa9\\xe0\\x02\\xa9\\xe1\" +\n\t\"\\x02\\xa9\\xe6\\x02\\xa3\\xcb\\x02\\xa3\\xc8\\x02\\xa3\\xc9\\x02\\x01#\\x02\\x01\\x08\" +\n\t\"\\x02\\x0e>\\x02\\x0e'\\x02\\x0f\\x03\\x02\\x03\\x0d\\x02\\x03\\x09\\x02\\x03\\x17\\x02\" +\n\t\"\\x03\\x0e\\x02\\x02\\x03\\x02\\x011\\x02\\x01\\x00\\x02\\x01\\x10\\x02\\x03<\\x02\\x07\" +\n\t\"\\x0d\\x02\\x02\\x0c\\x02\\x0c0\\x02\\x01\\x03\\x02\\x01\\x01\\x02\\x01 \\x02\\x01\\x22\" +\n\t\"\\x02\\x01)\\x02\\x01\\x0a\\x02\\x01\\x0c\\x02\\x02\\x06\\x02\\x02\\x02\\x02\\x03\\x10\" +\n\t\"\\x03\\x037 \\x03\\x0b+\\x03\\x021\\x00\\x02\\x01\\x04\\x02\\x01\\x02\\x02\\x019\\x02\" +\n\t\"\\x03\\x1c\\x02\\x02$\\x03\\x80p$\\x02\\x03:\\x02\\x03\\x0a\\x03\\xc1r.\\x03\\xc1r,\\x03\" +\n\t\"\\xc1r\\x02\\x02\\x02:\\x02\\x02>\\x02\\x02,\\x02\\x02\\x10\\x02\\x02\\x00\\x03\\xc1s<\" +\n\t\"\\x03\\xc1s*\\x03\\xc2L$\\x03\\xc2L;\\x02\\x09)\\x02\\x0a\\x19\\x03\\x83\\xab\\xe3\\x03\" +\n\t\"\\x83\\xab\\xf2\\x03 4\\xe0\\x03\\x81\\xab\\xea\\x03\\x81\\xab\\xf3\\x03 4\\xef\\x03\\x96\" +\n\t\"\\xe1\\xcd\\x03\\x84\\xe5\\xc3\\x02\\x0d\\x11\\x03\\x8b\\xec\\xcb\\x03\\x94\\xec\\xcf\\x03\" +\n\t\"\\x9a\\xec\\xc2\\x03\\x8b\\xec\\xdb\\x03\\x94\\xec\\xdf\\x03\\x9a\\xec\\xd2\\x03\\x01\\x0c\" +\n\t\"!\\x03\\x01\\x0c#\\x03ʠ\\x9d\\x03ʣ\\x9c\\x03ʢ\\x9f\\x03ʥ\\x9e\\x03ʤ\\x91\\x03ʧ\\x90\\x03\" +\n\t\"ʦ\\x93\\x03ʩ\\x92\\x03ʨ\\x95\\x03\\xca\\xf3\\xb5\\x03\\xca\\xf0\\xb4\\x03\\xca\\xf1\\xb7\" +\n\t\"\\x03\\xca\\xf6\\xb6\\x03\\xca\\xf7\\x89\\x03\\xca\\xf4\\x88\\x03\\xca\\xf5\\x8b\\x03\\xca\" +\n\t\"\\xfa\\x8a\\x03\\xca\\xfb\\x8d\\x03\\xca\\xf8\\x8c\\x03\\xca\\xf9\\x8f\\x03\\xca\\xfe\\x8e\" +\n\t\"\\x03\\xca\\xff\\x81\\x03\\xca\\xfc\\x80\\x03\\xca\\xfd\\x83\\x03\\xca\\xe2\\x82\\x03\\xca\" +\n\t\"\\xe3\\x85\\x03\\xca\\xe0\\x84\\x03\\xca\\xe1\\x87\\x03\\xca\\xe6\\x86\\x03\\xca\\xe7\\x99\" +\n\t\"\\x03\\xca\\xe4\\x98\\x03\\xca\\xe5\\x9b\\x03\\xca\\xea\\x9a\\x03\\xca\\xeb\\x9d\\x03\\xca\" +\n\t\"\\xe8\\x9c\\x03ؓ\\x89\\x03ߔ\\x8b\\x02\\x010\\x03\\x03\\x04\\x1e\\x03\\x04\\x15\\x12\\x03\" +\n\t\"\\x0b\\x05,\\x03\\x06\\x04\\x00\\x03\\x06\\x04)\\x03\\x06\\x044\\x03\\x06\\x04<\\x03\\x06\" +\n\t\"\\x05\\x1d\\x03\\x06\\x06\\x00\\x03\\x06\\x06\\x0a\\x03\\x06\\x06'\\x03\\x06\\x062\\x03\" +\n\t\"\\x0786\\x03\\x079/\\x03\\x079 \\x03\\x07:\\x0e\\x03\\x07:\\x1b\\x03\\x07:%\\x03\\x07;/\" +\n\t\"\\x03\\x07;%\\x03\\x074\\x11\\x03\\x076\\x09\\x03\\x077*\\x03\\x070\\x01\\x03\\x070\\x0f\" +\n\t\"\\x03\\x070.\\x03\\x071\\x16\\x03\\x071\\x04\\x03\\x0710\\x03\\x072\\x18\\x03\\x072-\" +\n\t\"\\x03\\x073\\x14\\x03\\x073>\\x03\\x07'\\x09\\x03\\x07 \\x00\\x03\\x07\\x1f\\x0b\\x03\" +\n\t\"\\x07\\x18#\\x03\\x07\\x18(\\x03\\x07\\x186\\x03\\x07\\x18\\x03\\x03\\x07\\x19\\x16\\x03\" +\n\t\"\\x07\\x116\\x03\\x07\\x12'\\x03\\x07\\x13\\x10\\x03\\x07\\x0c&\\x03\\x07\\x0c\\x08\\x03\" +\n\t\"\\x07\\x0c\\x13\\x03\\x07\\x0d\\x02\\x03\\x07\\x0d\\x1c\\x03\\x07\\x0b5\\x03\\x07\\x0b\" +\n\t\"\\x0a\\x03\\x07\\x0b\\x01\\x03\\x07\\x0b\\x0f\\x03\\x07\\x05\\x00\\x03\\x07\\x05\\x09\\x03\" +\n\t\"\\x07\\x05\\x0b\\x03\\x07\\x07\\x01\\x03\\x07\\x07\\x08\\x03\\x07\\x00<\\x03\\x07\\x00+\" +\n\t\"\\x03\\x07\\x01)\\x03\\x07\\x01\\x1b\\x03\\x07\\x01\\x08\\x03\\x07\\x03?\\x03\\x0445\\x03\" +\n\t\"\\x044\\x08\\x03\\x0454\\x03\\x04)/\\x03\\x04)5\\x03\\x04+\\x05\\x03\\x04+\\x14\\x03\" +\n\t\"\\x04+ \\x03\\x04+<\\x03\\x04*&\\x03\\x04*\\x22\\x03\\x04&8\\x03\\x04!\\x01\\x03\\x04!\" +\n\t\"\\x22\\x03\\x04\\x11+\\x03\\x04\\x10.\\x03\\x04\\x104\\x03\\x04\\x13=\\x03\\x04\\x12\\x04\" +\n\t\"\\x03\\x04\\x12\\x0a\\x03\\x04\\x0d\\x1d\\x03\\x04\\x0d\\x07\\x03\\x04\\x0d \\x03\\x05<>\" +\n\t\"\\x03\\x055<\\x03\\x055!\\x03\\x055#\\x03\\x055&\\x03\\x054\\x1d\\x03\\x054\\x02\\x03\" +\n\t\"\\x054\\x07\\x03\\x0571\\x03\\x053\\x1a\\x03\\x053\\x16\\x03\\x05.<\\x03\\x05.\\x07\\x03\" +\n\t\"\\x05):\\x03\\x05)<\\x03\\x05)\\x0c\\x03\\x05)\\x15\\x03\\x05+-\\x03\\x05+5\\x03\\x05$\" +\n\t\"\\x1e\\x03\\x05$\\x14\\x03\\x05'\\x04\\x03\\x05'\\x14\\x03\\x05&\\x02\\x03\\x05\\x226\" +\n\t\"\\x03\\x05\\x22\\x0c\\x03\\x05\\x22\\x1c\\x03\\x05\\x19\\x0a\\x03\\x05\\x1b\\x09\\x03\\x05\" +\n\t\"\\x1b\\x0c\\x03\\x05\\x14\\x07\\x03\\x05\\x16?\\x03\\x05\\x16\\x0c\\x03\\x05\\x0c\\x05\" +\n\t\"\\x03\\x05\\x0e\\x0f\\x03\\x05\\x01\\x0e\\x03\\x05\\x00(\\x03\\x05\\x030\\x03\\x05\\x03\" +\n\t\"\\x06\\x03\\x0a==\\x03\\x0a=1\\x03\\x0a=,\\x03\\x0a=\\x0c\\x03\\x0a??\\x03\\x0a<\\x08\" +\n\t\"\\x03\\x0a9!\\x03\\x0a9)\\x03\\x0a97\\x03\\x0a99\\x03\\x0a6\\x0a\\x03\\x0a6\\x1c\\x03\" +\n\t\"\\x0a6\\x17\\x03\\x0a7'\\x03\\x0a78\\x03\\x0a73\\x03\\x0a'\\x01\\x03\\x0a'&\\x03\\x0a\" +\n\t\"\\x1f\\x0e\\x03\\x0a\\x1f\\x03\\x03\\x0a\\x1f3\\x03\\x0a\\x1b/\\x03\\x0a\\x18\\x19\\x03\" +\n\t\"\\x0a\\x19\\x01\\x03\\x0a\\x16\\x14\\x03\\x0a\\x0e\\x22\\x03\\x0a\\x0f\\x10\\x03\\x0a\\x0f\" +\n\t\"\\x02\\x03\\x0a\\x0f \\x03\\x0a\\x0c\\x04\\x03\\x0a\\x0b>\\x03\\x0a\\x0b+\\x03\\x0a\\x08/\" +\n\t\"\\x03\\x0a\\x046\\x03\\x0a\\x05\\x14\\x03\\x0a\\x00\\x04\\x03\\x0a\\x00\\x10\\x03\\x0a\" +\n\t\"\\x00\\x14\\x03\\x0b<3\\x03\\x0b;*\\x03\\x0b9\\x22\\x03\\x0b9)\\x03\\x0b97\\x03\\x0b+\" +\n\t\"\\x10\\x03\\x0b((\\x03\\x0b&5\\x03\\x0b$\\x1c\\x03\\x0b$\\x12\\x03\\x0b%\\x04\\x03\\x0b#\" +\n\t\"<\\x03\\x0b#0\\x03\\x0b#\\x0d\\x03\\x0b#\\x19\\x03\\x0b!:\\x03\\x0b!\\x1f\\x03\\x0b!\" +\n\t\"\\x00\\x03\\x0b\\x1e5\\x03\\x0b\\x1c\\x1d\\x03\\x0b\\x1d-\\x03\\x0b\\x1d(\\x03\\x0b\\x18.\" +\n\t\"\\x03\\x0b\\x18 \\x03\\x0b\\x18\\x16\\x03\\x0b\\x14\\x13\\x03\\x0b\\x15$\\x03\\x0b\\x15\" +\n\t\"\\x22\\x03\\x0b\\x12\\x1b\\x03\\x0b\\x12\\x10\\x03\\x0b\\x132\\x03\\x0b\\x13=\\x03\\x0b\" +\n\t\"\\x12\\x18\\x03\\x0b\\x0c&\\x03\\x0b\\x061\\x03\\x0b\\x06:\\x03\\x0b\\x05#\\x03\\x0b\\x05\" +\n\t\"<\\x03\\x0b\\x04\\x0b\\x03\\x0b\\x04\\x04\\x03\\x0b\\x04\\x1b\\x03\\x0b\\x042\\x03\\x0b\" +\n\t\"\\x041\\x03\\x0b\\x03\\x03\\x03\\x0b\\x03\\x1d\\x03\\x0b\\x03/\\x03\\x0b\\x03+\\x03\\x0b\" +\n\t\"\\x02\\x1b\\x03\\x0b\\x02\\x00\\x03\\x0b\\x01\\x1e\\x03\\x0b\\x01\\x08\\x03\\x0b\\x015\" +\n\t\"\\x03\\x06\\x0d9\\x03\\x06\\x0d=\\x03\\x06\\x0d?\\x03\\x02\\x001\\x03\\x02\\x003\\x03\" +\n\t\"\\x02\\x02\\x19\\x03\\x02\\x006\\x03\\x02\\x02\\x1b\\x03\\x02\\x004\\x03\\x02\\x00<\\x03\" +\n\t\"\\x02\\x02\\x0a\\x03\\x02\\x02\\x0e\\x03\\x02\\x01\\x1a\\x03\\x02\\x01\\x07\\x03\\x02\\x01\" +\n\t\"\\x05\\x03\\x02\\x01\\x0b\\x03\\x02\\x01%\\x03\\x02\\x01\\x0c\\x03\\x02\\x01\\x04\\x03\" +\n\t\"\\x02\\x01\\x1c\\x03\\x02\\x00.\\x03\\x02\\x002\\x03\\x02\\x00>\\x03\\x02\\x00\\x12\\x03\" +\n\t\"\\x02\\x00\\x16\\x03\\x02\\x011\\x03\\x02\\x013\\x03\\x02\\x02 \\x03\\x02\\x02%\\x03\\x02\" +\n\t\"\\x02$\\x03\\x02\\x028\\x03\\x02\\x02;\\x03\\x02\\x024\\x03\\x02\\x012\\x03\\x02\\x022\" +\n\t\"\\x03\\x02\\x02/\\x03\\x02\\x01,\\x03\\x02\\x01\\x13\\x03\\x02\\x01\\x16\\x03\\x02\\x01\" +\n\t\"\\x11\\x03\\x02\\x01\\x1e\\x03\\x02\\x01\\x15\\x03\\x02\\x01\\x17\\x03\\x02\\x01\\x0f\\x03\" +\n\t\"\\x02\\x01\\x08\\x03\\x02\\x00?\\x03\\x02\\x03\\x07\\x03\\x02\\x03\\x0d\\x03\\x02\\x03\" +\n\t\"\\x13\\x03\\x02\\x03\\x1d\\x03\\x02\\x03\\x1f\\x03\\x02\\x00\\x03\\x03\\x02\\x00\\x0d\\x03\" +\n\t\"\\x02\\x00\\x01\\x03\\x02\\x00\\x1b\\x03\\x02\\x00\\x19\\x03\\x02\\x00\\x18\\x03\\x02\\x00\" +\n\t\"\\x13\\x03\\x02\\x00/\\x03\\x07>\\x12\\x03\\x07<\\x1f\\x03\\x07>\\x1d\\x03\\x06\\x1d\\x0e\" +\n\t\"\\x03\\x07>\\x1c\\x03\\x07>:\\x03\\x07>\\x13\\x03\\x04\\x12+\\x03\\x07?\\x03\\x03\\x07>\" +\n\t\"\\x02\\x03\\x06\\x224\\x03\\x06\\x1a.\\x03\\x07<%\\x03\\x06\\x1c\\x0b\\x03\\x0609\\x03\" +\n\t\"\\x05\\x1f\\x01\\x03\\x04'\\x08\\x03\\x93\\xfd\\xf5\\x03\\x02\\x0d \\x03\\x02\\x0d#\\x03\" +\n\t\"\\x02\\x0d!\\x03\\x02\\x0d&\\x03\\x02\\x0d\\x22\\x03\\x02\\x0d/\\x03\\x02\\x0d,\\x03\\x02\" +\n\t\"\\x0d$\\x03\\x02\\x0d'\\x03\\x02\\x0d%\\x03\\x02\\x0d;\\x03\\x02\\x0d=\\x03\\x02\\x0d?\" +\n\t\"\\x03\\x099.\\x03\\x08\\x0b7\\x03\\x08\\x02\\x14\\x03\\x08\\x14\\x0d\\x03\\x08.:\\x03\" +\n\t\"\\x089'\\x03\\x0f\\x0b\\x18\\x03\\x0f\\x1c1\\x03\\x0f\\x17&\\x03\\x0f9\\x1f\\x03\\x0f0\" +\n\t\"\\x0c\\x03\\x0e\\x0a9\\x03\\x0e\\x056\\x03\\x0e\\x1c#\\x03\\x0f\\x13\\x0e\\x03\\x072\\x00\" +\n\t\"\\x03\\x070\\x0d\\x03\\x072\\x0b\\x03\\x06\\x11\\x18\\x03\\x070\\x10\\x03\\x06\\x0f(\\x03\" +\n\t\"\\x072\\x05\\x03\\x06\\x0f,\\x03\\x073\\x15\\x03\\x06\\x07\\x08\\x03\\x05\\x16\\x02\\x03\" +\n\t\"\\x04\\x0b \\x03\\x05:8\\x03\\x05\\x16%\\x03\\x0a\\x0d\\x1f\\x03\\x06\\x16\\x10\\x03\\x05\" +\n\t\"\\x1d5\\x03\\x05*;\\x03\\x05\\x16\\x1b\\x03\\x04.-\\x03\\x06\\x1a\\x19\\x03\\x04\\x03,\" +\n\t\"\\x03\\x0b87\\x03\\x04/\\x0a\\x03\\x06\\x00,\\x03\\x04-\\x01\\x03\\x04\\x1e-\\x03\\x06/(\" +\n\t\"\\x03\\x0a\\x0b5\\x03\\x06\\x0e7\\x03\\x06\\x07.\\x03\\x0597\\x03\\x0a*%\\x03\\x0760\" +\n\t\"\\x03\\x06\\x0c;\\x03\\x05'\\x00\\x03\\x072.\\x03\\x072\\x08\\x03\\x06=\\x01\\x03\\x06\" +\n\t\"\\x05\\x1b\\x03\\x06\\x06\\x12\\x03\\x06$=\\x03\\x06'\\x0d\\x03\\x04\\x11\\x0f\\x03\\x076\" +\n\t\",\\x03\\x06\\x07;\\x03\\x06.,\\x03\\x86\\xf9\\xea\\x03\\x8f\\xff\\xeb\\x02\\x092\\x02\" +\n\t\"\\x095\\x02\\x094\\x02\\x09;\\x02\\x09>\\x02\\x098\\x02\\x09*\\x02\\x09/\\x02\\x09,\\x02\" +\n\t\"\\x09%\\x02\\x09&\\x02\\x09#\\x02\\x09 \\x02\\x08!\\x02\\x08%\\x02\\x08$\\x02\\x08+\\x02\" +\n\t\"\\x08.\\x02\\x08*\\x02\\x08&\\x02\\x088\\x02\\x08>\\x02\\x084\\x02\\x086\\x02\\x080\\x02\" +\n\t\"\\x08\\x10\\x02\\x08\\x17\\x02\\x08\\x12\\x02\\x08\\x1d\\x02\\x08\\x1f\\x02\\x08\\x13\\x02\" +\n\t\"\\x08\\x15\\x02\\x08\\x14\\x02\\x08\\x0c\\x03\\x8b\\xfd\\xd0\\x03\\x81\\xec\\xc6\\x03\\x87\" +\n\t\"\\xe0\\x8a\\x03-2\\xe3\\x03\\x80\\xef\\xe4\\x03-2\\xea\\x03\\x88\\xe6\\xeb\\x03\\x8e\\xe6\" +\n\t\"\\xe8\\x03\\x84\\xe6\\xe9\\x03\\x97\\xe6\\xee\\x03-2\\xf9\\x03-2\\xf6\\x03\\x8e\\xe3\\xad\" +\n\t\"\\x03\\x80\\xe3\\x92\\x03\\x88\\xe3\\x90\\x03\\x8e\\xe3\\x90\\x03\\x80\\xe3\\x97\\x03\\x88\" +\n\t\"\\xe3\\x95\\x03\\x88\\xfe\\xcb\\x03\\x8e\\xfe\\xca\\x03\\x84\\xfe\\xcd\\x03\\x91\\xef\\xc9\" +\n\t\"\\x03-2\\xc1\\x03-2\\xc0\\x03-2\\xcb\\x03\\x88@\\x09\\x03\\x8e@\\x08\\x03\\x8f\\xe0\\xf5\" +\n\t\"\\x03\\x8e\\xe6\\xf9\\x03\\x8e\\xe0\\xfa\\x03\\x93\\xff\\xf4\\x03\\x84\\xee\\xd3\\x03\\x0b\" +\n\t\"(\\x04\\x023 \\x03\\x0b)\\x08\\x021;\\x02\\x01*\\x03\\x0b#\\x10\\x03\\x0b 0\\x03\\x0b!\" +\n\t\"\\x10\\x03\\x0b!0\\x03\\x07\\x15\\x08\\x03\\x09?5\\x03\\x07\\x1f\\x08\\x03\\x07\\x17\\x0b\" +\n\t\"\\x03\\x09\\x1f\\x15\\x03\\x0b\\x1c7\\x03\\x0a+#\\x03\\x06\\x1a\\x1b\\x03\\x06\\x1a\\x14\" +\n\t\"\\x03\\x0a\\x01\\x18\\x03\\x06#\\x1b\\x03\\x0a2\\x0c\\x03\\x0a\\x01\\x04\\x03\\x09#;\\x03\" +\n\t\"\\x08='\\x03\\x08\\x1a\\x0a\\x03\\x07</\\x03\\x07:+\\x03\\x07\\x07*\\x03\\x06&\\x1c\\x03\" +\n\t\"\\x09\\x0c\\x16\\x03\\x09\\x10\\x0e\\x03\\x08'\\x0f\\x03\\x08+\\x09\\x03\\x074%\\x03\\x06\" +\n\t\"!3\\x03\\x06\\x03+\\x03\\x0b\\x1e\\x19\\x03\\x0a))\\x03\\x09\\x08\\x19\\x03\\x08,\\x05\" +\n\t\"\\x03\\x07<2\\x03\\x06\\x1c>\\x03\\x0a\\x111\\x03\\x09\\x1b\\x09\\x03\\x073.\\x03\\x07\" +\n\t\"\\x01\\x00\\x03\\x09/,\\x03\\x07#>\\x03\\x07\\x048\\x03\\x0a\\x1f\\x22\\x03\\x098>\\x03\" +\n\t\"\\x09\\x11\\x00\\x03\\x08/\\x17\\x03\\x06'\\x22\\x03\\x0b\\x1a+\\x03\\x0a\\x22\\x19\\x03\" +\n\t\"\\x0a/1\\x03\\x0974\\x03\\x09\\x0f\\x22\\x03\\x08,\\x22\\x03\\x08?\\x14\\x03\\x07$5\\x03\" +\n\t\"\\x07<3\\x03\\x07=*\\x03\\x07\\x13\\x18\\x03\\x068\\x0a\\x03\\x06\\x09\\x16\\x03\\x06\" +\n\t\"\\x13\\x00\\x03\\x08\\x067\\x03\\x08\\x01\\x03\\x03\\x08\\x12\\x1d\\x03\\x07+7\\x03\\x06(\" +\n\t\";\\x03\\x06\\x1c?\\x03\\x07\\x0e\\x17\\x03\\x0a\\x06\\x1d\\x03\\x0a\\x19\\x07\\x03\\x08\" +\n\t\"\\x14$\\x03\\x07$;\\x03\\x08,$\\x03\\x08\\x06\\x0d\\x03\\x07\\x16\\x0a\\x03\\x06>>\\x03\" +\n\t\"\\x0a\\x06\\x12\\x03\\x0a\\x14)\\x03\\x09\\x0d\\x1f\\x03\\x09\\x12\\x17\\x03\\x09\\x19\" +\n\t\"\\x01\\x03\\x08\\x11 \\x03\\x08\\x1d'\\x03\\x06<\\x1a\\x03\\x0a.\\x00\\x03\\x07'\\x18\" +\n\t\"\\x03\\x0a\\x22\\x08\\x03\\x08\\x0d\\x0a\\x03\\x08\\x13)\\x03\\x07*)\\x03\\x06<,\\x03\" +\n\t\"\\x07\\x0b\\x1a\\x03\\x09.\\x14\\x03\\x09\\x0d\\x1e\\x03\\x07\\x0e#\\x03\\x0b\\x1d'\\x03\" +\n\t\"\\x0a\\x0a8\\x03\\x09%2\\x03\\x08+&\\x03\\x080\\x12\\x03\\x0a)4\\x03\\x08\\x06\\x1f\\x03\" +\n\t\"\\x0b\\x1b\\x1a\\x03\\x0a\\x1b\\x0f\\x03\\x0b\\x1d*\\x03\\x09\\x16$\\x03\\x090\\x11\\x03\" +\n\t\"\\x08\\x11\\x08\\x03\\x0a*(\\x03\\x0a\\x042\\x03\\x089,\\x03\\x074'\\x03\\x07\\x0f\\x05\" +\n\t\"\\x03\\x09\\x0b\\x0a\\x03\\x07\\x1b\\x01\\x03\\x09\\x17:\\x03\\x09.\\x0d\\x03\\x07.\\x11\" +\n\t\"\\x03\\x09+\\x15\\x03\\x080\\x13\\x03\\x0b\\x1f\\x19\\x03\\x0a \\x11\\x03\\x0a\\x220\\x03\" +\n\t\"\\x09\\x07;\\x03\\x08\\x16\\x1c\\x03\\x07,\\x13\\x03\\x07\\x0e/\\x03\\x06\\x221\\x03\\x0a\" +\n\t\".\\x0a\\x03\\x0a7\\x02\\x03\\x0a\\x032\\x03\\x0a\\x1d.\\x03\\x091\\x06\\x03\\x09\\x19:\" +\n\t\"\\x03\\x08\\x02/\\x03\\x060+\\x03\\x06\\x0f-\\x03\\x06\\x1c\\x1f\\x03\\x06\\x1d\\x07\\x03\" +\n\t\"\\x0a,\\x11\\x03\\x09=\\x0d\\x03\\x09\\x0b;\\x03\\x07\\x1b/\\x03\\x0a\\x1f:\\x03\\x09 \" +\n\t\"\\x1f\\x03\\x09.\\x10\\x03\\x094\\x0b\\x03\\x09\\x1a1\\x03\\x08#\\x1a\\x03\\x084\\x1d\" +\n\t\"\\x03\\x08\\x01\\x1f\\x03\\x08\\x11\\x22\\x03\\x07'8\\x03\\x07\\x1a>\\x03\\x0757\\x03\" +\n\t\"\\x06&9\\x03\\x06+\\x11\\x03\\x0a.\\x0b\\x03\\x0a,>\\x03\\x0a4#\\x03\\x08%\\x17\\x03\" +\n\t\"\\x07\\x05\\x22\\x03\\x07\\x0c\\x0b\\x03\\x0a\\x1d+\\x03\\x0a\\x19\\x16\\x03\\x09+\\x1f\" +\n\t\"\\x03\\x09\\x08\\x0b\\x03\\x08\\x16\\x18\\x03\\x08+\\x12\\x03\\x0b\\x1d\\x0c\\x03\\x0a=\" +\n\t\"\\x10\\x03\\x0a\\x09\\x0d\\x03\\x0a\\x10\\x11\\x03\\x09&0\\x03\\x08(\\x1f\\x03\\x087\\x07\" +\n\t\"\\x03\\x08\\x185\\x03\\x07'6\\x03\\x06.\\x05\\x03\\x06=\\x04\\x03\\x06;;\\x03\\x06\\x06,\" +\n\t\"\\x03\\x0b\\x18>\\x03\\x08\\x00\\x18\\x03\\x06 \\x03\\x03\\x06<\\x00\\x03\\x09%\\x18\\x03\" +\n\t\"\\x0b\\x1c<\\x03\\x0a%!\\x03\\x0a\\x09\\x12\\x03\\x0a\\x16\\x02\\x03\\x090'\\x03\\x09\" +\n\t\"\\x0e=\\x03\\x08 \\x0e\\x03\\x08>\\x03\\x03\\x074>\\x03\\x06&?\\x03\\x06\\x19\\x09\\x03\" +\n\t\"\\x06?(\\x03\\x0a-\\x0e\\x03\\x09:3\\x03\\x098:\\x03\\x09\\x12\\x0b\\x03\\x09\\x1d\\x17\" +\n\t\"\\x03\\x087\\x05\\x03\\x082\\x14\\x03\\x08\\x06%\\x03\\x08\\x13\\x1f\\x03\\x06\\x06\\x0e\" +\n\t\"\\x03\\x0a\\x22<\\x03\\x09/<\\x03\\x06>+\\x03\\x0a'?\\x03\\x0a\\x13\\x0c\\x03\\x09\\x10<\" +\n\t\"\\x03\\x07\\x1b=\\x03\\x0a\\x19\\x13\\x03\\x09\\x22\\x1d\\x03\\x09\\x07\\x0d\\x03\\x08)\" +\n\t\"\\x1c\\x03\\x06=\\x1a\\x03\\x0a/4\\x03\\x0a7\\x11\\x03\\x0a\\x16:\\x03\\x09?3\\x03\\x09:\" +\n\t\"/\\x03\\x09\\x05\\x0a\\x03\\x09\\x14\\x06\\x03\\x087\\x22\\x03\\x080\\x07\\x03\\x08\\x1a\" +\n\t\"\\x1f\\x03\\x07\\x04(\\x03\\x07\\x04\\x09\\x03\\x06 %\\x03\\x06<\\x08\\x03\\x0a+\\x14\" +\n\t\"\\x03\\x09\\x1d\\x16\\x03\\x0a70\\x03\\x08 >\\x03\\x0857\\x03\\x070\\x0a\\x03\\x06=\\x12\" +\n\t\"\\x03\\x06\\x16%\\x03\\x06\\x1d,\\x03\\x099#\\x03\\x09\\x10>\\x03\\x07 \\x1e\\x03\\x08\" +\n\t\"\\x0c<\\x03\\x08\\x0b\\x18\\x03\\x08\\x15+\\x03\\x08,:\\x03\\x08%\\x22\\x03\\x07\\x0a$\" +\n\t\"\\x03\\x0b\\x1c=\\x03\\x07+\\x08\\x03\\x0a/\\x05\\x03\\x0a \\x07\\x03\\x0a\\x12'\\x03\" +\n\t\"\\x09#\\x11\\x03\\x08\\x1b\\x15\\x03\\x0a\\x06\\x01\\x03\\x09\\x1c\\x1b\\x03\\x0922\\x03\" +\n\t\"\\x07\\x14<\\x03\\x07\\x09\\x04\\x03\\x061\\x04\\x03\\x07\\x0e\\x01\\x03\\x0a\\x13\\x18\" +\n\t\"\\x03\\x0a-\\x0c\\x03\\x0a?\\x0d\\x03\\x0a\\x09\\x0a\\x03\\x091&\\x03\\x0a/\\x0b\\x03\" +\n\t\"\\x08$<\\x03\\x083\\x1d\\x03\\x08\\x0c$\\x03\\x08\\x0d\\x07\\x03\\x08\\x0d?\\x03\\x08\" +\n\t\"\\x0e\\x14\\x03\\x065\\x0a\\x03\\x08\\x1a#\\x03\\x08\\x16#\\x03\\x0702\\x03\\x07\\x03\" +\n\t\"\\x1a\\x03\\x06(\\x1d\\x03\\x06+\\x1b\\x03\\x06\\x0b\\x05\\x03\\x06\\x0b\\x17\\x03\\x06\" +\n\t\"\\x0c\\x04\\x03\\x06\\x1e\\x19\\x03\\x06+0\\x03\\x062\\x18\\x03\\x0b\\x16\\x1e\\x03\\x0a+\" +\n\t\"\\x16\\x03\\x0a-?\\x03\\x0a#:\\x03\\x0a#\\x10\\x03\\x0a%$\\x03\\x0a>+\\x03\\x0a01\\x03\" +\n\t\"\\x0a1\\x10\\x03\\x0a\\x099\\x03\\x0a\\x0a\\x12\\x03\\x0a\\x19\\x1f\\x03\\x0a\\x19\\x12\" +\n\t\"\\x03\\x09*)\\x03\\x09-\\x16\\x03\\x09.1\\x03\\x09.2\\x03\\x09<\\x0e\\x03\\x09> \\x03\" +\n\t\"\\x093\\x12\\x03\\x09\\x0b\\x01\\x03\\x09\\x1c2\\x03\\x09\\x11\\x1c\\x03\\x09\\x15%\\x03\" +\n\t\"\\x08,&\\x03\\x08!\\x22\\x03\\x089(\\x03\\x08\\x0b\\x1a\\x03\\x08\\x0d2\\x03\\x08\\x0c\" +\n\t\"\\x04\\x03\\x08\\x0c\\x06\\x03\\x08\\x0c\\x1f\\x03\\x08\\x0c\\x0c\\x03\\x08\\x0f\\x1f\\x03\" +\n\t\"\\x08\\x0f\\x1d\\x03\\x08\\x00\\x14\\x03\\x08\\x03\\x14\\x03\\x08\\x06\\x16\\x03\\x08\\x1e\" +\n\t\"#\\x03\\x08\\x11\\x11\\x03\\x08\\x10\\x18\\x03\\x08\\x14(\\x03\\x07)\\x1e\\x03\\x07.1\" +\n\t\"\\x03\\x07 $\\x03\\x07 '\\x03\\x078\\x08\\x03\\x07\\x0d0\\x03\\x07\\x0f7\\x03\\x07\\x05#\" +\n\t\"\\x03\\x07\\x05\\x1a\\x03\\x07\\x1a7\\x03\\x07\\x1d-\\x03\\x07\\x17\\x10\\x03\\x06)\\x1f\" +\n\t\"\\x03\\x062\\x0b\\x03\\x066\\x16\\x03\\x06\\x09\\x11\\x03\\x09(\\x1e\\x03\\x07!5\\x03\" +\n\t\"\\x0b\\x11\\x16\\x03\\x0a/\\x04\\x03\\x0a,\\x1a\\x03\\x0b\\x173\\x03\\x0a,1\\x03\\x0a/5\" +\n\t\"\\x03\\x0a\\x221\\x03\\x0a\\x22\\x0d\\x03\\x0a?%\\x03\\x0a<,\\x03\\x0a?#\\x03\\x0a>\\x19\" +\n\t\"\\x03\\x0a\\x08&\\x03\\x0a\\x0b\\x0e\\x03\\x0a\\x0c:\\x03\\x0a\\x0c+\\x03\\x0a\\x03\\x22\" +\n\t\"\\x03\\x0a\\x06)\\x03\\x0a\\x11\\x10\\x03\\x0a\\x11\\x1a\\x03\\x0a\\x17-\\x03\\x0a\\x14(\" +\n\t\"\\x03\\x09)\\x1e\\x03\\x09/\\x09\\x03\\x09.\\x00\\x03\\x09,\\x07\\x03\\x09/*\\x03\\x09-9\" +\n\t\"\\x03\\x09\\x228\\x03\\x09%\\x09\\x03\\x09:\\x12\\x03\\x09;\\x1d\\x03\\x09?\\x06\\x03\" +\n\t\"\\x093%\\x03\\x096\\x05\\x03\\x096\\x08\\x03\\x097\\x02\\x03\\x09\\x07,\\x03\\x09\\x04,\" +\n\t\"\\x03\\x09\\x1f\\x16\\x03\\x09\\x11\\x03\\x03\\x09\\x11\\x12\\x03\\x09\\x168\\x03\\x08*\" +\n\t\"\\x05\\x03\\x08/2\\x03\\x084:\\x03\\x08\\x22+\\x03\\x08 0\\x03\\x08&\\x0a\\x03\\x08;\" +\n\t\"\\x10\\x03\\x08>$\\x03\\x08>\\x18\\x03\\x0829\\x03\\x082:\\x03\\x081,\\x03\\x081<\\x03\" +\n\t\"\\x081\\x1c\\x03\\x087#\\x03\\x087*\\x03\\x08\\x09'\\x03\\x08\\x00\\x1d\\x03\\x08\\x05-\" +\n\t\"\\x03\\x08\\x1f4\\x03\\x08\\x1d\\x04\\x03\\x08\\x16\\x0f\\x03\\x07*7\\x03\\x07'!\\x03\" +\n\t\"\\x07%\\x1b\\x03\\x077\\x0c\\x03\\x07\\x0c1\\x03\\x07\\x0c.\\x03\\x07\\x00\\x06\\x03\\x07\" +\n\t\"\\x01\\x02\\x03\\x07\\x010\\x03\\x07\\x06=\\x03\\x07\\x01\\x03\\x03\\x07\\x01\\x13\\x03\" +\n\t\"\\x07\\x06\\x06\\x03\\x07\\x05\\x0a\\x03\\x07\\x1f\\x09\\x03\\x07\\x17:\\x03\\x06*1\\x03\" +\n\t\"\\x06-\\x1d\\x03\\x06\\x223\\x03\\x062:\\x03\\x060$\\x03\\x066\\x1e\\x03\\x064\\x12\\x03\" +\n\t\"\\x0645\\x03\\x06\\x0b\\x00\\x03\\x06\\x0b7\\x03\\x06\\x07\\x1f\\x03\\x06\\x15\\x12\\x03\" +\n\t\"\\x0c\\x05\\x0f\\x03\\x0b+\\x0b\\x03\\x0b+-\\x03\\x06\\x16\\x1b\\x03\\x06\\x15\\x17\\x03\" +\n\t\"\\x89\\xca\\xea\\x03\\x89\\xca\\xe8\\x03\\x0c8\\x10\\x03\\x0c8\\x01\\x03\\x0c8\\x0f\\x03\" +\n\t\"\\x0d8%\\x03\\x0d8!\\x03\\x0c8-\\x03\\x0c8/\\x03\\x0c8+\\x03\\x0c87\\x03\\x0c85\\x03\" +\n\t\"\\x0c9\\x09\\x03\\x0c9\\x0d\\x03\\x0c9\\x0f\\x03\\x0c9\\x0b\\x03\\xcfu\\x0c\\x03\\xcfu\" +\n\t\"\\x0f\\x03\\xcfu\\x0e\\x03\\xcfu\\x09\\x03\\x0c9\\x10\\x03\\x0d9\\x0c\\x03\\xcf`;\\x03\" +\n\t\"\\xcf`>\\x03\\xcf`9\\x03\\xcf`8\\x03\\xcf`7\\x03\\xcf`*\\x03\\xcf`-\\x03\\xcf`,\\x03\" +\n\t\"\\x0d\\x1b\\x1a\\x03\\x0d\\x1b&\\x03\\x0c=.\\x03\\x0c=%\\x03\\x0c>\\x1e\\x03\\x0c>\\x14\" +\n\t\"\\x03\\x0c?\\x06\\x03\\x0c?\\x0b\\x03\\x0c?\\x0c\\x03\\x0c?\\x0d\\x03\\x0c?\\x02\\x03\" +\n\t\"\\x0c>\\x0f\\x03\\x0c>\\x08\\x03\\x0c>\\x09\\x03\\x0c>,\\x03\\x0c>\\x0c\\x03\\x0c?\\x13\" +\n\t\"\\x03\\x0c?\\x16\\x03\\x0c?\\x15\\x03\\x0c?\\x1c\\x03\\x0c?\\x1f\\x03\\x0c?\\x1d\\x03\" +\n\t\"\\x0c?\\x1a\\x03\\x0c?\\x17\\x03\\x0c?\\x08\\x03\\x0c?\\x09\\x03\\x0c?\\x0e\\x03\\x0c?\" +\n\t\"\\x04\\x03\\x0c?\\x05\\x03\\x0c<?\\x03\\x0c=\\x00\\x03\\x0c=\\x06\\x03\\x0c=\\x05\\x03\" +\n\t\"\\x0c=\\x0c\\x03\\x0c=\\x0f\\x03\\x0c=\\x0d\\x03\\x0c=\\x0b\\x03\\x0c=\\x07\\x03\\x0c=\" +\n\t\"\\x19\\x03\\x0c=\\x15\\x03\\x0c=\\x11\\x03\\x0c=1\\x03\\x0c=3\\x03\\x0c=0\\x03\\x0c=>\" +\n\t\"\\x03\\x0c=2\\x03\\x0c=6\\x03\\x0c<\\x07\\x03\\x0c<\\x05\\x03\\x0e:!\\x03\\x0e:#\\x03\" +\n\t\"\\x0e8\\x09\\x03\\x0e:&\\x03\\x0e8\\x0b\\x03\\x0e:$\\x03\\x0e:,\\x03\\x0e8\\x1a\\x03\" +\n\t\"\\x0e8\\x1e\\x03\\x0e:*\\x03\\x0e:7\\x03\\x0e:5\\x03\\x0e:;\\x03\\x0e:\\x15\\x03\\x0e:<\" +\n\t\"\\x03\\x0e:4\\x03\\x0e:'\\x03\\x0e:-\\x03\\x0e:%\\x03\\x0e:?\\x03\\x0e:=\\x03\\x0e:)\" +\n\t\"\\x03\\x0e:/\\x03\\xcfs'\\x03\\x0d=\\x0f\\x03\\x0d+*\\x03\\x0d99\\x03\\x0d9;\\x03\\x0d9\" +\n\t\"?\\x03\\x0d)\\x0d\\x03\\x0d(%\\x02\\x01\\x18\\x02\\x01(\\x02\\x01\\x1e\\x03\\x0f$!\\x03\" +\n\t\"\\x0f87\\x03\\x0f4\\x0e\\x03\\x0f5\\x1d\\x03\\x06'\\x03\\x03\\x0f\\x08\\x18\\x03\\x0f\" +\n\t\"\\x0d\\x1b\\x03\\x0e2=\\x03\\x0e;\\x08\\x03\\x0e:\\x0b\\x03\\x0e\\x06$\\x03\\x0e\\x0d)\" +\n\t\"\\x03\\x0e\\x16\\x1f\\x03\\x0e\\x16\\x1b\\x03\\x0d$\\x0a\\x03\\x05,\\x1d\\x03\\x0d. \\x03\" +\n\t\"\\x0d.#\\x03\\x0c(/\\x03\\x09%\\x02\\x03\\x0d90\\x03\\x0d\\x0e4\\x03\\x0d\\x0d\\x0f\\x03\" +\n\t\"\\x0c#\\x00\\x03\\x0c,\\x1e\\x03\\x0c2\\x0e\\x03\\x0c\\x01\\x17\\x03\\x0c\\x09:\\x03\\x0e\" +\n\t\"\\x173\\x03\\x0c\\x08\\x03\\x03\\x0c\\x11\\x07\\x03\\x0c\\x10\\x18\\x03\\x0c\\x1f\\x1c\" +\n\t\"\\x03\\x0c\\x19\\x0e\\x03\\x0c\\x1a\\x1f\\x03\\x0f0>\\x03\\x0b->\\x03\\x0b<+\\x03\\x0b8\" +\n\t\"\\x13\\x03\\x0b\\x043\\x03\\x0b\\x14\\x03\\x03\\x0b\\x16%\\x03\\x0d\\x22&\\x03\\x0b\\x1a\" +\n\t\"\\x1a\\x03\\x0b\\x1a\\x04\\x03\\x0a%9\\x03\\x0a&2\\x03\\x0a&0\\x03\\x0a!\\x1a\\x03\\x0a!\" +\n\t\"7\\x03\\x0a5\\x10\\x03\\x0a=4\\x03\\x0a?\\x0e\\x03\\x0a>\\x10\\x03\\x0a\\x00 \\x03\\x0a\" +\n\t\"\\x0f:\\x03\\x0a\\x0f9\\x03\\x0a\\x0b\\x0a\\x03\\x0a\\x17%\\x03\\x0a\\x1b-\\x03\\x09-\" +\n\t\"\\x1a\\x03\\x09,4\\x03\\x09.,\\x03\\x09)\\x09\\x03\\x096!\\x03\\x091\\x1f\\x03\\x093\" +\n\t\"\\x16\\x03\\x0c+\\x1f\\x03\\x098 \\x03\\x098=\\x03\\x0c(\\x1a\\x03\\x0c(\\x16\\x03\\x09\" +\n\t\"\\x0a+\\x03\\x09\\x16\\x12\\x03\\x09\\x13\\x0e\\x03\\x09\\x153\\x03\\x08)!\\x03\\x09\\x1a\" +\n\t\"\\x01\\x03\\x09\\x18\\x01\\x03\\x08%#\\x03\\x08>\\x22\\x03\\x08\\x05%\\x03\\x08\\x02*\" +\n\t\"\\x03\\x08\\x15;\\x03\\x08\\x1b7\\x03\\x0f\\x07\\x1d\\x03\\x0f\\x04\\x03\\x03\\x070\\x0c\" +\n\t\"\\x03\\x07;\\x0b\\x03\\x07\\x08\\x17\\x03\\x07\\x12\\x06\\x03\\x06/-\\x03\\x0671\\x03\" +\n\t\"\\x065+\\x03\\x06>7\\x03\\x06\\x049\\x03\\x05+\\x1e\\x03\\x05,\\x17\\x03\\x05 \\x1d\\x03\" +\n\t\"\\x05\\x22\\x05\\x03\\x050\\x1d\"\n\n// lookup returns the trie value for the first UTF-8 encoding in s and\n// the width in bytes of this encoding. The size will be 0 if s does not\n// hold enough bytes to complete the encoding. len(s) must be greater than 0.\nfunc (t *idnaTrie) lookup(s []byte) (v uint16, sz int) {\n\tc0 := s[0]\n\tswitch {\n\tcase c0 < 0x80: // is ASCII\n\t\treturn idnaValues[c0], 1\n\tcase c0 < 0xC2:\n\t\treturn 0, 1 // Illegal UTF-8: not a starter, not ASCII.\n\tcase c0 < 0xE0: // 2-byte UTF-8\n\t\tif len(s) < 2 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c1), 2\n\tcase c0 < 0xF0: // 3-byte UTF-8\n\t\tif len(s) < 3 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c2), 3\n\tcase c0 < 0xF8: // 4-byte UTF-8\n\t\tif len(s) < 4 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to = uint32(i)<<6 + uint32(c2)\n\t\ti = idnaIndex[o]\n\t\tc3 := s[3]\n\t\tif c3 < 0x80 || 0xC0 <= c3 {\n\t\t\treturn 0, 3 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c3), 4\n\t}\n\t// Illegal rune\n\treturn 0, 1\n}\n\n// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.\n// s must start with a full and valid UTF-8 encoded rune.\nfunc (t *idnaTrie) lookupUnsafe(s []byte) uint16 {\n\tc0 := s[0]\n\tif c0 < 0x80 { // is ASCII\n\t\treturn idnaValues[c0]\n\t}\n\ti := idnaIndex[c0]\n\tif c0 < 0xE0 { // 2-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[1])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[1])]\n\tif c0 < 0xF0 { // 3-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[2])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[2])]\n\tif c0 < 0xF8 { // 4-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[3])\n\t}\n\treturn 0\n}\n\n// lookupString returns the trie value for the first UTF-8 encoding in s and\n// the width in bytes of this encoding. The size will be 0 if s does not\n// hold enough bytes to complete the encoding. len(s) must be greater than 0.\nfunc (t *idnaTrie) lookupString(s string) (v uint16, sz int) {\n\tc0 := s[0]\n\tswitch {\n\tcase c0 < 0x80: // is ASCII\n\t\treturn idnaValues[c0], 1\n\tcase c0 < 0xC2:\n\t\treturn 0, 1 // Illegal UTF-8: not a starter, not ASCII.\n\tcase c0 < 0xE0: // 2-byte UTF-8\n\t\tif len(s) < 2 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c1), 2\n\tcase c0 < 0xF0: // 3-byte UTF-8\n\t\tif len(s) < 3 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c2), 3\n\tcase c0 < 0xF8: // 4-byte UTF-8\n\t\tif len(s) < 4 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to = uint32(i)<<6 + uint32(c2)\n\t\ti = idnaIndex[o]\n\t\tc3 := s[3]\n\t\tif c3 < 0x80 || 0xC0 <= c3 {\n\t\t\treturn 0, 3 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c3), 4\n\t}\n\t// Illegal rune\n\treturn 0, 1\n}\n\n// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.\n// s must start with a full and valid UTF-8 encoded rune.\nfunc (t *idnaTrie) lookupStringUnsafe(s string) uint16 {\n\tc0 := s[0]\n\tif c0 < 0x80 { // is ASCII\n\t\treturn idnaValues[c0]\n\t}\n\ti := idnaIndex[c0]\n\tif c0 < 0xE0 { // 2-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[1])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[1])]\n\tif c0 < 0xF0 { // 3-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[2])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[2])]\n\tif c0 < 0xF8 { // 4-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[3])\n\t}\n\treturn 0\n}\n\n// idnaTrie. Total size: 30196 bytes (29.49 KiB). Checksum: e2ae95a945f04016.\ntype idnaTrie struct{}\n\nfunc newIdnaTrie(i int) *idnaTrie {\n\treturn &idnaTrie{}\n}\n\n// lookupValue determines the type of block n and looks up the value for b.\nfunc (t *idnaTrie) lookupValue(n uint32, b byte) uint16 {\n\tswitch {\n\tcase n < 126:\n\t\treturn uint16(idnaValues[n<<6+uint32(b)])\n\tdefault:\n\t\tn -= 126\n\t\treturn uint16(idnaSparse.lookup(n, b))\n\t}\n}\n\n// idnaValues: 128 blocks, 8192 entries, 16384 bytes\n// The third block is the zero block.\nvar idnaValues = [8192]uint16{\n\t// Block 0x0, offset 0x0\n\t0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080,\n\t0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080,\n\t0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080,\n\t0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080,\n\t0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080,\n\t0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080,\n\t0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080,\n\t0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080,\n\t0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008,\n\t0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080,\n\t0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080,\n\t// Block 0x1, offset 0x40\n\t0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105,\n\t0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105,\n\t0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105,\n\t0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105,\n\t0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080,\n\t0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008,\n\t0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008,\n\t0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008,\n\t0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008,\n\t0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080,\n\t0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080,\n\t// Block 0x2, offset 0x80\n\t// Block 0x3, offset 0xc0\n\t0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040,\n\t0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040,\n\t0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040,\n\t0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040,\n\t0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040,\n\t0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018,\n\t0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x0012, 0xe9: 0x0018,\n\t0xea: 0x0019, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x0022,\n\t0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0029, 0xf3: 0x0031, 0xf4: 0x003a, 0xf5: 0x0005,\n\t0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x0042, 0xf9: 0x0049, 0xfa: 0x0051, 0xfb: 0x0018,\n\t0xfc: 0x0059, 0xfd: 0x0061, 0xfe: 0x0069, 0xff: 0x0018,\n\t// Block 0x4, offset 0x100\n\t0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008,\n\t0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008,\n\t0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008,\n\t0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008,\n\t0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008,\n\t0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008,\n\t0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008,\n\t0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008,\n\t0x130: 0x0071, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008,\n\t0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d,\n\t0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0079,\n\t// Block 0x5, offset 0x140\n\t0x140: 0x0079, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d,\n\t0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x0081, 0x14a: 0xe00d, 0x14b: 0x0008,\n\t0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008,\n\t0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008,\n\t0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008,\n\t0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008,\n\t0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008,\n\t0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008,\n\t0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008,\n\t0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d,\n\t0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x0089,\n\t// Block 0x6, offset 0x180\n\t0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008,\n\t0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d,\n\t0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d,\n\t0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d,\n\t0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155,\n\t0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008,\n\t0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d,\n\t0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd,\n\t0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d,\n\t0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008,\n\t0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008,\n\t// Block 0x7, offset 0x1c0\n\t0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x0091, 0x1c5: 0x0091,\n\t0x1c6: 0x0091, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d,\n\t0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d,\n\t0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d,\n\t0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008,\n\t0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008,\n\t0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008,\n\t0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008,\n\t0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008,\n\t0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008,\n\t0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008,\n\t// Block 0x8, offset 0x200\n\t0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008,\n\t0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008,\n\t0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008,\n\t0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008,\n\t0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008,\n\t0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008,\n\t0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008,\n\t0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008,\n\t0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008,\n\t0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0099, 0x23b: 0xe03d,\n\t0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x00a1, 0x23f: 0x0008,\n\t// Block 0x9, offset 0x240\n\t0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018,\n\t0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008,\n\t0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008,\n\t0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018,\n\t0x258: 0x00d2, 0x259: 0x00da, 0x25a: 0x00e2, 0x25b: 0x00ea, 0x25c: 0x00f2, 0x25d: 0x00fa,\n\t0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0101, 0x262: 0x0089, 0x263: 0x0109,\n\t0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018,\n\t0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018,\n\t0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018,\n\t0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018,\n\t0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018,\n\t// Block 0xa, offset 0x280\n\t0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0111, 0x285: 0x040d,\n\t0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308,\n\t0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308,\n\t0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308,\n\t0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308,\n\t0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308,\n\t0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308,\n\t0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308,\n\t0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008,\n\t0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x011a, 0x2bb: 0x0008,\n\t0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x0122, 0x2bf: 0x043d,\n\t// Block 0xb, offset 0x2c0\n\t0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x003a, 0x2c5: 0x012a,\n\t0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040,\n\t0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105,\n\t0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105,\n\t0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105,\n\t0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d,\n\t0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d,\n\t0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008,\n\t0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008,\n\t0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008,\n\t0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008,\n\t// Block 0xc, offset 0x300\n\t0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008,\n\t0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008,\n\t0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd,\n\t0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008,\n\t0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008,\n\t0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008,\n\t0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008,\n\t0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008,\n\t0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd,\n\t0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008,\n\t0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d,\n\t// Block 0xd, offset 0x340\n\t0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008,\n\t0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008,\n\t0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008,\n\t0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008,\n\t0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008,\n\t0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008,\n\t0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008,\n\t0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008,\n\t0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008,\n\t0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008,\n\t0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008,\n\t// Block 0xe, offset 0x380\n\t0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308,\n\t0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008,\n\t0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008,\n\t0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008,\n\t0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008,\n\t0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008,\n\t0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008,\n\t0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008,\n\t0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008,\n\t0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008,\n\t0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008,\n\t// Block 0xf, offset 0x3c0\n\t0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d,\n\t0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d,\n\t0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008,\n\t0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008,\n\t0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008,\n\t0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008,\n\t0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008,\n\t0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008,\n\t0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008,\n\t0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008,\n\t0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008,\n\t// Block 0x10, offset 0x400\n\t0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008,\n\t0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008,\n\t0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008,\n\t0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008,\n\t0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008,\n\t0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008,\n\t0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008,\n\t0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008,\n\t0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5,\n\t0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5,\n\t0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5,\n\t// Block 0x11, offset 0x440\n\t0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840,\n\t0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818,\n\t0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308,\n\t0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308,\n\t0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040,\n\t0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08,\n\t0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08,\n\t0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08,\n\t0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08,\n\t0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08,\n\t0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08,\n\t// Block 0x12, offset 0x480\n\t0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08,\n\t0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308,\n\t0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308,\n\t0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308,\n\t0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308,\n\t0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808,\n\t0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808,\n\t0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08,\n\t0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0139,\n\t0x4b6: 0x0141, 0x4b7: 0x0149, 0x4b8: 0x0151, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08,\n\t0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08,\n\t// Block 0x13, offset 0x4c0\n\t0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08,\n\t0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08,\n\t0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08,\n\t0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308,\n\t0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840,\n\t0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308,\n\t0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018,\n\t0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08,\n\t0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008,\n\t0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08,\n\t0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08,\n\t// Block 0x14, offset 0x500\n\t0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818,\n\t0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818,\n\t0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308,\n\t0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08,\n\t0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08,\n\t0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08,\n\t0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08,\n\t0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08,\n\t0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308,\n\t0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308,\n\t0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308,\n\t// Block 0x15, offset 0x540\n\t0x540: 0x0c08, 0x541: 0x0a08, 0x542: 0x0a08, 0x543: 0x0a08, 0x544: 0x0a08, 0x545: 0x0a08,\n\t0x546: 0x0c08, 0x547: 0x0c08, 0x548: 0x0a08, 0x549: 0x0c08, 0x54a: 0x0a08, 0x54b: 0x0a08,\n\t0x54c: 0x0a08, 0x54d: 0x0a08, 0x54e: 0x0a08, 0x54f: 0x0a08, 0x550: 0x0a08, 0x551: 0x0a08,\n\t0x552: 0x0a08, 0x553: 0x0a08, 0x554: 0x0c08, 0x555: 0x0a08, 0x556: 0x0c08, 0x557: 0x0c08,\n\t0x558: 0x0c08, 0x559: 0x3308, 0x55a: 0x3308, 0x55b: 0x3308, 0x55c: 0x0040, 0x55d: 0x0040,\n\t0x55e: 0x0818, 0x55f: 0x0040, 0x560: 0x0a08, 0x561: 0x0808, 0x562: 0x0a08, 0x563: 0x0a08,\n\t0x564: 0x0a08, 0x565: 0x0a08, 0x566: 0x0808, 0x567: 0x0c08, 0x568: 0x0a08, 0x569: 0x0c08,\n\t0x56a: 0x0c08, 0x56b: 0x0040, 0x56c: 0x0040, 0x56d: 0x0040, 0x56e: 0x0040, 0x56f: 0x0040,\n\t0x570: 0x0040, 0x571: 0x0040, 0x572: 0x0040, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040,\n\t0x576: 0x0040, 0x577: 0x0040, 0x578: 0x0040, 0x579: 0x0040, 0x57a: 0x0040, 0x57b: 0x0040,\n\t0x57c: 0x0040, 0x57d: 0x0040, 0x57e: 0x0040, 0x57f: 0x0040,\n\t// Block 0x16, offset 0x580\n\t0x580: 0x3008, 0x581: 0x3308, 0x582: 0x3308, 0x583: 0x3308, 0x584: 0x3308, 0x585: 0x3308,\n\t0x586: 0x3308, 0x587: 0x3308, 0x588: 0x3308, 0x589: 0x3008, 0x58a: 0x3008, 0x58b: 0x3008,\n\t0x58c: 0x3008, 0x58d: 0x3b08, 0x58e: 0x3008, 0x58f: 0x3008, 0x590: 0x0008, 0x591: 0x3308,\n\t0x592: 0x3308, 0x593: 0x3308, 0x594: 0x3308, 0x595: 0x3308, 0x596: 0x3308, 0x597: 0x3308,\n\t0x598: 0x0159, 0x599: 0x0161, 0x59a: 0x0169, 0x59b: 0x0171, 0x59c: 0x0179, 0x59d: 0x0181,\n\t0x59e: 0x0189, 0x59f: 0x0191, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x3308, 0x5a3: 0x3308,\n\t0x5a4: 0x0018, 0x5a5: 0x0018, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008,\n\t0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008,\n\t0x5b0: 0x0018, 0x5b1: 0x0008, 0x5b2: 0x0008, 0x5b3: 0x0008, 0x5b4: 0x0008, 0x5b5: 0x0008,\n\t0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0008, 0x5bb: 0x0008,\n\t0x5bc: 0x0008, 0x5bd: 0x0008, 0x5be: 0x0008, 0x5bf: 0x0008,\n\t// Block 0x17, offset 0x5c0\n\t0x5c0: 0x0008, 0x5c1: 0x3308, 0x5c2: 0x3008, 0x5c3: 0x3008, 0x5c4: 0x0040, 0x5c5: 0x0008,\n\t0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0008,\n\t0x5cc: 0x0008, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040,\n\t0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008,\n\t0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008,\n\t0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008,\n\t0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040,\n\t0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008,\n\t0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0040, 0x5f4: 0x0040, 0x5f5: 0x0040,\n\t0x5f6: 0x0008, 0x5f7: 0x0008, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040,\n\t0x5fc: 0x3308, 0x5fd: 0x0008, 0x5fe: 0x3008, 0x5ff: 0x3008,\n\t// Block 0x18, offset 0x600\n\t0x600: 0x3008, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3308, 0x604: 0x3308, 0x605: 0x0040,\n\t0x606: 0x0040, 0x607: 0x3008, 0x608: 0x3008, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x3008,\n\t0x60c: 0x3008, 0x60d: 0x3b08, 0x60e: 0x0008, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x0040,\n\t0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x3008,\n\t0x618: 0x0040, 0x619: 0x0040, 0x61a: 0x0040, 0x61b: 0x0040, 0x61c: 0x0199, 0x61d: 0x01a1,\n\t0x61e: 0x0040, 0x61f: 0x01a9, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x3308, 0x623: 0x3308,\n\t0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008,\n\t0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008,\n\t0x630: 0x0008, 0x631: 0x0008, 0x632: 0x0018, 0x633: 0x0018, 0x634: 0x0018, 0x635: 0x0018,\n\t0x636: 0x0018, 0x637: 0x0018, 0x638: 0x0018, 0x639: 0x0018, 0x63a: 0x0018, 0x63b: 0x0018,\n\t0x63c: 0x0008, 0x63d: 0x0018, 0x63e: 0x3308, 0x63f: 0x0040,\n\t// Block 0x19, offset 0x640\n\t0x640: 0x0040, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x3008, 0x644: 0x0040, 0x645: 0x0008,\n\t0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0040,\n\t0x64c: 0x0040, 0x64d: 0x0040, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0040,\n\t0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008,\n\t0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008,\n\t0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008,\n\t0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040,\n\t0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008,\n\t0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x01b1, 0x674: 0x0040, 0x675: 0x0008,\n\t0x676: 0x01b9, 0x677: 0x0040, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040,\n\t0x67c: 0x3308, 0x67d: 0x0040, 0x67e: 0x3008, 0x67f: 0x3008,\n\t// Block 0x1a, offset 0x680\n\t0x680: 0x3008, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x0040, 0x684: 0x0040, 0x685: 0x0040,\n\t0x686: 0x0040, 0x687: 0x3308, 0x688: 0x3308, 0x689: 0x0040, 0x68a: 0x0040, 0x68b: 0x3308,\n\t0x68c: 0x3308, 0x68d: 0x3b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0040, 0x691: 0x3308,\n\t0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040,\n\t0x698: 0x0040, 0x699: 0x01c1, 0x69a: 0x01c9, 0x69b: 0x01d1, 0x69c: 0x0008, 0x69d: 0x0040,\n\t0x69e: 0x01d9, 0x69f: 0x0040, 0x6a0: 0x0040, 0x6a1: 0x0040, 0x6a2: 0x0040, 0x6a3: 0x0040,\n\t0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008,\n\t0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008,\n\t0x6b0: 0x3308, 0x6b1: 0x3308, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0008, 0x6b5: 0x3308,\n\t0x6b6: 0x0018, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0040, 0x6ba: 0x0040, 0x6bb: 0x0040,\n\t0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040,\n\t// Block 0x1b, offset 0x6c0\n\t0x6c0: 0x0040, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3008, 0x6c4: 0x0040, 0x6c5: 0x0008,\n\t0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008,\n\t0x6cc: 0x0008, 0x6cd: 0x0008, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0008,\n\t0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008,\n\t0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008,\n\t0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008,\n\t0x6e4: 0x0008, 0x6e5: 0x0008, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0040,\n\t0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008,\n\t0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008,\n\t0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040,\n\t0x6fc: 0x3308, 0x6fd: 0x0008, 0x6fe: 0x3008, 0x6ff: 0x3008,\n\t// Block 0x1c, offset 0x700\n\t0x700: 0x3008, 0x701: 0x3308, 0x702: 0x3308, 0x703: 0x3308, 0x704: 0x3308, 0x705: 0x3308,\n\t0x706: 0x0040, 0x707: 0x3308, 0x708: 0x3308, 0x709: 0x3008, 0x70a: 0x0040, 0x70b: 0x3008,\n\t0x70c: 0x3008, 0x70d: 0x3b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0008, 0x711: 0x0040,\n\t0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x0040, 0x717: 0x0040,\n\t0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0040, 0x71d: 0x0040,\n\t0x71e: 0x0040, 0x71f: 0x0040, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x3308, 0x723: 0x3308,\n\t0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008,\n\t0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008,\n\t0x730: 0x0018, 0x731: 0x0018, 0x732: 0x0040, 0x733: 0x0040, 0x734: 0x0040, 0x735: 0x0040,\n\t0x736: 0x0040, 0x737: 0x0040, 0x738: 0x0040, 0x739: 0x0008, 0x73a: 0x3308, 0x73b: 0x3308,\n\t0x73c: 0x3308, 0x73d: 0x3308, 0x73e: 0x3308, 0x73f: 0x3308,\n\t// Block 0x1d, offset 0x740\n\t0x740: 0x0040, 0x741: 0x3308, 0x742: 0x3008, 0x743: 0x3008, 0x744: 0x0040, 0x745: 0x0008,\n\t0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0008,\n\t0x74c: 0x0008, 0x74d: 0x0040, 0x74e: 0x0040, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040,\n\t0x752: 0x0040, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0008, 0x757: 0x0008,\n\t0x758: 0x0008, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0008, 0x75c: 0x0008, 0x75d: 0x0008,\n\t0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x0008, 0x763: 0x0008,\n\t0x764: 0x0008, 0x765: 0x0008, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0040,\n\t0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008,\n\t0x770: 0x0008, 0x771: 0x0040, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0040, 0x775: 0x0008,\n\t0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040,\n\t0x77c: 0x3308, 0x77d: 0x0008, 0x77e: 0x3008, 0x77f: 0x3308,\n\t// Block 0x1e, offset 0x780\n\t0x780: 0x3008, 0x781: 0x3308, 0x782: 0x3308, 0x783: 0x3308, 0x784: 0x3308, 0x785: 0x0040,\n\t0x786: 0x0040, 0x787: 0x3008, 0x788: 0x3008, 0x789: 0x0040, 0x78a: 0x0040, 0x78b: 0x3008,\n\t0x78c: 0x3008, 0x78d: 0x3b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040,\n\t0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x3308, 0x796: 0x3308, 0x797: 0x3008,\n\t0x798: 0x0040, 0x799: 0x0040, 0x79a: 0x0040, 0x79b: 0x0040, 0x79c: 0x01e1, 0x79d: 0x01e9,\n\t0x79e: 0x0040, 0x79f: 0x0008, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x3308, 0x7a3: 0x3308,\n\t0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008,\n\t0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008,\n\t0x7b0: 0x0018, 0x7b1: 0x0008, 0x7b2: 0x0018, 0x7b3: 0x0018, 0x7b4: 0x0018, 0x7b5: 0x0018,\n\t0x7b6: 0x0018, 0x7b7: 0x0018, 0x7b8: 0x0040, 0x7b9: 0x0040, 0x7ba: 0x0040, 0x7bb: 0x0040,\n\t0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x0040, 0x7bf: 0x0040,\n\t// Block 0x1f, offset 0x7c0\n\t0x7c0: 0x0040, 0x7c1: 0x0040, 0x7c2: 0x3308, 0x7c3: 0x0008, 0x7c4: 0x0040, 0x7c5: 0x0008,\n\t0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0040,\n\t0x7cc: 0x0040, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040,\n\t0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0040, 0x7d7: 0x0040,\n\t0x7d8: 0x0040, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0008, 0x7dd: 0x0040,\n\t0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0040, 0x7e1: 0x0040, 0x7e2: 0x0040, 0x7e3: 0x0008,\n\t0x7e4: 0x0008, 0x7e5: 0x0040, 0x7e6: 0x0040, 0x7e7: 0x0040, 0x7e8: 0x0008, 0x7e9: 0x0008,\n\t0x7ea: 0x0008, 0x7eb: 0x0040, 0x7ec: 0x0040, 0x7ed: 0x0040, 0x7ee: 0x0008, 0x7ef: 0x0008,\n\t0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0008, 0x7f5: 0x0008,\n\t0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040,\n\t0x7fc: 0x0040, 0x7fd: 0x0040, 0x7fe: 0x3008, 0x7ff: 0x3008,\n\t// Block 0x20, offset 0x800\n\t0x800: 0x3308, 0x801: 0x3008, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x3008, 0x805: 0x0040,\n\t0x806: 0x3308, 0x807: 0x3308, 0x808: 0x3308, 0x809: 0x0040, 0x80a: 0x3308, 0x80b: 0x3308,\n\t0x80c: 0x3308, 0x80d: 0x3b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040,\n\t0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x3308, 0x816: 0x3308, 0x817: 0x0040,\n\t0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040,\n\t0x81e: 0x0040, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x3308, 0x823: 0x3308,\n\t0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008,\n\t0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008,\n\t0x830: 0x0040, 0x831: 0x0040, 0x832: 0x0040, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040,\n\t0x836: 0x0040, 0x837: 0x0018, 0x838: 0x0018, 0x839: 0x0018, 0x83a: 0x0018, 0x83b: 0x0018,\n\t0x83c: 0x0018, 0x83d: 0x0018, 0x83e: 0x0018, 0x83f: 0x0018,\n\t// Block 0x21, offset 0x840\n\t0x840: 0x0008, 0x841: 0x3308, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x0018, 0x845: 0x0008,\n\t0x846: 0x0008, 0x847: 0x0008, 0x848: 0x0008, 0x849: 0x0008, 0x84a: 0x0008, 0x84b: 0x0008,\n\t0x84c: 0x0008, 0x84d: 0x0040, 0x84e: 0x0008, 0x84f: 0x0008, 0x850: 0x0008, 0x851: 0x0040,\n\t0x852: 0x0008, 0x853: 0x0008, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x0008,\n\t0x858: 0x0008, 0x859: 0x0008, 0x85a: 0x0008, 0x85b: 0x0008, 0x85c: 0x0008, 0x85d: 0x0008,\n\t0x85e: 0x0008, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x0008, 0x863: 0x0008,\n\t0x864: 0x0008, 0x865: 0x0008, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0040,\n\t0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008,\n\t0x870: 0x0008, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0008, 0x874: 0x0040, 0x875: 0x0008,\n\t0x876: 0x0008, 0x877: 0x0008, 0x878: 0x0008, 0x879: 0x0008, 0x87a: 0x0040, 0x87b: 0x0040,\n\t0x87c: 0x3308, 0x87d: 0x0008, 0x87e: 0x3008, 0x87f: 0x3308,\n\t// Block 0x22, offset 0x880\n\t0x880: 0x3008, 0x881: 0x3008, 0x882: 0x3008, 0x883: 0x3008, 0x884: 0x3008, 0x885: 0x0040,\n\t0x886: 0x3308, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008,\n\t0x88c: 0x3308, 0x88d: 0x3b08, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040,\n\t0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0040, 0x895: 0x3008, 0x896: 0x3008, 0x897: 0x0040,\n\t0x898: 0x0040, 0x899: 0x0040, 0x89a: 0x0040, 0x89b: 0x0040, 0x89c: 0x0040, 0x89d: 0x0040,\n\t0x89e: 0x0008, 0x89f: 0x0040, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308,\n\t0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008,\n\t0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008,\n\t0x8b0: 0x0040, 0x8b1: 0x0008, 0x8b2: 0x0008, 0x8b3: 0x0040, 0x8b4: 0x0040, 0x8b5: 0x0040,\n\t0x8b6: 0x0040, 0x8b7: 0x0040, 0x8b8: 0x0040, 0x8b9: 0x0040, 0x8ba: 0x0040, 0x8bb: 0x0040,\n\t0x8bc: 0x0040, 0x8bd: 0x0040, 0x8be: 0x0040, 0x8bf: 0x0040,\n\t// Block 0x23, offset 0x8c0\n\t0x8c0: 0x3008, 0x8c1: 0x3308, 0x8c2: 0x3308, 0x8c3: 0x3308, 0x8c4: 0x3308, 0x8c5: 0x0040,\n\t0x8c6: 0x3008, 0x8c7: 0x3008, 0x8c8: 0x3008, 0x8c9: 0x0040, 0x8ca: 0x3008, 0x8cb: 0x3008,\n\t0x8cc: 0x3008, 0x8cd: 0x3b08, 0x8ce: 0x0008, 0x8cf: 0x0018, 0x8d0: 0x0040, 0x8d1: 0x0040,\n\t0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x3008,\n\t0x8d8: 0x0018, 0x8d9: 0x0018, 0x8da: 0x0018, 0x8db: 0x0018, 0x8dc: 0x0018, 0x8dd: 0x0018,\n\t0x8de: 0x0018, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x3308, 0x8e3: 0x3308,\n\t0x8e4: 0x0040, 0x8e5: 0x0040, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0008,\n\t0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008,\n\t0x8f0: 0x0018, 0x8f1: 0x0018, 0x8f2: 0x0018, 0x8f3: 0x0018, 0x8f4: 0x0018, 0x8f5: 0x0018,\n\t0x8f6: 0x0018, 0x8f7: 0x0018, 0x8f8: 0x0018, 0x8f9: 0x0018, 0x8fa: 0x0008, 0x8fb: 0x0008,\n\t0x8fc: 0x0008, 0x8fd: 0x0008, 0x8fe: 0x0008, 0x8ff: 0x0008,\n\t// Block 0x24, offset 0x900\n\t0x900: 0x0040, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x0040, 0x904: 0x0008, 0x905: 0x0040,\n\t0x906: 0x0008, 0x907: 0x0008, 0x908: 0x0008, 0x909: 0x0008, 0x90a: 0x0008, 0x90b: 0x0040,\n\t0x90c: 0x0008, 0x90d: 0x0008, 0x90e: 0x0008, 0x90f: 0x0008, 0x910: 0x0008, 0x911: 0x0008,\n\t0x912: 0x0008, 0x913: 0x0008, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0008,\n\t0x918: 0x0008, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0008, 0x91d: 0x0008,\n\t0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0008, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008,\n\t0x924: 0x0040, 0x925: 0x0008, 0x926: 0x0040, 0x927: 0x0008, 0x928: 0x0008, 0x929: 0x0008,\n\t0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0008, 0x92d: 0x0008, 0x92e: 0x0008, 0x92f: 0x0008,\n\t0x930: 0x0008, 0x931: 0x3308, 0x932: 0x0008, 0x933: 0x01f9, 0x934: 0x3308, 0x935: 0x3308,\n\t0x936: 0x3308, 0x937: 0x3308, 0x938: 0x3308, 0x939: 0x3308, 0x93a: 0x3b08, 0x93b: 0x3308,\n\t0x93c: 0x3308, 0x93d: 0x0008, 0x93e: 0x0040, 0x93f: 0x0040,\n\t// Block 0x25, offset 0x940\n\t0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x0211, 0x944: 0x0008, 0x945: 0x0008,\n\t0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0040, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008,\n\t0x94c: 0x0008, 0x94d: 0x0219, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008,\n\t0x952: 0x0221, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0229,\n\t0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0231, 0x95d: 0x0008,\n\t0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008,\n\t0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0239,\n\t0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0008, 0x96d: 0x0040, 0x96e: 0x0040, 0x96f: 0x0040,\n\t0x970: 0x0040, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x0241, 0x974: 0x3308, 0x975: 0x0249,\n\t0x976: 0x0251, 0x977: 0x0259, 0x978: 0x0261, 0x979: 0x0269, 0x97a: 0x3308, 0x97b: 0x3308,\n\t0x97c: 0x3308, 0x97d: 0x3308, 0x97e: 0x3308, 0x97f: 0x3008,\n\t// Block 0x26, offset 0x980\n\t0x980: 0x3308, 0x981: 0x0271, 0x982: 0x3308, 0x983: 0x3308, 0x984: 0x3b08, 0x985: 0x0018,\n\t0x986: 0x3308, 0x987: 0x3308, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008,\n\t0x98c: 0x0008, 0x98d: 0x3308, 0x98e: 0x3308, 0x98f: 0x3308, 0x990: 0x3308, 0x991: 0x3308,\n\t0x992: 0x3308, 0x993: 0x0279, 0x994: 0x3308, 0x995: 0x3308, 0x996: 0x3308, 0x997: 0x3308,\n\t0x998: 0x0040, 0x999: 0x3308, 0x99a: 0x3308, 0x99b: 0x3308, 0x99c: 0x3308, 0x99d: 0x0281,\n\t0x99e: 0x3308, 0x99f: 0x3308, 0x9a0: 0x3308, 0x9a1: 0x3308, 0x9a2: 0x0289, 0x9a3: 0x3308,\n\t0x9a4: 0x3308, 0x9a5: 0x3308, 0x9a6: 0x3308, 0x9a7: 0x0291, 0x9a8: 0x3308, 0x9a9: 0x3308,\n\t0x9aa: 0x3308, 0x9ab: 0x3308, 0x9ac: 0x0299, 0x9ad: 0x3308, 0x9ae: 0x3308, 0x9af: 0x3308,\n\t0x9b0: 0x3308, 0x9b1: 0x3308, 0x9b2: 0x3308, 0x9b3: 0x3308, 0x9b4: 0x3308, 0x9b5: 0x3308,\n\t0x9b6: 0x3308, 0x9b7: 0x3308, 0x9b8: 0x3308, 0x9b9: 0x02a1, 0x9ba: 0x3308, 0x9bb: 0x3308,\n\t0x9bc: 0x3308, 0x9bd: 0x0040, 0x9be: 0x0018, 0x9bf: 0x0018,\n\t// Block 0x27, offset 0x9c0\n\t0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008,\n\t0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008,\n\t0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008,\n\t0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008,\n\t0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x0008, 0x9dc: 0x0008, 0x9dd: 0x0008,\n\t0x9de: 0x0008, 0x9df: 0x0008, 0x9e0: 0x0008, 0x9e1: 0x0008, 0x9e2: 0x0008, 0x9e3: 0x0008,\n\t0x9e4: 0x0008, 0x9e5: 0x0008, 0x9e6: 0x0008, 0x9e7: 0x0008, 0x9e8: 0x0008, 0x9e9: 0x0008,\n\t0x9ea: 0x0008, 0x9eb: 0x0008, 0x9ec: 0x0019, 0x9ed: 0x02e1, 0x9ee: 0x02e9, 0x9ef: 0x0008,\n\t0x9f0: 0x02f1, 0x9f1: 0x02f9, 0x9f2: 0x0301, 0x9f3: 0x0309, 0x9f4: 0x00a9, 0x9f5: 0x0311,\n\t0x9f6: 0x00b1, 0x9f7: 0x0319, 0x9f8: 0x0101, 0x9f9: 0x0321, 0x9fa: 0x0329, 0x9fb: 0x0008,\n\t0x9fc: 0x0051, 0x9fd: 0x0331, 0x9fe: 0x0339, 0x9ff: 0x00b9,\n\t// Block 0x28, offset 0xa00\n\t0xa00: 0x0341, 0xa01: 0x0349, 0xa02: 0x00c1, 0xa03: 0x0019, 0xa04: 0x0351, 0xa05: 0x0359,\n\t0xa06: 0x05b5, 0xa07: 0x02e9, 0xa08: 0x02f1, 0xa09: 0x02f9, 0xa0a: 0x0361, 0xa0b: 0x0369,\n\t0xa0c: 0x0371, 0xa0d: 0x0309, 0xa0e: 0x0008, 0xa0f: 0x0319, 0xa10: 0x0321, 0xa11: 0x0379,\n\t0xa12: 0x0051, 0xa13: 0x0381, 0xa14: 0x05cd, 0xa15: 0x05cd, 0xa16: 0x0339, 0xa17: 0x0341,\n\t0xa18: 0x0349, 0xa19: 0x05b5, 0xa1a: 0x0389, 0xa1b: 0x0391, 0xa1c: 0x05e5, 0xa1d: 0x0399,\n\t0xa1e: 0x03a1, 0xa1f: 0x03a9, 0xa20: 0x03b1, 0xa21: 0x03b9, 0xa22: 0x0311, 0xa23: 0x00b9,\n\t0xa24: 0x0349, 0xa25: 0x0391, 0xa26: 0x0399, 0xa27: 0x03a1, 0xa28: 0x03c1, 0xa29: 0x03b1,\n\t0xa2a: 0x03b9, 0xa2b: 0x0008, 0xa2c: 0x0008, 0xa2d: 0x0008, 0xa2e: 0x0008, 0xa2f: 0x0008,\n\t0xa30: 0x0008, 0xa31: 0x0008, 0xa32: 0x0008, 0xa33: 0x0008, 0xa34: 0x0008, 0xa35: 0x0008,\n\t0xa36: 0x0008, 0xa37: 0x0008, 0xa38: 0x03c9, 0xa39: 0x0008, 0xa3a: 0x0008, 0xa3b: 0x0008,\n\t0xa3c: 0x0008, 0xa3d: 0x0008, 0xa3e: 0x0008, 0xa3f: 0x0008,\n\t// Block 0x29, offset 0xa40\n\t0xa40: 0x0008, 0xa41: 0x0008, 0xa42: 0x0008, 0xa43: 0x0008, 0xa44: 0x0008, 0xa45: 0x0008,\n\t0xa46: 0x0008, 0xa47: 0x0008, 0xa48: 0x0008, 0xa49: 0x0008, 0xa4a: 0x0008, 0xa4b: 0x0008,\n\t0xa4c: 0x0008, 0xa4d: 0x0008, 0xa4e: 0x0008, 0xa4f: 0x0008, 0xa50: 0x0008, 0xa51: 0x0008,\n\t0xa52: 0x0008, 0xa53: 0x0008, 0xa54: 0x0008, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008,\n\t0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0008, 0xa5b: 0x03d1, 0xa5c: 0x03d9, 0xa5d: 0x03e1,\n\t0xa5e: 0x03e9, 0xa5f: 0x0371, 0xa60: 0x03f1, 0xa61: 0x03f9, 0xa62: 0x0401, 0xa63: 0x0409,\n\t0xa64: 0x0411, 0xa65: 0x0419, 0xa66: 0x0421, 0xa67: 0x05fd, 0xa68: 0x0429, 0xa69: 0x0431,\n\t0xa6a: 0xe17d, 0xa6b: 0x0439, 0xa6c: 0x0441, 0xa6d: 0x0449, 0xa6e: 0x0451, 0xa6f: 0x0459,\n\t0xa70: 0x0461, 0xa71: 0x0469, 0xa72: 0x0471, 0xa73: 0x0479, 0xa74: 0x0481, 0xa75: 0x0489,\n\t0xa76: 0x0491, 0xa77: 0x0499, 0xa78: 0x0615, 0xa79: 0x04a1, 0xa7a: 0x04a9, 0xa7b: 0x04b1,\n\t0xa7c: 0x04b9, 0xa7d: 0x04c1, 0xa7e: 0x04c9, 0xa7f: 0x04d1,\n\t// Block 0x2a, offset 0xa80\n\t0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008,\n\t0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008,\n\t0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008,\n\t0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0xe00d, 0xa97: 0x0008,\n\t0xa98: 0xe00d, 0xa99: 0x0008, 0xa9a: 0xe00d, 0xa9b: 0x0008, 0xa9c: 0xe00d, 0xa9d: 0x0008,\n\t0xa9e: 0xe00d, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008,\n\t0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008,\n\t0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008,\n\t0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008,\n\t0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008,\n\t0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008,\n\t// Block 0x2b, offset 0xac0\n\t0xac0: 0xe00d, 0xac1: 0x0008, 0xac2: 0xe00d, 0xac3: 0x0008, 0xac4: 0xe00d, 0xac5: 0x0008,\n\t0xac6: 0xe00d, 0xac7: 0x0008, 0xac8: 0xe00d, 0xac9: 0x0008, 0xaca: 0xe00d, 0xacb: 0x0008,\n\t0xacc: 0xe00d, 0xacd: 0x0008, 0xace: 0xe00d, 0xacf: 0x0008, 0xad0: 0xe00d, 0xad1: 0x0008,\n\t0xad2: 0xe00d, 0xad3: 0x0008, 0xad4: 0xe00d, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008,\n\t0xad8: 0x0008, 0xad9: 0x0008, 0xada: 0x062d, 0xadb: 0x064d, 0xadc: 0x0008, 0xadd: 0x0008,\n\t0xade: 0x04d9, 0xadf: 0x0008, 0xae0: 0xe00d, 0xae1: 0x0008, 0xae2: 0xe00d, 0xae3: 0x0008,\n\t0xae4: 0xe00d, 0xae5: 0x0008, 0xae6: 0xe00d, 0xae7: 0x0008, 0xae8: 0xe00d, 0xae9: 0x0008,\n\t0xaea: 0xe00d, 0xaeb: 0x0008, 0xaec: 0xe00d, 0xaed: 0x0008, 0xaee: 0xe00d, 0xaef: 0x0008,\n\t0xaf0: 0xe00d, 0xaf1: 0x0008, 0xaf2: 0xe00d, 0xaf3: 0x0008, 0xaf4: 0xe00d, 0xaf5: 0x0008,\n\t0xaf6: 0xe00d, 0xaf7: 0x0008, 0xaf8: 0xe00d, 0xaf9: 0x0008, 0xafa: 0xe00d, 0xafb: 0x0008,\n\t0xafc: 0xe00d, 0xafd: 0x0008, 0xafe: 0xe00d, 0xaff: 0x0008,\n\t// Block 0x2c, offset 0xb00\n\t0xb00: 0x0008, 0xb01: 0x0008, 0xb02: 0x0008, 0xb03: 0x0008, 0xb04: 0x0008, 0xb05: 0x0008,\n\t0xb06: 0x0040, 0xb07: 0x0040, 0xb08: 0xe045, 0xb09: 0xe045, 0xb0a: 0xe045, 0xb0b: 0xe045,\n\t0xb0c: 0xe045, 0xb0d: 0xe045, 0xb0e: 0x0040, 0xb0f: 0x0040, 0xb10: 0x0008, 0xb11: 0x0008,\n\t0xb12: 0x0008, 0xb13: 0x0008, 0xb14: 0x0008, 0xb15: 0x0008, 0xb16: 0x0008, 0xb17: 0x0008,\n\t0xb18: 0x0040, 0xb19: 0xe045, 0xb1a: 0x0040, 0xb1b: 0xe045, 0xb1c: 0x0040, 0xb1d: 0xe045,\n\t0xb1e: 0x0040, 0xb1f: 0xe045, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x0008,\n\t0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045,\n\t0xb2a: 0xe045, 0xb2b: 0xe045, 0xb2c: 0xe045, 0xb2d: 0xe045, 0xb2e: 0xe045, 0xb2f: 0xe045,\n\t0xb30: 0x0008, 0xb31: 0x04e1, 0xb32: 0x0008, 0xb33: 0x04e9, 0xb34: 0x0008, 0xb35: 0x04f1,\n\t0xb36: 0x0008, 0xb37: 0x04f9, 0xb38: 0x0008, 0xb39: 0x0501, 0xb3a: 0x0008, 0xb3b: 0x0509,\n\t0xb3c: 0x0008, 0xb3d: 0x0511, 0xb3e: 0x0040, 0xb3f: 0x0040,\n\t// Block 0x2d, offset 0xb40\n\t0xb40: 0x0519, 0xb41: 0x0521, 0xb42: 0x0529, 0xb43: 0x0531, 0xb44: 0x0539, 0xb45: 0x0541,\n\t0xb46: 0x0549, 0xb47: 0x0551, 0xb48: 0x0519, 0xb49: 0x0521, 0xb4a: 0x0529, 0xb4b: 0x0531,\n\t0xb4c: 0x0539, 0xb4d: 0x0541, 0xb4e: 0x0549, 0xb4f: 0x0551, 0xb50: 0x0559, 0xb51: 0x0561,\n\t0xb52: 0x0569, 0xb53: 0x0571, 0xb54: 0x0579, 0xb55: 0x0581, 0xb56: 0x0589, 0xb57: 0x0591,\n\t0xb58: 0x0559, 0xb59: 0x0561, 0xb5a: 0x0569, 0xb5b: 0x0571, 0xb5c: 0x0579, 0xb5d: 0x0581,\n\t0xb5e: 0x0589, 0xb5f: 0x0591, 0xb60: 0x0599, 0xb61: 0x05a1, 0xb62: 0x05a9, 0xb63: 0x05b1,\n\t0xb64: 0x05b9, 0xb65: 0x05c1, 0xb66: 0x05c9, 0xb67: 0x05d1, 0xb68: 0x0599, 0xb69: 0x05a1,\n\t0xb6a: 0x05a9, 0xb6b: 0x05b1, 0xb6c: 0x05b9, 0xb6d: 0x05c1, 0xb6e: 0x05c9, 0xb6f: 0x05d1,\n\t0xb70: 0x0008, 0xb71: 0x0008, 0xb72: 0x05d9, 0xb73: 0x05e1, 0xb74: 0x05e9, 0xb75: 0x0040,\n\t0xb76: 0x0008, 0xb77: 0x05f1, 0xb78: 0xe045, 0xb79: 0xe045, 0xb7a: 0x0665, 0xb7b: 0x04e1,\n\t0xb7c: 0x05e1, 0xb7d: 0x067e, 0xb7e: 0x05f9, 0xb7f: 0x069e,\n\t// Block 0x2e, offset 0xb80\n\t0xb80: 0x06be, 0xb81: 0x0602, 0xb82: 0x0609, 0xb83: 0x0611, 0xb84: 0x0619, 0xb85: 0x0040,\n\t0xb86: 0x0008, 0xb87: 0x0621, 0xb88: 0x06dd, 0xb89: 0x04e9, 0xb8a: 0x06f5, 0xb8b: 0x04f1,\n\t0xb8c: 0x0611, 0xb8d: 0x062a, 0xb8e: 0x0632, 0xb8f: 0x063a, 0xb90: 0x0008, 0xb91: 0x0008,\n\t0xb92: 0x0008, 0xb93: 0x0641, 0xb94: 0x0040, 0xb95: 0x0040, 0xb96: 0x0008, 0xb97: 0x0008,\n\t0xb98: 0xe045, 0xb99: 0xe045, 0xb9a: 0x070d, 0xb9b: 0x04f9, 0xb9c: 0x0040, 0xb9d: 0x064a,\n\t0xb9e: 0x0652, 0xb9f: 0x065a, 0xba0: 0x0008, 0xba1: 0x0008, 0xba2: 0x0008, 0xba3: 0x0661,\n\t0xba4: 0x0008, 0xba5: 0x0008, 0xba6: 0x0008, 0xba7: 0x0008, 0xba8: 0xe045, 0xba9: 0xe045,\n\t0xbaa: 0x0725, 0xbab: 0x0509, 0xbac: 0xe04d, 0xbad: 0x066a, 0xbae: 0x012a, 0xbaf: 0x0672,\n\t0xbb0: 0x0040, 0xbb1: 0x0040, 0xbb2: 0x0679, 0xbb3: 0x0681, 0xbb4: 0x0689, 0xbb5: 0x0040,\n\t0xbb6: 0x0008, 0xbb7: 0x0691, 0xbb8: 0x073d, 0xbb9: 0x0501, 0xbba: 0x0515, 0xbbb: 0x0511,\n\t0xbbc: 0x0681, 0xbbd: 0x0756, 0xbbe: 0x0776, 0xbbf: 0x0040,\n\t// Block 0x2f, offset 0xbc0\n\t0xbc0: 0x000a, 0xbc1: 0x000a, 0xbc2: 0x000a, 0xbc3: 0x000a, 0xbc4: 0x000a, 0xbc5: 0x000a,\n\t0xbc6: 0x000a, 0xbc7: 0x000a, 0xbc8: 0x000a, 0xbc9: 0x000a, 0xbca: 0x000a, 0xbcb: 0x03c0,\n\t0xbcc: 0x0003, 0xbcd: 0x0003, 0xbce: 0x0340, 0xbcf: 0x0b40, 0xbd0: 0x0018, 0xbd1: 0xe00d,\n\t0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x0796,\n\t0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018,\n\t0xbde: 0x0018, 0xbdf: 0x0018, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018,\n\t0xbe4: 0x0040, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0018, 0xbe8: 0x0040, 0xbe9: 0x0040,\n\t0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x000a,\n\t0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x0699, 0xbf4: 0x06a1, 0xbf5: 0x0018,\n\t0xbf6: 0x06a9, 0xbf7: 0x06b1, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018,\n\t0xbfc: 0x06ba, 0xbfd: 0x0018, 0xbfe: 0x07b6, 0xbff: 0x0018,\n\t// Block 0x30, offset 0xc00\n\t0xc00: 0x0018, 0xc01: 0x0018, 0xc02: 0x0018, 0xc03: 0x0018, 0xc04: 0x0018, 0xc05: 0x0018,\n\t0xc06: 0x0018, 0xc07: 0x06c2, 0xc08: 0x06ca, 0xc09: 0x06d2, 0xc0a: 0x0018, 0xc0b: 0x0018,\n\t0xc0c: 0x0018, 0xc0d: 0x0018, 0xc0e: 0x0018, 0xc0f: 0x0018, 0xc10: 0x0018, 0xc11: 0x0018,\n\t0xc12: 0x0018, 0xc13: 0x0018, 0xc14: 0x0018, 0xc15: 0x0018, 0xc16: 0x0018, 0xc17: 0x06d9,\n\t0xc18: 0x0018, 0xc19: 0x0018, 0xc1a: 0x0018, 0xc1b: 0x0018, 0xc1c: 0x0018, 0xc1d: 0x0018,\n\t0xc1e: 0x0018, 0xc1f: 0x000a, 0xc20: 0x03c0, 0xc21: 0x0340, 0xc22: 0x0340, 0xc23: 0x0340,\n\t0xc24: 0x03c0, 0xc25: 0x0040, 0xc26: 0x0040, 0xc27: 0x0040, 0xc28: 0x0040, 0xc29: 0x0040,\n\t0xc2a: 0x0340, 0xc2b: 0x0340, 0xc2c: 0x0340, 0xc2d: 0x0340, 0xc2e: 0x0340, 0xc2f: 0x0340,\n\t0xc30: 0x06e1, 0xc31: 0x0311, 0xc32: 0x0040, 0xc33: 0x0040, 0xc34: 0x06e9, 0xc35: 0x06f1,\n\t0xc36: 0x06f9, 0xc37: 0x0701, 0xc38: 0x0709, 0xc39: 0x0711, 0xc3a: 0x071a, 0xc3b: 0x07d5,\n\t0xc3c: 0x0722, 0xc3d: 0x072a, 0xc3e: 0x0732, 0xc3f: 0x0329,\n\t// Block 0x31, offset 0xc40\n\t0xc40: 0x06e1, 0xc41: 0x0049, 0xc42: 0x0029, 0xc43: 0x0031, 0xc44: 0x06e9, 0xc45: 0x06f1,\n\t0xc46: 0x06f9, 0xc47: 0x0701, 0xc48: 0x0709, 0xc49: 0x0711, 0xc4a: 0x071a, 0xc4b: 0x07ed,\n\t0xc4c: 0x0722, 0xc4d: 0x072a, 0xc4e: 0x0732, 0xc4f: 0x0040, 0xc50: 0x0019, 0xc51: 0x02f9,\n\t0xc52: 0x0051, 0xc53: 0x0109, 0xc54: 0x0361, 0xc55: 0x00a9, 0xc56: 0x0319, 0xc57: 0x0101,\n\t0xc58: 0x0321, 0xc59: 0x0329, 0xc5a: 0x0339, 0xc5b: 0x0089, 0xc5c: 0x0341, 0xc5d: 0x0040,\n\t0xc5e: 0x0040, 0xc5f: 0x0040, 0xc60: 0x0018, 0xc61: 0x0018, 0xc62: 0x0018, 0xc63: 0x0018,\n\t0xc64: 0x0018, 0xc65: 0x0018, 0xc66: 0x0018, 0xc67: 0x0018, 0xc68: 0x0739, 0xc69: 0x0018,\n\t0xc6a: 0x0018, 0xc6b: 0x0018, 0xc6c: 0x0018, 0xc6d: 0x0018, 0xc6e: 0x0018, 0xc6f: 0x0018,\n\t0xc70: 0x0018, 0xc71: 0x0018, 0xc72: 0x0018, 0xc73: 0x0018, 0xc74: 0x0018, 0xc75: 0x0018,\n\t0xc76: 0x0018, 0xc77: 0x0018, 0xc78: 0x0018, 0xc79: 0x0018, 0xc7a: 0x0018, 0xc7b: 0x0018,\n\t0xc7c: 0x0018, 0xc7d: 0x0018, 0xc7e: 0x0018, 0xc7f: 0x0018,\n\t// Block 0x32, offset 0xc80\n\t0xc80: 0x0806, 0xc81: 0x0826, 0xc82: 0x03d9, 0xc83: 0x0845, 0xc84: 0x0018, 0xc85: 0x0866,\n\t0xc86: 0x0886, 0xc87: 0x0369, 0xc88: 0x0018, 0xc89: 0x08a5, 0xc8a: 0x0309, 0xc8b: 0x00a9,\n\t0xc8c: 0x00a9, 0xc8d: 0x00a9, 0xc8e: 0x00a9, 0xc8f: 0x0741, 0xc90: 0x0311, 0xc91: 0x0311,\n\t0xc92: 0x0101, 0xc93: 0x0101, 0xc94: 0x0018, 0xc95: 0x0329, 0xc96: 0x0749, 0xc97: 0x0018,\n\t0xc98: 0x0018, 0xc99: 0x0339, 0xc9a: 0x0751, 0xc9b: 0x00b9, 0xc9c: 0x00b9, 0xc9d: 0x00b9,\n\t0xc9e: 0x0018, 0xc9f: 0x0018, 0xca0: 0x0759, 0xca1: 0x08c5, 0xca2: 0x0761, 0xca3: 0x0018,\n\t0xca4: 0x04b1, 0xca5: 0x0018, 0xca6: 0x0769, 0xca7: 0x0018, 0xca8: 0x04b1, 0xca9: 0x0018,\n\t0xcaa: 0x0319, 0xcab: 0x0771, 0xcac: 0x02e9, 0xcad: 0x03d9, 0xcae: 0x0018, 0xcaf: 0x02f9,\n\t0xcb0: 0x02f9, 0xcb1: 0x03f1, 0xcb2: 0x0040, 0xcb3: 0x0321, 0xcb4: 0x0051, 0xcb5: 0x0779,\n\t0xcb6: 0x0781, 0xcb7: 0x0789, 0xcb8: 0x0791, 0xcb9: 0x0311, 0xcba: 0x0018, 0xcbb: 0x08e5,\n\t0xcbc: 0x0799, 0xcbd: 0x03a1, 0xcbe: 0x03a1, 0xcbf: 0x0799,\n\t// Block 0x33, offset 0xcc0\n\t0xcc0: 0x0905, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x02f1,\n\t0xcc6: 0x02f1, 0xcc7: 0x02f9, 0xcc8: 0x0311, 0xcc9: 0x00b1, 0xcca: 0x0018, 0xccb: 0x0018,\n\t0xccc: 0x0018, 0xccd: 0x0018, 0xcce: 0x0008, 0xccf: 0x0018, 0xcd0: 0x07a1, 0xcd1: 0x07a9,\n\t0xcd2: 0x07b1, 0xcd3: 0x07b9, 0xcd4: 0x07c1, 0xcd5: 0x07c9, 0xcd6: 0x07d1, 0xcd7: 0x07d9,\n\t0xcd8: 0x07e1, 0xcd9: 0x07e9, 0xcda: 0x07f1, 0xcdb: 0x07f9, 0xcdc: 0x0801, 0xcdd: 0x0809,\n\t0xcde: 0x0811, 0xcdf: 0x0819, 0xce0: 0x0311, 0xce1: 0x0821, 0xce2: 0x091d, 0xce3: 0x0829,\n\t0xce4: 0x0391, 0xce5: 0x0831, 0xce6: 0x093d, 0xce7: 0x0839, 0xce8: 0x0841, 0xce9: 0x0109,\n\t0xcea: 0x0849, 0xceb: 0x095d, 0xcec: 0x0101, 0xced: 0x03d9, 0xcee: 0x02f1, 0xcef: 0x0321,\n\t0xcf0: 0x0311, 0xcf1: 0x0821, 0xcf2: 0x097d, 0xcf3: 0x0829, 0xcf4: 0x0391, 0xcf5: 0x0831,\n\t0xcf6: 0x099d, 0xcf7: 0x0839, 0xcf8: 0x0841, 0xcf9: 0x0109, 0xcfa: 0x0849, 0xcfb: 0x09bd,\n\t0xcfc: 0x0101, 0xcfd: 0x03d9, 0xcfe: 0x02f1, 0xcff: 0x0321,\n\t// Block 0x34, offset 0xd00\n\t0xd00: 0x0018, 0xd01: 0x0018, 0xd02: 0x0018, 0xd03: 0x0018, 0xd04: 0x0018, 0xd05: 0x0018,\n\t0xd06: 0x0018, 0xd07: 0x0018, 0xd08: 0x0018, 0xd09: 0x0018, 0xd0a: 0x0018, 0xd0b: 0x0040,\n\t0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040,\n\t0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040,\n\t0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0040, 0xd1d: 0x0040,\n\t0xd1e: 0x0040, 0xd1f: 0x0040, 0xd20: 0x0049, 0xd21: 0x0029, 0xd22: 0x0031, 0xd23: 0x06e9,\n\t0xd24: 0x06f1, 0xd25: 0x06f9, 0xd26: 0x0701, 0xd27: 0x0709, 0xd28: 0x0711, 0xd29: 0x0879,\n\t0xd2a: 0x0881, 0xd2b: 0x0889, 0xd2c: 0x0891, 0xd2d: 0x0899, 0xd2e: 0x08a1, 0xd2f: 0x08a9,\n\t0xd30: 0x08b1, 0xd31: 0x08b9, 0xd32: 0x08c1, 0xd33: 0x08c9, 0xd34: 0x0a1e, 0xd35: 0x0a3e,\n\t0xd36: 0x0a5e, 0xd37: 0x0a7e, 0xd38: 0x0a9e, 0xd39: 0x0abe, 0xd3a: 0x0ade, 0xd3b: 0x0afe,\n\t0xd3c: 0x0b1e, 0xd3d: 0x08d2, 0xd3e: 0x08da, 0xd3f: 0x08e2,\n\t// Block 0x35, offset 0xd40\n\t0xd40: 0x08ea, 0xd41: 0x08f2, 0xd42: 0x08fa, 0xd43: 0x0902, 0xd44: 0x090a, 0xd45: 0x0912,\n\t0xd46: 0x091a, 0xd47: 0x0922, 0xd48: 0x0040, 0xd49: 0x0040, 0xd4a: 0x0040, 0xd4b: 0x0040,\n\t0xd4c: 0x0040, 0xd4d: 0x0040, 0xd4e: 0x0040, 0xd4f: 0x0040, 0xd50: 0x0040, 0xd51: 0x0040,\n\t0xd52: 0x0040, 0xd53: 0x0040, 0xd54: 0x0040, 0xd55: 0x0040, 0xd56: 0x0040, 0xd57: 0x0040,\n\t0xd58: 0x0040, 0xd59: 0x0040, 0xd5a: 0x0040, 0xd5b: 0x0040, 0xd5c: 0x0b3e, 0xd5d: 0x0b5e,\n\t0xd5e: 0x0b7e, 0xd5f: 0x0b9e, 0xd60: 0x0bbe, 0xd61: 0x0bde, 0xd62: 0x0bfe, 0xd63: 0x0c1e,\n\t0xd64: 0x0c3e, 0xd65: 0x0c5e, 0xd66: 0x0c7e, 0xd67: 0x0c9e, 0xd68: 0x0cbe, 0xd69: 0x0cde,\n\t0xd6a: 0x0cfe, 0xd6b: 0x0d1e, 0xd6c: 0x0d3e, 0xd6d: 0x0d5e, 0xd6e: 0x0d7e, 0xd6f: 0x0d9e,\n\t0xd70: 0x0dbe, 0xd71: 0x0dde, 0xd72: 0x0dfe, 0xd73: 0x0e1e, 0xd74: 0x0e3e, 0xd75: 0x0e5e,\n\t0xd76: 0x0019, 0xd77: 0x02e9, 0xd78: 0x03d9, 0xd79: 0x02f1, 0xd7a: 0x02f9, 0xd7b: 0x03f1,\n\t0xd7c: 0x0309, 0xd7d: 0x00a9, 0xd7e: 0x0311, 0xd7f: 0x00b1,\n\t// Block 0x36, offset 0xd80\n\t0xd80: 0x0319, 0xd81: 0x0101, 0xd82: 0x0321, 0xd83: 0x0329, 0xd84: 0x0051, 0xd85: 0x0339,\n\t0xd86: 0x0751, 0xd87: 0x00b9, 0xd88: 0x0089, 0xd89: 0x0341, 0xd8a: 0x0349, 0xd8b: 0x0391,\n\t0xd8c: 0x00c1, 0xd8d: 0x0109, 0xd8e: 0x00c9, 0xd8f: 0x04b1, 0xd90: 0x0019, 0xd91: 0x02e9,\n\t0xd92: 0x03d9, 0xd93: 0x02f1, 0xd94: 0x02f9, 0xd95: 0x03f1, 0xd96: 0x0309, 0xd97: 0x00a9,\n\t0xd98: 0x0311, 0xd99: 0x00b1, 0xd9a: 0x0319, 0xd9b: 0x0101, 0xd9c: 0x0321, 0xd9d: 0x0329,\n\t0xd9e: 0x0051, 0xd9f: 0x0339, 0xda0: 0x0751, 0xda1: 0x00b9, 0xda2: 0x0089, 0xda3: 0x0341,\n\t0xda4: 0x0349, 0xda5: 0x0391, 0xda6: 0x00c1, 0xda7: 0x0109, 0xda8: 0x00c9, 0xda9: 0x04b1,\n\t0xdaa: 0x06e1, 0xdab: 0x0018, 0xdac: 0x0018, 0xdad: 0x0018, 0xdae: 0x0018, 0xdaf: 0x0018,\n\t0xdb0: 0x0018, 0xdb1: 0x0018, 0xdb2: 0x0018, 0xdb3: 0x0018, 0xdb4: 0x0018, 0xdb5: 0x0018,\n\t0xdb6: 0x0018, 0xdb7: 0x0018, 0xdb8: 0x0018, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018,\n\t0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018,\n\t// Block 0x37, offset 0xdc0\n\t0xdc0: 0x0008, 0xdc1: 0x0008, 0xdc2: 0x0008, 0xdc3: 0x0008, 0xdc4: 0x0008, 0xdc5: 0x0008,\n\t0xdc6: 0x0008, 0xdc7: 0x0008, 0xdc8: 0x0008, 0xdc9: 0x0008, 0xdca: 0x0008, 0xdcb: 0x0008,\n\t0xdcc: 0x0008, 0xdcd: 0x0008, 0xdce: 0x0008, 0xdcf: 0x0008, 0xdd0: 0x0008, 0xdd1: 0x0008,\n\t0xdd2: 0x0008, 0xdd3: 0x0008, 0xdd4: 0x0008, 0xdd5: 0x0008, 0xdd6: 0x0008, 0xdd7: 0x0008,\n\t0xdd8: 0x0008, 0xdd9: 0x0008, 0xdda: 0x0008, 0xddb: 0x0008, 0xddc: 0x0008, 0xddd: 0x0008,\n\t0xdde: 0x0008, 0xddf: 0x0040, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0x0941, 0xde3: 0x0ed5,\n\t0xde4: 0x0949, 0xde5: 0x0008, 0xde6: 0x0008, 0xde7: 0xe07d, 0xde8: 0x0008, 0xde9: 0xe01d,\n\t0xdea: 0x0008, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0x0359, 0xdee: 0x0441, 0xdef: 0x0351,\n\t0xdf0: 0x03d1, 0xdf1: 0x0008, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0008, 0xdf5: 0xe01d,\n\t0xdf6: 0x0008, 0xdf7: 0x0008, 0xdf8: 0x0008, 0xdf9: 0x0008, 0xdfa: 0x0008, 0xdfb: 0x0008,\n\t0xdfc: 0x00b1, 0xdfd: 0x0391, 0xdfe: 0x0951, 0xdff: 0x0959,\n\t// Block 0x38, offset 0xe00\n\t0xe00: 0xe00d, 0xe01: 0x0008, 0xe02: 0xe00d, 0xe03: 0x0008, 0xe04: 0xe00d, 0xe05: 0x0008,\n\t0xe06: 0xe00d, 0xe07: 0x0008, 0xe08: 0xe00d, 0xe09: 0x0008, 0xe0a: 0xe00d, 0xe0b: 0x0008,\n\t0xe0c: 0xe00d, 0xe0d: 0x0008, 0xe0e: 0xe00d, 0xe0f: 0x0008, 0xe10: 0xe00d, 0xe11: 0x0008,\n\t0xe12: 0xe00d, 0xe13: 0x0008, 0xe14: 0xe00d, 0xe15: 0x0008, 0xe16: 0xe00d, 0xe17: 0x0008,\n\t0xe18: 0xe00d, 0xe19: 0x0008, 0xe1a: 0xe00d, 0xe1b: 0x0008, 0xe1c: 0xe00d, 0xe1d: 0x0008,\n\t0xe1e: 0xe00d, 0xe1f: 0x0008, 0xe20: 0xe00d, 0xe21: 0x0008, 0xe22: 0xe00d, 0xe23: 0x0008,\n\t0xe24: 0x0008, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018,\n\t0xe2a: 0x0018, 0xe2b: 0xe03d, 0xe2c: 0x0008, 0xe2d: 0xe01d, 0xe2e: 0x0008, 0xe2f: 0x3308,\n\t0xe30: 0x3308, 0xe31: 0x3308, 0xe32: 0xe00d, 0xe33: 0x0008, 0xe34: 0x0040, 0xe35: 0x0040,\n\t0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0018, 0xe3a: 0x0018, 0xe3b: 0x0018,\n\t0xe3c: 0x0018, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018,\n\t// Block 0x39, offset 0xe40\n\t0xe40: 0x2715, 0xe41: 0x2735, 0xe42: 0x2755, 0xe43: 0x2775, 0xe44: 0x2795, 0xe45: 0x27b5,\n\t0xe46: 0x27d5, 0xe47: 0x27f5, 0xe48: 0x2815, 0xe49: 0x2835, 0xe4a: 0x2855, 0xe4b: 0x2875,\n\t0xe4c: 0x2895, 0xe4d: 0x28b5, 0xe4e: 0x28d5, 0xe4f: 0x28f5, 0xe50: 0x2915, 0xe51: 0x2935,\n\t0xe52: 0x2955, 0xe53: 0x2975, 0xe54: 0x2995, 0xe55: 0x29b5, 0xe56: 0x0040, 0xe57: 0x0040,\n\t0xe58: 0x0040, 0xe59: 0x0040, 0xe5a: 0x0040, 0xe5b: 0x0040, 0xe5c: 0x0040, 0xe5d: 0x0040,\n\t0xe5e: 0x0040, 0xe5f: 0x0040, 0xe60: 0x0040, 0xe61: 0x0040, 0xe62: 0x0040, 0xe63: 0x0040,\n\t0xe64: 0x0040, 0xe65: 0x0040, 0xe66: 0x0040, 0xe67: 0x0040, 0xe68: 0x0040, 0xe69: 0x0040,\n\t0xe6a: 0x0040, 0xe6b: 0x0040, 0xe6c: 0x0040, 0xe6d: 0x0040, 0xe6e: 0x0040, 0xe6f: 0x0040,\n\t0xe70: 0x0040, 0xe71: 0x0040, 0xe72: 0x0040, 0xe73: 0x0040, 0xe74: 0x0040, 0xe75: 0x0040,\n\t0xe76: 0x0040, 0xe77: 0x0040, 0xe78: 0x0040, 0xe79: 0x0040, 0xe7a: 0x0040, 0xe7b: 0x0040,\n\t0xe7c: 0x0040, 0xe7d: 0x0040, 0xe7e: 0x0040, 0xe7f: 0x0040,\n\t// Block 0x3a, offset 0xe80\n\t0xe80: 0x000a, 0xe81: 0x0018, 0xe82: 0x0961, 0xe83: 0x0018, 0xe84: 0x0018, 0xe85: 0x0008,\n\t0xe86: 0x0008, 0xe87: 0x0008, 0xe88: 0x0018, 0xe89: 0x0018, 0xe8a: 0x0018, 0xe8b: 0x0018,\n\t0xe8c: 0x0018, 0xe8d: 0x0018, 0xe8e: 0x0018, 0xe8f: 0x0018, 0xe90: 0x0018, 0xe91: 0x0018,\n\t0xe92: 0x0018, 0xe93: 0x0018, 0xe94: 0x0018, 0xe95: 0x0018, 0xe96: 0x0018, 0xe97: 0x0018,\n\t0xe98: 0x0018, 0xe99: 0x0018, 0xe9a: 0x0018, 0xe9b: 0x0018, 0xe9c: 0x0018, 0xe9d: 0x0018,\n\t0xe9e: 0x0018, 0xe9f: 0x0018, 0xea0: 0x0018, 0xea1: 0x0018, 0xea2: 0x0018, 0xea3: 0x0018,\n\t0xea4: 0x0018, 0xea5: 0x0018, 0xea6: 0x0018, 0xea7: 0x0018, 0xea8: 0x0018, 0xea9: 0x0018,\n\t0xeaa: 0x3308, 0xeab: 0x3308, 0xeac: 0x3308, 0xead: 0x3308, 0xeae: 0x3018, 0xeaf: 0x3018,\n\t0xeb0: 0x0018, 0xeb1: 0x0018, 0xeb2: 0x0018, 0xeb3: 0x0018, 0xeb4: 0x0018, 0xeb5: 0x0018,\n\t0xeb6: 0xe125, 0xeb7: 0x0018, 0xeb8: 0x29d5, 0xeb9: 0x29f5, 0xeba: 0x2a15, 0xebb: 0x0018,\n\t0xebc: 0x0008, 0xebd: 0x0018, 0xebe: 0x0018, 0xebf: 0x0018,\n\t// Block 0x3b, offset 0xec0\n\t0xec0: 0x2b55, 0xec1: 0x2b75, 0xec2: 0x2b95, 0xec3: 0x2bb5, 0xec4: 0x2bd5, 0xec5: 0x2bf5,\n\t0xec6: 0x2bf5, 0xec7: 0x2bf5, 0xec8: 0x2c15, 0xec9: 0x2c15, 0xeca: 0x2c15, 0xecb: 0x2c15,\n\t0xecc: 0x2c35, 0xecd: 0x2c35, 0xece: 0x2c35, 0xecf: 0x2c55, 0xed0: 0x2c75, 0xed1: 0x2c75,\n\t0xed2: 0x2a95, 0xed3: 0x2a95, 0xed4: 0x2c75, 0xed5: 0x2c75, 0xed6: 0x2c95, 0xed7: 0x2c95,\n\t0xed8: 0x2c75, 0xed9: 0x2c75, 0xeda: 0x2a95, 0xedb: 0x2a95, 0xedc: 0x2c75, 0xedd: 0x2c75,\n\t0xede: 0x2c55, 0xedf: 0x2c55, 0xee0: 0x2cb5, 0xee1: 0x2cb5, 0xee2: 0x2cd5, 0xee3: 0x2cd5,\n\t0xee4: 0x0040, 0xee5: 0x2cf5, 0xee6: 0x2d15, 0xee7: 0x2d35, 0xee8: 0x2d35, 0xee9: 0x2d55,\n\t0xeea: 0x2d75, 0xeeb: 0x2d95, 0xeec: 0x2db5, 0xeed: 0x2dd5, 0xeee: 0x2df5, 0xeef: 0x2e15,\n\t0xef0: 0x2e35, 0xef1: 0x2e55, 0xef2: 0x2e55, 0xef3: 0x2e75, 0xef4: 0x2e95, 0xef5: 0x2e95,\n\t0xef6: 0x2eb5, 0xef7: 0x2ed5, 0xef8: 0x2e75, 0xef9: 0x2ef5, 0xefa: 0x2f15, 0xefb: 0x2ef5,\n\t0xefc: 0x2e75, 0xefd: 0x2f35, 0xefe: 0x2f55, 0xeff: 0x2f75,\n\t// Block 0x3c, offset 0xf00\n\t0xf00: 0x2f95, 0xf01: 0x2fb5, 0xf02: 0x2d15, 0xf03: 0x2cf5, 0xf04: 0x2fd5, 0xf05: 0x2ff5,\n\t0xf06: 0x3015, 0xf07: 0x3035, 0xf08: 0x3055, 0xf09: 0x3075, 0xf0a: 0x3095, 0xf0b: 0x30b5,\n\t0xf0c: 0x30d5, 0xf0d: 0x30f5, 0xf0e: 0x3115, 0xf0f: 0x0040, 0xf10: 0x0018, 0xf11: 0x0018,\n\t0xf12: 0x3135, 0xf13: 0x3155, 0xf14: 0x3175, 0xf15: 0x3195, 0xf16: 0x31b5, 0xf17: 0x31d5,\n\t0xf18: 0x31f5, 0xf19: 0x3215, 0xf1a: 0x3235, 0xf1b: 0x3255, 0xf1c: 0x3175, 0xf1d: 0x3275,\n\t0xf1e: 0x3295, 0xf1f: 0x32b5, 0xf20: 0x0008, 0xf21: 0x0008, 0xf22: 0x0008, 0xf23: 0x0008,\n\t0xf24: 0x0008, 0xf25: 0x0008, 0xf26: 0x0008, 0xf27: 0x0008, 0xf28: 0x0008, 0xf29: 0x0008,\n\t0xf2a: 0x0008, 0xf2b: 0x0008, 0xf2c: 0x0008, 0xf2d: 0x0008, 0xf2e: 0x0008, 0xf2f: 0x0008,\n\t0xf30: 0x0008, 0xf31: 0x0008, 0xf32: 0x0008, 0xf33: 0x0008, 0xf34: 0x0008, 0xf35: 0x0008,\n\t0xf36: 0x0008, 0xf37: 0x0008, 0xf38: 0x0008, 0xf39: 0x0008, 0xf3a: 0x0008, 0xf3b: 0x0008,\n\t0xf3c: 0x0008, 0xf3d: 0x0008, 0xf3e: 0x0008, 0xf3f: 0x0008,\n\t// Block 0x3d, offset 0xf40\n\t0xf40: 0x0b82, 0xf41: 0x0b8a, 0xf42: 0x0b92, 0xf43: 0x0b9a, 0xf44: 0x32d5, 0xf45: 0x32f5,\n\t0xf46: 0x3315, 0xf47: 0x3335, 0xf48: 0x0018, 0xf49: 0x0018, 0xf4a: 0x0018, 0xf4b: 0x0018,\n\t0xf4c: 0x0018, 0xf4d: 0x0018, 0xf4e: 0x0018, 0xf4f: 0x0018, 0xf50: 0x3355, 0xf51: 0x0ba1,\n\t0xf52: 0x0ba9, 0xf53: 0x0bb1, 0xf54: 0x0bb9, 0xf55: 0x0bc1, 0xf56: 0x0bc9, 0xf57: 0x0bd1,\n\t0xf58: 0x0bd9, 0xf59: 0x0be1, 0xf5a: 0x0be9, 0xf5b: 0x0bf1, 0xf5c: 0x0bf9, 0xf5d: 0x0c01,\n\t0xf5e: 0x0c09, 0xf5f: 0x0c11, 0xf60: 0x3375, 0xf61: 0x3395, 0xf62: 0x33b5, 0xf63: 0x33d5,\n\t0xf64: 0x33f5, 0xf65: 0x33f5, 0xf66: 0x3415, 0xf67: 0x3435, 0xf68: 0x3455, 0xf69: 0x3475,\n\t0xf6a: 0x3495, 0xf6b: 0x34b5, 0xf6c: 0x34d5, 0xf6d: 0x34f5, 0xf6e: 0x3515, 0xf6f: 0x3535,\n\t0xf70: 0x3555, 0xf71: 0x3575, 0xf72: 0x3595, 0xf73: 0x35b5, 0xf74: 0x35d5, 0xf75: 0x35f5,\n\t0xf76: 0x3615, 0xf77: 0x3635, 0xf78: 0x3655, 0xf79: 0x3675, 0xf7a: 0x3695, 0xf7b: 0x36b5,\n\t0xf7c: 0x0c19, 0xf7d: 0x0c21, 0xf7e: 0x36d5, 0xf7f: 0x0018,\n\t// Block 0x3e, offset 0xf80\n\t0xf80: 0x36f5, 0xf81: 0x3715, 0xf82: 0x3735, 0xf83: 0x3755, 0xf84: 0x3775, 0xf85: 0x3795,\n\t0xf86: 0x37b5, 0xf87: 0x37d5, 0xf88: 0x37f5, 0xf89: 0x3815, 0xf8a: 0x3835, 0xf8b: 0x3855,\n\t0xf8c: 0x3875, 0xf8d: 0x3895, 0xf8e: 0x38b5, 0xf8f: 0x38d5, 0xf90: 0x38f5, 0xf91: 0x3915,\n\t0xf92: 0x3935, 0xf93: 0x3955, 0xf94: 0x3975, 0xf95: 0x3995, 0xf96: 0x39b5, 0xf97: 0x39d5,\n\t0xf98: 0x39f5, 0xf99: 0x3a15, 0xf9a: 0x3a35, 0xf9b: 0x3a55, 0xf9c: 0x3a75, 0xf9d: 0x3a95,\n\t0xf9e: 0x3ab5, 0xf9f: 0x3ad5, 0xfa0: 0x3af5, 0xfa1: 0x3b15, 0xfa2: 0x3b35, 0xfa3: 0x3b55,\n\t0xfa4: 0x3b75, 0xfa5: 0x3b95, 0xfa6: 0x1295, 0xfa7: 0x3bb5, 0xfa8: 0x3bd5, 0xfa9: 0x3bf5,\n\t0xfaa: 0x3c15, 0xfab: 0x3c35, 0xfac: 0x3c55, 0xfad: 0x3c75, 0xfae: 0x23b5, 0xfaf: 0x3c95,\n\t0xfb0: 0x3cb5, 0xfb1: 0x0c29, 0xfb2: 0x0c31, 0xfb3: 0x0c39, 0xfb4: 0x0c41, 0xfb5: 0x0c49,\n\t0xfb6: 0x0c51, 0xfb7: 0x0c59, 0xfb8: 0x0c61, 0xfb9: 0x0c69, 0xfba: 0x0c71, 0xfbb: 0x0c79,\n\t0xfbc: 0x0c81, 0xfbd: 0x0c89, 0xfbe: 0x0c91, 0xfbf: 0x0c99,\n\t// Block 0x3f, offset 0xfc0\n\t0xfc0: 0x0ca1, 0xfc1: 0x0ca9, 0xfc2: 0x0cb1, 0xfc3: 0x0cb9, 0xfc4: 0x0cc1, 0xfc5: 0x0cc9,\n\t0xfc6: 0x0cd1, 0xfc7: 0x0cd9, 0xfc8: 0x0ce1, 0xfc9: 0x0ce9, 0xfca: 0x0cf1, 0xfcb: 0x0cf9,\n\t0xfcc: 0x0d01, 0xfcd: 0x3cd5, 0xfce: 0x0d09, 0xfcf: 0x3cf5, 0xfd0: 0x3d15, 0xfd1: 0x3d2d,\n\t0xfd2: 0x3d45, 0xfd3: 0x3d5d, 0xfd4: 0x3d75, 0xfd5: 0x3d75, 0xfd6: 0x3d5d, 0xfd7: 0x3d8d,\n\t0xfd8: 0x07d5, 0xfd9: 0x3da5, 0xfda: 0x3dbd, 0xfdb: 0x3dd5, 0xfdc: 0x3ded, 0xfdd: 0x3e05,\n\t0xfde: 0x3e1d, 0xfdf: 0x3e35, 0xfe0: 0x3e4d, 0xfe1: 0x3e65, 0xfe2: 0x3e7d, 0xfe3: 0x3e95,\n\t0xfe4: 0x3ead, 0xfe5: 0x3ead, 0xfe6: 0x3ec5, 0xfe7: 0x3ec5, 0xfe8: 0x3edd, 0xfe9: 0x3edd,\n\t0xfea: 0x3ef5, 0xfeb: 0x3f0d, 0xfec: 0x3f25, 0xfed: 0x3f3d, 0xfee: 0x3f55, 0xfef: 0x3f55,\n\t0xff0: 0x3f6d, 0xff1: 0x3f6d, 0xff2: 0x3f6d, 0xff3: 0x3f85, 0xff4: 0x3f9d, 0xff5: 0x3fb5,\n\t0xff6: 0x3fcd, 0xff7: 0x3fb5, 0xff8: 0x3fe5, 0xff9: 0x3ffd, 0xffa: 0x3f85, 0xffb: 0x4015,\n\t0xffc: 0x402d, 0xffd: 0x402d, 0xffe: 0x402d, 0xfff: 0x0d11,\n\t// Block 0x40, offset 0x1000\n\t0x1000: 0x10f9, 0x1001: 0x1101, 0x1002: 0x40a5, 0x1003: 0x1109, 0x1004: 0x1111, 0x1005: 0x1119,\n\t0x1006: 0x1121, 0x1007: 0x1129, 0x1008: 0x40c5, 0x1009: 0x1131, 0x100a: 0x1139, 0x100b: 0x1141,\n\t0x100c: 0x40e5, 0x100d: 0x40e5, 0x100e: 0x1149, 0x100f: 0x1151, 0x1010: 0x1159, 0x1011: 0x4105,\n\t0x1012: 0x4125, 0x1013: 0x4145, 0x1014: 0x4165, 0x1015: 0x4185, 0x1016: 0x1161, 0x1017: 0x1169,\n\t0x1018: 0x1171, 0x1019: 0x1179, 0x101a: 0x1181, 0x101b: 0x41a5, 0x101c: 0x1189, 0x101d: 0x1191,\n\t0x101e: 0x1199, 0x101f: 0x41c5, 0x1020: 0x41e5, 0x1021: 0x11a1, 0x1022: 0x4205, 0x1023: 0x4225,\n\t0x1024: 0x4245, 0x1025: 0x11a9, 0x1026: 0x4265, 0x1027: 0x11b1, 0x1028: 0x11b9, 0x1029: 0x10f9,\n\t0x102a: 0x4285, 0x102b: 0x42a5, 0x102c: 0x42c5, 0x102d: 0x42e5, 0x102e: 0x11c1, 0x102f: 0x11c9,\n\t0x1030: 0x11d1, 0x1031: 0x11d9, 0x1032: 0x4305, 0x1033: 0x11e1, 0x1034: 0x11e9, 0x1035: 0x11f1,\n\t0x1036: 0x4325, 0x1037: 0x11f9, 0x1038: 0x1201, 0x1039: 0x11f9, 0x103a: 0x1209, 0x103b: 0x1211,\n\t0x103c: 0x4345, 0x103d: 0x1219, 0x103e: 0x1221, 0x103f: 0x1219,\n\t// Block 0x41, offset 0x1040\n\t0x1040: 0x4365, 0x1041: 0x4385, 0x1042: 0x0040, 0x1043: 0x1229, 0x1044: 0x1231, 0x1045: 0x1239,\n\t0x1046: 0x1241, 0x1047: 0x0040, 0x1048: 0x1249, 0x1049: 0x1251, 0x104a: 0x1259, 0x104b: 0x1261,\n\t0x104c: 0x1269, 0x104d: 0x1271, 0x104e: 0x1199, 0x104f: 0x1279, 0x1050: 0x1281, 0x1051: 0x1289,\n\t0x1052: 0x43a5, 0x1053: 0x1291, 0x1054: 0x1121, 0x1055: 0x43c5, 0x1056: 0x43e5, 0x1057: 0x1299,\n\t0x1058: 0x0040, 0x1059: 0x4405, 0x105a: 0x12a1, 0x105b: 0x12a9, 0x105c: 0x12b1, 0x105d: 0x12b9,\n\t0x105e: 0x12c1, 0x105f: 0x12c9, 0x1060: 0x12d1, 0x1061: 0x12d9, 0x1062: 0x12e1, 0x1063: 0x12e9,\n\t0x1064: 0x12f1, 0x1065: 0x12f9, 0x1066: 0x1301, 0x1067: 0x1309, 0x1068: 0x1311, 0x1069: 0x1319,\n\t0x106a: 0x1321, 0x106b: 0x1329, 0x106c: 0x1331, 0x106d: 0x1339, 0x106e: 0x1341, 0x106f: 0x1349,\n\t0x1070: 0x1351, 0x1071: 0x1359, 0x1072: 0x1361, 0x1073: 0x1369, 0x1074: 0x1371, 0x1075: 0x1379,\n\t0x1076: 0x1381, 0x1077: 0x1389, 0x1078: 0x1391, 0x1079: 0x1399, 0x107a: 0x13a1, 0x107b: 0x13a9,\n\t0x107c: 0x13b1, 0x107d: 0x13b9, 0x107e: 0x13c1, 0x107f: 0x4425,\n\t// Block 0x42, offset 0x1080\n\t0x1080: 0xe00d, 0x1081: 0x0008, 0x1082: 0xe00d, 0x1083: 0x0008, 0x1084: 0xe00d, 0x1085: 0x0008,\n\t0x1086: 0xe00d, 0x1087: 0x0008, 0x1088: 0xe00d, 0x1089: 0x0008, 0x108a: 0xe00d, 0x108b: 0x0008,\n\t0x108c: 0xe00d, 0x108d: 0x0008, 0x108e: 0xe00d, 0x108f: 0x0008, 0x1090: 0xe00d, 0x1091: 0x0008,\n\t0x1092: 0xe00d, 0x1093: 0x0008, 0x1094: 0xe00d, 0x1095: 0x0008, 0x1096: 0xe00d, 0x1097: 0x0008,\n\t0x1098: 0xe00d, 0x1099: 0x0008, 0x109a: 0xe00d, 0x109b: 0x0008, 0x109c: 0xe00d, 0x109d: 0x0008,\n\t0x109e: 0xe00d, 0x109f: 0x0008, 0x10a0: 0xe00d, 0x10a1: 0x0008, 0x10a2: 0xe00d, 0x10a3: 0x0008,\n\t0x10a4: 0xe00d, 0x10a5: 0x0008, 0x10a6: 0xe00d, 0x10a7: 0x0008, 0x10a8: 0xe00d, 0x10a9: 0x0008,\n\t0x10aa: 0xe00d, 0x10ab: 0x0008, 0x10ac: 0xe00d, 0x10ad: 0x0008, 0x10ae: 0x0008, 0x10af: 0x3308,\n\t0x10b0: 0x3318, 0x10b1: 0x3318, 0x10b2: 0x3318, 0x10b3: 0x0018, 0x10b4: 0x3308, 0x10b5: 0x3308,\n\t0x10b6: 0x3308, 0x10b7: 0x3308, 0x10b8: 0x3308, 0x10b9: 0x3308, 0x10ba: 0x3308, 0x10bb: 0x3308,\n\t0x10bc: 0x3308, 0x10bd: 0x3308, 0x10be: 0x0018, 0x10bf: 0x0008,\n\t// Block 0x43, offset 0x10c0\n\t0x10c0: 0xe00d, 0x10c1: 0x0008, 0x10c2: 0xe00d, 0x10c3: 0x0008, 0x10c4: 0xe00d, 0x10c5: 0x0008,\n\t0x10c6: 0xe00d, 0x10c7: 0x0008, 0x10c8: 0xe00d, 0x10c9: 0x0008, 0x10ca: 0xe00d, 0x10cb: 0x0008,\n\t0x10cc: 0xe00d, 0x10cd: 0x0008, 0x10ce: 0xe00d, 0x10cf: 0x0008, 0x10d0: 0xe00d, 0x10d1: 0x0008,\n\t0x10d2: 0xe00d, 0x10d3: 0x0008, 0x10d4: 0xe00d, 0x10d5: 0x0008, 0x10d6: 0xe00d, 0x10d7: 0x0008,\n\t0x10d8: 0xe00d, 0x10d9: 0x0008, 0x10da: 0xe00d, 0x10db: 0x0008, 0x10dc: 0x02d1, 0x10dd: 0x13c9,\n\t0x10de: 0x3308, 0x10df: 0x3308, 0x10e0: 0x0008, 0x10e1: 0x0008, 0x10e2: 0x0008, 0x10e3: 0x0008,\n\t0x10e4: 0x0008, 0x10e5: 0x0008, 0x10e6: 0x0008, 0x10e7: 0x0008, 0x10e8: 0x0008, 0x10e9: 0x0008,\n\t0x10ea: 0x0008, 0x10eb: 0x0008, 0x10ec: 0x0008, 0x10ed: 0x0008, 0x10ee: 0x0008, 0x10ef: 0x0008,\n\t0x10f0: 0x0008, 0x10f1: 0x0008, 0x10f2: 0x0008, 0x10f3: 0x0008, 0x10f4: 0x0008, 0x10f5: 0x0008,\n\t0x10f6: 0x0008, 0x10f7: 0x0008, 0x10f8: 0x0008, 0x10f9: 0x0008, 0x10fa: 0x0008, 0x10fb: 0x0008,\n\t0x10fc: 0x0008, 0x10fd: 0x0008, 0x10fe: 0x0008, 0x10ff: 0x0008,\n\t// Block 0x44, offset 0x1100\n\t0x1100: 0x0018, 0x1101: 0x0018, 0x1102: 0x0018, 0x1103: 0x0018, 0x1104: 0x0018, 0x1105: 0x0018,\n\t0x1106: 0x0018, 0x1107: 0x0018, 0x1108: 0x0018, 0x1109: 0x0018, 0x110a: 0x0018, 0x110b: 0x0018,\n\t0x110c: 0x0018, 0x110d: 0x0018, 0x110e: 0x0018, 0x110f: 0x0018, 0x1110: 0x0018, 0x1111: 0x0018,\n\t0x1112: 0x0018, 0x1113: 0x0018, 0x1114: 0x0018, 0x1115: 0x0018, 0x1116: 0x0018, 0x1117: 0x0008,\n\t0x1118: 0x0008, 0x1119: 0x0008, 0x111a: 0x0008, 0x111b: 0x0008, 0x111c: 0x0008, 0x111d: 0x0008,\n\t0x111e: 0x0008, 0x111f: 0x0008, 0x1120: 0x0018, 0x1121: 0x0018, 0x1122: 0xe00d, 0x1123: 0x0008,\n\t0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008,\n\t0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0xe00d, 0x112f: 0x0008,\n\t0x1130: 0x0008, 0x1131: 0x0008, 0x1132: 0xe00d, 0x1133: 0x0008, 0x1134: 0xe00d, 0x1135: 0x0008,\n\t0x1136: 0xe00d, 0x1137: 0x0008, 0x1138: 0xe00d, 0x1139: 0x0008, 0x113a: 0xe00d, 0x113b: 0x0008,\n\t0x113c: 0xe00d, 0x113d: 0x0008, 0x113e: 0xe00d, 0x113f: 0x0008,\n\t// Block 0x45, offset 0x1140\n\t0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008,\n\t0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008,\n\t0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008,\n\t0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008,\n\t0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0xe00d, 0x115d: 0x0008,\n\t0x115e: 0xe00d, 0x115f: 0x0008, 0x1160: 0xe00d, 0x1161: 0x0008, 0x1162: 0xe00d, 0x1163: 0x0008,\n\t0x1164: 0xe00d, 0x1165: 0x0008, 0x1166: 0xe00d, 0x1167: 0x0008, 0x1168: 0xe00d, 0x1169: 0x0008,\n\t0x116a: 0xe00d, 0x116b: 0x0008, 0x116c: 0xe00d, 0x116d: 0x0008, 0x116e: 0xe00d, 0x116f: 0x0008,\n\t0x1170: 0xe0fd, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008,\n\t0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0xe01d, 0x117a: 0x0008, 0x117b: 0xe03d,\n\t0x117c: 0x0008, 0x117d: 0x4445, 0x117e: 0xe00d, 0x117f: 0x0008,\n\t// Block 0x46, offset 0x1180\n\t0x1180: 0xe00d, 0x1181: 0x0008, 0x1182: 0xe00d, 0x1183: 0x0008, 0x1184: 0xe00d, 0x1185: 0x0008,\n\t0x1186: 0xe00d, 0x1187: 0x0008, 0x1188: 0x0008, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0xe03d,\n\t0x118c: 0x0008, 0x118d: 0x0409, 0x118e: 0x0008, 0x118f: 0x0008, 0x1190: 0xe00d, 0x1191: 0x0008,\n\t0x1192: 0xe00d, 0x1193: 0x0008, 0x1194: 0x0008, 0x1195: 0x0008, 0x1196: 0xe00d, 0x1197: 0x0008,\n\t0x1198: 0xe00d, 0x1199: 0x0008, 0x119a: 0xe00d, 0x119b: 0x0008, 0x119c: 0xe00d, 0x119d: 0x0008,\n\t0x119e: 0xe00d, 0x119f: 0x0008, 0x11a0: 0xe00d, 0x11a1: 0x0008, 0x11a2: 0xe00d, 0x11a3: 0x0008,\n\t0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008,\n\t0x11aa: 0x13d1, 0x11ab: 0x0371, 0x11ac: 0x0401, 0x11ad: 0x13d9, 0x11ae: 0x0421, 0x11af: 0x0008,\n\t0x11b0: 0x13e1, 0x11b1: 0x13e9, 0x11b2: 0x0429, 0x11b3: 0x4465, 0x11b4: 0xe00d, 0x11b5: 0x0008,\n\t0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0xe00d, 0x11b9: 0x0008, 0x11ba: 0xe00d, 0x11bb: 0x0008,\n\t0x11bc: 0xe00d, 0x11bd: 0x0008, 0x11be: 0xe00d, 0x11bf: 0x0008,\n\t// Block 0x47, offset 0x11c0\n\t0x11c0: 0x650d, 0x11c1: 0x652d, 0x11c2: 0x654d, 0x11c3: 0x656d, 0x11c4: 0x658d, 0x11c5: 0x65ad,\n\t0x11c6: 0x65cd, 0x11c7: 0x65ed, 0x11c8: 0x660d, 0x11c9: 0x662d, 0x11ca: 0x664d, 0x11cb: 0x666d,\n\t0x11cc: 0x668d, 0x11cd: 0x66ad, 0x11ce: 0x0008, 0x11cf: 0x0008, 0x11d0: 0x66cd, 0x11d1: 0x0008,\n\t0x11d2: 0x66ed, 0x11d3: 0x0008, 0x11d4: 0x0008, 0x11d5: 0x670d, 0x11d6: 0x672d, 0x11d7: 0x674d,\n\t0x11d8: 0x676d, 0x11d9: 0x678d, 0x11da: 0x67ad, 0x11db: 0x67cd, 0x11dc: 0x67ed, 0x11dd: 0x680d,\n\t0x11de: 0x682d, 0x11df: 0x0008, 0x11e0: 0x684d, 0x11e1: 0x0008, 0x11e2: 0x686d, 0x11e3: 0x0008,\n\t0x11e4: 0x0008, 0x11e5: 0x688d, 0x11e6: 0x68ad, 0x11e7: 0x0008, 0x11e8: 0x0008, 0x11e9: 0x0008,\n\t0x11ea: 0x68cd, 0x11eb: 0x68ed, 0x11ec: 0x690d, 0x11ed: 0x692d, 0x11ee: 0x694d, 0x11ef: 0x696d,\n\t0x11f0: 0x698d, 0x11f1: 0x69ad, 0x11f2: 0x69cd, 0x11f3: 0x69ed, 0x11f4: 0x6a0d, 0x11f5: 0x6a2d,\n\t0x11f6: 0x6a4d, 0x11f7: 0x6a6d, 0x11f8: 0x6a8d, 0x11f9: 0x6aad, 0x11fa: 0x6acd, 0x11fb: 0x6aed,\n\t0x11fc: 0x6b0d, 0x11fd: 0x6b2d, 0x11fe: 0x6b4d, 0x11ff: 0x6b6d,\n\t// Block 0x48, offset 0x1200\n\t0x1200: 0x7acd, 0x1201: 0x7aed, 0x1202: 0x7b0d, 0x1203: 0x7b2d, 0x1204: 0x7b4d, 0x1205: 0x7b6d,\n\t0x1206: 0x7b8d, 0x1207: 0x7bad, 0x1208: 0x7bcd, 0x1209: 0x7bed, 0x120a: 0x7c0d, 0x120b: 0x7c2d,\n\t0x120c: 0x7c4d, 0x120d: 0x7c6d, 0x120e: 0x7c8d, 0x120f: 0x1409, 0x1210: 0x1411, 0x1211: 0x1419,\n\t0x1212: 0x7cad, 0x1213: 0x7ccd, 0x1214: 0x7ced, 0x1215: 0x1421, 0x1216: 0x1429, 0x1217: 0x1431,\n\t0x1218: 0x7d0d, 0x1219: 0x7d2d, 0x121a: 0x0040, 0x121b: 0x0040, 0x121c: 0x0040, 0x121d: 0x0040,\n\t0x121e: 0x0040, 0x121f: 0x0040, 0x1220: 0x0040, 0x1221: 0x0040, 0x1222: 0x0040, 0x1223: 0x0040,\n\t0x1224: 0x0040, 0x1225: 0x0040, 0x1226: 0x0040, 0x1227: 0x0040, 0x1228: 0x0040, 0x1229: 0x0040,\n\t0x122a: 0x0040, 0x122b: 0x0040, 0x122c: 0x0040, 0x122d: 0x0040, 0x122e: 0x0040, 0x122f: 0x0040,\n\t0x1230: 0x0040, 0x1231: 0x0040, 0x1232: 0x0040, 0x1233: 0x0040, 0x1234: 0x0040, 0x1235: 0x0040,\n\t0x1236: 0x0040, 0x1237: 0x0040, 0x1238: 0x0040, 0x1239: 0x0040, 0x123a: 0x0040, 0x123b: 0x0040,\n\t0x123c: 0x0040, 0x123d: 0x0040, 0x123e: 0x0040, 0x123f: 0x0040,\n\t// Block 0x49, offset 0x1240\n\t0x1240: 0x1439, 0x1241: 0x1441, 0x1242: 0x1449, 0x1243: 0x7d4d, 0x1244: 0x7d6d, 0x1245: 0x1451,\n\t0x1246: 0x1451, 0x1247: 0x0040, 0x1248: 0x0040, 0x1249: 0x0040, 0x124a: 0x0040, 0x124b: 0x0040,\n\t0x124c: 0x0040, 0x124d: 0x0040, 0x124e: 0x0040, 0x124f: 0x0040, 0x1250: 0x0040, 0x1251: 0x0040,\n\t0x1252: 0x0040, 0x1253: 0x1459, 0x1254: 0x1461, 0x1255: 0x1469, 0x1256: 0x1471, 0x1257: 0x1479,\n\t0x1258: 0x0040, 0x1259: 0x0040, 0x125a: 0x0040, 0x125b: 0x0040, 0x125c: 0x0040, 0x125d: 0x1481,\n\t0x125e: 0x3308, 0x125f: 0x1489, 0x1260: 0x1491, 0x1261: 0x0779, 0x1262: 0x0791, 0x1263: 0x1499,\n\t0x1264: 0x14a1, 0x1265: 0x14a9, 0x1266: 0x14b1, 0x1267: 0x14b9, 0x1268: 0x14c1, 0x1269: 0x071a,\n\t0x126a: 0x14c9, 0x126b: 0x14d1, 0x126c: 0x14d9, 0x126d: 0x14e1, 0x126e: 0x14e9, 0x126f: 0x14f1,\n\t0x1270: 0x14f9, 0x1271: 0x1501, 0x1272: 0x1509, 0x1273: 0x1511, 0x1274: 0x1519, 0x1275: 0x1521,\n\t0x1276: 0x1529, 0x1277: 0x0040, 0x1278: 0x1531, 0x1279: 0x1539, 0x127a: 0x1541, 0x127b: 0x1549,\n\t0x127c: 0x1551, 0x127d: 0x0040, 0x127e: 0x1559, 0x127f: 0x0040,\n\t// Block 0x4a, offset 0x1280\n\t0x1280: 0x1561, 0x1281: 0x1569, 0x1282: 0x0040, 0x1283: 0x1571, 0x1284: 0x1579, 0x1285: 0x0040,\n\t0x1286: 0x1581, 0x1287: 0x1589, 0x1288: 0x1591, 0x1289: 0x1599, 0x128a: 0x15a1, 0x128b: 0x15a9,\n\t0x128c: 0x15b1, 0x128d: 0x15b9, 0x128e: 0x15c1, 0x128f: 0x15c9, 0x1290: 0x15d1, 0x1291: 0x15d1,\n\t0x1292: 0x15d9, 0x1293: 0x15d9, 0x1294: 0x15d9, 0x1295: 0x15d9, 0x1296: 0x15e1, 0x1297: 0x15e1,\n\t0x1298: 0x15e1, 0x1299: 0x15e1, 0x129a: 0x15e9, 0x129b: 0x15e9, 0x129c: 0x15e9, 0x129d: 0x15e9,\n\t0x129e: 0x15f1, 0x129f: 0x15f1, 0x12a0: 0x15f1, 0x12a1: 0x15f1, 0x12a2: 0x15f9, 0x12a3: 0x15f9,\n\t0x12a4: 0x15f9, 0x12a5: 0x15f9, 0x12a6: 0x1601, 0x12a7: 0x1601, 0x12a8: 0x1601, 0x12a9: 0x1601,\n\t0x12aa: 0x1609, 0x12ab: 0x1609, 0x12ac: 0x1609, 0x12ad: 0x1609, 0x12ae: 0x1611, 0x12af: 0x1611,\n\t0x12b0: 0x1611, 0x12b1: 0x1611, 0x12b2: 0x1619, 0x12b3: 0x1619, 0x12b4: 0x1619, 0x12b5: 0x1619,\n\t0x12b6: 0x1621, 0x12b7: 0x1621, 0x12b8: 0x1621, 0x12b9: 0x1621, 0x12ba: 0x1629, 0x12bb: 0x1629,\n\t0x12bc: 0x1629, 0x12bd: 0x1629, 0x12be: 0x1631, 0x12bf: 0x1631,\n\t// Block 0x4b, offset 0x12c0\n\t0x12c0: 0x1631, 0x12c1: 0x1631, 0x12c2: 0x1639, 0x12c3: 0x1639, 0x12c4: 0x1641, 0x12c5: 0x1641,\n\t0x12c6: 0x1649, 0x12c7: 0x1649, 0x12c8: 0x1651, 0x12c9: 0x1651, 0x12ca: 0x1659, 0x12cb: 0x1659,\n\t0x12cc: 0x1661, 0x12cd: 0x1661, 0x12ce: 0x1669, 0x12cf: 0x1669, 0x12d0: 0x1669, 0x12d1: 0x1669,\n\t0x12d2: 0x1671, 0x12d3: 0x1671, 0x12d4: 0x1671, 0x12d5: 0x1671, 0x12d6: 0x1679, 0x12d7: 0x1679,\n\t0x12d8: 0x1679, 0x12d9: 0x1679, 0x12da: 0x1681, 0x12db: 0x1681, 0x12dc: 0x1681, 0x12dd: 0x1681,\n\t0x12de: 0x1689, 0x12df: 0x1689, 0x12e0: 0x1691, 0x12e1: 0x1691, 0x12e2: 0x1691, 0x12e3: 0x1691,\n\t0x12e4: 0x1699, 0x12e5: 0x1699, 0x12e6: 0x16a1, 0x12e7: 0x16a1, 0x12e8: 0x16a1, 0x12e9: 0x16a1,\n\t0x12ea: 0x16a9, 0x12eb: 0x16a9, 0x12ec: 0x16a9, 0x12ed: 0x16a9, 0x12ee: 0x16b1, 0x12ef: 0x16b1,\n\t0x12f0: 0x16b9, 0x12f1: 0x16b9, 0x12f2: 0x0818, 0x12f3: 0x0818, 0x12f4: 0x0818, 0x12f5: 0x0818,\n\t0x12f6: 0x0818, 0x12f7: 0x0818, 0x12f8: 0x0818, 0x12f9: 0x0818, 0x12fa: 0x0818, 0x12fb: 0x0818,\n\t0x12fc: 0x0818, 0x12fd: 0x0818, 0x12fe: 0x0818, 0x12ff: 0x0818,\n\t// Block 0x4c, offset 0x1300\n\t0x1300: 0x0818, 0x1301: 0x0818, 0x1302: 0x0040, 0x1303: 0x0040, 0x1304: 0x0040, 0x1305: 0x0040,\n\t0x1306: 0x0040, 0x1307: 0x0040, 0x1308: 0x0040, 0x1309: 0x0040, 0x130a: 0x0040, 0x130b: 0x0040,\n\t0x130c: 0x0040, 0x130d: 0x0040, 0x130e: 0x0040, 0x130f: 0x0040, 0x1310: 0x0040, 0x1311: 0x0040,\n\t0x1312: 0x0040, 0x1313: 0x16c1, 0x1314: 0x16c1, 0x1315: 0x16c1, 0x1316: 0x16c1, 0x1317: 0x16c9,\n\t0x1318: 0x16c9, 0x1319: 0x16d1, 0x131a: 0x16d1, 0x131b: 0x16d9, 0x131c: 0x16d9, 0x131d: 0x0149,\n\t0x131e: 0x16e1, 0x131f: 0x16e1, 0x1320: 0x16e9, 0x1321: 0x16e9, 0x1322: 0x16f1, 0x1323: 0x16f1,\n\t0x1324: 0x16f9, 0x1325: 0x16f9, 0x1326: 0x16f9, 0x1327: 0x16f9, 0x1328: 0x1701, 0x1329: 0x1701,\n\t0x132a: 0x1709, 0x132b: 0x1709, 0x132c: 0x1711, 0x132d: 0x1711, 0x132e: 0x1719, 0x132f: 0x1719,\n\t0x1330: 0x1721, 0x1331: 0x1721, 0x1332: 0x1729, 0x1333: 0x1729, 0x1334: 0x1731, 0x1335: 0x1731,\n\t0x1336: 0x1739, 0x1337: 0x1739, 0x1338: 0x1739, 0x1339: 0x1741, 0x133a: 0x1741, 0x133b: 0x1741,\n\t0x133c: 0x1749, 0x133d: 0x1749, 0x133e: 0x1749, 0x133f: 0x1749,\n\t// Block 0x4d, offset 0x1340\n\t0x1340: 0x1949, 0x1341: 0x1951, 0x1342: 0x1959, 0x1343: 0x1961, 0x1344: 0x1969, 0x1345: 0x1971,\n\t0x1346: 0x1979, 0x1347: 0x1981, 0x1348: 0x1989, 0x1349: 0x1991, 0x134a: 0x1999, 0x134b: 0x19a1,\n\t0x134c: 0x19a9, 0x134d: 0x19b1, 0x134e: 0x19b9, 0x134f: 0x19c1, 0x1350: 0x19c9, 0x1351: 0x19d1,\n\t0x1352: 0x19d9, 0x1353: 0x19e1, 0x1354: 0x19e9, 0x1355: 0x19f1, 0x1356: 0x19f9, 0x1357: 0x1a01,\n\t0x1358: 0x1a09, 0x1359: 0x1a11, 0x135a: 0x1a19, 0x135b: 0x1a21, 0x135c: 0x1a29, 0x135d: 0x1a31,\n\t0x135e: 0x1a3a, 0x135f: 0x1a42, 0x1360: 0x1a4a, 0x1361: 0x1a52, 0x1362: 0x1a5a, 0x1363: 0x1a62,\n\t0x1364: 0x1a69, 0x1365: 0x1a71, 0x1366: 0x1761, 0x1367: 0x1a79, 0x1368: 0x1741, 0x1369: 0x1769,\n\t0x136a: 0x1a81, 0x136b: 0x1a89, 0x136c: 0x1789, 0x136d: 0x1a91, 0x136e: 0x1791, 0x136f: 0x1799,\n\t0x1370: 0x1a99, 0x1371: 0x1aa1, 0x1372: 0x17b9, 0x1373: 0x1aa9, 0x1374: 0x17c1, 0x1375: 0x17c9,\n\t0x1376: 0x1ab1, 0x1377: 0x1ab9, 0x1378: 0x17d9, 0x1379: 0x1ac1, 0x137a: 0x17e1, 0x137b: 0x17e9,\n\t0x137c: 0x18d1, 0x137d: 0x18d9, 0x137e: 0x18f1, 0x137f: 0x18f9,\n\t// Block 0x4e, offset 0x1380\n\t0x1380: 0x1901, 0x1381: 0x1921, 0x1382: 0x1929, 0x1383: 0x1931, 0x1384: 0x1939, 0x1385: 0x1959,\n\t0x1386: 0x1961, 0x1387: 0x1969, 0x1388: 0x1ac9, 0x1389: 0x1989, 0x138a: 0x1ad1, 0x138b: 0x1ad9,\n\t0x138c: 0x19b9, 0x138d: 0x1ae1, 0x138e: 0x19c1, 0x138f: 0x19c9, 0x1390: 0x1a31, 0x1391: 0x1ae9,\n\t0x1392: 0x1af1, 0x1393: 0x1a09, 0x1394: 0x1af9, 0x1395: 0x1a11, 0x1396: 0x1a19, 0x1397: 0x1751,\n\t0x1398: 0x1759, 0x1399: 0x1b01, 0x139a: 0x1761, 0x139b: 0x1b09, 0x139c: 0x1771, 0x139d: 0x1779,\n\t0x139e: 0x1781, 0x139f: 0x1789, 0x13a0: 0x1b11, 0x13a1: 0x17a1, 0x13a2: 0x17a9, 0x13a3: 0x17b1,\n\t0x13a4: 0x17b9, 0x13a5: 0x1b19, 0x13a6: 0x17d9, 0x13a7: 0x17f1, 0x13a8: 0x17f9, 0x13a9: 0x1801,\n\t0x13aa: 0x1809, 0x13ab: 0x1811, 0x13ac: 0x1821, 0x13ad: 0x1829, 0x13ae: 0x1831, 0x13af: 0x1839,\n\t0x13b0: 0x1841, 0x13b1: 0x1849, 0x13b2: 0x1b21, 0x13b3: 0x1851, 0x13b4: 0x1859, 0x13b5: 0x1861,\n\t0x13b6: 0x1869, 0x13b7: 0x1871, 0x13b8: 0x1879, 0x13b9: 0x1889, 0x13ba: 0x1891, 0x13bb: 0x1899,\n\t0x13bc: 0x18a1, 0x13bd: 0x18a9, 0x13be: 0x18b1, 0x13bf: 0x18b9,\n\t// Block 0x4f, offset 0x13c0\n\t0x13c0: 0x18c1, 0x13c1: 0x18c9, 0x13c2: 0x18e1, 0x13c3: 0x18e9, 0x13c4: 0x1909, 0x13c5: 0x1911,\n\t0x13c6: 0x1919, 0x13c7: 0x1921, 0x13c8: 0x1929, 0x13c9: 0x1941, 0x13ca: 0x1949, 0x13cb: 0x1951,\n\t0x13cc: 0x1959, 0x13cd: 0x1b29, 0x13ce: 0x1971, 0x13cf: 0x1979, 0x13d0: 0x1981, 0x13d1: 0x1989,\n\t0x13d2: 0x19a1, 0x13d3: 0x19a9, 0x13d4: 0x19b1, 0x13d5: 0x19b9, 0x13d6: 0x1b31, 0x13d7: 0x19d1,\n\t0x13d8: 0x19d9, 0x13d9: 0x1b39, 0x13da: 0x19f1, 0x13db: 0x19f9, 0x13dc: 0x1a01, 0x13dd: 0x1a09,\n\t0x13de: 0x1b41, 0x13df: 0x1761, 0x13e0: 0x1b09, 0x13e1: 0x1789, 0x13e2: 0x1b11, 0x13e3: 0x17b9,\n\t0x13e4: 0x1b19, 0x13e5: 0x17d9, 0x13e6: 0x1b49, 0x13e7: 0x1841, 0x13e8: 0x1b51, 0x13e9: 0x1b59,\n\t0x13ea: 0x1b61, 0x13eb: 0x1921, 0x13ec: 0x1929, 0x13ed: 0x1959, 0x13ee: 0x19b9, 0x13ef: 0x1b31,\n\t0x13f0: 0x1a09, 0x13f1: 0x1b41, 0x13f2: 0x1b69, 0x13f3: 0x1b71, 0x13f4: 0x1b79, 0x13f5: 0x1b81,\n\t0x13f6: 0x1b89, 0x13f7: 0x1b91, 0x13f8: 0x1b99, 0x13f9: 0x1ba1, 0x13fa: 0x1ba9, 0x13fb: 0x1bb1,\n\t0x13fc: 0x1bb9, 0x13fd: 0x1bc1, 0x13fe: 0x1bc9, 0x13ff: 0x1bd1,\n\t// Block 0x50, offset 0x1400\n\t0x1400: 0x1bd9, 0x1401: 0x1be1, 0x1402: 0x1be9, 0x1403: 0x1bf1, 0x1404: 0x1bf9, 0x1405: 0x1c01,\n\t0x1406: 0x1c09, 0x1407: 0x1c11, 0x1408: 0x1c19, 0x1409: 0x1c21, 0x140a: 0x1c29, 0x140b: 0x1c31,\n\t0x140c: 0x1b59, 0x140d: 0x1c39, 0x140e: 0x1c41, 0x140f: 0x1c49, 0x1410: 0x1c51, 0x1411: 0x1b81,\n\t0x1412: 0x1b89, 0x1413: 0x1b91, 0x1414: 0x1b99, 0x1415: 0x1ba1, 0x1416: 0x1ba9, 0x1417: 0x1bb1,\n\t0x1418: 0x1bb9, 0x1419: 0x1bc1, 0x141a: 0x1bc9, 0x141b: 0x1bd1, 0x141c: 0x1bd9, 0x141d: 0x1be1,\n\t0x141e: 0x1be9, 0x141f: 0x1bf1, 0x1420: 0x1bf9, 0x1421: 0x1c01, 0x1422: 0x1c09, 0x1423: 0x1c11,\n\t0x1424: 0x1c19, 0x1425: 0x1c21, 0x1426: 0x1c29, 0x1427: 0x1c31, 0x1428: 0x1b59, 0x1429: 0x1c39,\n\t0x142a: 0x1c41, 0x142b: 0x1c49, 0x142c: 0x1c51, 0x142d: 0x1c21, 0x142e: 0x1c29, 0x142f: 0x1c31,\n\t0x1430: 0x1b59, 0x1431: 0x1b51, 0x1432: 0x1b61, 0x1433: 0x1881, 0x1434: 0x1829, 0x1435: 0x1831,\n\t0x1436: 0x1839, 0x1437: 0x1c21, 0x1438: 0x1c29, 0x1439: 0x1c31, 0x143a: 0x1881, 0x143b: 0x1889,\n\t0x143c: 0x1c59, 0x143d: 0x1c59, 0x143e: 0x0018, 0x143f: 0x0018,\n\t// Block 0x51, offset 0x1440\n\t0x1440: 0x0040, 0x1441: 0x0040, 0x1442: 0x0040, 0x1443: 0x0040, 0x1444: 0x0040, 0x1445: 0x0040,\n\t0x1446: 0x0040, 0x1447: 0x0040, 0x1448: 0x0040, 0x1449: 0x0040, 0x144a: 0x0040, 0x144b: 0x0040,\n\t0x144c: 0x0040, 0x144d: 0x0040, 0x144e: 0x0040, 0x144f: 0x0040, 0x1450: 0x1c61, 0x1451: 0x1c69,\n\t0x1452: 0x1c69, 0x1453: 0x1c71, 0x1454: 0x1c79, 0x1455: 0x1c81, 0x1456: 0x1c89, 0x1457: 0x1c91,\n\t0x1458: 0x1c99, 0x1459: 0x1c99, 0x145a: 0x1ca1, 0x145b: 0x1ca9, 0x145c: 0x1cb1, 0x145d: 0x1cb9,\n\t0x145e: 0x1cc1, 0x145f: 0x1cc9, 0x1460: 0x1cc9, 0x1461: 0x1cd1, 0x1462: 0x1cd9, 0x1463: 0x1cd9,\n\t0x1464: 0x1ce1, 0x1465: 0x1ce1, 0x1466: 0x1ce9, 0x1467: 0x1cf1, 0x1468: 0x1cf1, 0x1469: 0x1cf9,\n\t0x146a: 0x1d01, 0x146b: 0x1d01, 0x146c: 0x1d09, 0x146d: 0x1d09, 0x146e: 0x1d11, 0x146f: 0x1d19,\n\t0x1470: 0x1d19, 0x1471: 0x1d21, 0x1472: 0x1d21, 0x1473: 0x1d29, 0x1474: 0x1d31, 0x1475: 0x1d39,\n\t0x1476: 0x1d41, 0x1477: 0x1d41, 0x1478: 0x1d49, 0x1479: 0x1d51, 0x147a: 0x1d59, 0x147b: 0x1d61,\n\t0x147c: 0x1d69, 0x147d: 0x1d69, 0x147e: 0x1d71, 0x147f: 0x1d79,\n\t// Block 0x52, offset 0x1480\n\t0x1480: 0x1f29, 0x1481: 0x1f31, 0x1482: 0x1f39, 0x1483: 0x1f11, 0x1484: 0x1d39, 0x1485: 0x1ce9,\n\t0x1486: 0x1f41, 0x1487: 0x1f49, 0x1488: 0x0040, 0x1489: 0x0040, 0x148a: 0x0040, 0x148b: 0x0040,\n\t0x148c: 0x0040, 0x148d: 0x0040, 0x148e: 0x0040, 0x148f: 0x0040, 0x1490: 0x0040, 0x1491: 0x0040,\n\t0x1492: 0x0040, 0x1493: 0x0040, 0x1494: 0x0040, 0x1495: 0x0040, 0x1496: 0x0040, 0x1497: 0x0040,\n\t0x1498: 0x0040, 0x1499: 0x0040, 0x149a: 0x0040, 0x149b: 0x0040, 0x149c: 0x0040, 0x149d: 0x0040,\n\t0x149e: 0x0040, 0x149f: 0x0040, 0x14a0: 0x0040, 0x14a1: 0x0040, 0x14a2: 0x0040, 0x14a3: 0x0040,\n\t0x14a4: 0x0040, 0x14a5: 0x0040, 0x14a6: 0x0040, 0x14a7: 0x0040, 0x14a8: 0x0040, 0x14a9: 0x0040,\n\t0x14aa: 0x0040, 0x14ab: 0x0040, 0x14ac: 0x0040, 0x14ad: 0x0040, 0x14ae: 0x0040, 0x14af: 0x0040,\n\t0x14b0: 0x1f51, 0x14b1: 0x1f59, 0x14b2: 0x1f61, 0x14b3: 0x1f69, 0x14b4: 0x1f71, 0x14b5: 0x1f79,\n\t0x14b6: 0x1f81, 0x14b7: 0x1f89, 0x14b8: 0x1f91, 0x14b9: 0x1f99, 0x14ba: 0x1fa2, 0x14bb: 0x1faa,\n\t0x14bc: 0x1fb1, 0x14bd: 0x0018, 0x14be: 0x0040, 0x14bf: 0x0040,\n\t// Block 0x53, offset 0x14c0\n\t0x14c0: 0x33c0, 0x14c1: 0x33c0, 0x14c2: 0x33c0, 0x14c3: 0x33c0, 0x14c4: 0x33c0, 0x14c5: 0x33c0,\n\t0x14c6: 0x33c0, 0x14c7: 0x33c0, 0x14c8: 0x33c0, 0x14c9: 0x33c0, 0x14ca: 0x33c0, 0x14cb: 0x33c0,\n\t0x14cc: 0x33c0, 0x14cd: 0x33c0, 0x14ce: 0x33c0, 0x14cf: 0x33c0, 0x14d0: 0x1fba, 0x14d1: 0x7d8d,\n\t0x14d2: 0x0040, 0x14d3: 0x1fc2, 0x14d4: 0x0122, 0x14d5: 0x1fca, 0x14d6: 0x1fd2, 0x14d7: 0x7dad,\n\t0x14d8: 0x7dcd, 0x14d9: 0x0040, 0x14da: 0x0040, 0x14db: 0x0040, 0x14dc: 0x0040, 0x14dd: 0x0040,\n\t0x14de: 0x0040, 0x14df: 0x0040, 0x14e0: 0x3308, 0x14e1: 0x3308, 0x14e2: 0x3308, 0x14e3: 0x3308,\n\t0x14e4: 0x3308, 0x14e5: 0x3308, 0x14e6: 0x3308, 0x14e7: 0x3308, 0x14e8: 0x3308, 0x14e9: 0x3308,\n\t0x14ea: 0x3308, 0x14eb: 0x3308, 0x14ec: 0x3308, 0x14ed: 0x3308, 0x14ee: 0x3308, 0x14ef: 0x3308,\n\t0x14f0: 0x0040, 0x14f1: 0x7ded, 0x14f2: 0x7e0d, 0x14f3: 0x1fda, 0x14f4: 0x1fda, 0x14f5: 0x072a,\n\t0x14f6: 0x0732, 0x14f7: 0x1fe2, 0x14f8: 0x1fea, 0x14f9: 0x7e2d, 0x14fa: 0x7e4d, 0x14fb: 0x7e6d,\n\t0x14fc: 0x7e2d, 0x14fd: 0x7e8d, 0x14fe: 0x7ead, 0x14ff: 0x7e8d,\n\t// Block 0x54, offset 0x1500\n\t0x1500: 0x7ecd, 0x1501: 0x7eed, 0x1502: 0x7f0d, 0x1503: 0x7eed, 0x1504: 0x7f2d, 0x1505: 0x0018,\n\t0x1506: 0x0018, 0x1507: 0x1ff2, 0x1508: 0x1ffa, 0x1509: 0x7f4e, 0x150a: 0x7f6e, 0x150b: 0x7f8e,\n\t0x150c: 0x7fae, 0x150d: 0x1fda, 0x150e: 0x1fda, 0x150f: 0x1fda, 0x1510: 0x1fba, 0x1511: 0x7fcd,\n\t0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x0122, 0x1515: 0x1fc2, 0x1516: 0x1fd2, 0x1517: 0x1fca,\n\t0x1518: 0x7fed, 0x1519: 0x072a, 0x151a: 0x0732, 0x151b: 0x1fe2, 0x151c: 0x1fea, 0x151d: 0x7ecd,\n\t0x151e: 0x7f2d, 0x151f: 0x2002, 0x1520: 0x200a, 0x1521: 0x2012, 0x1522: 0x071a, 0x1523: 0x2019,\n\t0x1524: 0x2022, 0x1525: 0x202a, 0x1526: 0x0722, 0x1527: 0x0040, 0x1528: 0x2032, 0x1529: 0x203a,\n\t0x152a: 0x2042, 0x152b: 0x204a, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040,\n\t0x1530: 0x800e, 0x1531: 0x2051, 0x1532: 0x802e, 0x1533: 0x0808, 0x1534: 0x804e, 0x1535: 0x0040,\n\t0x1536: 0x806e, 0x1537: 0x2059, 0x1538: 0x808e, 0x1539: 0x2061, 0x153a: 0x80ae, 0x153b: 0x2069,\n\t0x153c: 0x80ce, 0x153d: 0x2071, 0x153e: 0x80ee, 0x153f: 0x2079,\n\t// Block 0x55, offset 0x1540\n\t0x1540: 0x2081, 0x1541: 0x2089, 0x1542: 0x2089, 0x1543: 0x2091, 0x1544: 0x2091, 0x1545: 0x2099,\n\t0x1546: 0x2099, 0x1547: 0x20a1, 0x1548: 0x20a1, 0x1549: 0x20a9, 0x154a: 0x20a9, 0x154b: 0x20a9,\n\t0x154c: 0x20a9, 0x154d: 0x20b1, 0x154e: 0x20b1, 0x154f: 0x20b9, 0x1550: 0x20b9, 0x1551: 0x20b9,\n\t0x1552: 0x20b9, 0x1553: 0x20c1, 0x1554: 0x20c1, 0x1555: 0x20c9, 0x1556: 0x20c9, 0x1557: 0x20c9,\n\t0x1558: 0x20c9, 0x1559: 0x20d1, 0x155a: 0x20d1, 0x155b: 0x20d1, 0x155c: 0x20d1, 0x155d: 0x20d9,\n\t0x155e: 0x20d9, 0x155f: 0x20d9, 0x1560: 0x20d9, 0x1561: 0x20e1, 0x1562: 0x20e1, 0x1563: 0x20e1,\n\t0x1564: 0x20e1, 0x1565: 0x20e9, 0x1566: 0x20e9, 0x1567: 0x20e9, 0x1568: 0x20e9, 0x1569: 0x20f1,\n\t0x156a: 0x20f1, 0x156b: 0x20f9, 0x156c: 0x20f9, 0x156d: 0x2101, 0x156e: 0x2101, 0x156f: 0x2109,\n\t0x1570: 0x2109, 0x1571: 0x2111, 0x1572: 0x2111, 0x1573: 0x2111, 0x1574: 0x2111, 0x1575: 0x2119,\n\t0x1576: 0x2119, 0x1577: 0x2119, 0x1578: 0x2119, 0x1579: 0x2121, 0x157a: 0x2121, 0x157b: 0x2121,\n\t0x157c: 0x2121, 0x157d: 0x2129, 0x157e: 0x2129, 0x157f: 0x2129,\n\t// Block 0x56, offset 0x1580\n\t0x1580: 0x2129, 0x1581: 0x2131, 0x1582: 0x2131, 0x1583: 0x2131, 0x1584: 0x2131, 0x1585: 0x2139,\n\t0x1586: 0x2139, 0x1587: 0x2139, 0x1588: 0x2139, 0x1589: 0x2141, 0x158a: 0x2141, 0x158b: 0x2141,\n\t0x158c: 0x2141, 0x158d: 0x2149, 0x158e: 0x2149, 0x158f: 0x2149, 0x1590: 0x2149, 0x1591: 0x2151,\n\t0x1592: 0x2151, 0x1593: 0x2151, 0x1594: 0x2151, 0x1595: 0x2159, 0x1596: 0x2159, 0x1597: 0x2159,\n\t0x1598: 0x2159, 0x1599: 0x2161, 0x159a: 0x2161, 0x159b: 0x2161, 0x159c: 0x2161, 0x159d: 0x2169,\n\t0x159e: 0x2169, 0x159f: 0x2169, 0x15a0: 0x2169, 0x15a1: 0x2171, 0x15a2: 0x2171, 0x15a3: 0x2171,\n\t0x15a4: 0x2171, 0x15a5: 0x2179, 0x15a6: 0x2179, 0x15a7: 0x2179, 0x15a8: 0x2179, 0x15a9: 0x2181,\n\t0x15aa: 0x2181, 0x15ab: 0x2181, 0x15ac: 0x2181, 0x15ad: 0x2189, 0x15ae: 0x2189, 0x15af: 0x1701,\n\t0x15b0: 0x1701, 0x15b1: 0x2191, 0x15b2: 0x2191, 0x15b3: 0x2191, 0x15b4: 0x2191, 0x15b5: 0x2199,\n\t0x15b6: 0x2199, 0x15b7: 0x21a1, 0x15b8: 0x21a1, 0x15b9: 0x21a9, 0x15ba: 0x21a9, 0x15bb: 0x21b1,\n\t0x15bc: 0x21b1, 0x15bd: 0x0040, 0x15be: 0x0040, 0x15bf: 0x03c0,\n\t// Block 0x57, offset 0x15c0\n\t0x15c0: 0x0040, 0x15c1: 0x1fca, 0x15c2: 0x21ba, 0x15c3: 0x2002, 0x15c4: 0x203a, 0x15c5: 0x2042,\n\t0x15c6: 0x200a, 0x15c7: 0x21c2, 0x15c8: 0x072a, 0x15c9: 0x0732, 0x15ca: 0x2012, 0x15cb: 0x071a,\n\t0x15cc: 0x1fba, 0x15cd: 0x2019, 0x15ce: 0x0961, 0x15cf: 0x21ca, 0x15d0: 0x06e1, 0x15d1: 0x0049,\n\t0x15d2: 0x0029, 0x15d3: 0x0031, 0x15d4: 0x06e9, 0x15d5: 0x06f1, 0x15d6: 0x06f9, 0x15d7: 0x0701,\n\t0x15d8: 0x0709, 0x15d9: 0x0711, 0x15da: 0x1fc2, 0x15db: 0x0122, 0x15dc: 0x2022, 0x15dd: 0x0722,\n\t0x15de: 0x202a, 0x15df: 0x1fd2, 0x15e0: 0x204a, 0x15e1: 0x0019, 0x15e2: 0x02e9, 0x15e3: 0x03d9,\n\t0x15e4: 0x02f1, 0x15e5: 0x02f9, 0x15e6: 0x03f1, 0x15e7: 0x0309, 0x15e8: 0x00a9, 0x15e9: 0x0311,\n\t0x15ea: 0x00b1, 0x15eb: 0x0319, 0x15ec: 0x0101, 0x15ed: 0x0321, 0x15ee: 0x0329, 0x15ef: 0x0051,\n\t0x15f0: 0x0339, 0x15f1: 0x0751, 0x15f2: 0x00b9, 0x15f3: 0x0089, 0x15f4: 0x0341, 0x15f5: 0x0349,\n\t0x15f6: 0x0391, 0x15f7: 0x00c1, 0x15f8: 0x0109, 0x15f9: 0x00c9, 0x15fa: 0x04b1, 0x15fb: 0x1ff2,\n\t0x15fc: 0x2032, 0x15fd: 0x1ffa, 0x15fe: 0x21d2, 0x15ff: 0x1fda,\n\t// Block 0x58, offset 0x1600\n\t0x1600: 0x0672, 0x1601: 0x0019, 0x1602: 0x02e9, 0x1603: 0x03d9, 0x1604: 0x02f1, 0x1605: 0x02f9,\n\t0x1606: 0x03f1, 0x1607: 0x0309, 0x1608: 0x00a9, 0x1609: 0x0311, 0x160a: 0x00b1, 0x160b: 0x0319,\n\t0x160c: 0x0101, 0x160d: 0x0321, 0x160e: 0x0329, 0x160f: 0x0051, 0x1610: 0x0339, 0x1611: 0x0751,\n\t0x1612: 0x00b9, 0x1613: 0x0089, 0x1614: 0x0341, 0x1615: 0x0349, 0x1616: 0x0391, 0x1617: 0x00c1,\n\t0x1618: 0x0109, 0x1619: 0x00c9, 0x161a: 0x04b1, 0x161b: 0x1fe2, 0x161c: 0x21da, 0x161d: 0x1fea,\n\t0x161e: 0x21e2, 0x161f: 0x810d, 0x1620: 0x812d, 0x1621: 0x0961, 0x1622: 0x814d, 0x1623: 0x814d,\n\t0x1624: 0x816d, 0x1625: 0x818d, 0x1626: 0x81ad, 0x1627: 0x81cd, 0x1628: 0x81ed, 0x1629: 0x820d,\n\t0x162a: 0x822d, 0x162b: 0x824d, 0x162c: 0x826d, 0x162d: 0x828d, 0x162e: 0x82ad, 0x162f: 0x82cd,\n\t0x1630: 0x82ed, 0x1631: 0x830d, 0x1632: 0x832d, 0x1633: 0x834d, 0x1634: 0x836d, 0x1635: 0x838d,\n\t0x1636: 0x83ad, 0x1637: 0x83cd, 0x1638: 0x83ed, 0x1639: 0x840d, 0x163a: 0x842d, 0x163b: 0x844d,\n\t0x163c: 0x81ed, 0x163d: 0x846d, 0x163e: 0x848d, 0x163f: 0x824d,\n\t// Block 0x59, offset 0x1640\n\t0x1640: 0x84ad, 0x1641: 0x84cd, 0x1642: 0x84ed, 0x1643: 0x850d, 0x1644: 0x852d, 0x1645: 0x854d,\n\t0x1646: 0x856d, 0x1647: 0x858d, 0x1648: 0x850d, 0x1649: 0x85ad, 0x164a: 0x850d, 0x164b: 0x85cd,\n\t0x164c: 0x85cd, 0x164d: 0x85ed, 0x164e: 0x85ed, 0x164f: 0x860d, 0x1650: 0x854d, 0x1651: 0x862d,\n\t0x1652: 0x864d, 0x1653: 0x862d, 0x1654: 0x866d, 0x1655: 0x864d, 0x1656: 0x868d, 0x1657: 0x868d,\n\t0x1658: 0x86ad, 0x1659: 0x86ad, 0x165a: 0x86cd, 0x165b: 0x86cd, 0x165c: 0x864d, 0x165d: 0x814d,\n\t0x165e: 0x86ed, 0x165f: 0x870d, 0x1660: 0x0040, 0x1661: 0x872d, 0x1662: 0x874d, 0x1663: 0x876d,\n\t0x1664: 0x878d, 0x1665: 0x876d, 0x1666: 0x87ad, 0x1667: 0x87cd, 0x1668: 0x87ed, 0x1669: 0x87ed,\n\t0x166a: 0x880d, 0x166b: 0x880d, 0x166c: 0x882d, 0x166d: 0x882d, 0x166e: 0x880d, 0x166f: 0x880d,\n\t0x1670: 0x884d, 0x1671: 0x886d, 0x1672: 0x888d, 0x1673: 0x88ad, 0x1674: 0x88cd, 0x1675: 0x88ed,\n\t0x1676: 0x88ed, 0x1677: 0x88ed, 0x1678: 0x890d, 0x1679: 0x890d, 0x167a: 0x890d, 0x167b: 0x890d,\n\t0x167c: 0x87ed, 0x167d: 0x87ed, 0x167e: 0x87ed, 0x167f: 0x0040,\n\t// Block 0x5a, offset 0x1680\n\t0x1680: 0x0040, 0x1681: 0x0040, 0x1682: 0x874d, 0x1683: 0x872d, 0x1684: 0x892d, 0x1685: 0x872d,\n\t0x1686: 0x874d, 0x1687: 0x872d, 0x1688: 0x0040, 0x1689: 0x0040, 0x168a: 0x894d, 0x168b: 0x874d,\n\t0x168c: 0x896d, 0x168d: 0x892d, 0x168e: 0x896d, 0x168f: 0x874d, 0x1690: 0x0040, 0x1691: 0x0040,\n\t0x1692: 0x898d, 0x1693: 0x89ad, 0x1694: 0x88ad, 0x1695: 0x896d, 0x1696: 0x892d, 0x1697: 0x896d,\n\t0x1698: 0x0040, 0x1699: 0x0040, 0x169a: 0x89cd, 0x169b: 0x89ed, 0x169c: 0x89cd, 0x169d: 0x0040,\n\t0x169e: 0x0040, 0x169f: 0x0040, 0x16a0: 0x21e9, 0x16a1: 0x21f1, 0x16a2: 0x21f9, 0x16a3: 0x8a0e,\n\t0x16a4: 0x2201, 0x16a5: 0x2209, 0x16a6: 0x8a2d, 0x16a7: 0x0040, 0x16a8: 0x8a4d, 0x16a9: 0x8a6d,\n\t0x16aa: 0x8a8d, 0x16ab: 0x8a6d, 0x16ac: 0x8aad, 0x16ad: 0x8acd, 0x16ae: 0x8aed, 0x16af: 0x0040,\n\t0x16b0: 0x0040, 0x16b1: 0x0040, 0x16b2: 0x0040, 0x16b3: 0x0040, 0x16b4: 0x0040, 0x16b5: 0x0040,\n\t0x16b6: 0x0040, 0x16b7: 0x0040, 0x16b8: 0x0040, 0x16b9: 0x0340, 0x16ba: 0x0340, 0x16bb: 0x0340,\n\t0x16bc: 0x0040, 0x16bd: 0x0040, 0x16be: 0x0040, 0x16bf: 0x0040,\n\t// Block 0x5b, offset 0x16c0\n\t0x16c0: 0x0a08, 0x16c1: 0x0a08, 0x16c2: 0x0a08, 0x16c3: 0x0a08, 0x16c4: 0x0a08, 0x16c5: 0x0c08,\n\t0x16c6: 0x0808, 0x16c7: 0x0c08, 0x16c8: 0x0818, 0x16c9: 0x0c08, 0x16ca: 0x0c08, 0x16cb: 0x0808,\n\t0x16cc: 0x0808, 0x16cd: 0x0908, 0x16ce: 0x0c08, 0x16cf: 0x0c08, 0x16d0: 0x0c08, 0x16d1: 0x0c08,\n\t0x16d2: 0x0c08, 0x16d3: 0x0a08, 0x16d4: 0x0a08, 0x16d5: 0x0a08, 0x16d6: 0x0a08, 0x16d7: 0x0908,\n\t0x16d8: 0x0a08, 0x16d9: 0x0a08, 0x16da: 0x0a08, 0x16db: 0x0a08, 0x16dc: 0x0a08, 0x16dd: 0x0c08,\n\t0x16de: 0x0a08, 0x16df: 0x0a08, 0x16e0: 0x0a08, 0x16e1: 0x0c08, 0x16e2: 0x0808, 0x16e3: 0x0808,\n\t0x16e4: 0x0c08, 0x16e5: 0x3308, 0x16e6: 0x3308, 0x16e7: 0x0040, 0x16e8: 0x0040, 0x16e9: 0x0040,\n\t0x16ea: 0x0040, 0x16eb: 0x0a18, 0x16ec: 0x0a18, 0x16ed: 0x0a18, 0x16ee: 0x0a18, 0x16ef: 0x0c18,\n\t0x16f0: 0x0818, 0x16f1: 0x0818, 0x16f2: 0x0818, 0x16f3: 0x0818, 0x16f4: 0x0818, 0x16f5: 0x0818,\n\t0x16f6: 0x0818, 0x16f7: 0x0040, 0x16f8: 0x0040, 0x16f9: 0x0040, 0x16fa: 0x0040, 0x16fb: 0x0040,\n\t0x16fc: 0x0040, 0x16fd: 0x0040, 0x16fe: 0x0040, 0x16ff: 0x0040,\n\t// Block 0x5c, offset 0x1700\n\t0x1700: 0x0a08, 0x1701: 0x0c08, 0x1702: 0x0a08, 0x1703: 0x0c08, 0x1704: 0x0c08, 0x1705: 0x0c08,\n\t0x1706: 0x0a08, 0x1707: 0x0a08, 0x1708: 0x0a08, 0x1709: 0x0c08, 0x170a: 0x0a08, 0x170b: 0x0a08,\n\t0x170c: 0x0c08, 0x170d: 0x0a08, 0x170e: 0x0c08, 0x170f: 0x0c08, 0x1710: 0x0a08, 0x1711: 0x0c08,\n\t0x1712: 0x0040, 0x1713: 0x0040, 0x1714: 0x0040, 0x1715: 0x0040, 0x1716: 0x0040, 0x1717: 0x0040,\n\t0x1718: 0x0040, 0x1719: 0x0818, 0x171a: 0x0818, 0x171b: 0x0818, 0x171c: 0x0818, 0x171d: 0x0040,\n\t0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0x0040, 0x1721: 0x0040, 0x1722: 0x0040, 0x1723: 0x0040,\n\t0x1724: 0x0040, 0x1725: 0x0040, 0x1726: 0x0040, 0x1727: 0x0040, 0x1728: 0x0040, 0x1729: 0x0c18,\n\t0x172a: 0x0c18, 0x172b: 0x0c18, 0x172c: 0x0c18, 0x172d: 0x0a18, 0x172e: 0x0a18, 0x172f: 0x0818,\n\t0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040,\n\t0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0040, 0x173a: 0x0040, 0x173b: 0x0040,\n\t0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040,\n\t// Block 0x5d, offset 0x1740\n\t0x1740: 0x3308, 0x1741: 0x3308, 0x1742: 0x3008, 0x1743: 0x3008, 0x1744: 0x0040, 0x1745: 0x0008,\n\t0x1746: 0x0008, 0x1747: 0x0008, 0x1748: 0x0008, 0x1749: 0x0008, 0x174a: 0x0008, 0x174b: 0x0008,\n\t0x174c: 0x0008, 0x174d: 0x0040, 0x174e: 0x0040, 0x174f: 0x0008, 0x1750: 0x0008, 0x1751: 0x0040,\n\t0x1752: 0x0040, 0x1753: 0x0008, 0x1754: 0x0008, 0x1755: 0x0008, 0x1756: 0x0008, 0x1757: 0x0008,\n\t0x1758: 0x0008, 0x1759: 0x0008, 0x175a: 0x0008, 0x175b: 0x0008, 0x175c: 0x0008, 0x175d: 0x0008,\n\t0x175e: 0x0008, 0x175f: 0x0008, 0x1760: 0x0008, 0x1761: 0x0008, 0x1762: 0x0008, 0x1763: 0x0008,\n\t0x1764: 0x0008, 0x1765: 0x0008, 0x1766: 0x0008, 0x1767: 0x0008, 0x1768: 0x0008, 0x1769: 0x0040,\n\t0x176a: 0x0008, 0x176b: 0x0008, 0x176c: 0x0008, 0x176d: 0x0008, 0x176e: 0x0008, 0x176f: 0x0008,\n\t0x1770: 0x0008, 0x1771: 0x0040, 0x1772: 0x0008, 0x1773: 0x0008, 0x1774: 0x0040, 0x1775: 0x0008,\n\t0x1776: 0x0008, 0x1777: 0x0008, 0x1778: 0x0008, 0x1779: 0x0008, 0x177a: 0x0040, 0x177b: 0x3308,\n\t0x177c: 0x3308, 0x177d: 0x0008, 0x177e: 0x3008, 0x177f: 0x3008,\n\t// Block 0x5e, offset 0x1780\n\t0x1780: 0x3308, 0x1781: 0x3008, 0x1782: 0x3008, 0x1783: 0x3008, 0x1784: 0x3008, 0x1785: 0x0040,\n\t0x1786: 0x0040, 0x1787: 0x3008, 0x1788: 0x3008, 0x1789: 0x0040, 0x178a: 0x0040, 0x178b: 0x3008,\n\t0x178c: 0x3008, 0x178d: 0x3808, 0x178e: 0x0040, 0x178f: 0x0040, 0x1790: 0x0008, 0x1791: 0x0040,\n\t0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x3008,\n\t0x1798: 0x0040, 0x1799: 0x0040, 0x179a: 0x0040, 0x179b: 0x0040, 0x179c: 0x0040, 0x179d: 0x0008,\n\t0x179e: 0x0008, 0x179f: 0x0008, 0x17a0: 0x0008, 0x17a1: 0x0008, 0x17a2: 0x3008, 0x17a3: 0x3008,\n\t0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x3308, 0x17a7: 0x3308, 0x17a8: 0x3308, 0x17a9: 0x3308,\n\t0x17aa: 0x3308, 0x17ab: 0x3308, 0x17ac: 0x3308, 0x17ad: 0x0040, 0x17ae: 0x0040, 0x17af: 0x0040,\n\t0x17b0: 0x3308, 0x17b1: 0x3308, 0x17b2: 0x3308, 0x17b3: 0x3308, 0x17b4: 0x3308, 0x17b5: 0x0040,\n\t0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040,\n\t0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040,\n\t// Block 0x5f, offset 0x17c0\n\t0x17c0: 0x0008, 0x17c1: 0x0008, 0x17c2: 0x0008, 0x17c3: 0x0008, 0x17c4: 0x0008, 0x17c5: 0x0008,\n\t0x17c6: 0x0008, 0x17c7: 0x0040, 0x17c8: 0x0040, 0x17c9: 0x0008, 0x17ca: 0x0040, 0x17cb: 0x0040,\n\t0x17cc: 0x0008, 0x17cd: 0x0008, 0x17ce: 0x0008, 0x17cf: 0x0008, 0x17d0: 0x0008, 0x17d1: 0x0008,\n\t0x17d2: 0x0008, 0x17d3: 0x0008, 0x17d4: 0x0040, 0x17d5: 0x0008, 0x17d6: 0x0008, 0x17d7: 0x0040,\n\t0x17d8: 0x0008, 0x17d9: 0x0008, 0x17da: 0x0008, 0x17db: 0x0008, 0x17dc: 0x0008, 0x17dd: 0x0008,\n\t0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x0008, 0x17e3: 0x0008,\n\t0x17e4: 0x0008, 0x17e5: 0x0008, 0x17e6: 0x0008, 0x17e7: 0x0008, 0x17e8: 0x0008, 0x17e9: 0x0008,\n\t0x17ea: 0x0008, 0x17eb: 0x0008, 0x17ec: 0x0008, 0x17ed: 0x0008, 0x17ee: 0x0008, 0x17ef: 0x0008,\n\t0x17f0: 0x3008, 0x17f1: 0x3008, 0x17f2: 0x3008, 0x17f3: 0x3008, 0x17f4: 0x3008, 0x17f5: 0x3008,\n\t0x17f6: 0x0040, 0x17f7: 0x3008, 0x17f8: 0x3008, 0x17f9: 0x0040, 0x17fa: 0x0040, 0x17fb: 0x3308,\n\t0x17fc: 0x3308, 0x17fd: 0x3808, 0x17fe: 0x3b08, 0x17ff: 0x0008,\n\t// Block 0x60, offset 0x1800\n\t0x1800: 0x0019, 0x1801: 0x02e9, 0x1802: 0x03d9, 0x1803: 0x02f1, 0x1804: 0x02f9, 0x1805: 0x03f1,\n\t0x1806: 0x0309, 0x1807: 0x00a9, 0x1808: 0x0311, 0x1809: 0x00b1, 0x180a: 0x0319, 0x180b: 0x0101,\n\t0x180c: 0x0321, 0x180d: 0x0329, 0x180e: 0x0051, 0x180f: 0x0339, 0x1810: 0x0751, 0x1811: 0x00b9,\n\t0x1812: 0x0089, 0x1813: 0x0341, 0x1814: 0x0349, 0x1815: 0x0391, 0x1816: 0x00c1, 0x1817: 0x0109,\n\t0x1818: 0x00c9, 0x1819: 0x04b1, 0x181a: 0x0019, 0x181b: 0x02e9, 0x181c: 0x03d9, 0x181d: 0x02f1,\n\t0x181e: 0x02f9, 0x181f: 0x03f1, 0x1820: 0x0309, 0x1821: 0x00a9, 0x1822: 0x0311, 0x1823: 0x00b1,\n\t0x1824: 0x0319, 0x1825: 0x0101, 0x1826: 0x0321, 0x1827: 0x0329, 0x1828: 0x0051, 0x1829: 0x0339,\n\t0x182a: 0x0751, 0x182b: 0x00b9, 0x182c: 0x0089, 0x182d: 0x0341, 0x182e: 0x0349, 0x182f: 0x0391,\n\t0x1830: 0x00c1, 0x1831: 0x0109, 0x1832: 0x00c9, 0x1833: 0x04b1, 0x1834: 0x0019, 0x1835: 0x02e9,\n\t0x1836: 0x03d9, 0x1837: 0x02f1, 0x1838: 0x02f9, 0x1839: 0x03f1, 0x183a: 0x0309, 0x183b: 0x00a9,\n\t0x183c: 0x0311, 0x183d: 0x00b1, 0x183e: 0x0319, 0x183f: 0x0101,\n\t// Block 0x61, offset 0x1840\n\t0x1840: 0x0321, 0x1841: 0x0329, 0x1842: 0x0051, 0x1843: 0x0339, 0x1844: 0x0751, 0x1845: 0x00b9,\n\t0x1846: 0x0089, 0x1847: 0x0341, 0x1848: 0x0349, 0x1849: 0x0391, 0x184a: 0x00c1, 0x184b: 0x0109,\n\t0x184c: 0x00c9, 0x184d: 0x04b1, 0x184e: 0x0019, 0x184f: 0x02e9, 0x1850: 0x03d9, 0x1851: 0x02f1,\n\t0x1852: 0x02f9, 0x1853: 0x03f1, 0x1854: 0x0309, 0x1855: 0x0040, 0x1856: 0x0311, 0x1857: 0x00b1,\n\t0x1858: 0x0319, 0x1859: 0x0101, 0x185a: 0x0321, 0x185b: 0x0329, 0x185c: 0x0051, 0x185d: 0x0339,\n\t0x185e: 0x0751, 0x185f: 0x00b9, 0x1860: 0x0089, 0x1861: 0x0341, 0x1862: 0x0349, 0x1863: 0x0391,\n\t0x1864: 0x00c1, 0x1865: 0x0109, 0x1866: 0x00c9, 0x1867: 0x04b1, 0x1868: 0x0019, 0x1869: 0x02e9,\n\t0x186a: 0x03d9, 0x186b: 0x02f1, 0x186c: 0x02f9, 0x186d: 0x03f1, 0x186e: 0x0309, 0x186f: 0x00a9,\n\t0x1870: 0x0311, 0x1871: 0x00b1, 0x1872: 0x0319, 0x1873: 0x0101, 0x1874: 0x0321, 0x1875: 0x0329,\n\t0x1876: 0x0051, 0x1877: 0x0339, 0x1878: 0x0751, 0x1879: 0x00b9, 0x187a: 0x0089, 0x187b: 0x0341,\n\t0x187c: 0x0349, 0x187d: 0x0391, 0x187e: 0x00c1, 0x187f: 0x0109,\n\t// Block 0x62, offset 0x1880\n\t0x1880: 0x00c9, 0x1881: 0x04b1, 0x1882: 0x0019, 0x1883: 0x02e9, 0x1884: 0x03d9, 0x1885: 0x02f1,\n\t0x1886: 0x02f9, 0x1887: 0x03f1, 0x1888: 0x0309, 0x1889: 0x00a9, 0x188a: 0x0311, 0x188b: 0x00b1,\n\t0x188c: 0x0319, 0x188d: 0x0101, 0x188e: 0x0321, 0x188f: 0x0329, 0x1890: 0x0051, 0x1891: 0x0339,\n\t0x1892: 0x0751, 0x1893: 0x00b9, 0x1894: 0x0089, 0x1895: 0x0341, 0x1896: 0x0349, 0x1897: 0x0391,\n\t0x1898: 0x00c1, 0x1899: 0x0109, 0x189a: 0x00c9, 0x189b: 0x04b1, 0x189c: 0x0019, 0x189d: 0x0040,\n\t0x189e: 0x03d9, 0x189f: 0x02f1, 0x18a0: 0x0040, 0x18a1: 0x0040, 0x18a2: 0x0309, 0x18a3: 0x0040,\n\t0x18a4: 0x0040, 0x18a5: 0x00b1, 0x18a6: 0x0319, 0x18a7: 0x0040, 0x18a8: 0x0040, 0x18a9: 0x0329,\n\t0x18aa: 0x0051, 0x18ab: 0x0339, 0x18ac: 0x0751, 0x18ad: 0x0040, 0x18ae: 0x0089, 0x18af: 0x0341,\n\t0x18b0: 0x0349, 0x18b1: 0x0391, 0x18b2: 0x00c1, 0x18b3: 0x0109, 0x18b4: 0x00c9, 0x18b5: 0x04b1,\n\t0x18b6: 0x0019, 0x18b7: 0x02e9, 0x18b8: 0x03d9, 0x18b9: 0x02f1, 0x18ba: 0x0040, 0x18bb: 0x03f1,\n\t0x18bc: 0x0040, 0x18bd: 0x00a9, 0x18be: 0x0311, 0x18bf: 0x00b1,\n\t// Block 0x63, offset 0x18c0\n\t0x18c0: 0x0319, 0x18c1: 0x0101, 0x18c2: 0x0321, 0x18c3: 0x0329, 0x18c4: 0x0040, 0x18c5: 0x0339,\n\t0x18c6: 0x0751, 0x18c7: 0x00b9, 0x18c8: 0x0089, 0x18c9: 0x0341, 0x18ca: 0x0349, 0x18cb: 0x0391,\n\t0x18cc: 0x00c1, 0x18cd: 0x0109, 0x18ce: 0x00c9, 0x18cf: 0x04b1, 0x18d0: 0x0019, 0x18d1: 0x02e9,\n\t0x18d2: 0x03d9, 0x18d3: 0x02f1, 0x18d4: 0x02f9, 0x18d5: 0x03f1, 0x18d6: 0x0309, 0x18d7: 0x00a9,\n\t0x18d8: 0x0311, 0x18d9: 0x00b1, 0x18da: 0x0319, 0x18db: 0x0101, 0x18dc: 0x0321, 0x18dd: 0x0329,\n\t0x18de: 0x0051, 0x18df: 0x0339, 0x18e0: 0x0751, 0x18e1: 0x00b9, 0x18e2: 0x0089, 0x18e3: 0x0341,\n\t0x18e4: 0x0349, 0x18e5: 0x0391, 0x18e6: 0x00c1, 0x18e7: 0x0109, 0x18e8: 0x00c9, 0x18e9: 0x04b1,\n\t0x18ea: 0x0019, 0x18eb: 0x02e9, 0x18ec: 0x03d9, 0x18ed: 0x02f1, 0x18ee: 0x02f9, 0x18ef: 0x03f1,\n\t0x18f0: 0x0309, 0x18f1: 0x00a9, 0x18f2: 0x0311, 0x18f3: 0x00b1, 0x18f4: 0x0319, 0x18f5: 0x0101,\n\t0x18f6: 0x0321, 0x18f7: 0x0329, 0x18f8: 0x0051, 0x18f9: 0x0339, 0x18fa: 0x0751, 0x18fb: 0x00b9,\n\t0x18fc: 0x0089, 0x18fd: 0x0341, 0x18fe: 0x0349, 0x18ff: 0x0391,\n\t// Block 0x64, offset 0x1900\n\t0x1900: 0x00c1, 0x1901: 0x0109, 0x1902: 0x00c9, 0x1903: 0x04b1, 0x1904: 0x0019, 0x1905: 0x02e9,\n\t0x1906: 0x0040, 0x1907: 0x02f1, 0x1908: 0x02f9, 0x1909: 0x03f1, 0x190a: 0x0309, 0x190b: 0x0040,\n\t0x190c: 0x0040, 0x190d: 0x00b1, 0x190e: 0x0319, 0x190f: 0x0101, 0x1910: 0x0321, 0x1911: 0x0329,\n\t0x1912: 0x0051, 0x1913: 0x0339, 0x1914: 0x0751, 0x1915: 0x0040, 0x1916: 0x0089, 0x1917: 0x0341,\n\t0x1918: 0x0349, 0x1919: 0x0391, 0x191a: 0x00c1, 0x191b: 0x0109, 0x191c: 0x00c9, 0x191d: 0x0040,\n\t0x191e: 0x0019, 0x191f: 0x02e9, 0x1920: 0x03d9, 0x1921: 0x02f1, 0x1922: 0x02f9, 0x1923: 0x03f1,\n\t0x1924: 0x0309, 0x1925: 0x00a9, 0x1926: 0x0311, 0x1927: 0x00b1, 0x1928: 0x0319, 0x1929: 0x0101,\n\t0x192a: 0x0321, 0x192b: 0x0329, 0x192c: 0x0051, 0x192d: 0x0339, 0x192e: 0x0751, 0x192f: 0x00b9,\n\t0x1930: 0x0089, 0x1931: 0x0341, 0x1932: 0x0349, 0x1933: 0x0391, 0x1934: 0x00c1, 0x1935: 0x0109,\n\t0x1936: 0x00c9, 0x1937: 0x04b1, 0x1938: 0x0019, 0x1939: 0x02e9, 0x193a: 0x0040, 0x193b: 0x02f1,\n\t0x193c: 0x02f9, 0x193d: 0x03f1, 0x193e: 0x0309, 0x193f: 0x0040,\n\t// Block 0x65, offset 0x1940\n\t0x1940: 0x0311, 0x1941: 0x00b1, 0x1942: 0x0319, 0x1943: 0x0101, 0x1944: 0x0321, 0x1945: 0x0040,\n\t0x1946: 0x0051, 0x1947: 0x0040, 0x1948: 0x0040, 0x1949: 0x0040, 0x194a: 0x0089, 0x194b: 0x0341,\n\t0x194c: 0x0349, 0x194d: 0x0391, 0x194e: 0x00c1, 0x194f: 0x0109, 0x1950: 0x00c9, 0x1951: 0x0040,\n\t0x1952: 0x0019, 0x1953: 0x02e9, 0x1954: 0x03d9, 0x1955: 0x02f1, 0x1956: 0x02f9, 0x1957: 0x03f1,\n\t0x1958: 0x0309, 0x1959: 0x00a9, 0x195a: 0x0311, 0x195b: 0x00b1, 0x195c: 0x0319, 0x195d: 0x0101,\n\t0x195e: 0x0321, 0x195f: 0x0329, 0x1960: 0x0051, 0x1961: 0x0339, 0x1962: 0x0751, 0x1963: 0x00b9,\n\t0x1964: 0x0089, 0x1965: 0x0341, 0x1966: 0x0349, 0x1967: 0x0391, 0x1968: 0x00c1, 0x1969: 0x0109,\n\t0x196a: 0x00c9, 0x196b: 0x04b1, 0x196c: 0x0019, 0x196d: 0x02e9, 0x196e: 0x03d9, 0x196f: 0x02f1,\n\t0x1970: 0x02f9, 0x1971: 0x03f1, 0x1972: 0x0309, 0x1973: 0x00a9, 0x1974: 0x0311, 0x1975: 0x00b1,\n\t0x1976: 0x0319, 0x1977: 0x0101, 0x1978: 0x0321, 0x1979: 0x0329, 0x197a: 0x0051, 0x197b: 0x0339,\n\t0x197c: 0x0751, 0x197d: 0x00b9, 0x197e: 0x0089, 0x197f: 0x0341,\n\t// Block 0x66, offset 0x1980\n\t0x1980: 0x0349, 0x1981: 0x0391, 0x1982: 0x00c1, 0x1983: 0x0109, 0x1984: 0x00c9, 0x1985: 0x04b1,\n\t0x1986: 0x0019, 0x1987: 0x02e9, 0x1988: 0x03d9, 0x1989: 0x02f1, 0x198a: 0x02f9, 0x198b: 0x03f1,\n\t0x198c: 0x0309, 0x198d: 0x00a9, 0x198e: 0x0311, 0x198f: 0x00b1, 0x1990: 0x0319, 0x1991: 0x0101,\n\t0x1992: 0x0321, 0x1993: 0x0329, 0x1994: 0x0051, 0x1995: 0x0339, 0x1996: 0x0751, 0x1997: 0x00b9,\n\t0x1998: 0x0089, 0x1999: 0x0341, 0x199a: 0x0349, 0x199b: 0x0391, 0x199c: 0x00c1, 0x199d: 0x0109,\n\t0x199e: 0x00c9, 0x199f: 0x04b1, 0x19a0: 0x0019, 0x19a1: 0x02e9, 0x19a2: 0x03d9, 0x19a3: 0x02f1,\n\t0x19a4: 0x02f9, 0x19a5: 0x03f1, 0x19a6: 0x0309, 0x19a7: 0x00a9, 0x19a8: 0x0311, 0x19a9: 0x00b1,\n\t0x19aa: 0x0319, 0x19ab: 0x0101, 0x19ac: 0x0321, 0x19ad: 0x0329, 0x19ae: 0x0051, 0x19af: 0x0339,\n\t0x19b0: 0x0751, 0x19b1: 0x00b9, 0x19b2: 0x0089, 0x19b3: 0x0341, 0x19b4: 0x0349, 0x19b5: 0x0391,\n\t0x19b6: 0x00c1, 0x19b7: 0x0109, 0x19b8: 0x00c9, 0x19b9: 0x04b1, 0x19ba: 0x0019, 0x19bb: 0x02e9,\n\t0x19bc: 0x03d9, 0x19bd: 0x02f1, 0x19be: 0x02f9, 0x19bf: 0x03f1,\n\t// Block 0x67, offset 0x19c0\n\t0x19c0: 0x0309, 0x19c1: 0x00a9, 0x19c2: 0x0311, 0x19c3: 0x00b1, 0x19c4: 0x0319, 0x19c5: 0x0101,\n\t0x19c6: 0x0321, 0x19c7: 0x0329, 0x19c8: 0x0051, 0x19c9: 0x0339, 0x19ca: 0x0751, 0x19cb: 0x00b9,\n\t0x19cc: 0x0089, 0x19cd: 0x0341, 0x19ce: 0x0349, 0x19cf: 0x0391, 0x19d0: 0x00c1, 0x19d1: 0x0109,\n\t0x19d2: 0x00c9, 0x19d3: 0x04b1, 0x19d4: 0x0019, 0x19d5: 0x02e9, 0x19d6: 0x03d9, 0x19d7: 0x02f1,\n\t0x19d8: 0x02f9, 0x19d9: 0x03f1, 0x19da: 0x0309, 0x19db: 0x00a9, 0x19dc: 0x0311, 0x19dd: 0x00b1,\n\t0x19de: 0x0319, 0x19df: 0x0101, 0x19e0: 0x0321, 0x19e1: 0x0329, 0x19e2: 0x0051, 0x19e3: 0x0339,\n\t0x19e4: 0x0751, 0x19e5: 0x00b9, 0x19e6: 0x0089, 0x19e7: 0x0341, 0x19e8: 0x0349, 0x19e9: 0x0391,\n\t0x19ea: 0x00c1, 0x19eb: 0x0109, 0x19ec: 0x00c9, 0x19ed: 0x04b1, 0x19ee: 0x0019, 0x19ef: 0x02e9,\n\t0x19f0: 0x03d9, 0x19f1: 0x02f1, 0x19f2: 0x02f9, 0x19f3: 0x03f1, 0x19f4: 0x0309, 0x19f5: 0x00a9,\n\t0x19f6: 0x0311, 0x19f7: 0x00b1, 0x19f8: 0x0319, 0x19f9: 0x0101, 0x19fa: 0x0321, 0x19fb: 0x0329,\n\t0x19fc: 0x0051, 0x19fd: 0x0339, 0x19fe: 0x0751, 0x19ff: 0x00b9,\n\t// Block 0x68, offset 0x1a00\n\t0x1a00: 0x0089, 0x1a01: 0x0341, 0x1a02: 0x0349, 0x1a03: 0x0391, 0x1a04: 0x00c1, 0x1a05: 0x0109,\n\t0x1a06: 0x00c9, 0x1a07: 0x04b1, 0x1a08: 0x0019, 0x1a09: 0x02e9, 0x1a0a: 0x03d9, 0x1a0b: 0x02f1,\n\t0x1a0c: 0x02f9, 0x1a0d: 0x03f1, 0x1a0e: 0x0309, 0x1a0f: 0x00a9, 0x1a10: 0x0311, 0x1a11: 0x00b1,\n\t0x1a12: 0x0319, 0x1a13: 0x0101, 0x1a14: 0x0321, 0x1a15: 0x0329, 0x1a16: 0x0051, 0x1a17: 0x0339,\n\t0x1a18: 0x0751, 0x1a19: 0x00b9, 0x1a1a: 0x0089, 0x1a1b: 0x0341, 0x1a1c: 0x0349, 0x1a1d: 0x0391,\n\t0x1a1e: 0x00c1, 0x1a1f: 0x0109, 0x1a20: 0x00c9, 0x1a21: 0x04b1, 0x1a22: 0x0019, 0x1a23: 0x02e9,\n\t0x1a24: 0x03d9, 0x1a25: 0x02f1, 0x1a26: 0x02f9, 0x1a27: 0x03f1, 0x1a28: 0x0309, 0x1a29: 0x00a9,\n\t0x1a2a: 0x0311, 0x1a2b: 0x00b1, 0x1a2c: 0x0319, 0x1a2d: 0x0101, 0x1a2e: 0x0321, 0x1a2f: 0x0329,\n\t0x1a30: 0x0051, 0x1a31: 0x0339, 0x1a32: 0x0751, 0x1a33: 0x00b9, 0x1a34: 0x0089, 0x1a35: 0x0341,\n\t0x1a36: 0x0349, 0x1a37: 0x0391, 0x1a38: 0x00c1, 0x1a39: 0x0109, 0x1a3a: 0x00c9, 0x1a3b: 0x04b1,\n\t0x1a3c: 0x0019, 0x1a3d: 0x02e9, 0x1a3e: 0x03d9, 0x1a3f: 0x02f1,\n\t// Block 0x69, offset 0x1a40\n\t0x1a40: 0x02f9, 0x1a41: 0x03f1, 0x1a42: 0x0309, 0x1a43: 0x00a9, 0x1a44: 0x0311, 0x1a45: 0x00b1,\n\t0x1a46: 0x0319, 0x1a47: 0x0101, 0x1a48: 0x0321, 0x1a49: 0x0329, 0x1a4a: 0x0051, 0x1a4b: 0x0339,\n\t0x1a4c: 0x0751, 0x1a4d: 0x00b9, 0x1a4e: 0x0089, 0x1a4f: 0x0341, 0x1a50: 0x0349, 0x1a51: 0x0391,\n\t0x1a52: 0x00c1, 0x1a53: 0x0109, 0x1a54: 0x00c9, 0x1a55: 0x04b1, 0x1a56: 0x0019, 0x1a57: 0x02e9,\n\t0x1a58: 0x03d9, 0x1a59: 0x02f1, 0x1a5a: 0x02f9, 0x1a5b: 0x03f1, 0x1a5c: 0x0309, 0x1a5d: 0x00a9,\n\t0x1a5e: 0x0311, 0x1a5f: 0x00b1, 0x1a60: 0x0319, 0x1a61: 0x0101, 0x1a62: 0x0321, 0x1a63: 0x0329,\n\t0x1a64: 0x0051, 0x1a65: 0x0339, 0x1a66: 0x0751, 0x1a67: 0x00b9, 0x1a68: 0x0089, 0x1a69: 0x0341,\n\t0x1a6a: 0x0349, 0x1a6b: 0x0391, 0x1a6c: 0x00c1, 0x1a6d: 0x0109, 0x1a6e: 0x00c9, 0x1a6f: 0x04b1,\n\t0x1a70: 0x0019, 0x1a71: 0x02e9, 0x1a72: 0x03d9, 0x1a73: 0x02f1, 0x1a74: 0x02f9, 0x1a75: 0x03f1,\n\t0x1a76: 0x0309, 0x1a77: 0x00a9, 0x1a78: 0x0311, 0x1a79: 0x00b1, 0x1a7a: 0x0319, 0x1a7b: 0x0101,\n\t0x1a7c: 0x0321, 0x1a7d: 0x0329, 0x1a7e: 0x0051, 0x1a7f: 0x0339,\n\t// Block 0x6a, offset 0x1a80\n\t0x1a80: 0x0751, 0x1a81: 0x00b9, 0x1a82: 0x0089, 0x1a83: 0x0341, 0x1a84: 0x0349, 0x1a85: 0x0391,\n\t0x1a86: 0x00c1, 0x1a87: 0x0109, 0x1a88: 0x00c9, 0x1a89: 0x04b1, 0x1a8a: 0x0019, 0x1a8b: 0x02e9,\n\t0x1a8c: 0x03d9, 0x1a8d: 0x02f1, 0x1a8e: 0x02f9, 0x1a8f: 0x03f1, 0x1a90: 0x0309, 0x1a91: 0x00a9,\n\t0x1a92: 0x0311, 0x1a93: 0x00b1, 0x1a94: 0x0319, 0x1a95: 0x0101, 0x1a96: 0x0321, 0x1a97: 0x0329,\n\t0x1a98: 0x0051, 0x1a99: 0x0339, 0x1a9a: 0x0751, 0x1a9b: 0x00b9, 0x1a9c: 0x0089, 0x1a9d: 0x0341,\n\t0x1a9e: 0x0349, 0x1a9f: 0x0391, 0x1aa0: 0x00c1, 0x1aa1: 0x0109, 0x1aa2: 0x00c9, 0x1aa3: 0x04b1,\n\t0x1aa4: 0x2279, 0x1aa5: 0x2281, 0x1aa6: 0x0040, 0x1aa7: 0x0040, 0x1aa8: 0x2289, 0x1aa9: 0x0399,\n\t0x1aaa: 0x03a1, 0x1aab: 0x03a9, 0x1aac: 0x2291, 0x1aad: 0x2299, 0x1aae: 0x22a1, 0x1aaf: 0x04d1,\n\t0x1ab0: 0x05f9, 0x1ab1: 0x22a9, 0x1ab2: 0x22b1, 0x1ab3: 0x22b9, 0x1ab4: 0x22c1, 0x1ab5: 0x22c9,\n\t0x1ab6: 0x22d1, 0x1ab7: 0x0799, 0x1ab8: 0x03c1, 0x1ab9: 0x04d1, 0x1aba: 0x22d9, 0x1abb: 0x22e1,\n\t0x1abc: 0x22e9, 0x1abd: 0x03b1, 0x1abe: 0x03b9, 0x1abf: 0x22f1,\n\t// Block 0x6b, offset 0x1ac0\n\t0x1ac0: 0x0769, 0x1ac1: 0x22f9, 0x1ac2: 0x2289, 0x1ac3: 0x0399, 0x1ac4: 0x03a1, 0x1ac5: 0x03a9,\n\t0x1ac6: 0x2291, 0x1ac7: 0x2299, 0x1ac8: 0x22a1, 0x1ac9: 0x04d1, 0x1aca: 0x05f9, 0x1acb: 0x22a9,\n\t0x1acc: 0x22b1, 0x1acd: 0x22b9, 0x1ace: 0x22c1, 0x1acf: 0x22c9, 0x1ad0: 0x22d1, 0x1ad1: 0x0799,\n\t0x1ad2: 0x03c1, 0x1ad3: 0x22d9, 0x1ad4: 0x22d9, 0x1ad5: 0x22e1, 0x1ad6: 0x22e9, 0x1ad7: 0x03b1,\n\t0x1ad8: 0x03b9, 0x1ad9: 0x22f1, 0x1ada: 0x0769, 0x1adb: 0x2301, 0x1adc: 0x2291, 0x1add: 0x04d1,\n\t0x1ade: 0x22a9, 0x1adf: 0x03b1, 0x1ae0: 0x03c1, 0x1ae1: 0x0799, 0x1ae2: 0x2289, 0x1ae3: 0x0399,\n\t0x1ae4: 0x03a1, 0x1ae5: 0x03a9, 0x1ae6: 0x2291, 0x1ae7: 0x2299, 0x1ae8: 0x22a1, 0x1ae9: 0x04d1,\n\t0x1aea: 0x05f9, 0x1aeb: 0x22a9, 0x1aec: 0x22b1, 0x1aed: 0x22b9, 0x1aee: 0x22c1, 0x1aef: 0x22c9,\n\t0x1af0: 0x22d1, 0x1af1: 0x0799, 0x1af2: 0x03c1, 0x1af3: 0x04d1, 0x1af4: 0x22d9, 0x1af5: 0x22e1,\n\t0x1af6: 0x22e9, 0x1af7: 0x03b1, 0x1af8: 0x03b9, 0x1af9: 0x22f1, 0x1afa: 0x0769, 0x1afb: 0x22f9,\n\t0x1afc: 0x2289, 0x1afd: 0x0399, 0x1afe: 0x03a1, 0x1aff: 0x03a9,\n\t// Block 0x6c, offset 0x1b00\n\t0x1b00: 0x2291, 0x1b01: 0x2299, 0x1b02: 0x22a1, 0x1b03: 0x04d1, 0x1b04: 0x05f9, 0x1b05: 0x22a9,\n\t0x1b06: 0x22b1, 0x1b07: 0x22b9, 0x1b08: 0x22c1, 0x1b09: 0x22c9, 0x1b0a: 0x22d1, 0x1b0b: 0x0799,\n\t0x1b0c: 0x03c1, 0x1b0d: 0x22d9, 0x1b0e: 0x22d9, 0x1b0f: 0x22e1, 0x1b10: 0x22e9, 0x1b11: 0x03b1,\n\t0x1b12: 0x03b9, 0x1b13: 0x22f1, 0x1b14: 0x0769, 0x1b15: 0x2301, 0x1b16: 0x2291, 0x1b17: 0x04d1,\n\t0x1b18: 0x22a9, 0x1b19: 0x03b1, 0x1b1a: 0x03c1, 0x1b1b: 0x0799, 0x1b1c: 0x2289, 0x1b1d: 0x0399,\n\t0x1b1e: 0x03a1, 0x1b1f: 0x03a9, 0x1b20: 0x2291, 0x1b21: 0x2299, 0x1b22: 0x22a1, 0x1b23: 0x04d1,\n\t0x1b24: 0x05f9, 0x1b25: 0x22a9, 0x1b26: 0x22b1, 0x1b27: 0x22b9, 0x1b28: 0x22c1, 0x1b29: 0x22c9,\n\t0x1b2a: 0x22d1, 0x1b2b: 0x0799, 0x1b2c: 0x03c1, 0x1b2d: 0x04d1, 0x1b2e: 0x22d9, 0x1b2f: 0x22e1,\n\t0x1b30: 0x22e9, 0x1b31: 0x03b1, 0x1b32: 0x03b9, 0x1b33: 0x22f1, 0x1b34: 0x0769, 0x1b35: 0x22f9,\n\t0x1b36: 0x2289, 0x1b37: 0x0399, 0x1b38: 0x03a1, 0x1b39: 0x03a9, 0x1b3a: 0x2291, 0x1b3b: 0x2299,\n\t0x1b3c: 0x22a1, 0x1b3d: 0x04d1, 0x1b3e: 0x05f9, 0x1b3f: 0x22a9,\n\t// Block 0x6d, offset 0x1b40\n\t0x1b40: 0x22b1, 0x1b41: 0x22b9, 0x1b42: 0x22c1, 0x1b43: 0x22c9, 0x1b44: 0x22d1, 0x1b45: 0x0799,\n\t0x1b46: 0x03c1, 0x1b47: 0x22d9, 0x1b48: 0x22d9, 0x1b49: 0x22e1, 0x1b4a: 0x22e9, 0x1b4b: 0x03b1,\n\t0x1b4c: 0x03b9, 0x1b4d: 0x22f1, 0x1b4e: 0x0769, 0x1b4f: 0x2301, 0x1b50: 0x2291, 0x1b51: 0x04d1,\n\t0x1b52: 0x22a9, 0x1b53: 0x03b1, 0x1b54: 0x03c1, 0x1b55: 0x0799, 0x1b56: 0x2289, 0x1b57: 0x0399,\n\t0x1b58: 0x03a1, 0x1b59: 0x03a9, 0x1b5a: 0x2291, 0x1b5b: 0x2299, 0x1b5c: 0x22a1, 0x1b5d: 0x04d1,\n\t0x1b5e: 0x05f9, 0x1b5f: 0x22a9, 0x1b60: 0x22b1, 0x1b61: 0x22b9, 0x1b62: 0x22c1, 0x1b63: 0x22c9,\n\t0x1b64: 0x22d1, 0x1b65: 0x0799, 0x1b66: 0x03c1, 0x1b67: 0x04d1, 0x1b68: 0x22d9, 0x1b69: 0x22e1,\n\t0x1b6a: 0x22e9, 0x1b6b: 0x03b1, 0x1b6c: 0x03b9, 0x1b6d: 0x22f1, 0x1b6e: 0x0769, 0x1b6f: 0x22f9,\n\t0x1b70: 0x2289, 0x1b71: 0x0399, 0x1b72: 0x03a1, 0x1b73: 0x03a9, 0x1b74: 0x2291, 0x1b75: 0x2299,\n\t0x1b76: 0x22a1, 0x1b77: 0x04d1, 0x1b78: 0x05f9, 0x1b79: 0x22a9, 0x1b7a: 0x22b1, 0x1b7b: 0x22b9,\n\t0x1b7c: 0x22c1, 0x1b7d: 0x22c9, 0x1b7e: 0x22d1, 0x1b7f: 0x0799,\n\t// Block 0x6e, offset 0x1b80\n\t0x1b80: 0x03c1, 0x1b81: 0x22d9, 0x1b82: 0x22d9, 0x1b83: 0x22e1, 0x1b84: 0x22e9, 0x1b85: 0x03b1,\n\t0x1b86: 0x03b9, 0x1b87: 0x22f1, 0x1b88: 0x0769, 0x1b89: 0x2301, 0x1b8a: 0x2291, 0x1b8b: 0x04d1,\n\t0x1b8c: 0x22a9, 0x1b8d: 0x03b1, 0x1b8e: 0x03c1, 0x1b8f: 0x0799, 0x1b90: 0x2289, 0x1b91: 0x0399,\n\t0x1b92: 0x03a1, 0x1b93: 0x03a9, 0x1b94: 0x2291, 0x1b95: 0x2299, 0x1b96: 0x22a1, 0x1b97: 0x04d1,\n\t0x1b98: 0x05f9, 0x1b99: 0x22a9, 0x1b9a: 0x22b1, 0x1b9b: 0x22b9, 0x1b9c: 0x22c1, 0x1b9d: 0x22c9,\n\t0x1b9e: 0x22d1, 0x1b9f: 0x0799, 0x1ba0: 0x03c1, 0x1ba1: 0x04d1, 0x1ba2: 0x22d9, 0x1ba3: 0x22e1,\n\t0x1ba4: 0x22e9, 0x1ba5: 0x03b1, 0x1ba6: 0x03b9, 0x1ba7: 0x22f1, 0x1ba8: 0x0769, 0x1ba9: 0x22f9,\n\t0x1baa: 0x2289, 0x1bab: 0x0399, 0x1bac: 0x03a1, 0x1bad: 0x03a9, 0x1bae: 0x2291, 0x1baf: 0x2299,\n\t0x1bb0: 0x22a1, 0x1bb1: 0x04d1, 0x1bb2: 0x05f9, 0x1bb3: 0x22a9, 0x1bb4: 0x22b1, 0x1bb5: 0x22b9,\n\t0x1bb6: 0x22c1, 0x1bb7: 0x22c9, 0x1bb8: 0x22d1, 0x1bb9: 0x0799, 0x1bba: 0x03c1, 0x1bbb: 0x22d9,\n\t0x1bbc: 0x22d9, 0x1bbd: 0x22e1, 0x1bbe: 0x22e9, 0x1bbf: 0x03b1,\n\t// Block 0x6f, offset 0x1bc0\n\t0x1bc0: 0x03b9, 0x1bc1: 0x22f1, 0x1bc2: 0x0769, 0x1bc3: 0x2301, 0x1bc4: 0x2291, 0x1bc5: 0x04d1,\n\t0x1bc6: 0x22a9, 0x1bc7: 0x03b1, 0x1bc8: 0x03c1, 0x1bc9: 0x0799, 0x1bca: 0x2309, 0x1bcb: 0x2309,\n\t0x1bcc: 0x0040, 0x1bcd: 0x0040, 0x1bce: 0x06e1, 0x1bcf: 0x0049, 0x1bd0: 0x0029, 0x1bd1: 0x0031,\n\t0x1bd2: 0x06e9, 0x1bd3: 0x06f1, 0x1bd4: 0x06f9, 0x1bd5: 0x0701, 0x1bd6: 0x0709, 0x1bd7: 0x0711,\n\t0x1bd8: 0x06e1, 0x1bd9: 0x0049, 0x1bda: 0x0029, 0x1bdb: 0x0031, 0x1bdc: 0x06e9, 0x1bdd: 0x06f1,\n\t0x1bde: 0x06f9, 0x1bdf: 0x0701, 0x1be0: 0x0709, 0x1be1: 0x0711, 0x1be2: 0x06e1, 0x1be3: 0x0049,\n\t0x1be4: 0x0029, 0x1be5: 0x0031, 0x1be6: 0x06e9, 0x1be7: 0x06f1, 0x1be8: 0x06f9, 0x1be9: 0x0701,\n\t0x1bea: 0x0709, 0x1beb: 0x0711, 0x1bec: 0x06e1, 0x1bed: 0x0049, 0x1bee: 0x0029, 0x1bef: 0x0031,\n\t0x1bf0: 0x06e9, 0x1bf1: 0x06f1, 0x1bf2: 0x06f9, 0x1bf3: 0x0701, 0x1bf4: 0x0709, 0x1bf5: 0x0711,\n\t0x1bf6: 0x06e1, 0x1bf7: 0x0049, 0x1bf8: 0x0029, 0x1bf9: 0x0031, 0x1bfa: 0x06e9, 0x1bfb: 0x06f1,\n\t0x1bfc: 0x06f9, 0x1bfd: 0x0701, 0x1bfe: 0x0709, 0x1bff: 0x0711,\n\t// Block 0x70, offset 0x1c00\n\t0x1c00: 0xe115, 0x1c01: 0xe115, 0x1c02: 0xe135, 0x1c03: 0xe135, 0x1c04: 0xe115, 0x1c05: 0xe115,\n\t0x1c06: 0xe175, 0x1c07: 0xe175, 0x1c08: 0xe115, 0x1c09: 0xe115, 0x1c0a: 0xe135, 0x1c0b: 0xe135,\n\t0x1c0c: 0xe115, 0x1c0d: 0xe115, 0x1c0e: 0xe1f5, 0x1c0f: 0xe1f5, 0x1c10: 0xe115, 0x1c11: 0xe115,\n\t0x1c12: 0xe135, 0x1c13: 0xe135, 0x1c14: 0xe115, 0x1c15: 0xe115, 0x1c16: 0xe175, 0x1c17: 0xe175,\n\t0x1c18: 0xe115, 0x1c19: 0xe115, 0x1c1a: 0xe135, 0x1c1b: 0xe135, 0x1c1c: 0xe115, 0x1c1d: 0xe115,\n\t0x1c1e: 0x8b3d, 0x1c1f: 0x8b3d, 0x1c20: 0x04b5, 0x1c21: 0x04b5, 0x1c22: 0x0a08, 0x1c23: 0x0a08,\n\t0x1c24: 0x0a08, 0x1c25: 0x0a08, 0x1c26: 0x0a08, 0x1c27: 0x0a08, 0x1c28: 0x0a08, 0x1c29: 0x0a08,\n\t0x1c2a: 0x0a08, 0x1c2b: 0x0a08, 0x1c2c: 0x0a08, 0x1c2d: 0x0a08, 0x1c2e: 0x0a08, 0x1c2f: 0x0a08,\n\t0x1c30: 0x0a08, 0x1c31: 0x0a08, 0x1c32: 0x0a08, 0x1c33: 0x0a08, 0x1c34: 0x0a08, 0x1c35: 0x0a08,\n\t0x1c36: 0x0a08, 0x1c37: 0x0a08, 0x1c38: 0x0a08, 0x1c39: 0x0a08, 0x1c3a: 0x0a08, 0x1c3b: 0x0a08,\n\t0x1c3c: 0x0a08, 0x1c3d: 0x0a08, 0x1c3e: 0x0a08, 0x1c3f: 0x0a08,\n\t// Block 0x71, offset 0x1c40\n\t0x1c40: 0x20b1, 0x1c41: 0x20b9, 0x1c42: 0x20d9, 0x1c43: 0x20f1, 0x1c44: 0x0040, 0x1c45: 0x2189,\n\t0x1c46: 0x2109, 0x1c47: 0x20e1, 0x1c48: 0x2131, 0x1c49: 0x2191, 0x1c4a: 0x2161, 0x1c4b: 0x2169,\n\t0x1c4c: 0x2171, 0x1c4d: 0x2179, 0x1c4e: 0x2111, 0x1c4f: 0x2141, 0x1c50: 0x2151, 0x1c51: 0x2121,\n\t0x1c52: 0x2159, 0x1c53: 0x2101, 0x1c54: 0x2119, 0x1c55: 0x20c9, 0x1c56: 0x20d1, 0x1c57: 0x20e9,\n\t0x1c58: 0x20f9, 0x1c59: 0x2129, 0x1c5a: 0x2139, 0x1c5b: 0x2149, 0x1c5c: 0x2311, 0x1c5d: 0x1689,\n\t0x1c5e: 0x2319, 0x1c5f: 0x2321, 0x1c60: 0x0040, 0x1c61: 0x20b9, 0x1c62: 0x20d9, 0x1c63: 0x0040,\n\t0x1c64: 0x2181, 0x1c65: 0x0040, 0x1c66: 0x0040, 0x1c67: 0x20e1, 0x1c68: 0x0040, 0x1c69: 0x2191,\n\t0x1c6a: 0x2161, 0x1c6b: 0x2169, 0x1c6c: 0x2171, 0x1c6d: 0x2179, 0x1c6e: 0x2111, 0x1c6f: 0x2141,\n\t0x1c70: 0x2151, 0x1c71: 0x2121, 0x1c72: 0x2159, 0x1c73: 0x0040, 0x1c74: 0x2119, 0x1c75: 0x20c9,\n\t0x1c76: 0x20d1, 0x1c77: 0x20e9, 0x1c78: 0x0040, 0x1c79: 0x2129, 0x1c7a: 0x0040, 0x1c7b: 0x2149,\n\t0x1c7c: 0x0040, 0x1c7d: 0x0040, 0x1c7e: 0x0040, 0x1c7f: 0x0040,\n\t// Block 0x72, offset 0x1c80\n\t0x1c80: 0x0040, 0x1c81: 0x0040, 0x1c82: 0x20d9, 0x1c83: 0x0040, 0x1c84: 0x0040, 0x1c85: 0x0040,\n\t0x1c86: 0x0040, 0x1c87: 0x20e1, 0x1c88: 0x0040, 0x1c89: 0x2191, 0x1c8a: 0x0040, 0x1c8b: 0x2169,\n\t0x1c8c: 0x0040, 0x1c8d: 0x2179, 0x1c8e: 0x2111, 0x1c8f: 0x2141, 0x1c90: 0x0040, 0x1c91: 0x2121,\n\t0x1c92: 0x2159, 0x1c93: 0x0040, 0x1c94: 0x2119, 0x1c95: 0x0040, 0x1c96: 0x0040, 0x1c97: 0x20e9,\n\t0x1c98: 0x0040, 0x1c99: 0x2129, 0x1c9a: 0x0040, 0x1c9b: 0x2149, 0x1c9c: 0x0040, 0x1c9d: 0x1689,\n\t0x1c9e: 0x0040, 0x1c9f: 0x2321, 0x1ca0: 0x0040, 0x1ca1: 0x20b9, 0x1ca2: 0x20d9, 0x1ca3: 0x0040,\n\t0x1ca4: 0x2181, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0x20e1, 0x1ca8: 0x2131, 0x1ca9: 0x2191,\n\t0x1caa: 0x2161, 0x1cab: 0x0040, 0x1cac: 0x2171, 0x1cad: 0x2179, 0x1cae: 0x2111, 0x1caf: 0x2141,\n\t0x1cb0: 0x2151, 0x1cb1: 0x2121, 0x1cb2: 0x2159, 0x1cb3: 0x0040, 0x1cb4: 0x2119, 0x1cb5: 0x20c9,\n\t0x1cb6: 0x20d1, 0x1cb7: 0x20e9, 0x1cb8: 0x0040, 0x1cb9: 0x2129, 0x1cba: 0x2139, 0x1cbb: 0x2149,\n\t0x1cbc: 0x2311, 0x1cbd: 0x0040, 0x1cbe: 0x2319, 0x1cbf: 0x0040,\n\t// Block 0x73, offset 0x1cc0\n\t0x1cc0: 0x20b1, 0x1cc1: 0x20b9, 0x1cc2: 0x20d9, 0x1cc3: 0x20f1, 0x1cc4: 0x2181, 0x1cc5: 0x2189,\n\t0x1cc6: 0x2109, 0x1cc7: 0x20e1, 0x1cc8: 0x2131, 0x1cc9: 0x2191, 0x1cca: 0x0040, 0x1ccb: 0x2169,\n\t0x1ccc: 0x2171, 0x1ccd: 0x2179, 0x1cce: 0x2111, 0x1ccf: 0x2141, 0x1cd0: 0x2151, 0x1cd1: 0x2121,\n\t0x1cd2: 0x2159, 0x1cd3: 0x2101, 0x1cd4: 0x2119, 0x1cd5: 0x20c9, 0x1cd6: 0x20d1, 0x1cd7: 0x20e9,\n\t0x1cd8: 0x20f9, 0x1cd9: 0x2129, 0x1cda: 0x2139, 0x1cdb: 0x2149, 0x1cdc: 0x0040, 0x1cdd: 0x0040,\n\t0x1cde: 0x0040, 0x1cdf: 0x0040, 0x1ce0: 0x0040, 0x1ce1: 0x20b9, 0x1ce2: 0x20d9, 0x1ce3: 0x20f1,\n\t0x1ce4: 0x0040, 0x1ce5: 0x2189, 0x1ce6: 0x2109, 0x1ce7: 0x20e1, 0x1ce8: 0x2131, 0x1ce9: 0x2191,\n\t0x1cea: 0x0040, 0x1ceb: 0x2169, 0x1cec: 0x2171, 0x1ced: 0x2179, 0x1cee: 0x2111, 0x1cef: 0x2141,\n\t0x1cf0: 0x2151, 0x1cf1: 0x2121, 0x1cf2: 0x2159, 0x1cf3: 0x2101, 0x1cf4: 0x2119, 0x1cf5: 0x20c9,\n\t0x1cf6: 0x20d1, 0x1cf7: 0x20e9, 0x1cf8: 0x20f9, 0x1cf9: 0x2129, 0x1cfa: 0x2139, 0x1cfb: 0x2149,\n\t0x1cfc: 0x0040, 0x1cfd: 0x0040, 0x1cfe: 0x0040, 0x1cff: 0x0040,\n\t// Block 0x74, offset 0x1d00\n\t0x1d00: 0x0040, 0x1d01: 0x232a, 0x1d02: 0x2332, 0x1d03: 0x233a, 0x1d04: 0x2342, 0x1d05: 0x234a,\n\t0x1d06: 0x2352, 0x1d07: 0x235a, 0x1d08: 0x2362, 0x1d09: 0x236a, 0x1d0a: 0x2372, 0x1d0b: 0x0018,\n\t0x1d0c: 0x0018, 0x1d0d: 0x0018, 0x1d0e: 0x0018, 0x1d0f: 0x0018, 0x1d10: 0x237a, 0x1d11: 0x2382,\n\t0x1d12: 0x238a, 0x1d13: 0x2392, 0x1d14: 0x239a, 0x1d15: 0x23a2, 0x1d16: 0x23aa, 0x1d17: 0x23b2,\n\t0x1d18: 0x23ba, 0x1d19: 0x23c2, 0x1d1a: 0x23ca, 0x1d1b: 0x23d2, 0x1d1c: 0x23da, 0x1d1d: 0x23e2,\n\t0x1d1e: 0x23ea, 0x1d1f: 0x23f2, 0x1d20: 0x23fa, 0x1d21: 0x2402, 0x1d22: 0x240a, 0x1d23: 0x2412,\n\t0x1d24: 0x241a, 0x1d25: 0x2422, 0x1d26: 0x242a, 0x1d27: 0x2432, 0x1d28: 0x243a, 0x1d29: 0x2442,\n\t0x1d2a: 0x2449, 0x1d2b: 0x03d9, 0x1d2c: 0x00b9, 0x1d2d: 0x1239, 0x1d2e: 0x2451, 0x1d2f: 0x0018,\n\t0x1d30: 0x0019, 0x1d31: 0x02e9, 0x1d32: 0x03d9, 0x1d33: 0x02f1, 0x1d34: 0x02f9, 0x1d35: 0x03f1,\n\t0x1d36: 0x0309, 0x1d37: 0x00a9, 0x1d38: 0x0311, 0x1d39: 0x00b1, 0x1d3a: 0x0319, 0x1d3b: 0x0101,\n\t0x1d3c: 0x0321, 0x1d3d: 0x0329, 0x1d3e: 0x0051, 0x1d3f: 0x0339,\n\t// Block 0x75, offset 0x1d40\n\t0x1d40: 0x0751, 0x1d41: 0x00b9, 0x1d42: 0x0089, 0x1d43: 0x0341, 0x1d44: 0x0349, 0x1d45: 0x0391,\n\t0x1d46: 0x00c1, 0x1d47: 0x0109, 0x1d48: 0x00c9, 0x1d49: 0x04b1, 0x1d4a: 0x2459, 0x1d4b: 0x11f9,\n\t0x1d4c: 0x2461, 0x1d4d: 0x04d9, 0x1d4e: 0x2469, 0x1d4f: 0x2471, 0x1d50: 0x0018, 0x1d51: 0x0018,\n\t0x1d52: 0x0018, 0x1d53: 0x0018, 0x1d54: 0x0018, 0x1d55: 0x0018, 0x1d56: 0x0018, 0x1d57: 0x0018,\n\t0x1d58: 0x0018, 0x1d59: 0x0018, 0x1d5a: 0x0018, 0x1d5b: 0x0018, 0x1d5c: 0x0018, 0x1d5d: 0x0018,\n\t0x1d5e: 0x0018, 0x1d5f: 0x0018, 0x1d60: 0x0018, 0x1d61: 0x0018, 0x1d62: 0x0018, 0x1d63: 0x0018,\n\t0x1d64: 0x0018, 0x1d65: 0x0018, 0x1d66: 0x0018, 0x1d67: 0x0018, 0x1d68: 0x0018, 0x1d69: 0x0018,\n\t0x1d6a: 0x2479, 0x1d6b: 0x2481, 0x1d6c: 0x2489, 0x1d6d: 0x0018, 0x1d6e: 0x0018, 0x1d6f: 0x0018,\n\t0x1d70: 0x0018, 0x1d71: 0x0018, 0x1d72: 0x0018, 0x1d73: 0x0018, 0x1d74: 0x0018, 0x1d75: 0x0018,\n\t0x1d76: 0x0018, 0x1d77: 0x0018, 0x1d78: 0x0018, 0x1d79: 0x0018, 0x1d7a: 0x0018, 0x1d7b: 0x0018,\n\t0x1d7c: 0x0018, 0x1d7d: 0x0018, 0x1d7e: 0x0018, 0x1d7f: 0x0018,\n\t// Block 0x76, offset 0x1d80\n\t0x1d80: 0x2499, 0x1d81: 0x24a1, 0x1d82: 0x24a9, 0x1d83: 0x0040, 0x1d84: 0x0040, 0x1d85: 0x0040,\n\t0x1d86: 0x0040, 0x1d87: 0x0040, 0x1d88: 0x0040, 0x1d89: 0x0040, 0x1d8a: 0x0040, 0x1d8b: 0x0040,\n\t0x1d8c: 0x0040, 0x1d8d: 0x0040, 0x1d8e: 0x0040, 0x1d8f: 0x0040, 0x1d90: 0x24b1, 0x1d91: 0x24b9,\n\t0x1d92: 0x24c1, 0x1d93: 0x24c9, 0x1d94: 0x24d1, 0x1d95: 0x24d9, 0x1d96: 0x24e1, 0x1d97: 0x24e9,\n\t0x1d98: 0x24f1, 0x1d99: 0x24f9, 0x1d9a: 0x2501, 0x1d9b: 0x2509, 0x1d9c: 0x2511, 0x1d9d: 0x2519,\n\t0x1d9e: 0x2521, 0x1d9f: 0x2529, 0x1da0: 0x2531, 0x1da1: 0x2539, 0x1da2: 0x2541, 0x1da3: 0x2549,\n\t0x1da4: 0x2551, 0x1da5: 0x2559, 0x1da6: 0x2561, 0x1da7: 0x2569, 0x1da8: 0x2571, 0x1da9: 0x2579,\n\t0x1daa: 0x2581, 0x1dab: 0x2589, 0x1dac: 0x2591, 0x1dad: 0x2599, 0x1dae: 0x25a1, 0x1daf: 0x25a9,\n\t0x1db0: 0x25b1, 0x1db1: 0x25b9, 0x1db2: 0x25c1, 0x1db3: 0x25c9, 0x1db4: 0x25d1, 0x1db5: 0x25d9,\n\t0x1db6: 0x25e1, 0x1db7: 0x25e9, 0x1db8: 0x25f1, 0x1db9: 0x25f9, 0x1dba: 0x2601, 0x1dbb: 0x2609,\n\t0x1dbc: 0x0040, 0x1dbd: 0x0040, 0x1dbe: 0x0040, 0x1dbf: 0x0040,\n\t// Block 0x77, offset 0x1dc0\n\t0x1dc0: 0x2669, 0x1dc1: 0x2671, 0x1dc2: 0x2679, 0x1dc3: 0x8b55, 0x1dc4: 0x2681, 0x1dc5: 0x2689,\n\t0x1dc6: 0x2691, 0x1dc7: 0x2699, 0x1dc8: 0x26a1, 0x1dc9: 0x26a9, 0x1dca: 0x26b1, 0x1dcb: 0x26b9,\n\t0x1dcc: 0x26c1, 0x1dcd: 0x8b75, 0x1dce: 0x26c9, 0x1dcf: 0x26d1, 0x1dd0: 0x26d9, 0x1dd1: 0x26e1,\n\t0x1dd2: 0x8b95, 0x1dd3: 0x26e9, 0x1dd4: 0x26f1, 0x1dd5: 0x2521, 0x1dd6: 0x8bb5, 0x1dd7: 0x26f9,\n\t0x1dd8: 0x2701, 0x1dd9: 0x2709, 0x1dda: 0x2711, 0x1ddb: 0x2719, 0x1ddc: 0x8bd5, 0x1ddd: 0x2721,\n\t0x1dde: 0x2729, 0x1ddf: 0x2731, 0x1de0: 0x2739, 0x1de1: 0x2741, 0x1de2: 0x25f9, 0x1de3: 0x2749,\n\t0x1de4: 0x2751, 0x1de5: 0x2759, 0x1de6: 0x2761, 0x1de7: 0x2769, 0x1de8: 0x2771, 0x1de9: 0x2779,\n\t0x1dea: 0x2781, 0x1deb: 0x2789, 0x1dec: 0x2791, 0x1ded: 0x2799, 0x1dee: 0x27a1, 0x1def: 0x27a9,\n\t0x1df0: 0x27b1, 0x1df1: 0x27b9, 0x1df2: 0x27b9, 0x1df3: 0x27b9, 0x1df4: 0x8bf5, 0x1df5: 0x27c1,\n\t0x1df6: 0x27c9, 0x1df7: 0x27d1, 0x1df8: 0x8c15, 0x1df9: 0x27d9, 0x1dfa: 0x27e1, 0x1dfb: 0x27e9,\n\t0x1dfc: 0x27f1, 0x1dfd: 0x27f9, 0x1dfe: 0x2801, 0x1dff: 0x2809,\n\t// Block 0x78, offset 0x1e00\n\t0x1e00: 0x2811, 0x1e01: 0x2819, 0x1e02: 0x2821, 0x1e03: 0x2829, 0x1e04: 0x2831, 0x1e05: 0x2839,\n\t0x1e06: 0x2839, 0x1e07: 0x2841, 0x1e08: 0x2849, 0x1e09: 0x2851, 0x1e0a: 0x2859, 0x1e0b: 0x2861,\n\t0x1e0c: 0x2869, 0x1e0d: 0x2871, 0x1e0e: 0x2879, 0x1e0f: 0x2881, 0x1e10: 0x2889, 0x1e11: 0x2891,\n\t0x1e12: 0x2899, 0x1e13: 0x28a1, 0x1e14: 0x28a9, 0x1e15: 0x28b1, 0x1e16: 0x28b9, 0x1e17: 0x28c1,\n\t0x1e18: 0x28c9, 0x1e19: 0x8c35, 0x1e1a: 0x28d1, 0x1e1b: 0x28d9, 0x1e1c: 0x28e1, 0x1e1d: 0x24d9,\n\t0x1e1e: 0x28e9, 0x1e1f: 0x28f1, 0x1e20: 0x8c55, 0x1e21: 0x8c75, 0x1e22: 0x28f9, 0x1e23: 0x2901,\n\t0x1e24: 0x2909, 0x1e25: 0x2911, 0x1e26: 0x2919, 0x1e27: 0x2921, 0x1e28: 0x2040, 0x1e29: 0x2929,\n\t0x1e2a: 0x2931, 0x1e2b: 0x2931, 0x1e2c: 0x8c95, 0x1e2d: 0x2939, 0x1e2e: 0x2941, 0x1e2f: 0x2949,\n\t0x1e30: 0x2951, 0x1e31: 0x8cb5, 0x1e32: 0x2959, 0x1e33: 0x2961, 0x1e34: 0x2040, 0x1e35: 0x2969,\n\t0x1e36: 0x2971, 0x1e37: 0x2979, 0x1e38: 0x2981, 0x1e39: 0x2989, 0x1e3a: 0x2991, 0x1e3b: 0x8cd5,\n\t0x1e3c: 0x2999, 0x1e3d: 0x8cf5, 0x1e3e: 0x29a1, 0x1e3f: 0x29a9,\n\t// Block 0x79, offset 0x1e40\n\t0x1e40: 0x29b1, 0x1e41: 0x29b9, 0x1e42: 0x29c1, 0x1e43: 0x29c9, 0x1e44: 0x29d1, 0x1e45: 0x29d9,\n\t0x1e46: 0x29e1, 0x1e47: 0x29e9, 0x1e48: 0x29f1, 0x1e49: 0x8d15, 0x1e4a: 0x29f9, 0x1e4b: 0x2a01,\n\t0x1e4c: 0x2a09, 0x1e4d: 0x2a11, 0x1e4e: 0x2a19, 0x1e4f: 0x8d35, 0x1e50: 0x2a21, 0x1e51: 0x8d55,\n\t0x1e52: 0x8d75, 0x1e53: 0x2a29, 0x1e54: 0x2a31, 0x1e55: 0x2a31, 0x1e56: 0x2a39, 0x1e57: 0x8d95,\n\t0x1e58: 0x8db5, 0x1e59: 0x2a41, 0x1e5a: 0x2a49, 0x1e5b: 0x2a51, 0x1e5c: 0x2a59, 0x1e5d: 0x2a61,\n\t0x1e5e: 0x2a69, 0x1e5f: 0x2a71, 0x1e60: 0x2a79, 0x1e61: 0x2a81, 0x1e62: 0x2a89, 0x1e63: 0x2a91,\n\t0x1e64: 0x8dd5, 0x1e65: 0x2a99, 0x1e66: 0x2aa1, 0x1e67: 0x2aa9, 0x1e68: 0x2ab1, 0x1e69: 0x2aa9,\n\t0x1e6a: 0x2ab9, 0x1e6b: 0x2ac1, 0x1e6c: 0x2ac9, 0x1e6d: 0x2ad1, 0x1e6e: 0x2ad9, 0x1e6f: 0x2ae1,\n\t0x1e70: 0x2ae9, 0x1e71: 0x2af1, 0x1e72: 0x2af9, 0x1e73: 0x2b01, 0x1e74: 0x2b09, 0x1e75: 0x2b11,\n\t0x1e76: 0x2b19, 0x1e77: 0x2b21, 0x1e78: 0x8df5, 0x1e79: 0x2b29, 0x1e7a: 0x2b31, 0x1e7b: 0x2b39,\n\t0x1e7c: 0x2b41, 0x1e7d: 0x2b49, 0x1e7e: 0x8e15, 0x1e7f: 0x2b51,\n\t// Block 0x7a, offset 0x1e80\n\t0x1e80: 0x2b59, 0x1e81: 0x2b61, 0x1e82: 0x2b69, 0x1e83: 0x2b71, 0x1e84: 0x2b79, 0x1e85: 0x2b81,\n\t0x1e86: 0x2b89, 0x1e87: 0x2b91, 0x1e88: 0x2b99, 0x1e89: 0x2ba1, 0x1e8a: 0x8e35, 0x1e8b: 0x2ba9,\n\t0x1e8c: 0x2bb1, 0x1e8d: 0x2bb9, 0x1e8e: 0x2bc1, 0x1e8f: 0x2bc9, 0x1e90: 0x2bd1, 0x1e91: 0x2bd9,\n\t0x1e92: 0x2be1, 0x1e93: 0x2be9, 0x1e94: 0x2bf1, 0x1e95: 0x2bf9, 0x1e96: 0x2c01, 0x1e97: 0x2c09,\n\t0x1e98: 0x2c11, 0x1e99: 0x2c19, 0x1e9a: 0x2c21, 0x1e9b: 0x2c29, 0x1e9c: 0x2c31, 0x1e9d: 0x8e55,\n\t0x1e9e: 0x2c39, 0x1e9f: 0x2c41, 0x1ea0: 0x2c49, 0x1ea1: 0x2c51, 0x1ea2: 0x2c59, 0x1ea3: 0x8e75,\n\t0x1ea4: 0x2c61, 0x1ea5: 0x2c69, 0x1ea6: 0x2c71, 0x1ea7: 0x2c79, 0x1ea8: 0x2c81, 0x1ea9: 0x2c89,\n\t0x1eaa: 0x2c91, 0x1eab: 0x2c99, 0x1eac: 0x7f0d, 0x1ead: 0x2ca1, 0x1eae: 0x2ca9, 0x1eaf: 0x2cb1,\n\t0x1eb0: 0x8e95, 0x1eb1: 0x2cb9, 0x1eb2: 0x2cc1, 0x1eb3: 0x2cc9, 0x1eb4: 0x2cd1, 0x1eb5: 0x2cd9,\n\t0x1eb6: 0x2ce1, 0x1eb7: 0x8eb5, 0x1eb8: 0x8ed5, 0x1eb9: 0x8ef5, 0x1eba: 0x2ce9, 0x1ebb: 0x8f15,\n\t0x1ebc: 0x2cf1, 0x1ebd: 0x2cf9, 0x1ebe: 0x2d01, 0x1ebf: 0x2d09,\n\t// Block 0x7b, offset 0x1ec0\n\t0x1ec0: 0x2d11, 0x1ec1: 0x2d19, 0x1ec2: 0x2d21, 0x1ec3: 0x2d29, 0x1ec4: 0x2d31, 0x1ec5: 0x2d39,\n\t0x1ec6: 0x8f35, 0x1ec7: 0x2d41, 0x1ec8: 0x2d49, 0x1ec9: 0x2d51, 0x1eca: 0x2d59, 0x1ecb: 0x2d61,\n\t0x1ecc: 0x2d69, 0x1ecd: 0x8f55, 0x1ece: 0x2d71, 0x1ecf: 0x2d79, 0x1ed0: 0x8f75, 0x1ed1: 0x8f95,\n\t0x1ed2: 0x2d81, 0x1ed3: 0x2d89, 0x1ed4: 0x2d91, 0x1ed5: 0x2d99, 0x1ed6: 0x2da1, 0x1ed7: 0x2da9,\n\t0x1ed8: 0x2db1, 0x1ed9: 0x2db9, 0x1eda: 0x2dc1, 0x1edb: 0x8fb5, 0x1edc: 0x2dc9, 0x1edd: 0x8fd5,\n\t0x1ede: 0x2dd1, 0x1edf: 0x2040, 0x1ee0: 0x2dd9, 0x1ee1: 0x2de1, 0x1ee2: 0x2de9, 0x1ee3: 0x8ff5,\n\t0x1ee4: 0x2df1, 0x1ee5: 0x2df9, 0x1ee6: 0x9015, 0x1ee7: 0x9035, 0x1ee8: 0x2e01, 0x1ee9: 0x2e09,\n\t0x1eea: 0x2e11, 0x1eeb: 0x2e19, 0x1eec: 0x2e21, 0x1eed: 0x2e21, 0x1eee: 0x2e29, 0x1eef: 0x2e31,\n\t0x1ef0: 0x2e39, 0x1ef1: 0x2e41, 0x1ef2: 0x2e49, 0x1ef3: 0x2e51, 0x1ef4: 0x2e59, 0x1ef5: 0x9055,\n\t0x1ef6: 0x2e61, 0x1ef7: 0x9075, 0x1ef8: 0x2e69, 0x1ef9: 0x9095, 0x1efa: 0x2e71, 0x1efb: 0x90b5,\n\t0x1efc: 0x90d5, 0x1efd: 0x90f5, 0x1efe: 0x2e79, 0x1eff: 0x2e81,\n\t// Block 0x7c, offset 0x1f00\n\t0x1f00: 0x2e89, 0x1f01: 0x9115, 0x1f02: 0x9135, 0x1f03: 0x9155, 0x1f04: 0x9175, 0x1f05: 0x2e91,\n\t0x1f06: 0x2e99, 0x1f07: 0x2e99, 0x1f08: 0x2ea1, 0x1f09: 0x2ea9, 0x1f0a: 0x2eb1, 0x1f0b: 0x2eb9,\n\t0x1f0c: 0x2ec1, 0x1f0d: 0x9195, 0x1f0e: 0x2ec9, 0x1f0f: 0x2ed1, 0x1f10: 0x2ed9, 0x1f11: 0x2ee1,\n\t0x1f12: 0x91b5, 0x1f13: 0x2ee9, 0x1f14: 0x91d5, 0x1f15: 0x91f5, 0x1f16: 0x2ef1, 0x1f17: 0x2ef9,\n\t0x1f18: 0x2f01, 0x1f19: 0x2f09, 0x1f1a: 0x2f11, 0x1f1b: 0x2f19, 0x1f1c: 0x9215, 0x1f1d: 0x9235,\n\t0x1f1e: 0x9255, 0x1f1f: 0x2040, 0x1f20: 0x2f21, 0x1f21: 0x9275, 0x1f22: 0x2f29, 0x1f23: 0x2f31,\n\t0x1f24: 0x2f39, 0x1f25: 0x9295, 0x1f26: 0x2f41, 0x1f27: 0x2f49, 0x1f28: 0x2f51, 0x1f29: 0x2f59,\n\t0x1f2a: 0x2f61, 0x1f2b: 0x92b5, 0x1f2c: 0x2f69, 0x1f2d: 0x2f71, 0x1f2e: 0x2f79, 0x1f2f: 0x2f81,\n\t0x1f30: 0x2f89, 0x1f31: 0x2f91, 0x1f32: 0x92d5, 0x1f33: 0x92f5, 0x1f34: 0x2f99, 0x1f35: 0x9315,\n\t0x1f36: 0x2fa1, 0x1f37: 0x9335, 0x1f38: 0x2fa9, 0x1f39: 0x2fb1, 0x1f3a: 0x2fb9, 0x1f3b: 0x9355,\n\t0x1f3c: 0x9375, 0x1f3d: 0x2fc1, 0x1f3e: 0x9395, 0x1f3f: 0x2fc9,\n\t// Block 0x7d, offset 0x1f40\n\t0x1f40: 0x93b5, 0x1f41: 0x2fd1, 0x1f42: 0x2fd9, 0x1f43: 0x2fe1, 0x1f44: 0x2fe9, 0x1f45: 0x2ff1,\n\t0x1f46: 0x2ff9, 0x1f47: 0x93d5, 0x1f48: 0x93f5, 0x1f49: 0x9415, 0x1f4a: 0x9435, 0x1f4b: 0x2a29,\n\t0x1f4c: 0x3001, 0x1f4d: 0x3009, 0x1f4e: 0x3011, 0x1f4f: 0x3019, 0x1f50: 0x3021, 0x1f51: 0x3029,\n\t0x1f52: 0x3031, 0x1f53: 0x3039, 0x1f54: 0x3041, 0x1f55: 0x3049, 0x1f56: 0x3051, 0x1f57: 0x9455,\n\t0x1f58: 0x3059, 0x1f59: 0x3061, 0x1f5a: 0x3069, 0x1f5b: 0x3071, 0x1f5c: 0x3079, 0x1f5d: 0x3081,\n\t0x1f5e: 0x3089, 0x1f5f: 0x3091, 0x1f60: 0x3099, 0x1f61: 0x30a1, 0x1f62: 0x30a9, 0x1f63: 0x30b1,\n\t0x1f64: 0x9475, 0x1f65: 0x9495, 0x1f66: 0x94b5, 0x1f67: 0x30b9, 0x1f68: 0x30c1, 0x1f69: 0x30c9,\n\t0x1f6a: 0x30d1, 0x1f6b: 0x94d5, 0x1f6c: 0x30d9, 0x1f6d: 0x94f5, 0x1f6e: 0x30e1, 0x1f6f: 0x30e9,\n\t0x1f70: 0x9515, 0x1f71: 0x9535, 0x1f72: 0x30f1, 0x1f73: 0x30f9, 0x1f74: 0x3101, 0x1f75: 0x3109,\n\t0x1f76: 0x3111, 0x1f77: 0x3119, 0x1f78: 0x3121, 0x1f79: 0x3129, 0x1f7a: 0x3131, 0x1f7b: 0x3139,\n\t0x1f7c: 0x3141, 0x1f7d: 0x3149, 0x1f7e: 0x3151, 0x1f7f: 0x2040,\n\t// Block 0x7e, offset 0x1f80\n\t0x1f80: 0x3159, 0x1f81: 0x3161, 0x1f82: 0x3169, 0x1f83: 0x3171, 0x1f84: 0x3179, 0x1f85: 0x9555,\n\t0x1f86: 0x3181, 0x1f87: 0x3189, 0x1f88: 0x3191, 0x1f89: 0x3199, 0x1f8a: 0x31a1, 0x1f8b: 0x9575,\n\t0x1f8c: 0x9595, 0x1f8d: 0x31a9, 0x1f8e: 0x31b1, 0x1f8f: 0x31b9, 0x1f90: 0x31c1, 0x1f91: 0x31c9,\n\t0x1f92: 0x31d1, 0x1f93: 0x95b5, 0x1f94: 0x31d9, 0x1f95: 0x31e1, 0x1f96: 0x31e9, 0x1f97: 0x31f1,\n\t0x1f98: 0x95d5, 0x1f99: 0x95f5, 0x1f9a: 0x31f9, 0x1f9b: 0x3201, 0x1f9c: 0x3209, 0x1f9d: 0x9615,\n\t0x1f9e: 0x3211, 0x1f9f: 0x3219, 0x1fa0: 0x684d, 0x1fa1: 0x9635, 0x1fa2: 0x3221, 0x1fa3: 0x3229,\n\t0x1fa4: 0x3231, 0x1fa5: 0x9655, 0x1fa6: 0x3239, 0x1fa7: 0x3241, 0x1fa8: 0x3249, 0x1fa9: 0x3251,\n\t0x1faa: 0x3259, 0x1fab: 0x3261, 0x1fac: 0x3269, 0x1fad: 0x9675, 0x1fae: 0x3271, 0x1faf: 0x3279,\n\t0x1fb0: 0x3281, 0x1fb1: 0x9695, 0x1fb2: 0x3289, 0x1fb3: 0x3291, 0x1fb4: 0x3299, 0x1fb5: 0x32a1,\n\t0x1fb6: 0x7b6d, 0x1fb7: 0x96b5, 0x1fb8: 0x32a9, 0x1fb9: 0x32b1, 0x1fba: 0x32b9, 0x1fbb: 0x96d5,\n\t0x1fbc: 0x32c1, 0x1fbd: 0x96f5, 0x1fbe: 0x32c9, 0x1fbf: 0x32c9,\n\t// Block 0x7f, offset 0x1fc0\n\t0x1fc0: 0x32d1, 0x1fc1: 0x9715, 0x1fc2: 0x32d9, 0x1fc3: 0x32e1, 0x1fc4: 0x32e9, 0x1fc5: 0x32f1,\n\t0x1fc6: 0x32f9, 0x1fc7: 0x3301, 0x1fc8: 0x3309, 0x1fc9: 0x9735, 0x1fca: 0x3311, 0x1fcb: 0x3319,\n\t0x1fcc: 0x3321, 0x1fcd: 0x3329, 0x1fce: 0x3331, 0x1fcf: 0x3339, 0x1fd0: 0x9755, 0x1fd1: 0x3341,\n\t0x1fd2: 0x9775, 0x1fd3: 0x9795, 0x1fd4: 0x97b5, 0x1fd5: 0x3349, 0x1fd6: 0x3351, 0x1fd7: 0x3359,\n\t0x1fd8: 0x3361, 0x1fd9: 0x3369, 0x1fda: 0x3371, 0x1fdb: 0x3379, 0x1fdc: 0x3381, 0x1fdd: 0x97d5,\n\t0x1fde: 0x0040, 0x1fdf: 0x0040, 0x1fe0: 0x0040, 0x1fe1: 0x0040, 0x1fe2: 0x0040, 0x1fe3: 0x0040,\n\t0x1fe4: 0x0040, 0x1fe5: 0x0040, 0x1fe6: 0x0040, 0x1fe7: 0x0040, 0x1fe8: 0x0040, 0x1fe9: 0x0040,\n\t0x1fea: 0x0040, 0x1feb: 0x0040, 0x1fec: 0x0040, 0x1fed: 0x0040, 0x1fee: 0x0040, 0x1fef: 0x0040,\n\t0x1ff0: 0x0040, 0x1ff1: 0x0040, 0x1ff2: 0x0040, 0x1ff3: 0x0040, 0x1ff4: 0x0040, 0x1ff5: 0x0040,\n\t0x1ff6: 0x0040, 0x1ff7: 0x0040, 0x1ff8: 0x0040, 0x1ff9: 0x0040, 0x1ffa: 0x0040, 0x1ffb: 0x0040,\n\t0x1ffc: 0x0040, 0x1ffd: 0x0040, 0x1ffe: 0x0040, 0x1fff: 0x0040,\n}\n\n// idnaIndex: 37 blocks, 2368 entries, 4736 bytes\n// Block 0 is the zero block.\nvar idnaIndex = [2368]uint16{\n\t// Block 0x0, offset 0x0\n\t// Block 0x1, offset 0x40\n\t// Block 0x2, offset 0x80\n\t// Block 0x3, offset 0xc0\n\t0xc2: 0x01, 0xc3: 0x7e, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05,\n\t0xc8: 0x06, 0xc9: 0x7f, 0xca: 0x80, 0xcb: 0x07, 0xcc: 0x81, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a,\n\t0xd0: 0x82, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x83, 0xd6: 0x84, 0xd7: 0x85,\n\t0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x86, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x87, 0xde: 0x88, 0xdf: 0x89,\n\t0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07,\n\t0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c,\n\t0xf0: 0x1e, 0xf1: 0x1f, 0xf2: 0x1f, 0xf3: 0x21, 0xf4: 0x22,\n\t// Block 0x4, offset 0x100\n\t0x120: 0x8a, 0x121: 0x13, 0x122: 0x8b, 0x123: 0x8c, 0x124: 0x8d, 0x125: 0x14, 0x126: 0x15, 0x127: 0x16,\n\t0x128: 0x17, 0x129: 0x18, 0x12a: 0x19, 0x12b: 0x1a, 0x12c: 0x1b, 0x12d: 0x1c, 0x12e: 0x1d, 0x12f: 0x8e,\n\t0x130: 0x8f, 0x131: 0x1e, 0x132: 0x1f, 0x133: 0x20, 0x134: 0x90, 0x135: 0x21, 0x136: 0x91, 0x137: 0x92,\n\t0x138: 0x93, 0x139: 0x94, 0x13a: 0x22, 0x13b: 0x95, 0x13c: 0x96, 0x13d: 0x23, 0x13e: 0x24, 0x13f: 0x97,\n\t// Block 0x5, offset 0x140\n\t0x140: 0x98, 0x141: 0x99, 0x142: 0x9a, 0x143: 0x9b, 0x144: 0x9c, 0x145: 0x9d, 0x146: 0x9e, 0x147: 0x9f,\n\t0x148: 0xa0, 0x149: 0xa1, 0x14a: 0xa2, 0x14b: 0xa3, 0x14c: 0xa4, 0x14d: 0xa5, 0x14e: 0xa6, 0x14f: 0xa7,\n\t0x150: 0xa8, 0x151: 0xa0, 0x152: 0xa0, 0x153: 0xa0, 0x154: 0xa0, 0x155: 0xa0, 0x156: 0xa0, 0x157: 0xa0,\n\t0x158: 0xa0, 0x159: 0xa9, 0x15a: 0xaa, 0x15b: 0xab, 0x15c: 0xac, 0x15d: 0xad, 0x15e: 0xae, 0x15f: 0xaf,\n\t0x160: 0xb0, 0x161: 0xb1, 0x162: 0xb2, 0x163: 0xb3, 0x164: 0xb4, 0x165: 0xb5, 0x166: 0xb6, 0x167: 0xb7,\n\t0x168: 0xb8, 0x169: 0xb9, 0x16a: 0xba, 0x16b: 0xbb, 0x16c: 0xbc, 0x16d: 0xbd, 0x16e: 0xbe, 0x16f: 0xbf,\n\t0x170: 0xc0, 0x171: 0xc1, 0x172: 0xc2, 0x173: 0xc3, 0x174: 0x25, 0x175: 0x26, 0x176: 0x27, 0x177: 0xc4,\n\t0x178: 0x28, 0x179: 0x28, 0x17a: 0x29, 0x17b: 0x28, 0x17c: 0xc5, 0x17d: 0x2a, 0x17e: 0x2b, 0x17f: 0x2c,\n\t// Block 0x6, offset 0x180\n\t0x180: 0x2d, 0x181: 0x2e, 0x182: 0x2f, 0x183: 0xc6, 0x184: 0x30, 0x185: 0x31, 0x186: 0xc7, 0x187: 0x9c,\n\t0x188: 0xc8, 0x189: 0xc9, 0x18a: 0x9c, 0x18b: 0x9c, 0x18c: 0xca, 0x18d: 0x9c, 0x18e: 0x9c, 0x18f: 0x9c,\n\t0x190: 0xcb, 0x191: 0x32, 0x192: 0x33, 0x193: 0x34, 0x194: 0x9c, 0x195: 0x9c, 0x196: 0x9c, 0x197: 0x9c,\n\t0x198: 0x9c, 0x199: 0x9c, 0x19a: 0x9c, 0x19b: 0x9c, 0x19c: 0x9c, 0x19d: 0x9c, 0x19e: 0x9c, 0x19f: 0x9c,\n\t0x1a0: 0x9c, 0x1a1: 0x9c, 0x1a2: 0x9c, 0x1a3: 0x9c, 0x1a4: 0x9c, 0x1a5: 0x9c, 0x1a6: 0x9c, 0x1a7: 0x9c,\n\t0x1a8: 0xcc, 0x1a9: 0xcd, 0x1aa: 0x9c, 0x1ab: 0xce, 0x1ac: 0x9c, 0x1ad: 0xcf, 0x1ae: 0xd0, 0x1af: 0x9c,\n\t0x1b0: 0xd1, 0x1b1: 0x35, 0x1b2: 0x28, 0x1b3: 0x36, 0x1b4: 0xd2, 0x1b5: 0xd3, 0x1b6: 0xd4, 0x1b7: 0xd5,\n\t0x1b8: 0xd6, 0x1b9: 0xd7, 0x1ba: 0xd8, 0x1bb: 0xd9, 0x1bc: 0xda, 0x1bd: 0xdb, 0x1be: 0xdc, 0x1bf: 0x37,\n\t// Block 0x7, offset 0x1c0\n\t0x1c0: 0x38, 0x1c1: 0xdd, 0x1c2: 0xde, 0x1c3: 0xdf, 0x1c4: 0xe0, 0x1c5: 0x39, 0x1c6: 0x3a, 0x1c7: 0xe1,\n\t0x1c8: 0xe2, 0x1c9: 0x3b, 0x1ca: 0x3c, 0x1cb: 0x3d, 0x1cc: 0xe3, 0x1cd: 0xe4, 0x1ce: 0x3e, 0x1cf: 0x3f,\n\t0x1d0: 0xa0, 0x1d1: 0xa0, 0x1d2: 0xa0, 0x1d3: 0xa0, 0x1d4: 0xa0, 0x1d5: 0xa0, 0x1d6: 0xa0, 0x1d7: 0xa0,\n\t0x1d8: 0xa0, 0x1d9: 0xa0, 0x1da: 0xa0, 0x1db: 0xa0, 0x1dc: 0xa0, 0x1dd: 0xa0, 0x1de: 0xa0, 0x1df: 0xa0,\n\t0x1e0: 0xa0, 0x1e1: 0xa0, 0x1e2: 0xa0, 0x1e3: 0xa0, 0x1e4: 0xa0, 0x1e5: 0xa0, 0x1e6: 0xa0, 0x1e7: 0xa0,\n\t0x1e8: 0xa0, 0x1e9: 0xa0, 0x1ea: 0xa0, 0x1eb: 0xa0, 0x1ec: 0xa0, 0x1ed: 0xa0, 0x1ee: 0xa0, 0x1ef: 0xa0,\n\t0x1f0: 0xa0, 0x1f1: 0xa0, 0x1f2: 0xa0, 0x1f3: 0xa0, 0x1f4: 0xa0, 0x1f5: 0xa0, 0x1f6: 0xa0, 0x1f7: 0xa0,\n\t0x1f8: 0xa0, 0x1f9: 0xa0, 0x1fa: 0xa0, 0x1fb: 0xa0, 0x1fc: 0xa0, 0x1fd: 0xa0, 0x1fe: 0xa0, 0x1ff: 0xa0,\n\t// Block 0x8, offset 0x200\n\t0x200: 0xa0, 0x201: 0xa0, 0x202: 0xa0, 0x203: 0xa0, 0x204: 0xa0, 0x205: 0xa0, 0x206: 0xa0, 0x207: 0xa0,\n\t0x208: 0xa0, 0x209: 0xa0, 0x20a: 0xa0, 0x20b: 0xa0, 0x20c: 0xa0, 0x20d: 0xa0, 0x20e: 0xa0, 0x20f: 0xa0,\n\t0x210: 0xa0, 0x211: 0xa0, 0x212: 0xa0, 0x213: 0xa0, 0x214: 0xa0, 0x215: 0xa0, 0x216: 0xa0, 0x217: 0xa0,\n\t0x218: 0xa0, 0x219: 0xa0, 0x21a: 0xa0, 0x21b: 0xa0, 0x21c: 0xa0, 0x21d: 0xa0, 0x21e: 0xa0, 0x21f: 0xa0,\n\t0x220: 0xa0, 0x221: 0xa0, 0x222: 0xa0, 0x223: 0xa0, 0x224: 0xa0, 0x225: 0xa0, 0x226: 0xa0, 0x227: 0xa0,\n\t0x228: 0xa0, 0x229: 0xa0, 0x22a: 0xa0, 0x22b: 0xa0, 0x22c: 0xa0, 0x22d: 0xa0, 0x22e: 0xa0, 0x22f: 0xa0,\n\t0x230: 0xa0, 0x231: 0xa0, 0x232: 0xa0, 0x233: 0xa0, 0x234: 0xa0, 0x235: 0xa0, 0x236: 0xa0, 0x237: 0x9c,\n\t0x238: 0xa0, 0x239: 0xa0, 0x23a: 0xa0, 0x23b: 0xa0, 0x23c: 0xa0, 0x23d: 0xa0, 0x23e: 0xa0, 0x23f: 0xa0,\n\t// Block 0x9, offset 0x240\n\t0x240: 0xa0, 0x241: 0xa0, 0x242: 0xa0, 0x243: 0xa0, 0x244: 0xa0, 0x245: 0xa0, 0x246: 0xa0, 0x247: 0xa0,\n\t0x248: 0xa0, 0x249: 0xa0, 0x24a: 0xa0, 0x24b: 0xa0, 0x24c: 0xa0, 0x24d: 0xa0, 0x24e: 0xa0, 0x24f: 0xa0,\n\t0x250: 0xa0, 0x251: 0xa0, 0x252: 0xa0, 0x253: 0xa0, 0x254: 0xa0, 0x255: 0xa0, 0x256: 0xa0, 0x257: 0xa0,\n\t0x258: 0xa0, 0x259: 0xa0, 0x25a: 0xa0, 0x25b: 0xa0, 0x25c: 0xa0, 0x25d: 0xa0, 0x25e: 0xa0, 0x25f: 0xa0,\n\t0x260: 0xa0, 0x261: 0xa0, 0x262: 0xa0, 0x263: 0xa0, 0x264: 0xa0, 0x265: 0xa0, 0x266: 0xa0, 0x267: 0xa0,\n\t0x268: 0xa0, 0x269: 0xa0, 0x26a: 0xa0, 0x26b: 0xa0, 0x26c: 0xa0, 0x26d: 0xa0, 0x26e: 0xa0, 0x26f: 0xa0,\n\t0x270: 0xa0, 0x271: 0xa0, 0x272: 0xa0, 0x273: 0xa0, 0x274: 0xa0, 0x275: 0xa0, 0x276: 0xa0, 0x277: 0xa0,\n\t0x278: 0xa0, 0x279: 0xa0, 0x27a: 0xa0, 0x27b: 0xa0, 0x27c: 0xa0, 0x27d: 0xa0, 0x27e: 0xa0, 0x27f: 0xa0,\n\t// Block 0xa, offset 0x280\n\t0x280: 0xa0, 0x281: 0xa0, 0x282: 0xa0, 0x283: 0xa0, 0x284: 0xa0, 0x285: 0xa0, 0x286: 0xa0, 0x287: 0xa0,\n\t0x288: 0xa0, 0x289: 0xa0, 0x28a: 0xa0, 0x28b: 0xa0, 0x28c: 0xa0, 0x28d: 0xa0, 0x28e: 0xa0, 0x28f: 0xa0,\n\t0x290: 0xa0, 0x291: 0xa0, 0x292: 0xa0, 0x293: 0xa0, 0x294: 0xa0, 0x295: 0xa0, 0x296: 0xa0, 0x297: 0xa0,\n\t0x298: 0xa0, 0x299: 0xa0, 0x29a: 0xa0, 0x29b: 0xa0, 0x29c: 0xa0, 0x29d: 0xa0, 0x29e: 0xa0, 0x29f: 0xa0,\n\t0x2a0: 0xa0, 0x2a1: 0xa0, 0x2a2: 0xa0, 0x2a3: 0xa0, 0x2a4: 0xa0, 0x2a5: 0xa0, 0x2a6: 0xa0, 0x2a7: 0xa0,\n\t0x2a8: 0xa0, 0x2a9: 0xa0, 0x2aa: 0xa0, 0x2ab: 0xa0, 0x2ac: 0xa0, 0x2ad: 0xa0, 0x2ae: 0xa0, 0x2af: 0xa0,\n\t0x2b0: 0xa0, 0x2b1: 0xa0, 0x2b2: 0xa0, 0x2b3: 0xa0, 0x2b4: 0xa0, 0x2b5: 0xa0, 0x2b6: 0xa0, 0x2b7: 0xa0,\n\t0x2b8: 0xa0, 0x2b9: 0xa0, 0x2ba: 0xa0, 0x2bb: 0xa0, 0x2bc: 0xa0, 0x2bd: 0xa0, 0x2be: 0xa0, 0x2bf: 0xe5,\n\t// Block 0xb, offset 0x2c0\n\t0x2c0: 0xa0, 0x2c1: 0xa0, 0x2c2: 0xa0, 0x2c3: 0xa0, 0x2c4: 0xa0, 0x2c5: 0xa0, 0x2c6: 0xa0, 0x2c7: 0xa0,\n\t0x2c8: 0xa0, 0x2c9: 0xa0, 0x2ca: 0xa0, 0x2cb: 0xa0, 0x2cc: 0xa0, 0x2cd: 0xa0, 0x2ce: 0xa0, 0x2cf: 0xa0,\n\t0x2d0: 0xa0, 0x2d1: 0xa0, 0x2d2: 0xe6, 0x2d3: 0xe7, 0x2d4: 0xa0, 0x2d5: 0xa0, 0x2d6: 0xa0, 0x2d7: 0xa0,\n\t0x2d8: 0xe8, 0x2d9: 0x40, 0x2da: 0x41, 0x2db: 0xe9, 0x2dc: 0x42, 0x2dd: 0x43, 0x2de: 0x44, 0x2df: 0xea,\n\t0x2e0: 0xeb, 0x2e1: 0xec, 0x2e2: 0xed, 0x2e3: 0xee, 0x2e4: 0xef, 0x2e5: 0xf0, 0x2e6: 0xf1, 0x2e7: 0xf2,\n\t0x2e8: 0xf3, 0x2e9: 0xf4, 0x2ea: 0xf5, 0x2eb: 0xf6, 0x2ec: 0xf7, 0x2ed: 0xf8, 0x2ee: 0xf9, 0x2ef: 0xfa,\n\t0x2f0: 0xa0, 0x2f1: 0xa0, 0x2f2: 0xa0, 0x2f3: 0xa0, 0x2f4: 0xa0, 0x2f5: 0xa0, 0x2f6: 0xa0, 0x2f7: 0xa0,\n\t0x2f8: 0xa0, 0x2f9: 0xa0, 0x2fa: 0xa0, 0x2fb: 0xa0, 0x2fc: 0xa0, 0x2fd: 0xa0, 0x2fe: 0xa0, 0x2ff: 0xa0,\n\t// Block 0xc, offset 0x300\n\t0x300: 0xa0, 0x301: 0xa0, 0x302: 0xa0, 0x303: 0xa0, 0x304: 0xa0, 0x305: 0xa0, 0x306: 0xa0, 0x307: 0xa0,\n\t0x308: 0xa0, 0x309: 0xa0, 0x30a: 0xa0, 0x30b: 0xa0, 0x30c: 0xa0, 0x30d: 0xa0, 0x30e: 0xa0, 0x30f: 0xa0,\n\t0x310: 0xa0, 0x311: 0xa0, 0x312: 0xa0, 0x313: 0xa0, 0x314: 0xa0, 0x315: 0xa0, 0x316: 0xa0, 0x317: 0xa0,\n\t0x318: 0xa0, 0x319: 0xa0, 0x31a: 0xa0, 0x31b: 0xa0, 0x31c: 0xa0, 0x31d: 0xa0, 0x31e: 0xfb, 0x31f: 0xfc,\n\t// Block 0xd, offset 0x340\n\t0x340: 0xfd, 0x341: 0xfd, 0x342: 0xfd, 0x343: 0xfd, 0x344: 0xfd, 0x345: 0xfd, 0x346: 0xfd, 0x347: 0xfd,\n\t0x348: 0xfd, 0x349: 0xfd, 0x34a: 0xfd, 0x34b: 0xfd, 0x34c: 0xfd, 0x34d: 0xfd, 0x34e: 0xfd, 0x34f: 0xfd,\n\t0x350: 0xfd, 0x351: 0xfd, 0x352: 0xfd, 0x353: 0xfd, 0x354: 0xfd, 0x355: 0xfd, 0x356: 0xfd, 0x357: 0xfd,\n\t0x358: 0xfd, 0x359: 0xfd, 0x35a: 0xfd, 0x35b: 0xfd, 0x35c: 0xfd, 0x35d: 0xfd, 0x35e: 0xfd, 0x35f: 0xfd,\n\t0x360: 0xfd, 0x361: 0xfd, 0x362: 0xfd, 0x363: 0xfd, 0x364: 0xfd, 0x365: 0xfd, 0x366: 0xfd, 0x367: 0xfd,\n\t0x368: 0xfd, 0x369: 0xfd, 0x36a: 0xfd, 0x36b: 0xfd, 0x36c: 0xfd, 0x36d: 0xfd, 0x36e: 0xfd, 0x36f: 0xfd,\n\t0x370: 0xfd, 0x371: 0xfd, 0x372: 0xfd, 0x373: 0xfd, 0x374: 0xfd, 0x375: 0xfd, 0x376: 0xfd, 0x377: 0xfd,\n\t0x378: 0xfd, 0x379: 0xfd, 0x37a: 0xfd, 0x37b: 0xfd, 0x37c: 0xfd, 0x37d: 0xfd, 0x37e: 0xfd, 0x37f: 0xfd,\n\t// Block 0xe, offset 0x380\n\t0x380: 0xfd, 0x381: 0xfd, 0x382: 0xfd, 0x383: 0xfd, 0x384: 0xfd, 0x385: 0xfd, 0x386: 0xfd, 0x387: 0xfd,\n\t0x388: 0xfd, 0x389: 0xfd, 0x38a: 0xfd, 0x38b: 0xfd, 0x38c: 0xfd, 0x38d: 0xfd, 0x38e: 0xfd, 0x38f: 0xfd,\n\t0x390: 0xfd, 0x391: 0xfd, 0x392: 0xfd, 0x393: 0xfd, 0x394: 0xfd, 0x395: 0xfd, 0x396: 0xfd, 0x397: 0xfd,\n\t0x398: 0xfd, 0x399: 0xfd, 0x39a: 0xfd, 0x39b: 0xfd, 0x39c: 0xfd, 0x39d: 0xfd, 0x39e: 0xfd, 0x39f: 0xfd,\n\t0x3a0: 0xfd, 0x3a1: 0xfd, 0x3a2: 0xfd, 0x3a3: 0xfd, 0x3a4: 0xfe, 0x3a5: 0xff, 0x3a6: 0x100, 0x3a7: 0x101,\n\t0x3a8: 0x45, 0x3a9: 0x102, 0x3aa: 0x103, 0x3ab: 0x46, 0x3ac: 0x47, 0x3ad: 0x48, 0x3ae: 0x49, 0x3af: 0x4a,\n\t0x3b0: 0x104, 0x3b1: 0x4b, 0x3b2: 0x4c, 0x3b3: 0x4d, 0x3b4: 0x4e, 0x3b5: 0x4f, 0x3b6: 0x105, 0x3b7: 0x50,\n\t0x3b8: 0x51, 0x3b9: 0x52, 0x3ba: 0x53, 0x3bb: 0x54, 0x3bc: 0x55, 0x3bd: 0x56, 0x3be: 0x57, 0x3bf: 0x58,\n\t// Block 0xf, offset 0x3c0\n\t0x3c0: 0x106, 0x3c1: 0x107, 0x3c2: 0xa0, 0x3c3: 0x108, 0x3c4: 0x109, 0x3c5: 0x9c, 0x3c6: 0x10a, 0x3c7: 0x10b,\n\t0x3c8: 0xfd, 0x3c9: 0xfd, 0x3ca: 0x10c, 0x3cb: 0x10d, 0x3cc: 0x10e, 0x3cd: 0x10f, 0x3ce: 0x110, 0x3cf: 0x111,\n\t0x3d0: 0x112, 0x3d1: 0xa0, 0x3d2: 0x113, 0x3d3: 0x114, 0x3d4: 0x115, 0x3d5: 0x116, 0x3d6: 0xfd, 0x3d7: 0xfd,\n\t0x3d8: 0xa0, 0x3d9: 0xa0, 0x3da: 0xa0, 0x3db: 0xa0, 0x3dc: 0x117, 0x3dd: 0x118, 0x3de: 0xfd, 0x3df: 0xfd,\n\t0x3e0: 0x119, 0x3e1: 0x11a, 0x3e2: 0x11b, 0x3e3: 0x11c, 0x3e4: 0x11d, 0x3e5: 0xfd, 0x3e6: 0x11e, 0x3e7: 0x11f,\n\t0x3e8: 0x120, 0x3e9: 0x121, 0x3ea: 0x122, 0x3eb: 0x59, 0x3ec: 0x123, 0x3ed: 0x124, 0x3ee: 0x5a, 0x3ef: 0xfd,\n\t0x3f0: 0x125, 0x3f1: 0x126, 0x3f2: 0x127, 0x3f3: 0x128, 0x3f4: 0x129, 0x3f5: 0xfd, 0x3f6: 0xfd, 0x3f7: 0xfd,\n\t0x3f8: 0xfd, 0x3f9: 0x12a, 0x3fa: 0x12b, 0x3fb: 0xfd, 0x3fc: 0x12c, 0x3fd: 0x12d, 0x3fe: 0x12e, 0x3ff: 0x12f,\n\t// Block 0x10, offset 0x400\n\t0x400: 0x130, 0x401: 0x131, 0x402: 0x132, 0x403: 0x133, 0x404: 0x134, 0x405: 0x135, 0x406: 0x136, 0x407: 0x137,\n\t0x408: 0x138, 0x409: 0xfd, 0x40a: 0x139, 0x40b: 0x13a, 0x40c: 0x5b, 0x40d: 0x5c, 0x40e: 0xfd, 0x40f: 0xfd,\n\t0x410: 0x13b, 0x411: 0x13c, 0x412: 0x13d, 0x413: 0x13e, 0x414: 0xfd, 0x415: 0xfd, 0x416: 0x13f, 0x417: 0x140,\n\t0x418: 0x141, 0x419: 0x142, 0x41a: 0x143, 0x41b: 0x144, 0x41c: 0x145, 0x41d: 0xfd, 0x41e: 0xfd, 0x41f: 0xfd,\n\t0x420: 0x146, 0x421: 0xfd, 0x422: 0x147, 0x423: 0x148, 0x424: 0x5d, 0x425: 0x149, 0x426: 0x14a, 0x427: 0x14b,\n\t0x428: 0x14c, 0x429: 0x14d, 0x42a: 0x14e, 0x42b: 0x14f, 0x42c: 0xfd, 0x42d: 0xfd, 0x42e: 0xfd, 0x42f: 0xfd,\n\t0x430: 0x150, 0x431: 0x151, 0x432: 0x152, 0x433: 0xfd, 0x434: 0x153, 0x435: 0x154, 0x436: 0x155, 0x437: 0xfd,\n\t0x438: 0xfd, 0x439: 0xfd, 0x43a: 0xfd, 0x43b: 0x156, 0x43c: 0xfd, 0x43d: 0xfd, 0x43e: 0x157, 0x43f: 0x158,\n\t// Block 0x11, offset 0x440\n\t0x440: 0xa0, 0x441: 0xa0, 0x442: 0xa0, 0x443: 0xa0, 0x444: 0xa0, 0x445: 0xa0, 0x446: 0xa0, 0x447: 0xa0,\n\t0x448: 0xa0, 0x449: 0xa0, 0x44a: 0xa0, 0x44b: 0xa0, 0x44c: 0xa0, 0x44d: 0xa0, 0x44e: 0x159, 0x44f: 0xfd,\n\t0x450: 0x9c, 0x451: 0x15a, 0x452: 0xa0, 0x453: 0xa0, 0x454: 0xa0, 0x455: 0x15b, 0x456: 0xfd, 0x457: 0xfd,\n\t0x458: 0xfd, 0x459: 0xfd, 0x45a: 0xfd, 0x45b: 0xfd, 0x45c: 0xfd, 0x45d: 0xfd, 0x45e: 0xfd, 0x45f: 0xfd,\n\t0x460: 0xfd, 0x461: 0xfd, 0x462: 0xfd, 0x463: 0xfd, 0x464: 0xfd, 0x465: 0xfd, 0x466: 0xfd, 0x467: 0xfd,\n\t0x468: 0xfd, 0x469: 0xfd, 0x46a: 0xfd, 0x46b: 0xfd, 0x46c: 0xfd, 0x46d: 0xfd, 0x46e: 0xfd, 0x46f: 0xfd,\n\t0x470: 0xfd, 0x471: 0xfd, 0x472: 0xfd, 0x473: 0xfd, 0x474: 0xfd, 0x475: 0xfd, 0x476: 0xfd, 0x477: 0xfd,\n\t0x478: 0xfd, 0x479: 0xfd, 0x47a: 0xfd, 0x47b: 0xfd, 0x47c: 0xfd, 0x47d: 0xfd, 0x47e: 0xfd, 0x47f: 0xfd,\n\t// Block 0x12, offset 0x480\n\t0x480: 0xa0, 0x481: 0xa0, 0x482: 0xa0, 0x483: 0xa0, 0x484: 0xa0, 0x485: 0xa0, 0x486: 0xa0, 0x487: 0xa0,\n\t0x488: 0xa0, 0x489: 0xa0, 0x48a: 0xa0, 0x48b: 0xa0, 0x48c: 0xa0, 0x48d: 0xa0, 0x48e: 0xa0, 0x48f: 0xa0,\n\t0x490: 0x15c, 0x491: 0xfd, 0x492: 0xfd, 0x493: 0xfd, 0x494: 0xfd, 0x495: 0xfd, 0x496: 0xfd, 0x497: 0xfd,\n\t0x498: 0xfd, 0x499: 0xfd, 0x49a: 0xfd, 0x49b: 0xfd, 0x49c: 0xfd, 0x49d: 0xfd, 0x49e: 0xfd, 0x49f: 0xfd,\n\t0x4a0: 0xfd, 0x4a1: 0xfd, 0x4a2: 0xfd, 0x4a3: 0xfd, 0x4a4: 0xfd, 0x4a5: 0xfd, 0x4a6: 0xfd, 0x4a7: 0xfd,\n\t0x4a8: 0xfd, 0x4a9: 0xfd, 0x4aa: 0xfd, 0x4ab: 0xfd, 0x4ac: 0xfd, 0x4ad: 0xfd, 0x4ae: 0xfd, 0x4af: 0xfd,\n\t0x4b0: 0xfd, 0x4b1: 0xfd, 0x4b2: 0xfd, 0x4b3: 0xfd, 0x4b4: 0xfd, 0x4b5: 0xfd, 0x4b6: 0xfd, 0x4b7: 0xfd,\n\t0x4b8: 0xfd, 0x4b9: 0xfd, 0x4ba: 0xfd, 0x4bb: 0xfd, 0x4bc: 0xfd, 0x4bd: 0xfd, 0x4be: 0xfd, 0x4bf: 0xfd,\n\t// Block 0x13, offset 0x4c0\n\t0x4c0: 0xfd, 0x4c1: 0xfd, 0x4c2: 0xfd, 0x4c3: 0xfd, 0x4c4: 0xfd, 0x4c5: 0xfd, 0x4c6: 0xfd, 0x4c7: 0xfd,\n\t0x4c8: 0xfd, 0x4c9: 0xfd, 0x4ca: 0xfd, 0x4cb: 0xfd, 0x4cc: 0xfd, 0x4cd: 0xfd, 0x4ce: 0xfd, 0x4cf: 0xfd,\n\t0x4d0: 0xa0, 0x4d1: 0xa0, 0x4d2: 0xa0, 0x4d3: 0xa0, 0x4d4: 0xa0, 0x4d5: 0xa0, 0x4d6: 0xa0, 0x4d7: 0xa0,\n\t0x4d8: 0xa0, 0x4d9: 0x15d, 0x4da: 0xfd, 0x4db: 0xfd, 0x4dc: 0xfd, 0x4dd: 0xfd, 0x4de: 0xfd, 0x4df: 0xfd,\n\t0x4e0: 0xfd, 0x4e1: 0xfd, 0x4e2: 0xfd, 0x4e3: 0xfd, 0x4e4: 0xfd, 0x4e5: 0xfd, 0x4e6: 0xfd, 0x4e7: 0xfd,\n\t0x4e8: 0xfd, 0x4e9: 0xfd, 0x4ea: 0xfd, 0x4eb: 0xfd, 0x4ec: 0xfd, 0x4ed: 0xfd, 0x4ee: 0xfd, 0x4ef: 0xfd,\n\t0x4f0: 0xfd, 0x4f1: 0xfd, 0x4f2: 0xfd, 0x4f3: 0xfd, 0x4f4: 0xfd, 0x4f5: 0xfd, 0x4f6: 0xfd, 0x4f7: 0xfd,\n\t0x4f8: 0xfd, 0x4f9: 0xfd, 0x4fa: 0xfd, 0x4fb: 0xfd, 0x4fc: 0xfd, 0x4fd: 0xfd, 0x4fe: 0xfd, 0x4ff: 0xfd,\n\t// Block 0x14, offset 0x500\n\t0x500: 0xfd, 0x501: 0xfd, 0x502: 0xfd, 0x503: 0xfd, 0x504: 0xfd, 0x505: 0xfd, 0x506: 0xfd, 0x507: 0xfd,\n\t0x508: 0xfd, 0x509: 0xfd, 0x50a: 0xfd, 0x50b: 0xfd, 0x50c: 0xfd, 0x50d: 0xfd, 0x50e: 0xfd, 0x50f: 0xfd,\n\t0x510: 0xfd, 0x511: 0xfd, 0x512: 0xfd, 0x513: 0xfd, 0x514: 0xfd, 0x515: 0xfd, 0x516: 0xfd, 0x517: 0xfd,\n\t0x518: 0xfd, 0x519: 0xfd, 0x51a: 0xfd, 0x51b: 0xfd, 0x51c: 0xfd, 0x51d: 0xfd, 0x51e: 0xfd, 0x51f: 0xfd,\n\t0x520: 0xa0, 0x521: 0xa0, 0x522: 0xa0, 0x523: 0xa0, 0x524: 0xa0, 0x525: 0xa0, 0x526: 0xa0, 0x527: 0xa0,\n\t0x528: 0x14f, 0x529: 0x15e, 0x52a: 0xfd, 0x52b: 0x15f, 0x52c: 0x160, 0x52d: 0x161, 0x52e: 0x162, 0x52f: 0xfd,\n\t0x530: 0xfd, 0x531: 0xfd, 0x532: 0xfd, 0x533: 0xfd, 0x534: 0xfd, 0x535: 0xfd, 0x536: 0xfd, 0x537: 0xfd,\n\t0x538: 0xfd, 0x539: 0x163, 0x53a: 0x164, 0x53b: 0xfd, 0x53c: 0xa0, 0x53d: 0x165, 0x53e: 0x166, 0x53f: 0x167,\n\t// Block 0x15, offset 0x540\n\t0x540: 0xa0, 0x541: 0xa0, 0x542: 0xa0, 0x543: 0xa0, 0x544: 0xa0, 0x545: 0xa0, 0x546: 0xa0, 0x547: 0xa0,\n\t0x548: 0xa0, 0x549: 0xa0, 0x54a: 0xa0, 0x54b: 0xa0, 0x54c: 0xa0, 0x54d: 0xa0, 0x54e: 0xa0, 0x54f: 0xa0,\n\t0x550: 0xa0, 0x551: 0xa0, 0x552: 0xa0, 0x553: 0xa0, 0x554: 0xa0, 0x555: 0xa0, 0x556: 0xa0, 0x557: 0xa0,\n\t0x558: 0xa0, 0x559: 0xa0, 0x55a: 0xa0, 0x55b: 0xa0, 0x55c: 0xa0, 0x55d: 0xa0, 0x55e: 0xa0, 0x55f: 0x168,\n\t0x560: 0xa0, 0x561: 0xa0, 0x562: 0xa0, 0x563: 0xa0, 0x564: 0xa0, 0x565: 0xa0, 0x566: 0xa0, 0x567: 0xa0,\n\t0x568: 0xa0, 0x569: 0xa0, 0x56a: 0xa0, 0x56b: 0xa0, 0x56c: 0xa0, 0x56d: 0xa0, 0x56e: 0xa0, 0x56f: 0xa0,\n\t0x570: 0xa0, 0x571: 0xa0, 0x572: 0xa0, 0x573: 0x169, 0x574: 0x16a, 0x575: 0xfd, 0x576: 0xfd, 0x577: 0xfd,\n\t0x578: 0xfd, 0x579: 0xfd, 0x57a: 0xfd, 0x57b: 0xfd, 0x57c: 0xfd, 0x57d: 0xfd, 0x57e: 0xfd, 0x57f: 0xfd,\n\t// Block 0x16, offset 0x580\n\t0x580: 0xa0, 0x581: 0xa0, 0x582: 0xa0, 0x583: 0xa0, 0x584: 0x16b, 0x585: 0x16c, 0x586: 0xa0, 0x587: 0xa0,\n\t0x588: 0xa0, 0x589: 0xa0, 0x58a: 0xa0, 0x58b: 0x16d, 0x58c: 0xfd, 0x58d: 0xfd, 0x58e: 0xfd, 0x58f: 0xfd,\n\t0x590: 0xfd, 0x591: 0xfd, 0x592: 0xfd, 0x593: 0xfd, 0x594: 0xfd, 0x595: 0xfd, 0x596: 0xfd, 0x597: 0xfd,\n\t0x598: 0xfd, 0x599: 0xfd, 0x59a: 0xfd, 0x59b: 0xfd, 0x59c: 0xfd, 0x59d: 0xfd, 0x59e: 0xfd, 0x59f: 0xfd,\n\t0x5a0: 0xfd, 0x5a1: 0xfd, 0x5a2: 0xfd, 0x5a3: 0xfd, 0x5a4: 0xfd, 0x5a5: 0xfd, 0x5a6: 0xfd, 0x5a7: 0xfd,\n\t0x5a8: 0xfd, 0x5a9: 0xfd, 0x5aa: 0xfd, 0x5ab: 0xfd, 0x5ac: 0xfd, 0x5ad: 0xfd, 0x5ae: 0xfd, 0x5af: 0xfd,\n\t0x5b0: 0xa0, 0x5b1: 0x16e, 0x5b2: 0x16f, 0x5b3: 0xfd, 0x5b4: 0xfd, 0x5b5: 0xfd, 0x5b6: 0xfd, 0x5b7: 0xfd,\n\t0x5b8: 0xfd, 0x5b9: 0xfd, 0x5ba: 0xfd, 0x5bb: 0xfd, 0x5bc: 0xfd, 0x5bd: 0xfd, 0x5be: 0xfd, 0x5bf: 0xfd,\n\t// Block 0x17, offset 0x5c0\n\t0x5c0: 0x9c, 0x5c1: 0x9c, 0x5c2: 0x9c, 0x5c3: 0x170, 0x5c4: 0x171, 0x5c5: 0x172, 0x5c6: 0x173, 0x5c7: 0x174,\n\t0x5c8: 0x9c, 0x5c9: 0x175, 0x5ca: 0xfd, 0x5cb: 0x176, 0x5cc: 0x9c, 0x5cd: 0x177, 0x5ce: 0xfd, 0x5cf: 0xfd,\n\t0x5d0: 0x5e, 0x5d1: 0x5f, 0x5d2: 0x60, 0x5d3: 0x61, 0x5d4: 0x62, 0x5d5: 0x63, 0x5d6: 0x64, 0x5d7: 0x65,\n\t0x5d8: 0x66, 0x5d9: 0x67, 0x5da: 0x68, 0x5db: 0x69, 0x5dc: 0x6a, 0x5dd: 0x6b, 0x5de: 0x6c, 0x5df: 0x6d,\n\t0x5e0: 0x9c, 0x5e1: 0x9c, 0x5e2: 0x9c, 0x5e3: 0x9c, 0x5e4: 0x9c, 0x5e5: 0x9c, 0x5e6: 0x9c, 0x5e7: 0x9c,\n\t0x5e8: 0x178, 0x5e9: 0x179, 0x5ea: 0x17a, 0x5eb: 0xfd, 0x5ec: 0xfd, 0x5ed: 0xfd, 0x5ee: 0xfd, 0x5ef: 0xfd,\n\t0x5f0: 0xfd, 0x5f1: 0xfd, 0x5f2: 0xfd, 0x5f3: 0xfd, 0x5f4: 0xfd, 0x5f5: 0xfd, 0x5f6: 0xfd, 0x5f7: 0xfd,\n\t0x5f8: 0xfd, 0x5f9: 0xfd, 0x5fa: 0xfd, 0x5fb: 0xfd, 0x5fc: 0xfd, 0x5fd: 0xfd, 0x5fe: 0xfd, 0x5ff: 0xfd,\n\t// Block 0x18, offset 0x600\n\t0x600: 0x17b, 0x601: 0xfd, 0x602: 0xfd, 0x603: 0xfd, 0x604: 0x17c, 0x605: 0x17d, 0x606: 0xfd, 0x607: 0xfd,\n\t0x608: 0xfd, 0x609: 0xfd, 0x60a: 0xfd, 0x60b: 0x17e, 0x60c: 0xfd, 0x60d: 0xfd, 0x60e: 0xfd, 0x60f: 0xfd,\n\t0x610: 0xfd, 0x611: 0xfd, 0x612: 0xfd, 0x613: 0xfd, 0x614: 0xfd, 0x615: 0xfd, 0x616: 0xfd, 0x617: 0xfd,\n\t0x618: 0xfd, 0x619: 0xfd, 0x61a: 0xfd, 0x61b: 0xfd, 0x61c: 0xfd, 0x61d: 0xfd, 0x61e: 0xfd, 0x61f: 0xfd,\n\t0x620: 0x125, 0x621: 0x125, 0x622: 0x125, 0x623: 0x17f, 0x624: 0x6e, 0x625: 0x180, 0x626: 0xfd, 0x627: 0xfd,\n\t0x628: 0xfd, 0x629: 0xfd, 0x62a: 0xfd, 0x62b: 0xfd, 0x62c: 0xfd, 0x62d: 0xfd, 0x62e: 0xfd, 0x62f: 0xfd,\n\t0x630: 0xfd, 0x631: 0x181, 0x632: 0x182, 0x633: 0xfd, 0x634: 0x183, 0x635: 0xfd, 0x636: 0xfd, 0x637: 0xfd,\n\t0x638: 0x6f, 0x639: 0x70, 0x63a: 0x71, 0x63b: 0x184, 0x63c: 0xfd, 0x63d: 0xfd, 0x63e: 0xfd, 0x63f: 0xfd,\n\t// Block 0x19, offset 0x640\n\t0x640: 0x185, 0x641: 0x9c, 0x642: 0x186, 0x643: 0x187, 0x644: 0x72, 0x645: 0x73, 0x646: 0x188, 0x647: 0x189,\n\t0x648: 0x74, 0x649: 0x18a, 0x64a: 0xfd, 0x64b: 0xfd, 0x64c: 0x9c, 0x64d: 0x9c, 0x64e: 0x9c, 0x64f: 0x9c,\n\t0x650: 0x9c, 0x651: 0x9c, 0x652: 0x9c, 0x653: 0x9c, 0x654: 0x9c, 0x655: 0x9c, 0x656: 0x9c, 0x657: 0x9c,\n\t0x658: 0x9c, 0x659: 0x9c, 0x65a: 0x9c, 0x65b: 0x18b, 0x65c: 0x9c, 0x65d: 0x18c, 0x65e: 0x9c, 0x65f: 0x18d,\n\t0x660: 0x18e, 0x661: 0x18f, 0x662: 0x190, 0x663: 0xfd, 0x664: 0x9c, 0x665: 0x191, 0x666: 0x9c, 0x667: 0x192,\n\t0x668: 0x9c, 0x669: 0x193, 0x66a: 0x194, 0x66b: 0x195, 0x66c: 0x9c, 0x66d: 0x9c, 0x66e: 0x196, 0x66f: 0x197,\n\t0x670: 0xfd, 0x671: 0xfd, 0x672: 0xfd, 0x673: 0xfd, 0x674: 0xfd, 0x675: 0xfd, 0x676: 0xfd, 0x677: 0xfd,\n\t0x678: 0xfd, 0x679: 0xfd, 0x67a: 0xfd, 0x67b: 0xfd, 0x67c: 0xfd, 0x67d: 0xfd, 0x67e: 0xfd, 0x67f: 0xfd,\n\t// Block 0x1a, offset 0x680\n\t0x680: 0xa0, 0x681: 0xa0, 0x682: 0xa0, 0x683: 0xa0, 0x684: 0xa0, 0x685: 0xa0, 0x686: 0xa0, 0x687: 0xa0,\n\t0x688: 0xa0, 0x689: 0xa0, 0x68a: 0xa0, 0x68b: 0xa0, 0x68c: 0xa0, 0x68d: 0xa0, 0x68e: 0xa0, 0x68f: 0xa0,\n\t0x690: 0xa0, 0x691: 0xa0, 0x692: 0xa0, 0x693: 0xa0, 0x694: 0xa0, 0x695: 0xa0, 0x696: 0xa0, 0x697: 0xa0,\n\t0x698: 0xa0, 0x699: 0xa0, 0x69a: 0xa0, 0x69b: 0x198, 0x69c: 0xa0, 0x69d: 0xa0, 0x69e: 0xa0, 0x69f: 0xa0,\n\t0x6a0: 0xa0, 0x6a1: 0xa0, 0x6a2: 0xa0, 0x6a3: 0xa0, 0x6a4: 0xa0, 0x6a5: 0xa0, 0x6a6: 0xa0, 0x6a7: 0xa0,\n\t0x6a8: 0xa0, 0x6a9: 0xa0, 0x6aa: 0xa0, 0x6ab: 0xa0, 0x6ac: 0xa0, 0x6ad: 0xa0, 0x6ae: 0xa0, 0x6af: 0xa0,\n\t0x6b0: 0xa0, 0x6b1: 0xa0, 0x6b2: 0xa0, 0x6b3: 0xa0, 0x6b4: 0xa0, 0x6b5: 0xa0, 0x6b6: 0xa0, 0x6b7: 0xa0,\n\t0x6b8: 0xa0, 0x6b9: 0xa0, 0x6ba: 0xa0, 0x6bb: 0xa0, 0x6bc: 0xa0, 0x6bd: 0xa0, 0x6be: 0xa0, 0x6bf: 0xa0,\n\t// Block 0x1b, offset 0x6c0\n\t0x6c0: 0xa0, 0x6c1: 0xa0, 0x6c2: 0xa0, 0x6c3: 0xa0, 0x6c4: 0xa0, 0x6c5: 0xa0, 0x6c6: 0xa0, 0x6c7: 0xa0,\n\t0x6c8: 0xa0, 0x6c9: 0xa0, 0x6ca: 0xa0, 0x6cb: 0xa0, 0x6cc: 0xa0, 0x6cd: 0xa0, 0x6ce: 0xa0, 0x6cf: 0xa0,\n\t0x6d0: 0xa0, 0x6d1: 0xa0, 0x6d2: 0xa0, 0x6d3: 0xa0, 0x6d4: 0xa0, 0x6d5: 0xa0, 0x6d6: 0xa0, 0x6d7: 0xa0,\n\t0x6d8: 0xa0, 0x6d9: 0xa0, 0x6da: 0xa0, 0x6db: 0xa0, 0x6dc: 0x199, 0x6dd: 0xa0, 0x6de: 0xa0, 0x6df: 0xa0,\n\t0x6e0: 0x19a, 0x6e1: 0xa0, 0x6e2: 0xa0, 0x6e3: 0xa0, 0x6e4: 0xa0, 0x6e5: 0xa0, 0x6e6: 0xa0, 0x6e7: 0xa0,\n\t0x6e8: 0xa0, 0x6e9: 0xa0, 0x6ea: 0xa0, 0x6eb: 0xa0, 0x6ec: 0xa0, 0x6ed: 0xa0, 0x6ee: 0xa0, 0x6ef: 0xa0,\n\t0x6f0: 0xa0, 0x6f1: 0xa0, 0x6f2: 0xa0, 0x6f3: 0xa0, 0x6f4: 0xa0, 0x6f5: 0xa0, 0x6f6: 0xa0, 0x6f7: 0xa0,\n\t0x6f8: 0xa0, 0x6f9: 0xa0, 0x6fa: 0xa0, 0x6fb: 0xa0, 0x6fc: 0xa0, 0x6fd: 0xa0, 0x6fe: 0xa0, 0x6ff: 0xa0,\n\t// Block 0x1c, offset 0x700\n\t0x700: 0xa0, 0x701: 0xa0, 0x702: 0xa0, 0x703: 0xa0, 0x704: 0xa0, 0x705: 0xa0, 0x706: 0xa0, 0x707: 0xa0,\n\t0x708: 0xa0, 0x709: 0xa0, 0x70a: 0xa0, 0x70b: 0xa0, 0x70c: 0xa0, 0x70d: 0xa0, 0x70e: 0xa0, 0x70f: 0xa0,\n\t0x710: 0xa0, 0x711: 0xa0, 0x712: 0xa0, 0x713: 0xa0, 0x714: 0xa0, 0x715: 0xa0, 0x716: 0xa0, 0x717: 0xa0,\n\t0x718: 0xa0, 0x719: 0xa0, 0x71a: 0xa0, 0x71b: 0xa0, 0x71c: 0xa0, 0x71d: 0xa0, 0x71e: 0xa0, 0x71f: 0xa0,\n\t0x720: 0xa0, 0x721: 0xa0, 0x722: 0xa0, 0x723: 0xa0, 0x724: 0xa0, 0x725: 0xa0, 0x726: 0xa0, 0x727: 0xa0,\n\t0x728: 0xa0, 0x729: 0xa0, 0x72a: 0xa0, 0x72b: 0xa0, 0x72c: 0xa0, 0x72d: 0xa0, 0x72e: 0xa0, 0x72f: 0xa0,\n\t0x730: 0xa0, 0x731: 0xa0, 0x732: 0xa0, 0x733: 0xa0, 0x734: 0xa0, 0x735: 0xa0, 0x736: 0xa0, 0x737: 0xa0,\n\t0x738: 0xa0, 0x739: 0xa0, 0x73a: 0x19b, 0x73b: 0xa0, 0x73c: 0xa0, 0x73d: 0xa0, 0x73e: 0xa0, 0x73f: 0xa0,\n\t// Block 0x1d, offset 0x740\n\t0x740: 0xa0, 0x741: 0xa0, 0x742: 0xa0, 0x743: 0xa0, 0x744: 0xa0, 0x745: 0xa0, 0x746: 0xa0, 0x747: 0xa0,\n\t0x748: 0xa0, 0x749: 0xa0, 0x74a: 0xa0, 0x74b: 0xa0, 0x74c: 0xa0, 0x74d: 0xa0, 0x74e: 0xa0, 0x74f: 0xa0,\n\t0x750: 0xa0, 0x751: 0xa0, 0x752: 0xa0, 0x753: 0xa0, 0x754: 0xa0, 0x755: 0xa0, 0x756: 0xa0, 0x757: 0xa0,\n\t0x758: 0xa0, 0x759: 0xa0, 0x75a: 0xa0, 0x75b: 0xa0, 0x75c: 0xa0, 0x75d: 0xa0, 0x75e: 0xa0, 0x75f: 0xa0,\n\t0x760: 0xa0, 0x761: 0xa0, 0x762: 0xa0, 0x763: 0xa0, 0x764: 0xa0, 0x765: 0xa0, 0x766: 0xa0, 0x767: 0xa0,\n\t0x768: 0xa0, 0x769: 0xa0, 0x76a: 0xa0, 0x76b: 0xa0, 0x76c: 0xa0, 0x76d: 0xa0, 0x76e: 0xa0, 0x76f: 0x19c,\n\t0x770: 0xfd, 0x771: 0xfd, 0x772: 0xfd, 0x773: 0xfd, 0x774: 0xfd, 0x775: 0xfd, 0x776: 0xfd, 0x777: 0xfd,\n\t0x778: 0xfd, 0x779: 0xfd, 0x77a: 0xfd, 0x77b: 0xfd, 0x77c: 0xfd, 0x77d: 0xfd, 0x77e: 0xfd, 0x77f: 0xfd,\n\t// Block 0x1e, offset 0x780\n\t0x780: 0xfd, 0x781: 0xfd, 0x782: 0xfd, 0x783: 0xfd, 0x784: 0xfd, 0x785: 0xfd, 0x786: 0xfd, 0x787: 0xfd,\n\t0x788: 0xfd, 0x789: 0xfd, 0x78a: 0xfd, 0x78b: 0xfd, 0x78c: 0xfd, 0x78d: 0xfd, 0x78e: 0xfd, 0x78f: 0xfd,\n\t0x790: 0xfd, 0x791: 0xfd, 0x792: 0xfd, 0x793: 0xfd, 0x794: 0xfd, 0x795: 0xfd, 0x796: 0xfd, 0x797: 0xfd,\n\t0x798: 0xfd, 0x799: 0xfd, 0x79a: 0xfd, 0x79b: 0xfd, 0x79c: 0xfd, 0x79d: 0xfd, 0x79e: 0xfd, 0x79f: 0xfd,\n\t0x7a0: 0x75, 0x7a1: 0x76, 0x7a2: 0x77, 0x7a3: 0x78, 0x7a4: 0x79, 0x7a5: 0x7a, 0x7a6: 0x7b, 0x7a7: 0x7c,\n\t0x7a8: 0x7d, 0x7a9: 0xfd, 0x7aa: 0xfd, 0x7ab: 0xfd, 0x7ac: 0xfd, 0x7ad: 0xfd, 0x7ae: 0xfd, 0x7af: 0xfd,\n\t0x7b0: 0xfd, 0x7b1: 0xfd, 0x7b2: 0xfd, 0x7b3: 0xfd, 0x7b4: 0xfd, 0x7b5: 0xfd, 0x7b6: 0xfd, 0x7b7: 0xfd,\n\t0x7b8: 0xfd, 0x7b9: 0xfd, 0x7ba: 0xfd, 0x7bb: 0xfd, 0x7bc: 0xfd, 0x7bd: 0xfd, 0x7be: 0xfd, 0x7bf: 0xfd,\n\t// Block 0x1f, offset 0x7c0\n\t0x7c0: 0xa0, 0x7c1: 0xa0, 0x7c2: 0xa0, 0x7c3: 0xa0, 0x7c4: 0xa0, 0x7c5: 0xa0, 0x7c6: 0xa0, 0x7c7: 0xa0,\n\t0x7c8: 0xa0, 0x7c9: 0xa0, 0x7ca: 0xa0, 0x7cb: 0xa0, 0x7cc: 0xa0, 0x7cd: 0x19d, 0x7ce: 0xfd, 0x7cf: 0xfd,\n\t0x7d0: 0xfd, 0x7d1: 0xfd, 0x7d2: 0xfd, 0x7d3: 0xfd, 0x7d4: 0xfd, 0x7d5: 0xfd, 0x7d6: 0xfd, 0x7d7: 0xfd,\n\t0x7d8: 0xfd, 0x7d9: 0xfd, 0x7da: 0xfd, 0x7db: 0xfd, 0x7dc: 0xfd, 0x7dd: 0xfd, 0x7de: 0xfd, 0x7df: 0xfd,\n\t0x7e0: 0xfd, 0x7e1: 0xfd, 0x7e2: 0xfd, 0x7e3: 0xfd, 0x7e4: 0xfd, 0x7e5: 0xfd, 0x7e6: 0xfd, 0x7e7: 0xfd,\n\t0x7e8: 0xfd, 0x7e9: 0xfd, 0x7ea: 0xfd, 0x7eb: 0xfd, 0x7ec: 0xfd, 0x7ed: 0xfd, 0x7ee: 0xfd, 0x7ef: 0xfd,\n\t0x7f0: 0xfd, 0x7f1: 0xfd, 0x7f2: 0xfd, 0x7f3: 0xfd, 0x7f4: 0xfd, 0x7f5: 0xfd, 0x7f6: 0xfd, 0x7f7: 0xfd,\n\t0x7f8: 0xfd, 0x7f9: 0xfd, 0x7fa: 0xfd, 0x7fb: 0xfd, 0x7fc: 0xfd, 0x7fd: 0xfd, 0x7fe: 0xfd, 0x7ff: 0xfd,\n\t// Block 0x20, offset 0x800\n\t0x810: 0x0d, 0x811: 0x0e, 0x812: 0x0f, 0x813: 0x10, 0x814: 0x11, 0x815: 0x0b, 0x816: 0x12, 0x817: 0x07,\n\t0x818: 0x13, 0x819: 0x0b, 0x81a: 0x0b, 0x81b: 0x14, 0x81c: 0x0b, 0x81d: 0x15, 0x81e: 0x16, 0x81f: 0x17,\n\t0x820: 0x07, 0x821: 0x07, 0x822: 0x07, 0x823: 0x07, 0x824: 0x07, 0x825: 0x07, 0x826: 0x07, 0x827: 0x07,\n\t0x828: 0x07, 0x829: 0x07, 0x82a: 0x18, 0x82b: 0x19, 0x82c: 0x1a, 0x82d: 0x07, 0x82e: 0x1b, 0x82f: 0x1c,\n\t0x830: 0x07, 0x831: 0x1d, 0x832: 0x0b, 0x833: 0x0b, 0x834: 0x0b, 0x835: 0x0b, 0x836: 0x0b, 0x837: 0x0b,\n\t0x838: 0x0b, 0x839: 0x0b, 0x83a: 0x0b, 0x83b: 0x0b, 0x83c: 0x0b, 0x83d: 0x0b, 0x83e: 0x0b, 0x83f: 0x0b,\n\t// Block 0x21, offset 0x840\n\t0x840: 0x0b, 0x841: 0x0b, 0x842: 0x0b, 0x843: 0x0b, 0x844: 0x0b, 0x845: 0x0b, 0x846: 0x0b, 0x847: 0x0b,\n\t0x848: 0x0b, 0x849: 0x0b, 0x84a: 0x0b, 0x84b: 0x0b, 0x84c: 0x0b, 0x84d: 0x0b, 0x84e: 0x0b, 0x84f: 0x0b,\n\t0x850: 0x0b, 0x851: 0x0b, 0x852: 0x0b, 0x853: 0x0b, 0x854: 0x0b, 0x855: 0x0b, 0x856: 0x0b, 0x857: 0x0b,\n\t0x858: 0x0b, 0x859: 0x0b, 0x85a: 0x0b, 0x85b: 0x0b, 0x85c: 0x0b, 0x85d: 0x0b, 0x85e: 0x0b, 0x85f: 0x0b,\n\t0x860: 0x0b, 0x861: 0x0b, 0x862: 0x0b, 0x863: 0x0b, 0x864: 0x0b, 0x865: 0x0b, 0x866: 0x0b, 0x867: 0x0b,\n\t0x868: 0x0b, 0x869: 0x0b, 0x86a: 0x0b, 0x86b: 0x0b, 0x86c: 0x0b, 0x86d: 0x0b, 0x86e: 0x0b, 0x86f: 0x0b,\n\t0x870: 0x0b, 0x871: 0x0b, 0x872: 0x0b, 0x873: 0x0b, 0x874: 0x0b, 0x875: 0x0b, 0x876: 0x0b, 0x877: 0x0b,\n\t0x878: 0x0b, 0x879: 0x0b, 0x87a: 0x0b, 0x87b: 0x0b, 0x87c: 0x0b, 0x87d: 0x0b, 0x87e: 0x0b, 0x87f: 0x0b,\n\t// Block 0x22, offset 0x880\n\t0x880: 0x19e, 0x881: 0x19f, 0x882: 0xfd, 0x883: 0xfd, 0x884: 0x1a0, 0x885: 0x1a0, 0x886: 0x1a0, 0x887: 0x1a1,\n\t0x888: 0xfd, 0x889: 0xfd, 0x88a: 0xfd, 0x88b: 0xfd, 0x88c: 0xfd, 0x88d: 0xfd, 0x88e: 0xfd, 0x88f: 0xfd,\n\t0x890: 0xfd, 0x891: 0xfd, 0x892: 0xfd, 0x893: 0xfd, 0x894: 0xfd, 0x895: 0xfd, 0x896: 0xfd, 0x897: 0xfd,\n\t0x898: 0xfd, 0x899: 0xfd, 0x89a: 0xfd, 0x89b: 0xfd, 0x89c: 0xfd, 0x89d: 0xfd, 0x89e: 0xfd, 0x89f: 0xfd,\n\t0x8a0: 0xfd, 0x8a1: 0xfd, 0x8a2: 0xfd, 0x8a3: 0xfd, 0x8a4: 0xfd, 0x8a5: 0xfd, 0x8a6: 0xfd, 0x8a7: 0xfd,\n\t0x8a8: 0xfd, 0x8a9: 0xfd, 0x8aa: 0xfd, 0x8ab: 0xfd, 0x8ac: 0xfd, 0x8ad: 0xfd, 0x8ae: 0xfd, 0x8af: 0xfd,\n\t0x8b0: 0xfd, 0x8b1: 0xfd, 0x8b2: 0xfd, 0x8b3: 0xfd, 0x8b4: 0xfd, 0x8b5: 0xfd, 0x8b6: 0xfd, 0x8b7: 0xfd,\n\t0x8b8: 0xfd, 0x8b9: 0xfd, 0x8ba: 0xfd, 0x8bb: 0xfd, 0x8bc: 0xfd, 0x8bd: 0xfd, 0x8be: 0xfd, 0x8bf: 0xfd,\n\t// Block 0x23, offset 0x8c0\n\t0x8c0: 0x0b, 0x8c1: 0x0b, 0x8c2: 0x0b, 0x8c3: 0x0b, 0x8c4: 0x0b, 0x8c5: 0x0b, 0x8c6: 0x0b, 0x8c7: 0x0b,\n\t0x8c8: 0x0b, 0x8c9: 0x0b, 0x8ca: 0x0b, 0x8cb: 0x0b, 0x8cc: 0x0b, 0x8cd: 0x0b, 0x8ce: 0x0b, 0x8cf: 0x0b,\n\t0x8d0: 0x0b, 0x8d1: 0x0b, 0x8d2: 0x0b, 0x8d3: 0x0b, 0x8d4: 0x0b, 0x8d5: 0x0b, 0x8d6: 0x0b, 0x8d7: 0x0b,\n\t0x8d8: 0x0b, 0x8d9: 0x0b, 0x8da: 0x0b, 0x8db: 0x0b, 0x8dc: 0x0b, 0x8dd: 0x0b, 0x8de: 0x0b, 0x8df: 0x0b,\n\t0x8e0: 0x20, 0x8e1: 0x0b, 0x8e2: 0x0b, 0x8e3: 0x0b, 0x8e4: 0x0b, 0x8e5: 0x0b, 0x8e6: 0x0b, 0x8e7: 0x0b,\n\t0x8e8: 0x0b, 0x8e9: 0x0b, 0x8ea: 0x0b, 0x8eb: 0x0b, 0x8ec: 0x0b, 0x8ed: 0x0b, 0x8ee: 0x0b, 0x8ef: 0x0b,\n\t0x8f0: 0x0b, 0x8f1: 0x0b, 0x8f2: 0x0b, 0x8f3: 0x0b, 0x8f4: 0x0b, 0x8f5: 0x0b, 0x8f6: 0x0b, 0x8f7: 0x0b,\n\t0x8f8: 0x0b, 0x8f9: 0x0b, 0x8fa: 0x0b, 0x8fb: 0x0b, 0x8fc: 0x0b, 0x8fd: 0x0b, 0x8fe: 0x0b, 0x8ff: 0x0b,\n\t// Block 0x24, offset 0x900\n\t0x900: 0x0b, 0x901: 0x0b, 0x902: 0x0b, 0x903: 0x0b, 0x904: 0x0b, 0x905: 0x0b, 0x906: 0x0b, 0x907: 0x0b,\n\t0x908: 0x0b, 0x909: 0x0b, 0x90a: 0x0b, 0x90b: 0x0b, 0x90c: 0x0b, 0x90d: 0x0b, 0x90e: 0x0b, 0x90f: 0x0b,\n}\n\n// idnaSparseOffset: 292 entries, 584 bytes\nvar idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x33, 0x3e, 0x4a, 0x4e, 0x5d, 0x62, 0x6c, 0x78, 0x85, 0x8b, 0x94, 0xa4, 0xb2, 0xbd, 0xca, 0xdb, 0xe5, 0xec, 0xf9, 0x10a, 0x111, 0x11c, 0x12b, 0x139, 0x143, 0x145, 0x14a, 0x14d, 0x150, 0x152, 0x15e, 0x169, 0x171, 0x177, 0x17d, 0x182, 0x187, 0x18a, 0x18e, 0x194, 0x199, 0x1a5, 0x1af, 0x1b5, 0x1c6, 0x1d0, 0x1d3, 0x1db, 0x1de, 0x1eb, 0x1f3, 0x1f7, 0x1fe, 0x206, 0x216, 0x222, 0x225, 0x22f, 0x23b, 0x247, 0x253, 0x25b, 0x260, 0x26d, 0x27e, 0x282, 0x28d, 0x291, 0x29a, 0x2a2, 0x2a8, 0x2ad, 0x2b0, 0x2b4, 0x2ba, 0x2be, 0x2c2, 0x2c6, 0x2cc, 0x2d4, 0x2db, 0x2e6, 0x2f0, 0x2f4, 0x2f7, 0x2fd, 0x301, 0x303, 0x306, 0x308, 0x30b, 0x315, 0x318, 0x327, 0x32b, 0x32f, 0x331, 0x33a, 0x33d, 0x341, 0x346, 0x34b, 0x351, 0x362, 0x372, 0x378, 0x37c, 0x38b, 0x390, 0x398, 0x3a2, 0x3ad, 0x3b5, 0x3c6, 0x3cf, 0x3df, 0x3ec, 0x3f8, 0x3fd, 0x40a, 0x40e, 0x413, 0x415, 0x417, 0x41b, 0x41d, 0x421, 0x42a, 0x430, 0x434, 0x444, 0x44e, 0x453, 0x456, 0x45c, 0x463, 0x468, 0x46c, 0x472, 0x477, 0x480, 0x485, 0x48b, 0x492, 0x499, 0x4a0, 0x4a4, 0x4a9, 0x4ac, 0x4b1, 0x4bd, 0x4c3, 0x4c8, 0x4cf, 0x4d7, 0x4dc, 0x4e0, 0x4f0, 0x4f7, 0x4fb, 0x4ff, 0x506, 0x508, 0x50b, 0x50e, 0x512, 0x51b, 0x51f, 0x527, 0x52f, 0x537, 0x543, 0x54f, 0x555, 0x55e, 0x56a, 0x571, 0x57a, 0x585, 0x58c, 0x59b, 0x5a8, 0x5b5, 0x5be, 0x5c2, 0x5d1, 0x5d9, 0x5e4, 0x5ed, 0x5f3, 0x5fb, 0x604, 0x60f, 0x612, 0x61e, 0x627, 0x62a, 0x62f, 0x638, 0x63d, 0x64a, 0x655, 0x65e, 0x668, 0x66b, 0x675, 0x67e, 0x68a, 0x697, 0x6a4, 0x6b2, 0x6b9, 0x6bd, 0x6c1, 0x6c4, 0x6c9, 0x6cc, 0x6d1, 0x6d4, 0x6db, 0x6e2, 0x6e6, 0x6f1, 0x6f4, 0x6f7, 0x6fa, 0x700, 0x706, 0x70f, 0x712, 0x715, 0x718, 0x71b, 0x722, 0x725, 0x72a, 0x734, 0x737, 0x73b, 0x74a, 0x756, 0x75a, 0x75f, 0x763, 0x768, 0x76c, 0x771, 0x77a, 0x785, 0x78b, 0x791, 0x797, 0x79d, 0x7a6, 0x7a9, 0x7ac, 0x7b0, 0x7b4, 0x7b8, 0x7be, 0x7c4, 0x7c9, 0x7cc, 0x7dc, 0x7e3, 0x7e6, 0x7eb, 0x7ef, 0x7f5, 0x7fc, 0x800, 0x804, 0x80d, 0x814, 0x819, 0x81d, 0x82b, 0x82e, 0x831, 0x835, 0x839, 0x83c, 0x83f, 0x844, 0x846, 0x848}\n\n// idnaSparseValues: 2123 entries, 8492 bytes\nvar idnaSparseValues = [2123]valueRange{\n\t// Block 0x0, offset 0x0\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0xe105, lo: 0x80, hi: 0x96},\n\t{value: 0x0018, lo: 0x97, hi: 0x97},\n\t{value: 0xe105, lo: 0x98, hi: 0x9e},\n\t{value: 0x001f, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbf},\n\t// Block 0x1, offset 0x8\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0xe01d, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x82},\n\t{value: 0x0335, lo: 0x83, hi: 0x83},\n\t{value: 0x034d, lo: 0x84, hi: 0x84},\n\t{value: 0x0365, lo: 0x85, hi: 0x85},\n\t{value: 0xe00d, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0xe00d, lo: 0x88, hi: 0x88},\n\t{value: 0x0008, lo: 0x89, hi: 0x89},\n\t{value: 0xe00d, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0x8b},\n\t{value: 0xe00d, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0x8d},\n\t{value: 0xe00d, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0xbf},\n\t// Block 0x2, offset 0x19\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x00a9, lo: 0xb0, hi: 0xb0},\n\t{value: 0x037d, lo: 0xb1, hi: 0xb1},\n\t{value: 0x00b1, lo: 0xb2, hi: 0xb2},\n\t{value: 0x00b9, lo: 0xb3, hi: 0xb3},\n\t{value: 0x034d, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0395, lo: 0xb5, hi: 0xb5},\n\t{value: 0xe1bd, lo: 0xb6, hi: 0xb6},\n\t{value: 0x00c1, lo: 0xb7, hi: 0xb7},\n\t{value: 0x00c9, lo: 0xb8, hi: 0xb8},\n\t{value: 0x0008, lo: 0xb9, hi: 0xbf},\n\t// Block 0x3, offset 0x25\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x3308, lo: 0x80, hi: 0xbf},\n\t// Block 0x4, offset 0x27\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x03f5, lo: 0x80, hi: 0x8f},\n\t{value: 0xe105, lo: 0x90, hi: 0x9f},\n\t{value: 0x049d, lo: 0xa0, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x5, offset 0x2c\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe185, lo: 0x80, hi: 0x8f},\n\t{value: 0x0545, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x98},\n\t{value: 0x0008, lo: 0x99, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x6, offset 0x33\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0131, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x88},\n\t{value: 0x0018, lo: 0x89, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x3308, lo: 0x91, hi: 0xbd},\n\t{value: 0x0818, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x7, offset 0x3e\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0818, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x82},\n\t{value: 0x0818, lo: 0x83, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x85},\n\t{value: 0x0818, lo: 0x86, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xae},\n\t{value: 0x0808, lo: 0xaf, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x8, offset 0x4a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0a08, lo: 0x80, hi: 0x87},\n\t{value: 0x0c08, lo: 0x88, hi: 0x99},\n\t{value: 0x0a08, lo: 0x9a, hi: 0xbf},\n\t// Block 0x9, offset 0x4e\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3308, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0c08, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0a08, lo: 0x8e, hi: 0x98},\n\t{value: 0x0c08, lo: 0x99, hi: 0x9b},\n\t{value: 0x0a08, lo: 0x9c, hi: 0xaa},\n\t{value: 0x0c08, lo: 0xab, hi: 0xac},\n\t{value: 0x0a08, lo: 0xad, hi: 0xb0},\n\t{value: 0x0c08, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0a08, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0c08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0a08, lo: 0xb5, hi: 0xb7},\n\t{value: 0x0c08, lo: 0xb8, hi: 0xb9},\n\t{value: 0x0a08, lo: 0xba, hi: 0xbf},\n\t// Block 0xa, offset 0x5d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xb0},\n\t{value: 0x0808, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xb, offset 0x62\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0808, lo: 0x80, hi: 0x89},\n\t{value: 0x0a08, lo: 0x8a, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xb3},\n\t{value: 0x0808, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xb9},\n\t{value: 0x0818, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0818, lo: 0xbe, hi: 0xbf},\n\t// Block 0xc, offset 0x6c\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x99},\n\t{value: 0x0808, lo: 0x9a, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0xa3},\n\t{value: 0x0808, lo: 0xa4, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa7},\n\t{value: 0x0808, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0818, lo: 0xb0, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd, offset 0x78\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0a08, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0c08, lo: 0xaa, hi: 0xac},\n\t{value: 0x0808, lo: 0xad, hi: 0xad},\n\t{value: 0x0c08, lo: 0xae, hi: 0xae},\n\t{value: 0x0a08, lo: 0xaf, hi: 0xb0},\n\t{value: 0x0c08, lo: 0xb1, hi: 0xb2},\n\t{value: 0x0a08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0a08, lo: 0xb6, hi: 0xb8},\n\t{value: 0x0c08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0a08, lo: 0xba, hi: 0xbf},\n\t// Block 0xe, offset 0x85\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0a08, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x92},\n\t{value: 0x3308, lo: 0x93, hi: 0xa1},\n\t{value: 0x0840, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xbf},\n\t// Block 0xf, offset 0x8b\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x10, offset 0x94\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x85},\n\t{value: 0x3008, lo: 0x86, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x3008, lo: 0x8a, hi: 0x8c},\n\t{value: 0x3b08, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x11, offset 0xa4\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbf},\n\t// Block 0x12, offset 0xb2\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0xba},\n\t{value: 0x3b08, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x13, offset 0xbd\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0008, lo: 0xb3, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x14, offset 0xca\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x89},\n\t{value: 0x3b08, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8e},\n\t{value: 0x3008, lo: 0x8f, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x3008, lo: 0x98, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x15, offset 0xdb\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb2},\n\t{value: 0x01f1, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb9},\n\t{value: 0x3b08, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0x16, offset 0xe5\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x8e},\n\t{value: 0x0018, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0xbf},\n\t// Block 0x17, offset 0xec\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x3308, lo: 0x88, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0201, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0209, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0008, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x18, offset 0xf9\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0x8b},\n\t{value: 0xe03d, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3308, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x19, offset 0x10a\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0018, lo: 0x8e, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0xbf},\n\t// Block 0x1a, offset 0x111\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x3008, lo: 0xab, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xb0},\n\t{value: 0x3008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0x1b, offset 0x11c\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x95},\n\t{value: 0x3008, lo: 0x96, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0x9d},\n\t{value: 0x3308, lo: 0x9e, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3008, lo: 0xa2, hi: 0xa4},\n\t{value: 0x0008, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xbf},\n\t// Block 0x1c, offset 0x12b\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x3008, lo: 0x87, hi: 0x8c},\n\t{value: 0x3308, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x8e},\n\t{value: 0x3008, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x3008, lo: 0x9a, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x1d, offset 0x139\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x86},\n\t{value: 0x055d, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8c},\n\t{value: 0x055d, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbb},\n\t{value: 0xe105, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x1e, offset 0x143\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0018, lo: 0x80, hi: 0xbf},\n\t// Block 0x1f, offset 0x145\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xa0},\n\t{value: 0x2018, lo: 0xa1, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0x20, offset 0x14a\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xa7},\n\t{value: 0x2018, lo: 0xa8, hi: 0xbf},\n\t// Block 0x21, offset 0x14d\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x2018, lo: 0x80, hi: 0x82},\n\t{value: 0x0018, lo: 0x83, hi: 0xbf},\n\t// Block 0x22, offset 0x150\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0008, lo: 0x80, hi: 0xbf},\n\t// Block 0x23, offset 0x152\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x24, offset 0x15e\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x25, offset 0x169\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbf},\n\t// Block 0x26, offset 0x171\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbf},\n\t// Block 0x27, offset 0x177\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x28, offset 0x17d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x29, offset 0x182\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0xe045, lo: 0xb8, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x2a, offset 0x187\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xbf},\n\t// Block 0x2b, offset 0x18a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xac},\n\t{value: 0x0018, lo: 0xad, hi: 0xae},\n\t{value: 0x0008, lo: 0xaf, hi: 0xbf},\n\t// Block 0x2c, offset 0x18e\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x2d, offset 0x194\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xb0},\n\t{value: 0x0008, lo: 0xb1, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0x2e, offset 0x199\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x93},\n\t{value: 0x3b08, lo: 0x94, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3b08, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0018, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x2f, offset 0x1a5\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x30, offset 0x1af\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xb3},\n\t{value: 0x3340, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3008, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x31, offset 0x1b5\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x3008, lo: 0x80, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x3008, lo: 0x87, hi: 0x88},\n\t{value: 0x3308, lo: 0x89, hi: 0x91},\n\t{value: 0x3b08, lo: 0x92, hi: 0x92},\n\t{value: 0x3308, lo: 0x93, hi: 0x93},\n\t{value: 0x0018, lo: 0x94, hi: 0x96},\n\t{value: 0x0008, lo: 0x97, hi: 0x97},\n\t{value: 0x0018, lo: 0x98, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x32, offset 0x1c6\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0018, lo: 0x80, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x86},\n\t{value: 0x0218, lo: 0x87, hi: 0x87},\n\t{value: 0x0018, lo: 0x88, hi: 0x8a},\n\t{value: 0x33c0, lo: 0x8b, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0208, lo: 0xa0, hi: 0xbf},\n\t// Block 0x33, offset 0x1d0\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0208, lo: 0x80, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0x34, offset 0x1d3\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x0208, lo: 0x87, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0208, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x35, offset 0x1db\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0x36, offset 0x1de\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb8},\n\t{value: 0x3308, lo: 0xb9, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x37, offset 0x1eb\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x38, offset 0x1f3\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x39, offset 0x1f7\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0028, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0xbf},\n\t// Block 0x3a, offset 0x1fe\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x3308, lo: 0x97, hi: 0x98},\n\t{value: 0x3008, lo: 0x99, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x3b, offset 0x206\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x94},\n\t{value: 0x3008, lo: 0x95, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3b08, lo: 0xa0, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xac},\n\t{value: 0x3008, lo: 0xad, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x3c, offset 0x216\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0018, lo: 0xa8, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xbd},\n\t{value: 0x3318, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x3d, offset 0x222\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0xbf},\n\t// Block 0x3e, offset 0x225\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x3308, lo: 0x80, hi: 0x83},\n\t{value: 0x3008, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x3f, offset 0x22f\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x3808, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x40, offset 0x23b\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa9},\n\t{value: 0x3808, lo: 0xaa, hi: 0xaa},\n\t{value: 0x3b08, lo: 0xab, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xbf},\n\t// Block 0x41, offset 0x247\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa9},\n\t{value: 0x3008, lo: 0xaa, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3808, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbf},\n\t// Block 0x42, offset 0x253\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x3008, lo: 0xa4, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbf},\n\t// Block 0x43, offset 0x25b\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0x44, offset 0x260\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x02a9, lo: 0x80, hi: 0x80},\n\t{value: 0x02b1, lo: 0x81, hi: 0x81},\n\t{value: 0x02b9, lo: 0x82, hi: 0x82},\n\t{value: 0x02c1, lo: 0x83, hi: 0x83},\n\t{value: 0x02c9, lo: 0x84, hi: 0x85},\n\t{value: 0x02d1, lo: 0x86, hi: 0x86},\n\t{value: 0x02d9, lo: 0x87, hi: 0x87},\n\t{value: 0x057d, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x059d, lo: 0x90, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbc},\n\t{value: 0x059d, lo: 0xbd, hi: 0xbf},\n\t// Block 0x45, offset 0x26d\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x92},\n\t{value: 0x0018, lo: 0x93, hi: 0x93},\n\t{value: 0x3308, lo: 0x94, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa8},\n\t{value: 0x0008, lo: 0xa9, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x3008, lo: 0xb7, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x46, offset 0x27e\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3308, lo: 0x80, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbf},\n\t// Block 0x47, offset 0x282\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x87},\n\t{value: 0xe045, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0xe045, lo: 0x98, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0xe045, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb7},\n\t{value: 0xe045, lo: 0xb8, hi: 0xbf},\n\t// Block 0x48, offset 0x28d\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x3318, lo: 0x90, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbf},\n\t// Block 0x49, offset 0x291\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x88},\n\t{value: 0x0851, lo: 0x89, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x4a, offset 0x29a\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0xab},\n\t{value: 0x0859, lo: 0xac, hi: 0xac},\n\t{value: 0x0861, lo: 0xad, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xae},\n\t{value: 0x0869, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0871, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0018, lo: 0xb1, hi: 0xbf},\n\t// Block 0x4b, offset 0x2a2\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x9f},\n\t{value: 0x0080, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xad},\n\t{value: 0x0080, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x4c, offset 0x2a8\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xa8},\n\t{value: 0x09dd, lo: 0xa9, hi: 0xa9},\n\t{value: 0x09fd, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xbf},\n\t// Block 0x4d, offset 0x2ad\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xbf},\n\t// Block 0x4e, offset 0x2b0\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x0929, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0xbf},\n\t// Block 0x4f, offset 0x2b4\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0e7e, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0932, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0e9e, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0x50, offset 0x2ba\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x9b},\n\t{value: 0x0939, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0xbf},\n\t// Block 0x51, offset 0x2be\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0x52, offset 0x2c2\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x96},\n\t{value: 0x0018, lo: 0x97, hi: 0xbf},\n\t// Block 0x53, offset 0x2c6\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0xe185, lo: 0x80, hi: 0x8f},\n\t{value: 0x03f5, lo: 0x90, hi: 0x9f},\n\t{value: 0x0ebd, lo: 0xa0, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x54, offset 0x2cc\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xac},\n\t{value: 0x0008, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x55, offset 0x2d4\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xae},\n\t{value: 0xe075, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0x56, offset 0x2db\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x57, offset 0x2e6\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xbf},\n\t// Block 0x58, offset 0x2f0\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xae},\n\t{value: 0x0008, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x59, offset 0x2f4\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x92},\n\t{value: 0x0040, lo: 0x93, hi: 0xbf},\n\t// Block 0x5a, offset 0x2f7\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9e},\n\t{value: 0x0ef5, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbf},\n\t// Block 0x5b, offset 0x2fd\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb2},\n\t{value: 0x0f15, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x5c, offset 0x301\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x0f35, lo: 0x80, hi: 0xbf},\n\t// Block 0x5d, offset 0x303\n\t{value: 0x0020, lo: 0x02},\n\t{value: 0x1735, lo: 0x80, hi: 0x8f},\n\t{value: 0x1915, lo: 0x90, hi: 0xbf},\n\t// Block 0x5e, offset 0x306\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x1f15, lo: 0x80, hi: 0xbf},\n\t// Block 0x5f, offset 0x308\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xbf},\n\t// Block 0x60, offset 0x30b\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x98},\n\t{value: 0x3308, lo: 0x99, hi: 0x9a},\n\t{value: 0x096a, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0972, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0008, lo: 0x9d, hi: 0x9e},\n\t{value: 0x0979, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xbf},\n\t// Block 0x61, offset 0x315\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xbe},\n\t{value: 0x0981, lo: 0xbf, hi: 0xbf},\n\t// Block 0x62, offset 0x318\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0040, lo: 0x80, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xb0},\n\t{value: 0x2a35, lo: 0xb1, hi: 0xb1},\n\t{value: 0x2a55, lo: 0xb2, hi: 0xb2},\n\t{value: 0x2a75, lo: 0xb3, hi: 0xb3},\n\t{value: 0x2a95, lo: 0xb4, hi: 0xb4},\n\t{value: 0x2a75, lo: 0xb5, hi: 0xb5},\n\t{value: 0x2ab5, lo: 0xb6, hi: 0xb6},\n\t{value: 0x2ad5, lo: 0xb7, hi: 0xb7},\n\t{value: 0x2af5, lo: 0xb8, hi: 0xb9},\n\t{value: 0x2b15, lo: 0xba, hi: 0xbb},\n\t{value: 0x2b35, lo: 0xbc, hi: 0xbd},\n\t{value: 0x2b15, lo: 0xbe, hi: 0xbf},\n\t// Block 0x63, offset 0x327\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x64, offset 0x32b\n\t{value: 0x0008, lo: 0x03},\n\t{value: 0x098a, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0a82, lo: 0xa0, hi: 0xbf},\n\t// Block 0x65, offset 0x32f\n\t{value: 0x0008, lo: 0x01},\n\t{value: 0x0d19, lo: 0x80, hi: 0xbf},\n\t// Block 0x66, offset 0x331\n\t{value: 0x0008, lo: 0x08},\n\t{value: 0x0f19, lo: 0x80, hi: 0xb0},\n\t{value: 0x4045, lo: 0xb1, hi: 0xb1},\n\t{value: 0x10a1, lo: 0xb2, hi: 0xb3},\n\t{value: 0x4065, lo: 0xb4, hi: 0xb4},\n\t{value: 0x10b1, lo: 0xb5, hi: 0xb7},\n\t{value: 0x4085, lo: 0xb8, hi: 0xb8},\n\t{value: 0x4085, lo: 0xb9, hi: 0xb9},\n\t{value: 0x10c9, lo: 0xba, hi: 0xbf},\n\t// Block 0x67, offset 0x33a\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x68, offset 0x33d\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x69, offset 0x341\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0x6a, offset 0x346\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xbf},\n\t// Block 0x6b, offset 0x34b\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x0018, lo: 0xa6, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0018, lo: 0xb2, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x6c, offset 0x351\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0040, lo: 0x80, hi: 0x81},\n\t{value: 0xe00d, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0x83},\n\t{value: 0x03f5, lo: 0x84, hi: 0x84},\n\t{value: 0x0479, lo: 0x85, hi: 0x85},\n\t{value: 0x447d, lo: 0x86, hi: 0x86},\n\t{value: 0xe07d, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x88},\n\t{value: 0xe01d, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0xb4},\n\t{value: 0xe01d, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0008, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0741, lo: 0xb8, hi: 0xb8},\n\t{value: 0x13f1, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xbf},\n\t// Block 0x6d, offset 0x362\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0x85},\n\t{value: 0x3b08, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x8a},\n\t{value: 0x3308, lo: 0x8b, hi: 0x8b},\n\t{value: 0x0008, lo: 0x8c, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0018, lo: 0xa8, hi: 0xab},\n\t{value: 0x3b08, lo: 0xac, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x6e, offset 0x372\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0208, lo: 0x80, hi: 0xb1},\n\t{value: 0x0108, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0008, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x6f, offset 0x378\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xbf},\n\t// Block 0x70, offset 0x37c\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3008, lo: 0x80, hi: 0x83},\n\t{value: 0x3b08, lo: 0x84, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8d},\n\t{value: 0x0018, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xba},\n\t{value: 0x0008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x71, offset 0x38b\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x72, offset 0x390\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x91},\n\t{value: 0x3008, lo: 0x92, hi: 0x92},\n\t{value: 0x3808, lo: 0x93, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x73, offset 0x398\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb9},\n\t{value: 0x3008, lo: 0xba, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x74, offset 0x3a2\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3808, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x75, offset 0x3ad\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x76, offset 0x3b5\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x8b},\n\t{value: 0x3308, lo: 0x8c, hi: 0x8c},\n\t{value: 0x3008, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0018, lo: 0x9c, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x77, offset 0x3c6\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0008, lo: 0xb9, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbf},\n\t// Block 0x78, offset 0x3cf\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x9a},\n\t{value: 0x0008, lo: 0x9b, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xaa},\n\t{value: 0x3008, lo: 0xab, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3b08, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x79, offset 0x3df\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x88},\n\t{value: 0x0008, lo: 0x89, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x90},\n\t{value: 0x0008, lo: 0x91, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7a, offset 0x3ec\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x449d, lo: 0x9c, hi: 0x9c},\n\t{value: 0x44b5, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0941, lo: 0x9e, hi: 0x9e},\n\t{value: 0xe06d, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa8},\n\t{value: 0x13f9, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x44cd, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7b, offset 0x3f8\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x44ed, lo: 0x80, hi: 0x8f},\n\t{value: 0x450d, lo: 0x90, hi: 0x9f},\n\t{value: 0x452d, lo: 0xa0, hi: 0xaf},\n\t{value: 0x450d, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7c, offset 0x3fd\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3b08, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x7d, offset 0x40a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7e, offset 0x40e\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8a},\n\t{value: 0x0018, lo: 0x8b, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x7f, offset 0x413\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0040, lo: 0x80, hi: 0xbf},\n\t// Block 0x80, offset 0x415\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x454d, lo: 0x80, hi: 0xbf},\n\t// Block 0x81, offset 0x417\n\t{value: 0x0020, lo: 0x03},\n\t{value: 0x4d4d, lo: 0x80, hi: 0x94},\n\t{value: 0x4b0d, lo: 0x95, hi: 0x95},\n\t{value: 0x4fed, lo: 0x96, hi: 0xbf},\n\t// Block 0x82, offset 0x41b\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x552d, lo: 0x80, hi: 0xbf},\n\t// Block 0x83, offset 0x41d\n\t{value: 0x0020, lo: 0x03},\n\t{value: 0x5d2d, lo: 0x80, hi: 0x84},\n\t{value: 0x568d, lo: 0x85, hi: 0x85},\n\t{value: 0x5dcd, lo: 0x86, hi: 0xbf},\n\t// Block 0x84, offset 0x421\n\t{value: 0x0020, lo: 0x08},\n\t{value: 0x6b8d, lo: 0x80, hi: 0x8f},\n\t{value: 0x6d4d, lo: 0x90, hi: 0x90},\n\t{value: 0x6d8d, lo: 0x91, hi: 0xab},\n\t{value: 0x1401, lo: 0xac, hi: 0xac},\n\t{value: 0x70ed, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x710d, lo: 0xb0, hi: 0xbf},\n\t// Block 0x85, offset 0x42a\n\t{value: 0x0020, lo: 0x05},\n\t{value: 0x730d, lo: 0x80, hi: 0xad},\n\t{value: 0x656d, lo: 0xae, hi: 0xae},\n\t{value: 0x78cd, lo: 0xaf, hi: 0xb5},\n\t{value: 0x6f8d, lo: 0xb6, hi: 0xb6},\n\t{value: 0x79ad, lo: 0xb7, hi: 0xbf},\n\t// Block 0x86, offset 0x430\n\t{value: 0x0008, lo: 0x03},\n\t{value: 0x1751, lo: 0x80, hi: 0x82},\n\t{value: 0x1741, lo: 0x83, hi: 0x83},\n\t{value: 0x1769, lo: 0x84, hi: 0xbf},\n\t// Block 0x87, offset 0x434\n\t{value: 0x0008, lo: 0x0f},\n\t{value: 0x1d81, lo: 0x80, hi: 0x83},\n\t{value: 0x1d99, lo: 0x84, hi: 0x85},\n\t{value: 0x1da1, lo: 0x86, hi: 0x87},\n\t{value: 0x1da9, lo: 0x88, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x1de9, lo: 0x92, hi: 0x97},\n\t{value: 0x1e11, lo: 0x98, hi: 0x9c},\n\t{value: 0x1e31, lo: 0x9d, hi: 0xb3},\n\t{value: 0x1d71, lo: 0xb4, hi: 0xb4},\n\t{value: 0x1d81, lo: 0xb5, hi: 0xb5},\n\t{value: 0x1ee9, lo: 0xb6, hi: 0xbb},\n\t{value: 0x1f09, lo: 0xbc, hi: 0xbc},\n\t{value: 0x1ef9, lo: 0xbd, hi: 0xbd},\n\t{value: 0x1f19, lo: 0xbe, hi: 0xbf},\n\t// Block 0x88, offset 0x444\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0008, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0x89, offset 0x44e\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0x8a, offset 0x453\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x8b, offset 0x456\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0x8c, offset 0x45c\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0040, lo: 0xa1, hi: 0xbf},\n\t// Block 0x8d, offset 0x463\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x8e, offset 0x468\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x8f, offset 0x46c\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x90, offset 0x472\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xac},\n\t{value: 0x0008, lo: 0xad, hi: 0xbf},\n\t// Block 0x91, offset 0x477\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x92, offset 0x480\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x93, offset 0x485\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0xbf},\n\t// Block 0x94, offset 0x48b\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe145, lo: 0x80, hi: 0x87},\n\t{value: 0xe1c5, lo: 0x88, hi: 0x8f},\n\t{value: 0xe145, lo: 0x90, hi: 0x97},\n\t{value: 0x8b0d, lo: 0x98, hi: 0x9f},\n\t{value: 0x8b25, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xbf},\n\t// Block 0x95, offset 0x492\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x8b25, lo: 0xb0, hi: 0xb7},\n\t{value: 0x8b0d, lo: 0xb8, hi: 0xbf},\n\t// Block 0x96, offset 0x499\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe145, lo: 0x80, hi: 0x87},\n\t{value: 0xe1c5, lo: 0x88, hi: 0x8f},\n\t{value: 0xe145, lo: 0x90, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x97, offset 0x4a0\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x98, offset 0x4a4\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xae},\n\t{value: 0x0018, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x99, offset 0x4a9\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x9a, offset 0x4ac\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xbf},\n\t// Block 0x9b, offset 0x4b1\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x87},\n\t{value: 0x0808, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0808, lo: 0x8a, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0808, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbb},\n\t{value: 0x0808, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbe},\n\t{value: 0x0808, lo: 0xbf, hi: 0xbf},\n\t// Block 0x9c, offset 0x4bd\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x96},\n\t{value: 0x0818, lo: 0x97, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0818, lo: 0xb7, hi: 0xbf},\n\t// Block 0x9d, offset 0x4c3\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xa6},\n\t{value: 0x0818, lo: 0xa7, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x9e, offset 0x4c8\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0808, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xba},\n\t{value: 0x0818, lo: 0xbb, hi: 0xbf},\n\t// Block 0x9f, offset 0x4cf\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0818, lo: 0x96, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbe},\n\t{value: 0x0818, lo: 0xbf, hi: 0xbf},\n\t// Block 0xa0, offset 0x4d7\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbb},\n\t{value: 0x0818, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0808, lo: 0xbe, hi: 0xbf},\n\t// Block 0xa1, offset 0x4dc\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0818, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x91},\n\t{value: 0x0818, lo: 0x92, hi: 0xbf},\n\t// Block 0xa2, offset 0x4e0\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0808, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8b},\n\t{value: 0x3308, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x94},\n\t{value: 0x0808, lo: 0x95, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0x98},\n\t{value: 0x0808, lo: 0x99, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xa3, offset 0x4f0\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0818, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x0818, lo: 0x90, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xbc},\n\t{value: 0x0818, lo: 0xbd, hi: 0xbf},\n\t// Block 0xa4, offset 0x4f7\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0x9c},\n\t{value: 0x0818, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xa5, offset 0x4fb\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb8},\n\t{value: 0x0018, lo: 0xb9, hi: 0xbf},\n\t// Block 0xa6, offset 0x4ff\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0818, lo: 0x98, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb7},\n\t{value: 0x0818, lo: 0xb8, hi: 0xbf},\n\t// Block 0xa7, offset 0x506\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0808, lo: 0x80, hi: 0xbf},\n\t// Block 0xa8, offset 0x508\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0808, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0xbf},\n\t// Block 0xa9, offset 0x50b\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x03dd, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbf},\n\t// Block 0xaa, offset 0x50e\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb9},\n\t{value: 0x0818, lo: 0xba, hi: 0xbf},\n\t// Block 0xab, offset 0x512\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0908, lo: 0x80, hi: 0x80},\n\t{value: 0x0a08, lo: 0x81, hi: 0xa1},\n\t{value: 0x0c08, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0a08, lo: 0xa3, hi: 0xa3},\n\t{value: 0x3308, lo: 0xa4, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0808, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xac, offset 0x51b\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0818, lo: 0xa0, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xad, offset 0x51f\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xac},\n\t{value: 0x0818, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0808, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xae, offset 0x527\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0x9c},\n\t{value: 0x0818, lo: 0x9d, hi: 0xa6},\n\t{value: 0x0808, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0a08, lo: 0xb0, hi: 0xb2},\n\t{value: 0x0c08, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0a08, lo: 0xb4, hi: 0xbf},\n\t// Block 0xaf, offset 0x52f\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0a08, lo: 0x80, hi: 0x84},\n\t{value: 0x0808, lo: 0x85, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x90},\n\t{value: 0x0a18, lo: 0x91, hi: 0x93},\n\t{value: 0x0c18, lo: 0x94, hi: 0x94},\n\t{value: 0x0818, lo: 0x95, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xb0, offset 0x537\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0040, lo: 0x80, hi: 0xaf},\n\t{value: 0x0a08, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0808, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0a08, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0c08, lo: 0xb4, hi: 0xb6},\n\t{value: 0x0808, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0a08, lo: 0xb8, hi: 0xb8},\n\t{value: 0x0c08, lo: 0xb9, hi: 0xba},\n\t{value: 0x0a08, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0c08, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0a08, lo: 0xbe, hi: 0xbf},\n\t// Block 0xb1, offset 0x543\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x80},\n\t{value: 0x0a08, lo: 0x81, hi: 0x81},\n\t{value: 0x0c08, lo: 0x82, hi: 0x83},\n\t{value: 0x0a08, lo: 0x84, hi: 0x84},\n\t{value: 0x0818, lo: 0x85, hi: 0x88},\n\t{value: 0x0c18, lo: 0x89, hi: 0x89},\n\t{value: 0x0a18, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0918, lo: 0x8b, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xb2, offset 0x54f\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbf},\n\t// Block 0xb3, offset 0x555\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x85},\n\t{value: 0x3b08, lo: 0x86, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x91},\n\t{value: 0x0018, lo: 0x92, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb4, offset 0x55e\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb6},\n\t{value: 0x3008, lo: 0xb7, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0xb5, offset 0x56a\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x81},\n\t{value: 0x0040, lo: 0x82, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xb6, offset 0x571\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xb2},\n\t{value: 0x3b08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0008, lo: 0xb6, hi: 0xbf},\n\t// Block 0xb7, offset 0x57a\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0018, lo: 0x80, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x3008, lo: 0x85, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0008, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xb8, offset 0x585\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xbe},\n\t{value: 0x3008, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb9, offset 0x58c\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3808, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x88},\n\t{value: 0x3308, lo: 0x89, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8d},\n\t{value: 0x3008, lo: 0x8e, hi: 0x8e},\n\t{value: 0x3308, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xba, offset 0x59b\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x92},\n\t{value: 0x0008, lo: 0x93, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3808, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbb, offset 0x5a8\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0008, lo: 0x9f, hi: 0xa8},\n\t{value: 0x0018, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0xbc, offset 0x5b5\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x3308, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3008, lo: 0xa0, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xa9},\n\t{value: 0x3b08, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xbd, offset 0x5be\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbf},\n\t// Block 0xbe, offset 0x5c2\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x3b08, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x84},\n\t{value: 0x3008, lo: 0x85, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x8a},\n\t{value: 0x0018, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0x9d},\n\t{value: 0x3308, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0008, lo: 0x9f, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xbf},\n\t// Block 0xbf, offset 0x5d1\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb8},\n\t{value: 0x3008, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc0, offset 0x5d9\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x81},\n\t{value: 0x3b08, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x85},\n\t{value: 0x0018, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xc1, offset 0x5e4\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc2, offset 0x5ed\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x9b},\n\t{value: 0x3308, lo: 0x9c, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0xc3, offset 0x5f3\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc4, offset 0x5fb\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xbf},\n\t// Block 0xc5, offset 0x604\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb5},\n\t{value: 0x3808, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xc6, offset 0x60f\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0xbf},\n\t// Block 0xc7, offset 0x612\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9f},\n\t{value: 0x3008, lo: 0xa0, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xaa},\n\t{value: 0x3b08, lo: 0xab, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbf},\n\t// Block 0xc8, offset 0x61e\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0xc9, offset 0x627\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x049d, lo: 0xa0, hi: 0xbf},\n\t// Block 0xca, offset 0x62a\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0xcb, offset 0x62f\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3008, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xcc, offset 0x638\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xbf},\n\t// Block 0xcd, offset 0x63d\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x3008, lo: 0x91, hi: 0x93},\n\t{value: 0x3308, lo: 0x94, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0x99},\n\t{value: 0x3308, lo: 0x9a, hi: 0x9b},\n\t{value: 0x3008, lo: 0x9c, hi: 0x9f},\n\t{value: 0x3b08, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x0018, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0008, lo: 0xa3, hi: 0xa3},\n\t{value: 0x3008, lo: 0xa4, hi: 0xa4},\n\t{value: 0x0040, lo: 0xa5, hi: 0xbf},\n\t// Block 0xce, offset 0x64a\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3b08, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb8},\n\t{value: 0x3008, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0xcf, offset 0x655\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x3b08, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x3308, lo: 0x91, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x98},\n\t{value: 0x3308, lo: 0x99, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0xbf},\n\t// Block 0xd0, offset 0x65e\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x3308, lo: 0x8a, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x98},\n\t{value: 0x3b08, lo: 0x99, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9c},\n\t{value: 0x0008, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0xa2},\n\t{value: 0x0040, lo: 0xa3, hi: 0xbf},\n\t// Block 0xd1, offset 0x668\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xd2, offset 0x66b\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd3, offset 0x675\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xbf},\n\t// Block 0xd4, offset 0x67e\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xa9},\n\t{value: 0x3308, lo: 0xaa, hi: 0xb0},\n\t{value: 0x3008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xd5, offset 0x68a\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd6, offset 0x697\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x3308, lo: 0x80, hi: 0x83},\n\t{value: 0x3b08, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xbf},\n\t// Block 0xd7, offset 0x6a4\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x3008, lo: 0x8a, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x92},\n\t{value: 0x3008, lo: 0x93, hi: 0x94},\n\t{value: 0x3308, lo: 0x95, hi: 0x95},\n\t{value: 0x3008, lo: 0x96, hi: 0x96},\n\t{value: 0x3b08, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xbf},\n\t// Block 0xd8, offset 0x6b2\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xd9, offset 0x6b9\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbf},\n\t// Block 0xda, offset 0x6bd\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0xdb, offset 0x6c1\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xdc, offset 0x6c4\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xdd, offset 0x6c9\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0xbf},\n\t// Block 0xde, offset 0x6cc\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0340, lo: 0xb0, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xdf, offset 0x6d1\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0xbf},\n\t// Block 0xe0, offset 0x6d4\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0xe1, offset 0x6db\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0018, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xe2, offset 0x6e2\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0xe3, offset 0x6e6\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0008, lo: 0xa3, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbf},\n\t// Block 0xe4, offset 0x6f1\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0xbf},\n\t// Block 0xe5, offset 0x6f4\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0xe105, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0xe6, offset 0x6f7\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0xbf},\n\t// Block 0xe7, offset 0x6fa\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8e},\n\t{value: 0x3308, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x3008, lo: 0x91, hi: 0xbf},\n\t// Block 0xe8, offset 0x700\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3008, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8e},\n\t{value: 0x3308, lo: 0x8f, hi: 0x92},\n\t{value: 0x0008, lo: 0x93, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xe9, offset 0x706\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa1},\n\t{value: 0x0018, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0008, lo: 0xa3, hi: 0xa3},\n\t{value: 0x3308, lo: 0xa4, hi: 0xa4},\n\t{value: 0x0040, lo: 0xa5, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xea, offset 0x70f\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0xeb, offset 0x712\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0xbf},\n\t// Block 0xec, offset 0x715\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0xbf},\n\t// Block 0xed, offset 0x718\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xbf},\n\t// Block 0xee, offset 0x71b\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x92},\n\t{value: 0x0040, lo: 0x93, hi: 0xa3},\n\t{value: 0x0008, lo: 0xa4, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0xef, offset 0x722\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0xf0, offset 0x725\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0xf1, offset 0x72a\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0018, lo: 0x9c, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x03c0, lo: 0xa0, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xbf},\n\t// Block 0xf2, offset 0x734\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xf3, offset 0x737\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa8},\n\t{value: 0x0018, lo: 0xa9, hi: 0xbf},\n\t// Block 0xf4, offset 0x73b\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0018, lo: 0x80, hi: 0x9d},\n\t{value: 0x2211, lo: 0x9e, hi: 0x9e},\n\t{value: 0x2219, lo: 0x9f, hi: 0x9f},\n\t{value: 0x2221, lo: 0xa0, hi: 0xa0},\n\t{value: 0x2229, lo: 0xa1, hi: 0xa1},\n\t{value: 0x2231, lo: 0xa2, hi: 0xa2},\n\t{value: 0x2239, lo: 0xa3, hi: 0xa3},\n\t{value: 0x2241, lo: 0xa4, hi: 0xa4},\n\t{value: 0x3018, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3318, lo: 0xa7, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xac},\n\t{value: 0x3018, lo: 0xad, hi: 0xb2},\n\t{value: 0x0340, lo: 0xb3, hi: 0xba},\n\t{value: 0x3318, lo: 0xbb, hi: 0xbf},\n\t// Block 0xf5, offset 0x74a\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3318, lo: 0x80, hi: 0x82},\n\t{value: 0x0018, lo: 0x83, hi: 0x84},\n\t{value: 0x3318, lo: 0x85, hi: 0x8b},\n\t{value: 0x0018, lo: 0x8c, hi: 0xa9},\n\t{value: 0x3318, lo: 0xaa, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xba},\n\t{value: 0x2249, lo: 0xbb, hi: 0xbb},\n\t{value: 0x2251, lo: 0xbc, hi: 0xbc},\n\t{value: 0x2259, lo: 0xbd, hi: 0xbd},\n\t{value: 0x2261, lo: 0xbe, hi: 0xbe},\n\t{value: 0x2269, lo: 0xbf, hi: 0xbf},\n\t// Block 0xf6, offset 0x756\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x2271, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xbf},\n\t// Block 0xf7, offset 0x75a\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x81},\n\t{value: 0x3318, lo: 0x82, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0xbf},\n\t// Block 0xf8, offset 0x75f\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0xf9, offset 0x763\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xfa, offset 0x768\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3308, lo: 0x80, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbf},\n\t// Block 0xfb, offset 0x76c\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x3308, lo: 0x80, hi: 0xac},\n\t{value: 0x0018, lo: 0xad, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0xfc, offset 0x771\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x3308, lo: 0xa1, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0xfd, offset 0x77a\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x3308, lo: 0x88, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xa4},\n\t{value: 0x0040, lo: 0xa5, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xbf},\n\t// Block 0xfe, offset 0x785\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0008, lo: 0xb7, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0xff, offset 0x78b\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0018, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0xbf},\n\t// Block 0x100, offset 0x791\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0x101, offset 0x797\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0808, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x86},\n\t{value: 0x0818, lo: 0x87, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0xbf},\n\t// Block 0x102, offset 0x79d\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0a08, lo: 0x80, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x8a},\n\t{value: 0x0b08, lo: 0x8b, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0818, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x103, offset 0x7a6\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xb0},\n\t{value: 0x0818, lo: 0xb1, hi: 0xbf},\n\t// Block 0x104, offset 0x7a9\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0818, lo: 0x80, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x105, offset 0x7ac\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0818, lo: 0x81, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x106, offset 0x7b0\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0x107, offset 0x7b4\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x108, offset 0x7b8\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xb0},\n\t{value: 0x0018, lo: 0xb1, hi: 0xbf},\n\t// Block 0x109, offset 0x7be\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x0018, lo: 0x91, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0x10a, offset 0x7c4\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x8f},\n\t{value: 0x2491, lo: 0x90, hi: 0x90},\n\t{value: 0x0018, lo: 0x91, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xbf},\n\t// Block 0x10b, offset 0x7c9\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xa5},\n\t{value: 0x0018, lo: 0xa6, hi: 0xbf},\n\t// Block 0x10c, offset 0x7cc\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x2611, lo: 0x80, hi: 0x80},\n\t{value: 0x2619, lo: 0x81, hi: 0x81},\n\t{value: 0x2621, lo: 0x82, hi: 0x82},\n\t{value: 0x2629, lo: 0x83, hi: 0x83},\n\t{value: 0x2631, lo: 0x84, hi: 0x84},\n\t{value: 0x2639, lo: 0x85, hi: 0x85},\n\t{value: 0x2641, lo: 0x86, hi: 0x86},\n\t{value: 0x2649, lo: 0x87, hi: 0x87},\n\t{value: 0x2651, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x2659, lo: 0x90, hi: 0x90},\n\t{value: 0x2661, lo: 0x91, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xbf},\n\t// Block 0x10d, offset 0x7dc\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x10e, offset 0x7e3\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x10f, offset 0x7e6\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xbf},\n\t// Block 0x110, offset 0x7eb\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x111, offset 0x7ef\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbf},\n\t// Block 0x112, offset 0x7f5\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0x113, offset 0x7fc\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbf},\n\t// Block 0x114, offset 0x800\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0xbf},\n\t// Block 0x115, offset 0x804\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x116, offset 0x80d\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x117, offset 0x814\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0xbf},\n\t// Block 0x118, offset 0x819\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x92},\n\t{value: 0x0040, lo: 0x93, hi: 0x93},\n\t{value: 0x0018, lo: 0x94, hi: 0xbf},\n\t// Block 0x119, offset 0x81d\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0018, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0xaf},\n\t{value: 0x06e1, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0049, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0029, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0031, lo: 0xb3, hi: 0xb3},\n\t{value: 0x06e9, lo: 0xb4, hi: 0xb4},\n\t{value: 0x06f1, lo: 0xb5, hi: 0xb5},\n\t{value: 0x06f9, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0701, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0709, lo: 0xb8, hi: 0xb8},\n\t{value: 0x0711, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x11a, offset 0x82b\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0x11b, offset 0x82e\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x11c, offset 0x831\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x11d, offset 0x835\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x11e, offset 0x839\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xa0},\n\t{value: 0x0040, lo: 0xa1, hi: 0xbf},\n\t// Block 0x11f, offset 0x83c\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0xbf},\n\t// Block 0x120, offset 0x83f\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0340, lo: 0x81, hi: 0x81},\n\t{value: 0x0040, lo: 0x82, hi: 0x9f},\n\t{value: 0x0340, lo: 0xa0, hi: 0xbf},\n\t// Block 0x121, offset 0x844\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0340, lo: 0x80, hi: 0xbf},\n\t// Block 0x122, offset 0x846\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x33c0, lo: 0x80, hi: 0xbf},\n\t// Block 0x123, offset 0x848\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x33c0, lo: 0x80, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n}\n\n// Total table size 44953 bytes (43KiB); checksum: D51909DD\n"
  },
  {
    "path": "vendor/golang.org/x/net/idna/tables15.0.0.go",
    "content": "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n//go:build go1.21\n\npackage idna\n\n// UnicodeVersion is the Unicode version from which the tables in this package are derived.\nconst UnicodeVersion = \"15.0.0\"\n\nvar mappings string = \"\" + // Size: 6704 bytes\n\t\"  ̈a ̄23 ́ ̧1o1⁄41⁄23⁄4i̇l·ʼnsdžⱥⱦhjrwy ̆ ̇ ̊ ̨ ̃ ̋lẍ́ ι; ̈́եւاٴوٴۇٴيٴक\" +\n\t\"़ख़ग़ज़ड़ढ़फ़य़ড়ঢ়য়ਲ਼ਸ਼ਖ਼ਗ਼ਜ਼ਫ਼ଡ଼ଢ଼ําໍາຫນຫມགྷཌྷདྷབྷཛྷཀྵཱཱིུྲྀྲཱྀླྀླཱ\" +\n\t\"ཱྀྀྒྷྜྷྡྷྦྷྫྷྐྵвдостъѣæbdeǝgikmnȣptuɐɑəɛɜŋɔɯvβγδφχρнɒcɕðfɟɡɥɨɩɪʝɭʟɱɰɲɳ\" +\n\t\"ɴɵɸʂʃƫʉʊʋʌzʐʑʒθssάέήίόύώἀιἁιἂιἃιἄιἅιἆιἇιἠιἡιἢιἣιἤιἥιἦιἧιὠιὡιὢιὣιὤιὥιὦιὧ\" +\n\t\"ιὰιαιάιᾶιι ̈͂ὴιηιήιῆι ̓̀ ̓́ ̓͂ΐ ̔̀ ̔́ ̔͂ΰ ̈̀`ὼιωιώιῶι′′′′′‵‵‵‵‵!!???!!?\" +\n\t\"′′′′0456789+=()rsħnoqsmtmωåאבגדπ1⁄71⁄91⁄101⁄32⁄31⁄52⁄53⁄54⁄51⁄65⁄61⁄83\" +\n\t\"⁄85⁄87⁄81⁄iiivviviiiixxi0⁄3∫∫∫∫∫∮∮∮∮∮1011121314151617181920(10)(11)(12\" +\n\t\")(13)(14)(15)(16)(17)(18)(19)(20)∫∫∫∫==⫝̸ɫɽȿɀ. ゙ ゚よりコト(ᄀ)(ᄂ)(ᄃ)(ᄅ)(ᄆ)(ᄇ)\" +\n\t\"(ᄉ)(ᄋ)(ᄌ)(ᄎ)(ᄏ)(ᄐ)(ᄑ)(ᄒ)(가)(나)(다)(라)(마)(바)(사)(아)(자)(차)(카)(타)(파)(하)(주)(오전\" +\n\t\")(오후)(一)(二)(三)(四)(五)(六)(七)(八)(九)(十)(月)(火)(水)(木)(金)(土)(日)(株)(有)(社)(名)(特)(\" +\n\t\"財)(祝)(労)(代)(呼)(学)(監)(企)(資)(協)(祭)(休)(自)(至)21222324252627282930313233343\" +\n\t\"5참고주의3637383940414243444546474849501月2月3月4月5月6月7月8月9月10月11月12月hgev令和アパート\" +\n\t\"アルファアンペアアールイニングインチウォンエスクードエーカーオンスオームカイリカラットカロリーガロンガンマギガギニーキュリーギルダーキロキロ\" +\n\t\"グラムキロメートルキロワットグラムグラムトンクルゼイロクローネケースコルナコーポサイクルサンチームシリングセンチセントダースデシドルトンナノ\" +\n\t\"ノットハイツパーセントパーツバーレルピアストルピクルピコビルファラッドフィートブッシェルフランヘクタールペソペニヒヘルツペンスページベータポ\" +\n\t\"イントボルトホンポンドホールホーンマイクロマイルマッハマルクマンションミクロンミリミリバールメガメガトンメートルヤードヤールユアンリットルリ\" +\n\t\"ラルピールーブルレムレントゲンワット0点1点2点3点4点5点6点7点8点9点10点11点12点13点14点15点16点17点18点19点20\" +\n\t\"点21点22点23点24点daauovpcdmiu平成昭和大正明治株式会社panamakakbmbgbkcalpfnfmgkghzmldlk\" +\n\t\"lfmnmmmcmkmm2m3m∕sm∕s2rad∕srad∕s2psnsmspvnvmvkvpwnwmwkwbqcccdc∕kgdbgyhah\" +\n\t\"pinkkktlmlnlxphprsrsvwbv∕ma∕m1日2日3日4日5日6日7日8日9日10日11日12日13日14日15日16日17日1\" +\n\t\"8日19日20日21日22日23日24日25日26日27日28日29日30日31日ьɦɬʞʇœʍ𤋮𢡊𢡄𣏕𥉉𥳐𧻓fffiflstմնմեմիվնմ\" +\n\t\"խיִײַעהכלםרתשׁשׂשּׁשּׂאַאָאּבּגּדּהּוּזּטּיּךּכּלּמּנּסּףּפּצּקּרּשּתּו\" +\n\t\"ֹבֿכֿפֿאלٱٻپڀٺٿٹڤڦڄڃچڇڍڌڎڈژڑکگڳڱںڻۀہھےۓڭۇۆۈۋۅۉېىئائەئوئۇئۆئۈئېئىیئجئحئم\" +\n\t\"ئيبجبحبخبمبىبيتجتحتختمتىتيثجثمثىثيجحجمحجحمخجخحخمسجسحسخسمصحصمضجضحضخضمطحط\" +\n\t\"مظمعجعمغجغمفجفحفخفمفىفيقحقمقىقيكاكجكحكخكلكمكىكيلجلحلخلملىليمجمحمخمممىمي\" +\n\t\"نجنحنخنمنىنيهجهمهىهييجيحيخيميىييذٰرٰىٰ ٌّ ٍّ َّ ُّ ِّ ّٰئرئزئنبربزبنترت\" +\n\t\"زتنثرثزثنمانرنزننيريزينئخئهبهتهصخلهنههٰيهثهسهشمشهـَّـُّـِّطىطيعىعيغىغيس\" +\n\t\"ىسيشىشيحىحيجىجيخىخيصىصيضىضيشجشحشخشرسرصرضراًتجمتحجتحمتخمتمجتمحتمخجمححميح\" +\n\t\"مىسحجسجحسجىسمحسمجسممصححصممشحمشجيشمخشممضحىضخمطمحطممطميعجمعممعمىغممغميغمى\" +\n\t\"فخمقمحقمملحملحيلحىلججلخملمحمحجمحممحيمجحمجممخجمخممجخهمجهممنحمنحىنجمنجىنم\" +\n\t\"ينمىيممبخيتجيتجىتخيتخىتميتمىجميجحىجمىسخىصحيشحيضحيلجيلمييحييجييميمميقمين\" +\n\t\"حيعميكمينجحمخيلجمكممجحيحجيمجيفميبحيسخينجيصلےقلےاللهاكبرمحمدصلعمرسولعليه\" +\n\t\"وسلمصلىصلى الله عليه وسلمجل جلالهریال,:!?_{}[]#&*-<>\\\\$%@ـًـَـُـِـّـْءآ\" +\n\t\"أؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهويلآلألإلا\\x22'/^|~¢£¬¦¥ːˑʙɓʣꭦʥʤɖɗᶑɘɞʩɤɢ\" +\n\t\"ɠʛʜɧʄʪʫꞎɮʎøɶɷɺɾʀʨʦꭧʧʈⱱʏʡʢʘǀǁǂ𝅗𝅥𝅘𝅥𝅘𝅥𝅮𝅘𝅥𝅯𝅘𝅥𝅰𝅘𝅥𝅱𝅘𝅥𝅲𝆹𝅥𝆺𝅥𝆹𝅥𝅮𝆺𝅥𝅮𝆹𝅥𝅯𝆺𝅥𝅯ıȷαεζηκ\" +\n\t\"λμνξοστυψ∇∂ϝабгежзиклмпруфхцчшыэюꚉәіјөүӏґѕџҫꙑұٮڡٯ0,1,2,3,4,5,6,7,8,9,(a\" +\n\t\")(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)(m)(n)(o)(p)(q)(r)(s)(t)(u)(v)(w)(x)(y\" +\n\t\")(z)〔s〕wzhvsdppvwcmcmdmrdjほかココサ手字双デ二多解天交映無料前後再新初終生販声吹演投捕一三遊左中右指走打禁空合満有月申\" +\n\t\"割営配〔本〕〔三〕〔二〕〔安〕〔点〕〔打〕〔盗〕〔勝〕〔敗〕得可丽丸乁你侮侻倂偺備僧像㒞免兔兤具㒹內冗冤仌冬况凵刃㓟刻剆剷㔕勇勉勤勺包匆北卉\" +\n\t\"卑博即卽卿灰及叟叫叱吆咞吸呈周咢哶唐啓啣善喙喫喳嗂圖嘆圗噑噴切壮城埴堍型堲報墬売壷夆夢奢姬娛娧姘婦㛮嬈嬾寃寘寧寳寿将尢㞁屠屮峀岍嵃嵮嵫嵼巡巢\" +\n\t\"㠯巽帨帽幩㡢㡼庰庳庶廊廾舁弢㣇形彫㣣徚忍志忹悁㤺㤜悔惇慈慌慎慺憎憲憤憯懞懲懶成戛扝抱拔捐挽拼捨掃揤搢揅掩㨮摩摾撝摷㩬敏敬旣書晉㬙暑㬈㫤冒冕最\" +\n\t\"暜肭䏙朗望朡杞杓㭉柺枅桒梅梎栟椔㮝楂榣槪檨櫛㰘次歔㱎歲殟殺殻汎沿泍汧洖派海流浩浸涅洴港湮㴳滋滇淹潮濆瀹瀞瀛㶖灊災灷炭煅熜爨爵牐犀犕獺王㺬玥㺸\" +\n\t\"瑇瑜瑱璅瓊㼛甤甾異瘐㿼䀈直眞真睊䀹瞋䁆䂖硎碌磌䃣祖福秫䄯穀穊穏䈂篆築䈧糒䊠糨糣紀絣䌁緇縂繅䌴䍙罺羕翺者聠聰䏕育脃䐋脾媵舄辞䑫芑芋芝劳花芳芽苦\" +\n\t\"若茝荣莭茣莽菧著荓菊菌菜䔫蓱蓳蔖蕤䕝䕡䕫虐虜虧虩蚩蚈蜎蛢蝹蜨蝫螆蟡蠁䗹衠衣裗裞䘵裺㒻䚾䛇誠諭變豕貫賁贛起跋趼跰軔輸邔郱鄑鄛鈸鋗鋘鉼鏹鐕開䦕閷\" +\n\t\"䧦雃嶲霣䩮䩶韠䪲頋頩飢䬳餩馧駂駾䯎鬒鱀鳽䳎䳭鵧䳸麻䵖黹黾鼅鼏鼖鼻\"\n\nvar mappingIndex = []uint16{ // 1729 elements\n\t// Entry 0 - 3F\n\t0x0000, 0x0000, 0x0001, 0x0004, 0x0005, 0x0008, 0x0009, 0x000a,\n\t0x000d, 0x0010, 0x0011, 0x0012, 0x0017, 0x001c, 0x0021, 0x0024,\n\t0x0027, 0x002a, 0x002b, 0x002e, 0x0031, 0x0034, 0x0035, 0x0036,\n\t0x0037, 0x0038, 0x0039, 0x003c, 0x003f, 0x0042, 0x0045, 0x0048,\n\t0x004b, 0x004c, 0x004d, 0x0051, 0x0054, 0x0055, 0x005a, 0x005e,\n\t0x0062, 0x0066, 0x006a, 0x006e, 0x0074, 0x007a, 0x0080, 0x0086,\n\t0x008c, 0x0092, 0x0098, 0x009e, 0x00a4, 0x00aa, 0x00b0, 0x00b6,\n\t0x00bc, 0x00c2, 0x00c8, 0x00ce, 0x00d4, 0x00da, 0x00e0, 0x00e6,\n\t// Entry 40 - 7F\n\t0x00ec, 0x00f2, 0x00f8, 0x00fe, 0x0104, 0x010a, 0x0110, 0x0116,\n\t0x011c, 0x0122, 0x0128, 0x012e, 0x0137, 0x013d, 0x0146, 0x014c,\n\t0x0152, 0x0158, 0x015e, 0x0164, 0x016a, 0x0170, 0x0172, 0x0174,\n\t0x0176, 0x0178, 0x017a, 0x017c, 0x017e, 0x0180, 0x0181, 0x0182,\n\t0x0183, 0x0185, 0x0186, 0x0187, 0x0188, 0x0189, 0x018a, 0x018c,\n\t0x018d, 0x018e, 0x018f, 0x0191, 0x0193, 0x0195, 0x0197, 0x0199,\n\t0x019b, 0x019d, 0x019f, 0x01a0, 0x01a2, 0x01a4, 0x01a6, 0x01a8,\n\t0x01aa, 0x01ac, 0x01ae, 0x01b0, 0x01b1, 0x01b3, 0x01b5, 0x01b6,\n\t// Entry 80 - BF\n\t0x01b8, 0x01ba, 0x01bc, 0x01be, 0x01c0, 0x01c2, 0x01c4, 0x01c6,\n\t0x01c8, 0x01ca, 0x01cc, 0x01ce, 0x01d0, 0x01d2, 0x01d4, 0x01d6,\n\t0x01d8, 0x01da, 0x01dc, 0x01de, 0x01e0, 0x01e2, 0x01e4, 0x01e5,\n\t0x01e7, 0x01e9, 0x01eb, 0x01ed, 0x01ef, 0x01f1, 0x01f3, 0x01f5,\n\t0x01f7, 0x01f9, 0x01fb, 0x01fd, 0x0202, 0x0207, 0x020c, 0x0211,\n\t0x0216, 0x021b, 0x0220, 0x0225, 0x022a, 0x022f, 0x0234, 0x0239,\n\t0x023e, 0x0243, 0x0248, 0x024d, 0x0252, 0x0257, 0x025c, 0x0261,\n\t0x0266, 0x026b, 0x0270, 0x0275, 0x027a, 0x027e, 0x0282, 0x0287,\n\t// Entry C0 - FF\n\t0x0289, 0x028e, 0x0293, 0x0297, 0x029b, 0x02a0, 0x02a5, 0x02aa,\n\t0x02af, 0x02b1, 0x02b6, 0x02bb, 0x02c0, 0x02c2, 0x02c7, 0x02c8,\n\t0x02cd, 0x02d1, 0x02d5, 0x02da, 0x02e0, 0x02e9, 0x02ef, 0x02f8,\n\t0x02fa, 0x02fc, 0x02fe, 0x0300, 0x030c, 0x030d, 0x030e, 0x030f,\n\t0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317,\n\t0x0319, 0x031b, 0x031d, 0x031e, 0x0320, 0x0322, 0x0324, 0x0326,\n\t0x0328, 0x032a, 0x032c, 0x032e, 0x0330, 0x0335, 0x033a, 0x0340,\n\t0x0345, 0x034a, 0x034f, 0x0354, 0x0359, 0x035e, 0x0363, 0x0368,\n\t// Entry 100 - 13F\n\t0x036d, 0x0372, 0x0377, 0x037c, 0x0380, 0x0382, 0x0384, 0x0386,\n\t0x038a, 0x038c, 0x038e, 0x0393, 0x0399, 0x03a2, 0x03a8, 0x03b1,\n\t0x03b3, 0x03b5, 0x03b7, 0x03b9, 0x03bb, 0x03bd, 0x03bf, 0x03c1,\n\t0x03c3, 0x03c5, 0x03c7, 0x03cb, 0x03cf, 0x03d3, 0x03d7, 0x03db,\n\t0x03df, 0x03e3, 0x03e7, 0x03eb, 0x03ef, 0x03f3, 0x03ff, 0x0401,\n\t0x0406, 0x0408, 0x040a, 0x040c, 0x040e, 0x040f, 0x0413, 0x0417,\n\t0x041d, 0x0423, 0x0428, 0x042d, 0x0432, 0x0437, 0x043c, 0x0441,\n\t0x0446, 0x044b, 0x0450, 0x0455, 0x045a, 0x045f, 0x0464, 0x0469,\n\t// Entry 140 - 17F\n\t0x046e, 0x0473, 0x0478, 0x047d, 0x0482, 0x0487, 0x048c, 0x0491,\n\t0x0496, 0x049b, 0x04a0, 0x04a5, 0x04aa, 0x04af, 0x04b4, 0x04bc,\n\t0x04c4, 0x04c9, 0x04ce, 0x04d3, 0x04d8, 0x04dd, 0x04e2, 0x04e7,\n\t0x04ec, 0x04f1, 0x04f6, 0x04fb, 0x0500, 0x0505, 0x050a, 0x050f,\n\t0x0514, 0x0519, 0x051e, 0x0523, 0x0528, 0x052d, 0x0532, 0x0537,\n\t0x053c, 0x0541, 0x0546, 0x054b, 0x0550, 0x0555, 0x055a, 0x055f,\n\t0x0564, 0x0569, 0x056e, 0x0573, 0x0578, 0x057a, 0x057c, 0x057e,\n\t0x0580, 0x0582, 0x0584, 0x0586, 0x0588, 0x058a, 0x058c, 0x058e,\n\t// Entry 180 - 1BF\n\t0x0590, 0x0592, 0x0594, 0x0596, 0x059c, 0x05a2, 0x05a4, 0x05a6,\n\t0x05a8, 0x05aa, 0x05ac, 0x05ae, 0x05b0, 0x05b2, 0x05b4, 0x05b6,\n\t0x05b8, 0x05ba, 0x05bc, 0x05be, 0x05c0, 0x05c4, 0x05c8, 0x05cc,\n\t0x05d0, 0x05d4, 0x05d8, 0x05dc, 0x05e0, 0x05e4, 0x05e9, 0x05ee,\n\t0x05f3, 0x05f5, 0x05f7, 0x05fd, 0x0609, 0x0615, 0x0621, 0x062a,\n\t0x0636, 0x063f, 0x0648, 0x0657, 0x0663, 0x066c, 0x0675, 0x067e,\n\t0x068a, 0x0696, 0x069f, 0x06a8, 0x06ae, 0x06b7, 0x06c3, 0x06cf,\n\t0x06d5, 0x06e4, 0x06f6, 0x0705, 0x070e, 0x071d, 0x072c, 0x0738,\n\t// Entry 1C0 - 1FF\n\t0x0741, 0x074a, 0x0753, 0x075f, 0x076e, 0x077a, 0x0783, 0x078c,\n\t0x0795, 0x079b, 0x07a1, 0x07a7, 0x07ad, 0x07b6, 0x07bf, 0x07ce,\n\t0x07d7, 0x07e3, 0x07f2, 0x07fb, 0x0801, 0x0807, 0x0816, 0x0822,\n\t0x0831, 0x083a, 0x0849, 0x084f, 0x0858, 0x0861, 0x086a, 0x0873,\n\t0x087c, 0x0888, 0x0891, 0x0897, 0x08a0, 0x08a9, 0x08b2, 0x08be,\n\t0x08c7, 0x08d0, 0x08d9, 0x08e8, 0x08f4, 0x08fa, 0x0909, 0x090f,\n\t0x091b, 0x0927, 0x0930, 0x0939, 0x0942, 0x094e, 0x0954, 0x095d,\n\t0x0969, 0x096f, 0x097e, 0x0987, 0x098b, 0x098f, 0x0993, 0x0997,\n\t// Entry 200 - 23F\n\t0x099b, 0x099f, 0x09a3, 0x09a7, 0x09ab, 0x09af, 0x09b4, 0x09b9,\n\t0x09be, 0x09c3, 0x09c8, 0x09cd, 0x09d2, 0x09d7, 0x09dc, 0x09e1,\n\t0x09e6, 0x09eb, 0x09f0, 0x09f5, 0x09fa, 0x09fc, 0x09fe, 0x0a00,\n\t0x0a02, 0x0a04, 0x0a06, 0x0a0c, 0x0a12, 0x0a18, 0x0a1e, 0x0a2a,\n\t0x0a2c, 0x0a2e, 0x0a30, 0x0a32, 0x0a34, 0x0a36, 0x0a38, 0x0a3c,\n\t0x0a3e, 0x0a40, 0x0a42, 0x0a44, 0x0a46, 0x0a48, 0x0a4a, 0x0a4c,\n\t0x0a4e, 0x0a50, 0x0a52, 0x0a54, 0x0a56, 0x0a58, 0x0a5a, 0x0a5f,\n\t0x0a65, 0x0a6c, 0x0a74, 0x0a76, 0x0a78, 0x0a7a, 0x0a7c, 0x0a7e,\n\t// Entry 240 - 27F\n\t0x0a80, 0x0a82, 0x0a84, 0x0a86, 0x0a88, 0x0a8a, 0x0a8c, 0x0a8e,\n\t0x0a90, 0x0a96, 0x0a98, 0x0a9a, 0x0a9c, 0x0a9e, 0x0aa0, 0x0aa2,\n\t0x0aa4, 0x0aa6, 0x0aa8, 0x0aaa, 0x0aac, 0x0aae, 0x0ab0, 0x0ab2,\n\t0x0ab4, 0x0ab9, 0x0abe, 0x0ac2, 0x0ac6, 0x0aca, 0x0ace, 0x0ad2,\n\t0x0ad6, 0x0ada, 0x0ade, 0x0ae2, 0x0ae7, 0x0aec, 0x0af1, 0x0af6,\n\t0x0afb, 0x0b00, 0x0b05, 0x0b0a, 0x0b0f, 0x0b14, 0x0b19, 0x0b1e,\n\t0x0b23, 0x0b28, 0x0b2d, 0x0b32, 0x0b37, 0x0b3c, 0x0b41, 0x0b46,\n\t0x0b4b, 0x0b50, 0x0b52, 0x0b54, 0x0b56, 0x0b58, 0x0b5a, 0x0b5c,\n\t// Entry 280 - 2BF\n\t0x0b5e, 0x0b62, 0x0b66, 0x0b6a, 0x0b6e, 0x0b72, 0x0b76, 0x0b7a,\n\t0x0b7c, 0x0b7e, 0x0b80, 0x0b82, 0x0b86, 0x0b8a, 0x0b8e, 0x0b92,\n\t0x0b96, 0x0b9a, 0x0b9e, 0x0ba0, 0x0ba2, 0x0ba4, 0x0ba6, 0x0ba8,\n\t0x0baa, 0x0bac, 0x0bb0, 0x0bb4, 0x0bba, 0x0bc0, 0x0bc4, 0x0bc8,\n\t0x0bcc, 0x0bd0, 0x0bd4, 0x0bd8, 0x0bdc, 0x0be0, 0x0be4, 0x0be8,\n\t0x0bec, 0x0bf0, 0x0bf4, 0x0bf8, 0x0bfc, 0x0c00, 0x0c04, 0x0c08,\n\t0x0c0c, 0x0c10, 0x0c14, 0x0c18, 0x0c1c, 0x0c20, 0x0c24, 0x0c28,\n\t0x0c2c, 0x0c30, 0x0c34, 0x0c36, 0x0c38, 0x0c3a, 0x0c3c, 0x0c3e,\n\t// Entry 2C0 - 2FF\n\t0x0c40, 0x0c42, 0x0c44, 0x0c46, 0x0c48, 0x0c4a, 0x0c4c, 0x0c4e,\n\t0x0c50, 0x0c52, 0x0c54, 0x0c56, 0x0c58, 0x0c5a, 0x0c5c, 0x0c5e,\n\t0x0c60, 0x0c62, 0x0c64, 0x0c66, 0x0c68, 0x0c6a, 0x0c6c, 0x0c6e,\n\t0x0c70, 0x0c72, 0x0c74, 0x0c76, 0x0c78, 0x0c7a, 0x0c7c, 0x0c7e,\n\t0x0c80, 0x0c82, 0x0c86, 0x0c8a, 0x0c8e, 0x0c92, 0x0c96, 0x0c9a,\n\t0x0c9e, 0x0ca2, 0x0ca4, 0x0ca8, 0x0cac, 0x0cb0, 0x0cb4, 0x0cb8,\n\t0x0cbc, 0x0cc0, 0x0cc4, 0x0cc8, 0x0ccc, 0x0cd0, 0x0cd4, 0x0cd8,\n\t0x0cdc, 0x0ce0, 0x0ce4, 0x0ce8, 0x0cec, 0x0cf0, 0x0cf4, 0x0cf8,\n\t// Entry 300 - 33F\n\t0x0cfc, 0x0d00, 0x0d04, 0x0d08, 0x0d0c, 0x0d10, 0x0d14, 0x0d18,\n\t0x0d1c, 0x0d20, 0x0d24, 0x0d28, 0x0d2c, 0x0d30, 0x0d34, 0x0d38,\n\t0x0d3c, 0x0d40, 0x0d44, 0x0d48, 0x0d4c, 0x0d50, 0x0d54, 0x0d58,\n\t0x0d5c, 0x0d60, 0x0d64, 0x0d68, 0x0d6c, 0x0d70, 0x0d74, 0x0d78,\n\t0x0d7c, 0x0d80, 0x0d84, 0x0d88, 0x0d8c, 0x0d90, 0x0d94, 0x0d98,\n\t0x0d9c, 0x0da0, 0x0da4, 0x0da8, 0x0dac, 0x0db0, 0x0db4, 0x0db8,\n\t0x0dbc, 0x0dc0, 0x0dc4, 0x0dc8, 0x0dcc, 0x0dd0, 0x0dd4, 0x0dd8,\n\t0x0ddc, 0x0de0, 0x0de4, 0x0de8, 0x0dec, 0x0df0, 0x0df4, 0x0df8,\n\t// Entry 340 - 37F\n\t0x0dfc, 0x0e00, 0x0e04, 0x0e08, 0x0e0c, 0x0e10, 0x0e14, 0x0e18,\n\t0x0e1d, 0x0e22, 0x0e27, 0x0e2c, 0x0e31, 0x0e36, 0x0e3a, 0x0e3e,\n\t0x0e42, 0x0e46, 0x0e4a, 0x0e4e, 0x0e52, 0x0e56, 0x0e5a, 0x0e5e,\n\t0x0e62, 0x0e66, 0x0e6a, 0x0e6e, 0x0e72, 0x0e76, 0x0e7a, 0x0e7e,\n\t0x0e82, 0x0e86, 0x0e8a, 0x0e8e, 0x0e92, 0x0e96, 0x0e9a, 0x0e9e,\n\t0x0ea2, 0x0ea6, 0x0eaa, 0x0eae, 0x0eb2, 0x0eb6, 0x0ebc, 0x0ec2,\n\t0x0ec8, 0x0ecc, 0x0ed0, 0x0ed4, 0x0ed8, 0x0edc, 0x0ee0, 0x0ee4,\n\t0x0ee8, 0x0eec, 0x0ef0, 0x0ef4, 0x0ef8, 0x0efc, 0x0f00, 0x0f04,\n\t// Entry 380 - 3BF\n\t0x0f08, 0x0f0c, 0x0f10, 0x0f14, 0x0f18, 0x0f1c, 0x0f20, 0x0f24,\n\t0x0f28, 0x0f2c, 0x0f30, 0x0f34, 0x0f38, 0x0f3e, 0x0f44, 0x0f4a,\n\t0x0f50, 0x0f56, 0x0f5c, 0x0f62, 0x0f68, 0x0f6e, 0x0f74, 0x0f7a,\n\t0x0f80, 0x0f86, 0x0f8c, 0x0f92, 0x0f98, 0x0f9e, 0x0fa4, 0x0faa,\n\t0x0fb0, 0x0fb6, 0x0fbc, 0x0fc2, 0x0fc8, 0x0fce, 0x0fd4, 0x0fda,\n\t0x0fe0, 0x0fe6, 0x0fec, 0x0ff2, 0x0ff8, 0x0ffe, 0x1004, 0x100a,\n\t0x1010, 0x1016, 0x101c, 0x1022, 0x1028, 0x102e, 0x1034, 0x103a,\n\t0x1040, 0x1046, 0x104c, 0x1052, 0x1058, 0x105e, 0x1064, 0x106a,\n\t// Entry 3C0 - 3FF\n\t0x1070, 0x1076, 0x107c, 0x1082, 0x1088, 0x108e, 0x1094, 0x109a,\n\t0x10a0, 0x10a6, 0x10ac, 0x10b2, 0x10b8, 0x10be, 0x10c4, 0x10ca,\n\t0x10d0, 0x10d6, 0x10dc, 0x10e2, 0x10e8, 0x10ee, 0x10f4, 0x10fa,\n\t0x1100, 0x1106, 0x110c, 0x1112, 0x1118, 0x111e, 0x1124, 0x112a,\n\t0x1130, 0x1136, 0x113c, 0x1142, 0x1148, 0x114e, 0x1154, 0x115a,\n\t0x1160, 0x1166, 0x116c, 0x1172, 0x1178, 0x1180, 0x1188, 0x1190,\n\t0x1198, 0x11a0, 0x11a8, 0x11b0, 0x11b6, 0x11d7, 0x11e6, 0x11ee,\n\t0x11ef, 0x11f0, 0x11f1, 0x11f2, 0x11f3, 0x11f4, 0x11f5, 0x11f6,\n\t// Entry 400 - 43F\n\t0x11f7, 0x11f8, 0x11f9, 0x11fa, 0x11fb, 0x11fc, 0x11fd, 0x11fe,\n\t0x11ff, 0x1200, 0x1201, 0x1205, 0x1209, 0x120d, 0x1211, 0x1215,\n\t0x1219, 0x121b, 0x121d, 0x121f, 0x1221, 0x1223, 0x1225, 0x1227,\n\t0x1229, 0x122b, 0x122d, 0x122f, 0x1231, 0x1233, 0x1235, 0x1237,\n\t0x1239, 0x123b, 0x123d, 0x123f, 0x1241, 0x1243, 0x1245, 0x1247,\n\t0x1249, 0x124b, 0x124d, 0x124f, 0x1251, 0x1253, 0x1255, 0x1257,\n\t0x1259, 0x125b, 0x125d, 0x125f, 0x1263, 0x1267, 0x126b, 0x126f,\n\t0x1270, 0x1271, 0x1272, 0x1273, 0x1274, 0x1275, 0x1277, 0x1279,\n\t// Entry 440 - 47F\n\t0x127b, 0x127d, 0x127f, 0x1281, 0x1283, 0x1285, 0x1287, 0x1289,\n\t0x128c, 0x128e, 0x1290, 0x1292, 0x1294, 0x1297, 0x1299, 0x129b,\n\t0x129d, 0x129f, 0x12a1, 0x12a3, 0x12a5, 0x12a7, 0x12a9, 0x12ab,\n\t0x12ad, 0x12af, 0x12b2, 0x12b4, 0x12b6, 0x12b8, 0x12ba, 0x12bc,\n\t0x12be, 0x12c0, 0x12c2, 0x12c4, 0x12c6, 0x12c9, 0x12cb, 0x12cd,\n\t0x12d0, 0x12d2, 0x12d4, 0x12d6, 0x12d8, 0x12da, 0x12dc, 0x12de,\n\t0x12e6, 0x12ee, 0x12fa, 0x1306, 0x1312, 0x131e, 0x132a, 0x1332,\n\t0x133a, 0x1346, 0x1352, 0x135e, 0x136a, 0x136c, 0x136e, 0x1370,\n\t// Entry 480 - 4BF\n\t0x1372, 0x1374, 0x1376, 0x1378, 0x137a, 0x137c, 0x137e, 0x1380,\n\t0x1382, 0x1384, 0x1386, 0x1388, 0x138a, 0x138d, 0x1390, 0x1392,\n\t0x1394, 0x1396, 0x1398, 0x139a, 0x139c, 0x139e, 0x13a0, 0x13a2,\n\t0x13a4, 0x13a6, 0x13a8, 0x13aa, 0x13ac, 0x13ae, 0x13b0, 0x13b2,\n\t0x13b4, 0x13b6, 0x13b8, 0x13ba, 0x13bc, 0x13bf, 0x13c1, 0x13c3,\n\t0x13c5, 0x13c7, 0x13c9, 0x13cb, 0x13cd, 0x13cf, 0x13d1, 0x13d3,\n\t0x13d6, 0x13d8, 0x13da, 0x13dc, 0x13de, 0x13e0, 0x13e2, 0x13e4,\n\t0x13e6, 0x13e8, 0x13ea, 0x13ec, 0x13ee, 0x13f0, 0x13f2, 0x13f5,\n\t// Entry 4C0 - 4FF\n\t0x13f8, 0x13fb, 0x13fe, 0x1401, 0x1404, 0x1407, 0x140a, 0x140d,\n\t0x1410, 0x1413, 0x1416, 0x1419, 0x141c, 0x141f, 0x1422, 0x1425,\n\t0x1428, 0x142b, 0x142e, 0x1431, 0x1434, 0x1437, 0x143a, 0x143d,\n\t0x1440, 0x1447, 0x1449, 0x144b, 0x144d, 0x1450, 0x1452, 0x1454,\n\t0x1456, 0x1458, 0x145a, 0x1460, 0x1466, 0x1469, 0x146c, 0x146f,\n\t0x1472, 0x1475, 0x1478, 0x147b, 0x147e, 0x1481, 0x1484, 0x1487,\n\t0x148a, 0x148d, 0x1490, 0x1493, 0x1496, 0x1499, 0x149c, 0x149f,\n\t0x14a2, 0x14a5, 0x14a8, 0x14ab, 0x14ae, 0x14b1, 0x14b4, 0x14b7,\n\t// Entry 500 - 53F\n\t0x14ba, 0x14bd, 0x14c0, 0x14c3, 0x14c6, 0x14c9, 0x14cc, 0x14cf,\n\t0x14d2, 0x14d5, 0x14d8, 0x14db, 0x14de, 0x14e1, 0x14e4, 0x14e7,\n\t0x14ea, 0x14ed, 0x14f6, 0x14ff, 0x1508, 0x1511, 0x151a, 0x1523,\n\t0x152c, 0x1535, 0x153e, 0x1541, 0x1544, 0x1547, 0x154a, 0x154d,\n\t0x1550, 0x1553, 0x1556, 0x1559, 0x155c, 0x155f, 0x1562, 0x1565,\n\t0x1568, 0x156b, 0x156e, 0x1571, 0x1574, 0x1577, 0x157a, 0x157d,\n\t0x1580, 0x1583, 0x1586, 0x1589, 0x158c, 0x158f, 0x1592, 0x1595,\n\t0x1598, 0x159b, 0x159e, 0x15a1, 0x15a4, 0x15a7, 0x15aa, 0x15ad,\n\t// Entry 540 - 57F\n\t0x15b0, 0x15b3, 0x15b6, 0x15b9, 0x15bc, 0x15bf, 0x15c2, 0x15c5,\n\t0x15c8, 0x15cb, 0x15ce, 0x15d1, 0x15d4, 0x15d7, 0x15da, 0x15dd,\n\t0x15e0, 0x15e3, 0x15e6, 0x15e9, 0x15ec, 0x15ef, 0x15f2, 0x15f5,\n\t0x15f8, 0x15fb, 0x15fe, 0x1601, 0x1604, 0x1607, 0x160a, 0x160d,\n\t0x1610, 0x1613, 0x1616, 0x1619, 0x161c, 0x161f, 0x1622, 0x1625,\n\t0x1628, 0x162b, 0x162e, 0x1631, 0x1634, 0x1637, 0x163a, 0x163d,\n\t0x1640, 0x1643, 0x1646, 0x1649, 0x164c, 0x164f, 0x1652, 0x1655,\n\t0x1658, 0x165b, 0x165e, 0x1661, 0x1664, 0x1667, 0x166a, 0x166d,\n\t// Entry 580 - 5BF\n\t0x1670, 0x1673, 0x1676, 0x1679, 0x167c, 0x167f, 0x1682, 0x1685,\n\t0x1688, 0x168b, 0x168e, 0x1691, 0x1694, 0x1697, 0x169a, 0x169d,\n\t0x16a0, 0x16a3, 0x16a6, 0x16a9, 0x16ac, 0x16af, 0x16b2, 0x16b5,\n\t0x16b8, 0x16bb, 0x16be, 0x16c1, 0x16c4, 0x16c7, 0x16ca, 0x16cd,\n\t0x16d0, 0x16d3, 0x16d6, 0x16d9, 0x16dc, 0x16df, 0x16e2, 0x16e5,\n\t0x16e8, 0x16eb, 0x16ee, 0x16f1, 0x16f4, 0x16f7, 0x16fa, 0x16fd,\n\t0x1700, 0x1703, 0x1706, 0x1709, 0x170c, 0x170f, 0x1712, 0x1715,\n\t0x1718, 0x171b, 0x171e, 0x1721, 0x1724, 0x1727, 0x172a, 0x172d,\n\t// Entry 5C0 - 5FF\n\t0x1730, 0x1733, 0x1736, 0x1739, 0x173c, 0x173f, 0x1742, 0x1745,\n\t0x1748, 0x174b, 0x174e, 0x1751, 0x1754, 0x1757, 0x175a, 0x175d,\n\t0x1760, 0x1763, 0x1766, 0x1769, 0x176c, 0x176f, 0x1772, 0x1775,\n\t0x1778, 0x177b, 0x177e, 0x1781, 0x1784, 0x1787, 0x178a, 0x178d,\n\t0x1790, 0x1793, 0x1796, 0x1799, 0x179c, 0x179f, 0x17a2, 0x17a5,\n\t0x17a8, 0x17ab, 0x17ae, 0x17b1, 0x17b4, 0x17b7, 0x17ba, 0x17bd,\n\t0x17c0, 0x17c3, 0x17c6, 0x17c9, 0x17cc, 0x17cf, 0x17d2, 0x17d5,\n\t0x17d8, 0x17db, 0x17de, 0x17e1, 0x17e4, 0x17e7, 0x17ea, 0x17ed,\n\t// Entry 600 - 63F\n\t0x17f0, 0x17f3, 0x17f6, 0x17f9, 0x17fc, 0x17ff, 0x1802, 0x1805,\n\t0x1808, 0x180b, 0x180e, 0x1811, 0x1814, 0x1817, 0x181a, 0x181d,\n\t0x1820, 0x1823, 0x1826, 0x1829, 0x182c, 0x182f, 0x1832, 0x1835,\n\t0x1838, 0x183b, 0x183e, 0x1841, 0x1844, 0x1847, 0x184a, 0x184d,\n\t0x1850, 0x1853, 0x1856, 0x1859, 0x185c, 0x185f, 0x1862, 0x1865,\n\t0x1868, 0x186b, 0x186e, 0x1871, 0x1874, 0x1877, 0x187a, 0x187d,\n\t0x1880, 0x1883, 0x1886, 0x1889, 0x188c, 0x188f, 0x1892, 0x1895,\n\t0x1898, 0x189b, 0x189e, 0x18a1, 0x18a4, 0x18a7, 0x18aa, 0x18ad,\n\t// Entry 640 - 67F\n\t0x18b0, 0x18b3, 0x18b6, 0x18b9, 0x18bc, 0x18bf, 0x18c2, 0x18c5,\n\t0x18c8, 0x18cb, 0x18ce, 0x18d1, 0x18d4, 0x18d7, 0x18da, 0x18dd,\n\t0x18e0, 0x18e3, 0x18e6, 0x18e9, 0x18ec, 0x18ef, 0x18f2, 0x18f5,\n\t0x18f8, 0x18fb, 0x18fe, 0x1901, 0x1904, 0x1907, 0x190a, 0x190d,\n\t0x1910, 0x1913, 0x1916, 0x1919, 0x191c, 0x191f, 0x1922, 0x1925,\n\t0x1928, 0x192b, 0x192e, 0x1931, 0x1934, 0x1937, 0x193a, 0x193d,\n\t0x1940, 0x1943, 0x1946, 0x1949, 0x194c, 0x194f, 0x1952, 0x1955,\n\t0x1958, 0x195b, 0x195e, 0x1961, 0x1964, 0x1967, 0x196a, 0x196d,\n\t// Entry 680 - 6BF\n\t0x1970, 0x1973, 0x1976, 0x1979, 0x197c, 0x197f, 0x1982, 0x1985,\n\t0x1988, 0x198b, 0x198e, 0x1991, 0x1994, 0x1997, 0x199a, 0x199d,\n\t0x19a0, 0x19a3, 0x19a6, 0x19a9, 0x19ac, 0x19af, 0x19b2, 0x19b5,\n\t0x19b8, 0x19bb, 0x19be, 0x19c1, 0x19c4, 0x19c7, 0x19ca, 0x19cd,\n\t0x19d0, 0x19d3, 0x19d6, 0x19d9, 0x19dc, 0x19df, 0x19e2, 0x19e5,\n\t0x19e8, 0x19eb, 0x19ee, 0x19f1, 0x19f4, 0x19f7, 0x19fa, 0x19fd,\n\t0x1a00, 0x1a03, 0x1a06, 0x1a09, 0x1a0c, 0x1a0f, 0x1a12, 0x1a15,\n\t0x1a18, 0x1a1b, 0x1a1e, 0x1a21, 0x1a24, 0x1a27, 0x1a2a, 0x1a2d,\n\t// Entry 6C0 - 6FF\n\t0x1a30,\n} // Size: 3482 bytes\n\nvar xorData string = \"\" + // Size: 4907 bytes\n\t\"\\x02\\x0c\\x09\\x02\\xb0\\xec\\x02\\xad\\xd8\\x02\\xad\\xd9\\x02\\x06\\x07\\x02\\x0f\\x12\" +\n\t\"\\x02\\x0f\\x1f\\x02\\x0f\\x1d\\x02\\x01\\x13\\x02\\x0f\\x16\\x02\\x0f\\x0b\\x02\\x0f3\" +\n\t\"\\x02\\x0f7\\x02\\x0f?\\x02\\x0f/\\x02\\x0f*\\x02\\x0c&\\x02\\x0c*\\x02\\x0c;\\x02\\x0c9\" +\n\t\"\\x02\\x0c%\\x02\\xab\\xed\\x02\\xab\\xe2\\x02\\xab\\xe3\\x02\\xa9\\xe0\\x02\\xa9\\xe1\" +\n\t\"\\x02\\xa9\\xe6\\x02\\xa3\\xcb\\x02\\xa3\\xc8\\x02\\xa3\\xc9\\x02\\x01#\\x02\\x01\\x08\" +\n\t\"\\x02\\x0e>\\x02\\x0e'\\x02\\x0f\\x03\\x02\\x03\\x0d\\x02\\x03\\x09\\x02\\x03\\x17\\x02\" +\n\t\"\\x03\\x0e\\x02\\x02\\x03\\x02\\x011\\x02\\x01\\x00\\x02\\x01\\x10\\x02\\x03<\\x02\\x07\" +\n\t\"\\x0d\\x02\\x02\\x0c\\x02\\x0c0\\x02\\x01\\x03\\x02\\x01\\x01\\x02\\x01 \\x02\\x01\\x22\" +\n\t\"\\x02\\x01)\\x02\\x01\\x0a\\x02\\x01\\x0c\\x02\\x02\\x06\\x02\\x02\\x02\\x02\\x03\\x10\" +\n\t\"\\x03\\x037 \\x03\\x0b+\\x03\\x021\\x00\\x02\\x01\\x04\\x02\\x01\\x02\\x02\\x019\\x02\" +\n\t\"\\x03\\x1c\\x02\\x02$\\x03\\x80p$\\x02\\x03:\\x02\\x03\\x0a\\x03\\xc1r.\\x03\\xc1r,\\x03\" +\n\t\"\\xc1r\\x02\\x02\\x02:\\x02\\x02>\\x02\\x02,\\x02\\x02\\x10\\x02\\x02\\x00\\x03\\xc1s<\" +\n\t\"\\x03\\xc1s*\\x03\\xc2L$\\x03\\xc2L;\\x02\\x09)\\x02\\x0a\\x19\\x03\\x83\\xab\\xe3\\x03\" +\n\t\"\\x83\\xab\\xf2\\x03 4\\xe0\\x03\\x81\\xab\\xea\\x03\\x81\\xab\\xf3\\x03 4\\xef\\x03\\x96\" +\n\t\"\\xe1\\xcd\\x03\\x84\\xe5\\xc3\\x02\\x0d\\x11\\x03\\x8b\\xec\\xcb\\x03\\x94\\xec\\xcf\\x03\" +\n\t\"\\x9a\\xec\\xc2\\x03\\x8b\\xec\\xdb\\x03\\x94\\xec\\xdf\\x03\\x9a\\xec\\xd2\\x03\\x01\\x0c\" +\n\t\"!\\x03\\x01\\x0c#\\x03ʠ\\x9d\\x03ʣ\\x9c\\x03ʢ\\x9f\\x03ʥ\\x9e\\x03ʤ\\x91\\x03ʧ\\x90\\x03\" +\n\t\"ʦ\\x93\\x03ʩ\\x92\\x03ʨ\\x95\\x03\\xca\\xf3\\xb5\\x03\\xca\\xf0\\xb4\\x03\\xca\\xf1\\xb7\" +\n\t\"\\x03\\xca\\xf6\\xb6\\x03\\xca\\xf7\\x89\\x03\\xca\\xf4\\x88\\x03\\xca\\xf5\\x8b\\x03\\xca\" +\n\t\"\\xfa\\x8a\\x03\\xca\\xfb\\x8d\\x03\\xca\\xf8\\x8c\\x03\\xca\\xf9\\x8f\\x03\\xca\\xfe\\x8e\" +\n\t\"\\x03\\xca\\xff\\x81\\x03\\xca\\xfc\\x80\\x03\\xca\\xfd\\x83\\x03\\xca\\xe2\\x82\\x03\\xca\" +\n\t\"\\xe3\\x85\\x03\\xca\\xe0\\x84\\x03\\xca\\xe1\\x87\\x03\\xca\\xe6\\x86\\x03\\xca\\xe7\\x99\" +\n\t\"\\x03\\xca\\xe4\\x98\\x03\\xca\\xe5\\x9b\\x03\\xca\\xea\\x9a\\x03\\xca\\xeb\\x9d\\x03\\xca\" +\n\t\"\\xe8\\x9c\\x03ؓ\\x89\\x03ߔ\\x8b\\x02\\x010\\x03\\x03\\x04\\x1e\\x03\\x04\\x15\\x12\\x03\" +\n\t\"\\x0b\\x05,\\x03\\x06\\x04\\x00\\x03\\x06\\x04)\\x03\\x06\\x044\\x03\\x06\\x04<\\x03\\x06\" +\n\t\"\\x05\\x1d\\x03\\x06\\x06\\x00\\x03\\x06\\x06\\x0a\\x03\\x06\\x06'\\x03\\x06\\x062\\x03\" +\n\t\"\\x0786\\x03\\x079/\\x03\\x079 \\x03\\x07:\\x0e\\x03\\x07:\\x1b\\x03\\x07:%\\x03\\x07;/\" +\n\t\"\\x03\\x07;%\\x03\\x074\\x11\\x03\\x076\\x09\\x03\\x077*\\x03\\x070\\x01\\x03\\x070\\x0f\" +\n\t\"\\x03\\x070.\\x03\\x071\\x16\\x03\\x071\\x04\\x03\\x0710\\x03\\x072\\x18\\x03\\x072-\" +\n\t\"\\x03\\x073\\x14\\x03\\x073>\\x03\\x07'\\x09\\x03\\x07 \\x00\\x03\\x07\\x1f\\x0b\\x03\" +\n\t\"\\x07\\x18#\\x03\\x07\\x18(\\x03\\x07\\x186\\x03\\x07\\x18\\x03\\x03\\x07\\x19\\x16\\x03\" +\n\t\"\\x07\\x116\\x03\\x07\\x12'\\x03\\x07\\x13\\x10\\x03\\x07\\x0c&\\x03\\x07\\x0c\\x08\\x03\" +\n\t\"\\x07\\x0c\\x13\\x03\\x07\\x0d\\x02\\x03\\x07\\x0d\\x1c\\x03\\x07\\x0b5\\x03\\x07\\x0b\" +\n\t\"\\x0a\\x03\\x07\\x0b\\x01\\x03\\x07\\x0b\\x0f\\x03\\x07\\x05\\x00\\x03\\x07\\x05\\x09\\x03\" +\n\t\"\\x07\\x05\\x0b\\x03\\x07\\x07\\x01\\x03\\x07\\x07\\x08\\x03\\x07\\x00<\\x03\\x07\\x00+\" +\n\t\"\\x03\\x07\\x01)\\x03\\x07\\x01\\x1b\\x03\\x07\\x01\\x08\\x03\\x07\\x03?\\x03\\x0445\\x03\" +\n\t\"\\x044\\x08\\x03\\x0454\\x03\\x04)/\\x03\\x04)5\\x03\\x04+\\x05\\x03\\x04+\\x14\\x03\" +\n\t\"\\x04+ \\x03\\x04+<\\x03\\x04*&\\x03\\x04*\\x22\\x03\\x04&8\\x03\\x04!\\x01\\x03\\x04!\" +\n\t\"\\x22\\x03\\x04\\x11+\\x03\\x04\\x10.\\x03\\x04\\x104\\x03\\x04\\x13=\\x03\\x04\\x12\\x04\" +\n\t\"\\x03\\x04\\x12\\x0a\\x03\\x04\\x0d\\x1d\\x03\\x04\\x0d\\x07\\x03\\x04\\x0d \\x03\\x05<>\" +\n\t\"\\x03\\x055<\\x03\\x055!\\x03\\x055#\\x03\\x055&\\x03\\x054\\x1d\\x03\\x054\\x02\\x03\" +\n\t\"\\x054\\x07\\x03\\x0571\\x03\\x053\\x1a\\x03\\x053\\x16\\x03\\x05.<\\x03\\x05.\\x07\\x03\" +\n\t\"\\x05):\\x03\\x05)<\\x03\\x05)\\x0c\\x03\\x05)\\x15\\x03\\x05+-\\x03\\x05+5\\x03\\x05$\" +\n\t\"\\x1e\\x03\\x05$\\x14\\x03\\x05'\\x04\\x03\\x05'\\x14\\x03\\x05&\\x02\\x03\\x05\\x226\" +\n\t\"\\x03\\x05\\x22\\x0c\\x03\\x05\\x22\\x1c\\x03\\x05\\x19\\x0a\\x03\\x05\\x1b\\x09\\x03\\x05\" +\n\t\"\\x1b\\x0c\\x03\\x05\\x14\\x07\\x03\\x05\\x16?\\x03\\x05\\x16\\x0c\\x03\\x05\\x0c\\x05\" +\n\t\"\\x03\\x05\\x0e\\x0f\\x03\\x05\\x01\\x0e\\x03\\x05\\x00(\\x03\\x05\\x030\\x03\\x05\\x03\" +\n\t\"\\x06\\x03\\x0a==\\x03\\x0a=1\\x03\\x0a=,\\x03\\x0a=\\x0c\\x03\\x0a??\\x03\\x0a<\\x08\" +\n\t\"\\x03\\x0a9!\\x03\\x0a9)\\x03\\x0a97\\x03\\x0a99\\x03\\x0a6\\x0a\\x03\\x0a6\\x1c\\x03\" +\n\t\"\\x0a6\\x17\\x03\\x0a7'\\x03\\x0a78\\x03\\x0a73\\x03\\x0a'\\x01\\x03\\x0a'&\\x03\\x0a\" +\n\t\"\\x1f\\x0e\\x03\\x0a\\x1f\\x03\\x03\\x0a\\x1f3\\x03\\x0a\\x1b/\\x03\\x0a\\x18\\x19\\x03\" +\n\t\"\\x0a\\x19\\x01\\x03\\x0a\\x16\\x14\\x03\\x0a\\x0e\\x22\\x03\\x0a\\x0f\\x10\\x03\\x0a\\x0f\" +\n\t\"\\x02\\x03\\x0a\\x0f \\x03\\x0a\\x0c\\x04\\x03\\x0a\\x0b>\\x03\\x0a\\x0b+\\x03\\x0a\\x08/\" +\n\t\"\\x03\\x0a\\x046\\x03\\x0a\\x05\\x14\\x03\\x0a\\x00\\x04\\x03\\x0a\\x00\\x10\\x03\\x0a\" +\n\t\"\\x00\\x14\\x03\\x0b<3\\x03\\x0b;*\\x03\\x0b9\\x22\\x03\\x0b9)\\x03\\x0b97\\x03\\x0b+\" +\n\t\"\\x10\\x03\\x0b((\\x03\\x0b&5\\x03\\x0b$\\x1c\\x03\\x0b$\\x12\\x03\\x0b%\\x04\\x03\\x0b#\" +\n\t\"<\\x03\\x0b#0\\x03\\x0b#\\x0d\\x03\\x0b#\\x19\\x03\\x0b!:\\x03\\x0b!\\x1f\\x03\\x0b!\" +\n\t\"\\x00\\x03\\x0b\\x1e5\\x03\\x0b\\x1c\\x1d\\x03\\x0b\\x1d-\\x03\\x0b\\x1d(\\x03\\x0b\\x18.\" +\n\t\"\\x03\\x0b\\x18 \\x03\\x0b\\x18\\x16\\x03\\x0b\\x14\\x13\\x03\\x0b\\x15$\\x03\\x0b\\x15\" +\n\t\"\\x22\\x03\\x0b\\x12\\x1b\\x03\\x0b\\x12\\x10\\x03\\x0b\\x132\\x03\\x0b\\x13=\\x03\\x0b\" +\n\t\"\\x12\\x18\\x03\\x0b\\x0c&\\x03\\x0b\\x061\\x03\\x0b\\x06:\\x03\\x0b\\x05#\\x03\\x0b\\x05\" +\n\t\"<\\x03\\x0b\\x04\\x0b\\x03\\x0b\\x04\\x04\\x03\\x0b\\x04\\x1b\\x03\\x0b\\x042\\x03\\x0b\" +\n\t\"\\x041\\x03\\x0b\\x03\\x03\\x03\\x0b\\x03\\x1d\\x03\\x0b\\x03/\\x03\\x0b\\x03+\\x03\\x0b\" +\n\t\"\\x02\\x1b\\x03\\x0b\\x02\\x00\\x03\\x0b\\x01\\x1e\\x03\\x0b\\x01\\x08\\x03\\x0b\\x015\" +\n\t\"\\x03\\x06\\x0d9\\x03\\x06\\x0d=\\x03\\x06\\x0d?\\x03\\x02\\x001\\x03\\x02\\x003\\x03\" +\n\t\"\\x02\\x02\\x19\\x03\\x02\\x006\\x03\\x02\\x02\\x1b\\x03\\x02\\x004\\x03\\x02\\x00<\\x03\" +\n\t\"\\x02\\x02\\x0a\\x03\\x02\\x02\\x0e\\x03\\x02\\x01\\x1a\\x03\\x02\\x01\\x07\\x03\\x02\\x01\" +\n\t\"\\x05\\x03\\x02\\x01\\x0b\\x03\\x02\\x01%\\x03\\x02\\x01\\x0c\\x03\\x02\\x01\\x04\\x03\" +\n\t\"\\x02\\x01\\x1c\\x03\\x02\\x00.\\x03\\x02\\x002\\x03\\x02\\x00>\\x03\\x02\\x00\\x12\\x03\" +\n\t\"\\x02\\x00\\x16\\x03\\x02\\x011\\x03\\x02\\x013\\x03\\x02\\x02 \\x03\\x02\\x02%\\x03\\x02\" +\n\t\"\\x02$\\x03\\x02\\x028\\x03\\x02\\x02;\\x03\\x02\\x024\\x03\\x02\\x012\\x03\\x02\\x022\" +\n\t\"\\x03\\x02\\x02/\\x03\\x02\\x01,\\x03\\x02\\x01\\x13\\x03\\x02\\x01\\x16\\x03\\x02\\x01\" +\n\t\"\\x11\\x03\\x02\\x01\\x1e\\x03\\x02\\x01\\x15\\x03\\x02\\x01\\x17\\x03\\x02\\x01\\x0f\\x03\" +\n\t\"\\x02\\x01\\x08\\x03\\x02\\x00?\\x03\\x02\\x03\\x07\\x03\\x02\\x03\\x0d\\x03\\x02\\x03\" +\n\t\"\\x13\\x03\\x02\\x03\\x1d\\x03\\x02\\x03\\x1f\\x03\\x02\\x00\\x03\\x03\\x02\\x00\\x0d\\x03\" +\n\t\"\\x02\\x00\\x01\\x03\\x02\\x00\\x1b\\x03\\x02\\x00\\x19\\x03\\x02\\x00\\x18\\x03\\x02\\x00\" +\n\t\"\\x13\\x03\\x02\\x00/\\x03\\x07>\\x12\\x03\\x07<\\x1f\\x03\\x07>\\x1d\\x03\\x06\\x1d\\x0e\" +\n\t\"\\x03\\x07>\\x1c\\x03\\x07>:\\x03\\x07>\\x13\\x03\\x04\\x12+\\x03\\x07?\\x03\\x03\\x07>\" +\n\t\"\\x02\\x03\\x06\\x224\\x03\\x06\\x1a.\\x03\\x07<%\\x03\\x06\\x1c\\x0b\\x03\\x0609\\x03\" +\n\t\"\\x05\\x1f\\x01\\x03\\x04'\\x08\\x03\\x93\\xfd\\xf5\\x03\\x02\\x0d \\x03\\x02\\x0d#\\x03\" +\n\t\"\\x02\\x0d!\\x03\\x02\\x0d&\\x03\\x02\\x0d\\x22\\x03\\x02\\x0d/\\x03\\x02\\x0d,\\x03\\x02\" +\n\t\"\\x0d$\\x03\\x02\\x0d'\\x03\\x02\\x0d%\\x03\\x02\\x0d;\\x03\\x02\\x0d=\\x03\\x02\\x0d?\" +\n\t\"\\x03\\x099.\\x03\\x08\\x0b7\\x03\\x08\\x02\\x14\\x03\\x08\\x14\\x0d\\x03\\x08.:\\x03\" +\n\t\"\\x089'\\x03\\x0f\\x0b\\x18\\x03\\x0f\\x1c1\\x03\\x0f\\x17&\\x03\\x0f9\\x1f\\x03\\x0f0\" +\n\t\"\\x0c\\x03\\x0e\\x0a9\\x03\\x0e\\x056\\x03\\x0e\\x1c#\\x03\\x0f\\x13\\x0e\\x03\\x072\\x00\" +\n\t\"\\x03\\x070\\x0d\\x03\\x072\\x0b\\x03\\x06\\x11\\x18\\x03\\x070\\x10\\x03\\x06\\x0f(\\x03\" +\n\t\"\\x072\\x05\\x03\\x06\\x0f,\\x03\\x073\\x15\\x03\\x06\\x07\\x08\\x03\\x05\\x16\\x02\\x03\" +\n\t\"\\x04\\x0b \\x03\\x05:8\\x03\\x05\\x16%\\x03\\x0a\\x0d\\x1f\\x03\\x06\\x16\\x10\\x03\\x05\" +\n\t\"\\x1d5\\x03\\x05*;\\x03\\x05\\x16\\x1b\\x03\\x04.-\\x03\\x06\\x1a\\x19\\x03\\x04\\x03,\" +\n\t\"\\x03\\x0b87\\x03\\x04/\\x0a\\x03\\x06\\x00,\\x03\\x04-\\x01\\x03\\x04\\x1e-\\x03\\x06/(\" +\n\t\"\\x03\\x0a\\x0b5\\x03\\x06\\x0e7\\x03\\x06\\x07.\\x03\\x0597\\x03\\x0a*%\\x03\\x0760\" +\n\t\"\\x03\\x06\\x0c;\\x03\\x05'\\x00\\x03\\x072.\\x03\\x072\\x08\\x03\\x06=\\x01\\x03\\x06\" +\n\t\"\\x05\\x1b\\x03\\x06\\x06\\x12\\x03\\x06$=\\x03\\x06'\\x0d\\x03\\x04\\x11\\x0f\\x03\\x076\" +\n\t\",\\x03\\x06\\x07;\\x03\\x06.,\\x03\\x86\\xf9\\xea\\x03\\x8f\\xff\\xeb\\x02\\x092\\x02\" +\n\t\"\\x095\\x02\\x094\\x02\\x09;\\x02\\x09>\\x02\\x098\\x02\\x09*\\x02\\x09/\\x02\\x09,\\x02\" +\n\t\"\\x09%\\x02\\x09&\\x02\\x09#\\x02\\x09 \\x02\\x08!\\x02\\x08%\\x02\\x08$\\x02\\x08+\\x02\" +\n\t\"\\x08.\\x02\\x08*\\x02\\x08&\\x02\\x088\\x02\\x08>\\x02\\x084\\x02\\x086\\x02\\x080\\x02\" +\n\t\"\\x08\\x10\\x02\\x08\\x17\\x02\\x08\\x12\\x02\\x08\\x1d\\x02\\x08\\x1f\\x02\\x08\\x13\\x02\" +\n\t\"\\x08\\x15\\x02\\x08\\x14\\x02\\x08\\x0c\\x03\\x8b\\xfd\\xd0\\x03\\x81\\xec\\xc6\\x03\\x87\" +\n\t\"\\xe0\\x8a\\x03-2\\xe3\\x03\\x80\\xef\\xe4\\x03-2\\xea\\x03\\x88\\xe6\\xeb\\x03\\x8e\\xe6\" +\n\t\"\\xe8\\x03\\x84\\xe6\\xe9\\x03\\x97\\xe6\\xee\\x03-2\\xf9\\x03-2\\xf6\\x03\\x8e\\xe3\\xad\" +\n\t\"\\x03\\x80\\xe3\\x92\\x03\\x88\\xe3\\x90\\x03\\x8e\\xe3\\x90\\x03\\x80\\xe3\\x97\\x03\\x88\" +\n\t\"\\xe3\\x95\\x03\\x88\\xfe\\xcb\\x03\\x8e\\xfe\\xca\\x03\\x84\\xfe\\xcd\\x03\\x91\\xef\\xc9\" +\n\t\"\\x03-2\\xc1\\x03-2\\xc0\\x03-2\\xcb\\x03\\x88@\\x09\\x03\\x8e@\\x08\\x03\\x8f\\xe0\\xf5\" +\n\t\"\\x03\\x8e\\xe6\\xf9\\x03\\x8e\\xe0\\xfa\\x03\\x93\\xff\\xf4\\x03\\x84\\xee\\xd3\\x03\\x0b\" +\n\t\"(\\x04\\x023 \\x03\\x0b)\\x08\\x021;\\x02\\x01*\\x03\\x0b#\\x10\\x03\\x0b 0\\x03\\x0b!\" +\n\t\"\\x10\\x03\\x0b!0\\x03\\x07\\x15\\x08\\x03\\x09?5\\x03\\x07\\x1f\\x08\\x03\\x07\\x17\\x0b\" +\n\t\"\\x03\\x09\\x1f\\x15\\x03\\x0b\\x1c7\\x03\\x0a+#\\x03\\x06\\x1a\\x1b\\x03\\x06\\x1a\\x14\" +\n\t\"\\x03\\x0a\\x01\\x18\\x03\\x06#\\x1b\\x03\\x0a2\\x0c\\x03\\x0a\\x01\\x04\\x03\\x09#;\\x03\" +\n\t\"\\x08='\\x03\\x08\\x1a\\x0a\\x03\\x07</\\x03\\x07:+\\x03\\x07\\x07*\\x03\\x06&\\x1c\\x03\" +\n\t\"\\x09\\x0c\\x16\\x03\\x09\\x10\\x0e\\x03\\x08'\\x0f\\x03\\x08+\\x09\\x03\\x074%\\x03\\x06\" +\n\t\"!3\\x03\\x06\\x03+\\x03\\x0b\\x1e\\x19\\x03\\x0a))\\x03\\x09\\x08\\x19\\x03\\x08,\\x05\" +\n\t\"\\x03\\x07<2\\x03\\x06\\x1c>\\x03\\x0a\\x111\\x03\\x09\\x1b\\x09\\x03\\x073.\\x03\\x07\" +\n\t\"\\x01\\x00\\x03\\x09/,\\x03\\x07#>\\x03\\x07\\x048\\x03\\x0a\\x1f\\x22\\x03\\x098>\\x03\" +\n\t\"\\x09\\x11\\x00\\x03\\x08/\\x17\\x03\\x06'\\x22\\x03\\x0b\\x1a+\\x03\\x0a\\x22\\x19\\x03\" +\n\t\"\\x0a/1\\x03\\x0974\\x03\\x09\\x0f\\x22\\x03\\x08,\\x22\\x03\\x08?\\x14\\x03\\x07$5\\x03\" +\n\t\"\\x07<3\\x03\\x07=*\\x03\\x07\\x13\\x18\\x03\\x068\\x0a\\x03\\x06\\x09\\x16\\x03\\x06\" +\n\t\"\\x13\\x00\\x03\\x08\\x067\\x03\\x08\\x01\\x03\\x03\\x08\\x12\\x1d\\x03\\x07+7\\x03\\x06(\" +\n\t\";\\x03\\x06\\x1c?\\x03\\x07\\x0e\\x17\\x03\\x0a\\x06\\x1d\\x03\\x0a\\x19\\x07\\x03\\x08\" +\n\t\"\\x14$\\x03\\x07$;\\x03\\x08,$\\x03\\x08\\x06\\x0d\\x03\\x07\\x16\\x0a\\x03\\x06>>\\x03\" +\n\t\"\\x0a\\x06\\x12\\x03\\x0a\\x14)\\x03\\x09\\x0d\\x1f\\x03\\x09\\x12\\x17\\x03\\x09\\x19\" +\n\t\"\\x01\\x03\\x08\\x11 \\x03\\x08\\x1d'\\x03\\x06<\\x1a\\x03\\x0a.\\x00\\x03\\x07'\\x18\" +\n\t\"\\x03\\x0a\\x22\\x08\\x03\\x08\\x0d\\x0a\\x03\\x08\\x13)\\x03\\x07*)\\x03\\x06<,\\x03\" +\n\t\"\\x07\\x0b\\x1a\\x03\\x09.\\x14\\x03\\x09\\x0d\\x1e\\x03\\x07\\x0e#\\x03\\x0b\\x1d'\\x03\" +\n\t\"\\x0a\\x0a8\\x03\\x09%2\\x03\\x08+&\\x03\\x080\\x12\\x03\\x0a)4\\x03\\x08\\x06\\x1f\\x03\" +\n\t\"\\x0b\\x1b\\x1a\\x03\\x0a\\x1b\\x0f\\x03\\x0b\\x1d*\\x03\\x09\\x16$\\x03\\x090\\x11\\x03\" +\n\t\"\\x08\\x11\\x08\\x03\\x0a*(\\x03\\x0a\\x042\\x03\\x089,\\x03\\x074'\\x03\\x07\\x0f\\x05\" +\n\t\"\\x03\\x09\\x0b\\x0a\\x03\\x07\\x1b\\x01\\x03\\x09\\x17:\\x03\\x09.\\x0d\\x03\\x07.\\x11\" +\n\t\"\\x03\\x09+\\x15\\x03\\x080\\x13\\x03\\x0b\\x1f\\x19\\x03\\x0a \\x11\\x03\\x0a\\x220\\x03\" +\n\t\"\\x09\\x07;\\x03\\x08\\x16\\x1c\\x03\\x07,\\x13\\x03\\x07\\x0e/\\x03\\x06\\x221\\x03\\x0a\" +\n\t\".\\x0a\\x03\\x0a7\\x02\\x03\\x0a\\x032\\x03\\x0a\\x1d.\\x03\\x091\\x06\\x03\\x09\\x19:\" +\n\t\"\\x03\\x08\\x02/\\x03\\x060+\\x03\\x06\\x0f-\\x03\\x06\\x1c\\x1f\\x03\\x06\\x1d\\x07\\x03\" +\n\t\"\\x0a,\\x11\\x03\\x09=\\x0d\\x03\\x09\\x0b;\\x03\\x07\\x1b/\\x03\\x0a\\x1f:\\x03\\x09 \" +\n\t\"\\x1f\\x03\\x09.\\x10\\x03\\x094\\x0b\\x03\\x09\\x1a1\\x03\\x08#\\x1a\\x03\\x084\\x1d\" +\n\t\"\\x03\\x08\\x01\\x1f\\x03\\x08\\x11\\x22\\x03\\x07'8\\x03\\x07\\x1a>\\x03\\x0757\\x03\" +\n\t\"\\x06&9\\x03\\x06+\\x11\\x03\\x0a.\\x0b\\x03\\x0a,>\\x03\\x0a4#\\x03\\x08%\\x17\\x03\" +\n\t\"\\x07\\x05\\x22\\x03\\x07\\x0c\\x0b\\x03\\x0a\\x1d+\\x03\\x0a\\x19\\x16\\x03\\x09+\\x1f\" +\n\t\"\\x03\\x09\\x08\\x0b\\x03\\x08\\x16\\x18\\x03\\x08+\\x12\\x03\\x0b\\x1d\\x0c\\x03\\x0a=\" +\n\t\"\\x10\\x03\\x0a\\x09\\x0d\\x03\\x0a\\x10\\x11\\x03\\x09&0\\x03\\x08(\\x1f\\x03\\x087\\x07\" +\n\t\"\\x03\\x08\\x185\\x03\\x07'6\\x03\\x06.\\x05\\x03\\x06=\\x04\\x03\\x06;;\\x03\\x06\\x06,\" +\n\t\"\\x03\\x0b\\x18>\\x03\\x08\\x00\\x18\\x03\\x06 \\x03\\x03\\x06<\\x00\\x03\\x09%\\x18\\x03\" +\n\t\"\\x0b\\x1c<\\x03\\x0a%!\\x03\\x0a\\x09\\x12\\x03\\x0a\\x16\\x02\\x03\\x090'\\x03\\x09\" +\n\t\"\\x0e=\\x03\\x08 \\x0e\\x03\\x08>\\x03\\x03\\x074>\\x03\\x06&?\\x03\\x06\\x19\\x09\\x03\" +\n\t\"\\x06?(\\x03\\x0a-\\x0e\\x03\\x09:3\\x03\\x098:\\x03\\x09\\x12\\x0b\\x03\\x09\\x1d\\x17\" +\n\t\"\\x03\\x087\\x05\\x03\\x082\\x14\\x03\\x08\\x06%\\x03\\x08\\x13\\x1f\\x03\\x06\\x06\\x0e\" +\n\t\"\\x03\\x0a\\x22<\\x03\\x09/<\\x03\\x06>+\\x03\\x0a'?\\x03\\x0a\\x13\\x0c\\x03\\x09\\x10<\" +\n\t\"\\x03\\x07\\x1b=\\x03\\x0a\\x19\\x13\\x03\\x09\\x22\\x1d\\x03\\x09\\x07\\x0d\\x03\\x08)\" +\n\t\"\\x1c\\x03\\x06=\\x1a\\x03\\x0a/4\\x03\\x0a7\\x11\\x03\\x0a\\x16:\\x03\\x09?3\\x03\\x09:\" +\n\t\"/\\x03\\x09\\x05\\x0a\\x03\\x09\\x14\\x06\\x03\\x087\\x22\\x03\\x080\\x07\\x03\\x08\\x1a\" +\n\t\"\\x1f\\x03\\x07\\x04(\\x03\\x07\\x04\\x09\\x03\\x06 %\\x03\\x06<\\x08\\x03\\x0a+\\x14\" +\n\t\"\\x03\\x09\\x1d\\x16\\x03\\x0a70\\x03\\x08 >\\x03\\x0857\\x03\\x070\\x0a\\x03\\x06=\\x12\" +\n\t\"\\x03\\x06\\x16%\\x03\\x06\\x1d,\\x03\\x099#\\x03\\x09\\x10>\\x03\\x07 \\x1e\\x03\\x08\" +\n\t\"\\x0c<\\x03\\x08\\x0b\\x18\\x03\\x08\\x15+\\x03\\x08,:\\x03\\x08%\\x22\\x03\\x07\\x0a$\" +\n\t\"\\x03\\x0b\\x1c=\\x03\\x07+\\x08\\x03\\x0a/\\x05\\x03\\x0a \\x07\\x03\\x0a\\x12'\\x03\" +\n\t\"\\x09#\\x11\\x03\\x08\\x1b\\x15\\x03\\x0a\\x06\\x01\\x03\\x09\\x1c\\x1b\\x03\\x0922\\x03\" +\n\t\"\\x07\\x14<\\x03\\x07\\x09\\x04\\x03\\x061\\x04\\x03\\x07\\x0e\\x01\\x03\\x0a\\x13\\x18\" +\n\t\"\\x03\\x0a-\\x0c\\x03\\x0a?\\x0d\\x03\\x0a\\x09\\x0a\\x03\\x091&\\x03\\x0a/\\x0b\\x03\" +\n\t\"\\x08$<\\x03\\x083\\x1d\\x03\\x08\\x0c$\\x03\\x08\\x0d\\x07\\x03\\x08\\x0d?\\x03\\x08\" +\n\t\"\\x0e\\x14\\x03\\x065\\x0a\\x03\\x08\\x1a#\\x03\\x08\\x16#\\x03\\x0702\\x03\\x07\\x03\" +\n\t\"\\x1a\\x03\\x06(\\x1d\\x03\\x06+\\x1b\\x03\\x06\\x0b\\x05\\x03\\x06\\x0b\\x17\\x03\\x06\" +\n\t\"\\x0c\\x04\\x03\\x06\\x1e\\x19\\x03\\x06+0\\x03\\x062\\x18\\x03\\x0b\\x16\\x1e\\x03\\x0a+\" +\n\t\"\\x16\\x03\\x0a-?\\x03\\x0a#:\\x03\\x0a#\\x10\\x03\\x0a%$\\x03\\x0a>+\\x03\\x0a01\\x03\" +\n\t\"\\x0a1\\x10\\x03\\x0a\\x099\\x03\\x0a\\x0a\\x12\\x03\\x0a\\x19\\x1f\\x03\\x0a\\x19\\x12\" +\n\t\"\\x03\\x09*)\\x03\\x09-\\x16\\x03\\x09.1\\x03\\x09.2\\x03\\x09<\\x0e\\x03\\x09> \\x03\" +\n\t\"\\x093\\x12\\x03\\x09\\x0b\\x01\\x03\\x09\\x1c2\\x03\\x09\\x11\\x1c\\x03\\x09\\x15%\\x03\" +\n\t\"\\x08,&\\x03\\x08!\\x22\\x03\\x089(\\x03\\x08\\x0b\\x1a\\x03\\x08\\x0d2\\x03\\x08\\x0c\" +\n\t\"\\x04\\x03\\x08\\x0c\\x06\\x03\\x08\\x0c\\x1f\\x03\\x08\\x0c\\x0c\\x03\\x08\\x0f\\x1f\\x03\" +\n\t\"\\x08\\x0f\\x1d\\x03\\x08\\x00\\x14\\x03\\x08\\x03\\x14\\x03\\x08\\x06\\x16\\x03\\x08\\x1e\" +\n\t\"#\\x03\\x08\\x11\\x11\\x03\\x08\\x10\\x18\\x03\\x08\\x14(\\x03\\x07)\\x1e\\x03\\x07.1\" +\n\t\"\\x03\\x07 $\\x03\\x07 '\\x03\\x078\\x08\\x03\\x07\\x0d0\\x03\\x07\\x0f7\\x03\\x07\\x05#\" +\n\t\"\\x03\\x07\\x05\\x1a\\x03\\x07\\x1a7\\x03\\x07\\x1d-\\x03\\x07\\x17\\x10\\x03\\x06)\\x1f\" +\n\t\"\\x03\\x062\\x0b\\x03\\x066\\x16\\x03\\x06\\x09\\x11\\x03\\x09(\\x1e\\x03\\x07!5\\x03\" +\n\t\"\\x0b\\x11\\x16\\x03\\x0a/\\x04\\x03\\x0a,\\x1a\\x03\\x0b\\x173\\x03\\x0a,1\\x03\\x0a/5\" +\n\t\"\\x03\\x0a\\x221\\x03\\x0a\\x22\\x0d\\x03\\x0a?%\\x03\\x0a<,\\x03\\x0a?#\\x03\\x0a>\\x19\" +\n\t\"\\x03\\x0a\\x08&\\x03\\x0a\\x0b\\x0e\\x03\\x0a\\x0c:\\x03\\x0a\\x0c+\\x03\\x0a\\x03\\x22\" +\n\t\"\\x03\\x0a\\x06)\\x03\\x0a\\x11\\x10\\x03\\x0a\\x11\\x1a\\x03\\x0a\\x17-\\x03\\x0a\\x14(\" +\n\t\"\\x03\\x09)\\x1e\\x03\\x09/\\x09\\x03\\x09.\\x00\\x03\\x09,\\x07\\x03\\x09/*\\x03\\x09-9\" +\n\t\"\\x03\\x09\\x228\\x03\\x09%\\x09\\x03\\x09:\\x12\\x03\\x09;\\x1d\\x03\\x09?\\x06\\x03\" +\n\t\"\\x093%\\x03\\x096\\x05\\x03\\x096\\x08\\x03\\x097\\x02\\x03\\x09\\x07,\\x03\\x09\\x04,\" +\n\t\"\\x03\\x09\\x1f\\x16\\x03\\x09\\x11\\x03\\x03\\x09\\x11\\x12\\x03\\x09\\x168\\x03\\x08*\" +\n\t\"\\x05\\x03\\x08/2\\x03\\x084:\\x03\\x08\\x22+\\x03\\x08 0\\x03\\x08&\\x0a\\x03\\x08;\" +\n\t\"\\x10\\x03\\x08>$\\x03\\x08>\\x18\\x03\\x0829\\x03\\x082:\\x03\\x081,\\x03\\x081<\\x03\" +\n\t\"\\x081\\x1c\\x03\\x087#\\x03\\x087*\\x03\\x08\\x09'\\x03\\x08\\x00\\x1d\\x03\\x08\\x05-\" +\n\t\"\\x03\\x08\\x1f4\\x03\\x08\\x1d\\x04\\x03\\x08\\x16\\x0f\\x03\\x07*7\\x03\\x07'!\\x03\" +\n\t\"\\x07%\\x1b\\x03\\x077\\x0c\\x03\\x07\\x0c1\\x03\\x07\\x0c.\\x03\\x07\\x00\\x06\\x03\\x07\" +\n\t\"\\x01\\x02\\x03\\x07\\x010\\x03\\x07\\x06=\\x03\\x07\\x01\\x03\\x03\\x07\\x01\\x13\\x03\" +\n\t\"\\x07\\x06\\x06\\x03\\x07\\x05\\x0a\\x03\\x07\\x1f\\x09\\x03\\x07\\x17:\\x03\\x06*1\\x03\" +\n\t\"\\x06-\\x1d\\x03\\x06\\x223\\x03\\x062:\\x03\\x060$\\x03\\x066\\x1e\\x03\\x064\\x12\\x03\" +\n\t\"\\x0645\\x03\\x06\\x0b\\x00\\x03\\x06\\x0b7\\x03\\x06\\x07\\x1f\\x03\\x06\\x15\\x12\\x03\" +\n\t\"\\x0c\\x05\\x0f\\x03\\x0b+\\x0b\\x03\\x0b+-\\x03\\x06\\x16\\x1b\\x03\\x06\\x15\\x17\\x03\" +\n\t\"\\x89\\xca\\xea\\x03\\x89\\xca\\xe8\\x03\\x0c8\\x10\\x03\\x0c8\\x01\\x03\\x0c8\\x0f\\x03\" +\n\t\"\\x0d8%\\x03\\x0d8!\\x03\\x0c8-\\x03\\x0c8/\\x03\\x0c8+\\x03\\x0c87\\x03\\x0c85\\x03\" +\n\t\"\\x0c9\\x09\\x03\\x0c9\\x0d\\x03\\x0c9\\x0f\\x03\\x0c9\\x0b\\x03\\xcfu\\x0c\\x03\\xcfu\" +\n\t\"\\x0f\\x03\\xcfu\\x0e\\x03\\xcfu\\x09\\x03\\x0c9\\x10\\x03\\x0d9\\x0c\\x03\\xcf`;\\x03\" +\n\t\"\\xcf`>\\x03\\xcf`9\\x03\\xcf`8\\x03\\xcf`7\\x03\\xcf`*\\x03\\xcf`-\\x03\\xcf`,\\x03\" +\n\t\"\\x0d\\x1b\\x1a\\x03\\x0d\\x1b&\\x03\\x0c=.\\x03\\x0c=%\\x03\\x0c>\\x1e\\x03\\x0c>\\x14\" +\n\t\"\\x03\\x0c?\\x06\\x03\\x0c?\\x0b\\x03\\x0c?\\x0c\\x03\\x0c?\\x0d\\x03\\x0c?\\x02\\x03\" +\n\t\"\\x0c>\\x0f\\x03\\x0c>\\x08\\x03\\x0c>\\x09\\x03\\x0c>,\\x03\\x0c>\\x0c\\x03\\x0c?\\x13\" +\n\t\"\\x03\\x0c?\\x16\\x03\\x0c?\\x15\\x03\\x0c?\\x1c\\x03\\x0c?\\x1f\\x03\\x0c?\\x1d\\x03\" +\n\t\"\\x0c?\\x1a\\x03\\x0c?\\x17\\x03\\x0c?\\x08\\x03\\x0c?\\x09\\x03\\x0c?\\x0e\\x03\\x0c?\" +\n\t\"\\x04\\x03\\x0c?\\x05\\x03\\x0c<?\\x03\\x0c=\\x00\\x03\\x0c=\\x06\\x03\\x0c=\\x05\\x03\" +\n\t\"\\x0c=\\x0c\\x03\\x0c=\\x0f\\x03\\x0c=\\x0d\\x03\\x0c=\\x0b\\x03\\x0c=\\x07\\x03\\x0c=\" +\n\t\"\\x19\\x03\\x0c=\\x15\\x03\\x0c=\\x11\\x03\\x0c=1\\x03\\x0c=3\\x03\\x0c=0\\x03\\x0c=>\" +\n\t\"\\x03\\x0c=2\\x03\\x0c=6\\x03\\x0c<\\x07\\x03\\x0c<\\x05\\x03\\x0e:!\\x03\\x0e:#\\x03\" +\n\t\"\\x0e8\\x09\\x03\\x0e:&\\x03\\x0e8\\x0b\\x03\\x0e:$\\x03\\x0e:,\\x03\\x0e8\\x1a\\x03\" +\n\t\"\\x0e8\\x1e\\x03\\x0e:*\\x03\\x0e:7\\x03\\x0e:5\\x03\\x0e:;\\x03\\x0e:\\x15\\x03\\x0e:<\" +\n\t\"\\x03\\x0e:4\\x03\\x0e:'\\x03\\x0e:-\\x03\\x0e:%\\x03\\x0e:?\\x03\\x0e:=\\x03\\x0e:)\" +\n\t\"\\x03\\x0e:/\\x03\\xcfs'\\x03\\x0d=\\x0f\\x03\\x0d+*\\x03\\x0d99\\x03\\x0d9;\\x03\\x0d9\" +\n\t\"?\\x03\\x0d)\\x0d\\x03\\x0d(%\\x02\\x01\\x18\\x02\\x01(\\x02\\x03'\\x02\\x03)\\x02\\x03+\" +\n\t\"\\x02\\x03/\\x02\\x03\\x19\\x02\\x03\\x1b\\x02\\x03\\x1f\\x03\\x0d\\x22\\x18\\x03\\x0d\" +\n\t\"\\x22\\x1a\\x03\\x0d\\x22'\\x03\\x0d\\x22/\\x03\\x0d\\x223\\x03\\x0d\\x22$\\x02\\x01\\x1e\" +\n\t\"\\x03\\x0f$!\\x03\\x0f87\\x03\\x0f4\\x0e\\x03\\x0f5\\x1d\\x03\\x06'\\x03\\x03\\x0f\\x08\" +\n\t\"\\x18\\x03\\x0f\\x0d\\x1b\\x03\\x0e2=\\x03\\x0e;\\x08\\x03\\x0e:\\x0b\\x03\\x0e\\x06$\" +\n\t\"\\x03\\x0e\\x0d)\\x03\\x0e\\x16\\x1f\\x03\\x0e\\x16\\x1b\\x03\\x0d$\\x0a\\x03\\x05,\\x1d\" +\n\t\"\\x03\\x0d. \\x03\\x0d.#\\x03\\x0c(/\\x03\\x09%\\x02\\x03\\x0d90\\x03\\x0d\\x0e4\\x03\" +\n\t\"\\x0d\\x0d\\x0f\\x03\\x0c#\\x00\\x03\\x0c,\\x1e\\x03\\x0c2\\x0e\\x03\\x0c\\x01\\x17\\x03\" +\n\t\"\\x0c\\x09:\\x03\\x0e\\x173\\x03\\x0c\\x08\\x03\\x03\\x0c\\x11\\x07\\x03\\x0c\\x10\\x18\" +\n\t\"\\x03\\x0c\\x1f\\x1c\\x03\\x0c\\x19\\x0e\\x03\\x0c\\x1a\\x1f\\x03\\x0f0>\\x03\\x0b->\\x03\" +\n\t\"\\x0b<+\\x03\\x0b8\\x13\\x03\\x0b\\x043\\x03\\x0b\\x14\\x03\\x03\\x0b\\x16%\\x03\\x0d\" +\n\t\"\\x22&\\x03\\x0b\\x1a\\x1a\\x03\\x0b\\x1a\\x04\\x03\\x0a%9\\x03\\x0a&2\\x03\\x0a&0\\x03\" +\n\t\"\\x0a!\\x1a\\x03\\x0a!7\\x03\\x0a5\\x10\\x03\\x0a=4\\x03\\x0a?\\x0e\\x03\\x0a>\\x10\\x03\" +\n\t\"\\x0a\\x00 \\x03\\x0a\\x0f:\\x03\\x0a\\x0f9\\x03\\x0a\\x0b\\x0a\\x03\\x0a\\x17%\\x03\\x0a\" +\n\t\"\\x1b-\\x03\\x09-\\x1a\\x03\\x09,4\\x03\\x09.,\\x03\\x09)\\x09\\x03\\x096!\\x03\\x091\" +\n\t\"\\x1f\\x03\\x093\\x16\\x03\\x0c+\\x1f\\x03\\x098 \\x03\\x098=\\x03\\x0c(\\x1a\\x03\\x0c(\" +\n\t\"\\x16\\x03\\x09\\x0a+\\x03\\x09\\x16\\x12\\x03\\x09\\x13\\x0e\\x03\\x09\\x153\\x03\\x08)!\" +\n\t\"\\x03\\x09\\x1a\\x01\\x03\\x09\\x18\\x01\\x03\\x08%#\\x03\\x08>\\x22\\x03\\x08\\x05%\\x03\" +\n\t\"\\x08\\x02*\\x03\\x08\\x15;\\x03\\x08\\x1b7\\x03\\x0f\\x07\\x1d\\x03\\x0f\\x04\\x03\\x03\" +\n\t\"\\x070\\x0c\\x03\\x07;\\x0b\\x03\\x07\\x08\\x17\\x03\\x07\\x12\\x06\\x03\\x06/-\\x03\\x06\" +\n\t\"71\\x03\\x065+\\x03\\x06>7\\x03\\x06\\x049\\x03\\x05+\\x1e\\x03\\x05,\\x17\\x03\\x05 \" +\n\t\"\\x1d\\x03\\x05\\x22\\x05\\x03\\x050\\x1d\"\n\n// lookup returns the trie value for the first UTF-8 encoding in s and\n// the width in bytes of this encoding. The size will be 0 if s does not\n// hold enough bytes to complete the encoding. len(s) must be greater than 0.\nfunc (t *idnaTrie) lookup(s []byte) (v uint16, sz int) {\n\tc0 := s[0]\n\tswitch {\n\tcase c0 < 0x80: // is ASCII\n\t\treturn idnaValues[c0], 1\n\tcase c0 < 0xC2:\n\t\treturn 0, 1 // Illegal UTF-8: not a starter, not ASCII.\n\tcase c0 < 0xE0: // 2-byte UTF-8\n\t\tif len(s) < 2 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c1), 2\n\tcase c0 < 0xF0: // 3-byte UTF-8\n\t\tif len(s) < 3 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c2), 3\n\tcase c0 < 0xF8: // 4-byte UTF-8\n\t\tif len(s) < 4 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to = uint32(i)<<6 + uint32(c2)\n\t\ti = idnaIndex[o]\n\t\tc3 := s[3]\n\t\tif c3 < 0x80 || 0xC0 <= c3 {\n\t\t\treturn 0, 3 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c3), 4\n\t}\n\t// Illegal rune\n\treturn 0, 1\n}\n\n// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.\n// s must start with a full and valid UTF-8 encoded rune.\nfunc (t *idnaTrie) lookupUnsafe(s []byte) uint16 {\n\tc0 := s[0]\n\tif c0 < 0x80 { // is ASCII\n\t\treturn idnaValues[c0]\n\t}\n\ti := idnaIndex[c0]\n\tif c0 < 0xE0 { // 2-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[1])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[1])]\n\tif c0 < 0xF0 { // 3-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[2])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[2])]\n\tif c0 < 0xF8 { // 4-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[3])\n\t}\n\treturn 0\n}\n\n// lookupString returns the trie value for the first UTF-8 encoding in s and\n// the width in bytes of this encoding. The size will be 0 if s does not\n// hold enough bytes to complete the encoding. len(s) must be greater than 0.\nfunc (t *idnaTrie) lookupString(s string) (v uint16, sz int) {\n\tc0 := s[0]\n\tswitch {\n\tcase c0 < 0x80: // is ASCII\n\t\treturn idnaValues[c0], 1\n\tcase c0 < 0xC2:\n\t\treturn 0, 1 // Illegal UTF-8: not a starter, not ASCII.\n\tcase c0 < 0xE0: // 2-byte UTF-8\n\t\tif len(s) < 2 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c1), 2\n\tcase c0 < 0xF0: // 3-byte UTF-8\n\t\tif len(s) < 3 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c2), 3\n\tcase c0 < 0xF8: // 4-byte UTF-8\n\t\tif len(s) < 4 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to = uint32(i)<<6 + uint32(c2)\n\t\ti = idnaIndex[o]\n\t\tc3 := s[3]\n\t\tif c3 < 0x80 || 0xC0 <= c3 {\n\t\t\treturn 0, 3 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c3), 4\n\t}\n\t// Illegal rune\n\treturn 0, 1\n}\n\n// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.\n// s must start with a full and valid UTF-8 encoded rune.\nfunc (t *idnaTrie) lookupStringUnsafe(s string) uint16 {\n\tc0 := s[0]\n\tif c0 < 0x80 { // is ASCII\n\t\treturn idnaValues[c0]\n\t}\n\ti := idnaIndex[c0]\n\tif c0 < 0xE0 { // 2-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[1])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[1])]\n\tif c0 < 0xF0 { // 3-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[2])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[2])]\n\tif c0 < 0xF8 { // 4-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[3])\n\t}\n\treturn 0\n}\n\n// idnaTrie. Total size: 31598 bytes (30.86 KiB). Checksum: d3118eda0d6b5360.\ntype idnaTrie struct{}\n\nfunc newIdnaTrie(i int) *idnaTrie {\n\treturn &idnaTrie{}\n}\n\n// lookupValue determines the type of block n and looks up the value for b.\nfunc (t *idnaTrie) lookupValue(n uint32, b byte) uint16 {\n\tswitch {\n\tcase n < 133:\n\t\treturn uint16(idnaValues[n<<6+uint32(b)])\n\tdefault:\n\t\tn -= 133\n\t\treturn uint16(idnaSparse.lookup(n, b))\n\t}\n}\n\n// idnaValues: 135 blocks, 8640 entries, 17280 bytes\n// The third block is the zero block.\nvar idnaValues = [8640]uint16{\n\t// Block 0x0, offset 0x0\n\t0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080,\n\t0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080,\n\t0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080,\n\t0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080,\n\t0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080,\n\t0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080,\n\t0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080,\n\t0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080,\n\t0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008,\n\t0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080,\n\t0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080,\n\t// Block 0x1, offset 0x40\n\t0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105,\n\t0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105,\n\t0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105,\n\t0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105,\n\t0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080,\n\t0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008,\n\t0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008,\n\t0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008,\n\t0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008,\n\t0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080,\n\t0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080,\n\t// Block 0x2, offset 0x80\n\t// Block 0x3, offset 0xc0\n\t0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040,\n\t0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040,\n\t0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040,\n\t0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040,\n\t0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040,\n\t0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018,\n\t0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x0012, 0xe9: 0x0018,\n\t0xea: 0x0019, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x0022,\n\t0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0029, 0xf3: 0x0031, 0xf4: 0x003a, 0xf5: 0x0005,\n\t0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x0042, 0xf9: 0x0049, 0xfa: 0x0051, 0xfb: 0x0018,\n\t0xfc: 0x0059, 0xfd: 0x0061, 0xfe: 0x0069, 0xff: 0x0018,\n\t// Block 0x4, offset 0x100\n\t0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008,\n\t0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008,\n\t0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008,\n\t0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008,\n\t0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008,\n\t0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008,\n\t0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008,\n\t0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008,\n\t0x130: 0x0071, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008,\n\t0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d,\n\t0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0079,\n\t// Block 0x5, offset 0x140\n\t0x140: 0x0079, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d,\n\t0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x0081, 0x14a: 0xe00d, 0x14b: 0x0008,\n\t0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008,\n\t0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008,\n\t0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008,\n\t0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008,\n\t0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008,\n\t0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008,\n\t0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008,\n\t0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d,\n\t0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x0089,\n\t// Block 0x6, offset 0x180\n\t0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008,\n\t0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d,\n\t0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d,\n\t0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d,\n\t0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155,\n\t0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008,\n\t0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d,\n\t0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd,\n\t0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d,\n\t0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008,\n\t0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008,\n\t// Block 0x7, offset 0x1c0\n\t0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x0091, 0x1c5: 0x0091,\n\t0x1c6: 0x0091, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d,\n\t0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d,\n\t0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d,\n\t0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008,\n\t0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008,\n\t0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008,\n\t0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008,\n\t0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008,\n\t0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008,\n\t0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008,\n\t// Block 0x8, offset 0x200\n\t0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008,\n\t0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008,\n\t0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008,\n\t0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008,\n\t0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008,\n\t0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008,\n\t0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008,\n\t0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008,\n\t0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008,\n\t0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0099, 0x23b: 0xe03d,\n\t0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x00a1, 0x23f: 0x0008,\n\t// Block 0x9, offset 0x240\n\t0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018,\n\t0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008,\n\t0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008,\n\t0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018,\n\t0x258: 0x00d2, 0x259: 0x00da, 0x25a: 0x00e2, 0x25b: 0x00ea, 0x25c: 0x00f2, 0x25d: 0x00fa,\n\t0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0101, 0x262: 0x0089, 0x263: 0x0109,\n\t0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018,\n\t0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018,\n\t0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018,\n\t0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018,\n\t0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018,\n\t// Block 0xa, offset 0x280\n\t0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0111, 0x285: 0x040d,\n\t0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308,\n\t0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308,\n\t0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308,\n\t0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308,\n\t0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308,\n\t0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308,\n\t0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308,\n\t0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008,\n\t0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x011a, 0x2bb: 0x0008,\n\t0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x0122, 0x2bf: 0x043d,\n\t// Block 0xb, offset 0x2c0\n\t0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x003a, 0x2c5: 0x012a,\n\t0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040,\n\t0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105,\n\t0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105,\n\t0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105,\n\t0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d,\n\t0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d,\n\t0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008,\n\t0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008,\n\t0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008,\n\t0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008,\n\t// Block 0xc, offset 0x300\n\t0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008,\n\t0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008,\n\t0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd,\n\t0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008,\n\t0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008,\n\t0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008,\n\t0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008,\n\t0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008,\n\t0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd,\n\t0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008,\n\t0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d,\n\t// Block 0xd, offset 0x340\n\t0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008,\n\t0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008,\n\t0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008,\n\t0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008,\n\t0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008,\n\t0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008,\n\t0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008,\n\t0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008,\n\t0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008,\n\t0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008,\n\t0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008,\n\t// Block 0xe, offset 0x380\n\t0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308,\n\t0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008,\n\t0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008,\n\t0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008,\n\t0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008,\n\t0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008,\n\t0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008,\n\t0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008,\n\t0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008,\n\t0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008,\n\t0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008,\n\t// Block 0xf, offset 0x3c0\n\t0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d,\n\t0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d,\n\t0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008,\n\t0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008,\n\t0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008,\n\t0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008,\n\t0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008,\n\t0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008,\n\t0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008,\n\t0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008,\n\t0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008,\n\t// Block 0x10, offset 0x400\n\t0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008,\n\t0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008,\n\t0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008,\n\t0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008,\n\t0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008,\n\t0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008,\n\t0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008,\n\t0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008,\n\t0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5,\n\t0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5,\n\t0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5,\n\t// Block 0x11, offset 0x440\n\t0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840,\n\t0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818,\n\t0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308,\n\t0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308,\n\t0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0818,\n\t0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08,\n\t0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08,\n\t0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08,\n\t0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08,\n\t0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08,\n\t0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08,\n\t// Block 0x12, offset 0x480\n\t0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08,\n\t0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308,\n\t0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308,\n\t0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308,\n\t0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308,\n\t0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808,\n\t0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808,\n\t0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08,\n\t0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0139,\n\t0x4b6: 0x0141, 0x4b7: 0x0149, 0x4b8: 0x0151, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08,\n\t0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08,\n\t// Block 0x13, offset 0x4c0\n\t0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08,\n\t0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08,\n\t0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08,\n\t0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308,\n\t0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840,\n\t0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308,\n\t0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018,\n\t0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08,\n\t0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008,\n\t0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08,\n\t0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08,\n\t// Block 0x14, offset 0x500\n\t0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818,\n\t0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818,\n\t0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308,\n\t0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08,\n\t0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08,\n\t0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08,\n\t0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08,\n\t0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08,\n\t0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308,\n\t0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308,\n\t0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308,\n\t// Block 0x15, offset 0x540\n\t0x540: 0x0c08, 0x541: 0x0a08, 0x542: 0x0a08, 0x543: 0x0a08, 0x544: 0x0a08, 0x545: 0x0a08,\n\t0x546: 0x0c08, 0x547: 0x0c08, 0x548: 0x0a08, 0x549: 0x0c08, 0x54a: 0x0a08, 0x54b: 0x0a08,\n\t0x54c: 0x0a08, 0x54d: 0x0a08, 0x54e: 0x0a08, 0x54f: 0x0a08, 0x550: 0x0a08, 0x551: 0x0a08,\n\t0x552: 0x0a08, 0x553: 0x0a08, 0x554: 0x0c08, 0x555: 0x0a08, 0x556: 0x0c08, 0x557: 0x0c08,\n\t0x558: 0x0c08, 0x559: 0x3308, 0x55a: 0x3308, 0x55b: 0x3308, 0x55c: 0x0040, 0x55d: 0x0040,\n\t0x55e: 0x0818, 0x55f: 0x0040, 0x560: 0x0a08, 0x561: 0x0808, 0x562: 0x0a08, 0x563: 0x0a08,\n\t0x564: 0x0a08, 0x565: 0x0a08, 0x566: 0x0808, 0x567: 0x0c08, 0x568: 0x0a08, 0x569: 0x0c08,\n\t0x56a: 0x0c08, 0x56b: 0x0040, 0x56c: 0x0040, 0x56d: 0x0040, 0x56e: 0x0040, 0x56f: 0x0040,\n\t0x570: 0x0c08, 0x571: 0x0c08, 0x572: 0x0c08, 0x573: 0x0c08, 0x574: 0x0c08, 0x575: 0x0c08,\n\t0x576: 0x0c08, 0x577: 0x0c08, 0x578: 0x0c08, 0x579: 0x0c08, 0x57a: 0x0c08, 0x57b: 0x0c08,\n\t0x57c: 0x0c08, 0x57d: 0x0c08, 0x57e: 0x0c08, 0x57f: 0x0c08,\n\t// Block 0x16, offset 0x580\n\t0x580: 0x0c08, 0x581: 0x0c08, 0x582: 0x0c08, 0x583: 0x0808, 0x584: 0x0808, 0x585: 0x0808,\n\t0x586: 0x0a08, 0x587: 0x0808, 0x588: 0x0818, 0x589: 0x0a08, 0x58a: 0x0a08, 0x58b: 0x0a08,\n\t0x58c: 0x0a08, 0x58d: 0x0a08, 0x58e: 0x0c08, 0x58f: 0x0040, 0x590: 0x0840, 0x591: 0x0840,\n\t0x592: 0x0040, 0x593: 0x0040, 0x594: 0x0040, 0x595: 0x0040, 0x596: 0x0040, 0x597: 0x0040,\n\t0x598: 0x3308, 0x599: 0x3308, 0x59a: 0x3308, 0x59b: 0x3308, 0x59c: 0x3308, 0x59d: 0x3308,\n\t0x59e: 0x3308, 0x59f: 0x3308, 0x5a0: 0x0a08, 0x5a1: 0x0a08, 0x5a2: 0x0a08, 0x5a3: 0x0a08,\n\t0x5a4: 0x0a08, 0x5a5: 0x0a08, 0x5a6: 0x0a08, 0x5a7: 0x0a08, 0x5a8: 0x0a08, 0x5a9: 0x0a08,\n\t0x5aa: 0x0c08, 0x5ab: 0x0c08, 0x5ac: 0x0c08, 0x5ad: 0x0808, 0x5ae: 0x0c08, 0x5af: 0x0a08,\n\t0x5b0: 0x0a08, 0x5b1: 0x0c08, 0x5b2: 0x0c08, 0x5b3: 0x0a08, 0x5b4: 0x0a08, 0x5b5: 0x0a08,\n\t0x5b6: 0x0a08, 0x5b7: 0x0a08, 0x5b8: 0x0a08, 0x5b9: 0x0c08, 0x5ba: 0x0a08, 0x5bb: 0x0a08,\n\t0x5bc: 0x0a08, 0x5bd: 0x0a08, 0x5be: 0x0a08, 0x5bf: 0x0a08,\n\t// Block 0x17, offset 0x5c0\n\t0x5c0: 0x3008, 0x5c1: 0x3308, 0x5c2: 0x3308, 0x5c3: 0x3308, 0x5c4: 0x3308, 0x5c5: 0x3308,\n\t0x5c6: 0x3308, 0x5c7: 0x3308, 0x5c8: 0x3308, 0x5c9: 0x3008, 0x5ca: 0x3008, 0x5cb: 0x3008,\n\t0x5cc: 0x3008, 0x5cd: 0x3b08, 0x5ce: 0x3008, 0x5cf: 0x3008, 0x5d0: 0x0008, 0x5d1: 0x3308,\n\t0x5d2: 0x3308, 0x5d3: 0x3308, 0x5d4: 0x3308, 0x5d5: 0x3308, 0x5d6: 0x3308, 0x5d7: 0x3308,\n\t0x5d8: 0x0159, 0x5d9: 0x0161, 0x5da: 0x0169, 0x5db: 0x0171, 0x5dc: 0x0179, 0x5dd: 0x0181,\n\t0x5de: 0x0189, 0x5df: 0x0191, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x3308, 0x5e3: 0x3308,\n\t0x5e4: 0x0018, 0x5e5: 0x0018, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0008,\n\t0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008,\n\t0x5f0: 0x0018, 0x5f1: 0x0008, 0x5f2: 0x0008, 0x5f3: 0x0008, 0x5f4: 0x0008, 0x5f5: 0x0008,\n\t0x5f6: 0x0008, 0x5f7: 0x0008, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0008, 0x5fb: 0x0008,\n\t0x5fc: 0x0008, 0x5fd: 0x0008, 0x5fe: 0x0008, 0x5ff: 0x0008,\n\t// Block 0x18, offset 0x600\n\t0x600: 0x0008, 0x601: 0x3308, 0x602: 0x3008, 0x603: 0x3008, 0x604: 0x0040, 0x605: 0x0008,\n\t0x606: 0x0008, 0x607: 0x0008, 0x608: 0x0008, 0x609: 0x0008, 0x60a: 0x0008, 0x60b: 0x0008,\n\t0x60c: 0x0008, 0x60d: 0x0040, 0x60e: 0x0040, 0x60f: 0x0008, 0x610: 0x0008, 0x611: 0x0040,\n\t0x612: 0x0040, 0x613: 0x0008, 0x614: 0x0008, 0x615: 0x0008, 0x616: 0x0008, 0x617: 0x0008,\n\t0x618: 0x0008, 0x619: 0x0008, 0x61a: 0x0008, 0x61b: 0x0008, 0x61c: 0x0008, 0x61d: 0x0008,\n\t0x61e: 0x0008, 0x61f: 0x0008, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x0008, 0x623: 0x0008,\n\t0x624: 0x0008, 0x625: 0x0008, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0040,\n\t0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008,\n\t0x630: 0x0008, 0x631: 0x0040, 0x632: 0x0008, 0x633: 0x0040, 0x634: 0x0040, 0x635: 0x0040,\n\t0x636: 0x0008, 0x637: 0x0008, 0x638: 0x0008, 0x639: 0x0008, 0x63a: 0x0040, 0x63b: 0x0040,\n\t0x63c: 0x3308, 0x63d: 0x0008, 0x63e: 0x3008, 0x63f: 0x3008,\n\t// Block 0x19, offset 0x640\n\t0x640: 0x3008, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x3308, 0x644: 0x3308, 0x645: 0x0040,\n\t0x646: 0x0040, 0x647: 0x3008, 0x648: 0x3008, 0x649: 0x0040, 0x64a: 0x0040, 0x64b: 0x3008,\n\t0x64c: 0x3008, 0x64d: 0x3b08, 0x64e: 0x0008, 0x64f: 0x0040, 0x650: 0x0040, 0x651: 0x0040,\n\t0x652: 0x0040, 0x653: 0x0040, 0x654: 0x0040, 0x655: 0x0040, 0x656: 0x0040, 0x657: 0x3008,\n\t0x658: 0x0040, 0x659: 0x0040, 0x65a: 0x0040, 0x65b: 0x0040, 0x65c: 0x0199, 0x65d: 0x01a1,\n\t0x65e: 0x0040, 0x65f: 0x01a9, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x3308, 0x663: 0x3308,\n\t0x664: 0x0040, 0x665: 0x0040, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0008,\n\t0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008,\n\t0x670: 0x0008, 0x671: 0x0008, 0x672: 0x0018, 0x673: 0x0018, 0x674: 0x0018, 0x675: 0x0018,\n\t0x676: 0x0018, 0x677: 0x0018, 0x678: 0x0018, 0x679: 0x0018, 0x67a: 0x0018, 0x67b: 0x0018,\n\t0x67c: 0x0008, 0x67d: 0x0018, 0x67e: 0x3308, 0x67f: 0x0040,\n\t// Block 0x1a, offset 0x680\n\t0x680: 0x0040, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x3008, 0x684: 0x0040, 0x685: 0x0008,\n\t0x686: 0x0008, 0x687: 0x0008, 0x688: 0x0008, 0x689: 0x0008, 0x68a: 0x0008, 0x68b: 0x0040,\n\t0x68c: 0x0040, 0x68d: 0x0040, 0x68e: 0x0040, 0x68f: 0x0008, 0x690: 0x0008, 0x691: 0x0040,\n\t0x692: 0x0040, 0x693: 0x0008, 0x694: 0x0008, 0x695: 0x0008, 0x696: 0x0008, 0x697: 0x0008,\n\t0x698: 0x0008, 0x699: 0x0008, 0x69a: 0x0008, 0x69b: 0x0008, 0x69c: 0x0008, 0x69d: 0x0008,\n\t0x69e: 0x0008, 0x69f: 0x0008, 0x6a0: 0x0008, 0x6a1: 0x0008, 0x6a2: 0x0008, 0x6a3: 0x0008,\n\t0x6a4: 0x0008, 0x6a5: 0x0008, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0040,\n\t0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008,\n\t0x6b0: 0x0008, 0x6b1: 0x0040, 0x6b2: 0x0008, 0x6b3: 0x01b1, 0x6b4: 0x0040, 0x6b5: 0x0008,\n\t0x6b6: 0x01b9, 0x6b7: 0x0040, 0x6b8: 0x0008, 0x6b9: 0x0008, 0x6ba: 0x0040, 0x6bb: 0x0040,\n\t0x6bc: 0x3308, 0x6bd: 0x0040, 0x6be: 0x3008, 0x6bf: 0x3008,\n\t// Block 0x1b, offset 0x6c0\n\t0x6c0: 0x3008, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x0040, 0x6c4: 0x0040, 0x6c5: 0x0040,\n\t0x6c6: 0x0040, 0x6c7: 0x3308, 0x6c8: 0x3308, 0x6c9: 0x0040, 0x6ca: 0x0040, 0x6cb: 0x3308,\n\t0x6cc: 0x3308, 0x6cd: 0x3b08, 0x6ce: 0x0040, 0x6cf: 0x0040, 0x6d0: 0x0040, 0x6d1: 0x3308,\n\t0x6d2: 0x0040, 0x6d3: 0x0040, 0x6d4: 0x0040, 0x6d5: 0x0040, 0x6d6: 0x0040, 0x6d7: 0x0040,\n\t0x6d8: 0x0040, 0x6d9: 0x01c1, 0x6da: 0x01c9, 0x6db: 0x01d1, 0x6dc: 0x0008, 0x6dd: 0x0040,\n\t0x6de: 0x01d9, 0x6df: 0x0040, 0x6e0: 0x0040, 0x6e1: 0x0040, 0x6e2: 0x0040, 0x6e3: 0x0040,\n\t0x6e4: 0x0040, 0x6e5: 0x0040, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0008,\n\t0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008,\n\t0x6f0: 0x3308, 0x6f1: 0x3308, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0008, 0x6f5: 0x3308,\n\t0x6f6: 0x0018, 0x6f7: 0x0040, 0x6f8: 0x0040, 0x6f9: 0x0040, 0x6fa: 0x0040, 0x6fb: 0x0040,\n\t0x6fc: 0x0040, 0x6fd: 0x0040, 0x6fe: 0x0040, 0x6ff: 0x0040,\n\t// Block 0x1c, offset 0x700\n\t0x700: 0x0040, 0x701: 0x3308, 0x702: 0x3308, 0x703: 0x3008, 0x704: 0x0040, 0x705: 0x0008,\n\t0x706: 0x0008, 0x707: 0x0008, 0x708: 0x0008, 0x709: 0x0008, 0x70a: 0x0008, 0x70b: 0x0008,\n\t0x70c: 0x0008, 0x70d: 0x0008, 0x70e: 0x0040, 0x70f: 0x0008, 0x710: 0x0008, 0x711: 0x0008,\n\t0x712: 0x0040, 0x713: 0x0008, 0x714: 0x0008, 0x715: 0x0008, 0x716: 0x0008, 0x717: 0x0008,\n\t0x718: 0x0008, 0x719: 0x0008, 0x71a: 0x0008, 0x71b: 0x0008, 0x71c: 0x0008, 0x71d: 0x0008,\n\t0x71e: 0x0008, 0x71f: 0x0008, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x0008, 0x723: 0x0008,\n\t0x724: 0x0008, 0x725: 0x0008, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0040,\n\t0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008,\n\t0x730: 0x0008, 0x731: 0x0040, 0x732: 0x0008, 0x733: 0x0008, 0x734: 0x0040, 0x735: 0x0008,\n\t0x736: 0x0008, 0x737: 0x0008, 0x738: 0x0008, 0x739: 0x0008, 0x73a: 0x0040, 0x73b: 0x0040,\n\t0x73c: 0x3308, 0x73d: 0x0008, 0x73e: 0x3008, 0x73f: 0x3008,\n\t// Block 0x1d, offset 0x740\n\t0x740: 0x3008, 0x741: 0x3308, 0x742: 0x3308, 0x743: 0x3308, 0x744: 0x3308, 0x745: 0x3308,\n\t0x746: 0x0040, 0x747: 0x3308, 0x748: 0x3308, 0x749: 0x3008, 0x74a: 0x0040, 0x74b: 0x3008,\n\t0x74c: 0x3008, 0x74d: 0x3b08, 0x74e: 0x0040, 0x74f: 0x0040, 0x750: 0x0008, 0x751: 0x0040,\n\t0x752: 0x0040, 0x753: 0x0040, 0x754: 0x0040, 0x755: 0x0040, 0x756: 0x0040, 0x757: 0x0040,\n\t0x758: 0x0040, 0x759: 0x0040, 0x75a: 0x0040, 0x75b: 0x0040, 0x75c: 0x0040, 0x75d: 0x0040,\n\t0x75e: 0x0040, 0x75f: 0x0040, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x3308, 0x763: 0x3308,\n\t0x764: 0x0040, 0x765: 0x0040, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0008,\n\t0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008,\n\t0x770: 0x0018, 0x771: 0x0018, 0x772: 0x0040, 0x773: 0x0040, 0x774: 0x0040, 0x775: 0x0040,\n\t0x776: 0x0040, 0x777: 0x0040, 0x778: 0x0040, 0x779: 0x0008, 0x77a: 0x3308, 0x77b: 0x3308,\n\t0x77c: 0x3308, 0x77d: 0x3308, 0x77e: 0x3308, 0x77f: 0x3308,\n\t// Block 0x1e, offset 0x780\n\t0x780: 0x0040, 0x781: 0x3308, 0x782: 0x3008, 0x783: 0x3008, 0x784: 0x0040, 0x785: 0x0008,\n\t0x786: 0x0008, 0x787: 0x0008, 0x788: 0x0008, 0x789: 0x0008, 0x78a: 0x0008, 0x78b: 0x0008,\n\t0x78c: 0x0008, 0x78d: 0x0040, 0x78e: 0x0040, 0x78f: 0x0008, 0x790: 0x0008, 0x791: 0x0040,\n\t0x792: 0x0040, 0x793: 0x0008, 0x794: 0x0008, 0x795: 0x0008, 0x796: 0x0008, 0x797: 0x0008,\n\t0x798: 0x0008, 0x799: 0x0008, 0x79a: 0x0008, 0x79b: 0x0008, 0x79c: 0x0008, 0x79d: 0x0008,\n\t0x79e: 0x0008, 0x79f: 0x0008, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x0008, 0x7a3: 0x0008,\n\t0x7a4: 0x0008, 0x7a5: 0x0008, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0040,\n\t0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008,\n\t0x7b0: 0x0008, 0x7b1: 0x0040, 0x7b2: 0x0008, 0x7b3: 0x0008, 0x7b4: 0x0040, 0x7b5: 0x0008,\n\t0x7b6: 0x0008, 0x7b7: 0x0008, 0x7b8: 0x0008, 0x7b9: 0x0008, 0x7ba: 0x0040, 0x7bb: 0x0040,\n\t0x7bc: 0x3308, 0x7bd: 0x0008, 0x7be: 0x3008, 0x7bf: 0x3308,\n\t// Block 0x1f, offset 0x7c0\n\t0x7c0: 0x3008, 0x7c1: 0x3308, 0x7c2: 0x3308, 0x7c3: 0x3308, 0x7c4: 0x3308, 0x7c5: 0x0040,\n\t0x7c6: 0x0040, 0x7c7: 0x3008, 0x7c8: 0x3008, 0x7c9: 0x0040, 0x7ca: 0x0040, 0x7cb: 0x3008,\n\t0x7cc: 0x3008, 0x7cd: 0x3b08, 0x7ce: 0x0040, 0x7cf: 0x0040, 0x7d0: 0x0040, 0x7d1: 0x0040,\n\t0x7d2: 0x0040, 0x7d3: 0x0040, 0x7d4: 0x0040, 0x7d5: 0x3308, 0x7d6: 0x3308, 0x7d7: 0x3008,\n\t0x7d8: 0x0040, 0x7d9: 0x0040, 0x7da: 0x0040, 0x7db: 0x0040, 0x7dc: 0x01e1, 0x7dd: 0x01e9,\n\t0x7de: 0x0040, 0x7df: 0x0008, 0x7e0: 0x0008, 0x7e1: 0x0008, 0x7e2: 0x3308, 0x7e3: 0x3308,\n\t0x7e4: 0x0040, 0x7e5: 0x0040, 0x7e6: 0x0008, 0x7e7: 0x0008, 0x7e8: 0x0008, 0x7e9: 0x0008,\n\t0x7ea: 0x0008, 0x7eb: 0x0008, 0x7ec: 0x0008, 0x7ed: 0x0008, 0x7ee: 0x0008, 0x7ef: 0x0008,\n\t0x7f0: 0x0018, 0x7f1: 0x0008, 0x7f2: 0x0018, 0x7f3: 0x0018, 0x7f4: 0x0018, 0x7f5: 0x0018,\n\t0x7f6: 0x0018, 0x7f7: 0x0018, 0x7f8: 0x0040, 0x7f9: 0x0040, 0x7fa: 0x0040, 0x7fb: 0x0040,\n\t0x7fc: 0x0040, 0x7fd: 0x0040, 0x7fe: 0x0040, 0x7ff: 0x0040,\n\t// Block 0x20, offset 0x800\n\t0x800: 0x0040, 0x801: 0x0040, 0x802: 0x3308, 0x803: 0x0008, 0x804: 0x0040, 0x805: 0x0008,\n\t0x806: 0x0008, 0x807: 0x0008, 0x808: 0x0008, 0x809: 0x0008, 0x80a: 0x0008, 0x80b: 0x0040,\n\t0x80c: 0x0040, 0x80d: 0x0040, 0x80e: 0x0008, 0x80f: 0x0008, 0x810: 0x0008, 0x811: 0x0040,\n\t0x812: 0x0008, 0x813: 0x0008, 0x814: 0x0008, 0x815: 0x0008, 0x816: 0x0040, 0x817: 0x0040,\n\t0x818: 0x0040, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0040, 0x81c: 0x0008, 0x81d: 0x0040,\n\t0x81e: 0x0008, 0x81f: 0x0008, 0x820: 0x0040, 0x821: 0x0040, 0x822: 0x0040, 0x823: 0x0008,\n\t0x824: 0x0008, 0x825: 0x0040, 0x826: 0x0040, 0x827: 0x0040, 0x828: 0x0008, 0x829: 0x0008,\n\t0x82a: 0x0008, 0x82b: 0x0040, 0x82c: 0x0040, 0x82d: 0x0040, 0x82e: 0x0008, 0x82f: 0x0008,\n\t0x830: 0x0008, 0x831: 0x0008, 0x832: 0x0008, 0x833: 0x0008, 0x834: 0x0008, 0x835: 0x0008,\n\t0x836: 0x0008, 0x837: 0x0008, 0x838: 0x0008, 0x839: 0x0008, 0x83a: 0x0040, 0x83b: 0x0040,\n\t0x83c: 0x0040, 0x83d: 0x0040, 0x83e: 0x3008, 0x83f: 0x3008,\n\t// Block 0x21, offset 0x840\n\t0x840: 0x3308, 0x841: 0x3008, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x3008, 0x845: 0x0040,\n\t0x846: 0x3308, 0x847: 0x3308, 0x848: 0x3308, 0x849: 0x0040, 0x84a: 0x3308, 0x84b: 0x3308,\n\t0x84c: 0x3308, 0x84d: 0x3b08, 0x84e: 0x0040, 0x84f: 0x0040, 0x850: 0x0040, 0x851: 0x0040,\n\t0x852: 0x0040, 0x853: 0x0040, 0x854: 0x0040, 0x855: 0x3308, 0x856: 0x3308, 0x857: 0x0040,\n\t0x858: 0x0008, 0x859: 0x0008, 0x85a: 0x0008, 0x85b: 0x0040, 0x85c: 0x0040, 0x85d: 0x0008,\n\t0x85e: 0x0040, 0x85f: 0x0040, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x3308, 0x863: 0x3308,\n\t0x864: 0x0040, 0x865: 0x0040, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0008,\n\t0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008,\n\t0x870: 0x0040, 0x871: 0x0040, 0x872: 0x0040, 0x873: 0x0040, 0x874: 0x0040, 0x875: 0x0040,\n\t0x876: 0x0040, 0x877: 0x0018, 0x878: 0x0018, 0x879: 0x0018, 0x87a: 0x0018, 0x87b: 0x0018,\n\t0x87c: 0x0018, 0x87d: 0x0018, 0x87e: 0x0018, 0x87f: 0x0018,\n\t// Block 0x22, offset 0x880\n\t0x880: 0x0008, 0x881: 0x3308, 0x882: 0x3008, 0x883: 0x3008, 0x884: 0x0018, 0x885: 0x0008,\n\t0x886: 0x0008, 0x887: 0x0008, 0x888: 0x0008, 0x889: 0x0008, 0x88a: 0x0008, 0x88b: 0x0008,\n\t0x88c: 0x0008, 0x88d: 0x0040, 0x88e: 0x0008, 0x88f: 0x0008, 0x890: 0x0008, 0x891: 0x0040,\n\t0x892: 0x0008, 0x893: 0x0008, 0x894: 0x0008, 0x895: 0x0008, 0x896: 0x0008, 0x897: 0x0008,\n\t0x898: 0x0008, 0x899: 0x0008, 0x89a: 0x0008, 0x89b: 0x0008, 0x89c: 0x0008, 0x89d: 0x0008,\n\t0x89e: 0x0008, 0x89f: 0x0008, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x0008, 0x8a3: 0x0008,\n\t0x8a4: 0x0008, 0x8a5: 0x0008, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0040,\n\t0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008,\n\t0x8b0: 0x0008, 0x8b1: 0x0008, 0x8b2: 0x0008, 0x8b3: 0x0008, 0x8b4: 0x0040, 0x8b5: 0x0008,\n\t0x8b6: 0x0008, 0x8b7: 0x0008, 0x8b8: 0x0008, 0x8b9: 0x0008, 0x8ba: 0x0040, 0x8bb: 0x0040,\n\t0x8bc: 0x3308, 0x8bd: 0x0008, 0x8be: 0x3008, 0x8bf: 0x3308,\n\t// Block 0x23, offset 0x8c0\n\t0x8c0: 0x3008, 0x8c1: 0x3008, 0x8c2: 0x3008, 0x8c3: 0x3008, 0x8c4: 0x3008, 0x8c5: 0x0040,\n\t0x8c6: 0x3308, 0x8c7: 0x3008, 0x8c8: 0x3008, 0x8c9: 0x0040, 0x8ca: 0x3008, 0x8cb: 0x3008,\n\t0x8cc: 0x3308, 0x8cd: 0x3b08, 0x8ce: 0x0040, 0x8cf: 0x0040, 0x8d0: 0x0040, 0x8d1: 0x0040,\n\t0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0040, 0x8d5: 0x3008, 0x8d6: 0x3008, 0x8d7: 0x0040,\n\t0x8d8: 0x0040, 0x8d9: 0x0040, 0x8da: 0x0040, 0x8db: 0x0040, 0x8dc: 0x0040, 0x8dd: 0x0008,\n\t0x8de: 0x0008, 0x8df: 0x0040, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x3308, 0x8e3: 0x3308,\n\t0x8e4: 0x0040, 0x8e5: 0x0040, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0008,\n\t0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008,\n\t0x8f0: 0x0040, 0x8f1: 0x0008, 0x8f2: 0x0008, 0x8f3: 0x3008, 0x8f4: 0x0040, 0x8f5: 0x0040,\n\t0x8f6: 0x0040, 0x8f7: 0x0040, 0x8f8: 0x0040, 0x8f9: 0x0040, 0x8fa: 0x0040, 0x8fb: 0x0040,\n\t0x8fc: 0x0040, 0x8fd: 0x0040, 0x8fe: 0x0040, 0x8ff: 0x0040,\n\t// Block 0x24, offset 0x900\n\t0x900: 0x3008, 0x901: 0x3308, 0x902: 0x3308, 0x903: 0x3308, 0x904: 0x3308, 0x905: 0x0040,\n\t0x906: 0x3008, 0x907: 0x3008, 0x908: 0x3008, 0x909: 0x0040, 0x90a: 0x3008, 0x90b: 0x3008,\n\t0x90c: 0x3008, 0x90d: 0x3b08, 0x90e: 0x0008, 0x90f: 0x0018, 0x910: 0x0040, 0x911: 0x0040,\n\t0x912: 0x0040, 0x913: 0x0040, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x3008,\n\t0x918: 0x0018, 0x919: 0x0018, 0x91a: 0x0018, 0x91b: 0x0018, 0x91c: 0x0018, 0x91d: 0x0018,\n\t0x91e: 0x0018, 0x91f: 0x0008, 0x920: 0x0008, 0x921: 0x0008, 0x922: 0x3308, 0x923: 0x3308,\n\t0x924: 0x0040, 0x925: 0x0040, 0x926: 0x0008, 0x927: 0x0008, 0x928: 0x0008, 0x929: 0x0008,\n\t0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0008, 0x92d: 0x0008, 0x92e: 0x0008, 0x92f: 0x0008,\n\t0x930: 0x0018, 0x931: 0x0018, 0x932: 0x0018, 0x933: 0x0018, 0x934: 0x0018, 0x935: 0x0018,\n\t0x936: 0x0018, 0x937: 0x0018, 0x938: 0x0018, 0x939: 0x0018, 0x93a: 0x0008, 0x93b: 0x0008,\n\t0x93c: 0x0008, 0x93d: 0x0008, 0x93e: 0x0008, 0x93f: 0x0008,\n\t// Block 0x25, offset 0x940\n\t0x940: 0x0040, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x0040, 0x944: 0x0008, 0x945: 0x0040,\n\t0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0008, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0040,\n\t0x94c: 0x0008, 0x94d: 0x0008, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008,\n\t0x952: 0x0008, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0008,\n\t0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0008, 0x95d: 0x0008,\n\t0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008,\n\t0x964: 0x0040, 0x965: 0x0008, 0x966: 0x0040, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0008,\n\t0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0008, 0x96d: 0x0008, 0x96e: 0x0008, 0x96f: 0x0008,\n\t0x970: 0x0008, 0x971: 0x3308, 0x972: 0x0008, 0x973: 0x01f9, 0x974: 0x3308, 0x975: 0x3308,\n\t0x976: 0x3308, 0x977: 0x3308, 0x978: 0x3308, 0x979: 0x3308, 0x97a: 0x3b08, 0x97b: 0x3308,\n\t0x97c: 0x3308, 0x97d: 0x0008, 0x97e: 0x0040, 0x97f: 0x0040,\n\t// Block 0x26, offset 0x980\n\t0x980: 0x0008, 0x981: 0x0008, 0x982: 0x0008, 0x983: 0x0211, 0x984: 0x0008, 0x985: 0x0008,\n\t0x986: 0x0008, 0x987: 0x0008, 0x988: 0x0040, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008,\n\t0x98c: 0x0008, 0x98d: 0x0219, 0x98e: 0x0008, 0x98f: 0x0008, 0x990: 0x0008, 0x991: 0x0008,\n\t0x992: 0x0221, 0x993: 0x0008, 0x994: 0x0008, 0x995: 0x0008, 0x996: 0x0008, 0x997: 0x0229,\n\t0x998: 0x0008, 0x999: 0x0008, 0x99a: 0x0008, 0x99b: 0x0008, 0x99c: 0x0231, 0x99d: 0x0008,\n\t0x99e: 0x0008, 0x99f: 0x0008, 0x9a0: 0x0008, 0x9a1: 0x0008, 0x9a2: 0x0008, 0x9a3: 0x0008,\n\t0x9a4: 0x0008, 0x9a5: 0x0008, 0x9a6: 0x0008, 0x9a7: 0x0008, 0x9a8: 0x0008, 0x9a9: 0x0239,\n\t0x9aa: 0x0008, 0x9ab: 0x0008, 0x9ac: 0x0008, 0x9ad: 0x0040, 0x9ae: 0x0040, 0x9af: 0x0040,\n\t0x9b0: 0x0040, 0x9b1: 0x3308, 0x9b2: 0x3308, 0x9b3: 0x0241, 0x9b4: 0x3308, 0x9b5: 0x0249,\n\t0x9b6: 0x0251, 0x9b7: 0x0259, 0x9b8: 0x0261, 0x9b9: 0x0269, 0x9ba: 0x3308, 0x9bb: 0x3308,\n\t0x9bc: 0x3308, 0x9bd: 0x3308, 0x9be: 0x3308, 0x9bf: 0x3008,\n\t// Block 0x27, offset 0x9c0\n\t0x9c0: 0x3308, 0x9c1: 0x0271, 0x9c2: 0x3308, 0x9c3: 0x3308, 0x9c4: 0x3b08, 0x9c5: 0x0018,\n\t0x9c6: 0x3308, 0x9c7: 0x3308, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008,\n\t0x9cc: 0x0008, 0x9cd: 0x3308, 0x9ce: 0x3308, 0x9cf: 0x3308, 0x9d0: 0x3308, 0x9d1: 0x3308,\n\t0x9d2: 0x3308, 0x9d3: 0x0279, 0x9d4: 0x3308, 0x9d5: 0x3308, 0x9d6: 0x3308, 0x9d7: 0x3308,\n\t0x9d8: 0x0040, 0x9d9: 0x3308, 0x9da: 0x3308, 0x9db: 0x3308, 0x9dc: 0x3308, 0x9dd: 0x0281,\n\t0x9de: 0x3308, 0x9df: 0x3308, 0x9e0: 0x3308, 0x9e1: 0x3308, 0x9e2: 0x0289, 0x9e3: 0x3308,\n\t0x9e4: 0x3308, 0x9e5: 0x3308, 0x9e6: 0x3308, 0x9e7: 0x0291, 0x9e8: 0x3308, 0x9e9: 0x3308,\n\t0x9ea: 0x3308, 0x9eb: 0x3308, 0x9ec: 0x0299, 0x9ed: 0x3308, 0x9ee: 0x3308, 0x9ef: 0x3308,\n\t0x9f0: 0x3308, 0x9f1: 0x3308, 0x9f2: 0x3308, 0x9f3: 0x3308, 0x9f4: 0x3308, 0x9f5: 0x3308,\n\t0x9f6: 0x3308, 0x9f7: 0x3308, 0x9f8: 0x3308, 0x9f9: 0x02a1, 0x9fa: 0x3308, 0x9fb: 0x3308,\n\t0x9fc: 0x3308, 0x9fd: 0x0040, 0x9fe: 0x0018, 0x9ff: 0x0018,\n\t// Block 0x28, offset 0xa00\n\t0xa00: 0x0008, 0xa01: 0x0008, 0xa02: 0x0008, 0xa03: 0x0008, 0xa04: 0x0008, 0xa05: 0x0008,\n\t0xa06: 0x0008, 0xa07: 0x0008, 0xa08: 0x0008, 0xa09: 0x0008, 0xa0a: 0x0008, 0xa0b: 0x0008,\n\t0xa0c: 0x0008, 0xa0d: 0x0008, 0xa0e: 0x0008, 0xa0f: 0x0008, 0xa10: 0x0008, 0xa11: 0x0008,\n\t0xa12: 0x0008, 0xa13: 0x0008, 0xa14: 0x0008, 0xa15: 0x0008, 0xa16: 0x0008, 0xa17: 0x0008,\n\t0xa18: 0x0008, 0xa19: 0x0008, 0xa1a: 0x0008, 0xa1b: 0x0008, 0xa1c: 0x0008, 0xa1d: 0x0008,\n\t0xa1e: 0x0008, 0xa1f: 0x0008, 0xa20: 0x0008, 0xa21: 0x0008, 0xa22: 0x0008, 0xa23: 0x0008,\n\t0xa24: 0x0008, 0xa25: 0x0008, 0xa26: 0x0008, 0xa27: 0x0008, 0xa28: 0x0008, 0xa29: 0x0008,\n\t0xa2a: 0x0008, 0xa2b: 0x0008, 0xa2c: 0x0019, 0xa2d: 0x02e1, 0xa2e: 0x02e9, 0xa2f: 0x0008,\n\t0xa30: 0x02f1, 0xa31: 0x02f9, 0xa32: 0x0301, 0xa33: 0x0309, 0xa34: 0x00a9, 0xa35: 0x0311,\n\t0xa36: 0x00b1, 0xa37: 0x0319, 0xa38: 0x0101, 0xa39: 0x0321, 0xa3a: 0x0329, 0xa3b: 0x0008,\n\t0xa3c: 0x0051, 0xa3d: 0x0331, 0xa3e: 0x0339, 0xa3f: 0x00b9,\n\t// Block 0x29, offset 0xa40\n\t0xa40: 0x0341, 0xa41: 0x0349, 0xa42: 0x00c1, 0xa43: 0x0019, 0xa44: 0x0351, 0xa45: 0x0359,\n\t0xa46: 0x05b5, 0xa47: 0x02e9, 0xa48: 0x02f1, 0xa49: 0x02f9, 0xa4a: 0x0361, 0xa4b: 0x0369,\n\t0xa4c: 0x0371, 0xa4d: 0x0309, 0xa4e: 0x0008, 0xa4f: 0x0319, 0xa50: 0x0321, 0xa51: 0x0379,\n\t0xa52: 0x0051, 0xa53: 0x0381, 0xa54: 0x05cd, 0xa55: 0x05cd, 0xa56: 0x0339, 0xa57: 0x0341,\n\t0xa58: 0x0349, 0xa59: 0x05b5, 0xa5a: 0x0389, 0xa5b: 0x0391, 0xa5c: 0x05e5, 0xa5d: 0x0399,\n\t0xa5e: 0x03a1, 0xa5f: 0x03a9, 0xa60: 0x03b1, 0xa61: 0x03b9, 0xa62: 0x0311, 0xa63: 0x00b9,\n\t0xa64: 0x0349, 0xa65: 0x0391, 0xa66: 0x0399, 0xa67: 0x03a1, 0xa68: 0x03c1, 0xa69: 0x03b1,\n\t0xa6a: 0x03b9, 0xa6b: 0x0008, 0xa6c: 0x0008, 0xa6d: 0x0008, 0xa6e: 0x0008, 0xa6f: 0x0008,\n\t0xa70: 0x0008, 0xa71: 0x0008, 0xa72: 0x0008, 0xa73: 0x0008, 0xa74: 0x0008, 0xa75: 0x0008,\n\t0xa76: 0x0008, 0xa77: 0x0008, 0xa78: 0x03c9, 0xa79: 0x0008, 0xa7a: 0x0008, 0xa7b: 0x0008,\n\t0xa7c: 0x0008, 0xa7d: 0x0008, 0xa7e: 0x0008, 0xa7f: 0x0008,\n\t// Block 0x2a, offset 0xa80\n\t0xa80: 0x0008, 0xa81: 0x0008, 0xa82: 0x0008, 0xa83: 0x0008, 0xa84: 0x0008, 0xa85: 0x0008,\n\t0xa86: 0x0008, 0xa87: 0x0008, 0xa88: 0x0008, 0xa89: 0x0008, 0xa8a: 0x0008, 0xa8b: 0x0008,\n\t0xa8c: 0x0008, 0xa8d: 0x0008, 0xa8e: 0x0008, 0xa8f: 0x0008, 0xa90: 0x0008, 0xa91: 0x0008,\n\t0xa92: 0x0008, 0xa93: 0x0008, 0xa94: 0x0008, 0xa95: 0x0008, 0xa96: 0x0008, 0xa97: 0x0008,\n\t0xa98: 0x0008, 0xa99: 0x0008, 0xa9a: 0x0008, 0xa9b: 0x03d1, 0xa9c: 0x03d9, 0xa9d: 0x03e1,\n\t0xa9e: 0x03e9, 0xa9f: 0x0371, 0xaa0: 0x03f1, 0xaa1: 0x03f9, 0xaa2: 0x0401, 0xaa3: 0x0409,\n\t0xaa4: 0x0411, 0xaa5: 0x0419, 0xaa6: 0x0421, 0xaa7: 0x05fd, 0xaa8: 0x0429, 0xaa9: 0x0431,\n\t0xaaa: 0xe17d, 0xaab: 0x0439, 0xaac: 0x0441, 0xaad: 0x0449, 0xaae: 0x0451, 0xaaf: 0x0459,\n\t0xab0: 0x0461, 0xab1: 0x0469, 0xab2: 0x0471, 0xab3: 0x0479, 0xab4: 0x0481, 0xab5: 0x0489,\n\t0xab6: 0x0491, 0xab7: 0x0499, 0xab8: 0x0615, 0xab9: 0x04a1, 0xaba: 0x04a9, 0xabb: 0x04b1,\n\t0xabc: 0x04b9, 0xabd: 0x04c1, 0xabe: 0x04c9, 0xabf: 0x04d1,\n\t// Block 0x2b, offset 0xac0\n\t0xac0: 0xe00d, 0xac1: 0x0008, 0xac2: 0xe00d, 0xac3: 0x0008, 0xac4: 0xe00d, 0xac5: 0x0008,\n\t0xac6: 0xe00d, 0xac7: 0x0008, 0xac8: 0xe00d, 0xac9: 0x0008, 0xaca: 0xe00d, 0xacb: 0x0008,\n\t0xacc: 0xe00d, 0xacd: 0x0008, 0xace: 0xe00d, 0xacf: 0x0008, 0xad0: 0xe00d, 0xad1: 0x0008,\n\t0xad2: 0xe00d, 0xad3: 0x0008, 0xad4: 0xe00d, 0xad5: 0x0008, 0xad6: 0xe00d, 0xad7: 0x0008,\n\t0xad8: 0xe00d, 0xad9: 0x0008, 0xada: 0xe00d, 0xadb: 0x0008, 0xadc: 0xe00d, 0xadd: 0x0008,\n\t0xade: 0xe00d, 0xadf: 0x0008, 0xae0: 0xe00d, 0xae1: 0x0008, 0xae2: 0xe00d, 0xae3: 0x0008,\n\t0xae4: 0xe00d, 0xae5: 0x0008, 0xae6: 0xe00d, 0xae7: 0x0008, 0xae8: 0xe00d, 0xae9: 0x0008,\n\t0xaea: 0xe00d, 0xaeb: 0x0008, 0xaec: 0xe00d, 0xaed: 0x0008, 0xaee: 0xe00d, 0xaef: 0x0008,\n\t0xaf0: 0xe00d, 0xaf1: 0x0008, 0xaf2: 0xe00d, 0xaf3: 0x0008, 0xaf4: 0xe00d, 0xaf5: 0x0008,\n\t0xaf6: 0xe00d, 0xaf7: 0x0008, 0xaf8: 0xe00d, 0xaf9: 0x0008, 0xafa: 0xe00d, 0xafb: 0x0008,\n\t0xafc: 0xe00d, 0xafd: 0x0008, 0xafe: 0xe00d, 0xaff: 0x0008,\n\t// Block 0x2c, offset 0xb00\n\t0xb00: 0xe00d, 0xb01: 0x0008, 0xb02: 0xe00d, 0xb03: 0x0008, 0xb04: 0xe00d, 0xb05: 0x0008,\n\t0xb06: 0xe00d, 0xb07: 0x0008, 0xb08: 0xe00d, 0xb09: 0x0008, 0xb0a: 0xe00d, 0xb0b: 0x0008,\n\t0xb0c: 0xe00d, 0xb0d: 0x0008, 0xb0e: 0xe00d, 0xb0f: 0x0008, 0xb10: 0xe00d, 0xb11: 0x0008,\n\t0xb12: 0xe00d, 0xb13: 0x0008, 0xb14: 0xe00d, 0xb15: 0x0008, 0xb16: 0x0008, 0xb17: 0x0008,\n\t0xb18: 0x0008, 0xb19: 0x0008, 0xb1a: 0x062d, 0xb1b: 0x064d, 0xb1c: 0x0008, 0xb1d: 0x0008,\n\t0xb1e: 0x04d9, 0xb1f: 0x0008, 0xb20: 0xe00d, 0xb21: 0x0008, 0xb22: 0xe00d, 0xb23: 0x0008,\n\t0xb24: 0xe00d, 0xb25: 0x0008, 0xb26: 0xe00d, 0xb27: 0x0008, 0xb28: 0xe00d, 0xb29: 0x0008,\n\t0xb2a: 0xe00d, 0xb2b: 0x0008, 0xb2c: 0xe00d, 0xb2d: 0x0008, 0xb2e: 0xe00d, 0xb2f: 0x0008,\n\t0xb30: 0xe00d, 0xb31: 0x0008, 0xb32: 0xe00d, 0xb33: 0x0008, 0xb34: 0xe00d, 0xb35: 0x0008,\n\t0xb36: 0xe00d, 0xb37: 0x0008, 0xb38: 0xe00d, 0xb39: 0x0008, 0xb3a: 0xe00d, 0xb3b: 0x0008,\n\t0xb3c: 0xe00d, 0xb3d: 0x0008, 0xb3e: 0xe00d, 0xb3f: 0x0008,\n\t// Block 0x2d, offset 0xb40\n\t0xb40: 0x0008, 0xb41: 0x0008, 0xb42: 0x0008, 0xb43: 0x0008, 0xb44: 0x0008, 0xb45: 0x0008,\n\t0xb46: 0x0040, 0xb47: 0x0040, 0xb48: 0xe045, 0xb49: 0xe045, 0xb4a: 0xe045, 0xb4b: 0xe045,\n\t0xb4c: 0xe045, 0xb4d: 0xe045, 0xb4e: 0x0040, 0xb4f: 0x0040, 0xb50: 0x0008, 0xb51: 0x0008,\n\t0xb52: 0x0008, 0xb53: 0x0008, 0xb54: 0x0008, 0xb55: 0x0008, 0xb56: 0x0008, 0xb57: 0x0008,\n\t0xb58: 0x0040, 0xb59: 0xe045, 0xb5a: 0x0040, 0xb5b: 0xe045, 0xb5c: 0x0040, 0xb5d: 0xe045,\n\t0xb5e: 0x0040, 0xb5f: 0xe045, 0xb60: 0x0008, 0xb61: 0x0008, 0xb62: 0x0008, 0xb63: 0x0008,\n\t0xb64: 0x0008, 0xb65: 0x0008, 0xb66: 0x0008, 0xb67: 0x0008, 0xb68: 0xe045, 0xb69: 0xe045,\n\t0xb6a: 0xe045, 0xb6b: 0xe045, 0xb6c: 0xe045, 0xb6d: 0xe045, 0xb6e: 0xe045, 0xb6f: 0xe045,\n\t0xb70: 0x0008, 0xb71: 0x04e1, 0xb72: 0x0008, 0xb73: 0x04e9, 0xb74: 0x0008, 0xb75: 0x04f1,\n\t0xb76: 0x0008, 0xb77: 0x04f9, 0xb78: 0x0008, 0xb79: 0x0501, 0xb7a: 0x0008, 0xb7b: 0x0509,\n\t0xb7c: 0x0008, 0xb7d: 0x0511, 0xb7e: 0x0040, 0xb7f: 0x0040,\n\t// Block 0x2e, offset 0xb80\n\t0xb80: 0x0519, 0xb81: 0x0521, 0xb82: 0x0529, 0xb83: 0x0531, 0xb84: 0x0539, 0xb85: 0x0541,\n\t0xb86: 0x0549, 0xb87: 0x0551, 0xb88: 0x0519, 0xb89: 0x0521, 0xb8a: 0x0529, 0xb8b: 0x0531,\n\t0xb8c: 0x0539, 0xb8d: 0x0541, 0xb8e: 0x0549, 0xb8f: 0x0551, 0xb90: 0x0559, 0xb91: 0x0561,\n\t0xb92: 0x0569, 0xb93: 0x0571, 0xb94: 0x0579, 0xb95: 0x0581, 0xb96: 0x0589, 0xb97: 0x0591,\n\t0xb98: 0x0559, 0xb99: 0x0561, 0xb9a: 0x0569, 0xb9b: 0x0571, 0xb9c: 0x0579, 0xb9d: 0x0581,\n\t0xb9e: 0x0589, 0xb9f: 0x0591, 0xba0: 0x0599, 0xba1: 0x05a1, 0xba2: 0x05a9, 0xba3: 0x05b1,\n\t0xba4: 0x05b9, 0xba5: 0x05c1, 0xba6: 0x05c9, 0xba7: 0x05d1, 0xba8: 0x0599, 0xba9: 0x05a1,\n\t0xbaa: 0x05a9, 0xbab: 0x05b1, 0xbac: 0x05b9, 0xbad: 0x05c1, 0xbae: 0x05c9, 0xbaf: 0x05d1,\n\t0xbb0: 0x0008, 0xbb1: 0x0008, 0xbb2: 0x05d9, 0xbb3: 0x05e1, 0xbb4: 0x05e9, 0xbb5: 0x0040,\n\t0xbb6: 0x0008, 0xbb7: 0x05f1, 0xbb8: 0xe045, 0xbb9: 0xe045, 0xbba: 0x0665, 0xbbb: 0x04e1,\n\t0xbbc: 0x05e1, 0xbbd: 0x067e, 0xbbe: 0x05f9, 0xbbf: 0x069e,\n\t// Block 0x2f, offset 0xbc0\n\t0xbc0: 0x06be, 0xbc1: 0x0602, 0xbc2: 0x0609, 0xbc3: 0x0611, 0xbc4: 0x0619, 0xbc5: 0x0040,\n\t0xbc6: 0x0008, 0xbc7: 0x0621, 0xbc8: 0x06dd, 0xbc9: 0x04e9, 0xbca: 0x06f5, 0xbcb: 0x04f1,\n\t0xbcc: 0x0611, 0xbcd: 0x062a, 0xbce: 0x0632, 0xbcf: 0x063a, 0xbd0: 0x0008, 0xbd1: 0x0008,\n\t0xbd2: 0x0008, 0xbd3: 0x0641, 0xbd4: 0x0040, 0xbd5: 0x0040, 0xbd6: 0x0008, 0xbd7: 0x0008,\n\t0xbd8: 0xe045, 0xbd9: 0xe045, 0xbda: 0x070d, 0xbdb: 0x04f9, 0xbdc: 0x0040, 0xbdd: 0x064a,\n\t0xbde: 0x0652, 0xbdf: 0x065a, 0xbe0: 0x0008, 0xbe1: 0x0008, 0xbe2: 0x0008, 0xbe3: 0x0661,\n\t0xbe4: 0x0008, 0xbe5: 0x0008, 0xbe6: 0x0008, 0xbe7: 0x0008, 0xbe8: 0xe045, 0xbe9: 0xe045,\n\t0xbea: 0x0725, 0xbeb: 0x0509, 0xbec: 0xe04d, 0xbed: 0x066a, 0xbee: 0x012a, 0xbef: 0x0672,\n\t0xbf0: 0x0040, 0xbf1: 0x0040, 0xbf2: 0x0679, 0xbf3: 0x0681, 0xbf4: 0x0689, 0xbf5: 0x0040,\n\t0xbf6: 0x0008, 0xbf7: 0x0691, 0xbf8: 0x073d, 0xbf9: 0x0501, 0xbfa: 0x0515, 0xbfb: 0x0511,\n\t0xbfc: 0x0681, 0xbfd: 0x0756, 0xbfe: 0x0776, 0xbff: 0x0040,\n\t// Block 0x30, offset 0xc00\n\t0xc00: 0x000a, 0xc01: 0x000a, 0xc02: 0x000a, 0xc03: 0x000a, 0xc04: 0x000a, 0xc05: 0x000a,\n\t0xc06: 0x000a, 0xc07: 0x000a, 0xc08: 0x000a, 0xc09: 0x000a, 0xc0a: 0x000a, 0xc0b: 0x03c0,\n\t0xc0c: 0x0003, 0xc0d: 0x0003, 0xc0e: 0x0340, 0xc0f: 0x0b40, 0xc10: 0x0018, 0xc11: 0xe00d,\n\t0xc12: 0x0018, 0xc13: 0x0018, 0xc14: 0x0018, 0xc15: 0x0018, 0xc16: 0x0018, 0xc17: 0x0796,\n\t0xc18: 0x0018, 0xc19: 0x0018, 0xc1a: 0x0018, 0xc1b: 0x0018, 0xc1c: 0x0018, 0xc1d: 0x0018,\n\t0xc1e: 0x0018, 0xc1f: 0x0018, 0xc20: 0x0018, 0xc21: 0x0018, 0xc22: 0x0018, 0xc23: 0x0018,\n\t0xc24: 0x0040, 0xc25: 0x0040, 0xc26: 0x0040, 0xc27: 0x0018, 0xc28: 0x0040, 0xc29: 0x0040,\n\t0xc2a: 0x0340, 0xc2b: 0x0340, 0xc2c: 0x0340, 0xc2d: 0x0340, 0xc2e: 0x0340, 0xc2f: 0x000a,\n\t0xc30: 0x0018, 0xc31: 0x0018, 0xc32: 0x0018, 0xc33: 0x0699, 0xc34: 0x06a1, 0xc35: 0x0018,\n\t0xc36: 0x06a9, 0xc37: 0x06b1, 0xc38: 0x0018, 0xc39: 0x0018, 0xc3a: 0x0018, 0xc3b: 0x0018,\n\t0xc3c: 0x06ba, 0xc3d: 0x0018, 0xc3e: 0x07b6, 0xc3f: 0x0018,\n\t// Block 0x31, offset 0xc40\n\t0xc40: 0x0018, 0xc41: 0x0018, 0xc42: 0x0018, 0xc43: 0x0018, 0xc44: 0x0018, 0xc45: 0x0018,\n\t0xc46: 0x0018, 0xc47: 0x06c2, 0xc48: 0x06ca, 0xc49: 0x06d2, 0xc4a: 0x0018, 0xc4b: 0x0018,\n\t0xc4c: 0x0018, 0xc4d: 0x0018, 0xc4e: 0x0018, 0xc4f: 0x0018, 0xc50: 0x0018, 0xc51: 0x0018,\n\t0xc52: 0x0018, 0xc53: 0x0018, 0xc54: 0x0018, 0xc55: 0x0018, 0xc56: 0x0018, 0xc57: 0x06d9,\n\t0xc58: 0x0018, 0xc59: 0x0018, 0xc5a: 0x0018, 0xc5b: 0x0018, 0xc5c: 0x0018, 0xc5d: 0x0018,\n\t0xc5e: 0x0018, 0xc5f: 0x000a, 0xc60: 0x03c0, 0xc61: 0x0340, 0xc62: 0x0340, 0xc63: 0x0340,\n\t0xc64: 0x03c0, 0xc65: 0x0040, 0xc66: 0x0040, 0xc67: 0x0040, 0xc68: 0x0040, 0xc69: 0x0040,\n\t0xc6a: 0x0340, 0xc6b: 0x0340, 0xc6c: 0x0340, 0xc6d: 0x0340, 0xc6e: 0x0340, 0xc6f: 0x0340,\n\t0xc70: 0x06e1, 0xc71: 0x0311, 0xc72: 0x0040, 0xc73: 0x0040, 0xc74: 0x06e9, 0xc75: 0x06f1,\n\t0xc76: 0x06f9, 0xc77: 0x0701, 0xc78: 0x0709, 0xc79: 0x0711, 0xc7a: 0x071a, 0xc7b: 0x07d5,\n\t0xc7c: 0x0722, 0xc7d: 0x072a, 0xc7e: 0x0732, 0xc7f: 0x0329,\n\t// Block 0x32, offset 0xc80\n\t0xc80: 0x06e1, 0xc81: 0x0049, 0xc82: 0x0029, 0xc83: 0x0031, 0xc84: 0x06e9, 0xc85: 0x06f1,\n\t0xc86: 0x06f9, 0xc87: 0x0701, 0xc88: 0x0709, 0xc89: 0x0711, 0xc8a: 0x071a, 0xc8b: 0x07ed,\n\t0xc8c: 0x0722, 0xc8d: 0x072a, 0xc8e: 0x0732, 0xc8f: 0x0040, 0xc90: 0x0019, 0xc91: 0x02f9,\n\t0xc92: 0x0051, 0xc93: 0x0109, 0xc94: 0x0361, 0xc95: 0x00a9, 0xc96: 0x0319, 0xc97: 0x0101,\n\t0xc98: 0x0321, 0xc99: 0x0329, 0xc9a: 0x0339, 0xc9b: 0x0089, 0xc9c: 0x0341, 0xc9d: 0x0040,\n\t0xc9e: 0x0040, 0xc9f: 0x0040, 0xca0: 0x0018, 0xca1: 0x0018, 0xca2: 0x0018, 0xca3: 0x0018,\n\t0xca4: 0x0018, 0xca5: 0x0018, 0xca6: 0x0018, 0xca7: 0x0018, 0xca8: 0x0739, 0xca9: 0x0018,\n\t0xcaa: 0x0018, 0xcab: 0x0018, 0xcac: 0x0018, 0xcad: 0x0018, 0xcae: 0x0018, 0xcaf: 0x0018,\n\t0xcb0: 0x0018, 0xcb1: 0x0018, 0xcb2: 0x0018, 0xcb3: 0x0018, 0xcb4: 0x0018, 0xcb5: 0x0018,\n\t0xcb6: 0x0018, 0xcb7: 0x0018, 0xcb8: 0x0018, 0xcb9: 0x0018, 0xcba: 0x0018, 0xcbb: 0x0018,\n\t0xcbc: 0x0018, 0xcbd: 0x0018, 0xcbe: 0x0018, 0xcbf: 0x0018,\n\t// Block 0x33, offset 0xcc0\n\t0xcc0: 0x0806, 0xcc1: 0x0826, 0xcc2: 0x03d9, 0xcc3: 0x0845, 0xcc4: 0x0018, 0xcc5: 0x0866,\n\t0xcc6: 0x0886, 0xcc7: 0x0369, 0xcc8: 0x0018, 0xcc9: 0x08a5, 0xcca: 0x0309, 0xccb: 0x00a9,\n\t0xccc: 0x00a9, 0xccd: 0x00a9, 0xcce: 0x00a9, 0xccf: 0x0741, 0xcd0: 0x0311, 0xcd1: 0x0311,\n\t0xcd2: 0x0101, 0xcd3: 0x0101, 0xcd4: 0x0018, 0xcd5: 0x0329, 0xcd6: 0x0749, 0xcd7: 0x0018,\n\t0xcd8: 0x0018, 0xcd9: 0x0339, 0xcda: 0x0751, 0xcdb: 0x00b9, 0xcdc: 0x00b9, 0xcdd: 0x00b9,\n\t0xcde: 0x0018, 0xcdf: 0x0018, 0xce0: 0x0759, 0xce1: 0x08c5, 0xce2: 0x0761, 0xce3: 0x0018,\n\t0xce4: 0x04b1, 0xce5: 0x0018, 0xce6: 0x0769, 0xce7: 0x0018, 0xce8: 0x04b1, 0xce9: 0x0018,\n\t0xcea: 0x0319, 0xceb: 0x0771, 0xcec: 0x02e9, 0xced: 0x03d9, 0xcee: 0x0018, 0xcef: 0x02f9,\n\t0xcf0: 0x02f9, 0xcf1: 0x03f1, 0xcf2: 0x0040, 0xcf3: 0x0321, 0xcf4: 0x0051, 0xcf5: 0x0779,\n\t0xcf6: 0x0781, 0xcf7: 0x0789, 0xcf8: 0x0791, 0xcf9: 0x0311, 0xcfa: 0x0018, 0xcfb: 0x08e5,\n\t0xcfc: 0x0799, 0xcfd: 0x03a1, 0xcfe: 0x03a1, 0xcff: 0x0799,\n\t// Block 0x34, offset 0xd00\n\t0xd00: 0x0905, 0xd01: 0x0018, 0xd02: 0x0018, 0xd03: 0x0018, 0xd04: 0x0018, 0xd05: 0x02f1,\n\t0xd06: 0x02f1, 0xd07: 0x02f9, 0xd08: 0x0311, 0xd09: 0x00b1, 0xd0a: 0x0018, 0xd0b: 0x0018,\n\t0xd0c: 0x0018, 0xd0d: 0x0018, 0xd0e: 0x0008, 0xd0f: 0x0018, 0xd10: 0x07a1, 0xd11: 0x07a9,\n\t0xd12: 0x07b1, 0xd13: 0x07b9, 0xd14: 0x07c1, 0xd15: 0x07c9, 0xd16: 0x07d1, 0xd17: 0x07d9,\n\t0xd18: 0x07e1, 0xd19: 0x07e9, 0xd1a: 0x07f1, 0xd1b: 0x07f9, 0xd1c: 0x0801, 0xd1d: 0x0809,\n\t0xd1e: 0x0811, 0xd1f: 0x0819, 0xd20: 0x0311, 0xd21: 0x0821, 0xd22: 0x091d, 0xd23: 0x0829,\n\t0xd24: 0x0391, 0xd25: 0x0831, 0xd26: 0x093d, 0xd27: 0x0839, 0xd28: 0x0841, 0xd29: 0x0109,\n\t0xd2a: 0x0849, 0xd2b: 0x095d, 0xd2c: 0x0101, 0xd2d: 0x03d9, 0xd2e: 0x02f1, 0xd2f: 0x0321,\n\t0xd30: 0x0311, 0xd31: 0x0821, 0xd32: 0x097d, 0xd33: 0x0829, 0xd34: 0x0391, 0xd35: 0x0831,\n\t0xd36: 0x099d, 0xd37: 0x0839, 0xd38: 0x0841, 0xd39: 0x0109, 0xd3a: 0x0849, 0xd3b: 0x09bd,\n\t0xd3c: 0x0101, 0xd3d: 0x03d9, 0xd3e: 0x02f1, 0xd3f: 0x0321,\n\t// Block 0x35, offset 0xd40\n\t0xd40: 0x0018, 0xd41: 0x0018, 0xd42: 0x0018, 0xd43: 0x0018, 0xd44: 0x0018, 0xd45: 0x0018,\n\t0xd46: 0x0018, 0xd47: 0x0018, 0xd48: 0x0018, 0xd49: 0x0018, 0xd4a: 0x0018, 0xd4b: 0x0040,\n\t0xd4c: 0x0040, 0xd4d: 0x0040, 0xd4e: 0x0040, 0xd4f: 0x0040, 0xd50: 0x0040, 0xd51: 0x0040,\n\t0xd52: 0x0040, 0xd53: 0x0040, 0xd54: 0x0040, 0xd55: 0x0040, 0xd56: 0x0040, 0xd57: 0x0040,\n\t0xd58: 0x0040, 0xd59: 0x0040, 0xd5a: 0x0040, 0xd5b: 0x0040, 0xd5c: 0x0040, 0xd5d: 0x0040,\n\t0xd5e: 0x0040, 0xd5f: 0x0040, 0xd60: 0x0049, 0xd61: 0x0029, 0xd62: 0x0031, 0xd63: 0x06e9,\n\t0xd64: 0x06f1, 0xd65: 0x06f9, 0xd66: 0x0701, 0xd67: 0x0709, 0xd68: 0x0711, 0xd69: 0x0879,\n\t0xd6a: 0x0881, 0xd6b: 0x0889, 0xd6c: 0x0891, 0xd6d: 0x0899, 0xd6e: 0x08a1, 0xd6f: 0x08a9,\n\t0xd70: 0x08b1, 0xd71: 0x08b9, 0xd72: 0x08c1, 0xd73: 0x08c9, 0xd74: 0x0a1e, 0xd75: 0x0a3e,\n\t0xd76: 0x0a5e, 0xd77: 0x0a7e, 0xd78: 0x0a9e, 0xd79: 0x0abe, 0xd7a: 0x0ade, 0xd7b: 0x0afe,\n\t0xd7c: 0x0b1e, 0xd7d: 0x08d2, 0xd7e: 0x08da, 0xd7f: 0x08e2,\n\t// Block 0x36, offset 0xd80\n\t0xd80: 0x08ea, 0xd81: 0x08f2, 0xd82: 0x08fa, 0xd83: 0x0902, 0xd84: 0x090a, 0xd85: 0x0912,\n\t0xd86: 0x091a, 0xd87: 0x0922, 0xd88: 0x0040, 0xd89: 0x0040, 0xd8a: 0x0040, 0xd8b: 0x0040,\n\t0xd8c: 0x0040, 0xd8d: 0x0040, 0xd8e: 0x0040, 0xd8f: 0x0040, 0xd90: 0x0040, 0xd91: 0x0040,\n\t0xd92: 0x0040, 0xd93: 0x0040, 0xd94: 0x0040, 0xd95: 0x0040, 0xd96: 0x0040, 0xd97: 0x0040,\n\t0xd98: 0x0040, 0xd99: 0x0040, 0xd9a: 0x0040, 0xd9b: 0x0040, 0xd9c: 0x0b3e, 0xd9d: 0x0b5e,\n\t0xd9e: 0x0b7e, 0xd9f: 0x0b9e, 0xda0: 0x0bbe, 0xda1: 0x0bde, 0xda2: 0x0bfe, 0xda3: 0x0c1e,\n\t0xda4: 0x0c3e, 0xda5: 0x0c5e, 0xda6: 0x0c7e, 0xda7: 0x0c9e, 0xda8: 0x0cbe, 0xda9: 0x0cde,\n\t0xdaa: 0x0cfe, 0xdab: 0x0d1e, 0xdac: 0x0d3e, 0xdad: 0x0d5e, 0xdae: 0x0d7e, 0xdaf: 0x0d9e,\n\t0xdb0: 0x0dbe, 0xdb1: 0x0dde, 0xdb2: 0x0dfe, 0xdb3: 0x0e1e, 0xdb4: 0x0e3e, 0xdb5: 0x0e5e,\n\t0xdb6: 0x0019, 0xdb7: 0x02e9, 0xdb8: 0x03d9, 0xdb9: 0x02f1, 0xdba: 0x02f9, 0xdbb: 0x03f1,\n\t0xdbc: 0x0309, 0xdbd: 0x00a9, 0xdbe: 0x0311, 0xdbf: 0x00b1,\n\t// Block 0x37, offset 0xdc0\n\t0xdc0: 0x0319, 0xdc1: 0x0101, 0xdc2: 0x0321, 0xdc3: 0x0329, 0xdc4: 0x0051, 0xdc5: 0x0339,\n\t0xdc6: 0x0751, 0xdc7: 0x00b9, 0xdc8: 0x0089, 0xdc9: 0x0341, 0xdca: 0x0349, 0xdcb: 0x0391,\n\t0xdcc: 0x00c1, 0xdcd: 0x0109, 0xdce: 0x00c9, 0xdcf: 0x04b1, 0xdd0: 0x0019, 0xdd1: 0x02e9,\n\t0xdd2: 0x03d9, 0xdd3: 0x02f1, 0xdd4: 0x02f9, 0xdd5: 0x03f1, 0xdd6: 0x0309, 0xdd7: 0x00a9,\n\t0xdd8: 0x0311, 0xdd9: 0x00b1, 0xdda: 0x0319, 0xddb: 0x0101, 0xddc: 0x0321, 0xddd: 0x0329,\n\t0xdde: 0x0051, 0xddf: 0x0339, 0xde0: 0x0751, 0xde1: 0x00b9, 0xde2: 0x0089, 0xde3: 0x0341,\n\t0xde4: 0x0349, 0xde5: 0x0391, 0xde6: 0x00c1, 0xde7: 0x0109, 0xde8: 0x00c9, 0xde9: 0x04b1,\n\t0xdea: 0x06e1, 0xdeb: 0x0018, 0xdec: 0x0018, 0xded: 0x0018, 0xdee: 0x0018, 0xdef: 0x0018,\n\t0xdf0: 0x0018, 0xdf1: 0x0018, 0xdf2: 0x0018, 0xdf3: 0x0018, 0xdf4: 0x0018, 0xdf5: 0x0018,\n\t0xdf6: 0x0018, 0xdf7: 0x0018, 0xdf8: 0x0018, 0xdf9: 0x0018, 0xdfa: 0x0018, 0xdfb: 0x0018,\n\t0xdfc: 0x0018, 0xdfd: 0x0018, 0xdfe: 0x0018, 0xdff: 0x0018,\n\t// Block 0x38, offset 0xe00\n\t0xe00: 0x0008, 0xe01: 0x0008, 0xe02: 0x0008, 0xe03: 0x0008, 0xe04: 0x0008, 0xe05: 0x0008,\n\t0xe06: 0x0008, 0xe07: 0x0008, 0xe08: 0x0008, 0xe09: 0x0008, 0xe0a: 0x0008, 0xe0b: 0x0008,\n\t0xe0c: 0x0008, 0xe0d: 0x0008, 0xe0e: 0x0008, 0xe0f: 0x0008, 0xe10: 0x0008, 0xe11: 0x0008,\n\t0xe12: 0x0008, 0xe13: 0x0008, 0xe14: 0x0008, 0xe15: 0x0008, 0xe16: 0x0008, 0xe17: 0x0008,\n\t0xe18: 0x0008, 0xe19: 0x0008, 0xe1a: 0x0008, 0xe1b: 0x0008, 0xe1c: 0x0008, 0xe1d: 0x0008,\n\t0xe1e: 0x0008, 0xe1f: 0x0008, 0xe20: 0xe00d, 0xe21: 0x0008, 0xe22: 0x0941, 0xe23: 0x0ed5,\n\t0xe24: 0x0949, 0xe25: 0x0008, 0xe26: 0x0008, 0xe27: 0xe07d, 0xe28: 0x0008, 0xe29: 0xe01d,\n\t0xe2a: 0x0008, 0xe2b: 0xe03d, 0xe2c: 0x0008, 0xe2d: 0x0359, 0xe2e: 0x0441, 0xe2f: 0x0351,\n\t0xe30: 0x03d1, 0xe31: 0x0008, 0xe32: 0xe00d, 0xe33: 0x0008, 0xe34: 0x0008, 0xe35: 0xe01d,\n\t0xe36: 0x0008, 0xe37: 0x0008, 0xe38: 0x0008, 0xe39: 0x0008, 0xe3a: 0x0008, 0xe3b: 0x0008,\n\t0xe3c: 0x00b1, 0xe3d: 0x0391, 0xe3e: 0x0951, 0xe3f: 0x0959,\n\t// Block 0x39, offset 0xe40\n\t0xe40: 0xe00d, 0xe41: 0x0008, 0xe42: 0xe00d, 0xe43: 0x0008, 0xe44: 0xe00d, 0xe45: 0x0008,\n\t0xe46: 0xe00d, 0xe47: 0x0008, 0xe48: 0xe00d, 0xe49: 0x0008, 0xe4a: 0xe00d, 0xe4b: 0x0008,\n\t0xe4c: 0xe00d, 0xe4d: 0x0008, 0xe4e: 0xe00d, 0xe4f: 0x0008, 0xe50: 0xe00d, 0xe51: 0x0008,\n\t0xe52: 0xe00d, 0xe53: 0x0008, 0xe54: 0xe00d, 0xe55: 0x0008, 0xe56: 0xe00d, 0xe57: 0x0008,\n\t0xe58: 0xe00d, 0xe59: 0x0008, 0xe5a: 0xe00d, 0xe5b: 0x0008, 0xe5c: 0xe00d, 0xe5d: 0x0008,\n\t0xe5e: 0xe00d, 0xe5f: 0x0008, 0xe60: 0xe00d, 0xe61: 0x0008, 0xe62: 0xe00d, 0xe63: 0x0008,\n\t0xe64: 0x0008, 0xe65: 0x0018, 0xe66: 0x0018, 0xe67: 0x0018, 0xe68: 0x0018, 0xe69: 0x0018,\n\t0xe6a: 0x0018, 0xe6b: 0xe03d, 0xe6c: 0x0008, 0xe6d: 0xe01d, 0xe6e: 0x0008, 0xe6f: 0x3308,\n\t0xe70: 0x3308, 0xe71: 0x3308, 0xe72: 0xe00d, 0xe73: 0x0008, 0xe74: 0x0040, 0xe75: 0x0040,\n\t0xe76: 0x0040, 0xe77: 0x0040, 0xe78: 0x0040, 0xe79: 0x0018, 0xe7a: 0x0018, 0xe7b: 0x0018,\n\t0xe7c: 0x0018, 0xe7d: 0x0018, 0xe7e: 0x0018, 0xe7f: 0x0018,\n\t// Block 0x3a, offset 0xe80\n\t0xe80: 0x2715, 0xe81: 0x2735, 0xe82: 0x2755, 0xe83: 0x2775, 0xe84: 0x2795, 0xe85: 0x27b5,\n\t0xe86: 0x27d5, 0xe87: 0x27f5, 0xe88: 0x2815, 0xe89: 0x2835, 0xe8a: 0x2855, 0xe8b: 0x2875,\n\t0xe8c: 0x2895, 0xe8d: 0x28b5, 0xe8e: 0x28d5, 0xe8f: 0x28f5, 0xe90: 0x2915, 0xe91: 0x2935,\n\t0xe92: 0x2955, 0xe93: 0x2975, 0xe94: 0x2995, 0xe95: 0x29b5, 0xe96: 0x0040, 0xe97: 0x0040,\n\t0xe98: 0x0040, 0xe99: 0x0040, 0xe9a: 0x0040, 0xe9b: 0x0040, 0xe9c: 0x0040, 0xe9d: 0x0040,\n\t0xe9e: 0x0040, 0xe9f: 0x0040, 0xea0: 0x0040, 0xea1: 0x0040, 0xea2: 0x0040, 0xea3: 0x0040,\n\t0xea4: 0x0040, 0xea5: 0x0040, 0xea6: 0x0040, 0xea7: 0x0040, 0xea8: 0x0040, 0xea9: 0x0040,\n\t0xeaa: 0x0040, 0xeab: 0x0040, 0xeac: 0x0040, 0xead: 0x0040, 0xeae: 0x0040, 0xeaf: 0x0040,\n\t0xeb0: 0x0040, 0xeb1: 0x0040, 0xeb2: 0x0040, 0xeb3: 0x0040, 0xeb4: 0x0040, 0xeb5: 0x0040,\n\t0xeb6: 0x0040, 0xeb7: 0x0040, 0xeb8: 0x0040, 0xeb9: 0x0040, 0xeba: 0x0040, 0xebb: 0x0040,\n\t0xebc: 0x0040, 0xebd: 0x0040, 0xebe: 0x0040, 0xebf: 0x0040,\n\t// Block 0x3b, offset 0xec0\n\t0xec0: 0x000a, 0xec1: 0x0018, 0xec2: 0x0961, 0xec3: 0x0018, 0xec4: 0x0018, 0xec5: 0x0008,\n\t0xec6: 0x0008, 0xec7: 0x0008, 0xec8: 0x0018, 0xec9: 0x0018, 0xeca: 0x0018, 0xecb: 0x0018,\n\t0xecc: 0x0018, 0xecd: 0x0018, 0xece: 0x0018, 0xecf: 0x0018, 0xed0: 0x0018, 0xed1: 0x0018,\n\t0xed2: 0x0018, 0xed3: 0x0018, 0xed4: 0x0018, 0xed5: 0x0018, 0xed6: 0x0018, 0xed7: 0x0018,\n\t0xed8: 0x0018, 0xed9: 0x0018, 0xeda: 0x0018, 0xedb: 0x0018, 0xedc: 0x0018, 0xedd: 0x0018,\n\t0xede: 0x0018, 0xedf: 0x0018, 0xee0: 0x0018, 0xee1: 0x0018, 0xee2: 0x0018, 0xee3: 0x0018,\n\t0xee4: 0x0018, 0xee5: 0x0018, 0xee6: 0x0018, 0xee7: 0x0018, 0xee8: 0x0018, 0xee9: 0x0018,\n\t0xeea: 0x3308, 0xeeb: 0x3308, 0xeec: 0x3308, 0xeed: 0x3308, 0xeee: 0x3018, 0xeef: 0x3018,\n\t0xef0: 0x0018, 0xef1: 0x0018, 0xef2: 0x0018, 0xef3: 0x0018, 0xef4: 0x0018, 0xef5: 0x0018,\n\t0xef6: 0xe125, 0xef7: 0x0018, 0xef8: 0x29d5, 0xef9: 0x29f5, 0xefa: 0x2a15, 0xefb: 0x0018,\n\t0xefc: 0x0008, 0xefd: 0x0018, 0xefe: 0x0018, 0xeff: 0x0018,\n\t// Block 0x3c, offset 0xf00\n\t0xf00: 0x2b55, 0xf01: 0x2b75, 0xf02: 0x2b95, 0xf03: 0x2bb5, 0xf04: 0x2bd5, 0xf05: 0x2bf5,\n\t0xf06: 0x2bf5, 0xf07: 0x2bf5, 0xf08: 0x2c15, 0xf09: 0x2c15, 0xf0a: 0x2c15, 0xf0b: 0x2c15,\n\t0xf0c: 0x2c35, 0xf0d: 0x2c35, 0xf0e: 0x2c35, 0xf0f: 0x2c55, 0xf10: 0x2c75, 0xf11: 0x2c75,\n\t0xf12: 0x2a95, 0xf13: 0x2a95, 0xf14: 0x2c75, 0xf15: 0x2c75, 0xf16: 0x2c95, 0xf17: 0x2c95,\n\t0xf18: 0x2c75, 0xf19: 0x2c75, 0xf1a: 0x2a95, 0xf1b: 0x2a95, 0xf1c: 0x2c75, 0xf1d: 0x2c75,\n\t0xf1e: 0x2c55, 0xf1f: 0x2c55, 0xf20: 0x2cb5, 0xf21: 0x2cb5, 0xf22: 0x2cd5, 0xf23: 0x2cd5,\n\t0xf24: 0x0040, 0xf25: 0x2cf5, 0xf26: 0x2d15, 0xf27: 0x2d35, 0xf28: 0x2d35, 0xf29: 0x2d55,\n\t0xf2a: 0x2d75, 0xf2b: 0x2d95, 0xf2c: 0x2db5, 0xf2d: 0x2dd5, 0xf2e: 0x2df5, 0xf2f: 0x2e15,\n\t0xf30: 0x2e35, 0xf31: 0x2e55, 0xf32: 0x2e55, 0xf33: 0x2e75, 0xf34: 0x2e95, 0xf35: 0x2e95,\n\t0xf36: 0x2eb5, 0xf37: 0x2ed5, 0xf38: 0x2e75, 0xf39: 0x2ef5, 0xf3a: 0x2f15, 0xf3b: 0x2ef5,\n\t0xf3c: 0x2e75, 0xf3d: 0x2f35, 0xf3e: 0x2f55, 0xf3f: 0x2f75,\n\t// Block 0x3d, offset 0xf40\n\t0xf40: 0x2f95, 0xf41: 0x2fb5, 0xf42: 0x2d15, 0xf43: 0x2cf5, 0xf44: 0x2fd5, 0xf45: 0x2ff5,\n\t0xf46: 0x3015, 0xf47: 0x3035, 0xf48: 0x3055, 0xf49: 0x3075, 0xf4a: 0x3095, 0xf4b: 0x30b5,\n\t0xf4c: 0x30d5, 0xf4d: 0x30f5, 0xf4e: 0x3115, 0xf4f: 0x0040, 0xf50: 0x0018, 0xf51: 0x0018,\n\t0xf52: 0x3135, 0xf53: 0x3155, 0xf54: 0x3175, 0xf55: 0x3195, 0xf56: 0x31b5, 0xf57: 0x31d5,\n\t0xf58: 0x31f5, 0xf59: 0x3215, 0xf5a: 0x3235, 0xf5b: 0x3255, 0xf5c: 0x3175, 0xf5d: 0x3275,\n\t0xf5e: 0x3295, 0xf5f: 0x32b5, 0xf60: 0x0008, 0xf61: 0x0008, 0xf62: 0x0008, 0xf63: 0x0008,\n\t0xf64: 0x0008, 0xf65: 0x0008, 0xf66: 0x0008, 0xf67: 0x0008, 0xf68: 0x0008, 0xf69: 0x0008,\n\t0xf6a: 0x0008, 0xf6b: 0x0008, 0xf6c: 0x0008, 0xf6d: 0x0008, 0xf6e: 0x0008, 0xf6f: 0x0008,\n\t0xf70: 0x0008, 0xf71: 0x0008, 0xf72: 0x0008, 0xf73: 0x0008, 0xf74: 0x0008, 0xf75: 0x0008,\n\t0xf76: 0x0008, 0xf77: 0x0008, 0xf78: 0x0008, 0xf79: 0x0008, 0xf7a: 0x0008, 0xf7b: 0x0008,\n\t0xf7c: 0x0008, 0xf7d: 0x0008, 0xf7e: 0x0008, 0xf7f: 0x0008,\n\t// Block 0x3e, offset 0xf80\n\t0xf80: 0x0b82, 0xf81: 0x0b8a, 0xf82: 0x0b92, 0xf83: 0x0b9a, 0xf84: 0x32d5, 0xf85: 0x32f5,\n\t0xf86: 0x3315, 0xf87: 0x3335, 0xf88: 0x0018, 0xf89: 0x0018, 0xf8a: 0x0018, 0xf8b: 0x0018,\n\t0xf8c: 0x0018, 0xf8d: 0x0018, 0xf8e: 0x0018, 0xf8f: 0x0018, 0xf90: 0x3355, 0xf91: 0x0ba1,\n\t0xf92: 0x0ba9, 0xf93: 0x0bb1, 0xf94: 0x0bb9, 0xf95: 0x0bc1, 0xf96: 0x0bc9, 0xf97: 0x0bd1,\n\t0xf98: 0x0bd9, 0xf99: 0x0be1, 0xf9a: 0x0be9, 0xf9b: 0x0bf1, 0xf9c: 0x0bf9, 0xf9d: 0x0c01,\n\t0xf9e: 0x0c09, 0xf9f: 0x0c11, 0xfa0: 0x3375, 0xfa1: 0x3395, 0xfa2: 0x33b5, 0xfa3: 0x33d5,\n\t0xfa4: 0x33f5, 0xfa5: 0x33f5, 0xfa6: 0x3415, 0xfa7: 0x3435, 0xfa8: 0x3455, 0xfa9: 0x3475,\n\t0xfaa: 0x3495, 0xfab: 0x34b5, 0xfac: 0x34d5, 0xfad: 0x34f5, 0xfae: 0x3515, 0xfaf: 0x3535,\n\t0xfb0: 0x3555, 0xfb1: 0x3575, 0xfb2: 0x3595, 0xfb3: 0x35b5, 0xfb4: 0x35d5, 0xfb5: 0x35f5,\n\t0xfb6: 0x3615, 0xfb7: 0x3635, 0xfb8: 0x3655, 0xfb9: 0x3675, 0xfba: 0x3695, 0xfbb: 0x36b5,\n\t0xfbc: 0x0c19, 0xfbd: 0x0c21, 0xfbe: 0x36d5, 0xfbf: 0x0018,\n\t// Block 0x3f, offset 0xfc0\n\t0xfc0: 0x36f5, 0xfc1: 0x3715, 0xfc2: 0x3735, 0xfc3: 0x3755, 0xfc4: 0x3775, 0xfc5: 0x3795,\n\t0xfc6: 0x37b5, 0xfc7: 0x37d5, 0xfc8: 0x37f5, 0xfc9: 0x3815, 0xfca: 0x3835, 0xfcb: 0x3855,\n\t0xfcc: 0x3875, 0xfcd: 0x3895, 0xfce: 0x38b5, 0xfcf: 0x38d5, 0xfd0: 0x38f5, 0xfd1: 0x3915,\n\t0xfd2: 0x3935, 0xfd3: 0x3955, 0xfd4: 0x3975, 0xfd5: 0x3995, 0xfd6: 0x39b5, 0xfd7: 0x39d5,\n\t0xfd8: 0x39f5, 0xfd9: 0x3a15, 0xfda: 0x3a35, 0xfdb: 0x3a55, 0xfdc: 0x3a75, 0xfdd: 0x3a95,\n\t0xfde: 0x3ab5, 0xfdf: 0x3ad5, 0xfe0: 0x3af5, 0xfe1: 0x3b15, 0xfe2: 0x3b35, 0xfe3: 0x3b55,\n\t0xfe4: 0x3b75, 0xfe5: 0x3b95, 0xfe6: 0x1295, 0xfe7: 0x3bb5, 0xfe8: 0x3bd5, 0xfe9: 0x3bf5,\n\t0xfea: 0x3c15, 0xfeb: 0x3c35, 0xfec: 0x3c55, 0xfed: 0x3c75, 0xfee: 0x23b5, 0xfef: 0x3c95,\n\t0xff0: 0x3cb5, 0xff1: 0x0c29, 0xff2: 0x0c31, 0xff3: 0x0c39, 0xff4: 0x0c41, 0xff5: 0x0c49,\n\t0xff6: 0x0c51, 0xff7: 0x0c59, 0xff8: 0x0c61, 0xff9: 0x0c69, 0xffa: 0x0c71, 0xffb: 0x0c79,\n\t0xffc: 0x0c81, 0xffd: 0x0c89, 0xffe: 0x0c91, 0xfff: 0x0c99,\n\t// Block 0x40, offset 0x1000\n\t0x1000: 0x0ca1, 0x1001: 0x0ca9, 0x1002: 0x0cb1, 0x1003: 0x0cb9, 0x1004: 0x0cc1, 0x1005: 0x0cc9,\n\t0x1006: 0x0cd1, 0x1007: 0x0cd9, 0x1008: 0x0ce1, 0x1009: 0x0ce9, 0x100a: 0x0cf1, 0x100b: 0x0cf9,\n\t0x100c: 0x0d01, 0x100d: 0x3cd5, 0x100e: 0x0d09, 0x100f: 0x3cf5, 0x1010: 0x3d15, 0x1011: 0x3d2d,\n\t0x1012: 0x3d45, 0x1013: 0x3d5d, 0x1014: 0x3d75, 0x1015: 0x3d75, 0x1016: 0x3d5d, 0x1017: 0x3d8d,\n\t0x1018: 0x07d5, 0x1019: 0x3da5, 0x101a: 0x3dbd, 0x101b: 0x3dd5, 0x101c: 0x3ded, 0x101d: 0x3e05,\n\t0x101e: 0x3e1d, 0x101f: 0x3e35, 0x1020: 0x3e4d, 0x1021: 0x3e65, 0x1022: 0x3e7d, 0x1023: 0x3e95,\n\t0x1024: 0x3ead, 0x1025: 0x3ead, 0x1026: 0x3ec5, 0x1027: 0x3ec5, 0x1028: 0x3edd, 0x1029: 0x3edd,\n\t0x102a: 0x3ef5, 0x102b: 0x3f0d, 0x102c: 0x3f25, 0x102d: 0x3f3d, 0x102e: 0x3f55, 0x102f: 0x3f55,\n\t0x1030: 0x3f6d, 0x1031: 0x3f6d, 0x1032: 0x3f6d, 0x1033: 0x3f85, 0x1034: 0x3f9d, 0x1035: 0x3fb5,\n\t0x1036: 0x3fcd, 0x1037: 0x3fb5, 0x1038: 0x3fe5, 0x1039: 0x3ffd, 0x103a: 0x3f85, 0x103b: 0x4015,\n\t0x103c: 0x402d, 0x103d: 0x402d, 0x103e: 0x402d, 0x103f: 0x0d11,\n\t// Block 0x41, offset 0x1040\n\t0x1040: 0x10f9, 0x1041: 0x1101, 0x1042: 0x40a5, 0x1043: 0x1109, 0x1044: 0x1111, 0x1045: 0x1119,\n\t0x1046: 0x1121, 0x1047: 0x1129, 0x1048: 0x40c5, 0x1049: 0x1131, 0x104a: 0x1139, 0x104b: 0x1141,\n\t0x104c: 0x40e5, 0x104d: 0x40e5, 0x104e: 0x1149, 0x104f: 0x1151, 0x1050: 0x1159, 0x1051: 0x4105,\n\t0x1052: 0x4125, 0x1053: 0x4145, 0x1054: 0x4165, 0x1055: 0x4185, 0x1056: 0x1161, 0x1057: 0x1169,\n\t0x1058: 0x1171, 0x1059: 0x1179, 0x105a: 0x1181, 0x105b: 0x41a5, 0x105c: 0x1189, 0x105d: 0x1191,\n\t0x105e: 0x1199, 0x105f: 0x41c5, 0x1060: 0x41e5, 0x1061: 0x11a1, 0x1062: 0x4205, 0x1063: 0x4225,\n\t0x1064: 0x4245, 0x1065: 0x11a9, 0x1066: 0x4265, 0x1067: 0x11b1, 0x1068: 0x11b9, 0x1069: 0x10f9,\n\t0x106a: 0x4285, 0x106b: 0x42a5, 0x106c: 0x42c5, 0x106d: 0x42e5, 0x106e: 0x11c1, 0x106f: 0x11c9,\n\t0x1070: 0x11d1, 0x1071: 0x11d9, 0x1072: 0x4305, 0x1073: 0x11e1, 0x1074: 0x11e9, 0x1075: 0x11f1,\n\t0x1076: 0x4325, 0x1077: 0x11f9, 0x1078: 0x1201, 0x1079: 0x11f9, 0x107a: 0x1209, 0x107b: 0x1211,\n\t0x107c: 0x4345, 0x107d: 0x1219, 0x107e: 0x1221, 0x107f: 0x1219,\n\t// Block 0x42, offset 0x1080\n\t0x1080: 0x4365, 0x1081: 0x4385, 0x1082: 0x0040, 0x1083: 0x1229, 0x1084: 0x1231, 0x1085: 0x1239,\n\t0x1086: 0x1241, 0x1087: 0x0040, 0x1088: 0x1249, 0x1089: 0x1251, 0x108a: 0x1259, 0x108b: 0x1261,\n\t0x108c: 0x1269, 0x108d: 0x1271, 0x108e: 0x1199, 0x108f: 0x1279, 0x1090: 0x1281, 0x1091: 0x1289,\n\t0x1092: 0x43a5, 0x1093: 0x1291, 0x1094: 0x1121, 0x1095: 0x43c5, 0x1096: 0x43e5, 0x1097: 0x1299,\n\t0x1098: 0x0040, 0x1099: 0x4405, 0x109a: 0x12a1, 0x109b: 0x12a9, 0x109c: 0x12b1, 0x109d: 0x12b9,\n\t0x109e: 0x12c1, 0x109f: 0x12c9, 0x10a0: 0x12d1, 0x10a1: 0x12d9, 0x10a2: 0x12e1, 0x10a3: 0x12e9,\n\t0x10a4: 0x12f1, 0x10a5: 0x12f9, 0x10a6: 0x1301, 0x10a7: 0x1309, 0x10a8: 0x1311, 0x10a9: 0x1319,\n\t0x10aa: 0x1321, 0x10ab: 0x1329, 0x10ac: 0x1331, 0x10ad: 0x1339, 0x10ae: 0x1341, 0x10af: 0x1349,\n\t0x10b0: 0x1351, 0x10b1: 0x1359, 0x10b2: 0x1361, 0x10b3: 0x1369, 0x10b4: 0x1371, 0x10b5: 0x1379,\n\t0x10b6: 0x1381, 0x10b7: 0x1389, 0x10b8: 0x1391, 0x10b9: 0x1399, 0x10ba: 0x13a1, 0x10bb: 0x13a9,\n\t0x10bc: 0x13b1, 0x10bd: 0x13b9, 0x10be: 0x13c1, 0x10bf: 0x4425,\n\t// Block 0x43, offset 0x10c0\n\t0x10c0: 0xe00d, 0x10c1: 0x0008, 0x10c2: 0xe00d, 0x10c3: 0x0008, 0x10c4: 0xe00d, 0x10c5: 0x0008,\n\t0x10c6: 0xe00d, 0x10c7: 0x0008, 0x10c8: 0xe00d, 0x10c9: 0x0008, 0x10ca: 0xe00d, 0x10cb: 0x0008,\n\t0x10cc: 0xe00d, 0x10cd: 0x0008, 0x10ce: 0xe00d, 0x10cf: 0x0008, 0x10d0: 0xe00d, 0x10d1: 0x0008,\n\t0x10d2: 0xe00d, 0x10d3: 0x0008, 0x10d4: 0xe00d, 0x10d5: 0x0008, 0x10d6: 0xe00d, 0x10d7: 0x0008,\n\t0x10d8: 0xe00d, 0x10d9: 0x0008, 0x10da: 0xe00d, 0x10db: 0x0008, 0x10dc: 0xe00d, 0x10dd: 0x0008,\n\t0x10de: 0xe00d, 0x10df: 0x0008, 0x10e0: 0xe00d, 0x10e1: 0x0008, 0x10e2: 0xe00d, 0x10e3: 0x0008,\n\t0x10e4: 0xe00d, 0x10e5: 0x0008, 0x10e6: 0xe00d, 0x10e7: 0x0008, 0x10e8: 0xe00d, 0x10e9: 0x0008,\n\t0x10ea: 0xe00d, 0x10eb: 0x0008, 0x10ec: 0xe00d, 0x10ed: 0x0008, 0x10ee: 0x0008, 0x10ef: 0x3308,\n\t0x10f0: 0x3318, 0x10f1: 0x3318, 0x10f2: 0x3318, 0x10f3: 0x0018, 0x10f4: 0x3308, 0x10f5: 0x3308,\n\t0x10f6: 0x3308, 0x10f7: 0x3308, 0x10f8: 0x3308, 0x10f9: 0x3308, 0x10fa: 0x3308, 0x10fb: 0x3308,\n\t0x10fc: 0x3308, 0x10fd: 0x3308, 0x10fe: 0x0018, 0x10ff: 0x0008,\n\t// Block 0x44, offset 0x1100\n\t0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008,\n\t0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008,\n\t0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008,\n\t0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008,\n\t0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0x02d1, 0x111d: 0x13c9,\n\t0x111e: 0x3308, 0x111f: 0x3308, 0x1120: 0x0008, 0x1121: 0x0008, 0x1122: 0x0008, 0x1123: 0x0008,\n\t0x1124: 0x0008, 0x1125: 0x0008, 0x1126: 0x0008, 0x1127: 0x0008, 0x1128: 0x0008, 0x1129: 0x0008,\n\t0x112a: 0x0008, 0x112b: 0x0008, 0x112c: 0x0008, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x0008,\n\t0x1130: 0x0008, 0x1131: 0x0008, 0x1132: 0x0008, 0x1133: 0x0008, 0x1134: 0x0008, 0x1135: 0x0008,\n\t0x1136: 0x0008, 0x1137: 0x0008, 0x1138: 0x0008, 0x1139: 0x0008, 0x113a: 0x0008, 0x113b: 0x0008,\n\t0x113c: 0x0008, 0x113d: 0x0008, 0x113e: 0x0008, 0x113f: 0x0008,\n\t// Block 0x45, offset 0x1140\n\t0x1140: 0x0018, 0x1141: 0x0018, 0x1142: 0x0018, 0x1143: 0x0018, 0x1144: 0x0018, 0x1145: 0x0018,\n\t0x1146: 0x0018, 0x1147: 0x0018, 0x1148: 0x0018, 0x1149: 0x0018, 0x114a: 0x0018, 0x114b: 0x0018,\n\t0x114c: 0x0018, 0x114d: 0x0018, 0x114e: 0x0018, 0x114f: 0x0018, 0x1150: 0x0018, 0x1151: 0x0018,\n\t0x1152: 0x0018, 0x1153: 0x0018, 0x1154: 0x0018, 0x1155: 0x0018, 0x1156: 0x0018, 0x1157: 0x0008,\n\t0x1158: 0x0008, 0x1159: 0x0008, 0x115a: 0x0008, 0x115b: 0x0008, 0x115c: 0x0008, 0x115d: 0x0008,\n\t0x115e: 0x0008, 0x115f: 0x0008, 0x1160: 0x0018, 0x1161: 0x0018, 0x1162: 0xe00d, 0x1163: 0x0008,\n\t0x1164: 0xe00d, 0x1165: 0x0008, 0x1166: 0xe00d, 0x1167: 0x0008, 0x1168: 0xe00d, 0x1169: 0x0008,\n\t0x116a: 0xe00d, 0x116b: 0x0008, 0x116c: 0xe00d, 0x116d: 0x0008, 0x116e: 0xe00d, 0x116f: 0x0008,\n\t0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0xe00d, 0x1173: 0x0008, 0x1174: 0xe00d, 0x1175: 0x0008,\n\t0x1176: 0xe00d, 0x1177: 0x0008, 0x1178: 0xe00d, 0x1179: 0x0008, 0x117a: 0xe00d, 0x117b: 0x0008,\n\t0x117c: 0xe00d, 0x117d: 0x0008, 0x117e: 0xe00d, 0x117f: 0x0008,\n\t// Block 0x46, offset 0x1180\n\t0x1180: 0xe00d, 0x1181: 0x0008, 0x1182: 0xe00d, 0x1183: 0x0008, 0x1184: 0xe00d, 0x1185: 0x0008,\n\t0x1186: 0xe00d, 0x1187: 0x0008, 0x1188: 0xe00d, 0x1189: 0x0008, 0x118a: 0xe00d, 0x118b: 0x0008,\n\t0x118c: 0xe00d, 0x118d: 0x0008, 0x118e: 0xe00d, 0x118f: 0x0008, 0x1190: 0xe00d, 0x1191: 0x0008,\n\t0x1192: 0xe00d, 0x1193: 0x0008, 0x1194: 0xe00d, 0x1195: 0x0008, 0x1196: 0xe00d, 0x1197: 0x0008,\n\t0x1198: 0xe00d, 0x1199: 0x0008, 0x119a: 0xe00d, 0x119b: 0x0008, 0x119c: 0xe00d, 0x119d: 0x0008,\n\t0x119e: 0xe00d, 0x119f: 0x0008, 0x11a0: 0xe00d, 0x11a1: 0x0008, 0x11a2: 0xe00d, 0x11a3: 0x0008,\n\t0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008,\n\t0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008,\n\t0x11b0: 0xe0fd, 0x11b1: 0x0008, 0x11b2: 0x0008, 0x11b3: 0x0008, 0x11b4: 0x0008, 0x11b5: 0x0008,\n\t0x11b6: 0x0008, 0x11b7: 0x0008, 0x11b8: 0x0008, 0x11b9: 0xe01d, 0x11ba: 0x0008, 0x11bb: 0xe03d,\n\t0x11bc: 0x0008, 0x11bd: 0x4445, 0x11be: 0xe00d, 0x11bf: 0x0008,\n\t// Block 0x47, offset 0x11c0\n\t0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008,\n\t0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0x0008, 0x11c9: 0x0018, 0x11ca: 0x0018, 0x11cb: 0xe03d,\n\t0x11cc: 0x0008, 0x11cd: 0x0409, 0x11ce: 0x0008, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008,\n\t0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0x0008, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008,\n\t0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008,\n\t0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008,\n\t0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008,\n\t0x11ea: 0x13d1, 0x11eb: 0x0371, 0x11ec: 0x0401, 0x11ed: 0x13d9, 0x11ee: 0x0421, 0x11ef: 0x0008,\n\t0x11f0: 0x13e1, 0x11f1: 0x13e9, 0x11f2: 0x0429, 0x11f3: 0x4465, 0x11f4: 0xe00d, 0x11f5: 0x0008,\n\t0x11f6: 0xe00d, 0x11f7: 0x0008, 0x11f8: 0xe00d, 0x11f9: 0x0008, 0x11fa: 0xe00d, 0x11fb: 0x0008,\n\t0x11fc: 0xe00d, 0x11fd: 0x0008, 0x11fe: 0xe00d, 0x11ff: 0x0008,\n\t// Block 0x48, offset 0x1200\n\t0x1200: 0xe00d, 0x1201: 0x0008, 0x1202: 0xe00d, 0x1203: 0x0008, 0x1204: 0x03f5, 0x1205: 0x0479,\n\t0x1206: 0x447d, 0x1207: 0xe07d, 0x1208: 0x0008, 0x1209: 0xe01d, 0x120a: 0x0008, 0x120b: 0x0040,\n\t0x120c: 0x0040, 0x120d: 0x0040, 0x120e: 0x0040, 0x120f: 0x0040, 0x1210: 0xe00d, 0x1211: 0x0008,\n\t0x1212: 0x0040, 0x1213: 0x0008, 0x1214: 0x0040, 0x1215: 0x0008, 0x1216: 0xe00d, 0x1217: 0x0008,\n\t0x1218: 0xe00d, 0x1219: 0x0008, 0x121a: 0x0040, 0x121b: 0x0040, 0x121c: 0x0040, 0x121d: 0x0040,\n\t0x121e: 0x0040, 0x121f: 0x0040, 0x1220: 0x0040, 0x1221: 0x0040, 0x1222: 0x0040, 0x1223: 0x0040,\n\t0x1224: 0x0040, 0x1225: 0x0040, 0x1226: 0x0040, 0x1227: 0x0040, 0x1228: 0x0040, 0x1229: 0x0040,\n\t0x122a: 0x0040, 0x122b: 0x0040, 0x122c: 0x0040, 0x122d: 0x0040, 0x122e: 0x0040, 0x122f: 0x0040,\n\t0x1230: 0x0040, 0x1231: 0x0040, 0x1232: 0x03d9, 0x1233: 0x03f1, 0x1234: 0x0751, 0x1235: 0xe01d,\n\t0x1236: 0x0008, 0x1237: 0x0008, 0x1238: 0x0741, 0x1239: 0x13f1, 0x123a: 0x0008, 0x123b: 0x0008,\n\t0x123c: 0x0008, 0x123d: 0x0008, 0x123e: 0x0008, 0x123f: 0x0008,\n\t// Block 0x49, offset 0x1240\n\t0x1240: 0x650d, 0x1241: 0x652d, 0x1242: 0x654d, 0x1243: 0x656d, 0x1244: 0x658d, 0x1245: 0x65ad,\n\t0x1246: 0x65cd, 0x1247: 0x65ed, 0x1248: 0x660d, 0x1249: 0x662d, 0x124a: 0x664d, 0x124b: 0x666d,\n\t0x124c: 0x668d, 0x124d: 0x66ad, 0x124e: 0x0008, 0x124f: 0x0008, 0x1250: 0x66cd, 0x1251: 0x0008,\n\t0x1252: 0x66ed, 0x1253: 0x0008, 0x1254: 0x0008, 0x1255: 0x670d, 0x1256: 0x672d, 0x1257: 0x674d,\n\t0x1258: 0x676d, 0x1259: 0x678d, 0x125a: 0x67ad, 0x125b: 0x67cd, 0x125c: 0x67ed, 0x125d: 0x680d,\n\t0x125e: 0x682d, 0x125f: 0x0008, 0x1260: 0x684d, 0x1261: 0x0008, 0x1262: 0x686d, 0x1263: 0x0008,\n\t0x1264: 0x0008, 0x1265: 0x688d, 0x1266: 0x68ad, 0x1267: 0x0008, 0x1268: 0x0008, 0x1269: 0x0008,\n\t0x126a: 0x68cd, 0x126b: 0x68ed, 0x126c: 0x690d, 0x126d: 0x692d, 0x126e: 0x694d, 0x126f: 0x696d,\n\t0x1270: 0x698d, 0x1271: 0x69ad, 0x1272: 0x69cd, 0x1273: 0x69ed, 0x1274: 0x6a0d, 0x1275: 0x6a2d,\n\t0x1276: 0x6a4d, 0x1277: 0x6a6d, 0x1278: 0x6a8d, 0x1279: 0x6aad, 0x127a: 0x6acd, 0x127b: 0x6aed,\n\t0x127c: 0x6b0d, 0x127d: 0x6b2d, 0x127e: 0x6b4d, 0x127f: 0x6b6d,\n\t// Block 0x4a, offset 0x1280\n\t0x1280: 0x7acd, 0x1281: 0x7aed, 0x1282: 0x7b0d, 0x1283: 0x7b2d, 0x1284: 0x7b4d, 0x1285: 0x7b6d,\n\t0x1286: 0x7b8d, 0x1287: 0x7bad, 0x1288: 0x7bcd, 0x1289: 0x7bed, 0x128a: 0x7c0d, 0x128b: 0x7c2d,\n\t0x128c: 0x7c4d, 0x128d: 0x7c6d, 0x128e: 0x7c8d, 0x128f: 0x1409, 0x1290: 0x1411, 0x1291: 0x1419,\n\t0x1292: 0x7cad, 0x1293: 0x7ccd, 0x1294: 0x7ced, 0x1295: 0x1421, 0x1296: 0x1429, 0x1297: 0x1431,\n\t0x1298: 0x7d0d, 0x1299: 0x7d2d, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x0040,\n\t0x129e: 0x0040, 0x129f: 0x0040, 0x12a0: 0x0040, 0x12a1: 0x0040, 0x12a2: 0x0040, 0x12a3: 0x0040,\n\t0x12a4: 0x0040, 0x12a5: 0x0040, 0x12a6: 0x0040, 0x12a7: 0x0040, 0x12a8: 0x0040, 0x12a9: 0x0040,\n\t0x12aa: 0x0040, 0x12ab: 0x0040, 0x12ac: 0x0040, 0x12ad: 0x0040, 0x12ae: 0x0040, 0x12af: 0x0040,\n\t0x12b0: 0x0040, 0x12b1: 0x0040, 0x12b2: 0x0040, 0x12b3: 0x0040, 0x12b4: 0x0040, 0x12b5: 0x0040,\n\t0x12b6: 0x0040, 0x12b7: 0x0040, 0x12b8: 0x0040, 0x12b9: 0x0040, 0x12ba: 0x0040, 0x12bb: 0x0040,\n\t0x12bc: 0x0040, 0x12bd: 0x0040, 0x12be: 0x0040, 0x12bf: 0x0040,\n\t// Block 0x4b, offset 0x12c0\n\t0x12c0: 0x1439, 0x12c1: 0x1441, 0x12c2: 0x1449, 0x12c3: 0x7d4d, 0x12c4: 0x7d6d, 0x12c5: 0x1451,\n\t0x12c6: 0x1451, 0x12c7: 0x0040, 0x12c8: 0x0040, 0x12c9: 0x0040, 0x12ca: 0x0040, 0x12cb: 0x0040,\n\t0x12cc: 0x0040, 0x12cd: 0x0040, 0x12ce: 0x0040, 0x12cf: 0x0040, 0x12d0: 0x0040, 0x12d1: 0x0040,\n\t0x12d2: 0x0040, 0x12d3: 0x1459, 0x12d4: 0x1461, 0x12d5: 0x1469, 0x12d6: 0x1471, 0x12d7: 0x1479,\n\t0x12d8: 0x0040, 0x12d9: 0x0040, 0x12da: 0x0040, 0x12db: 0x0040, 0x12dc: 0x0040, 0x12dd: 0x1481,\n\t0x12de: 0x3308, 0x12df: 0x1489, 0x12e0: 0x1491, 0x12e1: 0x0779, 0x12e2: 0x0791, 0x12e3: 0x1499,\n\t0x12e4: 0x14a1, 0x12e5: 0x14a9, 0x12e6: 0x14b1, 0x12e7: 0x14b9, 0x12e8: 0x14c1, 0x12e9: 0x071a,\n\t0x12ea: 0x14c9, 0x12eb: 0x14d1, 0x12ec: 0x14d9, 0x12ed: 0x14e1, 0x12ee: 0x14e9, 0x12ef: 0x14f1,\n\t0x12f0: 0x14f9, 0x12f1: 0x1501, 0x12f2: 0x1509, 0x12f3: 0x1511, 0x12f4: 0x1519, 0x12f5: 0x1521,\n\t0x12f6: 0x1529, 0x12f7: 0x0040, 0x12f8: 0x1531, 0x12f9: 0x1539, 0x12fa: 0x1541, 0x12fb: 0x1549,\n\t0x12fc: 0x1551, 0x12fd: 0x0040, 0x12fe: 0x1559, 0x12ff: 0x0040,\n\t// Block 0x4c, offset 0x1300\n\t0x1300: 0x1561, 0x1301: 0x1569, 0x1302: 0x0040, 0x1303: 0x1571, 0x1304: 0x1579, 0x1305: 0x0040,\n\t0x1306: 0x1581, 0x1307: 0x1589, 0x1308: 0x1591, 0x1309: 0x1599, 0x130a: 0x15a1, 0x130b: 0x15a9,\n\t0x130c: 0x15b1, 0x130d: 0x15b9, 0x130e: 0x15c1, 0x130f: 0x15c9, 0x1310: 0x15d1, 0x1311: 0x15d1,\n\t0x1312: 0x15d9, 0x1313: 0x15d9, 0x1314: 0x15d9, 0x1315: 0x15d9, 0x1316: 0x15e1, 0x1317: 0x15e1,\n\t0x1318: 0x15e1, 0x1319: 0x15e1, 0x131a: 0x15e9, 0x131b: 0x15e9, 0x131c: 0x15e9, 0x131d: 0x15e9,\n\t0x131e: 0x15f1, 0x131f: 0x15f1, 0x1320: 0x15f1, 0x1321: 0x15f1, 0x1322: 0x15f9, 0x1323: 0x15f9,\n\t0x1324: 0x15f9, 0x1325: 0x15f9, 0x1326: 0x1601, 0x1327: 0x1601, 0x1328: 0x1601, 0x1329: 0x1601,\n\t0x132a: 0x1609, 0x132b: 0x1609, 0x132c: 0x1609, 0x132d: 0x1609, 0x132e: 0x1611, 0x132f: 0x1611,\n\t0x1330: 0x1611, 0x1331: 0x1611, 0x1332: 0x1619, 0x1333: 0x1619, 0x1334: 0x1619, 0x1335: 0x1619,\n\t0x1336: 0x1621, 0x1337: 0x1621, 0x1338: 0x1621, 0x1339: 0x1621, 0x133a: 0x1629, 0x133b: 0x1629,\n\t0x133c: 0x1629, 0x133d: 0x1629, 0x133e: 0x1631, 0x133f: 0x1631,\n\t// Block 0x4d, offset 0x1340\n\t0x1340: 0x1631, 0x1341: 0x1631, 0x1342: 0x1639, 0x1343: 0x1639, 0x1344: 0x1641, 0x1345: 0x1641,\n\t0x1346: 0x1649, 0x1347: 0x1649, 0x1348: 0x1651, 0x1349: 0x1651, 0x134a: 0x1659, 0x134b: 0x1659,\n\t0x134c: 0x1661, 0x134d: 0x1661, 0x134e: 0x1669, 0x134f: 0x1669, 0x1350: 0x1669, 0x1351: 0x1669,\n\t0x1352: 0x1671, 0x1353: 0x1671, 0x1354: 0x1671, 0x1355: 0x1671, 0x1356: 0x1679, 0x1357: 0x1679,\n\t0x1358: 0x1679, 0x1359: 0x1679, 0x135a: 0x1681, 0x135b: 0x1681, 0x135c: 0x1681, 0x135d: 0x1681,\n\t0x135e: 0x1689, 0x135f: 0x1689, 0x1360: 0x1691, 0x1361: 0x1691, 0x1362: 0x1691, 0x1363: 0x1691,\n\t0x1364: 0x1699, 0x1365: 0x1699, 0x1366: 0x16a1, 0x1367: 0x16a1, 0x1368: 0x16a1, 0x1369: 0x16a1,\n\t0x136a: 0x16a9, 0x136b: 0x16a9, 0x136c: 0x16a9, 0x136d: 0x16a9, 0x136e: 0x16b1, 0x136f: 0x16b1,\n\t0x1370: 0x16b9, 0x1371: 0x16b9, 0x1372: 0x0818, 0x1373: 0x0818, 0x1374: 0x0818, 0x1375: 0x0818,\n\t0x1376: 0x0818, 0x1377: 0x0818, 0x1378: 0x0818, 0x1379: 0x0818, 0x137a: 0x0818, 0x137b: 0x0818,\n\t0x137c: 0x0818, 0x137d: 0x0818, 0x137e: 0x0818, 0x137f: 0x0818,\n\t// Block 0x4e, offset 0x1380\n\t0x1380: 0x0818, 0x1381: 0x0818, 0x1382: 0x0818, 0x1383: 0x0040, 0x1384: 0x0040, 0x1385: 0x0040,\n\t0x1386: 0x0040, 0x1387: 0x0040, 0x1388: 0x0040, 0x1389: 0x0040, 0x138a: 0x0040, 0x138b: 0x0040,\n\t0x138c: 0x0040, 0x138d: 0x0040, 0x138e: 0x0040, 0x138f: 0x0040, 0x1390: 0x0040, 0x1391: 0x0040,\n\t0x1392: 0x0040, 0x1393: 0x16c1, 0x1394: 0x16c1, 0x1395: 0x16c1, 0x1396: 0x16c1, 0x1397: 0x16c9,\n\t0x1398: 0x16c9, 0x1399: 0x16d1, 0x139a: 0x16d1, 0x139b: 0x16d9, 0x139c: 0x16d9, 0x139d: 0x0149,\n\t0x139e: 0x16e1, 0x139f: 0x16e1, 0x13a0: 0x16e9, 0x13a1: 0x16e9, 0x13a2: 0x16f1, 0x13a3: 0x16f1,\n\t0x13a4: 0x16f9, 0x13a5: 0x16f9, 0x13a6: 0x16f9, 0x13a7: 0x16f9, 0x13a8: 0x1701, 0x13a9: 0x1701,\n\t0x13aa: 0x1709, 0x13ab: 0x1709, 0x13ac: 0x1711, 0x13ad: 0x1711, 0x13ae: 0x1719, 0x13af: 0x1719,\n\t0x13b0: 0x1721, 0x13b1: 0x1721, 0x13b2: 0x1729, 0x13b3: 0x1729, 0x13b4: 0x1731, 0x13b5: 0x1731,\n\t0x13b6: 0x1739, 0x13b7: 0x1739, 0x13b8: 0x1739, 0x13b9: 0x1741, 0x13ba: 0x1741, 0x13bb: 0x1741,\n\t0x13bc: 0x1749, 0x13bd: 0x1749, 0x13be: 0x1749, 0x13bf: 0x1749,\n\t// Block 0x4f, offset 0x13c0\n\t0x13c0: 0x1949, 0x13c1: 0x1951, 0x13c2: 0x1959, 0x13c3: 0x1961, 0x13c4: 0x1969, 0x13c5: 0x1971,\n\t0x13c6: 0x1979, 0x13c7: 0x1981, 0x13c8: 0x1989, 0x13c9: 0x1991, 0x13ca: 0x1999, 0x13cb: 0x19a1,\n\t0x13cc: 0x19a9, 0x13cd: 0x19b1, 0x13ce: 0x19b9, 0x13cf: 0x19c1, 0x13d0: 0x19c9, 0x13d1: 0x19d1,\n\t0x13d2: 0x19d9, 0x13d3: 0x19e1, 0x13d4: 0x19e9, 0x13d5: 0x19f1, 0x13d6: 0x19f9, 0x13d7: 0x1a01,\n\t0x13d8: 0x1a09, 0x13d9: 0x1a11, 0x13da: 0x1a19, 0x13db: 0x1a21, 0x13dc: 0x1a29, 0x13dd: 0x1a31,\n\t0x13de: 0x1a3a, 0x13df: 0x1a42, 0x13e0: 0x1a4a, 0x13e1: 0x1a52, 0x13e2: 0x1a5a, 0x13e3: 0x1a62,\n\t0x13e4: 0x1a69, 0x13e5: 0x1a71, 0x13e6: 0x1761, 0x13e7: 0x1a79, 0x13e8: 0x1741, 0x13e9: 0x1769,\n\t0x13ea: 0x1a81, 0x13eb: 0x1a89, 0x13ec: 0x1789, 0x13ed: 0x1a91, 0x13ee: 0x1791, 0x13ef: 0x1799,\n\t0x13f0: 0x1a99, 0x13f1: 0x1aa1, 0x13f2: 0x17b9, 0x13f3: 0x1aa9, 0x13f4: 0x17c1, 0x13f5: 0x17c9,\n\t0x13f6: 0x1ab1, 0x13f7: 0x1ab9, 0x13f8: 0x17d9, 0x13f9: 0x1ac1, 0x13fa: 0x17e1, 0x13fb: 0x17e9,\n\t0x13fc: 0x18d1, 0x13fd: 0x18d9, 0x13fe: 0x18f1, 0x13ff: 0x18f9,\n\t// Block 0x50, offset 0x1400\n\t0x1400: 0x1901, 0x1401: 0x1921, 0x1402: 0x1929, 0x1403: 0x1931, 0x1404: 0x1939, 0x1405: 0x1959,\n\t0x1406: 0x1961, 0x1407: 0x1969, 0x1408: 0x1ac9, 0x1409: 0x1989, 0x140a: 0x1ad1, 0x140b: 0x1ad9,\n\t0x140c: 0x19b9, 0x140d: 0x1ae1, 0x140e: 0x19c1, 0x140f: 0x19c9, 0x1410: 0x1a31, 0x1411: 0x1ae9,\n\t0x1412: 0x1af1, 0x1413: 0x1a09, 0x1414: 0x1af9, 0x1415: 0x1a11, 0x1416: 0x1a19, 0x1417: 0x1751,\n\t0x1418: 0x1759, 0x1419: 0x1b01, 0x141a: 0x1761, 0x141b: 0x1b09, 0x141c: 0x1771, 0x141d: 0x1779,\n\t0x141e: 0x1781, 0x141f: 0x1789, 0x1420: 0x1b11, 0x1421: 0x17a1, 0x1422: 0x17a9, 0x1423: 0x17b1,\n\t0x1424: 0x17b9, 0x1425: 0x1b19, 0x1426: 0x17d9, 0x1427: 0x17f1, 0x1428: 0x17f9, 0x1429: 0x1801,\n\t0x142a: 0x1809, 0x142b: 0x1811, 0x142c: 0x1821, 0x142d: 0x1829, 0x142e: 0x1831, 0x142f: 0x1839,\n\t0x1430: 0x1841, 0x1431: 0x1849, 0x1432: 0x1b21, 0x1433: 0x1851, 0x1434: 0x1859, 0x1435: 0x1861,\n\t0x1436: 0x1869, 0x1437: 0x1871, 0x1438: 0x1879, 0x1439: 0x1889, 0x143a: 0x1891, 0x143b: 0x1899,\n\t0x143c: 0x18a1, 0x143d: 0x18a9, 0x143e: 0x18b1, 0x143f: 0x18b9,\n\t// Block 0x51, offset 0x1440\n\t0x1440: 0x18c1, 0x1441: 0x18c9, 0x1442: 0x18e1, 0x1443: 0x18e9, 0x1444: 0x1909, 0x1445: 0x1911,\n\t0x1446: 0x1919, 0x1447: 0x1921, 0x1448: 0x1929, 0x1449: 0x1941, 0x144a: 0x1949, 0x144b: 0x1951,\n\t0x144c: 0x1959, 0x144d: 0x1b29, 0x144e: 0x1971, 0x144f: 0x1979, 0x1450: 0x1981, 0x1451: 0x1989,\n\t0x1452: 0x19a1, 0x1453: 0x19a9, 0x1454: 0x19b1, 0x1455: 0x19b9, 0x1456: 0x1b31, 0x1457: 0x19d1,\n\t0x1458: 0x19d9, 0x1459: 0x1b39, 0x145a: 0x19f1, 0x145b: 0x19f9, 0x145c: 0x1a01, 0x145d: 0x1a09,\n\t0x145e: 0x1b41, 0x145f: 0x1761, 0x1460: 0x1b09, 0x1461: 0x1789, 0x1462: 0x1b11, 0x1463: 0x17b9,\n\t0x1464: 0x1b19, 0x1465: 0x17d9, 0x1466: 0x1b49, 0x1467: 0x1841, 0x1468: 0x1b51, 0x1469: 0x1b59,\n\t0x146a: 0x1b61, 0x146b: 0x1921, 0x146c: 0x1929, 0x146d: 0x1959, 0x146e: 0x19b9, 0x146f: 0x1b31,\n\t0x1470: 0x1a09, 0x1471: 0x1b41, 0x1472: 0x1b69, 0x1473: 0x1b71, 0x1474: 0x1b79, 0x1475: 0x1b81,\n\t0x1476: 0x1b89, 0x1477: 0x1b91, 0x1478: 0x1b99, 0x1479: 0x1ba1, 0x147a: 0x1ba9, 0x147b: 0x1bb1,\n\t0x147c: 0x1bb9, 0x147d: 0x1bc1, 0x147e: 0x1bc9, 0x147f: 0x1bd1,\n\t// Block 0x52, offset 0x1480\n\t0x1480: 0x1bd9, 0x1481: 0x1be1, 0x1482: 0x1be9, 0x1483: 0x1bf1, 0x1484: 0x1bf9, 0x1485: 0x1c01,\n\t0x1486: 0x1c09, 0x1487: 0x1c11, 0x1488: 0x1c19, 0x1489: 0x1c21, 0x148a: 0x1c29, 0x148b: 0x1c31,\n\t0x148c: 0x1b59, 0x148d: 0x1c39, 0x148e: 0x1c41, 0x148f: 0x1c49, 0x1490: 0x1c51, 0x1491: 0x1b81,\n\t0x1492: 0x1b89, 0x1493: 0x1b91, 0x1494: 0x1b99, 0x1495: 0x1ba1, 0x1496: 0x1ba9, 0x1497: 0x1bb1,\n\t0x1498: 0x1bb9, 0x1499: 0x1bc1, 0x149a: 0x1bc9, 0x149b: 0x1bd1, 0x149c: 0x1bd9, 0x149d: 0x1be1,\n\t0x149e: 0x1be9, 0x149f: 0x1bf1, 0x14a0: 0x1bf9, 0x14a1: 0x1c01, 0x14a2: 0x1c09, 0x14a3: 0x1c11,\n\t0x14a4: 0x1c19, 0x14a5: 0x1c21, 0x14a6: 0x1c29, 0x14a7: 0x1c31, 0x14a8: 0x1b59, 0x14a9: 0x1c39,\n\t0x14aa: 0x1c41, 0x14ab: 0x1c49, 0x14ac: 0x1c51, 0x14ad: 0x1c21, 0x14ae: 0x1c29, 0x14af: 0x1c31,\n\t0x14b0: 0x1b59, 0x14b1: 0x1b51, 0x14b2: 0x1b61, 0x14b3: 0x1881, 0x14b4: 0x1829, 0x14b5: 0x1831,\n\t0x14b6: 0x1839, 0x14b7: 0x1c21, 0x14b8: 0x1c29, 0x14b9: 0x1c31, 0x14ba: 0x1881, 0x14bb: 0x1889,\n\t0x14bc: 0x1c59, 0x14bd: 0x1c59, 0x14be: 0x0018, 0x14bf: 0x0018,\n\t// Block 0x53, offset 0x14c0\n\t0x14c0: 0x0018, 0x14c1: 0x0018, 0x14c2: 0x0018, 0x14c3: 0x0018, 0x14c4: 0x0018, 0x14c5: 0x0018,\n\t0x14c6: 0x0018, 0x14c7: 0x0018, 0x14c8: 0x0018, 0x14c9: 0x0018, 0x14ca: 0x0018, 0x14cb: 0x0018,\n\t0x14cc: 0x0018, 0x14cd: 0x0018, 0x14ce: 0x0018, 0x14cf: 0x0018, 0x14d0: 0x1c61, 0x14d1: 0x1c69,\n\t0x14d2: 0x1c69, 0x14d3: 0x1c71, 0x14d4: 0x1c79, 0x14d5: 0x1c81, 0x14d6: 0x1c89, 0x14d7: 0x1c91,\n\t0x14d8: 0x1c99, 0x14d9: 0x1c99, 0x14da: 0x1ca1, 0x14db: 0x1ca9, 0x14dc: 0x1cb1, 0x14dd: 0x1cb9,\n\t0x14de: 0x1cc1, 0x14df: 0x1cc9, 0x14e0: 0x1cc9, 0x14e1: 0x1cd1, 0x14e2: 0x1cd9, 0x14e3: 0x1cd9,\n\t0x14e4: 0x1ce1, 0x14e5: 0x1ce1, 0x14e6: 0x1ce9, 0x14e7: 0x1cf1, 0x14e8: 0x1cf1, 0x14e9: 0x1cf9,\n\t0x14ea: 0x1d01, 0x14eb: 0x1d01, 0x14ec: 0x1d09, 0x14ed: 0x1d09, 0x14ee: 0x1d11, 0x14ef: 0x1d19,\n\t0x14f0: 0x1d19, 0x14f1: 0x1d21, 0x14f2: 0x1d21, 0x14f3: 0x1d29, 0x14f4: 0x1d31, 0x14f5: 0x1d39,\n\t0x14f6: 0x1d41, 0x14f7: 0x1d41, 0x14f8: 0x1d49, 0x14f9: 0x1d51, 0x14fa: 0x1d59, 0x14fb: 0x1d61,\n\t0x14fc: 0x1d69, 0x14fd: 0x1d69, 0x14fe: 0x1d71, 0x14ff: 0x1d79,\n\t// Block 0x54, offset 0x1500\n\t0x1500: 0x1f29, 0x1501: 0x1f31, 0x1502: 0x1f39, 0x1503: 0x1f11, 0x1504: 0x1d39, 0x1505: 0x1ce9,\n\t0x1506: 0x1f41, 0x1507: 0x1f49, 0x1508: 0x0040, 0x1509: 0x0040, 0x150a: 0x0040, 0x150b: 0x0040,\n\t0x150c: 0x0040, 0x150d: 0x0040, 0x150e: 0x0040, 0x150f: 0x0018, 0x1510: 0x0040, 0x1511: 0x0040,\n\t0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x0040, 0x1515: 0x0040, 0x1516: 0x0040, 0x1517: 0x0040,\n\t0x1518: 0x0040, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040,\n\t0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x0040, 0x1521: 0x0040, 0x1522: 0x0040, 0x1523: 0x0040,\n\t0x1524: 0x0040, 0x1525: 0x0040, 0x1526: 0x0040, 0x1527: 0x0040, 0x1528: 0x0040, 0x1529: 0x0040,\n\t0x152a: 0x0040, 0x152b: 0x0040, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040,\n\t0x1530: 0x1f51, 0x1531: 0x1f59, 0x1532: 0x1f61, 0x1533: 0x1f69, 0x1534: 0x1f71, 0x1535: 0x1f79,\n\t0x1536: 0x1f81, 0x1537: 0x1f89, 0x1538: 0x1f91, 0x1539: 0x1f99, 0x153a: 0x1fa2, 0x153b: 0x1faa,\n\t0x153c: 0x1fb1, 0x153d: 0x0018, 0x153e: 0x0018, 0x153f: 0x0018,\n\t// Block 0x55, offset 0x1540\n\t0x1540: 0x33c0, 0x1541: 0x33c0, 0x1542: 0x33c0, 0x1543: 0x33c0, 0x1544: 0x33c0, 0x1545: 0x33c0,\n\t0x1546: 0x33c0, 0x1547: 0x33c0, 0x1548: 0x33c0, 0x1549: 0x33c0, 0x154a: 0x33c0, 0x154b: 0x33c0,\n\t0x154c: 0x33c0, 0x154d: 0x33c0, 0x154e: 0x33c0, 0x154f: 0x33c0, 0x1550: 0x1fba, 0x1551: 0x7d8d,\n\t0x1552: 0x0040, 0x1553: 0x1fc2, 0x1554: 0x0122, 0x1555: 0x1fca, 0x1556: 0x1fd2, 0x1557: 0x7dad,\n\t0x1558: 0x7dcd, 0x1559: 0x0040, 0x155a: 0x0040, 0x155b: 0x0040, 0x155c: 0x0040, 0x155d: 0x0040,\n\t0x155e: 0x0040, 0x155f: 0x0040, 0x1560: 0x3308, 0x1561: 0x3308, 0x1562: 0x3308, 0x1563: 0x3308,\n\t0x1564: 0x3308, 0x1565: 0x3308, 0x1566: 0x3308, 0x1567: 0x3308, 0x1568: 0x3308, 0x1569: 0x3308,\n\t0x156a: 0x3308, 0x156b: 0x3308, 0x156c: 0x3308, 0x156d: 0x3308, 0x156e: 0x3308, 0x156f: 0x3308,\n\t0x1570: 0x0040, 0x1571: 0x7ded, 0x1572: 0x7e0d, 0x1573: 0x1fda, 0x1574: 0x1fda, 0x1575: 0x072a,\n\t0x1576: 0x0732, 0x1577: 0x1fe2, 0x1578: 0x1fea, 0x1579: 0x7e2d, 0x157a: 0x7e4d, 0x157b: 0x7e6d,\n\t0x157c: 0x7e2d, 0x157d: 0x7e8d, 0x157e: 0x7ead, 0x157f: 0x7e8d,\n\t// Block 0x56, offset 0x1580\n\t0x1580: 0x7ecd, 0x1581: 0x7eed, 0x1582: 0x7f0d, 0x1583: 0x7eed, 0x1584: 0x7f2d, 0x1585: 0x0018,\n\t0x1586: 0x0018, 0x1587: 0x1ff2, 0x1588: 0x1ffa, 0x1589: 0x7f4e, 0x158a: 0x7f6e, 0x158b: 0x7f8e,\n\t0x158c: 0x7fae, 0x158d: 0x1fda, 0x158e: 0x1fda, 0x158f: 0x1fda, 0x1590: 0x1fba, 0x1591: 0x7fcd,\n\t0x1592: 0x0040, 0x1593: 0x0040, 0x1594: 0x0122, 0x1595: 0x1fc2, 0x1596: 0x1fd2, 0x1597: 0x1fca,\n\t0x1598: 0x7fed, 0x1599: 0x072a, 0x159a: 0x0732, 0x159b: 0x1fe2, 0x159c: 0x1fea, 0x159d: 0x7ecd,\n\t0x159e: 0x7f2d, 0x159f: 0x2002, 0x15a0: 0x200a, 0x15a1: 0x2012, 0x15a2: 0x071a, 0x15a3: 0x2019,\n\t0x15a4: 0x2022, 0x15a5: 0x202a, 0x15a6: 0x0722, 0x15a7: 0x0040, 0x15a8: 0x2032, 0x15a9: 0x203a,\n\t0x15aa: 0x2042, 0x15ab: 0x204a, 0x15ac: 0x0040, 0x15ad: 0x0040, 0x15ae: 0x0040, 0x15af: 0x0040,\n\t0x15b0: 0x800e, 0x15b1: 0x2051, 0x15b2: 0x802e, 0x15b3: 0x0808, 0x15b4: 0x804e, 0x15b5: 0x0040,\n\t0x15b6: 0x806e, 0x15b7: 0x2059, 0x15b8: 0x808e, 0x15b9: 0x2061, 0x15ba: 0x80ae, 0x15bb: 0x2069,\n\t0x15bc: 0x80ce, 0x15bd: 0x2071, 0x15be: 0x80ee, 0x15bf: 0x2079,\n\t// Block 0x57, offset 0x15c0\n\t0x15c0: 0x2081, 0x15c1: 0x2089, 0x15c2: 0x2089, 0x15c3: 0x2091, 0x15c4: 0x2091, 0x15c5: 0x2099,\n\t0x15c6: 0x2099, 0x15c7: 0x20a1, 0x15c8: 0x20a1, 0x15c9: 0x20a9, 0x15ca: 0x20a9, 0x15cb: 0x20a9,\n\t0x15cc: 0x20a9, 0x15cd: 0x20b1, 0x15ce: 0x20b1, 0x15cf: 0x20b9, 0x15d0: 0x20b9, 0x15d1: 0x20b9,\n\t0x15d2: 0x20b9, 0x15d3: 0x20c1, 0x15d4: 0x20c1, 0x15d5: 0x20c9, 0x15d6: 0x20c9, 0x15d7: 0x20c9,\n\t0x15d8: 0x20c9, 0x15d9: 0x20d1, 0x15da: 0x20d1, 0x15db: 0x20d1, 0x15dc: 0x20d1, 0x15dd: 0x20d9,\n\t0x15de: 0x20d9, 0x15df: 0x20d9, 0x15e0: 0x20d9, 0x15e1: 0x20e1, 0x15e2: 0x20e1, 0x15e3: 0x20e1,\n\t0x15e4: 0x20e1, 0x15e5: 0x20e9, 0x15e6: 0x20e9, 0x15e7: 0x20e9, 0x15e8: 0x20e9, 0x15e9: 0x20f1,\n\t0x15ea: 0x20f1, 0x15eb: 0x20f9, 0x15ec: 0x20f9, 0x15ed: 0x2101, 0x15ee: 0x2101, 0x15ef: 0x2109,\n\t0x15f0: 0x2109, 0x15f1: 0x2111, 0x15f2: 0x2111, 0x15f3: 0x2111, 0x15f4: 0x2111, 0x15f5: 0x2119,\n\t0x15f6: 0x2119, 0x15f7: 0x2119, 0x15f8: 0x2119, 0x15f9: 0x2121, 0x15fa: 0x2121, 0x15fb: 0x2121,\n\t0x15fc: 0x2121, 0x15fd: 0x2129, 0x15fe: 0x2129, 0x15ff: 0x2129,\n\t// Block 0x58, offset 0x1600\n\t0x1600: 0x2129, 0x1601: 0x2131, 0x1602: 0x2131, 0x1603: 0x2131, 0x1604: 0x2131, 0x1605: 0x2139,\n\t0x1606: 0x2139, 0x1607: 0x2139, 0x1608: 0x2139, 0x1609: 0x2141, 0x160a: 0x2141, 0x160b: 0x2141,\n\t0x160c: 0x2141, 0x160d: 0x2149, 0x160e: 0x2149, 0x160f: 0x2149, 0x1610: 0x2149, 0x1611: 0x2151,\n\t0x1612: 0x2151, 0x1613: 0x2151, 0x1614: 0x2151, 0x1615: 0x2159, 0x1616: 0x2159, 0x1617: 0x2159,\n\t0x1618: 0x2159, 0x1619: 0x2161, 0x161a: 0x2161, 0x161b: 0x2161, 0x161c: 0x2161, 0x161d: 0x2169,\n\t0x161e: 0x2169, 0x161f: 0x2169, 0x1620: 0x2169, 0x1621: 0x2171, 0x1622: 0x2171, 0x1623: 0x2171,\n\t0x1624: 0x2171, 0x1625: 0x2179, 0x1626: 0x2179, 0x1627: 0x2179, 0x1628: 0x2179, 0x1629: 0x2181,\n\t0x162a: 0x2181, 0x162b: 0x2181, 0x162c: 0x2181, 0x162d: 0x2189, 0x162e: 0x2189, 0x162f: 0x1701,\n\t0x1630: 0x1701, 0x1631: 0x2191, 0x1632: 0x2191, 0x1633: 0x2191, 0x1634: 0x2191, 0x1635: 0x2199,\n\t0x1636: 0x2199, 0x1637: 0x21a1, 0x1638: 0x21a1, 0x1639: 0x21a9, 0x163a: 0x21a9, 0x163b: 0x21b1,\n\t0x163c: 0x21b1, 0x163d: 0x0040, 0x163e: 0x0040, 0x163f: 0x03c0,\n\t// Block 0x59, offset 0x1640\n\t0x1640: 0x0040, 0x1641: 0x1fca, 0x1642: 0x21ba, 0x1643: 0x2002, 0x1644: 0x203a, 0x1645: 0x2042,\n\t0x1646: 0x200a, 0x1647: 0x21c2, 0x1648: 0x072a, 0x1649: 0x0732, 0x164a: 0x2012, 0x164b: 0x071a,\n\t0x164c: 0x1fba, 0x164d: 0x2019, 0x164e: 0x0961, 0x164f: 0x21ca, 0x1650: 0x06e1, 0x1651: 0x0049,\n\t0x1652: 0x0029, 0x1653: 0x0031, 0x1654: 0x06e9, 0x1655: 0x06f1, 0x1656: 0x06f9, 0x1657: 0x0701,\n\t0x1658: 0x0709, 0x1659: 0x0711, 0x165a: 0x1fc2, 0x165b: 0x0122, 0x165c: 0x2022, 0x165d: 0x0722,\n\t0x165e: 0x202a, 0x165f: 0x1fd2, 0x1660: 0x204a, 0x1661: 0x0019, 0x1662: 0x02e9, 0x1663: 0x03d9,\n\t0x1664: 0x02f1, 0x1665: 0x02f9, 0x1666: 0x03f1, 0x1667: 0x0309, 0x1668: 0x00a9, 0x1669: 0x0311,\n\t0x166a: 0x00b1, 0x166b: 0x0319, 0x166c: 0x0101, 0x166d: 0x0321, 0x166e: 0x0329, 0x166f: 0x0051,\n\t0x1670: 0x0339, 0x1671: 0x0751, 0x1672: 0x00b9, 0x1673: 0x0089, 0x1674: 0x0341, 0x1675: 0x0349,\n\t0x1676: 0x0391, 0x1677: 0x00c1, 0x1678: 0x0109, 0x1679: 0x00c9, 0x167a: 0x04b1, 0x167b: 0x1ff2,\n\t0x167c: 0x2032, 0x167d: 0x1ffa, 0x167e: 0x21d2, 0x167f: 0x1fda,\n\t// Block 0x5a, offset 0x1680\n\t0x1680: 0x0672, 0x1681: 0x0019, 0x1682: 0x02e9, 0x1683: 0x03d9, 0x1684: 0x02f1, 0x1685: 0x02f9,\n\t0x1686: 0x03f1, 0x1687: 0x0309, 0x1688: 0x00a9, 0x1689: 0x0311, 0x168a: 0x00b1, 0x168b: 0x0319,\n\t0x168c: 0x0101, 0x168d: 0x0321, 0x168e: 0x0329, 0x168f: 0x0051, 0x1690: 0x0339, 0x1691: 0x0751,\n\t0x1692: 0x00b9, 0x1693: 0x0089, 0x1694: 0x0341, 0x1695: 0x0349, 0x1696: 0x0391, 0x1697: 0x00c1,\n\t0x1698: 0x0109, 0x1699: 0x00c9, 0x169a: 0x04b1, 0x169b: 0x1fe2, 0x169c: 0x21da, 0x169d: 0x1fea,\n\t0x169e: 0x21e2, 0x169f: 0x810d, 0x16a0: 0x812d, 0x16a1: 0x0961, 0x16a2: 0x814d, 0x16a3: 0x814d,\n\t0x16a4: 0x816d, 0x16a5: 0x818d, 0x16a6: 0x81ad, 0x16a7: 0x81cd, 0x16a8: 0x81ed, 0x16a9: 0x820d,\n\t0x16aa: 0x822d, 0x16ab: 0x824d, 0x16ac: 0x826d, 0x16ad: 0x828d, 0x16ae: 0x82ad, 0x16af: 0x82cd,\n\t0x16b0: 0x82ed, 0x16b1: 0x830d, 0x16b2: 0x832d, 0x16b3: 0x834d, 0x16b4: 0x836d, 0x16b5: 0x838d,\n\t0x16b6: 0x83ad, 0x16b7: 0x83cd, 0x16b8: 0x83ed, 0x16b9: 0x840d, 0x16ba: 0x842d, 0x16bb: 0x844d,\n\t0x16bc: 0x81ed, 0x16bd: 0x846d, 0x16be: 0x848d, 0x16bf: 0x824d,\n\t// Block 0x5b, offset 0x16c0\n\t0x16c0: 0x84ad, 0x16c1: 0x84cd, 0x16c2: 0x84ed, 0x16c3: 0x850d, 0x16c4: 0x852d, 0x16c5: 0x854d,\n\t0x16c6: 0x856d, 0x16c7: 0x858d, 0x16c8: 0x850d, 0x16c9: 0x85ad, 0x16ca: 0x850d, 0x16cb: 0x85cd,\n\t0x16cc: 0x85cd, 0x16cd: 0x85ed, 0x16ce: 0x85ed, 0x16cf: 0x860d, 0x16d0: 0x854d, 0x16d1: 0x862d,\n\t0x16d2: 0x864d, 0x16d3: 0x862d, 0x16d4: 0x866d, 0x16d5: 0x864d, 0x16d6: 0x868d, 0x16d7: 0x868d,\n\t0x16d8: 0x86ad, 0x16d9: 0x86ad, 0x16da: 0x86cd, 0x16db: 0x86cd, 0x16dc: 0x864d, 0x16dd: 0x814d,\n\t0x16de: 0x86ed, 0x16df: 0x870d, 0x16e0: 0x0040, 0x16e1: 0x872d, 0x16e2: 0x874d, 0x16e3: 0x876d,\n\t0x16e4: 0x878d, 0x16e5: 0x876d, 0x16e6: 0x87ad, 0x16e7: 0x87cd, 0x16e8: 0x87ed, 0x16e9: 0x87ed,\n\t0x16ea: 0x880d, 0x16eb: 0x880d, 0x16ec: 0x882d, 0x16ed: 0x882d, 0x16ee: 0x880d, 0x16ef: 0x880d,\n\t0x16f0: 0x884d, 0x16f1: 0x886d, 0x16f2: 0x888d, 0x16f3: 0x88ad, 0x16f4: 0x88cd, 0x16f5: 0x88ed,\n\t0x16f6: 0x88ed, 0x16f7: 0x88ed, 0x16f8: 0x890d, 0x16f9: 0x890d, 0x16fa: 0x890d, 0x16fb: 0x890d,\n\t0x16fc: 0x87ed, 0x16fd: 0x87ed, 0x16fe: 0x87ed, 0x16ff: 0x0040,\n\t// Block 0x5c, offset 0x1700\n\t0x1700: 0x0040, 0x1701: 0x0040, 0x1702: 0x874d, 0x1703: 0x872d, 0x1704: 0x892d, 0x1705: 0x872d,\n\t0x1706: 0x874d, 0x1707: 0x872d, 0x1708: 0x0040, 0x1709: 0x0040, 0x170a: 0x894d, 0x170b: 0x874d,\n\t0x170c: 0x896d, 0x170d: 0x892d, 0x170e: 0x896d, 0x170f: 0x874d, 0x1710: 0x0040, 0x1711: 0x0040,\n\t0x1712: 0x898d, 0x1713: 0x89ad, 0x1714: 0x88ad, 0x1715: 0x896d, 0x1716: 0x892d, 0x1717: 0x896d,\n\t0x1718: 0x0040, 0x1719: 0x0040, 0x171a: 0x89cd, 0x171b: 0x89ed, 0x171c: 0x89cd, 0x171d: 0x0040,\n\t0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0x21e9, 0x1721: 0x21f1, 0x1722: 0x21f9, 0x1723: 0x8a0e,\n\t0x1724: 0x2201, 0x1725: 0x2209, 0x1726: 0x8a2d, 0x1727: 0x0040, 0x1728: 0x8a4d, 0x1729: 0x8a6d,\n\t0x172a: 0x8a8d, 0x172b: 0x8a6d, 0x172c: 0x8aad, 0x172d: 0x8acd, 0x172e: 0x8aed, 0x172f: 0x0040,\n\t0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040,\n\t0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0340, 0x173a: 0x0340, 0x173b: 0x0340,\n\t0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040,\n\t// Block 0x5d, offset 0x1740\n\t0x1740: 0x0008, 0x1741: 0x0008, 0x1742: 0x0008, 0x1743: 0x0008, 0x1744: 0x0008, 0x1745: 0x0008,\n\t0x1746: 0x0008, 0x1747: 0x0008, 0x1748: 0x0008, 0x1749: 0x0008, 0x174a: 0x0008, 0x174b: 0x0008,\n\t0x174c: 0x0008, 0x174d: 0x0008, 0x174e: 0x0008, 0x174f: 0x0008, 0x1750: 0x0008, 0x1751: 0x0008,\n\t0x1752: 0x0008, 0x1753: 0x0008, 0x1754: 0x0008, 0x1755: 0x0008, 0x1756: 0x0008, 0x1757: 0x0008,\n\t0x1758: 0x0008, 0x1759: 0x0008, 0x175a: 0x0008, 0x175b: 0x0008, 0x175c: 0x0008, 0x175d: 0x0008,\n\t0x175e: 0x0008, 0x175f: 0x0008, 0x1760: 0x0008, 0x1761: 0x0008, 0x1762: 0x0008, 0x1763: 0x0008,\n\t0x1764: 0x0040, 0x1765: 0x0040, 0x1766: 0x0040, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0040,\n\t0x176a: 0x0040, 0x176b: 0x0040, 0x176c: 0x0040, 0x176d: 0x0040, 0x176e: 0x0040, 0x176f: 0x0018,\n\t0x1770: 0x8b3d, 0x1771: 0x8b55, 0x1772: 0x8b6d, 0x1773: 0x8b55, 0x1774: 0x8b85, 0x1775: 0x8b55,\n\t0x1776: 0x8b6d, 0x1777: 0x8b55, 0x1778: 0x8b3d, 0x1779: 0x8b9d, 0x177a: 0x8bb5, 0x177b: 0x0040,\n\t0x177c: 0x8bcd, 0x177d: 0x8b9d, 0x177e: 0x8bb5, 0x177f: 0x8b9d,\n\t// Block 0x5e, offset 0x1780\n\t0x1780: 0xe13d, 0x1781: 0xe14d, 0x1782: 0xe15d, 0x1783: 0xe14d, 0x1784: 0xe17d, 0x1785: 0xe14d,\n\t0x1786: 0xe15d, 0x1787: 0xe14d, 0x1788: 0xe13d, 0x1789: 0xe1cd, 0x178a: 0xe1dd, 0x178b: 0x0040,\n\t0x178c: 0xe1fd, 0x178d: 0xe1cd, 0x178e: 0xe1dd, 0x178f: 0xe1cd, 0x1790: 0xe13d, 0x1791: 0xe14d,\n\t0x1792: 0xe15d, 0x1793: 0x0040, 0x1794: 0xe17d, 0x1795: 0xe14d, 0x1796: 0x0040, 0x1797: 0x0008,\n\t0x1798: 0x0008, 0x1799: 0x0008, 0x179a: 0x0008, 0x179b: 0x0008, 0x179c: 0x0008, 0x179d: 0x0008,\n\t0x179e: 0x0008, 0x179f: 0x0008, 0x17a0: 0x0008, 0x17a1: 0x0008, 0x17a2: 0x0040, 0x17a3: 0x0008,\n\t0x17a4: 0x0008, 0x17a5: 0x0008, 0x17a6: 0x0008, 0x17a7: 0x0008, 0x17a8: 0x0008, 0x17a9: 0x0008,\n\t0x17aa: 0x0008, 0x17ab: 0x0008, 0x17ac: 0x0008, 0x17ad: 0x0008, 0x17ae: 0x0008, 0x17af: 0x0008,\n\t0x17b0: 0x0008, 0x17b1: 0x0008, 0x17b2: 0x0040, 0x17b3: 0x0008, 0x17b4: 0x0008, 0x17b5: 0x0008,\n\t0x17b6: 0x0008, 0x17b7: 0x0008, 0x17b8: 0x0008, 0x17b9: 0x0008, 0x17ba: 0x0040, 0x17bb: 0x0008,\n\t0x17bc: 0x0008, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040,\n\t// Block 0x5f, offset 0x17c0\n\t0x17c0: 0x0008, 0x17c1: 0x2211, 0x17c2: 0x2219, 0x17c3: 0x02e1, 0x17c4: 0x2221, 0x17c5: 0x2229,\n\t0x17c6: 0x0040, 0x17c7: 0x2231, 0x17c8: 0x2239, 0x17c9: 0x2241, 0x17ca: 0x2249, 0x17cb: 0x2251,\n\t0x17cc: 0x2259, 0x17cd: 0x2261, 0x17ce: 0x2269, 0x17cf: 0x2271, 0x17d0: 0x2279, 0x17d1: 0x2281,\n\t0x17d2: 0x2289, 0x17d3: 0x2291, 0x17d4: 0x2299, 0x17d5: 0x0741, 0x17d6: 0x22a1, 0x17d7: 0x22a9,\n\t0x17d8: 0x22b1, 0x17d9: 0x22b9, 0x17da: 0x22c1, 0x17db: 0x13d9, 0x17dc: 0x8be5, 0x17dd: 0x22c9,\n\t0x17de: 0x22d1, 0x17df: 0x8c05, 0x17e0: 0x22d9, 0x17e1: 0x8c25, 0x17e2: 0x22e1, 0x17e3: 0x22e9,\n\t0x17e4: 0x22f1, 0x17e5: 0x0751, 0x17e6: 0x22f9, 0x17e7: 0x8c45, 0x17e8: 0x0949, 0x17e9: 0x2301,\n\t0x17ea: 0x2309, 0x17eb: 0x2311, 0x17ec: 0x2319, 0x17ed: 0x2321, 0x17ee: 0x2329, 0x17ef: 0x2331,\n\t0x17f0: 0x2339, 0x17f1: 0x0040, 0x17f2: 0x2341, 0x17f3: 0x2349, 0x17f4: 0x2351, 0x17f5: 0x2359,\n\t0x17f6: 0x2361, 0x17f7: 0x2369, 0x17f8: 0x2371, 0x17f9: 0x8c65, 0x17fa: 0x8c85, 0x17fb: 0x0040,\n\t0x17fc: 0x0040, 0x17fd: 0x0040, 0x17fe: 0x0040, 0x17ff: 0x0040,\n\t// Block 0x60, offset 0x1800\n\t0x1800: 0x0a08, 0x1801: 0x0a08, 0x1802: 0x0a08, 0x1803: 0x0a08, 0x1804: 0x0a08, 0x1805: 0x0c08,\n\t0x1806: 0x0808, 0x1807: 0x0c08, 0x1808: 0x0818, 0x1809: 0x0c08, 0x180a: 0x0c08, 0x180b: 0x0808,\n\t0x180c: 0x0808, 0x180d: 0x0908, 0x180e: 0x0c08, 0x180f: 0x0c08, 0x1810: 0x0c08, 0x1811: 0x0c08,\n\t0x1812: 0x0c08, 0x1813: 0x0a08, 0x1814: 0x0a08, 0x1815: 0x0a08, 0x1816: 0x0a08, 0x1817: 0x0908,\n\t0x1818: 0x0a08, 0x1819: 0x0a08, 0x181a: 0x0a08, 0x181b: 0x0a08, 0x181c: 0x0a08, 0x181d: 0x0c08,\n\t0x181e: 0x0a08, 0x181f: 0x0a08, 0x1820: 0x0a08, 0x1821: 0x0c08, 0x1822: 0x0808, 0x1823: 0x0808,\n\t0x1824: 0x0c08, 0x1825: 0x3308, 0x1826: 0x3308, 0x1827: 0x0040, 0x1828: 0x0040, 0x1829: 0x0040,\n\t0x182a: 0x0040, 0x182b: 0x0a18, 0x182c: 0x0a18, 0x182d: 0x0a18, 0x182e: 0x0a18, 0x182f: 0x0c18,\n\t0x1830: 0x0818, 0x1831: 0x0818, 0x1832: 0x0818, 0x1833: 0x0818, 0x1834: 0x0818, 0x1835: 0x0818,\n\t0x1836: 0x0818, 0x1837: 0x0040, 0x1838: 0x0040, 0x1839: 0x0040, 0x183a: 0x0040, 0x183b: 0x0040,\n\t0x183c: 0x0040, 0x183d: 0x0040, 0x183e: 0x0040, 0x183f: 0x0040,\n\t// Block 0x61, offset 0x1840\n\t0x1840: 0x0a08, 0x1841: 0x0c08, 0x1842: 0x0a08, 0x1843: 0x0c08, 0x1844: 0x0c08, 0x1845: 0x0c08,\n\t0x1846: 0x0a08, 0x1847: 0x0a08, 0x1848: 0x0a08, 0x1849: 0x0c08, 0x184a: 0x0a08, 0x184b: 0x0a08,\n\t0x184c: 0x0c08, 0x184d: 0x0a08, 0x184e: 0x0c08, 0x184f: 0x0c08, 0x1850: 0x0a08, 0x1851: 0x0c08,\n\t0x1852: 0x0040, 0x1853: 0x0040, 0x1854: 0x0040, 0x1855: 0x0040, 0x1856: 0x0040, 0x1857: 0x0040,\n\t0x1858: 0x0040, 0x1859: 0x0818, 0x185a: 0x0818, 0x185b: 0x0818, 0x185c: 0x0818, 0x185d: 0x0040,\n\t0x185e: 0x0040, 0x185f: 0x0040, 0x1860: 0x0040, 0x1861: 0x0040, 0x1862: 0x0040, 0x1863: 0x0040,\n\t0x1864: 0x0040, 0x1865: 0x0040, 0x1866: 0x0040, 0x1867: 0x0040, 0x1868: 0x0040, 0x1869: 0x0c18,\n\t0x186a: 0x0c18, 0x186b: 0x0c18, 0x186c: 0x0c18, 0x186d: 0x0a18, 0x186e: 0x0a18, 0x186f: 0x0818,\n\t0x1870: 0x0040, 0x1871: 0x0040, 0x1872: 0x0040, 0x1873: 0x0040, 0x1874: 0x0040, 0x1875: 0x0040,\n\t0x1876: 0x0040, 0x1877: 0x0040, 0x1878: 0x0040, 0x1879: 0x0040, 0x187a: 0x0040, 0x187b: 0x0040,\n\t0x187c: 0x0040, 0x187d: 0x0040, 0x187e: 0x0040, 0x187f: 0x0040,\n\t// Block 0x62, offset 0x1880\n\t0x1880: 0x3308, 0x1881: 0x3308, 0x1882: 0x3008, 0x1883: 0x3008, 0x1884: 0x0040, 0x1885: 0x0008,\n\t0x1886: 0x0008, 0x1887: 0x0008, 0x1888: 0x0008, 0x1889: 0x0008, 0x188a: 0x0008, 0x188b: 0x0008,\n\t0x188c: 0x0008, 0x188d: 0x0040, 0x188e: 0x0040, 0x188f: 0x0008, 0x1890: 0x0008, 0x1891: 0x0040,\n\t0x1892: 0x0040, 0x1893: 0x0008, 0x1894: 0x0008, 0x1895: 0x0008, 0x1896: 0x0008, 0x1897: 0x0008,\n\t0x1898: 0x0008, 0x1899: 0x0008, 0x189a: 0x0008, 0x189b: 0x0008, 0x189c: 0x0008, 0x189d: 0x0008,\n\t0x189e: 0x0008, 0x189f: 0x0008, 0x18a0: 0x0008, 0x18a1: 0x0008, 0x18a2: 0x0008, 0x18a3: 0x0008,\n\t0x18a4: 0x0008, 0x18a5: 0x0008, 0x18a6: 0x0008, 0x18a7: 0x0008, 0x18a8: 0x0008, 0x18a9: 0x0040,\n\t0x18aa: 0x0008, 0x18ab: 0x0008, 0x18ac: 0x0008, 0x18ad: 0x0008, 0x18ae: 0x0008, 0x18af: 0x0008,\n\t0x18b0: 0x0008, 0x18b1: 0x0040, 0x18b2: 0x0008, 0x18b3: 0x0008, 0x18b4: 0x0040, 0x18b5: 0x0008,\n\t0x18b6: 0x0008, 0x18b7: 0x0008, 0x18b8: 0x0008, 0x18b9: 0x0008, 0x18ba: 0x0040, 0x18bb: 0x3308,\n\t0x18bc: 0x3308, 0x18bd: 0x0008, 0x18be: 0x3008, 0x18bf: 0x3008,\n\t// Block 0x63, offset 0x18c0\n\t0x18c0: 0x3308, 0x18c1: 0x3008, 0x18c2: 0x3008, 0x18c3: 0x3008, 0x18c4: 0x3008, 0x18c5: 0x0040,\n\t0x18c6: 0x0040, 0x18c7: 0x3008, 0x18c8: 0x3008, 0x18c9: 0x0040, 0x18ca: 0x0040, 0x18cb: 0x3008,\n\t0x18cc: 0x3008, 0x18cd: 0x3808, 0x18ce: 0x0040, 0x18cf: 0x0040, 0x18d0: 0x0008, 0x18d1: 0x0040,\n\t0x18d2: 0x0040, 0x18d3: 0x0040, 0x18d4: 0x0040, 0x18d5: 0x0040, 0x18d6: 0x0040, 0x18d7: 0x3008,\n\t0x18d8: 0x0040, 0x18d9: 0x0040, 0x18da: 0x0040, 0x18db: 0x0040, 0x18dc: 0x0040, 0x18dd: 0x0008,\n\t0x18de: 0x0008, 0x18df: 0x0008, 0x18e0: 0x0008, 0x18e1: 0x0008, 0x18e2: 0x3008, 0x18e3: 0x3008,\n\t0x18e4: 0x0040, 0x18e5: 0x0040, 0x18e6: 0x3308, 0x18e7: 0x3308, 0x18e8: 0x3308, 0x18e9: 0x3308,\n\t0x18ea: 0x3308, 0x18eb: 0x3308, 0x18ec: 0x3308, 0x18ed: 0x0040, 0x18ee: 0x0040, 0x18ef: 0x0040,\n\t0x18f0: 0x3308, 0x18f1: 0x3308, 0x18f2: 0x3308, 0x18f3: 0x3308, 0x18f4: 0x3308, 0x18f5: 0x0040,\n\t0x18f6: 0x0040, 0x18f7: 0x0040, 0x18f8: 0x0040, 0x18f9: 0x0040, 0x18fa: 0x0040, 0x18fb: 0x0040,\n\t0x18fc: 0x0040, 0x18fd: 0x0040, 0x18fe: 0x0040, 0x18ff: 0x0040,\n\t// Block 0x64, offset 0x1900\n\t0x1900: 0x0008, 0x1901: 0x0008, 0x1902: 0x0008, 0x1903: 0x0008, 0x1904: 0x0008, 0x1905: 0x0008,\n\t0x1906: 0x0008, 0x1907: 0x0040, 0x1908: 0x0040, 0x1909: 0x0008, 0x190a: 0x0040, 0x190b: 0x0040,\n\t0x190c: 0x0008, 0x190d: 0x0008, 0x190e: 0x0008, 0x190f: 0x0008, 0x1910: 0x0008, 0x1911: 0x0008,\n\t0x1912: 0x0008, 0x1913: 0x0008, 0x1914: 0x0040, 0x1915: 0x0008, 0x1916: 0x0008, 0x1917: 0x0040,\n\t0x1918: 0x0008, 0x1919: 0x0008, 0x191a: 0x0008, 0x191b: 0x0008, 0x191c: 0x0008, 0x191d: 0x0008,\n\t0x191e: 0x0008, 0x191f: 0x0008, 0x1920: 0x0008, 0x1921: 0x0008, 0x1922: 0x0008, 0x1923: 0x0008,\n\t0x1924: 0x0008, 0x1925: 0x0008, 0x1926: 0x0008, 0x1927: 0x0008, 0x1928: 0x0008, 0x1929: 0x0008,\n\t0x192a: 0x0008, 0x192b: 0x0008, 0x192c: 0x0008, 0x192d: 0x0008, 0x192e: 0x0008, 0x192f: 0x0008,\n\t0x1930: 0x3008, 0x1931: 0x3008, 0x1932: 0x3008, 0x1933: 0x3008, 0x1934: 0x3008, 0x1935: 0x3008,\n\t0x1936: 0x0040, 0x1937: 0x3008, 0x1938: 0x3008, 0x1939: 0x0040, 0x193a: 0x0040, 0x193b: 0x3308,\n\t0x193c: 0x3308, 0x193d: 0x3808, 0x193e: 0x3b08, 0x193f: 0x0008,\n\t// Block 0x65, offset 0x1940\n\t0x1940: 0x0019, 0x1941: 0x02e9, 0x1942: 0x03d9, 0x1943: 0x02f1, 0x1944: 0x02f9, 0x1945: 0x03f1,\n\t0x1946: 0x0309, 0x1947: 0x00a9, 0x1948: 0x0311, 0x1949: 0x00b1, 0x194a: 0x0319, 0x194b: 0x0101,\n\t0x194c: 0x0321, 0x194d: 0x0329, 0x194e: 0x0051, 0x194f: 0x0339, 0x1950: 0x0751, 0x1951: 0x00b9,\n\t0x1952: 0x0089, 0x1953: 0x0341, 0x1954: 0x0349, 0x1955: 0x0391, 0x1956: 0x00c1, 0x1957: 0x0109,\n\t0x1958: 0x00c9, 0x1959: 0x04b1, 0x195a: 0x0019, 0x195b: 0x02e9, 0x195c: 0x03d9, 0x195d: 0x02f1,\n\t0x195e: 0x02f9, 0x195f: 0x03f1, 0x1960: 0x0309, 0x1961: 0x00a9, 0x1962: 0x0311, 0x1963: 0x00b1,\n\t0x1964: 0x0319, 0x1965: 0x0101, 0x1966: 0x0321, 0x1967: 0x0329, 0x1968: 0x0051, 0x1969: 0x0339,\n\t0x196a: 0x0751, 0x196b: 0x00b9, 0x196c: 0x0089, 0x196d: 0x0341, 0x196e: 0x0349, 0x196f: 0x0391,\n\t0x1970: 0x00c1, 0x1971: 0x0109, 0x1972: 0x00c9, 0x1973: 0x04b1, 0x1974: 0x0019, 0x1975: 0x02e9,\n\t0x1976: 0x03d9, 0x1977: 0x02f1, 0x1978: 0x02f9, 0x1979: 0x03f1, 0x197a: 0x0309, 0x197b: 0x00a9,\n\t0x197c: 0x0311, 0x197d: 0x00b1, 0x197e: 0x0319, 0x197f: 0x0101,\n\t// Block 0x66, offset 0x1980\n\t0x1980: 0x0321, 0x1981: 0x0329, 0x1982: 0x0051, 0x1983: 0x0339, 0x1984: 0x0751, 0x1985: 0x00b9,\n\t0x1986: 0x0089, 0x1987: 0x0341, 0x1988: 0x0349, 0x1989: 0x0391, 0x198a: 0x00c1, 0x198b: 0x0109,\n\t0x198c: 0x00c9, 0x198d: 0x04b1, 0x198e: 0x0019, 0x198f: 0x02e9, 0x1990: 0x03d9, 0x1991: 0x02f1,\n\t0x1992: 0x02f9, 0x1993: 0x03f1, 0x1994: 0x0309, 0x1995: 0x0040, 0x1996: 0x0311, 0x1997: 0x00b1,\n\t0x1998: 0x0319, 0x1999: 0x0101, 0x199a: 0x0321, 0x199b: 0x0329, 0x199c: 0x0051, 0x199d: 0x0339,\n\t0x199e: 0x0751, 0x199f: 0x00b9, 0x19a0: 0x0089, 0x19a1: 0x0341, 0x19a2: 0x0349, 0x19a3: 0x0391,\n\t0x19a4: 0x00c1, 0x19a5: 0x0109, 0x19a6: 0x00c9, 0x19a7: 0x04b1, 0x19a8: 0x0019, 0x19a9: 0x02e9,\n\t0x19aa: 0x03d9, 0x19ab: 0x02f1, 0x19ac: 0x02f9, 0x19ad: 0x03f1, 0x19ae: 0x0309, 0x19af: 0x00a9,\n\t0x19b0: 0x0311, 0x19b1: 0x00b1, 0x19b2: 0x0319, 0x19b3: 0x0101, 0x19b4: 0x0321, 0x19b5: 0x0329,\n\t0x19b6: 0x0051, 0x19b7: 0x0339, 0x19b8: 0x0751, 0x19b9: 0x00b9, 0x19ba: 0x0089, 0x19bb: 0x0341,\n\t0x19bc: 0x0349, 0x19bd: 0x0391, 0x19be: 0x00c1, 0x19bf: 0x0109,\n\t// Block 0x67, offset 0x19c0\n\t0x19c0: 0x00c9, 0x19c1: 0x04b1, 0x19c2: 0x0019, 0x19c3: 0x02e9, 0x19c4: 0x03d9, 0x19c5: 0x02f1,\n\t0x19c6: 0x02f9, 0x19c7: 0x03f1, 0x19c8: 0x0309, 0x19c9: 0x00a9, 0x19ca: 0x0311, 0x19cb: 0x00b1,\n\t0x19cc: 0x0319, 0x19cd: 0x0101, 0x19ce: 0x0321, 0x19cf: 0x0329, 0x19d0: 0x0051, 0x19d1: 0x0339,\n\t0x19d2: 0x0751, 0x19d3: 0x00b9, 0x19d4: 0x0089, 0x19d5: 0x0341, 0x19d6: 0x0349, 0x19d7: 0x0391,\n\t0x19d8: 0x00c1, 0x19d9: 0x0109, 0x19da: 0x00c9, 0x19db: 0x04b1, 0x19dc: 0x0019, 0x19dd: 0x0040,\n\t0x19de: 0x03d9, 0x19df: 0x02f1, 0x19e0: 0x0040, 0x19e1: 0x0040, 0x19e2: 0x0309, 0x19e3: 0x0040,\n\t0x19e4: 0x0040, 0x19e5: 0x00b1, 0x19e6: 0x0319, 0x19e7: 0x0040, 0x19e8: 0x0040, 0x19e9: 0x0329,\n\t0x19ea: 0x0051, 0x19eb: 0x0339, 0x19ec: 0x0751, 0x19ed: 0x0040, 0x19ee: 0x0089, 0x19ef: 0x0341,\n\t0x19f0: 0x0349, 0x19f1: 0x0391, 0x19f2: 0x00c1, 0x19f3: 0x0109, 0x19f4: 0x00c9, 0x19f5: 0x04b1,\n\t0x19f6: 0x0019, 0x19f7: 0x02e9, 0x19f8: 0x03d9, 0x19f9: 0x02f1, 0x19fa: 0x0040, 0x19fb: 0x03f1,\n\t0x19fc: 0x0040, 0x19fd: 0x00a9, 0x19fe: 0x0311, 0x19ff: 0x00b1,\n\t// Block 0x68, offset 0x1a00\n\t0x1a00: 0x0319, 0x1a01: 0x0101, 0x1a02: 0x0321, 0x1a03: 0x0329, 0x1a04: 0x0040, 0x1a05: 0x0339,\n\t0x1a06: 0x0751, 0x1a07: 0x00b9, 0x1a08: 0x0089, 0x1a09: 0x0341, 0x1a0a: 0x0349, 0x1a0b: 0x0391,\n\t0x1a0c: 0x00c1, 0x1a0d: 0x0109, 0x1a0e: 0x00c9, 0x1a0f: 0x04b1, 0x1a10: 0x0019, 0x1a11: 0x02e9,\n\t0x1a12: 0x03d9, 0x1a13: 0x02f1, 0x1a14: 0x02f9, 0x1a15: 0x03f1, 0x1a16: 0x0309, 0x1a17: 0x00a9,\n\t0x1a18: 0x0311, 0x1a19: 0x00b1, 0x1a1a: 0x0319, 0x1a1b: 0x0101, 0x1a1c: 0x0321, 0x1a1d: 0x0329,\n\t0x1a1e: 0x0051, 0x1a1f: 0x0339, 0x1a20: 0x0751, 0x1a21: 0x00b9, 0x1a22: 0x0089, 0x1a23: 0x0341,\n\t0x1a24: 0x0349, 0x1a25: 0x0391, 0x1a26: 0x00c1, 0x1a27: 0x0109, 0x1a28: 0x00c9, 0x1a29: 0x04b1,\n\t0x1a2a: 0x0019, 0x1a2b: 0x02e9, 0x1a2c: 0x03d9, 0x1a2d: 0x02f1, 0x1a2e: 0x02f9, 0x1a2f: 0x03f1,\n\t0x1a30: 0x0309, 0x1a31: 0x00a9, 0x1a32: 0x0311, 0x1a33: 0x00b1, 0x1a34: 0x0319, 0x1a35: 0x0101,\n\t0x1a36: 0x0321, 0x1a37: 0x0329, 0x1a38: 0x0051, 0x1a39: 0x0339, 0x1a3a: 0x0751, 0x1a3b: 0x00b9,\n\t0x1a3c: 0x0089, 0x1a3d: 0x0341, 0x1a3e: 0x0349, 0x1a3f: 0x0391,\n\t// Block 0x69, offset 0x1a40\n\t0x1a40: 0x00c1, 0x1a41: 0x0109, 0x1a42: 0x00c9, 0x1a43: 0x04b1, 0x1a44: 0x0019, 0x1a45: 0x02e9,\n\t0x1a46: 0x0040, 0x1a47: 0x02f1, 0x1a48: 0x02f9, 0x1a49: 0x03f1, 0x1a4a: 0x0309, 0x1a4b: 0x0040,\n\t0x1a4c: 0x0040, 0x1a4d: 0x00b1, 0x1a4e: 0x0319, 0x1a4f: 0x0101, 0x1a50: 0x0321, 0x1a51: 0x0329,\n\t0x1a52: 0x0051, 0x1a53: 0x0339, 0x1a54: 0x0751, 0x1a55: 0x0040, 0x1a56: 0x0089, 0x1a57: 0x0341,\n\t0x1a58: 0x0349, 0x1a59: 0x0391, 0x1a5a: 0x00c1, 0x1a5b: 0x0109, 0x1a5c: 0x00c9, 0x1a5d: 0x0040,\n\t0x1a5e: 0x0019, 0x1a5f: 0x02e9, 0x1a60: 0x03d9, 0x1a61: 0x02f1, 0x1a62: 0x02f9, 0x1a63: 0x03f1,\n\t0x1a64: 0x0309, 0x1a65: 0x00a9, 0x1a66: 0x0311, 0x1a67: 0x00b1, 0x1a68: 0x0319, 0x1a69: 0x0101,\n\t0x1a6a: 0x0321, 0x1a6b: 0x0329, 0x1a6c: 0x0051, 0x1a6d: 0x0339, 0x1a6e: 0x0751, 0x1a6f: 0x00b9,\n\t0x1a70: 0x0089, 0x1a71: 0x0341, 0x1a72: 0x0349, 0x1a73: 0x0391, 0x1a74: 0x00c1, 0x1a75: 0x0109,\n\t0x1a76: 0x00c9, 0x1a77: 0x04b1, 0x1a78: 0x0019, 0x1a79: 0x02e9, 0x1a7a: 0x0040, 0x1a7b: 0x02f1,\n\t0x1a7c: 0x02f9, 0x1a7d: 0x03f1, 0x1a7e: 0x0309, 0x1a7f: 0x0040,\n\t// Block 0x6a, offset 0x1a80\n\t0x1a80: 0x0311, 0x1a81: 0x00b1, 0x1a82: 0x0319, 0x1a83: 0x0101, 0x1a84: 0x0321, 0x1a85: 0x0040,\n\t0x1a86: 0x0051, 0x1a87: 0x0040, 0x1a88: 0x0040, 0x1a89: 0x0040, 0x1a8a: 0x0089, 0x1a8b: 0x0341,\n\t0x1a8c: 0x0349, 0x1a8d: 0x0391, 0x1a8e: 0x00c1, 0x1a8f: 0x0109, 0x1a90: 0x00c9, 0x1a91: 0x0040,\n\t0x1a92: 0x0019, 0x1a93: 0x02e9, 0x1a94: 0x03d9, 0x1a95: 0x02f1, 0x1a96: 0x02f9, 0x1a97: 0x03f1,\n\t0x1a98: 0x0309, 0x1a99: 0x00a9, 0x1a9a: 0x0311, 0x1a9b: 0x00b1, 0x1a9c: 0x0319, 0x1a9d: 0x0101,\n\t0x1a9e: 0x0321, 0x1a9f: 0x0329, 0x1aa0: 0x0051, 0x1aa1: 0x0339, 0x1aa2: 0x0751, 0x1aa3: 0x00b9,\n\t0x1aa4: 0x0089, 0x1aa5: 0x0341, 0x1aa6: 0x0349, 0x1aa7: 0x0391, 0x1aa8: 0x00c1, 0x1aa9: 0x0109,\n\t0x1aaa: 0x00c9, 0x1aab: 0x04b1, 0x1aac: 0x0019, 0x1aad: 0x02e9, 0x1aae: 0x03d9, 0x1aaf: 0x02f1,\n\t0x1ab0: 0x02f9, 0x1ab1: 0x03f1, 0x1ab2: 0x0309, 0x1ab3: 0x00a9, 0x1ab4: 0x0311, 0x1ab5: 0x00b1,\n\t0x1ab6: 0x0319, 0x1ab7: 0x0101, 0x1ab8: 0x0321, 0x1ab9: 0x0329, 0x1aba: 0x0051, 0x1abb: 0x0339,\n\t0x1abc: 0x0751, 0x1abd: 0x00b9, 0x1abe: 0x0089, 0x1abf: 0x0341,\n\t// Block 0x6b, offset 0x1ac0\n\t0x1ac0: 0x0349, 0x1ac1: 0x0391, 0x1ac2: 0x00c1, 0x1ac3: 0x0109, 0x1ac4: 0x00c9, 0x1ac5: 0x04b1,\n\t0x1ac6: 0x0019, 0x1ac7: 0x02e9, 0x1ac8: 0x03d9, 0x1ac9: 0x02f1, 0x1aca: 0x02f9, 0x1acb: 0x03f1,\n\t0x1acc: 0x0309, 0x1acd: 0x00a9, 0x1ace: 0x0311, 0x1acf: 0x00b1, 0x1ad0: 0x0319, 0x1ad1: 0x0101,\n\t0x1ad2: 0x0321, 0x1ad3: 0x0329, 0x1ad4: 0x0051, 0x1ad5: 0x0339, 0x1ad6: 0x0751, 0x1ad7: 0x00b9,\n\t0x1ad8: 0x0089, 0x1ad9: 0x0341, 0x1ada: 0x0349, 0x1adb: 0x0391, 0x1adc: 0x00c1, 0x1add: 0x0109,\n\t0x1ade: 0x00c9, 0x1adf: 0x04b1, 0x1ae0: 0x0019, 0x1ae1: 0x02e9, 0x1ae2: 0x03d9, 0x1ae3: 0x02f1,\n\t0x1ae4: 0x02f9, 0x1ae5: 0x03f1, 0x1ae6: 0x0309, 0x1ae7: 0x00a9, 0x1ae8: 0x0311, 0x1ae9: 0x00b1,\n\t0x1aea: 0x0319, 0x1aeb: 0x0101, 0x1aec: 0x0321, 0x1aed: 0x0329, 0x1aee: 0x0051, 0x1aef: 0x0339,\n\t0x1af0: 0x0751, 0x1af1: 0x00b9, 0x1af2: 0x0089, 0x1af3: 0x0341, 0x1af4: 0x0349, 0x1af5: 0x0391,\n\t0x1af6: 0x00c1, 0x1af7: 0x0109, 0x1af8: 0x00c9, 0x1af9: 0x04b1, 0x1afa: 0x0019, 0x1afb: 0x02e9,\n\t0x1afc: 0x03d9, 0x1afd: 0x02f1, 0x1afe: 0x02f9, 0x1aff: 0x03f1,\n\t// Block 0x6c, offset 0x1b00\n\t0x1b00: 0x0309, 0x1b01: 0x00a9, 0x1b02: 0x0311, 0x1b03: 0x00b1, 0x1b04: 0x0319, 0x1b05: 0x0101,\n\t0x1b06: 0x0321, 0x1b07: 0x0329, 0x1b08: 0x0051, 0x1b09: 0x0339, 0x1b0a: 0x0751, 0x1b0b: 0x00b9,\n\t0x1b0c: 0x0089, 0x1b0d: 0x0341, 0x1b0e: 0x0349, 0x1b0f: 0x0391, 0x1b10: 0x00c1, 0x1b11: 0x0109,\n\t0x1b12: 0x00c9, 0x1b13: 0x04b1, 0x1b14: 0x0019, 0x1b15: 0x02e9, 0x1b16: 0x03d9, 0x1b17: 0x02f1,\n\t0x1b18: 0x02f9, 0x1b19: 0x03f1, 0x1b1a: 0x0309, 0x1b1b: 0x00a9, 0x1b1c: 0x0311, 0x1b1d: 0x00b1,\n\t0x1b1e: 0x0319, 0x1b1f: 0x0101, 0x1b20: 0x0321, 0x1b21: 0x0329, 0x1b22: 0x0051, 0x1b23: 0x0339,\n\t0x1b24: 0x0751, 0x1b25: 0x00b9, 0x1b26: 0x0089, 0x1b27: 0x0341, 0x1b28: 0x0349, 0x1b29: 0x0391,\n\t0x1b2a: 0x00c1, 0x1b2b: 0x0109, 0x1b2c: 0x00c9, 0x1b2d: 0x04b1, 0x1b2e: 0x0019, 0x1b2f: 0x02e9,\n\t0x1b30: 0x03d9, 0x1b31: 0x02f1, 0x1b32: 0x02f9, 0x1b33: 0x03f1, 0x1b34: 0x0309, 0x1b35: 0x00a9,\n\t0x1b36: 0x0311, 0x1b37: 0x00b1, 0x1b38: 0x0319, 0x1b39: 0x0101, 0x1b3a: 0x0321, 0x1b3b: 0x0329,\n\t0x1b3c: 0x0051, 0x1b3d: 0x0339, 0x1b3e: 0x0751, 0x1b3f: 0x00b9,\n\t// Block 0x6d, offset 0x1b40\n\t0x1b40: 0x0089, 0x1b41: 0x0341, 0x1b42: 0x0349, 0x1b43: 0x0391, 0x1b44: 0x00c1, 0x1b45: 0x0109,\n\t0x1b46: 0x00c9, 0x1b47: 0x04b1, 0x1b48: 0x0019, 0x1b49: 0x02e9, 0x1b4a: 0x03d9, 0x1b4b: 0x02f1,\n\t0x1b4c: 0x02f9, 0x1b4d: 0x03f1, 0x1b4e: 0x0309, 0x1b4f: 0x00a9, 0x1b50: 0x0311, 0x1b51: 0x00b1,\n\t0x1b52: 0x0319, 0x1b53: 0x0101, 0x1b54: 0x0321, 0x1b55: 0x0329, 0x1b56: 0x0051, 0x1b57: 0x0339,\n\t0x1b58: 0x0751, 0x1b59: 0x00b9, 0x1b5a: 0x0089, 0x1b5b: 0x0341, 0x1b5c: 0x0349, 0x1b5d: 0x0391,\n\t0x1b5e: 0x00c1, 0x1b5f: 0x0109, 0x1b60: 0x00c9, 0x1b61: 0x04b1, 0x1b62: 0x0019, 0x1b63: 0x02e9,\n\t0x1b64: 0x03d9, 0x1b65: 0x02f1, 0x1b66: 0x02f9, 0x1b67: 0x03f1, 0x1b68: 0x0309, 0x1b69: 0x00a9,\n\t0x1b6a: 0x0311, 0x1b6b: 0x00b1, 0x1b6c: 0x0319, 0x1b6d: 0x0101, 0x1b6e: 0x0321, 0x1b6f: 0x0329,\n\t0x1b70: 0x0051, 0x1b71: 0x0339, 0x1b72: 0x0751, 0x1b73: 0x00b9, 0x1b74: 0x0089, 0x1b75: 0x0341,\n\t0x1b76: 0x0349, 0x1b77: 0x0391, 0x1b78: 0x00c1, 0x1b79: 0x0109, 0x1b7a: 0x00c9, 0x1b7b: 0x04b1,\n\t0x1b7c: 0x0019, 0x1b7d: 0x02e9, 0x1b7e: 0x03d9, 0x1b7f: 0x02f1,\n\t// Block 0x6e, offset 0x1b80\n\t0x1b80: 0x02f9, 0x1b81: 0x03f1, 0x1b82: 0x0309, 0x1b83: 0x00a9, 0x1b84: 0x0311, 0x1b85: 0x00b1,\n\t0x1b86: 0x0319, 0x1b87: 0x0101, 0x1b88: 0x0321, 0x1b89: 0x0329, 0x1b8a: 0x0051, 0x1b8b: 0x0339,\n\t0x1b8c: 0x0751, 0x1b8d: 0x00b9, 0x1b8e: 0x0089, 0x1b8f: 0x0341, 0x1b90: 0x0349, 0x1b91: 0x0391,\n\t0x1b92: 0x00c1, 0x1b93: 0x0109, 0x1b94: 0x00c9, 0x1b95: 0x04b1, 0x1b96: 0x0019, 0x1b97: 0x02e9,\n\t0x1b98: 0x03d9, 0x1b99: 0x02f1, 0x1b9a: 0x02f9, 0x1b9b: 0x03f1, 0x1b9c: 0x0309, 0x1b9d: 0x00a9,\n\t0x1b9e: 0x0311, 0x1b9f: 0x00b1, 0x1ba0: 0x0319, 0x1ba1: 0x0101, 0x1ba2: 0x0321, 0x1ba3: 0x0329,\n\t0x1ba4: 0x0051, 0x1ba5: 0x0339, 0x1ba6: 0x0751, 0x1ba7: 0x00b9, 0x1ba8: 0x0089, 0x1ba9: 0x0341,\n\t0x1baa: 0x0349, 0x1bab: 0x0391, 0x1bac: 0x00c1, 0x1bad: 0x0109, 0x1bae: 0x00c9, 0x1baf: 0x04b1,\n\t0x1bb0: 0x0019, 0x1bb1: 0x02e9, 0x1bb2: 0x03d9, 0x1bb3: 0x02f1, 0x1bb4: 0x02f9, 0x1bb5: 0x03f1,\n\t0x1bb6: 0x0309, 0x1bb7: 0x00a9, 0x1bb8: 0x0311, 0x1bb9: 0x00b1, 0x1bba: 0x0319, 0x1bbb: 0x0101,\n\t0x1bbc: 0x0321, 0x1bbd: 0x0329, 0x1bbe: 0x0051, 0x1bbf: 0x0339,\n\t// Block 0x6f, offset 0x1bc0\n\t0x1bc0: 0x0751, 0x1bc1: 0x00b9, 0x1bc2: 0x0089, 0x1bc3: 0x0341, 0x1bc4: 0x0349, 0x1bc5: 0x0391,\n\t0x1bc6: 0x00c1, 0x1bc7: 0x0109, 0x1bc8: 0x00c9, 0x1bc9: 0x04b1, 0x1bca: 0x0019, 0x1bcb: 0x02e9,\n\t0x1bcc: 0x03d9, 0x1bcd: 0x02f1, 0x1bce: 0x02f9, 0x1bcf: 0x03f1, 0x1bd0: 0x0309, 0x1bd1: 0x00a9,\n\t0x1bd2: 0x0311, 0x1bd3: 0x00b1, 0x1bd4: 0x0319, 0x1bd5: 0x0101, 0x1bd6: 0x0321, 0x1bd7: 0x0329,\n\t0x1bd8: 0x0051, 0x1bd9: 0x0339, 0x1bda: 0x0751, 0x1bdb: 0x00b9, 0x1bdc: 0x0089, 0x1bdd: 0x0341,\n\t0x1bde: 0x0349, 0x1bdf: 0x0391, 0x1be0: 0x00c1, 0x1be1: 0x0109, 0x1be2: 0x00c9, 0x1be3: 0x04b1,\n\t0x1be4: 0x23e1, 0x1be5: 0x23e9, 0x1be6: 0x0040, 0x1be7: 0x0040, 0x1be8: 0x23f1, 0x1be9: 0x0399,\n\t0x1bea: 0x03a1, 0x1beb: 0x03a9, 0x1bec: 0x23f9, 0x1bed: 0x2401, 0x1bee: 0x2409, 0x1bef: 0x04d1,\n\t0x1bf0: 0x05f9, 0x1bf1: 0x2411, 0x1bf2: 0x2419, 0x1bf3: 0x2421, 0x1bf4: 0x2429, 0x1bf5: 0x2431,\n\t0x1bf6: 0x2439, 0x1bf7: 0x0799, 0x1bf8: 0x03c1, 0x1bf9: 0x04d1, 0x1bfa: 0x2441, 0x1bfb: 0x2449,\n\t0x1bfc: 0x2451, 0x1bfd: 0x03b1, 0x1bfe: 0x03b9, 0x1bff: 0x2459,\n\t// Block 0x70, offset 0x1c00\n\t0x1c00: 0x0769, 0x1c01: 0x2461, 0x1c02: 0x23f1, 0x1c03: 0x0399, 0x1c04: 0x03a1, 0x1c05: 0x03a9,\n\t0x1c06: 0x23f9, 0x1c07: 0x2401, 0x1c08: 0x2409, 0x1c09: 0x04d1, 0x1c0a: 0x05f9, 0x1c0b: 0x2411,\n\t0x1c0c: 0x2419, 0x1c0d: 0x2421, 0x1c0e: 0x2429, 0x1c0f: 0x2431, 0x1c10: 0x2439, 0x1c11: 0x0799,\n\t0x1c12: 0x03c1, 0x1c13: 0x2441, 0x1c14: 0x2441, 0x1c15: 0x2449, 0x1c16: 0x2451, 0x1c17: 0x03b1,\n\t0x1c18: 0x03b9, 0x1c19: 0x2459, 0x1c1a: 0x0769, 0x1c1b: 0x2469, 0x1c1c: 0x23f9, 0x1c1d: 0x04d1,\n\t0x1c1e: 0x2411, 0x1c1f: 0x03b1, 0x1c20: 0x03c1, 0x1c21: 0x0799, 0x1c22: 0x23f1, 0x1c23: 0x0399,\n\t0x1c24: 0x03a1, 0x1c25: 0x03a9, 0x1c26: 0x23f9, 0x1c27: 0x2401, 0x1c28: 0x2409, 0x1c29: 0x04d1,\n\t0x1c2a: 0x05f9, 0x1c2b: 0x2411, 0x1c2c: 0x2419, 0x1c2d: 0x2421, 0x1c2e: 0x2429, 0x1c2f: 0x2431,\n\t0x1c30: 0x2439, 0x1c31: 0x0799, 0x1c32: 0x03c1, 0x1c33: 0x04d1, 0x1c34: 0x2441, 0x1c35: 0x2449,\n\t0x1c36: 0x2451, 0x1c37: 0x03b1, 0x1c38: 0x03b9, 0x1c39: 0x2459, 0x1c3a: 0x0769, 0x1c3b: 0x2461,\n\t0x1c3c: 0x23f1, 0x1c3d: 0x0399, 0x1c3e: 0x03a1, 0x1c3f: 0x03a9,\n\t// Block 0x71, offset 0x1c40\n\t0x1c40: 0x23f9, 0x1c41: 0x2401, 0x1c42: 0x2409, 0x1c43: 0x04d1, 0x1c44: 0x05f9, 0x1c45: 0x2411,\n\t0x1c46: 0x2419, 0x1c47: 0x2421, 0x1c48: 0x2429, 0x1c49: 0x2431, 0x1c4a: 0x2439, 0x1c4b: 0x0799,\n\t0x1c4c: 0x03c1, 0x1c4d: 0x2441, 0x1c4e: 0x2441, 0x1c4f: 0x2449, 0x1c50: 0x2451, 0x1c51: 0x03b1,\n\t0x1c52: 0x03b9, 0x1c53: 0x2459, 0x1c54: 0x0769, 0x1c55: 0x2469, 0x1c56: 0x23f9, 0x1c57: 0x04d1,\n\t0x1c58: 0x2411, 0x1c59: 0x03b1, 0x1c5a: 0x03c1, 0x1c5b: 0x0799, 0x1c5c: 0x23f1, 0x1c5d: 0x0399,\n\t0x1c5e: 0x03a1, 0x1c5f: 0x03a9, 0x1c60: 0x23f9, 0x1c61: 0x2401, 0x1c62: 0x2409, 0x1c63: 0x04d1,\n\t0x1c64: 0x05f9, 0x1c65: 0x2411, 0x1c66: 0x2419, 0x1c67: 0x2421, 0x1c68: 0x2429, 0x1c69: 0x2431,\n\t0x1c6a: 0x2439, 0x1c6b: 0x0799, 0x1c6c: 0x03c1, 0x1c6d: 0x04d1, 0x1c6e: 0x2441, 0x1c6f: 0x2449,\n\t0x1c70: 0x2451, 0x1c71: 0x03b1, 0x1c72: 0x03b9, 0x1c73: 0x2459, 0x1c74: 0x0769, 0x1c75: 0x2461,\n\t0x1c76: 0x23f1, 0x1c77: 0x0399, 0x1c78: 0x03a1, 0x1c79: 0x03a9, 0x1c7a: 0x23f9, 0x1c7b: 0x2401,\n\t0x1c7c: 0x2409, 0x1c7d: 0x04d1, 0x1c7e: 0x05f9, 0x1c7f: 0x2411,\n\t// Block 0x72, offset 0x1c80\n\t0x1c80: 0x2419, 0x1c81: 0x2421, 0x1c82: 0x2429, 0x1c83: 0x2431, 0x1c84: 0x2439, 0x1c85: 0x0799,\n\t0x1c86: 0x03c1, 0x1c87: 0x2441, 0x1c88: 0x2441, 0x1c89: 0x2449, 0x1c8a: 0x2451, 0x1c8b: 0x03b1,\n\t0x1c8c: 0x03b9, 0x1c8d: 0x2459, 0x1c8e: 0x0769, 0x1c8f: 0x2469, 0x1c90: 0x23f9, 0x1c91: 0x04d1,\n\t0x1c92: 0x2411, 0x1c93: 0x03b1, 0x1c94: 0x03c1, 0x1c95: 0x0799, 0x1c96: 0x23f1, 0x1c97: 0x0399,\n\t0x1c98: 0x03a1, 0x1c99: 0x03a9, 0x1c9a: 0x23f9, 0x1c9b: 0x2401, 0x1c9c: 0x2409, 0x1c9d: 0x04d1,\n\t0x1c9e: 0x05f9, 0x1c9f: 0x2411, 0x1ca0: 0x2419, 0x1ca1: 0x2421, 0x1ca2: 0x2429, 0x1ca3: 0x2431,\n\t0x1ca4: 0x2439, 0x1ca5: 0x0799, 0x1ca6: 0x03c1, 0x1ca7: 0x04d1, 0x1ca8: 0x2441, 0x1ca9: 0x2449,\n\t0x1caa: 0x2451, 0x1cab: 0x03b1, 0x1cac: 0x03b9, 0x1cad: 0x2459, 0x1cae: 0x0769, 0x1caf: 0x2461,\n\t0x1cb0: 0x23f1, 0x1cb1: 0x0399, 0x1cb2: 0x03a1, 0x1cb3: 0x03a9, 0x1cb4: 0x23f9, 0x1cb5: 0x2401,\n\t0x1cb6: 0x2409, 0x1cb7: 0x04d1, 0x1cb8: 0x05f9, 0x1cb9: 0x2411, 0x1cba: 0x2419, 0x1cbb: 0x2421,\n\t0x1cbc: 0x2429, 0x1cbd: 0x2431, 0x1cbe: 0x2439, 0x1cbf: 0x0799,\n\t// Block 0x73, offset 0x1cc0\n\t0x1cc0: 0x03c1, 0x1cc1: 0x2441, 0x1cc2: 0x2441, 0x1cc3: 0x2449, 0x1cc4: 0x2451, 0x1cc5: 0x03b1,\n\t0x1cc6: 0x03b9, 0x1cc7: 0x2459, 0x1cc8: 0x0769, 0x1cc9: 0x2469, 0x1cca: 0x23f9, 0x1ccb: 0x04d1,\n\t0x1ccc: 0x2411, 0x1ccd: 0x03b1, 0x1cce: 0x03c1, 0x1ccf: 0x0799, 0x1cd0: 0x23f1, 0x1cd1: 0x0399,\n\t0x1cd2: 0x03a1, 0x1cd3: 0x03a9, 0x1cd4: 0x23f9, 0x1cd5: 0x2401, 0x1cd6: 0x2409, 0x1cd7: 0x04d1,\n\t0x1cd8: 0x05f9, 0x1cd9: 0x2411, 0x1cda: 0x2419, 0x1cdb: 0x2421, 0x1cdc: 0x2429, 0x1cdd: 0x2431,\n\t0x1cde: 0x2439, 0x1cdf: 0x0799, 0x1ce0: 0x03c1, 0x1ce1: 0x04d1, 0x1ce2: 0x2441, 0x1ce3: 0x2449,\n\t0x1ce4: 0x2451, 0x1ce5: 0x03b1, 0x1ce6: 0x03b9, 0x1ce7: 0x2459, 0x1ce8: 0x0769, 0x1ce9: 0x2461,\n\t0x1cea: 0x23f1, 0x1ceb: 0x0399, 0x1cec: 0x03a1, 0x1ced: 0x03a9, 0x1cee: 0x23f9, 0x1cef: 0x2401,\n\t0x1cf0: 0x2409, 0x1cf1: 0x04d1, 0x1cf2: 0x05f9, 0x1cf3: 0x2411, 0x1cf4: 0x2419, 0x1cf5: 0x2421,\n\t0x1cf6: 0x2429, 0x1cf7: 0x2431, 0x1cf8: 0x2439, 0x1cf9: 0x0799, 0x1cfa: 0x03c1, 0x1cfb: 0x2441,\n\t0x1cfc: 0x2441, 0x1cfd: 0x2449, 0x1cfe: 0x2451, 0x1cff: 0x03b1,\n\t// Block 0x74, offset 0x1d00\n\t0x1d00: 0x03b9, 0x1d01: 0x2459, 0x1d02: 0x0769, 0x1d03: 0x2469, 0x1d04: 0x23f9, 0x1d05: 0x04d1,\n\t0x1d06: 0x2411, 0x1d07: 0x03b1, 0x1d08: 0x03c1, 0x1d09: 0x0799, 0x1d0a: 0x2471, 0x1d0b: 0x2471,\n\t0x1d0c: 0x0040, 0x1d0d: 0x0040, 0x1d0e: 0x06e1, 0x1d0f: 0x0049, 0x1d10: 0x0029, 0x1d11: 0x0031,\n\t0x1d12: 0x06e9, 0x1d13: 0x06f1, 0x1d14: 0x06f9, 0x1d15: 0x0701, 0x1d16: 0x0709, 0x1d17: 0x0711,\n\t0x1d18: 0x06e1, 0x1d19: 0x0049, 0x1d1a: 0x0029, 0x1d1b: 0x0031, 0x1d1c: 0x06e9, 0x1d1d: 0x06f1,\n\t0x1d1e: 0x06f9, 0x1d1f: 0x0701, 0x1d20: 0x0709, 0x1d21: 0x0711, 0x1d22: 0x06e1, 0x1d23: 0x0049,\n\t0x1d24: 0x0029, 0x1d25: 0x0031, 0x1d26: 0x06e9, 0x1d27: 0x06f1, 0x1d28: 0x06f9, 0x1d29: 0x0701,\n\t0x1d2a: 0x0709, 0x1d2b: 0x0711, 0x1d2c: 0x06e1, 0x1d2d: 0x0049, 0x1d2e: 0x0029, 0x1d2f: 0x0031,\n\t0x1d30: 0x06e9, 0x1d31: 0x06f1, 0x1d32: 0x06f9, 0x1d33: 0x0701, 0x1d34: 0x0709, 0x1d35: 0x0711,\n\t0x1d36: 0x06e1, 0x1d37: 0x0049, 0x1d38: 0x0029, 0x1d39: 0x0031, 0x1d3a: 0x06e9, 0x1d3b: 0x06f1,\n\t0x1d3c: 0x06f9, 0x1d3d: 0x0701, 0x1d3e: 0x0709, 0x1d3f: 0x0711,\n\t// Block 0x75, offset 0x1d40\n\t0x1d40: 0x3308, 0x1d41: 0x3308, 0x1d42: 0x3308, 0x1d43: 0x3308, 0x1d44: 0x3308, 0x1d45: 0x3308,\n\t0x1d46: 0x3308, 0x1d47: 0x0040, 0x1d48: 0x3308, 0x1d49: 0x3308, 0x1d4a: 0x3308, 0x1d4b: 0x3308,\n\t0x1d4c: 0x3308, 0x1d4d: 0x3308, 0x1d4e: 0x3308, 0x1d4f: 0x3308, 0x1d50: 0x3308, 0x1d51: 0x3308,\n\t0x1d52: 0x3308, 0x1d53: 0x3308, 0x1d54: 0x3308, 0x1d55: 0x3308, 0x1d56: 0x3308, 0x1d57: 0x3308,\n\t0x1d58: 0x3308, 0x1d59: 0x0040, 0x1d5a: 0x0040, 0x1d5b: 0x3308, 0x1d5c: 0x3308, 0x1d5d: 0x3308,\n\t0x1d5e: 0x3308, 0x1d5f: 0x3308, 0x1d60: 0x3308, 0x1d61: 0x3308, 0x1d62: 0x0040, 0x1d63: 0x3308,\n\t0x1d64: 0x3308, 0x1d65: 0x0040, 0x1d66: 0x3308, 0x1d67: 0x3308, 0x1d68: 0x3308, 0x1d69: 0x3308,\n\t0x1d6a: 0x3308, 0x1d6b: 0x0040, 0x1d6c: 0x0040, 0x1d6d: 0x0040, 0x1d6e: 0x0040, 0x1d6f: 0x0040,\n\t0x1d70: 0x2479, 0x1d71: 0x2481, 0x1d72: 0x02a9, 0x1d73: 0x2489, 0x1d74: 0x02b1, 0x1d75: 0x2491,\n\t0x1d76: 0x2499, 0x1d77: 0x24a1, 0x1d78: 0x24a9, 0x1d79: 0x24b1, 0x1d7a: 0x24b9, 0x1d7b: 0x24c1,\n\t0x1d7c: 0x02b9, 0x1d7d: 0x24c9, 0x1d7e: 0x24d1, 0x1d7f: 0x02c1,\n\t// Block 0x76, offset 0x1d80\n\t0x1d80: 0x02c9, 0x1d81: 0x24d9, 0x1d82: 0x24e1, 0x1d83: 0x24e9, 0x1d84: 0x24f1, 0x1d85: 0x24f9,\n\t0x1d86: 0x2501, 0x1d87: 0x2509, 0x1d88: 0x2511, 0x1d89: 0x2519, 0x1d8a: 0x2521, 0x1d8b: 0x2529,\n\t0x1d8c: 0x2531, 0x1d8d: 0x2539, 0x1d8e: 0x2541, 0x1d8f: 0x2549, 0x1d90: 0x2551, 0x1d91: 0x2479,\n\t0x1d92: 0x2481, 0x1d93: 0x02a9, 0x1d94: 0x2489, 0x1d95: 0x02b1, 0x1d96: 0x2491, 0x1d97: 0x2499,\n\t0x1d98: 0x24a1, 0x1d99: 0x24a9, 0x1d9a: 0x24b1, 0x1d9b: 0x24b9, 0x1d9c: 0x02b9, 0x1d9d: 0x24c9,\n\t0x1d9e: 0x02c1, 0x1d9f: 0x24d9, 0x1da0: 0x24e1, 0x1da1: 0x24e9, 0x1da2: 0x24f1, 0x1da3: 0x24f9,\n\t0x1da4: 0x2501, 0x1da5: 0x02d1, 0x1da6: 0x2509, 0x1da7: 0x2559, 0x1da8: 0x2531, 0x1da9: 0x2561,\n\t0x1daa: 0x2569, 0x1dab: 0x2571, 0x1dac: 0x2579, 0x1dad: 0x2581, 0x1dae: 0x0040, 0x1daf: 0x0040,\n\t0x1db0: 0x0040, 0x1db1: 0x0040, 0x1db2: 0x0040, 0x1db3: 0x0040, 0x1db4: 0x0040, 0x1db5: 0x0040,\n\t0x1db6: 0x0040, 0x1db7: 0x0040, 0x1db8: 0x0040, 0x1db9: 0x0040, 0x1dba: 0x0040, 0x1dbb: 0x0040,\n\t0x1dbc: 0x0040, 0x1dbd: 0x0040, 0x1dbe: 0x0040, 0x1dbf: 0x0040,\n\t// Block 0x77, offset 0x1dc0\n\t0x1dc0: 0xe115, 0x1dc1: 0xe115, 0x1dc2: 0xe135, 0x1dc3: 0xe135, 0x1dc4: 0xe115, 0x1dc5: 0xe115,\n\t0x1dc6: 0xe175, 0x1dc7: 0xe175, 0x1dc8: 0xe115, 0x1dc9: 0xe115, 0x1dca: 0xe135, 0x1dcb: 0xe135,\n\t0x1dcc: 0xe115, 0x1dcd: 0xe115, 0x1dce: 0xe1f5, 0x1dcf: 0xe1f5, 0x1dd0: 0xe115, 0x1dd1: 0xe115,\n\t0x1dd2: 0xe135, 0x1dd3: 0xe135, 0x1dd4: 0xe115, 0x1dd5: 0xe115, 0x1dd6: 0xe175, 0x1dd7: 0xe175,\n\t0x1dd8: 0xe115, 0x1dd9: 0xe115, 0x1dda: 0xe135, 0x1ddb: 0xe135, 0x1ddc: 0xe115, 0x1ddd: 0xe115,\n\t0x1dde: 0x8ca5, 0x1ddf: 0x8ca5, 0x1de0: 0x04b5, 0x1de1: 0x04b5, 0x1de2: 0x0a08, 0x1de3: 0x0a08,\n\t0x1de4: 0x0a08, 0x1de5: 0x0a08, 0x1de6: 0x0a08, 0x1de7: 0x0a08, 0x1de8: 0x0a08, 0x1de9: 0x0a08,\n\t0x1dea: 0x0a08, 0x1deb: 0x0a08, 0x1dec: 0x0a08, 0x1ded: 0x0a08, 0x1dee: 0x0a08, 0x1def: 0x0a08,\n\t0x1df0: 0x0a08, 0x1df1: 0x0a08, 0x1df2: 0x0a08, 0x1df3: 0x0a08, 0x1df4: 0x0a08, 0x1df5: 0x0a08,\n\t0x1df6: 0x0a08, 0x1df7: 0x0a08, 0x1df8: 0x0a08, 0x1df9: 0x0a08, 0x1dfa: 0x0a08, 0x1dfb: 0x0a08,\n\t0x1dfc: 0x0a08, 0x1dfd: 0x0a08, 0x1dfe: 0x0a08, 0x1dff: 0x0a08,\n\t// Block 0x78, offset 0x1e00\n\t0x1e00: 0x20b1, 0x1e01: 0x20b9, 0x1e02: 0x20d9, 0x1e03: 0x20f1, 0x1e04: 0x0040, 0x1e05: 0x2189,\n\t0x1e06: 0x2109, 0x1e07: 0x20e1, 0x1e08: 0x2131, 0x1e09: 0x2191, 0x1e0a: 0x2161, 0x1e0b: 0x2169,\n\t0x1e0c: 0x2171, 0x1e0d: 0x2179, 0x1e0e: 0x2111, 0x1e0f: 0x2141, 0x1e10: 0x2151, 0x1e11: 0x2121,\n\t0x1e12: 0x2159, 0x1e13: 0x2101, 0x1e14: 0x2119, 0x1e15: 0x20c9, 0x1e16: 0x20d1, 0x1e17: 0x20e9,\n\t0x1e18: 0x20f9, 0x1e19: 0x2129, 0x1e1a: 0x2139, 0x1e1b: 0x2149, 0x1e1c: 0x2589, 0x1e1d: 0x1689,\n\t0x1e1e: 0x2591, 0x1e1f: 0x2599, 0x1e20: 0x0040, 0x1e21: 0x20b9, 0x1e22: 0x20d9, 0x1e23: 0x0040,\n\t0x1e24: 0x2181, 0x1e25: 0x0040, 0x1e26: 0x0040, 0x1e27: 0x20e1, 0x1e28: 0x0040, 0x1e29: 0x2191,\n\t0x1e2a: 0x2161, 0x1e2b: 0x2169, 0x1e2c: 0x2171, 0x1e2d: 0x2179, 0x1e2e: 0x2111, 0x1e2f: 0x2141,\n\t0x1e30: 0x2151, 0x1e31: 0x2121, 0x1e32: 0x2159, 0x1e33: 0x0040, 0x1e34: 0x2119, 0x1e35: 0x20c9,\n\t0x1e36: 0x20d1, 0x1e37: 0x20e9, 0x1e38: 0x0040, 0x1e39: 0x2129, 0x1e3a: 0x0040, 0x1e3b: 0x2149,\n\t0x1e3c: 0x0040, 0x1e3d: 0x0040, 0x1e3e: 0x0040, 0x1e3f: 0x0040,\n\t// Block 0x79, offset 0x1e40\n\t0x1e40: 0x0040, 0x1e41: 0x0040, 0x1e42: 0x20d9, 0x1e43: 0x0040, 0x1e44: 0x0040, 0x1e45: 0x0040,\n\t0x1e46: 0x0040, 0x1e47: 0x20e1, 0x1e48: 0x0040, 0x1e49: 0x2191, 0x1e4a: 0x0040, 0x1e4b: 0x2169,\n\t0x1e4c: 0x0040, 0x1e4d: 0x2179, 0x1e4e: 0x2111, 0x1e4f: 0x2141, 0x1e50: 0x0040, 0x1e51: 0x2121,\n\t0x1e52: 0x2159, 0x1e53: 0x0040, 0x1e54: 0x2119, 0x1e55: 0x0040, 0x1e56: 0x0040, 0x1e57: 0x20e9,\n\t0x1e58: 0x0040, 0x1e59: 0x2129, 0x1e5a: 0x0040, 0x1e5b: 0x2149, 0x1e5c: 0x0040, 0x1e5d: 0x1689,\n\t0x1e5e: 0x0040, 0x1e5f: 0x2599, 0x1e60: 0x0040, 0x1e61: 0x20b9, 0x1e62: 0x20d9, 0x1e63: 0x0040,\n\t0x1e64: 0x2181, 0x1e65: 0x0040, 0x1e66: 0x0040, 0x1e67: 0x20e1, 0x1e68: 0x2131, 0x1e69: 0x2191,\n\t0x1e6a: 0x2161, 0x1e6b: 0x0040, 0x1e6c: 0x2171, 0x1e6d: 0x2179, 0x1e6e: 0x2111, 0x1e6f: 0x2141,\n\t0x1e70: 0x2151, 0x1e71: 0x2121, 0x1e72: 0x2159, 0x1e73: 0x0040, 0x1e74: 0x2119, 0x1e75: 0x20c9,\n\t0x1e76: 0x20d1, 0x1e77: 0x20e9, 0x1e78: 0x0040, 0x1e79: 0x2129, 0x1e7a: 0x2139, 0x1e7b: 0x2149,\n\t0x1e7c: 0x2589, 0x1e7d: 0x0040, 0x1e7e: 0x2591, 0x1e7f: 0x0040,\n\t// Block 0x7a, offset 0x1e80\n\t0x1e80: 0x20b1, 0x1e81: 0x20b9, 0x1e82: 0x20d9, 0x1e83: 0x20f1, 0x1e84: 0x2181, 0x1e85: 0x2189,\n\t0x1e86: 0x2109, 0x1e87: 0x20e1, 0x1e88: 0x2131, 0x1e89: 0x2191, 0x1e8a: 0x0040, 0x1e8b: 0x2169,\n\t0x1e8c: 0x2171, 0x1e8d: 0x2179, 0x1e8e: 0x2111, 0x1e8f: 0x2141, 0x1e90: 0x2151, 0x1e91: 0x2121,\n\t0x1e92: 0x2159, 0x1e93: 0x2101, 0x1e94: 0x2119, 0x1e95: 0x20c9, 0x1e96: 0x20d1, 0x1e97: 0x20e9,\n\t0x1e98: 0x20f9, 0x1e99: 0x2129, 0x1e9a: 0x2139, 0x1e9b: 0x2149, 0x1e9c: 0x0040, 0x1e9d: 0x0040,\n\t0x1e9e: 0x0040, 0x1e9f: 0x0040, 0x1ea0: 0x0040, 0x1ea1: 0x20b9, 0x1ea2: 0x20d9, 0x1ea3: 0x20f1,\n\t0x1ea4: 0x0040, 0x1ea5: 0x2189, 0x1ea6: 0x2109, 0x1ea7: 0x20e1, 0x1ea8: 0x2131, 0x1ea9: 0x2191,\n\t0x1eaa: 0x0040, 0x1eab: 0x2169, 0x1eac: 0x2171, 0x1ead: 0x2179, 0x1eae: 0x2111, 0x1eaf: 0x2141,\n\t0x1eb0: 0x2151, 0x1eb1: 0x2121, 0x1eb2: 0x2159, 0x1eb3: 0x2101, 0x1eb4: 0x2119, 0x1eb5: 0x20c9,\n\t0x1eb6: 0x20d1, 0x1eb7: 0x20e9, 0x1eb8: 0x20f9, 0x1eb9: 0x2129, 0x1eba: 0x2139, 0x1ebb: 0x2149,\n\t0x1ebc: 0x0040, 0x1ebd: 0x0040, 0x1ebe: 0x0040, 0x1ebf: 0x0040,\n\t// Block 0x7b, offset 0x1ec0\n\t0x1ec0: 0x0040, 0x1ec1: 0x25a2, 0x1ec2: 0x25aa, 0x1ec3: 0x25b2, 0x1ec4: 0x25ba, 0x1ec5: 0x25c2,\n\t0x1ec6: 0x25ca, 0x1ec7: 0x25d2, 0x1ec8: 0x25da, 0x1ec9: 0x25e2, 0x1eca: 0x25ea, 0x1ecb: 0x0018,\n\t0x1ecc: 0x0018, 0x1ecd: 0x0018, 0x1ece: 0x0018, 0x1ecf: 0x0018, 0x1ed0: 0x25f2, 0x1ed1: 0x25fa,\n\t0x1ed2: 0x2602, 0x1ed3: 0x260a, 0x1ed4: 0x2612, 0x1ed5: 0x261a, 0x1ed6: 0x2622, 0x1ed7: 0x262a,\n\t0x1ed8: 0x2632, 0x1ed9: 0x263a, 0x1eda: 0x2642, 0x1edb: 0x264a, 0x1edc: 0x2652, 0x1edd: 0x265a,\n\t0x1ede: 0x2662, 0x1edf: 0x266a, 0x1ee0: 0x2672, 0x1ee1: 0x267a, 0x1ee2: 0x2682, 0x1ee3: 0x268a,\n\t0x1ee4: 0x2692, 0x1ee5: 0x269a, 0x1ee6: 0x26a2, 0x1ee7: 0x26aa, 0x1ee8: 0x26b2, 0x1ee9: 0x26ba,\n\t0x1eea: 0x26c1, 0x1eeb: 0x03d9, 0x1eec: 0x00b9, 0x1eed: 0x1239, 0x1eee: 0x26c9, 0x1eef: 0x0018,\n\t0x1ef0: 0x0019, 0x1ef1: 0x02e9, 0x1ef2: 0x03d9, 0x1ef3: 0x02f1, 0x1ef4: 0x02f9, 0x1ef5: 0x03f1,\n\t0x1ef6: 0x0309, 0x1ef7: 0x00a9, 0x1ef8: 0x0311, 0x1ef9: 0x00b1, 0x1efa: 0x0319, 0x1efb: 0x0101,\n\t0x1efc: 0x0321, 0x1efd: 0x0329, 0x1efe: 0x0051, 0x1eff: 0x0339,\n\t// Block 0x7c, offset 0x1f00\n\t0x1f00: 0x0751, 0x1f01: 0x00b9, 0x1f02: 0x0089, 0x1f03: 0x0341, 0x1f04: 0x0349, 0x1f05: 0x0391,\n\t0x1f06: 0x00c1, 0x1f07: 0x0109, 0x1f08: 0x00c9, 0x1f09: 0x04b1, 0x1f0a: 0x26d1, 0x1f0b: 0x11f9,\n\t0x1f0c: 0x26d9, 0x1f0d: 0x04d9, 0x1f0e: 0x26e1, 0x1f0f: 0x26e9, 0x1f10: 0x0018, 0x1f11: 0x0018,\n\t0x1f12: 0x0018, 0x1f13: 0x0018, 0x1f14: 0x0018, 0x1f15: 0x0018, 0x1f16: 0x0018, 0x1f17: 0x0018,\n\t0x1f18: 0x0018, 0x1f19: 0x0018, 0x1f1a: 0x0018, 0x1f1b: 0x0018, 0x1f1c: 0x0018, 0x1f1d: 0x0018,\n\t0x1f1e: 0x0018, 0x1f1f: 0x0018, 0x1f20: 0x0018, 0x1f21: 0x0018, 0x1f22: 0x0018, 0x1f23: 0x0018,\n\t0x1f24: 0x0018, 0x1f25: 0x0018, 0x1f26: 0x0018, 0x1f27: 0x0018, 0x1f28: 0x0018, 0x1f29: 0x0018,\n\t0x1f2a: 0x26f1, 0x1f2b: 0x26f9, 0x1f2c: 0x2701, 0x1f2d: 0x0018, 0x1f2e: 0x0018, 0x1f2f: 0x0018,\n\t0x1f30: 0x0018, 0x1f31: 0x0018, 0x1f32: 0x0018, 0x1f33: 0x0018, 0x1f34: 0x0018, 0x1f35: 0x0018,\n\t0x1f36: 0x0018, 0x1f37: 0x0018, 0x1f38: 0x0018, 0x1f39: 0x0018, 0x1f3a: 0x0018, 0x1f3b: 0x0018,\n\t0x1f3c: 0x0018, 0x1f3d: 0x0018, 0x1f3e: 0x0018, 0x1f3f: 0x0018,\n\t// Block 0x7d, offset 0x1f40\n\t0x1f40: 0x2711, 0x1f41: 0x2719, 0x1f42: 0x2721, 0x1f43: 0x0040, 0x1f44: 0x0040, 0x1f45: 0x0040,\n\t0x1f46: 0x0040, 0x1f47: 0x0040, 0x1f48: 0x0040, 0x1f49: 0x0040, 0x1f4a: 0x0040, 0x1f4b: 0x0040,\n\t0x1f4c: 0x0040, 0x1f4d: 0x0040, 0x1f4e: 0x0040, 0x1f4f: 0x0040, 0x1f50: 0x2729, 0x1f51: 0x2731,\n\t0x1f52: 0x2739, 0x1f53: 0x2741, 0x1f54: 0x2749, 0x1f55: 0x2751, 0x1f56: 0x2759, 0x1f57: 0x2761,\n\t0x1f58: 0x2769, 0x1f59: 0x2771, 0x1f5a: 0x2779, 0x1f5b: 0x2781, 0x1f5c: 0x2789, 0x1f5d: 0x2791,\n\t0x1f5e: 0x2799, 0x1f5f: 0x27a1, 0x1f60: 0x27a9, 0x1f61: 0x27b1, 0x1f62: 0x27b9, 0x1f63: 0x27c1,\n\t0x1f64: 0x27c9, 0x1f65: 0x27d1, 0x1f66: 0x27d9, 0x1f67: 0x27e1, 0x1f68: 0x27e9, 0x1f69: 0x27f1,\n\t0x1f6a: 0x27f9, 0x1f6b: 0x2801, 0x1f6c: 0x2809, 0x1f6d: 0x2811, 0x1f6e: 0x2819, 0x1f6f: 0x2821,\n\t0x1f70: 0x2829, 0x1f71: 0x2831, 0x1f72: 0x2839, 0x1f73: 0x2841, 0x1f74: 0x2849, 0x1f75: 0x2851,\n\t0x1f76: 0x2859, 0x1f77: 0x2861, 0x1f78: 0x2869, 0x1f79: 0x2871, 0x1f7a: 0x2879, 0x1f7b: 0x2881,\n\t0x1f7c: 0x0040, 0x1f7d: 0x0040, 0x1f7e: 0x0040, 0x1f7f: 0x0040,\n\t// Block 0x7e, offset 0x1f80\n\t0x1f80: 0x28e1, 0x1f81: 0x28e9, 0x1f82: 0x28f1, 0x1f83: 0x8cbd, 0x1f84: 0x28f9, 0x1f85: 0x2901,\n\t0x1f86: 0x2909, 0x1f87: 0x2911, 0x1f88: 0x2919, 0x1f89: 0x2921, 0x1f8a: 0x2929, 0x1f8b: 0x2931,\n\t0x1f8c: 0x2939, 0x1f8d: 0x8cdd, 0x1f8e: 0x2941, 0x1f8f: 0x2949, 0x1f90: 0x2951, 0x1f91: 0x2959,\n\t0x1f92: 0x8cfd, 0x1f93: 0x2961, 0x1f94: 0x2969, 0x1f95: 0x2799, 0x1f96: 0x8d1d, 0x1f97: 0x2971,\n\t0x1f98: 0x2979, 0x1f99: 0x2981, 0x1f9a: 0x2989, 0x1f9b: 0x2991, 0x1f9c: 0x8d3d, 0x1f9d: 0x2999,\n\t0x1f9e: 0x29a1, 0x1f9f: 0x29a9, 0x1fa0: 0x29b1, 0x1fa1: 0x29b9, 0x1fa2: 0x2871, 0x1fa3: 0x29c1,\n\t0x1fa4: 0x29c9, 0x1fa5: 0x29d1, 0x1fa6: 0x29d9, 0x1fa7: 0x29e1, 0x1fa8: 0x29e9, 0x1fa9: 0x29f1,\n\t0x1faa: 0x29f9, 0x1fab: 0x2a01, 0x1fac: 0x2a09, 0x1fad: 0x2a11, 0x1fae: 0x2a19, 0x1faf: 0x2a21,\n\t0x1fb0: 0x2a29, 0x1fb1: 0x2a31, 0x1fb2: 0x2a31, 0x1fb3: 0x2a31, 0x1fb4: 0x8d5d, 0x1fb5: 0x2a39,\n\t0x1fb6: 0x2a41, 0x1fb7: 0x2a49, 0x1fb8: 0x8d7d, 0x1fb9: 0x2a51, 0x1fba: 0x2a59, 0x1fbb: 0x2a61,\n\t0x1fbc: 0x2a69, 0x1fbd: 0x2a71, 0x1fbe: 0x2a79, 0x1fbf: 0x2a81,\n\t// Block 0x7f, offset 0x1fc0\n\t0x1fc0: 0x2a89, 0x1fc1: 0x2a91, 0x1fc2: 0x2a99, 0x1fc3: 0x2aa1, 0x1fc4: 0x2aa9, 0x1fc5: 0x2ab1,\n\t0x1fc6: 0x2ab1, 0x1fc7: 0x2ab9, 0x1fc8: 0x2ac1, 0x1fc9: 0x2ac9, 0x1fca: 0x2ad1, 0x1fcb: 0x2ad9,\n\t0x1fcc: 0x2ae1, 0x1fcd: 0x2ae9, 0x1fce: 0x2af1, 0x1fcf: 0x2af9, 0x1fd0: 0x2b01, 0x1fd1: 0x2b09,\n\t0x1fd2: 0x2b11, 0x1fd3: 0x2b19, 0x1fd4: 0x2b21, 0x1fd5: 0x2b29, 0x1fd6: 0x2b31, 0x1fd7: 0x2b39,\n\t0x1fd8: 0x2b41, 0x1fd9: 0x8d9d, 0x1fda: 0x2b49, 0x1fdb: 0x2b51, 0x1fdc: 0x2b59, 0x1fdd: 0x2751,\n\t0x1fde: 0x2b61, 0x1fdf: 0x2b69, 0x1fe0: 0x8dbd, 0x1fe1: 0x8ddd, 0x1fe2: 0x2b71, 0x1fe3: 0x2b79,\n\t0x1fe4: 0x2b81, 0x1fe5: 0x2b89, 0x1fe6: 0x2b91, 0x1fe7: 0x2b99, 0x1fe8: 0x2040, 0x1fe9: 0x2ba1,\n\t0x1fea: 0x2ba9, 0x1feb: 0x2ba9, 0x1fec: 0x8dfd, 0x1fed: 0x2bb1, 0x1fee: 0x2bb9, 0x1fef: 0x2bc1,\n\t0x1ff0: 0x2bc9, 0x1ff1: 0x8e1d, 0x1ff2: 0x2bd1, 0x1ff3: 0x2bd9, 0x1ff4: 0x2040, 0x1ff5: 0x2be1,\n\t0x1ff6: 0x2be9, 0x1ff7: 0x2bf1, 0x1ff8: 0x2bf9, 0x1ff9: 0x2c01, 0x1ffa: 0x2c09, 0x1ffb: 0x8e3d,\n\t0x1ffc: 0x2c11, 0x1ffd: 0x8e5d, 0x1ffe: 0x2c19, 0x1fff: 0x2c21,\n\t// Block 0x80, offset 0x2000\n\t0x2000: 0x2c29, 0x2001: 0x2c31, 0x2002: 0x2c39, 0x2003: 0x2c41, 0x2004: 0x2c49, 0x2005: 0x2c51,\n\t0x2006: 0x2c59, 0x2007: 0x2c61, 0x2008: 0x2c69, 0x2009: 0x8e7d, 0x200a: 0x2c71, 0x200b: 0x2c79,\n\t0x200c: 0x2c81, 0x200d: 0x2c89, 0x200e: 0x2c91, 0x200f: 0x8e9d, 0x2010: 0x2c99, 0x2011: 0x8ebd,\n\t0x2012: 0x8edd, 0x2013: 0x2ca1, 0x2014: 0x2ca9, 0x2015: 0x2ca9, 0x2016: 0x2cb1, 0x2017: 0x8efd,\n\t0x2018: 0x8f1d, 0x2019: 0x2cb9, 0x201a: 0x2cc1, 0x201b: 0x2cc9, 0x201c: 0x2cd1, 0x201d: 0x2cd9,\n\t0x201e: 0x2ce1, 0x201f: 0x2ce9, 0x2020: 0x2cf1, 0x2021: 0x2cf9, 0x2022: 0x2d01, 0x2023: 0x2d09,\n\t0x2024: 0x8f3d, 0x2025: 0x2d11, 0x2026: 0x2d19, 0x2027: 0x2d21, 0x2028: 0x2d29, 0x2029: 0x2d21,\n\t0x202a: 0x2d31, 0x202b: 0x2d39, 0x202c: 0x2d41, 0x202d: 0x2d49, 0x202e: 0x2d51, 0x202f: 0x2d59,\n\t0x2030: 0x2d61, 0x2031: 0x2d69, 0x2032: 0x2d71, 0x2033: 0x2d79, 0x2034: 0x2d81, 0x2035: 0x2d89,\n\t0x2036: 0x2d91, 0x2037: 0x2d99, 0x2038: 0x8f5d, 0x2039: 0x2da1, 0x203a: 0x2da9, 0x203b: 0x2db1,\n\t0x203c: 0x2db9, 0x203d: 0x2dc1, 0x203e: 0x8f7d, 0x203f: 0x2dc9,\n\t// Block 0x81, offset 0x2040\n\t0x2040: 0x2dd1, 0x2041: 0x2dd9, 0x2042: 0x2de1, 0x2043: 0x2de9, 0x2044: 0x2df1, 0x2045: 0x2df9,\n\t0x2046: 0x2e01, 0x2047: 0x2e09, 0x2048: 0x2e11, 0x2049: 0x2e19, 0x204a: 0x8f9d, 0x204b: 0x2e21,\n\t0x204c: 0x2e29, 0x204d: 0x2e31, 0x204e: 0x2e39, 0x204f: 0x2e41, 0x2050: 0x2e49, 0x2051: 0x2e51,\n\t0x2052: 0x2e59, 0x2053: 0x2e61, 0x2054: 0x2e69, 0x2055: 0x2e71, 0x2056: 0x2e79, 0x2057: 0x2e81,\n\t0x2058: 0x2e89, 0x2059: 0x2e91, 0x205a: 0x2e99, 0x205b: 0x2ea1, 0x205c: 0x2ea9, 0x205d: 0x8fbd,\n\t0x205e: 0x2eb1, 0x205f: 0x2eb9, 0x2060: 0x2ec1, 0x2061: 0x2ec9, 0x2062: 0x2ed1, 0x2063: 0x8fdd,\n\t0x2064: 0x2ed9, 0x2065: 0x2ee1, 0x2066: 0x2ee9, 0x2067: 0x2ef1, 0x2068: 0x2ef9, 0x2069: 0x2f01,\n\t0x206a: 0x2f09, 0x206b: 0x2f11, 0x206c: 0x7f0d, 0x206d: 0x2f19, 0x206e: 0x2f21, 0x206f: 0x2f29,\n\t0x2070: 0x8ffd, 0x2071: 0x2f31, 0x2072: 0x2f39, 0x2073: 0x2f41, 0x2074: 0x2f49, 0x2075: 0x2f51,\n\t0x2076: 0x2f59, 0x2077: 0x901d, 0x2078: 0x903d, 0x2079: 0x905d, 0x207a: 0x2f61, 0x207b: 0x907d,\n\t0x207c: 0x2f69, 0x207d: 0x2f71, 0x207e: 0x2f79, 0x207f: 0x2f81,\n\t// Block 0x82, offset 0x2080\n\t0x2080: 0x2f89, 0x2081: 0x2f91, 0x2082: 0x2f99, 0x2083: 0x2fa1, 0x2084: 0x2fa9, 0x2085: 0x2fb1,\n\t0x2086: 0x909d, 0x2087: 0x2fb9, 0x2088: 0x2fc1, 0x2089: 0x2fc9, 0x208a: 0x2fd1, 0x208b: 0x2fd9,\n\t0x208c: 0x2fe1, 0x208d: 0x90bd, 0x208e: 0x2fe9, 0x208f: 0x2ff1, 0x2090: 0x90dd, 0x2091: 0x90fd,\n\t0x2092: 0x2ff9, 0x2093: 0x3001, 0x2094: 0x3009, 0x2095: 0x3011, 0x2096: 0x3019, 0x2097: 0x3021,\n\t0x2098: 0x3029, 0x2099: 0x3031, 0x209a: 0x3039, 0x209b: 0x911d, 0x209c: 0x3041, 0x209d: 0x913d,\n\t0x209e: 0x3049, 0x209f: 0x2040, 0x20a0: 0x3051, 0x20a1: 0x3059, 0x20a2: 0x3061, 0x20a3: 0x915d,\n\t0x20a4: 0x3069, 0x20a5: 0x3071, 0x20a6: 0x917d, 0x20a7: 0x919d, 0x20a8: 0x3079, 0x20a9: 0x3081,\n\t0x20aa: 0x3089, 0x20ab: 0x3091, 0x20ac: 0x3099, 0x20ad: 0x3099, 0x20ae: 0x30a1, 0x20af: 0x30a9,\n\t0x20b0: 0x30b1, 0x20b1: 0x30b9, 0x20b2: 0x30c1, 0x20b3: 0x30c9, 0x20b4: 0x30d1, 0x20b5: 0x91bd,\n\t0x20b6: 0x30d9, 0x20b7: 0x91dd, 0x20b8: 0x30e1, 0x20b9: 0x91fd, 0x20ba: 0x30e9, 0x20bb: 0x921d,\n\t0x20bc: 0x923d, 0x20bd: 0x925d, 0x20be: 0x30f1, 0x20bf: 0x30f9,\n\t// Block 0x83, offset 0x20c0\n\t0x20c0: 0x3101, 0x20c1: 0x927d, 0x20c2: 0x929d, 0x20c3: 0x92bd, 0x20c4: 0x92dd, 0x20c5: 0x3109,\n\t0x20c6: 0x3111, 0x20c7: 0x3111, 0x20c8: 0x3119, 0x20c9: 0x3121, 0x20ca: 0x3129, 0x20cb: 0x3131,\n\t0x20cc: 0x3139, 0x20cd: 0x92fd, 0x20ce: 0x3141, 0x20cf: 0x3149, 0x20d0: 0x3151, 0x20d1: 0x3159,\n\t0x20d2: 0x931d, 0x20d3: 0x3161, 0x20d4: 0x933d, 0x20d5: 0x935d, 0x20d6: 0x3169, 0x20d7: 0x3171,\n\t0x20d8: 0x3179, 0x20d9: 0x3181, 0x20da: 0x3189, 0x20db: 0x3191, 0x20dc: 0x937d, 0x20dd: 0x939d,\n\t0x20de: 0x93bd, 0x20df: 0x2040, 0x20e0: 0x3199, 0x20e1: 0x93dd, 0x20e2: 0x31a1, 0x20e3: 0x31a9,\n\t0x20e4: 0x31b1, 0x20e5: 0x93fd, 0x20e6: 0x31b9, 0x20e7: 0x31c1, 0x20e8: 0x31c9, 0x20e9: 0x31d1,\n\t0x20ea: 0x31d9, 0x20eb: 0x941d, 0x20ec: 0x31e1, 0x20ed: 0x31e9, 0x20ee: 0x31f1, 0x20ef: 0x31f9,\n\t0x20f0: 0x3201, 0x20f1: 0x3209, 0x20f2: 0x943d, 0x20f3: 0x945d, 0x20f4: 0x3211, 0x20f5: 0x947d,\n\t0x20f6: 0x3219, 0x20f7: 0x949d, 0x20f8: 0x3221, 0x20f9: 0x3229, 0x20fa: 0x3231, 0x20fb: 0x94bd,\n\t0x20fc: 0x94dd, 0x20fd: 0x3239, 0x20fe: 0x94fd, 0x20ff: 0x3241,\n\t// Block 0x84, offset 0x2100\n\t0x2100: 0x951d, 0x2101: 0x3249, 0x2102: 0x3251, 0x2103: 0x3259, 0x2104: 0x3261, 0x2105: 0x3269,\n\t0x2106: 0x3271, 0x2107: 0x953d, 0x2108: 0x955d, 0x2109: 0x957d, 0x210a: 0x959d, 0x210b: 0x2ca1,\n\t0x210c: 0x3279, 0x210d: 0x3281, 0x210e: 0x3289, 0x210f: 0x3291, 0x2110: 0x3299, 0x2111: 0x32a1,\n\t0x2112: 0x32a9, 0x2113: 0x32b1, 0x2114: 0x32b9, 0x2115: 0x32c1, 0x2116: 0x32c9, 0x2117: 0x95bd,\n\t0x2118: 0x32d1, 0x2119: 0x32d9, 0x211a: 0x32e1, 0x211b: 0x32e9, 0x211c: 0x32f1, 0x211d: 0x32f9,\n\t0x211e: 0x3301, 0x211f: 0x3309, 0x2120: 0x3311, 0x2121: 0x3319, 0x2122: 0x3321, 0x2123: 0x3329,\n\t0x2124: 0x95dd, 0x2125: 0x95fd, 0x2126: 0x961d, 0x2127: 0x3331, 0x2128: 0x3339, 0x2129: 0x3341,\n\t0x212a: 0x3349, 0x212b: 0x963d, 0x212c: 0x3351, 0x212d: 0x965d, 0x212e: 0x3359, 0x212f: 0x3361,\n\t0x2130: 0x967d, 0x2131: 0x969d, 0x2132: 0x3369, 0x2133: 0x3371, 0x2134: 0x3379, 0x2135: 0x3381,\n\t0x2136: 0x3389, 0x2137: 0x3391, 0x2138: 0x3399, 0x2139: 0x33a1, 0x213a: 0x33a9, 0x213b: 0x33b1,\n\t0x213c: 0x33b9, 0x213d: 0x33c1, 0x213e: 0x33c9, 0x213f: 0x2040,\n\t// Block 0x85, offset 0x2140\n\t0x2140: 0x33d1, 0x2141: 0x33d9, 0x2142: 0x33e1, 0x2143: 0x33e9, 0x2144: 0x33f1, 0x2145: 0x96bd,\n\t0x2146: 0x33f9, 0x2147: 0x3401, 0x2148: 0x3409, 0x2149: 0x3411, 0x214a: 0x3419, 0x214b: 0x96dd,\n\t0x214c: 0x96fd, 0x214d: 0x3421, 0x214e: 0x3429, 0x214f: 0x3431, 0x2150: 0x3439, 0x2151: 0x3441,\n\t0x2152: 0x3449, 0x2153: 0x971d, 0x2154: 0x3451, 0x2155: 0x3459, 0x2156: 0x3461, 0x2157: 0x3469,\n\t0x2158: 0x973d, 0x2159: 0x975d, 0x215a: 0x3471, 0x215b: 0x3479, 0x215c: 0x3481, 0x215d: 0x977d,\n\t0x215e: 0x3489, 0x215f: 0x3491, 0x2160: 0x684d, 0x2161: 0x979d, 0x2162: 0x3499, 0x2163: 0x34a1,\n\t0x2164: 0x34a9, 0x2165: 0x97bd, 0x2166: 0x34b1, 0x2167: 0x34b9, 0x2168: 0x34c1, 0x2169: 0x34c9,\n\t0x216a: 0x34d1, 0x216b: 0x34d9, 0x216c: 0x34e1, 0x216d: 0x97dd, 0x216e: 0x34e9, 0x216f: 0x34f1,\n\t0x2170: 0x34f9, 0x2171: 0x97fd, 0x2172: 0x3501, 0x2173: 0x3509, 0x2174: 0x3511, 0x2175: 0x3519,\n\t0x2176: 0x7b6d, 0x2177: 0x981d, 0x2178: 0x3521, 0x2179: 0x3529, 0x217a: 0x3531, 0x217b: 0x983d,\n\t0x217c: 0x3539, 0x217d: 0x985d, 0x217e: 0x3541, 0x217f: 0x3541,\n\t// Block 0x86, offset 0x2180\n\t0x2180: 0x3549, 0x2181: 0x987d, 0x2182: 0x3551, 0x2183: 0x3559, 0x2184: 0x3561, 0x2185: 0x3569,\n\t0x2186: 0x3571, 0x2187: 0x3579, 0x2188: 0x3581, 0x2189: 0x989d, 0x218a: 0x3589, 0x218b: 0x3591,\n\t0x218c: 0x3599, 0x218d: 0x35a1, 0x218e: 0x35a9, 0x218f: 0x35b1, 0x2190: 0x98bd, 0x2191: 0x35b9,\n\t0x2192: 0x98dd, 0x2193: 0x98fd, 0x2194: 0x991d, 0x2195: 0x35c1, 0x2196: 0x35c9, 0x2197: 0x35d1,\n\t0x2198: 0x35d9, 0x2199: 0x35e1, 0x219a: 0x35e9, 0x219b: 0x35f1, 0x219c: 0x35f9, 0x219d: 0x993d,\n\t0x219e: 0x0040, 0x219f: 0x0040, 0x21a0: 0x0040, 0x21a1: 0x0040, 0x21a2: 0x0040, 0x21a3: 0x0040,\n\t0x21a4: 0x0040, 0x21a5: 0x0040, 0x21a6: 0x0040, 0x21a7: 0x0040, 0x21a8: 0x0040, 0x21a9: 0x0040,\n\t0x21aa: 0x0040, 0x21ab: 0x0040, 0x21ac: 0x0040, 0x21ad: 0x0040, 0x21ae: 0x0040, 0x21af: 0x0040,\n\t0x21b0: 0x0040, 0x21b1: 0x0040, 0x21b2: 0x0040, 0x21b3: 0x0040, 0x21b4: 0x0040, 0x21b5: 0x0040,\n\t0x21b6: 0x0040, 0x21b7: 0x0040, 0x21b8: 0x0040, 0x21b9: 0x0040, 0x21ba: 0x0040, 0x21bb: 0x0040,\n\t0x21bc: 0x0040, 0x21bd: 0x0040, 0x21be: 0x0040, 0x21bf: 0x0040,\n}\n\n// idnaIndex: 39 blocks, 2496 entries, 4992 bytes\n// Block 0 is the zero block.\nvar idnaIndex = [2496]uint16{\n\t// Block 0x0, offset 0x0\n\t// Block 0x1, offset 0x40\n\t// Block 0x2, offset 0x80\n\t// Block 0x3, offset 0xc0\n\t0xc2: 0x01, 0xc3: 0x85, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05,\n\t0xc8: 0x06, 0xc9: 0x86, 0xca: 0x87, 0xcb: 0x07, 0xcc: 0x88, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a,\n\t0xd0: 0x89, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x8a, 0xd6: 0x8b, 0xd7: 0x8c,\n\t0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x8d, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x8e, 0xde: 0x8f, 0xdf: 0x90,\n\t0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07,\n\t0xe8: 0x07, 0xe9: 0x07, 0xea: 0x08, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x09, 0xee: 0x0a, 0xef: 0x0b,\n\t0xf0: 0x20, 0xf1: 0x21, 0xf2: 0x21, 0xf3: 0x23, 0xf4: 0x24,\n\t// Block 0x4, offset 0x100\n\t0x120: 0x91, 0x121: 0x13, 0x122: 0x14, 0x123: 0x92, 0x124: 0x93, 0x125: 0x15, 0x126: 0x16, 0x127: 0x17,\n\t0x128: 0x18, 0x129: 0x19, 0x12a: 0x1a, 0x12b: 0x1b, 0x12c: 0x1c, 0x12d: 0x1d, 0x12e: 0x1e, 0x12f: 0x94,\n\t0x130: 0x95, 0x131: 0x1f, 0x132: 0x20, 0x133: 0x21, 0x134: 0x96, 0x135: 0x22, 0x136: 0x97, 0x137: 0x98,\n\t0x138: 0x99, 0x139: 0x9a, 0x13a: 0x23, 0x13b: 0x9b, 0x13c: 0x9c, 0x13d: 0x24, 0x13e: 0x25, 0x13f: 0x9d,\n\t// Block 0x5, offset 0x140\n\t0x140: 0x9e, 0x141: 0x9f, 0x142: 0xa0, 0x143: 0xa1, 0x144: 0xa2, 0x145: 0xa3, 0x146: 0xa4, 0x147: 0xa5,\n\t0x148: 0xa6, 0x149: 0xa7, 0x14a: 0xa8, 0x14b: 0xa9, 0x14c: 0xaa, 0x14d: 0xab, 0x14e: 0xac, 0x14f: 0xad,\n\t0x150: 0xae, 0x151: 0xa6, 0x152: 0xa6, 0x153: 0xa6, 0x154: 0xa6, 0x155: 0xa6, 0x156: 0xa6, 0x157: 0xa6,\n\t0x158: 0xa6, 0x159: 0xaf, 0x15a: 0xb0, 0x15b: 0xb1, 0x15c: 0xb2, 0x15d: 0xb3, 0x15e: 0xb4, 0x15f: 0xb5,\n\t0x160: 0xb6, 0x161: 0xb7, 0x162: 0xb8, 0x163: 0xb9, 0x164: 0xba, 0x165: 0xbb, 0x166: 0xbc, 0x167: 0xbd,\n\t0x168: 0xbe, 0x169: 0xbf, 0x16a: 0xc0, 0x16b: 0xc1, 0x16c: 0xc2, 0x16d: 0xc3, 0x16e: 0xc4, 0x16f: 0xc5,\n\t0x170: 0xc6, 0x171: 0xc7, 0x172: 0xc8, 0x173: 0xc9, 0x174: 0x26, 0x175: 0x27, 0x176: 0x28, 0x177: 0x88,\n\t0x178: 0x29, 0x179: 0x29, 0x17a: 0x2a, 0x17b: 0x29, 0x17c: 0xca, 0x17d: 0x2b, 0x17e: 0x2c, 0x17f: 0x2d,\n\t// Block 0x6, offset 0x180\n\t0x180: 0x2e, 0x181: 0x2f, 0x182: 0x30, 0x183: 0xcb, 0x184: 0x31, 0x185: 0x32, 0x186: 0xcc, 0x187: 0xa2,\n\t0x188: 0xcd, 0x189: 0xce, 0x18a: 0xa2, 0x18b: 0xa2, 0x18c: 0xcf, 0x18d: 0xa2, 0x18e: 0xa2, 0x18f: 0xa2,\n\t0x190: 0xd0, 0x191: 0x33, 0x192: 0x34, 0x193: 0x35, 0x194: 0xa2, 0x195: 0xa2, 0x196: 0xa2, 0x197: 0xa2,\n\t0x198: 0xa2, 0x199: 0xa2, 0x19a: 0xa2, 0x19b: 0xa2, 0x19c: 0xa2, 0x19d: 0xa2, 0x19e: 0xa2, 0x19f: 0xa2,\n\t0x1a0: 0xa2, 0x1a1: 0xa2, 0x1a2: 0xa2, 0x1a3: 0xa2, 0x1a4: 0xa2, 0x1a5: 0xa2, 0x1a6: 0xa2, 0x1a7: 0xa2,\n\t0x1a8: 0xd1, 0x1a9: 0xd2, 0x1aa: 0xa2, 0x1ab: 0xd3, 0x1ac: 0xa2, 0x1ad: 0xd4, 0x1ae: 0xd5, 0x1af: 0xa2,\n\t0x1b0: 0xd6, 0x1b1: 0x36, 0x1b2: 0x29, 0x1b3: 0x37, 0x1b4: 0xd7, 0x1b5: 0xd8, 0x1b6: 0xd9, 0x1b7: 0xda,\n\t0x1b8: 0xdb, 0x1b9: 0xdc, 0x1ba: 0xdd, 0x1bb: 0xde, 0x1bc: 0xdf, 0x1bd: 0xe0, 0x1be: 0xe1, 0x1bf: 0x38,\n\t// Block 0x7, offset 0x1c0\n\t0x1c0: 0x39, 0x1c1: 0xe2, 0x1c2: 0xe3, 0x1c3: 0xe4, 0x1c4: 0xe5, 0x1c5: 0x3a, 0x1c6: 0x3b, 0x1c7: 0xe6,\n\t0x1c8: 0xe7, 0x1c9: 0x3c, 0x1ca: 0x3d, 0x1cb: 0x3e, 0x1cc: 0xe8, 0x1cd: 0xe9, 0x1ce: 0x3f, 0x1cf: 0x40,\n\t0x1d0: 0xa6, 0x1d1: 0xa6, 0x1d2: 0xa6, 0x1d3: 0xa6, 0x1d4: 0xa6, 0x1d5: 0xa6, 0x1d6: 0xa6, 0x1d7: 0xa6,\n\t0x1d8: 0xa6, 0x1d9: 0xa6, 0x1da: 0xa6, 0x1db: 0xa6, 0x1dc: 0xa6, 0x1dd: 0xa6, 0x1de: 0xa6, 0x1df: 0xa6,\n\t0x1e0: 0xa6, 0x1e1: 0xa6, 0x1e2: 0xa6, 0x1e3: 0xa6, 0x1e4: 0xa6, 0x1e5: 0xa6, 0x1e6: 0xa6, 0x1e7: 0xa6,\n\t0x1e8: 0xa6, 0x1e9: 0xa6, 0x1ea: 0xa6, 0x1eb: 0xa6, 0x1ec: 0xa6, 0x1ed: 0xa6, 0x1ee: 0xa6, 0x1ef: 0xa6,\n\t0x1f0: 0xa6, 0x1f1: 0xa6, 0x1f2: 0xa6, 0x1f3: 0xa6, 0x1f4: 0xa6, 0x1f5: 0xa6, 0x1f6: 0xa6, 0x1f7: 0xa6,\n\t0x1f8: 0xa6, 0x1f9: 0xa6, 0x1fa: 0xa6, 0x1fb: 0xa6, 0x1fc: 0xa6, 0x1fd: 0xa6, 0x1fe: 0xa6, 0x1ff: 0xa6,\n\t// Block 0x8, offset 0x200\n\t0x200: 0xa6, 0x201: 0xa6, 0x202: 0xa6, 0x203: 0xa6, 0x204: 0xa6, 0x205: 0xa6, 0x206: 0xa6, 0x207: 0xa6,\n\t0x208: 0xa6, 0x209: 0xa6, 0x20a: 0xa6, 0x20b: 0xa6, 0x20c: 0xa6, 0x20d: 0xa6, 0x20e: 0xa6, 0x20f: 0xa6,\n\t0x210: 0xa6, 0x211: 0xa6, 0x212: 0xa6, 0x213: 0xa6, 0x214: 0xa6, 0x215: 0xa6, 0x216: 0xa6, 0x217: 0xa6,\n\t0x218: 0xa6, 0x219: 0xa6, 0x21a: 0xa6, 0x21b: 0xa6, 0x21c: 0xa6, 0x21d: 0xa6, 0x21e: 0xa6, 0x21f: 0xa6,\n\t0x220: 0xa6, 0x221: 0xa6, 0x222: 0xa6, 0x223: 0xa6, 0x224: 0xa6, 0x225: 0xa6, 0x226: 0xa6, 0x227: 0xa6,\n\t0x228: 0xa6, 0x229: 0xa6, 0x22a: 0xa6, 0x22b: 0xa6, 0x22c: 0xa6, 0x22d: 0xa6, 0x22e: 0xa6, 0x22f: 0xa6,\n\t0x230: 0xa6, 0x231: 0xa6, 0x232: 0xa6, 0x233: 0xa6, 0x234: 0xa6, 0x235: 0xa6, 0x236: 0xa6, 0x237: 0xa2,\n\t0x238: 0xa6, 0x239: 0xa6, 0x23a: 0xa6, 0x23b: 0xa6, 0x23c: 0xa6, 0x23d: 0xa6, 0x23e: 0xa6, 0x23f: 0xa6,\n\t// Block 0x9, offset 0x240\n\t0x240: 0xa6, 0x241: 0xa6, 0x242: 0xa6, 0x243: 0xa6, 0x244: 0xa6, 0x245: 0xa6, 0x246: 0xa6, 0x247: 0xa6,\n\t0x248: 0xa6, 0x249: 0xa6, 0x24a: 0xa6, 0x24b: 0xa6, 0x24c: 0xa6, 0x24d: 0xa6, 0x24e: 0xa6, 0x24f: 0xa6,\n\t0x250: 0xa6, 0x251: 0xa6, 0x252: 0xa6, 0x253: 0xa6, 0x254: 0xa6, 0x255: 0xa6, 0x256: 0xa6, 0x257: 0xa6,\n\t0x258: 0xa6, 0x259: 0xa6, 0x25a: 0xa6, 0x25b: 0xa6, 0x25c: 0xa6, 0x25d: 0xa6, 0x25e: 0xa6, 0x25f: 0xa6,\n\t0x260: 0xa6, 0x261: 0xa6, 0x262: 0xa6, 0x263: 0xa6, 0x264: 0xa6, 0x265: 0xa6, 0x266: 0xa6, 0x267: 0xa6,\n\t0x268: 0xa6, 0x269: 0xa6, 0x26a: 0xa6, 0x26b: 0xa6, 0x26c: 0xa6, 0x26d: 0xa6, 0x26e: 0xa6, 0x26f: 0xa6,\n\t0x270: 0xa6, 0x271: 0xa6, 0x272: 0xa6, 0x273: 0xa6, 0x274: 0xa6, 0x275: 0xa6, 0x276: 0xa6, 0x277: 0xa6,\n\t0x278: 0xa6, 0x279: 0xa6, 0x27a: 0xa6, 0x27b: 0xa6, 0x27c: 0xa6, 0x27d: 0xa6, 0x27e: 0xa6, 0x27f: 0xa6,\n\t// Block 0xa, offset 0x280\n\t0x280: 0xa6, 0x281: 0xa6, 0x282: 0xa6, 0x283: 0xa6, 0x284: 0xa6, 0x285: 0xa6, 0x286: 0xa6, 0x287: 0xa6,\n\t0x288: 0xa6, 0x289: 0xa6, 0x28a: 0xa6, 0x28b: 0xa6, 0x28c: 0xa6, 0x28d: 0xa6, 0x28e: 0xa6, 0x28f: 0xa6,\n\t0x290: 0xa6, 0x291: 0xa6, 0x292: 0xea, 0x293: 0xeb, 0x294: 0xa6, 0x295: 0xa6, 0x296: 0xa6, 0x297: 0xa6,\n\t0x298: 0xec, 0x299: 0x41, 0x29a: 0x42, 0x29b: 0xed, 0x29c: 0x43, 0x29d: 0x44, 0x29e: 0x45, 0x29f: 0x46,\n\t0x2a0: 0xee, 0x2a1: 0xef, 0x2a2: 0xf0, 0x2a3: 0xf1, 0x2a4: 0xf2, 0x2a5: 0xf3, 0x2a6: 0xf4, 0x2a7: 0xf5,\n\t0x2a8: 0xf6, 0x2a9: 0xf7, 0x2aa: 0xf8, 0x2ab: 0xf9, 0x2ac: 0xfa, 0x2ad: 0xfb, 0x2ae: 0xfc, 0x2af: 0xfd,\n\t0x2b0: 0xa6, 0x2b1: 0xa6, 0x2b2: 0xa6, 0x2b3: 0xa6, 0x2b4: 0xa6, 0x2b5: 0xa6, 0x2b6: 0xa6, 0x2b7: 0xa6,\n\t0x2b8: 0xa6, 0x2b9: 0xa6, 0x2ba: 0xa6, 0x2bb: 0xa6, 0x2bc: 0xa6, 0x2bd: 0xa6, 0x2be: 0xa6, 0x2bf: 0xa6,\n\t// Block 0xb, offset 0x2c0\n\t0x2c0: 0xa6, 0x2c1: 0xa6, 0x2c2: 0xa6, 0x2c3: 0xa6, 0x2c4: 0xa6, 0x2c5: 0xa6, 0x2c6: 0xa6, 0x2c7: 0xa6,\n\t0x2c8: 0xa6, 0x2c9: 0xa6, 0x2ca: 0xa6, 0x2cb: 0xa6, 0x2cc: 0xa6, 0x2cd: 0xa6, 0x2ce: 0xa6, 0x2cf: 0xa6,\n\t0x2d0: 0xa6, 0x2d1: 0xa6, 0x2d2: 0xa6, 0x2d3: 0xa6, 0x2d4: 0xa6, 0x2d5: 0xa6, 0x2d6: 0xa6, 0x2d7: 0xa6,\n\t0x2d8: 0xa6, 0x2d9: 0xa6, 0x2da: 0xa6, 0x2db: 0xa6, 0x2dc: 0xa6, 0x2dd: 0xa6, 0x2de: 0xfe, 0x2df: 0xff,\n\t// Block 0xc, offset 0x300\n\t0x300: 0x100, 0x301: 0x100, 0x302: 0x100, 0x303: 0x100, 0x304: 0x100, 0x305: 0x100, 0x306: 0x100, 0x307: 0x100,\n\t0x308: 0x100, 0x309: 0x100, 0x30a: 0x100, 0x30b: 0x100, 0x30c: 0x100, 0x30d: 0x100, 0x30e: 0x100, 0x30f: 0x100,\n\t0x310: 0x100, 0x311: 0x100, 0x312: 0x100, 0x313: 0x100, 0x314: 0x100, 0x315: 0x100, 0x316: 0x100, 0x317: 0x100,\n\t0x318: 0x100, 0x319: 0x100, 0x31a: 0x100, 0x31b: 0x100, 0x31c: 0x100, 0x31d: 0x100, 0x31e: 0x100, 0x31f: 0x100,\n\t0x320: 0x100, 0x321: 0x100, 0x322: 0x100, 0x323: 0x100, 0x324: 0x100, 0x325: 0x100, 0x326: 0x100, 0x327: 0x100,\n\t0x328: 0x100, 0x329: 0x100, 0x32a: 0x100, 0x32b: 0x100, 0x32c: 0x100, 0x32d: 0x100, 0x32e: 0x100, 0x32f: 0x100,\n\t0x330: 0x100, 0x331: 0x100, 0x332: 0x100, 0x333: 0x100, 0x334: 0x100, 0x335: 0x100, 0x336: 0x100, 0x337: 0x100,\n\t0x338: 0x100, 0x339: 0x100, 0x33a: 0x100, 0x33b: 0x100, 0x33c: 0x100, 0x33d: 0x100, 0x33e: 0x100, 0x33f: 0x100,\n\t// Block 0xd, offset 0x340\n\t0x340: 0x100, 0x341: 0x100, 0x342: 0x100, 0x343: 0x100, 0x344: 0x100, 0x345: 0x100, 0x346: 0x100, 0x347: 0x100,\n\t0x348: 0x100, 0x349: 0x100, 0x34a: 0x100, 0x34b: 0x100, 0x34c: 0x100, 0x34d: 0x100, 0x34e: 0x100, 0x34f: 0x100,\n\t0x350: 0x100, 0x351: 0x100, 0x352: 0x100, 0x353: 0x100, 0x354: 0x100, 0x355: 0x100, 0x356: 0x100, 0x357: 0x100,\n\t0x358: 0x100, 0x359: 0x100, 0x35a: 0x100, 0x35b: 0x100, 0x35c: 0x100, 0x35d: 0x100, 0x35e: 0x100, 0x35f: 0x100,\n\t0x360: 0x100, 0x361: 0x100, 0x362: 0x100, 0x363: 0x100, 0x364: 0x101, 0x365: 0x102, 0x366: 0x103, 0x367: 0x104,\n\t0x368: 0x47, 0x369: 0x105, 0x36a: 0x106, 0x36b: 0x48, 0x36c: 0x49, 0x36d: 0x4a, 0x36e: 0x4b, 0x36f: 0x4c,\n\t0x370: 0x107, 0x371: 0x4d, 0x372: 0x4e, 0x373: 0x4f, 0x374: 0x50, 0x375: 0x51, 0x376: 0x108, 0x377: 0x52,\n\t0x378: 0x53, 0x379: 0x54, 0x37a: 0x55, 0x37b: 0x56, 0x37c: 0x57, 0x37d: 0x58, 0x37e: 0x59, 0x37f: 0x5a,\n\t// Block 0xe, offset 0x380\n\t0x380: 0x109, 0x381: 0x10a, 0x382: 0xa6, 0x383: 0x10b, 0x384: 0x10c, 0x385: 0xa2, 0x386: 0x10d, 0x387: 0x10e,\n\t0x388: 0x100, 0x389: 0x100, 0x38a: 0x10f, 0x38b: 0x110, 0x38c: 0x111, 0x38d: 0x112, 0x38e: 0x113, 0x38f: 0x114,\n\t0x390: 0x115, 0x391: 0xa6, 0x392: 0x116, 0x393: 0x117, 0x394: 0x118, 0x395: 0x5b, 0x396: 0x5c, 0x397: 0x100,\n\t0x398: 0xa6, 0x399: 0xa6, 0x39a: 0xa6, 0x39b: 0xa6, 0x39c: 0x119, 0x39d: 0x11a, 0x39e: 0x5d, 0x39f: 0x100,\n\t0x3a0: 0x11b, 0x3a1: 0x11c, 0x3a2: 0x11d, 0x3a3: 0x11e, 0x3a4: 0x11f, 0x3a5: 0x100, 0x3a6: 0x120, 0x3a7: 0x121,\n\t0x3a8: 0x122, 0x3a9: 0x123, 0x3aa: 0x124, 0x3ab: 0x5e, 0x3ac: 0x125, 0x3ad: 0x126, 0x3ae: 0x5f, 0x3af: 0x100,\n\t0x3b0: 0x127, 0x3b1: 0x128, 0x3b2: 0x129, 0x3b3: 0x12a, 0x3b4: 0x12b, 0x3b5: 0x100, 0x3b6: 0x100, 0x3b7: 0x100,\n\t0x3b8: 0x100, 0x3b9: 0x12c, 0x3ba: 0x12d, 0x3bb: 0x12e, 0x3bc: 0x12f, 0x3bd: 0x130, 0x3be: 0x131, 0x3bf: 0x132,\n\t// Block 0xf, offset 0x3c0\n\t0x3c0: 0x133, 0x3c1: 0x134, 0x3c2: 0x135, 0x3c3: 0x136, 0x3c4: 0x137, 0x3c5: 0x138, 0x3c6: 0x139, 0x3c7: 0x13a,\n\t0x3c8: 0x13b, 0x3c9: 0x13c, 0x3ca: 0x13d, 0x3cb: 0x13e, 0x3cc: 0x60, 0x3cd: 0x61, 0x3ce: 0x100, 0x3cf: 0x100,\n\t0x3d0: 0x13f, 0x3d1: 0x140, 0x3d2: 0x141, 0x3d3: 0x142, 0x3d4: 0x100, 0x3d5: 0x100, 0x3d6: 0x143, 0x3d7: 0x144,\n\t0x3d8: 0x145, 0x3d9: 0x146, 0x3da: 0x147, 0x3db: 0x148, 0x3dc: 0x149, 0x3dd: 0x14a, 0x3de: 0x100, 0x3df: 0x100,\n\t0x3e0: 0x14b, 0x3e1: 0x100, 0x3e2: 0x14c, 0x3e3: 0x14d, 0x3e4: 0x62, 0x3e5: 0x14e, 0x3e6: 0x14f, 0x3e7: 0x150,\n\t0x3e8: 0x151, 0x3e9: 0x152, 0x3ea: 0x153, 0x3eb: 0x154, 0x3ec: 0x155, 0x3ed: 0x100, 0x3ee: 0x100, 0x3ef: 0x100,\n\t0x3f0: 0x156, 0x3f1: 0x157, 0x3f2: 0x158, 0x3f3: 0x100, 0x3f4: 0x159, 0x3f5: 0x15a, 0x3f6: 0x15b, 0x3f7: 0x100,\n\t0x3f8: 0x100, 0x3f9: 0x100, 0x3fa: 0x100, 0x3fb: 0x15c, 0x3fc: 0x15d, 0x3fd: 0x15e, 0x3fe: 0x15f, 0x3ff: 0x160,\n\t// Block 0x10, offset 0x400\n\t0x400: 0xa6, 0x401: 0xa6, 0x402: 0xa6, 0x403: 0xa6, 0x404: 0xa6, 0x405: 0xa6, 0x406: 0xa6, 0x407: 0xa6,\n\t0x408: 0xa6, 0x409: 0xa6, 0x40a: 0xa6, 0x40b: 0xa6, 0x40c: 0xa6, 0x40d: 0xa6, 0x40e: 0x161, 0x40f: 0x100,\n\t0x410: 0xa2, 0x411: 0x162, 0x412: 0xa6, 0x413: 0xa6, 0x414: 0xa6, 0x415: 0x163, 0x416: 0x100, 0x417: 0x100,\n\t0x418: 0x100, 0x419: 0x100, 0x41a: 0x100, 0x41b: 0x100, 0x41c: 0x100, 0x41d: 0x100, 0x41e: 0x100, 0x41f: 0x100,\n\t0x420: 0x100, 0x421: 0x100, 0x422: 0x100, 0x423: 0x100, 0x424: 0x100, 0x425: 0x100, 0x426: 0x100, 0x427: 0x100,\n\t0x428: 0x100, 0x429: 0x100, 0x42a: 0x100, 0x42b: 0x100, 0x42c: 0x100, 0x42d: 0x100, 0x42e: 0x100, 0x42f: 0x100,\n\t0x430: 0x100, 0x431: 0x100, 0x432: 0x100, 0x433: 0x100, 0x434: 0x100, 0x435: 0x100, 0x436: 0x100, 0x437: 0x100,\n\t0x438: 0x100, 0x439: 0x100, 0x43a: 0x100, 0x43b: 0x100, 0x43c: 0x100, 0x43d: 0x100, 0x43e: 0x164, 0x43f: 0x165,\n\t// Block 0x11, offset 0x440\n\t0x440: 0xa6, 0x441: 0xa6, 0x442: 0xa6, 0x443: 0xa6, 0x444: 0xa6, 0x445: 0xa6, 0x446: 0xa6, 0x447: 0xa6,\n\t0x448: 0xa6, 0x449: 0xa6, 0x44a: 0xa6, 0x44b: 0xa6, 0x44c: 0xa6, 0x44d: 0xa6, 0x44e: 0xa6, 0x44f: 0xa6,\n\t0x450: 0x166, 0x451: 0x167, 0x452: 0x100, 0x453: 0x100, 0x454: 0x100, 0x455: 0x100, 0x456: 0x100, 0x457: 0x100,\n\t0x458: 0x100, 0x459: 0x100, 0x45a: 0x100, 0x45b: 0x100, 0x45c: 0x100, 0x45d: 0x100, 0x45e: 0x100, 0x45f: 0x100,\n\t0x460: 0x100, 0x461: 0x100, 0x462: 0x100, 0x463: 0x100, 0x464: 0x100, 0x465: 0x100, 0x466: 0x100, 0x467: 0x100,\n\t0x468: 0x100, 0x469: 0x100, 0x46a: 0x100, 0x46b: 0x100, 0x46c: 0x100, 0x46d: 0x100, 0x46e: 0x100, 0x46f: 0x100,\n\t0x470: 0x100, 0x471: 0x100, 0x472: 0x100, 0x473: 0x100, 0x474: 0x100, 0x475: 0x100, 0x476: 0x100, 0x477: 0x100,\n\t0x478: 0x100, 0x479: 0x100, 0x47a: 0x100, 0x47b: 0x100, 0x47c: 0x100, 0x47d: 0x100, 0x47e: 0x100, 0x47f: 0x100,\n\t// Block 0x12, offset 0x480\n\t0x480: 0x100, 0x481: 0x100, 0x482: 0x100, 0x483: 0x100, 0x484: 0x100, 0x485: 0x100, 0x486: 0x100, 0x487: 0x100,\n\t0x488: 0x100, 0x489: 0x100, 0x48a: 0x100, 0x48b: 0x100, 0x48c: 0x100, 0x48d: 0x100, 0x48e: 0x100, 0x48f: 0x100,\n\t0x490: 0xa6, 0x491: 0xa6, 0x492: 0xa6, 0x493: 0xa6, 0x494: 0xa6, 0x495: 0xa6, 0x496: 0xa6, 0x497: 0xa6,\n\t0x498: 0xa6, 0x499: 0x14a, 0x49a: 0x100, 0x49b: 0x100, 0x49c: 0x100, 0x49d: 0x100, 0x49e: 0x100, 0x49f: 0x100,\n\t0x4a0: 0x100, 0x4a1: 0x100, 0x4a2: 0x100, 0x4a3: 0x100, 0x4a4: 0x100, 0x4a5: 0x100, 0x4a6: 0x100, 0x4a7: 0x100,\n\t0x4a8: 0x100, 0x4a9: 0x100, 0x4aa: 0x100, 0x4ab: 0x100, 0x4ac: 0x100, 0x4ad: 0x100, 0x4ae: 0x100, 0x4af: 0x100,\n\t0x4b0: 0x100, 0x4b1: 0x100, 0x4b2: 0x100, 0x4b3: 0x100, 0x4b4: 0x100, 0x4b5: 0x100, 0x4b6: 0x100, 0x4b7: 0x100,\n\t0x4b8: 0x100, 0x4b9: 0x100, 0x4ba: 0x100, 0x4bb: 0x100, 0x4bc: 0x100, 0x4bd: 0x100, 0x4be: 0x100, 0x4bf: 0x100,\n\t// Block 0x13, offset 0x4c0\n\t0x4c0: 0x100, 0x4c1: 0x100, 0x4c2: 0x100, 0x4c3: 0x100, 0x4c4: 0x100, 0x4c5: 0x100, 0x4c6: 0x100, 0x4c7: 0x100,\n\t0x4c8: 0x100, 0x4c9: 0x100, 0x4ca: 0x100, 0x4cb: 0x100, 0x4cc: 0x100, 0x4cd: 0x100, 0x4ce: 0x100, 0x4cf: 0x100,\n\t0x4d0: 0x100, 0x4d1: 0x100, 0x4d2: 0x100, 0x4d3: 0x100, 0x4d4: 0x100, 0x4d5: 0x100, 0x4d6: 0x100, 0x4d7: 0x100,\n\t0x4d8: 0x100, 0x4d9: 0x100, 0x4da: 0x100, 0x4db: 0x100, 0x4dc: 0x100, 0x4dd: 0x100, 0x4de: 0x100, 0x4df: 0x100,\n\t0x4e0: 0xa6, 0x4e1: 0xa6, 0x4e2: 0xa6, 0x4e3: 0xa6, 0x4e4: 0xa6, 0x4e5: 0xa6, 0x4e6: 0xa6, 0x4e7: 0xa6,\n\t0x4e8: 0x154, 0x4e9: 0x168, 0x4ea: 0x169, 0x4eb: 0x16a, 0x4ec: 0x16b, 0x4ed: 0x16c, 0x4ee: 0x16d, 0x4ef: 0x100,\n\t0x4f0: 0x100, 0x4f1: 0x100, 0x4f2: 0x100, 0x4f3: 0x100, 0x4f4: 0x100, 0x4f5: 0x100, 0x4f6: 0x100, 0x4f7: 0x100,\n\t0x4f8: 0x100, 0x4f9: 0x16e, 0x4fa: 0x16f, 0x4fb: 0x100, 0x4fc: 0xa6, 0x4fd: 0x170, 0x4fe: 0x171, 0x4ff: 0x172,\n\t// Block 0x14, offset 0x500\n\t0x500: 0xa6, 0x501: 0xa6, 0x502: 0xa6, 0x503: 0xa6, 0x504: 0xa6, 0x505: 0xa6, 0x506: 0xa6, 0x507: 0xa6,\n\t0x508: 0xa6, 0x509: 0xa6, 0x50a: 0xa6, 0x50b: 0xa6, 0x50c: 0xa6, 0x50d: 0xa6, 0x50e: 0xa6, 0x50f: 0xa6,\n\t0x510: 0xa6, 0x511: 0xa6, 0x512: 0xa6, 0x513: 0xa6, 0x514: 0xa6, 0x515: 0xa6, 0x516: 0xa6, 0x517: 0xa6,\n\t0x518: 0xa6, 0x519: 0xa6, 0x51a: 0xa6, 0x51b: 0xa6, 0x51c: 0xa6, 0x51d: 0xa6, 0x51e: 0xa6, 0x51f: 0x173,\n\t0x520: 0xa6, 0x521: 0xa6, 0x522: 0xa6, 0x523: 0xa6, 0x524: 0xa6, 0x525: 0xa6, 0x526: 0xa6, 0x527: 0xa6,\n\t0x528: 0xa6, 0x529: 0xa6, 0x52a: 0xa6, 0x52b: 0xa6, 0x52c: 0xa6, 0x52d: 0xa6, 0x52e: 0xa6, 0x52f: 0xa6,\n\t0x530: 0xa6, 0x531: 0xa6, 0x532: 0xa6, 0x533: 0x174, 0x534: 0x175, 0x535: 0x100, 0x536: 0x100, 0x537: 0x100,\n\t0x538: 0x100, 0x539: 0x100, 0x53a: 0x100, 0x53b: 0x100, 0x53c: 0x100, 0x53d: 0x100, 0x53e: 0x100, 0x53f: 0x100,\n\t// Block 0x15, offset 0x540\n\t0x540: 0x100, 0x541: 0x100, 0x542: 0x100, 0x543: 0x100, 0x544: 0x100, 0x545: 0x100, 0x546: 0x100, 0x547: 0x100,\n\t0x548: 0x100, 0x549: 0x100, 0x54a: 0x100, 0x54b: 0x100, 0x54c: 0x100, 0x54d: 0x100, 0x54e: 0x100, 0x54f: 0x100,\n\t0x550: 0x100, 0x551: 0x100, 0x552: 0x100, 0x553: 0x100, 0x554: 0x100, 0x555: 0x100, 0x556: 0x100, 0x557: 0x100,\n\t0x558: 0x100, 0x559: 0x100, 0x55a: 0x100, 0x55b: 0x100, 0x55c: 0x100, 0x55d: 0x100, 0x55e: 0x100, 0x55f: 0x100,\n\t0x560: 0x100, 0x561: 0x100, 0x562: 0x100, 0x563: 0x100, 0x564: 0x100, 0x565: 0x100, 0x566: 0x100, 0x567: 0x100,\n\t0x568: 0x100, 0x569: 0x100, 0x56a: 0x100, 0x56b: 0x100, 0x56c: 0x100, 0x56d: 0x100, 0x56e: 0x100, 0x56f: 0x100,\n\t0x570: 0x100, 0x571: 0x100, 0x572: 0x100, 0x573: 0x100, 0x574: 0x100, 0x575: 0x100, 0x576: 0x100, 0x577: 0x100,\n\t0x578: 0x100, 0x579: 0x100, 0x57a: 0x100, 0x57b: 0x100, 0x57c: 0x100, 0x57d: 0x100, 0x57e: 0x100, 0x57f: 0x176,\n\t// Block 0x16, offset 0x580\n\t0x580: 0xa6, 0x581: 0xa6, 0x582: 0xa6, 0x583: 0xa6, 0x584: 0x177, 0x585: 0x178, 0x586: 0xa6, 0x587: 0xa6,\n\t0x588: 0xa6, 0x589: 0xa6, 0x58a: 0xa6, 0x58b: 0x179, 0x58c: 0x100, 0x58d: 0x100, 0x58e: 0x100, 0x58f: 0x100,\n\t0x590: 0x100, 0x591: 0x100, 0x592: 0x100, 0x593: 0x100, 0x594: 0x100, 0x595: 0x100, 0x596: 0x100, 0x597: 0x100,\n\t0x598: 0x100, 0x599: 0x100, 0x59a: 0x100, 0x59b: 0x100, 0x59c: 0x100, 0x59d: 0x100, 0x59e: 0x100, 0x59f: 0x100,\n\t0x5a0: 0x100, 0x5a1: 0x100, 0x5a2: 0x100, 0x5a3: 0x100, 0x5a4: 0x100, 0x5a5: 0x100, 0x5a6: 0x100, 0x5a7: 0x100,\n\t0x5a8: 0x100, 0x5a9: 0x100, 0x5aa: 0x100, 0x5ab: 0x100, 0x5ac: 0x100, 0x5ad: 0x100, 0x5ae: 0x100, 0x5af: 0x100,\n\t0x5b0: 0xa6, 0x5b1: 0x17a, 0x5b2: 0x17b, 0x5b3: 0x100, 0x5b4: 0x100, 0x5b5: 0x100, 0x5b6: 0x100, 0x5b7: 0x100,\n\t0x5b8: 0x100, 0x5b9: 0x100, 0x5ba: 0x100, 0x5bb: 0x100, 0x5bc: 0x100, 0x5bd: 0x100, 0x5be: 0x100, 0x5bf: 0x100,\n\t// Block 0x17, offset 0x5c0\n\t0x5c0: 0x100, 0x5c1: 0x100, 0x5c2: 0x100, 0x5c3: 0x100, 0x5c4: 0x100, 0x5c5: 0x100, 0x5c6: 0x100, 0x5c7: 0x100,\n\t0x5c8: 0x100, 0x5c9: 0x100, 0x5ca: 0x100, 0x5cb: 0x100, 0x5cc: 0x100, 0x5cd: 0x100, 0x5ce: 0x100, 0x5cf: 0x100,\n\t0x5d0: 0x100, 0x5d1: 0x100, 0x5d2: 0x100, 0x5d3: 0x100, 0x5d4: 0x100, 0x5d5: 0x100, 0x5d6: 0x100, 0x5d7: 0x100,\n\t0x5d8: 0x100, 0x5d9: 0x100, 0x5da: 0x100, 0x5db: 0x100, 0x5dc: 0x100, 0x5dd: 0x100, 0x5de: 0x100, 0x5df: 0x100,\n\t0x5e0: 0x100, 0x5e1: 0x100, 0x5e2: 0x100, 0x5e3: 0x100, 0x5e4: 0x100, 0x5e5: 0x100, 0x5e6: 0x100, 0x5e7: 0x100,\n\t0x5e8: 0x100, 0x5e9: 0x100, 0x5ea: 0x100, 0x5eb: 0x100, 0x5ec: 0x100, 0x5ed: 0x100, 0x5ee: 0x100, 0x5ef: 0x100,\n\t0x5f0: 0x100, 0x5f1: 0x100, 0x5f2: 0x100, 0x5f3: 0x100, 0x5f4: 0x100, 0x5f5: 0x100, 0x5f6: 0x100, 0x5f7: 0x100,\n\t0x5f8: 0x100, 0x5f9: 0x100, 0x5fa: 0x100, 0x5fb: 0x100, 0x5fc: 0x17c, 0x5fd: 0x17d, 0x5fe: 0xa2, 0x5ff: 0x17e,\n\t// Block 0x18, offset 0x600\n\t0x600: 0xa2, 0x601: 0xa2, 0x602: 0xa2, 0x603: 0x17f, 0x604: 0x180, 0x605: 0x181, 0x606: 0x182, 0x607: 0x183,\n\t0x608: 0xa2, 0x609: 0x184, 0x60a: 0x100, 0x60b: 0x185, 0x60c: 0xa2, 0x60d: 0x186, 0x60e: 0x100, 0x60f: 0x100,\n\t0x610: 0x63, 0x611: 0x64, 0x612: 0x65, 0x613: 0x66, 0x614: 0x67, 0x615: 0x68, 0x616: 0x69, 0x617: 0x6a,\n\t0x618: 0x6b, 0x619: 0x6c, 0x61a: 0x6d, 0x61b: 0x6e, 0x61c: 0x6f, 0x61d: 0x70, 0x61e: 0x71, 0x61f: 0x72,\n\t0x620: 0xa2, 0x621: 0xa2, 0x622: 0xa2, 0x623: 0xa2, 0x624: 0xa2, 0x625: 0xa2, 0x626: 0xa2, 0x627: 0xa2,\n\t0x628: 0x187, 0x629: 0x188, 0x62a: 0x189, 0x62b: 0x100, 0x62c: 0x100, 0x62d: 0x100, 0x62e: 0x100, 0x62f: 0x100,\n\t0x630: 0x100, 0x631: 0x100, 0x632: 0x100, 0x633: 0x100, 0x634: 0x100, 0x635: 0x100, 0x636: 0x100, 0x637: 0x100,\n\t0x638: 0x100, 0x639: 0x100, 0x63a: 0x100, 0x63b: 0x100, 0x63c: 0x18a, 0x63d: 0x100, 0x63e: 0x100, 0x63f: 0x100,\n\t// Block 0x19, offset 0x640\n\t0x640: 0x73, 0x641: 0x74, 0x642: 0x18b, 0x643: 0x100, 0x644: 0x18c, 0x645: 0x18d, 0x646: 0x100, 0x647: 0x100,\n\t0x648: 0x100, 0x649: 0x100, 0x64a: 0x18e, 0x64b: 0x18f, 0x64c: 0x100, 0x64d: 0x100, 0x64e: 0x100, 0x64f: 0x100,\n\t0x650: 0x100, 0x651: 0x100, 0x652: 0x100, 0x653: 0x190, 0x654: 0x100, 0x655: 0x100, 0x656: 0x100, 0x657: 0x100,\n\t0x658: 0x100, 0x659: 0x100, 0x65a: 0x100, 0x65b: 0x100, 0x65c: 0x100, 0x65d: 0x100, 0x65e: 0x100, 0x65f: 0x191,\n\t0x660: 0x127, 0x661: 0x127, 0x662: 0x127, 0x663: 0x192, 0x664: 0x75, 0x665: 0x193, 0x666: 0x100, 0x667: 0x100,\n\t0x668: 0x100, 0x669: 0x100, 0x66a: 0x100, 0x66b: 0x100, 0x66c: 0x100, 0x66d: 0x100, 0x66e: 0x100, 0x66f: 0x100,\n\t0x670: 0x100, 0x671: 0x194, 0x672: 0x195, 0x673: 0x100, 0x674: 0x196, 0x675: 0x100, 0x676: 0x100, 0x677: 0x100,\n\t0x678: 0x76, 0x679: 0x77, 0x67a: 0x78, 0x67b: 0x197, 0x67c: 0x100, 0x67d: 0x100, 0x67e: 0x100, 0x67f: 0x100,\n\t// Block 0x1a, offset 0x680\n\t0x680: 0x198, 0x681: 0xa2, 0x682: 0x199, 0x683: 0x19a, 0x684: 0x79, 0x685: 0x7a, 0x686: 0x19b, 0x687: 0x19c,\n\t0x688: 0x7b, 0x689: 0x19d, 0x68a: 0x100, 0x68b: 0x100, 0x68c: 0xa2, 0x68d: 0xa2, 0x68e: 0xa2, 0x68f: 0xa2,\n\t0x690: 0xa2, 0x691: 0xa2, 0x692: 0xa2, 0x693: 0xa2, 0x694: 0xa2, 0x695: 0xa2, 0x696: 0xa2, 0x697: 0xa2,\n\t0x698: 0xa2, 0x699: 0xa2, 0x69a: 0xa2, 0x69b: 0x19e, 0x69c: 0xa2, 0x69d: 0x19f, 0x69e: 0xa2, 0x69f: 0x1a0,\n\t0x6a0: 0x1a1, 0x6a1: 0x1a2, 0x6a2: 0x1a3, 0x6a3: 0x100, 0x6a4: 0xa2, 0x6a5: 0xa2, 0x6a6: 0xa2, 0x6a7: 0xa2,\n\t0x6a8: 0xa2, 0x6a9: 0x1a4, 0x6aa: 0x1a5, 0x6ab: 0x1a6, 0x6ac: 0xa2, 0x6ad: 0xa2, 0x6ae: 0x1a7, 0x6af: 0x1a8,\n\t0x6b0: 0x100, 0x6b1: 0x100, 0x6b2: 0x100, 0x6b3: 0x100, 0x6b4: 0x100, 0x6b5: 0x100, 0x6b6: 0x100, 0x6b7: 0x100,\n\t0x6b8: 0x100, 0x6b9: 0x100, 0x6ba: 0x100, 0x6bb: 0x100, 0x6bc: 0x100, 0x6bd: 0x100, 0x6be: 0x100, 0x6bf: 0x100,\n\t// Block 0x1b, offset 0x6c0\n\t0x6c0: 0xa6, 0x6c1: 0xa6, 0x6c2: 0xa6, 0x6c3: 0xa6, 0x6c4: 0xa6, 0x6c5: 0xa6, 0x6c6: 0xa6, 0x6c7: 0xa6,\n\t0x6c8: 0xa6, 0x6c9: 0xa6, 0x6ca: 0xa6, 0x6cb: 0xa6, 0x6cc: 0xa6, 0x6cd: 0xa6, 0x6ce: 0xa6, 0x6cf: 0xa6,\n\t0x6d0: 0xa6, 0x6d1: 0xa6, 0x6d2: 0xa6, 0x6d3: 0xa6, 0x6d4: 0xa6, 0x6d5: 0xa6, 0x6d6: 0xa6, 0x6d7: 0xa6,\n\t0x6d8: 0xa6, 0x6d9: 0xa6, 0x6da: 0xa6, 0x6db: 0x1a9, 0x6dc: 0xa6, 0x6dd: 0xa6, 0x6de: 0xa6, 0x6df: 0xa6,\n\t0x6e0: 0xa6, 0x6e1: 0xa6, 0x6e2: 0xa6, 0x6e3: 0xa6, 0x6e4: 0xa6, 0x6e5: 0xa6, 0x6e6: 0xa6, 0x6e7: 0xa6,\n\t0x6e8: 0xa6, 0x6e9: 0xa6, 0x6ea: 0xa6, 0x6eb: 0xa6, 0x6ec: 0xa6, 0x6ed: 0xa6, 0x6ee: 0xa6, 0x6ef: 0xa6,\n\t0x6f0: 0xa6, 0x6f1: 0xa6, 0x6f2: 0xa6, 0x6f3: 0xa6, 0x6f4: 0xa6, 0x6f5: 0xa6, 0x6f6: 0xa6, 0x6f7: 0xa6,\n\t0x6f8: 0xa6, 0x6f9: 0xa6, 0x6fa: 0xa6, 0x6fb: 0xa6, 0x6fc: 0xa6, 0x6fd: 0xa6, 0x6fe: 0xa6, 0x6ff: 0xa6,\n\t// Block 0x1c, offset 0x700\n\t0x700: 0xa6, 0x701: 0xa6, 0x702: 0xa6, 0x703: 0xa6, 0x704: 0xa6, 0x705: 0xa6, 0x706: 0xa6, 0x707: 0xa6,\n\t0x708: 0xa6, 0x709: 0xa6, 0x70a: 0xa6, 0x70b: 0xa6, 0x70c: 0xa6, 0x70d: 0xa6, 0x70e: 0xa6, 0x70f: 0xa6,\n\t0x710: 0xa6, 0x711: 0xa6, 0x712: 0xa6, 0x713: 0xa6, 0x714: 0xa6, 0x715: 0xa6, 0x716: 0xa6, 0x717: 0xa6,\n\t0x718: 0xa6, 0x719: 0xa6, 0x71a: 0xa6, 0x71b: 0xa6, 0x71c: 0x1aa, 0x71d: 0xa6, 0x71e: 0xa6, 0x71f: 0xa6,\n\t0x720: 0x1ab, 0x721: 0xa6, 0x722: 0xa6, 0x723: 0xa6, 0x724: 0xa6, 0x725: 0xa6, 0x726: 0xa6, 0x727: 0xa6,\n\t0x728: 0xa6, 0x729: 0xa6, 0x72a: 0xa6, 0x72b: 0xa6, 0x72c: 0xa6, 0x72d: 0xa6, 0x72e: 0xa6, 0x72f: 0xa6,\n\t0x730: 0xa6, 0x731: 0xa6, 0x732: 0xa6, 0x733: 0xa6, 0x734: 0xa6, 0x735: 0xa6, 0x736: 0xa6, 0x737: 0xa6,\n\t0x738: 0xa6, 0x739: 0xa6, 0x73a: 0xa6, 0x73b: 0xa6, 0x73c: 0xa6, 0x73d: 0xa6, 0x73e: 0xa6, 0x73f: 0xa6,\n\t// Block 0x1d, offset 0x740\n\t0x740: 0xa6, 0x741: 0xa6, 0x742: 0xa6, 0x743: 0xa6, 0x744: 0xa6, 0x745: 0xa6, 0x746: 0xa6, 0x747: 0xa6,\n\t0x748: 0xa6, 0x749: 0xa6, 0x74a: 0xa6, 0x74b: 0xa6, 0x74c: 0xa6, 0x74d: 0xa6, 0x74e: 0xa6, 0x74f: 0xa6,\n\t0x750: 0xa6, 0x751: 0xa6, 0x752: 0xa6, 0x753: 0xa6, 0x754: 0xa6, 0x755: 0xa6, 0x756: 0xa6, 0x757: 0xa6,\n\t0x758: 0xa6, 0x759: 0xa6, 0x75a: 0xa6, 0x75b: 0xa6, 0x75c: 0xa6, 0x75d: 0xa6, 0x75e: 0xa6, 0x75f: 0xa6,\n\t0x760: 0xa6, 0x761: 0xa6, 0x762: 0xa6, 0x763: 0xa6, 0x764: 0xa6, 0x765: 0xa6, 0x766: 0xa6, 0x767: 0xa6,\n\t0x768: 0xa6, 0x769: 0xa6, 0x76a: 0xa6, 0x76b: 0xa6, 0x76c: 0xa6, 0x76d: 0xa6, 0x76e: 0xa6, 0x76f: 0xa6,\n\t0x770: 0xa6, 0x771: 0xa6, 0x772: 0xa6, 0x773: 0xa6, 0x774: 0xa6, 0x775: 0xa6, 0x776: 0xa6, 0x777: 0xa6,\n\t0x778: 0xa6, 0x779: 0xa6, 0x77a: 0x1ac, 0x77b: 0xa6, 0x77c: 0xa6, 0x77d: 0xa6, 0x77e: 0xa6, 0x77f: 0xa6,\n\t// Block 0x1e, offset 0x780\n\t0x780: 0xa6, 0x781: 0xa6, 0x782: 0xa6, 0x783: 0xa6, 0x784: 0xa6, 0x785: 0xa6, 0x786: 0xa6, 0x787: 0xa6,\n\t0x788: 0xa6, 0x789: 0xa6, 0x78a: 0xa6, 0x78b: 0xa6, 0x78c: 0xa6, 0x78d: 0xa6, 0x78e: 0xa6, 0x78f: 0xa6,\n\t0x790: 0xa6, 0x791: 0xa6, 0x792: 0xa6, 0x793: 0xa6, 0x794: 0xa6, 0x795: 0xa6, 0x796: 0xa6, 0x797: 0xa6,\n\t0x798: 0xa6, 0x799: 0xa6, 0x79a: 0xa6, 0x79b: 0xa6, 0x79c: 0xa6, 0x79d: 0xa6, 0x79e: 0xa6, 0x79f: 0xa6,\n\t0x7a0: 0xa6, 0x7a1: 0xa6, 0x7a2: 0xa6, 0x7a3: 0xa6, 0x7a4: 0xa6, 0x7a5: 0xa6, 0x7a6: 0xa6, 0x7a7: 0xa6,\n\t0x7a8: 0xa6, 0x7a9: 0xa6, 0x7aa: 0xa6, 0x7ab: 0xa6, 0x7ac: 0xa6, 0x7ad: 0xa6, 0x7ae: 0xa6, 0x7af: 0x1ad,\n\t0x7b0: 0x100, 0x7b1: 0x100, 0x7b2: 0x100, 0x7b3: 0x100, 0x7b4: 0x100, 0x7b5: 0x100, 0x7b6: 0x100, 0x7b7: 0x100,\n\t0x7b8: 0x100, 0x7b9: 0x100, 0x7ba: 0x100, 0x7bb: 0x100, 0x7bc: 0x100, 0x7bd: 0x100, 0x7be: 0x100, 0x7bf: 0x100,\n\t// Block 0x1f, offset 0x7c0\n\t0x7c0: 0x100, 0x7c1: 0x100, 0x7c2: 0x100, 0x7c3: 0x100, 0x7c4: 0x100, 0x7c5: 0x100, 0x7c6: 0x100, 0x7c7: 0x100,\n\t0x7c8: 0x100, 0x7c9: 0x100, 0x7ca: 0x100, 0x7cb: 0x100, 0x7cc: 0x100, 0x7cd: 0x100, 0x7ce: 0x100, 0x7cf: 0x100,\n\t0x7d0: 0x100, 0x7d1: 0x100, 0x7d2: 0x100, 0x7d3: 0x100, 0x7d4: 0x100, 0x7d5: 0x100, 0x7d6: 0x100, 0x7d7: 0x100,\n\t0x7d8: 0x100, 0x7d9: 0x100, 0x7da: 0x100, 0x7db: 0x100, 0x7dc: 0x100, 0x7dd: 0x100, 0x7de: 0x100, 0x7df: 0x100,\n\t0x7e0: 0x7c, 0x7e1: 0x7d, 0x7e2: 0x7e, 0x7e3: 0x7f, 0x7e4: 0x80, 0x7e5: 0x81, 0x7e6: 0x82, 0x7e7: 0x83,\n\t0x7e8: 0x84, 0x7e9: 0x100, 0x7ea: 0x100, 0x7eb: 0x100, 0x7ec: 0x100, 0x7ed: 0x100, 0x7ee: 0x100, 0x7ef: 0x100,\n\t0x7f0: 0x100, 0x7f1: 0x100, 0x7f2: 0x100, 0x7f3: 0x100, 0x7f4: 0x100, 0x7f5: 0x100, 0x7f6: 0x100, 0x7f7: 0x100,\n\t0x7f8: 0x100, 0x7f9: 0x100, 0x7fa: 0x100, 0x7fb: 0x100, 0x7fc: 0x100, 0x7fd: 0x100, 0x7fe: 0x100, 0x7ff: 0x100,\n\t// Block 0x20, offset 0x800\n\t0x800: 0xa6, 0x801: 0xa6, 0x802: 0xa6, 0x803: 0xa6, 0x804: 0xa6, 0x805: 0xa6, 0x806: 0xa6, 0x807: 0xa6,\n\t0x808: 0xa6, 0x809: 0xa6, 0x80a: 0xa6, 0x80b: 0xa6, 0x80c: 0xa6, 0x80d: 0x1ae, 0x80e: 0xa6, 0x80f: 0xa6,\n\t0x810: 0xa6, 0x811: 0xa6, 0x812: 0xa6, 0x813: 0xa6, 0x814: 0xa6, 0x815: 0xa6, 0x816: 0xa6, 0x817: 0xa6,\n\t0x818: 0xa6, 0x819: 0xa6, 0x81a: 0xa6, 0x81b: 0xa6, 0x81c: 0xa6, 0x81d: 0xa6, 0x81e: 0xa6, 0x81f: 0xa6,\n\t0x820: 0xa6, 0x821: 0xa6, 0x822: 0xa6, 0x823: 0xa6, 0x824: 0xa6, 0x825: 0xa6, 0x826: 0xa6, 0x827: 0xa6,\n\t0x828: 0xa6, 0x829: 0xa6, 0x82a: 0xa6, 0x82b: 0xa6, 0x82c: 0xa6, 0x82d: 0xa6, 0x82e: 0xa6, 0x82f: 0xa6,\n\t0x830: 0xa6, 0x831: 0xa6, 0x832: 0xa6, 0x833: 0xa6, 0x834: 0xa6, 0x835: 0xa6, 0x836: 0xa6, 0x837: 0xa6,\n\t0x838: 0xa6, 0x839: 0xa6, 0x83a: 0xa6, 0x83b: 0xa6, 0x83c: 0xa6, 0x83d: 0xa6, 0x83e: 0xa6, 0x83f: 0xa6,\n\t// Block 0x21, offset 0x840\n\t0x840: 0xa6, 0x841: 0xa6, 0x842: 0xa6, 0x843: 0xa6, 0x844: 0xa6, 0x845: 0xa6, 0x846: 0xa6, 0x847: 0xa6,\n\t0x848: 0xa6, 0x849: 0xa6, 0x84a: 0xa6, 0x84b: 0xa6, 0x84c: 0xa6, 0x84d: 0xa6, 0x84e: 0x1af, 0x84f: 0x100,\n\t0x850: 0x100, 0x851: 0x100, 0x852: 0x100, 0x853: 0x100, 0x854: 0x100, 0x855: 0x100, 0x856: 0x100, 0x857: 0x100,\n\t0x858: 0x100, 0x859: 0x100, 0x85a: 0x100, 0x85b: 0x100, 0x85c: 0x100, 0x85d: 0x100, 0x85e: 0x100, 0x85f: 0x100,\n\t0x860: 0x100, 0x861: 0x100, 0x862: 0x100, 0x863: 0x100, 0x864: 0x100, 0x865: 0x100, 0x866: 0x100, 0x867: 0x100,\n\t0x868: 0x100, 0x869: 0x100, 0x86a: 0x100, 0x86b: 0x100, 0x86c: 0x100, 0x86d: 0x100, 0x86e: 0x100, 0x86f: 0x100,\n\t0x870: 0x100, 0x871: 0x100, 0x872: 0x100, 0x873: 0x100, 0x874: 0x100, 0x875: 0x100, 0x876: 0x100, 0x877: 0x100,\n\t0x878: 0x100, 0x879: 0x100, 0x87a: 0x100, 0x87b: 0x100, 0x87c: 0x100, 0x87d: 0x100, 0x87e: 0x100, 0x87f: 0x100,\n\t// Block 0x22, offset 0x880\n\t0x890: 0x0c, 0x891: 0x0d, 0x892: 0x0e, 0x893: 0x0f, 0x894: 0x10, 0x895: 0x0a, 0x896: 0x11, 0x897: 0x07,\n\t0x898: 0x12, 0x899: 0x0a, 0x89a: 0x13, 0x89b: 0x14, 0x89c: 0x15, 0x89d: 0x16, 0x89e: 0x17, 0x89f: 0x18,\n\t0x8a0: 0x07, 0x8a1: 0x07, 0x8a2: 0x07, 0x8a3: 0x07, 0x8a4: 0x07, 0x8a5: 0x07, 0x8a6: 0x07, 0x8a7: 0x07,\n\t0x8a8: 0x07, 0x8a9: 0x07, 0x8aa: 0x19, 0x8ab: 0x1a, 0x8ac: 0x1b, 0x8ad: 0x07, 0x8ae: 0x1c, 0x8af: 0x1d,\n\t0x8b0: 0x07, 0x8b1: 0x1e, 0x8b2: 0x1f, 0x8b3: 0x0a, 0x8b4: 0x0a, 0x8b5: 0x0a, 0x8b6: 0x0a, 0x8b7: 0x0a,\n\t0x8b8: 0x0a, 0x8b9: 0x0a, 0x8ba: 0x0a, 0x8bb: 0x0a, 0x8bc: 0x0a, 0x8bd: 0x0a, 0x8be: 0x0a, 0x8bf: 0x0a,\n\t// Block 0x23, offset 0x8c0\n\t0x8c0: 0x0a, 0x8c1: 0x0a, 0x8c2: 0x0a, 0x8c3: 0x0a, 0x8c4: 0x0a, 0x8c5: 0x0a, 0x8c6: 0x0a, 0x8c7: 0x0a,\n\t0x8c8: 0x0a, 0x8c9: 0x0a, 0x8ca: 0x0a, 0x8cb: 0x0a, 0x8cc: 0x0a, 0x8cd: 0x0a, 0x8ce: 0x0a, 0x8cf: 0x0a,\n\t0x8d0: 0x0a, 0x8d1: 0x0a, 0x8d2: 0x0a, 0x8d3: 0x0a, 0x8d4: 0x0a, 0x8d5: 0x0a, 0x8d6: 0x0a, 0x8d7: 0x0a,\n\t0x8d8: 0x0a, 0x8d9: 0x0a, 0x8da: 0x0a, 0x8db: 0x0a, 0x8dc: 0x0a, 0x8dd: 0x0a, 0x8de: 0x0a, 0x8df: 0x0a,\n\t0x8e0: 0x0a, 0x8e1: 0x0a, 0x8e2: 0x0a, 0x8e3: 0x0a, 0x8e4: 0x0a, 0x8e5: 0x0a, 0x8e6: 0x0a, 0x8e7: 0x0a,\n\t0x8e8: 0x0a, 0x8e9: 0x0a, 0x8ea: 0x0a, 0x8eb: 0x0a, 0x8ec: 0x0a, 0x8ed: 0x0a, 0x8ee: 0x0a, 0x8ef: 0x0a,\n\t0x8f0: 0x0a, 0x8f1: 0x0a, 0x8f2: 0x0a, 0x8f3: 0x0a, 0x8f4: 0x0a, 0x8f5: 0x0a, 0x8f6: 0x0a, 0x8f7: 0x0a,\n\t0x8f8: 0x0a, 0x8f9: 0x0a, 0x8fa: 0x0a, 0x8fb: 0x0a, 0x8fc: 0x0a, 0x8fd: 0x0a, 0x8fe: 0x0a, 0x8ff: 0x0a,\n\t// Block 0x24, offset 0x900\n\t0x900: 0x1b0, 0x901: 0x1b1, 0x902: 0x100, 0x903: 0x100, 0x904: 0x1b2, 0x905: 0x1b2, 0x906: 0x1b2, 0x907: 0x1b3,\n\t0x908: 0x100, 0x909: 0x100, 0x90a: 0x100, 0x90b: 0x100, 0x90c: 0x100, 0x90d: 0x100, 0x90e: 0x100, 0x90f: 0x100,\n\t0x910: 0x100, 0x911: 0x100, 0x912: 0x100, 0x913: 0x100, 0x914: 0x100, 0x915: 0x100, 0x916: 0x100, 0x917: 0x100,\n\t0x918: 0x100, 0x919: 0x100, 0x91a: 0x100, 0x91b: 0x100, 0x91c: 0x100, 0x91d: 0x100, 0x91e: 0x100, 0x91f: 0x100,\n\t0x920: 0x100, 0x921: 0x100, 0x922: 0x100, 0x923: 0x100, 0x924: 0x100, 0x925: 0x100, 0x926: 0x100, 0x927: 0x100,\n\t0x928: 0x100, 0x929: 0x100, 0x92a: 0x100, 0x92b: 0x100, 0x92c: 0x100, 0x92d: 0x100, 0x92e: 0x100, 0x92f: 0x100,\n\t0x930: 0x100, 0x931: 0x100, 0x932: 0x100, 0x933: 0x100, 0x934: 0x100, 0x935: 0x100, 0x936: 0x100, 0x937: 0x100,\n\t0x938: 0x100, 0x939: 0x100, 0x93a: 0x100, 0x93b: 0x100, 0x93c: 0x100, 0x93d: 0x100, 0x93e: 0x100, 0x93f: 0x100,\n\t// Block 0x25, offset 0x940\n\t0x940: 0x0a, 0x941: 0x0a, 0x942: 0x0a, 0x943: 0x0a, 0x944: 0x0a, 0x945: 0x0a, 0x946: 0x0a, 0x947: 0x0a,\n\t0x948: 0x0a, 0x949: 0x0a, 0x94a: 0x0a, 0x94b: 0x0a, 0x94c: 0x0a, 0x94d: 0x0a, 0x94e: 0x0a, 0x94f: 0x0a,\n\t0x950: 0x0a, 0x951: 0x0a, 0x952: 0x0a, 0x953: 0x0a, 0x954: 0x0a, 0x955: 0x0a, 0x956: 0x0a, 0x957: 0x0a,\n\t0x958: 0x0a, 0x959: 0x0a, 0x95a: 0x0a, 0x95b: 0x0a, 0x95c: 0x0a, 0x95d: 0x0a, 0x95e: 0x0a, 0x95f: 0x0a,\n\t0x960: 0x22, 0x961: 0x0a, 0x962: 0x0a, 0x963: 0x0a, 0x964: 0x0a, 0x965: 0x0a, 0x966: 0x0a, 0x967: 0x0a,\n\t0x968: 0x0a, 0x969: 0x0a, 0x96a: 0x0a, 0x96b: 0x0a, 0x96c: 0x0a, 0x96d: 0x0a, 0x96e: 0x0a, 0x96f: 0x0a,\n\t0x970: 0x0a, 0x971: 0x0a, 0x972: 0x0a, 0x973: 0x0a, 0x974: 0x0a, 0x975: 0x0a, 0x976: 0x0a, 0x977: 0x0a,\n\t0x978: 0x0a, 0x979: 0x0a, 0x97a: 0x0a, 0x97b: 0x0a, 0x97c: 0x0a, 0x97d: 0x0a, 0x97e: 0x0a, 0x97f: 0x0a,\n\t// Block 0x26, offset 0x980\n\t0x980: 0x0a, 0x981: 0x0a, 0x982: 0x0a, 0x983: 0x0a, 0x984: 0x0a, 0x985: 0x0a, 0x986: 0x0a, 0x987: 0x0a,\n\t0x988: 0x0a, 0x989: 0x0a, 0x98a: 0x0a, 0x98b: 0x0a, 0x98c: 0x0a, 0x98d: 0x0a, 0x98e: 0x0a, 0x98f: 0x0a,\n}\n\n// idnaSparseOffset: 303 entries, 606 bytes\nvar idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x33, 0x3e, 0x4a, 0x4e, 0x5d, 0x62, 0x6c, 0x78, 0x7e, 0x87, 0x97, 0xa6, 0xb1, 0xbe, 0xcf, 0xd9, 0xe0, 0xed, 0xfe, 0x105, 0x110, 0x11f, 0x12d, 0x137, 0x139, 0x13e, 0x141, 0x144, 0x146, 0x152, 0x15d, 0x165, 0x16b, 0x171, 0x176, 0x17b, 0x17e, 0x182, 0x188, 0x18d, 0x198, 0x1a2, 0x1a8, 0x1b9, 0x1c4, 0x1c7, 0x1cf, 0x1d2, 0x1df, 0x1e7, 0x1eb, 0x1f2, 0x1fa, 0x20a, 0x216, 0x219, 0x223, 0x22f, 0x23b, 0x247, 0x24f, 0x254, 0x261, 0x272, 0x27d, 0x282, 0x28b, 0x293, 0x299, 0x29e, 0x2a1, 0x2a5, 0x2ab, 0x2af, 0x2b3, 0x2b7, 0x2bc, 0x2c4, 0x2cb, 0x2d6, 0x2e0, 0x2e4, 0x2e7, 0x2ed, 0x2f1, 0x2f3, 0x2f6, 0x2f8, 0x2fb, 0x305, 0x308, 0x317, 0x31b, 0x31f, 0x321, 0x32a, 0x32e, 0x333, 0x338, 0x33e, 0x34e, 0x354, 0x358, 0x367, 0x36c, 0x374, 0x37e, 0x389, 0x391, 0x3a2, 0x3ab, 0x3bb, 0x3c8, 0x3d4, 0x3d9, 0x3e6, 0x3ea, 0x3ef, 0x3f1, 0x3f3, 0x3f7, 0x3f9, 0x3fd, 0x406, 0x40c, 0x410, 0x420, 0x42a, 0x42f, 0x432, 0x438, 0x43f, 0x444, 0x448, 0x44e, 0x453, 0x45c, 0x461, 0x467, 0x46e, 0x475, 0x47c, 0x480, 0x483, 0x488, 0x494, 0x49a, 0x49f, 0x4a6, 0x4ae, 0x4b3, 0x4b7, 0x4c7, 0x4ce, 0x4d2, 0x4d6, 0x4dd, 0x4df, 0x4e2, 0x4e5, 0x4e9, 0x4f2, 0x4f6, 0x4fe, 0x501, 0x509, 0x514, 0x523, 0x52f, 0x535, 0x542, 0x54e, 0x556, 0x55f, 0x56a, 0x571, 0x580, 0x58d, 0x591, 0x59e, 0x5a7, 0x5ab, 0x5ba, 0x5c2, 0x5cd, 0x5d6, 0x5dc, 0x5e4, 0x5ed, 0x5f9, 0x5fc, 0x608, 0x60b, 0x614, 0x617, 0x61c, 0x625, 0x62a, 0x637, 0x642, 0x64b, 0x656, 0x659, 0x65c, 0x666, 0x66f, 0x67b, 0x688, 0x695, 0x6a3, 0x6aa, 0x6b5, 0x6bc, 0x6c0, 0x6c4, 0x6c7, 0x6cc, 0x6cf, 0x6d2, 0x6d6, 0x6d9, 0x6de, 0x6e5, 0x6e8, 0x6f0, 0x6f4, 0x6ff, 0x702, 0x705, 0x708, 0x70e, 0x714, 0x71d, 0x720, 0x723, 0x726, 0x72e, 0x733, 0x73c, 0x73f, 0x744, 0x74e, 0x752, 0x756, 0x759, 0x75c, 0x760, 0x76f, 0x77b, 0x77f, 0x784, 0x789, 0x78e, 0x792, 0x797, 0x7a0, 0x7a5, 0x7a9, 0x7af, 0x7b5, 0x7ba, 0x7c0, 0x7c6, 0x7d0, 0x7d6, 0x7df, 0x7e2, 0x7e5, 0x7e9, 0x7ed, 0x7f1, 0x7f7, 0x7fd, 0x802, 0x805, 0x815, 0x81c, 0x820, 0x827, 0x82b, 0x831, 0x838, 0x83f, 0x845, 0x84e, 0x852, 0x860, 0x863, 0x866, 0x86a, 0x86e, 0x871, 0x875, 0x878, 0x87d, 0x87f, 0x881}\n\n// idnaSparseValues: 2180 entries, 8720 bytes\nvar idnaSparseValues = [2180]valueRange{\n\t// Block 0x0, offset 0x0\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0xe105, lo: 0x80, hi: 0x96},\n\t{value: 0x0018, lo: 0x97, hi: 0x97},\n\t{value: 0xe105, lo: 0x98, hi: 0x9e},\n\t{value: 0x001f, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbf},\n\t// Block 0x1, offset 0x8\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0xe01d, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x82},\n\t{value: 0x0335, lo: 0x83, hi: 0x83},\n\t{value: 0x034d, lo: 0x84, hi: 0x84},\n\t{value: 0x0365, lo: 0x85, hi: 0x85},\n\t{value: 0xe00d, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0xe00d, lo: 0x88, hi: 0x88},\n\t{value: 0x0008, lo: 0x89, hi: 0x89},\n\t{value: 0xe00d, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0x8b},\n\t{value: 0xe00d, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0x8d},\n\t{value: 0xe00d, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0xbf},\n\t// Block 0x2, offset 0x19\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x00a9, lo: 0xb0, hi: 0xb0},\n\t{value: 0x037d, lo: 0xb1, hi: 0xb1},\n\t{value: 0x00b1, lo: 0xb2, hi: 0xb2},\n\t{value: 0x00b9, lo: 0xb3, hi: 0xb3},\n\t{value: 0x034d, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0395, lo: 0xb5, hi: 0xb5},\n\t{value: 0xe1bd, lo: 0xb6, hi: 0xb6},\n\t{value: 0x00c1, lo: 0xb7, hi: 0xb7},\n\t{value: 0x00c9, lo: 0xb8, hi: 0xb8},\n\t{value: 0x0008, lo: 0xb9, hi: 0xbf},\n\t// Block 0x3, offset 0x25\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x3308, lo: 0x80, hi: 0xbf},\n\t// Block 0x4, offset 0x27\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x03f5, lo: 0x80, hi: 0x8f},\n\t{value: 0xe105, lo: 0x90, hi: 0x9f},\n\t{value: 0x049d, lo: 0xa0, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x5, offset 0x2c\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe185, lo: 0x80, hi: 0x8f},\n\t{value: 0x0545, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x98},\n\t{value: 0x0008, lo: 0x99, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x6, offset 0x33\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0131, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x88},\n\t{value: 0x0018, lo: 0x89, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x3308, lo: 0x91, hi: 0xbd},\n\t{value: 0x0818, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x7, offset 0x3e\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0818, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x82},\n\t{value: 0x0818, lo: 0x83, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x85},\n\t{value: 0x0818, lo: 0x86, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xae},\n\t{value: 0x0808, lo: 0xaf, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x8, offset 0x4a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0a08, lo: 0x80, hi: 0x87},\n\t{value: 0x0c08, lo: 0x88, hi: 0x99},\n\t{value: 0x0a08, lo: 0x9a, hi: 0xbf},\n\t// Block 0x9, offset 0x4e\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3308, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0c08, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0a08, lo: 0x8e, hi: 0x98},\n\t{value: 0x0c08, lo: 0x99, hi: 0x9b},\n\t{value: 0x0a08, lo: 0x9c, hi: 0xaa},\n\t{value: 0x0c08, lo: 0xab, hi: 0xac},\n\t{value: 0x0a08, lo: 0xad, hi: 0xb0},\n\t{value: 0x0c08, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0a08, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0c08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0a08, lo: 0xb5, hi: 0xb7},\n\t{value: 0x0c08, lo: 0xb8, hi: 0xb9},\n\t{value: 0x0a08, lo: 0xba, hi: 0xbf},\n\t// Block 0xa, offset 0x5d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xb0},\n\t{value: 0x0808, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xb, offset 0x62\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0808, lo: 0x80, hi: 0x89},\n\t{value: 0x0a08, lo: 0x8a, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xb3},\n\t{value: 0x0808, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xb9},\n\t{value: 0x0818, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0818, lo: 0xbe, hi: 0xbf},\n\t// Block 0xc, offset 0x6c\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x99},\n\t{value: 0x0808, lo: 0x9a, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0xa3},\n\t{value: 0x0808, lo: 0xa4, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa7},\n\t{value: 0x0808, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0818, lo: 0xb0, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd, offset 0x78\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0a08, lo: 0x80, hi: 0x88},\n\t{value: 0x0808, lo: 0x89, hi: 0x89},\n\t{value: 0x3308, lo: 0x8a, hi: 0xa1},\n\t{value: 0x0840, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xbf},\n\t// Block 0xe, offset 0x7e\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0xf, offset 0x87\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x85},\n\t{value: 0x3008, lo: 0x86, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x3008, lo: 0x8a, hi: 0x8c},\n\t{value: 0x3b08, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x10, offset 0x97\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbf},\n\t// Block 0x11, offset 0xa6\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0xba},\n\t{value: 0x3b08, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x12, offset 0xb1\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0008, lo: 0xb3, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x13, offset 0xbe\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x89},\n\t{value: 0x3b08, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8e},\n\t{value: 0x3008, lo: 0x8f, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x3008, lo: 0x98, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x14, offset 0xcf\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb2},\n\t{value: 0x01f1, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb9},\n\t{value: 0x3b08, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0x15, offset 0xd9\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x8e},\n\t{value: 0x0018, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0xbf},\n\t// Block 0x16, offset 0xe0\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x3308, lo: 0x88, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0201, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0209, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0008, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x17, offset 0xed\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0x8b},\n\t{value: 0xe03d, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3308, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x18, offset 0xfe\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0018, lo: 0x8e, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0xbf},\n\t// Block 0x19, offset 0x105\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x3008, lo: 0xab, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xb0},\n\t{value: 0x3008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0x1a, offset 0x110\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x95},\n\t{value: 0x3008, lo: 0x96, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0x9d},\n\t{value: 0x3308, lo: 0x9e, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3008, lo: 0xa2, hi: 0xa4},\n\t{value: 0x0008, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xbf},\n\t// Block 0x1b, offset 0x11f\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x3008, lo: 0x87, hi: 0x8c},\n\t{value: 0x3308, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x8e},\n\t{value: 0x3008, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x3008, lo: 0x9a, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x1c, offset 0x12d\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x86},\n\t{value: 0x055d, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8c},\n\t{value: 0x055d, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbb},\n\t{value: 0xe105, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x1d, offset 0x137\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0018, lo: 0x80, hi: 0xbf},\n\t// Block 0x1e, offset 0x139\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xa0},\n\t{value: 0x2018, lo: 0xa1, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0x1f, offset 0x13e\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xa7},\n\t{value: 0x2018, lo: 0xa8, hi: 0xbf},\n\t// Block 0x20, offset 0x141\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x2018, lo: 0x80, hi: 0x82},\n\t{value: 0x0018, lo: 0x83, hi: 0xbf},\n\t// Block 0x21, offset 0x144\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0008, lo: 0x80, hi: 0xbf},\n\t// Block 0x22, offset 0x146\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x23, offset 0x152\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x24, offset 0x15d\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbf},\n\t// Block 0x25, offset 0x165\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbf},\n\t// Block 0x26, offset 0x16b\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x27, offset 0x171\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x28, offset 0x176\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0xe045, lo: 0xb8, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x29, offset 0x17b\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xbf},\n\t// Block 0x2a, offset 0x17e\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xac},\n\t{value: 0x0018, lo: 0xad, hi: 0xae},\n\t{value: 0x0008, lo: 0xaf, hi: 0xbf},\n\t// Block 0x2b, offset 0x182\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x2c, offset 0x188\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xb0},\n\t{value: 0x0008, lo: 0xb1, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0x2d, offset 0x18d\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x93},\n\t{value: 0x3b08, lo: 0x94, hi: 0x94},\n\t{value: 0x3808, lo: 0x95, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x9e},\n\t{value: 0x0008, lo: 0x9f, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3808, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0018, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x2e, offset 0x198\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x2f, offset 0x1a2\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xb3},\n\t{value: 0x3340, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3008, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x30, offset 0x1a8\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x3008, lo: 0x80, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x3008, lo: 0x87, hi: 0x88},\n\t{value: 0x3308, lo: 0x89, hi: 0x91},\n\t{value: 0x3b08, lo: 0x92, hi: 0x92},\n\t{value: 0x3308, lo: 0x93, hi: 0x93},\n\t{value: 0x0018, lo: 0x94, hi: 0x96},\n\t{value: 0x0008, lo: 0x97, hi: 0x97},\n\t{value: 0x0018, lo: 0x98, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x31, offset 0x1b9\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0018, lo: 0x80, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x86},\n\t{value: 0x0218, lo: 0x87, hi: 0x87},\n\t{value: 0x0018, lo: 0x88, hi: 0x8a},\n\t{value: 0x33c0, lo: 0x8b, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8e},\n\t{value: 0x33c0, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0208, lo: 0xa0, hi: 0xbf},\n\t// Block 0x32, offset 0x1c4\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0208, lo: 0x80, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0x33, offset 0x1c7\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x0208, lo: 0x87, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0208, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x34, offset 0x1cf\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0x35, offset 0x1d2\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb8},\n\t{value: 0x3308, lo: 0xb9, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x36, offset 0x1df\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x37, offset 0x1e7\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x38, offset 0x1eb\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0028, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0xbf},\n\t// Block 0x39, offset 0x1f2\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x3308, lo: 0x97, hi: 0x98},\n\t{value: 0x3008, lo: 0x99, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x3a, offset 0x1fa\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x94},\n\t{value: 0x3008, lo: 0x95, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3b08, lo: 0xa0, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xac},\n\t{value: 0x3008, lo: 0xad, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x3b, offset 0x20a\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0018, lo: 0xa8, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xbd},\n\t{value: 0x3318, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x3c, offset 0x216\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x3308, lo: 0x80, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0xbf},\n\t// Block 0x3d, offset 0x219\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x3308, lo: 0x80, hi: 0x83},\n\t{value: 0x3008, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x3e, offset 0x223\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x3808, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x3f, offset 0x22f\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa9},\n\t{value: 0x3808, lo: 0xaa, hi: 0xaa},\n\t{value: 0x3b08, lo: 0xab, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xbf},\n\t// Block 0x40, offset 0x23b\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa9},\n\t{value: 0x3008, lo: 0xaa, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3808, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbf},\n\t// Block 0x41, offset 0x247\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x3008, lo: 0xa4, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbf},\n\t// Block 0x42, offset 0x24f\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0x43, offset 0x254\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x02a9, lo: 0x80, hi: 0x80},\n\t{value: 0x02b1, lo: 0x81, hi: 0x81},\n\t{value: 0x02b9, lo: 0x82, hi: 0x82},\n\t{value: 0x02c1, lo: 0x83, hi: 0x83},\n\t{value: 0x02c9, lo: 0x84, hi: 0x85},\n\t{value: 0x02d1, lo: 0x86, hi: 0x86},\n\t{value: 0x02d9, lo: 0x87, hi: 0x87},\n\t{value: 0x057d, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x059d, lo: 0x90, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbc},\n\t{value: 0x059d, lo: 0xbd, hi: 0xbf},\n\t// Block 0x44, offset 0x261\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x92},\n\t{value: 0x0018, lo: 0x93, hi: 0x93},\n\t{value: 0x3308, lo: 0x94, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa8},\n\t{value: 0x0008, lo: 0xa9, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x3008, lo: 0xb7, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x45, offset 0x272\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x87},\n\t{value: 0xe045, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0xe045, lo: 0x98, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0xe045, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb7},\n\t{value: 0xe045, lo: 0xb8, hi: 0xbf},\n\t// Block 0x46, offset 0x27d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x8f},\n\t{value: 0x3318, lo: 0x90, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbf},\n\t// Block 0x47, offset 0x282\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x88},\n\t{value: 0x0851, lo: 0x89, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x48, offset 0x28b\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0xab},\n\t{value: 0x0859, lo: 0xac, hi: 0xac},\n\t{value: 0x0861, lo: 0xad, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xae},\n\t{value: 0x0869, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0871, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0018, lo: 0xb1, hi: 0xbf},\n\t// Block 0x49, offset 0x293\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x9f},\n\t{value: 0x0080, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xad},\n\t{value: 0x0080, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x4a, offset 0x299\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xa8},\n\t{value: 0x09dd, lo: 0xa9, hi: 0xa9},\n\t{value: 0x09fd, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xbf},\n\t// Block 0x4b, offset 0x29e\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xbf},\n\t// Block 0x4c, offset 0x2a1\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x0929, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0xbf},\n\t// Block 0x4d, offset 0x2a5\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0e7e, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0932, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0e9e, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0x4e, offset 0x2ab\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x9b},\n\t{value: 0x0939, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0xbf},\n\t// Block 0x4f, offset 0x2af\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0x50, offset 0x2b3\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x96},\n\t{value: 0x0018, lo: 0x97, hi: 0xbf},\n\t// Block 0x51, offset 0x2b7\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0xe185, lo: 0x80, hi: 0x8f},\n\t{value: 0x03f5, lo: 0x90, hi: 0x9f},\n\t{value: 0x0ebd, lo: 0xa0, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x52, offset 0x2bc\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xac},\n\t{value: 0x0008, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x53, offset 0x2c4\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xae},\n\t{value: 0xe075, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0x54, offset 0x2cb\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x55, offset 0x2d6\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xbf},\n\t// Block 0x56, offset 0x2e0\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xae},\n\t{value: 0x0008, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x57, offset 0x2e4\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0x58, offset 0x2e7\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9e},\n\t{value: 0x0ef5, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbf},\n\t// Block 0x59, offset 0x2ed\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb2},\n\t{value: 0x0f15, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x5a, offset 0x2f1\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x0f35, lo: 0x80, hi: 0xbf},\n\t// Block 0x5b, offset 0x2f3\n\t{value: 0x0020, lo: 0x02},\n\t{value: 0x1735, lo: 0x80, hi: 0x8f},\n\t{value: 0x1915, lo: 0x90, hi: 0xbf},\n\t// Block 0x5c, offset 0x2f6\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x1f15, lo: 0x80, hi: 0xbf},\n\t// Block 0x5d, offset 0x2f8\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xbf},\n\t// Block 0x5e, offset 0x2fb\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x98},\n\t{value: 0x3308, lo: 0x99, hi: 0x9a},\n\t{value: 0x096a, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0972, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0008, lo: 0x9d, hi: 0x9e},\n\t{value: 0x0979, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xbf},\n\t// Block 0x5f, offset 0x305\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xbe},\n\t{value: 0x0981, lo: 0xbf, hi: 0xbf},\n\t// Block 0x60, offset 0x308\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0040, lo: 0x80, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xb0},\n\t{value: 0x2a35, lo: 0xb1, hi: 0xb1},\n\t{value: 0x2a55, lo: 0xb2, hi: 0xb2},\n\t{value: 0x2a75, lo: 0xb3, hi: 0xb3},\n\t{value: 0x2a95, lo: 0xb4, hi: 0xb4},\n\t{value: 0x2a75, lo: 0xb5, hi: 0xb5},\n\t{value: 0x2ab5, lo: 0xb6, hi: 0xb6},\n\t{value: 0x2ad5, lo: 0xb7, hi: 0xb7},\n\t{value: 0x2af5, lo: 0xb8, hi: 0xb9},\n\t{value: 0x2b15, lo: 0xba, hi: 0xbb},\n\t{value: 0x2b35, lo: 0xbc, hi: 0xbd},\n\t{value: 0x2b15, lo: 0xbe, hi: 0xbf},\n\t// Block 0x61, offset 0x317\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x62, offset 0x31b\n\t{value: 0x0008, lo: 0x03},\n\t{value: 0x098a, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0a82, lo: 0xa0, hi: 0xbf},\n\t// Block 0x63, offset 0x31f\n\t{value: 0x0008, lo: 0x01},\n\t{value: 0x0d19, lo: 0x80, hi: 0xbf},\n\t// Block 0x64, offset 0x321\n\t{value: 0x0008, lo: 0x08},\n\t{value: 0x0f19, lo: 0x80, hi: 0xb0},\n\t{value: 0x4045, lo: 0xb1, hi: 0xb1},\n\t{value: 0x10a1, lo: 0xb2, hi: 0xb3},\n\t{value: 0x4065, lo: 0xb4, hi: 0xb4},\n\t{value: 0x10b1, lo: 0xb5, hi: 0xb7},\n\t{value: 0x4085, lo: 0xb8, hi: 0xb8},\n\t{value: 0x4085, lo: 0xb9, hi: 0xb9},\n\t{value: 0x10c9, lo: 0xba, hi: 0xbf},\n\t// Block 0x65, offset 0x32a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x66, offset 0x32e\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0x67, offset 0x333\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xbf},\n\t// Block 0x68, offset 0x338\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x0018, lo: 0xa6, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0018, lo: 0xb2, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x69, offset 0x33e\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0x85},\n\t{value: 0x3b08, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x8a},\n\t{value: 0x3308, lo: 0x8b, hi: 0x8b},\n\t{value: 0x0008, lo: 0x8c, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0018, lo: 0xa8, hi: 0xab},\n\t{value: 0x3b08, lo: 0xac, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x6a, offset 0x34e\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0208, lo: 0x80, hi: 0xb1},\n\t{value: 0x0108, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0008, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x6b, offset 0x354\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xbf},\n\t// Block 0x6c, offset 0x358\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3008, lo: 0x80, hi: 0x83},\n\t{value: 0x3b08, lo: 0x84, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8d},\n\t{value: 0x0018, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xba},\n\t{value: 0x0008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x6d, offset 0x367\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x6e, offset 0x36c\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x91},\n\t{value: 0x3008, lo: 0x92, hi: 0x92},\n\t{value: 0x3808, lo: 0x93, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x6f, offset 0x374\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb9},\n\t{value: 0x3008, lo: 0xba, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x70, offset 0x37e\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3808, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x71, offset 0x389\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x72, offset 0x391\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x8b},\n\t{value: 0x3308, lo: 0x8c, hi: 0x8c},\n\t{value: 0x3008, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0018, lo: 0x9c, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x73, offset 0x3a2\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0008, lo: 0xb9, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbf},\n\t// Block 0x74, offset 0x3ab\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x9a},\n\t{value: 0x0008, lo: 0x9b, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xaa},\n\t{value: 0x3008, lo: 0xab, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3b08, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x75, offset 0x3bb\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x88},\n\t{value: 0x0008, lo: 0x89, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x90},\n\t{value: 0x0008, lo: 0x91, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x76, offset 0x3c8\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x449d, lo: 0x9c, hi: 0x9c},\n\t{value: 0x44b5, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0941, lo: 0x9e, hi: 0x9e},\n\t{value: 0xe06d, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa8},\n\t{value: 0x13f9, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x44cd, lo: 0xb0, hi: 0xbf},\n\t// Block 0x77, offset 0x3d4\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x44ed, lo: 0x80, hi: 0x8f},\n\t{value: 0x450d, lo: 0x90, hi: 0x9f},\n\t{value: 0x452d, lo: 0xa0, hi: 0xaf},\n\t{value: 0x450d, lo: 0xb0, hi: 0xbf},\n\t// Block 0x78, offset 0x3d9\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3b08, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x79, offset 0x3e6\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7a, offset 0x3ea\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8a},\n\t{value: 0x0018, lo: 0x8b, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x7b, offset 0x3ef\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0040, lo: 0x80, hi: 0xbf},\n\t// Block 0x7c, offset 0x3f1\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x454d, lo: 0x80, hi: 0xbf},\n\t// Block 0x7d, offset 0x3f3\n\t{value: 0x0020, lo: 0x03},\n\t{value: 0x4d4d, lo: 0x80, hi: 0x94},\n\t{value: 0x4b0d, lo: 0x95, hi: 0x95},\n\t{value: 0x4fed, lo: 0x96, hi: 0xbf},\n\t// Block 0x7e, offset 0x3f7\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x552d, lo: 0x80, hi: 0xbf},\n\t// Block 0x7f, offset 0x3f9\n\t{value: 0x0020, lo: 0x03},\n\t{value: 0x5d2d, lo: 0x80, hi: 0x84},\n\t{value: 0x568d, lo: 0x85, hi: 0x85},\n\t{value: 0x5dcd, lo: 0x86, hi: 0xbf},\n\t// Block 0x80, offset 0x3fd\n\t{value: 0x0020, lo: 0x08},\n\t{value: 0x6b8d, lo: 0x80, hi: 0x8f},\n\t{value: 0x6d4d, lo: 0x90, hi: 0x90},\n\t{value: 0x6d8d, lo: 0x91, hi: 0xab},\n\t{value: 0x1401, lo: 0xac, hi: 0xac},\n\t{value: 0x70ed, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x710d, lo: 0xb0, hi: 0xbf},\n\t// Block 0x81, offset 0x406\n\t{value: 0x0020, lo: 0x05},\n\t{value: 0x730d, lo: 0x80, hi: 0xad},\n\t{value: 0x656d, lo: 0xae, hi: 0xae},\n\t{value: 0x78cd, lo: 0xaf, hi: 0xb5},\n\t{value: 0x6f8d, lo: 0xb6, hi: 0xb6},\n\t{value: 0x79ad, lo: 0xb7, hi: 0xbf},\n\t// Block 0x82, offset 0x40c\n\t{value: 0x0008, lo: 0x03},\n\t{value: 0x1751, lo: 0x80, hi: 0x82},\n\t{value: 0x1741, lo: 0x83, hi: 0x83},\n\t{value: 0x1769, lo: 0x84, hi: 0xbf},\n\t// Block 0x83, offset 0x410\n\t{value: 0x0008, lo: 0x0f},\n\t{value: 0x1d81, lo: 0x80, hi: 0x83},\n\t{value: 0x1d99, lo: 0x84, hi: 0x85},\n\t{value: 0x1da1, lo: 0x86, hi: 0x87},\n\t{value: 0x1da9, lo: 0x88, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x1de9, lo: 0x92, hi: 0x97},\n\t{value: 0x1e11, lo: 0x98, hi: 0x9c},\n\t{value: 0x1e31, lo: 0x9d, hi: 0xb3},\n\t{value: 0x1d71, lo: 0xb4, hi: 0xb4},\n\t{value: 0x1d81, lo: 0xb5, hi: 0xb5},\n\t{value: 0x1ee9, lo: 0xb6, hi: 0xbb},\n\t{value: 0x1f09, lo: 0xbc, hi: 0xbc},\n\t{value: 0x1ef9, lo: 0xbd, hi: 0xbd},\n\t{value: 0x1f19, lo: 0xbe, hi: 0xbf},\n\t// Block 0x84, offset 0x420\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0008, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0x85, offset 0x42a\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0x86, offset 0x42f\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x87, offset 0x432\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0x88, offset 0x438\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0040, lo: 0xa1, hi: 0xbf},\n\t// Block 0x89, offset 0x43f\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x8a, offset 0x444\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x8b, offset 0x448\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x8c, offset 0x44e\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xac},\n\t{value: 0x0008, lo: 0xad, hi: 0xbf},\n\t// Block 0x8d, offset 0x453\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x8e, offset 0x45c\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x8f, offset 0x461\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0xbf},\n\t// Block 0x90, offset 0x467\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe145, lo: 0x80, hi: 0x87},\n\t{value: 0xe1c5, lo: 0x88, hi: 0x8f},\n\t{value: 0xe145, lo: 0x90, hi: 0x97},\n\t{value: 0x8b0d, lo: 0x98, hi: 0x9f},\n\t{value: 0x8b25, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xbf},\n\t// Block 0x91, offset 0x46e\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x8b25, lo: 0xb0, hi: 0xb7},\n\t{value: 0x8b0d, lo: 0xb8, hi: 0xbf},\n\t// Block 0x92, offset 0x475\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe145, lo: 0x80, hi: 0x87},\n\t{value: 0xe1c5, lo: 0x88, hi: 0x8f},\n\t{value: 0xe145, lo: 0x90, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x93, offset 0x47c\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x94, offset 0x480\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x95, offset 0x483\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xbf},\n\t// Block 0x96, offset 0x488\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x87},\n\t{value: 0x0808, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0808, lo: 0x8a, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0808, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbb},\n\t{value: 0x0808, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbe},\n\t{value: 0x0808, lo: 0xbf, hi: 0xbf},\n\t// Block 0x97, offset 0x494\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x96},\n\t{value: 0x0818, lo: 0x97, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0818, lo: 0xb7, hi: 0xbf},\n\t// Block 0x98, offset 0x49a\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xa6},\n\t{value: 0x0818, lo: 0xa7, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x99, offset 0x49f\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0808, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xba},\n\t{value: 0x0818, lo: 0xbb, hi: 0xbf},\n\t// Block 0x9a, offset 0x4a6\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0818, lo: 0x96, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbe},\n\t{value: 0x0818, lo: 0xbf, hi: 0xbf},\n\t// Block 0x9b, offset 0x4ae\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbb},\n\t{value: 0x0818, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0808, lo: 0xbe, hi: 0xbf},\n\t// Block 0x9c, offset 0x4b3\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0818, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x91},\n\t{value: 0x0818, lo: 0x92, hi: 0xbf},\n\t// Block 0x9d, offset 0x4b7\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0808, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8b},\n\t{value: 0x3308, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x94},\n\t{value: 0x0808, lo: 0x95, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0x98},\n\t{value: 0x0808, lo: 0x99, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0x9e, offset 0x4c7\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0818, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x0818, lo: 0x90, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xbc},\n\t{value: 0x0818, lo: 0xbd, hi: 0xbf},\n\t// Block 0x9f, offset 0x4ce\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0x9c},\n\t{value: 0x0818, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xa0, offset 0x4d2\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb8},\n\t{value: 0x0018, lo: 0xb9, hi: 0xbf},\n\t// Block 0xa1, offset 0x4d6\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0818, lo: 0x98, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb7},\n\t{value: 0x0818, lo: 0xb8, hi: 0xbf},\n\t// Block 0xa2, offset 0x4dd\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0808, lo: 0x80, hi: 0xbf},\n\t// Block 0xa3, offset 0x4df\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0808, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0xbf},\n\t// Block 0xa4, offset 0x4e2\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x03dd, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbf},\n\t// Block 0xa5, offset 0x4e5\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb9},\n\t{value: 0x0818, lo: 0xba, hi: 0xbf},\n\t// Block 0xa6, offset 0x4e9\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0908, lo: 0x80, hi: 0x80},\n\t{value: 0x0a08, lo: 0x81, hi: 0xa1},\n\t{value: 0x0c08, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0a08, lo: 0xa3, hi: 0xa3},\n\t{value: 0x3308, lo: 0xa4, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0808, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xa7, offset 0x4f2\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0818, lo: 0xa0, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xa8, offset 0x4f6\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xac},\n\t{value: 0x0818, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0808, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xa9, offset 0x4fe\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbf},\n\t// Block 0xaa, offset 0x501\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0x9c},\n\t{value: 0x0818, lo: 0x9d, hi: 0xa6},\n\t{value: 0x0808, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0a08, lo: 0xb0, hi: 0xb2},\n\t{value: 0x0c08, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0a08, lo: 0xb4, hi: 0xbf},\n\t// Block 0xab, offset 0x509\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0a08, lo: 0x80, hi: 0x84},\n\t{value: 0x0808, lo: 0x85, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x90},\n\t{value: 0x0a18, lo: 0x91, hi: 0x93},\n\t{value: 0x0c18, lo: 0x94, hi: 0x94},\n\t{value: 0x0818, lo: 0x95, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xaf},\n\t{value: 0x0a08, lo: 0xb0, hi: 0xb3},\n\t{value: 0x0c08, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0a08, lo: 0xb6, hi: 0xbf},\n\t// Block 0xac, offset 0x514\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0a08, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x85},\n\t{value: 0x0818, lo: 0x86, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0xaf},\n\t{value: 0x0a08, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0808, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0a08, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0c08, lo: 0xb4, hi: 0xb6},\n\t{value: 0x0808, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0a08, lo: 0xb8, hi: 0xb8},\n\t{value: 0x0c08, lo: 0xb9, hi: 0xba},\n\t{value: 0x0a08, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0c08, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0a08, lo: 0xbe, hi: 0xbf},\n\t// Block 0xad, offset 0x523\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x80},\n\t{value: 0x0a08, lo: 0x81, hi: 0x81},\n\t{value: 0x0c08, lo: 0x82, hi: 0x83},\n\t{value: 0x0a08, lo: 0x84, hi: 0x84},\n\t{value: 0x0818, lo: 0x85, hi: 0x88},\n\t{value: 0x0c18, lo: 0x89, hi: 0x89},\n\t{value: 0x0a18, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0918, lo: 0x8b, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xae, offset 0x52f\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbf},\n\t// Block 0xaf, offset 0x535\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x3308, lo: 0x80, hi: 0x85},\n\t{value: 0x3b08, lo: 0x86, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x91},\n\t{value: 0x0018, lo: 0x92, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x3b08, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0008, lo: 0xb1, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb0, offset 0x542\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb6},\n\t{value: 0x3008, lo: 0xb7, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0xb1, offset 0x54e\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xb2, offset 0x556\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xb2},\n\t{value: 0x3b08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0008, lo: 0xb6, hi: 0xbf},\n\t// Block 0xb3, offset 0x55f\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0018, lo: 0x80, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x3008, lo: 0x85, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0008, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xb4, offset 0x56a\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xbe},\n\t{value: 0x3008, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb5, offset 0x571\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3808, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x88},\n\t{value: 0x3308, lo: 0x89, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8d},\n\t{value: 0x3008, lo: 0x8e, hi: 0x8e},\n\t{value: 0x3308, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xb6, offset 0x580\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x92},\n\t{value: 0x0008, lo: 0x93, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3808, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb7, offset 0x58d\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x0040, lo: 0x82, hi: 0xbf},\n\t// Block 0xb8, offset 0x591\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0008, lo: 0x9f, hi: 0xa8},\n\t{value: 0x0018, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0xb9, offset 0x59e\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x3308, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3008, lo: 0xa0, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xa9},\n\t{value: 0x3b08, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xba, offset 0x5a7\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbf},\n\t// Block 0xbb, offset 0x5ab\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x3b08, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x84},\n\t{value: 0x3008, lo: 0x85, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x8a},\n\t{value: 0x0018, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0x9d},\n\t{value: 0x3308, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0008, lo: 0x9f, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xbf},\n\t// Block 0xbc, offset 0x5ba\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb8},\n\t{value: 0x3008, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbd, offset 0x5c2\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x81},\n\t{value: 0x3b08, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x85},\n\t{value: 0x0018, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xbe, offset 0x5cd\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbf, offset 0x5d6\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x9b},\n\t{value: 0x3308, lo: 0x9c, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0xc0, offset 0x5dc\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc1, offset 0x5e4\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xbf},\n\t// Block 0xc2, offset 0x5ed\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb5},\n\t{value: 0x3808, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x0018, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xc3, offset 0x5f9\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0xbf},\n\t// Block 0xc4, offset 0x5fc\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9f},\n\t{value: 0x3008, lo: 0xa0, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xaa},\n\t{value: 0x3b08, lo: 0xab, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbf},\n\t// Block 0xc5, offset 0x608\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0xbf},\n\t// Block 0xc6, offset 0x60b\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0xc7, offset 0x614\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x049d, lo: 0xa0, hi: 0xbf},\n\t// Block 0xc8, offset 0x617\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc9, offset 0x61c\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3008, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xca, offset 0x625\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xbf},\n\t// Block 0xcb, offset 0x62a\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x3008, lo: 0x91, hi: 0x93},\n\t{value: 0x3308, lo: 0x94, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0x99},\n\t{value: 0x3308, lo: 0x9a, hi: 0x9b},\n\t{value: 0x3008, lo: 0x9c, hi: 0x9f},\n\t{value: 0x3b08, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x0018, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0008, lo: 0xa3, hi: 0xa3},\n\t{value: 0x3008, lo: 0xa4, hi: 0xa4},\n\t{value: 0x0040, lo: 0xa5, hi: 0xbf},\n\t// Block 0xcc, offset 0x637\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3b08, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb8},\n\t{value: 0x3008, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0xcd, offset 0x642\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x3b08, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x3308, lo: 0x91, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x98},\n\t{value: 0x3308, lo: 0x99, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0xbf},\n\t// Block 0xce, offset 0x64b\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x3308, lo: 0x8a, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x98},\n\t{value: 0x3b08, lo: 0x99, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9c},\n\t{value: 0x0008, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0xa2},\n\t{value: 0x0040, lo: 0xa3, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0xcf, offset 0x656\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xd0, offset 0x659\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0xbf},\n\t// Block 0xd1, offset 0x65c\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd2, offset 0x666\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xbf},\n\t// Block 0xd3, offset 0x66f\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xa9},\n\t{value: 0x3308, lo: 0xaa, hi: 0xb0},\n\t{value: 0x3008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xd4, offset 0x67b\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd5, offset 0x688\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x3308, lo: 0x80, hi: 0x83},\n\t{value: 0x3b08, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xbf},\n\t// Block 0xd6, offset 0x695\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x3008, lo: 0x8a, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x92},\n\t{value: 0x3008, lo: 0x93, hi: 0x94},\n\t{value: 0x3308, lo: 0x95, hi: 0x95},\n\t{value: 0x3008, lo: 0x96, hi: 0x96},\n\t{value: 0x3b08, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xbf},\n\t// Block 0xd7, offset 0x6a3\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xd8, offset 0x6aa\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0xd9, offset 0x6b5\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3808, lo: 0x81, hi: 0x81},\n\t{value: 0x3b08, lo: 0x82, hi: 0x82},\n\t{value: 0x0018, lo: 0x83, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xda, offset 0x6bc\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbf},\n\t// Block 0xdb, offset 0x6c0\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0xdc, offset 0x6c4\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xdd, offset 0x6c7\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xde, offset 0x6cc\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0xbf},\n\t// Block 0xdf, offset 0x6cf\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xbf},\n\t// Block 0xe0, offset 0x6d2\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xb0},\n\t{value: 0x0018, lo: 0xb1, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbf},\n\t// Block 0xe1, offset 0x6d6\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x0340, lo: 0xb0, hi: 0xbf},\n\t// Block 0xe2, offset 0x6d9\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0xbf},\n\t// Block 0xe3, offset 0x6de\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0xe4, offset 0x6e5\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xe5, offset 0x6e8\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0018, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xe6, offset 0x6f0\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0xe7, offset 0x6f4\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0008, lo: 0xa3, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbf},\n\t// Block 0xe8, offset 0x6ff\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0xbf},\n\t// Block 0xe9, offset 0x702\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0xe105, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0xea, offset 0x705\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0xbf},\n\t// Block 0xeb, offset 0x708\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8e},\n\t{value: 0x3308, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x3008, lo: 0x91, hi: 0xbf},\n\t// Block 0xec, offset 0x70e\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3008, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8e},\n\t{value: 0x3308, lo: 0x8f, hi: 0x92},\n\t{value: 0x0008, lo: 0x93, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xed, offset 0x714\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa1},\n\t{value: 0x0018, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0008, lo: 0xa3, hi: 0xa3},\n\t{value: 0x3308, lo: 0xa4, hi: 0xa4},\n\t{value: 0x0040, lo: 0xa5, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xee, offset 0x71d\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0xef, offset 0x720\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0xbf},\n\t// Block 0xf0, offset 0x723\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0xbf},\n\t// Block 0xf1, offset 0x726\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0040, lo: 0x80, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xf2, offset 0x72e\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa2},\n\t{value: 0x0040, lo: 0xa3, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbf},\n\t// Block 0xf3, offset 0x733\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x92},\n\t{value: 0x0040, lo: 0x93, hi: 0x94},\n\t{value: 0x0008, lo: 0x95, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0xa3},\n\t{value: 0x0008, lo: 0xa4, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0xf4, offset 0x73c\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0xf5, offset 0x73f\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0xf6, offset 0x744\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0018, lo: 0x9c, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x03c0, lo: 0xa0, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xbf},\n\t// Block 0xf7, offset 0x74e\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3308, lo: 0x80, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xbf},\n\t// Block 0xf8, offset 0x752\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3308, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0xf9, offset 0x756\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0xbf},\n\t// Block 0xfa, offset 0x759\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xfb, offset 0x75c\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa8},\n\t{value: 0x0018, lo: 0xa9, hi: 0xbf},\n\t// Block 0xfc, offset 0x760\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0018, lo: 0x80, hi: 0x9d},\n\t{value: 0x2379, lo: 0x9e, hi: 0x9e},\n\t{value: 0x2381, lo: 0x9f, hi: 0x9f},\n\t{value: 0x2389, lo: 0xa0, hi: 0xa0},\n\t{value: 0x2391, lo: 0xa1, hi: 0xa1},\n\t{value: 0x2399, lo: 0xa2, hi: 0xa2},\n\t{value: 0x23a1, lo: 0xa3, hi: 0xa3},\n\t{value: 0x23a9, lo: 0xa4, hi: 0xa4},\n\t{value: 0x3018, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3318, lo: 0xa7, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xac},\n\t{value: 0x3018, lo: 0xad, hi: 0xb2},\n\t{value: 0x0340, lo: 0xb3, hi: 0xba},\n\t{value: 0x3318, lo: 0xbb, hi: 0xbf},\n\t// Block 0xfd, offset 0x76f\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3318, lo: 0x80, hi: 0x82},\n\t{value: 0x0018, lo: 0x83, hi: 0x84},\n\t{value: 0x3318, lo: 0x85, hi: 0x8b},\n\t{value: 0x0018, lo: 0x8c, hi: 0xa9},\n\t{value: 0x3318, lo: 0xaa, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xba},\n\t{value: 0x23b1, lo: 0xbb, hi: 0xbb},\n\t{value: 0x23b9, lo: 0xbc, hi: 0xbc},\n\t{value: 0x23c1, lo: 0xbd, hi: 0xbd},\n\t{value: 0x23c9, lo: 0xbe, hi: 0xbe},\n\t{value: 0x23d1, lo: 0xbf, hi: 0xbf},\n\t// Block 0xfe, offset 0x77b\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x23d9, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xbf},\n\t// Block 0xff, offset 0x77f\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x81},\n\t{value: 0x3318, lo: 0x82, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0xbf},\n\t// Block 0x100, offset 0x784\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x101, offset 0x789\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0x102, offset 0x78e\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3308, lo: 0x80, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbf},\n\t// Block 0x103, offset 0x792\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x3308, lo: 0x80, hi: 0xac},\n\t{value: 0x0018, lo: 0xad, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0x104, offset 0x797\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x3308, lo: 0xa1, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x105, offset 0x7a0\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xa4},\n\t{value: 0x0008, lo: 0xa5, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xbf},\n\t// Block 0x106, offset 0x7a5\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x8e},\n\t{value: 0x3308, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0xbf},\n\t// Block 0x107, offset 0x7a9\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0008, lo: 0xb7, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x108, offset 0x7af\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0018, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0xbf},\n\t// Block 0x109, offset 0x7b5\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xad},\n\t{value: 0x3308, lo: 0xae, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xbf},\n\t// Block 0x10a, offset 0x7ba\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0x10b, offset 0x7c0\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x10c, offset 0x7c6\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xac},\n\t{value: 0x0008, lo: 0xad, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x10d, offset 0x7d0\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0808, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x86},\n\t{value: 0x0818, lo: 0x87, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0xbf},\n\t// Block 0x10e, offset 0x7d6\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0a08, lo: 0x80, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x8a},\n\t{value: 0x0b08, lo: 0x8b, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0818, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x10f, offset 0x7df\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xb0},\n\t{value: 0x0818, lo: 0xb1, hi: 0xbf},\n\t// Block 0x110, offset 0x7e2\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0818, lo: 0x80, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x111, offset 0x7e5\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0818, lo: 0x81, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x112, offset 0x7e9\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0x113, offset 0x7ed\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x114, offset 0x7f1\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xb0},\n\t{value: 0x0018, lo: 0xb1, hi: 0xbf},\n\t// Block 0x115, offset 0x7f7\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x0018, lo: 0x91, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0x116, offset 0x7fd\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x8f},\n\t{value: 0x2709, lo: 0x90, hi: 0x90},\n\t{value: 0x0018, lo: 0x91, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xbf},\n\t// Block 0x117, offset 0x802\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xa5},\n\t{value: 0x0018, lo: 0xa6, hi: 0xbf},\n\t// Block 0x118, offset 0x805\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x2889, lo: 0x80, hi: 0x80},\n\t{value: 0x2891, lo: 0x81, hi: 0x81},\n\t{value: 0x2899, lo: 0x82, hi: 0x82},\n\t{value: 0x28a1, lo: 0x83, hi: 0x83},\n\t{value: 0x28a9, lo: 0x84, hi: 0x84},\n\t{value: 0x28b1, lo: 0x85, hi: 0x85},\n\t{value: 0x28b9, lo: 0x86, hi: 0x86},\n\t{value: 0x28c1, lo: 0x87, hi: 0x87},\n\t{value: 0x28c9, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x28d1, lo: 0x90, hi: 0x90},\n\t{value: 0x28d9, lo: 0x91, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xbf},\n\t// Block 0x119, offset 0x815\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0x9b},\n\t{value: 0x0018, lo: 0x9c, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x11a, offset 0x81c\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbf},\n\t// Block 0x11b, offset 0x820\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbf},\n\t// Block 0x11c, offset 0x827\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x11d, offset 0x82b\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbf},\n\t// Block 0x11e, offset 0x831\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0x11f, offset 0x838\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x120, offset 0x83f\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0x121, offset 0x845\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8d},\n\t{value: 0x0018, lo: 0x8e, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0x122, offset 0x84e\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x92},\n\t{value: 0x0040, lo: 0x93, hi: 0x93},\n\t{value: 0x0018, lo: 0x94, hi: 0xbf},\n\t// Block 0x123, offset 0x852\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0018, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0xaf},\n\t{value: 0x06e1, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0049, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0029, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0031, lo: 0xb3, hi: 0xb3},\n\t{value: 0x06e9, lo: 0xb4, hi: 0xb4},\n\t{value: 0x06f1, lo: 0xb5, hi: 0xb5},\n\t{value: 0x06f9, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0701, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0709, lo: 0xb8, hi: 0xb8},\n\t{value: 0x0711, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x124, offset 0x860\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x125, offset 0x863\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x126, offset 0x866\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x127, offset 0x86a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x128, offset 0x86e\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xa0},\n\t{value: 0x0040, lo: 0xa1, hi: 0xbf},\n\t// Block 0x129, offset 0x871\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xbf},\n\t// Block 0x12a, offset 0x875\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x12b, offset 0x878\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0340, lo: 0x81, hi: 0x81},\n\t{value: 0x0040, lo: 0x82, hi: 0x9f},\n\t{value: 0x0340, lo: 0xa0, hi: 0xbf},\n\t// Block 0x12c, offset 0x87d\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0340, lo: 0x80, hi: 0xbf},\n\t// Block 0x12d, offset 0x87f\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x33c0, lo: 0x80, hi: 0xbf},\n\t// Block 0x12e, offset 0x881\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x33c0, lo: 0x80, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n}\n\n// Total table size 46723 bytes (45KiB); checksum: 4CF3143A\n"
  },
  {
    "path": "vendor/golang.org/x/net/idna/tables9.0.0.go",
    "content": "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n//go:build !go1.10\n\npackage idna\n\n// UnicodeVersion is the Unicode version from which the tables in this package are derived.\nconst UnicodeVersion = \"9.0.0\"\n\nvar mappings string = \"\" + // Size: 8175 bytes\n\t\"\\x00\\x01 \\x03 ̈\\x01a\\x03 ̄\\x012\\x013\\x03 ́\\x03 ̧\\x011\\x01o\\x051⁄4\\x051⁄2\" +\n\t\"\\x053⁄4\\x03i̇\\x03l·\\x03ʼn\\x01s\\x03dž\\x03ⱥ\\x03ⱦ\\x01h\\x01j\\x01r\\x01w\\x01y\" +\n\t\"\\x03 ̆\\x03 ̇\\x03 ̊\\x03 ̨\\x03 ̃\\x03 ̋\\x01l\\x01x\\x04̈́\\x03 ι\\x01;\\x05 ̈́\" +\n\t\"\\x04եւ\\x04اٴ\\x04وٴ\\x04ۇٴ\\x04يٴ\\x06क़\\x06ख़\\x06ग़\\x06ज़\\x06ड़\\x06ढ़\\x06फ़\" +\n\t\"\\x06य़\\x06ড়\\x06ঢ়\\x06য়\\x06ਲ਼\\x06ਸ਼\\x06ਖ਼\\x06ਗ਼\\x06ਜ਼\\x06ਫ਼\\x06ଡ଼\\x06ଢ଼\" +\n\t\"\\x06ํา\\x06ໍາ\\x06ຫນ\\x06ຫມ\\x06གྷ\\x06ཌྷ\\x06དྷ\\x06བྷ\\x06ཛྷ\\x06ཀྵ\\x06ཱི\\x06ཱུ\" +\n\t\"\\x06ྲྀ\\x09ྲཱྀ\\x06ླྀ\\x09ླཱྀ\\x06ཱྀ\\x06ྒྷ\\x06ྜྷ\\x06ྡྷ\\x06ྦྷ\\x06ྫྷ\\x06ྐྵ\\x02\" +\n\t\"в\\x02д\\x02о\\x02с\\x02т\\x02ъ\\x02ѣ\\x02æ\\x01b\\x01d\\x01e\\x02ǝ\\x01g\\x01i\\x01k\" +\n\t\"\\x01m\\x01n\\x02ȣ\\x01p\\x01t\\x01u\\x02ɐ\\x02ɑ\\x02ə\\x02ɛ\\x02ɜ\\x02ŋ\\x02ɔ\\x02ɯ\" +\n\t\"\\x01v\\x02β\\x02γ\\x02δ\\x02φ\\x02χ\\x02ρ\\x02н\\x02ɒ\\x01c\\x02ɕ\\x02ð\\x01f\\x02ɟ\" +\n\t\"\\x02ɡ\\x02ɥ\\x02ɨ\\x02ɩ\\x02ɪ\\x02ʝ\\x02ɭ\\x02ʟ\\x02ɱ\\x02ɰ\\x02ɲ\\x02ɳ\\x02ɴ\\x02ɵ\" +\n\t\"\\x02ɸ\\x02ʂ\\x02ʃ\\x02ƫ\\x02ʉ\\x02ʊ\\x02ʋ\\x02ʌ\\x01z\\x02ʐ\\x02ʑ\\x02ʒ\\x02θ\\x02ss\" +\n\t\"\\x02ά\\x02έ\\x02ή\\x02ί\\x02ό\\x02ύ\\x02ώ\\x05ἀι\\x05ἁι\\x05ἂι\\x05ἃι\\x05ἄι\\x05ἅι\" +\n\t\"\\x05ἆι\\x05ἇι\\x05ἠι\\x05ἡι\\x05ἢι\\x05ἣι\\x05ἤι\\x05ἥι\\x05ἦι\\x05ἧι\\x05ὠι\\x05ὡι\" +\n\t\"\\x05ὢι\\x05ὣι\\x05ὤι\\x05ὥι\\x05ὦι\\x05ὧι\\x05ὰι\\x04αι\\x04άι\\x05ᾶι\\x02ι\\x05 ̈͂\" +\n\t\"\\x05ὴι\\x04ηι\\x04ήι\\x05ῆι\\x05 ̓̀\\x05 ̓́\\x05 ̓͂\\x02ΐ\\x05 ̔̀\\x05 ̔́\\x05 ̔͂\" +\n\t\"\\x02ΰ\\x05 ̈̀\\x01`\\x05ὼι\\x04ωι\\x04ώι\\x05ῶι\\x06′′\\x09′′′\\x06‵‵\\x09‵‵‵\\x02!\" +\n\t\"!\\x02??\\x02?!\\x02!?\\x0c′′′′\\x010\\x014\\x015\\x016\\x017\\x018\\x019\\x01+\\x01=\" +\n\t\"\\x01(\\x01)\\x02rs\\x02ħ\\x02no\\x01q\\x02sm\\x02tm\\x02ω\\x02å\\x02א\\x02ב\\x02ג\" +\n\t\"\\x02ד\\x02π\\x051⁄7\\x051⁄9\\x061⁄10\\x051⁄3\\x052⁄3\\x051⁄5\\x052⁄5\\x053⁄5\\x054\" +\n\t\"⁄5\\x051⁄6\\x055⁄6\\x051⁄8\\x053⁄8\\x055⁄8\\x057⁄8\\x041⁄\\x02ii\\x02iv\\x02vi\" +\n\t\"\\x04viii\\x02ix\\x02xi\\x050⁄3\\x06∫∫\\x09∫∫∫\\x06∮∮\\x09∮∮∮\\x0210\\x0211\\x0212\" +\n\t\"\\x0213\\x0214\\x0215\\x0216\\x0217\\x0218\\x0219\\x0220\\x04(10)\\x04(11)\\x04(12)\" +\n\t\"\\x04(13)\\x04(14)\\x04(15)\\x04(16)\\x04(17)\\x04(18)\\x04(19)\\x04(20)\\x0c∫∫∫∫\" +\n\t\"\\x02==\\x05⫝̸\\x02ɫ\\x02ɽ\\x02ȿ\\x02ɀ\\x01.\\x04 ゙\\x04 ゚\\x06より\\x06コト\\x05(ᄀ)\\x05\" +\n\t\"(ᄂ)\\x05(ᄃ)\\x05(ᄅ)\\x05(ᄆ)\\x05(ᄇ)\\x05(ᄉ)\\x05(ᄋ)\\x05(ᄌ)\\x05(ᄎ)\\x05(ᄏ)\\x05(ᄐ\" +\n\t\")\\x05(ᄑ)\\x05(ᄒ)\\x05(가)\\x05(나)\\x05(다)\\x05(라)\\x05(마)\\x05(바)\\x05(사)\\x05(아)\" +\n\t\"\\x05(자)\\x05(차)\\x05(카)\\x05(타)\\x05(파)\\x05(하)\\x05(주)\\x08(오전)\\x08(오후)\\x05(一)\" +\n\t\"\\x05(二)\\x05(三)\\x05(四)\\x05(五)\\x05(六)\\x05(七)\\x05(八)\\x05(九)\\x05(十)\\x05(月)\" +\n\t\"\\x05(火)\\x05(水)\\x05(木)\\x05(金)\\x05(土)\\x05(日)\\x05(株)\\x05(有)\\x05(社)\\x05(名)\" +\n\t\"\\x05(特)\\x05(財)\\x05(祝)\\x05(労)\\x05(代)\\x05(呼)\\x05(学)\\x05(監)\\x05(企)\\x05(資)\" +\n\t\"\\x05(協)\\x05(祭)\\x05(休)\\x05(自)\\x05(至)\\x0221\\x0222\\x0223\\x0224\\x0225\\x0226\" +\n\t\"\\x0227\\x0228\\x0229\\x0230\\x0231\\x0232\\x0233\\x0234\\x0235\\x06참고\\x06주의\\x0236\" +\n\t\"\\x0237\\x0238\\x0239\\x0240\\x0241\\x0242\\x0243\\x0244\\x0245\\x0246\\x0247\\x0248\" +\n\t\"\\x0249\\x0250\\x041月\\x042月\\x043月\\x044月\\x045月\\x046月\\x047月\\x048月\\x049月\\x0510\" +\n\t\"月\\x0511月\\x0512月\\x02hg\\x02ev\\x0cアパート\\x0cアルファ\\x0cアンペア\\x09アール\\x0cイニング\\x09\" +\n\t\"インチ\\x09ウォン\\x0fエスクード\\x0cエーカー\\x09オンス\\x09オーム\\x09カイリ\\x0cカラット\\x0cカロリー\\x09ガロ\" +\n\t\"ン\\x09ガンマ\\x06ギガ\\x09ギニー\\x0cキュリー\\x0cギルダー\\x06キロ\\x0fキログラム\\x12キロメートル\\x0fキロワッ\" +\n\t\"ト\\x09グラム\\x0fグラムトン\\x0fクルゼイロ\\x0cクローネ\\x09ケース\\x09コルナ\\x09コーポ\\x0cサイクル\\x0fサンチ\" +\n\t\"ーム\\x0cシリング\\x09センチ\\x09セント\\x09ダース\\x06デシ\\x06ドル\\x06トン\\x06ナノ\\x09ノット\\x09ハイツ\" +\n\t\"\\x0fパーセント\\x09パーツ\\x0cバーレル\\x0fピアストル\\x09ピクル\\x06ピコ\\x06ビル\\x0fファラッド\\x0cフィート\" +\n\t\"\\x0fブッシェル\\x09フラン\\x0fヘクタール\\x06ペソ\\x09ペニヒ\\x09ヘルツ\\x09ペンス\\x09ページ\\x09ベータ\\x0cポイ\" +\n\t\"ント\\x09ボルト\\x06ホン\\x09ポンド\\x09ホール\\x09ホーン\\x0cマイクロ\\x09マイル\\x09マッハ\\x09マルク\\x0fマ\" +\n\t\"ンション\\x0cミクロン\\x06ミリ\\x0fミリバール\\x06メガ\\x0cメガトン\\x0cメートル\\x09ヤード\\x09ヤール\\x09ユアン\" +\n\t\"\\x0cリットル\\x06リラ\\x09ルピー\\x0cルーブル\\x06レム\\x0fレントゲン\\x09ワット\\x040点\\x041点\\x042点\" +\n\t\"\\x043点\\x044点\\x045点\\x046点\\x047点\\x048点\\x049点\\x0510点\\x0511点\\x0512点\\x0513点\" +\n\t\"\\x0514点\\x0515点\\x0516点\\x0517点\\x0518点\\x0519点\\x0520点\\x0521点\\x0522点\\x0523点\" +\n\t\"\\x0524点\\x02da\\x02au\\x02ov\\x02pc\\x02dm\\x02iu\\x06平成\\x06昭和\\x06大正\\x06明治\\x0c株\" +\n\t\"式会社\\x02pa\\x02na\\x02ma\\x02ka\\x02kb\\x02mb\\x02gb\\x04kcal\\x02pf\\x02nf\\x02m\" +\n\t\"g\\x02kg\\x02hz\\x02ml\\x02dl\\x02kl\\x02fm\\x02nm\\x02mm\\x02cm\\x02km\\x02m2\\x02m\" +\n\t\"3\\x05m∕s\\x06m∕s2\\x07rad∕s\\x08rad∕s2\\x02ps\\x02ns\\x02ms\\x02pv\\x02nv\\x02mv\" +\n\t\"\\x02kv\\x02pw\\x02nw\\x02mw\\x02kw\\x02bq\\x02cc\\x02cd\\x06c∕kg\\x02db\\x02gy\\x02\" +\n\t\"ha\\x02hp\\x02in\\x02kk\\x02kt\\x02lm\\x02ln\\x02lx\\x02ph\\x02pr\\x02sr\\x02sv\\x02\" +\n\t\"wb\\x05v∕m\\x05a∕m\\x041日\\x042日\\x043日\\x044日\\x045日\\x046日\\x047日\\x048日\\x049日\" +\n\t\"\\x0510日\\x0511日\\x0512日\\x0513日\\x0514日\\x0515日\\x0516日\\x0517日\\x0518日\\x0519日\" +\n\t\"\\x0520日\\x0521日\\x0522日\\x0523日\\x0524日\\x0525日\\x0526日\\x0527日\\x0528日\\x0529日\" +\n\t\"\\x0530日\\x0531日\\x02ь\\x02ɦ\\x02ɬ\\x02ʞ\\x02ʇ\\x02œ\\x04𤋮\\x04𢡊\\x04𢡄\\x04𣏕\\x04𥉉\" +\n\t\"\\x04𥳐\\x04𧻓\\x02ff\\x02fi\\x02fl\\x02st\\x04մն\\x04մե\\x04մի\\x04վն\\x04մխ\\x04יִ\" +\n\t\"\\x04ײַ\\x02ע\\x02ה\\x02כ\\x02ל\\x02ם\\x02ר\\x02ת\\x04שׁ\\x04שׂ\\x06שּׁ\\x06שּׂ\\x04א\" +\n\t\"ַ\\x04אָ\\x04אּ\\x04בּ\\x04גּ\\x04דּ\\x04הּ\\x04וּ\\x04זּ\\x04טּ\\x04יּ\\x04ךּ\\x04\" +\n\t\"כּ\\x04לּ\\x04מּ\\x04נּ\\x04סּ\\x04ףּ\\x04פּ\\x04צּ\\x04קּ\\x04רּ\\x04שּ\\x04תּ\" +\n\t\"\\x04וֹ\\x04בֿ\\x04כֿ\\x04פֿ\\x04אל\\x02ٱ\\x02ٻ\\x02پ\\x02ڀ\\x02ٺ\\x02ٿ\\x02ٹ\\x02ڤ\" +\n\t\"\\x02ڦ\\x02ڄ\\x02ڃ\\x02چ\\x02ڇ\\x02ڍ\\x02ڌ\\x02ڎ\\x02ڈ\\x02ژ\\x02ڑ\\x02ک\\x02گ\\x02ڳ\" +\n\t\"\\x02ڱ\\x02ں\\x02ڻ\\x02ۀ\\x02ہ\\x02ھ\\x02ے\\x02ۓ\\x02ڭ\\x02ۇ\\x02ۆ\\x02ۈ\\x02ۋ\\x02ۅ\" +\n\t\"\\x02ۉ\\x02ې\\x02ى\\x04ئا\\x04ئە\\x04ئو\\x04ئۇ\\x04ئۆ\\x04ئۈ\\x04ئې\\x04ئى\\x02ی\\x04\" +\n\t\"ئج\\x04ئح\\x04ئم\\x04ئي\\x04بج\\x04بح\\x04بخ\\x04بم\\x04بى\\x04بي\\x04تج\\x04تح\" +\n\t\"\\x04تخ\\x04تم\\x04تى\\x04تي\\x04ثج\\x04ثم\\x04ثى\\x04ثي\\x04جح\\x04جم\\x04حج\\x04حم\" +\n\t\"\\x04خج\\x04خح\\x04خم\\x04سج\\x04سح\\x04سخ\\x04سم\\x04صح\\x04صم\\x04ضج\\x04ضح\\x04ضخ\" +\n\t\"\\x04ضم\\x04طح\\x04طم\\x04ظم\\x04عج\\x04عم\\x04غج\\x04غم\\x04فج\\x04فح\\x04فخ\\x04فم\" +\n\t\"\\x04فى\\x04في\\x04قح\\x04قم\\x04قى\\x04قي\\x04كا\\x04كج\\x04كح\\x04كخ\\x04كل\\x04كم\" +\n\t\"\\x04كى\\x04كي\\x04لج\\x04لح\\x04لخ\\x04لم\\x04لى\\x04لي\\x04مج\\x04مح\\x04مخ\\x04مم\" +\n\t\"\\x04مى\\x04مي\\x04نج\\x04نح\\x04نخ\\x04نم\\x04نى\\x04ني\\x04هج\\x04هم\\x04هى\\x04هي\" +\n\t\"\\x04يج\\x04يح\\x04يخ\\x04يم\\x04يى\\x04يي\\x04ذٰ\\x04رٰ\\x04ىٰ\\x05 ٌّ\\x05 ٍّ\\x05\" +\n\t\" َّ\\x05 ُّ\\x05 ِّ\\x05 ّٰ\\x04ئر\\x04ئز\\x04ئن\\x04بر\\x04بز\\x04بن\\x04تر\\x04تز\" +\n\t\"\\x04تن\\x04ثر\\x04ثز\\x04ثن\\x04ما\\x04نر\\x04نز\\x04نن\\x04ير\\x04يز\\x04ين\\x04ئخ\" +\n\t\"\\x04ئه\\x04به\\x04ته\\x04صخ\\x04له\\x04نه\\x04هٰ\\x04يه\\x04ثه\\x04سه\\x04شم\\x04شه\" +\n\t\"\\x06ـَّ\\x06ـُّ\\x06ـِّ\\x04طى\\x04طي\\x04عى\\x04عي\\x04غى\\x04غي\\x04سى\\x04سي\" +\n\t\"\\x04شى\\x04شي\\x04حى\\x04حي\\x04جى\\x04جي\\x04خى\\x04خي\\x04صى\\x04صي\\x04ضى\\x04ضي\" +\n\t\"\\x04شج\\x04شح\\x04شخ\\x04شر\\x04سر\\x04صر\\x04ضر\\x04اً\\x06تجم\\x06تحج\\x06تحم\" +\n\t\"\\x06تخم\\x06تمج\\x06تمح\\x06تمخ\\x06جمح\\x06حمي\\x06حمى\\x06سحج\\x06سجح\\x06سجى\" +\n\t\"\\x06سمح\\x06سمج\\x06سمم\\x06صحح\\x06صمم\\x06شحم\\x06شجي\\x06شمخ\\x06شمم\\x06ضحى\" +\n\t\"\\x06ضخم\\x06طمح\\x06طمم\\x06طمي\\x06عجم\\x06عمم\\x06عمى\\x06غمم\\x06غمي\\x06غمى\" +\n\t\"\\x06فخم\\x06قمح\\x06قمم\\x06لحم\\x06لحي\\x06لحى\\x06لجج\\x06لخم\\x06لمح\\x06محج\" +\n\t\"\\x06محم\\x06محي\\x06مجح\\x06مجم\\x06مخج\\x06مخم\\x06مجخ\\x06همج\\x06همم\\x06نحم\" +\n\t\"\\x06نحى\\x06نجم\\x06نجى\\x06نمي\\x06نمى\\x06يمم\\x06بخي\\x06تجي\\x06تجى\\x06تخي\" +\n\t\"\\x06تخى\\x06تمي\\x06تمى\\x06جمي\\x06جحى\\x06جمى\\x06سخى\\x06صحي\\x06شحي\\x06ضحي\" +\n\t\"\\x06لجي\\x06لمي\\x06يحي\\x06يجي\\x06يمي\\x06ممي\\x06قمي\\x06نحي\\x06عمي\\x06كمي\" +\n\t\"\\x06نجح\\x06مخي\\x06لجم\\x06كمم\\x06جحي\\x06حجي\\x06مجي\\x06فمي\\x06بحي\\x06سخي\" +\n\t\"\\x06نجي\\x06صلے\\x06قلے\\x08الله\\x08اكبر\\x08محمد\\x08صلعم\\x08رسول\\x08عليه\" +\n\t\"\\x08وسلم\\x06صلى!صلى الله عليه وسلم\\x0fجل جلاله\\x08ریال\\x01,\\x01:\\x01!\" +\n\t\"\\x01?\\x01_\\x01{\\x01}\\x01[\\x01]\\x01#\\x01&\\x01*\\x01-\\x01<\\x01>\\x01\\\\\\x01$\" +\n\t\"\\x01%\\x01@\\x04ـً\\x04ـَ\\x04ـُ\\x04ـِ\\x04ـّ\\x04ـْ\\x02ء\\x02آ\\x02أ\\x02ؤ\\x02إ\" +\n\t\"\\x02ئ\\x02ا\\x02ب\\x02ة\\x02ت\\x02ث\\x02ج\\x02ح\\x02خ\\x02د\\x02ذ\\x02ر\\x02ز\\x02س\" +\n\t\"\\x02ش\\x02ص\\x02ض\\x02ط\\x02ظ\\x02ع\\x02غ\\x02ف\\x02ق\\x02ك\\x02ل\\x02م\\x02ن\\x02ه\" +\n\t\"\\x02و\\x02ي\\x04لآ\\x04لأ\\x04لإ\\x04لا\\x01\\x22\\x01'\\x01/\\x01^\\x01|\\x01~\\x02¢\" +\n\t\"\\x02£\\x02¬\\x02¦\\x02¥\\x08𝅗𝅥\\x08𝅘𝅥\\x0c𝅘𝅥𝅮\\x0c𝅘𝅥𝅯\\x0c𝅘𝅥𝅰\\x0c𝅘𝅥𝅱\\x0c𝅘𝅥𝅲\\x08𝆹\" +\n\t\"𝅥\\x08𝆺𝅥\\x0c𝆹𝅥𝅮\\x0c𝆺𝅥𝅮\\x0c𝆹𝅥𝅯\\x0c𝆺𝅥𝅯\\x02ı\\x02ȷ\\x02α\\x02ε\\x02ζ\\x02η\\x02\" +\n\t\"κ\\x02λ\\x02μ\\x02ν\\x02ξ\\x02ο\\x02σ\\x02τ\\x02υ\\x02ψ\\x03∇\\x03∂\\x02ϝ\\x02ٮ\\x02ڡ\" +\n\t\"\\x02ٯ\\x020,\\x021,\\x022,\\x023,\\x024,\\x025,\\x026,\\x027,\\x028,\\x029,\\x03(a)\" +\n\t\"\\x03(b)\\x03(c)\\x03(d)\\x03(e)\\x03(f)\\x03(g)\\x03(h)\\x03(i)\\x03(j)\\x03(k)\" +\n\t\"\\x03(l)\\x03(m)\\x03(n)\\x03(o)\\x03(p)\\x03(q)\\x03(r)\\x03(s)\\x03(t)\\x03(u)\" +\n\t\"\\x03(v)\\x03(w)\\x03(x)\\x03(y)\\x03(z)\\x07〔s〕\\x02wz\\x02hv\\x02sd\\x03ppv\\x02w\" +\n\t\"c\\x02mc\\x02md\\x02dj\\x06ほか\\x06ココ\\x03サ\\x03手\\x03字\\x03双\\x03デ\\x03二\\x03多\\x03解\" +\n\t\"\\x03天\\x03交\\x03映\\x03無\\x03料\\x03前\\x03後\\x03再\\x03新\\x03初\\x03終\\x03生\\x03販\\x03声\" +\n\t\"\\x03吹\\x03演\\x03投\\x03捕\\x03一\\x03三\\x03遊\\x03左\\x03中\\x03右\\x03指\\x03走\\x03打\\x03禁\" +\n\t\"\\x03空\\x03合\\x03満\\x03有\\x03月\\x03申\\x03割\\x03営\\x03配\\x09〔本〕\\x09〔三〕\\x09〔二〕\\x09〔安\" +\n\t\"〕\\x09〔点〕\\x09〔打〕\\x09〔盗〕\\x09〔勝〕\\x09〔敗〕\\x03得\\x03可\\x03丽\\x03丸\\x03乁\\x03你\\x03\" +\n\t\"侮\\x03侻\\x03倂\\x03偺\\x03備\\x03僧\\x03像\\x03㒞\\x03免\\x03兔\\x03兤\\x03具\\x03㒹\\x03內\\x03\" +\n\t\"冗\\x03冤\\x03仌\\x03冬\\x03况\\x03凵\\x03刃\\x03㓟\\x03刻\\x03剆\\x03剷\\x03㔕\\x03勇\\x03勉\\x03\" +\n\t\"勤\\x03勺\\x03包\\x03匆\\x03北\\x03卉\\x03卑\\x03博\\x03即\\x03卽\\x03卿\\x03灰\\x03及\\x03叟\\x03\" +\n\t\"叫\\x03叱\\x03吆\\x03咞\\x03吸\\x03呈\\x03周\\x03咢\\x03哶\\x03唐\\x03啓\\x03啣\\x03善\\x03喙\\x03\" +\n\t\"喫\\x03喳\\x03嗂\\x03圖\\x03嘆\\x03圗\\x03噑\\x03噴\\x03切\\x03壮\\x03城\\x03埴\\x03堍\\x03型\\x03\" +\n\t\"堲\\x03報\\x03墬\\x03売\\x03壷\\x03夆\\x03夢\\x03奢\\x03姬\\x03娛\\x03娧\\x03姘\\x03婦\\x03㛮\\x03\" +\n\t\"嬈\\x03嬾\\x03寃\\x03寘\\x03寧\\x03寳\\x03寿\\x03将\\x03尢\\x03㞁\\x03屠\\x03屮\\x03峀\\x03岍\\x03\" +\n\t\"嵃\\x03嵮\\x03嵫\\x03嵼\\x03巡\\x03巢\\x03㠯\\x03巽\\x03帨\\x03帽\\x03幩\\x03㡢\\x03㡼\\x03庰\\x03\" +\n\t\"庳\\x03庶\\x03廊\\x03廾\\x03舁\\x03弢\\x03㣇\\x03形\\x03彫\\x03㣣\\x03徚\\x03忍\\x03志\\x03忹\\x03\" +\n\t\"悁\\x03㤺\\x03㤜\\x03悔\\x03惇\\x03慈\\x03慌\\x03慎\\x03慺\\x03憎\\x03憲\\x03憤\\x03憯\\x03懞\\x03\" +\n\t\"懲\\x03懶\\x03成\\x03戛\\x03扝\\x03抱\\x03拔\\x03捐\\x03挽\\x03拼\\x03捨\\x03掃\\x03揤\\x03搢\\x03\" +\n\t\"揅\\x03掩\\x03㨮\\x03摩\\x03摾\\x03撝\\x03摷\\x03㩬\\x03敏\\x03敬\\x03旣\\x03書\\x03晉\\x03㬙\\x03\" +\n\t\"暑\\x03㬈\\x03㫤\\x03冒\\x03冕\\x03最\\x03暜\\x03肭\\x03䏙\\x03朗\\x03望\\x03朡\\x03杞\\x03杓\\x03\" +\n\t\"㭉\\x03柺\\x03枅\\x03桒\\x03梅\\x03梎\\x03栟\\x03椔\\x03㮝\\x03楂\\x03榣\\x03槪\\x03檨\\x03櫛\\x03\" +\n\t\"㰘\\x03次\\x03歔\\x03㱎\\x03歲\\x03殟\\x03殺\\x03殻\\x03汎\\x03沿\\x03泍\\x03汧\\x03洖\\x03派\\x03\" +\n\t\"海\\x03流\\x03浩\\x03浸\\x03涅\\x03洴\\x03港\\x03湮\\x03㴳\\x03滋\\x03滇\\x03淹\\x03潮\\x03濆\\x03\" +\n\t\"瀹\\x03瀞\\x03瀛\\x03㶖\\x03灊\\x03災\\x03灷\\x03炭\\x03煅\\x03熜\\x03爨\\x03爵\\x03牐\\x03犀\\x03\" +\n\t\"犕\\x03獺\\x03王\\x03㺬\\x03玥\\x03㺸\\x03瑇\\x03瑜\\x03瑱\\x03璅\\x03瓊\\x03㼛\\x03甤\\x03甾\\x03\" +\n\t\"異\\x03瘐\\x03㿼\\x03䀈\\x03直\\x03眞\\x03真\\x03睊\\x03䀹\\x03瞋\\x03䁆\\x03䂖\\x03硎\\x03碌\\x03\" +\n\t\"磌\\x03䃣\\x03祖\\x03福\\x03秫\\x03䄯\\x03穀\\x03穊\\x03穏\\x03䈂\\x03篆\\x03築\\x03䈧\\x03糒\\x03\" +\n\t\"䊠\\x03糨\\x03糣\\x03紀\\x03絣\\x03䌁\\x03緇\\x03縂\\x03繅\\x03䌴\\x03䍙\\x03罺\\x03羕\\x03翺\\x03\" +\n\t\"者\\x03聠\\x03聰\\x03䏕\\x03育\\x03脃\\x03䐋\\x03脾\\x03媵\\x03舄\\x03辞\\x03䑫\\x03芑\\x03芋\\x03\" +\n\t\"芝\\x03劳\\x03花\\x03芳\\x03芽\\x03苦\\x03若\\x03茝\\x03荣\\x03莭\\x03茣\\x03莽\\x03菧\\x03著\\x03\" +\n\t\"荓\\x03菊\\x03菌\\x03菜\\x03䔫\\x03蓱\\x03蓳\\x03蔖\\x03蕤\\x03䕝\\x03䕡\\x03䕫\\x03虐\\x03虜\\x03\" +\n\t\"虧\\x03虩\\x03蚩\\x03蚈\\x03蜎\\x03蛢\\x03蝹\\x03蜨\\x03蝫\\x03螆\\x03蟡\\x03蠁\\x03䗹\\x03衠\\x03\" +\n\t\"衣\\x03裗\\x03裞\\x03䘵\\x03裺\\x03㒻\\x03䚾\\x03䛇\\x03誠\\x03諭\\x03變\\x03豕\\x03貫\\x03賁\\x03\" +\n\t\"贛\\x03起\\x03跋\\x03趼\\x03跰\\x03軔\\x03輸\\x03邔\\x03郱\\x03鄑\\x03鄛\\x03鈸\\x03鋗\\x03鋘\\x03\" +\n\t\"鉼\\x03鏹\\x03鐕\\x03開\\x03䦕\\x03閷\\x03䧦\\x03雃\\x03嶲\\x03霣\\x03䩮\\x03䩶\\x03韠\\x03䪲\\x03\" +\n\t\"頋\\x03頩\\x03飢\\x03䬳\\x03餩\\x03馧\\x03駂\\x03駾\\x03䯎\\x03鬒\\x03鱀\\x03鳽\\x03䳎\\x03䳭\\x03\" +\n\t\"鵧\\x03䳸\\x03麻\\x03䵖\\x03黹\\x03黾\\x03鼅\\x03鼏\\x03鼖\\x03鼻\"\n\nvar xorData string = \"\" + // Size: 4855 bytes\n\t\"\\x02\\x0c\\x09\\x02\\xb0\\xec\\x02\\xad\\xd8\\x02\\xad\\xd9\\x02\\x06\\x07\\x02\\x0f\\x12\" +\n\t\"\\x02\\x0f\\x1f\\x02\\x0f\\x1d\\x02\\x01\\x13\\x02\\x0f\\x16\\x02\\x0f\\x0b\\x02\\x0f3\" +\n\t\"\\x02\\x0f7\\x02\\x0f?\\x02\\x0f/\\x02\\x0f*\\x02\\x0c&\\x02\\x0c*\\x02\\x0c;\\x02\\x0c9\" +\n\t\"\\x02\\x0c%\\x02\\xab\\xed\\x02\\xab\\xe2\\x02\\xab\\xe3\\x02\\xa9\\xe0\\x02\\xa9\\xe1\" +\n\t\"\\x02\\xa9\\xe6\\x02\\xa3\\xcb\\x02\\xa3\\xc8\\x02\\xa3\\xc9\\x02\\x01#\\x02\\x01\\x08\" +\n\t\"\\x02\\x0e>\\x02\\x0e'\\x02\\x0f\\x03\\x02\\x03\\x0d\\x02\\x03\\x09\\x02\\x03\\x17\\x02\" +\n\t\"\\x03\\x0e\\x02\\x02\\x03\\x02\\x011\\x02\\x01\\x00\\x02\\x01\\x10\\x02\\x03<\\x02\\x07\" +\n\t\"\\x0d\\x02\\x02\\x0c\\x02\\x0c0\\x02\\x01\\x03\\x02\\x01\\x01\\x02\\x01 \\x02\\x01\\x22\" +\n\t\"\\x02\\x01)\\x02\\x01\\x0a\\x02\\x01\\x0c\\x02\\x02\\x06\\x02\\x02\\x02\\x02\\x03\\x10\" +\n\t\"\\x03\\x037 \\x03\\x0b+\\x03\\x02\\x01\\x04\\x02\\x01\\x02\\x02\\x019\\x02\\x03\\x1c\\x02\" +\n\t\"\\x02$\\x03\\x80p$\\x02\\x03:\\x02\\x03\\x0a\\x03\\xc1r.\\x03\\xc1r,\\x03\\xc1r\\x02\" +\n\t\"\\x02\\x02:\\x02\\x02>\\x02\\x02,\\x02\\x02\\x10\\x02\\x02\\x00\\x03\\xc1s<\\x03\\xc1s*\" +\n\t\"\\x03\\xc2L$\\x03\\xc2L;\\x02\\x09)\\x02\\x0a\\x19\\x03\\x83\\xab\\xe3\\x03\\x83\\xab\" +\n\t\"\\xf2\\x03 4\\xe0\\x03\\x81\\xab\\xea\\x03\\x81\\xab\\xf3\\x03 4\\xef\\x03\\x96\\xe1\\xcd\" +\n\t\"\\x03\\x84\\xe5\\xc3\\x02\\x0d\\x11\\x03\\x8b\\xec\\xcb\\x03\\x94\\xec\\xcf\\x03\\x9a\\xec\" +\n\t\"\\xc2\\x03\\x8b\\xec\\xdb\\x03\\x94\\xec\\xdf\\x03\\x9a\\xec\\xd2\\x03\\x01\\x0c!\\x03\" +\n\t\"\\x01\\x0c#\\x03ʠ\\x9d\\x03ʣ\\x9c\\x03ʢ\\x9f\\x03ʥ\\x9e\\x03ʤ\\x91\\x03ʧ\\x90\\x03ʦ\\x93\" +\n\t\"\\x03ʩ\\x92\\x03ʨ\\x95\\x03\\xca\\xf3\\xb5\\x03\\xca\\xf0\\xb4\\x03\\xca\\xf1\\xb7\\x03\" +\n\t\"\\xca\\xf6\\xb6\\x03\\xca\\xf7\\x89\\x03\\xca\\xf4\\x88\\x03\\xca\\xf5\\x8b\\x03\\xca\\xfa\" +\n\t\"\\x8a\\x03\\xca\\xfb\\x8d\\x03\\xca\\xf8\\x8c\\x03\\xca\\xf9\\x8f\\x03\\xca\\xfe\\x8e\\x03\" +\n\t\"\\xca\\xff\\x81\\x03\\xca\\xfc\\x80\\x03\\xca\\xfd\\x83\\x03\\xca\\xe2\\x82\\x03\\xca\\xe3\" +\n\t\"\\x85\\x03\\xca\\xe0\\x84\\x03\\xca\\xe1\\x87\\x03\\xca\\xe6\\x86\\x03\\xca\\xe7\\x99\\x03\" +\n\t\"\\xca\\xe4\\x98\\x03\\xca\\xe5\\x9b\\x03\\xca\\xea\\x9a\\x03\\xca\\xeb\\x9d\\x03\\xca\\xe8\" +\n\t\"\\x9c\\x03ؓ\\x89\\x03ߔ\\x8b\\x02\\x010\\x03\\x03\\x04\\x1e\\x03\\x04\\x15\\x12\\x03\\x0b\" +\n\t\"\\x05,\\x03\\x06\\x04\\x00\\x03\\x06\\x04)\\x03\\x06\\x044\\x03\\x06\\x04<\\x03\\x06\\x05\" +\n\t\"\\x1d\\x03\\x06\\x06\\x00\\x03\\x06\\x06\\x0a\\x03\\x06\\x06'\\x03\\x06\\x062\\x03\\x0786\" +\n\t\"\\x03\\x079/\\x03\\x079 \\x03\\x07:\\x0e\\x03\\x07:\\x1b\\x03\\x07:%\\x03\\x07;/\\x03\" +\n\t\"\\x07;%\\x03\\x074\\x11\\x03\\x076\\x09\\x03\\x077*\\x03\\x070\\x01\\x03\\x070\\x0f\\x03\" +\n\t\"\\x070.\\x03\\x071\\x16\\x03\\x071\\x04\\x03\\x0710\\x03\\x072\\x18\\x03\\x072-\\x03\" +\n\t\"\\x073\\x14\\x03\\x073>\\x03\\x07'\\x09\\x03\\x07 \\x00\\x03\\x07\\x1f\\x0b\\x03\\x07\" +\n\t\"\\x18#\\x03\\x07\\x18(\\x03\\x07\\x186\\x03\\x07\\x18\\x03\\x03\\x07\\x19\\x16\\x03\\x07\" +\n\t\"\\x116\\x03\\x07\\x12'\\x03\\x07\\x13\\x10\\x03\\x07\\x0c&\\x03\\x07\\x0c\\x08\\x03\\x07\" +\n\t\"\\x0c\\x13\\x03\\x07\\x0d\\x02\\x03\\x07\\x0d\\x1c\\x03\\x07\\x0b5\\x03\\x07\\x0b\\x0a\" +\n\t\"\\x03\\x07\\x0b\\x01\\x03\\x07\\x0b\\x0f\\x03\\x07\\x05\\x00\\x03\\x07\\x05\\x09\\x03\\x07\" +\n\t\"\\x05\\x0b\\x03\\x07\\x07\\x01\\x03\\x07\\x07\\x08\\x03\\x07\\x00<\\x03\\x07\\x00+\\x03\" +\n\t\"\\x07\\x01)\\x03\\x07\\x01\\x1b\\x03\\x07\\x01\\x08\\x03\\x07\\x03?\\x03\\x0445\\x03\\x04\" +\n\t\"4\\x08\\x03\\x0454\\x03\\x04)/\\x03\\x04)5\\x03\\x04+\\x05\\x03\\x04+\\x14\\x03\\x04+ \" +\n\t\"\\x03\\x04+<\\x03\\x04*&\\x03\\x04*\\x22\\x03\\x04&8\\x03\\x04!\\x01\\x03\\x04!\\x22\" +\n\t\"\\x03\\x04\\x11+\\x03\\x04\\x10.\\x03\\x04\\x104\\x03\\x04\\x13=\\x03\\x04\\x12\\x04\\x03\" +\n\t\"\\x04\\x12\\x0a\\x03\\x04\\x0d\\x1d\\x03\\x04\\x0d\\x07\\x03\\x04\\x0d \\x03\\x05<>\\x03\" +\n\t\"\\x055<\\x03\\x055!\\x03\\x055#\\x03\\x055&\\x03\\x054\\x1d\\x03\\x054\\x02\\x03\\x054\" +\n\t\"\\x07\\x03\\x0571\\x03\\x053\\x1a\\x03\\x053\\x16\\x03\\x05.<\\x03\\x05.\\x07\\x03\\x05)\" +\n\t\":\\x03\\x05)<\\x03\\x05)\\x0c\\x03\\x05)\\x15\\x03\\x05+-\\x03\\x05+5\\x03\\x05$\\x1e\" +\n\t\"\\x03\\x05$\\x14\\x03\\x05'\\x04\\x03\\x05'\\x14\\x03\\x05&\\x02\\x03\\x05\\x226\\x03\" +\n\t\"\\x05\\x22\\x0c\\x03\\x05\\x22\\x1c\\x03\\x05\\x19\\x0a\\x03\\x05\\x1b\\x09\\x03\\x05\\x1b\" +\n\t\"\\x0c\\x03\\x05\\x14\\x07\\x03\\x05\\x16?\\x03\\x05\\x16\\x0c\\x03\\x05\\x0c\\x05\\x03\" +\n\t\"\\x05\\x0e\\x0f\\x03\\x05\\x01\\x0e\\x03\\x05\\x00(\\x03\\x05\\x030\\x03\\x05\\x03\\x06\" +\n\t\"\\x03\\x0a==\\x03\\x0a=1\\x03\\x0a=,\\x03\\x0a=\\x0c\\x03\\x0a??\\x03\\x0a<\\x08\\x03\" +\n\t\"\\x0a9!\\x03\\x0a9)\\x03\\x0a97\\x03\\x0a99\\x03\\x0a6\\x0a\\x03\\x0a6\\x1c\\x03\\x0a6\" +\n\t\"\\x17\\x03\\x0a7'\\x03\\x0a78\\x03\\x0a73\\x03\\x0a'\\x01\\x03\\x0a'&\\x03\\x0a\\x1f\" +\n\t\"\\x0e\\x03\\x0a\\x1f\\x03\\x03\\x0a\\x1f3\\x03\\x0a\\x1b/\\x03\\x0a\\x18\\x19\\x03\\x0a\" +\n\t\"\\x19\\x01\\x03\\x0a\\x16\\x14\\x03\\x0a\\x0e\\x22\\x03\\x0a\\x0f\\x10\\x03\\x0a\\x0f\\x02\" +\n\t\"\\x03\\x0a\\x0f \\x03\\x0a\\x0c\\x04\\x03\\x0a\\x0b>\\x03\\x0a\\x0b+\\x03\\x0a\\x08/\\x03\" +\n\t\"\\x0a\\x046\\x03\\x0a\\x05\\x14\\x03\\x0a\\x00\\x04\\x03\\x0a\\x00\\x10\\x03\\x0a\\x00\" +\n\t\"\\x14\\x03\\x0b<3\\x03\\x0b;*\\x03\\x0b9\\x22\\x03\\x0b9)\\x03\\x0b97\\x03\\x0b+\\x10\" +\n\t\"\\x03\\x0b((\\x03\\x0b&5\\x03\\x0b$\\x1c\\x03\\x0b$\\x12\\x03\\x0b%\\x04\\x03\\x0b#<\" +\n\t\"\\x03\\x0b#0\\x03\\x0b#\\x0d\\x03\\x0b#\\x19\\x03\\x0b!:\\x03\\x0b!\\x1f\\x03\\x0b!\\x00\" +\n\t\"\\x03\\x0b\\x1e5\\x03\\x0b\\x1c\\x1d\\x03\\x0b\\x1d-\\x03\\x0b\\x1d(\\x03\\x0b\\x18.\\x03\" +\n\t\"\\x0b\\x18 \\x03\\x0b\\x18\\x16\\x03\\x0b\\x14\\x13\\x03\\x0b\\x15$\\x03\\x0b\\x15\\x22\" +\n\t\"\\x03\\x0b\\x12\\x1b\\x03\\x0b\\x12\\x10\\x03\\x0b\\x132\\x03\\x0b\\x13=\\x03\\x0b\\x12\" +\n\t\"\\x18\\x03\\x0b\\x0c&\\x03\\x0b\\x061\\x03\\x0b\\x06:\\x03\\x0b\\x05#\\x03\\x0b\\x05<\" +\n\t\"\\x03\\x0b\\x04\\x0b\\x03\\x0b\\x04\\x04\\x03\\x0b\\x04\\x1b\\x03\\x0b\\x042\\x03\\x0b\" +\n\t\"\\x041\\x03\\x0b\\x03\\x03\\x03\\x0b\\x03\\x1d\\x03\\x0b\\x03/\\x03\\x0b\\x03+\\x03\\x0b\" +\n\t\"\\x02\\x1b\\x03\\x0b\\x02\\x00\\x03\\x0b\\x01\\x1e\\x03\\x0b\\x01\\x08\\x03\\x0b\\x015\" +\n\t\"\\x03\\x06\\x0d9\\x03\\x06\\x0d=\\x03\\x06\\x0d?\\x03\\x02\\x001\\x03\\x02\\x003\\x03\" +\n\t\"\\x02\\x02\\x19\\x03\\x02\\x006\\x03\\x02\\x02\\x1b\\x03\\x02\\x004\\x03\\x02\\x00<\\x03\" +\n\t\"\\x02\\x02\\x0a\\x03\\x02\\x02\\x0e\\x03\\x02\\x01\\x1a\\x03\\x02\\x01\\x07\\x03\\x02\\x01\" +\n\t\"\\x05\\x03\\x02\\x01\\x0b\\x03\\x02\\x01%\\x03\\x02\\x01\\x0c\\x03\\x02\\x01\\x04\\x03\" +\n\t\"\\x02\\x01\\x1c\\x03\\x02\\x00.\\x03\\x02\\x002\\x03\\x02\\x00>\\x03\\x02\\x00\\x12\\x03\" +\n\t\"\\x02\\x00\\x16\\x03\\x02\\x011\\x03\\x02\\x013\\x03\\x02\\x02 \\x03\\x02\\x02%\\x03\\x02\" +\n\t\"\\x02$\\x03\\x02\\x028\\x03\\x02\\x02;\\x03\\x02\\x024\\x03\\x02\\x012\\x03\\x02\\x022\" +\n\t\"\\x03\\x02\\x02/\\x03\\x02\\x01,\\x03\\x02\\x01\\x13\\x03\\x02\\x01\\x16\\x03\\x02\\x01\" +\n\t\"\\x11\\x03\\x02\\x01\\x1e\\x03\\x02\\x01\\x15\\x03\\x02\\x01\\x17\\x03\\x02\\x01\\x0f\\x03\" +\n\t\"\\x02\\x01\\x08\\x03\\x02\\x00?\\x03\\x02\\x03\\x07\\x03\\x02\\x03\\x0d\\x03\\x02\\x03\" +\n\t\"\\x13\\x03\\x02\\x03\\x1d\\x03\\x02\\x03\\x1f\\x03\\x02\\x00\\x03\\x03\\x02\\x00\\x0d\\x03\" +\n\t\"\\x02\\x00\\x01\\x03\\x02\\x00\\x1b\\x03\\x02\\x00\\x19\\x03\\x02\\x00\\x18\\x03\\x02\\x00\" +\n\t\"\\x13\\x03\\x02\\x00/\\x03\\x07>\\x12\\x03\\x07<\\x1f\\x03\\x07>\\x1d\\x03\\x06\\x1d\\x0e\" +\n\t\"\\x03\\x07>\\x1c\\x03\\x07>:\\x03\\x07>\\x13\\x03\\x04\\x12+\\x03\\x07?\\x03\\x03\\x07>\" +\n\t\"\\x02\\x03\\x06\\x224\\x03\\x06\\x1a.\\x03\\x07<%\\x03\\x06\\x1c\\x0b\\x03\\x0609\\x03\" +\n\t\"\\x05\\x1f\\x01\\x03\\x04'\\x08\\x03\\x93\\xfd\\xf5\\x03\\x02\\x0d \\x03\\x02\\x0d#\\x03\" +\n\t\"\\x02\\x0d!\\x03\\x02\\x0d&\\x03\\x02\\x0d\\x22\\x03\\x02\\x0d/\\x03\\x02\\x0d,\\x03\\x02\" +\n\t\"\\x0d$\\x03\\x02\\x0d'\\x03\\x02\\x0d%\\x03\\x02\\x0d;\\x03\\x02\\x0d=\\x03\\x02\\x0d?\" +\n\t\"\\x03\\x099.\\x03\\x08\\x0b7\\x03\\x08\\x02\\x14\\x03\\x08\\x14\\x0d\\x03\\x08.:\\x03\" +\n\t\"\\x089'\\x03\\x0f\\x0b\\x18\\x03\\x0f\\x1c1\\x03\\x0f\\x17&\\x03\\x0f9\\x1f\\x03\\x0f0\" +\n\t\"\\x0c\\x03\\x0e\\x0a9\\x03\\x0e\\x056\\x03\\x0e\\x1c#\\x03\\x0f\\x13\\x0e\\x03\\x072\\x00\" +\n\t\"\\x03\\x070\\x0d\\x03\\x072\\x0b\\x03\\x06\\x11\\x18\\x03\\x070\\x10\\x03\\x06\\x0f(\\x03\" +\n\t\"\\x072\\x05\\x03\\x06\\x0f,\\x03\\x073\\x15\\x03\\x06\\x07\\x08\\x03\\x05\\x16\\x02\\x03\" +\n\t\"\\x04\\x0b \\x03\\x05:8\\x03\\x05\\x16%\\x03\\x0a\\x0d\\x1f\\x03\\x06\\x16\\x10\\x03\\x05\" +\n\t\"\\x1d5\\x03\\x05*;\\x03\\x05\\x16\\x1b\\x03\\x04.-\\x03\\x06\\x1a\\x19\\x03\\x04\\x03,\" +\n\t\"\\x03\\x0b87\\x03\\x04/\\x0a\\x03\\x06\\x00,\\x03\\x04-\\x01\\x03\\x04\\x1e-\\x03\\x06/(\" +\n\t\"\\x03\\x0a\\x0b5\\x03\\x06\\x0e7\\x03\\x06\\x07.\\x03\\x0597\\x03\\x0a*%\\x03\\x0760\" +\n\t\"\\x03\\x06\\x0c;\\x03\\x05'\\x00\\x03\\x072.\\x03\\x072\\x08\\x03\\x06=\\x01\\x03\\x06\" +\n\t\"\\x05\\x1b\\x03\\x06\\x06\\x12\\x03\\x06$=\\x03\\x06'\\x0d\\x03\\x04\\x11\\x0f\\x03\\x076\" +\n\t\",\\x03\\x06\\x07;\\x03\\x06.,\\x03\\x86\\xf9\\xea\\x03\\x8f\\xff\\xeb\\x02\\x092\\x02\" +\n\t\"\\x095\\x02\\x094\\x02\\x09;\\x02\\x09>\\x02\\x098\\x02\\x09*\\x02\\x09/\\x02\\x09,\\x02\" +\n\t\"\\x09%\\x02\\x09&\\x02\\x09#\\x02\\x09 \\x02\\x08!\\x02\\x08%\\x02\\x08$\\x02\\x08+\\x02\" +\n\t\"\\x08.\\x02\\x08*\\x02\\x08&\\x02\\x088\\x02\\x08>\\x02\\x084\\x02\\x086\\x02\\x080\\x02\" +\n\t\"\\x08\\x10\\x02\\x08\\x17\\x02\\x08\\x12\\x02\\x08\\x1d\\x02\\x08\\x1f\\x02\\x08\\x13\\x02\" +\n\t\"\\x08\\x15\\x02\\x08\\x14\\x02\\x08\\x0c\\x03\\x8b\\xfd\\xd0\\x03\\x81\\xec\\xc6\\x03\\x87\" +\n\t\"\\xe0\\x8a\\x03-2\\xe3\\x03\\x80\\xef\\xe4\\x03-2\\xea\\x03\\x88\\xe6\\xeb\\x03\\x8e\\xe6\" +\n\t\"\\xe8\\x03\\x84\\xe6\\xe9\\x03\\x97\\xe6\\xee\\x03-2\\xf9\\x03-2\\xf6\\x03\\x8e\\xe3\\xad\" +\n\t\"\\x03\\x80\\xe3\\x92\\x03\\x88\\xe3\\x90\\x03\\x8e\\xe3\\x90\\x03\\x80\\xe3\\x97\\x03\\x88\" +\n\t\"\\xe3\\x95\\x03\\x88\\xfe\\xcb\\x03\\x8e\\xfe\\xca\\x03\\x84\\xfe\\xcd\\x03\\x91\\xef\\xc9\" +\n\t\"\\x03-2\\xc1\\x03-2\\xc0\\x03-2\\xcb\\x03\\x88@\\x09\\x03\\x8e@\\x08\\x03\\x8f\\xe0\\xf5\" +\n\t\"\\x03\\x8e\\xe6\\xf9\\x03\\x8e\\xe0\\xfa\\x03\\x93\\xff\\xf4\\x03\\x84\\xee\\xd3\\x03\\x0b\" +\n\t\"(\\x04\\x023 \\x021;\\x02\\x01*\\x03\\x0b#\\x10\\x03\\x0b 0\\x03\\x0b!\\x10\\x03\\x0b!0\" +\n\t\"\\x03\\x07\\x15\\x08\\x03\\x09?5\\x03\\x07\\x1f\\x08\\x03\\x07\\x17\\x0b\\x03\\x09\\x1f\" +\n\t\"\\x15\\x03\\x0b\\x1c7\\x03\\x0a+#\\x03\\x06\\x1a\\x1b\\x03\\x06\\x1a\\x14\\x03\\x0a\\x01\" +\n\t\"\\x18\\x03\\x06#\\x1b\\x03\\x0a2\\x0c\\x03\\x0a\\x01\\x04\\x03\\x09#;\\x03\\x08='\\x03\" +\n\t\"\\x08\\x1a\\x0a\\x03\\x07</\\x03\\x07:+\\x03\\x07\\x07*\\x03\\x06&\\x1c\\x03\\x09\\x0c\" +\n\t\"\\x16\\x03\\x09\\x10\\x0e\\x03\\x08'\\x0f\\x03\\x08+\\x09\\x03\\x074%\\x03\\x06!3\\x03\" +\n\t\"\\x06\\x03+\\x03\\x0b\\x1e\\x19\\x03\\x0a))\\x03\\x09\\x08\\x19\\x03\\x08,\\x05\\x03\\x07\" +\n\t\"<2\\x03\\x06\\x1c>\\x03\\x0a\\x111\\x03\\x09\\x1b\\x09\\x03\\x073.\\x03\\x07\\x01\\x00\" +\n\t\"\\x03\\x09/,\\x03\\x07#>\\x03\\x07\\x048\\x03\\x0a\\x1f\\x22\\x03\\x098>\\x03\\x09\\x11\" +\n\t\"\\x00\\x03\\x08/\\x17\\x03\\x06'\\x22\\x03\\x0b\\x1a+\\x03\\x0a\\x22\\x19\\x03\\x0a/1\" +\n\t\"\\x03\\x0974\\x03\\x09\\x0f\\x22\\x03\\x08,\\x22\\x03\\x08?\\x14\\x03\\x07$5\\x03\\x07<3\" +\n\t\"\\x03\\x07=*\\x03\\x07\\x13\\x18\\x03\\x068\\x0a\\x03\\x06\\x09\\x16\\x03\\x06\\x13\\x00\" +\n\t\"\\x03\\x08\\x067\\x03\\x08\\x01\\x03\\x03\\x08\\x12\\x1d\\x03\\x07+7\\x03\\x06(;\\x03\" +\n\t\"\\x06\\x1c?\\x03\\x07\\x0e\\x17\\x03\\x0a\\x06\\x1d\\x03\\x0a\\x19\\x07\\x03\\x08\\x14$\" +\n\t\"\\x03\\x07$;\\x03\\x08,$\\x03\\x08\\x06\\x0d\\x03\\x07\\x16\\x0a\\x03\\x06>>\\x03\\x0a\" +\n\t\"\\x06\\x12\\x03\\x0a\\x14)\\x03\\x09\\x0d\\x1f\\x03\\x09\\x12\\x17\\x03\\x09\\x19\\x01\" +\n\t\"\\x03\\x08\\x11 \\x03\\x08\\x1d'\\x03\\x06<\\x1a\\x03\\x0a.\\x00\\x03\\x07'\\x18\\x03\" +\n\t\"\\x0a\\x22\\x08\\x03\\x08\\x0d\\x0a\\x03\\x08\\x13)\\x03\\x07*)\\x03\\x06<,\\x03\\x07\" +\n\t\"\\x0b\\x1a\\x03\\x09.\\x14\\x03\\x09\\x0d\\x1e\\x03\\x07\\x0e#\\x03\\x0b\\x1d'\\x03\\x0a\" +\n\t\"\\x0a8\\x03\\x09%2\\x03\\x08+&\\x03\\x080\\x12\\x03\\x0a)4\\x03\\x08\\x06\\x1f\\x03\\x0b\" +\n\t\"\\x1b\\x1a\\x03\\x0a\\x1b\\x0f\\x03\\x0b\\x1d*\\x03\\x09\\x16$\\x03\\x090\\x11\\x03\\x08\" +\n\t\"\\x11\\x08\\x03\\x0a*(\\x03\\x0a\\x042\\x03\\x089,\\x03\\x074'\\x03\\x07\\x0f\\x05\\x03\" +\n\t\"\\x09\\x0b\\x0a\\x03\\x07\\x1b\\x01\\x03\\x09\\x17:\\x03\\x09.\\x0d\\x03\\x07.\\x11\\x03\" +\n\t\"\\x09+\\x15\\x03\\x080\\x13\\x03\\x0b\\x1f\\x19\\x03\\x0a \\x11\\x03\\x0a\\x220\\x03\\x09\" +\n\t\"\\x07;\\x03\\x08\\x16\\x1c\\x03\\x07,\\x13\\x03\\x07\\x0e/\\x03\\x06\\x221\\x03\\x0a.\" +\n\t\"\\x0a\\x03\\x0a7\\x02\\x03\\x0a\\x032\\x03\\x0a\\x1d.\\x03\\x091\\x06\\x03\\x09\\x19:\" +\n\t\"\\x03\\x08\\x02/\\x03\\x060+\\x03\\x06\\x0f-\\x03\\x06\\x1c\\x1f\\x03\\x06\\x1d\\x07\\x03\" +\n\t\"\\x0a,\\x11\\x03\\x09=\\x0d\\x03\\x09\\x0b;\\x03\\x07\\x1b/\\x03\\x0a\\x1f:\\x03\\x09 \" +\n\t\"\\x1f\\x03\\x09.\\x10\\x03\\x094\\x0b\\x03\\x09\\x1a1\\x03\\x08#\\x1a\\x03\\x084\\x1d\" +\n\t\"\\x03\\x08\\x01\\x1f\\x03\\x08\\x11\\x22\\x03\\x07'8\\x03\\x07\\x1a>\\x03\\x0757\\x03\" +\n\t\"\\x06&9\\x03\\x06+\\x11\\x03\\x0a.\\x0b\\x03\\x0a,>\\x03\\x0a4#\\x03\\x08%\\x17\\x03\" +\n\t\"\\x07\\x05\\x22\\x03\\x07\\x0c\\x0b\\x03\\x0a\\x1d+\\x03\\x0a\\x19\\x16\\x03\\x09+\\x1f\" +\n\t\"\\x03\\x09\\x08\\x0b\\x03\\x08\\x16\\x18\\x03\\x08+\\x12\\x03\\x0b\\x1d\\x0c\\x03\\x0a=\" +\n\t\"\\x10\\x03\\x0a\\x09\\x0d\\x03\\x0a\\x10\\x11\\x03\\x09&0\\x03\\x08(\\x1f\\x03\\x087\\x07\" +\n\t\"\\x03\\x08\\x185\\x03\\x07'6\\x03\\x06.\\x05\\x03\\x06=\\x04\\x03\\x06;;\\x03\\x06\\x06,\" +\n\t\"\\x03\\x0b\\x18>\\x03\\x08\\x00\\x18\\x03\\x06 \\x03\\x03\\x06<\\x00\\x03\\x09%\\x18\\x03\" +\n\t\"\\x0b\\x1c<\\x03\\x0a%!\\x03\\x0a\\x09\\x12\\x03\\x0a\\x16\\x02\\x03\\x090'\\x03\\x09\" +\n\t\"\\x0e=\\x03\\x08 \\x0e\\x03\\x08>\\x03\\x03\\x074>\\x03\\x06&?\\x03\\x06\\x19\\x09\\x03\" +\n\t\"\\x06?(\\x03\\x0a-\\x0e\\x03\\x09:3\\x03\\x098:\\x03\\x09\\x12\\x0b\\x03\\x09\\x1d\\x17\" +\n\t\"\\x03\\x087\\x05\\x03\\x082\\x14\\x03\\x08\\x06%\\x03\\x08\\x13\\x1f\\x03\\x06\\x06\\x0e\" +\n\t\"\\x03\\x0a\\x22<\\x03\\x09/<\\x03\\x06>+\\x03\\x0a'?\\x03\\x0a\\x13\\x0c\\x03\\x09\\x10<\" +\n\t\"\\x03\\x07\\x1b=\\x03\\x0a\\x19\\x13\\x03\\x09\\x22\\x1d\\x03\\x09\\x07\\x0d\\x03\\x08)\" +\n\t\"\\x1c\\x03\\x06=\\x1a\\x03\\x0a/4\\x03\\x0a7\\x11\\x03\\x0a\\x16:\\x03\\x09?3\\x03\\x09:\" +\n\t\"/\\x03\\x09\\x05\\x0a\\x03\\x09\\x14\\x06\\x03\\x087\\x22\\x03\\x080\\x07\\x03\\x08\\x1a\" +\n\t\"\\x1f\\x03\\x07\\x04(\\x03\\x07\\x04\\x09\\x03\\x06 %\\x03\\x06<\\x08\\x03\\x0a+\\x14\" +\n\t\"\\x03\\x09\\x1d\\x16\\x03\\x0a70\\x03\\x08 >\\x03\\x0857\\x03\\x070\\x0a\\x03\\x06=\\x12\" +\n\t\"\\x03\\x06\\x16%\\x03\\x06\\x1d,\\x03\\x099#\\x03\\x09\\x10>\\x03\\x07 \\x1e\\x03\\x08\" +\n\t\"\\x0c<\\x03\\x08\\x0b\\x18\\x03\\x08\\x15+\\x03\\x08,:\\x03\\x08%\\x22\\x03\\x07\\x0a$\" +\n\t\"\\x03\\x0b\\x1c=\\x03\\x07+\\x08\\x03\\x0a/\\x05\\x03\\x0a \\x07\\x03\\x0a\\x12'\\x03\" +\n\t\"\\x09#\\x11\\x03\\x08\\x1b\\x15\\x03\\x0a\\x06\\x01\\x03\\x09\\x1c\\x1b\\x03\\x0922\\x03\" +\n\t\"\\x07\\x14<\\x03\\x07\\x09\\x04\\x03\\x061\\x04\\x03\\x07\\x0e\\x01\\x03\\x0a\\x13\\x18\" +\n\t\"\\x03\\x0a-\\x0c\\x03\\x0a?\\x0d\\x03\\x0a\\x09\\x0a\\x03\\x091&\\x03\\x0a/\\x0b\\x03\" +\n\t\"\\x08$<\\x03\\x083\\x1d\\x03\\x08\\x0c$\\x03\\x08\\x0d\\x07\\x03\\x08\\x0d?\\x03\\x08\" +\n\t\"\\x0e\\x14\\x03\\x065\\x0a\\x03\\x08\\x1a#\\x03\\x08\\x16#\\x03\\x0702\\x03\\x07\\x03\" +\n\t\"\\x1a\\x03\\x06(\\x1d\\x03\\x06+\\x1b\\x03\\x06\\x0b\\x05\\x03\\x06\\x0b\\x17\\x03\\x06\" +\n\t\"\\x0c\\x04\\x03\\x06\\x1e\\x19\\x03\\x06+0\\x03\\x062\\x18\\x03\\x0b\\x16\\x1e\\x03\\x0a+\" +\n\t\"\\x16\\x03\\x0a-?\\x03\\x0a#:\\x03\\x0a#\\x10\\x03\\x0a%$\\x03\\x0a>+\\x03\\x0a01\\x03\" +\n\t\"\\x0a1\\x10\\x03\\x0a\\x099\\x03\\x0a\\x0a\\x12\\x03\\x0a\\x19\\x1f\\x03\\x0a\\x19\\x12\" +\n\t\"\\x03\\x09*)\\x03\\x09-\\x16\\x03\\x09.1\\x03\\x09.2\\x03\\x09<\\x0e\\x03\\x09> \\x03\" +\n\t\"\\x093\\x12\\x03\\x09\\x0b\\x01\\x03\\x09\\x1c2\\x03\\x09\\x11\\x1c\\x03\\x09\\x15%\\x03\" +\n\t\"\\x08,&\\x03\\x08!\\x22\\x03\\x089(\\x03\\x08\\x0b\\x1a\\x03\\x08\\x0d2\\x03\\x08\\x0c\" +\n\t\"\\x04\\x03\\x08\\x0c\\x06\\x03\\x08\\x0c\\x1f\\x03\\x08\\x0c\\x0c\\x03\\x08\\x0f\\x1f\\x03\" +\n\t\"\\x08\\x0f\\x1d\\x03\\x08\\x00\\x14\\x03\\x08\\x03\\x14\\x03\\x08\\x06\\x16\\x03\\x08\\x1e\" +\n\t\"#\\x03\\x08\\x11\\x11\\x03\\x08\\x10\\x18\\x03\\x08\\x14(\\x03\\x07)\\x1e\\x03\\x07.1\" +\n\t\"\\x03\\x07 $\\x03\\x07 '\\x03\\x078\\x08\\x03\\x07\\x0d0\\x03\\x07\\x0f7\\x03\\x07\\x05#\" +\n\t\"\\x03\\x07\\x05\\x1a\\x03\\x07\\x1a7\\x03\\x07\\x1d-\\x03\\x07\\x17\\x10\\x03\\x06)\\x1f\" +\n\t\"\\x03\\x062\\x0b\\x03\\x066\\x16\\x03\\x06\\x09\\x11\\x03\\x09(\\x1e\\x03\\x07!5\\x03\" +\n\t\"\\x0b\\x11\\x16\\x03\\x0a/\\x04\\x03\\x0a,\\x1a\\x03\\x0b\\x173\\x03\\x0a,1\\x03\\x0a/5\" +\n\t\"\\x03\\x0a\\x221\\x03\\x0a\\x22\\x0d\\x03\\x0a?%\\x03\\x0a<,\\x03\\x0a?#\\x03\\x0a>\\x19\" +\n\t\"\\x03\\x0a\\x08&\\x03\\x0a\\x0b\\x0e\\x03\\x0a\\x0c:\\x03\\x0a\\x0c+\\x03\\x0a\\x03\\x22\" +\n\t\"\\x03\\x0a\\x06)\\x03\\x0a\\x11\\x10\\x03\\x0a\\x11\\x1a\\x03\\x0a\\x17-\\x03\\x0a\\x14(\" +\n\t\"\\x03\\x09)\\x1e\\x03\\x09/\\x09\\x03\\x09.\\x00\\x03\\x09,\\x07\\x03\\x09/*\\x03\\x09-9\" +\n\t\"\\x03\\x09\\x228\\x03\\x09%\\x09\\x03\\x09:\\x12\\x03\\x09;\\x1d\\x03\\x09?\\x06\\x03\" +\n\t\"\\x093%\\x03\\x096\\x05\\x03\\x096\\x08\\x03\\x097\\x02\\x03\\x09\\x07,\\x03\\x09\\x04,\" +\n\t\"\\x03\\x09\\x1f\\x16\\x03\\x09\\x11\\x03\\x03\\x09\\x11\\x12\\x03\\x09\\x168\\x03\\x08*\" +\n\t\"\\x05\\x03\\x08/2\\x03\\x084:\\x03\\x08\\x22+\\x03\\x08 0\\x03\\x08&\\x0a\\x03\\x08;\" +\n\t\"\\x10\\x03\\x08>$\\x03\\x08>\\x18\\x03\\x0829\\x03\\x082:\\x03\\x081,\\x03\\x081<\\x03\" +\n\t\"\\x081\\x1c\\x03\\x087#\\x03\\x087*\\x03\\x08\\x09'\\x03\\x08\\x00\\x1d\\x03\\x08\\x05-\" +\n\t\"\\x03\\x08\\x1f4\\x03\\x08\\x1d\\x04\\x03\\x08\\x16\\x0f\\x03\\x07*7\\x03\\x07'!\\x03\" +\n\t\"\\x07%\\x1b\\x03\\x077\\x0c\\x03\\x07\\x0c1\\x03\\x07\\x0c.\\x03\\x07\\x00\\x06\\x03\\x07\" +\n\t\"\\x01\\x02\\x03\\x07\\x010\\x03\\x07\\x06=\\x03\\x07\\x01\\x03\\x03\\x07\\x01\\x13\\x03\" +\n\t\"\\x07\\x06\\x06\\x03\\x07\\x05\\x0a\\x03\\x07\\x1f\\x09\\x03\\x07\\x17:\\x03\\x06*1\\x03\" +\n\t\"\\x06-\\x1d\\x03\\x06\\x223\\x03\\x062:\\x03\\x060$\\x03\\x066\\x1e\\x03\\x064\\x12\\x03\" +\n\t\"\\x0645\\x03\\x06\\x0b\\x00\\x03\\x06\\x0b7\\x03\\x06\\x07\\x1f\\x03\\x06\\x15\\x12\\x03\" +\n\t\"\\x0c\\x05\\x0f\\x03\\x0b+\\x0b\\x03\\x0b+-\\x03\\x06\\x16\\x1b\\x03\\x06\\x15\\x17\\x03\" +\n\t\"\\x89\\xca\\xea\\x03\\x89\\xca\\xe8\\x03\\x0c8\\x10\\x03\\x0c8\\x01\\x03\\x0c8\\x0f\\x03\" +\n\t\"\\x0d8%\\x03\\x0d8!\\x03\\x0c8-\\x03\\x0c8/\\x03\\x0c8+\\x03\\x0c87\\x03\\x0c85\\x03\" +\n\t\"\\x0c9\\x09\\x03\\x0c9\\x0d\\x03\\x0c9\\x0f\\x03\\x0c9\\x0b\\x03\\xcfu\\x0c\\x03\\xcfu\" +\n\t\"\\x0f\\x03\\xcfu\\x0e\\x03\\xcfu\\x09\\x03\\x0c9\\x10\\x03\\x0d9\\x0c\\x03\\xcf`;\\x03\" +\n\t\"\\xcf`>\\x03\\xcf`9\\x03\\xcf`8\\x03\\xcf`7\\x03\\xcf`*\\x03\\xcf`-\\x03\\xcf`,\\x03\" +\n\t\"\\x0d\\x1b\\x1a\\x03\\x0d\\x1b&\\x03\\x0c=.\\x03\\x0c=%\\x03\\x0c>\\x1e\\x03\\x0c>\\x14\" +\n\t\"\\x03\\x0c?\\x06\\x03\\x0c?\\x0b\\x03\\x0c?\\x0c\\x03\\x0c?\\x0d\\x03\\x0c?\\x02\\x03\" +\n\t\"\\x0c>\\x0f\\x03\\x0c>\\x08\\x03\\x0c>\\x09\\x03\\x0c>,\\x03\\x0c>\\x0c\\x03\\x0c?\\x13\" +\n\t\"\\x03\\x0c?\\x16\\x03\\x0c?\\x15\\x03\\x0c?\\x1c\\x03\\x0c?\\x1f\\x03\\x0c?\\x1d\\x03\" +\n\t\"\\x0c?\\x1a\\x03\\x0c?\\x17\\x03\\x0c?\\x08\\x03\\x0c?\\x09\\x03\\x0c?\\x0e\\x03\\x0c?\" +\n\t\"\\x04\\x03\\x0c?\\x05\\x03\\x0c<?\\x03\\x0c=\\x00\\x03\\x0c=\\x06\\x03\\x0c=\\x05\\x03\" +\n\t\"\\x0c=\\x0c\\x03\\x0c=\\x0f\\x03\\x0c=\\x0d\\x03\\x0c=\\x0b\\x03\\x0c=\\x07\\x03\\x0c=\" +\n\t\"\\x19\\x03\\x0c=\\x15\\x03\\x0c=\\x11\\x03\\x0c=1\\x03\\x0c=3\\x03\\x0c=0\\x03\\x0c=>\" +\n\t\"\\x03\\x0c=2\\x03\\x0c=6\\x03\\x0c<\\x07\\x03\\x0c<\\x05\\x03\\x0e:!\\x03\\x0e:#\\x03\" +\n\t\"\\x0e8\\x09\\x03\\x0e:&\\x03\\x0e8\\x0b\\x03\\x0e:$\\x03\\x0e:,\\x03\\x0e8\\x1a\\x03\" +\n\t\"\\x0e8\\x1e\\x03\\x0e:*\\x03\\x0e:7\\x03\\x0e:5\\x03\\x0e:;\\x03\\x0e:\\x15\\x03\\x0e:<\" +\n\t\"\\x03\\x0e:4\\x03\\x0e:'\\x03\\x0e:-\\x03\\x0e:%\\x03\\x0e:?\\x03\\x0e:=\\x03\\x0e:)\" +\n\t\"\\x03\\x0e:/\\x03\\xcfs'\\x03\\x0d=\\x0f\\x03\\x0d+*\\x03\\x0d99\\x03\\x0d9;\\x03\\x0d9\" +\n\t\"?\\x03\\x0d)\\x0d\\x03\\x0d(%\\x02\\x01\\x18\\x02\\x01(\\x02\\x01\\x1e\\x03\\x0f$!\\x03\" +\n\t\"\\x0f87\\x03\\x0f4\\x0e\\x03\\x0f5\\x1d\\x03\\x06'\\x03\\x03\\x0f\\x08\\x18\\x03\\x0f\" +\n\t\"\\x0d\\x1b\\x03\\x0e2=\\x03\\x0e;\\x08\\x03\\x0e:\\x0b\\x03\\x0e\\x06$\\x03\\x0e\\x0d)\" +\n\t\"\\x03\\x0e\\x16\\x1f\\x03\\x0e\\x16\\x1b\\x03\\x0d$\\x0a\\x03\\x05,\\x1d\\x03\\x0d. \\x03\" +\n\t\"\\x0d.#\\x03\\x0c(/\\x03\\x09%\\x02\\x03\\x0d90\\x03\\x0d\\x0e4\\x03\\x0d\\x0d\\x0f\\x03\" +\n\t\"\\x0c#\\x00\\x03\\x0c,\\x1e\\x03\\x0c2\\x0e\\x03\\x0c\\x01\\x17\\x03\\x0c\\x09:\\x03\\x0e\" +\n\t\"\\x173\\x03\\x0c\\x08\\x03\\x03\\x0c\\x11\\x07\\x03\\x0c\\x10\\x18\\x03\\x0c\\x1f\\x1c\" +\n\t\"\\x03\\x0c\\x19\\x0e\\x03\\x0c\\x1a\\x1f\\x03\\x0f0>\\x03\\x0b->\\x03\\x0b<+\\x03\\x0b8\" +\n\t\"\\x13\\x03\\x0b\\x043\\x03\\x0b\\x14\\x03\\x03\\x0b\\x16%\\x03\\x0d\\x22&\\x03\\x0b\\x1a\" +\n\t\"\\x1a\\x03\\x0b\\x1a\\x04\\x03\\x0a%9\\x03\\x0a&2\\x03\\x0a&0\\x03\\x0a!\\x1a\\x03\\x0a!\" +\n\t\"7\\x03\\x0a5\\x10\\x03\\x0a=4\\x03\\x0a?\\x0e\\x03\\x0a>\\x10\\x03\\x0a\\x00 \\x03\\x0a\" +\n\t\"\\x0f:\\x03\\x0a\\x0f9\\x03\\x0a\\x0b\\x0a\\x03\\x0a\\x17%\\x03\\x0a\\x1b-\\x03\\x09-\" +\n\t\"\\x1a\\x03\\x09,4\\x03\\x09.,\\x03\\x09)\\x09\\x03\\x096!\\x03\\x091\\x1f\\x03\\x093\" +\n\t\"\\x16\\x03\\x0c+\\x1f\\x03\\x098 \\x03\\x098=\\x03\\x0c(\\x1a\\x03\\x0c(\\x16\\x03\\x09\" +\n\t\"\\x0a+\\x03\\x09\\x16\\x12\\x03\\x09\\x13\\x0e\\x03\\x09\\x153\\x03\\x08)!\\x03\\x09\\x1a\" +\n\t\"\\x01\\x03\\x09\\x18\\x01\\x03\\x08%#\\x03\\x08>\\x22\\x03\\x08\\x05%\\x03\\x08\\x02*\" +\n\t\"\\x03\\x08\\x15;\\x03\\x08\\x1b7\\x03\\x0f\\x07\\x1d\\x03\\x0f\\x04\\x03\\x03\\x070\\x0c\" +\n\t\"\\x03\\x07;\\x0b\\x03\\x07\\x08\\x17\\x03\\x07\\x12\\x06\\x03\\x06/-\\x03\\x0671\\x03\" +\n\t\"\\x065+\\x03\\x06>7\\x03\\x06\\x049\\x03\\x05+\\x1e\\x03\\x05,\\x17\\x03\\x05 \\x1d\\x03\" +\n\t\"\\x05\\x22\\x05\\x03\\x050\\x1d\"\n\n// lookup returns the trie value for the first UTF-8 encoding in s and\n// the width in bytes of this encoding. The size will be 0 if s does not\n// hold enough bytes to complete the encoding. len(s) must be greater than 0.\nfunc (t *idnaTrie) lookup(s []byte) (v uint16, sz int) {\n\tc0 := s[0]\n\tswitch {\n\tcase c0 < 0x80: // is ASCII\n\t\treturn idnaValues[c0], 1\n\tcase c0 < 0xC2:\n\t\treturn 0, 1 // Illegal UTF-8: not a starter, not ASCII.\n\tcase c0 < 0xE0: // 2-byte UTF-8\n\t\tif len(s) < 2 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c1), 2\n\tcase c0 < 0xF0: // 3-byte UTF-8\n\t\tif len(s) < 3 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c2), 3\n\tcase c0 < 0xF8: // 4-byte UTF-8\n\t\tif len(s) < 4 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to = uint32(i)<<6 + uint32(c2)\n\t\ti = idnaIndex[o]\n\t\tc3 := s[3]\n\t\tif c3 < 0x80 || 0xC0 <= c3 {\n\t\t\treturn 0, 3 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c3), 4\n\t}\n\t// Illegal rune\n\treturn 0, 1\n}\n\n// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.\n// s must start with a full and valid UTF-8 encoded rune.\nfunc (t *idnaTrie) lookupUnsafe(s []byte) uint16 {\n\tc0 := s[0]\n\tif c0 < 0x80 { // is ASCII\n\t\treturn idnaValues[c0]\n\t}\n\ti := idnaIndex[c0]\n\tif c0 < 0xE0 { // 2-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[1])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[1])]\n\tif c0 < 0xF0 { // 3-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[2])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[2])]\n\tif c0 < 0xF8 { // 4-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[3])\n\t}\n\treturn 0\n}\n\n// lookupString returns the trie value for the first UTF-8 encoding in s and\n// the width in bytes of this encoding. The size will be 0 if s does not\n// hold enough bytes to complete the encoding. len(s) must be greater than 0.\nfunc (t *idnaTrie) lookupString(s string) (v uint16, sz int) {\n\tc0 := s[0]\n\tswitch {\n\tcase c0 < 0x80: // is ASCII\n\t\treturn idnaValues[c0], 1\n\tcase c0 < 0xC2:\n\t\treturn 0, 1 // Illegal UTF-8: not a starter, not ASCII.\n\tcase c0 < 0xE0: // 2-byte UTF-8\n\t\tif len(s) < 2 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c1), 2\n\tcase c0 < 0xF0: // 3-byte UTF-8\n\t\tif len(s) < 3 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c2), 3\n\tcase c0 < 0xF8: // 4-byte UTF-8\n\t\tif len(s) < 4 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to = uint32(i)<<6 + uint32(c2)\n\t\ti = idnaIndex[o]\n\t\tc3 := s[3]\n\t\tif c3 < 0x80 || 0xC0 <= c3 {\n\t\t\treturn 0, 3 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c3), 4\n\t}\n\t// Illegal rune\n\treturn 0, 1\n}\n\n// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.\n// s must start with a full and valid UTF-8 encoded rune.\nfunc (t *idnaTrie) lookupStringUnsafe(s string) uint16 {\n\tc0 := s[0]\n\tif c0 < 0x80 { // is ASCII\n\t\treturn idnaValues[c0]\n\t}\n\ti := idnaIndex[c0]\n\tif c0 < 0xE0 { // 2-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[1])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[1])]\n\tif c0 < 0xF0 { // 3-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[2])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[2])]\n\tif c0 < 0xF8 { // 4-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[3])\n\t}\n\treturn 0\n}\n\n// idnaTrie. Total size: 28600 bytes (27.93 KiB). Checksum: 95575047b5d8fff.\ntype idnaTrie struct{}\n\nfunc newIdnaTrie(i int) *idnaTrie {\n\treturn &idnaTrie{}\n}\n\n// lookupValue determines the type of block n and looks up the value for b.\nfunc (t *idnaTrie) lookupValue(n uint32, b byte) uint16 {\n\tswitch {\n\tcase n < 124:\n\t\treturn uint16(idnaValues[n<<6+uint32(b)])\n\tdefault:\n\t\tn -= 124\n\t\treturn uint16(idnaSparse.lookup(n, b))\n\t}\n}\n\n// idnaValues: 126 blocks, 8064 entries, 16128 bytes\n// The third block is the zero block.\nvar idnaValues = [8064]uint16{\n\t// Block 0x0, offset 0x0\n\t0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080,\n\t0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080,\n\t0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080,\n\t0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080,\n\t0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080,\n\t0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080,\n\t0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080,\n\t0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080,\n\t0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008,\n\t0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080,\n\t0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080,\n\t// Block 0x1, offset 0x40\n\t0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105,\n\t0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105,\n\t0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105,\n\t0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105,\n\t0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080,\n\t0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008,\n\t0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008,\n\t0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008,\n\t0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008,\n\t0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080,\n\t0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080,\n\t// Block 0x2, offset 0x80\n\t// Block 0x3, offset 0xc0\n\t0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040,\n\t0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040,\n\t0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040,\n\t0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040,\n\t0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040,\n\t0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018,\n\t0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x001a, 0xe9: 0x0018,\n\t0xea: 0x0039, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x004a,\n\t0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0069, 0xf3: 0x0079, 0xf4: 0x008a, 0xf5: 0x0005,\n\t0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x00aa, 0xf9: 0x00c9, 0xfa: 0x00d9, 0xfb: 0x0018,\n\t0xfc: 0x00e9, 0xfd: 0x0119, 0xfe: 0x0149, 0xff: 0x0018,\n\t// Block 0x4, offset 0x100\n\t0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008,\n\t0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008,\n\t0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008,\n\t0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008,\n\t0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008,\n\t0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008,\n\t0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008,\n\t0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008,\n\t0x130: 0x0179, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008,\n\t0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d,\n\t0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0199,\n\t// Block 0x5, offset 0x140\n\t0x140: 0x0199, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d,\n\t0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x01b9, 0x14a: 0xe00d, 0x14b: 0x0008,\n\t0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008,\n\t0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008,\n\t0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008,\n\t0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008,\n\t0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008,\n\t0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008,\n\t0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008,\n\t0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d,\n\t0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x01d9,\n\t// Block 0x6, offset 0x180\n\t0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008,\n\t0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d,\n\t0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d,\n\t0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d,\n\t0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155,\n\t0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008,\n\t0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d,\n\t0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd,\n\t0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d,\n\t0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008,\n\t0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008,\n\t// Block 0x7, offset 0x1c0\n\t0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x01e9, 0x1c5: 0x01e9,\n\t0x1c6: 0x01e9, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d,\n\t0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d,\n\t0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d,\n\t0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008,\n\t0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008,\n\t0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008,\n\t0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008,\n\t0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008,\n\t0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008,\n\t0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008,\n\t// Block 0x8, offset 0x200\n\t0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008,\n\t0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008,\n\t0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008,\n\t0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008,\n\t0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008,\n\t0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008,\n\t0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008,\n\t0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008,\n\t0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008,\n\t0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0209, 0x23b: 0xe03d,\n\t0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x0229, 0x23f: 0x0008,\n\t// Block 0x9, offset 0x240\n\t0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018,\n\t0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008,\n\t0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008,\n\t0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018,\n\t0x258: 0x029a, 0x259: 0x02ba, 0x25a: 0x02da, 0x25b: 0x02fa, 0x25c: 0x031a, 0x25d: 0x033a,\n\t0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0359, 0x262: 0x01d9, 0x263: 0x0369,\n\t0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018,\n\t0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018,\n\t0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018,\n\t0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018,\n\t0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018,\n\t// Block 0xa, offset 0x280\n\t0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d,\n\t0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308,\n\t0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308,\n\t0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308,\n\t0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308,\n\t0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308,\n\t0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308,\n\t0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308,\n\t0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008,\n\t0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008,\n\t0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d,\n\t// Block 0xb, offset 0x2c0\n\t0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x008a, 0x2c5: 0x03d2,\n\t0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040,\n\t0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105,\n\t0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105,\n\t0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105,\n\t0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d,\n\t0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d,\n\t0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008,\n\t0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008,\n\t0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008,\n\t0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008,\n\t// Block 0xc, offset 0x300\n\t0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008,\n\t0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008,\n\t0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd,\n\t0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008,\n\t0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008,\n\t0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008,\n\t0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008,\n\t0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008,\n\t0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd,\n\t0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008,\n\t0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d,\n\t// Block 0xd, offset 0x340\n\t0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008,\n\t0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008,\n\t0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008,\n\t0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008,\n\t0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008,\n\t0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008,\n\t0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008,\n\t0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008,\n\t0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008,\n\t0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008,\n\t0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008,\n\t// Block 0xe, offset 0x380\n\t0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308,\n\t0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008,\n\t0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008,\n\t0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008,\n\t0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008,\n\t0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008,\n\t0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008,\n\t0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008,\n\t0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008,\n\t0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008,\n\t0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008,\n\t// Block 0xf, offset 0x3c0\n\t0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d,\n\t0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d,\n\t0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008,\n\t0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008,\n\t0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008,\n\t0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008,\n\t0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008,\n\t0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008,\n\t0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008,\n\t0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008,\n\t0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008,\n\t// Block 0x10, offset 0x400\n\t0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008,\n\t0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008,\n\t0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008,\n\t0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008,\n\t0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008,\n\t0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008,\n\t0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008,\n\t0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008,\n\t0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5,\n\t0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5,\n\t0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5,\n\t// Block 0x11, offset 0x440\n\t0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840,\n\t0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818,\n\t0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308,\n\t0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308,\n\t0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040,\n\t0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08,\n\t0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08,\n\t0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08,\n\t0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08,\n\t0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08,\n\t0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08,\n\t// Block 0x12, offset 0x480\n\t0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08,\n\t0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308,\n\t0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308,\n\t0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308,\n\t0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308,\n\t0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808,\n\t0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808,\n\t0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08,\n\t0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0429,\n\t0x4b6: 0x0451, 0x4b7: 0x0479, 0x4b8: 0x04a1, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08,\n\t0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08,\n\t// Block 0x13, offset 0x4c0\n\t0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08,\n\t0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08,\n\t0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08,\n\t0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308,\n\t0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840,\n\t0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308,\n\t0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018,\n\t0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08,\n\t0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008,\n\t0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08,\n\t0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08,\n\t// Block 0x14, offset 0x500\n\t0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818,\n\t0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818,\n\t0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308,\n\t0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08,\n\t0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08,\n\t0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08,\n\t0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08,\n\t0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08,\n\t0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308,\n\t0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308,\n\t0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308,\n\t// Block 0x15, offset 0x540\n\t0x540: 0x3008, 0x541: 0x3308, 0x542: 0x3308, 0x543: 0x3308, 0x544: 0x3308, 0x545: 0x3308,\n\t0x546: 0x3308, 0x547: 0x3308, 0x548: 0x3308, 0x549: 0x3008, 0x54a: 0x3008, 0x54b: 0x3008,\n\t0x54c: 0x3008, 0x54d: 0x3b08, 0x54e: 0x3008, 0x54f: 0x3008, 0x550: 0x0008, 0x551: 0x3308,\n\t0x552: 0x3308, 0x553: 0x3308, 0x554: 0x3308, 0x555: 0x3308, 0x556: 0x3308, 0x557: 0x3308,\n\t0x558: 0x04c9, 0x559: 0x0501, 0x55a: 0x0539, 0x55b: 0x0571, 0x55c: 0x05a9, 0x55d: 0x05e1,\n\t0x55e: 0x0619, 0x55f: 0x0651, 0x560: 0x0008, 0x561: 0x0008, 0x562: 0x3308, 0x563: 0x3308,\n\t0x564: 0x0018, 0x565: 0x0018, 0x566: 0x0008, 0x567: 0x0008, 0x568: 0x0008, 0x569: 0x0008,\n\t0x56a: 0x0008, 0x56b: 0x0008, 0x56c: 0x0008, 0x56d: 0x0008, 0x56e: 0x0008, 0x56f: 0x0008,\n\t0x570: 0x0018, 0x571: 0x0008, 0x572: 0x0008, 0x573: 0x0008, 0x574: 0x0008, 0x575: 0x0008,\n\t0x576: 0x0008, 0x577: 0x0008, 0x578: 0x0008, 0x579: 0x0008, 0x57a: 0x0008, 0x57b: 0x0008,\n\t0x57c: 0x0008, 0x57d: 0x0008, 0x57e: 0x0008, 0x57f: 0x0008,\n\t// Block 0x16, offset 0x580\n\t0x580: 0x0008, 0x581: 0x3308, 0x582: 0x3008, 0x583: 0x3008, 0x584: 0x0040, 0x585: 0x0008,\n\t0x586: 0x0008, 0x587: 0x0008, 0x588: 0x0008, 0x589: 0x0008, 0x58a: 0x0008, 0x58b: 0x0008,\n\t0x58c: 0x0008, 0x58d: 0x0040, 0x58e: 0x0040, 0x58f: 0x0008, 0x590: 0x0008, 0x591: 0x0040,\n\t0x592: 0x0040, 0x593: 0x0008, 0x594: 0x0008, 0x595: 0x0008, 0x596: 0x0008, 0x597: 0x0008,\n\t0x598: 0x0008, 0x599: 0x0008, 0x59a: 0x0008, 0x59b: 0x0008, 0x59c: 0x0008, 0x59d: 0x0008,\n\t0x59e: 0x0008, 0x59f: 0x0008, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x0008, 0x5a3: 0x0008,\n\t0x5a4: 0x0008, 0x5a5: 0x0008, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0040,\n\t0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008,\n\t0x5b0: 0x0008, 0x5b1: 0x0040, 0x5b2: 0x0008, 0x5b3: 0x0040, 0x5b4: 0x0040, 0x5b5: 0x0040,\n\t0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0040, 0x5bb: 0x0040,\n\t0x5bc: 0x3308, 0x5bd: 0x0008, 0x5be: 0x3008, 0x5bf: 0x3008,\n\t// Block 0x17, offset 0x5c0\n\t0x5c0: 0x3008, 0x5c1: 0x3308, 0x5c2: 0x3308, 0x5c3: 0x3308, 0x5c4: 0x3308, 0x5c5: 0x0040,\n\t0x5c6: 0x0040, 0x5c7: 0x3008, 0x5c8: 0x3008, 0x5c9: 0x0040, 0x5ca: 0x0040, 0x5cb: 0x3008,\n\t0x5cc: 0x3008, 0x5cd: 0x3b08, 0x5ce: 0x0008, 0x5cf: 0x0040, 0x5d0: 0x0040, 0x5d1: 0x0040,\n\t0x5d2: 0x0040, 0x5d3: 0x0040, 0x5d4: 0x0040, 0x5d5: 0x0040, 0x5d6: 0x0040, 0x5d7: 0x3008,\n\t0x5d8: 0x0040, 0x5d9: 0x0040, 0x5da: 0x0040, 0x5db: 0x0040, 0x5dc: 0x0689, 0x5dd: 0x06c1,\n\t0x5de: 0x0040, 0x5df: 0x06f9, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x3308, 0x5e3: 0x3308,\n\t0x5e4: 0x0040, 0x5e5: 0x0040, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0008,\n\t0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008,\n\t0x5f0: 0x0008, 0x5f1: 0x0008, 0x5f2: 0x0018, 0x5f3: 0x0018, 0x5f4: 0x0018, 0x5f5: 0x0018,\n\t0x5f6: 0x0018, 0x5f7: 0x0018, 0x5f8: 0x0018, 0x5f9: 0x0018, 0x5fa: 0x0018, 0x5fb: 0x0018,\n\t0x5fc: 0x0040, 0x5fd: 0x0040, 0x5fe: 0x0040, 0x5ff: 0x0040,\n\t// Block 0x18, offset 0x600\n\t0x600: 0x0040, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3008, 0x604: 0x0040, 0x605: 0x0008,\n\t0x606: 0x0008, 0x607: 0x0008, 0x608: 0x0008, 0x609: 0x0008, 0x60a: 0x0008, 0x60b: 0x0040,\n\t0x60c: 0x0040, 0x60d: 0x0040, 0x60e: 0x0040, 0x60f: 0x0008, 0x610: 0x0008, 0x611: 0x0040,\n\t0x612: 0x0040, 0x613: 0x0008, 0x614: 0x0008, 0x615: 0x0008, 0x616: 0x0008, 0x617: 0x0008,\n\t0x618: 0x0008, 0x619: 0x0008, 0x61a: 0x0008, 0x61b: 0x0008, 0x61c: 0x0008, 0x61d: 0x0008,\n\t0x61e: 0x0008, 0x61f: 0x0008, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x0008, 0x623: 0x0008,\n\t0x624: 0x0008, 0x625: 0x0008, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0040,\n\t0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008,\n\t0x630: 0x0008, 0x631: 0x0040, 0x632: 0x0008, 0x633: 0x0731, 0x634: 0x0040, 0x635: 0x0008,\n\t0x636: 0x0769, 0x637: 0x0040, 0x638: 0x0008, 0x639: 0x0008, 0x63a: 0x0040, 0x63b: 0x0040,\n\t0x63c: 0x3308, 0x63d: 0x0040, 0x63e: 0x3008, 0x63f: 0x3008,\n\t// Block 0x19, offset 0x640\n\t0x640: 0x3008, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x0040, 0x644: 0x0040, 0x645: 0x0040,\n\t0x646: 0x0040, 0x647: 0x3308, 0x648: 0x3308, 0x649: 0x0040, 0x64a: 0x0040, 0x64b: 0x3308,\n\t0x64c: 0x3308, 0x64d: 0x3b08, 0x64e: 0x0040, 0x64f: 0x0040, 0x650: 0x0040, 0x651: 0x3308,\n\t0x652: 0x0040, 0x653: 0x0040, 0x654: 0x0040, 0x655: 0x0040, 0x656: 0x0040, 0x657: 0x0040,\n\t0x658: 0x0040, 0x659: 0x07a1, 0x65a: 0x07d9, 0x65b: 0x0811, 0x65c: 0x0008, 0x65d: 0x0040,\n\t0x65e: 0x0849, 0x65f: 0x0040, 0x660: 0x0040, 0x661: 0x0040, 0x662: 0x0040, 0x663: 0x0040,\n\t0x664: 0x0040, 0x665: 0x0040, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0008,\n\t0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008,\n\t0x670: 0x3308, 0x671: 0x3308, 0x672: 0x0008, 0x673: 0x0008, 0x674: 0x0008, 0x675: 0x3308,\n\t0x676: 0x0040, 0x677: 0x0040, 0x678: 0x0040, 0x679: 0x0040, 0x67a: 0x0040, 0x67b: 0x0040,\n\t0x67c: 0x0040, 0x67d: 0x0040, 0x67e: 0x0040, 0x67f: 0x0040,\n\t// Block 0x1a, offset 0x680\n\t0x680: 0x0040, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x3008, 0x684: 0x0040, 0x685: 0x0008,\n\t0x686: 0x0008, 0x687: 0x0008, 0x688: 0x0008, 0x689: 0x0008, 0x68a: 0x0008, 0x68b: 0x0008,\n\t0x68c: 0x0008, 0x68d: 0x0008, 0x68e: 0x0040, 0x68f: 0x0008, 0x690: 0x0008, 0x691: 0x0008,\n\t0x692: 0x0040, 0x693: 0x0008, 0x694: 0x0008, 0x695: 0x0008, 0x696: 0x0008, 0x697: 0x0008,\n\t0x698: 0x0008, 0x699: 0x0008, 0x69a: 0x0008, 0x69b: 0x0008, 0x69c: 0x0008, 0x69d: 0x0008,\n\t0x69e: 0x0008, 0x69f: 0x0008, 0x6a0: 0x0008, 0x6a1: 0x0008, 0x6a2: 0x0008, 0x6a3: 0x0008,\n\t0x6a4: 0x0008, 0x6a5: 0x0008, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0040,\n\t0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008,\n\t0x6b0: 0x0008, 0x6b1: 0x0040, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0040, 0x6b5: 0x0008,\n\t0x6b6: 0x0008, 0x6b7: 0x0008, 0x6b8: 0x0008, 0x6b9: 0x0008, 0x6ba: 0x0040, 0x6bb: 0x0040,\n\t0x6bc: 0x3308, 0x6bd: 0x0008, 0x6be: 0x3008, 0x6bf: 0x3008,\n\t// Block 0x1b, offset 0x6c0\n\t0x6c0: 0x3008, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3308, 0x6c4: 0x3308, 0x6c5: 0x3308,\n\t0x6c6: 0x0040, 0x6c7: 0x3308, 0x6c8: 0x3308, 0x6c9: 0x3008, 0x6ca: 0x0040, 0x6cb: 0x3008,\n\t0x6cc: 0x3008, 0x6cd: 0x3b08, 0x6ce: 0x0040, 0x6cf: 0x0040, 0x6d0: 0x0008, 0x6d1: 0x0040,\n\t0x6d2: 0x0040, 0x6d3: 0x0040, 0x6d4: 0x0040, 0x6d5: 0x0040, 0x6d6: 0x0040, 0x6d7: 0x0040,\n\t0x6d8: 0x0040, 0x6d9: 0x0040, 0x6da: 0x0040, 0x6db: 0x0040, 0x6dc: 0x0040, 0x6dd: 0x0040,\n\t0x6de: 0x0040, 0x6df: 0x0040, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x3308, 0x6e3: 0x3308,\n\t0x6e4: 0x0040, 0x6e5: 0x0040, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0008,\n\t0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008,\n\t0x6f0: 0x0018, 0x6f1: 0x0018, 0x6f2: 0x0040, 0x6f3: 0x0040, 0x6f4: 0x0040, 0x6f5: 0x0040,\n\t0x6f6: 0x0040, 0x6f7: 0x0040, 0x6f8: 0x0040, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040,\n\t0x6fc: 0x0040, 0x6fd: 0x0040, 0x6fe: 0x0040, 0x6ff: 0x0040,\n\t// Block 0x1c, offset 0x700\n\t0x700: 0x0040, 0x701: 0x3308, 0x702: 0x3008, 0x703: 0x3008, 0x704: 0x0040, 0x705: 0x0008,\n\t0x706: 0x0008, 0x707: 0x0008, 0x708: 0x0008, 0x709: 0x0008, 0x70a: 0x0008, 0x70b: 0x0008,\n\t0x70c: 0x0008, 0x70d: 0x0040, 0x70e: 0x0040, 0x70f: 0x0008, 0x710: 0x0008, 0x711: 0x0040,\n\t0x712: 0x0040, 0x713: 0x0008, 0x714: 0x0008, 0x715: 0x0008, 0x716: 0x0008, 0x717: 0x0008,\n\t0x718: 0x0008, 0x719: 0x0008, 0x71a: 0x0008, 0x71b: 0x0008, 0x71c: 0x0008, 0x71d: 0x0008,\n\t0x71e: 0x0008, 0x71f: 0x0008, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x0008, 0x723: 0x0008,\n\t0x724: 0x0008, 0x725: 0x0008, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0040,\n\t0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008,\n\t0x730: 0x0008, 0x731: 0x0040, 0x732: 0x0008, 0x733: 0x0008, 0x734: 0x0040, 0x735: 0x0008,\n\t0x736: 0x0008, 0x737: 0x0008, 0x738: 0x0008, 0x739: 0x0008, 0x73a: 0x0040, 0x73b: 0x0040,\n\t0x73c: 0x3308, 0x73d: 0x0008, 0x73e: 0x3008, 0x73f: 0x3308,\n\t// Block 0x1d, offset 0x740\n\t0x740: 0x3008, 0x741: 0x3308, 0x742: 0x3308, 0x743: 0x3308, 0x744: 0x3308, 0x745: 0x0040,\n\t0x746: 0x0040, 0x747: 0x3008, 0x748: 0x3008, 0x749: 0x0040, 0x74a: 0x0040, 0x74b: 0x3008,\n\t0x74c: 0x3008, 0x74d: 0x3b08, 0x74e: 0x0040, 0x74f: 0x0040, 0x750: 0x0040, 0x751: 0x0040,\n\t0x752: 0x0040, 0x753: 0x0040, 0x754: 0x0040, 0x755: 0x0040, 0x756: 0x3308, 0x757: 0x3008,\n\t0x758: 0x0040, 0x759: 0x0040, 0x75a: 0x0040, 0x75b: 0x0040, 0x75c: 0x0881, 0x75d: 0x08b9,\n\t0x75e: 0x0040, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x3308, 0x763: 0x3308,\n\t0x764: 0x0040, 0x765: 0x0040, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0008,\n\t0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008,\n\t0x770: 0x0018, 0x771: 0x0008, 0x772: 0x0018, 0x773: 0x0018, 0x774: 0x0018, 0x775: 0x0018,\n\t0x776: 0x0018, 0x777: 0x0018, 0x778: 0x0040, 0x779: 0x0040, 0x77a: 0x0040, 0x77b: 0x0040,\n\t0x77c: 0x0040, 0x77d: 0x0040, 0x77e: 0x0040, 0x77f: 0x0040,\n\t// Block 0x1e, offset 0x780\n\t0x780: 0x0040, 0x781: 0x0040, 0x782: 0x3308, 0x783: 0x0008, 0x784: 0x0040, 0x785: 0x0008,\n\t0x786: 0x0008, 0x787: 0x0008, 0x788: 0x0008, 0x789: 0x0008, 0x78a: 0x0008, 0x78b: 0x0040,\n\t0x78c: 0x0040, 0x78d: 0x0040, 0x78e: 0x0008, 0x78f: 0x0008, 0x790: 0x0008, 0x791: 0x0040,\n\t0x792: 0x0008, 0x793: 0x0008, 0x794: 0x0008, 0x795: 0x0008, 0x796: 0x0040, 0x797: 0x0040,\n\t0x798: 0x0040, 0x799: 0x0008, 0x79a: 0x0008, 0x79b: 0x0040, 0x79c: 0x0008, 0x79d: 0x0040,\n\t0x79e: 0x0008, 0x79f: 0x0008, 0x7a0: 0x0040, 0x7a1: 0x0040, 0x7a2: 0x0040, 0x7a3: 0x0008,\n\t0x7a4: 0x0008, 0x7a5: 0x0040, 0x7a6: 0x0040, 0x7a7: 0x0040, 0x7a8: 0x0008, 0x7a9: 0x0008,\n\t0x7aa: 0x0008, 0x7ab: 0x0040, 0x7ac: 0x0040, 0x7ad: 0x0040, 0x7ae: 0x0008, 0x7af: 0x0008,\n\t0x7b0: 0x0008, 0x7b1: 0x0008, 0x7b2: 0x0008, 0x7b3: 0x0008, 0x7b4: 0x0008, 0x7b5: 0x0008,\n\t0x7b6: 0x0008, 0x7b7: 0x0008, 0x7b8: 0x0008, 0x7b9: 0x0008, 0x7ba: 0x0040, 0x7bb: 0x0040,\n\t0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x3008, 0x7bf: 0x3008,\n\t// Block 0x1f, offset 0x7c0\n\t0x7c0: 0x3308, 0x7c1: 0x3008, 0x7c2: 0x3008, 0x7c3: 0x3008, 0x7c4: 0x3008, 0x7c5: 0x0040,\n\t0x7c6: 0x3308, 0x7c7: 0x3308, 0x7c8: 0x3308, 0x7c9: 0x0040, 0x7ca: 0x3308, 0x7cb: 0x3308,\n\t0x7cc: 0x3308, 0x7cd: 0x3b08, 0x7ce: 0x0040, 0x7cf: 0x0040, 0x7d0: 0x0040, 0x7d1: 0x0040,\n\t0x7d2: 0x0040, 0x7d3: 0x0040, 0x7d4: 0x0040, 0x7d5: 0x3308, 0x7d6: 0x3308, 0x7d7: 0x0040,\n\t0x7d8: 0x0008, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0040, 0x7dd: 0x0040,\n\t0x7de: 0x0040, 0x7df: 0x0040, 0x7e0: 0x0008, 0x7e1: 0x0008, 0x7e2: 0x3308, 0x7e3: 0x3308,\n\t0x7e4: 0x0040, 0x7e5: 0x0040, 0x7e6: 0x0008, 0x7e7: 0x0008, 0x7e8: 0x0008, 0x7e9: 0x0008,\n\t0x7ea: 0x0008, 0x7eb: 0x0008, 0x7ec: 0x0008, 0x7ed: 0x0008, 0x7ee: 0x0008, 0x7ef: 0x0008,\n\t0x7f0: 0x0040, 0x7f1: 0x0040, 0x7f2: 0x0040, 0x7f3: 0x0040, 0x7f4: 0x0040, 0x7f5: 0x0040,\n\t0x7f6: 0x0040, 0x7f7: 0x0040, 0x7f8: 0x0018, 0x7f9: 0x0018, 0x7fa: 0x0018, 0x7fb: 0x0018,\n\t0x7fc: 0x0018, 0x7fd: 0x0018, 0x7fe: 0x0018, 0x7ff: 0x0018,\n\t// Block 0x20, offset 0x800\n\t0x800: 0x0008, 0x801: 0x3308, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x0040, 0x805: 0x0008,\n\t0x806: 0x0008, 0x807: 0x0008, 0x808: 0x0008, 0x809: 0x0008, 0x80a: 0x0008, 0x80b: 0x0008,\n\t0x80c: 0x0008, 0x80d: 0x0040, 0x80e: 0x0008, 0x80f: 0x0008, 0x810: 0x0008, 0x811: 0x0040,\n\t0x812: 0x0008, 0x813: 0x0008, 0x814: 0x0008, 0x815: 0x0008, 0x816: 0x0008, 0x817: 0x0008,\n\t0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0008, 0x81c: 0x0008, 0x81d: 0x0008,\n\t0x81e: 0x0008, 0x81f: 0x0008, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x0008, 0x823: 0x0008,\n\t0x824: 0x0008, 0x825: 0x0008, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0040,\n\t0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008,\n\t0x830: 0x0008, 0x831: 0x0008, 0x832: 0x0008, 0x833: 0x0008, 0x834: 0x0040, 0x835: 0x0008,\n\t0x836: 0x0008, 0x837: 0x0008, 0x838: 0x0008, 0x839: 0x0008, 0x83a: 0x0040, 0x83b: 0x0040,\n\t0x83c: 0x3308, 0x83d: 0x0008, 0x83e: 0x3008, 0x83f: 0x3308,\n\t// Block 0x21, offset 0x840\n\t0x840: 0x3008, 0x841: 0x3008, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x3008, 0x845: 0x0040,\n\t0x846: 0x3308, 0x847: 0x3008, 0x848: 0x3008, 0x849: 0x0040, 0x84a: 0x3008, 0x84b: 0x3008,\n\t0x84c: 0x3308, 0x84d: 0x3b08, 0x84e: 0x0040, 0x84f: 0x0040, 0x850: 0x0040, 0x851: 0x0040,\n\t0x852: 0x0040, 0x853: 0x0040, 0x854: 0x0040, 0x855: 0x3008, 0x856: 0x3008, 0x857: 0x0040,\n\t0x858: 0x0040, 0x859: 0x0040, 0x85a: 0x0040, 0x85b: 0x0040, 0x85c: 0x0040, 0x85d: 0x0040,\n\t0x85e: 0x0008, 0x85f: 0x0040, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x3308, 0x863: 0x3308,\n\t0x864: 0x0040, 0x865: 0x0040, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0008,\n\t0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008,\n\t0x870: 0x0040, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0040, 0x874: 0x0040, 0x875: 0x0040,\n\t0x876: 0x0040, 0x877: 0x0040, 0x878: 0x0040, 0x879: 0x0040, 0x87a: 0x0040, 0x87b: 0x0040,\n\t0x87c: 0x0040, 0x87d: 0x0040, 0x87e: 0x0040, 0x87f: 0x0040,\n\t// Block 0x22, offset 0x880\n\t0x880: 0x3008, 0x881: 0x3308, 0x882: 0x3308, 0x883: 0x3308, 0x884: 0x3308, 0x885: 0x0040,\n\t0x886: 0x3008, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008,\n\t0x88c: 0x3008, 0x88d: 0x3b08, 0x88e: 0x0008, 0x88f: 0x0018, 0x890: 0x0040, 0x891: 0x0040,\n\t0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0008, 0x895: 0x0008, 0x896: 0x0008, 0x897: 0x3008,\n\t0x898: 0x0018, 0x899: 0x0018, 0x89a: 0x0018, 0x89b: 0x0018, 0x89c: 0x0018, 0x89d: 0x0018,\n\t0x89e: 0x0018, 0x89f: 0x0008, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308,\n\t0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008,\n\t0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008,\n\t0x8b0: 0x0018, 0x8b1: 0x0018, 0x8b2: 0x0018, 0x8b3: 0x0018, 0x8b4: 0x0018, 0x8b5: 0x0018,\n\t0x8b6: 0x0018, 0x8b7: 0x0018, 0x8b8: 0x0018, 0x8b9: 0x0018, 0x8ba: 0x0008, 0x8bb: 0x0008,\n\t0x8bc: 0x0008, 0x8bd: 0x0008, 0x8be: 0x0008, 0x8bf: 0x0008,\n\t// Block 0x23, offset 0x8c0\n\t0x8c0: 0x0040, 0x8c1: 0x0008, 0x8c2: 0x0008, 0x8c3: 0x0040, 0x8c4: 0x0008, 0x8c5: 0x0040,\n\t0x8c6: 0x0040, 0x8c7: 0x0008, 0x8c8: 0x0008, 0x8c9: 0x0040, 0x8ca: 0x0008, 0x8cb: 0x0040,\n\t0x8cc: 0x0040, 0x8cd: 0x0008, 0x8ce: 0x0040, 0x8cf: 0x0040, 0x8d0: 0x0040, 0x8d1: 0x0040,\n\t0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x0008,\n\t0x8d8: 0x0040, 0x8d9: 0x0008, 0x8da: 0x0008, 0x8db: 0x0008, 0x8dc: 0x0008, 0x8dd: 0x0008,\n\t0x8de: 0x0008, 0x8df: 0x0008, 0x8e0: 0x0040, 0x8e1: 0x0008, 0x8e2: 0x0008, 0x8e3: 0x0008,\n\t0x8e4: 0x0040, 0x8e5: 0x0008, 0x8e6: 0x0040, 0x8e7: 0x0008, 0x8e8: 0x0040, 0x8e9: 0x0040,\n\t0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0040, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008,\n\t0x8f0: 0x0008, 0x8f1: 0x3308, 0x8f2: 0x0008, 0x8f3: 0x0929, 0x8f4: 0x3308, 0x8f5: 0x3308,\n\t0x8f6: 0x3308, 0x8f7: 0x3308, 0x8f8: 0x3308, 0x8f9: 0x3308, 0x8fa: 0x0040, 0x8fb: 0x3308,\n\t0x8fc: 0x3308, 0x8fd: 0x0008, 0x8fe: 0x0040, 0x8ff: 0x0040,\n\t// Block 0x24, offset 0x900\n\t0x900: 0x0008, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x09d1, 0x904: 0x0008, 0x905: 0x0008,\n\t0x906: 0x0008, 0x907: 0x0008, 0x908: 0x0040, 0x909: 0x0008, 0x90a: 0x0008, 0x90b: 0x0008,\n\t0x90c: 0x0008, 0x90d: 0x0a09, 0x90e: 0x0008, 0x90f: 0x0008, 0x910: 0x0008, 0x911: 0x0008,\n\t0x912: 0x0a41, 0x913: 0x0008, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0a79,\n\t0x918: 0x0008, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0ab1, 0x91d: 0x0008,\n\t0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0008, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008,\n\t0x924: 0x0008, 0x925: 0x0008, 0x926: 0x0008, 0x927: 0x0008, 0x928: 0x0008, 0x929: 0x0ae9,\n\t0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0008, 0x92d: 0x0040, 0x92e: 0x0040, 0x92f: 0x0040,\n\t0x930: 0x0040, 0x931: 0x3308, 0x932: 0x3308, 0x933: 0x0b21, 0x934: 0x3308, 0x935: 0x0b59,\n\t0x936: 0x0b91, 0x937: 0x0bc9, 0x938: 0x0c19, 0x939: 0x0c51, 0x93a: 0x3308, 0x93b: 0x3308,\n\t0x93c: 0x3308, 0x93d: 0x3308, 0x93e: 0x3308, 0x93f: 0x3008,\n\t// Block 0x25, offset 0x940\n\t0x940: 0x3308, 0x941: 0x0ca1, 0x942: 0x3308, 0x943: 0x3308, 0x944: 0x3b08, 0x945: 0x0018,\n\t0x946: 0x3308, 0x947: 0x3308, 0x948: 0x0008, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008,\n\t0x94c: 0x0008, 0x94d: 0x3308, 0x94e: 0x3308, 0x94f: 0x3308, 0x950: 0x3308, 0x951: 0x3308,\n\t0x952: 0x3308, 0x953: 0x0cd9, 0x954: 0x3308, 0x955: 0x3308, 0x956: 0x3308, 0x957: 0x3308,\n\t0x958: 0x0040, 0x959: 0x3308, 0x95a: 0x3308, 0x95b: 0x3308, 0x95c: 0x3308, 0x95d: 0x0d11,\n\t0x95e: 0x3308, 0x95f: 0x3308, 0x960: 0x3308, 0x961: 0x3308, 0x962: 0x0d49, 0x963: 0x3308,\n\t0x964: 0x3308, 0x965: 0x3308, 0x966: 0x3308, 0x967: 0x0d81, 0x968: 0x3308, 0x969: 0x3308,\n\t0x96a: 0x3308, 0x96b: 0x3308, 0x96c: 0x0db9, 0x96d: 0x3308, 0x96e: 0x3308, 0x96f: 0x3308,\n\t0x970: 0x3308, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x3308, 0x974: 0x3308, 0x975: 0x3308,\n\t0x976: 0x3308, 0x977: 0x3308, 0x978: 0x3308, 0x979: 0x0df1, 0x97a: 0x3308, 0x97b: 0x3308,\n\t0x97c: 0x3308, 0x97d: 0x0040, 0x97e: 0x0018, 0x97f: 0x0018,\n\t// Block 0x26, offset 0x980\n\t0x980: 0x0008, 0x981: 0x0008, 0x982: 0x0008, 0x983: 0x0008, 0x984: 0x0008, 0x985: 0x0008,\n\t0x986: 0x0008, 0x987: 0x0008, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008,\n\t0x98c: 0x0008, 0x98d: 0x0008, 0x98e: 0x0008, 0x98f: 0x0008, 0x990: 0x0008, 0x991: 0x0008,\n\t0x992: 0x0008, 0x993: 0x0008, 0x994: 0x0008, 0x995: 0x0008, 0x996: 0x0008, 0x997: 0x0008,\n\t0x998: 0x0008, 0x999: 0x0008, 0x99a: 0x0008, 0x99b: 0x0008, 0x99c: 0x0008, 0x99d: 0x0008,\n\t0x99e: 0x0008, 0x99f: 0x0008, 0x9a0: 0x0008, 0x9a1: 0x0008, 0x9a2: 0x0008, 0x9a3: 0x0008,\n\t0x9a4: 0x0008, 0x9a5: 0x0008, 0x9a6: 0x0008, 0x9a7: 0x0008, 0x9a8: 0x0008, 0x9a9: 0x0008,\n\t0x9aa: 0x0008, 0x9ab: 0x0008, 0x9ac: 0x0039, 0x9ad: 0x0ed1, 0x9ae: 0x0ee9, 0x9af: 0x0008,\n\t0x9b0: 0x0ef9, 0x9b1: 0x0f09, 0x9b2: 0x0f19, 0x9b3: 0x0f31, 0x9b4: 0x0249, 0x9b5: 0x0f41,\n\t0x9b6: 0x0259, 0x9b7: 0x0f51, 0x9b8: 0x0359, 0x9b9: 0x0f61, 0x9ba: 0x0f71, 0x9bb: 0x0008,\n\t0x9bc: 0x00d9, 0x9bd: 0x0f81, 0x9be: 0x0f99, 0x9bf: 0x0269,\n\t// Block 0x27, offset 0x9c0\n\t0x9c0: 0x0fa9, 0x9c1: 0x0fb9, 0x9c2: 0x0279, 0x9c3: 0x0039, 0x9c4: 0x0fc9, 0x9c5: 0x0fe1,\n\t0x9c6: 0x059d, 0x9c7: 0x0ee9, 0x9c8: 0x0ef9, 0x9c9: 0x0f09, 0x9ca: 0x0ff9, 0x9cb: 0x1011,\n\t0x9cc: 0x1029, 0x9cd: 0x0f31, 0x9ce: 0x0008, 0x9cf: 0x0f51, 0x9d0: 0x0f61, 0x9d1: 0x1041,\n\t0x9d2: 0x00d9, 0x9d3: 0x1059, 0x9d4: 0x05b5, 0x9d5: 0x05b5, 0x9d6: 0x0f99, 0x9d7: 0x0fa9,\n\t0x9d8: 0x0fb9, 0x9d9: 0x059d, 0x9da: 0x1071, 0x9db: 0x1089, 0x9dc: 0x05cd, 0x9dd: 0x1099,\n\t0x9de: 0x10b1, 0x9df: 0x10c9, 0x9e0: 0x10e1, 0x9e1: 0x10f9, 0x9e2: 0x0f41, 0x9e3: 0x0269,\n\t0x9e4: 0x0fb9, 0x9e5: 0x1089, 0x9e6: 0x1099, 0x9e7: 0x10b1, 0x9e8: 0x1111, 0x9e9: 0x10e1,\n\t0x9ea: 0x10f9, 0x9eb: 0x0008, 0x9ec: 0x0008, 0x9ed: 0x0008, 0x9ee: 0x0008, 0x9ef: 0x0008,\n\t0x9f0: 0x0008, 0x9f1: 0x0008, 0x9f2: 0x0008, 0x9f3: 0x0008, 0x9f4: 0x0008, 0x9f5: 0x0008,\n\t0x9f6: 0x0008, 0x9f7: 0x0008, 0x9f8: 0x1129, 0x9f9: 0x0008, 0x9fa: 0x0008, 0x9fb: 0x0008,\n\t0x9fc: 0x0008, 0x9fd: 0x0008, 0x9fe: 0x0008, 0x9ff: 0x0008,\n\t// Block 0x28, offset 0xa00\n\t0xa00: 0x0008, 0xa01: 0x0008, 0xa02: 0x0008, 0xa03: 0x0008, 0xa04: 0x0008, 0xa05: 0x0008,\n\t0xa06: 0x0008, 0xa07: 0x0008, 0xa08: 0x0008, 0xa09: 0x0008, 0xa0a: 0x0008, 0xa0b: 0x0008,\n\t0xa0c: 0x0008, 0xa0d: 0x0008, 0xa0e: 0x0008, 0xa0f: 0x0008, 0xa10: 0x0008, 0xa11: 0x0008,\n\t0xa12: 0x0008, 0xa13: 0x0008, 0xa14: 0x0008, 0xa15: 0x0008, 0xa16: 0x0008, 0xa17: 0x0008,\n\t0xa18: 0x0008, 0xa19: 0x0008, 0xa1a: 0x0008, 0xa1b: 0x1141, 0xa1c: 0x1159, 0xa1d: 0x1169,\n\t0xa1e: 0x1181, 0xa1f: 0x1029, 0xa20: 0x1199, 0xa21: 0x11a9, 0xa22: 0x11c1, 0xa23: 0x11d9,\n\t0xa24: 0x11f1, 0xa25: 0x1209, 0xa26: 0x1221, 0xa27: 0x05e5, 0xa28: 0x1239, 0xa29: 0x1251,\n\t0xa2a: 0xe17d, 0xa2b: 0x1269, 0xa2c: 0x1281, 0xa2d: 0x1299, 0xa2e: 0x12b1, 0xa2f: 0x12c9,\n\t0xa30: 0x12e1, 0xa31: 0x12f9, 0xa32: 0x1311, 0xa33: 0x1329, 0xa34: 0x1341, 0xa35: 0x1359,\n\t0xa36: 0x1371, 0xa37: 0x1389, 0xa38: 0x05fd, 0xa39: 0x13a1, 0xa3a: 0x13b9, 0xa3b: 0x13d1,\n\t0xa3c: 0x13e1, 0xa3d: 0x13f9, 0xa3e: 0x1411, 0xa3f: 0x1429,\n\t// Block 0x29, offset 0xa40\n\t0xa40: 0xe00d, 0xa41: 0x0008, 0xa42: 0xe00d, 0xa43: 0x0008, 0xa44: 0xe00d, 0xa45: 0x0008,\n\t0xa46: 0xe00d, 0xa47: 0x0008, 0xa48: 0xe00d, 0xa49: 0x0008, 0xa4a: 0xe00d, 0xa4b: 0x0008,\n\t0xa4c: 0xe00d, 0xa4d: 0x0008, 0xa4e: 0xe00d, 0xa4f: 0x0008, 0xa50: 0xe00d, 0xa51: 0x0008,\n\t0xa52: 0xe00d, 0xa53: 0x0008, 0xa54: 0xe00d, 0xa55: 0x0008, 0xa56: 0xe00d, 0xa57: 0x0008,\n\t0xa58: 0xe00d, 0xa59: 0x0008, 0xa5a: 0xe00d, 0xa5b: 0x0008, 0xa5c: 0xe00d, 0xa5d: 0x0008,\n\t0xa5e: 0xe00d, 0xa5f: 0x0008, 0xa60: 0xe00d, 0xa61: 0x0008, 0xa62: 0xe00d, 0xa63: 0x0008,\n\t0xa64: 0xe00d, 0xa65: 0x0008, 0xa66: 0xe00d, 0xa67: 0x0008, 0xa68: 0xe00d, 0xa69: 0x0008,\n\t0xa6a: 0xe00d, 0xa6b: 0x0008, 0xa6c: 0xe00d, 0xa6d: 0x0008, 0xa6e: 0xe00d, 0xa6f: 0x0008,\n\t0xa70: 0xe00d, 0xa71: 0x0008, 0xa72: 0xe00d, 0xa73: 0x0008, 0xa74: 0xe00d, 0xa75: 0x0008,\n\t0xa76: 0xe00d, 0xa77: 0x0008, 0xa78: 0xe00d, 0xa79: 0x0008, 0xa7a: 0xe00d, 0xa7b: 0x0008,\n\t0xa7c: 0xe00d, 0xa7d: 0x0008, 0xa7e: 0xe00d, 0xa7f: 0x0008,\n\t// Block 0x2a, offset 0xa80\n\t0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008,\n\t0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008,\n\t0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008,\n\t0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0x0008, 0xa97: 0x0008,\n\t0xa98: 0x0008, 0xa99: 0x0008, 0xa9a: 0x0615, 0xa9b: 0x0635, 0xa9c: 0x0008, 0xa9d: 0x0008,\n\t0xa9e: 0x1441, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008,\n\t0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008,\n\t0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008,\n\t0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008,\n\t0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008,\n\t0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008,\n\t// Block 0x2b, offset 0xac0\n\t0xac0: 0x0008, 0xac1: 0x0008, 0xac2: 0x0008, 0xac3: 0x0008, 0xac4: 0x0008, 0xac5: 0x0008,\n\t0xac6: 0x0040, 0xac7: 0x0040, 0xac8: 0xe045, 0xac9: 0xe045, 0xaca: 0xe045, 0xacb: 0xe045,\n\t0xacc: 0xe045, 0xacd: 0xe045, 0xace: 0x0040, 0xacf: 0x0040, 0xad0: 0x0008, 0xad1: 0x0008,\n\t0xad2: 0x0008, 0xad3: 0x0008, 0xad4: 0x0008, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008,\n\t0xad8: 0x0040, 0xad9: 0xe045, 0xada: 0x0040, 0xadb: 0xe045, 0xadc: 0x0040, 0xadd: 0xe045,\n\t0xade: 0x0040, 0xadf: 0xe045, 0xae0: 0x0008, 0xae1: 0x0008, 0xae2: 0x0008, 0xae3: 0x0008,\n\t0xae4: 0x0008, 0xae5: 0x0008, 0xae6: 0x0008, 0xae7: 0x0008, 0xae8: 0xe045, 0xae9: 0xe045,\n\t0xaea: 0xe045, 0xaeb: 0xe045, 0xaec: 0xe045, 0xaed: 0xe045, 0xaee: 0xe045, 0xaef: 0xe045,\n\t0xaf0: 0x0008, 0xaf1: 0x1459, 0xaf2: 0x0008, 0xaf3: 0x1471, 0xaf4: 0x0008, 0xaf5: 0x1489,\n\t0xaf6: 0x0008, 0xaf7: 0x14a1, 0xaf8: 0x0008, 0xaf9: 0x14b9, 0xafa: 0x0008, 0xafb: 0x14d1,\n\t0xafc: 0x0008, 0xafd: 0x14e9, 0xafe: 0x0040, 0xaff: 0x0040,\n\t// Block 0x2c, offset 0xb00\n\t0xb00: 0x1501, 0xb01: 0x1531, 0xb02: 0x1561, 0xb03: 0x1591, 0xb04: 0x15c1, 0xb05: 0x15f1,\n\t0xb06: 0x1621, 0xb07: 0x1651, 0xb08: 0x1501, 0xb09: 0x1531, 0xb0a: 0x1561, 0xb0b: 0x1591,\n\t0xb0c: 0x15c1, 0xb0d: 0x15f1, 0xb0e: 0x1621, 0xb0f: 0x1651, 0xb10: 0x1681, 0xb11: 0x16b1,\n\t0xb12: 0x16e1, 0xb13: 0x1711, 0xb14: 0x1741, 0xb15: 0x1771, 0xb16: 0x17a1, 0xb17: 0x17d1,\n\t0xb18: 0x1681, 0xb19: 0x16b1, 0xb1a: 0x16e1, 0xb1b: 0x1711, 0xb1c: 0x1741, 0xb1d: 0x1771,\n\t0xb1e: 0x17a1, 0xb1f: 0x17d1, 0xb20: 0x1801, 0xb21: 0x1831, 0xb22: 0x1861, 0xb23: 0x1891,\n\t0xb24: 0x18c1, 0xb25: 0x18f1, 0xb26: 0x1921, 0xb27: 0x1951, 0xb28: 0x1801, 0xb29: 0x1831,\n\t0xb2a: 0x1861, 0xb2b: 0x1891, 0xb2c: 0x18c1, 0xb2d: 0x18f1, 0xb2e: 0x1921, 0xb2f: 0x1951,\n\t0xb30: 0x0008, 0xb31: 0x0008, 0xb32: 0x1981, 0xb33: 0x19b1, 0xb34: 0x19d9, 0xb35: 0x0040,\n\t0xb36: 0x0008, 0xb37: 0x1a01, 0xb38: 0xe045, 0xb39: 0xe045, 0xb3a: 0x064d, 0xb3b: 0x1459,\n\t0xb3c: 0x19b1, 0xb3d: 0x0666, 0xb3e: 0x1a31, 0xb3f: 0x0686,\n\t// Block 0x2d, offset 0xb40\n\t0xb40: 0x06a6, 0xb41: 0x1a4a, 0xb42: 0x1a79, 0xb43: 0x1aa9, 0xb44: 0x1ad1, 0xb45: 0x0040,\n\t0xb46: 0x0008, 0xb47: 0x1af9, 0xb48: 0x06c5, 0xb49: 0x1471, 0xb4a: 0x06dd, 0xb4b: 0x1489,\n\t0xb4c: 0x1aa9, 0xb4d: 0x1b2a, 0xb4e: 0x1b5a, 0xb4f: 0x1b8a, 0xb50: 0x0008, 0xb51: 0x0008,\n\t0xb52: 0x0008, 0xb53: 0x1bb9, 0xb54: 0x0040, 0xb55: 0x0040, 0xb56: 0x0008, 0xb57: 0x0008,\n\t0xb58: 0xe045, 0xb59: 0xe045, 0xb5a: 0x06f5, 0xb5b: 0x14a1, 0xb5c: 0x0040, 0xb5d: 0x1bd2,\n\t0xb5e: 0x1c02, 0xb5f: 0x1c32, 0xb60: 0x0008, 0xb61: 0x0008, 0xb62: 0x0008, 0xb63: 0x1c61,\n\t0xb64: 0x0008, 0xb65: 0x0008, 0xb66: 0x0008, 0xb67: 0x0008, 0xb68: 0xe045, 0xb69: 0xe045,\n\t0xb6a: 0x070d, 0xb6b: 0x14d1, 0xb6c: 0xe04d, 0xb6d: 0x1c7a, 0xb6e: 0x03d2, 0xb6f: 0x1caa,\n\t0xb70: 0x0040, 0xb71: 0x0040, 0xb72: 0x1cb9, 0xb73: 0x1ce9, 0xb74: 0x1d11, 0xb75: 0x0040,\n\t0xb76: 0x0008, 0xb77: 0x1d39, 0xb78: 0x0725, 0xb79: 0x14b9, 0xb7a: 0x0515, 0xb7b: 0x14e9,\n\t0xb7c: 0x1ce9, 0xb7d: 0x073e, 0xb7e: 0x075e, 0xb7f: 0x0040,\n\t// Block 0x2e, offset 0xb80\n\t0xb80: 0x000a, 0xb81: 0x000a, 0xb82: 0x000a, 0xb83: 0x000a, 0xb84: 0x000a, 0xb85: 0x000a,\n\t0xb86: 0x000a, 0xb87: 0x000a, 0xb88: 0x000a, 0xb89: 0x000a, 0xb8a: 0x000a, 0xb8b: 0x03c0,\n\t0xb8c: 0x0003, 0xb8d: 0x0003, 0xb8e: 0x0340, 0xb8f: 0x0b40, 0xb90: 0x0018, 0xb91: 0xe00d,\n\t0xb92: 0x0018, 0xb93: 0x0018, 0xb94: 0x0018, 0xb95: 0x0018, 0xb96: 0x0018, 0xb97: 0x077e,\n\t0xb98: 0x0018, 0xb99: 0x0018, 0xb9a: 0x0018, 0xb9b: 0x0018, 0xb9c: 0x0018, 0xb9d: 0x0018,\n\t0xb9e: 0x0018, 0xb9f: 0x0018, 0xba0: 0x0018, 0xba1: 0x0018, 0xba2: 0x0018, 0xba3: 0x0018,\n\t0xba4: 0x0040, 0xba5: 0x0040, 0xba6: 0x0040, 0xba7: 0x0018, 0xba8: 0x0040, 0xba9: 0x0040,\n\t0xbaa: 0x0340, 0xbab: 0x0340, 0xbac: 0x0340, 0xbad: 0x0340, 0xbae: 0x0340, 0xbaf: 0x000a,\n\t0xbb0: 0x0018, 0xbb1: 0x0018, 0xbb2: 0x0018, 0xbb3: 0x1d69, 0xbb4: 0x1da1, 0xbb5: 0x0018,\n\t0xbb6: 0x1df1, 0xbb7: 0x1e29, 0xbb8: 0x0018, 0xbb9: 0x0018, 0xbba: 0x0018, 0xbbb: 0x0018,\n\t0xbbc: 0x1e7a, 0xbbd: 0x0018, 0xbbe: 0x079e, 0xbbf: 0x0018,\n\t// Block 0x2f, offset 0xbc0\n\t0xbc0: 0x0018, 0xbc1: 0x0018, 0xbc2: 0x0018, 0xbc3: 0x0018, 0xbc4: 0x0018, 0xbc5: 0x0018,\n\t0xbc6: 0x0018, 0xbc7: 0x1e92, 0xbc8: 0x1eaa, 0xbc9: 0x1ec2, 0xbca: 0x0018, 0xbcb: 0x0018,\n\t0xbcc: 0x0018, 0xbcd: 0x0018, 0xbce: 0x0018, 0xbcf: 0x0018, 0xbd0: 0x0018, 0xbd1: 0x0018,\n\t0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x1ed9,\n\t0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018,\n\t0xbde: 0x0018, 0xbdf: 0x000a, 0xbe0: 0x03c0, 0xbe1: 0x0340, 0xbe2: 0x0340, 0xbe3: 0x0340,\n\t0xbe4: 0x03c0, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0040, 0xbe8: 0x0040, 0xbe9: 0x0040,\n\t0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x0340,\n\t0xbf0: 0x1f41, 0xbf1: 0x0f41, 0xbf2: 0x0040, 0xbf3: 0x0040, 0xbf4: 0x1f51, 0xbf5: 0x1f61,\n\t0xbf6: 0x1f71, 0xbf7: 0x1f81, 0xbf8: 0x1f91, 0xbf9: 0x1fa1, 0xbfa: 0x1fb2, 0xbfb: 0x07bd,\n\t0xbfc: 0x1fc2, 0xbfd: 0x1fd2, 0xbfe: 0x1fe2, 0xbff: 0x0f71,\n\t// Block 0x30, offset 0xc00\n\t0xc00: 0x1f41, 0xc01: 0x00c9, 0xc02: 0x0069, 0xc03: 0x0079, 0xc04: 0x1f51, 0xc05: 0x1f61,\n\t0xc06: 0x1f71, 0xc07: 0x1f81, 0xc08: 0x1f91, 0xc09: 0x1fa1, 0xc0a: 0x1fb2, 0xc0b: 0x07d5,\n\t0xc0c: 0x1fc2, 0xc0d: 0x1fd2, 0xc0e: 0x1fe2, 0xc0f: 0x0040, 0xc10: 0x0039, 0xc11: 0x0f09,\n\t0xc12: 0x00d9, 0xc13: 0x0369, 0xc14: 0x0ff9, 0xc15: 0x0249, 0xc16: 0x0f51, 0xc17: 0x0359,\n\t0xc18: 0x0f61, 0xc19: 0x0f71, 0xc1a: 0x0f99, 0xc1b: 0x01d9, 0xc1c: 0x0fa9, 0xc1d: 0x0040,\n\t0xc1e: 0x0040, 0xc1f: 0x0040, 0xc20: 0x0018, 0xc21: 0x0018, 0xc22: 0x0018, 0xc23: 0x0018,\n\t0xc24: 0x0018, 0xc25: 0x0018, 0xc26: 0x0018, 0xc27: 0x0018, 0xc28: 0x1ff1, 0xc29: 0x0018,\n\t0xc2a: 0x0018, 0xc2b: 0x0018, 0xc2c: 0x0018, 0xc2d: 0x0018, 0xc2e: 0x0018, 0xc2f: 0x0018,\n\t0xc30: 0x0018, 0xc31: 0x0018, 0xc32: 0x0018, 0xc33: 0x0018, 0xc34: 0x0018, 0xc35: 0x0018,\n\t0xc36: 0x0018, 0xc37: 0x0018, 0xc38: 0x0018, 0xc39: 0x0018, 0xc3a: 0x0018, 0xc3b: 0x0018,\n\t0xc3c: 0x0018, 0xc3d: 0x0018, 0xc3e: 0x0018, 0xc3f: 0x0040,\n\t// Block 0x31, offset 0xc40\n\t0xc40: 0x07ee, 0xc41: 0x080e, 0xc42: 0x1159, 0xc43: 0x082d, 0xc44: 0x0018, 0xc45: 0x084e,\n\t0xc46: 0x086e, 0xc47: 0x1011, 0xc48: 0x0018, 0xc49: 0x088d, 0xc4a: 0x0f31, 0xc4b: 0x0249,\n\t0xc4c: 0x0249, 0xc4d: 0x0249, 0xc4e: 0x0249, 0xc4f: 0x2009, 0xc50: 0x0f41, 0xc51: 0x0f41,\n\t0xc52: 0x0359, 0xc53: 0x0359, 0xc54: 0x0018, 0xc55: 0x0f71, 0xc56: 0x2021, 0xc57: 0x0018,\n\t0xc58: 0x0018, 0xc59: 0x0f99, 0xc5a: 0x2039, 0xc5b: 0x0269, 0xc5c: 0x0269, 0xc5d: 0x0269,\n\t0xc5e: 0x0018, 0xc5f: 0x0018, 0xc60: 0x2049, 0xc61: 0x08ad, 0xc62: 0x2061, 0xc63: 0x0018,\n\t0xc64: 0x13d1, 0xc65: 0x0018, 0xc66: 0x2079, 0xc67: 0x0018, 0xc68: 0x13d1, 0xc69: 0x0018,\n\t0xc6a: 0x0f51, 0xc6b: 0x2091, 0xc6c: 0x0ee9, 0xc6d: 0x1159, 0xc6e: 0x0018, 0xc6f: 0x0f09,\n\t0xc70: 0x0f09, 0xc71: 0x1199, 0xc72: 0x0040, 0xc73: 0x0f61, 0xc74: 0x00d9, 0xc75: 0x20a9,\n\t0xc76: 0x20c1, 0xc77: 0x20d9, 0xc78: 0x20f1, 0xc79: 0x0f41, 0xc7a: 0x0018, 0xc7b: 0x08cd,\n\t0xc7c: 0x2109, 0xc7d: 0x10b1, 0xc7e: 0x10b1, 0xc7f: 0x2109,\n\t// Block 0x32, offset 0xc80\n\t0xc80: 0x08ed, 0xc81: 0x0018, 0xc82: 0x0018, 0xc83: 0x0018, 0xc84: 0x0018, 0xc85: 0x0ef9,\n\t0xc86: 0x0ef9, 0xc87: 0x0f09, 0xc88: 0x0f41, 0xc89: 0x0259, 0xc8a: 0x0018, 0xc8b: 0x0018,\n\t0xc8c: 0x0018, 0xc8d: 0x0018, 0xc8e: 0x0008, 0xc8f: 0x0018, 0xc90: 0x2121, 0xc91: 0x2151,\n\t0xc92: 0x2181, 0xc93: 0x21b9, 0xc94: 0x21e9, 0xc95: 0x2219, 0xc96: 0x2249, 0xc97: 0x2279,\n\t0xc98: 0x22a9, 0xc99: 0x22d9, 0xc9a: 0x2309, 0xc9b: 0x2339, 0xc9c: 0x2369, 0xc9d: 0x2399,\n\t0xc9e: 0x23c9, 0xc9f: 0x23f9, 0xca0: 0x0f41, 0xca1: 0x2421, 0xca2: 0x0905, 0xca3: 0x2439,\n\t0xca4: 0x1089, 0xca5: 0x2451, 0xca6: 0x0925, 0xca7: 0x2469, 0xca8: 0x2491, 0xca9: 0x0369,\n\t0xcaa: 0x24a9, 0xcab: 0x0945, 0xcac: 0x0359, 0xcad: 0x1159, 0xcae: 0x0ef9, 0xcaf: 0x0f61,\n\t0xcb0: 0x0f41, 0xcb1: 0x2421, 0xcb2: 0x0965, 0xcb3: 0x2439, 0xcb4: 0x1089, 0xcb5: 0x2451,\n\t0xcb6: 0x0985, 0xcb7: 0x2469, 0xcb8: 0x2491, 0xcb9: 0x0369, 0xcba: 0x24a9, 0xcbb: 0x09a5,\n\t0xcbc: 0x0359, 0xcbd: 0x1159, 0xcbe: 0x0ef9, 0xcbf: 0x0f61,\n\t// Block 0x33, offset 0xcc0\n\t0xcc0: 0x0018, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x0018,\n\t0xcc6: 0x0018, 0xcc7: 0x0018, 0xcc8: 0x0018, 0xcc9: 0x0018, 0xcca: 0x0018, 0xccb: 0x0040,\n\t0xccc: 0x0040, 0xccd: 0x0040, 0xcce: 0x0040, 0xccf: 0x0040, 0xcd0: 0x0040, 0xcd1: 0x0040,\n\t0xcd2: 0x0040, 0xcd3: 0x0040, 0xcd4: 0x0040, 0xcd5: 0x0040, 0xcd6: 0x0040, 0xcd7: 0x0040,\n\t0xcd8: 0x0040, 0xcd9: 0x0040, 0xcda: 0x0040, 0xcdb: 0x0040, 0xcdc: 0x0040, 0xcdd: 0x0040,\n\t0xcde: 0x0040, 0xcdf: 0x0040, 0xce0: 0x00c9, 0xce1: 0x0069, 0xce2: 0x0079, 0xce3: 0x1f51,\n\t0xce4: 0x1f61, 0xce5: 0x1f71, 0xce6: 0x1f81, 0xce7: 0x1f91, 0xce8: 0x1fa1, 0xce9: 0x2601,\n\t0xcea: 0x2619, 0xceb: 0x2631, 0xcec: 0x2649, 0xced: 0x2661, 0xcee: 0x2679, 0xcef: 0x2691,\n\t0xcf0: 0x26a9, 0xcf1: 0x26c1, 0xcf2: 0x26d9, 0xcf3: 0x26f1, 0xcf4: 0x0a06, 0xcf5: 0x0a26,\n\t0xcf6: 0x0a46, 0xcf7: 0x0a66, 0xcf8: 0x0a86, 0xcf9: 0x0aa6, 0xcfa: 0x0ac6, 0xcfb: 0x0ae6,\n\t0xcfc: 0x0b06, 0xcfd: 0x270a, 0xcfe: 0x2732, 0xcff: 0x275a,\n\t// Block 0x34, offset 0xd00\n\t0xd00: 0x2782, 0xd01: 0x27aa, 0xd02: 0x27d2, 0xd03: 0x27fa, 0xd04: 0x2822, 0xd05: 0x284a,\n\t0xd06: 0x2872, 0xd07: 0x289a, 0xd08: 0x0040, 0xd09: 0x0040, 0xd0a: 0x0040, 0xd0b: 0x0040,\n\t0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040,\n\t0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040,\n\t0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0b26, 0xd1d: 0x0b46,\n\t0xd1e: 0x0b66, 0xd1f: 0x0b86, 0xd20: 0x0ba6, 0xd21: 0x0bc6, 0xd22: 0x0be6, 0xd23: 0x0c06,\n\t0xd24: 0x0c26, 0xd25: 0x0c46, 0xd26: 0x0c66, 0xd27: 0x0c86, 0xd28: 0x0ca6, 0xd29: 0x0cc6,\n\t0xd2a: 0x0ce6, 0xd2b: 0x0d06, 0xd2c: 0x0d26, 0xd2d: 0x0d46, 0xd2e: 0x0d66, 0xd2f: 0x0d86,\n\t0xd30: 0x0da6, 0xd31: 0x0dc6, 0xd32: 0x0de6, 0xd33: 0x0e06, 0xd34: 0x0e26, 0xd35: 0x0e46,\n\t0xd36: 0x0039, 0xd37: 0x0ee9, 0xd38: 0x1159, 0xd39: 0x0ef9, 0xd3a: 0x0f09, 0xd3b: 0x1199,\n\t0xd3c: 0x0f31, 0xd3d: 0x0249, 0xd3e: 0x0f41, 0xd3f: 0x0259,\n\t// Block 0x35, offset 0xd40\n\t0xd40: 0x0f51, 0xd41: 0x0359, 0xd42: 0x0f61, 0xd43: 0x0f71, 0xd44: 0x00d9, 0xd45: 0x0f99,\n\t0xd46: 0x2039, 0xd47: 0x0269, 0xd48: 0x01d9, 0xd49: 0x0fa9, 0xd4a: 0x0fb9, 0xd4b: 0x1089,\n\t0xd4c: 0x0279, 0xd4d: 0x0369, 0xd4e: 0x0289, 0xd4f: 0x13d1, 0xd50: 0x0039, 0xd51: 0x0ee9,\n\t0xd52: 0x1159, 0xd53: 0x0ef9, 0xd54: 0x0f09, 0xd55: 0x1199, 0xd56: 0x0f31, 0xd57: 0x0249,\n\t0xd58: 0x0f41, 0xd59: 0x0259, 0xd5a: 0x0f51, 0xd5b: 0x0359, 0xd5c: 0x0f61, 0xd5d: 0x0f71,\n\t0xd5e: 0x00d9, 0xd5f: 0x0f99, 0xd60: 0x2039, 0xd61: 0x0269, 0xd62: 0x01d9, 0xd63: 0x0fa9,\n\t0xd64: 0x0fb9, 0xd65: 0x1089, 0xd66: 0x0279, 0xd67: 0x0369, 0xd68: 0x0289, 0xd69: 0x13d1,\n\t0xd6a: 0x1f41, 0xd6b: 0x0018, 0xd6c: 0x0018, 0xd6d: 0x0018, 0xd6e: 0x0018, 0xd6f: 0x0018,\n\t0xd70: 0x0018, 0xd71: 0x0018, 0xd72: 0x0018, 0xd73: 0x0018, 0xd74: 0x0018, 0xd75: 0x0018,\n\t0xd76: 0x0018, 0xd77: 0x0018, 0xd78: 0x0018, 0xd79: 0x0018, 0xd7a: 0x0018, 0xd7b: 0x0018,\n\t0xd7c: 0x0018, 0xd7d: 0x0018, 0xd7e: 0x0018, 0xd7f: 0x0018,\n\t// Block 0x36, offset 0xd80\n\t0xd80: 0x0008, 0xd81: 0x0008, 0xd82: 0x0008, 0xd83: 0x0008, 0xd84: 0x0008, 0xd85: 0x0008,\n\t0xd86: 0x0008, 0xd87: 0x0008, 0xd88: 0x0008, 0xd89: 0x0008, 0xd8a: 0x0008, 0xd8b: 0x0008,\n\t0xd8c: 0x0008, 0xd8d: 0x0008, 0xd8e: 0x0008, 0xd8f: 0x0008, 0xd90: 0x0008, 0xd91: 0x0008,\n\t0xd92: 0x0008, 0xd93: 0x0008, 0xd94: 0x0008, 0xd95: 0x0008, 0xd96: 0x0008, 0xd97: 0x0008,\n\t0xd98: 0x0008, 0xd99: 0x0008, 0xd9a: 0x0008, 0xd9b: 0x0008, 0xd9c: 0x0008, 0xd9d: 0x0008,\n\t0xd9e: 0x0008, 0xd9f: 0x0040, 0xda0: 0xe00d, 0xda1: 0x0008, 0xda2: 0x2971, 0xda3: 0x0ebd,\n\t0xda4: 0x2989, 0xda5: 0x0008, 0xda6: 0x0008, 0xda7: 0xe07d, 0xda8: 0x0008, 0xda9: 0xe01d,\n\t0xdaa: 0x0008, 0xdab: 0xe03d, 0xdac: 0x0008, 0xdad: 0x0fe1, 0xdae: 0x1281, 0xdaf: 0x0fc9,\n\t0xdb0: 0x1141, 0xdb1: 0x0008, 0xdb2: 0xe00d, 0xdb3: 0x0008, 0xdb4: 0x0008, 0xdb5: 0xe01d,\n\t0xdb6: 0x0008, 0xdb7: 0x0008, 0xdb8: 0x0008, 0xdb9: 0x0008, 0xdba: 0x0008, 0xdbb: 0x0008,\n\t0xdbc: 0x0259, 0xdbd: 0x1089, 0xdbe: 0x29a1, 0xdbf: 0x29b9,\n\t// Block 0x37, offset 0xdc0\n\t0xdc0: 0xe00d, 0xdc1: 0x0008, 0xdc2: 0xe00d, 0xdc3: 0x0008, 0xdc4: 0xe00d, 0xdc5: 0x0008,\n\t0xdc6: 0xe00d, 0xdc7: 0x0008, 0xdc8: 0xe00d, 0xdc9: 0x0008, 0xdca: 0xe00d, 0xdcb: 0x0008,\n\t0xdcc: 0xe00d, 0xdcd: 0x0008, 0xdce: 0xe00d, 0xdcf: 0x0008, 0xdd0: 0xe00d, 0xdd1: 0x0008,\n\t0xdd2: 0xe00d, 0xdd3: 0x0008, 0xdd4: 0xe00d, 0xdd5: 0x0008, 0xdd6: 0xe00d, 0xdd7: 0x0008,\n\t0xdd8: 0xe00d, 0xdd9: 0x0008, 0xdda: 0xe00d, 0xddb: 0x0008, 0xddc: 0xe00d, 0xddd: 0x0008,\n\t0xdde: 0xe00d, 0xddf: 0x0008, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0xe00d, 0xde3: 0x0008,\n\t0xde4: 0x0008, 0xde5: 0x0018, 0xde6: 0x0018, 0xde7: 0x0018, 0xde8: 0x0018, 0xde9: 0x0018,\n\t0xdea: 0x0018, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0xe01d, 0xdee: 0x0008, 0xdef: 0x3308,\n\t0xdf0: 0x3308, 0xdf1: 0x3308, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0040, 0xdf5: 0x0040,\n\t0xdf6: 0x0040, 0xdf7: 0x0040, 0xdf8: 0x0040, 0xdf9: 0x0018, 0xdfa: 0x0018, 0xdfb: 0x0018,\n\t0xdfc: 0x0018, 0xdfd: 0x0018, 0xdfe: 0x0018, 0xdff: 0x0018,\n\t// Block 0x38, offset 0xe00\n\t0xe00: 0x26fd, 0xe01: 0x271d, 0xe02: 0x273d, 0xe03: 0x275d, 0xe04: 0x277d, 0xe05: 0x279d,\n\t0xe06: 0x27bd, 0xe07: 0x27dd, 0xe08: 0x27fd, 0xe09: 0x281d, 0xe0a: 0x283d, 0xe0b: 0x285d,\n\t0xe0c: 0x287d, 0xe0d: 0x289d, 0xe0e: 0x28bd, 0xe0f: 0x28dd, 0xe10: 0x28fd, 0xe11: 0x291d,\n\t0xe12: 0x293d, 0xe13: 0x295d, 0xe14: 0x297d, 0xe15: 0x299d, 0xe16: 0x0040, 0xe17: 0x0040,\n\t0xe18: 0x0040, 0xe19: 0x0040, 0xe1a: 0x0040, 0xe1b: 0x0040, 0xe1c: 0x0040, 0xe1d: 0x0040,\n\t0xe1e: 0x0040, 0xe1f: 0x0040, 0xe20: 0x0040, 0xe21: 0x0040, 0xe22: 0x0040, 0xe23: 0x0040,\n\t0xe24: 0x0040, 0xe25: 0x0040, 0xe26: 0x0040, 0xe27: 0x0040, 0xe28: 0x0040, 0xe29: 0x0040,\n\t0xe2a: 0x0040, 0xe2b: 0x0040, 0xe2c: 0x0040, 0xe2d: 0x0040, 0xe2e: 0x0040, 0xe2f: 0x0040,\n\t0xe30: 0x0040, 0xe31: 0x0040, 0xe32: 0x0040, 0xe33: 0x0040, 0xe34: 0x0040, 0xe35: 0x0040,\n\t0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0040, 0xe3a: 0x0040, 0xe3b: 0x0040,\n\t0xe3c: 0x0040, 0xe3d: 0x0040, 0xe3e: 0x0040, 0xe3f: 0x0040,\n\t// Block 0x39, offset 0xe40\n\t0xe40: 0x000a, 0xe41: 0x0018, 0xe42: 0x29d1, 0xe43: 0x0018, 0xe44: 0x0018, 0xe45: 0x0008,\n\t0xe46: 0x0008, 0xe47: 0x0008, 0xe48: 0x0018, 0xe49: 0x0018, 0xe4a: 0x0018, 0xe4b: 0x0018,\n\t0xe4c: 0x0018, 0xe4d: 0x0018, 0xe4e: 0x0018, 0xe4f: 0x0018, 0xe50: 0x0018, 0xe51: 0x0018,\n\t0xe52: 0x0018, 0xe53: 0x0018, 0xe54: 0x0018, 0xe55: 0x0018, 0xe56: 0x0018, 0xe57: 0x0018,\n\t0xe58: 0x0018, 0xe59: 0x0018, 0xe5a: 0x0018, 0xe5b: 0x0018, 0xe5c: 0x0018, 0xe5d: 0x0018,\n\t0xe5e: 0x0018, 0xe5f: 0x0018, 0xe60: 0x0018, 0xe61: 0x0018, 0xe62: 0x0018, 0xe63: 0x0018,\n\t0xe64: 0x0018, 0xe65: 0x0018, 0xe66: 0x0018, 0xe67: 0x0018, 0xe68: 0x0018, 0xe69: 0x0018,\n\t0xe6a: 0x3308, 0xe6b: 0x3308, 0xe6c: 0x3308, 0xe6d: 0x3308, 0xe6e: 0x3018, 0xe6f: 0x3018,\n\t0xe70: 0x0018, 0xe71: 0x0018, 0xe72: 0x0018, 0xe73: 0x0018, 0xe74: 0x0018, 0xe75: 0x0018,\n\t0xe76: 0xe125, 0xe77: 0x0018, 0xe78: 0x29bd, 0xe79: 0x29dd, 0xe7a: 0x29fd, 0xe7b: 0x0018,\n\t0xe7c: 0x0008, 0xe7d: 0x0018, 0xe7e: 0x0018, 0xe7f: 0x0018,\n\t// Block 0x3a, offset 0xe80\n\t0xe80: 0x2b3d, 0xe81: 0x2b5d, 0xe82: 0x2b7d, 0xe83: 0x2b9d, 0xe84: 0x2bbd, 0xe85: 0x2bdd,\n\t0xe86: 0x2bdd, 0xe87: 0x2bdd, 0xe88: 0x2bfd, 0xe89: 0x2bfd, 0xe8a: 0x2bfd, 0xe8b: 0x2bfd,\n\t0xe8c: 0x2c1d, 0xe8d: 0x2c1d, 0xe8e: 0x2c1d, 0xe8f: 0x2c3d, 0xe90: 0x2c5d, 0xe91: 0x2c5d,\n\t0xe92: 0x2a7d, 0xe93: 0x2a7d, 0xe94: 0x2c5d, 0xe95: 0x2c5d, 0xe96: 0x2c7d, 0xe97: 0x2c7d,\n\t0xe98: 0x2c5d, 0xe99: 0x2c5d, 0xe9a: 0x2a7d, 0xe9b: 0x2a7d, 0xe9c: 0x2c5d, 0xe9d: 0x2c5d,\n\t0xe9e: 0x2c3d, 0xe9f: 0x2c3d, 0xea0: 0x2c9d, 0xea1: 0x2c9d, 0xea2: 0x2cbd, 0xea3: 0x2cbd,\n\t0xea4: 0x0040, 0xea5: 0x2cdd, 0xea6: 0x2cfd, 0xea7: 0x2d1d, 0xea8: 0x2d1d, 0xea9: 0x2d3d,\n\t0xeaa: 0x2d5d, 0xeab: 0x2d7d, 0xeac: 0x2d9d, 0xead: 0x2dbd, 0xeae: 0x2ddd, 0xeaf: 0x2dfd,\n\t0xeb0: 0x2e1d, 0xeb1: 0x2e3d, 0xeb2: 0x2e3d, 0xeb3: 0x2e5d, 0xeb4: 0x2e7d, 0xeb5: 0x2e7d,\n\t0xeb6: 0x2e9d, 0xeb7: 0x2ebd, 0xeb8: 0x2e5d, 0xeb9: 0x2edd, 0xeba: 0x2efd, 0xebb: 0x2edd,\n\t0xebc: 0x2e5d, 0xebd: 0x2f1d, 0xebe: 0x2f3d, 0xebf: 0x2f5d,\n\t// Block 0x3b, offset 0xec0\n\t0xec0: 0x2f7d, 0xec1: 0x2f9d, 0xec2: 0x2cfd, 0xec3: 0x2cdd, 0xec4: 0x2fbd, 0xec5: 0x2fdd,\n\t0xec6: 0x2ffd, 0xec7: 0x301d, 0xec8: 0x303d, 0xec9: 0x305d, 0xeca: 0x307d, 0xecb: 0x309d,\n\t0xecc: 0x30bd, 0xecd: 0x30dd, 0xece: 0x30fd, 0xecf: 0x0040, 0xed0: 0x0018, 0xed1: 0x0018,\n\t0xed2: 0x311d, 0xed3: 0x313d, 0xed4: 0x315d, 0xed5: 0x317d, 0xed6: 0x319d, 0xed7: 0x31bd,\n\t0xed8: 0x31dd, 0xed9: 0x31fd, 0xeda: 0x321d, 0xedb: 0x323d, 0xedc: 0x315d, 0xedd: 0x325d,\n\t0xede: 0x327d, 0xedf: 0x329d, 0xee0: 0x0008, 0xee1: 0x0008, 0xee2: 0x0008, 0xee3: 0x0008,\n\t0xee4: 0x0008, 0xee5: 0x0008, 0xee6: 0x0008, 0xee7: 0x0008, 0xee8: 0x0008, 0xee9: 0x0008,\n\t0xeea: 0x0008, 0xeeb: 0x0008, 0xeec: 0x0008, 0xeed: 0x0008, 0xeee: 0x0008, 0xeef: 0x0008,\n\t0xef0: 0x0008, 0xef1: 0x0008, 0xef2: 0x0008, 0xef3: 0x0008, 0xef4: 0x0008, 0xef5: 0x0008,\n\t0xef6: 0x0008, 0xef7: 0x0008, 0xef8: 0x0008, 0xef9: 0x0008, 0xefa: 0x0008, 0xefb: 0x0040,\n\t0xefc: 0x0040, 0xefd: 0x0040, 0xefe: 0x0040, 0xeff: 0x0040,\n\t// Block 0x3c, offset 0xf00\n\t0xf00: 0x36a2, 0xf01: 0x36d2, 0xf02: 0x3702, 0xf03: 0x3732, 0xf04: 0x32bd, 0xf05: 0x32dd,\n\t0xf06: 0x32fd, 0xf07: 0x331d, 0xf08: 0x0018, 0xf09: 0x0018, 0xf0a: 0x0018, 0xf0b: 0x0018,\n\t0xf0c: 0x0018, 0xf0d: 0x0018, 0xf0e: 0x0018, 0xf0f: 0x0018, 0xf10: 0x333d, 0xf11: 0x3761,\n\t0xf12: 0x3779, 0xf13: 0x3791, 0xf14: 0x37a9, 0xf15: 0x37c1, 0xf16: 0x37d9, 0xf17: 0x37f1,\n\t0xf18: 0x3809, 0xf19: 0x3821, 0xf1a: 0x3839, 0xf1b: 0x3851, 0xf1c: 0x3869, 0xf1d: 0x3881,\n\t0xf1e: 0x3899, 0xf1f: 0x38b1, 0xf20: 0x335d, 0xf21: 0x337d, 0xf22: 0x339d, 0xf23: 0x33bd,\n\t0xf24: 0x33dd, 0xf25: 0x33dd, 0xf26: 0x33fd, 0xf27: 0x341d, 0xf28: 0x343d, 0xf29: 0x345d,\n\t0xf2a: 0x347d, 0xf2b: 0x349d, 0xf2c: 0x34bd, 0xf2d: 0x34dd, 0xf2e: 0x34fd, 0xf2f: 0x351d,\n\t0xf30: 0x353d, 0xf31: 0x355d, 0xf32: 0x357d, 0xf33: 0x359d, 0xf34: 0x35bd, 0xf35: 0x35dd,\n\t0xf36: 0x35fd, 0xf37: 0x361d, 0xf38: 0x363d, 0xf39: 0x365d, 0xf3a: 0x367d, 0xf3b: 0x369d,\n\t0xf3c: 0x38c9, 0xf3d: 0x3901, 0xf3e: 0x36bd, 0xf3f: 0x0018,\n\t// Block 0x3d, offset 0xf40\n\t0xf40: 0x36dd, 0xf41: 0x36fd, 0xf42: 0x371d, 0xf43: 0x373d, 0xf44: 0x375d, 0xf45: 0x377d,\n\t0xf46: 0x379d, 0xf47: 0x37bd, 0xf48: 0x37dd, 0xf49: 0x37fd, 0xf4a: 0x381d, 0xf4b: 0x383d,\n\t0xf4c: 0x385d, 0xf4d: 0x387d, 0xf4e: 0x389d, 0xf4f: 0x38bd, 0xf50: 0x38dd, 0xf51: 0x38fd,\n\t0xf52: 0x391d, 0xf53: 0x393d, 0xf54: 0x395d, 0xf55: 0x397d, 0xf56: 0x399d, 0xf57: 0x39bd,\n\t0xf58: 0x39dd, 0xf59: 0x39fd, 0xf5a: 0x3a1d, 0xf5b: 0x3a3d, 0xf5c: 0x3a5d, 0xf5d: 0x3a7d,\n\t0xf5e: 0x3a9d, 0xf5f: 0x3abd, 0xf60: 0x3add, 0xf61: 0x3afd, 0xf62: 0x3b1d, 0xf63: 0x3b3d,\n\t0xf64: 0x3b5d, 0xf65: 0x3b7d, 0xf66: 0x127d, 0xf67: 0x3b9d, 0xf68: 0x3bbd, 0xf69: 0x3bdd,\n\t0xf6a: 0x3bfd, 0xf6b: 0x3c1d, 0xf6c: 0x3c3d, 0xf6d: 0x3c5d, 0xf6e: 0x239d, 0xf6f: 0x3c7d,\n\t0xf70: 0x3c9d, 0xf71: 0x3939, 0xf72: 0x3951, 0xf73: 0x3969, 0xf74: 0x3981, 0xf75: 0x3999,\n\t0xf76: 0x39b1, 0xf77: 0x39c9, 0xf78: 0x39e1, 0xf79: 0x39f9, 0xf7a: 0x3a11, 0xf7b: 0x3a29,\n\t0xf7c: 0x3a41, 0xf7d: 0x3a59, 0xf7e: 0x3a71, 0xf7f: 0x3a89,\n\t// Block 0x3e, offset 0xf80\n\t0xf80: 0x3aa1, 0xf81: 0x3ac9, 0xf82: 0x3af1, 0xf83: 0x3b19, 0xf84: 0x3b41, 0xf85: 0x3b69,\n\t0xf86: 0x3b91, 0xf87: 0x3bb9, 0xf88: 0x3be1, 0xf89: 0x3c09, 0xf8a: 0x3c39, 0xf8b: 0x3c69,\n\t0xf8c: 0x3c99, 0xf8d: 0x3cbd, 0xf8e: 0x3cb1, 0xf8f: 0x3cdd, 0xf90: 0x3cfd, 0xf91: 0x3d15,\n\t0xf92: 0x3d2d, 0xf93: 0x3d45, 0xf94: 0x3d5d, 0xf95: 0x3d5d, 0xf96: 0x3d45, 0xf97: 0x3d75,\n\t0xf98: 0x07bd, 0xf99: 0x3d8d, 0xf9a: 0x3da5, 0xf9b: 0x3dbd, 0xf9c: 0x3dd5, 0xf9d: 0x3ded,\n\t0xf9e: 0x3e05, 0xf9f: 0x3e1d, 0xfa0: 0x3e35, 0xfa1: 0x3e4d, 0xfa2: 0x3e65, 0xfa3: 0x3e7d,\n\t0xfa4: 0x3e95, 0xfa5: 0x3e95, 0xfa6: 0x3ead, 0xfa7: 0x3ead, 0xfa8: 0x3ec5, 0xfa9: 0x3ec5,\n\t0xfaa: 0x3edd, 0xfab: 0x3ef5, 0xfac: 0x3f0d, 0xfad: 0x3f25, 0xfae: 0x3f3d, 0xfaf: 0x3f3d,\n\t0xfb0: 0x3f55, 0xfb1: 0x3f55, 0xfb2: 0x3f55, 0xfb3: 0x3f6d, 0xfb4: 0x3f85, 0xfb5: 0x3f9d,\n\t0xfb6: 0x3fb5, 0xfb7: 0x3f9d, 0xfb8: 0x3fcd, 0xfb9: 0x3fe5, 0xfba: 0x3f6d, 0xfbb: 0x3ffd,\n\t0xfbc: 0x4015, 0xfbd: 0x4015, 0xfbe: 0x4015, 0xfbf: 0x0040,\n\t// Block 0x3f, offset 0xfc0\n\t0xfc0: 0x3cc9, 0xfc1: 0x3d31, 0xfc2: 0x3d99, 0xfc3: 0x3e01, 0xfc4: 0x3e51, 0xfc5: 0x3eb9,\n\t0xfc6: 0x3f09, 0xfc7: 0x3f59, 0xfc8: 0x3fd9, 0xfc9: 0x4041, 0xfca: 0x4091, 0xfcb: 0x40e1,\n\t0xfcc: 0x4131, 0xfcd: 0x4199, 0xfce: 0x4201, 0xfcf: 0x4251, 0xfd0: 0x42a1, 0xfd1: 0x42d9,\n\t0xfd2: 0x4329, 0xfd3: 0x4391, 0xfd4: 0x43f9, 0xfd5: 0x4431, 0xfd6: 0x44b1, 0xfd7: 0x4549,\n\t0xfd8: 0x45c9, 0xfd9: 0x4619, 0xfda: 0x4699, 0xfdb: 0x4719, 0xfdc: 0x4781, 0xfdd: 0x47d1,\n\t0xfde: 0x4821, 0xfdf: 0x4871, 0xfe0: 0x48d9, 0xfe1: 0x4959, 0xfe2: 0x49c1, 0xfe3: 0x4a11,\n\t0xfe4: 0x4a61, 0xfe5: 0x4ab1, 0xfe6: 0x4ae9, 0xfe7: 0x4b21, 0xfe8: 0x4b59, 0xfe9: 0x4b91,\n\t0xfea: 0x4be1, 0xfeb: 0x4c31, 0xfec: 0x4cb1, 0xfed: 0x4d01, 0xfee: 0x4d69, 0xfef: 0x4de9,\n\t0xff0: 0x4e39, 0xff1: 0x4e71, 0xff2: 0x4ea9, 0xff3: 0x4f29, 0xff4: 0x4f91, 0xff5: 0x5011,\n\t0xff6: 0x5061, 0xff7: 0x50e1, 0xff8: 0x5119, 0xff9: 0x5169, 0xffa: 0x51b9, 0xffb: 0x5209,\n\t0xffc: 0x5259, 0xffd: 0x52a9, 0xffe: 0x5311, 0xfff: 0x5361,\n\t// Block 0x40, offset 0x1000\n\t0x1000: 0x5399, 0x1001: 0x53e9, 0x1002: 0x5439, 0x1003: 0x5489, 0x1004: 0x54f1, 0x1005: 0x5541,\n\t0x1006: 0x5591, 0x1007: 0x55e1, 0x1008: 0x5661, 0x1009: 0x56c9, 0x100a: 0x5701, 0x100b: 0x5781,\n\t0x100c: 0x57b9, 0x100d: 0x5821, 0x100e: 0x5889, 0x100f: 0x58d9, 0x1010: 0x5929, 0x1011: 0x5979,\n\t0x1012: 0x59e1, 0x1013: 0x5a19, 0x1014: 0x5a69, 0x1015: 0x5ad1, 0x1016: 0x5b09, 0x1017: 0x5b89,\n\t0x1018: 0x5bd9, 0x1019: 0x5c01, 0x101a: 0x5c29, 0x101b: 0x5c51, 0x101c: 0x5c79, 0x101d: 0x5ca1,\n\t0x101e: 0x5cc9, 0x101f: 0x5cf1, 0x1020: 0x5d19, 0x1021: 0x5d41, 0x1022: 0x5d69, 0x1023: 0x5d99,\n\t0x1024: 0x5dc9, 0x1025: 0x5df9, 0x1026: 0x5e29, 0x1027: 0x5e59, 0x1028: 0x5e89, 0x1029: 0x5eb9,\n\t0x102a: 0x5ee9, 0x102b: 0x5f19, 0x102c: 0x5f49, 0x102d: 0x5f79, 0x102e: 0x5fa9, 0x102f: 0x5fd9,\n\t0x1030: 0x6009, 0x1031: 0x402d, 0x1032: 0x6039, 0x1033: 0x6051, 0x1034: 0x404d, 0x1035: 0x6069,\n\t0x1036: 0x6081, 0x1037: 0x6099, 0x1038: 0x406d, 0x1039: 0x406d, 0x103a: 0x60b1, 0x103b: 0x60c9,\n\t0x103c: 0x6101, 0x103d: 0x6139, 0x103e: 0x6171, 0x103f: 0x61a9,\n\t// Block 0x41, offset 0x1040\n\t0x1040: 0x6211, 0x1041: 0x6229, 0x1042: 0x408d, 0x1043: 0x6241, 0x1044: 0x6259, 0x1045: 0x6271,\n\t0x1046: 0x6289, 0x1047: 0x62a1, 0x1048: 0x40ad, 0x1049: 0x62b9, 0x104a: 0x62e1, 0x104b: 0x62f9,\n\t0x104c: 0x40cd, 0x104d: 0x40cd, 0x104e: 0x6311, 0x104f: 0x6329, 0x1050: 0x6341, 0x1051: 0x40ed,\n\t0x1052: 0x410d, 0x1053: 0x412d, 0x1054: 0x414d, 0x1055: 0x416d, 0x1056: 0x6359, 0x1057: 0x6371,\n\t0x1058: 0x6389, 0x1059: 0x63a1, 0x105a: 0x63b9, 0x105b: 0x418d, 0x105c: 0x63d1, 0x105d: 0x63e9,\n\t0x105e: 0x6401, 0x105f: 0x41ad, 0x1060: 0x41cd, 0x1061: 0x6419, 0x1062: 0x41ed, 0x1063: 0x420d,\n\t0x1064: 0x422d, 0x1065: 0x6431, 0x1066: 0x424d, 0x1067: 0x6449, 0x1068: 0x6479, 0x1069: 0x6211,\n\t0x106a: 0x426d, 0x106b: 0x428d, 0x106c: 0x42ad, 0x106d: 0x42cd, 0x106e: 0x64b1, 0x106f: 0x64f1,\n\t0x1070: 0x6539, 0x1071: 0x6551, 0x1072: 0x42ed, 0x1073: 0x6569, 0x1074: 0x6581, 0x1075: 0x6599,\n\t0x1076: 0x430d, 0x1077: 0x65b1, 0x1078: 0x65c9, 0x1079: 0x65b1, 0x107a: 0x65e1, 0x107b: 0x65f9,\n\t0x107c: 0x432d, 0x107d: 0x6611, 0x107e: 0x6629, 0x107f: 0x6611,\n\t// Block 0x42, offset 0x1080\n\t0x1080: 0x434d, 0x1081: 0x436d, 0x1082: 0x0040, 0x1083: 0x6641, 0x1084: 0x6659, 0x1085: 0x6671,\n\t0x1086: 0x6689, 0x1087: 0x0040, 0x1088: 0x66c1, 0x1089: 0x66d9, 0x108a: 0x66f1, 0x108b: 0x6709,\n\t0x108c: 0x6721, 0x108d: 0x6739, 0x108e: 0x6401, 0x108f: 0x6751, 0x1090: 0x6769, 0x1091: 0x6781,\n\t0x1092: 0x438d, 0x1093: 0x6799, 0x1094: 0x6289, 0x1095: 0x43ad, 0x1096: 0x43cd, 0x1097: 0x67b1,\n\t0x1098: 0x0040, 0x1099: 0x43ed, 0x109a: 0x67c9, 0x109b: 0x67e1, 0x109c: 0x67f9, 0x109d: 0x6811,\n\t0x109e: 0x6829, 0x109f: 0x6859, 0x10a0: 0x6889, 0x10a1: 0x68b1, 0x10a2: 0x68d9, 0x10a3: 0x6901,\n\t0x10a4: 0x6929, 0x10a5: 0x6951, 0x10a6: 0x6979, 0x10a7: 0x69a1, 0x10a8: 0x69c9, 0x10a9: 0x69f1,\n\t0x10aa: 0x6a21, 0x10ab: 0x6a51, 0x10ac: 0x6a81, 0x10ad: 0x6ab1, 0x10ae: 0x6ae1, 0x10af: 0x6b11,\n\t0x10b0: 0x6b41, 0x10b1: 0x6b71, 0x10b2: 0x6ba1, 0x10b3: 0x6bd1, 0x10b4: 0x6c01, 0x10b5: 0x6c31,\n\t0x10b6: 0x6c61, 0x10b7: 0x6c91, 0x10b8: 0x6cc1, 0x10b9: 0x6cf1, 0x10ba: 0x6d21, 0x10bb: 0x6d51,\n\t0x10bc: 0x6d81, 0x10bd: 0x6db1, 0x10be: 0x6de1, 0x10bf: 0x440d,\n\t// Block 0x43, offset 0x10c0\n\t0x10c0: 0xe00d, 0x10c1: 0x0008, 0x10c2: 0xe00d, 0x10c3: 0x0008, 0x10c4: 0xe00d, 0x10c5: 0x0008,\n\t0x10c6: 0xe00d, 0x10c7: 0x0008, 0x10c8: 0xe00d, 0x10c9: 0x0008, 0x10ca: 0xe00d, 0x10cb: 0x0008,\n\t0x10cc: 0xe00d, 0x10cd: 0x0008, 0x10ce: 0xe00d, 0x10cf: 0x0008, 0x10d0: 0xe00d, 0x10d1: 0x0008,\n\t0x10d2: 0xe00d, 0x10d3: 0x0008, 0x10d4: 0xe00d, 0x10d5: 0x0008, 0x10d6: 0xe00d, 0x10d7: 0x0008,\n\t0x10d8: 0xe00d, 0x10d9: 0x0008, 0x10da: 0xe00d, 0x10db: 0x0008, 0x10dc: 0xe00d, 0x10dd: 0x0008,\n\t0x10de: 0xe00d, 0x10df: 0x0008, 0x10e0: 0xe00d, 0x10e1: 0x0008, 0x10e2: 0xe00d, 0x10e3: 0x0008,\n\t0x10e4: 0xe00d, 0x10e5: 0x0008, 0x10e6: 0xe00d, 0x10e7: 0x0008, 0x10e8: 0xe00d, 0x10e9: 0x0008,\n\t0x10ea: 0xe00d, 0x10eb: 0x0008, 0x10ec: 0xe00d, 0x10ed: 0x0008, 0x10ee: 0x0008, 0x10ef: 0x3308,\n\t0x10f0: 0x3318, 0x10f1: 0x3318, 0x10f2: 0x3318, 0x10f3: 0x0018, 0x10f4: 0x3308, 0x10f5: 0x3308,\n\t0x10f6: 0x3308, 0x10f7: 0x3308, 0x10f8: 0x3308, 0x10f9: 0x3308, 0x10fa: 0x3308, 0x10fb: 0x3308,\n\t0x10fc: 0x3308, 0x10fd: 0x3308, 0x10fe: 0x0018, 0x10ff: 0x0008,\n\t// Block 0x44, offset 0x1100\n\t0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008,\n\t0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008,\n\t0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008,\n\t0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008,\n\t0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0x0ea1, 0x111d: 0x6e11,\n\t0x111e: 0x3308, 0x111f: 0x3308, 0x1120: 0x0008, 0x1121: 0x0008, 0x1122: 0x0008, 0x1123: 0x0008,\n\t0x1124: 0x0008, 0x1125: 0x0008, 0x1126: 0x0008, 0x1127: 0x0008, 0x1128: 0x0008, 0x1129: 0x0008,\n\t0x112a: 0x0008, 0x112b: 0x0008, 0x112c: 0x0008, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x0008,\n\t0x1130: 0x0008, 0x1131: 0x0008, 0x1132: 0x0008, 0x1133: 0x0008, 0x1134: 0x0008, 0x1135: 0x0008,\n\t0x1136: 0x0008, 0x1137: 0x0008, 0x1138: 0x0008, 0x1139: 0x0008, 0x113a: 0x0008, 0x113b: 0x0008,\n\t0x113c: 0x0008, 0x113d: 0x0008, 0x113e: 0x0008, 0x113f: 0x0008,\n\t// Block 0x45, offset 0x1140\n\t0x1140: 0x0018, 0x1141: 0x0018, 0x1142: 0x0018, 0x1143: 0x0018, 0x1144: 0x0018, 0x1145: 0x0018,\n\t0x1146: 0x0018, 0x1147: 0x0018, 0x1148: 0x0018, 0x1149: 0x0018, 0x114a: 0x0018, 0x114b: 0x0018,\n\t0x114c: 0x0018, 0x114d: 0x0018, 0x114e: 0x0018, 0x114f: 0x0018, 0x1150: 0x0018, 0x1151: 0x0018,\n\t0x1152: 0x0018, 0x1153: 0x0018, 0x1154: 0x0018, 0x1155: 0x0018, 0x1156: 0x0018, 0x1157: 0x0008,\n\t0x1158: 0x0008, 0x1159: 0x0008, 0x115a: 0x0008, 0x115b: 0x0008, 0x115c: 0x0008, 0x115d: 0x0008,\n\t0x115e: 0x0008, 0x115f: 0x0008, 0x1160: 0x0018, 0x1161: 0x0018, 0x1162: 0xe00d, 0x1163: 0x0008,\n\t0x1164: 0xe00d, 0x1165: 0x0008, 0x1166: 0xe00d, 0x1167: 0x0008, 0x1168: 0xe00d, 0x1169: 0x0008,\n\t0x116a: 0xe00d, 0x116b: 0x0008, 0x116c: 0xe00d, 0x116d: 0x0008, 0x116e: 0xe00d, 0x116f: 0x0008,\n\t0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0xe00d, 0x1173: 0x0008, 0x1174: 0xe00d, 0x1175: 0x0008,\n\t0x1176: 0xe00d, 0x1177: 0x0008, 0x1178: 0xe00d, 0x1179: 0x0008, 0x117a: 0xe00d, 0x117b: 0x0008,\n\t0x117c: 0xe00d, 0x117d: 0x0008, 0x117e: 0xe00d, 0x117f: 0x0008,\n\t// Block 0x46, offset 0x1180\n\t0x1180: 0xe00d, 0x1181: 0x0008, 0x1182: 0xe00d, 0x1183: 0x0008, 0x1184: 0xe00d, 0x1185: 0x0008,\n\t0x1186: 0xe00d, 0x1187: 0x0008, 0x1188: 0xe00d, 0x1189: 0x0008, 0x118a: 0xe00d, 0x118b: 0x0008,\n\t0x118c: 0xe00d, 0x118d: 0x0008, 0x118e: 0xe00d, 0x118f: 0x0008, 0x1190: 0xe00d, 0x1191: 0x0008,\n\t0x1192: 0xe00d, 0x1193: 0x0008, 0x1194: 0xe00d, 0x1195: 0x0008, 0x1196: 0xe00d, 0x1197: 0x0008,\n\t0x1198: 0xe00d, 0x1199: 0x0008, 0x119a: 0xe00d, 0x119b: 0x0008, 0x119c: 0xe00d, 0x119d: 0x0008,\n\t0x119e: 0xe00d, 0x119f: 0x0008, 0x11a0: 0xe00d, 0x11a1: 0x0008, 0x11a2: 0xe00d, 0x11a3: 0x0008,\n\t0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008,\n\t0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008,\n\t0x11b0: 0xe0fd, 0x11b1: 0x0008, 0x11b2: 0x0008, 0x11b3: 0x0008, 0x11b4: 0x0008, 0x11b5: 0x0008,\n\t0x11b6: 0x0008, 0x11b7: 0x0008, 0x11b8: 0x0008, 0x11b9: 0xe01d, 0x11ba: 0x0008, 0x11bb: 0xe03d,\n\t0x11bc: 0x0008, 0x11bd: 0x442d, 0x11be: 0xe00d, 0x11bf: 0x0008,\n\t// Block 0x47, offset 0x11c0\n\t0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008,\n\t0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0x0008, 0x11c9: 0x0018, 0x11ca: 0x0018, 0x11cb: 0xe03d,\n\t0x11cc: 0x0008, 0x11cd: 0x11d9, 0x11ce: 0x0008, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008,\n\t0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0x0008, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008,\n\t0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008,\n\t0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008,\n\t0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008,\n\t0x11ea: 0x6e29, 0x11eb: 0x1029, 0x11ec: 0x11c1, 0x11ed: 0x6e41, 0x11ee: 0x1221, 0x11ef: 0x0040,\n\t0x11f0: 0x6e59, 0x11f1: 0x6e71, 0x11f2: 0x1239, 0x11f3: 0x444d, 0x11f4: 0xe00d, 0x11f5: 0x0008,\n\t0x11f6: 0xe00d, 0x11f7: 0x0008, 0x11f8: 0x0040, 0x11f9: 0x0040, 0x11fa: 0x0040, 0x11fb: 0x0040,\n\t0x11fc: 0x0040, 0x11fd: 0x0040, 0x11fe: 0x0040, 0x11ff: 0x0040,\n\t// Block 0x48, offset 0x1200\n\t0x1200: 0x64d5, 0x1201: 0x64f5, 0x1202: 0x6515, 0x1203: 0x6535, 0x1204: 0x6555, 0x1205: 0x6575,\n\t0x1206: 0x6595, 0x1207: 0x65b5, 0x1208: 0x65d5, 0x1209: 0x65f5, 0x120a: 0x6615, 0x120b: 0x6635,\n\t0x120c: 0x6655, 0x120d: 0x6675, 0x120e: 0x0008, 0x120f: 0x0008, 0x1210: 0x6695, 0x1211: 0x0008,\n\t0x1212: 0x66b5, 0x1213: 0x0008, 0x1214: 0x0008, 0x1215: 0x66d5, 0x1216: 0x66f5, 0x1217: 0x6715,\n\t0x1218: 0x6735, 0x1219: 0x6755, 0x121a: 0x6775, 0x121b: 0x6795, 0x121c: 0x67b5, 0x121d: 0x67d5,\n\t0x121e: 0x67f5, 0x121f: 0x0008, 0x1220: 0x6815, 0x1221: 0x0008, 0x1222: 0x6835, 0x1223: 0x0008,\n\t0x1224: 0x0008, 0x1225: 0x6855, 0x1226: 0x6875, 0x1227: 0x0008, 0x1228: 0x0008, 0x1229: 0x0008,\n\t0x122a: 0x6895, 0x122b: 0x68b5, 0x122c: 0x68d5, 0x122d: 0x68f5, 0x122e: 0x6915, 0x122f: 0x6935,\n\t0x1230: 0x6955, 0x1231: 0x6975, 0x1232: 0x6995, 0x1233: 0x69b5, 0x1234: 0x69d5, 0x1235: 0x69f5,\n\t0x1236: 0x6a15, 0x1237: 0x6a35, 0x1238: 0x6a55, 0x1239: 0x6a75, 0x123a: 0x6a95, 0x123b: 0x6ab5,\n\t0x123c: 0x6ad5, 0x123d: 0x6af5, 0x123e: 0x6b15, 0x123f: 0x6b35,\n\t// Block 0x49, offset 0x1240\n\t0x1240: 0x7a95, 0x1241: 0x7ab5, 0x1242: 0x7ad5, 0x1243: 0x7af5, 0x1244: 0x7b15, 0x1245: 0x7b35,\n\t0x1246: 0x7b55, 0x1247: 0x7b75, 0x1248: 0x7b95, 0x1249: 0x7bb5, 0x124a: 0x7bd5, 0x124b: 0x7bf5,\n\t0x124c: 0x7c15, 0x124d: 0x7c35, 0x124e: 0x7c55, 0x124f: 0x6ec9, 0x1250: 0x6ef1, 0x1251: 0x6f19,\n\t0x1252: 0x7c75, 0x1253: 0x7c95, 0x1254: 0x7cb5, 0x1255: 0x6f41, 0x1256: 0x6f69, 0x1257: 0x6f91,\n\t0x1258: 0x7cd5, 0x1259: 0x7cf5, 0x125a: 0x0040, 0x125b: 0x0040, 0x125c: 0x0040, 0x125d: 0x0040,\n\t0x125e: 0x0040, 0x125f: 0x0040, 0x1260: 0x0040, 0x1261: 0x0040, 0x1262: 0x0040, 0x1263: 0x0040,\n\t0x1264: 0x0040, 0x1265: 0x0040, 0x1266: 0x0040, 0x1267: 0x0040, 0x1268: 0x0040, 0x1269: 0x0040,\n\t0x126a: 0x0040, 0x126b: 0x0040, 0x126c: 0x0040, 0x126d: 0x0040, 0x126e: 0x0040, 0x126f: 0x0040,\n\t0x1270: 0x0040, 0x1271: 0x0040, 0x1272: 0x0040, 0x1273: 0x0040, 0x1274: 0x0040, 0x1275: 0x0040,\n\t0x1276: 0x0040, 0x1277: 0x0040, 0x1278: 0x0040, 0x1279: 0x0040, 0x127a: 0x0040, 0x127b: 0x0040,\n\t0x127c: 0x0040, 0x127d: 0x0040, 0x127e: 0x0040, 0x127f: 0x0040,\n\t// Block 0x4a, offset 0x1280\n\t0x1280: 0x6fb9, 0x1281: 0x6fd1, 0x1282: 0x6fe9, 0x1283: 0x7d15, 0x1284: 0x7d35, 0x1285: 0x7001,\n\t0x1286: 0x7001, 0x1287: 0x0040, 0x1288: 0x0040, 0x1289: 0x0040, 0x128a: 0x0040, 0x128b: 0x0040,\n\t0x128c: 0x0040, 0x128d: 0x0040, 0x128e: 0x0040, 0x128f: 0x0040, 0x1290: 0x0040, 0x1291: 0x0040,\n\t0x1292: 0x0040, 0x1293: 0x7019, 0x1294: 0x7041, 0x1295: 0x7069, 0x1296: 0x7091, 0x1297: 0x70b9,\n\t0x1298: 0x0040, 0x1299: 0x0040, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x70e1,\n\t0x129e: 0x3308, 0x129f: 0x7109, 0x12a0: 0x7131, 0x12a1: 0x20a9, 0x12a2: 0x20f1, 0x12a3: 0x7149,\n\t0x12a4: 0x7161, 0x12a5: 0x7179, 0x12a6: 0x7191, 0x12a7: 0x71a9, 0x12a8: 0x71c1, 0x12a9: 0x1fb2,\n\t0x12aa: 0x71d9, 0x12ab: 0x7201, 0x12ac: 0x7229, 0x12ad: 0x7261, 0x12ae: 0x7299, 0x12af: 0x72c1,\n\t0x12b0: 0x72e9, 0x12b1: 0x7311, 0x12b2: 0x7339, 0x12b3: 0x7361, 0x12b4: 0x7389, 0x12b5: 0x73b1,\n\t0x12b6: 0x73d9, 0x12b7: 0x0040, 0x12b8: 0x7401, 0x12b9: 0x7429, 0x12ba: 0x7451, 0x12bb: 0x7479,\n\t0x12bc: 0x74a1, 0x12bd: 0x0040, 0x12be: 0x74c9, 0x12bf: 0x0040,\n\t// Block 0x4b, offset 0x12c0\n\t0x12c0: 0x74f1, 0x12c1: 0x7519, 0x12c2: 0x0040, 0x12c3: 0x7541, 0x12c4: 0x7569, 0x12c5: 0x0040,\n\t0x12c6: 0x7591, 0x12c7: 0x75b9, 0x12c8: 0x75e1, 0x12c9: 0x7609, 0x12ca: 0x7631, 0x12cb: 0x7659,\n\t0x12cc: 0x7681, 0x12cd: 0x76a9, 0x12ce: 0x76d1, 0x12cf: 0x76f9, 0x12d0: 0x7721, 0x12d1: 0x7721,\n\t0x12d2: 0x7739, 0x12d3: 0x7739, 0x12d4: 0x7739, 0x12d5: 0x7739, 0x12d6: 0x7751, 0x12d7: 0x7751,\n\t0x12d8: 0x7751, 0x12d9: 0x7751, 0x12da: 0x7769, 0x12db: 0x7769, 0x12dc: 0x7769, 0x12dd: 0x7769,\n\t0x12de: 0x7781, 0x12df: 0x7781, 0x12e0: 0x7781, 0x12e1: 0x7781, 0x12e2: 0x7799, 0x12e3: 0x7799,\n\t0x12e4: 0x7799, 0x12e5: 0x7799, 0x12e6: 0x77b1, 0x12e7: 0x77b1, 0x12e8: 0x77b1, 0x12e9: 0x77b1,\n\t0x12ea: 0x77c9, 0x12eb: 0x77c9, 0x12ec: 0x77c9, 0x12ed: 0x77c9, 0x12ee: 0x77e1, 0x12ef: 0x77e1,\n\t0x12f0: 0x77e1, 0x12f1: 0x77e1, 0x12f2: 0x77f9, 0x12f3: 0x77f9, 0x12f4: 0x77f9, 0x12f5: 0x77f9,\n\t0x12f6: 0x7811, 0x12f7: 0x7811, 0x12f8: 0x7811, 0x12f9: 0x7811, 0x12fa: 0x7829, 0x12fb: 0x7829,\n\t0x12fc: 0x7829, 0x12fd: 0x7829, 0x12fe: 0x7841, 0x12ff: 0x7841,\n\t// Block 0x4c, offset 0x1300\n\t0x1300: 0x7841, 0x1301: 0x7841, 0x1302: 0x7859, 0x1303: 0x7859, 0x1304: 0x7871, 0x1305: 0x7871,\n\t0x1306: 0x7889, 0x1307: 0x7889, 0x1308: 0x78a1, 0x1309: 0x78a1, 0x130a: 0x78b9, 0x130b: 0x78b9,\n\t0x130c: 0x78d1, 0x130d: 0x78d1, 0x130e: 0x78e9, 0x130f: 0x78e9, 0x1310: 0x78e9, 0x1311: 0x78e9,\n\t0x1312: 0x7901, 0x1313: 0x7901, 0x1314: 0x7901, 0x1315: 0x7901, 0x1316: 0x7919, 0x1317: 0x7919,\n\t0x1318: 0x7919, 0x1319: 0x7919, 0x131a: 0x7931, 0x131b: 0x7931, 0x131c: 0x7931, 0x131d: 0x7931,\n\t0x131e: 0x7949, 0x131f: 0x7949, 0x1320: 0x7961, 0x1321: 0x7961, 0x1322: 0x7961, 0x1323: 0x7961,\n\t0x1324: 0x7979, 0x1325: 0x7979, 0x1326: 0x7991, 0x1327: 0x7991, 0x1328: 0x7991, 0x1329: 0x7991,\n\t0x132a: 0x79a9, 0x132b: 0x79a9, 0x132c: 0x79a9, 0x132d: 0x79a9, 0x132e: 0x79c1, 0x132f: 0x79c1,\n\t0x1330: 0x79d9, 0x1331: 0x79d9, 0x1332: 0x0818, 0x1333: 0x0818, 0x1334: 0x0818, 0x1335: 0x0818,\n\t0x1336: 0x0818, 0x1337: 0x0818, 0x1338: 0x0818, 0x1339: 0x0818, 0x133a: 0x0818, 0x133b: 0x0818,\n\t0x133c: 0x0818, 0x133d: 0x0818, 0x133e: 0x0818, 0x133f: 0x0818,\n\t// Block 0x4d, offset 0x1340\n\t0x1340: 0x0818, 0x1341: 0x0818, 0x1342: 0x0040, 0x1343: 0x0040, 0x1344: 0x0040, 0x1345: 0x0040,\n\t0x1346: 0x0040, 0x1347: 0x0040, 0x1348: 0x0040, 0x1349: 0x0040, 0x134a: 0x0040, 0x134b: 0x0040,\n\t0x134c: 0x0040, 0x134d: 0x0040, 0x134e: 0x0040, 0x134f: 0x0040, 0x1350: 0x0040, 0x1351: 0x0040,\n\t0x1352: 0x0040, 0x1353: 0x79f1, 0x1354: 0x79f1, 0x1355: 0x79f1, 0x1356: 0x79f1, 0x1357: 0x7a09,\n\t0x1358: 0x7a09, 0x1359: 0x7a21, 0x135a: 0x7a21, 0x135b: 0x7a39, 0x135c: 0x7a39, 0x135d: 0x0479,\n\t0x135e: 0x7a51, 0x135f: 0x7a51, 0x1360: 0x7a69, 0x1361: 0x7a69, 0x1362: 0x7a81, 0x1363: 0x7a81,\n\t0x1364: 0x7a99, 0x1365: 0x7a99, 0x1366: 0x7a99, 0x1367: 0x7a99, 0x1368: 0x7ab1, 0x1369: 0x7ab1,\n\t0x136a: 0x7ac9, 0x136b: 0x7ac9, 0x136c: 0x7af1, 0x136d: 0x7af1, 0x136e: 0x7b19, 0x136f: 0x7b19,\n\t0x1370: 0x7b41, 0x1371: 0x7b41, 0x1372: 0x7b69, 0x1373: 0x7b69, 0x1374: 0x7b91, 0x1375: 0x7b91,\n\t0x1376: 0x7bb9, 0x1377: 0x7bb9, 0x1378: 0x7bb9, 0x1379: 0x7be1, 0x137a: 0x7be1, 0x137b: 0x7be1,\n\t0x137c: 0x7c09, 0x137d: 0x7c09, 0x137e: 0x7c09, 0x137f: 0x7c09,\n\t// Block 0x4e, offset 0x1380\n\t0x1380: 0x85f9, 0x1381: 0x8621, 0x1382: 0x8649, 0x1383: 0x8671, 0x1384: 0x8699, 0x1385: 0x86c1,\n\t0x1386: 0x86e9, 0x1387: 0x8711, 0x1388: 0x8739, 0x1389: 0x8761, 0x138a: 0x8789, 0x138b: 0x87b1,\n\t0x138c: 0x87d9, 0x138d: 0x8801, 0x138e: 0x8829, 0x138f: 0x8851, 0x1390: 0x8879, 0x1391: 0x88a1,\n\t0x1392: 0x88c9, 0x1393: 0x88f1, 0x1394: 0x8919, 0x1395: 0x8941, 0x1396: 0x8969, 0x1397: 0x8991,\n\t0x1398: 0x89b9, 0x1399: 0x89e1, 0x139a: 0x8a09, 0x139b: 0x8a31, 0x139c: 0x8a59, 0x139d: 0x8a81,\n\t0x139e: 0x8aaa, 0x139f: 0x8ada, 0x13a0: 0x8b0a, 0x13a1: 0x8b3a, 0x13a2: 0x8b6a, 0x13a3: 0x8b9a,\n\t0x13a4: 0x8bc9, 0x13a5: 0x8bf1, 0x13a6: 0x7c71, 0x13a7: 0x8c19, 0x13a8: 0x7be1, 0x13a9: 0x7c99,\n\t0x13aa: 0x8c41, 0x13ab: 0x8c69, 0x13ac: 0x7d39, 0x13ad: 0x8c91, 0x13ae: 0x7d61, 0x13af: 0x7d89,\n\t0x13b0: 0x8cb9, 0x13b1: 0x8ce1, 0x13b2: 0x7e29, 0x13b3: 0x8d09, 0x13b4: 0x7e51, 0x13b5: 0x7e79,\n\t0x13b6: 0x8d31, 0x13b7: 0x8d59, 0x13b8: 0x7ec9, 0x13b9: 0x8d81, 0x13ba: 0x7ef1, 0x13bb: 0x7f19,\n\t0x13bc: 0x83a1, 0x13bd: 0x83c9, 0x13be: 0x8441, 0x13bf: 0x8469,\n\t// Block 0x4f, offset 0x13c0\n\t0x13c0: 0x8491, 0x13c1: 0x8531, 0x13c2: 0x8559, 0x13c3: 0x8581, 0x13c4: 0x85a9, 0x13c5: 0x8649,\n\t0x13c6: 0x8671, 0x13c7: 0x8699, 0x13c8: 0x8da9, 0x13c9: 0x8739, 0x13ca: 0x8dd1, 0x13cb: 0x8df9,\n\t0x13cc: 0x8829, 0x13cd: 0x8e21, 0x13ce: 0x8851, 0x13cf: 0x8879, 0x13d0: 0x8a81, 0x13d1: 0x8e49,\n\t0x13d2: 0x8e71, 0x13d3: 0x89b9, 0x13d4: 0x8e99, 0x13d5: 0x89e1, 0x13d6: 0x8a09, 0x13d7: 0x7c21,\n\t0x13d8: 0x7c49, 0x13d9: 0x8ec1, 0x13da: 0x7c71, 0x13db: 0x8ee9, 0x13dc: 0x7cc1, 0x13dd: 0x7ce9,\n\t0x13de: 0x7d11, 0x13df: 0x7d39, 0x13e0: 0x8f11, 0x13e1: 0x7db1, 0x13e2: 0x7dd9, 0x13e3: 0x7e01,\n\t0x13e4: 0x7e29, 0x13e5: 0x8f39, 0x13e6: 0x7ec9, 0x13e7: 0x7f41, 0x13e8: 0x7f69, 0x13e9: 0x7f91,\n\t0x13ea: 0x7fb9, 0x13eb: 0x7fe1, 0x13ec: 0x8031, 0x13ed: 0x8059, 0x13ee: 0x8081, 0x13ef: 0x80a9,\n\t0x13f0: 0x80d1, 0x13f1: 0x80f9, 0x13f2: 0x8f61, 0x13f3: 0x8121, 0x13f4: 0x8149, 0x13f5: 0x8171,\n\t0x13f6: 0x8199, 0x13f7: 0x81c1, 0x13f8: 0x81e9, 0x13f9: 0x8239, 0x13fa: 0x8261, 0x13fb: 0x8289,\n\t0x13fc: 0x82b1, 0x13fd: 0x82d9, 0x13fe: 0x8301, 0x13ff: 0x8329,\n\t// Block 0x50, offset 0x1400\n\t0x1400: 0x8351, 0x1401: 0x8379, 0x1402: 0x83f1, 0x1403: 0x8419, 0x1404: 0x84b9, 0x1405: 0x84e1,\n\t0x1406: 0x8509, 0x1407: 0x8531, 0x1408: 0x8559, 0x1409: 0x85d1, 0x140a: 0x85f9, 0x140b: 0x8621,\n\t0x140c: 0x8649, 0x140d: 0x8f89, 0x140e: 0x86c1, 0x140f: 0x86e9, 0x1410: 0x8711, 0x1411: 0x8739,\n\t0x1412: 0x87b1, 0x1413: 0x87d9, 0x1414: 0x8801, 0x1415: 0x8829, 0x1416: 0x8fb1, 0x1417: 0x88a1,\n\t0x1418: 0x88c9, 0x1419: 0x8fd9, 0x141a: 0x8941, 0x141b: 0x8969, 0x141c: 0x8991, 0x141d: 0x89b9,\n\t0x141e: 0x9001, 0x141f: 0x7c71, 0x1420: 0x8ee9, 0x1421: 0x7d39, 0x1422: 0x8f11, 0x1423: 0x7e29,\n\t0x1424: 0x8f39, 0x1425: 0x7ec9, 0x1426: 0x9029, 0x1427: 0x80d1, 0x1428: 0x9051, 0x1429: 0x9079,\n\t0x142a: 0x90a1, 0x142b: 0x8531, 0x142c: 0x8559, 0x142d: 0x8649, 0x142e: 0x8829, 0x142f: 0x8fb1,\n\t0x1430: 0x89b9, 0x1431: 0x9001, 0x1432: 0x90c9, 0x1433: 0x9101, 0x1434: 0x9139, 0x1435: 0x9171,\n\t0x1436: 0x9199, 0x1437: 0x91c1, 0x1438: 0x91e9, 0x1439: 0x9211, 0x143a: 0x9239, 0x143b: 0x9261,\n\t0x143c: 0x9289, 0x143d: 0x92b1, 0x143e: 0x92d9, 0x143f: 0x9301,\n\t// Block 0x51, offset 0x1440\n\t0x1440: 0x9329, 0x1441: 0x9351, 0x1442: 0x9379, 0x1443: 0x93a1, 0x1444: 0x93c9, 0x1445: 0x93f1,\n\t0x1446: 0x9419, 0x1447: 0x9441, 0x1448: 0x9469, 0x1449: 0x9491, 0x144a: 0x94b9, 0x144b: 0x94e1,\n\t0x144c: 0x9079, 0x144d: 0x9509, 0x144e: 0x9531, 0x144f: 0x9559, 0x1450: 0x9581, 0x1451: 0x9171,\n\t0x1452: 0x9199, 0x1453: 0x91c1, 0x1454: 0x91e9, 0x1455: 0x9211, 0x1456: 0x9239, 0x1457: 0x9261,\n\t0x1458: 0x9289, 0x1459: 0x92b1, 0x145a: 0x92d9, 0x145b: 0x9301, 0x145c: 0x9329, 0x145d: 0x9351,\n\t0x145e: 0x9379, 0x145f: 0x93a1, 0x1460: 0x93c9, 0x1461: 0x93f1, 0x1462: 0x9419, 0x1463: 0x9441,\n\t0x1464: 0x9469, 0x1465: 0x9491, 0x1466: 0x94b9, 0x1467: 0x94e1, 0x1468: 0x9079, 0x1469: 0x9509,\n\t0x146a: 0x9531, 0x146b: 0x9559, 0x146c: 0x9581, 0x146d: 0x9491, 0x146e: 0x94b9, 0x146f: 0x94e1,\n\t0x1470: 0x9079, 0x1471: 0x9051, 0x1472: 0x90a1, 0x1473: 0x8211, 0x1474: 0x8059, 0x1475: 0x8081,\n\t0x1476: 0x80a9, 0x1477: 0x9491, 0x1478: 0x94b9, 0x1479: 0x94e1, 0x147a: 0x8211, 0x147b: 0x8239,\n\t0x147c: 0x95a9, 0x147d: 0x95a9, 0x147e: 0x0018, 0x147f: 0x0018,\n\t// Block 0x52, offset 0x1480\n\t0x1480: 0x0040, 0x1481: 0x0040, 0x1482: 0x0040, 0x1483: 0x0040, 0x1484: 0x0040, 0x1485: 0x0040,\n\t0x1486: 0x0040, 0x1487: 0x0040, 0x1488: 0x0040, 0x1489: 0x0040, 0x148a: 0x0040, 0x148b: 0x0040,\n\t0x148c: 0x0040, 0x148d: 0x0040, 0x148e: 0x0040, 0x148f: 0x0040, 0x1490: 0x95d1, 0x1491: 0x9609,\n\t0x1492: 0x9609, 0x1493: 0x9641, 0x1494: 0x9679, 0x1495: 0x96b1, 0x1496: 0x96e9, 0x1497: 0x9721,\n\t0x1498: 0x9759, 0x1499: 0x9759, 0x149a: 0x9791, 0x149b: 0x97c9, 0x149c: 0x9801, 0x149d: 0x9839,\n\t0x149e: 0x9871, 0x149f: 0x98a9, 0x14a0: 0x98a9, 0x14a1: 0x98e1, 0x14a2: 0x9919, 0x14a3: 0x9919,\n\t0x14a4: 0x9951, 0x14a5: 0x9951, 0x14a6: 0x9989, 0x14a7: 0x99c1, 0x14a8: 0x99c1, 0x14a9: 0x99f9,\n\t0x14aa: 0x9a31, 0x14ab: 0x9a31, 0x14ac: 0x9a69, 0x14ad: 0x9a69, 0x14ae: 0x9aa1, 0x14af: 0x9ad9,\n\t0x14b0: 0x9ad9, 0x14b1: 0x9b11, 0x14b2: 0x9b11, 0x14b3: 0x9b49, 0x14b4: 0x9b81, 0x14b5: 0x9bb9,\n\t0x14b6: 0x9bf1, 0x14b7: 0x9bf1, 0x14b8: 0x9c29, 0x14b9: 0x9c61, 0x14ba: 0x9c99, 0x14bb: 0x9cd1,\n\t0x14bc: 0x9d09, 0x14bd: 0x9d09, 0x14be: 0x9d41, 0x14bf: 0x9d79,\n\t// Block 0x53, offset 0x14c0\n\t0x14c0: 0xa949, 0x14c1: 0xa981, 0x14c2: 0xa9b9, 0x14c3: 0xa8a1, 0x14c4: 0x9bb9, 0x14c5: 0x9989,\n\t0x14c6: 0xa9f1, 0x14c7: 0xaa29, 0x14c8: 0x0040, 0x14c9: 0x0040, 0x14ca: 0x0040, 0x14cb: 0x0040,\n\t0x14cc: 0x0040, 0x14cd: 0x0040, 0x14ce: 0x0040, 0x14cf: 0x0040, 0x14d0: 0x0040, 0x14d1: 0x0040,\n\t0x14d2: 0x0040, 0x14d3: 0x0040, 0x14d4: 0x0040, 0x14d5: 0x0040, 0x14d6: 0x0040, 0x14d7: 0x0040,\n\t0x14d8: 0x0040, 0x14d9: 0x0040, 0x14da: 0x0040, 0x14db: 0x0040, 0x14dc: 0x0040, 0x14dd: 0x0040,\n\t0x14de: 0x0040, 0x14df: 0x0040, 0x14e0: 0x0040, 0x14e1: 0x0040, 0x14e2: 0x0040, 0x14e3: 0x0040,\n\t0x14e4: 0x0040, 0x14e5: 0x0040, 0x14e6: 0x0040, 0x14e7: 0x0040, 0x14e8: 0x0040, 0x14e9: 0x0040,\n\t0x14ea: 0x0040, 0x14eb: 0x0040, 0x14ec: 0x0040, 0x14ed: 0x0040, 0x14ee: 0x0040, 0x14ef: 0x0040,\n\t0x14f0: 0xaa61, 0x14f1: 0xaa99, 0x14f2: 0xaad1, 0x14f3: 0xab19, 0x14f4: 0xab61, 0x14f5: 0xaba9,\n\t0x14f6: 0xabf1, 0x14f7: 0xac39, 0x14f8: 0xac81, 0x14f9: 0xacc9, 0x14fa: 0xad02, 0x14fb: 0xae12,\n\t0x14fc: 0xae91, 0x14fd: 0x0018, 0x14fe: 0x0040, 0x14ff: 0x0040,\n\t// Block 0x54, offset 0x1500\n\t0x1500: 0x33c0, 0x1501: 0x33c0, 0x1502: 0x33c0, 0x1503: 0x33c0, 0x1504: 0x33c0, 0x1505: 0x33c0,\n\t0x1506: 0x33c0, 0x1507: 0x33c0, 0x1508: 0x33c0, 0x1509: 0x33c0, 0x150a: 0x33c0, 0x150b: 0x33c0,\n\t0x150c: 0x33c0, 0x150d: 0x33c0, 0x150e: 0x33c0, 0x150f: 0x33c0, 0x1510: 0xaeda, 0x1511: 0x7d55,\n\t0x1512: 0x0040, 0x1513: 0xaeea, 0x1514: 0x03c2, 0x1515: 0xaefa, 0x1516: 0xaf0a, 0x1517: 0x7d75,\n\t0x1518: 0x7d95, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040,\n\t0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x3308, 0x1521: 0x3308, 0x1522: 0x3308, 0x1523: 0x3308,\n\t0x1524: 0x3308, 0x1525: 0x3308, 0x1526: 0x3308, 0x1527: 0x3308, 0x1528: 0x3308, 0x1529: 0x3308,\n\t0x152a: 0x3308, 0x152b: 0x3308, 0x152c: 0x3308, 0x152d: 0x3308, 0x152e: 0x3308, 0x152f: 0x3308,\n\t0x1530: 0x0040, 0x1531: 0x7db5, 0x1532: 0x7dd5, 0x1533: 0xaf1a, 0x1534: 0xaf1a, 0x1535: 0x1fd2,\n\t0x1536: 0x1fe2, 0x1537: 0xaf2a, 0x1538: 0xaf3a, 0x1539: 0x7df5, 0x153a: 0x7e15, 0x153b: 0x7e35,\n\t0x153c: 0x7df5, 0x153d: 0x7e55, 0x153e: 0x7e75, 0x153f: 0x7e55,\n\t// Block 0x55, offset 0x1540\n\t0x1540: 0x7e95, 0x1541: 0x7eb5, 0x1542: 0x7ed5, 0x1543: 0x7eb5, 0x1544: 0x7ef5, 0x1545: 0x0018,\n\t0x1546: 0x0018, 0x1547: 0xaf4a, 0x1548: 0xaf5a, 0x1549: 0x7f16, 0x154a: 0x7f36, 0x154b: 0x7f56,\n\t0x154c: 0x7f76, 0x154d: 0xaf1a, 0x154e: 0xaf1a, 0x154f: 0xaf1a, 0x1550: 0xaeda, 0x1551: 0x7f95,\n\t0x1552: 0x0040, 0x1553: 0x0040, 0x1554: 0x03c2, 0x1555: 0xaeea, 0x1556: 0xaf0a, 0x1557: 0xaefa,\n\t0x1558: 0x7fb5, 0x1559: 0x1fd2, 0x155a: 0x1fe2, 0x155b: 0xaf2a, 0x155c: 0xaf3a, 0x155d: 0x7e95,\n\t0x155e: 0x7ef5, 0x155f: 0xaf6a, 0x1560: 0xaf7a, 0x1561: 0xaf8a, 0x1562: 0x1fb2, 0x1563: 0xaf99,\n\t0x1564: 0xafaa, 0x1565: 0xafba, 0x1566: 0x1fc2, 0x1567: 0x0040, 0x1568: 0xafca, 0x1569: 0xafda,\n\t0x156a: 0xafea, 0x156b: 0xaffa, 0x156c: 0x0040, 0x156d: 0x0040, 0x156e: 0x0040, 0x156f: 0x0040,\n\t0x1570: 0x7fd6, 0x1571: 0xb009, 0x1572: 0x7ff6, 0x1573: 0x0808, 0x1574: 0x8016, 0x1575: 0x0040,\n\t0x1576: 0x8036, 0x1577: 0xb031, 0x1578: 0x8056, 0x1579: 0xb059, 0x157a: 0x8076, 0x157b: 0xb081,\n\t0x157c: 0x8096, 0x157d: 0xb0a9, 0x157e: 0x80b6, 0x157f: 0xb0d1,\n\t// Block 0x56, offset 0x1580\n\t0x1580: 0xb0f9, 0x1581: 0xb111, 0x1582: 0xb111, 0x1583: 0xb129, 0x1584: 0xb129, 0x1585: 0xb141,\n\t0x1586: 0xb141, 0x1587: 0xb159, 0x1588: 0xb159, 0x1589: 0xb171, 0x158a: 0xb171, 0x158b: 0xb171,\n\t0x158c: 0xb171, 0x158d: 0xb189, 0x158e: 0xb189, 0x158f: 0xb1a1, 0x1590: 0xb1a1, 0x1591: 0xb1a1,\n\t0x1592: 0xb1a1, 0x1593: 0xb1b9, 0x1594: 0xb1b9, 0x1595: 0xb1d1, 0x1596: 0xb1d1, 0x1597: 0xb1d1,\n\t0x1598: 0xb1d1, 0x1599: 0xb1e9, 0x159a: 0xb1e9, 0x159b: 0xb1e9, 0x159c: 0xb1e9, 0x159d: 0xb201,\n\t0x159e: 0xb201, 0x159f: 0xb201, 0x15a0: 0xb201, 0x15a1: 0xb219, 0x15a2: 0xb219, 0x15a3: 0xb219,\n\t0x15a4: 0xb219, 0x15a5: 0xb231, 0x15a6: 0xb231, 0x15a7: 0xb231, 0x15a8: 0xb231, 0x15a9: 0xb249,\n\t0x15aa: 0xb249, 0x15ab: 0xb261, 0x15ac: 0xb261, 0x15ad: 0xb279, 0x15ae: 0xb279, 0x15af: 0xb291,\n\t0x15b0: 0xb291, 0x15b1: 0xb2a9, 0x15b2: 0xb2a9, 0x15b3: 0xb2a9, 0x15b4: 0xb2a9, 0x15b5: 0xb2c1,\n\t0x15b6: 0xb2c1, 0x15b7: 0xb2c1, 0x15b8: 0xb2c1, 0x15b9: 0xb2d9, 0x15ba: 0xb2d9, 0x15bb: 0xb2d9,\n\t0x15bc: 0xb2d9, 0x15bd: 0xb2f1, 0x15be: 0xb2f1, 0x15bf: 0xb2f1,\n\t// Block 0x57, offset 0x15c0\n\t0x15c0: 0xb2f1, 0x15c1: 0xb309, 0x15c2: 0xb309, 0x15c3: 0xb309, 0x15c4: 0xb309, 0x15c5: 0xb321,\n\t0x15c6: 0xb321, 0x15c7: 0xb321, 0x15c8: 0xb321, 0x15c9: 0xb339, 0x15ca: 0xb339, 0x15cb: 0xb339,\n\t0x15cc: 0xb339, 0x15cd: 0xb351, 0x15ce: 0xb351, 0x15cf: 0xb351, 0x15d0: 0xb351, 0x15d1: 0xb369,\n\t0x15d2: 0xb369, 0x15d3: 0xb369, 0x15d4: 0xb369, 0x15d5: 0xb381, 0x15d6: 0xb381, 0x15d7: 0xb381,\n\t0x15d8: 0xb381, 0x15d9: 0xb399, 0x15da: 0xb399, 0x15db: 0xb399, 0x15dc: 0xb399, 0x15dd: 0xb3b1,\n\t0x15de: 0xb3b1, 0x15df: 0xb3b1, 0x15e0: 0xb3b1, 0x15e1: 0xb3c9, 0x15e2: 0xb3c9, 0x15e3: 0xb3c9,\n\t0x15e4: 0xb3c9, 0x15e5: 0xb3e1, 0x15e6: 0xb3e1, 0x15e7: 0xb3e1, 0x15e8: 0xb3e1, 0x15e9: 0xb3f9,\n\t0x15ea: 0xb3f9, 0x15eb: 0xb3f9, 0x15ec: 0xb3f9, 0x15ed: 0xb411, 0x15ee: 0xb411, 0x15ef: 0x7ab1,\n\t0x15f0: 0x7ab1, 0x15f1: 0xb429, 0x15f2: 0xb429, 0x15f3: 0xb429, 0x15f4: 0xb429, 0x15f5: 0xb441,\n\t0x15f6: 0xb441, 0x15f7: 0xb469, 0x15f8: 0xb469, 0x15f9: 0xb491, 0x15fa: 0xb491, 0x15fb: 0xb4b9,\n\t0x15fc: 0xb4b9, 0x15fd: 0x0040, 0x15fe: 0x0040, 0x15ff: 0x03c0,\n\t// Block 0x58, offset 0x1600\n\t0x1600: 0x0040, 0x1601: 0xaefa, 0x1602: 0xb4e2, 0x1603: 0xaf6a, 0x1604: 0xafda, 0x1605: 0xafea,\n\t0x1606: 0xaf7a, 0x1607: 0xb4f2, 0x1608: 0x1fd2, 0x1609: 0x1fe2, 0x160a: 0xaf8a, 0x160b: 0x1fb2,\n\t0x160c: 0xaeda, 0x160d: 0xaf99, 0x160e: 0x29d1, 0x160f: 0xb502, 0x1610: 0x1f41, 0x1611: 0x00c9,\n\t0x1612: 0x0069, 0x1613: 0x0079, 0x1614: 0x1f51, 0x1615: 0x1f61, 0x1616: 0x1f71, 0x1617: 0x1f81,\n\t0x1618: 0x1f91, 0x1619: 0x1fa1, 0x161a: 0xaeea, 0x161b: 0x03c2, 0x161c: 0xafaa, 0x161d: 0x1fc2,\n\t0x161e: 0xafba, 0x161f: 0xaf0a, 0x1620: 0xaffa, 0x1621: 0x0039, 0x1622: 0x0ee9, 0x1623: 0x1159,\n\t0x1624: 0x0ef9, 0x1625: 0x0f09, 0x1626: 0x1199, 0x1627: 0x0f31, 0x1628: 0x0249, 0x1629: 0x0f41,\n\t0x162a: 0x0259, 0x162b: 0x0f51, 0x162c: 0x0359, 0x162d: 0x0f61, 0x162e: 0x0f71, 0x162f: 0x00d9,\n\t0x1630: 0x0f99, 0x1631: 0x2039, 0x1632: 0x0269, 0x1633: 0x01d9, 0x1634: 0x0fa9, 0x1635: 0x0fb9,\n\t0x1636: 0x1089, 0x1637: 0x0279, 0x1638: 0x0369, 0x1639: 0x0289, 0x163a: 0x13d1, 0x163b: 0xaf4a,\n\t0x163c: 0xafca, 0x163d: 0xaf5a, 0x163e: 0xb512, 0x163f: 0xaf1a,\n\t// Block 0x59, offset 0x1640\n\t0x1640: 0x1caa, 0x1641: 0x0039, 0x1642: 0x0ee9, 0x1643: 0x1159, 0x1644: 0x0ef9, 0x1645: 0x0f09,\n\t0x1646: 0x1199, 0x1647: 0x0f31, 0x1648: 0x0249, 0x1649: 0x0f41, 0x164a: 0x0259, 0x164b: 0x0f51,\n\t0x164c: 0x0359, 0x164d: 0x0f61, 0x164e: 0x0f71, 0x164f: 0x00d9, 0x1650: 0x0f99, 0x1651: 0x2039,\n\t0x1652: 0x0269, 0x1653: 0x01d9, 0x1654: 0x0fa9, 0x1655: 0x0fb9, 0x1656: 0x1089, 0x1657: 0x0279,\n\t0x1658: 0x0369, 0x1659: 0x0289, 0x165a: 0x13d1, 0x165b: 0xaf2a, 0x165c: 0xb522, 0x165d: 0xaf3a,\n\t0x165e: 0xb532, 0x165f: 0x80d5, 0x1660: 0x80f5, 0x1661: 0x29d1, 0x1662: 0x8115, 0x1663: 0x8115,\n\t0x1664: 0x8135, 0x1665: 0x8155, 0x1666: 0x8175, 0x1667: 0x8195, 0x1668: 0x81b5, 0x1669: 0x81d5,\n\t0x166a: 0x81f5, 0x166b: 0x8215, 0x166c: 0x8235, 0x166d: 0x8255, 0x166e: 0x8275, 0x166f: 0x8295,\n\t0x1670: 0x82b5, 0x1671: 0x82d5, 0x1672: 0x82f5, 0x1673: 0x8315, 0x1674: 0x8335, 0x1675: 0x8355,\n\t0x1676: 0x8375, 0x1677: 0x8395, 0x1678: 0x83b5, 0x1679: 0x83d5, 0x167a: 0x83f5, 0x167b: 0x8415,\n\t0x167c: 0x81b5, 0x167d: 0x8435, 0x167e: 0x8455, 0x167f: 0x8215,\n\t// Block 0x5a, offset 0x1680\n\t0x1680: 0x8475, 0x1681: 0x8495, 0x1682: 0x84b5, 0x1683: 0x84d5, 0x1684: 0x84f5, 0x1685: 0x8515,\n\t0x1686: 0x8535, 0x1687: 0x8555, 0x1688: 0x84d5, 0x1689: 0x8575, 0x168a: 0x84d5, 0x168b: 0x8595,\n\t0x168c: 0x8595, 0x168d: 0x85b5, 0x168e: 0x85b5, 0x168f: 0x85d5, 0x1690: 0x8515, 0x1691: 0x85f5,\n\t0x1692: 0x8615, 0x1693: 0x85f5, 0x1694: 0x8635, 0x1695: 0x8615, 0x1696: 0x8655, 0x1697: 0x8655,\n\t0x1698: 0x8675, 0x1699: 0x8675, 0x169a: 0x8695, 0x169b: 0x8695, 0x169c: 0x8615, 0x169d: 0x8115,\n\t0x169e: 0x86b5, 0x169f: 0x86d5, 0x16a0: 0x0040, 0x16a1: 0x86f5, 0x16a2: 0x8715, 0x16a3: 0x8735,\n\t0x16a4: 0x8755, 0x16a5: 0x8735, 0x16a6: 0x8775, 0x16a7: 0x8795, 0x16a8: 0x87b5, 0x16a9: 0x87b5,\n\t0x16aa: 0x87d5, 0x16ab: 0x87d5, 0x16ac: 0x87f5, 0x16ad: 0x87f5, 0x16ae: 0x87d5, 0x16af: 0x87d5,\n\t0x16b0: 0x8815, 0x16b1: 0x8835, 0x16b2: 0x8855, 0x16b3: 0x8875, 0x16b4: 0x8895, 0x16b5: 0x88b5,\n\t0x16b6: 0x88b5, 0x16b7: 0x88b5, 0x16b8: 0x88d5, 0x16b9: 0x88d5, 0x16ba: 0x88d5, 0x16bb: 0x88d5,\n\t0x16bc: 0x87b5, 0x16bd: 0x87b5, 0x16be: 0x87b5, 0x16bf: 0x0040,\n\t// Block 0x5b, offset 0x16c0\n\t0x16c0: 0x0040, 0x16c1: 0x0040, 0x16c2: 0x8715, 0x16c3: 0x86f5, 0x16c4: 0x88f5, 0x16c5: 0x86f5,\n\t0x16c6: 0x8715, 0x16c7: 0x86f5, 0x16c8: 0x0040, 0x16c9: 0x0040, 0x16ca: 0x8915, 0x16cb: 0x8715,\n\t0x16cc: 0x8935, 0x16cd: 0x88f5, 0x16ce: 0x8935, 0x16cf: 0x8715, 0x16d0: 0x0040, 0x16d1: 0x0040,\n\t0x16d2: 0x8955, 0x16d3: 0x8975, 0x16d4: 0x8875, 0x16d5: 0x8935, 0x16d6: 0x88f5, 0x16d7: 0x8935,\n\t0x16d8: 0x0040, 0x16d9: 0x0040, 0x16da: 0x8995, 0x16db: 0x89b5, 0x16dc: 0x8995, 0x16dd: 0x0040,\n\t0x16de: 0x0040, 0x16df: 0x0040, 0x16e0: 0xb541, 0x16e1: 0xb559, 0x16e2: 0xb571, 0x16e3: 0x89d6,\n\t0x16e4: 0xb589, 0x16e5: 0xb5a1, 0x16e6: 0x89f5, 0x16e7: 0x0040, 0x16e8: 0x8a15, 0x16e9: 0x8a35,\n\t0x16ea: 0x8a55, 0x16eb: 0x8a35, 0x16ec: 0x8a75, 0x16ed: 0x8a95, 0x16ee: 0x8ab5, 0x16ef: 0x0040,\n\t0x16f0: 0x0040, 0x16f1: 0x0040, 0x16f2: 0x0040, 0x16f3: 0x0040, 0x16f4: 0x0040, 0x16f5: 0x0040,\n\t0x16f6: 0x0040, 0x16f7: 0x0040, 0x16f8: 0x0040, 0x16f9: 0x0340, 0x16fa: 0x0340, 0x16fb: 0x0340,\n\t0x16fc: 0x0040, 0x16fd: 0x0040, 0x16fe: 0x0040, 0x16ff: 0x0040,\n\t// Block 0x5c, offset 0x1700\n\t0x1700: 0x0a08, 0x1701: 0x0a08, 0x1702: 0x0a08, 0x1703: 0x0a08, 0x1704: 0x0a08, 0x1705: 0x0c08,\n\t0x1706: 0x0808, 0x1707: 0x0c08, 0x1708: 0x0818, 0x1709: 0x0c08, 0x170a: 0x0c08, 0x170b: 0x0808,\n\t0x170c: 0x0808, 0x170d: 0x0908, 0x170e: 0x0c08, 0x170f: 0x0c08, 0x1710: 0x0c08, 0x1711: 0x0c08,\n\t0x1712: 0x0c08, 0x1713: 0x0a08, 0x1714: 0x0a08, 0x1715: 0x0a08, 0x1716: 0x0a08, 0x1717: 0x0908,\n\t0x1718: 0x0a08, 0x1719: 0x0a08, 0x171a: 0x0a08, 0x171b: 0x0a08, 0x171c: 0x0a08, 0x171d: 0x0c08,\n\t0x171e: 0x0a08, 0x171f: 0x0a08, 0x1720: 0x0a08, 0x1721: 0x0c08, 0x1722: 0x0808, 0x1723: 0x0808,\n\t0x1724: 0x0c08, 0x1725: 0x3308, 0x1726: 0x3308, 0x1727: 0x0040, 0x1728: 0x0040, 0x1729: 0x0040,\n\t0x172a: 0x0040, 0x172b: 0x0a18, 0x172c: 0x0a18, 0x172d: 0x0a18, 0x172e: 0x0a18, 0x172f: 0x0c18,\n\t0x1730: 0x0818, 0x1731: 0x0818, 0x1732: 0x0818, 0x1733: 0x0818, 0x1734: 0x0818, 0x1735: 0x0818,\n\t0x1736: 0x0818, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0040, 0x173a: 0x0040, 0x173b: 0x0040,\n\t0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040,\n\t// Block 0x5d, offset 0x1740\n\t0x1740: 0x0a08, 0x1741: 0x0c08, 0x1742: 0x0a08, 0x1743: 0x0c08, 0x1744: 0x0c08, 0x1745: 0x0c08,\n\t0x1746: 0x0a08, 0x1747: 0x0a08, 0x1748: 0x0a08, 0x1749: 0x0c08, 0x174a: 0x0a08, 0x174b: 0x0a08,\n\t0x174c: 0x0c08, 0x174d: 0x0a08, 0x174e: 0x0c08, 0x174f: 0x0c08, 0x1750: 0x0a08, 0x1751: 0x0c08,\n\t0x1752: 0x0040, 0x1753: 0x0040, 0x1754: 0x0040, 0x1755: 0x0040, 0x1756: 0x0040, 0x1757: 0x0040,\n\t0x1758: 0x0040, 0x1759: 0x0818, 0x175a: 0x0818, 0x175b: 0x0818, 0x175c: 0x0818, 0x175d: 0x0040,\n\t0x175e: 0x0040, 0x175f: 0x0040, 0x1760: 0x0040, 0x1761: 0x0040, 0x1762: 0x0040, 0x1763: 0x0040,\n\t0x1764: 0x0040, 0x1765: 0x0040, 0x1766: 0x0040, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0c18,\n\t0x176a: 0x0c18, 0x176b: 0x0c18, 0x176c: 0x0c18, 0x176d: 0x0a18, 0x176e: 0x0a18, 0x176f: 0x0818,\n\t0x1770: 0x0040, 0x1771: 0x0040, 0x1772: 0x0040, 0x1773: 0x0040, 0x1774: 0x0040, 0x1775: 0x0040,\n\t0x1776: 0x0040, 0x1777: 0x0040, 0x1778: 0x0040, 0x1779: 0x0040, 0x177a: 0x0040, 0x177b: 0x0040,\n\t0x177c: 0x0040, 0x177d: 0x0040, 0x177e: 0x0040, 0x177f: 0x0040,\n\t// Block 0x5e, offset 0x1780\n\t0x1780: 0x3308, 0x1781: 0x3308, 0x1782: 0x3008, 0x1783: 0x3008, 0x1784: 0x0040, 0x1785: 0x0008,\n\t0x1786: 0x0008, 0x1787: 0x0008, 0x1788: 0x0008, 0x1789: 0x0008, 0x178a: 0x0008, 0x178b: 0x0008,\n\t0x178c: 0x0008, 0x178d: 0x0040, 0x178e: 0x0040, 0x178f: 0x0008, 0x1790: 0x0008, 0x1791: 0x0040,\n\t0x1792: 0x0040, 0x1793: 0x0008, 0x1794: 0x0008, 0x1795: 0x0008, 0x1796: 0x0008, 0x1797: 0x0008,\n\t0x1798: 0x0008, 0x1799: 0x0008, 0x179a: 0x0008, 0x179b: 0x0008, 0x179c: 0x0008, 0x179d: 0x0008,\n\t0x179e: 0x0008, 0x179f: 0x0008, 0x17a0: 0x0008, 0x17a1: 0x0008, 0x17a2: 0x0008, 0x17a3: 0x0008,\n\t0x17a4: 0x0008, 0x17a5: 0x0008, 0x17a6: 0x0008, 0x17a7: 0x0008, 0x17a8: 0x0008, 0x17a9: 0x0040,\n\t0x17aa: 0x0008, 0x17ab: 0x0008, 0x17ac: 0x0008, 0x17ad: 0x0008, 0x17ae: 0x0008, 0x17af: 0x0008,\n\t0x17b0: 0x0008, 0x17b1: 0x0040, 0x17b2: 0x0008, 0x17b3: 0x0008, 0x17b4: 0x0040, 0x17b5: 0x0008,\n\t0x17b6: 0x0008, 0x17b7: 0x0008, 0x17b8: 0x0008, 0x17b9: 0x0008, 0x17ba: 0x0040, 0x17bb: 0x0040,\n\t0x17bc: 0x3308, 0x17bd: 0x0008, 0x17be: 0x3008, 0x17bf: 0x3008,\n\t// Block 0x5f, offset 0x17c0\n\t0x17c0: 0x3308, 0x17c1: 0x3008, 0x17c2: 0x3008, 0x17c3: 0x3008, 0x17c4: 0x3008, 0x17c5: 0x0040,\n\t0x17c6: 0x0040, 0x17c7: 0x3008, 0x17c8: 0x3008, 0x17c9: 0x0040, 0x17ca: 0x0040, 0x17cb: 0x3008,\n\t0x17cc: 0x3008, 0x17cd: 0x3808, 0x17ce: 0x0040, 0x17cf: 0x0040, 0x17d0: 0x0008, 0x17d1: 0x0040,\n\t0x17d2: 0x0040, 0x17d3: 0x0040, 0x17d4: 0x0040, 0x17d5: 0x0040, 0x17d6: 0x0040, 0x17d7: 0x3008,\n\t0x17d8: 0x0040, 0x17d9: 0x0040, 0x17da: 0x0040, 0x17db: 0x0040, 0x17dc: 0x0040, 0x17dd: 0x0008,\n\t0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x3008, 0x17e3: 0x3008,\n\t0x17e4: 0x0040, 0x17e5: 0x0040, 0x17e6: 0x3308, 0x17e7: 0x3308, 0x17e8: 0x3308, 0x17e9: 0x3308,\n\t0x17ea: 0x3308, 0x17eb: 0x3308, 0x17ec: 0x3308, 0x17ed: 0x0040, 0x17ee: 0x0040, 0x17ef: 0x0040,\n\t0x17f0: 0x3308, 0x17f1: 0x3308, 0x17f2: 0x3308, 0x17f3: 0x3308, 0x17f4: 0x3308, 0x17f5: 0x0040,\n\t0x17f6: 0x0040, 0x17f7: 0x0040, 0x17f8: 0x0040, 0x17f9: 0x0040, 0x17fa: 0x0040, 0x17fb: 0x0040,\n\t0x17fc: 0x0040, 0x17fd: 0x0040, 0x17fe: 0x0040, 0x17ff: 0x0040,\n\t// Block 0x60, offset 0x1800\n\t0x1800: 0x0039, 0x1801: 0x0ee9, 0x1802: 0x1159, 0x1803: 0x0ef9, 0x1804: 0x0f09, 0x1805: 0x1199,\n\t0x1806: 0x0f31, 0x1807: 0x0249, 0x1808: 0x0f41, 0x1809: 0x0259, 0x180a: 0x0f51, 0x180b: 0x0359,\n\t0x180c: 0x0f61, 0x180d: 0x0f71, 0x180e: 0x00d9, 0x180f: 0x0f99, 0x1810: 0x2039, 0x1811: 0x0269,\n\t0x1812: 0x01d9, 0x1813: 0x0fa9, 0x1814: 0x0fb9, 0x1815: 0x1089, 0x1816: 0x0279, 0x1817: 0x0369,\n\t0x1818: 0x0289, 0x1819: 0x13d1, 0x181a: 0x0039, 0x181b: 0x0ee9, 0x181c: 0x1159, 0x181d: 0x0ef9,\n\t0x181e: 0x0f09, 0x181f: 0x1199, 0x1820: 0x0f31, 0x1821: 0x0249, 0x1822: 0x0f41, 0x1823: 0x0259,\n\t0x1824: 0x0f51, 0x1825: 0x0359, 0x1826: 0x0f61, 0x1827: 0x0f71, 0x1828: 0x00d9, 0x1829: 0x0f99,\n\t0x182a: 0x2039, 0x182b: 0x0269, 0x182c: 0x01d9, 0x182d: 0x0fa9, 0x182e: 0x0fb9, 0x182f: 0x1089,\n\t0x1830: 0x0279, 0x1831: 0x0369, 0x1832: 0x0289, 0x1833: 0x13d1, 0x1834: 0x0039, 0x1835: 0x0ee9,\n\t0x1836: 0x1159, 0x1837: 0x0ef9, 0x1838: 0x0f09, 0x1839: 0x1199, 0x183a: 0x0f31, 0x183b: 0x0249,\n\t0x183c: 0x0f41, 0x183d: 0x0259, 0x183e: 0x0f51, 0x183f: 0x0359,\n\t// Block 0x61, offset 0x1840\n\t0x1840: 0x0f61, 0x1841: 0x0f71, 0x1842: 0x00d9, 0x1843: 0x0f99, 0x1844: 0x2039, 0x1845: 0x0269,\n\t0x1846: 0x01d9, 0x1847: 0x0fa9, 0x1848: 0x0fb9, 0x1849: 0x1089, 0x184a: 0x0279, 0x184b: 0x0369,\n\t0x184c: 0x0289, 0x184d: 0x13d1, 0x184e: 0x0039, 0x184f: 0x0ee9, 0x1850: 0x1159, 0x1851: 0x0ef9,\n\t0x1852: 0x0f09, 0x1853: 0x1199, 0x1854: 0x0f31, 0x1855: 0x0040, 0x1856: 0x0f41, 0x1857: 0x0259,\n\t0x1858: 0x0f51, 0x1859: 0x0359, 0x185a: 0x0f61, 0x185b: 0x0f71, 0x185c: 0x00d9, 0x185d: 0x0f99,\n\t0x185e: 0x2039, 0x185f: 0x0269, 0x1860: 0x01d9, 0x1861: 0x0fa9, 0x1862: 0x0fb9, 0x1863: 0x1089,\n\t0x1864: 0x0279, 0x1865: 0x0369, 0x1866: 0x0289, 0x1867: 0x13d1, 0x1868: 0x0039, 0x1869: 0x0ee9,\n\t0x186a: 0x1159, 0x186b: 0x0ef9, 0x186c: 0x0f09, 0x186d: 0x1199, 0x186e: 0x0f31, 0x186f: 0x0249,\n\t0x1870: 0x0f41, 0x1871: 0x0259, 0x1872: 0x0f51, 0x1873: 0x0359, 0x1874: 0x0f61, 0x1875: 0x0f71,\n\t0x1876: 0x00d9, 0x1877: 0x0f99, 0x1878: 0x2039, 0x1879: 0x0269, 0x187a: 0x01d9, 0x187b: 0x0fa9,\n\t0x187c: 0x0fb9, 0x187d: 0x1089, 0x187e: 0x0279, 0x187f: 0x0369,\n\t// Block 0x62, offset 0x1880\n\t0x1880: 0x0289, 0x1881: 0x13d1, 0x1882: 0x0039, 0x1883: 0x0ee9, 0x1884: 0x1159, 0x1885: 0x0ef9,\n\t0x1886: 0x0f09, 0x1887: 0x1199, 0x1888: 0x0f31, 0x1889: 0x0249, 0x188a: 0x0f41, 0x188b: 0x0259,\n\t0x188c: 0x0f51, 0x188d: 0x0359, 0x188e: 0x0f61, 0x188f: 0x0f71, 0x1890: 0x00d9, 0x1891: 0x0f99,\n\t0x1892: 0x2039, 0x1893: 0x0269, 0x1894: 0x01d9, 0x1895: 0x0fa9, 0x1896: 0x0fb9, 0x1897: 0x1089,\n\t0x1898: 0x0279, 0x1899: 0x0369, 0x189a: 0x0289, 0x189b: 0x13d1, 0x189c: 0x0039, 0x189d: 0x0040,\n\t0x189e: 0x1159, 0x189f: 0x0ef9, 0x18a0: 0x0040, 0x18a1: 0x0040, 0x18a2: 0x0f31, 0x18a3: 0x0040,\n\t0x18a4: 0x0040, 0x18a5: 0x0259, 0x18a6: 0x0f51, 0x18a7: 0x0040, 0x18a8: 0x0040, 0x18a9: 0x0f71,\n\t0x18aa: 0x00d9, 0x18ab: 0x0f99, 0x18ac: 0x2039, 0x18ad: 0x0040, 0x18ae: 0x01d9, 0x18af: 0x0fa9,\n\t0x18b0: 0x0fb9, 0x18b1: 0x1089, 0x18b2: 0x0279, 0x18b3: 0x0369, 0x18b4: 0x0289, 0x18b5: 0x13d1,\n\t0x18b6: 0x0039, 0x18b7: 0x0ee9, 0x18b8: 0x1159, 0x18b9: 0x0ef9, 0x18ba: 0x0040, 0x18bb: 0x1199,\n\t0x18bc: 0x0040, 0x18bd: 0x0249, 0x18be: 0x0f41, 0x18bf: 0x0259,\n\t// Block 0x63, offset 0x18c0\n\t0x18c0: 0x0f51, 0x18c1: 0x0359, 0x18c2: 0x0f61, 0x18c3: 0x0f71, 0x18c4: 0x0040, 0x18c5: 0x0f99,\n\t0x18c6: 0x2039, 0x18c7: 0x0269, 0x18c8: 0x01d9, 0x18c9: 0x0fa9, 0x18ca: 0x0fb9, 0x18cb: 0x1089,\n\t0x18cc: 0x0279, 0x18cd: 0x0369, 0x18ce: 0x0289, 0x18cf: 0x13d1, 0x18d0: 0x0039, 0x18d1: 0x0ee9,\n\t0x18d2: 0x1159, 0x18d3: 0x0ef9, 0x18d4: 0x0f09, 0x18d5: 0x1199, 0x18d6: 0x0f31, 0x18d7: 0x0249,\n\t0x18d8: 0x0f41, 0x18d9: 0x0259, 0x18da: 0x0f51, 0x18db: 0x0359, 0x18dc: 0x0f61, 0x18dd: 0x0f71,\n\t0x18de: 0x00d9, 0x18df: 0x0f99, 0x18e0: 0x2039, 0x18e1: 0x0269, 0x18e2: 0x01d9, 0x18e3: 0x0fa9,\n\t0x18e4: 0x0fb9, 0x18e5: 0x1089, 0x18e6: 0x0279, 0x18e7: 0x0369, 0x18e8: 0x0289, 0x18e9: 0x13d1,\n\t0x18ea: 0x0039, 0x18eb: 0x0ee9, 0x18ec: 0x1159, 0x18ed: 0x0ef9, 0x18ee: 0x0f09, 0x18ef: 0x1199,\n\t0x18f0: 0x0f31, 0x18f1: 0x0249, 0x18f2: 0x0f41, 0x18f3: 0x0259, 0x18f4: 0x0f51, 0x18f5: 0x0359,\n\t0x18f6: 0x0f61, 0x18f7: 0x0f71, 0x18f8: 0x00d9, 0x18f9: 0x0f99, 0x18fa: 0x2039, 0x18fb: 0x0269,\n\t0x18fc: 0x01d9, 0x18fd: 0x0fa9, 0x18fe: 0x0fb9, 0x18ff: 0x1089,\n\t// Block 0x64, offset 0x1900\n\t0x1900: 0x0279, 0x1901: 0x0369, 0x1902: 0x0289, 0x1903: 0x13d1, 0x1904: 0x0039, 0x1905: 0x0ee9,\n\t0x1906: 0x0040, 0x1907: 0x0ef9, 0x1908: 0x0f09, 0x1909: 0x1199, 0x190a: 0x0f31, 0x190b: 0x0040,\n\t0x190c: 0x0040, 0x190d: 0x0259, 0x190e: 0x0f51, 0x190f: 0x0359, 0x1910: 0x0f61, 0x1911: 0x0f71,\n\t0x1912: 0x00d9, 0x1913: 0x0f99, 0x1914: 0x2039, 0x1915: 0x0040, 0x1916: 0x01d9, 0x1917: 0x0fa9,\n\t0x1918: 0x0fb9, 0x1919: 0x1089, 0x191a: 0x0279, 0x191b: 0x0369, 0x191c: 0x0289, 0x191d: 0x0040,\n\t0x191e: 0x0039, 0x191f: 0x0ee9, 0x1920: 0x1159, 0x1921: 0x0ef9, 0x1922: 0x0f09, 0x1923: 0x1199,\n\t0x1924: 0x0f31, 0x1925: 0x0249, 0x1926: 0x0f41, 0x1927: 0x0259, 0x1928: 0x0f51, 0x1929: 0x0359,\n\t0x192a: 0x0f61, 0x192b: 0x0f71, 0x192c: 0x00d9, 0x192d: 0x0f99, 0x192e: 0x2039, 0x192f: 0x0269,\n\t0x1930: 0x01d9, 0x1931: 0x0fa9, 0x1932: 0x0fb9, 0x1933: 0x1089, 0x1934: 0x0279, 0x1935: 0x0369,\n\t0x1936: 0x0289, 0x1937: 0x13d1, 0x1938: 0x0039, 0x1939: 0x0ee9, 0x193a: 0x0040, 0x193b: 0x0ef9,\n\t0x193c: 0x0f09, 0x193d: 0x1199, 0x193e: 0x0f31, 0x193f: 0x0040,\n\t// Block 0x65, offset 0x1940\n\t0x1940: 0x0f41, 0x1941: 0x0259, 0x1942: 0x0f51, 0x1943: 0x0359, 0x1944: 0x0f61, 0x1945: 0x0040,\n\t0x1946: 0x00d9, 0x1947: 0x0040, 0x1948: 0x0040, 0x1949: 0x0040, 0x194a: 0x01d9, 0x194b: 0x0fa9,\n\t0x194c: 0x0fb9, 0x194d: 0x1089, 0x194e: 0x0279, 0x194f: 0x0369, 0x1950: 0x0289, 0x1951: 0x0040,\n\t0x1952: 0x0039, 0x1953: 0x0ee9, 0x1954: 0x1159, 0x1955: 0x0ef9, 0x1956: 0x0f09, 0x1957: 0x1199,\n\t0x1958: 0x0f31, 0x1959: 0x0249, 0x195a: 0x0f41, 0x195b: 0x0259, 0x195c: 0x0f51, 0x195d: 0x0359,\n\t0x195e: 0x0f61, 0x195f: 0x0f71, 0x1960: 0x00d9, 0x1961: 0x0f99, 0x1962: 0x2039, 0x1963: 0x0269,\n\t0x1964: 0x01d9, 0x1965: 0x0fa9, 0x1966: 0x0fb9, 0x1967: 0x1089, 0x1968: 0x0279, 0x1969: 0x0369,\n\t0x196a: 0x0289, 0x196b: 0x13d1, 0x196c: 0x0039, 0x196d: 0x0ee9, 0x196e: 0x1159, 0x196f: 0x0ef9,\n\t0x1970: 0x0f09, 0x1971: 0x1199, 0x1972: 0x0f31, 0x1973: 0x0249, 0x1974: 0x0f41, 0x1975: 0x0259,\n\t0x1976: 0x0f51, 0x1977: 0x0359, 0x1978: 0x0f61, 0x1979: 0x0f71, 0x197a: 0x00d9, 0x197b: 0x0f99,\n\t0x197c: 0x2039, 0x197d: 0x0269, 0x197e: 0x01d9, 0x197f: 0x0fa9,\n\t// Block 0x66, offset 0x1980\n\t0x1980: 0x0fb9, 0x1981: 0x1089, 0x1982: 0x0279, 0x1983: 0x0369, 0x1984: 0x0289, 0x1985: 0x13d1,\n\t0x1986: 0x0039, 0x1987: 0x0ee9, 0x1988: 0x1159, 0x1989: 0x0ef9, 0x198a: 0x0f09, 0x198b: 0x1199,\n\t0x198c: 0x0f31, 0x198d: 0x0249, 0x198e: 0x0f41, 0x198f: 0x0259, 0x1990: 0x0f51, 0x1991: 0x0359,\n\t0x1992: 0x0f61, 0x1993: 0x0f71, 0x1994: 0x00d9, 0x1995: 0x0f99, 0x1996: 0x2039, 0x1997: 0x0269,\n\t0x1998: 0x01d9, 0x1999: 0x0fa9, 0x199a: 0x0fb9, 0x199b: 0x1089, 0x199c: 0x0279, 0x199d: 0x0369,\n\t0x199e: 0x0289, 0x199f: 0x13d1, 0x19a0: 0x0039, 0x19a1: 0x0ee9, 0x19a2: 0x1159, 0x19a3: 0x0ef9,\n\t0x19a4: 0x0f09, 0x19a5: 0x1199, 0x19a6: 0x0f31, 0x19a7: 0x0249, 0x19a8: 0x0f41, 0x19a9: 0x0259,\n\t0x19aa: 0x0f51, 0x19ab: 0x0359, 0x19ac: 0x0f61, 0x19ad: 0x0f71, 0x19ae: 0x00d9, 0x19af: 0x0f99,\n\t0x19b0: 0x2039, 0x19b1: 0x0269, 0x19b2: 0x01d9, 0x19b3: 0x0fa9, 0x19b4: 0x0fb9, 0x19b5: 0x1089,\n\t0x19b6: 0x0279, 0x19b7: 0x0369, 0x19b8: 0x0289, 0x19b9: 0x13d1, 0x19ba: 0x0039, 0x19bb: 0x0ee9,\n\t0x19bc: 0x1159, 0x19bd: 0x0ef9, 0x19be: 0x0f09, 0x19bf: 0x1199,\n\t// Block 0x67, offset 0x19c0\n\t0x19c0: 0x0f31, 0x19c1: 0x0249, 0x19c2: 0x0f41, 0x19c3: 0x0259, 0x19c4: 0x0f51, 0x19c5: 0x0359,\n\t0x19c6: 0x0f61, 0x19c7: 0x0f71, 0x19c8: 0x00d9, 0x19c9: 0x0f99, 0x19ca: 0x2039, 0x19cb: 0x0269,\n\t0x19cc: 0x01d9, 0x19cd: 0x0fa9, 0x19ce: 0x0fb9, 0x19cf: 0x1089, 0x19d0: 0x0279, 0x19d1: 0x0369,\n\t0x19d2: 0x0289, 0x19d3: 0x13d1, 0x19d4: 0x0039, 0x19d5: 0x0ee9, 0x19d6: 0x1159, 0x19d7: 0x0ef9,\n\t0x19d8: 0x0f09, 0x19d9: 0x1199, 0x19da: 0x0f31, 0x19db: 0x0249, 0x19dc: 0x0f41, 0x19dd: 0x0259,\n\t0x19de: 0x0f51, 0x19df: 0x0359, 0x19e0: 0x0f61, 0x19e1: 0x0f71, 0x19e2: 0x00d9, 0x19e3: 0x0f99,\n\t0x19e4: 0x2039, 0x19e5: 0x0269, 0x19e6: 0x01d9, 0x19e7: 0x0fa9, 0x19e8: 0x0fb9, 0x19e9: 0x1089,\n\t0x19ea: 0x0279, 0x19eb: 0x0369, 0x19ec: 0x0289, 0x19ed: 0x13d1, 0x19ee: 0x0039, 0x19ef: 0x0ee9,\n\t0x19f0: 0x1159, 0x19f1: 0x0ef9, 0x19f2: 0x0f09, 0x19f3: 0x1199, 0x19f4: 0x0f31, 0x19f5: 0x0249,\n\t0x19f6: 0x0f41, 0x19f7: 0x0259, 0x19f8: 0x0f51, 0x19f9: 0x0359, 0x19fa: 0x0f61, 0x19fb: 0x0f71,\n\t0x19fc: 0x00d9, 0x19fd: 0x0f99, 0x19fe: 0x2039, 0x19ff: 0x0269,\n\t// Block 0x68, offset 0x1a00\n\t0x1a00: 0x01d9, 0x1a01: 0x0fa9, 0x1a02: 0x0fb9, 0x1a03: 0x1089, 0x1a04: 0x0279, 0x1a05: 0x0369,\n\t0x1a06: 0x0289, 0x1a07: 0x13d1, 0x1a08: 0x0039, 0x1a09: 0x0ee9, 0x1a0a: 0x1159, 0x1a0b: 0x0ef9,\n\t0x1a0c: 0x0f09, 0x1a0d: 0x1199, 0x1a0e: 0x0f31, 0x1a0f: 0x0249, 0x1a10: 0x0f41, 0x1a11: 0x0259,\n\t0x1a12: 0x0f51, 0x1a13: 0x0359, 0x1a14: 0x0f61, 0x1a15: 0x0f71, 0x1a16: 0x00d9, 0x1a17: 0x0f99,\n\t0x1a18: 0x2039, 0x1a19: 0x0269, 0x1a1a: 0x01d9, 0x1a1b: 0x0fa9, 0x1a1c: 0x0fb9, 0x1a1d: 0x1089,\n\t0x1a1e: 0x0279, 0x1a1f: 0x0369, 0x1a20: 0x0289, 0x1a21: 0x13d1, 0x1a22: 0x0039, 0x1a23: 0x0ee9,\n\t0x1a24: 0x1159, 0x1a25: 0x0ef9, 0x1a26: 0x0f09, 0x1a27: 0x1199, 0x1a28: 0x0f31, 0x1a29: 0x0249,\n\t0x1a2a: 0x0f41, 0x1a2b: 0x0259, 0x1a2c: 0x0f51, 0x1a2d: 0x0359, 0x1a2e: 0x0f61, 0x1a2f: 0x0f71,\n\t0x1a30: 0x00d9, 0x1a31: 0x0f99, 0x1a32: 0x2039, 0x1a33: 0x0269, 0x1a34: 0x01d9, 0x1a35: 0x0fa9,\n\t0x1a36: 0x0fb9, 0x1a37: 0x1089, 0x1a38: 0x0279, 0x1a39: 0x0369, 0x1a3a: 0x0289, 0x1a3b: 0x13d1,\n\t0x1a3c: 0x0039, 0x1a3d: 0x0ee9, 0x1a3e: 0x1159, 0x1a3f: 0x0ef9,\n\t// Block 0x69, offset 0x1a40\n\t0x1a40: 0x0f09, 0x1a41: 0x1199, 0x1a42: 0x0f31, 0x1a43: 0x0249, 0x1a44: 0x0f41, 0x1a45: 0x0259,\n\t0x1a46: 0x0f51, 0x1a47: 0x0359, 0x1a48: 0x0f61, 0x1a49: 0x0f71, 0x1a4a: 0x00d9, 0x1a4b: 0x0f99,\n\t0x1a4c: 0x2039, 0x1a4d: 0x0269, 0x1a4e: 0x01d9, 0x1a4f: 0x0fa9, 0x1a50: 0x0fb9, 0x1a51: 0x1089,\n\t0x1a52: 0x0279, 0x1a53: 0x0369, 0x1a54: 0x0289, 0x1a55: 0x13d1, 0x1a56: 0x0039, 0x1a57: 0x0ee9,\n\t0x1a58: 0x1159, 0x1a59: 0x0ef9, 0x1a5a: 0x0f09, 0x1a5b: 0x1199, 0x1a5c: 0x0f31, 0x1a5d: 0x0249,\n\t0x1a5e: 0x0f41, 0x1a5f: 0x0259, 0x1a60: 0x0f51, 0x1a61: 0x0359, 0x1a62: 0x0f61, 0x1a63: 0x0f71,\n\t0x1a64: 0x00d9, 0x1a65: 0x0f99, 0x1a66: 0x2039, 0x1a67: 0x0269, 0x1a68: 0x01d9, 0x1a69: 0x0fa9,\n\t0x1a6a: 0x0fb9, 0x1a6b: 0x1089, 0x1a6c: 0x0279, 0x1a6d: 0x0369, 0x1a6e: 0x0289, 0x1a6f: 0x13d1,\n\t0x1a70: 0x0039, 0x1a71: 0x0ee9, 0x1a72: 0x1159, 0x1a73: 0x0ef9, 0x1a74: 0x0f09, 0x1a75: 0x1199,\n\t0x1a76: 0x0f31, 0x1a77: 0x0249, 0x1a78: 0x0f41, 0x1a79: 0x0259, 0x1a7a: 0x0f51, 0x1a7b: 0x0359,\n\t0x1a7c: 0x0f61, 0x1a7d: 0x0f71, 0x1a7e: 0x00d9, 0x1a7f: 0x0f99,\n\t// Block 0x6a, offset 0x1a80\n\t0x1a80: 0x2039, 0x1a81: 0x0269, 0x1a82: 0x01d9, 0x1a83: 0x0fa9, 0x1a84: 0x0fb9, 0x1a85: 0x1089,\n\t0x1a86: 0x0279, 0x1a87: 0x0369, 0x1a88: 0x0289, 0x1a89: 0x13d1, 0x1a8a: 0x0039, 0x1a8b: 0x0ee9,\n\t0x1a8c: 0x1159, 0x1a8d: 0x0ef9, 0x1a8e: 0x0f09, 0x1a8f: 0x1199, 0x1a90: 0x0f31, 0x1a91: 0x0249,\n\t0x1a92: 0x0f41, 0x1a93: 0x0259, 0x1a94: 0x0f51, 0x1a95: 0x0359, 0x1a96: 0x0f61, 0x1a97: 0x0f71,\n\t0x1a98: 0x00d9, 0x1a99: 0x0f99, 0x1a9a: 0x2039, 0x1a9b: 0x0269, 0x1a9c: 0x01d9, 0x1a9d: 0x0fa9,\n\t0x1a9e: 0x0fb9, 0x1a9f: 0x1089, 0x1aa0: 0x0279, 0x1aa1: 0x0369, 0x1aa2: 0x0289, 0x1aa3: 0x13d1,\n\t0x1aa4: 0xba81, 0x1aa5: 0xba99, 0x1aa6: 0x0040, 0x1aa7: 0x0040, 0x1aa8: 0xbab1, 0x1aa9: 0x1099,\n\t0x1aaa: 0x10b1, 0x1aab: 0x10c9, 0x1aac: 0xbac9, 0x1aad: 0xbae1, 0x1aae: 0xbaf9, 0x1aaf: 0x1429,\n\t0x1ab0: 0x1a31, 0x1ab1: 0xbb11, 0x1ab2: 0xbb29, 0x1ab3: 0xbb41, 0x1ab4: 0xbb59, 0x1ab5: 0xbb71,\n\t0x1ab6: 0xbb89, 0x1ab7: 0x2109, 0x1ab8: 0x1111, 0x1ab9: 0x1429, 0x1aba: 0xbba1, 0x1abb: 0xbbb9,\n\t0x1abc: 0xbbd1, 0x1abd: 0x10e1, 0x1abe: 0x10f9, 0x1abf: 0xbbe9,\n\t// Block 0x6b, offset 0x1ac0\n\t0x1ac0: 0x2079, 0x1ac1: 0xbc01, 0x1ac2: 0xbab1, 0x1ac3: 0x1099, 0x1ac4: 0x10b1, 0x1ac5: 0x10c9,\n\t0x1ac6: 0xbac9, 0x1ac7: 0xbae1, 0x1ac8: 0xbaf9, 0x1ac9: 0x1429, 0x1aca: 0x1a31, 0x1acb: 0xbb11,\n\t0x1acc: 0xbb29, 0x1acd: 0xbb41, 0x1ace: 0xbb59, 0x1acf: 0xbb71, 0x1ad0: 0xbb89, 0x1ad1: 0x2109,\n\t0x1ad2: 0x1111, 0x1ad3: 0xbba1, 0x1ad4: 0xbba1, 0x1ad5: 0xbbb9, 0x1ad6: 0xbbd1, 0x1ad7: 0x10e1,\n\t0x1ad8: 0x10f9, 0x1ad9: 0xbbe9, 0x1ada: 0x2079, 0x1adb: 0xbc21, 0x1adc: 0xbac9, 0x1add: 0x1429,\n\t0x1ade: 0xbb11, 0x1adf: 0x10e1, 0x1ae0: 0x1111, 0x1ae1: 0x2109, 0x1ae2: 0xbab1, 0x1ae3: 0x1099,\n\t0x1ae4: 0x10b1, 0x1ae5: 0x10c9, 0x1ae6: 0xbac9, 0x1ae7: 0xbae1, 0x1ae8: 0xbaf9, 0x1ae9: 0x1429,\n\t0x1aea: 0x1a31, 0x1aeb: 0xbb11, 0x1aec: 0xbb29, 0x1aed: 0xbb41, 0x1aee: 0xbb59, 0x1aef: 0xbb71,\n\t0x1af0: 0xbb89, 0x1af1: 0x2109, 0x1af2: 0x1111, 0x1af3: 0x1429, 0x1af4: 0xbba1, 0x1af5: 0xbbb9,\n\t0x1af6: 0xbbd1, 0x1af7: 0x10e1, 0x1af8: 0x10f9, 0x1af9: 0xbbe9, 0x1afa: 0x2079, 0x1afb: 0xbc01,\n\t0x1afc: 0xbab1, 0x1afd: 0x1099, 0x1afe: 0x10b1, 0x1aff: 0x10c9,\n\t// Block 0x6c, offset 0x1b00\n\t0x1b00: 0xbac9, 0x1b01: 0xbae1, 0x1b02: 0xbaf9, 0x1b03: 0x1429, 0x1b04: 0x1a31, 0x1b05: 0xbb11,\n\t0x1b06: 0xbb29, 0x1b07: 0xbb41, 0x1b08: 0xbb59, 0x1b09: 0xbb71, 0x1b0a: 0xbb89, 0x1b0b: 0x2109,\n\t0x1b0c: 0x1111, 0x1b0d: 0xbba1, 0x1b0e: 0xbba1, 0x1b0f: 0xbbb9, 0x1b10: 0xbbd1, 0x1b11: 0x10e1,\n\t0x1b12: 0x10f9, 0x1b13: 0xbbe9, 0x1b14: 0x2079, 0x1b15: 0xbc21, 0x1b16: 0xbac9, 0x1b17: 0x1429,\n\t0x1b18: 0xbb11, 0x1b19: 0x10e1, 0x1b1a: 0x1111, 0x1b1b: 0x2109, 0x1b1c: 0xbab1, 0x1b1d: 0x1099,\n\t0x1b1e: 0x10b1, 0x1b1f: 0x10c9, 0x1b20: 0xbac9, 0x1b21: 0xbae1, 0x1b22: 0xbaf9, 0x1b23: 0x1429,\n\t0x1b24: 0x1a31, 0x1b25: 0xbb11, 0x1b26: 0xbb29, 0x1b27: 0xbb41, 0x1b28: 0xbb59, 0x1b29: 0xbb71,\n\t0x1b2a: 0xbb89, 0x1b2b: 0x2109, 0x1b2c: 0x1111, 0x1b2d: 0x1429, 0x1b2e: 0xbba1, 0x1b2f: 0xbbb9,\n\t0x1b30: 0xbbd1, 0x1b31: 0x10e1, 0x1b32: 0x10f9, 0x1b33: 0xbbe9, 0x1b34: 0x2079, 0x1b35: 0xbc01,\n\t0x1b36: 0xbab1, 0x1b37: 0x1099, 0x1b38: 0x10b1, 0x1b39: 0x10c9, 0x1b3a: 0xbac9, 0x1b3b: 0xbae1,\n\t0x1b3c: 0xbaf9, 0x1b3d: 0x1429, 0x1b3e: 0x1a31, 0x1b3f: 0xbb11,\n\t// Block 0x6d, offset 0x1b40\n\t0x1b40: 0xbb29, 0x1b41: 0xbb41, 0x1b42: 0xbb59, 0x1b43: 0xbb71, 0x1b44: 0xbb89, 0x1b45: 0x2109,\n\t0x1b46: 0x1111, 0x1b47: 0xbba1, 0x1b48: 0xbba1, 0x1b49: 0xbbb9, 0x1b4a: 0xbbd1, 0x1b4b: 0x10e1,\n\t0x1b4c: 0x10f9, 0x1b4d: 0xbbe9, 0x1b4e: 0x2079, 0x1b4f: 0xbc21, 0x1b50: 0xbac9, 0x1b51: 0x1429,\n\t0x1b52: 0xbb11, 0x1b53: 0x10e1, 0x1b54: 0x1111, 0x1b55: 0x2109, 0x1b56: 0xbab1, 0x1b57: 0x1099,\n\t0x1b58: 0x10b1, 0x1b59: 0x10c9, 0x1b5a: 0xbac9, 0x1b5b: 0xbae1, 0x1b5c: 0xbaf9, 0x1b5d: 0x1429,\n\t0x1b5e: 0x1a31, 0x1b5f: 0xbb11, 0x1b60: 0xbb29, 0x1b61: 0xbb41, 0x1b62: 0xbb59, 0x1b63: 0xbb71,\n\t0x1b64: 0xbb89, 0x1b65: 0x2109, 0x1b66: 0x1111, 0x1b67: 0x1429, 0x1b68: 0xbba1, 0x1b69: 0xbbb9,\n\t0x1b6a: 0xbbd1, 0x1b6b: 0x10e1, 0x1b6c: 0x10f9, 0x1b6d: 0xbbe9, 0x1b6e: 0x2079, 0x1b6f: 0xbc01,\n\t0x1b70: 0xbab1, 0x1b71: 0x1099, 0x1b72: 0x10b1, 0x1b73: 0x10c9, 0x1b74: 0xbac9, 0x1b75: 0xbae1,\n\t0x1b76: 0xbaf9, 0x1b77: 0x1429, 0x1b78: 0x1a31, 0x1b79: 0xbb11, 0x1b7a: 0xbb29, 0x1b7b: 0xbb41,\n\t0x1b7c: 0xbb59, 0x1b7d: 0xbb71, 0x1b7e: 0xbb89, 0x1b7f: 0x2109,\n\t// Block 0x6e, offset 0x1b80\n\t0x1b80: 0x1111, 0x1b81: 0xbba1, 0x1b82: 0xbba1, 0x1b83: 0xbbb9, 0x1b84: 0xbbd1, 0x1b85: 0x10e1,\n\t0x1b86: 0x10f9, 0x1b87: 0xbbe9, 0x1b88: 0x2079, 0x1b89: 0xbc21, 0x1b8a: 0xbac9, 0x1b8b: 0x1429,\n\t0x1b8c: 0xbb11, 0x1b8d: 0x10e1, 0x1b8e: 0x1111, 0x1b8f: 0x2109, 0x1b90: 0xbab1, 0x1b91: 0x1099,\n\t0x1b92: 0x10b1, 0x1b93: 0x10c9, 0x1b94: 0xbac9, 0x1b95: 0xbae1, 0x1b96: 0xbaf9, 0x1b97: 0x1429,\n\t0x1b98: 0x1a31, 0x1b99: 0xbb11, 0x1b9a: 0xbb29, 0x1b9b: 0xbb41, 0x1b9c: 0xbb59, 0x1b9d: 0xbb71,\n\t0x1b9e: 0xbb89, 0x1b9f: 0x2109, 0x1ba0: 0x1111, 0x1ba1: 0x1429, 0x1ba2: 0xbba1, 0x1ba3: 0xbbb9,\n\t0x1ba4: 0xbbd1, 0x1ba5: 0x10e1, 0x1ba6: 0x10f9, 0x1ba7: 0xbbe9, 0x1ba8: 0x2079, 0x1ba9: 0xbc01,\n\t0x1baa: 0xbab1, 0x1bab: 0x1099, 0x1bac: 0x10b1, 0x1bad: 0x10c9, 0x1bae: 0xbac9, 0x1baf: 0xbae1,\n\t0x1bb0: 0xbaf9, 0x1bb1: 0x1429, 0x1bb2: 0x1a31, 0x1bb3: 0xbb11, 0x1bb4: 0xbb29, 0x1bb5: 0xbb41,\n\t0x1bb6: 0xbb59, 0x1bb7: 0xbb71, 0x1bb8: 0xbb89, 0x1bb9: 0x2109, 0x1bba: 0x1111, 0x1bbb: 0xbba1,\n\t0x1bbc: 0xbba1, 0x1bbd: 0xbbb9, 0x1bbe: 0xbbd1, 0x1bbf: 0x10e1,\n\t// Block 0x6f, offset 0x1bc0\n\t0x1bc0: 0x10f9, 0x1bc1: 0xbbe9, 0x1bc2: 0x2079, 0x1bc3: 0xbc21, 0x1bc4: 0xbac9, 0x1bc5: 0x1429,\n\t0x1bc6: 0xbb11, 0x1bc7: 0x10e1, 0x1bc8: 0x1111, 0x1bc9: 0x2109, 0x1bca: 0xbc41, 0x1bcb: 0xbc41,\n\t0x1bcc: 0x0040, 0x1bcd: 0x0040, 0x1bce: 0x1f41, 0x1bcf: 0x00c9, 0x1bd0: 0x0069, 0x1bd1: 0x0079,\n\t0x1bd2: 0x1f51, 0x1bd3: 0x1f61, 0x1bd4: 0x1f71, 0x1bd5: 0x1f81, 0x1bd6: 0x1f91, 0x1bd7: 0x1fa1,\n\t0x1bd8: 0x1f41, 0x1bd9: 0x00c9, 0x1bda: 0x0069, 0x1bdb: 0x0079, 0x1bdc: 0x1f51, 0x1bdd: 0x1f61,\n\t0x1bde: 0x1f71, 0x1bdf: 0x1f81, 0x1be0: 0x1f91, 0x1be1: 0x1fa1, 0x1be2: 0x1f41, 0x1be3: 0x00c9,\n\t0x1be4: 0x0069, 0x1be5: 0x0079, 0x1be6: 0x1f51, 0x1be7: 0x1f61, 0x1be8: 0x1f71, 0x1be9: 0x1f81,\n\t0x1bea: 0x1f91, 0x1beb: 0x1fa1, 0x1bec: 0x1f41, 0x1bed: 0x00c9, 0x1bee: 0x0069, 0x1bef: 0x0079,\n\t0x1bf0: 0x1f51, 0x1bf1: 0x1f61, 0x1bf2: 0x1f71, 0x1bf3: 0x1f81, 0x1bf4: 0x1f91, 0x1bf5: 0x1fa1,\n\t0x1bf6: 0x1f41, 0x1bf7: 0x00c9, 0x1bf8: 0x0069, 0x1bf9: 0x0079, 0x1bfa: 0x1f51, 0x1bfb: 0x1f61,\n\t0x1bfc: 0x1f71, 0x1bfd: 0x1f81, 0x1bfe: 0x1f91, 0x1bff: 0x1fa1,\n\t// Block 0x70, offset 0x1c00\n\t0x1c00: 0xe115, 0x1c01: 0xe115, 0x1c02: 0xe135, 0x1c03: 0xe135, 0x1c04: 0xe115, 0x1c05: 0xe115,\n\t0x1c06: 0xe175, 0x1c07: 0xe175, 0x1c08: 0xe115, 0x1c09: 0xe115, 0x1c0a: 0xe135, 0x1c0b: 0xe135,\n\t0x1c0c: 0xe115, 0x1c0d: 0xe115, 0x1c0e: 0xe1f5, 0x1c0f: 0xe1f5, 0x1c10: 0xe115, 0x1c11: 0xe115,\n\t0x1c12: 0xe135, 0x1c13: 0xe135, 0x1c14: 0xe115, 0x1c15: 0xe115, 0x1c16: 0xe175, 0x1c17: 0xe175,\n\t0x1c18: 0xe115, 0x1c19: 0xe115, 0x1c1a: 0xe135, 0x1c1b: 0xe135, 0x1c1c: 0xe115, 0x1c1d: 0xe115,\n\t0x1c1e: 0x8b05, 0x1c1f: 0x8b05, 0x1c20: 0x04b5, 0x1c21: 0x04b5, 0x1c22: 0x0a08, 0x1c23: 0x0a08,\n\t0x1c24: 0x0a08, 0x1c25: 0x0a08, 0x1c26: 0x0a08, 0x1c27: 0x0a08, 0x1c28: 0x0a08, 0x1c29: 0x0a08,\n\t0x1c2a: 0x0a08, 0x1c2b: 0x0a08, 0x1c2c: 0x0a08, 0x1c2d: 0x0a08, 0x1c2e: 0x0a08, 0x1c2f: 0x0a08,\n\t0x1c30: 0x0a08, 0x1c31: 0x0a08, 0x1c32: 0x0a08, 0x1c33: 0x0a08, 0x1c34: 0x0a08, 0x1c35: 0x0a08,\n\t0x1c36: 0x0a08, 0x1c37: 0x0a08, 0x1c38: 0x0a08, 0x1c39: 0x0a08, 0x1c3a: 0x0a08, 0x1c3b: 0x0a08,\n\t0x1c3c: 0x0a08, 0x1c3d: 0x0a08, 0x1c3e: 0x0a08, 0x1c3f: 0x0a08,\n\t// Block 0x71, offset 0x1c40\n\t0x1c40: 0xb189, 0x1c41: 0xb1a1, 0x1c42: 0xb201, 0x1c43: 0xb249, 0x1c44: 0x0040, 0x1c45: 0xb411,\n\t0x1c46: 0xb291, 0x1c47: 0xb219, 0x1c48: 0xb309, 0x1c49: 0xb429, 0x1c4a: 0xb399, 0x1c4b: 0xb3b1,\n\t0x1c4c: 0xb3c9, 0x1c4d: 0xb3e1, 0x1c4e: 0xb2a9, 0x1c4f: 0xb339, 0x1c50: 0xb369, 0x1c51: 0xb2d9,\n\t0x1c52: 0xb381, 0x1c53: 0xb279, 0x1c54: 0xb2c1, 0x1c55: 0xb1d1, 0x1c56: 0xb1e9, 0x1c57: 0xb231,\n\t0x1c58: 0xb261, 0x1c59: 0xb2f1, 0x1c5a: 0xb321, 0x1c5b: 0xb351, 0x1c5c: 0xbc59, 0x1c5d: 0x7949,\n\t0x1c5e: 0xbc71, 0x1c5f: 0xbc89, 0x1c60: 0x0040, 0x1c61: 0xb1a1, 0x1c62: 0xb201, 0x1c63: 0x0040,\n\t0x1c64: 0xb3f9, 0x1c65: 0x0040, 0x1c66: 0x0040, 0x1c67: 0xb219, 0x1c68: 0x0040, 0x1c69: 0xb429,\n\t0x1c6a: 0xb399, 0x1c6b: 0xb3b1, 0x1c6c: 0xb3c9, 0x1c6d: 0xb3e1, 0x1c6e: 0xb2a9, 0x1c6f: 0xb339,\n\t0x1c70: 0xb369, 0x1c71: 0xb2d9, 0x1c72: 0xb381, 0x1c73: 0x0040, 0x1c74: 0xb2c1, 0x1c75: 0xb1d1,\n\t0x1c76: 0xb1e9, 0x1c77: 0xb231, 0x1c78: 0x0040, 0x1c79: 0xb2f1, 0x1c7a: 0x0040, 0x1c7b: 0xb351,\n\t0x1c7c: 0x0040, 0x1c7d: 0x0040, 0x1c7e: 0x0040, 0x1c7f: 0x0040,\n\t// Block 0x72, offset 0x1c80\n\t0x1c80: 0x0040, 0x1c81: 0x0040, 0x1c82: 0xb201, 0x1c83: 0x0040, 0x1c84: 0x0040, 0x1c85: 0x0040,\n\t0x1c86: 0x0040, 0x1c87: 0xb219, 0x1c88: 0x0040, 0x1c89: 0xb429, 0x1c8a: 0x0040, 0x1c8b: 0xb3b1,\n\t0x1c8c: 0x0040, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0x0040, 0x1c91: 0xb2d9,\n\t0x1c92: 0xb381, 0x1c93: 0x0040, 0x1c94: 0xb2c1, 0x1c95: 0x0040, 0x1c96: 0x0040, 0x1c97: 0xb231,\n\t0x1c98: 0x0040, 0x1c99: 0xb2f1, 0x1c9a: 0x0040, 0x1c9b: 0xb351, 0x1c9c: 0x0040, 0x1c9d: 0x7949,\n\t0x1c9e: 0x0040, 0x1c9f: 0xbc89, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0x0040,\n\t0x1ca4: 0xb3f9, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0xb219, 0x1ca8: 0xb309, 0x1ca9: 0xb429,\n\t0x1caa: 0xb399, 0x1cab: 0x0040, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339,\n\t0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0x0040, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1,\n\t0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0x0040, 0x1cb9: 0xb2f1, 0x1cba: 0xb321, 0x1cbb: 0xb351,\n\t0x1cbc: 0xbc59, 0x1cbd: 0x0040, 0x1cbe: 0xbc71, 0x1cbf: 0x0040,\n\t// Block 0x73, offset 0x1cc0\n\t0x1cc0: 0xb189, 0x1cc1: 0xb1a1, 0x1cc2: 0xb201, 0x1cc3: 0xb249, 0x1cc4: 0xb3f9, 0x1cc5: 0xb411,\n\t0x1cc6: 0xb291, 0x1cc7: 0xb219, 0x1cc8: 0xb309, 0x1cc9: 0xb429, 0x1cca: 0x0040, 0x1ccb: 0xb3b1,\n\t0x1ccc: 0xb3c9, 0x1ccd: 0xb3e1, 0x1cce: 0xb2a9, 0x1ccf: 0xb339, 0x1cd0: 0xb369, 0x1cd1: 0xb2d9,\n\t0x1cd2: 0xb381, 0x1cd3: 0xb279, 0x1cd4: 0xb2c1, 0x1cd5: 0xb1d1, 0x1cd6: 0xb1e9, 0x1cd7: 0xb231,\n\t0x1cd8: 0xb261, 0x1cd9: 0xb2f1, 0x1cda: 0xb321, 0x1cdb: 0xb351, 0x1cdc: 0x0040, 0x1cdd: 0x0040,\n\t0x1cde: 0x0040, 0x1cdf: 0x0040, 0x1ce0: 0x0040, 0x1ce1: 0xb1a1, 0x1ce2: 0xb201, 0x1ce3: 0xb249,\n\t0x1ce4: 0x0040, 0x1ce5: 0xb411, 0x1ce6: 0xb291, 0x1ce7: 0xb219, 0x1ce8: 0xb309, 0x1ce9: 0xb429,\n\t0x1cea: 0x0040, 0x1ceb: 0xb3b1, 0x1cec: 0xb3c9, 0x1ced: 0xb3e1, 0x1cee: 0xb2a9, 0x1cef: 0xb339,\n\t0x1cf0: 0xb369, 0x1cf1: 0xb2d9, 0x1cf2: 0xb381, 0x1cf3: 0xb279, 0x1cf4: 0xb2c1, 0x1cf5: 0xb1d1,\n\t0x1cf6: 0xb1e9, 0x1cf7: 0xb231, 0x1cf8: 0xb261, 0x1cf9: 0xb2f1, 0x1cfa: 0xb321, 0x1cfb: 0xb351,\n\t0x1cfc: 0x0040, 0x1cfd: 0x0040, 0x1cfe: 0x0040, 0x1cff: 0x0040,\n\t// Block 0x74, offset 0x1d00\n\t0x1d00: 0x0040, 0x1d01: 0xbca2, 0x1d02: 0xbcba, 0x1d03: 0xbcd2, 0x1d04: 0xbcea, 0x1d05: 0xbd02,\n\t0x1d06: 0xbd1a, 0x1d07: 0xbd32, 0x1d08: 0xbd4a, 0x1d09: 0xbd62, 0x1d0a: 0xbd7a, 0x1d0b: 0x0018,\n\t0x1d0c: 0x0018, 0x1d0d: 0x0040, 0x1d0e: 0x0040, 0x1d0f: 0x0040, 0x1d10: 0xbd92, 0x1d11: 0xbdb2,\n\t0x1d12: 0xbdd2, 0x1d13: 0xbdf2, 0x1d14: 0xbe12, 0x1d15: 0xbe32, 0x1d16: 0xbe52, 0x1d17: 0xbe72,\n\t0x1d18: 0xbe92, 0x1d19: 0xbeb2, 0x1d1a: 0xbed2, 0x1d1b: 0xbef2, 0x1d1c: 0xbf12, 0x1d1d: 0xbf32,\n\t0x1d1e: 0xbf52, 0x1d1f: 0xbf72, 0x1d20: 0xbf92, 0x1d21: 0xbfb2, 0x1d22: 0xbfd2, 0x1d23: 0xbff2,\n\t0x1d24: 0xc012, 0x1d25: 0xc032, 0x1d26: 0xc052, 0x1d27: 0xc072, 0x1d28: 0xc092, 0x1d29: 0xc0b2,\n\t0x1d2a: 0xc0d1, 0x1d2b: 0x1159, 0x1d2c: 0x0269, 0x1d2d: 0x6671, 0x1d2e: 0xc111, 0x1d2f: 0x0040,\n\t0x1d30: 0x0039, 0x1d31: 0x0ee9, 0x1d32: 0x1159, 0x1d33: 0x0ef9, 0x1d34: 0x0f09, 0x1d35: 0x1199,\n\t0x1d36: 0x0f31, 0x1d37: 0x0249, 0x1d38: 0x0f41, 0x1d39: 0x0259, 0x1d3a: 0x0f51, 0x1d3b: 0x0359,\n\t0x1d3c: 0x0f61, 0x1d3d: 0x0f71, 0x1d3e: 0x00d9, 0x1d3f: 0x0f99,\n\t// Block 0x75, offset 0x1d40\n\t0x1d40: 0x2039, 0x1d41: 0x0269, 0x1d42: 0x01d9, 0x1d43: 0x0fa9, 0x1d44: 0x0fb9, 0x1d45: 0x1089,\n\t0x1d46: 0x0279, 0x1d47: 0x0369, 0x1d48: 0x0289, 0x1d49: 0x13d1, 0x1d4a: 0xc129, 0x1d4b: 0x65b1,\n\t0x1d4c: 0xc141, 0x1d4d: 0x1441, 0x1d4e: 0xc159, 0x1d4f: 0xc179, 0x1d50: 0x0018, 0x1d51: 0x0018,\n\t0x1d52: 0x0018, 0x1d53: 0x0018, 0x1d54: 0x0018, 0x1d55: 0x0018, 0x1d56: 0x0018, 0x1d57: 0x0018,\n\t0x1d58: 0x0018, 0x1d59: 0x0018, 0x1d5a: 0x0018, 0x1d5b: 0x0018, 0x1d5c: 0x0018, 0x1d5d: 0x0018,\n\t0x1d5e: 0x0018, 0x1d5f: 0x0018, 0x1d60: 0x0018, 0x1d61: 0x0018, 0x1d62: 0x0018, 0x1d63: 0x0018,\n\t0x1d64: 0x0018, 0x1d65: 0x0018, 0x1d66: 0x0018, 0x1d67: 0x0018, 0x1d68: 0x0018, 0x1d69: 0x0018,\n\t0x1d6a: 0xc191, 0x1d6b: 0xc1a9, 0x1d6c: 0x0040, 0x1d6d: 0x0040, 0x1d6e: 0x0040, 0x1d6f: 0x0040,\n\t0x1d70: 0x0018, 0x1d71: 0x0018, 0x1d72: 0x0018, 0x1d73: 0x0018, 0x1d74: 0x0018, 0x1d75: 0x0018,\n\t0x1d76: 0x0018, 0x1d77: 0x0018, 0x1d78: 0x0018, 0x1d79: 0x0018, 0x1d7a: 0x0018, 0x1d7b: 0x0018,\n\t0x1d7c: 0x0018, 0x1d7d: 0x0018, 0x1d7e: 0x0018, 0x1d7f: 0x0018,\n\t// Block 0x76, offset 0x1d80\n\t0x1d80: 0xc1d9, 0x1d81: 0xc211, 0x1d82: 0xc249, 0x1d83: 0x0040, 0x1d84: 0x0040, 0x1d85: 0x0040,\n\t0x1d86: 0x0040, 0x1d87: 0x0040, 0x1d88: 0x0040, 0x1d89: 0x0040, 0x1d8a: 0x0040, 0x1d8b: 0x0040,\n\t0x1d8c: 0x0040, 0x1d8d: 0x0040, 0x1d8e: 0x0040, 0x1d8f: 0x0040, 0x1d90: 0xc269, 0x1d91: 0xc289,\n\t0x1d92: 0xc2a9, 0x1d93: 0xc2c9, 0x1d94: 0xc2e9, 0x1d95: 0xc309, 0x1d96: 0xc329, 0x1d97: 0xc349,\n\t0x1d98: 0xc369, 0x1d99: 0xc389, 0x1d9a: 0xc3a9, 0x1d9b: 0xc3c9, 0x1d9c: 0xc3e9, 0x1d9d: 0xc409,\n\t0x1d9e: 0xc429, 0x1d9f: 0xc449, 0x1da0: 0xc469, 0x1da1: 0xc489, 0x1da2: 0xc4a9, 0x1da3: 0xc4c9,\n\t0x1da4: 0xc4e9, 0x1da5: 0xc509, 0x1da6: 0xc529, 0x1da7: 0xc549, 0x1da8: 0xc569, 0x1da9: 0xc589,\n\t0x1daa: 0xc5a9, 0x1dab: 0xc5c9, 0x1dac: 0xc5e9, 0x1dad: 0xc609, 0x1dae: 0xc629, 0x1daf: 0xc649,\n\t0x1db0: 0xc669, 0x1db1: 0xc689, 0x1db2: 0xc6a9, 0x1db3: 0xc6c9, 0x1db4: 0xc6e9, 0x1db5: 0xc709,\n\t0x1db6: 0xc729, 0x1db7: 0xc749, 0x1db8: 0xc769, 0x1db9: 0xc789, 0x1dba: 0xc7a9, 0x1dbb: 0xc7c9,\n\t0x1dbc: 0x0040, 0x1dbd: 0x0040, 0x1dbe: 0x0040, 0x1dbf: 0x0040,\n\t// Block 0x77, offset 0x1dc0\n\t0x1dc0: 0xcaf9, 0x1dc1: 0xcb19, 0x1dc2: 0xcb39, 0x1dc3: 0x8b1d, 0x1dc4: 0xcb59, 0x1dc5: 0xcb79,\n\t0x1dc6: 0xcb99, 0x1dc7: 0xcbb9, 0x1dc8: 0xcbd9, 0x1dc9: 0xcbf9, 0x1dca: 0xcc19, 0x1dcb: 0xcc39,\n\t0x1dcc: 0xcc59, 0x1dcd: 0x8b3d, 0x1dce: 0xcc79, 0x1dcf: 0xcc99, 0x1dd0: 0xccb9, 0x1dd1: 0xccd9,\n\t0x1dd2: 0x8b5d, 0x1dd3: 0xccf9, 0x1dd4: 0xcd19, 0x1dd5: 0xc429, 0x1dd6: 0x8b7d, 0x1dd7: 0xcd39,\n\t0x1dd8: 0xcd59, 0x1dd9: 0xcd79, 0x1dda: 0xcd99, 0x1ddb: 0xcdb9, 0x1ddc: 0x8b9d, 0x1ddd: 0xcdd9,\n\t0x1dde: 0xcdf9, 0x1ddf: 0xce19, 0x1de0: 0xce39, 0x1de1: 0xce59, 0x1de2: 0xc789, 0x1de3: 0xce79,\n\t0x1de4: 0xce99, 0x1de5: 0xceb9, 0x1de6: 0xced9, 0x1de7: 0xcef9, 0x1de8: 0xcf19, 0x1de9: 0xcf39,\n\t0x1dea: 0xcf59, 0x1deb: 0xcf79, 0x1dec: 0xcf99, 0x1ded: 0xcfb9, 0x1dee: 0xcfd9, 0x1def: 0xcff9,\n\t0x1df0: 0xd019, 0x1df1: 0xd039, 0x1df2: 0xd039, 0x1df3: 0xd039, 0x1df4: 0x8bbd, 0x1df5: 0xd059,\n\t0x1df6: 0xd079, 0x1df7: 0xd099, 0x1df8: 0x8bdd, 0x1df9: 0xd0b9, 0x1dfa: 0xd0d9, 0x1dfb: 0xd0f9,\n\t0x1dfc: 0xd119, 0x1dfd: 0xd139, 0x1dfe: 0xd159, 0x1dff: 0xd179,\n\t// Block 0x78, offset 0x1e00\n\t0x1e00: 0xd199, 0x1e01: 0xd1b9, 0x1e02: 0xd1d9, 0x1e03: 0xd1f9, 0x1e04: 0xd219, 0x1e05: 0xd239,\n\t0x1e06: 0xd239, 0x1e07: 0xd259, 0x1e08: 0xd279, 0x1e09: 0xd299, 0x1e0a: 0xd2b9, 0x1e0b: 0xd2d9,\n\t0x1e0c: 0xd2f9, 0x1e0d: 0xd319, 0x1e0e: 0xd339, 0x1e0f: 0xd359, 0x1e10: 0xd379, 0x1e11: 0xd399,\n\t0x1e12: 0xd3b9, 0x1e13: 0xd3d9, 0x1e14: 0xd3f9, 0x1e15: 0xd419, 0x1e16: 0xd439, 0x1e17: 0xd459,\n\t0x1e18: 0xd479, 0x1e19: 0x8bfd, 0x1e1a: 0xd499, 0x1e1b: 0xd4b9, 0x1e1c: 0xd4d9, 0x1e1d: 0xc309,\n\t0x1e1e: 0xd4f9, 0x1e1f: 0xd519, 0x1e20: 0x8c1d, 0x1e21: 0x8c3d, 0x1e22: 0xd539, 0x1e23: 0xd559,\n\t0x1e24: 0xd579, 0x1e25: 0xd599, 0x1e26: 0xd5b9, 0x1e27: 0xd5d9, 0x1e28: 0x2040, 0x1e29: 0xd5f9,\n\t0x1e2a: 0xd619, 0x1e2b: 0xd619, 0x1e2c: 0x8c5d, 0x1e2d: 0xd639, 0x1e2e: 0xd659, 0x1e2f: 0xd679,\n\t0x1e30: 0xd699, 0x1e31: 0x8c7d, 0x1e32: 0xd6b9, 0x1e33: 0xd6d9, 0x1e34: 0x2040, 0x1e35: 0xd6f9,\n\t0x1e36: 0xd719, 0x1e37: 0xd739, 0x1e38: 0xd759, 0x1e39: 0xd779, 0x1e3a: 0xd799, 0x1e3b: 0x8c9d,\n\t0x1e3c: 0xd7b9, 0x1e3d: 0x8cbd, 0x1e3e: 0xd7d9, 0x1e3f: 0xd7f9,\n\t// Block 0x79, offset 0x1e40\n\t0x1e40: 0xd819, 0x1e41: 0xd839, 0x1e42: 0xd859, 0x1e43: 0xd879, 0x1e44: 0xd899, 0x1e45: 0xd8b9,\n\t0x1e46: 0xd8d9, 0x1e47: 0xd8f9, 0x1e48: 0xd919, 0x1e49: 0x8cdd, 0x1e4a: 0xd939, 0x1e4b: 0xd959,\n\t0x1e4c: 0xd979, 0x1e4d: 0xd999, 0x1e4e: 0xd9b9, 0x1e4f: 0x8cfd, 0x1e50: 0xd9d9, 0x1e51: 0x8d1d,\n\t0x1e52: 0x8d3d, 0x1e53: 0xd9f9, 0x1e54: 0xda19, 0x1e55: 0xda19, 0x1e56: 0xda39, 0x1e57: 0x8d5d,\n\t0x1e58: 0x8d7d, 0x1e59: 0xda59, 0x1e5a: 0xda79, 0x1e5b: 0xda99, 0x1e5c: 0xdab9, 0x1e5d: 0xdad9,\n\t0x1e5e: 0xdaf9, 0x1e5f: 0xdb19, 0x1e60: 0xdb39, 0x1e61: 0xdb59, 0x1e62: 0xdb79, 0x1e63: 0xdb99,\n\t0x1e64: 0x8d9d, 0x1e65: 0xdbb9, 0x1e66: 0xdbd9, 0x1e67: 0xdbf9, 0x1e68: 0xdc19, 0x1e69: 0xdbf9,\n\t0x1e6a: 0xdc39, 0x1e6b: 0xdc59, 0x1e6c: 0xdc79, 0x1e6d: 0xdc99, 0x1e6e: 0xdcb9, 0x1e6f: 0xdcd9,\n\t0x1e70: 0xdcf9, 0x1e71: 0xdd19, 0x1e72: 0xdd39, 0x1e73: 0xdd59, 0x1e74: 0xdd79, 0x1e75: 0xdd99,\n\t0x1e76: 0xddb9, 0x1e77: 0xddd9, 0x1e78: 0x8dbd, 0x1e79: 0xddf9, 0x1e7a: 0xde19, 0x1e7b: 0xde39,\n\t0x1e7c: 0xde59, 0x1e7d: 0xde79, 0x1e7e: 0x8ddd, 0x1e7f: 0xde99,\n\t// Block 0x7a, offset 0x1e80\n\t0x1e80: 0xe599, 0x1e81: 0xe5b9, 0x1e82: 0xe5d9, 0x1e83: 0xe5f9, 0x1e84: 0xe619, 0x1e85: 0xe639,\n\t0x1e86: 0x8efd, 0x1e87: 0xe659, 0x1e88: 0xe679, 0x1e89: 0xe699, 0x1e8a: 0xe6b9, 0x1e8b: 0xe6d9,\n\t0x1e8c: 0xe6f9, 0x1e8d: 0x8f1d, 0x1e8e: 0xe719, 0x1e8f: 0xe739, 0x1e90: 0x8f3d, 0x1e91: 0x8f5d,\n\t0x1e92: 0xe759, 0x1e93: 0xe779, 0x1e94: 0xe799, 0x1e95: 0xe7b9, 0x1e96: 0xe7d9, 0x1e97: 0xe7f9,\n\t0x1e98: 0xe819, 0x1e99: 0xe839, 0x1e9a: 0xe859, 0x1e9b: 0x8f7d, 0x1e9c: 0xe879, 0x1e9d: 0x8f9d,\n\t0x1e9e: 0xe899, 0x1e9f: 0x2040, 0x1ea0: 0xe8b9, 0x1ea1: 0xe8d9, 0x1ea2: 0xe8f9, 0x1ea3: 0x8fbd,\n\t0x1ea4: 0xe919, 0x1ea5: 0xe939, 0x1ea6: 0x8fdd, 0x1ea7: 0x8ffd, 0x1ea8: 0xe959, 0x1ea9: 0xe979,\n\t0x1eaa: 0xe999, 0x1eab: 0xe9b9, 0x1eac: 0xe9d9, 0x1ead: 0xe9d9, 0x1eae: 0xe9f9, 0x1eaf: 0xea19,\n\t0x1eb0: 0xea39, 0x1eb1: 0xea59, 0x1eb2: 0xea79, 0x1eb3: 0xea99, 0x1eb4: 0xeab9, 0x1eb5: 0x901d,\n\t0x1eb6: 0xead9, 0x1eb7: 0x903d, 0x1eb8: 0xeaf9, 0x1eb9: 0x905d, 0x1eba: 0xeb19, 0x1ebb: 0x907d,\n\t0x1ebc: 0x909d, 0x1ebd: 0x90bd, 0x1ebe: 0xeb39, 0x1ebf: 0xeb59,\n\t// Block 0x7b, offset 0x1ec0\n\t0x1ec0: 0xeb79, 0x1ec1: 0x90dd, 0x1ec2: 0x90fd, 0x1ec3: 0x911d, 0x1ec4: 0x913d, 0x1ec5: 0xeb99,\n\t0x1ec6: 0xebb9, 0x1ec7: 0xebb9, 0x1ec8: 0xebd9, 0x1ec9: 0xebf9, 0x1eca: 0xec19, 0x1ecb: 0xec39,\n\t0x1ecc: 0xec59, 0x1ecd: 0x915d, 0x1ece: 0xec79, 0x1ecf: 0xec99, 0x1ed0: 0xecb9, 0x1ed1: 0xecd9,\n\t0x1ed2: 0x917d, 0x1ed3: 0xecf9, 0x1ed4: 0x919d, 0x1ed5: 0x91bd, 0x1ed6: 0xed19, 0x1ed7: 0xed39,\n\t0x1ed8: 0xed59, 0x1ed9: 0xed79, 0x1eda: 0xed99, 0x1edb: 0xedb9, 0x1edc: 0x91dd, 0x1edd: 0x91fd,\n\t0x1ede: 0x921d, 0x1edf: 0x2040, 0x1ee0: 0xedd9, 0x1ee1: 0x923d, 0x1ee2: 0xedf9, 0x1ee3: 0xee19,\n\t0x1ee4: 0xee39, 0x1ee5: 0x925d, 0x1ee6: 0xee59, 0x1ee7: 0xee79, 0x1ee8: 0xee99, 0x1ee9: 0xeeb9,\n\t0x1eea: 0xeed9, 0x1eeb: 0x927d, 0x1eec: 0xeef9, 0x1eed: 0xef19, 0x1eee: 0xef39, 0x1eef: 0xef59,\n\t0x1ef0: 0xef79, 0x1ef1: 0xef99, 0x1ef2: 0x929d, 0x1ef3: 0x92bd, 0x1ef4: 0xefb9, 0x1ef5: 0x92dd,\n\t0x1ef6: 0xefd9, 0x1ef7: 0x92fd, 0x1ef8: 0xeff9, 0x1ef9: 0xf019, 0x1efa: 0xf039, 0x1efb: 0x931d,\n\t0x1efc: 0x933d, 0x1efd: 0xf059, 0x1efe: 0x935d, 0x1eff: 0xf079,\n\t// Block 0x7c, offset 0x1f00\n\t0x1f00: 0xf6b9, 0x1f01: 0xf6d9, 0x1f02: 0xf6f9, 0x1f03: 0xf719, 0x1f04: 0xf739, 0x1f05: 0x951d,\n\t0x1f06: 0xf759, 0x1f07: 0xf779, 0x1f08: 0xf799, 0x1f09: 0xf7b9, 0x1f0a: 0xf7d9, 0x1f0b: 0x953d,\n\t0x1f0c: 0x955d, 0x1f0d: 0xf7f9, 0x1f0e: 0xf819, 0x1f0f: 0xf839, 0x1f10: 0xf859, 0x1f11: 0xf879,\n\t0x1f12: 0xf899, 0x1f13: 0x957d, 0x1f14: 0xf8b9, 0x1f15: 0xf8d9, 0x1f16: 0xf8f9, 0x1f17: 0xf919,\n\t0x1f18: 0x959d, 0x1f19: 0x95bd, 0x1f1a: 0xf939, 0x1f1b: 0xf959, 0x1f1c: 0xf979, 0x1f1d: 0x95dd,\n\t0x1f1e: 0xf999, 0x1f1f: 0xf9b9, 0x1f20: 0x6815, 0x1f21: 0x95fd, 0x1f22: 0xf9d9, 0x1f23: 0xf9f9,\n\t0x1f24: 0xfa19, 0x1f25: 0x961d, 0x1f26: 0xfa39, 0x1f27: 0xfa59, 0x1f28: 0xfa79, 0x1f29: 0xfa99,\n\t0x1f2a: 0xfab9, 0x1f2b: 0xfad9, 0x1f2c: 0xfaf9, 0x1f2d: 0x963d, 0x1f2e: 0xfb19, 0x1f2f: 0xfb39,\n\t0x1f30: 0xfb59, 0x1f31: 0x965d, 0x1f32: 0xfb79, 0x1f33: 0xfb99, 0x1f34: 0xfbb9, 0x1f35: 0xfbd9,\n\t0x1f36: 0x7b35, 0x1f37: 0x967d, 0x1f38: 0xfbf9, 0x1f39: 0xfc19, 0x1f3a: 0xfc39, 0x1f3b: 0x969d,\n\t0x1f3c: 0xfc59, 0x1f3d: 0x96bd, 0x1f3e: 0xfc79, 0x1f3f: 0xfc79,\n\t// Block 0x7d, offset 0x1f40\n\t0x1f40: 0xfc99, 0x1f41: 0x96dd, 0x1f42: 0xfcb9, 0x1f43: 0xfcd9, 0x1f44: 0xfcf9, 0x1f45: 0xfd19,\n\t0x1f46: 0xfd39, 0x1f47: 0xfd59, 0x1f48: 0xfd79, 0x1f49: 0x96fd, 0x1f4a: 0xfd99, 0x1f4b: 0xfdb9,\n\t0x1f4c: 0xfdd9, 0x1f4d: 0xfdf9, 0x1f4e: 0xfe19, 0x1f4f: 0xfe39, 0x1f50: 0x971d, 0x1f51: 0xfe59,\n\t0x1f52: 0x973d, 0x1f53: 0x975d, 0x1f54: 0x977d, 0x1f55: 0xfe79, 0x1f56: 0xfe99, 0x1f57: 0xfeb9,\n\t0x1f58: 0xfed9, 0x1f59: 0xfef9, 0x1f5a: 0xff19, 0x1f5b: 0xff39, 0x1f5c: 0xff59, 0x1f5d: 0x979d,\n\t0x1f5e: 0x0040, 0x1f5f: 0x0040, 0x1f60: 0x0040, 0x1f61: 0x0040, 0x1f62: 0x0040, 0x1f63: 0x0040,\n\t0x1f64: 0x0040, 0x1f65: 0x0040, 0x1f66: 0x0040, 0x1f67: 0x0040, 0x1f68: 0x0040, 0x1f69: 0x0040,\n\t0x1f6a: 0x0040, 0x1f6b: 0x0040, 0x1f6c: 0x0040, 0x1f6d: 0x0040, 0x1f6e: 0x0040, 0x1f6f: 0x0040,\n\t0x1f70: 0x0040, 0x1f71: 0x0040, 0x1f72: 0x0040, 0x1f73: 0x0040, 0x1f74: 0x0040, 0x1f75: 0x0040,\n\t0x1f76: 0x0040, 0x1f77: 0x0040, 0x1f78: 0x0040, 0x1f79: 0x0040, 0x1f7a: 0x0040, 0x1f7b: 0x0040,\n\t0x1f7c: 0x0040, 0x1f7d: 0x0040, 0x1f7e: 0x0040, 0x1f7f: 0x0040,\n}\n\n// idnaIndex: 35 blocks, 2240 entries, 4480 bytes\n// Block 0 is the zero block.\nvar idnaIndex = [2240]uint16{\n\t// Block 0x0, offset 0x0\n\t// Block 0x1, offset 0x40\n\t// Block 0x2, offset 0x80\n\t// Block 0x3, offset 0xc0\n\t0xc2: 0x01, 0xc3: 0x7c, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05,\n\t0xc8: 0x06, 0xc9: 0x7d, 0xca: 0x7e, 0xcb: 0x07, 0xcc: 0x7f, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a,\n\t0xd0: 0x80, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x81, 0xd6: 0x82, 0xd7: 0x83,\n\t0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x84, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x85, 0xde: 0x86, 0xdf: 0x87,\n\t0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07,\n\t0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c,\n\t0xf0: 0x1c, 0xf1: 0x1d, 0xf2: 0x1d, 0xf3: 0x1f, 0xf4: 0x20,\n\t// Block 0x4, offset 0x100\n\t0x120: 0x88, 0x121: 0x89, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x13, 0x126: 0x14, 0x127: 0x15,\n\t0x128: 0x16, 0x129: 0x17, 0x12a: 0x18, 0x12b: 0x19, 0x12c: 0x1a, 0x12d: 0x1b, 0x12e: 0x1c, 0x12f: 0x8d,\n\t0x130: 0x8e, 0x131: 0x1d, 0x132: 0x1e, 0x133: 0x1f, 0x134: 0x8f, 0x135: 0x20, 0x136: 0x90, 0x137: 0x91,\n\t0x138: 0x92, 0x139: 0x93, 0x13a: 0x21, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x22, 0x13e: 0x23, 0x13f: 0x96,\n\t// Block 0x5, offset 0x140\n\t0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9d, 0x147: 0x9e,\n\t0x148: 0x9f, 0x149: 0xa0, 0x14a: 0xa1, 0x14b: 0xa2, 0x14c: 0xa3, 0x14d: 0xa4, 0x14e: 0xa5, 0x14f: 0xa6,\n\t0x150: 0xa7, 0x151: 0x9f, 0x152: 0x9f, 0x153: 0x9f, 0x154: 0x9f, 0x155: 0x9f, 0x156: 0x9f, 0x157: 0x9f,\n\t0x158: 0x9f, 0x159: 0xa8, 0x15a: 0xa9, 0x15b: 0xaa, 0x15c: 0xab, 0x15d: 0xac, 0x15e: 0xad, 0x15f: 0xae,\n\t0x160: 0xaf, 0x161: 0xb0, 0x162: 0xb1, 0x163: 0xb2, 0x164: 0xb3, 0x165: 0xb4, 0x166: 0xb5, 0x167: 0xb6,\n\t0x168: 0xb7, 0x169: 0xb8, 0x16a: 0xb9, 0x16b: 0xba, 0x16c: 0xbb, 0x16d: 0xbc, 0x16e: 0xbd, 0x16f: 0xbe,\n\t0x170: 0xbf, 0x171: 0xc0, 0x172: 0xc1, 0x173: 0xc2, 0x174: 0x24, 0x175: 0x25, 0x176: 0x26, 0x177: 0xc3,\n\t0x178: 0x27, 0x179: 0x27, 0x17a: 0x28, 0x17b: 0x27, 0x17c: 0xc4, 0x17d: 0x29, 0x17e: 0x2a, 0x17f: 0x2b,\n\t// Block 0x6, offset 0x180\n\t0x180: 0x2c, 0x181: 0x2d, 0x182: 0x2e, 0x183: 0xc5, 0x184: 0x2f, 0x185: 0x30, 0x186: 0xc6, 0x187: 0x9b,\n\t0x188: 0xc7, 0x189: 0xc8, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc9, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0xca,\n\t0x190: 0xcb, 0x191: 0x31, 0x192: 0x32, 0x193: 0x33, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b,\n\t0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b,\n\t0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b,\n\t0x1a8: 0xcc, 0x1a9: 0xcd, 0x1aa: 0x9b, 0x1ab: 0xce, 0x1ac: 0x9b, 0x1ad: 0xcf, 0x1ae: 0xd0, 0x1af: 0xd1,\n\t0x1b0: 0xd2, 0x1b1: 0x34, 0x1b2: 0x27, 0x1b3: 0x35, 0x1b4: 0xd3, 0x1b5: 0xd4, 0x1b6: 0xd5, 0x1b7: 0xd6,\n\t0x1b8: 0xd7, 0x1b9: 0xd8, 0x1ba: 0xd9, 0x1bb: 0xda, 0x1bc: 0xdb, 0x1bd: 0xdc, 0x1be: 0xdd, 0x1bf: 0x36,\n\t// Block 0x7, offset 0x1c0\n\t0x1c0: 0x37, 0x1c1: 0xde, 0x1c2: 0xdf, 0x1c3: 0xe0, 0x1c4: 0xe1, 0x1c5: 0x38, 0x1c6: 0x39, 0x1c7: 0xe2,\n\t0x1c8: 0xe3, 0x1c9: 0x3a, 0x1ca: 0x3b, 0x1cb: 0x3c, 0x1cc: 0x3d, 0x1cd: 0x3e, 0x1ce: 0x3f, 0x1cf: 0x40,\n\t0x1d0: 0x9f, 0x1d1: 0x9f, 0x1d2: 0x9f, 0x1d3: 0x9f, 0x1d4: 0x9f, 0x1d5: 0x9f, 0x1d6: 0x9f, 0x1d7: 0x9f,\n\t0x1d8: 0x9f, 0x1d9: 0x9f, 0x1da: 0x9f, 0x1db: 0x9f, 0x1dc: 0x9f, 0x1dd: 0x9f, 0x1de: 0x9f, 0x1df: 0x9f,\n\t0x1e0: 0x9f, 0x1e1: 0x9f, 0x1e2: 0x9f, 0x1e3: 0x9f, 0x1e4: 0x9f, 0x1e5: 0x9f, 0x1e6: 0x9f, 0x1e7: 0x9f,\n\t0x1e8: 0x9f, 0x1e9: 0x9f, 0x1ea: 0x9f, 0x1eb: 0x9f, 0x1ec: 0x9f, 0x1ed: 0x9f, 0x1ee: 0x9f, 0x1ef: 0x9f,\n\t0x1f0: 0x9f, 0x1f1: 0x9f, 0x1f2: 0x9f, 0x1f3: 0x9f, 0x1f4: 0x9f, 0x1f5: 0x9f, 0x1f6: 0x9f, 0x1f7: 0x9f,\n\t0x1f8: 0x9f, 0x1f9: 0x9f, 0x1fa: 0x9f, 0x1fb: 0x9f, 0x1fc: 0x9f, 0x1fd: 0x9f, 0x1fe: 0x9f, 0x1ff: 0x9f,\n\t// Block 0x8, offset 0x200\n\t0x200: 0x9f, 0x201: 0x9f, 0x202: 0x9f, 0x203: 0x9f, 0x204: 0x9f, 0x205: 0x9f, 0x206: 0x9f, 0x207: 0x9f,\n\t0x208: 0x9f, 0x209: 0x9f, 0x20a: 0x9f, 0x20b: 0x9f, 0x20c: 0x9f, 0x20d: 0x9f, 0x20e: 0x9f, 0x20f: 0x9f,\n\t0x210: 0x9f, 0x211: 0x9f, 0x212: 0x9f, 0x213: 0x9f, 0x214: 0x9f, 0x215: 0x9f, 0x216: 0x9f, 0x217: 0x9f,\n\t0x218: 0x9f, 0x219: 0x9f, 0x21a: 0x9f, 0x21b: 0x9f, 0x21c: 0x9f, 0x21d: 0x9f, 0x21e: 0x9f, 0x21f: 0x9f,\n\t0x220: 0x9f, 0x221: 0x9f, 0x222: 0x9f, 0x223: 0x9f, 0x224: 0x9f, 0x225: 0x9f, 0x226: 0x9f, 0x227: 0x9f,\n\t0x228: 0x9f, 0x229: 0x9f, 0x22a: 0x9f, 0x22b: 0x9f, 0x22c: 0x9f, 0x22d: 0x9f, 0x22e: 0x9f, 0x22f: 0x9f,\n\t0x230: 0x9f, 0x231: 0x9f, 0x232: 0x9f, 0x233: 0x9f, 0x234: 0x9f, 0x235: 0x9f, 0x236: 0xb2, 0x237: 0x9b,\n\t0x238: 0x9f, 0x239: 0x9f, 0x23a: 0x9f, 0x23b: 0x9f, 0x23c: 0x9f, 0x23d: 0x9f, 0x23e: 0x9f, 0x23f: 0x9f,\n\t// Block 0x9, offset 0x240\n\t0x240: 0x9f, 0x241: 0x9f, 0x242: 0x9f, 0x243: 0x9f, 0x244: 0x9f, 0x245: 0x9f, 0x246: 0x9f, 0x247: 0x9f,\n\t0x248: 0x9f, 0x249: 0x9f, 0x24a: 0x9f, 0x24b: 0x9f, 0x24c: 0x9f, 0x24d: 0x9f, 0x24e: 0x9f, 0x24f: 0x9f,\n\t0x250: 0x9f, 0x251: 0x9f, 0x252: 0x9f, 0x253: 0x9f, 0x254: 0x9f, 0x255: 0x9f, 0x256: 0x9f, 0x257: 0x9f,\n\t0x258: 0x9f, 0x259: 0x9f, 0x25a: 0x9f, 0x25b: 0x9f, 0x25c: 0x9f, 0x25d: 0x9f, 0x25e: 0x9f, 0x25f: 0x9f,\n\t0x260: 0x9f, 0x261: 0x9f, 0x262: 0x9f, 0x263: 0x9f, 0x264: 0x9f, 0x265: 0x9f, 0x266: 0x9f, 0x267: 0x9f,\n\t0x268: 0x9f, 0x269: 0x9f, 0x26a: 0x9f, 0x26b: 0x9f, 0x26c: 0x9f, 0x26d: 0x9f, 0x26e: 0x9f, 0x26f: 0x9f,\n\t0x270: 0x9f, 0x271: 0x9f, 0x272: 0x9f, 0x273: 0x9f, 0x274: 0x9f, 0x275: 0x9f, 0x276: 0x9f, 0x277: 0x9f,\n\t0x278: 0x9f, 0x279: 0x9f, 0x27a: 0x9f, 0x27b: 0x9f, 0x27c: 0x9f, 0x27d: 0x9f, 0x27e: 0x9f, 0x27f: 0x9f,\n\t// Block 0xa, offset 0x280\n\t0x280: 0x9f, 0x281: 0x9f, 0x282: 0x9f, 0x283: 0x9f, 0x284: 0x9f, 0x285: 0x9f, 0x286: 0x9f, 0x287: 0x9f,\n\t0x288: 0x9f, 0x289: 0x9f, 0x28a: 0x9f, 0x28b: 0x9f, 0x28c: 0x9f, 0x28d: 0x9f, 0x28e: 0x9f, 0x28f: 0x9f,\n\t0x290: 0x9f, 0x291: 0x9f, 0x292: 0x9f, 0x293: 0x9f, 0x294: 0x9f, 0x295: 0x9f, 0x296: 0x9f, 0x297: 0x9f,\n\t0x298: 0x9f, 0x299: 0x9f, 0x29a: 0x9f, 0x29b: 0x9f, 0x29c: 0x9f, 0x29d: 0x9f, 0x29e: 0x9f, 0x29f: 0x9f,\n\t0x2a0: 0x9f, 0x2a1: 0x9f, 0x2a2: 0x9f, 0x2a3: 0x9f, 0x2a4: 0x9f, 0x2a5: 0x9f, 0x2a6: 0x9f, 0x2a7: 0x9f,\n\t0x2a8: 0x9f, 0x2a9: 0x9f, 0x2aa: 0x9f, 0x2ab: 0x9f, 0x2ac: 0x9f, 0x2ad: 0x9f, 0x2ae: 0x9f, 0x2af: 0x9f,\n\t0x2b0: 0x9f, 0x2b1: 0x9f, 0x2b2: 0x9f, 0x2b3: 0x9f, 0x2b4: 0x9f, 0x2b5: 0x9f, 0x2b6: 0x9f, 0x2b7: 0x9f,\n\t0x2b8: 0x9f, 0x2b9: 0x9f, 0x2ba: 0x9f, 0x2bb: 0x9f, 0x2bc: 0x9f, 0x2bd: 0x9f, 0x2be: 0x9f, 0x2bf: 0xe4,\n\t// Block 0xb, offset 0x2c0\n\t0x2c0: 0x9f, 0x2c1: 0x9f, 0x2c2: 0x9f, 0x2c3: 0x9f, 0x2c4: 0x9f, 0x2c5: 0x9f, 0x2c6: 0x9f, 0x2c7: 0x9f,\n\t0x2c8: 0x9f, 0x2c9: 0x9f, 0x2ca: 0x9f, 0x2cb: 0x9f, 0x2cc: 0x9f, 0x2cd: 0x9f, 0x2ce: 0x9f, 0x2cf: 0x9f,\n\t0x2d0: 0x9f, 0x2d1: 0x9f, 0x2d2: 0xe5, 0x2d3: 0xe6, 0x2d4: 0x9f, 0x2d5: 0x9f, 0x2d6: 0x9f, 0x2d7: 0x9f,\n\t0x2d8: 0xe7, 0x2d9: 0x41, 0x2da: 0x42, 0x2db: 0xe8, 0x2dc: 0x43, 0x2dd: 0x44, 0x2de: 0x45, 0x2df: 0xe9,\n\t0x2e0: 0xea, 0x2e1: 0xeb, 0x2e2: 0xec, 0x2e3: 0xed, 0x2e4: 0xee, 0x2e5: 0xef, 0x2e6: 0xf0, 0x2e7: 0xf1,\n\t0x2e8: 0xf2, 0x2e9: 0xf3, 0x2ea: 0xf4, 0x2eb: 0xf5, 0x2ec: 0xf6, 0x2ed: 0xf7, 0x2ee: 0xf8, 0x2ef: 0xf9,\n\t0x2f0: 0x9f, 0x2f1: 0x9f, 0x2f2: 0x9f, 0x2f3: 0x9f, 0x2f4: 0x9f, 0x2f5: 0x9f, 0x2f6: 0x9f, 0x2f7: 0x9f,\n\t0x2f8: 0x9f, 0x2f9: 0x9f, 0x2fa: 0x9f, 0x2fb: 0x9f, 0x2fc: 0x9f, 0x2fd: 0x9f, 0x2fe: 0x9f, 0x2ff: 0x9f,\n\t// Block 0xc, offset 0x300\n\t0x300: 0x9f, 0x301: 0x9f, 0x302: 0x9f, 0x303: 0x9f, 0x304: 0x9f, 0x305: 0x9f, 0x306: 0x9f, 0x307: 0x9f,\n\t0x308: 0x9f, 0x309: 0x9f, 0x30a: 0x9f, 0x30b: 0x9f, 0x30c: 0x9f, 0x30d: 0x9f, 0x30e: 0x9f, 0x30f: 0x9f,\n\t0x310: 0x9f, 0x311: 0x9f, 0x312: 0x9f, 0x313: 0x9f, 0x314: 0x9f, 0x315: 0x9f, 0x316: 0x9f, 0x317: 0x9f,\n\t0x318: 0x9f, 0x319: 0x9f, 0x31a: 0x9f, 0x31b: 0x9f, 0x31c: 0x9f, 0x31d: 0x9f, 0x31e: 0xfa, 0x31f: 0xfb,\n\t// Block 0xd, offset 0x340\n\t0x340: 0xba, 0x341: 0xba, 0x342: 0xba, 0x343: 0xba, 0x344: 0xba, 0x345: 0xba, 0x346: 0xba, 0x347: 0xba,\n\t0x348: 0xba, 0x349: 0xba, 0x34a: 0xba, 0x34b: 0xba, 0x34c: 0xba, 0x34d: 0xba, 0x34e: 0xba, 0x34f: 0xba,\n\t0x350: 0xba, 0x351: 0xba, 0x352: 0xba, 0x353: 0xba, 0x354: 0xba, 0x355: 0xba, 0x356: 0xba, 0x357: 0xba,\n\t0x358: 0xba, 0x359: 0xba, 0x35a: 0xba, 0x35b: 0xba, 0x35c: 0xba, 0x35d: 0xba, 0x35e: 0xba, 0x35f: 0xba,\n\t0x360: 0xba, 0x361: 0xba, 0x362: 0xba, 0x363: 0xba, 0x364: 0xba, 0x365: 0xba, 0x366: 0xba, 0x367: 0xba,\n\t0x368: 0xba, 0x369: 0xba, 0x36a: 0xba, 0x36b: 0xba, 0x36c: 0xba, 0x36d: 0xba, 0x36e: 0xba, 0x36f: 0xba,\n\t0x370: 0xba, 0x371: 0xba, 0x372: 0xba, 0x373: 0xba, 0x374: 0xba, 0x375: 0xba, 0x376: 0xba, 0x377: 0xba,\n\t0x378: 0xba, 0x379: 0xba, 0x37a: 0xba, 0x37b: 0xba, 0x37c: 0xba, 0x37d: 0xba, 0x37e: 0xba, 0x37f: 0xba,\n\t// Block 0xe, offset 0x380\n\t0x380: 0xba, 0x381: 0xba, 0x382: 0xba, 0x383: 0xba, 0x384: 0xba, 0x385: 0xba, 0x386: 0xba, 0x387: 0xba,\n\t0x388: 0xba, 0x389: 0xba, 0x38a: 0xba, 0x38b: 0xba, 0x38c: 0xba, 0x38d: 0xba, 0x38e: 0xba, 0x38f: 0xba,\n\t0x390: 0xba, 0x391: 0xba, 0x392: 0xba, 0x393: 0xba, 0x394: 0xba, 0x395: 0xba, 0x396: 0xba, 0x397: 0xba,\n\t0x398: 0xba, 0x399: 0xba, 0x39a: 0xba, 0x39b: 0xba, 0x39c: 0xba, 0x39d: 0xba, 0x39e: 0xba, 0x39f: 0xba,\n\t0x3a0: 0xba, 0x3a1: 0xba, 0x3a2: 0xba, 0x3a3: 0xba, 0x3a4: 0xfc, 0x3a5: 0xfd, 0x3a6: 0xfe, 0x3a7: 0xff,\n\t0x3a8: 0x46, 0x3a9: 0x100, 0x3aa: 0x101, 0x3ab: 0x47, 0x3ac: 0x48, 0x3ad: 0x49, 0x3ae: 0x4a, 0x3af: 0x4b,\n\t0x3b0: 0x102, 0x3b1: 0x4c, 0x3b2: 0x4d, 0x3b3: 0x4e, 0x3b4: 0x4f, 0x3b5: 0x50, 0x3b6: 0x103, 0x3b7: 0x51,\n\t0x3b8: 0x52, 0x3b9: 0x53, 0x3ba: 0x54, 0x3bb: 0x55, 0x3bc: 0x56, 0x3bd: 0x57, 0x3be: 0x58, 0x3bf: 0x59,\n\t// Block 0xf, offset 0x3c0\n\t0x3c0: 0x104, 0x3c1: 0x105, 0x3c2: 0x9f, 0x3c3: 0x106, 0x3c4: 0x107, 0x3c5: 0x9b, 0x3c6: 0x108, 0x3c7: 0x109,\n\t0x3c8: 0xba, 0x3c9: 0xba, 0x3ca: 0x10a, 0x3cb: 0x10b, 0x3cc: 0x10c, 0x3cd: 0x10d, 0x3ce: 0x10e, 0x3cf: 0x10f,\n\t0x3d0: 0x110, 0x3d1: 0x9f, 0x3d2: 0x111, 0x3d3: 0x112, 0x3d4: 0x113, 0x3d5: 0x114, 0x3d6: 0xba, 0x3d7: 0xba,\n\t0x3d8: 0x9f, 0x3d9: 0x9f, 0x3da: 0x9f, 0x3db: 0x9f, 0x3dc: 0x115, 0x3dd: 0x116, 0x3de: 0xba, 0x3df: 0xba,\n\t0x3e0: 0x117, 0x3e1: 0x118, 0x3e2: 0x119, 0x3e3: 0x11a, 0x3e4: 0x11b, 0x3e5: 0xba, 0x3e6: 0x11c, 0x3e7: 0x11d,\n\t0x3e8: 0x11e, 0x3e9: 0x11f, 0x3ea: 0x120, 0x3eb: 0x5a, 0x3ec: 0x121, 0x3ed: 0x122, 0x3ee: 0x5b, 0x3ef: 0xba,\n\t0x3f0: 0x123, 0x3f1: 0x124, 0x3f2: 0x125, 0x3f3: 0x126, 0x3f4: 0xba, 0x3f5: 0xba, 0x3f6: 0xba, 0x3f7: 0xba,\n\t0x3f8: 0xba, 0x3f9: 0x127, 0x3fa: 0xba, 0x3fb: 0xba, 0x3fc: 0xba, 0x3fd: 0xba, 0x3fe: 0xba, 0x3ff: 0xba,\n\t// Block 0x10, offset 0x400\n\t0x400: 0x128, 0x401: 0x129, 0x402: 0x12a, 0x403: 0x12b, 0x404: 0x12c, 0x405: 0x12d, 0x406: 0x12e, 0x407: 0x12f,\n\t0x408: 0x130, 0x409: 0xba, 0x40a: 0x131, 0x40b: 0x132, 0x40c: 0x5c, 0x40d: 0x5d, 0x40e: 0xba, 0x40f: 0xba,\n\t0x410: 0x133, 0x411: 0x134, 0x412: 0x135, 0x413: 0x136, 0x414: 0xba, 0x415: 0xba, 0x416: 0x137, 0x417: 0x138,\n\t0x418: 0x139, 0x419: 0x13a, 0x41a: 0x13b, 0x41b: 0x13c, 0x41c: 0x13d, 0x41d: 0xba, 0x41e: 0xba, 0x41f: 0xba,\n\t0x420: 0xba, 0x421: 0xba, 0x422: 0x13e, 0x423: 0x13f, 0x424: 0xba, 0x425: 0xba, 0x426: 0xba, 0x427: 0xba,\n\t0x428: 0xba, 0x429: 0xba, 0x42a: 0xba, 0x42b: 0x140, 0x42c: 0xba, 0x42d: 0xba, 0x42e: 0xba, 0x42f: 0xba,\n\t0x430: 0x141, 0x431: 0x142, 0x432: 0x143, 0x433: 0xba, 0x434: 0xba, 0x435: 0xba, 0x436: 0xba, 0x437: 0xba,\n\t0x438: 0xba, 0x439: 0xba, 0x43a: 0xba, 0x43b: 0xba, 0x43c: 0xba, 0x43d: 0xba, 0x43e: 0xba, 0x43f: 0xba,\n\t// Block 0x11, offset 0x440\n\t0x440: 0x9f, 0x441: 0x9f, 0x442: 0x9f, 0x443: 0x9f, 0x444: 0x9f, 0x445: 0x9f, 0x446: 0x9f, 0x447: 0x9f,\n\t0x448: 0x9f, 0x449: 0x9f, 0x44a: 0x9f, 0x44b: 0x9f, 0x44c: 0x9f, 0x44d: 0x9f, 0x44e: 0x144, 0x44f: 0xba,\n\t0x450: 0x9b, 0x451: 0x145, 0x452: 0x9f, 0x453: 0x9f, 0x454: 0x9f, 0x455: 0x146, 0x456: 0xba, 0x457: 0xba,\n\t0x458: 0xba, 0x459: 0xba, 0x45a: 0xba, 0x45b: 0xba, 0x45c: 0xba, 0x45d: 0xba, 0x45e: 0xba, 0x45f: 0xba,\n\t0x460: 0xba, 0x461: 0xba, 0x462: 0xba, 0x463: 0xba, 0x464: 0xba, 0x465: 0xba, 0x466: 0xba, 0x467: 0xba,\n\t0x468: 0xba, 0x469: 0xba, 0x46a: 0xba, 0x46b: 0xba, 0x46c: 0xba, 0x46d: 0xba, 0x46e: 0xba, 0x46f: 0xba,\n\t0x470: 0xba, 0x471: 0xba, 0x472: 0xba, 0x473: 0xba, 0x474: 0xba, 0x475: 0xba, 0x476: 0xba, 0x477: 0xba,\n\t0x478: 0xba, 0x479: 0xba, 0x47a: 0xba, 0x47b: 0xba, 0x47c: 0xba, 0x47d: 0xba, 0x47e: 0xba, 0x47f: 0xba,\n\t// Block 0x12, offset 0x480\n\t0x480: 0x9f, 0x481: 0x9f, 0x482: 0x9f, 0x483: 0x9f, 0x484: 0x9f, 0x485: 0x9f, 0x486: 0x9f, 0x487: 0x9f,\n\t0x488: 0x9f, 0x489: 0x9f, 0x48a: 0x9f, 0x48b: 0x9f, 0x48c: 0x9f, 0x48d: 0x9f, 0x48e: 0x9f, 0x48f: 0x9f,\n\t0x490: 0x147, 0x491: 0xba, 0x492: 0xba, 0x493: 0xba, 0x494: 0xba, 0x495: 0xba, 0x496: 0xba, 0x497: 0xba,\n\t0x498: 0xba, 0x499: 0xba, 0x49a: 0xba, 0x49b: 0xba, 0x49c: 0xba, 0x49d: 0xba, 0x49e: 0xba, 0x49f: 0xba,\n\t0x4a0: 0xba, 0x4a1: 0xba, 0x4a2: 0xba, 0x4a3: 0xba, 0x4a4: 0xba, 0x4a5: 0xba, 0x4a6: 0xba, 0x4a7: 0xba,\n\t0x4a8: 0xba, 0x4a9: 0xba, 0x4aa: 0xba, 0x4ab: 0xba, 0x4ac: 0xba, 0x4ad: 0xba, 0x4ae: 0xba, 0x4af: 0xba,\n\t0x4b0: 0xba, 0x4b1: 0xba, 0x4b2: 0xba, 0x4b3: 0xba, 0x4b4: 0xba, 0x4b5: 0xba, 0x4b6: 0xba, 0x4b7: 0xba,\n\t0x4b8: 0xba, 0x4b9: 0xba, 0x4ba: 0xba, 0x4bb: 0xba, 0x4bc: 0xba, 0x4bd: 0xba, 0x4be: 0xba, 0x4bf: 0xba,\n\t// Block 0x13, offset 0x4c0\n\t0x4c0: 0xba, 0x4c1: 0xba, 0x4c2: 0xba, 0x4c3: 0xba, 0x4c4: 0xba, 0x4c5: 0xba, 0x4c6: 0xba, 0x4c7: 0xba,\n\t0x4c8: 0xba, 0x4c9: 0xba, 0x4ca: 0xba, 0x4cb: 0xba, 0x4cc: 0xba, 0x4cd: 0xba, 0x4ce: 0xba, 0x4cf: 0xba,\n\t0x4d0: 0x9f, 0x4d1: 0x9f, 0x4d2: 0x9f, 0x4d3: 0x9f, 0x4d4: 0x9f, 0x4d5: 0x9f, 0x4d6: 0x9f, 0x4d7: 0x9f,\n\t0x4d8: 0x9f, 0x4d9: 0x148, 0x4da: 0xba, 0x4db: 0xba, 0x4dc: 0xba, 0x4dd: 0xba, 0x4de: 0xba, 0x4df: 0xba,\n\t0x4e0: 0xba, 0x4e1: 0xba, 0x4e2: 0xba, 0x4e3: 0xba, 0x4e4: 0xba, 0x4e5: 0xba, 0x4e6: 0xba, 0x4e7: 0xba,\n\t0x4e8: 0xba, 0x4e9: 0xba, 0x4ea: 0xba, 0x4eb: 0xba, 0x4ec: 0xba, 0x4ed: 0xba, 0x4ee: 0xba, 0x4ef: 0xba,\n\t0x4f0: 0xba, 0x4f1: 0xba, 0x4f2: 0xba, 0x4f3: 0xba, 0x4f4: 0xba, 0x4f5: 0xba, 0x4f6: 0xba, 0x4f7: 0xba,\n\t0x4f8: 0xba, 0x4f9: 0xba, 0x4fa: 0xba, 0x4fb: 0xba, 0x4fc: 0xba, 0x4fd: 0xba, 0x4fe: 0xba, 0x4ff: 0xba,\n\t// Block 0x14, offset 0x500\n\t0x500: 0xba, 0x501: 0xba, 0x502: 0xba, 0x503: 0xba, 0x504: 0xba, 0x505: 0xba, 0x506: 0xba, 0x507: 0xba,\n\t0x508: 0xba, 0x509: 0xba, 0x50a: 0xba, 0x50b: 0xba, 0x50c: 0xba, 0x50d: 0xba, 0x50e: 0xba, 0x50f: 0xba,\n\t0x510: 0xba, 0x511: 0xba, 0x512: 0xba, 0x513: 0xba, 0x514: 0xba, 0x515: 0xba, 0x516: 0xba, 0x517: 0xba,\n\t0x518: 0xba, 0x519: 0xba, 0x51a: 0xba, 0x51b: 0xba, 0x51c: 0xba, 0x51d: 0xba, 0x51e: 0xba, 0x51f: 0xba,\n\t0x520: 0x9f, 0x521: 0x9f, 0x522: 0x9f, 0x523: 0x9f, 0x524: 0x9f, 0x525: 0x9f, 0x526: 0x9f, 0x527: 0x9f,\n\t0x528: 0x140, 0x529: 0x149, 0x52a: 0xba, 0x52b: 0x14a, 0x52c: 0x14b, 0x52d: 0x14c, 0x52e: 0x14d, 0x52f: 0xba,\n\t0x530: 0xba, 0x531: 0xba, 0x532: 0xba, 0x533: 0xba, 0x534: 0xba, 0x535: 0xba, 0x536: 0xba, 0x537: 0xba,\n\t0x538: 0xba, 0x539: 0xba, 0x53a: 0xba, 0x53b: 0xba, 0x53c: 0x9f, 0x53d: 0x14e, 0x53e: 0x14f, 0x53f: 0x150,\n\t// Block 0x15, offset 0x540\n\t0x540: 0x9f, 0x541: 0x9f, 0x542: 0x9f, 0x543: 0x9f, 0x544: 0x9f, 0x545: 0x9f, 0x546: 0x9f, 0x547: 0x9f,\n\t0x548: 0x9f, 0x549: 0x9f, 0x54a: 0x9f, 0x54b: 0x9f, 0x54c: 0x9f, 0x54d: 0x9f, 0x54e: 0x9f, 0x54f: 0x9f,\n\t0x550: 0x9f, 0x551: 0x9f, 0x552: 0x9f, 0x553: 0x9f, 0x554: 0x9f, 0x555: 0x9f, 0x556: 0x9f, 0x557: 0x9f,\n\t0x558: 0x9f, 0x559: 0x9f, 0x55a: 0x9f, 0x55b: 0x9f, 0x55c: 0x9f, 0x55d: 0x9f, 0x55e: 0x9f, 0x55f: 0x151,\n\t0x560: 0x9f, 0x561: 0x9f, 0x562: 0x9f, 0x563: 0x9f, 0x564: 0x9f, 0x565: 0x9f, 0x566: 0x9f, 0x567: 0x9f,\n\t0x568: 0x9f, 0x569: 0x9f, 0x56a: 0x9f, 0x56b: 0x152, 0x56c: 0xba, 0x56d: 0xba, 0x56e: 0xba, 0x56f: 0xba,\n\t0x570: 0xba, 0x571: 0xba, 0x572: 0xba, 0x573: 0xba, 0x574: 0xba, 0x575: 0xba, 0x576: 0xba, 0x577: 0xba,\n\t0x578: 0xba, 0x579: 0xba, 0x57a: 0xba, 0x57b: 0xba, 0x57c: 0xba, 0x57d: 0xba, 0x57e: 0xba, 0x57f: 0xba,\n\t// Block 0x16, offset 0x580\n\t0x580: 0x153, 0x581: 0xba, 0x582: 0xba, 0x583: 0xba, 0x584: 0xba, 0x585: 0xba, 0x586: 0xba, 0x587: 0xba,\n\t0x588: 0xba, 0x589: 0xba, 0x58a: 0xba, 0x58b: 0xba, 0x58c: 0xba, 0x58d: 0xba, 0x58e: 0xba, 0x58f: 0xba,\n\t0x590: 0xba, 0x591: 0xba, 0x592: 0xba, 0x593: 0xba, 0x594: 0xba, 0x595: 0xba, 0x596: 0xba, 0x597: 0xba,\n\t0x598: 0xba, 0x599: 0xba, 0x59a: 0xba, 0x59b: 0xba, 0x59c: 0xba, 0x59d: 0xba, 0x59e: 0xba, 0x59f: 0xba,\n\t0x5a0: 0xba, 0x5a1: 0xba, 0x5a2: 0xba, 0x5a3: 0xba, 0x5a4: 0xba, 0x5a5: 0xba, 0x5a6: 0xba, 0x5a7: 0xba,\n\t0x5a8: 0xba, 0x5a9: 0xba, 0x5aa: 0xba, 0x5ab: 0xba, 0x5ac: 0xba, 0x5ad: 0xba, 0x5ae: 0xba, 0x5af: 0xba,\n\t0x5b0: 0x9f, 0x5b1: 0x154, 0x5b2: 0x155, 0x5b3: 0xba, 0x5b4: 0xba, 0x5b5: 0xba, 0x5b6: 0xba, 0x5b7: 0xba,\n\t0x5b8: 0xba, 0x5b9: 0xba, 0x5ba: 0xba, 0x5bb: 0xba, 0x5bc: 0xba, 0x5bd: 0xba, 0x5be: 0xba, 0x5bf: 0xba,\n\t// Block 0x17, offset 0x5c0\n\t0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x156, 0x5c4: 0x157, 0x5c5: 0x158, 0x5c6: 0x159, 0x5c7: 0x15a,\n\t0x5c8: 0x9b, 0x5c9: 0x15b, 0x5ca: 0xba, 0x5cb: 0xba, 0x5cc: 0x9b, 0x5cd: 0x15c, 0x5ce: 0xba, 0x5cf: 0xba,\n\t0x5d0: 0x5e, 0x5d1: 0x5f, 0x5d2: 0x60, 0x5d3: 0x61, 0x5d4: 0x62, 0x5d5: 0x63, 0x5d6: 0x64, 0x5d7: 0x65,\n\t0x5d8: 0x66, 0x5d9: 0x67, 0x5da: 0x68, 0x5db: 0x69, 0x5dc: 0x6a, 0x5dd: 0x6b, 0x5de: 0x6c, 0x5df: 0x6d,\n\t0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b,\n\t0x5e8: 0x15d, 0x5e9: 0x15e, 0x5ea: 0x15f, 0x5eb: 0xba, 0x5ec: 0xba, 0x5ed: 0xba, 0x5ee: 0xba, 0x5ef: 0xba,\n\t0x5f0: 0xba, 0x5f1: 0xba, 0x5f2: 0xba, 0x5f3: 0xba, 0x5f4: 0xba, 0x5f5: 0xba, 0x5f6: 0xba, 0x5f7: 0xba,\n\t0x5f8: 0xba, 0x5f9: 0xba, 0x5fa: 0xba, 0x5fb: 0xba, 0x5fc: 0xba, 0x5fd: 0xba, 0x5fe: 0xba, 0x5ff: 0xba,\n\t// Block 0x18, offset 0x600\n\t0x600: 0x160, 0x601: 0xba, 0x602: 0xba, 0x603: 0xba, 0x604: 0xba, 0x605: 0xba, 0x606: 0xba, 0x607: 0xba,\n\t0x608: 0xba, 0x609: 0xba, 0x60a: 0xba, 0x60b: 0xba, 0x60c: 0xba, 0x60d: 0xba, 0x60e: 0xba, 0x60f: 0xba,\n\t0x610: 0xba, 0x611: 0xba, 0x612: 0xba, 0x613: 0xba, 0x614: 0xba, 0x615: 0xba, 0x616: 0xba, 0x617: 0xba,\n\t0x618: 0xba, 0x619: 0xba, 0x61a: 0xba, 0x61b: 0xba, 0x61c: 0xba, 0x61d: 0xba, 0x61e: 0xba, 0x61f: 0xba,\n\t0x620: 0x123, 0x621: 0x123, 0x622: 0x123, 0x623: 0x161, 0x624: 0x6e, 0x625: 0x162, 0x626: 0xba, 0x627: 0xba,\n\t0x628: 0xba, 0x629: 0xba, 0x62a: 0xba, 0x62b: 0xba, 0x62c: 0xba, 0x62d: 0xba, 0x62e: 0xba, 0x62f: 0xba,\n\t0x630: 0xba, 0x631: 0xba, 0x632: 0xba, 0x633: 0xba, 0x634: 0xba, 0x635: 0xba, 0x636: 0xba, 0x637: 0xba,\n\t0x638: 0x6f, 0x639: 0x70, 0x63a: 0x71, 0x63b: 0x163, 0x63c: 0xba, 0x63d: 0xba, 0x63e: 0xba, 0x63f: 0xba,\n\t// Block 0x19, offset 0x640\n\t0x640: 0x164, 0x641: 0x9b, 0x642: 0x165, 0x643: 0x166, 0x644: 0x72, 0x645: 0x73, 0x646: 0x167, 0x647: 0x168,\n\t0x648: 0x74, 0x649: 0x169, 0x64a: 0xba, 0x64b: 0xba, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b,\n\t0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b,\n\t0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x16a, 0x65c: 0x9b, 0x65d: 0x16b, 0x65e: 0x9b, 0x65f: 0x16c,\n\t0x660: 0x16d, 0x661: 0x16e, 0x662: 0x16f, 0x663: 0xba, 0x664: 0x170, 0x665: 0x171, 0x666: 0x172, 0x667: 0x173,\n\t0x668: 0xba, 0x669: 0xba, 0x66a: 0xba, 0x66b: 0xba, 0x66c: 0xba, 0x66d: 0xba, 0x66e: 0xba, 0x66f: 0xba,\n\t0x670: 0xba, 0x671: 0xba, 0x672: 0xba, 0x673: 0xba, 0x674: 0xba, 0x675: 0xba, 0x676: 0xba, 0x677: 0xba,\n\t0x678: 0xba, 0x679: 0xba, 0x67a: 0xba, 0x67b: 0xba, 0x67c: 0xba, 0x67d: 0xba, 0x67e: 0xba, 0x67f: 0xba,\n\t// Block 0x1a, offset 0x680\n\t0x680: 0x9f, 0x681: 0x9f, 0x682: 0x9f, 0x683: 0x9f, 0x684: 0x9f, 0x685: 0x9f, 0x686: 0x9f, 0x687: 0x9f,\n\t0x688: 0x9f, 0x689: 0x9f, 0x68a: 0x9f, 0x68b: 0x9f, 0x68c: 0x9f, 0x68d: 0x9f, 0x68e: 0x9f, 0x68f: 0x9f,\n\t0x690: 0x9f, 0x691: 0x9f, 0x692: 0x9f, 0x693: 0x9f, 0x694: 0x9f, 0x695: 0x9f, 0x696: 0x9f, 0x697: 0x9f,\n\t0x698: 0x9f, 0x699: 0x9f, 0x69a: 0x9f, 0x69b: 0x174, 0x69c: 0x9f, 0x69d: 0x9f, 0x69e: 0x9f, 0x69f: 0x9f,\n\t0x6a0: 0x9f, 0x6a1: 0x9f, 0x6a2: 0x9f, 0x6a3: 0x9f, 0x6a4: 0x9f, 0x6a5: 0x9f, 0x6a6: 0x9f, 0x6a7: 0x9f,\n\t0x6a8: 0x9f, 0x6a9: 0x9f, 0x6aa: 0x9f, 0x6ab: 0x9f, 0x6ac: 0x9f, 0x6ad: 0x9f, 0x6ae: 0x9f, 0x6af: 0x9f,\n\t0x6b0: 0x9f, 0x6b1: 0x9f, 0x6b2: 0x9f, 0x6b3: 0x9f, 0x6b4: 0x9f, 0x6b5: 0x9f, 0x6b6: 0x9f, 0x6b7: 0x9f,\n\t0x6b8: 0x9f, 0x6b9: 0x9f, 0x6ba: 0x9f, 0x6bb: 0x9f, 0x6bc: 0x9f, 0x6bd: 0x9f, 0x6be: 0x9f, 0x6bf: 0x9f,\n\t// Block 0x1b, offset 0x6c0\n\t0x6c0: 0x9f, 0x6c1: 0x9f, 0x6c2: 0x9f, 0x6c3: 0x9f, 0x6c4: 0x9f, 0x6c5: 0x9f, 0x6c6: 0x9f, 0x6c7: 0x9f,\n\t0x6c8: 0x9f, 0x6c9: 0x9f, 0x6ca: 0x9f, 0x6cb: 0x9f, 0x6cc: 0x9f, 0x6cd: 0x9f, 0x6ce: 0x9f, 0x6cf: 0x9f,\n\t0x6d0: 0x9f, 0x6d1: 0x9f, 0x6d2: 0x9f, 0x6d3: 0x9f, 0x6d4: 0x9f, 0x6d5: 0x9f, 0x6d6: 0x9f, 0x6d7: 0x9f,\n\t0x6d8: 0x9f, 0x6d9: 0x9f, 0x6da: 0x9f, 0x6db: 0x9f, 0x6dc: 0x175, 0x6dd: 0x9f, 0x6de: 0x9f, 0x6df: 0x9f,\n\t0x6e0: 0x176, 0x6e1: 0x9f, 0x6e2: 0x9f, 0x6e3: 0x9f, 0x6e4: 0x9f, 0x6e5: 0x9f, 0x6e6: 0x9f, 0x6e7: 0x9f,\n\t0x6e8: 0x9f, 0x6e9: 0x9f, 0x6ea: 0x9f, 0x6eb: 0x9f, 0x6ec: 0x9f, 0x6ed: 0x9f, 0x6ee: 0x9f, 0x6ef: 0x9f,\n\t0x6f0: 0x9f, 0x6f1: 0x9f, 0x6f2: 0x9f, 0x6f3: 0x9f, 0x6f4: 0x9f, 0x6f5: 0x9f, 0x6f6: 0x9f, 0x6f7: 0x9f,\n\t0x6f8: 0x9f, 0x6f9: 0x9f, 0x6fa: 0x9f, 0x6fb: 0x9f, 0x6fc: 0x9f, 0x6fd: 0x9f, 0x6fe: 0x9f, 0x6ff: 0x9f,\n\t// Block 0x1c, offset 0x700\n\t0x700: 0x9f, 0x701: 0x9f, 0x702: 0x9f, 0x703: 0x9f, 0x704: 0x9f, 0x705: 0x9f, 0x706: 0x9f, 0x707: 0x9f,\n\t0x708: 0x9f, 0x709: 0x9f, 0x70a: 0x9f, 0x70b: 0x9f, 0x70c: 0x9f, 0x70d: 0x9f, 0x70e: 0x9f, 0x70f: 0x9f,\n\t0x710: 0x9f, 0x711: 0x9f, 0x712: 0x9f, 0x713: 0x9f, 0x714: 0x9f, 0x715: 0x9f, 0x716: 0x9f, 0x717: 0x9f,\n\t0x718: 0x9f, 0x719: 0x9f, 0x71a: 0x9f, 0x71b: 0x9f, 0x71c: 0x9f, 0x71d: 0x9f, 0x71e: 0x9f, 0x71f: 0x9f,\n\t0x720: 0x9f, 0x721: 0x9f, 0x722: 0x9f, 0x723: 0x9f, 0x724: 0x9f, 0x725: 0x9f, 0x726: 0x9f, 0x727: 0x9f,\n\t0x728: 0x9f, 0x729: 0x9f, 0x72a: 0x9f, 0x72b: 0x9f, 0x72c: 0x9f, 0x72d: 0x9f, 0x72e: 0x9f, 0x72f: 0x9f,\n\t0x730: 0x9f, 0x731: 0x9f, 0x732: 0x9f, 0x733: 0x9f, 0x734: 0x9f, 0x735: 0x9f, 0x736: 0x9f, 0x737: 0x9f,\n\t0x738: 0x9f, 0x739: 0x9f, 0x73a: 0x177, 0x73b: 0xba, 0x73c: 0xba, 0x73d: 0xba, 0x73e: 0xba, 0x73f: 0xba,\n\t// Block 0x1d, offset 0x740\n\t0x740: 0xba, 0x741: 0xba, 0x742: 0xba, 0x743: 0xba, 0x744: 0xba, 0x745: 0xba, 0x746: 0xba, 0x747: 0xba,\n\t0x748: 0xba, 0x749: 0xba, 0x74a: 0xba, 0x74b: 0xba, 0x74c: 0xba, 0x74d: 0xba, 0x74e: 0xba, 0x74f: 0xba,\n\t0x750: 0xba, 0x751: 0xba, 0x752: 0xba, 0x753: 0xba, 0x754: 0xba, 0x755: 0xba, 0x756: 0xba, 0x757: 0xba,\n\t0x758: 0xba, 0x759: 0xba, 0x75a: 0xba, 0x75b: 0xba, 0x75c: 0xba, 0x75d: 0xba, 0x75e: 0xba, 0x75f: 0xba,\n\t0x760: 0x75, 0x761: 0x76, 0x762: 0x77, 0x763: 0x178, 0x764: 0x78, 0x765: 0x79, 0x766: 0x179, 0x767: 0x7a,\n\t0x768: 0x7b, 0x769: 0xba, 0x76a: 0xba, 0x76b: 0xba, 0x76c: 0xba, 0x76d: 0xba, 0x76e: 0xba, 0x76f: 0xba,\n\t0x770: 0xba, 0x771: 0xba, 0x772: 0xba, 0x773: 0xba, 0x774: 0xba, 0x775: 0xba, 0x776: 0xba, 0x777: 0xba,\n\t0x778: 0xba, 0x779: 0xba, 0x77a: 0xba, 0x77b: 0xba, 0x77c: 0xba, 0x77d: 0xba, 0x77e: 0xba, 0x77f: 0xba,\n\t// Block 0x1e, offset 0x780\n\t0x790: 0x0d, 0x791: 0x0e, 0x792: 0x0f, 0x793: 0x10, 0x794: 0x11, 0x795: 0x0b, 0x796: 0x12, 0x797: 0x07,\n\t0x798: 0x13, 0x799: 0x0b, 0x79a: 0x0b, 0x79b: 0x14, 0x79c: 0x0b, 0x79d: 0x15, 0x79e: 0x16, 0x79f: 0x17,\n\t0x7a0: 0x07, 0x7a1: 0x07, 0x7a2: 0x07, 0x7a3: 0x07, 0x7a4: 0x07, 0x7a5: 0x07, 0x7a6: 0x07, 0x7a7: 0x07,\n\t0x7a8: 0x07, 0x7a9: 0x07, 0x7aa: 0x18, 0x7ab: 0x19, 0x7ac: 0x1a, 0x7ad: 0x0b, 0x7ae: 0x0b, 0x7af: 0x1b,\n\t0x7b0: 0x0b, 0x7b1: 0x0b, 0x7b2: 0x0b, 0x7b3: 0x0b, 0x7b4: 0x0b, 0x7b5: 0x0b, 0x7b6: 0x0b, 0x7b7: 0x0b,\n\t0x7b8: 0x0b, 0x7b9: 0x0b, 0x7ba: 0x0b, 0x7bb: 0x0b, 0x7bc: 0x0b, 0x7bd: 0x0b, 0x7be: 0x0b, 0x7bf: 0x0b,\n\t// Block 0x1f, offset 0x7c0\n\t0x7c0: 0x0b, 0x7c1: 0x0b, 0x7c2: 0x0b, 0x7c3: 0x0b, 0x7c4: 0x0b, 0x7c5: 0x0b, 0x7c6: 0x0b, 0x7c7: 0x0b,\n\t0x7c8: 0x0b, 0x7c9: 0x0b, 0x7ca: 0x0b, 0x7cb: 0x0b, 0x7cc: 0x0b, 0x7cd: 0x0b, 0x7ce: 0x0b, 0x7cf: 0x0b,\n\t0x7d0: 0x0b, 0x7d1: 0x0b, 0x7d2: 0x0b, 0x7d3: 0x0b, 0x7d4: 0x0b, 0x7d5: 0x0b, 0x7d6: 0x0b, 0x7d7: 0x0b,\n\t0x7d8: 0x0b, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x0b, 0x7dc: 0x0b, 0x7dd: 0x0b, 0x7de: 0x0b, 0x7df: 0x0b,\n\t0x7e0: 0x0b, 0x7e1: 0x0b, 0x7e2: 0x0b, 0x7e3: 0x0b, 0x7e4: 0x0b, 0x7e5: 0x0b, 0x7e6: 0x0b, 0x7e7: 0x0b,\n\t0x7e8: 0x0b, 0x7e9: 0x0b, 0x7ea: 0x0b, 0x7eb: 0x0b, 0x7ec: 0x0b, 0x7ed: 0x0b, 0x7ee: 0x0b, 0x7ef: 0x0b,\n\t0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b,\n\t0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b,\n\t// Block 0x20, offset 0x800\n\t0x800: 0x17a, 0x801: 0x17b, 0x802: 0xba, 0x803: 0xba, 0x804: 0x17c, 0x805: 0x17c, 0x806: 0x17c, 0x807: 0x17d,\n\t0x808: 0xba, 0x809: 0xba, 0x80a: 0xba, 0x80b: 0xba, 0x80c: 0xba, 0x80d: 0xba, 0x80e: 0xba, 0x80f: 0xba,\n\t0x810: 0xba, 0x811: 0xba, 0x812: 0xba, 0x813: 0xba, 0x814: 0xba, 0x815: 0xba, 0x816: 0xba, 0x817: 0xba,\n\t0x818: 0xba, 0x819: 0xba, 0x81a: 0xba, 0x81b: 0xba, 0x81c: 0xba, 0x81d: 0xba, 0x81e: 0xba, 0x81f: 0xba,\n\t0x820: 0xba, 0x821: 0xba, 0x822: 0xba, 0x823: 0xba, 0x824: 0xba, 0x825: 0xba, 0x826: 0xba, 0x827: 0xba,\n\t0x828: 0xba, 0x829: 0xba, 0x82a: 0xba, 0x82b: 0xba, 0x82c: 0xba, 0x82d: 0xba, 0x82e: 0xba, 0x82f: 0xba,\n\t0x830: 0xba, 0x831: 0xba, 0x832: 0xba, 0x833: 0xba, 0x834: 0xba, 0x835: 0xba, 0x836: 0xba, 0x837: 0xba,\n\t0x838: 0xba, 0x839: 0xba, 0x83a: 0xba, 0x83b: 0xba, 0x83c: 0xba, 0x83d: 0xba, 0x83e: 0xba, 0x83f: 0xba,\n\t// Block 0x21, offset 0x840\n\t0x840: 0x0b, 0x841: 0x0b, 0x842: 0x0b, 0x843: 0x0b, 0x844: 0x0b, 0x845: 0x0b, 0x846: 0x0b, 0x847: 0x0b,\n\t0x848: 0x0b, 0x849: 0x0b, 0x84a: 0x0b, 0x84b: 0x0b, 0x84c: 0x0b, 0x84d: 0x0b, 0x84e: 0x0b, 0x84f: 0x0b,\n\t0x850: 0x0b, 0x851: 0x0b, 0x852: 0x0b, 0x853: 0x0b, 0x854: 0x0b, 0x855: 0x0b, 0x856: 0x0b, 0x857: 0x0b,\n\t0x858: 0x0b, 0x859: 0x0b, 0x85a: 0x0b, 0x85b: 0x0b, 0x85c: 0x0b, 0x85d: 0x0b, 0x85e: 0x0b, 0x85f: 0x0b,\n\t0x860: 0x1e, 0x861: 0x0b, 0x862: 0x0b, 0x863: 0x0b, 0x864: 0x0b, 0x865: 0x0b, 0x866: 0x0b, 0x867: 0x0b,\n\t0x868: 0x0b, 0x869: 0x0b, 0x86a: 0x0b, 0x86b: 0x0b, 0x86c: 0x0b, 0x86d: 0x0b, 0x86e: 0x0b, 0x86f: 0x0b,\n\t0x870: 0x0b, 0x871: 0x0b, 0x872: 0x0b, 0x873: 0x0b, 0x874: 0x0b, 0x875: 0x0b, 0x876: 0x0b, 0x877: 0x0b,\n\t0x878: 0x0b, 0x879: 0x0b, 0x87a: 0x0b, 0x87b: 0x0b, 0x87c: 0x0b, 0x87d: 0x0b, 0x87e: 0x0b, 0x87f: 0x0b,\n\t// Block 0x22, offset 0x880\n\t0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b,\n\t0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b,\n}\n\n// idnaSparseOffset: 258 entries, 516 bytes\nvar idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x34, 0x3f, 0x4b, 0x4f, 0x5e, 0x63, 0x6b, 0x77, 0x85, 0x93, 0x98, 0xa1, 0xb1, 0xbf, 0xcc, 0xd8, 0xe9, 0xf3, 0xfa, 0x107, 0x118, 0x11f, 0x12a, 0x139, 0x147, 0x151, 0x153, 0x158, 0x15b, 0x15e, 0x160, 0x16c, 0x177, 0x17f, 0x185, 0x18b, 0x190, 0x195, 0x198, 0x19c, 0x1a2, 0x1a7, 0x1b3, 0x1bd, 0x1c3, 0x1d4, 0x1de, 0x1e1, 0x1e9, 0x1ec, 0x1f9, 0x201, 0x205, 0x20c, 0x214, 0x224, 0x230, 0x232, 0x23c, 0x248, 0x254, 0x260, 0x268, 0x26d, 0x277, 0x288, 0x28c, 0x297, 0x29b, 0x2a4, 0x2ac, 0x2b2, 0x2b7, 0x2ba, 0x2bd, 0x2c1, 0x2c7, 0x2cb, 0x2cf, 0x2d5, 0x2dc, 0x2e2, 0x2ea, 0x2f1, 0x2fc, 0x306, 0x30a, 0x30d, 0x313, 0x317, 0x319, 0x31c, 0x31e, 0x321, 0x32b, 0x32e, 0x33d, 0x341, 0x346, 0x349, 0x34d, 0x352, 0x357, 0x35d, 0x363, 0x372, 0x378, 0x37c, 0x38b, 0x390, 0x398, 0x3a2, 0x3ad, 0x3b5, 0x3c6, 0x3cf, 0x3df, 0x3ec, 0x3f6, 0x3fb, 0x408, 0x40c, 0x411, 0x413, 0x417, 0x419, 0x41d, 0x426, 0x42c, 0x430, 0x440, 0x44a, 0x44f, 0x452, 0x458, 0x45f, 0x464, 0x468, 0x46e, 0x473, 0x47c, 0x481, 0x487, 0x48e, 0x495, 0x49c, 0x4a0, 0x4a5, 0x4a8, 0x4ad, 0x4b9, 0x4bf, 0x4c4, 0x4cb, 0x4d3, 0x4d8, 0x4dc, 0x4ec, 0x4f3, 0x4f7, 0x4fb, 0x502, 0x504, 0x507, 0x50a, 0x50e, 0x512, 0x518, 0x521, 0x52d, 0x534, 0x53d, 0x545, 0x54c, 0x55a, 0x567, 0x574, 0x57d, 0x581, 0x58f, 0x597, 0x5a2, 0x5ab, 0x5b1, 0x5b9, 0x5c2, 0x5cc, 0x5cf, 0x5db, 0x5de, 0x5e3, 0x5e6, 0x5f0, 0x5f9, 0x605, 0x608, 0x60d, 0x610, 0x613, 0x616, 0x61d, 0x624, 0x628, 0x633, 0x636, 0x63c, 0x641, 0x645, 0x648, 0x64b, 0x64e, 0x653, 0x65d, 0x660, 0x664, 0x673, 0x67f, 0x683, 0x688, 0x68d, 0x691, 0x696, 0x69f, 0x6aa, 0x6b0, 0x6b8, 0x6bc, 0x6c0, 0x6c6, 0x6cc, 0x6d1, 0x6d4, 0x6e2, 0x6e9, 0x6ec, 0x6ef, 0x6f3, 0x6f9, 0x6fe, 0x708, 0x70d, 0x710, 0x713, 0x716, 0x719, 0x71d, 0x720, 0x730, 0x741, 0x746, 0x748, 0x74a}\n\n// idnaSparseValues: 1869 entries, 7476 bytes\nvar idnaSparseValues = [1869]valueRange{\n\t// Block 0x0, offset 0x0\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0xe105, lo: 0x80, hi: 0x96},\n\t{value: 0x0018, lo: 0x97, hi: 0x97},\n\t{value: 0xe105, lo: 0x98, hi: 0x9e},\n\t{value: 0x001f, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbf},\n\t// Block 0x1, offset 0x8\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0xe01d, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x82},\n\t{value: 0x0335, lo: 0x83, hi: 0x83},\n\t{value: 0x034d, lo: 0x84, hi: 0x84},\n\t{value: 0x0365, lo: 0x85, hi: 0x85},\n\t{value: 0xe00d, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0xe00d, lo: 0x88, hi: 0x88},\n\t{value: 0x0008, lo: 0x89, hi: 0x89},\n\t{value: 0xe00d, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0x8b},\n\t{value: 0xe00d, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0x8d},\n\t{value: 0xe00d, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0xbf},\n\t// Block 0x2, offset 0x19\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x0249, lo: 0xb0, hi: 0xb0},\n\t{value: 0x037d, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0259, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0269, lo: 0xb3, hi: 0xb3},\n\t{value: 0x034d, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0395, lo: 0xb5, hi: 0xb5},\n\t{value: 0xe1bd, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0279, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0289, lo: 0xb8, hi: 0xb8},\n\t{value: 0x0008, lo: 0xb9, hi: 0xbf},\n\t// Block 0x3, offset 0x25\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x3308, lo: 0x80, hi: 0xbf},\n\t// Block 0x4, offset 0x27\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x03f5, lo: 0x80, hi: 0x8f},\n\t{value: 0xe105, lo: 0x90, hi: 0x9f},\n\t{value: 0x049d, lo: 0xa0, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x5, offset 0x2c\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0xe185, lo: 0x80, hi: 0x8f},\n\t{value: 0x0545, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x98},\n\t{value: 0x0008, lo: 0x99, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xbf},\n\t// Block 0x6, offset 0x34\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0401, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x88},\n\t{value: 0x0018, lo: 0x89, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x3308, lo: 0x91, hi: 0xbd},\n\t{value: 0x0818, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x7, offset 0x3f\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0818, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x82},\n\t{value: 0x0818, lo: 0x83, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x85},\n\t{value: 0x0818, lo: 0x86, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0808, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x8, offset 0x4b\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0a08, lo: 0x80, hi: 0x87},\n\t{value: 0x0c08, lo: 0x88, hi: 0x99},\n\t{value: 0x0a08, lo: 0x9a, hi: 0xbf},\n\t// Block 0x9, offset 0x4f\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3308, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0c08, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0a08, lo: 0x8e, hi: 0x98},\n\t{value: 0x0c08, lo: 0x99, hi: 0x9b},\n\t{value: 0x0a08, lo: 0x9c, hi: 0xaa},\n\t{value: 0x0c08, lo: 0xab, hi: 0xac},\n\t{value: 0x0a08, lo: 0xad, hi: 0xb0},\n\t{value: 0x0c08, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0a08, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0c08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0a08, lo: 0xb5, hi: 0xb7},\n\t{value: 0x0c08, lo: 0xb8, hi: 0xb9},\n\t{value: 0x0a08, lo: 0xba, hi: 0xbf},\n\t// Block 0xa, offset 0x5e\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xb0},\n\t{value: 0x0808, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xb, offset 0x63\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0x89},\n\t{value: 0x0a08, lo: 0x8a, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xb3},\n\t{value: 0x0808, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xb9},\n\t{value: 0x0818, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0xc, offset 0x6b\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x99},\n\t{value: 0x0808, lo: 0x9a, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0xa3},\n\t{value: 0x0808, lo: 0xa4, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa7},\n\t{value: 0x0808, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0818, lo: 0xb0, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd, offset 0x77\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0c08, lo: 0x80, hi: 0x80},\n\t{value: 0x0a08, lo: 0x81, hi: 0x85},\n\t{value: 0x0c08, lo: 0x86, hi: 0x87},\n\t{value: 0x0a08, lo: 0x88, hi: 0x88},\n\t{value: 0x0c08, lo: 0x89, hi: 0x89},\n\t{value: 0x0a08, lo: 0x8a, hi: 0x93},\n\t{value: 0x0c08, lo: 0x94, hi: 0x94},\n\t{value: 0x0a08, lo: 0x95, hi: 0x95},\n\t{value: 0x0808, lo: 0x96, hi: 0x98},\n\t{value: 0x3308, lo: 0x99, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9d},\n\t{value: 0x0818, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xbf},\n\t// Block 0xe, offset 0x85\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0a08, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0c08, lo: 0xaa, hi: 0xac},\n\t{value: 0x0808, lo: 0xad, hi: 0xad},\n\t{value: 0x0c08, lo: 0xae, hi: 0xae},\n\t{value: 0x0a08, lo: 0xaf, hi: 0xb0},\n\t{value: 0x0c08, lo: 0xb1, hi: 0xb2},\n\t{value: 0x0a08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0a08, lo: 0xb6, hi: 0xb8},\n\t{value: 0x0c08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0a08, lo: 0xba, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0xf, offset 0x93\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x93},\n\t{value: 0x3308, lo: 0x94, hi: 0xa1},\n\t{value: 0x0840, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xbf},\n\t// Block 0x10, offset 0x98\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x11, offset 0xa1\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x85},\n\t{value: 0x3008, lo: 0x86, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x3008, lo: 0x8a, hi: 0x8c},\n\t{value: 0x3b08, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x12, offset 0xb1\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbf},\n\t// Block 0x13, offset 0xbf\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x14, offset 0xcc\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0040, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0008, lo: 0xb3, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x15, offset 0xd8\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x89},\n\t{value: 0x3b08, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8e},\n\t{value: 0x3008, lo: 0x8f, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x3008, lo: 0x98, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x16, offset 0xe9\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb2},\n\t{value: 0x08f1, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb9},\n\t{value: 0x3b08, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0x17, offset 0xf3\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x8e},\n\t{value: 0x0018, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0xbf},\n\t// Block 0x18, offset 0xfa\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x3308, lo: 0x88, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0961, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0999, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0008, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x19, offset 0x107\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0x8b},\n\t{value: 0xe03d, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3308, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x1a, offset 0x118\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0018, lo: 0x8e, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0xbf},\n\t// Block 0x1b, offset 0x11f\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x3008, lo: 0xab, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xb0},\n\t{value: 0x3008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0x1c, offset 0x12a\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x95},\n\t{value: 0x3008, lo: 0x96, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0x9d},\n\t{value: 0x3308, lo: 0x9e, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3008, lo: 0xa2, hi: 0xa4},\n\t{value: 0x0008, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xbf},\n\t// Block 0x1d, offset 0x139\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x3008, lo: 0x87, hi: 0x8c},\n\t{value: 0x3308, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x8e},\n\t{value: 0x3008, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x3008, lo: 0x9a, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x1e, offset 0x147\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x86},\n\t{value: 0x055d, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8c},\n\t{value: 0x055d, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbb},\n\t{value: 0xe105, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x1f, offset 0x151\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0018, lo: 0x80, hi: 0xbf},\n\t// Block 0x20, offset 0x153\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xa0},\n\t{value: 0x2018, lo: 0xa1, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0x21, offset 0x158\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xa7},\n\t{value: 0x2018, lo: 0xa8, hi: 0xbf},\n\t// Block 0x22, offset 0x15b\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x2018, lo: 0x80, hi: 0x82},\n\t{value: 0x0018, lo: 0x83, hi: 0xbf},\n\t// Block 0x23, offset 0x15e\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0008, lo: 0x80, hi: 0xbf},\n\t// Block 0x24, offset 0x160\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x25, offset 0x16c\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x26, offset 0x177\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbf},\n\t// Block 0x27, offset 0x17f\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbf},\n\t// Block 0x28, offset 0x185\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x29, offset 0x18b\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x2a, offset 0x190\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0xe045, lo: 0xb8, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x2b, offset 0x195\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xbf},\n\t// Block 0x2c, offset 0x198\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xac},\n\t{value: 0x0018, lo: 0xad, hi: 0xae},\n\t{value: 0x0008, lo: 0xaf, hi: 0xbf},\n\t// Block 0x2d, offset 0x19c\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x2e, offset 0x1a2\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xb0},\n\t{value: 0x0008, lo: 0xb1, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0x2f, offset 0x1a7\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x93},\n\t{value: 0x3b08, lo: 0x94, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3b08, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0018, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x30, offset 0x1b3\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x31, offset 0x1bd\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xb3},\n\t{value: 0x3340, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3008, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x32, offset 0x1c3\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x3008, lo: 0x80, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x3008, lo: 0x87, hi: 0x88},\n\t{value: 0x3308, lo: 0x89, hi: 0x91},\n\t{value: 0x3b08, lo: 0x92, hi: 0x92},\n\t{value: 0x3308, lo: 0x93, hi: 0x93},\n\t{value: 0x0018, lo: 0x94, hi: 0x96},\n\t{value: 0x0008, lo: 0x97, hi: 0x97},\n\t{value: 0x0018, lo: 0x98, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x33, offset 0x1d4\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0018, lo: 0x80, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x86},\n\t{value: 0x0218, lo: 0x87, hi: 0x87},\n\t{value: 0x0018, lo: 0x88, hi: 0x8a},\n\t{value: 0x33c0, lo: 0x8b, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0208, lo: 0xa0, hi: 0xbf},\n\t// Block 0x34, offset 0x1de\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0208, lo: 0x80, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x35, offset 0x1e1\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x0208, lo: 0x87, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0208, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x36, offset 0x1e9\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0x37, offset 0x1ec\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb8},\n\t{value: 0x3308, lo: 0xb9, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x38, offset 0x1f9\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x39, offset 0x201\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x3a, offset 0x205\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0028, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0xbf},\n\t// Block 0x3b, offset 0x20c\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x3308, lo: 0x97, hi: 0x98},\n\t{value: 0x3008, lo: 0x99, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x3c, offset 0x214\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x94},\n\t{value: 0x3008, lo: 0x95, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3b08, lo: 0xa0, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xac},\n\t{value: 0x3008, lo: 0xad, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x3d, offset 0x224\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0018, lo: 0xa8, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xbd},\n\t{value: 0x3318, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x3e, offset 0x230\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0040, lo: 0x80, hi: 0xbf},\n\t// Block 0x3f, offset 0x232\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x3308, lo: 0x80, hi: 0x83},\n\t{value: 0x3008, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x40, offset 0x23c\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x3808, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x41, offset 0x248\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa9},\n\t{value: 0x3808, lo: 0xaa, hi: 0xaa},\n\t{value: 0x3b08, lo: 0xab, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xbf},\n\t// Block 0x42, offset 0x254\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa9},\n\t{value: 0x3008, lo: 0xaa, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3808, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbf},\n\t// Block 0x43, offset 0x260\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x3008, lo: 0xa4, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbf},\n\t// Block 0x44, offset 0x268\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0x45, offset 0x26d\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0e29, lo: 0x80, hi: 0x80},\n\t{value: 0x0e41, lo: 0x81, hi: 0x81},\n\t{value: 0x0e59, lo: 0x82, hi: 0x82},\n\t{value: 0x0e71, lo: 0x83, hi: 0x83},\n\t{value: 0x0e89, lo: 0x84, hi: 0x85},\n\t{value: 0x0ea1, lo: 0x86, hi: 0x86},\n\t{value: 0x0eb9, lo: 0x87, hi: 0x87},\n\t{value: 0x057d, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0xbf},\n\t// Block 0x46, offset 0x277\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x92},\n\t{value: 0x0018, lo: 0x93, hi: 0x93},\n\t{value: 0x3308, lo: 0x94, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa8},\n\t{value: 0x0008, lo: 0xa9, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x47, offset 0x288\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3308, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbf},\n\t// Block 0x48, offset 0x28c\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x87},\n\t{value: 0xe045, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0xe045, lo: 0x98, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0xe045, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb7},\n\t{value: 0xe045, lo: 0xb8, hi: 0xbf},\n\t// Block 0x49, offset 0x297\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x3318, lo: 0x90, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbf},\n\t// Block 0x4a, offset 0x29b\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x88},\n\t{value: 0x24c1, lo: 0x89, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x4b, offset 0x2a4\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0xab},\n\t{value: 0x24f1, lo: 0xac, hi: 0xac},\n\t{value: 0x2529, lo: 0xad, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xae},\n\t{value: 0x2579, lo: 0xaf, hi: 0xaf},\n\t{value: 0x25b1, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0018, lo: 0xb1, hi: 0xbf},\n\t// Block 0x4c, offset 0x2ac\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x9f},\n\t{value: 0x0080, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xad},\n\t{value: 0x0080, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x4d, offset 0x2b2\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xa8},\n\t{value: 0x09c5, lo: 0xa9, hi: 0xa9},\n\t{value: 0x09e5, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xbf},\n\t// Block 0x4e, offset 0x2b7\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x4f, offset 0x2ba\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xbf},\n\t// Block 0x50, offset 0x2bd\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x28c1, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0xbf},\n\t// Block 0x51, offset 0x2c1\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0e66, lo: 0xb4, hi: 0xb4},\n\t{value: 0x292a, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0e86, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0x52, offset 0x2c7\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x9b},\n\t{value: 0x2941, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0xbf},\n\t// Block 0x53, offset 0x2cb\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0x54, offset 0x2cf\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0018, lo: 0x98, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbc},\n\t{value: 0x0018, lo: 0xbd, hi: 0xbf},\n\t// Block 0x55, offset 0x2d5\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0xab},\n\t{value: 0x0018, lo: 0xac, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x56, offset 0x2dc\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0xe185, lo: 0x80, hi: 0x8f},\n\t{value: 0x03f5, lo: 0x90, hi: 0x9f},\n\t{value: 0x0ea5, lo: 0xa0, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x57, offset 0x2e2\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xac},\n\t{value: 0x0008, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x58, offset 0x2ea\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xae},\n\t{value: 0xe075, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0x59, offset 0x2f1\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x5a, offset 0x2fc\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xbf},\n\t// Block 0x5b, offset 0x306\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xae},\n\t{value: 0x0008, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x5c, offset 0x30a\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0xbf},\n\t// Block 0x5d, offset 0x30d\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9e},\n\t{value: 0x0edd, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbf},\n\t// Block 0x5e, offset 0x313\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb2},\n\t{value: 0x0efd, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x5f, offset 0x317\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x0f1d, lo: 0x80, hi: 0xbf},\n\t// Block 0x60, offset 0x319\n\t{value: 0x0020, lo: 0x02},\n\t{value: 0x171d, lo: 0x80, hi: 0x8f},\n\t{value: 0x18fd, lo: 0x90, hi: 0xbf},\n\t// Block 0x61, offset 0x31c\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x1efd, lo: 0x80, hi: 0xbf},\n\t// Block 0x62, offset 0x31e\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xbf},\n\t// Block 0x63, offset 0x321\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x98},\n\t{value: 0x3308, lo: 0x99, hi: 0x9a},\n\t{value: 0x29e2, lo: 0x9b, hi: 0x9b},\n\t{value: 0x2a0a, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0008, lo: 0x9d, hi: 0x9e},\n\t{value: 0x2a31, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xbf},\n\t// Block 0x64, offset 0x32b\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xbe},\n\t{value: 0x2a69, lo: 0xbf, hi: 0xbf},\n\t// Block 0x65, offset 0x32e\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0040, lo: 0x80, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xb0},\n\t{value: 0x2a1d, lo: 0xb1, hi: 0xb1},\n\t{value: 0x2a3d, lo: 0xb2, hi: 0xb2},\n\t{value: 0x2a5d, lo: 0xb3, hi: 0xb3},\n\t{value: 0x2a7d, lo: 0xb4, hi: 0xb4},\n\t{value: 0x2a5d, lo: 0xb5, hi: 0xb5},\n\t{value: 0x2a9d, lo: 0xb6, hi: 0xb6},\n\t{value: 0x2abd, lo: 0xb7, hi: 0xb7},\n\t{value: 0x2add, lo: 0xb8, hi: 0xb9},\n\t{value: 0x2afd, lo: 0xba, hi: 0xbb},\n\t{value: 0x2b1d, lo: 0xbc, hi: 0xbd},\n\t{value: 0x2afd, lo: 0xbe, hi: 0xbf},\n\t// Block 0x66, offset 0x33d\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x67, offset 0x341\n\t{value: 0x0030, lo: 0x04},\n\t{value: 0x2aa2, lo: 0x80, hi: 0x9d},\n\t{value: 0x305a, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x30a2, lo: 0xa0, hi: 0xbf},\n\t// Block 0x68, offset 0x346\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0xbf},\n\t// Block 0x69, offset 0x349\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x6a, offset 0x34d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0x6b, offset 0x352\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xbf},\n\t// Block 0x6c, offset 0x357\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x0018, lo: 0xa6, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0018, lo: 0xb2, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x6d, offset 0x35d\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0xb6},\n\t{value: 0x0008, lo: 0xb7, hi: 0xb7},\n\t{value: 0x2009, lo: 0xb8, hi: 0xb8},\n\t{value: 0x6e89, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xbf},\n\t// Block 0x6e, offset 0x363\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0x85},\n\t{value: 0x3b08, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x8a},\n\t{value: 0x3308, lo: 0x8b, hi: 0x8b},\n\t{value: 0x0008, lo: 0x8c, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0018, lo: 0xa8, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x6f, offset 0x372\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0208, lo: 0x80, hi: 0xb1},\n\t{value: 0x0108, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0008, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x70, offset 0x378\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xbf},\n\t// Block 0x71, offset 0x37c\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3008, lo: 0x80, hi: 0x83},\n\t{value: 0x3b08, lo: 0x84, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8d},\n\t{value: 0x0018, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xba},\n\t{value: 0x0008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x72, offset 0x38b\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x73, offset 0x390\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x91},\n\t{value: 0x3008, lo: 0x92, hi: 0x92},\n\t{value: 0x3808, lo: 0x93, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x74, offset 0x398\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb9},\n\t{value: 0x3008, lo: 0xba, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x75, offset 0x3a2\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3808, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x76, offset 0x3ad\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x77, offset 0x3b5\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x8b},\n\t{value: 0x3308, lo: 0x8c, hi: 0x8c},\n\t{value: 0x3008, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0018, lo: 0x9c, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x78, offset 0x3c6\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0008, lo: 0xb9, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbf},\n\t// Block 0x79, offset 0x3cf\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x9a},\n\t{value: 0x0008, lo: 0x9b, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xaa},\n\t{value: 0x3008, lo: 0xab, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3b08, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x7a, offset 0x3df\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x88},\n\t{value: 0x0008, lo: 0x89, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x90},\n\t{value: 0x0008, lo: 0x91, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7b, offset 0x3ec\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x4465, lo: 0x9c, hi: 0x9c},\n\t{value: 0x447d, lo: 0x9d, hi: 0x9d},\n\t{value: 0x2971, lo: 0x9e, hi: 0x9e},\n\t{value: 0xe06d, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xaf},\n\t{value: 0x4495, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7c, offset 0x3f6\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x44b5, lo: 0x80, hi: 0x8f},\n\t{value: 0x44d5, lo: 0x90, hi: 0x9f},\n\t{value: 0x44f5, lo: 0xa0, hi: 0xaf},\n\t{value: 0x44d5, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7d, offset 0x3fb\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3b08, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x7e, offset 0x408\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7f, offset 0x40c\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8a},\n\t{value: 0x0018, lo: 0x8b, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x80, offset 0x411\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x4515, lo: 0x80, hi: 0xbf},\n\t// Block 0x81, offset 0x413\n\t{value: 0x0020, lo: 0x03},\n\t{value: 0x4d15, lo: 0x80, hi: 0x94},\n\t{value: 0x4ad5, lo: 0x95, hi: 0x95},\n\t{value: 0x4fb5, lo: 0x96, hi: 0xbf},\n\t// Block 0x82, offset 0x417\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x54f5, lo: 0x80, hi: 0xbf},\n\t// Block 0x83, offset 0x419\n\t{value: 0x0020, lo: 0x03},\n\t{value: 0x5cf5, lo: 0x80, hi: 0x84},\n\t{value: 0x5655, lo: 0x85, hi: 0x85},\n\t{value: 0x5d95, lo: 0x86, hi: 0xbf},\n\t// Block 0x84, offset 0x41d\n\t{value: 0x0020, lo: 0x08},\n\t{value: 0x6b55, lo: 0x80, hi: 0x8f},\n\t{value: 0x6d15, lo: 0x90, hi: 0x90},\n\t{value: 0x6d55, lo: 0x91, hi: 0xab},\n\t{value: 0x6ea1, lo: 0xac, hi: 0xac},\n\t{value: 0x70b5, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x70d5, lo: 0xb0, hi: 0xbf},\n\t// Block 0x85, offset 0x426\n\t{value: 0x0020, lo: 0x05},\n\t{value: 0x72d5, lo: 0x80, hi: 0xad},\n\t{value: 0x6535, lo: 0xae, hi: 0xae},\n\t{value: 0x7895, lo: 0xaf, hi: 0xb5},\n\t{value: 0x6f55, lo: 0xb6, hi: 0xb6},\n\t{value: 0x7975, lo: 0xb7, hi: 0xbf},\n\t// Block 0x86, offset 0x42c\n\t{value: 0x0028, lo: 0x03},\n\t{value: 0x7c21, lo: 0x80, hi: 0x82},\n\t{value: 0x7be1, lo: 0x83, hi: 0x83},\n\t{value: 0x7c99, lo: 0x84, hi: 0xbf},\n\t// Block 0x87, offset 0x430\n\t{value: 0x0038, lo: 0x0f},\n\t{value: 0x9db1, lo: 0x80, hi: 0x83},\n\t{value: 0x9e59, lo: 0x84, hi: 0x85},\n\t{value: 0x9e91, lo: 0x86, hi: 0x87},\n\t{value: 0x9ec9, lo: 0x88, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0xa089, lo: 0x92, hi: 0x97},\n\t{value: 0xa1a1, lo: 0x98, hi: 0x9c},\n\t{value: 0xa281, lo: 0x9d, hi: 0xb3},\n\t{value: 0x9d41, lo: 0xb4, hi: 0xb4},\n\t{value: 0x9db1, lo: 0xb5, hi: 0xb5},\n\t{value: 0xa789, lo: 0xb6, hi: 0xbb},\n\t{value: 0xa869, lo: 0xbc, hi: 0xbc},\n\t{value: 0xa7f9, lo: 0xbd, hi: 0xbd},\n\t{value: 0xa8d9, lo: 0xbe, hi: 0xbf},\n\t// Block 0x88, offset 0x440\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0008, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0x89, offset 0x44a\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0x8a, offset 0x44f\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x8b, offset 0x452\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0x8c, offset 0x458\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0040, lo: 0xa1, hi: 0xbf},\n\t// Block 0x8d, offset 0x45f\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x8e, offset 0x464\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x8f, offset 0x468\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x90, offset 0x46e\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x91, offset 0x473\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x92, offset 0x47c\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x93, offset 0x481\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0xbf},\n\t// Block 0x94, offset 0x487\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe145, lo: 0x80, hi: 0x87},\n\t{value: 0xe1c5, lo: 0x88, hi: 0x8f},\n\t{value: 0xe145, lo: 0x90, hi: 0x97},\n\t{value: 0x8ad5, lo: 0x98, hi: 0x9f},\n\t{value: 0x8aed, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xbf},\n\t// Block 0x95, offset 0x48e\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x8aed, lo: 0xb0, hi: 0xb7},\n\t{value: 0x8ad5, lo: 0xb8, hi: 0xbf},\n\t// Block 0x96, offset 0x495\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe145, lo: 0x80, hi: 0x87},\n\t{value: 0xe1c5, lo: 0x88, hi: 0x8f},\n\t{value: 0xe145, lo: 0x90, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x97, offset 0x49c\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x98, offset 0x4a0\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xae},\n\t{value: 0x0018, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x99, offset 0x4a5\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x9a, offset 0x4a8\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xbf},\n\t// Block 0x9b, offset 0x4ad\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x87},\n\t{value: 0x0808, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0808, lo: 0x8a, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0808, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbb},\n\t{value: 0x0808, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbe},\n\t{value: 0x0808, lo: 0xbf, hi: 0xbf},\n\t// Block 0x9c, offset 0x4b9\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x96},\n\t{value: 0x0818, lo: 0x97, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0818, lo: 0xb7, hi: 0xbf},\n\t// Block 0x9d, offset 0x4bf\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xa6},\n\t{value: 0x0818, lo: 0xa7, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x9e, offset 0x4c4\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0808, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xba},\n\t{value: 0x0818, lo: 0xbb, hi: 0xbf},\n\t// Block 0x9f, offset 0x4cb\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0818, lo: 0x96, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbe},\n\t{value: 0x0818, lo: 0xbf, hi: 0xbf},\n\t// Block 0xa0, offset 0x4d3\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbb},\n\t{value: 0x0818, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0808, lo: 0xbe, hi: 0xbf},\n\t// Block 0xa1, offset 0x4d8\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0818, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x91},\n\t{value: 0x0818, lo: 0x92, hi: 0xbf},\n\t// Block 0xa2, offset 0x4dc\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0808, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8b},\n\t{value: 0x3308, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x94},\n\t{value: 0x0808, lo: 0x95, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0x98},\n\t{value: 0x0808, lo: 0x99, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xa3, offset 0x4ec\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0818, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0818, lo: 0x90, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xbc},\n\t{value: 0x0818, lo: 0xbd, hi: 0xbf},\n\t// Block 0xa4, offset 0x4f3\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0x9c},\n\t{value: 0x0818, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xa5, offset 0x4f7\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb8},\n\t{value: 0x0018, lo: 0xb9, hi: 0xbf},\n\t// Block 0xa6, offset 0x4fb\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0818, lo: 0x98, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb7},\n\t{value: 0x0818, lo: 0xb8, hi: 0xbf},\n\t// Block 0xa7, offset 0x502\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0808, lo: 0x80, hi: 0xbf},\n\t// Block 0xa8, offset 0x504\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0808, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0xbf},\n\t// Block 0xa9, offset 0x507\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x03dd, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbf},\n\t// Block 0xaa, offset 0x50a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb9},\n\t{value: 0x0818, lo: 0xba, hi: 0xbf},\n\t// Block 0xab, offset 0x50e\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0818, lo: 0xa0, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xac, offset 0x512\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbf},\n\t// Block 0xad, offset 0x518\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x85},\n\t{value: 0x3b08, lo: 0x86, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x91},\n\t{value: 0x0018, lo: 0x92, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xae, offset 0x521\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb6},\n\t{value: 0x3008, lo: 0xb7, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0340, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0xaf, offset 0x52d\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x81},\n\t{value: 0x0040, lo: 0x82, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xb0, offset 0x534\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xb2},\n\t{value: 0x3b08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0008, lo: 0xb6, hi: 0xbf},\n\t// Block 0xb1, offset 0x53d\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0008, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xb2, offset 0x545\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xbe},\n\t{value: 0x3008, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb3, offset 0x54c\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x3808, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x89},\n\t{value: 0x3308, lo: 0x8a, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xb4, offset 0x55a\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x92},\n\t{value: 0x0008, lo: 0x93, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3808, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb5, offset 0x567\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0008, lo: 0x9f, hi: 0xa8},\n\t{value: 0x0018, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0xb6, offset 0x574\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x3308, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3008, lo: 0xa0, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xa9},\n\t{value: 0x3b08, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xb7, offset 0x57d\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbf},\n\t// Block 0xb8, offset 0x581\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x3b08, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x84},\n\t{value: 0x3008, lo: 0x85, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x8a},\n\t{value: 0x0018, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0xb9, offset 0x58f\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb8},\n\t{value: 0x3008, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0xba, offset 0x597\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x81},\n\t{value: 0x3b08, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x85},\n\t{value: 0x0018, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xbb, offset 0x5a2\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbc, offset 0x5ab\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x9b},\n\t{value: 0x3308, lo: 0x9c, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0xbd, offset 0x5b1\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbe, offset 0x5b9\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xbf},\n\t// Block 0xbf, offset 0x5c2\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb5},\n\t{value: 0x3808, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0xc0, offset 0x5cc\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0xbf},\n\t// Block 0xc1, offset 0x5cf\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9f},\n\t{value: 0x3008, lo: 0xa0, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xaa},\n\t{value: 0x3b08, lo: 0xab, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbf},\n\t// Block 0xc2, offset 0x5db\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x049d, lo: 0xa0, hi: 0xbf},\n\t// Block 0xc3, offset 0x5de\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc4, offset 0x5e3\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xc5, offset 0x5e6\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc6, offset 0x5f0\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xbf},\n\t// Block 0xc7, offset 0x5f9\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xa9},\n\t{value: 0x3308, lo: 0xaa, hi: 0xb0},\n\t{value: 0x3008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xc8, offset 0x605\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xc9, offset 0x608\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xca, offset 0x60d\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0xbf},\n\t// Block 0xcb, offset 0x610\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xbf},\n\t// Block 0xcc, offset 0x613\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0xbf},\n\t// Block 0xcd, offset 0x616\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0xce, offset 0x61d\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0018, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xcf, offset 0x624\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0xd0, offset 0x628\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0008, lo: 0xa3, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbf},\n\t// Block 0xd1, offset 0x633\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0xbf},\n\t// Block 0xd2, offset 0x636\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x3008, lo: 0x91, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd3, offset 0x63c\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x8e},\n\t{value: 0x3308, lo: 0x8f, hi: 0x92},\n\t{value: 0x0008, lo: 0x93, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xd4, offset 0x641\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0040, lo: 0xa1, hi: 0xbf},\n\t// Block 0xd5, offset 0x645\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xbf},\n\t// Block 0xd6, offset 0x648\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbf},\n\t// Block 0xd7, offset 0x64b\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x81},\n\t{value: 0x0040, lo: 0x82, hi: 0xbf},\n\t// Block 0xd8, offset 0x64e\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0xd9, offset 0x653\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0018, lo: 0x9c, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x03c0, lo: 0xa0, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xbf},\n\t// Block 0xda, offset 0x65d\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xdb, offset 0x660\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa8},\n\t{value: 0x0018, lo: 0xa9, hi: 0xbf},\n\t// Block 0xdc, offset 0x664\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0018, lo: 0x80, hi: 0x9d},\n\t{value: 0xb5b9, lo: 0x9e, hi: 0x9e},\n\t{value: 0xb601, lo: 0x9f, hi: 0x9f},\n\t{value: 0xb649, lo: 0xa0, hi: 0xa0},\n\t{value: 0xb6b1, lo: 0xa1, hi: 0xa1},\n\t{value: 0xb719, lo: 0xa2, hi: 0xa2},\n\t{value: 0xb781, lo: 0xa3, hi: 0xa3},\n\t{value: 0xb7e9, lo: 0xa4, hi: 0xa4},\n\t{value: 0x3018, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3318, lo: 0xa7, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xac},\n\t{value: 0x3018, lo: 0xad, hi: 0xb2},\n\t{value: 0x0340, lo: 0xb3, hi: 0xba},\n\t{value: 0x3318, lo: 0xbb, hi: 0xbf},\n\t// Block 0xdd, offset 0x673\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3318, lo: 0x80, hi: 0x82},\n\t{value: 0x0018, lo: 0x83, hi: 0x84},\n\t{value: 0x3318, lo: 0x85, hi: 0x8b},\n\t{value: 0x0018, lo: 0x8c, hi: 0xa9},\n\t{value: 0x3318, lo: 0xaa, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xba},\n\t{value: 0xb851, lo: 0xbb, hi: 0xbb},\n\t{value: 0xb899, lo: 0xbc, hi: 0xbc},\n\t{value: 0xb8e1, lo: 0xbd, hi: 0xbd},\n\t{value: 0xb949, lo: 0xbe, hi: 0xbe},\n\t{value: 0xb9b1, lo: 0xbf, hi: 0xbf},\n\t// Block 0xde, offset 0x67f\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0xba19, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xbf},\n\t// Block 0xdf, offset 0x683\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x81},\n\t{value: 0x3318, lo: 0x82, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0xbf},\n\t// Block 0xe0, offset 0x688\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xe1, offset 0x68d\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3308, lo: 0x80, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbf},\n\t// Block 0xe2, offset 0x691\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x3308, lo: 0x80, hi: 0xac},\n\t{value: 0x0018, lo: 0xad, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0xe3, offset 0x696\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x3308, lo: 0xa1, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0xe4, offset 0x69f\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x3308, lo: 0x88, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xa4},\n\t{value: 0x0040, lo: 0xa5, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xbf},\n\t// Block 0xe5, offset 0x6aa\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0808, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x86},\n\t{value: 0x0818, lo: 0x87, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0xbf},\n\t// Block 0xe6, offset 0x6b0\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0a08, lo: 0x80, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0818, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xe7, offset 0x6b8\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xe8, offset 0x6bc\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0xe9, offset 0x6c0\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xb0},\n\t{value: 0x0018, lo: 0xb1, hi: 0xbf},\n\t// Block 0xea, offset 0x6c6\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x0018, lo: 0x91, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xeb, offset 0x6cc\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x8f},\n\t{value: 0xc1c1, lo: 0x90, hi: 0x90},\n\t{value: 0x0018, lo: 0x91, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xbf},\n\t// Block 0xec, offset 0x6d1\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xa5},\n\t{value: 0x0018, lo: 0xa6, hi: 0xbf},\n\t// Block 0xed, offset 0x6d4\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0xc7e9, lo: 0x80, hi: 0x80},\n\t{value: 0xc839, lo: 0x81, hi: 0x81},\n\t{value: 0xc889, lo: 0x82, hi: 0x82},\n\t{value: 0xc8d9, lo: 0x83, hi: 0x83},\n\t{value: 0xc929, lo: 0x84, hi: 0x84},\n\t{value: 0xc979, lo: 0x85, hi: 0x85},\n\t{value: 0xc9c9, lo: 0x86, hi: 0x86},\n\t{value: 0xca19, lo: 0x87, hi: 0x87},\n\t{value: 0xca69, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0xcab9, lo: 0x90, hi: 0x90},\n\t{value: 0xcad9, lo: 0x91, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0xbf},\n\t// Block 0xee, offset 0x6e2\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x92},\n\t{value: 0x0040, lo: 0x93, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xef, offset 0x6e9\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0xf0, offset 0x6ec\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0xbf},\n\t// Block 0xf1, offset 0x6ef\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0xf2, offset 0x6f3\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbf},\n\t// Block 0xf3, offset 0x6f9\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xbf},\n\t// Block 0xf4, offset 0x6fe\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb2},\n\t{value: 0x0018, lo: 0xb3, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xf5, offset 0x708\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xbf},\n\t// Block 0xf6, offset 0x70d\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0xbf},\n\t// Block 0xf7, offset 0x710\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0xbf},\n\t// Block 0xf8, offset 0x713\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0xbf},\n\t// Block 0xf9, offset 0x716\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xfa, offset 0x719\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0xfb, offset 0x71d\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xbf},\n\t// Block 0xfc, offset 0x720\n\t{value: 0x0020, lo: 0x0f},\n\t{value: 0xdeb9, lo: 0x80, hi: 0x89},\n\t{value: 0x8dfd, lo: 0x8a, hi: 0x8a},\n\t{value: 0xdff9, lo: 0x8b, hi: 0x9c},\n\t{value: 0x8e1d, lo: 0x9d, hi: 0x9d},\n\t{value: 0xe239, lo: 0x9e, hi: 0xa2},\n\t{value: 0x8e3d, lo: 0xa3, hi: 0xa3},\n\t{value: 0xe2d9, lo: 0xa4, hi: 0xab},\n\t{value: 0x7ed5, lo: 0xac, hi: 0xac},\n\t{value: 0xe3d9, lo: 0xad, hi: 0xaf},\n\t{value: 0x8e5d, lo: 0xb0, hi: 0xb0},\n\t{value: 0xe439, lo: 0xb1, hi: 0xb6},\n\t{value: 0x8e7d, lo: 0xb7, hi: 0xb9},\n\t{value: 0xe4f9, lo: 0xba, hi: 0xba},\n\t{value: 0x8edd, lo: 0xbb, hi: 0xbb},\n\t{value: 0xe519, lo: 0xbc, hi: 0xbf},\n\t// Block 0xfd, offset 0x730\n\t{value: 0x0020, lo: 0x10},\n\t{value: 0x937d, lo: 0x80, hi: 0x80},\n\t{value: 0xf099, lo: 0x81, hi: 0x86},\n\t{value: 0x939d, lo: 0x87, hi: 0x8a},\n\t{value: 0xd9f9, lo: 0x8b, hi: 0x8b},\n\t{value: 0xf159, lo: 0x8c, hi: 0x96},\n\t{value: 0x941d, lo: 0x97, hi: 0x97},\n\t{value: 0xf2b9, lo: 0x98, hi: 0xa3},\n\t{value: 0x943d, lo: 0xa4, hi: 0xa6},\n\t{value: 0xf439, lo: 0xa7, hi: 0xaa},\n\t{value: 0x949d, lo: 0xab, hi: 0xab},\n\t{value: 0xf4b9, lo: 0xac, hi: 0xac},\n\t{value: 0x94bd, lo: 0xad, hi: 0xad},\n\t{value: 0xf4d9, lo: 0xae, hi: 0xaf},\n\t{value: 0x94dd, lo: 0xb0, hi: 0xb1},\n\t{value: 0xf519, lo: 0xb2, hi: 0xbe},\n\t{value: 0x2040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xfe, offset 0x741\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0340, lo: 0x81, hi: 0x81},\n\t{value: 0x0040, lo: 0x82, hi: 0x9f},\n\t{value: 0x0340, lo: 0xa0, hi: 0xbf},\n\t// Block 0xff, offset 0x746\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0340, lo: 0x80, hi: 0xbf},\n\t// Block 0x100, offset 0x748\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x33c0, lo: 0x80, hi: 0xbf},\n\t// Block 0x101, offset 0x74a\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x33c0, lo: 0x80, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n}\n\n// Total table size 41662 bytes (40KiB); checksum: 355A58A4\n"
  },
  {
    "path": "vendor/golang.org/x/net/idna/trie.go",
    "content": "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n// Copyright 2016 The Go 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 idna\n\n// Sparse block handling code.\n\ntype valueRange struct {\n\tvalue  uint16 // header: value:stride\n\tlo, hi byte   // header: lo:n\n}\n\ntype sparseBlocks struct {\n\tvalues []valueRange\n\toffset []uint16\n}\n\nvar idnaSparse = sparseBlocks{\n\tvalues: idnaSparseValues[:],\n\toffset: idnaSparseOffset[:],\n}\n\n// Don't use newIdnaTrie to avoid unconditional linking in of the table.\nvar trie = &idnaTrie{}\n\n// lookup determines the type of block n and looks up the value for b.\n// For n < t.cutoff, the block is a simple lookup table. Otherwise, the block\n// is a list of ranges with an accompanying value. Given a matching range r,\n// the value for b is by r.value + (b - r.lo) * stride.\nfunc (t *sparseBlocks) lookup(n uint32, b byte) uint16 {\n\toffset := t.offset[n]\n\theader := t.values[offset]\n\tlo := offset + 1\n\thi := lo + uint16(header.lo)\n\tfor lo < hi {\n\t\tm := lo + (hi-lo)/2\n\t\tr := t.values[m]\n\t\tif r.lo <= b && b <= r.hi {\n\t\t\treturn r.value + uint16(b-r.lo)*header.value\n\t\t}\n\t\tif b < r.lo {\n\t\t\thi = m\n\t\t} else {\n\t\t\tlo = m + 1\n\t\t}\n\t}\n\treturn 0\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/idna/trie12.0.0.go",
    "content": "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n// Copyright 2016 The Go 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\n//go:build !go1.16\n\npackage idna\n\n// appendMapping appends the mapping for the respective rune. isMapped must be\n// true. A mapping is a categorization of a rune as defined in UTS #46.\nfunc (c info) appendMapping(b []byte, s string) []byte {\n\tindex := int(c >> indexShift)\n\tif c&xorBit == 0 {\n\t\ts := mappings[index:]\n\t\treturn append(b, s[1:s[0]+1]...)\n\t}\n\tb = append(b, s...)\n\tif c&inlineXOR == inlineXOR {\n\t\t// TODO: support and handle two-byte inline masks\n\t\tb[len(b)-1] ^= byte(index)\n\t} else {\n\t\tfor p := len(b) - int(xorData[index]); p < len(b); p++ {\n\t\t\tindex++\n\t\t\tb[p] ^= xorData[index]\n\t\t}\n\t}\n\treturn b\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/idna/trie13.0.0.go",
    "content": "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n// Copyright 2016 The Go 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\n//go:build go1.16\n\npackage idna\n\n// appendMapping appends the mapping for the respective rune. isMapped must be\n// true. A mapping is a categorization of a rune as defined in UTS #46.\nfunc (c info) appendMapping(b []byte, s string) []byte {\n\tindex := int(c >> indexShift)\n\tif c&xorBit == 0 {\n\t\tp := index\n\t\treturn append(b, mappings[mappingIndex[p]:mappingIndex[p+1]]...)\n\t}\n\tb = append(b, s...)\n\tif c&inlineXOR == inlineXOR {\n\t\t// TODO: support and handle two-byte inline masks\n\t\tb[len(b)-1] ^= byte(index)\n\t} else {\n\t\tfor p := len(b) - int(xorData[index]); p < len(b); p++ {\n\t\t\tindex++\n\t\t\tb[p] ^= xorData[index]\n\t\t}\n\t}\n\treturn b\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/idna/trieval.go",
    "content": "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\npackage idna\n\n// This file contains definitions for interpreting the trie value of the idna\n// trie generated by \"go run gen*.go\". It is shared by both the generator\n// program and the resultant package. Sharing is achieved by the generator\n// copying gen_trieval.go to trieval.go and changing what's above this comment.\n\n// info holds information from the IDNA mapping table for a single rune. It is\n// the value returned by a trie lookup. In most cases, all information fits in\n// a 16-bit value. For mappings, this value may contain an index into a slice\n// with the mapped string. Such mappings can consist of the actual mapped value\n// or an XOR pattern to be applied to the bytes of the UTF8 encoding of the\n// input rune. This technique is used by the cases packages and reduces the\n// table size significantly.\n//\n// The per-rune values have the following format:\n//\n//\tif mapped {\n//\t  if inlinedXOR {\n//\t    15..13 inline XOR marker\n//\t    12..11 unused\n//\t    10..3  inline XOR mask\n//\t  } else {\n//\t    15..3  index into xor or mapping table\n//\t  }\n//\t} else {\n//\t    15..14 unused\n//\t    13     mayNeedNorm\n//\t    12..11 attributes\n//\t    10..8  joining type\n//\t     7..3  category type\n//\t}\n//\t   2  use xor pattern\n//\t1..0  mapped category\n//\n// See the definitions below for a more detailed description of the various\n// bits.\ntype info uint16\n\nconst (\n\tcatSmallMask = 0x3\n\tcatBigMask   = 0xF8\n\tindexShift   = 3\n\txorBit       = 0x4    // interpret the index as an xor pattern\n\tinlineXOR    = 0xE000 // These bits are set if the XOR pattern is inlined.\n\n\tjoinShift = 8\n\tjoinMask  = 0x07\n\n\t// Attributes\n\tattributesMask = 0x1800\n\tviramaModifier = 0x1800\n\tmodifier       = 0x1000\n\trtl            = 0x0800\n\n\tmayNeedNorm = 0x2000\n)\n\n// A category corresponds to a category defined in the IDNA mapping table.\ntype category uint16\n\nconst (\n\tunknown              category = 0 // not currently defined in unicode.\n\tmapped               category = 1\n\tdisallowedSTD3Mapped category = 2\n\tdeviation            category = 3\n)\n\nconst (\n\tvalid               category = 0x08\n\tvalidNV8            category = 0x18\n\tvalidXV8            category = 0x28\n\tdisallowed          category = 0x40\n\tdisallowedSTD3Valid category = 0x80\n\tignored             category = 0xC0\n)\n\n// join types and additional rune information\nconst (\n\tjoiningL = (iota + 1)\n\tjoiningD\n\tjoiningT\n\tjoiningR\n\n\t//the following types are derived during processing\n\tjoinZWJ\n\tjoinZWNJ\n\tjoinVirama\n\tnumJoinTypes\n)\n\nfunc (c info) isMapped() bool {\n\treturn c&0x3 != 0\n}\n\nfunc (c info) category() category {\n\tsmall := c & catSmallMask\n\tif small != 0 {\n\t\treturn category(small)\n\t}\n\treturn category(c & catBigMask)\n}\n\nfunc (c info) joinType() info {\n\tif c.isMapped() {\n\t\treturn 0\n\t}\n\treturn (c >> joinShift) & joinMask\n}\n\nfunc (c info) isModifier() bool {\n\treturn c&(modifier|catSmallMask) == modifier\n}\n\nfunc (c info) isViramaModifier() bool {\n\treturn c&(attributesMask|catSmallMask) == viramaModifier\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/httpcommon/ascii.go",
    "content": "// Copyright 2025 The Go 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 httpcommon\n\nimport \"strings\"\n\n// The HTTP protocols are defined in terms of ASCII, not Unicode. This file\n// contains helper functions which may use Unicode-aware functions which would\n// otherwise be unsafe and could introduce vulnerabilities if used improperly.\n\n// asciiEqualFold is strings.EqualFold, ASCII only. It reports whether s and t\n// are equal, ASCII-case-insensitively.\nfunc asciiEqualFold(s, t string) bool {\n\tif len(s) != len(t) {\n\t\treturn false\n\t}\n\tfor i := 0; i < len(s); i++ {\n\t\tif lower(s[i]) != lower(t[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// lower returns the ASCII lowercase version of b.\nfunc lower(b byte) byte {\n\tif 'A' <= b && b <= 'Z' {\n\t\treturn b + ('a' - 'A')\n\t}\n\treturn b\n}\n\n// isASCIIPrint returns whether s is ASCII and printable according to\n// https://tools.ietf.org/html/rfc20#section-4.2.\nfunc isASCIIPrint(s string) bool {\n\tfor i := 0; i < len(s); i++ {\n\t\tif s[i] < ' ' || s[i] > '~' {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// asciiToLower returns the lowercase version of s if s is ASCII and printable,\n// and whether or not it was.\nfunc asciiToLower(s string) (lower string, ok bool) {\n\tif !isASCIIPrint(s) {\n\t\treturn \"\", false\n\t}\n\treturn strings.ToLower(s), true\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/httpcommon/headermap.go",
    "content": "// Copyright 2025 The Go 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 httpcommon\n\nimport (\n\t\"net/textproto\"\n\t\"sync\"\n)\n\nvar (\n\tcommonBuildOnce   sync.Once\n\tcommonLowerHeader map[string]string // Go-Canonical-Case -> lower-case\n\tcommonCanonHeader map[string]string // lower-case -> Go-Canonical-Case\n)\n\nfunc buildCommonHeaderMapsOnce() {\n\tcommonBuildOnce.Do(buildCommonHeaderMaps)\n}\n\nfunc buildCommonHeaderMaps() {\n\tcommon := []string{\n\t\t\"accept\",\n\t\t\"accept-charset\",\n\t\t\"accept-encoding\",\n\t\t\"accept-language\",\n\t\t\"accept-ranges\",\n\t\t\"age\",\n\t\t\"access-control-allow-credentials\",\n\t\t\"access-control-allow-headers\",\n\t\t\"access-control-allow-methods\",\n\t\t\"access-control-allow-origin\",\n\t\t\"access-control-expose-headers\",\n\t\t\"access-control-max-age\",\n\t\t\"access-control-request-headers\",\n\t\t\"access-control-request-method\",\n\t\t\"allow\",\n\t\t\"authorization\",\n\t\t\"cache-control\",\n\t\t\"content-disposition\",\n\t\t\"content-encoding\",\n\t\t\"content-language\",\n\t\t\"content-length\",\n\t\t\"content-location\",\n\t\t\"content-range\",\n\t\t\"content-type\",\n\t\t\"cookie\",\n\t\t\"date\",\n\t\t\"etag\",\n\t\t\"expect\",\n\t\t\"expires\",\n\t\t\"from\",\n\t\t\"host\",\n\t\t\"if-match\",\n\t\t\"if-modified-since\",\n\t\t\"if-none-match\",\n\t\t\"if-unmodified-since\",\n\t\t\"last-modified\",\n\t\t\"link\",\n\t\t\"location\",\n\t\t\"max-forwards\",\n\t\t\"origin\",\n\t\t\"proxy-authenticate\",\n\t\t\"proxy-authorization\",\n\t\t\"range\",\n\t\t\"referer\",\n\t\t\"refresh\",\n\t\t\"retry-after\",\n\t\t\"server\",\n\t\t\"set-cookie\",\n\t\t\"strict-transport-security\",\n\t\t\"trailer\",\n\t\t\"transfer-encoding\",\n\t\t\"user-agent\",\n\t\t\"vary\",\n\t\t\"via\",\n\t\t\"www-authenticate\",\n\t\t\"x-forwarded-for\",\n\t\t\"x-forwarded-proto\",\n\t}\n\tcommonLowerHeader = make(map[string]string, len(common))\n\tcommonCanonHeader = make(map[string]string, len(common))\n\tfor _, v := range common {\n\t\tchk := textproto.CanonicalMIMEHeaderKey(v)\n\t\tcommonLowerHeader[chk] = v\n\t\tcommonCanonHeader[v] = chk\n\t}\n}\n\n// LowerHeader returns the lowercase form of a header name,\n// used on the wire for HTTP/2 and HTTP/3 requests.\nfunc LowerHeader(v string) (lower string, ascii bool) {\n\tbuildCommonHeaderMapsOnce()\n\tif s, ok := commonLowerHeader[v]; ok {\n\t\treturn s, true\n\t}\n\treturn asciiToLower(v)\n}\n\n// CanonicalHeader canonicalizes a header name. (For example, \"host\" becomes \"Host\".)\nfunc CanonicalHeader(v string) string {\n\tbuildCommonHeaderMapsOnce()\n\tif s, ok := commonCanonHeader[v]; ok {\n\t\treturn s\n\t}\n\treturn textproto.CanonicalMIMEHeaderKey(v)\n}\n\n// CachedCanonicalHeader returns the canonical form of a well-known header name.\nfunc CachedCanonicalHeader(v string) (string, bool) {\n\tbuildCommonHeaderMapsOnce()\n\ts, ok := commonCanonHeader[v]\n\treturn s, ok\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/httpcommon/request.go",
    "content": "// Copyright 2025 The Go 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 httpcommon\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http/httptrace\"\n\t\"net/textproto\"\n\t\"net/url\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"golang.org/x/net/http/httpguts\"\n\t\"golang.org/x/net/http2/hpack\"\n)\n\nvar (\n\tErrRequestHeaderListSize = errors.New(\"request header list larger than peer's advertised limit\")\n)\n\n// Request is a subset of http.Request.\n// It'd be simpler to pass an *http.Request, of course, but we can't depend on net/http\n// without creating a dependency cycle.\ntype Request struct {\n\tURL                 *url.URL\n\tMethod              string\n\tHost                string\n\tHeader              map[string][]string\n\tTrailer             map[string][]string\n\tActualContentLength int64 // 0 means 0, -1 means unknown\n}\n\n// EncodeHeadersParam is parameters to EncodeHeaders.\ntype EncodeHeadersParam struct {\n\tRequest Request\n\n\t// AddGzipHeader indicates that an \"accept-encoding: gzip\" header should be\n\t// added to the request.\n\tAddGzipHeader bool\n\n\t// PeerMaxHeaderListSize, when non-zero, is the peer's MAX_HEADER_LIST_SIZE setting.\n\tPeerMaxHeaderListSize uint64\n\n\t// DefaultUserAgent is the User-Agent header to send when the request\n\t// neither contains a User-Agent nor disables it.\n\tDefaultUserAgent string\n}\n\n// EncodeHeadersParam is the result of EncodeHeaders.\ntype EncodeHeadersResult struct {\n\tHasBody     bool\n\tHasTrailers bool\n}\n\n// EncodeHeaders constructs request headers common to HTTP/2 and HTTP/3.\n// It validates a request and calls headerf with each pseudo-header and header\n// for the request.\n// The headerf function is called with the validated, canonicalized header name.\nfunc EncodeHeaders(ctx context.Context, param EncodeHeadersParam, headerf func(name, value string)) (res EncodeHeadersResult, _ error) {\n\treq := param.Request\n\n\t// Check for invalid connection-level headers.\n\tif err := checkConnHeaders(req.Header); err != nil {\n\t\treturn res, err\n\t}\n\n\tif req.URL == nil {\n\t\treturn res, errors.New(\"Request.URL is nil\")\n\t}\n\n\thost := req.Host\n\tif host == \"\" {\n\t\thost = req.URL.Host\n\t}\n\thost, err := httpguts.PunycodeHostPort(host)\n\tif err != nil {\n\t\treturn res, err\n\t}\n\tif !httpguts.ValidHostHeader(host) {\n\t\treturn res, errors.New(\"invalid Host header\")\n\t}\n\n\t// isNormalConnect is true if this is a non-extended CONNECT request.\n\tisNormalConnect := false\n\tvar protocol string\n\tif vv := req.Header[\":protocol\"]; len(vv) > 0 {\n\t\tprotocol = vv[0]\n\t}\n\tif req.Method == \"CONNECT\" && protocol == \"\" {\n\t\tisNormalConnect = true\n\t} else if protocol != \"\" && req.Method != \"CONNECT\" {\n\t\treturn res, errors.New(\"invalid :protocol header in non-CONNECT request\")\n\t}\n\n\t// Validate the path, except for non-extended CONNECT requests which have no path.\n\tvar path string\n\tif !isNormalConnect {\n\t\tpath = req.URL.RequestURI()\n\t\tif !validPseudoPath(path) {\n\t\t\torig := path\n\t\t\tpath = strings.TrimPrefix(path, req.URL.Scheme+\"://\"+host)\n\t\t\tif !validPseudoPath(path) {\n\t\t\t\tif req.URL.Opaque != \"\" {\n\t\t\t\t\treturn res, fmt.Errorf(\"invalid request :path %q from URL.Opaque = %q\", orig, req.URL.Opaque)\n\t\t\t\t} else {\n\t\t\t\t\treturn res, fmt.Errorf(\"invalid request :path %q\", orig)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check for any invalid headers+trailers and return an error before we\n\t// potentially pollute our hpack state. (We want to be able to\n\t// continue to reuse the hpack encoder for future requests)\n\tif err := validateHeaders(req.Header); err != \"\" {\n\t\treturn res, fmt.Errorf(\"invalid HTTP header %s\", err)\n\t}\n\tif err := validateHeaders(req.Trailer); err != \"\" {\n\t\treturn res, fmt.Errorf(\"invalid HTTP trailer %s\", err)\n\t}\n\n\ttrailers, err := commaSeparatedTrailers(req.Trailer)\n\tif err != nil {\n\t\treturn res, err\n\t}\n\n\tenumerateHeaders := func(f func(name, value string)) {\n\t\t// 8.1.2.3 Request Pseudo-Header Fields\n\t\t// The :path pseudo-header field includes the path and query parts of the\n\t\t// target URI (the path-absolute production and optionally a '?' character\n\t\t// followed by the query production, see Sections 3.3 and 3.4 of\n\t\t// [RFC3986]).\n\t\tf(\":authority\", host)\n\t\tm := req.Method\n\t\tif m == \"\" {\n\t\t\tm = \"GET\"\n\t\t}\n\t\tf(\":method\", m)\n\t\tif !isNormalConnect {\n\t\t\tf(\":path\", path)\n\t\t\tf(\":scheme\", req.URL.Scheme)\n\t\t}\n\t\tif protocol != \"\" {\n\t\t\tf(\":protocol\", protocol)\n\t\t}\n\t\tif trailers != \"\" {\n\t\t\tf(\"trailer\", trailers)\n\t\t}\n\n\t\tvar didUA bool\n\t\tfor k, vv := range req.Header {\n\t\t\tif asciiEqualFold(k, \"host\") || asciiEqualFold(k, \"content-length\") {\n\t\t\t\t// Host is :authority, already sent.\n\t\t\t\t// Content-Length is automatic, set below.\n\t\t\t\tcontinue\n\t\t\t} else if asciiEqualFold(k, \"connection\") ||\n\t\t\t\tasciiEqualFold(k, \"proxy-connection\") ||\n\t\t\t\tasciiEqualFold(k, \"transfer-encoding\") ||\n\t\t\t\tasciiEqualFold(k, \"upgrade\") ||\n\t\t\t\tasciiEqualFold(k, \"keep-alive\") {\n\t\t\t\t// Per 8.1.2.2 Connection-Specific Header\n\t\t\t\t// Fields, don't send connection-specific\n\t\t\t\t// fields. We have already checked if any\n\t\t\t\t// are error-worthy so just ignore the rest.\n\t\t\t\tcontinue\n\t\t\t} else if asciiEqualFold(k, \"user-agent\") {\n\t\t\t\t// Match Go's http1 behavior: at most one\n\t\t\t\t// User-Agent. If set to nil or empty string,\n\t\t\t\t// then omit it. Otherwise if not mentioned,\n\t\t\t\t// include the default (below).\n\t\t\t\tdidUA = true\n\t\t\t\tif len(vv) < 1 {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tvv = vv[:1]\n\t\t\t\tif vv[0] == \"\" {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t} else if asciiEqualFold(k, \"cookie\") {\n\t\t\t\t// Per 8.1.2.5 To allow for better compression efficiency, the\n\t\t\t\t// Cookie header field MAY be split into separate header fields,\n\t\t\t\t// each with one or more cookie-pairs.\n\t\t\t\tfor _, v := range vv {\n\t\t\t\t\tfor {\n\t\t\t\t\t\tp := strings.IndexByte(v, ';')\n\t\t\t\t\t\tif p < 0 {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf(\"cookie\", v[:p])\n\t\t\t\t\t\tp++\n\t\t\t\t\t\t// strip space after semicolon if any.\n\t\t\t\t\t\tfor p+1 <= len(v) && v[p] == ' ' {\n\t\t\t\t\t\t\tp++\n\t\t\t\t\t\t}\n\t\t\t\t\t\tv = v[p:]\n\t\t\t\t\t}\n\t\t\t\t\tif len(v) > 0 {\n\t\t\t\t\t\tf(\"cookie\", v)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t} else if k == \":protocol\" {\n\t\t\t\t// :protocol pseudo-header was already sent above.\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tfor _, v := range vv {\n\t\t\t\tf(k, v)\n\t\t\t}\n\t\t}\n\t\tif shouldSendReqContentLength(req.Method, req.ActualContentLength) {\n\t\t\tf(\"content-length\", strconv.FormatInt(req.ActualContentLength, 10))\n\t\t}\n\t\tif param.AddGzipHeader {\n\t\t\tf(\"accept-encoding\", \"gzip\")\n\t\t}\n\t\tif !didUA {\n\t\t\tf(\"user-agent\", param.DefaultUserAgent)\n\t\t}\n\t}\n\n\t// Do a first pass over the headers counting bytes to ensure\n\t// we don't exceed cc.peerMaxHeaderListSize. This is done as a\n\t// separate pass before encoding the headers to prevent\n\t// modifying the hpack state.\n\tif param.PeerMaxHeaderListSize > 0 {\n\t\thlSize := uint64(0)\n\t\tenumerateHeaders(func(name, value string) {\n\t\t\thf := hpack.HeaderField{Name: name, Value: value}\n\t\t\thlSize += uint64(hf.Size())\n\t\t})\n\n\t\tif hlSize > param.PeerMaxHeaderListSize {\n\t\t\treturn res, ErrRequestHeaderListSize\n\t\t}\n\t}\n\n\ttrace := httptrace.ContextClientTrace(ctx)\n\n\t// Header list size is ok. Write the headers.\n\tenumerateHeaders(func(name, value string) {\n\t\tname, ascii := LowerHeader(name)\n\t\tif !ascii {\n\t\t\t// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header\n\t\t\t// field names have to be ASCII characters (just as in HTTP/1.x).\n\t\t\treturn\n\t\t}\n\n\t\theaderf(name, value)\n\n\t\tif trace != nil && trace.WroteHeaderField != nil {\n\t\t\ttrace.WroteHeaderField(name, []string{value})\n\t\t}\n\t})\n\n\tres.HasBody = req.ActualContentLength != 0\n\tres.HasTrailers = trailers != \"\"\n\treturn res, nil\n}\n\n// IsRequestGzip reports whether we should add an Accept-Encoding: gzip header\n// for a request.\nfunc IsRequestGzip(method string, header map[string][]string, disableCompression bool) bool {\n\t// TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?\n\tif !disableCompression &&\n\t\tlen(header[\"Accept-Encoding\"]) == 0 &&\n\t\tlen(header[\"Range\"]) == 0 &&\n\t\tmethod != \"HEAD\" {\n\t\t// Request gzip only, not deflate. Deflate is ambiguous and\n\t\t// not as universally supported anyway.\n\t\t// See: https://zlib.net/zlib_faq.html#faq39\n\t\t//\n\t\t// Note that we don't request this for HEAD requests,\n\t\t// due to a bug in nginx:\n\t\t//   http://trac.nginx.org/nginx/ticket/358\n\t\t//   https://golang.org/issue/5522\n\t\t//\n\t\t// We don't request gzip if the request is for a range, since\n\t\t// auto-decoding a portion of a gzipped document will just fail\n\t\t// anyway. See https://golang.org/issue/8923\n\t\treturn true\n\t}\n\treturn false\n}\n\n// checkConnHeaders checks whether req has any invalid connection-level headers.\n//\n// https://www.rfc-editor.org/rfc/rfc9114.html#section-4.2-3\n// https://www.rfc-editor.org/rfc/rfc9113.html#section-8.2.2-1\n//\n// Certain headers are special-cased as okay but not transmitted later.\n// For example, we allow \"Transfer-Encoding: chunked\", but drop the header when encoding.\nfunc checkConnHeaders(h map[string][]string) error {\n\tif vv := h[\"Upgrade\"]; len(vv) > 0 && (vv[0] != \"\" && vv[0] != \"chunked\") {\n\t\treturn fmt.Errorf(\"invalid Upgrade request header: %q\", vv)\n\t}\n\tif vv := h[\"Transfer-Encoding\"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != \"\" && vv[0] != \"chunked\") {\n\t\treturn fmt.Errorf(\"invalid Transfer-Encoding request header: %q\", vv)\n\t}\n\tif vv := h[\"Connection\"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != \"\" && !asciiEqualFold(vv[0], \"close\") && !asciiEqualFold(vv[0], \"keep-alive\")) {\n\t\treturn fmt.Errorf(\"invalid Connection request header: %q\", vv)\n\t}\n\treturn nil\n}\n\nfunc commaSeparatedTrailers(trailer map[string][]string) (string, error) {\n\tkeys := make([]string, 0, len(trailer))\n\tfor k := range trailer {\n\t\tk = CanonicalHeader(k)\n\t\tswitch k {\n\t\tcase \"Transfer-Encoding\", \"Trailer\", \"Content-Length\":\n\t\t\treturn \"\", fmt.Errorf(\"invalid Trailer key %q\", k)\n\t\t}\n\t\tkeys = append(keys, k)\n\t}\n\tif len(keys) > 0 {\n\t\tsort.Strings(keys)\n\t\treturn strings.Join(keys, \",\"), nil\n\t}\n\treturn \"\", nil\n}\n\n// validPseudoPath reports whether v is a valid :path pseudo-header\n// value. It must be either:\n//\n//   - a non-empty string starting with '/'\n//   - the string '*', for OPTIONS requests.\n//\n// For now this is only used a quick check for deciding when to clean\n// up Opaque URLs before sending requests from the Transport.\n// See golang.org/issue/16847\n//\n// We used to enforce that the path also didn't start with \"//\", but\n// Google's GFE accepts such paths and Chrome sends them, so ignore\n// that part of the spec. See golang.org/issue/19103.\nfunc validPseudoPath(v string) bool {\n\treturn (len(v) > 0 && v[0] == '/') || v == \"*\"\n}\n\nfunc validateHeaders(hdrs map[string][]string) string {\n\tfor k, vv := range hdrs {\n\t\tif !httpguts.ValidHeaderFieldName(k) && k != \":protocol\" {\n\t\t\treturn fmt.Sprintf(\"name %q\", k)\n\t\t}\n\t\tfor _, v := range vv {\n\t\t\tif !httpguts.ValidHeaderFieldValue(v) {\n\t\t\t\t// Don't include the value in the error,\n\t\t\t\t// because it may be sensitive.\n\t\t\t\treturn fmt.Sprintf(\"value for header %q\", k)\n\t\t\t}\n\t\t}\n\t}\n\treturn \"\"\n}\n\n// shouldSendReqContentLength reports whether we should send\n// a \"content-length\" request header. This logic is basically a copy of the net/http\n// transferWriter.shouldSendContentLength.\n// The contentLength is the corrected contentLength (so 0 means actually 0, not unknown).\n// -1 means unknown.\nfunc shouldSendReqContentLength(method string, contentLength int64) bool {\n\tif contentLength > 0 {\n\t\treturn true\n\t}\n\tif contentLength < 0 {\n\t\treturn false\n\t}\n\t// For zero bodies, whether we send a content-length depends on the method.\n\t// It also kinda doesn't matter for http2 either way, with END_STREAM.\n\tswitch method {\n\tcase \"POST\", \"PUT\", \"PATCH\":\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// ServerRequestParam is parameters to NewServerRequest.\ntype ServerRequestParam struct {\n\tMethod                  string\n\tScheme, Authority, Path string\n\tProtocol                string\n\tHeader                  map[string][]string\n}\n\n// ServerRequestResult is the result of NewServerRequest.\ntype ServerRequestResult struct {\n\t// Various http.Request fields.\n\tURL        *url.URL\n\tRequestURI string\n\tTrailer    map[string][]string\n\n\tNeedsContinue bool // client provided an \"Expect: 100-continue\" header\n\n\t// If the request should be rejected, this is a short string suitable for passing\n\t// to the http2 package's CountError function.\n\t// It might be a bit odd to return errors this way rather than returing an error,\n\t// but this ensures we don't forget to include a CountError reason.\n\tInvalidReason string\n}\n\nfunc NewServerRequest(rp ServerRequestParam) ServerRequestResult {\n\tneedsContinue := httpguts.HeaderValuesContainsToken(rp.Header[\"Expect\"], \"100-continue\")\n\tif needsContinue {\n\t\tdelete(rp.Header, \"Expect\")\n\t}\n\t// Merge Cookie headers into one \"; \"-delimited value.\n\tif cookies := rp.Header[\"Cookie\"]; len(cookies) > 1 {\n\t\trp.Header[\"Cookie\"] = []string{strings.Join(cookies, \"; \")}\n\t}\n\n\t// Setup Trailers\n\tvar trailer map[string][]string\n\tfor _, v := range rp.Header[\"Trailer\"] {\n\t\tfor _, key := range strings.Split(v, \",\") {\n\t\t\tkey = textproto.CanonicalMIMEHeaderKey(textproto.TrimString(key))\n\t\t\tswitch key {\n\t\t\tcase \"Transfer-Encoding\", \"Trailer\", \"Content-Length\":\n\t\t\t\t// Bogus. (copy of http1 rules)\n\t\t\t\t// Ignore.\n\t\t\tdefault:\n\t\t\t\tif trailer == nil {\n\t\t\t\t\ttrailer = make(map[string][]string)\n\t\t\t\t}\n\t\t\t\ttrailer[key] = nil\n\t\t\t}\n\t\t}\n\t}\n\tdelete(rp.Header, \"Trailer\")\n\n\t// \"':authority' MUST NOT include the deprecated userinfo subcomponent\n\t// for \"http\" or \"https\" schemed URIs.\"\n\t// https://www.rfc-editor.org/rfc/rfc9113.html#section-8.3.1-2.3.8\n\tif strings.IndexByte(rp.Authority, '@') != -1 && (rp.Scheme == \"http\" || rp.Scheme == \"https\") {\n\t\treturn ServerRequestResult{\n\t\t\tInvalidReason: \"userinfo_in_authority\",\n\t\t}\n\t}\n\n\tvar url_ *url.URL\n\tvar requestURI string\n\tif rp.Method == \"CONNECT\" && rp.Protocol == \"\" {\n\t\turl_ = &url.URL{Host: rp.Authority}\n\t\trequestURI = rp.Authority // mimic HTTP/1 server behavior\n\t} else {\n\t\tvar err error\n\t\turl_, err = url.ParseRequestURI(rp.Path)\n\t\tif err != nil {\n\t\t\treturn ServerRequestResult{\n\t\t\t\tInvalidReason: \"bad_path\",\n\t\t\t}\n\t\t}\n\t\trequestURI = rp.Path\n\t}\n\n\treturn ServerRequestResult{\n\t\tURL:           url_,\n\t\tNeedsContinue: needsContinue,\n\t\tRequestURI:    requestURI,\n\t\tTrailer:       trailer,\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/iana/const.go",
    "content": "// go generate gen.go\n// Code generated by the command above; DO NOT EDIT.\n\n// Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA).\npackage iana // import \"golang.org/x/net/internal/iana\"\n\n// Differentiated Services Field Codepoints (DSCP), Updated: 2018-05-04\nconst (\n\tDiffServCS0           = 0x00 // CS0\n\tDiffServCS1           = 0x20 // CS1\n\tDiffServCS2           = 0x40 // CS2\n\tDiffServCS3           = 0x60 // CS3\n\tDiffServCS4           = 0x80 // CS4\n\tDiffServCS5           = 0xa0 // CS5\n\tDiffServCS6           = 0xc0 // CS6\n\tDiffServCS7           = 0xe0 // CS7\n\tDiffServAF11          = 0x28 // AF11\n\tDiffServAF12          = 0x30 // AF12\n\tDiffServAF13          = 0x38 // AF13\n\tDiffServAF21          = 0x48 // AF21\n\tDiffServAF22          = 0x50 // AF22\n\tDiffServAF23          = 0x58 // AF23\n\tDiffServAF31          = 0x68 // AF31\n\tDiffServAF32          = 0x70 // AF32\n\tDiffServAF33          = 0x78 // AF33\n\tDiffServAF41          = 0x88 // AF41\n\tDiffServAF42          = 0x90 // AF42\n\tDiffServAF43          = 0x98 // AF43\n\tDiffServEF            = 0xb8 // EF\n\tDiffServVOICEADMIT    = 0xb0 // VOICE-ADMIT\n\tNotECNTransport       = 0x00 // Not-ECT (Not ECN-Capable Transport)\n\tECNTransport1         = 0x01 // ECT(1) (ECN-Capable Transport(1))\n\tECNTransport0         = 0x02 // ECT(0) (ECN-Capable Transport(0))\n\tCongestionExperienced = 0x03 // CE (Congestion Experienced)\n)\n\n// Protocol Numbers, Updated: 2017-10-13\nconst (\n\tProtocolIP             = 0   // IPv4 encapsulation, pseudo protocol number\n\tProtocolHOPOPT         = 0   // IPv6 Hop-by-Hop Option\n\tProtocolICMP           = 1   // Internet Control Message\n\tProtocolIGMP           = 2   // Internet Group Management\n\tProtocolGGP            = 3   // Gateway-to-Gateway\n\tProtocolIPv4           = 4   // IPv4 encapsulation\n\tProtocolST             = 5   // Stream\n\tProtocolTCP            = 6   // Transmission Control\n\tProtocolCBT            = 7   // CBT\n\tProtocolEGP            = 8   // Exterior Gateway Protocol\n\tProtocolIGP            = 9   // any private interior gateway (used by Cisco for their IGRP)\n\tProtocolBBNRCCMON      = 10  // BBN RCC Monitoring\n\tProtocolNVPII          = 11  // Network Voice Protocol\n\tProtocolPUP            = 12  // PUP\n\tProtocolEMCON          = 14  // EMCON\n\tProtocolXNET           = 15  // Cross Net Debugger\n\tProtocolCHAOS          = 16  // Chaos\n\tProtocolUDP            = 17  // User Datagram\n\tProtocolMUX            = 18  // Multiplexing\n\tProtocolDCNMEAS        = 19  // DCN Measurement Subsystems\n\tProtocolHMP            = 20  // Host Monitoring\n\tProtocolPRM            = 21  // Packet Radio Measurement\n\tProtocolXNSIDP         = 22  // XEROX NS IDP\n\tProtocolTRUNK1         = 23  // Trunk-1\n\tProtocolTRUNK2         = 24  // Trunk-2\n\tProtocolLEAF1          = 25  // Leaf-1\n\tProtocolLEAF2          = 26  // Leaf-2\n\tProtocolRDP            = 27  // Reliable Data Protocol\n\tProtocolIRTP           = 28  // Internet Reliable Transaction\n\tProtocolISOTP4         = 29  // ISO Transport Protocol Class 4\n\tProtocolNETBLT         = 30  // Bulk Data Transfer Protocol\n\tProtocolMFENSP         = 31  // MFE Network Services Protocol\n\tProtocolMERITINP       = 32  // MERIT Internodal Protocol\n\tProtocolDCCP           = 33  // Datagram Congestion Control Protocol\n\tProtocol3PC            = 34  // Third Party Connect Protocol\n\tProtocolIDPR           = 35  // Inter-Domain Policy Routing Protocol\n\tProtocolXTP            = 36  // XTP\n\tProtocolDDP            = 37  // Datagram Delivery Protocol\n\tProtocolIDPRCMTP       = 38  // IDPR Control Message Transport Proto\n\tProtocolTPPP           = 39  // TP++ Transport Protocol\n\tProtocolIL             = 40  // IL Transport Protocol\n\tProtocolIPv6           = 41  // IPv6 encapsulation\n\tProtocolSDRP           = 42  // Source Demand Routing Protocol\n\tProtocolIPv6Route      = 43  // Routing Header for IPv6\n\tProtocolIPv6Frag       = 44  // Fragment Header for IPv6\n\tProtocolIDRP           = 45  // Inter-Domain Routing Protocol\n\tProtocolRSVP           = 46  // Reservation Protocol\n\tProtocolGRE            = 47  // Generic Routing Encapsulation\n\tProtocolDSR            = 48  // Dynamic Source Routing Protocol\n\tProtocolBNA            = 49  // BNA\n\tProtocolESP            = 50  // Encap Security Payload\n\tProtocolAH             = 51  // Authentication Header\n\tProtocolINLSP          = 52  // Integrated Net Layer Security  TUBA\n\tProtocolNARP           = 54  // NBMA Address Resolution Protocol\n\tProtocolMOBILE         = 55  // IP Mobility\n\tProtocolTLSP           = 56  // Transport Layer Security Protocol using Kryptonet key management\n\tProtocolSKIP           = 57  // SKIP\n\tProtocolIPv6ICMP       = 58  // ICMP for IPv6\n\tProtocolIPv6NoNxt      = 59  // No Next Header for IPv6\n\tProtocolIPv6Opts       = 60  // Destination Options for IPv6\n\tProtocolCFTP           = 62  // CFTP\n\tProtocolSATEXPAK       = 64  // SATNET and Backroom EXPAK\n\tProtocolKRYPTOLAN      = 65  // Kryptolan\n\tProtocolRVD            = 66  // MIT Remote Virtual Disk Protocol\n\tProtocolIPPC           = 67  // Internet Pluribus Packet Core\n\tProtocolSATMON         = 69  // SATNET Monitoring\n\tProtocolVISA           = 70  // VISA Protocol\n\tProtocolIPCV           = 71  // Internet Packet Core Utility\n\tProtocolCPNX           = 72  // Computer Protocol Network Executive\n\tProtocolCPHB           = 73  // Computer Protocol Heart Beat\n\tProtocolWSN            = 74  // Wang Span Network\n\tProtocolPVP            = 75  // Packet Video Protocol\n\tProtocolBRSATMON       = 76  // Backroom SATNET Monitoring\n\tProtocolSUNND          = 77  // SUN ND PROTOCOL-Temporary\n\tProtocolWBMON          = 78  // WIDEBAND Monitoring\n\tProtocolWBEXPAK        = 79  // WIDEBAND EXPAK\n\tProtocolISOIP          = 80  // ISO Internet Protocol\n\tProtocolVMTP           = 81  // VMTP\n\tProtocolSECUREVMTP     = 82  // SECURE-VMTP\n\tProtocolVINES          = 83  // VINES\n\tProtocolTTP            = 84  // Transaction Transport Protocol\n\tProtocolIPTM           = 84  // Internet Protocol Traffic Manager\n\tProtocolNSFNETIGP      = 85  // NSFNET-IGP\n\tProtocolDGP            = 86  // Dissimilar Gateway Protocol\n\tProtocolTCF            = 87  // TCF\n\tProtocolEIGRP          = 88  // EIGRP\n\tProtocolOSPFIGP        = 89  // OSPFIGP\n\tProtocolSpriteRPC      = 90  // Sprite RPC Protocol\n\tProtocolLARP           = 91  // Locus Address Resolution Protocol\n\tProtocolMTP            = 92  // Multicast Transport Protocol\n\tProtocolAX25           = 93  // AX.25 Frames\n\tProtocolIPIP           = 94  // IP-within-IP Encapsulation Protocol\n\tProtocolSCCSP          = 96  // Semaphore Communications Sec. Pro.\n\tProtocolETHERIP        = 97  // Ethernet-within-IP Encapsulation\n\tProtocolENCAP          = 98  // Encapsulation Header\n\tProtocolGMTP           = 100 // GMTP\n\tProtocolIFMP           = 101 // Ipsilon Flow Management Protocol\n\tProtocolPNNI           = 102 // PNNI over IP\n\tProtocolPIM            = 103 // Protocol Independent Multicast\n\tProtocolARIS           = 104 // ARIS\n\tProtocolSCPS           = 105 // SCPS\n\tProtocolQNX            = 106 // QNX\n\tProtocolAN             = 107 // Active Networks\n\tProtocolIPComp         = 108 // IP Payload Compression Protocol\n\tProtocolSNP            = 109 // Sitara Networks Protocol\n\tProtocolCompaqPeer     = 110 // Compaq Peer Protocol\n\tProtocolIPXinIP        = 111 // IPX in IP\n\tProtocolVRRP           = 112 // Virtual Router Redundancy Protocol\n\tProtocolPGM            = 113 // PGM Reliable Transport Protocol\n\tProtocolL2TP           = 115 // Layer Two Tunneling Protocol\n\tProtocolDDX            = 116 // D-II Data Exchange (DDX)\n\tProtocolIATP           = 117 // Interactive Agent Transfer Protocol\n\tProtocolSTP            = 118 // Schedule Transfer Protocol\n\tProtocolSRP            = 119 // SpectraLink Radio Protocol\n\tProtocolUTI            = 120 // UTI\n\tProtocolSMP            = 121 // Simple Message Protocol\n\tProtocolPTP            = 123 // Performance Transparency Protocol\n\tProtocolISIS           = 124 // ISIS over IPv4\n\tProtocolFIRE           = 125 // FIRE\n\tProtocolCRTP           = 126 // Combat Radio Transport Protocol\n\tProtocolCRUDP          = 127 // Combat Radio User Datagram\n\tProtocolSSCOPMCE       = 128 // SSCOPMCE\n\tProtocolIPLT           = 129 // IPLT\n\tProtocolSPS            = 130 // Secure Packet Shield\n\tProtocolPIPE           = 131 // Private IP Encapsulation within IP\n\tProtocolSCTP           = 132 // Stream Control Transmission Protocol\n\tProtocolFC             = 133 // Fibre Channel\n\tProtocolRSVPE2EIGNORE  = 134 // RSVP-E2E-IGNORE\n\tProtocolMobilityHeader = 135 // Mobility Header\n\tProtocolUDPLite        = 136 // UDPLite\n\tProtocolMPLSinIP       = 137 // MPLS-in-IP\n\tProtocolMANET          = 138 // MANET Protocols\n\tProtocolHIP            = 139 // Host Identity Protocol\n\tProtocolShim6          = 140 // Shim6 Protocol\n\tProtocolWESP           = 141 // Wrapped Encapsulating Security Payload\n\tProtocolROHC           = 142 // Robust Header Compression\n\tProtocolReserved       = 255 // Reserved\n)\n\n// Address Family Numbers, Updated: 2018-04-02\nconst (\n\tAddrFamilyIPv4                          = 1     // IP (IP version 4)\n\tAddrFamilyIPv6                          = 2     // IP6 (IP version 6)\n\tAddrFamilyNSAP                          = 3     // NSAP\n\tAddrFamilyHDLC                          = 4     // HDLC (8-bit multidrop)\n\tAddrFamilyBBN1822                       = 5     // BBN 1822\n\tAddrFamily802                           = 6     // 802 (includes all 802 media plus Ethernet \"canonical format\")\n\tAddrFamilyE163                          = 7     // E.163\n\tAddrFamilyE164                          = 8     // E.164 (SMDS, Frame Relay, ATM)\n\tAddrFamilyF69                           = 9     // F.69 (Telex)\n\tAddrFamilyX121                          = 10    // X.121 (X.25, Frame Relay)\n\tAddrFamilyIPX                           = 11    // IPX\n\tAddrFamilyAppletalk                     = 12    // Appletalk\n\tAddrFamilyDecnetIV                      = 13    // Decnet IV\n\tAddrFamilyBanyanVines                   = 14    // Banyan Vines\n\tAddrFamilyE164withSubaddress            = 15    // E.164 with NSAP format subaddress\n\tAddrFamilyDNS                           = 16    // DNS (Domain Name System)\n\tAddrFamilyDistinguishedName             = 17    // Distinguished Name\n\tAddrFamilyASNumber                      = 18    // AS Number\n\tAddrFamilyXTPoverIPv4                   = 19    // XTP over IP version 4\n\tAddrFamilyXTPoverIPv6                   = 20    // XTP over IP version 6\n\tAddrFamilyXTPnativemodeXTP              = 21    // XTP native mode XTP\n\tAddrFamilyFibreChannelWorldWidePortName = 22    // Fibre Channel World-Wide Port Name\n\tAddrFamilyFibreChannelWorldWideNodeName = 23    // Fibre Channel World-Wide Node Name\n\tAddrFamilyGWID                          = 24    // GWID\n\tAddrFamilyL2VPN                         = 25    // AFI for L2VPN information\n\tAddrFamilyMPLSTPSectionEndpointID       = 26    // MPLS-TP Section Endpoint Identifier\n\tAddrFamilyMPLSTPLSPEndpointID           = 27    // MPLS-TP LSP Endpoint Identifier\n\tAddrFamilyMPLSTPPseudowireEndpointID    = 28    // MPLS-TP Pseudowire Endpoint Identifier\n\tAddrFamilyMTIPv4                        = 29    // MT IP: Multi-Topology IP version 4\n\tAddrFamilyMTIPv6                        = 30    // MT IPv6: Multi-Topology IP version 6\n\tAddrFamilyEIGRPCommonServiceFamily      = 16384 // EIGRP Common Service Family\n\tAddrFamilyEIGRPIPv4ServiceFamily        = 16385 // EIGRP IPv4 Service Family\n\tAddrFamilyEIGRPIPv6ServiceFamily        = 16386 // EIGRP IPv6 Service Family\n\tAddrFamilyLISPCanonicalAddressFormat    = 16387 // LISP Canonical Address Format (LCAF)\n\tAddrFamilyBGPLS                         = 16388 // BGP-LS\n\tAddrFamily48bitMAC                      = 16389 // 48-bit MAC\n\tAddrFamily64bitMAC                      = 16390 // 64-bit MAC\n\tAddrFamilyOUI                           = 16391 // OUI\n\tAddrFamilyMACFinal24bits                = 16392 // MAC/24\n\tAddrFamilyMACFinal40bits                = 16393 // MAC/40\n\tAddrFamilyIPv6Initial64bits             = 16394 // IPv6/64\n\tAddrFamilyRBridgePortID                 = 16395 // RBridge Port ID\n\tAddrFamilyTRILLNickname                 = 16396 // TRILL Nickname\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/cmsghdr.go",
    "content": "// Copyright 2017 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\npackage socket\n\nfunc (h *cmsghdr) len() int { return int(h.Len) }\nfunc (h *cmsghdr) lvl() int { return int(h.Level) }\nfunc (h *cmsghdr) typ() int { return int(h.Type) }\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go",
    "content": "// Copyright 2017 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd\n\npackage socket\n\nfunc (h *cmsghdr) set(l, lvl, typ int) {\n\th.Len = uint32(l)\n\th.Level = int32(lvl)\n\th.Type = int32(typ)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go",
    "content": "// Copyright 2017 The Go 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\n//go:build (arm || mips || mipsle || 386 || ppc) && linux\n\npackage socket\n\nfunc (h *cmsghdr) set(l, lvl, typ int) {\n\th.Len = uint32(l)\n\th.Level = int32(lvl)\n\th.Type = int32(typ)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go",
    "content": "// Copyright 2017 The Go 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\n//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux\n\npackage socket\n\nfunc (h *cmsghdr) set(l, lvl, typ int) {\n\th.Len = uint64(l)\n\th.Level = int32(lvl)\n\th.Type = int32(typ)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go",
    "content": "// Copyright 2017 The Go 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\n//go:build amd64 && solaris\n\npackage socket\n\nfunc (h *cmsghdr) set(l, lvl, typ int) {\n\th.Len = uint32(l)\n\th.Level = int32(lvl)\n\th.Type = int32(typ)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go",
    "content": "// Copyright 2017 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos\n\npackage socket\n\nfunc controlHeaderLen() int {\n\treturn 0\n}\n\nfunc controlMessageLen(dataLen int) int {\n\treturn 0\n}\n\nfunc controlMessageSpace(dataLen int) int {\n\treturn 0\n}\n\ntype cmsghdr struct{}\n\nfunc (h *cmsghdr) len() int { return 0 }\nfunc (h *cmsghdr) lvl() int { return 0 }\nfunc (h *cmsghdr) typ() int { return 0 }\n\nfunc (h *cmsghdr) set(l, lvl, typ int) {}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go",
    "content": "// Copyright 2020 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\npackage socket\n\nimport \"golang.org/x/sys/unix\"\n\nfunc controlHeaderLen() int {\n\treturn unix.CmsgLen(0)\n}\n\nfunc controlMessageLen(dataLen int) int {\n\treturn unix.CmsgLen(dataLen)\n}\n\nfunc controlMessageSpace(dataLen int) int {\n\treturn unix.CmsgSpace(dataLen)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/cmsghdr_zos_s390x.go",
    "content": "// Copyright 2020 The Go 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 socket\n\nfunc (h *cmsghdr) set(l, lvl, typ int) {\n\th.Len = int32(l)\n\th.Level = int32(lvl)\n\th.Type = int32(typ)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/complete_dontwait.go",
    "content": "// Copyright 2021 The Go 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\n//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris\n\npackage socket\n\nimport (\n\t\"syscall\"\n)\n\n// ioComplete checks the flags and result of a syscall, to be used as return\n// value in a syscall.RawConn.Read or Write callback.\nfunc ioComplete(flags int, operr error) bool {\n\tif flags&syscall.MSG_DONTWAIT != 0 {\n\t\t// Caller explicitly said don't wait, so always return immediately.\n\t\treturn true\n\t}\n\tif operr == syscall.EAGAIN || operr == syscall.EWOULDBLOCK {\n\t\t// No data available, block for I/O and try again.\n\t\treturn false\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/complete_nodontwait.go",
    "content": "// Copyright 2021 The Go 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\n//go:build aix || windows || zos\n\npackage socket\n\nimport (\n\t\"syscall\"\n)\n\n// ioComplete checks the flags and result of a syscall, to be used as return\n// value in a syscall.RawConn.Read or Write callback.\nfunc ioComplete(flags int, operr error) bool {\n\tif operr == syscall.EAGAIN || operr == syscall.EWOULDBLOCK {\n\t\t// No data available, block for I/O and try again.\n\t\treturn false\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/empty.s",
    "content": "// Copyright 2018 The Go 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\n//go:build darwin && go1.12\n\n// This exists solely so we can linkname in symbols from syscall.\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/error_unix.go",
    "content": "// Copyright 2017 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\npackage socket\n\nimport \"syscall\"\n\nvar (\n\terrEAGAIN error = syscall.EAGAIN\n\terrEINVAL error = syscall.EINVAL\n\terrENOENT error = syscall.ENOENT\n)\n\n// errnoErr returns common boxed Errno values, to prevent allocations\n// at runtime.\nfunc errnoErr(errno syscall.Errno) error {\n\tswitch errno {\n\tcase 0:\n\t\treturn nil\n\tcase syscall.EAGAIN:\n\t\treturn errEAGAIN\n\tcase syscall.EINVAL:\n\t\treturn errEINVAL\n\tcase syscall.ENOENT:\n\t\treturn errENOENT\n\t}\n\treturn errno\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/error_windows.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nimport \"syscall\"\n\nvar (\n\terrERROR_IO_PENDING error = syscall.ERROR_IO_PENDING\n\terrEINVAL           error = syscall.EINVAL\n)\n\n// errnoErr returns common boxed Errno values, to prevent allocations\n// at runtime.\nfunc errnoErr(errno syscall.Errno) error {\n\tswitch errno {\n\tcase 0:\n\t\treturn nil\n\tcase syscall.ERROR_IO_PENDING:\n\t\treturn errERROR_IO_PENDING\n\tcase syscall.EINVAL:\n\t\treturn errEINVAL\n\t}\n\treturn errno\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/iovec_32bit.go",
    "content": "// Copyright 2017 The Go 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\n//go:build (arm || mips || mipsle || 386 || ppc) && (darwin || dragonfly || freebsd || linux || netbsd || openbsd)\n\npackage socket\n\nimport \"unsafe\"\n\nfunc (v *iovec) set(b []byte) {\n\tl := len(b)\n\tif l == 0 {\n\t\treturn\n\t}\n\tv.Base = (*byte)(unsafe.Pointer(&b[0]))\n\tv.Len = uint32(l)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/iovec_64bit.go",
    "content": "// Copyright 2017 The Go 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\n//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || zos)\n\npackage socket\n\nimport \"unsafe\"\n\nfunc (v *iovec) set(b []byte) {\n\tl := len(b)\n\tif l == 0 {\n\t\treturn\n\t}\n\tv.Base = (*byte)(unsafe.Pointer(&b[0]))\n\tv.Len = uint64(l)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go",
    "content": "// Copyright 2017 The Go 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\n//go:build amd64 && solaris\n\npackage socket\n\nimport \"unsafe\"\n\nfunc (v *iovec) set(b []byte) {\n\tl := len(b)\n\tif l == 0 {\n\t\treturn\n\t}\n\tv.Base = (*int8)(unsafe.Pointer(&b[0]))\n\tv.Len = uint64(l)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/iovec_stub.go",
    "content": "// Copyright 2017 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos\n\npackage socket\n\ntype iovec struct{}\n\nfunc (v *iovec) set(b []byte) {}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go",
    "content": "// Copyright 2017 The Go 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\n//go:build !aix && !linux && !netbsd\n\npackage socket\n\nimport \"net\"\n\ntype mmsghdr struct{}\n\ntype mmsghdrs []mmsghdr\n\nfunc (hs mmsghdrs) pack(ms []Message, parseFn func([]byte, string) (net.Addr, error), marshalFn func(net.Addr) []byte) error {\n\treturn nil\n}\n\nfunc (hs mmsghdrs) unpack(ms []Message, parseFn func([]byte, string) (net.Addr, error), hint string) error {\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go",
    "content": "// Copyright 2017 The Go 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\n//go:build aix || linux || netbsd\n\npackage socket\n\nimport (\n\t\"net\"\n\t\"os\"\n\t\"sync\"\n\t\"syscall\"\n)\n\ntype mmsghdrs []mmsghdr\n\nfunc (hs mmsghdrs) unpack(ms []Message, parseFn func([]byte, string) (net.Addr, error), hint string) error {\n\tfor i := range hs {\n\t\tms[i].N = int(hs[i].Len)\n\t\tms[i].NN = hs[i].Hdr.controllen()\n\t\tms[i].Flags = hs[i].Hdr.flags()\n\t\tif parseFn != nil {\n\t\t\tvar err error\n\t\t\tms[i].Addr, err = parseFn(hs[i].Hdr.name(), hint)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// mmsghdrsPacker packs Message-slices into mmsghdrs (re-)using pre-allocated buffers.\ntype mmsghdrsPacker struct {\n\t// hs are the pre-allocated mmsghdrs.\n\ths mmsghdrs\n\t// sockaddrs is the pre-allocated buffer for the Hdr.Name buffers.\n\t// We use one large buffer for all messages and slice it up.\n\tsockaddrs []byte\n\t// vs are the pre-allocated iovecs.\n\t// We allocate one large buffer for all messages and slice it up. This allows to reuse the buffer\n\t// if the number of buffers per message is distributed differently between calls.\n\tvs []iovec\n}\n\nfunc (p *mmsghdrsPacker) prepare(ms []Message) {\n\tn := len(ms)\n\tif n <= cap(p.hs) {\n\t\tp.hs = p.hs[:n]\n\t} else {\n\t\tp.hs = make(mmsghdrs, n)\n\t}\n\tif n*sizeofSockaddrInet6 <= cap(p.sockaddrs) {\n\t\tp.sockaddrs = p.sockaddrs[:n*sizeofSockaddrInet6]\n\t} else {\n\t\tp.sockaddrs = make([]byte, n*sizeofSockaddrInet6)\n\t}\n\n\tnb := 0\n\tfor _, m := range ms {\n\t\tnb += len(m.Buffers)\n\t}\n\tif nb <= cap(p.vs) {\n\t\tp.vs = p.vs[:nb]\n\t} else {\n\t\tp.vs = make([]iovec, nb)\n\t}\n}\n\nfunc (p *mmsghdrsPacker) pack(ms []Message, parseFn func([]byte, string) (net.Addr, error), marshalFn func(net.Addr, []byte) int) mmsghdrs {\n\tp.prepare(ms)\n\ths := p.hs\n\tvsRest := p.vs\n\tsaRest := p.sockaddrs\n\tfor i := range hs {\n\t\tnvs := len(ms[i].Buffers)\n\t\tvs := vsRest[:nvs]\n\t\tvsRest = vsRest[nvs:]\n\n\t\tvar sa []byte\n\t\tif parseFn != nil {\n\t\t\tsa = saRest[:sizeofSockaddrInet6]\n\t\t\tsaRest = saRest[sizeofSockaddrInet6:]\n\t\t} else if marshalFn != nil {\n\t\t\tn := marshalFn(ms[i].Addr, saRest)\n\t\t\tif n > 0 {\n\t\t\t\tsa = saRest[:n]\n\t\t\t\tsaRest = saRest[n:]\n\t\t\t}\n\t\t}\n\t\ths[i].Hdr.pack(vs, ms[i].Buffers, ms[i].OOB, sa)\n\t}\n\treturn hs\n}\n\n// syscaller is a helper to invoke recvmmsg and sendmmsg via the RawConn.Read/Write interface.\n// It is reusable, to amortize the overhead of allocating a closure for the function passed to\n// RawConn.Read/Write.\ntype syscaller struct {\n\tn     int\n\toperr error\n\ths    mmsghdrs\n\tflags int\n\n\tboundRecvmmsgF func(uintptr) bool\n\tboundSendmmsgF func(uintptr) bool\n}\n\nfunc (r *syscaller) init() {\n\tr.boundRecvmmsgF = r.recvmmsgF\n\tr.boundSendmmsgF = r.sendmmsgF\n}\n\nfunc (r *syscaller) recvmmsg(c syscall.RawConn, hs mmsghdrs, flags int) (int, error) {\n\tr.n = 0\n\tr.operr = nil\n\tr.hs = hs\n\tr.flags = flags\n\tif err := c.Read(r.boundRecvmmsgF); err != nil {\n\t\treturn r.n, err\n\t}\n\tif r.operr != nil {\n\t\treturn r.n, os.NewSyscallError(\"recvmmsg\", r.operr)\n\t}\n\treturn r.n, nil\n}\n\nfunc (r *syscaller) recvmmsgF(s uintptr) bool {\n\tr.n, r.operr = recvmmsg(s, r.hs, r.flags)\n\treturn ioComplete(r.flags, r.operr)\n}\n\nfunc (r *syscaller) sendmmsg(c syscall.RawConn, hs mmsghdrs, flags int) (int, error) {\n\tr.n = 0\n\tr.operr = nil\n\tr.hs = hs\n\tr.flags = flags\n\tif err := c.Write(r.boundSendmmsgF); err != nil {\n\t\treturn r.n, err\n\t}\n\tif r.operr != nil {\n\t\treturn r.n, os.NewSyscallError(\"sendmmsg\", r.operr)\n\t}\n\treturn r.n, nil\n}\n\nfunc (r *syscaller) sendmmsgF(s uintptr) bool {\n\tr.n, r.operr = sendmmsg(s, r.hs, r.flags)\n\treturn ioComplete(r.flags, r.operr)\n}\n\n// mmsgTmps holds reusable temporary helpers for recvmmsg and sendmmsg.\ntype mmsgTmps struct {\n\tpacker    mmsghdrsPacker\n\tsyscaller syscaller\n}\n\nvar defaultMmsgTmpsPool = mmsgTmpsPool{\n\tp: sync.Pool{\n\t\tNew: func() interface{} {\n\t\t\ttmps := new(mmsgTmps)\n\t\t\ttmps.syscaller.init()\n\t\t\treturn tmps\n\t\t},\n\t},\n}\n\ntype mmsgTmpsPool struct {\n\tp sync.Pool\n}\n\nfunc (p *mmsgTmpsPool) Get() *mmsgTmps {\n\tm := p.p.Get().(*mmsgTmps)\n\t// Clear fields up to the len (not the cap) of the slice,\n\t// assuming that the previous caller only used that many elements.\n\tfor i := range m.packer.sockaddrs {\n\t\tm.packer.sockaddrs[i] = 0\n\t}\n\tm.packer.sockaddrs = m.packer.sockaddrs[:0]\n\tfor i := range m.packer.vs {\n\t\tm.packer.vs[i] = iovec{}\n\t}\n\tm.packer.vs = m.packer.vs[:0]\n\tfor i := range m.packer.hs {\n\t\tm.packer.hs[i].Len = 0\n\t\tm.packer.hs[i].Hdr = msghdr{}\n\t}\n\tm.packer.hs = m.packer.hs[:0]\n\treturn m\n}\n\nfunc (p *mmsgTmpsPool) Put(tmps *mmsgTmps) {\n\tp.p.Put(tmps)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/msghdr_bsd.go",
    "content": "// Copyright 2017 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd\n\npackage socket\n\nimport \"unsafe\"\n\nfunc (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {\n\tfor i := range vs {\n\t\tvs[i].set(bs[i])\n\t}\n\th.setIov(vs)\n\tif len(oob) > 0 {\n\t\th.Control = (*byte)(unsafe.Pointer(&oob[0]))\n\t\th.Controllen = uint32(len(oob))\n\t}\n\tif sa != nil {\n\t\th.Name = (*byte)(unsafe.Pointer(&sa[0]))\n\t\th.Namelen = uint32(len(sa))\n\t}\n}\n\nfunc (h *msghdr) name() []byte {\n\tif h.Name != nil && h.Namelen > 0 {\n\t\treturn (*[sizeofSockaddrInet6]byte)(unsafe.Pointer(h.Name))[:h.Namelen]\n\t}\n\treturn nil\n}\n\nfunc (h *msghdr) controllen() int {\n\treturn int(h.Controllen)\n}\n\nfunc (h *msghdr) flags() int {\n\treturn int(h.Flags)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go",
    "content": "// Copyright 2017 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || netbsd\n\npackage socket\n\nfunc (h *msghdr) setIov(vs []iovec) {\n\tl := len(vs)\n\tif l == 0 {\n\t\treturn\n\t}\n\th.Iov = &vs[0]\n\th.Iovlen = int32(l)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/msghdr_linux.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nimport \"unsafe\"\n\nfunc (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {\n\tfor i := range vs {\n\t\tvs[i].set(bs[i])\n\t}\n\th.setIov(vs)\n\tif len(oob) > 0 {\n\t\th.setControl(oob)\n\t}\n\tif sa != nil {\n\t\th.Name = (*byte)(unsafe.Pointer(&sa[0]))\n\t\th.Namelen = uint32(len(sa))\n\t}\n}\n\nfunc (h *msghdr) name() []byte {\n\tif h.Name != nil && h.Namelen > 0 {\n\t\treturn (*[sizeofSockaddrInet6]byte)(unsafe.Pointer(h.Name))[:h.Namelen]\n\t}\n\treturn nil\n}\n\nfunc (h *msghdr) controllen() int {\n\treturn int(h.Controllen)\n}\n\nfunc (h *msghdr) flags() int {\n\treturn int(h.Flags)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go",
    "content": "// Copyright 2017 The Go 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\n//go:build (arm || mips || mipsle || 386 || ppc) && linux\n\npackage socket\n\nimport \"unsafe\"\n\nfunc (h *msghdr) setIov(vs []iovec) {\n\tl := len(vs)\n\tif l == 0 {\n\t\treturn\n\t}\n\th.Iov = &vs[0]\n\th.Iovlen = uint32(l)\n}\n\nfunc (h *msghdr) setControl(b []byte) {\n\th.Control = (*byte)(unsafe.Pointer(&b[0]))\n\th.Controllen = uint32(len(b))\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go",
    "content": "// Copyright 2017 The Go 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\n//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux\n\npackage socket\n\nimport \"unsafe\"\n\nfunc (h *msghdr) setIov(vs []iovec) {\n\tl := len(vs)\n\tif l == 0 {\n\t\treturn\n\t}\n\th.Iov = &vs[0]\n\th.Iovlen = uint64(l)\n}\n\nfunc (h *msghdr) setControl(b []byte) {\n\th.Control = (*byte)(unsafe.Pointer(&b[0]))\n\th.Controllen = uint64(len(b))\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/msghdr_openbsd.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nfunc (h *msghdr) setIov(vs []iovec) {\n\tl := len(vs)\n\tif l == 0 {\n\t\treturn\n\t}\n\th.Iov = &vs[0]\n\th.Iovlen = uint32(l)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go",
    "content": "// Copyright 2017 The Go 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\n//go:build amd64 && solaris\n\npackage socket\n\nimport \"unsafe\"\n\nfunc (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {\n\tfor i := range vs {\n\t\tvs[i].set(bs[i])\n\t}\n\tif len(vs) > 0 {\n\t\th.Iov = &vs[0]\n\t\th.Iovlen = int32(len(vs))\n\t}\n\tif len(oob) > 0 {\n\t\th.Accrights = (*int8)(unsafe.Pointer(&oob[0]))\n\t\th.Accrightslen = int32(len(oob))\n\t}\n\tif sa != nil {\n\t\th.Name = (*byte)(unsafe.Pointer(&sa[0]))\n\t\th.Namelen = uint32(len(sa))\n\t}\n}\n\nfunc (h *msghdr) controllen() int {\n\treturn int(h.Accrightslen)\n}\n\nfunc (h *msghdr) flags() int {\n\treturn int(NativeEndian.Uint32(h.Pad_cgo_2[:]))\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/msghdr_stub.go",
    "content": "// Copyright 2017 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos\n\npackage socket\n\ntype msghdr struct{}\n\nfunc (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {}\nfunc (h *msghdr) name() []byte                                        { return nil }\nfunc (h *msghdr) controllen() int                                     { return 0 }\nfunc (h *msghdr) flags() int                                          { return 0 }\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go",
    "content": "// Copyright 2020 The Go 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\n//go:build s390x && zos\n\npackage socket\n\nimport \"unsafe\"\n\nfunc (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {\n\tfor i := range vs {\n\t\tvs[i].set(bs[i])\n\t}\n\tif len(vs) > 0 {\n\t\th.Iov = &vs[0]\n\t\th.Iovlen = int32(len(vs))\n\t}\n\tif len(oob) > 0 {\n\t\th.Control = (*byte)(unsafe.Pointer(&oob[0]))\n\t\th.Controllen = uint32(len(oob))\n\t}\n\tif sa != nil {\n\t\th.Name = (*byte)(unsafe.Pointer(&sa[0]))\n\t\th.Namelen = uint32(len(sa))\n\t}\n}\n\nfunc (h *msghdr) controllen() int {\n\treturn int(h.Controllen)\n}\n\nfunc (h *msghdr) flags() int {\n\treturn int(h.Flags)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/norace.go",
    "content": "// Copyright 2019 The Go 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\n//go:build !race\n\npackage socket\n\nfunc (m *Message) raceRead() {\n}\nfunc (m *Message) raceWrite() {\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/race.go",
    "content": "// Copyright 2019 The Go 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\n//go:build race\n\npackage socket\n\nimport (\n\t\"runtime\"\n\t\"unsafe\"\n)\n\n// This package reads and writes the Message buffers using a\n// direct system call, which the race detector can't see.\n// These functions tell the race detector what is going on during the syscall.\n\nfunc (m *Message) raceRead() {\n\tfor _, b := range m.Buffers {\n\t\tif len(b) > 0 {\n\t\t\truntime.RaceReadRange(unsafe.Pointer(&b[0]), len(b))\n\t\t}\n\t}\n\tif b := m.OOB; len(b) > 0 {\n\t\truntime.RaceReadRange(unsafe.Pointer(&b[0]), len(b))\n\t}\n}\nfunc (m *Message) raceWrite() {\n\tfor _, b := range m.Buffers {\n\t\tif len(b) > 0 {\n\t\t\truntime.RaceWriteRange(unsafe.Pointer(&b[0]), len(b))\n\t\t}\n\t}\n\tif b := m.OOB; len(b) > 0 {\n\t\truntime.RaceWriteRange(unsafe.Pointer(&b[0]), len(b))\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/rawconn.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nimport (\n\t\"errors\"\n\t\"net\"\n\t\"os\"\n\t\"syscall\"\n)\n\n// A Conn represents a raw connection.\ntype Conn struct {\n\tnetwork string\n\tc       syscall.RawConn\n}\n\n// tcpConn is an interface implemented by net.TCPConn.\n// It can be used for interface assertions to check if a net.Conn is a TCP connection.\ntype tcpConn interface {\n\tSyscallConn() (syscall.RawConn, error)\n\tSetLinger(int) error\n}\n\nvar _ tcpConn = (*net.TCPConn)(nil)\n\n// udpConn is an interface implemented by net.UDPConn.\n// It can be used for interface assertions to check if a net.Conn is a UDP connection.\ntype udpConn interface {\n\tSyscallConn() (syscall.RawConn, error)\n\tReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error)\n}\n\nvar _ udpConn = (*net.UDPConn)(nil)\n\n// ipConn is an interface implemented by net.IPConn.\n// It can be used for interface assertions to check if a net.Conn is an IP connection.\ntype ipConn interface {\n\tSyscallConn() (syscall.RawConn, error)\n\tReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *net.IPAddr, err error)\n}\n\nvar _ ipConn = (*net.IPConn)(nil)\n\n// NewConn returns a new raw connection.\nfunc NewConn(c net.Conn) (*Conn, error) {\n\tvar err error\n\tvar cc Conn\n\tswitch c := c.(type) {\n\tcase tcpConn:\n\t\tcc.network = \"tcp\"\n\t\tcc.c, err = c.SyscallConn()\n\tcase udpConn:\n\t\tcc.network = \"udp\"\n\t\tcc.c, err = c.SyscallConn()\n\tcase ipConn:\n\t\tcc.network = \"ip\"\n\t\tcc.c, err = c.SyscallConn()\n\tdefault:\n\t\treturn nil, errors.New(\"unknown connection type\")\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &cc, nil\n}\n\nfunc (o *Option) get(c *Conn, b []byte) (int, error) {\n\tvar operr error\n\tvar n int\n\tfn := func(s uintptr) {\n\t\tn, operr = getsockopt(s, o.Level, o.Name, b)\n\t}\n\tif err := c.c.Control(fn); err != nil {\n\t\treturn 0, err\n\t}\n\treturn n, os.NewSyscallError(\"getsockopt\", operr)\n}\n\nfunc (o *Option) set(c *Conn, b []byte) error {\n\tvar operr error\n\tfn := func(s uintptr) {\n\t\toperr = setsockopt(s, o.Level, o.Name, b)\n\t}\n\tif err := c.c.Control(fn); err != nil {\n\t\treturn err\n\t}\n\treturn os.NewSyscallError(\"setsockopt\", operr)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go",
    "content": "// Copyright 2017 The Go 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\n//go:build linux\n\npackage socket\n\nimport (\n\t\"net\"\n)\n\nfunc (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {\n\tfor i := range ms {\n\t\tms[i].raceWrite()\n\t}\n\ttmps := defaultMmsgTmpsPool.Get()\n\tdefer defaultMmsgTmpsPool.Put(tmps)\n\tvar parseFn func([]byte, string) (net.Addr, error)\n\tif c.network != \"tcp\" {\n\t\tparseFn = parseInetAddr\n\t}\n\ths := tmps.packer.pack(ms, parseFn, nil)\n\tn, err := tmps.syscaller.recvmmsg(c.c, hs, flags)\n\tif err != nil {\n\t\treturn n, err\n\t}\n\tif err := hs[:n].unpack(ms[:n], parseFn, c.network); err != nil {\n\t\treturn n, err\n\t}\n\treturn n, nil\n}\n\nfunc (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {\n\tfor i := range ms {\n\t\tms[i].raceRead()\n\t}\n\ttmps := defaultMmsgTmpsPool.Get()\n\tdefer defaultMmsgTmpsPool.Put(tmps)\n\tvar marshalFn func(net.Addr, []byte) int\n\tif c.network != \"tcp\" {\n\t\tmarshalFn = marshalInetAddr\n\t}\n\ths := tmps.packer.pack(ms, nil, marshalFn)\n\tn, err := tmps.syscaller.sendmmsg(c.c, hs, flags)\n\tif err != nil {\n\t\treturn n, err\n\t}\n\tif err := hs[:n].unpack(ms[:n], nil, \"\"); err != nil {\n\t\treturn n, err\n\t}\n\treturn n, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/rawconn_msg.go",
    "content": "// Copyright 2017 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos\n\npackage socket\n\nimport (\n\t\"net\"\n\t\"os\"\n)\n\nfunc (c *Conn) recvMsg(m *Message, flags int) error {\n\tm.raceWrite()\n\tvar (\n\t\toperr     error\n\t\tn         int\n\t\toobn      int\n\t\trecvflags int\n\t\tfrom      net.Addr\n\t)\n\tfn := func(s uintptr) bool {\n\t\tn, oobn, recvflags, from, operr = recvmsg(s, m.Buffers, m.OOB, flags, c.network)\n\t\treturn ioComplete(flags, operr)\n\t}\n\tif err := c.c.Read(fn); err != nil {\n\t\treturn err\n\t}\n\tif operr != nil {\n\t\treturn os.NewSyscallError(\"recvmsg\", operr)\n\t}\n\tm.Addr = from\n\tm.N = n\n\tm.NN = oobn\n\tm.Flags = recvflags\n\treturn nil\n}\n\nfunc (c *Conn) sendMsg(m *Message, flags int) error {\n\tm.raceRead()\n\tvar (\n\t\toperr error\n\t\tn     int\n\t)\n\tfn := func(s uintptr) bool {\n\t\tn, operr = sendmsg(s, m.Buffers, m.OOB, m.Addr, flags)\n\t\treturn ioComplete(flags, operr)\n\t}\n\tif err := c.c.Write(fn); err != nil {\n\t\treturn err\n\t}\n\tif operr != nil {\n\t\treturn os.NewSyscallError(\"sendmsg\", operr)\n\t}\n\tm.N = n\n\tm.NN = len(m.OOB)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go",
    "content": "// Copyright 2017 The Go 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\n//go:build !linux\n\npackage socket\n\nfunc (c *Conn) recvMsgs(ms []Message, flags int) (int, error) {\n\treturn 0, errNotImplemented\n}\n\nfunc (c *Conn) sendMsgs(ms []Message, flags int) (int, error) {\n\treturn 0, errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go",
    "content": "// Copyright 2017 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos\n\npackage socket\n\nfunc (c *Conn) recvMsg(m *Message, flags int) error {\n\treturn errNotImplemented\n}\n\nfunc (c *Conn) sendMsg(m *Message, flags int) error {\n\treturn errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/socket.go",
    "content": "// Copyright 2017 The Go 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\n// Package socket provides a portable interface for socket system\n// calls.\npackage socket // import \"golang.org/x/net/internal/socket\"\n\nimport (\n\t\"errors\"\n\t\"net\"\n\t\"runtime\"\n\t\"unsafe\"\n)\n\nvar errNotImplemented = errors.New(\"not implemented on \" + runtime.GOOS + \"/\" + runtime.GOARCH)\n\n// An Option represents a sticky socket option.\ntype Option struct {\n\tLevel int // level\n\tName  int // name; must be equal or greater than 1\n\tLen   int // length of value in bytes; must be equal or greater than 1\n}\n\n// Get reads a value for the option from the kernel.\n// It returns the number of bytes written into b.\nfunc (o *Option) Get(c *Conn, b []byte) (int, error) {\n\tif o.Name < 1 || o.Len < 1 {\n\t\treturn 0, errors.New(\"invalid option\")\n\t}\n\tif len(b) < o.Len {\n\t\treturn 0, errors.New(\"short buffer\")\n\t}\n\treturn o.get(c, b)\n}\n\n// GetInt returns an integer value for the option.\n//\n// The Len field of Option must be either 1 or 4.\nfunc (o *Option) GetInt(c *Conn) (int, error) {\n\tif o.Len != 1 && o.Len != 4 {\n\t\treturn 0, errors.New(\"invalid option\")\n\t}\n\tvar b []byte\n\tvar bb [4]byte\n\tif o.Len == 1 {\n\t\tb = bb[:1]\n\t} else {\n\t\tb = bb[:4]\n\t}\n\tn, err := o.get(c, b)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif n != o.Len {\n\t\treturn 0, errors.New(\"invalid option length\")\n\t}\n\tif o.Len == 1 {\n\t\treturn int(b[0]), nil\n\t}\n\treturn int(NativeEndian.Uint32(b[:4])), nil\n}\n\n// Set writes the option and value to the kernel.\nfunc (o *Option) Set(c *Conn, b []byte) error {\n\tif o.Name < 1 || o.Len < 1 {\n\t\treturn errors.New(\"invalid option\")\n\t}\n\tif len(b) < o.Len {\n\t\treturn errors.New(\"short buffer\")\n\t}\n\treturn o.set(c, b)\n}\n\n// SetInt writes the option and value to the kernel.\n//\n// The Len field of Option must be either 1 or 4.\nfunc (o *Option) SetInt(c *Conn, v int) error {\n\tif o.Len != 1 && o.Len != 4 {\n\t\treturn errors.New(\"invalid option\")\n\t}\n\tvar b []byte\n\tif o.Len == 1 {\n\t\tb = []byte{byte(v)}\n\t} else {\n\t\tvar bb [4]byte\n\t\tNativeEndian.PutUint32(bb[:o.Len], uint32(v))\n\t\tb = bb[:4]\n\t}\n\treturn o.set(c, b)\n}\n\n// ControlMessageSpace returns the whole length of control message.\nfunc ControlMessageSpace(dataLen int) int {\n\treturn controlMessageSpace(dataLen)\n}\n\n// A ControlMessage represents the head message in a stream of control\n// messages.\n//\n// A control message comprises of a header, data and a few padding\n// fields to conform to the interface to the kernel.\n//\n// See RFC 3542 for further information.\ntype ControlMessage []byte\n\n// Data returns the data field of the control message at the head on\n// m.\nfunc (m ControlMessage) Data(dataLen int) []byte {\n\tl := controlHeaderLen()\n\tif len(m) < l || len(m) < l+dataLen {\n\t\treturn nil\n\t}\n\treturn m[l : l+dataLen]\n}\n\n// Next returns the control message at the next on m.\n//\n// Next works only for standard control messages.\nfunc (m ControlMessage) Next(dataLen int) ControlMessage {\n\tl := ControlMessageSpace(dataLen)\n\tif len(m) < l {\n\t\treturn nil\n\t}\n\treturn m[l:]\n}\n\n// MarshalHeader marshals the header fields of the control message at\n// the head on m.\nfunc (m ControlMessage) MarshalHeader(lvl, typ, dataLen int) error {\n\tif len(m) < controlHeaderLen() {\n\t\treturn errors.New(\"short message\")\n\t}\n\th := (*cmsghdr)(unsafe.Pointer(&m[0]))\n\th.set(controlMessageLen(dataLen), lvl, typ)\n\treturn nil\n}\n\n// ParseHeader parses and returns the header fields of the control\n// message at the head on m.\nfunc (m ControlMessage) ParseHeader() (lvl, typ, dataLen int, err error) {\n\tl := controlHeaderLen()\n\tif len(m) < l {\n\t\treturn 0, 0, 0, errors.New(\"short message\")\n\t}\n\th := (*cmsghdr)(unsafe.Pointer(&m[0]))\n\treturn h.lvl(), h.typ(), int(uint64(h.len()) - uint64(l)), nil\n}\n\n// Marshal marshals the control message at the head on m, and returns\n// the next control message.\nfunc (m ControlMessage) Marshal(lvl, typ int, data []byte) (ControlMessage, error) {\n\tl := len(data)\n\tif len(m) < ControlMessageSpace(l) {\n\t\treturn nil, errors.New(\"short message\")\n\t}\n\th := (*cmsghdr)(unsafe.Pointer(&m[0]))\n\th.set(controlMessageLen(l), lvl, typ)\n\tif l > 0 {\n\t\tcopy(m.Data(l), data)\n\t}\n\treturn m.Next(l), nil\n}\n\n// Parse parses m as a single or multiple control messages.\n//\n// Parse works for both standard and compatible messages.\nfunc (m ControlMessage) Parse() ([]ControlMessage, error) {\n\tvar ms []ControlMessage\n\tfor len(m) >= controlHeaderLen() {\n\t\th := (*cmsghdr)(unsafe.Pointer(&m[0]))\n\t\tl := h.len()\n\t\tif l <= 0 {\n\t\t\treturn nil, errors.New(\"invalid header length\")\n\t\t}\n\t\tif uint64(l) < uint64(controlHeaderLen()) {\n\t\t\treturn nil, errors.New(\"invalid message length\")\n\t\t}\n\t\tif uint64(l) > uint64(len(m)) {\n\t\t\treturn nil, errors.New(\"short buffer\")\n\t\t}\n\t\t// On message reception:\n\t\t//\n\t\t// |<- ControlMessageSpace --------------->|\n\t\t// |<- controlMessageLen ---------->|      |\n\t\t// |<- controlHeaderLen ->|         |      |\n\t\t// +---------------+------+---------+------+\n\t\t// |    Header     | PadH |  Data   | PadD |\n\t\t// +---------------+------+---------+------+\n\t\t//\n\t\t// On compatible message reception:\n\t\t//\n\t\t// | ... |<- controlMessageLen ----------->|\n\t\t// | ... |<- controlHeaderLen ->|          |\n\t\t// +-----+---------------+------+----------+\n\t\t// | ... |    Header     | PadH |   Data   |\n\t\t// +-----+---------------+------+----------+\n\t\tms = append(ms, ControlMessage(m[:l]))\n\t\tll := l - controlHeaderLen()\n\t\tif len(m) >= ControlMessageSpace(ll) {\n\t\t\tm = m[ControlMessageSpace(ll):]\n\t\t} else {\n\t\t\tm = m[controlMessageLen(ll):]\n\t\t}\n\t}\n\treturn ms, nil\n}\n\n// NewControlMessage returns a new stream of control messages.\nfunc NewControlMessage(dataLen []int) ControlMessage {\n\tvar l int\n\tfor i := range dataLen {\n\t\tl += ControlMessageSpace(dataLen[i])\n\t}\n\treturn make([]byte, l)\n}\n\n// A Message represents an IO message.\ntype Message struct {\n\t// When writing, the Buffers field must contain at least one\n\t// byte to write.\n\t// When reading, the Buffers field will always contain a byte\n\t// to read.\n\tBuffers [][]byte\n\n\t// OOB contains protocol-specific control or miscellaneous\n\t// ancillary data known as out-of-band data.\n\tOOB []byte\n\n\t// Addr specifies a destination address when writing.\n\t// It can be nil when the underlying protocol of the raw\n\t// connection uses connection-oriented communication.\n\t// After a successful read, it may contain the source address\n\t// on the received packet.\n\tAddr net.Addr\n\n\tN     int // # of bytes read or written from/to Buffers\n\tNN    int // # of bytes read or written from/to OOB\n\tFlags int // protocol-specific information on the received message\n}\n\n// RecvMsg wraps recvmsg system call.\n//\n// The provided flags is a set of platform-dependent flags, such as\n// syscall.MSG_PEEK.\nfunc (c *Conn) RecvMsg(m *Message, flags int) error {\n\treturn c.recvMsg(m, flags)\n}\n\n// SendMsg wraps sendmsg system call.\n//\n// The provided flags is a set of platform-dependent flags, such as\n// syscall.MSG_DONTROUTE.\nfunc (c *Conn) SendMsg(m *Message, flags int) error {\n\treturn c.sendMsg(m, flags)\n}\n\n// RecvMsgs wraps recvmmsg system call.\n//\n// It returns the number of processed messages.\n//\n// The provided flags is a set of platform-dependent flags, such as\n// syscall.MSG_PEEK.\n//\n// Only Linux supports this.\nfunc (c *Conn) RecvMsgs(ms []Message, flags int) (int, error) {\n\treturn c.recvMsgs(ms, flags)\n}\n\n// SendMsgs wraps sendmmsg system call.\n//\n// It returns the number of processed messages.\n//\n// The provided flags is a set of platform-dependent flags, such as\n// syscall.MSG_DONTROUTE.\n//\n// Only Linux supports this.\nfunc (c *Conn) SendMsgs(ms []Message, flags int) (int, error) {\n\treturn c.sendMsgs(ms, flags)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nimport (\n\t\"encoding/binary\"\n\t\"unsafe\"\n)\n\n// NativeEndian is the machine native endian implementation of ByteOrder.\nvar NativeEndian binary.ByteOrder\n\nfunc init() {\n\ti := uint32(1)\n\tb := (*[4]byte)(unsafe.Pointer(&i))\n\tif b[0] == 1 {\n\t\tNativeEndian = binary.LittleEndian\n\t} else {\n\t\tNativeEndian = binary.BigEndian\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_bsd.go",
    "content": "// Copyright 2017 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris\n\npackage socket\n\nfunc recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {\n\treturn 0, errNotImplemented\n}\n\nfunc sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {\n\treturn 0, errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_const_unix.go",
    "content": "// Copyright 2019 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\npackage socket\n\nimport \"golang.org/x/sys/unix\"\n\nconst (\n\tsysAF_UNSPEC = unix.AF_UNSPEC\n\tsysAF_INET   = unix.AF_INET\n\tsysAF_INET6  = unix.AF_INET6\n\n\tsysSOCK_RAW = unix.SOCK_RAW\n\n\tsizeofSockaddrInet4 = unix.SizeofSockaddrInet4\n\tsizeofSockaddrInet6 = unix.SizeofSockaddrInet6\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_linux.go",
    "content": "// Copyright 2017 The Go 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\n//go:build linux && !s390x && !386\n\npackage socket\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nfunc recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {\n\tn, _, errno := syscall.Syscall6(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)\n\treturn int(n), errnoErr(errno)\n}\n\nfunc sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {\n\tn, _, errno := syscall.Syscall6(sysSENDMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)\n\treturn int(n), errnoErr(errno)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_linux_386.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nconst (\n\tsysRECVMMSG = 0x13\n\tsysSENDMMSG = 0x14\n)\n\nfunc socketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)\nfunc rawsocketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)\n\nfunc recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {\n\tn, errno := socketcall(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)\n\treturn int(n), errnoErr(errno)\n}\n\nfunc sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {\n\tn, errno := socketcall(sysSENDMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)\n\treturn int(n), errnoErr(errno)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_linux_386.s",
    "content": "// Copyright 2014 The Go 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\n#include \"textflag.h\"\n\nTEXT\t·socketcall(SB),NOSPLIT,$0-36\n\tJMP\tsyscall·socketcall(SB)\n\nTEXT\t·rawsocketcall(SB),NOSPLIT,$0-36\n\tJMP\tsyscall·rawsocketcall(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_linux_amd64.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nconst (\n\tsysRECVMMSG = 0x12b\n\tsysSENDMMSG = 0x133\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_linux_arm.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nconst (\n\tsysRECVMMSG = 0x16d\n\tsysSENDMMSG = 0x176\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_linux_arm64.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nconst (\n\tsysRECVMMSG = 0xf3\n\tsysSENDMMSG = 0x10d\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_linux_loong64.go",
    "content": "// Copyright 2021 The Go 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\n//go:build loong64\n\npackage socket\n\nconst (\n\tsysRECVMMSG = 0xf3\n\tsysSENDMMSG = 0x10d\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_linux_mips.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nconst (\n\tsysRECVMMSG = 0x10ef\n\tsysSENDMMSG = 0x10f7\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_linux_mips64.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nconst (\n\tsysRECVMMSG = 0x14ae\n\tsysSENDMMSG = 0x14b6\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_linux_mips64le.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nconst (\n\tsysRECVMMSG = 0x14ae\n\tsysSENDMMSG = 0x14b6\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_linux_mipsle.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nconst (\n\tsysRECVMMSG = 0x10ef\n\tsysSENDMMSG = 0x10f7\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_linux_ppc.go",
    "content": "// Copyright 2021 The Go 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 socket\n\nconst (\n\tsysRECVMMSG = 0x157\n\tsysSENDMMSG = 0x15d\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_linux_ppc64.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nconst (\n\tsysRECVMMSG = 0x157\n\tsysSENDMMSG = 0x15d\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_linux_ppc64le.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nconst (\n\tsysRECVMMSG = 0x157\n\tsysSENDMMSG = 0x15d\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go",
    "content": "// Copyright 2019 The Go 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\n//go:build riscv64\n\npackage socket\n\nconst (\n\tsysRECVMMSG = 0xf3\n\tsysSENDMMSG = 0x10d\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nconst (\n\tsysRECVMMSG = 0x13\n\tsysSENDMMSG = 0x14\n)\n\nfunc socketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)\nfunc rawsocketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)\n\nfunc recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {\n\tn, errno := socketcall(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)\n\treturn int(n), errnoErr(errno)\n}\n\nfunc sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {\n\tn, errno := socketcall(sysSENDMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)\n\treturn int(n), errnoErr(errno)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_linux_s390x.s",
    "content": "// Copyright 2017 The Go 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\n#include \"textflag.h\"\n\nTEXT\t·socketcall(SB),NOSPLIT,$0-72\n\tJMP\tsyscall·socketcall(SB)\n\nTEXT\t·rawsocketcall(SB),NOSPLIT,$0-72\n\tJMP\tsyscall·rawsocketcall(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_netbsd.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nconst (\n\tsysRECVMMSG = 0x1db\n\tsysSENDMMSG = 0x1dc\n)\n\nfunc recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {\n\tn, _, errno := syscall.Syscall6(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)\n\treturn int(n), errnoErr(errno)\n}\n\nfunc sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {\n\tn, _, errno := syscall.Syscall6(sysSENDMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0)\n\treturn int(n), errnoErr(errno)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_posix.go",
    "content": "// Copyright 2017 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos\n\npackage socket\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"net\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"sync\"\n\t\"time\"\n)\n\n// marshalInetAddr writes a in sockaddr format into the buffer b.\n// The buffer must be sufficiently large (sizeofSockaddrInet4/6).\n// Returns the number of bytes written.\nfunc marshalInetAddr(a net.Addr, b []byte) int {\n\tswitch a := a.(type) {\n\tcase *net.TCPAddr:\n\t\treturn marshalSockaddr(a.IP, a.Port, a.Zone, b)\n\tcase *net.UDPAddr:\n\t\treturn marshalSockaddr(a.IP, a.Port, a.Zone, b)\n\tcase *net.IPAddr:\n\t\treturn marshalSockaddr(a.IP, 0, a.Zone, b)\n\tdefault:\n\t\treturn 0\n\t}\n}\n\nfunc marshalSockaddr(ip net.IP, port int, zone string, b []byte) int {\n\tif ip4 := ip.To4(); ip4 != nil {\n\t\tswitch runtime.GOOS {\n\t\tcase \"android\", \"illumos\", \"linux\", \"solaris\", \"windows\":\n\t\t\tNativeEndian.PutUint16(b[:2], uint16(sysAF_INET))\n\t\tdefault:\n\t\t\tb[0] = sizeofSockaddrInet4\n\t\t\tb[1] = sysAF_INET\n\t\t}\n\t\tbinary.BigEndian.PutUint16(b[2:4], uint16(port))\n\t\tcopy(b[4:8], ip4)\n\t\treturn sizeofSockaddrInet4\n\t}\n\tif ip6 := ip.To16(); ip6 != nil && ip.To4() == nil {\n\t\tswitch runtime.GOOS {\n\t\tcase \"android\", \"illumos\", \"linux\", \"solaris\", \"windows\":\n\t\t\tNativeEndian.PutUint16(b[:2], uint16(sysAF_INET6))\n\t\tdefault:\n\t\t\tb[0] = sizeofSockaddrInet6\n\t\t\tb[1] = sysAF_INET6\n\t\t}\n\t\tbinary.BigEndian.PutUint16(b[2:4], uint16(port))\n\t\tcopy(b[8:24], ip6)\n\t\tif zone != \"\" {\n\t\t\tNativeEndian.PutUint32(b[24:28], uint32(zoneCache.index(zone)))\n\t\t}\n\t\treturn sizeofSockaddrInet6\n\t}\n\treturn 0\n}\n\nfunc parseInetAddr(b []byte, network string) (net.Addr, error) {\n\tif len(b) < 2 {\n\t\treturn nil, errors.New(\"invalid address\")\n\t}\n\tvar af int\n\tswitch runtime.GOOS {\n\tcase \"android\", \"illumos\", \"linux\", \"solaris\", \"windows\":\n\t\taf = int(NativeEndian.Uint16(b[:2]))\n\tdefault:\n\t\taf = int(b[1])\n\t}\n\tvar ip net.IP\n\tvar zone string\n\tif af == sysAF_INET {\n\t\tif len(b) < sizeofSockaddrInet4 {\n\t\t\treturn nil, errors.New(\"short address\")\n\t\t}\n\t\tip = make(net.IP, net.IPv4len)\n\t\tcopy(ip, b[4:8])\n\t}\n\tif af == sysAF_INET6 {\n\t\tif len(b) < sizeofSockaddrInet6 {\n\t\t\treturn nil, errors.New(\"short address\")\n\t\t}\n\t\tip = make(net.IP, net.IPv6len)\n\t\tcopy(ip, b[8:24])\n\t\tif id := int(NativeEndian.Uint32(b[24:28])); id > 0 {\n\t\t\tzone = zoneCache.name(id)\n\t\t}\n\t}\n\tswitch network {\n\tcase \"tcp\", \"tcp4\", \"tcp6\":\n\t\treturn &net.TCPAddr{IP: ip, Port: int(binary.BigEndian.Uint16(b[2:4])), Zone: zone}, nil\n\tcase \"udp\", \"udp4\", \"udp6\":\n\t\treturn &net.UDPAddr{IP: ip, Port: int(binary.BigEndian.Uint16(b[2:4])), Zone: zone}, nil\n\tdefault:\n\t\treturn &net.IPAddr{IP: ip, Zone: zone}, nil\n\t}\n}\n\n// An ipv6ZoneCache represents a cache holding partial network\n// interface information. It is used for reducing the cost of IPv6\n// addressing scope zone resolution.\n//\n// Multiple names sharing the index are managed by first-come\n// first-served basis for consistency.\ntype ipv6ZoneCache struct {\n\tsync.RWMutex                // guard the following\n\tlastFetched  time.Time      // last time routing information was fetched\n\ttoIndex      map[string]int // interface name to its index\n\ttoName       map[int]string // interface index to its name\n}\n\nvar zoneCache = ipv6ZoneCache{\n\ttoIndex: make(map[string]int),\n\ttoName:  make(map[int]string),\n}\n\n// update refreshes the network interface information if the cache was last\n// updated more than 1 minute ago, or if force is set. It returns whether the\n// cache was updated.\nfunc (zc *ipv6ZoneCache) update(ift []net.Interface, force bool) (updated bool) {\n\tzc.Lock()\n\tdefer zc.Unlock()\n\tnow := time.Now()\n\tif !force && zc.lastFetched.After(now.Add(-60*time.Second)) {\n\t\treturn false\n\t}\n\tzc.lastFetched = now\n\tif len(ift) == 0 {\n\t\tvar err error\n\t\tif ift, err = net.Interfaces(); err != nil {\n\t\t\treturn false\n\t\t}\n\t}\n\tzc.toIndex = make(map[string]int, len(ift))\n\tzc.toName = make(map[int]string, len(ift))\n\tfor _, ifi := range ift {\n\t\tzc.toIndex[ifi.Name] = ifi.Index\n\t\tif _, ok := zc.toName[ifi.Index]; !ok {\n\t\t\tzc.toName[ifi.Index] = ifi.Name\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (zc *ipv6ZoneCache) name(zone int) string {\n\tupdated := zoneCache.update(nil, false)\n\tzoneCache.RLock()\n\tname, ok := zoneCache.toName[zone]\n\tzoneCache.RUnlock()\n\tif !ok && !updated {\n\t\tzoneCache.update(nil, true)\n\t\tzoneCache.RLock()\n\t\tname, ok = zoneCache.toName[zone]\n\t\tzoneCache.RUnlock()\n\t}\n\tif !ok { // last resort\n\t\tname = strconv.Itoa(zone)\n\t}\n\treturn name\n}\n\nfunc (zc *ipv6ZoneCache) index(zone string) int {\n\tupdated := zoneCache.update(nil, false)\n\tzoneCache.RLock()\n\tindex, ok := zoneCache.toIndex[zone]\n\tzoneCache.RUnlock()\n\tif !ok && !updated {\n\t\tzoneCache.update(nil, true)\n\t\tzoneCache.RLock()\n\t\tindex, ok = zoneCache.toIndex[zone]\n\t\tzoneCache.RUnlock()\n\t}\n\tif !ok { // last resort\n\t\tindex, _ = strconv.Atoi(zone)\n\t}\n\treturn index\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_stub.go",
    "content": "// Copyright 2017 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos\n\npackage socket\n\nimport \"net\"\n\nconst (\n\tsysAF_UNSPEC = 0x0\n\tsysAF_INET   = 0x2\n\tsysAF_INET6  = 0xa\n\n\tsysSOCK_RAW = 0x3\n\n\tsizeofSockaddrInet4 = 0x10\n\tsizeofSockaddrInet6 = 0x1c\n)\n\nfunc marshalInetAddr(ip net.IP, port int, zone string) []byte {\n\treturn nil\n}\n\nfunc parseInetAddr(b []byte, network string) (net.Addr, error) {\n\treturn nil, errNotImplemented\n}\n\nfunc getsockopt(s uintptr, level, name int, b []byte) (int, error) {\n\treturn 0, errNotImplemented\n}\n\nfunc setsockopt(s uintptr, level, name int, b []byte) error {\n\treturn errNotImplemented\n}\n\nfunc recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {\n\treturn 0, 0, 0, nil, errNotImplemented\n}\n\nfunc sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {\n\treturn 0, errNotImplemented\n}\n\nfunc recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {\n\treturn 0, errNotImplemented\n}\n\nfunc sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {\n\treturn 0, errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_unix.go",
    "content": "// Copyright 2017 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris\n\npackage socket\n\nimport (\n\t\"net\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\n//go:linkname syscall_getsockopt syscall.getsockopt\nfunc syscall_getsockopt(s, level, name int, val unsafe.Pointer, vallen *uint32) error\n\n//go:linkname syscall_setsockopt syscall.setsockopt\nfunc syscall_setsockopt(s, level, name int, val unsafe.Pointer, vallen uintptr) error\n\nfunc getsockopt(s uintptr, level, name int, b []byte) (int, error) {\n\tl := uint32(len(b))\n\terr := syscall_getsockopt(int(s), level, name, unsafe.Pointer(&b[0]), &l)\n\treturn int(l), err\n}\n\nfunc setsockopt(s uintptr, level, name int, b []byte) error {\n\treturn syscall_setsockopt(int(s), level, name, unsafe.Pointer(&b[0]), uintptr(len(b)))\n}\n\nfunc recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {\n\tvar unixFrom unix.Sockaddr\n\tn, oobn, recvflags, unixFrom, err = unix.RecvmsgBuffers(int(s), buffers, oob, flags)\n\tif unixFrom != nil {\n\t\tfrom = sockaddrToAddr(unixFrom, network)\n\t}\n\treturn\n}\n\nfunc sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {\n\tvar unixTo unix.Sockaddr\n\tif to != nil {\n\t\tunixTo = addrToSockaddr(to)\n\t}\n\treturn unix.SendmsgBuffers(int(s), buffers, oob, unixTo, flags)\n}\n\n// addrToSockaddr converts a net.Addr to a unix.Sockaddr.\nfunc addrToSockaddr(a net.Addr) unix.Sockaddr {\n\tvar (\n\t\tip   net.IP\n\t\tport int\n\t\tzone string\n\t)\n\tswitch a := a.(type) {\n\tcase *net.TCPAddr:\n\t\tip = a.IP\n\t\tport = a.Port\n\t\tzone = a.Zone\n\tcase *net.UDPAddr:\n\t\tip = a.IP\n\t\tport = a.Port\n\t\tzone = a.Zone\n\tcase *net.IPAddr:\n\t\tip = a.IP\n\t\tzone = a.Zone\n\tdefault:\n\t\treturn nil\n\t}\n\n\tif ip4 := ip.To4(); ip4 != nil {\n\t\tsa := unix.SockaddrInet4{Port: port}\n\t\tcopy(sa.Addr[:], ip4)\n\t\treturn &sa\n\t}\n\n\tif ip6 := ip.To16(); ip6 != nil && ip.To4() == nil {\n\t\tsa := unix.SockaddrInet6{Port: port}\n\t\tcopy(sa.Addr[:], ip6)\n\t\tif zone != \"\" {\n\t\t\tsa.ZoneId = uint32(zoneCache.index(zone))\n\t\t}\n\t\treturn &sa\n\t}\n\n\treturn nil\n}\n\n// sockaddrToAddr converts a unix.Sockaddr to a net.Addr.\nfunc sockaddrToAddr(sa unix.Sockaddr, network string) net.Addr {\n\tvar (\n\t\tip   net.IP\n\t\tport int\n\t\tzone string\n\t)\n\tswitch sa := sa.(type) {\n\tcase *unix.SockaddrInet4:\n\t\tip = make(net.IP, net.IPv4len)\n\t\tcopy(ip, sa.Addr[:])\n\t\tport = sa.Port\n\tcase *unix.SockaddrInet6:\n\t\tip = make(net.IP, net.IPv6len)\n\t\tcopy(ip, sa.Addr[:])\n\t\tport = sa.Port\n\t\tif sa.ZoneId > 0 {\n\t\t\tzone = zoneCache.name(int(sa.ZoneId))\n\t\t}\n\tdefault:\n\t\treturn nil\n\t}\n\n\tswitch network {\n\tcase \"tcp\", \"tcp4\", \"tcp6\":\n\t\treturn &net.TCPAddr{IP: ip, Port: port, Zone: zone}\n\tcase \"udp\", \"udp4\", \"udp6\":\n\t\treturn &net.UDPAddr{IP: ip, Port: port, Zone: zone}\n\tdefault:\n\t\treturn &net.IPAddr{IP: ip, Zone: zone}\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_windows.go",
    "content": "// Copyright 2017 The Go 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 socket\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\nfunc probeProtocolStack() int {\n\tvar p uintptr\n\treturn int(unsafe.Sizeof(p))\n}\n\nconst (\n\tsysAF_UNSPEC = windows.AF_UNSPEC\n\tsysAF_INET   = windows.AF_INET\n\tsysAF_INET6  = windows.AF_INET6\n\n\tsysSOCK_RAW = windows.SOCK_RAW\n\n\tsizeofSockaddrInet4 = 0x10\n\tsizeofSockaddrInet6 = 0x1c\n)\n\nfunc getsockopt(s uintptr, level, name int, b []byte) (int, error) {\n\tl := uint32(len(b))\n\terr := syscall.Getsockopt(syscall.Handle(s), int32(level), int32(name), (*byte)(unsafe.Pointer(&b[0])), (*int32)(unsafe.Pointer(&l)))\n\treturn int(l), err\n}\n\nfunc setsockopt(s uintptr, level, name int, b []byte) error {\n\treturn syscall.Setsockopt(syscall.Handle(s), int32(level), int32(name), (*byte)(unsafe.Pointer(&b[0])), int32(len(b)))\n}\n\nfunc recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {\n\treturn 0, 0, 0, nil, errNotImplemented\n}\n\nfunc sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {\n\treturn 0, errNotImplemented\n}\n\nfunc recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {\n\treturn 0, errNotImplemented\n}\n\nfunc sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) {\n\treturn 0, errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go",
    "content": "// Copyright 2020 The Go 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 socket\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nfunc syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)\nfunc syscall_syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)\n\nfunc probeProtocolStack() int {\n\treturn 4 // sizeof(int) on GOOS=zos GOARCH=s390x\n}\n\nfunc getsockopt(s uintptr, level, name int, b []byte) (int, error) {\n\tl := uint32(len(b))\n\t_, _, errno := syscall_syscall6(syscall.SYS_GETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0)\n\treturn int(l), errnoErr(errno)\n}\n\nfunc setsockopt(s uintptr, level, name int, b []byte) error {\n\t_, _, errno := syscall_syscall6(syscall.SYS_SETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0)\n\treturn errnoErr(errno)\n}\n\nfunc recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) {\n\tvar h msghdr\n\tvs := make([]iovec, len(buffers))\n\tvar sa []byte\n\tif network != \"tcp\" {\n\t\tsa = make([]byte, sizeofSockaddrInet6)\n\t}\n\th.pack(vs, buffers, oob, sa)\n\tsn, _, errno := syscall_syscall(syscall.SYS___RECVMSG_A, s, uintptr(unsafe.Pointer(&h)), uintptr(flags))\n\tn = int(sn)\n\toobn = h.controllen()\n\trecvflags = h.flags()\n\terr = errnoErr(errno)\n\tif network != \"tcp\" {\n\t\tvar err2 error\n\t\tfrom, err2 = parseInetAddr(sa, network)\n\t\tif err2 != nil && err == nil {\n\t\t\terr = err2\n\t\t}\n\t}\n\treturn\n}\n\nfunc sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) {\n\tvar h msghdr\n\tvs := make([]iovec, len(buffers))\n\tvar sa []byte\n\tif to != nil {\n\t\tvar a [sizeofSockaddrInet6]byte\n\t\tn := marshalInetAddr(to, a[:])\n\t\tsa = a[:n]\n\t}\n\th.pack(vs, buffers, oob, sa)\n\tn, _, errno := syscall_syscall(syscall.SYS___SENDMSG_A, s, uintptr(unsafe.Pointer(&h)), uintptr(flags))\n\treturn int(n), errnoErr(errno)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/sys_zos_s390x.s",
    "content": "// Copyright 2020 The Go 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\n#include \"textflag.h\"\n\nTEXT ·syscall_syscall(SB),NOSPLIT,$0\n        JMP     syscall·_syscall(SB)\n\nTEXT ·syscall_syscall6(SB),NOSPLIT,$0\n        JMP     syscall·_syscall6(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_aix.go\n\n// Added for go1.11 compatibility\n//go:build aix\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     int32\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype mmsghdr struct {\n\tHdr       msghdr\n\tLen       uint32\n\tPad_cgo_0 [4]byte\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x30\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_darwin.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tPad_cgo_0  [4]byte\n\tIov        *iovec\n\tIovlen     int32\n\tPad_cgo_1  [4]byte\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x30\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_darwin.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tPad_cgo_0  [4]byte\n\tIov        *iovec\n\tIovlen     int32\n\tPad_cgo_1  [4]byte\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x30\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_dragonfly.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tPad_cgo_0  [4]byte\n\tIov        *iovec\n\tIovlen     int32\n\tPad_cgo_1  [4]byte\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x30\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_freebsd.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint32\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     int32\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x8\n\tsizeofMsghdr = 0x1c\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_freebsd_amd64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_freebsd.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tPad_cgo_0  [4]byte\n\tIov        *iovec\n\tIovlen     int32\n\tPad_cgo_1  [4]byte\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x30\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_freebsd.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint32\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     int32\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x8\n\tsizeofMsghdr = 0x1c\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_freebsd.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tPad_cgo_0  [4]byte\n\tIov        *iovec\n\tIovlen     int32\n\tPad_cgo_1  [4]byte\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x30\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_freebsd_riscv64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_freebsd.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     int32\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x30\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_linux_386.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint32\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     uint32\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype mmsghdr struct {\n\tHdr msghdr\n\tLen uint32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x8\n\tsizeofMsghdr = 0x1c\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tPad_cgo_0  [4]byte\n\tIov        *iovec\n\tIovlen     uint64\n\tControl    *byte\n\tControllen uint64\n\tFlags      int32\n\tPad_cgo_1  [4]byte\n}\n\ntype mmsghdr struct {\n\tHdr       msghdr\n\tLen       uint32\n\tPad_cgo_0 [4]byte\n}\n\ntype cmsghdr struct {\n\tLen   uint64\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x38\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint32\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     uint32\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype mmsghdr struct {\n\tHdr msghdr\n\tLen uint32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x8\n\tsizeofMsghdr = 0x1c\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_linux_arm64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tPad_cgo_0  [4]byte\n\tIov        *iovec\n\tIovlen     uint64\n\tControl    *byte\n\tControllen uint64\n\tFlags      int32\n\tPad_cgo_1  [4]byte\n}\n\ntype mmsghdr struct {\n\tHdr       msghdr\n\tLen       uint32\n\tPad_cgo_0 [4]byte\n}\n\ntype cmsghdr struct {\n\tLen   uint64\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x38\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_linux_loong64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\n//go:build loong64\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     uint64\n\tControl    *byte\n\tControllen uint64\n\tFlags      int32\n\tPad_cgo_0  [4]byte\n}\n\ntype mmsghdr struct {\n\tHdr       msghdr\n\tLen       uint32\n\tPad_cgo_0 [4]byte\n}\n\ntype cmsghdr struct {\n\tLen   uint64\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x38\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_linux_mips.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint32\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     uint32\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype mmsghdr struct {\n\tHdr msghdr\n\tLen uint32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x8\n\tsizeofMsghdr = 0x1c\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_linux_mips64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tPad_cgo_0  [4]byte\n\tIov        *iovec\n\tIovlen     uint64\n\tControl    *byte\n\tControllen uint64\n\tFlags      int32\n\tPad_cgo_1  [4]byte\n}\n\ntype mmsghdr struct {\n\tHdr       msghdr\n\tLen       uint32\n\tPad_cgo_0 [4]byte\n}\n\ntype cmsghdr struct {\n\tLen   uint64\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x38\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_linux_mips64le.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tPad_cgo_0  [4]byte\n\tIov        *iovec\n\tIovlen     uint64\n\tControl    *byte\n\tControllen uint64\n\tFlags      int32\n\tPad_cgo_1  [4]byte\n}\n\ntype mmsghdr struct {\n\tHdr       msghdr\n\tLen       uint32\n\tPad_cgo_0 [4]byte\n}\n\ntype cmsghdr struct {\n\tLen   uint64\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x38\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_linux_mipsle.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint32\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     uint32\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype mmsghdr struct {\n\tHdr msghdr\n\tLen uint32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x8\n\tsizeofMsghdr = 0x1c\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_linux_ppc.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint32\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     uint32\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype mmsghdr struct {\n\tHdr msghdr\n\tLen uint32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x8\n\tsizeofMsghdr = 0x1c\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tPad_cgo_0  [4]byte\n\tIov        *iovec\n\tIovlen     uint64\n\tControl    *byte\n\tControllen uint64\n\tFlags      int32\n\tPad_cgo_1  [4]byte\n}\n\ntype mmsghdr struct {\n\tHdr       msghdr\n\tLen       uint32\n\tPad_cgo_0 [4]byte\n}\n\ntype cmsghdr struct {\n\tLen   uint64\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x38\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64le.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tPad_cgo_0  [4]byte\n\tIov        *iovec\n\tIovlen     uint64\n\tControl    *byte\n\tControllen uint64\n\tFlags      int32\n\tPad_cgo_1  [4]byte\n}\n\ntype mmsghdr struct {\n\tHdr       msghdr\n\tLen       uint32\n\tPad_cgo_0 [4]byte\n}\n\ntype cmsghdr struct {\n\tLen   uint64\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x38\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\n//go:build riscv64\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     uint64\n\tControl    *byte\n\tControllen uint64\n\tFlags      int32\n\tPad_cgo_0  [4]byte\n}\n\ntype mmsghdr struct {\n\tHdr       msghdr\n\tLen       uint32\n\tPad_cgo_0 [4]byte\n}\n\ntype cmsghdr struct {\n\tLen   uint64\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x38\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_linux_s390x.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tPad_cgo_0  [4]byte\n\tIov        *iovec\n\tIovlen     uint64\n\tControl    *byte\n\tControllen uint64\n\tFlags      int32\n\tPad_cgo_1  [4]byte\n}\n\ntype mmsghdr struct {\n\tHdr       msghdr\n\tLen       uint32\n\tPad_cgo_0 [4]byte\n}\n\ntype cmsghdr struct {\n\tLen   uint64\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x38\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_netbsd_386.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_netbsd.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint32\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     int32\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype mmsghdr struct {\n\tHdr msghdr\n\tLen uint32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x8\n\tsizeofMsghdr = 0x1c\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_netbsd_amd64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_netbsd.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tPad_cgo_0  [4]byte\n\tIov        *iovec\n\tIovlen     int32\n\tPad_cgo_1  [4]byte\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype mmsghdr struct {\n\tHdr       msghdr\n\tLen       uint32\n\tPad_cgo_0 [4]byte\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x30\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_netbsd.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint32\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     int32\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype mmsghdr struct {\n\tHdr msghdr\n\tLen uint32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x8\n\tsizeofMsghdr = 0x1c\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_netbsd.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tPad_cgo_0  [4]byte\n\tIov        *iovec\n\tIovlen     int32\n\tPad_cgo_1  [4]byte\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype mmsghdr struct {\n\tHdr       msghdr\n\tLen       uint32\n\tPad_cgo_0 [4]byte\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x30\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_openbsd_386.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_openbsd.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint32\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     uint32\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x8\n\tsizeofMsghdr = 0x1c\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_openbsd_amd64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_openbsd.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tPad_cgo_0  [4]byte\n\tIov        *iovec\n\tIovlen     uint32\n\tPad_cgo_1  [4]byte\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x30\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_openbsd.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint32\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     uint32\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x8\n\tsizeofMsghdr = 0x1c\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_openbsd.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tPad_cgo_0  [4]byte\n\tIov        *iovec\n\tIovlen     uint32\n\tPad_cgo_1  [4]byte\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x30\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_openbsd_mips64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_openbsd.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     uint32\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x30\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_openbsd_ppc64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_openbsd.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     uint32\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x30\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_openbsd_riscv64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_openbsd.go\n\npackage socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tNamelen    uint32\n\tIov        *iovec\n\tIovlen     uint32\n\tControl    *byte\n\tControllen uint32\n\tFlags      int32\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x30\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_solaris_amd64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_solaris.go\n\npackage socket\n\ntype iovec struct {\n\tBase *int8\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName         *byte\n\tNamelen      uint32\n\tPad_cgo_0    [4]byte\n\tIov          *iovec\n\tIovlen       int32\n\tPad_cgo_1    [4]byte\n\tAccrights    *int8\n\tAccrightslen int32\n\tPad_cgo_2    [4]byte\n}\n\ntype cmsghdr struct {\n\tLen   uint32\n\tLevel int32\n\tType  int32\n}\n\nconst (\n\tsizeofIovec  = 0x10\n\tsizeofMsghdr = 0x30\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socket/zsys_zos_s390x.go",
    "content": "// Copyright 2020 The Go 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 socket\n\ntype iovec struct {\n\tBase *byte\n\tLen  uint64\n}\n\ntype msghdr struct {\n\tName       *byte\n\tIov        *iovec\n\tControl    *byte\n\tFlags      int32\n\tNamelen    uint32\n\tIovlen     int32\n\tControllen uint32\n}\n\ntype cmsghdr struct {\n\tLen   int32\n\tLevel int32\n\tType  int32\n}\n\nconst sizeofCmsghdr = 12\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socks/client.go",
    "content": "// Copyright 2018 The Go 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 socks\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n\t\"strconv\"\n\t\"time\"\n)\n\nvar (\n\tnoDeadline   = time.Time{}\n\taLongTimeAgo = time.Unix(1, 0)\n)\n\nfunc (d *Dialer) connect(ctx context.Context, c net.Conn, address string) (_ net.Addr, ctxErr error) {\n\thost, port, err := splitHostPort(address)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif deadline, ok := ctx.Deadline(); ok && !deadline.IsZero() {\n\t\tc.SetDeadline(deadline)\n\t\tdefer c.SetDeadline(noDeadline)\n\t}\n\tif ctx != context.Background() {\n\t\terrCh := make(chan error, 1)\n\t\tdone := make(chan struct{})\n\t\tdefer func() {\n\t\t\tclose(done)\n\t\t\tif ctxErr == nil {\n\t\t\t\tctxErr = <-errCh\n\t\t\t}\n\t\t}()\n\t\tgo func() {\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\tc.SetDeadline(aLongTimeAgo)\n\t\t\t\terrCh <- ctx.Err()\n\t\t\tcase <-done:\n\t\t\t\terrCh <- nil\n\t\t\t}\n\t\t}()\n\t}\n\n\tb := make([]byte, 0, 6+len(host)) // the size here is just an estimate\n\tb = append(b, Version5)\n\tif len(d.AuthMethods) == 0 || d.Authenticate == nil {\n\t\tb = append(b, 1, byte(AuthMethodNotRequired))\n\t} else {\n\t\tams := d.AuthMethods\n\t\tif len(ams) > 255 {\n\t\t\treturn nil, errors.New(\"too many authentication methods\")\n\t\t}\n\t\tb = append(b, byte(len(ams)))\n\t\tfor _, am := range ams {\n\t\t\tb = append(b, byte(am))\n\t\t}\n\t}\n\tif _, ctxErr = c.Write(b); ctxErr != nil {\n\t\treturn\n\t}\n\n\tif _, ctxErr = io.ReadFull(c, b[:2]); ctxErr != nil {\n\t\treturn\n\t}\n\tif b[0] != Version5 {\n\t\treturn nil, errors.New(\"unexpected protocol version \" + strconv.Itoa(int(b[0])))\n\t}\n\tam := AuthMethod(b[1])\n\tif am == AuthMethodNoAcceptableMethods {\n\t\treturn nil, errors.New(\"no acceptable authentication methods\")\n\t}\n\tif d.Authenticate != nil {\n\t\tif ctxErr = d.Authenticate(ctx, c, am); ctxErr != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tb = b[:0]\n\tb = append(b, Version5, byte(d.cmd), 0)\n\tif ip := net.ParseIP(host); ip != nil {\n\t\tif ip4 := ip.To4(); ip4 != nil {\n\t\t\tb = append(b, AddrTypeIPv4)\n\t\t\tb = append(b, ip4...)\n\t\t} else if ip6 := ip.To16(); ip6 != nil {\n\t\t\tb = append(b, AddrTypeIPv6)\n\t\t\tb = append(b, ip6...)\n\t\t} else {\n\t\t\treturn nil, errors.New(\"unknown address type\")\n\t\t}\n\t} else {\n\t\tif len(host) > 255 {\n\t\t\treturn nil, errors.New(\"FQDN too long\")\n\t\t}\n\t\tb = append(b, AddrTypeFQDN)\n\t\tb = append(b, byte(len(host)))\n\t\tb = append(b, host...)\n\t}\n\tb = append(b, byte(port>>8), byte(port))\n\tif _, ctxErr = c.Write(b); ctxErr != nil {\n\t\treturn\n\t}\n\n\tif _, ctxErr = io.ReadFull(c, b[:4]); ctxErr != nil {\n\t\treturn\n\t}\n\tif b[0] != Version5 {\n\t\treturn nil, errors.New(\"unexpected protocol version \" + strconv.Itoa(int(b[0])))\n\t}\n\tif cmdErr := Reply(b[1]); cmdErr != StatusSucceeded {\n\t\treturn nil, errors.New(\"unknown error \" + cmdErr.String())\n\t}\n\tif b[2] != 0 {\n\t\treturn nil, errors.New(\"non-zero reserved field\")\n\t}\n\tl := 2\n\tvar a Addr\n\tswitch b[3] {\n\tcase AddrTypeIPv4:\n\t\tl += net.IPv4len\n\t\ta.IP = make(net.IP, net.IPv4len)\n\tcase AddrTypeIPv6:\n\t\tl += net.IPv6len\n\t\ta.IP = make(net.IP, net.IPv6len)\n\tcase AddrTypeFQDN:\n\t\tif _, err := io.ReadFull(c, b[:1]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tl += int(b[0])\n\tdefault:\n\t\treturn nil, errors.New(\"unknown address type \" + strconv.Itoa(int(b[3])))\n\t}\n\tif cap(b) < l {\n\t\tb = make([]byte, l)\n\t} else {\n\t\tb = b[:l]\n\t}\n\tif _, ctxErr = io.ReadFull(c, b); ctxErr != nil {\n\t\treturn\n\t}\n\tif a.IP != nil {\n\t\tcopy(a.IP, b)\n\t} else {\n\t\ta.Name = string(b[:len(b)-2])\n\t}\n\ta.Port = int(b[len(b)-2])<<8 | int(b[len(b)-1])\n\treturn &a, nil\n}\n\nfunc splitHostPort(address string) (string, int, error) {\n\thost, port, err := net.SplitHostPort(address)\n\tif err != nil {\n\t\treturn \"\", 0, err\n\t}\n\tportnum, err := strconv.Atoi(port)\n\tif err != nil {\n\t\treturn \"\", 0, err\n\t}\n\tif 1 > portnum || portnum > 0xffff {\n\t\treturn \"\", 0, errors.New(\"port number out of range \" + port)\n\t}\n\treturn host, portnum, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/socks/socks.go",
    "content": "// Copyright 2018 The Go 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\n// Package socks provides a SOCKS version 5 client implementation.\n//\n// SOCKS protocol version 5 is defined in RFC 1928.\n// Username/Password authentication for SOCKS version 5 is defined in\n// RFC 1929.\npackage socks\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n\t\"strconv\"\n)\n\n// A Command represents a SOCKS command.\ntype Command int\n\nfunc (cmd Command) String() string {\n\tswitch cmd {\n\tcase CmdConnect:\n\t\treturn \"socks connect\"\n\tcase cmdBind:\n\t\treturn \"socks bind\"\n\tdefault:\n\t\treturn \"socks \" + strconv.Itoa(int(cmd))\n\t}\n}\n\n// An AuthMethod represents a SOCKS authentication method.\ntype AuthMethod int\n\n// A Reply represents a SOCKS command reply code.\ntype Reply int\n\nfunc (code Reply) String() string {\n\tswitch code {\n\tcase StatusSucceeded:\n\t\treturn \"succeeded\"\n\tcase 0x01:\n\t\treturn \"general SOCKS server failure\"\n\tcase 0x02:\n\t\treturn \"connection not allowed by ruleset\"\n\tcase 0x03:\n\t\treturn \"network unreachable\"\n\tcase 0x04:\n\t\treturn \"host unreachable\"\n\tcase 0x05:\n\t\treturn \"connection refused\"\n\tcase 0x06:\n\t\treturn \"TTL expired\"\n\tcase 0x07:\n\t\treturn \"command not supported\"\n\tcase 0x08:\n\t\treturn \"address type not supported\"\n\tdefault:\n\t\treturn \"unknown code: \" + strconv.Itoa(int(code))\n\t}\n}\n\n// Wire protocol constants.\nconst (\n\tVersion5 = 0x05\n\n\tAddrTypeIPv4 = 0x01\n\tAddrTypeFQDN = 0x03\n\tAddrTypeIPv6 = 0x04\n\n\tCmdConnect Command = 0x01 // establishes an active-open forward proxy connection\n\tcmdBind    Command = 0x02 // establishes a passive-open forward proxy connection\n\n\tAuthMethodNotRequired         AuthMethod = 0x00 // no authentication required\n\tAuthMethodUsernamePassword    AuthMethod = 0x02 // use username/password\n\tAuthMethodNoAcceptableMethods AuthMethod = 0xff // no acceptable authentication methods\n\n\tStatusSucceeded Reply = 0x00\n)\n\n// An Addr represents a SOCKS-specific address.\n// Either Name or IP is used exclusively.\ntype Addr struct {\n\tName string // fully-qualified domain name\n\tIP   net.IP\n\tPort int\n}\n\nfunc (a *Addr) Network() string { return \"socks\" }\n\nfunc (a *Addr) String() string {\n\tif a == nil {\n\t\treturn \"<nil>\"\n\t}\n\tport := strconv.Itoa(a.Port)\n\tif a.IP == nil {\n\t\treturn net.JoinHostPort(a.Name, port)\n\t}\n\treturn net.JoinHostPort(a.IP.String(), port)\n}\n\n// A Conn represents a forward proxy connection.\ntype Conn struct {\n\tnet.Conn\n\n\tboundAddr net.Addr\n}\n\n// BoundAddr returns the address assigned by the proxy server for\n// connecting to the command target address from the proxy server.\nfunc (c *Conn) BoundAddr() net.Addr {\n\tif c == nil {\n\t\treturn nil\n\t}\n\treturn c.boundAddr\n}\n\n// A Dialer holds SOCKS-specific options.\ntype Dialer struct {\n\tcmd          Command // either CmdConnect or cmdBind\n\tproxyNetwork string  // network between a proxy server and a client\n\tproxyAddress string  // proxy server address\n\n\t// ProxyDial specifies the optional dial function for\n\t// establishing the transport connection.\n\tProxyDial func(context.Context, string, string) (net.Conn, error)\n\n\t// AuthMethods specifies the list of request authentication\n\t// methods.\n\t// If empty, SOCKS client requests only AuthMethodNotRequired.\n\tAuthMethods []AuthMethod\n\n\t// Authenticate specifies the optional authentication\n\t// function. It must be non-nil when AuthMethods is not empty.\n\t// It must return an error when the authentication is failed.\n\tAuthenticate func(context.Context, io.ReadWriter, AuthMethod) error\n}\n\n// DialContext connects to the provided address on the provided\n// network.\n//\n// The returned error value may be a net.OpError. When the Op field of\n// net.OpError contains \"socks\", the Source field contains a proxy\n// server address and the Addr field contains a command target\n// address.\n//\n// See func Dial of the net package of standard library for a\n// description of the network and address parameters.\nfunc (d *Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {\n\tif err := d.validateTarget(network, address); err != nil {\n\t\tproxy, dst, _ := d.pathAddrs(address)\n\t\treturn nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}\n\t}\n\tif ctx == nil {\n\t\tproxy, dst, _ := d.pathAddrs(address)\n\t\treturn nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New(\"nil context\")}\n\t}\n\tvar err error\n\tvar c net.Conn\n\tif d.ProxyDial != nil {\n\t\tc, err = d.ProxyDial(ctx, d.proxyNetwork, d.proxyAddress)\n\t} else {\n\t\tvar dd net.Dialer\n\t\tc, err = dd.DialContext(ctx, d.proxyNetwork, d.proxyAddress)\n\t}\n\tif err != nil {\n\t\tproxy, dst, _ := d.pathAddrs(address)\n\t\treturn nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}\n\t}\n\ta, err := d.connect(ctx, c, address)\n\tif err != nil {\n\t\tc.Close()\n\t\tproxy, dst, _ := d.pathAddrs(address)\n\t\treturn nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}\n\t}\n\treturn &Conn{Conn: c, boundAddr: a}, nil\n}\n\n// DialWithConn initiates a connection from SOCKS server to the target\n// network and address using the connection c that is already\n// connected to the SOCKS server.\n//\n// It returns the connection's local address assigned by the SOCKS\n// server.\nfunc (d *Dialer) DialWithConn(ctx context.Context, c net.Conn, network, address string) (net.Addr, error) {\n\tif err := d.validateTarget(network, address); err != nil {\n\t\tproxy, dst, _ := d.pathAddrs(address)\n\t\treturn nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}\n\t}\n\tif ctx == nil {\n\t\tproxy, dst, _ := d.pathAddrs(address)\n\t\treturn nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New(\"nil context\")}\n\t}\n\ta, err := d.connect(ctx, c, address)\n\tif err != nil {\n\t\tproxy, dst, _ := d.pathAddrs(address)\n\t\treturn nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}\n\t}\n\treturn a, nil\n}\n\n// Dial connects to the provided address on the provided network.\n//\n// Unlike DialContext, it returns a raw transport connection instead\n// of a forward proxy connection.\n//\n// Deprecated: Use DialContext or DialWithConn instead.\nfunc (d *Dialer) Dial(network, address string) (net.Conn, error) {\n\tif err := d.validateTarget(network, address); err != nil {\n\t\tproxy, dst, _ := d.pathAddrs(address)\n\t\treturn nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}\n\t}\n\tvar err error\n\tvar c net.Conn\n\tif d.ProxyDial != nil {\n\t\tc, err = d.ProxyDial(context.Background(), d.proxyNetwork, d.proxyAddress)\n\t} else {\n\t\tc, err = net.Dial(d.proxyNetwork, d.proxyAddress)\n\t}\n\tif err != nil {\n\t\tproxy, dst, _ := d.pathAddrs(address)\n\t\treturn nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}\n\t}\n\tif _, err := d.DialWithConn(context.Background(), c, network, address); err != nil {\n\t\tc.Close()\n\t\treturn nil, err\n\t}\n\treturn c, nil\n}\n\nfunc (d *Dialer) validateTarget(network, address string) error {\n\tswitch network {\n\tcase \"tcp\", \"tcp6\", \"tcp4\":\n\tdefault:\n\t\treturn errors.New(\"network not implemented\")\n\t}\n\tswitch d.cmd {\n\tcase CmdConnect, cmdBind:\n\tdefault:\n\t\treturn errors.New(\"command not implemented\")\n\t}\n\treturn nil\n}\n\nfunc (d *Dialer) pathAddrs(address string) (proxy, dst net.Addr, err error) {\n\tfor i, s := range []string{d.proxyAddress, address} {\n\t\thost, port, err := splitHostPort(s)\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t\ta := &Addr{Port: port}\n\t\ta.IP = net.ParseIP(host)\n\t\tif a.IP == nil {\n\t\t\ta.Name = host\n\t\t}\n\t\tif i == 0 {\n\t\t\tproxy = a\n\t\t} else {\n\t\t\tdst = a\n\t\t}\n\t}\n\treturn\n}\n\n// NewDialer returns a new Dialer that dials through the provided\n// proxy server's network and address.\nfunc NewDialer(network, address string) *Dialer {\n\treturn &Dialer{proxyNetwork: network, proxyAddress: address, cmd: CmdConnect}\n}\n\nconst (\n\tauthUsernamePasswordVersion = 0x01\n\tauthStatusSucceeded         = 0x00\n)\n\n// UsernamePassword are the credentials for the username/password\n// authentication method.\ntype UsernamePassword struct {\n\tUsername string\n\tPassword string\n}\n\n// Authenticate authenticates a pair of username and password with the\n// proxy server.\nfunc (up *UsernamePassword) Authenticate(ctx context.Context, rw io.ReadWriter, auth AuthMethod) error {\n\tswitch auth {\n\tcase AuthMethodNotRequired:\n\t\treturn nil\n\tcase AuthMethodUsernamePassword:\n\t\tif len(up.Username) == 0 || len(up.Username) > 255 || len(up.Password) > 255 {\n\t\t\treturn errors.New(\"invalid username/password\")\n\t\t}\n\t\tb := []byte{authUsernamePasswordVersion}\n\t\tb = append(b, byte(len(up.Username)))\n\t\tb = append(b, up.Username...)\n\t\tb = append(b, byte(len(up.Password)))\n\t\tb = append(b, up.Password...)\n\t\t// TODO(mikio): handle IO deadlines and cancelation if\n\t\t// necessary\n\t\tif _, err := rw.Write(b); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err := io.ReadFull(rw, b[:2]); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif b[0] != authUsernamePasswordVersion {\n\t\t\treturn errors.New(\"invalid username/password version\")\n\t\t}\n\t\tif b[1] != authStatusSucceeded {\n\t\t\treturn errors.New(\"username/password authentication failed\")\n\t\t}\n\t\treturn nil\n\t}\n\treturn errors.New(\"unsupported authentication method \" + strconv.Itoa(int(auth)))\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/internal/timeseries/timeseries.go",
    "content": "// Copyright 2015 The Go 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\n// Package timeseries implements a time series structure for stats collection.\npackage timeseries // import \"golang.org/x/net/internal/timeseries\"\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"time\"\n)\n\nconst (\n\ttimeSeriesNumBuckets       = 64\n\tminuteHourSeriesNumBuckets = 60\n)\n\nvar timeSeriesResolutions = []time.Duration{\n\t1 * time.Second,\n\t10 * time.Second,\n\t1 * time.Minute,\n\t10 * time.Minute,\n\t1 * time.Hour,\n\t6 * time.Hour,\n\t24 * time.Hour,          // 1 day\n\t7 * 24 * time.Hour,      // 1 week\n\t4 * 7 * 24 * time.Hour,  // 4 weeks\n\t16 * 7 * 24 * time.Hour, // 16 weeks\n}\n\nvar minuteHourSeriesResolutions = []time.Duration{\n\t1 * time.Second,\n\t1 * time.Minute,\n}\n\n// An Observable is a kind of data that can be aggregated in a time series.\ntype Observable interface {\n\tMultiply(ratio float64)    // Multiplies the data in self by a given ratio\n\tAdd(other Observable)      // Adds the data from a different observation to self\n\tClear()                    // Clears the observation so it can be reused.\n\tCopyFrom(other Observable) // Copies the contents of a given observation to self\n}\n\n// Float attaches the methods of Observable to a float64.\ntype Float float64\n\n// NewFloat returns a Float.\nfunc NewFloat() Observable {\n\tf := Float(0)\n\treturn &f\n}\n\n// String returns the float as a string.\nfunc (f *Float) String() string { return fmt.Sprintf(\"%g\", f.Value()) }\n\n// Value returns the float's value.\nfunc (f *Float) Value() float64 { return float64(*f) }\n\nfunc (f *Float) Multiply(ratio float64) { *f *= Float(ratio) }\n\nfunc (f *Float) Add(other Observable) {\n\to := other.(*Float)\n\t*f += *o\n}\n\nfunc (f *Float) Clear() { *f = 0 }\n\nfunc (f *Float) CopyFrom(other Observable) {\n\to := other.(*Float)\n\t*f = *o\n}\n\n// A Clock tells the current time.\ntype Clock interface {\n\tTime() time.Time\n}\n\ntype defaultClock int\n\nvar defaultClockInstance defaultClock\n\nfunc (defaultClock) Time() time.Time { return time.Now() }\n\n// Information kept per level. Each level consists of a circular list of\n// observations. The start of the level may be derived from end and the\n// len(buckets) * sizeInMillis.\ntype tsLevel struct {\n\toldest   int               // index to oldest bucketed Observable\n\tnewest   int               // index to newest bucketed Observable\n\tend      time.Time         // end timestamp for this level\n\tsize     time.Duration     // duration of the bucketed Observable\n\tbuckets  []Observable      // collections of observations\n\tprovider func() Observable // used for creating new Observable\n}\n\nfunc (l *tsLevel) Clear() {\n\tl.oldest = 0\n\tl.newest = len(l.buckets) - 1\n\tl.end = time.Time{}\n\tfor i := range l.buckets {\n\t\tif l.buckets[i] != nil {\n\t\t\tl.buckets[i].Clear()\n\t\t\tl.buckets[i] = nil\n\t\t}\n\t}\n}\n\nfunc (l *tsLevel) InitLevel(size time.Duration, numBuckets int, f func() Observable) {\n\tl.size = size\n\tl.provider = f\n\tl.buckets = make([]Observable, numBuckets)\n}\n\n// Keeps a sequence of levels. Each level is responsible for storing data at\n// a given resolution. For example, the first level stores data at a one\n// minute resolution while the second level stores data at a one hour\n// resolution.\n\n// Each level is represented by a sequence of buckets. Each bucket spans an\n// interval equal to the resolution of the level. New observations are added\n// to the last bucket.\ntype timeSeries struct {\n\tprovider    func() Observable // make more Observable\n\tnumBuckets  int               // number of buckets in each level\n\tlevels      []*tsLevel        // levels of bucketed Observable\n\tlastAdd     time.Time         // time of last Observable tracked\n\ttotal       Observable        // convenient aggregation of all Observable\n\tclock       Clock             // Clock for getting current time\n\tpending     Observable        // observations not yet bucketed\n\tpendingTime time.Time         // what time are we keeping in pending\n\tdirty       bool              // if there are pending observations\n}\n\n// init initializes a level according to the supplied criteria.\nfunc (ts *timeSeries) init(resolutions []time.Duration, f func() Observable, numBuckets int, clock Clock) {\n\tts.provider = f\n\tts.numBuckets = numBuckets\n\tts.clock = clock\n\tts.levels = make([]*tsLevel, len(resolutions))\n\n\tfor i := range resolutions {\n\t\tif i > 0 && resolutions[i-1] >= resolutions[i] {\n\t\t\tlog.Print(\"timeseries: resolutions must be monotonically increasing\")\n\t\t\tbreak\n\t\t}\n\t\tnewLevel := new(tsLevel)\n\t\tnewLevel.InitLevel(resolutions[i], ts.numBuckets, ts.provider)\n\t\tts.levels[i] = newLevel\n\t}\n\n\tts.Clear()\n}\n\n// Clear removes all observations from the time series.\nfunc (ts *timeSeries) Clear() {\n\tts.lastAdd = time.Time{}\n\tts.total = ts.resetObservation(ts.total)\n\tts.pending = ts.resetObservation(ts.pending)\n\tts.pendingTime = time.Time{}\n\tts.dirty = false\n\n\tfor i := range ts.levels {\n\t\tts.levels[i].Clear()\n\t}\n}\n\n// Add records an observation at the current time.\nfunc (ts *timeSeries) Add(observation Observable) {\n\tts.AddWithTime(observation, ts.clock.Time())\n}\n\n// AddWithTime records an observation at the specified time.\nfunc (ts *timeSeries) AddWithTime(observation Observable, t time.Time) {\n\n\tsmallBucketDuration := ts.levels[0].size\n\n\tif t.After(ts.lastAdd) {\n\t\tts.lastAdd = t\n\t}\n\n\tif t.After(ts.pendingTime) {\n\t\tts.advance(t)\n\t\tts.mergePendingUpdates()\n\t\tts.pendingTime = ts.levels[0].end\n\t\tts.pending.CopyFrom(observation)\n\t\tts.dirty = true\n\t} else if t.After(ts.pendingTime.Add(-1 * smallBucketDuration)) {\n\t\t// The observation is close enough to go into the pending bucket.\n\t\t// This compensates for clock skewing and small scheduling delays\n\t\t// by letting the update stay in the fast path.\n\t\tts.pending.Add(observation)\n\t\tts.dirty = true\n\t} else {\n\t\tts.mergeValue(observation, t)\n\t}\n}\n\n// mergeValue inserts the observation at the specified time in the past into all levels.\nfunc (ts *timeSeries) mergeValue(observation Observable, t time.Time) {\n\tfor _, level := range ts.levels {\n\t\tindex := (ts.numBuckets - 1) - int(level.end.Sub(t)/level.size)\n\t\tif 0 <= index && index < ts.numBuckets {\n\t\t\tbucketNumber := (level.oldest + index) % ts.numBuckets\n\t\t\tif level.buckets[bucketNumber] == nil {\n\t\t\t\tlevel.buckets[bucketNumber] = level.provider()\n\t\t\t}\n\t\t\tlevel.buckets[bucketNumber].Add(observation)\n\t\t}\n\t}\n\tts.total.Add(observation)\n}\n\n// mergePendingUpdates applies the pending updates into all levels.\nfunc (ts *timeSeries) mergePendingUpdates() {\n\tif ts.dirty {\n\t\tts.mergeValue(ts.pending, ts.pendingTime)\n\t\tts.pending = ts.resetObservation(ts.pending)\n\t\tts.dirty = false\n\t}\n}\n\n// advance cycles the buckets at each level until the latest bucket in\n// each level can hold the time specified.\nfunc (ts *timeSeries) advance(t time.Time) {\n\tif !t.After(ts.levels[0].end) {\n\t\treturn\n\t}\n\tfor i := 0; i < len(ts.levels); i++ {\n\t\tlevel := ts.levels[i]\n\t\tif !level.end.Before(t) {\n\t\t\tbreak\n\t\t}\n\n\t\t// If the time is sufficiently far, just clear the level and advance\n\t\t// directly.\n\t\tif !t.Before(level.end.Add(level.size * time.Duration(ts.numBuckets))) {\n\t\t\tfor _, b := range level.buckets {\n\t\t\t\tts.resetObservation(b)\n\t\t\t}\n\t\t\tlevel.end = time.Unix(0, (t.UnixNano()/level.size.Nanoseconds())*level.size.Nanoseconds())\n\t\t}\n\n\t\tfor t.After(level.end) {\n\t\t\tlevel.end = level.end.Add(level.size)\n\t\t\tlevel.newest = level.oldest\n\t\t\tlevel.oldest = (level.oldest + 1) % ts.numBuckets\n\t\t\tts.resetObservation(level.buckets[level.newest])\n\t\t}\n\n\t\tt = level.end\n\t}\n}\n\n// Latest returns the sum of the num latest buckets from the level.\nfunc (ts *timeSeries) Latest(level, num int) Observable {\n\tnow := ts.clock.Time()\n\tif ts.levels[0].end.Before(now) {\n\t\tts.advance(now)\n\t}\n\n\tts.mergePendingUpdates()\n\n\tresult := ts.provider()\n\tl := ts.levels[level]\n\tindex := l.newest\n\n\tfor i := 0; i < num; i++ {\n\t\tif l.buckets[index] != nil {\n\t\t\tresult.Add(l.buckets[index])\n\t\t}\n\t\tif index == 0 {\n\t\t\tindex = ts.numBuckets\n\t\t}\n\t\tindex--\n\t}\n\n\treturn result\n}\n\n// LatestBuckets returns a copy of the num latest buckets from level.\nfunc (ts *timeSeries) LatestBuckets(level, num int) []Observable {\n\tif level < 0 || level > len(ts.levels) {\n\t\tlog.Print(\"timeseries: bad level argument: \", level)\n\t\treturn nil\n\t}\n\tif num < 0 || num >= ts.numBuckets {\n\t\tlog.Print(\"timeseries: bad num argument: \", num)\n\t\treturn nil\n\t}\n\n\tresults := make([]Observable, num)\n\tnow := ts.clock.Time()\n\tif ts.levels[0].end.Before(now) {\n\t\tts.advance(now)\n\t}\n\n\tts.mergePendingUpdates()\n\n\tl := ts.levels[level]\n\tindex := l.newest\n\n\tfor i := 0; i < num; i++ {\n\t\tresult := ts.provider()\n\t\tresults[i] = result\n\t\tif l.buckets[index] != nil {\n\t\t\tresult.CopyFrom(l.buckets[index])\n\t\t}\n\n\t\tif index == 0 {\n\t\t\tindex = ts.numBuckets\n\t\t}\n\t\tindex -= 1\n\t}\n\treturn results\n}\n\n// ScaleBy updates observations by scaling by factor.\nfunc (ts *timeSeries) ScaleBy(factor float64) {\n\tfor _, l := range ts.levels {\n\t\tfor i := 0; i < ts.numBuckets; i++ {\n\t\t\tl.buckets[i].Multiply(factor)\n\t\t}\n\t}\n\n\tts.total.Multiply(factor)\n\tts.pending.Multiply(factor)\n}\n\n// Range returns the sum of observations added over the specified time range.\n// If start or finish times don't fall on bucket boundaries of the same\n// level, then return values are approximate answers.\nfunc (ts *timeSeries) Range(start, finish time.Time) Observable {\n\treturn ts.ComputeRange(start, finish, 1)[0]\n}\n\n// Recent returns the sum of observations from the last delta.\nfunc (ts *timeSeries) Recent(delta time.Duration) Observable {\n\tnow := ts.clock.Time()\n\treturn ts.Range(now.Add(-delta), now)\n}\n\n// Total returns the total of all observations.\nfunc (ts *timeSeries) Total() Observable {\n\tts.mergePendingUpdates()\n\treturn ts.total\n}\n\n// ComputeRange computes a specified number of values into a slice using\n// the observations recorded over the specified time period. The return\n// values are approximate if the start or finish times don't fall on the\n// bucket boundaries at the same level or if the number of buckets spanning\n// the range is not an integral multiple of num.\nfunc (ts *timeSeries) ComputeRange(start, finish time.Time, num int) []Observable {\n\tif start.After(finish) {\n\t\tlog.Printf(\"timeseries: start > finish, %v>%v\", start, finish)\n\t\treturn nil\n\t}\n\n\tif num < 0 {\n\t\tlog.Printf(\"timeseries: num < 0, %v\", num)\n\t\treturn nil\n\t}\n\n\tresults := make([]Observable, num)\n\n\tfor _, l := range ts.levels {\n\t\tif !start.Before(l.end.Add(-l.size * time.Duration(ts.numBuckets))) {\n\t\t\tts.extract(l, start, finish, num, results)\n\t\t\treturn results\n\t\t}\n\t}\n\n\t// Failed to find a level that covers the desired range. So just\n\t// extract from the last level, even if it doesn't cover the entire\n\t// desired range.\n\tts.extract(ts.levels[len(ts.levels)-1], start, finish, num, results)\n\n\treturn results\n}\n\n// RecentList returns the specified number of values in slice over the most\n// recent time period of the specified range.\nfunc (ts *timeSeries) RecentList(delta time.Duration, num int) []Observable {\n\tif delta < 0 {\n\t\treturn nil\n\t}\n\tnow := ts.clock.Time()\n\treturn ts.ComputeRange(now.Add(-delta), now, num)\n}\n\n// extract returns a slice of specified number of observations from a given\n// level over a given range.\nfunc (ts *timeSeries) extract(l *tsLevel, start, finish time.Time, num int, results []Observable) {\n\tts.mergePendingUpdates()\n\n\tsrcInterval := l.size\n\tdstInterval := finish.Sub(start) / time.Duration(num)\n\tdstStart := start\n\tsrcStart := l.end.Add(-srcInterval * time.Duration(ts.numBuckets))\n\n\tsrcIndex := 0\n\n\t// Where should scanning start?\n\tif dstStart.After(srcStart) {\n\t\tadvance := int(dstStart.Sub(srcStart) / srcInterval)\n\t\tsrcIndex += advance\n\t\tsrcStart = srcStart.Add(time.Duration(advance) * srcInterval)\n\t}\n\n\t// The i'th value is computed as show below.\n\t// interval = (finish/start)/num\n\t// i'th value = sum of observation in range\n\t//   [ start + i       * interval,\n\t//     start + (i + 1) * interval )\n\tfor i := 0; i < num; i++ {\n\t\tresults[i] = ts.resetObservation(results[i])\n\t\tdstEnd := dstStart.Add(dstInterval)\n\t\tfor srcIndex < ts.numBuckets && srcStart.Before(dstEnd) {\n\t\t\tsrcEnd := srcStart.Add(srcInterval)\n\t\t\tif srcEnd.After(ts.lastAdd) {\n\t\t\t\tsrcEnd = ts.lastAdd\n\t\t\t}\n\n\t\t\tif !srcEnd.Before(dstStart) {\n\t\t\t\tsrcValue := l.buckets[(srcIndex+l.oldest)%ts.numBuckets]\n\t\t\t\tif !srcStart.Before(dstStart) && !srcEnd.After(dstEnd) {\n\t\t\t\t\t// dst completely contains src.\n\t\t\t\t\tif srcValue != nil {\n\t\t\t\t\t\tresults[i].Add(srcValue)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// dst partially overlaps src.\n\t\t\t\t\toverlapStart := maxTime(srcStart, dstStart)\n\t\t\t\t\toverlapEnd := minTime(srcEnd, dstEnd)\n\t\t\t\t\tbase := srcEnd.Sub(srcStart)\n\t\t\t\t\tfraction := overlapEnd.Sub(overlapStart).Seconds() / base.Seconds()\n\n\t\t\t\t\tused := ts.provider()\n\t\t\t\t\tif srcValue != nil {\n\t\t\t\t\t\tused.CopyFrom(srcValue)\n\t\t\t\t\t}\n\t\t\t\t\tused.Multiply(fraction)\n\t\t\t\t\tresults[i].Add(used)\n\t\t\t\t}\n\n\t\t\t\tif srcEnd.After(dstEnd) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tsrcIndex++\n\t\t\tsrcStart = srcStart.Add(srcInterval)\n\t\t}\n\t\tdstStart = dstStart.Add(dstInterval)\n\t}\n}\n\n// resetObservation clears the content so the struct may be reused.\nfunc (ts *timeSeries) resetObservation(observation Observable) Observable {\n\tif observation == nil {\n\t\tobservation = ts.provider()\n\t} else {\n\t\tobservation.Clear()\n\t}\n\treturn observation\n}\n\n// TimeSeries tracks data at granularities from 1 second to 16 weeks.\ntype TimeSeries struct {\n\ttimeSeries\n}\n\n// NewTimeSeries creates a new TimeSeries using the function provided for creating new Observable.\nfunc NewTimeSeries(f func() Observable) *TimeSeries {\n\treturn NewTimeSeriesWithClock(f, defaultClockInstance)\n}\n\n// NewTimeSeriesWithClock creates a new TimeSeries using the function provided for creating new Observable and the clock for\n// assigning timestamps.\nfunc NewTimeSeriesWithClock(f func() Observable, clock Clock) *TimeSeries {\n\tts := new(TimeSeries)\n\tts.timeSeries.init(timeSeriesResolutions, f, timeSeriesNumBuckets, clock)\n\treturn ts\n}\n\n// MinuteHourSeries tracks data at granularities of 1 minute and 1 hour.\ntype MinuteHourSeries struct {\n\ttimeSeries\n}\n\n// NewMinuteHourSeries creates a new MinuteHourSeries using the function provided for creating new Observable.\nfunc NewMinuteHourSeries(f func() Observable) *MinuteHourSeries {\n\treturn NewMinuteHourSeriesWithClock(f, defaultClockInstance)\n}\n\n// NewMinuteHourSeriesWithClock creates a new MinuteHourSeries using the function provided for creating new Observable and the clock for\n// assigning timestamps.\nfunc NewMinuteHourSeriesWithClock(f func() Observable, clock Clock) *MinuteHourSeries {\n\tts := new(MinuteHourSeries)\n\tts.timeSeries.init(minuteHourSeriesResolutions, f,\n\t\tminuteHourSeriesNumBuckets, clock)\n\treturn ts\n}\n\nfunc (ts *MinuteHourSeries) Minute() Observable {\n\treturn ts.timeSeries.Latest(0, 60)\n}\n\nfunc (ts *MinuteHourSeries) Hour() Observable {\n\treturn ts.timeSeries.Latest(1, 60)\n}\n\nfunc minTime(a, b time.Time) time.Time {\n\tif a.Before(b) {\n\t\treturn a\n\t}\n\treturn b\n}\n\nfunc maxTime(a, b time.Time) time.Time {\n\tif a.After(b) {\n\t\treturn a\n\t}\n\treturn b\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/batch.go",
    "content": "// Copyright 2017 The Go 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 ipv4\n\nimport (\n\t\"net\"\n\t\"runtime\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\n// BUG(mikio): On Windows, the ReadBatch and WriteBatch methods of\n// PacketConn are not implemented.\n\n// BUG(mikio): On Windows, the ReadBatch and WriteBatch methods of\n// RawConn are not implemented.\n\n// A Message represents an IO message.\n//\n//\ttype Message struct {\n//\t\tBuffers [][]byte\n//\t\tOOB     []byte\n//\t\tAddr    net.Addr\n//\t\tN       int\n//\t\tNN      int\n//\t\tFlags   int\n//\t}\n//\n// The Buffers fields represents a list of contiguous buffers, which\n// can be used for vectored IO, for example, putting a header and a\n// payload in each slice.\n// When writing, the Buffers field must contain at least one byte to\n// write.\n// When reading, the Buffers field will always contain a byte to read.\n//\n// The OOB field contains protocol-specific control or miscellaneous\n// ancillary data known as out-of-band data.\n// It can be nil when not required.\n//\n// The Addr field specifies a destination address when writing.\n// It can be nil when the underlying protocol of the endpoint uses\n// connection-oriented communication.\n// After a successful read, it may contain the source address on the\n// received packet.\n//\n// The N field indicates the number of bytes read or written from/to\n// Buffers.\n//\n// The NN field indicates the number of bytes read or written from/to\n// OOB.\n//\n// The Flags field contains protocol-specific information on the\n// received message.\ntype Message = socket.Message\n\n// ReadBatch reads a batch of messages.\n//\n// The provided flags is a set of platform-dependent flags, such as\n// syscall.MSG_PEEK.\n//\n// On a successful read it returns the number of messages received, up\n// to len(ms).\n//\n// On Linux, a batch read will be optimized.\n// On other platforms, this method will read only a single message.\n//\n// Unlike the ReadFrom method, it doesn't strip the IPv4 header\n// followed by option headers from the received IPv4 datagram when the\n// underlying transport is net.IPConn. Each Buffers field of Message\n// must be large enough to accommodate an IPv4 header and option\n// headers.\nfunc (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\tswitch runtime.GOOS {\n\tcase \"linux\":\n\t\tn, err := c.RecvMsgs([]socket.Message(ms), flags)\n\t\tif err != nil {\n\t\t\terr = &net.OpError{Op: \"read\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}\n\t\t}\n\t\treturn n, err\n\tdefault:\n\t\tn := 1\n\t\terr := c.RecvMsg(&ms[0], flags)\n\t\tif err != nil {\n\t\t\tn = 0\n\t\t\terr = &net.OpError{Op: \"read\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}\n\t\t}\n\t\tif compatFreeBSD32 && ms[0].NN > 0 {\n\t\t\tadjustFreeBSD32(&ms[0])\n\t\t}\n\t\treturn n, err\n\t}\n}\n\n// WriteBatch writes a batch of messages.\n//\n// The provided flags is a set of platform-dependent flags, such as\n// syscall.MSG_DONTROUTE.\n//\n// It returns the number of messages written on a successful write.\n//\n// On Linux, a batch write will be optimized.\n// On other platforms, this method will write only a single message.\nfunc (c *payloadHandler) WriteBatch(ms []Message, flags int) (int, error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\tswitch runtime.GOOS {\n\tcase \"linux\":\n\t\tn, err := c.SendMsgs([]socket.Message(ms), flags)\n\t\tif err != nil {\n\t\t\terr = &net.OpError{Op: \"write\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}\n\t\t}\n\t\treturn n, err\n\tdefault:\n\t\tn := 1\n\t\terr := c.SendMsg(&ms[0], flags)\n\t\tif err != nil {\n\t\t\tn = 0\n\t\t\terr = &net.OpError{Op: \"write\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}\n\t\t}\n\t\treturn n, err\n\t}\n}\n\n// ReadBatch reads a batch of messages.\n//\n// The provided flags is a set of platform-dependent flags, such as\n// syscall.MSG_PEEK.\n//\n// On a successful read it returns the number of messages received, up\n// to len(ms).\n//\n// On Linux, a batch read will be optimized.\n// On other platforms, this method will read only a single message.\nfunc (c *packetHandler) ReadBatch(ms []Message, flags int) (int, error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\tswitch runtime.GOOS {\n\tcase \"linux\":\n\t\tn, err := c.RecvMsgs([]socket.Message(ms), flags)\n\t\tif err != nil {\n\t\t\terr = &net.OpError{Op: \"read\", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}\n\t\t}\n\t\treturn n, err\n\tdefault:\n\t\tn := 1\n\t\terr := c.RecvMsg(&ms[0], flags)\n\t\tif err != nil {\n\t\t\tn = 0\n\t\t\terr = &net.OpError{Op: \"read\", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}\n\t\t}\n\t\tif compatFreeBSD32 && ms[0].NN > 0 {\n\t\t\tadjustFreeBSD32(&ms[0])\n\t\t}\n\t\treturn n, err\n\t}\n}\n\n// WriteBatch writes a batch of messages.\n//\n// The provided flags is a set of platform-dependent flags, such as\n// syscall.MSG_DONTROUTE.\n//\n// It returns the number of messages written on a successful write.\n//\n// On Linux, a batch write will be optimized.\n// On other platforms, this method will write only a single message.\nfunc (c *packetHandler) WriteBatch(ms []Message, flags int) (int, error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\tswitch runtime.GOOS {\n\tcase \"linux\":\n\t\tn, err := c.SendMsgs([]socket.Message(ms), flags)\n\t\tif err != nil {\n\t\t\terr = &net.OpError{Op: \"write\", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}\n\t\t}\n\t\treturn n, err\n\tdefault:\n\t\tn := 1\n\t\terr := c.SendMsg(&ms[0], flags)\n\t\tif err != nil {\n\t\t\tn = 0\n\t\t\terr = &net.OpError{Op: \"write\", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}\n\t\t}\n\t\treturn n, err\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/control.go",
    "content": "// Copyright 2012 The Go 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 ipv4\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"sync\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n)\n\ntype rawOpt struct {\n\tsync.RWMutex\n\tcflags ControlFlags\n}\n\nfunc (c *rawOpt) set(f ControlFlags)        { c.cflags |= f }\nfunc (c *rawOpt) clear(f ControlFlags)      { c.cflags &^= f }\nfunc (c *rawOpt) isset(f ControlFlags) bool { return c.cflags&f != 0 }\n\ntype ControlFlags uint\n\nconst (\n\tFlagTTL       ControlFlags = 1 << iota // pass the TTL on the received packet\n\tFlagSrc                                // pass the source address on the received packet\n\tFlagDst                                // pass the destination address on the received packet\n\tFlagInterface                          // pass the interface index on the received packet\n)\n\n// A ControlMessage represents per packet basis IP-level socket options.\ntype ControlMessage struct {\n\t// Receiving socket options: SetControlMessage allows to\n\t// receive the options from the protocol stack using ReadFrom\n\t// method of PacketConn or RawConn.\n\t//\n\t// Specifying socket options: ControlMessage for WriteTo\n\t// method of PacketConn or RawConn allows to send the options\n\t// to the protocol stack.\n\t//\n\tTTL     int    // time-to-live, receiving only\n\tSrc     net.IP // source address, specifying only\n\tDst     net.IP // destination address, receiving only\n\tIfIndex int    // interface index, must be 1 <= value when specifying\n}\n\nfunc (cm *ControlMessage) String() string {\n\tif cm == nil {\n\t\treturn \"<nil>\"\n\t}\n\treturn fmt.Sprintf(\"ttl=%d src=%v dst=%v ifindex=%d\", cm.TTL, cm.Src, cm.Dst, cm.IfIndex)\n}\n\n// Marshal returns the binary encoding of cm.\nfunc (cm *ControlMessage) Marshal() []byte {\n\tif cm == nil {\n\t\treturn nil\n\t}\n\tvar m socket.ControlMessage\n\tif ctlOpts[ctlPacketInfo].name > 0 && (cm.Src.To4() != nil || cm.IfIndex > 0) {\n\t\tm = socket.NewControlMessage([]int{ctlOpts[ctlPacketInfo].length})\n\t}\n\tif len(m) > 0 {\n\t\tctlOpts[ctlPacketInfo].marshal(m, cm)\n\t}\n\treturn m\n}\n\n// Parse parses b as a control message and stores the result in cm.\nfunc (cm *ControlMessage) Parse(b []byte) error {\n\tms, err := socket.ControlMessage(b).Parse()\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor _, m := range ms {\n\t\tlvl, typ, l, err := m.ParseHeader()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif lvl != iana.ProtocolIP {\n\t\t\tcontinue\n\t\t}\n\t\tswitch {\n\t\tcase typ == ctlOpts[ctlTTL].name && l >= ctlOpts[ctlTTL].length:\n\t\t\tctlOpts[ctlTTL].parse(cm, m.Data(l))\n\t\tcase typ == ctlOpts[ctlDst].name && l >= ctlOpts[ctlDst].length:\n\t\t\tctlOpts[ctlDst].parse(cm, m.Data(l))\n\t\tcase typ == ctlOpts[ctlInterface].name && l >= ctlOpts[ctlInterface].length:\n\t\t\tctlOpts[ctlInterface].parse(cm, m.Data(l))\n\t\tcase typ == ctlOpts[ctlPacketInfo].name && l >= ctlOpts[ctlPacketInfo].length:\n\t\t\tctlOpts[ctlPacketInfo].parse(cm, m.Data(l))\n\t\t}\n\t}\n\treturn nil\n}\n\n// NewControlMessage returns a new control message.\n//\n// The returned message is large enough for options specified by cf.\nfunc NewControlMessage(cf ControlFlags) []byte {\n\topt := rawOpt{cflags: cf}\n\tvar l int\n\tif opt.isset(FlagTTL) && ctlOpts[ctlTTL].name > 0 {\n\t\tl += socket.ControlMessageSpace(ctlOpts[ctlTTL].length)\n\t}\n\tif ctlOpts[ctlPacketInfo].name > 0 {\n\t\tif opt.isset(FlagSrc | FlagDst | FlagInterface) {\n\t\t\tl += socket.ControlMessageSpace(ctlOpts[ctlPacketInfo].length)\n\t\t}\n\t} else {\n\t\tif opt.isset(FlagDst) && ctlOpts[ctlDst].name > 0 {\n\t\t\tl += socket.ControlMessageSpace(ctlOpts[ctlDst].length)\n\t\t}\n\t\tif opt.isset(FlagInterface) && ctlOpts[ctlInterface].name > 0 {\n\t\t\tl += socket.ControlMessageSpace(ctlOpts[ctlInterface].length)\n\t\t}\n\t}\n\tvar b []byte\n\tif l > 0 {\n\t\tb = make([]byte, l)\n\t}\n\treturn b\n}\n\n// Ancillary data socket options\nconst (\n\tctlTTL        = iota // header field\n\tctlSrc               // header field\n\tctlDst               // header field\n\tctlInterface         // inbound or outbound interface\n\tctlPacketInfo        // inbound or outbound packet path\n\tctlMax\n)\n\n// A ctlOpt represents a binding for ancillary data socket option.\ntype ctlOpt struct {\n\tname    int // option name, must be equal or greater than 1\n\tlength  int // option length\n\tmarshal func([]byte, *ControlMessage) []byte\n\tparse   func(*ControlMessage, []byte)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/control_bsd.go",
    "content": "// Copyright 2012 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd\n\npackage ipv4\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc marshalDst(b []byte, cm *ControlMessage) []byte {\n\tm := socket.ControlMessage(b)\n\tm.MarshalHeader(iana.ProtocolIP, unix.IP_RECVDSTADDR, net.IPv4len)\n\treturn m.Next(net.IPv4len)\n}\n\nfunc parseDst(cm *ControlMessage, b []byte) {\n\tif len(cm.Dst) < net.IPv4len {\n\t\tcm.Dst = make(net.IP, net.IPv4len)\n\t}\n\tcopy(cm.Dst, b[:net.IPv4len])\n}\n\nfunc marshalInterface(b []byte, cm *ControlMessage) []byte {\n\tm := socket.ControlMessage(b)\n\tm.MarshalHeader(iana.ProtocolIP, sockoptReceiveInterface, syscall.SizeofSockaddrDatalink)\n\treturn m.Next(syscall.SizeofSockaddrDatalink)\n}\n\nfunc parseInterface(cm *ControlMessage, b []byte) {\n\tvar sadl syscall.SockaddrDatalink\n\tcopy((*[unsafe.Sizeof(sadl)]byte)(unsafe.Pointer(&sadl))[:], b)\n\tcm.IfIndex = int(sadl.Index)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/control_pktinfo.go",
    "content": "// Copyright 2014 The Go 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\n//go:build darwin || linux || solaris\n\npackage ipv4\n\nimport (\n\t\"net\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc marshalPacketInfo(b []byte, cm *ControlMessage) []byte {\n\tm := socket.ControlMessage(b)\n\tm.MarshalHeader(iana.ProtocolIP, unix.IP_PKTINFO, sizeofInetPktinfo)\n\tif cm != nil {\n\t\tpi := (*inetPktinfo)(unsafe.Pointer(&m.Data(sizeofInetPktinfo)[0]))\n\t\tif ip := cm.Src.To4(); ip != nil {\n\t\t\tcopy(pi.Spec_dst[:], ip)\n\t\t}\n\t\tif cm.IfIndex > 0 {\n\t\t\tpi.setIfindex(cm.IfIndex)\n\t\t}\n\t}\n\treturn m.Next(sizeofInetPktinfo)\n}\n\nfunc parsePacketInfo(cm *ControlMessage, b []byte) {\n\tpi := (*inetPktinfo)(unsafe.Pointer(&b[0]))\n\tcm.IfIndex = int(pi.Ifindex)\n\tif len(cm.Dst) < net.IPv4len {\n\t\tcm.Dst = make(net.IP, net.IPv4len)\n\t}\n\tcopy(cm.Dst, pi.Addr[:])\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/control_stub.go",
    "content": "// Copyright 2012 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos\n\npackage ipv4\n\nimport \"golang.org/x/net/internal/socket\"\n\nfunc setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {\n\treturn errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/control_unix.go",
    "content": "// Copyright 2012 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris\n\npackage ipv4\n\nimport (\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {\n\topt.Lock()\n\tdefer opt.Unlock()\n\tif so, ok := sockOpts[ssoReceiveTTL]; ok && cf&FlagTTL != 0 {\n\t\tif err := so.SetInt(c, boolint(on)); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif on {\n\t\t\topt.set(FlagTTL)\n\t\t} else {\n\t\t\topt.clear(FlagTTL)\n\t\t}\n\t}\n\tif so, ok := sockOpts[ssoPacketInfo]; ok {\n\t\tif cf&(FlagSrc|FlagDst|FlagInterface) != 0 {\n\t\t\tif err := so.SetInt(c, boolint(on)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif on {\n\t\t\t\topt.set(cf & (FlagSrc | FlagDst | FlagInterface))\n\t\t\t} else {\n\t\t\t\topt.clear(cf & (FlagSrc | FlagDst | FlagInterface))\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif so, ok := sockOpts[ssoReceiveDst]; ok && cf&FlagDst != 0 {\n\t\t\tif err := so.SetInt(c, boolint(on)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif on {\n\t\t\t\topt.set(FlagDst)\n\t\t\t} else {\n\t\t\t\topt.clear(FlagDst)\n\t\t\t}\n\t\t}\n\t\tif so, ok := sockOpts[ssoReceiveInterface]; ok && cf&FlagInterface != 0 {\n\t\t\tif err := so.SetInt(c, boolint(on)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif on {\n\t\t\t\topt.set(FlagInterface)\n\t\t\t} else {\n\t\t\t\topt.clear(FlagInterface)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc marshalTTL(b []byte, cm *ControlMessage) []byte {\n\tm := socket.ControlMessage(b)\n\tm.MarshalHeader(iana.ProtocolIP, unix.IP_RECVTTL, 1)\n\treturn m.Next(1)\n}\n\nfunc parseTTL(cm *ControlMessage, b []byte) {\n\tcm.TTL = int(*(*byte)(unsafe.Pointer(&b[:1][0])))\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/control_windows.go",
    "content": "// Copyright 2012 The Go 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 ipv4\n\nimport \"golang.org/x/net/internal/socket\"\n\nfunc setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {\n\t// TODO(mikio): implement this\n\treturn errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/control_zos.go",
    "content": "// Copyright 2020 The Go 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 ipv4\n\nimport (\n\t\"net\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc marshalPacketInfo(b []byte, cm *ControlMessage) []byte {\n\tm := socket.ControlMessage(b)\n\tm.MarshalHeader(iana.ProtocolIP, unix.IP_PKTINFO, sizeofInetPktinfo)\n\tif cm != nil {\n\t\tpi := (*inetPktinfo)(unsafe.Pointer(&m.Data(sizeofInetPktinfo)[0]))\n\t\tif ip := cm.Src.To4(); ip != nil {\n\t\t\tcopy(pi.Addr[:], ip)\n\t\t}\n\t\tif cm.IfIndex > 0 {\n\t\t\tpi.setIfindex(cm.IfIndex)\n\t\t}\n\t}\n\treturn m.Next(sizeofInetPktinfo)\n}\n\nfunc parsePacketInfo(cm *ControlMessage, b []byte) {\n\tpi := (*inetPktinfo)(unsafe.Pointer(&b[0]))\n\tcm.IfIndex = int(pi.Ifindex)\n\tif len(cm.Dst) < net.IPv4len {\n\t\tcm.Dst = make(net.IP, net.IPv4len)\n\t}\n\tcopy(cm.Dst, pi.Addr[:])\n}\n\nfunc setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {\n\topt.Lock()\n\tdefer opt.Unlock()\n\tif so, ok := sockOpts[ssoReceiveTTL]; ok && cf&FlagTTL != 0 {\n\t\tif err := so.SetInt(c, boolint(on)); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif on {\n\t\t\topt.set(FlagTTL)\n\t\t} else {\n\t\t\topt.clear(FlagTTL)\n\t\t}\n\t}\n\tif so, ok := sockOpts[ssoPacketInfo]; ok {\n\t\tif cf&(FlagSrc|FlagDst|FlagInterface) != 0 {\n\t\t\tif err := so.SetInt(c, boolint(on)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif on {\n\t\t\t\topt.set(cf & (FlagSrc | FlagDst | FlagInterface))\n\t\t\t} else {\n\t\t\t\topt.clear(cf & (FlagSrc | FlagDst | FlagInterface))\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif so, ok := sockOpts[ssoReceiveDst]; ok && cf&FlagDst != 0 {\n\t\t\tif err := so.SetInt(c, boolint(on)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif on {\n\t\t\t\topt.set(FlagDst)\n\t\t\t} else {\n\t\t\t\topt.clear(FlagDst)\n\t\t\t}\n\t\t}\n\t\tif so, ok := sockOpts[ssoReceiveInterface]; ok && cf&FlagInterface != 0 {\n\t\t\tif err := so.SetInt(c, boolint(on)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif on {\n\t\t\t\topt.set(FlagInterface)\n\t\t\t} else {\n\t\t\t\topt.clear(FlagInterface)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/dgramopt.go",
    "content": "// Copyright 2012 The Go 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 ipv4\n\nimport (\n\t\"net\"\n\n\t\"golang.org/x/net/bpf\"\n)\n\n// MulticastTTL returns the time-to-live field value for outgoing\n// multicast packets.\nfunc (c *dgramOpt) MulticastTTL() (int, error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoMulticastTTL]\n\tif !ok {\n\t\treturn 0, errNotImplemented\n\t}\n\treturn so.GetInt(c.Conn)\n}\n\n// SetMulticastTTL sets the time-to-live field value for future\n// outgoing multicast packets.\nfunc (c *dgramOpt) SetMulticastTTL(ttl int) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoMulticastTTL]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\treturn so.SetInt(c.Conn, ttl)\n}\n\n// MulticastInterface returns the default interface for multicast\n// packet transmissions.\nfunc (c *dgramOpt) MulticastInterface() (*net.Interface, error) {\n\tif !c.ok() {\n\t\treturn nil, errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoMulticastInterface]\n\tif !ok {\n\t\treturn nil, errNotImplemented\n\t}\n\treturn so.getMulticastInterface(c.Conn)\n}\n\n// SetMulticastInterface sets the default interface for future\n// multicast packet transmissions.\nfunc (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoMulticastInterface]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\treturn so.setMulticastInterface(c.Conn, ifi)\n}\n\n// MulticastLoopback reports whether transmitted multicast packets\n// should be copied and send back to the originator.\nfunc (c *dgramOpt) MulticastLoopback() (bool, error) {\n\tif !c.ok() {\n\t\treturn false, errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoMulticastLoopback]\n\tif !ok {\n\t\treturn false, errNotImplemented\n\t}\n\ton, err := so.GetInt(c.Conn)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\treturn on == 1, nil\n}\n\n// SetMulticastLoopback sets whether transmitted multicast packets\n// should be copied and send back to the originator.\nfunc (c *dgramOpt) SetMulticastLoopback(on bool) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoMulticastLoopback]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\treturn so.SetInt(c.Conn, boolint(on))\n}\n\n// JoinGroup joins the group address group on the interface ifi.\n// By default all sources that can cast data to group are accepted.\n// It's possible to mute and unmute data transmission from a specific\n// source by using ExcludeSourceSpecificGroup and\n// IncludeSourceSpecificGroup.\n// JoinGroup uses the system assigned multicast interface when ifi is\n// nil, although this is not recommended because the assignment\n// depends on platforms and sometimes it might require routing\n// configuration.\nfunc (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoJoinGroup]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\tgrp := netAddrToIP4(group)\n\tif grp == nil {\n\t\treturn errMissingAddress\n\t}\n\treturn so.setGroup(c.Conn, ifi, grp)\n}\n\n// LeaveGroup leaves the group address group on the interface ifi\n// regardless of whether the group is any-source group or\n// source-specific group.\nfunc (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoLeaveGroup]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\tgrp := netAddrToIP4(group)\n\tif grp == nil {\n\t\treturn errMissingAddress\n\t}\n\treturn so.setGroup(c.Conn, ifi, grp)\n}\n\n// JoinSourceSpecificGroup joins the source-specific group comprising\n// group and source on the interface ifi.\n// JoinSourceSpecificGroup uses the system assigned multicast\n// interface when ifi is nil, although this is not recommended because\n// the assignment depends on platforms and sometimes it might require\n// routing configuration.\nfunc (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoJoinSourceGroup]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\tgrp := netAddrToIP4(group)\n\tif grp == nil {\n\t\treturn errMissingAddress\n\t}\n\tsrc := netAddrToIP4(source)\n\tif src == nil {\n\t\treturn errMissingAddress\n\t}\n\treturn so.setSourceGroup(c.Conn, ifi, grp, src)\n}\n\n// LeaveSourceSpecificGroup leaves the source-specific group on the\n// interface ifi.\nfunc (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoLeaveSourceGroup]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\tgrp := netAddrToIP4(group)\n\tif grp == nil {\n\t\treturn errMissingAddress\n\t}\n\tsrc := netAddrToIP4(source)\n\tif src == nil {\n\t\treturn errMissingAddress\n\t}\n\treturn so.setSourceGroup(c.Conn, ifi, grp, src)\n}\n\n// ExcludeSourceSpecificGroup excludes the source-specific group from\n// the already joined any-source groups by JoinGroup on the interface\n// ifi.\nfunc (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoBlockSourceGroup]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\tgrp := netAddrToIP4(group)\n\tif grp == nil {\n\t\treturn errMissingAddress\n\t}\n\tsrc := netAddrToIP4(source)\n\tif src == nil {\n\t\treturn errMissingAddress\n\t}\n\treturn so.setSourceGroup(c.Conn, ifi, grp, src)\n}\n\n// IncludeSourceSpecificGroup includes the excluded source-specific\n// group by ExcludeSourceSpecificGroup again on the interface ifi.\nfunc (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoUnblockSourceGroup]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\tgrp := netAddrToIP4(group)\n\tif grp == nil {\n\t\treturn errMissingAddress\n\t}\n\tsrc := netAddrToIP4(source)\n\tif src == nil {\n\t\treturn errMissingAddress\n\t}\n\treturn so.setSourceGroup(c.Conn, ifi, grp, src)\n}\n\n// ICMPFilter returns an ICMP filter.\n// Currently only Linux supports this.\nfunc (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {\n\tif !c.ok() {\n\t\treturn nil, errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoICMPFilter]\n\tif !ok {\n\t\treturn nil, errNotImplemented\n\t}\n\treturn so.getICMPFilter(c.Conn)\n}\n\n// SetICMPFilter deploys the ICMP filter.\n// Currently only Linux supports this.\nfunc (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoICMPFilter]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\treturn so.setICMPFilter(c.Conn, f)\n}\n\n// SetBPF attaches a BPF program to the connection.\n//\n// Only supported on Linux.\nfunc (c *dgramOpt) SetBPF(filter []bpf.RawInstruction) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoAttachFilter]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\treturn so.setBPF(c.Conn, filter)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/doc.go",
    "content": "// Copyright 2012 The Go 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\n// Package ipv4 implements IP-level socket options for the Internet\n// Protocol version 4.\n//\n// The package provides IP-level socket options that allow\n// manipulation of IPv4 facilities.\n//\n// The IPv4 protocol and basic host requirements for IPv4 are defined\n// in RFC 791 and RFC 1122.\n// Host extensions for multicasting and socket interface extensions\n// for multicast source filters are defined in RFC 1112 and RFC 3678.\n// IGMPv1, IGMPv2 and IGMPv3 are defined in RFC 1112, RFC 2236 and RFC\n// 3376.\n// Source-specific multicast is defined in RFC 4607.\n//\n// # Unicasting\n//\n// The options for unicasting are available for net.TCPConn,\n// net.UDPConn and net.IPConn which are created as network connections\n// that use the IPv4 transport. When a single TCP connection carrying\n// a data flow of multiple packets needs to indicate the flow is\n// important, Conn is used to set the type-of-service field on the\n// IPv4 header for each packet.\n//\n//\tln, err := net.Listen(\"tcp4\", \"0.0.0.0:1024\")\n//\tif err != nil {\n//\t\t// error handling\n//\t}\n//\tdefer ln.Close()\n//\tfor {\n//\t\tc, err := ln.Accept()\n//\t\tif err != nil {\n//\t\t\t// error handling\n//\t\t}\n//\t\tgo func(c net.Conn) {\n//\t\t\tdefer c.Close()\n//\n// The outgoing packets will be labeled DiffServ assured forwarding\n// class 1 low drop precedence, known as AF11 packets.\n//\n//\t\t\tif err := ipv4.NewConn(c).SetTOS(0x28); err != nil {\n//\t\t\t\t// error handling\n//\t\t\t}\n//\t\t\tif _, err := c.Write(data); err != nil {\n//\t\t\t\t// error handling\n//\t\t\t}\n//\t\t}(c)\n//\t}\n//\n// # Multicasting\n//\n// The options for multicasting are available for net.UDPConn and\n// net.IPConn which are created as network connections that use the\n// IPv4 transport. A few network facilities must be prepared before\n// you begin multicasting, at a minimum joining network interfaces and\n// multicast groups.\n//\n//\ten0, err := net.InterfaceByName(\"en0\")\n//\tif err != nil {\n//\t\t// error handling\n//\t}\n//\ten1, err := net.InterfaceByIndex(911)\n//\tif err != nil {\n//\t\t// error handling\n//\t}\n//\tgroup := net.IPv4(224, 0, 0, 250)\n//\n// First, an application listens to an appropriate address with an\n// appropriate service port.\n//\n//\tc, err := net.ListenPacket(\"udp4\", \"0.0.0.0:1024\")\n//\tif err != nil {\n//\t\t// error handling\n//\t}\n//\tdefer c.Close()\n//\n// Second, the application joins multicast groups, starts listening to\n// the groups on the specified network interfaces. Note that the\n// service port for transport layer protocol does not matter with this\n// operation as joining groups affects only network and link layer\n// protocols, such as IPv4 and Ethernet.\n//\n//\tp := ipv4.NewPacketConn(c)\n//\tif err := p.JoinGroup(en0, &net.UDPAddr{IP: group}); err != nil {\n//\t\t// error handling\n//\t}\n//\tif err := p.JoinGroup(en1, &net.UDPAddr{IP: group}); err != nil {\n//\t\t// error handling\n//\t}\n//\n// The application might set per packet control message transmissions\n// between the protocol stack within the kernel. When the application\n// needs a destination address on an incoming packet,\n// SetControlMessage of PacketConn is used to enable control message\n// transmissions.\n//\n//\tif err := p.SetControlMessage(ipv4.FlagDst, true); err != nil {\n//\t\t// error handling\n//\t}\n//\n// The application could identify whether the received packets are\n// of interest by using the control message that contains the\n// destination address of the received packet.\n//\n//\tb := make([]byte, 1500)\n//\tfor {\n//\t\tn, cm, src, err := p.ReadFrom(b)\n//\t\tif err != nil {\n//\t\t\t// error handling\n//\t\t}\n//\t\tif cm.Dst.IsMulticast() {\n//\t\t\tif cm.Dst.Equal(group) {\n//\t\t\t\t// joined group, do something\n//\t\t\t} else {\n//\t\t\t\t// unknown group, discard\n//\t\t\t\tcontinue\n//\t\t\t}\n//\t\t}\n//\n// The application can also send both unicast and multicast packets.\n//\n//\t\tp.SetTOS(0x0)\n//\t\tp.SetTTL(16)\n//\t\tif _, err := p.WriteTo(data, nil, src); err != nil {\n//\t\t\t// error handling\n//\t\t}\n//\t\tdst := &net.UDPAddr{IP: group, Port: 1024}\n//\t\tfor _, ifi := range []*net.Interface{en0, en1} {\n//\t\t\tif err := p.SetMulticastInterface(ifi); err != nil {\n//\t\t\t\t// error handling\n//\t\t\t}\n//\t\t\tp.SetMulticastTTL(2)\n//\t\t\tif _, err := p.WriteTo(data, nil, dst); err != nil {\n//\t\t\t\t// error handling\n//\t\t\t}\n//\t\t}\n//\t}\n//\n// # More multicasting\n//\n// An application that uses PacketConn or RawConn may join multiple\n// multicast groups. For example, a UDP listener with port 1024 might\n// join two different groups across over two different network\n// interfaces by using:\n//\n//\tc, err := net.ListenPacket(\"udp4\", \"0.0.0.0:1024\")\n//\tif err != nil {\n//\t\t// error handling\n//\t}\n//\tdefer c.Close()\n//\tp := ipv4.NewPacketConn(c)\n//\tif err := p.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 248)}); err != nil {\n//\t\t// error handling\n//\t}\n//\tif err := p.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}); err != nil {\n//\t\t// error handling\n//\t}\n//\tif err := p.JoinGroup(en1, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}); err != nil {\n//\t\t// error handling\n//\t}\n//\n// It is possible for multiple UDP listeners that listen on the same\n// UDP port to join the same multicast group. The net package will\n// provide a socket that listens to a wildcard address with reusable\n// UDP port when an appropriate multicast address prefix is passed to\n// the net.ListenPacket or net.ListenUDP.\n//\n//\tc1, err := net.ListenPacket(\"udp4\", \"224.0.0.0:1024\")\n//\tif err != nil {\n//\t\t// error handling\n//\t}\n//\tdefer c1.Close()\n//\tc2, err := net.ListenPacket(\"udp4\", \"224.0.0.0:1024\")\n//\tif err != nil {\n//\t\t// error handling\n//\t}\n//\tdefer c2.Close()\n//\tp1 := ipv4.NewPacketConn(c1)\n//\tif err := p1.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 248)}); err != nil {\n//\t\t// error handling\n//\t}\n//\tp2 := ipv4.NewPacketConn(c2)\n//\tif err := p2.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 248)}); err != nil {\n//\t\t// error handling\n//\t}\n//\n// Also it is possible for the application to leave or rejoin a\n// multicast group on the network interface.\n//\n//\tif err := p.LeaveGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 248)}); err != nil {\n//\t\t// error handling\n//\t}\n//\tif err := p.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 250)}); err != nil {\n//\t\t// error handling\n//\t}\n//\n// # Source-specific multicasting\n//\n// An application that uses PacketConn or RawConn on IGMPv3 supported\n// platform is able to join source-specific multicast groups.\n// The application may use JoinSourceSpecificGroup and\n// LeaveSourceSpecificGroup for the operation known as \"include\" mode,\n//\n//\tssmgroup := net.UDPAddr{IP: net.IPv4(232, 7, 8, 9)}\n//\tssmsource := net.UDPAddr{IP: net.IPv4(192, 168, 0, 1)}\n//\tif err := p.JoinSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil {\n//\t\t// error handling\n//\t}\n//\tif err := p.LeaveSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil {\n//\t\t// error handling\n//\t}\n//\n// or JoinGroup, ExcludeSourceSpecificGroup,\n// IncludeSourceSpecificGroup and LeaveGroup for the operation known\n// as \"exclude\" mode.\n//\n//\texclsource := net.UDPAddr{IP: net.IPv4(192, 168, 0, 254)}\n//\tif err := p.JoinGroup(en0, &ssmgroup); err != nil {\n//\t\t// error handling\n//\t}\n//\tif err := p.ExcludeSourceSpecificGroup(en0, &ssmgroup, &exclsource); err != nil {\n//\t\t// error handling\n//\t}\n//\tif err := p.LeaveGroup(en0, &ssmgroup); err != nil {\n//\t\t// error handling\n//\t}\n//\n// Note that it depends on each platform implementation what happens\n// when an application which runs on IGMPv3 unsupported platform uses\n// JoinSourceSpecificGroup and LeaveSourceSpecificGroup.\n// In general the platform tries to fall back to conversations using\n// IGMPv1 or IGMPv2 and starts to listen to multicast traffic.\n// In the fallback case, ExcludeSourceSpecificGroup and\n// IncludeSourceSpecificGroup may return an error.\npackage ipv4 // import \"golang.org/x/net/ipv4\"\n\n// BUG(mikio): This package is not implemented on JS, NaCl and Plan 9.\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/endpoint.go",
    "content": "// Copyright 2012 The Go 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 ipv4\n\nimport (\n\t\"net\"\n\t\"time\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\n// BUG(mikio): On Windows, the JoinSourceSpecificGroup,\n// LeaveSourceSpecificGroup, ExcludeSourceSpecificGroup and\n// IncludeSourceSpecificGroup methods of PacketConn and RawConn are\n// not implemented.\n\n// A Conn represents a network endpoint that uses the IPv4 transport.\n// It is used to control basic IP-level socket options such as TOS and\n// TTL.\ntype Conn struct {\n\tgenericOpt\n}\n\ntype genericOpt struct {\n\t*socket.Conn\n}\n\nfunc (c *genericOpt) ok() bool { return c != nil && c.Conn != nil }\n\n// NewConn returns a new Conn.\nfunc NewConn(c net.Conn) *Conn {\n\tcc, _ := socket.NewConn(c)\n\treturn &Conn{\n\t\tgenericOpt: genericOpt{Conn: cc},\n\t}\n}\n\n// A PacketConn represents a packet network endpoint that uses the\n// IPv4 transport. It is used to control several IP-level socket\n// options including multicasting. It also provides datagram based\n// network I/O methods specific to the IPv4 and higher layer protocols\n// such as UDP.\ntype PacketConn struct {\n\tgenericOpt\n\tdgramOpt\n\tpayloadHandler\n}\n\ntype dgramOpt struct {\n\t*socket.Conn\n}\n\nfunc (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil }\n\n// SetControlMessage sets the per packet IP-level socket options.\nfunc (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {\n\tif !c.payloadHandler.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on)\n}\n\n// SetDeadline sets the read and write deadlines associated with the\n// endpoint.\nfunc (c *PacketConn) SetDeadline(t time.Time) error {\n\tif !c.payloadHandler.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn c.payloadHandler.PacketConn.SetDeadline(t)\n}\n\n// SetReadDeadline sets the read deadline associated with the\n// endpoint.\nfunc (c *PacketConn) SetReadDeadline(t time.Time) error {\n\tif !c.payloadHandler.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn c.payloadHandler.PacketConn.SetReadDeadline(t)\n}\n\n// SetWriteDeadline sets the write deadline associated with the\n// endpoint.\nfunc (c *PacketConn) SetWriteDeadline(t time.Time) error {\n\tif !c.payloadHandler.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn c.payloadHandler.PacketConn.SetWriteDeadline(t)\n}\n\n// Close closes the endpoint.\nfunc (c *PacketConn) Close() error {\n\tif !c.payloadHandler.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn c.payloadHandler.PacketConn.Close()\n}\n\n// NewPacketConn returns a new PacketConn using c as its underlying\n// transport.\nfunc NewPacketConn(c net.PacketConn) *PacketConn {\n\tcc, _ := socket.NewConn(c.(net.Conn))\n\tp := &PacketConn{\n\t\tgenericOpt:     genericOpt{Conn: cc},\n\t\tdgramOpt:       dgramOpt{Conn: cc},\n\t\tpayloadHandler: payloadHandler{PacketConn: c, Conn: cc},\n\t}\n\treturn p\n}\n\n// A RawConn represents a packet network endpoint that uses the IPv4\n// transport. It is used to control several IP-level socket options\n// including IPv4 header manipulation. It also provides datagram\n// based network I/O methods specific to the IPv4 and higher layer\n// protocols that handle IPv4 datagram directly such as OSPF, GRE.\ntype RawConn struct {\n\tgenericOpt\n\tdgramOpt\n\tpacketHandler\n}\n\n// SetControlMessage sets the per packet IP-level socket options.\nfunc (c *RawConn) SetControlMessage(cf ControlFlags, on bool) error {\n\tif !c.packetHandler.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn setControlMessage(c.dgramOpt.Conn, &c.packetHandler.rawOpt, cf, on)\n}\n\n// SetDeadline sets the read and write deadlines associated with the\n// endpoint.\nfunc (c *RawConn) SetDeadline(t time.Time) error {\n\tif !c.packetHandler.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn c.packetHandler.IPConn.SetDeadline(t)\n}\n\n// SetReadDeadline sets the read deadline associated with the\n// endpoint.\nfunc (c *RawConn) SetReadDeadline(t time.Time) error {\n\tif !c.packetHandler.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn c.packetHandler.IPConn.SetReadDeadline(t)\n}\n\n// SetWriteDeadline sets the write deadline associated with the\n// endpoint.\nfunc (c *RawConn) SetWriteDeadline(t time.Time) error {\n\tif !c.packetHandler.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn c.packetHandler.IPConn.SetWriteDeadline(t)\n}\n\n// Close closes the endpoint.\nfunc (c *RawConn) Close() error {\n\tif !c.packetHandler.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn c.packetHandler.IPConn.Close()\n}\n\n// NewRawConn returns a new RawConn using c as its underlying\n// transport.\nfunc NewRawConn(c net.PacketConn) (*RawConn, error) {\n\tcc, err := socket.NewConn(c.(net.Conn))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tr := &RawConn{\n\t\tgenericOpt:    genericOpt{Conn: cc},\n\t\tdgramOpt:      dgramOpt{Conn: cc},\n\t\tpacketHandler: packetHandler{IPConn: c.(*net.IPConn), Conn: cc},\n\t}\n\tso, ok := sockOpts[ssoHeaderPrepend]\n\tif !ok {\n\t\treturn nil, errNotImplemented\n\t}\n\tif err := so.SetInt(r.dgramOpt.Conn, boolint(true)); err != nil {\n\t\treturn nil, err\n\t}\n\treturn r, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/genericopt.go",
    "content": "// Copyright 2012 The Go 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 ipv4\n\n// TOS returns the type-of-service field value for outgoing packets.\nfunc (c *genericOpt) TOS() (int, error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoTOS]\n\tif !ok {\n\t\treturn 0, errNotImplemented\n\t}\n\treturn so.GetInt(c.Conn)\n}\n\n// SetTOS sets the type-of-service field value for future outgoing\n// packets.\nfunc (c *genericOpt) SetTOS(tos int) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoTOS]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\treturn so.SetInt(c.Conn, tos)\n}\n\n// TTL returns the time-to-live field value for outgoing packets.\nfunc (c *genericOpt) TTL() (int, error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoTTL]\n\tif !ok {\n\t\treturn 0, errNotImplemented\n\t}\n\treturn so.GetInt(c.Conn)\n}\n\n// SetTTL sets the time-to-live field value for future outgoing\n// packets.\nfunc (c *genericOpt) SetTTL(ttl int) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoTTL]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\treturn so.SetInt(c.Conn, ttl)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/header.go",
    "content": "// Copyright 2012 The Go 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 ipv4\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"net\"\n\t\"runtime\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\nconst (\n\tVersion   = 4  // protocol version\n\tHeaderLen = 20 // header length without extension headers\n)\n\ntype HeaderFlags int\n\nconst (\n\tMoreFragments HeaderFlags = 1 << iota // more fragments flag\n\tDontFragment                          // don't fragment flag\n)\n\n// A Header represents an IPv4 header.\ntype Header struct {\n\tVersion  int         // protocol version\n\tLen      int         // header length\n\tTOS      int         // type-of-service\n\tTotalLen int         // packet total length\n\tID       int         // identification\n\tFlags    HeaderFlags // flags\n\tFragOff  int         // fragment offset\n\tTTL      int         // time-to-live\n\tProtocol int         // next protocol\n\tChecksum int         // checksum\n\tSrc      net.IP      // source address\n\tDst      net.IP      // destination address\n\tOptions  []byte      // options, extension headers\n}\n\nfunc (h *Header) String() string {\n\tif h == nil {\n\t\treturn \"<nil>\"\n\t}\n\treturn fmt.Sprintf(\"ver=%d hdrlen=%d tos=%#x totallen=%d id=%#x flags=%#x fragoff=%#x ttl=%d proto=%d cksum=%#x src=%v dst=%v\", h.Version, h.Len, h.TOS, h.TotalLen, h.ID, h.Flags, h.FragOff, h.TTL, h.Protocol, h.Checksum, h.Src, h.Dst)\n}\n\n// Marshal returns the binary encoding of h.\n//\n// The returned slice is in the format used by a raw IP socket on the\n// local system.\n// This may differ from the wire format, depending on the system.\nfunc (h *Header) Marshal() ([]byte, error) {\n\tif h == nil {\n\t\treturn nil, errNilHeader\n\t}\n\tif h.Len < HeaderLen {\n\t\treturn nil, errHeaderTooShort\n\t}\n\thdrlen := HeaderLen + len(h.Options)\n\tb := make([]byte, hdrlen)\n\tb[0] = byte(Version<<4 | (hdrlen >> 2 & 0x0f))\n\tb[1] = byte(h.TOS)\n\tflagsAndFragOff := (h.FragOff & 0x1fff) | int(h.Flags<<13)\n\tswitch runtime.GOOS {\n\tcase \"darwin\", \"ios\", \"dragonfly\", \"netbsd\":\n\t\tsocket.NativeEndian.PutUint16(b[2:4], uint16(h.TotalLen))\n\t\tsocket.NativeEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))\n\tcase \"freebsd\":\n\t\tif freebsdVersion < 1100000 {\n\t\t\tsocket.NativeEndian.PutUint16(b[2:4], uint16(h.TotalLen))\n\t\t\tsocket.NativeEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))\n\t\t} else {\n\t\t\tbinary.BigEndian.PutUint16(b[2:4], uint16(h.TotalLen))\n\t\t\tbinary.BigEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))\n\t\t}\n\tdefault:\n\t\tbinary.BigEndian.PutUint16(b[2:4], uint16(h.TotalLen))\n\t\tbinary.BigEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))\n\t}\n\tbinary.BigEndian.PutUint16(b[4:6], uint16(h.ID))\n\tb[8] = byte(h.TTL)\n\tb[9] = byte(h.Protocol)\n\tbinary.BigEndian.PutUint16(b[10:12], uint16(h.Checksum))\n\tif ip := h.Src.To4(); ip != nil {\n\t\tcopy(b[12:16], ip[:net.IPv4len])\n\t}\n\tif ip := h.Dst.To4(); ip != nil {\n\t\tcopy(b[16:20], ip[:net.IPv4len])\n\t} else {\n\t\treturn nil, errMissingAddress\n\t}\n\tif len(h.Options) > 0 {\n\t\tcopy(b[HeaderLen:], h.Options)\n\t}\n\treturn b, nil\n}\n\n// Parse parses b as an IPv4 header and stores the result in h.\n//\n// The provided b must be in the format used by a raw IP socket on the\n// local system.\n// This may differ from the wire format, depending on the system.\nfunc (h *Header) Parse(b []byte) error {\n\tif h == nil || b == nil {\n\t\treturn errNilHeader\n\t}\n\tif len(b) < HeaderLen {\n\t\treturn errHeaderTooShort\n\t}\n\thdrlen := int(b[0]&0x0f) << 2\n\tif len(b) < hdrlen {\n\t\treturn errExtHeaderTooShort\n\t}\n\th.Version = int(b[0] >> 4)\n\th.Len = hdrlen\n\th.TOS = int(b[1])\n\th.ID = int(binary.BigEndian.Uint16(b[4:6]))\n\th.TTL = int(b[8])\n\th.Protocol = int(b[9])\n\th.Checksum = int(binary.BigEndian.Uint16(b[10:12]))\n\th.Src = net.IPv4(b[12], b[13], b[14], b[15])\n\th.Dst = net.IPv4(b[16], b[17], b[18], b[19])\n\tswitch runtime.GOOS {\n\tcase \"darwin\", \"ios\", \"dragonfly\", \"netbsd\":\n\t\th.TotalLen = int(socket.NativeEndian.Uint16(b[2:4])) + hdrlen\n\t\th.FragOff = int(socket.NativeEndian.Uint16(b[6:8]))\n\tcase \"freebsd\":\n\t\tif freebsdVersion < 1100000 {\n\t\t\th.TotalLen = int(socket.NativeEndian.Uint16(b[2:4]))\n\t\t\tif freebsdVersion < 1000000 {\n\t\t\t\th.TotalLen += hdrlen\n\t\t\t}\n\t\t\th.FragOff = int(socket.NativeEndian.Uint16(b[6:8]))\n\t\t} else {\n\t\t\th.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))\n\t\t\th.FragOff = int(binary.BigEndian.Uint16(b[6:8]))\n\t\t}\n\tdefault:\n\t\th.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))\n\t\th.FragOff = int(binary.BigEndian.Uint16(b[6:8]))\n\t}\n\th.Flags = HeaderFlags(h.FragOff&0xe000) >> 13\n\th.FragOff = h.FragOff & 0x1fff\n\toptlen := hdrlen - HeaderLen\n\tif optlen > 0 && len(b) >= hdrlen {\n\t\tif cap(h.Options) < optlen {\n\t\t\th.Options = make([]byte, optlen)\n\t\t} else {\n\t\t\th.Options = h.Options[:optlen]\n\t\t}\n\t\tcopy(h.Options, b[HeaderLen:hdrlen])\n\t}\n\treturn nil\n}\n\n// ParseHeader parses b as an IPv4 header.\n//\n// The provided b must be in the format used by a raw IP socket on the\n// local system.\n// This may differ from the wire format, depending on the system.\nfunc ParseHeader(b []byte) (*Header, error) {\n\th := new(Header)\n\tif err := h.Parse(b); err != nil {\n\t\treturn nil, err\n\t}\n\treturn h, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/helper.go",
    "content": "// Copyright 2012 The Go 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 ipv4\n\nimport (\n\t\"errors\"\n\t\"net\"\n\t\"runtime\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\nvar (\n\terrInvalidConn       = errors.New(\"invalid connection\")\n\terrMissingAddress    = errors.New(\"missing address\")\n\terrNilHeader         = errors.New(\"nil header\")\n\terrHeaderTooShort    = errors.New(\"header too short\")\n\terrExtHeaderTooShort = errors.New(\"extension header too short\")\n\terrInvalidConnType   = errors.New(\"invalid conn type\")\n\terrNotImplemented    = errors.New(\"not implemented on \" + runtime.GOOS + \"/\" + runtime.GOARCH)\n\n\t// See https://www.freebsd.org/doc/en/books/porters-handbook/versions.html.\n\tfreebsdVersion  uint32\n\tcompatFreeBSD32 bool // 386 emulation on amd64\n)\n\n// See golang.org/issue/30899.\nfunc adjustFreeBSD32(m *socket.Message) {\n\t// FreeBSD 12.0-RELEASE is affected by https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236737\n\tif 1200086 <= freebsdVersion && freebsdVersion < 1201000 {\n\t\tl := (m.NN + 4 - 1) &^ (4 - 1)\n\t\tif m.NN < l && l <= len(m.OOB) {\n\t\t\tm.NN = l\n\t\t}\n\t}\n}\n\nfunc boolint(b bool) int {\n\tif b {\n\t\treturn 1\n\t}\n\treturn 0\n}\n\nfunc netAddrToIP4(a net.Addr) net.IP {\n\tswitch v := a.(type) {\n\tcase *net.UDPAddr:\n\t\tif ip := v.IP.To4(); ip != nil {\n\t\t\treturn ip\n\t\t}\n\tcase *net.IPAddr:\n\t\tif ip := v.IP.To4(); ip != nil {\n\t\t\treturn ip\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc opAddr(a net.Addr) net.Addr {\n\tswitch a.(type) {\n\tcase *net.TCPAddr:\n\t\tif a == nil {\n\t\t\treturn nil\n\t\t}\n\tcase *net.UDPAddr:\n\t\tif a == nil {\n\t\t\treturn nil\n\t\t}\n\tcase *net.IPAddr:\n\t\tif a == nil {\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn a\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/iana.go",
    "content": "// go generate gen.go\n// Code generated by the command above; DO NOT EDIT.\n\npackage ipv4\n\n// Internet Control Message Protocol (ICMP) Parameters, Updated: 2018-02-26\nconst (\n\tICMPTypeEchoReply              ICMPType = 0  // Echo Reply\n\tICMPTypeDestinationUnreachable ICMPType = 3  // Destination Unreachable\n\tICMPTypeRedirect               ICMPType = 5  // Redirect\n\tICMPTypeEcho                   ICMPType = 8  // Echo\n\tICMPTypeRouterAdvertisement    ICMPType = 9  // Router Advertisement\n\tICMPTypeRouterSolicitation     ICMPType = 10 // Router Solicitation\n\tICMPTypeTimeExceeded           ICMPType = 11 // Time Exceeded\n\tICMPTypeParameterProblem       ICMPType = 12 // Parameter Problem\n\tICMPTypeTimestamp              ICMPType = 13 // Timestamp\n\tICMPTypeTimestampReply         ICMPType = 14 // Timestamp Reply\n\tICMPTypePhoturis               ICMPType = 40 // Photuris\n\tICMPTypeExtendedEchoRequest    ICMPType = 42 // Extended Echo Request\n\tICMPTypeExtendedEchoReply      ICMPType = 43 // Extended Echo Reply\n)\n\n// Internet Control Message Protocol (ICMP) Parameters, Updated: 2018-02-26\nvar icmpTypes = map[ICMPType]string{\n\t0:  \"echo reply\",\n\t3:  \"destination unreachable\",\n\t5:  \"redirect\",\n\t8:  \"echo\",\n\t9:  \"router advertisement\",\n\t10: \"router solicitation\",\n\t11: \"time exceeded\",\n\t12: \"parameter problem\",\n\t13: \"timestamp\",\n\t14: \"timestamp reply\",\n\t40: \"photuris\",\n\t42: \"extended echo request\",\n\t43: \"extended echo reply\",\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/icmp.go",
    "content": "// Copyright 2013 The Go 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 ipv4\n\nimport \"golang.org/x/net/internal/iana\"\n\n// An ICMPType represents a type of ICMP message.\ntype ICMPType int\n\nfunc (typ ICMPType) String() string {\n\ts, ok := icmpTypes[typ]\n\tif !ok {\n\t\treturn \"<nil>\"\n\t}\n\treturn s\n}\n\n// Protocol returns the ICMPv4 protocol number.\nfunc (typ ICMPType) Protocol() int {\n\treturn iana.ProtocolICMP\n}\n\n// An ICMPFilter represents an ICMP message filter for incoming\n// packets. The filter belongs to a packet delivery path on a host and\n// it cannot interact with forwarding packets or tunnel-outer packets.\n//\n// Note: RFC 8200 defines a reasonable role model and it works not\n// only for IPv6 but IPv4. A node means a device that implements IP.\n// A router means a node that forwards IP packets not explicitly\n// addressed to itself, and a host means a node that is not a router.\ntype ICMPFilter struct {\n\ticmpFilter\n}\n\n// Accept accepts incoming ICMP packets including the type field value\n// typ.\nfunc (f *ICMPFilter) Accept(typ ICMPType) {\n\tf.accept(typ)\n}\n\n// Block blocks incoming ICMP packets including the type field value\n// typ.\nfunc (f *ICMPFilter) Block(typ ICMPType) {\n\tf.block(typ)\n}\n\n// SetAll sets the filter action to the filter.\nfunc (f *ICMPFilter) SetAll(block bool) {\n\tf.setAll(block)\n}\n\n// WillBlock reports whether the ICMP type will be blocked.\nfunc (f *ICMPFilter) WillBlock(typ ICMPType) bool {\n\treturn f.willBlock(typ)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/icmp_linux.go",
    "content": "// Copyright 2014 The Go 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 ipv4\n\nfunc (f *icmpFilter) accept(typ ICMPType) {\n\tf.Data &^= 1 << (uint32(typ) & 31)\n}\n\nfunc (f *icmpFilter) block(typ ICMPType) {\n\tf.Data |= 1 << (uint32(typ) & 31)\n}\n\nfunc (f *icmpFilter) setAll(block bool) {\n\tif block {\n\t\tf.Data = 1<<32 - 1\n\t} else {\n\t\tf.Data = 0\n\t}\n}\n\nfunc (f *icmpFilter) willBlock(typ ICMPType) bool {\n\treturn f.Data&(1<<(uint32(typ)&31)) != 0\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/icmp_stub.go",
    "content": "// Copyright 2014 The Go 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\n//go:build !linux\n\npackage ipv4\n\nconst sizeofICMPFilter = 0x0\n\ntype icmpFilter struct {\n}\n\nfunc (f *icmpFilter) accept(typ ICMPType) {\n}\n\nfunc (f *icmpFilter) block(typ ICMPType) {\n}\n\nfunc (f *icmpFilter) setAll(block bool) {\n}\n\nfunc (f *icmpFilter) willBlock(typ ICMPType) bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/packet.go",
    "content": "// Copyright 2012 The Go 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 ipv4\n\nimport (\n\t\"net\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\n// BUG(mikio): On Windows, the ReadFrom and WriteTo methods of RawConn\n// are not implemented.\n\n// A packetHandler represents the IPv4 datagram handler.\ntype packetHandler struct {\n\t*net.IPConn\n\t*socket.Conn\n\trawOpt\n}\n\nfunc (c *packetHandler) ok() bool { return c != nil && c.IPConn != nil && c.Conn != nil }\n\n// ReadFrom reads an IPv4 datagram from the endpoint c, copying the\n// datagram into b. It returns the received datagram as the IPv4\n// header h, the payload p and the control message cm.\nfunc (c *packetHandler) ReadFrom(b []byte) (h *Header, p []byte, cm *ControlMessage, err error) {\n\tif !c.ok() {\n\t\treturn nil, nil, nil, errInvalidConn\n\t}\n\tc.rawOpt.RLock()\n\tm := socket.Message{\n\t\tBuffers: [][]byte{b},\n\t\tOOB:     NewControlMessage(c.rawOpt.cflags),\n\t}\n\tc.rawOpt.RUnlock()\n\tif err := c.RecvMsg(&m, 0); err != nil {\n\t\treturn nil, nil, nil, &net.OpError{Op: \"read\", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}\n\t}\n\tvar hs []byte\n\tif hs, p, err = slicePacket(b[:m.N]); err != nil {\n\t\treturn nil, nil, nil, &net.OpError{Op: \"read\", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}\n\t}\n\tif h, err = ParseHeader(hs); err != nil {\n\t\treturn nil, nil, nil, &net.OpError{Op: \"read\", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}\n\t}\n\tif m.NN > 0 {\n\t\tif compatFreeBSD32 {\n\t\t\tadjustFreeBSD32(&m)\n\t\t}\n\t\tcm = new(ControlMessage)\n\t\tif err := cm.Parse(m.OOB[:m.NN]); err != nil {\n\t\t\treturn nil, nil, nil, &net.OpError{Op: \"read\", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}\n\t\t}\n\t}\n\tif src, ok := m.Addr.(*net.IPAddr); ok && cm != nil {\n\t\tcm.Src = src.IP\n\t}\n\treturn\n}\n\nfunc slicePacket(b []byte) (h, p []byte, err error) {\n\tif len(b) < HeaderLen {\n\t\treturn nil, nil, errHeaderTooShort\n\t}\n\thdrlen := int(b[0]&0x0f) << 2\n\treturn b[:hdrlen], b[hdrlen:], nil\n}\n\n// WriteTo writes an IPv4 datagram through the endpoint c, copying the\n// datagram from the IPv4 header h and the payload p. The control\n// message cm allows the datagram path and the outgoing interface to be\n// specified.  Currently only Darwin and Linux support this. The cm\n// may be nil if control of the outgoing datagram is not required.\n//\n// The IPv4 header h must contain appropriate fields that include:\n//\n//\tVersion       = <must be specified>\n//\tLen           = <must be specified>\n//\tTOS           = <must be specified>\n//\tTotalLen      = <must be specified>\n//\tID            = platform sets an appropriate value if ID is zero\n//\tFragOff       = <must be specified>\n//\tTTL           = <must be specified>\n//\tProtocol      = <must be specified>\n//\tChecksum      = platform sets an appropriate value if Checksum is zero\n//\tSrc           = platform sets an appropriate value if Src is nil\n//\tDst           = <must be specified>\n//\tOptions       = optional\nfunc (c *packetHandler) WriteTo(h *Header, p []byte, cm *ControlMessage) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tm := socket.Message{\n\t\tOOB: cm.Marshal(),\n\t}\n\twh, err := h.Marshal()\n\tif err != nil {\n\t\treturn err\n\t}\n\tm.Buffers = [][]byte{wh, p}\n\tdst := new(net.IPAddr)\n\tif cm != nil {\n\t\tif ip := cm.Dst.To4(); ip != nil {\n\t\t\tdst.IP = ip\n\t\t}\n\t}\n\tif dst.IP == nil {\n\t\tdst.IP = h.Dst\n\t}\n\tm.Addr = dst\n\tif err := c.SendMsg(&m, 0); err != nil {\n\t\treturn &net.OpError{Op: \"write\", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Addr: opAddr(dst), Err: err}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/payload.go",
    "content": "// Copyright 2012 The Go 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 ipv4\n\nimport (\n\t\"net\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\n// BUG(mikio): On Windows, the ControlMessage for ReadFrom and WriteTo\n// methods of PacketConn is not implemented.\n\n// A payloadHandler represents the IPv4 datagram payload handler.\ntype payloadHandler struct {\n\tnet.PacketConn\n\t*socket.Conn\n\trawOpt\n}\n\nfunc (c *payloadHandler) ok() bool { return c != nil && c.PacketConn != nil && c.Conn != nil }\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/payload_cmsg.go",
    "content": "// Copyright 2012 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\npackage ipv4\n\nimport (\n\t\"net\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\n// ReadFrom reads a payload of the received IPv4 datagram, from the\n// endpoint c, copying the payload into b. It returns the number of\n// bytes copied into b, the control message cm and the source address\n// src of the received datagram.\nfunc (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {\n\tif !c.ok() {\n\t\treturn 0, nil, nil, errInvalidConn\n\t}\n\tc.rawOpt.RLock()\n\tm := socket.Message{\n\t\tOOB: NewControlMessage(c.rawOpt.cflags),\n\t}\n\tc.rawOpt.RUnlock()\n\tswitch c.PacketConn.(type) {\n\tcase *net.UDPConn:\n\t\tm.Buffers = [][]byte{b}\n\t\tif err := c.RecvMsg(&m, 0); err != nil {\n\t\t\treturn 0, nil, nil, &net.OpError{Op: \"read\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}\n\t\t}\n\tcase *net.IPConn:\n\t\th := make([]byte, HeaderLen)\n\t\tm.Buffers = [][]byte{h, b}\n\t\tif err := c.RecvMsg(&m, 0); err != nil {\n\t\t\treturn 0, nil, nil, &net.OpError{Op: \"read\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}\n\t\t}\n\t\thdrlen := int(h[0]&0x0f) << 2\n\t\tif hdrlen > len(h) {\n\t\t\td := hdrlen - len(h)\n\t\t\tcopy(b, b[d:])\n\t\t\tm.N -= d\n\t\t} else {\n\t\t\tm.N -= hdrlen\n\t\t}\n\tdefault:\n\t\treturn 0, nil, nil, &net.OpError{Op: \"read\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errInvalidConnType}\n\t}\n\tif m.NN > 0 {\n\t\tif compatFreeBSD32 {\n\t\t\tadjustFreeBSD32(&m)\n\t\t}\n\t\tcm = new(ControlMessage)\n\t\tif err := cm.Parse(m.OOB[:m.NN]); err != nil {\n\t\t\treturn 0, nil, nil, &net.OpError{Op: \"read\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}\n\t\t}\n\t\tcm.Src = netAddrToIP4(m.Addr)\n\t}\n\treturn m.N, cm, m.Addr, nil\n}\n\n// WriteTo writes a payload of the IPv4 datagram, to the destination\n// address dst through the endpoint c, copying the payload from b. It\n// returns the number of bytes written. The control message cm allows\n// the datagram path and the outgoing interface to be specified.\n// Currently only Darwin and Linux support this. The cm may be nil if\n// control of the outgoing datagram is not required.\nfunc (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\tm := socket.Message{\n\t\tBuffers: [][]byte{b},\n\t\tOOB:     cm.Marshal(),\n\t\tAddr:    dst,\n\t}\n\terr = c.SendMsg(&m, 0)\n\tif err != nil {\n\t\terr = &net.OpError{Op: \"write\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Addr: opAddr(dst), Err: err}\n\t}\n\treturn m.N, err\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/payload_nocmsg.go",
    "content": "// Copyright 2012 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos\n\npackage ipv4\n\nimport \"net\"\n\n// ReadFrom reads a payload of the received IPv4 datagram, from the\n// endpoint c, copying the payload into b. It returns the number of\n// bytes copied into b, the control message cm and the source address\n// src of the received datagram.\nfunc (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {\n\tif !c.ok() {\n\t\treturn 0, nil, nil, errInvalidConn\n\t}\n\tif n, src, err = c.PacketConn.ReadFrom(b); err != nil {\n\t\treturn 0, nil, nil, err\n\t}\n\treturn\n}\n\n// WriteTo writes a payload of the IPv4 datagram, to the destination\n// address dst through the endpoint c, copying the payload from b. It\n// returns the number of bytes written. The control message cm allows\n// the datagram path and the outgoing interface to be specified.\n// Currently only Darwin and Linux support this. The cm may be nil if\n// control of the outgoing datagram is not required.\nfunc (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\tif dst == nil {\n\t\treturn 0, errMissingAddress\n\t}\n\treturn c.PacketConn.WriteTo(b, dst)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sockopt.go",
    "content": "// Copyright 2014 The Go 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 ipv4\n\nimport \"golang.org/x/net/internal/socket\"\n\n// Sticky socket options\nconst (\n\tssoTOS                = iota // header field for unicast packet\n\tssoTTL                       // header field for unicast packet\n\tssoMulticastTTL              // header field for multicast packet\n\tssoMulticastInterface        // outbound interface for multicast packet\n\tssoMulticastLoopback         // loopback for multicast packet\n\tssoReceiveTTL                // header field on received packet\n\tssoReceiveDst                // header field on received packet\n\tssoReceiveInterface          // inbound interface on received packet\n\tssoPacketInfo                // incbound or outbound packet path\n\tssoHeaderPrepend             // ipv4 header prepend\n\tssoStripHeader               // strip ipv4 header\n\tssoICMPFilter                // icmp filter\n\tssoJoinGroup                 // any-source multicast\n\tssoLeaveGroup                // any-source multicast\n\tssoJoinSourceGroup           // source-specific multicast\n\tssoLeaveSourceGroup          // source-specific multicast\n\tssoBlockSourceGroup          // any-source or source-specific multicast\n\tssoUnblockSourceGroup        // any-source or source-specific multicast\n\tssoAttachFilter              // attach BPF for filtering inbound traffic\n)\n\n// Sticky socket option value types\nconst (\n\tssoTypeIPMreq = iota + 1\n\tssoTypeIPMreqn\n\tssoTypeGroupReq\n\tssoTypeGroupSourceReq\n)\n\n// A sockOpt represents a binding for sticky socket option.\ntype sockOpt struct {\n\tsocket.Option\n\ttyp int // hint for option value type; optional\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sockopt_posix.go",
    "content": "// Copyright 2012 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos\n\npackage ipv4\n\nimport (\n\t\"net\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/bpf\"\n\t\"golang.org/x/net/internal/socket\"\n)\n\nfunc (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) {\n\tswitch so.typ {\n\tcase ssoTypeIPMreqn:\n\t\treturn so.getIPMreqn(c)\n\tdefault:\n\t\treturn so.getMulticastIf(c)\n\t}\n}\n\nfunc (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error {\n\tswitch so.typ {\n\tcase ssoTypeIPMreqn:\n\t\treturn so.setIPMreqn(c, ifi, nil)\n\tdefault:\n\t\treturn so.setMulticastIf(c, ifi)\n\t}\n}\n\nfunc (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) {\n\tb := make([]byte, so.Len)\n\tn, err := so.Get(c, b)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif n != sizeofICMPFilter {\n\t\treturn nil, errNotImplemented\n\t}\n\treturn (*ICMPFilter)(unsafe.Pointer(&b[0])), nil\n}\n\nfunc (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error {\n\tb := (*[sizeofICMPFilter]byte)(unsafe.Pointer(f))[:sizeofICMPFilter]\n\treturn so.Set(c, b)\n}\n\nfunc (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error {\n\tswitch so.typ {\n\tcase ssoTypeIPMreq:\n\t\treturn so.setIPMreq(c, ifi, grp)\n\tcase ssoTypeIPMreqn:\n\t\treturn so.setIPMreqn(c, ifi, grp)\n\tcase ssoTypeGroupReq:\n\t\treturn so.setGroupReq(c, ifi, grp)\n\tdefault:\n\t\treturn errNotImplemented\n\t}\n}\n\nfunc (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {\n\treturn so.setGroupSourceReq(c, ifi, grp, src)\n}\n\nfunc (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error {\n\treturn so.setAttachFilter(c, f)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sockopt_stub.go",
    "content": "// Copyright 2012 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos\n\npackage ipv4\n\nimport (\n\t\"net\"\n\n\t\"golang.org/x/net/bpf\"\n\t\"golang.org/x/net/internal/socket\"\n)\n\nfunc (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) {\n\treturn nil, errNotImplemented\n}\n\nfunc (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error {\n\treturn errNotImplemented\n}\n\nfunc (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) {\n\treturn nil, errNotImplemented\n}\n\nfunc (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error {\n\treturn errNotImplemented\n}\n\nfunc (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error {\n\treturn errNotImplemented\n}\n\nfunc (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {\n\treturn errNotImplemented\n}\n\nfunc (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error {\n\treturn errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_aix.go",
    "content": "// Copyright 2019 The Go 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\n// Added for go1.11 compatibility\n//go:build aix\n\npackage ipv4\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\n// IP_RECVIF is defined on AIX but doesn't work. IP_RECVINTERFACE must be used instead.\nconst sockoptReceiveInterface = unix.IP_RECVINTERFACE\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{\n\t\tctlTTL:       {unix.IP_RECVTTL, 1, marshalTTL, parseTTL},\n\t\tctlDst:       {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},\n\t\tctlInterface: {unix.IP_RECVINTERFACE, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},\n\t}\n\n\tsockOpts = map[int]*sockOpt{\n\t\tssoTOS:                {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},\n\t\tssoTTL:                {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},\n\t\tssoMulticastTTL:       {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},\n\t\tssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},\n\t\tssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 1}},\n\t\tssoReceiveTTL:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},\n\t\tssoReceiveDst:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}},\n\t\tssoReceiveInterface:   {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVINTERFACE, Len: 4}},\n\t\tssoHeaderPrepend:      {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},\n\t\tssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},\n\t\tssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},\n\t}\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_asmreq.go",
    "content": "// Copyright 2012 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd || solaris || windows\n\npackage ipv4\n\nimport (\n\t\"errors\"\n\t\"net\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\nvar errNoSuchInterface = errors.New(\"no such interface\")\n\nfunc (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {\n\tmreq := ipMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3]}}\n\tif err := setIPMreqInterface(&mreq, ifi); err != nil {\n\t\treturn err\n\t}\n\tb := (*[sizeofIPMreq]byte)(unsafe.Pointer(&mreq))[:sizeofIPMreq]\n\treturn so.Set(c, b)\n}\n\nfunc (so *sockOpt) getMulticastIf(c *socket.Conn) (*net.Interface, error) {\n\tvar b [4]byte\n\tif _, err := so.Get(c, b[:]); err != nil {\n\t\treturn nil, err\n\t}\n\tifi, err := netIP4ToInterface(net.IPv4(b[0], b[1], b[2], b[3]))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ifi, nil\n}\n\nfunc (so *sockOpt) setMulticastIf(c *socket.Conn, ifi *net.Interface) error {\n\tip, err := netInterfaceToIP4(ifi)\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar b [4]byte\n\tcopy(b[:], ip)\n\treturn so.Set(c, b[:])\n}\n\nfunc setIPMreqInterface(mreq *ipMreq, ifi *net.Interface) error {\n\tif ifi == nil {\n\t\treturn nil\n\t}\n\tifat, err := ifi.Addrs()\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor _, ifa := range ifat {\n\t\tswitch ifa := ifa.(type) {\n\t\tcase *net.IPAddr:\n\t\t\tif ip := ifa.IP.To4(); ip != nil {\n\t\t\t\tcopy(mreq.Interface[:], ip)\n\t\t\t\treturn nil\n\t\t\t}\n\t\tcase *net.IPNet:\n\t\t\tif ip := ifa.IP.To4(); ip != nil {\n\t\t\t\tcopy(mreq.Interface[:], ip)\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\treturn errNoSuchInterface\n}\n\nfunc netIP4ToInterface(ip net.IP) (*net.Interface, error) {\n\tift, err := net.Interfaces()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfor _, ifi := range ift {\n\t\tifat, err := ifi.Addrs()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfor _, ifa := range ifat {\n\t\t\tswitch ifa := ifa.(type) {\n\t\t\tcase *net.IPAddr:\n\t\t\t\tif ip.Equal(ifa.IP) {\n\t\t\t\t\treturn &ifi, nil\n\t\t\t\t}\n\t\t\tcase *net.IPNet:\n\t\t\t\tif ip.Equal(ifa.IP) {\n\t\t\t\t\treturn &ifi, nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, errNoSuchInterface\n}\n\nfunc netInterfaceToIP4(ifi *net.Interface) (net.IP, error) {\n\tif ifi == nil {\n\t\treturn net.IPv4zero.To4(), nil\n\t}\n\tifat, err := ifi.Addrs()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfor _, ifa := range ifat {\n\t\tswitch ifa := ifa.(type) {\n\t\tcase *net.IPAddr:\n\t\t\tif ip := ifa.IP.To4(); ip != nil {\n\t\t\t\treturn ip, nil\n\t\t\t}\n\t\tcase *net.IPNet:\n\t\t\tif ip := ifa.IP.To4(); ip != nil {\n\t\t\t\treturn ip, nil\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, errNoSuchInterface\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go",
    "content": "// Copyright 2017 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !netbsd && !openbsd && !solaris && !windows\n\npackage ipv4\n\nimport (\n\t\"net\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\nfunc (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {\n\treturn errNotImplemented\n}\n\nfunc (so *sockOpt) getMulticastIf(c *socket.Conn) (*net.Interface, error) {\n\treturn nil, errNotImplemented\n}\n\nfunc (so *sockOpt) setMulticastIf(c *socket.Conn, ifi *net.Interface) error {\n\treturn errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_asmreqn.go",
    "content": "// Copyright 2014 The Go 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\n//go:build darwin || freebsd || linux\n\npackage ipv4\n\nimport (\n\t\"net\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc (so *sockOpt) getIPMreqn(c *socket.Conn) (*net.Interface, error) {\n\tb := make([]byte, so.Len)\n\tif _, err := so.Get(c, b); err != nil {\n\t\treturn nil, err\n\t}\n\tmreqn := (*unix.IPMreqn)(unsafe.Pointer(&b[0]))\n\tif mreqn.Ifindex == 0 {\n\t\treturn nil, nil\n\t}\n\tifi, err := net.InterfaceByIndex(int(mreqn.Ifindex))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ifi, nil\n}\n\nfunc (so *sockOpt) setIPMreqn(c *socket.Conn, ifi *net.Interface, grp net.IP) error {\n\tvar mreqn unix.IPMreqn\n\tif ifi != nil {\n\t\tmreqn.Ifindex = int32(ifi.Index)\n\t}\n\tif grp != nil {\n\t\tmreqn.Multiaddr = [4]byte{grp[0], grp[1], grp[2], grp[3]}\n\t}\n\tb := (*[unix.SizeofIPMreqn]byte)(unsafe.Pointer(&mreqn))[:unix.SizeofIPMreqn]\n\treturn so.Set(c, b)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go",
    "content": "// Copyright 2014 The Go 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\n//go:build !darwin && !freebsd && !linux\n\npackage ipv4\n\nimport (\n\t\"net\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\nfunc (so *sockOpt) getIPMreqn(c *socket.Conn) (*net.Interface, error) {\n\treturn nil, errNotImplemented\n}\n\nfunc (so *sockOpt) setIPMreqn(c *socket.Conn, ifi *net.Interface, grp net.IP) error {\n\treturn errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_bpf.go",
    "content": "// Copyright 2017 The Go 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\n//go:build linux\n\npackage ipv4\n\nimport (\n\t\"unsafe\"\n\n\t\"golang.org/x/net/bpf\"\n\t\"golang.org/x/net/internal/socket\"\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error {\n\tprog := unix.SockFprog{\n\t\tLen:    uint16(len(f)),\n\t\tFilter: (*unix.SockFilter)(unsafe.Pointer(&f[0])),\n\t}\n\tb := (*[unix.SizeofSockFprog]byte)(unsafe.Pointer(&prog))[:unix.SizeofSockFprog]\n\treturn so.Set(c, b)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_bpf_stub.go",
    "content": "// Copyright 2017 The Go 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\n//go:build !linux\n\npackage ipv4\n\nimport (\n\t\"golang.org/x/net/bpf\"\n\t\"golang.org/x/net/internal/socket\"\n)\n\nfunc (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error {\n\treturn errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_bsd.go",
    "content": "// Copyright 2014 The Go 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\n//go:build netbsd || openbsd\n\npackage ipv4\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nconst sockoptReceiveInterface = unix.IP_RECVIF\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{\n\t\tctlTTL:       {unix.IP_RECVTTL, 1, marshalTTL, parseTTL},\n\t\tctlDst:       {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},\n\t\tctlInterface: {unix.IP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},\n\t}\n\n\tsockOpts = map[int]*sockOpt{\n\t\tssoTOS:                {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},\n\t\tssoTTL:                {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},\n\t\tssoMulticastTTL:       {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},\n\t\tssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},\n\t\tssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 1}},\n\t\tssoReceiveTTL:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},\n\t\tssoReceiveDst:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}},\n\t\tssoReceiveInterface:   {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVIF, Len: 4}},\n\t\tssoHeaderPrepend:      {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},\n\t\tssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},\n\t\tssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},\n\t}\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_darwin.go",
    "content": "// Copyright 2014 The Go 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 ipv4\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nconst sockoptReceiveInterface = unix.IP_RECVIF\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{\n\t\tctlTTL:        {unix.IP_RECVTTL, 1, marshalTTL, parseTTL},\n\t\tctlDst:        {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},\n\t\tctlInterface:  {unix.IP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},\n\t\tctlPacketInfo: {unix.IP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},\n\t}\n\n\tsockOpts = map[int]*sockOpt{\n\t\tssoTOS:                {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},\n\t\tssoTTL:                {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},\n\t\tssoMulticastTTL:       {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},\n\t\tssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: unix.SizeofIPMreqn}, typ: ssoTypeIPMreqn},\n\t\tssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 4}},\n\t\tssoReceiveTTL:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},\n\t\tssoReceiveDst:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}},\n\t\tssoReceiveInterface:   {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVIF, Len: 4}},\n\t\tssoHeaderPrepend:      {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},\n\t\tssoStripHeader:        {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_STRIPHDR, Len: 4}},\n\t\tssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoJoinSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoLeaveSourceGroup:   {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoBlockSourceGroup:   {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoPacketInfo:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVPKTINFO, Len: 4}},\n\t}\n)\n\nfunc (pi *inetPktinfo) setIfindex(i int) {\n\tpi.Ifindex = uint32(i)\n}\n\nfunc (gr *groupReq) setGroup(grp net.IP) {\n\tsa := (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4))\n\tsa.Len = sizeofSockaddrInet\n\tsa.Family = syscall.AF_INET\n\tcopy(sa.Addr[:], grp)\n}\n\nfunc (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {\n\tsa := (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4))\n\tsa.Len = sizeofSockaddrInet\n\tsa.Family = syscall.AF_INET\n\tcopy(sa.Addr[:], grp)\n\tsa = (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 132))\n\tsa.Len = sizeofSockaddrInet\n\tsa.Family = syscall.AF_INET\n\tcopy(sa.Addr[:], src)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_dragonfly.go",
    "content": "// Copyright 2017 The Go 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 ipv4\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nconst sockoptReceiveInterface = unix.IP_RECVIF\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{\n\t\tctlTTL:       {unix.IP_RECVTTL, 1, marshalTTL, parseTTL},\n\t\tctlDst:       {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},\n\t\tctlInterface: {unix.IP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},\n\t}\n\n\tsockOpts = map[int]*sockOpt{\n\t\tssoTOS:                {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},\n\t\tssoTTL:                {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},\n\t\tssoMulticastTTL:       {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},\n\t\tssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},\n\t\tssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 4}},\n\t\tssoReceiveTTL:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},\n\t\tssoReceiveDst:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}},\n\t\tssoReceiveInterface:   {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVIF, Len: 4}},\n\t\tssoHeaderPrepend:      {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},\n\t\tssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},\n\t\tssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},\n\t}\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_freebsd.go",
    "content": "// Copyright 2014 The Go 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 ipv4\n\nimport (\n\t\"net\"\n\t\"runtime\"\n\t\"strings\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nconst sockoptReceiveInterface = unix.IP_RECVIF\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{\n\t\tctlTTL:       {unix.IP_RECVTTL, 1, marshalTTL, parseTTL},\n\t\tctlDst:       {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},\n\t\tctlInterface: {unix.IP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},\n\t}\n\n\tsockOpts = map[int]*sockOpt{\n\t\tssoTOS:                {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},\n\t\tssoTTL:                {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},\n\t\tssoMulticastTTL:       {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},\n\t\tssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},\n\t\tssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 4}},\n\t\tssoReceiveTTL:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},\n\t\tssoReceiveDst:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}},\n\t\tssoReceiveInterface:   {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVIF, Len: 4}},\n\t\tssoHeaderPrepend:      {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},\n\t\tssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoJoinSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoLeaveSourceGroup:   {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoBlockSourceGroup:   {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t}\n)\n\nfunc init() {\n\tfreebsdVersion, _ = syscall.SysctlUint32(\"kern.osreldate\")\n\tif freebsdVersion >= 1000000 {\n\t\tsockOpts[ssoMulticastInterface] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: unix.SizeofIPMreqn}, typ: ssoTypeIPMreqn}\n\t}\n\tif runtime.GOOS == \"freebsd\" && runtime.GOARCH == \"386\" {\n\t\tarchs, _ := syscall.Sysctl(\"kern.supported_archs\")\n\t\tfor _, s := range strings.Fields(archs) {\n\t\t\tif s == \"amd64\" {\n\t\t\t\tcompatFreeBSD32 = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (gr *groupReq) setGroup(grp net.IP) {\n\tsa := (*sockaddrInet)(unsafe.Pointer(&gr.Group))\n\tsa.Len = sizeofSockaddrInet\n\tsa.Family = syscall.AF_INET\n\tcopy(sa.Addr[:], grp)\n}\n\nfunc (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {\n\tsa := (*sockaddrInet)(unsafe.Pointer(&gsr.Group))\n\tsa.Len = sizeofSockaddrInet\n\tsa.Family = syscall.AF_INET\n\tcopy(sa.Addr[:], grp)\n\tsa = (*sockaddrInet)(unsafe.Pointer(&gsr.Source))\n\tsa.Len = sizeofSockaddrInet\n\tsa.Family = syscall.AF_INET\n\tcopy(sa.Addr[:], src)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_linux.go",
    "content": "// Copyright 2014 The Go 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 ipv4\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{\n\t\tctlTTL:        {unix.IP_TTL, 1, marshalTTL, parseTTL},\n\t\tctlPacketInfo: {unix.IP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},\n\t}\n\n\tsockOpts = map[int]*sockOpt{\n\t\tssoTOS:                {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},\n\t\tssoTTL:                {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},\n\t\tssoMulticastTTL:       {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 4}},\n\t\tssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: unix.SizeofIPMreqn}, typ: ssoTypeIPMreqn},\n\t\tssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 4}},\n\t\tssoReceiveTTL:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},\n\t\tssoPacketInfo:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_PKTINFO, Len: 4}},\n\t\tssoHeaderPrepend:      {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},\n\t\tssoICMPFilter:         {Option: socket.Option{Level: iana.ProtocolReserved, Name: unix.ICMP_FILTER, Len: sizeofICMPFilter}},\n\t\tssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoJoinSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoLeaveSourceGroup:   {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoBlockSourceGroup:   {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoAttachFilter:       {Option: socket.Option{Level: unix.SOL_SOCKET, Name: unix.SO_ATTACH_FILTER, Len: unix.SizeofSockFprog}},\n\t}\n)\n\nfunc (pi *inetPktinfo) setIfindex(i int) {\n\tpi.Ifindex = int32(i)\n}\n\nfunc (gr *groupReq) setGroup(grp net.IP) {\n\tsa := (*sockaddrInet)(unsafe.Pointer(&gr.Group))\n\tsa.Family = syscall.AF_INET\n\tcopy(sa.Addr[:], grp)\n}\n\nfunc (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {\n\tsa := (*sockaddrInet)(unsafe.Pointer(&gsr.Group))\n\tsa.Family = syscall.AF_INET\n\tcopy(sa.Addr[:], grp)\n\tsa = (*sockaddrInet)(unsafe.Pointer(&gsr.Source))\n\tsa.Family = syscall.AF_INET\n\tcopy(sa.Addr[:], src)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_solaris.go",
    "content": "// Copyright 2016 The Go 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 ipv4\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nconst sockoptReceiveInterface = unix.IP_RECVIF\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{\n\t\tctlTTL:        {unix.IP_RECVTTL, 4, marshalTTL, parseTTL},\n\t\tctlPacketInfo: {unix.IP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},\n\t}\n\n\tsockOpts = map[int]sockOpt{\n\t\tssoTOS:                {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}},\n\t\tssoTTL:                {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}},\n\t\tssoMulticastTTL:       {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},\n\t\tssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},\n\t\tssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 1}},\n\t\tssoReceiveTTL:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}},\n\t\tssoPacketInfo:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVPKTINFO, Len: 4}},\n\t\tssoHeaderPrepend:      {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}},\n\t\tssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoJoinSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoLeaveSourceGroup:   {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoBlockSourceGroup:   {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t}\n)\n\nfunc (pi *inetPktinfo) setIfindex(i int) {\n\tpi.Ifindex = uint32(i)\n}\n\nfunc (gr *groupReq) setGroup(grp net.IP) {\n\tsa := (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4))\n\tsa.Family = syscall.AF_INET\n\tcopy(sa.Addr[:], grp)\n}\n\nfunc (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {\n\tsa := (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4))\n\tsa.Family = syscall.AF_INET\n\tcopy(sa.Addr[:], grp)\n\tsa = (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 260))\n\tsa.Family = syscall.AF_INET\n\tcopy(sa.Addr[:], src)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_ssmreq.go",
    "content": "// Copyright 2014 The Go 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\n//go:build darwin || freebsd || linux || solaris\n\npackage ipv4\n\nimport (\n\t\"net\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\nfunc (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {\n\tvar gr groupReq\n\tif ifi != nil {\n\t\tgr.Interface = uint32(ifi.Index)\n\t}\n\tgr.setGroup(grp)\n\tvar b []byte\n\tif compatFreeBSD32 {\n\t\tvar d [sizeofGroupReq + 4]byte\n\t\ts := (*[sizeofGroupReq]byte)(unsafe.Pointer(&gr))\n\t\tcopy(d[:4], s[:4])\n\t\tcopy(d[8:], s[4:])\n\t\tb = d[:]\n\t} else {\n\t\tb = (*[sizeofGroupReq]byte)(unsafe.Pointer(&gr))[:sizeofGroupReq]\n\t}\n\treturn so.Set(c, b)\n}\n\nfunc (so *sockOpt) setGroupSourceReq(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {\n\tvar gsr groupSourceReq\n\tif ifi != nil {\n\t\tgsr.Interface = uint32(ifi.Index)\n\t}\n\tgsr.setSourceGroup(grp, src)\n\tvar b []byte\n\tif compatFreeBSD32 {\n\t\tvar d [sizeofGroupSourceReq + 4]byte\n\t\ts := (*[sizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr))\n\t\tcopy(d[:4], s[:4])\n\t\tcopy(d[8:], s[4:])\n\t\tb = d[:]\n\t} else {\n\t\tb = (*[sizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr))[:sizeofGroupSourceReq]\n\t}\n\treturn so.Set(c, b)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go",
    "content": "// Copyright 2014 The Go 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\n//go:build !darwin && !freebsd && !linux && !solaris\n\npackage ipv4\n\nimport (\n\t\"net\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\nfunc (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {\n\treturn errNotImplemented\n}\n\nfunc (so *sockOpt) setGroupSourceReq(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {\n\treturn errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_stub.go",
    "content": "// Copyright 2014 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos\n\npackage ipv4\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{}\n\n\tsockOpts = map[int]*sockOpt{}\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_windows.go",
    "content": "// Copyright 2014 The Go 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 ipv4\n\nimport (\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\nconst (\n\tsizeofIPMreq       = 0x8\n\tsizeofIPMreqSource = 0xc\n)\n\ntype ipMreq struct {\n\tMultiaddr [4]byte\n\tInterface [4]byte\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  [4]byte\n\tSourceaddr [4]byte\n\tInterface  [4]byte\n}\n\n// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms738586(v=vs.85).aspx\nvar (\n\tctlOpts = [ctlMax]ctlOpt{}\n\n\tsockOpts = map[int]*sockOpt{\n\t\tssoTOS:                {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_TOS, Len: 4}},\n\t\tssoTTL:                {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_TTL, Len: 4}},\n\t\tssoMulticastTTL:       {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_MULTICAST_TTL, Len: 4}},\n\t\tssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_MULTICAST_IF, Len: 4}},\n\t\tssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_MULTICAST_LOOP, Len: 4}},\n\t\tssoHeaderPrepend:      {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_HDRINCL, Len: 4}},\n\t\tssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},\n\t\tssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},\n\t}\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/sys_zos.go",
    "content": "// Copyright 2020 The Go 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 ipv4\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{\n\t\tctlPacketInfo: {unix.IP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},\n\t}\n\n\tsockOpts = map[int]*sockOpt{\n\t\tssoMulticastTTL:       {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}},\n\t\tssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}},\n\t\tssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 1}},\n\t\tssoPacketInfo:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVPKTINFO, Len: 4}},\n\t\tssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoJoinSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoLeaveSourceGroup:   {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoBlockSourceGroup:   {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t}\n)\n\nfunc (pi *inetPktinfo) setIfindex(i int) {\n\tpi.Ifindex = uint32(i)\n}\n\nfunc (gr *groupReq) setGroup(grp net.IP) {\n\tsa := (*sockaddrInet4)(unsafe.Pointer(&gr.Group))\n\tsa.Family = syscall.AF_INET\n\tsa.Len = sizeofSockaddrInet4\n\tcopy(sa.Addr[:], grp)\n}\n\nfunc (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {\n\tsa := (*sockaddrInet4)(unsafe.Pointer(&gsr.Group))\n\tsa.Family = syscall.AF_INET\n\tsa.Len = sizeofSockaddrInet4\n\tcopy(sa.Addr[:], grp)\n\tsa = (*sockaddrInet4)(unsafe.Pointer(&gsr.Source))\n\tsa.Family = syscall.AF_INET\n\tsa.Len = sizeofSockaddrInet4\n\tcopy(sa.Addr[:], src)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_aix.go\n\n// Added for go1.11 compatibility\n//go:build aix\n\npackage ipv4\n\nconst (\n\tsizeofIPMreq = 0x8\n)\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_darwin.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_darwin.go\n\npackage ipv4\n\nconst (\n\tsizeofSockaddrStorage = 0x80\n\tsizeofSockaddrInet    = 0x10\n\tsizeofInetPktinfo     = 0xc\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x84\n\tsizeofGroupSourceReq = 0x104\n)\n\ntype sockaddrStorage struct {\n\tLen         uint8\n\tFamily      uint8\n\tX__ss_pad1  [6]int8\n\tX__ss_align int64\n\tX__ss_pad2  [112]int8\n}\n\ntype sockaddrInet struct {\n\tLen    uint8\n\tFamily uint8\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tZero   [8]int8\n}\n\ntype inetPktinfo struct {\n\tIfindex  uint32\n\tSpec_dst [4]byte /* in_addr */\n\tAddr     [4]byte /* in_addr */\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  [4]byte /* in_addr */\n\tSourceaddr [4]byte /* in_addr */\n\tInterface  [4]byte /* in_addr */\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [128]byte\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [128]byte\n\tPad_cgo_1 [128]byte\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_dragonfly.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_dragonfly.go\n\npackage ipv4\n\nconst (\n\tsizeofIPMreq = 0x8\n)\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_freebsd.go\n\npackage ipv4\n\nconst (\n\tsizeofSockaddrStorage = 0x80\n\tsizeofSockaddrInet    = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x84\n\tsizeofGroupSourceReq = 0x104\n)\n\ntype sockaddrStorage struct {\n\tLen         uint8\n\tFamily      uint8\n\tX__ss_pad1  [6]int8\n\tX__ss_align int64\n\tX__ss_pad2  [112]int8\n}\n\ntype sockaddrInet struct {\n\tLen    uint8\n\tFamily uint8\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tZero   [8]int8\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  [4]byte /* in_addr */\n\tSourceaddr [4]byte /* in_addr */\n\tInterface  [4]byte /* in_addr */\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tGroup     sockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tGroup     sockaddrStorage\n\tSource    sockaddrStorage\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_freebsd.go\n\npackage ipv4\n\nconst (\n\tsizeofSockaddrStorage = 0x80\n\tsizeofSockaddrInet    = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n)\n\ntype sockaddrStorage struct {\n\tLen         uint8\n\tFamily      uint8\n\tX__ss_pad1  [6]int8\n\tX__ss_align int64\n\tX__ss_pad2  [112]int8\n}\n\ntype sockaddrInet struct {\n\tLen    uint8\n\tFamily uint8\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tZero   [8]int8\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  [4]byte /* in_addr */\n\tSourceaddr [4]byte /* in_addr */\n\tInterface  [4]byte /* in_addr */\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     sockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     sockaddrStorage\n\tSource    sockaddrStorage\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_freebsd.go\n\npackage ipv4\n\nconst (\n\tsizeofSockaddrStorage = 0x80\n\tsizeofSockaddrInet    = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n)\n\ntype sockaddrStorage struct {\n\tLen         uint8\n\tFamily      uint8\n\tX__ss_pad1  [6]int8\n\tX__ss_align int64\n\tX__ss_pad2  [112]int8\n}\n\ntype sockaddrInet struct {\n\tLen    uint8\n\tFamily uint8\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tZero   [8]int8\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  [4]byte /* in_addr */\n\tSourceaddr [4]byte /* in_addr */\n\tInterface  [4]byte /* in_addr */\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     sockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     sockaddrStorage\n\tSource    sockaddrStorage\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_freebsd_arm64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_freebsd.go\n\npackage ipv4\n\nconst (\n\tsizeofSockaddrStorage = 0x80\n\tsizeofSockaddrInet    = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n)\n\ntype sockaddrStorage struct {\n\tLen         uint8\n\tFamily      uint8\n\tX__ss_pad1  [6]uint8\n\tX__ss_align int64\n\tX__ss_pad2  [112]uint8\n}\n\ntype sockaddrInet struct {\n\tLen    uint8\n\tFamily uint8\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tZero   [8]uint8\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  [4]byte /* in_addr */\n\tSourceaddr [4]byte /* in_addr */\n\tInterface  [4]byte /* in_addr */\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tGroup     sockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tGroup     sockaddrStorage\n\tSource    sockaddrStorage\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_freebsd_riscv64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_freebsd.go\n\npackage ipv4\n\nconst (\n\tsizeofSockaddrStorage = 0x80\n\tsizeofSockaddrInet    = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n)\n\ntype sockaddrStorage struct {\n\tLen         uint8\n\tFamily      uint8\n\tX__ss_pad1  [6]uint8\n\tX__ss_align int64\n\tX__ss_pad2  [112]uint8\n}\n\ntype sockaddrInet struct {\n\tLen    uint8\n\tFamily uint8\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tZero   [8]uint8\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  [4]byte /* in_addr */\n\tSourceaddr [4]byte /* in_addr */\n\tInterface  [4]byte /* in_addr */\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tGroup     sockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tGroup     sockaddrStorage\n\tSource    sockaddrStorage\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_linux_386.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv4\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet          = 0x10\n\tsizeofInetPktinfo           = 0xc\n\tsizeofSockExtendedErr       = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x84\n\tsizeofGroupSourceReq = 0x104\n\n\tsizeofICMPFilter = 0x4\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet struct {\n\tFamily uint16\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tX__pad [8]uint8\n}\n\ntype inetPktinfo struct {\n\tIfindex  int32\n\tSpec_dst [4]byte /* in_addr */\n\tAddr     [4]byte /* in_addr */\n}\n\ntype sockExtendedErr struct {\n\tErrno  uint32\n\tOrigin uint8\n\tType   uint8\n\tCode   uint8\n\tPad    uint8\n\tInfo   uint32\n\tData   uint32\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  uint32\n\tInterface  uint32\n\tSourceaddr uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpFilter struct {\n\tData uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv4\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet          = 0x10\n\tsizeofInetPktinfo           = 0xc\n\tsizeofSockExtendedErr       = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPFilter = 0x4\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet struct {\n\tFamily uint16\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tX__pad [8]uint8\n}\n\ntype inetPktinfo struct {\n\tIfindex  int32\n\tSpec_dst [4]byte /* in_addr */\n\tAddr     [4]byte /* in_addr */\n}\n\ntype sockExtendedErr struct {\n\tErrno  uint32\n\tOrigin uint8\n\tType   uint8\n\tCode   uint8\n\tPad    uint8\n\tInfo   uint32\n\tData   uint32\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  uint32\n\tInterface  uint32\n\tSourceaddr uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpFilter struct {\n\tData uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_linux_arm.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv4\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet          = 0x10\n\tsizeofInetPktinfo           = 0xc\n\tsizeofSockExtendedErr       = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x84\n\tsizeofGroupSourceReq = 0x104\n\n\tsizeofICMPFilter = 0x4\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet struct {\n\tFamily uint16\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tX__pad [8]uint8\n}\n\ntype inetPktinfo struct {\n\tIfindex  int32\n\tSpec_dst [4]byte /* in_addr */\n\tAddr     [4]byte /* in_addr */\n}\n\ntype sockExtendedErr struct {\n\tErrno  uint32\n\tOrigin uint8\n\tType   uint8\n\tCode   uint8\n\tPad    uint8\n\tInfo   uint32\n\tData   uint32\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  uint32\n\tInterface  uint32\n\tSourceaddr uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpFilter struct {\n\tData uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv4\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet          = 0x10\n\tsizeofInetPktinfo           = 0xc\n\tsizeofSockExtendedErr       = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPFilter = 0x4\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet struct {\n\tFamily uint16\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tX__pad [8]uint8\n}\n\ntype inetPktinfo struct {\n\tIfindex  int32\n\tSpec_dst [4]byte /* in_addr */\n\tAddr     [4]byte /* in_addr */\n}\n\ntype sockExtendedErr struct {\n\tErrno  uint32\n\tOrigin uint8\n\tType   uint8\n\tCode   uint8\n\tPad    uint8\n\tInfo   uint32\n\tData   uint32\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  uint32\n\tInterface  uint32\n\tSourceaddr uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpFilter struct {\n\tData uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_linux_loong64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\n//go:build loong64\n\npackage ipv4\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet          = 0x10\n\tsizeofInetPktinfo           = 0xc\n\tsizeofSockExtendedErr       = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPFilter = 0x4\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet struct {\n\tFamily uint16\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tX__pad [8]uint8\n}\n\ntype inetPktinfo struct {\n\tIfindex  int32\n\tSpec_dst [4]byte /* in_addr */\n\tAddr     [4]byte /* in_addr */\n}\n\ntype sockExtendedErr struct {\n\tErrno  uint32\n\tOrigin uint8\n\tType   uint8\n\tCode   uint8\n\tPad    uint8\n\tInfo   uint32\n\tData   uint32\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  uint32\n\tInterface  uint32\n\tSourceaddr uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpFilter struct {\n\tData uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_linux_mips.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv4\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet          = 0x10\n\tsizeofInetPktinfo           = 0xc\n\tsizeofSockExtendedErr       = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x84\n\tsizeofGroupSourceReq = 0x104\n\n\tsizeofICMPFilter = 0x4\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet struct {\n\tFamily uint16\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tX__pad [8]uint8\n}\n\ntype inetPktinfo struct {\n\tIfindex  int32\n\tSpec_dst [4]byte /* in_addr */\n\tAddr     [4]byte /* in_addr */\n}\n\ntype sockExtendedErr struct {\n\tErrno  uint32\n\tOrigin uint8\n\tType   uint8\n\tCode   uint8\n\tPad    uint8\n\tInfo   uint32\n\tData   uint32\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  uint32\n\tInterface  uint32\n\tSourceaddr uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpFilter struct {\n\tData uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv4\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet          = 0x10\n\tsizeofInetPktinfo           = 0xc\n\tsizeofSockExtendedErr       = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPFilter = 0x4\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet struct {\n\tFamily uint16\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tX__pad [8]uint8\n}\n\ntype inetPktinfo struct {\n\tIfindex  int32\n\tSpec_dst [4]byte /* in_addr */\n\tAddr     [4]byte /* in_addr */\n}\n\ntype sockExtendedErr struct {\n\tErrno  uint32\n\tOrigin uint8\n\tType   uint8\n\tCode   uint8\n\tPad    uint8\n\tInfo   uint32\n\tData   uint32\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  uint32\n\tInterface  uint32\n\tSourceaddr uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpFilter struct {\n\tData uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv4\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet          = 0x10\n\tsizeofInetPktinfo           = 0xc\n\tsizeofSockExtendedErr       = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPFilter = 0x4\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet struct {\n\tFamily uint16\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tX__pad [8]uint8\n}\n\ntype inetPktinfo struct {\n\tIfindex  int32\n\tSpec_dst [4]byte /* in_addr */\n\tAddr     [4]byte /* in_addr */\n}\n\ntype sockExtendedErr struct {\n\tErrno  uint32\n\tOrigin uint8\n\tType   uint8\n\tCode   uint8\n\tPad    uint8\n\tInfo   uint32\n\tData   uint32\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  uint32\n\tInterface  uint32\n\tSourceaddr uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpFilter struct {\n\tData uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv4\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet          = 0x10\n\tsizeofInetPktinfo           = 0xc\n\tsizeofSockExtendedErr       = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x84\n\tsizeofGroupSourceReq = 0x104\n\n\tsizeofICMPFilter = 0x4\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet struct {\n\tFamily uint16\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tX__pad [8]uint8\n}\n\ntype inetPktinfo struct {\n\tIfindex  int32\n\tSpec_dst [4]byte /* in_addr */\n\tAddr     [4]byte /* in_addr */\n}\n\ntype sockExtendedErr struct {\n\tErrno  uint32\n\tOrigin uint8\n\tType   uint8\n\tCode   uint8\n\tPad    uint8\n\tInfo   uint32\n\tData   uint32\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  uint32\n\tInterface  uint32\n\tSourceaddr uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpFilter struct {\n\tData uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv4\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet          = 0x10\n\tsizeofInetPktinfo           = 0xc\n\tsizeofSockExtendedErr       = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x84\n\tsizeofGroupSourceReq = 0x104\n\n\tsizeofICMPFilter = 0x4\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]uint8\n}\n\ntype sockaddrInet struct {\n\tFamily uint16\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tX__pad [8]uint8\n}\n\ntype inetPktinfo struct {\n\tIfindex  int32\n\tSpec_dst [4]byte /* in_addr */\n\tAddr     [4]byte /* in_addr */\n}\n\ntype sockExtendedErr struct {\n\tErrno  uint32\n\tOrigin uint8\n\tType   uint8\n\tCode   uint8\n\tPad    uint8\n\tInfo   uint32\n\tData   uint32\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  uint32\n\tInterface  uint32\n\tSourceaddr uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpFilter struct {\n\tData uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv4\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet          = 0x10\n\tsizeofInetPktinfo           = 0xc\n\tsizeofSockExtendedErr       = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPFilter = 0x4\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet struct {\n\tFamily uint16\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tX__pad [8]uint8\n}\n\ntype inetPktinfo struct {\n\tIfindex  int32\n\tSpec_dst [4]byte /* in_addr */\n\tAddr     [4]byte /* in_addr */\n}\n\ntype sockExtendedErr struct {\n\tErrno  uint32\n\tOrigin uint8\n\tType   uint8\n\tCode   uint8\n\tPad    uint8\n\tInfo   uint32\n\tData   uint32\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  uint32\n\tInterface  uint32\n\tSourceaddr uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpFilter struct {\n\tData uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv4\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet          = 0x10\n\tsizeofInetPktinfo           = 0xc\n\tsizeofSockExtendedErr       = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPFilter = 0x4\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet struct {\n\tFamily uint16\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tX__pad [8]uint8\n}\n\ntype inetPktinfo struct {\n\tIfindex  int32\n\tSpec_dst [4]byte /* in_addr */\n\tAddr     [4]byte /* in_addr */\n}\n\ntype sockExtendedErr struct {\n\tErrno  uint32\n\tOrigin uint8\n\tType   uint8\n\tCode   uint8\n\tPad    uint8\n\tInfo   uint32\n\tData   uint32\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  uint32\n\tInterface  uint32\n\tSourceaddr uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpFilter struct {\n\tData uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\n//go:build riscv64\n\npackage ipv4\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet          = 0x10\n\tsizeofInetPktinfo           = 0xc\n\tsizeofSockExtendedErr       = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPFilter = 0x4\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet struct {\n\tFamily uint16\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tX__pad [8]uint8\n}\n\ntype inetPktinfo struct {\n\tIfindex  int32\n\tSpec_dst [4]byte /* in_addr */\n\tAddr     [4]byte /* in_addr */\n}\n\ntype sockExtendedErr struct {\n\tErrno  uint32\n\tOrigin uint8\n\tType   uint8\n\tCode   uint8\n\tPad    uint8\n\tInfo   uint32\n\tData   uint32\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  uint32\n\tInterface  uint32\n\tSourceaddr uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpFilter struct {\n\tData uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv4\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet          = 0x10\n\tsizeofInetPktinfo           = 0xc\n\tsizeofSockExtendedErr       = 0x10\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPFilter = 0x4\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet struct {\n\tFamily uint16\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tX__pad [8]uint8\n}\n\ntype inetPktinfo struct {\n\tIfindex  int32\n\tSpec_dst [4]byte /* in_addr */\n\tAddr     [4]byte /* in_addr */\n}\n\ntype sockExtendedErr struct {\n\tErrno  uint32\n\tOrigin uint8\n\tType   uint8\n\tCode   uint8\n\tPad    uint8\n\tInfo   uint32\n\tData   uint32\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  uint32\n\tInterface  uint32\n\tSourceaddr uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpFilter struct {\n\tData uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_netbsd.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_netbsd.go\n\npackage ipv4\n\nconst (\n\tsizeofIPMreq = 0x8\n)\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_openbsd.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_openbsd.go\n\npackage ipv4\n\nconst (\n\tsizeofIPMreq = 0x8\n)\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_solaris.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_solaris.go\n\npackage ipv4\n\nconst (\n\tsizeofSockaddrStorage = 0x100\n\tsizeofSockaddrInet    = 0x10\n\tsizeofInetPktinfo     = 0xc\n\n\tsizeofIPMreq         = 0x8\n\tsizeofIPMreqSource   = 0xc\n\tsizeofGroupReq       = 0x104\n\tsizeofGroupSourceReq = 0x204\n)\n\ntype sockaddrStorage struct {\n\tFamily     uint16\n\tX_ss_pad1  [6]int8\n\tX_ss_align float64\n\tX_ss_pad2  [240]int8\n}\n\ntype sockaddrInet struct {\n\tFamily uint16\n\tPort   uint16\n\tAddr   [4]byte /* in_addr */\n\tZero   [8]int8\n}\n\ntype inetPktinfo struct {\n\tIfindex  uint32\n\tSpec_dst [4]byte /* in_addr */\n\tAddr     [4]byte /* in_addr */\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n\ntype ipMreqSource struct {\n\tMultiaddr  [4]byte /* in_addr */\n\tSourceaddr [4]byte /* in_addr */\n\tInterface  [4]byte /* in_addr */\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [256]byte\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [256]byte\n\tPad_cgo_1 [256]byte\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv4/zsys_zos_s390x.go",
    "content": "// Copyright 2020 The Go 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\n// Hand edited based on zerrors_zos_s390x.go\n// TODO(Bill O'Farrell): auto-generate.\n\npackage ipv4\n\nconst (\n\tsizeofIPMreq          = 8\n\tsizeofSockaddrInet4   = 16\n\tsizeofSockaddrStorage = 128\n\tsizeofGroupReq        = 136\n\tsizeofGroupSourceReq  = 264\n\tsizeofInetPktinfo     = 8\n)\n\ntype sockaddrInet4 struct {\n\tLen    uint8\n\tFamily uint8\n\tPort   uint16\n\tAddr   [4]byte\n\tZero   [8]uint8\n}\n\ntype inetPktinfo struct {\n\tAddr    [4]byte\n\tIfindex uint32\n}\n\ntype sockaddrStorage struct {\n\tLen      uint8\n\tFamily   byte\n\tss_pad1  [6]byte\n\tss_align int64\n\tss_pad2  [112]byte\n}\n\ntype groupReq struct {\n\tInterface uint32\n\treserved  uint32\n\tGroup     sockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\treserved  uint32\n\tGroup     sockaddrStorage\n\tSource    sockaddrStorage\n}\n\ntype ipMreq struct {\n\tMultiaddr [4]byte /* in_addr */\n\tInterface [4]byte /* in_addr */\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/batch.go",
    "content": "// Copyright 2017 The Go 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 ipv6\n\nimport (\n\t\"net\"\n\t\"runtime\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\n// BUG(mikio): On Windows, the ReadBatch and WriteBatch methods of\n// PacketConn are not implemented.\n\n// A Message represents an IO message.\n//\n//\ttype Message struct {\n//\t\tBuffers [][]byte\n//\t\tOOB     []byte\n//\t\tAddr    net.Addr\n//\t\tN       int\n//\t\tNN      int\n//\t\tFlags   int\n//\t}\n//\n// The Buffers fields represents a list of contiguous buffers, which\n// can be used for vectored IO, for example, putting a header and a\n// payload in each slice.\n// When writing, the Buffers field must contain at least one byte to\n// write.\n// When reading, the Buffers field will always contain a byte to read.\n//\n// The OOB field contains protocol-specific control or miscellaneous\n// ancillary data known as out-of-band data.\n// It can be nil when not required.\n//\n// The Addr field specifies a destination address when writing.\n// It can be nil when the underlying protocol of the endpoint uses\n// connection-oriented communication.\n// After a successful read, it may contain the source address on the\n// received packet.\n//\n// The N field indicates the number of bytes read or written from/to\n// Buffers.\n//\n// The NN field indicates the number of bytes read or written from/to\n// OOB.\n//\n// The Flags field contains protocol-specific information on the\n// received message.\ntype Message = socket.Message\n\n// ReadBatch reads a batch of messages.\n//\n// The provided flags is a set of platform-dependent flags, such as\n// syscall.MSG_PEEK.\n//\n// On a successful read it returns the number of messages received, up\n// to len(ms).\n//\n// On Linux, a batch read will be optimized.\n// On other platforms, this method will read only a single message.\nfunc (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\tswitch runtime.GOOS {\n\tcase \"linux\":\n\t\tn, err := c.RecvMsgs([]socket.Message(ms), flags)\n\t\tif err != nil {\n\t\t\terr = &net.OpError{Op: \"read\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}\n\t\t}\n\t\treturn n, err\n\tdefault:\n\t\tn := 1\n\t\terr := c.RecvMsg(&ms[0], flags)\n\t\tif err != nil {\n\t\t\tn = 0\n\t\t\terr = &net.OpError{Op: \"read\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}\n\t\t}\n\t\treturn n, err\n\t}\n}\n\n// WriteBatch writes a batch of messages.\n//\n// The provided flags is a set of platform-dependent flags, such as\n// syscall.MSG_DONTROUTE.\n//\n// It returns the number of messages written on a successful write.\n//\n// On Linux, a batch write will be optimized.\n// On other platforms, this method will write only a single message.\nfunc (c *payloadHandler) WriteBatch(ms []Message, flags int) (int, error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\tswitch runtime.GOOS {\n\tcase \"linux\":\n\t\tn, err := c.SendMsgs([]socket.Message(ms), flags)\n\t\tif err != nil {\n\t\t\terr = &net.OpError{Op: \"write\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}\n\t\t}\n\t\treturn n, err\n\tdefault:\n\t\tn := 1\n\t\terr := c.SendMsg(&ms[0], flags)\n\t\tif err != nil {\n\t\t\tn = 0\n\t\t\terr = &net.OpError{Op: \"write\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}\n\t\t}\n\t\treturn n, err\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/control.go",
    "content": "// Copyright 2013 The Go 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 ipv6\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"sync\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n)\n\n// Note that RFC 3542 obsoletes RFC 2292 but OS X Snow Leopard and the\n// former still support RFC 2292 only. Please be aware that almost\n// all protocol implementations prohibit using a combination of RFC\n// 2292 and RFC 3542 for some practical reasons.\n\ntype rawOpt struct {\n\tsync.RWMutex\n\tcflags ControlFlags\n}\n\nfunc (c *rawOpt) set(f ControlFlags)        { c.cflags |= f }\nfunc (c *rawOpt) clear(f ControlFlags)      { c.cflags &^= f }\nfunc (c *rawOpt) isset(f ControlFlags) bool { return c.cflags&f != 0 }\n\n// A ControlFlags represents per packet basis IP-level socket option\n// control flags.\ntype ControlFlags uint\n\nconst (\n\tFlagTrafficClass ControlFlags = 1 << iota // pass the traffic class on the received packet\n\tFlagHopLimit                              // pass the hop limit on the received packet\n\tFlagSrc                                   // pass the source address on the received packet\n\tFlagDst                                   // pass the destination address on the received packet\n\tFlagInterface                             // pass the interface index on the received packet\n\tFlagPathMTU                               // pass the path MTU on the received packet path\n)\n\nconst flagPacketInfo = FlagDst | FlagInterface\n\n// A ControlMessage represents per packet basis IP-level socket\n// options.\ntype ControlMessage struct {\n\t// Receiving socket options: SetControlMessage allows to\n\t// receive the options from the protocol stack using ReadFrom\n\t// method of PacketConn.\n\t//\n\t// Specifying socket options: ControlMessage for WriteTo\n\t// method of PacketConn allows to send the options to the\n\t// protocol stack.\n\t//\n\tTrafficClass int    // traffic class, must be 1 <= value <= 255 when specifying\n\tHopLimit     int    // hop limit, must be 1 <= value <= 255 when specifying\n\tSrc          net.IP // source address, specifying only\n\tDst          net.IP // destination address, receiving only\n\tIfIndex      int    // interface index, must be 1 <= value when specifying\n\tNextHop      net.IP // next hop address, specifying only\n\tMTU          int    // path MTU, receiving only\n}\n\nfunc (cm *ControlMessage) String() string {\n\tif cm == nil {\n\t\treturn \"<nil>\"\n\t}\n\treturn fmt.Sprintf(\"tclass=%#x hoplim=%d src=%v dst=%v ifindex=%d nexthop=%v mtu=%d\", cm.TrafficClass, cm.HopLimit, cm.Src, cm.Dst, cm.IfIndex, cm.NextHop, cm.MTU)\n}\n\n// Marshal returns the binary encoding of cm.\nfunc (cm *ControlMessage) Marshal() []byte {\n\tif cm == nil {\n\t\treturn nil\n\t}\n\tvar l int\n\ttclass := false\n\tif ctlOpts[ctlTrafficClass].name > 0 && cm.TrafficClass > 0 {\n\t\ttclass = true\n\t\tl += socket.ControlMessageSpace(ctlOpts[ctlTrafficClass].length)\n\t}\n\thoplimit := false\n\tif ctlOpts[ctlHopLimit].name > 0 && cm.HopLimit > 0 {\n\t\thoplimit = true\n\t\tl += socket.ControlMessageSpace(ctlOpts[ctlHopLimit].length)\n\t}\n\tpktinfo := false\n\tif ctlOpts[ctlPacketInfo].name > 0 && (cm.Src.To16() != nil && cm.Src.To4() == nil || cm.IfIndex > 0) {\n\t\tpktinfo = true\n\t\tl += socket.ControlMessageSpace(ctlOpts[ctlPacketInfo].length)\n\t}\n\tnexthop := false\n\tif ctlOpts[ctlNextHop].name > 0 && cm.NextHop.To16() != nil && cm.NextHop.To4() == nil {\n\t\tnexthop = true\n\t\tl += socket.ControlMessageSpace(ctlOpts[ctlNextHop].length)\n\t}\n\tvar b []byte\n\tif l > 0 {\n\t\tb = make([]byte, l)\n\t\tbb := b\n\t\tif tclass {\n\t\t\tbb = ctlOpts[ctlTrafficClass].marshal(bb, cm)\n\t\t}\n\t\tif hoplimit {\n\t\t\tbb = ctlOpts[ctlHopLimit].marshal(bb, cm)\n\t\t}\n\t\tif pktinfo {\n\t\t\tbb = ctlOpts[ctlPacketInfo].marshal(bb, cm)\n\t\t}\n\t\tif nexthop {\n\t\t\tbb = ctlOpts[ctlNextHop].marshal(bb, cm)\n\t\t}\n\t}\n\treturn b\n}\n\n// Parse parses b as a control message and stores the result in cm.\nfunc (cm *ControlMessage) Parse(b []byte) error {\n\tms, err := socket.ControlMessage(b).Parse()\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor _, m := range ms {\n\t\tlvl, typ, l, err := m.ParseHeader()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif lvl != iana.ProtocolIPv6 {\n\t\t\tcontinue\n\t\t}\n\t\tswitch {\n\t\tcase typ == ctlOpts[ctlTrafficClass].name && l >= ctlOpts[ctlTrafficClass].length:\n\t\t\tctlOpts[ctlTrafficClass].parse(cm, m.Data(l))\n\t\tcase typ == ctlOpts[ctlHopLimit].name && l >= ctlOpts[ctlHopLimit].length:\n\t\t\tctlOpts[ctlHopLimit].parse(cm, m.Data(l))\n\t\tcase typ == ctlOpts[ctlPacketInfo].name && l >= ctlOpts[ctlPacketInfo].length:\n\t\t\tctlOpts[ctlPacketInfo].parse(cm, m.Data(l))\n\t\tcase typ == ctlOpts[ctlPathMTU].name && l >= ctlOpts[ctlPathMTU].length:\n\t\t\tctlOpts[ctlPathMTU].parse(cm, m.Data(l))\n\t\t}\n\t}\n\treturn nil\n}\n\n// NewControlMessage returns a new control message.\n//\n// The returned message is large enough for options specified by cf.\nfunc NewControlMessage(cf ControlFlags) []byte {\n\topt := rawOpt{cflags: cf}\n\tvar l int\n\tif opt.isset(FlagTrafficClass) && ctlOpts[ctlTrafficClass].name > 0 {\n\t\tl += socket.ControlMessageSpace(ctlOpts[ctlTrafficClass].length)\n\t}\n\tif opt.isset(FlagHopLimit) && ctlOpts[ctlHopLimit].name > 0 {\n\t\tl += socket.ControlMessageSpace(ctlOpts[ctlHopLimit].length)\n\t}\n\tif opt.isset(flagPacketInfo) && ctlOpts[ctlPacketInfo].name > 0 {\n\t\tl += socket.ControlMessageSpace(ctlOpts[ctlPacketInfo].length)\n\t}\n\tif opt.isset(FlagPathMTU) && ctlOpts[ctlPathMTU].name > 0 {\n\t\tl += socket.ControlMessageSpace(ctlOpts[ctlPathMTU].length)\n\t}\n\tvar b []byte\n\tif l > 0 {\n\t\tb = make([]byte, l)\n\t}\n\treturn b\n}\n\n// Ancillary data socket options\nconst (\n\tctlTrafficClass = iota // header field\n\tctlHopLimit            // header field\n\tctlPacketInfo          // inbound or outbound packet path\n\tctlNextHop             // nexthop\n\tctlPathMTU             // path mtu\n\tctlMax\n)\n\n// A ctlOpt represents a binding for ancillary data socket option.\ntype ctlOpt struct {\n\tname    int // option name, must be equal or greater than 1\n\tlength  int // option length\n\tmarshal func([]byte, *ControlMessage) []byte\n\tparse   func(*ControlMessage, []byte)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/control_rfc2292_unix.go",
    "content": "// Copyright 2013 The Go 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\n//go:build darwin\n\npackage ipv6\n\nimport (\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc marshal2292HopLimit(b []byte, cm *ControlMessage) []byte {\n\tm := socket.ControlMessage(b)\n\tm.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_2292HOPLIMIT, 4)\n\tif cm != nil {\n\t\tsocket.NativeEndian.PutUint32(m.Data(4), uint32(cm.HopLimit))\n\t}\n\treturn m.Next(4)\n}\n\nfunc marshal2292PacketInfo(b []byte, cm *ControlMessage) []byte {\n\tm := socket.ControlMessage(b)\n\tm.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_2292PKTINFO, sizeofInet6Pktinfo)\n\tif cm != nil {\n\t\tpi := (*inet6Pktinfo)(unsafe.Pointer(&m.Data(sizeofInet6Pktinfo)[0]))\n\t\tif ip := cm.Src.To16(); ip != nil && ip.To4() == nil {\n\t\t\tcopy(pi.Addr[:], ip)\n\t\t}\n\t\tif cm.IfIndex > 0 {\n\t\t\tpi.setIfindex(cm.IfIndex)\n\t\t}\n\t}\n\treturn m.Next(sizeofInet6Pktinfo)\n}\n\nfunc marshal2292NextHop(b []byte, cm *ControlMessage) []byte {\n\tm := socket.ControlMessage(b)\n\tm.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_2292NEXTHOP, sizeofSockaddrInet6)\n\tif cm != nil {\n\t\tsa := (*sockaddrInet6)(unsafe.Pointer(&m.Data(sizeofSockaddrInet6)[0]))\n\t\tsa.setSockaddr(cm.NextHop, cm.IfIndex)\n\t}\n\treturn m.Next(sizeofSockaddrInet6)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go",
    "content": "// Copyright 2013 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\npackage ipv6\n\nimport (\n\t\"net\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc marshalTrafficClass(b []byte, cm *ControlMessage) []byte {\n\tm := socket.ControlMessage(b)\n\tm.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_TCLASS, 4)\n\tif cm != nil {\n\t\tsocket.NativeEndian.PutUint32(m.Data(4), uint32(cm.TrafficClass))\n\t}\n\treturn m.Next(4)\n}\n\nfunc parseTrafficClass(cm *ControlMessage, b []byte) {\n\tcm.TrafficClass = int(socket.NativeEndian.Uint32(b[:4]))\n}\n\nfunc marshalHopLimit(b []byte, cm *ControlMessage) []byte {\n\tm := socket.ControlMessage(b)\n\tm.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_HOPLIMIT, 4)\n\tif cm != nil {\n\t\tsocket.NativeEndian.PutUint32(m.Data(4), uint32(cm.HopLimit))\n\t}\n\treturn m.Next(4)\n}\n\nfunc parseHopLimit(cm *ControlMessage, b []byte) {\n\tcm.HopLimit = int(socket.NativeEndian.Uint32(b[:4]))\n}\n\nfunc marshalPacketInfo(b []byte, cm *ControlMessage) []byte {\n\tm := socket.ControlMessage(b)\n\tm.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_PKTINFO, sizeofInet6Pktinfo)\n\tif cm != nil {\n\t\tpi := (*inet6Pktinfo)(unsafe.Pointer(&m.Data(sizeofInet6Pktinfo)[0]))\n\t\tif ip := cm.Src.To16(); ip != nil && ip.To4() == nil {\n\t\t\tcopy(pi.Addr[:], ip)\n\t\t}\n\t\tif cm.IfIndex > 0 {\n\t\t\tpi.setIfindex(cm.IfIndex)\n\t\t}\n\t}\n\treturn m.Next(sizeofInet6Pktinfo)\n}\n\nfunc parsePacketInfo(cm *ControlMessage, b []byte) {\n\tpi := (*inet6Pktinfo)(unsafe.Pointer(&b[0]))\n\tif len(cm.Dst) < net.IPv6len {\n\t\tcm.Dst = make(net.IP, net.IPv6len)\n\t}\n\tcopy(cm.Dst, pi.Addr[:])\n\tcm.IfIndex = int(pi.Ifindex)\n}\n\nfunc marshalNextHop(b []byte, cm *ControlMessage) []byte {\n\tm := socket.ControlMessage(b)\n\tm.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_NEXTHOP, sizeofSockaddrInet6)\n\tif cm != nil {\n\t\tsa := (*sockaddrInet6)(unsafe.Pointer(&m.Data(sizeofSockaddrInet6)[0]))\n\t\tsa.setSockaddr(cm.NextHop, cm.IfIndex)\n\t}\n\treturn m.Next(sizeofSockaddrInet6)\n}\n\nfunc parseNextHop(cm *ControlMessage, b []byte) {\n}\n\nfunc marshalPathMTU(b []byte, cm *ControlMessage) []byte {\n\tm := socket.ControlMessage(b)\n\tm.MarshalHeader(iana.ProtocolIPv6, unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo)\n\treturn m.Next(sizeofIPv6Mtuinfo)\n}\n\nfunc parsePathMTU(cm *ControlMessage, b []byte) {\n\tmi := (*ipv6Mtuinfo)(unsafe.Pointer(&b[0]))\n\tif len(cm.Dst) < net.IPv6len {\n\t\tcm.Dst = make(net.IP, net.IPv6len)\n\t}\n\tcopy(cm.Dst, mi.Addr.Addr[:])\n\tcm.IfIndex = int(mi.Addr.Scope_id)\n\tcm.MTU = int(mi.Mtu)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/control_stub.go",
    "content": "// Copyright 2013 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos\n\npackage ipv6\n\nimport \"golang.org/x/net/internal/socket\"\n\nfunc setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {\n\treturn errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/control_unix.go",
    "content": "// Copyright 2013 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\npackage ipv6\n\nimport \"golang.org/x/net/internal/socket\"\n\nfunc setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {\n\topt.Lock()\n\tdefer opt.Unlock()\n\tif so, ok := sockOpts[ssoReceiveTrafficClass]; ok && cf&FlagTrafficClass != 0 {\n\t\tif err := so.SetInt(c, boolint(on)); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif on {\n\t\t\topt.set(FlagTrafficClass)\n\t\t} else {\n\t\t\topt.clear(FlagTrafficClass)\n\t\t}\n\t}\n\tif so, ok := sockOpts[ssoReceiveHopLimit]; ok && cf&FlagHopLimit != 0 {\n\t\tif err := so.SetInt(c, boolint(on)); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif on {\n\t\t\topt.set(FlagHopLimit)\n\t\t} else {\n\t\t\topt.clear(FlagHopLimit)\n\t\t}\n\t}\n\tif so, ok := sockOpts[ssoReceivePacketInfo]; ok && cf&flagPacketInfo != 0 {\n\t\tif err := so.SetInt(c, boolint(on)); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif on {\n\t\t\topt.set(cf & flagPacketInfo)\n\t\t} else {\n\t\t\topt.clear(cf & flagPacketInfo)\n\t\t}\n\t}\n\tif so, ok := sockOpts[ssoReceivePathMTU]; ok && cf&FlagPathMTU != 0 {\n\t\tif err := so.SetInt(c, boolint(on)); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif on {\n\t\t\topt.set(FlagPathMTU)\n\t\t} else {\n\t\t\topt.clear(FlagPathMTU)\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/control_windows.go",
    "content": "// Copyright 2013 The Go 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 ipv6\n\nimport \"golang.org/x/net/internal/socket\"\n\nfunc setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {\n\t// TODO(mikio): implement this\n\treturn errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/dgramopt.go",
    "content": "// Copyright 2013 The Go 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 ipv6\n\nimport (\n\t\"net\"\n\n\t\"golang.org/x/net/bpf\"\n)\n\n// MulticastHopLimit returns the hop limit field value for outgoing\n// multicast packets.\nfunc (c *dgramOpt) MulticastHopLimit() (int, error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoMulticastHopLimit]\n\tif !ok {\n\t\treturn 0, errNotImplemented\n\t}\n\treturn so.GetInt(c.Conn)\n}\n\n// SetMulticastHopLimit sets the hop limit field value for future\n// outgoing multicast packets.\nfunc (c *dgramOpt) SetMulticastHopLimit(hoplim int) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoMulticastHopLimit]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\treturn so.SetInt(c.Conn, hoplim)\n}\n\n// MulticastInterface returns the default interface for multicast\n// packet transmissions.\nfunc (c *dgramOpt) MulticastInterface() (*net.Interface, error) {\n\tif !c.ok() {\n\t\treturn nil, errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoMulticastInterface]\n\tif !ok {\n\t\treturn nil, errNotImplemented\n\t}\n\treturn so.getMulticastInterface(c.Conn)\n}\n\n// SetMulticastInterface sets the default interface for future\n// multicast packet transmissions.\nfunc (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoMulticastInterface]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\treturn so.setMulticastInterface(c.Conn, ifi)\n}\n\n// MulticastLoopback reports whether transmitted multicast packets\n// should be copied and send back to the originator.\nfunc (c *dgramOpt) MulticastLoopback() (bool, error) {\n\tif !c.ok() {\n\t\treturn false, errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoMulticastLoopback]\n\tif !ok {\n\t\treturn false, errNotImplemented\n\t}\n\ton, err := so.GetInt(c.Conn)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\treturn on == 1, nil\n}\n\n// SetMulticastLoopback sets whether transmitted multicast packets\n// should be copied and send back to the originator.\nfunc (c *dgramOpt) SetMulticastLoopback(on bool) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoMulticastLoopback]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\treturn so.SetInt(c.Conn, boolint(on))\n}\n\n// JoinGroup joins the group address group on the interface ifi.\n// By default all sources that can cast data to group are accepted.\n// It's possible to mute and unmute data transmission from a specific\n// source by using ExcludeSourceSpecificGroup and\n// IncludeSourceSpecificGroup.\n// JoinGroup uses the system assigned multicast interface when ifi is\n// nil, although this is not recommended because the assignment\n// depends on platforms and sometimes it might require routing\n// configuration.\nfunc (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoJoinGroup]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\tgrp := netAddrToIP16(group)\n\tif grp == nil {\n\t\treturn errMissingAddress\n\t}\n\treturn so.setGroup(c.Conn, ifi, grp)\n}\n\n// LeaveGroup leaves the group address group on the interface ifi\n// regardless of whether the group is any-source group or\n// source-specific group.\nfunc (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoLeaveGroup]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\tgrp := netAddrToIP16(group)\n\tif grp == nil {\n\t\treturn errMissingAddress\n\t}\n\treturn so.setGroup(c.Conn, ifi, grp)\n}\n\n// JoinSourceSpecificGroup joins the source-specific group comprising\n// group and source on the interface ifi.\n// JoinSourceSpecificGroup uses the system assigned multicast\n// interface when ifi is nil, although this is not recommended because\n// the assignment depends on platforms and sometimes it might require\n// routing configuration.\nfunc (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoJoinSourceGroup]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\tgrp := netAddrToIP16(group)\n\tif grp == nil {\n\t\treturn errMissingAddress\n\t}\n\tsrc := netAddrToIP16(source)\n\tif src == nil {\n\t\treturn errMissingAddress\n\t}\n\treturn so.setSourceGroup(c.Conn, ifi, grp, src)\n}\n\n// LeaveSourceSpecificGroup leaves the source-specific group on the\n// interface ifi.\nfunc (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoLeaveSourceGroup]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\tgrp := netAddrToIP16(group)\n\tif grp == nil {\n\t\treturn errMissingAddress\n\t}\n\tsrc := netAddrToIP16(source)\n\tif src == nil {\n\t\treturn errMissingAddress\n\t}\n\treturn so.setSourceGroup(c.Conn, ifi, grp, src)\n}\n\n// ExcludeSourceSpecificGroup excludes the source-specific group from\n// the already joined any-source groups by JoinGroup on the interface\n// ifi.\nfunc (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoBlockSourceGroup]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\tgrp := netAddrToIP16(group)\n\tif grp == nil {\n\t\treturn errMissingAddress\n\t}\n\tsrc := netAddrToIP16(source)\n\tif src == nil {\n\t\treturn errMissingAddress\n\t}\n\treturn so.setSourceGroup(c.Conn, ifi, grp, src)\n}\n\n// IncludeSourceSpecificGroup includes the excluded source-specific\n// group by ExcludeSourceSpecificGroup again on the interface ifi.\nfunc (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoUnblockSourceGroup]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\tgrp := netAddrToIP16(group)\n\tif grp == nil {\n\t\treturn errMissingAddress\n\t}\n\tsrc := netAddrToIP16(source)\n\tif src == nil {\n\t\treturn errMissingAddress\n\t}\n\treturn so.setSourceGroup(c.Conn, ifi, grp, src)\n}\n\n// Checksum reports whether the kernel will compute, store or verify a\n// checksum for both incoming and outgoing packets. If on is true, it\n// returns an offset in bytes into the data of where the checksum\n// field is located.\nfunc (c *dgramOpt) Checksum() (on bool, offset int, err error) {\n\tif !c.ok() {\n\t\treturn false, 0, errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoChecksum]\n\tif !ok {\n\t\treturn false, 0, errNotImplemented\n\t}\n\toffset, err = so.GetInt(c.Conn)\n\tif err != nil {\n\t\treturn false, 0, err\n\t}\n\tif offset < 0 {\n\t\treturn false, 0, nil\n\t}\n\treturn true, offset, nil\n}\n\n// SetChecksum enables the kernel checksum processing. If on is true,\n// the offset should be an offset in bytes into the data of where the\n// checksum field is located.\nfunc (c *dgramOpt) SetChecksum(on bool, offset int) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoChecksum]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\tif !on {\n\t\toffset = -1\n\t}\n\treturn so.SetInt(c.Conn, offset)\n}\n\n// ICMPFilter returns an ICMP filter.\nfunc (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {\n\tif !c.ok() {\n\t\treturn nil, errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoICMPFilter]\n\tif !ok {\n\t\treturn nil, errNotImplemented\n\t}\n\treturn so.getICMPFilter(c.Conn)\n}\n\n// SetICMPFilter deploys the ICMP filter.\nfunc (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoICMPFilter]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\treturn so.setICMPFilter(c.Conn, f)\n}\n\n// SetBPF attaches a BPF program to the connection.\n//\n// Only supported on Linux.\nfunc (c *dgramOpt) SetBPF(filter []bpf.RawInstruction) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoAttachFilter]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\treturn so.setBPF(c.Conn, filter)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/doc.go",
    "content": "// Copyright 2013 The Go 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\n// Package ipv6 implements IP-level socket options for the Internet\n// Protocol version 6.\n//\n// The package provides IP-level socket options that allow\n// manipulation of IPv6 facilities.\n//\n// The IPv6 protocol is defined in RFC 8200.\n// Socket interface extensions are defined in RFC 3493, RFC 3542 and\n// RFC 3678.\n// MLDv1 and MLDv2 are defined in RFC 2710 and RFC 3810.\n// Source-specific multicast is defined in RFC 4607.\n//\n// On Darwin, this package requires OS X Mavericks version 10.9 or\n// above, or equivalent.\n//\n// # Unicasting\n//\n// The options for unicasting are available for net.TCPConn,\n// net.UDPConn and net.IPConn which are created as network connections\n// that use the IPv6 transport. When a single TCP connection carrying\n// a data flow of multiple packets needs to indicate the flow is\n// important, Conn is used to set the traffic class field on the IPv6\n// header for each packet.\n//\n//\tln, err := net.Listen(\"tcp6\", \"[::]:1024\")\n//\tif err != nil {\n//\t\t// error handling\n//\t}\n//\tdefer ln.Close()\n//\tfor {\n//\t\tc, err := ln.Accept()\n//\t\tif err != nil {\n//\t\t\t// error handling\n//\t\t}\n//\t\tgo func(c net.Conn) {\n//\t\t\tdefer c.Close()\n//\n// The outgoing packets will be labeled DiffServ assured forwarding\n// class 1 low drop precedence, known as AF11 packets.\n//\n//\t\t\tif err := ipv6.NewConn(c).SetTrafficClass(0x28); err != nil {\n//\t\t\t\t// error handling\n//\t\t\t}\n//\t\t\tif _, err := c.Write(data); err != nil {\n//\t\t\t\t// error handling\n//\t\t\t}\n//\t\t}(c)\n//\t}\n//\n// # Multicasting\n//\n// The options for multicasting are available for net.UDPConn and\n// net.IPConn which are created as network connections that use the\n// IPv6 transport. A few network facilities must be prepared before\n// you begin multicasting, at a minimum joining network interfaces and\n// multicast groups.\n//\n//\ten0, err := net.InterfaceByName(\"en0\")\n//\tif err != nil {\n//\t\t// error handling\n//\t}\n//\ten1, err := net.InterfaceByIndex(911)\n//\tif err != nil {\n//\t\t// error handling\n//\t}\n//\tgroup := net.ParseIP(\"ff02::114\")\n//\n// First, an application listens to an appropriate address with an\n// appropriate service port.\n//\n//\tc, err := net.ListenPacket(\"udp6\", \"[::]:1024\")\n//\tif err != nil {\n//\t\t// error handling\n//\t}\n//\tdefer c.Close()\n//\n// Second, the application joins multicast groups, starts listening to\n// the groups on the specified network interfaces. Note that the\n// service port for transport layer protocol does not matter with this\n// operation as joining groups affects only network and link layer\n// protocols, such as IPv6 and Ethernet.\n//\n//\tp := ipv6.NewPacketConn(c)\n//\tif err := p.JoinGroup(en0, &net.UDPAddr{IP: group}); err != nil {\n//\t\t// error handling\n//\t}\n//\tif err := p.JoinGroup(en1, &net.UDPAddr{IP: group}); err != nil {\n//\t\t// error handling\n//\t}\n//\n// The application might set per packet control message transmissions\n// between the protocol stack within the kernel. When the application\n// needs a destination address on an incoming packet,\n// SetControlMessage of PacketConn is used to enable control message\n// transmissions.\n//\n//\tif err := p.SetControlMessage(ipv6.FlagDst, true); err != nil {\n//\t\t// error handling\n//\t}\n//\n// The application could identify whether the received packets are\n// of interest by using the control message that contains the\n// destination address of the received packet.\n//\n//\tb := make([]byte, 1500)\n//\tfor {\n//\t\tn, rcm, src, err := p.ReadFrom(b)\n//\t\tif err != nil {\n//\t\t\t// error handling\n//\t\t}\n//\t\tif rcm.Dst.IsMulticast() {\n//\t\t\tif rcm.Dst.Equal(group) {\n//\t\t\t\t// joined group, do something\n//\t\t\t} else {\n//\t\t\t\t// unknown group, discard\n//\t\t\t\tcontinue\n//\t\t\t}\n//\t\t}\n//\n// The application can also send both unicast and multicast packets.\n//\n//\t\tp.SetTrafficClass(0x0)\n//\t\tp.SetHopLimit(16)\n//\t\tif _, err := p.WriteTo(data[:n], nil, src); err != nil {\n//\t\t\t// error handling\n//\t\t}\n//\t\tdst := &net.UDPAddr{IP: group, Port: 1024}\n//\t\twcm := ipv6.ControlMessage{TrafficClass: 0xe0, HopLimit: 1}\n//\t\tfor _, ifi := range []*net.Interface{en0, en1} {\n//\t\t\twcm.IfIndex = ifi.Index\n//\t\t\tif _, err := p.WriteTo(data[:n], &wcm, dst); err != nil {\n//\t\t\t\t// error handling\n//\t\t\t}\n//\t\t}\n//\t}\n//\n// # More multicasting\n//\n// An application that uses PacketConn may join multiple multicast\n// groups. For example, a UDP listener with port 1024 might join two\n// different groups across over two different network interfaces by\n// using:\n//\n//\tc, err := net.ListenPacket(\"udp6\", \"[::]:1024\")\n//\tif err != nil {\n//\t\t// error handling\n//\t}\n//\tdefer c.Close()\n//\tp := ipv6.NewPacketConn(c)\n//\tif err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP(\"ff02::1:114\")}); err != nil {\n//\t\t// error handling\n//\t}\n//\tif err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP(\"ff02::2:114\")}); err != nil {\n//\t\t// error handling\n//\t}\n//\tif err := p.JoinGroup(en1, &net.UDPAddr{IP: net.ParseIP(\"ff02::2:114\")}); err != nil {\n//\t\t// error handling\n//\t}\n//\n// It is possible for multiple UDP listeners that listen on the same\n// UDP port to join the same multicast group. The net package will\n// provide a socket that listens to a wildcard address with reusable\n// UDP port when an appropriate multicast address prefix is passed to\n// the net.ListenPacket or net.ListenUDP.\n//\n//\tc1, err := net.ListenPacket(\"udp6\", \"[ff02::]:1024\")\n//\tif err != nil {\n//\t\t// error handling\n//\t}\n//\tdefer c1.Close()\n//\tc2, err := net.ListenPacket(\"udp6\", \"[ff02::]:1024\")\n//\tif err != nil {\n//\t\t// error handling\n//\t}\n//\tdefer c2.Close()\n//\tp1 := ipv6.NewPacketConn(c1)\n//\tif err := p1.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP(\"ff02::114\")}); err != nil {\n//\t\t// error handling\n//\t}\n//\tp2 := ipv6.NewPacketConn(c2)\n//\tif err := p2.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP(\"ff02::114\")}); err != nil {\n//\t\t// error handling\n//\t}\n//\n// Also it is possible for the application to leave or rejoin a\n// multicast group on the network interface.\n//\n//\tif err := p.LeaveGroup(en0, &net.UDPAddr{IP: net.ParseIP(\"ff02::114\")}); err != nil {\n//\t\t// error handling\n//\t}\n//\tif err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP(\"ff01::114\")}); err != nil {\n//\t\t// error handling\n//\t}\n//\n// # Source-specific multicasting\n//\n// An application that uses PacketConn on MLDv2 supported platform is\n// able to join source-specific multicast groups.\n// The application may use JoinSourceSpecificGroup and\n// LeaveSourceSpecificGroup for the operation known as \"include\" mode,\n//\n//\tssmgroup := net.UDPAddr{IP: net.ParseIP(\"ff32::8000:9\")}\n//\tssmsource := net.UDPAddr{IP: net.ParseIP(\"fe80::cafe\")}\n//\tif err := p.JoinSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil {\n//\t\t// error handling\n//\t}\n//\tif err := p.LeaveSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil {\n//\t\t// error handling\n//\t}\n//\n// or JoinGroup, ExcludeSourceSpecificGroup,\n// IncludeSourceSpecificGroup and LeaveGroup for the operation known\n// as \"exclude\" mode.\n//\n//\texclsource := net.UDPAddr{IP: net.ParseIP(\"fe80::dead\")}\n//\tif err := p.JoinGroup(en0, &ssmgroup); err != nil {\n//\t\t// error handling\n//\t}\n//\tif err := p.ExcludeSourceSpecificGroup(en0, &ssmgroup, &exclsource); err != nil {\n//\t\t// error handling\n//\t}\n//\tif err := p.LeaveGroup(en0, &ssmgroup); err != nil {\n//\t\t// error handling\n//\t}\n//\n// Note that it depends on each platform implementation what happens\n// when an application which runs on MLDv2 unsupported platform uses\n// JoinSourceSpecificGroup and LeaveSourceSpecificGroup.\n// In general the platform tries to fall back to conversations using\n// MLDv1 and starts to listen to multicast traffic.\n// In the fallback case, ExcludeSourceSpecificGroup and\n// IncludeSourceSpecificGroup may return an error.\npackage ipv6 // import \"golang.org/x/net/ipv6\"\n\n// BUG(mikio): This package is not implemented on JS, NaCl and Plan 9.\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/endpoint.go",
    "content": "// Copyright 2013 The Go 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 ipv6\n\nimport (\n\t\"net\"\n\t\"time\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\n// BUG(mikio): On Windows, the JoinSourceSpecificGroup,\n// LeaveSourceSpecificGroup, ExcludeSourceSpecificGroup and\n// IncludeSourceSpecificGroup methods of PacketConn are not\n// implemented.\n\n// A Conn represents a network endpoint that uses IPv6 transport.\n// It allows to set basic IP-level socket options such as traffic\n// class and hop limit.\ntype Conn struct {\n\tgenericOpt\n}\n\ntype genericOpt struct {\n\t*socket.Conn\n}\n\nfunc (c *genericOpt) ok() bool { return c != nil && c.Conn != nil }\n\n// PathMTU returns a path MTU value for the destination associated\n// with the endpoint.\nfunc (c *Conn) PathMTU() (int, error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoPathMTU]\n\tif !ok {\n\t\treturn 0, errNotImplemented\n\t}\n\t_, mtu, err := so.getMTUInfo(c.Conn)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn mtu, nil\n}\n\n// NewConn returns a new Conn.\nfunc NewConn(c net.Conn) *Conn {\n\tcc, _ := socket.NewConn(c)\n\treturn &Conn{\n\t\tgenericOpt: genericOpt{Conn: cc},\n\t}\n}\n\n// A PacketConn represents a packet network endpoint that uses IPv6\n// transport. It is used to control several IP-level socket options\n// including IPv6 header manipulation. It also provides datagram\n// based network I/O methods specific to the IPv6 and higher layer\n// protocols such as OSPF, GRE, and UDP.\ntype PacketConn struct {\n\tgenericOpt\n\tdgramOpt\n\tpayloadHandler\n}\n\ntype dgramOpt struct {\n\t*socket.Conn\n}\n\nfunc (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil }\n\n// SetControlMessage allows to receive the per packet basis IP-level\n// socket options.\nfunc (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {\n\tif !c.payloadHandler.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on)\n}\n\n// SetDeadline sets the read and write deadlines associated with the\n// endpoint.\nfunc (c *PacketConn) SetDeadline(t time.Time) error {\n\tif !c.payloadHandler.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn c.payloadHandler.SetDeadline(t)\n}\n\n// SetReadDeadline sets the read deadline associated with the\n// endpoint.\nfunc (c *PacketConn) SetReadDeadline(t time.Time) error {\n\tif !c.payloadHandler.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn c.payloadHandler.SetReadDeadline(t)\n}\n\n// SetWriteDeadline sets the write deadline associated with the\n// endpoint.\nfunc (c *PacketConn) SetWriteDeadline(t time.Time) error {\n\tif !c.payloadHandler.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn c.payloadHandler.SetWriteDeadline(t)\n}\n\n// Close closes the endpoint.\nfunc (c *PacketConn) Close() error {\n\tif !c.payloadHandler.ok() {\n\t\treturn errInvalidConn\n\t}\n\treturn c.payloadHandler.Close()\n}\n\n// NewPacketConn returns a new PacketConn using c as its underlying\n// transport.\nfunc NewPacketConn(c net.PacketConn) *PacketConn {\n\tcc, _ := socket.NewConn(c.(net.Conn))\n\treturn &PacketConn{\n\t\tgenericOpt:     genericOpt{Conn: cc},\n\t\tdgramOpt:       dgramOpt{Conn: cc},\n\t\tpayloadHandler: payloadHandler{PacketConn: c, Conn: cc},\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/genericopt.go",
    "content": "// Copyright 2013 The Go 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 ipv6\n\n// TrafficClass returns the traffic class field value for outgoing\n// packets.\nfunc (c *genericOpt) TrafficClass() (int, error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoTrafficClass]\n\tif !ok {\n\t\treturn 0, errNotImplemented\n\t}\n\treturn so.GetInt(c.Conn)\n}\n\n// SetTrafficClass sets the traffic class field value for future\n// outgoing packets.\nfunc (c *genericOpt) SetTrafficClass(tclass int) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoTrafficClass]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\treturn so.SetInt(c.Conn, tclass)\n}\n\n// HopLimit returns the hop limit field value for outgoing packets.\nfunc (c *genericOpt) HopLimit() (int, error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoHopLimit]\n\tif !ok {\n\t\treturn 0, errNotImplemented\n\t}\n\treturn so.GetInt(c.Conn)\n}\n\n// SetHopLimit sets the hop limit field value for future outgoing\n// packets.\nfunc (c *genericOpt) SetHopLimit(hoplim int) error {\n\tif !c.ok() {\n\t\treturn errInvalidConn\n\t}\n\tso, ok := sockOpts[ssoHopLimit]\n\tif !ok {\n\t\treturn errNotImplemented\n\t}\n\treturn so.SetInt(c.Conn, hoplim)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/header.go",
    "content": "// Copyright 2014 The Go 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 ipv6\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"net\"\n)\n\nconst (\n\tVersion   = 6  // protocol version\n\tHeaderLen = 40 // header length\n)\n\n// A Header represents an IPv6 base header.\ntype Header struct {\n\tVersion      int    // protocol version\n\tTrafficClass int    // traffic class\n\tFlowLabel    int    // flow label\n\tPayloadLen   int    // payload length\n\tNextHeader   int    // next header\n\tHopLimit     int    // hop limit\n\tSrc          net.IP // source address\n\tDst          net.IP // destination address\n}\n\nfunc (h *Header) String() string {\n\tif h == nil {\n\t\treturn \"<nil>\"\n\t}\n\treturn fmt.Sprintf(\"ver=%d tclass=%#x flowlbl=%#x payloadlen=%d nxthdr=%d hoplim=%d src=%v dst=%v\", h.Version, h.TrafficClass, h.FlowLabel, h.PayloadLen, h.NextHeader, h.HopLimit, h.Src, h.Dst)\n}\n\n// ParseHeader parses b as an IPv6 base header.\nfunc ParseHeader(b []byte) (*Header, error) {\n\tif len(b) < HeaderLen {\n\t\treturn nil, errHeaderTooShort\n\t}\n\th := &Header{\n\t\tVersion:      int(b[0]) >> 4,\n\t\tTrafficClass: int(b[0]&0x0f)<<4 | int(b[1])>>4,\n\t\tFlowLabel:    int(b[1]&0x0f)<<16 | int(b[2])<<8 | int(b[3]),\n\t\tPayloadLen:   int(binary.BigEndian.Uint16(b[4:6])),\n\t\tNextHeader:   int(b[6]),\n\t\tHopLimit:     int(b[7]),\n\t}\n\th.Src = make(net.IP, net.IPv6len)\n\tcopy(h.Src, b[8:24])\n\th.Dst = make(net.IP, net.IPv6len)\n\tcopy(h.Dst, b[24:40])\n\treturn h, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/helper.go",
    "content": "// Copyright 2013 The Go 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 ipv6\n\nimport (\n\t\"errors\"\n\t\"net\"\n\t\"runtime\"\n)\n\nvar (\n\terrInvalidConn     = errors.New(\"invalid connection\")\n\terrMissingAddress  = errors.New(\"missing address\")\n\terrHeaderTooShort  = errors.New(\"header too short\")\n\terrInvalidConnType = errors.New(\"invalid conn type\")\n\terrNotImplemented  = errors.New(\"not implemented on \" + runtime.GOOS + \"/\" + runtime.GOARCH)\n)\n\nfunc boolint(b bool) int {\n\tif b {\n\t\treturn 1\n\t}\n\treturn 0\n}\n\nfunc netAddrToIP16(a net.Addr) net.IP {\n\tswitch v := a.(type) {\n\tcase *net.UDPAddr:\n\t\tif ip := v.IP.To16(); ip != nil && ip.To4() == nil {\n\t\t\treturn ip\n\t\t}\n\tcase *net.IPAddr:\n\t\tif ip := v.IP.To16(); ip != nil && ip.To4() == nil {\n\t\t\treturn ip\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc opAddr(a net.Addr) net.Addr {\n\tswitch a.(type) {\n\tcase *net.TCPAddr:\n\t\tif a == nil {\n\t\t\treturn nil\n\t\t}\n\tcase *net.UDPAddr:\n\t\tif a == nil {\n\t\t\treturn nil\n\t\t}\n\tcase *net.IPAddr:\n\t\tif a == nil {\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn a\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/iana.go",
    "content": "// go generate gen.go\n// Code generated by the command above; DO NOT EDIT.\n\npackage ipv6\n\n// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2018-03-09\nconst (\n\tICMPTypeDestinationUnreachable                ICMPType = 1   // Destination Unreachable\n\tICMPTypePacketTooBig                          ICMPType = 2   // Packet Too Big\n\tICMPTypeTimeExceeded                          ICMPType = 3   // Time Exceeded\n\tICMPTypeParameterProblem                      ICMPType = 4   // Parameter Problem\n\tICMPTypeEchoRequest                           ICMPType = 128 // Echo Request\n\tICMPTypeEchoReply                             ICMPType = 129 // Echo Reply\n\tICMPTypeMulticastListenerQuery                ICMPType = 130 // Multicast Listener Query\n\tICMPTypeMulticastListenerReport               ICMPType = 131 // Multicast Listener Report\n\tICMPTypeMulticastListenerDone                 ICMPType = 132 // Multicast Listener Done\n\tICMPTypeRouterSolicitation                    ICMPType = 133 // Router Solicitation\n\tICMPTypeRouterAdvertisement                   ICMPType = 134 // Router Advertisement\n\tICMPTypeNeighborSolicitation                  ICMPType = 135 // Neighbor Solicitation\n\tICMPTypeNeighborAdvertisement                 ICMPType = 136 // Neighbor Advertisement\n\tICMPTypeRedirect                              ICMPType = 137 // Redirect Message\n\tICMPTypeRouterRenumbering                     ICMPType = 138 // Router Renumbering\n\tICMPTypeNodeInformationQuery                  ICMPType = 139 // ICMP Node Information Query\n\tICMPTypeNodeInformationResponse               ICMPType = 140 // ICMP Node Information Response\n\tICMPTypeInverseNeighborDiscoverySolicitation  ICMPType = 141 // Inverse Neighbor Discovery Solicitation Message\n\tICMPTypeInverseNeighborDiscoveryAdvertisement ICMPType = 142 // Inverse Neighbor Discovery Advertisement Message\n\tICMPTypeVersion2MulticastListenerReport       ICMPType = 143 // Version 2 Multicast Listener Report\n\tICMPTypeHomeAgentAddressDiscoveryRequest      ICMPType = 144 // Home Agent Address Discovery Request Message\n\tICMPTypeHomeAgentAddressDiscoveryReply        ICMPType = 145 // Home Agent Address Discovery Reply Message\n\tICMPTypeMobilePrefixSolicitation              ICMPType = 146 // Mobile Prefix Solicitation\n\tICMPTypeMobilePrefixAdvertisement             ICMPType = 147 // Mobile Prefix Advertisement\n\tICMPTypeCertificationPathSolicitation         ICMPType = 148 // Certification Path Solicitation Message\n\tICMPTypeCertificationPathAdvertisement        ICMPType = 149 // Certification Path Advertisement Message\n\tICMPTypeMulticastRouterAdvertisement          ICMPType = 151 // Multicast Router Advertisement\n\tICMPTypeMulticastRouterSolicitation           ICMPType = 152 // Multicast Router Solicitation\n\tICMPTypeMulticastRouterTermination            ICMPType = 153 // Multicast Router Termination\n\tICMPTypeFMIPv6                                ICMPType = 154 // FMIPv6 Messages\n\tICMPTypeRPLControl                            ICMPType = 155 // RPL Control Message\n\tICMPTypeILNPv6LocatorUpdate                   ICMPType = 156 // ILNPv6 Locator Update Message\n\tICMPTypeDuplicateAddressRequest               ICMPType = 157 // Duplicate Address Request\n\tICMPTypeDuplicateAddressConfirmation          ICMPType = 158 // Duplicate Address Confirmation\n\tICMPTypeMPLControl                            ICMPType = 159 // MPL Control Message\n\tICMPTypeExtendedEchoRequest                   ICMPType = 160 // Extended Echo Request\n\tICMPTypeExtendedEchoReply                     ICMPType = 161 // Extended Echo Reply\n)\n\n// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2018-03-09\nvar icmpTypes = map[ICMPType]string{\n\t1:   \"destination unreachable\",\n\t2:   \"packet too big\",\n\t3:   \"time exceeded\",\n\t4:   \"parameter problem\",\n\t128: \"echo request\",\n\t129: \"echo reply\",\n\t130: \"multicast listener query\",\n\t131: \"multicast listener report\",\n\t132: \"multicast listener done\",\n\t133: \"router solicitation\",\n\t134: \"router advertisement\",\n\t135: \"neighbor solicitation\",\n\t136: \"neighbor advertisement\",\n\t137: \"redirect message\",\n\t138: \"router renumbering\",\n\t139: \"icmp node information query\",\n\t140: \"icmp node information response\",\n\t141: \"inverse neighbor discovery solicitation message\",\n\t142: \"inverse neighbor discovery advertisement message\",\n\t143: \"version 2 multicast listener report\",\n\t144: \"home agent address discovery request message\",\n\t145: \"home agent address discovery reply message\",\n\t146: \"mobile prefix solicitation\",\n\t147: \"mobile prefix advertisement\",\n\t148: \"certification path solicitation message\",\n\t149: \"certification path advertisement message\",\n\t151: \"multicast router advertisement\",\n\t152: \"multicast router solicitation\",\n\t153: \"multicast router termination\",\n\t154: \"fmipv6 messages\",\n\t155: \"rpl control message\",\n\t156: \"ilnpv6 locator update message\",\n\t157: \"duplicate address request\",\n\t158: \"duplicate address confirmation\",\n\t159: \"mpl control message\",\n\t160: \"extended echo request\",\n\t161: \"extended echo reply\",\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/icmp.go",
    "content": "// Copyright 2013 The Go 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 ipv6\n\nimport \"golang.org/x/net/internal/iana\"\n\n// BUG(mikio): On Windows, methods related to ICMPFilter are not\n// implemented.\n\n// An ICMPType represents a type of ICMP message.\ntype ICMPType int\n\nfunc (typ ICMPType) String() string {\n\ts, ok := icmpTypes[typ]\n\tif !ok {\n\t\treturn \"<nil>\"\n\t}\n\treturn s\n}\n\n// Protocol returns the ICMPv6 protocol number.\nfunc (typ ICMPType) Protocol() int {\n\treturn iana.ProtocolIPv6ICMP\n}\n\n// An ICMPFilter represents an ICMP message filter for incoming\n// packets. The filter belongs to a packet delivery path on a host and\n// it cannot interact with forwarding packets or tunnel-outer packets.\n//\n// Note: RFC 8200 defines a reasonable role model. A node means a\n// device that implements IP. A router means a node that forwards IP\n// packets not explicitly addressed to itself, and a host means a node\n// that is not a router.\ntype ICMPFilter struct {\n\ticmpv6Filter\n}\n\n// Accept accepts incoming ICMP packets including the type field value\n// typ.\nfunc (f *ICMPFilter) Accept(typ ICMPType) {\n\tf.accept(typ)\n}\n\n// Block blocks incoming ICMP packets including the type field value\n// typ.\nfunc (f *ICMPFilter) Block(typ ICMPType) {\n\tf.block(typ)\n}\n\n// SetAll sets the filter action to the filter.\nfunc (f *ICMPFilter) SetAll(block bool) {\n\tf.setAll(block)\n}\n\n// WillBlock reports whether the ICMP type will be blocked.\nfunc (f *ICMPFilter) WillBlock(typ ICMPType) bool {\n\treturn f.willBlock(typ)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/icmp_bsd.go",
    "content": "// Copyright 2013 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd\n\npackage ipv6\n\nfunc (f *icmpv6Filter) accept(typ ICMPType) {\n\tf.Filt[typ>>5] |= 1 << (uint32(typ) & 31)\n}\n\nfunc (f *icmpv6Filter) block(typ ICMPType) {\n\tf.Filt[typ>>5] &^= 1 << (uint32(typ) & 31)\n}\n\nfunc (f *icmpv6Filter) setAll(block bool) {\n\tfor i := range f.Filt {\n\t\tif block {\n\t\t\tf.Filt[i] = 0\n\t\t} else {\n\t\t\tf.Filt[i] = 1<<32 - 1\n\t\t}\n\t}\n}\n\nfunc (f *icmpv6Filter) willBlock(typ ICMPType) bool {\n\treturn f.Filt[typ>>5]&(1<<(uint32(typ)&31)) == 0\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/icmp_linux.go",
    "content": "// Copyright 2013 The Go 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 ipv6\n\nfunc (f *icmpv6Filter) accept(typ ICMPType) {\n\tf.Data[typ>>5] &^= 1 << (uint32(typ) & 31)\n}\n\nfunc (f *icmpv6Filter) block(typ ICMPType) {\n\tf.Data[typ>>5] |= 1 << (uint32(typ) & 31)\n}\n\nfunc (f *icmpv6Filter) setAll(block bool) {\n\tfor i := range f.Data {\n\t\tif block {\n\t\t\tf.Data[i] = 1<<32 - 1\n\t\t} else {\n\t\t\tf.Data[i] = 0\n\t\t}\n\t}\n}\n\nfunc (f *icmpv6Filter) willBlock(typ ICMPType) bool {\n\treturn f.Data[typ>>5]&(1<<(uint32(typ)&31)) != 0\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/icmp_solaris.go",
    "content": "// Copyright 2013 The Go 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 ipv6\n\nfunc (f *icmpv6Filter) accept(typ ICMPType) {\n\tf.X__icmp6_filt[typ>>5] |= 1 << (uint32(typ) & 31)\n}\n\nfunc (f *icmpv6Filter) block(typ ICMPType) {\n\tf.X__icmp6_filt[typ>>5] &^= 1 << (uint32(typ) & 31)\n}\n\nfunc (f *icmpv6Filter) setAll(block bool) {\n\tfor i := range f.X__icmp6_filt {\n\t\tif block {\n\t\t\tf.X__icmp6_filt[i] = 0\n\t\t} else {\n\t\t\tf.X__icmp6_filt[i] = 1<<32 - 1\n\t\t}\n\t}\n}\n\nfunc (f *icmpv6Filter) willBlock(typ ICMPType) bool {\n\treturn f.X__icmp6_filt[typ>>5]&(1<<(uint32(typ)&31)) == 0\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/icmp_stub.go",
    "content": "// Copyright 2013 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos\n\npackage ipv6\n\ntype icmpv6Filter struct {\n}\n\nfunc (f *icmpv6Filter) accept(typ ICMPType) {\n}\n\nfunc (f *icmpv6Filter) block(typ ICMPType) {\n}\n\nfunc (f *icmpv6Filter) setAll(block bool) {\n}\n\nfunc (f *icmpv6Filter) willBlock(typ ICMPType) bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/icmp_windows.go",
    "content": "// Copyright 2013 The Go 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 ipv6\n\nfunc (f *icmpv6Filter) accept(typ ICMPType) {\n\t// TODO(mikio): implement this\n}\n\nfunc (f *icmpv6Filter) block(typ ICMPType) {\n\t// TODO(mikio): implement this\n}\n\nfunc (f *icmpv6Filter) setAll(block bool) {\n\t// TODO(mikio): implement this\n}\n\nfunc (f *icmpv6Filter) willBlock(typ ICMPType) bool {\n\t// TODO(mikio): implement this\n\treturn false\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/icmp_zos.go",
    "content": "// Copyright 2020 The Go 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 ipv6\n\nfunc (f *icmpv6Filter) accept(typ ICMPType) {\n\tf.Filt[typ>>5] |= 1 << (uint32(typ) & 31)\n\n}\n\nfunc (f *icmpv6Filter) block(typ ICMPType) {\n\tf.Filt[typ>>5] &^= 1 << (uint32(typ) & 31)\n\n}\n\nfunc (f *icmpv6Filter) setAll(block bool) {\n\tfor i := range f.Filt {\n\t\tif block {\n\t\t\tf.Filt[i] = 0\n\t\t} else {\n\t\t\tf.Filt[i] = 1<<32 - 1\n\t\t}\n\t}\n}\n\nfunc (f *icmpv6Filter) willBlock(typ ICMPType) bool {\n\treturn f.Filt[typ>>5]&(1<<(uint32(typ)&31)) == 0\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/payload.go",
    "content": "// Copyright 2013 The Go 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 ipv6\n\nimport (\n\t\"net\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\n// BUG(mikio): On Windows, the ControlMessage for ReadFrom and WriteTo\n// methods of PacketConn is not implemented.\n\n// A payloadHandler represents the IPv6 datagram payload handler.\ntype payloadHandler struct {\n\tnet.PacketConn\n\t*socket.Conn\n\trawOpt\n}\n\nfunc (c *payloadHandler) ok() bool { return c != nil && c.PacketConn != nil && c.Conn != nil }\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/payload_cmsg.go",
    "content": "// Copyright 2013 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\npackage ipv6\n\nimport (\n\t\"net\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\n// ReadFrom reads a payload of the received IPv6 datagram, from the\n// endpoint c, copying the payload into b. It returns the number of\n// bytes copied into b, the control message cm and the source address\n// src of the received datagram.\nfunc (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {\n\tif !c.ok() {\n\t\treturn 0, nil, nil, errInvalidConn\n\t}\n\tc.rawOpt.RLock()\n\tm := socket.Message{\n\t\tBuffers: [][]byte{b},\n\t\tOOB:     NewControlMessage(c.rawOpt.cflags),\n\t}\n\tc.rawOpt.RUnlock()\n\tswitch c.PacketConn.(type) {\n\tcase *net.UDPConn:\n\t\tif err := c.RecvMsg(&m, 0); err != nil {\n\t\t\treturn 0, nil, nil, &net.OpError{Op: \"read\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}\n\t\t}\n\tcase *net.IPConn:\n\t\tif err := c.RecvMsg(&m, 0); err != nil {\n\t\t\treturn 0, nil, nil, &net.OpError{Op: \"read\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}\n\t\t}\n\tdefault:\n\t\treturn 0, nil, nil, &net.OpError{Op: \"read\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errInvalidConnType}\n\t}\n\tif m.NN > 0 {\n\t\tcm = new(ControlMessage)\n\t\tif err := cm.Parse(m.OOB[:m.NN]); err != nil {\n\t\t\treturn 0, nil, nil, &net.OpError{Op: \"read\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}\n\t\t}\n\t\tcm.Src = netAddrToIP16(m.Addr)\n\t}\n\treturn m.N, cm, m.Addr, nil\n}\n\n// WriteTo writes a payload of the IPv6 datagram, to the destination\n// address dst through the endpoint c, copying the payload from b. It\n// returns the number of bytes written. The control message cm allows\n// the IPv6 header fields and the datagram path to be specified. The\n// cm may be nil if control of the outgoing datagram is not required.\nfunc (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\tm := socket.Message{\n\t\tBuffers: [][]byte{b},\n\t\tOOB:     cm.Marshal(),\n\t\tAddr:    dst,\n\t}\n\terr = c.SendMsg(&m, 0)\n\tif err != nil {\n\t\terr = &net.OpError{Op: \"write\", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Addr: opAddr(dst), Err: err}\n\t}\n\treturn m.N, err\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/payload_nocmsg.go",
    "content": "// Copyright 2013 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos\n\npackage ipv6\n\nimport \"net\"\n\n// ReadFrom reads a payload of the received IPv6 datagram, from the\n// endpoint c, copying the payload into b. It returns the number of\n// bytes copied into b, the control message cm and the source address\n// src of the received datagram.\nfunc (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {\n\tif !c.ok() {\n\t\treturn 0, nil, nil, errInvalidConn\n\t}\n\tif n, src, err = c.PacketConn.ReadFrom(b); err != nil {\n\t\treturn 0, nil, nil, err\n\t}\n\treturn\n}\n\n// WriteTo writes a payload of the IPv6 datagram, to the destination\n// address dst through the endpoint c, copying the payload from b. It\n// returns the number of bytes written. The control message cm allows\n// the IPv6 header fields and the datagram path to be specified. The\n// cm may be nil if control of the outgoing datagram is not required.\nfunc (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {\n\tif !c.ok() {\n\t\treturn 0, errInvalidConn\n\t}\n\tif dst == nil {\n\t\treturn 0, errMissingAddress\n\t}\n\treturn c.PacketConn.WriteTo(b, dst)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sockopt.go",
    "content": "// Copyright 2014 The Go 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 ipv6\n\nimport \"golang.org/x/net/internal/socket\"\n\n// Sticky socket options\nconst (\n\tssoTrafficClass        = iota // header field for unicast packet, RFC 3542\n\tssoHopLimit                   // header field for unicast packet, RFC 3493\n\tssoMulticastInterface         // outbound interface for multicast packet, RFC 3493\n\tssoMulticastHopLimit          // header field for multicast packet, RFC 3493\n\tssoMulticastLoopback          // loopback for multicast packet, RFC 3493\n\tssoReceiveTrafficClass        // header field on received packet, RFC 3542\n\tssoReceiveHopLimit            // header field on received packet, RFC 2292 or 3542\n\tssoReceivePacketInfo          // incbound or outbound packet path, RFC 2292 or 3542\n\tssoReceivePathMTU             // path mtu, RFC 3542\n\tssoPathMTU                    // path mtu, RFC 3542\n\tssoChecksum                   // packet checksum, RFC 2292 or 3542\n\tssoICMPFilter                 // icmp filter, RFC 2292 or 3542\n\tssoJoinGroup                  // any-source multicast, RFC 3493\n\tssoLeaveGroup                 // any-source multicast, RFC 3493\n\tssoJoinSourceGroup            // source-specific multicast\n\tssoLeaveSourceGroup           // source-specific multicast\n\tssoBlockSourceGroup           // any-source or source-specific multicast\n\tssoUnblockSourceGroup         // any-source or source-specific multicast\n\tssoAttachFilter               // attach BPF for filtering inbound traffic\n)\n\n// Sticky socket option value types\nconst (\n\tssoTypeIPMreq = iota + 1\n\tssoTypeGroupReq\n\tssoTypeGroupSourceReq\n)\n\n// A sockOpt represents a binding for sticky socket option.\ntype sockOpt struct {\n\tsocket.Option\n\ttyp int // hint for option value type; optional\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sockopt_posix.go",
    "content": "// Copyright 2013 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos\n\npackage ipv6\n\nimport (\n\t\"net\"\n\t\"runtime\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/bpf\"\n\t\"golang.org/x/net/internal/socket\"\n)\n\nfunc (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) {\n\tn, err := so.GetInt(c)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn net.InterfaceByIndex(n)\n}\n\nfunc (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error {\n\tvar n int\n\tif ifi != nil {\n\t\tn = ifi.Index\n\t}\n\treturn so.SetInt(c, n)\n}\n\nfunc (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) {\n\tb := make([]byte, so.Len)\n\tn, err := so.Get(c, b)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif n != sizeofICMPv6Filter {\n\t\treturn nil, errNotImplemented\n\t}\n\treturn (*ICMPFilter)(unsafe.Pointer(&b[0])), nil\n}\n\nfunc (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error {\n\tb := (*[sizeofICMPv6Filter]byte)(unsafe.Pointer(f))[:sizeofICMPv6Filter]\n\treturn so.Set(c, b)\n}\n\nfunc (so *sockOpt) getMTUInfo(c *socket.Conn) (*net.Interface, int, error) {\n\tb := make([]byte, so.Len)\n\tn, err := so.Get(c, b)\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\tif n != sizeofIPv6Mtuinfo {\n\t\treturn nil, 0, errNotImplemented\n\t}\n\tmi := (*ipv6Mtuinfo)(unsafe.Pointer(&b[0]))\n\tif mi.Addr.Scope_id == 0 || runtime.GOOS == \"aix\" {\n\t\t// AIX kernel might return a wrong address.\n\t\treturn nil, int(mi.Mtu), nil\n\t}\n\tifi, err := net.InterfaceByIndex(int(mi.Addr.Scope_id))\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\treturn ifi, int(mi.Mtu), nil\n}\n\nfunc (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error {\n\tswitch so.typ {\n\tcase ssoTypeIPMreq:\n\t\treturn so.setIPMreq(c, ifi, grp)\n\tcase ssoTypeGroupReq:\n\t\treturn so.setGroupReq(c, ifi, grp)\n\tdefault:\n\t\treturn errNotImplemented\n\t}\n}\n\nfunc (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {\n\treturn so.setGroupSourceReq(c, ifi, grp, src)\n}\n\nfunc (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error {\n\treturn so.setAttachFilter(c, f)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sockopt_stub.go",
    "content": "// Copyright 2013 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos\n\npackage ipv6\n\nimport (\n\t\"net\"\n\n\t\"golang.org/x/net/bpf\"\n\t\"golang.org/x/net/internal/socket\"\n)\n\nfunc (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) {\n\treturn nil, errNotImplemented\n}\n\nfunc (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error {\n\treturn errNotImplemented\n}\n\nfunc (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) {\n\treturn nil, errNotImplemented\n}\n\nfunc (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error {\n\treturn errNotImplemented\n}\n\nfunc (so *sockOpt) getMTUInfo(c *socket.Conn) (*net.Interface, int, error) {\n\treturn nil, 0, errNotImplemented\n}\n\nfunc (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error {\n\treturn errNotImplemented\n}\n\nfunc (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {\n\treturn errNotImplemented\n}\n\nfunc (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error {\n\treturn errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sys_aix.go",
    "content": "// Copyright 2019 The Go 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\n// Added for go1.11 compatibility\n//go:build aix\n\npackage ipv6\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{\n\t\tctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},\n\t\tctlHopLimit:     {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},\n\t\tctlPacketInfo:   {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},\n\t\tctlNextHop:      {unix.IPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},\n\t\tctlPathMTU:      {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},\n\t}\n\n\tsockOpts = map[int]*sockOpt{\n\t\tssoTrafficClass:        {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},\n\t\tssoHopLimit:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},\n\t\tssoMulticastInterface:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},\n\t\tssoMulticastHopLimit:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},\n\t\tssoMulticastLoopback:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},\n\t\tssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},\n\t\tssoReceiveHopLimit:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},\n\t\tssoReceivePacketInfo:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},\n\t\tssoReceivePathMTU:      {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},\n\t\tssoPathMTU:             {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},\n\t\tssoChecksum:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},\n\t\tssoICMPFilter:          {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},\n\t\tssoJoinGroup:           {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},\n\t\tssoLeaveGroup:          {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},\n\t}\n)\n\nfunc (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {\n\tsa.Len = sizeofSockaddrInet6\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], ip)\n\tsa.Scope_id = uint32(i)\n}\n\nfunc (pi *inet6Pktinfo) setIfindex(i int) {\n\tpi.Ifindex = int32(i)\n}\n\nfunc (mreq *ipv6Mreq) setIfindex(i int) {\n\tmreq.Interface = uint32(i)\n}\n\nfunc (gr *groupReq) setGroup(grp net.IP) {\n\tsa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4))\n\tsa.Len = sizeofSockaddrInet6\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], grp)\n}\n\nfunc (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {\n\tsa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4))\n\tsa.Len = sizeofSockaddrInet6\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], grp)\n\tsa = (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 132))\n\tsa.Len = sizeofSockaddrInet6\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], src)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sys_asmreq.go",
    "content": "// Copyright 2013 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows\n\npackage ipv6\n\nimport (\n\t\"net\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\nfunc (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {\n\tvar mreq ipv6Mreq\n\tcopy(mreq.Multiaddr[:], grp)\n\tif ifi != nil {\n\t\tmreq.setIfindex(ifi.Index)\n\t}\n\tb := (*[sizeofIPv6Mreq]byte)(unsafe.Pointer(&mreq))[:sizeofIPv6Mreq]\n\treturn so.Set(c, b)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sys_asmreq_stub.go",
    "content": "// Copyright 2013 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows\n\npackage ipv6\n\nimport (\n\t\"net\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\nfunc (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {\n\treturn errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sys_bpf.go",
    "content": "// Copyright 2017 The Go 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\n//go:build linux\n\npackage ipv6\n\nimport (\n\t\"unsafe\"\n\n\t\"golang.org/x/net/bpf\"\n\t\"golang.org/x/net/internal/socket\"\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error {\n\tprog := unix.SockFprog{\n\t\tLen:    uint16(len(f)),\n\t\tFilter: (*unix.SockFilter)(unsafe.Pointer(&f[0])),\n\t}\n\tb := (*[unix.SizeofSockFprog]byte)(unsafe.Pointer(&prog))[:unix.SizeofSockFprog]\n\treturn so.Set(c, b)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sys_bpf_stub.go",
    "content": "// Copyright 2017 The Go 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\n//go:build !linux\n\npackage ipv6\n\nimport (\n\t\"golang.org/x/net/bpf\"\n\t\"golang.org/x/net/internal/socket\"\n)\n\nfunc (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error {\n\treturn errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sys_bsd.go",
    "content": "// Copyright 2013 The Go 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\n//go:build dragonfly || netbsd || openbsd\n\npackage ipv6\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{\n\t\tctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},\n\t\tctlHopLimit:     {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},\n\t\tctlPacketInfo:   {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},\n\t\tctlNextHop:      {unix.IPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},\n\t\tctlPathMTU:      {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},\n\t}\n\n\tsockOpts = map[int]*sockOpt{\n\t\tssoTrafficClass:        {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},\n\t\tssoHopLimit:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},\n\t\tssoMulticastInterface:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},\n\t\tssoMulticastHopLimit:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},\n\t\tssoMulticastLoopback:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},\n\t\tssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},\n\t\tssoReceiveHopLimit:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},\n\t\tssoReceivePacketInfo:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},\n\t\tssoReceivePathMTU:      {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},\n\t\tssoPathMTU:             {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},\n\t\tssoChecksum:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},\n\t\tssoICMPFilter:          {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},\n\t\tssoJoinGroup:           {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},\n\t\tssoLeaveGroup:          {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},\n\t}\n)\n\nfunc (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {\n\tsa.Len = sizeofSockaddrInet6\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], ip)\n\tsa.Scope_id = uint32(i)\n}\n\nfunc (pi *inet6Pktinfo) setIfindex(i int) {\n\tpi.Ifindex = uint32(i)\n}\n\nfunc (mreq *ipv6Mreq) setIfindex(i int) {\n\tmreq.Interface = uint32(i)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sys_darwin.go",
    "content": "// Copyright 2013 The Go 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 ipv6\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{\n\t\tctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},\n\t\tctlHopLimit:     {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},\n\t\tctlPacketInfo:   {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},\n\t\tctlNextHop:      {unix.IPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},\n\t\tctlPathMTU:      {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},\n\t}\n\n\tsockOpts = map[int]*sockOpt{\n\t\tssoHopLimit:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},\n\t\tssoMulticastInterface:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},\n\t\tssoMulticastHopLimit:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},\n\t\tssoMulticastLoopback:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},\n\t\tssoTrafficClass:        {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},\n\t\tssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},\n\t\tssoReceiveHopLimit:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},\n\t\tssoReceivePacketInfo:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},\n\t\tssoReceivePathMTU:      {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},\n\t\tssoPathMTU:             {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},\n\t\tssoChecksum:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},\n\t\tssoICMPFilter:          {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},\n\t\tssoJoinGroup:           {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoLeaveGroup:          {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoJoinSourceGroup:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoLeaveSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoBlockSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoUnblockSourceGroup:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t}\n)\n\nfunc (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {\n\tsa.Len = sizeofSockaddrInet6\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], ip)\n\tsa.Scope_id = uint32(i)\n}\n\nfunc (pi *inet6Pktinfo) setIfindex(i int) {\n\tpi.Ifindex = uint32(i)\n}\n\nfunc (mreq *ipv6Mreq) setIfindex(i int) {\n\tmreq.Interface = uint32(i)\n}\n\nfunc (gr *groupReq) setGroup(grp net.IP) {\n\tsa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4))\n\tsa.Len = sizeofSockaddrInet6\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], grp)\n}\n\nfunc (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {\n\tsa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4))\n\tsa.Len = sizeofSockaddrInet6\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], grp)\n\tsa = (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 132))\n\tsa.Len = sizeofSockaddrInet6\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], src)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sys_freebsd.go",
    "content": "// Copyright 2013 The Go 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 ipv6\n\nimport (\n\t\"net\"\n\t\"runtime\"\n\t\"strings\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{\n\t\tctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},\n\t\tctlHopLimit:     {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},\n\t\tctlPacketInfo:   {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},\n\t\tctlNextHop:      {unix.IPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},\n\t\tctlPathMTU:      {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},\n\t}\n\n\tsockOpts = map[int]sockOpt{\n\t\tssoTrafficClass:        {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},\n\t\tssoHopLimit:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},\n\t\tssoMulticastInterface:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},\n\t\tssoMulticastHopLimit:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},\n\t\tssoMulticastLoopback:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},\n\t\tssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},\n\t\tssoReceiveHopLimit:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},\n\t\tssoReceivePacketInfo:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},\n\t\tssoReceivePathMTU:      {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},\n\t\tssoPathMTU:             {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},\n\t\tssoChecksum:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},\n\t\tssoICMPFilter:          {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},\n\t\tssoJoinGroup:           {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoLeaveGroup:          {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoJoinSourceGroup:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoLeaveSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoBlockSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoUnblockSourceGroup:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t}\n)\n\nfunc init() {\n\tif runtime.GOOS == \"freebsd\" && runtime.GOARCH == \"386\" {\n\t\tarchs, _ := syscall.Sysctl(\"kern.supported_archs\")\n\t\tfor _, s := range strings.Fields(archs) {\n\t\t\tif s == \"amd64\" {\n\t\t\t\tcompatFreeBSD32 = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {\n\tsa.Len = sizeofSockaddrInet6\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], ip)\n\tsa.Scope_id = uint32(i)\n}\n\nfunc (pi *inet6Pktinfo) setIfindex(i int) {\n\tpi.Ifindex = uint32(i)\n}\n\nfunc (mreq *ipv6Mreq) setIfindex(i int) {\n\tmreq.Interface = uint32(i)\n}\n\nfunc (gr *groupReq) setGroup(grp net.IP) {\n\tsa := (*sockaddrInet6)(unsafe.Pointer(&gr.Group))\n\tsa.Len = sizeofSockaddrInet6\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], grp)\n}\n\nfunc (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {\n\tsa := (*sockaddrInet6)(unsafe.Pointer(&gsr.Group))\n\tsa.Len = sizeofSockaddrInet6\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], grp)\n\tsa = (*sockaddrInet6)(unsafe.Pointer(&gsr.Source))\n\tsa.Len = sizeofSockaddrInet6\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], src)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sys_linux.go",
    "content": "// Copyright 2013 The Go 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 ipv6\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{\n\t\tctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},\n\t\tctlHopLimit:     {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},\n\t\tctlPacketInfo:   {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},\n\t\tctlPathMTU:      {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},\n\t}\n\n\tsockOpts = map[int]*sockOpt{\n\t\tssoTrafficClass:        {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},\n\t\tssoHopLimit:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},\n\t\tssoMulticastInterface:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},\n\t\tssoMulticastHopLimit:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},\n\t\tssoMulticastLoopback:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},\n\t\tssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},\n\t\tssoReceiveHopLimit:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},\n\t\tssoReceivePacketInfo:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},\n\t\tssoReceivePathMTU:      {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},\n\t\tssoPathMTU:             {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},\n\t\tssoChecksum:            {Option: socket.Option{Level: iana.ProtocolReserved, Name: unix.IPV6_CHECKSUM, Len: 4}},\n\t\tssoICMPFilter:          {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMPV6_FILTER, Len: sizeofICMPv6Filter}},\n\t\tssoJoinGroup:           {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoLeaveGroup:          {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoJoinSourceGroup:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoLeaveSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoBlockSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoUnblockSourceGroup:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoAttachFilter:        {Option: socket.Option{Level: unix.SOL_SOCKET, Name: unix.SO_ATTACH_FILTER, Len: unix.SizeofSockFprog}},\n\t}\n)\n\nfunc (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], ip)\n\tsa.Scope_id = uint32(i)\n}\n\nfunc (pi *inet6Pktinfo) setIfindex(i int) {\n\tpi.Ifindex = int32(i)\n}\n\nfunc (mreq *ipv6Mreq) setIfindex(i int) {\n\tmreq.Ifindex = int32(i)\n}\n\nfunc (gr *groupReq) setGroup(grp net.IP) {\n\tsa := (*sockaddrInet6)(unsafe.Pointer(&gr.Group))\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], grp)\n}\n\nfunc (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {\n\tsa := (*sockaddrInet6)(unsafe.Pointer(&gsr.Group))\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], grp)\n\tsa = (*sockaddrInet6)(unsafe.Pointer(&gsr.Source))\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], src)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sys_solaris.go",
    "content": "// Copyright 2016 The Go 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 ipv6\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{\n\t\tctlTrafficClass: {unix.IPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},\n\t\tctlHopLimit:     {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},\n\t\tctlPacketInfo:   {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},\n\t\tctlNextHop:      {unix.IPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},\n\t\tctlPathMTU:      {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},\n\t}\n\n\tsockOpts = map[int]*sockOpt{\n\t\tssoTrafficClass:        {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},\n\t\tssoHopLimit:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},\n\t\tssoMulticastInterface:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},\n\t\tssoMulticastHopLimit:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},\n\t\tssoMulticastLoopback:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},\n\t\tssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},\n\t\tssoReceiveHopLimit:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},\n\t\tssoReceivePacketInfo:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},\n\t\tssoReceivePathMTU:      {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},\n\t\tssoPathMTU:             {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},\n\t\tssoChecksum:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},\n\t\tssoICMPFilter:          {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},\n\t\tssoJoinGroup:           {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoLeaveGroup:          {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoJoinSourceGroup:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoLeaveSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoBlockSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoUnblockSourceGroup:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t}\n)\n\nfunc (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], ip)\n\tsa.Scope_id = uint32(i)\n}\n\nfunc (pi *inet6Pktinfo) setIfindex(i int) {\n\tpi.Ifindex = uint32(i)\n}\n\nfunc (mreq *ipv6Mreq) setIfindex(i int) {\n\tmreq.Interface = uint32(i)\n}\n\nfunc (gr *groupReq) setGroup(grp net.IP) {\n\tsa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4))\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], grp)\n}\n\nfunc (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {\n\tsa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4))\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], grp)\n\tsa = (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 260))\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], src)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sys_ssmreq.go",
    "content": "// Copyright 2014 The Go 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\n//go:build aix || darwin || freebsd || linux || solaris || zos\n\npackage ipv6\n\nimport (\n\t\"net\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\nvar compatFreeBSD32 bool // 386 emulation on amd64\n\nfunc (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {\n\tvar gr groupReq\n\tif ifi != nil {\n\t\tgr.Interface = uint32(ifi.Index)\n\t}\n\tgr.setGroup(grp)\n\tvar b []byte\n\tif compatFreeBSD32 {\n\t\tvar d [sizeofGroupReq + 4]byte\n\t\ts := (*[sizeofGroupReq]byte)(unsafe.Pointer(&gr))\n\t\tcopy(d[:4], s[:4])\n\t\tcopy(d[8:], s[4:])\n\t\tb = d[:]\n\t} else {\n\t\tb = (*[sizeofGroupReq]byte)(unsafe.Pointer(&gr))[:sizeofGroupReq]\n\t}\n\treturn so.Set(c, b)\n}\n\nfunc (so *sockOpt) setGroupSourceReq(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {\n\tvar gsr groupSourceReq\n\tif ifi != nil {\n\t\tgsr.Interface = uint32(ifi.Index)\n\t}\n\tgsr.setSourceGroup(grp, src)\n\tvar b []byte\n\tif compatFreeBSD32 {\n\t\tvar d [sizeofGroupSourceReq + 4]byte\n\t\ts := (*[sizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr))\n\t\tcopy(d[:4], s[:4])\n\t\tcopy(d[8:], s[4:])\n\t\tb = d[:]\n\t} else {\n\t\tb = (*[sizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr))[:sizeofGroupSourceReq]\n\t}\n\treturn so.Set(c, b)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sys_ssmreq_stub.go",
    "content": "// Copyright 2014 The Go 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\n//go:build !aix && !darwin && !freebsd && !linux && !solaris && !zos\n\npackage ipv6\n\nimport (\n\t\"net\"\n\n\t\"golang.org/x/net/internal/socket\"\n)\n\nfunc (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {\n\treturn errNotImplemented\n}\n\nfunc (so *sockOpt) setGroupSourceReq(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {\n\treturn errNotImplemented\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sys_stub.go",
    "content": "// Copyright 2014 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos\n\npackage ipv6\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{}\n\n\tsockOpts = map[int]*sockOpt{}\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sys_windows.go",
    "content": "// Copyright 2013 The Go 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 ipv6\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\nconst (\n\tsizeofSockaddrInet6 = 0x1c\n\n\tsizeofIPv6Mreq     = 0x14\n\tsizeofIPv6Mtuinfo  = 0x20\n\tsizeofICMPv6Filter = 0\n)\n\ntype sockaddrInet6 struct {\n\tFamily   uint16\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tInterface uint32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype icmpv6Filter struct {\n\t// TODO(mikio): implement this\n}\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{}\n\n\tsockOpts = map[int]*sockOpt{\n\t\tssoHopLimit:           {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_UNICAST_HOPS, Len: 4}},\n\t\tssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_MULTICAST_IF, Len: 4}},\n\t\tssoMulticastHopLimit:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_MULTICAST_HOPS, Len: 4}},\n\t\tssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_MULTICAST_LOOP, Len: 4}},\n\t\tssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},\n\t\tssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIPv6, Name: windows.IPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},\n\t}\n)\n\nfunc (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], ip)\n\tsa.Scope_id = uint32(i)\n}\n\nfunc (mreq *ipv6Mreq) setIfindex(i int) {\n\tmreq.Interface = uint32(i)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/sys_zos.go",
    "content": "// Copyright 2020 The Go 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 ipv6\n\nimport (\n\t\"net\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/net/internal/iana\"\n\t\"golang.org/x/net/internal/socket\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nvar (\n\tctlOpts = [ctlMax]ctlOpt{\n\t\tctlHopLimit:   {unix.IPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},\n\t\tctlPacketInfo: {unix.IPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},\n\t\tctlPathMTU:    {unix.IPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},\n\t}\n\n\tsockOpts = map[int]*sockOpt{\n\t\tssoTrafficClass:        {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_TCLASS, Len: 4}},\n\t\tssoHopLimit:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_UNICAST_HOPS, Len: 4}},\n\t\tssoMulticastInterface:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_IF, Len: 4}},\n\t\tssoMulticastHopLimit:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_HOPS, Len: 4}},\n\t\tssoMulticastLoopback:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_MULTICAST_LOOP, Len: 4}},\n\t\tssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVTCLASS, Len: 4}},\n\t\tssoReceiveHopLimit:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVHOPLIMIT, Len: 4}},\n\t\tssoReceivePacketInfo:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPKTINFO, Len: 4}},\n\t\tssoReceivePathMTU:      {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_RECVPATHMTU, Len: 4}},\n\t\tssoChecksum:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.IPV6_CHECKSUM, Len: 4}},\n\t\tssoICMPFilter:          {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: unix.ICMP6_FILTER, Len: sizeofICMPv6Filter}},\n\t\tssoJoinGroup:           {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoLeaveGroup:          {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},\n\t\tssoJoinSourceGroup:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoLeaveSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoBlockSourceGroup:    {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t\tssoUnblockSourceGroup:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},\n\t}\n)\n\nfunc (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {\n\tsa.Family = syscall.AF_INET6\n\tcopy(sa.Addr[:], ip)\n\tsa.Scope_id = uint32(i)\n}\n\nfunc (pi *inet6Pktinfo) setIfindex(i int) {\n\tpi.Ifindex = uint32(i)\n}\n\nfunc (gr *groupReq) setGroup(grp net.IP) {\n\tsa := (*sockaddrInet6)(unsafe.Pointer(&gr.Group))\n\tsa.Family = syscall.AF_INET6\n\tsa.Len = sizeofSockaddrInet6\n\tcopy(sa.Addr[:], grp)\n}\n\nfunc (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {\n\tsa := (*sockaddrInet6)(unsafe.Pointer(&gsr.Group))\n\tsa.Family = syscall.AF_INET6\n\tsa.Len = sizeofSockaddrInet6\n\tcopy(sa.Addr[:], grp)\n\tsa = (*sockaddrInet6)(unsafe.Pointer(&gsr.Source))\n\tsa.Family = syscall.AF_INET6\n\tsa.Len = sizeofSockaddrInet6\n\tcopy(sa.Addr[:], src)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_aix_ppc64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_aix.go\n\n// Added for go1.11 compatibility\n//go:build aix\n\npackage ipv6\n\nconst (\n\tsizeofSockaddrStorage = 0x508\n\tsizeofSockaddrInet6   = 0x1c\n\tsizeofInet6Pktinfo    = 0x14\n\tsizeofIPv6Mtuinfo     = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x510\n\tsizeofGroupSourceReq = 0xa18\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype sockaddrStorage struct {\n\tX__ss_len   uint8\n\tFamily      uint8\n\tX__ss_pad1  [6]uint8\n\tX__ss_align int64\n\tX__ss_pad2  [1265]uint8\n\tPad_cgo_0   [7]byte\n}\n\ntype sockaddrInet6 struct {\n\tLen      uint8\n\tFamily   uint8\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex int32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tInterface uint32\n}\n\ntype icmpv6Filter struct {\n\tFilt [8]uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tGroup     sockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tGroup     sockaddrStorage\n\tSource    sockaddrStorage\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_darwin.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_darwin.go\n\npackage ipv6\n\nconst (\n\tsizeofSockaddrStorage = 0x80\n\tsizeofSockaddrInet6   = 0x1c\n\tsizeofInet6Pktinfo    = 0x14\n\tsizeofIPv6Mtuinfo     = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x84\n\tsizeofGroupSourceReq = 0x104\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype sockaddrStorage struct {\n\tLen         uint8\n\tFamily      uint8\n\tX__ss_pad1  [6]int8\n\tX__ss_align int64\n\tX__ss_pad2  [112]int8\n}\n\ntype sockaddrInet6 struct {\n\tLen      uint8\n\tFamily   uint8\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex uint32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tInterface uint32\n}\n\ntype icmpv6Filter struct {\n\tFilt [8]uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [128]byte\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [128]byte\n\tPad_cgo_1 [128]byte\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_dragonfly.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_dragonfly.go\n\npackage ipv6\n\nconst (\n\tsizeofSockaddrInet6 = 0x1c\n\tsizeofInet6Pktinfo  = 0x14\n\tsizeofIPv6Mtuinfo   = 0x20\n\n\tsizeofIPv6Mreq = 0x14\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype sockaddrInet6 struct {\n\tLen      uint8\n\tFamily   uint8\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex uint32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tInterface uint32\n}\n\ntype icmpv6Filter struct {\n\tFilt [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_freebsd_386.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_freebsd.go\n\npackage ipv6\n\nconst (\n\tsizeofSockaddrStorage = 0x80\n\tsizeofSockaddrInet6   = 0x1c\n\tsizeofInet6Pktinfo    = 0x14\n\tsizeofIPv6Mtuinfo     = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x84\n\tsizeofGroupSourceReq = 0x104\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype sockaddrStorage struct {\n\tLen         uint8\n\tFamily      uint8\n\tX__ss_pad1  [6]int8\n\tX__ss_align int64\n\tX__ss_pad2  [112]int8\n}\n\ntype sockaddrInet6 struct {\n\tLen      uint8\n\tFamily   uint8\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex uint32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tInterface uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tGroup     sockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tGroup     sockaddrStorage\n\tSource    sockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tFilt [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_freebsd_amd64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_freebsd.go\n\npackage ipv6\n\nconst (\n\tsizeofSockaddrStorage = 0x80\n\tsizeofSockaddrInet6   = 0x1c\n\tsizeofInet6Pktinfo    = 0x14\n\tsizeofIPv6Mtuinfo     = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype sockaddrStorage struct {\n\tLen         uint8\n\tFamily      uint8\n\tX__ss_pad1  [6]int8\n\tX__ss_align int64\n\tX__ss_pad2  [112]int8\n}\n\ntype sockaddrInet6 struct {\n\tLen      uint8\n\tFamily   uint8\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex uint32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tInterface uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     sockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     sockaddrStorage\n\tSource    sockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tFilt [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_freebsd_arm.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_freebsd.go\n\npackage ipv6\n\nconst (\n\tsizeofSockaddrStorage = 0x80\n\tsizeofSockaddrInet6   = 0x1c\n\tsizeofInet6Pktinfo    = 0x14\n\tsizeofIPv6Mtuinfo     = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype sockaddrStorage struct {\n\tLen         uint8\n\tFamily      uint8\n\tX__ss_pad1  [6]int8\n\tX__ss_align int64\n\tX__ss_pad2  [112]int8\n}\n\ntype sockaddrInet6 struct {\n\tLen      uint8\n\tFamily   uint8\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex uint32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tInterface uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     sockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     sockaddrStorage\n\tSource    sockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tFilt [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_freebsd_arm64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_freebsd.go\n\npackage ipv6\n\nconst (\n\tsizeofSockaddrStorage = 0x80\n\tsizeofSockaddrInet6   = 0x1c\n\tsizeofInet6Pktinfo    = 0x14\n\tsizeofIPv6Mtuinfo     = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype sockaddrStorage struct {\n\tLen         uint8\n\tFamily      uint8\n\tX__ss_pad1  [6]uint8\n\tX__ss_align int64\n\tX__ss_pad2  [112]uint8\n}\n\ntype sockaddrInet6 struct {\n\tLen      uint8\n\tFamily   uint8\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex uint32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tInterface uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tGroup     sockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tGroup     sockaddrStorage\n\tSource    sockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tFilt [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_freebsd_riscv64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_freebsd.go\n\npackage ipv6\n\nconst (\n\tsizeofSockaddrStorage = 0x80\n\tsizeofSockaddrInet6   = 0x1c\n\tsizeofInet6Pktinfo    = 0x14\n\tsizeofIPv6Mtuinfo     = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype sockaddrStorage struct {\n\tLen         uint8\n\tFamily      uint8\n\tX__ss_pad1  [6]uint8\n\tX__ss_align int64\n\tX__ss_pad2  [112]uint8\n}\n\ntype sockaddrInet6 struct {\n\tLen      uint8\n\tFamily   uint8\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex uint32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tInterface uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tGroup     sockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tGroup     sockaddrStorage\n\tSource    sockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tFilt [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_linux_386.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv6\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet6         = 0x1c\n\tsizeofInet6Pktinfo          = 0x14\n\tsizeofIPv6Mtuinfo           = 0x20\n\tsizeofIPv6FlowlabelReq      = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x84\n\tsizeofGroupSourceReq = 0x104\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet6 struct {\n\tFamily   uint16\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex int32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6FlowlabelReq struct {\n\tDst        [16]byte /* in6_addr */\n\tLabel      uint32\n\tAction     uint8\n\tShare      uint8\n\tFlags      uint16\n\tExpires    uint16\n\tLinger     uint16\n\tX__flr_pad uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tIfindex   int32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tData [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_linux_amd64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv6\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet6         = 0x1c\n\tsizeofInet6Pktinfo          = 0x14\n\tsizeofIPv6Mtuinfo           = 0x20\n\tsizeofIPv6FlowlabelReq      = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet6 struct {\n\tFamily   uint16\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex int32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6FlowlabelReq struct {\n\tDst        [16]byte /* in6_addr */\n\tLabel      uint32\n\tAction     uint8\n\tShare      uint8\n\tFlags      uint16\n\tExpires    uint16\n\tLinger     uint16\n\tX__flr_pad uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tIfindex   int32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tData [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_linux_arm.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv6\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet6         = 0x1c\n\tsizeofInet6Pktinfo          = 0x14\n\tsizeofIPv6Mtuinfo           = 0x20\n\tsizeofIPv6FlowlabelReq      = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x84\n\tsizeofGroupSourceReq = 0x104\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet6 struct {\n\tFamily   uint16\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex int32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6FlowlabelReq struct {\n\tDst        [16]byte /* in6_addr */\n\tLabel      uint32\n\tAction     uint8\n\tShare      uint8\n\tFlags      uint16\n\tExpires    uint16\n\tLinger     uint16\n\tX__flr_pad uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tIfindex   int32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tData [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_linux_arm64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv6\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet6         = 0x1c\n\tsizeofInet6Pktinfo          = 0x14\n\tsizeofIPv6Mtuinfo           = 0x20\n\tsizeofIPv6FlowlabelReq      = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet6 struct {\n\tFamily   uint16\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex int32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6FlowlabelReq struct {\n\tDst        [16]byte /* in6_addr */\n\tLabel      uint32\n\tAction     uint8\n\tShare      uint8\n\tFlags      uint16\n\tExpires    uint16\n\tLinger     uint16\n\tX__flr_pad uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tIfindex   int32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tData [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_linux_loong64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\n//go:build loong64\n\npackage ipv6\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet6         = 0x1c\n\tsizeofInet6Pktinfo          = 0x14\n\tsizeofIPv6Mtuinfo           = 0x20\n\tsizeofIPv6FlowlabelReq      = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet6 struct {\n\tFamily   uint16\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex int32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6FlowlabelReq struct {\n\tDst        [16]byte /* in6_addr */\n\tLabel      uint32\n\tAction     uint8\n\tShare      uint8\n\tFlags      uint16\n\tExpires    uint16\n\tLinger     uint16\n\tX__flr_pad uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tIfindex   int32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tData [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_linux_mips.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv6\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet6         = 0x1c\n\tsizeofInet6Pktinfo          = 0x14\n\tsizeofIPv6Mtuinfo           = 0x20\n\tsizeofIPv6FlowlabelReq      = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x84\n\tsizeofGroupSourceReq = 0x104\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet6 struct {\n\tFamily   uint16\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex int32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6FlowlabelReq struct {\n\tDst        [16]byte /* in6_addr */\n\tLabel      uint32\n\tAction     uint8\n\tShare      uint8\n\tFlags      uint16\n\tExpires    uint16\n\tLinger     uint16\n\tX__flr_pad uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tIfindex   int32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tData [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_linux_mips64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv6\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet6         = 0x1c\n\tsizeofInet6Pktinfo          = 0x14\n\tsizeofIPv6Mtuinfo           = 0x20\n\tsizeofIPv6FlowlabelReq      = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet6 struct {\n\tFamily   uint16\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex int32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6FlowlabelReq struct {\n\tDst        [16]byte /* in6_addr */\n\tLabel      uint32\n\tAction     uint8\n\tShare      uint8\n\tFlags      uint16\n\tExpires    uint16\n\tLinger     uint16\n\tX__flr_pad uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tIfindex   int32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tData [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_linux_mips64le.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv6\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet6         = 0x1c\n\tsizeofInet6Pktinfo          = 0x14\n\tsizeofIPv6Mtuinfo           = 0x20\n\tsizeofIPv6FlowlabelReq      = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet6 struct {\n\tFamily   uint16\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex int32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6FlowlabelReq struct {\n\tDst        [16]byte /* in6_addr */\n\tLabel      uint32\n\tAction     uint8\n\tShare      uint8\n\tFlags      uint16\n\tExpires    uint16\n\tLinger     uint16\n\tX__flr_pad uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tIfindex   int32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tData [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv6\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet6         = 0x1c\n\tsizeofInet6Pktinfo          = 0x14\n\tsizeofIPv6Mtuinfo           = 0x20\n\tsizeofIPv6FlowlabelReq      = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x84\n\tsizeofGroupSourceReq = 0x104\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet6 struct {\n\tFamily   uint16\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex int32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6FlowlabelReq struct {\n\tDst        [16]byte /* in6_addr */\n\tLabel      uint32\n\tAction     uint8\n\tShare      uint8\n\tFlags      uint16\n\tExpires    uint16\n\tLinger     uint16\n\tX__flr_pad uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tIfindex   int32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tData [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_linux_ppc.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv6\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet6         = 0x1c\n\tsizeofInet6Pktinfo          = 0x14\n\tsizeofIPv6Mtuinfo           = 0x20\n\tsizeofIPv6FlowlabelReq      = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x84\n\tsizeofGroupSourceReq = 0x104\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]uint8\n}\n\ntype sockaddrInet6 struct {\n\tFamily   uint16\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex int32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6FlowlabelReq struct {\n\tDst        [16]byte /* in6_addr */\n\tLabel      uint32\n\tAction     uint8\n\tShare      uint8\n\tFlags      uint16\n\tExpires    uint16\n\tLinger     uint16\n\tX__flr_pad uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tIfindex   int32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tData [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_linux_ppc64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv6\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet6         = 0x1c\n\tsizeofInet6Pktinfo          = 0x14\n\tsizeofIPv6Mtuinfo           = 0x20\n\tsizeofIPv6FlowlabelReq      = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet6 struct {\n\tFamily   uint16\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex int32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6FlowlabelReq struct {\n\tDst        [16]byte /* in6_addr */\n\tLabel      uint32\n\tAction     uint8\n\tShare      uint8\n\tFlags      uint16\n\tExpires    uint16\n\tLinger     uint16\n\tX__flr_pad uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tIfindex   int32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tData [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_linux_ppc64le.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv6\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet6         = 0x1c\n\tsizeofInet6Pktinfo          = 0x14\n\tsizeofIPv6Mtuinfo           = 0x20\n\tsizeofIPv6FlowlabelReq      = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet6 struct {\n\tFamily   uint16\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex int32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6FlowlabelReq struct {\n\tDst        [16]byte /* in6_addr */\n\tLabel      uint32\n\tAction     uint8\n\tShare      uint8\n\tFlags      uint16\n\tExpires    uint16\n\tLinger     uint16\n\tX__flr_pad uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tIfindex   int32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tData [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\n//go:build riscv64\n\npackage ipv6\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet6         = 0x1c\n\tsizeofInet6Pktinfo          = 0x14\n\tsizeofIPv6Mtuinfo           = 0x20\n\tsizeofIPv6FlowlabelReq      = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet6 struct {\n\tFamily   uint16\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex int32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6FlowlabelReq struct {\n\tDst        [16]byte /* in6_addr */\n\tLabel      uint32\n\tAction     uint8\n\tShare      uint8\n\tFlags      uint16\n\tExpires    uint16\n\tLinger     uint16\n\tX__flr_pad uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tIfindex   int32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tData [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_linux_s390x.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_linux.go\n\npackage ipv6\n\nconst (\n\tsizeofKernelSockaddrStorage = 0x80\n\tsizeofSockaddrInet6         = 0x1c\n\tsizeofInet6Pktinfo          = 0x14\n\tsizeofIPv6Mtuinfo           = 0x20\n\tsizeofIPv6FlowlabelReq      = 0x20\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x88\n\tsizeofGroupSourceReq = 0x108\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype kernelSockaddrStorage struct {\n\tFamily  uint16\n\tX__data [126]int8\n}\n\ntype sockaddrInet6 struct {\n\tFamily   uint16\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex int32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6FlowlabelReq struct {\n\tDst        [16]byte /* in6_addr */\n\tLabel      uint32\n\tAction     uint8\n\tShare      uint8\n\tFlags      uint16\n\tExpires    uint16\n\tLinger     uint16\n\tX__flr_pad uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tIfindex   int32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [4]byte\n\tGroup     kernelSockaddrStorage\n\tSource    kernelSockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tData [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_netbsd.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_netbsd.go\n\npackage ipv6\n\nconst (\n\tsizeofSockaddrInet6 = 0x1c\n\tsizeofInet6Pktinfo  = 0x14\n\tsizeofIPv6Mtuinfo   = 0x20\n\n\tsizeofIPv6Mreq = 0x14\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype sockaddrInet6 struct {\n\tLen      uint8\n\tFamily   uint8\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex uint32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tInterface uint32\n}\n\ntype icmpv6Filter struct {\n\tFilt [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_openbsd.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_openbsd.go\n\npackage ipv6\n\nconst (\n\tsizeofSockaddrInet6 = 0x1c\n\tsizeofInet6Pktinfo  = 0x14\n\tsizeofIPv6Mtuinfo   = 0x20\n\n\tsizeofIPv6Mreq = 0x14\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype sockaddrInet6 struct {\n\tLen      uint8\n\tFamily   uint8\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte /* in6_addr */\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex uint32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tInterface uint32\n}\n\ntype icmpv6Filter struct {\n\tFilt [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_solaris.go",
    "content": "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n// cgo -godefs defs_solaris.go\n\npackage ipv6\n\nconst (\n\tsizeofSockaddrStorage = 0x100\n\tsizeofSockaddrInet6   = 0x20\n\tsizeofInet6Pktinfo    = 0x14\n\tsizeofIPv6Mtuinfo     = 0x24\n\n\tsizeofIPv6Mreq       = 0x14\n\tsizeofGroupReq       = 0x104\n\tsizeofGroupSourceReq = 0x204\n\n\tsizeofICMPv6Filter = 0x20\n)\n\ntype sockaddrStorage struct {\n\tFamily     uint16\n\tX_ss_pad1  [6]int8\n\tX_ss_align float64\n\tX_ss_pad2  [240]int8\n}\n\ntype sockaddrInet6 struct {\n\tFamily         uint16\n\tPort           uint16\n\tFlowinfo       uint32\n\tAddr           [16]byte /* in6_addr */\n\tScope_id       uint32\n\tX__sin6_src_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte /* in6_addr */\n\tIfindex uint32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype ipv6Mreq struct {\n\tMultiaddr [16]byte /* in6_addr */\n\tInterface uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\tPad_cgo_0 [256]byte\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\tPad_cgo_0 [256]byte\n\tPad_cgo_1 [256]byte\n}\n\ntype icmpv6Filter struct {\n\tX__icmp6_filt [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/ipv6/zsys_zos_s390x.go",
    "content": "// Copyright 2020 The Go 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\n// Hand edited based on zerrors_zos_s390x.go\n// TODO(Bill O'Farrell): auto-generate.\n\npackage ipv6\n\nconst (\n\tsizeofSockaddrStorage = 128\n\tsizeofICMPv6Filter    = 32\n\tsizeofInet6Pktinfo    = 20\n\tsizeofIPv6Mtuinfo     = 32\n\tsizeofSockaddrInet6   = 28\n\tsizeofGroupReq        = 136\n\tsizeofGroupSourceReq  = 264\n)\n\ntype sockaddrStorage struct {\n\tLen      uint8\n\tFamily   byte\n\tss_pad1  [6]byte\n\tss_align int64\n\tss_pad2  [112]byte\n}\n\ntype sockaddrInet6 struct {\n\tLen      uint8\n\tFamily   uint8\n\tPort     uint16\n\tFlowinfo uint32\n\tAddr     [16]byte\n\tScope_id uint32\n}\n\ntype inet6Pktinfo struct {\n\tAddr    [16]byte\n\tIfindex uint32\n}\n\ntype ipv6Mtuinfo struct {\n\tAddr sockaddrInet6\n\tMtu  uint32\n}\n\ntype groupReq struct {\n\tInterface uint32\n\treserved  uint32\n\tGroup     sockaddrStorage\n}\n\ntype groupSourceReq struct {\n\tInterface uint32\n\treserved  uint32\n\tGroup     sockaddrStorage\n\tSource    sockaddrStorage\n}\n\ntype icmpv6Filter struct {\n\tFilt [8]uint32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/nettest/conntest.go",
    "content": "// Copyright 2016 The Go 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 nettest\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"math/rand\"\n\t\"net\"\n\t\"runtime\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n)\n\n// MakePipe creates a connection between two endpoints and returns the pair\n// as c1 and c2, such that anything written to c1 is read by c2 and vice-versa.\n// The stop function closes all resources, including c1, c2, and the underlying\n// net.Listener (if there is one), and should not be nil.\ntype MakePipe func() (c1, c2 net.Conn, stop func(), err error)\n\n// TestConn tests that a net.Conn implementation properly satisfies the interface.\n// The tests should not produce any false positives, but may experience\n// false negatives. Thus, some issues may only be detected when the test is\n// run multiple times. For maximal effectiveness, run the tests under the\n// race detector.\nfunc TestConn(t *testing.T, mp MakePipe) {\n\tt.Run(\"BasicIO\", func(t *testing.T) { timeoutWrapper(t, mp, testBasicIO) })\n\tt.Run(\"PingPong\", func(t *testing.T) { timeoutWrapper(t, mp, testPingPong) })\n\tt.Run(\"RacyRead\", func(t *testing.T) { timeoutWrapper(t, mp, testRacyRead) })\n\tt.Run(\"RacyWrite\", func(t *testing.T) { timeoutWrapper(t, mp, testRacyWrite) })\n\tt.Run(\"ReadTimeout\", func(t *testing.T) { timeoutWrapper(t, mp, testReadTimeout) })\n\tt.Run(\"WriteTimeout\", func(t *testing.T) { timeoutWrapper(t, mp, testWriteTimeout) })\n\tt.Run(\"PastTimeout\", func(t *testing.T) { timeoutWrapper(t, mp, testPastTimeout) })\n\tt.Run(\"PresentTimeout\", func(t *testing.T) { timeoutWrapper(t, mp, testPresentTimeout) })\n\tt.Run(\"FutureTimeout\", func(t *testing.T) { timeoutWrapper(t, mp, testFutureTimeout) })\n\tt.Run(\"CloseTimeout\", func(t *testing.T) { timeoutWrapper(t, mp, testCloseTimeout) })\n\tt.Run(\"ConcurrentMethods\", func(t *testing.T) { timeoutWrapper(t, mp, testConcurrentMethods) })\n}\n\ntype connTester func(t *testing.T, c1, c2 net.Conn)\n\nfunc timeoutWrapper(t *testing.T, mp MakePipe, f connTester) {\n\tt.Helper()\n\tc1, c2, stop, err := mp()\n\tif err != nil {\n\t\tt.Fatalf(\"unable to make pipe: %v\", err)\n\t}\n\tvar once sync.Once\n\tdefer once.Do(func() { stop() })\n\ttimer := time.AfterFunc(time.Minute, func() {\n\t\tonce.Do(func() {\n\t\t\tt.Error(\"test timed out; terminating pipe\")\n\t\t\tstop()\n\t\t})\n\t})\n\tdefer timer.Stop()\n\tf(t, c1, c2)\n}\n\n// testBasicIO tests that the data sent on c1 is properly received on c2.\nfunc testBasicIO(t *testing.T, c1, c2 net.Conn) {\n\twant := make([]byte, 1<<20)\n\trand.New(rand.NewSource(0)).Read(want)\n\n\tdataCh := make(chan []byte)\n\tgo func() {\n\t\trd := bytes.NewReader(want)\n\t\tif err := chunkedCopy(c1, rd); err != nil {\n\t\t\tt.Errorf(\"unexpected c1.Write error: %v\", err)\n\t\t}\n\t\tif err := c1.Close(); err != nil {\n\t\t\tt.Errorf(\"unexpected c1.Close error: %v\", err)\n\t\t}\n\t}()\n\n\tgo func() {\n\t\twr := new(bytes.Buffer)\n\t\tif err := chunkedCopy(wr, c2); err != nil {\n\t\t\tt.Errorf(\"unexpected c2.Read error: %v\", err)\n\t\t}\n\t\tif err := c2.Close(); err != nil {\n\t\t\tt.Errorf(\"unexpected c2.Close error: %v\", err)\n\t\t}\n\t\tdataCh <- wr.Bytes()\n\t}()\n\n\tif got := <-dataCh; !bytes.Equal(got, want) {\n\t\tt.Error(\"transmitted data differs\")\n\t}\n}\n\n// testPingPong tests that the two endpoints can synchronously send data to\n// each other in a typical request-response pattern.\nfunc testPingPong(t *testing.T, c1, c2 net.Conn) {\n\tvar wg sync.WaitGroup\n\tdefer wg.Wait()\n\n\tpingPonger := func(c net.Conn) {\n\t\tdefer wg.Done()\n\t\tbuf := make([]byte, 8)\n\t\tvar prev uint64\n\t\tfor {\n\t\t\tif _, err := io.ReadFull(c, buf); err != nil {\n\t\t\t\tif err == io.EOF {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tt.Errorf(\"unexpected Read error: %v\", err)\n\t\t\t}\n\n\t\t\tv := binary.LittleEndian.Uint64(buf)\n\t\t\tbinary.LittleEndian.PutUint64(buf, v+1)\n\t\t\tif prev != 0 && prev+2 != v {\n\t\t\t\tt.Errorf(\"mismatching value: got %d, want %d\", v, prev+2)\n\t\t\t}\n\t\t\tprev = v\n\t\t\tif v == 1000 {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif _, err := c.Write(buf); err != nil {\n\t\t\t\tt.Errorf(\"unexpected Write error: %v\", err)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif err := c.Close(); err != nil {\n\t\t\tt.Errorf(\"unexpected Close error: %v\", err)\n\t\t}\n\t}\n\n\twg.Add(2)\n\tgo pingPonger(c1)\n\tgo pingPonger(c2)\n\n\t// Start off the chain reaction.\n\tif _, err := c1.Write(make([]byte, 8)); err != nil {\n\t\tt.Errorf(\"unexpected c1.Write error: %v\", err)\n\t}\n}\n\n// testRacyRead tests that it is safe to mutate the input Read buffer\n// immediately after cancelation has occurred.\nfunc testRacyRead(t *testing.T, c1, c2 net.Conn) {\n\tgo chunkedCopy(c2, rand.New(rand.NewSource(0)))\n\n\tvar wg sync.WaitGroup\n\tdefer wg.Wait()\n\n\tc1.SetReadDeadline(time.Now().Add(time.Millisecond))\n\tfor i := 0; i < 10; i++ {\n\t\twg.Add(1)\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\n\t\t\tb1 := make([]byte, 1024)\n\t\t\tb2 := make([]byte, 1024)\n\t\t\tfor j := 0; j < 100; j++ {\n\t\t\t\t_, err := c1.Read(b1)\n\t\t\t\tcopy(b1, b2) // Mutate b1 to trigger potential race\n\t\t\t\tif err != nil {\n\t\t\t\t\tcheckForTimeoutError(t, err)\n\t\t\t\t\tc1.SetReadDeadline(time.Now().Add(time.Millisecond))\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\t}\n}\n\n// testRacyWrite tests that it is safe to mutate the input Write buffer\n// immediately after cancelation has occurred.\nfunc testRacyWrite(t *testing.T, c1, c2 net.Conn) {\n\tgo chunkedCopy(io.Discard, c2)\n\n\tvar wg sync.WaitGroup\n\tdefer wg.Wait()\n\n\tc1.SetWriteDeadline(time.Now().Add(time.Millisecond))\n\tfor i := 0; i < 10; i++ {\n\t\twg.Add(1)\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\n\t\t\tb1 := make([]byte, 1024)\n\t\t\tb2 := make([]byte, 1024)\n\t\t\tfor j := 0; j < 100; j++ {\n\t\t\t\t_, err := c1.Write(b1)\n\t\t\t\tcopy(b1, b2) // Mutate b1 to trigger potential race\n\t\t\t\tif err != nil {\n\t\t\t\t\tcheckForTimeoutError(t, err)\n\t\t\t\t\tc1.SetWriteDeadline(time.Now().Add(time.Millisecond))\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\t}\n}\n\n// testReadTimeout tests that Read timeouts do not affect Write.\nfunc testReadTimeout(t *testing.T, c1, c2 net.Conn) {\n\tgo chunkedCopy(io.Discard, c2)\n\n\tc1.SetReadDeadline(aLongTimeAgo)\n\t_, err := c1.Read(make([]byte, 1024))\n\tcheckForTimeoutError(t, err)\n\tif _, err := c1.Write(make([]byte, 1024)); err != nil {\n\t\tt.Errorf(\"unexpected Write error: %v\", err)\n\t}\n}\n\n// testWriteTimeout tests that Write timeouts do not affect Read.\nfunc testWriteTimeout(t *testing.T, c1, c2 net.Conn) {\n\tgo chunkedCopy(c2, rand.New(rand.NewSource(0)))\n\n\tc1.SetWriteDeadline(aLongTimeAgo)\n\t_, err := c1.Write(make([]byte, 1024))\n\tcheckForTimeoutError(t, err)\n\tif _, err := c1.Read(make([]byte, 1024)); err != nil {\n\t\tt.Errorf(\"unexpected Read error: %v\", err)\n\t}\n}\n\n// testPastTimeout tests that a deadline set in the past immediately times out\n// Read and Write requests.\nfunc testPastTimeout(t *testing.T, c1, c2 net.Conn) {\n\tgo chunkedCopy(c2, c2)\n\n\ttestRoundtrip(t, c1)\n\n\tc1.SetDeadline(aLongTimeAgo)\n\tn, err := c1.Write(make([]byte, 1024))\n\tif n != 0 {\n\t\tt.Errorf(\"unexpected Write count: got %d, want 0\", n)\n\t}\n\tcheckForTimeoutError(t, err)\n\tn, err = c1.Read(make([]byte, 1024))\n\tif n != 0 {\n\t\tt.Errorf(\"unexpected Read count: got %d, want 0\", n)\n\t}\n\tcheckForTimeoutError(t, err)\n\n\ttestRoundtrip(t, c1)\n}\n\n// testPresentTimeout tests that a past deadline set while there are pending\n// Read and Write operations immediately times out those operations.\nfunc testPresentTimeout(t *testing.T, c1, c2 net.Conn) {\n\tvar wg sync.WaitGroup\n\tdefer wg.Wait()\n\twg.Add(3)\n\n\tdeadlineSet := make(chan bool, 1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\ttime.Sleep(100 * time.Millisecond)\n\t\tdeadlineSet <- true\n\t\tc1.SetReadDeadline(aLongTimeAgo)\n\t\tc1.SetWriteDeadline(aLongTimeAgo)\n\t}()\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tn, err := c1.Read(make([]byte, 1024))\n\t\tif n != 0 {\n\t\t\tt.Errorf(\"unexpected Read count: got %d, want 0\", n)\n\t\t}\n\t\tcheckForTimeoutError(t, err)\n\t\tif len(deadlineSet) == 0 {\n\t\t\tt.Error(\"Read timed out before deadline is set\")\n\t\t}\n\t}()\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tvar err error\n\t\tfor err == nil {\n\t\t\t_, err = c1.Write(make([]byte, 1024))\n\t\t}\n\t\tcheckForTimeoutError(t, err)\n\t\tif len(deadlineSet) == 0 {\n\t\t\tt.Error(\"Write timed out before deadline is set\")\n\t\t}\n\t}()\n}\n\n// testFutureTimeout tests that a future deadline will eventually time out\n// Read and Write operations.\nfunc testFutureTimeout(t *testing.T, c1, c2 net.Conn) {\n\tvar wg sync.WaitGroup\n\twg.Add(2)\n\n\tc1.SetDeadline(time.Now().Add(100 * time.Millisecond))\n\tgo func() {\n\t\tdefer wg.Done()\n\t\t_, err := c1.Read(make([]byte, 1024))\n\t\tcheckForTimeoutError(t, err)\n\t}()\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tvar err error\n\t\tfor err == nil {\n\t\t\t_, err = c1.Write(make([]byte, 1024))\n\t\t}\n\t\tcheckForTimeoutError(t, err)\n\t}()\n\twg.Wait()\n\n\tgo chunkedCopy(c2, c2)\n\tresyncConn(t, c1)\n\ttestRoundtrip(t, c1)\n}\n\n// testCloseTimeout tests that calling Close immediately times out pending\n// Read and Write operations.\nfunc testCloseTimeout(t *testing.T, c1, c2 net.Conn) {\n\tgo chunkedCopy(c2, c2)\n\n\tvar wg sync.WaitGroup\n\tdefer wg.Wait()\n\twg.Add(3)\n\n\t// Test for cancelation upon connection closure.\n\tc1.SetDeadline(neverTimeout)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\ttime.Sleep(100 * time.Millisecond)\n\t\tc1.Close()\n\t}()\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tvar err error\n\t\tbuf := make([]byte, 1024)\n\t\tfor err == nil {\n\t\t\t_, err = c1.Read(buf)\n\t\t}\n\t}()\n\tgo func() {\n\t\tdefer wg.Done()\n\t\tvar err error\n\t\tbuf := make([]byte, 1024)\n\t\tfor err == nil {\n\t\t\t_, err = c1.Write(buf)\n\t\t}\n\t}()\n}\n\n// testConcurrentMethods tests that the methods of net.Conn can safely\n// be called concurrently.\nfunc testConcurrentMethods(t *testing.T, c1, c2 net.Conn) {\n\tif runtime.GOOS == \"plan9\" {\n\t\tt.Skip(\"skipping on plan9; see https://golang.org/issue/20489\")\n\t}\n\tgo chunkedCopy(c2, c2)\n\n\t// The results of the calls may be nonsensical, but this should\n\t// not trigger a race detector warning.\n\tvar wg sync.WaitGroup\n\tfor i := 0; i < 100; i++ {\n\t\twg.Add(7)\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\tc1.Read(make([]byte, 1024))\n\t\t}()\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\tc1.Write(make([]byte, 1024))\n\t\t}()\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\tc1.SetDeadline(time.Now().Add(10 * time.Millisecond))\n\t\t}()\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\tc1.SetReadDeadline(aLongTimeAgo)\n\t\t}()\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\tc1.SetWriteDeadline(aLongTimeAgo)\n\t\t}()\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\tc1.LocalAddr()\n\t\t}()\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\tc1.RemoteAddr()\n\t\t}()\n\t}\n\twg.Wait() // At worst, the deadline is set 10ms into the future\n\n\tresyncConn(t, c1)\n\ttestRoundtrip(t, c1)\n}\n\n// checkForTimeoutError checks that the error satisfies the Error interface\n// and that Timeout returns true.\nfunc checkForTimeoutError(t *testing.T, err error) {\n\tt.Helper()\n\tif nerr, ok := err.(net.Error); ok {\n\t\tif !nerr.Timeout() {\n\t\t\tif runtime.GOOS == \"windows\" && runtime.GOARCH == \"arm64\" && t.Name() == \"TestTestConn/TCP/RacyRead\" {\n\t\t\t\tt.Logf(\"ignoring known failure mode on windows/arm64; see https://go.dev/issue/52893\")\n\t\t\t} else {\n\t\t\t\tt.Errorf(\"got error: %v, want err.Timeout() = true\", nerr)\n\t\t\t}\n\t\t}\n\t} else {\n\t\tt.Errorf(\"got %T: %v, want net.Error\", err, err)\n\t}\n}\n\n// testRoundtrip writes something into c and reads it back.\n// It assumes that everything written into c is echoed back to itself.\nfunc testRoundtrip(t *testing.T, c net.Conn) {\n\tt.Helper()\n\tif err := c.SetDeadline(neverTimeout); err != nil {\n\t\tt.Errorf(\"roundtrip SetDeadline error: %v\", err)\n\t}\n\n\tconst s = \"Hello, world!\"\n\tbuf := []byte(s)\n\tif _, err := c.Write(buf); err != nil {\n\t\tt.Errorf(\"roundtrip Write error: %v\", err)\n\t}\n\tif _, err := io.ReadFull(c, buf); err != nil {\n\t\tt.Errorf(\"roundtrip Read error: %v\", err)\n\t}\n\tif string(buf) != s {\n\t\tt.Errorf(\"roundtrip data mismatch: got %q, want %q\", buf, s)\n\t}\n}\n\n// resyncConn resynchronizes the connection into a sane state.\n// It assumes that everything written into c is echoed back to itself.\n// It assumes that 0xff is not currently on the wire or in the read buffer.\nfunc resyncConn(t *testing.T, c net.Conn) {\n\tt.Helper()\n\tc.SetDeadline(neverTimeout)\n\terrCh := make(chan error)\n\tgo func() {\n\t\t_, err := c.Write([]byte{0xff})\n\t\terrCh <- err\n\t}()\n\tbuf := make([]byte, 1024)\n\tfor {\n\t\tn, err := c.Read(buf)\n\t\tif n > 0 && bytes.IndexByte(buf[:n], 0xff) == n-1 {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"unexpected Read error: %v\", err)\n\t\t\tbreak\n\t\t}\n\t}\n\tif err := <-errCh; err != nil {\n\t\tt.Errorf(\"unexpected Write error: %v\", err)\n\t}\n}\n\n// chunkedCopy copies from r to w in fixed-width chunks to avoid\n// causing a Write that exceeds the maximum packet size for packet-based\n// connections like \"unixpacket\".\n// We assume that the maximum packet size is at least 1024.\nfunc chunkedCopy(w io.Writer, r io.Reader) error {\n\tb := make([]byte, 1024)\n\t_, err := io.CopyBuffer(struct{ io.Writer }{w}, struct{ io.Reader }{r}, b)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/nettest/nettest.go",
    "content": "// Copyright 2019 The Go 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\n// Package nettest provides utilities for network testing.\npackage nettest\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"os/exec\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\nvar (\n\tstackOnce               sync.Once\n\tipv4Enabled             bool\n\tcanListenTCP4OnLoopback bool\n\tipv6Enabled             bool\n\tcanListenTCP6OnLoopback bool\n\tunStrmDgramEnabled      bool\n\trawSocketSess           bool\n\n\taLongTimeAgo = time.Unix(233431200, 0)\n\tneverTimeout = time.Time{}\n\n\terrNoAvailableInterface = errors.New(\"no available interface\")\n\terrNoAvailableAddress   = errors.New(\"no available address\")\n)\n\nfunc probeStack() {\n\tif _, err := RoutedInterface(\"ip4\", net.FlagUp); err == nil {\n\t\tipv4Enabled = true\n\t}\n\tif ln, err := net.Listen(\"tcp4\", \"127.0.0.1:0\"); err == nil {\n\t\tln.Close()\n\t\tcanListenTCP4OnLoopback = true\n\t}\n\tif _, err := RoutedInterface(\"ip6\", net.FlagUp); err == nil {\n\t\tipv6Enabled = true\n\t}\n\tif ln, err := net.Listen(\"tcp6\", \"[::1]:0\"); err == nil {\n\t\tln.Close()\n\t\tcanListenTCP6OnLoopback = true\n\t}\n\trawSocketSess = supportsRawSocket()\n\tswitch runtime.GOOS {\n\tcase \"aix\":\n\t\t// Unix network isn't properly working on AIX 7.2 with\n\t\t// Technical Level < 2.\n\t\tout, _ := exec.Command(\"oslevel\", \"-s\").Output()\n\t\tif len(out) >= len(\"7200-XX-ZZ-YYMM\") { // AIX 7.2, Tech Level XX, Service Pack ZZ, date YYMM\n\t\t\tver := string(out[:4])\n\t\t\ttl, _ := strconv.Atoi(string(out[5:7]))\n\t\t\tunStrmDgramEnabled = ver > \"7200\" || (ver == \"7200\" && tl >= 2)\n\t\t}\n\tdefault:\n\t\tunStrmDgramEnabled = true\n\t}\n}\n\nfunc unixStrmDgramEnabled() bool {\n\tstackOnce.Do(probeStack)\n\treturn unStrmDgramEnabled\n}\n\n// SupportsIPv4 reports whether the platform supports IPv4 networking\n// functionality.\nfunc SupportsIPv4() bool {\n\tstackOnce.Do(probeStack)\n\treturn ipv4Enabled\n}\n\n// SupportsIPv6 reports whether the platform supports IPv6 networking\n// functionality.\nfunc SupportsIPv6() bool {\n\tstackOnce.Do(probeStack)\n\treturn ipv6Enabled\n}\n\n// SupportsRawSocket reports whether the current session is available\n// to use raw sockets.\nfunc SupportsRawSocket() bool {\n\tstackOnce.Do(probeStack)\n\treturn rawSocketSess\n}\n\n// TestableNetwork reports whether network is testable on the current\n// platform configuration.\n//\n// See func Dial of the standard library for the supported networks.\nfunc TestableNetwork(network string) bool {\n\tss := strings.Split(network, \":\")\n\tswitch ss[0] {\n\tcase \"ip+nopriv\":\n\t\t// This is an internal network name for testing on the\n\t\t// package net of the standard library.\n\t\tswitch runtime.GOOS {\n\t\tcase \"android\", \"fuchsia\", \"hurd\", \"ios\", \"js\", \"nacl\", \"plan9\", \"wasip1\", \"windows\":\n\t\t\treturn false\n\t\t}\n\tcase \"ip\", \"ip4\", \"ip6\":\n\t\tswitch runtime.GOOS {\n\t\tcase \"fuchsia\", \"hurd\", \"js\", \"nacl\", \"plan9\", \"wasip1\":\n\t\t\treturn false\n\t\tdefault:\n\t\t\tif os.Getuid() != 0 {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\tcase \"unix\", \"unixgram\":\n\t\tswitch runtime.GOOS {\n\t\tcase \"android\", \"fuchsia\", \"hurd\", \"ios\", \"js\", \"nacl\", \"plan9\", \"wasip1\", \"windows\":\n\t\t\treturn false\n\t\tcase \"aix\":\n\t\t\treturn unixStrmDgramEnabled()\n\t\t}\n\tcase \"unixpacket\":\n\t\tswitch runtime.GOOS {\n\t\tcase \"aix\", \"android\", \"fuchsia\", \"hurd\", \"darwin\", \"ios\", \"js\", \"nacl\", \"plan9\", \"wasip1\", \"windows\", \"zos\":\n\t\t\treturn false\n\t\t}\n\t}\n\tswitch ss[0] {\n\tcase \"tcp4\", \"udp4\", \"ip4\":\n\t\treturn SupportsIPv4()\n\tcase \"tcp6\", \"udp6\", \"ip6\":\n\t\treturn SupportsIPv6()\n\t}\n\treturn true\n}\n\n// TestableAddress reports whether address of network is testable on\n// the current platform configuration.\nfunc TestableAddress(network, address string) bool {\n\tswitch ss := strings.Split(network, \":\"); ss[0] {\n\tcase \"unix\", \"unixgram\", \"unixpacket\":\n\t\t// Abstract unix domain sockets, a Linux-ism.\n\t\tif address[0] == '@' && runtime.GOOS != \"linux\" {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// NewLocalListener returns a listener which listens to a loopback IP\n// address or local file system path.\n//\n// The provided network must be \"tcp\", \"tcp4\", \"tcp6\", \"unix\" or\n// \"unixpacket\".\nfunc NewLocalListener(network string) (net.Listener, error) {\n\tstackOnce.Do(probeStack)\n\tswitch network {\n\tcase \"tcp\":\n\t\tif canListenTCP4OnLoopback {\n\t\t\tif ln, err := net.Listen(\"tcp4\", \"127.0.0.1:0\"); err == nil {\n\t\t\t\treturn ln, nil\n\t\t\t}\n\t\t}\n\t\tif canListenTCP6OnLoopback {\n\t\t\treturn net.Listen(\"tcp6\", \"[::1]:0\")\n\t\t}\n\tcase \"tcp4\":\n\t\tif canListenTCP4OnLoopback {\n\t\t\treturn net.Listen(\"tcp4\", \"127.0.0.1:0\")\n\t\t}\n\tcase \"tcp6\":\n\t\tif canListenTCP6OnLoopback {\n\t\t\treturn net.Listen(\"tcp6\", \"[::1]:0\")\n\t\t}\n\tcase \"unix\", \"unixpacket\":\n\t\tpath, err := LocalPath()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn net.Listen(network, path)\n\t}\n\treturn nil, fmt.Errorf(\"%s is not supported on %s/%s\", network, runtime.GOOS, runtime.GOARCH)\n}\n\n// NewLocalPacketListener returns a packet listener which listens to a\n// loopback IP address or local file system path.\n//\n// The provided network must be \"udp\", \"udp4\", \"udp6\" or \"unixgram\".\nfunc NewLocalPacketListener(network string) (net.PacketConn, error) {\n\tstackOnce.Do(probeStack)\n\tswitch network {\n\tcase \"udp\":\n\t\tif canListenTCP4OnLoopback {\n\t\t\tif c, err := net.ListenPacket(\"udp4\", \"127.0.0.1:0\"); err == nil {\n\t\t\t\treturn c, nil\n\t\t\t}\n\t\t}\n\t\tif canListenTCP6OnLoopback {\n\t\t\treturn net.ListenPacket(\"udp6\", \"[::1]:0\")\n\t\t}\n\tcase \"udp4\":\n\t\tif canListenTCP4OnLoopback {\n\t\t\treturn net.ListenPacket(\"udp4\", \"127.0.0.1:0\")\n\t\t}\n\tcase \"udp6\":\n\t\tif canListenTCP6OnLoopback {\n\t\t\treturn net.ListenPacket(\"udp6\", \"[::1]:0\")\n\t\t}\n\tcase \"unixgram\":\n\t\tpath, err := LocalPath()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn net.ListenPacket(network, path)\n\t}\n\treturn nil, fmt.Errorf(\"%s is not supported on %s/%s\", network, runtime.GOOS, runtime.GOARCH)\n}\n\n// LocalPath returns a local path that can be used for Unix-domain\n// protocol testing.\nfunc LocalPath() (string, error) {\n\tdir := \"\"\n\tif runtime.GOOS == \"darwin\" {\n\t\tdir = \"/tmp\"\n\t}\n\tf, err := os.CreateTemp(dir, \"go-nettest\")\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tpath := f.Name()\n\tf.Close()\n\tos.Remove(path)\n\treturn path, nil\n}\n\n// MulticastSource returns a unicast IP address on ifi when ifi is an\n// IP multicast-capable network interface.\n//\n// The provided network must be \"ip\", \"ip4\" or \"ip6\".\nfunc MulticastSource(network string, ifi *net.Interface) (net.IP, error) {\n\tswitch network {\n\tcase \"ip\", \"ip4\", \"ip6\":\n\tdefault:\n\t\treturn nil, errNoAvailableAddress\n\t}\n\tif ifi == nil || ifi.Flags&net.FlagUp == 0 || ifi.Flags&net.FlagMulticast == 0 {\n\t\treturn nil, errNoAvailableAddress\n\t}\n\tip, ok := hasRoutableIP(network, ifi)\n\tif !ok {\n\t\treturn nil, errNoAvailableAddress\n\t}\n\treturn ip, nil\n}\n\n// LoopbackInterface returns an available logical network interface\n// for loopback test.\nfunc LoopbackInterface() (*net.Interface, error) {\n\tift, err := net.Interfaces()\n\tif err != nil {\n\t\treturn nil, errNoAvailableInterface\n\t}\n\tfor _, ifi := range ift {\n\t\tif ifi.Flags&net.FlagLoopback != 0 && ifi.Flags&net.FlagUp != 0 {\n\t\t\treturn &ifi, nil\n\t\t}\n\t}\n\treturn nil, errNoAvailableInterface\n}\n\n// RoutedInterface returns a network interface that can route IP\n// traffic and satisfies flags.\n//\n// The provided network must be \"ip\", \"ip4\" or \"ip6\".\nfunc RoutedInterface(network string, flags net.Flags) (*net.Interface, error) {\n\tswitch network {\n\tcase \"ip\", \"ip4\", \"ip6\":\n\tdefault:\n\t\treturn nil, errNoAvailableInterface\n\t}\n\tift, err := net.Interfaces()\n\tif err != nil {\n\t\treturn nil, errNoAvailableInterface\n\t}\n\tfor _, ifi := range ift {\n\t\tif ifi.Flags&flags != flags {\n\t\t\tcontinue\n\t\t}\n\t\tif _, ok := hasRoutableIP(network, &ifi); !ok {\n\t\t\tcontinue\n\t\t}\n\t\treturn &ifi, nil\n\t}\n\treturn nil, errNoAvailableInterface\n}\n\nfunc hasRoutableIP(network string, ifi *net.Interface) (net.IP, bool) {\n\tifat, err := ifi.Addrs()\n\tif err != nil {\n\t\treturn nil, false\n\t}\n\tfor _, ifa := range ifat {\n\t\tswitch ifa := ifa.(type) {\n\t\tcase *net.IPAddr:\n\t\t\tif ip, ok := routableIP(network, ifa.IP); ok {\n\t\t\t\treturn ip, true\n\t\t\t}\n\t\tcase *net.IPNet:\n\t\t\tif ip, ok := routableIP(network, ifa.IP); ok {\n\t\t\t\treturn ip, true\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, false\n}\n\nfunc routableIP(network string, ip net.IP) (net.IP, bool) {\n\tif !ip.IsLoopback() && !ip.IsLinkLocalUnicast() && !ip.IsGlobalUnicast() {\n\t\treturn nil, false\n\t}\n\tswitch network {\n\tcase \"ip4\":\n\t\tif ip := ip.To4(); ip != nil {\n\t\t\treturn ip, true\n\t\t}\n\tcase \"ip6\":\n\t\tif ip.IsLoopback() { // addressing scope of the loopback address depends on each implementation\n\t\t\treturn nil, false\n\t\t}\n\t\tif ip := ip.To16(); ip != nil && ip.To4() == nil {\n\t\t\treturn ip, true\n\t\t}\n\tdefault:\n\t\tif ip := ip.To4(); ip != nil {\n\t\t\treturn ip, true\n\t\t}\n\t\tif ip := ip.To16(); ip != nil {\n\t\t\treturn ip, true\n\t\t}\n\t}\n\treturn nil, false\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/nettest/nettest_stub.go",
    "content": "// Copyright 2019 The Go 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\n//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos\n\npackage nettest\n\nfunc supportsRawSocket() bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/nettest/nettest_unix.go",
    "content": "// Copyright 2019 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\npackage nettest\n\nimport \"syscall\"\n\nfunc supportsRawSocket() bool {\n\tfor _, af := range []int{syscall.AF_INET, syscall.AF_INET6} {\n\t\ts, err := syscall.Socket(af, syscall.SOCK_RAW, 0)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tsyscall.Close(s)\n\t\treturn true\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/nettest/nettest_windows.go",
    "content": "// Copyright 2019 The Go 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 nettest\n\nimport \"syscall\"\n\nfunc supportsRawSocket() bool {\n\t// From http://msdn.microsoft.com/en-us/library/windows/desktop/ms740548.aspx:\n\t// Note: To use a socket of type SOCK_RAW requires administrative privileges.\n\t// Users running Winsock applications that use raw sockets must be a member of\n\t// the Administrators group on the local computer, otherwise raw socket calls\n\t// will fail with an error code of WSAEACCES. On Windows Vista and later, access\n\t// for raw sockets is enforced at socket creation. In earlier versions of Windows,\n\t// access for raw sockets is enforced during other socket operations.\n\tfor _, af := range []int{syscall.AF_INET, syscall.AF_INET6} {\n\t\ts, err := syscall.Socket(af, syscall.SOCK_RAW, 0)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tsyscall.Closesocket(s)\n\t\treturn true\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/proxy/dial.go",
    "content": "// Copyright 2019 The Go 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 proxy\n\nimport (\n\t\"context\"\n\t\"net\"\n)\n\n// A ContextDialer dials using a context.\ntype ContextDialer interface {\n\tDialContext(ctx context.Context, network, address string) (net.Conn, error)\n}\n\n// Dial works like DialContext on net.Dialer but using a dialer returned by FromEnvironment.\n//\n// The passed ctx is only used for returning the Conn, not the lifetime of the Conn.\n//\n// Custom dialers (registered via RegisterDialerType) that do not implement ContextDialer\n// can leak a goroutine for as long as it takes the underlying Dialer implementation to timeout.\n//\n// A Conn returned from a successful Dial after the context has been cancelled will be immediately closed.\nfunc Dial(ctx context.Context, network, address string) (net.Conn, error) {\n\td := FromEnvironment()\n\tif xd, ok := d.(ContextDialer); ok {\n\t\treturn xd.DialContext(ctx, network, address)\n\t}\n\treturn dialContext(ctx, d, network, address)\n}\n\n// WARNING: this can leak a goroutine for as long as the underlying Dialer implementation takes to timeout\n// A Conn returned from a successful Dial after the context has been cancelled will be immediately closed.\nfunc dialContext(ctx context.Context, d Dialer, network, address string) (net.Conn, error) {\n\tvar (\n\t\tconn net.Conn\n\t\tdone = make(chan struct{}, 1)\n\t\terr  error\n\t)\n\tgo func() {\n\t\tconn, err = d.Dial(network, address)\n\t\tclose(done)\n\t\tif conn != nil && ctx.Err() != nil {\n\t\t\tconn.Close()\n\t\t}\n\t}()\n\tselect {\n\tcase <-ctx.Done():\n\t\terr = ctx.Err()\n\tcase <-done:\n\t}\n\treturn conn, err\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/proxy/direct.go",
    "content": "// Copyright 2011 The Go 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 proxy\n\nimport (\n\t\"context\"\n\t\"net\"\n)\n\ntype direct struct{}\n\n// Direct implements Dialer by making network connections directly using net.Dial or net.DialContext.\nvar Direct = direct{}\n\nvar (\n\t_ Dialer        = Direct\n\t_ ContextDialer = Direct\n)\n\n// Dial directly invokes net.Dial with the supplied parameters.\nfunc (direct) Dial(network, addr string) (net.Conn, error) {\n\treturn net.Dial(network, addr)\n}\n\n// DialContext instantiates a net.Dialer and invokes its DialContext receiver with the supplied parameters.\nfunc (direct) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {\n\tvar d net.Dialer\n\treturn d.DialContext(ctx, network, addr)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/proxy/per_host.go",
    "content": "// Copyright 2011 The Go 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 proxy\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/netip\"\n\t\"strings\"\n)\n\n// A PerHost directs connections to a default Dialer unless the host name\n// requested matches one of a number of exceptions.\ntype PerHost struct {\n\tdef, bypass Dialer\n\n\tbypassNetworks []*net.IPNet\n\tbypassIPs      []net.IP\n\tbypassZones    []string\n\tbypassHosts    []string\n}\n\n// NewPerHost returns a PerHost Dialer that directs connections to either\n// defaultDialer or bypass, depending on whether the connection matches one of\n// the configured rules.\nfunc NewPerHost(defaultDialer, bypass Dialer) *PerHost {\n\treturn &PerHost{\n\t\tdef:    defaultDialer,\n\t\tbypass: bypass,\n\t}\n}\n\n// Dial connects to the address addr on the given network through either\n// defaultDialer or bypass.\nfunc (p *PerHost) Dial(network, addr string) (c net.Conn, err error) {\n\thost, _, err := net.SplitHostPort(addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn p.dialerForRequest(host).Dial(network, addr)\n}\n\n// DialContext connects to the address addr on the given network through either\n// defaultDialer or bypass.\nfunc (p *PerHost) DialContext(ctx context.Context, network, addr string) (c net.Conn, err error) {\n\thost, _, err := net.SplitHostPort(addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\td := p.dialerForRequest(host)\n\tif x, ok := d.(ContextDialer); ok {\n\t\treturn x.DialContext(ctx, network, addr)\n\t}\n\treturn dialContext(ctx, d, network, addr)\n}\n\nfunc (p *PerHost) dialerForRequest(host string) Dialer {\n\tif nip, err := netip.ParseAddr(host); err == nil {\n\t\tip := net.IP(nip.AsSlice())\n\t\tfor _, net := range p.bypassNetworks {\n\t\t\tif net.Contains(ip) {\n\t\t\t\treturn p.bypass\n\t\t\t}\n\t\t}\n\t\tfor _, bypassIP := range p.bypassIPs {\n\t\t\tif bypassIP.Equal(ip) {\n\t\t\t\treturn p.bypass\n\t\t\t}\n\t\t}\n\t\treturn p.def\n\t}\n\n\tfor _, zone := range p.bypassZones {\n\t\tif strings.HasSuffix(host, zone) {\n\t\t\treturn p.bypass\n\t\t}\n\t\tif host == zone[1:] {\n\t\t\t// For a zone \".example.com\", we match \"example.com\"\n\t\t\t// too.\n\t\t\treturn p.bypass\n\t\t}\n\t}\n\tfor _, bypassHost := range p.bypassHosts {\n\t\tif bypassHost == host {\n\t\t\treturn p.bypass\n\t\t}\n\t}\n\treturn p.def\n}\n\n// AddFromString parses a string that contains comma-separated values\n// specifying hosts that should use the bypass proxy. Each value is either an\n// IP address, a CIDR range, a zone (*.example.com) or a host name\n// (localhost). A best effort is made to parse the string and errors are\n// ignored.\nfunc (p *PerHost) AddFromString(s string) {\n\thosts := strings.Split(s, \",\")\n\tfor _, host := range hosts {\n\t\thost = strings.TrimSpace(host)\n\t\tif len(host) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tif strings.Contains(host, \"/\") {\n\t\t\t// We assume that it's a CIDR address like 127.0.0.0/8\n\t\t\tif _, net, err := net.ParseCIDR(host); err == nil {\n\t\t\t\tp.AddNetwork(net)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif nip, err := netip.ParseAddr(host); err == nil {\n\t\t\tp.AddIP(net.IP(nip.AsSlice()))\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(host, \"*.\") {\n\t\t\tp.AddZone(host[1:])\n\t\t\tcontinue\n\t\t}\n\t\tp.AddHost(host)\n\t}\n}\n\n// AddIP specifies an IP address that will use the bypass proxy. Note that\n// this will only take effect if a literal IP address is dialed. A connection\n// to a named host will never match an IP.\nfunc (p *PerHost) AddIP(ip net.IP) {\n\tp.bypassIPs = append(p.bypassIPs, ip)\n}\n\n// AddNetwork specifies an IP range that will use the bypass proxy. Note that\n// this will only take effect if a literal IP address is dialed. A connection\n// to a named host will never match.\nfunc (p *PerHost) AddNetwork(net *net.IPNet) {\n\tp.bypassNetworks = append(p.bypassNetworks, net)\n}\n\n// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of\n// \"example.com\" matches \"example.com\" and all of its subdomains.\nfunc (p *PerHost) AddZone(zone string) {\n\tzone = strings.TrimSuffix(zone, \".\")\n\tif !strings.HasPrefix(zone, \".\") {\n\t\tzone = \".\" + zone\n\t}\n\tp.bypassZones = append(p.bypassZones, zone)\n}\n\n// AddHost specifies a host name that will use the bypass proxy.\nfunc (p *PerHost) AddHost(host string) {\n\thost = strings.TrimSuffix(host, \".\")\n\tp.bypassHosts = append(p.bypassHosts, host)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/proxy/proxy.go",
    "content": "// Copyright 2011 The Go 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\n// Package proxy provides support for a variety of protocols to proxy network\n// data.\npackage proxy // import \"golang.org/x/net/proxy\"\n\nimport (\n\t\"errors\"\n\t\"net\"\n\t\"net/url\"\n\t\"os\"\n\t\"sync\"\n)\n\n// A Dialer is a means to establish a connection.\n// Custom dialers should also implement ContextDialer.\ntype Dialer interface {\n\t// Dial connects to the given address via the proxy.\n\tDial(network, addr string) (c net.Conn, err error)\n}\n\n// Auth contains authentication parameters that specific Dialers may require.\ntype Auth struct {\n\tUser, Password string\n}\n\n// FromEnvironment returns the dialer specified by the proxy-related\n// variables in the environment and makes underlying connections\n// directly.\nfunc FromEnvironment() Dialer {\n\treturn FromEnvironmentUsing(Direct)\n}\n\n// FromEnvironmentUsing returns the dialer specify by the proxy-related\n// variables in the environment and makes underlying connections\n// using the provided forwarding Dialer (for instance, a *net.Dialer\n// with desired configuration).\nfunc FromEnvironmentUsing(forward Dialer) Dialer {\n\tallProxy := allProxyEnv.Get()\n\tif len(allProxy) == 0 {\n\t\treturn forward\n\t}\n\n\tproxyURL, err := url.Parse(allProxy)\n\tif err != nil {\n\t\treturn forward\n\t}\n\tproxy, err := FromURL(proxyURL, forward)\n\tif err != nil {\n\t\treturn forward\n\t}\n\n\tnoProxy := noProxyEnv.Get()\n\tif len(noProxy) == 0 {\n\t\treturn proxy\n\t}\n\n\tperHost := NewPerHost(proxy, forward)\n\tperHost.AddFromString(noProxy)\n\treturn perHost\n}\n\n// proxySchemes is a map from URL schemes to a function that creates a Dialer\n// from a URL with such a scheme.\nvar proxySchemes map[string]func(*url.URL, Dialer) (Dialer, error)\n\n// RegisterDialerType takes a URL scheme and a function to generate Dialers from\n// a URL with that scheme and a forwarding Dialer. Registered schemes are used\n// by FromURL.\nfunc RegisterDialerType(scheme string, f func(*url.URL, Dialer) (Dialer, error)) {\n\tif proxySchemes == nil {\n\t\tproxySchemes = make(map[string]func(*url.URL, Dialer) (Dialer, error))\n\t}\n\tproxySchemes[scheme] = f\n}\n\n// FromURL returns a Dialer given a URL specification and an underlying\n// Dialer for it to make network requests.\nfunc FromURL(u *url.URL, forward Dialer) (Dialer, error) {\n\tvar auth *Auth\n\tif u.User != nil {\n\t\tauth = new(Auth)\n\t\tauth.User = u.User.Username()\n\t\tif p, ok := u.User.Password(); ok {\n\t\t\tauth.Password = p\n\t\t}\n\t}\n\n\tswitch u.Scheme {\n\tcase \"socks5\", \"socks5h\":\n\t\taddr := u.Hostname()\n\t\tport := u.Port()\n\t\tif port == \"\" {\n\t\t\tport = \"1080\"\n\t\t}\n\t\treturn SOCKS5(\"tcp\", net.JoinHostPort(addr, port), auth, forward)\n\t}\n\n\t// If the scheme doesn't match any of the built-in schemes, see if it\n\t// was registered by another package.\n\tif proxySchemes != nil {\n\t\tif f, ok := proxySchemes[u.Scheme]; ok {\n\t\t\treturn f(u, forward)\n\t\t}\n\t}\n\n\treturn nil, errors.New(\"proxy: unknown scheme: \" + u.Scheme)\n}\n\nvar (\n\tallProxyEnv = &envOnce{\n\t\tnames: []string{\"ALL_PROXY\", \"all_proxy\"},\n\t}\n\tnoProxyEnv = &envOnce{\n\t\tnames: []string{\"NO_PROXY\", \"no_proxy\"},\n\t}\n)\n\n// envOnce looks up an environment variable (optionally by multiple\n// names) once. It mitigates expensive lookups on some platforms\n// (e.g. Windows).\n// (Borrowed from net/http/transport.go)\ntype envOnce struct {\n\tnames []string\n\tonce  sync.Once\n\tval   string\n}\n\nfunc (e *envOnce) Get() string {\n\te.once.Do(e.init)\n\treturn e.val\n}\n\nfunc (e *envOnce) init() {\n\tfor _, n := range e.names {\n\t\te.val = os.Getenv(n)\n\t\tif e.val != \"\" {\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// reset is used by tests\nfunc (e *envOnce) reset() {\n\te.once = sync.Once{}\n\te.val = \"\"\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/proxy/socks5.go",
    "content": "// Copyright 2011 The Go 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 proxy\n\nimport (\n\t\"context\"\n\t\"net\"\n\n\t\"golang.org/x/net/internal/socks\"\n)\n\n// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given\n// address with an optional username and password.\n// See RFC 1928 and RFC 1929.\nfunc SOCKS5(network, address string, auth *Auth, forward Dialer) (Dialer, error) {\n\td := socks.NewDialer(network, address)\n\tif forward != nil {\n\t\tif f, ok := forward.(ContextDialer); ok {\n\t\t\td.ProxyDial = func(ctx context.Context, network string, address string) (net.Conn, error) {\n\t\t\t\treturn f.DialContext(ctx, network, address)\n\t\t\t}\n\t\t} else {\n\t\t\td.ProxyDial = func(ctx context.Context, network string, address string) (net.Conn, error) {\n\t\t\t\treturn dialContext(ctx, forward, network, address)\n\t\t\t}\n\t\t}\n\t}\n\tif auth != nil {\n\t\tup := socks.UsernamePassword{\n\t\t\tUsername: auth.User,\n\t\t\tPassword: auth.Password,\n\t\t}\n\t\td.AuthMethods = []socks.AuthMethod{\n\t\t\tsocks.AuthMethodNotRequired,\n\t\t\tsocks.AuthMethodUsernamePassword,\n\t\t}\n\t\td.Authenticate = up.Authenticate\n\t}\n\treturn d, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/trace/events.go",
    "content": "// Copyright 2015 The Go 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 trace\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"html/template\"\n\t\"io\"\n\t\"log\"\n\t\"net/http\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"text/tabwriter\"\n\t\"time\"\n)\n\nconst maxEventsPerLog = 100\n\ntype bucket struct {\n\tMaxErrAge time.Duration\n\tString    string\n}\n\nvar buckets = []bucket{\n\t{0, \"total\"},\n\t{10 * time.Second, \"errs<10s\"},\n\t{1 * time.Minute, \"errs<1m\"},\n\t{10 * time.Minute, \"errs<10m\"},\n\t{1 * time.Hour, \"errs<1h\"},\n\t{10 * time.Hour, \"errs<10h\"},\n\t{24000 * time.Hour, \"errors\"},\n}\n\n// RenderEvents renders the HTML page typically served at /debug/events.\n// It does not do any auth checking. The request may be nil.\n//\n// Most users will use the Events handler.\nfunc RenderEvents(w http.ResponseWriter, req *http.Request, sensitive bool) {\n\tnow := time.Now()\n\tdata := &struct {\n\t\tFamilies []string // family names\n\t\tBuckets  []bucket\n\t\tCounts   [][]int // eventLog count per family/bucket\n\n\t\t// Set when a bucket has been selected.\n\t\tFamily    string\n\t\tBucket    int\n\t\tEventLogs eventLogs\n\t\tExpanded  bool\n\t}{\n\t\tBuckets: buckets,\n\t}\n\n\tdata.Families = make([]string, 0, len(families))\n\tfamMu.RLock()\n\tfor name := range families {\n\t\tdata.Families = append(data.Families, name)\n\t}\n\tfamMu.RUnlock()\n\tsort.Strings(data.Families)\n\n\t// Count the number of eventLogs in each family for each error age.\n\tdata.Counts = make([][]int, len(data.Families))\n\tfor i, name := range data.Families {\n\t\t// TODO(sameer): move this loop under the family lock.\n\t\tf := getEventFamily(name)\n\t\tdata.Counts[i] = make([]int, len(data.Buckets))\n\t\tfor j, b := range data.Buckets {\n\t\t\tdata.Counts[i][j] = f.Count(now, b.MaxErrAge)\n\t\t}\n\t}\n\n\tif req != nil {\n\t\tvar ok bool\n\t\tdata.Family, data.Bucket, ok = parseEventsArgs(req)\n\t\tif !ok {\n\t\t\t// No-op\n\t\t} else {\n\t\t\tdata.EventLogs = getEventFamily(data.Family).Copy(now, buckets[data.Bucket].MaxErrAge)\n\t\t}\n\t\tif data.EventLogs != nil {\n\t\t\tdefer data.EventLogs.Free()\n\t\t\tsort.Sort(data.EventLogs)\n\t\t}\n\t\tif exp, err := strconv.ParseBool(req.FormValue(\"exp\")); err == nil {\n\t\t\tdata.Expanded = exp\n\t\t}\n\t}\n\n\tfamMu.RLock()\n\tdefer famMu.RUnlock()\n\tif err := eventsTmpl().Execute(w, data); err != nil {\n\t\tlog.Printf(\"net/trace: Failed executing template: %v\", err)\n\t}\n}\n\nfunc parseEventsArgs(req *http.Request) (fam string, b int, ok bool) {\n\tfam, bStr := req.FormValue(\"fam\"), req.FormValue(\"b\")\n\tif fam == \"\" || bStr == \"\" {\n\t\treturn \"\", 0, false\n\t}\n\tb, err := strconv.Atoi(bStr)\n\tif err != nil || b < 0 || b >= len(buckets) {\n\t\treturn \"\", 0, false\n\t}\n\treturn fam, b, true\n}\n\n// An EventLog provides a log of events associated with a specific object.\ntype EventLog interface {\n\t// Printf formats its arguments with fmt.Sprintf and adds the\n\t// result to the event log.\n\tPrintf(format string, a ...interface{})\n\n\t// Errorf is like Printf, but it marks this event as an error.\n\tErrorf(format string, a ...interface{})\n\n\t// Finish declares that this event log is complete.\n\t// The event log should not be used after calling this method.\n\tFinish()\n}\n\n// NewEventLog returns a new EventLog with the specified family name\n// and title.\nfunc NewEventLog(family, title string) EventLog {\n\tel := newEventLog()\n\tel.ref()\n\tel.Family, el.Title = family, title\n\tel.Start = time.Now()\n\tel.events = make([]logEntry, 0, maxEventsPerLog)\n\tel.stack = make([]uintptr, 32)\n\tn := runtime.Callers(2, el.stack)\n\tel.stack = el.stack[:n]\n\n\tgetEventFamily(family).add(el)\n\treturn el\n}\n\nfunc (el *eventLog) Finish() {\n\tgetEventFamily(el.Family).remove(el)\n\tel.unref() // matches ref in New\n}\n\nvar (\n\tfamMu    sync.RWMutex\n\tfamilies = make(map[string]*eventFamily) // family name => family\n)\n\nfunc getEventFamily(fam string) *eventFamily {\n\tfamMu.Lock()\n\tdefer famMu.Unlock()\n\tf := families[fam]\n\tif f == nil {\n\t\tf = &eventFamily{}\n\t\tfamilies[fam] = f\n\t}\n\treturn f\n}\n\ntype eventFamily struct {\n\tmu        sync.RWMutex\n\teventLogs eventLogs\n}\n\nfunc (f *eventFamily) add(el *eventLog) {\n\tf.mu.Lock()\n\tf.eventLogs = append(f.eventLogs, el)\n\tf.mu.Unlock()\n}\n\nfunc (f *eventFamily) remove(el *eventLog) {\n\tf.mu.Lock()\n\tdefer f.mu.Unlock()\n\tfor i, el0 := range f.eventLogs {\n\t\tif el == el0 {\n\t\t\tcopy(f.eventLogs[i:], f.eventLogs[i+1:])\n\t\t\tf.eventLogs = f.eventLogs[:len(f.eventLogs)-1]\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (f *eventFamily) Count(now time.Time, maxErrAge time.Duration) (n int) {\n\tf.mu.RLock()\n\tdefer f.mu.RUnlock()\n\tfor _, el := range f.eventLogs {\n\t\tif el.hasRecentError(now, maxErrAge) {\n\t\t\tn++\n\t\t}\n\t}\n\treturn\n}\n\nfunc (f *eventFamily) Copy(now time.Time, maxErrAge time.Duration) (els eventLogs) {\n\tf.mu.RLock()\n\tdefer f.mu.RUnlock()\n\tels = make(eventLogs, 0, len(f.eventLogs))\n\tfor _, el := range f.eventLogs {\n\t\tif el.hasRecentError(now, maxErrAge) {\n\t\t\tel.ref()\n\t\t\tels = append(els, el)\n\t\t}\n\t}\n\treturn\n}\n\ntype eventLogs []*eventLog\n\n// Free calls unref on each element of the list.\nfunc (els eventLogs) Free() {\n\tfor _, el := range els {\n\t\tel.unref()\n\t}\n}\n\n// eventLogs may be sorted in reverse chronological order.\nfunc (els eventLogs) Len() int           { return len(els) }\nfunc (els eventLogs) Less(i, j int) bool { return els[i].Start.After(els[j].Start) }\nfunc (els eventLogs) Swap(i, j int)      { els[i], els[j] = els[j], els[i] }\n\n// A logEntry is a timestamped log entry in an event log.\ntype logEntry struct {\n\tWhen    time.Time\n\tElapsed time.Duration // since previous event in log\n\tNewDay  bool          // whether this event is on a different day to the previous event\n\tWhat    string\n\tIsErr   bool\n}\n\n// WhenString returns a string representation of the elapsed time of the event.\n// It will include the date if midnight was crossed.\nfunc (e logEntry) WhenString() string {\n\tif e.NewDay {\n\t\treturn e.When.Format(\"2006/01/02 15:04:05.000000\")\n\t}\n\treturn e.When.Format(\"15:04:05.000000\")\n}\n\n// An eventLog represents an active event log.\ntype eventLog struct {\n\t// Family is the top-level grouping of event logs to which this belongs.\n\tFamily string\n\n\t// Title is the title of this event log.\n\tTitle string\n\n\t// Timing information.\n\tStart time.Time\n\n\t// Call stack where this event log was created.\n\tstack []uintptr\n\n\t// Append-only sequence of events.\n\t//\n\t// TODO(sameer): change this to a ring buffer to avoid the array copy\n\t// when we hit maxEventsPerLog.\n\tmu            sync.RWMutex\n\tevents        []logEntry\n\tLastErrorTime time.Time\n\tdiscarded     int\n\n\trefs int32 // how many buckets this is in\n}\n\nfunc (el *eventLog) reset() {\n\t// Clear all but the mutex. Mutexes may not be copied, even when unlocked.\n\tel.Family = \"\"\n\tel.Title = \"\"\n\tel.Start = time.Time{}\n\tel.stack = nil\n\tel.events = nil\n\tel.LastErrorTime = time.Time{}\n\tel.discarded = 0\n\tel.refs = 0\n}\n\nfunc (el *eventLog) hasRecentError(now time.Time, maxErrAge time.Duration) bool {\n\tif maxErrAge == 0 {\n\t\treturn true\n\t}\n\tel.mu.RLock()\n\tdefer el.mu.RUnlock()\n\treturn now.Sub(el.LastErrorTime) < maxErrAge\n}\n\n// delta returns the elapsed time since the last event or the log start,\n// and whether it spans midnight.\n// L >= el.mu\nfunc (el *eventLog) delta(t time.Time) (time.Duration, bool) {\n\tif len(el.events) == 0 {\n\t\treturn t.Sub(el.Start), false\n\t}\n\tprev := el.events[len(el.events)-1].When\n\treturn t.Sub(prev), prev.Day() != t.Day()\n\n}\n\nfunc (el *eventLog) Printf(format string, a ...interface{}) {\n\tel.printf(false, format, a...)\n}\n\nfunc (el *eventLog) Errorf(format string, a ...interface{}) {\n\tel.printf(true, format, a...)\n}\n\nfunc (el *eventLog) printf(isErr bool, format string, a ...interface{}) {\n\te := logEntry{When: time.Now(), IsErr: isErr, What: fmt.Sprintf(format, a...)}\n\tel.mu.Lock()\n\te.Elapsed, e.NewDay = el.delta(e.When)\n\tif len(el.events) < maxEventsPerLog {\n\t\tel.events = append(el.events, e)\n\t} else {\n\t\t// Discard the oldest event.\n\t\tif el.discarded == 0 {\n\t\t\t// el.discarded starts at two to count for the event it\n\t\t\t// is replacing, plus the next one that we are about to\n\t\t\t// drop.\n\t\t\tel.discarded = 2\n\t\t} else {\n\t\t\tel.discarded++\n\t\t}\n\t\t// TODO(sameer): if this causes allocations on a critical path,\n\t\t// change eventLog.What to be a fmt.Stringer, as in trace.go.\n\t\tel.events[0].What = fmt.Sprintf(\"(%d events discarded)\", el.discarded)\n\t\t// The timestamp of the discarded meta-event should be\n\t\t// the time of the last event it is representing.\n\t\tel.events[0].When = el.events[1].When\n\t\tcopy(el.events[1:], el.events[2:])\n\t\tel.events[maxEventsPerLog-1] = e\n\t}\n\tif e.IsErr {\n\t\tel.LastErrorTime = e.When\n\t}\n\tel.mu.Unlock()\n}\n\nfunc (el *eventLog) ref() {\n\tatomic.AddInt32(&el.refs, 1)\n}\n\nfunc (el *eventLog) unref() {\n\tif atomic.AddInt32(&el.refs, -1) == 0 {\n\t\tfreeEventLog(el)\n\t}\n}\n\nfunc (el *eventLog) When() string {\n\treturn el.Start.Format(\"2006/01/02 15:04:05.000000\")\n}\n\nfunc (el *eventLog) ElapsedTime() string {\n\telapsed := time.Since(el.Start)\n\treturn fmt.Sprintf(\"%.6f\", elapsed.Seconds())\n}\n\nfunc (el *eventLog) Stack() string {\n\tbuf := new(bytes.Buffer)\n\ttw := tabwriter.NewWriter(buf, 1, 8, 1, '\\t', 0)\n\tprintStackRecord(tw, el.stack)\n\ttw.Flush()\n\treturn buf.String()\n}\n\n// printStackRecord prints the function + source line information\n// for a single stack trace.\n// Adapted from runtime/pprof/pprof.go.\nfunc printStackRecord(w io.Writer, stk []uintptr) {\n\tfor _, pc := range stk {\n\t\tf := runtime.FuncForPC(pc)\n\t\tif f == nil {\n\t\t\tcontinue\n\t\t}\n\t\tfile, line := f.FileLine(pc)\n\t\tname := f.Name()\n\t\t// Hide runtime.goexit and any runtime functions at the beginning.\n\t\tif strings.HasPrefix(name, \"runtime.\") {\n\t\t\tcontinue\n\t\t}\n\t\tfmt.Fprintf(w, \"#   %s\\t%s:%d\\n\", name, file, line)\n\t}\n}\n\nfunc (el *eventLog) Events() []logEntry {\n\tel.mu.RLock()\n\tdefer el.mu.RUnlock()\n\treturn el.events\n}\n\n// freeEventLogs is a freelist of *eventLog\nvar freeEventLogs = make(chan *eventLog, 1000)\n\n// newEventLog returns a event log ready to use.\nfunc newEventLog() *eventLog {\n\tselect {\n\tcase el := <-freeEventLogs:\n\t\treturn el\n\tdefault:\n\t\treturn new(eventLog)\n\t}\n}\n\n// freeEventLog adds el to freeEventLogs if there's room.\n// This is non-blocking.\nfunc freeEventLog(el *eventLog) {\n\tel.reset()\n\tselect {\n\tcase freeEventLogs <- el:\n\tdefault:\n\t}\n}\n\nvar eventsTmplCache *template.Template\nvar eventsTmplOnce sync.Once\n\nfunc eventsTmpl() *template.Template {\n\teventsTmplOnce.Do(func() {\n\t\teventsTmplCache = template.Must(template.New(\"events\").Funcs(template.FuncMap{\n\t\t\t\"elapsed\":   elapsed,\n\t\t\t\"trimSpace\": strings.TrimSpace,\n\t\t}).Parse(eventsHTML))\n\t})\n\treturn eventsTmplCache\n}\n\nconst eventsHTML = `\n<html>\n\t<head>\n\t\t<title>events</title>\n\t</head>\n\t<style type=\"text/css\">\n\t\tbody {\n\t\t\tfont-family: sans-serif;\n\t\t}\n\t\ttable#req-status td.family {\n\t\t\tpadding-right: 2em;\n\t\t}\n\t\ttable#req-status td.active {\n\t\t\tpadding-right: 1em;\n\t\t}\n\t\ttable#req-status td.empty {\n\t\t\tcolor: #aaa;\n\t\t}\n\t\ttable#reqs {\n\t\t\tmargin-top: 1em;\n\t\t}\n\t\ttable#reqs tr.first {\n\t\t\t{{if $.Expanded}}font-weight: bold;{{end}}\n\t\t}\n\t\ttable#reqs td {\n\t\t\tfont-family: monospace;\n\t\t}\n\t\ttable#reqs td.when {\n\t\t\ttext-align: right;\n\t\t\twhite-space: nowrap;\n\t\t}\n\t\ttable#reqs td.elapsed {\n\t\t\tpadding: 0 0.5em;\n\t\t\ttext-align: right;\n\t\t\twhite-space: pre;\n\t\t\twidth: 10em;\n\t\t}\n\t\taddress {\n\t\t\tfont-size: smaller;\n\t\t\tmargin-top: 5em;\n\t\t}\n\t</style>\n\t<body>\n\n<h1>/debug/events</h1>\n\n<table id=\"req-status\">\n\t{{range $i, $fam := .Families}}\n\t<tr>\n\t\t<td class=\"family\">{{$fam}}</td>\n\n\t        {{range $j, $bucket := $.Buckets}}\n\t        {{$n := index $.Counts $i $j}}\n\t\t<td class=\"{{if not $bucket.MaxErrAge}}active{{end}}{{if not $n}}empty{{end}}\">\n\t                {{if $n}}<a href=\"?fam={{$fam}}&b={{$j}}{{if $.Expanded}}&exp=1{{end}}\">{{end}}\n\t\t        [{{$n}} {{$bucket.String}}]\n\t\t\t{{if $n}}</a>{{end}}\n\t\t</td>\n                {{end}}\n\n\t</tr>{{end}}\n</table>\n\n{{if $.EventLogs}}\n<hr />\n<h3>Family: {{$.Family}}</h3>\n\n{{if $.Expanded}}<a href=\"?fam={{$.Family}}&b={{$.Bucket}}\">{{end}}\n[Summary]{{if $.Expanded}}</a>{{end}}\n\n{{if not $.Expanded}}<a href=\"?fam={{$.Family}}&b={{$.Bucket}}&exp=1\">{{end}}\n[Expanded]{{if not $.Expanded}}</a>{{end}}\n\n<table id=\"reqs\">\n\t<tr><th>When</th><th>Elapsed</th></tr>\n\t{{range $el := $.EventLogs}}\n\t<tr class=\"first\">\n\t\t<td class=\"when\">{{$el.When}}</td>\n\t\t<td class=\"elapsed\">{{$el.ElapsedTime}}</td>\n\t\t<td>{{$el.Title}}\n\t</tr>\n\t{{if $.Expanded}}\n\t<tr>\n\t\t<td class=\"when\"></td>\n\t\t<td class=\"elapsed\"></td>\n\t\t<td><pre>{{$el.Stack|trimSpace}}</pre></td>\n\t</tr>\n\t{{range $el.Events}}\n\t<tr>\n\t\t<td class=\"when\">{{.WhenString}}</td>\n\t\t<td class=\"elapsed\">{{elapsed .Elapsed}}</td>\n\t\t<td>.{{if .IsErr}}E{{else}}.{{end}}. {{.What}}</td>\n\t</tr>\n\t{{end}}\n\t{{end}}\n\t{{end}}\n</table>\n{{end}}\n\t</body>\n</html>\n`\n"
  },
  {
    "path": "vendor/golang.org/x/net/trace/histogram.go",
    "content": "// Copyright 2015 The Go 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 trace\n\n// This file implements histogramming for RPC statistics collection.\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"html/template\"\n\t\"log\"\n\t\"math\"\n\t\"sync\"\n\n\t\"golang.org/x/net/internal/timeseries\"\n)\n\nconst (\n\tbucketCount = 38\n)\n\n// histogram keeps counts of values in buckets that are spaced\n// out in powers of 2: 0-1, 2-3, 4-7...\n// histogram implements timeseries.Observable\ntype histogram struct {\n\tsum          int64   // running total of measurements\n\tsumOfSquares float64 // square of running total\n\tbuckets      []int64 // bucketed values for histogram\n\tvalue        int     // holds a single value as an optimization\n\tvalueCount   int64   // number of values recorded for single value\n}\n\n// addMeasurement records a value measurement observation to the histogram.\nfunc (h *histogram) addMeasurement(value int64) {\n\t// TODO: assert invariant\n\th.sum += value\n\th.sumOfSquares += float64(value) * float64(value)\n\n\tbucketIndex := getBucket(value)\n\n\tif h.valueCount == 0 || (h.valueCount > 0 && h.value == bucketIndex) {\n\t\th.value = bucketIndex\n\t\th.valueCount++\n\t} else {\n\t\th.allocateBuckets()\n\t\th.buckets[bucketIndex]++\n\t}\n}\n\nfunc (h *histogram) allocateBuckets() {\n\tif h.buckets == nil {\n\t\th.buckets = make([]int64, bucketCount)\n\t\th.buckets[h.value] = h.valueCount\n\t\th.value = 0\n\t\th.valueCount = -1\n\t}\n}\n\nfunc log2(i int64) int {\n\tn := 0\n\tfor ; i >= 0x100; i >>= 8 {\n\t\tn += 8\n\t}\n\tfor ; i > 0; i >>= 1 {\n\t\tn += 1\n\t}\n\treturn n\n}\n\nfunc getBucket(i int64) (index int) {\n\tindex = log2(i) - 1\n\tif index < 0 {\n\t\tindex = 0\n\t}\n\tif index >= bucketCount {\n\t\tindex = bucketCount - 1\n\t}\n\treturn\n}\n\n// Total returns the number of recorded observations.\nfunc (h *histogram) total() (total int64) {\n\tif h.valueCount >= 0 {\n\t\ttotal = h.valueCount\n\t}\n\tfor _, val := range h.buckets {\n\t\ttotal += int64(val)\n\t}\n\treturn\n}\n\n// Average returns the average value of recorded observations.\nfunc (h *histogram) average() float64 {\n\tt := h.total()\n\tif t == 0 {\n\t\treturn 0\n\t}\n\treturn float64(h.sum) / float64(t)\n}\n\n// Variance returns the variance of recorded observations.\nfunc (h *histogram) variance() float64 {\n\tt := float64(h.total())\n\tif t == 0 {\n\t\treturn 0\n\t}\n\ts := float64(h.sum) / t\n\treturn h.sumOfSquares/t - s*s\n}\n\n// StandardDeviation returns the standard deviation of recorded observations.\nfunc (h *histogram) standardDeviation() float64 {\n\treturn math.Sqrt(h.variance())\n}\n\n// PercentileBoundary estimates the value that the given fraction of recorded\n// observations are less than.\nfunc (h *histogram) percentileBoundary(percentile float64) int64 {\n\ttotal := h.total()\n\n\t// Corner cases (make sure result is strictly less than Total())\n\tif total == 0 {\n\t\treturn 0\n\t} else if total == 1 {\n\t\treturn int64(h.average())\n\t}\n\n\tpercentOfTotal := round(float64(total) * percentile)\n\tvar runningTotal int64\n\n\tfor i := range h.buckets {\n\t\tvalue := h.buckets[i]\n\t\trunningTotal += value\n\t\tif runningTotal == percentOfTotal {\n\t\t\t// We hit an exact bucket boundary. If the next bucket has data, it is a\n\t\t\t// good estimate of the value. If the bucket is empty, we interpolate the\n\t\t\t// midpoint between the next bucket's boundary and the next non-zero\n\t\t\t// bucket. If the remaining buckets are all empty, then we use the\n\t\t\t// boundary for the next bucket as the estimate.\n\t\t\tj := uint8(i + 1)\n\t\t\tmin := bucketBoundary(j)\n\t\t\tif runningTotal < total {\n\t\t\t\tfor h.buckets[j] == 0 {\n\t\t\t\t\tj++\n\t\t\t\t}\n\t\t\t}\n\t\t\tmax := bucketBoundary(j)\n\t\t\treturn min + round(float64(max-min)/2)\n\t\t} else if runningTotal > percentOfTotal {\n\t\t\t// The value is in this bucket. Interpolate the value.\n\t\t\tdelta := runningTotal - percentOfTotal\n\t\t\tpercentBucket := float64(value-delta) / float64(value)\n\t\t\tbucketMin := bucketBoundary(uint8(i))\n\t\t\tnextBucketMin := bucketBoundary(uint8(i + 1))\n\t\t\tbucketSize := nextBucketMin - bucketMin\n\t\t\treturn bucketMin + round(percentBucket*float64(bucketSize))\n\t\t}\n\t}\n\treturn bucketBoundary(bucketCount - 1)\n}\n\n// Median returns the estimated median of the observed values.\nfunc (h *histogram) median() int64 {\n\treturn h.percentileBoundary(0.5)\n}\n\n// Add adds other to h.\nfunc (h *histogram) Add(other timeseries.Observable) {\n\to := other.(*histogram)\n\tif o.valueCount == 0 {\n\t\t// Other histogram is empty\n\t} else if h.valueCount >= 0 && o.valueCount > 0 && h.value == o.value {\n\t\t// Both have a single bucketed value, aggregate them\n\t\th.valueCount += o.valueCount\n\t} else {\n\t\t// Two different values necessitate buckets in this histogram\n\t\th.allocateBuckets()\n\t\tif o.valueCount >= 0 {\n\t\t\th.buckets[o.value] += o.valueCount\n\t\t} else {\n\t\t\tfor i := range h.buckets {\n\t\t\t\th.buckets[i] += o.buckets[i]\n\t\t\t}\n\t\t}\n\t}\n\th.sumOfSquares += o.sumOfSquares\n\th.sum += o.sum\n}\n\n// Clear resets the histogram to an empty state, removing all observed values.\nfunc (h *histogram) Clear() {\n\th.buckets = nil\n\th.value = 0\n\th.valueCount = 0\n\th.sum = 0\n\th.sumOfSquares = 0\n}\n\n// CopyFrom copies from other, which must be a *histogram, into h.\nfunc (h *histogram) CopyFrom(other timeseries.Observable) {\n\to := other.(*histogram)\n\tif o.valueCount == -1 {\n\t\th.allocateBuckets()\n\t\tcopy(h.buckets, o.buckets)\n\t}\n\th.sum = o.sum\n\th.sumOfSquares = o.sumOfSquares\n\th.value = o.value\n\th.valueCount = o.valueCount\n}\n\n// Multiply scales the histogram by the specified ratio.\nfunc (h *histogram) Multiply(ratio float64) {\n\tif h.valueCount == -1 {\n\t\tfor i := range h.buckets {\n\t\t\th.buckets[i] = int64(float64(h.buckets[i]) * ratio)\n\t\t}\n\t} else {\n\t\th.valueCount = int64(float64(h.valueCount) * ratio)\n\t}\n\th.sum = int64(float64(h.sum) * ratio)\n\th.sumOfSquares = h.sumOfSquares * ratio\n}\n\n// New creates a new histogram.\nfunc (h *histogram) New() timeseries.Observable {\n\tr := new(histogram)\n\tr.Clear()\n\treturn r\n}\n\nfunc (h *histogram) String() string {\n\treturn fmt.Sprintf(\"%d, %f, %d, %d, %v\",\n\t\th.sum, h.sumOfSquares, h.value, h.valueCount, h.buckets)\n}\n\n// round returns the closest int64 to the argument\nfunc round(in float64) int64 {\n\treturn int64(math.Floor(in + 0.5))\n}\n\n// bucketBoundary returns the first value in the bucket.\nfunc bucketBoundary(bucket uint8) int64 {\n\tif bucket == 0 {\n\t\treturn 0\n\t}\n\treturn 1 << bucket\n}\n\n// bucketData holds data about a specific bucket for use in distTmpl.\ntype bucketData struct {\n\tLower, Upper       int64\n\tN                  int64\n\tPct, CumulativePct float64\n\tGraphWidth         int\n}\n\n// data holds data about a Distribution for use in distTmpl.\ntype data struct {\n\tBuckets                 []*bucketData\n\tCount, Median           int64\n\tMean, StandardDeviation float64\n}\n\n// maxHTMLBarWidth is the maximum width of the HTML bar for visualizing buckets.\nconst maxHTMLBarWidth = 350.0\n\n// newData returns data representing h for use in distTmpl.\nfunc (h *histogram) newData() *data {\n\t// Force the allocation of buckets to simplify the rendering implementation\n\th.allocateBuckets()\n\t// We scale the bars on the right so that the largest bar is\n\t// maxHTMLBarWidth pixels in width.\n\tmaxBucket := int64(0)\n\tfor _, n := range h.buckets {\n\t\tif n > maxBucket {\n\t\t\tmaxBucket = n\n\t\t}\n\t}\n\ttotal := h.total()\n\tbarsizeMult := maxHTMLBarWidth / float64(maxBucket)\n\tvar pctMult float64\n\tif total == 0 {\n\t\tpctMult = 1.0\n\t} else {\n\t\tpctMult = 100.0 / float64(total)\n\t}\n\n\tbuckets := make([]*bucketData, len(h.buckets))\n\trunningTotal := int64(0)\n\tfor i, n := range h.buckets {\n\t\tif n == 0 {\n\t\t\tcontinue\n\t\t}\n\t\trunningTotal += n\n\t\tvar upperBound int64\n\t\tif i < bucketCount-1 {\n\t\t\tupperBound = bucketBoundary(uint8(i + 1))\n\t\t} else {\n\t\t\tupperBound = math.MaxInt64\n\t\t}\n\t\tbuckets[i] = &bucketData{\n\t\t\tLower:         bucketBoundary(uint8(i)),\n\t\t\tUpper:         upperBound,\n\t\t\tN:             n,\n\t\t\tPct:           float64(n) * pctMult,\n\t\t\tCumulativePct: float64(runningTotal) * pctMult,\n\t\t\tGraphWidth:    int(float64(n) * barsizeMult),\n\t\t}\n\t}\n\treturn &data{\n\t\tBuckets:           buckets,\n\t\tCount:             total,\n\t\tMedian:            h.median(),\n\t\tMean:              h.average(),\n\t\tStandardDeviation: h.standardDeviation(),\n\t}\n}\n\nfunc (h *histogram) html() template.HTML {\n\tbuf := new(bytes.Buffer)\n\tif err := distTmpl().Execute(buf, h.newData()); err != nil {\n\t\tbuf.Reset()\n\t\tlog.Printf(\"net/trace: couldn't execute template: %v\", err)\n\t}\n\treturn template.HTML(buf.String())\n}\n\nvar distTmplCache *template.Template\nvar distTmplOnce sync.Once\n\nfunc distTmpl() *template.Template {\n\tdistTmplOnce.Do(func() {\n\t\t// Input: data\n\t\tdistTmplCache = template.Must(template.New(\"distTmpl\").Parse(`\n<table>\n<tr>\n    <td style=\"padding:0.25em\">Count: {{.Count}}</td>\n    <td style=\"padding:0.25em\">Mean: {{printf \"%.0f\" .Mean}}</td>\n    <td style=\"padding:0.25em\">StdDev: {{printf \"%.0f\" .StandardDeviation}}</td>\n    <td style=\"padding:0.25em\">Median: {{.Median}}</td>\n</tr>\n</table>\n<hr>\n<table>\n{{range $b := .Buckets}}\n{{if $b}}\n  <tr>\n    <td style=\"padding:0 0 0 0.25em\">[</td>\n    <td style=\"text-align:right;padding:0 0.25em\">{{.Lower}},</td>\n    <td style=\"text-align:right;padding:0 0.25em\">{{.Upper}})</td>\n    <td style=\"text-align:right;padding:0 0.25em\">{{.N}}</td>\n    <td style=\"text-align:right;padding:0 0.25em\">{{printf \"%#.3f\" .Pct}}%</td>\n    <td style=\"text-align:right;padding:0 0.25em\">{{printf \"%#.3f\" .CumulativePct}}%</td>\n    <td><div style=\"background-color: blue; height: 1em; width: {{.GraphWidth}};\"></div></td>\n  </tr>\n{{end}}\n{{end}}\n</table>\n`))\n\t})\n\treturn distTmplCache\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/trace/trace.go",
    "content": "// Copyright 2015 The Go 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\n/*\nPackage trace implements tracing of requests and long-lived objects.\nIt exports HTTP interfaces on /debug/requests and /debug/events.\n\nA trace.Trace provides tracing for short-lived objects, usually requests.\nA request handler might be implemented like this:\n\n\tfunc fooHandler(w http.ResponseWriter, req *http.Request) {\n\t\ttr := trace.New(\"mypkg.Foo\", req.URL.Path)\n\t\tdefer tr.Finish()\n\t\t...\n\t\ttr.LazyPrintf(\"some event %q happened\", str)\n\t\t...\n\t\tif err := somethingImportant(); err != nil {\n\t\t\ttr.LazyPrintf(\"somethingImportant failed: %v\", err)\n\t\t\ttr.SetError()\n\t\t}\n\t}\n\nThe /debug/requests HTTP endpoint organizes the traces by family,\nerrors, and duration.  It also provides histogram of request duration\nfor each family.\n\nA trace.EventLog provides tracing for long-lived objects, such as RPC\nconnections.\n\n\t// A Fetcher fetches URL paths for a single domain.\n\ttype Fetcher struct {\n\t\tdomain string\n\t\tevents trace.EventLog\n\t}\n\n\tfunc NewFetcher(domain string) *Fetcher {\n\t\treturn &Fetcher{\n\t\t\tdomain,\n\t\t\ttrace.NewEventLog(\"mypkg.Fetcher\", domain),\n\t\t}\n\t}\n\n\tfunc (f *Fetcher) Fetch(path string) (string, error) {\n\t\tresp, err := http.Get(\"http://\" + f.domain + \"/\" + path)\n\t\tif err != nil {\n\t\t\tf.events.Errorf(\"Get(%q) = %v\", path, err)\n\t\t\treturn \"\", err\n\t\t}\n\t\tf.events.Printf(\"Get(%q) = %s\", path, resp.Status)\n\t\t...\n\t}\n\n\tfunc (f *Fetcher) Close() error {\n\t\tf.events.Finish()\n\t\treturn nil\n\t}\n\nThe /debug/events HTTP endpoint organizes the event logs by family and\nby time since the last error.  The expanded view displays recent log\nentries and the log's call stack.\n*/\npackage trace // import \"golang.org/x/net/trace\"\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"html/template\"\n\t\"io\"\n\t\"log\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strconv\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"golang.org/x/net/internal/timeseries\"\n)\n\n// DebugUseAfterFinish controls whether to debug uses of Trace values after finishing.\n// FOR DEBUGGING ONLY. This will slow down the program.\nvar DebugUseAfterFinish = false\n\n// HTTP ServeMux paths.\nconst (\n\tdebugRequestsPath = \"/debug/requests\"\n\tdebugEventsPath   = \"/debug/events\"\n)\n\n// AuthRequest determines whether a specific request is permitted to load the\n// /debug/requests or /debug/events pages.\n//\n// It returns two bools; the first indicates whether the page may be viewed at all,\n// and the second indicates whether sensitive events will be shown.\n//\n// AuthRequest may be replaced by a program to customize its authorization requirements.\n//\n// The default AuthRequest function returns (true, true) if and only if the request\n// comes from localhost/127.0.0.1/[::1].\nvar AuthRequest = func(req *http.Request) (any, sensitive bool) {\n\t// RemoteAddr is commonly in the form \"IP\" or \"IP:port\".\n\t// If it is in the form \"IP:port\", split off the port.\n\thost, _, err := net.SplitHostPort(req.RemoteAddr)\n\tif err != nil {\n\t\thost = req.RemoteAddr\n\t}\n\tswitch host {\n\tcase \"localhost\", \"127.0.0.1\", \"::1\":\n\t\treturn true, true\n\tdefault:\n\t\treturn false, false\n\t}\n}\n\nfunc init() {\n\t_, pat := http.DefaultServeMux.Handler(&http.Request{URL: &url.URL{Path: debugRequestsPath}})\n\tif pat == debugRequestsPath {\n\t\tpanic(\"/debug/requests is already registered. You may have two independent copies of \" +\n\t\t\t\"golang.org/x/net/trace in your binary, trying to maintain separate state. This may \" +\n\t\t\t\"involve a vendored copy of golang.org/x/net/trace.\")\n\t}\n\n\t// TODO(jbd): Serve Traces from /debug/traces in the future?\n\t// There is no requirement for a request to be present to have traces.\n\thttp.HandleFunc(debugRequestsPath, Traces)\n\thttp.HandleFunc(debugEventsPath, Events)\n}\n\n// NewContext returns a copy of the parent context\n// and associates it with a Trace.\nfunc NewContext(ctx context.Context, tr Trace) context.Context {\n\treturn context.WithValue(ctx, contextKey, tr)\n}\n\n// FromContext returns the Trace bound to the context, if any.\nfunc FromContext(ctx context.Context) (tr Trace, ok bool) {\n\ttr, ok = ctx.Value(contextKey).(Trace)\n\treturn\n}\n\n// Traces responds with traces from the program.\n// The package initialization registers it in http.DefaultServeMux\n// at /debug/requests.\n//\n// It performs authorization by running AuthRequest.\nfunc Traces(w http.ResponseWriter, req *http.Request) {\n\tany, sensitive := AuthRequest(req)\n\tif !any {\n\t\thttp.Error(w, \"not allowed\", http.StatusUnauthorized)\n\t\treturn\n\t}\n\tw.Header().Set(\"Content-Type\", \"text/html; charset=utf-8\")\n\tRender(w, req, sensitive)\n}\n\n// Events responds with a page of events collected by EventLogs.\n// The package initialization registers it in http.DefaultServeMux\n// at /debug/events.\n//\n// It performs authorization by running AuthRequest.\nfunc Events(w http.ResponseWriter, req *http.Request) {\n\tany, sensitive := AuthRequest(req)\n\tif !any {\n\t\thttp.Error(w, \"not allowed\", http.StatusUnauthorized)\n\t\treturn\n\t}\n\tw.Header().Set(\"Content-Type\", \"text/html; charset=utf-8\")\n\tRenderEvents(w, req, sensitive)\n}\n\n// Render renders the HTML page typically served at /debug/requests.\n// It does not do any auth checking. The request may be nil.\n//\n// Most users will use the Traces handler.\nfunc Render(w io.Writer, req *http.Request, sensitive bool) {\n\tdata := &struct {\n\t\tFamilies         []string\n\t\tActiveTraceCount map[string]int\n\t\tCompletedTraces  map[string]*family\n\n\t\t// Set when a bucket has been selected.\n\t\tTraces        traceList\n\t\tFamily        string\n\t\tBucket        int\n\t\tExpanded      bool\n\t\tTraced        bool\n\t\tActive        bool\n\t\tShowSensitive bool // whether to show sensitive events\n\n\t\tHistogram       template.HTML\n\t\tHistogramWindow string // e.g. \"last minute\", \"last hour\", \"all time\"\n\n\t\t// If non-zero, the set of traces is a partial set,\n\t\t// and this is the total number.\n\t\tTotal int\n\t}{\n\t\tCompletedTraces: completedTraces,\n\t}\n\n\tdata.ShowSensitive = sensitive\n\tif req != nil {\n\t\t// Allow show_sensitive=0 to force hiding of sensitive data for testing.\n\t\t// This only goes one way; you can't use show_sensitive=1 to see things.\n\t\tif req.FormValue(\"show_sensitive\") == \"0\" {\n\t\t\tdata.ShowSensitive = false\n\t\t}\n\n\t\tif exp, err := strconv.ParseBool(req.FormValue(\"exp\")); err == nil {\n\t\t\tdata.Expanded = exp\n\t\t}\n\t\tif exp, err := strconv.ParseBool(req.FormValue(\"rtraced\")); err == nil {\n\t\t\tdata.Traced = exp\n\t\t}\n\t}\n\n\tcompletedMu.RLock()\n\tdata.Families = make([]string, 0, len(completedTraces))\n\tfor fam := range completedTraces {\n\t\tdata.Families = append(data.Families, fam)\n\t}\n\tcompletedMu.RUnlock()\n\tsort.Strings(data.Families)\n\n\t// We are careful here to minimize the time spent locking activeMu,\n\t// since that lock is required every time an RPC starts and finishes.\n\tdata.ActiveTraceCount = make(map[string]int, len(data.Families))\n\tactiveMu.RLock()\n\tfor fam, s := range activeTraces {\n\t\tdata.ActiveTraceCount[fam] = s.Len()\n\t}\n\tactiveMu.RUnlock()\n\n\tvar ok bool\n\tdata.Family, data.Bucket, ok = parseArgs(req)\n\tswitch {\n\tcase !ok:\n\t\t// No-op\n\tcase data.Bucket == -1:\n\t\tdata.Active = true\n\t\tn := data.ActiveTraceCount[data.Family]\n\t\tdata.Traces = getActiveTraces(data.Family)\n\t\tif len(data.Traces) < n {\n\t\t\tdata.Total = n\n\t\t}\n\tcase data.Bucket < bucketsPerFamily:\n\t\tif b := lookupBucket(data.Family, data.Bucket); b != nil {\n\t\t\tdata.Traces = b.Copy(data.Traced)\n\t\t}\n\tdefault:\n\t\tif f := getFamily(data.Family, false); f != nil {\n\t\t\tvar obs timeseries.Observable\n\t\t\tf.LatencyMu.RLock()\n\t\t\tswitch o := data.Bucket - bucketsPerFamily; o {\n\t\t\tcase 0:\n\t\t\t\tobs = f.Latency.Minute()\n\t\t\t\tdata.HistogramWindow = \"last minute\"\n\t\t\tcase 1:\n\t\t\t\tobs = f.Latency.Hour()\n\t\t\t\tdata.HistogramWindow = \"last hour\"\n\t\t\tcase 2:\n\t\t\t\tobs = f.Latency.Total()\n\t\t\t\tdata.HistogramWindow = \"all time\"\n\t\t\t}\n\t\t\tf.LatencyMu.RUnlock()\n\t\t\tif obs != nil {\n\t\t\t\tdata.Histogram = obs.(*histogram).html()\n\t\t\t}\n\t\t}\n\t}\n\n\tif data.Traces != nil {\n\t\tdefer data.Traces.Free()\n\t\tsort.Sort(data.Traces)\n\t}\n\n\tcompletedMu.RLock()\n\tdefer completedMu.RUnlock()\n\tif err := pageTmpl().ExecuteTemplate(w, \"Page\", data); err != nil {\n\t\tlog.Printf(\"net/trace: Failed executing template: %v\", err)\n\t}\n}\n\nfunc parseArgs(req *http.Request) (fam string, b int, ok bool) {\n\tif req == nil {\n\t\treturn \"\", 0, false\n\t}\n\tfam, bStr := req.FormValue(\"fam\"), req.FormValue(\"b\")\n\tif fam == \"\" || bStr == \"\" {\n\t\treturn \"\", 0, false\n\t}\n\tb, err := strconv.Atoi(bStr)\n\tif err != nil || b < -1 {\n\t\treturn \"\", 0, false\n\t}\n\n\treturn fam, b, true\n}\n\nfunc lookupBucket(fam string, b int) *traceBucket {\n\tf := getFamily(fam, false)\n\tif f == nil || b < 0 || b >= len(f.Buckets) {\n\t\treturn nil\n\t}\n\treturn f.Buckets[b]\n}\n\ntype contextKeyT string\n\nvar contextKey = contextKeyT(\"golang.org/x/net/trace.Trace\")\n\n// Trace represents an active request.\ntype Trace interface {\n\t// LazyLog adds x to the event log. It will be evaluated each time the\n\t// /debug/requests page is rendered. Any memory referenced by x will be\n\t// pinned until the trace is finished and later discarded.\n\tLazyLog(x fmt.Stringer, sensitive bool)\n\n\t// LazyPrintf evaluates its arguments with fmt.Sprintf each time the\n\t// /debug/requests page is rendered. Any memory referenced by a will be\n\t// pinned until the trace is finished and later discarded.\n\tLazyPrintf(format string, a ...interface{})\n\n\t// SetError declares that this trace resulted in an error.\n\tSetError()\n\n\t// SetRecycler sets a recycler for the trace.\n\t// f will be called for each event passed to LazyLog at a time when\n\t// it is no longer required, whether while the trace is still active\n\t// and the event is discarded, or when a completed trace is discarded.\n\tSetRecycler(f func(interface{}))\n\n\t// SetTraceInfo sets the trace info for the trace.\n\t// This is currently unused.\n\tSetTraceInfo(traceID, spanID uint64)\n\n\t// SetMaxEvents sets the maximum number of events that will be stored\n\t// in the trace. This has no effect if any events have already been\n\t// added to the trace.\n\tSetMaxEvents(m int)\n\n\t// Finish declares that this trace is complete.\n\t// The trace should not be used after calling this method.\n\tFinish()\n}\n\ntype lazySprintf struct {\n\tformat string\n\ta      []interface{}\n}\n\nfunc (l *lazySprintf) String() string {\n\treturn fmt.Sprintf(l.format, l.a...)\n}\n\n// New returns a new Trace with the specified family and title.\nfunc New(family, title string) Trace {\n\ttr := newTrace()\n\ttr.ref()\n\ttr.Family, tr.Title = family, title\n\ttr.Start = time.Now()\n\ttr.maxEvents = maxEventsPerTrace\n\ttr.events = tr.eventsBuf[:0]\n\n\tactiveMu.RLock()\n\ts := activeTraces[tr.Family]\n\tactiveMu.RUnlock()\n\tif s == nil {\n\t\tactiveMu.Lock()\n\t\ts = activeTraces[tr.Family] // check again\n\t\tif s == nil {\n\t\t\ts = new(traceSet)\n\t\t\tactiveTraces[tr.Family] = s\n\t\t}\n\t\tactiveMu.Unlock()\n\t}\n\ts.Add(tr)\n\n\t// Trigger allocation of the completed trace structure for this family.\n\t// This will cause the family to be present in the request page during\n\t// the first trace of this family. We don't care about the return value,\n\t// nor is there any need for this to run inline, so we execute it in its\n\t// own goroutine, but only if the family isn't allocated yet.\n\tcompletedMu.RLock()\n\tif _, ok := completedTraces[tr.Family]; !ok {\n\t\tgo allocFamily(tr.Family)\n\t}\n\tcompletedMu.RUnlock()\n\n\treturn tr\n}\n\nfunc (tr *trace) Finish() {\n\telapsed := time.Since(tr.Start)\n\ttr.mu.Lock()\n\ttr.Elapsed = elapsed\n\ttr.mu.Unlock()\n\n\tif DebugUseAfterFinish {\n\t\tbuf := make([]byte, 4<<10) // 4 KB should be enough\n\t\tn := runtime.Stack(buf, false)\n\t\ttr.finishStack = buf[:n]\n\t}\n\n\tactiveMu.RLock()\n\tm := activeTraces[tr.Family]\n\tactiveMu.RUnlock()\n\tm.Remove(tr)\n\n\tf := getFamily(tr.Family, true)\n\ttr.mu.RLock() // protects tr fields in Cond.match calls\n\tfor _, b := range f.Buckets {\n\t\tif b.Cond.match(tr) {\n\t\t\tb.Add(tr)\n\t\t}\n\t}\n\ttr.mu.RUnlock()\n\n\t// Add a sample of elapsed time as microseconds to the family's timeseries\n\th := new(histogram)\n\th.addMeasurement(elapsed.Nanoseconds() / 1e3)\n\tf.LatencyMu.Lock()\n\tf.Latency.Add(h)\n\tf.LatencyMu.Unlock()\n\n\ttr.unref() // matches ref in New\n}\n\nconst (\n\tbucketsPerFamily    = 9\n\ttracesPerBucket     = 10\n\tmaxActiveTraces     = 20 // Maximum number of active traces to show.\n\tmaxEventsPerTrace   = 10\n\tnumHistogramBuckets = 38\n)\n\nvar (\n\t// The active traces.\n\tactiveMu     sync.RWMutex\n\tactiveTraces = make(map[string]*traceSet) // family -> traces\n\n\t// Families of completed traces.\n\tcompletedMu     sync.RWMutex\n\tcompletedTraces = make(map[string]*family) // family -> traces\n)\n\ntype traceSet struct {\n\tmu sync.RWMutex\n\tm  map[*trace]bool\n\n\t// We could avoid the entire map scan in FirstN by having a slice of all the traces\n\t// ordered by start time, and an index into that from the trace struct, with a periodic\n\t// repack of the slice after enough traces finish; we could also use a skip list or similar.\n\t// However, that would shift some of the expense from /debug/requests time to RPC time,\n\t// which is probably the wrong trade-off.\n}\n\nfunc (ts *traceSet) Len() int {\n\tts.mu.RLock()\n\tdefer ts.mu.RUnlock()\n\treturn len(ts.m)\n}\n\nfunc (ts *traceSet) Add(tr *trace) {\n\tts.mu.Lock()\n\tif ts.m == nil {\n\t\tts.m = make(map[*trace]bool)\n\t}\n\tts.m[tr] = true\n\tts.mu.Unlock()\n}\n\nfunc (ts *traceSet) Remove(tr *trace) {\n\tts.mu.Lock()\n\tdelete(ts.m, tr)\n\tts.mu.Unlock()\n}\n\n// FirstN returns the first n traces ordered by time.\nfunc (ts *traceSet) FirstN(n int) traceList {\n\tts.mu.RLock()\n\tdefer ts.mu.RUnlock()\n\n\tif n > len(ts.m) {\n\t\tn = len(ts.m)\n\t}\n\ttrl := make(traceList, 0, n)\n\n\t// Fast path for when no selectivity is needed.\n\tif n == len(ts.m) {\n\t\tfor tr := range ts.m {\n\t\t\ttr.ref()\n\t\t\ttrl = append(trl, tr)\n\t\t}\n\t\tsort.Sort(trl)\n\t\treturn trl\n\t}\n\n\t// Pick the oldest n traces.\n\t// This is inefficient. See the comment in the traceSet struct.\n\tfor tr := range ts.m {\n\t\t// Put the first n traces into trl in the order they occur.\n\t\t// When we have n, sort trl, and thereafter maintain its order.\n\t\tif len(trl) < n {\n\t\t\ttr.ref()\n\t\t\ttrl = append(trl, tr)\n\t\t\tif len(trl) == n {\n\t\t\t\t// This is guaranteed to happen exactly once during this loop.\n\t\t\t\tsort.Sort(trl)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif tr.Start.After(trl[n-1].Start) {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Find where to insert this one.\n\t\ttr.ref()\n\t\ti := sort.Search(n, func(i int) bool { return trl[i].Start.After(tr.Start) })\n\t\ttrl[n-1].unref()\n\t\tcopy(trl[i+1:], trl[i:])\n\t\ttrl[i] = tr\n\t}\n\n\treturn trl\n}\n\nfunc getActiveTraces(fam string) traceList {\n\tactiveMu.RLock()\n\ts := activeTraces[fam]\n\tactiveMu.RUnlock()\n\tif s == nil {\n\t\treturn nil\n\t}\n\treturn s.FirstN(maxActiveTraces)\n}\n\nfunc getFamily(fam string, allocNew bool) *family {\n\tcompletedMu.RLock()\n\tf := completedTraces[fam]\n\tcompletedMu.RUnlock()\n\tif f == nil && allocNew {\n\t\tf = allocFamily(fam)\n\t}\n\treturn f\n}\n\nfunc allocFamily(fam string) *family {\n\tcompletedMu.Lock()\n\tdefer completedMu.Unlock()\n\tf := completedTraces[fam]\n\tif f == nil {\n\t\tf = newFamily()\n\t\tcompletedTraces[fam] = f\n\t}\n\treturn f\n}\n\n// family represents a set of trace buckets and associated latency information.\ntype family struct {\n\t// traces may occur in multiple buckets.\n\tBuckets [bucketsPerFamily]*traceBucket\n\n\t// latency time series\n\tLatencyMu sync.RWMutex\n\tLatency   *timeseries.MinuteHourSeries\n}\n\nfunc newFamily() *family {\n\treturn &family{\n\t\tBuckets: [bucketsPerFamily]*traceBucket{\n\t\t\t{Cond: minCond(0)},\n\t\t\t{Cond: minCond(50 * time.Millisecond)},\n\t\t\t{Cond: minCond(100 * time.Millisecond)},\n\t\t\t{Cond: minCond(200 * time.Millisecond)},\n\t\t\t{Cond: minCond(500 * time.Millisecond)},\n\t\t\t{Cond: minCond(1 * time.Second)},\n\t\t\t{Cond: minCond(10 * time.Second)},\n\t\t\t{Cond: minCond(100 * time.Second)},\n\t\t\t{Cond: errorCond{}},\n\t\t},\n\t\tLatency: timeseries.NewMinuteHourSeries(func() timeseries.Observable { return new(histogram) }),\n\t}\n}\n\n// traceBucket represents a size-capped bucket of historic traces,\n// along with a condition for a trace to belong to the bucket.\ntype traceBucket struct {\n\tCond cond\n\n\t// Ring buffer implementation of a fixed-size FIFO queue.\n\tmu     sync.RWMutex\n\tbuf    [tracesPerBucket]*trace\n\tstart  int // < tracesPerBucket\n\tlength int // <= tracesPerBucket\n}\n\nfunc (b *traceBucket) Add(tr *trace) {\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\n\ti := b.start + b.length\n\tif i >= tracesPerBucket {\n\t\ti -= tracesPerBucket\n\t}\n\tif b.length == tracesPerBucket {\n\t\t// \"Remove\" an element from the bucket.\n\t\tb.buf[i].unref()\n\t\tb.start++\n\t\tif b.start == tracesPerBucket {\n\t\t\tb.start = 0\n\t\t}\n\t}\n\tb.buf[i] = tr\n\tif b.length < tracesPerBucket {\n\t\tb.length++\n\t}\n\ttr.ref()\n}\n\n// Copy returns a copy of the traces in the bucket.\n// If tracedOnly is true, only the traces with trace information will be returned.\n// The logs will be ref'd before returning; the caller should call\n// the Free method when it is done with them.\n// TODO(dsymonds): keep track of traced requests in separate buckets.\nfunc (b *traceBucket) Copy(tracedOnly bool) traceList {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\n\ttrl := make(traceList, 0, b.length)\n\tfor i, x := 0, b.start; i < b.length; i++ {\n\t\ttr := b.buf[x]\n\t\tif !tracedOnly || tr.spanID != 0 {\n\t\t\ttr.ref()\n\t\t\ttrl = append(trl, tr)\n\t\t}\n\t\tx++\n\t\tif x == b.length {\n\t\t\tx = 0\n\t\t}\n\t}\n\treturn trl\n}\n\nfunc (b *traceBucket) Empty() bool {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\treturn b.length == 0\n}\n\n// cond represents a condition on a trace.\ntype cond interface {\n\tmatch(t *trace) bool\n\tString() string\n}\n\ntype minCond time.Duration\n\nfunc (m minCond) match(t *trace) bool { return t.Elapsed >= time.Duration(m) }\nfunc (m minCond) String() string      { return fmt.Sprintf(\"≥%gs\", time.Duration(m).Seconds()) }\n\ntype errorCond struct{}\n\nfunc (e errorCond) match(t *trace) bool { return t.IsError }\nfunc (e errorCond) String() string      { return \"errors\" }\n\ntype traceList []*trace\n\n// Free calls unref on each element of the list.\nfunc (trl traceList) Free() {\n\tfor _, t := range trl {\n\t\tt.unref()\n\t}\n}\n\n// traceList may be sorted in reverse chronological order.\nfunc (trl traceList) Len() int           { return len(trl) }\nfunc (trl traceList) Less(i, j int) bool { return trl[i].Start.After(trl[j].Start) }\nfunc (trl traceList) Swap(i, j int)      { trl[i], trl[j] = trl[j], trl[i] }\n\n// An event is a timestamped log entry in a trace.\ntype event struct {\n\tWhen       time.Time\n\tElapsed    time.Duration // since previous event in trace\n\tNewDay     bool          // whether this event is on a different day to the previous event\n\tRecyclable bool          // whether this event was passed via LazyLog\n\tSensitive  bool          // whether this event contains sensitive information\n\tWhat       interface{}   // string or fmt.Stringer\n}\n\n// WhenString returns a string representation of the elapsed time of the event.\n// It will include the date if midnight was crossed.\nfunc (e event) WhenString() string {\n\tif e.NewDay {\n\t\treturn e.When.Format(\"2006/01/02 15:04:05.000000\")\n\t}\n\treturn e.When.Format(\"15:04:05.000000\")\n}\n\n// discarded represents a number of discarded events.\n// It is stored as *discarded to make it easier to update in-place.\ntype discarded int\n\nfunc (d *discarded) String() string {\n\treturn fmt.Sprintf(\"(%d events discarded)\", int(*d))\n}\n\n// trace represents an active or complete request,\n// either sent or received by this program.\ntype trace struct {\n\t// Family is the top-level grouping of traces to which this belongs.\n\tFamily string\n\n\t// Title is the title of this trace.\n\tTitle string\n\n\t// Start time of the this trace.\n\tStart time.Time\n\n\tmu        sync.RWMutex\n\tevents    []event // Append-only sequence of events (modulo discards).\n\tmaxEvents int\n\trecycler  func(interface{})\n\tIsError   bool          // Whether this trace resulted in an error.\n\tElapsed   time.Duration // Elapsed time for this trace, zero while active.\n\ttraceID   uint64        // Trace information if non-zero.\n\tspanID    uint64\n\n\trefs int32     // how many buckets this is in\n\tdisc discarded // scratch space to avoid allocation\n\n\tfinishStack []byte // where finish was called, if DebugUseAfterFinish is set\n\n\teventsBuf [4]event // preallocated buffer in case we only log a few events\n}\n\nfunc (tr *trace) reset() {\n\t// Clear all but the mutex. Mutexes may not be copied, even when unlocked.\n\ttr.Family = \"\"\n\ttr.Title = \"\"\n\ttr.Start = time.Time{}\n\n\ttr.mu.Lock()\n\ttr.Elapsed = 0\n\ttr.traceID = 0\n\ttr.spanID = 0\n\ttr.IsError = false\n\ttr.maxEvents = 0\n\ttr.events = nil\n\ttr.recycler = nil\n\ttr.mu.Unlock()\n\n\ttr.refs = 0\n\ttr.disc = 0\n\ttr.finishStack = nil\n\tfor i := range tr.eventsBuf {\n\t\ttr.eventsBuf[i] = event{}\n\t}\n}\n\n// delta returns the elapsed time since the last event or the trace start,\n// and whether it spans midnight.\n// L >= tr.mu\nfunc (tr *trace) delta(t time.Time) (time.Duration, bool) {\n\tif len(tr.events) == 0 {\n\t\treturn t.Sub(tr.Start), false\n\t}\n\tprev := tr.events[len(tr.events)-1].When\n\treturn t.Sub(prev), prev.Day() != t.Day()\n}\n\nfunc (tr *trace) addEvent(x interface{}, recyclable, sensitive bool) {\n\tif DebugUseAfterFinish && tr.finishStack != nil {\n\t\tbuf := make([]byte, 4<<10) // 4 KB should be enough\n\t\tn := runtime.Stack(buf, false)\n\t\tlog.Printf(\"net/trace: trace used after finish:\\nFinished at:\\n%s\\nUsed at:\\n%s\", tr.finishStack, buf[:n])\n\t}\n\n\t/*\n\t\tNOTE TO DEBUGGERS\n\n\t\tIf you are here because your program panicked in this code,\n\t\tit is almost definitely the fault of code using this package,\n\t\tand very unlikely to be the fault of this code.\n\n\t\tThe most likely scenario is that some code elsewhere is using\n\t\ta trace.Trace after its Finish method is called.\n\t\tYou can temporarily set the DebugUseAfterFinish var\n\t\tto help discover where that is; do not leave that var set,\n\t\tsince it makes this package much less efficient.\n\t*/\n\n\te := event{When: time.Now(), What: x, Recyclable: recyclable, Sensitive: sensitive}\n\ttr.mu.Lock()\n\te.Elapsed, e.NewDay = tr.delta(e.When)\n\tif len(tr.events) < tr.maxEvents {\n\t\ttr.events = append(tr.events, e)\n\t} else {\n\t\t// Discard the middle events.\n\t\tdi := int((tr.maxEvents - 1) / 2)\n\t\tif d, ok := tr.events[di].What.(*discarded); ok {\n\t\t\t(*d)++\n\t\t} else {\n\t\t\t// disc starts at two to count for the event it is replacing,\n\t\t\t// plus the next one that we are about to drop.\n\t\t\ttr.disc = 2\n\t\t\tif tr.recycler != nil && tr.events[di].Recyclable {\n\t\t\t\tgo tr.recycler(tr.events[di].What)\n\t\t\t}\n\t\t\ttr.events[di].What = &tr.disc\n\t\t}\n\t\t// The timestamp of the discarded meta-event should be\n\t\t// the time of the last event it is representing.\n\t\ttr.events[di].When = tr.events[di+1].When\n\n\t\tif tr.recycler != nil && tr.events[di+1].Recyclable {\n\t\t\tgo tr.recycler(tr.events[di+1].What)\n\t\t}\n\t\tcopy(tr.events[di+1:], tr.events[di+2:])\n\t\ttr.events[tr.maxEvents-1] = e\n\t}\n\ttr.mu.Unlock()\n}\n\nfunc (tr *trace) LazyLog(x fmt.Stringer, sensitive bool) {\n\ttr.addEvent(x, true, sensitive)\n}\n\nfunc (tr *trace) LazyPrintf(format string, a ...interface{}) {\n\ttr.addEvent(&lazySprintf{format, a}, false, false)\n}\n\nfunc (tr *trace) SetError() {\n\ttr.mu.Lock()\n\ttr.IsError = true\n\ttr.mu.Unlock()\n}\n\nfunc (tr *trace) SetRecycler(f func(interface{})) {\n\ttr.mu.Lock()\n\ttr.recycler = f\n\ttr.mu.Unlock()\n}\n\nfunc (tr *trace) SetTraceInfo(traceID, spanID uint64) {\n\ttr.mu.Lock()\n\ttr.traceID, tr.spanID = traceID, spanID\n\ttr.mu.Unlock()\n}\n\nfunc (tr *trace) SetMaxEvents(m int) {\n\ttr.mu.Lock()\n\t// Always keep at least three events: first, discarded count, last.\n\tif len(tr.events) == 0 && m > 3 {\n\t\ttr.maxEvents = m\n\t}\n\ttr.mu.Unlock()\n}\n\nfunc (tr *trace) ref() {\n\tatomic.AddInt32(&tr.refs, 1)\n}\n\nfunc (tr *trace) unref() {\n\tif atomic.AddInt32(&tr.refs, -1) == 0 {\n\t\ttr.mu.RLock()\n\t\tif tr.recycler != nil {\n\t\t\t// freeTrace clears tr, so we hold tr.recycler and tr.events here.\n\t\t\tgo func(f func(interface{}), es []event) {\n\t\t\t\tfor _, e := range es {\n\t\t\t\t\tif e.Recyclable {\n\t\t\t\t\t\tf(e.What)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}(tr.recycler, tr.events)\n\t\t}\n\t\ttr.mu.RUnlock()\n\n\t\tfreeTrace(tr)\n\t}\n}\n\nfunc (tr *trace) When() string {\n\treturn tr.Start.Format(\"2006/01/02 15:04:05.000000\")\n}\n\nfunc (tr *trace) ElapsedTime() string {\n\ttr.mu.RLock()\n\tt := tr.Elapsed\n\ttr.mu.RUnlock()\n\n\tif t == 0 {\n\t\t// Active trace.\n\t\tt = time.Since(tr.Start)\n\t}\n\treturn fmt.Sprintf(\"%.6f\", t.Seconds())\n}\n\nfunc (tr *trace) Events() []event {\n\ttr.mu.RLock()\n\tdefer tr.mu.RUnlock()\n\treturn tr.events\n}\n\nvar traceFreeList = make(chan *trace, 1000) // TODO(dsymonds): Use sync.Pool?\n\n// newTrace returns a trace ready to use.\nfunc newTrace() *trace {\n\tselect {\n\tcase tr := <-traceFreeList:\n\t\treturn tr\n\tdefault:\n\t\treturn new(trace)\n\t}\n}\n\n// freeTrace adds tr to traceFreeList if there's room.\n// This is non-blocking.\nfunc freeTrace(tr *trace) {\n\tif DebugUseAfterFinish {\n\t\treturn // never reuse\n\t}\n\ttr.reset()\n\tselect {\n\tcase traceFreeList <- tr:\n\tdefault:\n\t}\n}\n\nfunc elapsed(d time.Duration) string {\n\tb := []byte(fmt.Sprintf(\"%.6f\", d.Seconds()))\n\n\t// For subsecond durations, blank all zeros before decimal point,\n\t// and all zeros between the decimal point and the first non-zero digit.\n\tif d < time.Second {\n\t\tdot := bytes.IndexByte(b, '.')\n\t\tfor i := 0; i < dot; i++ {\n\t\t\tb[i] = ' '\n\t\t}\n\t\tfor i := dot + 1; i < len(b); i++ {\n\t\t\tif b[i] == '0' {\n\t\t\t\tb[i] = ' '\n\t\t\t} else {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\treturn string(b)\n}\n\nvar pageTmplCache *template.Template\nvar pageTmplOnce sync.Once\n\nfunc pageTmpl() *template.Template {\n\tpageTmplOnce.Do(func() {\n\t\tpageTmplCache = template.Must(template.New(\"Page\").Funcs(template.FuncMap{\n\t\t\t\"elapsed\": elapsed,\n\t\t\t\"add\":     func(a, b int) int { return a + b },\n\t\t}).Parse(pageHTML))\n\t})\n\treturn pageTmplCache\n}\n\nconst pageHTML = `\n{{template \"Prolog\" .}}\n{{template \"StatusTable\" .}}\n{{template \"Epilog\" .}}\n\n{{define \"Prolog\"}}\n<html>\n\t<head>\n\t<title>/debug/requests</title>\n\t<style type=\"text/css\">\n\t\tbody {\n\t\t\tfont-family: sans-serif;\n\t\t}\n\t\ttable#tr-status td.family {\n\t\t\tpadding-right: 2em;\n\t\t}\n\t\ttable#tr-status td.active {\n\t\t\tpadding-right: 1em;\n\t\t}\n\t\ttable#tr-status td.latency-first {\n\t\t\tpadding-left: 1em;\n\t\t}\n\t\ttable#tr-status td.empty {\n\t\t\tcolor: #aaa;\n\t\t}\n\t\ttable#reqs {\n\t\t\tmargin-top: 1em;\n\t\t}\n\t\ttable#reqs tr.first {\n\t\t\t{{if $.Expanded}}font-weight: bold;{{end}}\n\t\t}\n\t\ttable#reqs td {\n\t\t\tfont-family: monospace;\n\t\t}\n\t\ttable#reqs td.when {\n\t\t\ttext-align: right;\n\t\t\twhite-space: nowrap;\n\t\t}\n\t\ttable#reqs td.elapsed {\n\t\t\tpadding: 0 0.5em;\n\t\t\ttext-align: right;\n\t\t\twhite-space: pre;\n\t\t\twidth: 10em;\n\t\t}\n\t\taddress {\n\t\t\tfont-size: smaller;\n\t\t\tmargin-top: 5em;\n\t\t}\n\t</style>\n\t</head>\n\t<body>\n\n<h1>/debug/requests</h1>\n{{end}} {{/* end of Prolog */}}\n\n{{define \"StatusTable\"}}\n<table id=\"tr-status\">\n\t{{range $fam := .Families}}\n\t<tr>\n\t\t<td class=\"family\">{{$fam}}</td>\n\n\t\t{{$n := index $.ActiveTraceCount $fam}}\n\t\t<td class=\"active {{if not $n}}empty{{end}}\">\n\t\t\t{{if $n}}<a href=\"?fam={{$fam}}&b=-1{{if $.Expanded}}&exp=1{{end}}\">{{end}}\n\t\t\t[{{$n}} active]\n\t\t\t{{if $n}}</a>{{end}}\n\t\t</td>\n\n\t\t{{$f := index $.CompletedTraces $fam}}\n\t\t{{range $i, $b := $f.Buckets}}\n\t\t{{$empty := $b.Empty}}\n\t\t<td {{if $empty}}class=\"empty\"{{end}}>\n\t\t{{if not $empty}}<a href=\"?fam={{$fam}}&b={{$i}}{{if $.Expanded}}&exp=1{{end}}\">{{end}}\n\t\t[{{.Cond}}]\n\t\t{{if not $empty}}</a>{{end}}\n\t\t</td>\n\t\t{{end}}\n\n\t\t{{$nb := len $f.Buckets}}\n\t\t<td class=\"latency-first\">\n\t\t<a href=\"?fam={{$fam}}&b={{$nb}}\">[minute]</a>\n\t\t</td>\n\t\t<td>\n\t\t<a href=\"?fam={{$fam}}&b={{add $nb 1}}\">[hour]</a>\n\t\t</td>\n\t\t<td>\n\t\t<a href=\"?fam={{$fam}}&b={{add $nb 2}}\">[total]</a>\n\t\t</td>\n\n\t</tr>\n\t{{end}}\n</table>\n{{end}} {{/* end of StatusTable */}}\n\n{{define \"Epilog\"}}\n{{if $.Traces}}\n<hr />\n<h3>Family: {{$.Family}}</h3>\n\n{{if or $.Expanded $.Traced}}\n  <a href=\"?fam={{$.Family}}&b={{$.Bucket}}\">[Normal/Summary]</a>\n{{else}}\n  [Normal/Summary]\n{{end}}\n\n{{if or (not $.Expanded) $.Traced}}\n  <a href=\"?fam={{$.Family}}&b={{$.Bucket}}&exp=1\">[Normal/Expanded]</a>\n{{else}}\n  [Normal/Expanded]\n{{end}}\n\n{{if not $.Active}}\n\t{{if or $.Expanded (not $.Traced)}}\n\t<a href=\"?fam={{$.Family}}&b={{$.Bucket}}&rtraced=1\">[Traced/Summary]</a>\n\t{{else}}\n\t[Traced/Summary]\n\t{{end}}\n\t{{if or (not $.Expanded) (not $.Traced)}}\n\t<a href=\"?fam={{$.Family}}&b={{$.Bucket}}&exp=1&rtraced=1\">[Traced/Expanded]</a>\n        {{else}}\n\t[Traced/Expanded]\n\t{{end}}\n{{end}}\n\n{{if $.Total}}\n<p><em>Showing <b>{{len $.Traces}}</b> of <b>{{$.Total}}</b> traces.</em></p>\n{{end}}\n\n<table id=\"reqs\">\n\t<caption>\n\t\t{{if $.Active}}Active{{else}}Completed{{end}} Requests\n\t</caption>\n\t<tr><th>When</th><th>Elapsed&nbsp;(s)</th></tr>\n\t{{range $tr := $.Traces}}\n\t<tr class=\"first\">\n\t\t<td class=\"when\">{{$tr.When}}</td>\n\t\t<td class=\"elapsed\">{{$tr.ElapsedTime}}</td>\n\t\t<td>{{$tr.Title}}</td>\n\t\t{{/* TODO: include traceID/spanID */}}\n\t</tr>\n\t{{if $.Expanded}}\n\t{{range $tr.Events}}\n\t<tr>\n\t\t<td class=\"when\">{{.WhenString}}</td>\n\t\t<td class=\"elapsed\">{{elapsed .Elapsed}}</td>\n\t\t<td>{{if or $.ShowSensitive (not .Sensitive)}}... {{.What}}{{else}}<em>[redacted]</em>{{end}}</td>\n\t</tr>\n\t{{end}}\n\t{{end}}\n\t{{end}}\n</table>\n{{end}} {{/* if $.Traces */}}\n\n{{if $.Histogram}}\n<h4>Latency (&micro;s) of {{$.Family}} over {{$.HistogramWindow}}</h4>\n{{$.Histogram}}\n{{end}} {{/* if $.Histogram */}}\n\n\t</body>\n</html>\n{{end}} {{/* end of Epilog */}}\n`\n"
  },
  {
    "path": "vendor/golang.org/x/net/websocket/client.go",
    "content": "// Copyright 2009 The Go 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 websocket\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"time\"\n)\n\n// DialError is an error that occurs while dialling a websocket server.\ntype DialError struct {\n\t*Config\n\tErr error\n}\n\nfunc (e *DialError) Error() string {\n\treturn \"websocket.Dial \" + e.Config.Location.String() + \": \" + e.Err.Error()\n}\n\n// NewConfig creates a new WebSocket config for client connection.\nfunc NewConfig(server, origin string) (config *Config, err error) {\n\tconfig = new(Config)\n\tconfig.Version = ProtocolVersionHybi13\n\tconfig.Location, err = url.ParseRequestURI(server)\n\tif err != nil {\n\t\treturn\n\t}\n\tconfig.Origin, err = url.ParseRequestURI(origin)\n\tif err != nil {\n\t\treturn\n\t}\n\tconfig.Header = http.Header(make(map[string][]string))\n\treturn\n}\n\n// NewClient creates a new WebSocket client connection over rwc.\nfunc NewClient(config *Config, rwc io.ReadWriteCloser) (ws *Conn, err error) {\n\tbr := bufio.NewReader(rwc)\n\tbw := bufio.NewWriter(rwc)\n\terr = hybiClientHandshake(config, br, bw)\n\tif err != nil {\n\t\treturn\n\t}\n\tbuf := bufio.NewReadWriter(br, bw)\n\tws = newHybiClientConn(config, buf, rwc)\n\treturn\n}\n\n// Dial opens a new client connection to a WebSocket.\nfunc Dial(url_, protocol, origin string) (ws *Conn, err error) {\n\tconfig, err := NewConfig(url_, origin)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif protocol != \"\" {\n\t\tconfig.Protocol = []string{protocol}\n\t}\n\treturn DialConfig(config)\n}\n\nvar portMap = map[string]string{\n\t\"ws\":  \"80\",\n\t\"wss\": \"443\",\n}\n\nfunc parseAuthority(location *url.URL) string {\n\tif _, ok := portMap[location.Scheme]; ok {\n\t\tif _, _, err := net.SplitHostPort(location.Host); err != nil {\n\t\t\treturn net.JoinHostPort(location.Host, portMap[location.Scheme])\n\t\t}\n\t}\n\treturn location.Host\n}\n\n// DialConfig opens a new client connection to a WebSocket with a config.\nfunc DialConfig(config *Config) (ws *Conn, err error) {\n\treturn config.DialContext(context.Background())\n}\n\n// DialContext opens a new client connection to a WebSocket, with context support for timeouts/cancellation.\nfunc (config *Config) DialContext(ctx context.Context) (*Conn, error) {\n\tif config.Location == nil {\n\t\treturn nil, &DialError{config, ErrBadWebSocketLocation}\n\t}\n\tif config.Origin == nil {\n\t\treturn nil, &DialError{config, ErrBadWebSocketOrigin}\n\t}\n\n\tdialer := config.Dialer\n\tif dialer == nil {\n\t\tdialer = &net.Dialer{}\n\t}\n\n\tclient, err := dialWithDialer(ctx, dialer, config)\n\tif err != nil {\n\t\treturn nil, &DialError{config, err}\n\t}\n\n\t// Cleanup the connection if we fail to create the websocket successfully\n\tsuccess := false\n\tdefer func() {\n\t\tif !success {\n\t\t\t_ = client.Close()\n\t\t}\n\t}()\n\n\tvar ws *Conn\n\tvar wsErr error\n\tdoneConnecting := make(chan struct{})\n\tgo func() {\n\t\tdefer close(doneConnecting)\n\t\tws, err = NewClient(config, client)\n\t\tif err != nil {\n\t\t\twsErr = &DialError{config, err}\n\t\t}\n\t}()\n\n\t// The websocket.NewClient() function can block indefinitely, make sure that we\n\t// respect the deadlines specified by the context.\n\tselect {\n\tcase <-ctx.Done():\n\t\t// Force the pending operations to fail, terminating the pending connection attempt\n\t\t_ = client.SetDeadline(time.Now())\n\t\t<-doneConnecting // Wait for the goroutine that tries to establish the connection to finish\n\t\treturn nil, &DialError{config, ctx.Err()}\n\tcase <-doneConnecting:\n\t\tif wsErr == nil {\n\t\t\tsuccess = true // Disarm the deferred connection cleanup\n\t\t}\n\t\treturn ws, wsErr\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/websocket/dial.go",
    "content": "// Copyright 2015 The Go 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 websocket\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"net\"\n)\n\nfunc dialWithDialer(ctx context.Context, dialer *net.Dialer, config *Config) (conn net.Conn, err error) {\n\tswitch config.Location.Scheme {\n\tcase \"ws\":\n\t\tconn, err = dialer.DialContext(ctx, \"tcp\", parseAuthority(config.Location))\n\n\tcase \"wss\":\n\t\ttlsDialer := &tls.Dialer{\n\t\t\tNetDialer: dialer,\n\t\t\tConfig:    config.TlsConfig,\n\t\t}\n\n\t\tconn, err = tlsDialer.DialContext(ctx, \"tcp\", parseAuthority(config.Location))\n\tdefault:\n\t\terr = ErrBadScheme\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/websocket/hybi.go",
    "content": "// Copyright 2011 The Go 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 websocket\n\n// This file implements a protocol of hybi draft.\n// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"crypto/rand\"\n\t\"crypto/sha1\"\n\t\"encoding/base64\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\nconst (\n\twebsocketGUID = \"258EAFA5-E914-47DA-95CA-C5AB0DC85B11\"\n\n\tcloseStatusNormal            = 1000\n\tcloseStatusGoingAway         = 1001\n\tcloseStatusProtocolError     = 1002\n\tcloseStatusUnsupportedData   = 1003\n\tcloseStatusFrameTooLarge     = 1004\n\tcloseStatusNoStatusRcvd      = 1005\n\tcloseStatusAbnormalClosure   = 1006\n\tcloseStatusBadMessageData    = 1007\n\tcloseStatusPolicyViolation   = 1008\n\tcloseStatusTooBigData        = 1009\n\tcloseStatusExtensionMismatch = 1010\n\n\tmaxControlFramePayloadLength = 125\n)\n\nvar (\n\tErrBadMaskingKey         = &ProtocolError{\"bad masking key\"}\n\tErrBadPongMessage        = &ProtocolError{\"bad pong message\"}\n\tErrBadClosingStatus      = &ProtocolError{\"bad closing status\"}\n\tErrUnsupportedExtensions = &ProtocolError{\"unsupported extensions\"}\n\tErrNotImplemented        = &ProtocolError{\"not implemented\"}\n\n\thandshakeHeader = map[string]bool{\n\t\t\"Host\":                   true,\n\t\t\"Upgrade\":                true,\n\t\t\"Connection\":             true,\n\t\t\"Sec-Websocket-Key\":      true,\n\t\t\"Sec-Websocket-Origin\":   true,\n\t\t\"Sec-Websocket-Version\":  true,\n\t\t\"Sec-Websocket-Protocol\": true,\n\t\t\"Sec-Websocket-Accept\":   true,\n\t}\n)\n\n// A hybiFrameHeader is a frame header as defined in hybi draft.\ntype hybiFrameHeader struct {\n\tFin        bool\n\tRsv        [3]bool\n\tOpCode     byte\n\tLength     int64\n\tMaskingKey []byte\n\n\tdata *bytes.Buffer\n}\n\n// A hybiFrameReader is a reader for hybi frame.\ntype hybiFrameReader struct {\n\treader io.Reader\n\n\theader hybiFrameHeader\n\tpos    int64\n\tlength int\n}\n\nfunc (frame *hybiFrameReader) Read(msg []byte) (n int, err error) {\n\tn, err = frame.reader.Read(msg)\n\tif frame.header.MaskingKey != nil {\n\t\tfor i := 0; i < n; i++ {\n\t\t\tmsg[i] = msg[i] ^ frame.header.MaskingKey[frame.pos%4]\n\t\t\tframe.pos++\n\t\t}\n\t}\n\treturn n, err\n}\n\nfunc (frame *hybiFrameReader) PayloadType() byte { return frame.header.OpCode }\n\nfunc (frame *hybiFrameReader) HeaderReader() io.Reader {\n\tif frame.header.data == nil {\n\t\treturn nil\n\t}\n\tif frame.header.data.Len() == 0 {\n\t\treturn nil\n\t}\n\treturn frame.header.data\n}\n\nfunc (frame *hybiFrameReader) TrailerReader() io.Reader { return nil }\n\nfunc (frame *hybiFrameReader) Len() (n int) { return frame.length }\n\n// A hybiFrameReaderFactory creates new frame reader based on its frame type.\ntype hybiFrameReaderFactory struct {\n\t*bufio.Reader\n}\n\n// NewFrameReader reads a frame header from the connection, and creates new reader for the frame.\n// See Section 5.2 Base Framing protocol for detail.\n// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17#section-5.2\nfunc (buf hybiFrameReaderFactory) NewFrameReader() (frame frameReader, err error) {\n\thybiFrame := new(hybiFrameReader)\n\tframe = hybiFrame\n\tvar header []byte\n\tvar b byte\n\t// First byte. FIN/RSV1/RSV2/RSV3/OpCode(4bits)\n\tb, err = buf.ReadByte()\n\tif err != nil {\n\t\treturn\n\t}\n\theader = append(header, b)\n\thybiFrame.header.Fin = ((header[0] >> 7) & 1) != 0\n\tfor i := 0; i < 3; i++ {\n\t\tj := uint(6 - i)\n\t\thybiFrame.header.Rsv[i] = ((header[0] >> j) & 1) != 0\n\t}\n\thybiFrame.header.OpCode = header[0] & 0x0f\n\n\t// Second byte. Mask/Payload len(7bits)\n\tb, err = buf.ReadByte()\n\tif err != nil {\n\t\treturn\n\t}\n\theader = append(header, b)\n\tmask := (b & 0x80) != 0\n\tb &= 0x7f\n\tlengthFields := 0\n\tswitch {\n\tcase b <= 125: // Payload length 7bits.\n\t\thybiFrame.header.Length = int64(b)\n\tcase b == 126: // Payload length 7+16bits\n\t\tlengthFields = 2\n\tcase b == 127: // Payload length 7+64bits\n\t\tlengthFields = 8\n\t}\n\tfor i := 0; i < lengthFields; i++ {\n\t\tb, err = buf.ReadByte()\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tif lengthFields == 8 && i == 0 { // MSB must be zero when 7+64 bits\n\t\t\tb &= 0x7f\n\t\t}\n\t\theader = append(header, b)\n\t\thybiFrame.header.Length = hybiFrame.header.Length*256 + int64(b)\n\t}\n\tif mask {\n\t\t// Masking key. 4 bytes.\n\t\tfor i := 0; i < 4; i++ {\n\t\t\tb, err = buf.ReadByte()\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\theader = append(header, b)\n\t\t\thybiFrame.header.MaskingKey = append(hybiFrame.header.MaskingKey, b)\n\t\t}\n\t}\n\thybiFrame.reader = io.LimitReader(buf.Reader, hybiFrame.header.Length)\n\thybiFrame.header.data = bytes.NewBuffer(header)\n\thybiFrame.length = len(header) + int(hybiFrame.header.Length)\n\treturn\n}\n\n// A HybiFrameWriter is a writer for hybi frame.\ntype hybiFrameWriter struct {\n\twriter *bufio.Writer\n\n\theader *hybiFrameHeader\n}\n\nfunc (frame *hybiFrameWriter) Write(msg []byte) (n int, err error) {\n\tvar header []byte\n\tvar b byte\n\tif frame.header.Fin {\n\t\tb |= 0x80\n\t}\n\tfor i := 0; i < 3; i++ {\n\t\tif frame.header.Rsv[i] {\n\t\t\tj := uint(6 - i)\n\t\t\tb |= 1 << j\n\t\t}\n\t}\n\tb |= frame.header.OpCode\n\theader = append(header, b)\n\tif frame.header.MaskingKey != nil {\n\t\tb = 0x80\n\t} else {\n\t\tb = 0\n\t}\n\tlengthFields := 0\n\tlength := len(msg)\n\tswitch {\n\tcase length <= 125:\n\t\tb |= byte(length)\n\tcase length < 65536:\n\t\tb |= 126\n\t\tlengthFields = 2\n\tdefault:\n\t\tb |= 127\n\t\tlengthFields = 8\n\t}\n\theader = append(header, b)\n\tfor i := 0; i < lengthFields; i++ {\n\t\tj := uint((lengthFields - i - 1) * 8)\n\t\tb = byte((length >> j) & 0xff)\n\t\theader = append(header, b)\n\t}\n\tif frame.header.MaskingKey != nil {\n\t\tif len(frame.header.MaskingKey) != 4 {\n\t\t\treturn 0, ErrBadMaskingKey\n\t\t}\n\t\theader = append(header, frame.header.MaskingKey...)\n\t\tframe.writer.Write(header)\n\t\tdata := make([]byte, length)\n\t\tfor i := range data {\n\t\t\tdata[i] = msg[i] ^ frame.header.MaskingKey[i%4]\n\t\t}\n\t\tframe.writer.Write(data)\n\t\terr = frame.writer.Flush()\n\t\treturn length, err\n\t}\n\tframe.writer.Write(header)\n\tframe.writer.Write(msg)\n\terr = frame.writer.Flush()\n\treturn length, err\n}\n\nfunc (frame *hybiFrameWriter) Close() error { return nil }\n\ntype hybiFrameWriterFactory struct {\n\t*bufio.Writer\n\tneedMaskingKey bool\n}\n\nfunc (buf hybiFrameWriterFactory) NewFrameWriter(payloadType byte) (frame frameWriter, err error) {\n\tframeHeader := &hybiFrameHeader{Fin: true, OpCode: payloadType}\n\tif buf.needMaskingKey {\n\t\tframeHeader.MaskingKey, err = generateMaskingKey()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn &hybiFrameWriter{writer: buf.Writer, header: frameHeader}, nil\n}\n\ntype hybiFrameHandler struct {\n\tconn        *Conn\n\tpayloadType byte\n}\n\nfunc (handler *hybiFrameHandler) HandleFrame(frame frameReader) (frameReader, error) {\n\tif handler.conn.IsServerConn() {\n\t\t// The client MUST mask all frames sent to the server.\n\t\tif frame.(*hybiFrameReader).header.MaskingKey == nil {\n\t\t\thandler.WriteClose(closeStatusProtocolError)\n\t\t\treturn nil, io.EOF\n\t\t}\n\t} else {\n\t\t// The server MUST NOT mask all frames.\n\t\tif frame.(*hybiFrameReader).header.MaskingKey != nil {\n\t\t\thandler.WriteClose(closeStatusProtocolError)\n\t\t\treturn nil, io.EOF\n\t\t}\n\t}\n\tif header := frame.HeaderReader(); header != nil {\n\t\tio.Copy(io.Discard, header)\n\t}\n\tswitch frame.PayloadType() {\n\tcase ContinuationFrame:\n\t\tframe.(*hybiFrameReader).header.OpCode = handler.payloadType\n\tcase TextFrame, BinaryFrame:\n\t\thandler.payloadType = frame.PayloadType()\n\tcase CloseFrame:\n\t\treturn nil, io.EOF\n\tcase PingFrame, PongFrame:\n\t\tb := make([]byte, maxControlFramePayloadLength)\n\t\tn, err := io.ReadFull(frame, b)\n\t\tif err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {\n\t\t\treturn nil, err\n\t\t}\n\t\tio.Copy(io.Discard, frame)\n\t\tif frame.PayloadType() == PingFrame {\n\t\t\tif _, err := handler.WritePong(b[:n]); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\treturn nil, nil\n\t}\n\treturn frame, nil\n}\n\nfunc (handler *hybiFrameHandler) WriteClose(status int) (err error) {\n\thandler.conn.wio.Lock()\n\tdefer handler.conn.wio.Unlock()\n\tw, err := handler.conn.frameWriterFactory.NewFrameWriter(CloseFrame)\n\tif err != nil {\n\t\treturn err\n\t}\n\tmsg := make([]byte, 2)\n\tbinary.BigEndian.PutUint16(msg, uint16(status))\n\t_, err = w.Write(msg)\n\tw.Close()\n\treturn err\n}\n\nfunc (handler *hybiFrameHandler) WritePong(msg []byte) (n int, err error) {\n\thandler.conn.wio.Lock()\n\tdefer handler.conn.wio.Unlock()\n\tw, err := handler.conn.frameWriterFactory.NewFrameWriter(PongFrame)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tn, err = w.Write(msg)\n\tw.Close()\n\treturn n, err\n}\n\n// newHybiConn creates a new WebSocket connection speaking hybi draft protocol.\nfunc newHybiConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn {\n\tif buf == nil {\n\t\tbr := bufio.NewReader(rwc)\n\t\tbw := bufio.NewWriter(rwc)\n\t\tbuf = bufio.NewReadWriter(br, bw)\n\t}\n\tws := &Conn{config: config, request: request, buf: buf, rwc: rwc,\n\t\tframeReaderFactory: hybiFrameReaderFactory{buf.Reader},\n\t\tframeWriterFactory: hybiFrameWriterFactory{\n\t\t\tbuf.Writer, request == nil},\n\t\tPayloadType:        TextFrame,\n\t\tdefaultCloseStatus: closeStatusNormal}\n\tws.frameHandler = &hybiFrameHandler{conn: ws}\n\treturn ws\n}\n\n// generateMaskingKey generates a masking key for a frame.\nfunc generateMaskingKey() (maskingKey []byte, err error) {\n\tmaskingKey = make([]byte, 4)\n\tif _, err = io.ReadFull(rand.Reader, maskingKey); err != nil {\n\t\treturn\n\t}\n\treturn\n}\n\n// generateNonce generates a nonce consisting of a randomly selected 16-byte\n// value that has been base64-encoded.\nfunc generateNonce() (nonce []byte) {\n\tkey := make([]byte, 16)\n\tif _, err := io.ReadFull(rand.Reader, key); err != nil {\n\t\tpanic(err)\n\t}\n\tnonce = make([]byte, 24)\n\tbase64.StdEncoding.Encode(nonce, key)\n\treturn\n}\n\n// removeZone removes IPv6 zone identifier from host.\n// E.g., \"[fe80::1%en0]:8080\" to \"[fe80::1]:8080\"\nfunc removeZone(host string) string {\n\tif !strings.HasPrefix(host, \"[\") {\n\t\treturn host\n\t}\n\ti := strings.LastIndex(host, \"]\")\n\tif i < 0 {\n\t\treturn host\n\t}\n\tj := strings.LastIndex(host[:i], \"%\")\n\tif j < 0 {\n\t\treturn host\n\t}\n\treturn host[:j] + host[i:]\n}\n\n// getNonceAccept computes the base64-encoded SHA-1 of the concatenation of\n// the nonce (\"Sec-WebSocket-Key\" value) with the websocket GUID string.\nfunc getNonceAccept(nonce []byte) (expected []byte, err error) {\n\th := sha1.New()\n\tif _, err = h.Write(nonce); err != nil {\n\t\treturn\n\t}\n\tif _, err = h.Write([]byte(websocketGUID)); err != nil {\n\t\treturn\n\t}\n\texpected = make([]byte, 28)\n\tbase64.StdEncoding.Encode(expected, h.Sum(nil))\n\treturn\n}\n\n// Client handshake described in draft-ietf-hybi-thewebsocket-protocol-17\nfunc hybiClientHandshake(config *Config, br *bufio.Reader, bw *bufio.Writer) (err error) {\n\tbw.WriteString(\"GET \" + config.Location.RequestURI() + \" HTTP/1.1\\r\\n\")\n\n\t// According to RFC 6874, an HTTP client, proxy, or other\n\t// intermediary must remove any IPv6 zone identifier attached\n\t// to an outgoing URI.\n\tbw.WriteString(\"Host: \" + removeZone(config.Location.Host) + \"\\r\\n\")\n\tbw.WriteString(\"Upgrade: websocket\\r\\n\")\n\tbw.WriteString(\"Connection: Upgrade\\r\\n\")\n\tnonce := generateNonce()\n\tif config.handshakeData != nil {\n\t\tnonce = []byte(config.handshakeData[\"key\"])\n\t}\n\tbw.WriteString(\"Sec-WebSocket-Key: \" + string(nonce) + \"\\r\\n\")\n\tbw.WriteString(\"Origin: \" + strings.ToLower(config.Origin.String()) + \"\\r\\n\")\n\n\tif config.Version != ProtocolVersionHybi13 {\n\t\treturn ErrBadProtocolVersion\n\t}\n\n\tbw.WriteString(\"Sec-WebSocket-Version: \" + fmt.Sprintf(\"%d\", config.Version) + \"\\r\\n\")\n\tif len(config.Protocol) > 0 {\n\t\tbw.WriteString(\"Sec-WebSocket-Protocol: \" + strings.Join(config.Protocol, \", \") + \"\\r\\n\")\n\t}\n\t// TODO(ukai): send Sec-WebSocket-Extensions.\n\terr = config.Header.WriteSubset(bw, handshakeHeader)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbw.WriteString(\"\\r\\n\")\n\tif err = bw.Flush(); err != nil {\n\t\treturn err\n\t}\n\n\tresp, err := http.ReadResponse(br, &http.Request{Method: \"GET\"})\n\tif err != nil {\n\t\treturn err\n\t}\n\tif resp.StatusCode != 101 {\n\t\treturn ErrBadStatus\n\t}\n\tif strings.ToLower(resp.Header.Get(\"Upgrade\")) != \"websocket\" ||\n\t\tstrings.ToLower(resp.Header.Get(\"Connection\")) != \"upgrade\" {\n\t\treturn ErrBadUpgrade\n\t}\n\texpectedAccept, err := getNonceAccept(nonce)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif resp.Header.Get(\"Sec-WebSocket-Accept\") != string(expectedAccept) {\n\t\treturn ErrChallengeResponse\n\t}\n\tif resp.Header.Get(\"Sec-WebSocket-Extensions\") != \"\" {\n\t\treturn ErrUnsupportedExtensions\n\t}\n\tofferedProtocol := resp.Header.Get(\"Sec-WebSocket-Protocol\")\n\tif offeredProtocol != \"\" {\n\t\tprotocolMatched := false\n\t\tfor i := 0; i < len(config.Protocol); i++ {\n\t\t\tif config.Protocol[i] == offeredProtocol {\n\t\t\t\tprotocolMatched = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !protocolMatched {\n\t\t\treturn ErrBadWebSocketProtocol\n\t\t}\n\t\tconfig.Protocol = []string{offeredProtocol}\n\t}\n\n\treturn nil\n}\n\n// newHybiClientConn creates a client WebSocket connection after handshake.\nfunc newHybiClientConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser) *Conn {\n\treturn newHybiConn(config, buf, rwc, nil)\n}\n\n// A HybiServerHandshaker performs a server handshake using hybi draft protocol.\ntype hybiServerHandshaker struct {\n\t*Config\n\taccept []byte\n}\n\nfunc (c *hybiServerHandshaker) ReadHandshake(buf *bufio.Reader, req *http.Request) (code int, err error) {\n\tc.Version = ProtocolVersionHybi13\n\tif req.Method != \"GET\" {\n\t\treturn http.StatusMethodNotAllowed, ErrBadRequestMethod\n\t}\n\t// HTTP version can be safely ignored.\n\n\tif strings.ToLower(req.Header.Get(\"Upgrade\")) != \"websocket\" ||\n\t\t!strings.Contains(strings.ToLower(req.Header.Get(\"Connection\")), \"upgrade\") {\n\t\treturn http.StatusBadRequest, ErrNotWebSocket\n\t}\n\n\tkey := req.Header.Get(\"Sec-Websocket-Key\")\n\tif key == \"\" {\n\t\treturn http.StatusBadRequest, ErrChallengeResponse\n\t}\n\tversion := req.Header.Get(\"Sec-Websocket-Version\")\n\tswitch version {\n\tcase \"13\":\n\t\tc.Version = ProtocolVersionHybi13\n\tdefault:\n\t\treturn http.StatusBadRequest, ErrBadWebSocketVersion\n\t}\n\tvar scheme string\n\tif req.TLS != nil {\n\t\tscheme = \"wss\"\n\t} else {\n\t\tscheme = \"ws\"\n\t}\n\tc.Location, err = url.ParseRequestURI(scheme + \"://\" + req.Host + req.URL.RequestURI())\n\tif err != nil {\n\t\treturn http.StatusBadRequest, err\n\t}\n\tprotocol := strings.TrimSpace(req.Header.Get(\"Sec-Websocket-Protocol\"))\n\tif protocol != \"\" {\n\t\tprotocols := strings.Split(protocol, \",\")\n\t\tfor i := 0; i < len(protocols); i++ {\n\t\t\tc.Protocol = append(c.Protocol, strings.TrimSpace(protocols[i]))\n\t\t}\n\t}\n\tc.accept, err = getNonceAccept([]byte(key))\n\tif err != nil {\n\t\treturn http.StatusInternalServerError, err\n\t}\n\treturn http.StatusSwitchingProtocols, nil\n}\n\n// Origin parses the Origin header in req.\n// If the Origin header is not set, it returns nil and nil.\nfunc Origin(config *Config, req *http.Request) (*url.URL, error) {\n\tvar origin string\n\tswitch config.Version {\n\tcase ProtocolVersionHybi13:\n\t\torigin = req.Header.Get(\"Origin\")\n\t}\n\tif origin == \"\" {\n\t\treturn nil, nil\n\t}\n\treturn url.ParseRequestURI(origin)\n}\n\nfunc (c *hybiServerHandshaker) AcceptHandshake(buf *bufio.Writer) (err error) {\n\tif len(c.Protocol) > 0 {\n\t\tif len(c.Protocol) != 1 {\n\t\t\t// You need choose a Protocol in Handshake func in Server.\n\t\t\treturn ErrBadWebSocketProtocol\n\t\t}\n\t}\n\tbuf.WriteString(\"HTTP/1.1 101 Switching Protocols\\r\\n\")\n\tbuf.WriteString(\"Upgrade: websocket\\r\\n\")\n\tbuf.WriteString(\"Connection: Upgrade\\r\\n\")\n\tbuf.WriteString(\"Sec-WebSocket-Accept: \" + string(c.accept) + \"\\r\\n\")\n\tif len(c.Protocol) > 0 {\n\t\tbuf.WriteString(\"Sec-WebSocket-Protocol: \" + c.Protocol[0] + \"\\r\\n\")\n\t}\n\t// TODO(ukai): send Sec-WebSocket-Extensions.\n\tif c.Header != nil {\n\t\terr := c.Header.WriteSubset(buf, handshakeHeader)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tbuf.WriteString(\"\\r\\n\")\n\treturn buf.Flush()\n}\n\nfunc (c *hybiServerHandshaker) NewServerConn(buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn {\n\treturn newHybiServerConn(c.Config, buf, rwc, request)\n}\n\n// newHybiServerConn returns a new WebSocket connection speaking hybi draft protocol.\nfunc newHybiServerConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn {\n\treturn newHybiConn(config, buf, rwc, request)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/websocket/server.go",
    "content": "// Copyright 2009 The Go 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 websocket\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\nfunc newServerConn(rwc io.ReadWriteCloser, buf *bufio.ReadWriter, req *http.Request, config *Config, handshake func(*Config, *http.Request) error) (conn *Conn, err error) {\n\tvar hs serverHandshaker = &hybiServerHandshaker{Config: config}\n\tcode, err := hs.ReadHandshake(buf.Reader, req)\n\tif err == ErrBadWebSocketVersion {\n\t\tfmt.Fprintf(buf, \"HTTP/1.1 %03d %s\\r\\n\", code, http.StatusText(code))\n\t\tfmt.Fprintf(buf, \"Sec-WebSocket-Version: %s\\r\\n\", SupportedProtocolVersion)\n\t\tbuf.WriteString(\"\\r\\n\")\n\t\tbuf.WriteString(err.Error())\n\t\tbuf.Flush()\n\t\treturn\n\t}\n\tif err != nil {\n\t\tfmt.Fprintf(buf, \"HTTP/1.1 %03d %s\\r\\n\", code, http.StatusText(code))\n\t\tbuf.WriteString(\"\\r\\n\")\n\t\tbuf.WriteString(err.Error())\n\t\tbuf.Flush()\n\t\treturn\n\t}\n\tif handshake != nil {\n\t\terr = handshake(config, req)\n\t\tif err != nil {\n\t\t\tcode = http.StatusForbidden\n\t\t\tfmt.Fprintf(buf, \"HTTP/1.1 %03d %s\\r\\n\", code, http.StatusText(code))\n\t\t\tbuf.WriteString(\"\\r\\n\")\n\t\t\tbuf.Flush()\n\t\t\treturn\n\t\t}\n\t}\n\terr = hs.AcceptHandshake(buf.Writer)\n\tif err != nil {\n\t\tcode = http.StatusBadRequest\n\t\tfmt.Fprintf(buf, \"HTTP/1.1 %03d %s\\r\\n\", code, http.StatusText(code))\n\t\tbuf.WriteString(\"\\r\\n\")\n\t\tbuf.Flush()\n\t\treturn\n\t}\n\tconn = hs.NewServerConn(buf, rwc, req)\n\treturn\n}\n\n// Server represents a server of a WebSocket.\ntype Server struct {\n\t// Config is a WebSocket configuration for new WebSocket connection.\n\tConfig\n\n\t// Handshake is an optional function in WebSocket handshake.\n\t// For example, you can check, or don't check Origin header.\n\t// Another example, you can select config.Protocol.\n\tHandshake func(*Config, *http.Request) error\n\n\t// Handler handles a WebSocket connection.\n\tHandler\n}\n\n// ServeHTTP implements the http.Handler interface for a WebSocket\nfunc (s Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {\n\ts.serveWebSocket(w, req)\n}\n\nfunc (s Server) serveWebSocket(w http.ResponseWriter, req *http.Request) {\n\trwc, buf, err := w.(http.Hijacker).Hijack()\n\tif err != nil {\n\t\tpanic(\"Hijack failed: \" + err.Error())\n\t}\n\t// The server should abort the WebSocket connection if it finds\n\t// the client did not send a handshake that matches with protocol\n\t// specification.\n\tdefer rwc.Close()\n\tconn, err := newServerConn(rwc, buf, req, &s.Config, s.Handshake)\n\tif err != nil {\n\t\treturn\n\t}\n\tif conn == nil {\n\t\tpanic(\"unexpected nil conn\")\n\t}\n\ts.Handler(conn)\n}\n\n// Handler is a simple interface to a WebSocket browser client.\n// It checks if Origin header is valid URL by default.\n// You might want to verify websocket.Conn.Config().Origin in the func.\n// If you use Server instead of Handler, you could call websocket.Origin and\n// check the origin in your Handshake func. So, if you want to accept\n// non-browser clients, which do not send an Origin header, set a\n// Server.Handshake that does not check the origin.\ntype Handler func(*Conn)\n\nfunc checkOrigin(config *Config, req *http.Request) (err error) {\n\tconfig.Origin, err = Origin(config, req)\n\tif err == nil && config.Origin == nil {\n\t\treturn fmt.Errorf(\"null origin\")\n\t}\n\treturn err\n}\n\n// ServeHTTP implements the http.Handler interface for a WebSocket\nfunc (h Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {\n\ts := Server{Handler: h, Handshake: checkOrigin}\n\ts.serveWebSocket(w, req)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/websocket/websocket.go",
    "content": "// Copyright 2009 The Go 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\n// Package websocket implements a client and server for the WebSocket protocol\n// as specified in RFC 6455.\n//\n// This package currently lacks some features found in an alternative\n// and more actively maintained WebSocket packages:\n//\n//   - [github.com/gorilla/websocket]\n//   - [github.com/coder/websocket]\npackage websocket // import \"golang.org/x/net/websocket\"\n\nimport (\n\t\"bufio\"\n\t\"crypto/tls\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sync\"\n\t\"time\"\n)\n\nconst (\n\tProtocolVersionHybi13    = 13\n\tProtocolVersionHybi      = ProtocolVersionHybi13\n\tSupportedProtocolVersion = \"13\"\n\n\tContinuationFrame = 0\n\tTextFrame         = 1\n\tBinaryFrame       = 2\n\tCloseFrame        = 8\n\tPingFrame         = 9\n\tPongFrame         = 10\n\tUnknownFrame      = 255\n\n\tDefaultMaxPayloadBytes = 32 << 20 // 32MB\n)\n\n// ProtocolError represents WebSocket protocol errors.\ntype ProtocolError struct {\n\tErrorString string\n}\n\nfunc (err *ProtocolError) Error() string { return err.ErrorString }\n\nvar (\n\tErrBadProtocolVersion   = &ProtocolError{\"bad protocol version\"}\n\tErrBadScheme            = &ProtocolError{\"bad scheme\"}\n\tErrBadStatus            = &ProtocolError{\"bad status\"}\n\tErrBadUpgrade           = &ProtocolError{\"missing or bad upgrade\"}\n\tErrBadWebSocketOrigin   = &ProtocolError{\"missing or bad WebSocket-Origin\"}\n\tErrBadWebSocketLocation = &ProtocolError{\"missing or bad WebSocket-Location\"}\n\tErrBadWebSocketProtocol = &ProtocolError{\"missing or bad WebSocket-Protocol\"}\n\tErrBadWebSocketVersion  = &ProtocolError{\"missing or bad WebSocket Version\"}\n\tErrChallengeResponse    = &ProtocolError{\"mismatch challenge/response\"}\n\tErrBadFrame             = &ProtocolError{\"bad frame\"}\n\tErrBadFrameBoundary     = &ProtocolError{\"not on frame boundary\"}\n\tErrNotWebSocket         = &ProtocolError{\"not websocket protocol\"}\n\tErrBadRequestMethod     = &ProtocolError{\"bad method\"}\n\tErrNotSupported         = &ProtocolError{\"not supported\"}\n)\n\n// ErrFrameTooLarge is returned by Codec's Receive method if payload size\n// exceeds limit set by Conn.MaxPayloadBytes\nvar ErrFrameTooLarge = errors.New(\"websocket: frame payload size exceeds limit\")\n\n// Addr is an implementation of net.Addr for WebSocket.\ntype Addr struct {\n\t*url.URL\n}\n\n// Network returns the network type for a WebSocket, \"websocket\".\nfunc (addr *Addr) Network() string { return \"websocket\" }\n\n// Config is a WebSocket configuration\ntype Config struct {\n\t// A WebSocket server address.\n\tLocation *url.URL\n\n\t// A Websocket client origin.\n\tOrigin *url.URL\n\n\t// WebSocket subprotocols.\n\tProtocol []string\n\n\t// WebSocket protocol version.\n\tVersion int\n\n\t// TLS config for secure WebSocket (wss).\n\tTlsConfig *tls.Config\n\n\t// Additional header fields to be sent in WebSocket opening handshake.\n\tHeader http.Header\n\n\t// Dialer used when opening websocket connections.\n\tDialer *net.Dialer\n\n\thandshakeData map[string]string\n}\n\n// serverHandshaker is an interface to handle WebSocket server side handshake.\ntype serverHandshaker interface {\n\t// ReadHandshake reads handshake request message from client.\n\t// Returns http response code and error if any.\n\tReadHandshake(buf *bufio.Reader, req *http.Request) (code int, err error)\n\n\t// AcceptHandshake accepts the client handshake request and sends\n\t// handshake response back to client.\n\tAcceptHandshake(buf *bufio.Writer) (err error)\n\n\t// NewServerConn creates a new WebSocket connection.\n\tNewServerConn(buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) (conn *Conn)\n}\n\n// frameReader is an interface to read a WebSocket frame.\ntype frameReader interface {\n\t// Reader is to read payload of the frame.\n\tio.Reader\n\n\t// PayloadType returns payload type.\n\tPayloadType() byte\n\n\t// HeaderReader returns a reader to read header of the frame.\n\tHeaderReader() io.Reader\n\n\t// TrailerReader returns a reader to read trailer of the frame.\n\t// If it returns nil, there is no trailer in the frame.\n\tTrailerReader() io.Reader\n\n\t// Len returns total length of the frame, including header and trailer.\n\tLen() int\n}\n\n// frameReaderFactory is an interface to creates new frame reader.\ntype frameReaderFactory interface {\n\tNewFrameReader() (r frameReader, err error)\n}\n\n// frameWriter is an interface to write a WebSocket frame.\ntype frameWriter interface {\n\t// Writer is to write payload of the frame.\n\tio.WriteCloser\n}\n\n// frameWriterFactory is an interface to create new frame writer.\ntype frameWriterFactory interface {\n\tNewFrameWriter(payloadType byte) (w frameWriter, err error)\n}\n\ntype frameHandler interface {\n\tHandleFrame(frame frameReader) (r frameReader, err error)\n\tWriteClose(status int) (err error)\n}\n\n// Conn represents a WebSocket connection.\n//\n// Multiple goroutines may invoke methods on a Conn simultaneously.\ntype Conn struct {\n\tconfig  *Config\n\trequest *http.Request\n\n\tbuf *bufio.ReadWriter\n\trwc io.ReadWriteCloser\n\n\trio sync.Mutex\n\tframeReaderFactory\n\tframeReader\n\n\twio sync.Mutex\n\tframeWriterFactory\n\n\tframeHandler\n\tPayloadType        byte\n\tdefaultCloseStatus int\n\n\t// MaxPayloadBytes limits the size of frame payload received over Conn\n\t// by Codec's Receive method. If zero, DefaultMaxPayloadBytes is used.\n\tMaxPayloadBytes int\n}\n\n// Read implements the io.Reader interface:\n// it reads data of a frame from the WebSocket connection.\n// if msg is not large enough for the frame data, it fills the msg and next Read\n// will read the rest of the frame data.\n// it reads Text frame or Binary frame.\nfunc (ws *Conn) Read(msg []byte) (n int, err error) {\n\tws.rio.Lock()\n\tdefer ws.rio.Unlock()\nagain:\n\tif ws.frameReader == nil {\n\t\tframe, err := ws.frameReaderFactory.NewFrameReader()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tws.frameReader, err = ws.frameHandler.HandleFrame(frame)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tif ws.frameReader == nil {\n\t\t\tgoto again\n\t\t}\n\t}\n\tn, err = ws.frameReader.Read(msg)\n\tif err == io.EOF {\n\t\tif trailer := ws.frameReader.TrailerReader(); trailer != nil {\n\t\t\tio.Copy(io.Discard, trailer)\n\t\t}\n\t\tws.frameReader = nil\n\t\tgoto again\n\t}\n\treturn n, err\n}\n\n// Write implements the io.Writer interface:\n// it writes data as a frame to the WebSocket connection.\nfunc (ws *Conn) Write(msg []byte) (n int, err error) {\n\tws.wio.Lock()\n\tdefer ws.wio.Unlock()\n\tw, err := ws.frameWriterFactory.NewFrameWriter(ws.PayloadType)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tn, err = w.Write(msg)\n\tw.Close()\n\treturn n, err\n}\n\n// Close implements the io.Closer interface.\nfunc (ws *Conn) Close() error {\n\terr := ws.frameHandler.WriteClose(ws.defaultCloseStatus)\n\terr1 := ws.rwc.Close()\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn err1\n}\n\n// IsClientConn reports whether ws is a client-side connection.\nfunc (ws *Conn) IsClientConn() bool { return ws.request == nil }\n\n// IsServerConn reports whether ws is a server-side connection.\nfunc (ws *Conn) IsServerConn() bool { return ws.request != nil }\n\n// LocalAddr returns the WebSocket Origin for the connection for client, or\n// the WebSocket location for server.\nfunc (ws *Conn) LocalAddr() net.Addr {\n\tif ws.IsClientConn() {\n\t\treturn &Addr{ws.config.Origin}\n\t}\n\treturn &Addr{ws.config.Location}\n}\n\n// RemoteAddr returns the WebSocket location for the connection for client, or\n// the Websocket Origin for server.\nfunc (ws *Conn) RemoteAddr() net.Addr {\n\tif ws.IsClientConn() {\n\t\treturn &Addr{ws.config.Location}\n\t}\n\treturn &Addr{ws.config.Origin}\n}\n\nvar errSetDeadline = errors.New(\"websocket: cannot set deadline: not using a net.Conn\")\n\n// SetDeadline sets the connection's network read & write deadlines.\nfunc (ws *Conn) SetDeadline(t time.Time) error {\n\tif conn, ok := ws.rwc.(net.Conn); ok {\n\t\treturn conn.SetDeadline(t)\n\t}\n\treturn errSetDeadline\n}\n\n// SetReadDeadline sets the connection's network read deadline.\nfunc (ws *Conn) SetReadDeadline(t time.Time) error {\n\tif conn, ok := ws.rwc.(net.Conn); ok {\n\t\treturn conn.SetReadDeadline(t)\n\t}\n\treturn errSetDeadline\n}\n\n// SetWriteDeadline sets the connection's network write deadline.\nfunc (ws *Conn) SetWriteDeadline(t time.Time) error {\n\tif conn, ok := ws.rwc.(net.Conn); ok {\n\t\treturn conn.SetWriteDeadline(t)\n\t}\n\treturn errSetDeadline\n}\n\n// Config returns the WebSocket config.\nfunc (ws *Conn) Config() *Config { return ws.config }\n\n// Request returns the http request upgraded to the WebSocket.\n// It is nil for client side.\nfunc (ws *Conn) Request() *http.Request { return ws.request }\n\n// Codec represents a symmetric pair of functions that implement a codec.\ntype Codec struct {\n\tMarshal   func(v interface{}) (data []byte, payloadType byte, err error)\n\tUnmarshal func(data []byte, payloadType byte, v interface{}) (err error)\n}\n\n// Send sends v marshaled by cd.Marshal as single frame to ws.\nfunc (cd Codec) Send(ws *Conn, v interface{}) (err error) {\n\tdata, payloadType, err := cd.Marshal(v)\n\tif err != nil {\n\t\treturn err\n\t}\n\tws.wio.Lock()\n\tdefer ws.wio.Unlock()\n\tw, err := ws.frameWriterFactory.NewFrameWriter(payloadType)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = w.Write(data)\n\tw.Close()\n\treturn err\n}\n\n// Receive receives single frame from ws, unmarshaled by cd.Unmarshal and stores\n// in v. The whole frame payload is read to an in-memory buffer; max size of\n// payload is defined by ws.MaxPayloadBytes. If frame payload size exceeds\n// limit, ErrFrameTooLarge is returned; in this case frame is not read off wire\n// completely. The next call to Receive would read and discard leftover data of\n// previous oversized frame before processing next frame.\nfunc (cd Codec) Receive(ws *Conn, v interface{}) (err error) {\n\tws.rio.Lock()\n\tdefer ws.rio.Unlock()\n\tif ws.frameReader != nil {\n\t\t_, err = io.Copy(io.Discard, ws.frameReader)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tws.frameReader = nil\n\t}\nagain:\n\tframe, err := ws.frameReaderFactory.NewFrameReader()\n\tif err != nil {\n\t\treturn err\n\t}\n\tframe, err = ws.frameHandler.HandleFrame(frame)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif frame == nil {\n\t\tgoto again\n\t}\n\tmaxPayloadBytes := ws.MaxPayloadBytes\n\tif maxPayloadBytes == 0 {\n\t\tmaxPayloadBytes = DefaultMaxPayloadBytes\n\t}\n\tif hf, ok := frame.(*hybiFrameReader); ok && hf.header.Length > int64(maxPayloadBytes) {\n\t\t// payload size exceeds limit, no need to call Unmarshal\n\t\t//\n\t\t// set frameReader to current oversized frame so that\n\t\t// the next call to this function can drain leftover\n\t\t// data before processing the next frame\n\t\tws.frameReader = frame\n\t\treturn ErrFrameTooLarge\n\t}\n\tpayloadType := frame.PayloadType()\n\tdata, err := io.ReadAll(frame)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn cd.Unmarshal(data, payloadType, v)\n}\n\nfunc marshal(v interface{}) (msg []byte, payloadType byte, err error) {\n\tswitch data := v.(type) {\n\tcase string:\n\t\treturn []byte(data), TextFrame, nil\n\tcase []byte:\n\t\treturn data, BinaryFrame, nil\n\t}\n\treturn nil, UnknownFrame, ErrNotSupported\n}\n\nfunc unmarshal(msg []byte, payloadType byte, v interface{}) (err error) {\n\tswitch data := v.(type) {\n\tcase *string:\n\t\t*data = string(msg)\n\t\treturn nil\n\tcase *[]byte:\n\t\t*data = msg\n\t\treturn nil\n\t}\n\treturn ErrNotSupported\n}\n\n/*\nMessage is a codec to send/receive text/binary data in a frame on WebSocket connection.\nTo send/receive text frame, use string type.\nTo send/receive binary frame, use []byte type.\n\nTrivial usage:\n\n\timport \"websocket\"\n\n\t// receive text frame\n\tvar message string\n\twebsocket.Message.Receive(ws, &message)\n\n\t// send text frame\n\tmessage = \"hello\"\n\twebsocket.Message.Send(ws, message)\n\n\t// receive binary frame\n\tvar data []byte\n\twebsocket.Message.Receive(ws, &data)\n\n\t// send binary frame\n\tdata = []byte{0, 1, 2}\n\twebsocket.Message.Send(ws, data)\n*/\nvar Message = Codec{marshal, unmarshal}\n\nfunc jsonMarshal(v interface{}) (msg []byte, payloadType byte, err error) {\n\tmsg, err = json.Marshal(v)\n\treturn msg, TextFrame, err\n}\n\nfunc jsonUnmarshal(msg []byte, payloadType byte, v interface{}) (err error) {\n\treturn json.Unmarshal(msg, v)\n}\n\n/*\nJSON is a codec to send/receive JSON data in a frame from a WebSocket connection.\n\nTrivial usage:\n\n\timport \"websocket\"\n\n\ttype T struct {\n\t\tMsg string\n\t\tCount int\n\t}\n\n\t// receive JSON type T\n\tvar data T\n\twebsocket.JSON.Receive(ws, &data)\n\n\t// send JSON type T\n\twebsocket.JSON.Send(ws, data)\n*/\nvar JSON = Codec{jsonMarshal, jsonUnmarshal}\n"
  },
  {
    "path": "vendor/golang.org/x/oauth2/.travis.yml",
    "content": "language: go\n\ngo:\n  - tip\n\ninstall:\n  - export GOPATH=\"$HOME/gopath\"\n  - mkdir -p \"$GOPATH/src/golang.org/x\"\n  - mv \"$TRAVIS_BUILD_DIR\" \"$GOPATH/src/golang.org/x/oauth2\"\n  - go get -v -t -d golang.org/x/oauth2/...\n\nscript:\n  - go test -v golang.org/x/oauth2/...\n"
  },
  {
    "path": "vendor/golang.org/x/oauth2/CONTRIBUTING.md",
    "content": "# Contributing to Go\n\nGo is an open source project.\n\nIt is the work of hundreds of contributors. We appreciate your help!\n\n## Filing issues\n\nWhen [filing an issue](https://github.com/golang/oauth2/issues), make sure to answer these five questions:\n\n1.  What version of Go are you using (`go version`)?\n2.  What operating system and processor architecture are you using?\n3.  What did you do?\n4.  What did you expect to see?\n5.  What did you see instead?\n\nGeneral questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.\nThe gophers there will answer or ask you to file an issue if you've tripped over a bug.\n\n## Contributing code\n\nPlease read the [Contribution Guidelines](https://golang.org/doc/contribute.html)\nbefore sending patches.\n\nUnless otherwise noted, the Go source files are distributed under\nthe BSD-style license found in the LICENSE file.\n"
  },
  {
    "path": "vendor/golang.org/x/oauth2/LICENSE",
    "content": "Copyright 2009 The Go Authors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google LLC nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(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": "vendor/golang.org/x/oauth2/README.md",
    "content": "# OAuth2 for Go\n\n[![Go Reference](https://pkg.go.dev/badge/golang.org/x/oauth2.svg)](https://pkg.go.dev/golang.org/x/oauth2)\n[![Build Status](https://travis-ci.org/golang/oauth2.svg?branch=master)](https://travis-ci.org/golang/oauth2)\n\noauth2 package contains a client implementation for OAuth 2.0 spec.\n\nSee pkg.go.dev for further documentation and examples.\n\n* [pkg.go.dev/golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2)\n* [pkg.go.dev/golang.org/x/oauth2/google](https://pkg.go.dev/golang.org/x/oauth2/google)\n\n## Policy for new endpoints\n\nWe no longer accept new provider-specific packages in this repo if all\nthey do is add a single endpoint variable. If you just want to add a\nsingle endpoint, add it to the\n[pkg.go.dev/golang.org/x/oauth2/endpoints](https://pkg.go.dev/golang.org/x/oauth2/endpoints)\npackage.\n\n## Report Issues / Send Patches\n\nThe main issue tracker for the oauth2 repository is located at\nhttps://github.com/golang/oauth2/issues.\n\nThis repository uses Gerrit for code changes. To learn how to submit changes to\nthis repository, see https://go.dev/doc/contribute.\n\nThe git repository is https://go.googlesource.com/oauth2.\n\nNote:\n\n* Excluding trivial changes, all contributions should be connected to an existing issue.\n* API changes must go through the [change proposal process](https://go.dev/s/proposal-process) before they can be accepted.\n* The code owners are listed at [dev.golang.org/owners](https://dev.golang.org/owners#:~:text=x/oauth2).\n"
  },
  {
    "path": "vendor/golang.org/x/oauth2/deviceauth.go",
    "content": "package oauth2\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n\n\t\"golang.org/x/oauth2/internal\"\n)\n\n// https://datatracker.ietf.org/doc/html/rfc8628#section-3.5\nconst (\n\terrAuthorizationPending = \"authorization_pending\"\n\terrSlowDown             = \"slow_down\"\n\terrAccessDenied         = \"access_denied\"\n\terrExpiredToken         = \"expired_token\"\n)\n\n// DeviceAuthResponse describes a successful RFC 8628 Device Authorization Response\n// https://datatracker.ietf.org/doc/html/rfc8628#section-3.2\ntype DeviceAuthResponse struct {\n\t// DeviceCode\n\tDeviceCode string `json:\"device_code\"`\n\t// UserCode is the code the user should enter at the verification uri\n\tUserCode string `json:\"user_code\"`\n\t// VerificationURI is where user should enter the user code\n\tVerificationURI string `json:\"verification_uri\"`\n\t// VerificationURIComplete (if populated) includes the user code in the verification URI. This is typically shown to the user in non-textual form, such as a QR code.\n\tVerificationURIComplete string `json:\"verification_uri_complete,omitempty\"`\n\t// Expiry is when the device code and user code expire\n\tExpiry time.Time `json:\"expires_in,omitempty\"`\n\t// Interval is the duration in seconds that Poll should wait between requests\n\tInterval int64 `json:\"interval,omitempty\"`\n}\n\nfunc (d DeviceAuthResponse) MarshalJSON() ([]byte, error) {\n\ttype Alias DeviceAuthResponse\n\tvar expiresIn int64\n\tif !d.Expiry.IsZero() {\n\t\texpiresIn = int64(time.Until(d.Expiry).Seconds())\n\t}\n\treturn json.Marshal(&struct {\n\t\tExpiresIn int64 `json:\"expires_in,omitempty\"`\n\t\t*Alias\n\t}{\n\t\tExpiresIn: expiresIn,\n\t\tAlias:     (*Alias)(&d),\n\t})\n\n}\n\nfunc (c *DeviceAuthResponse) UnmarshalJSON(data []byte) error {\n\ttype Alias DeviceAuthResponse\n\taux := &struct {\n\t\tExpiresIn int64 `json:\"expires_in\"`\n\t\t// workaround misspelling of verification_uri\n\t\tVerificationURL string `json:\"verification_url\"`\n\t\t*Alias\n\t}{\n\t\tAlias: (*Alias)(c),\n\t}\n\tif err := json.Unmarshal(data, &aux); err != nil {\n\t\treturn err\n\t}\n\tif aux.ExpiresIn != 0 {\n\t\tc.Expiry = time.Now().UTC().Add(time.Second * time.Duration(aux.ExpiresIn))\n\t}\n\tif c.VerificationURI == \"\" {\n\t\tc.VerificationURI = aux.VerificationURL\n\t}\n\treturn nil\n}\n\n// DeviceAuth returns a device auth struct which contains a device code\n// and authorization information provided for users to enter on another device.\nfunc (c *Config) DeviceAuth(ctx context.Context, opts ...AuthCodeOption) (*DeviceAuthResponse, error) {\n\t// https://datatracker.ietf.org/doc/html/rfc8628#section-3.1\n\tv := url.Values{\n\t\t\"client_id\": {c.ClientID},\n\t}\n\tif len(c.Scopes) > 0 {\n\t\tv.Set(\"scope\", strings.Join(c.Scopes, \" \"))\n\t}\n\tfor _, opt := range opts {\n\t\topt.setValue(v)\n\t}\n\treturn retrieveDeviceAuth(ctx, c, v)\n}\n\nfunc retrieveDeviceAuth(ctx context.Context, c *Config, v url.Values) (*DeviceAuthResponse, error) {\n\tif c.Endpoint.DeviceAuthURL == \"\" {\n\t\treturn nil, errors.New(\"endpoint missing DeviceAuthURL\")\n\t}\n\n\treq, err := http.NewRequest(\"POST\", c.Endpoint.DeviceAuthURL, strings.NewReader(v.Encode()))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/x-www-form-urlencoded\")\n\treq.Header.Set(\"Accept\", \"application/json\")\n\n\tt := time.Now()\n\tr, err := internal.ContextClient(ctx).Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tbody, err := io.ReadAll(io.LimitReader(r.Body, 1<<20))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"oauth2: cannot auth device: %v\", err)\n\t}\n\tif code := r.StatusCode; code < 200 || code > 299 {\n\t\treturn nil, &RetrieveError{\n\t\t\tResponse: r,\n\t\t\tBody:     body,\n\t\t}\n\t}\n\n\tda := &DeviceAuthResponse{}\n\terr = json.Unmarshal(body, &da)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unmarshal %s\", err)\n\t}\n\n\tif !da.Expiry.IsZero() {\n\t\t// Make a small adjustment to account for time taken by the request\n\t\tda.Expiry = da.Expiry.Add(-time.Since(t))\n\t}\n\n\treturn da, nil\n}\n\n// DeviceAccessToken polls the server to exchange a device code for a token.\nfunc (c *Config) DeviceAccessToken(ctx context.Context, da *DeviceAuthResponse, opts ...AuthCodeOption) (*Token, error) {\n\tif !da.Expiry.IsZero() {\n\t\tvar cancel context.CancelFunc\n\t\tctx, cancel = context.WithDeadline(ctx, da.Expiry)\n\t\tdefer cancel()\n\t}\n\n\t// https://datatracker.ietf.org/doc/html/rfc8628#section-3.4\n\tv := url.Values{\n\t\t\"client_id\":   {c.ClientID},\n\t\t\"grant_type\":  {\"urn:ietf:params:oauth:grant-type:device_code\"},\n\t\t\"device_code\": {da.DeviceCode},\n\t}\n\tif len(c.Scopes) > 0 {\n\t\tv.Set(\"scope\", strings.Join(c.Scopes, \" \"))\n\t}\n\tfor _, opt := range opts {\n\t\topt.setValue(v)\n\t}\n\n\t// \"If no value is provided, clients MUST use 5 as the default.\"\n\t// https://datatracker.ietf.org/doc/html/rfc8628#section-3.2\n\tinterval := da.Interval\n\tif interval == 0 {\n\t\tinterval = 5\n\t}\n\n\tticker := time.NewTicker(time.Duration(interval) * time.Second)\n\tdefer ticker.Stop()\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn nil, ctx.Err()\n\t\tcase <-ticker.C:\n\t\t\ttok, err := retrieveToken(ctx, c, v)\n\t\t\tif err == nil {\n\t\t\t\treturn tok, nil\n\t\t\t}\n\n\t\t\te, ok := err.(*RetrieveError)\n\t\t\tif !ok {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tswitch e.ErrorCode {\n\t\t\tcase errSlowDown:\n\t\t\t\t// https://datatracker.ietf.org/doc/html/rfc8628#section-3.5\n\t\t\t\t// \"the interval MUST be increased by 5 seconds for this and all subsequent requests\"\n\t\t\t\tinterval += 5\n\t\t\t\tticker.Reset(time.Duration(interval) * time.Second)\n\t\t\tcase errAuthorizationPending:\n\t\t\t\t// Do nothing.\n\t\t\tcase errAccessDenied, errExpiredToken:\n\t\t\t\tfallthrough\n\t\t\tdefault:\n\t\t\t\treturn tok, err\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/oauth2/internal/doc.go",
    "content": "// Copyright 2017 The Go 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\n// Package internal contains support packages for [golang.org/x/oauth2].\npackage internal\n"
  },
  {
    "path": "vendor/golang.org/x/oauth2/internal/oauth2.go",
    "content": "// Copyright 2014 The Go 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 internal\n\nimport (\n\t\"crypto/rsa\"\n\t\"crypto/x509\"\n\t\"encoding/pem\"\n\t\"errors\"\n\t\"fmt\"\n)\n\n// ParseKey converts the binary contents of a private key file\n// to an [*rsa.PrivateKey]. It detects whether the private key is in a\n// PEM container or not. If so, it extracts the private key\n// from PEM container before conversion. It only supports PEM\n// containers with no passphrase.\nfunc ParseKey(key []byte) (*rsa.PrivateKey, error) {\n\tblock, _ := pem.Decode(key)\n\tif block != nil {\n\t\tkey = block.Bytes\n\t}\n\tparsedKey, err := x509.ParsePKCS8PrivateKey(key)\n\tif err != nil {\n\t\tparsedKey, err = x509.ParsePKCS1PrivateKey(key)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"private key should be a PEM or plain PKCS1 or PKCS8; parse error: %v\", err)\n\t\t}\n\t}\n\tparsed, ok := parsedKey.(*rsa.PrivateKey)\n\tif !ok {\n\t\treturn nil, errors.New(\"private key is invalid\")\n\t}\n\treturn parsed, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/oauth2/internal/token.go",
    "content": "// Copyright 2014 The Go 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 internal\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"mime\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n)\n\n// Token represents the credentials used to authorize\n// the requests to access protected resources on the OAuth 2.0\n// provider's backend.\n//\n// This type is a mirror of [golang.org/x/oauth2.Token] and exists to break\n// an otherwise-circular dependency. Other internal packages\n// should convert this Token into an [golang.org/x/oauth2.Token] before use.\ntype Token struct {\n\t// AccessToken is the token that authorizes and authenticates\n\t// the requests.\n\tAccessToken string\n\n\t// TokenType is the type of token.\n\t// The Type method returns either this or \"Bearer\", the default.\n\tTokenType string\n\n\t// RefreshToken is a token that's used by the application\n\t// (as opposed to the user) to refresh the access token\n\t// if it expires.\n\tRefreshToken string\n\n\t// Expiry is the optional expiration time of the access token.\n\t//\n\t// If zero, TokenSource implementations will reuse the same\n\t// token forever and RefreshToken or equivalent\n\t// mechanisms for that TokenSource will not be used.\n\tExpiry time.Time\n\n\t// ExpiresIn is the OAuth2 wire format \"expires_in\" field,\n\t// which specifies how many seconds later the token expires,\n\t// relative to an unknown time base approximately around \"now\".\n\t// It is the application's responsibility to populate\n\t// `Expiry` from `ExpiresIn` when required.\n\tExpiresIn int64 `json:\"expires_in,omitempty\"`\n\n\t// Raw optionally contains extra metadata from the server\n\t// when updating a token.\n\tRaw any\n}\n\n// tokenJSON is the struct representing the HTTP response from OAuth2\n// providers returning a token or error in JSON form.\n// https://datatracker.ietf.org/doc/html/rfc6749#section-5.1\ntype tokenJSON struct {\n\tAccessToken  string         `json:\"access_token\"`\n\tTokenType    string         `json:\"token_type\"`\n\tRefreshToken string         `json:\"refresh_token\"`\n\tExpiresIn    expirationTime `json:\"expires_in\"` // at least PayPal returns string, while most return number\n\t// error fields\n\t// https://datatracker.ietf.org/doc/html/rfc6749#section-5.2\n\tErrorCode        string `json:\"error\"`\n\tErrorDescription string `json:\"error_description\"`\n\tErrorURI         string `json:\"error_uri\"`\n}\n\nfunc (e *tokenJSON) expiry() (t time.Time) {\n\tif v := e.ExpiresIn; v != 0 {\n\t\treturn time.Now().Add(time.Duration(v) * time.Second)\n\t}\n\treturn\n}\n\ntype expirationTime int32\n\nfunc (e *expirationTime) UnmarshalJSON(b []byte) error {\n\tif len(b) == 0 || string(b) == \"null\" {\n\t\treturn nil\n\t}\n\tvar n json.Number\n\terr := json.Unmarshal(b, &n)\n\tif err != nil {\n\t\treturn err\n\t}\n\ti, err := n.Int64()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif i > math.MaxInt32 {\n\t\ti = math.MaxInt32\n\t}\n\t*e = expirationTime(i)\n\treturn nil\n}\n\n// AuthStyle is a copy of the golang.org/x/oauth2 package's AuthStyle type.\ntype AuthStyle int\n\nconst (\n\tAuthStyleUnknown  AuthStyle = 0\n\tAuthStyleInParams AuthStyle = 1\n\tAuthStyleInHeader AuthStyle = 2\n)\n\n// LazyAuthStyleCache is a backwards compatibility compromise to let Configs\n// have a lazily-initialized AuthStyleCache.\n//\n// The two users of this, oauth2.Config and oauth2/clientcredentials.Config,\n// both would ideally just embed an unexported AuthStyleCache but because both\n// were historically allowed to be copied by value we can't retroactively add an\n// uncopyable Mutex to them.\n//\n// We could use an atomic.Pointer, but that was added recently enough (in Go\n// 1.18) that we'd break Go 1.17 users where the tests as of 2023-08-03\n// still pass. By using an atomic.Value, it supports both Go 1.17 and\n// copying by value, even if that's not ideal.\ntype LazyAuthStyleCache struct {\n\tv atomic.Value // of *AuthStyleCache\n}\n\nfunc (lc *LazyAuthStyleCache) Get() *AuthStyleCache {\n\tif c, ok := lc.v.Load().(*AuthStyleCache); ok {\n\t\treturn c\n\t}\n\tc := new(AuthStyleCache)\n\tif !lc.v.CompareAndSwap(nil, c) {\n\t\tc = lc.v.Load().(*AuthStyleCache)\n\t}\n\treturn c\n}\n\ntype authStyleCacheKey struct {\n\turl      string\n\tclientID string\n}\n\n// AuthStyleCache is the set of tokenURLs we've successfully used via\n// RetrieveToken and which style auth we ended up using.\n// It's called a cache, but it doesn't (yet?) shrink. It's expected that\n// the set of OAuth2 servers a program contacts over time is fixed and\n// small.\ntype AuthStyleCache struct {\n\tmu sync.Mutex\n\tm  map[authStyleCacheKey]AuthStyle\n}\n\n// lookupAuthStyle reports which auth style we last used with tokenURL\n// when calling RetrieveToken and whether we have ever done so.\nfunc (c *AuthStyleCache) lookupAuthStyle(tokenURL, clientID string) (style AuthStyle, ok bool) {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\tstyle, ok = c.m[authStyleCacheKey{tokenURL, clientID}]\n\treturn\n}\n\n// setAuthStyle adds an entry to authStyleCache, documented above.\nfunc (c *AuthStyleCache) setAuthStyle(tokenURL, clientID string, v AuthStyle) {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\tif c.m == nil {\n\t\tc.m = make(map[authStyleCacheKey]AuthStyle)\n\t}\n\tc.m[authStyleCacheKey{tokenURL, clientID}] = v\n}\n\n// newTokenRequest returns a new *http.Request to retrieve a new token\n// from tokenURL using the provided clientID, clientSecret, and POST\n// body parameters.\n//\n// inParams is whether the clientID & clientSecret should be encoded\n// as the POST body. An 'inParams' value of true means to send it in\n// the POST body (along with any values in v); false means to send it\n// in the Authorization header.\nfunc newTokenRequest(tokenURL, clientID, clientSecret string, v url.Values, authStyle AuthStyle) (*http.Request, error) {\n\tif authStyle == AuthStyleInParams {\n\t\tv = cloneURLValues(v)\n\t\tif clientID != \"\" {\n\t\t\tv.Set(\"client_id\", clientID)\n\t\t}\n\t\tif clientSecret != \"\" {\n\t\t\tv.Set(\"client_secret\", clientSecret)\n\t\t}\n\t}\n\treq, err := http.NewRequest(\"POST\", tokenURL, strings.NewReader(v.Encode()))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/x-www-form-urlencoded\")\n\tif authStyle == AuthStyleInHeader {\n\t\treq.SetBasicAuth(url.QueryEscape(clientID), url.QueryEscape(clientSecret))\n\t}\n\treturn req, nil\n}\n\nfunc cloneURLValues(v url.Values) url.Values {\n\tv2 := make(url.Values, len(v))\n\tfor k, vv := range v {\n\t\tv2[k] = append([]string(nil), vv...)\n\t}\n\treturn v2\n}\n\nfunc RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string, v url.Values, authStyle AuthStyle, styleCache *AuthStyleCache) (*Token, error) {\n\tneedsAuthStyleProbe := authStyle == AuthStyleUnknown\n\tif needsAuthStyleProbe {\n\t\tif style, ok := styleCache.lookupAuthStyle(tokenURL, clientID); ok {\n\t\t\tauthStyle = style\n\t\t\tneedsAuthStyleProbe = false\n\t\t} else {\n\t\t\tauthStyle = AuthStyleInHeader // the first way we'll try\n\t\t}\n\t}\n\treq, err := newTokenRequest(tokenURL, clientID, clientSecret, v, authStyle)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttoken, err := doTokenRoundTrip(ctx, req)\n\tif err != nil && needsAuthStyleProbe {\n\t\t// If we get an error, assume the server wants the\n\t\t// clientID & clientSecret in a different form.\n\t\t// See https://code.google.com/p/goauth2/issues/detail?id=31 for background.\n\t\t// In summary:\n\t\t// - Reddit only accepts client secret in the Authorization header\n\t\t// - Dropbox accepts either it in URL param or Auth header, but not both.\n\t\t// - Google only accepts URL param (not spec compliant?), not Auth header\n\t\t// - Stripe only accepts client secret in Auth header with Bearer method, not Basic\n\t\t//\n\t\t// We used to maintain a big table in this code of all the sites and which way\n\t\t// they went, but maintaining it didn't scale & got annoying.\n\t\t// So just try both ways.\n\t\tauthStyle = AuthStyleInParams // the second way we'll try\n\t\treq, _ = newTokenRequest(tokenURL, clientID, clientSecret, v, authStyle)\n\t\ttoken, err = doTokenRoundTrip(ctx, req)\n\t}\n\tif needsAuthStyleProbe && err == nil {\n\t\tstyleCache.setAuthStyle(tokenURL, clientID, authStyle)\n\t}\n\t// Don't overwrite `RefreshToken` with an empty value\n\t// if this was a token refreshing request.\n\tif token != nil && token.RefreshToken == \"\" {\n\t\ttoken.RefreshToken = v.Get(\"refresh_token\")\n\t}\n\treturn token, err\n}\n\nfunc doTokenRoundTrip(ctx context.Context, req *http.Request) (*Token, error) {\n\tr, err := ContextClient(ctx).Do(req.WithContext(ctx))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tbody, err := io.ReadAll(io.LimitReader(r.Body, 1<<20))\n\tr.Body.Close()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"oauth2: cannot fetch token: %v\", err)\n\t}\n\n\tfailureStatus := r.StatusCode < 200 || r.StatusCode > 299\n\tretrieveError := &RetrieveError{\n\t\tResponse: r,\n\t\tBody:     body,\n\t\t// attempt to populate error detail below\n\t}\n\n\tvar token *Token\n\tcontent, _, _ := mime.ParseMediaType(r.Header.Get(\"Content-Type\"))\n\tswitch content {\n\tcase \"application/x-www-form-urlencoded\", \"text/plain\":\n\t\t// some endpoints return a query string\n\t\tvals, err := url.ParseQuery(string(body))\n\t\tif err != nil {\n\t\t\tif failureStatus {\n\t\t\t\treturn nil, retrieveError\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"oauth2: cannot parse response: %v\", err)\n\t\t}\n\t\tretrieveError.ErrorCode = vals.Get(\"error\")\n\t\tretrieveError.ErrorDescription = vals.Get(\"error_description\")\n\t\tretrieveError.ErrorURI = vals.Get(\"error_uri\")\n\t\ttoken = &Token{\n\t\t\tAccessToken:  vals.Get(\"access_token\"),\n\t\t\tTokenType:    vals.Get(\"token_type\"),\n\t\t\tRefreshToken: vals.Get(\"refresh_token\"),\n\t\t\tRaw:          vals,\n\t\t}\n\t\te := vals.Get(\"expires_in\")\n\t\texpires, _ := strconv.Atoi(e)\n\t\tif expires != 0 {\n\t\t\ttoken.Expiry = time.Now().Add(time.Duration(expires) * time.Second)\n\t\t}\n\tdefault:\n\t\tvar tj tokenJSON\n\t\tif err = json.Unmarshal(body, &tj); err != nil {\n\t\t\tif failureStatus {\n\t\t\t\treturn nil, retrieveError\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"oauth2: cannot parse json: %v\", err)\n\t\t}\n\t\tretrieveError.ErrorCode = tj.ErrorCode\n\t\tretrieveError.ErrorDescription = tj.ErrorDescription\n\t\tretrieveError.ErrorURI = tj.ErrorURI\n\t\ttoken = &Token{\n\t\t\tAccessToken:  tj.AccessToken,\n\t\t\tTokenType:    tj.TokenType,\n\t\t\tRefreshToken: tj.RefreshToken,\n\t\t\tExpiry:       tj.expiry(),\n\t\t\tExpiresIn:    int64(tj.ExpiresIn),\n\t\t\tRaw:          make(map[string]any),\n\t\t}\n\t\tjson.Unmarshal(body, &token.Raw) // no error checks for optional fields\n\t}\n\t// according to spec, servers should respond status 400 in error case\n\t// https://www.rfc-editor.org/rfc/rfc6749#section-5.2\n\t// but some unorthodox servers respond 200 in error case\n\tif failureStatus || retrieveError.ErrorCode != \"\" {\n\t\treturn nil, retrieveError\n\t}\n\tif token.AccessToken == \"\" {\n\t\treturn nil, errors.New(\"oauth2: server response missing access_token\")\n\t}\n\treturn token, nil\n}\n\n// mirrors oauth2.RetrieveError\ntype RetrieveError struct {\n\tResponse         *http.Response\n\tBody             []byte\n\tErrorCode        string\n\tErrorDescription string\n\tErrorURI         string\n}\n\nfunc (r *RetrieveError) Error() string {\n\tif r.ErrorCode != \"\" {\n\t\ts := fmt.Sprintf(\"oauth2: %q\", r.ErrorCode)\n\t\tif r.ErrorDescription != \"\" {\n\t\t\ts += fmt.Sprintf(\" %q\", r.ErrorDescription)\n\t\t}\n\t\tif r.ErrorURI != \"\" {\n\t\t\ts += fmt.Sprintf(\" %q\", r.ErrorURI)\n\t\t}\n\t\treturn s\n\t}\n\treturn fmt.Sprintf(\"oauth2: cannot fetch token: %v\\nResponse: %s\", r.Response.Status, r.Body)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/oauth2/internal/transport.go",
    "content": "// Copyright 2014 The Go 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 internal\n\nimport (\n\t\"context\"\n\t\"net/http\"\n)\n\n// HTTPClient is the context key to use with [context.WithValue]\n// to associate an [*http.Client] value with a context.\nvar HTTPClient ContextKey\n\n// ContextKey is just an empty struct. It exists so HTTPClient can be\n// an immutable public variable with a unique type. It's immutable\n// because nobody else can create a ContextKey, being unexported.\ntype ContextKey struct{}\n\nfunc ContextClient(ctx context.Context) *http.Client {\n\tif ctx != nil {\n\t\tif hc, ok := ctx.Value(HTTPClient).(*http.Client); ok {\n\t\t\treturn hc\n\t\t}\n\t}\n\treturn http.DefaultClient\n}\n"
  },
  {
    "path": "vendor/golang.org/x/oauth2/oauth2.go",
    "content": "// Copyright 2014 The Go 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\n// Package oauth2 provides support for making\n// OAuth2 authorized and authenticated HTTP requests,\n// as specified in RFC 6749.\n// It can additionally grant authorization with Bearer JWT.\npackage oauth2 // import \"golang.org/x/oauth2\"\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"golang.org/x/oauth2/internal\"\n)\n\n// NoContext is the default context you should supply if not using\n// your own [context.Context].\n//\n// Deprecated: Use [context.Background] or [context.TODO] instead.\nvar NoContext = context.TODO()\n\n// RegisterBrokenAuthHeaderProvider previously did something. It is now a no-op.\n//\n// Deprecated: this function no longer does anything. Caller code that\n// wants to avoid potential extra HTTP requests made during\n// auto-probing of the provider's auth style should set\n// Endpoint.AuthStyle.\nfunc RegisterBrokenAuthHeaderProvider(tokenURL string) {}\n\n// Config describes a typical 3-legged OAuth2 flow, with both the\n// client application information and the server's endpoint URLs.\n// For the client credentials 2-legged OAuth2 flow, see the\n// [golang.org/x/oauth2/clientcredentials] package.\ntype Config struct {\n\t// ClientID is the application's ID.\n\tClientID string\n\n\t// ClientSecret is the application's secret.\n\tClientSecret string\n\n\t// Endpoint contains the authorization server's token endpoint\n\t// URLs. These are constants specific to each server and are\n\t// often available via site-specific packages, such as\n\t// google.Endpoint or github.Endpoint.\n\tEndpoint Endpoint\n\n\t// RedirectURL is the URL to redirect users going through\n\t// the OAuth flow, after the resource owner's URLs.\n\tRedirectURL string\n\n\t// Scopes specifies optional requested permissions.\n\tScopes []string\n\n\t// authStyleCache caches which auth style to use when Endpoint.AuthStyle is\n\t// the zero value (AuthStyleAutoDetect).\n\tauthStyleCache internal.LazyAuthStyleCache\n}\n\n// A TokenSource is anything that can return a token.\ntype TokenSource interface {\n\t// Token returns a token or an error.\n\t// Token must be safe for concurrent use by multiple goroutines.\n\t// The returned Token must not be modified.\n\tToken() (*Token, error)\n}\n\n// Endpoint represents an OAuth 2.0 provider's authorization and token\n// endpoint URLs.\ntype Endpoint struct {\n\tAuthURL       string\n\tDeviceAuthURL string\n\tTokenURL      string\n\n\t// AuthStyle optionally specifies how the endpoint wants the\n\t// client ID & client secret sent. The zero value means to\n\t// auto-detect.\n\tAuthStyle AuthStyle\n}\n\n// AuthStyle represents how requests for tokens are authenticated\n// to the server.\ntype AuthStyle int\n\nconst (\n\t// AuthStyleAutoDetect means to auto-detect which authentication\n\t// style the provider wants by trying both ways and caching\n\t// the successful way for the future.\n\tAuthStyleAutoDetect AuthStyle = 0\n\n\t// AuthStyleInParams sends the \"client_id\" and \"client_secret\"\n\t// in the POST body as application/x-www-form-urlencoded parameters.\n\tAuthStyleInParams AuthStyle = 1\n\n\t// AuthStyleInHeader sends the client_id and client_password\n\t// using HTTP Basic Authorization. This is an optional style\n\t// described in the OAuth2 RFC 6749 section 2.3.1.\n\tAuthStyleInHeader AuthStyle = 2\n)\n\nvar (\n\t// AccessTypeOnline and AccessTypeOffline are options passed\n\t// to the Options.AuthCodeURL method. They modify the\n\t// \"access_type\" field that gets sent in the URL returned by\n\t// AuthCodeURL.\n\t//\n\t// Online is the default if neither is specified. If your\n\t// application needs to refresh access tokens when the user\n\t// is not present at the browser, then use offline. This will\n\t// result in your application obtaining a refresh token the\n\t// first time your application exchanges an authorization\n\t// code for a user.\n\tAccessTypeOnline  AuthCodeOption = SetAuthURLParam(\"access_type\", \"online\")\n\tAccessTypeOffline AuthCodeOption = SetAuthURLParam(\"access_type\", \"offline\")\n\n\t// ApprovalForce forces the users to view the consent dialog\n\t// and confirm the permissions request at the URL returned\n\t// from AuthCodeURL, even if they've already done so.\n\tApprovalForce AuthCodeOption = SetAuthURLParam(\"prompt\", \"consent\")\n)\n\n// An AuthCodeOption is passed to Config.AuthCodeURL.\ntype AuthCodeOption interface {\n\tsetValue(url.Values)\n}\n\ntype setParam struct{ k, v string }\n\nfunc (p setParam) setValue(m url.Values) { m.Set(p.k, p.v) }\n\n// SetAuthURLParam builds an [AuthCodeOption] which passes key/value parameters\n// to a provider's authorization endpoint.\nfunc SetAuthURLParam(key, value string) AuthCodeOption {\n\treturn setParam{key, value}\n}\n\n// AuthCodeURL returns a URL to OAuth 2.0 provider's consent page\n// that asks for permissions for the required scopes explicitly.\n//\n// State is an opaque value used by the client to maintain state between the\n// request and callback. The authorization server includes this value when\n// redirecting the user agent back to the client.\n//\n// Opts may include [AccessTypeOnline] or [AccessTypeOffline], as well\n// as [ApprovalForce].\n//\n// To protect against CSRF attacks, opts should include a PKCE challenge\n// (S256ChallengeOption). Not all servers support PKCE. An alternative is to\n// generate a random state parameter and verify it after exchange.\n// See https://datatracker.ietf.org/doc/html/rfc6749#section-10.12 (predating\n// PKCE), https://www.oauth.com/oauth2-servers/pkce/ and\n// https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-09.html#name-cross-site-request-forgery (describing both approaches)\nfunc (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {\n\tvar buf bytes.Buffer\n\tbuf.WriteString(c.Endpoint.AuthURL)\n\tv := url.Values{\n\t\t\"response_type\": {\"code\"},\n\t\t\"client_id\":     {c.ClientID},\n\t}\n\tif c.RedirectURL != \"\" {\n\t\tv.Set(\"redirect_uri\", c.RedirectURL)\n\t}\n\tif len(c.Scopes) > 0 {\n\t\tv.Set(\"scope\", strings.Join(c.Scopes, \" \"))\n\t}\n\tif state != \"\" {\n\t\tv.Set(\"state\", state)\n\t}\n\tfor _, opt := range opts {\n\t\topt.setValue(v)\n\t}\n\tif strings.Contains(c.Endpoint.AuthURL, \"?\") {\n\t\tbuf.WriteByte('&')\n\t} else {\n\t\tbuf.WriteByte('?')\n\t}\n\tbuf.WriteString(v.Encode())\n\treturn buf.String()\n}\n\n// PasswordCredentialsToken converts a resource owner username and password\n// pair into a token.\n//\n// Per the RFC, this grant type should only be used \"when there is a high\n// degree of trust between the resource owner and the client (e.g., the client\n// is part of the device operating system or a highly privileged application),\n// and when other authorization grant types are not available.\"\n// See https://tools.ietf.org/html/rfc6749#section-4.3 for more info.\n//\n// The provided context optionally controls which HTTP client is used. See the [HTTPClient] variable.\nfunc (c *Config) PasswordCredentialsToken(ctx context.Context, username, password string) (*Token, error) {\n\tv := url.Values{\n\t\t\"grant_type\": {\"password\"},\n\t\t\"username\":   {username},\n\t\t\"password\":   {password},\n\t}\n\tif len(c.Scopes) > 0 {\n\t\tv.Set(\"scope\", strings.Join(c.Scopes, \" \"))\n\t}\n\treturn retrieveToken(ctx, c, v)\n}\n\n// Exchange converts an authorization code into a token.\n//\n// It is used after a resource provider redirects the user back\n// to the Redirect URI (the URL obtained from AuthCodeURL).\n//\n// The provided context optionally controls which HTTP client is used. See the [HTTPClient] variable.\n//\n// The code will be in the [http.Request.FormValue](\"code\"). Before\n// calling Exchange, be sure to validate [http.Request.FormValue](\"state\") if you are\n// using it to protect against CSRF attacks.\n//\n// If using PKCE to protect against CSRF attacks, opts should include a\n// VerifierOption.\nfunc (c *Config) Exchange(ctx context.Context, code string, opts ...AuthCodeOption) (*Token, error) {\n\tv := url.Values{\n\t\t\"grant_type\": {\"authorization_code\"},\n\t\t\"code\":       {code},\n\t}\n\tif c.RedirectURL != \"\" {\n\t\tv.Set(\"redirect_uri\", c.RedirectURL)\n\t}\n\tfor _, opt := range opts {\n\t\topt.setValue(v)\n\t}\n\treturn retrieveToken(ctx, c, v)\n}\n\n// Client returns an HTTP client using the provided token.\n// The token will auto-refresh as necessary. The underlying\n// HTTP transport will be obtained using the provided context.\n// The returned client and its Transport should not be modified.\nfunc (c *Config) Client(ctx context.Context, t *Token) *http.Client {\n\treturn NewClient(ctx, c.TokenSource(ctx, t))\n}\n\n// TokenSource returns a [TokenSource] that returns t until t expires,\n// automatically refreshing it as necessary using the provided context.\n//\n// Most users will use [Config.Client] instead.\nfunc (c *Config) TokenSource(ctx context.Context, t *Token) TokenSource {\n\ttkr := &tokenRefresher{\n\t\tctx:  ctx,\n\t\tconf: c,\n\t}\n\tif t != nil {\n\t\ttkr.refreshToken = t.RefreshToken\n\t}\n\treturn &reuseTokenSource{\n\t\tt:   t,\n\t\tnew: tkr,\n\t}\n}\n\n// tokenRefresher is a TokenSource that makes \"grant_type=refresh_token\"\n// HTTP requests to renew a token using a RefreshToken.\ntype tokenRefresher struct {\n\tctx          context.Context // used to get HTTP requests\n\tconf         *Config\n\trefreshToken string\n}\n\n// WARNING: Token is not safe for concurrent access, as it\n// updates the tokenRefresher's refreshToken field.\n// Within this package, it is used by reuseTokenSource which\n// synchronizes calls to this method with its own mutex.\nfunc (tf *tokenRefresher) Token() (*Token, error) {\n\tif tf.refreshToken == \"\" {\n\t\treturn nil, errors.New(\"oauth2: token expired and refresh token is not set\")\n\t}\n\n\ttk, err := retrieveToken(tf.ctx, tf.conf, url.Values{\n\t\t\"grant_type\":    {\"refresh_token\"},\n\t\t\"refresh_token\": {tf.refreshToken},\n\t})\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif tf.refreshToken != tk.RefreshToken {\n\t\ttf.refreshToken = tk.RefreshToken\n\t}\n\treturn tk, nil\n}\n\n// reuseTokenSource is a TokenSource that holds a single token in memory\n// and validates its expiry before each call to retrieve it with\n// Token. If it's expired, it will be auto-refreshed using the\n// new TokenSource.\ntype reuseTokenSource struct {\n\tnew TokenSource // called when t is expired.\n\n\tmu sync.Mutex // guards t\n\tt  *Token\n\n\texpiryDelta time.Duration\n}\n\n// Token returns the current token if it's still valid, else will\n// refresh the current token and return the new one.\nfunc (s *reuseTokenSource) Token() (*Token, error) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\tif s.t.Valid() {\n\t\treturn s.t, nil\n\t}\n\tt, err := s.new.Token()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tt.expiryDelta = s.expiryDelta\n\ts.t = t\n\treturn t, nil\n}\n\n// StaticTokenSource returns a [TokenSource] that always returns the same token.\n// Because the provided token t is never refreshed, StaticTokenSource is only\n// useful for tokens that never expire.\nfunc StaticTokenSource(t *Token) TokenSource {\n\treturn staticTokenSource{t}\n}\n\n// staticTokenSource is a TokenSource that always returns the same Token.\ntype staticTokenSource struct {\n\tt *Token\n}\n\nfunc (s staticTokenSource) Token() (*Token, error) {\n\treturn s.t, nil\n}\n\n// HTTPClient is the context key to use with [context.WithValue]\n// to associate a [*http.Client] value with a context.\nvar HTTPClient internal.ContextKey\n\n// NewClient creates an [*http.Client] from a [context.Context] and [TokenSource].\n// The returned client is not valid beyond the lifetime of the context.\n//\n// Note that if a custom [*http.Client] is provided via the [context.Context] it\n// is used only for token acquisition and is not used to configure the\n// [*http.Client] returned from NewClient.\n//\n// As a special case, if src is nil, a non-OAuth2 client is returned\n// using the provided context. This exists to support related OAuth2\n// packages.\nfunc NewClient(ctx context.Context, src TokenSource) *http.Client {\n\tif src == nil {\n\t\treturn internal.ContextClient(ctx)\n\t}\n\tcc := internal.ContextClient(ctx)\n\treturn &http.Client{\n\t\tTransport: &Transport{\n\t\t\tBase:   cc.Transport,\n\t\t\tSource: ReuseTokenSource(nil, src),\n\t\t},\n\t\tCheckRedirect: cc.CheckRedirect,\n\t\tJar:           cc.Jar,\n\t\tTimeout:       cc.Timeout,\n\t}\n}\n\n// ReuseTokenSource returns a [TokenSource] which repeatedly returns the\n// same token as long as it's valid, starting with t.\n// When its cached token is invalid, a new token is obtained from src.\n//\n// ReuseTokenSource is typically used to reuse tokens from a cache\n// (such as a file on disk) between runs of a program, rather than\n// obtaining new tokens unnecessarily.\n//\n// The initial token t may be nil, in which case the [TokenSource] is\n// wrapped in a caching version if it isn't one already. This also\n// means it's always safe to wrap ReuseTokenSource around any other\n// [TokenSource] without adverse effects.\nfunc ReuseTokenSource(t *Token, src TokenSource) TokenSource {\n\t// Don't wrap a reuseTokenSource in itself. That would work,\n\t// but cause an unnecessary number of mutex operations.\n\t// Just build the equivalent one.\n\tif rt, ok := src.(*reuseTokenSource); ok {\n\t\tif t == nil {\n\t\t\t// Just use it directly.\n\t\t\treturn rt\n\t\t}\n\t\tsrc = rt.new\n\t}\n\treturn &reuseTokenSource{\n\t\tt:   t,\n\t\tnew: src,\n\t}\n}\n\n// ReuseTokenSourceWithExpiry returns a [TokenSource] that acts in the same manner as the\n// [TokenSource] returned by [ReuseTokenSource], except the expiry buffer is\n// configurable. The expiration time of a token is calculated as\n// t.Expiry.Add(-earlyExpiry).\nfunc ReuseTokenSourceWithExpiry(t *Token, src TokenSource, earlyExpiry time.Duration) TokenSource {\n\t// Don't wrap a reuseTokenSource in itself. That would work,\n\t// but cause an unnecessary number of mutex operations.\n\t// Just build the equivalent one.\n\tif rt, ok := src.(*reuseTokenSource); ok {\n\t\tif t == nil {\n\t\t\t// Just use it directly, but set the expiryDelta to earlyExpiry,\n\t\t\t// so the behavior matches what the user expects.\n\t\t\trt.expiryDelta = earlyExpiry\n\t\t\treturn rt\n\t\t}\n\t\tsrc = rt.new\n\t}\n\tif t != nil {\n\t\tt.expiryDelta = earlyExpiry\n\t}\n\treturn &reuseTokenSource{\n\t\tt:           t,\n\t\tnew:         src,\n\t\texpiryDelta: earlyExpiry,\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/oauth2/pkce.go",
    "content": "// Copyright 2023 The Go 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 oauth2\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/sha256\"\n\t\"encoding/base64\"\n\t\"net/url\"\n)\n\nconst (\n\tcodeChallengeKey       = \"code_challenge\"\n\tcodeChallengeMethodKey = \"code_challenge_method\"\n\tcodeVerifierKey        = \"code_verifier\"\n)\n\n// GenerateVerifier generates a PKCE code verifier with 32 octets of randomness.\n// This follows recommendations in RFC 7636.\n//\n// A fresh verifier should be generated for each authorization.\n// The resulting verifier should be passed to [Config.AuthCodeURL] or [Config.DeviceAuth]\n// with [S256ChallengeOption], and to [Config.Exchange] or [Config.DeviceAccessToken]\n// with [VerifierOption].\nfunc GenerateVerifier() string {\n\t// \"RECOMMENDED that the output of a suitable random number generator be\n\t// used to create a 32-octet sequence.  The octet sequence is then\n\t// base64url-encoded to produce a 43-octet URL-safe string to use as the\n\t// code verifier.\"\n\t// https://datatracker.ietf.org/doc/html/rfc7636#section-4.1\n\tdata := make([]byte, 32)\n\tif _, err := rand.Read(data); err != nil {\n\t\tpanic(err)\n\t}\n\treturn base64.RawURLEncoding.EncodeToString(data)\n}\n\n// VerifierOption returns a PKCE code verifier [AuthCodeOption]. It should only be\n// passed to [Config.Exchange] or [Config.DeviceAccessToken].\nfunc VerifierOption(verifier string) AuthCodeOption {\n\treturn setParam{k: codeVerifierKey, v: verifier}\n}\n\n// S256ChallengeFromVerifier returns a PKCE code challenge derived from verifier with method S256.\n//\n// Prefer to use [S256ChallengeOption] where possible.\nfunc S256ChallengeFromVerifier(verifier string) string {\n\tsha := sha256.Sum256([]byte(verifier))\n\treturn base64.RawURLEncoding.EncodeToString(sha[:])\n}\n\n// S256ChallengeOption derives a PKCE code challenge derived from verifier with\n// method S256. It should be passed to [Config.AuthCodeURL] or [Config.DeviceAuth]\n// only.\nfunc S256ChallengeOption(verifier string) AuthCodeOption {\n\treturn challengeOption{\n\t\tchallenge_method: \"S256\",\n\t\tchallenge:        S256ChallengeFromVerifier(verifier),\n\t}\n}\n\ntype challengeOption struct{ challenge_method, challenge string }\n\nfunc (p challengeOption) setValue(m url.Values) {\n\tm.Set(codeChallengeMethodKey, p.challenge_method)\n\tm.Set(codeChallengeKey, p.challenge)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/oauth2/token.go",
    "content": "// Copyright 2014 The Go 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 oauth2\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"golang.org/x/oauth2/internal\"\n)\n\n// defaultExpiryDelta determines how earlier a token should be considered\n// expired than its actual expiration time. It is used to avoid late\n// expirations due to client-server time mismatches.\nconst defaultExpiryDelta = 10 * time.Second\n\n// Token represents the credentials used to authorize\n// the requests to access protected resources on the OAuth 2.0\n// provider's backend.\n//\n// Most users of this package should not access fields of Token\n// directly. They're exported mostly for use by related packages\n// implementing derivative OAuth2 flows.\ntype Token struct {\n\t// AccessToken is the token that authorizes and authenticates\n\t// the requests.\n\tAccessToken string `json:\"access_token\"`\n\n\t// TokenType is the type of token.\n\t// The Type method returns either this or \"Bearer\", the default.\n\tTokenType string `json:\"token_type,omitempty\"`\n\n\t// RefreshToken is a token that's used by the application\n\t// (as opposed to the user) to refresh the access token\n\t// if it expires.\n\tRefreshToken string `json:\"refresh_token,omitempty\"`\n\n\t// Expiry is the optional expiration time of the access token.\n\t//\n\t// If zero, [TokenSource] implementations will reuse the same\n\t// token forever and RefreshToken or equivalent\n\t// mechanisms for that TokenSource will not be used.\n\tExpiry time.Time `json:\"expiry,omitempty\"`\n\n\t// ExpiresIn is the OAuth2 wire format \"expires_in\" field,\n\t// which specifies how many seconds later the token expires,\n\t// relative to an unknown time base approximately around \"now\".\n\t// It is the application's responsibility to populate\n\t// `Expiry` from `ExpiresIn` when required.\n\tExpiresIn int64 `json:\"expires_in,omitempty\"`\n\n\t// raw optionally contains extra metadata from the server\n\t// when updating a token.\n\traw any\n\n\t// expiryDelta is used to calculate when a token is considered\n\t// expired, by subtracting from Expiry. If zero, defaultExpiryDelta\n\t// is used.\n\texpiryDelta time.Duration\n}\n\n// Type returns t.TokenType if non-empty, else \"Bearer\".\nfunc (t *Token) Type() string {\n\tif strings.EqualFold(t.TokenType, \"bearer\") {\n\t\treturn \"Bearer\"\n\t}\n\tif strings.EqualFold(t.TokenType, \"mac\") {\n\t\treturn \"MAC\"\n\t}\n\tif strings.EqualFold(t.TokenType, \"basic\") {\n\t\treturn \"Basic\"\n\t}\n\tif t.TokenType != \"\" {\n\t\treturn t.TokenType\n\t}\n\treturn \"Bearer\"\n}\n\n// SetAuthHeader sets the Authorization header to r using the access\n// token in t.\n//\n// This method is unnecessary when using [Transport] or an HTTP Client\n// returned by this package.\nfunc (t *Token) SetAuthHeader(r *http.Request) {\n\tr.Header.Set(\"Authorization\", t.Type()+\" \"+t.AccessToken)\n}\n\n// WithExtra returns a new [Token] that's a clone of t, but using the\n// provided raw extra map. This is only intended for use by packages\n// implementing derivative OAuth2 flows.\nfunc (t *Token) WithExtra(extra any) *Token {\n\tt2 := new(Token)\n\t*t2 = *t\n\tt2.raw = extra\n\treturn t2\n}\n\n// Extra returns an extra field.\n// Extra fields are key-value pairs returned by the server as a\n// part of the token retrieval response.\nfunc (t *Token) Extra(key string) any {\n\tif raw, ok := t.raw.(map[string]any); ok {\n\t\treturn raw[key]\n\t}\n\n\tvals, ok := t.raw.(url.Values)\n\tif !ok {\n\t\treturn nil\n\t}\n\n\tv := vals.Get(key)\n\tswitch s := strings.TrimSpace(v); strings.Count(s, \".\") {\n\tcase 0: // Contains no \".\"; try to parse as int\n\t\tif i, err := strconv.ParseInt(s, 10, 64); err == nil {\n\t\t\treturn i\n\t\t}\n\tcase 1: // Contains a single \".\"; try to parse as float\n\t\tif f, err := strconv.ParseFloat(s, 64); err == nil {\n\t\t\treturn f\n\t\t}\n\t}\n\n\treturn v\n}\n\n// timeNow is time.Now but pulled out as a variable for tests.\nvar timeNow = time.Now\n\n// expired reports whether the token is expired.\n// t must be non-nil.\nfunc (t *Token) expired() bool {\n\tif t.Expiry.IsZero() {\n\t\treturn false\n\t}\n\n\texpiryDelta := defaultExpiryDelta\n\tif t.expiryDelta != 0 {\n\t\texpiryDelta = t.expiryDelta\n\t}\n\treturn t.Expiry.Round(0).Add(-expiryDelta).Before(timeNow())\n}\n\n// Valid reports whether t is non-nil, has an AccessToken, and is not expired.\nfunc (t *Token) Valid() bool {\n\treturn t != nil && t.AccessToken != \"\" && !t.expired()\n}\n\n// tokenFromInternal maps an *internal.Token struct into\n// a *Token struct.\nfunc tokenFromInternal(t *internal.Token) *Token {\n\tif t == nil {\n\t\treturn nil\n\t}\n\treturn &Token{\n\t\tAccessToken:  t.AccessToken,\n\t\tTokenType:    t.TokenType,\n\t\tRefreshToken: t.RefreshToken,\n\t\tExpiry:       t.Expiry,\n\t\tExpiresIn:    t.ExpiresIn,\n\t\traw:          t.Raw,\n\t}\n}\n\n// retrieveToken takes a *Config and uses that to retrieve an *internal.Token.\n// This token is then mapped from *internal.Token into an *oauth2.Token which is returned along\n// with an error.\nfunc retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) {\n\ttk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.Endpoint.TokenURL, v, internal.AuthStyle(c.Endpoint.AuthStyle), c.authStyleCache.Get())\n\tif err != nil {\n\t\tif rErr, ok := err.(*internal.RetrieveError); ok {\n\t\t\treturn nil, (*RetrieveError)(rErr)\n\t\t}\n\t\treturn nil, err\n\t}\n\treturn tokenFromInternal(tk), nil\n}\n\n// RetrieveError is the error returned when the token endpoint returns a\n// non-2XX HTTP status code or populates RFC 6749's 'error' parameter.\n// https://datatracker.ietf.org/doc/html/rfc6749#section-5.2\ntype RetrieveError struct {\n\tResponse *http.Response\n\t// Body is the body that was consumed by reading Response.Body.\n\t// It may be truncated.\n\tBody []byte\n\t// ErrorCode is RFC 6749's 'error' parameter.\n\tErrorCode string\n\t// ErrorDescription is RFC 6749's 'error_description' parameter.\n\tErrorDescription string\n\t// ErrorURI is RFC 6749's 'error_uri' parameter.\n\tErrorURI string\n}\n\nfunc (r *RetrieveError) Error() string {\n\tif r.ErrorCode != \"\" {\n\t\ts := fmt.Sprintf(\"oauth2: %q\", r.ErrorCode)\n\t\tif r.ErrorDescription != \"\" {\n\t\t\ts += fmt.Sprintf(\" %q\", r.ErrorDescription)\n\t\t}\n\t\tif r.ErrorURI != \"\" {\n\t\t\ts += fmt.Sprintf(\" %q\", r.ErrorURI)\n\t\t}\n\t\treturn s\n\t}\n\treturn fmt.Sprintf(\"oauth2: cannot fetch token: %v\\nResponse: %s\", r.Response.Status, r.Body)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/oauth2/transport.go",
    "content": "// Copyright 2014 The Go 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 oauth2\n\nimport (\n\t\"errors\"\n\t\"log\"\n\t\"net/http\"\n\t\"sync\"\n)\n\n// Transport is an [http.RoundTripper] that makes OAuth 2.0 HTTP requests,\n// wrapping a base [http.RoundTripper] and adding an Authorization header\n// with a token from the supplied [TokenSource].\n//\n// Transport is a low-level mechanism. Most code will use the\n// higher-level [Config.Client] method instead.\ntype Transport struct {\n\t// Source supplies the token to add to outgoing requests'\n\t// Authorization headers.\n\tSource TokenSource\n\n\t// Base is the base RoundTripper used to make HTTP requests.\n\t// If nil, http.DefaultTransport is used.\n\tBase http.RoundTripper\n}\n\n// RoundTrip authorizes and authenticates the request with an\n// access token from Transport's Source.\nfunc (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {\n\treqBodyClosed := false\n\tif req.Body != nil {\n\t\tdefer func() {\n\t\t\tif !reqBodyClosed {\n\t\t\t\treq.Body.Close()\n\t\t\t}\n\t\t}()\n\t}\n\n\tif t.Source == nil {\n\t\treturn nil, errors.New(\"oauth2: Transport's Source is nil\")\n\t}\n\ttoken, err := t.Source.Token()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treq2 := req.Clone(req.Context())\n\ttoken.SetAuthHeader(req2)\n\n\t// req.Body is assumed to be closed by the base RoundTripper.\n\treqBodyClosed = true\n\treturn t.base().RoundTrip(req2)\n}\n\nvar cancelOnce sync.Once\n\n// CancelRequest does nothing. It used to be a legacy cancellation mechanism\n// but now only it only logs on first use to warn that it's deprecated.\n//\n// Deprecated: use contexts for cancellation instead.\nfunc (t *Transport) CancelRequest(req *http.Request) {\n\tcancelOnce.Do(func() {\n\t\tlog.Printf(\"deprecated: golang.org/x/oauth2: Transport.CancelRequest no longer does anything; use contexts\")\n\t})\n}\n\nfunc (t *Transport) base() http.RoundTripper {\n\tif t.Base != nil {\n\t\treturn t.Base\n\t}\n\treturn http.DefaultTransport\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sync/LICENSE",
    "content": "Copyright 2009 The Go Authors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google LLC nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(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": "vendor/golang.org/x/sync/PATENTS",
    "content": "Additional IP Rights Grant (Patents)\n\n\"This implementation\" means the copyrightable works distributed by\nGoogle as part of the Go project.\n\nGoogle hereby grants to You a perpetual, worldwide, non-exclusive,\nno-charge, royalty-free, irrevocable (except as stated in this section)\npatent license to make, have made, use, offer to sell, sell, import,\ntransfer and otherwise run, modify and propagate the contents of this\nimplementation of Go, where such license applies only to those patent\nclaims, both currently owned or controlled by Google and acquired in\nthe future, licensable by Google that are necessarily infringed by this\nimplementation of Go.  This grant does not include claims that would be\ninfringed only as a consequence of further modification of this\nimplementation.  If you or your agent or exclusive licensee institute or\norder or agree to the institution of patent litigation against any\nentity (including a cross-claim or counterclaim in a lawsuit) alleging\nthat this implementation of Go or any code incorporated within this\nimplementation of Go constitutes direct or contributory patent\ninfringement, or inducement of patent infringement, then any patent\nrights granted to you under this License for this implementation of Go\nshall terminate as of the date such litigation is filed.\n"
  },
  {
    "path": "vendor/golang.org/x/sync/errgroup/errgroup.go",
    "content": "// Copyright 2016 The Go 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\n// Package errgroup provides synchronization, error propagation, and Context\n// cancelation for groups of goroutines working on subtasks of a common task.\n//\n// [errgroup.Group] is related to [sync.WaitGroup] but adds handling of tasks\n// returning errors.\npackage errgroup\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"runtime\"\n\t\"runtime/debug\"\n\t\"sync\"\n)\n\ntype token struct{}\n\n// A Group is a collection of goroutines working on subtasks that are part of\n// the same overall task. A Group should not be reused for different tasks.\n//\n// A zero Group is valid, has no limit on the number of active goroutines,\n// and does not cancel on error.\ntype Group struct {\n\tcancel func(error)\n\n\twg sync.WaitGroup\n\n\tsem chan token\n\n\terrOnce sync.Once\n\terr     error\n\n\tmu         sync.Mutex\n\tpanicValue any  // = PanicError | PanicValue; non-nil if some Group.Go goroutine panicked.\n\tabnormal   bool // some Group.Go goroutine terminated abnormally (panic or goexit).\n}\n\nfunc (g *Group) done() {\n\tif g.sem != nil {\n\t\t<-g.sem\n\t}\n\tg.wg.Done()\n}\n\n// WithContext returns a new Group and an associated Context derived from ctx.\n//\n// The derived Context is canceled the first time a function passed to Go\n// returns a non-nil error or the first time Wait returns, whichever occurs\n// first.\nfunc WithContext(ctx context.Context) (*Group, context.Context) {\n\tctx, cancel := context.WithCancelCause(ctx)\n\treturn &Group{cancel: cancel}, ctx\n}\n\n// Wait blocks until all function calls from the Go method have returned\n// normally, then returns the first non-nil error (if any) from them.\n//\n// If any of the calls panics, Wait panics with a [PanicValue];\n// and if any of them calls [runtime.Goexit], Wait calls runtime.Goexit.\nfunc (g *Group) Wait() error {\n\tg.wg.Wait()\n\tif g.cancel != nil {\n\t\tg.cancel(g.err)\n\t}\n\tif g.panicValue != nil {\n\t\tpanic(g.panicValue)\n\t}\n\tif g.abnormal {\n\t\truntime.Goexit()\n\t}\n\treturn g.err\n}\n\n// Go calls the given function in a new goroutine.\n// The first call to Go must happen before a Wait.\n// It blocks until the new goroutine can be added without the number of\n// active goroutines in the group exceeding the configured limit.\n//\n// It blocks until the new goroutine can be added without the number of\n// goroutines in the group exceeding the configured limit.\n//\n// The first goroutine in the group that returns a non-nil error, panics, or\n// invokes [runtime.Goexit] will cancel the associated Context, if any.\nfunc (g *Group) Go(f func() error) {\n\tif g.sem != nil {\n\t\tg.sem <- token{}\n\t}\n\n\tg.add(f)\n}\n\nfunc (g *Group) add(f func() error) {\n\tg.wg.Add(1)\n\tgo func() {\n\t\tdefer g.done()\n\t\tnormalReturn := false\n\t\tdefer func() {\n\t\t\tif normalReturn {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tv := recover()\n\t\t\tg.mu.Lock()\n\t\t\tdefer g.mu.Unlock()\n\t\t\tif !g.abnormal {\n\t\t\t\tif g.cancel != nil {\n\t\t\t\t\tg.cancel(g.err)\n\t\t\t\t}\n\t\t\t\tg.abnormal = true\n\t\t\t}\n\t\t\tif v != nil && g.panicValue == nil {\n\t\t\t\tswitch v := v.(type) {\n\t\t\t\tcase error:\n\t\t\t\t\tg.panicValue = PanicError{\n\t\t\t\t\t\tRecovered: v,\n\t\t\t\t\t\tStack:     debug.Stack(),\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tg.panicValue = PanicValue{\n\t\t\t\t\t\tRecovered: v,\n\t\t\t\t\t\tStack:     debug.Stack(),\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\n\t\terr := f()\n\t\tnormalReturn = true\n\t\tif err != nil {\n\t\t\tg.errOnce.Do(func() {\n\t\t\t\tg.err = err\n\t\t\t\tif g.cancel != nil {\n\t\t\t\t\tg.cancel(g.err)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}()\n}\n\n// TryGo calls the given function in a new goroutine only if the number of\n// active goroutines in the group is currently below the configured limit.\n//\n// The return value reports whether the goroutine was started.\nfunc (g *Group) TryGo(f func() error) bool {\n\tif g.sem != nil {\n\t\tselect {\n\t\tcase g.sem <- token{}:\n\t\t\t// Note: this allows barging iff channels in general allow barging.\n\t\tdefault:\n\t\t\treturn false\n\t\t}\n\t}\n\n\tg.add(f)\n\treturn true\n}\n\n// SetLimit limits the number of active goroutines in this group to at most n.\n// A negative value indicates no limit.\n// A limit of zero will prevent any new goroutines from being added.\n//\n// Any subsequent call to the Go method will block until it can add an active\n// goroutine without exceeding the configured limit.\n//\n// The limit must not be modified while any goroutines in the group are active.\nfunc (g *Group) SetLimit(n int) {\n\tif n < 0 {\n\t\tg.sem = nil\n\t\treturn\n\t}\n\tif len(g.sem) != 0 {\n\t\tpanic(fmt.Errorf(\"errgroup: modify limit while %v goroutines in the group are still active\", len(g.sem)))\n\t}\n\tg.sem = make(chan token, n)\n}\n\n// PanicError wraps an error recovered from an unhandled panic\n// when calling a function passed to Go or TryGo.\ntype PanicError struct {\n\tRecovered error\n\tStack     []byte // result of call to [debug.Stack]\n}\n\nfunc (p PanicError) Error() string {\n\t// A Go Error method conventionally does not include a stack dump, so omit it\n\t// here. (Callers who care can extract it from the Stack field.)\n\treturn fmt.Sprintf(\"recovered from errgroup.Group: %v\", p.Recovered)\n}\n\nfunc (p PanicError) Unwrap() error { return p.Recovered }\n\n// PanicValue wraps a value that does not implement the error interface,\n// recovered from an unhandled panic when calling a function passed to Go or\n// TryGo.\ntype PanicValue struct {\n\tRecovered any\n\tStack     []byte // result of call to [debug.Stack]\n}\n\nfunc (p PanicValue) String() string {\n\tif len(p.Stack) > 0 {\n\t\treturn fmt.Sprintf(\"recovered from errgroup.Group: %v\\n%s\", p.Recovered, p.Stack)\n\t}\n\treturn fmt.Sprintf(\"recovered from errgroup.Group: %v\", p.Recovered)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/LICENSE",
    "content": "Copyright 2009 The Go Authors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google LLC nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(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": "vendor/golang.org/x/sys/PATENTS",
    "content": "Additional IP Rights Grant (Patents)\n\n\"This implementation\" means the copyrightable works distributed by\nGoogle as part of the Go project.\n\nGoogle hereby grants to You a perpetual, worldwide, non-exclusive,\nno-charge, royalty-free, irrevocable (except as stated in this section)\npatent license to make, have made, use, offer to sell, sell, import,\ntransfer and otherwise run, modify and propagate the contents of this\nimplementation of Go, where such license applies only to those patent\nclaims, both currently owned or controlled by Google and acquired in\nthe future, licensable by Google that are necessarily infringed by this\nimplementation of Go.  This grant does not include claims that would be\ninfringed only as a consequence of further modification of this\nimplementation.  If you or your agent or exclusive licensee institute or\norder or agree to the institution of patent litigation against any\nentity (including a cross-claim or counterclaim in a lawsuit) alleging\nthat this implementation of Go or any code incorporated within this\nimplementation of Go constitutes direct or contributory patent\ninfringement, or inducement of patent infringement, then any patent\nrights granted to you under this License for this implementation of Go\nshall terminate as of the date such litigation is filed.\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s",
    "content": "// Copyright 2018 The Go 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\n//go:build gc\n\n#include \"textflag.h\"\n\n//\n// System calls for ppc64, AIX are implemented in runtime/syscall_aix.go\n//\n\nTEXT ·syscall6(SB),NOSPLIT,$0-88\n\tJMP\tsyscall·syscall6(SB)\n\nTEXT ·rawSyscall6(SB),NOSPLIT,$0-88\n\tJMP\tsyscall·rawSyscall6(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/asm_darwin_x86_gc.s",
    "content": "// Copyright 2024 The Go 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\n//go:build darwin && amd64 && gc\n\n#include \"textflag.h\"\n\nTEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0\n\tJMP\tlibc_sysctl(SB)\nGLOBL\t·libc_sysctl_trampoline_addr(SB), RODATA, $8\nDATA\t·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)\n\nTEXT libc_sysctlbyname_trampoline<>(SB),NOSPLIT,$0-0\n\tJMP\tlibc_sysctlbyname(SB)\nGLOBL\t·libc_sysctlbyname_trampoline_addr(SB), RODATA, $8\nDATA\t·libc_sysctlbyname_trampoline_addr(SB)/8, $libc_sysctlbyname_trampoline<>(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/byteorder.go",
    "content": "// Copyright 2019 The Go 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 cpu\n\nimport (\n\t\"runtime\"\n)\n\n// byteOrder is a subset of encoding/binary.ByteOrder.\ntype byteOrder interface {\n\tUint32([]byte) uint32\n\tUint64([]byte) uint64\n}\n\ntype littleEndian struct{}\ntype bigEndian struct{}\n\nfunc (littleEndian) Uint32(b []byte) uint32 {\n\t_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808\n\treturn uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24\n}\n\nfunc (littleEndian) Uint64(b []byte) uint64 {\n\t_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808\n\treturn uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |\n\t\tuint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56\n}\n\nfunc (bigEndian) Uint32(b []byte) uint32 {\n\t_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808\n\treturn uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24\n}\n\nfunc (bigEndian) Uint64(b []byte) uint64 {\n\t_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808\n\treturn uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |\n\t\tuint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56\n}\n\n// hostByteOrder returns littleEndian on little-endian machines and\n// bigEndian on big-endian machines.\nfunc hostByteOrder() byteOrder {\n\tswitch runtime.GOARCH {\n\tcase \"386\", \"amd64\", \"amd64p32\",\n\t\t\"alpha\",\n\t\t\"arm\", \"arm64\",\n\t\t\"loong64\",\n\t\t\"mipsle\", \"mips64le\", \"mips64p32le\",\n\t\t\"nios2\",\n\t\t\"ppc64le\",\n\t\t\"riscv\", \"riscv64\",\n\t\t\"sh\":\n\t\treturn littleEndian{}\n\tcase \"armbe\", \"arm64be\",\n\t\t\"m68k\",\n\t\t\"mips\", \"mips64\", \"mips64p32\",\n\t\t\"ppc\", \"ppc64\",\n\t\t\"s390\", \"s390x\",\n\t\t\"shbe\",\n\t\t\"sparc\", \"sparc64\":\n\t\treturn bigEndian{}\n\t}\n\tpanic(\"unknown architecture\")\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu.go",
    "content": "// Copyright 2018 The Go 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\n// Package cpu implements processor feature detection for\n// various CPU architectures.\npackage cpu\n\nimport (\n\t\"os\"\n\t\"strings\"\n)\n\n// Initialized reports whether the CPU features were initialized.\n//\n// For some GOOS/GOARCH combinations initialization of the CPU features depends\n// on reading an operating specific file, e.g. /proc/self/auxv on linux/arm\n// Initialized will report false if reading the file fails.\nvar Initialized bool\n\n// CacheLinePad is used to pad structs to avoid false sharing.\ntype CacheLinePad struct{ _ [cacheLineSize]byte }\n\n// X86 contains the supported CPU features of the\n// current X86/AMD64 platform. If the current platform\n// is not X86/AMD64 then all feature flags are false.\n//\n// X86 is padded to avoid false sharing. Further the HasAVX\n// and HasAVX2 are only set if the OS supports XMM and YMM\n// registers in addition to the CPUID feature bit being set.\nvar X86 struct {\n\t_                   CacheLinePad\n\tHasAES              bool // AES hardware implementation (AES NI)\n\tHasADX              bool // Multi-precision add-carry instruction extensions\n\tHasAVX              bool // Advanced vector extension\n\tHasAVX2             bool // Advanced vector extension 2\n\tHasAVX512           bool // Advanced vector extension 512\n\tHasAVX512F          bool // Advanced vector extension 512 Foundation Instructions\n\tHasAVX512CD         bool // Advanced vector extension 512 Conflict Detection Instructions\n\tHasAVX512ER         bool // Advanced vector extension 512 Exponential and Reciprocal Instructions\n\tHasAVX512PF         bool // Advanced vector extension 512 Prefetch Instructions\n\tHasAVX512VL         bool // Advanced vector extension 512 Vector Length Extensions\n\tHasAVX512BW         bool // Advanced vector extension 512 Byte and Word Instructions\n\tHasAVX512DQ         bool // Advanced vector extension 512 Doubleword and Quadword Instructions\n\tHasAVX512IFMA       bool // Advanced vector extension 512 Integer Fused Multiply Add\n\tHasAVX512VBMI       bool // Advanced vector extension 512 Vector Byte Manipulation Instructions\n\tHasAVX5124VNNIW     bool // Advanced vector extension 512 Vector Neural Network Instructions Word variable precision\n\tHasAVX5124FMAPS     bool // Advanced vector extension 512 Fused Multiply Accumulation Packed Single precision\n\tHasAVX512VPOPCNTDQ  bool // Advanced vector extension 512 Double and quad word population count instructions\n\tHasAVX512VPCLMULQDQ bool // Advanced vector extension 512 Vector carry-less multiply operations\n\tHasAVX512VNNI       bool // Advanced vector extension 512 Vector Neural Network Instructions\n\tHasAVX512GFNI       bool // Advanced vector extension 512 Galois field New Instructions\n\tHasAVX512VAES       bool // Advanced vector extension 512 Vector AES instructions\n\tHasAVX512VBMI2      bool // Advanced vector extension 512 Vector Byte Manipulation Instructions 2\n\tHasAVX512BITALG     bool // Advanced vector extension 512 Bit Algorithms\n\tHasAVX512BF16       bool // Advanced vector extension 512 BFloat16 Instructions\n\tHasAMXTile          bool // Advanced Matrix Extension Tile instructions\n\tHasAMXInt8          bool // Advanced Matrix Extension Int8 instructions\n\tHasAMXBF16          bool // Advanced Matrix Extension BFloat16 instructions\n\tHasBMI1             bool // Bit manipulation instruction set 1\n\tHasBMI2             bool // Bit manipulation instruction set 2\n\tHasCX16             bool // Compare and exchange 16 Bytes\n\tHasERMS             bool // Enhanced REP for MOVSB and STOSB\n\tHasFMA              bool // Fused-multiply-add instructions\n\tHasOSXSAVE          bool // OS supports XSAVE/XRESTOR for saving/restoring XMM registers.\n\tHasPCLMULQDQ        bool // PCLMULQDQ instruction - most often used for AES-GCM\n\tHasPOPCNT           bool // Hamming weight instruction POPCNT.\n\tHasRDRAND           bool // RDRAND instruction (on-chip random number generator)\n\tHasRDSEED           bool // RDSEED instruction (on-chip random number generator)\n\tHasSSE2             bool // Streaming SIMD extension 2 (always available on amd64)\n\tHasSSE3             bool // Streaming SIMD extension 3\n\tHasSSSE3            bool // Supplemental streaming SIMD extension 3\n\tHasSSE41            bool // Streaming SIMD extension 4 and 4.1\n\tHasSSE42            bool // Streaming SIMD extension 4 and 4.2\n\tHasAVXIFMA          bool // Advanced vector extension Integer Fused Multiply Add\n\tHasAVXVNNI          bool // Advanced vector extension Vector Neural Network Instructions\n\tHasAVXVNNIInt8      bool // Advanced vector extension Vector Neural Network Int8 instructions\n\t_                   CacheLinePad\n}\n\n// ARM64 contains the supported CPU features of the\n// current ARMv8(aarch64) platform. If the current platform\n// is not arm64 then all feature flags are false.\nvar ARM64 struct {\n\t_           CacheLinePad\n\tHasFP       bool // Floating-point instruction set (always available)\n\tHasASIMD    bool // Advanced SIMD (always available)\n\tHasEVTSTRM  bool // Event stream support\n\tHasAES      bool // AES hardware implementation\n\tHasPMULL    bool // Polynomial multiplication instruction set\n\tHasSHA1     bool // SHA1 hardware implementation\n\tHasSHA2     bool // SHA2 hardware implementation\n\tHasCRC32    bool // CRC32 hardware implementation\n\tHasATOMICS  bool // Atomic memory operation instruction set\n\tHasFPHP     bool // Half precision floating-point instruction set\n\tHasASIMDHP  bool // Advanced SIMD half precision instruction set\n\tHasCPUID    bool // CPUID identification scheme registers\n\tHasASIMDRDM bool // Rounding double multiply add/subtract instruction set\n\tHasJSCVT    bool // Javascript conversion from floating-point to integer\n\tHasFCMA     bool // Floating-point multiplication and addition of complex numbers\n\tHasLRCPC    bool // Release Consistent processor consistent support\n\tHasDCPOP    bool // Persistent memory support\n\tHasSHA3     bool // SHA3 hardware implementation\n\tHasSM3      bool // SM3 hardware implementation\n\tHasSM4      bool // SM4 hardware implementation\n\tHasASIMDDP  bool // Advanced SIMD double precision instruction set\n\tHasSHA512   bool // SHA512 hardware implementation\n\tHasSVE      bool // Scalable Vector Extensions\n\tHasSVE2     bool // Scalable Vector Extensions 2\n\tHasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32\n\tHasDIT      bool // Data Independent Timing support\n\tHasI8MM     bool // Advanced SIMD Int8 matrix multiplication instructions\n\t_           CacheLinePad\n}\n\n// ARM contains the supported CPU features of the current ARM (32-bit) platform.\n// All feature flags are false if:\n//  1. the current platform is not arm, or\n//  2. the current operating system is not Linux.\nvar ARM struct {\n\t_           CacheLinePad\n\tHasSWP      bool // SWP instruction support\n\tHasHALF     bool // Half-word load and store support\n\tHasTHUMB    bool // ARM Thumb instruction set\n\tHas26BIT    bool // Address space limited to 26-bits\n\tHasFASTMUL  bool // 32-bit operand, 64-bit result multiplication support\n\tHasFPA      bool // Floating point arithmetic support\n\tHasVFP      bool // Vector floating point support\n\tHasEDSP     bool // DSP Extensions support\n\tHasJAVA     bool // Java instruction set\n\tHasIWMMXT   bool // Intel Wireless MMX technology support\n\tHasCRUNCH   bool // MaverickCrunch context switching and handling\n\tHasTHUMBEE  bool // Thumb EE instruction set\n\tHasNEON     bool // NEON instruction set\n\tHasVFPv3    bool // Vector floating point version 3 support\n\tHasVFPv3D16 bool // Vector floating point version 3 D8-D15\n\tHasTLS      bool // Thread local storage support\n\tHasVFPv4    bool // Vector floating point version 4 support\n\tHasIDIVA    bool // Integer divide instruction support in ARM mode\n\tHasIDIVT    bool // Integer divide instruction support in Thumb mode\n\tHasVFPD32   bool // Vector floating point version 3 D15-D31\n\tHasLPAE     bool // Large Physical Address Extensions\n\tHasEVTSTRM  bool // Event stream support\n\tHasAES      bool // AES hardware implementation\n\tHasPMULL    bool // Polynomial multiplication instruction set\n\tHasSHA1     bool // SHA1 hardware implementation\n\tHasSHA2     bool // SHA2 hardware implementation\n\tHasCRC32    bool // CRC32 hardware implementation\n\t_           CacheLinePad\n}\n\n// The booleans in Loong64 contain the correspondingly named cpu feature bit.\n// The struct is padded to avoid false sharing.\nvar Loong64 struct {\n\t_         CacheLinePad\n\tHasLSX    bool // support 128-bit vector extension\n\tHasLASX   bool // support 256-bit vector extension\n\tHasCRC32  bool // support CRC instruction\n\tHasLAM_BH bool // support AM{SWAP/ADD}[_DB].{B/H} instruction\n\tHasLAMCAS bool // support AMCAS[_DB].{B/H/W/D} instruction\n\t_         CacheLinePad\n}\n\n// MIPS64X contains the supported CPU features of the current mips64/mips64le\n// platforms. If the current platform is not mips64/mips64le or the current\n// operating system is not Linux then all feature flags are false.\nvar MIPS64X struct {\n\t_      CacheLinePad\n\tHasMSA bool // MIPS SIMD architecture\n\t_      CacheLinePad\n}\n\n// PPC64 contains the supported CPU features of the current ppc64/ppc64le platforms.\n// If the current platform is not ppc64/ppc64le then all feature flags are false.\n//\n// For ppc64/ppc64le, it is safe to check only for ISA level starting on ISA v3.00,\n// since there are no optional categories. There are some exceptions that also\n// require kernel support to work (DARN, SCV), so there are feature bits for\n// those as well. The struct is padded to avoid false sharing.\nvar PPC64 struct {\n\t_        CacheLinePad\n\tHasDARN  bool // Hardware random number generator (requires kernel enablement)\n\tHasSCV   bool // Syscall vectored (requires kernel enablement)\n\tIsPOWER8 bool // ISA v2.07 (POWER8)\n\tIsPOWER9 bool // ISA v3.00 (POWER9), implies IsPOWER8\n\t_        CacheLinePad\n}\n\n// S390X contains the supported CPU features of the current IBM Z\n// (s390x) platform. If the current platform is not IBM Z then all\n// feature flags are false.\n//\n// S390X is padded to avoid false sharing. Further HasVX is only set\n// if the OS supports vector registers in addition to the STFLE\n// feature bit being set.\nvar S390X struct {\n\t_         CacheLinePad\n\tHasZARCH  bool // z/Architecture mode is active [mandatory]\n\tHasSTFLE  bool // store facility list extended\n\tHasLDISP  bool // long (20-bit) displacements\n\tHasEIMM   bool // 32-bit immediates\n\tHasDFP    bool // decimal floating point\n\tHasETF3EH bool // ETF-3 enhanced\n\tHasMSA    bool // message security assist (CPACF)\n\tHasAES    bool // KM-AES{128,192,256} functions\n\tHasAESCBC bool // KMC-AES{128,192,256} functions\n\tHasAESCTR bool // KMCTR-AES{128,192,256} functions\n\tHasAESGCM bool // KMA-GCM-AES{128,192,256} functions\n\tHasGHASH  bool // KIMD-GHASH function\n\tHasSHA1   bool // K{I,L}MD-SHA-1 functions\n\tHasSHA256 bool // K{I,L}MD-SHA-256 functions\n\tHasSHA512 bool // K{I,L}MD-SHA-512 functions\n\tHasSHA3   bool // K{I,L}MD-SHA3-{224,256,384,512} and K{I,L}MD-SHAKE-{128,256} functions\n\tHasVX     bool // vector facility\n\tHasVXE    bool // vector-enhancements facility 1\n\t_         CacheLinePad\n}\n\n// RISCV64 contains the supported CPU features and performance characteristics for riscv64\n// platforms. The booleans in RISCV64, with the exception of HasFastMisaligned, indicate\n// the presence of RISC-V extensions.\n//\n// It is safe to assume that all the RV64G extensions are supported and so they are omitted from\n// this structure. As riscv64 Go programs require at least RV64G, the code that populates\n// this structure cannot run successfully if some of the RV64G extensions are missing.\n// The struct is padded to avoid false sharing.\nvar RISCV64 struct {\n\t_                 CacheLinePad\n\tHasFastMisaligned bool // Fast misaligned accesses\n\tHasC              bool // Compressed instruction-set extension\n\tHasV              bool // Vector extension compatible with RVV 1.0\n\tHasZba            bool // Address generation instructions extension\n\tHasZbb            bool // Basic bit-manipulation extension\n\tHasZbs            bool // Single-bit instructions extension\n\tHasZvbb           bool // Vector Basic Bit-manipulation\n\tHasZvbc           bool // Vector Carryless Multiplication\n\tHasZvkb           bool // Vector Cryptography Bit-manipulation\n\tHasZvkt           bool // Vector Data-Independent Execution Latency\n\tHasZvkg           bool // Vector GCM/GMAC\n\tHasZvkn           bool // NIST Algorithm Suite (AES/SHA256/SHA512)\n\tHasZvknc          bool // NIST Algorithm Suite with carryless multiply\n\tHasZvkng          bool // NIST Algorithm Suite with GCM\n\tHasZvks           bool // ShangMi Algorithm Suite\n\tHasZvksc          bool // ShangMi Algorithm Suite with carryless multiplication\n\tHasZvksg          bool // ShangMi Algorithm Suite with GCM\n\t_                 CacheLinePad\n}\n\nfunc init() {\n\tarchInit()\n\tinitOptions()\n\tprocessOptions()\n}\n\n// options contains the cpu debug options that can be used in GODEBUG.\n// Options are arch dependent and are added by the arch specific initOptions functions.\n// Features that are mandatory for the specific GOARCH should have the Required field set\n// (e.g. SSE2 on amd64).\nvar options []option\n\n// Option names should be lower case. e.g. avx instead of AVX.\ntype option struct {\n\tName      string\n\tFeature   *bool\n\tSpecified bool // whether feature value was specified in GODEBUG\n\tEnable    bool // whether feature should be enabled\n\tRequired  bool // whether feature is mandatory and can not be disabled\n}\n\nfunc processOptions() {\n\tenv := os.Getenv(\"GODEBUG\")\nfield:\n\tfor env != \"\" {\n\t\tfield := \"\"\n\t\ti := strings.IndexByte(env, ',')\n\t\tif i < 0 {\n\t\t\tfield, env = env, \"\"\n\t\t} else {\n\t\t\tfield, env = env[:i], env[i+1:]\n\t\t}\n\t\tif len(field) < 4 || field[:4] != \"cpu.\" {\n\t\t\tcontinue\n\t\t}\n\t\ti = strings.IndexByte(field, '=')\n\t\tif i < 0 {\n\t\t\tprint(\"GODEBUG sys/cpu: no value specified for \\\"\", field, \"\\\"\\n\")\n\t\t\tcontinue\n\t\t}\n\t\tkey, value := field[4:i], field[i+1:] // e.g. \"SSE2\", \"on\"\n\n\t\tvar enable bool\n\t\tswitch value {\n\t\tcase \"on\":\n\t\t\tenable = true\n\t\tcase \"off\":\n\t\t\tenable = false\n\t\tdefault:\n\t\t\tprint(\"GODEBUG sys/cpu: value \\\"\", value, \"\\\" not supported for cpu option \\\"\", key, \"\\\"\\n\")\n\t\t\tcontinue field\n\t\t}\n\n\t\tif key == \"all\" {\n\t\t\tfor i := range options {\n\t\t\t\toptions[i].Specified = true\n\t\t\t\toptions[i].Enable = enable || options[i].Required\n\t\t\t}\n\t\t\tcontinue field\n\t\t}\n\n\t\tfor i := range options {\n\t\t\tif options[i].Name == key {\n\t\t\t\toptions[i].Specified = true\n\t\t\t\toptions[i].Enable = enable\n\t\t\t\tcontinue field\n\t\t\t}\n\t\t}\n\n\t\tprint(\"GODEBUG sys/cpu: unknown cpu feature \\\"\", key, \"\\\"\\n\")\n\t}\n\n\tfor _, o := range options {\n\t\tif !o.Specified {\n\t\t\tcontinue\n\t\t}\n\n\t\tif o.Enable && !*o.Feature {\n\t\t\tprint(\"GODEBUG sys/cpu: can not enable \\\"\", o.Name, \"\\\", missing CPU support\\n\")\n\t\t\tcontinue\n\t\t}\n\n\t\tif !o.Enable && o.Required {\n\t\t\tprint(\"GODEBUG sys/cpu: can not disable \\\"\", o.Name, \"\\\", required CPU feature\\n\")\n\t\t\tcontinue\n\t\t}\n\n\t\t*o.Feature = o.Enable\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_aix.go",
    "content": "// Copyright 2019 The Go 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\n//go:build aix\n\npackage cpu\n\nconst (\n\t// getsystemcfg constants\n\t_SC_IMPL     = 2\n\t_IMPL_POWER8 = 0x10000\n\t_IMPL_POWER9 = 0x20000\n)\n\nfunc archInit() {\n\timpl := getsystemcfg(_SC_IMPL)\n\tif impl&_IMPL_POWER8 != 0 {\n\t\tPPC64.IsPOWER8 = true\n\t}\n\tif impl&_IMPL_POWER9 != 0 {\n\t\tPPC64.IsPOWER8 = true\n\t\tPPC64.IsPOWER9 = true\n\t}\n\n\tInitialized = true\n}\n\nfunc getsystemcfg(label int) (n uint64) {\n\tr0, _ := callgetsystemcfg(label)\n\tn = uint64(r0)\n\treturn\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_arm.go",
    "content": "// Copyright 2018 The Go 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 cpu\n\nconst cacheLineSize = 32\n\n// HWCAP/HWCAP2 bits.\n// These are specific to Linux.\nconst (\n\thwcap_SWP       = 1 << 0\n\thwcap_HALF      = 1 << 1\n\thwcap_THUMB     = 1 << 2\n\thwcap_26BIT     = 1 << 3\n\thwcap_FAST_MULT = 1 << 4\n\thwcap_FPA       = 1 << 5\n\thwcap_VFP       = 1 << 6\n\thwcap_EDSP      = 1 << 7\n\thwcap_JAVA      = 1 << 8\n\thwcap_IWMMXT    = 1 << 9\n\thwcap_CRUNCH    = 1 << 10\n\thwcap_THUMBEE   = 1 << 11\n\thwcap_NEON      = 1 << 12\n\thwcap_VFPv3     = 1 << 13\n\thwcap_VFPv3D16  = 1 << 14\n\thwcap_TLS       = 1 << 15\n\thwcap_VFPv4     = 1 << 16\n\thwcap_IDIVA     = 1 << 17\n\thwcap_IDIVT     = 1 << 18\n\thwcap_VFPD32    = 1 << 19\n\thwcap_LPAE      = 1 << 20\n\thwcap_EVTSTRM   = 1 << 21\n\n\thwcap2_AES   = 1 << 0\n\thwcap2_PMULL = 1 << 1\n\thwcap2_SHA1  = 1 << 2\n\thwcap2_SHA2  = 1 << 3\n\thwcap2_CRC32 = 1 << 4\n)\n\nfunc initOptions() {\n\toptions = []option{\n\t\t{Name: \"pmull\", Feature: &ARM.HasPMULL},\n\t\t{Name: \"sha1\", Feature: &ARM.HasSHA1},\n\t\t{Name: \"sha2\", Feature: &ARM.HasSHA2},\n\t\t{Name: \"swp\", Feature: &ARM.HasSWP},\n\t\t{Name: \"thumb\", Feature: &ARM.HasTHUMB},\n\t\t{Name: \"thumbee\", Feature: &ARM.HasTHUMBEE},\n\t\t{Name: \"tls\", Feature: &ARM.HasTLS},\n\t\t{Name: \"vfp\", Feature: &ARM.HasVFP},\n\t\t{Name: \"vfpd32\", Feature: &ARM.HasVFPD32},\n\t\t{Name: \"vfpv3\", Feature: &ARM.HasVFPv3},\n\t\t{Name: \"vfpv3d16\", Feature: &ARM.HasVFPv3D16},\n\t\t{Name: \"vfpv4\", Feature: &ARM.HasVFPv4},\n\t\t{Name: \"half\", Feature: &ARM.HasHALF},\n\t\t{Name: \"26bit\", Feature: &ARM.Has26BIT},\n\t\t{Name: \"fastmul\", Feature: &ARM.HasFASTMUL},\n\t\t{Name: \"fpa\", Feature: &ARM.HasFPA},\n\t\t{Name: \"edsp\", Feature: &ARM.HasEDSP},\n\t\t{Name: \"java\", Feature: &ARM.HasJAVA},\n\t\t{Name: \"iwmmxt\", Feature: &ARM.HasIWMMXT},\n\t\t{Name: \"crunch\", Feature: &ARM.HasCRUNCH},\n\t\t{Name: \"neon\", Feature: &ARM.HasNEON},\n\t\t{Name: \"idivt\", Feature: &ARM.HasIDIVT},\n\t\t{Name: \"idiva\", Feature: &ARM.HasIDIVA},\n\t\t{Name: \"lpae\", Feature: &ARM.HasLPAE},\n\t\t{Name: \"evtstrm\", Feature: &ARM.HasEVTSTRM},\n\t\t{Name: \"aes\", Feature: &ARM.HasAES},\n\t\t{Name: \"crc32\", Feature: &ARM.HasCRC32},\n\t}\n\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_arm64.go",
    "content": "// Copyright 2019 The Go 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 cpu\n\nimport \"runtime\"\n\n// cacheLineSize is used to prevent false sharing of cache lines.\n// We choose 128 because Apple Silicon, a.k.a. M1, has 128-byte cache line size.\n// It doesn't cost much and is much more future-proof.\nconst cacheLineSize = 128\n\nfunc initOptions() {\n\toptions = []option{\n\t\t{Name: \"fp\", Feature: &ARM64.HasFP},\n\t\t{Name: \"asimd\", Feature: &ARM64.HasASIMD},\n\t\t{Name: \"evstrm\", Feature: &ARM64.HasEVTSTRM},\n\t\t{Name: \"aes\", Feature: &ARM64.HasAES},\n\t\t{Name: \"fphp\", Feature: &ARM64.HasFPHP},\n\t\t{Name: \"jscvt\", Feature: &ARM64.HasJSCVT},\n\t\t{Name: \"lrcpc\", Feature: &ARM64.HasLRCPC},\n\t\t{Name: \"pmull\", Feature: &ARM64.HasPMULL},\n\t\t{Name: \"sha1\", Feature: &ARM64.HasSHA1},\n\t\t{Name: \"sha2\", Feature: &ARM64.HasSHA2},\n\t\t{Name: \"sha3\", Feature: &ARM64.HasSHA3},\n\t\t{Name: \"sha512\", Feature: &ARM64.HasSHA512},\n\t\t{Name: \"sm3\", Feature: &ARM64.HasSM3},\n\t\t{Name: \"sm4\", Feature: &ARM64.HasSM4},\n\t\t{Name: \"sve\", Feature: &ARM64.HasSVE},\n\t\t{Name: \"sve2\", Feature: &ARM64.HasSVE2},\n\t\t{Name: \"crc32\", Feature: &ARM64.HasCRC32},\n\t\t{Name: \"atomics\", Feature: &ARM64.HasATOMICS},\n\t\t{Name: \"asimdhp\", Feature: &ARM64.HasASIMDHP},\n\t\t{Name: \"cpuid\", Feature: &ARM64.HasCPUID},\n\t\t{Name: \"asimrdm\", Feature: &ARM64.HasASIMDRDM},\n\t\t{Name: \"fcma\", Feature: &ARM64.HasFCMA},\n\t\t{Name: \"dcpop\", Feature: &ARM64.HasDCPOP},\n\t\t{Name: \"asimddp\", Feature: &ARM64.HasASIMDDP},\n\t\t{Name: \"asimdfhm\", Feature: &ARM64.HasASIMDFHM},\n\t\t{Name: \"dit\", Feature: &ARM64.HasDIT},\n\t\t{Name: \"i8mm\", Feature: &ARM64.HasI8MM},\n\t}\n}\n\nfunc archInit() {\n\tswitch runtime.GOOS {\n\tcase \"freebsd\":\n\t\treadARM64Registers()\n\tcase \"linux\", \"netbsd\", \"openbsd\":\n\t\tdoinit()\n\tdefault:\n\t\t// Many platforms don't seem to allow reading these registers.\n\t\tsetMinimalFeatures()\n\t}\n}\n\n// setMinimalFeatures fakes the minimal ARM64 features expected by\n// TestARM64minimalFeatures.\nfunc setMinimalFeatures() {\n\tARM64.HasASIMD = true\n\tARM64.HasFP = true\n}\n\nfunc readARM64Registers() {\n\tInitialized = true\n\n\tparseARM64SystemRegisters(getisar0(), getisar1(), getpfr0())\n}\n\nfunc parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) {\n\t// ID_AA64ISAR0_EL1\n\tswitch extractBits(isar0, 4, 7) {\n\tcase 1:\n\t\tARM64.HasAES = true\n\tcase 2:\n\t\tARM64.HasAES = true\n\t\tARM64.HasPMULL = true\n\t}\n\n\tswitch extractBits(isar0, 8, 11) {\n\tcase 1:\n\t\tARM64.HasSHA1 = true\n\t}\n\n\tswitch extractBits(isar0, 12, 15) {\n\tcase 1:\n\t\tARM64.HasSHA2 = true\n\tcase 2:\n\t\tARM64.HasSHA2 = true\n\t\tARM64.HasSHA512 = true\n\t}\n\n\tswitch extractBits(isar0, 16, 19) {\n\tcase 1:\n\t\tARM64.HasCRC32 = true\n\t}\n\n\tswitch extractBits(isar0, 20, 23) {\n\tcase 2:\n\t\tARM64.HasATOMICS = true\n\t}\n\n\tswitch extractBits(isar0, 28, 31) {\n\tcase 1:\n\t\tARM64.HasASIMDRDM = true\n\t}\n\n\tswitch extractBits(isar0, 32, 35) {\n\tcase 1:\n\t\tARM64.HasSHA3 = true\n\t}\n\n\tswitch extractBits(isar0, 36, 39) {\n\tcase 1:\n\t\tARM64.HasSM3 = true\n\t}\n\n\tswitch extractBits(isar0, 40, 43) {\n\tcase 1:\n\t\tARM64.HasSM4 = true\n\t}\n\n\tswitch extractBits(isar0, 44, 47) {\n\tcase 1:\n\t\tARM64.HasASIMDDP = true\n\t}\n\n\t// ID_AA64ISAR1_EL1\n\tswitch extractBits(isar1, 0, 3) {\n\tcase 1:\n\t\tARM64.HasDCPOP = true\n\t}\n\n\tswitch extractBits(isar1, 12, 15) {\n\tcase 1:\n\t\tARM64.HasJSCVT = true\n\t}\n\n\tswitch extractBits(isar1, 16, 19) {\n\tcase 1:\n\t\tARM64.HasFCMA = true\n\t}\n\n\tswitch extractBits(isar1, 20, 23) {\n\tcase 1:\n\t\tARM64.HasLRCPC = true\n\t}\n\n\tswitch extractBits(isar1, 52, 55) {\n\tcase 1:\n\t\tARM64.HasI8MM = true\n\t}\n\n\t// ID_AA64PFR0_EL1\n\tswitch extractBits(pfr0, 16, 19) {\n\tcase 0:\n\t\tARM64.HasFP = true\n\tcase 1:\n\t\tARM64.HasFP = true\n\t\tARM64.HasFPHP = true\n\t}\n\n\tswitch extractBits(pfr0, 20, 23) {\n\tcase 0:\n\t\tARM64.HasASIMD = true\n\tcase 1:\n\t\tARM64.HasASIMD = true\n\t\tARM64.HasASIMDHP = true\n\t}\n\n\tswitch extractBits(pfr0, 32, 35) {\n\tcase 1:\n\t\tARM64.HasSVE = true\n\n\t\tparseARM64SVERegister(getzfr0())\n\t}\n\n\tswitch extractBits(pfr0, 48, 51) {\n\tcase 1:\n\t\tARM64.HasDIT = true\n\t}\n}\n\nfunc parseARM64SVERegister(zfr0 uint64) {\n\tswitch extractBits(zfr0, 0, 3) {\n\tcase 1:\n\t\tARM64.HasSVE2 = true\n\t}\n}\n\nfunc extractBits(data uint64, start, end uint) uint {\n\treturn (uint)(data>>start) & ((1 << (end - start + 1)) - 1)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_arm64.s",
    "content": "// Copyright 2019 The Go 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\n//go:build gc\n\n#include \"textflag.h\"\n\n// func getisar0() uint64\nTEXT ·getisar0(SB),NOSPLIT,$0-8\n\t// get Instruction Set Attributes 0 into x0\n\tMRS\tID_AA64ISAR0_EL1, R0\n\tMOVD\tR0, ret+0(FP)\n\tRET\n\n// func getisar1() uint64\nTEXT ·getisar1(SB),NOSPLIT,$0-8\n\t// get Instruction Set Attributes 1 into x0\n\tMRS\tID_AA64ISAR1_EL1, R0\n\tMOVD\tR0, ret+0(FP)\n\tRET\n\n// func getpfr0() uint64\nTEXT ·getpfr0(SB),NOSPLIT,$0-8\n\t// get Processor Feature Register 0 into x0\n\tMRS\tID_AA64PFR0_EL1, R0\n\tMOVD\tR0, ret+0(FP)\n\tRET\n\n// func getzfr0() uint64\nTEXT ·getzfr0(SB),NOSPLIT,$0-8\n\t// get SVE Feature Register 0 into x0\n\tMRS\tID_AA64ZFR0_EL1, R0\n\tMOVD\tR0, ret+0(FP)\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_darwin_x86.go",
    "content": "// Copyright 2024 The Go 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\n//go:build darwin && amd64 && gc\n\npackage cpu\n\n// darwinSupportsAVX512 checks Darwin kernel for AVX512 support via sysctl\n// call (see issue 43089). It also restricts AVX512 support for Darwin to\n// kernel version 21.3.0 (MacOS 12.2.0) or later (see issue 49233).\n//\n// Background:\n// Darwin implements a special mechanism to economize on thread state when\n// AVX512 specific registers are not in use. This scheme minimizes state when\n// preempting threads that haven't yet used any AVX512 instructions, but adds\n// special requirements to check for AVX512 hardware support at runtime (e.g.\n// via sysctl call or commpage inspection). See issue 43089 and link below for\n// full background:\n// https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.1.10/osfmk/i386/fpu.c#L214-L240\n//\n// Additionally, all versions of the Darwin kernel from 19.6.0 through 21.2.0\n// (corresponding to MacOS 10.15.6 - 12.1) have a bug that can cause corruption\n// of the AVX512 mask registers (K0-K7) upon signal return. For this reason\n// AVX512 is considered unsafe to use on Darwin for kernel versions prior to\n// 21.3.0, where a fix has been confirmed. See issue 49233 for full background.\nfunc darwinSupportsAVX512() bool {\n\treturn darwinSysctlEnabled([]byte(\"hw.optional.avx512f\\x00\")) && darwinKernelVersionCheck(21, 3, 0)\n}\n\n// Ensure Darwin kernel version is at least major.minor.patch, avoiding dependencies\nfunc darwinKernelVersionCheck(major, minor, patch int) bool {\n\tvar release [256]byte\n\terr := darwinOSRelease(&release)\n\tif err != nil {\n\t\treturn false\n\t}\n\n\tvar mmp [3]int\n\tc := 0\nLoop:\n\tfor _, b := range release[:] {\n\t\tswitch {\n\t\tcase b >= '0' && b <= '9':\n\t\t\tmmp[c] = 10*mmp[c] + int(b-'0')\n\t\tcase b == '.':\n\t\t\tc++\n\t\t\tif c > 2 {\n\t\t\t\treturn false\n\t\t\t}\n\t\tcase b == 0:\n\t\t\tbreak Loop\n\t\tdefault:\n\t\t\treturn false\n\t\t}\n\t}\n\tif c != 2 {\n\t\treturn false\n\t}\n\treturn mmp[0] > major || mmp[0] == major && (mmp[1] > minor || mmp[1] == minor && mmp[2] >= patch)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go",
    "content": "// Copyright 2019 The Go 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\n//go:build gc\n\npackage cpu\n\nfunc getisar0() uint64\nfunc getisar1() uint64\nfunc getpfr0() uint64\nfunc getzfr0() uint64\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go",
    "content": "// Copyright 2019 The Go 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\n//go:build gc\n\npackage cpu\n\n// haveAsmFunctions reports whether the other functions in this file can\n// be safely called.\nfunc haveAsmFunctions() bool { return true }\n\n// The following feature detection functions are defined in cpu_s390x.s.\n// They are likely to be expensive to call so the results should be cached.\nfunc stfle() facilityList\nfunc kmQuery() queryResult\nfunc kmcQuery() queryResult\nfunc kmctrQuery() queryResult\nfunc kmaQuery() queryResult\nfunc kimdQuery() queryResult\nfunc klmdQuery() queryResult\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_gc_x86.go",
    "content": "// Copyright 2018 The Go 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\n//go:build (386 || amd64 || amd64p32) && gc\n\npackage cpu\n\n// cpuid is implemented in cpu_gc_x86.s for gc compiler\n// and in cpu_gccgo.c for gccgo.\nfunc cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)\n\n// xgetbv with ecx = 0 is implemented in cpu_gc_x86.s for gc compiler\n// and in cpu_gccgo.c for gccgo.\nfunc xgetbv() (eax, edx uint32)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_gc_x86.s",
    "content": "// Copyright 2018 The Go 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\n//go:build (386 || amd64 || amd64p32) && gc\n\n#include \"textflag.h\"\n\n// func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)\nTEXT ·cpuid(SB), NOSPLIT, $0-24\n\tMOVL eaxArg+0(FP), AX\n\tMOVL ecxArg+4(FP), CX\n\tCPUID\n\tMOVL AX, eax+8(FP)\n\tMOVL BX, ebx+12(FP)\n\tMOVL CX, ecx+16(FP)\n\tMOVL DX, edx+20(FP)\n\tRET\n\n// func xgetbv() (eax, edx uint32)\nTEXT ·xgetbv(SB), NOSPLIT, $0-8\n\tMOVL $0, CX\n\tXGETBV\n\tMOVL AX, eax+0(FP)\n\tMOVL DX, edx+4(FP)\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go",
    "content": "// Copyright 2019 The Go 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\n//go:build gccgo\n\npackage cpu\n\nfunc getisar0() uint64 { return 0 }\nfunc getisar1() uint64 { return 0 }\nfunc getpfr0() uint64  { return 0 }\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go",
    "content": "// Copyright 2019 The Go 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\n//go:build gccgo\n\npackage cpu\n\n// haveAsmFunctions reports whether the other functions in this file can\n// be safely called.\nfunc haveAsmFunctions() bool { return false }\n\n// TODO(mundaym): the following feature detection functions are currently\n// stubs. See https://golang.org/cl/162887 for how to fix this.\n// They are likely to be expensive to call so the results should be cached.\nfunc stfle() facilityList     { panic(\"not implemented for gccgo\") }\nfunc kmQuery() queryResult    { panic(\"not implemented for gccgo\") }\nfunc kmcQuery() queryResult   { panic(\"not implemented for gccgo\") }\nfunc kmctrQuery() queryResult { panic(\"not implemented for gccgo\") }\nfunc kmaQuery() queryResult   { panic(\"not implemented for gccgo\") }\nfunc kimdQuery() queryResult  { panic(\"not implemented for gccgo\") }\nfunc klmdQuery() queryResult  { panic(\"not implemented for gccgo\") }\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c",
    "content": "// Copyright 2018 The Go 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\n//go:build (386 || amd64 || amd64p32) && gccgo\n\n#include <cpuid.h>\n#include <stdint.h>\n#include <x86intrin.h>\n\n// Need to wrap __get_cpuid_count because it's declared as static.\nint\ngccgoGetCpuidCount(uint32_t leaf, uint32_t subleaf,\n                   uint32_t *eax, uint32_t *ebx,\n                   uint32_t *ecx, uint32_t *edx)\n{\n\treturn __get_cpuid_count(leaf, subleaf, eax, ebx, ecx, edx);\n}\n\n#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n#pragma GCC push_options\n#pragma GCC target(\"xsave\")\n#pragma clang attribute push (__attribute__((target(\"xsave\"))), apply_to=function)\n\n// xgetbv reads the contents of an XCR (Extended Control Register)\n// specified in the ECX register into registers EDX:EAX.\n// Currently, the only supported value for XCR is 0.\nvoid\ngccgoXgetbv(uint32_t *eax, uint32_t *edx)\n{\n\tuint64_t v = _xgetbv(0);\n\t*eax = v & 0xffffffff;\n\t*edx = v >> 32;\n}\n\n#pragma clang attribute pop\n#pragma GCC pop_options\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go",
    "content": "// Copyright 2018 The Go 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\n//go:build (386 || amd64 || amd64p32) && gccgo\n\npackage cpu\n\n//extern gccgoGetCpuidCount\nfunc gccgoGetCpuidCount(eaxArg, ecxArg uint32, eax, ebx, ecx, edx *uint32)\n\nfunc cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) {\n\tvar a, b, c, d uint32\n\tgccgoGetCpuidCount(eaxArg, ecxArg, &a, &b, &c, &d)\n\treturn a, b, c, d\n}\n\n//extern gccgoXgetbv\nfunc gccgoXgetbv(eax, edx *uint32)\n\nfunc xgetbv() (eax, edx uint32) {\n\tvar a, d uint32\n\tgccgoXgetbv(&a, &d)\n\treturn a, d\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_linux.go",
    "content": "// Copyright 2018 The Go 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\n//go:build !386 && !amd64 && !amd64p32 && !arm64\n\npackage cpu\n\nfunc archInit() {\n\tif err := readHWCAP(); err != nil {\n\t\treturn\n\t}\n\tdoinit()\n\tInitialized = true\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_linux_arm.go",
    "content": "// Copyright 2019 The Go 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 cpu\n\nfunc doinit() {\n\tARM.HasSWP = isSet(hwCap, hwcap_SWP)\n\tARM.HasHALF = isSet(hwCap, hwcap_HALF)\n\tARM.HasTHUMB = isSet(hwCap, hwcap_THUMB)\n\tARM.Has26BIT = isSet(hwCap, hwcap_26BIT)\n\tARM.HasFASTMUL = isSet(hwCap, hwcap_FAST_MULT)\n\tARM.HasFPA = isSet(hwCap, hwcap_FPA)\n\tARM.HasVFP = isSet(hwCap, hwcap_VFP)\n\tARM.HasEDSP = isSet(hwCap, hwcap_EDSP)\n\tARM.HasJAVA = isSet(hwCap, hwcap_JAVA)\n\tARM.HasIWMMXT = isSet(hwCap, hwcap_IWMMXT)\n\tARM.HasCRUNCH = isSet(hwCap, hwcap_CRUNCH)\n\tARM.HasTHUMBEE = isSet(hwCap, hwcap_THUMBEE)\n\tARM.HasNEON = isSet(hwCap, hwcap_NEON)\n\tARM.HasVFPv3 = isSet(hwCap, hwcap_VFPv3)\n\tARM.HasVFPv3D16 = isSet(hwCap, hwcap_VFPv3D16)\n\tARM.HasTLS = isSet(hwCap, hwcap_TLS)\n\tARM.HasVFPv4 = isSet(hwCap, hwcap_VFPv4)\n\tARM.HasIDIVA = isSet(hwCap, hwcap_IDIVA)\n\tARM.HasIDIVT = isSet(hwCap, hwcap_IDIVT)\n\tARM.HasVFPD32 = isSet(hwCap, hwcap_VFPD32)\n\tARM.HasLPAE = isSet(hwCap, hwcap_LPAE)\n\tARM.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM)\n\tARM.HasAES = isSet(hwCap2, hwcap2_AES)\n\tARM.HasPMULL = isSet(hwCap2, hwcap2_PMULL)\n\tARM.HasSHA1 = isSet(hwCap2, hwcap2_SHA1)\n\tARM.HasSHA2 = isSet(hwCap2, hwcap2_SHA2)\n\tARM.HasCRC32 = isSet(hwCap2, hwcap2_CRC32)\n}\n\nfunc isSet(hwc uint, value uint) bool {\n\treturn hwc&value != 0\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go",
    "content": "// Copyright 2018 The Go 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 cpu\n\nimport (\n\t\"strings\"\n\t\"syscall\"\n)\n\n// HWCAP/HWCAP2 bits. These are exposed by Linux.\nconst (\n\thwcap_FP       = 1 << 0\n\thwcap_ASIMD    = 1 << 1\n\thwcap_EVTSTRM  = 1 << 2\n\thwcap_AES      = 1 << 3\n\thwcap_PMULL    = 1 << 4\n\thwcap_SHA1     = 1 << 5\n\thwcap_SHA2     = 1 << 6\n\thwcap_CRC32    = 1 << 7\n\thwcap_ATOMICS  = 1 << 8\n\thwcap_FPHP     = 1 << 9\n\thwcap_ASIMDHP  = 1 << 10\n\thwcap_CPUID    = 1 << 11\n\thwcap_ASIMDRDM = 1 << 12\n\thwcap_JSCVT    = 1 << 13\n\thwcap_FCMA     = 1 << 14\n\thwcap_LRCPC    = 1 << 15\n\thwcap_DCPOP    = 1 << 16\n\thwcap_SHA3     = 1 << 17\n\thwcap_SM3      = 1 << 18\n\thwcap_SM4      = 1 << 19\n\thwcap_ASIMDDP  = 1 << 20\n\thwcap_SHA512   = 1 << 21\n\thwcap_SVE      = 1 << 22\n\thwcap_ASIMDFHM = 1 << 23\n\thwcap_DIT      = 1 << 24\n\n\thwcap2_SVE2 = 1 << 1\n\thwcap2_I8MM = 1 << 13\n)\n\n// linuxKernelCanEmulateCPUID reports whether we're running\n// on Linux 4.11+. Ideally we'd like to ask the question about\n// whether the current kernel contains\n// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=77c97b4ee21290f5f083173d957843b615abbff2\n// but the version number will have to do.\nfunc linuxKernelCanEmulateCPUID() bool {\n\tvar un syscall.Utsname\n\tsyscall.Uname(&un)\n\tvar sb strings.Builder\n\tfor _, b := range un.Release[:] {\n\t\tif b == 0 {\n\t\t\tbreak\n\t\t}\n\t\tsb.WriteByte(byte(b))\n\t}\n\tmajor, minor, _, ok := parseRelease(sb.String())\n\treturn ok && (major > 4 || major == 4 && minor >= 11)\n}\n\nfunc doinit() {\n\tif err := readHWCAP(); err != nil {\n\t\t// We failed to read /proc/self/auxv. This can happen if the binary has\n\t\t// been given extra capabilities(7) with /bin/setcap.\n\t\t//\n\t\t// When this happens, we have two options. If the Linux kernel is new\n\t\t// enough (4.11+), we can read the arm64 registers directly which'll\n\t\t// trap into the kernel and then return back to userspace.\n\t\t//\n\t\t// But on older kernels, such as Linux 4.4.180 as used on many Synology\n\t\t// devices, calling readARM64Registers (specifically getisar0) will\n\t\t// cause a SIGILL and we'll die. So for older kernels, parse /proc/cpuinfo\n\t\t// instead.\n\t\t//\n\t\t// See golang/go#57336.\n\t\tif linuxKernelCanEmulateCPUID() {\n\t\t\treadARM64Registers()\n\t\t} else {\n\t\t\treadLinuxProcCPUInfo()\n\t\t}\n\t\treturn\n\t}\n\n\t// HWCAP feature bits\n\tARM64.HasFP = isSet(hwCap, hwcap_FP)\n\tARM64.HasASIMD = isSet(hwCap, hwcap_ASIMD)\n\tARM64.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM)\n\tARM64.HasAES = isSet(hwCap, hwcap_AES)\n\tARM64.HasPMULL = isSet(hwCap, hwcap_PMULL)\n\tARM64.HasSHA1 = isSet(hwCap, hwcap_SHA1)\n\tARM64.HasSHA2 = isSet(hwCap, hwcap_SHA2)\n\tARM64.HasCRC32 = isSet(hwCap, hwcap_CRC32)\n\tARM64.HasATOMICS = isSet(hwCap, hwcap_ATOMICS)\n\tARM64.HasFPHP = isSet(hwCap, hwcap_FPHP)\n\tARM64.HasASIMDHP = isSet(hwCap, hwcap_ASIMDHP)\n\tARM64.HasCPUID = isSet(hwCap, hwcap_CPUID)\n\tARM64.HasASIMDRDM = isSet(hwCap, hwcap_ASIMDRDM)\n\tARM64.HasJSCVT = isSet(hwCap, hwcap_JSCVT)\n\tARM64.HasFCMA = isSet(hwCap, hwcap_FCMA)\n\tARM64.HasLRCPC = isSet(hwCap, hwcap_LRCPC)\n\tARM64.HasDCPOP = isSet(hwCap, hwcap_DCPOP)\n\tARM64.HasSHA3 = isSet(hwCap, hwcap_SHA3)\n\tARM64.HasSM3 = isSet(hwCap, hwcap_SM3)\n\tARM64.HasSM4 = isSet(hwCap, hwcap_SM4)\n\tARM64.HasASIMDDP = isSet(hwCap, hwcap_ASIMDDP)\n\tARM64.HasSHA512 = isSet(hwCap, hwcap_SHA512)\n\tARM64.HasSVE = isSet(hwCap, hwcap_SVE)\n\tARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM)\n\tARM64.HasDIT = isSet(hwCap, hwcap_DIT)\n\n\t// HWCAP2 feature bits\n\tARM64.HasSVE2 = isSet(hwCap2, hwcap2_SVE2)\n\tARM64.HasI8MM = isSet(hwCap2, hwcap2_I8MM)\n}\n\nfunc isSet(hwc uint, value uint) bool {\n\treturn hwc&value != 0\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_linux_loong64.go",
    "content": "// Copyright 2025 The Go 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 cpu\n\n// HWCAP bits. These are exposed by the Linux kernel.\nconst (\n\thwcap_LOONGARCH_LSX  = 1 << 4\n\thwcap_LOONGARCH_LASX = 1 << 5\n)\n\nfunc doinit() {\n\t// TODO: Features that require kernel support like LSX and LASX can\n\t// be detected here once needed in std library or by the compiler.\n\tLoong64.HasLSX = hwcIsSet(hwCap, hwcap_LOONGARCH_LSX)\n\tLoong64.HasLASX = hwcIsSet(hwCap, hwcap_LOONGARCH_LASX)\n}\n\nfunc hwcIsSet(hwc uint, val uint) bool {\n\treturn hwc&val != 0\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go",
    "content": "// Copyright 2020 The Go 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\n//go:build linux && (mips64 || mips64le)\n\npackage cpu\n\n// HWCAP bits. These are exposed by the Linux kernel 5.4.\nconst (\n\t// CPU features\n\thwcap_MIPS_MSA = 1 << 1\n)\n\nfunc doinit() {\n\t// HWCAP feature bits\n\tMIPS64X.HasMSA = isSet(hwCap, hwcap_MIPS_MSA)\n}\n\nfunc isSet(hwc uint, value uint) bool {\n\treturn hwc&value != 0\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go",
    "content": "// Copyright 2019 The Go 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\n//go:build linux && !arm && !arm64 && !loong64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !s390x && !riscv64\n\npackage cpu\n\nfunc doinit() {}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go",
    "content": "// Copyright 2018 The Go 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\n//go:build linux && (ppc64 || ppc64le)\n\npackage cpu\n\n// HWCAP/HWCAP2 bits. These are exposed by the kernel.\nconst (\n\t// ISA Level\n\t_PPC_FEATURE2_ARCH_2_07 = 0x80000000\n\t_PPC_FEATURE2_ARCH_3_00 = 0x00800000\n\n\t// CPU features\n\t_PPC_FEATURE2_DARN = 0x00200000\n\t_PPC_FEATURE2_SCV  = 0x00100000\n)\n\nfunc doinit() {\n\t// HWCAP2 feature bits\n\tPPC64.IsPOWER8 = isSet(hwCap2, _PPC_FEATURE2_ARCH_2_07)\n\tPPC64.IsPOWER9 = isSet(hwCap2, _PPC_FEATURE2_ARCH_3_00)\n\tPPC64.HasDARN = isSet(hwCap2, _PPC_FEATURE2_DARN)\n\tPPC64.HasSCV = isSet(hwCap2, _PPC_FEATURE2_SCV)\n}\n\nfunc isSet(hwc uint, value uint) bool {\n\treturn hwc&value != 0\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go",
    "content": "// Copyright 2024 The Go 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 cpu\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n// RISC-V extension discovery code for Linux. The approach here is to first try the riscv_hwprobe\n// syscall falling back to HWCAP to check for the C extension if riscv_hwprobe is not available.\n//\n// A note on detection of the Vector extension using HWCAP.\n//\n// Support for the Vector extension version 1.0 was added to the Linux kernel in release 6.5.\n// Support for the riscv_hwprobe syscall was added in 6.4. It follows that if the riscv_hwprobe\n// syscall is not available then neither is the Vector extension (which needs kernel support).\n// The riscv_hwprobe syscall should then be all we need to detect the Vector extension.\n// However, some RISC-V board manufacturers ship boards with an older kernel on top of which\n// they have back-ported various versions of the Vector extension patches but not the riscv_hwprobe\n// patches. These kernels advertise support for the Vector extension using HWCAP. Falling\n// back to HWCAP to detect the Vector extension, if riscv_hwprobe is not available, or simply not\n// bothering with riscv_hwprobe at all and just using HWCAP may then seem like an attractive option.\n//\n// Unfortunately, simply checking the 'V' bit in AT_HWCAP will not work as this bit is used by\n// RISC-V board and cloud instance providers to mean different things. The Lichee Pi 4A board\n// and the Scaleway RV1 cloud instances use the 'V' bit to advertise their support for the unratified\n// 0.7.1 version of the Vector Specification. The Banana Pi BPI-F3 and the CanMV-K230 board use\n// it to advertise support for 1.0 of the Vector extension. Versions 0.7.1 and 1.0 of the Vector\n// extension are binary incompatible. HWCAP can then not be used in isolation to populate the\n// HasV field as this field indicates that the underlying CPU is compatible with RVV 1.0.\n//\n// There is a way at runtime to distinguish between versions 0.7.1 and 1.0 of the Vector\n// specification by issuing a RVV 1.0 vsetvli instruction and checking the vill bit of the vtype\n// register. This check would allow us to safely detect version 1.0 of the Vector extension\n// with HWCAP, if riscv_hwprobe were not available. However, the check cannot\n// be added until the assembler supports the Vector instructions.\n//\n// Note the riscv_hwprobe syscall does not suffer from these ambiguities by design as all of the\n// extensions it advertises support for are explicitly versioned. It's also worth noting that\n// the riscv_hwprobe syscall is the only way to detect multi-letter RISC-V extensions, e.g., Zba.\n// These cannot be detected using HWCAP and so riscv_hwprobe must be used to detect the majority\n// of RISC-V extensions.\n//\n// Please see https://docs.kernel.org/arch/riscv/hwprobe.html for more information.\n\n// golang.org/x/sys/cpu is not allowed to depend on golang.org/x/sys/unix so we must\n// reproduce the constants, types and functions needed to make the riscv_hwprobe syscall\n// here.\n\nconst (\n\t// Copied from golang.org/x/sys/unix/ztypes_linux_riscv64.go.\n\triscv_HWPROBE_KEY_IMA_EXT_0   = 0x4\n\triscv_HWPROBE_IMA_C           = 0x2\n\triscv_HWPROBE_IMA_V           = 0x4\n\triscv_HWPROBE_EXT_ZBA         = 0x8\n\triscv_HWPROBE_EXT_ZBB         = 0x10\n\triscv_HWPROBE_EXT_ZBS         = 0x20\n\triscv_HWPROBE_EXT_ZVBB        = 0x20000\n\triscv_HWPROBE_EXT_ZVBC        = 0x40000\n\triscv_HWPROBE_EXT_ZVKB        = 0x80000\n\triscv_HWPROBE_EXT_ZVKG        = 0x100000\n\triscv_HWPROBE_EXT_ZVKNED      = 0x200000\n\triscv_HWPROBE_EXT_ZVKNHB      = 0x800000\n\triscv_HWPROBE_EXT_ZVKSED      = 0x1000000\n\triscv_HWPROBE_EXT_ZVKSH       = 0x2000000\n\triscv_HWPROBE_EXT_ZVKT        = 0x4000000\n\triscv_HWPROBE_KEY_CPUPERF_0   = 0x5\n\triscv_HWPROBE_MISALIGNED_FAST = 0x3\n\triscv_HWPROBE_MISALIGNED_MASK = 0x7\n)\n\nconst (\n\t// sys_RISCV_HWPROBE is copied from golang.org/x/sys/unix/zsysnum_linux_riscv64.go.\n\tsys_RISCV_HWPROBE = 258\n)\n\n// riscvHWProbePairs is copied from golang.org/x/sys/unix/ztypes_linux_riscv64.go.\ntype riscvHWProbePairs struct {\n\tkey   int64\n\tvalue uint64\n}\n\nconst (\n\t// CPU features\n\thwcap_RISCV_ISA_C = 1 << ('C' - 'A')\n)\n\nfunc doinit() {\n\t// A slice of key/value pair structures is passed to the RISCVHWProbe syscall. The key\n\t// field should be initialised with one of the key constants defined above, e.g.,\n\t// RISCV_HWPROBE_KEY_IMA_EXT_0. The syscall will set the value field to the appropriate value.\n\t// If the kernel does not recognise a key it will set the key field to -1 and the value field to 0.\n\n\tpairs := []riscvHWProbePairs{\n\t\t{riscv_HWPROBE_KEY_IMA_EXT_0, 0},\n\t\t{riscv_HWPROBE_KEY_CPUPERF_0, 0},\n\t}\n\n\t// This call only indicates that extensions are supported if they are implemented on all cores.\n\tif riscvHWProbe(pairs, 0) {\n\t\tif pairs[0].key != -1 {\n\t\t\tv := uint(pairs[0].value)\n\t\t\tRISCV64.HasC = isSet(v, riscv_HWPROBE_IMA_C)\n\t\t\tRISCV64.HasV = isSet(v, riscv_HWPROBE_IMA_V)\n\t\t\tRISCV64.HasZba = isSet(v, riscv_HWPROBE_EXT_ZBA)\n\t\t\tRISCV64.HasZbb = isSet(v, riscv_HWPROBE_EXT_ZBB)\n\t\t\tRISCV64.HasZbs = isSet(v, riscv_HWPROBE_EXT_ZBS)\n\t\t\tRISCV64.HasZvbb = isSet(v, riscv_HWPROBE_EXT_ZVBB)\n\t\t\tRISCV64.HasZvbc = isSet(v, riscv_HWPROBE_EXT_ZVBC)\n\t\t\tRISCV64.HasZvkb = isSet(v, riscv_HWPROBE_EXT_ZVKB)\n\t\t\tRISCV64.HasZvkg = isSet(v, riscv_HWPROBE_EXT_ZVKG)\n\t\t\tRISCV64.HasZvkt = isSet(v, riscv_HWPROBE_EXT_ZVKT)\n\t\t\t// Cryptography shorthand extensions\n\t\t\tRISCV64.HasZvkn = isSet(v, riscv_HWPROBE_EXT_ZVKNED) &&\n\t\t\t\tisSet(v, riscv_HWPROBE_EXT_ZVKNHB) && RISCV64.HasZvkb && RISCV64.HasZvkt\n\t\t\tRISCV64.HasZvknc = RISCV64.HasZvkn && RISCV64.HasZvbc\n\t\t\tRISCV64.HasZvkng = RISCV64.HasZvkn && RISCV64.HasZvkg\n\t\t\tRISCV64.HasZvks = isSet(v, riscv_HWPROBE_EXT_ZVKSED) &&\n\t\t\t\tisSet(v, riscv_HWPROBE_EXT_ZVKSH) && RISCV64.HasZvkb && RISCV64.HasZvkt\n\t\t\tRISCV64.HasZvksc = RISCV64.HasZvks && RISCV64.HasZvbc\n\t\t\tRISCV64.HasZvksg = RISCV64.HasZvks && RISCV64.HasZvkg\n\t\t}\n\t\tif pairs[1].key != -1 {\n\t\t\tv := pairs[1].value & riscv_HWPROBE_MISALIGNED_MASK\n\t\t\tRISCV64.HasFastMisaligned = v == riscv_HWPROBE_MISALIGNED_FAST\n\t\t}\n\t}\n\n\t// Let's double check with HWCAP if the C extension does not appear to be supported.\n\t// This may happen if we're running on a kernel older than 6.4.\n\n\tif !RISCV64.HasC {\n\t\tRISCV64.HasC = isSet(hwCap, hwcap_RISCV_ISA_C)\n\t}\n}\n\nfunc isSet(hwc uint, value uint) bool {\n\treturn hwc&value != 0\n}\n\n// riscvHWProbe is a simplified version of the generated wrapper function found in\n// golang.org/x/sys/unix/zsyscall_linux_riscv64.go. We simplify it by removing the\n// cpuCount and cpus parameters which we do not need. We always want to pass 0 for\n// these parameters here so the kernel only reports the extensions that are present\n// on all cores.\nfunc riscvHWProbe(pairs []riscvHWProbePairs, flags uint) bool {\n\tvar _zero uintptr\n\tvar p0 unsafe.Pointer\n\tif len(pairs) > 0 {\n\t\tp0 = unsafe.Pointer(&pairs[0])\n\t} else {\n\t\tp0 = unsafe.Pointer(&_zero)\n\t}\n\n\t_, _, e1 := syscall.Syscall6(sys_RISCV_HWPROBE, uintptr(p0), uintptr(len(pairs)), uintptr(0), uintptr(0), uintptr(flags), 0)\n\treturn e1 == 0\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go",
    "content": "// Copyright 2019 The Go 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 cpu\n\nconst (\n\t// bit mask values from /usr/include/bits/hwcap.h\n\thwcap_ZARCH  = 2\n\thwcap_STFLE  = 4\n\thwcap_MSA    = 8\n\thwcap_LDISP  = 16\n\thwcap_EIMM   = 32\n\thwcap_DFP    = 64\n\thwcap_ETF3EH = 256\n\thwcap_VX     = 2048\n\thwcap_VXE    = 8192\n)\n\nfunc initS390Xbase() {\n\t// test HWCAP bit vector\n\thas := func(featureMask uint) bool {\n\t\treturn hwCap&featureMask == featureMask\n\t}\n\n\t// mandatory\n\tS390X.HasZARCH = has(hwcap_ZARCH)\n\n\t// optional\n\tS390X.HasSTFLE = has(hwcap_STFLE)\n\tS390X.HasLDISP = has(hwcap_LDISP)\n\tS390X.HasEIMM = has(hwcap_EIMM)\n\tS390X.HasETF3EH = has(hwcap_ETF3EH)\n\tS390X.HasDFP = has(hwcap_DFP)\n\tS390X.HasMSA = has(hwcap_MSA)\n\tS390X.HasVX = has(hwcap_VX)\n\tif S390X.HasVX {\n\t\tS390X.HasVXE = has(hwcap_VXE)\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_loong64.go",
    "content": "// Copyright 2022 The Go 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\n//go:build loong64\n\npackage cpu\n\nconst cacheLineSize = 64\n\n// Bit fields for CPUCFG registers, Related reference documents:\n// https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#_cpucfg\nconst (\n\t// CPUCFG1 bits\n\tcpucfg1_CRC32 = 1 << 25\n\n\t// CPUCFG2 bits\n\tcpucfg2_LAM_BH = 1 << 27\n\tcpucfg2_LAMCAS = 1 << 28\n)\n\nfunc initOptions() {\n\toptions = []option{\n\t\t{Name: \"lsx\", Feature: &Loong64.HasLSX},\n\t\t{Name: \"lasx\", Feature: &Loong64.HasLASX},\n\t\t{Name: \"crc32\", Feature: &Loong64.HasCRC32},\n\t\t{Name: \"lam_bh\", Feature: &Loong64.HasLAM_BH},\n\t\t{Name: \"lamcas\", Feature: &Loong64.HasLAMCAS},\n\t}\n\n\t// The CPUCFG data on Loong64 only reflects the hardware capabilities,\n\t// not the kernel support status, so features such as LSX and LASX that\n\t// require kernel support cannot be obtained from the CPUCFG data.\n\t//\n\t// These features only require hardware capability support and do not\n\t// require kernel specific support, so they can be obtained directly\n\t// through CPUCFG\n\tcfg1 := get_cpucfg(1)\n\tcfg2 := get_cpucfg(2)\n\n\tLoong64.HasCRC32 = cfgIsSet(cfg1, cpucfg1_CRC32)\n\tLoong64.HasLAMCAS = cfgIsSet(cfg2, cpucfg2_LAMCAS)\n\tLoong64.HasLAM_BH = cfgIsSet(cfg2, cpucfg2_LAM_BH)\n}\n\nfunc get_cpucfg(reg uint32) uint32\n\nfunc cfgIsSet(cfg uint32, val uint32) bool {\n\treturn cfg&val != 0\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_loong64.s",
    "content": "// Copyright 2025 The Go 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\n#include \"textflag.h\"\n\n// func get_cpucfg(reg uint32) uint32\nTEXT ·get_cpucfg(SB), NOSPLIT|NOFRAME, $0\n\tMOVW\treg+0(FP), R5\n\t// CPUCFG R5, R4 = 0x00006ca4\n\tWORD\t$0x00006ca4\n\tMOVW\tR4, ret+8(FP)\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_mips64x.go",
    "content": "// Copyright 2018 The Go 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\n//go:build mips64 || mips64le\n\npackage cpu\n\nconst cacheLineSize = 32\n\nfunc initOptions() {\n\toptions = []option{\n\t\t{Name: \"msa\", Feature: &MIPS64X.HasMSA},\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_mipsx.go",
    "content": "// Copyright 2018 The Go 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\n//go:build mips || mipsle\n\npackage cpu\n\nconst cacheLineSize = 32\n\nfunc initOptions() {}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go",
    "content": "// Copyright 2020 The Go 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 cpu\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n// Minimal copy of functionality from x/sys/unix so the cpu package can call\n// sysctl without depending on x/sys/unix.\n\nconst (\n\t_CTL_QUERY = -2\n\n\t_SYSCTL_VERS_1 = 0x1000000\n)\n\nvar _zero uintptr\n\nfunc sysctl(mib []int32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(mib) > 0 {\n\t\t_p0 = unsafe.Pointer(&mib[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\t_, _, errno := syscall.Syscall6(\n\t\tsyscall.SYS___SYSCTL,\n\t\tuintptr(_p0),\n\t\tuintptr(len(mib)),\n\t\tuintptr(unsafe.Pointer(old)),\n\t\tuintptr(unsafe.Pointer(oldlen)),\n\t\tuintptr(unsafe.Pointer(new)),\n\t\tuintptr(newlen))\n\tif errno != 0 {\n\t\treturn errno\n\t}\n\treturn nil\n}\n\ntype sysctlNode struct {\n\tFlags          uint32\n\tNum            int32\n\tName           [32]int8\n\tVer            uint32\n\t__rsvd         uint32\n\tUn             [16]byte\n\t_sysctl_size   [8]byte\n\t_sysctl_func   [8]byte\n\t_sysctl_parent [8]byte\n\t_sysctl_desc   [8]byte\n}\n\nfunc sysctlNodes(mib []int32) ([]sysctlNode, error) {\n\tvar olen uintptr\n\n\t// Get a list of all sysctl nodes below the given MIB by performing\n\t// a sysctl for the given MIB with CTL_QUERY appended.\n\tmib = append(mib, _CTL_QUERY)\n\tqnode := sysctlNode{Flags: _SYSCTL_VERS_1}\n\tqp := (*byte)(unsafe.Pointer(&qnode))\n\tsz := unsafe.Sizeof(qnode)\n\tif err := sysctl(mib, nil, &olen, qp, sz); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Now that we know the size, get the actual nodes.\n\tnodes := make([]sysctlNode, olen/sz)\n\tnp := (*byte)(unsafe.Pointer(&nodes[0]))\n\tif err := sysctl(mib, np, &olen, qp, sz); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn nodes, nil\n}\n\nfunc nametomib(name string) ([]int32, error) {\n\t// Split name into components.\n\tvar parts []string\n\tlast := 0\n\tfor i := 0; i < len(name); i++ {\n\t\tif name[i] == '.' {\n\t\t\tparts = append(parts, name[last:i])\n\t\t\tlast = i + 1\n\t\t}\n\t}\n\tparts = append(parts, name[last:])\n\n\tmib := []int32{}\n\t// Discover the nodes and construct the MIB OID.\n\tfor partno, part := range parts {\n\t\tnodes, err := sysctlNodes(mib)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfor _, node := range nodes {\n\t\t\tn := make([]byte, 0)\n\t\t\tfor i := range node.Name {\n\t\t\t\tif node.Name[i] != 0 {\n\t\t\t\t\tn = append(n, byte(node.Name[i]))\n\t\t\t\t}\n\t\t\t}\n\t\t\tif string(n) == part {\n\t\t\t\tmib = append(mib, int32(node.Num))\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif len(mib) != partno+1 {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn mib, nil\n}\n\n// aarch64SysctlCPUID is struct aarch64_sysctl_cpu_id from NetBSD's <aarch64/armreg.h>\ntype aarch64SysctlCPUID struct {\n\tmidr      uint64 /* Main ID Register */\n\trevidr    uint64 /* Revision ID Register */\n\tmpidr     uint64 /* Multiprocessor Affinity Register */\n\taa64dfr0  uint64 /* A64 Debug Feature Register 0 */\n\taa64dfr1  uint64 /* A64 Debug Feature Register 1 */\n\taa64isar0 uint64 /* A64 Instruction Set Attribute Register 0 */\n\taa64isar1 uint64 /* A64 Instruction Set Attribute Register 1 */\n\taa64mmfr0 uint64 /* A64 Memory Model Feature Register 0 */\n\taa64mmfr1 uint64 /* A64 Memory Model Feature Register 1 */\n\taa64mmfr2 uint64 /* A64 Memory Model Feature Register 2 */\n\taa64pfr0  uint64 /* A64 Processor Feature Register 0 */\n\taa64pfr1  uint64 /* A64 Processor Feature Register 1 */\n\taa64zfr0  uint64 /* A64 SVE Feature ID Register 0 */\n\tmvfr0     uint32 /* Media and VFP Feature Register 0 */\n\tmvfr1     uint32 /* Media and VFP Feature Register 1 */\n\tmvfr2     uint32 /* Media and VFP Feature Register 2 */\n\tpad       uint32\n\tclidr     uint64 /* Cache Level ID Register */\n\tctr       uint64 /* Cache Type Register */\n}\n\nfunc sysctlCPUID(name string) (*aarch64SysctlCPUID, error) {\n\tmib, err := nametomib(name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tout := aarch64SysctlCPUID{}\n\tn := unsafe.Sizeof(out)\n\t_, _, errno := syscall.Syscall6(\n\t\tsyscall.SYS___SYSCTL,\n\t\tuintptr(unsafe.Pointer(&mib[0])),\n\t\tuintptr(len(mib)),\n\t\tuintptr(unsafe.Pointer(&out)),\n\t\tuintptr(unsafe.Pointer(&n)),\n\t\tuintptr(0),\n\t\tuintptr(0))\n\tif errno != 0 {\n\t\treturn nil, errno\n\t}\n\treturn &out, nil\n}\n\nfunc doinit() {\n\tcpuid, err := sysctlCPUID(\"machdep.cpu0.cpu_id\")\n\tif err != nil {\n\t\tsetMinimalFeatures()\n\t\treturn\n\t}\n\tparseARM64SystemRegisters(cpuid.aa64isar0, cpuid.aa64isar1, cpuid.aa64pfr0)\n\n\tInitialized = true\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go",
    "content": "// Copyright 2022 The Go 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 cpu\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n// Minimal copy of functionality from x/sys/unix so the cpu package can call\n// sysctl without depending on x/sys/unix.\n\nconst (\n\t// From OpenBSD's sys/sysctl.h.\n\t_CTL_MACHDEP = 7\n\n\t// From OpenBSD's machine/cpu.h.\n\t_CPU_ID_AA64ISAR0 = 2\n\t_CPU_ID_AA64ISAR1 = 3\n)\n\n// Implemented in the runtime package (runtime/sys_openbsd3.go)\nfunc syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)\n\n//go:linkname syscall_syscall6 syscall.syscall6\n\nfunc sysctl(mib []uint32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {\n\t_, _, errno := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(unsafe.Pointer(&mib[0])), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))\n\tif errno != 0 {\n\t\treturn errno\n\t}\n\treturn nil\n}\n\nvar libc_sysctl_trampoline_addr uintptr\n\n//go:cgo_import_dynamic libc_sysctl sysctl \"libc.so\"\n\nfunc sysctlUint64(mib []uint32) (uint64, bool) {\n\tvar out uint64\n\tnout := unsafe.Sizeof(out)\n\tif err := sysctl(mib, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0); err != nil {\n\t\treturn 0, false\n\t}\n\treturn out, true\n}\n\nfunc doinit() {\n\tsetMinimalFeatures()\n\n\t// Get ID_AA64ISAR0 and ID_AA64ISAR1 from sysctl.\n\tisar0, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR0})\n\tif !ok {\n\t\treturn\n\t}\n\tisar1, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR1})\n\tif !ok {\n\t\treturn\n\t}\n\tparseARM64SystemRegisters(isar0, isar1, 0)\n\n\tInitialized = true\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.s",
    "content": "// Copyright 2022 The Go 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\n#include \"textflag.h\"\n\nTEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0\n\tJMP\tlibc_sysctl(SB)\n\nGLOBL\t·libc_sysctl_trampoline_addr(SB), RODATA, $8\nDATA\t·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_other_arm.go",
    "content": "// Copyright 2020 The Go 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\n//go:build !linux && arm\n\npackage cpu\n\nfunc archInit() {}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_other_arm64.go",
    "content": "// Copyright 2019 The Go 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\n//go:build !linux && !netbsd && !openbsd && arm64\n\npackage cpu\n\nfunc doinit() {}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_other_mips64x.go",
    "content": "// Copyright 2020 The Go 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\n//go:build !linux && (mips64 || mips64le)\n\npackage cpu\n\nfunc archInit() {\n\tInitialized = true\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_other_ppc64x.go",
    "content": "// Copyright 2022 The Go 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\n//go:build !aix && !linux && (ppc64 || ppc64le)\n\npackage cpu\n\nfunc archInit() {\n\tPPC64.IsPOWER8 = true\n\tInitialized = true\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_other_riscv64.go",
    "content": "// Copyright 2022 The Go 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\n//go:build !linux && riscv64\n\npackage cpu\n\nfunc archInit() {\n\tInitialized = true\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_other_x86.go",
    "content": "// Copyright 2024 The Go 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\n//go:build 386 || amd64p32 || (amd64 && (!darwin || !gc))\n\npackage cpu\n\nfunc darwinSupportsAVX512() bool {\n\tpanic(\"only implemented for gc && amd64 && darwin\")\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_ppc64x.go",
    "content": "// Copyright 2020 The Go 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\n//go:build ppc64 || ppc64le\n\npackage cpu\n\nconst cacheLineSize = 128\n\nfunc initOptions() {\n\toptions = []option{\n\t\t{Name: \"darn\", Feature: &PPC64.HasDARN},\n\t\t{Name: \"scv\", Feature: &PPC64.HasSCV},\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_riscv64.go",
    "content": "// Copyright 2019 The Go 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\n//go:build riscv64\n\npackage cpu\n\nconst cacheLineSize = 64\n\nfunc initOptions() {\n\toptions = []option{\n\t\t{Name: \"fastmisaligned\", Feature: &RISCV64.HasFastMisaligned},\n\t\t{Name: \"c\", Feature: &RISCV64.HasC},\n\t\t{Name: \"v\", Feature: &RISCV64.HasV},\n\t\t{Name: \"zba\", Feature: &RISCV64.HasZba},\n\t\t{Name: \"zbb\", Feature: &RISCV64.HasZbb},\n\t\t{Name: \"zbs\", Feature: &RISCV64.HasZbs},\n\t\t// RISC-V Cryptography Extensions\n\t\t{Name: \"zvbb\", Feature: &RISCV64.HasZvbb},\n\t\t{Name: \"zvbc\", Feature: &RISCV64.HasZvbc},\n\t\t{Name: \"zvkb\", Feature: &RISCV64.HasZvkb},\n\t\t{Name: \"zvkg\", Feature: &RISCV64.HasZvkg},\n\t\t{Name: \"zvkt\", Feature: &RISCV64.HasZvkt},\n\t\t{Name: \"zvkn\", Feature: &RISCV64.HasZvkn},\n\t\t{Name: \"zvknc\", Feature: &RISCV64.HasZvknc},\n\t\t{Name: \"zvkng\", Feature: &RISCV64.HasZvkng},\n\t\t{Name: \"zvks\", Feature: &RISCV64.HasZvks},\n\t\t{Name: \"zvksc\", Feature: &RISCV64.HasZvksc},\n\t\t{Name: \"zvksg\", Feature: &RISCV64.HasZvksg},\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_s390x.go",
    "content": "// Copyright 2020 The Go 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 cpu\n\nconst cacheLineSize = 256\n\nfunc initOptions() {\n\toptions = []option{\n\t\t{Name: \"zarch\", Feature: &S390X.HasZARCH, Required: true},\n\t\t{Name: \"stfle\", Feature: &S390X.HasSTFLE, Required: true},\n\t\t{Name: \"ldisp\", Feature: &S390X.HasLDISP, Required: true},\n\t\t{Name: \"eimm\", Feature: &S390X.HasEIMM, Required: true},\n\t\t{Name: \"dfp\", Feature: &S390X.HasDFP},\n\t\t{Name: \"etf3eh\", Feature: &S390X.HasETF3EH},\n\t\t{Name: \"msa\", Feature: &S390X.HasMSA},\n\t\t{Name: \"aes\", Feature: &S390X.HasAES},\n\t\t{Name: \"aescbc\", Feature: &S390X.HasAESCBC},\n\t\t{Name: \"aesctr\", Feature: &S390X.HasAESCTR},\n\t\t{Name: \"aesgcm\", Feature: &S390X.HasAESGCM},\n\t\t{Name: \"ghash\", Feature: &S390X.HasGHASH},\n\t\t{Name: \"sha1\", Feature: &S390X.HasSHA1},\n\t\t{Name: \"sha256\", Feature: &S390X.HasSHA256},\n\t\t{Name: \"sha3\", Feature: &S390X.HasSHA3},\n\t\t{Name: \"sha512\", Feature: &S390X.HasSHA512},\n\t\t{Name: \"vx\", Feature: &S390X.HasVX},\n\t\t{Name: \"vxe\", Feature: &S390X.HasVXE},\n\t}\n}\n\n// bitIsSet reports whether the bit at index is set. The bit index\n// is in big endian order, so bit index 0 is the leftmost bit.\nfunc bitIsSet(bits []uint64, index uint) bool {\n\treturn bits[index/64]&((1<<63)>>(index%64)) != 0\n}\n\n// facility is a bit index for the named facility.\ntype facility uint8\n\nconst (\n\t// mandatory facilities\n\tzarch  facility = 1  // z architecture mode is active\n\tstflef facility = 7  // store-facility-list-extended\n\tldisp  facility = 18 // long-displacement\n\teimm   facility = 21 // extended-immediate\n\n\t// miscellaneous facilities\n\tdfp    facility = 42 // decimal-floating-point\n\tetf3eh facility = 30 // extended-translation 3 enhancement\n\n\t// cryptography facilities\n\tmsa  facility = 17  // message-security-assist\n\tmsa3 facility = 76  // message-security-assist extension 3\n\tmsa4 facility = 77  // message-security-assist extension 4\n\tmsa5 facility = 57  // message-security-assist extension 5\n\tmsa8 facility = 146 // message-security-assist extension 8\n\tmsa9 facility = 155 // message-security-assist extension 9\n\n\t// vector facilities\n\tvx   facility = 129 // vector facility\n\tvxe  facility = 135 // vector-enhancements 1\n\tvxe2 facility = 148 // vector-enhancements 2\n)\n\n// facilityList contains the result of an STFLE call.\n// Bits are numbered in big endian order so the\n// leftmost bit (the MSB) is at index 0.\ntype facilityList struct {\n\tbits [4]uint64\n}\n\n// Has reports whether the given facilities are present.\nfunc (s *facilityList) Has(fs ...facility) bool {\n\tif len(fs) == 0 {\n\t\tpanic(\"no facility bits provided\")\n\t}\n\tfor _, f := range fs {\n\t\tif !bitIsSet(s.bits[:], uint(f)) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// function is the code for the named cryptographic function.\ntype function uint8\n\nconst (\n\t// KM{,A,C,CTR} function codes\n\taes128 function = 18 // AES-128\n\taes192 function = 19 // AES-192\n\taes256 function = 20 // AES-256\n\n\t// K{I,L}MD function codes\n\tsha1     function = 1  // SHA-1\n\tsha256   function = 2  // SHA-256\n\tsha512   function = 3  // SHA-512\n\tsha3_224 function = 32 // SHA3-224\n\tsha3_256 function = 33 // SHA3-256\n\tsha3_384 function = 34 // SHA3-384\n\tsha3_512 function = 35 // SHA3-512\n\tshake128 function = 36 // SHAKE-128\n\tshake256 function = 37 // SHAKE-256\n\n\t// KLMD function codes\n\tghash function = 65 // GHASH\n)\n\n// queryResult contains the result of a Query function\n// call. Bits are numbered in big endian order so the\n// leftmost bit (the MSB) is at index 0.\ntype queryResult struct {\n\tbits [2]uint64\n}\n\n// Has reports whether the given functions are present.\nfunc (q *queryResult) Has(fns ...function) bool {\n\tif len(fns) == 0 {\n\t\tpanic(\"no function codes provided\")\n\t}\n\tfor _, f := range fns {\n\t\tif !bitIsSet(q.bits[:], uint(f)) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc doinit() {\n\tinitS390Xbase()\n\n\t// We need implementations of stfle, km and so on\n\t// to detect cryptographic features.\n\tif !haveAsmFunctions() {\n\t\treturn\n\t}\n\n\t// optional cryptographic functions\n\tif S390X.HasMSA {\n\t\taes := []function{aes128, aes192, aes256}\n\n\t\t// cipher message\n\t\tkm, kmc := kmQuery(), kmcQuery()\n\t\tS390X.HasAES = km.Has(aes...)\n\t\tS390X.HasAESCBC = kmc.Has(aes...)\n\t\tif S390X.HasSTFLE {\n\t\t\tfacilities := stfle()\n\t\t\tif facilities.Has(msa4) {\n\t\t\t\tkmctr := kmctrQuery()\n\t\t\t\tS390X.HasAESCTR = kmctr.Has(aes...)\n\t\t\t}\n\t\t\tif facilities.Has(msa8) {\n\t\t\t\tkma := kmaQuery()\n\t\t\t\tS390X.HasAESGCM = kma.Has(aes...)\n\t\t\t}\n\t\t}\n\n\t\t// compute message digest\n\t\tkimd := kimdQuery() // intermediate (no padding)\n\t\tklmd := klmdQuery() // last (padding)\n\t\tS390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1)\n\t\tS390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256)\n\t\tS390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512)\n\t\tS390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist\n\t\tsha3 := []function{\n\t\t\tsha3_224, sha3_256, sha3_384, sha3_512,\n\t\t\tshake128, shake256,\n\t\t}\n\t\tS390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...)\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_s390x.s",
    "content": "// Copyright 2019 The Go 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\n//go:build gc\n\n#include \"textflag.h\"\n\n// func stfle() facilityList\nTEXT ·stfle(SB), NOSPLIT|NOFRAME, $0-32\n\tMOVD $ret+0(FP), R1\n\tMOVD $3, R0          // last doubleword index to store\n\tXC   $32, (R1), (R1) // clear 4 doublewords (32 bytes)\n\tWORD $0xb2b01000     // store facility list extended (STFLE)\n\tRET\n\n// func kmQuery() queryResult\nTEXT ·kmQuery(SB), NOSPLIT|NOFRAME, $0-16\n\tMOVD $0, R0         // set function code to 0 (KM-Query)\n\tMOVD $ret+0(FP), R1 // address of 16-byte return value\n\tWORD $0xB92E0024    // cipher message (KM)\n\tRET\n\n// func kmcQuery() queryResult\nTEXT ·kmcQuery(SB), NOSPLIT|NOFRAME, $0-16\n\tMOVD $0, R0         // set function code to 0 (KMC-Query)\n\tMOVD $ret+0(FP), R1 // address of 16-byte return value\n\tWORD $0xB92F0024    // cipher message with chaining (KMC)\n\tRET\n\n// func kmctrQuery() queryResult\nTEXT ·kmctrQuery(SB), NOSPLIT|NOFRAME, $0-16\n\tMOVD $0, R0         // set function code to 0 (KMCTR-Query)\n\tMOVD $ret+0(FP), R1 // address of 16-byte return value\n\tWORD $0xB92D4024    // cipher message with counter (KMCTR)\n\tRET\n\n// func kmaQuery() queryResult\nTEXT ·kmaQuery(SB), NOSPLIT|NOFRAME, $0-16\n\tMOVD $0, R0         // set function code to 0 (KMA-Query)\n\tMOVD $ret+0(FP), R1 // address of 16-byte return value\n\tWORD $0xb9296024    // cipher message with authentication (KMA)\n\tRET\n\n// func kimdQuery() queryResult\nTEXT ·kimdQuery(SB), NOSPLIT|NOFRAME, $0-16\n\tMOVD $0, R0         // set function code to 0 (KIMD-Query)\n\tMOVD $ret+0(FP), R1 // address of 16-byte return value\n\tWORD $0xB93E0024    // compute intermediate message digest (KIMD)\n\tRET\n\n// func klmdQuery() queryResult\nTEXT ·klmdQuery(SB), NOSPLIT|NOFRAME, $0-16\n\tMOVD $0, R0         // set function code to 0 (KLMD-Query)\n\tMOVD $ret+0(FP), R1 // address of 16-byte return value\n\tWORD $0xB93F0024    // compute last message digest (KLMD)\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_wasm.go",
    "content": "// Copyright 2019 The Go 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\n//go:build wasm\n\npackage cpu\n\n// We're compiling the cpu package for an unknown (software-abstracted) CPU.\n// Make CacheLinePad an empty struct and hope that the usual struct alignment\n// rules are good enough.\n\nconst cacheLineSize = 0\n\nfunc initOptions() {}\n\nfunc archInit() {}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_x86.go",
    "content": "// Copyright 2018 The Go 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\n//go:build 386 || amd64 || amd64p32\n\npackage cpu\n\nimport \"runtime\"\n\nconst cacheLineSize = 64\n\nfunc initOptions() {\n\toptions = []option{\n\t\t{Name: \"adx\", Feature: &X86.HasADX},\n\t\t{Name: \"aes\", Feature: &X86.HasAES},\n\t\t{Name: \"avx\", Feature: &X86.HasAVX},\n\t\t{Name: \"avx2\", Feature: &X86.HasAVX2},\n\t\t{Name: \"avx512\", Feature: &X86.HasAVX512},\n\t\t{Name: \"avx512f\", Feature: &X86.HasAVX512F},\n\t\t{Name: \"avx512cd\", Feature: &X86.HasAVX512CD},\n\t\t{Name: \"avx512er\", Feature: &X86.HasAVX512ER},\n\t\t{Name: \"avx512pf\", Feature: &X86.HasAVX512PF},\n\t\t{Name: \"avx512vl\", Feature: &X86.HasAVX512VL},\n\t\t{Name: \"avx512bw\", Feature: &X86.HasAVX512BW},\n\t\t{Name: \"avx512dq\", Feature: &X86.HasAVX512DQ},\n\t\t{Name: \"avx512ifma\", Feature: &X86.HasAVX512IFMA},\n\t\t{Name: \"avx512vbmi\", Feature: &X86.HasAVX512VBMI},\n\t\t{Name: \"avx512vnniw\", Feature: &X86.HasAVX5124VNNIW},\n\t\t{Name: \"avx5124fmaps\", Feature: &X86.HasAVX5124FMAPS},\n\t\t{Name: \"avx512vpopcntdq\", Feature: &X86.HasAVX512VPOPCNTDQ},\n\t\t{Name: \"avx512vpclmulqdq\", Feature: &X86.HasAVX512VPCLMULQDQ},\n\t\t{Name: \"avx512vnni\", Feature: &X86.HasAVX512VNNI},\n\t\t{Name: \"avx512gfni\", Feature: &X86.HasAVX512GFNI},\n\t\t{Name: \"avx512vaes\", Feature: &X86.HasAVX512VAES},\n\t\t{Name: \"avx512vbmi2\", Feature: &X86.HasAVX512VBMI2},\n\t\t{Name: \"avx512bitalg\", Feature: &X86.HasAVX512BITALG},\n\t\t{Name: \"avx512bf16\", Feature: &X86.HasAVX512BF16},\n\t\t{Name: \"amxtile\", Feature: &X86.HasAMXTile},\n\t\t{Name: \"amxint8\", Feature: &X86.HasAMXInt8},\n\t\t{Name: \"amxbf16\", Feature: &X86.HasAMXBF16},\n\t\t{Name: \"bmi1\", Feature: &X86.HasBMI1},\n\t\t{Name: \"bmi2\", Feature: &X86.HasBMI2},\n\t\t{Name: \"cx16\", Feature: &X86.HasCX16},\n\t\t{Name: \"erms\", Feature: &X86.HasERMS},\n\t\t{Name: \"fma\", Feature: &X86.HasFMA},\n\t\t{Name: \"osxsave\", Feature: &X86.HasOSXSAVE},\n\t\t{Name: \"pclmulqdq\", Feature: &X86.HasPCLMULQDQ},\n\t\t{Name: \"popcnt\", Feature: &X86.HasPOPCNT},\n\t\t{Name: \"rdrand\", Feature: &X86.HasRDRAND},\n\t\t{Name: \"rdseed\", Feature: &X86.HasRDSEED},\n\t\t{Name: \"sse3\", Feature: &X86.HasSSE3},\n\t\t{Name: \"sse41\", Feature: &X86.HasSSE41},\n\t\t{Name: \"sse42\", Feature: &X86.HasSSE42},\n\t\t{Name: \"ssse3\", Feature: &X86.HasSSSE3},\n\t\t{Name: \"avxifma\", Feature: &X86.HasAVXIFMA},\n\t\t{Name: \"avxvnni\", Feature: &X86.HasAVXVNNI},\n\t\t{Name: \"avxvnniint8\", Feature: &X86.HasAVXVNNIInt8},\n\n\t\t// These capabilities should always be enabled on amd64:\n\t\t{Name: \"sse2\", Feature: &X86.HasSSE2, Required: runtime.GOARCH == \"amd64\"},\n\t}\n}\n\nfunc archInit() {\n\n\t// From internal/cpu\n\tconst (\n\t\t// eax bits\n\t\tcpuid_AVXVNNI = 1 << 4\n\n\t\t// ecx bits\n\t\tcpuid_SSE3            = 1 << 0\n\t\tcpuid_PCLMULQDQ       = 1 << 1\n\t\tcpuid_AVX512VBMI      = 1 << 1\n\t\tcpuid_AVX512VBMI2     = 1 << 6\n\t\tcpuid_SSSE3           = 1 << 9\n\t\tcpuid_AVX512GFNI      = 1 << 8\n\t\tcpuid_AVX512VAES      = 1 << 9\n\t\tcpuid_AVX512VNNI      = 1 << 11\n\t\tcpuid_AVX512BITALG    = 1 << 12\n\t\tcpuid_FMA             = 1 << 12\n\t\tcpuid_AVX512VPOPCNTDQ = 1 << 14\n\t\tcpuid_SSE41           = 1 << 19\n\t\tcpuid_SSE42           = 1 << 20\n\t\tcpuid_POPCNT          = 1 << 23\n\t\tcpuid_AES             = 1 << 25\n\t\tcpuid_OSXSAVE         = 1 << 27\n\t\tcpuid_AVX             = 1 << 28\n\n\t\t// \"Extended Feature Flag\" bits returned in EBX for CPUID EAX=0x7 ECX=0x0\n\t\tcpuid_BMI1     = 1 << 3\n\t\tcpuid_AVX2     = 1 << 5\n\t\tcpuid_BMI2     = 1 << 8\n\t\tcpuid_ERMS     = 1 << 9\n\t\tcpuid_AVX512F  = 1 << 16\n\t\tcpuid_AVX512DQ = 1 << 17\n\t\tcpuid_ADX      = 1 << 19\n\t\tcpuid_AVX512CD = 1 << 28\n\t\tcpuid_SHA      = 1 << 29\n\t\tcpuid_AVX512BW = 1 << 30\n\t\tcpuid_AVX512VL = 1 << 31\n\n\t\t// \"Extended Feature Flag\" bits returned in ECX for CPUID EAX=0x7 ECX=0x0\n\t\tcpuid_AVX512_VBMI      = 1 << 1\n\t\tcpuid_AVX512_VBMI2     = 1 << 6\n\t\tcpuid_GFNI             = 1 << 8\n\t\tcpuid_AVX512VPCLMULQDQ = 1 << 10\n\t\tcpuid_AVX512_BITALG    = 1 << 12\n\n\t\t// edx bits\n\t\tcpuid_FSRM = 1 << 4\n\t\t// edx bits for CPUID 0x80000001\n\t\tcpuid_RDTSCP = 1 << 27\n\t)\n\t// Additional constants not in internal/cpu\n\tconst (\n\t\t// eax=1: edx\n\t\tcpuid_SSE2 = 1 << 26\n\t\t// eax=1: ecx\n\t\tcpuid_CX16   = 1 << 13\n\t\tcpuid_RDRAND = 1 << 30\n\t\t// eax=7,ecx=0: ebx\n\t\tcpuid_RDSEED     = 1 << 18\n\t\tcpuid_AVX512IFMA = 1 << 21\n\t\tcpuid_AVX512PF   = 1 << 26\n\t\tcpuid_AVX512ER   = 1 << 27\n\t\t// eax=7,ecx=0: edx\n\t\tcpuid_AVX5124VNNIW = 1 << 2\n\t\tcpuid_AVX5124FMAPS = 1 << 3\n\t\tcpuid_AMXBF16      = 1 << 22\n\t\tcpuid_AMXTile      = 1 << 24\n\t\tcpuid_AMXInt8      = 1 << 25\n\t\t// eax=7,ecx=1: eax\n\t\tcpuid_AVX512BF16 = 1 << 5\n\t\tcpuid_AVXIFMA    = 1 << 23\n\t\t// eax=7,ecx=1: edx\n\t\tcpuid_AVXVNNIInt8 = 1 << 4\n\t)\n\n\tInitialized = true\n\n\tmaxID, _, _, _ := cpuid(0, 0)\n\n\tif maxID < 1 {\n\t\treturn\n\t}\n\n\t_, _, ecx1, edx1 := cpuid(1, 0)\n\tX86.HasSSE2 = isSet(edx1, cpuid_SSE2)\n\n\tX86.HasSSE3 = isSet(ecx1, cpuid_SSE3)\n\tX86.HasPCLMULQDQ = isSet(ecx1, cpuid_PCLMULQDQ)\n\tX86.HasSSSE3 = isSet(ecx1, cpuid_SSSE3)\n\tX86.HasFMA = isSet(ecx1, cpuid_FMA)\n\tX86.HasCX16 = isSet(ecx1, cpuid_CX16)\n\tX86.HasSSE41 = isSet(ecx1, cpuid_SSE41)\n\tX86.HasSSE42 = isSet(ecx1, cpuid_SSE42)\n\tX86.HasPOPCNT = isSet(ecx1, cpuid_POPCNT)\n\tX86.HasAES = isSet(ecx1, cpuid_AES)\n\tX86.HasOSXSAVE = isSet(ecx1, cpuid_OSXSAVE)\n\tX86.HasRDRAND = isSet(ecx1, cpuid_RDRAND)\n\n\tvar osSupportsAVX, osSupportsAVX512 bool\n\t// For XGETBV, OSXSAVE bit is required and sufficient.\n\tif X86.HasOSXSAVE {\n\t\teax, _ := xgetbv()\n\t\t// Check if XMM and YMM registers have OS support.\n\t\tosSupportsAVX = isSet(eax, 1<<1) && isSet(eax, 1<<2)\n\n\t\tif runtime.GOOS == \"darwin\" {\n\t\t\t// Darwin requires special AVX512 checks, see cpu_darwin_x86.go\n\t\t\tosSupportsAVX512 = osSupportsAVX && darwinSupportsAVX512()\n\t\t} else {\n\t\t\t// Check if OPMASK and ZMM registers have OS support.\n\t\t\tosSupportsAVX512 = osSupportsAVX && isSet(eax, 1<<5) && isSet(eax, 1<<6) && isSet(eax, 1<<7)\n\t\t}\n\t}\n\n\tX86.HasAVX = isSet(ecx1, cpuid_AVX) && osSupportsAVX\n\n\tif maxID < 7 {\n\t\treturn\n\t}\n\n\teax7, ebx7, ecx7, edx7 := cpuid(7, 0)\n\tX86.HasBMI1 = isSet(ebx7, cpuid_BMI1)\n\tX86.HasAVX2 = isSet(ebx7, cpuid_AVX2) && osSupportsAVX\n\tX86.HasBMI2 = isSet(ebx7, cpuid_BMI2)\n\tX86.HasERMS = isSet(ebx7, cpuid_ERMS)\n\tX86.HasRDSEED = isSet(ebx7, cpuid_RDSEED)\n\tX86.HasADX = isSet(ebx7, cpuid_ADX)\n\n\tX86.HasAVX512 = isSet(ebx7, cpuid_AVX512F) && osSupportsAVX512 // Because avx-512 foundation is the core required extension\n\tif X86.HasAVX512 {\n\t\tX86.HasAVX512F = true\n\t\tX86.HasAVX512CD = isSet(ebx7, cpuid_AVX512CD)\n\t\tX86.HasAVX512ER = isSet(ebx7, cpuid_AVX512ER)\n\t\tX86.HasAVX512PF = isSet(ebx7, cpuid_AVX512PF)\n\t\tX86.HasAVX512VL = isSet(ebx7, cpuid_AVX512VL)\n\t\tX86.HasAVX512BW = isSet(ebx7, cpuid_AVX512BW)\n\t\tX86.HasAVX512DQ = isSet(ebx7, cpuid_AVX512DQ)\n\t\tX86.HasAVX512IFMA = isSet(ebx7, cpuid_AVX512IFMA)\n\t\tX86.HasAVX512VBMI = isSet(ecx7, cpuid_AVX512_VBMI)\n\t\tX86.HasAVX5124VNNIW = isSet(edx7, cpuid_AVX5124VNNIW)\n\t\tX86.HasAVX5124FMAPS = isSet(edx7, cpuid_AVX5124FMAPS)\n\t\tX86.HasAVX512VPOPCNTDQ = isSet(ecx7, cpuid_AVX512VPOPCNTDQ)\n\t\tX86.HasAVX512VPCLMULQDQ = isSet(ecx7, cpuid_AVX512VPCLMULQDQ)\n\t\tX86.HasAVX512VNNI = isSet(ecx7, cpuid_AVX512VNNI)\n\t\tX86.HasAVX512GFNI = isSet(ecx7, cpuid_AVX512GFNI)\n\t\tX86.HasAVX512VAES = isSet(ecx7, cpuid_AVX512VAES)\n\t\tX86.HasAVX512VBMI2 = isSet(ecx7, cpuid_AVX512VBMI2)\n\t\tX86.HasAVX512BITALG = isSet(ecx7, cpuid_AVX512BITALG)\n\t}\n\n\tX86.HasAMXTile = isSet(edx7, cpuid_AMXTile)\n\tX86.HasAMXInt8 = isSet(edx7, cpuid_AMXInt8)\n\tX86.HasAMXBF16 = isSet(edx7, cpuid_AMXBF16)\n\n\t// These features depend on the second level of extended features.\n\tif eax7 >= 1 {\n\t\teax71, _, _, edx71 := cpuid(7, 1)\n\t\tif X86.HasAVX512 {\n\t\t\tX86.HasAVX512BF16 = isSet(eax71, cpuid_AVX512BF16)\n\t\t}\n\t\tif X86.HasAVX {\n\t\t\tX86.HasAVXIFMA = isSet(eax71, cpuid_AVXIFMA)\n\t\t\tX86.HasAVXVNNI = isSet(eax71, cpuid_AVXVNNI)\n\t\t\tX86.HasAVXVNNIInt8 = isSet(edx71, cpuid_AVXVNNIInt8)\n\t\t}\n\t}\n}\n\nfunc isSet(hwc uint32, value uint32) bool {\n\treturn hwc&value != 0\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_zos.go",
    "content": "// Copyright 2020 The Go 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 cpu\n\nfunc archInit() {\n\tdoinit()\n\tInitialized = true\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/cpu_zos_s390x.go",
    "content": "// Copyright 2020 The Go 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 cpu\n\nfunc initS390Xbase() {\n\t// get the facilities list\n\tfacilities := stfle()\n\n\t// mandatory\n\tS390X.HasZARCH = facilities.Has(zarch)\n\tS390X.HasSTFLE = facilities.Has(stflef)\n\tS390X.HasLDISP = facilities.Has(ldisp)\n\tS390X.HasEIMM = facilities.Has(eimm)\n\n\t// optional\n\tS390X.HasETF3EH = facilities.Has(etf3eh)\n\tS390X.HasDFP = facilities.Has(dfp)\n\tS390X.HasMSA = facilities.Has(msa)\n\tS390X.HasVX = facilities.Has(vx)\n\tif S390X.HasVX {\n\t\tS390X.HasVXE = facilities.Has(vxe)\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/endian_big.go",
    "content": "// Copyright 2023 The Go 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\n//go:build armbe || arm64be || m68k || mips || mips64 || mips64p32 || ppc || ppc64 || s390 || s390x || shbe || sparc || sparc64\n\npackage cpu\n\n// IsBigEndian records whether the GOARCH's byte order is big endian.\nconst IsBigEndian = true\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/endian_little.go",
    "content": "// Copyright 2023 The Go 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\n//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh || wasm\n\npackage cpu\n\n// IsBigEndian records whether the GOARCH's byte order is big endian.\nconst IsBigEndian = false\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/hwcap_linux.go",
    "content": "// Copyright 2019 The Go 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 cpu\n\nimport (\n\t\"os\"\n)\n\nconst (\n\t_AT_HWCAP  = 16\n\t_AT_HWCAP2 = 26\n\n\tprocAuxv = \"/proc/self/auxv\"\n\n\tuintSize = int(32 << (^uint(0) >> 63))\n)\n\n// For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2\n// These are initialized in cpu_$GOARCH.go\n// and should not be changed after they are initialized.\nvar hwCap uint\nvar hwCap2 uint\n\nfunc readHWCAP() error {\n\t// For Go 1.21+, get auxv from the Go runtime.\n\tif a := getAuxv(); len(a) > 0 {\n\t\tfor len(a) >= 2 {\n\t\t\ttag, val := a[0], uint(a[1])\n\t\t\ta = a[2:]\n\t\t\tswitch tag {\n\t\t\tcase _AT_HWCAP:\n\t\t\t\thwCap = val\n\t\t\tcase _AT_HWCAP2:\n\t\t\t\thwCap2 = val\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\n\tbuf, err := os.ReadFile(procAuxv)\n\tif err != nil {\n\t\t// e.g. on android /proc/self/auxv is not accessible, so silently\n\t\t// ignore the error and leave Initialized = false. On some\n\t\t// architectures (e.g. arm64) doinit() implements a fallback\n\t\t// readout and will set Initialized = true again.\n\t\treturn err\n\t}\n\tbo := hostByteOrder()\n\tfor len(buf) >= 2*(uintSize/8) {\n\t\tvar tag, val uint\n\t\tswitch uintSize {\n\t\tcase 32:\n\t\t\ttag = uint(bo.Uint32(buf[0:]))\n\t\t\tval = uint(bo.Uint32(buf[4:]))\n\t\t\tbuf = buf[8:]\n\t\tcase 64:\n\t\t\ttag = uint(bo.Uint64(buf[0:]))\n\t\t\tval = uint(bo.Uint64(buf[8:]))\n\t\t\tbuf = buf[16:]\n\t\t}\n\t\tswitch tag {\n\t\tcase _AT_HWCAP:\n\t\t\thwCap = val\n\t\tcase _AT_HWCAP2:\n\t\t\thwCap2 = val\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/parse.go",
    "content": "// Copyright 2022 The Go 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 cpu\n\nimport \"strconv\"\n\n// parseRelease parses a dot-separated version number. It follows the semver\n// syntax, but allows the minor and patch versions to be elided.\n//\n// This is a copy of the Go runtime's parseRelease from\n// https://golang.org/cl/209597.\nfunc parseRelease(rel string) (major, minor, patch int, ok bool) {\n\t// Strip anything after a dash or plus.\n\tfor i := range len(rel) {\n\t\tif rel[i] == '-' || rel[i] == '+' {\n\t\t\trel = rel[:i]\n\t\t\tbreak\n\t\t}\n\t}\n\n\tnext := func() (int, bool) {\n\t\tfor i := range len(rel) {\n\t\t\tif rel[i] == '.' {\n\t\t\t\tver, err := strconv.Atoi(rel[:i])\n\t\t\t\trel = rel[i+1:]\n\t\t\t\treturn ver, err == nil\n\t\t\t}\n\t\t}\n\t\tver, err := strconv.Atoi(rel)\n\t\trel = \"\"\n\t\treturn ver, err == nil\n\t}\n\tif major, ok = next(); !ok || rel == \"\" {\n\t\treturn\n\t}\n\tif minor, ok = next(); !ok || rel == \"\" {\n\t\treturn\n\t}\n\tpatch, ok = next()\n\treturn\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/proc_cpuinfo_linux.go",
    "content": "// Copyright 2022 The Go 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\n//go:build linux && arm64\n\npackage cpu\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc readLinuxProcCPUInfo() error {\n\tf, err := os.Open(\"/proc/cpuinfo\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer f.Close()\n\n\tvar buf [1 << 10]byte // enough for first CPU\n\tn, err := io.ReadFull(f, buf[:])\n\tif err != nil && err != io.ErrUnexpectedEOF {\n\t\treturn err\n\t}\n\tin := string(buf[:n])\n\tconst features = \"\\nFeatures\t: \"\n\ti := strings.Index(in, features)\n\tif i == -1 {\n\t\treturn errors.New(\"no CPU features found\")\n\t}\n\tin = in[i+len(features):]\n\tif i := strings.Index(in, \"\\n\"); i != -1 {\n\t\tin = in[:i]\n\t}\n\tm := map[string]*bool{}\n\n\tinitOptions() // need it early here; it's harmless to call twice\n\tfor _, o := range options {\n\t\tm[o.Name] = o.Feature\n\t}\n\t// The EVTSTRM field has alias \"evstrm\" in Go, but Linux calls it \"evtstrm\".\n\tm[\"evtstrm\"] = &ARM64.HasEVTSTRM\n\n\tfor _, f := range strings.Fields(in) {\n\t\tif p, ok := m[f]; ok {\n\t\t\t*p = true\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/runtime_auxv.go",
    "content": "// Copyright 2023 The Go 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 cpu\n\n// getAuxvFn is non-nil on Go 1.21+ (via runtime_auxv_go121.go init)\n// on platforms that use auxv.\nvar getAuxvFn func() []uintptr\n\nfunc getAuxv() []uintptr {\n\tif getAuxvFn == nil {\n\t\treturn nil\n\t}\n\treturn getAuxvFn()\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/runtime_auxv_go121.go",
    "content": "// Copyright 2023 The Go 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\n//go:build go1.21\n\npackage cpu\n\nimport (\n\t_ \"unsafe\" // for linkname\n)\n\n//go:linkname runtime_getAuxv runtime.getAuxv\nfunc runtime_getAuxv() []uintptr\n\nfunc init() {\n\tgetAuxvFn = runtime_getAuxv\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/syscall_aix_gccgo.go",
    "content": "// Copyright 2020 The Go 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\n// Recreate a getsystemcfg syscall handler instead of\n// using the one provided by x/sys/unix to avoid having\n// the dependency between them. (See golang.org/issue/32102)\n// Moreover, this file will be used during the building of\n// gccgo's libgo and thus must not used a CGo method.\n\n//go:build aix && gccgo\n\npackage cpu\n\nimport (\n\t\"syscall\"\n)\n\n//extern getsystemcfg\nfunc gccgoGetsystemcfg(label uint32) (r uint64)\n\nfunc callgetsystemcfg(label int) (r1 uintptr, e1 syscall.Errno) {\n\tr1 = uintptr(gccgoGetsystemcfg(uint32(label)))\n\te1 = syscall.GetErrno()\n\treturn\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go",
    "content": "// Copyright 2019 The Go 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\n// Minimal copy of x/sys/unix so the cpu package can make a\n// system call on AIX without depending on x/sys/unix.\n// (See golang.org/issue/32102)\n\n//go:build aix && ppc64 && gc\n\npackage cpu\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n//go:cgo_import_dynamic libc_getsystemcfg getsystemcfg \"libc.a/shr_64.o\"\n\n//go:linkname libc_getsystemcfg libc_getsystemcfg\n\ntype syscallFunc uintptr\n\nvar libc_getsystemcfg syscallFunc\n\ntype errno = syscall.Errno\n\n// Implemented in runtime/syscall_aix.go.\nfunc rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err errno)\nfunc syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err errno)\n\nfunc callgetsystemcfg(label int) (r1 uintptr, e1 errno) {\n\tr1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_getsystemcfg)), 1, uintptr(label), 0, 0, 0, 0, 0)\n\treturn\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/cpu/syscall_darwin_x86_gc.go",
    "content": "// Copyright 2024 The Go 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\n// Minimal copy of x/sys/unix so the cpu package can make a\n// system call on Darwin without depending on x/sys/unix.\n\n//go:build darwin && amd64 && gc\n\npackage cpu\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\ntype _C_int int32\n\n// adapted from unix.Uname() at x/sys/unix/syscall_darwin.go L419\nfunc darwinOSRelease(release *[256]byte) error {\n\t// from x/sys/unix/zerrors_openbsd_amd64.go\n\tconst (\n\t\tCTL_KERN       = 0x1\n\t\tKERN_OSRELEASE = 0x2\n\t)\n\n\tmib := []_C_int{CTL_KERN, KERN_OSRELEASE}\n\tn := unsafe.Sizeof(*release)\n\n\treturn sysctl(mib, &release[0], &n, nil, 0)\n}\n\ntype Errno = syscall.Errno\n\nvar _zero uintptr // Single-word zero for use when we need a valid pointer to 0 bytes.\n\n// from x/sys/unix/zsyscall_darwin_amd64.go L791-807\nfunc sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) error {\n\tvar _p0 unsafe.Pointer\n\tif len(mib) > 0 {\n\t\t_p0 = unsafe.Pointer(&mib[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tif _, _, err := syscall_syscall6(\n\t\tlibc_sysctl_trampoline_addr,\n\t\tuintptr(_p0),\n\t\tuintptr(len(mib)),\n\t\tuintptr(unsafe.Pointer(old)),\n\t\tuintptr(unsafe.Pointer(oldlen)),\n\t\tuintptr(unsafe.Pointer(new)),\n\t\tuintptr(newlen),\n\t); err != 0 {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nvar libc_sysctl_trampoline_addr uintptr\n\n// adapted from internal/cpu/cpu_arm64_darwin.go\nfunc darwinSysctlEnabled(name []byte) bool {\n\tout := int32(0)\n\tnout := unsafe.Sizeof(out)\n\tif ret := sysctlbyname(&name[0], (*byte)(unsafe.Pointer(&out)), &nout, nil, 0); ret != nil {\n\t\treturn false\n\t}\n\treturn out > 0\n}\n\n//go:cgo_import_dynamic libc_sysctl sysctl \"/usr/lib/libSystem.B.dylib\"\n\nvar libc_sysctlbyname_trampoline_addr uintptr\n\n// adapted from runtime/sys_darwin.go in the pattern of sysctl() above, as defined in x/sys/unix\nfunc sysctlbyname(name *byte, old *byte, oldlen *uintptr, new *byte, newlen uintptr) error {\n\tif _, _, err := syscall_syscall6(\n\t\tlibc_sysctlbyname_trampoline_addr,\n\t\tuintptr(unsafe.Pointer(name)),\n\t\tuintptr(unsafe.Pointer(old)),\n\t\tuintptr(unsafe.Pointer(oldlen)),\n\t\tuintptr(unsafe.Pointer(new)),\n\t\tuintptr(newlen),\n\t\t0,\n\t); err != 0 {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n//go:cgo_import_dynamic libc_sysctlbyname sysctlbyname \"/usr/lib/libSystem.B.dylib\"\n\n// Implemented in the runtime package (runtime/sys_darwin.go)\nfunc syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)\n\n//go:linkname syscall_syscall6 syscall.syscall6\n"
  },
  {
    "path": "vendor/golang.org/x/sys/execabs/execabs.go",
    "content": "// Copyright 2020 The Go 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\n// Package execabs is a drop-in replacement for os/exec\n// that requires PATH lookups to find absolute paths.\n// That is, execabs.Command(\"cmd\") runs the same PATH lookup\n// as exec.Command(\"cmd\"), but if the result is a path\n// which is relative, the Run and Start methods will report\n// an error instead of running the executable.\n//\n// See https://blog.golang.org/path-security for more information\n// about when it may be necessary or appropriate to use this package.\npackage execabs\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"unsafe\"\n)\n\n// ErrNotFound is the error resulting if a path search failed to find an executable file.\n// It is an alias for exec.ErrNotFound.\nvar ErrNotFound = exec.ErrNotFound\n\n// Cmd represents an external command being prepared or run.\n// It is an alias for exec.Cmd.\ntype Cmd = exec.Cmd\n\n// Error is returned by LookPath when it fails to classify a file as an executable.\n// It is an alias for exec.Error.\ntype Error = exec.Error\n\n// An ExitError reports an unsuccessful exit by a command.\n// It is an alias for exec.ExitError.\ntype ExitError = exec.ExitError\n\nfunc relError(file, path string) error {\n\treturn fmt.Errorf(\"%s resolves to executable in current directory (.%c%s)\", file, filepath.Separator, path)\n}\n\n// LookPath searches for an executable named file in the directories\n// named by the PATH environment variable. If file contains a slash,\n// it is tried directly and the PATH is not consulted. The result will be\n// an absolute path.\n//\n// LookPath differs from exec.LookPath in its handling of PATH lookups,\n// which are used for file names without slashes. If exec.LookPath's\n// PATH lookup would have returned an executable from the current directory,\n// LookPath instead returns an error.\nfunc LookPath(file string) (string, error) {\n\tpath, err := exec.LookPath(file)\n\tif err != nil && !isGo119ErrDot(err) {\n\t\treturn \"\", err\n\t}\n\tif filepath.Base(file) == file && !filepath.IsAbs(path) {\n\t\treturn \"\", relError(file, path)\n\t}\n\treturn path, nil\n}\n\nfunc fixCmd(name string, cmd *exec.Cmd) {\n\tif filepath.Base(name) == name && !filepath.IsAbs(cmd.Path) && !isGo119ErrFieldSet(cmd) {\n\t\t// exec.Command was called with a bare binary name and\n\t\t// exec.LookPath returned a path which is not absolute.\n\t\t// Set cmd.lookPathErr and clear cmd.Path so that it\n\t\t// cannot be run.\n\t\tlookPathErr := (*error)(unsafe.Pointer(reflect.ValueOf(cmd).Elem().FieldByName(\"lookPathErr\").Addr().Pointer()))\n\t\tif *lookPathErr == nil {\n\t\t\t*lookPathErr = relError(name, cmd.Path)\n\t\t}\n\t\tcmd.Path = \"\"\n\t}\n}\n\n// CommandContext is like Command but includes a context.\n//\n// The provided context is used to kill the process (by calling os.Process.Kill)\n// if the context becomes done before the command completes on its own.\nfunc CommandContext(ctx context.Context, name string, arg ...string) *exec.Cmd {\n\tcmd := exec.CommandContext(ctx, name, arg...)\n\tfixCmd(name, cmd)\n\treturn cmd\n\n}\n\n// Command returns the Cmd struct to execute the named program with the given arguments.\n// See exec.Command for most details.\n//\n// Command differs from exec.Command in its handling of PATH lookups,\n// which are used when the program name contains no slashes.\n// If exec.Command would have returned an exec.Cmd configured to run an\n// executable from the current directory, Command instead\n// returns an exec.Cmd that will return an error from Start or Run.\nfunc Command(name string, arg ...string) *exec.Cmd {\n\tcmd := exec.Command(name, arg...)\n\tfixCmd(name, cmd)\n\treturn cmd\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/execabs/execabs_go118.go",
    "content": "// Copyright 2022 The Go 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\n//go:build !go1.19\n\npackage execabs\n\nimport \"os/exec\"\n\nfunc isGo119ErrDot(err error) bool {\n\treturn false\n}\n\nfunc isGo119ErrFieldSet(cmd *exec.Cmd) bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/execabs/execabs_go119.go",
    "content": "// Copyright 2022 The Go 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\n//go:build go1.19\n\npackage execabs\n\nimport (\n\t\"errors\"\n\t\"os/exec\"\n)\n\nfunc isGo119ErrDot(err error) bool {\n\treturn errors.Is(err, exec.ErrDot)\n}\n\nfunc isGo119ErrFieldSet(cmd *exec.Cmd) bool {\n\treturn cmd.Err != nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/asm.s",
    "content": "// Copyright 2014 The Go 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\n#include \"textflag.h\"\n\nTEXT ·use(SB),NOSPLIT,$0\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/asm_plan9_386.s",
    "content": "// Copyright 2009 The Go 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\n#include \"textflag.h\"\n\n//\n// System call support for 386, Plan 9\n//\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT\t·Syscall(SB),NOSPLIT,$0-32\n\tJMP\tsyscall·Syscall(SB)\n\nTEXT\t·Syscall6(SB),NOSPLIT,$0-44\n\tJMP\tsyscall·Syscall6(SB)\n\nTEXT ·RawSyscall(SB),NOSPLIT,$0-28\n\tJMP\tsyscall·RawSyscall(SB)\n\nTEXT ·RawSyscall6(SB),NOSPLIT,$0-40\n\tJMP\tsyscall·RawSyscall6(SB)\n\nTEXT ·seek(SB),NOSPLIT,$0-36\n\tJMP\tsyscall·seek(SB)\n\nTEXT ·exit(SB),NOSPLIT,$4-4\n\tJMP\tsyscall·exit(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s",
    "content": "// Copyright 2009 The Go 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\n#include \"textflag.h\"\n\n//\n// System call support for amd64, Plan 9\n//\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT\t·Syscall(SB),NOSPLIT,$0-64\n\tJMP\tsyscall·Syscall(SB)\n\nTEXT\t·Syscall6(SB),NOSPLIT,$0-88\n\tJMP\tsyscall·Syscall6(SB)\n\nTEXT ·RawSyscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·RawSyscall(SB)\n\nTEXT\t·RawSyscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·RawSyscall6(SB)\n\nTEXT ·seek(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·seek(SB)\n\nTEXT ·exit(SB),NOSPLIT,$8-8\n\tJMP\tsyscall·exit(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/asm_plan9_arm.s",
    "content": "// Copyright 2009 The Go 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\n#include \"textflag.h\"\n\n// System call support for plan9 on arm\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT ·Syscall(SB),NOSPLIT,$0-32\n\tJMP\tsyscall·Syscall(SB)\n\nTEXT ·Syscall6(SB),NOSPLIT,$0-44\n\tJMP\tsyscall·Syscall6(SB)\n\nTEXT ·RawSyscall(SB),NOSPLIT,$0-28\n\tJMP\tsyscall·RawSyscall(SB)\n\nTEXT ·RawSyscall6(SB),NOSPLIT,$0-40\n\tJMP\tsyscall·RawSyscall6(SB)\n\nTEXT ·seek(SB),NOSPLIT,$0-36\n\tJMP\tsyscall·exit(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/const_plan9.go",
    "content": "package plan9\n\n// Plan 9 Constants\n\n// Open modes\nconst (\n\tO_RDONLY  = 0\n\tO_WRONLY  = 1\n\tO_RDWR    = 2\n\tO_TRUNC   = 16\n\tO_CLOEXEC = 32\n\tO_EXCL    = 0x1000\n)\n\n// Rfork flags\nconst (\n\tRFNAMEG  = 1 << 0\n\tRFENVG   = 1 << 1\n\tRFFDG    = 1 << 2\n\tRFNOTEG  = 1 << 3\n\tRFPROC   = 1 << 4\n\tRFMEM    = 1 << 5\n\tRFNOWAIT = 1 << 6\n\tRFCNAMEG = 1 << 10\n\tRFCENVG  = 1 << 11\n\tRFCFDG   = 1 << 12\n\tRFREND   = 1 << 13\n\tRFNOMNT  = 1 << 14\n)\n\n// Qid.Type bits\nconst (\n\tQTDIR    = 0x80\n\tQTAPPEND = 0x40\n\tQTEXCL   = 0x20\n\tQTMOUNT  = 0x10\n\tQTAUTH   = 0x08\n\tQTTMP    = 0x04\n\tQTFILE   = 0x00\n)\n\n// Dir.Mode bits\nconst (\n\tDMDIR    = 0x80000000\n\tDMAPPEND = 0x40000000\n\tDMEXCL   = 0x20000000\n\tDMMOUNT  = 0x10000000\n\tDMAUTH   = 0x08000000\n\tDMTMP    = 0x04000000\n\tDMREAD   = 0x4\n\tDMWRITE  = 0x2\n\tDMEXEC   = 0x1\n)\n\nconst (\n\tSTATMAX    = 65535\n\tERRMAX     = 128\n\tSTATFIXLEN = 49\n)\n\n// Mount and bind flags\nconst (\n\tMREPL   = 0x0000\n\tMBEFORE = 0x0001\n\tMAFTER  = 0x0002\n\tMORDER  = 0x0003\n\tMCREATE = 0x0004\n\tMCACHE  = 0x0010\n\tMMASK   = 0x0017\n)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/dir_plan9.go",
    "content": "// Copyright 2012 The Go 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\n// Plan 9 directory marshalling. See intro(5).\n\npackage plan9\n\nimport \"errors\"\n\nvar (\n\tErrShortStat = errors.New(\"stat buffer too short\")\n\tErrBadStat   = errors.New(\"malformed stat buffer\")\n\tErrBadName   = errors.New(\"bad character in file name\")\n)\n\n// A Qid represents a 9P server's unique identification for a file.\ntype Qid struct {\n\tPath uint64 // the file server's unique identification for the file\n\tVers uint32 // version number for given Path\n\tType uint8  // the type of the file (plan9.QTDIR for example)\n}\n\n// A Dir contains the metadata for a file.\ntype Dir struct {\n\t// system-modified data\n\tType uint16 // server type\n\tDev  uint32 // server subtype\n\n\t// file data\n\tQid    Qid    // unique id from server\n\tMode   uint32 // permissions\n\tAtime  uint32 // last read time\n\tMtime  uint32 // last write time\n\tLength int64  // file length\n\tName   string // last element of path\n\tUid    string // owner name\n\tGid    string // group name\n\tMuid   string // last modifier name\n}\n\nvar nullDir = Dir{\n\tType: ^uint16(0),\n\tDev:  ^uint32(0),\n\tQid: Qid{\n\t\tPath: ^uint64(0),\n\t\tVers: ^uint32(0),\n\t\tType: ^uint8(0),\n\t},\n\tMode:   ^uint32(0),\n\tAtime:  ^uint32(0),\n\tMtime:  ^uint32(0),\n\tLength: ^int64(0),\n}\n\n// Null assigns special \"don't touch\" values to members of d to\n// avoid modifying them during plan9.Wstat.\nfunc (d *Dir) Null() { *d = nullDir }\n\n// Marshal encodes a 9P stat message corresponding to d into b\n//\n// If there isn't enough space in b for a stat message, ErrShortStat is returned.\nfunc (d *Dir) Marshal(b []byte) (n int, err error) {\n\tn = STATFIXLEN + len(d.Name) + len(d.Uid) + len(d.Gid) + len(d.Muid)\n\tif n > len(b) {\n\t\treturn n, ErrShortStat\n\t}\n\n\tfor _, c := range d.Name {\n\t\tif c == '/' {\n\t\t\treturn n, ErrBadName\n\t\t}\n\t}\n\n\tb = pbit16(b, uint16(n)-2)\n\tb = pbit16(b, d.Type)\n\tb = pbit32(b, d.Dev)\n\tb = pbit8(b, d.Qid.Type)\n\tb = pbit32(b, d.Qid.Vers)\n\tb = pbit64(b, d.Qid.Path)\n\tb = pbit32(b, d.Mode)\n\tb = pbit32(b, d.Atime)\n\tb = pbit32(b, d.Mtime)\n\tb = pbit64(b, uint64(d.Length))\n\tb = pstring(b, d.Name)\n\tb = pstring(b, d.Uid)\n\tb = pstring(b, d.Gid)\n\tb = pstring(b, d.Muid)\n\n\treturn n, nil\n}\n\n// UnmarshalDir decodes a single 9P stat message from b and returns the resulting Dir.\n//\n// If b is too small to hold a valid stat message, ErrShortStat is returned.\n//\n// If the stat message itself is invalid, ErrBadStat is returned.\nfunc UnmarshalDir(b []byte) (*Dir, error) {\n\tif len(b) < STATFIXLEN {\n\t\treturn nil, ErrShortStat\n\t}\n\tsize, buf := gbit16(b)\n\tif len(b) != int(size)+2 {\n\t\treturn nil, ErrBadStat\n\t}\n\tb = buf\n\n\tvar d Dir\n\td.Type, b = gbit16(b)\n\td.Dev, b = gbit32(b)\n\td.Qid.Type, b = gbit8(b)\n\td.Qid.Vers, b = gbit32(b)\n\td.Qid.Path, b = gbit64(b)\n\td.Mode, b = gbit32(b)\n\td.Atime, b = gbit32(b)\n\td.Mtime, b = gbit32(b)\n\n\tn, b := gbit64(b)\n\td.Length = int64(n)\n\n\tvar ok bool\n\tif d.Name, b, ok = gstring(b); !ok {\n\t\treturn nil, ErrBadStat\n\t}\n\tif d.Uid, b, ok = gstring(b); !ok {\n\t\treturn nil, ErrBadStat\n\t}\n\tif d.Gid, b, ok = gstring(b); !ok {\n\t\treturn nil, ErrBadStat\n\t}\n\tif d.Muid, b, ok = gstring(b); !ok {\n\t\treturn nil, ErrBadStat\n\t}\n\n\treturn &d, nil\n}\n\n// pbit8 copies the 8-bit number v to b and returns the remaining slice of b.\nfunc pbit8(b []byte, v uint8) []byte {\n\tb[0] = byte(v)\n\treturn b[1:]\n}\n\n// pbit16 copies the 16-bit number v to b in little-endian order and returns the remaining slice of b.\nfunc pbit16(b []byte, v uint16) []byte {\n\tb[0] = byte(v)\n\tb[1] = byte(v >> 8)\n\treturn b[2:]\n}\n\n// pbit32 copies the 32-bit number v to b in little-endian order and returns the remaining slice of b.\nfunc pbit32(b []byte, v uint32) []byte {\n\tb[0] = byte(v)\n\tb[1] = byte(v >> 8)\n\tb[2] = byte(v >> 16)\n\tb[3] = byte(v >> 24)\n\treturn b[4:]\n}\n\n// pbit64 copies the 64-bit number v to b in little-endian order and returns the remaining slice of b.\nfunc pbit64(b []byte, v uint64) []byte {\n\tb[0] = byte(v)\n\tb[1] = byte(v >> 8)\n\tb[2] = byte(v >> 16)\n\tb[3] = byte(v >> 24)\n\tb[4] = byte(v >> 32)\n\tb[5] = byte(v >> 40)\n\tb[6] = byte(v >> 48)\n\tb[7] = byte(v >> 56)\n\treturn b[8:]\n}\n\n// pstring copies the string s to b, prepending it with a 16-bit length in little-endian order, and\n// returning the remaining slice of b..\nfunc pstring(b []byte, s string) []byte {\n\tb = pbit16(b, uint16(len(s)))\n\tn := copy(b, s)\n\treturn b[n:]\n}\n\n// gbit8 reads an 8-bit number from b and returns it with the remaining slice of b.\nfunc gbit8(b []byte) (uint8, []byte) {\n\treturn uint8(b[0]), b[1:]\n}\n\n// gbit16 reads a 16-bit number in little-endian order from b and returns it with the remaining slice of b.\nfunc gbit16(b []byte) (uint16, []byte) {\n\treturn uint16(b[0]) | uint16(b[1])<<8, b[2:]\n}\n\n// gbit32 reads a 32-bit number in little-endian order from b and returns it with the remaining slice of b.\nfunc gbit32(b []byte) (uint32, []byte) {\n\treturn uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24, b[4:]\n}\n\n// gbit64 reads a 64-bit number in little-endian order from b and returns it with the remaining slice of b.\nfunc gbit64(b []byte) (uint64, []byte) {\n\tlo := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24\n\thi := uint32(b[4]) | uint32(b[5])<<8 | uint32(b[6])<<16 | uint32(b[7])<<24\n\treturn uint64(lo) | uint64(hi)<<32, b[8:]\n}\n\n// gstring reads a string from b, prefixed with a 16-bit length in little-endian order.\n// It returns the string with the remaining slice of b and a boolean. If the length is\n// greater than the number of bytes in b, the boolean will be false.\nfunc gstring(b []byte) (string, []byte, bool) {\n\tn, b := gbit16(b)\n\tif int(n) > len(b) {\n\t\treturn \"\", b, false\n\t}\n\treturn string(b[:n]), b[n:], true\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/env_plan9.go",
    "content": "// Copyright 2011 The Go 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\n// Plan 9 environment variables.\n\npackage plan9\n\nimport (\n\t\"syscall\"\n)\n\nfunc Getenv(key string) (value string, found bool) {\n\treturn syscall.Getenv(key)\n}\n\nfunc Setenv(key, value string) error {\n\treturn syscall.Setenv(key, value)\n}\n\nfunc Clearenv() {\n\tsyscall.Clearenv()\n}\n\nfunc Environ() []string {\n\treturn syscall.Environ()\n}\n\nfunc Unsetenv(key string) error {\n\treturn syscall.Unsetenv(key)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/errors_plan9.go",
    "content": "// Copyright 2011 The Go 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 plan9\n\nimport \"syscall\"\n\n// Constants\nconst (\n\t// Invented values to support what package os expects.\n\tO_CREAT    = 0x02000\n\tO_APPEND   = 0x00400\n\tO_NOCTTY   = 0x00000\n\tO_NONBLOCK = 0x00000\n\tO_SYNC     = 0x00000\n\tO_ASYNC    = 0x00000\n\n\tS_IFMT   = 0x1f000\n\tS_IFIFO  = 0x1000\n\tS_IFCHR  = 0x2000\n\tS_IFDIR  = 0x4000\n\tS_IFBLK  = 0x6000\n\tS_IFREG  = 0x8000\n\tS_IFLNK  = 0xa000\n\tS_IFSOCK = 0xc000\n)\n\n// Errors\nvar (\n\tEINVAL       = syscall.NewError(\"bad arg in system call\")\n\tENOTDIR      = syscall.NewError(\"not a directory\")\n\tEISDIR       = syscall.NewError(\"file is a directory\")\n\tENOENT       = syscall.NewError(\"file does not exist\")\n\tEEXIST       = syscall.NewError(\"file already exists\")\n\tEMFILE       = syscall.NewError(\"no free file descriptors\")\n\tEIO          = syscall.NewError(\"i/o error\")\n\tENAMETOOLONG = syscall.NewError(\"file name too long\")\n\tEINTR        = syscall.NewError(\"interrupted\")\n\tEPERM        = syscall.NewError(\"permission denied\")\n\tEBUSY        = syscall.NewError(\"no free devices\")\n\tETIMEDOUT    = syscall.NewError(\"connection timed out\")\n\tEPLAN9       = syscall.NewError(\"not supported by plan 9\")\n\n\t// The following errors do not correspond to any\n\t// Plan 9 system messages. Invented to support\n\t// what package os and others expect.\n\tEACCES       = syscall.NewError(\"access permission denied\")\n\tEAFNOSUPPORT = syscall.NewError(\"address family not supported by protocol\")\n)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/mkall.sh",
    "content": "#!/usr/bin/env bash\n# Copyright 2009 The Go 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\n# The plan9 package provides access to the raw system call\n# interface of the underlying operating system.  Porting Go to\n# a new architecture/operating system combination requires\n# some manual effort, though there are tools that automate\n# much of the process.  The auto-generated files have names\n# beginning with z.\n#\n# This script runs or (given -n) prints suggested commands to generate z files\n# for the current system.  Running those commands is not automatic.\n# This script is documentation more than anything else.\n#\n# * asm_${GOOS}_${GOARCH}.s\n#\n# This hand-written assembly file implements system call dispatch.\n# There are three entry points:\n#\n# \tfunc Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);\n# \tfunc Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);\n# \tfunc RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);\n#\n# The first and second are the standard ones; they differ only in\n# how many arguments can be passed to the kernel.\n# The third is for low-level use by the ForkExec wrapper;\n# unlike the first two, it does not call into the scheduler to\n# let it know that a system call is running.\n#\n# * syscall_${GOOS}.go\n#\n# This hand-written Go file implements system calls that need\n# special handling and lists \"//sys\" comments giving prototypes\n# for ones that can be auto-generated.  Mksyscall reads those\n# comments to generate the stubs.\n#\n# * syscall_${GOOS}_${GOARCH}.go\n#\n# Same as syscall_${GOOS}.go except that it contains code specific\n# to ${GOOS} on one particular architecture.\n#\n# * types_${GOOS}.c\n#\n# This hand-written C file includes standard C headers and then\n# creates typedef or enum names beginning with a dollar sign\n# (use of $ in variable names is a gcc extension).  The hardest\n# part about preparing this file is figuring out which headers to\n# include and which symbols need to be #defined to get the\n# actual data structures that pass through to the kernel system calls.\n# Some C libraries present alternate versions for binary compatibility\n# and translate them on the way in and out of system calls, but\n# there is almost always a #define that can get the real ones.\n# See types_darwin.c and types_linux.c for examples.\n#\n# * zerror_${GOOS}_${GOARCH}.go\n#\n# This machine-generated file defines the system's error numbers,\n# error strings, and signal numbers.  The generator is \"mkerrors.sh\".\n# Usually no arguments are needed, but mkerrors.sh will pass its\n# arguments on to godefs.\n#\n# * zsyscall_${GOOS}_${GOARCH}.go\n#\n# Generated by mksyscall.pl; see syscall_${GOOS}.go above.\n#\n# * zsysnum_${GOOS}_${GOARCH}.go\n#\n# Generated by mksysnum_${GOOS}.\n#\n# * ztypes_${GOOS}_${GOARCH}.go\n#\n# Generated by godefs; see types_${GOOS}.c above.\n\nGOOSARCH=\"${GOOS}_${GOARCH}\"\n\n# defaults\nmksyscall=\"go run mksyscall.go\"\nmkerrors=\"./mkerrors.sh\"\nzerrors=\"zerrors_$GOOSARCH.go\"\nmksysctl=\"\"\nzsysctl=\"zsysctl_$GOOSARCH.go\"\nmksysnum=\nmktypes=\nrun=\"sh\"\n\ncase \"$1\" in\n-syscalls)\n\tfor i in zsyscall*go\n\tdo\n\t\tsed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i\n\t\trm _$i\n\tdone\n\texit 0\n\t;;\n-n)\n\trun=\"cat\"\n\tshift\nesac\n\ncase \"$#\" in\n0)\n\t;;\n*)\n\techo 'usage: mkall.sh [-n]' 1>&2\n\texit 2\nesac\n\ncase \"$GOOSARCH\" in\n_* | *_ | _)\n\techo 'undefined $GOOS_$GOARCH:' \"$GOOSARCH\" 1>&2\n\texit 1\n\t;;\nplan9_386)\n\tmkerrors=\n\tmksyscall=\"go run mksyscall.go -l32 -plan9 -tags plan9,386\"\n\tmksysnum=\"./mksysnum_plan9.sh /n/sources/plan9/sys/src/libc/9syscall/sys.h\"\n\tmktypes=\"XXX\"\n\t;;\nplan9_amd64)\n\tmkerrors=\n\tmksyscall=\"go run mksyscall.go -l32 -plan9 -tags plan9,amd64\"\n\tmksysnum=\"./mksysnum_plan9.sh /n/sources/plan9/sys/src/libc/9syscall/sys.h\"\n\tmktypes=\"XXX\"\n\t;;\nplan9_arm)\n\tmkerrors=\n\tmksyscall=\"go run mksyscall.go -l32 -plan9 -tags plan9,arm\"\n\tmksysnum=\"./mksysnum_plan9.sh /n/sources/plan9/sys/src/libc/9syscall/sys.h\"\n\tmktypes=\"XXX\"\n\t;;\n*)\n\techo 'unrecognized $GOOS_$GOARCH: ' \"$GOOSARCH\" 1>&2\n\texit 1\n\t;;\nesac\n\n(\n\tif [ -n \"$mkerrors\" ]; then echo \"$mkerrors |gofmt >$zerrors\"; fi\n\tcase \"$GOOS\" in\n\tplan9)\n\t\tsyscall_goos=\"syscall_$GOOS.go\"\n\t\tif [ -n \"$mksyscall\" ]; then echo \"$mksyscall $syscall_goos |gofmt >zsyscall_$GOOSARCH.go\"; fi\n\t\t;;\n\tesac\n\tif [ -n \"$mksysctl\" ]; then echo \"$mksysctl |gofmt >$zsysctl\"; fi\n\tif [ -n \"$mksysnum\" ]; then echo \"$mksysnum |gofmt >zsysnum_$GOOSARCH.go\"; fi\n\tif [ -n \"$mktypes\" ]; then echo \"$mktypes types_$GOOS.go |gofmt >ztypes_$GOOSARCH.go\"; fi\n) | $run\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/mkerrors.sh",
    "content": "#!/usr/bin/env bash\n# Copyright 2009 The Go 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\n# Generate Go code listing errors and other #defined constant\n# values (ENAMETOOLONG etc.), by asking the preprocessor\n# about the definitions.\n\nunset LANG\nexport LC_ALL=C\nexport LC_CTYPE=C\n\nCC=${CC:-gcc}\n\nuname=$(uname)\n\nincludes='\n#include <sys/types.h>\n#include <sys/file.h>\n#include <fcntl.h>\n#include <dirent.h>\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <netinet/ip.h>\n#include <netinet/ip6.h>\n#include <netinet/tcp.h>\n#include <errno.h>\n#include <sys/signal.h>\n#include <signal.h>\n#include <sys/resource.h>\n'\n\nccflags=\"$@\"\n\n# Write go tool cgo -godefs input.\n(\n\techo package plan9\n\techo\n\techo '/*'\n\tindirect=\"includes_$(uname)\"\n\techo \"${!indirect} $includes\"\n\techo '*/'\n\techo 'import \"C\"'\n\techo\n\techo 'const ('\n\n\t# The gcc command line prints all the #defines\n\t# it encounters while processing the input\n\techo \"${!indirect} $includes\" | $CC -x c - -E -dM $ccflags |\n\tawk '\n\t\t$1 != \"#define\" || $2 ~ /\\(/ || $3 == \"\" {next}\n\n\t\t$2 ~ /^E([ABCD]X|[BIS]P|[SD]I|S|FL)$/ {next}  # 386 registers\n\t\t$2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next}\n\t\t$2 ~ /^(SCM_SRCRT)$/ {next}\n\t\t$2 ~ /^(MAP_FAILED)$/ {next}\n\n\t\t$2 !~ /^ETH_/ &&\n\t\t$2 !~ /^EPROC_/ &&\n\t\t$2 !~ /^EQUIV_/ &&\n\t\t$2 !~ /^EXPR_/ &&\n\t\t$2 ~ /^E[A-Z0-9_]+$/ ||\n\t\t$2 ~ /^B[0-9_]+$/ ||\n\t\t$2 ~ /^V[A-Z0-9]+$/ ||\n\t\t$2 ~ /^CS[A-Z0-9]/ ||\n\t\t$2 ~ /^I(SIG|CANON|CRNL|EXTEN|MAXBEL|STRIP|UTF8)$/ ||\n\t\t$2 ~ /^IGN/ ||\n\t\t$2 ~ /^IX(ON|ANY|OFF)$/ ||\n\t\t$2 ~ /^IN(LCR|PCK)$/ ||\n\t\t$2 ~ /(^FLU?SH)|(FLU?SH$)/ ||\n\t\t$2 ~ /^C(LOCAL|READ)$/ ||\n\t\t$2 == \"BRKINT\" ||\n\t\t$2 == \"HUPCL\" ||\n\t\t$2 == \"PENDIN\" ||\n\t\t$2 == \"TOSTOP\" ||\n\t\t$2 ~ /^PAR/ ||\n\t\t$2 ~ /^SIG[^_]/ ||\n\t\t$2 ~ /^O[CNPFP][A-Z]+[^_][A-Z]+$/ ||\n\t\t$2 ~ /^IN_/ ||\n\t\t$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||\n\t\t$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||\n\t\t$2 == \"ICMPV6_FILTER\" ||\n\t\t$2 == \"SOMAXCONN\" ||\n\t\t$2 == \"NAME_MAX\" ||\n\t\t$2 == \"IFNAMSIZ\" ||\n\t\t$2 ~ /^CTL_(MAXNAME|NET|QUERY)$/ ||\n\t\t$2 ~ /^SYSCTL_VERS/ ||\n\t\t$2 ~ /^(MS|MNT)_/ ||\n\t\t$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||\n\t\t$2 ~ /^(O|F|FD|NAME|S|PTRACE|PT)_/ ||\n\t\t$2 ~ /^LINUX_REBOOT_CMD_/ ||\n\t\t$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||\n\t\t$2 !~ \"NLA_TYPE_MASK\" &&\n\t\t$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ ||\n\t\t$2 ~ /^SIOC/ ||\n\t\t$2 ~ /^TIOC/ ||\n\t\t$2 !~ \"RTF_BITS\" &&\n\t\t$2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ ||\n\t\t$2 ~ /^BIOC/ ||\n\t\t$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||\n\t\t$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|NOFILE|STACK)|RLIM_INFINITY/ ||\n\t\t$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||\n\t\t$2 ~ /^CLONE_[A-Z_]+/ ||\n\t\t$2 !~ /^(BPF_TIMEVAL)$/ &&\n\t\t$2 ~ /^(BPF|DLT)_/ ||\n\t\t$2 !~ \"WMESGLEN\" &&\n\t\t$2 ~ /^W[A-Z0-9]+$/ {printf(\"\\t%s = C.%s\\n\", $2, $2)}\n\t\t$2 ~ /^__WCOREFLAG$/ {next}\n\t\t$2 ~ /^__W[A-Z0-9]+$/ {printf(\"\\t%s = C.%s\\n\", substr($2,3), $2)}\n\n\t\t{next}\n\t' | sort\n\n\techo ')'\n) >_const.go\n\n# Pull out the error names for later.\nerrors=$(\n\techo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |\n\tawk '$1==\"#define\" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' |\n\tsort\n)\n\n# Pull out the signal names for later.\nsignals=$(\n\techo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |\n\tawk '$1==\"#define\" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |\n\tgrep -v 'SIGSTKSIZE\\|SIGSTKSZ\\|SIGRT' |\n\tsort\n)\n\n# Again, writing regexps to a file.\necho '#include <errno.h>' | $CC -x c - -E -dM $ccflags |\n\tawk '$1==\"#define\" && $2 ~ /^E[A-Z0-9_]+$/ { print \"^\\t\" $2 \"[ \\t]*=\" }' |\n\tsort >_error.grep\necho '#include <signal.h>' | $CC -x c - -E -dM $ccflags |\n\tawk '$1==\"#define\" && $2 ~ /^SIG[A-Z0-9]+$/ { print \"^\\t\" $2 \"[ \\t]*=\" }' |\n\tgrep -v 'SIGSTKSIZE\\|SIGSTKSZ\\|SIGRT' |\n\tsort >_signal.grep\n\necho '// mkerrors.sh' \"$@\"\necho '// Code generated by the command above; DO NOT EDIT.'\necho\ngo tool cgo -godefs -- \"$@\" _const.go >_error.out\ncat _error.out | grep -vf _error.grep | grep -vf _signal.grep\necho\necho '// Errors'\necho 'const ('\ncat _error.out | grep -f _error.grep | sed 's/=\\(.*\\)/= Errno(\\1)/'\necho ')'\n\necho\necho '// Signals'\necho 'const ('\ncat _error.out | grep -f _signal.grep | sed 's/=\\(.*\\)/= Signal(\\1)/'\necho ')'\n\n# Run C program to print error and syscall strings.\n(\n\techo -E \"\n#include <stdio.h>\n#include <stdlib.h>\n#include <errno.h>\n#include <ctype.h>\n#include <string.h>\n#include <signal.h>\n\n#define nelem(x) (sizeof(x)/sizeof((x)[0]))\n\nenum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below\n\nint errors[] = {\n\"\n\tfor i in $errors\n\tdo\n\t\techo -E '\t'$i,\n\tdone\n\n\techo -E \"\n};\n\nint signals[] = {\n\"\n\tfor i in $signals\n\tdo\n\t\techo -E '\t'$i,\n\tdone\n\n\t# Use -E because on some systems bash builtin interprets \\n itself.\n\techo -E '\n};\n\nstatic int\nintcmp(const void *a, const void *b)\n{\n\treturn *(int*)a - *(int*)b;\n}\n\nint\nmain(void)\n{\n\tint i, j, e;\n\tchar buf[1024], *p;\n\n\tprintf(\"\\n\\n// Error table\\n\");\n\tprintf(\"var errors = [...]string {\\n\");\n\tqsort(errors, nelem(errors), sizeof errors[0], intcmp);\n\tfor(i=0; i<nelem(errors); i++) {\n\t\te = errors[i];\n\t\tif(i > 0 && errors[i-1] == e)\n\t\t\tcontinue;\n\t\tstrcpy(buf, strerror(e));\n\t\t// lowercase first letter: Bad -> bad, but STREAM -> STREAM.\n\t\tif(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)\n\t\t\tbuf[0] += a - A;\n\t\tprintf(\"\\t%d: \\\"%s\\\",\\n\", e, buf);\n\t}\n\tprintf(\"}\\n\\n\");\n\t\n\tprintf(\"\\n\\n// Signal table\\n\");\n\tprintf(\"var signals = [...]string {\\n\");\n\tqsort(signals, nelem(signals), sizeof signals[0], intcmp);\n\tfor(i=0; i<nelem(signals); i++) {\n\t\te = signals[i];\n\t\tif(i > 0 && signals[i-1] == e)\n\t\t\tcontinue;\n\t\tstrcpy(buf, strsignal(e));\n\t\t// lowercase first letter: Bad -> bad, but STREAM -> STREAM.\n\t\tif(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)\n\t\t\tbuf[0] += a - A;\n\t\t// cut trailing : number.\n\t\tp = strrchr(buf, \":\"[0]);\n\t\tif(p)\n\t\t\t*p = '\\0';\n\t\tprintf(\"\\t%d: \\\"%s\\\",\\n\", e, buf);\n\t}\n\tprintf(\"}\\n\\n\");\n\n\treturn 0;\n}\n\n'\n) >_errors.c\n\n$CC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/mksysnum_plan9.sh",
    "content": "#!/bin/sh\n# Copyright 2009 The Go 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\nCOMMAND=\"mksysnum_plan9.sh $@\"\n\ncat <<EOF\n// $COMMAND\n// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT\n\npackage plan9\n\nconst(\nEOF\n\nSP='[ \t]' # space or tab\nsed \"s/^#define${SP}\\\\([A-Z0-9_][A-Z0-9_]*\\\\)${SP}${SP}*\\\\([0-9][0-9]*\\\\)/SYS_\\\\1=\\\\2/g\" \\\n\t< $1 | grep -v SYS__\n\ncat <<EOF\n)\nEOF\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/pwd_plan9.go",
    "content": "// Copyright 2015 The Go 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 plan9\n\nimport \"syscall\"\n\nfunc fixwd() {\n\tsyscall.Fixwd()\n}\n\nfunc Getwd() (wd string, err error) {\n\treturn syscall.Getwd()\n}\n\nfunc Chdir(path string) error {\n\treturn syscall.Chdir(path)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/race.go",
    "content": "// Copyright 2012 The Go 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\n//go:build plan9 && race\n\npackage plan9\n\nimport (\n\t\"runtime\"\n\t\"unsafe\"\n)\n\nconst raceenabled = true\n\nfunc raceAcquire(addr unsafe.Pointer) {\n\truntime.RaceAcquire(addr)\n}\n\nfunc raceReleaseMerge(addr unsafe.Pointer) {\n\truntime.RaceReleaseMerge(addr)\n}\n\nfunc raceReadRange(addr unsafe.Pointer, len int) {\n\truntime.RaceReadRange(addr, len)\n}\n\nfunc raceWriteRange(addr unsafe.Pointer, len int) {\n\truntime.RaceWriteRange(addr, len)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/race0.go",
    "content": "// Copyright 2012 The Go 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\n//go:build plan9 && !race\n\npackage plan9\n\nimport (\n\t\"unsafe\"\n)\n\nconst raceenabled = false\n\nfunc raceAcquire(addr unsafe.Pointer) {\n}\n\nfunc raceReleaseMerge(addr unsafe.Pointer) {\n}\n\nfunc raceReadRange(addr unsafe.Pointer, len int) {\n}\n\nfunc raceWriteRange(addr unsafe.Pointer, len int) {\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/str.go",
    "content": "// Copyright 2009 The Go 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\n//go:build plan9\n\npackage plan9\n\nfunc itoa(val int) string { // do it here rather than with fmt to avoid dependency\n\tif val < 0 {\n\t\treturn \"-\" + itoa(-val)\n\t}\n\tvar buf [32]byte // big enough for int64\n\ti := len(buf) - 1\n\tfor val >= 10 {\n\t\tbuf[i] = byte(val%10 + '0')\n\t\ti--\n\t\tval /= 10\n\t}\n\tbuf[i] = byte(val + '0')\n\treturn string(buf[i:])\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/syscall.go",
    "content": "// Copyright 2009 The Go 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\n//go:build plan9\n\n// Package plan9 contains an interface to the low-level operating system\n// primitives. OS details vary depending on the underlying system, and\n// by default, godoc will display the OS-specific documentation for the current\n// system. If you want godoc to display documentation for another\n// system, set $GOOS and $GOARCH to the desired system. For example, if\n// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS\n// to freebsd and $GOARCH to arm.\n//\n// The primary use of this package is inside other packages that provide a more\n// portable interface to the system, such as \"os\", \"time\" and \"net\".  Use\n// those packages rather than this one if you can.\n//\n// For details of the functions and data types in this package consult\n// the manuals for the appropriate operating system.\n//\n// These calls return err == nil to indicate success; otherwise\n// err represents an operating system error describing the failure and\n// holds a value of type syscall.ErrorString.\npackage plan9 // import \"golang.org/x/sys/plan9\"\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n\t\"unsafe\"\n)\n\n// ByteSliceFromString returns a NUL-terminated slice of bytes\n// containing the text of s. If s contains a NUL byte at any\n// location, it returns (nil, EINVAL).\nfunc ByteSliceFromString(s string) ([]byte, error) {\n\tif strings.IndexByte(s, 0) != -1 {\n\t\treturn nil, EINVAL\n\t}\n\ta := make([]byte, len(s)+1)\n\tcopy(a, s)\n\treturn a, nil\n}\n\n// BytePtrFromString returns a pointer to a NUL-terminated array of\n// bytes containing the text of s. If s contains a NUL byte at any\n// location, it returns (nil, EINVAL).\nfunc BytePtrFromString(s string) (*byte, error) {\n\ta, err := ByteSliceFromString(s)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &a[0], nil\n}\n\n// ByteSliceToString returns a string form of the text represented by the slice s, with a terminating NUL and any\n// bytes after the NUL removed.\nfunc ByteSliceToString(s []byte) string {\n\tif i := bytes.IndexByte(s, 0); i != -1 {\n\t\ts = s[:i]\n\t}\n\treturn string(s)\n}\n\n// BytePtrToString takes a pointer to a sequence of text and returns the corresponding string.\n// If the pointer is nil, it returns the empty string. It assumes that the text sequence is terminated\n// at a zero byte; if the zero byte is not present, the program may crash.\nfunc BytePtrToString(p *byte) string {\n\tif p == nil {\n\t\treturn \"\"\n\t}\n\tif *p == 0 {\n\t\treturn \"\"\n\t}\n\n\t// Find NUL terminator.\n\tn := 0\n\tfor ptr := unsafe.Pointer(p); *(*byte)(ptr) != 0; n++ {\n\t\tptr = unsafe.Pointer(uintptr(ptr) + 1)\n\t}\n\n\treturn string(unsafe.Slice(p, n))\n}\n\n// Single-word zero for use when we need a valid pointer to 0 bytes.\n// See mksyscall.pl.\nvar _zero uintptr\n\nfunc (ts *Timespec) Unix() (sec int64, nsec int64) {\n\treturn int64(ts.Sec), int64(ts.Nsec)\n}\n\nfunc (tv *Timeval) Unix() (sec int64, nsec int64) {\n\treturn int64(tv.Sec), int64(tv.Usec) * 1000\n}\n\nfunc (ts *Timespec) Nano() int64 {\n\treturn int64(ts.Sec)*1e9 + int64(ts.Nsec)\n}\n\nfunc (tv *Timeval) Nano() int64 {\n\treturn int64(tv.Sec)*1e9 + int64(tv.Usec)*1000\n}\n\n// use is a no-op, but the compiler cannot see that it is.\n// Calling use(p) ensures that p is kept live until that point.\n//\n//go:noescape\nfunc use(p unsafe.Pointer)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/syscall_plan9.go",
    "content": "// Copyright 2011 The Go 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\n// Plan 9 system calls.\n// This file is compiled as ordinary Go code,\n// but it is also input to mksyscall,\n// which parses the //sys lines and generates system call stubs.\n// Note that sometimes we use a lowercase //sys name and\n// wrap it in our own nicer implementation.\n\npackage plan9\n\nimport (\n\t\"bytes\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n// A Note is a string describing a process note.\n// It implements the os.Signal interface.\ntype Note string\n\nfunc (n Note) Signal() {}\n\nfunc (n Note) String() string {\n\treturn string(n)\n}\n\nvar (\n\tStdin  = 0\n\tStdout = 1\n\tStderr = 2\n)\n\n// For testing: clients can set this flag to force\n// creation of IPv6 sockets to return EAFNOSUPPORT.\nvar SocketDisableIPv6 bool\n\nfunc Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.ErrorString)\nfunc Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.ErrorString)\nfunc RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)\nfunc RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)\n\nfunc atoi(b []byte) (n uint) {\n\tn = 0\n\tfor i := 0; i < len(b); i++ {\n\t\tn = n*10 + uint(b[i]-'0')\n\t}\n\treturn\n}\n\nfunc cstring(s []byte) string {\n\ti := bytes.IndexByte(s, 0)\n\tif i == -1 {\n\t\ti = len(s)\n\t}\n\treturn string(s[:i])\n}\n\nfunc errstr() string {\n\tvar buf [ERRMAX]byte\n\n\tRawSyscall(SYS_ERRSTR, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0)\n\n\tbuf[len(buf)-1] = 0\n\treturn cstring(buf[:])\n}\n\n// Implemented in assembly to import from runtime.\nfunc exit(code int)\n\nfunc Exit(code int) { exit(code) }\n\nfunc readnum(path string) (uint, error) {\n\tvar b [12]byte\n\n\tfd, e := Open(path, O_RDONLY)\n\tif e != nil {\n\t\treturn 0, e\n\t}\n\tdefer Close(fd)\n\n\tn, e := Pread(fd, b[:], 0)\n\n\tif e != nil {\n\t\treturn 0, e\n\t}\n\n\tm := 0\n\tfor ; m < n && b[m] == ' '; m++ {\n\t}\n\n\treturn atoi(b[m : n-1]), nil\n}\n\nfunc Getpid() (pid int) {\n\tn, _ := readnum(\"#c/pid\")\n\treturn int(n)\n}\n\nfunc Getppid() (ppid int) {\n\tn, _ := readnum(\"#c/ppid\")\n\treturn int(n)\n}\n\nfunc Read(fd int, p []byte) (n int, err error) {\n\treturn Pread(fd, p, -1)\n}\n\nfunc Write(fd int, p []byte) (n int, err error) {\n\treturn Pwrite(fd, p, -1)\n}\n\nvar ioSync int64\n\n//sys\tfd2path(fd int, buf []byte) (err error)\n\nfunc Fd2path(fd int) (path string, err error) {\n\tvar buf [512]byte\n\n\te := fd2path(fd, buf[:])\n\tif e != nil {\n\t\treturn \"\", e\n\t}\n\treturn cstring(buf[:]), nil\n}\n\n//sys\tpipe(p *[2]int32) (err error)\n\nfunc Pipe(p []int) (err error) {\n\tif len(p) != 2 {\n\t\treturn syscall.ErrorString(\"bad arg in system call\")\n\t}\n\tvar pp [2]int32\n\terr = pipe(&pp)\n\tif err == nil {\n\t\tp[0] = int(pp[0])\n\t\tp[1] = int(pp[1])\n\t}\n\treturn\n}\n\n// Underlying system call writes to newoffset via pointer.\n// Implemented in assembly to avoid allocation.\nfunc seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)\n\nfunc Seek(fd int, offset int64, whence int) (newoffset int64, err error) {\n\tnewoffset, e := seek(0, fd, offset, whence)\n\n\tif newoffset == -1 {\n\t\terr = syscall.ErrorString(e)\n\t}\n\treturn\n}\n\nfunc Mkdir(path string, mode uint32) (err error) {\n\tfd, err := Create(path, O_RDONLY, DMDIR|mode)\n\n\tif fd != -1 {\n\t\tClose(fd)\n\t}\n\n\treturn\n}\n\ntype Waitmsg struct {\n\tPid  int\n\tTime [3]uint32\n\tMsg  string\n}\n\nfunc (w Waitmsg) Exited() bool   { return true }\nfunc (w Waitmsg) Signaled() bool { return false }\n\nfunc (w Waitmsg) ExitStatus() int {\n\tif len(w.Msg) == 0 {\n\t\t// a normal exit returns no message\n\t\treturn 0\n\t}\n\treturn 1\n}\n\n//sys\tawait(s []byte) (n int, err error)\n\nfunc Await(w *Waitmsg) (err error) {\n\tvar buf [512]byte\n\tvar f [5][]byte\n\n\tn, err := await(buf[:])\n\n\tif err != nil || w == nil {\n\t\treturn\n\t}\n\n\tnf := 0\n\tp := 0\n\tfor i := 0; i < n && nf < len(f)-1; i++ {\n\t\tif buf[i] == ' ' {\n\t\t\tf[nf] = buf[p:i]\n\t\t\tp = i + 1\n\t\t\tnf++\n\t\t}\n\t}\n\tf[nf] = buf[p:]\n\tnf++\n\n\tif nf != len(f) {\n\t\treturn syscall.ErrorString(\"invalid wait message\")\n\t}\n\tw.Pid = int(atoi(f[0]))\n\tw.Time[0] = uint32(atoi(f[1]))\n\tw.Time[1] = uint32(atoi(f[2]))\n\tw.Time[2] = uint32(atoi(f[3]))\n\tw.Msg = cstring(f[4])\n\tif w.Msg == \"''\" {\n\t\t// await() returns '' for no error\n\t\tw.Msg = \"\"\n\t}\n\treturn\n}\n\nfunc Unmount(name, old string) (err error) {\n\tfixwd()\n\toldp, err := BytePtrFromString(old)\n\tif err != nil {\n\t\treturn err\n\t}\n\toldptr := uintptr(unsafe.Pointer(oldp))\n\n\tvar r0 uintptr\n\tvar e syscall.ErrorString\n\n\t// bind(2) man page: If name is zero, everything bound or mounted upon old is unbound or unmounted.\n\tif name == \"\" {\n\t\tr0, _, e = Syscall(SYS_UNMOUNT, _zero, oldptr, 0)\n\t} else {\n\t\tnamep, err := BytePtrFromString(name)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tr0, _, e = Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(namep)), oldptr, 0)\n\t}\n\n\tif int32(r0) == -1 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc Fchdir(fd int) (err error) {\n\tpath, err := Fd2path(fd)\n\n\tif err != nil {\n\t\treturn\n\t}\n\n\treturn Chdir(path)\n}\n\ntype Timespec struct {\n\tSec  int32\n\tNsec int32\n}\n\ntype Timeval struct {\n\tSec  int32\n\tUsec int32\n}\n\nfunc NsecToTimeval(nsec int64) (tv Timeval) {\n\tnsec += 999 // round up to microsecond\n\ttv.Usec = int32(nsec % 1e9 / 1e3)\n\ttv.Sec = int32(nsec / 1e9)\n\treturn\n}\n\nfunc nsec() int64 {\n\tvar scratch int64\n\n\tr0, _, _ := Syscall(SYS_NSEC, uintptr(unsafe.Pointer(&scratch)), 0, 0)\n\t// TODO(aram): remove hack after I fix _nsec in the pc64 kernel.\n\tif r0 == 0 {\n\t\treturn scratch\n\t}\n\treturn int64(r0)\n}\n\nfunc Gettimeofday(tv *Timeval) error {\n\tnsec := nsec()\n\t*tv = NsecToTimeval(nsec)\n\treturn nil\n}\n\nfunc Getpagesize() int { return 0x1000 }\n\nfunc Getegid() (egid int) { return -1 }\nfunc Geteuid() (euid int) { return -1 }\nfunc Getgid() (gid int)   { return -1 }\nfunc Getuid() (uid int)   { return -1 }\n\nfunc Getgroups() (gids []int, err error) {\n\treturn make([]int, 0), nil\n}\n\n//sys\topen(path string, mode int) (fd int, err error)\n\nfunc Open(path string, mode int) (fd int, err error) {\n\tfixwd()\n\treturn open(path, mode)\n}\n\n//sys\tcreate(path string, mode int, perm uint32) (fd int, err error)\n\nfunc Create(path string, mode int, perm uint32) (fd int, err error) {\n\tfixwd()\n\treturn create(path, mode, perm)\n}\n\n//sys\tremove(path string) (err error)\n\nfunc Remove(path string) error {\n\tfixwd()\n\treturn remove(path)\n}\n\n//sys\tstat(path string, edir []byte) (n int, err error)\n\nfunc Stat(path string, edir []byte) (n int, err error) {\n\tfixwd()\n\treturn stat(path, edir)\n}\n\n//sys\tbind(name string, old string, flag int) (err error)\n\nfunc Bind(name string, old string, flag int) (err error) {\n\tfixwd()\n\treturn bind(name, old, flag)\n}\n\n//sys\tmount(fd int, afd int, old string, flag int, aname string) (err error)\n\nfunc Mount(fd int, afd int, old string, flag int, aname string) (err error) {\n\tfixwd()\n\treturn mount(fd, afd, old, flag, aname)\n}\n\n//sys\twstat(path string, edir []byte) (err error)\n\nfunc Wstat(path string, edir []byte) (err error) {\n\tfixwd()\n\treturn wstat(path, edir)\n}\n\n//sys\tchdir(path string) (err error)\n//sys\tDup(oldfd int, newfd int) (fd int, err error)\n//sys\tPread(fd int, p []byte, offset int64) (n int, err error)\n//sys\tPwrite(fd int, p []byte, offset int64) (n int, err error)\n//sys\tClose(fd int) (err error)\n//sys\tFstat(fd int, edir []byte) (n int, err error)\n//sys\tFwstat(fd int, edir []byte) (err error)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/zsyscall_plan9_386.go",
    "content": "// go run mksyscall.go -l32 -plan9 -tags plan9,386 syscall_plan9.go\n// Code generated by the command above; see README.md. DO NOT EDIT.\n\n//go:build plan9 && 386\n\npackage plan9\n\nimport \"unsafe\"\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc fd2path(fd int, buf []byte) (err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(buf) > 0 {\n\t\t_p0 = unsafe.Pointer(&buf[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc pipe(p *[2]int32) (err error) {\n\tr0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc await(s []byte) (n int, err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(s) > 0 {\n\t\t_p0 = unsafe.Pointer(&s[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)\n\tn = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc open(path string, mode int) (fd int, err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)\n\tfd = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc create(path string, mode int, perm uint32) (fd int, err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))\n\tfd = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc remove(path string) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc stat(path string, edir []byte) (n int, err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 unsafe.Pointer\n\tif len(edir) > 0 {\n\t\t_p1 = unsafe.Pointer(&edir[0])\n\t} else {\n\t\t_p1 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))\n\tn = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc bind(name string, old string, flag int) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(name)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 *byte\n\t_p1, err = BytePtrFromString(old)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc mount(fd int, afd int, old string, flag int, aname string) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(old)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 *byte\n\t_p1, err = BytePtrFromString(aname)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc wstat(path string, edir []byte) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 unsafe.Pointer\n\tif len(edir) > 0 {\n\t\t_p1 = unsafe.Pointer(&edir[0])\n\t} else {\n\t\t_p1 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc chdir(path string) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Dup(oldfd int, newfd int) (fd int, err error) {\n\tr0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)\n\tfd = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Pread(fd int, p []byte, offset int64) (n int, err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(p) > 0 {\n\t\t_p0 = unsafe.Pointer(&p[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)\n\tn = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Pwrite(fd int, p []byte, offset int64) (n int, err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(p) > 0 {\n\t\t_p0 = unsafe.Pointer(&p[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)\n\tn = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Close(fd int) (err error) {\n\tr0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Fstat(fd int, edir []byte) (n int, err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(edir) > 0 {\n\t\t_p0 = unsafe.Pointer(&edir[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))\n\tn = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Fwstat(fd int, edir []byte) (err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(edir) > 0 {\n\t\t_p0 = unsafe.Pointer(&edir[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/zsyscall_plan9_amd64.go",
    "content": "// go run mksyscall.go -l32 -plan9 -tags plan9,amd64 syscall_plan9.go\n// Code generated by the command above; see README.md. DO NOT EDIT.\n\n//go:build plan9 && amd64\n\npackage plan9\n\nimport \"unsafe\"\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc fd2path(fd int, buf []byte) (err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(buf) > 0 {\n\t\t_p0 = unsafe.Pointer(&buf[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc pipe(p *[2]int32) (err error) {\n\tr0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc await(s []byte) (n int, err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(s) > 0 {\n\t\t_p0 = unsafe.Pointer(&s[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)\n\tn = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc open(path string, mode int) (fd int, err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)\n\tfd = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc create(path string, mode int, perm uint32) (fd int, err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))\n\tfd = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc remove(path string) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc stat(path string, edir []byte) (n int, err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 unsafe.Pointer\n\tif len(edir) > 0 {\n\t\t_p1 = unsafe.Pointer(&edir[0])\n\t} else {\n\t\t_p1 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))\n\tn = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc bind(name string, old string, flag int) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(name)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 *byte\n\t_p1, err = BytePtrFromString(old)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc mount(fd int, afd int, old string, flag int, aname string) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(old)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 *byte\n\t_p1, err = BytePtrFromString(aname)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc wstat(path string, edir []byte) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 unsafe.Pointer\n\tif len(edir) > 0 {\n\t\t_p1 = unsafe.Pointer(&edir[0])\n\t} else {\n\t\t_p1 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc chdir(path string) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Dup(oldfd int, newfd int) (fd int, err error) {\n\tr0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)\n\tfd = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Pread(fd int, p []byte, offset int64) (n int, err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(p) > 0 {\n\t\t_p0 = unsafe.Pointer(&p[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)\n\tn = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Pwrite(fd int, p []byte, offset int64) (n int, err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(p) > 0 {\n\t\t_p0 = unsafe.Pointer(&p[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)\n\tn = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Close(fd int) (err error) {\n\tr0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Fstat(fd int, edir []byte) (n int, err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(edir) > 0 {\n\t\t_p0 = unsafe.Pointer(&edir[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))\n\tn = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Fwstat(fd int, edir []byte) (err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(edir) > 0 {\n\t\t_p0 = unsafe.Pointer(&edir[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/zsyscall_plan9_arm.go",
    "content": "// go run mksyscall.go -l32 -plan9 -tags plan9,arm syscall_plan9.go\n// Code generated by the command above; see README.md. DO NOT EDIT.\n\n//go:build plan9 && arm\n\npackage plan9\n\nimport \"unsafe\"\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc fd2path(fd int, buf []byte) (err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(buf) > 0 {\n\t\t_p0 = unsafe.Pointer(&buf[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc pipe(p *[2]int32) (err error) {\n\tr0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc await(s []byte) (n int, err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(s) > 0 {\n\t\t_p0 = unsafe.Pointer(&s[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)\n\tn = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc open(path string, mode int) (fd int, err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)\n\tfd = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc create(path string, mode int, perm uint32) (fd int, err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))\n\tfd = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc remove(path string) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc stat(path string, edir []byte) (n int, err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 unsafe.Pointer\n\tif len(edir) > 0 {\n\t\t_p1 = unsafe.Pointer(&edir[0])\n\t} else {\n\t\t_p1 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))\n\tn = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc bind(name string, old string, flag int) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(name)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 *byte\n\t_p1, err = BytePtrFromString(old)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc mount(fd int, afd int, old string, flag int, aname string) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(old)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 *byte\n\t_p1, err = BytePtrFromString(aname)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc wstat(path string, edir []byte) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 unsafe.Pointer\n\tif len(edir) > 0 {\n\t\t_p1 = unsafe.Pointer(&edir[0])\n\t} else {\n\t\t_p1 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc chdir(path string) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Dup(oldfd int, newfd int) (fd int, err error) {\n\tr0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)\n\tfd = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Pread(fd int, p []byte, offset int64) (n int, err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(p) > 0 {\n\t\t_p0 = unsafe.Pointer(&p[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)\n\tn = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Pwrite(fd int, p []byte, offset int64) (n int, err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(p) > 0 {\n\t\t_p0 = unsafe.Pointer(&p[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)\n\tn = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Close(fd int) (err error) {\n\tr0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Fstat(fd int, edir []byte) (n int, err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(edir) > 0 {\n\t\t_p0 = unsafe.Pointer(&edir[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))\n\tn = int(r0)\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\nfunc Fwstat(fd int, edir []byte) (err error) {\n\tvar _p0 unsafe.Pointer\n\tif len(edir) > 0 {\n\t\t_p0 = unsafe.Pointer(&edir[0])\n\t} else {\n\t\t_p0 = unsafe.Pointer(&_zero)\n\t}\n\tr0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))\n\tif int32(r0) == -1 {\n\t\terr = e1\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/plan9/zsysnum_plan9.go",
    "content": "// mksysnum_plan9.sh /opt/plan9/sys/src/libc/9syscall/sys.h\n// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT\n\npackage plan9\n\nconst (\n\tSYS_SYSR1       = 0\n\tSYS_BIND        = 2\n\tSYS_CHDIR       = 3\n\tSYS_CLOSE       = 4\n\tSYS_DUP         = 5\n\tSYS_ALARM       = 6\n\tSYS_EXEC        = 7\n\tSYS_EXITS       = 8\n\tSYS_FAUTH       = 10\n\tSYS_SEGBRK      = 12\n\tSYS_OPEN        = 14\n\tSYS_OSEEK       = 16\n\tSYS_SLEEP       = 17\n\tSYS_RFORK       = 19\n\tSYS_PIPE        = 21\n\tSYS_CREATE      = 22\n\tSYS_FD2PATH     = 23\n\tSYS_BRK_        = 24\n\tSYS_REMOVE      = 25\n\tSYS_NOTIFY      = 28\n\tSYS_NOTED       = 29\n\tSYS_SEGATTACH   = 30\n\tSYS_SEGDETACH   = 31\n\tSYS_SEGFREE     = 32\n\tSYS_SEGFLUSH    = 33\n\tSYS_RENDEZVOUS  = 34\n\tSYS_UNMOUNT     = 35\n\tSYS_SEMACQUIRE  = 37\n\tSYS_SEMRELEASE  = 38\n\tSYS_SEEK        = 39\n\tSYS_FVERSION    = 40\n\tSYS_ERRSTR      = 41\n\tSYS_STAT        = 42\n\tSYS_FSTAT       = 43\n\tSYS_WSTAT       = 44\n\tSYS_FWSTAT      = 45\n\tSYS_MOUNT       = 46\n\tSYS_AWAIT       = 47\n\tSYS_PREAD       = 50\n\tSYS_PWRITE      = 51\n\tSYS_TSEMACQUIRE = 52\n\tSYS_NSEC        = 53\n)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/.gitignore",
    "content": "_obj/\nunix.test\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/README.md",
    "content": "# Building `sys/unix`\n\nThe sys/unix package provides access to the raw system call interface of the\nunderlying operating system. See: https://godoc.org/golang.org/x/sys/unix\n\nPorting Go to a new architecture/OS combination or adding syscalls, types, or\nconstants to an existing architecture/OS pair requires some manual effort;\nhowever, there are tools that automate much of the process.\n\n## Build Systems\n\nThere are currently two ways we generate the necessary files. We are currently\nmigrating the build system to use containers so the builds are reproducible.\nThis is being done on an OS-by-OS basis. Please update this documentation as\ncomponents of the build system change.\n\n### Old Build System (currently for `GOOS != \"linux\"`)\n\nThe old build system generates the Go files based on the C header files\npresent on your system. This means that files\nfor a given GOOS/GOARCH pair must be generated on a system with that OS and\narchitecture. This also means that the generated code can differ from system\nto system, based on differences in the header files.\n\nTo avoid this, if you are using the old build system, only generate the Go\nfiles on an installation with unmodified header files. It is also important to\nkeep track of which version of the OS the files were generated from (ex.\nDarwin 14 vs Darwin 15). This makes it easier to track the progress of changes\nand have each OS upgrade correspond to a single change.\n\nTo build the files for your current OS and architecture, make sure GOOS and\nGOARCH are set correctly and run `mkall.sh`. This will generate the files for\nyour specific system. Running `mkall.sh -n` shows the commands that will be run.\n\nRequirements: bash, go\n\n### New Build System (currently for `GOOS == \"linux\"`)\n\nThe new build system uses a Docker container to generate the go files directly\nfrom source checkouts of the kernel and various system libraries. This means\nthat on any platform that supports Docker, all the files using the new build\nsystem can be generated at once, and generated files will not change based on\nwhat the person running the scripts has installed on their computer.\n\nThe OS specific files for the new build system are located in the `${GOOS}`\ndirectory, and the build is coordinated by the `${GOOS}/mkall.go` program. When\nthe kernel or system library updates, modify the Dockerfile at\n`${GOOS}/Dockerfile` to checkout the new release of the source.\n\nTo build all the files under the new build system, you must be on an amd64/Linux\nsystem and have your GOOS and GOARCH set accordingly. Running `mkall.sh` will\nthen generate all of the files for all of the GOOS/GOARCH pairs in the new build\nsystem. Running `mkall.sh -n` shows the commands that will be run.\n\nRequirements: bash, go, docker\n\n## Component files\n\nThis section describes the various files used in the code generation process.\nIt also contains instructions on how to modify these files to add a new\narchitecture/OS or to add additional syscalls, types, or constants. Note that\nif you are using the new build system, the scripts/programs cannot be called normally.\nThey must be called from within the docker container.\n\n### asm files\n\nThe hand-written assembly file at `asm_${GOOS}_${GOARCH}.s` implements system\ncall dispatch. There are three entry points:\n```\n  func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)\n  func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)\n  func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)\n```\nThe first and second are the standard ones; they differ only in how many\narguments can be passed to the kernel. The third is for low-level use by the\nForkExec wrapper. Unlike the first two, it does not call into the scheduler to\nlet it know that a system call is running.\n\nWhen porting Go to a new architecture/OS, this file must be implemented for\neach GOOS/GOARCH pair.\n\n### mksysnum\n\nMksysnum is a Go program located at `${GOOS}/mksysnum.go` (or `mksysnum_${GOOS}.go`\nfor the old system). This program takes in a list of header files containing the\nsyscall number declarations and parses them to produce the corresponding list of\nGo numeric constants. See `zsysnum_${GOOS}_${GOARCH}.go` for the generated\nconstants.\n\nAdding new syscall numbers is mostly done by running the build on a sufficiently\nnew installation of the target OS (or updating the source checkouts for the\nnew build system). However, depending on the OS, you may need to update the\nparsing in mksysnum.\n\n### mksyscall.go\n\nThe `syscall.go`, `syscall_${GOOS}.go`, `syscall_${GOOS}_${GOARCH}.go` are\nhand-written Go files which implement system calls (for unix, the specific OS,\nor the specific OS/Architecture pair respectively) that need special handling\nand list `//sys` comments giving prototypes for ones that can be generated.\n\nThe mksyscall.go program takes the `//sys` and `//sysnb` comments and converts\nthem into syscalls. This requires the name of the prototype in the comment to\nmatch a syscall number in the `zsysnum_${GOOS}_${GOARCH}.go` file. The function\nprototype can be exported (capitalized) or not.\n\nAdding a new syscall often just requires adding a new `//sys` function prototype\nwith the desired arguments and a capitalized name so it is exported. However, if\nyou want the interface to the syscall to be different, often one will make an\nunexported `//sys` prototype, and then write a custom wrapper in\n`syscall_${GOOS}.go`.\n\n### types files\n\nFor each OS, there is a hand-written Go file at `${GOOS}/types.go` (or\n`types_${GOOS}.go` on the old system). This file includes standard C headers and\ncreates Go type aliases to the corresponding C types. The file is then fed\nthrough godef to get the Go compatible definitions. Finally, the generated code\nis fed though mkpost.go to format the code correctly and remove any hidden or\nprivate identifiers. This cleaned-up code is written to\n`ztypes_${GOOS}_${GOARCH}.go`.\n\nThe hardest part about preparing this file is figuring out which headers to\ninclude and which symbols need to be `#define`d to get the actual data\nstructures that pass through to the kernel system calls. Some C libraries\npreset alternate versions for binary compatibility and translate them on the\nway in and out of system calls, but there is almost always a `#define` that can\nget the real ones.\nSee `types_darwin.go` and `linux/types.go` for examples.\n\nTo add a new type, add in the necessary include statement at the top of the\nfile (if it is not already there) and add in a type alias line. Note that if\nyour type is significantly different on different architectures, you may need\nsome `#if/#elif` macros in your include statements.\n\n### mkerrors.sh\n\nThis script is used to generate the system's various constants. This doesn't\njust include the error numbers and error strings, but also the signal numbers\nand a wide variety of miscellaneous constants. The constants come from the list\nof include files in the `includes_${uname}` variable. A regex then picks out\nthe desired `#define` statements, and generates the corresponding Go constants.\nThe error numbers and strings are generated from `#include <errno.h>`, and the\nsignal numbers and strings are generated from `#include <signal.h>`. All of\nthese constants are written to `zerrors_${GOOS}_${GOARCH}.go` via a C program,\n`_errors.c`, which prints out all the constants.\n\nTo add a constant, add the header that includes it to the appropriate variable.\nThen, edit the regex (if necessary) to match the desired constant. Avoid making\nthe regex too broad to avoid matching unintended constants.\n\n### internal/mkmerge\n\nThis program is used to extract duplicate const, func, and type declarations\nfrom the generated architecture-specific files listed below, and merge these\ninto a common file for each OS.\n\nThe merge is performed in the following steps:\n1. Construct the set of common code that is identical in all architecture-specific files.\n2. Write this common code to the merged file.\n3. Remove the common code from all architecture-specific files.\n\n\n## Generated files\n\n### `zerrors_${GOOS}_${GOARCH}.go`\n\nA file containing all of the system's generated error numbers, error strings,\nsignal numbers, and constants. Generated by `mkerrors.sh` (see above).\n\n### `zsyscall_${GOOS}_${GOARCH}.go`\n\nA file containing all the generated syscalls for a specific GOOS and GOARCH.\nGenerated by `mksyscall.go` (see above).\n\n### `zsysnum_${GOOS}_${GOARCH}.go`\n\nA list of numeric constants for all the syscall number of the specific GOOS\nand GOARCH. Generated by mksysnum (see above).\n\n### `ztypes_${GOOS}_${GOARCH}.go`\n\nA file containing Go types for passing into (or returning from) syscalls.\nGenerated by godefs and the types file (see above).\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/affinity_linux.go",
    "content": "// Copyright 2018 The Go 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\n// CPU affinity functions\n\npackage unix\n\nimport (\n\t\"math/bits\"\n\t\"unsafe\"\n)\n\nconst cpuSetSize = _CPU_SETSIZE / _NCPUBITS\n\n// CPUSet represents a CPU affinity mask.\ntype CPUSet [cpuSetSize]cpuMask\n\nfunc schedAffinity(trap uintptr, pid int, set *CPUSet) error {\n\t_, _, e := RawSyscall(trap, uintptr(pid), uintptr(unsafe.Sizeof(*set)), uintptr(unsafe.Pointer(set)))\n\tif e != 0 {\n\t\treturn errnoErr(e)\n\t}\n\treturn nil\n}\n\n// SchedGetaffinity gets the CPU affinity mask of the thread specified by pid.\n// If pid is 0 the calling thread is used.\nfunc SchedGetaffinity(pid int, set *CPUSet) error {\n\treturn schedAffinity(SYS_SCHED_GETAFFINITY, pid, set)\n}\n\n// SchedSetaffinity sets the CPU affinity mask of the thread specified by pid.\n// If pid is 0 the calling thread is used.\nfunc SchedSetaffinity(pid int, set *CPUSet) error {\n\treturn schedAffinity(SYS_SCHED_SETAFFINITY, pid, set)\n}\n\n// Zero clears the set s, so that it contains no CPUs.\nfunc (s *CPUSet) Zero() {\n\tclear(s[:])\n}\n\n// Fill adds all possible CPU bits to the set s. On Linux, [SchedSetaffinity]\n// will silently ignore any invalid CPU bits in [CPUSet] so this is an\n// efficient way of resetting the CPU affinity of a process.\nfunc (s *CPUSet) Fill() {\n\tfor i := range s {\n\t\ts[i] = ^cpuMask(0)\n\t}\n}\n\nfunc cpuBitsIndex(cpu int) int {\n\treturn cpu / _NCPUBITS\n}\n\nfunc cpuBitsMask(cpu int) cpuMask {\n\treturn cpuMask(1 << (uint(cpu) % _NCPUBITS))\n}\n\n// Set adds cpu to the set s.\nfunc (s *CPUSet) Set(cpu int) {\n\ti := cpuBitsIndex(cpu)\n\tif i < len(s) {\n\t\ts[i] |= cpuBitsMask(cpu)\n\t}\n}\n\n// Clear removes cpu from the set s.\nfunc (s *CPUSet) Clear(cpu int) {\n\ti := cpuBitsIndex(cpu)\n\tif i < len(s) {\n\t\ts[i] &^= cpuBitsMask(cpu)\n\t}\n}\n\n// IsSet reports whether cpu is in the set s.\nfunc (s *CPUSet) IsSet(cpu int) bool {\n\ti := cpuBitsIndex(cpu)\n\tif i < len(s) {\n\t\treturn s[i]&cpuBitsMask(cpu) != 0\n\t}\n\treturn false\n}\n\n// Count returns the number of CPUs in the set s.\nfunc (s *CPUSet) Count() int {\n\tc := 0\n\tfor _, b := range s {\n\t\tc += bits.OnesCount64(uint64(b))\n\t}\n\treturn c\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/aliases.go",
    "content": "// Copyright 2018 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\npackage unix\n\nimport \"syscall\"\n\ntype Signal = syscall.Signal\ntype Errno = syscall.Errno\ntype SysProcAttr = syscall.SysProcAttr\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_aix_ppc64.s",
    "content": "// Copyright 2018 The Go 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\n//go:build gc\n\n#include \"textflag.h\"\n\n//\n// System calls for ppc64, AIX are implemented in runtime/syscall_aix.go\n//\n\nTEXT ·syscall6(SB),NOSPLIT,$0-88\n\tJMP\tsyscall·syscall6(SB)\n\nTEXT ·rawSyscall6(SB),NOSPLIT,$0-88\n\tJMP\tsyscall·rawSyscall6(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_bsd_386.s",
    "content": "// Copyright 2021 The Go 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\n//go:build (freebsd || netbsd || openbsd) && gc\n\n#include \"textflag.h\"\n\n// System call support for 386 BSD\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT\t·Syscall(SB),NOSPLIT,$0-28\n\tJMP\tsyscall·Syscall(SB)\n\nTEXT\t·Syscall6(SB),NOSPLIT,$0-40\n\tJMP\tsyscall·Syscall6(SB)\n\nTEXT\t·Syscall9(SB),NOSPLIT,$0-52\n\tJMP\tsyscall·Syscall9(SB)\n\nTEXT\t·RawSyscall(SB),NOSPLIT,$0-28\n\tJMP\tsyscall·RawSyscall(SB)\n\nTEXT\t·RawSyscall6(SB),NOSPLIT,$0-40\n\tJMP\tsyscall·RawSyscall6(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_bsd_amd64.s",
    "content": "// Copyright 2021 The Go 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\n//go:build (darwin || dragonfly || freebsd || netbsd || openbsd) && gc\n\n#include \"textflag.h\"\n\n// System call support for AMD64 BSD\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT\t·Syscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·Syscall(SB)\n\nTEXT\t·Syscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·Syscall6(SB)\n\nTEXT\t·Syscall9(SB),NOSPLIT,$0-104\n\tJMP\tsyscall·Syscall9(SB)\n\nTEXT\t·RawSyscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·RawSyscall(SB)\n\nTEXT\t·RawSyscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·RawSyscall6(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_bsd_arm.s",
    "content": "// Copyright 2021 The Go 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\n//go:build (freebsd || netbsd || openbsd) && gc\n\n#include \"textflag.h\"\n\n// System call support for ARM BSD\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT\t·Syscall(SB),NOSPLIT,$0-28\n\tB\tsyscall·Syscall(SB)\n\nTEXT\t·Syscall6(SB),NOSPLIT,$0-40\n\tB\tsyscall·Syscall6(SB)\n\nTEXT\t·Syscall9(SB),NOSPLIT,$0-52\n\tB\tsyscall·Syscall9(SB)\n\nTEXT\t·RawSyscall(SB),NOSPLIT,$0-28\n\tB\tsyscall·RawSyscall(SB)\n\nTEXT\t·RawSyscall6(SB),NOSPLIT,$0-40\n\tB\tsyscall·RawSyscall6(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_bsd_arm64.s",
    "content": "// Copyright 2021 The Go 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\n//go:build (darwin || freebsd || netbsd || openbsd) && gc\n\n#include \"textflag.h\"\n\n// System call support for ARM64 BSD\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT\t·Syscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·Syscall(SB)\n\nTEXT\t·Syscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·Syscall6(SB)\n\nTEXT\t·Syscall9(SB),NOSPLIT,$0-104\n\tJMP\tsyscall·Syscall9(SB)\n\nTEXT\t·RawSyscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·RawSyscall(SB)\n\nTEXT\t·RawSyscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·RawSyscall6(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s",
    "content": "// Copyright 2022 The Go 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\n//go:build (darwin || freebsd || netbsd || openbsd) && gc\n\n#include \"textflag.h\"\n\n//\n// System call support for ppc64, BSD\n//\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT\t·Syscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·Syscall(SB)\n\nTEXT\t·Syscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·Syscall6(SB)\n\nTEXT\t·Syscall9(SB),NOSPLIT,$0-104\n\tJMP\tsyscall·Syscall9(SB)\n\nTEXT\t·RawSyscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·RawSyscall(SB)\n\nTEXT\t·RawSyscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·RawSyscall6(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_bsd_riscv64.s",
    "content": "// Copyright 2021 The Go 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\n//go:build (darwin || freebsd || netbsd || openbsd) && gc\n\n#include \"textflag.h\"\n\n// System call support for RISCV64 BSD\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT\t·Syscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·Syscall(SB)\n\nTEXT\t·Syscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·Syscall6(SB)\n\nTEXT\t·Syscall9(SB),NOSPLIT,$0-104\n\tJMP\tsyscall·Syscall9(SB)\n\nTEXT\t·RawSyscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·RawSyscall(SB)\n\nTEXT\t·RawSyscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·RawSyscall6(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_linux_386.s",
    "content": "// Copyright 2009 The Go 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\n//go:build gc\n\n#include \"textflag.h\"\n\n//\n// System calls for 386, Linux\n//\n\n// See ../runtime/sys_linux_386.s for the reason why we always use int 0x80\n// instead of the glibc-specific \"CALL 0x10(GS)\".\n#define INVOKE_SYSCALL\tINT\t$0x80\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT ·Syscall(SB),NOSPLIT,$0-28\n\tJMP\tsyscall·Syscall(SB)\n\nTEXT ·Syscall6(SB),NOSPLIT,$0-40\n\tJMP\tsyscall·Syscall6(SB)\n\nTEXT ·SyscallNoError(SB),NOSPLIT,$0-24\n\tCALL\truntime·entersyscall(SB)\n\tMOVL\ttrap+0(FP), AX  // syscall entry\n\tMOVL\ta1+4(FP), BX\n\tMOVL\ta2+8(FP), CX\n\tMOVL\ta3+12(FP), DX\n\tMOVL\t$0, SI\n\tMOVL\t$0, DI\n\tINVOKE_SYSCALL\n\tMOVL\tAX, r1+16(FP)\n\tMOVL\tDX, r2+20(FP)\n\tCALL\truntime·exitsyscall(SB)\n\tRET\n\nTEXT ·RawSyscall(SB),NOSPLIT,$0-28\n\tJMP\tsyscall·RawSyscall(SB)\n\nTEXT ·RawSyscall6(SB),NOSPLIT,$0-40\n\tJMP\tsyscall·RawSyscall6(SB)\n\nTEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24\n\tMOVL\ttrap+0(FP), AX  // syscall entry\n\tMOVL\ta1+4(FP), BX\n\tMOVL\ta2+8(FP), CX\n\tMOVL\ta3+12(FP), DX\n\tMOVL\t$0, SI\n\tMOVL\t$0, DI\n\tINVOKE_SYSCALL\n\tMOVL\tAX, r1+16(FP)\n\tMOVL\tDX, r2+20(FP)\n\tRET\n\nTEXT ·socketcall(SB),NOSPLIT,$0-36\n\tJMP\tsyscall·socketcall(SB)\n\nTEXT ·rawsocketcall(SB),NOSPLIT,$0-36\n\tJMP\tsyscall·rawsocketcall(SB)\n\nTEXT ·seek(SB),NOSPLIT,$0-28\n\tJMP\tsyscall·seek(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_linux_amd64.s",
    "content": "// Copyright 2009 The Go 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\n//go:build gc\n\n#include \"textflag.h\"\n\n//\n// System calls for AMD64, Linux\n//\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT ·Syscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·Syscall(SB)\n\nTEXT ·Syscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·Syscall6(SB)\n\nTEXT ·SyscallNoError(SB),NOSPLIT,$0-48\n\tCALL\truntime·entersyscall(SB)\n\tMOVQ\ta1+8(FP), DI\n\tMOVQ\ta2+16(FP), SI\n\tMOVQ\ta3+24(FP), DX\n\tMOVQ\t$0, R10\n\tMOVQ\t$0, R8\n\tMOVQ\t$0, R9\n\tMOVQ\ttrap+0(FP), AX\t// syscall entry\n\tSYSCALL\n\tMOVQ\tAX, r1+32(FP)\n\tMOVQ\tDX, r2+40(FP)\n\tCALL\truntime·exitsyscall(SB)\n\tRET\n\nTEXT ·RawSyscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·RawSyscall(SB)\n\nTEXT ·RawSyscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·RawSyscall6(SB)\n\nTEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48\n\tMOVQ\ta1+8(FP), DI\n\tMOVQ\ta2+16(FP), SI\n\tMOVQ\ta3+24(FP), DX\n\tMOVQ\t$0, R10\n\tMOVQ\t$0, R8\n\tMOVQ\t$0, R9\n\tMOVQ\ttrap+0(FP), AX\t// syscall entry\n\tSYSCALL\n\tMOVQ\tAX, r1+32(FP)\n\tMOVQ\tDX, r2+40(FP)\n\tRET\n\nTEXT ·gettimeofday(SB),NOSPLIT,$0-16\n\tJMP\tsyscall·gettimeofday(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_linux_arm.s",
    "content": "// Copyright 2009 The Go 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\n//go:build gc\n\n#include \"textflag.h\"\n\n//\n// System calls for arm, Linux\n//\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT ·Syscall(SB),NOSPLIT,$0-28\n\tB\tsyscall·Syscall(SB)\n\nTEXT ·Syscall6(SB),NOSPLIT,$0-40\n\tB\tsyscall·Syscall6(SB)\n\nTEXT ·SyscallNoError(SB),NOSPLIT,$0-24\n\tBL\truntime·entersyscall(SB)\n\tMOVW\ttrap+0(FP), R7\n\tMOVW\ta1+4(FP), R0\n\tMOVW\ta2+8(FP), R1\n\tMOVW\ta3+12(FP), R2\n\tMOVW\t$0, R3\n\tMOVW\t$0, R4\n\tMOVW\t$0, R5\n\tSWI\t$0\n\tMOVW\tR0, r1+16(FP)\n\tMOVW\t$0, R0\n\tMOVW\tR0, r2+20(FP)\n\tBL\truntime·exitsyscall(SB)\n\tRET\n\nTEXT ·RawSyscall(SB),NOSPLIT,$0-28\n\tB\tsyscall·RawSyscall(SB)\n\nTEXT ·RawSyscall6(SB),NOSPLIT,$0-40\n\tB\tsyscall·RawSyscall6(SB)\n\nTEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24\n\tMOVW\ttrap+0(FP), R7\t// syscall entry\n\tMOVW\ta1+4(FP), R0\n\tMOVW\ta2+8(FP), R1\n\tMOVW\ta3+12(FP), R2\n\tSWI\t$0\n\tMOVW\tR0, r1+16(FP)\n\tMOVW\t$0, R0\n\tMOVW\tR0, r2+20(FP)\n\tRET\n\nTEXT ·seek(SB),NOSPLIT,$0-28\n\tB\tsyscall·seek(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_linux_arm64.s",
    "content": "// Copyright 2015 The Go 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\n//go:build linux && arm64 && gc\n\n#include \"textflag.h\"\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT ·Syscall(SB),NOSPLIT,$0-56\n\tB\tsyscall·Syscall(SB)\n\nTEXT ·Syscall6(SB),NOSPLIT,$0-80\n\tB\tsyscall·Syscall6(SB)\n\nTEXT ·SyscallNoError(SB),NOSPLIT,$0-48\n\tBL\truntime·entersyscall(SB)\n\tMOVD\ta1+8(FP), R0\n\tMOVD\ta2+16(FP), R1\n\tMOVD\ta3+24(FP), R2\n\tMOVD\t$0, R3\n\tMOVD\t$0, R4\n\tMOVD\t$0, R5\n\tMOVD\ttrap+0(FP), R8\t// syscall entry\n\tSVC\n\tMOVD\tR0, r1+32(FP)\t// r1\n\tMOVD\tR1, r2+40(FP)\t// r2\n\tBL\truntime·exitsyscall(SB)\n\tRET\n\nTEXT ·RawSyscall(SB),NOSPLIT,$0-56\n\tB\tsyscall·RawSyscall(SB)\n\nTEXT ·RawSyscall6(SB),NOSPLIT,$0-80\n\tB\tsyscall·RawSyscall6(SB)\n\nTEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48\n\tMOVD\ta1+8(FP), R0\n\tMOVD\ta2+16(FP), R1\n\tMOVD\ta3+24(FP), R2\n\tMOVD\t$0, R3\n\tMOVD\t$0, R4\n\tMOVD\t$0, R5\n\tMOVD\ttrap+0(FP), R8\t// syscall entry\n\tSVC\n\tMOVD\tR0, r1+32(FP)\n\tMOVD\tR1, r2+40(FP)\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_linux_loong64.s",
    "content": "// Copyright 2022 The Go 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\n//go:build linux && loong64 && gc\n\n#include \"textflag.h\"\n\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT ·Syscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·Syscall(SB)\n\nTEXT ·Syscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·Syscall6(SB)\n\nTEXT ·SyscallNoError(SB),NOSPLIT,$0-48\n\tJAL\truntime·entersyscall(SB)\n\tMOVV\ta1+8(FP), R4\n\tMOVV\ta2+16(FP), R5\n\tMOVV\ta3+24(FP), R6\n\tMOVV\tR0, R7\n\tMOVV\tR0, R8\n\tMOVV\tR0, R9\n\tMOVV\ttrap+0(FP), R11\t// syscall entry\n\tSYSCALL\n\tMOVV\tR4, r1+32(FP)\n\tMOVV\tR0, r2+40(FP)\t// r2 is not used. Always set to 0\n\tJAL\truntime·exitsyscall(SB)\n\tRET\n\nTEXT ·RawSyscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·RawSyscall(SB)\n\nTEXT ·RawSyscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·RawSyscall6(SB)\n\nTEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48\n\tMOVV\ta1+8(FP), R4\n\tMOVV\ta2+16(FP), R5\n\tMOVV\ta3+24(FP), R6\n\tMOVV\tR0, R7\n\tMOVV\tR0, R8\n\tMOVV\tR0, R9\n\tMOVV\ttrap+0(FP), R11\t// syscall entry\n\tSYSCALL\n\tMOVV\tR4, r1+32(FP)\n\tMOVV\tR0, r2+40(FP)\t// r2 is not used. Always set to 0\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_linux_mips64x.s",
    "content": "// Copyright 2015 The Go 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\n//go:build linux && (mips64 || mips64le) && gc\n\n#include \"textflag.h\"\n\n//\n// System calls for mips64, Linux\n//\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT ·Syscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·Syscall(SB)\n\nTEXT ·Syscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·Syscall6(SB)\n\nTEXT ·SyscallNoError(SB),NOSPLIT,$0-48\n\tJAL\truntime·entersyscall(SB)\n\tMOVV\ta1+8(FP), R4\n\tMOVV\ta2+16(FP), R5\n\tMOVV\ta3+24(FP), R6\n\tMOVV\tR0, R7\n\tMOVV\tR0, R8\n\tMOVV\tR0, R9\n\tMOVV\ttrap+0(FP), R2\t// syscall entry\n\tSYSCALL\n\tMOVV\tR2, r1+32(FP)\n\tMOVV\tR3, r2+40(FP)\n\tJAL\truntime·exitsyscall(SB)\n\tRET\n\nTEXT ·RawSyscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·RawSyscall(SB)\n\nTEXT ·RawSyscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·RawSyscall6(SB)\n\nTEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48\n\tMOVV\ta1+8(FP), R4\n\tMOVV\ta2+16(FP), R5\n\tMOVV\ta3+24(FP), R6\n\tMOVV\tR0, R7\n\tMOVV\tR0, R8\n\tMOVV\tR0, R9\n\tMOVV\ttrap+0(FP), R2\t// syscall entry\n\tSYSCALL\n\tMOVV\tR2, r1+32(FP)\n\tMOVV\tR3, r2+40(FP)\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_linux_mipsx.s",
    "content": "// Copyright 2016 The Go 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\n//go:build linux && (mips || mipsle) && gc\n\n#include \"textflag.h\"\n\n//\n// System calls for mips, Linux\n//\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT ·Syscall(SB),NOSPLIT,$0-28\n\tJMP syscall·Syscall(SB)\n\nTEXT ·Syscall6(SB),NOSPLIT,$0-40\n\tJMP syscall·Syscall6(SB)\n\nTEXT ·Syscall9(SB),NOSPLIT,$0-52\n\tJMP syscall·Syscall9(SB)\n\nTEXT ·SyscallNoError(SB),NOSPLIT,$0-24\n\tJAL\truntime·entersyscall(SB)\n\tMOVW\ta1+4(FP), R4\n\tMOVW\ta2+8(FP), R5\n\tMOVW\ta3+12(FP), R6\n\tMOVW\tR0, R7\n\tMOVW\ttrap+0(FP), R2\t// syscall entry\n\tSYSCALL\n\tMOVW\tR2, r1+16(FP)\t// r1\n\tMOVW\tR3, r2+20(FP)\t// r2\n\tJAL\truntime·exitsyscall(SB)\n\tRET\n\nTEXT ·RawSyscall(SB),NOSPLIT,$0-28\n\tJMP syscall·RawSyscall(SB)\n\nTEXT ·RawSyscall6(SB),NOSPLIT,$0-40\n\tJMP syscall·RawSyscall6(SB)\n\nTEXT ·RawSyscallNoError(SB),NOSPLIT,$0-24\n\tMOVW\ta1+4(FP), R4\n\tMOVW\ta2+8(FP), R5\n\tMOVW\ta3+12(FP), R6\n\tMOVW\ttrap+0(FP), R2\t// syscall entry\n\tSYSCALL\n\tMOVW\tR2, r1+16(FP)\n\tMOVW\tR3, r2+20(FP)\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s",
    "content": "// Copyright 2014 The Go 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\n//go:build linux && (ppc64 || ppc64le) && gc\n\n#include \"textflag.h\"\n\n//\n// System calls for ppc64, Linux\n//\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT ·SyscallNoError(SB),NOSPLIT,$0-48\n\tBL\truntime·entersyscall(SB)\n\tMOVD\ta1+8(FP), R3\n\tMOVD\ta2+16(FP), R4\n\tMOVD\ta3+24(FP), R5\n\tMOVD\tR0, R6\n\tMOVD\tR0, R7\n\tMOVD\tR0, R8\n\tMOVD\ttrap+0(FP), R9\t// syscall entry\n\tSYSCALL R9\n\tMOVD\tR3, r1+32(FP)\n\tMOVD\tR4, r2+40(FP)\n\tBL\truntime·exitsyscall(SB)\n\tRET\n\nTEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48\n\tMOVD\ta1+8(FP), R3\n\tMOVD\ta2+16(FP), R4\n\tMOVD\ta3+24(FP), R5\n\tMOVD\tR0, R6\n\tMOVD\tR0, R7\n\tMOVD\tR0, R8\n\tMOVD\ttrap+0(FP), R9\t// syscall entry\n\tSYSCALL R9\n\tMOVD\tR3, r1+32(FP)\n\tMOVD\tR4, r2+40(FP)\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_linux_riscv64.s",
    "content": "// Copyright 2019 The Go 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\n//go:build riscv64 && gc\n\n#include \"textflag.h\"\n\n//\n// System calls for linux/riscv64.\n//\n// Where available, just jump to package syscall's implementation of\n// these functions.\n\nTEXT ·Syscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·Syscall(SB)\n\nTEXT ·Syscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·Syscall6(SB)\n\nTEXT ·SyscallNoError(SB),NOSPLIT,$0-48\n\tCALL\truntime·entersyscall(SB)\n\tMOV\ta1+8(FP), A0\n\tMOV\ta2+16(FP), A1\n\tMOV\ta3+24(FP), A2\n\tMOV\ttrap+0(FP), A7\t// syscall entry\n\tECALL\n\tMOV\tA0, r1+32(FP)\t// r1\n\tMOV\tA1, r2+40(FP)\t// r2\n\tCALL\truntime·exitsyscall(SB)\n\tRET\n\nTEXT ·RawSyscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·RawSyscall(SB)\n\nTEXT ·RawSyscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·RawSyscall6(SB)\n\nTEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48\n\tMOV\ta1+8(FP), A0\n\tMOV\ta2+16(FP), A1\n\tMOV\ta3+24(FP), A2\n\tMOV\ttrap+0(FP), A7\t// syscall entry\n\tECALL\n\tMOV\tA0, r1+32(FP)\n\tMOV\tA1, r2+40(FP)\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_linux_s390x.s",
    "content": "// Copyright 2016 The Go 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\n//go:build linux && s390x && gc\n\n#include \"textflag.h\"\n\n//\n// System calls for s390x, Linux\n//\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT ·Syscall(SB),NOSPLIT,$0-56\n\tBR\tsyscall·Syscall(SB)\n\nTEXT ·Syscall6(SB),NOSPLIT,$0-80\n\tBR\tsyscall·Syscall6(SB)\n\nTEXT ·SyscallNoError(SB),NOSPLIT,$0-48\n\tBL\truntime·entersyscall(SB)\n\tMOVD\ta1+8(FP), R2\n\tMOVD\ta2+16(FP), R3\n\tMOVD\ta3+24(FP), R4\n\tMOVD\t$0, R5\n\tMOVD\t$0, R6\n\tMOVD\t$0, R7\n\tMOVD\ttrap+0(FP), R1\t// syscall entry\n\tSYSCALL\n\tMOVD\tR2, r1+32(FP)\n\tMOVD\tR3, r2+40(FP)\n\tBL\truntime·exitsyscall(SB)\n\tRET\n\nTEXT ·RawSyscall(SB),NOSPLIT,$0-56\n\tBR\tsyscall·RawSyscall(SB)\n\nTEXT ·RawSyscall6(SB),NOSPLIT,$0-80\n\tBR\tsyscall·RawSyscall6(SB)\n\nTEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48\n\tMOVD\ta1+8(FP), R2\n\tMOVD\ta2+16(FP), R3\n\tMOVD\ta3+24(FP), R4\n\tMOVD\t$0, R5\n\tMOVD\t$0, R6\n\tMOVD\t$0, R7\n\tMOVD\ttrap+0(FP), R1\t// syscall entry\n\tSYSCALL\n\tMOVD\tR2, r1+32(FP)\n\tMOVD\tR3, r2+40(FP)\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_openbsd_mips64.s",
    "content": "// Copyright 2019 The Go 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\n//go:build gc\n\n#include \"textflag.h\"\n\n//\n// System call support for mips64, OpenBSD\n//\n\n// Just jump to package syscall's implementation for all these functions.\n// The runtime may know about them.\n\nTEXT\t·Syscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·Syscall(SB)\n\nTEXT\t·Syscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·Syscall6(SB)\n\nTEXT\t·Syscall9(SB),NOSPLIT,$0-104\n\tJMP\tsyscall·Syscall9(SB)\n\nTEXT\t·RawSyscall(SB),NOSPLIT,$0-56\n\tJMP\tsyscall·RawSyscall(SB)\n\nTEXT\t·RawSyscall6(SB),NOSPLIT,$0-80\n\tJMP\tsyscall·RawSyscall6(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_solaris_amd64.s",
    "content": "// Copyright 2014 The Go 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\n//go:build gc\n\n#include \"textflag.h\"\n\n//\n// System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go\n//\n\nTEXT ·sysvicall6(SB),NOSPLIT,$0-88\n\tJMP\tsyscall·sysvicall6(SB)\n\nTEXT ·rawSysvicall6(SB),NOSPLIT,$0-88\n\tJMP\tsyscall·rawSysvicall6(SB)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/asm_zos_s390x.s",
    "content": "// Copyright 2020 The Go 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\n//go:build zos && s390x && gc\n\n#include \"textflag.h\"\n\n#define PSALAA            1208(R0)\n#define GTAB64(x)           80(x)\n#define LCA64(x)            88(x)\n#define SAVSTACK_ASYNC(x)  336(x) // in the LCA\n#define CAA(x)               8(x)\n#define CEECAATHDID(x)     976(x) // in the CAA\n#define EDCHPXV(x)        1016(x) // in the CAA\n#define GOCB(x)           1104(x) // in the CAA\n\n// SS_*, where x=SAVSTACK_ASYNC\n#define SS_LE(x)             0(x)\n#define SS_GO(x)             8(x)\n#define SS_ERRNO(x)         16(x)\n#define SS_ERRNOJR(x)       20(x)\n\n// Function Descriptor Offsets\n#define __errno  0x156*16\n#define __err2ad 0x16C*16\n\n// Call Instructions\n#define LE_CALL    BYTE $0x0D; BYTE $0x76 // BL R7, R6\n#define SVC_LOAD   BYTE $0x0A; BYTE $0x08 // SVC 08 LOAD\n#define SVC_DELETE BYTE $0x0A; BYTE $0x09 // SVC 09 DELETE\n\nDATA zosLibVec<>(SB)/8, $0\nGLOBL zosLibVec<>(SB), NOPTR, $8\n\nTEXT ·initZosLibVec(SB), NOSPLIT|NOFRAME, $0-0\n\tMOVW PSALAA, R8\n\tMOVD LCA64(R8), R8\n\tMOVD CAA(R8), R8\n\tMOVD EDCHPXV(R8), R8\n\tMOVD R8, zosLibVec<>(SB)\n\tRET\n\nTEXT ·GetZosLibVec(SB), NOSPLIT|NOFRAME, $0-0\n\tMOVD zosLibVec<>(SB), R8\n\tMOVD R8, ret+0(FP)\n\tRET\n\nTEXT ·clearErrno(SB), NOSPLIT, $0-0\n\tBL   addrerrno<>(SB)\n\tMOVD $0, 0(R3)\n\tRET\n\n// Returns the address of errno in R3.\nTEXT addrerrno<>(SB), NOSPLIT|NOFRAME, $0-0\n\t// Get library control area (LCA).\n\tMOVW PSALAA, R8\n\tMOVD LCA64(R8), R8\n\n\t// Get __errno FuncDesc.\n\tMOVD CAA(R8), R9\n\tMOVD EDCHPXV(R9), R9\n\tADD  $(__errno), R9\n\tLMG  0(R9), R5, R6\n\n\t// Switch to saved LE stack.\n\tMOVD SAVSTACK_ASYNC(R8), R9\n\tMOVD 0(R9), R4\n\tMOVD $0, 0(R9)\n\n\t// Call __errno function.\n\tLE_CALL\n\tNOPH\n\n\t// Switch back to Go stack.\n\tXOR  R0, R0    // Restore R0 to $0.\n\tMOVD R4, 0(R9) // Save stack pointer.\n\tRET\n\n// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)\nTEXT ·svcCall(SB), NOSPLIT, $0\n\tBL   runtime·save_g(SB)     // Save g and stack pointer\n\tMOVW PSALAA, R8\n\tMOVD LCA64(R8), R8\n\tMOVD SAVSTACK_ASYNC(R8), R9\n\tMOVD R15, 0(R9)\n\n\tMOVD argv+8(FP), R1   // Move function arguments into registers\n\tMOVD dsa+16(FP), g\n\tMOVD fnptr+0(FP), R15\n\n\tBYTE $0x0D // Branch to function\n\tBYTE $0xEF\n\n\tBL   runtime·load_g(SB)     // Restore g and stack pointer\n\tMOVW PSALAA, R8\n\tMOVD LCA64(R8), R8\n\tMOVD SAVSTACK_ASYNC(R8), R9\n\tMOVD 0(R9), R15\n\n\tRET\n\n// func svcLoad(name *byte) unsafe.Pointer\nTEXT ·svcLoad(SB), NOSPLIT, $0\n\tMOVD R15, R2         // Save go stack pointer\n\tMOVD name+0(FP), R0  // Move SVC args into registers\n\tMOVD $0x80000000, R1\n\tMOVD $0, R15\n\tSVC_LOAD\n\tMOVW R15, R3         // Save return code from SVC\n\tMOVD R2, R15         // Restore go stack pointer\n\tCMP  R3, $0          // Check SVC return code\n\tBNE  error\n\n\tMOVD $-2, R3       // Reset last bit of entry point to zero\n\tAND  R0, R3\n\tMOVD R3, ret+8(FP) // Return entry point returned by SVC\n\tCMP  R0, R3        // Check if last bit of entry point was set\n\tBNE  done\n\n\tMOVD R15, R2 // Save go stack pointer\n\tMOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08)\n\tSVC_DELETE\n\tMOVD R2, R15 // Restore go stack pointer\n\nerror:\n\tMOVD $0, ret+8(FP) // Return 0 on failure\n\ndone:\n\tXOR R0, R0 // Reset r0 to 0\n\tRET\n\n// func svcUnload(name *byte, fnptr unsafe.Pointer) int64\nTEXT ·svcUnload(SB), NOSPLIT, $0\n\tMOVD R15, R2          // Save go stack pointer\n\tMOVD name+0(FP), R0   // Move SVC args into registers\n\tMOVD fnptr+8(FP), R15\n\tSVC_DELETE\n\tXOR  R0, R0           // Reset r0 to 0\n\tMOVD R15, R1          // Save SVC return code\n\tMOVD R2, R15          // Restore go stack pointer\n\tMOVD R1, ret+16(FP)   // Return SVC return code\n\tRET\n\n// func gettid() uint64\nTEXT ·gettid(SB), NOSPLIT, $0\n\t// Get library control area (LCA).\n\tMOVW PSALAA, R8\n\tMOVD LCA64(R8), R8\n\n\t// Get CEECAATHDID\n\tMOVD CAA(R8), R9\n\tMOVD CEECAATHDID(R9), R9\n\tMOVD R9, ret+0(FP)\n\n\tRET\n\n//\n// Call LE function, if the return is -1\n// errno and errno2 is retrieved\n//\nTEXT ·CallLeFuncWithErr(SB), NOSPLIT, $0\n\tMOVW PSALAA, R8\n\tMOVD LCA64(R8), R8\n\tMOVD CAA(R8), R9\n\tMOVD g, GOCB(R9)\n\n\t// Restore LE stack.\n\tMOVD SAVSTACK_ASYNC(R8), R9 // R9-> LE stack frame saving address\n\tMOVD 0(R9), R4              // R4-> restore previously saved stack frame pointer\n\n\tMOVD parms_base+8(FP), R7 // R7 -> argument array\n\tMOVD parms_len+16(FP), R8 // R8 number of arguments\n\n\t//  arg 1 ---> R1\n\tCMP  R8, $0\n\tBEQ  docall\n\tSUB  $1, R8\n\tMOVD 0(R7), R1\n\n\t//  arg 2 ---> R2\n\tCMP  R8, $0\n\tBEQ  docall\n\tSUB  $1, R8\n\tADD  $8, R7\n\tMOVD 0(R7), R2\n\n\t//  arg 3 --> R3\n\tCMP  R8, $0\n\tBEQ  docall\n\tSUB  $1, R8\n\tADD  $8, R7\n\tMOVD 0(R7), R3\n\n\tCMP  R8, $0\n\tBEQ  docall\n\tMOVD $2176+16, R6 // starting LE stack address-8 to store 4th argument\n\nrepeat:\n\tADD  $8, R7\n\tMOVD 0(R7), R0      // advance arg pointer by 8 byte\n\tADD  $8, R6         // advance LE argument address by 8 byte\n\tMOVD R0, (R4)(R6*1) // copy argument from go-slice to le-frame\n\tSUB  $1, R8\n\tCMP  R8, $0\n\tBNE  repeat\n\ndocall:\n\tMOVD funcdesc+0(FP), R8 // R8-> function descriptor\n\tLMG  0(R8), R5, R6\n\tMOVD $0, 0(R9)          // R9 address of SAVSTACK_ASYNC\n\tLE_CALL                 // balr R7, R6 (return #1)\n\tNOPH\n\tMOVD R3, ret+32(FP)\n\tCMP  R3, $-1            // compare result to -1\n\tBNE  done\n\n\t// retrieve errno and errno2\n\tMOVD  zosLibVec<>(SB), R8\n\tADD   $(__errno), R8\n\tLMG   0(R8), R5, R6\n\tLE_CALL                   // balr R7, R6 __errno (return #3)\n\tNOPH\n\tMOVWZ 0(R3), R3\n\tMOVD  R3, err+48(FP)\n\tMOVD  zosLibVec<>(SB), R8\n\tADD   $(__err2ad), R8\n\tLMG   0(R8), R5, R6\n\tLE_CALL                   // balr R7, R6 __err2ad (return #2)\n\tNOPH\n\tMOVW  (R3), R2            // retrieve errno2\n\tMOVD  R2, errno2+40(FP)   // store in return area\n\ndone:\n\tMOVD R4, 0(R9)            // Save stack pointer.\n\tRET\n\n//\n// Call LE function, if the return is 0\n// errno and errno2 is retrieved\n//\nTEXT ·CallLeFuncWithPtrReturn(SB), NOSPLIT, $0\n\tMOVW PSALAA, R8\n\tMOVD LCA64(R8), R8\n\tMOVD CAA(R8), R9\n\tMOVD g, GOCB(R9)\n\n\t// Restore LE stack.\n\tMOVD SAVSTACK_ASYNC(R8), R9 // R9-> LE stack frame saving address\n\tMOVD 0(R9), R4              // R4-> restore previously saved stack frame pointer\n\n\tMOVD parms_base+8(FP), R7 // R7 -> argument array\n\tMOVD parms_len+16(FP), R8 // R8 number of arguments\n\n\t//  arg 1 ---> R1\n\tCMP  R8, $0\n\tBEQ  docall\n\tSUB  $1, R8\n\tMOVD 0(R7), R1\n\n\t//  arg 2 ---> R2\n\tCMP  R8, $0\n\tBEQ  docall\n\tSUB  $1, R8\n\tADD  $8, R7\n\tMOVD 0(R7), R2\n\n\t//  arg 3 --> R3\n\tCMP  R8, $0\n\tBEQ  docall\n\tSUB  $1, R8\n\tADD  $8, R7\n\tMOVD 0(R7), R3\n\n\tCMP  R8, $0\n\tBEQ  docall\n\tMOVD $2176+16, R6 // starting LE stack address-8 to store 4th argument\n\nrepeat:\n\tADD  $8, R7\n\tMOVD 0(R7), R0      // advance arg pointer by 8 byte\n\tADD  $8, R6         // advance LE argument address by 8 byte\n\tMOVD R0, (R4)(R6*1) // copy argument from go-slice to le-frame\n\tSUB  $1, R8\n\tCMP  R8, $0\n\tBNE  repeat\n\ndocall:\n\tMOVD funcdesc+0(FP), R8 // R8-> function descriptor\n\tLMG  0(R8), R5, R6\n\tMOVD $0, 0(R9)          // R9 address of SAVSTACK_ASYNC\n\tLE_CALL                 // balr R7, R6 (return #1)\n\tNOPH\n\tMOVD R3, ret+32(FP)\n\tCMP  R3, $0             // compare result to 0\n\tBNE  done\n\n\t// retrieve errno and errno2\n\tMOVD  zosLibVec<>(SB), R8\n\tADD   $(__errno), R8\n\tLMG   0(R8), R5, R6\n\tLE_CALL                   // balr R7, R6 __errno (return #3)\n\tNOPH\n\tMOVWZ 0(R3), R3\n\tMOVD  R3, err+48(FP)\n\tMOVD  zosLibVec<>(SB), R8\n\tADD   $(__err2ad), R8\n\tLMG   0(R8), R5, R6\n\tLE_CALL                   // balr R7, R6 __err2ad (return #2)\n\tNOPH\n\tMOVW  (R3), R2            // retrieve errno2\n\tMOVD  R2, errno2+40(FP)   // store in return area\n\tXOR   R2, R2\n\tMOVWZ R2, (R3)            // clear errno2\n\ndone:\n\tMOVD R4, 0(R9)            // Save stack pointer.\n\tRET\n\n//\n// function to test if a pointer can be safely dereferenced (content read)\n// return 0 for succces\n//\nTEXT ·ptrtest(SB), NOSPLIT, $0-16\n\tMOVD arg+0(FP), R10 // test pointer in R10\n\n\t// set up R2 to point to CEECAADMC\n\tBYTE $0xE3; BYTE $0x20; BYTE $0x04; BYTE $0xB8; BYTE $0x00; BYTE $0x17 // llgt  2,1208\n\tBYTE $0xB9; BYTE $0x17; BYTE $0x00; BYTE $0x22                         // llgtr 2,2\n\tBYTE $0xA5; BYTE $0x26; BYTE $0x7F; BYTE $0xFF                         // nilh  2,32767\n\tBYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x58; BYTE $0x00; BYTE $0x04 // lg    2,88(2)\n\tBYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x08; BYTE $0x00; BYTE $0x04 // lg    2,8(2)\n\tBYTE $0x41; BYTE $0x22; BYTE $0x03; BYTE $0x68                         // la    2,872(2)\n\n\t// set up R5 to point to the \"shunt\" path which set 1 to R3 (failure)\n\tBYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x33 // xgr   3,3\n\tBYTE $0xA7; BYTE $0x55; BYTE $0x00; BYTE $0x04 // bras  5,lbl1\n\tBYTE $0xA7; BYTE $0x39; BYTE $0x00; BYTE $0x01 // lghi  3,1\n\n\t// if r3 is not zero (failed) then branch to finish\n\tBYTE $0xB9; BYTE $0x02; BYTE $0x00; BYTE $0x33 // lbl1     ltgr  3,3\n\tBYTE $0xA7; BYTE $0x74; BYTE $0x00; BYTE $0x08 // brc   b'0111',lbl2\n\n\t// stomic store shunt address in R5 into CEECAADMC\n\tBYTE $0xE3; BYTE $0x52; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg   5,0(2)\n\n\t// now try reading from the test pointer in R10, if it fails it branches to the \"lghi\" instruction above\n\tBYTE $0xE3; BYTE $0x9A; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x04 // lg    9,0(10)\n\n\t// finish here, restore 0 into CEECAADMC\n\tBYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x99                         // lbl2     xgr   9,9\n\tBYTE $0xE3; BYTE $0x92; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg   9,0(2)\n\tMOVD R3, ret+8(FP)                                                     // result in R3\n\tRET\n\n//\n// function to test if a untptr can be loaded from a pointer\n// return 1: the 8-byte content\n//        2: 0 for success, 1 for failure\n//\n// func safeload(ptr uintptr) ( value uintptr, error uintptr)\nTEXT ·safeload(SB), NOSPLIT, $0-24\n\tMOVD ptr+0(FP), R10                                                    // test pointer in R10\n\tMOVD $0x0, R6\n\tBYTE $0xE3; BYTE $0x20; BYTE $0x04; BYTE $0xB8; BYTE $0x00; BYTE $0x17 // llgt  2,1208\n\tBYTE $0xB9; BYTE $0x17; BYTE $0x00; BYTE $0x22                         // llgtr 2,2\n\tBYTE $0xA5; BYTE $0x26; BYTE $0x7F; BYTE $0xFF                         // nilh  2,32767\n\tBYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x58; BYTE $0x00; BYTE $0x04 // lg    2,88(2)\n\tBYTE $0xE3; BYTE $0x22; BYTE $0x00; BYTE $0x08; BYTE $0x00; BYTE $0x04 // lg    2,8(2)\n\tBYTE $0x41; BYTE $0x22; BYTE $0x03; BYTE $0x68                         // la    2,872(2)\n\tBYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x33                         // xgr   3,3\n\tBYTE $0xA7; BYTE $0x55; BYTE $0x00; BYTE $0x04                         // bras  5,lbl1\n\tBYTE $0xA7; BYTE $0x39; BYTE $0x00; BYTE $0x01                         // lghi  3,1\n\tBYTE $0xB9; BYTE $0x02; BYTE $0x00; BYTE $0x33                         // lbl1     ltgr  3,3\n\tBYTE $0xA7; BYTE $0x74; BYTE $0x00; BYTE $0x08                         // brc   b'0111',lbl2\n\tBYTE $0xE3; BYTE $0x52; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg 5,0(2)\n\tBYTE $0xE3; BYTE $0x6A; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x04 // lg    6,0(10)\n\tBYTE $0xB9; BYTE $0x82; BYTE $0x00; BYTE $0x99                         // lbl2     xgr   9,9\n\tBYTE $0xE3; BYTE $0x92; BYTE $0x00; BYTE $0x00; BYTE $0x00; BYTE $0x24 // stg   9,0(2)\n\tMOVD R6, value+8(FP)                                                   // result in R6\n\tMOVD R3, error+16(FP)                                                  // error in R3\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/auxv.go",
    "content": "// Copyright 2025 The Go 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\n//go:build go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos)\n\npackage unix\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n//go:linkname runtime_getAuxv runtime.getAuxv\nfunc runtime_getAuxv() []uintptr\n\n// Auxv returns the ELF auxiliary vector as a sequence of key/value pairs.\n// The returned slice is always a fresh copy, owned by the caller.\n// It returns an error on non-ELF platforms, or if the auxiliary vector cannot be accessed,\n// which happens in some locked-down environments and build modes.\nfunc Auxv() ([][2]uintptr, error) {\n\tvec := runtime_getAuxv()\n\tvecLen := len(vec)\n\n\tif vecLen == 0 {\n\t\treturn nil, syscall.ENOENT\n\t}\n\n\tif vecLen%2 != 0 {\n\t\treturn nil, syscall.EINVAL\n\t}\n\n\tresult := make([]uintptr, vecLen)\n\tcopy(result, vec)\n\treturn unsafe.Slice((*[2]uintptr)(unsafe.Pointer(&result[0])), vecLen/2), nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/auxv_unsupported.go",
    "content": "// Copyright 2025 The Go 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\n//go:build !go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos)\n\npackage unix\n\nimport \"syscall\"\n\nfunc Auxv() ([][2]uintptr, error) {\n\treturn nil, syscall.ENOTSUP\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/bluetooth_linux.go",
    "content": "// Copyright 2016 The Go 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\n// Bluetooth sockets and messages\n\npackage unix\n\n// Bluetooth Protocols\nconst (\n\tBTPROTO_L2CAP  = 0\n\tBTPROTO_HCI    = 1\n\tBTPROTO_SCO    = 2\n\tBTPROTO_RFCOMM = 3\n\tBTPROTO_BNEP   = 4\n\tBTPROTO_CMTP   = 5\n\tBTPROTO_HIDP   = 6\n\tBTPROTO_AVDTP  = 7\n)\n\nconst (\n\tHCI_CHANNEL_RAW     = 0\n\tHCI_CHANNEL_USER    = 1\n\tHCI_CHANNEL_MONITOR = 2\n\tHCI_CHANNEL_CONTROL = 3\n\tHCI_CHANNEL_LOGGING = 4\n)\n\n// Socketoption Level\nconst (\n\tSOL_BLUETOOTH = 0x112\n\tSOL_HCI       = 0x0\n\tSOL_L2CAP     = 0x6\n\tSOL_RFCOMM    = 0x12\n\tSOL_SCO       = 0x11\n)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/bpxsvc_zos.go",
    "content": "// Copyright 2024 The Go 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\n//go:build zos\n\npackage unix\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"unsafe\"\n)\n\n//go:noescape\nfunc bpxcall(plist []unsafe.Pointer, bpx_offset int64)\n\n//go:noescape\nfunc A2e([]byte)\n\n//go:noescape\nfunc E2a([]byte)\n\nconst (\n\tBPX4STA = 192  // stat\n\tBPX4FST = 104  // fstat\n\tBPX4LST = 132  // lstat\n\tBPX4OPN = 156  // open\n\tBPX4CLO = 72   // close\n\tBPX4CHR = 500  // chattr\n\tBPX4FCR = 504  // fchattr\n\tBPX4LCR = 1180 // lchattr\n\tBPX4CTW = 492  // cond_timed_wait\n\tBPX4GTH = 1056 // __getthent\n\tBPX4PTQ = 412  // pthread_quiesc\n\tBPX4PTR = 320  // ptrace\n)\n\nconst (\n\t//options\n\t//byte1\n\tBPX_OPNFHIGH = 0x80\n\t//byte2\n\tBPX_OPNFEXEC = 0x80\n\t//byte3\n\tBPX_O_NOLARGEFILE = 0x08\n\tBPX_O_LARGEFILE   = 0x04\n\tBPX_O_ASYNCSIG    = 0x02\n\tBPX_O_SYNC        = 0x01\n\t//byte4\n\tBPX_O_CREXCL   = 0xc0\n\tBPX_O_CREAT    = 0x80\n\tBPX_O_EXCL     = 0x40\n\tBPX_O_NOCTTY   = 0x20\n\tBPX_O_TRUNC    = 0x10\n\tBPX_O_APPEND   = 0x08\n\tBPX_O_NONBLOCK = 0x04\n\tBPX_FNDELAY    = 0x04\n\tBPX_O_RDWR     = 0x03\n\tBPX_O_RDONLY   = 0x02\n\tBPX_O_WRONLY   = 0x01\n\tBPX_O_ACCMODE  = 0x03\n\tBPX_O_GETFL    = 0x0f\n\n\t//mode\n\t// byte1 (file type)\n\tBPX_FT_DIR      = 1\n\tBPX_FT_CHARSPEC = 2\n\tBPX_FT_REGFILE  = 3\n\tBPX_FT_FIFO     = 4\n\tBPX_FT_SYMLINK  = 5\n\tBPX_FT_SOCKET   = 6\n\t//byte3\n\tBPX_S_ISUID  = 0x08\n\tBPX_S_ISGID  = 0x04\n\tBPX_S_ISVTX  = 0x02\n\tBPX_S_IRWXU1 = 0x01\n\tBPX_S_IRUSR  = 0x01\n\t//byte4\n\tBPX_S_IRWXU2 = 0xc0\n\tBPX_S_IWUSR  = 0x80\n\tBPX_S_IXUSR  = 0x40\n\tBPX_S_IRWXG  = 0x38\n\tBPX_S_IRGRP  = 0x20\n\tBPX_S_IWGRP  = 0x10\n\tBPX_S_IXGRP  = 0x08\n\tBPX_S_IRWXOX = 0x07\n\tBPX_S_IROTH  = 0x04\n\tBPX_S_IWOTH  = 0x02\n\tBPX_S_IXOTH  = 0x01\n\n\tCW_INTRPT  = 1\n\tCW_CONDVAR = 32\n\tCW_TIMEOUT = 64\n\n\tPGTHA_NEXT        = 2\n\tPGTHA_CURRENT     = 1\n\tPGTHA_FIRST       = 0\n\tPGTHA_LAST        = 3\n\tPGTHA_PROCESS     = 0x80\n\tPGTHA_CONTTY      = 0x40\n\tPGTHA_PATH        = 0x20\n\tPGTHA_COMMAND     = 0x10\n\tPGTHA_FILEDATA    = 0x08\n\tPGTHA_THREAD      = 0x04\n\tPGTHA_PTAG        = 0x02\n\tPGTHA_COMMANDLONG = 0x01\n\tPGTHA_THREADFAST  = 0x80\n\tPGTHA_FILEPATH    = 0x40\n\tPGTHA_THDSIGMASK  = 0x20\n\t// thread quiece mode\n\tQUIESCE_TERM       int32 = 1\n\tQUIESCE_FORCE      int32 = 2\n\tQUIESCE_QUERY      int32 = 3\n\tQUIESCE_FREEZE     int32 = 4\n\tQUIESCE_UNFREEZE   int32 = 5\n\tFREEZE_THIS_THREAD int32 = 6\n\tFREEZE_EXIT        int32 = 8\n\tQUIESCE_SRB        int32 = 9\n)\n\ntype Pgtha struct {\n\tPid        uint32 // 0\n\tTid0       uint32 // 4\n\tTid1       uint32\n\tAccesspid  byte    // C\n\tAccesstid  byte    // D\n\tAccessasid uint16  // E\n\tLoginname  [8]byte // 10\n\tFlag1      byte    // 18\n\tFlag1b2    byte    // 19\n}\n\ntype Bpxystat_t struct { // DSECT BPXYSTAT\n\tSt_id           [4]uint8  // 0\n\tSt_length       uint16    // 0x4\n\tSt_version      uint16    // 0x6\n\tSt_mode         uint32    // 0x8\n\tSt_ino          uint32    // 0xc\n\tSt_dev          uint32    // 0x10\n\tSt_nlink        uint32    // 0x14\n\tSt_uid          uint32    // 0x18\n\tSt_gid          uint32    // 0x1c\n\tSt_size         uint64    // 0x20\n\tSt_atime        uint32    // 0x28\n\tSt_mtime        uint32    // 0x2c\n\tSt_ctime        uint32    // 0x30\n\tSt_rdev         uint32    // 0x34\n\tSt_auditoraudit uint32    // 0x38\n\tSt_useraudit    uint32    // 0x3c\n\tSt_blksize      uint32    // 0x40\n\tSt_createtime   uint32    // 0x44\n\tSt_auditid      [4]uint32 // 0x48\n\tSt_res01        uint32    // 0x58\n\tFt_ccsid        uint16    // 0x5c\n\tFt_flags        uint16    // 0x5e\n\tSt_res01a       [2]uint32 // 0x60\n\tSt_res02        uint32    // 0x68\n\tSt_blocks       uint32    // 0x6c\n\tSt_opaque       [3]uint8  // 0x70\n\tSt_visible      uint8     // 0x73\n\tSt_reftime      uint32    // 0x74\n\tSt_fid          uint64    // 0x78\n\tSt_filefmt      uint8     // 0x80\n\tSt_fspflag2     uint8     // 0x81\n\tSt_res03        [2]uint8  // 0x82\n\tSt_ctimemsec    uint32    // 0x84\n\tSt_seclabel     [8]uint8  // 0x88\n\tSt_res04        [4]uint8  // 0x90\n\t// end of version 1\n\t_               uint32    // 0x94\n\tSt_atime64      uint64    // 0x98\n\tSt_mtime64      uint64    // 0xa0\n\tSt_ctime64      uint64    // 0xa8\n\tSt_createtime64 uint64    // 0xb0\n\tSt_reftime64    uint64    // 0xb8\n\t_               uint64    // 0xc0\n\tSt_res05        [16]uint8 // 0xc8\n\t// end of version 2\n}\n\ntype BpxFilestatus struct {\n\tOflag1 byte\n\tOflag2 byte\n\tOflag3 byte\n\tOflag4 byte\n}\n\ntype BpxMode struct {\n\tFtype byte\n\tMode1 byte\n\tMode2 byte\n\tMode3 byte\n}\n\n// Thr attribute structure for extended attributes\ntype Bpxyatt_t struct { // DSECT BPXYATT\n\tAtt_id           [4]uint8\n\tAtt_version      uint16\n\tAtt_res01        [2]uint8\n\tAtt_setflags1    uint8\n\tAtt_setflags2    uint8\n\tAtt_setflags3    uint8\n\tAtt_setflags4    uint8\n\tAtt_mode         uint32\n\tAtt_uid          uint32\n\tAtt_gid          uint32\n\tAtt_opaquemask   [3]uint8\n\tAtt_visblmaskres uint8\n\tAtt_opaque       [3]uint8\n\tAtt_visibleres   uint8\n\tAtt_size_h       uint32\n\tAtt_size_l       uint32\n\tAtt_atime        uint32\n\tAtt_mtime        uint32\n\tAtt_auditoraudit uint32\n\tAtt_useraudit    uint32\n\tAtt_ctime        uint32\n\tAtt_reftime      uint32\n\t// end of version 1\n\tAtt_filefmt uint8\n\tAtt_res02   [3]uint8\n\tAtt_filetag uint32\n\tAtt_res03   [8]uint8\n\t// end of version 2\n\tAtt_atime64   uint64\n\tAtt_mtime64   uint64\n\tAtt_ctime64   uint64\n\tAtt_reftime64 uint64\n\tAtt_seclabel  [8]uint8\n\tAtt_ver3res02 [8]uint8\n\t// end of version 3\n}\n\nfunc BpxOpen(name string, options *BpxFilestatus, mode *BpxMode) (rv int32, rc int32, rn int32) {\n\tif len(name) < 1024 {\n\t\tvar namebuf [1024]byte\n\t\tsz := int32(copy(namebuf[:], name))\n\t\tA2e(namebuf[:sz])\n\t\tvar parms [7]unsafe.Pointer\n\t\tparms[0] = unsafe.Pointer(&sz)\n\t\tparms[1] = unsafe.Pointer(&namebuf[0])\n\t\tparms[2] = unsafe.Pointer(options)\n\t\tparms[3] = unsafe.Pointer(mode)\n\t\tparms[4] = unsafe.Pointer(&rv)\n\t\tparms[5] = unsafe.Pointer(&rc)\n\t\tparms[6] = unsafe.Pointer(&rn)\n\t\tbpxcall(parms[:], BPX4OPN)\n\t\treturn rv, rc, rn\n\t}\n\treturn -1, -1, -1\n}\n\nfunc BpxClose(fd int32) (rv int32, rc int32, rn int32) {\n\tvar parms [4]unsafe.Pointer\n\tparms[0] = unsafe.Pointer(&fd)\n\tparms[1] = unsafe.Pointer(&rv)\n\tparms[2] = unsafe.Pointer(&rc)\n\tparms[3] = unsafe.Pointer(&rn)\n\tbpxcall(parms[:], BPX4CLO)\n\treturn rv, rc, rn\n}\n\nfunc BpxFileFStat(fd int32, st *Bpxystat_t) (rv int32, rc int32, rn int32) {\n\tst.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}\n\tst.St_version = 2\n\tstat_sz := uint32(unsafe.Sizeof(*st))\n\tvar parms [6]unsafe.Pointer\n\tparms[0] = unsafe.Pointer(&fd)\n\tparms[1] = unsafe.Pointer(&stat_sz)\n\tparms[2] = unsafe.Pointer(st)\n\tparms[3] = unsafe.Pointer(&rv)\n\tparms[4] = unsafe.Pointer(&rc)\n\tparms[5] = unsafe.Pointer(&rn)\n\tbpxcall(parms[:], BPX4FST)\n\treturn rv, rc, rn\n}\n\nfunc BpxFileStat(name string, st *Bpxystat_t) (rv int32, rc int32, rn int32) {\n\tif len(name) < 1024 {\n\t\tvar namebuf [1024]byte\n\t\tsz := int32(copy(namebuf[:], name))\n\t\tA2e(namebuf[:sz])\n\t\tst.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}\n\t\tst.St_version = 2\n\t\tstat_sz := uint32(unsafe.Sizeof(*st))\n\t\tvar parms [7]unsafe.Pointer\n\t\tparms[0] = unsafe.Pointer(&sz)\n\t\tparms[1] = unsafe.Pointer(&namebuf[0])\n\t\tparms[2] = unsafe.Pointer(&stat_sz)\n\t\tparms[3] = unsafe.Pointer(st)\n\t\tparms[4] = unsafe.Pointer(&rv)\n\t\tparms[5] = unsafe.Pointer(&rc)\n\t\tparms[6] = unsafe.Pointer(&rn)\n\t\tbpxcall(parms[:], BPX4STA)\n\t\treturn rv, rc, rn\n\t}\n\treturn -1, -1, -1\n}\n\nfunc BpxFileLStat(name string, st *Bpxystat_t) (rv int32, rc int32, rn int32) {\n\tif len(name) < 1024 {\n\t\tvar namebuf [1024]byte\n\t\tsz := int32(copy(namebuf[:], name))\n\t\tA2e(namebuf[:sz])\n\t\tst.St_id = [4]uint8{0xe2, 0xe3, 0xc1, 0xe3}\n\t\tst.St_version = 2\n\t\tstat_sz := uint32(unsafe.Sizeof(*st))\n\t\tvar parms [7]unsafe.Pointer\n\t\tparms[0] = unsafe.Pointer(&sz)\n\t\tparms[1] = unsafe.Pointer(&namebuf[0])\n\t\tparms[2] = unsafe.Pointer(&stat_sz)\n\t\tparms[3] = unsafe.Pointer(st)\n\t\tparms[4] = unsafe.Pointer(&rv)\n\t\tparms[5] = unsafe.Pointer(&rc)\n\t\tparms[6] = unsafe.Pointer(&rn)\n\t\tbpxcall(parms[:], BPX4LST)\n\t\treturn rv, rc, rn\n\t}\n\treturn -1, -1, -1\n}\n\nfunc BpxChattr(path string, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {\n\tif len(path) >= 1024 {\n\t\treturn -1, -1, -1\n\t}\n\tvar namebuf [1024]byte\n\tsz := int32(copy(namebuf[:], path))\n\tA2e(namebuf[:sz])\n\tattr_sz := uint32(unsafe.Sizeof(*attr))\n\tvar parms [7]unsafe.Pointer\n\tparms[0] = unsafe.Pointer(&sz)\n\tparms[1] = unsafe.Pointer(&namebuf[0])\n\tparms[2] = unsafe.Pointer(&attr_sz)\n\tparms[3] = unsafe.Pointer(attr)\n\tparms[4] = unsafe.Pointer(&rv)\n\tparms[5] = unsafe.Pointer(&rc)\n\tparms[6] = unsafe.Pointer(&rn)\n\tbpxcall(parms[:], BPX4CHR)\n\treturn rv, rc, rn\n}\n\nfunc BpxLchattr(path string, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {\n\tif len(path) >= 1024 {\n\t\treturn -1, -1, -1\n\t}\n\tvar namebuf [1024]byte\n\tsz := int32(copy(namebuf[:], path))\n\tA2e(namebuf[:sz])\n\tattr_sz := uint32(unsafe.Sizeof(*attr))\n\tvar parms [7]unsafe.Pointer\n\tparms[0] = unsafe.Pointer(&sz)\n\tparms[1] = unsafe.Pointer(&namebuf[0])\n\tparms[2] = unsafe.Pointer(&attr_sz)\n\tparms[3] = unsafe.Pointer(attr)\n\tparms[4] = unsafe.Pointer(&rv)\n\tparms[5] = unsafe.Pointer(&rc)\n\tparms[6] = unsafe.Pointer(&rn)\n\tbpxcall(parms[:], BPX4LCR)\n\treturn rv, rc, rn\n}\n\nfunc BpxFchattr(fd int32, attr *Bpxyatt_t) (rv int32, rc int32, rn int32) {\n\tattr_sz := uint32(unsafe.Sizeof(*attr))\n\tvar parms [6]unsafe.Pointer\n\tparms[0] = unsafe.Pointer(&fd)\n\tparms[1] = unsafe.Pointer(&attr_sz)\n\tparms[2] = unsafe.Pointer(attr)\n\tparms[3] = unsafe.Pointer(&rv)\n\tparms[4] = unsafe.Pointer(&rc)\n\tparms[5] = unsafe.Pointer(&rn)\n\tbpxcall(parms[:], BPX4FCR)\n\treturn rv, rc, rn\n}\n\nfunc BpxCondTimedWait(sec uint32, nsec uint32, events uint32, secrem *uint32, nsecrem *uint32) (rv int32, rc int32, rn int32) {\n\tvar parms [8]unsafe.Pointer\n\tparms[0] = unsafe.Pointer(&sec)\n\tparms[1] = unsafe.Pointer(&nsec)\n\tparms[2] = unsafe.Pointer(&events)\n\tparms[3] = unsafe.Pointer(secrem)\n\tparms[4] = unsafe.Pointer(nsecrem)\n\tparms[5] = unsafe.Pointer(&rv)\n\tparms[6] = unsafe.Pointer(&rc)\n\tparms[7] = unsafe.Pointer(&rn)\n\tbpxcall(parms[:], BPX4CTW)\n\treturn rv, rc, rn\n}\nfunc BpxGetthent(in *Pgtha, outlen *uint32, out unsafe.Pointer) (rv int32, rc int32, rn int32) {\n\tvar parms [7]unsafe.Pointer\n\tinlen := uint32(26) // nothing else will work. Go says Pgtha is 28-byte because of alignment, but Pgtha is \"packed\" and must be 26-byte\n\tparms[0] = unsafe.Pointer(&inlen)\n\tparms[1] = unsafe.Pointer(&in)\n\tparms[2] = unsafe.Pointer(outlen)\n\tparms[3] = unsafe.Pointer(&out)\n\tparms[4] = unsafe.Pointer(&rv)\n\tparms[5] = unsafe.Pointer(&rc)\n\tparms[6] = unsafe.Pointer(&rn)\n\tbpxcall(parms[:], BPX4GTH)\n\treturn rv, rc, rn\n}\nfunc ZosJobname() (jobname string, err error) {\n\tvar pgtha Pgtha\n\tpgtha.Pid = uint32(Getpid())\n\tpgtha.Accesspid = PGTHA_CURRENT\n\tpgtha.Flag1 = PGTHA_PROCESS\n\tvar out [256]byte\n\tvar outlen uint32\n\toutlen = 256\n\trv, rc, rn := BpxGetthent(&pgtha, &outlen, unsafe.Pointer(&out[0]))\n\tif rv == 0 {\n\t\tgthc := []byte{0x87, 0xa3, 0x88, 0x83} // 'gthc' in ebcdic\n\t\tix := bytes.Index(out[:], gthc)\n\t\tif ix == -1 {\n\t\t\terr = fmt.Errorf(\"BPX4GTH: gthc return data not found\")\n\t\t\treturn\n\t\t}\n\t\tjn := out[ix+80 : ix+88] // we didn't declare Pgthc, but jobname is 8-byte at offset 80\n\t\tE2a(jn)\n\t\tjobname = string(bytes.TrimRight(jn, \" \"))\n\n\t} else {\n\t\terr = fmt.Errorf(\"BPX4GTH: rc=%d errno=%d reason=code=0x%x\", rv, rc, rn)\n\t}\n\treturn\n}\nfunc Bpx4ptq(code int32, data string) (rv int32, rc int32, rn int32) {\n\tvar userdata [8]byte\n\tvar parms [5]unsafe.Pointer\n\tcopy(userdata[:], data+\"        \")\n\tA2e(userdata[:])\n\tparms[0] = unsafe.Pointer(&code)\n\tparms[1] = unsafe.Pointer(&userdata[0])\n\tparms[2] = unsafe.Pointer(&rv)\n\tparms[3] = unsafe.Pointer(&rc)\n\tparms[4] = unsafe.Pointer(&rn)\n\tbpxcall(parms[:], BPX4PTQ)\n\treturn rv, rc, rn\n}\n\nconst (\n\tPT_TRACE_ME             = 0  // Debug this process\n\tPT_READ_I               = 1  // Read a full word\n\tPT_READ_D               = 2  // Read a full word\n\tPT_READ_U               = 3  // Read control info\n\tPT_WRITE_I              = 4  //Write a full word\n\tPT_WRITE_D              = 5  //Write a full word\n\tPT_CONTINUE             = 7  //Continue the process\n\tPT_KILL                 = 8  //Terminate the process\n\tPT_READ_GPR             = 11 // Read GPR, CR, PSW\n\tPT_READ_FPR             = 12 // Read FPR\n\tPT_READ_VR              = 13 // Read VR\n\tPT_WRITE_GPR            = 14 // Write GPR, CR, PSW\n\tPT_WRITE_FPR            = 15 // Write FPR\n\tPT_WRITE_VR             = 16 // Write VR\n\tPT_READ_BLOCK           = 17 // Read storage\n\tPT_WRITE_BLOCK          = 19 // Write storage\n\tPT_READ_GPRH            = 20 // Read GPRH\n\tPT_WRITE_GPRH           = 21 // Write GPRH\n\tPT_REGHSET              = 22 // Read all GPRHs\n\tPT_ATTACH               = 30 // Attach to a process\n\tPT_DETACH               = 31 // Detach from a process\n\tPT_REGSET               = 32 // Read all GPRs\n\tPT_REATTACH             = 33 // Reattach to a process\n\tPT_LDINFO               = 34 // Read loader info\n\tPT_MULTI                = 35 // Multi process mode\n\tPT_LD64INFO             = 36 // RMODE64 Info Area\n\tPT_BLOCKREQ             = 40 // Block request\n\tPT_THREAD_INFO          = 60 // Read thread info\n\tPT_THREAD_MODIFY        = 61\n\tPT_THREAD_READ_FOCUS    = 62\n\tPT_THREAD_WRITE_FOCUS   = 63\n\tPT_THREAD_HOLD          = 64\n\tPT_THREAD_SIGNAL        = 65\n\tPT_EXPLAIN              = 66\n\tPT_EVENTS               = 67\n\tPT_THREAD_INFO_EXTENDED = 68\n\tPT_REATTACH2            = 71\n\tPT_CAPTURE              = 72\n\tPT_UNCAPTURE            = 73\n\tPT_GET_THREAD_TCB       = 74\n\tPT_GET_ALET             = 75\n\tPT_SWAPIN               = 76\n\tPT_EXTENDED_EVENT       = 98\n\tPT_RECOVER              = 99  // Debug a program check\n\tPT_GPR0                 = 0   // General purpose register 0\n\tPT_GPR1                 = 1   // General purpose register 1\n\tPT_GPR2                 = 2   // General purpose register 2\n\tPT_GPR3                 = 3   // General purpose register 3\n\tPT_GPR4                 = 4   // General purpose register 4\n\tPT_GPR5                 = 5   // General purpose register 5\n\tPT_GPR6                 = 6   // General purpose register 6\n\tPT_GPR7                 = 7   // General purpose register 7\n\tPT_GPR8                 = 8   // General purpose register 8\n\tPT_GPR9                 = 9   // General purpose register 9\n\tPT_GPR10                = 10  // General purpose register 10\n\tPT_GPR11                = 11  // General purpose register 11\n\tPT_GPR12                = 12  // General purpose register 12\n\tPT_GPR13                = 13  // General purpose register 13\n\tPT_GPR14                = 14  // General purpose register 14\n\tPT_GPR15                = 15  // General purpose register 15\n\tPT_FPR0                 = 16  // Floating point register 0\n\tPT_FPR1                 = 17  // Floating point register 1\n\tPT_FPR2                 = 18  // Floating point register 2\n\tPT_FPR3                 = 19  // Floating point register 3\n\tPT_FPR4                 = 20  // Floating point register 4\n\tPT_FPR5                 = 21  // Floating point register 5\n\tPT_FPR6                 = 22  // Floating point register 6\n\tPT_FPR7                 = 23  // Floating point register 7\n\tPT_FPR8                 = 24  // Floating point register 8\n\tPT_FPR9                 = 25  // Floating point register 9\n\tPT_FPR10                = 26  // Floating point register 10\n\tPT_FPR11                = 27  // Floating point register 11\n\tPT_FPR12                = 28  // Floating point register 12\n\tPT_FPR13                = 29  // Floating point register 13\n\tPT_FPR14                = 30  // Floating point register 14\n\tPT_FPR15                = 31  // Floating point register 15\n\tPT_FPC                  = 32  // Floating point control register\n\tPT_PSW                  = 40  // PSW\n\tPT_PSW0                 = 40  // Left half of the PSW\n\tPT_PSW1                 = 41  // Right half of the PSW\n\tPT_CR0                  = 42  // Control register 0\n\tPT_CR1                  = 43  // Control register 1\n\tPT_CR2                  = 44  // Control register 2\n\tPT_CR3                  = 45  // Control register 3\n\tPT_CR4                  = 46  // Control register 4\n\tPT_CR5                  = 47  // Control register 5\n\tPT_CR6                  = 48  // Control register 6\n\tPT_CR7                  = 49  // Control register 7\n\tPT_CR8                  = 50  // Control register 8\n\tPT_CR9                  = 51  // Control register 9\n\tPT_CR10                 = 52  // Control register 10\n\tPT_CR11                 = 53  // Control register 11\n\tPT_CR12                 = 54  // Control register 12\n\tPT_CR13                 = 55  // Control register 13\n\tPT_CR14                 = 56  // Control register 14\n\tPT_CR15                 = 57  // Control register 15\n\tPT_GPRH0                = 58  // GP High register 0\n\tPT_GPRH1                = 59  // GP High register 1\n\tPT_GPRH2                = 60  // GP High register 2\n\tPT_GPRH3                = 61  // GP High register 3\n\tPT_GPRH4                = 62  // GP High register 4\n\tPT_GPRH5                = 63  // GP High register 5\n\tPT_GPRH6                = 64  // GP High register 6\n\tPT_GPRH7                = 65  // GP High register 7\n\tPT_GPRH8                = 66  // GP High register 8\n\tPT_GPRH9                = 67  // GP High register 9\n\tPT_GPRH10               = 68  // GP High register 10\n\tPT_GPRH11               = 69  // GP High register 11\n\tPT_GPRH12               = 70  // GP High register 12\n\tPT_GPRH13               = 71  // GP High register 13\n\tPT_GPRH14               = 72  // GP High register 14\n\tPT_GPRH15               = 73  // GP High register 15\n\tPT_VR0                  = 74  // Vector register 0\n\tPT_VR1                  = 75  // Vector register 1\n\tPT_VR2                  = 76  // Vector register 2\n\tPT_VR3                  = 77  // Vector register 3\n\tPT_VR4                  = 78  // Vector register 4\n\tPT_VR5                  = 79  // Vector register 5\n\tPT_VR6                  = 80  // Vector register 6\n\tPT_VR7                  = 81  // Vector register 7\n\tPT_VR8                  = 82  // Vector register 8\n\tPT_VR9                  = 83  // Vector register 9\n\tPT_VR10                 = 84  // Vector register 10\n\tPT_VR11                 = 85  // Vector register 11\n\tPT_VR12                 = 86  // Vector register 12\n\tPT_VR13                 = 87  // Vector register 13\n\tPT_VR14                 = 88  // Vector register 14\n\tPT_VR15                 = 89  // Vector register 15\n\tPT_VR16                 = 90  // Vector register 16\n\tPT_VR17                 = 91  // Vector register 17\n\tPT_VR18                 = 92  // Vector register 18\n\tPT_VR19                 = 93  // Vector register 19\n\tPT_VR20                 = 94  // Vector register 20\n\tPT_VR21                 = 95  // Vector register 21\n\tPT_VR22                 = 96  // Vector register 22\n\tPT_VR23                 = 97  // Vector register 23\n\tPT_VR24                 = 98  // Vector register 24\n\tPT_VR25                 = 99  // Vector register 25\n\tPT_VR26                 = 100 // Vector register 26\n\tPT_VR27                 = 101 // Vector register 27\n\tPT_VR28                 = 102 // Vector register 28\n\tPT_VR29                 = 103 // Vector register 29\n\tPT_VR30                 = 104 // Vector register 30\n\tPT_VR31                 = 105 // Vector register 31\n\tPT_PSWG                 = 106 // PSWG\n\tPT_PSWG0                = 106 // Bytes 0-3\n\tPT_PSWG1                = 107 // Bytes 4-7\n\tPT_PSWG2                = 108 // Bytes 8-11 (IA high word)\n\tPT_PSWG3                = 109 // Bytes 12-15 (IA low word)\n)\n\nfunc Bpx4ptr(request int32, pid int32, addr unsafe.Pointer, data unsafe.Pointer, buffer unsafe.Pointer) (rv int32, rc int32, rn int32) {\n\tvar parms [8]unsafe.Pointer\n\tparms[0] = unsafe.Pointer(&request)\n\tparms[1] = unsafe.Pointer(&pid)\n\tparms[2] = unsafe.Pointer(&addr)\n\tparms[3] = unsafe.Pointer(&data)\n\tparms[4] = unsafe.Pointer(&buffer)\n\tparms[5] = unsafe.Pointer(&rv)\n\tparms[6] = unsafe.Pointer(&rc)\n\tparms[7] = unsafe.Pointer(&rn)\n\tbpxcall(parms[:], BPX4PTR)\n\treturn rv, rc, rn\n}\n\nfunc copyU8(val uint8, dest []uint8) int {\n\tif len(dest) < 1 {\n\t\treturn 0\n\t}\n\tdest[0] = val\n\treturn 1\n}\n\nfunc copyU8Arr(src, dest []uint8) int {\n\tif len(dest) < len(src) {\n\t\treturn 0\n\t}\n\tfor i, v := range src {\n\t\tdest[i] = v\n\t}\n\treturn len(src)\n}\n\nfunc copyU16(val uint16, dest []uint16) int {\n\tif len(dest) < 1 {\n\t\treturn 0\n\t}\n\tdest[0] = val\n\treturn 1\n}\n\nfunc copyU32(val uint32, dest []uint32) int {\n\tif len(dest) < 1 {\n\t\treturn 0\n\t}\n\tdest[0] = val\n\treturn 1\n}\n\nfunc copyU32Arr(src, dest []uint32) int {\n\tif len(dest) < len(src) {\n\t\treturn 0\n\t}\n\tfor i, v := range src {\n\t\tdest[i] = v\n\t}\n\treturn len(src)\n}\n\nfunc copyU64(val uint64, dest []uint64) int {\n\tif len(dest) < 1 {\n\t\treturn 0\n\t}\n\tdest[0] = val\n\treturn 1\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/bpxsvc_zos.s",
    "content": "// Copyright 2024 The Go 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\n#include \"go_asm.h\"\n#include \"textflag.h\"\n\n// function to call USS assembly language services\n//\n// doc: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_3.1.0/com.ibm.zos.v3r1.bpxb100/bit64env.htm\n//\n//   arg1 unsafe.Pointer array that ressembles an OS PLIST\n//\n//   arg2 function offset as in\n//       doc: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_3.1.0/com.ibm.zos.v3r1.bpxb100/bpx2cr_List_of_offsets.htm\n//\n// func bpxcall(plist []unsafe.Pointer, bpx_offset int64)\n\nTEXT ·bpxcall(SB), NOSPLIT|NOFRAME, $0\n\tMOVD  plist_base+0(FP), R1  // r1 points to plist\n\tMOVD  bpx_offset+24(FP), R2 // r2 offset to BPX vector table\n\tMOVD  R14, R7               // save r14\n\tMOVD  R15, R8               // save r15\n\tMOVWZ 16(R0), R9\n\tMOVWZ 544(R9), R9\n\tMOVWZ 24(R9), R9            // call vector in r9\n\tADD   R2, R9                // add offset to vector table\n\tMOVWZ (R9), R9              // r9 points to entry point\n\tBYTE  $0x0D                 // BL R14,R9 --> basr r14,r9\n\tBYTE  $0xE9                 // clobbers 0,1,14,15\n\tMOVD  R8, R15               // restore 15\n\tJMP   R7                    // return via saved return address\n\n//   func A2e(arr [] byte)\n//   code page conversion from  819 to 1047\nTEXT ·A2e(SB), NOSPLIT|NOFRAME, $0\n\tMOVD arg_base+0(FP), R2                        // pointer to arry of characters\n\tMOVD arg_len+8(FP), R3                         // count\n\tXOR  R0, R0\n\tXOR  R1, R1\n\tBYTE $0xA7; BYTE $0x15; BYTE $0x00; BYTE $0x82 // BRAS 1,(2+(256/2))\n\n\t// ASCII -> EBCDIC conversion table:\n\tBYTE $0x00; BYTE $0x01; BYTE $0x02; BYTE $0x03\n\tBYTE $0x37; BYTE $0x2d; BYTE $0x2e; BYTE $0x2f\n\tBYTE $0x16; BYTE $0x05; BYTE $0x15; BYTE $0x0b\n\tBYTE $0x0c; BYTE $0x0d; BYTE $0x0e; BYTE $0x0f\n\tBYTE $0x10; BYTE $0x11; BYTE $0x12; BYTE $0x13\n\tBYTE $0x3c; BYTE $0x3d; BYTE $0x32; BYTE $0x26\n\tBYTE $0x18; BYTE $0x19; BYTE $0x3f; BYTE $0x27\n\tBYTE $0x1c; BYTE $0x1d; BYTE $0x1e; BYTE $0x1f\n\tBYTE $0x40; BYTE $0x5a; BYTE $0x7f; BYTE $0x7b\n\tBYTE $0x5b; BYTE $0x6c; BYTE $0x50; BYTE $0x7d\n\tBYTE $0x4d; BYTE $0x5d; BYTE $0x5c; BYTE $0x4e\n\tBYTE $0x6b; BYTE $0x60; BYTE $0x4b; BYTE $0x61\n\tBYTE $0xf0; BYTE $0xf1; BYTE $0xf2; BYTE $0xf3\n\tBYTE $0xf4; BYTE $0xf5; BYTE $0xf6; BYTE $0xf7\n\tBYTE $0xf8; BYTE $0xf9; BYTE $0x7a; BYTE $0x5e\n\tBYTE $0x4c; BYTE $0x7e; BYTE $0x6e; BYTE $0x6f\n\tBYTE $0x7c; BYTE $0xc1; BYTE $0xc2; BYTE $0xc3\n\tBYTE $0xc4; BYTE $0xc5; BYTE $0xc6; BYTE $0xc7\n\tBYTE $0xc8; BYTE $0xc9; BYTE $0xd1; BYTE $0xd2\n\tBYTE $0xd3; BYTE $0xd4; BYTE $0xd5; BYTE $0xd6\n\tBYTE $0xd7; BYTE $0xd8; BYTE $0xd9; BYTE $0xe2\n\tBYTE $0xe3; BYTE $0xe4; BYTE $0xe5; BYTE $0xe6\n\tBYTE $0xe7; BYTE $0xe8; BYTE $0xe9; BYTE $0xad\n\tBYTE $0xe0; BYTE $0xbd; BYTE $0x5f; BYTE $0x6d\n\tBYTE $0x79; BYTE $0x81; BYTE $0x82; BYTE $0x83\n\tBYTE $0x84; BYTE $0x85; BYTE $0x86; BYTE $0x87\n\tBYTE $0x88; BYTE $0x89; BYTE $0x91; BYTE $0x92\n\tBYTE $0x93; BYTE $0x94; BYTE $0x95; BYTE $0x96\n\tBYTE $0x97; BYTE $0x98; BYTE $0x99; BYTE $0xa2\n\tBYTE $0xa3; BYTE $0xa4; BYTE $0xa5; BYTE $0xa6\n\tBYTE $0xa7; BYTE $0xa8; BYTE $0xa9; BYTE $0xc0\n\tBYTE $0x4f; BYTE $0xd0; BYTE $0xa1; BYTE $0x07\n\tBYTE $0x20; BYTE $0x21; BYTE $0x22; BYTE $0x23\n\tBYTE $0x24; BYTE $0x25; BYTE $0x06; BYTE $0x17\n\tBYTE $0x28; BYTE $0x29; BYTE $0x2a; BYTE $0x2b\n\tBYTE $0x2c; BYTE $0x09; BYTE $0x0a; BYTE $0x1b\n\tBYTE $0x30; BYTE $0x31; BYTE $0x1a; BYTE $0x33\n\tBYTE $0x34; BYTE $0x35; BYTE $0x36; BYTE $0x08\n\tBYTE $0x38; BYTE $0x39; BYTE $0x3a; BYTE $0x3b\n\tBYTE $0x04; BYTE $0x14; BYTE $0x3e; BYTE $0xff\n\tBYTE $0x41; BYTE $0xaa; BYTE $0x4a; BYTE $0xb1\n\tBYTE $0x9f; BYTE $0xb2; BYTE $0x6a; BYTE $0xb5\n\tBYTE $0xbb; BYTE $0xb4; BYTE $0x9a; BYTE $0x8a\n\tBYTE $0xb0; BYTE $0xca; BYTE $0xaf; BYTE $0xbc\n\tBYTE $0x90; BYTE $0x8f; BYTE $0xea; BYTE $0xfa\n\tBYTE $0xbe; BYTE $0xa0; BYTE $0xb6; BYTE $0xb3\n\tBYTE $0x9d; BYTE $0xda; BYTE $0x9b; BYTE $0x8b\n\tBYTE $0xb7; BYTE $0xb8; BYTE $0xb9; BYTE $0xab\n\tBYTE $0x64; BYTE $0x65; BYTE $0x62; BYTE $0x66\n\tBYTE $0x63; BYTE $0x67; BYTE $0x9e; BYTE $0x68\n\tBYTE $0x74; BYTE $0x71; BYTE $0x72; BYTE $0x73\n\tBYTE $0x78; BYTE $0x75; BYTE $0x76; BYTE $0x77\n\tBYTE $0xac; BYTE $0x69; BYTE $0xed; BYTE $0xee\n\tBYTE $0xeb; BYTE $0xef; BYTE $0xec; BYTE $0xbf\n\tBYTE $0x80; BYTE $0xfd; BYTE $0xfe; BYTE $0xfb\n\tBYTE $0xfc; BYTE $0xba; BYTE $0xae; BYTE $0x59\n\tBYTE $0x44; BYTE $0x45; BYTE $0x42; BYTE $0x46\n\tBYTE $0x43; BYTE $0x47; BYTE $0x9c; BYTE $0x48\n\tBYTE $0x54; BYTE $0x51; BYTE $0x52; BYTE $0x53\n\tBYTE $0x58; BYTE $0x55; BYTE $0x56; BYTE $0x57\n\tBYTE $0x8c; BYTE $0x49; BYTE $0xcd; BYTE $0xce\n\tBYTE $0xcb; BYTE $0xcf; BYTE $0xcc; BYTE $0xe1\n\tBYTE $0x70; BYTE $0xdd; BYTE $0xde; BYTE $0xdb\n\tBYTE $0xdc; BYTE $0x8d; BYTE $0x8e; BYTE $0xdf\n\nretry:\n\tWORD $0xB9931022 // TROO 2,2,b'0001'\n\tBVS  retry\n\tRET\n\n//   func e2a(arr [] byte)\n//   code page conversion from  1047 to 819\nTEXT ·E2a(SB), NOSPLIT|NOFRAME, $0\n\tMOVD arg_base+0(FP), R2                        // pointer to arry of characters\n\tMOVD arg_len+8(FP), R3                         // count\n\tXOR  R0, R0\n\tXOR  R1, R1\n\tBYTE $0xA7; BYTE $0x15; BYTE $0x00; BYTE $0x82 // BRAS 1,(2+(256/2))\n\n\t// EBCDIC -> ASCII conversion table:\n\tBYTE $0x00; BYTE $0x01; BYTE $0x02; BYTE $0x03\n\tBYTE $0x9c; BYTE $0x09; BYTE $0x86; BYTE $0x7f\n\tBYTE $0x97; BYTE $0x8d; BYTE $0x8e; BYTE $0x0b\n\tBYTE $0x0c; BYTE $0x0d; BYTE $0x0e; BYTE $0x0f\n\tBYTE $0x10; BYTE $0x11; BYTE $0x12; BYTE $0x13\n\tBYTE $0x9d; BYTE $0x0a; BYTE $0x08; BYTE $0x87\n\tBYTE $0x18; BYTE $0x19; BYTE $0x92; BYTE $0x8f\n\tBYTE $0x1c; BYTE $0x1d; BYTE $0x1e; BYTE $0x1f\n\tBYTE $0x80; BYTE $0x81; BYTE $0x82; BYTE $0x83\n\tBYTE $0x84; BYTE $0x85; BYTE $0x17; BYTE $0x1b\n\tBYTE $0x88; BYTE $0x89; BYTE $0x8a; BYTE $0x8b\n\tBYTE $0x8c; BYTE $0x05; BYTE $0x06; BYTE $0x07\n\tBYTE $0x90; BYTE $0x91; BYTE $0x16; BYTE $0x93\n\tBYTE $0x94; BYTE $0x95; BYTE $0x96; BYTE $0x04\n\tBYTE $0x98; BYTE $0x99; BYTE $0x9a; BYTE $0x9b\n\tBYTE $0x14; BYTE $0x15; BYTE $0x9e; BYTE $0x1a\n\tBYTE $0x20; BYTE $0xa0; BYTE $0xe2; BYTE $0xe4\n\tBYTE $0xe0; BYTE $0xe1; BYTE $0xe3; BYTE $0xe5\n\tBYTE $0xe7; BYTE $0xf1; BYTE $0xa2; BYTE $0x2e\n\tBYTE $0x3c; BYTE $0x28; BYTE $0x2b; BYTE $0x7c\n\tBYTE $0x26; BYTE $0xe9; BYTE $0xea; BYTE $0xeb\n\tBYTE $0xe8; BYTE $0xed; BYTE $0xee; BYTE $0xef\n\tBYTE $0xec; BYTE $0xdf; BYTE $0x21; BYTE $0x24\n\tBYTE $0x2a; BYTE $0x29; BYTE $0x3b; BYTE $0x5e\n\tBYTE $0x2d; BYTE $0x2f; BYTE $0xc2; BYTE $0xc4\n\tBYTE $0xc0; BYTE $0xc1; BYTE $0xc3; BYTE $0xc5\n\tBYTE $0xc7; BYTE $0xd1; BYTE $0xa6; BYTE $0x2c\n\tBYTE $0x25; BYTE $0x5f; BYTE $0x3e; BYTE $0x3f\n\tBYTE $0xf8; BYTE $0xc9; BYTE $0xca; BYTE $0xcb\n\tBYTE $0xc8; BYTE $0xcd; BYTE $0xce; BYTE $0xcf\n\tBYTE $0xcc; BYTE $0x60; BYTE $0x3a; BYTE $0x23\n\tBYTE $0x40; BYTE $0x27; BYTE $0x3d; BYTE $0x22\n\tBYTE $0xd8; BYTE $0x61; BYTE $0x62; BYTE $0x63\n\tBYTE $0x64; BYTE $0x65; BYTE $0x66; BYTE $0x67\n\tBYTE $0x68; BYTE $0x69; BYTE $0xab; BYTE $0xbb\n\tBYTE $0xf0; BYTE $0xfd; BYTE $0xfe; BYTE $0xb1\n\tBYTE $0xb0; BYTE $0x6a; BYTE $0x6b; BYTE $0x6c\n\tBYTE $0x6d; BYTE $0x6e; BYTE $0x6f; BYTE $0x70\n\tBYTE $0x71; BYTE $0x72; BYTE $0xaa; BYTE $0xba\n\tBYTE $0xe6; BYTE $0xb8; BYTE $0xc6; BYTE $0xa4\n\tBYTE $0xb5; BYTE $0x7e; BYTE $0x73; BYTE $0x74\n\tBYTE $0x75; BYTE $0x76; BYTE $0x77; BYTE $0x78\n\tBYTE $0x79; BYTE $0x7a; BYTE $0xa1; BYTE $0xbf\n\tBYTE $0xd0; BYTE $0x5b; BYTE $0xde; BYTE $0xae\n\tBYTE $0xac; BYTE $0xa3; BYTE $0xa5; BYTE $0xb7\n\tBYTE $0xa9; BYTE $0xa7; BYTE $0xb6; BYTE $0xbc\n\tBYTE $0xbd; BYTE $0xbe; BYTE $0xdd; BYTE $0xa8\n\tBYTE $0xaf; BYTE $0x5d; BYTE $0xb4; BYTE $0xd7\n\tBYTE $0x7b; BYTE $0x41; BYTE $0x42; BYTE $0x43\n\tBYTE $0x44; BYTE $0x45; BYTE $0x46; BYTE $0x47\n\tBYTE $0x48; BYTE $0x49; BYTE $0xad; BYTE $0xf4\n\tBYTE $0xf6; BYTE $0xf2; BYTE $0xf3; BYTE $0xf5\n\tBYTE $0x7d; BYTE $0x4a; BYTE $0x4b; BYTE $0x4c\n\tBYTE $0x4d; BYTE $0x4e; BYTE $0x4f; BYTE $0x50\n\tBYTE $0x51; BYTE $0x52; BYTE $0xb9; BYTE $0xfb\n\tBYTE $0xfc; BYTE $0xf9; BYTE $0xfa; BYTE $0xff\n\tBYTE $0x5c; BYTE $0xf7; BYTE $0x53; BYTE $0x54\n\tBYTE $0x55; BYTE $0x56; BYTE $0x57; BYTE $0x58\n\tBYTE $0x59; BYTE $0x5a; BYTE $0xb2; BYTE $0xd4\n\tBYTE $0xd6; BYTE $0xd2; BYTE $0xd3; BYTE $0xd5\n\tBYTE $0x30; BYTE $0x31; BYTE $0x32; BYTE $0x33\n\tBYTE $0x34; BYTE $0x35; BYTE $0x36; BYTE $0x37\n\tBYTE $0x38; BYTE $0x39; BYTE $0xb3; BYTE $0xdb\n\tBYTE $0xdc; BYTE $0xd9; BYTE $0xda; BYTE $0x9f\n\nretry:\n\tWORD $0xB9931022 // TROO 2,2,b'0001'\n\tBVS  retry\n\tRET\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/cap_freebsd.go",
    "content": "// Copyright 2017 The Go 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\n//go:build freebsd\n\npackage unix\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// Go implementation of C mostly found in /usr/src/sys/kern/subr_capability.c\n\nconst (\n\t// This is the version of CapRights this package understands. See C implementation for parallels.\n\tcapRightsGoVersion = CAP_RIGHTS_VERSION_00\n\tcapArSizeMin       = CAP_RIGHTS_VERSION_00 + 2\n\tcapArSizeMax       = capRightsGoVersion + 2\n)\n\nvar (\n\tbit2idx = []int{\n\t\t-1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1,\n\t\t4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n\t}\n)\n\nfunc capidxbit(right uint64) int {\n\treturn int((right >> 57) & 0x1f)\n}\n\nfunc rightToIndex(right uint64) (int, error) {\n\tidx := capidxbit(right)\n\tif idx < 0 || idx >= len(bit2idx) {\n\t\treturn -2, fmt.Errorf(\"index for right 0x%x out of range\", right)\n\t}\n\treturn bit2idx[idx], nil\n}\n\nfunc caprver(right uint64) int {\n\treturn int(right >> 62)\n}\n\nfunc capver(rights *CapRights) int {\n\treturn caprver(rights.Rights[0])\n}\n\nfunc caparsize(rights *CapRights) int {\n\treturn capver(rights) + 2\n}\n\n// CapRightsSet sets the permissions in setrights in rights.\nfunc CapRightsSet(rights *CapRights, setrights []uint64) error {\n\t// This is essentially a copy of cap_rights_vset()\n\tif capver(rights) != CAP_RIGHTS_VERSION_00 {\n\t\treturn fmt.Errorf(\"bad rights version %d\", capver(rights))\n\t}\n\n\tn := caparsize(rights)\n\tif n < capArSizeMin || n > capArSizeMax {\n\t\treturn errors.New(\"bad rights size\")\n\t}\n\n\tfor _, right := range setrights {\n\t\tif caprver(right) != CAP_RIGHTS_VERSION_00 {\n\t\t\treturn errors.New(\"bad right version\")\n\t\t}\n\t\ti, err := rightToIndex(right)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif i >= n {\n\t\t\treturn errors.New(\"index overflow\")\n\t\t}\n\t\tif capidxbit(rights.Rights[i]) != capidxbit(right) {\n\t\t\treturn errors.New(\"index mismatch\")\n\t\t}\n\t\trights.Rights[i] |= right\n\t\tif capidxbit(rights.Rights[i]) != capidxbit(right) {\n\t\t\treturn errors.New(\"index mismatch (after assign)\")\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// CapRightsClear clears the permissions in clearrights from rights.\nfunc CapRightsClear(rights *CapRights, clearrights []uint64) error {\n\t// This is essentially a copy of cap_rights_vclear()\n\tif capver(rights) != CAP_RIGHTS_VERSION_00 {\n\t\treturn fmt.Errorf(\"bad rights version %d\", capver(rights))\n\t}\n\n\tn := caparsize(rights)\n\tif n < capArSizeMin || n > capArSizeMax {\n\t\treturn errors.New(\"bad rights size\")\n\t}\n\n\tfor _, right := range clearrights {\n\t\tif caprver(right) != CAP_RIGHTS_VERSION_00 {\n\t\t\treturn errors.New(\"bad right version\")\n\t\t}\n\t\ti, err := rightToIndex(right)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif i >= n {\n\t\t\treturn errors.New(\"index overflow\")\n\t\t}\n\t\tif capidxbit(rights.Rights[i]) != capidxbit(right) {\n\t\t\treturn errors.New(\"index mismatch\")\n\t\t}\n\t\trights.Rights[i] &= ^(right & 0x01FFFFFFFFFFFFFF)\n\t\tif capidxbit(rights.Rights[i]) != capidxbit(right) {\n\t\t\treturn errors.New(\"index mismatch (after assign)\")\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// CapRightsIsSet checks whether all the permissions in setrights are present in rights.\nfunc CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) {\n\t// This is essentially a copy of cap_rights_is_vset()\n\tif capver(rights) != CAP_RIGHTS_VERSION_00 {\n\t\treturn false, fmt.Errorf(\"bad rights version %d\", capver(rights))\n\t}\n\n\tn := caparsize(rights)\n\tif n < capArSizeMin || n > capArSizeMax {\n\t\treturn false, errors.New(\"bad rights size\")\n\t}\n\n\tfor _, right := range setrights {\n\t\tif caprver(right) != CAP_RIGHTS_VERSION_00 {\n\t\t\treturn false, errors.New(\"bad right version\")\n\t\t}\n\t\ti, err := rightToIndex(right)\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\t\tif i >= n {\n\t\t\treturn false, errors.New(\"index overflow\")\n\t\t}\n\t\tif capidxbit(rights.Rights[i]) != capidxbit(right) {\n\t\t\treturn false, errors.New(\"index mismatch\")\n\t\t}\n\t\tif (rights.Rights[i] & right) != right {\n\t\t\treturn false, nil\n\t\t}\n\t}\n\n\treturn true, nil\n}\n\nfunc capright(idx uint64, bit uint64) uint64 {\n\treturn ((1 << (57 + idx)) | bit)\n}\n\n// CapRightsInit returns a pointer to an initialised CapRights structure filled with rights.\n// See man cap_rights_init(3) and rights(4).\nfunc CapRightsInit(rights []uint64) (*CapRights, error) {\n\tvar r CapRights\n\tr.Rights[0] = (capRightsGoVersion << 62) | capright(0, 0)\n\tr.Rights[1] = capright(1, 0)\n\n\terr := CapRightsSet(&r, rights)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &r, nil\n}\n\n// CapRightsLimit reduces the operations permitted on fd to at most those contained in rights.\n// The capability rights on fd can never be increased by CapRightsLimit.\n// See man cap_rights_limit(2) and rights(4).\nfunc CapRightsLimit(fd uintptr, rights *CapRights) error {\n\treturn capRightsLimit(int(fd), rights)\n}\n\n// CapRightsGet returns a CapRights structure containing the operations permitted on fd.\n// See man cap_rights_get(3) and rights(4).\nfunc CapRightsGet(fd uintptr) (*CapRights, error) {\n\tr, err := CapRightsInit(nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\terr = capRightsGet(capRightsGoVersion, int(fd), r)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn r, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/constants.go",
    "content": "// Copyright 2015 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\npackage unix\n\nconst (\n\tR_OK = 0x4\n\tW_OK = 0x2\n\tX_OK = 0x1\n)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/dev_aix_ppc.go",
    "content": "// Copyright 2018 The Go 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\n//go:build aix && ppc\n\n// Functions to access/create device major and minor numbers matching the\n// encoding used by AIX.\n\npackage unix\n\n// Major returns the major component of a Linux device number.\nfunc Major(dev uint64) uint32 {\n\treturn uint32((dev >> 16) & 0xffff)\n}\n\n// Minor returns the minor component of a Linux device number.\nfunc Minor(dev uint64) uint32 {\n\treturn uint32(dev & 0xffff)\n}\n\n// Mkdev returns a Linux device number generated from the given major and minor\n// components.\nfunc Mkdev(major, minor uint32) uint64 {\n\treturn uint64(((major) << 16) | (minor))\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/dev_aix_ppc64.go",
    "content": "// Copyright 2018 The Go 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\n//go:build aix && ppc64\n\n// Functions to access/create device major and minor numbers matching the\n// encoding used AIX.\n\npackage unix\n\n// Major returns the major component of a Linux device number.\nfunc Major(dev uint64) uint32 {\n\treturn uint32((dev & 0x3fffffff00000000) >> 32)\n}\n\n// Minor returns the minor component of a Linux device number.\nfunc Minor(dev uint64) uint32 {\n\treturn uint32((dev & 0x00000000ffffffff) >> 0)\n}\n\n// Mkdev returns a Linux device number generated from the given major and minor\n// components.\nfunc Mkdev(major, minor uint32) uint64 {\n\tvar DEVNO64 uint64\n\tDEVNO64 = 0x8000000000000000\n\treturn ((uint64(major) << 32) | (uint64(minor) & 0x00000000FFFFFFFF) | DEVNO64)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/dev_darwin.go",
    "content": "// Copyright 2017 The Go 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\n// Functions to access/create device major and minor numbers matching the\n// encoding used in Darwin's sys/types.h header.\n\npackage unix\n\n// Major returns the major component of a Darwin device number.\nfunc Major(dev uint64) uint32 {\n\treturn uint32((dev >> 24) & 0xff)\n}\n\n// Minor returns the minor component of a Darwin device number.\nfunc Minor(dev uint64) uint32 {\n\treturn uint32(dev & 0xffffff)\n}\n\n// Mkdev returns a Darwin device number generated from the given major and minor\n// components.\nfunc Mkdev(major, minor uint32) uint64 {\n\treturn (uint64(major) << 24) | uint64(minor)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/dev_dragonfly.go",
    "content": "// Copyright 2017 The Go 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\n// Functions to access/create device major and minor numbers matching the\n// encoding used in Dragonfly's sys/types.h header.\n//\n// The information below is extracted and adapted from sys/types.h:\n//\n// Minor gives a cookie instead of an index since in order to avoid changing the\n// meanings of bits 0-15 or wasting time and space shifting bits 16-31 for\n// devices that don't use them.\n\npackage unix\n\n// Major returns the major component of a DragonFlyBSD device number.\nfunc Major(dev uint64) uint32 {\n\treturn uint32((dev >> 8) & 0xff)\n}\n\n// Minor returns the minor component of a DragonFlyBSD device number.\nfunc Minor(dev uint64) uint32 {\n\treturn uint32(dev & 0xffff00ff)\n}\n\n// Mkdev returns a DragonFlyBSD device number generated from the given major and\n// minor components.\nfunc Mkdev(major, minor uint32) uint64 {\n\treturn (uint64(major) << 8) | uint64(minor)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/dev_freebsd.go",
    "content": "// Copyright 2017 The Go 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\n// Functions to access/create device major and minor numbers matching the\n// encoding used in FreeBSD's sys/types.h header.\n//\n// The information below is extracted and adapted from sys/types.h:\n//\n// Minor gives a cookie instead of an index since in order to avoid changing the\n// meanings of bits 0-15 or wasting time and space shifting bits 16-31 for\n// devices that don't use them.\n\npackage unix\n\n// Major returns the major component of a FreeBSD device number.\nfunc Major(dev uint64) uint32 {\n\treturn uint32((dev >> 8) & 0xff)\n}\n\n// Minor returns the minor component of a FreeBSD device number.\nfunc Minor(dev uint64) uint32 {\n\treturn uint32(dev & 0xffff00ff)\n}\n\n// Mkdev returns a FreeBSD device number generated from the given major and\n// minor components.\nfunc Mkdev(major, minor uint32) uint64 {\n\treturn (uint64(major) << 8) | uint64(minor)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/dev_linux.go",
    "content": "// Copyright 2017 The Go 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\n// Functions to access/create device major and minor numbers matching the\n// encoding used by the Linux kernel and glibc.\n//\n// The information below is extracted and adapted from bits/sysmacros.h in the\n// glibc sources:\n//\n// dev_t in glibc is 64-bit, with 32-bit major and minor numbers. glibc's\n// default encoding is MMMM Mmmm mmmM MMmm, where M is a hex digit of the major\n// number and m is a hex digit of the minor number. This is backward compatible\n// with legacy systems where dev_t is 16 bits wide, encoded as MMmm. It is also\n// backward compatible with the Linux kernel, which for some architectures uses\n// 32-bit dev_t, encoded as mmmM MMmm.\n\npackage unix\n\n// Major returns the major component of a Linux device number.\nfunc Major(dev uint64) uint32 {\n\tmajor := uint32((dev & 0x00000000000fff00) >> 8)\n\tmajor |= uint32((dev & 0xfffff00000000000) >> 32)\n\treturn major\n}\n\n// Minor returns the minor component of a Linux device number.\nfunc Minor(dev uint64) uint32 {\n\tminor := uint32((dev & 0x00000000000000ff) >> 0)\n\tminor |= uint32((dev & 0x00000ffffff00000) >> 12)\n\treturn minor\n}\n\n// Mkdev returns a Linux device number generated from the given major and minor\n// components.\nfunc Mkdev(major, minor uint32) uint64 {\n\tdev := (uint64(major) & 0x00000fff) << 8\n\tdev |= (uint64(major) & 0xfffff000) << 32\n\tdev |= (uint64(minor) & 0x000000ff) << 0\n\tdev |= (uint64(minor) & 0xffffff00) << 12\n\treturn dev\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/dev_netbsd.go",
    "content": "// Copyright 2017 The Go 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\n// Functions to access/create device major and minor numbers matching the\n// encoding used in NetBSD's sys/types.h header.\n\npackage unix\n\n// Major returns the major component of a NetBSD device number.\nfunc Major(dev uint64) uint32 {\n\treturn uint32((dev & 0x000fff00) >> 8)\n}\n\n// Minor returns the minor component of a NetBSD device number.\nfunc Minor(dev uint64) uint32 {\n\tminor := uint32((dev & 0x000000ff) >> 0)\n\tminor |= uint32((dev & 0xfff00000) >> 12)\n\treturn minor\n}\n\n// Mkdev returns a NetBSD device number generated from the given major and minor\n// components.\nfunc Mkdev(major, minor uint32) uint64 {\n\tdev := (uint64(major) << 8) & 0x000fff00\n\tdev |= (uint64(minor) << 12) & 0xfff00000\n\tdev |= (uint64(minor) << 0) & 0x000000ff\n\treturn dev\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/dev_openbsd.go",
    "content": "// Copyright 2017 The Go 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\n// Functions to access/create device major and minor numbers matching the\n// encoding used in OpenBSD's sys/types.h header.\n\npackage unix\n\n// Major returns the major component of an OpenBSD device number.\nfunc Major(dev uint64) uint32 {\n\treturn uint32((dev & 0x0000ff00) >> 8)\n}\n\n// Minor returns the minor component of an OpenBSD device number.\nfunc Minor(dev uint64) uint32 {\n\tminor := uint32((dev & 0x000000ff) >> 0)\n\tminor |= uint32((dev & 0xffff0000) >> 8)\n\treturn minor\n}\n\n// Mkdev returns an OpenBSD device number generated from the given major and minor\n// components.\nfunc Mkdev(major, minor uint32) uint64 {\n\tdev := (uint64(major) << 8) & 0x0000ff00\n\tdev |= (uint64(minor) << 8) & 0xffff0000\n\tdev |= (uint64(minor) << 0) & 0x000000ff\n\treturn dev\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/dev_zos.go",
    "content": "// Copyright 2020 The Go 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\n//go:build zos && s390x\n\n// Functions to access/create device major and minor numbers matching the\n// encoding used by z/OS.\n//\n// The information below is extracted and adapted from <sys/stat.h> macros.\n\npackage unix\n\n// Major returns the major component of a z/OS device number.\nfunc Major(dev uint64) uint32 {\n\treturn uint32((dev >> 16) & 0x0000FFFF)\n}\n\n// Minor returns the minor component of a z/OS device number.\nfunc Minor(dev uint64) uint32 {\n\treturn uint32(dev & 0x0000FFFF)\n}\n\n// Mkdev returns a z/OS device number generated from the given major and minor\n// components.\nfunc Mkdev(major, minor uint32) uint64 {\n\treturn (uint64(major) << 16) | uint64(minor)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/dirent.go",
    "content": "// Copyright 2009 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\npackage unix\n\nimport \"unsafe\"\n\n// readInt returns the size-bytes unsigned integer in native byte order at offset off.\nfunc readInt(b []byte, off, size uintptr) (u uint64, ok bool) {\n\tif len(b) < int(off+size) {\n\t\treturn 0, false\n\t}\n\tif isBigEndian {\n\t\treturn readIntBE(b[off:], size), true\n\t}\n\treturn readIntLE(b[off:], size), true\n}\n\nfunc readIntBE(b []byte, size uintptr) uint64 {\n\tswitch size {\n\tcase 1:\n\t\treturn uint64(b[0])\n\tcase 2:\n\t\t_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808\n\t\treturn uint64(b[1]) | uint64(b[0])<<8\n\tcase 4:\n\t\t_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808\n\t\treturn uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24\n\tcase 8:\n\t\t_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808\n\t\treturn uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |\n\t\t\tuint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56\n\tdefault:\n\t\tpanic(\"syscall: readInt with unsupported size\")\n\t}\n}\n\nfunc readIntLE(b []byte, size uintptr) uint64 {\n\tswitch size {\n\tcase 1:\n\t\treturn uint64(b[0])\n\tcase 2:\n\t\t_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808\n\t\treturn uint64(b[0]) | uint64(b[1])<<8\n\tcase 4:\n\t\t_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808\n\t\treturn uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24\n\tcase 8:\n\t\t_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808\n\t\treturn uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |\n\t\t\tuint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56\n\tdefault:\n\t\tpanic(\"syscall: readInt with unsupported size\")\n\t}\n}\n\n// ParseDirent parses up to max directory entries in buf,\n// appending the names to names. It returns the number of\n// bytes consumed from buf, the number of entries added\n// to names, and the new names slice.\nfunc ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {\n\toriglen := len(buf)\n\tcount = 0\n\tfor max != 0 && len(buf) > 0 {\n\t\treclen, ok := direntReclen(buf)\n\t\tif !ok || reclen > uint64(len(buf)) {\n\t\t\treturn origlen, count, names\n\t\t}\n\t\trec := buf[:reclen]\n\t\tbuf = buf[reclen:]\n\t\tino, ok := direntIno(rec)\n\t\tif !ok {\n\t\t\tbreak\n\t\t}\n\t\tif ino == 0 { // File absent in directory.\n\t\t\tcontinue\n\t\t}\n\t\tconst namoff = uint64(unsafe.Offsetof(Dirent{}.Name))\n\t\tnamlen, ok := direntNamlen(rec)\n\t\tif !ok || namoff+namlen > uint64(len(rec)) {\n\t\t\tbreak\n\t\t}\n\t\tname := rec[namoff : namoff+namlen]\n\t\tfor i, c := range name {\n\t\t\tif c == 0 {\n\t\t\t\tname = name[:i]\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\t// Check for useless names before allocating a string.\n\t\tif string(name) == \".\" || string(name) == \"..\" {\n\t\t\tcontinue\n\t\t}\n\t\tmax--\n\t\tcount++\n\t\tnames = append(names, string(name))\n\t}\n\treturn origlen - len(buf), count, names\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/endian_big.go",
    "content": "// Copyright 2016 The Go 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//\n//go:build armbe || arm64be || m68k || mips || mips64 || mips64p32 || ppc || ppc64 || s390 || s390x || shbe || sparc || sparc64\n\npackage unix\n\nconst isBigEndian = true\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/endian_little.go",
    "content": "// Copyright 2016 The Go 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//\n//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh\n\npackage unix\n\nconst isBigEndian = false\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/env_unix.go",
    "content": "// Copyright 2010 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\n// Unix environment variables.\n\npackage unix\n\nimport \"syscall\"\n\nfunc Getenv(key string) (value string, found bool) {\n\treturn syscall.Getenv(key)\n}\n\nfunc Setenv(key, value string) error {\n\treturn syscall.Setenv(key, value)\n}\n\nfunc Clearenv() {\n\tsyscall.Clearenv()\n}\n\nfunc Environ() []string {\n\treturn syscall.Environ()\n}\n\nfunc Unsetenv(key string) error {\n\treturn syscall.Unsetenv(key)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/fcntl.go",
    "content": "// Copyright 2014 The Go 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\n//go:build dragonfly || freebsd || linux || netbsd\n\npackage unix\n\nimport \"unsafe\"\n\n// fcntl64Syscall is usually SYS_FCNTL, but is overridden on 32-bit Linux\n// systems by fcntl_linux_32bit.go to be SYS_FCNTL64.\nvar fcntl64Syscall uintptr = SYS_FCNTL\n\nfunc fcntl(fd int, cmd, arg int) (int, error) {\n\tvalptr, _, errno := Syscall(fcntl64Syscall, uintptr(fd), uintptr(cmd), uintptr(arg))\n\tvar err error\n\tif errno != 0 {\n\t\terr = errno\n\t}\n\treturn int(valptr), err\n}\n\n// FcntlInt performs a fcntl syscall on fd with the provided command and argument.\nfunc FcntlInt(fd uintptr, cmd, arg int) (int, error) {\n\treturn fcntl(int(fd), cmd, arg)\n}\n\n// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.\nfunc FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {\n\t_, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk)))\n\tif errno == 0 {\n\t\treturn nil\n\t}\n\treturn errno\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/fcntl_darwin.go",
    "content": "// Copyright 2019 The Go 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 unix\n\nimport \"unsafe\"\n\n// FcntlInt performs a fcntl syscall on fd with the provided command and argument.\nfunc FcntlInt(fd uintptr, cmd, arg int) (int, error) {\n\treturn fcntl(int(fd), cmd, arg)\n}\n\n// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.\nfunc FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {\n\t_, err := fcntl(int(fd), cmd, int(uintptr(unsafe.Pointer(lk))))\n\treturn err\n}\n\n// FcntlFstore performs a fcntl syscall for the F_PREALLOCATE command.\nfunc FcntlFstore(fd uintptr, cmd int, fstore *Fstore_t) error {\n\t_, err := fcntl(int(fd), cmd, int(uintptr(unsafe.Pointer(fstore))))\n\treturn err\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/fcntl_linux_32bit.go",
    "content": "// Copyright 2014 The Go 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\n//go:build (linux && 386) || (linux && arm) || (linux && mips) || (linux && mipsle) || (linux && ppc)\n\npackage unix\n\nfunc init() {\n\t// On 32-bit Linux systems, the fcntl syscall that matches Go's\n\t// Flock_t type is SYS_FCNTL64, not SYS_FCNTL.\n\tfcntl64Syscall = SYS_FCNTL64\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/fdset.go",
    "content": "// Copyright 2019 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\npackage unix\n\n// Set adds fd to the set fds.\nfunc (fds *FdSet) Set(fd int) {\n\tfds.Bits[fd/NFDBITS] |= (1 << (uintptr(fd) % NFDBITS))\n}\n\n// Clear removes fd from the set fds.\nfunc (fds *FdSet) Clear(fd int) {\n\tfds.Bits[fd/NFDBITS] &^= (1 << (uintptr(fd) % NFDBITS))\n}\n\n// IsSet returns whether fd is in the set fds.\nfunc (fds *FdSet) IsSet(fd int) bool {\n\treturn fds.Bits[fd/NFDBITS]&(1<<(uintptr(fd)%NFDBITS)) != 0\n}\n\n// Zero clears the set fds.\nfunc (fds *FdSet) Zero() {\n\tclear(fds.Bits[:])\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/gccgo.go",
    "content": "// Copyright 2015 The Go 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\n//go:build gccgo && !aix && !hurd\n\npackage unix\n\nimport \"syscall\"\n\n// We can't use the gc-syntax .s files for gccgo. On the plus side\n// much of the functionality can be written directly in Go.\n\nfunc realSyscallNoError(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r uintptr)\n\nfunc realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r, errno uintptr)\n\nfunc SyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) {\n\tsyscall.Entersyscall()\n\tr := realSyscallNoError(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)\n\tsyscall.Exitsyscall()\n\treturn r, 0\n}\n\nfunc Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {\n\tsyscall.Entersyscall()\n\tr, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)\n\tsyscall.Exitsyscall()\n\treturn r, 0, syscall.Errno(errno)\n}\n\nfunc Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) {\n\tsyscall.Entersyscall()\n\tr, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)\n\tsyscall.Exitsyscall()\n\treturn r, 0, syscall.Errno(errno)\n}\n\nfunc Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) {\n\tsyscall.Entersyscall()\n\tr, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9)\n\tsyscall.Exitsyscall()\n\treturn r, 0, syscall.Errno(errno)\n}\n\nfunc RawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) {\n\tr := realSyscallNoError(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)\n\treturn r, 0\n}\n\nfunc RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {\n\tr, errno := realSyscall(trap, a1, a2, a3, 0, 0, 0, 0, 0, 0)\n\treturn r, 0, syscall.Errno(errno)\n}\n\nfunc RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) {\n\tr, errno := realSyscall(trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)\n\treturn r, 0, syscall.Errno(errno)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/gccgo_c.c",
    "content": "// Copyright 2015 The Go 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\n//go:build gccgo && !aix && !hurd\n\n#include <errno.h>\n#include <stdint.h>\n#include <unistd.h>\n\n#define _STRINGIFY2_(x) #x\n#define _STRINGIFY_(x) _STRINGIFY2_(x)\n#define GOSYM_PREFIX _STRINGIFY_(__USER_LABEL_PREFIX__)\n\n// Call syscall from C code because the gccgo support for calling from\n// Go to C does not support varargs functions.\n\nstruct ret {\n\tuintptr_t r;\n\tuintptr_t err;\n};\n\nstruct ret gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9)\n  __asm__(GOSYM_PREFIX GOPKGPATH \".realSyscall\");\n\nstruct ret\ngccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9)\n{\n\tstruct ret r;\n\n\terrno = 0;\n\tr.r = syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9);\n\tr.err = errno;\n\treturn r;\n}\n\nuintptr_t gccgoRealSyscallNoError(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9)\n  __asm__(GOSYM_PREFIX GOPKGPATH \".realSyscallNoError\");\n\nuintptr_t\ngccgoRealSyscallNoError(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9)\n{\n\treturn syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9);\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/gccgo_linux_amd64.go",
    "content": "// Copyright 2015 The Go 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\n//go:build gccgo && linux && amd64\n\npackage unix\n\nimport \"syscall\"\n\n//extern gettimeofday\nfunc realGettimeofday(*Timeval, *byte) int32\n\nfunc gettimeofday(tv *Timeval) (err syscall.Errno) {\n\tr := realGettimeofday(tv, nil)\n\tif r < 0 {\n\t\treturn syscall.GetErrno()\n\t}\n\treturn 0\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/ifreq_linux.go",
    "content": "// Copyright 2021 The Go 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\n//go:build linux\n\npackage unix\n\nimport (\n\t\"unsafe\"\n)\n\n// Helpers for dealing with ifreq since it contains a union and thus requires a\n// lot of unsafe.Pointer casts to use properly.\n\n// An Ifreq is a type-safe wrapper around the raw ifreq struct. An Ifreq\n// contains an interface name and a union of arbitrary data which can be\n// accessed using the Ifreq's methods. To create an Ifreq, use the NewIfreq\n// function.\n//\n// Use the Name method to access the stored interface name. The union data\n// fields can be get and set using the following methods:\n//   - Uint16/SetUint16: flags\n//   - Uint32/SetUint32: ifindex, metric, mtu\ntype Ifreq struct{ raw ifreq }\n\n// NewIfreq creates an Ifreq with the input network interface name after\n// validating the name does not exceed IFNAMSIZ-1 (trailing NULL required)\n// bytes.\nfunc NewIfreq(name string) (*Ifreq, error) {\n\t// Leave room for terminating NULL byte.\n\tif len(name) >= IFNAMSIZ {\n\t\treturn nil, EINVAL\n\t}\n\n\tvar ifr ifreq\n\tcopy(ifr.Ifrn[:], name)\n\n\treturn &Ifreq{raw: ifr}, nil\n}\n\n// TODO(mdlayher): get/set methods for hardware address sockaddr, char array, etc.\n\n// Name returns the interface name associated with the Ifreq.\nfunc (ifr *Ifreq) Name() string {\n\treturn ByteSliceToString(ifr.raw.Ifrn[:])\n}\n\n// According to netdevice(7), only AF_INET addresses are returned for numerous\n// sockaddr ioctls. For convenience, we expose these as Inet4Addr since the Port\n// field and other data is always empty.\n\n// Inet4Addr returns the Ifreq union data from an embedded sockaddr as a C\n// in_addr/Go []byte (4-byte IPv4 address) value. If the sockaddr family is not\n// AF_INET, an error is returned.\nfunc (ifr *Ifreq) Inet4Addr() ([]byte, error) {\n\traw := *(*RawSockaddrInet4)(unsafe.Pointer(&ifr.raw.Ifru[:SizeofSockaddrInet4][0]))\n\tif raw.Family != AF_INET {\n\t\t// Cannot safely interpret raw.Addr bytes as an IPv4 address.\n\t\treturn nil, EINVAL\n\t}\n\n\treturn raw.Addr[:], nil\n}\n\n// SetInet4Addr sets a C in_addr/Go []byte (4-byte IPv4 address) value in an\n// embedded sockaddr within the Ifreq's union data. v must be 4 bytes in length\n// or an error will be returned.\nfunc (ifr *Ifreq) SetInet4Addr(v []byte) error {\n\tif len(v) != 4 {\n\t\treturn EINVAL\n\t}\n\n\tvar addr [4]byte\n\tcopy(addr[:], v)\n\n\tifr.clear()\n\t*(*RawSockaddrInet4)(\n\t\tunsafe.Pointer(&ifr.raw.Ifru[:SizeofSockaddrInet4][0]),\n\t) = RawSockaddrInet4{\n\t\t// Always set IP family as ioctls would require it anyway.\n\t\tFamily: AF_INET,\n\t\tAddr:   addr,\n\t}\n\n\treturn nil\n}\n\n// Uint16 returns the Ifreq union data as a C short/Go uint16 value.\nfunc (ifr *Ifreq) Uint16() uint16 {\n\treturn *(*uint16)(unsafe.Pointer(&ifr.raw.Ifru[:2][0]))\n}\n\n// SetUint16 sets a C short/Go uint16 value as the Ifreq's union data.\nfunc (ifr *Ifreq) SetUint16(v uint16) {\n\tifr.clear()\n\t*(*uint16)(unsafe.Pointer(&ifr.raw.Ifru[:2][0])) = v\n}\n\n// Uint32 returns the Ifreq union data as a C int/Go uint32 value.\nfunc (ifr *Ifreq) Uint32() uint32 {\n\treturn *(*uint32)(unsafe.Pointer(&ifr.raw.Ifru[:4][0]))\n}\n\n// SetUint32 sets a C int/Go uint32 value as the Ifreq's union data.\nfunc (ifr *Ifreq) SetUint32(v uint32) {\n\tifr.clear()\n\t*(*uint32)(unsafe.Pointer(&ifr.raw.Ifru[:4][0])) = v\n}\n\n// clear zeroes the ifreq's union field to prevent trailing garbage data from\n// being sent to the kernel if an ifreq is reused.\nfunc (ifr *Ifreq) clear() {\n\tclear(ifr.raw.Ifru[:])\n}\n\n// TODO(mdlayher): export as IfreqData? For now we can provide helpers such as\n// IoctlGetEthtoolDrvinfo which use these APIs under the hood.\n\n// An ifreqData is an Ifreq which carries pointer data. To produce an ifreqData,\n// use the Ifreq.withData method.\ntype ifreqData struct {\n\tname [IFNAMSIZ]byte\n\t// A type separate from ifreq is required in order to comply with the\n\t// unsafe.Pointer rules since the \"pointer-ness\" of data would not be\n\t// preserved if it were cast into the byte array of a raw ifreq.\n\tdata unsafe.Pointer\n\t// Pad to the same size as ifreq.\n\t_ [len(ifreq{}.Ifru) - SizeofPtr]byte\n}\n\n// withData produces an ifreqData with the pointer p set for ioctls which require\n// arbitrary pointer data.\nfunc (ifr Ifreq) withData(p unsafe.Pointer) ifreqData {\n\treturn ifreqData{\n\t\tname: ifr.raw.Ifrn,\n\t\tdata: p,\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/ioctl_linux.go",
    "content": "// Copyright 2021 The Go 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 unix\n\nimport \"unsafe\"\n\n// IoctlRetInt performs an ioctl operation specified by req on a device\n// associated with opened file descriptor fd, and returns a non-negative\n// integer that is returned by the ioctl syscall.\nfunc IoctlRetInt(fd int, req uint) (int, error) {\n\tret, _, err := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), 0)\n\tif err != 0 {\n\t\treturn 0, err\n\t}\n\treturn int(ret), nil\n}\n\nfunc IoctlGetUint32(fd int, req uint) (uint32, error) {\n\tvar value uint32\n\terr := ioctlPtr(fd, req, unsafe.Pointer(&value))\n\treturn value, err\n}\n\nfunc IoctlGetRTCTime(fd int) (*RTCTime, error) {\n\tvar value RTCTime\n\terr := ioctlPtr(fd, RTC_RD_TIME, unsafe.Pointer(&value))\n\treturn &value, err\n}\n\nfunc IoctlSetRTCTime(fd int, value *RTCTime) error {\n\treturn ioctlPtr(fd, RTC_SET_TIME, unsafe.Pointer(value))\n}\n\nfunc IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) {\n\tvar value RTCWkAlrm\n\terr := ioctlPtr(fd, RTC_WKALM_RD, unsafe.Pointer(&value))\n\treturn &value, err\n}\n\nfunc IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error {\n\treturn ioctlPtr(fd, RTC_WKALM_SET, unsafe.Pointer(value))\n}\n\n// IoctlGetEthtoolDrvinfo fetches ethtool driver information for the network\n// device specified by ifname.\nfunc IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) {\n\tifr, err := NewIfreq(ifname)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvalue := EthtoolDrvinfo{Cmd: ETHTOOL_GDRVINFO}\n\tifrd := ifr.withData(unsafe.Pointer(&value))\n\n\terr = ioctlIfreqData(fd, SIOCETHTOOL, &ifrd)\n\treturn &value, err\n}\n\n// IoctlGetEthtoolTsInfo fetches ethtool timestamping and PHC\n// association for the network device specified by ifname.\nfunc IoctlGetEthtoolTsInfo(fd int, ifname string) (*EthtoolTsInfo, error) {\n\tifr, err := NewIfreq(ifname)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvalue := EthtoolTsInfo{Cmd: ETHTOOL_GET_TS_INFO}\n\tifrd := ifr.withData(unsafe.Pointer(&value))\n\n\terr = ioctlIfreqData(fd, SIOCETHTOOL, &ifrd)\n\treturn &value, err\n}\n\n// IoctlGetHwTstamp retrieves the hardware timestamping configuration\n// for the network device specified by ifname.\nfunc IoctlGetHwTstamp(fd int, ifname string) (*HwTstampConfig, error) {\n\tifr, err := NewIfreq(ifname)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvalue := HwTstampConfig{}\n\tifrd := ifr.withData(unsafe.Pointer(&value))\n\n\terr = ioctlIfreqData(fd, SIOCGHWTSTAMP, &ifrd)\n\treturn &value, err\n}\n\n// IoctlSetHwTstamp updates the hardware timestamping configuration for\n// the network device specified by ifname.\nfunc IoctlSetHwTstamp(fd int, ifname string, cfg *HwTstampConfig) error {\n\tifr, err := NewIfreq(ifname)\n\tif err != nil {\n\t\treturn err\n\t}\n\tifrd := ifr.withData(unsafe.Pointer(cfg))\n\treturn ioctlIfreqData(fd, SIOCSHWTSTAMP, &ifrd)\n}\n\n// FdToClockID derives the clock ID from the file descriptor number\n// - see clock_gettime(3), FD_TO_CLOCKID macros. The resulting ID is\n// suitable for system calls like ClockGettime.\nfunc FdToClockID(fd int) int32 { return int32((int(^fd) << 3) | 3) }\n\n// IoctlPtpClockGetcaps returns the description of a given PTP device.\nfunc IoctlPtpClockGetcaps(fd int) (*PtpClockCaps, error) {\n\tvar value PtpClockCaps\n\terr := ioctlPtr(fd, PTP_CLOCK_GETCAPS2, unsafe.Pointer(&value))\n\treturn &value, err\n}\n\n// IoctlPtpSysOffsetPrecise returns a description of the clock\n// offset compared to the system clock.\nfunc IoctlPtpSysOffsetPrecise(fd int) (*PtpSysOffsetPrecise, error) {\n\tvar value PtpSysOffsetPrecise\n\terr := ioctlPtr(fd, PTP_SYS_OFFSET_PRECISE2, unsafe.Pointer(&value))\n\treturn &value, err\n}\n\n// IoctlPtpSysOffsetExtended returns an extended description of the\n// clock offset compared to the system clock. The samples parameter\n// specifies the desired number of measurements.\nfunc IoctlPtpSysOffsetExtended(fd int, samples uint) (*PtpSysOffsetExtended, error) {\n\tvalue := PtpSysOffsetExtended{Samples: uint32(samples)}\n\terr := ioctlPtr(fd, PTP_SYS_OFFSET_EXTENDED2, unsafe.Pointer(&value))\n\treturn &value, err\n}\n\n// IoctlPtpPinGetfunc returns the configuration of the specified\n// I/O pin on given PTP device.\nfunc IoctlPtpPinGetfunc(fd int, index uint) (*PtpPinDesc, error) {\n\tvalue := PtpPinDesc{Index: uint32(index)}\n\terr := ioctlPtr(fd, PTP_PIN_GETFUNC2, unsafe.Pointer(&value))\n\treturn &value, err\n}\n\n// IoctlPtpPinSetfunc updates configuration of the specified PTP\n// I/O pin.\nfunc IoctlPtpPinSetfunc(fd int, pd *PtpPinDesc) error {\n\treturn ioctlPtr(fd, PTP_PIN_SETFUNC2, unsafe.Pointer(pd))\n}\n\n// IoctlPtpPeroutRequest configures the periodic output mode of the\n// PTP I/O pins.\nfunc IoctlPtpPeroutRequest(fd int, r *PtpPeroutRequest) error {\n\treturn ioctlPtr(fd, PTP_PEROUT_REQUEST2, unsafe.Pointer(r))\n}\n\n// IoctlPtpExttsRequest configures the external timestamping mode\n// of the PTP I/O pins.\nfunc IoctlPtpExttsRequest(fd int, r *PtpExttsRequest) error {\n\treturn ioctlPtr(fd, PTP_EXTTS_REQUEST2, unsafe.Pointer(r))\n}\n\n// IoctlGetWatchdogInfo fetches information about a watchdog device from the\n// Linux watchdog API. For more information, see:\n// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.\nfunc IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) {\n\tvar value WatchdogInfo\n\terr := ioctlPtr(fd, WDIOC_GETSUPPORT, unsafe.Pointer(&value))\n\treturn &value, err\n}\n\n// IoctlWatchdogKeepalive issues a keepalive ioctl to a watchdog device. For\n// more information, see:\n// https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.\nfunc IoctlWatchdogKeepalive(fd int) error {\n\t// arg is ignored and not a pointer, so ioctl is fine instead of ioctlPtr.\n\treturn ioctl(fd, WDIOC_KEEPALIVE, 0)\n}\n\n// IoctlFileCloneRange performs an FICLONERANGE ioctl operation to clone the\n// range of data conveyed in value to the file associated with the file\n// descriptor destFd. See the ioctl_ficlonerange(2) man page for details.\nfunc IoctlFileCloneRange(destFd int, value *FileCloneRange) error {\n\treturn ioctlPtr(destFd, FICLONERANGE, unsafe.Pointer(value))\n}\n\n// IoctlFileClone performs an FICLONE ioctl operation to clone the entire file\n// associated with the file description srcFd to the file associated with the\n// file descriptor destFd. See the ioctl_ficlone(2) man page for details.\nfunc IoctlFileClone(destFd, srcFd int) error {\n\treturn ioctl(destFd, FICLONE, uintptr(srcFd))\n}\n\ntype FileDedupeRange struct {\n\tSrc_offset uint64\n\tSrc_length uint64\n\tReserved1  uint16\n\tReserved2  uint32\n\tInfo       []FileDedupeRangeInfo\n}\n\ntype FileDedupeRangeInfo struct {\n\tDest_fd       int64\n\tDest_offset   uint64\n\tBytes_deduped uint64\n\tStatus        int32\n\tReserved      uint32\n}\n\n// IoctlFileDedupeRange performs an FIDEDUPERANGE ioctl operation to share the\n// range of data conveyed in value from the file associated with the file\n// descriptor srcFd to the value.Info destinations. See the\n// ioctl_fideduperange(2) man page for details.\nfunc IoctlFileDedupeRange(srcFd int, value *FileDedupeRange) error {\n\tbuf := make([]byte, SizeofRawFileDedupeRange+\n\t\tlen(value.Info)*SizeofRawFileDedupeRangeInfo)\n\trawrange := (*RawFileDedupeRange)(unsafe.Pointer(&buf[0]))\n\trawrange.Src_offset = value.Src_offset\n\trawrange.Src_length = value.Src_length\n\trawrange.Dest_count = uint16(len(value.Info))\n\trawrange.Reserved1 = value.Reserved1\n\trawrange.Reserved2 = value.Reserved2\n\n\tfor i := range value.Info {\n\t\trawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer(\n\t\t\tuintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) +\n\t\t\t\tuintptr(i*SizeofRawFileDedupeRangeInfo)))\n\t\trawinfo.Dest_fd = value.Info[i].Dest_fd\n\t\trawinfo.Dest_offset = value.Info[i].Dest_offset\n\t\trawinfo.Bytes_deduped = value.Info[i].Bytes_deduped\n\t\trawinfo.Status = value.Info[i].Status\n\t\trawinfo.Reserved = value.Info[i].Reserved\n\t}\n\n\terr := ioctlPtr(srcFd, FIDEDUPERANGE, unsafe.Pointer(&buf[0]))\n\n\t// Output\n\tfor i := range value.Info {\n\t\trawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer(\n\t\t\tuintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) +\n\t\t\t\tuintptr(i*SizeofRawFileDedupeRangeInfo)))\n\t\tvalue.Info[i].Dest_fd = rawinfo.Dest_fd\n\t\tvalue.Info[i].Dest_offset = rawinfo.Dest_offset\n\t\tvalue.Info[i].Bytes_deduped = rawinfo.Bytes_deduped\n\t\tvalue.Info[i].Status = rawinfo.Status\n\t\tvalue.Info[i].Reserved = rawinfo.Reserved\n\t}\n\n\treturn err\n}\n\nfunc IoctlHIDGetDesc(fd int, value *HIDRawReportDescriptor) error {\n\treturn ioctlPtr(fd, HIDIOCGRDESC, unsafe.Pointer(value))\n}\n\nfunc IoctlHIDGetRawInfo(fd int) (*HIDRawDevInfo, error) {\n\tvar value HIDRawDevInfo\n\terr := ioctlPtr(fd, HIDIOCGRAWINFO, unsafe.Pointer(&value))\n\treturn &value, err\n}\n\nfunc IoctlHIDGetRawName(fd int) (string, error) {\n\tvar value [_HIDIOCGRAWNAME_LEN]byte\n\terr := ioctlPtr(fd, _HIDIOCGRAWNAME, unsafe.Pointer(&value[0]))\n\treturn ByteSliceToString(value[:]), err\n}\n\nfunc IoctlHIDGetRawPhys(fd int) (string, error) {\n\tvar value [_HIDIOCGRAWPHYS_LEN]byte\n\terr := ioctlPtr(fd, _HIDIOCGRAWPHYS, unsafe.Pointer(&value[0]))\n\treturn ByteSliceToString(value[:]), err\n}\n\nfunc IoctlHIDGetRawUniq(fd int) (string, error) {\n\tvar value [_HIDIOCGRAWUNIQ_LEN]byte\n\terr := ioctlPtr(fd, _HIDIOCGRAWUNIQ, unsafe.Pointer(&value[0]))\n\treturn ByteSliceToString(value[:]), err\n}\n\n// IoctlIfreq performs an ioctl using an Ifreq structure for input and/or\n// output. See the netdevice(7) man page for details.\nfunc IoctlIfreq(fd int, req uint, value *Ifreq) error {\n\t// It is possible we will add more fields to *Ifreq itself later to prevent\n\t// misuse, so pass the raw *ifreq directly.\n\treturn ioctlPtr(fd, req, unsafe.Pointer(&value.raw))\n}\n\n// TODO(mdlayher): export if and when IfreqData is exported.\n\n// ioctlIfreqData performs an ioctl using an ifreqData structure for input\n// and/or output. See the netdevice(7) man page for details.\nfunc ioctlIfreqData(fd int, req uint, value *ifreqData) error {\n\t// The memory layout of IfreqData (type-safe) and ifreq (not type-safe) are\n\t// identical so pass *IfreqData directly.\n\treturn ioctlPtr(fd, req, unsafe.Pointer(value))\n}\n\n// IoctlKCMClone attaches a new file descriptor to a multiplexor by cloning an\n// existing KCM socket, returning a structure containing the file descriptor of\n// the new socket.\nfunc IoctlKCMClone(fd int) (*KCMClone, error) {\n\tvar info KCMClone\n\tif err := ioctlPtr(fd, SIOCKCMCLONE, unsafe.Pointer(&info)); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &info, nil\n}\n\n// IoctlKCMAttach attaches a TCP socket and associated BPF program file\n// descriptor to a multiplexor.\nfunc IoctlKCMAttach(fd int, info KCMAttach) error {\n\treturn ioctlPtr(fd, SIOCKCMATTACH, unsafe.Pointer(&info))\n}\n\n// IoctlKCMUnattach unattaches a TCP socket file descriptor from a multiplexor.\nfunc IoctlKCMUnattach(fd int, info KCMUnattach) error {\n\treturn ioctlPtr(fd, SIOCKCMUNATTACH, unsafe.Pointer(&info))\n}\n\n// IoctlLoopGetStatus64 gets the status of the loop device associated with the\n// file descriptor fd using the LOOP_GET_STATUS64 operation.\nfunc IoctlLoopGetStatus64(fd int) (*LoopInfo64, error) {\n\tvar value LoopInfo64\n\tif err := ioctlPtr(fd, LOOP_GET_STATUS64, unsafe.Pointer(&value)); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &value, nil\n}\n\n// IoctlLoopSetStatus64 sets the status of the loop device associated with the\n// file descriptor fd using the LOOP_SET_STATUS64 operation.\nfunc IoctlLoopSetStatus64(fd int, value *LoopInfo64) error {\n\treturn ioctlPtr(fd, LOOP_SET_STATUS64, unsafe.Pointer(value))\n}\n\n// IoctlLoopConfigure configures all loop device parameters in a single step\nfunc IoctlLoopConfigure(fd int, value *LoopConfig) error {\n\treturn ioctlPtr(fd, LOOP_CONFIGURE, unsafe.Pointer(value))\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/ioctl_signed.go",
    "content": "// Copyright 2018 The Go 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\n//go:build aix || solaris\n\npackage unix\n\nimport (\n\t\"unsafe\"\n)\n\n// ioctl itself should not be exposed directly, but additional get/set\n// functions for specific types are permissible.\n\n// IoctlSetInt performs an ioctl operation which sets an integer value\n// on fd, using the specified request number.\nfunc IoctlSetInt(fd int, req int, value int) error {\n\treturn ioctl(fd, req, uintptr(value))\n}\n\n// IoctlSetPointerInt performs an ioctl operation which sets an\n// integer value on fd, using the specified request number. The ioctl\n// argument is called with a pointer to the integer value, rather than\n// passing the integer value directly.\nfunc IoctlSetPointerInt(fd int, req int, value int) error {\n\tv := int32(value)\n\treturn ioctlPtr(fd, req, unsafe.Pointer(&v))\n}\n\n// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.\n//\n// To change fd's window size, the req argument should be TIOCSWINSZ.\nfunc IoctlSetWinsize(fd int, req int, value *Winsize) error {\n\t// TODO: if we get the chance, remove the req parameter and\n\t// hardcode TIOCSWINSZ.\n\treturn ioctlPtr(fd, req, unsafe.Pointer(value))\n}\n\n// IoctlSetTermios performs an ioctl on fd with a *Termios.\n//\n// The req value will usually be TCSETA or TIOCSETA.\nfunc IoctlSetTermios(fd int, req int, value *Termios) error {\n\t// TODO: if we get the chance, remove the req parameter.\n\treturn ioctlPtr(fd, req, unsafe.Pointer(value))\n}\n\n// IoctlGetInt performs an ioctl operation which gets an integer value\n// from fd, using the specified request number.\n//\n// A few ioctl requests use the return value as an output parameter;\n// for those, IoctlRetInt should be used instead of this function.\nfunc IoctlGetInt(fd int, req int) (int, error) {\n\tvar value int\n\terr := ioctlPtr(fd, req, unsafe.Pointer(&value))\n\treturn value, err\n}\n\nfunc IoctlGetWinsize(fd int, req int) (*Winsize, error) {\n\tvar value Winsize\n\terr := ioctlPtr(fd, req, unsafe.Pointer(&value))\n\treturn &value, err\n}\n\nfunc IoctlGetTermios(fd int, req int) (*Termios, error) {\n\tvar value Termios\n\terr := ioctlPtr(fd, req, unsafe.Pointer(&value))\n\treturn &value, err\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/ioctl_unsigned.go",
    "content": "// Copyright 2018 The Go 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\n//go:build darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd\n\npackage unix\n\nimport (\n\t\"unsafe\"\n)\n\n// ioctl itself should not be exposed directly, but additional get/set\n// functions for specific types are permissible.\n\n// IoctlSetInt performs an ioctl operation which sets an integer value\n// on fd, using the specified request number.\nfunc IoctlSetInt(fd int, req uint, value int) error {\n\treturn ioctl(fd, req, uintptr(value))\n}\n\n// IoctlSetPointerInt performs an ioctl operation which sets an\n// integer value on fd, using the specified request number. The ioctl\n// argument is called with a pointer to the integer value, rather than\n// passing the integer value directly.\nfunc IoctlSetPointerInt(fd int, req uint, value int) error {\n\tv := int32(value)\n\treturn ioctlPtr(fd, req, unsafe.Pointer(&v))\n}\n\n// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.\n//\n// To change fd's window size, the req argument should be TIOCSWINSZ.\nfunc IoctlSetWinsize(fd int, req uint, value *Winsize) error {\n\t// TODO: if we get the chance, remove the req parameter and\n\t// hardcode TIOCSWINSZ.\n\treturn ioctlPtr(fd, req, unsafe.Pointer(value))\n}\n\n// IoctlSetTermios performs an ioctl on fd with a *Termios.\n//\n// The req value will usually be TCSETA or TIOCSETA.\nfunc IoctlSetTermios(fd int, req uint, value *Termios) error {\n\t// TODO: if we get the chance, remove the req parameter.\n\treturn ioctlPtr(fd, req, unsafe.Pointer(value))\n}\n\n// IoctlGetInt performs an ioctl operation which gets an integer value\n// from fd, using the specified request number.\n//\n// A few ioctl requests use the return value as an output parameter;\n// for those, IoctlRetInt should be used instead of this function.\nfunc IoctlGetInt(fd int, req uint) (int, error) {\n\tvar value int\n\terr := ioctlPtr(fd, req, unsafe.Pointer(&value))\n\treturn value, err\n}\n\nfunc IoctlGetWinsize(fd int, req uint) (*Winsize, error) {\n\tvar value Winsize\n\terr := ioctlPtr(fd, req, unsafe.Pointer(&value))\n\treturn &value, err\n}\n\nfunc IoctlGetTermios(fd int, req uint) (*Termios, error) {\n\tvar value Termios\n\terr := ioctlPtr(fd, req, unsafe.Pointer(&value))\n\treturn &value, err\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/ioctl_zos.go",
    "content": "// Copyright 2020 The Go 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\n//go:build zos && s390x\n\npackage unix\n\nimport (\n\t\"runtime\"\n\t\"unsafe\"\n)\n\n// ioctl itself should not be exposed directly, but additional get/set\n// functions for specific types are permissible.\n\n// IoctlSetInt performs an ioctl operation which sets an integer value\n// on fd, using the specified request number.\nfunc IoctlSetInt(fd int, req int, value int) error {\n\treturn ioctl(fd, req, uintptr(value))\n}\n\n// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.\n//\n// To change fd's window size, the req argument should be TIOCSWINSZ.\nfunc IoctlSetWinsize(fd int, req int, value *Winsize) error {\n\t// TODO: if we get the chance, remove the req parameter and\n\t// hardcode TIOCSWINSZ.\n\treturn ioctlPtr(fd, req, unsafe.Pointer(value))\n}\n\n// IoctlSetTermios performs an ioctl on fd with a *Termios.\n//\n// The req value is expected to be TCSETS, TCSETSW, or TCSETSF\nfunc IoctlSetTermios(fd int, req int, value *Termios) error {\n\tif (req != TCSETS) && (req != TCSETSW) && (req != TCSETSF) {\n\t\treturn ENOSYS\n\t}\n\terr := Tcsetattr(fd, int(req), value)\n\truntime.KeepAlive(value)\n\treturn err\n}\n\n// IoctlGetInt performs an ioctl operation which gets an integer value\n// from fd, using the specified request number.\n//\n// A few ioctl requests use the return value as an output parameter;\n// for those, IoctlRetInt should be used instead of this function.\nfunc IoctlGetInt(fd int, req int) (int, error) {\n\tvar value int\n\terr := ioctlPtr(fd, req, unsafe.Pointer(&value))\n\treturn value, err\n}\n\nfunc IoctlGetWinsize(fd int, req int) (*Winsize, error) {\n\tvar value Winsize\n\terr := ioctlPtr(fd, req, unsafe.Pointer(&value))\n\treturn &value, err\n}\n\n// IoctlGetTermios performs an ioctl on fd with a *Termios.\n//\n// The req value is expected to be TCGETS\nfunc IoctlGetTermios(fd int, req int) (*Termios, error) {\n\tvar value Termios\n\tif req != TCGETS {\n\t\treturn &value, ENOSYS\n\t}\n\terr := Tcgetattr(fd, &value)\n\treturn &value, err\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/mkall.sh",
    "content": "#!/usr/bin/env bash\n# Copyright 2009 The Go 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\n# This script runs or (given -n) prints suggested commands to generate files for\n# the Architecture/OS specified by the GOARCH and GOOS environment variables.\n# See README.md for more information about how the build system works.\n\nGOOSARCH=\"${GOOS}_${GOARCH}\"\n\n# defaults\nmksyscall=\"go run mksyscall.go\"\nmkerrors=\"./mkerrors.sh\"\nzerrors=\"zerrors_$GOOSARCH.go\"\nmksysctl=\"\"\nzsysctl=\"zsysctl_$GOOSARCH.go\"\nmksysnum=\nmktypes=\nmkasm=\nrun=\"sh\"\ncmd=\"\"\n\ncase \"$1\" in\n-syscalls)\n\tfor i in zsyscall*go\n\tdo\n\t\t# Run the command line that appears in the first line\n\t\t# of the generated file to regenerate it.\n\t\tsed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i\n\t\trm _$i\n\tdone\n\texit 0\n\t;;\n-n)\n\trun=\"cat\"\n\tcmd=\"echo\"\n\tshift\nesac\n\ncase \"$#\" in\n0)\n\t;;\n*)\n\techo 'usage: mkall.sh [-n]' 1>&2\n\texit 2\nesac\n\nif [[ \"$GOOS\" = \"linux\" ]]; then\n\t# Use the Docker-based build system\n\t# Files generated through docker (use $cmd so you can Ctl-C the build or run)\n\tset -e\n\t$cmd docker build --tag generate:$GOOS $GOOS\n\t$cmd docker run --interactive --tty --volume $(cd -- \"$(dirname -- \"$0\")/..\" && pwd):/build generate:$GOOS\n\texit\nfi\n\nGOOSARCH_in=syscall_$GOOSARCH.go\ncase \"$GOOSARCH\" in\n_* | *_ | _)\n\techo 'undefined $GOOS_$GOARCH:' \"$GOOSARCH\" 1>&2\n\texit 1\n\t;;\naix_ppc)\n\tmkerrors=\"$mkerrors -maix32\"\n\tmksyscall=\"go run mksyscall_aix_ppc.go -aix\"\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs\"\n\t;;\naix_ppc64)\n\tmkerrors=\"$mkerrors -maix64\"\n\tmksyscall=\"go run mksyscall_aix_ppc64.go -aix\"\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs\"\n\t;;\ndarwin_amd64)\n\tmkerrors=\"$mkerrors -m64\"\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs\"\n\tmkasm=\"go run mkasm.go\"\n\t;;\ndarwin_arm64)\n\tmkerrors=\"$mkerrors -m64\"\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs\"\n\tmkasm=\"go run mkasm.go\"\n\t;;\ndragonfly_amd64)\n\tmkerrors=\"$mkerrors -m64\"\n\tmksyscall=\"go run mksyscall.go -dragonfly\"\n\tmksysnum=\"go run mksysnum.go 'https://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master'\"\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs\"\n\t;;\nfreebsd_386)\n\tmkerrors=\"$mkerrors -m32\"\n\tmksyscall=\"go run mksyscall.go -l32\"\n\tmksysnum=\"go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'\"\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs\"\n\t;;\nfreebsd_amd64)\n\tmkerrors=\"$mkerrors -m64\"\n\tmksysnum=\"go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'\"\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs\"\n\t;;\nfreebsd_arm)\n\tmkerrors=\"$mkerrors\"\n\tmksyscall=\"go run mksyscall.go -l32 -arm\"\n\tmksysnum=\"go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'\"\n\t# Let the type of C char be signed for making the bare syscall\n\t# API consistent across platforms.\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char\"\n\t;;\nfreebsd_arm64)\n\tmkerrors=\"$mkerrors -m64\"\n\tmksysnum=\"go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'\"\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char\"\n\t;;\nfreebsd_riscv64)\n\tmkerrors=\"$mkerrors -m64\"\n\tmksysnum=\"go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'\"\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char\"\n\t;;\nnetbsd_386)\n\tmkerrors=\"$mkerrors -m32\"\n\tmksyscall=\"go run mksyscall.go -l32 -netbsd\"\n\tmksysnum=\"go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'\"\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs\"\n\t;;\nnetbsd_amd64)\n\tmkerrors=\"$mkerrors -m64\"\n\tmksyscall=\"go run mksyscall.go -netbsd\"\n\tmksysnum=\"go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'\"\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs\"\n\t;;\nnetbsd_arm)\n\tmkerrors=\"$mkerrors\"\n\tmksyscall=\"go run mksyscall.go -l32 -netbsd -arm\"\n\tmksysnum=\"go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'\"\n\t# Let the type of C char be signed for making the bare syscall\n\t# API consistent across platforms.\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char\"\n\t;;\nnetbsd_arm64)\n\tmkerrors=\"$mkerrors -m64\"\n\tmksyscall=\"go run mksyscall.go -netbsd\"\n\tmksysnum=\"go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'\"\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs\"\n\t;;\nopenbsd_386)\n\tmkasm=\"go run mkasm.go\"\n\tmkerrors=\"$mkerrors -m32\"\n\tmksyscall=\"go run mksyscall.go -l32 -openbsd -libc\"\n\tmksysctl=\"go run mksysctl_openbsd.go\"\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs\"\n\t;;\nopenbsd_amd64)\n\tmkasm=\"go run mkasm.go\"\n\tmkerrors=\"$mkerrors -m64\"\n\tmksyscall=\"go run mksyscall.go -openbsd -libc\"\n\tmksysctl=\"go run mksysctl_openbsd.go\"\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs\"\n\t;;\nopenbsd_arm)\n\tmkasm=\"go run mkasm.go\"\n\tmkerrors=\"$mkerrors\"\n\tmksyscall=\"go run mksyscall.go -l32 -openbsd -arm -libc\"\n\tmksysctl=\"go run mksysctl_openbsd.go\"\n\t# Let the type of C char be signed for making the bare syscall\n\t# API consistent across platforms.\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char\"\n\t;;\nopenbsd_arm64)\n\tmkasm=\"go run mkasm.go\"\n\tmkerrors=\"$mkerrors -m64\"\n\tmksyscall=\"go run mksyscall.go -openbsd -libc\"\n\tmksysctl=\"go run mksysctl_openbsd.go\"\n\t# Let the type of C char be signed for making the bare syscall\n\t# API consistent across platforms.\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char\"\n\t;;\nopenbsd_mips64)\n\tmkasm=\"go run mkasm.go\"\n\tmkerrors=\"$mkerrors -m64\"\n\tmksyscall=\"go run mksyscall.go -openbsd -libc\"\n\tmksysctl=\"go run mksysctl_openbsd.go\"\n\t# Let the type of C char be signed for making the bare syscall\n\t# API consistent across platforms.\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char\"\n\t;;\nopenbsd_ppc64)\n\tmkasm=\"go run mkasm.go\"\n\tmkerrors=\"$mkerrors -m64\"\n\tmksyscall=\"go run mksyscall.go -openbsd -libc\"\n\tmksysctl=\"go run mksysctl_openbsd.go\"\n\t# Let the type of C char be signed for making the bare syscall\n\t# API consistent across platforms.\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char\"\n\t;;\nopenbsd_riscv64)\n\tmkasm=\"go run mkasm.go\"\n\tmkerrors=\"$mkerrors -m64\"\n\tmksyscall=\"go run mksyscall.go -openbsd -libc\"\n\tmksysctl=\"go run mksysctl_openbsd.go\"\n\t# Let the type of C char be signed for making the bare syscall\n\t# API consistent across platforms.\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char\"\n\t;;\nsolaris_amd64)\n\tmksyscall=\"go run mksyscall_solaris.go\"\n\tmkerrors=\"$mkerrors -m64\"\n\tmksysnum=\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs\"\n\t;;\nillumos_amd64)\n        mksyscall=\"go run mksyscall_solaris.go\"\n\tmkerrors=\n\tmksysnum=\n\tmktypes=\"GOARCH=$GOARCH go tool cgo -godefs\"\n\t;;\n*)\n\techo 'unrecognized $GOOS_$GOARCH: ' \"$GOOSARCH\" 1>&2\n\texit 1\n\t;;\nesac\n\n(\n\tif [ -n \"$mkerrors\" ]; then echo \"$mkerrors |gofmt >$zerrors\"; fi\n\tcase \"$GOOS\" in\n\t*)\n\t\tsyscall_goos=\"syscall_$GOOS.go\"\n\t\tcase \"$GOOS\" in\n\t\tdarwin | dragonfly | freebsd | netbsd | openbsd)\n\t\t\tsyscall_goos=\"syscall_bsd.go $syscall_goos\"\n\t\t\t;;\n\t\tesac\n\t\tif [ -n \"$mksyscall\" ]; then\n\t\t\tif [ \"$GOOSARCH\" == \"aix_ppc64\" ]; then\n\t\t\t\t# aix/ppc64 script generates files instead of writing to stdin.\n\t\t\t\techo \"$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_\"$GOOSARCH\"_gccgo.go && gofmt -w zsyscall_\"$GOOSARCH\"_gc.go \" ;\n\t\t\telif [ \"$GOOS\" == \"illumos\" ]; then\n\t\t\t        # illumos code generation requires a --illumos switch\n\t\t\t        echo \"$mksyscall -illumos -tags illumos,$GOARCH syscall_illumos.go |gofmt > zsyscall_illumos_$GOARCH.go\";\n\t\t\t        # illumos implies solaris, so solaris code generation is also required\n\t\t\t\techo \"$mksyscall -tags solaris,$GOARCH syscall_solaris.go syscall_solaris_$GOARCH.go |gofmt >zsyscall_solaris_$GOARCH.go\";\n\t\t\telse\n\t\t\t\techo \"$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go\";\n\t\t\tfi\n\t\tfi\n\tesac\n\tif [ -n \"$mksysctl\" ]; then echo \"$mksysctl |gofmt >$zsysctl\"; fi\n\tif [ -n \"$mksysnum\" ]; then echo \"$mksysnum |gofmt >zsysnum_$GOOSARCH.go\"; fi\n\tif [ -n \"$mktypes\" ]; then echo \"$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go\"; fi\n\tif [ -n \"$mkasm\" ]; then echo \"$mkasm $GOOS $GOARCH\"; fi\n) | $run\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/mkerrors.sh",
    "content": "#!/usr/bin/env bash\n# Copyright 2009 The Go 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\n# Generate Go code listing errors and other #defined constant\n# values (ENAMETOOLONG etc.), by asking the preprocessor\n# about the definitions.\n\nunset LANG\nexport LC_ALL=C\nexport LC_CTYPE=C\n\nif test -z \"$GOARCH\" -o -z \"$GOOS\"; then\n\techo 1>&2 \"GOARCH or GOOS not defined in environment\"\n\texit 1\nfi\n\n# Check that we are using the new build system if we should\nif [[ \"$GOOS\" = \"linux\" ]] && [[ \"$GOLANG_SYS_BUILD\" != \"docker\" ]]; then\n\techo 1>&2 \"In the Docker based build system, mkerrors should not be called directly.\"\n\techo 1>&2 \"See README.md\"\n\texit 1\nfi\n\nif [[ \"$GOOS\" = \"aix\" ]]; then\n\tCC=${CC:-gcc}\nelse\n\tCC=${CC:-cc}\nfi\n\nif [[ \"$GOOS\" = \"solaris\" ]]; then\n\t# Assumes GNU versions of utilities in PATH.\n\texport PATH=/usr/gnu/bin:$PATH\nfi\n\nuname=$(uname)\n\nincludes_AIX='\n#include <net/if.h>\n#include <net/netopt.h>\n#include <netinet/ip_mroute.h>\n#include <sys/protosw.h>\n#include <sys/stropts.h>\n#include <sys/mman.h>\n#include <sys/poll.h>\n#include <sys/select.h>\n#include <sys/termio.h>\n#include <termios.h>\n#include <fcntl.h>\n\n#define AF_LOCAL AF_UNIX\n'\n\nincludes_Darwin='\n#define _DARWIN_C_SOURCE\n#define KERNEL 1\n#define _DARWIN_USE_64_BIT_INODE\n#define __APPLE_USE_RFC_3542\n#include <stdint.h>\n#include <sys/stdio.h>\n#include <sys/attr.h>\n#include <sys/clonefile.h>\n#include <sys/kern_control.h>\n#include <sys/types.h>\n#include <sys/event.h>\n#include <sys/ptrace.h>\n#include <sys/select.h>\n#include <sys/socket.h>\n#include <sys/stat.h>\n#include <sys/un.h>\n#include <sys/sockio.h>\n#include <sys/sys_domain.h>\n#include <sys/sysctl.h>\n#include <sys/mman.h>\n#include <sys/mount.h>\n#include <sys/utsname.h>\n#include <sys/wait.h>\n#include <sys/xattr.h>\n#include <sys/vsock.h>\n#include <net/bpf.h>\n#include <net/if.h>\n#include <net/if_types.h>\n#include <net/route.h>\n#include <netinet/in.h>\n#include <netinet/ip.h>\n#include <termios.h>\n\n// for backwards compatibility because moved TIOCREMOTE to Kernel.framework after MacOSX12.0.sdk.\n#define TIOCREMOTE 0x80047469\n'\n\nincludes_DragonFly='\n#include <sys/types.h>\n#include <sys/event.h>\n#include <sys/select.h>\n#include <sys/socket.h>\n#include <sys/sockio.h>\n#include <sys/stat.h>\n#include <sys/sysctl.h>\n#include <sys/mman.h>\n#include <sys/mount.h>\n#include <sys/wait.h>\n#include <sys/ioctl.h>\n#include <net/bpf.h>\n#include <net/if.h>\n#include <net/if_clone.h>\n#include <net/if_types.h>\n#include <net/route.h>\n#include <netinet/in.h>\n#include <termios.h>\n#include <netinet/ip.h>\n#include <net/ip_mroute/ip_mroute.h>\n'\n\nincludes_FreeBSD='\n#include <sys/capsicum.h>\n#include <sys/param.h>\n#include <sys/types.h>\n#include <sys/disk.h>\n#include <sys/event.h>\n#include <sys/sched.h>\n#include <sys/select.h>\n#include <sys/socket.h>\n#include <sys/un.h>\n#include <sys/sockio.h>\n#include <sys/stat.h>\n#include <sys/sysctl.h>\n#include <sys/mman.h>\n#include <sys/mount.h>\n#include <sys/wait.h>\n#include <sys/ioctl.h>\n#include <sys/ptrace.h>\n#include <net/bpf.h>\n#include <net/if.h>\n#include <net/if_types.h>\n#include <net/route.h>\n#include <netinet/in.h>\n#include <termios.h>\n#include <netinet/ip.h>\n#include <netinet/ip_mroute.h>\n#include <sys/extattr.h>\n\n#if __FreeBSD__ >= 10\n#define IFT_CARP\t0xf8\t// IFT_CARP is deprecated in FreeBSD 10\n#undef SIOCAIFADDR\n#define SIOCAIFADDR\t_IOW(105, 26, struct oifaliasreq)\t// ifaliasreq contains if_data\n#undef SIOCSIFPHYADDR\n#define SIOCSIFPHYADDR\t_IOW(105, 70, struct oifaliasreq)\t// ifaliasreq contains if_data\n#endif\n'\n\nincludes_Linux='\n#define _LARGEFILE_SOURCE\n#define _LARGEFILE64_SOURCE\n#ifndef __LP64__\n#define _FILE_OFFSET_BITS 64\n#endif\n#define _GNU_SOURCE\n\n// See the description in unix/linux/types.go\n#if defined(__ARM_EABI__) || \\\n\t(defined(__mips__) && (_MIPS_SIM == _ABIO32)) || \\\n\t(defined(__powerpc__) && (!defined(__powerpc64__)))\n# ifdef   _TIME_BITS\n#  undef  _TIME_BITS\n# endif\n# define  _TIME_BITS 32\n#endif\n\n// <sys/ioctl.h> is broken on powerpc64, as it fails to include definitions of\n// these structures. We just include them copied from <bits/termios.h>.\n#if defined(__powerpc__)\nstruct sgttyb {\n        char    sg_ispeed;\n        char    sg_ospeed;\n        char    sg_erase;\n        char    sg_kill;\n        short   sg_flags;\n};\n\nstruct tchars {\n        char    t_intrc;\n        char    t_quitc;\n        char    t_startc;\n        char    t_stopc;\n        char    t_eofc;\n        char    t_brkc;\n};\n\nstruct ltchars {\n        char    t_suspc;\n        char    t_dsuspc;\n        char    t_rprntc;\n        char    t_flushc;\n        char    t_werasc;\n        char    t_lnextc;\n};\n#endif\n\n#include <bits/sockaddr.h>\n#include <sys/epoll.h>\n#include <sys/eventfd.h>\n#include <sys/inotify.h>\n#include <sys/ioctl.h>\n#include <sys/mman.h>\n#include <sys/mount.h>\n#include <sys/prctl.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <sys/time.h>\n#include <sys/select.h>\n#include <sys/signalfd.h>\n#include <sys/socket.h>\n#include <sys/timerfd.h>\n#include <sys/uio.h>\n#include <sys/xattr.h>\n#include <netinet/udp.h>\n#include <linux/audit.h>\n#include <linux/bpf.h>\n#include <linux/can.h>\n#include <linux/can/error.h>\n#include <linux/can/netlink.h>\n#include <linux/can/raw.h>\n#include <linux/capability.h>\n#include <linux/cryptouser.h>\n#include <linux/devlink.h>\n#include <linux/dm-ioctl.h>\n#include <linux/elf.h>\n#include <linux/errqueue.h>\n#include <linux/ethtool_netlink.h>\n#include <linux/falloc.h>\n#include <linux/fanotify.h>\n#include <linux/fib_rules.h>\n#include <linux/filter.h>\n#include <linux/fs.h>\n#include <linux/fscrypt.h>\n#include <linux/fsverity.h>\n#include <linux/genetlink.h>\n#include <linux/hdreg.h>\n#include <linux/hidraw.h>\n#include <linux/if.h>\n#include <linux/if_addr.h>\n#include <linux/if_alg.h>\n#include <linux/if_arp.h>\n#include <linux/if_ether.h>\n#include <linux/if_ppp.h>\n#include <linux/if_tun.h>\n#include <linux/if_packet.h>\n#include <linux/if_xdp.h>\n#include <linux/input.h>\n#include <linux/kcm.h>\n#include <linux/kexec.h>\n#include <linux/keyctl.h>\n#include <linux/landlock.h>\n#include <linux/loop.h>\n#include <linux/lwtunnel.h>\n#include <linux/magic.h>\n#include <linux/mei.h>\n#include <linux/memfd.h>\n#include <linux/module.h>\n#include <linux/mount.h>\n#include <linux/netfilter/nfnetlink.h>\n#include <linux/netfilter/nf_tables.h>\n#include <linux/netlink.h>\n#include <linux/net_namespace.h>\n#include <linux/nfc.h>\n#include <linux/nsfs.h>\n#include <linux/perf_event.h>\n#include <linux/pps.h>\n#include <linux/ptp_clock.h>\n#include <linux/ptrace.h>\n#include <linux/random.h>\n#include <linux/reboot.h>\n#include <linux/rtc.h>\n#include <linux/rtnetlink.h>\n#include <linux/sched.h>\n#include <linux/seccomp.h>\n#include <linux/serial.h>\n#include <linux/sock_diag.h>\n#include <linux/sockios.h>\n#include <linux/taskstats.h>\n#include <linux/tipc.h>\n#include <linux/vm_sockets.h>\n#include <linux/wait.h>\n#include <linux/watchdog.h>\n#include <linux/wireguard.h>\n\n#include <mtd/ubi-user.h>\n#include <mtd/mtd-user.h>\n#include <net/route.h>\n\n#if defined(__sparc__)\n// On sparc{,64}, the kernel defines struct termios2 itself which clashes with the\n// definition in glibc. As only the error constants are needed here, include the\n// generic termibits.h (which is included by termbits.h on sparc).\n#include <asm-generic/termbits.h>\n#else\n#include <asm/termbits.h>\n#endif\n\n#ifndef PTRACE_GETREGS\n#define PTRACE_GETREGS\t0xc\n#endif\n\n#ifndef PTRACE_SETREGS\n#define PTRACE_SETREGS\t0xd\n#endif\n\n#ifdef SOL_BLUETOOTH\n// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h\n// but it is already in bluetooth_linux.go\n#undef SOL_BLUETOOTH\n#endif\n\n// Certain constants are missing from the fs/crypto UAPI\n#define FS_KEY_DESC_PREFIX              \"fscrypt:\"\n#define FS_KEY_DESC_PREFIX_SIZE         8\n#define FS_MAX_KEY_SIZE                 64\n\n// The code generator produces -0x1 for (~0), but an unsigned value is necessary\n// for the tipc_subscr timeout __u32 field.\n#undef TIPC_WAIT_FOREVER\n#define TIPC_WAIT_FOREVER 0xffffffff\n\n// Copied from linux/netfilter/nf_nat.h\n// Including linux/netfilter/nf_nat.h here causes conflicts between linux/in.h\n// and netinet/in.h.\n#define NF_NAT_RANGE_MAP_IPS\t\t\t(1 << 0)\n#define NF_NAT_RANGE_PROTO_SPECIFIED\t\t(1 << 1)\n#define NF_NAT_RANGE_PROTO_RANDOM\t\t(1 << 2)\n#define NF_NAT_RANGE_PERSISTENT\t\t\t(1 << 3)\n#define NF_NAT_RANGE_PROTO_RANDOM_FULLY\t\t(1 << 4)\n#define NF_NAT_RANGE_PROTO_OFFSET\t\t(1 << 5)\n#define NF_NAT_RANGE_NETMAP\t\t\t(1 << 6)\n#define NF_NAT_RANGE_PROTO_RANDOM_ALL\t\t\\\n\t(NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY)\n#define NF_NAT_RANGE_MASK\t\t\t\t\t\\\n\t(NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED |\t\\\n\t NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PERSISTENT |\t\\\n\t NF_NAT_RANGE_PROTO_RANDOM_FULLY | NF_NAT_RANGE_PROTO_OFFSET | \\\n\t NF_NAT_RANGE_NETMAP)\n\n// Copied from linux/hid.h.\n// Keep in sync with the size of the referenced fields.\n#define _HIDIOCGRAWNAME_LEN\t128 // sizeof_field(struct hid_device, name)\n#define _HIDIOCGRAWPHYS_LEN\t64  // sizeof_field(struct hid_device, phys)\n#define _HIDIOCGRAWUNIQ_LEN\t64  // sizeof_field(struct hid_device, uniq)\n\n#define _HIDIOCGRAWNAME\t\tHIDIOCGRAWNAME(_HIDIOCGRAWNAME_LEN)\n#define _HIDIOCGRAWPHYS\t\tHIDIOCGRAWPHYS(_HIDIOCGRAWPHYS_LEN)\n#define _HIDIOCGRAWUNIQ\t\tHIDIOCGRAWUNIQ(_HIDIOCGRAWUNIQ_LEN)\n\n// Renamed in v6.16, commit c6d732c38f93 (\"net: ethtool: remove duplicate defines for family info\")\n#define ETHTOOL_FAMILY_NAME\tETHTOOL_GENL_NAME\n#define ETHTOOL_FAMILY_VERSION\tETHTOOL_GENL_VERSION\n'\n\nincludes_NetBSD='\n#include <sys/types.h>\n#include <sys/param.h>\n#include <sys/event.h>\n#include <sys/extattr.h>\n#include <sys/mman.h>\n#include <sys/mount.h>\n#include <sys/sched.h>\n#include <sys/select.h>\n#include <sys/socket.h>\n#include <sys/sockio.h>\n#include <sys/sysctl.h>\n#include <sys/termios.h>\n#include <sys/ttycom.h>\n#include <sys/wait.h>\n#include <net/bpf.h>\n#include <net/if.h>\n#include <net/if_types.h>\n#include <net/route.h>\n#include <netinet/in.h>\n#include <netinet/in_systm.h>\n#include <netinet/ip.h>\n#include <netinet/ip_mroute.h>\n#include <netinet/if_ether.h>\n\n// Needed since <sys/param.h> refers to it...\n#define schedppq 1\n'\n\nincludes_OpenBSD='\n#include <sys/types.h>\n#include <sys/param.h>\n#include <sys/event.h>\n#include <sys/mman.h>\n#include <sys/mount.h>\n#include <sys/select.h>\n#include <sys/sched.h>\n#include <sys/socket.h>\n#include <sys/sockio.h>\n#include <sys/stat.h>\n#include <sys/sysctl.h>\n#include <sys/termios.h>\n#include <sys/ttycom.h>\n#include <sys/unistd.h>\n#include <sys/wait.h>\n#include <net/bpf.h>\n#include <net/if.h>\n#include <net/if_types.h>\n#include <net/if_var.h>\n#include <net/route.h>\n#include <netinet/in.h>\n#include <netinet/in_systm.h>\n#include <netinet/ip.h>\n#include <netinet/ip_mroute.h>\n#include <netinet/if_ether.h>\n#include <net/if_bridge.h>\n\n// We keep some constants not supported in OpenBSD 5.5 and beyond for\n// the promise of compatibility.\n#define EMUL_ENABLED\t\t0x1\n#define EMUL_NATIVE\t\t0x2\n#define IPV6_FAITH\t\t0x1d\n#define IPV6_OPTIONS\t\t0x1\n#define IPV6_RTHDR_STRICT\t0x1\n#define IPV6_SOCKOPT_RESERVED1\t0x3\n#define SIOCGIFGENERIC\t\t0xc020693a\n#define SIOCSIFGENERIC\t\t0x80206939\n#define WALTSIG\t\t\t0x4\n'\n\nincludes_SunOS='\n#include <limits.h>\n#include <sys/types.h>\n#include <sys/select.h>\n#include <sys/socket.h>\n#include <sys/sockio.h>\n#include <sys/stat.h>\n#include <sys/stream.h>\n#include <sys/mman.h>\n#include <sys/wait.h>\n#include <sys/ioctl.h>\n#include <sys/mkdev.h>\n#include <net/bpf.h>\n#include <net/if.h>\n#include <net/if_arp.h>\n#include <net/if_types.h>\n#include <net/route.h>\n#include <netinet/icmp6.h>\n#include <netinet/in.h>\n#include <netinet/ip.h>\n#include <netinet/ip_mroute.h>\n#include <termios.h>\n'\n\n\nincludes='\n#include <sys/types.h>\n#include <sys/file.h>\n#include <fcntl.h>\n#include <dirent.h>\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <netinet/ip.h>\n#include <netinet/ip6.h>\n#include <netinet/tcp.h>\n#include <errno.h>\n#include <sys/signal.h>\n#include <signal.h>\n#include <sys/resource.h>\n#include <time.h>\n'\nccflags=\"$@\"\n\n# Write go tool cgo -godefs input.\n(\n\techo package unix\n\techo\n\techo '/*'\n\tindirect=\"includes_$(uname)\"\n\techo \"${!indirect} $includes\"\n\techo '*/'\n\techo 'import \"C\"'\n\techo 'import \"syscall\"'\n\techo\n\techo 'const ('\n\n\t# The gcc command line prints all the #defines\n\t# it encounters while processing the input\n\techo \"${!indirect} $includes\" | $CC -x c - -E -dM $ccflags |\n\tawk '\n\t\t$1 != \"#define\" || $2 ~ /\\(/ || $3 == \"\" {next}\n\n\t\t$2 ~ /^E([ABCD]X|[BIS]P|[SD]I|S|FL)$/ {next}  # 386 registers\n\t\t$2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next}\n\t\t$2 ~ /^(SCM_SRCRT)$/ {next}\n\t\t$2 ~ /^(MAP_FAILED)$/ {next}\n\t\t$2 ~ /^ELF_.*$/ {next}# <asm/elf.h> contains ELF_ARCH, etc.\n\n\t\t$2 ~ /^EXTATTR_NAMESPACE_NAMES/ ||\n\t\t$2 ~ /^EXTATTR_NAMESPACE_[A-Z]+_STRING/ {next}\n\n\t\t$2 !~ /^ECCAPBITS/ &&\n\t\t$2 !~ /^ETH_/ &&\n\t\t$2 !~ /^EPROC_/ &&\n\t\t$2 !~ /^EQUIV_/ &&\n\t\t$2 !~ /^EXPR_/ &&\n\t\t$2 !~ /^EVIOC/ &&\n\t\t$2 ~ /^E[A-Z0-9_]+$/ ||\n\t\t$2 ~ /^B[0-9_]+$/ ||\n\t\t$2 ~ /^(OLD|NEW)DEV$/ ||\n\t\t$2 == \"BOTHER\" ||\n\t\t$2 ~ /^CI?BAUD(EX)?$/ ||\n\t\t$2 == \"IBSHIFT\" ||\n\t\t$2 ~ /^V[A-Z0-9]+$/ ||\n\t\t$2 ~ /^CS[A-Z0-9]/ ||\n\t\t$2 ~ /^I(SIG|CANON|CRNL|UCLC|EXTEN|MAXBEL|STRIP|UTF8)$/ ||\n\t\t$2 ~ /^IGN/ ||\n\t\t$2 ~ /^IX(ON|ANY|OFF)$/ ||\n\t\t$2 ~ /^IN(LCR|PCK)$/ ||\n\t\t$2 !~ \"X86_CR3_PCID_NOFLUSH\" &&\n\t\t$2 ~ /(^FLU?SH)|(FLU?SH$)/ ||\n\t\t$2 ~ /^C(LOCAL|READ|MSPAR|RTSCTS)$/ ||\n\t\t$2 == \"BRKINT\" ||\n\t\t$2 == \"HUPCL\" ||\n\t\t$2 == \"PENDIN\" ||\n\t\t$2 == \"TOSTOP\" ||\n\t\t$2 == \"XCASE\" ||\n\t\t$2 == \"ALTWERASE\" ||\n\t\t$2 == \"NOKERNINFO\" ||\n\t\t$2 == \"NFDBITS\" ||\n\t\t$2 ~ /^PAR/ ||\n\t\t$2 ~ /^SIG[^_]/ ||\n\t\t$2 ~ /^O[CNPFPL][A-Z]+[^_][A-Z]+$/ ||\n\t\t$2 ~ /^(NL|CR|TAB|BS|VT|FF)DLY$/ ||\n\t\t$2 ~ /^(NL|CR|TAB|BS|VT|FF)[0-9]$/ ||\n\t\t$2 ~ /^(DT|EI|ELF|EV|NN|NT|PF|SHF|SHN|SHT|STB|STT|VER)_/ ||\n\t\t$2 ~ /^O?XTABS$/ ||\n\t\t$2 ~ /^TC[IO](ON|OFF)$/ ||\n\t\t$2 ~ /^IN_/ ||\n\t\t$2 ~ /^KCM/ ||\n\t\t$2 ~ /^LANDLOCK_/ ||\n\t\t$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||\n\t\t$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||\n\t\t$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||\n\t\t$2 == \"LOOP_CONFIGURE\" ||\n\t\t$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MREMAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ ||\n\t\t$2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ ||\n\t\t$2 ~ /^NFC_.*_(MAX)?SIZE$/ ||\n\t\t$2 ~ /^PTP_/ ||\n\t\t$2 ~ /^RAW_PAYLOAD_/ ||\n\t\t$2 ~ /^[US]F_/ ||\n\t\t$2 ~ /^TP_STATUS_/ ||\n\t\t$2 ~ /^FALLOC_/ ||\n\t\t$2 ~ /^ICMPV?6?_(FILTER|SEC)/ ||\n\t\t$2 == \"SOMAXCONN\" ||\n\t\t$2 == \"NAME_MAX\" ||\n\t\t$2 == \"IFNAMSIZ\" ||\n\t\t$2 ~ /^CTL_(HW|KERN|MAXNAME|NET|QUERY)$/ ||\n\t\t$2 ~ /^KERN_(HOSTNAME|OS(RELEASE|TYPE)|VERSION)$/ ||\n\t\t$2 ~ /^HW_MACHINE$/ ||\n\t\t$2 ~ /^SYSCTL_VERS/ ||\n\t\t$2 !~ \"MNT_BITS\" &&\n\t\t$2 ~ /^(MS|MNT|MOUNT|UMOUNT)_/ ||\n\t\t$2 ~ /^NS_GET_/ ||\n\t\t$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||\n\t\t$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|PIOD|TFD)_/ ||\n\t\t$2 ~ /^KEXEC_/ ||\n\t\t$2 ~ /^LINUX_REBOOT_CMD_/ ||\n\t\t$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||\n\t\t$2 ~ /^MODULE_INIT_/ ||\n\t\t$2 !~ \"NLA_TYPE_MASK\" &&\n\t\t$2 !~ /^RTC_VL_(ACCURACY|BACKUP|DATA)/ &&\n\t\t$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ ||\n\t\t$2 ~ /^SOCK_|SK_DIAG_|SKNLGRP_$/ ||\n\t\t$2 ~ /^(CONNECT|SAE)_/ ||\n\t\t$2 ~ /^FIORDCHK$/ ||\n\t\t$2 ~ /^SIOC/ ||\n\t\t$2 ~ /^TIOC/ ||\n\t\t$2 ~ /^TCGET/ ||\n\t\t$2 ~ /^TCSET/ ||\n\t\t$2 ~ /^TC(FLSH|SBRKP?|XONC)$/ ||\n\t\t$2 !~ \"RTF_BITS\" &&\n\t\t$2 ~ /^(IFF|IFT|NET_RT|RTM(GRP)?|RTF|RTV|RTA|RTAX)_/ ||\n\t\t$2 ~ /^BIOC/ ||\n\t\t$2 ~ /^DIOC/ ||\n\t\t$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||\n\t\t$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|LOCKS|MEMLOCK|MSGQUEUE|NICE|NOFILE|NPROC|RSS|RTPRIO|RTTIME|SIGPENDING|STACK)|RLIM_INFINITY/ ||\n\t\t$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||\n\t\t$2 ~ /^CLONE_[A-Z_]+/ ||\n\t\t$2 !~ /^(BPF_TIMEVAL|BPF_FIB_LOOKUP_[A-Z]+|BPF_F_LINK)$/ &&\n\t\t$2 ~ /^(BPF|DLT)_/ ||\n\t\t$2 ~ /^AUDIT_/ ||\n\t\t$2 ~ /^(CLOCK|TIMER)_/ ||\n\t\t$2 ~ /^CAN_/ ||\n\t\t$2 ~ /^CAP_/ ||\n\t\t$2 ~ /^CP_/ ||\n\t\t$2 ~ /^CPUSTATES$/ ||\n\t\t$2 ~ /^CTLIOCGINFO$/ ||\n\t\t$2 ~ /^ALG_/ ||\n\t\t$2 ~ /^FI(CLONE|DEDUPERANGE)/ ||\n\t\t$2 ~ /^FS_(POLICY_FLAGS|KEY_DESC|ENCRYPTION_MODE|[A-Z0-9_]+_KEY_SIZE)/ ||\n\t\t$2 ~ /^FS_IOC_.*(ENCRYPTION|VERITY|[GS]ETFLAGS)/ ||\n\t\t$2 ~ /^FS_VERITY_/ ||\n\t\t$2 ~ /^FSCRYPT_/ ||\n\t\t$2 ~ /^DM_/ ||\n\t\t$2 ~ /^GRND_/ ||\n\t\t$2 ~ /^RND/ ||\n\t\t$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ ||\n\t\t$2 ~ /^KEYCTL_/ ||\n\t\t$2 ~ /^PERF_/ ||\n\t\t$2 ~ /^SECCOMP_/ ||\n\t\t$2 ~ /^SEEK_/ ||\n\t\t$2 ~ /^SCHED_/ ||\n\t\t$2 ~ /^SPLICE_/ ||\n\t\t$2 ~ /^SYNC_FILE_RANGE_/ ||\n\t\t$2 !~ /IOC_MAGIC/ &&\n\t\t$2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ ||\n\t\t$2 ~ /^(VM|VMADDR)_/ ||\n\t\t$2 ~ /^(IOCTL_VM_SOCKETS_|IOCTL_MEI_)/ ||\n\t\t$2 ~ /^(TASKSTATS|TS)_/ ||\n\t\t$2 ~ /^CGROUPSTATS_/ ||\n\t\t$2 ~ /^GENL_/ ||\n\t\t$2 ~ /^STATX_/ ||\n\t\t$2 ~ /^RENAME/ ||\n\t\t$2 ~ /^UBI_IOC[A-Z]/ ||\n\t\t$2 ~ /^UTIME_/ ||\n\t\t$2 ~ /^XATTR_(CREATE|REPLACE|NO(DEFAULT|FOLLOW|SECURITY)|SHOWCOMPRESSION)/ ||\n\t\t$2 ~ /^ATTR_(BIT_MAP_COUNT|(CMN|VOL|FILE)_)/ ||\n\t\t$2 ~ /^FSOPT_/ ||\n\t\t$2 ~ /^WDIO[CFS]_/ ||\n\t\t$2 ~ /^NFN/ ||\n\t\t$2 !~ /^NFT_META_IIFTYPE/ &&\n\t\t$2 ~ /^NFT_/ ||\n\t\t$2 ~ /^NF_NAT_/ ||\n\t\t$2 ~ /^XDP_/ ||\n\t\t$2 ~ /^RWF_/ ||\n\t\t$2 ~ /^(HDIO|WIN|SMART)_/ ||\n\t\t$2 ~ /^CRYPTO_/ ||\n\t\t$2 ~ /^TIPC_/ ||\n\t\t$2 !~  \"DEVLINK_RELOAD_LIMITS_VALID_MASK\" &&\n\t\t$2 ~ /^DEVLINK_/ ||\n\t\t$2 ~ /^ETHTOOL_/ ||\n\t\t$2 ~ /^LWTUNNEL_IP/ ||\n\t\t$2 ~ /^ITIMER_/ ||\n\t\t$2 !~ \"WMESGLEN\" &&\n\t\t$2 ~ /^W[A-Z0-9]+$/ ||\n\t\t$2 ~ /^P_/ ||\n\t\t$2 ~/^PPPIOC/ ||\n\t\t$2 ~ /^FAN_|FANOTIFY_/ ||\n\t\t$2 == \"HID_MAX_DESCRIPTOR_SIZE\" ||\n\t\t$2 ~ /^_?HIDIOC/ ||\n\t\t$2 ~ /^BUS_(USB|HIL|BLUETOOTH|VIRTUAL)$/ ||\n\t\t$2 ~ /^MTD/ ||\n\t\t$2 ~ /^OTP/ ||\n\t\t$2 ~ /^MEM/ ||\n\t\t$2 ~ /^WG/ ||\n\t\t$2 ~ /^FIB_RULE_/ ||\n\t\t$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE|IOMIN$|IOOPT$|ALIGNOFF$|DISCARD|ROTATIONAL$|ZEROOUT$|GETDISKSEQ$)/ {printf(\"\\t%s = C.%s\\n\", $2, $2)}\n\t\t$2 ~ /^__WCOREFLAG$/ {next}\n\t\t$2 ~ /^__W[A-Z0-9]+$/ {printf(\"\\t%s = C.%s\\n\", substr($2,3), $2)}\n\n\t\t{next}\n\t' | sort\n\n\techo ')'\n) >_const.go\n\n# Pull out the error names for later.\nerrors=$(\n\techo '#include <errno.h>' | $CC -x c - -E -dM $ccflags |\n\tawk '$1==\"#define\" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' |\n\tsort\n)\n\n# Pull out the signal names for later.\nsignals=$(\n\techo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |\n\tawk '$1==\"#define\" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |\n\tgrep -E -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |\n\tsort\n)\n\n# Again, writing regexps to a file.\necho '#include <errno.h>' | $CC -x c - -E -dM $ccflags |\n\tawk '$1==\"#define\" && $2 ~ /^E[A-Z0-9_]+$/ { print \"^\\t\" $2 \"[ \\t]*=\" }' |\n\tsort >_error.grep\necho '#include <signal.h>' | $CC -x c - -E -dM $ccflags |\n\tawk '$1==\"#define\" && $2 ~ /^SIG[A-Z0-9]+$/ { print \"^\\t\" $2 \"[ \\t]*=\" }' |\n\tgrep -E -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |\n\tsort >_signal.grep\n\necho '// mkerrors.sh' \"$@\"\necho '// Code generated by the command above; see README.md. DO NOT EDIT.'\necho\necho \"//go:build ${GOARCH} && ${GOOS}\"\necho\ngo tool cgo -godefs -- \"$@\" _const.go >_error.out\ncat _error.out | grep -vf _error.grep | grep -vf _signal.grep\necho\necho '// Errors'\necho 'const ('\ncat _error.out | grep -f _error.grep | sed 's/=\\(.*\\)/= syscall.Errno(\\1)/'\necho ')'\n\necho\necho '// Signals'\necho 'const ('\ncat _error.out | grep -f _signal.grep | sed 's/=\\(.*\\)/= syscall.Signal(\\1)/'\necho ')'\n\n# Run C program to print error and syscall strings.\n(\n\techo -E \"\n#include <stdio.h>\n#include <stdlib.h>\n#include <errno.h>\n#include <ctype.h>\n#include <string.h>\n#include <signal.h>\n\n#define nelem(x) (sizeof(x)/sizeof((x)[0]))\n\nenum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below\n\nstruct tuple {\n\tint num;\n\tconst char *name;\n};\n\nstruct tuple errors[] = {\n\"\n\tfor i in $errors\n\tdo\n\t\techo -E '\t{'$i', \"'$i'\" },'\n\tdone\n\n\techo -E \"\n};\n\nstruct tuple signals[] = {\n\"\n\tfor i in $signals\n\tdo\n\t\techo -E '\t{'$i', \"'$i'\" },'\n\tdone\n\n\t# Use -E because on some systems bash builtin interprets \\n itself.\n\techo -E '\n};\n\nstatic int\ntuplecmp(const void *a, const void *b)\n{\n\treturn ((struct tuple *)a)->num - ((struct tuple *)b)->num;\n}\n\nint\nmain(void)\n{\n\tint i, e;\n\tchar buf[1024], *p;\n\n\tprintf(\"\\n\\n// Error table\\n\");\n\tprintf(\"var errorList = [...]struct {\\n\");\n\tprintf(\"\\tnum  syscall.Errno\\n\");\n\tprintf(\"\\tname string\\n\");\n\tprintf(\"\\tdesc string\\n\");\n\tprintf(\"} {\\n\");\n\tqsort(errors, nelem(errors), sizeof errors[0], tuplecmp);\n\tfor(i=0; i<nelem(errors); i++) {\n\t\te = errors[i].num;\n\t\tif(i > 0 && errors[i-1].num == e)\n\t\t\tcontinue;\n\t\tstrncpy(buf, strerror(e), sizeof(buf) - 1);\n\t\tbuf[sizeof(buf) - 1] = '\\0';\n\t\t// lowercase first letter: Bad -> bad, but STREAM -> STREAM.\n\t\tif(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)\n\t\t\tbuf[0] += a - A;\n\t\tprintf(\"\\t{ %d, \\\"%s\\\", \\\"%s\\\" },\\n\", e, errors[i].name, buf);\n\t}\n\tprintf(\"}\\n\\n\");\n\n\tprintf(\"\\n\\n// Signal table\\n\");\n\tprintf(\"var signalList = [...]struct {\\n\");\n\tprintf(\"\\tnum  syscall.Signal\\n\");\n\tprintf(\"\\tname string\\n\");\n\tprintf(\"\\tdesc string\\n\");\n\tprintf(\"} {\\n\");\n\tqsort(signals, nelem(signals), sizeof signals[0], tuplecmp);\n\tfor(i=0; i<nelem(signals); i++) {\n\t\te = signals[i].num;\n\t\tif(i > 0 && signals[i-1].num == e)\n\t\t\tcontinue;\n\t\tstrncpy(buf, strsignal(e), sizeof(buf) - 1);\n\t\tbuf[sizeof(buf) - 1] = '\\0';\n\t\t// lowercase first letter: Bad -> bad, but STREAM -> STREAM.\n\t\tif(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)\n\t\t\tbuf[0] += a - A;\n\t\t// cut trailing : number.\n\t\tp = strrchr(buf, \":\"[0]);\n\t\tif(p)\n\t\t\t*p = '\\0';\n\t\tprintf(\"\\t{ %d, \\\"%s\\\", \\\"%s\\\" },\\n\", e, signals[i].name, buf);\n\t}\n\tprintf(\"}\\n\\n\");\n\n\treturn 0;\n}\n\n'\n) >_errors.c\n\n$CC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/mmap_nomremap.go",
    "content": "// Copyright 2023 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris || zos\n\npackage unix\n\nvar mapper = &mmapper{\n\tactive: make(map[*byte][]byte),\n\tmmap:   mmap,\n\tmunmap: munmap,\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/mremap.go",
    "content": "// Copyright 2023 The Go 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\n//go:build linux || netbsd\n\npackage unix\n\nimport \"unsafe\"\n\ntype mremapMmapper struct {\n\tmmapper\n\tmremap func(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)\n}\n\nvar mapper = &mremapMmapper{\n\tmmapper: mmapper{\n\t\tactive: make(map[*byte][]byte),\n\t\tmmap:   mmap,\n\t\tmunmap: munmap,\n\t},\n\tmremap: mremap,\n}\n\nfunc (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {\n\tif newLength <= 0 || len(oldData) == 0 || len(oldData) != cap(oldData) || flags&mremapFixed != 0 {\n\t\treturn nil, EINVAL\n\t}\n\n\tpOld := &oldData[cap(oldData)-1]\n\tm.Lock()\n\tdefer m.Unlock()\n\tbOld := m.active[pOld]\n\tif bOld == nil || &bOld[0] != &oldData[0] {\n\t\treturn nil, EINVAL\n\t}\n\tnewAddr, errno := m.mremap(uintptr(unsafe.Pointer(&bOld[0])), uintptr(len(bOld)), uintptr(newLength), flags, 0)\n\tif errno != nil {\n\t\treturn nil, errno\n\t}\n\tbNew := unsafe.Slice((*byte)(unsafe.Pointer(newAddr)), newLength)\n\tpNew := &bNew[cap(bNew)-1]\n\tif flags&mremapDontunmap == 0 {\n\t\tdelete(m.active, pOld)\n\t}\n\tm.active[pNew] = bNew\n\treturn bNew, nil\n}\n\nfunc Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {\n\treturn mapper.Mremap(oldData, newLength, flags)\n}\n\nfunc MremapPtr(oldAddr unsafe.Pointer, oldSize uintptr, newAddr unsafe.Pointer, newSize uintptr, flags int) (ret unsafe.Pointer, err error) {\n\txaddr, err := mapper.mremap(uintptr(oldAddr), oldSize, newSize, flags, uintptr(newAddr))\n\treturn unsafe.Pointer(xaddr), err\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/pagesize_unix.go",
    "content": "// Copyright 2017 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\n// For Unix, get the pagesize from the runtime.\n\npackage unix\n\nimport \"syscall\"\n\nfunc Getpagesize() int {\n\treturn syscall.Getpagesize()\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/pledge_openbsd.go",
    "content": "// Copyright 2016 The Go 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 unix\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n)\n\n// Pledge implements the pledge syscall.\n//\n// This changes both the promises and execpromises; use PledgePromises or\n// PledgeExecpromises to only change the promises or execpromises\n// respectively.\n//\n// For more information see pledge(2).\nfunc Pledge(promises, execpromises string) error {\n\tif err := pledgeAvailable(); err != nil {\n\t\treturn err\n\t}\n\n\tpptr, err := BytePtrFromString(promises)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\texptr, err := BytePtrFromString(execpromises)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn pledge(pptr, exptr)\n}\n\n// PledgePromises implements the pledge syscall.\n//\n// This changes the promises and leaves the execpromises untouched.\n//\n// For more information see pledge(2).\nfunc PledgePromises(promises string) error {\n\tif err := pledgeAvailable(); err != nil {\n\t\treturn err\n\t}\n\n\tpptr, err := BytePtrFromString(promises)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn pledge(pptr, nil)\n}\n\n// PledgeExecpromises implements the pledge syscall.\n//\n// This changes the execpromises and leaves the promises untouched.\n//\n// For more information see pledge(2).\nfunc PledgeExecpromises(execpromises string) error {\n\tif err := pledgeAvailable(); err != nil {\n\t\treturn err\n\t}\n\n\texptr, err := BytePtrFromString(execpromises)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn pledge(nil, exptr)\n}\n\n// majmin returns major and minor version number for an OpenBSD system.\nfunc majmin() (major int, minor int, err error) {\n\tvar v Utsname\n\terr = Uname(&v)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tmajor, err = strconv.Atoi(string(v.Release[0]))\n\tif err != nil {\n\t\terr = errors.New(\"cannot parse major version number returned by uname\")\n\t\treturn\n\t}\n\n\tminor, err = strconv.Atoi(string(v.Release[2]))\n\tif err != nil {\n\t\terr = errors.New(\"cannot parse minor version number returned by uname\")\n\t\treturn\n\t}\n\n\treturn\n}\n\n// pledgeAvailable checks for availability of the pledge(2) syscall\n// based on the running OpenBSD version.\nfunc pledgeAvailable() error {\n\tmaj, min, err := majmin()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Require OpenBSD 6.4 as a minimum.\n\tif maj < 6 || (maj == 6 && min <= 3) {\n\t\treturn fmt.Errorf(\"cannot call Pledge on OpenBSD %d.%d\", maj, min)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/ptrace_darwin.go",
    "content": "// Copyright 2020 The Go 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\n//go:build darwin && !ios\n\npackage unix\n\nfunc ptrace(request int, pid int, addr uintptr, data uintptr) error {\n\treturn ptrace1(request, pid, addr, data)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/ptrace_ios.go",
    "content": "// Copyright 2020 The Go 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\n//go:build ios\n\npackage unix\n\nfunc ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {\n\treturn ENOTSUP\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/race.go",
    "content": "// Copyright 2012 The Go 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\n//go:build (darwin && race) || (linux && race) || (freebsd && race)\n\npackage unix\n\nimport (\n\t\"runtime\"\n\t\"unsafe\"\n)\n\nconst raceenabled = true\n\nfunc raceAcquire(addr unsafe.Pointer) {\n\truntime.RaceAcquire(addr)\n}\n\nfunc raceReleaseMerge(addr unsafe.Pointer) {\n\truntime.RaceReleaseMerge(addr)\n}\n\nfunc raceReadRange(addr unsafe.Pointer, len int) {\n\truntime.RaceReadRange(addr, len)\n}\n\nfunc raceWriteRange(addr unsafe.Pointer, len int) {\n\truntime.RaceWriteRange(addr, len)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/race0.go",
    "content": "// Copyright 2012 The Go 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\n//go:build aix || (darwin && !race) || (linux && !race) || (freebsd && !race) || netbsd || openbsd || solaris || dragonfly || zos\n\npackage unix\n\nimport (\n\t\"unsafe\"\n)\n\nconst raceenabled = false\n\nfunc raceAcquire(addr unsafe.Pointer) {\n}\n\nfunc raceReleaseMerge(addr unsafe.Pointer) {\n}\n\nfunc raceReadRange(addr unsafe.Pointer, len int) {\n}\n\nfunc raceWriteRange(addr unsafe.Pointer, len int) {\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/readdirent_getdents.go",
    "content": "// Copyright 2019 The Go 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\n//go:build aix || dragonfly || freebsd || linux || netbsd || openbsd\n\npackage unix\n\n// ReadDirent reads directory entries from fd and writes them into buf.\nfunc ReadDirent(fd int, buf []byte) (n int, err error) {\n\treturn Getdents(fd, buf)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/readdirent_getdirentries.go",
    "content": "// Copyright 2019 The Go 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\n//go:build darwin || zos\n\npackage unix\n\nimport \"unsafe\"\n\n// ReadDirent reads directory entries from fd and writes them into buf.\nfunc ReadDirent(fd int, buf []byte) (n int, err error) {\n\t// Final argument is (basep *uintptr) and the syscall doesn't take nil.\n\t// 64 bits should be enough. (32 bits isn't even on 386). Since the\n\t// actual system call is getdirentries64, 64 is a good guess.\n\t// TODO(rsc): Can we use a single global basep for all calls?\n\tvar base = (*uintptr)(unsafe.Pointer(new(uint64)))\n\treturn Getdirentries(fd, buf, base)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/sockcmsg_dragonfly.go",
    "content": "// Copyright 2019 The Go 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 unix\n\n// Round the length of a raw sockaddr up to align it properly.\nfunc cmsgAlignOf(salen int) int {\n\tsalign := SizeofPtr\n\tif SizeofPtr == 8 && !supportsABI(_dragonflyABIChangeVersion) {\n\t\t// 64-bit Dragonfly before the September 2019 ABI changes still requires\n\t\t// 32-bit aligned access to network subsystem.\n\t\tsalign = 4\n\t}\n\treturn (salen + salign - 1) & ^(salign - 1)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/sockcmsg_linux.go",
    "content": "// Copyright 2011 The Go 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\n// Socket control messages\n\npackage unix\n\nimport \"unsafe\"\n\n// UnixCredentials encodes credentials into a socket control message\n// for sending to another process. This can be used for\n// authentication.\nfunc UnixCredentials(ucred *Ucred) []byte {\n\tb := make([]byte, CmsgSpace(SizeofUcred))\n\th := (*Cmsghdr)(unsafe.Pointer(&b[0]))\n\th.Level = SOL_SOCKET\n\th.Type = SCM_CREDENTIALS\n\th.SetLen(CmsgLen(SizeofUcred))\n\t*(*Ucred)(h.data(0)) = *ucred\n\treturn b\n}\n\n// ParseUnixCredentials decodes a socket control message that contains\n// credentials in a Ucred structure. To receive such a message, the\n// SO_PASSCRED option must be enabled on the socket.\nfunc ParseUnixCredentials(m *SocketControlMessage) (*Ucred, error) {\n\tif m.Header.Level != SOL_SOCKET {\n\t\treturn nil, EINVAL\n\t}\n\tif m.Header.Type != SCM_CREDENTIALS {\n\t\treturn nil, EINVAL\n\t}\n\tucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))\n\treturn &ucred, nil\n}\n\n// PktInfo4 encodes Inet4Pktinfo into a socket control message of type IP_PKTINFO.\nfunc PktInfo4(info *Inet4Pktinfo) []byte {\n\tb := make([]byte, CmsgSpace(SizeofInet4Pktinfo))\n\th := (*Cmsghdr)(unsafe.Pointer(&b[0]))\n\th.Level = SOL_IP\n\th.Type = IP_PKTINFO\n\th.SetLen(CmsgLen(SizeofInet4Pktinfo))\n\t*(*Inet4Pktinfo)(h.data(0)) = *info\n\treturn b\n}\n\n// PktInfo6 encodes Inet6Pktinfo into a socket control message of type IPV6_PKTINFO.\nfunc PktInfo6(info *Inet6Pktinfo) []byte {\n\tb := make([]byte, CmsgSpace(SizeofInet6Pktinfo))\n\th := (*Cmsghdr)(unsafe.Pointer(&b[0]))\n\th.Level = SOL_IPV6\n\th.Type = IPV6_PKTINFO\n\th.SetLen(CmsgLen(SizeofInet6Pktinfo))\n\t*(*Inet6Pktinfo)(h.data(0)) = *info\n\treturn b\n}\n\n// ParseOrigDstAddr decodes a socket control message containing the original\n// destination address. To receive such a message the IP_RECVORIGDSTADDR or\n// IPV6_RECVORIGDSTADDR option must be enabled on the socket.\nfunc ParseOrigDstAddr(m *SocketControlMessage) (Sockaddr, error) {\n\tswitch {\n\tcase m.Header.Level == SOL_IP && m.Header.Type == IP_ORIGDSTADDR:\n\t\tpp := (*RawSockaddrInet4)(unsafe.Pointer(&m.Data[0]))\n\t\tsa := new(SockaddrInet4)\n\t\tp := (*[2]byte)(unsafe.Pointer(&pp.Port))\n\t\tsa.Port = int(p[0])<<8 + int(p[1])\n\t\tsa.Addr = pp.Addr\n\t\treturn sa, nil\n\n\tcase m.Header.Level == SOL_IPV6 && m.Header.Type == IPV6_ORIGDSTADDR:\n\t\tpp := (*RawSockaddrInet6)(unsafe.Pointer(&m.Data[0]))\n\t\tsa := new(SockaddrInet6)\n\t\tp := (*[2]byte)(unsafe.Pointer(&pp.Port))\n\t\tsa.Port = int(p[0])<<8 + int(p[1])\n\t\tsa.ZoneId = pp.Scope_id\n\t\tsa.Addr = pp.Addr\n\t\treturn sa, nil\n\n\tdefault:\n\t\treturn nil, EINVAL\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/sockcmsg_unix.go",
    "content": "// Copyright 2011 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\n// Socket control messages\n\npackage unix\n\nimport (\n\t\"unsafe\"\n)\n\n// CmsgLen returns the value to store in the Len field of the Cmsghdr\n// structure, taking into account any necessary alignment.\nfunc CmsgLen(datalen int) int {\n\treturn cmsgAlignOf(SizeofCmsghdr) + datalen\n}\n\n// CmsgSpace returns the number of bytes an ancillary element with\n// payload of the passed data length occupies.\nfunc CmsgSpace(datalen int) int {\n\treturn cmsgAlignOf(SizeofCmsghdr) + cmsgAlignOf(datalen)\n}\n\nfunc (h *Cmsghdr) data(offset uintptr) unsafe.Pointer {\n\treturn unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(SizeofCmsghdr)) + offset)\n}\n\n// SocketControlMessage represents a socket control message.\ntype SocketControlMessage struct {\n\tHeader Cmsghdr\n\tData   []byte\n}\n\n// ParseSocketControlMessage parses b as an array of socket control\n// messages.\nfunc ParseSocketControlMessage(b []byte) ([]SocketControlMessage, error) {\n\tvar msgs []SocketControlMessage\n\ti := 0\n\tfor i+CmsgLen(0) <= len(b) {\n\t\th, dbuf, err := socketControlMessageHeaderAndData(b[i:])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tm := SocketControlMessage{Header: *h, Data: dbuf}\n\t\tmsgs = append(msgs, m)\n\t\ti += cmsgAlignOf(int(h.Len))\n\t}\n\treturn msgs, nil\n}\n\n// ParseOneSocketControlMessage parses a single socket control message from b, returning the message header,\n// message data (a slice of b), and the remainder of b after that single message.\n// When there are no remaining messages, len(remainder) == 0.\nfunc ParseOneSocketControlMessage(b []byte) (hdr Cmsghdr, data []byte, remainder []byte, err error) {\n\th, dbuf, err := socketControlMessageHeaderAndData(b)\n\tif err != nil {\n\t\treturn Cmsghdr{}, nil, nil, err\n\t}\n\tif i := cmsgAlignOf(int(h.Len)); i < len(b) {\n\t\tremainder = b[i:]\n\t}\n\treturn *h, dbuf, remainder, nil\n}\n\nfunc socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) {\n\th := (*Cmsghdr)(unsafe.Pointer(&b[0]))\n\tif h.Len < SizeofCmsghdr || uint64(h.Len) > uint64(len(b)) {\n\t\treturn nil, nil, EINVAL\n\t}\n\treturn h, b[cmsgAlignOf(SizeofCmsghdr):h.Len], nil\n}\n\n// UnixRights encodes a set of open file descriptors into a socket\n// control message for sending to another process.\nfunc UnixRights(fds ...int) []byte {\n\tdatalen := len(fds) * 4\n\tb := make([]byte, CmsgSpace(datalen))\n\th := (*Cmsghdr)(unsafe.Pointer(&b[0]))\n\th.Level = SOL_SOCKET\n\th.Type = SCM_RIGHTS\n\th.SetLen(CmsgLen(datalen))\n\tfor i, fd := range fds {\n\t\t*(*int32)(h.data(4 * uintptr(i))) = int32(fd)\n\t}\n\treturn b\n}\n\n// ParseUnixRights decodes a socket control message that contains an\n// integer array of open file descriptors from another process.\nfunc ParseUnixRights(m *SocketControlMessage) ([]int, error) {\n\tif m.Header.Level != SOL_SOCKET {\n\t\treturn nil, EINVAL\n\t}\n\tif m.Header.Type != SCM_RIGHTS {\n\t\treturn nil, EINVAL\n\t}\n\tfds := make([]int, len(m.Data)>>2)\n\tfor i, j := 0, 0; i < len(m.Data); i += 4 {\n\t\tfds[j] = int(*(*int32)(unsafe.Pointer(&m.Data[i])))\n\t\tj++\n\t}\n\treturn fds, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go",
    "content": "// Copyright 2019 The Go 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\n//go:build aix || darwin || freebsd || linux || netbsd || openbsd || solaris || zos\n\npackage unix\n\nimport (\n\t\"runtime\"\n)\n\n// Round the length of a raw sockaddr up to align it properly.\nfunc cmsgAlignOf(salen int) int {\n\tsalign := SizeofPtr\n\n\t// dragonfly needs to check ABI version at runtime, see cmsgAlignOf in\n\t// sockcmsg_dragonfly.go\n\tswitch runtime.GOOS {\n\tcase \"aix\":\n\t\t// There is no alignment on AIX.\n\t\tsalign = 1\n\tcase \"darwin\", \"ios\", \"illumos\", \"solaris\":\n\t\t// NOTE: It seems like 64-bit Darwin, Illumos and Solaris\n\t\t// kernels still require 32-bit aligned access to network\n\t\t// subsystem.\n\t\tif SizeofPtr == 8 {\n\t\t\tsalign = 4\n\t\t}\n\tcase \"netbsd\", \"openbsd\":\n\t\t// NetBSD and OpenBSD armv7 require 64-bit alignment.\n\t\tif runtime.GOARCH == \"arm\" {\n\t\t\tsalign = 8\n\t\t}\n\t\t// NetBSD aarch64 requires 128-bit alignment.\n\t\tif runtime.GOOS == \"netbsd\" && runtime.GOARCH == \"arm64\" {\n\t\t\tsalign = 16\n\t\t}\n\tcase \"zos\":\n\t\t// z/OS socket macros use [32-bit] sizeof(int) alignment,\n\t\t// not pointer width.\n\t\tsalign = SizeofInt\n\t}\n\n\treturn (salen + salign - 1) & ^(salign - 1)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/sockcmsg_zos.go",
    "content": "// Copyright 2024 The Go 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\n// Socket control messages\n\npackage unix\n\nimport \"unsafe\"\n\n// UnixCredentials encodes credentials into a socket control message\n// for sending to another process. This can be used for\n// authentication.\nfunc UnixCredentials(ucred *Ucred) []byte {\n\tb := make([]byte, CmsgSpace(SizeofUcred))\n\th := (*Cmsghdr)(unsafe.Pointer(&b[0]))\n\th.Level = SOL_SOCKET\n\th.Type = SCM_CREDENTIALS\n\th.SetLen(CmsgLen(SizeofUcred))\n\t*(*Ucred)(h.data(0)) = *ucred\n\treturn b\n}\n\n// ParseUnixCredentials decodes a socket control message that contains\n// credentials in a Ucred structure. To receive such a message, the\n// SO_PASSCRED option must be enabled on the socket.\nfunc ParseUnixCredentials(m *SocketControlMessage) (*Ucred, error) {\n\tif m.Header.Level != SOL_SOCKET {\n\t\treturn nil, EINVAL\n\t}\n\tif m.Header.Type != SCM_CREDENTIALS {\n\t\treturn nil, EINVAL\n\t}\n\tucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))\n\treturn &ucred, nil\n}\n\n// PktInfo4 encodes Inet4Pktinfo into a socket control message of type IP_PKTINFO.\nfunc PktInfo4(info *Inet4Pktinfo) []byte {\n\tb := make([]byte, CmsgSpace(SizeofInet4Pktinfo))\n\th := (*Cmsghdr)(unsafe.Pointer(&b[0]))\n\th.Level = SOL_IP\n\th.Type = IP_PKTINFO\n\th.SetLen(CmsgLen(SizeofInet4Pktinfo))\n\t*(*Inet4Pktinfo)(h.data(0)) = *info\n\treturn b\n}\n\n// PktInfo6 encodes Inet6Pktinfo into a socket control message of type IPV6_PKTINFO.\nfunc PktInfo6(info *Inet6Pktinfo) []byte {\n\tb := make([]byte, CmsgSpace(SizeofInet6Pktinfo))\n\th := (*Cmsghdr)(unsafe.Pointer(&b[0]))\n\th.Level = SOL_IPV6\n\th.Type = IPV6_PKTINFO\n\th.SetLen(CmsgLen(SizeofInet6Pktinfo))\n\t*(*Inet6Pktinfo)(h.data(0)) = *info\n\treturn b\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/symaddr_zos_s390x.s",
    "content": "// Copyright 2024 The Go 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\n//go:build zos && s390x && gc\n\n#include \"textflag.h\"\n\n//  provide the address of function variable to be fixed up.\n\nTEXT ·getPipe2Addr(SB), NOSPLIT|NOFRAME, $0-8\n\tMOVD $·Pipe2(SB), R8\n\tMOVD R8, ret+0(FP)\n\tRET\n\nTEXT ·get_FlockAddr(SB), NOSPLIT|NOFRAME, $0-8\n\tMOVD $·Flock(SB), R8\n\tMOVD R8, ret+0(FP)\n\tRET\n\nTEXT ·get_GetxattrAddr(SB), NOSPLIT|NOFRAME, $0-8\n\tMOVD $·Getxattr(SB), R8\n\tMOVD R8, ret+0(FP)\n\tRET\n\nTEXT ·get_NanosleepAddr(SB), NOSPLIT|NOFRAME, $0-8\n\tMOVD $·Nanosleep(SB), R8\n\tMOVD R8, ret+0(FP)\n\tRET\n\nTEXT ·get_SetxattrAddr(SB), NOSPLIT|NOFRAME, $0-8\n\tMOVD $·Setxattr(SB), R8\n\tMOVD R8, ret+0(FP)\n\tRET\n\nTEXT ·get_Wait4Addr(SB), NOSPLIT|NOFRAME, $0-8\n\tMOVD $·Wait4(SB), R8\n\tMOVD R8, ret+0(FP)\n\tRET\n\nTEXT ·get_MountAddr(SB), NOSPLIT|NOFRAME, $0-8\n\tMOVD $·Mount(SB), R8\n\tMOVD R8, ret+0(FP)\n\tRET\n\nTEXT ·get_UnmountAddr(SB), NOSPLIT|NOFRAME, $0-8\n\tMOVD $·Unmount(SB), R8\n\tMOVD R8, ret+0(FP)\n\tRET\n\nTEXT ·get_UtimesNanoAtAddr(SB), NOSPLIT|NOFRAME, $0-8\n\tMOVD $·UtimesNanoAt(SB), R8\n\tMOVD R8, ret+0(FP)\n\tRET\n\nTEXT ·get_UtimesNanoAddr(SB), NOSPLIT|NOFRAME, $0-8\n\tMOVD $·UtimesNano(SB), R8\n\tMOVD R8, ret+0(FP)\n\tRET\n\nTEXT ·get_MkfifoatAddr(SB), NOSPLIT|NOFRAME, $0-8\n\tMOVD $·Mkfifoat(SB), R8\n\tMOVD R8, ret+0(FP)\n\tRET\n\nTEXT ·get_ChtagAddr(SB), NOSPLIT|NOFRAME, $0-8\n\tMOVD $·Chtag(SB), R8\n\tMOVD R8, ret+0(FP)\n\tRET\n\nTEXT ·get_ReadlinkatAddr(SB), NOSPLIT|NOFRAME, $0-8\n\tMOVD $·Readlinkat(SB), R8\n\tMOVD R8, ret+0(FP)\n\tRET\n\t\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall.go",
    "content": "// Copyright 2009 The Go 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\n//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos\n\n// Package unix contains an interface to the low-level operating system\n// primitives. OS details vary depending on the underlying system, and\n// by default, godoc will display OS-specific documentation for the current\n// system. If you want godoc to display OS documentation for another\n// system, set $GOOS and $GOARCH to the desired system. For example, if\n// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS\n// to freebsd and $GOARCH to arm.\n//\n// The primary use of this package is inside other packages that provide a more\n// portable interface to the system, such as \"os\", \"time\" and \"net\".  Use\n// those packages rather than this one if you can.\n//\n// For details of the functions and data types in this package consult\n// the manuals for the appropriate operating system.\n//\n// These calls return err == nil to indicate success; otherwise\n// err represents an operating system error describing the failure and\n// holds a value of type syscall.Errno.\npackage unix // import \"golang.org/x/sys/unix\"\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n\t\"unsafe\"\n)\n\n// ByteSliceFromString returns a NUL-terminated slice of bytes\n// containing the text of s. If s contains a NUL byte at any\n// location, it returns (nil, EINVAL).\nfunc ByteSliceFromString(s string) ([]byte, error) {\n\tif strings.IndexByte(s, 0) != -1 {\n\t\treturn nil, EINVAL\n\t}\n\ta := make([]byte, len(s)+1)\n\tcopy(a, s)\n\treturn a, nil\n}\n\n// BytePtrFromString returns a pointer to a NUL-terminated array of\n// bytes containing the text of s. If s contains a NUL byte at any\n// location, it returns (nil, EINVAL).\nfunc BytePtrFromString(s string) (*byte, error) {\n\ta, err := ByteSliceFromString(s)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &a[0], nil\n}\n\n// ByteSliceToString returns a string form of the text represented by the slice s, with a terminating NUL and any\n// bytes after the NUL removed.\nfunc ByteSliceToString(s []byte) string {\n\tif i := bytes.IndexByte(s, 0); i != -1 {\n\t\ts = s[:i]\n\t}\n\treturn string(s)\n}\n\n// BytePtrToString takes a pointer to a sequence of text and returns the corresponding string.\n// If the pointer is nil, it returns the empty string. It assumes that the text sequence is terminated\n// at a zero byte; if the zero byte is not present, the program may crash.\nfunc BytePtrToString(p *byte) string {\n\tif p == nil {\n\t\treturn \"\"\n\t}\n\tif *p == 0 {\n\t\treturn \"\"\n\t}\n\n\t// Find NUL terminator.\n\tn := 0\n\tfor ptr := unsafe.Pointer(p); *(*byte)(ptr) != 0; n++ {\n\t\tptr = unsafe.Pointer(uintptr(ptr) + 1)\n\t}\n\n\treturn string(unsafe.Slice(p, n))\n}\n\n// Single-word zero for use when we need a valid pointer to 0 bytes.\nvar _zero uintptr\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_aix.go",
    "content": "// Copyright 2018 The Go 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\n//go:build aix\n\n// Aix system calls.\n// This file is compiled as ordinary Go code,\n// but it is also input to mksyscall,\n// which parses the //sys lines and generates system call stubs.\n// Note that sometimes we use a lowercase //sys name and\n// wrap it in our own nicer implementation.\n\npackage unix\n\nimport \"unsafe\"\n\n/*\n * Wrapped\n */\n\nfunc Access(path string, mode uint32) (err error) {\n\treturn Faccessat(AT_FDCWD, path, mode, 0)\n}\n\nfunc Chmod(path string, mode uint32) (err error) {\n\treturn Fchmodat(AT_FDCWD, path, mode, 0)\n}\n\nfunc Chown(path string, uid int, gid int) (err error) {\n\treturn Fchownat(AT_FDCWD, path, uid, gid, 0)\n}\n\nfunc Creat(path string, mode uint32) (fd int, err error) {\n\treturn Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)\n}\n\n//sys\tutimes(path string, times *[2]Timeval) (err error)\n\nfunc Utimes(path string, tv []Timeval) error {\n\tif len(tv) != 2 {\n\t\treturn EINVAL\n\t}\n\treturn utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))\n}\n\n//sys\tutimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)\n\nfunc UtimesNano(path string, ts []Timespec) error {\n\tif len(ts) != 2 {\n\t\treturn EINVAL\n\t}\n\treturn utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)\n}\n\nfunc UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {\n\tif ts == nil {\n\t\treturn utimensat(dirfd, path, nil, flags)\n\t}\n\tif len(ts) != 2 {\n\t\treturn EINVAL\n\t}\n\treturn utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)\n}\n\nfunc (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tif sa.Port < 0 || sa.Port > 0xFFFF {\n\t\treturn nil, 0, EINVAL\n\t}\n\tsa.raw.Family = AF_INET\n\tp := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))\n\tp[0] = byte(sa.Port >> 8)\n\tp[1] = byte(sa.Port)\n\tsa.raw.Addr = sa.Addr\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil\n}\n\nfunc (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tif sa.Port < 0 || sa.Port > 0xFFFF {\n\t\treturn nil, 0, EINVAL\n\t}\n\tsa.raw.Family = AF_INET6\n\tp := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))\n\tp[0] = byte(sa.Port >> 8)\n\tp[1] = byte(sa.Port)\n\tsa.raw.Scope_id = sa.ZoneId\n\tsa.raw.Addr = sa.Addr\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil\n}\n\nfunc (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tname := sa.Name\n\tn := len(name)\n\tif n > len(sa.raw.Path) {\n\t\treturn nil, 0, EINVAL\n\t}\n\tif n == len(sa.raw.Path) && name[0] != '@' {\n\t\treturn nil, 0, EINVAL\n\t}\n\tsa.raw.Family = AF_UNIX\n\tfor i := 0; i < n; i++ {\n\t\tsa.raw.Path[i] = uint8(name[i])\n\t}\n\t// length is family (uint16), name, NUL.\n\tsl := _Socklen(2)\n\tif n > 0 {\n\t\tsl += _Socklen(n) + 1\n\t}\n\tif sa.raw.Path[0] == '@' || (sa.raw.Path[0] == 0 && sl > 3) {\n\t\t// Check sl > 3 so we don't change unnamed socket behavior.\n\t\tsa.raw.Path[0] = 0\n\t\t// Don't count trailing NUL for abstract address.\n\t\tsl--\n\t}\n\n\treturn unsafe.Pointer(&sa.raw), sl, nil\n}\n\nfunc Getsockname(fd int) (sa Sockaddr, err error) {\n\tvar rsa RawSockaddrAny\n\tvar len _Socklen = SizeofSockaddrAny\n\tif err = getsockname(fd, &rsa, &len); err != nil {\n\t\treturn\n\t}\n\treturn anyToSockaddr(fd, &rsa)\n}\n\n//sys\tgetcwd(buf []byte) (err error)\n\nconst ImplementsGetwd = true\n\nfunc Getwd() (ret string, err error) {\n\tfor len := uint64(4096); ; len *= 2 {\n\t\tb := make([]byte, len)\n\t\terr := getcwd(b)\n\t\tif err == nil {\n\t\t\ti := 0\n\t\t\tfor b[i] != 0 {\n\t\t\t\ti++\n\t\t\t}\n\t\t\treturn string(b[0:i]), nil\n\t\t}\n\t\tif err != ERANGE {\n\t\t\treturn \"\", err\n\t\t}\n\t}\n}\n\nfunc Getcwd(buf []byte) (n int, err error) {\n\terr = getcwd(buf)\n\tif err == nil {\n\t\ti := 0\n\t\tfor buf[i] != 0 {\n\t\t\ti++\n\t\t}\n\t\tn = i + 1\n\t}\n\treturn\n}\n\nfunc Getgroups() (gids []int, err error) {\n\tn, err := getgroups(0, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif n == 0 {\n\t\treturn nil, nil\n\t}\n\n\t// Sanity check group count. Max is 16 on BSD.\n\tif n < 0 || n > 1000 {\n\t\treturn nil, EINVAL\n\t}\n\n\ta := make([]_Gid_t, n)\n\tn, err = getgroups(n, &a[0])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tgids = make([]int, n)\n\tfor i, v := range a[0:n] {\n\t\tgids[i] = int(v)\n\t}\n\treturn\n}\n\nfunc Setgroups(gids []int) (err error) {\n\tif len(gids) == 0 {\n\t\treturn setgroups(0, nil)\n\t}\n\n\ta := make([]_Gid_t, len(gids))\n\tfor i, v := range gids {\n\t\ta[i] = _Gid_t(v)\n\t}\n\treturn setgroups(len(a), &a[0])\n}\n\n/*\n * Socket\n */\n\n//sys\taccept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)\n\nfunc Accept(fd int) (nfd int, sa Sockaddr, err error) {\n\tvar rsa RawSockaddrAny\n\tvar len _Socklen = SizeofSockaddrAny\n\tnfd, err = accept(fd, &rsa, &len)\n\tif nfd == -1 {\n\t\treturn\n\t}\n\tsa, err = anyToSockaddr(fd, &rsa)\n\tif err != nil {\n\t\tClose(nfd)\n\t\tnfd = 0\n\t}\n\treturn\n}\n\nfunc recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {\n\tvar msg Msghdr\n\tmsg.Name = (*byte)(unsafe.Pointer(rsa))\n\tmsg.Namelen = uint32(SizeofSockaddrAny)\n\tvar dummy byte\n\tif len(oob) > 0 {\n\t\t// receive at least one normal byte\n\t\tif emptyIovecs(iov) {\n\t\t\tvar iova [1]Iovec\n\t\t\tiova[0].Base = &dummy\n\t\t\tiova[0].SetLen(1)\n\t\t\tiov = iova[:]\n\t\t}\n\t\tmsg.Control = (*byte)(unsafe.Pointer(&oob[0]))\n\t\tmsg.SetControllen(len(oob))\n\t}\n\tif len(iov) > 0 {\n\t\tmsg.Iov = &iov[0]\n\t\tmsg.SetIovlen(len(iov))\n\t}\n\tif n, err = recvmsg(fd, &msg, flags); n == -1 {\n\t\treturn\n\t}\n\toobn = int(msg.Controllen)\n\trecvflags = int(msg.Flags)\n\treturn\n}\n\nfunc sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {\n\tvar msg Msghdr\n\tmsg.Name = (*byte)(unsafe.Pointer(ptr))\n\tmsg.Namelen = uint32(salen)\n\tvar dummy byte\n\tvar empty bool\n\tif len(oob) > 0 {\n\t\t// send at least one normal byte\n\t\tempty = emptyIovecs(iov)\n\t\tif empty {\n\t\t\tvar iova [1]Iovec\n\t\t\tiova[0].Base = &dummy\n\t\t\tiova[0].SetLen(1)\n\t\t\tiov = iova[:]\n\t\t}\n\t\tmsg.Control = (*byte)(unsafe.Pointer(&oob[0]))\n\t\tmsg.SetControllen(len(oob))\n\t}\n\tif len(iov) > 0 {\n\t\tmsg.Iov = &iov[0]\n\t\tmsg.SetIovlen(len(iov))\n\t}\n\tif n, err = sendmsg(fd, &msg, flags); err != nil {\n\t\treturn 0, err\n\t}\n\tif len(oob) > 0 && empty {\n\t\tn = 0\n\t}\n\treturn n, nil\n}\n\nfunc anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {\n\tswitch rsa.Addr.Family {\n\n\tcase AF_UNIX:\n\t\tpp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))\n\t\tsa := new(SockaddrUnix)\n\n\t\t// Some versions of AIX have a bug in getsockname (see IV78655).\n\t\t// We can't rely on sa.Len being set correctly.\n\t\tn := SizeofSockaddrUnix - 3 // subtract leading Family, Len, terminating NUL.\n\t\tfor i := 0; i < n; i++ {\n\t\t\tif pp.Path[i] == 0 {\n\t\t\t\tn = i\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tsa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))\n\t\treturn sa, nil\n\n\tcase AF_INET:\n\t\tpp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))\n\t\tsa := new(SockaddrInet4)\n\t\tp := (*[2]byte)(unsafe.Pointer(&pp.Port))\n\t\tsa.Port = int(p[0])<<8 + int(p[1])\n\t\tsa.Addr = pp.Addr\n\t\treturn sa, nil\n\n\tcase AF_INET6:\n\t\tpp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))\n\t\tsa := new(SockaddrInet6)\n\t\tp := (*[2]byte)(unsafe.Pointer(&pp.Port))\n\t\tsa.Port = int(p[0])<<8 + int(p[1])\n\t\tsa.ZoneId = pp.Scope_id\n\t\tsa.Addr = pp.Addr\n\t\treturn sa, nil\n\t}\n\treturn nil, EAFNOSUPPORT\n}\n\nfunc Gettimeofday(tv *Timeval) (err error) {\n\terr = gettimeofday(tv, nil)\n\treturn\n}\n\nfunc Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\tif raceenabled {\n\t\traceReleaseMerge(unsafe.Pointer(&ioSync))\n\t}\n\treturn sendfile(outfd, infd, offset, count)\n}\n\n// TODO\nfunc sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\treturn -1, ENOSYS\n}\n\nfunc direntIno(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))\n}\n\nfunc direntReclen(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))\n}\n\nfunc direntNamlen(buf []byte) (uint64, bool) {\n\treclen, ok := direntReclen(buf)\n\tif !ok {\n\t\treturn 0, false\n\t}\n\treturn reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true\n}\n\n//sys\tgetdirent(fd int, buf []byte) (n int, err error)\n\nfunc Getdents(fd int, buf []byte) (n int, err error) {\n\treturn getdirent(fd, buf)\n}\n\n//sys\twait4(pid Pid_t, status *_C_int, options int, rusage *Rusage) (wpid Pid_t, err error)\n\nfunc Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {\n\tvar status _C_int\n\tvar r Pid_t\n\terr = ERESTART\n\t// AIX wait4 may return with ERESTART errno, while the process is still\n\t// active.\n\tfor err == ERESTART {\n\t\tr, err = wait4(Pid_t(pid), &status, options, rusage)\n\t}\n\twpid = int(r)\n\tif wstatus != nil {\n\t\t*wstatus = WaitStatus(status)\n\t}\n\treturn\n}\n\n/*\n * Wait\n */\n\ntype WaitStatus uint32\n\nfunc (w WaitStatus) Stopped() bool { return w&0x40 != 0 }\nfunc (w WaitStatus) StopSignal() Signal {\n\tif !w.Stopped() {\n\t\treturn -1\n\t}\n\treturn Signal(w>>8) & 0xFF\n}\n\nfunc (w WaitStatus) Exited() bool { return w&0xFF == 0 }\nfunc (w WaitStatus) ExitStatus() int {\n\tif !w.Exited() {\n\t\treturn -1\n\t}\n\treturn int((w >> 8) & 0xFF)\n}\n\nfunc (w WaitStatus) Signaled() bool { return w&0x40 == 0 && w&0xFF != 0 }\nfunc (w WaitStatus) Signal() Signal {\n\tif !w.Signaled() {\n\t\treturn -1\n\t}\n\treturn Signal(w>>16) & 0xFF\n}\n\nfunc (w WaitStatus) Continued() bool { return w&0x01000000 != 0 }\n\nfunc (w WaitStatus) CoreDump() bool { return w&0x80 == 0x80 }\n\nfunc (w WaitStatus) TrapCause() int { return -1 }\n\n//sys\tioctl(fd int, req int, arg uintptr) (err error)\n//sys\tioctlPtr(fd int, req int, arg unsafe.Pointer) (err error) = ioctl\n\n// fcntl must never be called with cmd=F_DUP2FD because it doesn't work on AIX\n// There is no way to create a custom fcntl and to keep //sys fcntl easily,\n// Therefore, the programmer must call dup2 instead of fcntl in this case.\n\n// FcntlInt performs a fcntl syscall on fd with the provided command and argument.\n//sys\tFcntlInt(fd uintptr, cmd int, arg int) (r int,err error) = fcntl\n\n// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.\n//sys\tFcntlFlock(fd uintptr, cmd int, lk *Flock_t) (err error) = fcntl\n\n//sys\tfcntl(fd int, cmd int, arg int) (val int, err error)\n\n//sys\tfsyncRange(fd int, how int, start int64, length int64) (err error) = fsync_range\n\nfunc Fsync(fd int) error {\n\treturn fsyncRange(fd, O_SYNC, 0, 0)\n}\n\n/*\n * Direct access\n */\n\n//sys\tAcct(path string) (err error)\n//sys\tChdir(path string) (err error)\n//sys\tChroot(path string) (err error)\n//sys\tClose(fd int) (err error)\n//sys\tDup(oldfd int) (fd int, err error)\n//sys\tExit(code int)\n//sys\tFaccessat(dirfd int, path string, mode uint32, flags int) (err error)\n//sys\tFchdir(fd int) (err error)\n//sys\tFchmod(fd int, mode uint32) (err error)\n//sys\tFchmodat(dirfd int, path string, mode uint32, flags int) (err error)\n//sys\tFchownat(dirfd int, path string, uid int, gid int, flags int) (err error)\n//sys\tFdatasync(fd int) (err error)\n// readdir_r\n//sysnb\tGetpgid(pid int) (pgid int, err error)\n\n//sys\tGetpgrp() (pid int)\n\n//sysnb\tGetpid() (pid int)\n//sysnb\tGetppid() (ppid int)\n//sys\tGetpriority(which int, who int) (prio int, err error)\n//sysnb\tGetrusage(who int, rusage *Rusage) (err error)\n//sysnb\tGetsid(pid int) (sid int, err error)\n//sysnb\tKill(pid int, sig Signal) (err error)\n//sys\tKlogctl(typ int, buf []byte) (n int, err error) = syslog\n//sys\tMkdir(dirfd int, path string, mode uint32) (err error)\n//sys\tMkdirat(dirfd int, path string, mode uint32) (err error)\n//sys\tMkfifo(path string, mode uint32) (err error)\n//sys\tMknod(path string, mode uint32, dev int) (err error)\n//sys\tMknodat(dirfd int, path string, mode uint32, dev int) (err error)\n//sys\tNanosleep(time *Timespec, leftover *Timespec) (err error)\n//sys\tOpen(path string, mode int, perm uint32) (fd int, err error) = open64\n//sys\tOpenat(dirfd int, path string, flags int, mode uint32) (fd int, err error)\n//sys\tread(fd int, p []byte) (n int, err error)\n//sys\tReadlink(path string, buf []byte) (n int, err error)\n//sys\tRenameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)\n//sys\tSetdomainname(p []byte) (err error)\n//sys\tSethostname(p []byte) (err error)\n//sysnb\tSetpgid(pid int, pgid int) (err error)\n//sysnb\tSetsid() (pid int, err error)\n//sysnb\tSettimeofday(tv *Timeval) (err error)\n\n//sys\tSetuid(uid int) (err error)\n//sys\tSetgid(uid int) (err error)\n\n//sys\tSetpriority(which int, who int, prio int) (err error)\n//sys\tStatx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error)\n//sys\tSync()\n//sysnb\tTimes(tms *Tms) (ticks uintptr, err error)\n//sysnb\tUmask(mask int) (oldmask int)\n//sysnb\tUname(buf *Utsname) (err error)\n//sys\tUnlink(path string) (err error)\n//sys\tUnlinkat(dirfd int, path string, flags int) (err error)\n//sys\tUstat(dev int, ubuf *Ustat_t) (err error)\n//sys\twrite(fd int, p []byte) (n int, err error)\n\n//sys\tDup2(oldfd int, newfd int) (err error)\n//sys\tFadvise(fd int, offset int64, length int64, advice int) (err error) = posix_fadvise64\n//sys\tFchown(fd int, uid int, gid int) (err error)\n//sys\tfstat(fd int, stat *Stat_t) (err error)\n//sys\tfstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = fstatat\n//sys\tFstatfs(fd int, buf *Statfs_t) (err error)\n//sys\tFtruncate(fd int, length int64) (err error)\n//sysnb\tGetegid() (egid int)\n//sysnb\tGeteuid() (euid int)\n//sysnb\tGetgid() (gid int)\n//sysnb\tGetuid() (uid int)\n//sys\tLchown(path string, uid int, gid int) (err error)\n//sys\tListen(s int, n int) (err error)\n//sys\tlstat(path string, stat *Stat_t) (err error)\n//sys\tPause() (err error)\n//sys\tpread(fd int, p []byte, offset int64) (n int, err error) = pread64\n//sys\tpwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64\n//sys\tSelect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)\n//sys\tPselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error)\n//sysnb\tSetregid(rgid int, egid int) (err error)\n//sysnb\tSetreuid(ruid int, euid int) (err error)\n//sys\tShutdown(fd int, how int) (err error)\n//sys\tSplice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)\n//sys\tstat(path string, statptr *Stat_t) (err error)\n//sys\tStatfs(path string, buf *Statfs_t) (err error)\n//sys\tTruncate(path string, length int64) (err error)\n\n//sys\tbind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\tconnect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sysnb\tgetgroups(n int, list *_Gid_t) (nn int, err error)\n//sysnb\tsetgroups(n int, list *_Gid_t) (err error)\n//sys\tgetsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)\n//sys\tsetsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)\n//sysnb\tsocket(domain int, typ int, proto int) (fd int, err error)\n//sysnb\tsocketpair(domain int, typ int, proto int, fd *[2]int32) (err error)\n//sysnb\tgetpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sysnb\tgetsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sys\trecvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)\n//sys\tsendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)\n\n// In order to use msghdr structure with Control, Controllen, nrecvmsg and nsendmsg must be used.\n//sys\trecvmsg(s int, msg *Msghdr, flags int) (n int, err error) = nrecvmsg\n//sys\tsendmsg(s int, msg *Msghdr, flags int) (n int, err error) = nsendmsg\n\n//sys\tmunmap(addr uintptr, length uintptr) (err error)\n//sys\tMadvise(b []byte, advice int) (err error)\n//sys\tMprotect(b []byte, prot int) (err error)\n//sys\tMlock(b []byte) (err error)\n//sys\tMlockall(flags int) (err error)\n//sys\tMsync(b []byte, flags int) (err error)\n//sys\tMunlock(b []byte) (err error)\n//sys\tMunlockall() (err error)\n\n//sysnb\tpipe(p *[2]_C_int) (err error)\n\nfunc Pipe(p []int) (err error) {\n\tif len(p) != 2 {\n\t\treturn EINVAL\n\t}\n\tvar pp [2]_C_int\n\terr = pipe(&pp)\n\tif err == nil {\n\t\tp[0] = int(pp[0])\n\t\tp[1] = int(pp[1])\n\t}\n\treturn\n}\n\n//sys\tpoll(fds *PollFd, nfds int, timeout int) (n int, err error)\n\nfunc Poll(fds []PollFd, timeout int) (n int, err error) {\n\tif len(fds) == 0 {\n\t\treturn poll(nil, 0, timeout)\n\t}\n\treturn poll(&fds[0], len(fds), timeout)\n}\n\n//sys\tgettimeofday(tv *Timeval, tzp *Timezone) (err error)\n//sysnb\tTime(t *Time_t) (tt Time_t, err error)\n//sys\tUtime(path string, buf *Utimbuf) (err error)\n\n//sys\tGetsystemcfg(label int) (n uint64)\n\n//sys\tumount(target string) (err error)\n\nfunc Unmount(target string, flags int) (err error) {\n\tif flags != 0 {\n\t\t// AIX doesn't have any flags for umount.\n\t\treturn ENOSYS\n\t}\n\treturn umount(target)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_aix_ppc.go",
    "content": "// Copyright 2018 The Go 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\n//go:build aix && ppc\n\npackage unix\n\n//sysnb\tGetrlimit(resource int, rlim *Rlimit) (err error) = getrlimit64\n//sys\tSeek(fd int, offset int64, whence int) (off int64, err error) = lseek64\n\n//sys\tmmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: int32(sec), Nsec: int32(nsec)}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: int32(sec), Usec: int32(usec)}\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = int32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\nfunc Fstat(fd int, stat *Stat_t) error {\n\treturn fstat(fd, stat)\n}\n\nfunc Fstatat(dirfd int, path string, stat *Stat_t, flags int) error {\n\treturn fstatat(dirfd, path, stat, flags)\n}\n\nfunc Lstat(path string, stat *Stat_t) error {\n\treturn lstat(path, stat)\n}\n\nfunc Stat(path string, statptr *Stat_t) error {\n\treturn stat(path, statptr)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_aix_ppc64.go",
    "content": "// Copyright 2018 The Go 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\n//go:build aix && ppc64\n\npackage unix\n\n//sysnb\tGetrlimit(resource int, rlim *Rlimit) (err error)\n//sys\tSeek(fd int, offset int64, whence int) (off int64, err error) = lseek\n\n//sys\tmmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) = mmap64\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: int64(sec), Usec: int32(usec)}\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = int32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\n// In order to only have Timespec structure, type of Stat_t's fields\n// Atim, Mtim and Ctim is changed from StTimespec to Timespec during\n// ztypes generation.\n// On ppc64, Timespec.Nsec is an int64 while StTimespec.Nsec is an\n// int32, so the fields' value must be modified.\nfunc fixStatTimFields(stat *Stat_t) {\n\tstat.Atim.Nsec >>= 32\n\tstat.Mtim.Nsec >>= 32\n\tstat.Ctim.Nsec >>= 32\n}\n\nfunc Fstat(fd int, stat *Stat_t) error {\n\terr := fstat(fd, stat)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfixStatTimFields(stat)\n\treturn nil\n}\n\nfunc Fstatat(dirfd int, path string, stat *Stat_t, flags int) error {\n\terr := fstatat(dirfd, path, stat, flags)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfixStatTimFields(stat)\n\treturn nil\n}\n\nfunc Lstat(path string, stat *Stat_t) error {\n\terr := lstat(path, stat)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfixStatTimFields(stat)\n\treturn nil\n}\n\nfunc Stat(path string, statptr *Stat_t) error {\n\terr := stat(path, statptr)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfixStatTimFields(statptr)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_bsd.go",
    "content": "// Copyright 2009 The Go 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\n//go:build darwin || dragonfly || freebsd || netbsd || openbsd\n\n// BSD system call wrappers shared by *BSD based systems\n// including OS X (Darwin) and FreeBSD.  Like the other\n// syscall_*.go files it is compiled as Go code but also\n// used as input to mksyscall which parses the //sys\n// lines and generates system call stubs.\n\npackage unix\n\nimport (\n\t\"runtime\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nconst ImplementsGetwd = true\n\nfunc Getwd() (string, error) {\n\tvar buf [PathMax]byte\n\t_, err := Getcwd(buf[0:])\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tn := clen(buf[:])\n\tif n < 1 {\n\t\treturn \"\", EINVAL\n\t}\n\treturn string(buf[:n]), nil\n}\n\n/*\n * Wrapped\n */\n\n//sysnb\tgetgroups(ngid int, gid *_Gid_t) (n int, err error)\n//sysnb\tsetgroups(ngid int, gid *_Gid_t) (err error)\n\nfunc Getgroups() (gids []int, err error) {\n\tn, err := getgroups(0, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif n == 0 {\n\t\treturn nil, nil\n\t}\n\n\t// Sanity check group count. Max is 16 on BSD.\n\tif n < 0 || n > 1000 {\n\t\treturn nil, EINVAL\n\t}\n\n\ta := make([]_Gid_t, n)\n\tn, err = getgroups(n, &a[0])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tgids = make([]int, n)\n\tfor i, v := range a[0:n] {\n\t\tgids[i] = int(v)\n\t}\n\treturn\n}\n\nfunc Setgroups(gids []int) (err error) {\n\tif len(gids) == 0 {\n\t\treturn setgroups(0, nil)\n\t}\n\n\ta := make([]_Gid_t, len(gids))\n\tfor i, v := range gids {\n\t\ta[i] = _Gid_t(v)\n\t}\n\treturn setgroups(len(a), &a[0])\n}\n\n// Wait status is 7 bits at bottom, either 0 (exited),\n// 0x7F (stopped), or a signal number that caused an exit.\n// The 0x80 bit is whether there was a core dump.\n// An extra number (exit code, signal causing a stop)\n// is in the high bits.\n\ntype WaitStatus uint32\n\nconst (\n\tmask  = 0x7F\n\tcore  = 0x80\n\tshift = 8\n\n\texited  = 0\n\tkilled  = 9\n\tstopped = 0x7F\n)\n\nfunc (w WaitStatus) Exited() bool { return w&mask == exited }\n\nfunc (w WaitStatus) ExitStatus() int {\n\tif w&mask != exited {\n\t\treturn -1\n\t}\n\treturn int(w >> shift)\n}\n\nfunc (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }\n\nfunc (w WaitStatus) Signal() syscall.Signal {\n\tsig := syscall.Signal(w & mask)\n\tif sig == stopped || sig == 0 {\n\t\treturn -1\n\t}\n\treturn sig\n}\n\nfunc (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }\n\nfunc (w WaitStatus) Stopped() bool { return w&mask == stopped && syscall.Signal(w>>shift) != SIGSTOP }\n\nfunc (w WaitStatus) Killed() bool { return w&mask == killed && syscall.Signal(w>>shift) != SIGKILL }\n\nfunc (w WaitStatus) Continued() bool { return w&mask == stopped && syscall.Signal(w>>shift) == SIGSTOP }\n\nfunc (w WaitStatus) StopSignal() syscall.Signal {\n\tif !w.Stopped() {\n\t\treturn -1\n\t}\n\treturn syscall.Signal(w>>shift) & 0xFF\n}\n\nfunc (w WaitStatus) TrapCause() int { return -1 }\n\n//sys\twait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)\n\nfunc Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {\n\tvar status _C_int\n\twpid, err = wait4(pid, &status, options, rusage)\n\tif wstatus != nil {\n\t\t*wstatus = WaitStatus(status)\n\t}\n\treturn\n}\n\n//sys\taccept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)\n//sys\tbind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\tconnect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sysnb\tsocket(domain int, typ int, proto int) (fd int, err error)\n//sys\tgetsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)\n//sys\tsetsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)\n//sysnb\tgetpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sysnb\tgetsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sys\tShutdown(s int, how int) (err error)\n\nfunc (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tif sa.Port < 0 || sa.Port > 0xFFFF {\n\t\treturn nil, 0, EINVAL\n\t}\n\tsa.raw.Len = SizeofSockaddrInet4\n\tsa.raw.Family = AF_INET\n\tp := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))\n\tp[0] = byte(sa.Port >> 8)\n\tp[1] = byte(sa.Port)\n\tsa.raw.Addr = sa.Addr\n\treturn unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil\n}\n\nfunc (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tif sa.Port < 0 || sa.Port > 0xFFFF {\n\t\treturn nil, 0, EINVAL\n\t}\n\tsa.raw.Len = SizeofSockaddrInet6\n\tsa.raw.Family = AF_INET6\n\tp := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))\n\tp[0] = byte(sa.Port >> 8)\n\tp[1] = byte(sa.Port)\n\tsa.raw.Scope_id = sa.ZoneId\n\tsa.raw.Addr = sa.Addr\n\treturn unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil\n}\n\nfunc (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tname := sa.Name\n\tn := len(name)\n\tif n >= len(sa.raw.Path) || n == 0 {\n\t\treturn nil, 0, EINVAL\n\t}\n\tsa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL\n\tsa.raw.Family = AF_UNIX\n\tfor i := 0; i < n; i++ {\n\t\tsa.raw.Path[i] = int8(name[i])\n\t}\n\treturn unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil\n}\n\nfunc (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tif sa.Index == 0 {\n\t\treturn nil, 0, EINVAL\n\t}\n\tsa.raw.Len = sa.Len\n\tsa.raw.Family = AF_LINK\n\tsa.raw.Index = sa.Index\n\tsa.raw.Type = sa.Type\n\tsa.raw.Nlen = sa.Nlen\n\tsa.raw.Alen = sa.Alen\n\tsa.raw.Slen = sa.Slen\n\tsa.raw.Data = sa.Data\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil\n}\n\nfunc anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {\n\tswitch rsa.Addr.Family {\n\tcase AF_LINK:\n\t\tpp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa))\n\t\tsa := new(SockaddrDatalink)\n\t\tsa.Len = pp.Len\n\t\tsa.Family = pp.Family\n\t\tsa.Index = pp.Index\n\t\tsa.Type = pp.Type\n\t\tsa.Nlen = pp.Nlen\n\t\tsa.Alen = pp.Alen\n\t\tsa.Slen = pp.Slen\n\t\tsa.Data = pp.Data\n\t\treturn sa, nil\n\n\tcase AF_UNIX:\n\t\tpp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))\n\t\tif pp.Len < 2 || pp.Len > SizeofSockaddrUnix {\n\t\t\treturn nil, EINVAL\n\t\t}\n\t\tsa := new(SockaddrUnix)\n\n\t\t// Some BSDs include the trailing NUL in the length, whereas\n\t\t// others do not. Work around this by subtracting the leading\n\t\t// family and len. The path is then scanned to see if a NUL\n\t\t// terminator still exists within the length.\n\t\tn := int(pp.Len) - 2 // subtract leading Family, Len\n\t\tfor i := 0; i < n; i++ {\n\t\t\tif pp.Path[i] == 0 {\n\t\t\t\t// found early NUL; assume Len included the NUL\n\t\t\t\t// or was overestimating.\n\t\t\t\tn = i\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tsa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))\n\t\treturn sa, nil\n\n\tcase AF_INET:\n\t\tpp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))\n\t\tsa := new(SockaddrInet4)\n\t\tp := (*[2]byte)(unsafe.Pointer(&pp.Port))\n\t\tsa.Port = int(p[0])<<8 + int(p[1])\n\t\tsa.Addr = pp.Addr\n\t\treturn sa, nil\n\n\tcase AF_INET6:\n\t\tpp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))\n\t\tsa := new(SockaddrInet6)\n\t\tp := (*[2]byte)(unsafe.Pointer(&pp.Port))\n\t\tsa.Port = int(p[0])<<8 + int(p[1])\n\t\tsa.ZoneId = pp.Scope_id\n\t\tsa.Addr = pp.Addr\n\t\treturn sa, nil\n\t}\n\treturn anyToSockaddrGOOS(fd, rsa)\n}\n\nfunc Accept(fd int) (nfd int, sa Sockaddr, err error) {\n\tvar rsa RawSockaddrAny\n\tvar len _Socklen = SizeofSockaddrAny\n\tnfd, err = accept(fd, &rsa, &len)\n\tif err != nil {\n\t\treturn\n\t}\n\tif (runtime.GOOS == \"darwin\" || runtime.GOOS == \"ios\") && len == 0 {\n\t\t// Accepted socket has no address.\n\t\t// This is likely due to a bug in xnu kernels,\n\t\t// where instead of ECONNABORTED error socket\n\t\t// is accepted, but has no address.\n\t\tClose(nfd)\n\t\treturn 0, nil, ECONNABORTED\n\t}\n\tsa, err = anyToSockaddr(fd, &rsa)\n\tif err != nil {\n\t\tClose(nfd)\n\t\tnfd = 0\n\t}\n\treturn\n}\n\nfunc Getsockname(fd int) (sa Sockaddr, err error) {\n\tvar rsa RawSockaddrAny\n\tvar len _Socklen = SizeofSockaddrAny\n\tif err = getsockname(fd, &rsa, &len); err != nil {\n\t\treturn\n\t}\n\t// TODO(jsing): DragonFly has a \"bug\" (see issue 3349), which should be\n\t// reported upstream.\n\tif runtime.GOOS == \"dragonfly\" && rsa.Addr.Family == AF_UNSPEC && rsa.Addr.Len == 0 {\n\t\trsa.Addr.Family = AF_UNIX\n\t\trsa.Addr.Len = SizeofSockaddrUnix\n\t}\n\treturn anyToSockaddr(fd, &rsa)\n}\n\n//sysnb\tsocketpair(domain int, typ int, proto int, fd *[2]int32) (err error)\n\n// GetsockoptString returns the string value of the socket option opt for the\n// socket associated with fd at the given socket level.\nfunc GetsockoptString(fd, level, opt int) (string, error) {\n\tbuf := make([]byte, 256)\n\tvallen := _Socklen(len(buf))\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn ByteSliceToString(buf[:vallen]), nil\n}\n\n//sys\trecvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)\n//sys\tsendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\trecvmsg(s int, msg *Msghdr, flags int) (n int, err error)\n\nfunc recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {\n\tvar msg Msghdr\n\tmsg.Name = (*byte)(unsafe.Pointer(rsa))\n\tmsg.Namelen = uint32(SizeofSockaddrAny)\n\tvar dummy byte\n\tif len(oob) > 0 {\n\t\t// receive at least one normal byte\n\t\tif emptyIovecs(iov) {\n\t\t\tvar iova [1]Iovec\n\t\t\tiova[0].Base = &dummy\n\t\t\tiova[0].SetLen(1)\n\t\t\tiov = iova[:]\n\t\t}\n\t\tmsg.Control = (*byte)(unsafe.Pointer(&oob[0]))\n\t\tmsg.SetControllen(len(oob))\n\t}\n\tif len(iov) > 0 {\n\t\tmsg.Iov = &iov[0]\n\t\tmsg.SetIovlen(len(iov))\n\t}\n\tif n, err = recvmsg(fd, &msg, flags); err != nil {\n\t\treturn\n\t}\n\toobn = int(msg.Controllen)\n\trecvflags = int(msg.Flags)\n\treturn\n}\n\n//sys\tsendmsg(s int, msg *Msghdr, flags int) (n int, err error)\n\nfunc sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {\n\tvar msg Msghdr\n\tmsg.Name = (*byte)(unsafe.Pointer(ptr))\n\tmsg.Namelen = uint32(salen)\n\tvar dummy byte\n\tvar empty bool\n\tif len(oob) > 0 {\n\t\t// send at least one normal byte\n\t\tempty = emptyIovecs(iov)\n\t\tif empty {\n\t\t\tvar iova [1]Iovec\n\t\t\tiova[0].Base = &dummy\n\t\t\tiova[0].SetLen(1)\n\t\t\tiov = iova[:]\n\t\t}\n\t\tmsg.Control = (*byte)(unsafe.Pointer(&oob[0]))\n\t\tmsg.SetControllen(len(oob))\n\t}\n\tif len(iov) > 0 {\n\t\tmsg.Iov = &iov[0]\n\t\tmsg.SetIovlen(len(iov))\n\t}\n\tif n, err = sendmsg(fd, &msg, flags); err != nil {\n\t\treturn 0, err\n\t}\n\tif len(oob) > 0 && empty {\n\t\tn = 0\n\t}\n\treturn n, nil\n}\n\n//sys\tkevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error)\n\nfunc Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, err error) {\n\tvar change, event unsafe.Pointer\n\tif len(changes) > 0 {\n\t\tchange = unsafe.Pointer(&changes[0])\n\t}\n\tif len(events) > 0 {\n\t\tevent = unsafe.Pointer(&events[0])\n\t}\n\treturn kevent(kq, change, len(changes), event, len(events), timeout)\n}\n\n// sysctlmib translates name to mib number and appends any additional args.\nfunc sysctlmib(name string, args ...int) ([]_C_int, error) {\n\t// Translate name to mib number.\n\tmib, err := nametomib(name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, a := range args {\n\t\tmib = append(mib, _C_int(a))\n\t}\n\n\treturn mib, nil\n}\n\nfunc Sysctl(name string) (string, error) {\n\treturn SysctlArgs(name)\n}\n\nfunc SysctlArgs(name string, args ...int) (string, error) {\n\tbuf, err := SysctlRaw(name, args...)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tn := len(buf)\n\n\t// Throw away terminating NUL.\n\tif n > 0 && buf[n-1] == '\\x00' {\n\t\tn--\n\t}\n\treturn string(buf[0:n]), nil\n}\n\nfunc SysctlUint32(name string) (uint32, error) {\n\treturn SysctlUint32Args(name)\n}\n\nfunc SysctlUint32Args(name string, args ...int) (uint32, error) {\n\tmib, err := sysctlmib(name, args...)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tn := uintptr(4)\n\tbuf := make([]byte, 4)\n\tif err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {\n\t\treturn 0, err\n\t}\n\tif n != 4 {\n\t\treturn 0, EIO\n\t}\n\treturn *(*uint32)(unsafe.Pointer(&buf[0])), nil\n}\n\nfunc SysctlUint64(name string, args ...int) (uint64, error) {\n\tmib, err := sysctlmib(name, args...)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tn := uintptr(8)\n\tbuf := make([]byte, 8)\n\tif err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {\n\t\treturn 0, err\n\t}\n\tif n != 8 {\n\t\treturn 0, EIO\n\t}\n\treturn *(*uint64)(unsafe.Pointer(&buf[0])), nil\n}\n\nfunc SysctlRaw(name string, args ...int) ([]byte, error) {\n\tmib, err := sysctlmib(name, args...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Find size.\n\tn := uintptr(0)\n\tif err := sysctl(mib, nil, &n, nil, 0); err != nil {\n\t\treturn nil, err\n\t}\n\tif n == 0 {\n\t\treturn nil, nil\n\t}\n\n\t// Read into buffer of that size.\n\tbuf := make([]byte, n)\n\tif err := sysctl(mib, &buf[0], &n, nil, 0); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// The actual call may return less than the original reported required\n\t// size so ensure we deal with that.\n\treturn buf[:n], nil\n}\n\nfunc SysctlClockinfo(name string) (*Clockinfo, error) {\n\tmib, err := sysctlmib(name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tn := uintptr(SizeofClockinfo)\n\tvar ci Clockinfo\n\tif err := sysctl(mib, (*byte)(unsafe.Pointer(&ci)), &n, nil, 0); err != nil {\n\t\treturn nil, err\n\t}\n\tif n != SizeofClockinfo {\n\t\treturn nil, EIO\n\t}\n\treturn &ci, nil\n}\n\nfunc SysctlTimeval(name string) (*Timeval, error) {\n\tmib, err := sysctlmib(name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar tv Timeval\n\tn := uintptr(unsafe.Sizeof(tv))\n\tif err := sysctl(mib, (*byte)(unsafe.Pointer(&tv)), &n, nil, 0); err != nil {\n\t\treturn nil, err\n\t}\n\tif n != unsafe.Sizeof(tv) {\n\t\treturn nil, EIO\n\t}\n\treturn &tv, nil\n}\n\n//sys\tutimes(path string, timeval *[2]Timeval) (err error)\n\nfunc Utimes(path string, tv []Timeval) error {\n\tif tv == nil {\n\t\treturn utimes(path, nil)\n\t}\n\tif len(tv) != 2 {\n\t\treturn EINVAL\n\t}\n\treturn utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))\n}\n\nfunc UtimesNano(path string, ts []Timespec) error {\n\tif ts == nil {\n\t\terr := utimensat(AT_FDCWD, path, nil, 0)\n\t\tif err != ENOSYS {\n\t\t\treturn err\n\t\t}\n\t\treturn utimes(path, nil)\n\t}\n\tif len(ts) != 2 {\n\t\treturn EINVAL\n\t}\n\terr := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)\n\tif err != ENOSYS {\n\t\treturn err\n\t}\n\t// Not as efficient as it could be because Timespec and\n\t// Timeval have different types in the different OSes\n\ttv := [2]Timeval{\n\t\tNsecToTimeval(TimespecToNsec(ts[0])),\n\t\tNsecToTimeval(TimespecToNsec(ts[1])),\n\t}\n\treturn utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))\n}\n\nfunc UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {\n\tif ts == nil {\n\t\treturn utimensat(dirfd, path, nil, flags)\n\t}\n\tif len(ts) != 2 {\n\t\treturn EINVAL\n\t}\n\treturn utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)\n}\n\n//sys\tfutimes(fd int, timeval *[2]Timeval) (err error)\n\nfunc Futimes(fd int, tv []Timeval) error {\n\tif tv == nil {\n\t\treturn futimes(fd, nil)\n\t}\n\tif len(tv) != 2 {\n\t\treturn EINVAL\n\t}\n\treturn futimes(fd, (*[2]Timeval)(unsafe.Pointer(&tv[0])))\n}\n\n//sys\tpoll(fds *PollFd, nfds int, timeout int) (n int, err error)\n\nfunc Poll(fds []PollFd, timeout int) (n int, err error) {\n\tif len(fds) == 0 {\n\t\treturn poll(nil, 0, timeout)\n\t}\n\treturn poll(&fds[0], len(fds), timeout)\n}\n\n// TODO: wrap\n//\tAcct(name nil-string) (err error)\n//\tGethostuuid(uuid *byte, timeout *Timespec) (err error)\n//\tPtrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error)\n\n//sys\tMadvise(b []byte, behav int) (err error)\n//sys\tMlock(b []byte) (err error)\n//sys\tMlockall(flags int) (err error)\n//sys\tMprotect(b []byte, prot int) (err error)\n//sys\tMsync(b []byte, flags int) (err error)\n//sys\tMunlock(b []byte) (err error)\n//sys\tMunlockall() (err error)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_darwin.go",
    "content": "// Copyright 2009,2010 The Go 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\n// Darwin system calls.\n// This file is compiled as ordinary Go code,\n// but it is also input to mksyscall,\n// which parses the //sys lines and generates system call stubs.\n// Note that sometimes we use a lowercase //sys name and wrap\n// it in our own nicer implementation, either here or in\n// syscall_bsd.go or syscall_unix.go.\n\npackage unix\n\nimport (\n\t\"fmt\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n//sys\tclosedir(dir uintptr) (err error)\n//sys\treaddir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno)\n\nfunc fdopendir(fd int) (dir uintptr, err error) {\n\tr0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0)\n\tdir = uintptr(r0)\n\tif e1 != 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nvar libc_fdopendir_trampoline_addr uintptr\n\n//go:cgo_import_dynamic libc_fdopendir fdopendir \"/usr/lib/libSystem.B.dylib\"\n\nfunc Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {\n\t// Simulate Getdirentries using fdopendir/readdir_r/closedir.\n\t// We store the number of entries to skip in the seek\n\t// offset of fd. See issue #31368.\n\t// It's not the full required semantics, but should handle the case\n\t// of calling Getdirentries or ReadDirent repeatedly.\n\t// It won't handle assigning the results of lseek to *basep, or handle\n\t// the directory being edited underfoot.\n\tskip, err := Seek(fd, 0, 1 /* SEEK_CUR */)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\t// We need to duplicate the incoming file descriptor\n\t// because the caller expects to retain control of it, but\n\t// fdopendir expects to take control of its argument.\n\t// Just Dup'ing the file descriptor is not enough, as the\n\t// result shares underlying state. Use Openat to make a really\n\t// new file descriptor referring to the same directory.\n\tfd2, err := Openat(fd, \".\", O_RDONLY, 0)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\td, err := fdopendir(fd2)\n\tif err != nil {\n\t\tClose(fd2)\n\t\treturn 0, err\n\t}\n\tdefer closedir(d)\n\n\tvar cnt int64\n\tfor {\n\t\tvar entry Dirent\n\t\tvar entryp *Dirent\n\t\te := readdir_r(d, &entry, &entryp)\n\t\tif e != 0 {\n\t\t\treturn n, errnoErr(e)\n\t\t}\n\t\tif entryp == nil {\n\t\t\tbreak\n\t\t}\n\t\tif skip > 0 {\n\t\t\tskip--\n\t\t\tcnt++\n\t\t\tcontinue\n\t\t}\n\n\t\treclen := int(entry.Reclen)\n\t\tif reclen > len(buf) {\n\t\t\t// Not enough room. Return for now.\n\t\t\t// The counter will let us know where we should start up again.\n\t\t\t// Note: this strategy for suspending in the middle and\n\t\t\t// restarting is O(n^2) in the length of the directory. Oh well.\n\t\t\tbreak\n\t\t}\n\n\t\t// Copy entry into return buffer.\n\t\ts := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)\n\t\tcopy(buf, s)\n\n\t\tbuf = buf[reclen:]\n\t\tn += reclen\n\t\tcnt++\n\t}\n\t// Set the seek offset of the input fd to record\n\t// how many files we've already returned.\n\t_, err = Seek(fd, cnt, 0 /* SEEK_SET */)\n\tif err != nil {\n\t\treturn n, err\n\t}\n\n\treturn n, nil\n}\n\n// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.\ntype SockaddrDatalink struct {\n\tLen    uint8\n\tFamily uint8\n\tIndex  uint16\n\tType   uint8\n\tNlen   uint8\n\tAlen   uint8\n\tSlen   uint8\n\tData   [12]int8\n\traw    RawSockaddrDatalink\n}\n\n// SockaddrCtl implements the Sockaddr interface for AF_SYSTEM type sockets.\ntype SockaddrCtl struct {\n\tID   uint32\n\tUnit uint32\n\traw  RawSockaddrCtl\n}\n\nfunc (sa *SockaddrCtl) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tsa.raw.Sc_len = SizeofSockaddrCtl\n\tsa.raw.Sc_family = AF_SYSTEM\n\tsa.raw.Ss_sysaddr = AF_SYS_CONTROL\n\tsa.raw.Sc_id = sa.ID\n\tsa.raw.Sc_unit = sa.Unit\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrCtl, nil\n}\n\n// SockaddrVM implements the Sockaddr interface for AF_VSOCK type sockets.\n// SockaddrVM provides access to Darwin VM sockets: a mechanism that enables\n// bidirectional communication between a hypervisor and its guest virtual\n// machines.\ntype SockaddrVM struct {\n\t// CID and Port specify a context ID and port address for a VM socket.\n\t// Guests have a unique CID, and hosts may have a well-known CID of:\n\t//  - VMADDR_CID_HYPERVISOR: refers to the hypervisor process.\n\t//  - VMADDR_CID_LOCAL: refers to local communication (loopback).\n\t//  - VMADDR_CID_HOST: refers to other processes on the host.\n\tCID  uint32\n\tPort uint32\n\traw  RawSockaddrVM\n}\n\nfunc (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tsa.raw.Len = SizeofSockaddrVM\n\tsa.raw.Family = AF_VSOCK\n\tsa.raw.Port = sa.Port\n\tsa.raw.Cid = sa.CID\n\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil\n}\n\nfunc anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {\n\tswitch rsa.Addr.Family {\n\tcase AF_SYSTEM:\n\t\tpp := (*RawSockaddrCtl)(unsafe.Pointer(rsa))\n\t\tif pp.Ss_sysaddr == AF_SYS_CONTROL {\n\t\t\tsa := new(SockaddrCtl)\n\t\t\tsa.ID = pp.Sc_id\n\t\t\tsa.Unit = pp.Sc_unit\n\t\t\treturn sa, nil\n\t\t}\n\tcase AF_VSOCK:\n\t\tpp := (*RawSockaddrVM)(unsafe.Pointer(rsa))\n\t\tsa := &SockaddrVM{\n\t\t\tCID:  pp.Cid,\n\t\t\tPort: pp.Port,\n\t\t}\n\t\treturn sa, nil\n\t}\n\treturn nil, EAFNOSUPPORT\n}\n\n// Some external packages rely on SYS___SYSCTL being defined to implement their\n// own sysctl wrappers. Provide it here, even though direct syscalls are no\n// longer supported on darwin.\nconst SYS___SYSCTL = SYS_SYSCTL\n\n// Translate \"kern.hostname\" to []_C_int{0,1,2,3}.\nfunc nametomib(name string) (mib []_C_int, err error) {\n\tconst siz = unsafe.Sizeof(mib[0])\n\n\t// NOTE(rsc): It seems strange to set the buffer to have\n\t// size CTL_MAXNAME+2 but use only CTL_MAXNAME\n\t// as the size. I don't know why the +2 is here, but the\n\t// kernel uses +2 for its own implementation of this function.\n\t// I am scared that if we don't include the +2 here, the kernel\n\t// will silently write 2 words farther than we specify\n\t// and we'll get memory corruption.\n\tvar buf [CTL_MAXNAME + 2]_C_int\n\tn := uintptr(CTL_MAXNAME) * siz\n\n\tp := (*byte)(unsafe.Pointer(&buf[0]))\n\tbytes, err := ByteSliceFromString(name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Magic sysctl: \"setting\" 0.3 to a string name\n\t// lets you read back the array of integers form.\n\tif err = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); err != nil {\n\t\treturn nil, err\n\t}\n\treturn buf[0 : n/siz], nil\n}\n\nfunc direntIno(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))\n}\n\nfunc direntReclen(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))\n}\n\nfunc direntNamlen(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))\n}\n\nfunc PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }\nfunc PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }\nfunc PtraceDenyAttach() (err error)    { return ptrace(PT_DENY_ATTACH, 0, 0, 0) }\n\n//sysnb\tpipe(p *[2]int32) (err error)\n\nfunc Pipe(p []int) (err error) {\n\tif len(p) != 2 {\n\t\treturn EINVAL\n\t}\n\tvar x [2]int32\n\terr = pipe(&x)\n\tif err == nil {\n\t\tp[0] = int(x[0])\n\t\tp[1] = int(x[1])\n\t}\n\treturn\n}\n\nfunc Getfsstat(buf []Statfs_t, flags int) (n int, err error) {\n\tvar _p0 unsafe.Pointer\n\tvar bufsize uintptr\n\tif len(buf) > 0 {\n\t\t_p0 = unsafe.Pointer(&buf[0])\n\t\tbufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))\n\t}\n\treturn getfsstat(_p0, bufsize, flags)\n}\n\nfunc xattrPointer(dest []byte) *byte {\n\t// It's only when dest is set to NULL that the OS X implementations of\n\t// getxattr() and listxattr() return the current sizes of the named attributes.\n\t// An empty byte array is not sufficient. To maintain the same behaviour as the\n\t// linux implementation, we wrap around the system calls and pass in NULL when\n\t// dest is empty.\n\tvar destp *byte\n\tif len(dest) > 0 {\n\t\tdestp = &dest[0]\n\t}\n\treturn destp\n}\n\n//sys\tgetxattr(path string, attr string, dest *byte, size int, position uint32, options int) (sz int, err error)\n\nfunc Getxattr(path string, attr string, dest []byte) (sz int, err error) {\n\treturn getxattr(path, attr, xattrPointer(dest), len(dest), 0, 0)\n}\n\nfunc Lgetxattr(link string, attr string, dest []byte) (sz int, err error) {\n\treturn getxattr(link, attr, xattrPointer(dest), len(dest), 0, XATTR_NOFOLLOW)\n}\n\n//sys\tfgetxattr(fd int, attr string, dest *byte, size int, position uint32, options int) (sz int, err error)\n\nfunc Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) {\n\treturn fgetxattr(fd, attr, xattrPointer(dest), len(dest), 0, 0)\n}\n\n//sys\tsetxattr(path string, attr string, data *byte, size int, position uint32, options int) (err error)\n\nfunc Setxattr(path string, attr string, data []byte, flags int) (err error) {\n\t// The parameters for the OS X implementation vary slightly compared to the\n\t// linux system call, specifically the position parameter:\n\t//\n\t//  linux:\n\t//      int setxattr(\n\t//          const char *path,\n\t//          const char *name,\n\t//          const void *value,\n\t//          size_t size,\n\t//          int flags\n\t//      );\n\t//\n\t//  darwin:\n\t//      int setxattr(\n\t//          const char *path,\n\t//          const char *name,\n\t//          void *value,\n\t//          size_t size,\n\t//          u_int32_t position,\n\t//          int options\n\t//      );\n\t//\n\t// position specifies the offset within the extended attribute. In the\n\t// current implementation, only the resource fork extended attribute makes\n\t// use of this argument. For all others, position is reserved. We simply\n\t// default to setting it to zero.\n\treturn setxattr(path, attr, xattrPointer(data), len(data), 0, flags)\n}\n\nfunc Lsetxattr(link string, attr string, data []byte, flags int) (err error) {\n\treturn setxattr(link, attr, xattrPointer(data), len(data), 0, flags|XATTR_NOFOLLOW)\n}\n\n//sys\tfsetxattr(fd int, attr string, data *byte, size int, position uint32, options int) (err error)\n\nfunc Fsetxattr(fd int, attr string, data []byte, flags int) (err error) {\n\treturn fsetxattr(fd, attr, xattrPointer(data), len(data), 0, 0)\n}\n\n//sys\tremovexattr(path string, attr string, options int) (err error)\n\nfunc Removexattr(path string, attr string) (err error) {\n\t// We wrap around and explicitly zero out the options provided to the OS X\n\t// implementation of removexattr, we do so for interoperability with the\n\t// linux variant.\n\treturn removexattr(path, attr, 0)\n}\n\nfunc Lremovexattr(link string, attr string) (err error) {\n\treturn removexattr(link, attr, XATTR_NOFOLLOW)\n}\n\n//sys\tfremovexattr(fd int, attr string, options int) (err error)\n\nfunc Fremovexattr(fd int, attr string) (err error) {\n\treturn fremovexattr(fd, attr, 0)\n}\n\n//sys\tlistxattr(path string, dest *byte, size int, options int) (sz int, err error)\n\nfunc Listxattr(path string, dest []byte) (sz int, err error) {\n\treturn listxattr(path, xattrPointer(dest), len(dest), 0)\n}\n\nfunc Llistxattr(link string, dest []byte) (sz int, err error) {\n\treturn listxattr(link, xattrPointer(dest), len(dest), XATTR_NOFOLLOW)\n}\n\n//sys\tflistxattr(fd int, dest *byte, size int, options int) (sz int, err error)\n\nfunc Flistxattr(fd int, dest []byte) (sz int, err error) {\n\treturn flistxattr(fd, xattrPointer(dest), len(dest), 0)\n}\n\n//sys\tutimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)\n\n/*\n * Wrapped\n */\n\n//sys\tfcntl(fd int, cmd int, arg int) (val int, err error)\n\n//sys\tkill(pid int, signum int, posix int) (err error)\n\nfunc Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(signum), 1) }\n\n//sys\tioctl(fd int, req uint, arg uintptr) (err error)\n//sys\tioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL\n\nfunc IoctlCtlInfo(fd int, ctlInfo *CtlInfo) error {\n\treturn ioctlPtr(fd, CTLIOCGINFO, unsafe.Pointer(ctlInfo))\n}\n\n// IfreqMTU is struct ifreq used to get or set a network device's MTU.\ntype IfreqMTU struct {\n\tName [IFNAMSIZ]byte\n\tMTU  int32\n}\n\n// IoctlGetIfreqMTU performs the SIOCGIFMTU ioctl operation on fd to get the MTU\n// of the network device specified by ifname.\nfunc IoctlGetIfreqMTU(fd int, ifname string) (*IfreqMTU, error) {\n\tvar ifreq IfreqMTU\n\tcopy(ifreq.Name[:], ifname)\n\terr := ioctlPtr(fd, SIOCGIFMTU, unsafe.Pointer(&ifreq))\n\treturn &ifreq, err\n}\n\n// IoctlSetIfreqMTU performs the SIOCSIFMTU ioctl operation on fd to set the MTU\n// of the network device specified by ifreq.Name.\nfunc IoctlSetIfreqMTU(fd int, ifreq *IfreqMTU) error {\n\treturn ioctlPtr(fd, SIOCSIFMTU, unsafe.Pointer(ifreq))\n}\n\n//sys\trenamexNp(from string, to string, flag uint32) (err error)\n\nfunc RenamexNp(from string, to string, flag uint32) (err error) {\n\treturn renamexNp(from, to, flag)\n}\n\n//sys\trenameatxNp(fromfd int, from string, tofd int, to string, flag uint32) (err error)\n\nfunc RenameatxNp(fromfd int, from string, tofd int, to string, flag uint32) (err error) {\n\treturn renameatxNp(fromfd, from, tofd, to, flag)\n}\n\n//sys\tsysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS_SYSCTL\n\nfunc Uname(uname *Utsname) error {\n\tmib := []_C_int{CTL_KERN, KERN_OSTYPE}\n\tn := unsafe.Sizeof(uname.Sysname)\n\tif err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {\n\t\treturn err\n\t}\n\n\tmib = []_C_int{CTL_KERN, KERN_HOSTNAME}\n\tn = unsafe.Sizeof(uname.Nodename)\n\tif err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil {\n\t\treturn err\n\t}\n\n\tmib = []_C_int{CTL_KERN, KERN_OSRELEASE}\n\tn = unsafe.Sizeof(uname.Release)\n\tif err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil {\n\t\treturn err\n\t}\n\n\tmib = []_C_int{CTL_KERN, KERN_VERSION}\n\tn = unsafe.Sizeof(uname.Version)\n\tif err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {\n\t\treturn err\n\t}\n\n\t// The version might have newlines or tabs in it, convert them to\n\t// spaces.\n\tfor i, b := range uname.Version {\n\t\tif b == '\\n' || b == '\\t' {\n\t\t\tif i == len(uname.Version)-1 {\n\t\t\t\tuname.Version[i] = 0\n\t\t\t} else {\n\t\t\t\tuname.Version[i] = ' '\n\t\t\t}\n\t\t}\n\t}\n\n\tmib = []_C_int{CTL_HW, HW_MACHINE}\n\tn = unsafe.Sizeof(uname.Machine)\n\tif err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\tif raceenabled {\n\t\traceReleaseMerge(unsafe.Pointer(&ioSync))\n\t}\n\tvar length = int64(count)\n\terr = sendfile(infd, outfd, *offset, &length, nil, 0)\n\twritten = int(length)\n\treturn\n}\n\nfunc GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {\n\tvar value IPMreqn\n\tvallen := _Socklen(SizeofIPMreqn)\n\terrno := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)\n\treturn &value, errno\n}\n\nfunc SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))\n}\n\n// GetsockoptXucred is a getsockopt wrapper that returns an Xucred struct.\n// The usual level and opt are SOL_LOCAL and LOCAL_PEERCRED, respectively.\nfunc GetsockoptXucred(fd, level, opt int) (*Xucred, error) {\n\tx := new(Xucred)\n\tvallen := _Socklen(SizeofXucred)\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(x), &vallen)\n\treturn x, err\n}\n\nfunc GetsockoptTCPConnectionInfo(fd, level, opt int) (*TCPConnectionInfo, error) {\n\tvar value TCPConnectionInfo\n\tvallen := _Socklen(SizeofTCPConnectionInfo)\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)\n\treturn &value, err\n}\n\nfunc SysctlKinfoProc(name string, args ...int) (*KinfoProc, error) {\n\tmib, err := sysctlmib(name, args...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar kinfo KinfoProc\n\tn := uintptr(SizeofKinfoProc)\n\tif err := sysctl(mib, (*byte)(unsafe.Pointer(&kinfo)), &n, nil, 0); err != nil {\n\t\treturn nil, err\n\t}\n\tif n != SizeofKinfoProc {\n\t\treturn nil, EIO\n\t}\n\treturn &kinfo, nil\n}\n\nfunc SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {\n\tmib, err := sysctlmib(name, args...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor {\n\t\t// Find size.\n\t\tn := uintptr(0)\n\t\tif err := sysctl(mib, nil, &n, nil, 0); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif n == 0 {\n\t\t\treturn nil, nil\n\t\t}\n\t\tif n%SizeofKinfoProc != 0 {\n\t\t\treturn nil, fmt.Errorf(\"sysctl() returned a size of %d, which is not a multiple of %d\", n, SizeofKinfoProc)\n\t\t}\n\n\t\t// Read into buffer of that size.\n\t\tbuf := make([]KinfoProc, n/SizeofKinfoProc)\n\t\tif err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil {\n\t\t\tif err == ENOMEM {\n\t\t\t\t// Process table grew. Try again.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn nil, err\n\t\t}\n\t\tif n%SizeofKinfoProc != 0 {\n\t\t\treturn nil, fmt.Errorf(\"sysctl() returned a size of %d, which is not a multiple of %d\", n, SizeofKinfoProc)\n\t\t}\n\n\t\t// The actual call may return less than the original reported required\n\t\t// size so ensure we deal with that.\n\t\treturn buf[:n/SizeofKinfoProc], nil\n\t}\n}\n\n//sys\tpthread_chdir_np(path string) (err error)\n\nfunc PthreadChdir(path string) (err error) {\n\treturn pthread_chdir_np(path)\n}\n\n//sys\tpthread_fchdir_np(fd int) (err error)\n\nfunc PthreadFchdir(fd int) (err error) {\n\treturn pthread_fchdir_np(fd)\n}\n\n// Connectx calls connectx(2) to initiate a connection on a socket.\n//\n// srcIf, srcAddr, and dstAddr are filled into a [SaEndpoints] struct and passed as the endpoints argument.\n//\n//   - srcIf is the optional source interface index. 0 means unspecified.\n//   - srcAddr is the optional source address. nil means unspecified.\n//   - dstAddr is the destination address.\n//\n// On success, Connectx returns the number of bytes enqueued for transmission.\nfunc Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocID, flags uint32, iov []Iovec, connid *SaeConnID) (n uintptr, err error) {\n\tendpoints := SaEndpoints{\n\t\tSrcif: srcIf,\n\t}\n\n\tif srcAddr != nil {\n\t\taddrp, addrlen, err := srcAddr.sockaddr()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tendpoints.Srcaddr = (*RawSockaddr)(addrp)\n\t\tendpoints.Srcaddrlen = uint32(addrlen)\n\t}\n\n\tif dstAddr != nil {\n\t\taddrp, addrlen, err := dstAddr.sockaddr()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tendpoints.Dstaddr = (*RawSockaddr)(addrp)\n\t\tendpoints.Dstaddrlen = uint32(addrlen)\n\t}\n\n\terr = connectx(fd, &endpoints, associd, flags, iov, &n, connid)\n\treturn\n}\n\nconst minIovec = 8\n\nfunc Readv(fd int, iovs [][]byte) (n int, err error) {\n\tiovecs := make([]Iovec, 0, minIovec)\n\tiovecs = appendBytes(iovecs, iovs)\n\tn, err = readv(fd, iovecs)\n\treadvRacedetect(iovecs, n, err)\n\treturn n, err\n}\n\nfunc Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {\n\tiovecs := make([]Iovec, 0, minIovec)\n\tiovecs = appendBytes(iovecs, iovs)\n\tn, err = preadv(fd, iovecs, offset)\n\treadvRacedetect(iovecs, n, err)\n\treturn n, err\n}\n\nfunc Writev(fd int, iovs [][]byte) (n int, err error) {\n\tiovecs := make([]Iovec, 0, minIovec)\n\tiovecs = appendBytes(iovecs, iovs)\n\tif raceenabled {\n\t\traceReleaseMerge(unsafe.Pointer(&ioSync))\n\t}\n\tn, err = writev(fd, iovecs)\n\twritevRacedetect(iovecs, n)\n\treturn n, err\n}\n\nfunc Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {\n\tiovecs := make([]Iovec, 0, minIovec)\n\tiovecs = appendBytes(iovecs, iovs)\n\tif raceenabled {\n\t\traceReleaseMerge(unsafe.Pointer(&ioSync))\n\t}\n\tn, err = pwritev(fd, iovecs, offset)\n\twritevRacedetect(iovecs, n)\n\treturn n, err\n}\n\nfunc appendBytes(vecs []Iovec, bs [][]byte) []Iovec {\n\tfor _, b := range bs {\n\t\tvar v Iovec\n\t\tv.SetLen(len(b))\n\t\tif len(b) > 0 {\n\t\t\tv.Base = &b[0]\n\t\t} else {\n\t\t\tv.Base = (*byte)(unsafe.Pointer(&_zero))\n\t\t}\n\t\tvecs = append(vecs, v)\n\t}\n\treturn vecs\n}\n\nfunc writevRacedetect(iovecs []Iovec, n int) {\n\tif !raceenabled {\n\t\treturn\n\t}\n\tfor i := 0; n > 0 && i < len(iovecs); i++ {\n\t\tm := int(iovecs[i].Len)\n\t\tif m > n {\n\t\t\tm = n\n\t\t}\n\t\tn -= m\n\t\tif m > 0 {\n\t\t\traceReadRange(unsafe.Pointer(iovecs[i].Base), m)\n\t\t}\n\t}\n}\n\nfunc readvRacedetect(iovecs []Iovec, n int, err error) {\n\tif !raceenabled {\n\t\treturn\n\t}\n\tfor i := 0; n > 0 && i < len(iovecs); i++ {\n\t\tm := int(iovecs[i].Len)\n\t\tif m > n {\n\t\t\tm = n\n\t\t}\n\t\tn -= m\n\t\tif m > 0 {\n\t\t\traceWriteRange(unsafe.Pointer(iovecs[i].Base), m)\n\t\t}\n\t}\n\tif err == nil {\n\t\traceAcquire(unsafe.Pointer(&ioSync))\n\t}\n}\n\n//sys\tconnectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error)\n//sys\tsendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)\n\n//sys\tshmat(id int, addr uintptr, flag int) (ret uintptr, err error)\n//sys\tshmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error)\n//sys\tshmdt(addr uintptr) (err error)\n//sys\tshmget(key int, size int, flag int) (id int, err error)\n\n/*\n * Exposed directly\n */\n//sys\tAccess(path string, mode uint32) (err error)\n//sys\tAdjtime(delta *Timeval, olddelta *Timeval) (err error)\n//sys\tChdir(path string) (err error)\n//sys\tChflags(path string, flags int) (err error)\n//sys\tChmod(path string, mode uint32) (err error)\n//sys\tChown(path string, uid int, gid int) (err error)\n//sys\tChroot(path string) (err error)\n//sys\tClockGettime(clockid int32, time *Timespec) (err error)\n//sys\tClose(fd int) (err error)\n//sys\tClonefile(src string, dst string, flags int) (err error)\n//sys\tClonefileat(srcDirfd int, src string, dstDirfd int, dst string, flags int) (err error)\n//sys\tDup(fd int) (nfd int, err error)\n//sys\tDup2(from int, to int) (err error)\n//sys\tExchangedata(path1 string, path2 string, options int) (err error)\n//sys\tExit(code int)\n//sys\tFaccessat(dirfd int, path string, mode uint32, flags int) (err error)\n//sys\tFchdir(fd int) (err error)\n//sys\tFchflags(fd int, flags int) (err error)\n//sys\tFchmod(fd int, mode uint32) (err error)\n//sys\tFchmodat(dirfd int, path string, mode uint32, flags int) (err error)\n//sys\tFchown(fd int, uid int, gid int) (err error)\n//sys\tFchownat(dirfd int, path string, uid int, gid int, flags int) (err error)\n//sys\tFclonefileat(srcDirfd int, dstDirfd int, dst string, flags int) (err error)\n//sys\tFlock(fd int, how int) (err error)\n//sys\tFpathconf(fd int, name int) (val int, err error)\n//sys\tFsync(fd int) (err error)\n//sys\tFtruncate(fd int, length int64) (err error)\n//sys\tGetcwd(buf []byte) (n int, err error)\n//sys\tGetdtablesize() (size int)\n//sysnb\tGetegid() (egid int)\n//sysnb\tGeteuid() (uid int)\n//sysnb\tGetgid() (gid int)\n//sysnb\tGetpgid(pid int) (pgid int, err error)\n//sysnb\tGetpgrp() (pgrp int)\n//sysnb\tGetpid() (pid int)\n//sysnb\tGetppid() (ppid int)\n//sys\tGetpriority(which int, who int) (prio int, err error)\n//sysnb\tGetrlimit(which int, lim *Rlimit) (err error)\n//sysnb\tGetrusage(who int, rusage *Rusage) (err error)\n//sysnb\tGetsid(pid int) (sid int, err error)\n//sysnb\tGettimeofday(tp *Timeval) (err error)\n//sysnb\tGetuid() (uid int)\n//sysnb\tIssetugid() (tainted bool)\n//sys\tKqueue() (fd int, err error)\n//sys\tLchown(path string, uid int, gid int) (err error)\n//sys\tLink(path string, link string) (err error)\n//sys\tLinkat(pathfd int, path string, linkfd int, link string, flags int) (err error)\n//sys\tListen(s int, backlog int) (err error)\n//sys\tMkdir(path string, mode uint32) (err error)\n//sys\tMkdirat(dirfd int, path string, mode uint32) (err error)\n//sys\tMkfifo(path string, mode uint32) (err error)\n//sys\tMknod(path string, mode uint32, dev int) (err error)\n//sys\tMount(fsType string, dir string, flags int, data unsafe.Pointer) (err error)\n//sys\tOpen(path string, mode int, perm uint32) (fd int, err error)\n//sys\tOpenat(dirfd int, path string, mode int, perm uint32) (fd int, err error)\n//sys\tPathconf(path string, name int) (val int, err error)\n//sys\tpread(fd int, p []byte, offset int64) (n int, err error)\n//sys\tpwrite(fd int, p []byte, offset int64) (n int, err error)\n//sys\tread(fd int, p []byte) (n int, err error)\n//sys\tReadlink(path string, buf []byte) (n int, err error)\n//sys\tReadlinkat(dirfd int, path string, buf []byte) (n int, err error)\n//sys\tRename(from string, to string) (err error)\n//sys\tRenameat(fromfd int, from string, tofd int, to string) (err error)\n//sys\tRevoke(path string) (err error)\n//sys\tRmdir(path string) (err error)\n//sys\tSeek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK\n//sys\tSelect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)\n//sys\tSetattrlist(path string, attrlist *Attrlist, attrBuf []byte, options int) (err error)\n//sys\tSetegid(egid int) (err error)\n//sysnb\tSeteuid(euid int) (err error)\n//sysnb\tSetgid(gid int) (err error)\n//sys\tSetlogin(name string) (err error)\n//sysnb\tSetpgid(pid int, pgid int) (err error)\n//sys\tSetpriority(which int, who int, prio int) (err error)\n//sys\tSetprivexec(flag int) (err error)\n//sysnb\tSetregid(rgid int, egid int) (err error)\n//sysnb\tSetreuid(ruid int, euid int) (err error)\n//sysnb\tSetsid() (pid int, err error)\n//sysnb\tSettimeofday(tp *Timeval) (err error)\n//sysnb\tSetuid(uid int) (err error)\n//sys\tSymlink(path string, link string) (err error)\n//sys\tSymlinkat(oldpath string, newdirfd int, newpath string) (err error)\n//sys\tSync() (err error)\n//sys\tTruncate(path string, length int64) (err error)\n//sys\tUmask(newmask int) (oldmask int)\n//sys\tUndelete(path string) (err error)\n//sys\tUnlink(path string) (err error)\n//sys\tUnlinkat(dirfd int, path string, flags int) (err error)\n//sys\tUnmount(path string, flags int) (err error)\n//sys\twrite(fd int, p []byte) (n int, err error)\n//sys\tmmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)\n//sys\tmunmap(addr uintptr, length uintptr) (err error)\n//sys\treadv(fd int, iovecs []Iovec) (n int, err error)\n//sys\tpreadv(fd int, iovecs []Iovec, offset int64) (n int, err error)\n//sys\twritev(fd int, iovecs []Iovec) (n int, err error)\n//sys\tpwritev(fd int, iovecs []Iovec, offset int64) (n int, err error)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go",
    "content": "// Copyright 2009 The Go 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\n//go:build amd64 && darwin\n\npackage unix\n\nimport \"syscall\"\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: int32(usec)}\n}\n\nfunc SetKevent(k *Kevent_t, fd, mode, flags int) {\n\tk.Ident = uint64(fd)\n\tk.Filter = int16(mode)\n\tk.Flags = uint16(flags)\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = int32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\nfunc Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)\n\n//sys\tFstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64\n//sys\tFstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64\n//sys\tFstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64\n//sys\tgetfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64\n//sys\tLstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64\n//sys\tptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace\n//sys\tStat(path string, stat *Stat_t) (err error) = SYS_STAT64\n//sys\tStatfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go",
    "content": "// Copyright 2015 The Go 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\n//go:build arm64 && darwin\n\npackage unix\n\nimport \"syscall\"\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: int32(usec)}\n}\n\nfunc SetKevent(k *Kevent_t, fd, mode, flags int) {\n\tk.Ident = uint64(fd)\n\tk.Filter = int16(mode)\n\tk.Flags = uint16(flags)\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = int32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\nfunc Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // sic\n\n//sys\tFstat(fd int, stat *Stat_t) (err error)\n//sys\tFstatat(fd int, path string, stat *Stat_t, flags int) (err error)\n//sys\tFstatfs(fd int, stat *Statfs_t) (err error)\n//sys\tgetfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT\n//sys\tLstat(path string, stat *Stat_t) (err error)\n//sys\tptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace\n//sys\tStat(path string, stat *Stat_t) (err error)\n//sys\tStatfs(path string, stat *Statfs_t) (err error)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go",
    "content": "// Copyright 2018 The Go 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\n//go:build darwin\n\npackage unix\n\nimport _ \"unsafe\"\n\n// Implemented in the runtime package (runtime/sys_darwin.go)\nfunc syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)\nfunc syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)\nfunc syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)\nfunc syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) // 32-bit only\nfunc syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)\nfunc syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)\nfunc syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)\n\n//go:linkname syscall_syscall syscall.syscall\n//go:linkname syscall_syscall6 syscall.syscall6\n//go:linkname syscall_syscall6X syscall.syscall6X\n//go:linkname syscall_syscall9 syscall.syscall9\n//go:linkname syscall_rawSyscall syscall.rawSyscall\n//go:linkname syscall_rawSyscall6 syscall.rawSyscall6\n//go:linkname syscall_syscallPtr syscall.syscallPtr\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_dragonfly.go",
    "content": "// Copyright 2009 The Go 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\n// DragonFly BSD system calls.\n// This file is compiled as ordinary Go code,\n// but it is also input to mksyscall,\n// which parses the //sys lines and generates system call stubs.\n// Note that sometimes we use a lowercase //sys name and wrap\n// it in our own nicer implementation, either here or in\n// syscall_bsd.go or syscall_unix.go.\n\npackage unix\n\nimport (\n\t\"sync\"\n\t\"unsafe\"\n)\n\n// See version list in https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sys/sys/param.h\nvar (\n\tosreldateOnce sync.Once\n\tosreldate     uint32\n)\n\n// First __DragonFly_version after September 2019 ABI changes\n// http://lists.dragonflybsd.org/pipermail/users/2019-September/358280.html\nconst _dragonflyABIChangeVersion = 500705\n\nfunc supportsABI(ver uint32) bool {\n\tosreldateOnce.Do(func() { osreldate, _ = SysctlUint32(\"kern.osreldate\") })\n\treturn osreldate >= ver\n}\n\n// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.\ntype SockaddrDatalink struct {\n\tLen    uint8\n\tFamily uint8\n\tIndex  uint16\n\tType   uint8\n\tNlen   uint8\n\tAlen   uint8\n\tSlen   uint8\n\tData   [12]int8\n\tRcf    uint16\n\tRoute  [16]uint16\n\traw    RawSockaddrDatalink\n}\n\nfunc anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {\n\treturn nil, EAFNOSUPPORT\n}\n\n// Translate \"kern.hostname\" to []_C_int{0,1,2,3}.\nfunc nametomib(name string) (mib []_C_int, err error) {\n\tconst siz = unsafe.Sizeof(mib[0])\n\n\t// NOTE(rsc): It seems strange to set the buffer to have\n\t// size CTL_MAXNAME+2 but use only CTL_MAXNAME\n\t// as the size. I don't know why the +2 is here, but the\n\t// kernel uses +2 for its own implementation of this function.\n\t// I am scared that if we don't include the +2 here, the kernel\n\t// will silently write 2 words farther than we specify\n\t// and we'll get memory corruption.\n\tvar buf [CTL_MAXNAME + 2]_C_int\n\tn := uintptr(CTL_MAXNAME) * siz\n\n\tp := (*byte)(unsafe.Pointer(&buf[0]))\n\tbytes, err := ByteSliceFromString(name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Magic sysctl: \"setting\" 0.3 to a string name\n\t// lets you read back the array of integers form.\n\tif err = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); err != nil {\n\t\treturn nil, err\n\t}\n\treturn buf[0 : n/siz], nil\n}\n\nfunc direntIno(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))\n}\n\nfunc direntReclen(buf []byte) (uint64, bool) {\n\tnamlen, ok := direntNamlen(buf)\n\tif !ok {\n\t\treturn 0, false\n\t}\n\treturn (16 + namlen + 1 + 7) &^ 7, true\n}\n\nfunc direntNamlen(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))\n}\n\n//sysnb\tpipe() (r int, w int, err error)\n\nfunc Pipe(p []int) (err error) {\n\tif len(p) != 2 {\n\t\treturn EINVAL\n\t}\n\tr, w, err := pipe()\n\tif err == nil {\n\t\tp[0], p[1] = r, w\n\t}\n\treturn\n}\n\n//sysnb\tpipe2(p *[2]_C_int, flags int) (r int, w int, err error)\n\nfunc Pipe2(p []int, flags int) (err error) {\n\tif len(p) != 2 {\n\t\treturn EINVAL\n\t}\n\tvar pp [2]_C_int\n\t// pipe2 on dragonfly takes an fds array as an argument, but still\n\t// returns the file descriptors.\n\tr, w, err := pipe2(&pp, flags)\n\tif err == nil {\n\t\tp[0], p[1] = r, w\n\t}\n\treturn err\n}\n\n//sys\textpread(fd int, p []byte, flags int, offset int64) (n int, err error)\n\nfunc pread(fd int, p []byte, offset int64) (n int, err error) {\n\treturn extpread(fd, p, 0, offset)\n}\n\n//sys\textpwrite(fd int, p []byte, flags int, offset int64) (n int, err error)\n\nfunc pwrite(fd int, p []byte, offset int64) (n int, err error) {\n\treturn extpwrite(fd, p, 0, offset)\n}\n\nfunc Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {\n\tvar rsa RawSockaddrAny\n\tvar len _Socklen = SizeofSockaddrAny\n\tnfd, err = accept4(fd, &rsa, &len, flags)\n\tif err != nil {\n\t\treturn\n\t}\n\tif len > SizeofSockaddrAny {\n\t\tpanic(\"RawSockaddrAny too small\")\n\t}\n\tsa, err = anyToSockaddr(fd, &rsa)\n\tif err != nil {\n\t\tClose(nfd)\n\t\tnfd = 0\n\t}\n\treturn\n}\n\n//sys\tGetcwd(buf []byte) (n int, err error) = SYS___GETCWD\n\nfunc Getfsstat(buf []Statfs_t, flags int) (n int, err error) {\n\tvar _p0 unsafe.Pointer\n\tvar bufsize uintptr\n\tif len(buf) > 0 {\n\t\t_p0 = unsafe.Pointer(&buf[0])\n\t\tbufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))\n\t}\n\tr0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))\n\tn = int(r0)\n\tif e1 != 0 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n//sys\tioctl(fd int, req uint, arg uintptr) (err error)\n//sys\tioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL\n\n//sys\tsysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL\n\nfunc sysctlUname(mib []_C_int, old *byte, oldlen *uintptr) error {\n\terr := sysctl(mib, old, oldlen, nil, 0)\n\tif err != nil {\n\t\t// Utsname members on Dragonfly are only 32 bytes and\n\t\t// the syscall returns ENOMEM in case the actual value\n\t\t// is longer.\n\t\tif err == ENOMEM {\n\t\t\terr = nil\n\t\t}\n\t}\n\treturn err\n}\n\nfunc Uname(uname *Utsname) error {\n\tmib := []_C_int{CTL_KERN, KERN_OSTYPE}\n\tn := unsafe.Sizeof(uname.Sysname)\n\tif err := sysctlUname(mib, &uname.Sysname[0], &n); err != nil {\n\t\treturn err\n\t}\n\tuname.Sysname[unsafe.Sizeof(uname.Sysname)-1] = 0\n\n\tmib = []_C_int{CTL_KERN, KERN_HOSTNAME}\n\tn = unsafe.Sizeof(uname.Nodename)\n\tif err := sysctlUname(mib, &uname.Nodename[0], &n); err != nil {\n\t\treturn err\n\t}\n\tuname.Nodename[unsafe.Sizeof(uname.Nodename)-1] = 0\n\n\tmib = []_C_int{CTL_KERN, KERN_OSRELEASE}\n\tn = unsafe.Sizeof(uname.Release)\n\tif err := sysctlUname(mib, &uname.Release[0], &n); err != nil {\n\t\treturn err\n\t}\n\tuname.Release[unsafe.Sizeof(uname.Release)-1] = 0\n\n\tmib = []_C_int{CTL_KERN, KERN_VERSION}\n\tn = unsafe.Sizeof(uname.Version)\n\tif err := sysctlUname(mib, &uname.Version[0], &n); err != nil {\n\t\treturn err\n\t}\n\n\t// The version might have newlines or tabs in it, convert them to\n\t// spaces.\n\tfor i, b := range uname.Version {\n\t\tif b == '\\n' || b == '\\t' {\n\t\t\tif i == len(uname.Version)-1 {\n\t\t\t\tuname.Version[i] = 0\n\t\t\t} else {\n\t\t\t\tuname.Version[i] = ' '\n\t\t\t}\n\t\t}\n\t}\n\n\tmib = []_C_int{CTL_HW, HW_MACHINE}\n\tn = unsafe.Sizeof(uname.Machine)\n\tif err := sysctlUname(mib, &uname.Machine[0], &n); err != nil {\n\t\treturn err\n\t}\n\tuname.Machine[unsafe.Sizeof(uname.Machine)-1] = 0\n\n\treturn nil\n}\n\nfunc Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\tif raceenabled {\n\t\traceReleaseMerge(unsafe.Pointer(&ioSync))\n\t}\n\treturn sendfile(outfd, infd, offset, count)\n}\n\nfunc Dup3(oldfd, newfd, flags int) error {\n\tif oldfd == newfd || flags&^O_CLOEXEC != 0 {\n\t\treturn EINVAL\n\t}\n\thow := F_DUP2FD\n\tif flags&O_CLOEXEC != 0 {\n\t\thow = F_DUP2FD_CLOEXEC\n\t}\n\t_, err := fcntl(oldfd, how, newfd)\n\treturn err\n}\n\n/*\n * Exposed directly\n */\n//sys\tAccess(path string, mode uint32) (err error)\n//sys\tAdjtime(delta *Timeval, olddelta *Timeval) (err error)\n//sys\tChdir(path string) (err error)\n//sys\tChflags(path string, flags int) (err error)\n//sys\tChmod(path string, mode uint32) (err error)\n//sys\tChown(path string, uid int, gid int) (err error)\n//sys\tChroot(path string) (err error)\n//sys\tClockGettime(clockid int32, time *Timespec) (err error)\n//sys\tClose(fd int) (err error)\n//sys\tDup(fd int) (nfd int, err error)\n//sys\tDup2(from int, to int) (err error)\n//sys\tExit(code int)\n//sys\tFaccessat(dirfd int, path string, mode uint32, flags int) (err error)\n//sys\tFchdir(fd int) (err error)\n//sys\tFchflags(fd int, flags int) (err error)\n//sys\tFchmod(fd int, mode uint32) (err error)\n//sys\tFchmodat(dirfd int, path string, mode uint32, flags int) (err error)\n//sys\tFchown(fd int, uid int, gid int) (err error)\n//sys\tFchownat(dirfd int, path string, uid int, gid int, flags int) (err error)\n//sys\tFlock(fd int, how int) (err error)\n//sys\tFpathconf(fd int, name int) (val int, err error)\n//sys\tFstat(fd int, stat *Stat_t) (err error)\n//sys\tFstatat(fd int, path string, stat *Stat_t, flags int) (err error)\n//sys\tFstatfs(fd int, stat *Statfs_t) (err error)\n//sys\tFsync(fd int) (err error)\n//sys\tFtruncate(fd int, length int64) (err error)\n//sys\tGetdents(fd int, buf []byte) (n int, err error)\n//sys\tGetdirentries(fd int, buf []byte, basep *uintptr) (n int, err error)\n//sys\tGetdtablesize() (size int)\n//sysnb\tGetegid() (egid int)\n//sysnb\tGeteuid() (uid int)\n//sysnb\tGetgid() (gid int)\n//sysnb\tGetpgid(pid int) (pgid int, err error)\n//sysnb\tGetpgrp() (pgrp int)\n//sysnb\tGetpid() (pid int)\n//sysnb\tGetppid() (ppid int)\n//sys\tGetpriority(which int, who int) (prio int, err error)\n//sysnb\tGetrlimit(which int, lim *Rlimit) (err error)\n//sysnb\tGetrusage(who int, rusage *Rusage) (err error)\n//sysnb\tGetsid(pid int) (sid int, err error)\n//sysnb\tGettimeofday(tv *Timeval) (err error)\n//sysnb\tGetuid() (uid int)\n//sys\tIssetugid() (tainted bool)\n//sys\tKill(pid int, signum syscall.Signal) (err error)\n//sys\tKqueue() (fd int, err error)\n//sys\tLchown(path string, uid int, gid int) (err error)\n//sys\tLink(path string, link string) (err error)\n//sys\tLinkat(pathfd int, path string, linkfd int, link string, flags int) (err error)\n//sys\tListen(s int, backlog int) (err error)\n//sys\tLstat(path string, stat *Stat_t) (err error)\n//sys\tMkdir(path string, mode uint32) (err error)\n//sys\tMkdirat(dirfd int, path string, mode uint32) (err error)\n//sys\tMkfifo(path string, mode uint32) (err error)\n//sys\tMknod(path string, mode uint32, dev int) (err error)\n//sys\tMknodat(fd int, path string, mode uint32, dev int) (err error)\n//sys\tNanosleep(time *Timespec, leftover *Timespec) (err error)\n//sys\tOpen(path string, mode int, perm uint32) (fd int, err error)\n//sys\tOpenat(dirfd int, path string, mode int, perm uint32) (fd int, err error)\n//sys\tPathconf(path string, name int) (val int, err error)\n//sys\tread(fd int, p []byte) (n int, err error)\n//sys\tReadlink(path string, buf []byte) (n int, err error)\n//sys\tRename(from string, to string) (err error)\n//sys\tRenameat(fromfd int, from string, tofd int, to string) (err error)\n//sys\tRevoke(path string) (err error)\n//sys\tRmdir(path string) (err error)\n//sys\tSeek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK\n//sys\tSelect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)\n//sysnb\tSetegid(egid int) (err error)\n//sysnb\tSeteuid(euid int) (err error)\n//sysnb\tSetgid(gid int) (err error)\n//sys\tSetlogin(name string) (err error)\n//sysnb\tSetpgid(pid int, pgid int) (err error)\n//sys\tSetpriority(which int, who int, prio int) (err error)\n//sysnb\tSetregid(rgid int, egid int) (err error)\n//sysnb\tSetreuid(ruid int, euid int) (err error)\n//sysnb\tSetresgid(rgid int, egid int, sgid int) (err error)\n//sysnb\tSetresuid(ruid int, euid int, suid int) (err error)\n//sysnb\tSetsid() (pid int, err error)\n//sysnb\tSettimeofday(tp *Timeval) (err error)\n//sysnb\tSetuid(uid int) (err error)\n//sys\tStat(path string, stat *Stat_t) (err error)\n//sys\tStatfs(path string, stat *Statfs_t) (err error)\n//sys\tSymlink(path string, link string) (err error)\n//sys\tSymlinkat(oldpath string, newdirfd int, newpath string) (err error)\n//sys\tSync() (err error)\n//sys\tTruncate(path string, length int64) (err error)\n//sys\tUmask(newmask int) (oldmask int)\n//sys\tUndelete(path string) (err error)\n//sys\tUnlink(path string) (err error)\n//sys\tUnlinkat(dirfd int, path string, flags int) (err error)\n//sys\tUnmount(path string, flags int) (err error)\n//sys\twrite(fd int, p []byte) (n int, err error)\n//sys\tmmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)\n//sys\tmunmap(addr uintptr, length uintptr) (err error)\n//sys\taccept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error)\n//sys\tutimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_dragonfly_amd64.go",
    "content": "// Copyright 2009 The Go 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\n//go:build amd64 && dragonfly\n\npackage unix\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: usec}\n}\n\nfunc SetKevent(k *Kevent_t, fd, mode, flags int) {\n\tk.Ident = uint64(fd)\n\tk.Filter = int16(mode)\n\tk.Flags = uint16(flags)\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = int32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\nfunc sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\tvar writtenOut uint64 = 0\n\t_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0)\n\n\twritten = int(writtenOut)\n\n\tif e1 != 0 {\n\t\terr = e1\n\t}\n\treturn\n}\n\nfunc Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_freebsd.go",
    "content": "// Copyright 2009,2010 The Go 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\n// FreeBSD system calls.\n// This file is compiled as ordinary Go code,\n// but it is also input to mksyscall,\n// which parses the //sys lines and generates system call stubs.\n// Note that sometimes we use a lowercase //sys name and wrap\n// it in our own nicer implementation, either here or in\n// syscall_bsd.go or syscall_unix.go.\n\npackage unix\n\nimport (\n\t\"errors\"\n\t\"sync\"\n\t\"unsafe\"\n)\n\n// See https://www.freebsd.org/doc/en_US.ISO8859-1/books/porters-handbook/versions.html.\nvar (\n\tosreldateOnce sync.Once\n\tosreldate     uint32\n)\n\nfunc supportsABI(ver uint32) bool {\n\tosreldateOnce.Do(func() { osreldate, _ = SysctlUint32(\"kern.osreldate\") })\n\treturn osreldate >= ver\n}\n\n// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.\ntype SockaddrDatalink struct {\n\tLen    uint8\n\tFamily uint8\n\tIndex  uint16\n\tType   uint8\n\tNlen   uint8\n\tAlen   uint8\n\tSlen   uint8\n\tData   [46]int8\n\traw    RawSockaddrDatalink\n}\n\nfunc anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {\n\treturn nil, EAFNOSUPPORT\n}\n\n// Translate \"kern.hostname\" to []_C_int{0,1,2,3}.\nfunc nametomib(name string) (mib []_C_int, err error) {\n\tconst siz = unsafe.Sizeof(mib[0])\n\n\t// NOTE(rsc): It seems strange to set the buffer to have\n\t// size CTL_MAXNAME+2 but use only CTL_MAXNAME\n\t// as the size. I don't know why the +2 is here, but the\n\t// kernel uses +2 for its own implementation of this function.\n\t// I am scared that if we don't include the +2 here, the kernel\n\t// will silently write 2 words farther than we specify\n\t// and we'll get memory corruption.\n\tvar buf [CTL_MAXNAME + 2]_C_int\n\tn := uintptr(CTL_MAXNAME) * siz\n\n\tp := (*byte)(unsafe.Pointer(&buf[0]))\n\tbytes, err := ByteSliceFromString(name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Magic sysctl: \"setting\" 0.3 to a string name\n\t// lets you read back the array of integers form.\n\tif err = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); err != nil {\n\t\treturn nil, err\n\t}\n\treturn buf[0 : n/siz], nil\n}\n\nfunc direntIno(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))\n}\n\nfunc direntReclen(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))\n}\n\nfunc direntNamlen(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))\n}\n\nfunc Pipe(p []int) (err error) {\n\treturn Pipe2(p, 0)\n}\n\n//sysnb\tpipe2(p *[2]_C_int, flags int) (err error)\n\nfunc Pipe2(p []int, flags int) error {\n\tif len(p) != 2 {\n\t\treturn EINVAL\n\t}\n\tvar pp [2]_C_int\n\terr := pipe2(&pp, flags)\n\tif err == nil {\n\t\tp[0] = int(pp[0])\n\t\tp[1] = int(pp[1])\n\t}\n\treturn err\n}\n\nfunc GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {\n\tvar value IPMreqn\n\tvallen := _Socklen(SizeofIPMreqn)\n\terrno := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)\n\treturn &value, errno\n}\n\nfunc SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))\n}\n\n// GetsockoptXucred is a getsockopt wrapper that returns an Xucred struct.\n// The usual level and opt are SOL_LOCAL and LOCAL_PEERCRED, respectively.\nfunc GetsockoptXucred(fd, level, opt int) (*Xucred, error) {\n\tx := new(Xucred)\n\tvallen := _Socklen(SizeofXucred)\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(x), &vallen)\n\treturn x, err\n}\n\nfunc Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {\n\tvar rsa RawSockaddrAny\n\tvar len _Socklen = SizeofSockaddrAny\n\tnfd, err = accept4(fd, &rsa, &len, flags)\n\tif err != nil {\n\t\treturn\n\t}\n\tif len > SizeofSockaddrAny {\n\t\tpanic(\"RawSockaddrAny too small\")\n\t}\n\tsa, err = anyToSockaddr(fd, &rsa)\n\tif err != nil {\n\t\tClose(nfd)\n\t\tnfd = 0\n\t}\n\treturn\n}\n\n//sys\tGetcwd(buf []byte) (n int, err error) = SYS___GETCWD\n\nfunc Getfsstat(buf []Statfs_t, flags int) (n int, err error) {\n\tvar (\n\t\t_p0     unsafe.Pointer\n\t\tbufsize uintptr\n\t)\n\tif len(buf) > 0 {\n\t\t_p0 = unsafe.Pointer(&buf[0])\n\t\tbufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))\n\t}\n\tr0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))\n\tn = int(r0)\n\tif e1 != 0 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n//sys\tioctl(fd int, req uint, arg uintptr) (err error) = SYS_IOCTL\n//sys\tioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL\n\n//sys\tsysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL\n\nfunc Uname(uname *Utsname) error {\n\tmib := []_C_int{CTL_KERN, KERN_OSTYPE}\n\tn := unsafe.Sizeof(uname.Sysname)\n\t// Suppress ENOMEM errors to be compatible with the C library __xuname() implementation.\n\tif err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {\n\t\treturn err\n\t}\n\n\tmib = []_C_int{CTL_KERN, KERN_HOSTNAME}\n\tn = unsafe.Sizeof(uname.Nodename)\n\tif err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {\n\t\treturn err\n\t}\n\n\tmib = []_C_int{CTL_KERN, KERN_OSRELEASE}\n\tn = unsafe.Sizeof(uname.Release)\n\tif err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {\n\t\treturn err\n\t}\n\n\tmib = []_C_int{CTL_KERN, KERN_VERSION}\n\tn = unsafe.Sizeof(uname.Version)\n\tif err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {\n\t\treturn err\n\t}\n\n\t// The version might have newlines or tabs in it, convert them to\n\t// spaces.\n\tfor i, b := range uname.Version {\n\t\tif b == '\\n' || b == '\\t' {\n\t\t\tif i == len(uname.Version)-1 {\n\t\t\t\tuname.Version[i] = 0\n\t\t\t} else {\n\t\t\t\tuname.Version[i] = ' '\n\t\t\t}\n\t\t}\n\t}\n\n\tmib = []_C_int{CTL_HW, HW_MACHINE}\n\tn = unsafe.Sizeof(uname.Machine)\n\tif err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc Stat(path string, st *Stat_t) (err error) {\n\treturn Fstatat(AT_FDCWD, path, st, 0)\n}\n\nfunc Lstat(path string, st *Stat_t) (err error) {\n\treturn Fstatat(AT_FDCWD, path, st, AT_SYMLINK_NOFOLLOW)\n}\n\nfunc Getdents(fd int, buf []byte) (n int, err error) {\n\treturn Getdirentries(fd, buf, nil)\n}\n\nfunc Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {\n\tif basep == nil || unsafe.Sizeof(*basep) == 8 {\n\t\treturn getdirentries(fd, buf, (*uint64)(unsafe.Pointer(basep)))\n\t}\n\t// The syscall needs a 64-bit base. On 32-bit machines\n\t// we can't just use the basep passed in. See #32498.\n\tvar base uint64 = uint64(*basep)\n\tn, err = getdirentries(fd, buf, &base)\n\t*basep = uintptr(base)\n\tif base>>32 != 0 {\n\t\t// We can't stuff the base back into a uintptr, so any\n\t\t// future calls would be suspect. Generate an error.\n\t\t// EIO is allowed by getdirentries.\n\t\terr = EIO\n\t}\n\treturn\n}\n\nfunc Mknod(path string, mode uint32, dev uint64) (err error) {\n\treturn Mknodat(AT_FDCWD, path, mode, dev)\n}\n\nfunc Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\tif raceenabled {\n\t\traceReleaseMerge(unsafe.Pointer(&ioSync))\n\t}\n\treturn sendfile(outfd, infd, offset, count)\n}\n\n//sys\tptrace(request int, pid int, addr uintptr, data int) (err error)\n//sys\tptracePtr(request int, pid int, addr unsafe.Pointer, data int) (err error) = SYS_PTRACE\n\nfunc PtraceAttach(pid int) (err error) {\n\treturn ptrace(PT_ATTACH, pid, 0, 0)\n}\n\nfunc PtraceCont(pid int, signal int) (err error) {\n\treturn ptrace(PT_CONTINUE, pid, 1, signal)\n}\n\nfunc PtraceDetach(pid int) (err error) {\n\treturn ptrace(PT_DETACH, pid, 1, 0)\n}\n\nfunc PtraceGetFpRegs(pid int, fpregsout *FpReg) (err error) {\n\treturn ptracePtr(PT_GETFPREGS, pid, unsafe.Pointer(fpregsout), 0)\n}\n\nfunc PtraceGetRegs(pid int, regsout *Reg) (err error) {\n\treturn ptracePtr(PT_GETREGS, pid, unsafe.Pointer(regsout), 0)\n}\n\nfunc PtraceIO(req int, pid int, offs uintptr, out []byte, countin int) (count int, err error) {\n\tioDesc := PtraceIoDesc{\n\t\tOp:   int32(req),\n\t\tOffs: offs,\n\t}\n\tif countin > 0 {\n\t\t_ = out[:countin] // check bounds\n\t\tioDesc.Addr = &out[0]\n\t} else if out != nil {\n\t\tioDesc.Addr = (*byte)(unsafe.Pointer(&_zero))\n\t}\n\tioDesc.SetLen(countin)\n\n\terr = ptracePtr(PT_IO, pid, unsafe.Pointer(&ioDesc), 0)\n\treturn int(ioDesc.Len), err\n}\n\nfunc PtraceLwpEvents(pid int, enable int) (err error) {\n\treturn ptrace(PT_LWP_EVENTS, pid, 0, enable)\n}\n\nfunc PtraceLwpInfo(pid int, info *PtraceLwpInfoStruct) (err error) {\n\treturn ptracePtr(PT_LWPINFO, pid, unsafe.Pointer(info), int(unsafe.Sizeof(*info)))\n}\n\nfunc PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {\n\treturn PtraceIO(PIOD_READ_D, pid, addr, out, SizeofLong)\n}\n\nfunc PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {\n\treturn PtraceIO(PIOD_READ_I, pid, addr, out, SizeofLong)\n}\n\nfunc PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {\n\treturn PtraceIO(PIOD_WRITE_D, pid, addr, data, SizeofLong)\n}\n\nfunc PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {\n\treturn PtraceIO(PIOD_WRITE_I, pid, addr, data, SizeofLong)\n}\n\nfunc PtraceSetRegs(pid int, regs *Reg) (err error) {\n\treturn ptracePtr(PT_SETREGS, pid, unsafe.Pointer(regs), 0)\n}\n\nfunc PtraceSingleStep(pid int) (err error) {\n\treturn ptrace(PT_STEP, pid, 1, 0)\n}\n\nfunc Dup3(oldfd, newfd, flags int) error {\n\tif oldfd == newfd || flags&^O_CLOEXEC != 0 {\n\t\treturn EINVAL\n\t}\n\thow := F_DUP2FD\n\tif flags&O_CLOEXEC != 0 {\n\t\thow = F_DUP2FD_CLOEXEC\n\t}\n\t_, err := fcntl(oldfd, how, newfd)\n\treturn err\n}\n\n/*\n * Exposed directly\n */\n//sys\tAccess(path string, mode uint32) (err error)\n//sys\tAdjtime(delta *Timeval, olddelta *Timeval) (err error)\n//sys\tCapEnter() (err error)\n//sys\tcapRightsGet(version int, fd int, rightsp *CapRights) (err error) = SYS___CAP_RIGHTS_GET\n//sys\tcapRightsLimit(fd int, rightsp *CapRights) (err error)\n//sys\tChdir(path string) (err error)\n//sys\tChflags(path string, flags int) (err error)\n//sys\tChmod(path string, mode uint32) (err error)\n//sys\tChown(path string, uid int, gid int) (err error)\n//sys\tChroot(path string) (err error)\n//sys\tClockGettime(clockid int32, time *Timespec) (err error)\n//sys\tClose(fd int) (err error)\n//sys\tDup(fd int) (nfd int, err error)\n//sys\tDup2(from int, to int) (err error)\n//sys\tExit(code int)\n//sys\tExtattrGetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)\n//sys\tExtattrSetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)\n//sys\tExtattrDeleteFd(fd int, attrnamespace int, attrname string) (err error)\n//sys\tExtattrListFd(fd int, attrnamespace int, data uintptr, nbytes int) (ret int, err error)\n//sys\tExtattrGetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)\n//sys\tExtattrSetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)\n//sys\tExtattrDeleteFile(file string, attrnamespace int, attrname string) (err error)\n//sys\tExtattrListFile(file string, attrnamespace int, data uintptr, nbytes int) (ret int, err error)\n//sys\tExtattrGetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)\n//sys\tExtattrSetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)\n//sys\tExtattrDeleteLink(link string, attrnamespace int, attrname string) (err error)\n//sys\tExtattrListLink(link string, attrnamespace int, data uintptr, nbytes int) (ret int, err error)\n//sys\tFadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_POSIX_FADVISE\n//sys\tFaccessat(dirfd int, path string, mode uint32, flags int) (err error)\n//sys\tFchdir(fd int) (err error)\n//sys\tFchflags(fd int, flags int) (err error)\n//sys\tFchmod(fd int, mode uint32) (err error)\n//sys\tFchmodat(dirfd int, path string, mode uint32, flags int) (err error)\n//sys\tFchown(fd int, uid int, gid int) (err error)\n//sys\tFchownat(dirfd int, path string, uid int, gid int, flags int) (err error)\n//sys\tFlock(fd int, how int) (err error)\n//sys\tFpathconf(fd int, name int) (val int, err error)\n//sys\tFstat(fd int, stat *Stat_t) (err error)\n//sys\tFstatat(fd int, path string, stat *Stat_t, flags int) (err error)\n//sys\tFstatfs(fd int, stat *Statfs_t) (err error)\n//sys\tFsync(fd int) (err error)\n//sys\tFtruncate(fd int, length int64) (err error)\n//sys\tgetdirentries(fd int, buf []byte, basep *uint64) (n int, err error)\n//sys\tGetdtablesize() (size int)\n//sysnb\tGetegid() (egid int)\n//sysnb\tGeteuid() (uid int)\n//sysnb\tGetgid() (gid int)\n//sysnb\tGetpgid(pid int) (pgid int, err error)\n//sysnb\tGetpgrp() (pgrp int)\n//sysnb\tGetpid() (pid int)\n//sysnb\tGetppid() (ppid int)\n//sys\tGetpriority(which int, who int) (prio int, err error)\n//sysnb\tGetrlimit(which int, lim *Rlimit) (err error)\n//sysnb\tGetrusage(who int, rusage *Rusage) (err error)\n//sysnb\tGetsid(pid int) (sid int, err error)\n//sysnb\tGettimeofday(tv *Timeval) (err error)\n//sysnb\tGetuid() (uid int)\n//sys\tIssetugid() (tainted bool)\n//sys\tKill(pid int, signum syscall.Signal) (err error)\n//sys\tKqueue() (fd int, err error)\n//sys\tLchown(path string, uid int, gid int) (err error)\n//sys\tLink(path string, link string) (err error)\n//sys\tLinkat(pathfd int, path string, linkfd int, link string, flags int) (err error)\n//sys\tListen(s int, backlog int) (err error)\n//sys\tMkdir(path string, mode uint32) (err error)\n//sys\tMkdirat(dirfd int, path string, mode uint32) (err error)\n//sys\tMkfifo(path string, mode uint32) (err error)\n//sys\tMknodat(fd int, path string, mode uint32, dev uint64) (err error)\n//sys\tNanosleep(time *Timespec, leftover *Timespec) (err error)\n//sys\tOpen(path string, mode int, perm uint32) (fd int, err error)\n//sys\tOpenat(fdat int, path string, mode int, perm uint32) (fd int, err error)\n//sys\tPathconf(path string, name int) (val int, err error)\n//sys\tpread(fd int, p []byte, offset int64) (n int, err error)\n//sys\tpwrite(fd int, p []byte, offset int64) (n int, err error)\n//sys\tread(fd int, p []byte) (n int, err error)\n//sys\tReadlink(path string, buf []byte) (n int, err error)\n//sys\tReadlinkat(dirfd int, path string, buf []byte) (n int, err error)\n//sys\tRename(from string, to string) (err error)\n//sys\tRenameat(fromfd int, from string, tofd int, to string) (err error)\n//sys\tRevoke(path string) (err error)\n//sys\tRmdir(path string) (err error)\n//sys\tSeek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK\n//sys\tSelect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)\n//sysnb\tSetegid(egid int) (err error)\n//sysnb\tSeteuid(euid int) (err error)\n//sysnb\tSetgid(gid int) (err error)\n//sys\tSetlogin(name string) (err error)\n//sysnb\tSetpgid(pid int, pgid int) (err error)\n//sys\tSetpriority(which int, who int, prio int) (err error)\n//sysnb\tSetregid(rgid int, egid int) (err error)\n//sysnb\tSetreuid(ruid int, euid int) (err error)\n//sysnb\tSetresgid(rgid int, egid int, sgid int) (err error)\n//sysnb\tSetresuid(ruid int, euid int, suid int) (err error)\n//sysnb\tSetsid() (pid int, err error)\n//sysnb\tSettimeofday(tp *Timeval) (err error)\n//sysnb\tSetuid(uid int) (err error)\n//sys\tStatfs(path string, stat *Statfs_t) (err error)\n//sys\tSymlink(path string, link string) (err error)\n//sys\tSymlinkat(oldpath string, newdirfd int, newpath string) (err error)\n//sys\tSync() (err error)\n//sys\tTruncate(path string, length int64) (err error)\n//sys\tUmask(newmask int) (oldmask int)\n//sys\tUndelete(path string) (err error)\n//sys\tUnlink(path string) (err error)\n//sys\tUnlinkat(dirfd int, path string, flags int) (err error)\n//sys\tUnmount(path string, flags int) (err error)\n//sys\twrite(fd int, p []byte) (n int, err error)\n//sys\tmmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)\n//sys\tmunmap(addr uintptr, length uintptr) (err error)\n//sys\taccept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error)\n//sys\tutimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_freebsd_386.go",
    "content": "// Copyright 2009 The Go 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\n//go:build 386 && freebsd\n\npackage unix\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: int32(sec), Nsec: int32(nsec)}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: int32(sec), Usec: int32(usec)}\n}\n\nfunc SetKevent(k *Kevent_t, fd, mode, flags int) {\n\tk.Ident = uint32(fd)\n\tk.Filter = int16(mode)\n\tk.Flags = uint16(flags)\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = int32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\nfunc (d *PtraceIoDesc) SetLen(length int) {\n\td.Len = uint32(length)\n}\n\nfunc sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\tvar writtenOut uint64 = 0\n\t_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr((*offset)>>32), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0)\n\n\twritten = int(writtenOut)\n\n\tif e1 != 0 {\n\t\terr = e1\n\t}\n\treturn\n}\n\nfunc Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)\n\nfunc PtraceGetFsBase(pid int, fsbase *int64) (err error) {\n\treturn ptracePtr(PT_GETFSBASE, pid, unsafe.Pointer(fsbase), 0)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go",
    "content": "// Copyright 2009 The Go 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\n//go:build amd64 && freebsd\n\npackage unix\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: usec}\n}\n\nfunc SetKevent(k *Kevent_t, fd, mode, flags int) {\n\tk.Ident = uint64(fd)\n\tk.Filter = int16(mode)\n\tk.Flags = uint16(flags)\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = int32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\nfunc (d *PtraceIoDesc) SetLen(length int) {\n\td.Len = uint64(length)\n}\n\nfunc sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\tvar writtenOut uint64 = 0\n\t_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0)\n\n\twritten = int(writtenOut)\n\n\tif e1 != 0 {\n\t\terr = e1\n\t}\n\treturn\n}\n\nfunc Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)\n\nfunc PtraceGetFsBase(pid int, fsbase *int64) (err error) {\n\treturn ptracePtr(PT_GETFSBASE, pid, unsafe.Pointer(fsbase), 0)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go",
    "content": "// Copyright 2012 The Go 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\n//go:build arm && freebsd\n\npackage unix\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: int32(nsec)}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: int32(usec)}\n}\n\nfunc SetKevent(k *Kevent_t, fd, mode, flags int) {\n\tk.Ident = uint32(fd)\n\tk.Filter = int16(mode)\n\tk.Flags = uint16(flags)\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = int32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\nfunc (d *PtraceIoDesc) SetLen(length int) {\n\td.Len = uint32(length)\n}\n\nfunc sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\tvar writtenOut uint64 = 0\n\t_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr((*offset)>>32), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0)\n\n\twritten = int(writtenOut)\n\n\tif e1 != 0 {\n\t\terr = e1\n\t}\n\treturn\n}\n\nfunc Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go",
    "content": "// Copyright 2018 The Go 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\n//go:build arm64 && freebsd\n\npackage unix\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: usec}\n}\n\nfunc SetKevent(k *Kevent_t, fd, mode, flags int) {\n\tk.Ident = uint64(fd)\n\tk.Filter = int16(mode)\n\tk.Flags = uint16(flags)\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = int32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\nfunc (d *PtraceIoDesc) SetLen(length int) {\n\td.Len = uint64(length)\n}\n\nfunc sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\tvar writtenOut uint64 = 0\n\t_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0)\n\n\twritten = int(writtenOut)\n\n\tif e1 != 0 {\n\t\terr = e1\n\t}\n\treturn\n}\n\nfunc Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_freebsd_riscv64.go",
    "content": "// Copyright 2022 The Go 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\n//go:build riscv64 && freebsd\n\npackage unix\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: usec}\n}\n\nfunc SetKevent(k *Kevent_t, fd, mode, flags int) {\n\tk.Ident = uint64(fd)\n\tk.Filter = int16(mode)\n\tk.Flags = uint16(flags)\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = int32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\nfunc (d *PtraceIoDesc) SetLen(length int) {\n\td.Len = uint64(length)\n}\n\nfunc sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\tvar writtenOut uint64 = 0\n\t_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0)\n\n\twritten = int(writtenOut)\n\n\tif e1 != 0 {\n\t\terr = e1\n\t}\n\treturn\n}\n\nfunc Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_hurd.go",
    "content": "// Copyright 2022 The Go 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\n//go:build hurd\n\npackage unix\n\n/*\n#include <stdint.h>\nint ioctl(int, unsigned long int, uintptr_t);\n*/\nimport \"C\"\nimport \"unsafe\"\n\nfunc ioctl(fd int, req uint, arg uintptr) (err error) {\n\tr0, er := C.ioctl(C.int(fd), C.ulong(req), C.uintptr_t(arg))\n\tif r0 == -1 && er != nil {\n\t\terr = er\n\t}\n\treturn\n}\n\nfunc ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) {\n\tr0, er := C.ioctl(C.int(fd), C.ulong(req), C.uintptr_t(uintptr(arg)))\n\tif r0 == -1 && er != nil {\n\t\terr = er\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_hurd_386.go",
    "content": "// Copyright 2022 The Go 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\n//go:build 386 && hurd\n\npackage unix\n\nconst (\n\tTIOCGETA = 0x62251713\n)\n\ntype Winsize struct {\n\tRow    uint16\n\tCol    uint16\n\tXpixel uint16\n\tYpixel uint16\n}\n\ntype Termios struct {\n\tIflag  uint32\n\tOflag  uint32\n\tCflag  uint32\n\tLflag  uint32\n\tCc     [20]uint8\n\tIspeed int32\n\tOspeed int32\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_illumos.go",
    "content": "// Copyright 2021 The Go 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\n// illumos system calls not present on Solaris.\n\n//go:build amd64 && illumos\n\npackage unix\n\nimport (\n\t\"unsafe\"\n)\n\nfunc bytes2iovec(bs [][]byte) []Iovec {\n\tiovecs := make([]Iovec, len(bs))\n\tfor i, b := range bs {\n\t\tiovecs[i].SetLen(len(b))\n\t\tif len(b) > 0 {\n\t\t\tiovecs[i].Base = &b[0]\n\t\t} else {\n\t\t\tiovecs[i].Base = (*byte)(unsafe.Pointer(&_zero))\n\t\t}\n\t}\n\treturn iovecs\n}\n\n//sys\treadv(fd int, iovs []Iovec) (n int, err error)\n\nfunc Readv(fd int, iovs [][]byte) (n int, err error) {\n\tiovecs := bytes2iovec(iovs)\n\tn, err = readv(fd, iovecs)\n\treturn n, err\n}\n\n//sys\tpreadv(fd int, iovs []Iovec, off int64) (n int, err error)\n\nfunc Preadv(fd int, iovs [][]byte, off int64) (n int, err error) {\n\tiovecs := bytes2iovec(iovs)\n\tn, err = preadv(fd, iovecs, off)\n\treturn n, err\n}\n\n//sys\twritev(fd int, iovs []Iovec) (n int, err error)\n\nfunc Writev(fd int, iovs [][]byte) (n int, err error) {\n\tiovecs := bytes2iovec(iovs)\n\tn, err = writev(fd, iovecs)\n\treturn n, err\n}\n\n//sys\tpwritev(fd int, iovs []Iovec, off int64) (n int, err error)\n\nfunc Pwritev(fd int, iovs [][]byte, off int64) (n int, err error) {\n\tiovecs := bytes2iovec(iovs)\n\tn, err = pwritev(fd, iovecs, off)\n\treturn n, err\n}\n\n//sys\taccept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) = libsocket.accept4\n\nfunc Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {\n\tvar rsa RawSockaddrAny\n\tvar len _Socklen = SizeofSockaddrAny\n\tnfd, err = accept4(fd, &rsa, &len, flags)\n\tif err != nil {\n\t\treturn\n\t}\n\tif len > SizeofSockaddrAny {\n\t\tpanic(\"RawSockaddrAny too small\")\n\t}\n\tsa, err = anyToSockaddr(fd, &rsa)\n\tif err != nil {\n\t\tClose(nfd)\n\t\tnfd = 0\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux.go",
    "content": "// Copyright 2009 The Go 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\n// Linux system calls.\n// This file is compiled as ordinary Go code,\n// but it is also input to mksyscall,\n// which parses the //sys lines and generates system call stubs.\n// Note that sometimes we use a lowercase //sys name and\n// wrap it in our own nicer implementation.\n\npackage unix\n\nimport (\n\t\"encoding/binary\"\n\t\"slices\"\n\t\"strconv\"\n\t\"syscall\"\n\t\"time\"\n\t\"unsafe\"\n)\n\n/*\n * Wrapped\n */\n\nfunc Access(path string, mode uint32) (err error) {\n\treturn Faccessat(AT_FDCWD, path, mode, 0)\n}\n\nfunc Chmod(path string, mode uint32) (err error) {\n\treturn Fchmodat(AT_FDCWD, path, mode, 0)\n}\n\nfunc Chown(path string, uid int, gid int) (err error) {\n\treturn Fchownat(AT_FDCWD, path, uid, gid, 0)\n}\n\nfunc Creat(path string, mode uint32) (fd int, err error) {\n\treturn Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)\n}\n\nfunc EpollCreate(size int) (fd int, err error) {\n\tif size <= 0 {\n\t\treturn -1, EINVAL\n\t}\n\treturn EpollCreate1(0)\n}\n\n//sys\tFanotifyInit(flags uint, event_f_flags uint) (fd int, err error)\n//sys\tfanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error)\n\nfunc FanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname string) (err error) {\n\tif pathname == \"\" {\n\t\treturn fanotifyMark(fd, flags, mask, dirFd, nil)\n\t}\n\tp, err := BytePtrFromString(pathname)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn fanotifyMark(fd, flags, mask, dirFd, p)\n}\n\n//sys\tfchmodat(dirfd int, path string, mode uint32) (err error)\n//sys\tfchmodat2(dirfd int, path string, mode uint32, flags int) (err error)\n\nfunc Fchmodat(dirfd int, path string, mode uint32, flags int) error {\n\t// Linux fchmodat doesn't support the flags parameter, but fchmodat2 does.\n\t// Try fchmodat2 if flags are specified.\n\tif flags != 0 {\n\t\terr := fchmodat2(dirfd, path, mode, flags)\n\t\tif err == ENOSYS {\n\t\t\t// fchmodat2 isn't available. If the flags are known to be valid,\n\t\t\t// return EOPNOTSUPP to indicate that fchmodat doesn't support them.\n\t\t\tif flags&^(AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) != 0 {\n\t\t\t\treturn EINVAL\n\t\t\t} else if flags&(AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) != 0 {\n\t\t\t\treturn EOPNOTSUPP\n\t\t\t}\n\t\t}\n\t\treturn err\n\t}\n\treturn fchmodat(dirfd, path, mode)\n}\n\nfunc InotifyInit() (fd int, err error) {\n\treturn InotifyInit1(0)\n}\n\n//sys\tioctl(fd int, req uint, arg uintptr) (err error) = SYS_IOCTL\n//sys\tioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL\n\n// ioctl itself should not be exposed directly, but additional get/set functions\n// for specific types are permissible. These are defined in ioctl.go and\n// ioctl_linux.go.\n//\n// The third argument to ioctl is often a pointer but sometimes an integer.\n// Callers should use ioctlPtr when the third argument is a pointer and ioctl\n// when the third argument is an integer.\n//\n// TODO: some existing code incorrectly uses ioctl when it should use ioctlPtr.\n\n//sys\tLinkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)\n\nfunc Link(oldpath string, newpath string) (err error) {\n\treturn Linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0)\n}\n\nfunc Mkdir(path string, mode uint32) (err error) {\n\treturn Mkdirat(AT_FDCWD, path, mode)\n}\n\nfunc Mknod(path string, mode uint32, dev int) (err error) {\n\treturn Mknodat(AT_FDCWD, path, mode, dev)\n}\n\nfunc Open(path string, mode int, perm uint32) (fd int, err error) {\n\treturn openat(AT_FDCWD, path, mode|O_LARGEFILE, perm)\n}\n\n//sys\topenat(dirfd int, path string, flags int, mode uint32) (fd int, err error)\n\nfunc Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {\n\treturn openat(dirfd, path, flags|O_LARGEFILE, mode)\n}\n\n//sys\topenat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error)\n\nfunc Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) {\n\treturn openat2(dirfd, path, how, SizeofOpenHow)\n}\n\nfunc Pipe(p []int) error {\n\treturn Pipe2(p, 0)\n}\n\n//sysnb\tpipe2(p *[2]_C_int, flags int) (err error)\n\nfunc Pipe2(p []int, flags int) error {\n\tif len(p) != 2 {\n\t\treturn EINVAL\n\t}\n\tvar pp [2]_C_int\n\terr := pipe2(&pp, flags)\n\tif err == nil {\n\t\tp[0] = int(pp[0])\n\t\tp[1] = int(pp[1])\n\t}\n\treturn err\n}\n\n//sys\tppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)\n\nfunc Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {\n\tif len(fds) == 0 {\n\t\treturn ppoll(nil, 0, timeout, sigmask)\n\t}\n\treturn ppoll(&fds[0], len(fds), timeout, sigmask)\n}\n\nfunc Poll(fds []PollFd, timeout int) (n int, err error) {\n\tvar ts *Timespec\n\tif timeout >= 0 {\n\t\tts = new(Timespec)\n\t\t*ts = NsecToTimespec(int64(timeout) * 1e6)\n\t}\n\treturn Ppoll(fds, ts, nil)\n}\n\n//sys\tReadlinkat(dirfd int, path string, buf []byte) (n int, err error)\n\nfunc Readlink(path string, buf []byte) (n int, err error) {\n\treturn Readlinkat(AT_FDCWD, path, buf)\n}\n\nfunc Rename(oldpath string, newpath string) (err error) {\n\treturn Renameat(AT_FDCWD, oldpath, AT_FDCWD, newpath)\n}\n\nfunc Rmdir(path string) error {\n\treturn Unlinkat(AT_FDCWD, path, AT_REMOVEDIR)\n}\n\n//sys\tSymlinkat(oldpath string, newdirfd int, newpath string) (err error)\n\nfunc Symlink(oldpath string, newpath string) (err error) {\n\treturn Symlinkat(oldpath, AT_FDCWD, newpath)\n}\n\nfunc Unlink(path string) error {\n\treturn Unlinkat(AT_FDCWD, path, 0)\n}\n\n//sys\tUnlinkat(dirfd int, path string, flags int) (err error)\n\nfunc Utimes(path string, tv []Timeval) error {\n\tif tv == nil {\n\t\terr := utimensat(AT_FDCWD, path, nil, 0)\n\t\tif err != ENOSYS {\n\t\t\treturn err\n\t\t}\n\t\treturn utimes(path, nil)\n\t}\n\tif len(tv) != 2 {\n\t\treturn EINVAL\n\t}\n\tvar ts [2]Timespec\n\tts[0] = NsecToTimespec(TimevalToNsec(tv[0]))\n\tts[1] = NsecToTimespec(TimevalToNsec(tv[1]))\n\terr := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)\n\tif err != ENOSYS {\n\t\treturn err\n\t}\n\treturn utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))\n}\n\n//sys\tutimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)\n\nfunc UtimesNano(path string, ts []Timespec) error {\n\treturn UtimesNanoAt(AT_FDCWD, path, ts, 0)\n}\n\nfunc UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {\n\tif ts == nil {\n\t\treturn utimensat(dirfd, path, nil, flags)\n\t}\n\tif len(ts) != 2 {\n\t\treturn EINVAL\n\t}\n\treturn utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)\n}\n\nfunc Futimesat(dirfd int, path string, tv []Timeval) error {\n\tif tv == nil {\n\t\treturn futimesat(dirfd, path, nil)\n\t}\n\tif len(tv) != 2 {\n\t\treturn EINVAL\n\t}\n\treturn futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))\n}\n\nfunc Futimes(fd int, tv []Timeval) (err error) {\n\t// Believe it or not, this is the best we can do on Linux\n\t// (and is what glibc does).\n\treturn Utimes(\"/proc/self/fd/\"+strconv.Itoa(fd), tv)\n}\n\nconst ImplementsGetwd = true\n\n//sys\tGetcwd(buf []byte) (n int, err error)\n\nfunc Getwd() (wd string, err error) {\n\tvar buf [PathMax]byte\n\tn, err := Getcwd(buf[0:])\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\t// Getcwd returns the number of bytes written to buf, including the NUL.\n\tif n < 1 || n > len(buf) || buf[n-1] != 0 {\n\t\treturn \"\", EINVAL\n\t}\n\t// In some cases, Linux can return a path that starts with the\n\t// \"(unreachable)\" prefix, which can potentially be a valid relative\n\t// path. To work around that, return ENOENT if path is not absolute.\n\tif buf[0] != '/' {\n\t\treturn \"\", ENOENT\n\t}\n\n\treturn string(buf[0 : n-1]), nil\n}\n\nfunc Getgroups() (gids []int, err error) {\n\tn, err := getgroups(0, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif n == 0 {\n\t\treturn nil, nil\n\t}\n\n\t// Sanity check group count. Max is 1<<16 on Linux.\n\tif n < 0 || n > 1<<20 {\n\t\treturn nil, EINVAL\n\t}\n\n\ta := make([]_Gid_t, n)\n\tn, err = getgroups(n, &a[0])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tgids = make([]int, n)\n\tfor i, v := range a[0:n] {\n\t\tgids[i] = int(v)\n\t}\n\treturn\n}\n\nfunc Setgroups(gids []int) (err error) {\n\tif len(gids) == 0 {\n\t\treturn setgroups(0, nil)\n\t}\n\n\ta := make([]_Gid_t, len(gids))\n\tfor i, v := range gids {\n\t\ta[i] = _Gid_t(v)\n\t}\n\treturn setgroups(len(a), &a[0])\n}\n\ntype WaitStatus uint32\n\n// Wait status is 7 bits at bottom, either 0 (exited),\n// 0x7F (stopped), or a signal number that caused an exit.\n// The 0x80 bit is whether there was a core dump.\n// An extra number (exit code, signal causing a stop)\n// is in the high bits. At least that's the idea.\n// There are various irregularities. For example, the\n// \"continued\" status is 0xFFFF, distinguishing itself\n// from stopped via the core dump bit.\n\nconst (\n\tmask    = 0x7F\n\tcore    = 0x80\n\texited  = 0x00\n\tstopped = 0x7F\n\tshift   = 8\n)\n\nfunc (w WaitStatus) Exited() bool { return w&mask == exited }\n\nfunc (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }\n\nfunc (w WaitStatus) Stopped() bool { return w&0xFF == stopped }\n\nfunc (w WaitStatus) Continued() bool { return w == 0xFFFF }\n\nfunc (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }\n\nfunc (w WaitStatus) ExitStatus() int {\n\tif !w.Exited() {\n\t\treturn -1\n\t}\n\treturn int(w>>shift) & 0xFF\n}\n\nfunc (w WaitStatus) Signal() syscall.Signal {\n\tif !w.Signaled() {\n\t\treturn -1\n\t}\n\treturn syscall.Signal(w & mask)\n}\n\nfunc (w WaitStatus) StopSignal() syscall.Signal {\n\tif !w.Stopped() {\n\t\treturn -1\n\t}\n\treturn syscall.Signal(w>>shift) & 0xFF\n}\n\nfunc (w WaitStatus) TrapCause() int {\n\tif w.StopSignal() != SIGTRAP {\n\t\treturn -1\n\t}\n\treturn int(w>>shift) >> 8\n}\n\n//sys\twait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)\n\nfunc Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {\n\tvar status _C_int\n\twpid, err = wait4(pid, &status, options, rusage)\n\tif wstatus != nil {\n\t\t*wstatus = WaitStatus(status)\n\t}\n\treturn\n}\n\n//sys\tWaitid(idType int, id int, info *Siginfo, options int, rusage *Rusage) (err error)\n\nfunc Mkfifo(path string, mode uint32) error {\n\treturn Mknod(path, mode|S_IFIFO, 0)\n}\n\nfunc Mkfifoat(dirfd int, path string, mode uint32) error {\n\treturn Mknodat(dirfd, path, mode|S_IFIFO, 0)\n}\n\nfunc (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tif sa.Port < 0 || sa.Port > 0xFFFF {\n\t\treturn nil, 0, EINVAL\n\t}\n\tsa.raw.Family = AF_INET\n\tp := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))\n\tp[0] = byte(sa.Port >> 8)\n\tp[1] = byte(sa.Port)\n\tsa.raw.Addr = sa.Addr\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil\n}\n\nfunc (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tif sa.Port < 0 || sa.Port > 0xFFFF {\n\t\treturn nil, 0, EINVAL\n\t}\n\tsa.raw.Family = AF_INET6\n\tp := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))\n\tp[0] = byte(sa.Port >> 8)\n\tp[1] = byte(sa.Port)\n\tsa.raw.Scope_id = sa.ZoneId\n\tsa.raw.Addr = sa.Addr\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil\n}\n\nfunc (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tname := sa.Name\n\tn := len(name)\n\tif n >= len(sa.raw.Path) {\n\t\treturn nil, 0, EINVAL\n\t}\n\tsa.raw.Family = AF_UNIX\n\tfor i := range n {\n\t\tsa.raw.Path[i] = int8(name[i])\n\t}\n\t// length is family (uint16), name, NUL.\n\tsl := _Socklen(2)\n\tif n > 0 {\n\t\tsl += _Socklen(n) + 1\n\t}\n\tif sa.raw.Path[0] == '@' || (sa.raw.Path[0] == 0 && sl > 3) {\n\t\t// Check sl > 3 so we don't change unnamed socket behavior.\n\t\tsa.raw.Path[0] = 0\n\t\t// Don't count trailing NUL for abstract address.\n\t\tsl--\n\t}\n\n\treturn unsafe.Pointer(&sa.raw), sl, nil\n}\n\n// SockaddrLinklayer implements the Sockaddr interface for AF_PACKET type sockets.\ntype SockaddrLinklayer struct {\n\tProtocol uint16\n\tIfindex  int\n\tHatype   uint16\n\tPkttype  uint8\n\tHalen    uint8\n\tAddr     [8]byte\n\traw      RawSockaddrLinklayer\n}\n\nfunc (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tif sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {\n\t\treturn nil, 0, EINVAL\n\t}\n\tsa.raw.Family = AF_PACKET\n\tsa.raw.Protocol = sa.Protocol\n\tsa.raw.Ifindex = int32(sa.Ifindex)\n\tsa.raw.Hatype = sa.Hatype\n\tsa.raw.Pkttype = sa.Pkttype\n\tsa.raw.Halen = sa.Halen\n\tsa.raw.Addr = sa.Addr\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil\n}\n\n// SockaddrNetlink implements the Sockaddr interface for AF_NETLINK type sockets.\ntype SockaddrNetlink struct {\n\tFamily uint16\n\tPad    uint16\n\tPid    uint32\n\tGroups uint32\n\traw    RawSockaddrNetlink\n}\n\nfunc (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tsa.raw.Family = AF_NETLINK\n\tsa.raw.Pad = sa.Pad\n\tsa.raw.Pid = sa.Pid\n\tsa.raw.Groups = sa.Groups\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil\n}\n\n// SockaddrHCI implements the Sockaddr interface for AF_BLUETOOTH type sockets\n// using the HCI protocol.\ntype SockaddrHCI struct {\n\tDev     uint16\n\tChannel uint16\n\traw     RawSockaddrHCI\n}\n\nfunc (sa *SockaddrHCI) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tsa.raw.Family = AF_BLUETOOTH\n\tsa.raw.Dev = sa.Dev\n\tsa.raw.Channel = sa.Channel\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrHCI, nil\n}\n\n// SockaddrL2 implements the Sockaddr interface for AF_BLUETOOTH type sockets\n// using the L2CAP protocol.\ntype SockaddrL2 struct {\n\tPSM      uint16\n\tCID      uint16\n\tAddr     [6]uint8\n\tAddrType uint8\n\traw      RawSockaddrL2\n}\n\nfunc (sa *SockaddrL2) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tsa.raw.Family = AF_BLUETOOTH\n\tpsm := (*[2]byte)(unsafe.Pointer(&sa.raw.Psm))\n\tpsm[0] = byte(sa.PSM)\n\tpsm[1] = byte(sa.PSM >> 8)\n\tfor i := range len(sa.Addr) {\n\t\tsa.raw.Bdaddr[i] = sa.Addr[len(sa.Addr)-1-i]\n\t}\n\tcid := (*[2]byte)(unsafe.Pointer(&sa.raw.Cid))\n\tcid[0] = byte(sa.CID)\n\tcid[1] = byte(sa.CID >> 8)\n\tsa.raw.Bdaddr_type = sa.AddrType\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrL2, nil\n}\n\n// SockaddrRFCOMM implements the Sockaddr interface for AF_BLUETOOTH type sockets\n// using the RFCOMM protocol.\n//\n// Server example:\n//\n//\tfd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)\n//\t_ = unix.Bind(fd, &unix.SockaddrRFCOMM{\n//\t\tChannel: 1,\n//\t\tAddr:    [6]uint8{0, 0, 0, 0, 0, 0}, // BDADDR_ANY or 00:00:00:00:00:00\n//\t})\n//\t_ = Listen(fd, 1)\n//\tnfd, sa, _ := Accept(fd)\n//\tfmt.Printf(\"conn addr=%v fd=%d\", sa.(*unix.SockaddrRFCOMM).Addr, nfd)\n//\tRead(nfd, buf)\n//\n// Client example:\n//\n//\tfd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)\n//\t_ = Connect(fd, &SockaddrRFCOMM{\n//\t\tChannel: 1,\n//\t\tAddr:    [6]byte{0x11, 0x22, 0x33, 0xaa, 0xbb, 0xcc}, // CC:BB:AA:33:22:11\n//\t})\n//\tWrite(fd, []byte(`hello`))\ntype SockaddrRFCOMM struct {\n\t// Addr represents a bluetooth address, byte ordering is little-endian.\n\tAddr [6]uint8\n\n\t// Channel is a designated bluetooth channel, only 1-30 are available for use.\n\t// Since Linux 2.6.7 and further zero value is the first available channel.\n\tChannel uint8\n\n\traw RawSockaddrRFCOMM\n}\n\nfunc (sa *SockaddrRFCOMM) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tsa.raw.Family = AF_BLUETOOTH\n\tsa.raw.Channel = sa.Channel\n\tsa.raw.Bdaddr = sa.Addr\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrRFCOMM, nil\n}\n\n// SockaddrCAN implements the Sockaddr interface for AF_CAN type sockets.\n// The RxID and TxID fields are used for transport protocol addressing in\n// (CAN_TP16, CAN_TP20, CAN_MCNET, and CAN_ISOTP), they can be left with\n// zero values for CAN_RAW and CAN_BCM sockets as they have no meaning.\n//\n// The SockaddrCAN struct must be bound to the socket file descriptor\n// using Bind before the CAN socket can be used.\n//\n//\t// Read one raw CAN frame\n//\tfd, _ := Socket(AF_CAN, SOCK_RAW, CAN_RAW)\n//\taddr := &SockaddrCAN{Ifindex: index}\n//\tBind(fd, addr)\n//\tframe := make([]byte, 16)\n//\tRead(fd, frame)\n//\n// The full SocketCAN documentation can be found in the linux kernel\n// archives at: https://www.kernel.org/doc/Documentation/networking/can.txt\ntype SockaddrCAN struct {\n\tIfindex int\n\tRxID    uint32\n\tTxID    uint32\n\traw     RawSockaddrCAN\n}\n\nfunc (sa *SockaddrCAN) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tif sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {\n\t\treturn nil, 0, EINVAL\n\t}\n\tsa.raw.Family = AF_CAN\n\tsa.raw.Ifindex = int32(sa.Ifindex)\n\trx := (*[4]byte)(unsafe.Pointer(&sa.RxID))\n\tfor i := range 4 {\n\t\tsa.raw.Addr[i] = rx[i]\n\t}\n\ttx := (*[4]byte)(unsafe.Pointer(&sa.TxID))\n\tfor i := range 4 {\n\t\tsa.raw.Addr[i+4] = tx[i]\n\t}\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil\n}\n\n// SockaddrCANJ1939 implements the Sockaddr interface for AF_CAN using J1939\n// protocol (https://en.wikipedia.org/wiki/SAE_J1939). For more information\n// on the purposes of the fields, check the official linux kernel documentation\n// available here: https://www.kernel.org/doc/Documentation/networking/j1939.rst\ntype SockaddrCANJ1939 struct {\n\tIfindex int\n\tName    uint64\n\tPGN     uint32\n\tAddr    uint8\n\traw     RawSockaddrCAN\n}\n\nfunc (sa *SockaddrCANJ1939) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tif sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {\n\t\treturn nil, 0, EINVAL\n\t}\n\tsa.raw.Family = AF_CAN\n\tsa.raw.Ifindex = int32(sa.Ifindex)\n\tn := (*[8]byte)(unsafe.Pointer(&sa.Name))\n\tfor i := range 8 {\n\t\tsa.raw.Addr[i] = n[i]\n\t}\n\tp := (*[4]byte)(unsafe.Pointer(&sa.PGN))\n\tfor i := range 4 {\n\t\tsa.raw.Addr[i+8] = p[i]\n\t}\n\tsa.raw.Addr[12] = sa.Addr\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil\n}\n\n// SockaddrALG implements the Sockaddr interface for AF_ALG type sockets.\n// SockaddrALG enables userspace access to the Linux kernel's cryptography\n// subsystem. The Type and Name fields specify which type of hash or cipher\n// should be used with a given socket.\n//\n// To create a file descriptor that provides access to a hash or cipher, both\n// Bind and Accept must be used. Once the setup process is complete, input\n// data can be written to the socket, processed by the kernel, and then read\n// back as hash output or ciphertext.\n//\n// Here is an example of using an AF_ALG socket with SHA1 hashing.\n// The initial socket setup process is as follows:\n//\n//\t// Open a socket to perform SHA1 hashing.\n//\tfd, _ := unix.Socket(unix.AF_ALG, unix.SOCK_SEQPACKET, 0)\n//\taddr := &unix.SockaddrALG{Type: \"hash\", Name: \"sha1\"}\n//\tunix.Bind(fd, addr)\n//\t// Note: unix.Accept does not work at this time; must invoke accept()\n//\t// manually using unix.Syscall.\n//\thashfd, _, _ := unix.Syscall(unix.SYS_ACCEPT, uintptr(fd), 0, 0)\n//\n// Once a file descriptor has been returned from Accept, it may be used to\n// perform SHA1 hashing. The descriptor is not safe for concurrent use, but\n// may be re-used repeatedly with subsequent Write and Read operations.\n//\n// When hashing a small byte slice or string, a single Write and Read may\n// be used:\n//\n//\t// Assume hashfd is already configured using the setup process.\n//\thash := os.NewFile(hashfd, \"sha1\")\n//\t// Hash an input string and read the results. Each Write discards\n//\t// previous hash state. Read always reads the current state.\n//\tb := make([]byte, 20)\n//\tfor i := 0; i < 2; i++ {\n//\t    io.WriteString(hash, \"Hello, world.\")\n//\t    hash.Read(b)\n//\t    fmt.Println(hex.EncodeToString(b))\n//\t}\n//\t// Output:\n//\t// 2ae01472317d1935a84797ec1983ae243fc6aa28\n//\t// 2ae01472317d1935a84797ec1983ae243fc6aa28\n//\n// For hashing larger byte slices, or byte streams such as those read from\n// a file or socket, use Sendto with MSG_MORE to instruct the kernel to update\n// the hash digest instead of creating a new one for a given chunk and finalizing it.\n//\n//\t// Assume hashfd and addr are already configured using the setup process.\n//\thash := os.NewFile(hashfd, \"sha1\")\n//\t// Hash the contents of a file.\n//\tf, _ := os.Open(\"/tmp/linux-4.10-rc7.tar.xz\")\n//\tb := make([]byte, 4096)\n//\tfor {\n//\t    n, err := f.Read(b)\n//\t    if err == io.EOF {\n//\t        break\n//\t    }\n//\t    unix.Sendto(hashfd, b[:n], unix.MSG_MORE, addr)\n//\t}\n//\thash.Read(b)\n//\tfmt.Println(hex.EncodeToString(b))\n//\t// Output: 85cdcad0c06eef66f805ecce353bec9accbeecc5\n//\n// For more information, see: http://www.chronox.de/crypto-API/crypto/userspace-if.html.\ntype SockaddrALG struct {\n\tType    string\n\tName    string\n\tFeature uint32\n\tMask    uint32\n\traw     RawSockaddrALG\n}\n\nfunc (sa *SockaddrALG) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\t// Leave room for NUL byte terminator.\n\tif len(sa.Type) > len(sa.raw.Type)-1 {\n\t\treturn nil, 0, EINVAL\n\t}\n\tif len(sa.Name) > len(sa.raw.Name)-1 {\n\t\treturn nil, 0, EINVAL\n\t}\n\n\tsa.raw.Family = AF_ALG\n\tsa.raw.Feat = sa.Feature\n\tsa.raw.Mask = sa.Mask\n\n\tcopy(sa.raw.Type[:], sa.Type)\n\tcopy(sa.raw.Name[:], sa.Name)\n\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrALG, nil\n}\n\n// SockaddrVM implements the Sockaddr interface for AF_VSOCK type sockets.\n// SockaddrVM provides access to Linux VM sockets: a mechanism that enables\n// bidirectional communication between a hypervisor and its guest virtual\n// machines.\ntype SockaddrVM struct {\n\t// CID and Port specify a context ID and port address for a VM socket.\n\t// Guests have a unique CID, and hosts may have a well-known CID of:\n\t//  - VMADDR_CID_HYPERVISOR: refers to the hypervisor process.\n\t//  - VMADDR_CID_LOCAL: refers to local communication (loopback).\n\t//  - VMADDR_CID_HOST: refers to other processes on the host.\n\tCID   uint32\n\tPort  uint32\n\tFlags uint8\n\traw   RawSockaddrVM\n}\n\nfunc (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tsa.raw.Family = AF_VSOCK\n\tsa.raw.Port = sa.Port\n\tsa.raw.Cid = sa.CID\n\tsa.raw.Flags = sa.Flags\n\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil\n}\n\ntype SockaddrXDP struct {\n\tFlags        uint16\n\tIfindex      uint32\n\tQueueID      uint32\n\tSharedUmemFD uint32\n\traw          RawSockaddrXDP\n}\n\nfunc (sa *SockaddrXDP) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tsa.raw.Family = AF_XDP\n\tsa.raw.Flags = sa.Flags\n\tsa.raw.Ifindex = sa.Ifindex\n\tsa.raw.Queue_id = sa.QueueID\n\tsa.raw.Shared_umem_fd = sa.SharedUmemFD\n\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrXDP, nil\n}\n\n// This constant mirrors the #define of PX_PROTO_OE in\n// linux/if_pppox.h. We're defining this by hand here instead of\n// autogenerating through mkerrors.sh because including\n// linux/if_pppox.h causes some declaration conflicts with other\n// includes (linux/if_pppox.h includes linux/in.h, which conflicts\n// with netinet/in.h). Given that we only need a single zero constant\n// out of that file, it's cleaner to just define it by hand here.\nconst px_proto_oe = 0\n\ntype SockaddrPPPoE struct {\n\tSID    uint16\n\tRemote []byte\n\tDev    string\n\traw    RawSockaddrPPPoX\n}\n\nfunc (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tif len(sa.Remote) != 6 {\n\t\treturn nil, 0, EINVAL\n\t}\n\tif len(sa.Dev) > IFNAMSIZ-1 {\n\t\treturn nil, 0, EINVAL\n\t}\n\n\t*(*uint16)(unsafe.Pointer(&sa.raw[0])) = AF_PPPOX\n\t// This next field is in host-endian byte order. We can't use the\n\t// same unsafe pointer cast as above, because this value is not\n\t// 32-bit aligned and some architectures don't allow unaligned\n\t// access.\n\t//\n\t// However, the value of px_proto_oe is 0, so we can use\n\t// encoding/binary helpers to write the bytes without worrying\n\t// about the ordering.\n\tbinary.BigEndian.PutUint32(sa.raw[2:6], px_proto_oe)\n\t// This field is deliberately big-endian, unlike the previous\n\t// one. The kernel expects SID to be in network byte order.\n\tbinary.BigEndian.PutUint16(sa.raw[6:8], sa.SID)\n\tcopy(sa.raw[8:14], sa.Remote)\n\tclear(sa.raw[14 : 14+IFNAMSIZ])\n\tcopy(sa.raw[14:], sa.Dev)\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil\n}\n\n// SockaddrTIPC implements the Sockaddr interface for AF_TIPC type sockets.\n// For more information on TIPC, see: http://tipc.sourceforge.net/.\ntype SockaddrTIPC struct {\n\t// Scope is the publication scopes when binding service/service range.\n\t// Should be set to TIPC_CLUSTER_SCOPE or TIPC_NODE_SCOPE.\n\tScope int\n\n\t// Addr is the type of address used to manipulate a socket. Addr must be\n\t// one of:\n\t//  - *TIPCSocketAddr: \"id\" variant in the C addr union\n\t//  - *TIPCServiceRange: \"nameseq\" variant in the C addr union\n\t//  - *TIPCServiceName: \"name\" variant in the C addr union\n\t//\n\t// If nil, EINVAL will be returned when the structure is used.\n\tAddr TIPCAddr\n\n\traw RawSockaddrTIPC\n}\n\n// TIPCAddr is implemented by types that can be used as an address for\n// SockaddrTIPC. It is only implemented by *TIPCSocketAddr, *TIPCServiceRange,\n// and *TIPCServiceName.\ntype TIPCAddr interface {\n\ttipcAddrtype() uint8\n\ttipcAddr() [12]byte\n}\n\nfunc (sa *TIPCSocketAddr) tipcAddr() [12]byte {\n\tvar out [12]byte\n\tcopy(out[:], (*(*[unsafe.Sizeof(TIPCSocketAddr{})]byte)(unsafe.Pointer(sa)))[:])\n\treturn out\n}\n\nfunc (sa *TIPCSocketAddr) tipcAddrtype() uint8 { return TIPC_SOCKET_ADDR }\n\nfunc (sa *TIPCServiceRange) tipcAddr() [12]byte {\n\tvar out [12]byte\n\tcopy(out[:], (*(*[unsafe.Sizeof(TIPCServiceRange{})]byte)(unsafe.Pointer(sa)))[:])\n\treturn out\n}\n\nfunc (sa *TIPCServiceRange) tipcAddrtype() uint8 { return TIPC_SERVICE_RANGE }\n\nfunc (sa *TIPCServiceName) tipcAddr() [12]byte {\n\tvar out [12]byte\n\tcopy(out[:], (*(*[unsafe.Sizeof(TIPCServiceName{})]byte)(unsafe.Pointer(sa)))[:])\n\treturn out\n}\n\nfunc (sa *TIPCServiceName) tipcAddrtype() uint8 { return TIPC_SERVICE_ADDR }\n\nfunc (sa *SockaddrTIPC) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tif sa.Addr == nil {\n\t\treturn nil, 0, EINVAL\n\t}\n\tsa.raw.Family = AF_TIPC\n\tsa.raw.Scope = int8(sa.Scope)\n\tsa.raw.Addrtype = sa.Addr.tipcAddrtype()\n\tsa.raw.Addr = sa.Addr.tipcAddr()\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil\n}\n\n// SockaddrL2TPIP implements the Sockaddr interface for IPPROTO_L2TP/AF_INET sockets.\ntype SockaddrL2TPIP struct {\n\tAddr   [4]byte\n\tConnId uint32\n\traw    RawSockaddrL2TPIP\n}\n\nfunc (sa *SockaddrL2TPIP) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tsa.raw.Family = AF_INET\n\tsa.raw.Conn_id = sa.ConnId\n\tsa.raw.Addr = sa.Addr\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP, nil\n}\n\n// SockaddrL2TPIP6 implements the Sockaddr interface for IPPROTO_L2TP/AF_INET6 sockets.\ntype SockaddrL2TPIP6 struct {\n\tAddr   [16]byte\n\tZoneId uint32\n\tConnId uint32\n\traw    RawSockaddrL2TPIP6\n}\n\nfunc (sa *SockaddrL2TPIP6) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tsa.raw.Family = AF_INET6\n\tsa.raw.Conn_id = sa.ConnId\n\tsa.raw.Scope_id = sa.ZoneId\n\tsa.raw.Addr = sa.Addr\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil\n}\n\n// SockaddrIUCV implements the Sockaddr interface for AF_IUCV sockets.\ntype SockaddrIUCV struct {\n\tUserID string\n\tName   string\n\traw    RawSockaddrIUCV\n}\n\nfunc (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tsa.raw.Family = AF_IUCV\n\t// These are EBCDIC encoded by the kernel, but we still need to pad them\n\t// with blanks. Initializing with blanks allows the caller to feed in either\n\t// a padded or an unpadded string.\n\tfor i := range 8 {\n\t\tsa.raw.Nodeid[i] = ' '\n\t\tsa.raw.User_id[i] = ' '\n\t\tsa.raw.Name[i] = ' '\n\t}\n\tif len(sa.UserID) > 8 || len(sa.Name) > 8 {\n\t\treturn nil, 0, EINVAL\n\t}\n\tfor i, b := range []byte(sa.UserID[:]) {\n\t\tsa.raw.User_id[i] = int8(b)\n\t}\n\tfor i, b := range []byte(sa.Name[:]) {\n\t\tsa.raw.Name[i] = int8(b)\n\t}\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrIUCV, nil\n}\n\ntype SockaddrNFC struct {\n\tDeviceIdx   uint32\n\tTargetIdx   uint32\n\tNFCProtocol uint32\n\traw         RawSockaddrNFC\n}\n\nfunc (sa *SockaddrNFC) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tsa.raw.Sa_family = AF_NFC\n\tsa.raw.Dev_idx = sa.DeviceIdx\n\tsa.raw.Target_idx = sa.TargetIdx\n\tsa.raw.Nfc_protocol = sa.NFCProtocol\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrNFC, nil\n}\n\ntype SockaddrNFCLLCP struct {\n\tDeviceIdx      uint32\n\tTargetIdx      uint32\n\tNFCProtocol    uint32\n\tDestinationSAP uint8\n\tSourceSAP      uint8\n\tServiceName    string\n\traw            RawSockaddrNFCLLCP\n}\n\nfunc (sa *SockaddrNFCLLCP) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tsa.raw.Sa_family = AF_NFC\n\tsa.raw.Dev_idx = sa.DeviceIdx\n\tsa.raw.Target_idx = sa.TargetIdx\n\tsa.raw.Nfc_protocol = sa.NFCProtocol\n\tsa.raw.Dsap = sa.DestinationSAP\n\tsa.raw.Ssap = sa.SourceSAP\n\tif len(sa.ServiceName) > len(sa.raw.Service_name) {\n\t\treturn nil, 0, EINVAL\n\t}\n\tcopy(sa.raw.Service_name[:], sa.ServiceName)\n\tsa.raw.SetServiceNameLen(len(sa.ServiceName))\n\treturn unsafe.Pointer(&sa.raw), SizeofSockaddrNFCLLCP, nil\n}\n\nvar socketProtocol = func(fd int) (int, error) {\n\treturn GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)\n}\n\nfunc anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {\n\tswitch rsa.Addr.Family {\n\tcase AF_NETLINK:\n\t\tpp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))\n\t\tsa := new(SockaddrNetlink)\n\t\tsa.Family = pp.Family\n\t\tsa.Pad = pp.Pad\n\t\tsa.Pid = pp.Pid\n\t\tsa.Groups = pp.Groups\n\t\treturn sa, nil\n\n\tcase AF_PACKET:\n\t\tpp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))\n\t\tsa := new(SockaddrLinklayer)\n\t\tsa.Protocol = pp.Protocol\n\t\tsa.Ifindex = int(pp.Ifindex)\n\t\tsa.Hatype = pp.Hatype\n\t\tsa.Pkttype = pp.Pkttype\n\t\tsa.Halen = pp.Halen\n\t\tsa.Addr = pp.Addr\n\t\treturn sa, nil\n\n\tcase AF_UNIX:\n\t\tpp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))\n\t\tsa := new(SockaddrUnix)\n\t\tif pp.Path[0] == 0 {\n\t\t\t// \"Abstract\" Unix domain socket.\n\t\t\t// Rewrite leading NUL as @ for textual display.\n\t\t\t// (This is the standard convention.)\n\t\t\t// Not friendly to overwrite in place,\n\t\t\t// but the callers below don't care.\n\t\t\tpp.Path[0] = '@'\n\t\t}\n\n\t\t// Assume path ends at NUL.\n\t\t// This is not technically the Linux semantics for\n\t\t// abstract Unix domain sockets--they are supposed\n\t\t// to be uninterpreted fixed-size binary blobs--but\n\t\t// everyone uses this convention.\n\t\tn := 0\n\t\tfor n < len(pp.Path) && pp.Path[n] != 0 {\n\t\t\tn++\n\t\t}\n\t\tsa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))\n\t\treturn sa, nil\n\n\tcase AF_INET:\n\t\tproto, err := socketProtocol(fd)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tswitch proto {\n\t\tcase IPPROTO_L2TP:\n\t\t\tpp := (*RawSockaddrL2TPIP)(unsafe.Pointer(rsa))\n\t\t\tsa := new(SockaddrL2TPIP)\n\t\t\tsa.ConnId = pp.Conn_id\n\t\t\tsa.Addr = pp.Addr\n\t\t\treturn sa, nil\n\t\tdefault:\n\t\t\tpp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))\n\t\t\tsa := new(SockaddrInet4)\n\t\t\tp := (*[2]byte)(unsafe.Pointer(&pp.Port))\n\t\t\tsa.Port = int(p[0])<<8 + int(p[1])\n\t\t\tsa.Addr = pp.Addr\n\t\t\treturn sa, nil\n\t\t}\n\n\tcase AF_INET6:\n\t\tproto, err := socketProtocol(fd)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tswitch proto {\n\t\tcase IPPROTO_L2TP:\n\t\t\tpp := (*RawSockaddrL2TPIP6)(unsafe.Pointer(rsa))\n\t\t\tsa := new(SockaddrL2TPIP6)\n\t\t\tsa.ConnId = pp.Conn_id\n\t\t\tsa.ZoneId = pp.Scope_id\n\t\t\tsa.Addr = pp.Addr\n\t\t\treturn sa, nil\n\t\tdefault:\n\t\t\tpp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))\n\t\t\tsa := new(SockaddrInet6)\n\t\t\tp := (*[2]byte)(unsafe.Pointer(&pp.Port))\n\t\t\tsa.Port = int(p[0])<<8 + int(p[1])\n\t\t\tsa.ZoneId = pp.Scope_id\n\t\t\tsa.Addr = pp.Addr\n\t\t\treturn sa, nil\n\t\t}\n\n\tcase AF_VSOCK:\n\t\tpp := (*RawSockaddrVM)(unsafe.Pointer(rsa))\n\t\tsa := &SockaddrVM{\n\t\t\tCID:   pp.Cid,\n\t\t\tPort:  pp.Port,\n\t\t\tFlags: pp.Flags,\n\t\t}\n\t\treturn sa, nil\n\tcase AF_BLUETOOTH:\n\t\tproto, err := socketProtocol(fd)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// only BTPROTO_L2CAP and BTPROTO_RFCOMM can accept connections\n\t\tswitch proto {\n\t\tcase BTPROTO_L2CAP:\n\t\t\tpp := (*RawSockaddrL2)(unsafe.Pointer(rsa))\n\t\t\tsa := &SockaddrL2{\n\t\t\t\tPSM:      pp.Psm,\n\t\t\t\tCID:      pp.Cid,\n\t\t\t\tAddr:     pp.Bdaddr,\n\t\t\t\tAddrType: pp.Bdaddr_type,\n\t\t\t}\n\t\t\treturn sa, nil\n\t\tcase BTPROTO_RFCOMM:\n\t\t\tpp := (*RawSockaddrRFCOMM)(unsafe.Pointer(rsa))\n\t\t\tsa := &SockaddrRFCOMM{\n\t\t\t\tChannel: pp.Channel,\n\t\t\t\tAddr:    pp.Bdaddr,\n\t\t\t}\n\t\t\treturn sa, nil\n\t\t}\n\tcase AF_XDP:\n\t\tpp := (*RawSockaddrXDP)(unsafe.Pointer(rsa))\n\t\tsa := &SockaddrXDP{\n\t\t\tFlags:        pp.Flags,\n\t\t\tIfindex:      pp.Ifindex,\n\t\t\tQueueID:      pp.Queue_id,\n\t\t\tSharedUmemFD: pp.Shared_umem_fd,\n\t\t}\n\t\treturn sa, nil\n\tcase AF_PPPOX:\n\t\tpp := (*RawSockaddrPPPoX)(unsafe.Pointer(rsa))\n\t\tif binary.BigEndian.Uint32(pp[2:6]) != px_proto_oe {\n\t\t\treturn nil, EINVAL\n\t\t}\n\t\tsa := &SockaddrPPPoE{\n\t\t\tSID:    binary.BigEndian.Uint16(pp[6:8]),\n\t\t\tRemote: pp[8:14],\n\t\t}\n\t\tfor i := 14; i < 14+IFNAMSIZ; i++ {\n\t\t\tif pp[i] == 0 {\n\t\t\t\tsa.Dev = string(pp[14:i])\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\treturn sa, nil\n\tcase AF_TIPC:\n\t\tpp := (*RawSockaddrTIPC)(unsafe.Pointer(rsa))\n\n\t\tsa := &SockaddrTIPC{\n\t\t\tScope: int(pp.Scope),\n\t\t}\n\n\t\t// Determine which union variant is present in pp.Addr by checking\n\t\t// pp.Addrtype.\n\t\tswitch pp.Addrtype {\n\t\tcase TIPC_SERVICE_RANGE:\n\t\t\tsa.Addr = (*TIPCServiceRange)(unsafe.Pointer(&pp.Addr))\n\t\tcase TIPC_SERVICE_ADDR:\n\t\t\tsa.Addr = (*TIPCServiceName)(unsafe.Pointer(&pp.Addr))\n\t\tcase TIPC_SOCKET_ADDR:\n\t\t\tsa.Addr = (*TIPCSocketAddr)(unsafe.Pointer(&pp.Addr))\n\t\tdefault:\n\t\t\treturn nil, EINVAL\n\t\t}\n\n\t\treturn sa, nil\n\tcase AF_IUCV:\n\t\tpp := (*RawSockaddrIUCV)(unsafe.Pointer(rsa))\n\n\t\tvar user [8]byte\n\t\tvar name [8]byte\n\n\t\tfor i := range 8 {\n\t\t\tuser[i] = byte(pp.User_id[i])\n\t\t\tname[i] = byte(pp.Name[i])\n\t\t}\n\n\t\tsa := &SockaddrIUCV{\n\t\t\tUserID: string(user[:]),\n\t\t\tName:   string(name[:]),\n\t\t}\n\t\treturn sa, nil\n\n\tcase AF_CAN:\n\t\tproto, err := socketProtocol(fd)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tpp := (*RawSockaddrCAN)(unsafe.Pointer(rsa))\n\n\t\tswitch proto {\n\t\tcase CAN_J1939:\n\t\t\tsa := &SockaddrCANJ1939{\n\t\t\t\tIfindex: int(pp.Ifindex),\n\t\t\t}\n\t\t\tname := (*[8]byte)(unsafe.Pointer(&sa.Name))\n\t\t\tfor i := range 8 {\n\t\t\t\tname[i] = pp.Addr[i]\n\t\t\t}\n\t\t\tpgn := (*[4]byte)(unsafe.Pointer(&sa.PGN))\n\t\t\tfor i := range 4 {\n\t\t\t\tpgn[i] = pp.Addr[i+8]\n\t\t\t}\n\t\t\taddr := (*[1]byte)(unsafe.Pointer(&sa.Addr))\n\t\t\taddr[0] = pp.Addr[12]\n\t\t\treturn sa, nil\n\t\tdefault:\n\t\t\tsa := &SockaddrCAN{\n\t\t\t\tIfindex: int(pp.Ifindex),\n\t\t\t}\n\t\t\trx := (*[4]byte)(unsafe.Pointer(&sa.RxID))\n\t\t\tfor i := range 4 {\n\t\t\t\trx[i] = pp.Addr[i]\n\t\t\t}\n\t\t\ttx := (*[4]byte)(unsafe.Pointer(&sa.TxID))\n\t\t\tfor i := range 4 {\n\t\t\t\ttx[i] = pp.Addr[i+4]\n\t\t\t}\n\t\t\treturn sa, nil\n\t\t}\n\tcase AF_NFC:\n\t\tproto, err := socketProtocol(fd)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tswitch proto {\n\t\tcase NFC_SOCKPROTO_RAW:\n\t\t\tpp := (*RawSockaddrNFC)(unsafe.Pointer(rsa))\n\t\t\tsa := &SockaddrNFC{\n\t\t\t\tDeviceIdx:   pp.Dev_idx,\n\t\t\t\tTargetIdx:   pp.Target_idx,\n\t\t\t\tNFCProtocol: pp.Nfc_protocol,\n\t\t\t}\n\t\t\treturn sa, nil\n\t\tcase NFC_SOCKPROTO_LLCP:\n\t\t\tpp := (*RawSockaddrNFCLLCP)(unsafe.Pointer(rsa))\n\t\t\tif uint64(pp.Service_name_len) > uint64(len(pp.Service_name)) {\n\t\t\t\treturn nil, EINVAL\n\t\t\t}\n\t\t\tsa := &SockaddrNFCLLCP{\n\t\t\t\tDeviceIdx:      pp.Dev_idx,\n\t\t\t\tTargetIdx:      pp.Target_idx,\n\t\t\t\tNFCProtocol:    pp.Nfc_protocol,\n\t\t\t\tDestinationSAP: pp.Dsap,\n\t\t\t\tSourceSAP:      pp.Ssap,\n\t\t\t\tServiceName:    string(pp.Service_name[:pp.Service_name_len]),\n\t\t\t}\n\t\t\treturn sa, nil\n\t\tdefault:\n\t\t\treturn nil, EINVAL\n\t\t}\n\t}\n\treturn nil, EAFNOSUPPORT\n}\n\nfunc Accept(fd int) (nfd int, sa Sockaddr, err error) {\n\tvar rsa RawSockaddrAny\n\tvar len _Socklen = SizeofSockaddrAny\n\tnfd, err = accept4(fd, &rsa, &len, 0)\n\tif err != nil {\n\t\treturn\n\t}\n\tsa, err = anyToSockaddr(fd, &rsa)\n\tif err != nil {\n\t\tClose(nfd)\n\t\tnfd = 0\n\t}\n\treturn\n}\n\nfunc Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {\n\tvar rsa RawSockaddrAny\n\tvar len _Socklen = SizeofSockaddrAny\n\tnfd, err = accept4(fd, &rsa, &len, flags)\n\tif err != nil {\n\t\treturn\n\t}\n\tif len > SizeofSockaddrAny {\n\t\tpanic(\"RawSockaddrAny too small\")\n\t}\n\tsa, err = anyToSockaddr(fd, &rsa)\n\tif err != nil {\n\t\tClose(nfd)\n\t\tnfd = 0\n\t}\n\treturn\n}\n\nfunc Getsockname(fd int) (sa Sockaddr, err error) {\n\tvar rsa RawSockaddrAny\n\tvar len _Socklen = SizeofSockaddrAny\n\tif err = getsockname(fd, &rsa, &len); err != nil {\n\t\treturn\n\t}\n\treturn anyToSockaddr(fd, &rsa)\n}\n\nfunc GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {\n\tvar value IPMreqn\n\tvallen := _Socklen(SizeofIPMreqn)\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)\n\treturn &value, err\n}\n\nfunc GetsockoptUcred(fd, level, opt int) (*Ucred, error) {\n\tvar value Ucred\n\tvallen := _Socklen(SizeofUcred)\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)\n\treturn &value, err\n}\n\nfunc GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {\n\tvar value TCPInfo\n\tvallen := _Socklen(SizeofTCPInfo)\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)\n\treturn &value, err\n}\n\n// GetsockoptTCPCCVegasInfo returns algorithm specific congestion control information for a socket using the \"vegas\"\n// algorithm.\n//\n// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option:\n//\n//\talgo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION)\nfunc GetsockoptTCPCCVegasInfo(fd, level, opt int) (*TCPVegasInfo, error) {\n\tvar value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment\n\tvallen := _Socklen(SizeofTCPCCInfo)\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)\n\tout := (*TCPVegasInfo)(unsafe.Pointer(&value[0]))\n\treturn out, err\n}\n\n// GetsockoptTCPCCDCTCPInfo returns algorithm specific congestion control information for a socket using the \"dctp\"\n// algorithm.\n//\n// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option:\n//\n//\talgo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION)\nfunc GetsockoptTCPCCDCTCPInfo(fd, level, opt int) (*TCPDCTCPInfo, error) {\n\tvar value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment\n\tvallen := _Socklen(SizeofTCPCCInfo)\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)\n\tout := (*TCPDCTCPInfo)(unsafe.Pointer(&value[0]))\n\treturn out, err\n}\n\n// GetsockoptTCPCCBBRInfo returns algorithm specific congestion control information for a socket using the \"bbr\"\n// algorithm.\n//\n// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option:\n//\n//\talgo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION)\nfunc GetsockoptTCPCCBBRInfo(fd, level, opt int) (*TCPBBRInfo, error) {\n\tvar value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment\n\tvallen := _Socklen(SizeofTCPCCInfo)\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)\n\tout := (*TCPBBRInfo)(unsafe.Pointer(&value[0]))\n\treturn out, err\n}\n\n// GetsockoptString returns the string value of the socket option opt for the\n// socket associated with fd at the given socket level.\nfunc GetsockoptString(fd, level, opt int) (string, error) {\n\tbuf := make([]byte, 256)\n\tvallen := _Socklen(len(buf))\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)\n\tif err != nil {\n\t\tif err == ERANGE {\n\t\t\tbuf = make([]byte, vallen)\n\t\t\terr = getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t}\n\treturn ByteSliceToString(buf[:vallen]), nil\n}\n\nfunc GetsockoptTpacketStats(fd, level, opt int) (*TpacketStats, error) {\n\tvar value TpacketStats\n\tvallen := _Socklen(SizeofTpacketStats)\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)\n\treturn &value, err\n}\n\nfunc GetsockoptTpacketStatsV3(fd, level, opt int) (*TpacketStatsV3, error) {\n\tvar value TpacketStatsV3\n\tvallen := _Socklen(SizeofTpacketStatsV3)\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)\n\treturn &value, err\n}\n\nfunc SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))\n}\n\nfunc SetsockoptPacketMreq(fd, level, opt int, mreq *PacketMreq) error {\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))\n}\n\n// SetsockoptSockFprog attaches a classic BPF or an extended BPF program to a\n// socket to filter incoming packets.  See 'man 7 socket' for usage information.\nfunc SetsockoptSockFprog(fd, level, opt int, fprog *SockFprog) error {\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(fprog), unsafe.Sizeof(*fprog))\n}\n\nfunc SetsockoptCanRawFilter(fd, level, opt int, filter []CanFilter) error {\n\tvar p unsafe.Pointer\n\tif len(filter) > 0 {\n\t\tp = unsafe.Pointer(&filter[0])\n\t}\n\treturn setsockopt(fd, level, opt, p, uintptr(len(filter)*SizeofCanFilter))\n}\n\nfunc SetsockoptTpacketReq(fd, level, opt int, tp *TpacketReq) error {\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp))\n}\n\nfunc SetsockoptTpacketReq3(fd, level, opt int, tp *TpacketReq3) error {\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp))\n}\n\nfunc SetsockoptTCPRepairOpt(fd, level, opt int, o []TCPRepairOpt) (err error) {\n\tif len(o) == 0 {\n\t\treturn EINVAL\n\t}\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(&o[0]), uintptr(SizeofTCPRepairOpt*len(o)))\n}\n\nfunc SetsockoptTCPMD5Sig(fd, level, opt int, s *TCPMD5Sig) error {\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(s), unsafe.Sizeof(*s))\n}\n\n// Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html)\n\n// KeyctlInt calls keyctl commands in which each argument is an int.\n// These commands are KEYCTL_REVOKE, KEYCTL_CHOWN, KEYCTL_CLEAR, KEYCTL_LINK,\n// KEYCTL_UNLINK, KEYCTL_NEGATE, KEYCTL_SET_REQKEY_KEYRING, KEYCTL_SET_TIMEOUT,\n// KEYCTL_ASSUME_AUTHORITY, KEYCTL_SESSION_TO_PARENT, KEYCTL_REJECT,\n// KEYCTL_INVALIDATE, and KEYCTL_GET_PERSISTENT.\n//sys\tKeyctlInt(cmd int, arg2 int, arg3 int, arg4 int, arg5 int) (ret int, err error) = SYS_KEYCTL\n\n// KeyctlBuffer calls keyctl commands in which the third and fourth\n// arguments are a buffer and its length, respectively.\n// These commands are KEYCTL_UPDATE, KEYCTL_READ, and KEYCTL_INSTANTIATE.\n//sys\tKeyctlBuffer(cmd int, arg2 int, buf []byte, arg5 int) (ret int, err error) = SYS_KEYCTL\n\n// KeyctlString calls keyctl commands which return a string.\n// These commands are KEYCTL_DESCRIBE and KEYCTL_GET_SECURITY.\nfunc KeyctlString(cmd int, id int) (string, error) {\n\t// We must loop as the string data may change in between the syscalls.\n\t// We could allocate a large buffer here to reduce the chance that the\n\t// syscall needs to be called twice; however, this is unnecessary as\n\t// the performance loss is negligible.\n\tvar buffer []byte\n\tfor {\n\t\t// Try to fill the buffer with data\n\t\tlength, err := KeyctlBuffer(cmd, id, buffer, 0)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\n\t\t// Check if the data was written\n\t\tif length <= len(buffer) {\n\t\t\t// Exclude the null terminator\n\t\t\treturn string(buffer[:length-1]), nil\n\t\t}\n\n\t\t// Make a bigger buffer if needed\n\t\tbuffer = make([]byte, length)\n\t}\n}\n\n// Keyctl commands with special signatures.\n\n// KeyctlGetKeyringID implements the KEYCTL_GET_KEYRING_ID command.\n// See the full documentation at:\n// http://man7.org/linux/man-pages/man3/keyctl_get_keyring_ID.3.html\nfunc KeyctlGetKeyringID(id int, create bool) (ringid int, err error) {\n\tcreateInt := 0\n\tif create {\n\t\tcreateInt = 1\n\t}\n\treturn KeyctlInt(KEYCTL_GET_KEYRING_ID, id, createInt, 0, 0)\n}\n\n// KeyctlSetperm implements the KEYCTL_SETPERM command. The perm value is the\n// key handle permission mask as described in the \"keyctl setperm\" section of\n// http://man7.org/linux/man-pages/man1/keyctl.1.html.\n// See the full documentation at:\n// http://man7.org/linux/man-pages/man3/keyctl_setperm.3.html\nfunc KeyctlSetperm(id int, perm uint32) error {\n\t_, err := KeyctlInt(KEYCTL_SETPERM, id, int(perm), 0, 0)\n\treturn err\n}\n\n//sys\tkeyctlJoin(cmd int, arg2 string) (ret int, err error) = SYS_KEYCTL\n\n// KeyctlJoinSessionKeyring implements the KEYCTL_JOIN_SESSION_KEYRING command.\n// See the full documentation at:\n// http://man7.org/linux/man-pages/man3/keyctl_join_session_keyring.3.html\nfunc KeyctlJoinSessionKeyring(name string) (ringid int, err error) {\n\treturn keyctlJoin(KEYCTL_JOIN_SESSION_KEYRING, name)\n}\n\n//sys\tkeyctlSearch(cmd int, arg2 int, arg3 string, arg4 string, arg5 int) (ret int, err error) = SYS_KEYCTL\n\n// KeyctlSearch implements the KEYCTL_SEARCH command.\n// See the full documentation at:\n// http://man7.org/linux/man-pages/man3/keyctl_search.3.html\nfunc KeyctlSearch(ringid int, keyType, description string, destRingid int) (id int, err error) {\n\treturn keyctlSearch(KEYCTL_SEARCH, ringid, keyType, description, destRingid)\n}\n\n//sys\tkeyctlIOV(cmd int, arg2 int, payload []Iovec, arg5 int) (err error) = SYS_KEYCTL\n\n// KeyctlInstantiateIOV implements the KEYCTL_INSTANTIATE_IOV command. This\n// command is similar to KEYCTL_INSTANTIATE, except that the payload is a slice\n// of Iovec (each of which represents a buffer) instead of a single buffer.\n// See the full documentation at:\n// http://man7.org/linux/man-pages/man3/keyctl_instantiate_iov.3.html\nfunc KeyctlInstantiateIOV(id int, payload []Iovec, ringid int) error {\n\treturn keyctlIOV(KEYCTL_INSTANTIATE_IOV, id, payload, ringid)\n}\n\n//sys\tkeyctlDH(cmd int, arg2 *KeyctlDHParams, buf []byte) (ret int, err error) = SYS_KEYCTL\n\n// KeyctlDHCompute implements the KEYCTL_DH_COMPUTE command. This command\n// computes a Diffie-Hellman shared secret based on the provide params. The\n// secret is written to the provided buffer and the returned size is the number\n// of bytes written (returning an error if there is insufficient space in the\n// buffer). If a nil buffer is passed in, this function returns the minimum\n// buffer length needed to store the appropriate data. Note that this differs\n// from KEYCTL_READ's behavior which always returns the requested payload size.\n// See the full documentation at:\n// http://man7.org/linux/man-pages/man3/keyctl_dh_compute.3.html\nfunc KeyctlDHCompute(params *KeyctlDHParams, buffer []byte) (size int, err error) {\n\treturn keyctlDH(KEYCTL_DH_COMPUTE, params, buffer)\n}\n\n// KeyctlRestrictKeyring implements the KEYCTL_RESTRICT_KEYRING command. This\n// command limits the set of keys that can be linked to the keyring, regardless\n// of keyring permissions. The command requires the \"setattr\" permission.\n//\n// When called with an empty keyType the command locks the keyring, preventing\n// any further keys from being linked to the keyring.\n//\n// The \"asymmetric\" keyType defines restrictions requiring key payloads to be\n// DER encoded X.509 certificates signed by keys in another keyring. Restrictions\n// for \"asymmetric\" include \"builtin_trusted\", \"builtin_and_secondary_trusted\",\n// \"key_or_keyring:<key>\", and \"key_or_keyring:<key>:chain\".\n//\n// As of Linux 4.12, only the \"asymmetric\" keyType defines type-specific\n// restrictions.\n//\n// See the full documentation at:\n// http://man7.org/linux/man-pages/man3/keyctl_restrict_keyring.3.html\n// http://man7.org/linux/man-pages/man2/keyctl.2.html\nfunc KeyctlRestrictKeyring(ringid int, keyType string, restriction string) error {\n\tif keyType == \"\" {\n\t\treturn keyctlRestrictKeyring(KEYCTL_RESTRICT_KEYRING, ringid)\n\t}\n\treturn keyctlRestrictKeyringByType(KEYCTL_RESTRICT_KEYRING, ringid, keyType, restriction)\n}\n\n//sys\tkeyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL\n//sys\tkeyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL\n\nfunc recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {\n\tvar msg Msghdr\n\tmsg.Name = (*byte)(unsafe.Pointer(rsa))\n\tmsg.Namelen = uint32(SizeofSockaddrAny)\n\tvar dummy byte\n\tif len(oob) > 0 {\n\t\tif emptyIovecs(iov) {\n\t\t\tvar sockType int\n\t\t\tsockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// receive at least one normal byte\n\t\t\tif sockType != SOCK_DGRAM {\n\t\t\t\tvar iova [1]Iovec\n\t\t\t\tiova[0].Base = &dummy\n\t\t\t\tiova[0].SetLen(1)\n\t\t\t\tiov = iova[:]\n\t\t\t}\n\t\t}\n\t\tmsg.Control = &oob[0]\n\t\tmsg.SetControllen(len(oob))\n\t}\n\tif len(iov) > 0 {\n\t\tmsg.Iov = &iov[0]\n\t\tmsg.SetIovlen(len(iov))\n\t}\n\tif n, err = recvmsg(fd, &msg, flags); err != nil {\n\t\treturn\n\t}\n\toobn = int(msg.Controllen)\n\trecvflags = int(msg.Flags)\n\treturn\n}\n\nfunc sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {\n\tvar msg Msghdr\n\tmsg.Name = (*byte)(ptr)\n\tmsg.Namelen = uint32(salen)\n\tvar dummy byte\n\tvar empty bool\n\tif len(oob) > 0 {\n\t\tempty = emptyIovecs(iov)\n\t\tif empty {\n\t\t\tvar sockType int\n\t\t\tsockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\t// send at least one normal byte\n\t\t\tif sockType != SOCK_DGRAM {\n\t\t\t\tvar iova [1]Iovec\n\t\t\t\tiova[0].Base = &dummy\n\t\t\t\tiova[0].SetLen(1)\n\t\t\t\tiov = iova[:]\n\t\t\t}\n\t\t}\n\t\tmsg.Control = &oob[0]\n\t\tmsg.SetControllen(len(oob))\n\t}\n\tif len(iov) > 0 {\n\t\tmsg.Iov = &iov[0]\n\t\tmsg.SetIovlen(len(iov))\n\t}\n\tif n, err = sendmsg(fd, &msg, flags); err != nil {\n\t\treturn 0, err\n\t}\n\tif len(oob) > 0 && empty {\n\t\tn = 0\n\t}\n\treturn n, nil\n}\n\n// BindToDevice binds the socket associated with fd to device.\nfunc BindToDevice(fd int, device string) (err error) {\n\treturn SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)\n}\n\n//sys\tptrace(request int, pid int, addr uintptr, data uintptr) (err error)\n//sys\tptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) = SYS_PTRACE\n\nfunc ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {\n\t// The peek requests are machine-size oriented, so we wrap it\n\t// to retrieve arbitrary-length data.\n\n\t// The ptrace syscall differs from glibc's ptrace.\n\t// Peeks returns the word in *data, not as the return value.\n\n\tvar buf [SizeofPtr]byte\n\n\t// Leading edge. PEEKTEXT/PEEKDATA don't require aligned\n\t// access (PEEKUSER warns that it might), but if we don't\n\t// align our reads, we might straddle an unmapped page\n\t// boundary and not get the bytes leading up to the page\n\t// boundary.\n\tn := 0\n\tif addr%SizeofPtr != 0 {\n\t\terr = ptracePtr(req, pid, addr-addr%SizeofPtr, unsafe.Pointer(&buf[0]))\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tn += copy(out, buf[addr%SizeofPtr:])\n\t\tout = out[n:]\n\t}\n\n\t// Remainder.\n\tfor len(out) > 0 {\n\t\t// We use an internal buffer to guarantee alignment.\n\t\t// It's not documented if this is necessary, but we're paranoid.\n\t\terr = ptracePtr(req, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))\n\t\tif err != nil {\n\t\t\treturn n, err\n\t\t}\n\t\tcopied := copy(out, buf[0:])\n\t\tn += copied\n\t\tout = out[copied:]\n\t}\n\n\treturn n, nil\n}\n\nfunc PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {\n\treturn ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)\n}\n\nfunc PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {\n\treturn ptracePeek(PTRACE_PEEKDATA, pid, addr, out)\n}\n\nfunc PtracePeekUser(pid int, addr uintptr, out []byte) (count int, err error) {\n\treturn ptracePeek(PTRACE_PEEKUSR, pid, addr, out)\n}\n\nfunc ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {\n\t// As for ptracePeek, we need to align our accesses to deal\n\t// with the possibility of straddling an invalid page.\n\n\t// Leading edge.\n\tn := 0\n\tif addr%SizeofPtr != 0 {\n\t\tvar buf [SizeofPtr]byte\n\t\terr = ptracePtr(peekReq, pid, addr-addr%SizeofPtr, unsafe.Pointer(&buf[0]))\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tn += copy(buf[addr%SizeofPtr:], data)\n\t\tword := *((*uintptr)(unsafe.Pointer(&buf[0])))\n\t\terr = ptrace(pokeReq, pid, addr-addr%SizeofPtr, word)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tdata = data[n:]\n\t}\n\n\t// Interior.\n\tfor len(data) > SizeofPtr {\n\t\tword := *((*uintptr)(unsafe.Pointer(&data[0])))\n\t\terr = ptrace(pokeReq, pid, addr+uintptr(n), word)\n\t\tif err != nil {\n\t\t\treturn n, err\n\t\t}\n\t\tn += SizeofPtr\n\t\tdata = data[SizeofPtr:]\n\t}\n\n\t// Trailing edge.\n\tif len(data) > 0 {\n\t\tvar buf [SizeofPtr]byte\n\t\terr = ptracePtr(peekReq, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))\n\t\tif err != nil {\n\t\t\treturn n, err\n\t\t}\n\t\tcopy(buf[0:], data)\n\t\tword := *((*uintptr)(unsafe.Pointer(&buf[0])))\n\t\terr = ptrace(pokeReq, pid, addr+uintptr(n), word)\n\t\tif err != nil {\n\t\t\treturn n, err\n\t\t}\n\t\tn += len(data)\n\t}\n\n\treturn n, nil\n}\n\nfunc PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {\n\treturn ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)\n}\n\nfunc PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {\n\treturn ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)\n}\n\nfunc PtracePokeUser(pid int, addr uintptr, data []byte) (count int, err error) {\n\treturn ptracePoke(PTRACE_POKEUSR, PTRACE_PEEKUSR, pid, addr, data)\n}\n\n// elfNT_PRSTATUS is a copy of the debug/elf.NT_PRSTATUS constant so\n// x/sys/unix doesn't need to depend on debug/elf and thus\n// compress/zlib, debug/dwarf, and other packages.\nconst elfNT_PRSTATUS = 1\n\nfunc PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {\n\tvar iov Iovec\n\tiov.Base = (*byte)(unsafe.Pointer(regsout))\n\tiov.SetLen(int(unsafe.Sizeof(*regsout)))\n\treturn ptracePtr(PTRACE_GETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov))\n}\n\nfunc PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {\n\tvar iov Iovec\n\tiov.Base = (*byte)(unsafe.Pointer(regs))\n\tiov.SetLen(int(unsafe.Sizeof(*regs)))\n\treturn ptracePtr(PTRACE_SETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov))\n}\n\nfunc PtraceSetOptions(pid int, options int) (err error) {\n\treturn ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))\n}\n\nfunc PtraceGetEventMsg(pid int) (msg uint, err error) {\n\tvar data _C_long\n\terr = ptracePtr(PTRACE_GETEVENTMSG, pid, 0, unsafe.Pointer(&data))\n\tmsg = uint(data)\n\treturn\n}\n\nfunc PtraceCont(pid int, signal int) (err error) {\n\treturn ptrace(PTRACE_CONT, pid, 0, uintptr(signal))\n}\n\nfunc PtraceSyscall(pid int, signal int) (err error) {\n\treturn ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))\n}\n\nfunc PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }\n\nfunc PtraceInterrupt(pid int) (err error) { return ptrace(PTRACE_INTERRUPT, pid, 0, 0) }\n\nfunc PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }\n\nfunc PtraceSeize(pid int) (err error) { return ptrace(PTRACE_SEIZE, pid, 0, 0) }\n\nfunc PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }\n\n//sys\treboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)\n\nfunc Reboot(cmd int) (err error) {\n\treturn reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, \"\")\n}\n\nfunc direntIno(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))\n}\n\nfunc direntReclen(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))\n}\n\nfunc direntNamlen(buf []byte) (uint64, bool) {\n\treclen, ok := direntReclen(buf)\n\tif !ok {\n\t\treturn 0, false\n\t}\n\treturn reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true\n}\n\n//sys\tmount(source string, target string, fstype string, flags uintptr, data *byte) (err error)\n\nfunc Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {\n\t// Certain file systems get rather angry and EINVAL if you give\n\t// them an empty string of data, rather than NULL.\n\tif data == \"\" {\n\t\treturn mount(source, target, fstype, flags, nil)\n\t}\n\tdatap, err := BytePtrFromString(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn mount(source, target, fstype, flags, datap)\n}\n\n//sys\tmountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr, size uintptr) (err error) = SYS_MOUNT_SETATTR\n\n// MountSetattr is a wrapper for mount_setattr(2).\n// https://man7.org/linux/man-pages/man2/mount_setattr.2.html\n//\n// Requires kernel >= 5.12.\nfunc MountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr) error {\n\treturn mountSetattr(dirfd, pathname, flags, attr, unsafe.Sizeof(*attr))\n}\n\nfunc Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\tif raceenabled {\n\t\traceReleaseMerge(unsafe.Pointer(&ioSync))\n\t}\n\treturn sendfile(outfd, infd, offset, count)\n}\n\n// Sendto\n// Recvfrom\n// Socketpair\n\n/*\n * Direct access\n */\n//sys\tAcct(path string) (err error)\n//sys\tAddKey(keyType string, description string, payload []byte, ringid int) (id int, err error)\n//sys\tAdjtimex(buf *Timex) (state int, err error)\n//sysnb\tCapget(hdr *CapUserHeader, data *CapUserData) (err error)\n//sysnb\tCapset(hdr *CapUserHeader, data *CapUserData) (err error)\n//sys\tChdir(path string) (err error)\n//sys\tChroot(path string) (err error)\n//sys\tClockAdjtime(clockid int32, buf *Timex) (state int, err error)\n//sys\tClockGetres(clockid int32, res *Timespec) (err error)\n//sys\tClockGettime(clockid int32, time *Timespec) (err error)\n//sys\tClockSettime(clockid int32, time *Timespec) (err error)\n//sys\tClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error)\n//sys\tClose(fd int) (err error)\n//sys\tCloseRange(first uint, last uint, flags uint) (err error)\n//sys\tCopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)\n//sys\tDeleteModule(name string, flags int) (err error)\n//sys\tDup(oldfd int) (fd int, err error)\n\nfunc Dup2(oldfd, newfd int) error {\n\treturn Dup3(oldfd, newfd, 0)\n}\n\n//sys\tDup3(oldfd int, newfd int, flags int) (err error)\n//sysnb\tEpollCreate1(flag int) (fd int, err error)\n//sysnb\tEpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)\n//sys\tEventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2\n//sys\tExit(code int) = SYS_EXIT_GROUP\n//sys\tFallocate(fd int, mode uint32, off int64, len int64) (err error)\n//sys\tFchdir(fd int) (err error)\n//sys\tFchmod(fd int, mode uint32) (err error)\n//sys\tFchownat(dirfd int, path string, uid int, gid int, flags int) (err error)\n//sys\tFdatasync(fd int) (err error)\n//sys\tFgetxattr(fd int, attr string, dest []byte) (sz int, err error)\n//sys\tFinitModule(fd int, params string, flags int) (err error)\n//sys\tFlistxattr(fd int, dest []byte) (sz int, err error)\n//sys\tFlock(fd int, how int) (err error)\n//sys\tFremovexattr(fd int, attr string) (err error)\n//sys\tFsetxattr(fd int, attr string, dest []byte, flags int) (err error)\n//sys\tFsync(fd int) (err error)\n//sys\tFsmount(fd int, flags int, mountAttrs int) (fsfd int, err error)\n//sys\tFsopen(fsName string, flags int) (fd int, err error)\n//sys\tFspick(dirfd int, pathName string, flags int) (fd int, err error)\n\n//sys\tfsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error)\n\nfunc fsconfigCommon(fd int, cmd uint, key string, value *byte, aux int) (err error) {\n\tvar keyp *byte\n\tif keyp, err = BytePtrFromString(key); err != nil {\n\t\treturn\n\t}\n\treturn fsconfig(fd, cmd, keyp, value, aux)\n}\n\n// FsconfigSetFlag is equivalent to fsconfig(2) called\n// with cmd == FSCONFIG_SET_FLAG.\n//\n// fd is the filesystem context to act upon.\n// key the parameter key to set.\nfunc FsconfigSetFlag(fd int, key string) (err error) {\n\treturn fsconfigCommon(fd, FSCONFIG_SET_FLAG, key, nil, 0)\n}\n\n// FsconfigSetString is equivalent to fsconfig(2) called\n// with cmd == FSCONFIG_SET_STRING.\n//\n// fd is the filesystem context to act upon.\n// key the parameter key to set.\n// value is the parameter value to set.\nfunc FsconfigSetString(fd int, key string, value string) (err error) {\n\tvar valuep *byte\n\tif valuep, err = BytePtrFromString(value); err != nil {\n\t\treturn\n\t}\n\treturn fsconfigCommon(fd, FSCONFIG_SET_STRING, key, valuep, 0)\n}\n\n// FsconfigSetBinary is equivalent to fsconfig(2) called\n// with cmd == FSCONFIG_SET_BINARY.\n//\n// fd is the filesystem context to act upon.\n// key the parameter key to set.\n// value is the parameter value to set.\nfunc FsconfigSetBinary(fd int, key string, value []byte) (err error) {\n\tif len(value) == 0 {\n\t\treturn EINVAL\n\t}\n\treturn fsconfigCommon(fd, FSCONFIG_SET_BINARY, key, &value[0], len(value))\n}\n\n// FsconfigSetPath is equivalent to fsconfig(2) called\n// with cmd == FSCONFIG_SET_PATH.\n//\n// fd is the filesystem context to act upon.\n// key the parameter key to set.\n// path is a non-empty path for specified key.\n// atfd is a file descriptor at which to start lookup from or AT_FDCWD.\nfunc FsconfigSetPath(fd int, key string, path string, atfd int) (err error) {\n\tvar valuep *byte\n\tif valuep, err = BytePtrFromString(path); err != nil {\n\t\treturn\n\t}\n\treturn fsconfigCommon(fd, FSCONFIG_SET_PATH, key, valuep, atfd)\n}\n\n// FsconfigSetPathEmpty is equivalent to fsconfig(2) called\n// with cmd == FSCONFIG_SET_PATH_EMPTY. The same as\n// FconfigSetPath but with AT_PATH_EMPTY implied.\nfunc FsconfigSetPathEmpty(fd int, key string, path string, atfd int) (err error) {\n\tvar valuep *byte\n\tif valuep, err = BytePtrFromString(path); err != nil {\n\t\treturn\n\t}\n\treturn fsconfigCommon(fd, FSCONFIG_SET_PATH_EMPTY, key, valuep, atfd)\n}\n\n// FsconfigSetFd is equivalent to fsconfig(2) called\n// with cmd == FSCONFIG_SET_FD.\n//\n// fd is the filesystem context to act upon.\n// key the parameter key to set.\n// value is a file descriptor to be assigned to specified key.\nfunc FsconfigSetFd(fd int, key string, value int) (err error) {\n\treturn fsconfigCommon(fd, FSCONFIG_SET_FD, key, nil, value)\n}\n\n// FsconfigCreate is equivalent to fsconfig(2) called\n// with cmd == FSCONFIG_CMD_CREATE.\n//\n// fd is the filesystem context to act upon.\nfunc FsconfigCreate(fd int) (err error) {\n\treturn fsconfig(fd, FSCONFIG_CMD_CREATE, nil, nil, 0)\n}\n\n// FsconfigReconfigure is equivalent to fsconfig(2) called\n// with cmd == FSCONFIG_CMD_RECONFIGURE.\n//\n// fd is the filesystem context to act upon.\nfunc FsconfigReconfigure(fd int) (err error) {\n\treturn fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, nil, nil, 0)\n}\n\n//sys\tGetdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64\n//sysnb\tGetpgid(pid int) (pgid int, err error)\n\nfunc Getpgrp() (pid int) {\n\tpid, _ = Getpgid(0)\n\treturn\n}\n\n//sysnb\tGetpid() (pid int)\n//sysnb\tGetppid() (ppid int)\n//sys\tGetpriority(which int, who int) (prio int, err error)\n\nfunc Getrandom(buf []byte, flags int) (n int, err error) {\n\tvdsoRet, supported := vgetrandom(buf, uint32(flags))\n\tif supported {\n\t\tif vdsoRet < 0 {\n\t\t\treturn 0, errnoErr(syscall.Errno(-vdsoRet))\n\t\t}\n\t\treturn vdsoRet, nil\n\t}\n\tvar p *byte\n\tif len(buf) > 0 {\n\t\tp = &buf[0]\n\t}\n\tr, _, e := Syscall(SYS_GETRANDOM, uintptr(unsafe.Pointer(p)), uintptr(len(buf)), uintptr(flags))\n\tif e != 0 {\n\t\treturn 0, errnoErr(e)\n\t}\n\treturn int(r), nil\n}\n\n//sysnb\tGetrusage(who int, rusage *Rusage) (err error)\n//sysnb\tGetsid(pid int) (sid int, err error)\n//sysnb\tGettid() (tid int)\n//sys\tGetxattr(path string, attr string, dest []byte) (sz int, err error)\n//sys\tInitModule(moduleImage []byte, params string) (err error)\n//sys\tInotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)\n//sysnb\tInotifyInit1(flags int) (fd int, err error)\n//sysnb\tInotifyRmWatch(fd int, watchdesc uint32) (success int, err error)\n//sysnb\tKill(pid int, sig syscall.Signal) (err error)\n//sys\tKlogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG\n//sys\tLgetxattr(path string, attr string, dest []byte) (sz int, err error)\n//sys\tListxattr(path string, dest []byte) (sz int, err error)\n//sys\tLlistxattr(path string, dest []byte) (sz int, err error)\n//sys\tLremovexattr(path string, attr string) (err error)\n//sys\tLsetxattr(path string, attr string, data []byte, flags int) (err error)\n//sys\tMemfdCreate(name string, flags int) (fd int, err error)\n//sys\tMkdirat(dirfd int, path string, mode uint32) (err error)\n//sys\tMknodat(dirfd int, path string, mode uint32, dev int) (err error)\n//sys\tMoveMount(fromDirfd int, fromPathName string, toDirfd int, toPathName string, flags int) (err error)\n//sys\tNanosleep(time *Timespec, leftover *Timespec) (err error)\n//sys\tOpenTree(dfd int, fileName string, flags uint) (r int, err error)\n//sys\tPerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error)\n//sys\tPivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT\n//sys\tPrctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error)\n//sys\tpselect6(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_argpack) (n int, err error)\n//sys\tread(fd int, p []byte) (n int, err error)\n//sys\tRemovexattr(path string, attr string) (err error)\n//sys\tRenameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error)\n//sys\tRequestKey(keyType string, description string, callback string, destRingid int) (id int, err error)\n//sys\tSetdomainname(p []byte) (err error)\n//sys\tSethostname(p []byte) (err error)\n//sysnb\tSetpgid(pid int, pgid int) (err error)\n//sysnb\tSetsid() (pid int, err error)\n//sysnb\tSettimeofday(tv *Timeval) (err error)\n//sys\tSetns(fd int, nstype int) (err error)\n\n//go:linkname syscall_prlimit syscall.prlimit\nfunc syscall_prlimit(pid, resource int, newlimit, old *syscall.Rlimit) error\n\nfunc Prlimit(pid, resource int, newlimit, old *Rlimit) error {\n\t// Just call the syscall version, because as of Go 1.21\n\t// it will affect starting a new process.\n\treturn syscall_prlimit(pid, resource, (*syscall.Rlimit)(newlimit), (*syscall.Rlimit)(old))\n}\n\n// PrctlRetInt performs a prctl operation specified by option and further\n// optional arguments arg2 through arg5 depending on option. It returns a\n// non-negative integer that is returned by the prctl syscall.\nfunc PrctlRetInt(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (int, error) {\n\tret, _, err := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0)\n\tif err != 0 {\n\t\treturn 0, err\n\t}\n\treturn int(ret), nil\n}\n\nfunc Setuid(uid int) (err error) {\n\treturn syscall.Setuid(uid)\n}\n\nfunc Setgid(gid int) (err error) {\n\treturn syscall.Setgid(gid)\n}\n\nfunc Setreuid(ruid, euid int) (err error) {\n\treturn syscall.Setreuid(ruid, euid)\n}\n\nfunc Setregid(rgid, egid int) (err error) {\n\treturn syscall.Setregid(rgid, egid)\n}\n\nfunc Setresuid(ruid, euid, suid int) (err error) {\n\treturn syscall.Setresuid(ruid, euid, suid)\n}\n\nfunc Setresgid(rgid, egid, sgid int) (err error) {\n\treturn syscall.Setresgid(rgid, egid, sgid)\n}\n\n// SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set.\n// setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability.\n// If the call fails due to other reasons, current fsgid will be returned.\nfunc SetfsgidRetGid(gid int) (int, error) {\n\treturn setfsgid(gid)\n}\n\n// SetfsuidRetUid sets fsuid for current thread and returns previous fsuid set.\n// setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability\n// If the call fails due to other reasons, current fsuid will be returned.\nfunc SetfsuidRetUid(uid int) (int, error) {\n\treturn setfsuid(uid)\n}\n\nfunc Setfsgid(gid int) error {\n\t_, err := setfsgid(gid)\n\treturn err\n}\n\nfunc Setfsuid(uid int) error {\n\t_, err := setfsuid(uid)\n\treturn err\n}\n\nfunc Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {\n\treturn signalfd(fd, sigmask, _C__NSIG/8, flags)\n}\n\n//sys\tSetpriority(which int, who int, prio int) (err error)\n//sys\tSetxattr(path string, attr string, data []byte, flags int) (err error)\n//sys\tsignalfd(fd int, sigmask *Sigset_t, maskSize uintptr, flags int) (newfd int, err error) = SYS_SIGNALFD4\n//sys\tStatx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error)\n//sys\tSync()\n//sys\tSyncfs(fd int) (err error)\n//sysnb\tSysinfo(info *Sysinfo_t) (err error)\n//sys\tTee(rfd int, wfd int, len int, flags int) (n int64, err error)\n//sysnb\tTimerfdCreate(clockid int, flags int) (fd int, err error)\n//sysnb\tTimerfdGettime(fd int, currValue *ItimerSpec) (err error)\n//sysnb\tTimerfdSettime(fd int, flags int, newValue *ItimerSpec, oldValue *ItimerSpec) (err error)\n//sysnb\tTgkill(tgid int, tid int, sig syscall.Signal) (err error)\n//sysnb\tTimes(tms *Tms) (ticks uintptr, err error)\n//sysnb\tUmask(mask int) (oldmask int)\n//sysnb\tUname(buf *Utsname) (err error)\n//sys\tUnmount(target string, flags int) (err error) = SYS_UMOUNT2\n//sys\tUnshare(flags int) (err error)\n//sys\twrite(fd int, p []byte) (n int, err error)\n//sys\texitThread(code int) (err error) = SYS_EXIT\n//sys\treadv(fd int, iovs []Iovec) (n int, err error) = SYS_READV\n//sys\twritev(fd int, iovs []Iovec) (n int, err error) = SYS_WRITEV\n//sys\tpreadv(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PREADV\n//sys\tpwritev(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PWRITEV\n//sys\tpreadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2\n//sys\tpwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2\n\n// minIovec is the size of the small initial allocation used by\n// Readv, Writev, etc.\n//\n// This small allocation gets stack allocated, which lets the\n// common use case of len(iovs) <= minIovs avoid more expensive\n// heap allocations.\nconst minIovec = 8\n\n// appendBytes converts bs to Iovecs and appends them to vecs.\nfunc appendBytes(vecs []Iovec, bs [][]byte) []Iovec {\n\tfor _, b := range bs {\n\t\tvar v Iovec\n\t\tv.SetLen(len(b))\n\t\tif len(b) > 0 {\n\t\t\tv.Base = &b[0]\n\t\t} else {\n\t\t\tv.Base = (*byte)(unsafe.Pointer(&_zero))\n\t\t}\n\t\tvecs = append(vecs, v)\n\t}\n\treturn vecs\n}\n\n// offs2lohi splits offs into its low and high order bits.\nfunc offs2lohi(offs int64) (lo, hi uintptr) {\n\tconst longBits = SizeofLong * 8\n\treturn uintptr(offs), uintptr(uint64(offs) >> (longBits - 1) >> 1) // two shifts to avoid false positive in vet\n}\n\nfunc Readv(fd int, iovs [][]byte) (n int, err error) {\n\tiovecs := make([]Iovec, 0, minIovec)\n\tiovecs = appendBytes(iovecs, iovs)\n\tn, err = readv(fd, iovecs)\n\treadvRacedetect(iovecs, n, err)\n\treturn n, err\n}\n\nfunc Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) {\n\tiovecs := make([]Iovec, 0, minIovec)\n\tiovecs = appendBytes(iovecs, iovs)\n\tlo, hi := offs2lohi(offset)\n\tn, err = preadv(fd, iovecs, lo, hi)\n\treadvRacedetect(iovecs, n, err)\n\treturn n, err\n}\n\nfunc Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {\n\tiovecs := make([]Iovec, 0, minIovec)\n\tiovecs = appendBytes(iovecs, iovs)\n\tlo, hi := offs2lohi(offset)\n\tn, err = preadv2(fd, iovecs, lo, hi, flags)\n\treadvRacedetect(iovecs, n, err)\n\treturn n, err\n}\n\nfunc readvRacedetect(iovecs []Iovec, n int, err error) {\n\tif !raceenabled {\n\t\treturn\n\t}\n\tfor i := 0; n > 0 && i < len(iovecs); i++ {\n\t\tm := min(int(iovecs[i].Len), n)\n\t\tn -= m\n\t\tif m > 0 {\n\t\t\traceWriteRange(unsafe.Pointer(iovecs[i].Base), m)\n\t\t}\n\t}\n\tif err == nil {\n\t\traceAcquire(unsafe.Pointer(&ioSync))\n\t}\n}\n\nfunc Writev(fd int, iovs [][]byte) (n int, err error) {\n\tiovecs := make([]Iovec, 0, minIovec)\n\tiovecs = appendBytes(iovecs, iovs)\n\tif raceenabled {\n\t\traceReleaseMerge(unsafe.Pointer(&ioSync))\n\t}\n\tn, err = writev(fd, iovecs)\n\twritevRacedetect(iovecs, n)\n\treturn n, err\n}\n\nfunc Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) {\n\tiovecs := make([]Iovec, 0, minIovec)\n\tiovecs = appendBytes(iovecs, iovs)\n\tif raceenabled {\n\t\traceReleaseMerge(unsafe.Pointer(&ioSync))\n\t}\n\tlo, hi := offs2lohi(offset)\n\tn, err = pwritev(fd, iovecs, lo, hi)\n\twritevRacedetect(iovecs, n)\n\treturn n, err\n}\n\nfunc Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) {\n\tiovecs := make([]Iovec, 0, minIovec)\n\tiovecs = appendBytes(iovecs, iovs)\n\tif raceenabled {\n\t\traceReleaseMerge(unsafe.Pointer(&ioSync))\n\t}\n\tlo, hi := offs2lohi(offset)\n\tn, err = pwritev2(fd, iovecs, lo, hi, flags)\n\twritevRacedetect(iovecs, n)\n\treturn n, err\n}\n\nfunc writevRacedetect(iovecs []Iovec, n int) {\n\tif !raceenabled {\n\t\treturn\n\t}\n\tfor i := 0; n > 0 && i < len(iovecs); i++ {\n\t\tm := min(int(iovecs[i].Len), n)\n\t\tn -= m\n\t\tif m > 0 {\n\t\t\traceReadRange(unsafe.Pointer(iovecs[i].Base), m)\n\t\t}\n\t}\n}\n\n// mmap varies by architecture; see syscall_linux_*.go.\n//sys\tmunmap(addr uintptr, length uintptr) (err error)\n//sys\tmremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)\n//sys\tMadvise(b []byte, advice int) (err error)\n//sys\tMprotect(b []byte, prot int) (err error)\n//sys\tMlock(b []byte) (err error)\n//sys\tMlockall(flags int) (err error)\n//sys\tMsync(b []byte, flags int) (err error)\n//sys\tMunlock(b []byte) (err error)\n//sys\tMunlockall() (err error)\n\nconst (\n\tmremapFixed     = MREMAP_FIXED\n\tmremapDontunmap = MREMAP_DONTUNMAP\n\tmremapMaymove   = MREMAP_MAYMOVE\n)\n\n// Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd,\n// using the specified flags.\nfunc Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {\n\tvar p unsafe.Pointer\n\tif len(iovs) > 0 {\n\t\tp = unsafe.Pointer(&iovs[0])\n\t}\n\n\tn, _, errno := Syscall6(SYS_VMSPLICE, uintptr(fd), uintptr(p), uintptr(len(iovs)), uintptr(flags), 0, 0)\n\tif errno != 0 {\n\t\treturn 0, syscall.Errno(errno)\n\t}\n\n\treturn int(n), nil\n}\n\nfunc isGroupMember(gid int) bool {\n\tgroups, err := Getgroups()\n\tif err != nil {\n\t\treturn false\n\t}\n\n\treturn slices.Contains(groups, gid)\n}\n\nfunc isCapDacOverrideSet() bool {\n\thdr := CapUserHeader{Version: LINUX_CAPABILITY_VERSION_3}\n\tdata := [2]CapUserData{}\n\terr := Capget(&hdr, &data[0])\n\n\treturn err == nil && data[0].Effective&(1<<CAP_DAC_OVERRIDE) != 0\n}\n\n//sys\tfaccessat(dirfd int, path string, mode uint32) (err error)\n//sys\tFaccessat2(dirfd int, path string, mode uint32, flags int) (err error)\n\nfunc Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {\n\tif flags == 0 {\n\t\treturn faccessat(dirfd, path, mode)\n\t}\n\n\tif err := Faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM {\n\t\treturn err\n\t}\n\n\t// The Linux kernel faccessat system call does not take any flags.\n\t// The glibc faccessat implements the flags itself; see\n\t// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD\n\t// Because people naturally expect syscall.Faccessat to act\n\t// like C faccessat, we do the same.\n\n\tif flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 {\n\t\treturn EINVAL\n\t}\n\n\tvar st Stat_t\n\tif err := Fstatat(dirfd, path, &st, flags&AT_SYMLINK_NOFOLLOW); err != nil {\n\t\treturn err\n\t}\n\n\tmode &= 7\n\tif mode == 0 {\n\t\treturn nil\n\t}\n\n\tvar uid int\n\tif flags&AT_EACCESS != 0 {\n\t\tuid = Geteuid()\n\t\tif uid != 0 && isCapDacOverrideSet() {\n\t\t\t// If CAP_DAC_OVERRIDE is set, file access check is\n\t\t\t// done by the kernel in the same way as for root\n\t\t\t// (see generic_permission() in the Linux sources).\n\t\t\tuid = 0\n\t\t}\n\t} else {\n\t\tuid = Getuid()\n\t}\n\n\tif uid == 0 {\n\t\tif mode&1 == 0 {\n\t\t\t// Root can read and write any file.\n\t\t\treturn nil\n\t\t}\n\t\tif st.Mode&0111 != 0 {\n\t\t\t// Root can execute any file that anybody can execute.\n\t\t\treturn nil\n\t\t}\n\t\treturn EACCES\n\t}\n\n\tvar fmode uint32\n\tif uint32(uid) == st.Uid {\n\t\tfmode = (st.Mode >> 6) & 7\n\t} else {\n\t\tvar gid int\n\t\tif flags&AT_EACCESS != 0 {\n\t\t\tgid = Getegid()\n\t\t} else {\n\t\t\tgid = Getgid()\n\t\t}\n\n\t\tif uint32(gid) == st.Gid || isGroupMember(int(st.Gid)) {\n\t\t\tfmode = (st.Mode >> 3) & 7\n\t\t} else {\n\t\t\tfmode = st.Mode & 7\n\t\t}\n\t}\n\n\tif fmode&mode == mode {\n\t\treturn nil\n\t}\n\n\treturn EACCES\n}\n\n//sys\tnameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) = SYS_NAME_TO_HANDLE_AT\n//sys\topenByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) = SYS_OPEN_BY_HANDLE_AT\n\n// fileHandle is the argument to nameToHandleAt and openByHandleAt. We\n// originally tried to generate it via unix/linux/types.go with \"type\n// fileHandle C.struct_file_handle\" but that generated empty structs\n// for mips64 and mips64le. Instead, hard code it for now (it's the\n// same everywhere else) until the mips64 generator issue is fixed.\ntype fileHandle struct {\n\tBytes uint32\n\tType  int32\n}\n\n// FileHandle represents the C struct file_handle used by\n// name_to_handle_at (see NameToHandleAt) and open_by_handle_at (see\n// OpenByHandleAt).\ntype FileHandle struct {\n\t*fileHandle\n}\n\n// NewFileHandle constructs a FileHandle.\nfunc NewFileHandle(handleType int32, handle []byte) FileHandle {\n\tconst hdrSize = unsafe.Sizeof(fileHandle{})\n\tbuf := make([]byte, hdrSize+uintptr(len(handle)))\n\tcopy(buf[hdrSize:], handle)\n\tfh := (*fileHandle)(unsafe.Pointer(&buf[0]))\n\tfh.Type = handleType\n\tfh.Bytes = uint32(len(handle))\n\treturn FileHandle{fh}\n}\n\nfunc (fh *FileHandle) Size() int   { return int(fh.fileHandle.Bytes) }\nfunc (fh *FileHandle) Type() int32 { return fh.fileHandle.Type }\nfunc (fh *FileHandle) Bytes() []byte {\n\tn := fh.Size()\n\tif n == 0 {\n\t\treturn nil\n\t}\n\treturn unsafe.Slice((*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type))+4)), n)\n}\n\n// NameToHandleAt wraps the name_to_handle_at system call; it obtains\n// a handle for a path name.\nfunc NameToHandleAt(dirfd int, path string, flags int) (handle FileHandle, mountID int, err error) {\n\tvar mid _C_int\n\t// Try first with a small buffer, assuming the handle will\n\t// only be 32 bytes.\n\tsize := uint32(32 + unsafe.Sizeof(fileHandle{}))\n\tdidResize := false\n\tfor {\n\t\tbuf := make([]byte, size)\n\t\tfh := (*fileHandle)(unsafe.Pointer(&buf[0]))\n\t\tfh.Bytes = size - uint32(unsafe.Sizeof(fileHandle{}))\n\t\terr = nameToHandleAt(dirfd, path, fh, &mid, flags)\n\t\tif err == EOVERFLOW {\n\t\t\tif didResize {\n\t\t\t\t// We shouldn't need to resize more than once\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdidResize = true\n\t\t\tsize = fh.Bytes + uint32(unsafe.Sizeof(fileHandle{}))\n\t\t\tcontinue\n\t\t}\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\treturn FileHandle{fh}, int(mid), nil\n\t}\n}\n\n// OpenByHandleAt wraps the open_by_handle_at system call; it opens a\n// file via a handle as previously returned by NameToHandleAt.\nfunc OpenByHandleAt(mountFD int, handle FileHandle, flags int) (fd int, err error) {\n\treturn openByHandleAt(mountFD, handle.fileHandle, flags)\n}\n\n// Klogset wraps the sys_syslog system call; it sets console_loglevel to\n// the value specified by arg and passes a dummy pointer to bufp.\nfunc Klogset(typ int, arg int) (err error) {\n\tvar p unsafe.Pointer\n\t_, _, errno := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(p), uintptr(arg))\n\tif errno != 0 {\n\t\treturn errnoErr(errno)\n\t}\n\treturn nil\n}\n\n// RemoteIovec is Iovec with the pointer replaced with an integer.\n// It is used for ProcessVMReadv and ProcessVMWritev, where the pointer\n// refers to a location in a different process' address space, which\n// would confuse the Go garbage collector.\ntype RemoteIovec struct {\n\tBase uintptr\n\tLen  int\n}\n\n//sys\tProcessVMReadv(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_READV\n//sys\tProcessVMWritev(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_WRITEV\n\n//sys\tPidfdOpen(pid int, flags int) (fd int, err error) = SYS_PIDFD_OPEN\n//sys\tPidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) = SYS_PIDFD_GETFD\n//sys\tPidfdSendSignal(pidfd int, sig Signal, info *Siginfo, flags int) (err error) = SYS_PIDFD_SEND_SIGNAL\n\n//sys\tshmat(id int, addr uintptr, flag int) (ret uintptr, err error)\n//sys\tshmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error)\n//sys\tshmdt(addr uintptr) (err error)\n//sys\tshmget(key int, size int, flag int) (id int, err error)\n\n//sys\tgetitimer(which int, currValue *Itimerval) (err error)\n//sys\tsetitimer(which int, newValue *Itimerval, oldValue *Itimerval) (err error)\n\n// MakeItimerval creates an Itimerval from interval and value durations.\nfunc MakeItimerval(interval, value time.Duration) Itimerval {\n\treturn Itimerval{\n\t\tInterval: NsecToTimeval(interval.Nanoseconds()),\n\t\tValue:    NsecToTimeval(value.Nanoseconds()),\n\t}\n}\n\n// A value which may be passed to the which parameter for Getitimer and\n// Setitimer.\ntype ItimerWhich int\n\n// Possible which values for Getitimer and Setitimer.\nconst (\n\tItimerReal    ItimerWhich = ITIMER_REAL\n\tItimerVirtual ItimerWhich = ITIMER_VIRTUAL\n\tItimerProf    ItimerWhich = ITIMER_PROF\n)\n\n// Getitimer wraps getitimer(2) to return the current value of the timer\n// specified by which.\nfunc Getitimer(which ItimerWhich) (Itimerval, error) {\n\tvar it Itimerval\n\tif err := getitimer(int(which), &it); err != nil {\n\t\treturn Itimerval{}, err\n\t}\n\n\treturn it, nil\n}\n\n// Setitimer wraps setitimer(2) to arm or disarm the timer specified by which.\n// It returns the previous value of the timer.\n//\n// If the Itimerval argument is the zero value, the timer will be disarmed.\nfunc Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) {\n\tvar prev Itimerval\n\tif err := setitimer(int(which), &it, &prev); err != nil {\n\t\treturn Itimerval{}, err\n\t}\n\n\treturn prev, nil\n}\n\n//sysnb\trtSigprocmask(how int, set *Sigset_t, oldset *Sigset_t, sigsetsize uintptr) (err error) = SYS_RT_SIGPROCMASK\n\nfunc PthreadSigmask(how int, set, oldset *Sigset_t) error {\n\tif oldset != nil {\n\t\t// Explicitly clear in case Sigset_t is larger than _C__NSIG.\n\t\t*oldset = Sigset_t{}\n\t}\n\treturn rtSigprocmask(how, set, oldset, _C__NSIG/8)\n}\n\n//sysnb\tgetresuid(ruid *_C_int, euid *_C_int, suid *_C_int)\n//sysnb\tgetresgid(rgid *_C_int, egid *_C_int, sgid *_C_int)\n\nfunc Getresuid() (ruid, euid, suid int) {\n\tvar r, e, s _C_int\n\tgetresuid(&r, &e, &s)\n\treturn int(r), int(e), int(s)\n}\n\nfunc Getresgid() (rgid, egid, sgid int) {\n\tvar r, e, s _C_int\n\tgetresgid(&r, &e, &s)\n\treturn int(r), int(e), int(s)\n}\n\n// Pselect is a wrapper around the Linux pselect6 system call.\n// This version does not modify the timeout argument.\nfunc Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {\n\t// Per https://man7.org/linux/man-pages/man2/select.2.html#NOTES,\n\t// The Linux pselect6() system call modifies its timeout argument.\n\t// [Not modifying the argument] is the behavior required by POSIX.1-2001.\n\tvar mutableTimeout *Timespec\n\tif timeout != nil {\n\t\tmutableTimeout = new(Timespec)\n\t\t*mutableTimeout = *timeout\n\t}\n\n\t// The final argument of the pselect6() system call is not a\n\t// sigset_t * pointer, but is instead a structure\n\tvar kernelMask *sigset_argpack\n\tif sigmask != nil {\n\t\twordBits := 32 << (^uintptr(0) >> 63) // see math.intSize\n\n\t\t// A sigset stores one bit per signal,\n\t\t// offset by 1 (because signal 0 does not exist).\n\t\t// So the number of words needed is ⌈__C_NSIG - 1 / wordBits⌉.\n\t\tsigsetWords := (_C__NSIG - 1 + wordBits - 1) / (wordBits)\n\n\t\tsigsetBytes := uintptr(sigsetWords * (wordBits / 8))\n\t\tkernelMask = &sigset_argpack{\n\t\t\tss:    sigmask,\n\t\t\tssLen: sigsetBytes,\n\t\t}\n\t}\n\n\treturn pselect6(nfd, r, w, e, mutableTimeout, kernelMask)\n}\n\n//sys\tschedSetattr(pid int, attr *SchedAttr, flags uint) (err error)\n//sys\tschedGetattr(pid int, attr *SchedAttr, size uint, flags uint) (err error)\n\n// SchedSetAttr is a wrapper for sched_setattr(2) syscall.\n// https://man7.org/linux/man-pages/man2/sched_setattr.2.html\nfunc SchedSetAttr(pid int, attr *SchedAttr, flags uint) error {\n\tif attr == nil {\n\t\treturn EINVAL\n\t}\n\tattr.Size = SizeofSchedAttr\n\treturn schedSetattr(pid, attr, flags)\n}\n\n// SchedGetAttr is a wrapper for sched_getattr(2) syscall.\n// https://man7.org/linux/man-pages/man2/sched_getattr.2.html\nfunc SchedGetAttr(pid int, flags uint) (*SchedAttr, error) {\n\tattr := &SchedAttr{}\n\tif err := schedGetattr(pid, attr, SizeofSchedAttr, flags); err != nil {\n\t\treturn nil, err\n\t}\n\treturn attr, nil\n}\n\n//sys\tCachestat(fd uint, crange *CachestatRange, cstat *Cachestat_t, flags uint) (err error)\n//sys\tMseal(b []byte, flags uint) (err error)\n\n//sys\tsetMemPolicy(mode int, mask *CPUSet, size int) (err error) = SYS_SET_MEMPOLICY\n\nfunc SetMemPolicy(mode int, mask *CPUSet) error {\n\treturn setMemPolicy(mode, mask, _CPU_SETSIZE)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_386.go",
    "content": "// Copyright 2009 The Go 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\n//go:build 386 && linux\n\npackage unix\n\nimport (\n\t\"unsafe\"\n)\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: int32(sec), Nsec: int32(nsec)}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: int32(sec), Usec: int32(usec)}\n}\n\n// 64-bit file system and 32-bit uid calls\n// (386 default is 32-bit file system and 16-bit uid).\n//sys\tEpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)\n//sys\tFadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64_64\n//sys\tFchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32\n//sys\tFstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64\n//sys\tFstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64\n//sys\tFtruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64\n//sysnb\tGetegid() (egid int) = SYS_GETEGID32\n//sysnb\tGeteuid() (euid int) = SYS_GETEUID32\n//sysnb\tGetgid() (gid int) = SYS_GETGID32\n//sysnb\tGetuid() (uid int) = SYS_GETUID32\n//sys\tIoperm(from int, num int, on int) (err error)\n//sys\tIopl(level int) (err error)\n//sys\tLchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32\n//sys\tLstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64\n//sys\tpread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64\n//sys\tpwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64\n//sys\tRenameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)\n//sys\tsendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64\n//sys\tsetfsgid(gid int) (prev int, err error) = SYS_SETFSGID32\n//sys\tsetfsuid(uid int) (prev int, err error) = SYS_SETFSUID32\n//sys\tSplice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)\n//sys\tStat(path string, stat *Stat_t) (err error) = SYS_STAT64\n//sys\tSyncFileRange(fd int, off int64, n int64, flags int) (err error)\n//sys\tTruncate(path string, length int64) (err error) = SYS_TRUNCATE64\n//sys\tUstat(dev int, ubuf *Ustat_t) (err error)\n//sysnb\tgetgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32\n//sysnb\tsetgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32\n//sys\tSelect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT\n\n//sys\tmmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)\n//sys\tPause() (err error)\n\nfunc mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {\n\tpage := uintptr(offset / 4096)\n\tif offset != int64(page)*4096 {\n\t\treturn 0, EINVAL\n\t}\n\treturn mmap2(addr, length, prot, flags, fd, page)\n}\n\ntype rlimit32 struct {\n\tCur uint32\n\tMax uint32\n}\n\n//sysnb\tgetrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT\n\nconst rlimInf32 = ^uint32(0)\nconst rlimInf64 = ^uint64(0)\n\nfunc Getrlimit(resource int, rlim *Rlimit) (err error) {\n\terr = Prlimit(0, resource, nil, rlim)\n\tif err != ENOSYS {\n\t\treturn err\n\t}\n\n\trl := rlimit32{}\n\terr = getrlimit(resource, &rl)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tif rl.Cur == rlimInf32 {\n\t\trlim.Cur = rlimInf64\n\t} else {\n\t\trlim.Cur = uint64(rl.Cur)\n\t}\n\n\tif rl.Max == rlimInf32 {\n\t\trlim.Max = rlimInf64\n\t} else {\n\t\trlim.Max = uint64(rl.Max)\n\t}\n\treturn\n}\n\nfunc Seek(fd int, offset int64, whence int) (newoffset int64, err error) {\n\tnewoffset, errno := seek(fd, offset, whence)\n\tif errno != 0 {\n\t\treturn 0, errno\n\t}\n\treturn newoffset, nil\n}\n\n//sys\tfutimesat(dirfd int, path string, times *[2]Timeval) (err error)\n//sysnb\tGettimeofday(tv *Timeval) (err error)\n//sysnb\tTime(t *Time_t) (tt Time_t, err error)\n//sys\tUtime(path string, buf *Utimbuf) (err error)\n//sys\tutimes(path string, times *[2]Timeval) (err error)\n\n// On x86 Linux, all the socket calls go through an extra indirection,\n// I think because the 5-register system call interface can't handle\n// the 6-argument calls like sendto and recvfrom. Instead the\n// arguments to the underlying system call are the number below\n// and a pointer to an array of uintptr. We hide the pointer in the\n// socketcall assembly to avoid allocation on every system call.\n\nconst (\n\t// see linux/net.h\n\t_SOCKET      = 1\n\t_BIND        = 2\n\t_CONNECT     = 3\n\t_LISTEN      = 4\n\t_ACCEPT      = 5\n\t_GETSOCKNAME = 6\n\t_GETPEERNAME = 7\n\t_SOCKETPAIR  = 8\n\t_SEND        = 9\n\t_RECV        = 10\n\t_SENDTO      = 11\n\t_RECVFROM    = 12\n\t_SHUTDOWN    = 13\n\t_SETSOCKOPT  = 14\n\t_GETSOCKOPT  = 15\n\t_SENDMSG     = 16\n\t_RECVMSG     = 17\n\t_ACCEPT4     = 18\n\t_RECVMMSG    = 19\n\t_SENDMMSG    = 20\n)\n\nfunc accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {\n\tfd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {\n\t_, e := rawsocketcall(_GETSOCKNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {\n\t_, e := rawsocketcall(_GETPEERNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc socketpair(domain int, typ int, flags int, fd *[2]int32) (err error) {\n\t_, e := rawsocketcall(_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd)), 0, 0)\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {\n\t_, e := socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {\n\t_, e := socketcall(_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc socket(domain int, typ int, proto int) (fd int, err error) {\n\tfd, e := rawsocketcall(_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0)\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {\n\t_, e := socketcall(_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {\n\t_, e := socketcall(_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), vallen, 0)\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc recvfrom(s int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {\n\tvar base uintptr\n\tif len(p) > 0 {\n\t\tbase = uintptr(unsafe.Pointer(&p[0]))\n\t}\n\tn, e := socketcall(_RECVFROM, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc sendto(s int, p []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {\n\tvar base uintptr\n\tif len(p) > 0 {\n\t\tbase = uintptr(unsafe.Pointer(&p[0]))\n\t}\n\t_, e := socketcall(_SENDTO, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(to), uintptr(addrlen))\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {\n\tn, e := socketcall(_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {\n\tn, e := socketcall(_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc Listen(s int, n int) (err error) {\n\t_, e := socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0)\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc Shutdown(s, how int) (err error) {\n\t_, e := socketcall(_SHUTDOWN, uintptr(s), uintptr(how), 0, 0, 0, 0)\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc Fstatfs(fd int, buf *Statfs_t) (err error) {\n\t_, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc Statfs(path string, buf *Statfs_t) (err error) {\n\tpathp, err := BytePtrFromString(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc (r *PtraceRegs) PC() uint64 { return uint64(uint32(r.Eip)) }\n\nfunc (r *PtraceRegs) SetPC(pc uint64) { r.Eip = int32(pc) }\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = uint32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\nfunc (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {\n\trsa.Service_name_len = uint32(length)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_alarm.go",
    "content": "// Copyright 2022 The Go 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\n//go:build linux && (386 || amd64 || mips || mipsle || mips64 || mipsle || ppc64 || ppc64le || ppc || s390x || sparc64)\n\npackage unix\n\n// SYS_ALARM is not defined on arm or riscv, but is available for other GOARCH\n// values.\n\n//sys\tAlarm(seconds uint) (remaining uint, err error)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_amd64.go",
    "content": "// Copyright 2009 The Go 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\n//go:build amd64 && linux\n\npackage unix\n\n//sys\tEpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)\n//sys\tFadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64\n//sys\tFchown(fd int, uid int, gid int) (err error)\n//sys\tFstat(fd int, stat *Stat_t) (err error)\n//sys\tFstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT\n//sys\tFstatfs(fd int, buf *Statfs_t) (err error)\n//sys\tFtruncate(fd int, length int64) (err error)\n//sysnb\tGetegid() (egid int)\n//sysnb\tGeteuid() (euid int)\n//sysnb\tGetgid() (gid int)\n//sysnb\tGetrlimit(resource int, rlim *Rlimit) (err error)\n//sysnb\tGetuid() (uid int)\n//sys\tIoperm(from int, num int, on int) (err error)\n//sys\tIopl(level int) (err error)\n//sys\tLchown(path string, uid int, gid int) (err error)\n//sys\tListen(s int, n int) (err error)\n\nfunc Lstat(path string, stat *Stat_t) (err error) {\n\treturn Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW)\n}\n\n//sys\tMemfdSecret(flags int) (fd int, err error)\n//sys\tPause() (err error)\n//sys\tpread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64\n//sys\tpwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64\n//sys\tRenameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)\n//sys\tSeek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK\n\nfunc Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {\n\tvar ts *Timespec\n\tif timeout != nil {\n\t\tts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}\n\t}\n\treturn pselect6(nfd, r, w, e, ts, nil)\n}\n\n//sys\tsendfile(outfd int, infd int, offset *int64, count int) (written int, err error)\n//sys\tsetfsgid(gid int) (prev int, err error)\n//sys\tsetfsuid(uid int) (prev int, err error)\n//sys\tShutdown(fd int, how int) (err error)\n//sys\tSplice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)\n\nfunc Stat(path string, stat *Stat_t) (err error) {\n\t// Use fstatat, because Android's seccomp policy blocks stat.\n\treturn Fstatat(AT_FDCWD, path, stat, 0)\n}\n\n//sys\tStatfs(path string, buf *Statfs_t) (err error)\n//sys\tSyncFileRange(fd int, off int64, n int64, flags int) (err error)\n//sys\tTruncate(path string, length int64) (err error)\n//sys\tUstat(dev int, ubuf *Ustat_t) (err error)\n//sys\taccept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)\n//sys\tbind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\tconnect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sysnb\tgetgroups(n int, list *_Gid_t) (nn int, err error)\n//sysnb\tsetgroups(n int, list *_Gid_t) (err error)\n//sys\tgetsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)\n//sys\tsetsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)\n//sysnb\tsocket(domain int, typ int, proto int) (fd int, err error)\n//sysnb\tsocketpair(domain int, typ int, proto int, fd *[2]int32) (err error)\n//sysnb\tgetpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sysnb\tgetsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sys\trecvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)\n//sys\tsendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\trecvmsg(s int, msg *Msghdr, flags int) (n int, err error)\n//sys\tsendmsg(s int, msg *Msghdr, flags int) (n int, err error)\n//sys\tmmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)\n\n//sys\tfutimesat(dirfd int, path string, times *[2]Timeval) (err error)\n\nfunc Gettimeofday(tv *Timeval) (err error) {\n\terrno := gettimeofday(tv)\n\tif errno != 0 {\n\t\treturn errno\n\t}\n\treturn nil\n}\n\nfunc Time(t *Time_t) (tt Time_t, err error) {\n\tvar tv Timeval\n\terrno := gettimeofday(&tv)\n\tif errno != 0 {\n\t\treturn 0, errno\n\t}\n\tif t != nil {\n\t\t*t = Time_t(tv.Sec)\n\t}\n\treturn Time_t(tv.Sec), nil\n}\n\n//sys\tUtime(path string, buf *Utimbuf) (err error)\n//sys\tutimes(path string, times *[2]Timeval) (err error)\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: usec}\n}\n\nfunc (r *PtraceRegs) PC() uint64 { return r.Rip }\n\nfunc (r *PtraceRegs) SetPC(pc uint64) { r.Rip = pc }\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = uint64(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint64(length)\n}\n\nfunc (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {\n\trsa.Service_name_len = uint64(length)\n}\n\n//sys\tkexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)\n\nfunc KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {\n\tcmdlineLen := len(cmdline)\n\tif cmdlineLen > 0 {\n\t\t// Account for the additional NULL byte added by\n\t\t// BytePtrFromString in kexecFileLoad. The kexec_file_load\n\t\t// syscall expects a NULL-terminated string.\n\t\tcmdlineLen++\n\t}\n\treturn kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_amd64_gc.go",
    "content": "// Copyright 2016 The Go 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\n//go:build amd64 && linux && gc\n\npackage unix\n\nimport \"syscall\"\n\n//go:noescape\nfunc gettimeofday(tv *Timeval) (err syscall.Errno)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_arm.go",
    "content": "// Copyright 2009 The Go 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\n//go:build arm && linux\n\npackage unix\n\nimport (\n\t\"unsafe\"\n)\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: int32(sec), Nsec: int32(nsec)}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: int32(sec), Usec: int32(usec)}\n}\n\nfunc Seek(fd int, offset int64, whence int) (newoffset int64, err error) {\n\tnewoffset, errno := seek(fd, offset, whence)\n\tif errno != 0 {\n\t\treturn 0, errno\n\t}\n\treturn newoffset, nil\n}\n\n//sys\taccept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)\n//sys\tbind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\tconnect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sysnb\tgetgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32\n//sysnb\tsetgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32\n//sys\tgetsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)\n//sys\tsetsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)\n//sysnb\tsocket(domain int, typ int, proto int) (fd int, err error)\n//sysnb\tgetpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sysnb\tgetsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sys\trecvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)\n//sys\tsendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)\n//sysnb\tsocketpair(domain int, typ int, flags int, fd *[2]int32) (err error)\n//sys\trecvmsg(s int, msg *Msghdr, flags int) (n int, err error)\n//sys\tsendmsg(s int, msg *Msghdr, flags int) (n int, err error)\n\n// 64-bit file system and 32-bit uid calls\n// (16-bit uid calls are not always supported in newer kernels)\n//sys\tEpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)\n//sys\tFchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32\n//sys\tFstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64\n//sys\tFstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64\n//sysnb\tGetegid() (egid int) = SYS_GETEGID32\n//sysnb\tGeteuid() (euid int) = SYS_GETEUID32\n//sysnb\tGetgid() (gid int) = SYS_GETGID32\n//sysnb\tGetuid() (uid int) = SYS_GETUID32\n//sys\tLchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32\n//sys\tListen(s int, n int) (err error)\n//sys\tLstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64\n//sys\tPause() (err error)\n//sys\tRenameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)\n//sys\tsendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64\n//sys\tSelect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT\n//sys\tsetfsgid(gid int) (prev int, err error) = SYS_SETFSGID32\n//sys\tsetfsuid(uid int) (prev int, err error) = SYS_SETFSUID32\n//sys\tShutdown(fd int, how int) (err error)\n//sys\tSplice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)\n//sys\tStat(path string, stat *Stat_t) (err error) = SYS_STAT64\n//sys\tUstat(dev int, ubuf *Ustat_t) (err error)\n\n//sys\tfutimesat(dirfd int, path string, times *[2]Timeval) (err error)\n//sysnb\tGettimeofday(tv *Timeval) (err error)\n\nfunc Time(t *Time_t) (Time_t, error) {\n\tvar tv Timeval\n\terr := Gettimeofday(&tv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif t != nil {\n\t\t*t = Time_t(tv.Sec)\n\t}\n\treturn Time_t(tv.Sec), nil\n}\n\nfunc Utime(path string, buf *Utimbuf) error {\n\ttv := []Timeval{\n\t\t{Sec: buf.Actime},\n\t\t{Sec: buf.Modtime},\n\t}\n\treturn Utimes(path, tv)\n}\n\n//sys\tutimes(path string, times *[2]Timeval) (err error)\n\n//sys\tpread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64\n//sys\tpwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64\n//sys\tTruncate(path string, length int64) (err error) = SYS_TRUNCATE64\n//sys\tFtruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64\n\nfunc Fadvise(fd int, offset int64, length int64, advice int) (err error) {\n\t_, _, e1 := Syscall6(SYS_ARM_FADVISE64_64, uintptr(fd), uintptr(advice), uintptr(offset), uintptr(offset>>32), uintptr(length), uintptr(length>>32))\n\tif e1 != 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\n//sys\tmmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)\n\nfunc Fstatfs(fd int, buf *Statfs_t) (err error) {\n\t_, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc Statfs(path string, buf *Statfs_t) (err error) {\n\tpathp, err := BytePtrFromString(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {\n\tpage := uintptr(offset / 4096)\n\tif offset != int64(page)*4096 {\n\t\treturn 0, EINVAL\n\t}\n\treturn mmap2(addr, length, prot, flags, fd, page)\n}\n\ntype rlimit32 struct {\n\tCur uint32\n\tMax uint32\n}\n\n//sysnb\tgetrlimit(resource int, rlim *rlimit32) (err error) = SYS_UGETRLIMIT\n\nconst rlimInf32 = ^uint32(0)\nconst rlimInf64 = ^uint64(0)\n\nfunc Getrlimit(resource int, rlim *Rlimit) (err error) {\n\terr = Prlimit(0, resource, nil, rlim)\n\tif err != ENOSYS {\n\t\treturn err\n\t}\n\n\trl := rlimit32{}\n\terr = getrlimit(resource, &rl)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tif rl.Cur == rlimInf32 {\n\t\trlim.Cur = rlimInf64\n\t} else {\n\t\trlim.Cur = uint64(rl.Cur)\n\t}\n\n\tif rl.Max == rlimInf32 {\n\t\trlim.Max = rlimInf64\n\t} else {\n\t\trlim.Max = uint64(rl.Max)\n\t}\n\treturn\n}\n\nfunc (r *PtraceRegs) PC() uint64 { return uint64(r.Uregs[15]) }\n\nfunc (r *PtraceRegs) SetPC(pc uint64) { r.Uregs[15] = uint32(pc) }\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = uint32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\nfunc (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {\n\trsa.Service_name_len = uint32(length)\n}\n\n//sys\tarmSyncFileRange(fd int, flags int, off int64, n int64) (err error) = SYS_ARM_SYNC_FILE_RANGE\n\nfunc SyncFileRange(fd int, off int64, n int64, flags int) error {\n\t// The sync_file_range and arm_sync_file_range syscalls differ only in the\n\t// order of their arguments.\n\treturn armSyncFileRange(fd, flags, off, n)\n}\n\n//sys\tkexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)\n\nfunc KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {\n\tcmdlineLen := len(cmdline)\n\tif cmdlineLen > 0 {\n\t\t// Account for the additional NULL byte added by\n\t\t// BytePtrFromString in kexecFileLoad. The kexec_file_load\n\t\t// syscall expects a NULL-terminated string.\n\t\tcmdlineLen++\n\t}\n\treturn kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_arm64.go",
    "content": "// Copyright 2015 The Go 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\n//go:build arm64 && linux\n\npackage unix\n\nimport \"unsafe\"\n\n//sys\tEpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT\n//sys\tFadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64\n//sys\tFchown(fd int, uid int, gid int) (err error)\n//sys\tFstat(fd int, stat *Stat_t) (err error)\n//sys\tFstatat(fd int, path string, stat *Stat_t, flags int) (err error)\n//sys\tFstatfs(fd int, buf *Statfs_t) (err error)\n//sys\tFtruncate(fd int, length int64) (err error)\n//sysnb\tGetegid() (egid int)\n//sysnb\tGeteuid() (euid int)\n//sysnb\tGetgid() (gid int)\n//sysnb\tgetrlimit(resource int, rlim *Rlimit) (err error)\n//sysnb\tGetuid() (uid int)\n//sys\tListen(s int, n int) (err error)\n//sys\tMemfdSecret(flags int) (fd int, err error)\n//sys\tpread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64\n//sys\tpwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64\n//sys\tRenameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)\n//sys\tSeek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK\n\nfunc Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {\n\tvar ts *Timespec\n\tif timeout != nil {\n\t\tts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}\n\t}\n\treturn pselect6(nfd, r, w, e, ts, nil)\n}\n\n//sys\tsendfile(outfd int, infd int, offset *int64, count int) (written int, err error)\n//sys\tsetfsgid(gid int) (prev int, err error)\n//sys\tsetfsuid(uid int) (prev int, err error)\n//sys\tShutdown(fd int, how int) (err error)\n//sys\tSplice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)\n\nfunc Stat(path string, stat *Stat_t) (err error) {\n\treturn Fstatat(AT_FDCWD, path, stat, 0)\n}\n\nfunc Lchown(path string, uid int, gid int) (err error) {\n\treturn Fchownat(AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW)\n}\n\nfunc Lstat(path string, stat *Stat_t) (err error) {\n\treturn Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW)\n}\n\n//sys\tStatfs(path string, buf *Statfs_t) (err error)\n//sys\tSyncFileRange(fd int, off int64, n int64, flags int) (err error)\n//sys\tTruncate(path string, length int64) (err error)\n\nfunc Ustat(dev int, ubuf *Ustat_t) (err error) {\n\treturn ENOSYS\n}\n\n//sys\taccept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)\n//sys\tbind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\tconnect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sysnb\tgetgroups(n int, list *_Gid_t) (nn int, err error)\n//sysnb\tsetgroups(n int, list *_Gid_t) (err error)\n//sys\tgetsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)\n//sys\tsetsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)\n//sysnb\tsocket(domain int, typ int, proto int) (fd int, err error)\n//sysnb\tsocketpair(domain int, typ int, proto int, fd *[2]int32) (err error)\n//sysnb\tgetpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sysnb\tgetsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sys\trecvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)\n//sys\tsendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\trecvmsg(s int, msg *Msghdr, flags int) (n int, err error)\n//sys\tsendmsg(s int, msg *Msghdr, flags int) (n int, err error)\n//sys\tmmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)\n\n//sysnb\tGettimeofday(tv *Timeval) (err error)\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: usec}\n}\n\nfunc futimesat(dirfd int, path string, tv *[2]Timeval) (err error) {\n\tif tv == nil {\n\t\treturn utimensat(dirfd, path, nil, 0)\n\t}\n\n\tts := []Timespec{\n\t\tNsecToTimespec(TimevalToNsec(tv[0])),\n\t\tNsecToTimespec(TimevalToNsec(tv[1])),\n\t}\n\treturn utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)\n}\n\nfunc Time(t *Time_t) (Time_t, error) {\n\tvar tv Timeval\n\terr := Gettimeofday(&tv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif t != nil {\n\t\t*t = Time_t(tv.Sec)\n\t}\n\treturn Time_t(tv.Sec), nil\n}\n\nfunc Utime(path string, buf *Utimbuf) error {\n\ttv := []Timeval{\n\t\t{Sec: buf.Actime},\n\t\t{Sec: buf.Modtime},\n\t}\n\treturn Utimes(path, tv)\n}\n\nfunc utimes(path string, tv *[2]Timeval) (err error) {\n\tif tv == nil {\n\t\treturn utimensat(AT_FDCWD, path, nil, 0)\n\t}\n\n\tts := []Timespec{\n\t\tNsecToTimespec(TimevalToNsec(tv[0])),\n\t\tNsecToTimespec(TimevalToNsec(tv[1])),\n\t}\n\treturn utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)\n}\n\n// Getrlimit prefers the prlimit64 system call. See issue 38604.\nfunc Getrlimit(resource int, rlim *Rlimit) error {\n\terr := Prlimit(0, resource, nil, rlim)\n\tif err != ENOSYS {\n\t\treturn err\n\t}\n\treturn getrlimit(resource, rlim)\n}\n\nfunc (r *PtraceRegs) PC() uint64 { return r.Pc }\n\nfunc (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc }\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = uint64(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint64(length)\n}\n\nfunc (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {\n\trsa.Service_name_len = uint64(length)\n}\n\nfunc Pause() error {\n\t_, err := ppoll(nil, 0, nil, nil)\n\treturn err\n}\n\n//sys\tkexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)\n\nfunc KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {\n\tcmdlineLen := len(cmdline)\n\tif cmdlineLen > 0 {\n\t\t// Account for the additional NULL byte added by\n\t\t// BytePtrFromString in kexecFileLoad. The kexec_file_load\n\t\t// syscall expects a NULL-terminated string.\n\t\tcmdlineLen++\n\t}\n\treturn kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)\n}\n\nconst SYS_FSTATAT = SYS_NEWFSTATAT\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_gc.go",
    "content": "// Copyright 2018 The Go 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\n//go:build linux && gc\n\npackage unix\n\n// SyscallNoError may be used instead of Syscall for syscalls that don't fail.\nfunc SyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)\n\n// RawSyscallNoError may be used instead of RawSyscall for syscalls that don't\n// fail.\nfunc RawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_gc_386.go",
    "content": "// Copyright 2018 The Go 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\n//go:build linux && gc && 386\n\npackage unix\n\nimport \"syscall\"\n\n// Underlying system call writes to newoffset via pointer.\n// Implemented in assembly to avoid allocation.\nfunc seek(fd int, offset int64, whence int) (newoffset int64, err syscall.Errno)\n\nfunc socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)\nfunc rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err syscall.Errno)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_gc_arm.go",
    "content": "// Copyright 2009 The Go 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\n//go:build arm && gc && linux\n\npackage unix\n\nimport \"syscall\"\n\n// Underlying system call writes to newoffset via pointer.\n// Implemented in assembly to avoid allocation.\nfunc seek(fd int, offset int64, whence int) (newoffset int64, err syscall.Errno)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_gccgo_386.go",
    "content": "// Copyright 2018 The Go 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\n//go:build linux && gccgo && 386\n\npackage unix\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nfunc seek(fd int, offset int64, whence int) (int64, syscall.Errno) {\n\tvar newoffset int64\n\toffsetLow := uint32(offset & 0xffffffff)\n\toffsetHigh := uint32((offset >> 32) & 0xffffffff)\n\t_, _, err := Syscall6(SYS__LLSEEK, uintptr(fd), uintptr(offsetHigh), uintptr(offsetLow), uintptr(unsafe.Pointer(&newoffset)), uintptr(whence), 0)\n\treturn newoffset, err\n}\n\nfunc socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno) {\n\tfd, _, err := Syscall(SYS_SOCKETCALL, uintptr(call), uintptr(unsafe.Pointer(&a0)), 0)\n\treturn int(fd), err\n}\n\nfunc rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno) {\n\tfd, _, err := RawSyscall(SYS_SOCKETCALL, uintptr(call), uintptr(unsafe.Pointer(&a0)), 0)\n\treturn int(fd), err\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_gccgo_arm.go",
    "content": "// Copyright 2018 The Go 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\n//go:build linux && gccgo && arm\n\npackage unix\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nfunc seek(fd int, offset int64, whence int) (int64, syscall.Errno) {\n\tvar newoffset int64\n\toffsetLow := uint32(offset & 0xffffffff)\n\toffsetHigh := uint32((offset >> 32) & 0xffffffff)\n\t_, _, err := Syscall6(SYS__LLSEEK, uintptr(fd), uintptr(offsetHigh), uintptr(offsetLow), uintptr(unsafe.Pointer(&newoffset)), uintptr(whence), 0)\n\treturn newoffset, err\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_loong64.go",
    "content": "// Copyright 2022 The Go 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\n//go:build loong64 && linux\n\npackage unix\n\nimport \"unsafe\"\n\n//sys\tEpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT\n//sys\tFadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64\n//sys\tFchown(fd int, uid int, gid int) (err error)\n//sys\tFstatfs(fd int, buf *Statfs_t) (err error)\n//sys\tFtruncate(fd int, length int64) (err error)\n//sysnb\tGetegid() (egid int)\n//sysnb\tGeteuid() (euid int)\n//sysnb\tGetgid() (gid int)\n//sysnb\tGetuid() (uid int)\n//sys\tListen(s int, n int) (err error)\n//sys\tpread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64\n//sys\tpwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64\n//sys\tSeek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK\n\nfunc Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {\n\tvar ts *Timespec\n\tif timeout != nil {\n\t\tts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}\n\t}\n\treturn pselect6(nfd, r, w, e, ts, nil)\n}\n\n//sys\tsendfile(outfd int, infd int, offset *int64, count int) (written int, err error)\n//sys\tsetfsgid(gid int) (prev int, err error)\n//sys\tsetfsuid(uid int) (prev int, err error)\n//sys\tShutdown(fd int, how int) (err error)\n//sys\tSplice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)\n\nfunc timespecFromStatxTimestamp(x StatxTimestamp) Timespec {\n\treturn Timespec{\n\t\tSec:  x.Sec,\n\t\tNsec: int64(x.Nsec),\n\t}\n}\n\nfunc Fstatat(fd int, path string, stat *Stat_t, flags int) error {\n\tvar r Statx_t\n\t// Do it the glibc way, add AT_NO_AUTOMOUNT.\n\tif err := Statx(fd, path, AT_NO_AUTOMOUNT|flags, STATX_BASIC_STATS, &r); err != nil {\n\t\treturn err\n\t}\n\n\tstat.Dev = Mkdev(r.Dev_major, r.Dev_minor)\n\tstat.Ino = r.Ino\n\tstat.Mode = uint32(r.Mode)\n\tstat.Nlink = r.Nlink\n\tstat.Uid = r.Uid\n\tstat.Gid = r.Gid\n\tstat.Rdev = Mkdev(r.Rdev_major, r.Rdev_minor)\n\t// hope we don't get to process files so large to overflow these size\n\t// fields...\n\tstat.Size = int64(r.Size)\n\tstat.Blksize = int32(r.Blksize)\n\tstat.Blocks = int64(r.Blocks)\n\tstat.Atim = timespecFromStatxTimestamp(r.Atime)\n\tstat.Mtim = timespecFromStatxTimestamp(r.Mtime)\n\tstat.Ctim = timespecFromStatxTimestamp(r.Ctime)\n\n\treturn nil\n}\n\nfunc Fstat(fd int, stat *Stat_t) (err error) {\n\treturn Fstatat(fd, \"\", stat, AT_EMPTY_PATH)\n}\n\nfunc Stat(path string, stat *Stat_t) (err error) {\n\treturn Fstatat(AT_FDCWD, path, stat, 0)\n}\n\nfunc Lchown(path string, uid int, gid int) (err error) {\n\treturn Fchownat(AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW)\n}\n\nfunc Lstat(path string, stat *Stat_t) (err error) {\n\treturn Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW)\n}\n\n//sys\tStatfs(path string, buf *Statfs_t) (err error)\n//sys\tSyncFileRange(fd int, off int64, n int64, flags int) (err error)\n//sys\tTruncate(path string, length int64) (err error)\n\nfunc Ustat(dev int, ubuf *Ustat_t) (err error) {\n\treturn ENOSYS\n}\n\n//sys\taccept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)\n//sys\tbind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\tconnect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sysnb\tgetgroups(n int, list *_Gid_t) (nn int, err error)\n//sysnb\tsetgroups(n int, list *_Gid_t) (err error)\n//sys\tgetsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)\n//sys\tsetsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)\n//sysnb\tsocket(domain int, typ int, proto int) (fd int, err error)\n//sysnb\tsocketpair(domain int, typ int, proto int, fd *[2]int32) (err error)\n//sysnb\tgetpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sysnb\tgetsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sys\trecvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)\n//sys\tsendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\trecvmsg(s int, msg *Msghdr, flags int) (n int, err error)\n//sys\tsendmsg(s int, msg *Msghdr, flags int) (n int, err error)\n//sys\tmmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)\n\n//sysnb\tGettimeofday(tv *Timeval) (err error)\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: usec}\n}\n\nfunc Getrlimit(resource int, rlim *Rlimit) (err error) {\n\terr = Prlimit(0, resource, nil, rlim)\n\treturn\n}\n\nfunc futimesat(dirfd int, path string, tv *[2]Timeval) (err error) {\n\tif tv == nil {\n\t\treturn utimensat(dirfd, path, nil, 0)\n\t}\n\n\tts := []Timespec{\n\t\tNsecToTimespec(TimevalToNsec(tv[0])),\n\t\tNsecToTimespec(TimevalToNsec(tv[1])),\n\t}\n\treturn utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)\n}\n\nfunc Time(t *Time_t) (Time_t, error) {\n\tvar tv Timeval\n\terr := Gettimeofday(&tv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif t != nil {\n\t\t*t = Time_t(tv.Sec)\n\t}\n\treturn Time_t(tv.Sec), nil\n}\n\nfunc Utime(path string, buf *Utimbuf) error {\n\ttv := []Timeval{\n\t\t{Sec: buf.Actime},\n\t\t{Sec: buf.Modtime},\n\t}\n\treturn Utimes(path, tv)\n}\n\nfunc utimes(path string, tv *[2]Timeval) (err error) {\n\tif tv == nil {\n\t\treturn utimensat(AT_FDCWD, path, nil, 0)\n\t}\n\n\tts := []Timespec{\n\t\tNsecToTimespec(TimevalToNsec(tv[0])),\n\t\tNsecToTimespec(TimevalToNsec(tv[1])),\n\t}\n\treturn utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)\n}\n\nfunc (r *PtraceRegs) PC() uint64 { return r.Era }\n\nfunc (r *PtraceRegs) SetPC(era uint64) { r.Era = era }\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = uint64(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint64(length)\n}\n\nfunc (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {\n\trsa.Service_name_len = uint64(length)\n}\n\nfunc Pause() error {\n\t_, err := ppoll(nil, 0, nil, nil)\n\treturn err\n}\n\nfunc Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {\n\treturn Renameat2(olddirfd, oldpath, newdirfd, newpath, 0)\n}\n\n//sys\tkexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)\n\nfunc KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {\n\tcmdlineLen := len(cmdline)\n\tif cmdlineLen > 0 {\n\t\t// Account for the additional NULL byte added by\n\t\t// BytePtrFromString in kexecFileLoad. The kexec_file_load\n\t\t// syscall expects a NULL-terminated string.\n\t\tcmdlineLen++\n\t}\n\treturn kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)\n}\n\nconst SYS_FSTATAT = SYS_NEWFSTATAT\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go",
    "content": "// Copyright 2015 The Go 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\n//go:build linux && (mips64 || mips64le)\n\npackage unix\n\n//sys\tEpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)\n//sys\tFadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64\n//sys\tFchown(fd int, uid int, gid int) (err error)\n//sys\tFstatfs(fd int, buf *Statfs_t) (err error)\n//sys\tFtruncate(fd int, length int64) (err error)\n//sysnb\tGetegid() (egid int)\n//sysnb\tGeteuid() (euid int)\n//sysnb\tGetgid() (gid int)\n//sysnb\tGetrlimit(resource int, rlim *Rlimit) (err error)\n//sysnb\tGetuid() (uid int)\n//sys\tLchown(path string, uid int, gid int) (err error)\n//sys\tListen(s int, n int) (err error)\n//sys\tPause() (err error)\n//sys\tpread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64\n//sys\tpwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64\n//sys\tRenameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)\n//sys\tSeek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK\n\nfunc Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {\n\tvar ts *Timespec\n\tif timeout != nil {\n\t\tts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}\n\t}\n\treturn pselect6(nfd, r, w, e, ts, nil)\n}\n\n//sys\tsendfile(outfd int, infd int, offset *int64, count int) (written int, err error)\n//sys\tsetfsgid(gid int) (prev int, err error)\n//sys\tsetfsuid(uid int) (prev int, err error)\n//sys\tShutdown(fd int, how int) (err error)\n//sys\tSplice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)\n//sys\tStatfs(path string, buf *Statfs_t) (err error)\n//sys\tSyncFileRange(fd int, off int64, n int64, flags int) (err error)\n//sys\tTruncate(path string, length int64) (err error)\n//sys\tUstat(dev int, ubuf *Ustat_t) (err error)\n//sys\taccept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)\n//sys\tbind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\tconnect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sysnb\tgetgroups(n int, list *_Gid_t) (nn int, err error)\n//sysnb\tsetgroups(n int, list *_Gid_t) (err error)\n//sys\tgetsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)\n//sys\tsetsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)\n//sysnb\tsocket(domain int, typ int, proto int) (fd int, err error)\n//sysnb\tsocketpair(domain int, typ int, proto int, fd *[2]int32) (err error)\n//sysnb\tgetpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sysnb\tgetsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sys\trecvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)\n//sys\tsendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\trecvmsg(s int, msg *Msghdr, flags int) (n int, err error)\n//sys\tsendmsg(s int, msg *Msghdr, flags int) (n int, err error)\n//sys\tmmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)\n\n//sys\tfutimesat(dirfd int, path string, times *[2]Timeval) (err error)\n//sysnb\tGettimeofday(tv *Timeval) (err error)\n\nfunc Time(t *Time_t) (tt Time_t, err error) {\n\tvar tv Timeval\n\terr = Gettimeofday(&tv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif t != nil {\n\t\t*t = Time_t(tv.Sec)\n\t}\n\treturn Time_t(tv.Sec), nil\n}\n\n//sys\tUtime(path string, buf *Utimbuf) (err error)\n//sys\tutimes(path string, times *[2]Timeval) (err error)\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: usec}\n}\n\nfunc Ioperm(from int, num int, on int) (err error) {\n\treturn ENOSYS\n}\n\nfunc Iopl(level int) (err error) {\n\treturn ENOSYS\n}\n\ntype stat_t struct {\n\tDev        uint32\n\tPad0       [3]int32\n\tIno        uint64\n\tMode       uint32\n\tNlink      uint32\n\tUid        uint32\n\tGid        uint32\n\tRdev       uint32\n\tPad1       [3]uint32\n\tSize       int64\n\tAtime      uint32\n\tAtime_nsec uint32\n\tMtime      uint32\n\tMtime_nsec uint32\n\tCtime      uint32\n\tCtime_nsec uint32\n\tBlksize    uint32\n\tPad2       uint32\n\tBlocks     int64\n}\n\n//sys\tfstat(fd int, st *stat_t) (err error)\n//sys\tfstatat(dirfd int, path string, st *stat_t, flags int) (err error) = SYS_NEWFSTATAT\n//sys\tlstat(path string, st *stat_t) (err error)\n//sys\tstat(path string, st *stat_t) (err error)\n\nfunc Fstat(fd int, s *Stat_t) (err error) {\n\tst := &stat_t{}\n\terr = fstat(fd, st)\n\tfillStat_t(s, st)\n\treturn\n}\n\nfunc Fstatat(dirfd int, path string, s *Stat_t, flags int) (err error) {\n\tst := &stat_t{}\n\terr = fstatat(dirfd, path, st, flags)\n\tfillStat_t(s, st)\n\treturn\n}\n\nfunc Lstat(path string, s *Stat_t) (err error) {\n\tst := &stat_t{}\n\terr = lstat(path, st)\n\tfillStat_t(s, st)\n\treturn\n}\n\nfunc Stat(path string, s *Stat_t) (err error) {\n\tst := &stat_t{}\n\terr = stat(path, st)\n\tfillStat_t(s, st)\n\treturn\n}\n\nfunc fillStat_t(s *Stat_t, st *stat_t) {\n\ts.Dev = st.Dev\n\ts.Ino = st.Ino\n\ts.Mode = st.Mode\n\ts.Nlink = st.Nlink\n\ts.Uid = st.Uid\n\ts.Gid = st.Gid\n\ts.Rdev = st.Rdev\n\ts.Size = st.Size\n\ts.Atim = Timespec{int64(st.Atime), int64(st.Atime_nsec)}\n\ts.Mtim = Timespec{int64(st.Mtime), int64(st.Mtime_nsec)}\n\ts.Ctim = Timespec{int64(st.Ctime), int64(st.Ctime_nsec)}\n\ts.Blksize = st.Blksize\n\ts.Blocks = st.Blocks\n}\n\nfunc (r *PtraceRegs) PC() uint64 { return r.Epc }\n\nfunc (r *PtraceRegs) SetPC(pc uint64) { r.Epc = pc }\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = uint64(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint64(length)\n}\n\nfunc (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {\n\trsa.Service_name_len = uint64(length)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go",
    "content": "// Copyright 2016 The Go 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\n//go:build linux && (mips || mipsle)\n\npackage unix\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nfunc Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)\n\n//sys\tEpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)\n//sys\tFadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64\n//sys\tFchown(fd int, uid int, gid int) (err error)\n//sys\tFtruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64\n//sysnb\tGetegid() (egid int)\n//sysnb\tGeteuid() (euid int)\n//sysnb\tGetgid() (gid int)\n//sysnb\tGetuid() (uid int)\n//sys\tLchown(path string, uid int, gid int) (err error)\n//sys\tListen(s int, n int) (err error)\n//sys\tpread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64\n//sys\tpwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64\n//sys\tRenameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)\n//sys\tSelect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT\n//sys\tsendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64\n//sys\tsetfsgid(gid int) (prev int, err error)\n//sys\tsetfsuid(uid int) (prev int, err error)\n//sys\tShutdown(fd int, how int) (err error)\n//sys\tSplice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)\n//sys\tSyncFileRange(fd int, off int64, n int64, flags int) (err error)\n//sys\tTruncate(path string, length int64) (err error) = SYS_TRUNCATE64\n//sys\tUstat(dev int, ubuf *Ustat_t) (err error)\n//sys\taccept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)\n//sys\tbind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\tconnect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sysnb\tgetgroups(n int, list *_Gid_t) (nn int, err error)\n//sysnb\tsetgroups(n int, list *_Gid_t) (err error)\n//sys\tgetsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)\n//sys\tsetsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)\n//sysnb\tsocket(domain int, typ int, proto int) (fd int, err error)\n//sysnb\tsocketpair(domain int, typ int, proto int, fd *[2]int32) (err error)\n//sysnb\tgetpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sysnb\tgetsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sys\trecvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)\n//sys\tsendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\trecvmsg(s int, msg *Msghdr, flags int) (n int, err error)\n//sys\tsendmsg(s int, msg *Msghdr, flags int) (n int, err error)\n\n//sys\tIoperm(from int, num int, on int) (err error)\n//sys\tIopl(level int) (err error)\n\n//sys\tfutimesat(dirfd int, path string, times *[2]Timeval) (err error)\n//sysnb\tGettimeofday(tv *Timeval) (err error)\n//sysnb\tTime(t *Time_t) (tt Time_t, err error)\n//sys\tUtime(path string, buf *Utimbuf) (err error)\n//sys\tutimes(path string, times *[2]Timeval) (err error)\n\n//sys\tLstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64\n//sys\tFstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64\n//sys\tFstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64\n//sys\tStat(path string, stat *Stat_t) (err error) = SYS_STAT64\n\n//sys\tPause() (err error)\n\nfunc Fstatfs(fd int, buf *Statfs_t) (err error) {\n\t_, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))\n\tif e != 0 {\n\t\terr = errnoErr(e)\n\t}\n\treturn\n}\n\nfunc Statfs(path string, buf *Statfs_t) (err error) {\n\tp, err := BytePtrFromString(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(p)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))\n\tif e != 0 {\n\t\terr = errnoErr(e)\n\t}\n\treturn\n}\n\nfunc Seek(fd int, offset int64, whence int) (off int64, err error) {\n\t_, _, e := Syscall6(SYS__LLSEEK, uintptr(fd), uintptr(offset>>32), uintptr(offset), uintptr(unsafe.Pointer(&off)), uintptr(whence), 0)\n\tif e != 0 {\n\t\terr = errnoErr(e)\n\t}\n\treturn\n}\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: int32(sec), Nsec: int32(nsec)}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: int32(sec), Usec: int32(usec)}\n}\n\n//sys\tmmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)\n\nfunc mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {\n\tpage := uintptr(offset / 4096)\n\tif offset != int64(page)*4096 {\n\t\treturn 0, EINVAL\n\t}\n\treturn mmap2(addr, length, prot, flags, fd, page)\n}\n\nconst rlimInf32 = ^uint32(0)\nconst rlimInf64 = ^uint64(0)\n\ntype rlimit32 struct {\n\tCur uint32\n\tMax uint32\n}\n\n//sysnb\tgetrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT\n\nfunc Getrlimit(resource int, rlim *Rlimit) (err error) {\n\terr = Prlimit(0, resource, nil, rlim)\n\tif err != ENOSYS {\n\t\treturn err\n\t}\n\n\trl := rlimit32{}\n\terr = getrlimit(resource, &rl)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tif rl.Cur == rlimInf32 {\n\t\trlim.Cur = rlimInf64\n\t} else {\n\t\trlim.Cur = uint64(rl.Cur)\n\t}\n\n\tif rl.Max == rlimInf32 {\n\t\trlim.Max = rlimInf64\n\t} else {\n\t\trlim.Max = uint64(rl.Max)\n\t}\n\treturn\n}\n\nfunc (r *PtraceRegs) PC() uint64 { return r.Epc }\n\nfunc (r *PtraceRegs) SetPC(pc uint64) { r.Epc = pc }\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = uint32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\nfunc (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {\n\trsa.Service_name_len = uint32(length)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_ppc.go",
    "content": "// Copyright 2021 The Go 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\n//go:build linux && ppc\n\npackage unix\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n//sys\tEpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)\n//sys\tFchown(fd int, uid int, gid int) (err error)\n//sys\tFstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64\n//sys\tFstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64\n//sys\tFtruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64\n//sysnb\tGetegid() (egid int)\n//sysnb\tGeteuid() (euid int)\n//sysnb\tGetgid() (gid int)\n//sysnb\tGetuid() (uid int)\n//sys\tIoperm(from int, num int, on int) (err error)\n//sys\tIopl(level int) (err error)\n//sys\tLchown(path string, uid int, gid int) (err error)\n//sys\tListen(s int, n int) (err error)\n//sys\tLstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64\n//sys\tPause() (err error)\n//sys\tpread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64\n//sys\tpwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64\n//sys\tRenameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)\n//sys\tSelect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT\n//sys\tsendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64\n//sys\tsetfsgid(gid int) (prev int, err error)\n//sys\tsetfsuid(uid int) (prev int, err error)\n//sys\tShutdown(fd int, how int) (err error)\n//sys\tSplice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)\n//sys\tStat(path string, stat *Stat_t) (err error) = SYS_STAT64\n//sys\tTruncate(path string, length int64) (err error) = SYS_TRUNCATE64\n//sys\tUstat(dev int, ubuf *Ustat_t) (err error)\n//sys\taccept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)\n//sys\tbind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\tconnect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sysnb\tgetgroups(n int, list *_Gid_t) (nn int, err error)\n//sysnb\tsetgroups(n int, list *_Gid_t) (err error)\n//sys\tgetsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)\n//sys\tsetsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)\n//sysnb\tsocket(domain int, typ int, proto int) (fd int, err error)\n//sysnb\tsocketpair(domain int, typ int, proto int, fd *[2]int32) (err error)\n//sysnb\tgetpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sysnb\tgetsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sys\trecvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)\n//sys\tsendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\trecvmsg(s int, msg *Msghdr, flags int) (n int, err error)\n//sys\tsendmsg(s int, msg *Msghdr, flags int) (n int, err error)\n\n//sys\tfutimesat(dirfd int, path string, times *[2]Timeval) (err error)\n//sysnb\tGettimeofday(tv *Timeval) (err error)\n//sysnb\tTime(t *Time_t) (tt Time_t, err error)\n//sys\tUtime(path string, buf *Utimbuf) (err error)\n//sys\tutimes(path string, times *[2]Timeval) (err error)\n\nfunc Fadvise(fd int, offset int64, length int64, advice int) (err error) {\n\t_, _, e1 := Syscall6(SYS_FADVISE64_64, uintptr(fd), uintptr(advice), uintptr(offset>>32), uintptr(offset), uintptr(length>>32), uintptr(length))\n\tif e1 != 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc seek(fd int, offset int64, whence int) (int64, syscall.Errno) {\n\tvar newoffset int64\n\toffsetLow := uint32(offset & 0xffffffff)\n\toffsetHigh := uint32((offset >> 32) & 0xffffffff)\n\t_, _, err := Syscall6(SYS__LLSEEK, uintptr(fd), uintptr(offsetHigh), uintptr(offsetLow), uintptr(unsafe.Pointer(&newoffset)), uintptr(whence), 0)\n\treturn newoffset, err\n}\n\nfunc Seek(fd int, offset int64, whence int) (newoffset int64, err error) {\n\tnewoffset, errno := seek(fd, offset, whence)\n\tif errno != 0 {\n\t\treturn 0, errno\n\t}\n\treturn newoffset, nil\n}\n\nfunc Fstatfs(fd int, buf *Statfs_t) (err error) {\n\t_, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\nfunc Statfs(path string, buf *Statfs_t) (err error) {\n\tpathp, err := BytePtrFromString(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))\n\tif e != 0 {\n\t\terr = e\n\t}\n\treturn\n}\n\n//sys\tmmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)\n\nfunc mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {\n\tpage := uintptr(offset / 4096)\n\tif offset != int64(page)*4096 {\n\t\treturn 0, EINVAL\n\t}\n\treturn mmap2(addr, length, prot, flags, fd, page)\n}\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: int32(sec), Nsec: int32(nsec)}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: int32(sec), Usec: int32(usec)}\n}\n\ntype rlimit32 struct {\n\tCur uint32\n\tMax uint32\n}\n\n//sysnb\tgetrlimit(resource int, rlim *rlimit32) (err error) = SYS_UGETRLIMIT\n\nconst rlimInf32 = ^uint32(0)\nconst rlimInf64 = ^uint64(0)\n\nfunc Getrlimit(resource int, rlim *Rlimit) (err error) {\n\terr = Prlimit(0, resource, nil, rlim)\n\tif err != ENOSYS {\n\t\treturn err\n\t}\n\n\trl := rlimit32{}\n\terr = getrlimit(resource, &rl)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tif rl.Cur == rlimInf32 {\n\t\trlim.Cur = rlimInf64\n\t} else {\n\t\trlim.Cur = uint64(rl.Cur)\n\t}\n\n\tif rl.Max == rlimInf32 {\n\t\trlim.Max = rlimInf64\n\t} else {\n\t\trlim.Max = uint64(rl.Max)\n\t}\n\treturn\n}\n\nfunc (r *PtraceRegs) PC() uint32 { return r.Nip }\n\nfunc (r *PtraceRegs) SetPC(pc uint32) { r.Nip = pc }\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = uint32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\nfunc (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {\n\trsa.Service_name_len = uint32(length)\n}\n\n//sys\tsyncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2\n\nfunc SyncFileRange(fd int, off int64, n int64, flags int) error {\n\t// The sync_file_range and sync_file_range2 syscalls differ only in the\n\t// order of their arguments.\n\treturn syncFileRange2(fd, flags, off, n)\n}\n\n//sys\tkexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)\n\nfunc KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {\n\tcmdlineLen := len(cmdline)\n\tif cmdlineLen > 0 {\n\t\t// Account for the additional NULL byte added by\n\t\t// BytePtrFromString in kexecFileLoad. The kexec_file_load\n\t\t// syscall expects a NULL-terminated string.\n\t\tcmdlineLen++\n\t}\n\treturn kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go",
    "content": "// Copyright 2009 The Go 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\n//go:build linux && (ppc64 || ppc64le)\n\npackage unix\n\n//sys\tEpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)\n//sys\tFadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64\n//sys\tFchown(fd int, uid int, gid int) (err error)\n//sys\tFstat(fd int, stat *Stat_t) (err error)\n//sys\tFstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT\n//sys\tFstatfs(fd int, buf *Statfs_t) (err error)\n//sys\tFtruncate(fd int, length int64) (err error)\n//sysnb\tGetegid() (egid int)\n//sysnb\tGeteuid() (euid int)\n//sysnb\tGetgid() (gid int)\n//sysnb\tGetrlimit(resource int, rlim *Rlimit) (err error) = SYS_UGETRLIMIT\n//sysnb\tGetuid() (uid int)\n//sys\tIoperm(from int, num int, on int) (err error)\n//sys\tIopl(level int) (err error)\n//sys\tLchown(path string, uid int, gid int) (err error)\n//sys\tListen(s int, n int) (err error)\n//sys\tLstat(path string, stat *Stat_t) (err error)\n//sys\tPause() (err error)\n//sys\tpread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64\n//sys\tpwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64\n//sys\tRenameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)\n//sys\tSeek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK\n//sys\tSelect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT\n//sys\tsendfile(outfd int, infd int, offset *int64, count int) (written int, err error)\n//sys\tsetfsgid(gid int) (prev int, err error)\n//sys\tsetfsuid(uid int) (prev int, err error)\n//sys\tShutdown(fd int, how int) (err error)\n//sys\tSplice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)\n//sys\tStat(path string, stat *Stat_t) (err error)\n//sys\tStatfs(path string, buf *Statfs_t) (err error)\n//sys\tTruncate(path string, length int64) (err error)\n//sys\tUstat(dev int, ubuf *Ustat_t) (err error)\n//sys\taccept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)\n//sys\tbind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\tconnect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sysnb\tgetgroups(n int, list *_Gid_t) (nn int, err error)\n//sysnb\tsetgroups(n int, list *_Gid_t) (err error)\n//sys\tgetsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)\n//sys\tsetsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)\n//sysnb\tsocket(domain int, typ int, proto int) (fd int, err error)\n//sysnb\tsocketpair(domain int, typ int, proto int, fd *[2]int32) (err error)\n//sysnb\tgetpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sysnb\tgetsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sys\trecvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)\n//sys\tsendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\trecvmsg(s int, msg *Msghdr, flags int) (n int, err error)\n//sys\tsendmsg(s int, msg *Msghdr, flags int) (n int, err error)\n//sys\tmmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)\n\n//sys\tfutimesat(dirfd int, path string, times *[2]Timeval) (err error)\n//sysnb\tGettimeofday(tv *Timeval) (err error)\n//sysnb\tTime(t *Time_t) (tt Time_t, err error)\n//sys\tUtime(path string, buf *Utimbuf) (err error)\n//sys\tutimes(path string, times *[2]Timeval) (err error)\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: usec}\n}\n\nfunc (r *PtraceRegs) PC() uint64 { return r.Nip }\n\nfunc (r *PtraceRegs) SetPC(pc uint64) { r.Nip = pc }\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = uint64(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint64(length)\n}\n\nfunc (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {\n\trsa.Service_name_len = uint64(length)\n}\n\n//sys\tsyncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2\n\nfunc SyncFileRange(fd int, off int64, n int64, flags int) error {\n\t// The sync_file_range and sync_file_range2 syscalls differ only in the\n\t// order of their arguments.\n\treturn syncFileRange2(fd, flags, off, n)\n}\n\n//sys\tkexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)\n\nfunc KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {\n\tcmdlineLen := len(cmdline)\n\tif cmdlineLen > 0 {\n\t\t// Account for the additional NULL byte added by\n\t\t// BytePtrFromString in kexecFileLoad. The kexec_file_load\n\t\t// syscall expects a NULL-terminated string.\n\t\tcmdlineLen++\n\t}\n\treturn kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go",
    "content": "// Copyright 2018 The Go 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\n//go:build riscv64 && linux\n\npackage unix\n\nimport \"unsafe\"\n\n//sys\tEpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT\n//sys\tFadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64\n//sys\tFchown(fd int, uid int, gid int) (err error)\n//sys\tFstat(fd int, stat *Stat_t) (err error)\n//sys\tFstatat(fd int, path string, stat *Stat_t, flags int) (err error)\n//sys\tFstatfs(fd int, buf *Statfs_t) (err error)\n//sys\tFtruncate(fd int, length int64) (err error)\n//sysnb\tGetegid() (egid int)\n//sysnb\tGeteuid() (euid int)\n//sysnb\tGetgid() (gid int)\n//sysnb\tGetrlimit(resource int, rlim *Rlimit) (err error)\n//sysnb\tGetuid() (uid int)\n//sys\tListen(s int, n int) (err error)\n//sys\tMemfdSecret(flags int) (fd int, err error)\n//sys\tpread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64\n//sys\tpwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64\n//sys\tSeek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK\n\nfunc Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {\n\tvar ts *Timespec\n\tif timeout != nil {\n\t\tts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000}\n\t}\n\treturn pselect6(nfd, r, w, e, ts, nil)\n}\n\n//sys\tsendfile(outfd int, infd int, offset *int64, count int) (written int, err error)\n//sys\tsetfsgid(gid int) (prev int, err error)\n//sys\tsetfsuid(uid int) (prev int, err error)\n//sys\tShutdown(fd int, how int) (err error)\n//sys\tSplice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)\n\nfunc Stat(path string, stat *Stat_t) (err error) {\n\treturn Fstatat(AT_FDCWD, path, stat, 0)\n}\n\nfunc Lchown(path string, uid int, gid int) (err error) {\n\treturn Fchownat(AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW)\n}\n\nfunc Lstat(path string, stat *Stat_t) (err error) {\n\treturn Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW)\n}\n\n//sys\tStatfs(path string, buf *Statfs_t) (err error)\n//sys\tSyncFileRange(fd int, off int64, n int64, flags int) (err error)\n//sys\tTruncate(path string, length int64) (err error)\n\nfunc Ustat(dev int, ubuf *Ustat_t) (err error) {\n\treturn ENOSYS\n}\n\n//sys\taccept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)\n//sys\tbind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\tconnect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)\n//sysnb\tgetgroups(n int, list *_Gid_t) (nn int, err error)\n//sysnb\tsetgroups(n int, list *_Gid_t) (err error)\n//sys\tgetsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)\n//sys\tsetsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)\n//sysnb\tsocket(domain int, typ int, proto int) (fd int, err error)\n//sysnb\tsocketpair(domain int, typ int, proto int, fd *[2]int32) (err error)\n//sysnb\tgetpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sysnb\tgetsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)\n//sys\trecvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)\n//sys\tsendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)\n//sys\trecvmsg(s int, msg *Msghdr, flags int) (n int, err error)\n//sys\tsendmsg(s int, msg *Msghdr, flags int) (n int, err error)\n//sys\tmmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)\n\n//sysnb\tGettimeofday(tv *Timeval) (err error)\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: usec}\n}\n\nfunc futimesat(dirfd int, path string, tv *[2]Timeval) (err error) {\n\tif tv == nil {\n\t\treturn utimensat(dirfd, path, nil, 0)\n\t}\n\n\tts := []Timespec{\n\t\tNsecToTimespec(TimevalToNsec(tv[0])),\n\t\tNsecToTimespec(TimevalToNsec(tv[1])),\n\t}\n\treturn utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)\n}\n\nfunc Time(t *Time_t) (Time_t, error) {\n\tvar tv Timeval\n\terr := Gettimeofday(&tv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif t != nil {\n\t\t*t = Time_t(tv.Sec)\n\t}\n\treturn Time_t(tv.Sec), nil\n}\n\nfunc Utime(path string, buf *Utimbuf) error {\n\ttv := []Timeval{\n\t\t{Sec: buf.Actime},\n\t\t{Sec: buf.Modtime},\n\t}\n\treturn Utimes(path, tv)\n}\n\nfunc utimes(path string, tv *[2]Timeval) (err error) {\n\tif tv == nil {\n\t\treturn utimensat(AT_FDCWD, path, nil, 0)\n\t}\n\n\tts := []Timespec{\n\t\tNsecToTimespec(TimevalToNsec(tv[0])),\n\t\tNsecToTimespec(TimevalToNsec(tv[1])),\n\t}\n\treturn utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)\n}\n\nfunc (r *PtraceRegs) PC() uint64 { return r.Pc }\n\nfunc (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc }\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = uint64(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint64(length)\n}\n\nfunc (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {\n\trsa.Service_name_len = uint64(length)\n}\n\nfunc Pause() error {\n\t_, err := ppoll(nil, 0, nil, nil)\n\treturn err\n}\n\nfunc Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {\n\treturn Renameat2(olddirfd, oldpath, newdirfd, newpath, 0)\n}\n\n//sys\tkexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)\n\nfunc KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {\n\tcmdlineLen := len(cmdline)\n\tif cmdlineLen > 0 {\n\t\t// Account for the additional NULL byte added by\n\t\t// BytePtrFromString in kexecFileLoad. The kexec_file_load\n\t\t// syscall expects a NULL-terminated string.\n\t\tcmdlineLen++\n\t}\n\treturn kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)\n}\n\n//sys\triscvHWProbe(pairs []RISCVHWProbePairs, cpuCount uintptr, cpus *CPUSet, flags uint) (err error)\n\nfunc RISCVHWProbe(pairs []RISCVHWProbePairs, set *CPUSet, flags uint) (err error) {\n\tvar setSize uintptr\n\n\tif set != nil {\n\t\tsetSize = uintptr(unsafe.Sizeof(*set))\n\t}\n\treturn riscvHWProbe(pairs, setSize, set, flags)\n}\n\nconst SYS_FSTATAT = SYS_NEWFSTATAT\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_linux_s390x.go",
    "content": "// Copyright 2016 The Go 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\n//go:build s390x && linux\n\npackage unix\n\nimport (\n\t\"unsafe\"\n)\n\n//sys\tEpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)\n//sys\tFadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64\n//sys\tFchown(fd int, uid int, gid int) (err error)\n//sys\tFstat(fd int, stat *Stat_t) (err error)\n//sys\tFstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT\n//sys\tFstatfs(fd int, buf *Statfs_t) (err error)\n//sys\tFtruncate(fd int, length int64) (err error)\n//sysnb\tGetegid() (egid int)\n//sysnb\tGeteuid() (euid int)\n//sysnb\tGetgid() (gid int)\n//sysnb\tGetrlimit(resource int, rlim *Rlimit) (err error)\n//sysnb\tGetuid() (uid int)\n//sys\tLchown(path string, uid int, gid int) (err error)\n//sys\tLstat(path string, stat *Stat_t) (err error)\n//sys\tPause() (err error)\n//sys\tpread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64\n//sys\tpwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64\n//sys\tRenameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)\n//sys\tSeek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK\n//sys\tSelect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)\n//sys\tsendfile(outfd int, infd int, offset *int64, count int) (written int, err error)\n//sys\tsetfsgid(gid int) (prev int, err error)\n//sys\tsetfsuid(uid int) (prev int, err error)\n//sys\tSplice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)\n//sys\tStat(path string, stat *Stat_t) (err error)\n//sys\tStatfs(path string, buf *Statfs_t) (err error)\n//sys\tSyncFileRange(fd int, off int64, n int64, flags int) (err error)\n//sys\tTruncate(path string, length int64) (err error)\n//sys\tUstat(dev int, ubuf *Ustat_t) (err error)\n//sysnb\tgetgroups(n int, list *_Gid_t) (nn int, err error)\n//sysnb\tsetgroups(n int, list *_Gid_t) (err error)\n\n//sys\tfutimesat(dirfd int, path string, times *[2]Timeval) (err error)\n//sysnb\tGettimeofday(tv *Timeval) (err error)\n\nfunc Time(t *Time_t) (tt Time_t, err error) {\n\tvar tv Timeval\n\terr = Gettimeofday(&tv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif t != nil {\n\t\t*t = Time_t(tv.Sec)\n\t}\n\treturn Time_t(tv.Sec), nil\n}\n\n//sys\tUtime(path string, buf *Utimbuf) (err error)\n//sys\tutimes(path string, times *[2]Timeval) (err error)\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: usec}\n}\n\nfunc Ioperm(from int, num int, on int) (err error) {\n\treturn ENOSYS\n}\n\nfunc Iopl(level int) (err error) {\n\treturn ENOSYS\n}\n\nfunc (r *PtraceRegs) PC() uint64 { return r.Psw.Addr }\n\nfunc (r *PtraceRegs) SetPC(pc uint64) { r.Psw.Addr = pc }\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = uint64(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint64(length)\n}\n\nfunc (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {\n\trsa.Service_name_len = uint64(length)\n}\n\n// Linux on s390x uses the old mmap interface, which requires arguments to be passed in a struct.\n// mmap2 also requires arguments to be passed in a struct; it is currently not exposed in <asm/unistd.h>.\nfunc mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {\n\tmmap_args := [6]uintptr{addr, length, uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset)}\n\tr0, _, e1 := Syscall(SYS_MMAP, uintptr(unsafe.Pointer(&mmap_args[0])), 0, 0)\n\txaddr = uintptr(r0)\n\tif e1 != 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\n// On s390x Linux, all the socket calls go through an extra indirection.\n// The arguments to the underlying system call (SYS_SOCKETCALL) are the\n// number below and a pointer to an array of uintptr.\nconst (\n\t// see linux/net.h\n\tnetSocket      = 1\n\tnetBind        = 2\n\tnetConnect     = 3\n\tnetListen      = 4\n\tnetAccept      = 5\n\tnetGetSockName = 6\n\tnetGetPeerName = 7\n\tnetSocketPair  = 8\n\tnetSend        = 9\n\tnetRecv        = 10\n\tnetSendTo      = 11\n\tnetRecvFrom    = 12\n\tnetShutdown    = 13\n\tnetSetSockOpt  = 14\n\tnetGetSockOpt  = 15\n\tnetSendMsg     = 16\n\tnetRecvMsg     = 17\n\tnetAccept4     = 18\n\tnetRecvMMsg    = 19\n\tnetSendMMsg    = 20\n)\n\nfunc accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (int, error) {\n\targs := [4]uintptr{uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags)}\n\tfd, _, err := Syscall(SYS_SOCKETCALL, netAccept4, uintptr(unsafe.Pointer(&args)), 0)\n\tif err != 0 {\n\t\treturn 0, err\n\t}\n\treturn int(fd), nil\n}\n\nfunc getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) error {\n\targs := [3]uintptr{uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))}\n\t_, _, err := RawSyscall(SYS_SOCKETCALL, netGetSockName, uintptr(unsafe.Pointer(&args)), 0)\n\tif err != 0 {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) error {\n\targs := [3]uintptr{uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))}\n\t_, _, err := RawSyscall(SYS_SOCKETCALL, netGetPeerName, uintptr(unsafe.Pointer(&args)), 0)\n\tif err != 0 {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc socketpair(domain int, typ int, flags int, fd *[2]int32) error {\n\targs := [4]uintptr{uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd))}\n\t_, _, err := RawSyscall(SYS_SOCKETCALL, netSocketPair, uintptr(unsafe.Pointer(&args)), 0)\n\tif err != 0 {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc bind(s int, addr unsafe.Pointer, addrlen _Socklen) error {\n\targs := [3]uintptr{uintptr(s), uintptr(addr), uintptr(addrlen)}\n\t_, _, err := Syscall(SYS_SOCKETCALL, netBind, uintptr(unsafe.Pointer(&args)), 0)\n\tif err != 0 {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc connect(s int, addr unsafe.Pointer, addrlen _Socklen) error {\n\targs := [3]uintptr{uintptr(s), uintptr(addr), uintptr(addrlen)}\n\t_, _, err := Syscall(SYS_SOCKETCALL, netConnect, uintptr(unsafe.Pointer(&args)), 0)\n\tif err != 0 {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc socket(domain int, typ int, proto int) (int, error) {\n\targs := [3]uintptr{uintptr(domain), uintptr(typ), uintptr(proto)}\n\tfd, _, err := RawSyscall(SYS_SOCKETCALL, netSocket, uintptr(unsafe.Pointer(&args)), 0)\n\tif err != 0 {\n\t\treturn 0, err\n\t}\n\treturn int(fd), nil\n}\n\nfunc getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) error {\n\targs := [5]uintptr{uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen))}\n\t_, _, err := Syscall(SYS_SOCKETCALL, netGetSockOpt, uintptr(unsafe.Pointer(&args)), 0)\n\tif err != 0 {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) error {\n\targs := [5]uintptr{uintptr(s), uintptr(level), uintptr(name), uintptr(val), vallen}\n\t_, _, err := Syscall(SYS_SOCKETCALL, netSetSockOpt, uintptr(unsafe.Pointer(&args)), 0)\n\tif err != 0 {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc recvfrom(s int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (int, error) {\n\tvar base uintptr\n\tif len(p) > 0 {\n\t\tbase = uintptr(unsafe.Pointer(&p[0]))\n\t}\n\targs := [6]uintptr{uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))}\n\tn, _, err := Syscall(SYS_SOCKETCALL, netRecvFrom, uintptr(unsafe.Pointer(&args)), 0)\n\tif err != 0 {\n\t\treturn 0, err\n\t}\n\treturn int(n), nil\n}\n\nfunc sendto(s int, p []byte, flags int, to unsafe.Pointer, addrlen _Socklen) error {\n\tvar base uintptr\n\tif len(p) > 0 {\n\t\tbase = uintptr(unsafe.Pointer(&p[0]))\n\t}\n\targs := [6]uintptr{uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(to), uintptr(addrlen)}\n\t_, _, err := Syscall(SYS_SOCKETCALL, netSendTo, uintptr(unsafe.Pointer(&args)), 0)\n\tif err != 0 {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc recvmsg(s int, msg *Msghdr, flags int) (int, error) {\n\targs := [3]uintptr{uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)}\n\tn, _, err := Syscall(SYS_SOCKETCALL, netRecvMsg, uintptr(unsafe.Pointer(&args)), 0)\n\tif err != 0 {\n\t\treturn 0, err\n\t}\n\treturn int(n), nil\n}\n\nfunc sendmsg(s int, msg *Msghdr, flags int) (int, error) {\n\targs := [3]uintptr{uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)}\n\tn, _, err := Syscall(SYS_SOCKETCALL, netSendMsg, uintptr(unsafe.Pointer(&args)), 0)\n\tif err != 0 {\n\t\treturn 0, err\n\t}\n\treturn int(n), nil\n}\n\nfunc Listen(s int, n int) error {\n\targs := [2]uintptr{uintptr(s), uintptr(n)}\n\t_, _, err := Syscall(SYS_SOCKETCALL, netListen, uintptr(unsafe.Pointer(&args)), 0)\n\tif err != 0 {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc Shutdown(s, how int) error {\n\targs := [2]uintptr{uintptr(s), uintptr(how)}\n\t_, _, err := Syscall(SYS_SOCKETCALL, netShutdown, uintptr(unsafe.Pointer(&args)), 0)\n\tif err != 0 {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n//sys\tkexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)\n\nfunc KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {\n\tcmdlineLen := len(cmdline)\n\tif cmdlineLen > 0 {\n\t\t// Account for the additional NULL byte added by\n\t\t// BytePtrFromString in kexecFileLoad. The kexec_file_load\n\t\t// syscall expects a NULL-terminated string.\n\t\tcmdlineLen++\n\t}\n\treturn kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_netbsd.go",
    "content": "// Copyright 2009,2010 The Go 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\n// NetBSD system calls.\n// This file is compiled as ordinary Go code,\n// but it is also input to mksyscall,\n// which parses the //sys lines and generates system call stubs.\n// Note that sometimes we use a lowercase //sys name and wrap\n// it in our own nicer implementation, either here or in\n// syscall_bsd.go or syscall_unix.go.\n\npackage unix\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.\ntype SockaddrDatalink struct {\n\tLen    uint8\n\tFamily uint8\n\tIndex  uint16\n\tType   uint8\n\tNlen   uint8\n\tAlen   uint8\n\tSlen   uint8\n\tData   [12]int8\n\traw    RawSockaddrDatalink\n}\n\nfunc anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {\n\treturn nil, EAFNOSUPPORT\n}\n\nfunc Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)\n\nfunc sysctlNodes(mib []_C_int) (nodes []Sysctlnode, err error) {\n\tvar olen uintptr\n\n\t// Get a list of all sysctl nodes below the given MIB by performing\n\t// a sysctl for the given MIB with CTL_QUERY appended.\n\tmib = append(mib, CTL_QUERY)\n\tqnode := Sysctlnode{Flags: SYSCTL_VERS_1}\n\tqp := (*byte)(unsafe.Pointer(&qnode))\n\tsz := unsafe.Sizeof(qnode)\n\tif err = sysctl(mib, nil, &olen, qp, sz); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Now that we know the size, get the actual nodes.\n\tnodes = make([]Sysctlnode, olen/sz)\n\tnp := (*byte)(unsafe.Pointer(&nodes[0]))\n\tif err = sysctl(mib, np, &olen, qp, sz); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn nodes, nil\n}\n\nfunc nametomib(name string) (mib []_C_int, err error) {\n\t// Split name into components.\n\tvar parts []string\n\tlast := 0\n\tfor i := 0; i < len(name); i++ {\n\t\tif name[i] == '.' {\n\t\t\tparts = append(parts, name[last:i])\n\t\t\tlast = i + 1\n\t\t}\n\t}\n\tparts = append(parts, name[last:])\n\n\t// Discover the nodes and construct the MIB OID.\n\tfor partno, part := range parts {\n\t\tnodes, err := sysctlNodes(mib)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfor _, node := range nodes {\n\t\t\tn := make([]byte, 0)\n\t\t\tfor i := range node.Name {\n\t\t\t\tif node.Name[i] != 0 {\n\t\t\t\t\tn = append(n, byte(node.Name[i]))\n\t\t\t\t}\n\t\t\t}\n\t\t\tif string(n) == part {\n\t\t\t\tmib = append(mib, _C_int(node.Num))\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif len(mib) != partno+1 {\n\t\t\treturn nil, EINVAL\n\t\t}\n\t}\n\n\treturn mib, nil\n}\n\nfunc direntIno(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))\n}\n\nfunc direntReclen(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))\n}\n\nfunc direntNamlen(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))\n}\n\nfunc SysctlUvmexp(name string) (*Uvmexp, error) {\n\tmib, err := sysctlmib(name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tn := uintptr(SizeofUvmexp)\n\tvar u Uvmexp\n\tif err := sysctl(mib, (*byte)(unsafe.Pointer(&u)), &n, nil, 0); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &u, nil\n}\n\nfunc Pipe(p []int) (err error) {\n\treturn Pipe2(p, 0)\n}\n\n//sysnb\tpipe2(p *[2]_C_int, flags int) (err error)\n\nfunc Pipe2(p []int, flags int) error {\n\tif len(p) != 2 {\n\t\treturn EINVAL\n\t}\n\tvar pp [2]_C_int\n\terr := pipe2(&pp, flags)\n\tif err == nil {\n\t\tp[0] = int(pp[0])\n\t\tp[1] = int(pp[1])\n\t}\n\treturn err\n}\n\n//sys\tGetdents(fd int, buf []byte) (n int, err error)\n\nfunc Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {\n\tn, err = Getdents(fd, buf)\n\tif err != nil || basep == nil {\n\t\treturn\n\t}\n\n\tvar off int64\n\toff, err = Seek(fd, 0, 1 /* SEEK_CUR */)\n\tif err != nil {\n\t\t*basep = ^uintptr(0)\n\t\treturn\n\t}\n\t*basep = uintptr(off)\n\tif unsafe.Sizeof(*basep) == 8 {\n\t\treturn\n\t}\n\tif off>>32 != 0 {\n\t\t// We can't stuff the offset back into a uintptr, so any\n\t\t// future calls would be suspect. Generate an error.\n\t\t// EIO is allowed by getdirentries.\n\t\terr = EIO\n\t}\n\treturn\n}\n\n//sys\tGetcwd(buf []byte) (n int, err error) = SYS___GETCWD\n\n// TODO\nfunc sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\treturn -1, ENOSYS\n}\n\n//sys\tioctl(fd int, req uint, arg uintptr) (err error)\n//sys\tioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL\n\n//sys\tsysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL\n\nfunc IoctlGetPtmget(fd int, req uint) (*Ptmget, error) {\n\tvar value Ptmget\n\terr := ioctlPtr(fd, req, unsafe.Pointer(&value))\n\treturn &value, err\n}\n\nfunc Uname(uname *Utsname) error {\n\tmib := []_C_int{CTL_KERN, KERN_OSTYPE}\n\tn := unsafe.Sizeof(uname.Sysname)\n\tif err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {\n\t\treturn err\n\t}\n\n\tmib = []_C_int{CTL_KERN, KERN_HOSTNAME}\n\tn = unsafe.Sizeof(uname.Nodename)\n\tif err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil {\n\t\treturn err\n\t}\n\n\tmib = []_C_int{CTL_KERN, KERN_OSRELEASE}\n\tn = unsafe.Sizeof(uname.Release)\n\tif err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil {\n\t\treturn err\n\t}\n\n\tmib = []_C_int{CTL_KERN, KERN_VERSION}\n\tn = unsafe.Sizeof(uname.Version)\n\tif err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {\n\t\treturn err\n\t}\n\n\t// The version might have newlines or tabs in it, convert them to\n\t// spaces.\n\tfor i, b := range uname.Version {\n\t\tif b == '\\n' || b == '\\t' {\n\t\t\tif i == len(uname.Version)-1 {\n\t\t\t\tuname.Version[i] = 0\n\t\t\t} else {\n\t\t\t\tuname.Version[i] = ' '\n\t\t\t}\n\t\t}\n\t}\n\n\tmib = []_C_int{CTL_HW, HW_MACHINE}\n\tn = unsafe.Sizeof(uname.Machine)\n\tif err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\tif raceenabled {\n\t\traceReleaseMerge(unsafe.Pointer(&ioSync))\n\t}\n\treturn sendfile(outfd, infd, offset, count)\n}\n\nfunc Fstatvfs(fd int, buf *Statvfs_t) (err error) {\n\treturn Fstatvfs1(fd, buf, ST_WAIT)\n}\n\nfunc Statvfs(path string, buf *Statvfs_t) (err error) {\n\treturn Statvfs1(path, buf, ST_WAIT)\n}\n\nfunc Getvfsstat(buf []Statvfs_t, flags int) (n int, err error) {\n\tvar (\n\t\t_p0     unsafe.Pointer\n\t\tbufsize uintptr\n\t)\n\tif len(buf) > 0 {\n\t\t_p0 = unsafe.Pointer(&buf[0])\n\t\tbufsize = unsafe.Sizeof(Statvfs_t{}) * uintptr(len(buf))\n\t}\n\tr0, _, e1 := Syscall(SYS_GETVFSSTAT, uintptr(_p0), bufsize, uintptr(flags))\n\tn = int(r0)\n\tif e1 != 0 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n/*\n * Exposed directly\n */\n//sys\tAccess(path string, mode uint32) (err error)\n//sys\tAdjtime(delta *Timeval, olddelta *Timeval) (err error)\n//sys\tChdir(path string) (err error)\n//sys\tChflags(path string, flags int) (err error)\n//sys\tChmod(path string, mode uint32) (err error)\n//sys\tChown(path string, uid int, gid int) (err error)\n//sys\tChroot(path string) (err error)\n//sys\tClockGettime(clockid int32, time *Timespec) (err error)\n//sys\tClose(fd int) (err error)\n//sys\tDup(fd int) (nfd int, err error)\n//sys\tDup2(from int, to int) (err error)\n//sys\tDup3(from int, to int, flags int) (err error)\n//sys\tExit(code int)\n//sys\tExtattrGetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)\n//sys\tExtattrSetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)\n//sys\tExtattrDeleteFd(fd int, attrnamespace int, attrname string) (err error)\n//sys\tExtattrListFd(fd int, attrnamespace int, data uintptr, nbytes int) (ret int, err error)\n//sys\tExtattrGetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)\n//sys\tExtattrSetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)\n//sys\tExtattrDeleteFile(file string, attrnamespace int, attrname string) (err error)\n//sys\tExtattrListFile(file string, attrnamespace int, data uintptr, nbytes int) (ret int, err error)\n//sys\tExtattrGetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)\n//sys\tExtattrSetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error)\n//sys\tExtattrDeleteLink(link string, attrnamespace int, attrname string) (err error)\n//sys\tExtattrListLink(link string, attrnamespace int, data uintptr, nbytes int) (ret int, err error)\n//sys\tFaccessat(dirfd int, path string, mode uint32, flags int) (err error)\n//sys\tFadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_POSIX_FADVISE\n//sys\tFchdir(fd int) (err error)\n//sys\tFchflags(fd int, flags int) (err error)\n//sys\tFchmod(fd int, mode uint32) (err error)\n//sys\tFchmodat(dirfd int, path string, mode uint32, flags int) (err error)\n//sys\tFchown(fd int, uid int, gid int) (err error)\n//sys\tFchownat(dirfd int, path string, uid int, gid int, flags int) (err error)\n//sys\tFlock(fd int, how int) (err error)\n//sys\tFpathconf(fd int, name int) (val int, err error)\n//sys\tFstat(fd int, stat *Stat_t) (err error)\n//sys\tFstatat(fd int, path string, stat *Stat_t, flags int) (err error)\n//sys\tFstatvfs1(fd int, buf *Statvfs_t, flags int) (err error) = SYS_FSTATVFS1\n//sys\tFsync(fd int) (err error)\n//sys\tFtruncate(fd int, length int64) (err error)\n//sysnb\tGetegid() (egid int)\n//sysnb\tGeteuid() (uid int)\n//sysnb\tGetgid() (gid int)\n//sysnb\tGetpgid(pid int) (pgid int, err error)\n//sysnb\tGetpgrp() (pgrp int)\n//sysnb\tGetpid() (pid int)\n//sysnb\tGetppid() (ppid int)\n//sys\tGetpriority(which int, who int) (prio int, err error)\n//sysnb\tGetrlimit(which int, lim *Rlimit) (err error)\n//sysnb\tGetrusage(who int, rusage *Rusage) (err error)\n//sysnb\tGetsid(pid int) (sid int, err error)\n//sysnb\tGettimeofday(tv *Timeval) (err error)\n//sysnb\tGetuid() (uid int)\n//sys\tIssetugid() (tainted bool)\n//sys\tKill(pid int, signum syscall.Signal) (err error)\n//sys\tKqueue() (fd int, err error)\n//sys\tLchown(path string, uid int, gid int) (err error)\n//sys\tLink(path string, link string) (err error)\n//sys\tLinkat(pathfd int, path string, linkfd int, link string, flags int) (err error)\n//sys\tListen(s int, backlog int) (err error)\n//sys\tLstat(path string, stat *Stat_t) (err error)\n//sys\tMkdir(path string, mode uint32) (err error)\n//sys\tMkdirat(dirfd int, path string, mode uint32) (err error)\n//sys\tMkfifo(path string, mode uint32) (err error)\n//sys\tMkfifoat(dirfd int, path string, mode uint32) (err error)\n//sys\tMknod(path string, mode uint32, dev int) (err error)\n//sys\tMknodat(dirfd int, path string, mode uint32, dev int) (err error)\n//sys\tNanosleep(time *Timespec, leftover *Timespec) (err error)\n//sys\tOpen(path string, mode int, perm uint32) (fd int, err error)\n//sys\tOpenat(dirfd int, path string, mode int, perm uint32) (fd int, err error)\n//sys\tPathconf(path string, name int) (val int, err error)\n//sys\tpread(fd int, p []byte, offset int64) (n int, err error)\n//sys\tpwrite(fd int, p []byte, offset int64) (n int, err error)\n//sys\tread(fd int, p []byte) (n int, err error)\n//sys\tReadlink(path string, buf []byte) (n int, err error)\n//sys\tReadlinkat(dirfd int, path string, buf []byte) (n int, err error)\n//sys\tRename(from string, to string) (err error)\n//sys\tRenameat(fromfd int, from string, tofd int, to string) (err error)\n//sys\tRevoke(path string) (err error)\n//sys\tRmdir(path string) (err error)\n//sys\tSeek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK\n//sys\tSelect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)\n//sysnb\tSetegid(egid int) (err error)\n//sysnb\tSeteuid(euid int) (err error)\n//sysnb\tSetgid(gid int) (err error)\n//sysnb\tSetpgid(pid int, pgid int) (err error)\n//sys\tSetpriority(which int, who int, prio int) (err error)\n//sysnb\tSetregid(rgid int, egid int) (err error)\n//sysnb\tSetreuid(ruid int, euid int) (err error)\n//sysnb\tSetsid() (pid int, err error)\n//sysnb\tSettimeofday(tp *Timeval) (err error)\n//sysnb\tSetuid(uid int) (err error)\n//sys\tStat(path string, stat *Stat_t) (err error)\n//sys\tStatvfs1(path string, buf *Statvfs_t, flags int) (err error) = SYS_STATVFS1\n//sys\tSymlink(path string, link string) (err error)\n//sys\tSymlinkat(oldpath string, newdirfd int, newpath string) (err error)\n//sys\tSync() (err error)\n//sys\tTruncate(path string, length int64) (err error)\n//sys\tUmask(newmask int) (oldmask int)\n//sys\tUnlink(path string) (err error)\n//sys\tUnlinkat(dirfd int, path string, flags int) (err error)\n//sys\tUnmount(path string, flags int) (err error)\n//sys\twrite(fd int, p []byte) (n int, err error)\n//sys\tmmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)\n//sys\tmunmap(addr uintptr, length uintptr) (err error)\n//sys\tutimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)\n\nconst (\n\tmremapFixed     = MAP_FIXED\n\tmremapDontunmap = 0\n\tmremapMaymove   = 0\n)\n\n//sys\tmremapNetBSD(oldp uintptr, oldsize uintptr, newp uintptr, newsize uintptr, flags int) (xaddr uintptr, err error) = SYS_MREMAP\n\nfunc mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (uintptr, error) {\n\treturn mremapNetBSD(oldaddr, oldlength, newaddr, newlength, flags)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_netbsd_386.go",
    "content": "// Copyright 2009 The Go 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\n//go:build 386 && netbsd\n\npackage unix\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: int32(nsec)}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: int32(usec)}\n}\n\nfunc SetKevent(k *Kevent_t, fd, mode, flags int) {\n\tk.Ident = uint32(fd)\n\tk.Filter = uint32(mode)\n\tk.Flags = uint32(flags)\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = int32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_netbsd_amd64.go",
    "content": "// Copyright 2009 The Go 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\n//go:build amd64 && netbsd\n\npackage unix\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: int32(usec)}\n}\n\nfunc SetKevent(k *Kevent_t, fd, mode, flags int) {\n\tk.Ident = uint64(fd)\n\tk.Filter = uint32(mode)\n\tk.Flags = uint32(flags)\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = int32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_netbsd_arm.go",
    "content": "// Copyright 2013 The Go 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\n//go:build arm && netbsd\n\npackage unix\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: int32(nsec)}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: int32(usec)}\n}\n\nfunc SetKevent(k *Kevent_t, fd, mode, flags int) {\n\tk.Ident = uint32(fd)\n\tk.Filter = uint32(mode)\n\tk.Flags = uint32(flags)\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = int32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_openbsd.go",
    "content": "// Copyright 2009,2010 The Go 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\n// OpenBSD system calls.\n// This file is compiled as ordinary Go code,\n// but it is also input to mksyscall,\n// which parses the //sys lines and generates system call stubs.\n// Note that sometimes we use a lowercase //sys name and wrap\n// it in our own nicer implementation, either here or in\n// syscall_bsd.go or syscall_unix.go.\n\npackage unix\n\nimport (\n\t\"sort\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n// SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.\ntype SockaddrDatalink struct {\n\tLen    uint8\n\tFamily uint8\n\tIndex  uint16\n\tType   uint8\n\tNlen   uint8\n\tAlen   uint8\n\tSlen   uint8\n\tData   [24]int8\n\traw    RawSockaddrDatalink\n}\n\nfunc anyToSockaddrGOOS(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {\n\treturn nil, EAFNOSUPPORT\n}\n\nfunc Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)\n\nfunc nametomib(name string) (mib []_C_int, err error) {\n\ti := sort.Search(len(sysctlMib), func(i int) bool {\n\t\treturn sysctlMib[i].ctlname >= name\n\t})\n\tif i < len(sysctlMib) && sysctlMib[i].ctlname == name {\n\t\treturn sysctlMib[i].ctloid, nil\n\t}\n\treturn nil, EINVAL\n}\n\nfunc direntIno(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))\n}\n\nfunc direntReclen(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))\n}\n\nfunc direntNamlen(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))\n}\n\nfunc SysctlUvmexp(name string) (*Uvmexp, error) {\n\tmib, err := sysctlmib(name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tn := uintptr(SizeofUvmexp)\n\tvar u Uvmexp\n\tif err := sysctl(mib, (*byte)(unsafe.Pointer(&u)), &n, nil, 0); err != nil {\n\t\treturn nil, err\n\t}\n\tif n != SizeofUvmexp {\n\t\treturn nil, EIO\n\t}\n\treturn &u, nil\n}\n\nfunc Pipe(p []int) (err error) {\n\treturn Pipe2(p, 0)\n}\n\n//sysnb\tpipe2(p *[2]_C_int, flags int) (err error)\n\nfunc Pipe2(p []int, flags int) error {\n\tif len(p) != 2 {\n\t\treturn EINVAL\n\t}\n\tvar pp [2]_C_int\n\terr := pipe2(&pp, flags)\n\tif err == nil {\n\t\tp[0] = int(pp[0])\n\t\tp[1] = int(pp[1])\n\t}\n\treturn err\n}\n\n//sys\tGetdents(fd int, buf []byte) (n int, err error)\n\nfunc Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {\n\tn, err = Getdents(fd, buf)\n\tif err != nil || basep == nil {\n\t\treturn\n\t}\n\n\tvar off int64\n\toff, err = Seek(fd, 0, 1 /* SEEK_CUR */)\n\tif err != nil {\n\t\t*basep = ^uintptr(0)\n\t\treturn\n\t}\n\t*basep = uintptr(off)\n\tif unsafe.Sizeof(*basep) == 8 {\n\t\treturn\n\t}\n\tif off>>32 != 0 {\n\t\t// We can't stuff the offset back into a uintptr, so any\n\t\t// future calls would be suspect. Generate an error.\n\t\t// EIO was allowed by getdirentries.\n\t\terr = EIO\n\t}\n\treturn\n}\n\n//sys\tGetcwd(buf []byte) (n int, err error) = SYS___GETCWD\n\nfunc Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\tif raceenabled {\n\t\traceReleaseMerge(unsafe.Pointer(&ioSync))\n\t}\n\treturn sendfile(outfd, infd, offset, count)\n}\n\n// TODO\nfunc sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\treturn -1, ENOSYS\n}\n\nfunc Getfsstat(buf []Statfs_t, flags int) (n int, err error) {\n\tvar bufptr *Statfs_t\n\tvar bufsize uintptr\n\tif len(buf) > 0 {\n\t\tbufptr = &buf[0]\n\t\tbufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))\n\t}\n\treturn getfsstat(bufptr, bufsize, flags)\n}\n\n//sysnb\tgetresuid(ruid *_C_int, euid *_C_int, suid *_C_int)\n//sysnb\tgetresgid(rgid *_C_int, egid *_C_int, sgid *_C_int)\n\nfunc Getresuid() (ruid, euid, suid int) {\n\tvar r, e, s _C_int\n\tgetresuid(&r, &e, &s)\n\treturn int(r), int(e), int(s)\n}\n\nfunc Getresgid() (rgid, egid, sgid int) {\n\tvar r, e, s _C_int\n\tgetresgid(&r, &e, &s)\n\treturn int(r), int(e), int(s)\n}\n\n//sys\tioctl(fd int, req uint, arg uintptr) (err error)\n//sys\tioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL\n\n//sys\tsysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL\n\n//sys\tfcntl(fd int, cmd int, arg int) (n int, err error)\n//sys\tfcntlPtr(fd int, cmd int, arg unsafe.Pointer) (n int, err error) = SYS_FCNTL\n\n// FcntlInt performs a fcntl syscall on fd with the provided command and argument.\nfunc FcntlInt(fd uintptr, cmd, arg int) (int, error) {\n\treturn fcntl(int(fd), cmd, arg)\n}\n\n// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.\nfunc FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {\n\t_, err := fcntlPtr(int(fd), cmd, unsafe.Pointer(lk))\n\treturn err\n}\n\n//sys\tppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)\n\nfunc Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {\n\tif len(fds) == 0 {\n\t\treturn ppoll(nil, 0, timeout, sigmask)\n\t}\n\treturn ppoll(&fds[0], len(fds), timeout, sigmask)\n}\n\nfunc Uname(uname *Utsname) error {\n\tmib := []_C_int{CTL_KERN, KERN_OSTYPE}\n\tn := unsafe.Sizeof(uname.Sysname)\n\tif err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {\n\t\treturn err\n\t}\n\n\tmib = []_C_int{CTL_KERN, KERN_HOSTNAME}\n\tn = unsafe.Sizeof(uname.Nodename)\n\tif err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil {\n\t\treturn err\n\t}\n\n\tmib = []_C_int{CTL_KERN, KERN_OSRELEASE}\n\tn = unsafe.Sizeof(uname.Release)\n\tif err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil {\n\t\treturn err\n\t}\n\n\tmib = []_C_int{CTL_KERN, KERN_VERSION}\n\tn = unsafe.Sizeof(uname.Version)\n\tif err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {\n\t\treturn err\n\t}\n\n\t// The version might have newlines or tabs in it, convert them to\n\t// spaces.\n\tfor i, b := range uname.Version {\n\t\tif b == '\\n' || b == '\\t' {\n\t\t\tif i == len(uname.Version)-1 {\n\t\t\t\tuname.Version[i] = 0\n\t\t\t} else {\n\t\t\t\tuname.Version[i] = ' '\n\t\t\t}\n\t\t}\n\t}\n\n\tmib = []_C_int{CTL_HW, HW_MACHINE}\n\tn = unsafe.Sizeof(uname.Machine)\n\tif err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n/*\n * Exposed directly\n */\n//sys\tAccess(path string, mode uint32) (err error)\n//sys\tAdjtime(delta *Timeval, olddelta *Timeval) (err error)\n//sys\tChdir(path string) (err error)\n//sys\tChflags(path string, flags int) (err error)\n//sys\tChmod(path string, mode uint32) (err error)\n//sys\tChown(path string, uid int, gid int) (err error)\n//sys\tChroot(path string) (err error)\n//sys\tClockGettime(clockid int32, time *Timespec) (err error)\n//sys\tClose(fd int) (err error)\n//sys\tDup(fd int) (nfd int, err error)\n//sys\tDup2(from int, to int) (err error)\n//sys\tDup3(from int, to int, flags int) (err error)\n//sys\tExit(code int)\n//sys\tFaccessat(dirfd int, path string, mode uint32, flags int) (err error)\n//sys\tFchdir(fd int) (err error)\n//sys\tFchflags(fd int, flags int) (err error)\n//sys\tFchmod(fd int, mode uint32) (err error)\n//sys\tFchmodat(dirfd int, path string, mode uint32, flags int) (err error)\n//sys\tFchown(fd int, uid int, gid int) (err error)\n//sys\tFchownat(dirfd int, path string, uid int, gid int, flags int) (err error)\n//sys\tFlock(fd int, how int) (err error)\n//sys\tFpathconf(fd int, name int) (val int, err error)\n//sys\tFstat(fd int, stat *Stat_t) (err error)\n//sys\tFstatat(fd int, path string, stat *Stat_t, flags int) (err error)\n//sys\tFstatfs(fd int, stat *Statfs_t) (err error)\n//sys\tFsync(fd int) (err error)\n//sys\tFtruncate(fd int, length int64) (err error)\n//sysnb\tGetegid() (egid int)\n//sysnb\tGeteuid() (uid int)\n//sysnb\tGetgid() (gid int)\n//sysnb\tGetpgid(pid int) (pgid int, err error)\n//sysnb\tGetpgrp() (pgrp int)\n//sysnb\tGetpid() (pid int)\n//sysnb\tGetppid() (ppid int)\n//sys\tGetpriority(which int, who int) (prio int, err error)\n//sysnb\tGetrlimit(which int, lim *Rlimit) (err error)\n//sysnb\tGetrtable() (rtable int, err error)\n//sysnb\tGetrusage(who int, rusage *Rusage) (err error)\n//sysnb\tGetsid(pid int) (sid int, err error)\n//sysnb\tGettimeofday(tv *Timeval) (err error)\n//sysnb\tGetuid() (uid int)\n//sys\tIssetugid() (tainted bool)\n//sys\tKill(pid int, signum syscall.Signal) (err error)\n//sys\tKqueue() (fd int, err error)\n//sys\tLchown(path string, uid int, gid int) (err error)\n//sys\tLink(path string, link string) (err error)\n//sys\tLinkat(pathfd int, path string, linkfd int, link string, flags int) (err error)\n//sys\tListen(s int, backlog int) (err error)\n//sys\tLstat(path string, stat *Stat_t) (err error)\n//sys\tMkdir(path string, mode uint32) (err error)\n//sys\tMkdirat(dirfd int, path string, mode uint32) (err error)\n//sys\tMkfifo(path string, mode uint32) (err error)\n//sys\tMkfifoat(dirfd int, path string, mode uint32) (err error)\n//sys\tMknod(path string, mode uint32, dev int) (err error)\n//sys\tMknodat(dirfd int, path string, mode uint32, dev int) (err error)\n//sys\tMount(fsType string, dir string, flags int, data unsafe.Pointer) (err error)\n//sys\tNanosleep(time *Timespec, leftover *Timespec) (err error)\n//sys\tOpen(path string, mode int, perm uint32) (fd int, err error)\n//sys\tOpenat(dirfd int, path string, mode int, perm uint32) (fd int, err error)\n//sys\tPathconf(path string, name int) (val int, err error)\n//sys\tpread(fd int, p []byte, offset int64) (n int, err error)\n//sys\tpwrite(fd int, p []byte, offset int64) (n int, err error)\n//sys\tread(fd int, p []byte) (n int, err error)\n//sys\tReadlink(path string, buf []byte) (n int, err error)\n//sys\tReadlinkat(dirfd int, path string, buf []byte) (n int, err error)\n//sys\tRename(from string, to string) (err error)\n//sys\tRenameat(fromfd int, from string, tofd int, to string) (err error)\n//sys\tRevoke(path string) (err error)\n//sys\tRmdir(path string) (err error)\n//sys\tSeek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK\n//sys\tSelect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)\n//sysnb\tSetegid(egid int) (err error)\n//sysnb\tSeteuid(euid int) (err error)\n//sysnb\tSetgid(gid int) (err error)\n//sys\tSetlogin(name string) (err error)\n//sysnb\tSetpgid(pid int, pgid int) (err error)\n//sys\tSetpriority(which int, who int, prio int) (err error)\n//sysnb\tSetregid(rgid int, egid int) (err error)\n//sysnb\tSetreuid(ruid int, euid int) (err error)\n//sysnb\tSetresgid(rgid int, egid int, sgid int) (err error)\n//sysnb\tSetresuid(ruid int, euid int, suid int) (err error)\n//sysnb\tSetrtable(rtable int) (err error)\n//sysnb\tSetsid() (pid int, err error)\n//sysnb\tSettimeofday(tp *Timeval) (err error)\n//sysnb\tSetuid(uid int) (err error)\n//sys\tStat(path string, stat *Stat_t) (err error)\n//sys\tStatfs(path string, stat *Statfs_t) (err error)\n//sys\tSymlink(path string, link string) (err error)\n//sys\tSymlinkat(oldpath string, newdirfd int, newpath string) (err error)\n//sys\tSync() (err error)\n//sys\tTruncate(path string, length int64) (err error)\n//sys\tUmask(newmask int) (oldmask int)\n//sys\tUnlink(path string) (err error)\n//sys\tUnlinkat(dirfd int, path string, flags int) (err error)\n//sys\tUnmount(path string, flags int) (err error)\n//sys\twrite(fd int, p []byte) (n int, err error)\n//sys\tmmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)\n//sys\tmunmap(addr uintptr, length uintptr) (err error)\n//sys\tgetfsstat(stat *Statfs_t, bufsize uintptr, flags int) (n int, err error)\n//sys\tutimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)\n//sys\tpledge(promises *byte, execpromises *byte) (err error)\n//sys\tunveil(path *byte, flags *byte) (err error)\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_openbsd_386.go",
    "content": "// Copyright 2009 The Go 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\n//go:build 386 && openbsd\n\npackage unix\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: int32(nsec)}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: int32(usec)}\n}\n\nfunc SetKevent(k *Kevent_t, fd, mode, flags int) {\n\tk.Ident = uint32(fd)\n\tk.Filter = int16(mode)\n\tk.Flags = uint16(flags)\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = uint32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\n// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions\n// of openbsd/386 the syscall is called sysctl instead of __sysctl.\nconst SYS___SYSCTL = SYS_SYSCTL\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_openbsd_amd64.go",
    "content": "// Copyright 2009 The Go 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\n//go:build amd64 && openbsd\n\npackage unix\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: usec}\n}\n\nfunc SetKevent(k *Kevent_t, fd, mode, flags int) {\n\tk.Ident = uint64(fd)\n\tk.Filter = int16(mode)\n\tk.Flags = uint16(flags)\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = uint32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\n// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions\n// of openbsd/amd64 the syscall is called sysctl instead of __sysctl.\nconst SYS___SYSCTL = SYS_SYSCTL\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_openbsd_arm64.go",
    "content": "// Copyright 2019 The Go 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\n//go:build arm64 && openbsd\n\npackage unix\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: usec}\n}\n\nfunc SetKevent(k *Kevent_t, fd, mode, flags int) {\n\tk.Ident = uint64(fd)\n\tk.Filter = int16(mode)\n\tk.Flags = uint16(flags)\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = uint32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\n// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions\n// of openbsd/amd64 the syscall is called sysctl instead of __sysctl.\nconst SYS___SYSCTL = SYS_SYSCTL\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_openbsd_libc.go",
    "content": "// Copyright 2022 The Go 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\n//go:build openbsd\n\npackage unix\n\nimport _ \"unsafe\"\n\n// Implemented in the runtime package (runtime/sys_openbsd3.go)\nfunc syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)\nfunc syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)\nfunc syscall_syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2 uintptr, err Errno)\nfunc syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)\nfunc syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)\n\n//go:linkname syscall_syscall syscall.syscall\n//go:linkname syscall_syscall6 syscall.syscall6\n//go:linkname syscall_syscall10 syscall.syscall10\n//go:linkname syscall_rawSyscall syscall.rawSyscall\n//go:linkname syscall_rawSyscall6 syscall.rawSyscall6\n\nfunc syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) {\n\treturn syscall_syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, 0)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_openbsd_mips64.go",
    "content": "// Copyright 2019 The Go 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 unix\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: usec}\n}\n\nfunc SetKevent(k *Kevent_t, fd, mode, flags int) {\n\tk.Ident = uint64(fd)\n\tk.Filter = int16(mode)\n\tk.Flags = uint16(flags)\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = uint32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\n// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions\n// of OpenBSD the syscall is called sysctl instead of __sysctl.\nconst SYS___SYSCTL = SYS_SYSCTL\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_openbsd_ppc64.go",
    "content": "// Copyright 2019 The Go 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\n//go:build ppc64 && openbsd\n\npackage unix\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: usec}\n}\n\nfunc SetKevent(k *Kevent_t, fd, mode, flags int) {\n\tk.Ident = uint64(fd)\n\tk.Filter = int16(mode)\n\tk.Flags = uint16(flags)\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = uint32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\n// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions\n// of openbsd/ppc64 the syscall is called sysctl instead of __sysctl.\nconst SYS___SYSCTL = SYS_SYSCTL\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_openbsd_riscv64.go",
    "content": "// Copyright 2019 The Go 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\n//go:build riscv64 && openbsd\n\npackage unix\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval {\n\treturn Timeval{Sec: sec, Usec: usec}\n}\n\nfunc SetKevent(k *Kevent_t, fd, mode, flags int) {\n\tk.Ident = uint64(fd)\n\tk.Filter = int16(mode)\n\tk.Flags = uint16(flags)\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = uint32(length)\n}\n\nfunc (msghdr *Msghdr) SetIovlen(length int) {\n\tmsghdr.Iovlen = uint32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = uint32(length)\n}\n\n// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions\n// of openbsd/riscv64 the syscall is called sysctl instead of __sysctl.\nconst SYS___SYSCTL = SYS_SYSCTL\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/syscall_zos_s390x.go",
    "content": "// Copyright 2020 The Go 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\n//go:build zos && s390x\n\n// Many of the following syscalls are not available on all versions of z/OS.\n// Some missing calls have legacy implementations/simulations but others\n// will be missing completely. To achieve consistent failing behaviour on\n// legacy systems, we first test the function pointer via a safeloading\n// mechanism to see if the function exists on a given system. Then execution\n// is branched to either continue the function call, or return an error.\n\npackage unix\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"os\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n//go:noescape\nfunc initZosLibVec()\n\n//go:noescape\nfunc GetZosLibVec() uintptr\n\nfunc init() {\n\tinitZosLibVec()\n\tr0, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS_____GETENV_A<<4, uintptr(unsafe.Pointer(&([]byte(\"__ZOS_XSYSTRACE\\x00\"))[0])))\n\tif r0 != 0 {\n\t\tn, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___ATOI_A<<4, r0)\n\t\tZosTraceLevel = int(n)\n\t\tr0, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS_____GETENV_A<<4, uintptr(unsafe.Pointer(&([]byte(\"__ZOS_XSYSTRACEFD\\x00\"))[0])))\n\t\tif r0 != 0 {\n\t\t\tfd, _, _ := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___ATOI_A<<4, r0)\n\t\t\tf := os.NewFile(fd, \"zostracefile\")\n\t\t\tif f != nil {\n\t\t\t\tZosTracefile = f\n\t\t\t}\n\t\t}\n\n\t}\n}\n\n//go:noescape\nfunc CallLeFuncWithErr(funcdesc uintptr, parms ...uintptr) (ret, errno2 uintptr, err Errno)\n\n//go:noescape\nfunc CallLeFuncWithPtrReturn(funcdesc uintptr, parms ...uintptr) (ret, errno2 uintptr, err Errno)\n\n// -------------------------------\n// pointer validity test\n// good pointer returns 0\n// bad pointer returns 1\n//\n//go:nosplit\nfunc ptrtest(uintptr) uint64\n\n// Load memory at ptr location with error handling if the location is invalid\n//\n//go:noescape\nfunc safeload(ptr uintptr) (value uintptr, error uintptr)\n\nconst (\n\tentrypointLocationOffset = 8 // From function descriptor\n\n\txplinkEyecatcher   = 0x00c300c500c500f1 // \".C.E.E.1\"\n\teyecatcherOffset   = 16                 // From function entrypoint (negative)\n\tppa1LocationOffset = 8                  // From function entrypoint (negative)\n\n\tnameLenOffset = 0x14 // From PPA1 start\n\tnameOffset    = 0x16 // From PPA1 start\n)\n\nfunc getPpaOffset(funcptr uintptr) int64 {\n\tentrypoint, err := safeload(funcptr + entrypointLocationOffset)\n\tif err != 0 {\n\t\treturn -1\n\t}\n\n\t// XPLink functions have \".C.E.E.1\" as the first 8 bytes (EBCDIC)\n\tval, err := safeload(entrypoint - eyecatcherOffset)\n\tif err != 0 {\n\t\treturn -1\n\t}\n\tif val != xplinkEyecatcher {\n\t\treturn -1\n\t}\n\n\tppaoff, err := safeload(entrypoint - ppa1LocationOffset)\n\tif err != 0 {\n\t\treturn -1\n\t}\n\n\tppaoff >>= 32\n\treturn int64(ppaoff)\n}\n\n//-------------------------------\n// function descriptor pointer validity test\n// good pointer returns 0\n// bad pointer returns 1\n\n// TODO: currently mksyscall_zos_s390x.go generate empty string for funcName\n// have correct funcName pass to the funcptrtest function\nfunc funcptrtest(funcptr uintptr, funcName string) uint64 {\n\tentrypoint, err := safeload(funcptr + entrypointLocationOffset)\n\tif err != 0 {\n\t\treturn 1\n\t}\n\n\tppaoff := getPpaOffset(funcptr)\n\tif ppaoff == -1 {\n\t\treturn 1\n\t}\n\n\t// PPA1 offset value is from the start of the entire function block, not the entrypoint\n\tppa1 := (entrypoint - eyecatcherOffset) + uintptr(ppaoff)\n\n\tnameLen, err := safeload(ppa1 + nameLenOffset)\n\tif err != 0 {\n\t\treturn 1\n\t}\n\n\tnameLen >>= 48\n\tif nameLen > 128 {\n\t\treturn 1\n\t}\n\n\t// no function name input to argument end here\n\tif funcName == \"\" {\n\t\treturn 0\n\t}\n\n\tvar funcname [128]byte\n\tfor i := 0; i < int(nameLen); i += 8 {\n\t\tv, err := safeload(ppa1 + nameOffset + uintptr(i))\n\t\tif err != 0 {\n\t\t\treturn 1\n\t\t}\n\t\tfuncname[i] = byte(v >> 56)\n\t\tfuncname[i+1] = byte(v >> 48)\n\t\tfuncname[i+2] = byte(v >> 40)\n\t\tfuncname[i+3] = byte(v >> 32)\n\t\tfuncname[i+4] = byte(v >> 24)\n\t\tfuncname[i+5] = byte(v >> 16)\n\t\tfuncname[i+6] = byte(v >> 8)\n\t\tfuncname[i+7] = byte(v)\n\t}\n\n\truntime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4, // __e2a_l\n\t\t[]uintptr{uintptr(unsafe.Pointer(&funcname[0])), nameLen})\n\n\tname := string(funcname[:nameLen])\n\tif name != funcName {\n\t\treturn 1\n\t}\n\n\treturn 0\n}\n\n// For detection of capabilities on a system.\n// Is function descriptor f a valid function?\nfunc isValidLeFunc(f uintptr) error {\n\tret := funcptrtest(f, \"\")\n\tif ret != 0 {\n\t\treturn fmt.Errorf(\"Bad pointer, not an LE function \")\n\t}\n\treturn nil\n}\n\n// Retrieve function name from descriptor\nfunc getLeFuncName(f uintptr) (string, error) {\n\t// assume it has been checked, only check ppa1 validity here\n\tentry := ((*[2]uintptr)(unsafe.Pointer(f)))[1]\n\tpreamp := ((*[4]uint32)(unsafe.Pointer(entry - eyecatcherOffset)))\n\n\toffsetPpa1 := preamp[2]\n\tif offsetPpa1 > 0x0ffff {\n\t\treturn \"\", fmt.Errorf(\"PPA1 offset seems too big 0x%x\\n\", offsetPpa1)\n\t}\n\n\tppa1 := uintptr(unsafe.Pointer(preamp)) + uintptr(offsetPpa1)\n\tres := ptrtest(ppa1)\n\tif res != 0 {\n\t\treturn \"\", fmt.Errorf(\"PPA1 address not valid\")\n\t}\n\n\tsize := *(*uint16)(unsafe.Pointer(ppa1 + nameLenOffset))\n\tif size > 128 {\n\t\treturn \"\", fmt.Errorf(\"Function name seems too long, length=%d\\n\", size)\n\t}\n\n\tvar name [128]byte\n\tfuncname := (*[128]byte)(unsafe.Pointer(ppa1 + nameOffset))\n\tcopy(name[0:size], funcname[0:size])\n\n\truntime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4, // __e2a_l\n\t\t[]uintptr{uintptr(unsafe.Pointer(&name[0])), uintptr(size)})\n\n\treturn string(name[:size]), nil\n}\n\n// Check z/OS version\nfunc zosLeVersion() (version, release uint32) {\n\tp1 := (*(*uintptr)(unsafe.Pointer(uintptr(1208)))) >> 32\n\tp1 = *(*uintptr)(unsafe.Pointer(uintptr(p1 + 88)))\n\tp1 = *(*uintptr)(unsafe.Pointer(uintptr(p1 + 8)))\n\tp1 = *(*uintptr)(unsafe.Pointer(uintptr(p1 + 984)))\n\tvrm := *(*uint32)(unsafe.Pointer(p1 + 80))\n\tversion = (vrm & 0x00ff0000) >> 16\n\trelease = (vrm & 0x0000ff00) >> 8\n\treturn\n}\n\n// returns a zos C FILE * for stdio fd 0, 1, 2\nfunc ZosStdioFilep(fd int32) uintptr {\n\treturn uintptr(*(*uint64)(unsafe.Pointer(uintptr(*(*uint64)(unsafe.Pointer(uintptr(*(*uint64)(unsafe.Pointer(uintptr(uint64(*(*uint32)(unsafe.Pointer(uintptr(1208)))) + 80))) + uint64((fd+2)<<3))))))))\n}\n\nfunc copyStat(stat *Stat_t, statLE *Stat_LE_t) {\n\tstat.Dev = uint64(statLE.Dev)\n\tstat.Ino = uint64(statLE.Ino)\n\tstat.Nlink = uint64(statLE.Nlink)\n\tstat.Mode = uint32(statLE.Mode)\n\tstat.Uid = uint32(statLE.Uid)\n\tstat.Gid = uint32(statLE.Gid)\n\tstat.Rdev = uint64(statLE.Rdev)\n\tstat.Size = statLE.Size\n\tstat.Atim.Sec = int64(statLE.Atim)\n\tstat.Atim.Nsec = 0 //zos doesn't return nanoseconds\n\tstat.Mtim.Sec = int64(statLE.Mtim)\n\tstat.Mtim.Nsec = 0 //zos doesn't return nanoseconds\n\tstat.Ctim.Sec = int64(statLE.Ctim)\n\tstat.Ctim.Nsec = 0 //zos doesn't return nanoseconds\n\tstat.Blksize = int64(statLE.Blksize)\n\tstat.Blocks = statLE.Blocks\n}\n\nfunc svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)\nfunc svcLoad(name *byte) unsafe.Pointer\nfunc svcUnload(name *byte, fnptr unsafe.Pointer) int64\n\nfunc (d *Dirent) NameString() string {\n\tif d == nil {\n\t\treturn \"\"\n\t}\n\ts := string(d.Name[:])\n\tidx := strings.IndexByte(s, 0)\n\tif idx == -1 {\n\t\treturn s\n\t} else {\n\t\treturn s[:idx]\n\t}\n}\n\nfunc DecodeData(dest []byte, sz int, val uint64) {\n\tfor i := 0; i < sz; i++ {\n\t\tdest[sz-1-i] = byte((val >> (uint64(i * 8))) & 0xff)\n\t}\n}\n\nfunc EncodeData(data []byte) uint64 {\n\tvar value uint64\n\tsz := len(data)\n\tfor i := 0; i < sz; i++ {\n\t\tvalue |= uint64(data[i]) << uint64(((sz - i - 1) * 8))\n\t}\n\treturn value\n}\n\nfunc (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tif sa.Port < 0 || sa.Port > 0xFFFF {\n\t\treturn nil, 0, EINVAL\n\t}\n\tsa.raw.Len = SizeofSockaddrInet4\n\tsa.raw.Family = AF_INET\n\tp := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))\n\tp[0] = byte(sa.Port >> 8)\n\tp[1] = byte(sa.Port)\n\tfor i := 0; i < len(sa.Addr); i++ {\n\t\tsa.raw.Addr[i] = sa.Addr[i]\n\t}\n\treturn unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil\n}\n\nfunc (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tif sa.Port < 0 || sa.Port > 0xFFFF {\n\t\treturn nil, 0, EINVAL\n\t}\n\tsa.raw.Len = SizeofSockaddrInet6\n\tsa.raw.Family = AF_INET6\n\tp := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))\n\tp[0] = byte(sa.Port >> 8)\n\tp[1] = byte(sa.Port)\n\tsa.raw.Scope_id = sa.ZoneId\n\tfor i := 0; i < len(sa.Addr); i++ {\n\t\tsa.raw.Addr[i] = sa.Addr[i]\n\t}\n\treturn unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil\n}\n\nfunc (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {\n\tname := sa.Name\n\tn := len(name)\n\tif n >= len(sa.raw.Path) || n == 0 {\n\t\treturn nil, 0, EINVAL\n\t}\n\tsa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL\n\tsa.raw.Family = AF_UNIX\n\tfor i := 0; i < n; i++ {\n\t\tsa.raw.Path[i] = int8(name[i])\n\t}\n\treturn unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil\n}\n\nfunc anyToSockaddr(_ int, rsa *RawSockaddrAny) (Sockaddr, error) {\n\t// TODO(neeilan): Implement use of first param (fd)\n\tswitch rsa.Addr.Family {\n\tcase AF_UNIX:\n\t\tpp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))\n\t\tsa := new(SockaddrUnix)\n\t\t// For z/OS, only replace NUL with @ when the\n\t\t// length is not zero.\n\t\tif pp.Len != 0 && pp.Path[0] == 0 {\n\t\t\t// \"Abstract\" Unix domain socket.\n\t\t\t// Rewrite leading NUL as @ for textual display.\n\t\t\t// (This is the standard convention.)\n\t\t\t// Not friendly to overwrite in place,\n\t\t\t// but the callers below don't care.\n\t\t\tpp.Path[0] = '@'\n\t\t}\n\n\t\t// Assume path ends at NUL.\n\t\t//\n\t\t// For z/OS, the length of the name is a field\n\t\t// in the structure. To be on the safe side, we\n\t\t// will still scan the name for a NUL but only\n\t\t// to the length provided in the structure.\n\t\t//\n\t\t// This is not technically the Linux semantics for\n\t\t// abstract Unix domain sockets--they are supposed\n\t\t// to be uninterpreted fixed-size binary blobs--but\n\t\t// everyone uses this convention.\n\t\tn := 0\n\t\tfor n < int(pp.Len) && pp.Path[n] != 0 {\n\t\t\tn++\n\t\t}\n\t\tsa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))\n\t\treturn sa, nil\n\n\tcase AF_INET:\n\t\tpp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))\n\t\tsa := new(SockaddrInet4)\n\t\tp := (*[2]byte)(unsafe.Pointer(&pp.Port))\n\t\tsa.Port = int(p[0])<<8 + int(p[1])\n\t\tfor i := 0; i < len(sa.Addr); i++ {\n\t\t\tsa.Addr[i] = pp.Addr[i]\n\t\t}\n\t\treturn sa, nil\n\n\tcase AF_INET6:\n\t\tpp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))\n\t\tsa := new(SockaddrInet6)\n\t\tp := (*[2]byte)(unsafe.Pointer(&pp.Port))\n\t\tsa.Port = int(p[0])<<8 + int(p[1])\n\t\tsa.ZoneId = pp.Scope_id\n\t\tfor i := 0; i < len(sa.Addr); i++ {\n\t\t\tsa.Addr[i] = pp.Addr[i]\n\t\t}\n\t\treturn sa, nil\n\t}\n\treturn nil, EAFNOSUPPORT\n}\n\nfunc Accept(fd int) (nfd int, sa Sockaddr, err error) {\n\tvar rsa RawSockaddrAny\n\tvar len _Socklen = SizeofSockaddrAny\n\tnfd, err = accept(fd, &rsa, &len)\n\tif err != nil {\n\t\treturn\n\t}\n\t// TODO(neeilan): Remove 0 in call\n\tsa, err = anyToSockaddr(0, &rsa)\n\tif err != nil {\n\t\tClose(nfd)\n\t\tnfd = 0\n\t}\n\treturn\n}\n\nfunc Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {\n\tvar rsa RawSockaddrAny\n\tvar len _Socklen = SizeofSockaddrAny\n\tnfd, err = accept4(fd, &rsa, &len, flags)\n\tif err != nil {\n\t\treturn\n\t}\n\tif len > SizeofSockaddrAny {\n\t\tpanic(\"RawSockaddrAny too small\")\n\t}\n\t// TODO(neeilan): Remove 0 in call\n\tsa, err = anyToSockaddr(0, &rsa)\n\tif err != nil {\n\t\tClose(nfd)\n\t\tnfd = 0\n\t}\n\treturn\n}\n\nfunc Ctermid() (tty string, err error) {\n\tvar termdev [1025]byte\n\truntime.EnterSyscall()\n\tr0, err2, err1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___CTERMID_A<<4, uintptr(unsafe.Pointer(&termdev[0])))\n\truntime.ExitSyscall()\n\tif r0 == 0 {\n\t\treturn \"\", fmt.Errorf(\"%s (errno2=0x%x)\\n\", err1.Error(), err2)\n\t}\n\ts := string(termdev[:])\n\tidx := strings.Index(s, string(rune(0)))\n\tif idx == -1 {\n\t\ttty = s\n\t} else {\n\t\ttty = s[:idx]\n\t}\n\treturn\n}\n\nfunc (iov *Iovec) SetLen(length int) {\n\tiov.Len = uint64(length)\n}\n\nfunc (msghdr *Msghdr) SetControllen(length int) {\n\tmsghdr.Controllen = int32(length)\n}\n\nfunc (cmsg *Cmsghdr) SetLen(length int) {\n\tcmsg.Len = int32(length)\n}\n\n//sys   fcntl(fd int, cmd int, arg int) (val int, err error)\n//sys   Flistxattr(fd int, dest []byte) (sz int, err error) = SYS___FLISTXATTR_A\n//sys   Fremovexattr(fd int, attr string) (err error) = SYS___FREMOVEXATTR_A\n//sys\tread(fd int, p []byte) (n int, err error)\n//sys\twrite(fd int, p []byte) (n int, err error)\n\n//sys   Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) = SYS___FGETXATTR_A\n//sys   Fsetxattr(fd int, attr string, data []byte, flag int) (err error) = SYS___FSETXATTR_A\n\n//sys\taccept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = SYS___ACCEPT_A\n//sys\taccept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) = SYS___ACCEPT4_A\n//sys\tbind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___BIND_A\n//sys\tconnect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = SYS___CONNECT_A\n//sysnb\tgetgroups(n int, list *_Gid_t) (nn int, err error)\n//sysnb\tsetgroups(n int, list *_Gid_t) (err error)\n//sys\tgetsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)\n//sys\tsetsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)\n//sysnb\tsocket(domain int, typ int, proto int) (fd int, err error)\n//sysnb\tsocketpair(domain int, typ int, proto int, fd *[2]int32) (err error)\n//sysnb\tgetpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETPEERNAME_A\n//sysnb\tgetsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = SYS___GETSOCKNAME_A\n//sys   Removexattr(path string, attr string) (err error) = SYS___REMOVEXATTR_A\n//sys\trecvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = SYS___RECVFROM_A\n//sys\tsendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = SYS___SENDTO_A\n//sys\trecvmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___RECVMSG_A\n//sys\tsendmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___SENDMSG_A\n//sys   mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) = SYS_MMAP\n//sys   munmap(addr uintptr, length uintptr) (err error) = SYS_MUNMAP\n//sys   ioctl(fd int, req int, arg uintptr) (err error) = SYS_IOCTL\n//sys   ioctlPtr(fd int, req int, arg unsafe.Pointer) (err error) = SYS_IOCTL\n//sys\tshmat(id int, addr uintptr, flag int) (ret uintptr, err error) = SYS_SHMAT\n//sys\tshmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error) = SYS_SHMCTL64\n//sys\tshmdt(addr uintptr) (err error) = SYS_SHMDT\n//sys\tshmget(key int, size int, flag int) (id int, err error) = SYS_SHMGET\n\n//sys   Access(path string, mode uint32) (err error) = SYS___ACCESS_A\n//sys   Chdir(path string) (err error) = SYS___CHDIR_A\n//sys\tChown(path string, uid int, gid int) (err error) = SYS___CHOWN_A\n//sys\tChmod(path string, mode uint32) (err error) = SYS___CHMOD_A\n//sys   Creat(path string, mode uint32) (fd int, err error) = SYS___CREAT_A\n//sys\tDup(oldfd int) (fd int, err error)\n//sys\tDup2(oldfd int, newfd int) (err error)\n//sys\tDup3(oldfd int, newfd int, flags int) (err error) = SYS_DUP3\n//sys\tDirfd(dirp uintptr) (fd int, err error) = SYS_DIRFD\n//sys\tEpollCreate(size int) (fd int, err error) = SYS_EPOLL_CREATE\n//sys\tEpollCreate1(flags int) (fd int, err error) = SYS_EPOLL_CREATE1\n//sys\tEpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) = SYS_EPOLL_CTL\n//sys\tEpollPwait(epfd int, events []EpollEvent, msec int, sigmask *int) (n int, err error) = SYS_EPOLL_PWAIT\n//sys\tEpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_WAIT\n//sys\tErrno2() (er2 int) = SYS___ERRNO2\n//sys\tEventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD\n//sys\tExit(code int)\n//sys\tFaccessat(dirfd int, path string, mode uint32, flags int) (err error) = SYS___FACCESSAT_A\n\nfunc Faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {\n\treturn Faccessat(dirfd, path, mode, flags)\n}\n\n//sys\tFchdir(fd int) (err error)\n//sys\tFchmod(fd int, mode uint32) (err error)\n//sys\tFchmodat(dirfd int, path string, mode uint32, flags int) (err error) = SYS___FCHMODAT_A\n//sys\tFchown(fd int, uid int, gid int) (err error)\n//sys\tFchownat(fd int, path string, uid int, gid int, flags int) (err error) = SYS___FCHOWNAT_A\n//sys\tFcntlInt(fd uintptr, cmd int, arg int) (retval int, err error) = SYS_FCNTL\n//sys\tFdatasync(fd int) (err error) = SYS_FDATASYNC\n//sys\tfstat(fd int, stat *Stat_LE_t) (err error)\n//sys\tfstatat(dirfd int, path string, stat *Stat_LE_t, flags int) (err error) = SYS___FSTATAT_A\n\nfunc Fstat(fd int, stat *Stat_t) (err error) {\n\tvar statLE Stat_LE_t\n\terr = fstat(fd, &statLE)\n\tcopyStat(stat, &statLE)\n\treturn\n}\n\nfunc Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {\n\tvar statLE Stat_LE_t\n\terr = fstatat(dirfd, path, &statLE, flags)\n\tcopyStat(stat, &statLE)\n\treturn\n}\n\nfunc impl_Getxattr(path string, attr string, dest []byte) (sz int, err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 *byte\n\t_p1, err = BytePtrFromString(attr)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p2 unsafe.Pointer\n\tif len(dest) > 0 {\n\t\t_p2 = unsafe.Pointer(&dest[0])\n\t} else {\n\t\t_p2 = unsafe.Pointer(&_zero)\n\t}\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___GETXATTR_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)))\n\tsz = int(r0)\n\tif int64(r0) == -1 {\n\t\terr = errnoErr2(e1, e2)\n\t}\n\treturn\n}\n\n//go:nosplit\nfunc get_GetxattrAddr() *(func(path string, attr string, dest []byte) (sz int, err error))\n\nvar Getxattr = enter_Getxattr\n\nfunc enter_Getxattr(path string, attr string, dest []byte) (sz int, err error) {\n\tfuncref := get_GetxattrAddr()\n\tif validGetxattr() {\n\t\t*funcref = impl_Getxattr\n\t} else {\n\t\t*funcref = error_Getxattr\n\t}\n\treturn (*funcref)(path, attr, dest)\n}\n\nfunc error_Getxattr(path string, attr string, dest []byte) (sz int, err error) {\n\treturn -1, ENOSYS\n}\n\nfunc validGetxattr() bool {\n\tif funcptrtest(GetZosLibVec()+SYS___GETXATTR_A<<4, \"\") == 0 {\n\t\tif name, err := getLeFuncName(GetZosLibVec() + SYS___GETXATTR_A<<4); err == nil {\n\t\t\treturn name == \"__getxattr_a\"\n\t\t}\n\t}\n\treturn false\n}\n\n//sys   Lgetxattr(link string, attr string, dest []byte) (sz int, err error) = SYS___LGETXATTR_A\n//sys   Lsetxattr(path string, attr string, data []byte, flags int) (err error) = SYS___LSETXATTR_A\n\nfunc impl_Setxattr(path string, attr string, data []byte, flags int) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 *byte\n\t_p1, err = BytePtrFromString(attr)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p2 unsafe.Pointer\n\tif len(data) > 0 {\n\t\t_p2 = unsafe.Pointer(&data[0])\n\t} else {\n\t\t_p2 = unsafe.Pointer(&_zero)\n\t}\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___SETXATTR_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags))\n\tif int64(r0) == -1 {\n\t\terr = errnoErr2(e1, e2)\n\t}\n\treturn\n}\n\n//go:nosplit\nfunc get_SetxattrAddr() *(func(path string, attr string, data []byte, flags int) (err error))\n\nvar Setxattr = enter_Setxattr\n\nfunc enter_Setxattr(path string, attr string, data []byte, flags int) (err error) {\n\tfuncref := get_SetxattrAddr()\n\tif validSetxattr() {\n\t\t*funcref = impl_Setxattr\n\t} else {\n\t\t*funcref = error_Setxattr\n\t}\n\treturn (*funcref)(path, attr, data, flags)\n}\n\nfunc error_Setxattr(path string, attr string, data []byte, flags int) (err error) {\n\treturn ENOSYS\n}\n\nfunc validSetxattr() bool {\n\tif funcptrtest(GetZosLibVec()+SYS___SETXATTR_A<<4, \"\") == 0 {\n\t\tif name, err := getLeFuncName(GetZosLibVec() + SYS___SETXATTR_A<<4); err == nil {\n\t\t\treturn name == \"__setxattr_a\"\n\t\t}\n\t}\n\treturn false\n}\n\n//sys\tFstatfs(fd int, buf *Statfs_t) (err error) = SYS_FSTATFS\n//sys\tFstatvfs(fd int, stat *Statvfs_t) (err error) = SYS_FSTATVFS\n//sys\tFsync(fd int) (err error)\n//sys\tFutimes(fd int, tv []Timeval) (err error) = SYS_FUTIMES\n//sys\tFutimesat(dirfd int, path string, tv []Timeval) (err error) = SYS___FUTIMESAT_A\n//sys\tFtruncate(fd int, length int64) (err error)\n//sys\tGetrandom(buf []byte, flags int) (n int, err error) = SYS_GETRANDOM\n//sys\tInotifyInit() (fd int, err error) = SYS_INOTIFY_INIT\n//sys\tInotifyInit1(flags int) (fd int, err error) = SYS_INOTIFY_INIT1\n//sys\tInotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) = SYS___INOTIFY_ADD_WATCH_A\n//sys\tInotifyRmWatch(fd int, watchdesc uint32) (success int, err error) = SYS_INOTIFY_RM_WATCH\n//sys   Listxattr(path string, dest []byte) (sz int, err error) = SYS___LISTXATTR_A\n//sys   Llistxattr(path string, dest []byte) (sz int, err error) = SYS___LLISTXATTR_A\n//sys   Lremovexattr(path string, attr string) (err error) = SYS___LREMOVEXATTR_A\n//sys\tLutimes(path string, tv []Timeval) (err error) = SYS___LUTIMES_A\n//sys   Mprotect(b []byte, prot int) (err error) = SYS_MPROTECT\n//sys   Msync(b []byte, flags int) (err error) = SYS_MSYNC\n//sys   Console2(cmsg *ConsMsg2, modstr *byte, concmd *uint32) (err error) = SYS___CONSOLE2\n\n// Pipe2 begin\n\n//go:nosplit\nfunc getPipe2Addr() *(func([]int, int) error)\n\nvar Pipe2 = pipe2Enter\n\nfunc pipe2Enter(p []int, flags int) (err error) {\n\tif funcptrtest(GetZosLibVec()+SYS_PIPE2<<4, \"\") == 0 {\n\t\t*getPipe2Addr() = pipe2Impl\n\t} else {\n\t\t*getPipe2Addr() = pipe2Error\n\t}\n\treturn (*getPipe2Addr())(p, flags)\n}\n\nfunc pipe2Impl(p []int, flags int) (err error) {\n\tvar pp [2]_C_int\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_PIPE2<<4, uintptr(unsafe.Pointer(&pp[0])), uintptr(flags))\n\tif int64(r0) == -1 {\n\t\terr = errnoErr2(e1, e2)\n\t} else {\n\t\tp[0] = int(pp[0])\n\t\tp[1] = int(pp[1])\n\t}\n\treturn\n}\nfunc pipe2Error(p []int, flags int) (err error) {\n\treturn fmt.Errorf(\"Pipe2 is not available on this system\")\n}\n\n// Pipe2 end\n\n//sys   Poll(fds []PollFd, timeout int) (n int, err error) = SYS_POLL\n\nfunc Readdir(dir uintptr) (dirent *Dirent, err error) {\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___READDIR_A<<4, uintptr(dir))\n\truntime.ExitSyscall()\n\tdirent = (*Dirent)(unsafe.Pointer(r0))\n\tif int64(r0) == -1 {\n\t\terr = errnoErr2(e1, e2)\n\t}\n\treturn\n}\n\n//sys\tReaddir_r(dirp uintptr, entry *direntLE, result **direntLE) (err error) = SYS___READDIR_R_A\n//sys\tStatfs(path string, buf *Statfs_t) (err error) = SYS___STATFS_A\n//sys\tSyncfs(fd int) (err error) = SYS_SYNCFS\n//sys   Times(tms *Tms) (ticks uintptr, err error) = SYS_TIMES\n//sys   W_Getmntent(buff *byte, size int) (lastsys int, err error) = SYS_W_GETMNTENT\n//sys   W_Getmntent_A(buff *byte, size int) (lastsys int, err error) = SYS___W_GETMNTENT_A\n\n//sys   mount_LE(path string, filesystem string, fstype string, mtm uint32, parmlen int32, parm string) (err error) = SYS___MOUNT_A\n//sys   unmount_LE(filesystem string, mtm int) (err error) = SYS___UMOUNT_A\n//sys   Chroot(path string) (err error) = SYS___CHROOT_A\n//sys   Select(nmsgsfds int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (ret int, err error) = SYS_SELECT\n//sysnb Uname(buf *Utsname) (err error) = SYS_____OSNAME_A\n//sys   Unshare(flags int) (err error) = SYS_UNSHARE\n\nfunc Ptsname(fd int) (name string, err error) {\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___PTSNAME_A<<4, uintptr(fd))\n\truntime.ExitSyscall()\n\tif r0 == 0 {\n\t\terr = errnoErr2(e1, e2)\n\t} else {\n\t\tname = u2s(unsafe.Pointer(r0))\n\t}\n\treturn\n}\n\nfunc u2s(cstr unsafe.Pointer) string {\n\tstr := (*[1024]uint8)(cstr)\n\ti := 0\n\tfor str[i] != 0 {\n\t\ti++\n\t}\n\treturn string(str[:i])\n}\n\nfunc Close(fd int) (err error) {\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_CLOSE<<4, uintptr(fd))\n\truntime.ExitSyscall()\n\tfor i := 0; e1 == EAGAIN && i < 10; i++ {\n\t\truntime.EnterSyscall()\n\t\tCallLeFuncWithErr(GetZosLibVec()+SYS_USLEEP<<4, uintptr(10))\n\t\truntime.ExitSyscall()\n\t\truntime.EnterSyscall()\n\t\tr0, e2, e1 = CallLeFuncWithErr(GetZosLibVec()+SYS_CLOSE<<4, uintptr(fd))\n\t\truntime.ExitSyscall()\n\t}\n\tif r0 != 0 {\n\t\terr = errnoErr2(e1, e2)\n\t}\n\treturn\n}\n\n// Dummy function: there are no semantics for Madvise on z/OS\nfunc Madvise(b []byte, advice int) (err error) {\n\treturn\n}\n\nfunc Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {\n\treturn mapper.Mmap(fd, offset, length, prot, flags)\n}\n\nfunc Munmap(b []byte) (err error) {\n\treturn mapper.Munmap(b)\n}\n\nfunc MmapPtr(fd int, offset int64, addr unsafe.Pointer, length uintptr, prot int, flags int) (ret unsafe.Pointer, err error) {\n\txaddr, err := mapper.mmap(uintptr(addr), length, prot, flags, fd, offset)\n\treturn unsafe.Pointer(xaddr), err\n}\n\nfunc MunmapPtr(addr unsafe.Pointer, length uintptr) (err error) {\n\treturn mapper.munmap(uintptr(addr), length)\n}\n\n//sys   Gethostname(buf []byte) (err error) = SYS___GETHOSTNAME_A\n//sysnb\tGetgid() (gid int)\n//sysnb\tGetpid() (pid int)\n//sysnb\tGetpgid(pid int) (pgid int, err error) = SYS_GETPGID\n\nfunc Getpgrp() (pid int) {\n\tpid, _ = Getpgid(0)\n\treturn\n}\n\n//sysnb\tGetppid() (pid int)\n//sys\tGetpriority(which int, who int) (prio int, err error)\n//sysnb\tGetrlimit(resource int, rlim *Rlimit) (err error) = SYS_GETRLIMIT\n\n//sysnb getrusage(who int, rusage *rusage_zos) (err error) = SYS_GETRUSAGE\n\nfunc Getrusage(who int, rusage *Rusage) (err error) {\n\tvar ruz rusage_zos\n\terr = getrusage(who, &ruz)\n\t//Only the first two fields of Rusage are set\n\trusage.Utime.Sec = ruz.Utime.Sec\n\trusage.Utime.Usec = int64(ruz.Utime.Usec)\n\trusage.Stime.Sec = ruz.Stime.Sec\n\trusage.Stime.Usec = int64(ruz.Stime.Usec)\n\treturn\n}\n\n//sys\tGetegid() (egid int) = SYS_GETEGID\n//sys\tGeteuid() (euid int) = SYS_GETEUID\n//sysnb Getsid(pid int) (sid int, err error) = SYS_GETSID\n//sysnb\tGetuid() (uid int)\n//sysnb\tKill(pid int, sig Signal) (err error)\n//sys\tLchown(path string, uid int, gid int) (err error) = SYS___LCHOWN_A\n//sys\tLink(path string, link string) (err error) = SYS___LINK_A\n//sys\tLinkat(oldDirFd int, oldPath string, newDirFd int, newPath string, flags int) (err error) = SYS___LINKAT_A\n//sys\tListen(s int, n int) (err error)\n//sys\tlstat(path string, stat *Stat_LE_t) (err error) = SYS___LSTAT_A\n\nfunc Lstat(path string, stat *Stat_t) (err error) {\n\tvar statLE Stat_LE_t\n\terr = lstat(path, &statLE)\n\tcopyStat(stat, &statLE)\n\treturn\n}\n\n// for checking symlinks begins with $VERSION/ $SYSNAME/ $SYSSYMR/ $SYSSYMA/\nfunc isSpecialPath(path []byte) (v bool) {\n\tvar special = [4][8]byte{\n\t\t{'V', 'E', 'R', 'S', 'I', 'O', 'N', '/'},\n\t\t{'S', 'Y', 'S', 'N', 'A', 'M', 'E', '/'},\n\t\t{'S', 'Y', 'S', 'S', 'Y', 'M', 'R', '/'},\n\t\t{'S', 'Y', 'S', 'S', 'Y', 'M', 'A', '/'}}\n\n\tvar i, j int\n\tfor i = 0; i < len(special); i++ {\n\t\tfor j = 0; j < len(special[i]); j++ {\n\t\t\tif path[j] != special[i][j] {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif j == len(special[i]) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc realpath(srcpath string, abspath []byte) (pathlen int, errno int) {\n\tvar source [1024]byte\n\tcopy(source[:], srcpath)\n\tsource[len(srcpath)] = 0\n\tret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___REALPATH_A<<4, //__realpath_a()\n\t\t[]uintptr{uintptr(unsafe.Pointer(&source[0])),\n\t\t\tuintptr(unsafe.Pointer(&abspath[0]))})\n\tif ret != 0 {\n\t\tindex := bytes.IndexByte(abspath[:], byte(0))\n\t\tif index != -1 {\n\t\t\treturn index, 0\n\t\t}\n\t} else {\n\t\terrptr := (*int)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4, []uintptr{}))) //__errno()\n\t\treturn 0, *errptr\n\t}\n\treturn 0, 245 // EBADDATA   245\n}\n\nfunc Readlink(path string, buf []byte) (n int, err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 unsafe.Pointer\n\tif len(buf) > 0 {\n\t\t_p1 = unsafe.Pointer(&buf[0])\n\t} else {\n\t\t_p1 = unsafe.Pointer(&_zero)\n\t}\n\tn = int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___READLINK_A<<4,\n\t\t[]uintptr{uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf))}))\n\truntime.KeepAlive(unsafe.Pointer(_p0))\n\tif n == -1 {\n\t\tvalue := *(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4, []uintptr{})))\n\t\terr = errnoErr(Errno(value))\n\t} else {\n\t\tif buf[0] == '$' {\n\t\t\tif isSpecialPath(buf[1:9]) {\n\t\t\t\tcnt, err1 := realpath(path, buf)\n\t\t\t\tif err1 == 0 {\n\t\t\t\t\tn = cnt\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\nfunc impl_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 unsafe.Pointer\n\tif len(buf) > 0 {\n\t\t_p1 = unsafe.Pointer(&buf[0])\n\t} else {\n\t\t_p1 = unsafe.Pointer(&_zero)\n\t}\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___READLINKAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))\n\truntime.ExitSyscall()\n\tn = int(r0)\n\tif int64(r0) == -1 {\n\t\terr = errnoErr2(e1, e2)\n\t\treturn n, err\n\t} else {\n\t\tif buf[0] == '$' {\n\t\t\tif isSpecialPath(buf[1:9]) {\n\t\t\t\tcnt, err1 := realpath(path, buf)\n\t\t\t\tif err1 == 0 {\n\t\t\t\t\tn = cnt\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\n//go:nosplit\nfunc get_ReadlinkatAddr() *(func(dirfd int, path string, buf []byte) (n int, err error))\n\nvar Readlinkat = enter_Readlinkat\n\nfunc enter_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {\n\tfuncref := get_ReadlinkatAddr()\n\tif funcptrtest(GetZosLibVec()+SYS___READLINKAT_A<<4, \"\") == 0 {\n\t\t*funcref = impl_Readlinkat\n\t} else {\n\t\t*funcref = error_Readlinkat\n\t}\n\treturn (*funcref)(dirfd, path, buf)\n}\n\nfunc error_Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {\n\tn = -1\n\terr = ENOSYS\n\treturn\n}\n\n//sys\tMkdir(path string, mode uint32) (err error) = SYS___MKDIR_A\n//sys\tMkdirat(dirfd int, path string, mode uint32) (err error) = SYS___MKDIRAT_A\n//sys   Mkfifo(path string, mode uint32) (err error) = SYS___MKFIFO_A\n//sys\tMknod(path string, mode uint32, dev int) (err error) = SYS___MKNOD_A\n//sys\tMknodat(dirfd int, path string, mode uint32, dev int) (err error) = SYS___MKNODAT_A\n//sys\tPivotRoot(newroot string, oldroot string) (err error) = SYS___PIVOT_ROOT_A\n//sys\tPread(fd int, p []byte, offset int64) (n int, err error)\n//sys\tPwrite(fd int, p []byte, offset int64) (n int, err error)\n//sys\tPrctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) = SYS___PRCTL_A\n//sysnb\tPrlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT\n//sys\tRename(from string, to string) (err error) = SYS___RENAME_A\n//sys\tRenameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) = SYS___RENAMEAT_A\n//sys\tRenameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) = SYS___RENAMEAT2_A\n//sys\tRmdir(path string) (err error) = SYS___RMDIR_A\n//sys   Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK\n//sys\tSetegid(egid int) (err error) = SYS_SETEGID\n//sys\tSeteuid(euid int) (err error) = SYS_SETEUID\n//sys\tSethostname(p []byte) (err error) = SYS___SETHOSTNAME_A\n//sys   Setns(fd int, nstype int) (err error) = SYS_SETNS\n//sys\tSetpriority(which int, who int, prio int) (err error)\n//sysnb\tSetpgid(pid int, pgid int) (err error) = SYS_SETPGID\n//sysnb\tSetrlimit(resource int, lim *Rlimit) (err error)\n//sysnb\tSetregid(rgid int, egid int) (err error) = SYS_SETREGID\n//sysnb\tSetreuid(ruid int, euid int) (err error) = SYS_SETREUID\n//sysnb\tSetsid() (pid int, err error) = SYS_SETSID\n//sys\tSetuid(uid int) (err error) = SYS_SETUID\n//sys\tSetgid(uid int) (err error) = SYS_SETGID\n//sys\tShutdown(fd int, how int) (err error)\n//sys\tstat(path string, statLE *Stat_LE_t) (err error) = SYS___STAT_A\n\nfunc Stat(path string, sta *Stat_t) (err error) {\n\tvar statLE Stat_LE_t\n\terr = stat(path, &statLE)\n\tcopyStat(sta, &statLE)\n\treturn\n}\n\n//sys\tSymlink(path string, link string) (err error) = SYS___SYMLINK_A\n//sys\tSymlinkat(oldPath string, dirfd int, newPath string) (err error) = SYS___SYMLINKAT_A\n//sys\tSync() = SYS_SYNC\n//sys\tTruncate(path string, length int64) (err error) = SYS___TRUNCATE_A\n//sys\tTcgetattr(fildes int, termptr *Termios) (err error) = SYS_TCGETATTR\n//sys\tTcsetattr(fildes int, when int, termptr *Termios) (err error) = SYS_TCSETATTR\n//sys\tUmask(mask int) (oldmask int)\n//sys\tUnlink(path string) (err error) = SYS___UNLINK_A\n//sys\tUnlinkat(dirfd int, path string, flags int) (err error) = SYS___UNLINKAT_A\n//sys\tUtime(path string, utim *Utimbuf) (err error) = SYS___UTIME_A\n\n//sys\topen(path string, mode int, perm uint32) (fd int, err error) = SYS___OPEN_A\n\nfunc Open(path string, mode int, perm uint32) (fd int, err error) {\n\tif mode&O_ACCMODE == 0 {\n\t\tmode |= O_RDONLY\n\t}\n\treturn open(path, mode, perm)\n}\n\n//sys\topenat(dirfd int, path string, flags int, mode uint32) (fd int, err error) = SYS___OPENAT_A\n\nfunc Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {\n\tif flags&O_ACCMODE == 0 {\n\t\tflags |= O_RDONLY\n\t}\n\treturn openat(dirfd, path, flags, mode)\n}\n\n//sys\topenat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) = SYS___OPENAT2_A\n\nfunc Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) {\n\tif how.Flags&O_ACCMODE == 0 {\n\t\thow.Flags |= O_RDONLY\n\t}\n\treturn openat2(dirfd, path, how, SizeofOpenHow)\n}\n\nfunc ZosFdToPath(dirfd int) (path string, err error) {\n\tvar buffer [1024]byte\n\truntime.EnterSyscall()\n\tret, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_W_IOCTL<<4, uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0])))\n\truntime.ExitSyscall()\n\tif ret == 0 {\n\t\tzb := bytes.IndexByte(buffer[:], 0)\n\t\tif zb == -1 {\n\t\t\tzb = len(buffer)\n\t\t}\n\t\tCallLeFuncWithErr(GetZosLibVec()+SYS___E2A_L<<4, uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb))\n\t\treturn string(buffer[:zb]), nil\n\t}\n\treturn \"\", errnoErr2(e1, e2)\n}\n\n//sys\tremove(path string) (err error)\n\nfunc Remove(path string) error {\n\treturn remove(path)\n}\n\nconst ImplementsGetwd = true\n\nfunc Getcwd(buf []byte) (n int, err error) {\n\tvar p unsafe.Pointer\n\tif len(buf) > 0 {\n\t\tp = unsafe.Pointer(&buf[0])\n\t} else {\n\t\tp = unsafe.Pointer(&_zero)\n\t}\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___GETCWD_A<<4, uintptr(p), uintptr(len(buf)))\n\truntime.ExitSyscall()\n\tn = clen(buf) + 1\n\tif r0 == 0 {\n\t\terr = errnoErr2(e1, e2)\n\t}\n\treturn\n}\n\nfunc Getwd() (wd string, err error) {\n\tvar buf [PathMax]byte\n\tn, err := Getcwd(buf[0:])\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\t// Getcwd returns the number of bytes written to buf, including the NUL.\n\tif n < 1 || n > len(buf) || buf[n-1] != 0 {\n\t\treturn \"\", EINVAL\n\t}\n\treturn string(buf[0 : n-1]), nil\n}\n\nfunc Getgroups() (gids []int, err error) {\n\tn, err := getgroups(0, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif n == 0 {\n\t\treturn nil, nil\n\t}\n\n\t// Sanity check group count.  Max is 1<<16 on Linux.\n\tif n < 0 || n > 1<<20 {\n\t\treturn nil, EINVAL\n\t}\n\n\ta := make([]_Gid_t, n)\n\tn, err = getgroups(n, &a[0])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tgids = make([]int, n)\n\tfor i, v := range a[0:n] {\n\t\tgids[i] = int(v)\n\t}\n\treturn\n}\n\nfunc Setgroups(gids []int) (err error) {\n\tif len(gids) == 0 {\n\t\treturn setgroups(0, nil)\n\t}\n\n\ta := make([]_Gid_t, len(gids))\n\tfor i, v := range gids {\n\t\ta[i] = _Gid_t(v)\n\t}\n\treturn setgroups(len(a), &a[0])\n}\n\nfunc gettid() uint64\n\nfunc Gettid() (tid int) {\n\treturn int(gettid())\n}\n\ntype WaitStatus uint32\n\n// Wait status is 7 bits at bottom, either 0 (exited),\n// 0x7F (stopped), or a signal number that caused an exit.\n// The 0x80 bit is whether there was a core dump.\n// An extra number (exit code, signal causing a stop)\n// is in the high bits.  At least that's the idea.\n// There are various irregularities.  For example, the\n// \"continued\" status is 0xFFFF, distinguishing itself\n// from stopped via the core dump bit.\n\nconst (\n\tmask    = 0x7F\n\tcore    = 0x80\n\texited  = 0x00\n\tstopped = 0x7F\n\tshift   = 8\n)\n\nfunc (w WaitStatus) Exited() bool { return w&mask == exited }\n\nfunc (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }\n\nfunc (w WaitStatus) Stopped() bool { return w&0xFF == stopped }\n\nfunc (w WaitStatus) Continued() bool { return w == 0xFFFF }\n\nfunc (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }\n\nfunc (w WaitStatus) ExitStatus() int {\n\tif !w.Exited() {\n\t\treturn -1\n\t}\n\treturn int(w>>shift) & 0xFF\n}\n\nfunc (w WaitStatus) Signal() Signal {\n\tif !w.Signaled() {\n\t\treturn -1\n\t}\n\treturn Signal(w & mask)\n}\n\nfunc (w WaitStatus) StopSignal() Signal {\n\tif !w.Stopped() {\n\t\treturn -1\n\t}\n\treturn Signal(w>>shift) & 0xFF\n}\n\nfunc (w WaitStatus) TrapCause() int { return -1 }\n\n//sys\twaitid(idType int, id int, info *Siginfo, options int) (err error)\n\nfunc Waitid(idType int, id int, info *Siginfo, options int, rusage *Rusage) (err error) {\n\treturn waitid(idType, id, info, options)\n}\n\n//sys\twaitpid(pid int, wstatus *_C_int, options int) (wpid int, err error)\n\nfunc impl_Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_WAIT4<<4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)))\n\truntime.ExitSyscall()\n\twpid = int(r0)\n\tif int64(r0) == -1 {\n\t\terr = errnoErr2(e1, e2)\n\t}\n\treturn\n}\n\n//go:nosplit\nfunc get_Wait4Addr() *(func(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error))\n\nvar Wait4 = enter_Wait4\n\nfunc enter_Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {\n\tfuncref := get_Wait4Addr()\n\tif funcptrtest(GetZosLibVec()+SYS_WAIT4<<4, \"\") == 0 {\n\t\t*funcref = impl_Wait4\n\t} else {\n\t\t*funcref = legacyWait4\n\t}\n\treturn (*funcref)(pid, wstatus, options, rusage)\n}\n\nfunc legacyWait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {\n\t// TODO(mundaym): z/OS doesn't have wait4. I don't think getrusage does what we want.\n\t// At the moment rusage will not be touched.\n\tvar status _C_int\n\twpid, err = waitpid(pid, &status, options)\n\tif wstatus != nil {\n\t\t*wstatus = WaitStatus(status)\n\t}\n\treturn\n}\n\n//sysnb\tgettimeofday(tv *timeval_zos) (err error)\n\nfunc Gettimeofday(tv *Timeval) (err error) {\n\tvar tvz timeval_zos\n\terr = gettimeofday(&tvz)\n\ttv.Sec = tvz.Sec\n\ttv.Usec = int64(tvz.Usec)\n\treturn\n}\n\nfunc Time(t *Time_t) (tt Time_t, err error) {\n\tvar tv Timeval\n\terr = Gettimeofday(&tv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif t != nil {\n\t\t*t = Time_t(tv.Sec)\n\t}\n\treturn Time_t(tv.Sec), nil\n}\n\nfunc setTimespec(sec, nsec int64) Timespec {\n\treturn Timespec{Sec: sec, Nsec: nsec}\n}\n\nfunc setTimeval(sec, usec int64) Timeval { //fix\n\treturn Timeval{Sec: sec, Usec: usec}\n}\n\n//sysnb pipe(p *[2]_C_int) (err error)\n\nfunc Pipe(p []int) (err error) {\n\tif len(p) != 2 {\n\t\treturn EINVAL\n\t}\n\tvar pp [2]_C_int\n\terr = pipe(&pp)\n\tp[0] = int(pp[0])\n\tp[1] = int(pp[1])\n\treturn\n}\n\n//sys\tutimes(path string, timeval *[2]Timeval) (err error) = SYS___UTIMES_A\n\nfunc Utimes(path string, tv []Timeval) (err error) {\n\tif tv == nil {\n\t\treturn utimes(path, nil)\n\t}\n\tif len(tv) != 2 {\n\t\treturn EINVAL\n\t}\n\treturn utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))\n}\n\n//sys\tutimensat(dirfd int, path string, ts *[2]Timespec, flags int) (err error) = SYS___UTIMENSAT_A\n\nfunc validUtimensat() bool {\n\tif funcptrtest(GetZosLibVec()+SYS___UTIMENSAT_A<<4, \"\") == 0 {\n\t\tif name, err := getLeFuncName(GetZosLibVec() + SYS___UTIMENSAT_A<<4); err == nil {\n\t\t\treturn name == \"__utimensat_a\"\n\t\t}\n\t}\n\treturn false\n}\n\n// Begin UtimesNano\n\n//go:nosplit\nfunc get_UtimesNanoAddr() *(func(path string, ts []Timespec) (err error))\n\nvar UtimesNano = enter_UtimesNano\n\nfunc enter_UtimesNano(path string, ts []Timespec) (err error) {\n\tfuncref := get_UtimesNanoAddr()\n\tif validUtimensat() {\n\t\t*funcref = utimesNanoImpl\n\t} else {\n\t\t*funcref = legacyUtimesNano\n\t}\n\treturn (*funcref)(path, ts)\n}\n\nfunc utimesNanoImpl(path string, ts []Timespec) (err error) {\n\tif ts == nil {\n\t\treturn utimensat(AT_FDCWD, path, nil, 0)\n\t}\n\tif len(ts) != 2 {\n\t\treturn EINVAL\n\t}\n\treturn utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)\n}\n\nfunc legacyUtimesNano(path string, ts []Timespec) (err error) {\n\tif len(ts) != 2 {\n\t\treturn EINVAL\n\t}\n\t// Not as efficient as it could be because Timespec and\n\t// Timeval have different types in the different OSes\n\ttv := [2]Timeval{\n\t\tNsecToTimeval(TimespecToNsec(ts[0])),\n\t\tNsecToTimeval(TimespecToNsec(ts[1])),\n\t}\n\treturn utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))\n}\n\n// End UtimesNano\n\n// Begin UtimesNanoAt\n\n//go:nosplit\nfunc get_UtimesNanoAtAddr() *(func(dirfd int, path string, ts []Timespec, flags int) (err error))\n\nvar UtimesNanoAt = enter_UtimesNanoAt\n\nfunc enter_UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) (err error) {\n\tfuncref := get_UtimesNanoAtAddr()\n\tif validUtimensat() {\n\t\t*funcref = utimesNanoAtImpl\n\t} else {\n\t\t*funcref = legacyUtimesNanoAt\n\t}\n\treturn (*funcref)(dirfd, path, ts, flags)\n}\n\nfunc utimesNanoAtImpl(dirfd int, path string, ts []Timespec, flags int) (err error) {\n\tif ts == nil {\n\t\treturn utimensat(dirfd, path, nil, flags)\n\t}\n\tif len(ts) != 2 {\n\t\treturn EINVAL\n\t}\n\treturn utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)\n}\n\nfunc legacyUtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) (err error) {\n\tif path[0] != '/' {\n\t\tdirPath, err := ZosFdToPath(dirfd)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tpath = dirPath + \"/\" + path\n\t}\n\tif flags == AT_SYMLINK_NOFOLLOW {\n\t\tif len(ts) != 2 {\n\t\t\treturn EINVAL\n\t\t}\n\n\t\tif ts[0].Nsec >= 5e8 {\n\t\t\tts[0].Sec++\n\t\t}\n\t\tts[0].Nsec = 0\n\t\tif ts[1].Nsec >= 5e8 {\n\t\t\tts[1].Sec++\n\t\t}\n\t\tts[1].Nsec = 0\n\n\t\t// Not as efficient as it could be because Timespec and\n\t\t// Timeval have different types in the different OSes\n\t\ttv := []Timeval{\n\t\t\tNsecToTimeval(TimespecToNsec(ts[0])),\n\t\t\tNsecToTimeval(TimespecToNsec(ts[1])),\n\t\t}\n\t\treturn Lutimes(path, tv)\n\t}\n\treturn UtimesNano(path, ts)\n}\n\n// End UtimesNanoAt\n\nfunc Getsockname(fd int) (sa Sockaddr, err error) {\n\tvar rsa RawSockaddrAny\n\tvar len _Socklen = SizeofSockaddrAny\n\tif err = getsockname(fd, &rsa, &len); err != nil {\n\t\treturn\n\t}\n\t// TODO(neeilan) : Remove this 0 ( added to get sys/unix compiling on z/OS )\n\treturn anyToSockaddr(0, &rsa)\n}\n\nconst (\n\t// identifier constants\n\tnwmHeaderIdentifier    = 0xd5e6d4c8\n\tnwmFilterIdentifier    = 0xd5e6d4c6\n\tnwmTCPConnIdentifier   = 0xd5e6d4c3\n\tnwmRecHeaderIdentifier = 0xd5e6d4d9\n\tnwmIPStatsIdentifier   = 0xd5e6d4c9d7e2e340\n\tnwmIPGStatsIdentifier  = 0xd5e6d4c9d7c7e2e3\n\tnwmTCPStatsIdentifier  = 0xd5e6d4e3c3d7e2e3\n\tnwmUDPStatsIdentifier  = 0xd5e6d4e4c4d7e2e3\n\tnwmICMPGStatsEntry     = 0xd5e6d4c9c3d4d7c7\n\tnwmICMPTStatsEntry     = 0xd5e6d4c9c3d4d7e3\n\n\t// nwmHeader constants\n\tnwmVersion1   = 1\n\tnwmVersion2   = 2\n\tnwmCurrentVer = 2\n\n\tnwmTCPConnType     = 1\n\tnwmGlobalStatsType = 14\n\n\t// nwmFilter constants\n\tnwmFilterLclAddrMask = 0x20000000 // Local address\n\tnwmFilterSrcAddrMask = 0x20000000 // Source address\n\tnwmFilterLclPortMask = 0x10000000 // Local port\n\tnwmFilterSrcPortMask = 0x10000000 // Source port\n\n\t// nwmConnEntry constants\n\tnwmTCPStateClosed   = 1\n\tnwmTCPStateListen   = 2\n\tnwmTCPStateSynSent  = 3\n\tnwmTCPStateSynRcvd  = 4\n\tnwmTCPStateEstab    = 5\n\tnwmTCPStateFinWait1 = 6\n\tnwmTCPStateFinWait2 = 7\n\tnwmTCPStateClosWait = 8\n\tnwmTCPStateLastAck  = 9\n\tnwmTCPStateClosing  = 10\n\tnwmTCPStateTimeWait = 11\n\tnwmTCPStateDeletTCB = 12\n\n\t// Existing constants on linux\n\tBPF_TCP_CLOSE        = 1\n\tBPF_TCP_LISTEN       = 2\n\tBPF_TCP_SYN_SENT     = 3\n\tBPF_TCP_SYN_RECV     = 4\n\tBPF_TCP_ESTABLISHED  = 5\n\tBPF_TCP_FIN_WAIT1    = 6\n\tBPF_TCP_FIN_WAIT2    = 7\n\tBPF_TCP_CLOSE_WAIT   = 8\n\tBPF_TCP_LAST_ACK     = 9\n\tBPF_TCP_CLOSING      = 10\n\tBPF_TCP_TIME_WAIT    = 11\n\tBPF_TCP_NEW_SYN_RECV = -1\n\tBPF_TCP_MAX_STATES   = -2\n)\n\ntype nwmTriplet struct {\n\toffset uint32\n\tlength uint32\n\tnumber uint32\n}\n\ntype nwmQuadruplet struct {\n\toffset uint32\n\tlength uint32\n\tnumber uint32\n\tmatch  uint32\n}\n\ntype nwmHeader struct {\n\tident       uint32\n\tlength      uint32\n\tversion     uint16\n\tnwmType     uint16\n\tbytesNeeded uint32\n\toptions     uint32\n\t_           [16]byte\n\tinputDesc   nwmTriplet\n\toutputDesc  nwmQuadruplet\n}\n\ntype nwmFilter struct {\n\tident         uint32\n\tflags         uint32\n\tresourceName  [8]byte\n\tresourceId    uint32\n\tlistenerId    uint32\n\tlocal         [28]byte // union of sockaddr4 and sockaddr6\n\tremote        [28]byte // union of sockaddr4 and sockaddr6\n\t_             uint16\n\t_             uint16\n\tasid          uint16\n\t_             [2]byte\n\ttnLuName      [8]byte\n\ttnMonGrp      uint32\n\ttnAppl        [8]byte\n\tapplData      [40]byte\n\tnInterface    [16]byte\n\tdVipa         [16]byte\n\tdVipaPfx      uint16\n\tdVipaPort     uint16\n\tdVipaFamily   byte\n\t_             [3]byte\n\tdestXCF       [16]byte\n\tdestXCFPfx    uint16\n\tdestXCFFamily byte\n\t_             [1]byte\n\ttargIP        [16]byte\n\ttargIPPfx     uint16\n\ttargIPFamily  byte\n\t_             [1]byte\n\t_             [20]byte\n}\n\ntype nwmRecHeader struct {\n\tident  uint32\n\tlength uint32\n\tnumber byte\n\t_      [3]byte\n}\n\ntype nwmTCPStatsEntry struct {\n\tident             uint64\n\tcurrEstab         uint32\n\tactiveOpened      uint32\n\tpassiveOpened     uint32\n\tconnClosed        uint32\n\testabResets       uint32\n\tattemptFails      uint32\n\tpassiveDrops      uint32\n\ttimeWaitReused    uint32\n\tinSegs            uint64\n\tpredictAck        uint32\n\tpredictData       uint32\n\tinDupAck          uint32\n\tinBadSum          uint32\n\tinBadLen          uint32\n\tinShort           uint32\n\tinDiscOldTime     uint32\n\tinAllBeforeWin    uint32\n\tinSomeBeforeWin   uint32\n\tinAllAfterWin     uint32\n\tinSomeAfterWin    uint32\n\tinOutOfOrder      uint32\n\tinAfterClose      uint32\n\tinWinProbes       uint32\n\tinWinUpdates      uint32\n\toutWinUpdates     uint32\n\toutSegs           uint64\n\toutDelayAcks      uint32\n\toutRsts           uint32\n\tretransSegs       uint32\n\tretransTimeouts   uint32\n\tretransDrops      uint32\n\tpmtuRetrans       uint32\n\tpmtuErrors        uint32\n\toutWinProbes      uint32\n\tprobeDrops        uint32\n\tkeepAliveProbes   uint32\n\tkeepAliveDrops    uint32\n\tfinwait2Drops     uint32\n\tacceptCount       uint64\n\tinBulkQSegs       uint64\n\tinDiscards        uint64\n\tconnFloods        uint32\n\tconnStalls        uint32\n\tcfgEphemDef       uint16\n\tephemInUse        uint16\n\tephemHiWater      uint16\n\tflags             byte\n\t_                 [1]byte\n\tephemExhaust      uint32\n\tsmcRCurrEstabLnks uint32\n\tsmcRLnkActTimeOut uint32\n\tsmcRActLnkOpened  uint32\n\tsmcRPasLnkOpened  uint32\n\tsmcRLnksClosed    uint32\n\tsmcRCurrEstab     uint32\n\tsmcRActiveOpened  uint32\n\tsmcRPassiveOpened uint32\n\tsmcRConnClosed    uint32\n\tsmcRInSegs        uint64\n\tsmcROutSegs       uint64\n\tsmcRInRsts        uint32\n\tsmcROutRsts       uint32\n\tsmcDCurrEstabLnks uint32\n\tsmcDActLnkOpened  uint32\n\tsmcDPasLnkOpened  uint32\n\tsmcDLnksClosed    uint32\n\tsmcDCurrEstab     uint32\n\tsmcDActiveOpened  uint32\n\tsmcDPassiveOpened uint32\n\tsmcDConnClosed    uint32\n\tsmcDInSegs        uint64\n\tsmcDOutSegs       uint64\n\tsmcDInRsts        uint32\n\tsmcDOutRsts       uint32\n}\n\ntype nwmConnEntry struct {\n\tident             uint32\n\tlocal             [28]byte // union of sockaddr4 and sockaddr6\n\tremote            [28]byte // union of sockaddr4 and sockaddr6\n\tstartTime         [8]byte  // uint64, changed to prevent padding from being inserted\n\tlastActivity      [8]byte  // uint64\n\tbytesIn           [8]byte  // uint64\n\tbytesOut          [8]byte  // uint64\n\tinSegs            [8]byte  // uint64\n\toutSegs           [8]byte  // uint64\n\tstate             uint16\n\tactiveOpen        byte\n\tflag01            byte\n\toutBuffered       uint32\n\tinBuffered        uint32\n\tmaxSndWnd         uint32\n\treXmtCount        uint32\n\tcongestionWnd     uint32\n\tssThresh          uint32\n\troundTripTime     uint32\n\troundTripVar      uint32\n\tsendMSS           uint32\n\tsndWnd            uint32\n\trcvBufSize        uint32\n\tsndBufSize        uint32\n\toutOfOrderCount   uint32\n\tlcl0WindowCount   uint32\n\trmt0WindowCount   uint32\n\tdupacks           uint32\n\tflag02            byte\n\tsockOpt6Cont      byte\n\tasid              uint16\n\tresourceName      [8]byte\n\tresourceId        uint32\n\tsubtask           uint32\n\tsockOpt           byte\n\tsockOpt6          byte\n\tclusterConnFlag   byte\n\tproto             byte\n\ttargetAppl        [8]byte\n\tluName            [8]byte\n\tclientUserId      [8]byte\n\tlogMode           [8]byte\n\ttimeStamp         uint32\n\ttimeStampAge      uint32\n\tserverResourceId  uint32\n\tintfName          [16]byte\n\tttlsStatPol       byte\n\tttlsStatConn      byte\n\tttlsSSLProt       uint16\n\tttlsNegCiph       [2]byte\n\tttlsSecType       byte\n\tttlsFIPS140Mode   byte\n\tttlsUserID        [8]byte\n\tapplData          [40]byte\n\tinOldestTime      [8]byte // uint64\n\toutOldestTime     [8]byte // uint64\n\ttcpTrustedPartner byte\n\t_                 [3]byte\n\tbulkDataIntfName  [16]byte\n\tttlsNegCiph4      [4]byte\n\tsmcReason         uint32\n\tlclSMCLinkId      uint32\n\trmtSMCLinkId      uint32\n\tsmcStatus         byte\n\tsmcFlags          byte\n\t_                 [2]byte\n\trcvWnd            uint32\n\tlclSMCBufSz       uint32\n\trmtSMCBufSz       uint32\n\tttlsSessID        [32]byte\n\tttlsSessIDLen     int16\n\t_                 [1]byte\n\tsmcDStatus        byte\n\tsmcDReason        uint32\n}\n\nvar svcNameTable [][]byte = [][]byte{\n\t[]byte(\"\\xc5\\xe9\\xc2\\xd5\\xd4\\xc9\\xc6\\xf4\"), // svc_EZBNMIF4\n}\n\nconst (\n\tsvc_EZBNMIF4 = 0\n)\n\nfunc GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {\n\tjobname := []byte(\"\\x5c\\x40\\x40\\x40\\x40\\x40\\x40\\x40\") // \"*\"\n\tresponseBuffer := [4096]byte{0}\n\tvar bufferAlet, reasonCode uint32 = 0, 0\n\tvar bufferLen, returnValue, returnCode int32 = 4096, 0, 0\n\n\tdsa := [18]uint64{0}\n\tvar argv [7]unsafe.Pointer\n\targv[0] = unsafe.Pointer(&jobname[0])\n\targv[1] = unsafe.Pointer(&responseBuffer[0])\n\targv[2] = unsafe.Pointer(&bufferAlet)\n\targv[3] = unsafe.Pointer(&bufferLen)\n\targv[4] = unsafe.Pointer(&returnValue)\n\targv[5] = unsafe.Pointer(&returnCode)\n\targv[6] = unsafe.Pointer(&reasonCode)\n\n\trequest := (*struct {\n\t\theader nwmHeader\n\t\tfilter nwmFilter\n\t})(unsafe.Pointer(&responseBuffer[0]))\n\n\tEZBNMIF4 := svcLoad(&svcNameTable[svc_EZBNMIF4][0])\n\tif EZBNMIF4 == nil {\n\t\treturn nil, errnoErr(EINVAL)\n\t}\n\n\t// GetGlobalStats EZBNMIF4 call\n\trequest.header.ident = nwmHeaderIdentifier\n\trequest.header.length = uint32(unsafe.Sizeof(request.header))\n\trequest.header.version = nwmCurrentVer\n\trequest.header.nwmType = nwmGlobalStatsType\n\trequest.header.options = 0x80000000\n\n\tsvcCall(EZBNMIF4, &argv[0], &dsa[0])\n\n\t// outputDesc field is filled by EZBNMIF4 on success\n\tif returnCode != 0 || request.header.outputDesc.offset == 0 {\n\t\treturn nil, errnoErr(EINVAL)\n\t}\n\n\t// Check that EZBNMIF4 returned a nwmRecHeader\n\trecHeader := (*nwmRecHeader)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))\n\tif recHeader.ident != nwmRecHeaderIdentifier {\n\t\treturn nil, errnoErr(EINVAL)\n\t}\n\n\t// Parse nwmTriplets to get offsets of returned entries\n\tvar sections []*uint64\n\tvar sectionDesc *nwmTriplet = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[0]))\n\tfor i := uint32(0); i < uint32(recHeader.number); i++ {\n\t\toffset := request.header.outputDesc.offset + uint32(unsafe.Sizeof(*recHeader)) + i*uint32(unsafe.Sizeof(*sectionDesc))\n\t\tsectionDesc = (*nwmTriplet)(unsafe.Pointer(&responseBuffer[offset]))\n\t\tfor j := uint32(0); j < sectionDesc.number; j++ {\n\t\t\toffset = request.header.outputDesc.offset + sectionDesc.offset + j*sectionDesc.length\n\t\t\tsections = append(sections, (*uint64)(unsafe.Pointer(&responseBuffer[offset])))\n\t\t}\n\t}\n\n\t// Find nwmTCPStatsEntry in returned entries\n\tvar tcpStats *nwmTCPStatsEntry = nil\n\tfor _, ptr := range sections {\n\t\tswitch *ptr {\n\t\tcase nwmTCPStatsIdentifier:\n\t\t\tif tcpStats != nil {\n\t\t\t\treturn nil, errnoErr(EINVAL)\n\t\t\t}\n\t\t\ttcpStats = (*nwmTCPStatsEntry)(unsafe.Pointer(ptr))\n\t\tcase nwmIPStatsIdentifier:\n\t\tcase nwmIPGStatsIdentifier:\n\t\tcase nwmUDPStatsIdentifier:\n\t\tcase nwmICMPGStatsEntry:\n\t\tcase nwmICMPTStatsEntry:\n\t\tdefault:\n\t\t\treturn nil, errnoErr(EINVAL)\n\t\t}\n\t}\n\tif tcpStats == nil {\n\t\treturn nil, errnoErr(EINVAL)\n\t}\n\n\t// GetConnectionDetail EZBNMIF4 call\n\tresponseBuffer = [4096]byte{0}\n\tdsa = [18]uint64{0}\n\tbufferAlet, reasonCode = 0, 0\n\tbufferLen, returnValue, returnCode = 4096, 0, 0\n\tnameptr := (*uint32)(unsafe.Pointer(uintptr(0x21c))) // Get jobname of current process\n\tnameptr = (*uint32)(unsafe.Pointer(uintptr(*nameptr + 12)))\n\targv[0] = unsafe.Pointer(uintptr(*nameptr))\n\n\trequest.header.ident = nwmHeaderIdentifier\n\trequest.header.length = uint32(unsafe.Sizeof(request.header))\n\trequest.header.version = nwmCurrentVer\n\trequest.header.nwmType = nwmTCPConnType\n\trequest.header.options = 0x80000000\n\n\trequest.filter.ident = nwmFilterIdentifier\n\n\tvar localSockaddr RawSockaddrAny\n\tsocklen := _Socklen(SizeofSockaddrAny)\n\terr := getsockname(fd, &localSockaddr, &socklen)\n\tif err != nil {\n\t\treturn nil, errnoErr(EINVAL)\n\t}\n\tif localSockaddr.Addr.Family == AF_INET {\n\t\tlocalSockaddr := (*RawSockaddrInet4)(unsafe.Pointer(&localSockaddr.Addr))\n\t\tlocalSockFilter := (*RawSockaddrInet4)(unsafe.Pointer(&request.filter.local[0]))\n\t\tlocalSockFilter.Family = AF_INET\n\t\tvar i int\n\t\tfor i = 0; i < 4; i++ {\n\t\t\tif localSockaddr.Addr[i] != 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif i != 4 {\n\t\t\trequest.filter.flags |= nwmFilterLclAddrMask\n\t\t\tfor i = 0; i < 4; i++ {\n\t\t\t\tlocalSockFilter.Addr[i] = localSockaddr.Addr[i]\n\t\t\t}\n\t\t}\n\t\tif localSockaddr.Port != 0 {\n\t\t\trequest.filter.flags |= nwmFilterLclPortMask\n\t\t\tlocalSockFilter.Port = localSockaddr.Port\n\t\t}\n\t} else if localSockaddr.Addr.Family == AF_INET6 {\n\t\tlocalSockaddr := (*RawSockaddrInet6)(unsafe.Pointer(&localSockaddr.Addr))\n\t\tlocalSockFilter := (*RawSockaddrInet6)(unsafe.Pointer(&request.filter.local[0]))\n\t\tlocalSockFilter.Family = AF_INET6\n\t\tvar i int\n\t\tfor i = 0; i < 16; i++ {\n\t\t\tif localSockaddr.Addr[i] != 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif i != 16 {\n\t\t\trequest.filter.flags |= nwmFilterLclAddrMask\n\t\t\tfor i = 0; i < 16; i++ {\n\t\t\t\tlocalSockFilter.Addr[i] = localSockaddr.Addr[i]\n\t\t\t}\n\t\t}\n\t\tif localSockaddr.Port != 0 {\n\t\t\trequest.filter.flags |= nwmFilterLclPortMask\n\t\t\tlocalSockFilter.Port = localSockaddr.Port\n\t\t}\n\t}\n\n\tsvcCall(EZBNMIF4, &argv[0], &dsa[0])\n\n\t// outputDesc field is filled by EZBNMIF4 on success\n\tif returnCode != 0 || request.header.outputDesc.offset == 0 {\n\t\treturn nil, errnoErr(EINVAL)\n\t}\n\n\t// Check that EZBNMIF4 returned a nwmConnEntry\n\tconn := (*nwmConnEntry)(unsafe.Pointer(&responseBuffer[request.header.outputDesc.offset]))\n\tif conn.ident != nwmTCPConnIdentifier {\n\t\treturn nil, errnoErr(EINVAL)\n\t}\n\n\t// Copy data from the returned data structures into tcpInfo\n\t// Stats from nwmConnEntry are specific to that connection.\n\t// Stats from nwmTCPStatsEntry are global (to the interface?)\n\t// Fields may not be an exact match. Some fields have no equivalent.\n\tvar tcpinfo TCPInfo\n\ttcpinfo.State = uint8(conn.state)\n\ttcpinfo.Ca_state = 0 // dummy\n\ttcpinfo.Retransmits = uint8(tcpStats.retransSegs)\n\ttcpinfo.Probes = uint8(tcpStats.outWinProbes)\n\ttcpinfo.Backoff = 0 // dummy\n\ttcpinfo.Options = 0 // dummy\n\ttcpinfo.Rto = tcpStats.retransTimeouts\n\ttcpinfo.Ato = tcpStats.outDelayAcks\n\ttcpinfo.Snd_mss = conn.sendMSS\n\ttcpinfo.Rcv_mss = conn.sendMSS // dummy\n\ttcpinfo.Unacked = 0            // dummy\n\ttcpinfo.Sacked = 0             // dummy\n\ttcpinfo.Lost = 0               // dummy\n\ttcpinfo.Retrans = conn.reXmtCount\n\ttcpinfo.Fackets = 0 // dummy\n\ttcpinfo.Last_data_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.lastActivity[0])))\n\ttcpinfo.Last_ack_sent = uint32(*(*uint64)(unsafe.Pointer(&conn.outOldestTime[0])))\n\ttcpinfo.Last_data_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))\n\ttcpinfo.Last_ack_recv = uint32(*(*uint64)(unsafe.Pointer(&conn.inOldestTime[0])))\n\ttcpinfo.Pmtu = conn.sendMSS // dummy, NWMIfRouteMtu is a candidate\n\ttcpinfo.Rcv_ssthresh = conn.ssThresh\n\ttcpinfo.Rtt = conn.roundTripTime\n\ttcpinfo.Rttvar = conn.roundTripVar\n\ttcpinfo.Snd_ssthresh = conn.ssThresh // dummy\n\ttcpinfo.Snd_cwnd = conn.congestionWnd\n\ttcpinfo.Advmss = conn.sendMSS        // dummy\n\ttcpinfo.Reordering = 0               // dummy\n\ttcpinfo.Rcv_rtt = conn.roundTripTime // dummy\n\ttcpinfo.Rcv_space = conn.sendMSS     // dummy\n\ttcpinfo.Total_retrans = conn.reXmtCount\n\n\tsvcUnload(&svcNameTable[svc_EZBNMIF4][0], EZBNMIF4)\n\n\treturn &tcpinfo, nil\n}\n\n// GetsockoptString returns the string value of the socket option opt for the\n// socket associated with fd at the given socket level.\nfunc GetsockoptString(fd, level, opt int) (string, error) {\n\tbuf := make([]byte, 256)\n\tvallen := _Socklen(len(buf))\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn ByteSliceToString(buf[:vallen]), nil\n}\n\nfunc Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {\n\tvar msg Msghdr\n\tvar rsa RawSockaddrAny\n\tmsg.Name = (*byte)(unsafe.Pointer(&rsa))\n\tmsg.Namelen = SizeofSockaddrAny\n\tvar iov Iovec\n\tif len(p) > 0 {\n\t\tiov.Base = (*byte)(unsafe.Pointer(&p[0]))\n\t\tiov.SetLen(len(p))\n\t}\n\tvar dummy byte\n\tif len(oob) > 0 {\n\t\t// receive at least one normal byte\n\t\tif len(p) == 0 {\n\t\t\tiov.Base = &dummy\n\t\t\tiov.SetLen(1)\n\t\t}\n\t\tmsg.Control = (*byte)(unsafe.Pointer(&oob[0]))\n\t\tmsg.SetControllen(len(oob))\n\t}\n\tmsg.Iov = &iov\n\tmsg.Iovlen = 1\n\tif n, err = recvmsg(fd, &msg, flags); err != nil {\n\t\treturn\n\t}\n\toobn = int(msg.Controllen)\n\trecvflags = int(msg.Flags)\n\t// source address is only specified if the socket is unconnected\n\tif rsa.Addr.Family != AF_UNSPEC {\n\t\t// TODO(neeilan): Remove 0 arg added to get this compiling on z/OS\n\t\tfrom, err = anyToSockaddr(0, &rsa)\n\t}\n\treturn\n}\n\nfunc Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {\n\t_, err = SendmsgN(fd, p, oob, to, flags)\n\treturn\n}\n\nfunc SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {\n\tvar ptr unsafe.Pointer\n\tvar salen _Socklen\n\tif to != nil {\n\t\tvar err error\n\t\tptr, salen, err = to.sockaddr()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t}\n\tvar msg Msghdr\n\tmsg.Name = (*byte)(unsafe.Pointer(ptr))\n\tmsg.Namelen = int32(salen)\n\tvar iov Iovec\n\tif len(p) > 0 {\n\t\tiov.Base = (*byte)(unsafe.Pointer(&p[0]))\n\t\tiov.SetLen(len(p))\n\t}\n\tvar dummy byte\n\tif len(oob) > 0 {\n\t\t// send at least one normal byte\n\t\tif len(p) == 0 {\n\t\t\tiov.Base = &dummy\n\t\t\tiov.SetLen(1)\n\t\t}\n\t\tmsg.Control = (*byte)(unsafe.Pointer(&oob[0]))\n\t\tmsg.SetControllen(len(oob))\n\t}\n\tmsg.Iov = &iov\n\tmsg.Iovlen = 1\n\tif n, err = sendmsg(fd, &msg, flags); err != nil {\n\t\treturn 0, err\n\t}\n\tif len(oob) > 0 && len(p) == 0 {\n\t\tn = 0\n\t}\n\treturn n, nil\n}\n\nfunc Opendir(name string) (uintptr, error) {\n\tp, err := BytePtrFromString(name)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\terr = nil\n\truntime.EnterSyscall()\n\tdir, e2, e1 := CallLeFuncWithPtrReturn(GetZosLibVec()+SYS___OPENDIR_A<<4, uintptr(unsafe.Pointer(p)))\n\truntime.ExitSyscall()\n\truntime.KeepAlive(unsafe.Pointer(p))\n\tif dir == 0 {\n\t\terr = errnoErr2(e1, e2)\n\t}\n\treturn dir, err\n}\n\n// clearsyscall.Errno resets the errno value to 0.\nfunc clearErrno()\n\nfunc Closedir(dir uintptr) error {\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_CLOSEDIR<<4, dir)\n\truntime.ExitSyscall()\n\tif r0 != 0 {\n\t\treturn errnoErr2(e1, e2)\n\t}\n\treturn nil\n}\n\nfunc Seekdir(dir uintptr, pos int) {\n\truntime.EnterSyscall()\n\tCallLeFuncWithErr(GetZosLibVec()+SYS_SEEKDIR<<4, dir, uintptr(pos))\n\truntime.ExitSyscall()\n}\n\nfunc Telldir(dir uintptr) (int, error) {\n\tp, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_TELLDIR<<4, dir)\n\tpos := int(p)\n\tif int64(p) == -1 {\n\t\treturn pos, errnoErr2(e1, e2)\n\t}\n\treturn pos, nil\n}\n\n// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.\nfunc FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {\n\t// struct flock is packed on z/OS. We can't emulate that in Go so\n\t// instead we pack it here.\n\tvar flock [24]byte\n\t*(*int16)(unsafe.Pointer(&flock[0])) = lk.Type\n\t*(*int16)(unsafe.Pointer(&flock[2])) = lk.Whence\n\t*(*int64)(unsafe.Pointer(&flock[4])) = lk.Start\n\t*(*int64)(unsafe.Pointer(&flock[12])) = lk.Len\n\t*(*int32)(unsafe.Pointer(&flock[20])) = lk.Pid\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCNTL<<4, fd, uintptr(cmd), uintptr(unsafe.Pointer(&flock)))\n\truntime.ExitSyscall()\n\tlk.Type = *(*int16)(unsafe.Pointer(&flock[0]))\n\tlk.Whence = *(*int16)(unsafe.Pointer(&flock[2]))\n\tlk.Start = *(*int64)(unsafe.Pointer(&flock[4]))\n\tlk.Len = *(*int64)(unsafe.Pointer(&flock[12]))\n\tlk.Pid = *(*int32)(unsafe.Pointer(&flock[20]))\n\tif r0 == 0 {\n\t\treturn nil\n\t}\n\treturn errnoErr2(e1, e2)\n}\n\nfunc impl_Flock(fd int, how int) (err error) {\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FLOCK<<4, uintptr(fd), uintptr(how))\n\truntime.ExitSyscall()\n\tif int64(r0) == -1 {\n\t\terr = errnoErr2(e1, e2)\n\t}\n\treturn\n}\n\n//go:nosplit\nfunc get_FlockAddr() *(func(fd int, how int) (err error))\n\nvar Flock = enter_Flock\n\nfunc validFlock(fp uintptr) bool {\n\tif funcptrtest(GetZosLibVec()+SYS_FLOCK<<4, \"\") == 0 {\n\t\tif name, err := getLeFuncName(GetZosLibVec() + SYS_FLOCK<<4); err == nil {\n\t\t\treturn name == \"flock\"\n\t\t}\n\t}\n\treturn false\n}\n\nfunc enter_Flock(fd int, how int) (err error) {\n\tfuncref := get_FlockAddr()\n\tif validFlock(GetZosLibVec() + SYS_FLOCK<<4) {\n\t\t*funcref = impl_Flock\n\t} else {\n\t\t*funcref = legacyFlock\n\t}\n\treturn (*funcref)(fd, how)\n}\n\nfunc legacyFlock(fd int, how int) error {\n\n\tvar flock_type int16\n\tvar fcntl_cmd int\n\n\tswitch how {\n\tcase LOCK_SH | LOCK_NB:\n\t\tflock_type = F_RDLCK\n\t\tfcntl_cmd = F_SETLK\n\tcase LOCK_EX | LOCK_NB:\n\t\tflock_type = F_WRLCK\n\t\tfcntl_cmd = F_SETLK\n\tcase LOCK_EX:\n\t\tflock_type = F_WRLCK\n\t\tfcntl_cmd = F_SETLKW\n\tcase LOCK_UN:\n\t\tflock_type = F_UNLCK\n\t\tfcntl_cmd = F_SETLKW\n\tdefault:\n\t}\n\n\tflock := Flock_t{\n\t\tType:   int16(flock_type),\n\t\tWhence: int16(0),\n\t\tStart:  int64(0),\n\t\tLen:    int64(0),\n\t\tPid:    int32(Getppid()),\n\t}\n\n\terr := FcntlFlock(uintptr(fd), fcntl_cmd, &flock)\n\treturn err\n}\n\nfunc Mlock(b []byte) (err error) {\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)\n\truntime.ExitSyscall()\n\tif r0 != 0 {\n\t\terr = errnoErr2(e1, e2)\n\t}\n\treturn\n}\n\nfunc Mlock2(b []byte, flags int) (err error) {\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)\n\truntime.ExitSyscall()\n\tif r0 != 0 {\n\t\terr = errnoErr2(e1, e2)\n\t}\n\treturn\n}\n\nfunc Mlockall(flags int) (err error) {\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_NONSWAP)\n\truntime.ExitSyscall()\n\tif r0 != 0 {\n\t\terr = errnoErr2(e1, e2)\n\t}\n\treturn\n}\n\nfunc Munlock(b []byte) (err error) {\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_SWAP)\n\truntime.ExitSyscall()\n\tif r0 != 0 {\n\t\terr = errnoErr2(e1, e2)\n\t}\n\treturn\n}\n\nfunc Munlockall() (err error) {\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MLOCKALL<<4, _BPX_SWAP)\n\truntime.ExitSyscall()\n\tif r0 != 0 {\n\t\terr = errnoErr2(e1, e2)\n\t}\n\treturn\n}\n\nfunc ClockGettime(clockid int32, ts *Timespec) error {\n\n\tvar ticks_per_sec uint32 = 100 //TODO(kenan): value is currently hardcoded; need sysconf() call otherwise\n\tvar nsec_per_sec int64 = 1000000000\n\n\tif ts == nil {\n\t\treturn EFAULT\n\t}\n\tif clockid == CLOCK_REALTIME || clockid == CLOCK_MONOTONIC {\n\t\tvar nanotime int64 = runtime.Nanotime1()\n\t\tts.Sec = nanotime / nsec_per_sec\n\t\tts.Nsec = nanotime % nsec_per_sec\n\t} else if clockid == CLOCK_PROCESS_CPUTIME_ID || clockid == CLOCK_THREAD_CPUTIME_ID {\n\t\tvar tm Tms\n\t\t_, err := Times(&tm)\n\t\tif err != nil {\n\t\t\treturn EFAULT\n\t\t}\n\t\tts.Sec = int64(tm.Utime / ticks_per_sec)\n\t\tts.Nsec = int64(tm.Utime) * nsec_per_sec / int64(ticks_per_sec)\n\t} else {\n\t\treturn EINVAL\n\t}\n\treturn nil\n}\n\n// Chtag\n\n//go:nosplit\nfunc get_ChtagAddr() *(func(path string, ccsid uint64, textbit uint64) error)\n\nvar Chtag = enter_Chtag\n\nfunc enter_Chtag(path string, ccsid uint64, textbit uint64) error {\n\tfuncref := get_ChtagAddr()\n\tif validSetxattr() {\n\t\t*funcref = impl_Chtag\n\t} else {\n\t\t*funcref = legacy_Chtag\n\t}\n\treturn (*funcref)(path, ccsid, textbit)\n}\n\nfunc legacy_Chtag(path string, ccsid uint64, textbit uint64) error {\n\ttag := ccsid<<16 | textbit<<15\n\tvar tag_buff [8]byte\n\tDecodeData(tag_buff[:], 8, tag)\n\treturn Setxattr(path, \"filetag\", tag_buff[:], XATTR_REPLACE)\n}\n\nfunc impl_Chtag(path string, ccsid uint64, textbit uint64) error {\n\ttag := ccsid<<16 | textbit<<15\n\tvar tag_buff [4]byte\n\tDecodeData(tag_buff[:], 4, tag)\n\treturn Setxattr(path, \"system.filetag\", tag_buff[:], XATTR_REPLACE)\n}\n\n// End of Chtag\n\n// Nanosleep\n\n//go:nosplit\nfunc get_NanosleepAddr() *(func(time *Timespec, leftover *Timespec) error)\n\nvar Nanosleep = enter_Nanosleep\n\nfunc enter_Nanosleep(time *Timespec, leftover *Timespec) error {\n\tfuncref := get_NanosleepAddr()\n\tif funcptrtest(GetZosLibVec()+SYS_NANOSLEEP<<4, \"\") == 0 {\n\t\t*funcref = impl_Nanosleep\n\t} else {\n\t\t*funcref = legacyNanosleep\n\t}\n\treturn (*funcref)(time, leftover)\n}\n\nfunc impl_Nanosleep(time *Timespec, leftover *Timespec) error {\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_NANOSLEEP<<4, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)))\n\truntime.ExitSyscall()\n\tif int64(r0) == -1 {\n\t\treturn errnoErr2(e1, e2)\n\t}\n\treturn nil\n}\n\nfunc legacyNanosleep(time *Timespec, leftover *Timespec) error {\n\tt0 := runtime.Nanotime1()\n\tvar secrem uint32\n\tvar nsecrem uint32\n\ttotal := time.Sec*1000000000 + time.Nsec\n\telapsed := runtime.Nanotime1() - t0\n\tvar rv int32\n\tvar rc int32\n\tvar err error\n\t// repeatedly sleep for 1 second until less than 1 second left\n\tfor total-elapsed > 1000000000 {\n\t\trv, rc, _ = BpxCondTimedWait(uint32(1), uint32(0), uint32(CW_CONDVAR), &secrem, &nsecrem)\n\t\tif rv != 0 && rc != 112 { // 112 is EAGAIN\n\t\t\tif leftover != nil && rc == 120 { // 120 is EINTR\n\t\t\t\tleftover.Sec = int64(secrem)\n\t\t\t\tleftover.Nsec = int64(nsecrem)\n\t\t\t}\n\t\t\terr = Errno(rc)\n\t\t\treturn err\n\t\t}\n\t\telapsed = runtime.Nanotime1() - t0\n\t}\n\t// sleep the remainder\n\tif total > elapsed {\n\t\trv, rc, _ = BpxCondTimedWait(uint32(0), uint32(total-elapsed), uint32(CW_CONDVAR), &secrem, &nsecrem)\n\t}\n\tif leftover != nil && rc == 120 {\n\t\tleftover.Sec = int64(secrem)\n\t\tleftover.Nsec = int64(nsecrem)\n\t}\n\tif rv != 0 && rc != 112 {\n\t\terr = Errno(rc)\n\t}\n\treturn err\n}\n\n// End of Nanosleep\n\nvar (\n\tStdin  = 0\n\tStdout = 1\n\tStderr = 2\n)\n\n// Do the interface allocations only once for common\n// Errno values.\nvar (\n\terrEAGAIN error = syscall.EAGAIN\n\terrEINVAL error = syscall.EINVAL\n\terrENOENT error = syscall.ENOENT\n)\n\nvar ZosTraceLevel int\nvar ZosTracefile *os.File\n\nvar (\n\tsignalNameMapOnce sync.Once\n\tsignalNameMap     map[string]syscall.Signal\n)\n\n// errnoErr returns common boxed Errno values, to prevent\n// allocations at runtime.\nfunc errnoErr(e Errno) error {\n\tswitch e {\n\tcase 0:\n\t\treturn nil\n\tcase EAGAIN:\n\t\treturn errEAGAIN\n\tcase EINVAL:\n\t\treturn errEINVAL\n\tcase ENOENT:\n\t\treturn errENOENT\n\t}\n\treturn e\n}\n\nvar reg *regexp.Regexp\n\n// enhanced with zos specific errno2\nfunc errnoErr2(e Errno, e2 uintptr) error {\n\tswitch e {\n\tcase 0:\n\t\treturn nil\n\tcase EAGAIN:\n\t\treturn errEAGAIN\n\t\t/*\n\t\t\tAllow the retrieval of errno2 for EINVAL and ENOENT on zos\n\t\t\t\tcase EINVAL:\n\t\t\t\t\treturn errEINVAL\n\t\t\t\tcase ENOENT:\n\t\t\t\t\treturn errENOENT\n\t\t*/\n\t}\n\tif ZosTraceLevel > 0 {\n\t\tvar name string\n\t\tif reg == nil {\n\t\t\treg = regexp.MustCompile(\"(^unix\\\\.[^/]+$|.*\\\\/unix\\\\.[^/]+$)\")\n\t\t}\n\t\ti := 1\n\t\tpc, file, line, ok := runtime.Caller(i)\n\t\tif ok {\n\t\t\tname = runtime.FuncForPC(pc).Name()\n\t\t}\n\t\tfor ok && reg.MatchString(runtime.FuncForPC(pc).Name()) {\n\t\t\ti += 1\n\t\t\tpc, file, line, ok = runtime.Caller(i)\n\t\t}\n\t\tif ok {\n\t\t\tif ZosTracefile == nil {\n\t\t\t\tZosConsolePrintf(\"From %s:%d\\n\", file, line)\n\t\t\t\tZosConsolePrintf(\"%s: %s (errno2=0x%x)\\n\", name, e.Error(), e2)\n\t\t\t} else {\n\t\t\t\tfmt.Fprintf(ZosTracefile, \"From %s:%d\\n\", file, line)\n\t\t\t\tfmt.Fprintf(ZosTracefile, \"%s: %s (errno2=0x%x)\\n\", name, e.Error(), e2)\n\t\t\t}\n\t\t} else {\n\t\t\tif ZosTracefile == nil {\n\t\t\t\tZosConsolePrintf(\"%s (errno2=0x%x)\\n\", e.Error(), e2)\n\t\t\t} else {\n\t\t\t\tfmt.Fprintf(ZosTracefile, \"%s (errno2=0x%x)\\n\", e.Error(), e2)\n\t\t\t}\n\t\t}\n\t}\n\treturn e\n}\n\n// ErrnoName returns the error name for error number e.\nfunc ErrnoName(e Errno) string {\n\ti := sort.Search(len(errorList), func(i int) bool {\n\t\treturn errorList[i].num >= e\n\t})\n\tif i < len(errorList) && errorList[i].num == e {\n\t\treturn errorList[i].name\n\t}\n\treturn \"\"\n}\n\n// SignalName returns the signal name for signal number s.\nfunc SignalName(s syscall.Signal) string {\n\ti := sort.Search(len(signalList), func(i int) bool {\n\t\treturn signalList[i].num >= s\n\t})\n\tif i < len(signalList) && signalList[i].num == s {\n\t\treturn signalList[i].name\n\t}\n\treturn \"\"\n}\n\n// SignalNum returns the syscall.Signal for signal named s,\n// or 0 if a signal with such name is not found.\n// The signal name should start with \"SIG\".\nfunc SignalNum(s string) syscall.Signal {\n\tsignalNameMapOnce.Do(func() {\n\t\tsignalNameMap = make(map[string]syscall.Signal, len(signalList))\n\t\tfor _, signal := range signalList {\n\t\t\tsignalNameMap[signal.name] = signal.num\n\t\t}\n\t})\n\treturn signalNameMap[s]\n}\n\n// clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.\nfunc clen(n []byte) int {\n\ti := bytes.IndexByte(n, 0)\n\tif i == -1 {\n\t\ti = len(n)\n\t}\n\treturn i\n}\n\n// Mmap manager, for use by operating system-specific implementations.\n\ntype mmapper struct {\n\tsync.Mutex\n\tactive map[*byte][]byte // active mappings; key is last byte in mapping\n\tmmap   func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)\n\tmunmap func(addr uintptr, length uintptr) error\n}\n\nfunc (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {\n\tif length <= 0 {\n\t\treturn nil, EINVAL\n\t}\n\n\t// Set __MAP_64 by default\n\tflags |= __MAP_64\n\n\t// Map the requested memory.\n\taddr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)\n\tif errno != nil {\n\t\treturn nil, errno\n\t}\n\n\t// Slice memory layout\n\tvar sl = struct {\n\t\taddr uintptr\n\t\tlen  int\n\t\tcap  int\n\t}{addr, length, length}\n\n\t// Use unsafe to turn sl into a []byte.\n\tb := *(*[]byte)(unsafe.Pointer(&sl))\n\n\t// Register mapping in m and return it.\n\tp := &b[cap(b)-1]\n\tm.Lock()\n\tdefer m.Unlock()\n\tm.active[p] = b\n\treturn b, nil\n}\n\nfunc (m *mmapper) Munmap(data []byte) (err error) {\n\tif len(data) == 0 || len(data) != cap(data) {\n\t\treturn EINVAL\n\t}\n\n\t// Find the base of the mapping.\n\tp := &data[cap(data)-1]\n\tm.Lock()\n\tdefer m.Unlock()\n\tb := m.active[p]\n\tif b == nil || &b[0] != &data[0] {\n\t\treturn EINVAL\n\t}\n\n\t// Unmap the memory and update m.\n\tif errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {\n\t\treturn errno\n\t}\n\tdelete(m.active, p)\n\treturn nil\n}\n\nfunc Read(fd int, p []byte) (n int, err error) {\n\tn, err = read(fd, p)\n\tif raceenabled {\n\t\tif n > 0 {\n\t\t\traceWriteRange(unsafe.Pointer(&p[0]), n)\n\t\t}\n\t\tif err == nil {\n\t\t\traceAcquire(unsafe.Pointer(&ioSync))\n\t\t}\n\t}\n\treturn\n}\n\nfunc Write(fd int, p []byte) (n int, err error) {\n\tif raceenabled {\n\t\traceReleaseMerge(unsafe.Pointer(&ioSync))\n\t}\n\tn, err = write(fd, p)\n\tif raceenabled && n > 0 {\n\t\traceReadRange(unsafe.Pointer(&p[0]), n)\n\t}\n\treturn\n}\n\n// For testing: clients can set this flag to force\n// creation of IPv6 sockets to return EAFNOSUPPORT.\nvar SocketDisableIPv6 bool\n\n// Sockaddr represents a socket address.\ntype Sockaddr interface {\n\tsockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs\n}\n\n// SockaddrInet4 implements the Sockaddr interface for AF_INET type sockets.\ntype SockaddrInet4 struct {\n\tPort int\n\tAddr [4]byte\n\traw  RawSockaddrInet4\n}\n\n// SockaddrInet6 implements the Sockaddr interface for AF_INET6 type sockets.\ntype SockaddrInet6 struct {\n\tPort   int\n\tZoneId uint32\n\tAddr   [16]byte\n\traw    RawSockaddrInet6\n}\n\n// SockaddrUnix implements the Sockaddr interface for AF_UNIX type sockets.\ntype SockaddrUnix struct {\n\tName string\n\traw  RawSockaddrUnix\n}\n\nfunc Bind(fd int, sa Sockaddr) (err error) {\n\tptr, n, err := sa.sockaddr()\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn bind(fd, ptr, n)\n}\n\nfunc Connect(fd int, sa Sockaddr) (err error) {\n\tptr, n, err := sa.sockaddr()\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn connect(fd, ptr, n)\n}\n\nfunc Getpeername(fd int) (sa Sockaddr, err error) {\n\tvar rsa RawSockaddrAny\n\tvar len _Socklen = SizeofSockaddrAny\n\tif err = getpeername(fd, &rsa, &len); err != nil {\n\t\treturn\n\t}\n\treturn anyToSockaddr(fd, &rsa)\n}\n\nfunc GetsockoptByte(fd, level, opt int) (value byte, err error) {\n\tvar n byte\n\tvallen := _Socklen(1)\n\terr = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)\n\treturn n, err\n}\n\nfunc GetsockoptInt(fd, level, opt int) (value int, err error) {\n\tvar n int32\n\tvallen := _Socklen(4)\n\terr = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)\n\treturn int(n), err\n}\n\nfunc GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {\n\tvallen := _Socklen(4)\n\terr = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)\n\treturn value, err\n}\n\nfunc GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {\n\tvar value IPMreq\n\tvallen := _Socklen(SizeofIPMreq)\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)\n\treturn &value, err\n}\n\nfunc GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {\n\tvar value IPv6Mreq\n\tvallen := _Socklen(SizeofIPv6Mreq)\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)\n\treturn &value, err\n}\n\nfunc GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {\n\tvar value IPv6MTUInfo\n\tvallen := _Socklen(SizeofIPv6MTUInfo)\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)\n\treturn &value, err\n}\n\nfunc GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {\n\tvar value ICMPv6Filter\n\tvallen := _Socklen(SizeofICMPv6Filter)\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)\n\treturn &value, err\n}\n\nfunc GetsockoptLinger(fd, level, opt int) (*Linger, error) {\n\tvar linger Linger\n\tvallen := _Socklen(SizeofLinger)\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&linger), &vallen)\n\treturn &linger, err\n}\n\nfunc GetsockoptTimeval(fd, level, opt int) (*Timeval, error) {\n\tvar tv Timeval\n\tvallen := _Socklen(unsafe.Sizeof(tv))\n\terr := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen)\n\treturn &tv, err\n}\n\nfunc GetsockoptUint64(fd, level, opt int) (value uint64, err error) {\n\tvar n uint64\n\tvallen := _Socklen(8)\n\terr = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)\n\treturn n, err\n}\n\nfunc Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {\n\tvar rsa RawSockaddrAny\n\tvar len _Socklen = SizeofSockaddrAny\n\tif n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {\n\t\treturn\n\t}\n\tif rsa.Addr.Family != AF_UNSPEC {\n\t\tfrom, err = anyToSockaddr(fd, &rsa)\n\t}\n\treturn\n}\n\nfunc Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {\n\tptr, n, err := to.sockaddr()\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn sendto(fd, p, flags, ptr, n)\n}\n\nfunc SetsockoptByte(fd, level, opt int, value byte) (err error) {\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)\n}\n\nfunc SetsockoptInt(fd, level, opt int, value int) (err error) {\n\tvar n = int32(value)\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)\n}\n\nfunc SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)\n}\n\nfunc SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)\n}\n\nfunc SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)\n}\n\nfunc SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)\n}\n\nfunc SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)\n}\n\nfunc SetsockoptString(fd, level, opt int, s string) (err error) {\n\tvar p unsafe.Pointer\n\tif len(s) > 0 {\n\t\tp = unsafe.Pointer(&[]byte(s)[0])\n\t}\n\treturn setsockopt(fd, level, opt, p, uintptr(len(s)))\n}\n\nfunc SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))\n}\n\nfunc SetsockoptUint64(fd, level, opt int, value uint64) (err error) {\n\treturn setsockopt(fd, level, opt, unsafe.Pointer(&value), 8)\n}\n\nfunc Socket(domain, typ, proto int) (fd int, err error) {\n\tif domain == AF_INET6 && SocketDisableIPv6 {\n\t\treturn -1, EAFNOSUPPORT\n\t}\n\tfd, err = socket(domain, typ, proto)\n\treturn\n}\n\nfunc Socketpair(domain, typ, proto int) (fd [2]int, err error) {\n\tvar fdx [2]int32\n\terr = socketpair(domain, typ, proto, &fdx)\n\tif err == nil {\n\t\tfd[0] = int(fdx[0])\n\t\tfd[1] = int(fdx[1])\n\t}\n\treturn\n}\n\nvar ioSync int64\n\nfunc CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }\n\nfunc SetNonblock(fd int, nonblocking bool) (err error) {\n\tflag, err := fcntl(fd, F_GETFL, 0)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif nonblocking {\n\t\tflag |= O_NONBLOCK\n\t} else {\n\t\tflag &= ^O_NONBLOCK\n\t}\n\t_, err = fcntl(fd, F_SETFL, flag)\n\treturn err\n}\n\n// Exec calls execve(2), which replaces the calling executable in the process\n// tree. argv0 should be the full path to an executable (\"/bin/ls\") and the\n// executable name should also be the first argument in argv ([\"ls\", \"-l\"]).\n// envv are the environment variables that should be passed to the new\n// process ([\"USER=go\", \"PWD=/tmp\"]).\nfunc Exec(argv0 string, argv []string, envv []string) error {\n\treturn syscall.Exec(argv0, argv, envv)\n}\n\nfunc Getag(path string) (ccsid uint16, flag uint16, err error) {\n\tvar val [8]byte\n\tsz, err := Getxattr(path, \"ccsid\", val[:])\n\tif err != nil {\n\t\treturn\n\t}\n\tccsid = uint16(EncodeData(val[0:sz]))\n\tsz, err = Getxattr(path, \"flags\", val[:])\n\tif err != nil {\n\t\treturn\n\t}\n\tflag = uint16(EncodeData(val[0:sz]) >> 15)\n\treturn\n}\n\n// Mount begin\nfunc impl_Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(source)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 *byte\n\t_p1, err = BytePtrFromString(target)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p2 *byte\n\t_p2, err = BytePtrFromString(fstype)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p3 *byte\n\t_p3, err = BytePtrFromString(data)\n\tif err != nil {\n\t\treturn\n\t}\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MOUNT1_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(_p3)))\n\truntime.ExitSyscall()\n\tif int64(r0) == -1 {\n\t\terr = errnoErr2(e1, e2)\n\t}\n\treturn\n}\n\n//go:nosplit\nfunc get_MountAddr() *(func(source string, target string, fstype string, flags uintptr, data string) (err error))\n\nvar Mount = enter_Mount\n\nfunc enter_Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {\n\tfuncref := get_MountAddr()\n\tif validMount() {\n\t\t*funcref = impl_Mount\n\t} else {\n\t\t*funcref = legacyMount\n\t}\n\treturn (*funcref)(source, target, fstype, flags, data)\n}\n\nfunc legacyMount(source string, target string, fstype string, flags uintptr, data string) (err error) {\n\tif needspace := 8 - len(fstype); needspace <= 0 {\n\t\tfstype = fstype[0:8]\n\t} else {\n\t\tfstype += \"        \"[0:needspace]\n\t}\n\treturn mount_LE(target, source, fstype, uint32(flags), int32(len(data)), data)\n}\n\nfunc validMount() bool {\n\tif funcptrtest(GetZosLibVec()+SYS___MOUNT1_A<<4, \"\") == 0 {\n\t\tif name, err := getLeFuncName(GetZosLibVec() + SYS___MOUNT1_A<<4); err == nil {\n\t\t\treturn name == \"__mount1_a\"\n\t\t}\n\t}\n\treturn false\n}\n\n// Mount end\n\n// Unmount begin\nfunc impl_Unmount(target string, flags int) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(target)\n\tif err != nil {\n\t\treturn\n\t}\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___UMOUNT2_A<<4, uintptr(unsafe.Pointer(_p0)), uintptr(flags))\n\truntime.ExitSyscall()\n\tif int64(r0) == -1 {\n\t\terr = errnoErr2(e1, e2)\n\t}\n\treturn\n}\n\n//go:nosplit\nfunc get_UnmountAddr() *(func(target string, flags int) (err error))\n\nvar Unmount = enter_Unmount\n\nfunc enter_Unmount(target string, flags int) (err error) {\n\tfuncref := get_UnmountAddr()\n\tif funcptrtest(GetZosLibVec()+SYS___UMOUNT2_A<<4, \"\") == 0 {\n\t\t*funcref = impl_Unmount\n\t} else {\n\t\t*funcref = legacyUnmount\n\t}\n\treturn (*funcref)(target, flags)\n}\n\nfunc legacyUnmount(name string, mtm int) (err error) {\n\t// mountpoint is always a full path and starts with a '/'\n\t// check if input string is not a mountpoint but a filesystem name\n\tif name[0] != '/' {\n\t\treturn unmount_LE(name, mtm)\n\t}\n\t// treat name as mountpoint\n\tb2s := func(arr []byte) string {\n\t\tvar str string\n\t\tfor i := 0; i < len(arr); i++ {\n\t\t\tif arr[i] == 0 {\n\t\t\t\tstr = string(arr[:i])\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\treturn str\n\t}\n\tvar buffer struct {\n\t\theader W_Mnth\n\t\tfsinfo [64]W_Mntent\n\t}\n\tfs_count, err := W_Getmntent_A((*byte)(unsafe.Pointer(&buffer)), int(unsafe.Sizeof(buffer)))\n\tif err == nil {\n\t\terr = EINVAL\n\t\tfor i := 0; i < fs_count; i++ {\n\t\t\tif b2s(buffer.fsinfo[i].Mountpoint[:]) == name {\n\t\t\t\terr = unmount_LE(b2s(buffer.fsinfo[i].Fsname[:]), mtm)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t} else if fs_count == 0 {\n\t\terr = EINVAL\n\t}\n\treturn err\n}\n\n// Unmount end\n\nfunc direntIno(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))\n}\n\nfunc direntReclen(buf []byte) (uint64, bool) {\n\treturn readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))\n}\n\nfunc direntNamlen(buf []byte) (uint64, bool) {\n\treclen, ok := direntReclen(buf)\n\tif !ok {\n\t\treturn 0, false\n\t}\n\treturn reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true\n}\n\nfunc direntLeToDirentUnix(dirent *direntLE, dir uintptr, path string) (Dirent, error) {\n\tvar d Dirent\n\n\td.Ino = uint64(dirent.Ino)\n\toffset, err := Telldir(dir)\n\tif err != nil {\n\t\treturn d, err\n\t}\n\n\td.Off = int64(offset)\n\ts := string(bytes.Split(dirent.Name[:], []byte{0})[0])\n\tcopy(d.Name[:], s)\n\n\td.Reclen = uint16(24 + len(d.NameString()))\n\tvar st Stat_t\n\tpath = path + \"/\" + s\n\terr = Lstat(path, &st)\n\tif err != nil {\n\t\treturn d, err\n\t}\n\n\td.Type = uint8(st.Mode >> 24)\n\treturn d, err\n}\n\nfunc Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {\n\t// Simulation of Getdirentries port from the Darwin implementation.\n\t// COMMENTS FROM DARWIN:\n\t// It's not the full required semantics, but should handle the case\n\t// of calling Getdirentries or ReadDirent repeatedly.\n\t// It won't handle assigning the results of lseek to *basep, or handle\n\t// the directory being edited underfoot.\n\n\tskip, err := Seek(fd, 0, 1 /* SEEK_CUR */)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\t// Get path from fd to avoid unavailable call (fdopendir)\n\tpath, err := ZosFdToPath(fd)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\td, err := Opendir(path)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tdefer Closedir(d)\n\n\tvar cnt int64\n\tfor {\n\t\tvar entryLE direntLE\n\t\tvar entrypLE *direntLE\n\t\te := Readdir_r(d, &entryLE, &entrypLE)\n\t\tif e != nil {\n\t\t\treturn n, e\n\t\t}\n\t\tif entrypLE == nil {\n\t\t\tbreak\n\t\t}\n\t\tif skip > 0 {\n\t\t\tskip--\n\t\t\tcnt++\n\t\t\tcontinue\n\t\t}\n\n\t\t// Dirent on zos has a different structure\n\t\tentry, e := direntLeToDirentUnix(&entryLE, d, path)\n\t\tif e != nil {\n\t\t\treturn n, e\n\t\t}\n\n\t\treclen := int(entry.Reclen)\n\t\tif reclen > len(buf) {\n\t\t\t// Not enough room. Return for now.\n\t\t\t// The counter will let us know where we should start up again.\n\t\t\t// Note: this strategy for suspending in the middle and\n\t\t\t// restarting is O(n^2) in the length of the directory. Oh well.\n\t\t\tbreak\n\t\t}\n\n\t\t// Copy entry into return buffer.\n\t\ts := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)\n\t\tcopy(buf, s)\n\n\t\tbuf = buf[reclen:]\n\t\tn += reclen\n\t\tcnt++\n\t}\n\t// Set the seek offset of the input fd to record\n\t// how many files we've already returned.\n\t_, err = Seek(fd, cnt, 0 /* SEEK_SET */)\n\tif err != nil {\n\t\treturn n, err\n\t}\n\n\treturn n, nil\n}\n\nfunc Err2ad() (eadd *int) {\n\tr0, _, _ := CallLeFuncWithErr(GetZosLibVec() + SYS___ERR2AD<<4)\n\teadd = (*int)(unsafe.Pointer(r0))\n\treturn\n}\n\nfunc ZosConsolePrintf(format string, v ...interface{}) (int, error) {\n\ttype __cmsg struct {\n\t\t_            uint16\n\t\t_            [2]uint8\n\t\t__msg_length uint32\n\t\t__msg        uintptr\n\t\t_            [4]uint8\n\t}\n\tmsg := fmt.Sprintf(format, v...)\n\tstrptr := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&msg)).Data)\n\tlen := (*reflect.StringHeader)(unsafe.Pointer(&msg)).Len\n\tcmsg := __cmsg{__msg_length: uint32(len), __msg: uintptr(strptr)}\n\tcmd := uint32(0)\n\truntime.EnterSyscall()\n\trc, err2, err1 := CallLeFuncWithErr(GetZosLibVec()+SYS_____CONSOLE_A<<4, uintptr(unsafe.Pointer(&cmsg)), 0, uintptr(unsafe.Pointer(&cmd)))\n\truntime.ExitSyscall()\n\tif rc != 0 {\n\t\treturn 0, fmt.Errorf(\"%s (errno2=0x%x)\\n\", err1.Error(), err2)\n\t}\n\treturn 0, nil\n}\nfunc ZosStringToEbcdicBytes(str string, nullterm bool) (ebcdicBytes []byte) {\n\tif nullterm {\n\t\tebcdicBytes = []byte(str + \"\\x00\")\n\t} else {\n\t\tebcdicBytes = []byte(str)\n\t}\n\tA2e(ebcdicBytes)\n\treturn\n}\nfunc ZosEbcdicBytesToString(b []byte, trimRight bool) (str string) {\n\tres := make([]byte, len(b))\n\tcopy(res, b)\n\tE2a(res)\n\tif trimRight {\n\t\tstr = string(bytes.TrimRight(res, \" \\x00\"))\n\t} else {\n\t\tstr = string(res)\n\t}\n\treturn\n}\n\nfunc fdToPath(dirfd int) (path string, err error) {\n\tvar buffer [1024]byte\n\t// w_ctrl()\n\tret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_W_IOCTL<<4,\n\t\t[]uintptr{uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0]))})\n\tif ret == 0 {\n\t\tzb := bytes.IndexByte(buffer[:], 0)\n\t\tif zb == -1 {\n\t\t\tzb = len(buffer)\n\t\t}\n\t\t// __e2a_l()\n\t\truntime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,\n\t\t\t[]uintptr{uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb)})\n\t\treturn string(buffer[:zb]), nil\n\t}\n\t// __errno()\n\terrno := int(*(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4,\n\t\t[]uintptr{}))))\n\t// __errno2()\n\terrno2 := int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO2<<4,\n\t\t[]uintptr{}))\n\t// strerror_r()\n\tret = runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_STRERROR_R<<4,\n\t\t[]uintptr{uintptr(errno), uintptr(unsafe.Pointer(&buffer[0])), 1024})\n\tif ret == 0 {\n\t\tzb := bytes.IndexByte(buffer[:], 0)\n\t\tif zb == -1 {\n\t\t\tzb = len(buffer)\n\t\t}\n\t\treturn \"\", fmt.Errorf(\"%s (errno2=0x%x)\", buffer[:zb], errno2)\n\t} else {\n\t\treturn \"\", fmt.Errorf(\"fdToPath errno %d (errno2=0x%x)\", errno, errno2)\n\t}\n}\n\nfunc impl_Mkfifoat(dirfd int, path string, mode uint32) (err error) {\n\tvar _p0 *byte\n\t_p0, err = BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MKFIFOAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))\n\truntime.ExitSyscall()\n\tif int64(r0) == -1 {\n\t\terr = errnoErr2(e1, e2)\n\t}\n\treturn\n}\n\n//go:nosplit\nfunc get_MkfifoatAddr() *(func(dirfd int, path string, mode uint32) (err error))\n\nvar Mkfifoat = enter_Mkfifoat\n\nfunc enter_Mkfifoat(dirfd int, path string, mode uint32) (err error) {\n\tfuncref := get_MkfifoatAddr()\n\tif funcptrtest(GetZosLibVec()+SYS___MKFIFOAT_A<<4, \"\") == 0 {\n\t\t*funcref = impl_Mkfifoat\n\t} else {\n\t\t*funcref = legacy_Mkfifoat\n\t}\n\treturn (*funcref)(dirfd, path, mode)\n}\n\nfunc legacy_Mkfifoat(dirfd int, path string, mode uint32) (err error) {\n\tdirname, err := ZosFdToPath(dirfd)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn Mkfifo(dirname+\"/\"+path, mode)\n}\n\n//sys\tPosix_openpt(oflag int) (fd int, err error) = SYS_POSIX_OPENPT\n//sys\tGrantpt(fildes int) (rc int, err error) = SYS_GRANTPT\n//sys\tUnlockpt(fildes int) (rc int, err error) = SYS_UNLOCKPT\n\nfunc fcntlAsIs(fd uintptr, cmd int, arg uintptr) (val int, err error) {\n\truntime.EnterSyscall()\n\tr0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCNTL<<4, uintptr(fd), uintptr(cmd), arg)\n\truntime.ExitSyscall()\n\tval = int(r0)\n\tif int64(r0) == -1 {\n\t\terr = errnoErr2(e1, e2)\n\t}\n\treturn\n}\n\nfunc Fcntl(fd uintptr, cmd int, op interface{}) (ret int, err error) {\n\tswitch op.(type) {\n\tcase *Flock_t:\n\t\terr = FcntlFlock(fd, cmd, op.(*Flock_t))\n\t\tif err != nil {\n\t\t\tret = -1\n\t\t}\n\t\treturn\n\tcase int:\n\t\treturn FcntlInt(fd, cmd, op.(int))\n\tcase *F_cnvrt:\n\t\treturn fcntlAsIs(fd, cmd, uintptr(unsafe.Pointer(op.(*F_cnvrt))))\n\tcase unsafe.Pointer:\n\t\treturn fcntlAsIs(fd, cmd, uintptr(op.(unsafe.Pointer)))\n\tdefault:\n\t\treturn -1, EINVAL\n\t}\n\treturn\n}\n\nfunc Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\tif raceenabled {\n\t\traceReleaseMerge(unsafe.Pointer(&ioSync))\n\t}\n\treturn sendfile(outfd, infd, offset, count)\n}\n\nfunc sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {\n\t// TODO: use LE call instead if the call is implemented\n\toriginalOffset, err := Seek(infd, 0, SEEK_CUR)\n\tif err != nil {\n\t\treturn -1, err\n\t}\n\t//start reading data from in_fd\n\tif offset != nil {\n\t\t_, err := Seek(infd, *offset, SEEK_SET)\n\t\tif err != nil {\n\t\t\treturn -1, err\n\t\t}\n\t}\n\n\tbuf := make([]byte, count)\n\treadBuf := make([]byte, 0)\n\tvar n int = 0\n\tfor i := 0; i < count; i += n {\n\t\tn, err := Read(infd, buf)\n\t\tif n == 0 {\n\t\t\tif err != nil {\n\t\t\t\treturn -1, err\n\t\t\t} else { // EOF\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\treadBuf = append(readBuf, buf...)\n\t\tbuf = buf[0:0]\n\t}\n\n\tn2, err := Write(outfd, readBuf)\n\tif err != nil {\n\t\treturn -1, err\n\t}\n\n\t//When sendfile() returns, this variable will be set to the\n\t// offset of the byte following the last byte that was read.\n\tif offset != nil {\n\t\t*offset = *offset + int64(n)\n\t\t// If offset is not NULL, then sendfile() does not modify the file\n\t\t// offset of in_fd\n\t\t_, err := Seek(infd, originalOffset, SEEK_SET)\n\t\tif err != nil {\n\t\t\treturn -1, err\n\t\t}\n\t}\n\treturn n2, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/sys/unix/unveil_openbsd.go",
    "content": "// Copyright 2018 The Go 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 unix\n\nimport \"fmt\"\n\n// Unveil implements the unveil syscall.\n// For more information see unveil(2).\n// Note that the special case of blocking further\n// unveil calls is handled by UnveilBlock.\nfunc Unveil(path string, flags string) error {\n\tif err := supportsUnveil(); err != nil {\n\t\treturn err\n\t}\n\tpathPtr, err := BytePtrFromString(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\tflagsPtr, err := BytePtrFromString(flags)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn unveil(pathPtr, flagsPtr)\n}\n\n// UnveilBlock blocks future unveil calls.\n// For more information see unveil(2).\nfunc UnveilBlock() error {\n\tif err := supportsUnveil(); err != nil {\n\t\treturn err\n\t}\n\treturn unveil(nil, nil)\n}\n\n// supportsUnveil checks for availability of the unveil(2) system call based\n// on the running OpenBSD version.\nfunc supportsUnveil() error {\n\tmaj, min, err := majmin()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// unveil is not available before 6.4\n\tif maj < 6 || (maj == 6 && min <= 3) {\n\t\treturn fmt.Errorf(\"cannot call Unveil on OpenBSD %d.%d\", maj, min)\n\t}\n\n\treturn nil\n}\n"
  }
]